[
  {
    "path": ".htaccess",
    "content": "<IfModule mod_rewrite.c>\r\n  Options +FollowSymlinks -Multiviews\r\n  RewriteEngine On\r\n\r\n  RewriteCond %{REQUEST_FILENAME} !-d\r\n  RewriteCond %{REQUEST_FILENAME} !-f\r\n  RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]\r\n</IfModule>\r\n"
  },
  {
    "path": ".travis.yml",
    "content": "sudo: false\r\n\r\nlanguage: php\r\n\r\nbranches:\r\n  only:\r\n    - stable\r\n\r\ncache:\r\n  directories:\r\n    - $HOME/.composer/cache\r\n\r\nbefore_install:\r\n  - composer self-update\r\n\r\ninstall:\r\n  - composer install --no-dev --no-interaction --ignore-platform-reqs\r\n  - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Core.zip .\r\n  - composer require --update-no-dev --no-interaction \"topthink/think-image:^1.0\"\r\n  - composer require --update-no-dev --no-interaction \"topthink/think-migration:^1.0\"\r\n  - composer require --update-no-dev --no-interaction \"topthink/think-captcha:^1.0\"\r\n  - composer require --update-no-dev --no-interaction \"topthink/think-mongo:^1.0\"\r\n  - composer require --update-no-dev --no-interaction \"topthink/think-worker:^1.0\"\r\n  - composer require --update-no-dev --no-interaction \"topthink/think-helper:^1.0\"\r\n  - composer require --update-no-dev --no-interaction \"topthink/think-queue:^1.0\"\r\n  - composer require --update-no-dev --no-interaction \"topthink/think-angular:^1.0\"\r\n  - composer require --dev --update-no-dev --no-interaction \"topthink/think-testing:^1.0\"\r\n  - zip -r --exclude='*.git*' --exclude='*.zip' --exclude='*.travis.yml' ThinkPHP_Full.zip .\r\n\r\nscript:\r\n  - php think unit\r\n\r\ndeploy:\r\n  provider: releases\r\n  api_key:\r\n    secure: TSF6bnl2JYN72UQOORAJYL+CqIryP2gHVKt6grfveQ7d9rleAEoxlq6PWxbvTI4jZ5nrPpUcBUpWIJHNgVcs+bzLFtyh5THaLqm39uCgBbrW7M8rI26L8sBh/6nsdtGgdeQrO/cLu31QoTzbwuz1WfAVoCdCkOSZeXyT/CclH99qV6RYyQYqaD2wpRjrhA5O4fSsEkiPVuk0GaOogFlrQHx+C+lHnf6pa1KxEoN1A0UxxVfGX6K4y5g4WQDO5zT4bLeubkWOXK0G51XSvACDOZVIyLdjApaOFTwamPcD3S1tfvuxRWWvsCD5ljFvb2kSmx5BIBNwN80MzuBmrGIC27XLGOxyMerwKxB6DskNUO9PflKHDPI61DRq0FTy1fv70SFMSiAtUv9aJRT41NQh9iJJ0vC8dl+xcxrWIjU1GG6+l/ZcRqVx9V1VuGQsLKndGhja7SQ+X1slHl76fRq223sMOql7MFCd0vvvxVQ2V39CcFKao/LB1aPH3VhODDEyxwx6aXoTznvC/QPepgWsHOWQzKj9ftsgDbsNiyFlXL4cu8DWUty6rQy8zT2b4O8b1xjcwSUCsy+auEjBamzQkMJFNlZAIUrukL/NbUhQU37TAbwsFyz7X0E/u/VMle/nBCNAzgkMwAUjiHM6FqrKKBRWFbPrSIixjfjkCnrMEPw=\r\n  file:\r\n    - ThinkPHP_Core.zip\r\n    - ThinkPHP_Full.zip\r\n  skip_cleanup: true\r\n  on:\r\n    tags: true\r\n"
  },
  {
    "path": "LICENSE.txt",
    "content": "\r\nThinkPHP遵循Apache2开源协议发布，并提供免费使用。\r\n版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)\r\nAll rights reserved。\r\nThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。\r\n\r\nApache Licence是著名的非盈利开源组织Apache采用的协议。\r\n该协议和BSD类似，鼓励代码共享和尊重原作者的著作权，\r\n允许代码修改，再作为开源或商业软件发布。需要满足\r\n的条件： \r\n1． 需要给代码的用户一份Apache Licence ；\r\n2． 如果你修改了代码，需要在被修改的文件中说明；\r\n3． 在延伸的代码中（修改和有源代码衍生的代码中）需要\r\n带有原来代码中的协议，商标，专利声明和其他原来作者规\r\n定需要包含的说明；\r\n4． 如果再发布的产品中包含一个Notice文件，则在Notice文\r\n件中需要带有本协议内容。你可以在Notice中增加自己的\r\n许可，但不可以表现为对Apache Licence构成更改。 \r\n具体的协议参考：http://www.apache.org/licenses/LICENSE-2.0\r\n\r\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\r\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\r\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\r\nFOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\r\nCOPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\r\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\r\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\r\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\r\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\r\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r\nPOSSIBILITY OF SUCH DAMAGE.\r\n"
  },
  {
    "path": "README.md",
    "content": "WeMall商城 7.0 (不含商城)\n===============\n\n\n\n​\twemall7.0 开源系统，基于thinkphp5开发，支持composer，优化核心，减少依赖，基于全新的架构思想和命名空间。\n\n\n\n### thinkphp5.0特性\n\n- 基于命名空间和众多PHP新特性\n- 核心功能组件化\n- 强化路由功能\n- 更灵活的控制器\n- 重构的模型和数据库类\n- 配置文件可分离\n- 重写的自动验证和完成\n- 简化扩展机制\n- API支持完善\n- 改进的Log类\n- 命令行访问支持\n- REST支持\n- 引导文件支持\n- 方便的自动生成定义\n- 真正惰性加载\n- 分布式环境支持\n- 更多的社交类库\n\n> ThinkPHP5的运行环境要求PHP5.4以上。\n\n\n\n### wemall7.0特性\n\n- 基于TP5，性能优越\n- 前后分离，简单方便\n- 插件扩展，功能丰富\n- 钩子机制，高度扩展\n- 自动升级，维护简单\n- 使用pjax，体验提升\n- rest架构，耦合度低\n\n\n> ##### 功能列表\n>\n> 1. 首页=》系统首页\n>\n> 2. 设置=》站点设置，短信配置，邮件配置\n>\n> 3. 微信=》微信配置，微信菜单，自定义回复，模版消息，多客服设置，微信打印机\n>\n> 4. 内容=》文章分类，文章列表\n>\n> 5. 模版=》模版设置，邮件模版，短信模版\n>\n> 6. 用户=》管理员用户组，管理员列表，用户列表，会员列表\n>\n> 7. 插件=》插件管理，插件商店\n>\n> 8. 帮助=》使用帮助\n>\n>    ...\n\n\n\n\n## 插件钩子机制\n\n### 安装\n\n> composer require qingyuexi/think-addons\n\n### 配置\n\n#### 公共配置\n\n```\n'addons'=>[\n    // 可以定义多个钩子\n    'testhook'=>'putong\\demo\\demo' // 键为钩子名称，用于在业务中自定义钩子处理，值为实现该钩子的插件，\n                    // 多个插件可以用数组也可以用逗号分割\n]\n\n```\n\n或者在application\\extra目录中新建`addons.php`,内容为：\n\n```\n<?php\nreturn [\n    // 可以定义多个钩子\n    'testhook'=>'putong\\demo\\demo' // 键为钩子名称，用于在业务中自定义钩子处理，值为实现该钩子的插件，\n                    // 多个插件可以用数组也可以用逗号分割\n]\n\n```\n\n### 创建插件\n\n> 创建的插件可以在view视图中使用，也可以在php业务中使用\n\n安装完成后访问系统时会在项目根目录生成名为`addons`的目录，在该目录中创建需要的插件。\n\n下面写一个例子：\n\n#### 创建putong分类插件\n\n> 在addons目录中创建putong目录\n\n#### 创建插件分类配置文件\n\n> 在putong目录中创建config.php类文件，插件配置文件可以省略。\n\n```\n<?php\nreturn [\n    'name' => 'putong',\n    'title' => 'putong',\n    'description' => 'putong类插件',\n    'status' => 1,\n    'author' => '清月曦'\n];\n\n```\n\n#### 在putong分类下创建demo插件\n\n> 在addons目录下的putong目录下创建demo目录\n\n#### 创建钩子实现类\n\n> 在test目录中创建Demo.php类文件。注意：类文件首字母需大写\n\n```\n<?php\nnamespace addons\\putong\\demo;   // 注意命名空间规范\n\nuse think\\Addons;\n\n/**\n * 插件测试\n * @author byron sampson\n */\nclass Demo extends Addons   // 需继承think\\addons\\Addons类\n{\n    // 该插件的基础信息\n    public $info = [\n        'name' => 'test',   // 插件标识\n        'title' => '插件测试',  // 插件名称\n        'description' => 'thinkph5插件测试',    // 插件简介\n        'status' => 0,  // 状态\n        'author' => 'byron sampson',\n        'version' => '0.1'\n    ];\n\n    /**\n     * 插件安装方法\n     * @return bool\n     */\n    public function install()\n    {\n        return true;\n    }\n\n    /**\n     * 插件卸载方法\n     * @return bool\n     */\n    public function uninstall()\n    {\n        return true;\n    }\n\n    /**\n     * 实现的testhook钩子方法\n     * @return mixed\n     */\n    public function testhook($param)\n    {\n        // 调用钩子时候的参数信息\n        print_r($param);\n        // 当前插件的配置信息，配置信息存在当前目录的config.php文件中，见下方\n        print_r($this->getConfig());\n        // 可以返回模板，模板文件默认读取的为插件目录中的文件。模板名不能为空！\n        return $this->fetch('info');\n    }\n\n}\n\n```\n\n#### 创建插件配置文件\n\n> 在test目录中创建config.php类文件，插件配置文件可以省略。\n\n```\n<?php\nreturn [\n    'name' => 'demo',\n    'title' => 'demo',\n    'description' => 'demo插件',\n    'status' => 1,\n    'url' => true,\n    'author' => '清月曦',\n    'version' => '0.1'\n];\n\n```\n\n#### 创建钩子模板文件\n\n> 在demo目录中创建info.html模板文件，钩子在使用fetch方法时对应的模板文件。\n\n```\n<h1>hello tpl</h1>\n\n如果插件中需要有链接或提交数据的业务，可以在插件中创建controller业务文件，\n要访问插件中的controller时使用addon_url生成url链接。\n如下：\n<a href=\"{:addon_url('putong://demo/admin/index')}\">link demo</a>\n格式为：\ndemo为插件名，admin为controller中的类名，index为controller中的方法\n\n```\n\n#### 创建插件的controller文件\n\n> 在test目录中创建controller目录，在controller目录中创建Action.php文件 controller类的用法与tp5中的controller一致\n\n```\n<?php\nnamespace addons\\putong\\demo\\controller;\n\nclass Admin\n{\n    public function index()\n    {\n        echo 'hello link';\n    }\n}\n\n```\n\n> 如果需要使用view模板则需要继承`\\think\\addons\\Controller`类 模板文件所在位置为插件目录的view中，规则与模块中的view规则一致\n\n```\n<?php\nnamespace addons\\putong\\demo\\controller;\n\nuse think\\addons\\Controller;\n\nclass Admin extends Controller\n{\n    public function index()\n    {\n        return $this->fetch();\n    }\n}\n\n```\n\n### 使用钩子\n\n> 创建好插件后就可以在正常业务中使用该插件中的钩子了 使用钩子的时候第二个参数可以省略\n\n#### 模板中使用钩子\n\n```\n<div>{:hook('testhook', ['id'=>1])}</div>\n\n```\n\n#### php业务中使用\n\n> 只要是thinkphp5正常流程中的任意位置均可以使用\n\n```\nhook('testhook', ['id'=>1])\n\n```\n\n### 插件目录结构\n\n#### 最终生成的目录结构为\n\n```\ntp5\n - addons\n -- putong\n --- demo\n ---- controller\n ----- Admin.php\n ---- view\n ---- action\n ----- link.html\n --- config.php\n --- info.html\n --- Demo.php\n - application\n - thinkphp\n - extend\n - vendor\n - public\n```\n\n\n\n## 版权信息\n\nwemall7开源版遵循Apache2开源协议发布，并提供免费使用。本项目包含的第三方源码和二进制文件之版权信息另行标注。版权所有Copyright © 2016-2017 by wemallshop.com ([http://www.wemallshop.com](http://www.wemallshop.com)) All rights reserved。"
  },
  {
    "path": "addons/common/config.php",
    "content": "<?php\n/**\n * \n * @authors 清月曦 (1604583867@qq.com)\n * @date    2017-03-07 23:29:12\n * @version $Id$\n */\nreturn [\n    'name' => 'common',\n    'title' => '公共插件',\n    'description' => '公共插件列表',\n    'author' => '清月曦'\n];"
  },
  {
    "path": "addons/putong/config.php",
    "content": "<?php\n/**\n * \n * @authors 清月曦 (1604583867@qq.com)\n * @date    2017-03-07 23:29:12\n * @version $Id$\n */\nreturn [\n    'name' => 'putong',\n    'title' => '普通版',\n    'description' => '普通版插件列表',\n    'status' => 1,\n    'url' => true,\n    'author' => '清月曦',\n    'version' => '0.1'\n];"
  },
  {
    "path": "addons/putong/demo/Demo.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | thinkphp5 Addons [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2016 http://www.zzstudio.net All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: Byron Sampson <xiaobo.sun@qq.com>\n// +----------------------------------------------------------------------\nnamespace addons\\putong\\demo;\n\nuse think\\Addons;\n\n/**\n * 插件测试\n * @author byron sampson\n */\nclass Demo extends Addons\n{\n    public $info = [\n        'name' => 'test',\n        'title' => '插件测试',\n        'description' => 'thinkph5插件测试',\n        'status' => 0,\n        'author' => 'byron sampson',\n        'version' => '0.1'\n    ];\n\n    /**\n     * 插件安装方法\n     * @return bool\n     */\n    public function install()\n    {\n        return true;\n    }\n\n    /**\n     * 插件卸载方法\n     * @return bool\n     */\n    public function uninstall()\n    {\n        return true;\n    }\n\n    /**\n     * 实现的testHook钩子方法\n     * @return mixed\n     */\n    public function temphook($param)\n    {\n        echo '<p><font color=\"red\">开始处理钩子啦</font></p>';\n        echo '<p><font color=\"green\">打印传给钩子的参数：</font></p>';\n        dump($param);\n        echo '<p><font color=\"green\">打印插件配置：</font></p>';\n        dump($this->getConfig());\n\n        // 这里可以通过钩子来调用钩子模板\n        return $this->fetch('info');\n    }\n\n}\n"
  },
  {
    "path": "addons/putong/demo/config.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | thinkphp5 Addons [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2016 http://www.zzstudio.net All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: Byron Sampson <xiaobo.sun@qq.com>\n// +----------------------------------------------------------------------\nreturn [\n    'name' => 'demo',\n    'title' => 'demo',\n    'description' => 'demo插件',\n    'status' => 1,\n    'url' => true,\n    'author' => '清月曦',\n    'version' => '0.1'\n];\n"
  },
  {
    "path": "addons/putong/demo/controller/Admin.php",
    "content": "<?php\nnamespace addons\\putong\\demo\\controller;\n\nuse think\\addons\\Controller;\nuse addons\\putong\\demo\\model\\AddonsPutongDemoConfig;\n\nclass Admin extends Controller\n{\n\tpublic function _initialize(){\n        // 判断是否登录，没有登录跳转登录页面\n        if(!session('user_auth') || !session('user_auth_sign')){\n            $this->redirect('admin/public/login');\n        }\n        if ($this->request->isPjax()){\n            $this->view->engine->layout(false);\n        }else{\n            $this->view->engine->layout('./application/admin/view/layout_addons.html');\n        }\n\t}\n\t\n    //活动列表\n    public function index()\n    {\n        $configList = AddonsPutongDemoConfig::with('file')->order('id desc')->paginate();\n        // dump($configList->toArray());\n        cookie(\"prevUrl\", request()->url());\n\n        $this->assign('configList', $configList);\n        return view('admin_index');\n    }\n\n    //新增修改活动\n    public function add()\n    {   \n        if (request()->isPost()){\n            $data = input('post.');\n            $data['status'] = input('?post.status') ? $data['status'] : 0;\n\n            if(input('post.id')){\n                $result = AddonsPutongDemoConfig::update($data);\n            }else{\n                $result = AddonsPutongDemoConfig::create($data);\n            }\n\n            if($result){\n                $this->success(\"保存成功\", cookie(\"prevUrl\"));\n            }else{\n                $this->error('保存失败', cookie(\"prevUrl\"));\n            }\n        }else{\n            $id = input('param.id');\n            if($id){\n                $config = AddonsPutongDemoConfig::with('file')->find($id);\n                $this->assign('config', $config);\n            }\n\n            return view('admin_add');\n        }\n    }\n\n    //更新状态\n    public function update()\n    {\n        $data = input('param.');\n\n        $result = AddonsPutongDemoConfig::where('id','in',$data['id'])->update(['status' => $data['status']]);\n        if($result){\n            $this->success(\"修改成功\", cookie(\"prevUrl\"));\n        }else{\n            $this->error('修改失败', cookie(\"prevUrl\"));\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "addons/putong/demo/controller/Index.php",
    "content": "<?php\nnamespace addons\\putong\\demo\\controller;\n\nuse think\\addons\\Controller;\n\nclass Index extends Controller\n{\n\tpublic function _initialize(){\n        //插件资源文件\n        $this->view->replace([\n                '__CSS__'       =>  request()->root(true).'/addons/putong/demo/view/public/css',\n                '__IMG__'       =>  request()->root(true).'/addons/putong/demo/view/public/image',\n            ]);\n\t}\n\t\n    public function index()\n    {\n\n        return view('index_index');\n    }\n\n\n\n\n\n}\n"
  },
  {
    "path": "addons/putong/demo/data/install.sql",
    "content": "--\n-- 表的结构 `addons_putong_demo_config`\n--\n\nCREATE TABLE `addons_putong_demo_config` (\n  `id` int(10) unsigned NOT NULL,\n  `name` text NOT NULL COMMENT '活动名称',\n  `file_id` int(11) NOT NULL COMMENT '活动图片',\n  `sub` text NOT NULL COMMENT '活动描述',\n  `detail` text NOT NULL COMMENT '活动详情',\n  `timerange` text NOT NULL COMMENT '活动时间',\n  `remark` text NOT NULL COMMENT '备注',\n  `status` int(1) NOT NULL DEFAULT '1' COMMENT '1:开启0:关闭',\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `addons_putong_demo_config`\n--\n\nINSERT INTO `addons_putong_demo_config` (`id`, `name`, `file_id`, `sub`, `detail`, `timerange`, `remark`, `status`, `created_at`, `updated_at`) VALUES\n(1, '活动名称', 1, '这里是活动描述', '', '2017-05-01 12:00:00 --- 2017-05-25 11:59:59', '', 1, '2017-05-01 10:25:26', '2017-05-01 12:12:04'),\n(2, '活动2', 1, '活动描述', '<p>111</p>', '2017-05-01 12:00:00 --- 2017-05-11 11:59:59', '', 1, '2017-05-01 10:37:35', '2017-05-01 12:11:06');"
  },
  {
    "path": "addons/putong/demo/data/uninstall.sql",
    "content": "/* \n* @Author: qingyuexi\n* @Date:   2016-10-04 14:24:05\n* @Last Modified by:   qingyuexi\n* @Last Modified time: 2016-02-18 15:11:31\n*/\nDROP TABLE IF EXISTS `addons_putong_demo_config`;\n"
  },
  {
    "path": "addons/putong/demo/info.html",
    "content": "<p>我是钩子模板</p>\n<p>我是在钩子中生成的url</p>\n<p>\n<a href=\"{:addon_url('putong://demo/index/index')}\">\n\t{:addon_url('putong://demo/admin/index', [], true, true)}\n</a>\n</p>\n<p><font color=\"red\">钩子处理结束啦</font></p>\n<a href=\"\"></a>\n"
  },
  {
    "path": "addons/putong/demo/model/AddonsPutongDemoConfig.php",
    "content": "<?php\nnamespace addons\\putong\\demo\\model;\nuse think\\Model;\n\nclass AddonsPutongDemoConfig extends Model\n{\n\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n    // 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\n\tpublic function file()\n    {\n        return $this->hasOne('app\\common\\model\\File','id','file_id');\n    }\n\n}"
  },
  {
    "path": "addons/putong/demo/view/admin_add.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- general form elements -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">新增/修改活动</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal layui-form\" action=\"{:addon_url('putong://demo/admin/add')}\" method=\"post\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$config.id|default=0}\"\n                               type=\"hidden\">\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">活动名称</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"name\" placeholder=\"\" value=\"{$config.name|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">活动描述</label>\n\n                            <div class=\"col-sm-10\">\n                                <textarea class=\"form-control\" name=\"sub\" rows=\"3\">{$config.sub|default=''}</textarea>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">活动图片</label>\n\n                            <div class=\"col-sm-10\">\n                                <div class=\"fileupload fileupload-new\" data-provides=\"fileupload\">\n                                    <div class=\"fileupload-new img-thumbnail\">\n                                        {empty name=\"config.file_id\"}\n                                            <img src=\"__PUBLIC__/static/dist/img/noimage.gif\">\n                                        {else /}\n                                            <img src=\"__PUBLIC__/uploads/{$config['file']['savepath']}{$config['file']['savename']}\">\n                                        {/empty}\n                                        <input class=\"form-control\" name=\"file_id\" id=\"file_id\" placeholder=\"\"\n                                               value=\"{$config.file_id|default=''}\" type=\"hidden\">\n\n                                        <div class=\"edit_pic_mask\">\n                                            <i class=\"fa fa-plus-circle\" onclick=\"imageUploader(this,false)\"></i>\n                                            <i class=\"fa fa-minus-circle\" onclick=\"removeImage(this,false)\"></i>\n                                        </div>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">活动时间</label>\n                            <div class=\"col-md-7\">\n                                <input class=\"form-control pull-right\" name=\"timerange\"\n                                           id=\"reservationtime\" value=\"{$config.timerange|default=''}\" type=\"text\" >\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">活动详情</label>\n\n                            <div class=\"col-md-10\">\n                                <!-- 加载编辑器的容器 -->\n                                <script id=\"UEditor\" name=\"detail\" type=\"text/plain\" style=\"height:500px;\">\n                                    {$config.detail|default=''}\n                                </script>\n                            </div>\n                        </div>\n\n          \n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">活动状态</label>\n\n                            <div class=\"col-md-7\">\n                                <input type=\"checkbox\" name=\"status\" lay-skin=\"switch\" value=\"1\"\n                                {notempty name=\"config.status\"}checked{/notempty}>\n                            </div>\n                        </div>\n                    </div>\n\n                    <!-- /.box-body -->\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button class=\"btn btn-block btn-danger\" lay-submit lay-filter=\"save\">保存</button>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <button type=\"button\" class=\"btn btn-block btn-default\" onclick=\"history.go(-1)\">取消\n                            </button>\n                        </div>\n                    </div>\n                </form>\n            </div>\n            <!-- /.box -->\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n\tif('{$ads.position_id|default=''}'){\n        $('select[name=\"position_id\"]').val('{$ads.position_id|default=''}');\n    }\n    $(function () {\n    \t//实例化编辑器异步载入\n        var editor = new UE.ui.Editor();\n        editor.render(\"UEditor\");\n\n        //时间段插件\n        $('#reservationtime').daterangepicker({\n            timePicker: true,\n            timePickerIncrement: 30,\n            format: 'YYYY-MM-DD h:mm:ss',\n            separator: ' --- ',\n        });\n\n        layui.use('form', function() {\n            var form = layui.form();\n            form.render(); //更新全部\n        });\n    });\n</script>\n"
  },
  {
    "path": "addons/putong/demo/view/admin_index.html",
    "content": "\n<section class=\"content\">\n    <div class=\"row\">\n        <!-- /.col -->\n        <div class=\"col-md-12\">\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">活动列表</h3>\n                </div>\n                <div style=\"margin-top: 10px;\">\n                    <div class=\"btn-group\" style=\"margin-left: 10px;\">\n                        <a href=\"{:addon_url('putong://demo/admin/add')}\" class=\"btn btn-danger \">\n                            新增活动\n                        </a>\n                    </div>\n                </div>\n                <div class=\"box-body table-responsive\">\n                    <table class=\"table table-bordered table-hover\">\n                        <tbody>\n                        <tr>\n                            <th>活动编号</th>\n                            <th>活动名称</th>\n                            <th>活动图片</th>\n                            <th>活动时间</th>\n                            <th>活动状态</th>\n                            <th>操作</th>\n                        </tr>\n                        {volist name=\"configList\" id=\"config\" empty=\"暂时没有数据\"}\n                            <tr>\n                                <td>{$config.id}</td>\n                                <td>{$config.name}</td>\n                                <td>\n                                \t{empty name=\"config.file_id\"}\n                                        <img style=\"width: 60px;\" src=\"__PUBLIC__/static/dist/img/noimage.gif\">\n                                    {else /}\n                                        <img style=\"width: 60px;\"\n                                        src=\"__PUBLIC__/uploads/{$config['file']['savepath']}{$config['file']['savename']}\">\n                                    {/empty}\n                                </td>\n                                <td>{$config.timerange}</td>\n                                <td>\n                                    {eq name=\"config.status\" value=\"1\"}\n                                        <span class=\"label label-success\">已开启</span>\n                                    {else/}\n                                        <span class=\"label label-default\">已关闭</span>\n                                    {/eq}\n                                </td>\n                                <td>\n                                \t<a href=\"{:addon_url('putong://demo/admin/add',array('id'=>$config['id']))}\">编辑</a>\n                                \t{eq name=\"config.status\" value=\"0\"}\n                                    <a href=\"{:addon_url('putong://demo/admin/update',array('id'=>$config['id'],'status'=>1))}\">开启</a> \n                                    {/eq}\n                                    {eq name=\"config.status\" value=\"1\"}\n                                    <a href=\"{:addon_url('putong://demo/admin/update',array('id'=>$config['id'],'status'=>0))}\">关闭</a> \n                                    {/eq}\n                                </td>\n                            </tr>\n                        {/volist}\n                        </tbody>\n                    </table>\n                </div>\n                <div class=\"box-footer no-padding\">\n                    <div class=\"mailbox-controls\">\n                        <div class=\"pull-right\">\n                            {$configList->render()}\n                        </div>\n                    </div>\n                </div>\n            </div>\n            <!-- /. box -->\n        </div>\n        <!-- /.col -->\n    </div>\n</section>"
  },
  {
    "path": "addons/putong/demo/view/index_index.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n    <title>Examples</title>\n    <meta name=\"description\" content=\"\">\n    <meta name=\"keywords\" content=\"\">\n    <link href=\"__CSS__/style.css\" rel=\"stylesheet\">\n</head>\n\n<body>\n\t这里是插件前台\n</body>\n\n</html>\n"
  },
  {
    "path": "addons/putong/demo/view/public_left.html",
    "content": "<li class=\"treeview\">\n    <a href=\"#\">\n        <i class=\"fa fa-dashboard\"></i> <span>Demo</span> \n    </a>\n    <ul class=\"treeview-menu\">\n        <li><a href=\"{:addon_url('putong://demo/admin/index')}\"><i class=\"fa \"></i>demo插件</a></li>\n    </ul>\n</li>"
  },
  {
    "path": "application/.htaccess",
    "content": "deny from all"
  },
  {
    "path": "application/admin/common.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: 流年 <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\n// 应用公共文件\n\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "application/admin/config.php",
    "content": "<?php\r\n// +----------------------------------------------------------------------\r\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\r\n// +----------------------------------------------------------------------\r\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\r\n// +----------------------------------------------------------------------\r\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\r\n// +----------------------------------------------------------------------\r\n// | Author: 流年 <liu21st@gmail.com>\r\n// +----------------------------------------------------------------------\r\n\r\n// 应用公共文件\r\nreturn [\r\n    'template'               => [\r\n        // 模板引擎类型 支持 php think 支持扩展\r\n        'type'         => 'Think',\r\n        // 模板路径\r\n        'view_path'    => '',\r\n        // 模板后缀\r\n        'view_suffix'  => 'html',\r\n        // 模板文件名分隔符\r\n        'view_depr'    => '_',\r\n        // 模板引擎普通标签开始标记\r\n        'tpl_begin'    => '{',\r\n        // 模板引擎普通标签结束标记\r\n        'tpl_end'      => '}',\r\n        // 标签库标签开始标记\r\n        'taglib_begin' => '{',\r\n        // 标签库标签结束标记\r\n        'taglib_end'   => '}',\r\n\r\n        'tpl_cache'    => false,\r\n    ],\r\n];"
  },
  {
    "path": "application/admin/controller/AddonsController.php",
    "content": "<?php\n/**\n * \n * @authors 清月曦 (1604583867@qq.com)\n * @date    2017-05-01 13:21:11\n * @version $Id$\n */\nnamespace app\\admin\\controller;\nuse ZipArchive;\nclass AddonsController extends BaseController\n{\n\tpublic $appUrl = \"\";\n    private static $addonUrl = \"http://addon.wemallshop.com\";\n\n    public function _initialize()\n    {\n        parent::_initialize();\n        $this->appUrl = request()->root(true);\n    }\n    //插件列表\n    public function index()\n    {\n    \t$item = getDir(ADDON_PATH);\n\n        $info = array();\n        if($item){\n            foreach ($item as $key => $value) {\n                if (is_file(ADDON_PATH . '/' . $value . '/' . 'config.php')) {\n                    $item_config = require ADDON_PATH . '/' . $value . '/' . 'config.php';\n                    $info[$value] = $item_config;\n                    $info[$value]['sub'] = array();\n                }\n                \n                $addons = getDir(ADDON_PATH.$value);\n                foreach ($addons as $k => $v) {\n                    if ($v && is_file(ADDON_PATH . '/' . $value . '/' . $v . '/' . 'config.php')) {\n                        $config = require ADDON_PATH . '/' . $value . '/'  . $v . '/' . 'config.php';\n                        $config['addons_admin_url'] = addon_url($value . '://'.$v.'/admin/index',[]);\n                        $config['addons_img_url'] = $this->appUrl .'/addons/' . $value . '/' . $v . '/' . $v .'.png';\n                        \n                        if (is_file(ADDON_PATH . '/' . $value . '/' . $v . '/' . 'install.lock')) {\n                            $config['lock'] = 1;\n                        }else{\n                            $config['lock'] = 0;\n                        }\n                        \n                        array_push($info[$value]['sub'], $config);\n                    }\n                }\n            }\n        }\n        cookie(\"prevUrl\", request()->url());\n\n        $this->assign('item', $info);\n        return view();\n    }\n\n    //应用商店\n    public function shop()\n    {\n        $domain = request()->domain();\n        $this->assign('domain', $domain);\n        return view();\n    }\n\n    //下载解压插件\n    public function getFileDownload()\n    {\n        $data = input('param.');\n        \n        $path = $data['path'];\n        $uuid = $data['uuid'];\n        $type = $data['type'];\n        $sort = $data['sort'];\n        if($sort == 'install'){\n            $filePath = self::$addonUrl . $path . '?order_uuid=' . $uuid . '&type=' . $type;\n        }else{\n            $filePath = self::$addonUrl . $path . '?uuid=' .$uuid . '&type=' . $type;\n        }\n\n        $zipPath = \"./addons.zip\";\n        http_down($filePath, $zipPath);\n\n        $re = unzip($zipPath,'./');\n        if($re){\n            return json(['data' => false, 'msg' => '恭喜您，下载完成!', 'code' => 1]);\n        }else{\n            return json(['data' => false, 'msg' => '下载安装失败', 'code' => 0]);\n        }\n    }\n    //自动安装插件\n    public function compare()\n    {\n        $item = getDir(ADDON_PATH);\n        if($item){\n            foreach ($item as $key => $value) {\n                $addons = getDir(ADDON_PATH.$value);\n                foreach ($addons as $k => $v) {\n                    $addons_path = ADDON_PATH . $value . '/' . $v;\n                    //安装sql\n                    if (!file_exists($addons_path . '/install.lock')) {\n                        $install_sql = $addons_path . '/data/install.sql';\n                        try {\n                            if (file_exists($install_sql)) {\n                                execute_sql_file($install_sql);\n                                file_put_contents($addons_path . '/install.lock','');\n                                // unlink('./update.sql');\n                            }\n                        } catch (\\Exception $e) {\n                            // 这是进行异常捕获\n                            return json(['data' => false, 'msg' => $e->getMessage(), 'code' => 0]);\n                        }\n                    }\n                    //升级sql\n                    $update_sql = $addons_path . '/update.sql';\n                    try {\n                        if (file_exists($update_sql)) {\n                            execute_sql_file($update_sql);\n                            unlink('./update.sql');\n                        }\n                    } catch (\\Exception $e) {\n                        // 这是进行异常捕获\n                        return json(['data' => false, 'msg' => $e->getMessage(), 'code' => 0]);\n                    }\n                }\n            }\n        }\n        return json(['data' => false, 'msg' => '恭喜您，安装完成！', 'code' => 1]);\n    }\n\n\n\n\n\n}"
  },
  {
    "path": "application/admin/controller/BaseController.php",
    "content": "<?php\n/**\n * \n * @authors 清月曦 (1604583867@qq.com)\n * @date    2017-05-01 11:27:23\n * @version $Id$\n */\nnamespace app\\admin\\controller;\nuse think\\Controller;\n\nclass BaseController extends Controller\n{\n    public function _initialize(){\n        // 判断是否登录，没有登录跳转登录页面\n        if(!session('user_auth') || !session('user_auth_sign')){\n            $this->redirect('public/login');\n        }\n\n        $activeRouter = request()->module() . '/' . request()->controller() . '/' . request()->action();\n        // dump(strtolower($activeRouter));\n        if(!in_array(strtolower($activeRouter), array(\"admin/help/index\",\"admin/addons/getfiledownload\",\"admin/addons/compare\"))){\n            $auth = new \\com\\Auth();\n            if(!$auth->check($activeRouter, session('user_auth')['uid'])){\n                return $this->error('你没有权限',cookie(\"prevUrl\"));\n            }\n        }\n\n        if ($this->request->isPjax()){\n\t\t\t$this->view->engine->layout(false);\n\t\t}else{\n\t\t\t$this->view->engine->layout(true);\n\t\t}\n    }\n\n\n\n}"
  },
  {
    "path": "application/admin/controller/FileController.php",
    "content": "<?php\nnamespace app\\admin\\controller;\n\nclass FileController extends BaseController\n{\n\t// 图片列表\n\tpublic function index(){\n\t\t$filelist = model('File')->order('id', 'desc')->paginate(12);\n\t\t$page = $filelist->render();\n\t\tcookie(\"imgUrl\", $this->request->url());\n\t\t\n\t\t$this->assign('filelist', $filelist);\n\t\t$this->assign('page', $page);\n\t\t// 临时关闭当前模板的布局功能\n        $this->view->engine->layout(false);\n\t\treturn view();\n\t}\n\t//上传图片\n\tpublic function upload(){\n\t\t// 获取表单上传文件\n        $files = $this->request->file('image');\n        $data = array();\n        foreach($files as $file){\n        \t// 移动到框架应用根目录/public/uploads/ 目录下\n\t        $info = $file->validate(['ext'=>'jpg,png,gif,jpeg'])->move(ROOT_PATH . 'public' . DS . 'uploads');\n\t        if ($info) {\n\t            $item = array();\n\t            $item['name'] = $info->getInfo('name');\n\t            $item['type'] = $info->getInfo('type');\n\t            $item['savename'] = $info->getFilename();\n            \t$item['savepath'] = date(\"Ymd\") .'/';\n            \tarray_push($data,$item);\n\t        } else {\n\t            // 上传失败获取错误信息\n\t            $this->error($file->getError());\n\t        }\n        }   \n        model('File')->saveAll($data);\n        $this->success('文件上传成功',cookie(\"imgUrl\"));     \n\t}\n\n\n}"
  },
  {
    "path": "application/admin/controller/HelpController.php",
    "content": "<?php\nnamespace app\\admin\\controller;\n\nclass HelpController extends BaseController\n{\n    //使用帮助\n    public function index(){\n       \n        return view();\n    }\n}"
  },
  {
    "path": "application/admin/controller/IndexController.php",
    "content": "<?php\r\nnamespace app\\admin\\controller;\r\nuse think\\helper\\Time;\r\nuse app\\common\\model\\User;\r\nuse app\\common\\model\\Analysis;\r\nclass IndexController extends BaseController\r\n{\r\n    public function index()\r\n    {\r\n    \t//今日用户\r\n        $todayUser     = User::whereTime('created_at', 'today')->count();\r\n        $this->assign(\"todayUser\", $todayUser);\r\n        //本周用户\r\n        $weekUser      = User::whereTime('created_at', 'week')->count();\r\n        $this->assign(\"weekUser\", $weekUser);\r\n        //本月用户\r\n        $monthUser     = User::whereTime('created_at', 'month')->count();\r\n        $this->assign(\"monthUser\", $monthUser);\r\n        //总用户\r\n        $totalUser     = User::count();\r\n        $this->assign(\"totalUser\", $totalUser);\r\n\r\n\t\t$line_data = $this->getDateAnalysis();\r\n\r\n\t\t$newUserLine = array();\r\n        foreach ($line_data as $key => $value) {\r\n            $newUserLine[$key] = $value[\"registers\"];\r\n        }\r\n        $this->assign(\"newUserLine\", json_encode($newUserLine));\r\n\r\n\r\n        $newsList = getHttpResponseGET('http://www.wemallshop.com/cms/index/news');\r\n\r\n        $this->assign(\"newsList\", json_decode($newsList,true));\r\n        $this->assign(\"url\", 'http://www.wemallshop.com/');\r\n\r\n    \tcookie(\"prevUrl\", request()->url());\r\n        return view();\r\n    }\r\n\r\n\tpublic function getDateAnalysis(){\r\n        $analysis = Analysis::whereTime('created_at', 'between', Time::dayToNow(18, true))\r\n                  ->order('id desc')\r\n                  ->select()\r\n                  ->toArray();\r\n\r\n        $date = array();\r\n        for ($i = 18; $i >= 0; $i--) {\r\n            array_push($date, date(\"Y-m-d\", strtotime(\"-$i day\")));\r\n        }\r\n        $this->assign(\"date\", json_encode($date));\r\n\r\n        $line_data = array();\r\n        foreach ($date as $key => $value) {\r\n            $line_data[$key] = array(\r\n                \"id\" => \"0\",\r\n                \"orders\" => \"0\",\r\n                \"trades\" => \"0\",\r\n                \"registers\" => \"0\",\r\n                \"users\" => \"0\",\r\n                \"date\" => \"0\",\r\n            );\r\n            foreach ($analysis as $k => $v) {\r\n                if ($v[\"date\"] == $value) {\r\n                    $line_data[$key] = $v;\r\n                }\r\n            }\r\n        }\r\n        return $line_data;\r\n\t}\r\n\r\n\r\n\r\n\r\n}\r\n"
  },
  {
    "path": "application/admin/controller/PublicController.php",
    "content": "<?php\n/**\n * \n * @authors 清月曦 (1604583867@qq.com)\n * @date    2017-05-01 11:29:17\n * @version $Id$\n */\nnamespace app\\admin\\controller;\nuse think\\Controller;\n\nuse app\\common\\model\\Admin;\nclass PublicController extends Controller\n{\n    /**\n     * 后台登录\n     * @author 清月曦 (1604583867@qq.com)\n     * @date    2017-05-01 11:29:18\n     * @return   [type]                   [login]\n     */\n\tpublic function login()\n    {\n    \tif (request()->isPost()){\n            $data = input('post.');\n            if (!captcha_check($data['verify'])) {\n                return json(['status' => 0, 'msg' => '验证码不正确！']);\n            }\n            $uid = (new Admin)->login($data['username'], $data['password']);\n\n            if($uid > 0){\n                /*记录session和cookie*/\n                $group_id = Admin::where('id', $uid)->value('group_id');\n\n                $auth = [\n                    'uid'=>$uid,\n                    'group_id'=>$group_id,\n                    'username'=>$data['username'],\n                    'last_login_time'=>date(\"Y-m-d H:i:s\"),\n                ];\n                session('user_auth',$auth);\n                session('user_auth_sign', data_auth_sign($auth));\n                return json(['status' => 1, 'msg' => '登录成功！']);\n            }else{\n                switch ($uid) {\n                    case '-1':\n                        $info = ['status' => 0, 'msg' => '用户不存在或被禁用'];\n                        break;\n                    case '-2':\n                        $info = ['status' => 0, 'msg' => '密码错误'];\n                        break;  \n                    default:\n                        $info = ['status' => 0, 'msg' => '未知错误'];\n                        break;\n                }\n                return json($info);\n            }\n    \t}else{\n            // 检测登录状态\n            if(session('user_auth') && session('user_auth_sign')){\n                $this->redirect('index/index');\n            }\n    \t\treturn view();\n    \t}\n    }\n    /**\n     * 退出登录状态\n     * @author 清月曦 (1604583867@qq.com)\n     * @date    2017-05-01 11:29:19\n     * @return   [type]                   [out]\n     */\n    public function loginout(){\n        session(null);\n        $this->redirect('index/index');\n    }\n}"
  },
  {
    "path": "application/admin/controller/WechatController.php",
    "content": "<?php\nnamespace app\\admin\\controller;\n\nuse think\\Controller;\n\nclass WechatController extends Controller\n{\n    public static $weObj;\n    public static $appUrl;\n    public static $revData;\n    public static $revFrom;\n\n    public function _initialize(){\n        self::$appUrl = request()->root(true);\n    }\n\n    public function init()\n    {\n        vendor(\"dodgepudding.wechat-php-sdk.wechat#class\");\n        $config = model('WxConfig')->find()->toArray();\n\n        $options = array(\n            'token' => $config [\"token\"], //填写你设定的key\n            'encodingaeskey' => $config [\"encodingaeskey\"], //填写加密用的EncodingAESKey\n            'appid' => $config [\"appid\"], //填写高级调用功能的app id\n            'appsecret' => $config [\"appsecret\"] //填写高级调用功能的密钥\n        );\n\n        self::$weObj = new \\Wechat ($options);\n    }\n\n    public function index()\n    {\n        $this->init();\n\n        if (request()->isGet()) {\n            ob_clean();\n            self::$weObj->valid();\n        } else {\n            if (!self::$weObj->valid(true)) {\n                die('no access!!!');\n            }\n        }\n\n        $type = self::$weObj->getRev()->getRevType();\n        self::$revData = self::$weObj->getRevData();\n        self::$revFrom = self::$weObj->getRevFrom();\n        \n        $this->check($type);\n    }\n\n    public function check($type)\n    {\n        switch ($type) {\n            case \\Wechat::MSGTYPE_TEXT:\n                $this->checkKeywords();\n                break;\n            case \\Wechat::MSGTYPE_EVENT:\n                $this->checkEvents(self::$revData['Event']);\n                break;\n            case \\Wechat::MSGTYPE_IMAGE:\n                self::$weObj->text('本系统暂不支持图片信息！')->reply();\n                break;\n            default:\n                self::$weObj->text('本系统暂时无法识别您的指令！')->reply();\n        }\n    }\n\n    public function checkEvents($event)\n    {\n        $openId = self::$revData['FromUserName'];\n        \n        switch ($event) {\n            case 'subscribe':\n                $this->checkUser($openId);\n                $this->checkKeyWords('subscribe');\n                break;\n            case 'unsubscribe':\n                $this->updateUser($openId);\n                break;\n            case 'CLICK':\n                $this->checkKeyWords(self::$revData['EventKey']);\n                break;\n\n        }\n    }\n\n    public function checkKeyWords($key = '')\n    {\n        $key = $key ? $key : self::$weObj->getRev()->getRevContent();\n        if ($key == 'qqkf') {\n            $reply = model('WxReply')->where('key',$key)->find();\n            $qq = $reply[\"remark\"];\n            $str = \"<a href='http://wpa.qq.com/msgrd?v=3&uin=\" . $qq . \"&site=qq&menu=yes&from=singlemessage'>\" . htmlspecialchars_decode('点击联系QQ客服') . \"</a>\";\n            self::$weObj->text($str)->reply();\n            exit();\n        }\n\n        $reply = model('WxReply')->where('key',$key)->find();\n        if ($reply) {\n            if ($reply[\"type\"] == \"news\") {\n                $newsArr = array(\n                    array(\n                        'Title' => $reply[\"title\"],\n                        'Description' => $reply[\"description\"],\n                        'PicUrl' => self::$appUrl . '/public/uploads/' . $reply[\"savepath\"] . $reply[\"savename\"],\n                        'Url' => $reply[\"url\"]\n                    )\n                );\n                self::$weObj->news($newsArr)->reply();\n                exit();\n            } else {\n                self::$weObj->text($reply[\"title\"])->reply();\n                exit();\n            }\n        } else {\n            // self::$weObj->text(\"请核对关键词!\")->reply();\n\n            $this->toKeyUnknow($key);\n        }\n    }\n\n    public function toKeyUnknow($key)\n    {\n        // self::$weObj->text(\"未找到此关键词匹配！\")->reply();\n        //或取所有客服\n        $kfList=self::$weObj->getCustomServiceKFlist();\n        \n        $wx_kefu = model('WxKefu')->find();\n        \n        $kf_account = '';\n        if($wx_kefu['status']){\n            foreach ($kfList['kf_list'] as $k => $value) { \n                if($value['kf_wx'] == $wx_kefu['kefu']){\n                    $kf_account = $value['kf_account'];\n                }\n            } \n        }else{\n            //随即客服\n            $num=rand(0,count($kfList['kf_list'])-1);\n            $kf_account = $kfList['kf_list'][$num]['kf_account'];\n        }\n\n        //获取用户openid；\n        $openid = self::$revData['FromUserName'];\n        \n        self::$weObj->createKFSession($openid,$kf_account,$key);\n    }\n\n    public function checkUser($openId)\n    {\n        $oauth_wx = model('OauthWx')->where('openid',\"$openId\")->find();\n  \n        if ($oauth_wx) {\n            model('OauthWx')->update(['id' => $oauth_wx['id'], 'subscribe' => 1]);\n        }else{\n            $userInfo  = self::$weObj->getUserInfo($openId);\n            $avater_id = action('api/PublicController/getavater',['headimgurl' => $userInfo['headimgurl']]);\n            $user = model('User')->create([\n                'avater_id' => $avater_id,\n                'username' => $userInfo['nickname'],\n            ]);\n            $oauth_wx = model('OauthWx')->create([\n                    'user_id' => $user->id,\n                    'openid' => $openId,\n                    'nickname' => $userInfo['nickname'],\n                    'sex' => $userInfo['sex'],\n                    'city' => $userInfo['city'],\n                    'country' => $userInfo['country'],\n                    'province' => $userInfo['province'],\n                    'language' => $userInfo['language'],\n                    'headimgurl' => $userInfo['headimgurl'],\n                    'subscribe_time' => date(\"Y-m-d h:i:s\"),\n                    'subscribe' => 1,\n                ]);\n\n            model(\"Analysis\")->add(0, 0, 1, 0); //统计\n        }\n    }\n\n    public function updateUser($openId)\n    {\n        $oauth_wx = model('OauthWx')->where('openid',\"$openId\")->find();\n        if ($oauth_wx) {\n            model('OauthWx')->update(['id' => $oauth_wx['id'], 'subscribe' => 0]);\n        }\n    }\n\n    public function getQRCode()\n    {\n        $this->init();\n        $ticket = self::$weObj->getQRCode(\"1\", 1);\n        $qrcode = self::$weObj->getQRUrl($ticket[\"ticket\"]);\n        if ($qrcode) {\n            model('Config')->update(['id' => 1, 'qrcode' => $qrcode]);\n            $this->success(\"生成二维码成功\", \"admin/config/shop\");\n        } else {\n            $this->error(\"生成二维码失败\", \"admin/config/shop\");\n        }\n    }\n\n    public function getMenu()\n    {\n        $this->init();\n\n        self::$weObj->getMenu();\n    }\n\n    public function createWxMenu()\n    {\n        $this->init();\n\n        $menulist = model('WxMenu')->all()->toArray();\n        $menutree = list_to_tree($menulist, 'id', 'pid', 'sub', 'rank', 'desc');\n\n        $newmenu[\"button\"] = array();\n        foreach ($menutree as $k => $v) {\n            if ($v[\"type\"] == \"view\") {\n                if ($v['sub']) {\n                    $sub_button = array();\n                    foreach ($v[\"sub\"] as $kk => $sub) {\n                        if ($sub[\"type\"] == \"view\") {\n                            array_push($sub_button, array('type' => 'view', 'name' => $sub[\"name\"], 'url' => $sub[\"url\"]));\n                        }else{\n                            array_push($sub_button, array('type' => 'click', 'name' => $sub[\"name\"], 'key' => $sub[\"key\"]));\n                        }\n                    }\n                    array_push($newmenu[\"button\"], array('name' => $v[\"name\"], 'sub_button' => $sub_button));\n                }else{\n                    array_push($newmenu[\"button\"], array('type' => 'view', 'name' => $v[\"name\"], 'url' => $v[\"url\"]));\n                }\n            }else{\n                if ($v['sub']) {\n                    $sub_button = array();\n                    foreach ($v[\"sub\"] as $kk => $sub) {\n                        if ($sub[\"type\"] == \"view\") {\n                            array_push($sub_button, array('type' => 'view', 'name' => $sub[\"name\"], 'url' => $sub[\"url\"]));\n                        } else {\n                            array_push($sub_button, array('type' => 'click', 'name' => $sub[\"name\"], 'key' => $sub[\"key\"]));\n                        }\n                    }\n                    array_push($newmenu[\"button\"], array('name' => $v[\"name\"], 'sub_button' => $sub_button));\n                } else {\n                    array_push($newmenu[\"button\"], array('type' => 'click', 'name' => $v[\"name\"], 'key' => $v[\"key\"]));\n                }\n            }\n        }\n\n        $result = self::$weObj->createMenu($newmenu);\n        if ($result) {\n            $this->success(\"重新创建菜单成功!\", \"admin/wx/menu\");\n        } else {\n            $this->error(\"重新创建菜单失败!\", \"admin/wx/menu\");\n        }\n    }\n\n    public function addTplMessageId($id)\n    {\n        $this->init();\n\n        $tempMsg = model('WxTplmsg')->where('template_id_short',$id)->find();\n        if ($tempMsg[\"template_id\"]) {\n            $template_id = $tempMsg[\"template_id\"];\n        } else {\n            $template_id = self::$weObj->addTemplateMessage($id);\n            if ($template_id) {\n                model('WxTplmsg')->update(['id' => $tempMsg['id'], 'template_id' => $template_id]);\n            }\n        }\n        $tempMsg = model('WxTplmsg')->where('template_id_short',$id)->find();\n\n        return $tempMsg;\n    }\n\n    //新订单通知\n    public function sendTplMsgOrder($order_id)\n    {\n        $this->init();\n\n        $tempMsg = $this->addTplMessageId(\"OPENTM201785396\");\n        $order = model('Order')->with('user.wx,contact,delivery,detail')->find($order_id)->toArray();\n        \n        $msg = array();\n        $msg[\"touser\"] = $order['user']['wx']['openid'];\n        $msg[\"template_id\"] = $tempMsg['template_id'];\n        $msg[\"url\"] = \"\";\n        $msg[\"topcolor\"] = \"\";\n        $msg[\"data\"] = array(\n            \"first\" => array(\n                \"value\" => $tempMsg['title'],\n                \"color\" => \"#ff0000\"\n            ),\n            \"keyword1\" => array(\n                \"value\" => $order[\"orderid\"],\n                \"color\" => \"#000000\"\n            ),\n            \"keyword2\" => array(\n                \"value\" => $order[\"payment\"] . \",\" . $order[\"pay_status\"],\n                \"color\" => \"#000000\"\n            ),\n            \"keyword3\" => array(\n                \"value\" => $order[\"totalprice\"],\n                \"color\" => \"#000000\"\n            ),\n            \"keyword4\" => array(\n                \"value\" => $order[\"created_at\"],\n                \"color\" => \"#000000\"\n            ),\n            \"keyword5\" => array(\n                \"value\" => \"姓名:\" . $order[\"contact\"][\"name\"] . \",电话:\" . $order[\"contact\"][\"phone\"] . \",地址: \" . $order[\"contact\"][\"province\"] . $order[\"contact\"][\"city\"] . $order[\"contact\"][\"address\"],\n                \"color\" => \"#000000\"\n            ),\n            \"remark\" => array(\n                \"value\" => $tempMsg['remark'].$order[\"remark\"],\n                \"color\" => \"#ff0000\"\n            ),\n        );\n        if($tempMsg['status']){\n            self::$weObj->sendTemplateMessage($msg);\n        }\n        // $this->sendTplMessageOrderAdmin($order_id);\n    }\n    \n    //员工通知\n    public function sendTplMessageOrderAdmin($order_id)\n    {\n       \n        $this->init();\n         \n        $order = model('Order')->with('user.wx,contact,delivery,detail.product')->find($order_id)->toArray();\n       \n        $tempMsg = $this->addTplMessageId(\"OPENTM201785396\");\n\n        $shop = model(\"Config\")->find();\n       \n        $employee = explode(',', $shop[\"employee\"]);\n      \n        foreach ($employee as $key => $value) {\n            if(!$value){\n                continue;\n            }\n        \n            $openid = model('OauthWx')->where('user_id',$value)->value('openid');\n            $data = '{\n                \"touser\":\"' . $openid . '\",\n                \"template_id\":\"' . $tempMsg['template_id'] . '\",\n                \"url\":\"' . \"http://\" . I(\"server.HTTP_HOST\") . U(\"App/Admin/order\",array(\"id\"=>$order_id)).'\",\n                \"topcolor\":\"#FF0000\",\n                \"data\":{\n                    \"first\": {\n                        \"value\":\"客户新订单提醒\",\n                        \"color\":\"#FF0000\"\n                        },\n                    \"keyword1\":{\n                        \"value\":\"' . $order[\"orderid\"] . '\",\n                        \"color\":\"#0000ff\"\n                        },\n                    \"keyword2\":{\n                        \"value\":\"' . $order[\"payment\"] . '\",\n                        \"color\":\"#0000ff\"\n                        },\n                    \"keyword3\":{\n                        \"value\":\"' . $order[\"totalprice\"] . '\",\n                        \"color\":\"#0000ff\"\n                        },\n                    \"keyword4\":{\n                        \"value\":\"' . $order[\"create_time\"] . '\",\n                        \"color\":\"#0000ff\"\n                        },\n                    \"keyword5\":{\n                        \"value\":\"' . $order[\"contact\"][\"name\"] . '-' . $order[\"contact\"][\"phone\"] . '-' . $order[\"contact\"][\"province\"] . $order[\"contact\"][\"city\"] . $order[\"contact\"][\"address\"] . '\",\n                        \"color\":\"#0000ff\"\n                        },\n                    \"remark\":{\n                        \"value\":\"配送时间：' .$order[\"delivery_time\"].\"备注：\". $order[\"remark\"] . '\",\n                        \"color\":\"#0000ff\"\n                        }\n                }\n            }';\n\n            $data = json_decode($data, true);\n            self::$weObj->sendTemplateMessage($data);\n        }\n    }\n    //订单支付成功通知\n    public function sendTplMsgPay($order_id)\n    {\n        $this->init();\n\n        $tempMsg = $this->addTplMessageId(\"OPENTM207791277\");\n        $order = model('Order')->with('user.wx')->find($order_id)->toArray();\n\n        $msg = array();\n        $msg[\"touser\"] = $order[\"user\"]['wx'][\"openid\"];\n        $msg[\"template_id\"] = $tempMsg['template_id'];\n        $msg[\"url\"] = \"\";\n        $msg[\"topcolor\"] = \"\";\n        $msg[\"data\"] = array(\n            \"first\" => array(\n                \"value\" => $tempMsg['title'],\n                \"color\" => \"#ff0000\"\n            ),\n            \"keyword1\" => array(\n                \"value\" => $order[\"orderid\"],\n                \"color\" => \"#000000\"\n            ),\n            \"keyword2\" => array(\n                \"value\" => $order[\"totalprice\"].'元',\n                \"color\" => \"#000000\"\n            ),\n            \"remark\" => array(\n                \"value\" => $tempMsg[\"remark\"],\n                \"color\" => \"#ff0000\"\n            ),\n        );\n        \n        if($tempMsg['status']){\n            self::$weObj->sendTemplateMessage($msg);\n        }\n    }\n\n    //订单发货提醒\n    public function sendTplMsgOrderPublish($order_id)\n    {\n        $this->init();\n        $tempMsg = $this->addTplMessageId(\"OPENTM207763419\");\n        $order = model('Order')->with('user.wx,detail.product')->find($order_id)->toArray();\n        \n        $detail = '';\n        foreach ($order['detail'] as $key => $value) {\n            if($value['sku_name']){\n                $detail .= '【'.$value['name'].'('.$value['sku_name'].')'.$value['price'].'元x'.$value['num'].'份】';\n            }else{\n                $detail .= '【'.$value['name'].$value['price'].'元x'.$value['num'].'份】';\n            }\n        }\n\n        $msg = array();\n        $msg[\"touser\"] = $order['user']['wx'][\"openid\"];\n        $msg[\"template_id\"] = $tempMsg['template_id'];\n        $msg[\"url\"] = \"\";\n        $msg[\"topcolor\"] = \"\";\n        $msg[\"data\"] = array(\n            \"first\" => array(\n                \"value\" => $tempMsg['title'],\n                \"color\" => \"#ff0000\"\n            ),\n            \"keyword1\" => array(\n                \"value\" => '合计'.$order[\"totalprice\"].'元',\n                \"color\" => \"#000000\"\n            ),\n            \"keyword2\" => array(\n                \"value\" => $detail,\n                \"color\" => \"#000000\"\n            ),\n            \"remark\" => array(\n                \"value\" => $tempMsg[\"remark\"].'|'.$order[\"remark\"],\n                \"color\" => \"#ff0000\"\n            ),\n        );\n\n        if($tempMsg['status']){\n            self::$weObj->sendTemplateMessage($msg);\n        }\n    }\n\n\n\n}"
  },
  {
    "path": "application/admin/controller/article/CategoryController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\article;\nuse app\\admin\\controller\\BaseController;\n\nuse app\\common\\model\\ArticleCategory;\nuse app\\common\\model\\Article;\nclass CategoryController extends BaseController\n{\n\t//文章分类\n\tpublic function index(){\n\t\t$categorylist = ArticleCategory::all()->toArray();\n\t\t\n\t\tcookie(\"prevUrl\", request()->url());\n\n\t\t$tree = list_to_tree($categorylist, 'id', 'pid', 'sub');\n\n\t\t$this->assign('categorylist', $tree);\n\t\treturn view();\n\t}\n\n\t//新增修改文章分类\n\tpublic function add(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\t\t\t$data['status'] = input('?post.status') ? $data['status'] : 0;\n\t\t\t\n\t\t\tif(input('post.id')){\n\t\t\t\t$result = ArticleCategory::update($data);\n\t\t\t}else{\n\t\t\t\t$result = ArticleCategory::create($data);\n\t\t\t}\n\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$id = input('param.id');\n\t\t\tif($id){\n\t\t\t\t$category = ArticleCategory::find($id);\n\t\t\t\t$this->assign('category', $category);\n\t\t\t}\n\t\t\t$parentcategory = ArticleCategory::all(['pid'=>0]);\n            $this->assign(\"parentcategory\", $parentcategory);\n\t\t\treturn view();\n\t\t}\n\t}\n\n\t//改变文章类型状态\n\tpublic function update(){\n\t\t$data = input('param.');\n\t\t$result = ArticleCategory::where('id','in',$data['id'])->update(['status' => $data['status']]);\n\t\tArticle::where('category_id',$data['id'])->update(['status' => $data['status']]);\n\t\tif($result){\n\t\t\t$this->success(\"修改成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('修改失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\n\t//删除文章分类\n\tpublic function del(){\n\t\t$ids = input('param.id');\n\t\t\n\t\t$result = ArticleCategory::destroy($ids);\n\t\tif($result){\n\t\t\t$this->success(\"删除成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('删除失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n}"
  },
  {
    "path": "application/admin/controller/article/IndexController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\article;\nuse app\\admin\\controller\\BaseController;\n\nuse app\\common\\model\\Article;\nuse app\\common\\model\\ArticleCategory;\nclass IndexController extends BaseController\n{\n\t//文章列表\n\tpublic function index(){\n\t\t$articlelist = Article::with('category')->order('id desc')->paginate();\n\t\t\n\t\tcookie(\"prevUrl\", request()->url());\n\n\t\t$this->assign('articlelist', $articlelist);\n\t\treturn view();\n\t}\n\n\t//新增修改文章\n\tpublic function add(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\t\t\t$data['status'] = input('?post.status') ? $data['status'] : 0;\n\t\t\t\n\t\t\tif(input('post.id')){\n\t\t\t\t$result = Article::update($data);\n\t\t\t}else{\n\t\t\t\t$result = Article::create($data);\n\t\t\t}\n\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$id = input('param.id');\n\t\t\tif($id){\n\t\t\t\t$article = Article::find($id);\n\t\t\t\t$this->assign('article', $article);\n\t\t\t}\n\t\t\t$category = ArticleCategory::all()->toArray();\n\t\t\t$tree = list_to_tree($category, 'id', 'pid', 'sub');\n            $this->assign(\"category\", $tree);\n\t\t\treturn view();\n\t\t}\n\t}\n\n\t//改变文章状态\n\tpublic function update(){\n\t\t$data = input('param.');\n\t\t$result = Article::where('id','in',$data['id'])->update(['status' => $data['status']]);\n\t\tif($result){\n\t\t\t$this->success(\"修改成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('修改失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\n\t//删除文章\n\tpublic function del(){\n\t\t$ids = input('param.id');\n\t\t\n\t\t$result = Article::destroy($ids);\n\t\tif($result){\n\t\t\t$this->success(\"删除成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('删除失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\n\n}"
  },
  {
    "path": "application/admin/controller/auth/AdminController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\auth;\nuse app\\admin\\controller\\BaseController;\n\nuse app\\common\\model\\Admin;\nuse app\\common\\model\\AuthGroupAccess;\nclass AdminController extends BaseController\n{ \n    \n\t//管理员列表\n\tpublic function index(){\n\t\t$adminlist = Admin::all();\n\n\t\tcookie(\"prevUrl\", request()->url());\n\n\t\t$this->assign('adminlist', $adminlist);\n\t\treturn view();\n\t}\n\t//新增修改用管理员\n\tpublic function add(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\t\t\tif($data['password']){\n\t\t\t\t$data['password'] = md5($data['password']);\n\t\t\t}else{\n\t\t\t\tunset($data['password']);\n\t\t\t}\n\t\t\tif($data['id']){\n\t\t\t\t$oid = Admin::where('username', $data['username'])->value('id');\n\t\t\t\tif ($oid && $oid != $data['id']){\n\t\t\t\t\t$this->error('用户名已存在', cookie(\"prevUrl\"));\n\t\t\t\t}\n\t\t\t\tif($data['id'] == 1){\n\t\t\t\t\tif($data['id'] == session('user_auth.uid')){\n\t\t\t\t\t\t$result = Admin::update($data);\n\t\t\t\t\t}else{\n\t\t\t\t\t\t$this->error('非超管不能编辑', cookie(\"prevUrl\"));\n\t\t\t\t\t}\n\t\t\t\t}else{\n\t\t\t\t\t$result = Admin::update($data);\n\t\t\t\t\tAuthGroupAccess::where('uid',$data['id'])->update(['group_id' => $data['group_id']]);\n\t\t\t\t}\n\t\t\t}else{\n\t\t\t\t$Admin = new Admin;\n\t\t\t\t$result = $Admin->validate(true)->save($data);\n\t\t\t\tif(false === $result){\n\t\t\t\t    // 验证失败 输出错误信息\n\t\t\t\t    $this->error($Admin->getError(), cookie(\"prevUrl\"));\n\t\t\t\t}\n\t\t\t\t$uid = $Admin->getLastInsID();\n\t\t\t\tAuthGroupAccess::create([\n\t\t\t\t\t'uid' =>  $uid,\n\t\t\t\t\t'group_id' =>  $data['group_id'],\n\t\t\t\t]);\n\t\t\t}\n\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$id = input('param.id');\n\t\t\tif($id){\n\t\t\t\t$admin = Admin::find($id);\n\t\t\t\t$this->assign('admin', $admin);\n\t\t\t}\n\t\t\t$group = model(\"AuthGroup\")->all();\n            $this->assign(\"group\", $group);\n\t\t\treturn view();\n\t\t}\n\t}\n\t//删除用户组\n\tpublic function del(){\n\t\t$ids = input('param.id');\n\t\tif($ids == 1){\n\t\t\t$this->error('默认管理员不允许删除', cookie(\"prevUrl\"));\n\t\t}\n\t\t$result = Admin::destroy($ids);\n\t\tif($result){\n\t\t\tAuthGroupAccess::where('uid','in',$ids)->delete();\n\t\t\t$this->success(\"删除成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('删除失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\n\t//改变管理员状态\n\tpublic function update(){\n\t\t$data = input('param.');\n\t\tif($data['id'] == 1){\n\t\t\t$this->error('默认管理员不允许操作', cookie(\"prevUrl\"));\n\t\t}\n\t\t$result = Admin::where('id', $data['id'])->update(['status' => $data['status']]);\n\t\tif($result){\n\t\t\t$this->success(\"修改成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('修改失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\n\n\n\n}"
  },
  {
    "path": "application/admin/controller/auth/GroupController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\auth;\nuse app\\admin\\controller\\BaseController;\n\nuse app\\common\\model\\AuthGroup;\nuse app\\common\\model\\AuthRule;\nclass GroupController extends BaseController\n{\n\t//用户组列表\n\tpublic function index(){\n\t\t$grouplist = AuthGroup::all();\n\n\t\tcookie(\"prevUrl\", request()->url());\n\n\t\t$this->assign('grouplist', $grouplist);\n\t\treturn view();\n\t}\n\n\t//新增修改用户组\n\tpublic function add(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\t\t\t$data['rules'] = implode(',',$data['rules']);\n\n\t\t\tif(input('post.id')){\n\t\t\t\tif(input('post.id') == 1){\n\t\t\t\t\t$this->error('默认用户组不允许修改', cookie(\"prevUrl\"));\n\t\t\t\t}else{\n\t\t\t\t\t$result = AuthGroup::update($data);\n\t\t\t\t}\n\t\t\t}else{\n\t\t\t\t$result = AuthGroup::create($data);\n\t\t\t}\n\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$id = input('param.id');\n\t\t\tif($id){\n\t\t\t\t$group = AuthGroup::find($id);\n\t\t\t\t$this->assign('group', $group);\n\t\t\t}\n\t\t\t$rule = AuthRule::all();\n            $this->assign(\"rule\", $rule);\n\t\t\treturn view();\n\t\t}\n\t}\n\t//删除用户组\n\tpublic function del(){\n\t\t$ids = input('param.id');\n\t\tif($ids == 1){\n\t\t\t$this->error('默认用户组不允许删除', cookie(\"prevUrl\"));\n\t\t}\n\t\t$result = AuthGroup::destroy($ids);\n\t\tif($result){\n\t\t\t$this->success(\"删除成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('删除失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\t//改变用户组状态\n\tpublic function update(){\n\t\t$data = input('param.');\n\t\tif($data['id'] == 1){\n\t\t\t$this->error('默认用户组不允许操作', cookie(\"prevUrl\"));\n\t\t}\n\t\t$result = AuthGroup::where('id', $data['id'])->update(['status' => $data['status']]);\n\t\tif($result){\n\t\t\t$this->success(\"修改成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('修改失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\n\n}"
  },
  {
    "path": "application/admin/controller/config/MailController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\config;\nuse app\\admin\\controller\\BaseController;\n\nclass MailController extends BaseController\n{\n\t//邮件配置\n\tpublic function index(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\n\t\t\t$result = model('Mail')->update($data);\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$mail = model('Mail')->find();\n\n\t\t\tcookie(\"prevUrl\", request()->url());\n\n\t\t\t$this->assign('mail', $mail);\n\t\t\treturn view();\n\t\t}\n\t}\n\n}"
  },
  {
    "path": "application/admin/controller/config/SiteController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\config;\nuse app\\admin\\controller\\BaseController;\n\nuse app\\common\\model\\Config;\nclass SiteController extends BaseController\n{ \n    \n\t//站点设置\n\tpublic function index(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\t\t\t$result = Config::update($data);\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$config = Config::with('logo')->find();\n\n\t\t\tcookie(\"prevUrl\", request()->url());\n\n\t\t\t$this->assign('config', $config);\n\t\t\treturn view();\n\t\t}\n\t}\n\n\n}"
  },
  {
    "path": "application/admin/controller/config/SmsController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\config;\nuse app\\admin\\controller\\BaseController;\n\nclass SmsController extends BaseController\n{\n\t//邮件配置\n\tpublic function index(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\n\t\t\t$result = model('Sms')->update($data);\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$sms = model('Sms')->find();\n\n\t\t\tcookie(\"prevUrl\", request()->url());\n\n\t\t\t$this->assign('sms', $sms);\n\t\t\treturn view();\n\t\t}\n\t}\n\n}"
  },
  {
    "path": "application/admin/controller/tpl/MailController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\tpl;\nuse app\\admin\\controller\\BaseController;\n\nclass MailController extends BaseController\n{\n\t//邮件模版列表\n\tpublic function index(){\n\t\t$maillist = model('MailTpl')->paginate();\n\t\t// halt($maillist->toArray());\n\t\tcookie(\"prevUrl\", $this->request->url());\n\n\t\t$this->assign('maillist', $maillist);\n\t\treturn view();\n\t}\n\n\t//新增修改邮件模版\n\tpublic function add(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\t\t\tif($data['id']){\n\t\t\t\t$result = model('MailTpl')->update($data);\n\t\t\t}else{\n\t\t\t\t$result = model('MailTpl')->create($data);\n\t\t\t}\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$id = input('param.id');\n\t\t\tif($id){\n\t\t\t\t$mail = model('MailTpl')->find($id);\n\t\t\t\t$this->assign('mail', $mail);\n\t\t\t}\n\t\t\treturn view();\n\t\t}\n\t}\n\n\t//改变邮件模版状态\n\tpublic function update(){\n\t\t$data = input('param.');\n\t\t$result = model('MailTpl')->where('id','in',$data['id'])->update(['status' => $data['status']]);\n\t\tif($result){\n\t\t\t$this->success(\"修改成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('修改失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\n\t//发送测试邮件\n    public function send()\n    {\n    \t$id = input('param.id');\n    \t$mail_tpl = model('MailTpl')->find($id);\n\n    \t$toemail = $mail_tpl['mail'];  \n\t\t$name = $mail_tpl['mail'];//收件人昵称\n\t\t$subject='邮件测试';\n\t\t$code = mt_rand(100000, 999999);//验证码\n\t\t// $mail_tpl = model('MailTpl')->where('type', 'register')->find()->toArray();\n\t\t$content = str_replace(\"\\$code\",$code,$mail_tpl['content']);\n\t\t$result = send_mail($toemail,$name,$subject,$content);\n\t\tif($result){\n            $this->success(\"发送成功\", cookie(\"prevUrl\"));\n        }else{\n        \t$this->success(\"发送失败\", cookie(\"prevUrl\"));\n        }\n    }\n\n\n\n\n\n\n\n\n\n}"
  },
  {
    "path": "application/admin/controller/tpl/ShopController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\tpl;\nuse app\\admin\\controller\\BaseController;\n\nclass ShopController extends BaseController\n{\n\t//商城模版设置\n\tpublic function index(){\n\t\tif (input('param.theme')){\n\t\t\t$theme = input('param.theme');\n\t\t\t\n\t\t\tmodel('Config')->where('id',1)->setField('theme', $theme);\n\t\t\t$this->success(\"设置成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$config = model('Config')->find();\n\t\t\tcookie(\"prevUrl\", $this->request->url());\n\n\t\t\t$themedir = getDir(\"./tpl/theme\");\n\n\t\t\t$this->assign(\"rootUrl\", request()->root(true));\n\t\t\t$this->assign(\"theme\", $themedir);\n\t\t\t$this->assign(\"settheme\", $config[\"theme\"]);\n\t\t\treturn view();\n\t\t}\n\t}\n}"
  },
  {
    "path": "application/admin/controller/tpl/SmsController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\tpl;\nuse app\\admin\\controller\\BaseController;\nuse Flc\\Alidayu\\Client;\nuse Flc\\Alidayu\\App;\nuse Flc\\Alidayu\\Requests\\AlibabaAliqinFcSmsNumSend;\n\nclass SmsController extends BaseController\n{\n\t//短信模版列表\n\tpublic function index(){\n\t\t$smslist = model('SmsTpl')->paginate();\n\t\t// halt($maillist->toArray());\n\t\tcookie(\"prevUrl\", $this->request->url());\n\n\t\t$this->assign('smslist', $smslist);\n\t\treturn view();\n\t}\n\n\t//新增修改短信模版\n\tpublic function add(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\t\t\tif($data['id']){\n\t\t\t\t$result = model('SmsTpl')->update($data);\n\t\t\t}else{\n\t\t\t\t$result = model('SmsTpl')->create($data);\n\t\t\t}\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$id = input('param.id');\n\t\t\tif($id){\n\t\t\t\t$sms = model('SmsTpl')->find($id);\n\t\t\t\t$this->assign('sms', $sms);\n\t\t\t}\n\t\t\treturn view();\n\t\t}\n\t}\n\n\t//开启关闭短信模版\n\tpublic function update(){\n\t\t$data = input('param.');\n\t\t$result = model('SmsTpl')->where('id','in',$data['id'])->update(['status' => $data['status']]);\n\t\tif($result){\n\t\t\t$this->success(\"修改成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('修改失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\n\t//发送测试短信\n    public function send()\n    {   \n    \t$id = input('param.id');\n    \t$tpl = model('SmsTpl')->find($id);\n\n        $config_sms = model('Sms')->find()->toArray();\n        // 配置信息\n        $config = [\n            'app_key'    => $config_sms['app_key'],\n            'app_secret' => $config_sms['app_secret'],\n            // 'sandbox'    => true,  // 是否为沙箱环境，默认false\n        ];\n         \n        $client = new Client(new App($config));\n        $req    = new AlibabaAliqinFcSmsNumSend;\n        $req->setRecNum($tpl['phone'])\n            ->setSmsParam([\n                'code' => mt_rand(100000, 999999)\n            ])\n            ->setSmsFreeSignName($config_sms['sign'])\n            ->setSmsTemplateCode($tpl['template_code']);\n\n        $resp = $client->execute($req);\n        $result = isset($resp->result->success) ? $resp->result->success : false;\n        if($result){\n            $this->success(\"发送成功\", cookie(\"prevUrl\"));\n        }else{\n            $msg = isset($resp->sub_msg) ? $resp->sub_msg : '发送失败,请检查短信配置';\n        \t$this->error($msg, cookie(\"prevUrl\"));\n        }\n    }\n\n\n\n}"
  },
  {
    "path": "application/admin/controller/user/IndexController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\user;\nuse app\\admin\\controller\\BaseController;\n\nuse app\\common\\model\\User;\nclass IndexController extends BaseController\n{\n\t//用户列表\n\tpublic function index(){\n\t\t$map = array();\n\t\tif(input('param.id') != ''){\n            $map['id']  = input('param.id');\n        }\n\t\tif(input('param.name') != ''){\n            $map['username']  = ['like','%'.input('param.name').'%'];\n        }\n        if(input('param.day') != ''){\n            $userlist    = User::whereTime('created_at', input('param.day'))->paginate();\n        }else{\n        \t$userlist    = User::where($map)->order('id desc')->paginate();\n        }\n\n\t\tcookie(\"prevUrl\", $this->request->url());\n\n\t\t$this->assign('userlist', $userlist);\n\t\treturn view();\n\t}\n\n\t//新增修改用户\n\tpublic function add(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\t\t\tif($data['password']){\n\t\t\t\t$data['password'] = md5($data['password']);\n\t\t\t}else{\n\t\t\t\tunset($data['password']);\n\t\t\t}\n\t\t\tif($data['id']){\n\t\t\t\t$result = User::update($data);\n\t\t\t}else{\n\t\t\t\t$result = User::create($data);\n\t\t\t}\n\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$id = input('param.id');\n\t\t\tif($id){\n\t\t\t\t$user = User::find($id);\n\t\t\t\t$this->assign('user', $user);\n\t\t\t}\n\t\t\treturn view();\n\t\t}\n\t}\n\t//删除用户\n\tpublic function del(){\n\t\t$ids = input('param.id');\n\t\tif($ids == 1){\n\t\t\t$this->error('默认用户组允许删除', cookie(\"prevUrl\"));\n\t\t}\n\t\t$result = User::destroy($ids);\n\t\tif($result){\n\t\t\t$this->success(\"删除成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('删除失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\t//改变用户状态\n\tpublic function update(){\n\t\t$data = input('param.');\n\t\tif($data['id'] == 1){\n\t\t\t$this->error('测试用户不允许操作', cookie(\"prevUrl\"));\n\t\t}\n\t\t$result = User::where('id', $data['id'])->update(['status' => $data['status']]);\n\t\tif($result){\n\t\t\t$this->success(\"修改成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('修改失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\n\t//导出用户\n\tpublic function export(){\n\t\t$userlist = User::all()->toArray();\n\n\t\t$data = array(\n\t\t\t'0' => array(\n                '1' => '编号',\n                '2' => '用户名',\n                '3' => '手机号',\n                '9' => '余额',\n                '10' => '积分',\n                '11' => '状态',\n                '12' => '购买量',\n                '13' => '会员等级',\n                '14' => '注册时间',\n            ),\n        );\n\t\tforeach ($userlist as &$v) {\n\t\t\tswitch ($v['status']) {\n\t\t\t\tcase '0':\n\t\t\t\t\t$v['status'] = '禁用';\n\t\t\t\t\tbreak;\n\t\t\t\tcase '1':\n\t\t\t\t\t$v['status'] = '启用';\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t$v['status'] = '未知状态';\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tarray_push($data, array(\n\t\t\t\t'1' => $v['id'],\n                '2' => $v['username'],\n                '3' => $v['phone'],\n                '9' => $v['money'],\n                '10' => $v['score'],\n                '11' => $v['status'],\n                '12' => $v['buy_num'],\n                '13' => $v['level'],\n                '14' => $v['created_at'],\n\t\t\t));\n\t\t}\n\t\texport_to($data,'用户列表');//导出excle\n\t}\n\n\n}"
  },
  {
    "path": "application/admin/controller/user/LevelController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\user;\nuse app\\admin\\controller\\BaseController;\n\nuse app\\common\\model\\UserLevel;\nclass LevelController extends BaseController\n{\n\n\t//等级列表\n\tpublic function index(){\n\t\t$levellist = UserLevel::all();\n\n\t\tcookie(\"prevUrl\", $this->request->url());\n\n\t\t$this->assign('levellist', $levellist);\n\t\treturn view();\n\t}\n\n\n\t//新增修改等级\n\tpublic function add(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\t\t\tif(input('post.id')){\n\t\t\t\t$result = UserLevel::update($data);\n\t\t\t}else{\n\t\t\t\t$result = UserLevel::create($data);\n\t\t\t}\n\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$id = input('param.id');\n\t\t\tif($id){\n\t\t\t\t$level = UserLevel::find($id);\n\t\t\t\t$this->assign('level', $level);\n\t\t\t}\n\t\t\treturn view();\n\t\t}\n\t}\n\n\n}"
  },
  {
    "path": "application/admin/controller/wx/ConfigController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\wx;\nuse app\\admin\\controller\\BaseController;\n\nclass ConfigController extends BaseController\n{\n\t//微信设置\n\tpublic function index(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\n\t\t\t$result = model('WxConfig')->update($data);\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$config = model('WxConfig')->find();\n\t\t\tcookie(\"prevUrl\", request()->url());\n\n\t\t\t$this->assign(\"url\", 'http://' . $_SERVER[\"HTTP_HOST\"] . \"/admin/wechat/index\");\n\t\t\t$this->assign('config', $config);\n\t\t\treturn view();\n\t\t}\n\t}\n\n\n}"
  },
  {
    "path": "application/admin/controller/wx/KefuController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\wx;\nuse app\\admin\\controller\\BaseController;\n\nclass KefuController extends BaseController\n{\n\t//微信客服设置\n\tpublic function index(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\n\t\t\t$result = model('WxKefu')->update($data);\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$kefu = model('WxKefu')->find();\n\t\t\tcookie(\"prevUrl\", request()->url());\n\n\t\t\t$this->assign('kefu', $kefu);\n\t\t\treturn view();\n\t\t}\n\t}\n\n\n}"
  },
  {
    "path": "application/admin/controller/wx/MenuController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\wx;\nuse app\\admin\\controller\\BaseController;\n\nclass MenuController extends BaseController\n{\n\t//微信菜单\n\tpublic function index(){\n\t\t$menulist = model('WxMenu')->all()->toArray();\n\t\tcookie(\"prevUrl\", request()->url());\n\n\t\t$tree = list_to_tree($menulist, 'id', 'pid', 'sub', 'rank', 'desc');\n\n\t\t$this->assign('menulist', $tree);\n\t\treturn view();\n\t}\n\n\t//新增修改微信菜单\n\tpublic function add(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\t\t\tif(input('post.id')){\n\t\t\t\t$result = model('WxMenu')->update($data);\n\t\t\t}else{\n\t\t\t\t$result = model('WxMenu')->create($data);\n\t\t\t}\n\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$id = input('param.id');\n\t\t\tif($id){\n\t\t\t\t$menu = model('WxMenu')->find($id);\n\t\t\t\t$this->assign('menu', $menu);\n\t\t\t}\n\t\t\t$parentmenu = model('WxMenu')->all(['pid'=>0]);\n            $this->assign(\"parentmenu\", $parentmenu);\n\t\t\treturn view();\n\t\t}\n\t}\n\t//删除微信菜单\n\tpublic function del(){\n\t\t$ids = input('param.id');\n\t\t\n\t\t$result = model('WxMenu')->destroy($ids);\n\t\tif($result){\n\t\t\t$this->success(\"删除成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('删除失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\n\n\n}"
  },
  {
    "path": "application/admin/controller/wx/PrintController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\wx;\nuse app\\admin\\controller\\BaseController;\n\nclass PrintController extends BaseController\n{\n\t//微信打印机设置\n\tpublic function index(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\n\t\t\t$result = model('WxPrint')->update($data);\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$print = model('WxPrint')->find();\n\t\t\tcookie(\"prevUrl\", request()->url());\n\n\t\t\t$this->assign('print', $print);\n\t\t\treturn view();\n\t\t}\n\t}\n\n\n}"
  },
  {
    "path": "application/admin/controller/wx/ReplyController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\wx;\nuse app\\admin\\controller\\BaseController;\n\nclass ReplyController extends BaseController\n{\n\t//微信自定义回复\n\tpublic function index(){\n\t\t$replylist = model('WxReply')->with('file')->select()->toArray();\n\n\t\tcookie(\"prevUrl\", request()->url());\n\n\t\t$this->assign('replylist', $replylist);\n\t\treturn view();\n\t}\n\n\t//新增修改自定义回复\n\tpublic function add(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\n\t\t\tif(input('post.id')){\n\t\t\t\t$result = model('WxReply')->update($data);\n\t\t\t}else{\n\t\t\t\t$result = model('WxReply')->create($data);\n\t\t\t}\n\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$id = input('param.id');\n\t\t\tif($id){\n\t\t\t\t$reply = model('WxReply')->with('file')->find($id);\n\t\t\t\t$this->assign('reply', $reply);\n\t\t\t}\n\t\t\treturn view();\n\t\t}\n\t}\n\n\t//删除自定义回复\n\tpublic function del(){\n\t\t$ids = input('param.id');\n\t\t\n\t\t$result = model('WxReply')->destroy($ids);\n\t\tif($result){\n\t\t\t$this->success(\"删除成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('删除失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\n\n\n}"
  },
  {
    "path": "application/admin/controller/wx/TplmsgController.php",
    "content": "<?php\nnamespace app\\admin\\controller\\wx;\nuse app\\admin\\controller\\BaseController;\n\nclass TplmsgController extends BaseController\n{\n\n\t//微信模版消息\n\tpublic function index(){\n\t\t$tplmsglist = model('WxTplmsg')->all();\n\t\t// halt($tplmsglist->toArray());\n\t\tcookie(\"prevUrl\", request()->url());\n\n\t\t$this->assign('tplmsglist', $tplmsglist);\n\t\treturn view();\n\t}\n\n\t//新增编辑模版消息\n\tpublic function add(){\n\t\tif (request()->isPost()){\n\t\t\t$data = input('post.');\n\t\t\t$data['status'] = input('?post.status') ? $data['status'] : 0;\n\t\t\tif($data['id']){\n\t\t\t\t$result = model('WxTplmsg')->update($data);\n\t\t\t}else{\n\t\t\t\t$result = model('WxTplmsg')->create($data);\n\t\t\t}\n\t\t\tif($result){\n\t\t\t\t$this->success(\"保存成功\", cookie(\"prevUrl\"));\n\t\t\t}else{\n\t\t\t\t$this->error('保存失败', cookie(\"prevUrl\"));\n\t\t\t}\n\t\t}else{\n\t\t\t$id = input('param.id');\n\t\t\tif($id){\n\t\t\t\t$tplmsg = model('WxTplmsg')->find($id);\n\t\t\t\t$this->assign('tplmsg', $tplmsg);\n\t\t\t}\n\t\t\treturn view();\n\t\t}\n\t}\n\n\t//改变模版消息状态\n\tpublic function update(){\n\t\t$data = input('param.');\n\t\t$result = model('WxTplmsg')->where('id','in',$data['id'])->update(['status' => $data['status']]);\n\t\tif($result){\n\t\t\t$this->success(\"修改成功\", cookie(\"prevUrl\"));\n\t\t}else{\n\t\t\t$this->error('修改失败', cookie(\"prevUrl\"));\n\t\t}\n\t}\n\n\n\n}"
  },
  {
    "path": "application/admin/validate/Admin.php",
    "content": "<?php\nnamespace app\\admin\\validate;\n\nuse think\\Validate;\n\nclass Admin extends Validate\n{\n    protected $rule =   [\n        'username'  => 'unique:admin', \n    ];\n\n    protected $message  =   [\n        'username.unique' => '用户名已存在',  \n    ];\n\n}"
  },
  {
    "path": "application/admin/view/addons_index.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"box box-default color-palette-box\">\n        <div class=\"box-header with-border\">\n\n            <h3 class=\"box-title\">插件列表</h3>\n        </div>\n        <div class=\"box-body\">\n            {volist name=\"item\" id=\"item\"}\n            <div class=\"row\">\n                <div class=\"col-xs-12\">\n                    <p class=\"lead\">{$item.title}</p>\n                </div>\n                <div class=\"col-xs-12 table-responsive\">\n                    {volist name=\"item.sub\" id=\"addon\"}\n                    <div class=\"col-md-3 col-sm-6 col-xs-12\" style=\"min-width: 300px;\">\n                        <a href=\"{$addon.addons_admin_url}\" target=\"_blank\">\n                            <div class=\"info-box\" style=\"cursor:pointer;border: 1px solid #f7f7f7;box-shadow: none;height: 90px;\">\n                                <span style=\"float: left;width: 90px;text-align: center;line-height: 90px;\">\n                                    <img src=\"{$addon.addons_img_url}\" style=\"height: 60px;\">\n                                </span>\n                                <div class=\"info-box-content\">\n                                    <span class=\"info-box-number\">{$addon.title}</span>\n                                    <small>{$addon.description}</small>\n                                </div>\n                            </div>\n                        </a>\n                    </div>\n                    {/volist}\n                </div>\n            </div>\n            {/volist}\n        </div>\n    </div>\n</section>\n"
  },
  {
    "path": "application/admin/view/addons_shop.html",
    "content": "<iframe src=\"http://addon.wemallshop.com?url={$domain|urlencode}\" allowtransparency=\"true\" id=\"myiframe\"\n        style=\"background-color:transparent;min-height: 800px;\" frameborder=\"0\" width=\"100%\">\n</iframe>\n\n<script type=\"text/javascript\">\n    \n    window.addEventListener('message', function (e) {\n        if (e.origin != 'http://addon.wemallshop.com') {\n            return\n        }\n        var data = JSON.parse(e.data);\n        install(data.path, data.uuid, data.type, data.sort);\n    }, false);\n    \n    function install(path, uuid, type, sort) {\n        console.log('开始下载');\n\n        $.ajax({\n            type: \"post\",\n            url: \"{:url('admin/addons/getFileDownload')}\",\n            data: {\n                path: path,\n                uuid: uuid,\n                type: type,\n                sort: sort\n            },\n            beforeSend: function(XMLHttpRequest){\n                layui.use('layer', function(){\n                    var layer = layui.layer;\n                    layer.msg('正在努力下载...',{icon: 16,time: 20000, shade: [0.5, '#000']});\n                }); \n            },\n            success: function (res) {\n                console.log('下载完成');\n                layui.use('layer', function(){\n                    var layer = layui.layer;\n                    layer.closeAll();\n                    layer.msg(res.msg,{icon: 6,time: 2000, shade: [0.5, '#000']}); \n                });\n                compare();\n            }\n        });\n    }\n    \n    function compare() {\n        $.ajax({\n            type: \"post\",\n            url: \"{:url('admin/addons/compare')}\",\n            data: {\n                // path: path,\n                // filename: filename,\n                // filesize: filesize,\n            },\n            beforeSend: function(XMLHttpRequest){\n                layui.use('layer', function(){\n                    var layer = layui.layer;\n                    layer.msg('正在安装...',{icon: 16,time: 20000, shade: [0.5, '#000']});\n                }); \n            },\n            success: function (res) {\n                if (res.code) {\n                    console.log('安装完成');\n                    layui.use('layer', function(){\n                        var layer = layui.layer;\n                        layer.msg(res.msg,{icon: 6,time: 2000, shade: [0.5, '#000']});\n                    });\n                    location.href=\"{:url('admin/addons/index')}\";\n                }else{\n                    layui.use('layer', function(){\n                        var layer = layui.layer;\n                        layer.alert(res.msg, {icon: 5,title: '安装失败'});\n                    });\n                }\n            }\n        });\n    }\n    \n</script>"
  },
  {
    "path": "application/admin/view/analysis_user.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <!-- ./col -->\n        <div class=\"col-lg-3 col-xs-6\">\n            <!-- small box -->\n            <div class=\"small-box bg-aqua\">\n                <div class=\"inner\">\n                    <h3>{$todayNewUser|default =0}</h3>\n\n                    <p>今日新用户</p>\n                </div>\n                <div class=\"icon\">\n                    <i class=\"ion ion-person-add\"></i>\n                </div>\n                <a href=\"{:url('/admin/user/index/index',array('day'=>date('Y-m-d')))}\" class=\"small-box-footer\">更多详情 <i class=\"fa fa-arrow-circle-right\"></i></a>\n            </div>\n        </div>\n        <!-- ./col -->\n        <div class=\"col-lg-3 col-xs-6\">\n            <!-- small box -->\n            <div class=\"small-box bg-green\">\n                <div class=\"inner\">\n                    <h3>{$yesterdayNewUser|default = 0}</h3>\n\n                    <p>昨日新用户</p>\n                </div>\n                <div class=\"icon\">\n                    <i class=\"ion ion-person-add\"></i>\n                </div>\n                <a href=\"{:url('/admin/user/index/index',array('day'=>date('Y-m-d', strtotime('-1 day'))))}\" class=\"small-box-footer\">更多详情 <i class=\"fa fa-arrow-circle-right\"></i></a>\n            </div>\n        </div>\n        <div class=\"col-lg-3 col-xs-6\">\n            <!-- small box -->\n            <div class=\"small-box bg-yellow\">\n                <div class=\"inner\">\n                    <h3>{$newUserBuyRate|default = '1'}<sup style=\"font-size: 20px\">%</sup></h3>\n\n                    <p>今日新用户购买率</p>\n                </div>\n                <div class=\"icon\">\n                    <i class=\"ion ion-pie-graph\"></i>\n                </div>\n                <a href=\"#\" class=\"small-box-footer\">&nbsp;</a>\n            </div>\n        </div>\n        <div class=\"col-lg-3 col-xs-6\">\n            <!-- small box -->\n            <div class=\"small-box bg-red\">\n                <div class=\"inner\">\n                    <h3>{$buyRate|default = '1'}<sup style=\"font-size: 20px\">%</sup></h3>\n\n                    <p>购买率</p>\n                </div>\n                <div class=\"icon\">\n                    <i class=\"ion ion-pie-graph\"></i>\n                </div>\n                <a href=\"#\" class=\"small-box-footer\">&nbsp;</a>\n            </div>\n        </div>\n        <!-- ./col -->\n    </div>\n\n\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- LINE CHART -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">新用户走势图</h3>\n                </div>\n                <div class=\"box-body\">\n                    <div class=\"chart\">\n                        <canvas id=\"newUserLineChart\" style=\"height:250px\"></canvas>\n                    </div>\n                </div>\n                <!-- /.box-body -->\n            </div>\n            <!-- /.box -->\n        </div>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- LINE CHART -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">用户消费走势图</h3>\n                </div>\n                <div class=\"box-body\">\n                    <div class=\"chart\">\n                        <canvas id=\"userBuyLineChart\" style=\"height:250px\"></canvas>\n                    </div>\n                </div>\n                <!-- /.box-body -->\n            </div>\n            <!-- /.box -->\n        </div>\n    </div>\n</section>\n<script type=\"text/javascript\">\n    $(function () {\n        //Get context with jQuery - using jQuery's .get() method.\n        var ctx = $(\"#newUserLineChart\").get(0).getContext(\"2d\");\n        //This will get the first returned node in the jQuery collection.\n\n        var data = {\n            labels : {$date|default = '1'},\n            datasets : [\n                {\n                    fillColor : \"rgba(220,220,220,0.5)\",\n                    strokeColor : \"rgba(220,220,220,1)\",\n                    pointColor : \"rgba(220,220,220,1)\",\n                    pointStrokeColor : \"#fff\",\n                    data : {$newUserLine|default = '1'}\n                }\n            ]\n        }\n\n        new Chart(ctx).Line(data);\n\n        var ctx = $(\"#userBuyLineChart\").get(0).getContext(\"2d\");\n        //This will get the first returned node in the jQuery collection.\n\n        var data = {\n            labels : {$date|default = '1'},\n            datasets : [\n                {\n                    fillColor : \"rgba(220,220,220,0.5)\",\n                    strokeColor : \"rgba(220,220,220,1)\",\n                    pointColor : \"rgba(220,220,220,1)\",\n                    pointStrokeColor : \"#fff\",\n                    data : {$userBuyLine|default = '1'}\n                }\n            ]\n        }\n\n        new Chart(ctx).Line(data);\n    });\n</script>"
  },
  {
    "path": "application/admin/view/article/category_add.html",
    "content": "<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- general form elements -->\n            <div class=\"box\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">编辑分类</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal layui-form\" action=\"{:url('/admin/article/category/add')}\" method=\"post\" enctype=\"text/plain\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$category.id|default=0}\"\n                               type=\"hidden\">\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">上级菜单</label>\n\n                            <div class=\"col-sm-10\">\n                                <select name=\"pid\" class=\"form-control\">\n                                    <option value=\"0\">一级菜单</option>\n                                    {volist name=\"parentcategory\" id=\"vo\"}\n                                        <option value=\"{$vo.id}\" {eq name=\"vo.id\" value=\"$category.pid|default=''\" }selected{/eq}>{$vo.name}</option>\n                                    {/volist}\n                                </select>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">名称</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"name\" placeholder=\"\" value=\"{$category.name|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">备注</label>\n\n                            <div class=\"col-sm-10\">\n                                <textarea class=\"form-control\" name=\"remark\"\n                                          rows=\"3\">{$category.remark|default=''}</textarea>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">状态</label>\n\n                            <div class=\"col-md-7\">\n                                <input type=\"checkbox\" name=\"status\" lay-skin=\"switch\" value=\"1\"\n                                {notempty name=\"category.status\"}checked{/notempty}>\n                            </div>\n                        </div>\n                    </div>\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <button type=\"button\" class=\"btn btn-block btn-default\" onclick=\"history.go(-1)\">取消\n                            </button>\n                        </div>\n                    </div>\n\n                </form>\n            </div>\n            <!-- /.box -->\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n\t$(function () {\n\t\tlayui.use('form', function() {\n            var form = layui.form();\n            form.render(); //更新全部\n        });\n\t});\n</script>\n"
  },
  {
    "path": "application/admin/view/article/category_index.html",
    "content": "<!-- Main content -->\n<section class=\"content\">\n\t<div class=\"row\">\n\t\t<!-- /.col -->\n\t\t<div class=\"col-md-12\">\n\t\t\t<div class=\"box box-default\">\n\t\t\t\t<div class=\"box-header with-border\">\n\t\t\t\t\t<h3 class=\"box-title\">文章分类</h3>\n\t\t\t\t</div>\n\t\t\t\t<div style=\"margin-top: 10px;\">\n                    <div class=\"btn-group\" style=\"margin-left: 10px;\">\n                        <a href=\"{:url('/admin/article/category/add')}\" class=\"btn btn-danger \">\n\t\t\t\t\t\t\t新增分类\n\t\t\t\t\t\t</a>\n                    </div>\n                </div>\n\t\t\t\t<div class=\"box-body table-responsive\">\n\t\t\t\t\t<table class=\"table table-bordered table-hover\">\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<th class=\"hidden-xs\">\n\t\t\t\t\t\t\t\t\t<label><input onchange=\"checkAll()\" type=\"checkbox\" value=\"\"></label>\n\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t<th>编号</th>\n\t\t\t\t\t\t\t\t<th>名称</th>\n\t\t\t\t\t\t\t\t<th>状态</th>\n\t\t\t\t\t\t\t\t<th>备注</th>\n\t\t\t\t\t\t\t\t<th>操作</th>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t{volist name=\"categorylist\" id=\"category\"}\n\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t<td class=\"hidden-xs\">\n\t\t\t\t\t\t\t\t\t\t<label><input name=\"checkbox\" class=\"check\" type=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t  value=\"{$category.id}\"></label>\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t{$category.id}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t{$category.name}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t<td>\n\t                                    {eq name=\"category.status\" value=\"1\"}\n\t                                    \t<span class=\"label label-success\">开启</span> \n\t                                    {else/}\n\t                                    \t<span class=\"label label-default\">关闭</span> \n\t                                    {/eq}\n\t                                </td>\n\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t{$category.remark}\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t<td class=\"table-action\">\n\t\t\t\t\t\t\t\t\t\t<a href=\"{:url('/admin/article/category/add',array('id'=>$category['id']))}\">编辑</a>\n\t\t\t\t\t\t\t\t\t\t{eq name=\"category.status\" value=\"0\"}\n\t                                    <a href=\"{:url('/admin/article/category/update',array('id'=>$category['id'],'status'=>1))}\">开启</a> \n\t                                    {else}\n\t                                    <a href=\"{:url('/admin/article/category/update',array('id'=>$category['id'],'status'=>0))}\">关闭</a> \n\t                                    {/eq}\n\t                                    <!-- <a href=\"{:url('/admin/article/category/del',array('id'=>$category['id']))}\">删除</a> -->\n\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t{volist name=\"category.sub\" id=\"category1\"}\n\t\t\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t\t\t<td class=\"hidden-xs\">\n\t\t\t\t\t\t\t\t\t\t\t<label><input name=\"checkbox\" class=\"check\" type=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t  value=\"{$category1.id}\"></label>\n\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t\t{$category1.id}\n\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t\t|─{$category1.name}\n\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t<td>\n\t\t                                    {eq name=\"category1.status\" value=\"1\"}\n\t\t                                    \t<span class=\"label label-success\">开启</span> \n\t\t                                    {else/}\n\t\t                                    \t<span class=\"label label-default\">关闭</span> \n\t\t                                    {/eq}\n\t\t                                </td>\n\t\t\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t\t\t{$category1.remark}\n\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t<td class=\"table-action\">\n\t                                        <a href=\"{:url('/admin/article/category/add',array('id'=>$category1['id']))}\">编辑</a>\n\t                                        {eq name=\"category1.status\" value=\"0\"}\n\t\t                                    <a href=\"{:url('/admin/article/category/update',array('id'=>$category1['id'],'status'=>1))}\">开启</a> \n\t\t                                    {else}\n\t\t                                    <a href=\"{:url('/admin/article/category/update',array('id'=>$category1['id'],'status'=>0))}\">关闭</a> \n\t\t                                    {/eq}\n\t                                        <!-- <a href=\"{:url('/admin/article/category/del',array('id'=>$category1['id']))}\">删除</a> -->\n\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t{/volist}\n\t\t\t\t\t\t\t{/volist}\n\t\t\t\t\t\t</tbody>\n\t\t\t\t\t</table>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"box-footer table-responsive\">\n                \t<div class=\"btn-group\">\n                        <button type=\"button\" class=\"btn btn-danger\"\n                                onclick=\"batchUrl('{:url(\\'/admin/article/category/update\\',array(\\'status\\'=>1))}')\">\n                            开启\n                        </button>\n                    </div>\n                    <div class=\"btn-group\">\n                        <button type=\"button\" class=\"btn btn-danger\"\n                                onclick=\"batchUrl('{:url(\\'/admin/article/category/update\\',array(\\'status\\'=>0))}')\">\n                            关闭\n                        </button>\n                    </div>\n                    <!-- <div class=\"btn-group\">\n                        <button type=\"button\" class=\"btn btn-danger\"\n                                onclick=\"batchUrl('{:url(\\'/admin/article/category/del\\')}')\">删除\n                        </button>\n                    </div> -->\n                    <div class=\"pull-right\">\n\t\t\t\t\t</div>\n                </div>\n\t\t\t</div>\n\t\t\t<!-- /. box -->\n\t\t</div>\n\t\t<!-- /.col -->\n\t</div>\n</section>\n<script type=\"text/javascript\">\n\t\n</script>"
  },
  {
    "path": "application/admin/view/article/index_add.html",
    "content": "<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- general form elements -->\n            <div class=\"box\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">编辑文章</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal layui-form\" action=\"{:url('/admin/article/index/add')}\" method=\"post\" enctype=\"text/plain\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$article.id|default=0}\"\n                               type=\"hidden\">\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">分类</label>\n\n                            <div class=\"col-sm-10\">\n                                <select name=\"category_id\" class=\"form-control\">\n                                \t{volist name=\"category\" id=\"category\"}\n                                        <option value=\"{$category.id}\">{$category.name}</option>\n                                        {volist name=\"category.sub\" id=\"sub\"}\n                                            <option value=\"{$sub.id}\">|─{$sub.name}</option>\n                                        {/volist}\n                                    {/volist}\n                                </select>\n                            </div>\n                        </div>\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">标题</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"title\" placeholder=\"\" value=\"{$article.title|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">作者</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"author\" placeholder=\"\" value=\"{$article.author|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">简介</label>\n\n                            <div class=\"col-sm-10\">\n                                <textarea class=\"form-control\" name=\"sub\"\n                                          rows=\"3\">{$article.sub|default=''}</textarea>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">内容</label>\n\n                            <div class=\"col-sm-10\">\n                                 <!-- 加载编辑器的容器 -->\n                                <script id=\"UEditor\" name=\"content\" type=\"text/plain\" style=\"height:400px;\">\n                                    {$article.content|default=''}\n                                </script>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">备注</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"remark\" placeholder=\"\" value=\"{$article.remark|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        \n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">状态</label>\n\n                            <div class=\"col-md-7\">\n                                <input type=\"checkbox\" name=\"status\" lay-skin=\"switch\" value=\"1\"\n                                {notempty name=\"article.status\"}checked{/notempty}>\n                            </div>\n                        </div>\n                    </div>\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <button type=\"button\" class=\"btn btn-block btn-default\" onclick=\"history.go(-1)\">取消\n                            </button>\n                        </div>\n                    </div>\n                </form>\n            </div>\n            <!-- /.box -->\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n    if('{$article.category_id|default=''}'){\n        $('select[name=\"category_id\"]').val('{$article.category_id|default=''}');\n    }\n    \n    $(function () {\n        var editor = new UE.ui.Editor();\n        editor.render(\"UEditor\");\n        layui.use('form', function() {\n            var form = layui.form();\n            form.render(); //更新全部\n        });\n    });\n</script>\n"
  },
  {
    "path": "application/admin/view/article/index_index.html",
    "content": "<!-- Main content -->\n<section class=\"content\">\n\t<div class=\"row\">\n\t\t<!-- /.col -->\n\t\t<div class=\"col-md-12\">\n\t\t\t<div class=\"box box-default\">\n\t\t\t\t<div class=\"box-header with-border\">\n\t\t\t\t\t<h3 class=\"box-title\">文章列表</h3>\n\t\t\t\t</div>\n\t\t\t\t<div style=\"margin-top: 10px;\">\n                    <div class=\"btn-group\" style=\"margin-left: 10px;\">\n                        <a href=\"{:url('/admin/article/index/add')}\" class=\"btn btn-danger \">\n\t\t\t\t\t\t\t新增文章\n\t\t\t\t\t\t</a>\n                    </div>\n                </div>\n\t\t\t\t<div class=\"box-body table-responsive\">\n\t\t\t\t\t<table class=\"table table-bordered table-hover\">\n\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<th class=\"hidden-xs\">\n\t\t\t\t\t\t\t\t\t<label><input onchange=\"checkAll()\" type=\"checkbox\" value=\"\"></label>\n\t\t\t\t\t\t\t\t</th>\n\t\t\t\t\t\t\t\t<th>编号</th>\n\t\t\t\t\t\t\t\t<th>标题</th>\n\t\t\t\t\t\t\t\t<th>分类</th>\n\t\t\t\t\t\t\t\t<th>作者</th>\n\t\t\t\t\t\t\t\t<th>状态</th>\n\t\t\t\t\t\t\t\t<th>备注</th>\n\t\t\t\t\t\t\t\t<th>时间</th>\n\t\t\t\t\t\t\t\t<th>操作</th>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t{volist name=\"articlelist\" id=\"article\"}\n\t\t\t\t\t\t\t<tr>\n\t\t\t\t\t\t\t\t<td class=\"hidden-xs\">\n\t\t\t\t\t\t\t\t\t<label><input name=\"checkbox\" class=\"check\" type=\"checkbox\"\n\t\t\t\t\t\t\t\t\t\t\t\t  value=\"{$article.id}\"></label>\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t{$article.id}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t《{$article.title}》\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t{$article.category.name}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t{$article.author}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td>\n                                    {eq name=\"article.status\" value=\"1\"}\n                                    \t<span class=\"label label-success\">开启</span> \n                                    {else/}\n                                    \t<span class=\"label label-default\">关闭</span> \n                                    {/eq}\n                                </td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t{$article.remark}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td>\n\t\t\t\t\t\t\t\t\t{$article.created_at}\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t<td class=\"table-action\">\n\t\t\t\t\t\t\t\t\t<a href=\"{:url('/admin/article/index/add',array('id'=>$article['id']))}\">编辑</a>\n\t\t\t\t\t\t\t\t\t{eq name=\"article.status\" value=\"0\"}\n                                    <a href=\"{:url('/admin/article/index/update',array('id'=>$article['id'],'status'=>1))}\">开启</a> \n                                    {else}\n                                    <a href=\"{:url('/admin/article/index/update',array('id'=>$article['id'],'status'=>0))}\">关闭</a> \n                                    {/eq}\n\t\t\t\t\t\t\t\t\t<!-- <a href=\"{:url('/admin/article/index/del',array('id'=>$article['id']))}\">删除</a> -->\n\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t{/volist}\n\t\t\t\t\t\t</tbody>\n\t\t\t\t\t</table>\n\t\t\t\t</div>\n\t\t\t\t<div class=\"box-footer table-responsive\">\n\t\t\t\t\t<div class=\"btn-group\">\n                        <button type=\"button\" class=\"btn btn-danger\"\n                                onclick=\"batchUrl('{:url(\\'/admin/article/index/update\\',array(\\'status\\'=>1))}')\">\n                            开启\n                        </button>\n                    </div>\n                    <div class=\"btn-group\">\n                        <button type=\"button\" class=\"btn btn-danger\"\n                                onclick=\"batchUrl('{:url(\\'/admin/article/index/update\\',array(\\'status\\'=>0))}')\">\n                            关闭\n                        </button>\n                    </div>\n\t\t\t\t\t<!-- <div class=\"btn-group\">\n                        <button type=\"button\" class=\"btn btn-danger\"\n                                onclick=\"batchUrl('{:url(\\'/admin/article/index/del\\')}')\">删除\n                        </button>\n                    </div> -->\n\t\t\t\t\t<div class=\"btn-group\">\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"pull-right\">\n\t\t\t\t\t\t{$articlelist->render()}\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<!-- /. box -->\n\t\t</div>\n\t\t<!-- /.col -->\n\t</div>\n</section>\n<script type=\"text/javascript\">\n\t\n</script>"
  },
  {
    "path": "application/admin/view/auth/admin_add.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- general form elements -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">新增/修改管理员</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal layui-form\" action=\"{:url('/admin/auth/admin/add')}\" method=\"post\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$admin.id|default=0}\"\n                               type=\"hidden\">\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">用户组</label>\n\n                            <div class=\"col-sm-10\">\n                                <select name=\"group_id\" class=\"form-control\">\n                                    {volist name=\"group\" id=\"group\"}\n                                        <option value=\"{$group.id}\" {eq name=\"group.id\" value=\"$admin.group_id|default=''\" }selected{/eq}>{$group.title}</option>\n                                    {/volist}\n                                </select>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">用户名</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"username\" required lay-verify=\"required\" placeholder=\"\" value=\"{$admin.username|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">手机号</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"mobile\" placeholder=\"\" lay-verify='phone' value=\"{$admin.mobile|default=''}\"\n                                       type=\"number\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">密码</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"password\" placeholder=\"请输入新密码\" value=\"\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">邮箱</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"email\" placeholder=\"\" lay-verify='email' value=\"{$admin.email|default=''}\"\n                                       type=\"email\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">备注</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"remark\" placeholder=\"\" value=\"{$admin.remark|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        {neq name=\"admin.id|default=0\" value=\"1\"}\n\t                        <div class=\"form-group\">\n\t                            <label class=\"control-label col-md-2\">状态</label>\n\n\t                            <div class=\"col-md-7\">\n\t                                <input type=\"radio\" name=\"status\" value=\"1\" lay-filter=\"type\" title=\"启用\"\n\t                                {eq name=\"admin.status|default='1'\" value=\"1\"}checked{/eq}>\n\t                                <input type=\"radio\" name=\"status\" value=\"0\" lay-filter=\"type\" title=\"禁用\" \n\t                                {eq name=\"admin.status|default=''\" value=\"0\"}checked{/eq}>\n\t                            </div>\n\t                        </div>\n                        {/neq}\n                        <!-- /.box-body -->\n\n                        <div class=\"box-footer\">\n                            <div class=\"col-sm-2\">\n                                <button class=\"btn btn-block btn-danger\" lay-submit lay-filter=\"save\">保存</button>\n                            </div>\n\n                            <div class=\"col-sm-2\">\n                                <button type=\"button\" class=\"btn btn-block btn-default\" onclick=\"history.go(-1)\">取消\n                                </button>\n                            </div>\n                        </div>\n                </form>\n            </div>\n            <!-- /.box -->\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n    $(function () {\n        layui.use('form', function() {\n            var form = layui.form();\n            form.render(); //更新全部\n            //监听提交\n        \tform.on('submit(save)', function(data) {\n\n        \t});\n        });\n    });\n</script>\n"
  },
  {
    "path": "application/admin/view/auth/admin_index.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">管理员管理</h3>\n                </div>\n                <div style=\"margin-top: 10px;\">\n                    <div class=\"btn-group\" style=\"margin-left: 10px;\">\n                        <a href=\"{:url('/admin/auth/admin/add')}\" class=\"btn btn-danger \">\n                            新增管理员\n                        </a>\n                    </div>\n                </div>\n                <div class=\"box-body table-responsive\">\n                    <table class=\"table table-bordered table-hover\">\n                        <tbody>\n                        <tr>\n                            <!-- <th class=\"hidden-xs\">\n                                <label><input onchange=\"checkAll()\" type=\"checkbox\" value=\"\"></label>\n                            </th> -->\n                            <th>编号</th>\n                            <th>用户名</th>\n                            <th>用户组</th>\n                            <th>手机号</th>\n                            <th>邮箱</th>\n                            <th>状态</th>\n                            <th>备注</th>\n                            <th>最后登录时间</th>\n                            <th>操作</th>\n                        </tr>\n                        {volist name=\"adminlist\" id=\"user\"}\n                            <tr>\n                                <!-- <td class=\"hidden-xs\">\n                                    <label><input name=\"checkbox\" class=\"check\" type=\"checkbox\" value=\"{$user.id}\"></label>\n                                </td> -->\n                                <td>{$user.id}</td>\n                                <td>{$user.username}</td>\n                                <td>{$user.group.title}</td>\n                                <td>{$user.mobile}</td>\n                                <td>{$user.email}</td>\n                                <td>\n                                    {eq name=\"user.status\" value=\"1\"}\n                                        <span class=\"label label-success\">启用</span>\n                                    {else/}\n                                        <span class=\"label label-default\">禁用</span>\n                                    {/eq}\n                                </td>\n                                <td>{$user.remark}</td>\n                                <td>{$user.last_login_time}</td>\n                                <td class=\"table-action\">\n                                    <a href=\"{:url('/admin/auth/admin/add',array('id'=>$user['id']))}\">修改</a>\n                                    {gt name=\"user.id\" value=\"1\"}\n                                        {eq name=\"user.status\" value=\"0\"}\n                                            <a href=\"{:url('/admin/auth/admin/update',array('id'=>$user['id'],'status'=>1))}\">开启</a>\n                                        {else}\n                                            <a href=\"{:url('/admin/auth/admin/update',array('id'=>$user['id'],'status'=>0))}\">关闭</a>\n                                        {/eq}\n                                        <a href=\"{:url('/admin/auth/admin/del',array('id'=>$user['id']))}\">删除</a>\n                                    {/gt}\n                                </td>\n                            </tr>\n                        {/volist}\n                        </tbody>\n                    </table>\n                    <!-- <div class=\"box-footer no-padding\"> -->\n                        <!-- <div class=\"mailbox-controls\"> -->\n                            <!-- <div class=\"btn-group\"> -->\n                                <!-- <button type=\"button\" class=\"btn btn-danger\"\n                                        onclick=\"batchUrl('{:url(\\'/admin/auth/admin/del\\')}')\">全部删除\n                                </button> -->\n                            <!-- </div> -->\n                            <!-- /.btn-group -->\n                            <!-- <div class=\"pull-right\"> -->\n                                \n                            <!-- </div> -->\n                            <!-- /.pull-right -->\n                        <!-- </div> -->\n                    <!-- </div> -->\n                </div>\n            </div>\n            <!-- /. box -->\n        </div>\n        <!-- /.col -->\n    </div>\n</section>"
  },
  {
    "path": "application/admin/view/auth/group_add.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- general form elements -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">新增用户组</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal\" action=\"{:url('/admin/auth/group/add')}\" method=\"post\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$group.id|default=0}\"\n                               type=\"hidden\">\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">名称</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"title\" required=\"required\" placeholder=\"\" value=\"{$group.title|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">权限</label>\n\n                            <div class=\"col-sm-10\">\n                                <div class=\"table-responsive\" style=\"overflow-x: visible;\">\n                                    <table class=\"table table-bordered table-hover\">\n                                        <tbody>\n                                        <tr>\n                                            <th style=\"width: 30px\">\n                                                <input onchange=\"checkAll()\" type=\"checkbox\" value=\"\">\n                                            </th>\n                                            <th>编号</th>\n                                            <th>权限标题</th>\n                                            <th>权限</th>\n                                        </tr>\n                                        {volist name=\"rule\" id=\"auth\"}\n                                            <tr>\n                                                <td>\n                                                    <label>\n                                                    <input type=\"checkbox\" name=\"rules[]\" class=\"check\" value=\"{$auth.id|default=''}\"\n                                                        {in name=\"auth.id\" value=\"$group.rules|default=''\"}checked=\"true\"{/in}/>\n                                                    </label>\n                                                </td>\n                                                <td>\n                                                    {$auth.id}\n                                                </td>\n                                                <td>\n                                                    {$auth.title}\n                                                </td>\n                                                <td>\n                                                    {$auth.name}\n                                                </td>\n                                            </tr>\n                                        {/volist}\n                                    </table>\n                                </div>\n                            </div>\n                        </div>\n                        <!-- /.box-body -->\n\n                        <div class=\"box-footer\">\n                            <div class=\"col-sm-2\">\n                                <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                            </div>\n\n                            <div class=\"col-sm-2\">\n                                <button type=\"button\" class=\"btn btn-block btn-default\" onclick=\"history.go(-1)\">取消\n                                </button>\n                            </div>\n                        </div>\n                    </div>\n                </form>\n            </div>\n            <!-- /.box -->\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n    $(function () {\n       \n    });\n</script>\n"
  },
  {
    "path": "application/admin/view/auth/group_index.html",
    "content": "\n<section class=\"content\">\n    <div class=\"row\">\n        <!-- /.col -->\n        <div class=\"col-md-12\">\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">用户组管理</h3>\n                </div>\n                <div style=\"margin-top: 10px;\">\n                    <div class=\"btn-group\" style=\"margin-left: 10px;\">\n                        <a href=\"{:url('/admin/auth/group/add')}\" class=\"btn btn-danger \">\n                            新增用户组\n                        </a>\n                    </div>\n                </div>\n                <div class=\"box-body table-responsive\">\n                    <table class=\"table table-bordered table-hover\">\n                        <tbody>\n                        <tr>\n                            <th>编号</th>\n                            <th>用户组</th>\n                            <th>状态</th>\n                            <th>时间</th>\n                            <th>操作</th>\n                        </tr>\n                        {volist name=\"grouplist\" id=\"group\"}\n                            <tr>\n                                <td>{$group.id}</td>\n                                <td>{$group.title}</td>\n                                <td>\n                                    {eq name=\"group.status\" value=\"1\"}\n                                        <span class=\"label label-success\">启用</span>\n                                    {else/}\n                                        <span class=\"label label-default\">禁用</span>\n                                    {/eq}\n                                </td>\n                                <td>{$group.created_at}</td>\n                                <td class=\"table-action\">\n                                    <a href=\"{:url('/admin/auth/group/add',array('id'=>$group['id']))}\">修改</a>\n                                    {gt name=\"group.id\" value=\"1\"}\n                                        {eq name=\"group.status\" value=\"0\"}\n                                            <a href=\"{:url('/admin/auth/group/update',array('id'=>$group['id'],'status'=>1))}\">开启</a>\n                                        {else}\n                                            <a href=\"{:url('/admin/auth/group/update',array('id'=>$group['id'],'status'=>0))}\">关闭</a>\n                                        {/eq}\n                                        <a href=\"{:url('/admin/auth/group/del',array('id'=>$group['id']))}\">删除</a>\n                                    {/gt}\n                                </td>\n                            </tr>\n                        {/volist}\n                        </tbody>\n                    </table>\n                </div>\n            </div>\n            <!-- /. box -->\n        </div>\n        <!-- /.col -->\n    </div>\n</section>"
  },
  {
    "path": "application/admin/view/config/mail_index.html",
    "content": "<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- general form elements -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">邮件配置</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal layui-form\" method=\"post\" action=\"{:url('/admin/config/mail/index')}\">\n                    <div class=\"box-body\">\n\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$mail.id}\"\n                               type=\"hidden\">\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">服务器地址</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"host\" placeholder=\"\" value=\"{$mail.host}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">服务器端口</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"port\" placeholder=\"\" value=\"{$mail.port}\"\n                                       type=\"number\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">加密</label>\n\n                            <div class=\"col-md-7\">\n                                <input type=\"checkbox\" name=\"secure\" lay-skin=\"switch\" value=\"1\"\n                                {notempty name=\"mail.secure\"}checked{/notempty}>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">回信地址</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"replyTo\" placeholder=\"\" value=\"{$mail.replyTo}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">用户名</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"user\" placeholder=\"\" value=\"{$mail.user}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">密码</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"pass\" placeholder=\"\" value=\"{$mail.pass}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                    </div>\n                    <!-- /.box-body -->\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                        </div>\n                    </div>\n                </form>\n            </div>\n            <!-- /.box -->\n\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n    layui.use('form', function() {\n        var form = layui.form();\n        form.render(); //更新全部\n    });\n</script>\n"
  },
  {
    "path": "application/admin/view/config/site_index.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- general form elements -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">站点设置</h3>\n                </div>\n                <!-- form start -->\n                <form action=\"{:url('/admin/config/site/index')}\" method=\"post\" class=\"form-horizontal layui-form\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$config.id|default='0'}\"\n                               type=\"hidden\">\n \n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">站点名称</label>\n\n                            <div class=\"col-sm-4\">\n                                <input type=\"text\" name=\"title\" required  lay-verify=\"required\" placeholder=\"请输入名称\" autocomplete=\"off\" \n                                class=\"form-control\" value=\"{$config.title|default=''}\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\"></label>\n\n                            <div class=\"col-sm-4\">\n                                站点名称将显示在浏览器的标题栏\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">关键词</label>\n\n                            <div class=\"col-sm-4\">\n                                <input class=\"form-control\" name=\"keywords\" placeholder=\"\" value=\"{$config.keywords|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">站点Logo</label>\n\n                            <div class=\"col-sm-10\">\n                                <div class=\"fileupload fileupload-new\" data-provides=\"fileupload\">\n                                    <div class=\"fileupload-new img-thumbnail\">\n                                        {empty name=\"config.logo_id\"}\n                                            <img src=\"__PUBLIC__/static/dist/img/noimage.gif\">\n                                        {else /}\n                                            <img src=\"__PUBLIC__/uploads/{$config['logo']['savepath']}{$config['logo']['savename']}\">\n                                        {/empty}\n                                        <input class=\"form-control\" name=\"logo_id\" id=\"file_id\" placeholder=\"\" value=\"{$config.logo_id|default=''}\" type=\"hidden\">\n                                        <div class=\"edit_pic_mask\">\n                                            <i class=\"fa fa-plus-circle\" onclick=\"imageUploader(this,false)\"></i>\n                                            <i class=\"fa fa-minus-circle\" onclick=\"removeImage(this,false)\"></i>\n                                        </div>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">站点描述</label>\n\n                            <div class=\"col-sm-6\">\n                                <textarea class=\"form-control\" name=\"description\" placeholder=\"\" rows=\"3\">{$config.description|default=''}</textarea>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">版权</label>\n\n                            <div class=\"col-sm-6\">\n                            \t<input class=\"form-control\" name=\"copyright\" placeholder=\"\" value=\"{$config.copyright|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">统计代码</label>\n\n                            <div class=\"col-sm-6\">\n                                <textarea class=\"form-control\" name=\"tongji_code\" placeholder=\"\" rows=\"3\">{$config.tongji_code|default=''}</textarea>\n                            </div>\n                        </div>\n                    </div>\n                    <!-- /.box-body -->\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button class=\"btn btn-block btn-danger\" lay-submit lay-filter=\"shopSet\">保存</button>\n                        </div>\n                    </div>\n                </form>\n            </div>\n            <!-- /.box -->\n\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n<script>\n    layui.use('form', function() {\n        var form = layui.form();\n        form.render(); //更新全部\n        //监听提交\n        // form.on('submit(shopSet)', function(data) {\n            // console.log(data.field);\n            // layer.msg(JSON.stringify(data.field));\n            // return false;\n        // });\n    });\n</script>\n"
  },
  {
    "path": "application/admin/view/config/sms_index.html",
    "content": "<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <div class=\"callout callout-danger\">\n                <p>目前仅支持阿里大于 网站:\n                    <a href=\"http://www.alidayu.com/\" target=\"_blank\">http://www.alidayu.com/</a>\n                </p>\n                <p>应用管理－应用列表－创建应用</p>\n                <p>配置管理－验证码－配置短信签名－添加签名</p>\n                <p>配置管理－验证码－配置短信模版－添加模版</p>\n            </div>\n            <!-- general form elements -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">短信验证设置</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal\" method=\"post\" action=\"{:url('/admin/config/sms/index')}\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$sms.id}\"\n                               type=\"hidden\">\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">App Key</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"app_key\" placeholder=\"\" value=\"{$sms.app_key}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">App Secret</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"app_secret\" placeholder=\"\" value=\"{$sms.app_secret}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">短信签名</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"sign\" placeholder=\"\" value=\"{$sms.sign}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                    </div>\n                    <!-- /.box-body -->\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                        </div>\n                    </div>\n                </form>\n            </div>\n            <!-- /.box -->\n\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n\n"
  },
  {
    "path": "application/admin/view/file_index.html",
    "content": "<div id=\"dialog-imageUploader\">\n    <!-- /.box-header -->\n    <div class=\"box-body\">\n        <div class=\"row\" style=\"border-bottom:1px solid #f4f4f4;\">\n            <div class=\"margin pull-right\">\n                <form action=\"{:url('admin/file/upload')}\" id=\"myForm\" enctype=\"multipart/form-data\" method=\"post\">\n                    <div class=\"btn btn-success\" style=\"cursor: pointer\">本地上传</div>\n                    <input type=\"file\" id=\"file\" name=\"image[]\" multiple=\"multiple\" onchange=\"ajaxForm()\"\n                           style=\"margin-top: -30px;width: 82px;height: 34px;opacity: 0;cursor: pointer;\"/>\n                </form>\n            </div>\n        </div>\n        <div class=\"row\" id=\"dialog-content\">\n            {volist name=\"filelist\" id=\"file\"}\n                <div class=\"margin\" style=\"width: 120px;height: 120px;float: left;text-align: center;line-height: 120px;\">\n                    <img class=\"img-thumbnail\" style=\"max-width: 120px; max-height: 120px;\"\n                         onclick=\"selectImage(this,'{$file.id}')\"\n                         src=\"__PUBLIC__/uploads/{$file.savepath}{$file.savename}\">\n\n                    <div class=\"cover\" onclick=\"cancelSelectImage(this,'{$file.id}')\"></div>\n                </div>\n            {/volist}\n        </div>\n    </div>\n    <!-- /.box-body -->\n    <div class=\"box-footer clearfix\">\n        {$page}\n    </div>\n</div>\n<script type=\"text/javascript\">\n    $('#dialog-imageUploader .pagination a[href]').attr('onclick', 'tabPage(this)');\n</script>"
  },
  {
    "path": "application/admin/view/help_index.html",
    "content": "<style type=\"text/css\">\n\t#bodybox {\n\t    margin: 0 auto 10% auto;\n\t    width: 100%;\n\t    max-width: 640px;\n\t}\n\t.content-div {\n\t    background: #5cb3ff;\n\t    color: #fff;\n\t    padding: 5px 10px;\n\t    border-top-right-radius: 20px;\n\t    border-bottom-right-radius: 20px;\n\t    line-height: 30px;\n\t}\n\t#bodybox img {\n\t    width: 95%;\n\t    margin-top: 5%;\n\t    margin-left: 2.5%;\n\t}\n\tp {\n\t    margin-left: 10px;\n\t    text-indent: 2em;\n\t}\n\th2 {\n\t    text-align: center;\n\t}\n\t.text-center {\n\t    text-align: center;\n\t}\n</style>\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"box box-default color-palette-box\">\n        <div class=\"box-header with-border\">\n\n            <h3 class=\"box-title\">使用帮助</h3>\n        </div>\n        <div class=\"box-body\" id=\"bodybox\">\n        \t<span class=\"content-div\">第一步：对接公众号URL和Token</span>\n        \t<p>打开后台系统中系统设置项下面的微信设置，找到微信token项以及它下面的那串url地址（注：token类似于密码，token可以自己修改）。</p>\n\t\t    <img src=\"__PUBLIC__/static/dist/img/help/image1.png\" />\n\t\t    <p class=\"text-center\">图1 后台token对应位置</p>\n\t\t    <p>打开微信官方公众后台（https://mp.weixin.qq.com）,登陆自己的公众号，进入到开发者模式模块，启用开发者模式，填写URL和Token两项（就是图1中的相关值）</p>\n\t\t    <img src=\"__PUBLIC__/static/dist/img/help/image2.png\" />\n\t\t    <p class=\"text-center\">图2 配置微信后台</p>\n\n\t\t    <span class=\"content-div\">第二步：对接appid和AppSecret及微信支付参数</span>\n\t\t    <p>在微信公众后台可看到该公众号的appid和AppSecret，把这两项复制到后台系统中的对应位置。 微信支付参数设置同上述，将相关信息复制进对应位置。\n\t\t    </p>\n\t\t    <img src=\"__PUBLIC__/static/dist/img/help/image3.png\" />\n\t\t    <p class=\"text-center\">图3 系统后台对应位置</p>\n\t\t    <img src=\"__PUBLIC__/static/dist/img/help/image4.png\" />\n\t\t    <p class=\"text-center\">图4 微信appid和AppSecret</p>\n\n\t\t    <span class=\"content-div\">第三步：设置自定义菜单</span>\n\t\t    <p>建议设置项：</p>\n\t\t    <p>商城首页：http://<?php echo $_SERVER['HTTP_HOST'];?>__ROOT__/app/index/index</p>\n\n\t\t    <span class=\"content-div\">第四步：设置首次关注回复图片或文字</span>\n\t\t    <img src=\"__PUBLIC__/static/dist/img/help/image5.png\" />\n\t\t    <p class=\"text-center\">图5 系统后台对应微信设置</p>\n\t\t    <p>若需设置首次关注的图片，开启对应功能并上传对应图片。如果没开启，系统会去查询是否设置首次关注对应的描述，如果仍未设置，则不会有系统首次关注的回复。</p>\n\n\t\t    <span class=\"content-div\">第五步：可设置qq客服</span>\n\t\t    <img src=\"__PUBLIC__/static/dist/img/help/image6.png\" />\n\t\t    <p class=\"text-center\">图5 系统后台对应设置</p>\n        </div>\n    </div>\n</section>\n"
  },
  {
    "path": "application/admin/view/index_index.html",
    "content": "\n<section class=\"content\">\n    <div class=\"row\">\n        <!-- ./col -->\n        <div class=\"col-lg-3 col-xs-6\">\n            <!-- small box -->\n            <div class=\"small-box bg-aqua\">\n                <div class=\"inner\">\n                    <h3>{$todayUser|default =0}</h3>\n\n                    <p>今日新用户</p>\n                </div>\n                <div class=\"icon\">\n                    <i class=\"ion ion-person-stalker\"></i>\n                </div>\n                <a href=\"{:url('/admin/user/index/index',array('day'=>'today'))}\" class=\"small-box-footer\">更多详情 <i class=\"fa fa-arrow-circle-right\"></i></a>\n            </div>\n        </div>\n        <!-- ./col -->\n        <div class=\"col-lg-3 col-xs-6\">\n            <!-- small box -->\n            <div class=\"small-box bg-green\">\n                <div class=\"inner\">\n                    <h3>{$weekUser|default = 0}</h3>\n\n                    <p>本周新用户</p>\n                </div>\n                <div class=\"icon\">\n                    <i class=\"ion ion-person-stalker\"></i>\n                </div>\n                <a href=\"{:url('/admin/user/index/index',array('day'=>'week'))}\" class=\"small-box-footer\">更多详情 <i class=\"fa fa-arrow-circle-right\"></i></a>\n            </div>\n        </div>\n        <div class=\"col-lg-3 col-xs-6\">\n            <!-- small box -->\n            <div class=\"small-box bg-yellow\">\n                <div class=\"inner\">\n                    <h3>{$monthUser|default = 0}</h3>\n\n                    <p>本月新用户</p>\n                </div>\n                <div class=\"icon\">\n                    <i class=\"ion ion-person-stalker\"></i>\n                </div>\n                <a href=\"{:url('/admin/user/index/index',array('day'=>'month'))}\" class=\"small-box-footer\">更多详情 <i class=\"fa fa-arrow-circle-right\"></i></a>\n            </div>\n        </div>\n        <div class=\"col-lg-3 col-xs-6\">\n            <!-- small box -->\n            <div class=\"small-box bg-red\">\n                <div class=\"inner\">\n                    <h3>{$totalUser|default = 0}</h3>\n\n                    <p>总用户</p>\n                </div>\n                <div class=\"icon\">\n                    <i class=\"ion ion-person-stalker\"></i>\n                </div>\n                <a href=\"{:url('/admin/user/index/index',array('day'=>''))}\" class=\"small-box-footer\">更多详情 <i class=\"fa fa-arrow-circle-right\"></i></a>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- LINE CHART -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">新用户走势图</h3>\n                </div>\n                <div class=\"box-body\">\n                    <div class=\"chart\">\n                        <canvas id=\"newUserLineChart\" style=\"height:250px\"></canvas>\n                    </div>\n                </div>\n                <!-- /.box-body -->\n            </div>\n            <!-- /.box -->\n        </div>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <div class=\"box box-danger\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">系统信息</h3>\n                </div>\n                <div class=\"box-body\">\n                    <blockquote style=\"font-size: 13.5px;padding-left: 10px;\">\n                        THINKPHP版本：{$Think.THINK_VERSION}<br/>\n                        服务器IP：{$Think.server.SERVER_ADDR}<br/>\n                        服务器系统：<?php echo PHP_OS ?><br/>\n                        PHP版本：<?php echo PHP_VERSION ?><br/>\n                        当前时间：<?php echo (date(\"Y-m-d H:i:s\",time())); ?><br/>\n                        官网网址：<a href=\"http://www.wemallshop.com\" target=\"_black\">http://www.wemallshop.com</a><br/>\n                    </blockquote>\n                </div>\n            </div>\n        </div>\n    </div>\n\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <i class=\"fa fa-bullhorn\"></i>\n                    <h3 class=\"box-title\">通知列表</h3>\n                </div>\n                <!-- /.box-header -->\n                <div class=\"box-body\">\n                    {volist name=\"newsList.data\" id=\"news\"}\n                        <div class=\"attachment-block clearfix\" style=\"background-color: #fff\">\n                            <img class=\"attachment-img\" src=\"{$url}public/uploads/{$news.file.savepath}{$news.file.savename}\" alt=\"Attachment Image\" style=\"width: 105px;height: 60px\">\n                            <div class=\"attachment-pushed\">\n                                <h3 class=\"attachment-heading\" style=\"line-height: 60px\">\n                                    <a href=\"{$url}cms/article/{$news.pinyin}\" target=\"_black\" style=\"font-weight: 500;\">{$news.title}</a>\n                                </h3>\n                                <!-- <div class=\"attachment-text\"> -->\n                                    <!-- {$news.sub}{$news.created_at} -->\n                                    <!-- <a href=\"{$url}cms/article/{$news.pinyin}\" target=\"_black\">点击查看</a> -->\n                                <!-- </div> -->\n                            </div>\n                        </div>\n                    {/volist}\n                </div>\n            </div>\n        </div>\n    </div>\n\n\n\n\n\n\n\n\n\n\n\n</section>\n\n<script type=\"text/javascript\">\n    $(function () {\n        //Get context with jQuery - using jQuery's .get() method.\n        var ctx = $(\"#newUserLineChart\").get(0).getContext(\"2d\");\n        //This will get the first returned node in the jQuery collection.\n\n        var data = {\n            labels : {$date|default = '1'},\n            datasets : [\n                {\n                    fillColor : \"rgba(220,220,220,0.5)\",\n                    strokeColor : \"rgba(220,220,220,1)\",\n                    pointColor : \"rgba(220,220,220,1)\",\n                    pointStrokeColor : \"#fff\",\n                    data : {$newUserLine|default = '1'}\n                }\n            ]\n        }\n\n        new Chart(ctx).Line(data);\n    });\n</script>\n"
  },
  {
    "path": "application/admin/view/layout.html",
    "content": "{include file=\"./application/admin/view/public_header.html\" /}\n\n<body class=\"hold-transition skin-red-light\">\n    <div class=\"wrapper\">\n        <header class=\"main-header\" style=\"position: fixed;width: 100%;background-color: white;z-index: 99;border-bottom: 1px solid #eeeeee;\">\n            <!-- Header Navbar: style can be found in header.less -->\n            <nav class=\"navbar navbar-static-top\" role=\"navigation\">\n                <!-- Sidebar toggle button-->\n                <a href=\"javascript:void(0)\" class=\"sidebar-toggle\" id=\"sidebar-menu-title\"></a>\n                <div class=\"navbar-custom-menu\">\n                    <ul class=\"nav navbar-nav\">\n                        <!-- Messages: style can be found in dropdown.less-->\n                        <!--信息通知-->\n                        <li class=\"dropdown messages-menu\">\n                            <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">\n                                <i class=\"fa fa-envelope-o\"></i>\n                            </a>\n                            <ul class=\"dropdown-menu\">\n                            </ul>\n                        </li>\n                        <!-- Notifications: style can be found in dropdown.less -->\n                        <li class=\"dropdown notifications-menu\">\n                            <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">\n                                <i class=\"fa fa-bell-o\"></i>\n                            </a>\n                            <ul class=\"dropdown-menu\">\n                            </ul>\n                        </li>\n                        <!-- User Account: style can be found in dropdown.less -->\n                        <li class=\"dropdown user user-menu\">\n                            <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">\n                                <img src=\"__PUBLIC__/static/dist/img/avatar-wemall.png\" class=\"user-image\" alt=\"User Image\">\n                                <span class=\"hidden-xs\">{$Think.session.user_auth.username}</span>\n                            </a>\n                            <ul class=\"dropdown-menu\">\n                                <!-- User image -->\n                                <!-- <li class=\"user-header\">\n                                    <img src=\"__PUBLIC__/static/dist/img/avatar-wemall.png\" class=\"img-circle\" alt=\"User Image\">\n                                    <p>\n                                        {$Think.session.user_auth.username}\n                                        <small>管理员</small>\n                                    </p>\n                                </li> -->\n                                <!-- Menu Footer-->\n                                <li class=\"user-footer\">\n                                    <a href=\"{:url('admin/public/loginout')}\" target=\"_self\" class=\"btn btn-default btn-flat\">注销</a>\n                                </li>\n                            </ul>\n                        </li>\n                    </ul>\n                </div>\n            </nav>\n        </header>\n        <!-- Left side column. contains the logo and sidebar -->\n        <aside class=\"main-sidebar\" style=\"background-color: #444;\">\n            <!-- sidebar: style can be found in sidebar.less -->\n            <section class=\"sidebar\">\n                <div class=\"team-logo\" style=\"background-image: url(__PUBLIC__/static/dist/img/avatar-wemall.png)\"></div>\n                <!-- Sidebar user panel -->\n                <!-- sidebar menu: : style can be found in sidebar.less -->\n                <ul class=\"sidebar-menu\" id=\"sidebar-menu\" style=\"margin-top: 24px\">\n                    {include file=\"./application/admin/view/public_left.html\" /}\n                </ul>\n            </section>\n            <!-- /.sidebar -->\n        </aside>\n        <aside class=\"main-sidebar\" style=\"margin-left: 90px;width: 110px;border-right: 1px solid #eeeeee;\">\n            <ul class=\"sidebar-menu\" style=\"margin-top: 6px\" id=\"sidebar-menu-sub\">\n                <!--sidebar-menu-sub container-->\n            </ul>\n        </aside>\n        <!-- Content Wrapper. Contains page content -->\n        <div class=\"content-wrapper\" id=\"pjax-container\" style=\"padding-top: 50px;\">\n            {__CONTENT__}\n        </div>\n        <!-- /.content-wrapper -->\n        <footer class=\"main-footer\">\n            <div class=\"pull-right hidden-xs\">\n                <b>Version</b>7.0.0\n            </div>\n            <strong>Copyright &copy; 2014-2017 <a href=\"http://wemallshop.com/\" target=\"_blank\">wemallshop.com</a>.</strong> All rights reserved.\n        </footer>\n    </div>\n    {include file=\"./application/admin/view/public_footer.html\" /}\n\n\n"
  },
  {
    "path": "application/admin/view/layout_addons.html",
    "content": "{include file=\"./application/admin/view/public_header.html\" /}\n\n<body class=\"hold-transition skin-red-light\">\n    <div class=\"wrapper\">\n        <header class=\"main-header\" style=\"position: fixed;width: 100%;background-color: white;z-index: 99;border-bottom: 1px solid #eeeeee;\">\n            <!-- Header Navbar: style can be found in header.less -->\n            <nav class=\"navbar navbar-static-top\" role=\"navigation\">\n                <!-- Sidebar toggle button-->\n                <a href=\"javascript:void(0)\" class=\"sidebar-toggle\" id=\"sidebar-menu-title\"></a>\n                <div class=\"navbar-custom-menu\">\n                    <ul class=\"nav navbar-nav\">\n                        <!-- Messages: style can be found in dropdown.less-->\n                        <!--信息通知-->\n                        <li class=\"dropdown messages-menu\">\n                            <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">\n                                <i class=\"fa fa-envelope-o\"></i>\n                            </a>\n                            <ul class=\"dropdown-menu\">\n                            </ul>\n                        </li>\n                        <!-- Notifications: style can be found in dropdown.less -->\n                        <li class=\"dropdown notifications-menu\">\n                            <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">\n                                <i class=\"fa fa-bell-o\"></i>\n                            </a>\n                            <ul class=\"dropdown-menu\">\n                            </ul>\n                        </li>\n                        <!-- User Account: style can be found in dropdown.less -->\n                        <li class=\"dropdown user user-menu\">\n                            <a href=\"#\" class=\"dropdown-toggle\" data-toggle=\"dropdown\">\n                                <img src=\"__PUBLIC__/static/dist/img/avatar-wemall.png\" class=\"user-image\" alt=\"User Image\">\n                                <span class=\"hidden-xs\">{$Think.session.user_auth.username}</span>\n                            </a>\n                            <ul class=\"dropdown-menu\">\n                                <!-- User image -->\n                                <!-- <li class=\"user-header\">\n                                    <img src=\"__PUBLIC__/static/dist/img/avatar-wemall.png\" class=\"img-circle\" alt=\"User Image\">\n                                    <p>\n                                        {$Think.session.user_auth.username}\n                                        <small>管理员</small>\n                                    </p>\n                                </li> -->\n                                <!-- Menu Footer-->\n                                <li class=\"user-footer\">\n                                    <a href=\"{:url('admin/public/loginout')}\" target=\"_self\" class=\"btn btn-default btn-flat\">注销</a>\n                                </li>\n                            </ul>\n                        </li>\n                    </ul>\n                </div>\n            </nav>\n        </header>\n        <!-- Left side column. contains the logo and sidebar -->\n        <aside class=\"main-sidebar\" style=\"background-color: #444;\">\n            <!-- sidebar: style can be found in sidebar.less -->\n            <section class=\"sidebar\">\n                <div class=\"team-logo\" style=\"background-image: url(__PUBLIC__/static/dist/img/avatar-wemall.png)\"></div>\n                <!-- Sidebar user panel -->\n                <!-- sidebar menu: : style can be found in sidebar.less -->\n                <ul class=\"sidebar-menu\" id=\"sidebar-menu\" style=\"margin-top: 24px\">\n                    {include file=\"public/left\" /}\n                </ul>\n            </section>\n            <!-- /.sidebar -->\n        </aside>\n        <aside class=\"main-sidebar\" style=\"margin-left: 90px;width: 110px;border-right: 1px solid #eeeeee;\">\n            <ul class=\"sidebar-menu\" style=\"margin-top: 6px\" id=\"sidebar-menu-sub\">\n                <!--sidebar-menu-sub container-->\n            </ul>\n        </aside>\n        <!-- Content Wrapper. Contains page content -->\n        <div class=\"content-wrapper\" id=\"pjax-container\" style=\"padding-top: 50px;\">\n            {__CONTENT__}\n        </div>\n        <!-- /.content-wrapper -->\n        <footer class=\"main-footer\">\n            <div class=\"pull-right hidden-xs\">\n                <b>Version</b> 7.0.0\n            </div>\n            <strong>Copyright &copy; 2014-2017 <a href=\"http://wemallshop.com/\" target=\"_blank\">wemallshop.com</a>.</strong> All rights reserved.\n        </footer>\n    </div>\n    {include file=\"./application/admin/view/public_footer.html\" /}\n\n\n"
  },
  {
    "path": "application/admin/view/public_footer.html",
    "content": "<!-- Bootstrap 3.3.5 -->\n<script src=\"__PUBLIC__/static/plugins/bootstrap/js/bootstrap.min.js\"></script>\n<!-- Select2 -->\n<script src=\"__PUBLIC__/static/plugins/select2/select2.full.js\"></script>\n<!-- ChartJS 1.0.1 -->\n<script src=\"__PUBLIC__/static/plugins/chartjs/Chart.min.js\"></script>\n<!-- daterangepicker -->\n<script src=\"__PUBLIC__/static/dist/js/moment.min.js\"></script>\n<script src=\"__PUBLIC__/static/plugins/daterangepicker/daterangepicker.js\"></script>\n<!-- datepicker -->\n<script src=\"__PUBLIC__/static/plugins/datepicker/bootstrap-datepicker.js\"></script>\n<!-- bootstrap time picker -->\n<script src=\"__PUBLIC__/static/plugins/timepicker/bootstrap-timepicker.min.js\"></script>\n<!-- Slimscroll -->\n<script src=\"__PUBLIC__/static/plugins/slimScroll/jquery.slimscroll.min.js\"></script>\n<!-- FastClick -->\n<script src=\"__PUBLIC__/static/plugins/fastclick/fastclick.min.js\"></script>\n<!-- AdminLTE App -->\n<script src=\"__PUBLIC__/static/dist/js/app.js?v=6\"></script>\n<!--layer-->\n<!-- <script src=\"__PUBLIC__/static/plugins/layer/layer.js\"></script> -->\n<!--toastr-->\n<script src=\"__PUBLIC__/static/plugins/toastr/toastr.min.js\"></script>\n<!--bootbox-->\n<script src=\"__PUBLIC__/static/plugins/bootbox/bootbox.js\"></script>\n<!--pjax-->\n<script src=\"__PUBLIC__/static/plugins/pjax/jquery.pjax.js\"></script>\n<!--jquery.form-->\n<script src=\"__PUBLIC__/static/plugins/form/jquery.form.js\"></script>\n<!--wangeditor-->\n<!-- <link rel=\"stylesheet\" type=\"text/css\" href=\"__PUBLIC__/static/plugins/wangeditor/css/wangEditor.css\"> -->\n<!-- <script src=\"__PUBLIC__/static/plugins/wangeditor/js/wangEditor.js\"></script> -->\n\n<!--时间-->\n<script src=\"__PUBLIC__/static/plugins/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js\"></script>\n<script src=\"__PUBLIC__/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.zh-CN.js\"></script>\n\n<!--ueditor-->\n<!-- <script type=\"text/javascript\" src=\"/public/ueditor/ueditor.config.js\"></script> -->\n<!-- <script type=\"text/javascript\" src=\"/public/ueditor/ueditor.all.min.js\"></script> -->\n<!--地图-->\n<script type=\"text/javascript\" src=\"http://webapi.amap.com/maps?v=1.3&key=8daf0e161f44e7900d2193f85c5cfe1f&plugin=AMap.DistrictSearch\"></script>\n<script src=\"__PUBLIC__/static/dist/js/wemall.js?v=114\"></script>\n</body>\n</html>"
  },
  {
    "path": "application/admin/view/public_header.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <title>wemall商城后台管理</title>\n    <!-- Tell the browser to be responsive to screen width -->\n    <meta content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\" name=\"viewport\">\n    <!-- Bootstrap 3.3.5 -->\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/plugins/bootstrap/css/bootstrap.min.css?v=1\">\n    <!-- Font Awesome -->\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/dist/css/font-awesome.min.css\">\n    <!-- Ionicons -->\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/dist/css/ionicons.min.css\">\n    <!-- Select2 -->\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/plugins/select2/select2.min.css\">\n    <!-- Theme style -->\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/dist/css/AdminLTE.css?v=1\">\n    <!-- Date Picker -->\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/plugins/datepicker/datepicker3.css\">\n    <!-- Daterange picker -->\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/plugins/daterangepicker/daterangepicker-bs3.css\">\n    <!-- Bootstrap time Picker -->\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/plugins/timepicker/bootstrap-timepicker.min.css\">\n    <!-- layui -->\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/layui/css/layui.css?v=2\">\n\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/plugins/bootstrap-datetimepicker/css/bootstrap-datetimepicker.css\">\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n    <script src=\"__PUBLIC__/static/dist/js/html5shiv.min.js\"></script>\n    <script src=\"__PUBLIC__/static/dist/js/respond.min.js\"></script>\n    <![endif]-->\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/plugins/toastr/toastr.min.css\">\n    <!-- jQuery 2.1.4 -->\n    <script src=\"__PUBLIC__/static/plugins/jQuery/jQuery-2.2.0.min.js\"></script>\n    <!-- layui -->\n    <script src=\"__PUBLIC__/static/layui/layui.js?v=2\"></script>\n    <!--ueditor-->\n    <script type=\"text/javascript\" charset=\"utf-8\" src=\"__PUBLIC__/static/ueditor/ueditor.config.js?v=1\"></script>\n    <script type=\"text/javascript\" charset=\"utf-8\" src=\"__PUBLIC__/static/ueditor/ueditor.all.min.js\"></script>\n    <!--建议手动加在语言，避免在ie下有时因为加载语言失败导致编辑器加载失败-->\n    <!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型，比如你在配置项目里配置的是英文，这里加载的中文，那最后就是中文-->\n    <script type=\"text/javascript\" charset=\"utf-8\" src=\"__PUBLIC__/static/ueditor/lang/zh-cn/zh-cn.js\"></script>\n    <script type=\"text/javascript\" charset=\"utf-8\" src='__PUBLIC__/static/plugins/nprogress/nprogress.js'></script>\n    <link rel='stylesheet' href='__PUBLIC__/static/plugins/nprogress/nprogress.css'/>\n    <!-- Ionicons -->\n    <!-- <link rel=\"stylesheet\" href=\"__PUBLIC__/static/zTree/css/zTreeStyle/zTreeStyle.css\"> -->\n    <!-- <script type=\"text/javascript\" charset=\"utf-8\" src='__PUBLIC__/static/zTree/js/jquery.ztree.all.js'></script> -->\n    <script>\n        var URL = '__ROOT__/';\n        var PUBLIC = '__PUBLIC__';\n    </script>\n</head>"
  },
  {
    "path": "application/admin/view/public_left.html",
    "content": "<li class=\"treeview\">\n    <a href=\"#\">\n        <i class=\"fa fa-dashboard\"></i> <span>首页</span> \n    </a>\n    <ul class=\"treeview-menu\">\n        <li><a href=\"{:url('admin/index/index')}\"><i class=\"fa \"></i>系统首页</a></li>\n    </ul>\n</li>\n<li class=\"treeview\">\n    <a href=\"#\">\n        <i class=\"fa fa-gears\"></i> <span>设置</span> \n    </a>\n    <ul class=\"treeview-menu\">\n        <li><a href=\"{:url('/admin/config/site/index')}\"><i class=\"fa \"></i>站点设置</a></li>\n        <li><a href=\"{:url('/admin/config/sms/index')}\"><i class=\"fa \"></i>短信配置</a></li>\n        <li><a href=\"{:url('/admin/config/mail/index')}\"><i class=\"fa \"></i>邮件配置</a></li>\n    </ul>\n</li>\n<li class=\"treeview\">\n    <a href=\"#\">\n        <i class=\"fa fa-link\"></i> <span>微信</span> \n    </a>\n    <ul class=\"treeview-menu\">\n        <li><a href=\"{:url('/admin/wx/config/index')}\"><i class=\"fa \"></i>微信配置</a></li>\n        <li><a href=\"{:url('/admin/wx/menu/index')}\"><i class=\"fa \"></i>微信菜单</a></li>\n        <li><a href=\"{:url('/admin/wx/reply/index')}\"><i class=\"fa \"></i>自定义回复</a></li>\n        <li><a href=\"{:url('/admin/wx/tplmsg/index')}\"><i class=\"fa \"></i>模版消息</a></li>\n        <li><a href=\"{:url('/admin/wx/kefu/index')}\"><i class=\"fa \"></i>多客服设置</a></li>\n        <li><a href=\"{:url('/admin/wx/print/index')}\"><i class=\"fa \"></i>微信打印机</a></li>\n    </ul>\n</li>\n<li class=\"treeview\">\n    <a href=\"#\">\n        <i class=\"fa fa-edit\"></i> <span>内容</span> \n    </a>\n    <ul class=\"treeview-menu\">\n        <li><a href=\"{:url('/admin/article/category/index')}\"><i class=\"fa \"></i>文章分类</a></li>\n        <li><a href=\"{:url('/admin/article/index/index')}\"><i class=\"fa \"></i>文章列表</a></li>\n    </ul>\n</li>\n<li class=\"treeview\">\n    <a href=\"javascript:void(0)\">\n        <i class=\"fa fa-code\"></i> <span>模版</span>\n    </a>\n    <ul class=\"treeview-menu\">\n        <li><a href=\"{:url('/admin/tpl/shop/index')}\"><i class=\"fa \"></i>模版设置</a></li>\n        <li><a href=\"{:url('/admin/tpl/mail/index')}\"><i class=\"fa \"></i>邮件模版</a></li>\n        <li><a href=\"{:url('/admin/tpl/sms/index')}\"><i class=\"fa \"></i>短信模版</a></li>\n    </ul>\n</li>\n<li class=\"treeview\">\n    <a href=\"#\">\n        <i class=\"fa fa-group\"></i> <span>用户</span> \n    </a>\n    <ul class=\"treeview-menu\">\n        <li><a href=\"{:url('/admin/auth/group/index')}\"><i class=\"fa \"></i>管理员用户组</a></li>\n        <li><a href=\"{:url('/admin/auth/admin/index')}\"><i class=\"fa \"></i>管理员列表</a></li>\n        <li><a href=\"{:url('/admin/user/index/index')}\"><i class=\"fa \"></i>用户列表</a></li>\n        <li><a href=\"{:url('/admin/user/level/index')}\"><i class=\"fa \"></i>会员等级</a></li>\n    </ul>\n</li>\n<li class=\"treeview\">\n    <a href=\"#\">\n        <i class=\"fa fa-inbox\"></i> <span>插件</span>\n    </a>\n    <ul class=\"treeview-menu\">\n        <li><a href=\"{:url('/admin/addons/index')}\"><i class=\"fa \"></i>插件管理</a></li>\n        <li><a href=\"{:url('/admin/addons/shop')}\"><i class=\"fa \"></i>插件商店</a></li>\n    </ul>\n</li>\n<li class=\"treeview\">\n    <a href=\"#\">\n        <i class=\"fa fa-hand-o-right\"></i> <span>帮助</span>\n    </a>\n    <ul class=\"treeview-menu\">\n        <li><a href=\"{:url('/admin/help/index')}\"><i class=\"fa \"></i>使用帮助</a></li>\n    </ul>\n</li>\n"
  },
  {
    "path": "application/admin/view/public_login.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <title>WeMall微商城</title>\n    <!-- Tell the browser to be responsive to screen width -->\n    <meta content=\"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no\" name=\"viewport\">\n    <!-- Bootstrap 3.3.5 -->\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/plugins/bootstrap/css/bootstrap.min.css\">\n    <!-- Theme style -->\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/dist/css/AdminLTE.css\">\n    <!-- layui -->\n    <link rel=\"stylesheet\" href=\"__PUBLIC__/static/layui/css/layui.css\">\n    <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries -->\n    <!-- WARNING: Respond.js doesn't work if you view the page via file:// -->\n    <!--[if lt IE 9]>\n    <script src=\"/static/dist/js/html5shiv.min.js\"></script>\n    <script src=\"/static/dist/js/1.4.2/respond.min.js\"></script>\n    <![endif]-->\n</head>\n\n<body class=\"hold-transition login-page\" style=\"background-image:url(__PUBLIC__/static/wallpage/bg_{:rand(1,8)}.jpg);background-size: cover;\">\n    <div class=\"login-box\">\n        <div class=\"login-box-body\">\n            <div class=\"login-logo\" style=\"margin: 30px 10px\">\n                <img src=\"__PUBLIC__/static/dist/img/logo.png\">\n            </div>\n            <form class=\"layui-form\">\n                <div class=\"form-group has-feedback\">\n                    <input type=\"text\" name=\"username\" required lay-verify=\"required\" placeholder=\"用户名\" class=\"layui-input\">\n                    <span class=\"glyphicon glyphicon-envelope form-control-feedback\"></span>\n                </div>\n                <div class=\"form-group has-feedback\">\n                    <input type=\"password\" name=\"password\" required lay-verify=\"required\" placeholder=\"密码\" class=\"layui-input\">\n                    <span class=\"glyphicon glyphicon-lock form-control-feedback\"></span>\n                </div>\n                <div class=\"form-group has-feedback\" id=\"changeVerity\">\n                    <input type=\"text\" name=\"verify\" required lay-verify=\"required\" placeholder=\"验证码\" class=\"layui-input\" style=\"width: 70%;float: left\">\n                    <img src=\"{:captcha_src()}?t={:rand(10000,99999)}\" alt=\"captcha\" class=\"yzm-img\" style=\"width: 30%;border: 1px solid #ccc;height: 38px;border-left: 0px;cursor:pointer\" onclick=\"this.src='{:captcha_src()}'+'?t='+Math.random()\" />\n                </div>\n                <div class=\"row\">\n                    <div class=\"col-xs-8\"></div>\n                    <div class=\"col-xs-4\">\n                        <button class=\"btn btn-primary btn-block btn-flat\" lay-submit lay-filter=\"login\">登录</button>\n                    </div>\n                </div>\n            </form>\n        </div>\n    </div>\n    <div class=\"common_footer\">Powered by WeMall | Copyright © <a href=\"http://www.wemallshop.com/\" style=\"color: white;\" target=\"_blank\">wemallshop.com</a> All rights reserved.\n    </div>\n    <!-- jQuery 2.1.4 -->\n    <script src=\"__PUBLIC__/static/dist/js/jquery-2.1.4.min.js\"></script>\n    <!-- Bootstrap 3.3.5 -->\n    <script src=\"__PUBLIC__/static/plugins/bootstrap/js/bootstrap.min.js\"></script>\n    <!-- layui -->\n    <script src=\"__PUBLIC__/static/layui/layui.js\"></script>\n    <script>\n    $('#changeVerity').click(function() {\n        $(this).find('img').attr('src', '{:captcha_src()}?' + Math.random());\n    });\n    layui.use('form', function() {\n        var form = layui.form();\n\n        //监听提交\n        form.on('submit(login)', function(data) {\n            // layer.msg(JSON.stringify(data.field));\n            $.ajax({\n                type: \"post\",\n                url: \"{:url('admin/public/login')}\",\n                data: data.field,\n                success: function(data) {\n                    layer.msg(data.msg);\n                    if (data.status) {\n                        location.href = \"{:url('admin/index/index')}\";\n                    }\n                },\n                beforeSend: function() {\n\n                },\n                complete: function() {\n\n                }\n\n            });\n            return false;\n        });\n    });\n    </script>\n</body>\n\n</html>\n"
  },
  {
    "path": "application/admin/view/tpl/mail_add.html",
    "content": "<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <div class=\"callout callout-danger\">\n                <p>支持的变量：</p>\n                <p>验证码：$code</p>\n                <p>模版内容举例：您好，欢迎您注册wemallshop微信商城，您的验证码是：$code</p>\n            </div>\n            <!-- general form elements -->\n            <div class=\"box\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">邮件模版</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal\" action=\"{:url('/admin/tpl/mail/add')}\" method=\"post\" enctype=\"text/plain\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$mail.id|default=0}\"\n                               type=\"hidden\">\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">邮件类型</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"name\" disabled placeholder=\"\" value=\"{$mail.name|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">内容</label>\n\n                            <div class=\"col-sm-10\">\n                                <!-- 加载编辑器的容器 -->\n                                <script id=\"UEditor\" name=\"content\" type=\"text/plain\" style=\"height:500px;\">\n                                    {$mail.content|default=''}\n                                </script>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">测试邮箱</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"mail\" placeholder=\"\" value=\"{$mail.mail|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                    </div>\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                        </div>\n                    </div>\n\n                </form>\n            </div>\n            <!-- /.box -->\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n\n<script type=\"text/javascript\">\n    $(function () {\n        //实例化编辑器异步载入\n        var editor = new UE.ui.Editor();\n        editor.render(\"UEditor\");\n    });\n</script>"
  },
  {
    "path": "application/admin/view/tpl/mail_index.html",
    "content": "<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <!-- /.col -->\n        <div class=\"col-md-12\">\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">邮件模版管理</h3>\n                    <!-- /.box-tools -->\n                </div>\n                <!-- /.box-header -->\n                <div class=\"box-body no-padding\">\n                    <div class=\"mailbox-controls\">\n                        <!-- <div class=\"btn-group\">\n                            <a href=\"{:url('/admin/tpl/mail/add')}\" class=\"btn btn-danger \">\n                                新增邮件模版\n                            </a>\n                        </div> -->\n                    </div>\n                    <div class=\"table-responsive\" style=\"overflow-x: visible;\">\n                        <table class=\"table table-bordered table-hover\">\n                            <tbody>\n                            <tr>\n                                <th>\n                                    <label><input onchange=\"checkAll()\" type=\"checkbox\" value=\"\"></label>\n                                </th>\n                                <th>编号</th>\n                                <th>邮件类型</th>\n                                <th>模版内容</th>\n                                <th>测试邮箱</th>\n                                <th>状态</th>\n                                <th>操作</th>\n                            </tr>\n                            {volist name=\"maillist\" id=\"mail\"}\n                            <tr>\n                                <td>\n                                    <label><input name=\"checkbox\" class=\"check\" type=\"checkbox\" value=\"{$mail.id}\"></label>\n                                </td>\n                                <td>{$mail.id}</td>\n                                <td>{$mail.name}</td>\n                                <td>{$mail.content}</td>\n                                <td>{$mail.mail}</td>\n                                <td>\n                                    {eq name=\"mail.status\" value=\"1\"}\n                                        <span class=\"label label-success\">开启</span> \n                                    {else/}\n                                        <span class=\"label label-default\">关闭</span> \n                                    {/eq} \n                                </td>\n                                <td class=\"table-action\">\n                                    <a href=\"{:url('/admin/tpl/mail/add',array('id'=>$mail['id']))}\">编辑</a>\n                                    {eq name=\"mail.status\" value=\"0\"}\n                                    <a href=\"{:url('/admin/tpl/mail/update',array('id'=>$mail['id'],'status'=>1))}\">开启</a> \n                                    {else}\n                                    <a href=\"{:url('/admin/tpl/mail/update',array('id'=>$mail['id'],'status'=>0))}\">关闭</a> \n                                    {/eq} \n                                    <a href=\"{:url('/admin/tpl/mail/send',array('id'=>$mail['id']))}\">发一封测试</a>\n                                </td>\n                            </tr>\n                            {/volist}\n                            </tbody>\n                        </table>\n                    </div>\n                    <!-- /.mail-box-messages -->\n                </div>\n                <!-- /.box-body -->\n                <div class=\"box-footer no-padding\">\n                    <div class=\"mailbox-controls\">\n                        <div class=\"btn-group\">\n                            <button type=\"button\" class=\"btn btn-danger\"\n                                    onclick=\"batchUrl('{:url(\\'/admin/tpl/mail/update\\',array(\\'status\\'=>1))}')\">\n                                开启\n                            </button>\n                        </div>\n                        <div class=\"btn-group\">\n                        \t<button type=\"button\" class=\"btn btn-danger\"\n                                    onclick=\"batchUrl('{:url(\\'/admin/tpl/mail/update\\',array(\\'status\\'=>0))}')\">\n                                关闭\n                            </button>\n                        </div>\n                        <div class=\"btn-group pull-right\">\n                            {$maillist->render()}\n                        </div>\n                    </div>\n                </div>\n            </div>\n            <!-- /. box -->\n        </div>\n        <!-- /.col -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n\n\n</script>\n\n"
  },
  {
    "path": "application/admin/view/tpl/shop_index.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-lg-12\">\n            <div class=\"widget-container fluid-height clearfix\">\n                <div class=\"widget-content padded\">\n                    <div class=\"row\">\n                        <div class=\"col-xs-12 no-padding-right\">\n                            <div style=\"width: 260px; float: left;\">\n                                <img src=\"{$rootUrl}/tpl/theme/{$settheme}/thumb.png\" style=\"width: 240px; height: 340px;\"\n                                     class=\"img-thumbnail\">\n                                <button type=\"button\" class=\"btn btn-danger\"\n                                        style=\"margin: 6px 10px 0px 0px; width: 240px;\">已设置\n                                </button>\n                            </div>\n                        </div>\n                    </div>\n                    <div class=\"row\">\n                        <div class=\"col-xs-12\" style=\"margin-top:20px;\">\n                            {volist name=\"theme\" id=\"theme\"}\n                                <div style=\"width: 260px; float: left;\">\n                                    <img src=\"{$rootUrl}/tpl/theme/{$theme}/thumb.png\"\n                                         style=\"width: 240px; height: 340px;\"\n                                         class=\"img-thumbnail\">\n                                    <a href=\"{:url('/admin/tpl/shop/index',array('theme'=>$theme))}\" type=\"button\"\n                                       class=\"btn btn-default\"\n                                       style=\"margin: 6px 10px 0px 0px; width: 240px;\">设置</a>\n                                </div>\n                            {/volist}\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n    </div>\n</section>\n\n"
  },
  {
    "path": "application/admin/view/tpl/sms_add.html",
    "content": "<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <div class=\"callout callout-danger\">\n                <p>支持的变量：</p>\n                <p>验证码：${code}</p>\n                <p>模版内容举例：您的本次验证码${code}，10分钟内输入有效，感谢使用平台</p>\n            </div>\n            <!-- general form elements -->\n            <div class=\"box\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">短信模版</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal\" action=\"{:url('/admin/tpl/sms/add')}\" method=\"post\" enctype=\"text/plain\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$sms.id|default=0}\"\n                               type=\"hidden\">\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">模版类型</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"name\" disabled placeholder=\"\" value=\"{$sms.name|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">模版ID</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"template_code\" placeholder=\"\" value=\"{$sms.template_code|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">模版内容</label>\n\n                            <div class=\"col-sm-10\">\n                               <!-- <textarea class=\"form-control\" name=\"description\" placeholder=\"\" rows=\"3\">{$sms.content|default=''}</textarea> -->\n                               <textarea class=\"form-control\" name=\"content\" maxlength=\"5000\" placeholder=\"变量格式：${code}; 示例：您的本次验证码${code}，10分钟内输入有效，感谢使用平台\">{$sms.content|default=''}</textarea>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">测试手机号</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"phone\" placeholder=\"\" value=\"{$sms.phone|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n      \n                    </div>\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                        </div>\n                    </div>\n\n                </form>\n            </div>\n            <!-- /.box -->\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n\n<script type=\"text/javascript\">\n    $(function () {\n      \n    });\n</script>"
  },
  {
    "path": "application/admin/view/tpl/sms_index.html",
    "content": "<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <!-- /.col -->\n        <div class=\"col-md-12\">\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">短信模版管理</h3>\n                    <!-- /.box-tools -->\n                </div>\n                <!-- /.box-header -->\n                <div class=\"box-body no-padding\">\n                    <div class=\"mailbox-controls\">\n                        <!-- <div class=\"btn-group\">\n                            <a href=\"{:url('/admin/tpl/sms/add')}\" class=\"btn btn-danger \">\n                                新增短信模版\n                            </a>\n                        </div> -->\n                    </div>\n                    <div class=\"table-responsive\" style=\"overflow-x: visible;\">\n                        <table class=\"table table-bordered table-hover\">\n                            <tbody>\n                            <tr>\n                                <th>\n                                    <label><input onchange=\"checkAll()\" type=\"checkbox\" value=\"\"></label>\n                                </th>\n                                <th>编号</th>\n                                <th>模版类型</th>\n                                <th>模版ID</th>\n                                <th>模版内容</th>\n                                <th>测试号码</th>\n                                <th>状态</th>\n                                <th>操作</th>\n                            </tr>\n                            {volist name=\"smslist\" id=\"sms\"}\n                            <tr>\n                                <td>\n                                    <label><input name=\"checkbox\" class=\"check\" type=\"checkbox\" value=\"{$sms.id}\"></label>\n                                </td>\n                                <td>{$sms.id}</td>\n                                <td>{$sms.name}</td>\n                                <td>{$sms.template_code}</td>\n                                <td>{$sms.content}</td>\n                                <td>{$sms.phone}</td>\n                                <td>\n                                    {eq name=\"sms.status\" value=\"1\"}\n                                        <span class=\"label label-success\">开启</span> \n                                    {else/}\n                                        <span class=\"label label-default\">关闭</span> \n                                    {/eq} \n                                </td>\n                                <td class=\"table-action\">\n                                    <a href=\"{:url('/admin/tpl/sms/add',array('id'=>$sms['id']))}\">编辑</a>\n                                    {eq name=\"sms.status\" value=\"0\"}\n                                    <a href=\"{:url('/admin/tpl/sms/update',array('id'=>$sms['id'],'status'=>1))}\">开启</a> \n                                    {else}\n                                    <a href=\"{:url('/admin/tpl/sms/update',array('id'=>$sms['id'],'status'=>0))}\">关闭</a> \n                                    {/eq}\n                                    <a href=\"{:url('/admin/tpl/sms/send',array('id'=>$sms['id']))}\">发一条测试</a>\n                                </td>\n                            </tr>\n                            {/volist}\n                            </tbody>\n                        </table>\n                    </div>\n                    <!-- /.sms-box-messages -->\n                </div>\n                <!-- /.box-body -->\n                <div class=\"box-footer no-padding\">\n                    <div class=\"mailbox-controls\">\n                        <div class=\"btn-group\">\n                            <button type=\"button\" class=\"btn btn-danger\"\n                                    onclick=\"batchUrl('{:url(\\'/admin/tpl/sms/update\\',array(\\'status\\'=>1))}')\">\n                                开启\n                            </button>\n                        </div>\n                        <div class=\"btn-group\">\n                        \t<button type=\"button\" class=\"btn btn-danger\"\n                                    onclick=\"batchUrl('{:url(\\'/admin/tpl/sms/update\\',array(\\'status\\'=>0))}')\">\n                                关闭\n                            </button>\n                        </div>\n                        <div class=\"btn-group pull-right\">\n                            {$smslist->render()}\n                        </div>\n                    </div>\n                </div>\n            </div>\n            <!-- /. box -->\n        </div>\n        <!-- /.col -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n\n\n</script>\n\n"
  },
  {
    "path": "application/admin/view/user/index_add.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- general form elements -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">新增/修改用户</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal layui-form\" action=\"{:url('/admin/user/index/add')}\" method=\"post\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$user.id|default=0}\"\n                               type=\"hidden\">\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">用户名</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"username\" placeholder=\"\" value=\"{$user.username}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">手机号</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"phone\" placeholder=\"\" value=\"{$user.phone}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">密码</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"password\" placeholder=\"请输入新密码\" value=\"\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">账户</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"money\" placeholder=\"\" value=\"{$user.money}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">积分</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"score\" placeholder=\"\" value=\"{$user.score}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">备注</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"remark\" placeholder=\"\" value=\"{$user.remark}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        {neq name=\"user.id|default=0\" value=\"1\"}\n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">状态</label>\n\n                            <div class=\"col-md-7\">\n                                <input type=\"radio\" name=\"status\" value=\"1\" lay-filter=\"type\" title=\"启用\"\n                                    {eq name=\"user.status|default='1'\" value=\"1\"}checked{/eq}>\n                                <input type=\"radio\" name=\"status\" value=\"0\" lay-filter=\"type\" title=\"禁用\" \n                                    {eq name=\"user.status|default=''\" value=\"0\"}checked{/eq}>\n                            </div>\n                        </div>\n                        {/neq}\n                        <!-- /.box-body -->\n\n                        <div class=\"box-footer\">\n                            <div class=\"col-sm-2\">\n                                <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                            </div>\n\n                            <div class=\"col-sm-2\">\n                                <button type=\"button\" class=\"btn btn-block btn-default\" onclick=\"history.go(-1)\">取消\n                                </button>\n                            </div>\n                        </div>\n                </form>\n            </div>\n            <!-- /.box -->\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n    $(function () {\n        layui.use('form', function() {\n            var form = layui.form();\n            form.render(); //更新全部\n        });\n    });\n</script>\n"
  },
  {
    "path": "application/admin/view/user/index_index.html",
    "content": "<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <!-- /.col -->\n        <div class=\"col-md-12\">\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">用户管理</h3>\n                    <!-- /.box-tools -->\n                    <div class=\"box-tools\">\n                        <form class=\"form-horizontal\" action=\"{:url('/admin/user/index/index')}\" method=\"post\">\n                            <div class=\"input-group input-group-sm\" style=\"width: 250px;\">\n                                <input type=\"text\" name=\"name\" class=\"form-control pull-right\" placeholder=\"用户名\">\n\n                                <div class=\"input-group-btn\">\n                                    <button type=\"submit\" class=\"btn btn-default\"><i class=\"fa fa-search\"></i></button>\n                                </div>\n                            </div>\n                        </form>\n                    </div>\n                </div>\n                <div style=\"margin-top: 10px;\">\n                    <div class=\"btn-group\" style=\"margin-left: 10px;\">\n                        <a href=\"{:url('/admin/user/index/export')}\" target=\"_blank\" class=\"btn btn-danger \">\n                            导出全部用户\n                        </a>\n                    </div>\n                </div>\n                <!-- /.box-header -->\n                <div class=\"box-body table-responsive\">\n                    <table class=\"table table-bordered table-hover\">\n                        <tbody>\n                            <tr>\n                                <th class=\"hidden-xs\">\n                                    <label>\n                                        <input onchange=\"checkAll()\" type=\"checkbox\" value=\"\">\n                                    </label>\n                                </th>\n                                <th>编号</th>\n                                <th>用户名</th>\n                                <th>账户</th>\n                                <th>积分</th>\n                                <th>等级</th>\n                                <th>状态</th>\n                                <th>备注</th>\n                                <th>注册时间</th>\n                                <th>操作</th>\n                            </tr>\n                            {volist name=\"userlist\" id=\"user\"}\n                            <tr>\n                                <td class=\"hidden-xs\">\n                                    <label>\n                                        <input name=\"checkbox\" class=\"check\" type=\"checkbox\" value=\"{$user.id}\">\n                                    </label>\n                                </td>\n                                <td>{$user.id}</td>\n                                <td>\n                                    {empty name=\"user.avater\"}\n                                        <img style=\"width: 50px;border-radius: 50%;\" src=\"__PUBLIC__/static/dist/img/noimage.gif\">\n                                    {else /}\n                                        <img style=\"width: 50px;border-radius: 50%;\"\n                                        src=\"__PUBLIC__/uploads/{$user['avater']['savepath']}{$user['avater']['savename']}\">\n                                    {/empty}\n                                    <strong>{$user.username}</strong>                                        \n                                </td>\n                                <td>{$user.money}</td>\n                                <td>{$user.score}</td>\n                                <td>{$user.level}</td>\n                                <td>\n                                    {eq name=\"user.status\" value=\"1\"}\n                                        <span class=\"label label-success\">启用</span> \n                                    {else/}\n                                        <span class=\"label label-default\">禁用</span>\n                                    {/eq}\n                                </td>\n                                <td>{$user.remark}</td>\n                                <td>{$user.created_at}</td>\n                                <td class=\"table-action\">\n                                    <a href=\"{:url('/admin/user/index/add',array('id'=>$user['id']))}\">修改</a> \n                                    {gt name=\"user.id\" value=\"1\"} \n                                        {eq name=\"user.status\" value=\"0\"}\n                                            <a href=\"{:url('/admin/user/index/update',array('id'=>$user['id'],'status'=>1))}\">开启</a> \n                                        {else}\n                                            <a href=\"{:url('/admin/user/index/update',array('id'=>$user['id'],'status'=>0))}\">关闭</a> \n                                        {/eq}\n                                        <!-- <a href=\"{:url('admin/user/index/del',array('id'=>$user['id']))}\">删除</a>  -->\n                                    {/gt}\n                                </td>\n                            </tr>\n                            {/volist}\n                        </tbody>\n                    </table>\n                </div>\n                <div class=\"box-footer no-padding\">\n                    <div class=\"mailbox-controls\">\n                        <div class=\"btn-group\">\n                            <!-- <button type=\"button\" class=\"btn btn-danger\"\n                                    onclick=\"batchUrl('{:url(\\'admin/user/del\\')}')\">全部删除\n                            </button> -->\n                        </div>\n                        <!-- /.btn-group -->\n                        <div class=\"pull-right\">\n                            {$userlist->render()}\n                        </div>\n                        <!-- /.pull-right -->\n                    </div>\n                </div>\n            </div>\n            <!-- /. box -->\n        </div>\n        <!-- /.col -->\n    </div>\n</section>\n"
  },
  {
    "path": "application/admin/view/user/level_add.html",
    "content": "<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- general form elements -->\n            <div class=\"box\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">新增等级</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal\" action=\"{:url('/admin/user/level/add')}\" method=\"post\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$level.id|default=0}\"\n                               type=\"hidden\">\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">名称</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"name\" placeholder=\"\" value=\"{$level.name|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">积分 >=</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"score\" placeholder=\"\" value=\"{$level.score|default=''}\"\n                                       type=\"number\">\n                            </div>\n                        </div>\n\n                        <div class=\"box-footer\">\n                            <div class=\"col-sm-2\">\n                                <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                            </div>\n\n                            <div class=\"col-sm-2\">\n                                <button type=\"button\" class=\"btn btn-block btn-default\" onclick=\"history.go(-1)\">取消\n                                </button>\n                            </div>\n                        </div>\n                </form>\n            </div>\n            <!-- /.box -->\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>"
  },
  {
    "path": "application/admin/view/user/level_index.html",
    "content": "<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <!-- /.col -->\n        <div class=\"col-md-12\">\n            <div class=\"box\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">会员等级</h3>\n                    <!-- /.box-tools -->\n                </div>\n                <div style=\"margin-top: 10px;\">\n                    <div class=\"btn-group\" style=\"margin-left: 10px;\">\n                        <a href=\"{:url('/admin/user/level/add')}\" class=\"btn btn-danger \">\n                            新增等级\n                        </a>\n                    </div>\n                </div>\n                <!-- /.box-header -->\n                <div class=\"box-body table-responsive\">\n                    <table class=\"table table-bordered table-hover\">\n                        <tbody>\n                        <tr>\n                            <th>\n                                <label><input onchange=\"checkAll()\" type=\"checkbox\" value=\"\"></label>\n                            </th>\n                            <th>编号</th>\n                            <th>名称</th>\n                            <th>积分(大于等于)</th>\n                            <th>时间</th>\n                            <th>操作</th>\n                        </tr>\n\n                        {volist name=\"levellist\" id=\"level\"}\n                            <tr>\n                                <td>\n                                    <label><input name=\"checkbox\" class=\"check\" type=\"checkbox\" value=\"{$level.id}\"></label>\n                                </td>\n                                <td>{$level.id}</td>\n                                <td>{$level.name}</td>\n                                <td>>=  {$level.score}</td>\n                                <td>{$level.created_at}</td>\n                                <td class=\"table-action\">\n                                    <a href=\"{:url('/admin/user/level/add',array('id'=>$level['id']))}\">编辑</a> \n                                </td>\n                            </tr>\n                        {/volist}\n\n                        </tbody>\n                    </table>\n                </div>\n                <div class=\"box-footer no-padding\">\n                    <div class=\"mailbox-controls\">\n                        <div class=\"btn-group\">\n\n                        </div>\n                        <div class=\"btn-group\">\n                            \n                        </div>\n                        <div class=\"pull-right\">\n                            \n                        </div>\n                    </div>\n                </div>\n            </div>\n            <!-- /. box -->\n        </div>\n        <!-- /.col -->\n    </div>\n</section>"
  },
  {
    "path": "application/admin/view/wx/config_index.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- general form elements -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">微信设置</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal\" method=\"post\" action=\"{:url('/admin/wx/config/index')}\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$config.id|default=1}\"\n                               type=\"hidden\">\n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">url</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"url\" placeholder=\"\" disabled value=\"{$url|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">token</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"token\" placeholder=\"\" value=\"{$config.token|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">appid</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"appid\" placeholder=\"\" value=\"{$config.appid|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">appsecret</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"appsecret\" placeholder=\"\" value=\"{$config.appsecret|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">encodingaeskey</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"encodingaeskey\" placeholder=\"\"\n                                       value=\"{$config.encodingaeskey|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">公众号原始ID</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"old_id\" placeholder=\"\"\n                                       value=\"{$config.old_id|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">appid(小程序)</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"x_appid\" placeholder=\"\" value=\"{$config.x_appid|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">appsecret(小程序)</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"x_appsecret\" placeholder=\"\" value=\"{$config.x_appsecret|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                    </div>\n                    <!-- /.box-body -->\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                        </div>\n                    </div>\n                </form>\n            </div>\n            <!-- /.box -->\n\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n\n"
  },
  {
    "path": "application/admin/view/wx/kefu_index.html",
    "content": "<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <div class=\"callout callout-danger\">\n                <p>微信转接客服，转接到配置客服，不设置将随机转接。详细可见官方说明文档http://dkf.qq.com/faq-1_1.html。</p>\n            </div>\n            <!-- general form elements -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">微信多客服设置</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal layui-form\" action=\"{:url('/admin/wx/kefu/index')}\" method=\"post\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$kefu.id}\"\n                               type=\"hidden\">\n\n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">状态</label>\n\n                            <div class=\"col-md-7\">\n                                <input type=\"checkbox\" name=\"status\" lay-skin=\"switch\" value=\"1\"\n                                {notempty name=\"kefu.status\"}checked{/notempty}>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">转接客服(微信号)</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"kefu\" placeholder=\"\" value=\"{$kefu.kefu}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                    </div>\n                    <!-- /.box-body -->\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                        </div>\n                    </div>\n                </form>\n            </div>\n            <!-- /.box -->\n\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n    layui.use('form', function() {\n        var form = layui.form();\n        form.render(); //更新全部\n    });\n</script>\n"
  },
  {
    "path": "application/admin/view/wx/menu_add.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- general form elements -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">新增微信菜单</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal layui-form\" action=\"{:url('/admin/wx/menu/add')}\" method=\"post\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$menu.id|default=''}\"\n                               type=\"hidden\">\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">上级菜单</label>\n\n                            <div class=\"col-sm-10\">\n                                <select name=\"pid\" class=\"form-control\">\n                                    <option value=\"0\">一级菜单</option>\n                                    {volist name=\"parentmenu\" id=\"parentmenu\"}\n                                        <option value=\"{$parentmenu.id}\" {eq name=\"parentmenu.id\" value=\"$menu.pid|default=''\" }selected{/eq}>{$parentmenu.name}</option>\n                                    {/volist}\n                                </select>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">菜单名称</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"name\" placeholder=\"\" value=\"{$menu.name|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">类型</label>\n\n                            <div class=\"col-sm-10\">\n                                <input type=\"radio\" name=\"type\" value=\"click\" lay-filter=\"type\" title=\"模拟关键字\"\n                                {eq name=\"menu.type|default='click'\" value=\"click\"}checked{/eq}>\n                                <input type=\"radio\" name=\"type\" value=\"view\" lay-filter=\"type\" title=\"链接\" \n                                {eq name=\"menu.type|default=''\" value=\"view\"}checked{/eq}>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group click\" {neq name=\"menu.type|default='click'\" value=\"click\"}style=\"display: none;\"{/neq}>\n                            <label class=\"col-sm-2 control-label\">关键词</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"key\" placeholder=\"\" value=\"{$menu.key|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group view\" {neq name=\"menu.type|default=''\" value=\"view\"}style=\"display: none;\"{/neq}>\n                            <label class=\"col-sm-2 control-label\">url</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"url\" placeholder=\"\" value=\"{$menu.url|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">排序</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"rank\" placeholder=\"\" value=\"{$menu.rank|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">备注</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"remark\" placeholder=\"\" value=\"{$menu.remark|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                    </div>\n                    <!-- /.box-body -->\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <button type=\"button\" class=\"btn btn-block btn-default\" onclick=\"history.go(-1)\">取消</button>\n                        </div>\n                    </div>\n                </form>\n            </div>\n            <!-- /.box -->\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n    $(function () {\n        layui.use('form', function() {\n            var form = layui.form();\n            form.render(); //更新全部\n            form.on('radio(type)', function(data){\n                if (data.value == \"view\") {\n                    $('.view').show();\n                    $('.click').hide();\n                } else {\n                    $('.view').hide();\n                    $('.click').show();\n                }\n            }); \n        });\n    });\n</script>\n"
  },
  {
    "path": "application/admin/view/wx/menu_index.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <div class=\"callout callout-danger\">\n                <p>关键词:qqkf 设置qq客服,备注设置qq号</p>\n            </div>\n\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">微信菜单管理</h3>\n                </div>\n                <div class=\"box-body no-padding\">\n                    <div class=\"mailbox-controls\">\n                        <div class=\"btn-group\">\n                            <a href=\"{:url('/admin/wx/menu/add')}\" class=\"btn btn-danger \">\n                                新增菜单\n                            </a>\n                        </div>\n                    </div>\n                    <div class=\"table-responsive\" style=\"overflow-x: visible;\">\n                        <table class=\"table table-bordered table-hover\">\n                            <tbody>\n                            <tr>\n                                <th class=\"hidden-xs\">\n                                    <label><input onchange=\"checkAll()\" type=\"checkbox\" value=\"\"></label>\n                                </th>\n                                <th>ID</th>\n                                <th>PID(上级)</th>\n                                <th>菜单名称</th>\n                                <th>类型</th>\n                                <th>URL</th>\n                                <th>关键词</th>\n                                <th>排序</th>\n                                <th>备注</th>\n                                <th>操作</th>\n                            </tr>\n                            {volist name=\"menulist\" id=\"menu\"}\n                                <tr>\n                                    <td class=\"hidden-xs\">\n                                        <label><input name=\"checkbox\" class=\"check\" type=\"checkbox\" value=\"{$menu.id}\"></label>\n                                    </td>\n                                    <td>{$menu.id}</td>\n                                    <td>{$menu.pid}</td>\n                                    <td>{$menu.name}</td>\n                                    <td>\n                                        {eq name=\"menu.type|default=''\" value=\"view\"}链接{/eq} \n                                        {eq name=\"menu.type|default=''\" value=\"click\"}模拟关键字{/eq} \n                                    </td>\n                                    <td>\n                                        {eq name=\"menu.type|default=''\" value=\"view\"}\n                                            {$menu.url}\n                                        {/eq}  \n                                    </td>\n                                    <td>\n                                        {eq name=\"menu.type|default=''\" value=\"click\"}\n                                            {$menu.key}\n                                        {/eq}  \n                                    </td>\n                                    <td>{$menu.rank}</td>\n                                    <td>{$menu.remark}</td>\n                                    <td class=\"table-action\">\n                                        <a href=\"{:url('/admin/wx/menu/add',array('id'=>$menu['id']))}\">修改</a>\n                                        <a href=\"{:url('/admin/wx/menu/del',array('id'=>$menu['id']))}\">删除</a>\n                                    </td>\n                                </tr>\n                                {volist name=\"menu.sub\" id=\"menu1\"}\n                                    <tr>\n                                        <td class=\"hidden-xs\">\n                                            <label><input name=\"checkbox\" class=\"check\" type=\"checkbox\" value=\"{$menu1.id}\"></label>\n                                        </td>\n                                        <td>{$menu1.id}</td>\n                                        <td>{$menu1.pid}</td>\n                                        <td>|─{$menu1.name}</td>\n                                        <td>\n                                            {eq name=\"menu1.type|default=''\" value=\"view\"}链接{/eq} \n                                            {eq name=\"menu1.type|default=''\" value=\"click\"}模拟关键字{/eq} \n                                        </td>\n                                        <td>\n                                            {eq name=\"menu1.type|default=''\" value=\"view\"}\n                                                {$menu1.url}\n                                            {/eq}  \n                                        </td>\n                                        <td>\n                                            {eq name=\"menu1.type|default=''\" value=\"click\"}\n                                                {$menu1.key}\n                                            {/eq}  \n                                        </td>\n                                        <td>{$menu1.rank}</td>\n                                        <td>{$menu1.remark}</td>\n                                        <td class=\"table-action\">\n                                            <a href=\"{:url('/admin/wx/menu/add',array('id'=>$menu1['id']))}\">修改</a>\n                                            <a href=\"{:url('/admin/wx/menu/del',array('id'=>$menu1['id']))}\">删除</a>\n                                        </td>\n                                    </tr>\n                                {/volist}\n                            {/volist}\n                            </tbody>\n                        </table>\n                    </div>\n                </div>\n\n                <div class=\"box-footer no-padding\">\n                    <div class=\"mailbox-controls\">\n                        <div class=\"btn-group\">\n                            <a class=\"btn btn-danger\" href=\"{:url('/admin/wechat/createWxMenu')}\">生成自定义菜单</a>\n                        </div>\n                    </div>\n                </div>\n            </div>\n        </div>\n        <!-- /.col -->\n    </div>\n</section>"
  },
  {
    "path": "application/admin/view/wx/print_index.html",
    "content": "<style>\n    .print_buy{\n        text-decoration: none;\n        background-color: hsla(0,0%,100%,.2);\n    }\n    .print_buy:hover {\n        color: #eee;\n        border: 1px solid white;\n    }\n</style>\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <div class=\"callout callout-danger\">\n                <p>目前仅支持易联云微信打印机:\n                    <a href=\"https://www.koahub.com/home/product/83\" target=\"_blank\">\n                        <button type=\"button\" class=\"btn print_buy\">我要购买</button>\n                    </a>\n                </p>\n            </div>\n            <!-- general form elements -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">微信打印机设置</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal layui-form\" action=\"{:url('/admin/wx/print/index')}\" method=\"post\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$print.id}\"\n                               type=\"hidden\">\n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">自动打印</label>\n\n                            <div class=\"col-md-7\">\n                                <input type=\"checkbox\" name=\"switch\" lay-skin=\"switch\" value=\"1\"\n                                {notempty name=\"print.switch\"}checked{/notempty}>\n                            </div>\n                        </div>\n                        \n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">用户id</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"partner\" placeholder=\"\" value=\"{$print.partner}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        \n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">API 密钥</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"apikey\" placeholder=\"\" value=\"{$print.apikey}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        \n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">终端号</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"machine_code\" placeholder=\"\"\n                                       value=\"{$print.machine_code}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        \n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">密钥</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"mkey\" placeholder=\"\" value=\"{$print.mkey}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                    </div>\n                    <!-- /.box-body -->\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                        </div>\n                    </div>\n                </form>\n            </div>\n            <!-- /.box -->\n\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n    layui.use('form', function() {\n        var form = layui.form();\n        form.render(); //更新全部\n    });\n</script>\n"
  },
  {
    "path": "application/admin/view/wx/reply_add.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- general form elements -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">新增微信自定义回复</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal layui-form\" method=\"post\" action=\"{:url('/admin/wx/reply/add')}\">\n                    <div class=\"box-body\">\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$reply.id|default=0}\"\n                               type=\"hidden\">\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">标题</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"title\" placeholder=\"\" value=\"{$reply.title|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">类型</label>\n\n                            <div class=\"col-sm-10\">\n                                <input type=\"radio\" name=\"type\" value=\"news\" lay-filter=\"type\" title=\"图文\"\n                                {eq name=\"reply.type|default='news'\" value=\"news\"}checked{/eq}>\n                                <input type=\"radio\" name=\"type\" value=\"text\" lay-filter=\"type\" title=\"文本\" \n                                {eq name=\"reply.type|default=''\" value=\"text\"}checked{/eq}>\n                            </div>\n                        </div>\n                        \n                        <div class=\"form-group news\" {neq name=\"reply.type|default='news'\" value=\"news\"}style=\"display: none;\"{/neq}>\n                            <label class=\"col-sm-2 control-label\">描述</label>\n\n                            <div class=\"col-sm-10\">\n                                <textarea class=\"form-control\" name=\"description\"\n                                          rows=\"3\">{$reply.description|default=''}</textarea>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group news\" {neq name=\"reply.type|default='news'\" value=\"news\"}style=\"display: none;\"{/neq}>\n                            <label class=\"col-sm-2 control-label\">图片</label>\n\n                            <div class=\"col-sm-10\">\n                                <div class=\"fileupload fileupload-new\" data-provides=\"fileupload\">\n                                    <div class=\"fileupload-new img-thumbnail\">\n                                        {empty name=\"reply.file_id\"}\n                                            <img src=\"__PUBLIC__/static/dist/img/noimage.gif\">\n                                        {else /}\n                                            <img src=\"__PUBLIC__/uploads/{$reply['file']['savepath']}{$reply['file']['savename']}\">\n                                        {/empty}\n                                        <input class=\"form-control\" name=\"file_id\" id=\"file_id\" placeholder=\"\"\n                                               value=\"{$reply.file_id|default=''}\"\n                                               type=\"hidden\">\n\n                                        <div class=\"edit_pic_mask\">\n                                            <i class=\"fa fa-plus-circle\" onclick=\"imageUploader(this,false)\"></i>\n                                            <i class=\"fa fa-minus-circle\" onclick=\"removeImage(this,false)\"></i>\n                                        </div>\n                                    </div>\n                                </div>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group news\" {neq name=\"reply.type|default='news'\" value=\"news\"}style=\"display: none;\"{/neq}>\n                            <label class=\"col-sm-2 control-label\">链接</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"url\" placeholder=\"\" value=\"{$reply.url|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">关键词</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"key\" placeholder=\"\" value=\"{$reply.key|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">备注</label>\n\n                            <div class=\"col-sm-10\">\n                                <input class=\"form-control\" name=\"remark\" placeholder=\"\" value=\"{$reply.remark|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n                    </div>\n                    <!-- /.box-body -->\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button type=\"submit\" class=\"btn btn-block btn-danger\" lay-submit lay-filter=\"addreply\">保存</button>\n                        </div>\n\n                        <div class=\"col-sm-2\">\n                            <button type=\"button\" class=\"btn btn-block btn-default\" onclick=\"history.go(-1)\">取消</button>\n                        </div>\n                    </div>\n                </form>\n            </div>\n            <!-- /.box -->\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n    $(function () {\n        layui.use('form', function() {\n            var form = layui.form();\n            form.render('radio'); //更新全部\n            form.on('radio(type)', function(data){\n                if (data.value == \"news\") {\n                    $('.news').show();\n                } else {\n                    $('.news').hide();\n                }\n            });\n        });\n    });\n</script>\n\n\n"
  },
  {
    "path": "application/admin/view/wx/reply_index.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <!-- /.col -->\n        <div class=\"col-md-12\">\n            <div class=\"callout callout-danger\">\n                <p>关键词:subscribe 设置关注自动回复</p>\n            </div>\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">微信自定义回复</h3>\n                </div>\n                <!-- /.box-header -->\n                <div class=\"box-body no-padding\">\n                    <div class=\"mailbox-controls\">\n                        <div class=\"btn-group\">\n                            <a href=\"{:url('/admin/wx/reply/add')}\" class=\"btn btn-danger \">\n                                新增自定义回复\n                            </a>\n                        </div>\n                        <!-- /.btn-group -->\n                    </div>\n                    <div class=\"table-responsive\" style=\"overflow-x: visible;\">\n                        <table class=\"table table-bordered table-hover\">\n                            <tbody>\n                            <tr>\n                                <th class=\"hidden-xs\">\n                                    <label><input onchange=\"checkAll()\" type=\"checkbox\" value=\"\"></label>\n                                </th>\n                                <th>ID</th>\n                                <th>类型</th>\n                                <th>标题</th>\n                                <th>描述</th>\n                                <th>图片</th>\n                                <th>链接</th>\n                                <th>关键词</th>\n                                <th>备注</th>\n                                <th>操作</th>\n                            </tr>\n\n                            {volist name=\"replylist\" id=\"replylist\"}\n                                <tr>\n                                    <td class=\"hidden-xs\">\n                                        <label><input name=\"checkbox\" class=\"check\" type=\"checkbox\"\n                                                      value=\"{$replylist.id}\"></label>\n                                    </td>\n                                    <td>{$replylist.id}</td>\n                                    <td>\n                                        {eq name=\"replylist.type|default=''\" value=\"news\"}图文{/eq}\n                                        {eq name=\"replylist.type|default=''\" value=\"text\"}文本{/eq}\n                                    </td>\n                                    <td>{$replylist.title|substr=0,12}</td>\n                                    <td>{$replylist.description|substr=0,12}</td>\n                                    <td>\n                                        <div class=\"btn-group\" style=\"margin: 0px;\">\n                                            {empty name=\"replylist.file_id\"}\n                                                <img style=\"height: 50px\" src=\"__PUBLIC__/static/dist/img/noimage.gif\">\n                                            {else /}\n                                                <img style=\"height: 50px\"\n                                                src=\"__PUBLIC__/uploads/{$replylist['file']['savepath']}{$replylist['file']['savename']}\">\n                                            {/empty}\n                                        </div>\n                                    </td>\n                                    <td>{$replylist.url}</td>\n                                    <td>{$replylist.key}</td>\n                                    <td>{$replylist.remark}</td>\n                                    <td class=\"table-action\"><a\n                                            href=\"{:url('/admin/wx/reply/add',array('id'=>$replylist['id']))}\">修改</a><a\n                                            href=\"{:url('/admin/wx/reply/del',array('id'=>$replylist['id']))}\">删除</a>\n                                    </td>\n                                </tr>\n                            {/volist}\n                            </tbody>\n                        </table>\n                        <div class=\"box-footer no-padding\">\n                            <div class=\"mailbox-controls\">\n                                <div class=\"btn-group\">\n                                    <button type=\"button\" class=\"btn btn-danger\"\n                                            onclick=\"batchUrl('{:url(\\'/admin/wx/reply/del\\')}')\">全部删除\n                                    </button>\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                    <!-- /.mail-box-messages -->\n                </div>\n            </div>\n            <!-- /. box -->\n        </div>\n        <!-- /.col -->\n    </div>\n</section>"
  },
  {
    "path": "application/admin/view/wx/tplmsg_add.html",
    "content": "<section class=\"content\">\n    <div class=\"row\">\n        <div class=\"col-md-12\">\n            <!-- general form elements -->\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">模版消息配置</h3>\n                </div>\n                <!-- form start -->\n                <form class=\"form-horizontal layui-form\" method=\"post\" action=\"{:url('/admin/wx/tplmsg/add')}\">\n                    <div class=\"box-body\">\n\n                        <input class=\"form-control\" name=\"id\" placeholder=\"\" value=\"{$tplmsg.id|default=0}\"\n                               type=\"hidden\">\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">模版类型</label>\n\n                            <div class=\"col-sm-3\">\n                                <input class=\"form-control\" name=\"name\" placeholder=\"\" disabled value=\"{$tplmsg.name|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">模版编号</label>\n\n                            <div class=\"col-sm-3\">\n                                <input class=\"form-control\" name=\"template_id_short\" placeholder=\"\" disabled value=\"{$tplmsg.template_id_short|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">模版标题</label>\n\n                            <div class=\"col-sm-3\">\n                                <input class=\"form-control\" name=\"title\" placeholder=\"\" value=\"{$tplmsg.title|default=''}\"\n                                       type=\"text\">\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"col-sm-2 control-label\">备注</label>\n\n                            <div class=\"col-sm-6\">\n                                <textarea class=\"form-control\" name=\"remark\" placeholder=\"\" rows=\"3\">{$tplmsg.remark|default=''}</textarea>\n                            </div>\n                        </div>\n\n                        <div class=\"form-group\">\n                            <label class=\"control-label col-md-2\">状态</label>\n\n                            <div class=\"col-md-7\">\n                                <input type=\"checkbox\" name=\"status\" lay-skin=\"switch\" value=\"1\"\n                                {notempty name=\"tplmsg.status\"}checked{/notempty}>\n                            </div>\n                        </div>\n                    </div>\n                    <!-- /.box-body -->\n\n                    <div class=\"box-footer\">\n                        <div class=\"col-sm-2\">\n                            <button type=\"submit\" class=\"btn btn-block btn-danger\">保存</button>\n                        </div>\n                        <div class=\"col-sm-2\">\n                            <button type=\"button\" class=\"btn btn-block btn-default\" onclick=\"history.go(-1)\">取消</button>\n                        </div>\n                    </div>\n                </form>\n            </div>\n            <!-- /.box -->\n\n        </div>\n        <!--/.col (right) -->\n    </div>\n</section>\n<script type=\"text/javascript\">\n    layui.use('form', function() {\n        var form = layui.form();\n        form.render(); //更新全部\n    });\n</script>\n"
  },
  {
    "path": "application/admin/view/wx/tplmsg_index.html",
    "content": "\n<!-- Main content -->\n<section class=\"content\">\n    <div class=\"row\">\n        <!-- /.col -->\n        <div class=\"col-md-12\">\n            <div class=\"callout callout-danger\">\n                <p>微信模板消息请设置所在行业为IT科技/互联网|电子商务，消费品/消费品</p>\n                <p>无法自动添加的用户请在微信后台手动添加设置</p>\n            </div>\n            <div class=\"box box-default\">\n                <div class=\"box-header with-border\">\n                    <h3 class=\"box-title\">微信模版消息列表</h3>\n                </div>\n                <!-- /.box-header -->\n                <div class=\"box-body no-padding\">\n                    <div class=\"mailbox-controls\">\n                        <div class=\"btn-group\">\n                            <!-- <a href=\"{:url('/admin/wx/tplmsg/add')}\" class=\"btn btn-danger \">\n                                新增模版消息\n                            </a> -->\n                        </div>\n                        <!-- /.btn-group -->\n                    </div>\n                    <div class=\"table-responsive\" style=\"overflow-x: visible;\">\n                        <table class=\"table table-bordered table-hover\">\n                            <tbody>\n                            <tr>\n                                <th class=\"hidden-xs\">\n                                    <label><input onchange=\"checkAll()\" type=\"checkbox\" value=\"\"></label>\n                                </th>\n                                <th>ID</th>\n                                <th>模版类型</th>\n                                <th>模版编号</th>\n                                <th>模版标题</th>\n                                <th>备注</th>\n                                <th>状态</th>\n                                <th>操作</th>\n                            </tr>\n\n                            {volist name=\"tplmsglist\" id=\"tplmsg\"}\n                                <tr>\n                                    <td class=\"hidden-xs\">\n                                        <label><input name=\"checkbox\" class=\"check\" type=\"checkbox\"\n                                                      value=\"{$tplmsg.id}\"></label>\n                                    </td>\n                                    <td>{$tplmsg.id}</td>\n                                    <td>{$tplmsg.name}</td>\n                                    <td>{$tplmsg.template_id_short}</td>\n                                    <!-- <td>{$tplmsg.title|substr=0,12}</td> -->\n                                    <td>{$tplmsg.title}</td>\n                                    <td>{$tplmsg.remark}</td>\n                                    <td>\n                                    \t{eq name=\"tplmsg.status\" value=\"1\"}\n                                            <span class=\"label label-success\">开启</span> \n                                        {else/}\n                                            <span class=\"label label-default\">关闭</span> \n                                        {/eq} \n                                    </td>\n                                    <td class=\"table-action\">\n                                        <a href=\"{:url('/admin/wx/tplmsg/add',array('id'=>$tplmsg['id']))}\">编辑</a>\n                                        {eq name=\"tplmsg.status\" value=\"0\"}\n                                        <a href=\"{:url('/admin/wx/tplmsg/update',array('id'=>$tplmsg['id'],'status'=>1))}\">开启</a> \n                                        {else}\n                                        <a href=\"{:url('/admin/wx/tplmsg/update',array('id'=>$tplmsg['id'],'status'=>0))}\">关闭</a> \n                                        {/eq} \n                                    </td>\n                                </tr>\n                            {/volist}\n                            </tbody>\n                        </table>\n                        <div class=\"box-footer no-padding\">\n                            <div class=\"mailbox-controls\">\n                                <div class=\"btn-group\">\n                                    <!-- <button type=\"button\" class=\"btn btn-danger\"\n                                            onclick=\"batchUrl('{:url(\\'/admin/wx/tplmsg/del\\')}')\">删除选中\n                                    </button> -->\n                                </div>\n                            </div>\n                        </div>\n                    </div>\n                    <!-- /.mail-box-messages -->\n                </div>\n            </div>\n            <!-- /. box -->\n        </div>\n        <!-- /.col -->\n    </div>\n</section>"
  },
  {
    "path": "application/app/controller/AddonsController.php",
    "content": "<?php\n/**\n * \n * @authors 清月曦 (1604583867@qq.com)\n * @date    2017-05-02 15:40:06\n * @version $Id$\n */\nnamespace app\\app\\controller;\nuse think\\Controller;\nuse think\\View;\n\nclass AddonsController extends Controller\n{\n    protected $v = null;\n    protected $addon = null;\n    public function _initialize(){\n        $this->v = $this->request->param('v', '');\n        $this->addon = $this->request->param('addon', '');\n    }\n    public function index()\n    {\n        $view = new View();\n        if (is_dir('./tpl/addons/'.$this->v.'/'.$this->addon.'/dist/')) {\n            return $view->fetch('./tpl/addons/'.$this->v.'/'.$this->addon.'/dist/index.html');\n        }else{\n            return $view->fetch('./tpl/addons/'.$this->v.'/'.$this->addon.'/index.html');\n        }\n    }\n}\n"
  },
  {
    "path": "application/app/controller/IndexController.php",
    "content": "<?php\r\n/**\r\n * \r\n * @authors 清月曦 (1604583867@qq.com)\r\n * @date    2017-05-02 15:40:06\r\n * @version $Id$\r\n */\r\nnamespace app\\app\\controller;\r\nuse think\\Controller;\r\nuse think\\View;\r\n\r\nclass IndexController extends Controller\r\n{\r\n    public function index()\r\n    {\r\n        $theme = model('Config')->where('id',1)->value('theme');\r\n\r\n        $view = new View();\r\n        if (is_dir('./tpl/theme/'.$theme.'/dist/')) {\r\n            return $view->fetch('./tpl/theme/'.$theme.'/dist/index.html');\r\n        }else{\r\n            return $view->fetch('./tpl/theme/'.$theme.'/index.html');\r\n        }\r\n    }\r\n    \r\n    public function themeStatic()\r\n    {\r\n        $referer = request()->header('referer');\r\n        if(strpos($referer, '/addons/')){\r\n            $referers = explode('/',$referer);\r\n            if(strpos($referer, '/tpl/addons/')){\r\n                if (is_dir('./tpl/addons/'.$referers[5].'/'.$referers[6].'/dist/')) {\r\n                    $source = request()->root(true).'/tpl/addons/'.$referers[5].'/'.$referers[6].'/dist/'.request()->pathinfo();\r\n                }else{\r\n                    $source = request()->root(true).'/tpl/addons/'.$referers[5].'/'.$referers[6].'/'.request()->pathinfo();\r\n                }\r\n            }else{\r\n                if (is_dir('./tpl/addons/'.$referers[4].'/'.$referers[5].'/dist/')) {\r\n                    $source = request()->root(true).'/tpl/addons/'.$referers[4].'/'.$referers[5].'/dist/'.request()->pathinfo();\r\n                }else{\r\n                    $source = request()->root(true).'/tpl/addons/'.$referers[4].'/'.$referers[5].'/'.request()->pathinfo();\r\n                }\r\n            }\r\n\r\n            $this->redirect($source);\r\n        }else{\r\n            $theme = model('Config')->where('id',1)->value('theme');\r\n            if (is_dir('./tpl/theme/'.$theme.'/dist/')) {\r\n                $this->redirect(request()->root(true).'/tpl/theme/'.$theme.'/dist/'. request()->pathinfo());  \r\n            }else{\r\n                $this->redirect(request()->root(true).'/tpl/theme/'.$theme.'/'. request()->pathinfo());  \r\n            }\r\n        }\r\n    }\r\n\r\n    public function source(){\r\n        \r\n        $file = request()->url(true);\r\n        if (file_exists($file)) {\r\n             $this->redirect($file);\r\n        }else{\r\n            return json('资源不存在', 404);\r\n        }\r\n    }\r\n}\r\n"
  },
  {
    "path": "application/command.php",
    "content": "<?php\r\n// +----------------------------------------------------------------------\r\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\r\n// +----------------------------------------------------------------------\r\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\r\n// +----------------------------------------------------------------------\r\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\r\n// +----------------------------------------------------------------------\r\n// | Author: yunwuxin <448901948@qq.com>\r\n// +----------------------------------------------------------------------\r\n\r\nreturn [];\r\n"
  },
  {
    "path": "application/common/behavior/Config.php",
    "content": "<?php\n/**\n * \n * @authors 清月曦 (1604583867@qq.com)\n * @date    2017-04-12 10:03:28\n * @version $Id$\n */\nnamespace app\\common\\behavior;\n\nclass Config {\n    /**\n     * 执行行为 run方法是Behavior唯一的接口\n     * @access public\n     * @param mixed $params  行为参数\n     * @return void\n     */\n    public function run(&$params)\n    {        \n    \t// 获取入口目录\n        $base_file = request()->baseFile();\n        $base_dir  = preg_replace(['/\\/index.php$/', '/admin.php$/'], ['', ''], $base_file);\n        defined('PUBLIC_PATH') or define('PUBLIC_PATH', '');\n        // 视图输出字符串内容替换\n        $view_replace_str = [\n            // 静态资源目录\n        \t'__PUBLIC__'    => $base_dir.PUBLIC_PATH,\n            '__STATIC__'    => $base_dir.PUBLIC_PATH. '/static',\n            // 文件上传目录\n            '__UPLOADS__'   => $base_dir.PUBLIC_PATH. '/uploads'\n        ];\n        config('view_replace_str', $view_replace_str);\n\n    }\n\n\n\n}"
  },
  {
    "path": "application/common/model/Admin.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass Admin extends Model\n{\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\n\tpublic function group(){\n        return $this->hasOne('AuthGroup','id','group_id');\n    }\n\n\t/**\n\t * 用户登录认证\n\t * @param  string  $username 用户名\n\t * @param  string  $password 用户密码\n\t * @param  integer $type     用户名类型 （1-用户名，2-邮箱，3-手机，4-UID）\n\t * @return integer           登录成功-用户ID，登录失败-错误编号\n\t */\n\tpublic function login($username, $password, $type = 1){\n\t\t$map = array();\n\t\tswitch ($type) {\n\t\t\tcase 1:\n\t\t\t\t$map['username'] = $username;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\t$map['email'] = $username;\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\t$map['mobile'] = $username;\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\t$map['id'] = $username;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn 0; //参数错误\n\t\t}\n\t\t/* 获取用户数据 */\n\t\t$user = $this->get($map);\n\t\tif($user){\n\t\t\t/* 验证用户密码 */\n\t\t\tif(md5($password) === $user->password){\n\t\t\t\t$this->updateLogin($user->id); //更新用户登录信息\n\t\t\t\treturn $user->id; //登录成功，返回用户ID\n\t\t\t} else {\n\t\t\t\treturn -2; //密码错误\n\t\t\t}\n\t\t} else {\n\t\t\treturn -1; //用户不存在或被禁用\n\t\t}\n\t}\n\n\t/**\n\t * 更新用户登录信息\n\t * @param  integer $uid 用户ID\n\t */\n\tprotected function updateLogin($uid){\n\t\t$data = array(\n\t\t\t'id'              => $uid,\n\t\t\t'last_login_time' => date(\"Y-m-d H:i:s\"),\n\t\t\t'last_login_ip'   => request()->ip(),\n\t\t);\n\t\t$this->update($data);\n\t}\n\n\n\n}"
  },
  {
    "path": "application/common/model/Analysis.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass Analysis extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\n\n     /**\n     * @param int $orders 新订单\n     * @param int $trades 新交易额\n     * @param int $registers 新注册量\n     * @param int $users 新购买用户\n     */\n    public function add($orders = 0, $trades = 0, $registers = 0, $users = 0)\n    {\n    \t$data = $this->whereTime('created_at', 'today')->find();\n\n    \tif ($data) {\n    \t\t$this->where('id',$data[\"id\"])->setInc(\"orders\", $orders);\n            $this->where('id',$data[\"id\"])->setInc(\"trades\", $trades);\n            $this->where('id',$data[\"id\"])->setInc(\"registers\", $registers);\n            $this->where('id',$data[\"id\"])->setInc(\"users\", $users);\n    \t}else{\n    \t\tparent::create([\n                'date'  \t =>  date(\"Y-m-d\"),\n                'orders'  \t =>  $orders,\n                'trades' \t =>  $trades,\n                'registers'  =>  $registers,\n                'users'      =>  $users\n            ]);\n    \t}\n    }\n}"
  },
  {
    "path": "application/common/model/Article.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass Article extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n    \n    public function category()\n    {\n        return $this->hasOne('ArticleCategory','id','category_id');\n    }\n\n}"
  },
  {
    "path": "application/common/model/ArticleCategory.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass ArticleCategory extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\n\n}"
  },
  {
    "path": "application/common/model/AuthGroup.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass AuthGroup extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\n\n}"
  },
  {
    "path": "application/common/model/AuthGroupAccess.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass AuthGroupAccess extends Model\n{\n\n\n\n}"
  },
  {
    "path": "application/common/model/AuthRule.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass AuthRule extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\n\n}"
  },
  {
    "path": "application/common/model/Config.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass Config extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\n    public function logo()\n    {\n        return $this->hasOne('File','id','logo_id');\n    }\n}"
  },
  {
    "path": "application/common/model/File.php",
    "content": "<?php\n/**\n * \n * @authors 清月曦 (1604583867@qq.com)\n * @date    2017-05-01 18:33:22\n * @version $Id$\n */\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass File extends Model\n{\n\tprotected $resultSetType = 'collection';\n\t\n\n\n}"
  },
  {
    "path": "application/common/model/Mail.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass Mail extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\tprotected $auto = ['secure'];\n\n\n}"
  },
  {
    "path": "application/common/model/MailTpl.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass MailTpl extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\n\n}"
  },
  {
    "path": "application/common/model/Sms.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass Sms extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\n\n}"
  },
  {
    "path": "application/common/model/SmsTpl.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass SmsTpl extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\n\n}"
  },
  {
    "path": "application/common/model/User.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass User extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n    protected $type = [\n        'money'     =>  'float',\n    ];\n\tpublic function contact()\n    {\n        return $this->hasOne('UserContact','id','contact_id');\n    }\n    public function avater()\n    {\n        return $this->hasOne('File','id','avater_id');\n    }\n    public function wx()\n    {\n        return $this->hasOne('OauthWx','user_id','id');\n    }\n    public function applet()\n    {\n        return $this->hasOne('OauthApplet','user_id','id');\n    }\n\n\tprotected $append  = ['level'];\n\tprotected function getLevelAttr($value, $data)\n    {\n        $score = $data['score'];\n        $level = '';\n        $levellist = model('app\\common\\model\\UserLevel')->all()->toArray();\n        foreach ($levellist as &$v) {\n\t\t\tif($score >= $v['score']){\n\t\t\t\t$level = $v['name'];\n\t\t\t}\n\t\t}\n        return $level ? $level : '未知等级';\n    }\n\n\t/**\n\t * 用户登录认证\n\t * @param  string  $username 用户名\n\t * @param  string  $password 用户密码\n\t * @param  integer $type     用户名类型 （1-用户名，2-邮箱，3-手机，4-UID）\n\t * @return integer           登录成功-用户ID，登录失败-错误编号\n\t */\n\tpublic function login($username, $password, $type = 1){\n\t\t$map = array();\n\t\tswitch ($type) {\n\t\t\tcase 1:\n\t\t\t\t$map['username'] = $username;\n\t\t\t\tbreak;\n\t\t\tcase 2:\n\t\t\t\t$map['email'] = $username;\n\t\t\t\tbreak;\n\t\t\tcase 3:\n\t\t\t\t$map['phone'] = $username;\n\t\t\t\tbreak;\n\t\t\tcase 4:\n\t\t\t\t$map['id'] = $username;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\treturn 0; //参数错误\n\t\t}\n\t\t/* 获取用户数据 */\n\t\t$user = $this->get($map);\n\t\tif($user){\n\t\t\t/* 验证用户密码 */\n\t\t\tif(md5($password) === $user->password){\n\t\t\t\t$this->updateLogin($user->id); //更新用户登录信息\n\t\t\t\treturn $user->id; //登录成功，返回用户ID\n\t\t\t} else {\n\t\t\t\treturn -2; //密码错误\n\t\t\t}\n\t\t} else {\n\t\t\treturn -1; //用户不存在或被禁用\n\t\t}\n\t}\n\n\t/**\n\t * 更新用户登录信息\n\t * @param  integer $uid 用户ID\n\t */\n\tprotected function updateLogin($uid){\n\t\t$data = array(\n\t\t\t'id'              => $uid,\n\t\t\t'last_login_time' => date(\"Y-m-d H:i:s\"),\n\t\t\t'last_login_ip'   => request()->ip(),\n\t\t);\n\t\t$this->update($data);\n\t}\n\n\n\n\n\n}"
  },
  {
    "path": "application/common/model/UserLevel.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass UserLevel extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\n\n}"
  },
  {
    "path": "application/common/model/WxConfig.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass WxConfig extends Model\n{\n    protected $resultSetType = 'collection';\n    protected $autoWriteTimestamp = 'timestamp';\n    // 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n    \n    public function getJsSign($url = '')\n    {\n        vendor(\"dodgepudding.wechat-php-sdk.JSSDK#class\");\n        $wxConfig = $this->find();\n        $jssdk = new \\JSSDK($wxConfig[\"appid\"], $wxConfig[\"appsecret\"],$url);\n\n        $result = $jssdk->getSignPackage();\n\n        return $result;\n    }\n    /**\n     * getWeObj\n     * @param  integer $type     用户名类型 （1-公众号，2-小程序）\n     * @return integer           登录成功-用户ID，登录失败-错误编号\n     */\n    public function getWeObj($type = 1)\n    {\n        vendor(\"dodgepudding.wechat-php-sdk.wechat#class\");\n        $config = $this->find();\n\n        switch ($type) {\n            case 1:\n                $options = array(\n                    'token' => $config [\"token\"], //填写你设定的key\n                    'encodingaeskey' => $config [\"encodingaeskey\"], //填写加密用的EncodingAESKey\n                    'appid' => $config [\"appid\"], //填写高级调用功能的app id\n                    'appsecret' => $config [\"appsecret\"] //填写高级调用功能的密钥\n                );\n                break;\n            case 2:\n                $options = array(\n                    'appid' => $config [\"x_appid\"], //填写高级调用功能的app id\n                    'appsecret' => $config [\"x_appsecret\"] //填写高级调用功能的密钥\n                );\n                break;\n            default:\n                return 0; //参数错误\n        }\n        $weObj = new \\Wechat ($options);\n        return $weObj;\n    }\n\n}"
  },
  {
    "path": "application/common/model/WxKefu.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass WxKefu extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n    \n\tprotected $auto = ['status'];\n\n}"
  },
  {
    "path": "application/common/model/WxMenu.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass WxMenu extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\n\n}"
  },
  {
    "path": "application/common/model/WxPrint.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass WxPrint extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n    \n\tprotected $auto = ['switch'];\n\n}"
  },
  {
    "path": "application/common/model/WxReply.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass WxReply extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n    \n\tpublic function file()\n    {\n        return $this->hasOne('File','id','file_id');\n    }\n\n\n}"
  },
  {
    "path": "application/common/model/WxTplmsg.php",
    "content": "<?php\nnamespace app\\common\\model;\n\nuse think\\Model;\n\nclass WxTplmsg extends Model\n{\n\tprotected $resultSetType = 'collection';\n\tprotected $autoWriteTimestamp = 'timestamp';\n\t// 定义时间戳字段名\n    protected $createTime = 'created_at';\n    protected $updateTime = 'updated_at';\n\n}"
  },
  {
    "path": "application/common.php",
    "content": "<?php\r\n/**\r\n * 数据签名认证\r\n * @param  array  $data 被认证的数据\r\n * @return string       签名\r\n * @author 清月曦 <1604583867@qq.com>\r\n */\r\n\r\n// 应用公共文件\r\nfunction data_auth_sign($data) {\r\n    //数据类型检测\r\n    if(!is_array($data)){\r\n        $data = (array)$data;\r\n    }\r\n    ksort($data); //排序\r\n    $code = http_build_query($data); //url编码并生成query字符串\r\n    $sign = sha1($code); //生成签名\r\n    return $sign;\r\n}\r\n/**\r\n * 下载远程文件\r\n * @param  string  $url     网址\r\n * @param  string  $filename    保存文件名\r\n * @param  integer $timeout 过期时间\r\n * return boolean|string\r\n */\r\nfunction http_down($url, $filename, $timeout = 60) {\r\n    $path = dirname($filename);\r\n    if (!is_dir($path) && !mkdir($path, 0755, true)) {\r\n        return false;\r\n    }\r\n    $fp = fopen($filename, 'w');\r\n    $ch = curl_init($url);\r\n    curl_setopt($ch, CURLOPT_FILE, $fp);\r\n    curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);\r\n    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);\r\n    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); \r\n    curl_exec($ch);\r\n    curl_close($ch);\r\n    fclose($fp);\r\n    return $filename;\r\n}\r\n\r\n// 防超时的file_get_contents改造函数\r\nfunction wp_file_get_contents($url)\r\n{\r\n    $context = stream_context_create(array(\r\n        'http' => array(\r\n            'timeout' => 30\r\n        )\r\n    )); // 超时时间，单位为秒\r\n\r\n    return file_get_contents($url, 0, $context);\r\n}\r\n/**\r\n*解压文件\r\n*/\r\nfunction unzip($filePath, $toPath,$filesize=0){\r\n    // $length = filesize($filePath);\r\n    // if ($filesize == $length) {\r\n        $zip = new ZipArchive; \r\n        $res = $zip->open($filePath); \r\n\r\n        if ($res === TRUE) {\r\n            //解压缩到指定文件夹 \r\n            $zip->extractTo($toPath); \r\n            $zip->close(); \r\n            //删除压缩包\r\n            unlink($filePath);\r\n            if ( is_dir( $toPath . '__MACOSX' ) ) {\r\n                delDirAndFile($toPath . '__MACOSX');\r\n            }\r\n            return true;\r\n        }else{\r\n            return false;\r\n        }\r\n    // }else{\r\n        // return false;\r\n    // }\r\n}\r\n// 导出excle\r\nfunction export_to($data,$name=false,$type = 0){\r\n    if(!$name){$name=date(\"Y-m-d-H-i-s\",time());}\r\n    $PHPExcel = new PHPExcel(); //实例化PHPExcel类，类似于在桌面上新建一个Excel表格\r\n    $PHPExcel->getActiveSheet()->fromArray($data);\r\n    $PHPExcel->getActiveSheet()->setTitle('Sheet1'); //给当前活动sheet设置名称\r\n    $PHPExcel->setActiveSheetIndex(0);\r\n    $fileName = './public/'.date('Y-m-d_', time()).time().'.xlsx';\r\n    $saveName = $name.date('Y-m-d', time()).'.xlsx';\r\n\r\n    $PHPWriter = PHPExcel_IOFactory::createWriter($PHPExcel,'Excel5');//按照指定格式生成Excel文件，‘Excel2007’表示生成2007版本的xlsx，‘Excel5’表示生成2003版本Excel文件\r\n    if ($type == 0) {\r\n        header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');//告诉浏览器输出07Excel文件\r\n        header('Content-Type:application/vnd.ms-excel');//告诉浏览器将要输出Excel03版本文件\r\n        header('Content-Disposition: attachment;filename=\"'.$saveName.'\"');//告诉浏览器输出浏览器名称\r\n        // header('Content-Disposition: attachment;filename=\"01simple.xlsx\"');//告诉浏览器输出浏览器名称\r\n        header('Cache-Control: max-age=0');//禁止缓存\r\n        $PHPWriter->save(\"php://output\");\r\n    }else{\r\n        $PHPWriter->save($fileName); //表示在$path路径下面生成demo.xlsx文件\r\n    }\r\n}\r\n\r\nfunction list_to_tree($list, $pk = 'id', $pid = 'pid', $child = '_child', $keys = 'id', $sort = 'asc', $root = 0)\r\n{\r\n    // 创建Tree\r\n    $tree = array();\r\n    if (is_array($list)) {\r\n        // 创建基于主键的数组引用\r\n        $refer = array();\r\n        foreach ($list as $key => $data) {\r\n            $list[$key][$child] = [];\r\n            $refer [$data[$pk]] = &$list[$key];\r\n        }\r\n\r\n        foreach ($list as $key => $data) {\r\n            // 判断是否存在parent\r\n            $parentId = $data[$pid];\r\n            if ($root == $parentId) {\r\n                $tree [] = &$list[$key];\r\n                $tree = my_sort($tree,$keys,$sort,SORT_NUMERIC);\r\n            } else {\r\n                if (isset ($refer [$parentId])) {\r\n                    $parent = &$refer[$parentId];\r\n                    $parent[$child] [] = &$list[$key];\r\n                    $parent[$child] = my_sort($parent[$child],$keys,$sort,SORT_NUMERIC);\r\n                }\r\n            }\r\n        }\r\n    }\r\n    return $tree;\r\n}\r\n/**\r\n * 数组按字段排序\r\n * @param  $arrays  要排序的数组\r\n * @return SORT_ASC     - 默认，按升序排列。(A-Z)\r\n * @return SORT_DESC    - 按降序排列。(Z-A)\r\n * @return SORT_REGULAR - 默认。将每一项按常规顺序排列。\r\n * @return SORT_NUMERIC - 将每一项按数字顺序排列。\r\n * @return SORT_STRING  - 将每一项按字母顺序排列\r\n * @author 清月曦 <1604583867@qq.com>\r\n */\r\nfunction my_sort($arrays,$sort_key,$sort_order='asc',$sort_type=SORT_NUMERIC ){\r\n    if($sort_order == 'asc') $sort_order=SORT_ASC;\r\n    if($sort_order == 'desc') $sort_order=SORT_DESC;\r\n\r\n    if(is_array($arrays)){   \r\n        foreach ($arrays as $array){   \r\n            if(is_array($array)){   \r\n                $key_arrays[] = $array[$sort_key];   \r\n            }else{   \r\n                return false;   \r\n            }   \r\n        }   \r\n    }else{   \r\n        return false;   \r\n    }  \r\n    array_multisort($key_arrays,$sort_order,$sort_type,$arrays);   \r\n    return $arrays;   \r\n} \r\n/**\r\n * 及时显示提示信息\r\n * @param  string $msg 提示信息\r\n */\r\nfunction show_msg($msg, $class = ''){\r\n    echo \"<script type=\\\"text/javascript\\\">showmsg(\\\"{$msg}\\\", \\\"{$class}\\\")</script>\";\r\n    flush();\r\n    ob_flush();\r\n}\r\n/**\r\n * 执行SQL文件\r\n */\r\nfunction execute_sql_file($sql_path)\r\n{\r\n    // 读取SQL文件\r\n    $sql = wp_file_get_contents($sql_path);\r\n    $sql = str_replace(\"\\r\", \"\\n\", $sql);\r\n    $sql = explode(\";\\n\", $sql);\r\n\r\n    // 替换表前缀\r\n    $orginal = 'wemall_';\r\n    $prefix = config('DB_PREFIX');\r\n    $sql = str_replace(\"{$orginal}\", \"{$prefix}\", $sql);\r\n\r\n    // 开始安装\r\n    foreach ($sql as $value) {\r\n        $value = trim($value);\r\n        if (empty ($value))\r\n            continue;\r\n\r\n        $res = \\think\\Db::execute($value);\r\n    }\r\n}\r\n/**\r\n * 远程获取数据，GET模式\r\n * 注意：\r\n * 1.使用Crul需要修改服务器中php.ini文件的设置，找到php_curl.dll去掉前面的\";\"就行了\r\n * @param $url 指定URL完整路径地址\r\n * return 远程输出的数据\r\n */\r\nfunction getHttpResponseGET($url) {\r\n    $curl = curl_init($url);\r\n    curl_setopt($curl, CURLOPT_HEADER, 0 ); // 过滤HTTP头\r\n    curl_setopt($curl,CURLOPT_RETURNTRANSFER, 1);// 显示输出结果\r\n    $responseText = curl_exec($curl);\r\n    //var_dump( curl_error($curl) );//如果执行curl过程中出现异常，可打开此开关，以便查看异常内容\r\n    curl_close($curl);\r\n    \r\n    return $responseText;\r\n}\r\n\r\n/**\r\n * 系统邮件发送函数\r\n * @param string $tomail 接收邮件者邮箱\r\n * @param string $name 接收邮件者名称\r\n * @param string $subject 邮件主题\r\n * @param string $body 邮件内容\r\n * @param string $attachment 附件列表\r\n * @return boolean\r\n * @author static7 <static7@qq.com>\r\n 使用方法：\r\n$toemail='1604583867@qq.com';  \r\n$name = '清月曦';//收件人昵称\r\n$subject='注册验证码';\r\n$mail_tpl = model('MailTpl')->where('type', 'register')->find()->toArray();\r\n$content = str_replace(\"\\$code\",\"123456\",$mail_tpl['content']);\r\n$result = send_mail($toemail,$name,$subject,$content);\r\ndump($result);\r\n */\r\nfunction send_mail($tomail, $name, $subject = '', $body = '', $attachment = null) {\r\n    $config_mail = model('Mail')->find()->toArray();\r\n    $shop = model('Config')->find();\r\n    $mail = new \\PHPMailer();           //实例化PHPMailer对象\r\n    \r\n    $mail->CharSet = 'UTF-8';           //设定邮件编码，默认ISO-8859-1，如果发中文此项必须设置，否则乱码\r\n    $mail->IsSMTP();                    // 设定使用SMTP服务\r\n    $mail->SMTPDebug = 0;               // SMTP调试功能 0=关闭 1 = 错误和消息 2 = 消息\r\n    $mail->SMTPAuth = true;             // 启用 SMTP 验证功能\r\n    if($config_mail['secure']){\r\n        $mail->SMTPSecure = 'ssl';      // 使用安全协议Enable TLS encryption, `ssl` also accepted\r\n    }else{\r\n        $mail->SMTPSecure = 'tls';      // 使用安全协议Enable TLS encryption, `ssl` also accepted\r\n    }\r\n    $mail->Host = $config_mail['host']; // SMTP 服务器\r\n    $mail->Port = $config_mail['port'];                  // SMTP服务器的端口号\r\n    $mail->Username = $config_mail['user'];    // SMTP服务器用户名\r\n    $mail->Password = $config_mail['pass'];     // SMTP服务器密码\r\n    $mail->SetFrom($config_mail['user'], $shop['title']);\r\n    $replyEmail = $config_mail['replyTo'];                   //留空则为发件人EMAIL\r\n    $replyName = '发送回复';                    //回复名称（留空则为发件人名称）\r\n    $mail->AddReplyTo($replyEmail, $replyName);\r\n    $mail->Subject = $subject;\r\n    $mail->MsgHTML($body);\r\n    $mail->AddAddress($tomail, $name);\r\n    if (is_array($attachment)) { // 添加附件\r\n        foreach ($attachment as $file) {\r\n            is_file($file) && $mail->AddAttachment($file);\r\n        }\r\n    }\r\n    return $mail->Send() ? true : $mail->ErrorInfo;\r\n}\r\n/**\r\n * @param $id\r\n *\r\n * 易联云微信打印机\r\n */\r\nfunction wxPrint($id)\r\n{\r\n    $result = model('Order')->with('user,contact,delivery,detail.product.file')->find($id);\r\n\r\n    $config = model('Config')->find();\r\n\r\n    $msg = '';\r\n    $msgtitle = $config['name'] . '欢迎您订购\r\n\r\n订单编号：' . $result[\"orderid\"] . '\r\n\r\n条目      单价（元）    数量\r\n--------------------------------------------\r\n';\r\n    $detail = '';\r\n    for ($j = 0; $j < count($result[\"detail\"]); $j++) {\r\n        $row = $result[\"detail\"][$j];\r\n        $title = $row['name'];\r\n        $price = $row['price'];\r\n        $num = $row['num'];\r\n\r\n        $detail .=\r\n            $title . '      ' . $price . '      ' . $num . '\r\n';\r\n    }\r\n    $msgcontent = $detail;\r\n\r\n    $msgfooter = '\r\n备注：' . $result[\"remark\"] . '\r\n--------------------------------------------\r\n合计：' . $result[\"totalprice\"] . '元\r\n付款状态：' . $result['pay_status'] . '\r\n\r\n联系用户：' . $result[\"contact\"][\"name\"] . '\r\n送货地址：' . $result[\"contact\"][\"province\"] . $result[\"contact\"][\"city\"] . $result[\"contact\"][\"district\"] . $result[\"contact\"][\"address\"] . '\r\n联系电话：' . $result[\"contact\"][\"phone\"] . '\r\n订购时间：' . $result[\"created_at\"] . '\r\n\r\n\r\n\r\n\r\n';//自由输出\r\n\r\n    $msg .= $msgtitle . $msgcontent . $msgfooter;\r\n\r\n    $wxPrint = model(\"WxPrint\")->find();\r\n    $partner = $wxPrint[\"partner\"];//用户id\r\n    $machine_code = $wxPrint[\"machine_code\"];//机器码\r\n    $apiKey = $wxPrint[\"apikey\"];//apiKey\r\n    $msign = $wxPrint[\"mkey\"];//秘钥\r\n\r\n    vendor(\"dodgepudding.wechat-php-sdk.WxPrint#class\");\r\n    $print = new \\WxPrint();\r\n    //打印\r\n    $print->action_print($partner,$machine_code,$msg,$apiKey,$msign);\r\n}\r\n/**\r\n *  产生一个随机数，传入长度\r\n * @param [type]  用户 QQ互联一键登录　产生密码随机\r\n * .@param string $length 随机数密码长度  默认为10个字符;\r\n **/\r\nfunction rand_code($length = 6)\r\n{\r\n    $chars = \"123456789\";\r\n    $str = \"\";\r\n    $size = strlen($chars);\r\n    for ($i = 0; $i < $length; $i++) {\r\n        $str .= $chars[mt_rand(0, $size - 1)];\r\n    }\r\n    return $str;\r\n}\r\n\r\n/**\r\n * 最简单的XML转数组\r\n * @param string $xmlstring XML字符串\r\n * @return array XML数组\r\n */\r\nfunction simplest_xml_to_array($xmlstring)\r\n{\r\n    return json_decode(json_encode((array)simplexml_load_string($xmlstring)), true);\r\n}\r\n\r\n"
  },
  {
    "path": "application/config.php",
    "content": "<?php\r\n// +----------------------------------------------------------------------\r\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\r\n// +----------------------------------------------------------------------\r\n// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.\r\n// +----------------------------------------------------------------------\r\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\r\n// +----------------------------------------------------------------------\r\n// | Author: liu21st <liu21st@gmail.com>\r\n// +----------------------------------------------------------------------\r\n\r\nreturn [\r\n    // +----------------------------------------------------------------------\r\n    // | 应用设置\r\n    // +----------------------------------------------------------------------\r\n\r\n    // 应用命名空间\r\n    'app_namespace'          => 'app',\r\n    // 应用调试模式\r\n    'app_debug'              => true,\r\n    // 应用Trace\r\n    'app_trace'              => false,\r\n    // 应用模式状态\r\n    'app_status'             => '',\r\n    // 是否支持多模块\r\n    'app_multi_module'       => true,\r\n    // 入口自动绑定模块\r\n    'auto_bind_module'       => false,\r\n    // 注册的根命名空间\r\n    'root_namespace'         => [],\r\n    // 扩展函数文件\r\n    'extra_file_list'        => [THINK_PATH . 'helper' . EXT],\r\n    // 默认输出类型\r\n    'default_return_type'    => 'html',\r\n    // 默认AJAX 数据返回格式,可选json xml ...\r\n    'default_ajax_return'    => 'json',\r\n    // 默认JSONP格式返回的处理方法\r\n    'default_jsonp_handler'  => 'jsonpReturn',\r\n    // 默认JSONP处理方法\r\n    'var_jsonp_handler'      => 'callback',\r\n    // 默认时区\r\n    'default_timezone'       => 'PRC',\r\n    // 是否开启多语言\r\n    'lang_switch_on'         => false,\r\n    // 默认全局过滤方法 用逗号分隔多个\r\n    'default_filter'         => '',\r\n    // 默认语言\r\n    'default_lang'           => 'zh-cn',\r\n    // 应用类库后缀\r\n    'class_suffix'           => false,\r\n    // 控制器类后缀\r\n    'controller_suffix'      => true,\r\n\r\n    // +----------------------------------------------------------------------\r\n    // | 模块设置\r\n    // +----------------------------------------------------------------------\r\n\r\n    // 默认模块名\r\n    'default_module'         => 'admin',\r\n    // 禁止访问模块\r\n    'deny_module_list'       => ['common'],\r\n    // 默认控制器名\r\n    'default_controller'     => 'Index',\r\n    // 默认操作名\r\n    'default_action'         => 'index',\r\n    // 默认验证器\r\n    'default_validate'       => '',\r\n    // 默认的空控制器名\r\n    'empty_controller'       => 'Error',\r\n    // 操作方法后缀\r\n    'action_suffix'          => '',\r\n    // 自动搜索控制器\r\n    'controller_auto_search' => true,\r\n\r\n    // +----------------------------------------------------------------------\r\n    // | URL设置\r\n    // +----------------------------------------------------------------------\r\n\r\n    // PATHINFO变量名 用于兼容模式\r\n    'var_pathinfo'           => 's',\r\n    // 兼容PATH_INFO获取\r\n    'pathinfo_fetch'         => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],\r\n    // pathinfo分隔符\r\n    'pathinfo_depr'          => '/',\r\n    // URL伪静态后缀\r\n    'url_html_suffix'        => 'html',\r\n    // URL普通方式参数 用于自动生成\r\n    'url_common_param'       => false,\r\n    // URL参数方式 0 按名称成对解析 1 按顺序解析\r\n    'url_param_type'         => 0,\r\n    // 是否开启路由\r\n    'url_route_on'           => true,\r\n    // 路由使用完整匹配\r\n    'route_complete_match'   => false,\r\n    // 路由配置文件（支持配置多个）\r\n    'route_config_file'      => ['route'],\r\n    // 是否强制使用路由\r\n    'url_route_must'         => false,\r\n    // 域名部署\r\n    'url_domain_deploy'      => false,\r\n    // 域名根，如thinkphp.cn\r\n    'url_domain_root'        => '',\r\n    // 是否自动转换URL中的控制器和操作名\r\n    'url_convert'            => true,\r\n    // 默认的访问控制器层\r\n    'url_controller_layer'   => 'controller',\r\n    // 表单请求类型伪装变量\r\n    'var_method'             => '_method',\r\n    // 表单ajax伪装变量\r\n    'var_ajax'               => '_ajax',\r\n    // 表单pjax伪装变量\r\n    'var_pjax'               => '_pjax',\r\n    // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则\r\n    'request_cache'          => false,\r\n    // 请求缓存有效期\r\n    'request_cache_expire'   => null,\r\n\r\n    // +----------------------------------------------------------------------\r\n    // | 模板设置\r\n    // +----------------------------------------------------------------------\r\n\r\n    'template'               => [\r\n        // 模板引擎类型 支持 php think 支持扩展\r\n        'type'         => 'Think',\r\n        // 模板路径\r\n        'view_path'    => '',\r\n        // 模板后缀\r\n        'view_suffix'  => 'html',\r\n        // 模板文件名分隔符\r\n        'view_depr'    => '_',\r\n        // 模板引擎普通标签开始标记\r\n        'tpl_begin'    => '{',\r\n        // 模板引擎普通标签结束标记\r\n        'tpl_end'      => '}',\r\n        // 标签库标签开始标记\r\n        'taglib_begin' => '{',\r\n        // 标签库标签结束标记\r\n        'taglib_end'   => '}',\r\n\r\n        'tpl_cache'   => false,\r\n    ],\r\n\r\n    // 视图输出字符串内容替换\r\n    'view_replace_str'       => [],\r\n    // 默认跳转页面对应的模板文件\r\n    'dispatch_success_tmpl'  => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',\r\n    'dispatch_error_tmpl'    => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',\r\n\r\n    // +----------------------------------------------------------------------\r\n    // | 异常及错误设置\r\n    // +----------------------------------------------------------------------\r\n\r\n    // 异常页面的模板文件\r\n    'exception_tmpl'         => THINK_PATH . 'tpl' . DS . 'think_exception.tpl',\r\n\r\n    // 错误显示信息,非调试模式有效\r\n    'error_message'          => '页面错误！请稍后再试～',\r\n    // 显示错误信息\r\n    'show_error_msg'         => false,\r\n    // 异常处理handle类 留空使用 \\think\\exception\\Handle\r\n    'exception_handle'       => '',\r\n\r\n    // +----------------------------------------------------------------------\r\n    // | 日志设置\r\n    // +----------------------------------------------------------------------\r\n\r\n    'log'                    => [\r\n        // 日志记录方式，内置 file socket 支持扩展\r\n        'type'  => 'File',\r\n        // 日志保存目录\r\n        'path'  => LOG_PATH,\r\n        // 日志记录级别\r\n        'level' => [],\r\n    ],\r\n\r\n    // +----------------------------------------------------------------------\r\n    // | Trace设置 开启 app_trace 后 有效\r\n    // +----------------------------------------------------------------------\r\n    'trace'                  => [\r\n        // 内置Html Console 支持扩展\r\n        'type' => 'Html',\r\n    ],\r\n\r\n    // +----------------------------------------------------------------------\r\n    // | 缓存设置\r\n    // +----------------------------------------------------------------------\r\n\r\n    'cache'                  => [\r\n        // 驱动方式\r\n        'type'   => 'File',\r\n        // 缓存保存目录\r\n        'path'   => CACHE_PATH,\r\n        // 缓存前缀\r\n        'prefix' => '',\r\n        // 缓存有效期 0表示永久缓存\r\n        'expire' => 0,\r\n    ],\r\n\r\n    // +----------------------------------------------------------------------\r\n    // | 会话设置\r\n    // +----------------------------------------------------------------------\r\n\r\n    'session'                => [\r\n        'id'             => '',\r\n        // SESSION_ID的提交变量,解决flash上传跨域\r\n        'var_session_id' => '',\r\n        // SESSION 前缀\r\n        'prefix'         => 'think',\r\n        // 驱动方式 支持redis memcache memcached\r\n        'type'           => '',\r\n        // 是否自动开启 SESSION\r\n        'auto_start'     => true,\r\n    ],\r\n\r\n    // +----------------------------------------------------------------------\r\n    // | Cookie设置\r\n    // +----------------------------------------------------------------------\r\n    'cookie'                 => [\r\n        // cookie 名称前缀\r\n        'prefix'    => '',\r\n        // cookie 保存时间\r\n        'expire'    => 0,\r\n        // cookie 保存路径\r\n        'path'      => '/',\r\n        // cookie 有效域名\r\n        'domain'    => '',\r\n        //  cookie 启用安全传输\r\n        'secure'    => false,\r\n        // httponly设置\r\n        'httponly'  => '',\r\n        // 是否使用 setcookie\r\n        'setcookie' => true,\r\n    ],\r\n\r\n    //分页配置\r\n    'paginate'               => [\r\n        'type'      => 'bootstrap',\r\n        'var_page'  => 'page',\r\n        'list_rows' => 15,\r\n    ],\r\n    //验证码\r\n    'captcha'  => [\r\n        // 验证码字符集合\r\n        'codeSet'  => '2345678abcdefhijkmnpqrstuvwxyzABCDEFGHJKLMNPQRTUVWXY',\r\n        // 使用中文验证码\r\n        'useZh' =>false,\r\n        // 字体大小\r\n        'fontSize' => 35,\r\n        // 是否画混淆曲线\r\n        'useCurve' => true, \r\n         // 验证码图片高度\r\n        'imageH'   => '',\r\n        // 验证码图片宽度\r\n        'imageW'   => '',\r\n        // 验证码长度（位数）\r\n        'length'   => 4,\r\n        // 验证成功后是否重置        \r\n        'reset'    => true\r\n    ],\r\n];\r\n"
  },
  {
    "path": "application/database.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nreturn [\n    // 数据库类型\n    'type'            => 'mysql',\n    // 服务器地址\n    'hostname'        => '127.0.0.1',\n    // 数据库名\n    'database'        => 'kaiyuan',\n    // 用户名\n    'username'        => 'root',\n    // 密码\n    'password'        => 'root',\n    // 端口\n    'hostport'        => '3306',\n    // 连接dsn\n    'dsn'             => '',\n    // 数据库连接参数\n    'params'          => [],\n    // 数据库编码默认采用utf8\n    'charset'         => 'utf8',\n    // 数据库表前缀\n    'prefix'          => '',\n    // 数据库调试模式\n    'debug'           => true,\n    // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)\n    'deploy'          => 0,\n    // 数据库读写是否分离 主从式有效\n    'rw_separate'     => false,\n    // 读写分离后 主服务器数量\n    'master_num'      => 1,\n    // 指定从服务器序号\n    'slave_no'        => '',\n    // 是否严格检查字段是否存在\n    'fields_strict'   => true,\n    // 数据集返回类型\n    'resultset_type'  => 'array',\n    // 自动写入时间戳字段\n    'auto_timestamp'  => false,\n    // 时间字段取出后的默认时间格式\n    'datetime_format' => 'Y-m-d H:i:s',\n    // 是否需要进行SQL性能分析\n    'sql_explain'     => false,\n];\n"
  },
  {
    "path": "application/install/common.php",
    "content": "<?php\n\n/**\n * 系统环境检测\n * @return array 系统环境数据\n */\nfunction check_env()\n{\n    $items = array(\n        'os' => array('操作系统', '不限制', '类Unix', PHP_OS, 'success'),\n        'php' => array('PHP版本', '5.4', '5.4+', PHP_VERSION, 'success'),\n        'upload' => array('附件上传', '不限制', '2M+', '未知', 'success'),\n        'gd' => array('GD库', '2.0', '2.0+', '未知', 'success'),\n    );\n\n    //PHP环境检测\n    if ($items['php'][3] < $items['php'][1]) {\n        $items['php'][4] = 'error';\n    }\n\n    //附件上传检测\n    if (@ini_get('file_uploads'))\n        $items['upload'][3] = ini_get('upload_max_filesize');\n\n    //GD库检测\n    $tmp = function_exists('gd_info') ? gd_info() : array();\n    if (empty($tmp['GD Version'])) {\n        $items['gd'][3] = '未安装';\n        $items['gd'][4] = 'error';\n    } else {\n        $items['gd'][3] = $tmp['GD Version'];\n    }\n    unset($tmp);\n    return $items;\n}\n\n/**\n * 目录，文件读写检测\n * @return array 检测数据\n */\nfunction check_dirfile()\n{\n    $items = array(\n        array('dir', '可写', 'success', 'addons'),\n        array('dir', '可写', 'success', 'application'),\n        array('dir', '可写', 'success', 'data'),\n        array('dir', '可写', 'success', 'public'),\n        array('dir', '可写', 'success', 'tpl'),\n        array('dir', '可写', 'success', 'thinkphp'),\n    );\n    foreach ($items as &$val) {\n        if ('dir' == $val[0]) {\n            if (!is_writable($val[3])) {\n                if (is_dir($items[3])) {\n                    $val[1] = '可读';\n                    $val[2] = 'error';\n                    session('error', true);\n                } else {\n                    $val[1] = '不存在';\n                    $val[2] = 'error';\n                    session('error', true);\n                }\n            }\n        } else {\n            if (file_exists($val[3])) {\n                if (!is_writable($val[3])) {\n                    $val[1] = '不可写';\n                    $val[2] = 'error';\n                    session('error', true);\n                }\n            } else {\n                if (!is_writable(dirname($val[3]))) {\n                    $val[1] = '不存在';\n                    $val[2] = 'error';\n                    session('error', true);\n                }\n            }\n        }\n    }\n    return $items;\n}\n\n/**\n * 函数检测\n * @return array 检测数据\n */\nfunction check_func()\n{\n    $items = array(\n        array('pdo','支持','success','类'),\n        array('pdo_mysql','支持','success','模块'),\n        array('fileinfo','支持','success','模块'),\n        array('file_get_contents', '支持', 'success','函数'),\n        array('mb_strlen', '支持', 'success','函数'),\n        array('pathinfo', '支持', 'success','函数'),\n        array('curl','支持','success','模块'),\n    );\n    foreach ($items as &$val) {\n        if(('类'==$val[3] && !class_exists($val[0]))\n            || ('模块'==$val[3] && !extension_loaded($val[0]))\n            || ('函数'==$val[3] && !function_exists($val[0]))\n        ){\n            $val[1] = '不支持';\n            $val[2] = 'error';\n        }\n    }\n\n    return $items;\n}\n\n/**\n * 及时显示提示信息\n * @param  string $msg 提示信息\n */\nfunction install_show_msg($msg, $class = true)\n{\n    if ($class) {\n        echo \"<script type=\\\"text/javascript\\\">showmsg(\\\"{$msg}\\\")</script>\";\n    } else {\n        echo \"<script type=\\\"text/javascript\\\">showmsg(\\\"{$msg}\\\", \\\"error\\\")</script>\";\n        exit;\n    }\n}\n\n/**\n * 过滤数据\n * @param  array $data 过滤数据\n */\nfunction filter_string($data)\n{\n    if ($data === NULL) {\n        return false;\n    }\n    if (is_array($data)) {\n        foreach ($data as $k => $v) {\n            $data[$k] = filter_string($v);\n        }\n        return $data;\n    } else {\n        return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');\n    }\n}\n\n/**\n * 保存模块配置\n * @param string $file 调用文件\n * @return array\n */\nfunction install_save_config($file, $config)\n{\n    if (empty($config) || !is_array($config)) {\n        return array();\n    }\n    $file = install_get_config_file($file);\n    //读取配置内容\n    $conf = file_get_contents($file);\n    //替换配置项\n    foreach ($config as $key => $value) {\n        if (is_string($value) && !in_array($value, array('true', 'false'))) {\n            if (!is_numeric($value)) {\n                $value = \"'\" . $value . \"'\"; //如果是字符串，加上单引号\n            }\n        }\n        $conf = preg_replace(\"/'\" . $key . \"'\\s*=\\>\\s*(.*?),/iU\", \"'\" . $key . \"'=>\" . $value . \",\", $conf);\n    }\n    //写入应用配置文件\n    if (!IS_WRITE) {\n        return false;\n    } else {\n        if (file_put_contents($file, $conf)) {\n            return true;\n        } else {\n            return false;\n        }\n        return '';\n    }\n}\n\n/**\n * 解析配置文件路径\n * @param string $file 文件路径或简写路径\n * @return dir\n */\nfunction install_get_config_file($file)\n{\n    $name = $file;\n    if (!is_file($file)) {\n        $str = explode('/', $file);\n        $strCount = count($str);\n        switch ($strCount) {\n            case 1:\n                $app = APP_NAME;\n                $name = $str[0];\n                break;\n            case 2:\n                $app = $str[0];\n                $name = $str[1];\n                break;\n        }\n        $app = strtolower($app);\n        if (empty($app) && empty($file)) {\n            throw new \\Exception(\"Config '{$file}' not found'\", 500);\n        }\n        $file = APP_PATH . \"{$app}/conf/{$name}.php\";\n        if (!file_exists($file)) {\n            throw new \\Exception(\"Config '{$file}' not found\", 500);\n        }\n    }\n    return $file;\n}\n\n/**\n * 写入配置文件\n * @param $config\n * @return array 配置信息\n */\nfunction write_config($config){\n    if(is_array($config)){\n        //读取配置内容\n        $conf = file_get_contents(APP_PATH . 'install/data/database.tpl');\n        // 替换配置项\n        foreach ($config as $name => $value) {\n            $conf = str_replace(\"[{$name}]\", $value, $conf);\n        }\n\n        //写入应用配置文件\n        if(file_put_contents(APP_PATH . 'database.php', $conf)){\n            install_show_msg('配置文件写入成功');\n        } else {\n            install_show_msg('配置文件写入失败！', 'error');\n        }\n        return '';\n    }\n}\n\n/*\n    参数：\n    $sql_path:sql文件路径；\n    $old_prefix:原表前缀；\n    $new_prefix:新表前缀；\n    $separator:分隔符 参数可为\";\\n\"或\";\\r\\n\"或\";\\r\"\n*/\nfunction get_mysql_data($sql_path, $old_prefix = \"\", $new_prefix = \"\", $separator = \";\\n\")\n{\n\n    $commenter = array('#', '--');\n    //判断文件是否存在\n    if (!file_exists($sql_path))\n        return false;\n\n    $content = file_get_contents($sql_path);   //读取sql文件\n    $content = str_replace(array($old_prefix, \"\\r\"), array($new_prefix, \"\\n\"), $content);//替换前缀\n\n    //通过sql语法的语句分割符进行分割\n    $segment = explode($separator, trim($content));\n\n    //去掉注释和多余的空行\n    $data = array();\n    foreach ($segment as $statement) {\n        $sentence = explode(\"\\n\", $statement);\n        $newStatement = array();\n        foreach ($sentence as $subSentence) {\n            if ('' != trim($subSentence)) {\n                //判断是会否是注释\n                $isComment = false;\n                foreach ($commenter as $comer) {\n                    if (preg_match(\"/^(\" . $comer . \")/is\", trim($subSentence))) {\n                        $isComment = true;\n                        break;\n                    }\n                }\n                //如果不是注释，则认为是sql语句\n                if (!$isComment)\n                    $newStatement[] = $subSentence;\n            }\n        }\n        $data[] = $newStatement;\n    }\n\n    //组合sql语句\n    foreach ($data as $statement) {\n        $newStmt = '';\n        foreach ($statement as $sentence) {\n            $newStmt = $newStmt . trim($sentence) . \"\\n\";\n        }\n        if (!empty($newStmt)) {\n            $result[] = $newStmt;\n        }\n    }\n    return $result;\n}\n\n\n\n\n\n\n\n\n\n\n\n"
  },
  {
    "path": "application/install/config.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: 流年 <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\n// 应用公共文件\nreturn [\n    'template'               => [\n        // 模板引擎类型 支持 php think 支持扩展\n        'type'         => 'Think',\n        // 模板路径\n        'view_path'    => '',\n        // 模板后缀\n        'view_suffix'  => 'html',\n        // 模板文件名分隔符\n        'view_depr'    => '_',\n        // 模板引擎普通标签开始标记\n        'tpl_begin'    => '{',\n        // 模板引擎普通标签结束标记\n        'tpl_end'      => '}',\n        // 标签库标签开始标记\n        'taglib_begin' => '{',\n        // 标签库标签结束标记\n        'taglib_end'   => '}',\n    ],\n];"
  },
  {
    "path": "application/install/controller/IndexController.php",
    "content": "<?php\r\nnamespace app\\install\\controller;\r\nuse think\\Controller;\r\nuse think\\Db;\r\n\r\nclass IndexController extends Controller\r\n{\r\n    public function _initialize()\r\n    {\r\n        //资源加载\r\n        if(strstr(request()->baseFile(), 'public')){\r\n            $this->view->replace([\r\n                '__PUBLIC__'       =>  request()->root(true),\r\n            ]);\r\n        }else{\r\n            $this->view->replace([\r\n                '__PUBLIC__'       =>  request()->root(true).'/public',\r\n            ]);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 主页\r\n     */\r\n    public function index()\r\n    {\r\n        return view();\r\n    }\r\n\r\n    /**\r\n     * 安装环境检测\r\n     */\r\n    public function setup1()\r\n    {\r\n        $this->assign('check_env', check_env());\r\n        $this->assign('check_func', check_func());\r\n        $this->assign('check_dirfile', check_dirfile());\r\n\r\n        return view();\r\n    }\r\n\r\n    /**\r\n     * 安装程序\r\n     */\r\n    public function setup2()\r\n    {\r\n        return view();\r\n    }\r\n\r\n    /**\r\n     * 开始安装\r\n     */\r\n    public function setup3()\r\n    {\r\n        echo $this->fetch();\r\n\r\n        //检测信息\r\n        $data = input('post.');\r\n      \r\n        if (!$data['db']['hostname']) {\r\n            install_show_msg('请填写数据库地址！', false);\r\n        }\r\n        if (!$data['db']['hostport']) {\r\n            install_show_msg('请填写数据库端口！', false);\r\n        }\r\n        if (!$data['db']['database']) {\r\n            install_show_msg('请填写数据库名称！', false);\r\n        }\r\n        if (!$data['db']['username']) {\r\n            install_show_msg('请填写数据库用户名！', false);\r\n        }\r\n        if (!$data['username']) {\r\n            install_show_msg('请填写用户名/邮箱！', false);\r\n        }\r\n        if (!$data['password']) {\r\n            install_show_msg('请填写密码！', false);\r\n        }\r\n        if (!$data['password2']) {\r\n            install_show_msg('请填写重复密码！', false);\r\n        }\r\n        if ($data['password'] != $data['password2']) {\r\n            install_show_msg('重复密码不匹配！', false);\r\n        }\r\n\r\n        // 缓存数据库配置\r\n        session('db_config', $data['db']);\r\n\r\n        // 防止不存在的数据库导致连接数据库失败\r\n        $db_name = $data['db']['database'];\r\n        unset($data['db']['database']);\r\n\r\n        // 创建数据库连接\r\n        $db_instance = Db::connect($data['db']);\r\n        // 检测数据库连接\r\n        try{\r\n            $db_instance->execute('select version()');\r\n        }catch(\\Exception $e){\r\n            install_show_msg('数据库连接失败，请检查连接信息是否正确！', false);\r\n        }\r\n\r\n        $result = $db_instance->execute('SELECT * FROM information_schema.schemata WHERE schema_name=\"'.$db_name.'\"');\r\n        if ($result) {\r\n            install_show_msg('该数据库已存在，请更换名称！', false);\r\n        }\r\n\r\n        // 创建数据库\r\n        $sql2 = \"CREATE DATABASE IF NOT EXISTS `{$db_name}` DEFAULT CHARACTER SET utf8\";\r\n        $db_instance->execute($sql2) || install_show_msg($db_instance->getError(), false);\r\n        //修改数据库配置文件\r\n        write_config(session('db_config'));\r\n        $db_instance2 = Db::connect(session('db_config'));\r\n        // 开始安装\r\n        $file = './wemall7.sql';\r\n        $sqlData = get_mysql_data($file, '', '');\r\n        foreach ($sqlData as $sql) {\r\n            $db_instance2->execute($sql);\r\n        }\r\n        \r\n        //创建超级管理员\r\n        $db_instance2->name('admin')->where('id',1)->update(['username' => $data['username'],'password'=>md5($data['password'])]);\r\n        install_show_msg('超级管理员创建完成...');\r\n\r\n        //创建文件锁\r\n        file_put_contents('./data/install.lock', '');\r\n\r\n        //安装完毕\r\n        show_msg('安装程序执行完毕！重新安装需要删除./data/install.lock');\r\n        $adminUrl = url('../admin/index/index');\r\n        echo \"<script type=\\\"text/javascript\\\">insok(\\\"{$adminUrl}\\\")</script>\";\r\n    }\r\n\r\n\r\n}"
  },
  {
    "path": "application/install/data/database.tpl",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nreturn [\n    // 数据库类型\n    'type'            => 'mysql',\n    // 服务器地址\n    'hostname'        => '[hostname]',\n    // 数据库名\n    'database'        => '[database]',\n    // 用户名\n    'username'        => '[username]',\n    // 密码\n    'password'        => '[password]',\n    // 端口\n    'hostport'        => '[hostport]',\n    // 连接dsn\n    'dsn'             => '',\n    // 数据库连接参数\n    'params'          => [],\n    // 数据库编码默认采用utf8\n    'charset'         => 'utf8',\n    // 数据库表前缀\n    'prefix'          => '',\n    // 数据库调试模式\n    'debug'           => true,\n    // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)\n    'deploy'          => 0,\n    // 数据库读写是否分离 主从式有效\n    'rw_separate'     => false,\n    // 读写分离后 主服务器数量\n    'master_num'      => 1,\n    // 指定从服务器序号\n    'slave_no'        => '',\n    // 是否严格检查字段是否存在\n    'fields_strict'   => true,\n    // 数据集返回类型\n    'resultset_type'  => 'array',\n    // 自动写入时间戳字段\n    'auto_timestamp'  => false,\n    // 时间字段取出后的默认时间格式\n    'datetime_format' => 'Y-m-d H:i:s',\n    // 是否需要进行SQL性能分析\n    'sql_explain'     => false,\n];\n"
  },
  {
    "path": "application/install/view/index.html",
    "content": " "
  },
  {
    "path": "application/install/view/index_header.html",
    "content": "<!doctype html>\n<html>\n<head>\n    <meta charset=\"utf-8\">\n    <title>WeMall安装向导</title>\n    <link href=\"__PUBLIC__/install/css/base.css\" rel=\"stylesheet\" type=\"text/css\"/>\n    <link href=\"__PUBLIC__/install/css/style.css\" rel=\"stylesheet\" type=\"text/css\"/>\n    <script src=\"__PUBLIC__/install/js/jquery-1.10.2.min.js\"></script>\n    <script src=\"__PUBLIC__/install/js/install.js?v=2\"></script>\n</head>"
  },
  {
    "path": "application/install/view/index_index.html",
    "content": "{include file=\"index/header\" /}\r\n<body>\r\n<div class=\"g-install\">\r\n    <div class=\"m-head\">\r\n        <h1>WeMall使用协议</h1>\r\n    </div>\r\n    <div class=\"m-body\">\r\n        <p>版权完全遵循<a href=\"http://baike.baidu.com/subview/74918/8382747.htm#viewPageContent\" target=\"_blank\">MIT开源协议</a>，以下为基于\r\n            WeMall 的补充协议。</p>\r\n\r\n        <p>为了保证您和他人的利益请遵循以下几条使用规则：</p>\r\n\r\n        <p>1、您可以在完全遵循本协议的情况下，将 WeMall 用于商业用途，而不必支付使用费用，但我们也不承诺会对非赞助用户提供任何形式的技术支持；</p>\r\n\r\n        <p>2、使用 WeMall 您可以不用在明显页面保留程序版权信息，但程序最终版权仍归原作者所有，为了程序能持续发展建议您在网站底部注明：powered by\r\n            WeMall，另外我们可能不会对未保留版权信息的用户提供任何无偿的技术支持；</p>\r\n\r\n        <p>3、非授权用户后台版权与程序内版权信息不可以去除，这是我们唯一可以保护自己权益的地方；</p>\r\n\r\n        <p>4、您可以免费使用 WeMall ，修改源代码或界面风格以适应您的实际要求，但是禁止对软件进行改名发布，禁止以任何形式对 WeMall 形成竞争；</p>\r\n\r\n        <p>5、您可以对 WeMall 进行二次开发，但禁止重新分发任何在 WeMall 的整体或任何部分基础上发展的派生版本、修改版本或第三方版本，可以自己分配使用版权请参考第四条；</p>\r\n\r\n        <p>6、如果您在您的程序如引用WeMall的功能或者设计，请在明显的地方如官网等地方加入本设计或功能采用 WeMall ；</p>\r\n\r\n        <p>7、自您开始使用 WeMall 时本协议已自动生效；</p>\r\n\r\n        <p>8、如果您未能遵守本协议的条款3、条款4、条款5、条款6，您的免费使用授权将被终止，并将依法承担相应法律责任。</p>\r\n    </div>\r\n    <div class=\"m-foot\">\r\n        <a href=\"javascript:;\" onclick=\"no()\">不同意</a>\r\n        <a href=\"{:url('setup1')}\" class=\"submit\">同意</a>\r\n    </div>\r\n</div>\r\n</body>\r\n</html>"
  },
  {
    "path": "application/install/view/index_setup1.html",
    "content": "{include file=\"index/header\" /}\r\n\r\n<body>\r\n    <div class=\"g-install\">\r\n        <div class=\"m-head\">\r\n            <h1>WeMall安装环境测试</h1>\r\n        </div>\r\n        <div class=\"m-body\">\r\n            <div class=\"tt\"></div>\r\n            <div class=\"m-form\">\r\n                <legend>功能支持检测</legend>\r\n                {volist name=\"check_env\" id=\"vo\"}\r\n                    <div class=\"formitm\">\r\n                        <label class=\"lab\">{$vo.0}：</label>\r\n                        <div class=\"ipt\">\r\n                            {$vo.3}&nbsp;&nbsp;&nbsp;&nbsp;\r\n                            <?php if ($vo[4] == 'error'){\r\n            echo \"<font color=red><b>×</b></font>\";\r\n                        } else {\r\n                        echo \"<font color=green><b>√</b></font>\";\r\n                        } ?>\r\n                        </div>\r\n                    </div>\r\n                {/volist}\r\n                <legend>函数支持检测</legend>\r\n                {volist name=\"check_func\" id=\"vo\"}\r\n                    <div class=\"formitm\">\r\n                        <label class=\"lab\">{$vo.0}：</label>\r\n                        <div class=\"ipt\">\r\n                            {$vo.1}&nbsp;&nbsp;&nbsp;&nbsp;\r\n                            <?php if ($vo[2] == 'error'){\r\n            echo \"<font color=red><b>×</b></font>\";\r\n                        } else {\r\n                        echo \"<font color=green><b>√</b></font>\";\r\n                        } ?>\r\n                        </div>\r\n                    </div>\r\n                {/volist}\r\n                <div class=\"formitm\"> 以上模块功能如果不可用可能会影响到系统的部分功能将无法使用</div>\r\n                <legend>目录权限检测</legend>\r\n                {volist name=\"check_dirfile\" id=\"vo\"}\r\n                    <div class=\"formitm\">\r\n                        <label class=\"lab\">{$vo.1}：</label>\r\n                        <div class=\"ipt\">\r\n                            {$vo.3}&nbsp;&nbsp;&nbsp;&nbsp;\r\n                            <?php if ($vo[2] == 'error'){\r\n            echo \"<font color=red><b>×</b></font>\";\r\n                        } else {\r\n                        echo \"<font color=green><b>√</b></font>\";\r\n                        } ?>\r\n                        </div>\r\n                    </div>\r\n                {/volist}\r\n            </div>\r\n        </div>\r\n        <div class=\"m-foot\"><a href=\"{:url('index')}\">上一步</a>\r\n            <?php if (!function_exists('mysql_connect')||!function_exists('mysql_pconnect')){ ?>\r\n            <a href=\"javascript:;\" onclick=\"alert('关键功能无法使用，无法继续操作！')\">下一步</a>\r\n            <?php }else { ?>\r\n            <a href=\"{:url('setup2')}\" class=\"submit\">下一步</a>\r\n            <?php } ?>\r\n        </div>\r\n    </div>\r\n</body>\r\n\r\n</html>\r\n"
  },
  {
    "path": "application/install/view/index_setup2.html",
    "content": "{include file=\"index/header\" /}\r\n\r\n<body>\r\n<div class=\"g-install\">\r\n    <div class=\"m-head\">\r\n        <h1>WeMall安装配置</h1>\r\n    </div>\r\n    <form action=\"{:url('setup3')}\" method=\"post\">\r\n        <div class=\"m-body\">\r\n            <div class=\"tt\"></div>\r\n            <div class=\"m-form\">\r\n                <div class=\"form-group\">\r\n                    <label class=\"lab\">数据库类型</label>\r\n                    <div class=\"ipt\">\r\n                        <input type=\"radio\" name=\"db[type]\" checked=\"\" value=\"mysql\"><span></span> MySQL\r\n                    </div>\r\n                </div>\r\n                <div class=\"formitm\">\r\n                    <label class=\"lab\">数据库地址：</label>\r\n\r\n                    <div class=\"ipt\">\r\n                        <input type=\"text\" class=\"u-element\" name=\"db[hostname]\" value=\"127.0.0.1\"/>\r\n                    </div>\r\n                </div>\r\n                <div class=\"formitm\">\r\n                    <label class=\"lab\">数据库端口：</label>\r\n\r\n                    <div class=\"ipt\">\r\n                        <input type=\"text\" class=\"u-element\" name=\"db[hostport]\" value=\"3306\"/>\r\n                    </div>\r\n                </div>\r\n                <div class=\"formitm\">\r\n                    <label class=\"lab\">数据库名称：</label>\r\n\r\n                    <div class=\"ipt\">\r\n                        <input type=\"text\" class=\"u-element\" name=\"db[database]\" value=\"wemall\"/>\r\n                    </div>\r\n                </div>\r\n                <div class=\"formitm\">\r\n                    <label class=\"lab\">数据库用户名：</label>\r\n\r\n                    <div class=\"ipt\">\r\n                        <input type=\"text\" class=\"u-element\" name=\"db[username]\" value=\"root\"/>\r\n                    </div>\r\n                </div>\r\n                <div class=\"formitm\">\r\n                    <label class=\"lab\">数据库密码：</label>\r\n\r\n                    <div class=\"ipt\">\r\n                        <input type=\"text\" class=\"u-element\" name=\"db[password]\" value=\"\"/>\r\n                    </div>\r\n                </div>\r\n\r\n                <div style=\"color: #ffffff;width: 100px;height: 30px;background-color:#dd4b39;position: relative;left: -20px;text-align: center;margin-top: 16px; \">\r\n                    超级管理员\r\n                </div>\r\n                <div class=\"formitm\">\r\n                    <label class=\"lab\">用户名/邮箱：</label>\r\n\r\n                    <div class=\"ipt\">\r\n                        <input type=\"text\" class=\"u-element\" name=\"username\" value=\"\"/>\r\n                    </div>\r\n                </div>\r\n                <div class=\"formitm\">\r\n                    <label class=\"lab\">密码：</label>\r\n\r\n                    <div class=\"ipt\">\r\n                        <input type=\"password\" class=\"u-element\" name=\"password\" value=\"\"/>\r\n                    </div>\r\n                </div>\r\n                <div class=\"formitm\">\r\n                    <label class=\"lab\">重复密码：</label>\r\n\r\n                    <div class=\"ipt\">\r\n                        <input type=\"password\" class=\"u-element\" name=\"password2\" value=\"\"/>\r\n                    </div>\r\n                </div>\r\n\r\n            </div>\r\n        </div>\r\n        <div class=\"m-foot\">\r\n            <a href=\"{:url('setup1')}\">上一步</a>\r\n            <button type=\"submit\" class=\"submit\">安装</button>\r\n        </div>\r\n    </form>\r\n</div>\r\n</body>\r\n</html>"
  },
  {
    "path": "application/install/view/index_setup3.html",
    "content": "{include file=\"index/header\" /}\r\n<body>\r\n<div class=\"g-install\">\r\n    <div class=\"m-head\">\r\n        <h1>WeMall安装进行中</h1>\r\n    </div>\r\n    <div class=\"m-body\">\r\n        <div class=\"m-log\">\r\n\r\n        </div>\r\n    </div>\r\n    <div class=\"m-foot\">\r\n        <a href=\"javascript:;\">安装中...</a>\r\n    </div>\r\n</div>\r\n</body>\r\n</html>"
  },
  {
    "path": "application/route.php",
    "content": "<?php\r\n// +----------------------------------------------------------------------\r\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\r\n// +----------------------------------------------------------------------\r\n// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.\r\n// +----------------------------------------------------------------------\r\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\r\n// +----------------------------------------------------------------------\r\n// | Author: liu21st <liu21st@gmail.com>\r\n// +----------------------------------------------------------------------\r\nuse think\\Route;\r\nRoute::any('addons/:v/:addon/index', 'app/addons/index',['ext'=>'html']);\r\nRoute::any('static', \"app/index/themeStatic\");\r\nRoute::any('tpl/theme', \"app/index/source\");\r\n"
  },
  {
    "path": "application/tags.php",
    "content": "<?php\r\n// +----------------------------------------------------------------------\r\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\r\n// +----------------------------------------------------------------------\r\n// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.\r\n// +----------------------------------------------------------------------\r\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\r\n// +----------------------------------------------------------------------\r\n// | Author: liu21st <liu21st@gmail.com>\r\n// +----------------------------------------------------------------------\r\n\r\n// 应用行为扩展定义文件\r\nreturn [\r\n    // 应用初始化\r\n    'app_init'     => [],\r\n    // 应用开始\r\n    'app_begin'    => [\r\n        'app\\\\common\\\\behavior\\\\Config', // 注册配置行为\r\n    ],\r\n    // 模块初始化\r\n    'module_init'  => [],\r\n    // 操作开始执行\r\n    'action_begin' => [],\r\n    // 视图内容过滤\r\n    'view_filter'  => [],\r\n    // 日志写入\r\n    'log_write'    => [],\r\n    // 应用结束\r\n    'app_end'      => [],\r\n];\r\n"
  },
  {
    "path": "build.php",
    "content": "<?php\r\n// +----------------------------------------------------------------------\r\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\r\n// +----------------------------------------------------------------------\r\n// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.\r\n// +----------------------------------------------------------------------\r\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\r\n// +----------------------------------------------------------------------\r\n// | Author: liu21st <liu21st@gmail.com>\r\n// +----------------------------------------------------------------------\r\n\r\nreturn [\r\n    // 生成应用公共文件\r\n    '__file__' => ['common.php', 'config.php', 'database.php'],\r\n\r\n    // 定义demo模块的自动生成 （按照实际定义的文件名生成）\r\n    'demo'     => [\r\n        '__file__'   => ['common.php'],\r\n        '__dir__'    => ['behavior', 'controller', 'model', 'view'],\r\n        'controller' => ['Index', 'Test', 'UserType'],\r\n        'model'      => ['User', 'UserType'],\r\n        'view'       => ['index/index'],\r\n    ],\r\n    // 其他更多的模块定义\r\n];\r\n"
  },
  {
    "path": "composer.json",
    "content": "{\r\n    \"name\": \"topthink/think\",\r\n    \"description\": \"the new thinkphp framework\",\r\n    \"type\": \"project\",\r\n    \"keywords\": [\r\n        \"framework\",\r\n        \"thinkphp\",\r\n        \"ORM\"\r\n    ],\r\n    \"homepage\": \"http://thinkphp.cn/\",\r\n    \"license\": \"Apache-2.0\",\r\n    \"authors\": [\r\n        {\r\n            \"name\": \"liu21st\",\r\n            \"email\": \"liu21st@gmail.com\"\r\n        }\r\n    ],\r\n    \"require\": {\r\n        \"php\": \">=5.4.0\",\r\n        \"topthink/framework\": \"^5.0\",\r\n        \"topthink/think-captcha\": \"^1.0\",\r\n        \"qingyuexi/think-addons\": \"^1.0\",\r\n        \"phpoffice/phpexcel\": \"^1.8\",\r\n        \"phpmailer/phpmailer\": \"^5.2\",\r\n        \"flc/alidayu\": \"^2.0\"\r\n    },\r\n    \"extra\": {\r\n        \"think-path\": \"thinkphp\"\r\n    },\r\n    \"config\": {\r\n        \"preferred-install\": \"dist\"\r\n    }\r\n}\r\n"
  },
  {
    "path": "data/index.html",
    "content": ""
  },
  {
    "path": "extend/com/Auth.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2011 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: luofei614 <weibo.com/luofei614>　\n// +----------------------------------------------------------------------\nnamespace com;\n/**\n * 权限认证类\n * 功能特性：\n * 1，是对规则进行认证，不是对节点进行认证。用户可以把节点当作规则名称实现对节点进行认证。\n *      $auth=new Auth();  $auth->check('规则名称','用户id')\n * 2，可以同时对多条规则进行认证，并设置多条规则的关系（or或者and）\n *      $auth=new Auth();  $auth->check('规则1,规则2','用户id','and') \n *      第三个参数为and时表示，用户需要同时具有规则1和规则2的权限。 当第三个参数为or时，表示用户值需要具备其中一个条件即可。默认为or\n * 3，一个用户可以属于多个用户组(think_auth_group_access表 定义了用户所属用户组)。我们需要设置每个用户组拥有哪些规则(think_auth_group 定义了用户组权限)\n * \n * 4，支持规则表达式。\n *      在think_auth_rule 表中定义一条规则时，如果type为1， condition字段就可以定义规则表达式。 如定义{score}>5  and {score}<100  表示用户的分数在5-100之间时这条规则才会通过。\n */\n\n//数据库\n/*\n-- ----------------------------\n-- think_auth_rule，规则表，\n-- id:主键，name：规则唯一标识, title：规则中文名称 status 状态：为1正常，为0禁用，condition：规则表达式，为空表示存在就验证，不为空表示按照条件验证\n-- ----------------------------\n DROP TABLE IF EXISTS `think_auth_rule`;\nCREATE TABLE `think_auth_rule` (  \n    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,  \n    `name` char(80) NOT NULL DEFAULT '',  \n    `title` char(20) NOT NULL DEFAULT '',  \n    `type` tinyint(1) NOT NULL DEFAULT '1',    \n    `status` tinyint(1) NOT NULL DEFAULT '1',  \n    `condition` char(100) NOT NULL DEFAULT '',  # 规则附件条件,满足附加条件的规则,才认为是有效的规则\n    PRIMARY KEY (`id`),  \n    UNIQUE KEY `name` (`name`)\n) ENGINE=MyISAM  DEFAULT CHARSET=utf8;\n-- ----------------------------\n-- think_auth_group 用户组表， \n-- id：主键， title:用户组中文名称， rules：用户组拥有的规则id， 多个规则\",\"隔开，status 状态：为1正常，为0禁用\n-- ----------------------------\n DROP TABLE IF EXISTS `think_auth_group`;\nCREATE TABLE `think_auth_group` ( \n    `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT, \n    `title` char(100) NOT NULL DEFAULT '', \n    `status` tinyint(1) NOT NULL DEFAULT '1', \n    `rules` char(80) NOT NULL DEFAULT '', \n    PRIMARY KEY (`id`)\n) ENGINE=MyISAM  DEFAULT CHARSET=utf8;\n-- ----------------------------\n-- think_auth_group_access 用户组明细表\n-- uid:用户id，group_id：用户组id\n-- ----------------------------\nDROP TABLE IF EXISTS `think_auth_group_access`;\nCREATE TABLE `think_auth_group_access` (  \n    `uid` mediumint(8) unsigned NOT NULL,  \n    `group_id` mediumint(8) unsigned NOT NULL, \n    UNIQUE KEY `uid_group_id` (`uid`,`group_id`),  \n    KEY `uid` (`uid`), \n    KEY `group_id` (`group_id`)\n) ENGINE=MyISAM DEFAULT CHARSET=utf8;\n */\n\nclass Auth{\n\n    //默认配置\n    protected $_config = array(\n        'auth_on'           => true,                      // 认证开关\n        'auth_type'         => 1,                         // 认证方式，1为实时认证；2为登录认证。\n        'auth_group'        => 'auth_group',        // 用户组数据表名\n        'auth_group_access' => 'auth_group_access', // 用户-用户组关系表\n        'auth_rule'         => 'auth_rule',         // 权限规则表\n        'auth_user'         => 'admin'             // 用户信息表\n    );\n\n    public function __construct() {\n        if (config('auth_config')) {\n            //可设置配置项 auth_config, 此配置项为数组。\n            $this->_config = array_merge($this->_config, config('auth_config'));\n        }\n    }\n\n    /**\n      * 检查权限\n      * @param name string|array  需要验证的规则列表,支持逗号分隔的权限规则或索引数组\n      * @param uid  int           认证用户的id\n      * @param string mode        执行check的模式\n      * @param relation string    如果为 'or' 表示满足任一条规则即通过验证;如果为 'and'则表示需满足所有规则才能通过验证\n      * @return boolean           通过验证返回true;失败返回false\n     */\n    public function check($name, $uid, $type=1, $mode='url', $relation='or') {\n        if (!$this->_config['auth_on'])\n            return true;\n        $authList = $this->getAuthList($uid,$type); //获取用户需要验证的所有有效规则列表\n\n        if (is_string($name)) {\n            $name = strtolower($name);\n            if (strpos($name, ',') !== false) {\n                $name = explode(',', $name);\n            } else {\n                $name = array($name);\n            }\n        }\n        $list = array(); //保存验证通过的规则名\n        if ($mode=='url') {\n            $REQUEST = unserialize( strtolower(serialize($_REQUEST)) );\n        }\n        foreach ( $authList as $auth ) {\n            $query = preg_replace('/^.+\\?/U','',$auth);\n            if ($mode=='url' && $query!=$auth ) {\n                parse_str($query,$param); //解析规则中的param\n                $intersect = array_intersect_assoc($REQUEST,$param);\n                $auth = preg_replace('/\\?.*$/U','',$auth);\n                if ( in_array($auth,$name) && $intersect==$param ) {  //如果节点相符且url参数满足\n                    $list[] = $auth ;\n                }\n            }else if (in_array($auth , $name)){\n                $list[] = $auth ;\n            }\n        }\n        if ($relation == 'or' and !empty($list)) {\n            return true;\n        }\n        $diff = array_diff($name, $list);\n        if ($relation == 'and' and empty($diff)) {\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 根据用户id获取用户组,返回值为数组\n     * @param  uid int     用户id\n     * @return array       用户所属的用户组 array(\n     *     array('uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'),\n     *     ...)   \n     */\n    public function getGroups($uid) {\n        static $groups = array();\n        if (isset($groups[$uid]))\n            return $groups[$uid];\n        $user_groups = \\think\\Db::name('auth_group_access')\n            ->alias('a')\n            ->join(\"auth_group g\", \"g.id=a.group_id\")\n            ->where(\"a.uid='$uid' and g.status='1'\")\n            ->field('uid,group_id,title,rules')->select();\n        $groups[$uid] = $user_groups ? $user_groups : array();\n     \n        return $groups[$uid];\n    }\n\n    /**\n     * 获得权限列表\n     * @param integer $uid  用户id\n     * @param integer $type \n     */\n    protected function getAuthList($uid,$type) {\n        static $_authList = array(); //保存用户验证通过的权限列表\n        $t = implode(',',(array)$type);\n        if (isset($_authList[$uid.$t])) {\n            return $_authList[$uid.$t];\n        }\n\n        if( $this->_config['auth_type']==2 && \\think\\Session::get('_auth_list_'.$uid.$t)){\n            return \\think\\Session::get('_auth_list_'.$uid.$t);\n        }\n\n        //读取用户所属用户组\n        $groups = $this->getGroups($uid);\n\n        $ids = array();//保存用户所属用户组设置的所有权限规则id\n        foreach ($groups as $g) {\n            $ids = array_merge($ids, explode(',', trim($g['rules'], ',')));\n        }\n        $ids = array_unique($ids);\n        if (empty($ids)) {\n            $_authList[$uid.$t] = array();\n            return array();\n        }\n\n        $map=array(\n            'id'=>array('in',$ids),\n            'type'=>$type,\n            'status'=>1,\n        );\n\n        //读取用户组所有权限规则\n        $rules = \\think\\Db::name('auth_rule')->where($map)->field('condition,name')->select();\n\n        //循环规则，判断结果。\n        $authList = array();   //\n        foreach ($rules as $rule) {\n            if (!empty($rule['condition'])) { //根据condition进行验证\n                $user = $this->getUserInfo($uid);//获取用户信息,一维数组\n\n                $command = preg_replace('/\\{(\\w*?)\\}/', '$user[\\'\\\\1\\']', $rule['condition']);\n                //dump($command);//debug\n                @(eval('$condition=(' . $command . ');'));\n                if ($condition) {\n                    $authList[] = strtolower($rule['name']);\n                }\n            } else {\n                //只要存在就记录\n                $authList[] = strtolower($rule['name']);\n            }\n        }\n        $_authList[$uid.$t] = $authList;\n        if($this->_config['auth_type']==2){\n            //规则列表结果保存到session\n            \\think\\Session::set('_auth_list_'.$uid.$t, $authList);\n        }\n        return array_unique($authList);\n    }\n\n    /**\n     * 获得用户资料,根据自己的情况读取数据库\n     */\n    protected function getUserInfo($uid) {\n        static $userinfo=array();\n        if(!isset($userinfo[$uid])){\n             $userinfo[$uid]=\\think\\Db::name('admin')->where('id',$uid)->find();\n        }\n        return $userinfo[$uid];\n    }\n\n}\n"
  },
  {
    "path": "index.php",
    "content": "<?php\n/**\n * \n * @authors 清月曦 (1604583867@qq.com)\n * @date    2017-05-01 11:20:54\n * @version $Id$\n */\n// [ 应用入口文件 ]\n\n// 定义应用目录\ndefine('APP_PATH', __DIR__ . '/application/');\ndefine('DATA_PATH', __DIR__ . '/data/');\ndefine('PUBLIC_PATH', '/public');\n\n// 检查是否安装\nif(!is_file('./data/install.lock')){\n\t// 检测PHP环境\n\tif (version_compare(PHP_VERSION, '5.4.0', '<')) die('require PHP > 5.4.0 !');\n\t// 绑定模块\n    define('BIND_MODULE', 'install');\n}\n// 加载框架引导文件\nrequire __DIR__ . '/thinkphp/start.php';"
  },
  {
    "path": "public/.htaccess",
    "content": "<IfModule mod_rewrite.c>\r\n  Options +FollowSymlinks -Multiviews\r\n  RewriteEngine On\r\n\r\n  RewriteCond %{REQUEST_FILENAME} !-d\r\n  RewriteCond %{REQUEST_FILENAME} !-f\r\n  RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]\r\n</IfModule>\r\n"
  },
  {
    "path": "public/index.php",
    "content": "<?php\r\n// +----------------------------------------------------------------------\r\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\r\n// +----------------------------------------------------------------------\r\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\r\n// +----------------------------------------------------------------------\r\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\r\n// +----------------------------------------------------------------------\r\n// | Author: liu21st <liu21st@gmail.com>\r\n// +----------------------------------------------------------------------\r\n\r\n// [ 应用入口文件 ]\r\n\r\n// 定义应用目录\r\ndefine('APP_PATH', __DIR__ . '/../application/');\r\n// 加载框架引导文件\r\nrequire __DIR__ . '/../thinkphp/start.php';\r\n"
  },
  {
    "path": "public/install/css/base.css",
    "content": "@charset \"utf-8\";\r\n\r\n/* reset */\r\nhtml, body, h1, h2, h3, h4, h5, h6, div, dl, dt, dd, ul, ol, li, p, blockquote, pre, hr, figure, table, caption, th, td, form, fieldset, legend, input, button, textarea, menu {\r\n    margin: 0;\r\n    padding: 0;\r\n    font-family: \"Microsoft YaHei\"\r\n}\r\n\r\nheader, footer, section, article, aside, nav, hgroup, address, figure, figcaption, menu, details {\r\n    display: block;\r\n}\r\n\r\ntable {\r\n    border-collapse: collapse;\r\n    border-spacing: 0;\r\n}\r\n\r\ncaption, th {\r\n    text-align: left;\r\n    font-weight: normal;\r\n}\r\n\r\nhtml, body, fieldset, img, iframe, abbr {\r\n    border: 0;\r\n}\r\n\r\ni, cite, em, var, address, dfn {\r\n    font-style: normal;\r\n}\r\n\r\n[hidefocus], summary {\r\n    outline: 0;\r\n}\r\n\r\nli {\r\n    list-style: none;\r\n}\r\n\r\nh1, h2, h3, h4, h5, h6, small {\r\n    font-size: 100%;\r\n}\r\n\r\nsup, sub {\r\n    font-size: 83%;\r\n}\r\n\r\npre, code, kbd, samp {\r\n    font-family: inherit;\r\n}\r\n\r\nq:before, q:after {\r\n    content: none;\r\n}\r\n\r\ntextarea {\r\n    overflow: auto;\r\n    resize: none;\r\n}\r\n\r\nlabel, summary {\r\n    cursor: default;\r\n}\r\n\r\na, button {\r\n    cursor: pointer;\r\n}\r\n\r\nh1, h2, h3, h4, h5, h6, em, strong, b {\r\n    font-weight: bold;\r\n}\r\n\r\ndel, ins, u, s, a, a:hover {\r\n    text-decoration: none;\r\n}\r\n\r\nbody, textarea, input, button, select, keygen, legend {\r\n    color: #333;\r\n    outline: 0;\r\n}\r\n\r\nbody {\r\n    background: #fff;\r\n}\r\n\r\na, a:hover {\r\n    color: #333;\r\n}\r\n\r\n/* function */\r\n.f-cb:after, .f-cbli li:after {\r\n    display: block;\r\n    clear: both;\r\n    visibility: hidden;\r\n    height: 0;\r\n    overflow: hidden;\r\n    content: \".\";\r\n}\r\n\r\n.f-cb, .f-cbli li {\r\n    zoom: 1;\r\n}\r\n\r\n.f-ib {\r\n    display: inline-block;\r\n    *display: inline;\r\n    *zoom: 1;\r\n}\r\n\r\n.f-dn {\r\n    display: none;\r\n}\r\n\r\n.f-db {\r\n    display: block;\r\n}\r\n\r\n.f-fl {\r\n    float: left;\r\n}\r\n\r\n.f-fr {\r\n    float: right;\r\n}\r\n\r\n.f-pr {\r\n    position: relative;\r\n}\r\n\r\n.f-prz {\r\n    position: relative;\r\n    zoom: 1;\r\n}\r\n\r\n.f-oh {\r\n    overflow: hidden;\r\n}\r\n\r\n.f-ff0 {\r\n    font-family: arial, \\5b8b\\4f53;\r\n}\r\n\r\n.f-ff1 {\r\n    font-family: \"Microsoft YaHei\", \\5fae\\8f6f\\96c5\\9ed1, arial, \\5b8b\\4f53;\r\n}\r\n\r\n.f-fs1 {\r\n    font-size: 12px;\r\n}\r\n\r\n.f-fs2 {\r\n    font-size: 14px;\r\n}\r\n\r\n.f-fwn {\r\n    font-weight: normal;\r\n}\r\n\r\n.f-fwb {\r\n    font-weight: bold;\r\n}\r\n\r\n.f-tal {\r\n    text-align: left;\r\n}\r\n\r\n.f-tac {\r\n    text-align: center;\r\n}\r\n\r\n.f-tar {\r\n    text-align: right;\r\n}\r\n\r\n.f-taj {\r\n    text-align: justify;\r\n    text-justify: inter-ideograph;\r\n}\r\n\r\n.f-vam, .f-vama * {\r\n    vertical-align: middle;\r\n}\r\n\r\n.f-wsn {\r\n    word-wrap: normal;\r\n    white-space: nowrap;\r\n}\r\n\r\n.f-pre {\r\n    overflow: hidden;\r\n    text-align: left;\r\n    white-space: pre-wrap;\r\n    word-wrap: break-word;\r\n    word-break: break-all;\r\n}\r\n\r\n.f-wwb {\r\n    white-space: normal;\r\n    word-wrap: break-word;\r\n    word-break: break-all;\r\n}\r\n\r\n.f-ti {\r\n    overflow: hidden;\r\n    text-indent: -30000px;\r\n}\r\n\r\n.f-ti2 {\r\n    text-indent: 2em;\r\n}\r\n\r\n.f-lhn {\r\n    line-height: normal;\r\n}\r\n\r\n.f-tdu, .f-tdu:hover {\r\n    text-decoration: underline;\r\n}\r\n\r\n.f-tdn, .f-tdn:hover {\r\n    text-decoration: none;\r\n}\r\n\r\n.f-toe {\r\n    overflow: hidden;\r\n    word-wrap: normal;\r\n    white-space: nowrap;\r\n    text-overflow: ellipsis;\r\n}\r\n\r\n.f-csp {\r\n    cursor: pointer;\r\n}\r\n\r\n.f-csd {\r\n    cursor: default;\r\n}\r\n\r\n.f-csh {\r\n    cursor: help;\r\n}\r\n\r\n.f-csm {\r\n    cursor: move;\r\n}\r\n\r\n.f-usn {\r\n    -webkit-user-select: none;\r\n    -moz-user-select: none;\r\n    -ms-user-select: none;\r\n    -o-user-select: none;\r\n    user-select: none;\r\n}\r\n\r\n/* animation */\r\n/* 淡入 */\r\n.a-fadein {\r\n    -webkit-animation-name: fadein;\r\n    -moz-animation-name: fadein;\r\n    -ms-animation-name: fadein;\r\n    animation-name: fadein;\r\n}\r\n\r\n/* define */\r\n/* 淡入 */\r\n@-webkit-keyframes fadein {\r\n    0% {\r\n        opacity: 0;\r\n    }\r\n    100% {\r\n        opacity: 1;\r\n    }\r\n}\r\n\r\n@-moz-keyframes fadein {\r\n    0% {\r\n        opacity: 0;\r\n    }\r\n    100% {\r\n        opacity: 1;\r\n    }\r\n}\r\n\r\n@-ms-keyframes fadein {\r\n    0% {\r\n        opacity: 0;\r\n    }\r\n    100% {\r\n        opacity: 1;\r\n    }\r\n}\r\n\r\n@keyframes fadein {\r\n    0% {\r\n        opacity: 0;\r\n    }\r\n    100% {\r\n        opacity: 1;\r\n    }\r\n}\r\n\r\n"
  },
  {
    "path": "public/install/css/style.css",
    "content": "body {\r\n    color: #333333;\r\n    font-size: 14px;\r\n    font-family: '微软雅黑';\r\n    background-color: #f2f2f2;\r\n}\r\n\r\na {\r\n    border-bottom: 1px dashed #06C;\r\n    color: #06C\r\n}\r\n\r\na:hover {\r\n    color: #F60\r\n}\r\n\r\n.g-install {\r\n    width: 640px;\r\n    margin-right: auto;\r\n    margin-left: auto;\r\n    margin-top: 30px;\r\n    background-color: #FFF;\r\n    border: 1px solid #eee;\r\n}\r\n\r\n.m-head {\r\n    color: #fff;\r\n    background-color: #dd4b39;\r\n    text-align: center;\r\n    padding: 20px 0;\r\n}\r\n\r\n.m-head h1 {\r\n    font-size: 26px;\r\n    font-weight: bold;\r\n}\r\n\r\n.m-body {\r\n    padding: 20px;\r\n    line-height: 25px;\r\n}\r\n\r\n.m-body p {\r\n    padding-top: 10px;\r\n}\r\n\r\n.m-foot {\r\n    border-top: 1px solid #eee;\r\n    padding: 30px 0;\r\n    text-align: center\r\n}\r\n\r\n.m-foot a, .m-foot button {\r\n    padding: 8px 15px;\r\n    margin: 0 5px;\r\n    background-color: #f5f5f5;\r\n    color: #666;\r\n    border: 0;\r\n}\r\n\r\n.m-foot .submit {\r\n    background-color: #dd4b39;\r\n    color: #fff;\r\n}\r\n\r\n.m-form {\r\n    line-height: 29px;\r\n    color: #555;\r\n}\r\n\r\n.m-form legend {\r\n    font-size: 14px;\r\n    font-weight: bold;\r\n    margin-top: 20px;\r\n}\r\n\r\n.m-form .formitm {\r\n    padding: 20px 0 0;\r\n    line-height: 25px;\r\n}\r\n\r\n.m-form .lab {\r\n    float: left;\r\n    width: 140px;\r\n    margin-right: -140px;\r\n    text-align: left;\r\n}\r\n\r\n.m-form .ipt {\r\n    margin-left: 150px;\r\n}\r\n\r\n.u-element {\r\n    border: 1px solid #ddd;\r\n    color: #444;\r\n    background: #fff;\r\n    padding: 5px 5px;\r\n    max-width: 100%;\r\n    vertical-align: middle;\r\n    width: 260px;\r\n}\r\n\r\n.m-log {\r\n}\r\n\r\n.m-log .error {\r\n    color: #F00\r\n}\r\n"
  },
  {
    "path": "public/install/js/install.js",
    "content": "function no() {\r\n    alert('感谢您对WeMall的支持！');\r\n    window.close();\r\n}\r\nfunction showmsg(msg, tyle) {\r\n    var html = '<p class=\"' + tyle + '\">' + msg + '</p>';\r\n    $('.m-log').append(html);\r\n}\r\nfunction insok(adminUrl) {\r\n    var html = '\\\r\n\t<a href=\"' + adminUrl + '\" class=\"submit\">进入后台</a>\\\r\n\t';\r\n    $('.m-foot').html(html);\r\n}"
  },
  {
    "path": "public/robots.txt",
    "content": "User-agent: *\r\nDisallow:\r\n"
  },
  {
    "path": "public/router.php",
    "content": "<?php\r\n// +----------------------------------------------------------------------\r\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\r\n// +----------------------------------------------------------------------\r\n// | Copyright (c) 2006~2016 http://thinkphp.cn All rights reserved.\r\n// +----------------------------------------------------------------------\r\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\r\n// +----------------------------------------------------------------------\r\n// | Author: liu21st <liu21st@gmail.com>\r\n// +----------------------------------------------------------------------\r\n// $Id$\r\n\r\nif (is_file($_SERVER[\"DOCUMENT_ROOT\"] . $_SERVER[\"REQUEST_URI\"])) {\r\n    return false;\r\n} else {\r\n    require __DIR__ . \"/index.php\";\r\n}\r\n"
  },
  {
    "path": "public/static/article/page_mp_article_improve2756b8.css",
    "content": "html{-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%;line-height:1.6}body{-webkit-touch-callout:none;font-family:\"Helvetica Neue\",Helvetica,\"Hiragino Sans GB\",\"Microsoft YaHei\",Arial,sans-serif;background-color:#f3f3f3;line-height:inherit}h1,h2,h3,h4,h5,h6{font-weight:400;font-size:16px}*{margin:0;padding:0;font-style:normal}a{color:#607fa6;text-decoration:none}.rich_media_inner{font-size:16px;word-wrap:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}.rich_media_area_primary{position:relative;padding:20px 15px 15px;background-color:#fff}.rich_media_area_primary:before{content:\" \";position:absolute;left:0;top:0;width:100%;height:1px;border-top:1px solid #e5e5e5;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(0.5);transform:scaleY(0.5);top:auto;bottom:-2px}.rich_media_area_extra{padding:0 15px 0}.rich_media_title{margin-bottom:10px;line-height:1.4;font-weight:400;font-size:24px}.rich_media_meta_list{margin-bottom:18px;line-height:20px;font-size:0}.rich_media_meta{display:inline-block;vertical-align:middle;margin-right:8px;margin-bottom:10px;font-size:16px}.meta_original_tag{line-height:100px;overflow:hidden;background:transparent url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/icon_original_tag.2x25ab3f.png) no-repeat 0 0;width:49px;height:20px;vertical-align:middle;display:inline-block;-webkit-background-size:100% auto;background-size:100% auto}.meta_enterprise_tag img{width:30px;height:30px!important;display:block;position:relative;margin-top:-3px;border:0}.rich_media_meta_text{color:#8c8c8c}.rich_media_meta_nickname{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:9em}span.rich_media_meta_nickname{display:none}.rich_media_thumb{width:100%;margin-bottom:6px}.rich_media_content{overflow:hidden;color:#3e3e3e}.rich_media_content *{max-width:100%!important;box-sizing:border-box!important;-webkit-box-sizing:border-box!important;word-wrap:break-word!important}.rich_media_content p{clear:both;min-height:1em;white-space:pre-wrap}.rich_media_content em{font-style:italic}.rich_media_content fieldset{min-width:0}.rich_media_content .list-paddingleft-2{padding-left:30px}.rich_media_content blockquote{margin:0;padding-left:10px;border-left:3px solid #dbdbdb}img{height:auto!important}@media(min-device-width:375px) and (max-device-width:667px) and (-webkit-min-device-pixel-ratio:2){.mm_appmsg .rich_media_inner,.mm_appmsg .rich_media_meta,.mm_appmsg .discuss_list,.mm_appmsg .rich_media_extra,.mm_appmsg .title_tips .tips{font-size:17px}}@media(min-device-width:414px) and (max-device-width:736px) and (-webkit-min-device-pixel-ratio:3){.mm_appmsg .rich_media_title{font-size:25px}}.original_tool_area{display:block;padding:.75em 1em 0;-webkit-tap-highlight-color:rgba(0,0,0,0);color:#3e3e3e;border:1px solid #eaeaea;margin:20px 0}.original_tool_area .radius_avatar{display:inline-block;background-color:#fff;padding:3px;border-radius:50%;-moz-border-radius:50%;-webkit-border-radius:50%;overflow:hidden;vertical-align:middle}.original_tool_area .radius_avatar img{width:100%;height:100%;border-radius:50%;-moz-border-radius:50%;-webkit-border-radius:50%;background-color:#eee}.original_tool_area .tips_global{position:relative;padding-bottom:.5em;font-size:15px}.original_tool_area .tips_global:after{content:\" \";position:absolute;left:0;bottom:0;width:100%;height:1px;border-bottom:1px solid #dbdbdb;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(0.5);transform:scaleY(0.5)}.original_tool_area .radius_avatar{width:27px;height:27px;padding:0;margin-right:.5em}.original_tool_area .radius_avatar img{height:100%!important}.original_tool_area .cell{padding:.8em 0;display:block;position:relative}.original_tool_area .cell_hd,.original_tool_area .cell_bd,.original_tool_area .cell_ft{display:table-cell;vertical-align:middle;word-wrap:break-word;word-break:break-all;white-space:nowrap}.original_tool_area .cell_primary{width:2000px;white-space:normal}.original_tool_area .icon_access:before{content:\" \";display:inline-block;height:8px;width:8px;border-width:1px 1px 0 0;border-color:#cbcad0;border-style:solid;transform:matrix(0.71,0.71,-0.71,0.71,0,0);-ms-transform:matrix(0.71,0.71,-0.71,0.71,0,0);-webkit-transform:matrix(0.71,0.71,-0.71,0.71,0,0);position:relative;top:-2px;top:-1px}"
  },
  {
    "path": "public/static/article/page_mp_article_improve_combo2805ea.css",
    "content": ".selectTdClass{background-color:#edf5fa!important}table.noBorderTable td,table.noBorderTable th,table.noBorderTable caption{border:1px dashed #ddd!important}table{margin-bottom:10px;border-collapse:collapse;display:table;width:100%!important}td,th{word-wrap:break-word;word-break:break-all;padding:5px 10px;border:1px solid #DDD}caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center}th{border-top:2px solid #BBB;background:#f7f7f7}.ue-table-interlace-color-single{background-color:#fcfcfc}.ue-table-interlace-color-double{background-color:#f7faff}td p{margin:0;padding:0}.res_iframe{display:block;width:100%;background-color:transparent;border:0}.vote_area{display:block;position:relative;margin:14px 0;white-space:normal!important}.vote_iframe{display:block;width:100%;height:100%;background-color:transparent;border:0}form{display:none!important}@media screen and (min-width:0\\0) and (min-resolution:72dpi){.rich_media_content table{table-layout:fixed!important}.rich_media_content td,.rich_media_content th{width:auto!important}}.tc{text-align:center}.tl{text-align:left}.tr{text-align:right}.tips_global{color:#8c8c8c}.rich_split_tips{margin:20px 0;min-height:24px}.rich_media_tool_tips{margin-bottom:8px}.rich_media_tool{overflow:hidden;padding-top:15px;line-height:32px}.rich_media_tool .meta_primary{float:left;margin-right:10px}.rich_media_tool .meta_extra{float:right;margin-left:10px}.rich_media_tool .meta_praise{margin-right:0;margin-left:8px}.media_tool_meta i{vertical-align:0;position:relative;top:1px;margin-right:3px}.meta_praise{-webkit-tap-highlight-color:rgba(0,0,0,0);outline:0;min-width:3.5em}.meta_praise .praise_num{display:inline-block;vertical-align:top}.icon_praise_gray{background:transparent url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAA+CAYAAAA1dwvuAAAACXBIWXMAAA7EAAAOxAGVKw4bAAACd0lEQVRYhe2XMWhUMRjHfycdpDg4iJN26CQih4NUlFIc3iTasaAO+iZBnorIId2CDg6PLqWDXSy0p28TJ6ejILgoKiLFSeRcnASLnDf2HPKll8b3ah5NQPB+cHzJl0v+73J5Sf6NwWCAD6kqxoEV4BywCTwA2j59V9QlxrxUNJeBOSkfBtaAHvDcp/O+GkJHJd4H7kr5nm/nOkJHJH4FHkv5WAyhUxLfAgelvBlUKFXFBNCU6oYl+j6oEHohADwFtoDTUn8dTChVxX7gjlSfSJyS+CaYEDCPXs4d4IXkzDR+8BWqfI9SVUyil/ENST20ml8BF4Afu4z9HT3V80B/TAY9CxTABNAHxp1Oj4B1q34dWAamGa5Al0PALfSs3TS/aE1EcERWgQXgozPIN+Ai6O2ljFQVM8BLZJqN0KTEhgj9kvrViqf1wYz5BcoXQ38Pg9uckfiuSigU0xLXowmlqpgCjgNd4FM0IeCKxGcmEUtoRqLZScILpaqYA06iN9/tTTfGLzKvxLKdDCqUquIEcB59xK9GE2J4xLeBn3ZD1abaq/sQqSpmgWvo82rBbTdCPeAA4N69/noXS1XhphaBz27SPPVtapz/FXSBFsNDcgcN3wvkiBEjRoSndAtqLXXKvuvtYfMs+SP3T3tYm6ge1iaqh7UJ62HRTqNZko/mYV3CeVjA9rAuUTxsGd4edrcX1vWwddn2sHmWaA/bWuq4HnYLff3aC7U8bAiaMPyPJp3GhnxCUOlhQxPdwxrieViLbp4lUT2sIbqHNcTzsBYbeZZE9bCGeB7WIrqHNbTzLNnhYWMIlXpYI9Rz8gM8/GsFi3mW/Ace9jf8QZwIX5o4uQAAAABJRU5ErkJggg==) no-repeat 0 0;width:13px;height:13px;vertical-align:middle;display:inline-block;-webkit-background-size:100% auto;background-size:100% auto}.icon_praise_gray.praised{background-position:0 -18px}.praised .icon_praise_gray{background-position:0 -18px}.rich_tips{margin-top:25px;margin-bottom:0;min-height:24px;text-align:center}.rich_tips .tips{display:inline-block;vertical-align:middle}.rich_tips .tips,.rich_tips .rich_icon{vertical-align:middle}.rich_tips .rich_icon{margin-top:-3px 5px 0 0}.rich_tips.with_line{border-top:1px dotted #e1e1e1}.rich_tips.with_line .tips{position:relative;top:-12px;padding-left:16px;padding-right:16px;background-color:#f3f3f3}.rich_tips.with_line{line-height:16px}.rich_tips.with_line .tips{top:-11px;padding-left:.35em;padding-right:.35em}.title_tips .tips{color:#868686;font-size:16px}.loading_tips{margin:36px 0 20px}.title_bottom_tips{margin-top:-10px}.icon_arrow_gray{width:7px}.icon_loading_white{width:16px}.icon_loading_white.icon_before{margin-right:1em}.icon_loading_white.icon_after{margin-left:1em}.btn{display:block;padding-left:14px;padding-right:14px;font-size:18px;text-align:center;text-decoration:none;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;color:#fff;line-height:42px;-webkit-tap-highlight-color:rgba(255,255,255,0)}.btn.btn_inline{display:inline-block}.btn_primary{background-color:#04be02}.btn_primary:not(.btn_disabled):visited{color:#fff}.btn_primary:not(.btn_disabled):active{color:rgba(255,255,255,0.4);background-color:#039702}.btn_disabled{color:rgba(255,255,255,0.6)}.emotion_tool{position:relative;overflow:hidden}.pic_emotion_switch_wrp{margin-left:15px;margin-bottom:6px;display:inline-block;font-size:0}.pic_emotion_switch_wrp img{width:35px;display:block}.pic_emotion_switch_wrp .pic_active{display:none}.pic_emotion_switch_wrp:active .pic_default{display:none}.pic_emotion_switch_wrp:active .pic_active{display:block}.emotion_switch{margin-left:15px;margin-bottom:6px;background:transparent url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/icon_emotion_tool.2x278965.png) no-repeat 0 0;width:35px;height:35px;vertical-align:middle;display:inline-block;-webkit-background-size:35px auto;background-size:35px auto}.emotion_switch:active{background-position:0 -40px}.emotion_panel_arrow_wrp{position:absolute;margin-top:-6px;margin-left:26px}.emotion_panel_arrow_wrp .emotion_panel_arrow{position:absolute;display:inline-block;width:0;height:0;border-width:6px;border-style:dashed;border-color:transparent;border-top-width:0;border-bottom-color:#e5e5e7;border-bottom-style:solid}.emotion_panel_arrow_wrp .arrow_in{border-bottom-color:#f6f6f8;top:1px}.emotion_panel{background-color:#f6f6f8;position:relative}.emotion_panel:before{content:\" \";position:absolute;left:0;top:0;width:100%;height:1px;border-top:1px solid #e3e3e5;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(0.5);transform:scaleY(0.5)}.emotion_panel:after{content:\" \";position:absolute;left:0;bottom:0;width:100%;height:1px;border-bottom:1px solid #e3e3e5;-webkit-transform-origin:0 100%;transform-origin:0 100%;-webkit-transform:scaleY(0.5);transform:scaleY(0.5)}.emotion_list_wrp{overflow:hidden;position:relative;font-size:0;white-space:nowrap}.emotion_list{padding:10px 15px 0;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box;white-space:normal;display:inline-block;vertical-align:top}.emotion_item{display:inline-block;width:36px;height:36px;margin-bottom:5px;text-align:center;line-height:36px}.emotion_navs{text-align:center;padding-bottom:5px}.emotion_nav{display:inline-block;width:8px;height:8px;border-radius:50%;-moz-border-radius:50%;-webkit-border-radius:50%;overflow:hidden;background-color:#bbb;margin:0 5px}.emotion_nav.current{background-color:#8c8c8c}.icon_emotion{width:22px;height:22px;vertical-align:middle;display:inline-block;background:transparent url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/icon_emotion.2x278965.png) no-repeat 0 0;-webkit-background-size:2520px auto;background-size:2520px auto}.icon_emotion.del{background:transparent url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/icon_emotion_tool.2x278965.png) no-repeat 0 0;width:28px;height:28px;vertical-align:middle;display:inline-block;background-position:2px -62px;-webkit-background-size:28px auto;background-size:28px auto}.icon_emotion.del:active{background-position:2px -92px}.icon_emotion_single{width:22px;height:22px;vertical-align:middle;display:inline-block;-webkit-background-size:22px auto;background-size:22px auto}.icon_emotion_single.icon1{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_01278965.png)}.icon_emotion_single.icon2{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_02278965.png)}.icon_emotion_single.icon3{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_03278965.png)}.icon_emotion_single.icon4{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_04278965.png)}.icon_emotion_single.icon5{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_05278965.png)}.icon_emotion_single.icon6{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_06278965.png)}.icon_emotion_single.icon7{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_07278965.png)}.icon_emotion_single.icon8{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_08278965.png)}.icon_emotion_single.icon9{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_09278965.png)}.icon_emotion_single.icon10{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_10278965.png)}.icon_emotion_single.icon11{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_11278965.png)}.icon_emotion_single.icon12{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_12278965.png)}.icon_emotion_single.icon13{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_13278965.png)}.icon_emotion_single.icon14{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_14278965.png)}.icon_emotion_single.icon15{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_15278965.png)}.icon_emotion_single.icon16{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_16278965.png)}.icon_emotion_single.icon17{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_17278965.png)}.icon_emotion_single.icon18{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_18278965.png)}.icon_emotion_single.icon19{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_19278965.png)}.icon_emotion_single.icon20{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_20278965.png)}.icon_emotion_single.icon21{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_21278965.png)}.icon_emotion_single.icon22{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_22278965.png)}.icon_emotion_single.icon23{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_23278965.png)}.icon_emotion_single.icon24{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_24278965.png)}.icon_emotion_single.icon25{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_25278965.png)}.icon_emotion_single.icon26{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_26278965.png)}.icon_emotion_single.icon27{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_27278965.png)}.icon_emotion_single.icon28{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_28278965.png)}.icon_emotion_single.icon29{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_29278965.png)}.icon_emotion_single.icon30{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_30278965.png)}.icon_emotion_single.icon31{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_31278965.png)}.icon_emotion_single.icon32{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_32278965.png)}.icon_emotion_single.icon33{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_33278965.png)}.icon_emotion_single.icon34{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_34278965.png)}.icon_emotion_single.icon35{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_35278965.png)}.icon_emotion_single.icon36{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_36278965.png)}.icon_emotion_single.icon37{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_37278965.png)}.icon_emotion_single.icon38{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_38278965.png)}.icon_emotion_single.icon39{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_39278965.png)}.icon_emotion_single.icon40{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_40278965.png)}.icon_emotion_single.icon41{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_41278965.png)}.icon_emotion_single.icon42{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_42278965.png)}.icon_emotion_single.icon43{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_43278965.png)}.icon_emotion_single.icon44{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_44278965.png)}.icon_emotion_single.icon45{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_45278965.png)}.icon_emotion_single.icon46{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_46278965.png)}.icon_emotion_single.icon47{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_47278965.png)}.icon_emotion_single.icon48{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_48278965.png)}.icon_emotion_single.icon49{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_49278965.png)}.icon_emotion_single.icon50{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_50278965.png)}.icon_emotion_single.icon51{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_51278965.png)}.icon_emotion_single.icon52{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_52278965.png)}.icon_emotion_single.icon53{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_53278965.png)}.icon_emotion_single.icon54{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_54278965.png)}.icon_emotion_single.icon55{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_55278965.png)}.icon_emotion_single.icon56{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_56278965.png)}.icon_emotion_single.icon57{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_57278965.png)}.icon_emotion_single.icon58{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_58278965.png)}.icon_emotion_single.icon59{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_59278965.png)}.icon_emotion_single.icon60{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_60278965.png)}.icon_emotion_single.icon61{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_61278965.png)}.icon_emotion_single.icon62{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_62278965.png)}.icon_emotion_single.icon63{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_63278965.png)}.icon_emotion_single.icon64{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_64278965.png)}.icon_emotion_single.icon65{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_65278965.png)}.icon_emotion_single.icon66{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_66278965.png)}.icon_emotion_single.icon67{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_67278965.png)}.icon_emotion_single.icon68{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_68278965.png)}.icon_emotion_single.icon69{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_69278965.png)}.icon_emotion_single.icon70{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_70278965.png)}.icon_emotion_single.icon71{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_71278965.png)}.icon_emotion_single.icon72{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_72278965.png)}.icon_emotion_single.icon73{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_73278965.png)}.icon_emotion_single.icon74{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_74278965.png)}.icon_emotion_single.icon75{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_75278965.png)}.icon_emotion_single.icon76{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_76278965.png)}.icon_emotion_single.icon77{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_77278965.png)}.icon_emotion_single.icon78{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_78278965.png)}.icon_emotion_single.icon79{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_79278965.png)}.icon_emotion_single.icon80{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_80278965.png)}.icon_emotion_single.icon81{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_81278965.png)}.icon_emotion_single.icon82{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_82278965.png)}.icon_emotion_single.icon83{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_83278965.png)}.icon_emotion_single.icon84{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_84278965.png)}.icon_emotion_single.icon85{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_85278965.png)}.icon_emotion_single.icon86{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_86278965.png)}.icon_emotion_single.icon87{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_87278965.png)}.icon_emotion_single.icon88{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_88278965.png)}.icon_emotion_single.icon89{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_89278965.png)}.icon_emotion_single.icon90{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_90278965.png)}.icon_emotion_single.icon91{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_91278965.png)}.icon_emotion_single.icon92{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_92278965.png)}.icon_emotion_single.icon93{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_93278965.png)}.icon_emotion_single.icon94{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_94278965.png)}.icon_emotion_single.icon95{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_95278965.png)}.icon_emotion_single.icon96{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_96278965.png)}.icon_emotion_single.icon97{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_97278965.png)}.icon_emotion_single.icon98{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_98278965.png)}.icon_emotion_single.icon99{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_99278965.png)}.icon_emotion_single.icon100{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_100278965.png)}.icon_emotion_single.icon101{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_101278965.png)}.icon_emotion_single.icon102{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_102278965.png)}.icon_emotion_single.icon103{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_103278965.png)}.icon_emotion_single.icon104{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_104278965.png)}.icon_emotion_single.icon105{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/emotion/default-skin/Expression@2x_105278965.png)}.wx_poptips{position:fixed;z-index:3;width:120px;min-height:120px;top:180px;left:50%;margin-left:-60px;background:rgba(40,40,40,0.5)!important;filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#80282828',endcolorstr = '#80282828');text-align:center;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;color:#fff}.wx_poptips .icon_toast{width:53px;margin:15px 0 0}.wx_poptips .toast_content{margin:0 0 15px}.discuss_container .rich_media_title{font-size:18px}.discuss_container .discuss_message{word-wrap:break-word;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}.discuss_container.disabled .btn_discuss{color:#60f05f}.discuss_container.access .discuss_container_inner{padding:15px 15px 0}.discuss_container.editing .discuss_container_inner{padding-bottom:25px}.discuss_container.editing .frm_textarea_box_wrp{margin:0 -15px}.discuss_container.editing .frm_textarea{height:78px;-webkit-overflow-scrolling:touch}.discuss_container.editing .frm_append.counter{display:block}.discuss_container.editing .discuss_btn_wrp{display:block}.discuss_container.editing .discuss_icon_tips{margin-top:0;margin-bottom:-14px}.discuss_container.editing .discuss_title_line{margin-bottom:-20px}.discuss_container.warning .counter{color:#e15f63}.frm_textarea{width:100%;background-color:transparent;border:0;display:block;font-size:14px;-webkit-box-sizing:border-box;box-sizing:border-box;height:37px;padding:10px 15px;resize:none;outline:0;-webkit-tap-highlight-color:rgba(0,0,0,0)}.frm_textarea_box_wrp{position:relative}.frm_textarea_box_wrp:before{content:\" \";position:absolute;left:0;top:0;width:100%;height:1px;border-top:1px solid #e7e6e4;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(0.5);transform:scaleY(0.5);top:-1px}.frm_textarea_box_wrp:after{content:\" \";position:absolute;left:0;top:0;width:100%;height:1px;border-top:1px solid #e7e6e4;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(0.5);transform:scaleY(0.5);top:auto;bottom:-2px}.frm_textarea_box{display:block;background-color:#fff}.frm_append.counter{display:none;position:absolute;right:8px;bottom:8px;color:#a3a3a3;font-weight:400;font-style:normal;font-size:12px}.frm_append .current_num.warn{color:#f43631}.discuss_btn_wrp{display:none;margin-top:20px;margin-bottom:20px;text-align:right}.btn_discuss{padding-left:1.5em;padding-right:1.5em}.discuss_list{margin-top:-5px;padding-bottom:20px;font-size:16px}.discuss_item{position:relative;padding-left:45px;margin-top:26px;*zoom:1}.discuss_item:after{content:\"\\200B\";display:block;height:0;clear:both}.discuss_item .user_info{min-height:20px;overflow:hidden}.discuss_item .nickname{display:block;font-weight:400;font-style:normal;color:#727272;width:9em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal}.discuss_item .avatar{position:absolute;top:0;left:0;top:3px;width:35px;height:35px;background-color:#ccc;vertical-align:top;margin-top:0;border-radius:2px;-moz-border-radius:2px;-webkit-border-radius:2px}.discuss_item .discuss_message{color:#3e3e3e;line-height:1.5}.discuss_item .discuss_extra_info{color:#8c8c8c;font-size:12px}.discuss_item .discuss_extra_info a{margin-left:.5em}.discuss_item .discuss_status{color:#ff7a21;white-space:nowrap}.discuss_item .discuss_status i{font-style:normal;margin-right:2px}.discuss_item .discuss_opr{float:right}.discuss_item .discuss_opr .meta_praise{display:inline-block;text-align:right;padding-top:5px;margin-top:-5px}.discuss_item .discuss_del{margin-left:.5em}.discuss_icon_tips{margin-bottom:20px}.discuss_icon_tips img{vertical-align:middle;margin-left:3px;margin-top:-4px}.discuss_icon_tips .icon_edit{width:12px}.discuss_icon_tips .icon_access{width:13px}.reply_result{position:relative;margin-top:.5em;padding-top:.5em;padding-left:.4em}.reply_result:before{content:\" \";position:absolute;left:0;top:0;width:100%;height:1px;border-top:1px solid #dadada;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(0.5);transform:scaleY(0.5)}.reply_result .nickname{position:relative;overflow:visible}.reply_result .nickname:before{content:\" \";position:absolute;left:-0.4em;top:50%;margin-top:-7px;width:3px;height:14px;background-color:#02bb00}.rich_tips.discuss_title_line{margin-top:50px}.reward_area{padding:38px 5% 20px;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0 auto}.reward_area_inner{margin:0 auto;position:relative;left:3px}.reward_access{display:inline-block;padding:0 1.6em;line-height:2;border-radius:5px;-moz-border-radius:5px;-webkit-border-radius:5px;background-color:#dc5d4a;color:#fff;font-size:16px;-webkit-tap-highlight-color:rgba(0,0,0,0)}.reward_access:active{background-color:#be5041;color:#e69990}.reward_tips{margin-bottom:5px}.reward_user_tips{margin-top:1.4em}.reward_user_list{padding-top:.5em;overflow:hidden}.reward_user_avatar{display:inline-block;vertical-align:top;width:28px;height:28px;margin:0 6px 6px 0}.reward_user_avatar img{width:100%;height:100%!important}.reward_user_avatar.readmore{-webkit-tap-highlight-color:rgba(0,0,0,0)}.rich_media_extra{position:relative}.rich_media_extra .extra_link{display:block}.rich_media_extra img{vertical-align:middle;margin-top:-3px}.rich_media_extra .appmsg_banner{width:100%}.rich_media_extra .ad_msg_mask{position:absolute;left:0;top:0;width:100%;height:100%;text-align:center;line-height:200px;background-color:#000;filter:alpha(opacity = 20);-moz-opacity:.2;-khtml-opacity:.2;opacity:.2}.mpda_bottom_container .rich_media_extra{padding-bottom:15px}.btn_default.btn_line,.btn_primary.btn_line{background-color:#fff;color:#04be02;border:1px solid #04be02;font-size:15px}.rich_media_extra .extra_link{position:relative}.promotion_tag{position:absolute;display:block;height:21px;line-height:21px;width:79px;background:transparent url(/mmbizwap/zh_CN/htmledition/images/ad/promotion_tag_bg24a2fe.png) no-repeat 0 0;-webkit-background-size:79px 21px;background-size:79px 21px;font-size:14px;font-style:normal;color:#fff;padding-left:7px;left:0;bottom:0}.brand_logo{position:absolute;display:block;width:24%;right:1.54%;top:0}.brand_logo img{width:100%;vertical-align:top;max-height:35px}.top_banner{background-color:#fff}.top_banner .rich_media_extra{padding:15px 15px 20px 15px}.top_banner .rich_media_extra .extra_link{position:relative;padding-bottom:10px}.top_banner .rich_media_extra .extra_link:before{content:\" \";position:absolute;left:0;top:0;width:100%;height:1px;border-top:1px solid #d6d6d6;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleY(0.5);transform:scaleY(0.5);top:auto;bottom:-2px}.top_banner .rich_media_extra .extra_link:active,.top_banner .rich_media_extra .extra_link:focus{outline:0;border:0}.top_banner .rich_media_extra .appmsg_banner{width:100%;vertical-align:top;outline:0}.top_banner .rich_media_extra .appmsg_banner:active,.top_banner .rich_media_extra .appmsg_banner:focus{outline:0;border:0}.top_banner .rich_media_extra .promotion_tag{height:19px;line-height:19px;width:69px;background:transparent url(/mmbizwap/zh_CN/htmledition/images/ad/promotion_tag_bg_small24a2fe.png) no-repeat 0 0;font-size:12px;-webkit-background-size:69px 19px;background-size:69px 19px;bottom:10px;padding-left:6px}.top_banner .rich_media_extra .brand_logo{width:20%;right:2.22%}.top_banner .rich_media_extra .brand_logo img{max-height:35px}.top_banner .rich_media_extra .ad_msg_mask{position:absolute;left:0;top:0;width:100%;height:100%;text-align:center;line-height:200px;background-color:#000;filter:alpha(opacity = 20);-moz-opacity:.2;-khtml-opacity:.2;opacity:.2}.top_banner .rich_media_extra .ad_msg_mask img{position:absolute;width:16px;top:50%;margin-top:-8px;left:50%;margin-left:-8px}.top_banner .preview_group.obvious_app{min-height:54px;position:relative}.top_banner .preview_group.obvious_app .pic_app{width:66.6%}.top_banner .preview_group.obvious_app .pic_app img{height:100%;min-height:54px}.top_banner .preview_group.obvious_app .info_app{width:33%;left:68%}.top_banner .preview_group.obvious_app .info_app .name_app{line-height:18px;font-size:13px}.top_banner .preview_group.obvious_app .info_app .profile_app{font-size:10px}.top_banner .preview_group.obvious_app .info_app .dm_app{bottom:5px}.top_banner .preview_group.obvious_app .info_app .dm_app .ad_btn{font-size:12px;padding-left:17px;line-height:16px}.top_banner .preview_group.obvious_app .info_app .dm_app .ad_btn.btn_download,.top_banner .preview_group.obvious_app .info_app .dm_app .ad_btn.btn_install,.top_banner .preview_group.obvious_app .info_app .dm_app .ad_btn.btn_installed,.top_banner .preview_group.obvious_app .info_app .dm_app .ad_btn.btn_open{-webkit-background-size:14px 14px;background-size:14px 14px;background-position:0 center;-webkit-background-position:0 center}.top_banner .preview_group.obvious_app .info_app .dm_app .extra_info{display:none}.wrp_preview_group{padding-top:100px}.preview_group{position:relative;min-height:83px;background-color:#fff;border:1px solid #e7e7eb;-webkit-text-size-adjust:none;text-size-adjust:none}.preview_group.fixed_pos{position:fixed;bottom:0;left:0;right:0}.preview_group .preview_group_inner{padding:14px}.preview_group .preview_group_inner .preview_group_info{padding-left:68px;color:#8d8d8d;font-size:14px}.preview_group .preview_group_inner .preview_group_info .preview_group_title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal;color:#000;font-weight:400;font-style:normal;padding-right:73px;max-width:142px;display:block}.preview_group .preview_group_inner .preview_group_info .preview_group_desc{padding-right:65px;display:inline-block;line-height:20px}.preview_group .preview_group_inner .preview_group_info .preview_group_avatar{position:absolute;width:55px;height:55px;left:13px;top:50%;margin-top:-27px;z-index:1}.preview_group .preview_group_inner .preview_group_info .preview_group_avatar.br_radius{border-radius:100%;-moz-border-radius:100%;-webkit-border-radius:100%}.preview_group .preview_group_inner .preview_group_opr{position:absolute;line-height:83px;top:0;right:13px}.preview_group .preview_group_inner .preview_group_opr .btn{padding:0;min-width:60px;min-height:30px;height:auto;line-height:30px;text-align:center}.preview_group.preview_card .card_inner .preview_card_avatar{position:absolute;width:57px;height:57px;left:13px;top:50%;margin-top:-28px}.preview_group.preview_card .card_inner .preview_group_info{padding-left:70px}.preview_group.preview_card .card_inner .preview_group_info .preview_group_title2{width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal;padding-right:0;display:block}.preview_group.preview_card .card_inner .preview_group_info .preview_group_desc{padding-right:0}.preview_group.preview_card .card_inner .preview_group_info.append_btn .preview_group_desc,.preview_group.preview_card .card_inner .preview_group_info.append_btn .preview_group_title{padding-right:68px;width:auto}.preview_group.obvious_app{width:100%}.preview_group.obvious_app .preview_group_inner{padding:0}.preview_group.obvious_app .pic_app{width:58.3%;height:100%;display:inline-block;margin-right:2%;vertical-align:top}.preview_group.obvious_app .pic_app img{width:100%;vertical-align:top;margin-top:0}.preview_group.obvious_app .info_app{display:inline-block;width:38%;color:#8a8a8a;font-size:12px;box-sizing:border-box;-webkit-box-sizing:border-box;position:absolute;left:62%;top:0;height:100%}.preview_group.obvious_app .info_app .name_app{color:#000;font-size:15px;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal;margin-top:3px}.preview_group.obvious_app .info_app .profile_app{line-height:10px;width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal}.preview_group.obvious_app .info_app .profile_app span{padding:0 5px}.preview_group.obvious_app .info_app .profile_app span:first-child{padding-left:0}.preview_group.obvious_app .info_app .profile_app em{font-size:9px;line-height:16px;font-weight:400;font-style:normal;color:#dfdfdf}.preview_group.obvious_app .info_app .dm_app{line-height:20px;vertical-align:middle;position:absolute;left:0;bottom:5px}.preview_group.obvious_app .info_app .dm_app .ad_btn{display:block;color:#04be02;font-size:15px;padding-left:22px}.preview_group.obvious_app .info_app .dm_app .ad_btn.btn_download{background:transparent url(http://res.wx.qq.com/mmbizwap/zh_CN/htmledition/images/ad/icon58_download@3x.png) no-repeat 0 0;-webkit-background-size:19px 19px;background-size:16px 16px;-webkit-background-position:0 center;background-position:0 center}.preview_group.obvious_app .info_app .dm_app .ad_btn.btn_install{background:transparent url(http://res.wx.qq.com/mmbizwap/zh_CN/htmledition/images/ad/icon58_install@3x.png) no-repeat 0 0;-webkit-background-size:19px 19px;background-size:16px 16px;-webkit-background-position:0 center;background-position:0 center}.preview_group.obvious_app .info_app .dm_app .ad_btn.btn_installed{background:transparent url(http://res.wx.qq.com/mmbizwap/zh_CN/htmledition/images/ad/icon58_installed@3x.png) no-repeat 0 0;-webkit-background-size:19px 19px;background-size:16px 16px;color:#8a8a8a;-webkit-background-position:0 center;background-position:0 center}.preview_group.obvious_app .info_app .dm_app .ad_btn.btn_open{background:transparent url(http://res.wx.qq.com/mmbizwap/zh_CN/htmledition/images/ad/icon58_open@3x.png) no-repeat 0 0;-webkit-background-size:19px 19px;background-size:16px 16px;-webkit-background-position:0 center;background-position:0 center}.preview_group.obvious_app .info_app .dm_app p{line-height:15px}.preview_group.obvious_app .info_app .dm_app .extra_info{font-size:9px}.preview_group.obvious_app .info_app .grade_app{height:11px;line-height:11px;font-size:12px;color:#888}.preview_group.obvious_app .info_app .grade_app .stars{display:inline-block;width:55px;height:11px;background:transparent url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/star_sprite25624b.png) no-repeat 0 0;-webkit-background-size:55px 110px;background-size:55px 110px}.preview_group.obvious_app .info_app .grade_app .stars.star_half{backgroud-position:0}.preview_group.obvious_app .info_app .grade_app .stars.star_one{background-position:0 -11px}.preview_group.obvious_app .info_app .grade_app .stars.star_one_half{background-position:0 -22px}.preview_group.obvious_app .info_app .grade_app .stars.star_two{background-position:0 -33px}.preview_group.obvious_app .info_app .grade_app .stars.star_two_half{background-position:0 -44px}.preview_group.obvious_app .info_app .grade_app .stars.star_three{background-position:0 -55px}.preview_group.obvious_app .info_app .grade_app .stars.star_three_half{background-position:0 -66px}.preview_group.obvious_app .info_app .grade_app .stars.star_four{background-position:0 -77px}.preview_group.obvious_app .info_app .grade_app .stars.star_four_half{background-position:0 -88px}.preview_group.obvious_app .info_app .grade_app .stars.star_five{background-position:0 -99px}.db{display:block}.qqmusic_area{display:inline-block;width:100%;vertical-align:top;margin:17px 1px 16px 0;font-weight:400;text-decoration:none;font-size:0;line-height:0;text-align:left;-ms-text-size-adjust:none;-webkit-text-size-adjust:none;text-size-adjust:none}.qqmusic_area .unsupport_tips{display:none;padding:20px 20px 8px;line-height:1.6;font-size:16px}.qqmusic_area .pic_qqmusic_default{position:absolute;top:50%;left:50%;margin-top:-18.5px;margin-left:-18.5px;width:37px;height:37px;display:none}.qqmusic_area.unsupport .unsupport_tips{display:block}.qqmusic_area.unsupport .pic_qqmusic_default{display:inline-block}.qqmusic_area.unsupport .icon_qqmusic_switch{display:none}.qqmusic_wrp{border:1px solid #ebebeb;line-height:1.6}.qqmusic_bd{position:relative;background-color:#fcfcfc;overflow:hidden}.qqmusic_ft{text-align:right;background-color:#f5f5f5;border-top:1px solid #ebebeb;line-height:2.5;overflow:hidden;font-size:11px;padding:0 .5em}.play_area{float:left;width:60px;height:60px;margin-right:12px;position:relative}.qqmusic_thumb{display:block;width:60px;height:60px!important}.access_area{display:block;color:#8c8c8c;min-height:60px;overflow:hidden;margin-right:10px;-webkit-tap-highlight-color:rgba(0,0,0,0);outline:0}.qqmusic_songname,.qqmusic_singername{display:block;width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal}.qqmusic_songname{padding:7px 0 3px;margin-bottom:-4px;font-size:16px;color:#3e3e3e}.qqmusic_singername{font-size:14px;margin-right:20px}.qqmusic_source{position:absolute;right:6px;bottom:6px}.qqmusic_source img{width:13px;height:13px;vertical-align:top;border:0}.qqmusic_love{position:relative;float:right;margin:10px 0 0 10px;height:54px;color:#607fa6;width:53px;text-align:center;font-size:13px;background:transparent url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/qqmusic/icon_qqmusic_play_sprite.2x26f1f1.png) no-repeat 0 0}.qqmusic_love:before{content:\" \";position:absolute;left:0;top:0;width:1px;height:100%;border-left:1px solid #e7e6e4;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleX(0.5);transform:scaleX(0.5)}.qqmusic_love .icon_love{margin-top:16px}.qqmusic_love .love_num{display:block}.icon_qqmusic_switch{position:absolute;top:50%;left:50%;margin-top:-18.5px;margin-left:-18.5px;line-height:200px;overflow:hidden;cursor:pointer;width:37px;height:37px;-webkit-tap-highlight-color:rgba(0,0,0,0);outline:0;background:transparent url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/qqmusic/icon_qqmusic_play_sprite.2x26f1f1.png) no-repeat 0 0;-webkit-background-size:37px auto;background-size:37px auto}.qqmusic_playing .icon_qqmusic_switch{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/qqmusic/icon_qqmusic_play_sprite.2x26f1f1.png);background-position:0 -42px}.icon_love{width:12px;height:12px;vertical-align:middle;display:inline-block;margin-top:-0.2em;background:transparent url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/qqmusic/icon_love_mini_sprite.2x25ded2.png) no-repeat 0 0;-webkit-background-size:12px auto;background-size:12px auto}.loved .icon_love{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/qqmusic/icon_love_mini_sprite.2x25ded2.png);background-position:0 -17px}.audio_area{display:inline-block;width:100%;vertical-align:top;margin:17px 1px 16px 0;font-size:0;position:relative;font-weight:400;text-decoration:none;-ms-text-size-adjust:none;-webkit-text-size-adjust:none;text-size-adjust:none}.audio_area .audio_title{font-weight:400;font-size:17px;margin-top:-2px;margin-bottom:-3px;width:auto;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;word-wrap:normal}.audio_area .audio_length{float:right;font-size:14px;margin-top:3px;margin-left:1em}.audio_area .audio_source{font-size:14px}.audio_area .progress_bar{position:absolute;left:0;bottom:0;background-color:#0cbb08;height:2px}.audio_area .unsupport_tips{display:none;padding:20px 20px 8px;line-height:1.6;font-size:16px}.audio_area .pic_audio_default{display:none;width:18px}.audio_area.unsupport .unsupport_tips{display:block}.audio_area.unsupport .pic_audio_default{display:inline-block}.audio_area.unsupport .icon_audio_playing{display:none}.audio_area.unsupport .icon_audio_default{display:none}.audio_wrp{border:1px solid #ebebeb;background-color:#fcfcfc;overflow:hidden;*zoom:1;padding:12px 20px 12px 12px}.audio_info_area{overflow:hidden;*zoom:1}.audio_play_area{float:left;margin:9px 22px 10px 5px;font-size:0;width:18px;height:25px}.playing .audio_play_area .icon_audio_playing{display:inline-block}.playing .audio_play_area .icon_audio_default{display:none}.audio_play_area .icon_audio_default{background:transparent url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/audio/icon_audio_unread26f1f1.png) no-repeat 0 0;width:18px;height:25px;vertical-align:middle;display:inline-block;-webkit-background-size:18px auto;background-size:18px auto}.audio_play_area .icon_audio_playing{background:transparent url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/audio/icon_audio_reading_126f1f1.png) no-repeat 0 0;width:18px;height:25px;vertical-align:middle;display:inline-block;-webkit-background-size:18px auto;background-size:18px auto;-webkit-animation:audio_playing 1s infinite;display:none}@-webkit-keyframes audio_playing{30%{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/audio/icon_audio_reading_126f1f1.png)}31%{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/audio/icon_audio_reading_226f1f1.png)}61%{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/audio/icon_audio_reading_226f1f1.png)}62%{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/audio/icon_audio_reading_326f1f1.png)}100%{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/audio/icon_audio_reading_326f1f1.png)}}.iframe_full_video{position:fixed!important;left:0;right:0;top:0;bottom:0;z-index:1000;background-color:#000;margin-top:0!important}.video_iframe{display:block}.video_ad_iframe{border:0;position:absolute;left:0;top:0;z-index:100;width:100%;height:100%;background-color:#fff}@media(min-device-width:375px) and (max-device-width:667px) and (-webkit-min-device-pixel-ratio:2){.mm_appmsg .rich_media_inner,.mm_appmsg .rich_media_meta,.mm_appmsg .discuss_list,.mm_appmsg .rich_media_extra,.mm_appmsg .title_tips .tips{font-size:17px}}@media(min-device-width:414px) and (max-device-width:736px) and (-webkit-min-device-pixel-ratio:3){.mm_appmsg .rich_media_title{font-size:25px}}@media screen and (max-width:1023px){.qr_code_pc_outer{display:none!important}}@media screen and (min-width:1024px){.rich_media{width:740px;margin-left:auto;margin-right:auto}.rich_media_inner{padding:20px}.rich_media_meta{max-width:none}a.rich_media_meta_nickname{display:inline-block!important}span.rich_media_meta_nickname{display:none!important}.rich_media_content{min-height:350px}.rich_media_title{padding-bottom:10px;margin-bottom:14px;border-bottom:1px solid #e7e7eb}body{background-color:#fff}.discuss_container.access{width:740px;margin-left:auto;margin-right:auto;background-color:#fff}.discuss_container.editing .frm_textarea_box{margin:0}.frm_textarea_box{position:relative}.frm_textarea_box:before{content:\" \";position:absolute;left:0;top:0;width:1px;height:100%;border-left:1px solid #e7e6e4;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleX(0.5);transform:scaleX(0.5)}.frm_textarea_box:after{content:\" \";position:absolute;left:0;top:0;width:1px;height:100%;border-left:1px solid #e7e6e4;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleX(0.5);transform:scaleX(0.5);left:auto;right:-2px}.rich_media_meta.nickname{max-width:none}.rich_tips.with_line .tips{background-color:#fff}}@media screen and (min-width:1025px){body{font-family:\"Helvetica Neue\",Helvetica,\"Hiragino Sans GB\",\"Microsoft YaHei\",Arial,sans-serif}.rich_media{position:relative}.rich_media_inner{background-color:#fff;padding-bottom:100px}.rich_media_inner{position:relative}.qr_code_pc_outer{display:block!important;position:fixed;left:0;right:0;top:20px;color:#717375;text-align:center}.qr_code_pc_inner{position:relative;width:740px;margin-left:auto;margin-right:auto}.qr_code_pc{position:absolute;right:-145px;top:0;padding:16px;border:1px solid #d9dadc;background-color:#fff}.qr_code_pc p{font-size:14px;line-height:20px}.qr_code_pc_img{width:102px;height:102px}}"
  },
  {
    "path": "public/static/article/page_mp_article_improve_pc2637ae.css",
    "content": ".rich_media{width:740px;margin-left:auto;margin-right:auto}.rich_media_inner{padding:20px;background-color:#fff}.rich_media_meta{max-width:none}a.rich_media_meta_nickname{display:inline-block!important}span.rich_media_meta_nickname{display:none!important}.rich_media_content{position:relative;min-height:350px}.rich_media_title{padding-bottom:10px;margin-bottom:5px;border-bottom:1px solid #e7e7eb}.discuss_container{width:740px;margin-left:auto;margin-right:auto}.discuss_container.editing .frm_textarea_box{margin:0}.frm_textarea_box{position:relative}.frm_textarea_box:before{content:\" \";position:absolute;left:0;top:0;width:1px;height:100%;border-left:1px solid #e7e6e4;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleX(0.5);transform:scaleX(0.5)}.frm_textarea_box:after{content:\" \";position:absolute;left:0;top:0;width:1px;height:100%;border-left:1px solid #e7e6e4;-webkit-transform-origin:0 0;transform-origin:0 0;-webkit-transform:scaleX(0.5);transform:scaleX(0.5);left:auto;right:-2px}.rich_media_meta.nickname{max-width:none}.rich_tips.with_line .tips{background-color:#fff}body{background-color:#fff;font-family:\"Hiragino Sans GB\",\"Microsoft YaHei\",Arial,sans-serif}.rich_media{position:relative}.rich_media_inner{padding-bottom:100px}.meta_original_tag{background:transparent url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/icon_original_tag25ab3f.png) no-repeat 0 0;width:49px;height:20px;vertical-align:middle;display:inline-block}.rich_media_inner{position:relative}.qr_code_pc_outer{display:block!important;position:fixed;left:0;right:0;top:20px;color:#717375;text-align:center}.qr_code_pc_inner{position:relative;width:740px;margin-left:auto;margin-right:auto}.qr_code_pc{position:absolute;right:-145px;top:0;padding:16px;border:1px solid #d9dadc;background-color:#fff}.qr_code_pc p{font-size:14px;line-height:20px}.qr_code_pc_img{width:102px;height:102px}.qqmusic_wrp .icon_qqmusic_switch{background:transparent url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/qqmusic/icon_qqmusic_play_sprite264e76.png) no-repeat 0 0}.qqmusic_playing .qqmusic_wrp .icon_qqmusic_switch{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/qqmusic/icon_qqmusic_play_sprite264e76.png);background-position:0 -46px}.qqmusic_wrp .icon_love{width:12px;height:12px;vertical-align:middle;display:inline-block;margin-top:-0.2em;background:transparent url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/qqmusic/icon_love_mini_sprite25ded2.png) no-repeat 0 0}.loved .qqmusic_wrp .icon_love{background-image:url(/mmbizwap/zh_CN/htmledition/images/icon/appmsg/qqmusic/icon_love_mini_sprite25ded2.png);background-position:0 -22px}"
  },
  {
    "path": "public/static/dist/css/AdminLTE.css",
    "content": "/*!\n *   AdminLTE v2.3.1\n *   Author: Almsaeed Studio\n *\t Website: Almsaeed Studio <http://almsaeedstudio.com>\n *   License: Open source - MIT\n *           Please visit http://opensource.org/licenses/MIT for more information\n!*/\nhtml, body {\n    min-height: 100%\n}\n\n.layout-boxed html, .layout-boxed body {\n    height: 100%\n}\n\nbody {\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n    font-family: 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif;\n    font-weight: 400;\n    overflow-x: hidden;\n    overflow-y: auto\n}\n\n.wrapper {\n    min-height: 100%;\n    position: relative;\n    overflow: hidden\n}\n\n.wrapper:before, .wrapper:after {\n    content: \" \";\n    display: table\n}\n\n.wrapper:after {\n    clear: both\n}\n\n.layout-boxed .wrapper {\n    max-width: 1250px;\n    margin: 0 auto;\n    min-height: 100%;\n    box-shadow: 0 0 8px rgba(0, 0, 0, 0.5);\n    position: relative\n}\n\n.layout-boxed {\n    background: url('../img/boxed-bg.jpg') repeat fixed\n}\n\n.content-wrapper, .right-side, .main-footer {\n    -webkit-transition: -webkit-transform .3s ease-in-out, margin .3s ease-in-out;\n    -moz-transition: -moz-transform .3s ease-in-out, margin .3s ease-in-out;\n    -o-transition: -o-transform .3s ease-in-out, margin .3s ease-in-out;\n    transition: transform .3s ease-in-out, margin .3s ease-in-out;\n    /*margin-left: 230px;*/\n    margin-left: 200px;\n    z-index: 820\n}\n\n.layout-top-nav .content-wrapper, .layout-top-nav .right-side, .layout-top-nav .main-footer {\n    margin-left: 0\n}\n\n@media (max-width: 767px) {\n    .content-wrapper, .right-side, .main-footer {\n        margin-left: 0\n    }\n}\n\n@media (min-width: 768px) {\n    .sidebar-collapse .content-wrapper, .sidebar-collapse .right-side, .sidebar-collapse .main-footer {\n        margin-left: 0\n    }\n}\n\n@media (max-width: 767px) {\n    .sidebar-open .content-wrapper, .sidebar-open .right-side, .sidebar-open .main-footer {\n        -webkit-transform: translate(230px, 0);\n        -ms-transform: translate(230px, 0);\n        -o-transform: translate(230px, 0);\n        transform: translate(230px, 0)\n    }\n}\n\n.content-wrapper, .right-side {\n    min-height: 100%;\n    background-color: #ecf0f5;\n    z-index: 800\n}\n\n.main-footer {\n    background: #fff;\n    padding: 15px;\n    color: #444;\n    border-top: 1px solid #d2d6de\n}\n\n.fixed .main-header, .fixed .main-sidebar, .fixed .left-side {\n    position: fixed\n}\n\n.fixed .main-header {\n    top: 0;\n    right: 0;\n    left: 0\n}\n\n.fixed .content-wrapper, .fixed .right-side {\n    padding-top: 50px\n}\n\n@media (max-width: 767px) {\n    .fixed .content-wrapper, .fixed .right-side {\n        padding-top: 100px\n    }\n}\n\n.fixed.layout-boxed .wrapper {\n    max-width: 100%\n}\n\nbody.hold-transition .content-wrapper, body.hold-transition .right-side, body.hold-transition .main-footer, body.hold-transition .main-sidebar, body.hold-transition .left-side, body.hold-transition .main-header > .navbar, body.hold-transition .main-header .logo {\n    -webkit-transition: none;\n    -o-transition: none;\n    transition: none\n}\n\n.content {\n    min-height: 720px;\n    padding: 15px;\n    margin-right: auto;\n    margin-left: auto;\n    padding-left: 15px;\n    padding-right: 15px\n}\n\nh1, h2, h3, h4, h5, h6, .h1, .h2, .h3, .h4, .h5, .h6 {\n    font-family: 'Source Sans Pro', sans-serif\n}\n\na {\n    color: #3c8dbc\n}\n\na:hover, a:active, a:focus {\n    outline: none;\n    text-decoration: none;\n    color: #72afd2\n}\n\n.page-header {\n    margin: 10px 0 20px 0;\n    font-size: 22px\n}\n\n.page-header > small {\n    color: #666;\n    display: block;\n    margin-top: 5px\n}\n\n.main-header {\n    /*position: fixed;*/\n    /*max-height: 100px;*/\n    /*z-index: 1030;*/\n    /*width: 100%;*/\n    /*box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);*/\n}\n\n.main-header > .navbar {\n    -webkit-transition: margin-left .3s ease-in-out;\n    -o-transition: margin-left .3s ease-in-out;\n    transition: margin-left .3s ease-in-out;\n    margin-bottom: 0;\n    margin-left: 210px;\n    border: none;\n    min-height: 50px;\n    border-radius: 0\n}\n\n.layout-top-nav .main-header > .navbar {\n    margin-left: 0\n}\n\n.main-header #navbar-search-input.form-control {\n    background: rgba(255, 255, 255, 0.2);\n    border-color: transparent\n}\n\n.main-header #navbar-search-input.form-control:focus, .main-header #navbar-search-input.form-control:active {\n    border-color: rgba(0, 0, 0, 0.1);\n    background: rgba(255, 255, 255, 0.9)\n}\n\n.main-header #navbar-search-input.form-control::-moz-placeholder {\n    color: #ccc;\n    opacity: 1\n}\n\n.main-header #navbar-search-input.form-control:-ms-input-placeholder {\n    color: #ccc\n}\n\n.main-header #navbar-search-input.form-control::-webkit-input-placeholder {\n    color: #ccc\n}\n\n.main-header .navbar-custom-menu, .main-header .navbar-right {\n    float: right\n}\n\n@media (max-width: 991px) {\n    .main-header .navbar-custom-menu a, .main-header .navbar-right a {\n        color: inherit;\n        background: transparent\n    }\n}\n\n@media (max-width: 767px) {\n    .main-header .navbar-right {\n        float: none\n    }\n\n    .navbar-collapse .main-header .navbar-right {\n        margin: 7.5px -15px\n    }\n\n    .main-header .navbar-right > li {\n        color: inherit;\n        border: 0\n    }\n}\n\n.main-header .sidebar-toggle {\n    float: left;\n    background-color: transparent;\n    background-image: none;\n    padding: 15px 15px;\n    font-family: fontAwesome\n}\n\n/*.main-header .sidebar-toggle:before {*/\n    /*content: \"\\f0c9\"*/\n/*}*/\n\n.main-header .sidebar-toggle:hover {\n    color: #fff\n}\n\n.main-header .sidebar-toggle:focus, .main-header .sidebar-toggle:active {\n    background: transparent\n}\n\n.main-header .sidebar-toggle .icon-bar {\n    display: none\n}\n\n.main-header .navbar .nav > li.user > a > .fa, .main-header .navbar .nav > li.user > a > .glyphicon, .main-header .navbar .nav > li.user > a > .ion {\n    margin-right: 5px\n}\n\n.main-header .navbar .nav > li > a > .label {\n    position: absolute;\n    top: 9px;\n    right: 7px;\n    text-align: center;\n    font-size: 9px;\n    padding: 2px 3px;\n    line-height: .9\n}\n\n.main-header .logo {\n    -webkit-transition: width .3s ease-in-out;\n    -o-transition: width .3s ease-in-out;\n    transition: width .3s ease-in-out;\n    display: block;\n    float: left;\n    height: 50px;\n    font-size: 20px;\n    line-height: 50px;\n    text-align: center;\n    width: 230px;\n    font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n    padding: 0 15px;\n    font-weight: 300;\n    overflow: hidden\n}\n\n.main-sidebar .team-logo {\n    margin: 15px auto 0;\n    width: 32px;\n    height: 32px;\n    border-radius: 16px;\n    background-size: cover;\n    background-position: 50% 50%;\n    background-color: #fff;\n}\n\n.main-header .logo .logo-lg {\n    display: block\n}\n\n.main-header .logo .logo-mini {\n    display: none\n}\n\n.main-header .navbar-brand {\n    color: #fff\n}\n\n.content-header {\n    position: relative;\n    padding: 15px 15px 0 15px\n}\n\n.content-header > h1 {\n    margin: 0;\n    font-size: 24px\n}\n\n.content-header > h1 > small {\n    font-size: 15px;\n    display: inline-block;\n    padding-left: 4px;\n    font-weight: 300\n}\n\n.content-header > .breadcrumb {\n    float: right;\n    background: transparent;\n    margin-top: 0;\n    margin-bottom: 0;\n    font-size: 12px;\n    padding: 7px 5px;\n    position: absolute;\n    top: 15px;\n    right: 10px;\n    border-radius: 2px\n}\n\n.content-header > .breadcrumb > li > a {\n    color: #444;\n    text-decoration: none;\n    display: inline-block\n}\n\n.content-header > .breadcrumb > li > a > .fa, .content-header > .breadcrumb > li > a > .glyphicon, .content-header > .breadcrumb > li > a > .ion {\n    margin-right: 5px\n}\n\n.content-header > .breadcrumb > li + li:before {\n    content: '>\\00a0'\n}\n\n@media (max-width: 991px) {\n    .content-header > .breadcrumb {\n        position: relative;\n        margin-top: 5px;\n        top: 0;\n        right: 0;\n        float: none;\n        background: #d2d6de;\n        padding-left: 10px\n    }\n\n    .content-header > .breadcrumb li:before {\n        color: #97a0b3\n    }\n}\n\n.navbar-toggle {\n    color: #fff;\n    border: 0;\n    margin: 0;\n    padding: 15px 15px\n}\n\n@media (max-width: 991px) {\n    .navbar-custom-menu .navbar-nav > li {\n        float: left\n    }\n\n    .navbar-custom-menu .navbar-nav {\n        margin: 0;\n        float: left\n    }\n\n    .navbar-custom-menu .navbar-nav > li > a {\n        padding-top: 15px;\n        padding-bottom: 15px;\n        line-height: 20px\n    }\n}\n\n@media (max-width: 767px) {\n    .main-header {\n        position: relative\n    }\n\n    .main-header .logo, .main-header .navbar {\n        width: 100%;\n        float: none\n    }\n\n    .main-header .navbar {\n        margin: 0\n    }\n\n    .main-header .navbar-custom-menu {\n        float: right\n    }\n}\n\n@media (max-width: 991px) {\n    .navbar-collapse.pull-left {\n        float: none !important\n    }\n\n    .navbar-collapse.pull-left + .navbar-custom-menu {\n        display: block;\n        position: absolute;\n        top: 0;\n        right: 40px\n    }\n}\n\n.main-sidebar, .left-side {\n    /*position: absolute;*/\n    top: 0;\n    left: 0;\n    /*padding-top: 50px;*/\n    min-height: 100%;\n    /*width: 230px;*/\n    position: fixed;\n    width: 90px;\n    z-index: 810;\n    -webkit-transition: -webkit-transform .3s ease-in-out, width .3s ease-in-out;\n    -moz-transition: -moz-transform .3s ease-in-out, width .3s ease-in-out;\n    -o-transition: -o-transform .3s ease-in-out, width .3s ease-in-out;\n    transition: transform .3s ease-in-out, width .3s ease-in-out\n}\n\n@media (max-width: 767px) {\n    .main-sidebar, .left-side {\n        padding-top: 100px\n    }\n}\n\n@media (max-width: 767px) {\n    .main-sidebar, .left-side {\n        -webkit-transform: translate(-230px, 0);\n        -ms-transform: translate(-230px, 0);\n        -o-transform: translate(-230px, 0);\n        transform: translate(-230px, 0)\n    }\n}\n\n@media (min-width: 768px) {\n    .sidebar-collapse .main-sidebar, .sidebar-collapse .left-side {\n        -webkit-transform: translate(-230px, 0);\n        -ms-transform: translate(-230px, 0);\n        -o-transform: translate(-230px, 0);\n        transform: translate(-230px, 0)\n    }\n}\n\n@media (max-width: 767px) {\n    .sidebar-open .main-sidebar, .sidebar-open .left-side {\n        -webkit-transform: translate(0, 0);\n        -ms-transform: translate(0, 0);\n        -o-transform: translate(0, 0);\n        transform: translate(0, 0)\n    }\n}\n\n.sidebar {\n    padding-bottom: 10px\n}\n\n.sidebar-form input:focus {\n    border-color: transparent\n}\n\n.user-panel {\n    position: relative;\n    width: 100%;\n    padding: 10px;\n    overflow: hidden\n}\n\n.user-panel:before, .user-panel:after {\n    content: \" \";\n    display: table\n}\n\n.user-panel:after {\n    clear: both\n}\n\n.user-panel > .image > img {\n    width: 100%;\n    max-width: 45px;\n    height: auto\n}\n\n.user-panel > .info {\n    padding: 5px 5px 5px 15px;\n    line-height: 1;\n    position: absolute;\n    left: 55px\n}\n\n.user-panel > .info > p {\n    font-weight: 600;\n    margin-bottom: 9px\n}\n\n.user-panel > .info > a {\n    text-decoration: none;\n    padding-right: 5px;\n    margin-top: 3px;\n    font-size: 11px\n}\n\n.user-panel > .info > a > .fa, .user-panel > .info > a > .ion, .user-panel > .info > a > .glyphicon {\n    margin-right: 3px\n}\n\n.sidebar-menu {\n    list-style: none;\n    margin: 0;\n    padding: 0\n}\n\n.sidebar-menu > li {\n    position: relative;\n    margin: 0;\n    padding: 0\n}\n\n.sidebar-menu > li > a {\n    padding: 12px 5px 12px 15px;\n    display: block\n}\n\n.sidebar-menu > li > a > .fa, .sidebar-menu > li > a > .glyphicon, .sidebar-menu > li > a > .ion {\n    width: 20px\n}\n\n.sidebar-menu > li .label, .sidebar-menu > li .badge {\n    margin-top: 3px;\n    margin-right: 5px\n}\n\n.sidebar-menu li.header {\n    padding: 10px 25px 10px 15px;\n    font-size: 12px\n}\n\n.sidebar-menu li > a > .fa-angle-left {\n    width: auto;\n    height: auto;\n    padding: 0;\n    margin-right: 10px;\n    margin-top: 3px\n}\n\n.sidebar-menu li.active > a > .fa-angle-right {\n    margin-top: 0px;\n    right: 16px;\n    -webkit-transform: rotate(90deg);\n    -ms-transform: rotate(90deg);\n    -o-transform: rotate(90deg);\n    transform: rotate(90deg);\n}\n\n/*.sidebar-menu li.active > .treeview-menu {*/\n/*display: block;*/\n/*}*/\n\n.sidebar-menu .treeview-menu {\n    display: none;\n    list-style: none;\n    padding: 0;\n    margin: 0;\n    padding-left: 0px\n}\n\n.sidebar-menu .treeview-menu .treeview-menu {\n    padding-left: 20px\n}\n\n.sidebar-menu .treeview-menu > li {\n    margin: 0;\n    line-height: 36px;\n    margin-bottom: 14px;\n    border-radius: 3px;\n}\n\n.sidebar-menu .treeview-menu > li > a {\n    /*padding: 5px 5px 5px 5px;*/\n    display: block;\n    font-size: 14px\n}\n\n.sidebar-menu .treeview-menu > li > a > .fa, .sidebar-menu .treeview-menu > li > a > .glyphicon, .sidebar-menu .treeview-menu > li > a > .ion {\n    width: 20px\n}\n\n.sidebar-menu .treeview-menu > li > a > .fa-angle-left, .sidebar-menu .treeview-menu > li > a > .fa-angle-down {\n    width: auto\n}\n\n@media (min-width: 768px) {\n    .sidebar-mini.sidebar-collapse .content-wrapper, .sidebar-mini.sidebar-collapse .right-side, .sidebar-mini.sidebar-collapse .main-footer {\n        margin-left: 50px !important;\n        z-index: 840\n    }\n\n    .sidebar-mini.sidebar-collapse .main-sidebar {\n        -webkit-transform: translate(0, 0);\n        -ms-transform: translate(0, 0);\n        -o-transform: translate(0, 0);\n        transform: translate(0, 0);\n        width: 50px !important;\n        z-index: 850;\n    }\n\n    .sidebar-mini.sidebar-collapse .sidebar-menu > li {\n        position: relative\n    }\n\n    .sidebar-mini.sidebar-collapse .sidebar-menu > li > a {\n        margin-right: 0\n    }\n\n    .sidebar-mini.sidebar-collapse .sidebar-menu > li > a > span {\n        border-top-right-radius: 4px\n    }\n\n    .sidebar-mini.sidebar-collapse .sidebar-menu > li:not(.treeview) > a > span {\n        border-bottom-right-radius: 4px\n    }\n\n    .sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {\n        padding-top: 5px;\n        padding-bottom: 5px;\n        border-bottom-right-radius: 4px\n    }\n\n    .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span:not(.pull-right), .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > .treeview-menu {\n        display: block !important;\n        position: absolute;\n        width: 180px;\n        left: 50px\n    }\n\n    .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > a > span {\n        top: 0;\n        margin-left: -3px;\n        padding: 12px 5px 12px 20px;\n        background-color: inherit\n    }\n\n    .sidebar-mini.sidebar-collapse .sidebar-menu > li:hover > .treeview-menu {\n        top: 44px;\n        margin-left: 0\n    }\n\n    .sidebar-mini.sidebar-collapse .main-sidebar .user-panel > .info, .sidebar-mini.sidebar-collapse .sidebar-form, .sidebar-mini.sidebar-collapse .sidebar-menu > li > a > span, .sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu, .sidebar-mini.sidebar-collapse .sidebar-menu > li > a > .pull-right, .sidebar-mini.sidebar-collapse .sidebar-menu li.header {\n        display: none !important;\n        -webkit-transform: translateZ(0)\n    }\n\n    .sidebar-mini.sidebar-collapse .main-header .logo {\n        width: 50px\n    }\n\n    .sidebar-mini.sidebar-collapse .main-header .logo > .logo-mini {\n        display: block;\n        margin-left: -15px;\n        margin-right: -15px;\n        font-size: 12px\n    }\n\n    .sidebar-mini.sidebar-collapse .main-header .logo > .logo-lg {\n        display: none\n    }\n\n    .sidebar-mini.sidebar-collapse .main-header .navbar {\n        margin-left: 50px\n    }\n}\n\n.sidebar-menu, .main-sidebar .user-panel, .sidebar-menu > li.header {\n    white-space: nowrap;\n    overflow: hidden\n}\n\n.sidebar-menu:hover {\n    overflow: visible\n}\n\n.sidebar-form, .sidebar-menu > li.header {\n    overflow: hidden;\n    text-overflow: clip\n}\n\n.sidebar-menu li > a {\n    position: relative\n}\n\n.sidebar-menu li > a > .pull-right {\n    position: absolute;\n    top: 50%;\n    right: 10px;\n    margin-top: -7px\n}\n\n.control-sidebar-bg {\n    position: fixed;\n    z-index: 1000;\n    bottom: 0\n}\n\n.control-sidebar-bg, .control-sidebar {\n    top: 0;\n    right: -230px;\n    width: 230px;\n    -webkit-transition: right .3s ease-in-out;\n    -o-transition: right .3s ease-in-out;\n    transition: right .3s ease-in-out\n}\n\n.control-sidebar {\n    position: absolute;\n    padding-top: 50px;\n    z-index: 1010\n}\n\n@media (max-width: 768px) {\n    .control-sidebar {\n        padding-top: 100px\n    }\n}\n\n.control-sidebar > .tab-content {\n    padding: 10px 15px\n}\n\n.control-sidebar.control-sidebar-open, .control-sidebar.control-sidebar-open + .control-sidebar-bg {\n    right: 0\n}\n\n.control-sidebar-open .control-sidebar-bg, .control-sidebar-open .control-sidebar {\n    right: 0\n}\n\n@media (min-width: 768px) {\n    .control-sidebar-open .content-wrapper, .control-sidebar-open .right-side, .control-sidebar-open .main-footer {\n        margin-right: 230px\n    }\n}\n\n.nav-tabs.control-sidebar-tabs > li:first-of-type > a, .nav-tabs.control-sidebar-tabs > li:first-of-type > a:hover, .nav-tabs.control-sidebar-tabs > li:first-of-type > a:focus {\n    border-left-width: 0\n}\n\n.nav-tabs.control-sidebar-tabs > li > a {\n    border-radius: 0\n}\n\n.nav-tabs.control-sidebar-tabs > li > a, .nav-tabs.control-sidebar-tabs > li > a:hover {\n    border-top: none;\n    border-right: none;\n    border-left: 1px solid transparent;\n    border-bottom: 1px solid transparent\n}\n\n.nav-tabs.control-sidebar-tabs > li > a .icon {\n    font-size: 16px\n}\n\n.nav-tabs.control-sidebar-tabs > li.active > a, .nav-tabs.control-sidebar-tabs > li.active > a:hover, .nav-tabs.control-sidebar-tabs > li.active > a:focus, .nav-tabs.control-sidebar-tabs > li.active > a:active {\n    border-top: none;\n    border-right: none;\n    border-bottom: none\n}\n\n@media (max-width: 768px) {\n    .nav-tabs.control-sidebar-tabs {\n        display: table\n    }\n\n    .nav-tabs.control-sidebar-tabs > li {\n        display: table-cell\n    }\n}\n\n.control-sidebar-heading {\n    font-weight: 400;\n    font-size: 16px;\n    padding: 10px 0;\n    margin-bottom: 10px\n}\n\n.control-sidebar-subheading {\n    display: block;\n    font-weight: 400;\n    font-size: 14px\n}\n\n.control-sidebar-menu {\n    list-style: none;\n    padding: 0;\n    margin: 0 -15px\n}\n\n.control-sidebar-menu > li > a {\n    display: block;\n    padding: 10px 15px\n}\n\n.control-sidebar-menu > li > a:before, .control-sidebar-menu > li > a:after {\n    content: \" \";\n    display: table\n}\n\n.control-sidebar-menu > li > a:after {\n    clear: both\n}\n\n.control-sidebar-menu > li > a > .control-sidebar-subheading {\n    margin-top: 0\n}\n\n.control-sidebar-menu .menu-icon {\n    float: left;\n    width: 35px;\n    height: 35px;\n    border-radius: 50%;\n    text-align: center;\n    line-height: 35px\n}\n\n.control-sidebar-menu .menu-info {\n    margin-left: 45px;\n    margin-top: 3px\n}\n\n.control-sidebar-menu .menu-info > .control-sidebar-subheading {\n    margin: 0\n}\n\n.control-sidebar-menu .menu-info > p {\n    margin: 0;\n    font-size: 11px\n}\n\n.control-sidebar-menu .progress {\n    margin: 0\n}\n\n.control-sidebar-dark {\n    color: #b8c7ce\n}\n\n.control-sidebar-dark, .control-sidebar-dark + .control-sidebar-bg {\n    background: #222d32\n}\n\n.control-sidebar-dark .nav-tabs.control-sidebar-tabs {\n    border-bottom: #1c2529\n}\n\n.control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a {\n    background: #181f23;\n    color: #b8c7ce\n}\n\n.control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a:hover, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a:focus {\n    border-left-color: #141a1d;\n    border-bottom-color: #141a1d\n}\n\n.control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a:hover, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a:focus, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a:active {\n    background: #1c2529\n}\n\n.control-sidebar-dark .nav-tabs.control-sidebar-tabs > li > a:hover {\n    color: #fff\n}\n\n.control-sidebar-dark .nav-tabs.control-sidebar-tabs > li.active > a, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li.active > a:hover, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li.active > a:focus, .control-sidebar-dark .nav-tabs.control-sidebar-tabs > li.active > a:active {\n    background: #222d32;\n    color: #fff\n}\n\n.control-sidebar-dark .control-sidebar-heading, .control-sidebar-dark .control-sidebar-subheading {\n    color: #fff\n}\n\n.control-sidebar-dark .control-sidebar-menu > li > a:hover {\n    background: #1e282c\n}\n\n.control-sidebar-dark .control-sidebar-menu > li > a .menu-info > p {\n    color: #b8c7ce\n}\n\n.control-sidebar-light {\n    color: #5e5e5e\n}\n\n.control-sidebar-light, .control-sidebar-light + .control-sidebar-bg {\n    background: #ffffff;\n    border-left: 1px solid #eeeeee;\n}\n\n.control-sidebar-light .nav-tabs.control-sidebar-tabs {\n    border-bottom: #d2d6de\n}\n\n.control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a {\n    background: #e8ecf4;\n    color: #444\n}\n\n.control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:hover, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:focus {\n    border-left-color: #d2d6de;\n    border-bottom-color: #d2d6de\n}\n\n.control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:hover, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:focus, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li > a:active {\n    background: #eff1f7\n}\n\n.control-sidebar-light .nav-tabs.control-sidebar-tabs > li.active > a, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li.active > a:hover, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li.active > a:focus, .control-sidebar-light .nav-tabs.control-sidebar-tabs > li.active > a:active {\n    background: #f9fafc;\n    color: #111\n}\n\n.control-sidebar-light .control-sidebar-heading, .control-sidebar-light .control-sidebar-subheading {\n    color: #111\n}\n\n.control-sidebar-light .control-sidebar-menu {\n    margin-left: -14px\n}\n\n.control-sidebar-light .control-sidebar-menu > li > a:hover {\n    background: #f4f4f5\n}\n\n.control-sidebar-light .control-sidebar-menu > li > a .menu-info > p {\n    color: #5e5e5e\n}\n\n.dropdown-menu {\n    box-shadow: none;\n    border-color: #eee\n}\n\n.dropdown-menu > li > a {\n    color: #777\n}\n\n.dropdown-menu > li > a > .glyphicon, .dropdown-menu > li > a > .fa, .dropdown-menu > li > a > .ion {\n    margin-right: 10px\n}\n\n.dropdown-menu > li > a:hover {\n    background-color: #e1e3e9;\n    color: #333\n}\n\n.dropdown-menu > .divider {\n    background-color: #eee\n}\n\n.navbar-nav > .notifications-menu > .dropdown-menu, .navbar-nav > .messages-menu > .dropdown-menu, .navbar-nav > .tasks-menu > .dropdown-menu {\n    width: 280px;\n    padding: 0 0 0 0;\n    margin: 0;\n    top: 100%\n}\n\n.navbar-nav > .notifications-menu > .dropdown-menu > li, .navbar-nav > .messages-menu > .dropdown-menu > li, .navbar-nav > .tasks-menu > .dropdown-menu > li {\n    position: relative\n}\n\n.navbar-nav > .notifications-menu > .dropdown-menu > li.header, .navbar-nav > .messages-menu > .dropdown-menu > li.header, .navbar-nav > .tasks-menu > .dropdown-menu > li.header {\n    border-top-left-radius: 4px;\n    border-top-right-radius: 4px;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 0;\n    background-color: #ffffff;\n    padding: 7px 10px;\n    border-bottom: 1px solid #f4f4f4;\n    color: #444444;\n    font-size: 14px\n}\n\n.navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a, .navbar-nav > .messages-menu > .dropdown-menu > li.footer > a, .navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a {\n    border-top-left-radius: 0;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 4px;\n    border-bottom-left-radius: 4px;\n    font-size: 12px;\n    background-color: #fff;\n    padding: 7px 10px;\n    border-bottom: 1px solid #eeeeee;\n    color: #444 !important;\n    text-align: center\n}\n\n@media (max-width: 991px) {\n    .navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a, .navbar-nav > .messages-menu > .dropdown-menu > li.footer > a, .navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a {\n        background: #fff !important;\n        color: #444 !important\n    }\n}\n\n.navbar-nav > .notifications-menu > .dropdown-menu > li.footer > a:hover, .navbar-nav > .messages-menu > .dropdown-menu > li.footer > a:hover, .navbar-nav > .tasks-menu > .dropdown-menu > li.footer > a:hover {\n    text-decoration: none;\n    font-weight: normal\n}\n\n.navbar-nav > .notifications-menu > .dropdown-menu > li .menu, .navbar-nav > .messages-menu > .dropdown-menu > li .menu, .navbar-nav > .tasks-menu > .dropdown-menu > li .menu {\n    max-height: 200px;\n    margin: 0;\n    padding: 0;\n    list-style: none;\n    overflow-x: hidden\n}\n\n.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a, .navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a, .navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a {\n    display: block;\n    white-space: nowrap;\n    border-bottom: 1px solid #f4f4f4\n}\n\n.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a:hover, .navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:hover, .navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a:hover {\n    background: #f4f4f4;\n    text-decoration: none\n}\n\n.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a {\n    color: #444444;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    padding: 10px\n}\n\n.navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .glyphicon, .navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .fa, .navbar-nav > .notifications-menu > .dropdown-menu > li .menu > li > a > .ion {\n    width: 20px\n}\n\n.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a {\n    margin: 0;\n    padding: 10px 10px\n}\n\n.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > div > img {\n    margin: auto 10px auto auto;\n    width: 40px;\n    height: 40px\n}\n\n.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4 {\n    padding: 0;\n    margin: 0 0 0 45px;\n    color: #444444;\n    font-size: 15px;\n    position: relative\n}\n\n.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > h4 > small {\n    color: #999999;\n    font-size: 10px;\n    position: absolute;\n    top: 0;\n    right: 0\n}\n\n.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a > p {\n    margin: 0 0 0 45px;\n    font-size: 12px;\n    color: #888888\n}\n\n.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:before, .navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after {\n    content: \" \";\n    display: table\n}\n\n.navbar-nav > .messages-menu > .dropdown-menu > li .menu > li > a:after {\n    clear: both\n}\n\n.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a {\n    padding: 10px\n}\n\n.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a > h3 {\n    font-size: 14px;\n    padding: 0;\n    margin: 0 0 10px 0;\n    color: #666666\n}\n\n.navbar-nav > .tasks-menu > .dropdown-menu > li .menu > li > a > .progress {\n    padding: 0;\n    margin: 0\n}\n\n.navbar-nav > .user-menu > .dropdown-menu {\n    border-top-right-radius: 0;\n    border-top-left-radius: 0;\n    padding: 1px 0 0 0;\n    border-top-width: 0;\n    /*width: 280px*/\n}\n\n.navbar-nav > .user-menu > .dropdown-menu, .navbar-nav > .user-menu > .dropdown-menu > .user-body {\n    border-bottom-right-radius: 4px;\n    border-bottom-left-radius: 4px\n}\n\n.navbar-nav > .user-menu > .dropdown-menu > li.user-header {\n    height: 175px;\n    padding: 10px;\n    text-align: center\n}\n\n.navbar-nav > .user-menu > .dropdown-menu > li.user-header > img {\n    z-index: 5;\n    height: 90px;\n    width: 90px;\n    border: 3px solid;\n    border-color: transparent;\n    border-color: rgba(255, 255, 255, 0.2)\n}\n\n.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p {\n    z-index: 5;\n    color: #fff;\n    color: rgba(255, 255, 255, 0.8);\n    font-size: 17px;\n    margin-top: 10px\n}\n\n.navbar-nav > .user-menu > .dropdown-menu > li.user-header > p > small {\n    display: block;\n    font-size: 12px\n}\n\n.navbar-nav > .user-menu > .dropdown-menu > .user-body {\n    padding: 15px;\n    border-bottom: 1px solid #f4f4f4;\n    border-top: 1px solid #dddddd\n}\n\n.navbar-nav > .user-menu > .dropdown-menu > .user-body:before, .navbar-nav > .user-menu > .dropdown-menu > .user-body:after {\n    content: \" \";\n    display: table\n}\n\n.navbar-nav > .user-menu > .dropdown-menu > .user-body:after {\n    clear: both\n}\n\n.navbar-nav > .user-menu > .dropdown-menu > .user-body a {\n    color: #444 !important\n}\n\n@media (max-width: 991px) {\n    .navbar-nav > .user-menu > .dropdown-menu > .user-body a {\n        background: #fff !important;\n        color: #444 !important\n    }\n}\n\n.navbar-nav > .user-menu > .dropdown-menu > .user-footer {\n    background-color: #ffffff;\n    padding: 10px\n}\n\n.navbar-nav > .user-menu > .dropdown-menu > .user-footer:before, .navbar-nav > .user-menu > .dropdown-menu > .user-footer:after {\n    content: \" \";\n    display: table\n}\n\n.navbar-nav > .user-menu > .dropdown-menu > .user-footer:after {\n    clear: both\n}\n\n.navbar-nav > .user-menu > .dropdown-menu > .user-footer .btn-default {\n    color: #666666;\n    background-color: #ffffff;\n}\n\n@media (max-width: 991px) {\n    .navbar-nav > .user-menu > .dropdown-menu > .user-footer .btn-default:hover {\n        background-color: #f9f9f9\n    }\n}\n\n.navbar-nav > .user-menu .user-image {\n    float: left;\n    width: 25px;\n    height: 25px;\n    border-radius: 50%;\n    margin-right: 10px;\n    margin-top: -2px\n}\n\n@media (max-width: 767px) {\n    .navbar-nav > .user-menu .user-image {\n        float: none;\n        margin-right: 0;\n        margin-top: -8px;\n        line-height: 10px\n    }\n}\n\n.open:not(.dropup) > .animated-dropdown-menu {\n    backface-visibility: visible !important;\n    -webkit-animation: flipInX .7s both;\n    -o-animation: flipInX .7s both;\n    animation: flipInX .7s both\n}\n\n@keyframes flipInX {\n    0% {\n        transform: perspective(400px) rotate3d(1, 0, 0, 90deg);\n        transition-timing-function: ease-in;\n        opacity: 0\n    }\n    40% {\n        transform: perspective(400px) rotate3d(1, 0, 0, -20deg);\n        transition-timing-function: ease-in\n    }\n    60% {\n        transform: perspective(400px) rotate3d(1, 0, 0, 10deg);\n        opacity: 1\n    }\n    80% {\n        transform: perspective(400px) rotate3d(1, 0, 0, -5deg)\n    }\n    100% {\n        transform: perspective(400px)\n    }\n}\n\n@-webkit-keyframes flipInX {\n    0% {\n        -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 90deg);\n        -webkit-transition-timing-function: ease-in;\n        opacity: 0\n    }\n    40% {\n        -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -20deg);\n        -webkit-transition-timing-function: ease-in\n    }\n    60% {\n        -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 10deg);\n        opacity: 1\n    }\n    80% {\n        -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -5deg)\n    }\n    100% {\n        -webkit-transform: perspective(400px)\n    }\n}\n\n.navbar-custom-menu > .navbar-nav > li {\n    position: relative\n}\n\n.navbar-custom-menu > .navbar-nav > li > .dropdown-menu {\n    position: absolute;\n    right: 0;\n    left: auto\n}\n\n@media (max-width: 991px) {\n    .navbar-custom-menu > .navbar-nav {\n        float: right\n    }\n\n    .navbar-custom-menu > .navbar-nav > li {\n        position: static\n    }\n\n    .navbar-custom-menu > .navbar-nav > li > .dropdown-menu {\n        position: absolute;\n        right: 5%;\n        left: auto;\n        border: 1px solid #ddd;\n        background: #fff\n    }\n}\n\n.form-control {\n    border-radius: 0;\n    box-shadow: none;\n    border-color: #d2d6de\n}\n\n.form-control:focus {\n    border-color: #3c8dbc;\n    box-shadow: none\n}\n\n.form-control::-moz-placeholder, .form-control:-ms-input-placeholder, .form-control::-webkit-input-placeholder {\n    color: #bbb;\n    opacity: 1\n}\n\n.form-control:not(select) {\n    -webkit-appearance: none;\n    -moz-appearance: none;\n    appearance: none\n}\n\n.form-group.has-success label {\n    color: #00a65a\n}\n\n.form-group.has-success .form-control {\n    border-color: #00a65a;\n    box-shadow: none\n}\n\n.form-group.has-warning label {\n    color: #f39c12\n}\n\n.form-group.has-warning .form-control {\n    border-color: #f39c12;\n    box-shadow: none\n}\n\n.form-group.has-error label {\n    color: #dd4b39\n}\n\n.form-group.has-error .form-control {\n    border-color: #dd4b39;\n    box-shadow: none\n}\n\n.input-group .input-group-addon {\n    border-radius: 0;\n    border-color: #d2d6de;\n    background-color: #fff\n}\n\n.btn-group-vertical .btn.btn-flat:first-of-type, .btn-group-vertical .btn.btn-flat:last-of-type {\n    border-radius: 0\n}\n\n.icheck > label {\n    padding-left: 0\n}\n\n.form-control-feedback.fa {\n    line-height: 34px\n}\n\n.input-lg + .form-control-feedback.fa, .input-group-lg + .form-control-feedback.fa, .form-group-lg .form-control + .form-control-feedback.fa {\n    line-height: 46px\n}\n\n.input-sm + .form-control-feedback.fa, .input-group-sm + .form-control-feedback.fa, .form-group-sm .form-control + .form-control-feedback.fa {\n    line-height: 30px\n}\n\n.progress, .progress > .progress-bar {\n    -webkit-box-shadow: none;\n    box-shadow: none\n}\n\n.progress, .progress > .progress-bar, .progress .progress-bar, .progress > .progress-bar .progress-bar {\n    border-radius: 1px\n}\n\n.progress.sm, .progress-sm {\n    height: 10px\n}\n\n.progress.sm, .progress-sm, .progress.sm .progress-bar, .progress-sm .progress-bar {\n    border-radius: 1px\n}\n\n.progress.xs, .progress-xs {\n    height: 7px\n}\n\n.progress.xs, .progress-xs, .progress.xs .progress-bar, .progress-xs .progress-bar {\n    border-radius: 1px\n}\n\n.progress.xxs, .progress-xxs {\n    height: 3px\n}\n\n.progress.xxs, .progress-xxs, .progress.xxs .progress-bar, .progress-xxs .progress-bar {\n    border-radius: 1px\n}\n\n.progress.vertical {\n    position: relative;\n    width: 30px;\n    height: 200px;\n    display: inline-block;\n    margin-right: 10px\n}\n\n.progress.vertical > .progress-bar {\n    width: 100%;\n    position: absolute;\n    bottom: 0\n}\n\n.progress.vertical.sm, .progress.vertical.progress-sm {\n    width: 20px\n}\n\n.progress.vertical.xs, .progress.vertical.progress-xs {\n    width: 10px\n}\n\n.progress.vertical.xxs, .progress.vertical.progress-xxs {\n    width: 3px\n}\n\n.progress-group .progress-text {\n    font-weight: 600\n}\n\n.progress-group .progress-number {\n    float: right\n}\n\n.table tr > td .progress {\n    margin: 0\n}\n\n.progress-bar-light-blue, .progress-bar-primary {\n    background-color: #3c8dbc\n}\n\n.progress-striped .progress-bar-light-blue, .progress-striped .progress-bar-primary {\n    background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n    background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n    background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent)\n}\n\n.progress-bar-green, .progress-bar-success {\n    background-color: #00a65a\n}\n\n.progress-striped .progress-bar-green, .progress-striped .progress-bar-success {\n    background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n    background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n    background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent)\n}\n\n.progress-bar-aqua, .progress-bar-info {\n    background-color: #00c0ef\n}\n\n.progress-striped .progress-bar-aqua, .progress-striped .progress-bar-info {\n    background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n    background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n    background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent)\n}\n\n.progress-bar-yellow, .progress-bar-warning {\n    background-color: #f39c12\n}\n\n.progress-striped .progress-bar-yellow, .progress-striped .progress-bar-warning {\n    background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n    background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n    background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent)\n}\n\n.progress-bar-red, .progress-bar-danger {\n    background-color: #dd4b39\n}\n\n.progress-striped .progress-bar-red, .progress-striped .progress-bar-danger {\n    background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n    background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);\n    background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent)\n}\n\n.small-box {\n    border-radius: 2px;\n    position: relative;\n    display: block;\n    margin-bottom: 20px;\n    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1)\n}\n\n.small-box > .inner {\n    padding: 10px\n}\n\n.small-box > .small-box-footer {\n    position: relative;\n    text-align: center;\n    padding: 3px 0;\n    color: #fff;\n    color: rgba(255, 255, 255, 0.8);\n    display: block;\n    z-index: 10;\n    background: rgba(0, 0, 0, 0.1);\n    text-decoration: none\n}\n\n.small-box > .small-box-footer:hover {\n    color: #fff;\n    background: rgba(0, 0, 0, 0.15)\n}\n\n.small-box h3 {\n    font-size: 38px;\n    font-weight: bold;\n    margin: 0 0 10px 0;\n    white-space: nowrap;\n    padding: 0\n}\n\n.small-box p {\n    font-size: 15px\n}\n\n.small-box p > small {\n    display: block;\n    color: #f9f9f9;\n    font-size: 13px;\n    margin-top: 5px\n}\n\n.small-box h3, .small-box p {\n    z-index: 5px\n}\n\n.small-box .icon {\n    -webkit-transition: all .3s linear;\n    -o-transition: all .3s linear;\n    transition: all .3s linear;\n    position: absolute;\n    top: -10px;\n    right: 10px;\n    z-index: 0;\n    font-size: 90px;\n    color: rgba(0, 0, 0, 0.15)\n}\n\n.small-box:hover {\n    text-decoration: none;\n    color: #f9f9f9\n}\n\n.small-box:hover .icon {\n    font-size: 95px\n}\n\n@media (max-width: 767px) {\n    .small-box {\n        text-align: center\n    }\n\n    .small-box .icon {\n        display: none\n    }\n\n    .small-box p {\n        font-size: 12px\n    }\n}\n\n.box {\n    position: relative;\n    border-radius: 3px;\n    background: #ffffff;\n    border-top: 3px solid #d2d6de;\n    margin-bottom: 20px;\n    width: 100%;\n    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1)\n}\n\n.box.box-primary {\n    border-top-color: #3c8dbc\n}\n\n.box.box-info {\n    border-top-color: #00c0ef\n}\n\n.box.box-danger {\n    border-top-color: #dd4b39\n}\n\n.box.box-warning {\n    border-top-color: #f39c12\n}\n\n.box.box-success {\n    border-top-color: #00a65a\n}\n\n.box.box-default {\n    border-top-color: #d2d6de\n}\n\n.box.collapsed-box .box-body, .box.collapsed-box .box-footer {\n    display: none\n}\n\n.box .nav-stacked > li {\n    border-bottom: 1px solid #f4f4f4;\n    margin: 0\n}\n\n.box .nav-stacked > li:last-of-type {\n    border-bottom: none\n}\n\n.box.height-control .box-body {\n    max-height: 300px;\n    overflow: auto\n}\n\n.box .border-right {\n    border-right: 1px solid #f4f4f4\n}\n\n.box .border-left {\n    border-left: 1px solid #f4f4f4\n}\n\n.box.box-solid {\n    border-top: 0\n}\n\n.box.box-solid > .box-header .btn.btn-default {\n    background: transparent\n}\n\n.box.box-solid > .box-header .btn:hover, .box.box-solid > .box-header a:hover {\n    background: rgba(0, 0, 0, 0.1)\n}\n\n.box.box-solid.box-default {\n    border: 1px solid #d2d6de\n}\n\n.box.box-solid.box-default > .box-header {\n    color: #444;\n    background: #d2d6de;\n    background-color: #d2d6de\n}\n\n.box.box-solid.box-default > .box-header a, .box.box-solid.box-default > .box-header .btn {\n    color: #444\n}\n\n.box.box-solid.box-primary {\n    border: 1px solid #3c8dbc\n}\n\n.box.box-solid.box-primary > .box-header {\n    color: #fff;\n    background: #3c8dbc;\n    background-color: #3c8dbc\n}\n\n.box.box-solid.box-primary > .box-header a, .box.box-solid.box-primary > .box-header .btn {\n    color: #fff\n}\n\n.box.box-solid.box-info {\n    border: 1px solid #00c0ef\n}\n\n.box.box-solid.box-info > .box-header {\n    color: #fff;\n    background: #00c0ef;\n    background-color: #00c0ef\n}\n\n.box.box-solid.box-info > .box-header a, .box.box-solid.box-info > .box-header .btn {\n    color: #fff\n}\n\n.box.box-solid.box-danger {\n    border: 1px solid #dd4b39\n}\n\n.box.box-solid.box-danger > .box-header {\n    color: #fff;\n    background: #dd4b39;\n    background-color: #dd4b39\n}\n\n.box.box-solid.box-danger > .box-header a, .box.box-solid.box-danger > .box-header .btn {\n    color: #fff\n}\n\n.box.box-solid.box-warning {\n    border: 1px solid #f39c12\n}\n\n.box.box-solid.box-warning > .box-header {\n    color: #fff;\n    background: #f39c12;\n    background-color: #f39c12\n}\n\n.box.box-solid.box-warning > .box-header a, .box.box-solid.box-warning > .box-header .btn {\n    color: #fff\n}\n\n.box.box-solid.box-success {\n    border: 1px solid #00a65a\n}\n\n.box.box-solid.box-success > .box-header {\n    color: #fff;\n    background: #00a65a;\n    background-color: #00a65a\n}\n\n.box.box-solid.box-success > .box-header a, .box.box-solid.box-success > .box-header .btn {\n    color: #fff\n}\n\n.box.box-solid > .box-header > .box-tools .btn {\n    border: 0;\n    box-shadow: none\n}\n\n.box.box-solid[class*='bg'] > .box-header {\n    color: #fff\n}\n\n.box .box-group > .box {\n    margin-bottom: 5px\n}\n\n.box .knob-label {\n    text-align: center;\n    color: #333;\n    font-weight: 100;\n    font-size: 12px;\n    margin-bottom: 0.3em\n}\n\n.box > .overlay, .overlay-wrapper > .overlay, .box > .loading-img, .overlay-wrapper > .loading-img {\n    position: absolute;\n    top: 0;\n    left: 0;\n    width: 100%;\n    height: 100%\n}\n\n.box .overlay, .overlay-wrapper .overlay {\n    z-index: 50;\n    background: rgba(255, 255, 255, 0.7);\n    border-radius: 3px\n}\n\n.box .overlay > .fa, .overlay-wrapper .overlay > .fa {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    margin-left: -15px;\n    margin-top: -15px;\n    color: #000;\n    font-size: 30px\n}\n\n.box .overlay.dark, .overlay-wrapper .overlay.dark {\n    background: rgba(0, 0, 0, 0.5)\n}\n\n.box-header:before, .box-body:before, .box-footer:before, .box-header:after, .box-body:after, .box-footer:after {\n    content: \" \";\n    display: table\n}\n\n.box-header:after, .box-body:after, .box-footer:after {\n    clear: both\n}\n\n.box-header {\n    color: #444;\n    display: block;\n    padding: 10px;\n    position: relative\n}\n\n.box-header.with-border {\n    border-bottom: 1px solid #f4f4f4\n}\n\n.collapsed-box .box-header.with-border {\n    border-bottom: none\n}\n\n.box-header > .fa, .box-header > .glyphicon, .box-header > .ion, .box-header .box-title {\n    display: inline-block;\n    font-size: 18px;\n    margin: 0;\n    line-height: 1\n}\n\n.box-header > .fa, .box-header > .glyphicon, .box-header > .ion {\n    margin-right: 5px\n}\n\n.box-header > .box-tools {\n    position: absolute;\n    right: 10px;\n    top: 5px\n}\n\n.box-header > .box-tools [data-toggle=\"tooltip\"] {\n    position: relative\n}\n\n.box-header > .box-tools.pull-right .dropdown-menu {\n    right: 0;\n    left: auto\n}\n\n.btn-box-tool {\n    padding: 5px;\n    font-size: 12px;\n    background: transparent;\n    color: #97a0b3\n}\n\n.open .btn-box-tool, .btn-box-tool:hover {\n    color: #606c84\n}\n\n.btn-box-tool.btn:active {\n    box-shadow: none\n}\n\n.box-body {\n    border-top-left-radius: 0;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 3px;\n    border-bottom-left-radius: 3px;\n    padding: 10px\n}\n\n.no-header .box-body {\n    border-top-right-radius: 3px;\n    border-top-left-radius: 3px\n}\n\n.box-body > .table {\n    margin-bottom: 0\n}\n\n.box-body .fc {\n    margin-top: 5px\n}\n\n.box-body .full-width-chart {\n    margin: -19px\n}\n\n.box-body.no-padding .full-width-chart {\n    margin: -9px\n}\n\n.box-body .box-pane {\n    border-top-left-radius: 0;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 3px\n}\n\n.box-body .box-pane-right {\n    border-top-left-radius: 0;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 3px;\n    border-bottom-left-radius: 0\n}\n\n.box-footer {\n    border-top-left-radius: 0;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 3px;\n    border-bottom-left-radius: 3px;\n    border-top: 1px solid #f4f4f4;\n    padding: 10px;\n    background-color: #fff\n}\n\n.chart-legend {\n    margin: 10px 0\n}\n\n@media (max-width: 991px) {\n    .chart-legend > li {\n        float: left;\n        margin-right: 10px\n    }\n}\n\n.box-comments {\n    background: #f7f7f7\n}\n\n.box-comments .box-comment {\n    padding: 8px 0;\n    border-bottom: 1px solid #eee\n}\n\n.box-comments .box-comment:before, .box-comments .box-comment:after {\n    content: \" \";\n    display: table\n}\n\n.box-comments .box-comment:after {\n    clear: both\n}\n\n.box-comments .box-comment:last-of-type {\n    border-bottom: 0\n}\n\n.box-comments .box-comment:first-of-type {\n    padding-top: 0\n}\n\n.box-comments .box-comment img {\n    float: left\n}\n\n.box-comments .comment-text {\n    margin-left: 40px;\n    color: #555\n}\n\n.box-comments .username {\n    color: #444;\n    display: block;\n    font-weight: 600\n}\n\n.box-comments .text-muted {\n    font-weight: 400;\n    font-size: 12px\n}\n\n.todo-list {\n    margin: 0;\n    padding: 0;\n    list-style: none;\n    overflow: auto\n}\n\n.todo-list > li {\n    border-radius: 2px;\n    padding: 10px;\n    background: #f4f4f4;\n    margin-bottom: 2px;\n    border-left: 2px solid #e6e7e8;\n    color: #444\n}\n\n.todo-list > li:last-of-type {\n    margin-bottom: 0\n}\n\n.todo-list > li > input[type='checkbox'] {\n    margin: 0 10px 0 5px\n}\n\n.todo-list > li .text {\n    display: inline-block;\n    margin-left: 5px;\n    font-weight: 600\n}\n\n.todo-list > li .label {\n    margin-left: 10px;\n    font-size: 9px\n}\n\n.todo-list > li .tools {\n    display: none;\n    float: right;\n    color: #dd4b39\n}\n\n.todo-list > li .tools > .fa, .todo-list > li .tools > .glyphicon, .todo-list > li .tools > .ion {\n    margin-right: 5px;\n    cursor: pointer\n}\n\n.todo-list > li:hover .tools {\n    display: inline-block\n}\n\n.todo-list > li.done {\n    color: #999\n}\n\n.todo-list > li.done .text {\n    text-decoration: line-through;\n    font-weight: 500\n}\n\n.todo-list > li.done .label {\n    background: #d2d6de !important\n}\n\n.todo-list .danger {\n    border-left-color: #dd4b39\n}\n\n.todo-list .warning {\n    border-left-color: #f39c12\n}\n\n.todo-list .info {\n    border-left-color: #00c0ef\n}\n\n.todo-list .success {\n    border-left-color: #00a65a\n}\n\n.todo-list .primary {\n    border-left-color: #3c8dbc\n}\n\n.todo-list .handle {\n    display: inline-block;\n    cursor: move;\n    margin: 0 5px\n}\n\n.chat {\n    padding: 5px 20px 5px 10px\n}\n\n.chat .item {\n    margin-bottom: 10px\n}\n\n.chat .item:before, .chat .item:after {\n    content: \" \";\n    display: table\n}\n\n.chat .item:after {\n    clear: both\n}\n\n.chat .item > img {\n    width: 40px;\n    height: 40px;\n    border: 2px solid transparent;\n    border-radius: 50%\n}\n\n.chat .item > .online {\n    border: 2px solid #00a65a\n}\n\n.chat .item > .offline {\n    border: 2px solid #dd4b39\n}\n\n.chat .item > .message {\n    margin-left: 55px;\n    margin-top: -40px\n}\n\n.chat .item > .message > .name {\n    display: block;\n    font-weight: 600\n}\n\n.chat .item > .attachment {\n    border-radius: 3px;\n    background: #f4f4f4;\n    margin-left: 65px;\n    margin-right: 15px;\n    padding: 10px\n}\n\n.chat .item > .attachment > h4 {\n    margin: 0 0 5px 0;\n    font-weight: 600;\n    font-size: 14px\n}\n\n.chat .item > .attachment > p, .chat .item > .attachment > .filename {\n    font-weight: 600;\n    font-size: 13px;\n    font-style: italic;\n    margin: 0\n}\n\n.chat .item > .attachment:before, .chat .item > .attachment:after {\n    content: \" \";\n    display: table\n}\n\n.chat .item > .attachment:after {\n    clear: both\n}\n\n.box-input {\n    max-width: 200px\n}\n\n.modal .panel-body {\n    color: #444\n}\n\n.info-box {\n    display: block;\n    min-height: 90px;\n    background: #fff;\n    width: 100%;\n    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n    border-radius: 2px;\n    margin-bottom: 15px\n}\n\n.info-box small {\n    font-size: 14px\n}\n\n.info-box .progress {\n    background: rgba(0, 0, 0, 0.2);\n    margin: 5px -10px 5px -10px;\n    height: 2px\n}\n\n.info-box .progress, .info-box .progress .progress-bar {\n    border-radius: 0\n}\n\n.info-box .progress .progress-bar {\n    background: #fff\n}\n\n.info-box-icon {\n    border-top-left-radius: 2px;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 2px;\n    display: block;\n    float: left;\n    height: 90px;\n    width: 90px;\n    text-align: center;\n    font-size: 45px;\n    line-height: 90px;\n    background: rgba(0, 0, 0, 0.2)\n}\n\n.info-box-icon > img {\n    max-width: 100%\n}\n\n.info-box-content {\n    padding: 5px 10px;\n    margin-left: 90px\n}\n\n.info-box-number {\n    display: block;\n    font-weight: bold;\n    font-size: 18px\n}\n\n.progress-description, .info-box-text {\n    display: block;\n    font-size: 14px;\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis\n}\n\n.info-box-text {\n    text-transform: uppercase\n}\n\n.info-box-more {\n    display: block\n}\n\n.progress-description {\n    margin: 0\n}\n\n.timeline {\n    position: relative;\n    margin: 0 0 30px 0;\n    padding: 0;\n    list-style: none\n}\n\n.timeline:before {\n    content: '';\n    position: absolute;\n    top: 0;\n    bottom: 0;\n    width: 4px;\n    background: #ddd;\n    left: 31px;\n    margin: 0;\n    border-radius: 2px\n}\n\n.timeline > li {\n    position: relative;\n    margin-right: 10px;\n    margin-bottom: 15px\n}\n\n.timeline > li:before, .timeline > li:after {\n    content: \" \";\n    display: table\n}\n\n.timeline > li:after {\n    clear: both\n}\n\n.timeline > li > .timeline-item {\n    -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n    border-radius: 3px;\n    margin-top: 0;\n    background: #fff;\n    color: #444;\n    margin-left: 60px;\n    margin-right: 15px;\n    padding: 0;\n    position: relative\n}\n\n.timeline > li > .timeline-item > .time {\n    color: #999;\n    float: right;\n    padding: 10px;\n    font-size: 12px\n}\n\n.timeline > li > .timeline-item > .timeline-header {\n    margin: 0;\n    color: #555;\n    border-bottom: 1px solid #f4f4f4;\n    padding: 10px;\n    font-size: 16px;\n    line-height: 1.1\n}\n\n.timeline > li > .timeline-item > .timeline-header > a {\n    font-weight: 600\n}\n\n.timeline > li > .timeline-item > .timeline-body, .timeline > li > .timeline-item > .timeline-footer {\n    padding: 10px\n}\n\n.timeline > li > .fa, .timeline > li > .glyphicon, .timeline > li > .ion {\n    width: 30px;\n    height: 30px;\n    font-size: 15px;\n    line-height: 30px;\n    position: absolute;\n    color: #666;\n    background: #d2d6de;\n    border-radius: 50%;\n    text-align: center;\n    left: 18px;\n    top: 0\n}\n\n.timeline > .time-label > span {\n    font-weight: 600;\n    padding: 5px;\n    display: inline-block;\n    background-color: #fff;\n    border-radius: 4px\n}\n\n.timeline-inverse > li > .timeline-item {\n    background: #f0f0f0;\n    border: 1px solid #ddd;\n    -webkit-box-shadow: none;\n    box-shadow: none\n}\n\n.timeline-inverse > li > .timeline-item > .timeline-header {\n    border-bottom-color: #ddd\n}\n\n.btn {\n    border-radius: 3px;\n    -webkit-box-shadow: none;\n    box-shadow: none;\n    border: 1px solid transparent\n}\n\n.btn.uppercase {\n    text-transform: uppercase\n}\n\n.btn.btn-flat {\n    border-radius: 0;\n    -webkit-box-shadow: none;\n    -moz-box-shadow: none;\n    box-shadow: none;\n    border-width: 1px\n}\n\n.btn:active {\n    -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n    -moz-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n    box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125)\n}\n\n.btn:focus {\n    outline: none\n}\n\n.btn.btn-file {\n    position: relative;\n    overflow: hidden\n}\n\n.btn.btn-file > input[type='file'] {\n    position: absolute;\n    top: 0;\n    right: 0;\n    min-width: 100%;\n    min-height: 100%;\n    font-size: 100px;\n    text-align: right;\n    opacity: 0;\n    filter: alpha(opacity=0);\n    outline: none;\n    background: white;\n    cursor: inherit;\n    display: block\n}\n\n.btn-default {\n    background-color: #f4f4f4;\n    color: #444;\n    border-color: #ddd\n}\n\n.btn-default:hover, .btn-default:active, .btn-default.hover {\n    background-color: #e7e7e7\n}\n\n.btn-primary {\n    background-color: #3c8dbc;\n    border-color: #367fa9\n}\n\n.btn-primary:hover, .btn-primary:active, .btn-primary.hover {\n    background-color: #367fa9\n}\n\n.btn-success {\n    background-color: #00a65a;\n    border-color: #008d4c\n}\n\n.btn-success:hover, .btn-success:active, .btn-success.hover {\n    background-color: #008d4c\n}\n\n.btn-info {\n    background-color: #00c0ef;\n    border-color: #00acd6\n}\n\n.btn-info:hover, .btn-info:active, .btn-info.hover {\n    background-color: #00acd6\n}\n\n.btn-danger {\n    background-color: #dd4b39;\n    border-color: #d73925\n}\n\n.btn-danger:hover, .btn-danger:active, .btn-danger.hover {\n    background-color: #d73925\n}\n\n.btn-warning {\n    background-color: #f39c12;\n    border-color: #e08e0b\n}\n\n.btn-warning:hover, .btn-warning:active, .btn-warning.hover {\n    background-color: #e08e0b\n}\n\n.btn-outline {\n    border: 1px solid #fff;\n    background: transparent;\n    color: #fff\n}\n\n.btn-outline:hover, .btn-outline:focus, .btn-outline:active {\n    color: rgba(255, 255, 255, 0.7);\n    border-color: rgba(255, 255, 255, 0.7)\n}\n\n.btn-link {\n    -webkit-box-shadow: none;\n    box-shadow: none\n}\n\n.btn[class*='bg-']:hover {\n    -webkit-box-shadow: inset 0 0 100px rgba(0, 0, 0, 0.2);\n    box-shadow: inset 0 0 100px rgba(0, 0, 0, 0.2)\n}\n\n.btn-app {\n    border-radius: 3px;\n    position: relative;\n    padding: 15px 5px;\n    margin: 0 0 10px 10px;\n    min-width: 80px;\n    height: 60px;\n    text-align: center;\n    color: #666;\n    border: 1px solid #ddd;\n    background-color: #f4f4f4;\n    font-size: 12px\n}\n\n.btn-app > .fa, .btn-app > .glyphicon, .btn-app > .ion {\n    font-size: 20px;\n    display: block\n}\n\n.btn-app:hover {\n    background: #f4f4f4;\n    color: #444;\n    border-color: #aaa\n}\n\n.btn-app:active, .btn-app:focus {\n    -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n    -moz-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125);\n    box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.125)\n}\n\n.btn-app > .badge {\n    position: absolute;\n    top: -3px;\n    right: -10px;\n    font-size: 10px;\n    font-weight: 400\n}\n\n.callout {\n    border-radius: 3px;\n    margin: 0 0 20px 0;\n    padding: 15px 30px 15px 15px;\n    border-left: 5px solid #eee\n}\n\n.callout a {\n    color: #fff;\n    text-decoration: underline\n}\n\n.callout a:hover {\n    color: #eee\n}\n\n.callout h4 {\n    margin-top: 0;\n    font-weight: 600\n}\n\n.callout p:last-child {\n    margin-bottom: 0\n}\n\n.callout code, .callout .highlight {\n    background-color: #fff\n}\n\n.callout.callout-danger {\n    border-color: #c23321\n}\n\n.callout.callout-warning {\n    border-color: #c87f0a\n}\n\n.callout.callout-info {\n    border-color: #0097bc\n}\n\n.callout.callout-success {\n    border-color: #00733e\n}\n\n.alert {\n    border-radius: 3px\n}\n\n.alert h4 {\n    font-weight: 600\n}\n\n.alert .icon {\n    margin-right: 10px\n}\n\n.alert .close {\n    color: #000;\n    opacity: .2;\n    filter: alpha(opacity=20)\n}\n\n.alert .close:hover {\n    opacity: .5;\n    filter: alpha(opacity=50)\n}\n\n.alert a {\n    color: #fff;\n    text-decoration: underline\n}\n\n.alert-success {\n    border-color: #008d4c\n}\n\n.alert-danger, .alert-error {\n    border-color: #d73925\n}\n\n.alert-warning {\n    border-color: #e08e0b\n}\n\n.alert-info {\n    border-color: #00acd6\n}\n\n.nav > li > a:hover, .nav > li > a:active, .nav > li > a:focus {\n    color: #444;\n    background: #f7f7f7\n}\n\n.nav-pills > li > a {\n    border-radius: 0;\n    border-top: 3px solid transparent;\n    color: #444\n}\n\n.nav-pills > li > a > .fa, .nav-pills > li > a > .glyphicon, .nav-pills > li > a > .ion {\n    margin-right: 5px\n}\n\n.nav-pills > li.active > a, .nav-pills > li.active > a:hover, .nav-pills > li.active > a:focus {\n    border-top-color: #3c8dbc\n}\n\n.nav-pills > li.active > a {\n    font-weight: 600\n}\n\n.nav-stacked > li > a {\n    border-radius: 0;\n    border-top: 0;\n    border-left: 3px solid transparent;\n    color: #444\n}\n\n.nav-stacked > li.active > a, .nav-stacked > li.active > a:hover {\n    background: transparent;\n    color: #444;\n    border-top: 0;\n    border-left-color: #3c8dbc\n}\n\n.nav-stacked > li.header {\n    border-bottom: 1px solid #ddd;\n    color: #777;\n    margin-bottom: 10px;\n    padding: 5px 10px;\n    text-transform: uppercase\n}\n\n.nav-tabs-custom {\n    margin-bottom: 20px;\n    background: #fff;\n    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n    border-radius: 3px\n}\n\n.nav-tabs-custom > .nav-tabs {\n    margin: 0;\n    border-bottom-color: #f4f4f4;\n    border-top-right-radius: 3px;\n    border-top-left-radius: 3px\n}\n\n.nav-tabs-custom > .nav-tabs > li {\n    border-top: 3px solid transparent;\n    margin-bottom: -2px;\n    margin-right: 5px\n}\n\n.nav-tabs-custom > .nav-tabs > li > a {\n    color: #444;\n    border-radius: 0\n}\n\n.nav-tabs-custom > .nav-tabs > li > a.text-muted {\n    color: #999\n}\n\n.nav-tabs-custom > .nav-tabs > li > a, .nav-tabs-custom > .nav-tabs > li > a:hover {\n    background: transparent;\n    margin: 0\n}\n\n.nav-tabs-custom > .nav-tabs > li > a:hover {\n    color: #999\n}\n\n.nav-tabs-custom > .nav-tabs > li:not(.active) > a:hover, .nav-tabs-custom > .nav-tabs > li:not(.active) > a:focus, .nav-tabs-custom > .nav-tabs > li:not(.active) > a:active {\n    border-color: transparent\n}\n\n.nav-tabs-custom > .nav-tabs > li.active {\n    border-top-color: #b0b4b7\n}\n\n.nav-tabs-custom > .nav-tabs > li.active > a, .nav-tabs-custom > .nav-tabs > li.active:hover > a {\n    background-color: #fff;\n    color: #444\n}\n\n.nav-tabs-custom > .nav-tabs > li.active > a {\n    border-top-color: transparent;\n    border-left-color: #f4f4f4;\n    border-right-color: #f4f4f4\n}\n\n.nav-tabs-custom > .nav-tabs > li:first-of-type {\n    margin-left: 0\n}\n\n.nav-tabs-custom > .nav-tabs > li:first-of-type.active > a {\n    border-left-color: transparent\n}\n\n.nav-tabs-custom > .nav-tabs.pull-right {\n    float: none !important\n}\n\n.nav-tabs-custom > .nav-tabs.pull-right > li {\n    float: right\n}\n\n.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type {\n    margin-right: 0\n}\n\n.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type > a {\n    border-left-width: 1px\n}\n\n.nav-tabs-custom > .nav-tabs.pull-right > li:first-of-type.active > a {\n    border-left-color: #f4f4f4;\n    border-right-color: transparent\n}\n\n.nav-tabs-custom > .nav-tabs > li.header {\n    line-height: 35px;\n    padding: 0 10px;\n    font-size: 20px;\n    color: #444\n}\n\n.nav-tabs-custom > .nav-tabs > li.header > .fa, .nav-tabs-custom > .nav-tabs > li.header > .glyphicon, .nav-tabs-custom > .nav-tabs > li.header > .ion {\n    margin-right: 5px\n}\n\n.nav-tabs-custom > .tab-content {\n    background: #fff;\n    padding: 10px;\n    border-bottom-right-radius: 3px;\n    border-bottom-left-radius: 3px\n}\n\n.nav-tabs-custom .dropdown.open > a:active, .nav-tabs-custom .dropdown.open > a:focus {\n    background: transparent;\n    color: #999\n}\n\n.nav-tabs-custom.tab-primary > .nav-tabs > li.active {\n    border-top-color: #3c8dbc\n}\n\n.nav-tabs-custom.tab-info > .nav-tabs > li.active {\n    border-top-color: #00c0ef\n}\n\n.nav-tabs-custom.tab-danger > .nav-tabs > li.active {\n    border-top-color: #dd4b39\n}\n\n.nav-tabs-custom.tab-warning > .nav-tabs > li.active {\n    border-top-color: #f39c12\n}\n\n.nav-tabs-custom.tab-success > .nav-tabs > li.active {\n    border-top-color: #00a65a\n}\n\n.nav-tabs-custom.tab-default > .nav-tabs > li.active {\n    border-top-color: #d2d6de\n}\n\n.pagination > li > a {\n    background: #fafafa;\n    color: #666\n}\n\n.pagination.pagination-flat > li > a {\n    border-radius: 0 !important\n}\n\n.products-list {\n    list-style: none;\n    margin: 0;\n    padding: 0\n}\n\n.products-list > .item {\n    border-radius: 3px;\n    -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n    padding: 10px 0;\n    background: #fff\n}\n\n.products-list > .item:before, .products-list > .item:after {\n    content: \" \";\n    display: table\n}\n\n.products-list > .item:after {\n    clear: both\n}\n\n.products-list .product-img {\n    float: left\n}\n\n.products-list .product-img img {\n    width: 50px;\n    height: 50px\n}\n\n.products-list .product-info {\n    margin-left: 60px\n}\n\n.products-list .product-title {\n    font-weight: 600\n}\n\n.products-list .product-description {\n    display: block;\n    color: #999;\n    overflow: hidden;\n    white-space: nowrap;\n    text-overflow: ellipsis\n}\n\n.product-list-in-box > .item {\n    -webkit-box-shadow: none;\n    box-shadow: none;\n    border-radius: 0;\n    border-bottom: 1px solid #f4f4f4\n}\n\n.product-list-in-box > .item:last-of-type {\n    border-bottom-width: 0\n}\n\n.table > thead > tr > th, .table > tbody > tr > th, .table > tfoot > tr > th, .table > thead > tr > td, .table > tbody > tr > td, .table > tfoot > tr > td {\n    border-top: 1px solid #f4f4f4\n}\n\n.table > thead > tr > th {\n    border-bottom: 2px solid #f4f4f4\n}\n\n.table tr td .progress {\n    margin-top: 5px\n}\n\n.table-bordered {\n    border: 1px solid #f4f4f4\n}\n\n.table-bordered > thead > tr > th, .table-bordered > tbody > tr > th, .table-bordered > tfoot > tr > th, .table-bordered > thead > tr > td, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > td {\n    border: 1px solid #f4f4f4\n}\n\n.table-bordered > thead > tr > th, .table-bordered > thead > tr > td {\n    border-bottom-width: 2px\n}\n\n.table.no-border, .table.no-border td, .table.no-border th {\n    border: 0\n}\n\ntable.text-center, table.text-center td, table.text-center th {\n    text-align: center\n}\n\n.table.align th {\n    text-align: left\n}\n\n.table.align td {\n    text-align: right\n}\n\n.label-default {\n    background-color: #d2d6de;\n    color: #444\n}\n\n.direct-chat .box-body {\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 0;\n    position: relative;\n    overflow-x: hidden;\n    padding: 0\n}\n\n.direct-chat.chat-pane-open .direct-chat-contacts {\n    -webkit-transform: translate(0, 0);\n    -ms-transform: translate(0, 0);\n    -o-transform: translate(0, 0);\n    transform: translate(0, 0)\n}\n\n.direct-chat-messages {\n    -webkit-transform: translate(0, 0);\n    -ms-transform: translate(0, 0);\n    -o-transform: translate(0, 0);\n    transform: translate(0, 0);\n    padding: 10px;\n    height: 250px;\n    overflow: auto\n}\n\n.direct-chat-msg, .direct-chat-text {\n    display: block\n}\n\n.direct-chat-msg {\n    margin-bottom: 10px\n}\n\n.direct-chat-msg:before, .direct-chat-msg:after {\n    content: \" \";\n    display: table\n}\n\n.direct-chat-msg:after {\n    clear: both\n}\n\n.direct-chat-messages, .direct-chat-contacts {\n    -webkit-transition: -webkit-transform .5s ease-in-out;\n    -moz-transition: -moz-transform .5s ease-in-out;\n    -o-transition: -o-transform .5s ease-in-out;\n    transition: transform .5s ease-in-out\n}\n\n.direct-chat-text {\n    border-radius: 5px;\n    position: relative;\n    padding: 5px 10px;\n    background: #d2d6de;\n    border: 1px solid #d2d6de;\n    margin: 5px 0 0 50px;\n    color: #444\n}\n\n.direct-chat-text:after, .direct-chat-text:before {\n    position: absolute;\n    right: 100%;\n    top: 15px;\n    border: solid transparent;\n    border-right-color: #d2d6de;\n    content: ' ';\n    height: 0;\n    width: 0;\n    pointer-events: none\n}\n\n.direct-chat-text:after {\n    border-width: 5px;\n    margin-top: -5px\n}\n\n.direct-chat-text:before {\n    border-width: 6px;\n    margin-top: -6px\n}\n\n.right .direct-chat-text {\n    margin-right: 50px;\n    margin-left: 0\n}\n\n.right .direct-chat-text:after, .right .direct-chat-text:before {\n    right: auto;\n    left: 100%;\n    border-right-color: transparent;\n    border-left-color: #d2d6de\n}\n\n.direct-chat-img {\n    border-radius: 50%;\n    float: left;\n    width: 40px;\n    height: 40px\n}\n\n.right .direct-chat-img {\n    float: right\n}\n\n.direct-chat-info {\n    display: block;\n    margin-bottom: 2px;\n    font-size: 12px\n}\n\n.direct-chat-name {\n    font-weight: 600\n}\n\n.direct-chat-timestamp {\n    color: #999\n}\n\n.direct-chat-contacts-open .direct-chat-contacts {\n    -webkit-transform: translate(0, 0);\n    -ms-transform: translate(0, 0);\n    -o-transform: translate(0, 0);\n    transform: translate(0, 0)\n}\n\n.direct-chat-contacts {\n    -webkit-transform: translate(101%, 0);\n    -ms-transform: translate(101%, 0);\n    -o-transform: translate(101%, 0);\n    transform: translate(101%, 0);\n    position: absolute;\n    top: 0;\n    bottom: 0;\n    height: 250px;\n    width: 100%;\n    background: #222d32;\n    color: #fff;\n    overflow: auto\n}\n\n.contacts-list > li {\n    border-bottom: 1px solid rgba(0, 0, 0, 0.2);\n    padding: 10px;\n    margin: 0\n}\n\n.contacts-list > li:before, .contacts-list > li:after {\n    content: \" \";\n    display: table\n}\n\n.contacts-list > li:after {\n    clear: both\n}\n\n.contacts-list > li:last-of-type {\n    border-bottom: none\n}\n\n.contacts-list-img {\n    border-radius: 50%;\n    width: 40px;\n    float: left\n}\n\n.contacts-list-info {\n    margin-left: 45px;\n    color: #fff\n}\n\n.contacts-list-name, .contacts-list-status {\n    display: block\n}\n\n.contacts-list-name {\n    font-weight: 600\n}\n\n.contacts-list-status {\n    font-size: 12px\n}\n\n.contacts-list-date {\n    color: #aaa;\n    font-weight: normal\n}\n\n.contacts-list-msg {\n    color: #999\n}\n\n.direct-chat-danger .right > .direct-chat-text {\n    background: #dd4b39;\n    border-color: #dd4b39;\n    color: #fff\n}\n\n.direct-chat-danger .right > .direct-chat-text:after, .direct-chat-danger .right > .direct-chat-text:before {\n    border-left-color: #dd4b39\n}\n\n.direct-chat-primary .right > .direct-chat-text {\n    background: #3c8dbc;\n    border-color: #3c8dbc;\n    color: #fff\n}\n\n.direct-chat-primary .right > .direct-chat-text:after, .direct-chat-primary .right > .direct-chat-text:before {\n    border-left-color: #3c8dbc\n}\n\n.direct-chat-warning .right > .direct-chat-text {\n    background: #f39c12;\n    border-color: #f39c12;\n    color: #fff\n}\n\n.direct-chat-warning .right > .direct-chat-text:after, .direct-chat-warning .right > .direct-chat-text:before {\n    border-left-color: #f39c12\n}\n\n.direct-chat-info .right > .direct-chat-text {\n    background: #00c0ef;\n    border-color: #00c0ef;\n    color: #fff\n}\n\n.direct-chat-info .right > .direct-chat-text:after, .direct-chat-info .right > .direct-chat-text:before {\n    border-left-color: #00c0ef\n}\n\n.direct-chat-success .right > .direct-chat-text {\n    background: #00a65a;\n    border-color: #00a65a;\n    color: #fff\n}\n\n.direct-chat-success .right > .direct-chat-text:after, .direct-chat-success .right > .direct-chat-text:before {\n    border-left-color: #00a65a\n}\n\n.users-list > li {\n    width: 25%;\n    float: left;\n    padding: 10px;\n    text-align: center\n}\n\n.users-list > li img {\n    border-radius: 50%;\n    max-width: 100%;\n    height: auto\n}\n\n.users-list > li > a:hover, .users-list > li > a:hover .users-list-name {\n    color: #999\n}\n\n.users-list-name, .users-list-date {\n    display: block\n}\n\n.users-list-name {\n    font-weight: 600;\n    color: #444;\n    overflow: hidden;\n    white-space: nowrap;\n    text-overflow: ellipsis\n}\n\n.users-list-date {\n    color: #999;\n    font-size: 12px\n}\n\n.carousel-control.left, .carousel-control.right {\n    background-image: none\n}\n\n.carousel-control > .fa {\n    font-size: 40px;\n    position: absolute;\n    top: 50%;\n    z-index: 5;\n    display: inline-block;\n    margin-top: -20px\n}\n\n.modal {\n    background: rgba(0, 0, 0, 0.3)\n}\n\n.modal-content {\n    border-radius: 0;\n    -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125);\n    box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125);\n    border: 0\n}\n\n@media (min-width: 768px) {\n    .modal-content {\n        -webkit-box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125);\n        box-shadow: 0 2px 3px rgba(0, 0, 0, 0.125)\n    }\n}\n\n.modal-header {\n    border-bottom-color: #f4f4f4\n}\n\n.modal-footer {\n    border-top-color: #f4f4f4\n}\n\n.modal-primary .modal-header, .modal-primary .modal-footer {\n    border-color: #307095\n}\n\n.modal-warning .modal-header, .modal-warning .modal-footer {\n    border-color: #c87f0a\n}\n\n.modal-info .modal-header, .modal-info .modal-footer {\n    border-color: #0097bc\n}\n\n.modal-success .modal-header, .modal-success .modal-footer {\n    border-color: #00733e\n}\n\n.modal-danger .modal-header, .modal-danger .modal-footer {\n    border-color: #c23321\n}\n\n.box-widget {\n    border: none;\n    position: relative\n}\n\n.widget-user .widget-user-header {\n    padding: 20px;\n    height: 120px;\n    border-top-right-radius: 3px;\n    border-top-left-radius: 3px\n}\n\n.widget-user .widget-user-username {\n    margin-top: 0;\n    margin-bottom: 5px;\n    font-size: 25px;\n    font-weight: 300;\n    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2)\n}\n\n.widget-user .widget-user-desc {\n    margin-top: 0\n}\n\n.widget-user .widget-user-image {\n    position: absolute;\n    top: 65px;\n    left: 50%;\n    margin-left: -45px\n}\n\n.widget-user .widget-user-image > img {\n    width: 90px;\n    height: auto;\n    border: 3px solid #fff\n}\n\n.widget-user .box-footer {\n    padding-top: 30px\n}\n\n.widget-user-2 .widget-user-header {\n    padding: 20px;\n    border-top-right-radius: 3px;\n    border-top-left-radius: 3px\n}\n\n.widget-user-2 .widget-user-username {\n    margin-top: 5px;\n    margin-bottom: 5px;\n    font-size: 25px;\n    font-weight: 300\n}\n\n.widget-user-2 .widget-user-desc {\n    margin-top: 0\n}\n\n.widget-user-2 .widget-user-username, .widget-user-2 .widget-user-desc {\n    margin-left: 75px\n}\n\n.widget-user-2 .widget-user-image > img {\n    width: 65px;\n    height: auto;\n    float: left\n}\n\n.mailbox-messages > .table {\n    margin: 0\n}\n\n.mailbox-controls {\n    padding: 5px\n}\n\n.mailbox-controls.with-border {\n    border-bottom: 1px solid #f4f4f4\n}\n\n.mailbox-read-info {\n    border-bottom: 1px solid #f4f4f4;\n    padding: 10px\n}\n\n.mailbox-read-info h3 {\n    font-size: 20px;\n    margin: 0\n}\n\n.mailbox-read-info h5 {\n    margin: 0;\n    padding: 5px 0 0 0\n}\n\n.mailbox-read-time {\n    color: #999;\n    font-size: 13px\n}\n\n.mailbox-read-message {\n    padding: 10px\n}\n\n.mailbox-attachments li {\n    float: left;\n    width: 200px;\n    border: 1px solid #eee;\n    margin-bottom: 10px;\n    margin-right: 10px\n}\n\n.mailbox-attachment-name {\n    font-weight: bold;\n    color: #666\n}\n\n.mailbox-attachment-icon, .mailbox-attachment-info, .mailbox-attachment-size {\n    display: block\n}\n\n.mailbox-attachment-info {\n    padding: 10px;\n    background: #f4f4f4\n}\n\n.mailbox-attachment-size {\n    color: #999;\n    font-size: 12px\n}\n\n.mailbox-attachment-icon {\n    text-align: center;\n    font-size: 65px;\n    color: #666;\n    padding: 20px 10px\n}\n\n.mailbox-attachment-icon.has-img {\n    padding: 0\n}\n\n.mailbox-attachment-icon.has-img > img {\n    max-width: 100%;\n    height: auto\n}\n\n.lockscreen {\n    background: #d2d6de\n}\n\n.lockscreen-logo {\n    font-size: 35px;\n    text-align: center;\n    margin-bottom: 25px;\n    font-weight: 300\n}\n\n.lockscreen-logo a {\n    color: #444\n}\n\n.lockscreen-wrapper {\n    max-width: 400px;\n    margin: 0 auto;\n    margin-top: 10%\n}\n\n.lockscreen .lockscreen-name {\n    text-align: center;\n    font-weight: 600\n}\n\n.lockscreen-item {\n    border-radius: 4px;\n    padding: 0;\n    background: #fff;\n    position: relative;\n    margin: 10px auto 30px auto;\n    width: 290px\n}\n\n.lockscreen-image {\n    border-radius: 50%;\n    position: absolute;\n    left: -10px;\n    top: -25px;\n    background: #fff;\n    padding: 5px;\n    z-index: 10\n}\n\n.lockscreen-image > img {\n    border-radius: 50%;\n    width: 70px;\n    height: 70px\n}\n\n.lockscreen-credentials {\n    margin-left: 70px\n}\n\n.lockscreen-credentials .form-control {\n    border: 0\n}\n\n.lockscreen-credentials .btn {\n    background-color: #fff;\n    border: 0;\n    padding: 0 10px\n}\n\n.lockscreen-footer {\n    margin-top: 10px\n}\n\n.login-logo, .register-logo {\n    font-size: 35px;\n    text-align: center;\n    margin-bottom: 25px;\n    font-weight: 300\n}\n\n.login-logo a, .register-logo a {\n    color: #444\n}\n\n.login-page, .register-page {\n    background: #d2d6de\n}\n\n.login-box, .register-box {\n    width: 360px;\n    margin: 7% auto\n}\n\n@media (max-width: 768px) {\n    .login-box, .register-box {\n        width: 90%;\n        margin-top: 20px\n    }\n}\n\n.login-box-body, .register-box-body {\n    background-color: rgba(255, 255, 255, 0.75);\n    border-radius: 3px;\n    box-shadow: 0 0 50px rgba(0, 0, 0, 0.2);\n    padding: 20px;\n    border-top: 0;\n    color: #666\n}\n\n.login-box-body .form-control-feedback, .register-box-body .form-control-feedback {\n    color: #777\n}\n\n.login-box-msg, .register-box-msg {\n    margin: 0;\n    text-align: center;\n    padding: 0 20px 20px 20px\n}\n\n.social-auth-links {\n    margin: 10px 0\n}\n\n.error-page {\n    width: 600px;\n    margin: 20px auto 0 auto\n}\n\n@media (max-width: 991px) {\n    .error-page {\n        width: 100%\n    }\n}\n\n.error-page > .headline {\n    float: left;\n    font-size: 100px;\n    font-weight: 300\n}\n\n@media (max-width: 991px) {\n    .error-page > .headline {\n        float: none;\n        text-align: center\n    }\n}\n\n.error-page > .error-content {\n    margin-left: 190px;\n    display: block\n}\n\n@media (max-width: 991px) {\n    .error-page > .error-content {\n        margin-left: 0\n    }\n}\n\n.error-page > .error-content > h3 {\n    font-weight: 300;\n    font-size: 25px\n}\n\n@media (max-width: 991px) {\n    .error-page > .error-content > h3 {\n        text-align: center\n    }\n}\n\n.invoice {\n    position: relative;\n    background: #fff;\n    border: 1px solid #f4f4f4;\n    padding: 20px;\n    margin: 10px 25px\n}\n\n.invoice-title {\n    margin-top: 0\n}\n\n.profile-user-img {\n    margin: 0 auto;\n    width: 100px;\n    padding: 3px;\n    border: 3px solid #d2d6de\n}\n\n.profile-username {\n    font-size: 21px;\n    margin-top: 5px\n}\n\n.post {\n    border-bottom: 1px solid #d2d6de;\n    margin-bottom: 15px;\n    padding-bottom: 15px;\n    color: #666\n}\n\n.post:last-of-type {\n    border-bottom: 0;\n    margin-bottom: 0;\n    padding-bottom: 0\n}\n\n.post .user-block {\n    margin-bottom: 15px\n}\n\n.btn-social {\n    position: relative;\n    padding-left: 44px;\n    text-align: left;\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis\n}\n\n.btn-social > :first-child {\n    position: absolute;\n    left: 0;\n    top: 0;\n    bottom: 0;\n    width: 32px;\n    line-height: 34px;\n    font-size: 1.6em;\n    text-align: center;\n    border-right: 1px solid rgba(0, 0, 0, 0.2)\n}\n\n.btn-social.btn-lg {\n    padding-left: 61px\n}\n\n.btn-social.btn-lg > :first-child {\n    line-height: 45px;\n    width: 45px;\n    font-size: 1.8em\n}\n\n.btn-social.btn-sm {\n    padding-left: 38px\n}\n\n.btn-social.btn-sm > :first-child {\n    line-height: 28px;\n    width: 28px;\n    font-size: 1.4em\n}\n\n.btn-social.btn-xs {\n    padding-left: 30px\n}\n\n.btn-social.btn-xs > :first-child {\n    line-height: 20px;\n    width: 20px;\n    font-size: 1.2em\n}\n\n.btn-social-icon {\n    position: relative;\n    padding-left: 44px;\n    text-align: left;\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis;\n    height: 34px;\n    width: 34px;\n    padding: 0\n}\n\n.btn-social-icon > :first-child {\n    position: absolute;\n    left: 0;\n    top: 0;\n    bottom: 0;\n    width: 32px;\n    line-height: 34px;\n    font-size: 1.6em;\n    text-align: center;\n    border-right: 1px solid rgba(0, 0, 0, 0.2)\n}\n\n.btn-social-icon.btn-lg {\n    padding-left: 61px\n}\n\n.btn-social-icon.btn-lg > :first-child {\n    line-height: 45px;\n    width: 45px;\n    font-size: 1.8em\n}\n\n.btn-social-icon.btn-sm {\n    padding-left: 38px\n}\n\n.btn-social-icon.btn-sm > :first-child {\n    line-height: 28px;\n    width: 28px;\n    font-size: 1.4em\n}\n\n.btn-social-icon.btn-xs {\n    padding-left: 30px\n}\n\n.btn-social-icon.btn-xs > :first-child {\n    line-height: 20px;\n    width: 20px;\n    font-size: 1.2em\n}\n\n.btn-social-icon > :first-child {\n    border: none;\n    text-align: center;\n    width: 100%\n}\n\n.btn-social-icon.btn-lg {\n    height: 45px;\n    width: 45px;\n    padding-left: 0;\n    padding-right: 0\n}\n\n.btn-social-icon.btn-sm {\n    height: 30px;\n    width: 30px;\n    padding-left: 0;\n    padding-right: 0\n}\n\n.btn-social-icon.btn-xs {\n    height: 22px;\n    width: 22px;\n    padding-left: 0;\n    padding-right: 0\n}\n\n.btn-adn {\n    color: #fff;\n    background-color: #d87a68;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-adn:hover, .btn-adn:focus, .btn-adn.focus, .btn-adn:active, .btn-adn.active, .open > .dropdown-toggle.btn-adn {\n    color: #fff;\n    background-color: #ce563f;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-adn:active, .btn-adn.active, .open > .dropdown-toggle.btn-adn {\n    background-image: none\n}\n\n.btn-adn .badge {\n    color: #d87a68;\n    background-color: #fff\n}\n\n.btn-bitbucket {\n    color: #fff;\n    background-color: #205081;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-bitbucket:hover, .btn-bitbucket:focus, .btn-bitbucket.focus, .btn-bitbucket:active, .btn-bitbucket.active, .open > .dropdown-toggle.btn-bitbucket {\n    color: #fff;\n    background-color: #163758;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-bitbucket:active, .btn-bitbucket.active, .open > .dropdown-toggle.btn-bitbucket {\n    background-image: none\n}\n\n.btn-bitbucket .badge {\n    color: #205081;\n    background-color: #fff\n}\n\n.btn-dropbox {\n    color: #fff;\n    background-color: #1087dd;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-dropbox:hover, .btn-dropbox:focus, .btn-dropbox.focus, .btn-dropbox:active, .btn-dropbox.active, .open > .dropdown-toggle.btn-dropbox {\n    color: #fff;\n    background-color: #0d6aad;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-dropbox:active, .btn-dropbox.active, .open > .dropdown-toggle.btn-dropbox {\n    background-image: none\n}\n\n.btn-dropbox .badge {\n    color: #1087dd;\n    background-color: #fff\n}\n\n.btn-facebook {\n    color: #fff;\n    background-color: #3b5998;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-facebook:hover, .btn-facebook:focus, .btn-facebook.focus, .btn-facebook:active, .btn-facebook.active, .open > .dropdown-toggle.btn-facebook {\n    color: #fff;\n    background-color: #2d4373;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-facebook:active, .btn-facebook.active, .open > .dropdown-toggle.btn-facebook {\n    background-image: none\n}\n\n.btn-facebook .badge {\n    color: #3b5998;\n    background-color: #fff\n}\n\n.btn-flickr {\n    color: #fff;\n    background-color: #ff0084;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-flickr:hover, .btn-flickr:focus, .btn-flickr.focus, .btn-flickr:active, .btn-flickr.active, .open > .dropdown-toggle.btn-flickr {\n    color: #fff;\n    background-color: #cc006a;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-flickr:active, .btn-flickr.active, .open > .dropdown-toggle.btn-flickr {\n    background-image: none\n}\n\n.btn-flickr .badge {\n    color: #ff0084;\n    background-color: #fff\n}\n\n.btn-foursquare {\n    color: #fff;\n    background-color: #f94877;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-foursquare:hover, .btn-foursquare:focus, .btn-foursquare.focus, .btn-foursquare:active, .btn-foursquare.active, .open > .dropdown-toggle.btn-foursquare {\n    color: #fff;\n    background-color: #f71752;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-foursquare:active, .btn-foursquare.active, .open > .dropdown-toggle.btn-foursquare {\n    background-image: none\n}\n\n.btn-foursquare .badge {\n    color: #f94877;\n    background-color: #fff\n}\n\n.btn-github {\n    color: #fff;\n    background-color: #444;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-github:hover, .btn-github:focus, .btn-github.focus, .btn-github:active, .btn-github.active, .open > .dropdown-toggle.btn-github {\n    color: #fff;\n    background-color: #2b2b2b;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-github:active, .btn-github.active, .open > .dropdown-toggle.btn-github {\n    background-image: none\n}\n\n.btn-github .badge {\n    color: #444;\n    background-color: #fff\n}\n\n.btn-google {\n    color: #fff;\n    background-color: #dd4b39;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-google:hover, .btn-google:focus, .btn-google.focus, .btn-google:active, .btn-google.active, .open > .dropdown-toggle.btn-google {\n    color: #fff;\n    background-color: #c23321;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-google:active, .btn-google.active, .open > .dropdown-toggle.btn-google {\n    background-image: none\n}\n\n.btn-google .badge {\n    color: #dd4b39;\n    background-color: #fff\n}\n\n.btn-instagram {\n    color: #fff;\n    background-color: #3f729b;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-instagram:hover, .btn-instagram:focus, .btn-instagram.focus, .btn-instagram:active, .btn-instagram.active, .open > .dropdown-toggle.btn-instagram {\n    color: #fff;\n    background-color: #305777;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-instagram:active, .btn-instagram.active, .open > .dropdown-toggle.btn-instagram {\n    background-image: none\n}\n\n.btn-instagram .badge {\n    color: #3f729b;\n    background-color: #fff\n}\n\n.btn-linkedin {\n    color: #fff;\n    background-color: #007bb6;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-linkedin:hover, .btn-linkedin:focus, .btn-linkedin.focus, .btn-linkedin:active, .btn-linkedin.active, .open > .dropdown-toggle.btn-linkedin {\n    color: #fff;\n    background-color: #005983;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-linkedin:active, .btn-linkedin.active, .open > .dropdown-toggle.btn-linkedin {\n    background-image: none\n}\n\n.btn-linkedin .badge {\n    color: #007bb6;\n    background-color: #fff\n}\n\n.btn-microsoft {\n    color: #fff;\n    background-color: #2672ec;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-microsoft:hover, .btn-microsoft:focus, .btn-microsoft.focus, .btn-microsoft:active, .btn-microsoft.active, .open > .dropdown-toggle.btn-microsoft {\n    color: #fff;\n    background-color: #125acd;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-microsoft:active, .btn-microsoft.active, .open > .dropdown-toggle.btn-microsoft {\n    background-image: none\n}\n\n.btn-microsoft .badge {\n    color: #2672ec;\n    background-color: #fff\n}\n\n.btn-openid {\n    color: #fff;\n    background-color: #f7931e;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-openid:hover, .btn-openid:focus, .btn-openid.focus, .btn-openid:active, .btn-openid.active, .open > .dropdown-toggle.btn-openid {\n    color: #fff;\n    background-color: #da7908;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-openid:active, .btn-openid.active, .open > .dropdown-toggle.btn-openid {\n    background-image: none\n}\n\n.btn-openid .badge {\n    color: #f7931e;\n    background-color: #fff\n}\n\n.btn-pinterest {\n    color: #fff;\n    background-color: #cb2027;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-pinterest:hover, .btn-pinterest:focus, .btn-pinterest.focus, .btn-pinterest:active, .btn-pinterest.active, .open > .dropdown-toggle.btn-pinterest {\n    color: #fff;\n    background-color: #9f191f;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-pinterest:active, .btn-pinterest.active, .open > .dropdown-toggle.btn-pinterest {\n    background-image: none\n}\n\n.btn-pinterest .badge {\n    color: #cb2027;\n    background-color: #fff\n}\n\n.btn-reddit {\n    color: #000;\n    background-color: #eff7ff;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-reddit:hover, .btn-reddit:focus, .btn-reddit.focus, .btn-reddit:active, .btn-reddit.active, .open > .dropdown-toggle.btn-reddit {\n    color: #000;\n    background-color: #bcddff;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-reddit:active, .btn-reddit.active, .open > .dropdown-toggle.btn-reddit {\n    background-image: none\n}\n\n.btn-reddit .badge {\n    color: #eff7ff;\n    background-color: #000\n}\n\n.btn-soundcloud {\n    color: #fff;\n    background-color: #f50;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-soundcloud:hover, .btn-soundcloud:focus, .btn-soundcloud.focus, .btn-soundcloud:active, .btn-soundcloud.active, .open > .dropdown-toggle.btn-soundcloud {\n    color: #fff;\n    background-color: #c40;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-soundcloud:active, .btn-soundcloud.active, .open > .dropdown-toggle.btn-soundcloud {\n    background-image: none\n}\n\n.btn-soundcloud .badge {\n    color: #f50;\n    background-color: #fff\n}\n\n.btn-tumblr {\n    color: #fff;\n    background-color: #2c4762;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-tumblr:hover, .btn-tumblr:focus, .btn-tumblr.focus, .btn-tumblr:active, .btn-tumblr.active, .open > .dropdown-toggle.btn-tumblr {\n    color: #fff;\n    background-color: #1c2d3f;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-tumblr:active, .btn-tumblr.active, .open > .dropdown-toggle.btn-tumblr {\n    background-image: none\n}\n\n.btn-tumblr .badge {\n    color: #2c4762;\n    background-color: #fff\n}\n\n.btn-twitter {\n    color: #fff;\n    background-color: #55acee;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-twitter:hover, .btn-twitter:focus, .btn-twitter.focus, .btn-twitter:active, .btn-twitter.active, .open > .dropdown-toggle.btn-twitter {\n    color: #fff;\n    background-color: #2795e9;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-twitter:active, .btn-twitter.active, .open > .dropdown-toggle.btn-twitter {\n    background-image: none\n}\n\n.btn-twitter .badge {\n    color: #55acee;\n    background-color: #fff\n}\n\n.btn-vimeo {\n    color: #fff;\n    background-color: #1ab7ea;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-vimeo:hover, .btn-vimeo:focus, .btn-vimeo.focus, .btn-vimeo:active, .btn-vimeo.active, .open > .dropdown-toggle.btn-vimeo {\n    color: #fff;\n    background-color: #1295bf;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-vimeo:active, .btn-vimeo.active, .open > .dropdown-toggle.btn-vimeo {\n    background-image: none\n}\n\n.btn-vimeo .badge {\n    color: #1ab7ea;\n    background-color: #fff\n}\n\n.btn-vk {\n    color: #fff;\n    background-color: #587ea3;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-vk:hover, .btn-vk:focus, .btn-vk.focus, .btn-vk:active, .btn-vk.active, .open > .dropdown-toggle.btn-vk {\n    color: #fff;\n    background-color: #466482;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-vk:active, .btn-vk.active, .open > .dropdown-toggle.btn-vk {\n    background-image: none\n}\n\n.btn-vk .badge {\n    color: #587ea3;\n    background-color: #fff\n}\n\n.btn-yahoo {\n    color: #fff;\n    background-color: #720e9e;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-yahoo:hover, .btn-yahoo:focus, .btn-yahoo.focus, .btn-yahoo:active, .btn-yahoo.active, .open > .dropdown-toggle.btn-yahoo {\n    color: #fff;\n    background-color: #500a6f;\n    border-color: rgba(0, 0, 0, 0.2)\n}\n\n.btn-yahoo:active, .btn-yahoo.active, .open > .dropdown-toggle.btn-yahoo {\n    background-image: none\n}\n\n.btn-yahoo .badge {\n    color: #720e9e;\n    background-color: #fff\n}\n\n.fc-button {\n    background: #f4f4f4;\n    background-image: none;\n    color: #444;\n    border-color: #ddd;\n    border-bottom-color: #ddd\n}\n\n.fc-button:hover, .fc-button:active, .fc-button.hover {\n    background-color: #e9e9e9\n}\n\n.fc-header-title h2 {\n    font-size: 15px;\n    line-height: 1.6em;\n    color: #666;\n    margin-left: 10px\n}\n\n.fc-header-right {\n    padding-right: 10px\n}\n\n.fc-header-left {\n    padding-left: 10px\n}\n\n.fc-widget-header {\n    background: #fafafa\n}\n\n.fc-grid {\n    width: 100%;\n    border: 0\n}\n\n.fc-widget-header:first-of-type, .fc-widget-content:first-of-type {\n    border-left: 0;\n    border-right: 0\n}\n\n.fc-widget-header:last-of-type, .fc-widget-content:last-of-type {\n    border-right: 0\n}\n\n.fc-toolbar {\n    padding: 10px;\n    margin: 0\n}\n\n.fc-day-number {\n    font-size: 20px;\n    font-weight: 300;\n    padding-right: 10px\n}\n\n.fc-color-picker {\n    list-style: none;\n    margin: 0;\n    padding: 0\n}\n\n.fc-color-picker > li {\n    float: left;\n    font-size: 30px;\n    margin-right: 5px;\n    line-height: 30px\n}\n\n.fc-color-picker > li .fa {\n    -webkit-transition: -webkit-transform linear .3s;\n    -moz-transition: -moz-transform linear .3s;\n    -o-transition: -o-transform linear .3s;\n    transition: transform linear .3s\n}\n\n.fc-color-picker > li .fa:hover {\n    -webkit-transform: rotate(30deg);\n    -ms-transform: rotate(30deg);\n    -o-transform: rotate(30deg);\n    transform: rotate(30deg)\n}\n\n#add-new-event {\n    -webkit-transition: all linear .3s;\n    -o-transition: all linear .3s;\n    transition: all linear .3s\n}\n\n.external-event {\n    padding: 5px 10px;\n    font-weight: bold;\n    margin-bottom: 4px;\n    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\n    border-radius: 3px;\n    cursor: move\n}\n\n.external-event:hover {\n    box-shadow: inset 0 0 90px rgba(0, 0, 0, 0.2)\n}\n\n.select2-container--default.select2-container--focus, .select2-selection.select2-container--focus, .select2-container--default:focus, .select2-selection:focus, .select2-container--default:active, .select2-selection:active {\n    outline: none\n}\n\n.select2-container--default .select2-selection--single, .select2-selection .select2-selection--single {\n    border: 1px solid #d2d6de;\n    border-radius: 0;\n    padding: 6px 12px;\n    height: 34px\n}\n\n.select2-container--default.select2-container--open {\n    border-color: #3c8dbc\n}\n\n.select2-dropdown {\n    border: 1px solid #d2d6de;\n    border-radius: 0\n}\n\n.select2-container--default .select2-results__option--highlighted[aria-selected] {\n    background-color: #3c8dbc;\n    color: white\n}\n\n.select2-results__option {\n    padding: 6px 12px;\n    user-select: none;\n    -webkit-user-select: none\n}\n\n.select2-container .select2-selection--single .select2-selection__rendered {\n    padding-left: 0;\n    padding-right: 0;\n    height: auto;\n    margin-top: -4px\n}\n\n.select2-container[dir=\"rtl\"] .select2-selection--single .select2-selection__rendered {\n    padding-right: 6px;\n    padding-left: 20px\n}\n\n.select2-container--default .select2-selection--single .select2-selection__arrow {\n    height: 28px;\n    right: 3px\n}\n\n.select2-container--default .select2-selection--single .select2-selection__arrow b {\n    margin-top: 0\n}\n\n.select2-dropdown .select2-search__field, .select2-search--inline .select2-search__field {\n    border: 1px solid #d2d6de\n}\n\n.select2-dropdown .select2-search__field:focus, .select2-search--inline .select2-search__field:focus {\n    outline: none;\n    border: 1px solid #3c8dbc\n}\n\n.select2-container--default .select2-results__option[aria-disabled=true] {\n    color: #999\n}\n\n.select2-container--default .select2-results__option[aria-selected=true] {\n    background-color: #ddd\n}\n\n.select2-container--default .select2-results__option[aria-selected=true], .select2-container--default .select2-results__option[aria-selected=true]:hover {\n    color: #444\n}\n\n.select2-container--default .select2-selection--multiple {\n    border: 1px solid #d2d6de;\n    border-radius: 0\n}\n\n.select2-container--default .select2-selection--multiple:focus {\n    border-color: #3c8dbc\n}\n\n.select2-container--default.select2-container--focus .select2-selection--multiple {\n    border-color: #d2d6de\n}\n\n.select2-container--default .select2-selection--multiple .select2-selection__choice {\n    background-color: #3c8dbc;\n    border-color: #367fa9;\n    padding: 1px 10px;\n    color: #fff\n}\n\n.select2-container--default .select2-selection--multiple .select2-selection__choice__remove {\n    margin-right: 5px;\n    color: rgba(255, 255, 255, 0.7)\n}\n\n.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {\n    color: #fff\n}\n\n.select2-container .select2-selection--single .select2-selection__rendered {\n    padding-right: 10px\n}\n\n.pad {\n    padding: 10px\n}\n\n.margin {\n    margin: 10px\n}\n\n.margin-bottom {\n    margin-bottom: 20px\n}\n\n.margin-bottom-none {\n    margin-bottom: 0\n}\n\n.margin-r-5 {\n    margin-right: 5px\n}\n\n.inline {\n    display: inline\n}\n\n.description-block {\n    display: block;\n    margin: 10px 0;\n    text-align: center\n}\n\n.description-block.margin-bottom {\n    margin-bottom: 25px\n}\n\n.description-block > .description-header {\n    margin: 0;\n    padding: 0;\n    font-weight: 600;\n    font-size: 16px\n}\n\n.description-block > .description-text {\n    text-transform: uppercase\n}\n\n.bg-red, .bg-yellow, .bg-aqua, .bg-blue, .bg-light-blue, .bg-green, .bg-navy, .bg-teal, .bg-olive, .bg-lime, .bg-orange, .bg-fuchsia, .bg-purple, .bg-maroon, .bg-black, .bg-red-active, .bg-yellow-active, .bg-aqua-active, .bg-blue-active, .bg-light-blue-active, .bg-green-active, .bg-navy-active, .bg-teal-active, .bg-olive-active, .bg-lime-active, .bg-orange-active, .bg-fuchsia-active, .bg-purple-active, .bg-maroon-active, .bg-black-active, .callout.callout-danger, .callout.callout-warning, .callout.callout-info, .callout.callout-success, .alert-success, .alert-danger, .alert-error, .alert-warning, .alert-info, .label-danger, .label-info, .label-warning, .label-primary, .label-success, .modal-primary .modal-body, .modal-primary .modal-header, .modal-primary .modal-footer, .modal-warning .modal-body, .modal-warning .modal-header, .modal-warning .modal-footer, .modal-info .modal-body, .modal-info .modal-header, .modal-info .modal-footer, .modal-success .modal-body, .modal-success .modal-header, .modal-success .modal-footer, .modal-danger .modal-body, .modal-danger .modal-header, .modal-danger .modal-footer {\n    color: #fff !important\n}\n\n.bg-gray {\n    color: #000;\n    background-color: #d2d6de !important\n}\n\n.bg-gray-light {\n    background-color: #f7f7f7\n}\n\n.bg-black {\n    background-color: #111 !important\n}\n\n.bg-red, .callout.callout-danger, .alert-danger, .alert-error, .label-danger, .modal-danger .modal-body {\n    background-color: #dd4b39 !important\n}\n\n.bg-yellow, .callout.callout-warning, .alert-warning, .label-warning, .modal-warning .modal-body {\n    background-color: #f39c12 !important\n}\n\n.bg-aqua, .callout.callout-info, .alert-info, .label-info, .modal-info .modal-body {\n    background-color: #00c0ef !important\n}\n\n.bg-blue {\n    background-color: #0073b7 !important\n}\n\n.bg-light-blue, .label-primary, .modal-primary .modal-body {\n    background-color: #3c8dbc !important\n}\n\n.bg-green, .callout.callout-success, .alert-success, .label-success, .modal-success .modal-body {\n    background-color: #00a65a !important\n}\n\n.bg-navy {\n    background-color: #001f3f !important\n}\n\n.bg-teal {\n    background-color: #39cccc !important\n}\n\n.bg-olive {\n    background-color: #3d9970 !important\n}\n\n.bg-lime {\n    background-color: #01ff70 !important\n}\n\n.bg-orange {\n    background-color: #ff851b !important\n}\n\n.bg-fuchsia {\n    background-color: #f012be !important\n}\n\n.bg-purple {\n    background-color: #605ca8 !important\n}\n\n.bg-maroon {\n    background-color: #d81b60 !important\n}\n\n.bg-gray-active {\n    color: #000;\n    background-color: #b5bbc8 !important\n}\n\n.bg-black-active {\n    background-color: #000 !important\n}\n\n.bg-red-active, .modal-danger .modal-header, .modal-danger .modal-footer {\n    background-color: #d33724 !important\n}\n\n.bg-yellow-active, .modal-warning .modal-header, .modal-warning .modal-footer {\n    background-color: #db8b0b !important\n}\n\n.bg-aqua-active, .modal-info .modal-header, .modal-info .modal-footer {\n    background-color: #00a7d0 !important\n}\n\n.bg-blue-active {\n    background-color: #005384 !important\n}\n\n.bg-light-blue-active, .modal-primary .modal-header, .modal-primary .modal-footer {\n    background-color: #357ca5 !important\n}\n\n.bg-green-active, .modal-success .modal-header, .modal-success .modal-footer {\n    background-color: #008d4c !important\n}\n\n.bg-navy-active {\n    background-color: #001a35 !important\n}\n\n.bg-teal-active {\n    background-color: #30bbbb !important\n}\n\n.bg-olive-active {\n    background-color: #368763 !important\n}\n\n.bg-lime-active {\n    background-color: #00e765 !important\n}\n\n.bg-orange-active {\n    background-color: #ff7701 !important\n}\n\n.bg-fuchsia-active {\n    background-color: #db0ead !important\n}\n\n.bg-purple-active {\n    background-color: #555299 !important\n}\n\n.bg-maroon-active {\n    background-color: #ca195a !important\n}\n\n[class^=\"bg-\"].disabled {\n    opacity: .65;\n    filter: alpha(opacity=65)\n}\n\n.text-red {\n    color: #dd4b39 !important\n}\n\n.text-yellow {\n    color: #f39c12 !important\n}\n\n.text-aqua {\n    color: #00c0ef !important\n}\n\n.text-blue {\n    color: #0073b7 !important\n}\n\n.text-black {\n    color: #111 !important\n}\n\n.text-light-blue {\n    color: #3c8dbc !important\n}\n\n.text-green {\n    color: #00a65a !important\n}\n\n.text-gray {\n    color: #d2d6de !important\n}\n\n.text-navy {\n    color: #001f3f !important\n}\n\n.text-teal {\n    color: #39cccc !important\n}\n\n.text-olive {\n    color: #3d9970 !important\n}\n\n.text-lime {\n    color: #01ff70 !important\n}\n\n.text-orange {\n    color: #ff851b !important\n}\n\n.text-fuchsia {\n    color: #f012be !important\n}\n\n.text-purple {\n    color: #605ca8 !important\n}\n\n.text-maroon {\n    color: #d81b60 !important\n}\n\n.link-muted {\n    color: #7a869d\n}\n\n.link-muted:hover, .link-muted:focus {\n    color: #606c84\n}\n\n.link-black {\n    color: #666\n}\n\n.link-black:hover, .link-black:focus {\n    color: #999\n}\n\n.hide {\n    display: none !important\n}\n\n.no-border {\n    border: 0 !important\n}\n\n.no-padding {\n    padding: 0 !important\n}\n\n.no-margin {\n    margin: 0 !important\n}\n\n.no-shadow {\n    box-shadow: none !important\n}\n\n.list-unstyled, .chart-legend, .contacts-list, .users-list, .mailbox-attachments {\n    list-style: none;\n    margin: 0;\n    padding: 0\n}\n\n.list-group-unbordered > .list-group-item {\n    border-left: 0;\n    border-right: 0;\n    border-radius: 0;\n    padding-left: 0;\n    padding-right: 0\n}\n\n.flat {\n    border-radius: 0 !important\n}\n\n.text-bold, .text-bold.table td, .text-bold.table th {\n    font-weight: 700\n}\n\n.text-sm {\n    font-size: 12px\n}\n\n.jqstooltip {\n    padding: 5px !important;\n    width: auto !important;\n    height: auto !important\n}\n\n.bg-teal-gradient {\n    background: #39cccc !important;\n    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #39cccc), color-stop(1, #7adddd)) !important;\n    background: -ms-linear-gradient(bottom, #39cccc, #7adddd) !important;\n    background: -moz-linear-gradient(center bottom, #39cccc 0, #7adddd 100%) !important;\n    background: -o-linear-gradient(#7adddd, #39cccc) !important;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#7adddd', endColorstr='#39cccc', GradientType=0) !important;\n    color: #fff\n}\n\n.bg-light-blue-gradient {\n    background: #3c8dbc !important;\n    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #3c8dbc), color-stop(1, #67a8ce)) !important;\n    background: -ms-linear-gradient(bottom, #3c8dbc, #67a8ce) !important;\n    background: -moz-linear-gradient(center bottom, #3c8dbc 0, #67a8ce 100%) !important;\n    background: -o-linear-gradient(#67a8ce, #3c8dbc) !important;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#67a8ce', endColorstr='#3c8dbc', GradientType=0) !important;\n    color: #fff\n}\n\n.bg-blue-gradient {\n    background: #0073b7 !important;\n    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #0073b7), color-stop(1, #0089db)) !important;\n    background: -ms-linear-gradient(bottom, #0073b7, #0089db) !important;\n    background: -moz-linear-gradient(center bottom, #0073b7 0, #0089db 100%) !important;\n    background: -o-linear-gradient(#0089db, #0073b7) !important;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0089db', endColorstr='#0073b7', GradientType=0) !important;\n    color: #fff\n}\n\n.bg-aqua-gradient {\n    background: #00c0ef !important;\n    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #00c0ef), color-stop(1, #14d1ff)) !important;\n    background: -ms-linear-gradient(bottom, #00c0ef, #14d1ff) !important;\n    background: -moz-linear-gradient(center bottom, #00c0ef 0, #14d1ff 100%) !important;\n    background: -o-linear-gradient(#14d1ff, #00c0ef) !important;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#14d1ff', endColorstr='#00c0ef', GradientType=0) !important;\n    color: #fff\n}\n\n.bg-yellow-gradient {\n    background: #f39c12 !important;\n    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #f39c12), color-stop(1, #f7bc60)) !important;\n    background: -ms-linear-gradient(bottom, #f39c12, #f7bc60) !important;\n    background: -moz-linear-gradient(center bottom, #f39c12 0, #f7bc60 100%) !important;\n    background: -o-linear-gradient(#f7bc60, #f39c12) !important;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#f7bc60', endColorstr='#f39c12', GradientType=0) !important;\n    color: #fff\n}\n\n.bg-purple-gradient {\n    background: #605ca8 !important;\n    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #605ca8), color-stop(1, #9491c4)) !important;\n    background: -ms-linear-gradient(bottom, #605ca8, #9491c4) !important;\n    background: -moz-linear-gradient(center bottom, #605ca8 0, #9491c4 100%) !important;\n    background: -o-linear-gradient(#9491c4, #605ca8) !important;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#9491c4', endColorstr='#605ca8', GradientType=0) !important;\n    color: #fff\n}\n\n.bg-green-gradient {\n    background: #00a65a !important;\n    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #00a65a), color-stop(1, #00ca6d)) !important;\n    background: -ms-linear-gradient(bottom, #00a65a, #00ca6d) !important;\n    background: -moz-linear-gradient(center bottom, #00a65a 0, #00ca6d 100%) !important;\n    background: -o-linear-gradient(#00ca6d, #00a65a) !important;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00ca6d', endColorstr='#00a65a', GradientType=0) !important;\n    color: #fff\n}\n\n.bg-red-gradient {\n    background: #dd4b39 !important;\n    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #dd4b39), color-stop(1, #e47365)) !important;\n    background: -ms-linear-gradient(bottom, #dd4b39, #e47365) !important;\n    background: -moz-linear-gradient(center bottom, #dd4b39 0, #e47365 100%) !important;\n    background: -o-linear-gradient(#e47365, #dd4b39) !important;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#e47365', endColorstr='#dd4b39', GradientType=0) !important;\n    color: #fff\n}\n\n.bg-black-gradient {\n    background: #111 !important;\n    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #111), color-stop(1, #2b2b2b)) !important;\n    background: -ms-linear-gradient(bottom, #111, #2b2b2b) !important;\n    background: -moz-linear-gradient(center bottom, #111 0, #2b2b2b 100%) !important;\n    background: -o-linear-gradient(#2b2b2b, #111) !important;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#2b2b2b', endColorstr='#111111', GradientType=0) !important;\n    color: #fff\n}\n\n.bg-maroon-gradient {\n    background: #d81b60 !important;\n    background: -webkit-gradient(linear, left bottom, left top, color-stop(0, #d81b60), color-stop(1, #e73f7c)) !important;\n    background: -ms-linear-gradient(bottom, #d81b60, #e73f7c) !important;\n    background: -moz-linear-gradient(center bottom, #d81b60 0, #e73f7c 100%) !important;\n    background: -o-linear-gradient(#e73f7c, #d81b60) !important;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#e73f7c', endColorstr='#d81b60', GradientType=0) !important;\n    color: #fff\n}\n\n.description-block .description-icon {\n    font-size: 16px\n}\n\n.no-pad-top {\n    padding-top: 0\n}\n\n.position-static {\n    position: static !important\n}\n\n.list-header {\n    font-size: 15px;\n    padding: 10px 4px;\n    font-weight: bold;\n    color: #666\n}\n\n.list-seperator {\n    height: 1px;\n    background: #f4f4f4;\n    margin: 15px 0 9px 0\n}\n\n.list-link > a {\n    padding: 4px;\n    color: #777\n}\n\n.list-link > a:hover {\n    color: #222\n}\n\n.font-light {\n    font-weight: 300\n}\n\n.user-block:before, .user-block:after {\n    content: \" \";\n    display: table\n}\n\n.user-block:after {\n    clear: both\n}\n\n.user-block img {\n    width: 40px;\n    height: 40px;\n    float: left\n}\n\n.user-block .username, .user-block .description, .user-block .comment {\n    display: block;\n    margin-left: 50px\n}\n\n.user-block .username {\n    font-size: 16px;\n    font-weight: 600\n}\n\n.user-block .description {\n    color: #999;\n    font-size: 13px\n}\n\n.user-block.user-block-sm .username, .user-block.user-block-sm .description, .user-block.user-block-sm .comment {\n    margin-left: 40px\n}\n\n.user-block.user-block-sm .username {\n    font-size: 14px\n}\n\n.img-sm, .img-md, .img-lg, .box-comments .box-comment img, .user-block.user-block-sm img {\n    float: left\n}\n\n.img-sm, .box-comments .box-comment img, .user-block.user-block-sm img {\n    width: 30px !important;\n    height: 30px !important\n}\n\n.img-sm + .img-push {\n    margin-left: 40px\n}\n\n.img-md {\n    width: 60px;\n    height: 60px\n}\n\n.img-md + .img-push {\n    margin-left: 70px\n}\n\n.img-lg {\n    width: 100px;\n    height: 100px\n}\n\n.img-lg + .img-push {\n    margin-left: 110px\n}\n\n.img-bordered {\n    border: 3px solid #d2d6de;\n    padding: 3px\n}\n\n.img-bordered-sm {\n    border: 2px solid #d2d6de;\n    padding: 2px\n}\n\n.attachment-block {\n    border: 1px solid #f4f4f4;\n    padding: 5px;\n    margin-bottom: 10px;\n    background: #f7f7f7\n}\n\n.attachment-block .attachment-img {\n    max-width: 100px;\n    max-height: 100px;\n    height: auto;\n    float: left\n}\n\n.attachment-block .attachment-pushed {\n    margin-left: 110px\n}\n\n.attachment-block .attachment-heading {\n    margin: 0\n}\n\n.attachment-block .attachment-text {\n    color: #555\n}\n\n.connectedSortable {\n    min-height: 100px\n}\n\n.ui-helper-hidden-accessible {\n    border: 0;\n    clip: rect(0 0 0 0);\n    height: 1px;\n    margin: -1px;\n    overflow: hidden;\n    padding: 0;\n    position: absolute;\n    width: 1px\n}\n\n.sort-highlight {\n    background: #f4f4f4;\n    border: 1px dashed #ddd;\n    margin-bottom: 10px\n}\n\n.full-opacity-hover {\n    opacity: .65;\n    filter: alpha(opacity=65)\n}\n\n.full-opacity-hover:hover {\n    opacity: 1;\n    filter: alpha(opacity=100)\n}\n\n.chart {\n    position: relative;\n    overflow: hidden;\n    width: 100%\n}\n\n.chart svg, .chart canvas {\n    width: 100% !important\n}\n\n@media print {\n    .no-print, .main-sidebar, .left-side, .main-header, .content-header {\n        display: none !important\n    }\n\n    .content-wrapper, .right-side, .main-footer {\n        margin-left: 0 !important;\n        min-height: 0 !important;\n        -webkit-transform: translate(0, 0) !important;\n        -ms-transform: translate(0, 0) !important;\n        -o-transform: translate(0, 0) !important;\n        transform: translate(0, 0) !important\n    }\n\n    .fixed .content-wrapper, .fixed .right-side {\n        padding-top: 0 !important\n    }\n\n    .invoice {\n        width: 100%;\n        border: 0;\n        margin: 0;\n        padding: 0\n    }\n\n    .invoice-col {\n        float: left;\n        width: 33.3333333%\n    }\n\n    .table-responsive {\n        overflow: auto\n    }\n\n    .table-responsive > .table tr th, .table-responsive > .table tr td {\n        white-space: normal !important\n    }\n}\n\n/*new add*/\n.common_footer {\n    color: #eee;\n    position: fixed;\n    bottom: 0px;\n    text-align: center;\n    width: 100%;\n    /*background: #444;*/\n    background: rgba(0, 0, 0, 0.3);\n    padding: 10px;\n}\n\n#loading, #loading .lbk, #loading .lcont {\n    width: 146px;\n    height: 146px;\n}\n\n#loading {\n    position: absolute;\n    left: 50%;\n    top: 60px;\n    z-index: 99;\n    display: none;\n}\n\n#loading .lbk {\n    background-color: #000;\n    opacity: .5;\n    border-radius: 10px;\n    margin: -73px 0 0 -73px;\n    z-index: 0;\n}\n\n#loading .lbk, #loading .lcont {\n    position: relative;\n}\n\n#loading, #loading .lbk, #loading .lcont {\n    width: 146px;\n    height: 146px;\n}\n\n#loading .lcont {\n    margin: -146px 0 0 -73px;\n    text-align: center;\n    color: #f5f5f5;\n    font-size: 14px;\n    line-height: 35px;\n    z-index: 1;\n}\n\n#loading img {\n    width: 35px;\n    height: 35px;\n    margin: 30px auto;\n    display: block;\n}\n\nimg, fieldset {\n    border: none;\n}\n\n#dialog-content .cover {\n    width: 120px;\n    height: 120px;\n    position: absolute;\n    background-size: cover;\n    background: url('../img/choosed.png') no-repeat center center;\n    display: none;\n    margin-top: -120px;\n}\n\n.table-action a {\n    margin-right: 12px;\n}\n\n.edit_pic_mask {\n    text-align: center;\n    position: relative;\n    margin-top: -40px;\n    height: 40px;\n    font-size: 22px;\n    padding-top: 6px;\n    background-color: rgba(229, 229, 229, 0.3);\n}\n\n.edit_pic_mask i {\n    margin-right: 12px;\n    cursor: pointer;\n}\n\n.fileupload-new {\n    margin-right: 12px;\n}\n\n.fileupload-new img {\n    width: 200px;\n    height: 150px;\n}\n\n/*skins*/\n.skin-blue .main-header .navbar {\n    background-color: #3c8dbc\n}\n\n.skin-blue .main-header .navbar .nav > li > a {\n    color: #fff\n}\n\n.skin-blue .main-header .navbar .nav > li > a:hover, .skin-blue .main-header .navbar .nav > li > a:active, .skin-blue .main-header .navbar .nav > li > a:focus, .skin-blue .main-header .navbar .nav .open > a, .skin-blue .main-header .navbar .nav .open > a:hover, .skin-blue .main-header .navbar .nav .open > a:focus, .skin-blue .main-header .navbar .nav > .active > a {\n    background: rgba(0, 0, 0, 0.1);\n    color: #f6f6f6\n}\n\n.skin-blue .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-blue .main-header .navbar .sidebar-toggle:hover {\n    color: #f6f6f6;\n    background: rgba(0, 0, 0, 0.1)\n}\n\n.skin-blue .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-blue .main-header .navbar .sidebar-toggle:hover {\n    background-color: #367fa9\n}\n\n@media (max-width: 767px) {\n    .skin-blue .main-header .navbar .dropdown-menu li.divider {\n        background-color: rgba(255, 255, 255, 0.1)\n    }\n\n    .skin-blue .main-header .navbar .dropdown-menu li a {\n        color: #fff\n    }\n\n    .skin-blue .main-header .navbar .dropdown-menu li a:hover {\n        background: #367fa9\n    }\n}\n\n.skin-blue .main-header .logo {\n    background-color: #367fa9;\n    color: #fff;\n    border-bottom: 0 solid transparent\n}\n\n.skin-blue .main-header .logo:hover {\n    background-color: #357ca5\n}\n\n.skin-blue .main-header li.user-header {\n    background-color: #3c8dbc\n}\n\n.skin-blue .content-header {\n    background: transparent\n}\n\n.skin-blue .wrapper, .skin-blue .main-sidebar, .skin-blue .left-side {\n    background-color: #222d32\n}\n\n.skin-blue .user-panel > .info, .skin-blue .user-panel > .info > a {\n    color: #fff\n}\n\n.skin-blue .sidebar-menu > li.header {\n    color: #4b646f;\n    background: #1a2226\n}\n\n.skin-blue .sidebar-menu > li > a {\n    border-left: 3px solid transparent\n}\n\n.skin-blue .sidebar-menu > li:hover > a, .skin-blue .sidebar-menu > li.active > a {\n    color: #fff;\n    background: #1e282c;\n    border-left-color: #3c8dbc\n}\n\n.skin-blue .sidebar-menu > li > .treeview-menu {\n    margin: 0 1px;\n    background: #2c3b41\n}\n\n.skin-blue .sidebar a {\n    color: #b8c7ce\n}\n\n.skin-blue .sidebar a:hover {\n    text-decoration: none\n}\n\n.skin-blue .treeview-menu > li > a {\n    color: #8aa4af\n}\n\n.skin-blue .treeview-menu > li.active > a, .skin-blue .treeview-menu > li > a:hover {\n    color: #fff\n}\n\n.skin-blue .sidebar-form {\n    border-radius: 3px;\n    border: 1px solid #374850;\n    margin: 10px 10px\n}\n\n.skin-blue .sidebar-form input[type=\"text\"], .skin-blue .sidebar-form .btn {\n    box-shadow: none;\n    background-color: #374850;\n    border: 1px solid transparent;\n    height: 35px;\n    -webkit-transition: all .3s ease-in-out;\n    -o-transition: all .3s ease-in-out;\n    transition: all .3s ease-in-out\n}\n\n.skin-blue .sidebar-form input[type=\"text\"] {\n    color: #666;\n    border-top-left-radius: 2px;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 2px\n}\n\n.skin-blue .sidebar-form input[type=\"text\"]:focus, .skin-blue .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    background-color: #fff;\n    color: #666\n}\n\n.skin-blue .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    border-left-color: #fff\n}\n\n.skin-blue .sidebar-form .btn {\n    color: #999;\n    border-top-left-radius: 0;\n    border-top-right-radius: 2px;\n    border-bottom-right-radius: 2px;\n    border-bottom-left-radius: 0\n}\n\n.skin-blue.layout-top-nav .main-header > .logo {\n    background-color: #3c8dbc;\n    color: #fff;\n    border-bottom: 0 solid transparent\n}\n\n.skin-blue.layout-top-nav .main-header > .logo:hover {\n    background-color: #3b8ab8\n}\n\n.skin-blue-light .main-header .navbar {\n    background-color: #3c8dbc\n}\n\n.skin-blue-light .main-header .navbar .nav > li > a {\n    color: #fff\n}\n\n.skin-blue-light .main-header .navbar .nav > li > a:hover, .skin-blue-light .main-header .navbar .nav > li > a:active, .skin-blue-light .main-header .navbar .nav > li > a:focus, .skin-blue-light .main-header .navbar .nav .open > a, .skin-blue-light .main-header .navbar .nav .open > a:hover, .skin-blue-light .main-header .navbar .nav .open > a:focus, .skin-blue-light .main-header .navbar .nav > .active > a {\n    background: rgba(0, 0, 0, 0.1);\n    color: #f6f6f6\n}\n\n.skin-blue-light .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-blue-light .main-header .navbar .sidebar-toggle:hover {\n    color: #f6f6f6;\n    background: rgba(0, 0, 0, 0.1)\n}\n\n.skin-blue-light .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-blue-light .main-header .navbar .sidebar-toggle:hover {\n    background-color: #367fa9\n}\n\n@media (max-width: 767px) {\n    .skin-blue-light .main-header .navbar .dropdown-menu li.divider {\n        background-color: rgba(255, 255, 255, 0.1)\n    }\n\n    .skin-blue-light .main-header .navbar .dropdown-menu li a {\n        color: #fff\n    }\n\n    .skin-blue-light .main-header .navbar .dropdown-menu li a:hover {\n        background: #367fa9\n    }\n}\n\n.skin-blue-light .main-header .logo {\n    background-color: #3c8dbc;\n    color: #fff;\n    border-bottom: 0 solid transparent\n}\n\n.skin-blue-light .main-header .logo:hover {\n    background-color: #3b8ab8\n}\n\n.skin-blue-light .main-header li.user-header {\n    background-color: #3c8dbc\n}\n\n.skin-blue-light .content-header {\n    background: transparent\n}\n\n.skin-blue-light .wrapper, .skin-blue-light .main-sidebar, .skin-blue-light .left-side {\n    background-color: #f9fafc\n}\n\n.skin-blue-light .content-wrapper, .skin-blue-light .main-footer {\n    border-left: 1px solid #d2d6de\n}\n\n.skin-blue-light .user-panel > .info, .skin-blue-light .user-panel > .info > a {\n    color: #444\n}\n\n.skin-blue-light .sidebar-menu > li {\n    -webkit-transition: border-left-color .3s ease;\n    -o-transition: border-left-color .3s ease;\n    transition: border-left-color .3s ease\n}\n\n.skin-blue-light .sidebar-menu > li.header {\n    color: #848484;\n    background: #f9fafc\n}\n\n.skin-blue-light .sidebar-menu > li > a {\n    border-left: 3px solid transparent;\n    font-weight: 600\n}\n\n.skin-blue-light .sidebar-menu > li:hover > a, .skin-blue-light .sidebar-menu > li.active > a {\n    color: #000;\n    background: #f4f4f5\n}\n\n.skin-blue-light .sidebar-menu > li.active {\n    border-left-color: #3c8dbc\n}\n\n.skin-blue-light .sidebar-menu > li.active > a {\n    font-weight: 600\n}\n\n.skin-blue-light .sidebar-menu > li > .treeview-menu {\n    background: #f4f4f5\n}\n\n.skin-blue-light .sidebar a {\n    color: #444\n}\n\n.skin-blue-light .sidebar a:hover {\n    text-decoration: none\n}\n\n.skin-blue-light .treeview-menu > li > a {\n    color: #777\n}\n\n.skin-blue-light .treeview-menu > li.active > a, .skin-blue-light .treeview-menu > li > a:hover {\n    color: #000\n}\n\n.skin-blue-light .treeview-menu > li.active > a {\n    font-weight: 600\n}\n\n.skin-blue-light .sidebar-form {\n    border-radius: 3px;\n    border: 1px solid #d2d6de;\n    margin: 10px 10px\n}\n\n.skin-blue-light .sidebar-form input[type=\"text\"], .skin-blue-light .sidebar-form .btn {\n    box-shadow: none;\n    background-color: #fff;\n    border: 1px solid transparent;\n    height: 35px;\n    -webkit-transition: all .3s ease-in-out;\n    -o-transition: all .3s ease-in-out;\n    transition: all .3s ease-in-out\n}\n\n.skin-blue-light .sidebar-form input[type=\"text\"] {\n    color: #666;\n    border-top-left-radius: 2px;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 2px\n}\n\n.skin-blue-light .sidebar-form input[type=\"text\"]:focus, .skin-blue-light .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    background-color: #fff;\n    color: #666\n}\n\n.skin-blue-light .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    border-left-color: #fff\n}\n\n.skin-blue-light .sidebar-form .btn {\n    color: #999;\n    border-top-left-radius: 0;\n    border-top-right-radius: 2px;\n    border-bottom-right-radius: 2px;\n    border-bottom-left-radius: 0\n}\n\n@media (min-width: 768px) {\n    .skin-blue-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {\n        border-left: 1px solid #d2d6de\n    }\n}\n\n.skin-blue-light .main-footer {\n    border-top-color: #d2d6de\n}\n\n.skin-blue.layout-top-nav .main-header > .logo {\n    background-color: #3c8dbc;\n    color: #fff;\n    border-bottom: 0 solid transparent\n}\n\n.skin-blue.layout-top-nav .main-header > .logo:hover {\n    background-color: #3b8ab8\n}\n\n.skin-black .main-header {\n    -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05)\n}\n\n.skin-black .main-header .navbar-toggle {\n    color: #333\n}\n\n.skin-black .main-header .navbar-brand {\n    color: #333;\n    border-right: 1px solid #eee\n}\n\n.skin-black .main-header > .navbar {\n    background-color: #fff\n}\n\n.skin-black .main-header > .navbar .nav > li > a {\n    color: #333\n}\n\n.skin-black .main-header > .navbar .nav > li > a:hover, .skin-black .main-header > .navbar .nav > li > a:active, .skin-black .main-header > .navbar .nav > li > a:focus, .skin-black .main-header > .navbar .nav .open > a, .skin-black .main-header > .navbar .nav .open > a:hover, .skin-black .main-header > .navbar .nav .open > a:focus, .skin-black .main-header > .navbar .nav > .active > a {\n    background: #fff;\n    color: #999\n}\n\n.skin-black .main-header > .navbar .sidebar-toggle {\n    color: #333\n}\n\n.skin-black .main-header > .navbar .sidebar-toggle:hover {\n    color: #999;\n    background: #fff\n}\n\n.skin-black .main-header > .navbar > .sidebar-toggle {\n    color: #333;\n    border-right: 1px solid #eee\n}\n\n.skin-black .main-header > .navbar .navbar-nav > li > a {\n    border-right: 1px solid #eee\n}\n\n.skin-black .main-header > .navbar .navbar-custom-menu .navbar-nav > li > a, .skin-black .main-header > .navbar .navbar-right > li > a {\n    border-left: 1px solid #eee;\n    border-right-width: 0\n}\n\n.skin-black .main-header > .logo {\n    background-color: #fff;\n    color: #333;\n    border-bottom: 0 solid transparent;\n    border-right: 1px solid #eee\n}\n\n.skin-black .main-header > .logo:hover {\n    background-color: #fcfcfc\n}\n\n@media (max-width: 767px) {\n    .skin-black .main-header > .logo {\n        background-color: #222;\n        color: #fff;\n        border-bottom: 0 solid transparent;\n        border-right: none\n    }\n\n    .skin-black .main-header > .logo:hover {\n        background-color: #1f1f1f\n    }\n}\n\n.skin-black .main-header li.user-header {\n    background-color: #222\n}\n\n.skin-black .content-header {\n    background: transparent;\n    box-shadow: none\n}\n\n.skin-black .wrapper, .skin-black .main-sidebar, .skin-black .left-side {\n    background-color: #222d32\n}\n\n.skin-black .user-panel > .info, .skin-black .user-panel > .info > a {\n    color: #fff\n}\n\n.skin-black .sidebar-menu > li.header {\n    color: #4b646f;\n    background: #1a2226\n}\n\n.skin-black .sidebar-menu > li > a {\n    border-left: 3px solid transparent\n}\n\n.skin-black .sidebar-menu > li:hover > a, .skin-black .sidebar-menu > li.active > a {\n    color: #fff;\n    background: #1e282c;\n    border-left-color: #fff\n}\n\n.skin-black .sidebar-menu > li > .treeview-menu {\n    margin: 0 1px;\n    background: #2c3b41\n}\n\n.skin-black .sidebar a {\n    color: #b8c7ce\n}\n\n.skin-black .sidebar a:hover {\n    text-decoration: none\n}\n\n.skin-black .treeview-menu > li > a {\n    color: #8aa4af\n}\n\n.skin-black .treeview-menu > li.active > a, .skin-black .treeview-menu > li > a:hover {\n    color: #fff\n}\n\n.skin-black .sidebar-form {\n    border-radius: 3px;\n    border: 1px solid #374850;\n    margin: 10px 10px\n}\n\n.skin-black .sidebar-form input[type=\"text\"], .skin-black .sidebar-form .btn {\n    box-shadow: none;\n    background-color: #374850;\n    border: 1px solid transparent;\n    height: 35px;\n    -webkit-transition: all .3s ease-in-out;\n    -o-transition: all .3s ease-in-out;\n    transition: all .3s ease-in-out\n}\n\n.skin-black .sidebar-form input[type=\"text\"] {\n    color: #666;\n    border-top-left-radius: 2px;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 2px\n}\n\n.skin-black .sidebar-form input[type=\"text\"]:focus, .skin-black .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    background-color: #fff;\n    color: #666\n}\n\n.skin-black .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    border-left-color: #fff\n}\n\n.skin-black .sidebar-form .btn {\n    color: #999;\n    border-top-left-radius: 0;\n    border-top-right-radius: 2px;\n    border-bottom-right-radius: 2px;\n    border-bottom-left-radius: 0\n}\n\n.skin-black-light .main-header {\n    -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05);\n    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.05)\n}\n\n.skin-black-light .main-header .navbar-toggle {\n    color: #333\n}\n\n.skin-black-light .main-header .navbar-brand {\n    color: #333;\n    border-right: 1px solid #eee\n}\n\n.skin-black-light .main-header > .navbar {\n    background-color: #fff\n}\n\n.skin-black-light .main-header > .navbar .nav > li > a {\n    color: #333\n}\n\n.skin-black-light .main-header > .navbar .nav > li > a:hover, .skin-black-light .main-header > .navbar .nav > li > a:active, .skin-black-light .main-header > .navbar .nav > li > a:focus, .skin-black-light .main-header > .navbar .nav .open > a, .skin-black-light .main-header > .navbar .nav .open > a:hover, .skin-black-light .main-header > .navbar .nav .open > a:focus, .skin-black-light .main-header > .navbar .nav > .active > a {\n    background: #fff;\n    color: #999\n}\n\n.skin-black-light .main-header > .navbar .sidebar-toggle {\n    color: #333\n}\n\n.skin-black-light .main-header > .navbar .sidebar-toggle:hover {\n    color: #999;\n    background: #fff\n}\n\n.skin-black-light .main-header > .navbar > .sidebar-toggle {\n    color: #333;\n    border-right: 1px solid #eee\n}\n\n.skin-black-light .main-header > .navbar .navbar-nav > li > a {\n    border-right: 1px solid #eee\n}\n\n.skin-black-light .main-header > .navbar .navbar-custom-menu .navbar-nav > li > a, .skin-black-light .main-header > .navbar .navbar-right > li > a {\n    border-left: 1px solid #eee;\n    border-right-width: 0\n}\n\n.skin-black-light .main-header > .logo {\n    background-color: #fff;\n    color: #333;\n    border-bottom: 0 solid transparent;\n    border-right: 1px solid #eee\n}\n\n.skin-black-light .main-header > .logo:hover {\n    background-color: #fcfcfc\n}\n\n@media (max-width: 767px) {\n    .skin-black-light .main-header > .logo {\n        background-color: #222;\n        color: #fff;\n        border-bottom: 0 solid transparent;\n        border-right: none\n    }\n\n    .skin-black-light .main-header > .logo:hover {\n        background-color: #1f1f1f\n    }\n}\n\n.skin-black-light .main-header li.user-header {\n    background-color: #222\n}\n\n.skin-black-light .content-header {\n    background: transparent;\n    box-shadow: none\n}\n\n.skin-black-light .wrapper, .skin-black-light .main-sidebar, .skin-black-light .left-side {\n    background-color: #f9fafc\n}\n\n.skin-black-light .content-wrapper, .skin-black-light .main-footer {\n    border-left: 1px solid #d2d6de\n}\n\n.skin-black-light .user-panel > .info, .skin-black-light .user-panel > .info > a {\n    color: #444\n}\n\n.skin-black-light .sidebar-menu > li {\n    -webkit-transition: border-left-color .3s ease;\n    -o-transition: border-left-color .3s ease;\n    transition: border-left-color .3s ease\n}\n\n.skin-black-light .sidebar-menu > li.header {\n    color: #848484;\n    background: #f9fafc\n}\n\n.skin-black-light .sidebar-menu > li > a {\n    border-left: 3px solid transparent;\n    font-weight: 600\n}\n\n.skin-black-light .sidebar-menu > li:hover > a, .skin-black-light .sidebar-menu > li.active > a {\n    color: #000;\n    background: #f4f4f5\n}\n\n.skin-black-light .sidebar-menu > li.active {\n    border-left-color: #fff\n}\n\n.skin-black-light .sidebar-menu > li.active > a {\n    font-weight: 600\n}\n\n.skin-black-light .sidebar-menu > li > .treeview-menu {\n    background: #f4f4f5\n}\n\n.skin-black-light .sidebar a {\n    color: #444\n}\n\n.skin-black-light .sidebar a:hover {\n    text-decoration: none\n}\n\n.skin-black-light .treeview-menu > li > a {\n    color: #777\n}\n\n.skin-black-light .treeview-menu > li.active > a, .skin-black-light .treeview-menu > li > a:hover {\n    color: #000\n}\n\n.skin-black-light .treeview-menu > li.active > a {\n    font-weight: 600\n}\n\n.skin-black-light .sidebar-form {\n    border-radius: 3px;\n    border: 1px solid #d2d6de;\n    margin: 10px 10px\n}\n\n.skin-black-light .sidebar-form input[type=\"text\"], .skin-black-light .sidebar-form .btn {\n    box-shadow: none;\n    background-color: #fff;\n    border: 1px solid transparent;\n    height: 35px;\n    -webkit-transition: all .3s ease-in-out;\n    -o-transition: all .3s ease-in-out;\n    transition: all .3s ease-in-out\n}\n\n.skin-black-light .sidebar-form input[type=\"text\"] {\n    color: #666;\n    border-top-left-radius: 2px;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 2px\n}\n\n.skin-black-light .sidebar-form input[type=\"text\"]:focus, .skin-black-light .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    background-color: #fff;\n    color: #666\n}\n\n.skin-black-light .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    border-left-color: #fff\n}\n\n.skin-black-light .sidebar-form .btn {\n    color: #999;\n    border-top-left-radius: 0;\n    border-top-right-radius: 2px;\n    border-bottom-right-radius: 2px;\n    border-bottom-left-radius: 0\n}\n\n@media (min-width: 768px) {\n    .skin-black-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {\n        border-left: 1px solid #d2d6de\n    }\n}\n\n.skin-green .main-header .navbar {\n    background-color: #00a65a\n}\n\n.skin-green .main-header .navbar .nav > li > a {\n    color: #fff\n}\n\n.skin-green .main-header .navbar .nav > li > a:hover, .skin-green .main-header .navbar .nav > li > a:active, .skin-green .main-header .navbar .nav > li > a:focus, .skin-green .main-header .navbar .nav .open > a, .skin-green .main-header .navbar .nav .open > a:hover, .skin-green .main-header .navbar .nav .open > a:focus, .skin-green .main-header .navbar .nav > .active > a {\n    background: rgba(0, 0, 0, 0.1);\n    color: #f6f6f6\n}\n\n.skin-green .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-green .main-header .navbar .sidebar-toggle:hover {\n    color: #f6f6f6;\n    background: rgba(0, 0, 0, 0.1)\n}\n\n.skin-green .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-green .main-header .navbar .sidebar-toggle:hover {\n    background-color: #008d4c\n}\n\n@media (max-width: 767px) {\n    .skin-green .main-header .navbar .dropdown-menu li.divider {\n        background-color: rgba(255, 255, 255, 0.1)\n    }\n\n    .skin-green .main-header .navbar .dropdown-menu li a {\n        color: #fff\n    }\n\n    .skin-green .main-header .navbar .dropdown-menu li a:hover {\n        background: #008d4c\n    }\n}\n\n.skin-green .main-header .logo {\n    background-color: #008d4c;\n    color: #fff;\n    border-bottom: 0 solid transparent\n}\n\n.skin-green .main-header .logo:hover {\n    background-color: #008749\n}\n\n.skin-green .main-header li.user-header {\n    background-color: #00a65a\n}\n\n.skin-green .content-header {\n    background: transparent\n}\n\n.skin-green .wrapper, .skin-green .main-sidebar, .skin-green .left-side {\n    background-color: #222d32\n}\n\n.skin-green .user-panel > .info, .skin-green .user-panel > .info > a {\n    color: #fff\n}\n\n.skin-green .sidebar-menu > li.header {\n    color: #4b646f;\n    background: #1a2226\n}\n\n.skin-green .sidebar-menu > li > a {\n    border-left: 3px solid transparent\n}\n\n.skin-green .sidebar-menu > li:hover > a, .skin-green .sidebar-menu > li.active > a {\n    color: #fff;\n    background: #1e282c;\n    border-left-color: #00a65a\n}\n\n.skin-green .sidebar-menu > li > .treeview-menu {\n    margin: 0 1px;\n    background: #2c3b41\n}\n\n.skin-green .sidebar a {\n    color: #b8c7ce\n}\n\n.skin-green .sidebar a:hover {\n    text-decoration: none\n}\n\n.skin-green .treeview-menu > li > a {\n    color: #8aa4af\n}\n\n.skin-green .treeview-menu > li.active > a, .skin-green .treeview-menu > li > a:hover {\n    color: #fff\n}\n\n.skin-green .sidebar-form {\n    border-radius: 3px;\n    border: 1px solid #374850;\n    margin: 10px 10px\n}\n\n.skin-green .sidebar-form input[type=\"text\"], .skin-green .sidebar-form .btn {\n    box-shadow: none;\n    background-color: #374850;\n    border: 1px solid transparent;\n    height: 35px;\n    -webkit-transition: all .3s ease-in-out;\n    -o-transition: all .3s ease-in-out;\n    transition: all .3s ease-in-out\n}\n\n.skin-green .sidebar-form input[type=\"text\"] {\n    color: #666;\n    border-top-left-radius: 2px;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 2px\n}\n\n.skin-green .sidebar-form input[type=\"text\"]:focus, .skin-green .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    background-color: #fff;\n    color: #666\n}\n\n.skin-green .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    border-left-color: #fff\n}\n\n.skin-green .sidebar-form .btn {\n    color: #999;\n    border-top-left-radius: 0;\n    border-top-right-radius: 2px;\n    border-bottom-right-radius: 2px;\n    border-bottom-left-radius: 0\n}\n\n.skin-green-light .main-header .navbar {\n    background-color: #00a65a\n}\n\n.skin-green-light .main-header .navbar .nav > li > a {\n    color: #fff\n}\n\n.skin-green-light .main-header .navbar .nav > li > a:hover, .skin-green-light .main-header .navbar .nav > li > a:active, .skin-green-light .main-header .navbar .nav > li > a:focus, .skin-green-light .main-header .navbar .nav .open > a, .skin-green-light .main-header .navbar .nav .open > a:hover, .skin-green-light .main-header .navbar .nav .open > a:focus, .skin-green-light .main-header .navbar .nav > .active > a {\n    background: rgba(0, 0, 0, 0.1);\n    color: #f6f6f6\n}\n\n.skin-green-light .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-green-light .main-header .navbar .sidebar-toggle:hover {\n    color: #f6f6f6;\n    background: rgba(0, 0, 0, 0.1)\n}\n\n.skin-green-light .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-green-light .main-header .navbar .sidebar-toggle:hover {\n    background-color: #008d4c\n}\n\n@media (max-width: 767px) {\n    .skin-green-light .main-header .navbar .dropdown-menu li.divider {\n        background-color: rgba(255, 255, 255, 0.1)\n    }\n\n    .skin-green-light .main-header .navbar .dropdown-menu li a {\n        color: #fff\n    }\n\n    .skin-green-light .main-header .navbar .dropdown-menu li a:hover {\n        background: #008d4c\n    }\n}\n\n.skin-green-light .main-header .logo {\n    background-color: #00a65a;\n    color: #fff;\n    border-bottom: 0 solid transparent\n}\n\n.skin-green-light .main-header .logo:hover {\n    background-color: #00a157\n}\n\n.skin-green-light .main-header li.user-header {\n    background-color: #00a65a\n}\n\n.skin-green-light .content-header {\n    background: transparent\n}\n\n.skin-green-light .wrapper, .skin-green-light .main-sidebar, .skin-green-light .left-side {\n    background-color: #f9fafc\n}\n\n.skin-green-light .content-wrapper, .skin-green-light .main-footer {\n    border-left: 1px solid #d2d6de\n}\n\n.skin-green-light .user-panel > .info, .skin-green-light .user-panel > .info > a {\n    color: #444\n}\n\n.skin-green-light .sidebar-menu > li {\n    -webkit-transition: border-left-color .3s ease;\n    -o-transition: border-left-color .3s ease;\n    transition: border-left-color .3s ease\n}\n\n.skin-green-light .sidebar-menu > li.header {\n    color: #848484;\n    background: #f9fafc\n}\n\n.skin-green-light .sidebar-menu > li > a {\n    border-left: 3px solid transparent;\n    font-weight: 600\n}\n\n.skin-green-light .sidebar-menu > li:hover > a, .skin-green-light .sidebar-menu > li.active > a {\n    color: #000;\n    background: #f4f4f5\n}\n\n.skin-green-light .sidebar-menu > li.active {\n    border-left-color: #00a65a\n}\n\n.skin-green-light .sidebar-menu > li.active > a {\n    font-weight: 600\n}\n\n.skin-green-light .sidebar-menu > li > .treeview-menu {\n    background: #f4f4f5\n}\n\n.skin-green-light .sidebar a {\n    color: #444\n}\n\n.skin-green-light .sidebar a:hover {\n    text-decoration: none\n}\n\n.skin-green-light .treeview-menu > li > a {\n    color: #777\n}\n\n.skin-green-light .treeview-menu > li.active > a, .skin-green-light .treeview-menu > li > a:hover {\n    color: #000\n}\n\n.skin-green-light .treeview-menu > li.active > a {\n    font-weight: 600\n}\n\n.skin-green-light .sidebar-form {\n    border-radius: 3px;\n    border: 1px solid #d2d6de;\n    margin: 10px 10px\n}\n\n.skin-green-light .sidebar-form input[type=\"text\"], .skin-green-light .sidebar-form .btn {\n    box-shadow: none;\n    background-color: #fff;\n    border: 1px solid transparent;\n    height: 35px;\n    -webkit-transition: all .3s ease-in-out;\n    -o-transition: all .3s ease-in-out;\n    transition: all .3s ease-in-out\n}\n\n.skin-green-light .sidebar-form input[type=\"text\"] {\n    color: #666;\n    border-top-left-radius: 2px;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 2px\n}\n\n.skin-green-light .sidebar-form input[type=\"text\"]:focus, .skin-green-light .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    background-color: #fff;\n    color: #666\n}\n\n.skin-green-light .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    border-left-color: #fff\n}\n\n.skin-green-light .sidebar-form .btn {\n    color: #999;\n    border-top-left-radius: 0;\n    border-top-right-radius: 2px;\n    border-bottom-right-radius: 2px;\n    border-bottom-left-radius: 0\n}\n\n@media (min-width: 768px) {\n    .skin-green-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {\n        border-left: 1px solid #d2d6de\n    }\n}\n\n.skin-red .main-header .navbar {\n    background-color: #dd4b39\n}\n\n.skin-red .main-header .navbar .nav > li > a {\n    color: #fff\n}\n\n.skin-red .main-header .navbar .nav > li > a:hover, .skin-red .main-header .navbar .nav > li > a:active, .skin-red .main-header .navbar .nav > li > a:focus, .skin-red .main-header .navbar .nav .open > a, .skin-red .main-header .navbar .nav .open > a:hover, .skin-red .main-header .navbar .nav .open > a:focus, .skin-red .main-header .navbar .nav > .active > a {\n    background: rgba(0, 0, 0, 0.1);\n    color: #f6f6f6\n}\n\n.skin-red .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-red .main-header .navbar .sidebar-toggle:hover {\n    color: #f6f6f6;\n    background: rgba(0, 0, 0, 0.1)\n}\n\n.skin-red .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-red .main-header .navbar .sidebar-toggle:hover {\n    background-color: #d73925\n}\n\n@media (max-width: 767px) {\n    .skin-red .main-header .navbar .dropdown-menu li.divider {\n        background-color: rgba(255, 255, 255, 0.1)\n    }\n\n    .skin-red .main-header .navbar .dropdown-menu li a {\n        color: #fff\n    }\n\n    .skin-red .main-header .navbar .dropdown-menu li a:hover {\n        background: #d73925\n    }\n}\n\n.skin-red .main-header .logo {\n    background-color: #d73925;\n    color: #fff;\n    border-bottom: 0 solid transparent\n}\n\n.skin-red .main-header .logo:hover {\n    background-color: #d33724\n}\n\n.skin-red .main-header li.user-header {\n    background-color: #dd4b39\n}\n\n.skin-red .content-header {\n    background: transparent\n}\n\n.skin-red .wrapper, .skin-red .main-sidebar, .skin-red .left-side {\n    background-color: #222d32\n}\n\n.skin-red .user-panel > .info, .skin-red .user-panel > .info > a {\n    color: #fff\n}\n\n.skin-red .sidebar-menu > li.header {\n    color: #4b646f;\n    background: #1a2226\n}\n\n.skin-red .sidebar-menu > li > a {\n    border-left: 3px solid transparent\n}\n\n.skin-red .sidebar-menu > li:hover > a, .skin-red .sidebar-menu > li.active > a {\n    color: #fff;\n    background: #1e282c;\n    border-left-color: #dd4b39\n}\n\n.skin-red .sidebar-menu > li > .treeview-menu {\n    margin: 0 1px;\n    background: #2c3b41\n}\n\n.skin-red .sidebar a {\n    color: #b8c7ce\n}\n\n.skin-red .sidebar a:hover {\n    text-decoration: none\n}\n\n.skin-red .treeview-menu > li > a {\n    color: #8aa4af\n}\n\n.skin-red .treeview-menu > li.active > a, .skin-red .treeview-menu > li > a:hover {\n    color: #fff\n}\n\n.skin-red .sidebar-form {\n    border-radius: 3px;\n    border: 1px solid #374850;\n    margin: 10px 10px\n}\n\n.skin-red .sidebar-form input[type=\"text\"], .skin-red .sidebar-form .btn {\n    box-shadow: none;\n    background-color: #374850;\n    border: 1px solid transparent;\n    height: 35px;\n    -webkit-transition: all .3s ease-in-out;\n    -o-transition: all .3s ease-in-out;\n    transition: all .3s ease-in-out\n}\n\n.skin-red .sidebar-form input[type=\"text\"] {\n    color: #666;\n    border-top-left-radius: 2px;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 2px\n}\n\n.skin-red .sidebar-form input[type=\"text\"]:focus, .skin-red .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    background-color: #fff;\n    color: #666\n}\n\n.skin-red .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    border-left-color: #fff\n}\n\n.skin-red .sidebar-form .btn {\n    color: #999;\n    border-top-left-radius: 0;\n    border-top-right-radius: 2px;\n    border-bottom-right-radius: 2px;\n    border-bottom-left-radius: 0\n}\n\n.skin-red-light .main-header .navbar {\n    /*background-color: #dd4b39;*/\n    /*box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);*/\n}\n\n.skin-red-light .main-header .navbar .nav > li > a {\n    color: #000\n}\n\n.skin-red-light .main-header .navbar .nav > li > a:hover, .skin-red-light .main-header .navbar .nav > li > a:active, .skin-red-light .main-header .navbar .nav > li > a:focus, .skin-red-light .main-header .navbar .nav .open > a, .skin-red-light .main-header .navbar .nav .open > a:hover, .skin-red-light .main-header .navbar .nav .open > a:focus, .skin-red-light .main-header .navbar .nav > .active > a {\n    background-color: #f8f8f8;\n    /*color: #f6f6f6*/\n}\n\n.skin-red-light .main-header .navbar .sidebar-toggle {\n    color: #000\n}\n\n/*.skin-red-light .main-header .navbar .sidebar-toggle:hover {*/\n    /*color: #f6f6f6;*/\n    /*background: rgba(0, 0, 0, 0.1)*/\n/*}*/\n\n/*.skin-red-light .main-header .navbar .sidebar-toggle {*/\n    /*color: #777*/\n/*}*/\n\n/*.skin-red-light .main-header .navbar .sidebar-toggle:hover {*/\n    /*background-color: #d73925*/\n/*}*/\n\n@media (max-width: 767px) {\n    .skin-red-light .main-header .navbar .dropdown-menu li.divider {\n        background-color: rgba(255, 255, 255, 0.1)\n    }\n\n    .skin-red-light .main-header .navbar .dropdown-menu li a {\n        color: #fff\n    }\n\n    .skin-red-light .main-header .navbar .dropdown-menu li a:hover {\n        background: #d73925\n    }\n}\n\n.skin-red-light .main-header .logo {\n    background-color: #dd4b39;\n    color: #fff;\n    /*border-bottom: 0 solid transparent*/\n}\n\n.skin-red-light .main-header .logo:hover {\n    background-color: #dc4735\n}\n\n.skin-red-light .main-header li.user-header {\n    background-color: #dd4b39\n}\n\n.skin-red-light .content-header {\n    background: transparent\n}\n\n.skin-red-light .wrapper, .skin-red-light .main-sidebar, .skin-red-light .left-side {\n    /*background-color: #ffffff;*/\n    /*box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);*/\n}\n\n.skin-red-light .content-wrapper, .skin-red-light .main-footer {\n    border-left: 1px solid #eeeeee;\n\n}\n\n.skin-red-light .user-panel > .info, .skin-red-light .user-panel > .info > a {\n    color: #444\n}\n\n.skin-red-light .sidebar-menu > li {\n    -webkit-transition: border-left-color .3s ease;\n    -o-transition: border-left-color .3s ease;\n    transition: border-left-color .3s ease;\n    /*border-top: 1px solid #FCFCFC;*/\n}\n\n.skin-red-light .sidebar-menu > li.header {\n    color: #848484;\n    background: #f9fafc\n}\n\n.skin-red-light .sidebar-menu > li > a {\n    border-left: 3px solid transparent;\n    font-weight: 600\n}\n\n.skin-red-light .sidebar-menu > li:hover > a, .skin-red-light .sidebar-menu > li.active > a {\n    color: #000;\n    background: #ffffff\n}\n\n.skin-red-light .sidebar-menu > li.active > a, .skin-red-light .sidebar-menu > li.active > a {\n    color: #000;\n    background: #ffffff\n}\n\n.skin-red-light .sidebar-menu > li.active {\n    border-left-color: #dd4b39\n}\n\n.skin-red-light .sidebar-menu > li.active > a {\n    font-weight: 600\n}\n\n.skin-red-light .sidebar-menu > li > .treeview-menu {\n    background: #ffffff;\n    border-top: 1px solid #eeeeee;\n    padding: 10px;\n}\n\n.skin-red-light .sidebar-menu > li > .treeview-menu.menu-open {\n    display: block;\n    text-align: center;\n}\n\n.skin-red-light .sidebar-menu > li > .treeview-menu.menu-open > li.active {\n    background-color: #f8f8f8;\n}\n\n/*.skin-red-light .sidebar-menu > li > .treeview-menu.menu-open > li.active > a {*/\n/*color: #777;*/\n/*}*/\n\n/*.skin-red-light .sidebar-menu > li > .treeview-menu:before {*/\n/*content: \"\";*/\n/*display: block;*/\n/*position: absolute;*/\n/*z-index: 1;*/\n/*left: 23px;*/\n/*top: 44px;*/\n/*bottom: 0px;*/\n/*border-left: 1px solid #e2e2e2;*/\n/*}*/\n\n.skin-red-light .sidebar a {\n    color: #CACACA;\n}\n\n.skin-red-light .sidebar a:hover {\n    text-decoration: none\n}\n\n.skin-red-light .treeview-menu > li > a {\n    color: #777\n}\n\n/*.skin-red-light .treeview-menu > li > a:before {*/\n/*content: \"\";*/\n/*display: inline-block;*/\n/*position: absolute;*/\n/*width: 5px;*/\n/*height: 5px;*/\n/*left: 21px;*/\n/*top: 12px;*/\n/*background-color: #fff;*/\n/*border: 1px solid #e2e2e2;*/\n/*z-index: 2;*/\n/*}*/\n\n.skin-red-light .treeview-menu > li.active > a, .skin-red-light .treeview-menu > li > a:hover {\n    color: #000\n}\n\n.skin-red-light .treeview-menu > li.active > a {\n    font-weight: 600;\n    /*background-color: #f5f5f5;*/\n    color: #777;\n}\n\n.skin-red-light .sidebar-form {\n    border-radius: 3px;\n    border: 1px solid #d2d6de;\n    margin: 10px 10px\n}\n\n.skin-red-light .sidebar-form input[type=\"text\"], .skin-red-light .sidebar-form .btn {\n    box-shadow: none;\n    background-color: #fff;\n    border: 1px solid transparent;\n    height: 35px;\n    -webkit-transition: all .3s ease-in-out;\n    -o-transition: all .3s ease-in-out;\n    transition: all .3s ease-in-out\n}\n\n.skin-red-light .sidebar-form input[type=\"text\"] {\n    color: #666;\n    border-top-left-radius: 2px;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 2px\n}\n\n.skin-red-light .sidebar-form input[type=\"text\"]:focus, .skin-red-light .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    background-color: #fff;\n    color: #666\n}\n\n.skin-red-light .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    border-left-color: #fff\n}\n\n.skin-red-light .sidebar-form .btn {\n    color: #999;\n    border-top-left-radius: 0;\n    border-top-right-radius: 2px;\n    border-bottom-right-radius: 2px;\n    border-bottom-left-radius: 0\n}\n\n@media (min-width: 768px) {\n    .skin-red-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {\n        border-left: 1px solid #d2d6de\n    }\n}\n\n.skin-yellow .main-header .navbar {\n    background-color: #f39c12\n}\n\n.skin-yellow .main-header .navbar .nav > li > a {\n    color: #fff\n}\n\n.skin-yellow .main-header .navbar .nav > li > a:hover, .skin-yellow .main-header .navbar .nav > li > a:active, .skin-yellow .main-header .navbar .nav > li > a:focus, .skin-yellow .main-header .navbar .nav .open > a, .skin-yellow .main-header .navbar .nav .open > a:hover, .skin-yellow .main-header .navbar .nav .open > a:focus, .skin-yellow .main-header .navbar .nav > .active > a {\n    background: rgba(0, 0, 0, 0.1);\n    color: #f6f6f6\n}\n\n.skin-yellow .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-yellow .main-header .navbar .sidebar-toggle:hover {\n    color: #f6f6f6;\n    background: rgba(0, 0, 0, 0.1)\n}\n\n.skin-yellow .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-yellow .main-header .navbar .sidebar-toggle:hover {\n    background-color: #e08e0b\n}\n\n@media (max-width: 767px) {\n    .skin-yellow .main-header .navbar .dropdown-menu li.divider {\n        background-color: rgba(255, 255, 255, 0.1)\n    }\n\n    .skin-yellow .main-header .navbar .dropdown-menu li a {\n        color: #fff\n    }\n\n    .skin-yellow .main-header .navbar .dropdown-menu li a:hover {\n        background: #e08e0b\n    }\n}\n\n.skin-yellow .main-header .logo {\n    background-color: #e08e0b;\n    color: #fff;\n    border-bottom: 0 solid transparent\n}\n\n.skin-yellow .main-header .logo:hover {\n    background-color: #db8b0b\n}\n\n.skin-yellow .main-header li.user-header {\n    background-color: #f39c12\n}\n\n.skin-yellow .content-header {\n    background: transparent\n}\n\n.skin-yellow .wrapper, .skin-yellow .main-sidebar, .skin-yellow .left-side {\n    background-color: #222d32\n}\n\n.skin-yellow .user-panel > .info, .skin-yellow .user-panel > .info > a {\n    color: #fff\n}\n\n.skin-yellow .sidebar-menu > li.header {\n    color: #4b646f;\n    background: #1a2226\n}\n\n.skin-yellow .sidebar-menu > li > a {\n    border-left: 3px solid transparent\n}\n\n.skin-yellow .sidebar-menu > li:hover > a, .skin-yellow .sidebar-menu > li.active > a {\n    color: #fff;\n    background: #1e282c;\n    border-left-color: #f39c12\n}\n\n.skin-yellow .sidebar-menu > li > .treeview-menu {\n    margin: 0 1px;\n    background: #2c3b41\n}\n\n.skin-yellow .sidebar a {\n    color: #b8c7ce\n}\n\n.skin-yellow .sidebar a:hover {\n    text-decoration: none\n}\n\n.skin-yellow .treeview-menu > li > a {\n    color: #8aa4af\n}\n\n.skin-yellow .treeview-menu > li.active > a, .skin-yellow .treeview-menu > li > a:hover {\n    color: #fff\n}\n\n.skin-yellow .sidebar-form {\n    border-radius: 3px;\n    border: 1px solid #374850;\n    margin: 10px 10px\n}\n\n.skin-yellow .sidebar-form input[type=\"text\"], .skin-yellow .sidebar-form .btn {\n    box-shadow: none;\n    background-color: #374850;\n    border: 1px solid transparent;\n    height: 35px;\n    -webkit-transition: all .3s ease-in-out;\n    -o-transition: all .3s ease-in-out;\n    transition: all .3s ease-in-out\n}\n\n.skin-yellow .sidebar-form input[type=\"text\"] {\n    color: #666;\n    border-top-left-radius: 2px;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 2px\n}\n\n.skin-yellow .sidebar-form input[type=\"text\"]:focus, .skin-yellow .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    background-color: #fff;\n    color: #666\n}\n\n.skin-yellow .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    border-left-color: #fff\n}\n\n.skin-yellow .sidebar-form .btn {\n    color: #999;\n    border-top-left-radius: 0;\n    border-top-right-radius: 2px;\n    border-bottom-right-radius: 2px;\n    border-bottom-left-radius: 0\n}\n\n.skin-yellow-light .main-header .navbar {\n    background-color: #f39c12\n}\n\n.skin-yellow-light .main-header .navbar .nav > li > a {\n    color: #fff\n}\n\n.skin-yellow-light .main-header .navbar .nav > li > a:hover, .skin-yellow-light .main-header .navbar .nav > li > a:active, .skin-yellow-light .main-header .navbar .nav > li > a:focus, .skin-yellow-light .main-header .navbar .nav .open > a, .skin-yellow-light .main-header .navbar .nav .open > a:hover, .skin-yellow-light .main-header .navbar .nav .open > a:focus, .skin-yellow-light .main-header .navbar .nav > .active > a {\n    background: rgba(0, 0, 0, 0.1);\n    color: #f6f6f6\n}\n\n.skin-yellow-light .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-yellow-light .main-header .navbar .sidebar-toggle:hover {\n    color: #f6f6f6;\n    background: rgba(0, 0, 0, 0.1)\n}\n\n.skin-yellow-light .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-yellow-light .main-header .navbar .sidebar-toggle:hover {\n    background-color: #e08e0b\n}\n\n@media (max-width: 767px) {\n    .skin-yellow-light .main-header .navbar .dropdown-menu li.divider {\n        background-color: rgba(255, 255, 255, 0.1)\n    }\n\n    .skin-yellow-light .main-header .navbar .dropdown-menu li a {\n        color: #fff\n    }\n\n    .skin-yellow-light .main-header .navbar .dropdown-menu li a:hover {\n        background: #e08e0b\n    }\n}\n\n.skin-yellow-light .main-header .logo {\n    background-color: #f39c12;\n    color: #fff;\n    border-bottom: 0 solid transparent\n}\n\n.skin-yellow-light .main-header .logo:hover {\n    background-color: #f39a0d\n}\n\n.skin-yellow-light .main-header li.user-header {\n    background-color: #f39c12\n}\n\n.skin-yellow-light .content-header {\n    background: transparent\n}\n\n.skin-yellow-light .wrapper, .skin-yellow-light .main-sidebar, .skin-yellow-light .left-side {\n    background-color: #f9fafc\n}\n\n.skin-yellow-light .content-wrapper, .skin-yellow-light .main-footer {\n    border-left: 1px solid #d2d6de\n}\n\n.skin-yellow-light .user-panel > .info, .skin-yellow-light .user-panel > .info > a {\n    color: #444\n}\n\n.skin-yellow-light .sidebar-menu > li {\n    -webkit-transition: border-left-color .3s ease;\n    -o-transition: border-left-color .3s ease;\n    transition: border-left-color .3s ease\n}\n\n.skin-yellow-light .sidebar-menu > li.header {\n    color: #848484;\n    background: #f9fafc\n}\n\n.skin-yellow-light .sidebar-menu > li > a {\n    border-left: 3px solid transparent;\n    font-weight: 600\n}\n\n.skin-yellow-light .sidebar-menu > li:hover > a, .skin-yellow-light .sidebar-menu > li.active > a {\n    color: #000;\n    background: #f4f4f5\n}\n\n.skin-yellow-light .sidebar-menu > li.active {\n    border-left-color: #f39c12\n}\n\n.skin-yellow-light .sidebar-menu > li.active > a {\n    font-weight: 600\n}\n\n.skin-yellow-light .sidebar-menu > li > .treeview-menu {\n    background: #f4f4f5\n}\n\n.skin-yellow-light .sidebar a {\n    color: #444\n}\n\n.skin-yellow-light .sidebar a:hover {\n    text-decoration: none\n}\n\n.skin-yellow-light .treeview-menu > li > a {\n    color: #777\n}\n\n.skin-yellow-light .treeview-menu > li.active > a, .skin-yellow-light .treeview-menu > li > a:hover {\n    color: #000\n}\n\n.skin-yellow-light .treeview-menu > li.active > a {\n    font-weight: 600\n}\n\n.skin-yellow-light .sidebar-form {\n    border-radius: 3px;\n    border: 1px solid #d2d6de;\n    margin: 10px 10px\n}\n\n.skin-yellow-light .sidebar-form input[type=\"text\"], .skin-yellow-light .sidebar-form .btn {\n    box-shadow: none;\n    background-color: #fff;\n    border: 1px solid transparent;\n    height: 35px;\n    -webkit-transition: all .3s ease-in-out;\n    -o-transition: all .3s ease-in-out;\n    transition: all .3s ease-in-out\n}\n\n.skin-yellow-light .sidebar-form input[type=\"text\"] {\n    color: #666;\n    border-top-left-radius: 2px;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 2px\n}\n\n.skin-yellow-light .sidebar-form input[type=\"text\"]:focus, .skin-yellow-light .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    background-color: #fff;\n    color: #666\n}\n\n.skin-yellow-light .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    border-left-color: #fff\n}\n\n.skin-yellow-light .sidebar-form .btn {\n    color: #999;\n    border-top-left-radius: 0;\n    border-top-right-radius: 2px;\n    border-bottom-right-radius: 2px;\n    border-bottom-left-radius: 0\n}\n\n@media (min-width: 768px) {\n    .skin-yellow-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {\n        border-left: 1px solid #d2d6de\n    }\n}\n\n.skin-purple .main-header .navbar {\n    background-color: #605ca8\n}\n\n.skin-purple .main-header .navbar .nav > li > a {\n    color: #fff\n}\n\n.skin-purple .main-header .navbar .nav > li > a:hover, .skin-purple .main-header .navbar .nav > li > a:active, .skin-purple .main-header .navbar .nav > li > a:focus, .skin-purple .main-header .navbar .nav .open > a, .skin-purple .main-header .navbar .nav .open > a:hover, .skin-purple .main-header .navbar .nav .open > a:focus, .skin-purple .main-header .navbar .nav > .active > a {\n    background: rgba(0, 0, 0, 0.1);\n    color: #f6f6f6\n}\n\n.skin-purple .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-purple .main-header .navbar .sidebar-toggle:hover {\n    color: #f6f6f6;\n    background: rgba(0, 0, 0, 0.1)\n}\n\n.skin-purple .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-purple .main-header .navbar .sidebar-toggle:hover {\n    background-color: #555299\n}\n\n@media (max-width: 767px) {\n    .skin-purple .main-header .navbar .dropdown-menu li.divider {\n        background-color: rgba(255, 255, 255, 0.1)\n    }\n\n    .skin-purple .main-header .navbar .dropdown-menu li a {\n        color: #fff\n    }\n\n    .skin-purple .main-header .navbar .dropdown-menu li a:hover {\n        background: #555299\n    }\n}\n\n.skin-purple .main-header .logo {\n    background-color: #555299;\n    color: #fff;\n    border-bottom: 0 solid transparent\n}\n\n.skin-purple .main-header .logo:hover {\n    background-color: #545096\n}\n\n.skin-purple .main-header li.user-header {\n    background-color: #605ca8\n}\n\n.skin-purple .content-header {\n    background: transparent\n}\n\n.skin-purple .wrapper, .skin-purple .main-sidebar, .skin-purple .left-side {\n    background-color: #222d32\n}\n\n.skin-purple .user-panel > .info, .skin-purple .user-panel > .info > a {\n    color: #fff\n}\n\n.skin-purple .sidebar-menu > li.header {\n    color: #4b646f;\n    background: #1a2226\n}\n\n.skin-purple .sidebar-menu > li > a {\n    border-left: 3px solid transparent\n}\n\n.skin-purple .sidebar-menu > li:hover > a, .skin-purple .sidebar-menu > li.active > a {\n    color: #fff;\n    background: #1e282c;\n    border-left-color: #605ca8\n}\n\n.skin-purple .sidebar-menu > li > .treeview-menu {\n    margin: 0 1px;\n    background: #2c3b41\n}\n\n.skin-purple .sidebar a {\n    color: #b8c7ce\n}\n\n.skin-purple .sidebar a:hover {\n    text-decoration: none\n}\n\n.skin-purple .treeview-menu > li > a {\n    color: #8aa4af\n}\n\n.skin-purple .treeview-menu > li.active > a, .skin-purple .treeview-menu > li > a:hover {\n    color: #fff\n}\n\n.skin-purple .sidebar-form {\n    border-radius: 3px;\n    border: 1px solid #374850;\n    margin: 10px 10px\n}\n\n.skin-purple .sidebar-form input[type=\"text\"], .skin-purple .sidebar-form .btn {\n    box-shadow: none;\n    background-color: #374850;\n    border: 1px solid transparent;\n    height: 35px;\n    -webkit-transition: all .3s ease-in-out;\n    -o-transition: all .3s ease-in-out;\n    transition: all .3s ease-in-out\n}\n\n.skin-purple .sidebar-form input[type=\"text\"] {\n    color: #666;\n    border-top-left-radius: 2px;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 2px\n}\n\n.skin-purple .sidebar-form input[type=\"text\"]:focus, .skin-purple .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    background-color: #fff;\n    color: #666\n}\n\n.skin-purple .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    border-left-color: #fff\n}\n\n.skin-purple .sidebar-form .btn {\n    color: #999;\n    border-top-left-radius: 0;\n    border-top-right-radius: 2px;\n    border-bottom-right-radius: 2px;\n    border-bottom-left-radius: 0\n}\n\n.skin-purple-light .main-header .navbar {\n    background-color: #605ca8\n}\n\n.skin-purple-light .main-header .navbar .nav > li > a {\n    color: #fff\n}\n\n.skin-purple-light .main-header .navbar .nav > li > a:hover, .skin-purple-light .main-header .navbar .nav > li > a:active, .skin-purple-light .main-header .navbar .nav > li > a:focus, .skin-purple-light .main-header .navbar .nav .open > a, .skin-purple-light .main-header .navbar .nav .open > a:hover, .skin-purple-light .main-header .navbar .nav .open > a:focus, .skin-purple-light .main-header .navbar .nav > .active > a {\n    background: rgba(0, 0, 0, 0.1);\n    color: #f6f6f6\n}\n\n.skin-purple-light .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-purple-light .main-header .navbar .sidebar-toggle:hover {\n    color: #f6f6f6;\n    background: rgba(0, 0, 0, 0.1)\n}\n\n.skin-purple-light .main-header .navbar .sidebar-toggle {\n    color: #fff\n}\n\n.skin-purple-light .main-header .navbar .sidebar-toggle:hover {\n    background-color: #555299\n}\n\n@media (max-width: 767px) {\n    .skin-purple-light .main-header .navbar .dropdown-menu li.divider {\n        background-color: rgba(255, 255, 255, 0.1)\n    }\n\n    .skin-purple-light .main-header .navbar .dropdown-menu li a {\n        color: #fff\n    }\n\n    .skin-purple-light .main-header .navbar .dropdown-menu li a:hover {\n        background: #555299\n    }\n}\n\n.skin-purple-light .main-header .logo {\n    background-color: #605ca8;\n    color: #fff;\n    border-bottom: 0 solid transparent\n}\n\n.skin-purple-light .main-header .logo:hover {\n    background-color: #5d59a6\n}\n\n.skin-purple-light .main-header li.user-header {\n    background-color: #605ca8\n}\n\n.skin-purple-light .content-header {\n    background: transparent\n}\n\n.skin-purple-light .wrapper, .skin-purple-light .main-sidebar, .skin-purple-light .left-side {\n    background-color: #f9fafc\n}\n\n.skin-purple-light .content-wrapper, .skin-purple-light .main-footer {\n    border-left: 1px solid #d2d6de\n}\n\n.skin-purple-light .user-panel > .info, .skin-purple-light .user-panel > .info > a {\n    color: #444\n}\n\n.skin-purple-light .sidebar-menu > li {\n    -webkit-transition: border-left-color .3s ease;\n    -o-transition: border-left-color .3s ease;\n    transition: border-left-color .3s ease\n}\n\n.skin-purple-light .sidebar-menu > li.header {\n    color: #848484;\n    background: #f9fafc\n}\n\n.skin-purple-light .sidebar-menu > li > a {\n    border-left: 3px solid transparent;\n    font-weight: 600\n}\n\n.skin-purple-light .sidebar-menu > li:hover > a, .skin-purple-light .sidebar-menu > li.active > a {\n    color: #000;\n    background: #f4f4f5\n}\n\n.skin-purple-light .sidebar-menu > li.active {\n    border-left-color: #605ca8\n}\n\n.skin-purple-light .sidebar-menu > li.active > a {\n    font-weight: 600\n}\n\n.skin-purple-light .sidebar-menu > li > .treeview-menu {\n    background: #f4f4f5\n}\n\n.skin-purple-light .sidebar a {\n    color: #444\n}\n\n.skin-purple-light .sidebar a:hover {\n    text-decoration: none\n}\n\n.skin-purple-light .treeview-menu > li > a {\n    color: #777\n}\n\n.skin-purple-light .treeview-menu > li.active > a, .skin-purple-light .treeview-menu > li > a:hover {\n    color: #000\n}\n\n.skin-purple-light .treeview-menu > li.active > a {\n    font-weight: 600\n}\n\n.skin-purple-light .sidebar-form {\n    border-radius: 3px;\n    border: 1px solid #d2d6de;\n    margin: 10px 10px\n}\n\n.skin-purple-light .sidebar-form input[type=\"text\"], .skin-purple-light .sidebar-form .btn {\n    box-shadow: none;\n    background-color: #fff;\n    border: 1px solid transparent;\n    height: 35px;\n    -webkit-transition: all .3s ease-in-out;\n    -o-transition: all .3s ease-in-out;\n    transition: all .3s ease-in-out\n}\n\n.skin-purple-light .sidebar-form input[type=\"text\"] {\n    color: #666;\n    border-top-left-radius: 2px;\n    border-top-right-radius: 0;\n    border-bottom-right-radius: 0;\n    border-bottom-left-radius: 2px\n}\n\n.skin-purple-light .sidebar-form input[type=\"text\"]:focus, .skin-purple-light .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    background-color: #fff;\n    color: #666\n}\n\n.skin-purple-light .sidebar-form input[type=\"text\"]:focus + .input-group-btn .btn {\n    border-left-color: #fff\n}\n\n.skin-purple-light .sidebar-form .btn {\n    color: #999;\n    border-top-left-radius: 0;\n    border-top-right-radius: 2px;\n    border-bottom-right-radius: 2px;\n    border-bottom-left-radius: 0\n}\n\n@media (min-width: 768px) {\n    .skin-purple-light.sidebar-mini.sidebar-collapse .sidebar-menu > li > .treeview-menu {\n        border-left: 1px solid #d2d6de\n    }\n}"
  },
  {
    "path": "public/static/dist/js/app.js",
    "content": "/*! AdminLTE app.js\n * ================\n * Main JS application file for AdminLTE v2. This file\n * should be included in all pages. It controls some layout\n * options and implements exclusive AdminLTE plugins.\n *\n * @Author  Almsaeed Studio\n * @Support <http://www.almsaeedstudio.com>\n * @Email   <support@almsaeedstudio.com>\n * @version 2.3.3\n * @license MIT <http://opensource.org/licenses/MIT>\n */\n\n//Make sure jQuery has been loaded before app.js\nif (typeof jQuery === \"undefined\") {\n    throw new Error(\"AdminLTE requires jQuery\");\n}\n\n/* AdminLTE\n *\n * @type Object\n * @description $.AdminLTE is the main object for the template's app.\n *              It's used for implementing functions and options related\n *              to the template. Keeping everything wrapped in an object\n *              prevents conflict with other plugins and is a better\n *              way to organize our code.\n */\n$.AdminLTE = {};\n\n/* --------------------\n * - AdminLTE Options -\n * --------------------\n * Modify these options to suit your implementation\n */\n$.AdminLTE.options = {\n    //Add slimscroll to navbar menus\n    //This requires you to load the slimscroll plugin\n    //in every page before app.js\n    navbarMenuSlimscroll: true,\n    navbarMenuSlimscrollWidth: \"3px\", //The width of the scroll bar\n    navbarMenuHeight: \"200px\", //The height of the inner menu\n    //General animation speed for JS animated elements such as box collapse/expand and\n    //sidebar treeview slide up/down. This options accepts an integer as milliseconds,\n    //'fast', 'normal', or 'slow'\n    animationSpeed: 500,\n    //Sidebar push menu toggle button selector\n    sidebarToggleSelector: \"[data-toggle='offcanvas']\",\n    //Activate sidebar push menu\n    sidebarPushMenu: true,\n    //Activate sidebar slimscroll if the fixed layout is set (requires SlimScroll Plugin)\n    sidebarSlimScroll: true,\n    //Enable sidebar expand on hover effect for sidebar mini\n    //This option is forced to true if both the fixed layout and sidebar mini\n    //are used together\n    sidebarExpandOnHover: false,\n    //BoxRefresh Plugin\n    enableBoxRefresh: true,\n    //Bootstrap.js tooltip\n    enableBSToppltip: true,\n    BSTooltipSelector: \"[data-toggle='tooltip']\",\n    //Enable Fast Click. Fastclick.js creates a more\n    //native touch experience with touch devices. If you\n    //choose to enable the plugin, make sure you load the script\n    //before AdminLTE's app.js\n    enableFastclick: true,\n    //Control Sidebar Options\n    enableControlSidebar: true,\n    controlSidebarOptions: {\n        //Which button should trigger the open/close event\n        toggleBtnSelector: \"[data-toggle='control-sidebar']\",\n        //The sidebar selector\n        selector: \".control-sidebar\",\n        //Enable slide over content\n        slide: true\n    },\n    //Box Widget Plugin. Enable this plugin\n    //to allow boxes to be collapsed and/or removed\n    enableBoxWidget: true,\n    //Box Widget plugin options\n    boxWidgetOptions: {\n        boxWidgetIcons: {\n            //Collapse icon\n            collapse: 'fa-minus',\n            //Open icon\n            open: 'fa-plus',\n            //Remove icon\n            remove: 'fa-times'\n        },\n        boxWidgetSelectors: {\n            //Remove button selector\n            remove: '[data-widget=\"remove\"]',\n            //Collapse button selector\n            collapse: '[data-widget=\"collapse\"]'\n        }\n    },\n    //Direct Chat plugin options\n    directChat: {\n        //Enable direct chat by default\n        enable: true,\n        //The button to open and close the chat contacts pane\n        contactToggleSelector: '[data-widget=\"chat-pane-toggle\"]'\n    },\n    //Define the set of colors to use globally around the website\n    colors: {\n        lightBlue: \"#3c8dbc\",\n        red: \"#f56954\",\n        green: \"#00a65a\",\n        aqua: \"#00c0ef\",\n        yellow: \"#f39c12\",\n        blue: \"#0073b7\",\n        navy: \"#001F3F\",\n        teal: \"#39CCCC\",\n        olive: \"#3D9970\",\n        lime: \"#01FF70\",\n        orange: \"#FF851B\",\n        fuchsia: \"#F012BE\",\n        purple: \"#8E24AA\",\n        maroon: \"#D81B60\",\n        black: \"#222222\",\n        gray: \"#d2d6de\"\n    },\n    //The standard screen sizes that bootstrap uses.\n    //If you change these in the variables.less file, change\n    //them here too.\n    screenSizes: {\n        xs: 480,\n        sm: 768,\n        md: 992,\n        lg: 1200\n    }\n};\n\n/* ------------------\n * - Implementation -\n * ------------------\n * The next block of code implements AdminLTE's\n * functions and plugins as specified by the\n * options above.\n */\n$(function () {\n    \"use strict\";\n\n    //Fix for IE page transitions\n    $(\"body\").removeClass(\"hold-transition\");\n\n    //Extend options if external options exist\n    if (typeof AdminLTEOptions !== \"undefined\") {\n        $.extend(true,\n            $.AdminLTE.options,\n            AdminLTEOptions);\n    }\n\n    //Easy access to options\n    var o = $.AdminLTE.options;\n\n    //Set up the object\n    _init();\n\n    //Activate the layout maker\n    $.AdminLTE.layout.activate();\n\n    // -----  sidebar-menu start\n    //Enable sidebar tree view controls\n    $.AdminLTE.tree('#sidebar-menu');\n\n    $(document).on('click', '#sidebar-menu-sub ul.treeview-menu.menu-open li', function (e) {\n        $(this).parent().find(\"li\").removeClass('active');\n        $(this).addClass('active');\n\n        // set menu title\n        var title = $(this).find('a').html();\n        $('#sidebar-menu-title').html(title);\n    });\n\n    var pathname = window.location.pathname + window.location.search;\n    $.AdminLTE.treeInit(pathname);\n    // ----- sidebar-menu end\n\n\n    //Enable control sidebar\n    if (o.enableControlSidebar) {\n        $.AdminLTE.controlSidebar.activate();\n    }\n\n    //Add slimscroll to navbar dropdown\n    if (o.navbarMenuSlimscroll && typeof $.fn.slimscroll != 'undefined') {\n        $(\".navbar .menu\").slimscroll({\n            height: o.navbarMenuHeight,\n            alwaysVisible: false,\n            size: o.navbarMenuSlimscrollWidth\n        }).css(\"width\", \"100%\");\n    }\n\n    //Activate sidebar push menu\n    if (o.sidebarPushMenu) {\n        $.AdminLTE.pushMenu.activate(o.sidebarToggleSelector);\n    }\n\n    //Activate Bootstrap tooltip\n    if (o.enableBSToppltip) {\n        $('body').tooltip({\n            selector: o.BSTooltipSelector\n        });\n    }\n\n    //Activate box widget\n    if (o.enableBoxWidget) {\n        $.AdminLTE.boxWidget.activate();\n    }\n\n    //Activate fast click\n    if (o.enableFastclick && typeof FastClick != 'undefined') {\n        FastClick.attach(document.body);\n    }\n\n    //Activate direct chat widget\n    if (o.directChat.enable) {\n        $(document).on('click', o.directChat.contactToggleSelector, function () {\n            var box = $(this).parents('.direct-chat').first();\n            box.toggleClass('direct-chat-contacts-open');\n        });\n    }\n\n    /*\n     * INITIALIZE BUTTON TOGGLE\n     * ------------------------\n     */\n    $('.btn-group[data-toggle=\"btn-toggle\"]').each(function () {\n        var group = $(this);\n        $(this).find(\".btn\").on('click', function (e) {\n            group.find(\".btn.active\").removeClass(\"active\");\n            $(this).addClass(\"active\");\n            e.preventDefault();\n        });\n\n    });\n});\n\n/* ----------------------------------\n * - Initialize the AdminLTE Object -\n * ----------------------------------\n * All AdminLTE functions are implemented below.\n */\nfunction _init() {\n    'use strict';\n    /* Layout\n     * ======\n     * Fixes the layout height in case min-height fails.\n     *\n     * @type Object\n     * @usage $.AdminLTE.layout.activate()\n     *        $.AdminLTE.layout.fix()\n     *        $.AdminLTE.layout.fixSidebar()\n     */\n    $.AdminLTE.layout = {\n        activate: function () {\n            var _this = this;\n            _this.fix();\n            _this.fixSidebar();\n            $(window, \".wrapper\").resize(function () {\n                _this.fix();\n                _this.fixSidebar();\n            });\n        },\n        fix: function () {\n            //Get window height and the wrapper height\n            var neg = $('.main-header').outerHeight() + $('.main-footer').outerHeight();\n            var window_height = $(window).height();\n            var sidebar_height = $(\".sidebar\").height();\n            //Set the min-height of the content and sidebar based on the\n            //the height of the document.\n            if ($(\"body\").hasClass(\"fixed\")) {\n                $(\".content-wrapper, .right-side\").css('min-height', window_height - $('.main-footer').outerHeight());\n            } else {\n                var postSetWidth;\n                if (window_height >= sidebar_height) {\n                    $(\".content-wrapper, .right-side\").css('min-height', window_height - neg);\n                    postSetWidth = window_height - neg;\n                } else {\n                    $(\".content-wrapper, .right-side\").css('min-height', sidebar_height);\n                    postSetWidth = sidebar_height;\n                }\n\n                //Fix for the control sidebar height\n                var controlSidebar = $($.AdminLTE.options.controlSidebarOptions.selector);\n                if (typeof controlSidebar !== \"undefined\") {\n                    if (controlSidebar.height() > postSetWidth)\n                        $(\".content-wrapper, .right-side\").css('min-height', controlSidebar.height());\n                }\n\n            }\n        },\n        fixSidebar: function () {\n            //Make sure the body tag has the .fixed class\n            if (!$(\"body\").hasClass(\"fixed\")) {\n                if (typeof $.fn.slimScroll != 'undefined') {\n                    $(\".sidebar\").slimScroll({destroy: true}).height(\"auto\");\n                }\n                return;\n            } else if (typeof $.fn.slimScroll == 'undefined' && window.console) {\n                window.console.error(\"Error: the fixed layout requires the slimscroll plugin!\");\n            }\n            //Enable slimscroll for fixed layout\n            if ($.AdminLTE.options.sidebarSlimScroll) {\n                if (typeof $.fn.slimScroll != 'undefined') {\n                    //Destroy if it exists\n                    $(\".sidebar\").slimScroll({destroy: true}).height(\"auto\");\n                    //Add slimscroll\n                    $(\".sidebar\").slimscroll({\n                        height: ($(window).height() - $(\".main-header\").height()) + \"px\",\n                        color: \"rgba(0,0,0,0.2)\",\n                        size: \"3px\"\n                    });\n                }\n            }\n        }\n    };\n\n    /* PushMenu()\n     * ==========\n     * Adds the push menu functionality to the sidebar.\n     *\n     * @type Function\n     * @usage: $.AdminLTE.pushMenu(\"[data-toggle='offcanvas']\")\n     */\n    $.AdminLTE.pushMenu = {\n        activate: function (toggleBtn) {\n            //Get the screen sizes\n            var screenSizes = $.AdminLTE.options.screenSizes;\n\n            //Enable sidebar toggle\n            $(document).on('click', toggleBtn, function (e) {\n                e.preventDefault();\n\n                //Enable sidebar push menu\n                if ($(window).width() > (screenSizes.sm - 1)) {\n                    if ($(\"body\").hasClass('sidebar-collapse')) {\n                        $(\"body\").removeClass('sidebar-collapse').trigger('expanded.pushMenu');\n                    } else {\n                        $(\"body\").addClass('sidebar-collapse').trigger('collapsed.pushMenu');\n                    }\n                }\n                //Handle sidebar push menu for small screens\n                else {\n                    if ($(\"body\").hasClass('sidebar-open')) {\n                        $(\"body\").removeClass('sidebar-open').removeClass('sidebar-collapse').trigger('collapsed.pushMenu');\n                    } else {\n                        $(\"body\").addClass('sidebar-open').trigger('expanded.pushMenu');\n                    }\n                }\n            });\n\n            $(\".content-wrapper\").click(function () {\n                //Enable hide menu when clicking on the content-wrapper on small screens\n                if ($(window).width() <= (screenSizes.sm - 1) && $(\"body\").hasClass(\"sidebar-open\")) {\n                    $(\"body\").removeClass('sidebar-open');\n                }\n            });\n\n            //Enable expand on hover for sidebar mini\n            if ($.AdminLTE.options.sidebarExpandOnHover\n                || ($('body').hasClass('fixed')\n                && $('body').hasClass('sidebar-mini'))) {\n                this.expandOnHover();\n            }\n        },\n        expandOnHover: function () {\n            var _this = this;\n            var screenWidth = $.AdminLTE.options.screenSizes.sm - 1;\n            //Expand sidebar on hover\n            $('.main-sidebar').hover(function () {\n                if ($('body').hasClass('sidebar-mini')\n                    && $(\"body\").hasClass('sidebar-collapse')\n                    && $(window).width() > screenWidth) {\n                    _this.expand();\n                }\n            }, function () {\n                if ($('body').hasClass('sidebar-mini')\n                    && $('body').hasClass('sidebar-expanded-on-hover')\n                    && $(window).width() > screenWidth) {\n                    _this.collapse();\n                }\n            });\n        },\n        expand: function () {\n            $(\"body\").removeClass('sidebar-collapse').addClass('sidebar-expanded-on-hover');\n        },\n        collapse: function () {\n            if ($('body').hasClass('sidebar-expanded-on-hover')) {\n                $('body').removeClass('sidebar-expanded-on-hover').addClass('sidebar-collapse');\n            }\n        }\n    };\n\n    /* Tree()\n     * ======\n     * Converts the sidebar into a multilevel\n     * tree view menu.\n     *\n     * @type Function\n     * @Usage: $.AdminLTE.tree('.sidebar')\n     */\n    $.AdminLTE.tree = function (menu) {\n        var _this = this;\n        var animationSpeed = $.AdminLTE.options.animationSpeed;\n\n        $(document).on('click', menu + ' li a', function (e) {\n\n            //Get the clicked link and the next element\n            var $this = $(this);\n            var checkElement = $this.next();\n\n            //remove parent li active\n            $this.parent(\"li\").parent().find(\"li\").removeClass(\"active\");\n            $this.parent(\"li\").addClass(\"active\");\n\n            var parent = $this.parent(\"li\").clone();\n            var parent_li = parent.addClass(\"active\");\n\n            parent_li.find(\"ul\").addClass(\"menu-open\");\n            parent_li.find(\"i\").remove();\n\n            $('#sidebar-menu-sub').html(parent_li);\n\n            // click first children\n            parent_li.find(\"ul li\").first().find(\"a\").click();\n\n            _this.layout.fix();\n\n            //if this isn't a link, prevent the page from being redirected\n            if (checkElement.is('.treeview-menu')) {\n                e.preventDefault();\n            }\n        });\n    };\n\n    /**\n     *  刷新浏览器导航菜单同步\n     *  first render page init tree\n     */\n    $.AdminLTE.treeInit = function (pathname) {\n        \n        var $this = $('#sidebar-menu').find('a[href^=\"' + pathname + '\"]').parent().parent();\n\n        if ($this.length) {\n            //remove parent li active\n            $this.parent(\"li\").parent().find(\"li\").removeClass(\"active\");\n            $this.parent(\"li\").first().addClass(\"active\");\n\n            var parent = $this.parent(\"li\").first().clone();\n            var parent_li = parent.addClass(\"active\");\n            parent_li.find(\"ul\").addClass(\"menu-open\");\n            parent_li.find(\"i\").remove();\n\n            $('#sidebar-menu-sub').html(parent_li);\n\n            parent_li.find('a[href^=\"' + pathname + '\"]').parent().first().click()\n        } else {\n            var paths = pathname.split('/');\n            var _pathname = '';\n\n            if(pathname.indexOf(\"addons/execute\") > 0){\n                _pathname = '/admin/addons/index.html';\n            }else{\n                for (var i = 0; i < paths.length - 1; i++) {\n                    if (!paths[i]) {\n                        continue;\n                    }\n                    _pathname += '/' + paths[i];\n                }\n            }\n\n            $.AdminLTE.treeInit(_pathname);\n        }\n    }\n\n    /* ControlSidebar\n     * ==============\n     * Adds functionality to the right sidebar\n     *\n     * @type Object\n     * @usage $.AdminLTE.controlSidebar.activate(options)\n     */\n    $.AdminLTE.controlSidebar = {\n        //instantiate the object\n        activate: function () {\n            //Get the object\n            var _this = this;\n            //Update options\n            var o = $.AdminLTE.options.controlSidebarOptions;\n            //Get the sidebar\n            var sidebar = $(o.selector);\n            //The toggle button\n            var btn = $(o.toggleBtnSelector);\n\n            //Listen to the click event\n            btn.on('click', function (e) {\n                e.preventDefault();\n                //If the sidebar is not open\n                if (!sidebar.hasClass('control-sidebar-open')\n                    && !$('body').hasClass('control-sidebar-open')) {\n                    //Open the sidebar\n                    _this.open(sidebar, o.slide);\n                } else {\n                    _this.close(sidebar, o.slide);\n                }\n            });\n\n            //If the body has a boxed layout, fix the sidebar bg position\n            var bg = $(\".control-sidebar-bg\");\n            _this._fix(bg);\n\n            //If the body has a fixed layout, make the control sidebar fixed\n            if ($('body').hasClass('fixed')) {\n                _this._fixForFixed(sidebar);\n            } else {\n                //If the content height is less than the sidebar's height, force max height\n                if ($('.content-wrapper, .right-side').height() < sidebar.height()) {\n                    _this._fixForContent(sidebar);\n                }\n            }\n        },\n        //Open the control sidebar\n        open: function (sidebar, slide) {\n            //Slide over content\n            if (slide) {\n                sidebar.addClass('control-sidebar-open');\n            } else {\n                //Push the content by adding the open class to the body instead\n                //of the sidebar itself\n                $('body').addClass('control-sidebar-open');\n            }\n        },\n        //Close the control sidebar\n        close: function (sidebar, slide) {\n            if (slide) {\n                sidebar.removeClass('control-sidebar-open');\n            } else {\n                $('body').removeClass('control-sidebar-open');\n            }\n        },\n        _fix: function (sidebar) {\n            var _this = this;\n            if ($(\"body\").hasClass('layout-boxed')) {\n                sidebar.css('position', 'absolute');\n                sidebar.height($(\".wrapper\").height());\n                $(window).resize(function () {\n                    _this._fix(sidebar);\n                });\n            } else {\n                sidebar.css({\n                    'position': 'fixed',\n                    'height': 'auto'\n                });\n            }\n        },\n        _fixForFixed: function (sidebar) {\n            sidebar.css({\n                'position': 'fixed',\n                'max-height': '100%',\n                'overflow': 'auto',\n                'padding-bottom': '50px'\n            });\n        },\n        _fixForContent: function (sidebar) {\n            $(\".content-wrapper, .right-side\").css('min-height', sidebar.height());\n        }\n    };\n\n    /* BoxWidget\n     * =========\n     * BoxWidget is a plugin to handle collapsing and\n     * removing boxes from the screen.\n     *\n     * @type Object\n     * @usage $.AdminLTE.boxWidget.activate()\n     *        Set all your options in the main $.AdminLTE.options object\n     */\n    $.AdminLTE.boxWidget = {\n        selectors: $.AdminLTE.options.boxWidgetOptions.boxWidgetSelectors,\n        icons: $.AdminLTE.options.boxWidgetOptions.boxWidgetIcons,\n        animationSpeed: $.AdminLTE.options.animationSpeed,\n        activate: function (_box) {\n            var _this = this;\n            if (!_box) {\n                _box = document; // activate all boxes per default\n            }\n            //Listen for collapse event triggers\n            $(_box).on('click', _this.selectors.collapse, function (e) {\n                e.preventDefault();\n                _this.collapse($(this));\n            });\n\n            //Listen for remove event triggers\n            $(_box).on('click', _this.selectors.remove, function (e) {\n                e.preventDefault();\n                _this.remove($(this));\n            });\n        },\n        collapse: function (element) {\n            var _this = this;\n            //Find the box parent\n            var box = element.parents(\".box\").first();\n            //Find the body and the footer\n            var box_content = box.find(\"> .box-body, > .box-footer, > form  >.box-body, > form > .box-footer\");\n            if (!box.hasClass(\"collapsed-box\")) {\n                //Convert minus into plus\n                element.children(\":first\")\n                    .removeClass(_this.icons.collapse)\n                    .addClass(_this.icons.open);\n                //Hide the content\n                box_content.slideUp(_this.animationSpeed, function () {\n                    box.addClass(\"collapsed-box\");\n                });\n            } else {\n                //Convert plus into minus\n                element.children(\":first\")\n                    .removeClass(_this.icons.open)\n                    .addClass(_this.icons.collapse);\n                //Show the content\n                box_content.slideDown(_this.animationSpeed, function () {\n                    box.removeClass(\"collapsed-box\");\n                });\n            }\n        },\n        remove: function (element) {\n            //Find the box parent\n            var box = element.parents(\".box\").first();\n            box.slideUp(this.animationSpeed);\n        }\n    };\n}\n\n/* ------------------\n * - Custom Plugins -\n * ------------------\n * All custom plugins are defined below.\n */\n\n/*\n * BOX REFRESH BUTTON\n * ------------------\n * This is a custom plugin to use with the component BOX. It allows you to add\n * a refresh button to the box. It converts the box's state to a loading state.\n *\n * @type plugin\n * @usage $(\"#box-widget\").boxRefresh( options );\n */\n(function ($) {\n\n    \"use strict\";\n\n    $.fn.boxRefresh = function (options) {\n\n        // Render options\n        var settings = $.extend({\n            //Refresh button selector\n            trigger: \".refresh-btn\",\n            //File source to be loaded (e.g: ajax/src.php)\n            source: \"\",\n            //Callbacks\n            onLoadStart: function (box) {\n                return box;\n            }, //Right after the button has been clicked\n            onLoadDone: function (box) {\n                return box;\n            } //When the source has been loaded\n\n        }, options);\n\n        //The overlay\n        var overlay = $('<div class=\"overlay\"><div class=\"fa fa-refresh fa-spin\"></div></div>');\n\n        return this.each(function () {\n            //if a source is specified\n            if (settings.source === \"\") {\n                if (window.console) {\n                    window.console.log(\"Please specify a source first - boxRefresh()\");\n                }\n                return;\n            }\n            //the box\n            var box = $(this);\n            //the button\n            var rBtn = box.find(settings.trigger).first();\n\n            //On trigger click\n            rBtn.on('click', function (e) {\n                e.preventDefault();\n                //Add loading overlay\n                start(box);\n\n                //Perform ajax call\n                box.find(\".box-body\").load(settings.source, function () {\n                    done(box);\n                });\n            });\n        });\n\n        function start(box) {\n            //Add overlay and loading img\n            box.append(overlay);\n\n            settings.onLoadStart.call(box);\n        }\n\n        function done(box) {\n            //Remove overlay and loading img\n            box.find(overlay).remove();\n\n            settings.onLoadDone.call(box);\n        }\n\n    };\n\n})(jQuery);\n\n/*\n * EXPLICIT BOX CONTROLS\n * -----------------------\n * This is a custom plugin to use with the component BOX. It allows you to activate\n * a box inserted in the DOM after the app.js was loaded, toggle and remove box.\n *\n * @type plugin\n * @usage $(\"#box-widget\").activateBox();\n * @usage $(\"#box-widget\").toggleBox();\n * @usage $(\"#box-widget\").removeBox();\n */\n(function ($) {\n\n    'use strict';\n\n    $.fn.activateBox = function () {\n        $.AdminLTE.boxWidget.activate(this);\n    };\n\n    $.fn.toggleBox = function () {\n        var button = $($.AdminLTE.boxWidget.selectors.collapse, this);\n        $.AdminLTE.boxWidget.collapse(button);\n    };\n\n    $.fn.removeBox = function () {\n        var button = $($.AdminLTE.boxWidget.selectors.remove, this);\n        $.AdminLTE.boxWidget.remove(button);\n    };\n\n})(jQuery);\n\n/*\n * TODO LIST CUSTOM PLUGIN\n * -----------------------\n * This plugin depends on iCheck plugin for checkbox and radio inputs\n *\n * @type plugin\n * @usage $(\"#todo-widget\").todolist( options );\n */\n(function ($) {\n\n    'use strict';\n\n    $.fn.todolist = function (options) {\n        // Render options\n        var settings = $.extend({\n            //When the user checks the input\n            onCheck: function (ele) {\n                return ele;\n            },\n            //When the user unchecks the input\n            onUncheck: function (ele) {\n                return ele;\n            }\n        }, options);\n\n        return this.each(function () {\n\n            if (typeof $.fn.iCheck != 'undefined') {\n                $('input', this).on('ifChecked', function () {\n                    var ele = $(this).parents(\"li\").first();\n                    ele.toggleClass(\"done\");\n                    settings.onCheck.call(ele);\n                });\n\n                $('input', this).on('ifUnchecked', function () {\n                    var ele = $(this).parents(\"li\").first();\n                    ele.toggleClass(\"done\");\n                    settings.onUncheck.call(ele);\n                });\n            } else {\n                $('input', this).on('change', function () {\n                    var ele = $(this).parents(\"li\").first();\n                    ele.toggleClass(\"done\");\n                    if ($('input', ele).is(\":checked\")) {\n                        settings.onCheck.call(ele);\n                    } else {\n                        settings.onUncheck.call(ele);\n                    }\n                });\n            }\n        });\n    };\n}(jQuery));\n"
  },
  {
    "path": "public/static/dist/js/wemall.js",
    "content": "/**\n * Created by heqing on 15/9/25.\n */\n(function ($) {\n    NProgress.configure({\n        template: '<div class=\"bar\" role=\"bar\" style=\"background: red\"><div class=\"peg\" style=\"box-shadow: 0 0 10px #fff, 0 0 5px #fff;\"></div></div><div class=\"spinner\" role=\"spinner\"><div class=\"spinner-icon\" style=\"border-top-color:white;border-left-color: red\"></div></div>'\n    });\n    if ($.support.pjax) {\n        $.pjax.defaults.timeout = 6000;\n        $(document).pjax('a[target!=_blank][target!=_self]', '#pjax-container');\n\n        $(document).on('pjax:send', function () {\n            NProgress.start();\n        });\n        $(document).on('pjax:complete', function () {\n            NProgress.done();\n        });\n        $(document).on('pjax:timeout', function (event) {\n            // Prevent default timeout redirection behavior\n            event.preventDefault()\n        });\n        $(document).on('pjax:beforeReplace', function (contents, options) {\n            //处理服务器返回的json通知\n            if (options['0'].data != undefined) {\n                options['0'].data = '';\n            }\n        });\n        $(document).on('submit', 'form', function (event) {\n            //隐藏返回值\n            $.pjax.submit(event, '#pjax-container', {push: false});\n        });\n        $(document).on('pjax:success', function (event, data, status, xhr) {\n \n            //正则匹配JSON\n            if (data.match(\"^\\{(.+:.+,*){1,}\\}$\")) {\n                var data = JSON.parse(data);\n                \n                if(data.code == 0 || status != 'success') {\n                    toastr.error(data.msg)\n                }else{\n                    toastr.success(data.msg);\n                }\n\n                if (data.url) {\n                    $.pjax({\n                        url: data.url,\n                        container: '#pjax-container'\n                    })\n                }\n            }\n        });\n    }\n})(jQuery);\n\nfunction imageUploader(obj, more) {\n    $.ajax({\n        type: \"get\",\n        url: URL + \"admin/file/index\",\n        data: {},\n        beforeSend: function (xhr) {\n            xhr.setRequestHeader('x-pjax', 'true');\n        },\n        success: function (data) {\n            bootbox.dialog({\n                message: data,\n                title: \"图片上传管理器\",\n                className: \"modal-darkorange\",\n                buttons: {\n                    \"确定\": {\n                        className: \"btn-success\",\n                        callback: function () {\n                            $(obj).parent().parent().find('input').val(selectedImage.id);\n                            $(obj).parent().parent().find('img').attr('src', selectedImage.url);\n                            selectedImage = {};\n\n                            if (more) {\n                                var moreObj = $('#albumsClone').children().first().clone();\n                                moreObj.find('input').val('');\n                                moreObj.find('img').attr('src', PUBLIC +'/static/dist/img/noimage.gif');\n                                $('#albumsClone').append(moreObj);\n                            }\n                        }\n                    },\n                    \"取消\": {\n                        className: \"btn-default\",\n                        callback: function () {\n\n                        }\n                    }\n                }\n            });\n        },\n        error: function (xhr) {\n            toastr.error(\"通讯失败！请重试！\");\n        }\n    });\n    return false;\n}\n\nfunction removeImage(obj, more) {\n    var parentObj = $(obj).parent().parent();\n    parentObj.find('input').val('');\n    parentObj.find('img').attr('src', PUBLIC +'/static/dist/img/noimage.gif');\n\n    var length = $('#albumsClone').find('.fileupload-new.img-thumbnail').length;\n    if (more && length > 1) {\n        parentObj.remove();\n    }\n}\n\nfunction tabPage(obj) {\n    var pagUrl = $(obj).attr('href');\n    $.pjax({\n        url: pagUrl,\n        container: '.bootbox .bootbox-body',\n        push: false,\n    });\n    event.preventDefault();\n}\n\nvar selectedImage = {\n    id: 0,\n    url: '',\n};\nfunction selectImage(obj, id) {\n    $('#dialog-content .cover').hide();\n    $(obj).next().show();\n    selectedImage.id = id;\n    selectedImage.url = $(obj).attr('src');\n}\n\nfunction cancelSelectImage(obj, id) {\n    $(obj).hide();\n    selectedImage = {};\n}\n\nfunction ajaxForm() {\n    $('#myForm').ajaxSubmit(function (data) {\n        toastr.info(data.msg);\n        console.log(data);\n        $.pjax({\n            url: data.url,\n            container: '.bootbox .bootbox-body',\n            push: false,\n        });\n    });\n}\n\nfunction checkAll() {\n    //Enable check and uncheck all functionality\n    $(\"table .check\").prop(\"checked\", function (index, oldValue) {\n        return !oldValue;\n    });\n}\n\nfunction batchUrl(url, is_pajx) {\n    var id = \"\";\n    $(\"table .check\").each(function () {\n        if ($(this).prop(\"checked\")) {\n            id += $(this).val() + \",\";\n        }\n    });\n    id = id.substr(0, id.length - 1);\n    if (id) {\n        is_pajx = (typeof(is_pajx) == \"undefined\") ? true : false;\n        if (is_pajx) {\n            $.pjax({\n                url: url + '?id=' + id,\n                container: '#pjax-container',\n                push: false,\n            });\n        } else {\n            window.location.href = url + '?id=' + id;\n        }\n    } else {\n        toastr.error(\"请先选择目标\");\n    }\n}"
  },
  {
    "path": "public/static/layui/css/layui.css",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n\n.layui-btn,\n.layui-inline,\nimg {\n    vertical-align: middle\n}\n\n.layui-btn,\n.layui-unselect {\n    -webkit-user-select: none;\n    -ms-user-select: none;\n    -moz-user-select: none\n}\n\n.layui-laypage a,\na {\n    text-decoration: none\n}\n\n.layui-btn,\n.layui-tree li i,\n.layui-unselect {\n    -moz-user-select: none\n}\n\n.layui-form-select dl,\n.layui-nav-child {\n    min-width: 100%;\n    box-shadow: 0 2px 4px rgba(0, 0, 0, .12)\n}\n\nblockquote,\nbody,\nbutton,\ndd,\ndiv,\ndl,\ndt,\nform,\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\ninput,\nli,\nol,\np,\npre,\ntd,\ntextarea,\nth,\nul {\n    margin: 0;\n    padding: 0;\n    -webkit-tap-highlight-color: rgba(0, 0, 0, 0)\n}\n\na:active,\na:hover {\n    outline: 0\n}\n\nimg {\n    display: inline-block;\n    border: none\n}\n\nli {\n    list-style: none\n}\n\ntable {\n    border-collapse: collapse;\n    border-spacing: 0\n}\n\nh1,\nh2,\nh3 {\n    font-size: 14px;\n    font-weight: 400\n}\n\nh4,\nh5,\nh6 {\n    font-size: 100%;\n    font-weight: 400\n}\n\nbutton,\ninput,\noptgroup,\noption,\nselect,\ntextarea {\n    font-family: inherit;\n    font-size: inherit;\n    font-style: inherit;\n    font-weight: inherit;\n    outline: 0\n}\n\npre {\n    white-space: pre-wrap;\n    white-space: -moz-pre-wrap;\n    white-space: -pre-wrap;\n    white-space: -o-pre-wrap;\n    word-wrap: break-word\n}\n\n::-webkit-scrollbar {\n    width: 10px;\n    height: 10px\n}\n\n::-webkit-scrollbar-button:vertical {\n    display: none\n}\n\n::-webkit-scrollbar-corner,\n::-webkit-scrollbar-track {\n    background-color: #e2e2e2\n}\n\n::-webkit-scrollbar-thumb {\n    border-radius: 0;\n    background-color: rgba(0, 0, 0, .3)\n}\n\n::-webkit-scrollbar-thumb:vertical:hover {\n    background-color: rgba(0, 0, 0, .35)\n}\n\n::-webkit-scrollbar-thumb:vertical:active {\n    background-color: rgba(0, 0, 0, .38)\n}\n\n@font-face {\n    font-family: layui-icon;\n    src: url(../font/iconfont.eot);\n    src: url(../font/iconfont.eot?#iefix) format('embedded-opentype'), url(../font/iconfont.woff) format('woff'), url(../font/iconfont.ttf) format('truetype'), url(../font/iconfont.svg#iconfont) format('svg')\n}\n\n.layui-icon {\n    font-family: layui-icon!important;\n    font-size: 16px;\n    font-style: normal;\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale\n}\n\nbody {\n    line-height: 24px;\n    font: 14px Helvetica Neue, Helvetica, PingFang SC, \\5FAE\\8F6F\\96C5\\9ED1, Tahoma, Arial, sans-serif\n}\n\n.layui-flow-more a cite,\n.layui-laypage em,\n.layui-tree li a cite,\na cite {\n    font-style: normal\n}\n\nhr {\n    height: 1px;\n    margin: 10px 0;\n    border: 0;\n    background-color: #e2e2e2;\n    clear: both\n}\n\na {\n    color: #333\n}\n\na:hover {\n    color: #777\n}\n\na cite {\n    *cursor: pointer\n}\n\n.layui-box,\n.layui-box * {\n    -webkit-box-sizing: content-box!important;\n    -moz-box-sizing: content-box!important;\n    box-sizing: content-box!important\n}\n\n.layui-border-box,\n.layui-border-box * {\n    -webkit-box-sizing: border-box!important;\n    -moz-box-sizing: border-box!important;\n    box-sizing: border-box!important\n}\n\n.layui-clear {\n    clear: both;\n    *zoom: 1\n}\n\n.layui-clear:after {\n    content: '\\20';\n    clear: both;\n    *zoom: 1;\n    display: block;\n    height: 0\n}\n\n.layui-inline {\n    position: relative;\n    display: inline-block;\n    *display: inline;\n    *zoom: 1\n}\n\n.layui-edge {\n    position: absolute;\n    width: 0;\n    height: 0;\n    border-style: dashed;\n    border-color: transparent;\n    overflow: hidden\n}\n\n.layui-elip {\n    text-overflow: ellipsis;\n    overflow: hidden;\n    white-space: nowrap\n}\n\n.layui-disabled,\n.layui-disabled:hover {\n    color: #d2d2d2!important;\n    cursor: not-allowed!important\n}\n\n.layui-circle {\n    border-radius: 100%\n}\n\n.layui-show {\n    display: block!important\n}\n\n.layui-hide {\n    display: none!important\n}\n\n.layui-main {\n    position: relative;\n    width: 1140px;\n    margin: 0 auto\n}\n\n.layui-header {\n    position: relative;\n    z-index: 1000;\n    height: 65px\n}\n\n.layui-header a:hover {\n    transition: all .5s;\n    -webkit-transition: all .5s\n}\n\n.layui-side {\n    position: fixed;\n    top: 0;\n    bottom: 0;\n    z-index: 999;\n    width: 200px;\n    overflow-x: hidden\n}\n\n.layui-side-scroll {\n    width: 220px;\n    height: 100%;\n    overflow-x: hidden\n}\n\n.layui-body {\n    position: absolute;\n    left: 200px;\n    right: 0;\n    top: 0;\n    bottom: 0;\n    z-index: 998;\n    width: auto;\n    overflow: hidden;\n    overflow-y: auto;\n    -webkit-box-sizing: border-box;\n    -moz-box-sizing: border-box;\n    box-sizing: border-box\n}\n\n.layui-layout-admin .layui-header {\n    border-bottom: 5px solid #1AA094\n}\n\n.layui-layout-admin .layui-side {\n    top: 70px;\n    width: 200px;\n    overflow-x: hidden\n}\n\n.layui-layout-admin .layui-body {\n    top: 70px;\n    bottom: 44px\n}\n\n.layui-layout-admin .layui-main {\n    width: auto;\n    margin: 0 15px\n}\n\n.layui-layout-admin .layui-footer {\n    position: fixed;\n    left: 200px;\n    right: 0;\n    bottom: 0;\n    height: 44px;\n    background-color: #eee\n}\n\n.layui-btn,\n.layui-input,\n.layui-select,\n.layui-textarea,\n.layui-upload-button {\n    outline: 0;\n    -webkit-transition: border-color .3s cubic-bezier(.65, .05, .35, .5);\n    transition: border-color .3s cubic-bezier(.65, .05, .35, .5);\n    -webkit-box-sizing: border-box!important;\n    -moz-box-sizing: border-box!important;\n    box-sizing: border-box!important\n}\n\n.layui-elem-quote {\n    margin-bottom: 10px;\n    padding: 15px;\n    line-height: 22px;\n    border-left: 5px solid #009688;\n    border-radius: 0 2px 2px 0;\n    background-color: #f2f2f2\n}\n\n.layui-quote-nm {\n    border-color: #e2e2e2;\n    border-style: solid;\n    border-width: 1px 1px 1px 5px;\n    background: 0 0\n}\n\n.layui-elem-field {\n    margin-bottom: 10px;\n    padding: 0;\n    border: 1px solid #e2e2e2\n}\n\n.layui-elem-field legend {\n    margin-left: 20px;\n    padding: 0 10px;\n    font-size: 20px;\n    font-weight: 300\n}\n\n.layui-field-title {\n    margin: 10px 0 20px;\n    border: none;\n    border-top: 1px solid #e2e2e2\n}\n\n.layui-field-box {\n    padding: 10px 15px\n}\n\n.layui-field-title .layui-field-box {\n    padding: 10px 0\n}\n\n.layui-bg-black {\n    background-color: #393D49;\n    color: #c2c2c2\n}\n\n.layui-bg-black a {\n    color: #c2c2c2\n}\n\n.layui-bg-black a:hover {\n    color: #fff\n}\n\n.layui-bg-gray {\n    background-color: #eee;\n    color: #333\n}\n\n.layui-bg-green {\n    background-color: #009688;\n    color: #D7EEE8\n}\n\n.layui-bg-blue {\n    background-color: #1E9FFF;\n    color: #D7EEE8\n}\n\n.layui-word-aux {\n    font-size: 12px;\n    color: #999;\n    padding: 0 5px\n}\n\n.layui-btn {\n    display: inline-block;\n    height: 38px;\n    line-height: 38px;\n    padding: 0 18px;\n    background-color: #009688;\n    color: #fff;\n    white-space: nowrap;\n    text-align: center;\n    border: none;\n    border-radius: 2px;\n    cursor: pointer;\n    opacity: .9;\n    filter: alpha(opacity=90)\n}\n\n.layui-btn:hover {\n    opacity: .8;\n    filter: alpha(opacity=80);\n    color: #fff\n}\n\n.layui-btn:active {\n    opacity: 1;\n    filter: alpha(opacity=100)\n}\n\n.layui-btn+.layui-btn {\n    margin-left: 10px\n}\n\n.layui-btn-radius {\n    border-radius: 100px\n}\n\n.layui-btn .layui-icon {\n    font-size: 18px;\n    vertical-align: bottom\n}\n\n.layui-btn-primary {\n    border: 1px solid #C9C9C9;\n    background-color: #fff;\n    color: #555\n}\n\n.layui-btn-primary:hover {\n    border-color: #009688;\n    color: #333\n}\n\n.layui-btn-normal {\n    background-color: #1E9FFF\n}\n\n.layui-btn-warm {\n    background-color: #F7B824\n}\n\n.layui-btn-danger {\n    background-color: #FF5722\n}\n\n.layui-btn-disabled,\n.layui-btn-disabled:active,\n.layui-btn-disabled:hover {\n    border: 1px solid #e6e6e6;\n    background-color: #FBFBFB;\n    color: #C9C9C9;\n    cursor: not-allowed;\n    opacity: 1\n}\n\n.layui-btn-big {\n    height: 44px;\n    line-height: 44px;\n    padding: 0 25px;\n    font-size: 16px\n}\n\n.layui-btn-small {\n    height: 30px;\n    line-height: 30px;\n    padding: 0 10px;\n    font-size: 12px\n}\n\n.layui-btn-small i {\n    font-size: 16px!important\n}\n\n.layui-btn-mini {\n    height: 22px;\n    line-height: 22px;\n    padding: 0 5px;\n    font-size: 12px\n}\n\n.layui-btn-mini i {\n    font-size: 14px!important\n}\n\n.layui-input,\n.layui-select,\n.layui-textarea {\n    height: 38px;\n    line-height: 38px;\n    line-height: 36px\\9;\n    border: 1px solid #e6e6e6;\n    background-color: #fff;\n    border-radius: 2px\n}\n\n.layui-form-label,\n.layui-form-mid,\n.layui-textarea {\n    line-height: 20px;\n    position: relative\n}\n\n.layui-input,\n.layui-textarea {\n    display: block;\n    width: 100%;\n    padding-left: 10px\n}\n\n.layui-input:hover,\n.layui-textarea:hover {\n    border-color: #D2D2D2!important\n}\n\n.layui-input:focus,\n.layui-textarea:focus {\n    border-color: #C9C9C9!important\n}\n\n.layui-textarea {\n    min-height: 100px;\n    height: auto;\n    padding: 6px 10px;\n    resize: vertical\n}\n\n.layui-select {\n    padding: 0 10px\n}\n\n.layui-form input[type=checkbox],\n.layui-form input[type=radio],\n.layui-form select {\n    display: none\n}\n\n.layui-form-item {\n    margin-bottom: 15px;\n    clear: both;\n    *zoom: 1\n}\n\n.layui-form-item:after {\n    content: '\\20';\n    clear: both;\n    *zoom: 1;\n    display: block;\n    height: 0\n}\n\n.layui-form-label {\n    float: left;\n    display: block;\n    padding: 9px 15px;\n    width: 80px;\n    font-weight: 400;\n    text-align: right\n}\n\n.layui-form-item .layui-inline {\n    margin-bottom: 5px;\n    margin-right: 10px\n}\n\n.layui-input-block,\n.layui-input-inline {\n    position: relative\n}\n\n.layui-input-block {\n    margin-left: 110px;\n    min-height: 36px\n}\n\n.layui-input-inline {\n    display: inline-block;\n    vertical-align: middle\n}\n\n.layui-form-item .layui-input-inline {\n    float: left;\n    width: 190px;\n    margin-right: 10px\n}\n\n.layui-form-text .layui-input-inline {\n    width: auto\n}\n\n.layui-form-mid {\n    float: left;\n    display: block;\n    padding: 8px 0;\n    margin-right: 10px\n}\n\n.layui-form-danger+.layui-form-select .layui-input,\n.layui-form-danger:focus {\n    border: 1px solid #FF5722!important\n}\n\n.layui-form-select {\n    position: relative\n}\n\n.layui-form-select .layui-input {\n    padding-right: 30px;\n    cursor: pointer\n}\n\n.layui-form-select .layui-edge {\n    position: absolute;\n    right: 10px;\n    top: 50%;\n    margin-top: -3px;\n    cursor: pointer;\n    border-width: 6px;\n    border-top-color: #c2c2c2;\n    border-top-style: solid;\n    transition: all .3s;\n    -webkit-transition: all .3s\n}\n\n.layui-form-checkbox,\n.layui-form-switch {\n    -webkit-transition: .1s linear;\n    cursor: pointer\n}\n\n.layui-form-select dl {\n    display: none;\n    position: absolute;\n    left: 0;\n    top: 42px;\n    padding: 5px 0;\n    z-index: 999;\n    border: 1px solid #d2d2d2;\n    max-height: 300px;\n    overflow-y: auto;\n    background-color: #fff;\n    border-radius: 2px;\n    box-sizing: border-box\n}\n\n.layui-form-select dl dd,\n.layui-form-select dl dt {\n    padding: 0 10px;\n    line-height: 36px;\n    white-space: nowrap;\n    overflow: hidden;\n    text-overflow: ellipsis\n}\n\n.layui-form-select dl dt {\n    font-size: 12px;\n    color: #999\n}\n\n.layui-form-select dl dd {\n    cursor: pointer\n}\n\n.layui-form-select dl dd:hover {\n    background-color: #f2f2f2\n}\n\n.layui-form-select .layui-select-group dd {\n    padding-left: 20px\n}\n\n.layui-form-select dl dd.layui-this {\n    background-color: #5FB878;\n    color: #fff\n}\n\n.layui-form-checkbox,\n.layui-form-select dl dd.layui-disabled {\n    background-color: #fff\n}\n\n.layui-form-selected dl {\n    display: block\n}\n\n.layui-form-checkbox,\n.layui-form-checkbox *,\n.layui-form-radio,\n.layui-form-radio *,\n.layui-form-switch {\n    display: inline-block;\n    vertical-align: middle\n}\n\n.layui-form-selected .layui-edge {\n    margin-top: -9px;\n    -webkit-transform: rotate(180deg);\n    transform: rotate(180deg);\n    margin-top: -3px\\9\n}\n\n:root .layui-form-selected .layui-edge {\n    margin-top: -9px\\0/IE9\n}\n\n.layui-select-disabled .layui-disabled {\n    border-color: #eee!important\n}\n\n.layui-select-disabled .layui-edge {\n    border-top-color: #d2d2d2\n}\n\n.layui-form-checkbox {\n    position: relative;\n    height: 30px;\n    line-height: 28px;\n    margin: 4px 10px 0 0;\n    padding-right: 30px;\n    border: 1px solid #d2d2d2;\n    font-size: 0;\n    border-radius: 2px;\n    transition: .1s linear;\n    box-sizing: border-box!important\n}\n\n.layui-form-checkbox:hover {\n    border: 1px solid #c2c2c2\n}\n\n.layui-form-checkbox span {\n    padding: 0 10px;\n    font-size: 14px;\n    background-color: #d2d2d2;\n    color: #fff;\n    overflow: hidden;\n    white-space: nowrap;\n    text-overflow: ellipsis\n}\n\n.layui-form-checkbox:hover span {\n    background-color: #c2c2c2\n}\n\n.layui-form-checkbox i {\n    position: absolute;\n    right: 0;\n    width: 37px;\n    color: #fff;\n    font-size: 20px\n}\n\n.layui-form-checkbox:hover i {\n    color: #c2c2c2\n}\n\n.layui-form-checked,\n.layui-form-checked:hover {\n    border: 1px solid #5FB878\n}\n\n.layui-form-checked span,\n.layui-form-checked:hover span {\n    background-color: #5FB878\n}\n\n.layui-form-checked i,\n.layui-form-checked:hover i {\n    color: #5FB878\n}\n\n.layui-form-switch {\n    position: relative;\n    height: 24px;\n    line-height: 22px;\n    width: 50px;\n    padding: 0 5px;\n    margin-top: 8px;\n    border: 1px solid #d2d2d2;\n    border-radius: 20px;\n    background-color: #fff;\n    transition: .1s linear\n}\n\n.layui-form-switch i {\n    position: absolute;\n    left: 5px;\n    top: 3px;\n    width: 16px;\n    height: 16px;\n    border-radius: 20px;\n    background-color: #d2d2d2;\n    -webkit-transition: .1s linear;\n    transition: .1s linear\n}\n\n.layui-form-onswitch {\n    border-color: #5FB878;\n    background-color: #5FB878\n}\n\n.layui-form-onswitch:before {\n    content: 'ON';\n    color: #fff\n}\n\n.layui-form-onswitch i {\n    left: 30px;\n    background-color: #fff\n}\n\n.layui-checkbox-disbaled {\n    border-color: #e2e2e2!important\n}\n\n.layui-checkbox-disbaled span {\n    background-color: #e2e2e2!important\n}\n\n.layui-checkbox-disbaled:hover i {\n    color: #fff!important\n}\n\n.layui-form-radio {\n    line-height: 28px;\n    margin: 6px 10px 0 0;\n    padding-right: 10px;\n    cursor: pointer;\n    font-size: 0\n}\n\n.layui-form-radio i {\n    margin-right: 8px;\n    font-size: 22px;\n    color: #c2c2c2\n}\n\n.layui-form-radio span {\n    font-size: 14px\n}\n\n.layui-form-radio i:hover,\n.layui-form-radioed i {\n    color: #5FB878\n}\n\n.layui-radio-disbaled i {\n    color: #e2e2e2!important\n}\n\n.layui-form-pane .layui-form-label {\n    width: 80px;\n    padding: 8px 15px;\n    line-height: 20px;\n    border: 1px solid #e6e6e6;\n    border-radius: 2px 0 0 2px;\n    text-align: center;\n    background-color: #FBFBFB;\n    overflow: hidden;\n    white-space: nowrap;\n    text-overflow: ellipsis\n}\n\n.layui-form-pane .layui-input-inline {\n    margin-left: -1px\n}\n\n.layui-form-pane .layui-input-block {\n    margin-left: 112px;\n    left: -1px\n}\n\n.layui-form-pane .layui-input {\n    border-radius: 0 2px 2px 0\n}\n\n.layui-form-pane .layui-form-text .layui-form-label {\n    float: none;\n    width: 100%;\n    border-right: 1px solid #e6e6e6;\n    border-radius: 2px;\n    box-sizing: border-box!important;\n    text-align: left\n}\n\n.layui-laypage button,\n.layui-laypage input,\n.layui-nav {\n    -webkit-box-sizing: border-box!important;\n    -moz-box-sizing: border-box!important\n}\n\n.layui-form-pane .layui-form-text .layui-input-inline {\n    display: block;\n    margin: 0;\n    top: -1px;\n    clear: both\n}\n\n.layui-form-pane .layui-form-text .layui-input-block {\n    margin: 0;\n    left: 0;\n    top: -1px\n}\n\n.layui-form-pane .layui-form-text .layui-textarea {\n    min-height: 100px;\n    border-radius: 0 0 2px 2px\n}\n\n.layui-form-pane .layui-input:hover,\n.layui-form-pane .layui-textarea:hover {\n    border-color: #e6e6e6!important\n}\n\n.layui-form-pane .layui-input:focus,\n.layui-form-pane .layui-textarea:focus {\n    border-color: #e6e6e6!important\n}\n\n.layui-form-pane .layui-form-checkbox {\n    margin: 0 0 10px 10px\n}\n\n.layui-form-pane .layui-form-radio,\n.layui-form-pane .layui-form-switch {\n    margin-left: 10px\n}\n\n.layui-layedit {\n    border: 1px solid #d2d2d2;\n    border-radius: 2px\n}\n\n.layui-layedit-tool {\n    padding: 3px 5px;\n    border-bottom: 1px solid #e2e2e2;\n    font-size: 0\n}\n\n.layedit-tool-fixed {\n    position: fixed;\n    top: 0;\n    border-top: 1px solid #e2e2e2\n}\n\n.layui-layedit-tool .layedit-tool-mid,\n.layui-layedit-tool .layui-icon {\n    display: inline-block;\n    vertical-align: middle;\n    text-align: center;\n    font-size: 14px\n}\n\n.layui-layedit-tool .layui-icon {\n    position: relative;\n    width: 32px;\n    height: 30px;\n    line-height: 30px;\n    margin: 3px 5px;\n    color: #777;\n    cursor: pointer;\n    border-radius: 2px\n}\n\n.layui-layedit-tool .layui-icon:hover {\n    color: #393D49\n}\n\n.layui-layedit-tool .layui-icon:active {\n    color: #000\n}\n\n.layui-layedit-tool .layedit-tool-active {\n    background-color: #e2e2e2;\n    color: #000\n}\n\n.layui-layedit-tool .layui-disabled,\n.layui-layedit-tool .layui-disabled:hover {\n    color: #d2d2d2;\n    cursor: not-allowed\n}\n\n.layui-layedit-tool .layedit-tool-mid {\n    width: 1px;\n    height: 18px;\n    margin: 0 10px;\n    background-color: #d2d2d2\n}\n\n.layedit-tool-html {\n    width: 50px!important;\n    font-size: 30px!important\n}\n\n.layedit-tool-b,\n.layedit-tool-code,\n.layedit-tool-help {\n    font-size: 16px!important\n}\n\n.layedit-tool-d,\n.layedit-tool-face,\n.layedit-tool-image,\n.layedit-tool-unlink {\n    font-size: 18px!important\n}\n\n.layedit-tool-image input {\n    position: absolute;\n    font-size: 0;\n    left: 0;\n    top: 0;\n    width: 100%;\n    height: 100%;\n    opacity: .01;\n    filter: Alpha(opacity=1);\n    cursor: pointer\n}\n\n.layui-layedit-iframe iframe {\n    display: block;\n    width: 100%\n}\n\n#LAY_layedit_code {\n    overflow: hidden\n}\n\n.layui-table {\n    width: 100%;\n    margin: 10px 0;\n    background-color: #fff\n}\n\n.layui-table tr {\n    transition: all .3s;\n    -webkit-transition: all .3s\n}\n\n.layui-table thead tr {\n    background-color: #f2f2f2\n}\n\n.layui-table th {\n    text-align: left\n}\n\n.layui-table td,\n.layui-table th {\n    padding: 9px 15px;\n    min-height: 20px;\n    line-height: 20px;\n    border: 1px solid #e2e2e2;\n    font-size: 14px\n}\n\n.layui-table tr:hover,\n.layui-table[lay-even] tr:nth-child(even) {\n    background-color: #f8f8f8\n}\n\n.layui-table[lay-skin=line],\n.layui-table[lay-skin=row] {\n    border: 1px solid #e2e2e2\n}\n\n.layui-table[lay-skin=line] td,\n.layui-table[lay-skin=line] th {\n    border: none;\n    border-bottom: 1px solid #e2e2e2\n}\n\n.layui-table[lay-skin=row] td,\n.layui-table[lay-skin=row] th {\n    border: none;\n    border-right: 1px solid #e2e2e2\n}\n\n.layui-table[lay-skin=nob] td,\n.layui-table[lay-skin=nob] th {\n    border: none\n}\n\n.layui-upload-button {\n    position: relative;\n    display: inline-block;\n    vertical-align: middle;\n    min-width: 60px;\n    height: 38px;\n    line-height: 38px;\n    border: 1px solid #DFDFDF;\n    border-radius: 2px;\n    overflow: hidden;\n    background-color: #fff;\n    color: #666\n}\n\n.layui-upload-button:hover {\n    border: 1px solid #aaa;\n    color: #333\n}\n\n.layui-upload-button:active {\n    border: 1px solid #4CAF50;\n    color: #000\n}\n\n.layui-upload-button input,\n.layui-upload-file {\n    opacity: .01;\n    filter: Alpha(opacity=1);\n    cursor: pointer\n}\n\n.layui-upload-button input {\n    position: absolute;\n    left: 0;\n    top: 0;\n    z-index: 10;\n    font-size: 100px;\n    width: 100%;\n    height: 100%\n}\n\n.layui-upload-icon {\n    display: block;\n    margin: 0 15px;\n    text-align: center\n}\n\n.layui-upload-icon i {\n    margin-right: 5px;\n    vertical-align: top;\n    font-size: 20px;\n    color: #5FB878\n}\n\n.layui-upload-iframe {\n    position: absolute;\n    width: 0;\n    height: 0;\n    border: 0;\n    visibility: hidden\n}\n\n.layui-upload-enter {\n    border: 1px solid #009E94;\n    background-color: #009E94;\n    color: #fff;\n    -webkit-transform: scale(1.1);\n    transform: scale(1.1)\n}\n\n.layui-upload-enter .layui-upload-icon,\n.layui-upload-enter .layui-upload-icon i {\n    color: #fff\n}\n\n.layui-flow-more {\n    margin: 10px 0;\n    text-align: center;\n    color: #999;\n    font-size: 14px\n}\n\n.layui-flow-more a {\n    height: 32px;\n    line-height: 32px\n}\n\n.layui-flow-more a * {\n    display: inline-block;\n    vertical-align: top\n}\n\n.layui-flow-more a cite {\n    padding: 0 20px;\n    border-radius: 3px;\n    background-color: #eee;\n    color: #333\n}\n\n.layui-flow-more a cite:hover {\n    opacity: .8\n}\n\n.layui-flow-more a i {\n    font-size: 30px;\n    color: #737383\n}\n\n.layui-laypage {\n    display: inline-block;\n    *display: inline;\n    *zoom: 1;\n    vertical-align: middle;\n    margin: 10px 0;\n    font-size: 0\n}\n\n.layui-laypage>:first-child,\n.layui-laypage>:first-child em {\n    border-radius: 2px 0 0 2px\n}\n\n.layui-laypage>:last-child,\n.layui-laypage>:last-child em {\n    border-radius: 0 2px 2px 0\n}\n\n.layui-laypage a,\n.layui-laypage span {\n    display: inline-block;\n    *display: inline;\n    *zoom: 1;\n    vertical-align: middle;\n    padding: 0 15px;\n    border: 1px solid #e2e2e2;\n    height: 28px;\n    line-height: 28px;\n    margin: 0 -1px 5px 0;\n    background-color: #fff;\n    color: #333;\n    font-size: 12px\n}\n\n.layui-laypage span {\n    color: #999;\n    font-weight: 700\n}\n\n.layui-laypage .layui-laypage-curr {\n    position: relative\n}\n\n.layui-laypage .layui-laypage-curr em {\n    position: relative;\n    color: #fff;\n    font-weight: 400\n}\n\n.layui-laypage .layui-laypage-curr .layui-laypage-em {\n    position: absolute;\n    left: -1px;\n    top: -1px;\n    padding: 1px;\n    width: 100%;\n    height: 100%;\n    background-color: #009688\n}\n\n.layui-laypage-em {\n    border-radius: 2px\n}\n\n.layui-laypage-next em,\n.layui-laypage-prev em {\n    font-family: Sim sun;\n    font-size: 16px\n}\n\n.layui-laypage .layui-laypage-total {\n    height: 30px;\n    line-height: 30px;\n    margin-left: 1px;\n    border: none;\n    font-weight: 400\n}\n\n.layui-laypage button,\n.layui-laypage input {\n    height: 30px;\n    line-height: 30px;\n    border: 1px solid #e2e2e2;\n    border-radius: 2px;\n    vertical-align: top;\n    background-color: #fff;\n    box-sizing: border-box!important\n}\n\n.layui-laypage input {\n    width: 50px;\n    margin: 0 5px;\n    text-align: center\n}\n\n.layui-laypage button {\n    margin-left: 5px;\n    padding: 0 15px;\n    cursor: pointer\n}\n\n.layui-code {\n    position: relative;\n    margin: 10px 0;\n    padding: 15px;\n    line-height: 20px;\n    border: 1px solid #ddd;\n    border-left-width: 6px;\n    background-color: #F2F2F2;\n    color: #333;\n    font-family: Courier New;\n    font-size: 12px\n}\n\n.layui-tree {\n    line-height: 26px\n}\n\n.layui-tree li {\n    text-overflow: ellipsis;\n    overflow: hidden;\n    white-space: nowrap\n}\n\n.layui-tree li .layui-tree-spread,\n.layui-tree li a {\n    display: inline-block;\n    vertical-align: top;\n    height: 26px;\n    *display: inline;\n    *zoom: 1;\n    cursor: pointer\n}\n\n.layui-tree li a {\n    font-size: 0\n}\n\n.layui-tree li a i {\n    font-size: 16px\n}\n\n.layui-tree li a cite {\n    padding: 0 6px;\n    font-size: 14px\n}\n\n.layui-tree li i {\n    padding-left: 6px;\n    color: #333\n}\n\n.layui-tree li .layui-tree-check {\n    font-size: 13px\n}\n\n.layui-tree li .layui-tree-check:hover {\n    color: #009E94\n}\n\n.layui-tree li ul {\n    display: none;\n    margin-left: 20px\n}\n\n.layui-tree li .layui-tree-enter {\n    line-height: 24px;\n    border: 1px dotted #000\n}\n\n.layui-tree-drag {\n    display: none;\n    position: absolute;\n    left: -666px;\n    top: -666px;\n    background-color: #f2f2f2;\n    padding: 5px 10px;\n    border: 1px dotted #000;\n    white-space: nowrap\n}\n\n.layui-nav .layui-nav-item,\n.layui-tab-title li {\n    display: inline-block;\n    *zoom: 1;\n    vertical-align: middle\n}\n\n.layui-tree-drag i {\n    padding-right: 5px\n}\n\n.layui-nav {\n    position: relative;\n    padding: 0 20px;\n    background-color: #393D49;\n    color: #c2c2c2;\n    border-radius: 2px;\n    font-size: 0;\n    box-sizing: border-box!important\n}\n\n.layui-nav * {\n    font-size: 14px\n}\n\n.layui-nav .layui-nav-item {\n    position: relative;\n    *display: inline;\n    line-height: 60px\n}\n\n.layui-nav .layui-nav-item a {\n    display: block;\n    padding: 0 20px;\n    color: #c2c2c2;\n    transition: all .3s;\n    -webkit-transition: all .3s\n}\n\n.layui-nav .layui-this:after,\n.layui-nav-bar,\n.layui-nav-tree .layui-nav-itemed:after {\n    position: absolute;\n    left: 0;\n    top: 0;\n    width: 0;\n    height: 5px;\n    background-color: #5FB878;\n    transition: all .2s;\n    -webkit-transition: all .2s\n}\n\n.layui-nav-bar {\n    z-index: 1000\n}\n\n.layui-nav .layui-nav-item a:hover,\n.layui-nav .layui-this a {\n    color: #fff\n}\n\n.layui-nav .layui-this:after {\n    content: '';\n    top: auto;\n    bottom: 0;\n    width: 100%\n}\n\n.layui-nav .layui-nav-more {\n    content: '';\n    width: 0;\n    height: 0;\n    border-style: solid dashed dashed;\n    border-color: #c2c2c2 transparent transparent;\n    overflow: hidden;\n    cursor: pointer;\n    transition: all .2s;\n    -webkit-transition: all .2s;\n    position: absolute;\n    top: 28px;\n    right: 3px;\n    border-width: 6px\n}\n\n.layui-nav .layui-nav-mored,\n.layui-nav-itemed .layui-nav-more {\n    top: 22px;\n    border-style: dashed dashed solid;\n    border-color: transparent transparent #c2c2c2\n}\n\n.layui-nav-child {\n    display: none;\n    position: absolute;\n    left: 0;\n    top: 65px;\n    line-height: 36px;\n    padding: 5px 0;\n    border: 1px solid #d2d2d2;\n    background-color: #fff;\n    z-index: 100;\n    border-radius: 2px;\n    white-space: nowrap\n}\n\n.layui-nav .layui-nav-child a {\n    color: #333\n}\n\n.layui-nav .layui-nav-child a:hover {\n    background-color: #f2f2f2;\n    color: #333\n}\n\n.layui-nav-child dd {\n    position: relative\n}\n\n.layui-nav-child dd.layui-this {\n    background-color: #5FB878;\n    color: #fff\n}\n\n.layui-nav-child dd.layui-this a {\n    color: #fff\n}\n\n.layui-nav-child dd.layui-this:after {\n    display: none\n}\n\n.layui-nav-tree {\n    width: 200px;\n    padding: 0\n}\n\n.layui-nav-tree .layui-nav-item {\n    display: block;\n    width: 100%;\n    line-height: 45px\n}\n\n.layui-nav-tree .layui-nav-item a {\n    height: 45px;\n    text-overflow: ellipsis;\n    overflow: hidden;\n    white-space: nowrap\n}\n\n.layui-nav-tree .layui-nav-item a:hover {\n    background-color: #4E5465\n}\n\n.layui-nav-tree .layui-nav-child dd.layui-this,\n.layui-nav-tree .layui-this,\n.layui-nav-tree .layui-this>a,\n.layui-nav-tree .layui-this>a:hover {\n    background-color: #009688;\n    color: #fff\n}\n\n.layui-nav-tree .layui-this:after {\n    display: none\n}\n\n.layui-nav-itemed>a,\n.layui-nav-tree .layui-nav-title a,\n.layui-nav-tree .layui-nav-title a:hover {\n    background-color: #2B2E37!important;\n    color: #fff!important\n}\n\n.layui-nav-tree .layui-nav-bar {\n    width: 5px;\n    height: 0;\n    background-color: #009688\n}\n\n.layui-nav-tree .layui-nav-child {\n    position: relative;\n    z-index: 0;\n    top: 0;\n    border: none;\n    box-shadow: none\n}\n\n.layui-nav-tree .layui-nav-child a {\n    height: 40px;\n    line-height: 40px;\n    color: #c2c2c2\n}\n\n.layui-nav-tree .layui-nav-child,\n.layui-nav-tree .layui-nav-child a:hover {\n    background: 0 0;\n    color: #fff\n}\n\n.layui-nav-tree .layui-nav-more {\n    top: 20px;\n    right: 10px\n}\n\n.layui-nav-itemed .layui-nav-more {\n    top: 14px\n}\n\n.layui-nav-itemed .layui-nav-child {\n    display: block;\n    padding: 0\n}\n\n.layui-nav-side {\n    position: fixed;\n    top: 0;\n    bottom: 0;\n    left: 0;\n    overflow-x: hidden;\n    z-index: 999\n}\n\n.layui-breadcrumb {\n    visibility: hidden;\n    font-size: 0\n}\n\n.layui-breadcrumb a {\n    padding-right: 8px;\n    line-height: 22px;\n    font-size: 14px;\n    color: #333!important\n}\n\n.layui-breadcrumb a:hover {\n    color: #01AAED!important\n}\n\n.layui-breadcrumb a cite,\n.layui-breadcrumb a span {\n    color: #666;\n    cursor: text;\n    font-style: normal\n}\n\n.layui-breadcrumb a span {\n    padding-left: 8px;\n    font-family: Sim sun\n}\n\n.layui-tab {\n    margin: 10px 0;\n    overflow: hidden;\n    text-align: left!important\n}\n\n.layui-fixbar li,\n.layui-tab-bar,\n.layui-tab-title li,\n.layui-util-face ul li {\n    cursor: pointer;\n    text-align: center\n}\n\n.layui-tab-title {\n    position: relative;\n    left: 0;\n    height: 40px;\n    white-space: nowrap;\n    font-size: 0;\n    border-bottom: 1px solid #e2e2e2;\n    transition: all .2s;\n    -webkit-transition: all .2s\n}\n\n.layui-tab-title li {\n    *display: inline;\n    font-size: 14px;\n    transition: all .3s;\n    -webkit-transition: all .3s;\n    position: relative;\n    line-height: 40px;\n    min-width: 65px;\n    padding: 0 10px\n}\n\n.layui-tab-title .layui-this {\n    color: #000\n}\n\n.layui-tab-title .layui-this:after {\n    position: absolute;\n    left: 0;\n    top: 0;\n    content: '';\n    width: 100%;\n    height: 41px;\n    border: 1px solid #e2e2e2;\n    border-bottom-color: #fff;\n    border-radius: 2px 2px 0 0;\n    -webkit-box-sizing: border-box!important;\n    -moz-box-sizing: border-box!important;\n    box-sizing: border-box!important;\n    pointer-events: none\n}\n\n.layui-tab-bar {\n    position: absolute;\n    right: 0;\n    top: 0;\n    width: 30px;\n    height: 39px;\n    line-height: 39px;\n    border: 1px solid #e2e2e2;\n    border-radius: 2px;\n    background-color: #fff\n}\n\n.layui-tab-bar .layui-icon {\n    position: relative;\n    display: inline-block;\n    top: 3px;\n    transition: all .3s;\n    -webkit-transition: all .3s\n}\n\n.layui-tab-item,\n.layui-util-face .layui-layer-TipsG {\n    display: none\n}\n\n.layui-tab-more {\n    padding-right: 30px;\n    height: auto;\n    white-space: normal\n}\n\n.layui-tab-more li.layui-this:after {\n    border-bottom-color: #e2e2e2;\n    border-radius: 2px\n}\n\n.layui-tab-more .layui-tab-bar .layui-icon {\n    top: -2px;\n    top: 3px\\9;\n    -webkit-transform: rotate(180deg);\n    transform: rotate(180deg)\n}\n\n:root .layui-tab-more .layui-tab-bar .layui-icon {\n    top: -2px\\0/IE9\n}\n\n.layui-tab-content {\n    padding: 10px\n}\n\n.layui-tab-title li .layui-tab-close {\n    position: relative;\n    margin-left: 8px;\n    top: 1px;\n    color: #c2c2c2\n}\n\n.layui-tab-title li .layui-tab-close:hover {\n    border-radius: 10px;\n    background-color: #FF5722;\n    color: #fff\n}\n\n.layui-tab-brief>.layui-tab-title .layui-this {\n    color: #009688\n}\n\n.layui-tab-brief>.layui-tab-more li.layui-this:after,\n.layui-tab-brief>.layui-tab-title .layui-this:after {\n    border: none;\n    border-radius: 0;\n    border-bottom: 3px solid #5FB878\n}\n\n.layui-tab-card {\n    border: 1px solid #e2e2e2;\n    border-radius: 2px;\n    box-shadow: 0 2px 5px 0 rgba(0, 0, 0, .1)\n}\n\n.layui-tab-card>.layui-tab-title {\n    background-color: #f2f2f2\n}\n\n.layui-tab-card>.layui-tab-title li {\n    margin-right: -1px;\n    margin-left: -1px\n}\n\n.layui-tab-card>.layui-tab-title .layui-this {\n    background-color: #fff\n}\n\n.layui-tab-card>.layui-tab-title .layui-this:after {\n    border-top: none;\n    border-width: 1px;\n    border-bottom-color: #fff\n}\n\n.layui-tab-card>.layui-tab-title .layui-tab-bar {\n    height: 40px;\n    line-height: 40px;\n    border-radius: 0;\n    border-top: none;\n    border-right: none\n}\n\n.layui-tab-card>.layui-tab-more .layui-this {\n    background: 0 0;\n    color: #5FB878\n}\n\n.layui-tab-card>.layui-tab-more .layui-this:after {\n    border: none\n}\n\n.layui-fixbar {\n    position: fixed;\n    right: 15px;\n    bottom: 15px;\n    z-index: 9999\n}\n\n.layui-fixbar li {\n    width: 50px;\n    height: 50px;\n    line-height: 50px;\n    margin-bottom: 1px;\n    font-size: 30px;\n    background-color: #9F9F9F;\n    color: #fff;\n    border-radius: 2px;\n    opacity: .95\n}\n\n.layui-fixbar li:hover {\n    opacity: .85\n}\n\n.layui-fixbar li:active {\n    opacity: 1\n}\n\n.layui-fixbar .layui-fixbar-top {\n    display: none;\n    font-size: 40px\n}\n\nbody .layui-util-face {\n    border: none;\n    background: 0 0\n}\n\nbody .layui-util-face .layui-layer-content {\n    padding: 0;\n    background-color: #fff;\n    color: #666;\n    box-shadow: none\n}\n\n.layui-util-face ul {\n    position: relative;\n    width: 372px;\n    padding: 10px;\n    border: 1px solid #D9D9D9;\n    background-color: #fff;\n    box-shadow: 0 0 20px rgba(0, 0, 0, .2)\n}\n\n.layui-util-face ul li {\n    float: left;\n    border: 1px solid #e8e8e8;\n    height: 22px;\n    width: 26px;\n    overflow: hidden;\n    margin: -1px 0 0 -1px;\n    padding: 4px 2px\n}\n\n.layui-util-face ul li:hover {\n    position: relative;\n    z-index: 2;\n    border: 1px solid #eb7350;\n    background: #fff9ec\n}\n\n.layui-anim {\n    -webkit-animation-duration: .3s;\n    animation-duration: .3s;\n    -webkit-animation-fill-mode: both;\n    animation-fill-mode: both\n}\n\n.layui-anim-loop {\n    -webkit-animation-iteration-count: infinite;\n    animation-iteration-count: infinite\n}\n\n@-webkit-keyframes layui-rotate {\n    from {\n        -webkit-transform: rotate(0)\n    }\n    to {\n        -webkit-transform: rotate(360deg)\n    }\n}\n\n@keyframes layui-rotate {\n    from {\n        transform: rotate(0)\n    }\n    to {\n        transform: rotate(360deg)\n    }\n}\n\n.layui-anim-rotate {\n    -webkit-animation-name: layui-rotate;\n    animation-name: layui-rotate;\n    -webkit-animation-duration: 1s;\n    animation-duration: 1s;\n    -webkit-animation-timing-function: linear;\n    animation-timing-function: linear\n}\n\n@-webkit-keyframes layui-up {\n    from {\n        -webkit-transform: translate3d(0, 100%, 0);\n        opacity: .3\n    }\n    to {\n        -webkit-transform: translate3d(0, 0, 0);\n        opacity: 1\n    }\n}\n\n@keyframes layui-up {\n    from {\n        transform: translate3d(0, 100%, 0);\n        opacity: .3\n    }\n    to {\n        transform: translate3d(0, 0, 0);\n        opacity: 1\n    }\n}\n\n.layui-anim-up {\n    -webkit-animation-name: layui-up;\n    animation-name: layui-up\n}\n\n@-webkit-keyframes layui-upbit {\n    from {\n        -webkit-transform: translate3d(0, 30px, 0);\n        opacity: .3\n    }\n    to {\n        -webkit-transform: translate3d(0, 0, 0);\n        opacity: 1\n    }\n}\n\n@keyframes layui-upbit {\n    from {\n        transform: translate3d(0, 30px, 0);\n        opacity: .3\n    }\n    to {\n        transform: translate3d(0, 0, 0);\n        opacity: 1\n    }\n}\n\n.layui-anim-upbit {\n    -webkit-animation-name: layui-upbit;\n    animation-name: layui-upbit\n}\n\n@-webkit-keyframes layui-scale {\n    0% {\n        opacity: .3;\n        -webkit-transform: scale(.5)\n    }\n    100% {\n        opacity: 1;\n        -webkit-transform: scale(1)\n    }\n}\n\n@keyframes layui-scale {\n    0% {\n        opacity: .3;\n        -ms-transform: scale(.5);\n        transform: scale(.5)\n    }\n    100% {\n        opacity: 1;\n        -ms-transform: scale(1);\n        transform: scale(1)\n    }\n}\n\n.layui-anim-scale {\n    -webkit-animation-name: layui-scale;\n    animation-name: layui-scale\n}\n\n@-webkit-keyframes layui-scale-spring {\n    0% {\n        opacity: .5;\n        -webkit-transform: scale(.5)\n    }\n    80% {\n        opacity: .8;\n        -webkit-transform: scale(1.1)\n    }\n    100% {\n        opacity: 1;\n        -webkit-transform: scale(1)\n    }\n}\n\n@keyframes layui-scale-spring {\n    0% {\n        opacity: .5;\n        -ms-transform: scale(.5);\n        transform: scale(.5)\n    }\n    80% {\n        opacity: .8;\n        -ms-transform: scale(1.1);\n        transform: scale(1.1)\n    }\n    100% {\n        opacity: 1;\n        -ms-transform: scale(1);\n        transform: scale(1)\n    }\n}\n\n.layui-anim-scaleSpring {\n    -webkit-animation-name: layui-scale-spring;\n    animation-name: layui-scale-spring\n}\n\n@media screen and (max-width:450px) {\n    .layui-form-item .layui-form-label {\n        text-overflow: ellipsis;\n        overflow: hidden;\n        white-space: nowrap\n    }\n    .layui-form-item .layui-inline {\n        display: block;\n        margin-right: 0;\n        margin-bottom: 20px;\n        clear: both\n    }\n    .layui-form-item .layui-inline:after {\n        content: '\\20';\n        clear: both;\n        display: block;\n        height: 0\n    }\n    .layui-form-item .layui-input-inline {\n        display: block;\n        float: none;\n        left: -1px;\n        width: auto;\n        margin: 0 0 10px 112px\n    }\n    .layui-form-item .layui-input-inline+.layui-form-mid {\n        margin-left: 110px;\n        top: -5px;\n        padding: 0\n    }\n    .layui-form-item .layui-form-checkbox {\n        margin-right: 5px;\n        margin-bottom: 5px\n    }\n}\n"
  },
  {
    "path": "public/static/layui/css/modules/code.css",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n html #layuicss-skincodecss{display:none;position:absolute;width:1989px}.layui-code-h3,.layui-code-view{position:relative;font-size:12px}.layui-code-view{display:block;margin:10px 0;padding:0;border:1px solid #ddd;border-left-width:6px;background-color:#F2F2F2;color:#333;font-family:Courier New}.layui-code-h3{padding:0 10px;height:30px;line-height:30px;border-bottom:1px solid #ddd}.layui-code-h3 a{position:absolute;right:10px;top:0;color:#999}.layui-code-view .layui-code-ol{position:relative;overflow:auto}.layui-code-view .layui-code-ol li{position:relative;margin-left:45px;line-height:20px;padding:0 5px;border-left:1px solid #ddd;list-style-type:decimal-leading-zero;*list-style-type:decimal;background-color:#fff}.layui-code-view pre{margin:0}.layui-code-notepad{border:1px solid #0C0C0C;border-left-color:#3F3F3F;background-color:#0C0C0C;color:#C2BE9E}.layui-code-notepad .layui-code-h3{border-bottom:none}.layui-code-notepad .layui-code-ol li{background-color:#3F3F3F;border-left:none}"
  },
  {
    "path": "public/static/layui/css/modules/laydate/laydate.css",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n #layuicss-laydatecss{display:none;position:absolute;width:1989px}.laydate_body .laydate_box,.laydate_body .laydate_box *{margin:0;padding:0;box-sizing:content-box}.laydate-icon,.laydate-icon-dahong,.laydate-icon-danlan,.laydate-icon-default,.laydate-icon-molv{height:22px;line-height:22px;padding-right:20px;border:1px solid #C6C6C6;background-repeat:no-repeat;background-position:right center;background-color:#fff;outline:0}.laydate-icon-default{background-image:url(../skins/default/icon.png)}.laydate-icon-danlan{border:1px solid #B1D2EC;background-image:url(../skins/danlan/icon.png)}.laydate-icon-dahong{background-image:url(../skins/dahong/icon.png)}.laydate-icon-molv{background-image:url(../skins/molv/icon.png)}.laydate_body .laydate_box{width:240px;font:12px '\\5B8B\\4F53';z-index:99999999;*overflow:hidden;_margin:0;_position:absolute!important}.laydate_body .laydate_box li{list-style:none}.laydate_body .laydate_box .laydate_void{cursor:text!important}.laydate_body .laydate_box cite,.laydate_body .laydate_box label{position:absolute;width:0;height:0;border-width:5px;border-style:dashed;border-color:transparent;overflow:hidden;cursor:pointer}.laydate_body .laydate_box .laydate_time,.laydate_body .laydate_box .laydate_yms{display:none}.laydate_body .laydate_box .laydate_show{display:block}.laydate_body .laydate_box input{outline:0;font-size:14px;background-color:#fff;color:#333}.laydate_body .laydate_top{position:relative;height:26px;padding:5px;*width:100%;z-index:99}.laydate_body .laydate_ym{position:relative;float:left;height:24px;cursor:pointer}.laydate_body .laydate_ym input{float:left;height:24px;line-height:24px;text-align:center;border:none;cursor:pointer}.laydate_body .laydate_ym .laydate_yms{position:absolute;left:-1px;top:24px;height:181px}.laydate_body .laydate_y{width:121px;margin-right:6px}.laydate_body .laydate_y input{width:64px;margin-right:15px}.laydate_body .laydate_y .laydate_yms{width:121px;text-align:center}.laydate_body .laydate_y .laydate_yms a{position:relative;display:block;height:20px}.laydate_body .laydate_y .laydate_yms ul{height:139px;padding:0;*overflow:hidden}.laydate_body .laydate_y .laydate_yms ul li{float:left;width:60px;height:20px;line-height:20px;text-overflow:ellipsis;overflow:hidden;white-space:nowrap}.laydate_body .laydate_m{width:99px}.laydate_body .laydate_m .laydate_yms{width:99px;padding:0}.laydate_body .laydate_m input{width:42px;margin-right:15px}.laydate_body .laydate_m .laydate_yms span{display:block;float:left;width:42px;margin:5px 0 0 5px;line-height:24px;text-align:center;_display:inline}.laydate_body .laydate_choose{display:block;float:left;position:relative;width:20px;height:24px}.laydate_body .laydate_choose cite,.laydate_body .laydate_tab cite{left:50%;top:50%}.laydate_body .laydate_chtop cite{margin:-7px 0 0 -5px;border-bottom-style:solid}.laydate_body .laydate_chdown cite,.laydate_body .laydate_ym label{top:50%;margin:-2px 0 0 -5px;border-top-style:solid}.laydate_body .laydate_chprev cite{margin:-5px 0 0 -7px}.laydate_body .laydate_chnext cite{margin:-5px 0 0 -2px}.laydate_body .laydate_ym label{right:28px}.laydate_body .laydate_table{width:230px;margin:0 5px;border-collapse:collapse;border-spacing:0}.laydate_body .laydate_table td{width:31px;text-align:center;cursor:pointer;font-size:12px}.laydate_body .laydate_table thead th{font-weight:400;font-size:12px;text-align:center}.laydate_body .laydate_bottom{position:relative;height:22px;line-height:20px;padding:5px;font-size:12px}.laydate_body .laydate_bottom #laydate_hms{position:relative;z-index:1;float:left}.laydate_body .laydate_time{position:absolute;left:5px;bottom:26px;width:129px;height:125px;*overflow:hidden}.laydate_body .laydate_time .laydate_hmsno{padding:5px 0 0 5px}.laydate_body .laydate_time .laydate_hmsno span{display:block;float:left;width:24px;height:19px;line-height:19px;text-align:center;cursor:pointer;*margin-bottom:-5px}.laydate_body .laydate_time1{width:228px;height:154px}.laydate_body .laydate_time1 .laydate_hmsno{padding:6px 0 0 8px}.laydate_body .laydate_time1 .laydate_hmsno span{width:21px;height:20px;line-height:20px}.laydate_body .laydate_msg{left:49px;bottom:67px;width:141px;height:auto;overflow:hidden}.laydate_body .laydate_msg p{padding:5px 10px}.laydate_body .laydate_bottom li{float:left;height:20px;line-height:20px;border-right:none;font-weight:900}.laydate_body .laydate_bottom .laydate_sj{width:33px;text-align:center;font-weight:400}.laydate_body .laydate_bottom input{float:left;width:21px;height:20px;line-height:20px;border:none;text-align:center;cursor:pointer;font-size:12px;font-weight:400}.laydate_body .laydate_bottom .laydte_hsmtex{height:20px;line-height:20px;text-align:center}.laydate_body .laydate_bottom .laydte_hsmtex span{position:absolute;width:20px;top:0;right:0;cursor:pointer}.laydate_body .laydate_bottom .laydte_hsmtex span:hover{font-size:14px}.laydate_body .laydate_bottom .laydate_btn{position:absolute;right:5px;top:5px}.laydate_body .laydate_bottom .laydate_btn a{float:left;height:20px;padding:0 6px;_padding:0 5px}.laydate_body .laydate_table td,.laydate_body .laydate_table thead{height:21px!important;line-height:21px!important}.laydate-icon{border:1px solid #C6C6C6;background-image:url(icon.png)}.laydate_body .laydate_bottom #laydate_hms,.laydate_body .laydate_bottom .laydate_btn a,.laydate_body .laydate_box,.laydate_body .laydate_table,.laydate_body .laydate_table td,.laydate_body .laydate_time,.laydate_body .laydate_ym,.laydate_body .laydate_ym .laydate_yms{border:1px solid #ccc}.laydate_body .laydate_bottom .laydte_hsmtex,.laydate_body .laydate_choose,.laydate_body .laydate_table thead,.laydate_body .laydate_y .laydate_yms a{background-color:#F6F6F6}.laydate_body .laydate_box,.laydate_body .laydate_time,.laydate_body .laydate_ym .laydate_yms{box-shadow:2px 2px 5px rgba(0,0,0,.1)}.laydate_body .laydate_box{border-top:none;border-bottom:none;background-color:#fff;color:#333}.laydate_body .laydate_box .laydate_void{color:#ccc!important}.laydate_body .laydate_box .laydate_void:hover{background-color:#fff!important}.laydate_body .laydate_box a,.laydate_body .laydate_box a:hover{text-decoration:none;blr:expression(this.onFocus=this.blur());cursor:pointer;color:#333}.laydate_body .laydate_box a:hover{text-decoration:none;color:#666}.laydate_body .laydate_click{background-color:#eee!important}.laydate_body .laydate_bottom #laydate_hms,.laydate_body .laydate_choose:hover,.laydate_body .laydate_table td,.laydate_body .laydate_time,.laydate_body .laydate_y .laydate_yms a:hover{background-color:#fff}.laydate_body .laydate_top{border-top:1px solid #C6C6C6}.laydate_body .laydate_ym .laydate_yms{border:1px solid #C6C6C6;background-color:#fff}.laydate_body .laydate_y .laydate_yms a{border-bottom:1px solid #C6C6C6}.laydate_body .laydate_y .laydate_yms .laydate_chdown{border-top:1px solid #C6C6C6;border-bottom:none}.laydate_body .laydate_choose{border-left:1px solid #C6C6C6}.laydate_body .laydate_chprev{border-left:none;border-right:1px solid #C6C6C6}.laydate_body .laydate_chtop cite{border-bottom-color:#666}.laydate_body .laydate_chdown cite,.laydate_body .laydate_ym label{border-top-color:#666}.laydate_body .laydate_chprev cite{border-right-style:solid;border-right-color:#666}.laydate_body .laydate_chnext cite{border-left-style:solid;border-left-color:#666}.laydate_body .laydate_table td{border:none}.laydate_body .laydate_table .laydate_nothis{color:#999}.laydate_body .laydate_table thead th{border-bottom:1px solid #ccc}.laydate_body .laydate_bottom,.laydate_body .laydate_bottom .laydte_hsmtex{border-bottom:1px solid #C6C6C6}.laydate_body .laydate_bottom .laydate_sj{border-right:1px solid #C6C6C6;background-color:#F6F6F6}.laydate_body .laydate_bottom input{background-color:#fff}.laydate_body .laydate_bottom .laydate_btn{border-right:1px solid #C6C6C6}.laydate_body .laydate_bottom .laydate_v{position:absolute;left:10px;top:6px;font-family:Courier;z-index:0;color:#999}.laydate_body .laydate_bottom .laydate_btn a{border-right:none;background-color:#F6F6F6}.laydate_body .laydate_bottom .laydate_btn a:hover{color:#000;background-color:#fff}.laydate_body .laydate_m .laydate_yms span:hover,.laydate_body .laydate_table td:hover,.laydate_body .laydate_time .laydate_hmsno span:hover,.laydate_body .laydate_y .laydate_yms ul li:hover{background-color:#F3F3F3}"
  },
  {
    "path": "public/static/layui/css/modules/layer/default/layer.css",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n .layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span,.layui-layer-title{text-overflow:ellipsis;white-space:nowrap}*html{background-image:url(about:blank);background-attachment:fixed}html #layuicss-skinlayercss{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+\"px\")}.layui-layer{-webkit-overflow-scrolling:touch;top:150px;left:0;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;box-shadow:1px 1px 50px rgba(0,0,0,.3)}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.1);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-load{background:url(loading-1.gif) center center no-repeat #eee}.layui-layer-ico{background:url(icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-move{display:none;position:fixed;*position:absolute;left:0;top:0;width:100%;height:100%;cursor:move;opacity:0;filter:alpha(opacity=0);background-color:#fff;z-index:2147483647}.layui-layer-resize{position:absolute;width:15px;height:15px;right:0;bottom:0;cursor:se-resize}.layui-layer{border-radius:2px;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-01{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layer-anim-02{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layer-anim-03{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layer-anim-04{-webkit-animation-name:rollIn;animation-name:rollIn}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layer-anim-05{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layer-anim-06{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}@-webkit-keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.05);-ms-transform:scale(1.05);transform:scale(1.05)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layer-anim-close{-webkit-animation-name:bounceOut;animation-name:bounceOut;-webkit-animation-duration:.2s;animation-duration:.2s}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:0 -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-149px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-180px -31px}.layui-layer-btn{text-align:right;padding:0 10px 12px;pointer-events:auto;user-select:none;-webkit-user-select:none}.layui-layer-btn a{height:28px;line-height:28px;margin:0 6px;padding:0 15px;border:1px solid #dedede;background-color:#f1f1f1;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.8}.layui-layer-btn .layui-layer-btn0{border-color:#4898d5;background-color:#2e8ded;color:#fff}.layui-layer-btn-l{text-align:left}.layui-layer-btn-c{text-align:center}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;overflow:hidden;font-size:14px;overflow-x:hidden;overflow-y:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:5px 10px;font-size:12px;_float:left;border-radius:2px;box-shadow:1px 1px 3px rgba(0,0,0,.2);background-color:#000;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#000}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:1px;border-bottom-style:solid;border-bottom-color:#000}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-btn{padding:10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#BBB5B5;border:none}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}.layui-layer-iconext{background:url(icon-ext.png) no-repeat}.layui-layer-prompt .layui-layer-input{display:block;width:220px;height:30px;margin:0 auto;line-height:30px;padding:0 5px;border:1px solid #ccc;box-shadow:1px 1px 5px rgba(0,0,0,.1) inset;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px}.layui-layer-prompt .layui-layer-content{padding:20px}.layui-layer-prompt .layui-layer-btn{padding-top:0}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;border-bottom:1px solid #ccc;background-color:#eee;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;cursor:default;overflow:hidden}.layui-layer-tab .layui-layer-title span.layui-layer-tabnow{height:43px;border-left:1px solid #ccc;border-right:1px solid #ccc;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.xubox_tab_layer{display:block}.xubox_tabclose{position:absolute;right:10px;top:5px;cursor:pointer}.layui-layer-photos{-webkit-animation-duration:1s;animation-duration:1s}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal}@media screen and (max-width:1100px){.layui-layer-iframe{overflow-y:auto;-webkit-overflow-scrolling:touch}}"
  },
  {
    "path": "public/static/layui/lay/dest/layui.all.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;!function(e){\"use strict\";var t=function(){this.v=\"1.0.7\"};t.fn=t.prototype;var n=document,o=t.fn.cache={},i=function(){var e=n.scripts,t=e[e.length-1].src;return t.substring(0,t.lastIndexOf(\"/\")+1)}(),r=function(t){e.console&&console.error&&console.error(\"Layui hint: \"+t)},u=\"undefined\"!=typeof opera&&\"[object Opera]\"===opera.toString(),l={layer:\"modules/layer\",laydate:\"modules/laydate\",laypage:\"modules/laypage\",laytpl:\"modules/laytpl\",layim:\"modules/layim\",layedit:\"modules/layedit\",form:\"modules/form\",upload:\"modules/upload\",tree:\"modules/tree\",slide:\"modules/slide\",table:\"modules/table\",element:\"modules/element\",util:\"modules/util\",flow:\"modules/flow\",code:\"modules/code\",single:\"modules/single\",mobile:\"modules/mobile\",jquery:\"lib/jquery\",\"layui.mod\":\"dest/layui.mod\"};o.modules={},o.status={},o.timeout=10,o.event={},t.fn.define=function(e,t){var n=this,i=\"function\"==typeof e,r=function(){return\"function\"==typeof t&&t(function(e,t){layui[e]=t,o.status[e]=!0}),this};return i&&(t=e,e=[]),layui[\"layui.all\"]?r.call(n):(n.use(e,r),n)},t.fn.use=function(e,t,a){function s(e,t){var n=\"PLaySTATION 3\"===navigator.platform?/^complete$/:/^(complete|loaded)$/;(\"load\"===e.type||n.test((e.currentTarget||e.srcElement).readyState))&&(o.modules[m]=t,y.removeChild(v),function i(){return++p>1e3*o.timeout/4?r(m+\" is not a valid module\"):void(o.status[m]?c():setTimeout(i,4))}())}function c(){a.push(layui[m]),e.length>1?f.use(e.slice(1),t,a):\"function\"==typeof t&&t.apply(layui,a)}var f=this,d=o.dir=o.dir?o.dir:i,y=n.getElementsByTagName(\"head\")[0];e=\"string\"==typeof e?[e]:e,window.jQuery&&jQuery.fn.on&&(f.each(e,function(t,n){\"jquery\"===n&&e.splice(t,1)}),layui.jquery=jQuery);var m=e[0],p=0;if(a=a||[],o.host=o.host||(d.match(/\\/\\/([\\s\\S]+?)\\//)||[\"//\"+location.host+\"/\"])[0],0===e.length||layui[\"layui.all\"]&&l[m])return\"function\"==typeof t&&t.apply(layui,a),f;var v=n.createElement(\"script\"),h=(l[m]?d+\"lay/\":o.base||\"\")+(f.modules[m]||m)+\".js\";return v.async=!0,v.charset=\"utf-8\",v.src=h+function(){var e=o.version===!0?o.v||(new Date).getTime():o.version||\"\";return e?\"?v=\"+e:\"\"}(),o.modules[m]?!function g(){return++p>1e3*o.timeout/4?r(m+\" is not a valid module\"):void(\"string\"==typeof o.modules[m]&&o.status[m]?c():setTimeout(g,4))}():(y.appendChild(v),!v.attachEvent||v.attachEvent.toString&&v.attachEvent.toString().indexOf(\"[native code\")<0||u?v.addEventListener(\"load\",function(e){s(e,h)},!1):v.attachEvent(\"onreadystatechange\",function(e){s(e,h)})),o.modules[m]=h,f},t.fn.getStyle=function(t,n){var o=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return o[o.getPropertyValue?\"getPropertyValue\":\"getAttribute\"](n)},t.fn.link=function(e,t,i){var u=this,l=n.createElement(\"link\"),a=n.getElementsByTagName(\"head\")[0];\"string\"==typeof t&&(i=t);var s=(i||e).replace(/\\.|\\//g,\"\"),c=l.id=\"layuicss-\"+s,f=0;l.rel=\"stylesheet\",l.href=e+(o.debug?\"?v=\"+(new Date).getTime():\"\"),l.media=\"all\",n.getElementById(c)||a.appendChild(l),\"function\"==typeof t&&!function d(){return++f>1e3*o.timeout/100?r(e+\" timeout\"):void(1989===parseInt(u.getStyle(n.getElementById(c),\"width\"))?function(){t()}():setTimeout(d,100))}()},t.fn.addcss=function(e,t,n){layui.link(o.dir+\"css/\"+e,t,n)},t.fn.img=function(e,t,n){var o=new Image;return o.src=e,o.complete?t(o):(o.onload=function(){o.onload=null,t(o)},void(o.onerror=function(e){o.onerror=null,n(e)}))},t.fn.config=function(e){e=e||{};for(var t in e)o[t]=e[t];return this},t.fn.modules=function(){var e={};for(var t in l)e[t]=l[t];return e}(),t.fn.extend=function(e){var t=this;e=e||{};for(var n in e)t[n]||t.modules[n]?r(\"模块名 \"+n+\" 已被占用\"):t.modules[n]=e[n];return t},t.fn.router=function(e){for(var t,n=(e||location.hash).replace(/^#/,\"\").split(\"/\")||[],o={dir:[]},i=0;i<n.length;i++)t=n[i].split(\"=\"),/^\\w+=/.test(n[i])?function(){\"dir\"!==t[0]&&(o[t[0]]=t[1])}():o.dir.push(n[i]),t=null;return o},t.fn.data=function(t,n){if(t=t||\"layui\",e.JSON&&e.JSON.parse){if(null===n)return delete localStorage[t];n=\"object\"==typeof n?n:{key:n};try{var o=JSON.parse(localStorage[t])}catch(i){var o={}}return n.value&&(o[n.key]=n.value),n.remove&&delete o[n.key],localStorage[t]=JSON.stringify(o),n.key?o[n.key]:o}},t.fn.device=function(t){var n=navigator.userAgent.toLowerCase(),o=function(e){var t=new RegExp(e+\"/([^\\\\s\\\\_\\\\-]+)\");return e=(n.match(t)||[])[1],e||!1},i={os:function(){return/windows/.test(n)?\"windows\":/linux/.test(n)?\"linux\":/iphone|ipod|ipad|ios/.test(n)?\"ios\":void 0}(),ie:function(){return!!(e.ActiveXObject||\"ActiveXObject\"in e)&&((n.match(/msie\\s(\\d+)/)||[])[1]||\"11\")}(),weixin:o(\"micromessenger\")};return t&&!i[t]&&(i[t]=o(t)),i.android=/android/.test(n),i.ios=\"ios\"===i.os,i},t.fn.hint=function(){return{error:r}},t.fn.each=function(e,t){var n,o=this;if(\"function\"!=typeof t)return o;if(e=e||[],e.constructor===Object){for(n in e)if(t.call(e[n],n,e[n]))break}else for(n=0;n<e.length&&!t.call(e[n],n,e[n]);n++);return o},t.fn.stope=function(t){t=t||e.event,t.stopPropagation?t.stopPropagation():t.cancelBubble=!0},t.fn.onevent=function(e,t,n){return\"string\"!=typeof e||\"function\"!=typeof n?this:(o.event[e+\".\"+t]=[n],this)},t.fn.event=function(e,t,n){var i=this,r=null,u=t.match(/\\(.*\\)$/)||[],l=(t=e+\".\"+t).replace(u,\"\"),a=function(e,t){var o=t&&t.call(i,n);o===!1&&null===r&&(r=!1)};return layui.each(o.event[l],a),u[0]&&layui.each(o.event[t],a),r},e.layui=new t}(window);layui.define(function(a){var i=layui.cache;layui.config({dir:i.dir.replace(/lay\\/dest\\/$/,\"\")}),a(\"layui.all\",layui.v)});layui.define(function(e){\"use strict\";var r={open:\"{{\",close:\"}}\"},n={exp:function(e){return new RegExp(e,\"g\")},query:function(e,n,t){var o=[\"#([\\\\s\\\\S])+?\",\"([^{#}])*?\"][e||0];return c((n||\"\")+r.open+o+r.close+(t||\"\"))},escape:function(e){return String(e||\"\").replace(/&(?!#?[a-zA-Z0-9]+;)/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/'/g,\"&#39;\").replace(/\"/g,\"&quot;\")},error:function(e,r){var n=\"Laytpl Error：\";return\"object\"==typeof console&&console.error(n+e+\"\\n\"+(r||\"\")),n+e}},c=n.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(e,t){var o=this,p=e,a=c(\"^\"+r.open+\"#\",\"\"),l=c(r.close+\"$\",\"\");e=e.replace(/\\s+|\\r|\\t|\\n/g,\" \").replace(c(r.open+\"#\"),r.open+\"# \").replace(c(r.close+\"}\"),\"} \"+r.close).replace(/\\\\/g,\"\\\\\\\\\").replace(/(?=\"|')/g,\"\\\\\").replace(n.query(),function(e){return e=e.replace(a,\"\").replace(l,\"\"),'\";'+e.replace(/\\\\/g,\"\")+';view+=\"'}).replace(n.query(1),function(e){var n='\"+(';return e.replace(/\\s/g,\"\")===r.open+r.close?\"\":(e=e.replace(c(r.open+\"|\"+r.close),\"\"),/^=/.test(e)&&(e=e.replace(/^=/,\"\"),n='\"+_escape_('),n+e.replace(/\\\\/g,\"\")+')+\"')}),e='\"use strict\";var view = \"'+e+'\";return view;';try{return o.cache=e=new Function(\"d, _escape_\",e),e(t,n.escape)}catch(u){return delete o.cache,n.error(u,p)}},t.pt.render=function(e,r){var c,t=this;return e?(c=t.cache?t.cache(e,n.escape):t.parse(t.tpl,e),r?void r(c):c):n.error(\"no data\")};var o=function(e){return\"string\"!=typeof e?n.error(\"Template not found\"):new t(e)};o.config=function(e){e=e||{};for(var n in e)r[n]=e[n]},o.v=\"1.2.0\",e(\"laytpl\",o)});layui.define(function(a){\"use strict\";function t(a){new p(a)}var e=document,r=\"getElementById\",n=\"getElementsByTagName\",s=0,p=function(a){var t=this,e=t.config=a||{};e.item=s++,t.render(!0)};p.on=function(a,t,e){return a.attachEvent?a.attachEvent(\"on\"+t,function(){e.call(a,window.even)}):a.addEventListener(t,e,!1),p},p.prototype.type=function(){var a=this.config;if(\"object\"==typeof a.cont)return void 0===a.cont.length?2:3},p.prototype.view=function(){var a=this,t=a.config,e=[],r={};if(t.pages=0|t.pages,t.curr=0|t.curr||1,t.groups=\"groups\"in t?0|t.groups:5,t.first=\"first\"in t?t.first:\"&#x9996;&#x9875;\",t.last=\"last\"in t?t.last:\"&#x672B;&#x9875;\",t.prev=\"prev\"in t?t.prev:\"&#x4E0A;&#x4E00;&#x9875;\",t.next=\"next\"in t?t.next:\"&#x4E0B;&#x4E00;&#x9875;\",t.pages<=1)return\"\";for(t.groups>t.pages&&(t.groups=t.pages),r.index=Math.ceil((t.curr+(t.groups>1&&t.groups!==t.pages?1:0))/(0===t.groups?1:t.groups)),t.curr>1&&t.prev&&e.push('<a href=\"javascript:;\" class=\"layui-laypage-prev\" data-page=\"'+(t.curr-1)+'\">'+t.prev+\"</a>\"),r.index>1&&t.first&&0!==t.groups&&e.push('<a href=\"javascript:;\" class=\"laypage_first\" data-page=\"1\"  title=\"&#x9996;&#x9875;\">'+t.first+\"</a><span>&#x2026;</span>\"),r.poor=Math.floor((t.groups-1)/2),r.start=r.index>1?t.curr-r.poor:1,r.end=r.index>1?function(){var a=t.curr+(t.groups-r.poor-1);return a>t.pages?t.pages:a}():t.groups,r.end-r.start<t.groups-1&&(r.start=r.end-t.groups+1);r.start<=r.end;r.start++)r.start===t.curr?e.push('<span class=\"layui-laypage-curr\"><em class=\"layui-laypage-em\" '+(/^#/.test(t.skin)?'style=\"background-color:'+t.skin+';\"':\"\")+\"></em><em>\"+r.start+\"</em></span>\"):e.push('<a href=\"javascript:;\" data-page=\"'+r.start+'\">'+r.start+\"</a>\");return t.pages>t.groups&&r.end<t.pages&&t.last&&0!==t.groups&&e.push('<span>&#x2026;</span><a href=\"javascript:;\" class=\"layui-laypage-last\" title=\"&#x5C3E;&#x9875;\"  data-page=\"'+t.pages+'\">'+t.last+\"</a>\"),r.flow=!t.prev&&0===t.groups,(t.curr!==t.pages&&t.next||r.flow)&&e.push(function(){return r.flow&&t.curr===t.pages?'<span class=\"layui-laypage-nomore\" title=\"&#x5DF2;&#x6CA1;&#x6709;&#x66F4;&#x591A;\">'+t.next+\"</span>\":'<a href=\"javascript:;\" class=\"layui-laypage-next\" data-page=\"'+(t.curr+1)+'\">'+t.next+\"</a>\"}()),'<div class=\"layui-box layui-laypage layui-laypage-'+(t.skin?function(a){return/^#/.test(a)?\"molv\":a}(t.skin):\"default\")+'\" id=\"layui-laypage-'+a.config.item+'\">'+e.join(\"\")+function(){return t.skip?'<span class=\"layui-laypage-total\">&#x5230;&#x7B2C; <input type=\"number\" min=\"1\" onkeyup=\"this.value=this.value.replace(/\\\\D/, \\'\\');\" value=\"'+t.curr+'\" class=\"layui-laypage-skip\"> &#x9875; <button type=\"button\" class=\"layui-laypage-btn\">&#x786e;&#x5b9a;</button></span>':\"\"}()+\"</div>\"},p.prototype.jump=function(a){if(a){for(var t=this,e=t.config,r=a.children,s=a[n](\"button\")[0],i=a[n](\"input\")[0],u=0,o=r.length;u<o;u++)\"a\"===r[u].nodeName.toLowerCase()&&p.on(r[u],\"click\",function(){var a=0|this.getAttribute(\"data-page\");e.curr=a,t.render()});s&&p.on(s,\"click\",function(){var a=0|i.value.replace(/\\s|\\D/g,\"\");a&&a<=e.pages&&(e.curr=a,t.render())})}},p.prototype.render=function(a){var t=this,n=t.config,s=t.type(),p=t.view();2===s?n.cont.innerHTML=p:3===s?n.cont.html(p):e[r](n.cont).innerHTML=p,n.jump&&n.jump(n,a),t.jump(e[r](\"layui-laypage-\"+n.item)),n.hash&&!a&&(location.hash=\"!\"+n.hash+\"=\"+n.curr)},a(\"laypage\",t)});layui.define(function(e){\"use strict\";var t=window,a={path:\"\",skin:\"default\",format:\"YYYY-MM-DD\",min:\"1900-01-01 00:00:00\",max:\"2099-12-31 23:59:59\",isv:!1,init:!0},n={},s=document,i=\"createElement\",o=\"getElementById\",l=\"getElementsByTagName\",d=[\"laydate_box\",\"laydate_void\",\"laydate_click\",\"LayDateSkin\",\"skins/\",\"/laydate.css\"];t.laydate=function(e){return e=e||{},n.run(e),laydate},laydate.v=\"1.1\",n.trim=function(e){return e=e||\"\",e.replace(/^\\s|\\s$/g,\"\").replace(/\\s+/g,\" \")},n.digit=function(e){return e<10?\"0\"+(0|e):e},n.stopmp=function(e){return e=e||t.event,e.stopPropagation?e.stopPropagation():e.cancelBubble=!0,this},n.each=function(e,t){for(var a=0,n=e.length;a<n&&t(a,e[a])!==!1;a++);},n.hasClass=function(e,t){return e=e||{},new RegExp(\"\\\\b\"+t+\"\\\\b\").test(e.className)},n.addClass=function(e,t){return e=e||{},n.hasClass(e,t)||(e.className+=\" \"+t),e.className=n.trim(e.className),this},n.removeClass=function(e,t){if(e=e||{},n.hasClass(e,t)){var a=new RegExp(\"\\\\b\"+t+\"\\\\b\");e.className=e.className.replace(a,\"\")}return this},n.removeCssAttr=function(e,t){var a=e.style;a.removeProperty?a.removeProperty(t):a.removeAttribute(t)},n.shde=function(e,t){e.style.display=t?\"none\":\"block\"},n.query=function(e){if(e&&1===e.nodeType){if(\"input\"!==e.tagName.toLowerCase())throw new Error(\"选择器elem错误\");return e}var t,e=n.trim(e).split(\" \"),a=s[o](e[0].substr(1));if(a){if(e[1]){if(/^\\./.test(e[1])){var i,d=e[1].substr(1),r=new RegExp(\"\\\\b\"+d+\"\\\\b\");return t=[],i=s.getElementsByClassName?a.getElementsByClassName(d):a[l](\"*\"),n.each(i,function(e,a){r.test(a.className)&&t.push(a)}),t[0]?t:\"\"}return t=a[l](e[1]),t[0]?a[l](e[1]):\"\"}return a}},n.on=function(e,a,s){return e.attachEvent?e.attachEvent(\"on\"+a,function(){s.call(e,t.even)}):e.addEventListener(a,s,!1),n},n.stopMosup=function(e,t){\"mouseup\"!==e&&n.on(t,\"mouseup\",function(e){n.stopmp(e)})},n.run=function(e){var t=(n.query,e.elem);t&&(d.elemv=/textarea|input/.test(t.tagName.toLocaleLowerCase())?\"value\":\"innerHTML\",(\"init\"in e?e.init:a.init)&&!t[d.elemv]&&(t[d.elemv]=laydate.now(null,e.format||a.format)),n.view(t,e),n.reshow())},n.scroll=function(e){return e=e?\"scrollLeft\":\"scrollTop\",s.body[e]|s.documentElement[e]},n.winarea=function(e){return document.documentElement[e?\"clientWidth\":\"clientHeight\"]},n.isleap=function(e){return e%4===0&&e%100!==0||e%400===0},n.checkVoid=function(e,t,a){var s=[];return e=0|e,t=0|t,a=0|a,e<n.mins[0]?s=[\"y\"]:e>n.maxs[0]?s=[\"y\",1]:e>=n.mins[0]&&e<=n.maxs[0]&&(e==n.mins[0]&&(t<n.mins[1]?s=[\"m\"]:t==n.mins[1]&&a<n.mins[2]&&(s=[\"d\"])),e==n.maxs[0]&&(t>n.maxs[1]?s=[\"m\",1]:t==n.maxs[1]&&a>n.maxs[2]&&(s=[\"d\",1]))),s},n.timeVoid=function(e,t){if(n.ymd[1]+1==n.mins[1]&&n.ymd[2]==n.mins[2]){if(0===t&&e<n.mins[3])return 1;if(1===t&&e<n.mins[4])return 1;if(2===t&&e<n.mins[5])return 1}else if(n.ymd[1]+1==n.maxs[1]&&n.ymd[2]==n.maxs[2]){if(0===t&&e>n.maxs[3])return 1;if(1===t&&e>n.maxs[4])return 1;if(2===t&&e>n.maxs[5])return 1}if(e>(t?59:23))return 1},n.check=function(){var e=n.options.format.replace(/YYYY|MM|DD|hh|mm|ss/g,\"\\\\d+\\\\\").replace(/\\\\$/g,\"\"),t=new RegExp(e),a=n.elem[d.elemv],s=a.match(/\\d+/g)||[],i=n.checkVoid(s[0],s[1],s[2]);if(\"\"!==a.replace(/\\s/g,\"\")){if(!t.test(a))return n.elem[d.elemv]=\"\",n.msg(\"日期不符合格式，请重新选择。\"),1;if(i[0])return n.elem[d.elemv]=\"\",n.msg(\"日期不在有效期内，请重新选择。\"),1;i.value=n.elem[d.elemv].match(t).join(),s=i.value.match(/\\d+/g),s[1]<1?(s[1]=1,i.auto=1):s[1]>12?(s[1]=12,i.auto=1):s[1].length<2&&(i.auto=1),s[2]<1?(s[2]=1,i.auto=1):s[2]>n.months[(0|s[1])-1]?(s[2]=31,i.auto=1):s[2].length<2&&(i.auto=1),s.length>3&&(n.timeVoid(s[3],0)&&(i.auto=1),n.timeVoid(s[4],1)&&(i.auto=1),n.timeVoid(s[5],2)&&(i.auto=1)),i.auto?n.creation([s[0],0|s[1],0|s[2]],1):i.value!==n.elem[d.elemv]&&(n.elem[d.elemv]=i.value)}},n.months=[31,null,31,30,31,30,31,31,30,31,30,31],n.viewDate=function(e,t,a){var s=(n.query,{}),i=new Date;e<(0|n.mins[0])&&(e=0|n.mins[0]),e>(0|n.maxs[0])&&(e=0|n.maxs[0]),i.setFullYear(e,t,a),s.ymd=[i.getFullYear(),i.getMonth(),i.getDate()],n.months[1]=n.isleap(s.ymd[0])?29:28,i.setFullYear(s.ymd[0],s.ymd[1],1),s.FDay=i.getDay(),s.PDay=n.months[0===t?11:t-1]-s.FDay+1,s.NDay=1,n.each(d.tds,function(e,t){var a,i=s.ymd[0],o=s.ymd[1]+1;t.className=\"\",e<s.FDay?(t.innerHTML=a=e+s.PDay,n.addClass(t,\"laydate_nothis\"),1===o&&(i-=1),o=1===o?12:o-1):e>=s.FDay&&e<s.FDay+n.months[s.ymd[1]]?(t.innerHTML=a=e-s.FDay+1,e-s.FDay+1===s.ymd[2]&&(n.addClass(t,d[2]),s.thisDay=t)):(t.innerHTML=a=s.NDay++,n.addClass(t,\"laydate_nothis\"),12===o&&(i+=1),o=12===o?1:o+1),n.checkVoid(i,o,a)[0]&&n.addClass(t,d[1]),n.options.festival&&n.festival(t,o+\".\"+a),t.setAttribute(\"y\",i),t.setAttribute(\"m\",o),t.setAttribute(\"d\",a),i=o=a=null}),n.valid=!n.hasClass(s.thisDay,d[1]),n.ymd=s.ymd,d.year.value=n.ymd[0]+\"年\",d.month.value=n.digit(n.ymd[1]+1)+\"月\",n.each(d.mms,function(e,t){var a=n.checkVoid(n.ymd[0],(0|t.getAttribute(\"m\"))+1);\"y\"===a[0]||\"m\"===a[0]?n.addClass(t,d[1]):n.removeClass(t,d[1]),n.removeClass(t,d[2]),a=null}),n.addClass(d.mms[n.ymd[1]],d[2]),s.times=[0|n.inymd[3]||0,0|n.inymd[4]||0,0|n.inymd[5]||0],n.each(new Array(3),function(e){n.hmsin[e].value=n.digit(n.timeVoid(s.times[e],e)?0|n.mins[e+3]:0|s.times[e])}),n[n.valid?\"removeClass\":\"addClass\"](d.ok,d[1])},n.festival=function(e,t){var a;switch(t){case\"1.1\":a=\"元旦\";break;case\"3.8\":a=\"妇女\";break;case\"4.5\":a=\"清明\";break;case\"5.1\":a=\"劳动\";break;case\"6.1\":a=\"儿童\";break;case\"9.10\":a=\"教师\";break;case\"10.1\":a=\"国庆\"}a&&(e.innerHTML=a),a=null},n.viewYears=function(e){var t=n.query,a=\"\";n.each(new Array(14),function(t){a+=7===t?\"<li \"+(parseInt(d.year.value)===e?'class=\"'+d[2]+'\"':\"\")+' y=\"'+e+'\">'+e+\"年</li>\":'<li y=\"'+(e-7+t)+'\">'+(e-7+t)+\"年</li>\"}),t(\"#laydate_ys\").innerHTML=a,n.each(t(\"#laydate_ys li\"),function(e,t){\"y\"===n.checkVoid(t.getAttribute(\"y\"))[0]?n.addClass(t,d[1]):n.on(t,\"click\",function(e){n.stopmp(e).reshow(),n.viewDate(0|this.getAttribute(\"y\"),n.ymd[1],n.ymd[2])})})},n.initDate=function(){var e=(n.query,new Date),t=n.elem[d.elemv].match(/\\d+/g)||[];t.length<3&&(t=n.options.start.match(/\\d+/g)||[],t.length<3&&(t=[e.getFullYear(),e.getMonth()+1,e.getDate()])),n.inymd=t,n.viewDate(t[0],t[1]-1,t[2])},n.iswrite=function(){var e=n.query,t={time:e(\"#laydate_hms\")};n.shde(t.time,!n.options.istime),n.shde(d.oclear,!(\"isclear\"in n.options?n.options.isclear:1)),n.shde(d.otoday,!(\"istoday\"in n.options?n.options.istoday:1)),n.shde(d.ok,!(\"issure\"in n.options?n.options.issure:1))},n.orien=function(e,t){var a,s=n.elem.getBoundingClientRect();e.style.left=s.left+(t?0:n.scroll(1))+\"px\",a=s.bottom+e.offsetHeight/1.5<=n.winarea()?s.bottom-1:s.top>e.offsetHeight/1.5?s.top-e.offsetHeight+1:n.winarea()-e.offsetHeight,e.style.top=Math.max(a+(t?0:n.scroll()),1)+\"px\"},n.follow=function(e){n.options.fixed?(e.style.position=\"fixed\",n.orien(e,1)):(e.style.position=\"absolute\",n.orien(e))},n.viewtb=function(){var e,t=[],a=[\"日\",\"一\",\"二\",\"三\",\"四\",\"五\",\"六\"],o={},d=s[i](\"table\"),r=s[i](\"thead\");return r.appendChild(s[i](\"tr\")),o.creath=function(e){var t=s[i](\"th\");t.innerHTML=a[e],r[l](\"tr\")[0].appendChild(t),t=null},n.each(new Array(6),function(a){t.push([]),e=d.insertRow(0),n.each(new Array(7),function(n){t[a][n]=0,0===a&&o.creath(n),e.insertCell(n)})}),d.insertBefore(r,d.children[0]),d.id=d.className=\"laydate_table\",e=t=null,d.outerHTML.toLowerCase()}(),n.view=function(e,t){var o,l=n.query,r={};t=t||e,n.elem=e,n.options=t,n.options.format||(n.options.format=a.format),n.options.start=n.options.start||\"\",n.mm=r.mm=[n.options.min||a.min,n.options.max||a.max],n.mins=r.mm[0].match(/\\d+/g),n.maxs=r.mm[1].match(/\\d+/g),n.box?n.shde(n.box):(o=s[i](\"div\"),o.id=d[0],o.className=d[0],o.style.cssText=\"position: absolute;\",o.setAttribute(\"name\",\"laydate-v\"+laydate.v),o.innerHTML=r.html='<div class=\"laydate_top\"><div class=\"laydate_ym laydate_y\" id=\"laydate_YY\"><a class=\"laydate_choose laydate_chprev laydate_tab\"><cite></cite></a><input id=\"laydate_y\" readonly><label></label><a class=\"laydate_choose laydate_chnext laydate_tab\"><cite></cite></a><div class=\"laydate_yms\"><a class=\"laydate_tab laydate_chtop\"><cite></cite></a><ul id=\"laydate_ys\"></ul><a class=\"laydate_tab laydate_chdown\"><cite></cite></a></div></div><div class=\"laydate_ym laydate_m\" id=\"laydate_MM\"><a class=\"laydate_choose laydate_chprev laydate_tab\"><cite></cite></a><input id=\"laydate_m\" readonly><label></label><a class=\"laydate_choose laydate_chnext laydate_tab\"><cite></cite></a><div class=\"laydate_yms\" id=\"laydate_ms\">'+function(){var e=\"\";return n.each(new Array(12),function(t){e+='<span m=\"'+t+'\">'+n.digit(t+1)+\"月</span>\"}),e}()+\"</div></div></div>\"+n.viewtb+'<div class=\"laydate_bottom\"><ul id=\"laydate_hms\"><li class=\"laydate_sj\">时间</li><li><input readonly>:</li><li><input readonly>:</li><li><input readonly></li></ul><div class=\"laydate_time\" id=\"laydate_time\"></div><div class=\"laydate_btn\"><a id=\"laydate_clear\">清空</a><a id=\"laydate_today\">今天</a><a id=\"laydate_ok\">确认</a></div>'+(a.isv?'<a href=\"http://sentsin.com/layui/laydate/\" class=\"laydate_v\" target=\"_blank\">laydate-v'+laydate.v+\"</a>\":\"\")+\"</div>\",s.body.appendChild(o),n.box=l(\"#\"+d[0]),n.events(),o=null),n.follow(n.box),t.zIndex?n.box.style.zIndex=t.zIndex:n.removeCssAttr(n.box,\"z-index\"),n.stopMosup(\"click\",n.box),n.initDate(),n.iswrite(),n.check()},n.reshow=function(){return n.each(n.query(\"#\"+d[0]+\" .laydate_show\"),function(e,t){n.removeClass(t,\"laydate_show\")}),this},n.close=function(){n.reshow(),n.shde(n.query(\"#\"+d[0]),1),n.elem=null},n.parse=function(e,t,s){return e=e.concat(t),s=s||(n.options?n.options.format:a.format),s.replace(/YYYY|MM|DD|hh|mm|ss/g,function(t,a){return e.index=0|++e.index,n.digit(e[e.index])})},n.creation=function(e,t){var a=(n.query,n.hmsin),s=n.parse(e,[a[0].value,a[1].value,a[2].value]);n.elem[d.elemv]=s,t||(n.close(),\"function\"==typeof n.options.choose&&n.options.choose(s))},n.events=function(){var e=n.query,a={box:\"#\"+d[0]};n.addClass(s.body,\"laydate_body\"),d.tds=e(\"#laydate_table td\"),d.mms=e(\"#laydate_ms span\"),d.year=e(\"#laydate_y\"),d.month=e(\"#laydate_m\"),n.each(e(a.box+\" .laydate_ym\"),function(e,t){n.on(t,\"click\",function(t){n.stopmp(t).reshow(),n.addClass(this[l](\"div\")[0],\"laydate_show\"),e||(a.YY=parseInt(d.year.value),n.viewYears(a.YY))})}),n.on(e(a.box),\"click\",function(){n.reshow()}),a.tabYear=function(e){0===e?n.ymd[0]--:1===e?n.ymd[0]++:2===e?a.YY-=14:a.YY+=14,e<2?(n.viewDate(n.ymd[0],n.ymd[1],n.ymd[2]),n.reshow()):n.viewYears(a.YY)},n.each(e(\"#laydate_YY .laydate_tab\"),function(e,t){n.on(t,\"click\",function(t){n.stopmp(t),a.tabYear(e)})}),a.tabMonth=function(e){e?(n.ymd[1]++,12===n.ymd[1]&&(n.ymd[0]++,n.ymd[1]=0)):(n.ymd[1]--,n.ymd[1]===-1&&(n.ymd[0]--,n.ymd[1]=11)),n.viewDate(n.ymd[0],n.ymd[1],n.ymd[2])},n.each(e(\"#laydate_MM .laydate_tab\"),function(e,t){n.on(t,\"click\",function(t){n.stopmp(t).reshow(),a.tabMonth(e)})}),n.each(e(\"#laydate_ms span\"),function(e,t){n.on(t,\"click\",function(e){n.stopmp(e).reshow(),n.hasClass(this,d[1])||n.viewDate(n.ymd[0],0|this.getAttribute(\"m\"),n.ymd[2])})}),n.each(e(\"#laydate_table td\"),function(e,t){n.on(t,\"click\",function(e){n.hasClass(this,d[1])||(n.stopmp(e),n.creation([0|this.getAttribute(\"y\"),0|this.getAttribute(\"m\"),0|this.getAttribute(\"d\")]))})}),d.oclear=e(\"#laydate_clear\"),n.on(d.oclear,\"click\",function(){n.elem[d.elemv]=\"\",n.close()}),d.otoday=e(\"#laydate_today\"),n.on(d.otoday,\"click\",function(){var e=new Date;n.creation([e.getFullYear(),e.getMonth()+1,e.getDate()])}),d.ok=e(\"#laydate_ok\"),n.on(d.ok,\"click\",function(){n.valid&&n.creation([n.ymd[0],n.ymd[1]+1,n.ymd[2]])}),a.times=e(\"#laydate_time\"),n.hmsin=a.hmsin=e(\"#laydate_hms input\"),a.hmss=[\"小时\",\"分钟\",\"秒数\"],a.hmsarr=[],n.msg=function(t,s){var i='<div class=\"laydte_hsmtex\">'+(s||\"提示\")+\"<span>×</span></div>\";\"string\"==typeof t?(i+=\"<p>\"+t+\"</p>\",n.shde(e(\"#\"+d[0])),n.removeClass(a.times,\"laydate_time1\").addClass(a.times,\"laydate_msg\")):(a.hmsarr[t]?i=a.hmsarr[t]:(i+='<div id=\"laydate_hmsno\" class=\"laydate_hmsno\">',n.each(new Array(0===t?24:60),function(e){i+=\"<span>\"+e+\"</span>\"}),i+=\"</div>\",a.hmsarr[t]=i),n.removeClass(a.times,\"laydate_msg\"),n[0===t?\"removeClass\":\"addClass\"](a.times,\"laydate_time1\")),n.addClass(a.times,\"laydate_show\"),a.times.innerHTML=i},a.hmson=function(t,a){var s=e(\"#laydate_hmsno span\"),i=n.valid?null:1;n.each(s,function(e,s){i?n.addClass(s,d[1]):n.timeVoid(e,a)?n.addClass(s,d[1]):n.on(s,\"click\",function(e){n.hasClass(this,d[1])||(t.value=n.digit(0|this.innerHTML))})}),n.addClass(s[0|t.value],\"laydate_click\")},n.each(a.hmsin,function(e,t){n.on(t,\"click\",function(t){n.stopmp(t).reshow(),n.msg(e,a.hmss[e]),a.hmson(this,e)})}),n.on(s,\"mouseup\",function(){var t=e(\"#\"+d[0]);t&&\"none\"!==t.style.display&&(n.check()||n.close())}).on(s,\"keydown\",function(e){e=e||t.event;var a=e.keyCode;13===a&&n.elem&&n.creation([n.ymd[0],n.ymd[1]+1,n.ymd[2]])})},laydate.reset=function(){n.box&&n.elem&&n.follow(n.box)},laydate.now=function(e,t){var a=new Date(0|e?function(e){return e<864e5?+new Date+864e5*e:e}(parseInt(e)):+new Date);return n.parse([a.getFullYear(),a.getMonth()+1,a.getDate()],[a.getHours(),a.getMinutes(),a.getSeconds()],t)},layui.addcss(\"modules/laydate/laydate.css\",function(){},\"laydatecss\"),e(\"laydate\",laydate)});!function(e,t){\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return t(e)}:t(e)}(\"undefined\"!=typeof window?window:this,function(e,t){function n(e){var t=!!e&&\"length\"in e&&e.length,n=pe.type(e);return\"function\"!==n&&!pe.isWindow(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&t>0&&t-1 in e)}function r(e,t,n){if(pe.isFunction(t))return pe.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return pe.grep(e,function(e){return e===t!==n});if(\"string\"==typeof t){if(Ce.test(t))return pe.filter(t,e,n);t=pe.filter(t,e)}return pe.grep(e,function(e){return pe.inArray(e,t)>-1!==n})}function i(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function o(e){var t={};return pe.each(e.match(De)||[],function(e,n){t[n]=!0}),t}function a(){re.addEventListener?(re.removeEventListener(\"DOMContentLoaded\",s),e.removeEventListener(\"load\",s)):(re.detachEvent(\"onreadystatechange\",s),e.detachEvent(\"onload\",s))}function s(){(re.addEventListener||\"load\"===e.event.type||\"complete\"===re.readyState)&&(a(),pe.ready())}function u(e,t,n){if(void 0===n&&1===e.nodeType){var r=\"data-\"+t.replace(_e,\"-$1\").toLowerCase();if(n=e.getAttribute(r),\"string\"==typeof n){try{n=\"true\"===n||\"false\"!==n&&(\"null\"===n?null:+n+\"\"===n?+n:qe.test(n)?pe.parseJSON(n):n)}catch(i){}pe.data(e,t,n)}else n=void 0}return n}function l(e){var t;for(t in e)if((\"data\"!==t||!pe.isEmptyObject(e[t]))&&\"toJSON\"!==t)return!1;return!0}function c(e,t,n,r){if(He(e)){var i,o,a=pe.expando,s=e.nodeType,u=s?pe.cache:e,l=s?e[a]:e[a]&&a;if(l&&u[l]&&(r||u[l].data)||void 0!==n||\"string\"!=typeof t)return l||(l=s?e[a]=ne.pop()||pe.guid++:a),u[l]||(u[l]=s?{}:{toJSON:pe.noop}),\"object\"!=typeof t&&\"function\"!=typeof t||(r?u[l]=pe.extend(u[l],t):u[l].data=pe.extend(u[l].data,t)),o=u[l],r||(o.data||(o.data={}),o=o.data),void 0!==n&&(o[pe.camelCase(t)]=n),\"string\"==typeof t?(i=o[t],null==i&&(i=o[pe.camelCase(t)])):i=o,i}}function f(e,t,n){if(He(e)){var r,i,o=e.nodeType,a=o?pe.cache:e,s=o?e[pe.expando]:pe.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){pe.isArray(t)?t=t.concat(pe.map(t,pe.camelCase)):t in r?t=[t]:(t=pe.camelCase(t),t=t in r?[t]:t.split(\" \")),i=t.length;for(;i--;)delete r[t[i]];if(n?!l(r):!pe.isEmptyObject(r))return}(n||(delete a[s].data,l(a[s])))&&(o?pe.cleanData([e],!0):fe.deleteExpando||a!=a.window?delete a[s]:a[s]=void 0)}}}function d(e,t,n,r){var i,o=1,a=20,s=r?function(){return r.cur()}:function(){return pe.css(e,t,\"\")},u=s(),l=n&&n[3]||(pe.cssNumber[t]?\"\":\"px\"),c=(pe.cssNumber[t]||\"px\"!==l&&+u)&&Me.exec(pe.css(e,t));if(c&&c[3]!==l){l=l||c[3],n=n||[],c=+u||1;do o=o||\".5\",c/=o,pe.style(e,t,c+l);while(o!==(o=s()/u)&&1!==o&&--a)}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}function p(e){var t=ze.split(\"|\"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function h(e,t){var n,r,i=0,o=\"undefined\"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):\"undefined\"!=typeof e.querySelectorAll?e.querySelectorAll(t||\"*\"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(r=n[i]);i++)!t||pe.nodeName(r,t)?o.push(r):pe.merge(o,h(r,t));return void 0===t||t&&pe.nodeName(e,t)?pe.merge([e],o):o}function g(e,t){for(var n,r=0;null!=(n=e[r]);r++)pe._data(n,\"globalEval\",!t||pe._data(t[r],\"globalEval\"))}function m(e){Be.test(e.type)&&(e.defaultChecked=e.checked)}function y(e,t,n,r,i){for(var o,a,s,u,l,c,f,d=e.length,y=p(t),v=[],x=0;x<d;x++)if(a=e[x],a||0===a)if(\"object\"===pe.type(a))pe.merge(v,a.nodeType?[a]:a);else if(Ue.test(a)){for(u=u||y.appendChild(t.createElement(\"div\")),l=(We.exec(a)||[\"\",\"\"])[1].toLowerCase(),f=Xe[l]||Xe._default,u.innerHTML=f[1]+pe.htmlPrefilter(a)+f[2],o=f[0];o--;)u=u.lastChild;if(!fe.leadingWhitespace&&$e.test(a)&&v.push(t.createTextNode($e.exec(a)[0])),!fe.tbody)for(a=\"table\"!==l||Ve.test(a)?\"<table>\"!==f[1]||Ve.test(a)?0:u:u.firstChild,o=a&&a.childNodes.length;o--;)pe.nodeName(c=a.childNodes[o],\"tbody\")&&!c.childNodes.length&&a.removeChild(c);for(pe.merge(v,u.childNodes),u.textContent=\"\";u.firstChild;)u.removeChild(u.firstChild);u=y.lastChild}else v.push(t.createTextNode(a));for(u&&y.removeChild(u),fe.appendChecked||pe.grep(h(v,\"input\"),m),x=0;a=v[x++];)if(r&&pe.inArray(a,r)>-1)i&&i.push(a);else if(s=pe.contains(a.ownerDocument,a),u=h(y.appendChild(a),\"script\"),s&&g(u),n)for(o=0;a=u[o++];)Ie.test(a.type||\"\")&&n.push(a);return u=null,y}function v(){return!0}function x(){return!1}function b(){try{return re.activeElement}catch(e){}}function w(e,t,n,r,i,o){var a,s;if(\"object\"==typeof t){\"string\"!=typeof n&&(r=r||n,n=void 0);for(s in t)w(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&(\"string\"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),i===!1)i=x;else if(!i)return e;return 1===o&&(a=i,i=function(e){return pe().off(e),a.apply(this,arguments)},i.guid=a.guid||(a.guid=pe.guid++)),e.each(function(){pe.event.add(this,t,i,r,n)})}function T(e,t){return pe.nodeName(e,\"table\")&&pe.nodeName(11!==t.nodeType?t:t.firstChild,\"tr\")?e.getElementsByTagName(\"tbody\")[0]||e.appendChild(e.ownerDocument.createElement(\"tbody\")):e}function C(e){return e.type=(null!==pe.find.attr(e,\"type\"))+\"/\"+e.type,e}function E(e){var t=it.exec(e.type);return t?e.type=t[1]:e.removeAttribute(\"type\"),e}function N(e,t){if(1===t.nodeType&&pe.hasData(e)){var n,r,i,o=pe._data(e),a=pe._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;r<i;r++)pe.event.add(t,n,s[n][r])}a.data&&(a.data=pe.extend({},a.data))}}function k(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!fe.noCloneEvent&&t[pe.expando]){i=pe._data(t);for(r in i.events)pe.removeEvent(t,r,i.handle);t.removeAttribute(pe.expando)}\"script\"===n&&t.text!==e.text?(C(t).text=e.text,E(t)):\"object\"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),fe.html5Clone&&e.innerHTML&&!pe.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):\"input\"===n&&Be.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):\"option\"===n?t.defaultSelected=t.selected=e.defaultSelected:\"input\"!==n&&\"textarea\"!==n||(t.defaultValue=e.defaultValue)}}function S(e,t,n,r){t=oe.apply([],t);var i,o,a,s,u,l,c=0,f=e.length,d=f-1,p=t[0],g=pe.isFunction(p);if(g||f>1&&\"string\"==typeof p&&!fe.checkClone&&rt.test(p))return e.each(function(i){var o=e.eq(i);g&&(t[0]=p.call(this,i,o.html())),S(o,t,n,r)});if(f&&(l=y(t,e[0].ownerDocument,!1,e,r),i=l.firstChild,1===l.childNodes.length&&(l=i),i||r)){for(s=pe.map(h(l,\"script\"),C),a=s.length;c<f;c++)o=l,c!==d&&(o=pe.clone(o,!0,!0),a&&pe.merge(s,h(o,\"script\"))),n.call(e[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,pe.map(s,E),c=0;c<a;c++)o=s[c],Ie.test(o.type||\"\")&&!pe._data(o,\"globalEval\")&&pe.contains(u,o)&&(o.src?pe._evalUrl&&pe._evalUrl(o.src):pe.globalEval((o.text||o.textContent||o.innerHTML||\"\").replace(ot,\"\")));l=i=null}return e}function A(e,t,n){for(var r,i=t?pe.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||pe.cleanData(h(r)),r.parentNode&&(n&&pe.contains(r.ownerDocument,r)&&g(h(r,\"script\")),r.parentNode.removeChild(r));return e}function D(e,t){var n=pe(t.createElement(e)).appendTo(t.body),r=pe.css(n[0],\"display\");return n.detach(),r}function j(e){var t=re,n=lt[e];return n||(n=D(e,t),\"none\"!==n&&n||(ut=(ut||pe(\"<iframe frameborder='0' width='0' height='0'/>\")).appendTo(t.documentElement),t=(ut[0].contentWindow||ut[0].contentDocument).document,t.write(),t.close(),n=D(e,t),ut.detach()),lt[e]=n),n}function L(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function H(e){if(e in Et)return e;for(var t=e.charAt(0).toUpperCase()+e.slice(1),n=Ct.length;n--;)if(e=Ct[n]+t,e in Et)return e}function q(e,t){for(var n,r,i,o=[],a=0,s=e.length;a<s;a++)r=e[a],r.style&&(o[a]=pe._data(r,\"olddisplay\"),n=r.style.display,t?(o[a]||\"none\"!==n||(r.style.display=\"\"),\"\"===r.style.display&&Re(r)&&(o[a]=pe._data(r,\"olddisplay\",j(r.nodeName)))):(i=Re(r),(n&&\"none\"!==n||!i)&&pe._data(r,\"olddisplay\",i?n:pe.css(r,\"display\"))));for(a=0;a<s;a++)r=e[a],r.style&&(t&&\"none\"!==r.style.display&&\"\"!==r.style.display||(r.style.display=t?o[a]||\"\":\"none\"));return e}function _(e,t,n){var r=bt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||\"px\"):t}function F(e,t,n,r,i){for(var o=n===(r?\"border\":\"content\")?4:\"width\"===t?1:0,a=0;o<4;o+=2)\"margin\"===n&&(a+=pe.css(e,n+Oe[o],!0,i)),r?(\"content\"===n&&(a-=pe.css(e,\"padding\"+Oe[o],!0,i)),\"margin\"!==n&&(a-=pe.css(e,\"border\"+Oe[o]+\"Width\",!0,i))):(a+=pe.css(e,\"padding\"+Oe[o],!0,i),\"padding\"!==n&&(a+=pe.css(e,\"border\"+Oe[o]+\"Width\",!0,i)));return a}function M(t,n,r){var i=!0,o=\"width\"===n?t.offsetWidth:t.offsetHeight,a=ht(t),s=fe.boxSizing&&\"border-box\"===pe.css(t,\"boxSizing\",!1,a);if(re.msFullscreenElement&&e.top!==e&&t.getClientRects().length&&(o=Math.round(100*t.getBoundingClientRect()[n])),o<=0||null==o){if(o=gt(t,n,a),(o<0||null==o)&&(o=t.style[n]),ft.test(o))return o;i=s&&(fe.boxSizingReliable()||o===t.style[n]),o=parseFloat(o)||0}return o+F(t,n,r||(s?\"border\":\"content\"),i,a)+\"px\"}function O(e,t,n,r,i){return new O.prototype.init(e,t,n,r,i)}function R(){return e.setTimeout(function(){Nt=void 0}),Nt=pe.now()}function P(e,t){var n,r={height:e},i=0;for(t=t?1:0;i<4;i+=2-t)n=Oe[i],r[\"margin\"+n]=r[\"padding\"+n]=e;return t&&(r.opacity=r.width=e),r}function B(e,t,n){for(var r,i=($.tweeners[t]||[]).concat($.tweeners[\"*\"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function W(e,t,n){var r,i,o,a,s,u,l,c,f=this,d={},p=e.style,h=e.nodeType&&Re(e),g=pe._data(e,\"fxshow\");n.queue||(s=pe._queueHooks(e,\"fx\"),null==s.unqueued&&(s.unqueued=0,u=s.empty.fire,s.empty.fire=function(){s.unqueued||u()}),s.unqueued++,f.always(function(){f.always(function(){s.unqueued--,pe.queue(e,\"fx\").length||s.empty.fire()})})),1===e.nodeType&&(\"height\"in t||\"width\"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],l=pe.css(e,\"display\"),c=\"none\"===l?pe._data(e,\"olddisplay\")||j(e.nodeName):l,\"inline\"===c&&\"none\"===pe.css(e,\"float\")&&(fe.inlineBlockNeedsLayout&&\"inline\"!==j(e.nodeName)?p.zoom=1:p.display=\"inline-block\")),n.overflow&&(p.overflow=\"hidden\",fe.shrinkWrapBlocks()||f.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],St.exec(i)){if(delete t[r],o=o||\"toggle\"===i,i===(h?\"hide\":\"show\")){if(\"show\"!==i||!g||void 0===g[r])continue;h=!0}d[r]=g&&g[r]||pe.style(e,r)}else l=void 0;if(pe.isEmptyObject(d))\"inline\"===(\"none\"===l?j(e.nodeName):l)&&(p.display=l);else{g?\"hidden\"in g&&(h=g.hidden):g=pe._data(e,\"fxshow\",{}),o&&(g.hidden=!h),h?pe(e).show():f.done(function(){pe(e).hide()}),f.done(function(){var t;pe._removeData(e,\"fxshow\");for(t in d)pe.style(e,t,d[t])});for(r in d)a=B(h?g[r]:0,r,f),r in g||(g[r]=a.start,h&&(a.end=a.start,a.start=\"width\"===r||\"height\"===r?1:0))}}function I(e,t){var n,r,i,o,a;for(n in e)if(r=pe.camelCase(n),i=t[r],o=e[n],pe.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=pe.cssHooks[r],a&&\"expand\"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function $(e,t,n){var r,i,o=0,a=$.prefilters.length,s=pe.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=Nt||R(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;a<u;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),o<1&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:pe.extend({},t),opts:pe.extend(!0,{specialEasing:{},easing:pe.easing._default},n),originalProperties:t,originalOptions:n,startTime:Nt||R(),duration:n.duration,tweens:[],createTween:function(t,n){var r=pe.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(I(c,l.opts.specialEasing);o<a;o++)if(r=$.prefilters[o].call(l,e,c,l.opts))return pe.isFunction(r.stop)&&(pe._queueHooks(l.elem,l.opts.queue).stop=pe.proxy(r.stop,r)),r;return pe.map(c,B,l),pe.isFunction(l.opts.start)&&l.opts.start.call(e,l),pe.fx.timer(pe.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function z(e){return pe.attr(e,\"class\")||\"\"}function X(e){return function(t,n){\"string\"!=typeof t&&(n=t,t=\"*\");var r,i=0,o=t.toLowerCase().match(De)||[];if(pe.isFunction(n))for(;r=o[i++];)\"+\"===r.charAt(0)?(r=r.slice(1)||\"*\",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function U(e,t,n,r){function i(s){var u;return o[s]=!0,pe.each(e[s]||[],function(e,s){var l=s(t,n,r);return\"string\"!=typeof l||a||o[l]?a?!(u=l):void 0:(t.dataTypes.unshift(l),i(l),!1)}),u}var o={},a=e===Qt;return i(t.dataTypes[0])||!o[\"*\"]&&i(\"*\")}function V(e,t){var n,r,i=pe.ajaxSettings.flatOptions||{};for(r in t)void 0!==t[r]&&((i[r]?e:n||(n={}))[r]=t[r]);return n&&pe.extend(!0,e,n),e}function Y(e,t,n){for(var r,i,o,a,s=e.contents,u=e.dataTypes;\"*\"===u[0];)u.shift(),void 0===i&&(i=e.mimeType||t.getResponseHeader(\"Content-Type\"));if(i)for(a in s)if(s[a]&&s[a].test(i)){u.unshift(a);break}if(u[0]in n)o=u[0];else{for(a in n){if(!u[0]||e.converters[a+\" \"+u[0]]){o=a;break}r||(r=a)}o=o||r}if(o)return o!==u[0]&&u.unshift(o),n[o]}function J(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if(\"*\"===o)o=u;else if(\"*\"!==u&&u!==o){if(a=l[u+\" \"+o]||l[\"* \"+o],!a)for(i in l)if(s=i.split(\" \"),s[1]===o&&(a=l[u+\" \"+s[0]]||l[\"* \"+s[0]])){a===!0?a=l[i]:l[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e[\"throws\"])t=a(t);else try{t=a(t)}catch(f){return{state:\"parsererror\",error:a?f:\"No conversion from \"+u+\" to \"+o}}}return{state:\"success\",data:t}}function G(e){return e.style&&e.style.display||pe.css(e,\"display\")}function K(e){for(;e&&1===e.nodeType;){if(\"none\"===G(e)||\"hidden\"===e.type)return!0;e=e.parentNode}return!1}function Q(e,t,n,r){var i;if(pe.isArray(t))pe.each(t,function(t,i){n||rn.test(e)?r(e,i):Q(e+\"[\"+(\"object\"==typeof i&&null!=i?t:\"\")+\"]\",i,n,r)});else if(n||\"object\"!==pe.type(t))r(e,t);else for(i in t)Q(e+\"[\"+i+\"]\",t[i],n,r)}function Z(){try{return new e.XMLHttpRequest}catch(t){}}function ee(){try{return new e.ActiveXObject(\"Microsoft.XMLHTTP\")}catch(t){}}function te(e){return pe.isWindow(e)?e:9===e.nodeType&&(e.defaultView||e.parentWindow)}var ne=[],re=e.document,ie=ne.slice,oe=ne.concat,ae=ne.push,se=ne.indexOf,ue={},le=ue.toString,ce=ue.hasOwnProperty,fe={},de=\"1.12.3\",pe=function(e,t){return new pe.fn.init(e,t)},he=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,ge=/^-ms-/,me=/-([\\da-z])/gi,ye=function(e,t){return t.toUpperCase()};pe.fn=pe.prototype={jquery:de,constructor:pe,selector:\"\",length:0,toArray:function(){return ie.call(this)},get:function(e){return null!=e?e<0?this[e+this.length]:this[e]:ie.call(this)},pushStack:function(e){var t=pe.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e){return pe.each(this,e)},map:function(e){return this.pushStack(pe.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(ie.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:ae,sort:ne.sort,splice:ne.splice},pe.extend=pe.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for(\"boolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||pe.isFunction(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(i=arguments[s]))for(r in i)e=a[r],n=i[r],a!==n&&(l&&n&&(pe.isPlainObject(n)||(t=pe.isArray(n)))?(t?(t=!1,o=e&&pe.isArray(e)?e:[]):o=e&&pe.isPlainObject(e)?e:{},a[r]=pe.extend(l,o,n)):void 0!==n&&(a[r]=n));return a},pe.extend({expando:\"jQuery\"+(de+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isFunction:function(e){return\"function\"===pe.type(e)},isArray:Array.isArray||function(e){return\"array\"===pe.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){var t=e&&e.toString();return!pe.isArray(e)&&t-parseFloat(t)+1>=0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},isPlainObject:function(e){var t;if(!e||\"object\"!==pe.type(e)||e.nodeType||pe.isWindow(e))return!1;try{if(e.constructor&&!ce.call(e,\"constructor\")&&!ce.call(e.constructor.prototype,\"isPrototypeOf\"))return!1}catch(n){return!1}if(!fe.ownFirst)for(t in e)return ce.call(e,t);for(t in e);return void 0===t||ce.call(e,t)},type:function(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?ue[le.call(e)]||\"object\":typeof e},globalEval:function(t){t&&pe.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(ge,\"ms-\").replace(me,ye)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var r,i=0;if(n(e))for(r=e.length;i<r&&t.call(e[i],i,e[i])!==!1;i++);else for(i in e)if(t.call(e[i],i,e[i])===!1)break;return e},trim:function(e){return null==e?\"\":(e+\"\").replace(he,\"\")},makeArray:function(e,t){var r=t||[];return null!=e&&(n(Object(e))?pe.merge(r,\"string\"==typeof e?[e]:e):ae.call(r,e)),r},inArray:function(e,t,n){var r;if(t){if(se)return se.call(t,e,n);for(r=t.length,n=n?n<0?Math.max(0,r+n):n:0;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;)e[i++]=t[r++];if(n!==n)for(;void 0!==t[r];)e[i++]=t[r++];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)r=!t(e[o],o),r!==s&&i.push(e[o]);return i},map:function(e,t,r){var i,o,a=0,s=[];if(n(e))for(i=e.length;a<i;a++)o=t(e[a],a,r),null!=o&&s.push(o);else for(a in e)o=t(e[a],a,r),null!=o&&s.push(o);return oe.apply([],s)},guid:1,proxy:function(e,t){var n,r,i;if(\"string\"==typeof t&&(i=e[t],t=e,e=i),pe.isFunction(e))return n=ie.call(arguments,2),r=function(){return e.apply(t||this,n.concat(ie.call(arguments)))},r.guid=e.guid=e.guid||pe.guid++,r},now:function(){return+new Date},support:fe}),\"function\"==typeof Symbol&&(pe.fn[Symbol.iterator]=ne[Symbol.iterator]),pe.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){ue[\"[object \"+t+\"]\"]=t.toLowerCase()});var ve=function(e){function t(e,t,n,r){var i,o,a,s,u,l,f,p,h=t&&t.ownerDocument,g=t?t.nodeType:9;if(n=n||[],\"string\"!=typeof e||!e||1!==g&&9!==g&&11!==g)return n;if(!r&&((t?t.ownerDocument||t:B)!==H&&L(t),t=t||H,_)){if(11!==g&&(l=ye.exec(e)))if(i=l[1]){if(9===g){if(!(a=t.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(h&&(a=h.getElementById(i))&&R(t,a)&&a.id===i)return n.push(a),n}else{if(l[2])return Q.apply(n,t.getElementsByTagName(e)),n;if((i=l[3])&&w.getElementsByClassName&&t.getElementsByClassName)return Q.apply(n,t.getElementsByClassName(i)),n}if(w.qsa&&!X[e+\" \"]&&(!F||!F.test(e))){if(1!==g)h=t,p=e;else if(\"object\"!==t.nodeName.toLowerCase()){for((s=t.getAttribute(\"id\"))?s=s.replace(xe,\"\\\\$&\"):t.setAttribute(\"id\",s=P),f=N(e),o=f.length,u=de.test(s)?\"#\"+s:\"[id='\"+s+\"']\";o--;)f[o]=u+\" \"+d(f[o]);p=f.join(\",\"),h=ve.test(e)&&c(t.parentNode)||t}if(p)try{return Q.apply(n,h.querySelectorAll(p)),n}catch(m){}finally{s===P&&t.removeAttribute(\"id\")}}}return S(e.replace(se,\"$1\"),t,n,r)}function n(){function e(n,r){return t.push(n+\" \")>T.cacheLength&&delete e[t.shift()],e[n+\" \"]=r}var t=[];return e}function r(e){return e[P]=!0,e}function i(e){var t=H.createElement(\"div\");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split(\"|\"),r=n.length;r--;)T.attrHandle[n[r]]=t}function a(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||V)-(~e.sourceIndex||V);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){var n=t.nodeName.toLowerCase();return\"input\"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return(\"input\"===n||\"button\"===n)&&t.type===e}}function l(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function c(e){return e&&\"undefined\"!=typeof e.getElementsByTagName&&e}function f(){}function d(e){for(var t=0,n=e.length,r=\"\";t<n;t++)r+=e[t].value;return r}function p(e,t,n){var r=t.dir,i=n&&\"parentNode\"===r,o=I++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,a){var s,u,l,c=[W,o];if(a){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,a))return!0}else for(;t=t[r];)if(1===t.nodeType||i){if(l=t[P]||(t[P]={}),u=l[t.uniqueID]||(l[t.uniqueID]={}),(s=u[r])&&s[0]===W&&s[1]===o)return c[2]=s[2];if(u[r]=c,c[2]=e(t,n,a))return!0}}}function h(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function g(e,n,r){for(var i=0,o=n.length;i<o;i++)t(e,n[i],r);return r}function m(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function y(e,t,n,i,o,a){return i&&!i[P]&&(i=y(i)),o&&!o[P]&&(o=y(o,a)),r(function(r,a,s,u){var l,c,f,d=[],p=[],h=a.length,y=r||g(t||\"*\",s.nodeType?[s]:s,[]),v=!e||!r&&t?y:m(y,d,e,s,u),x=n?o||(r?e:h||i)?[]:a:v;if(n&&n(v,x,s,u),i)for(l=m(x,p),i(l,[],s,u),c=l.length;c--;)(f=l[c])&&(x[p[c]]=!(v[p[c]]=f));if(r){if(o||e){if(o){for(l=[],c=x.length;c--;)(f=x[c])&&l.push(v[c]=f);o(null,x=[],l,u)}for(c=x.length;c--;)(f=x[c])&&(l=o?ee(r,f):d[c])>-1&&(r[l]=!(a[l]=f))}}else x=m(x===a?x.splice(h,x.length):x),o?o(null,a,x,u):Q.apply(a,x)})}function v(e){for(var t,n,r,i=e.length,o=T.relative[e[0].type],a=o||T.relative[\" \"],s=o?1:0,u=p(function(e){return e===t},a,!0),l=p(function(e){return ee(t,e)>-1},a,!0),c=[function(e,n,r){var i=!o&&(r||n!==A)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,i}];s<i;s++)if(n=T.relative[e[s].type])c=[p(h(c),n)];else{if(n=T.filter[e[s].type].apply(null,e[s].matches),n[P]){for(r=++s;r<i&&!T.relative[e[r].type];r++);return y(s>1&&h(c),s>1&&d(e.slice(0,s-1).concat({value:\" \"===e[s-2].type?\"*\":\"\"})).replace(se,\"$1\"),n,s<r&&v(e.slice(s,r)),r<i&&v(e=e.slice(r)),r<i&&d(e))}c.push(n)}return h(c)}function x(e,n){var i=n.length>0,o=e.length>0,a=function(r,a,s,u,l){var c,f,d,p=0,h=\"0\",g=r&&[],y=[],v=A,x=r||o&&T.find.TAG(\"*\",l),b=W+=null==v?1:Math.random()||.1,w=x.length;for(l&&(A=a===H||a||l);h!==w&&null!=(c=x[h]);h++){if(o&&c){for(f=0,a||c.ownerDocument===H||(L(c),s=!_);d=e[f++];)if(d(c,a||H,s)){u.push(c);break}l&&(W=b)}i&&((c=!d&&c)&&p--,r&&g.push(c))}if(p+=h,i&&h!==p){for(f=0;d=n[f++];)d(g,y,a,s);if(r){if(p>0)for(;h--;)g[h]||y[h]||(y[h]=G.call(u));y=m(y)}Q.apply(u,y),l&&!r&&y.length>0&&p+n.length>1&&t.uniqueSort(u)}return l&&(W=b,A=v),g};return i?r(a):a}var b,w,T,C,E,N,k,S,A,D,j,L,H,q,_,F,M,O,R,P=\"sizzle\"+1*new Date,B=e.document,W=0,I=0,$=n(),z=n(),X=n(),U=function(e,t){return e===t&&(j=!0),0},V=1<<31,Y={}.hasOwnProperty,J=[],G=J.pop,K=J.push,Q=J.push,Z=J.slice,ee=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},te=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",ne=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",re=\"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",ie=\"\\\\[\"+ne+\"*(\"+re+\")(?:\"+ne+\"*([*^$|!~]?=)\"+ne+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+re+\"))|)\"+ne+\"*\\\\]\",oe=\":(\"+re+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+ie+\")*)|.*)\\\\)|)\",ae=new RegExp(ne+\"+\",\"g\"),se=new RegExp(\"^\"+ne+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+ne+\"+$\",\"g\"),ue=new RegExp(\"^\"+ne+\"*,\"+ne+\"*\"),le=new RegExp(\"^\"+ne+\"*([>+~]|\"+ne+\")\"+ne+\"*\"),ce=new RegExp(\"=\"+ne+\"*([^\\\\]'\\\"]*?)\"+ne+\"*\\\\]\",\"g\"),fe=new RegExp(oe),de=new RegExp(\"^\"+re+\"$\"),pe={ID:new RegExp(\"^#(\"+re+\")\"),CLASS:new RegExp(\"^\\\\.(\"+re+\")\"),TAG:new RegExp(\"^(\"+re+\"|[*])\"),ATTR:new RegExp(\"^\"+ie),PSEUDO:new RegExp(\"^\"+oe),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+ne+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+ne+\"*(?:([+-]|)\"+ne+\"*(\\\\d+)|))\"+ne+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+te+\")$\",\"i\"),needsContext:new RegExp(\"^\"+ne+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+ne+\"*((?:-\\\\d)?\\\\d*)\"+ne+\"*\\\\)|)(?=[^-]|$)\",\"i\")},he=/^(?:input|select|textarea|button)$/i,ge=/^h\\d$/i,me=/^[^{]+\\{\\s*\\[native \\w/,ye=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ve=/[+~]/,xe=/'|\\\\/g,be=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+ne+\"?|(\"+ne+\")|.)\",\"ig\"),we=function(e,t,n){var r=\"0x\"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},Te=function(){L()};try{Q.apply(J=Z.call(B.childNodes),B.childNodes),J[B.childNodes.length].nodeType}catch(Ce){Q={apply:J.length?function(e,t){K.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}w=t.support={},E=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&\"HTML\"!==t.nodeName},L=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:B;return r!==H&&9===r.nodeType&&r.documentElement?(H=r,q=H.documentElement,_=!E(H),(n=H.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener(\"unload\",Te,!1):n.attachEvent&&n.attachEvent(\"onunload\",Te)),w.attributes=i(function(e){return e.className=\"i\",!e.getAttribute(\"className\")}),w.getElementsByTagName=i(function(e){return e.appendChild(H.createComment(\"\")),!e.getElementsByTagName(\"*\").length}),w.getElementsByClassName=me.test(H.getElementsByClassName),w.getById=i(function(e){return q.appendChild(e).id=P,!H.getElementsByName||!H.getElementsByName(P).length}),w.getById?(T.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&_){var n=t.getElementById(e);return n?[n]:[]}},T.filter.ID=function(e){var t=e.replace(be,we);return function(e){return e.getAttribute(\"id\")===t}}):(delete T.find.ID,T.filter.ID=function(e){var t=e.replace(be,we);return function(e){var n=\"undefined\"!=typeof e.getAttributeNode&&e.getAttributeNode(\"id\");return n&&n.value===t}}),T.find.TAG=w.getElementsByTagName?function(e,t){return\"undefined\"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):w.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if(\"*\"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},T.find.CLASS=w.getElementsByClassName&&function(e,t){if(\"undefined\"!=typeof t.getElementsByClassName&&_)return t.getElementsByClassName(e)},M=[],F=[],(w.qsa=me.test(H.querySelectorAll))&&(i(function(e){q.appendChild(e).innerHTML=\"<a id='\"+P+\"'></a><select id='\"+P+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",e.querySelectorAll(\"[msallowcapture^='']\").length&&F.push(\"[*^$]=\"+ne+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\"[selected]\").length||F.push(\"\\\\[\"+ne+\"*(?:value|\"+te+\")\"),e.querySelectorAll(\"[id~=\"+P+\"-]\").length||F.push(\"~=\"),e.querySelectorAll(\":checked\").length||F.push(\":checked\"),e.querySelectorAll(\"a#\"+P+\"+*\").length||F.push(\".#.+[+~]\")}),i(function(e){var t=H.createElement(\"input\");t.setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),e.querySelectorAll(\"[name=d]\").length&&F.push(\"name\"+ne+\"*[*^$|!~]?=\"),e.querySelectorAll(\":enabled\").length||F.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),F.push(\",.*:\")})),(w.matchesSelector=me.test(O=q.matches||q.webkitMatchesSelector||q.mozMatchesSelector||q.oMatchesSelector||q.msMatchesSelector))&&i(function(e){w.disconnectedMatch=O.call(e,\"div\"),O.call(e,\"[s!='']:x\"),M.push(\"!=\",oe)}),F=F.length&&new RegExp(F.join(\"|\")),M=M.length&&new RegExp(M.join(\"|\")),t=me.test(q.compareDocumentPosition),R=t||me.test(q.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},U=t?function(e,t){if(e===t)return j=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!w.sortDetached&&t.compareDocumentPosition(e)===n?e===H||e.ownerDocument===B&&R(B,e)?-1:t===H||t.ownerDocument===B&&R(B,t)?1:D?ee(D,e)-ee(D,t):0:4&n?-1:1)}:function(e,t){if(e===t)return j=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,s=[e],u=[t];if(!i||!o)return e===H?-1:t===H?1:i?-1:o?1:D?ee(D,e)-ee(D,t):0;if(i===o)return a(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;s[r]===u[r];)r++;return r?a(s[r],u[r]):s[r]===B?-1:u[r]===B?1:0},H):H},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==H&&L(e),n=n.replace(ce,\"='$1']\"),w.matchesSelector&&_&&!X[n+\" \"]&&(!M||!M.test(n))&&(!F||!F.test(n)))try{var r=O.call(e,n);if(r||w.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return t(n,H,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==H&&L(e),R(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==H&&L(e);var n=T.attrHandle[t.toLowerCase()],r=n&&Y.call(T.attrHandle,t.toLowerCase())?n(e,t,!_):void 0;return void 0!==r?r:w.attributes||!_?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.error=function(e){throw new Error(\"Syntax error, unrecognized expression: \"+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(j=!w.detectDuplicates,D=!w.sortStable&&e.slice(0),e.sort(U),j){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return D=null,e},C=t.getText=function(e){var t,n=\"\",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if(\"string\"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=C(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=C(t);return n},T=t.selectors={cacheLength:50,createPseudo:r,match:pe,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(be,we),e[3]=(e[3]||e[4]||e[5]||\"\").replace(be,we),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return pe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&fe.test(n)&&(t=N(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(be,we).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=$[e+\" \"];return t||(t=new RegExp(\"(^|\"+ne+\")\"+e+\"(\"+ne+\"|$)\"))&&$(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||\"undefined\"!=typeof e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(e,n,r){return function(i){var o=t.attr(i,e);return null==o?\"!=\"===n:!n||(o+=\"\",\"=\"===n?o===r:\"!=\"===n?o!==r:\"^=\"===n?r&&0===o.indexOf(r):\"*=\"===n?r&&o.indexOf(r)>-1:\"$=\"===n?r&&o.slice(-r.length)===r:\"~=\"===n?(\" \"+o.replace(ae,\" \")+\" \").indexOf(r)>-1:\"|=\"===n&&(o===r||o.slice(0,r.length+1)===r+\"-\"))}},CHILD:function(e,t,n,r,i){var o=\"nth\"!==e.slice(0,3),a=\"last\"!==e.slice(-4),s=\"of-type\"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,d,p,h,g=o!==a?\"nextSibling\":\"previousSibling\",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s,x=!1;if(m){if(o){for(;g;){for(d=t;d=d[g];)if(s?d.nodeName.toLowerCase()===y:1===d.nodeType)return!1;h=g=\"only\"===e&&!h&&\"nextSibling\"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){for(d=m,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),\nl=c[e]||[],p=l[0]===W&&l[1],x=p&&l[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(x=p=0)||h.pop();)if(1===d.nodeType&&++x&&d===t){c[e]=[W,p,x];break}}else if(v&&(d=t,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),l=c[e]||[],p=l[0]===W&&l[1],x=p),x===!1)for(;(d=++p&&d&&d[g]||(x=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==y:1!==d.nodeType)||!++x||(v&&(f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),c[e]=[W,x]),d!==t)););return x-=i,x===r||x%r===0&&x/r>=0}}},PSEUDO:function(e,n){var i,o=T.pseudos[e]||T.setFilters[e.toLowerCase()]||t.error(\"unsupported pseudo: \"+e);return o[P]?o(n):o.length>1?(i=[e,e,\"\",n],T.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),a=i.length;a--;)r=ee(e,i[a]),e[r]=!(t[r]=i[a])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=k(e.replace(se,\"$1\"));return i[P]?r(function(e,t,n,r){for(var o,a=i(e,null,r,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(be,we),function(t){return(t.textContent||t.innerText||C(t)).indexOf(e)>-1}}),lang:r(function(e){return de.test(e||\"\")||t.error(\"unsupported lang: \"+e),e=e.replace(be,we).toLowerCase(),function(t){var n;do if(n=_?t.lang:t.getAttribute(\"xml:lang\")||t.getAttribute(\"lang\"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+\"-\");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===q},focus:function(e){return e===H.activeElement&&(!H.hasFocus||H.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&!!e.checked||\"option\"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!T.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return he.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&\"button\"===e.type||\"button\"===t},text:function(e){var t;return\"input\"===e.nodeName.toLowerCase()&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||\"text\"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[n<0?n+t:n]}),even:l(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:l(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:l(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:l(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},T.pseudos.nth=T.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})T.pseudos[b]=s(b);for(b in{submit:!0,reset:!0})T.pseudos[b]=u(b);return f.prototype=T.filters=T.pseudos,T.setFilters=new f,N=t.tokenize=function(e,n){var r,i,o,a,s,u,l,c=z[e+\" \"];if(c)return n?0:c.slice(0);for(s=e,u=[],l=T.preFilter;s;){r&&!(i=ue.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),r=!1,(i=le.exec(s))&&(r=i.shift(),o.push({value:r,type:i[0].replace(se,\" \")}),s=s.slice(r.length));for(a in T.filter)!(i=pe[a].exec(s))||l[a]&&!(i=l[a](i))||(r=i.shift(),o.push({value:r,type:a,matches:i}),s=s.slice(r.length));if(!r)break}return n?s.length:s?t.error(e):z(e,u).slice(0)},k=t.compile=function(e,t){var n,r=[],i=[],o=X[e+\" \"];if(!o){for(t||(t=N(e)),n=t.length;n--;)o=v(t[n]),o[P]?r.push(o):i.push(o);o=X(e,x(i,r)),o.selector=e}return o},S=t.select=function(e,t,n,r){var i,o,a,s,u,l=\"function\"==typeof e&&e,f=!r&&N(e=l.selector||e);if(n=n||[],1===f.length){if(o=f[0]=f[0].slice(0),o.length>2&&\"ID\"===(a=o[0]).type&&w.getById&&9===t.nodeType&&_&&T.relative[o[1].type]){if(t=(T.find.ID(a.matches[0].replace(be,we),t)||[])[0],!t)return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=pe.needsContext.test(e)?0:o.length;i--&&(a=o[i],!T.relative[s=a.type]);)if((u=T.find[s])&&(r=u(a.matches[0].replace(be,we),ve.test(o[0].type)&&c(t.parentNode)||t))){if(o.splice(i,1),e=r.length&&d(o),!e)return Q.apply(n,r),n;break}}return(l||k(e,f))(r,t,!_,n,!t||ve.test(e)&&c(t.parentNode)||t),n},w.sortStable=P.split(\"\").sort(U).join(\"\")===P,w.detectDuplicates=!!j,L(),w.sortDetached=i(function(e){return 1&e.compareDocumentPosition(H.createElement(\"div\"))}),i(function(e){return e.innerHTML=\"<a href='#'></a>\",\"#\"===e.firstChild.getAttribute(\"href\")})||o(\"type|href|height|width\",function(e,t,n){if(!n)return e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)}),w.attributes&&i(function(e){return e.innerHTML=\"<input/>\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")})||o(\"value\",function(e,t,n){if(!n&&\"input\"===e.nodeName.toLowerCase())return e.defaultValue}),i(function(e){return null==e.getAttribute(\"disabled\")})||o(te,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);pe.find=ve,pe.expr=ve.selectors,pe.expr[\":\"]=pe.expr.pseudos,pe.uniqueSort=pe.unique=ve.uniqueSort,pe.text=ve.getText,pe.isXMLDoc=ve.isXML,pe.contains=ve.contains;var xe=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&pe(e).is(n))break;r.push(e)}return r},be=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},we=pe.expr.match.needsContext,Te=/^<([\\w-]+)\\s*\\/?>(?:<\\/\\1>|)$/,Ce=/^.[^:#\\[\\.,]*$/;pe.filter=function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?pe.find.matchesSelector(r,e)?[r]:[]:pe.find.matches(e,pe.grep(t,function(e){return 1===e.nodeType}))},pe.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if(\"string\"!=typeof e)return this.pushStack(pe(e).filter(function(){for(t=0;t<i;t++)if(pe.contains(r[t],this))return!0}));for(t=0;t<i;t++)pe.find(e,r[t],n);return n=this.pushStack(i>1?pe.unique(n):n),n.selector=this.selector?this.selector+\" \"+e:e,n},filter:function(e){return this.pushStack(r(this,e||[],!1))},not:function(e){return this.pushStack(r(this,e||[],!0))},is:function(e){return!!r(this,\"string\"==typeof e&&we.test(e)?pe(e):e||[],!1).length}});var Ee,Ne=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,ke=pe.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||Ee,\"string\"==typeof e){if(r=\"<\"===e.charAt(0)&&\">\"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:Ne.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof pe?t[0]:t,pe.merge(this,pe.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:re,!0)),Te.test(r[1])&&pe.isPlainObject(t))for(r in t)pe.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}if(i=re.getElementById(r[2]),i&&i.parentNode){if(i.id!==r[2])return Ee.find(e);this.length=1,this[0]=i}return this.context=re,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):pe.isFunction(e)?\"undefined\"!=typeof n.ready?n.ready(e):e(pe):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),pe.makeArray(e,this))};ke.prototype=pe.fn,Ee=pe(re);var Se=/^(?:parents|prev(?:Until|All))/,Ae={children:!0,contents:!0,next:!0,prev:!0};pe.fn.extend({has:function(e){var t,n=pe(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(pe.contains(this,n[t]))return!0})},closest:function(e,t){for(var n,r=0,i=this.length,o=[],a=we.test(e)||\"string\"!=typeof e?pe(e,t||this.context):0;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&pe.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?pe.uniqueSort(o):o)},index:function(e){return e?\"string\"==typeof e?pe.inArray(this[0],pe(e)):pe.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(pe.uniqueSort(pe.merge(this.get(),pe(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),pe.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return xe(e,\"parentNode\")},parentsUntil:function(e,t,n){return xe(e,\"parentNode\",n)},next:function(e){return i(e,\"nextSibling\")},prev:function(e){return i(e,\"previousSibling\")},nextAll:function(e){return xe(e,\"nextSibling\")},prevAll:function(e){return xe(e,\"previousSibling\")},nextUntil:function(e,t,n){return xe(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return xe(e,\"previousSibling\",n)},siblings:function(e){return be((e.parentNode||{}).firstChild,e)},children:function(e){return be(e.firstChild)},contents:function(e){return pe.nodeName(e,\"iframe\")?e.contentDocument||e.contentWindow.document:pe.merge([],e.childNodes)}},function(e,t){pe.fn[e]=function(n,r){var i=pe.map(this,t,n);return\"Until\"!==e.slice(-5)&&(r=n),r&&\"string\"==typeof r&&(i=pe.filter(r,i)),this.length>1&&(Ae[e]||(i=pe.uniqueSort(i)),Se.test(e)&&(i=i.reverse())),this.pushStack(i)}});var De=/\\S+/g;pe.Callbacks=function(e){e=\"string\"==typeof e?o(e):pe.extend({},e);var t,n,r,i,a=[],s=[],u=-1,l=function(){for(i=e.once,r=t=!0;s.length;u=-1)for(n=s.shift();++u<a.length;)a[u].apply(n[0],n[1])===!1&&e.stopOnFalse&&(u=a.length,n=!1);e.memory||(n=!1),t=!1,i&&(a=n?[]:\"\")},c={add:function(){return a&&(n&&!t&&(u=a.length-1,s.push(n)),function r(t){pe.each(t,function(t,n){pe.isFunction(n)?e.unique&&c.has(n)||a.push(n):n&&n.length&&\"string\"!==pe.type(n)&&r(n)})}(arguments),n&&!t&&l()),this},remove:function(){return pe.each(arguments,function(e,t){for(var n;(n=pe.inArray(t,a,n))>-1;)a.splice(n,1),n<=u&&u--}),this},has:function(e){return e?pe.inArray(e,a)>-1:a.length>0},empty:function(){return a&&(a=[]),this},disable:function(){return i=s=[],a=n=\"\",this},disabled:function(){return!a},lock:function(){return i=!0,n||c.disable(),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=n||[],n=[e,n.slice?n.slice():n],s.push(n),t||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},pe.extend({Deferred:function(e){var t=[[\"resolve\",\"done\",pe.Callbacks(\"once memory\"),\"resolved\"],[\"reject\",\"fail\",pe.Callbacks(\"once memory\"),\"rejected\"],[\"notify\",\"progress\",pe.Callbacks(\"memory\")]],n=\"pending\",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return pe.Deferred(function(n){pe.each(t,function(t,o){var a=pe.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&pe.isFunction(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[o[0]+\"With\"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?pe.extend(e,r):r}},i={};return r.pipe=r.then,pe.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+\"With\"](this===i?r:this,arguments),this},i[o[0]+\"With\"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t,n,r,i=0,o=ie.call(arguments),a=o.length,s=1!==a||e&&pe.isFunction(e.promise)?a:0,u=1===s?e:pe.Deferred(),l=function(e,n,r){return function(i){n[e]=this,r[e]=arguments.length>1?ie.call(arguments):i,r===t?u.notifyWith(n,r):--s||u.resolveWith(n,r)}};if(a>1)for(t=new Array(a),n=new Array(a),r=new Array(a);i<a;i++)o[i]&&pe.isFunction(o[i].promise)?o[i].promise().progress(l(i,n,t)).done(l(i,r,o)).fail(u.reject):--s;return s||u.resolveWith(r,o),u.promise()}});var je;pe.fn.ready=function(e){return pe.ready.promise().done(e),this},pe.extend({isReady:!1,readyWait:1,holdReady:function(e){e?pe.readyWait++:pe.ready(!0)},ready:function(e){(e===!0?--pe.readyWait:pe.isReady)||(pe.isReady=!0,e!==!0&&--pe.readyWait>0||(je.resolveWith(re,[pe]),pe.fn.triggerHandler&&(pe(re).triggerHandler(\"ready\"),pe(re).off(\"ready\"))))}}),pe.ready.promise=function(t){if(!je)if(je=pe.Deferred(),\"complete\"===re.readyState||\"loading\"!==re.readyState&&!re.documentElement.doScroll)e.setTimeout(pe.ready);else if(re.addEventListener)re.addEventListener(\"DOMContentLoaded\",s),e.addEventListener(\"load\",s);else{re.attachEvent(\"onreadystatechange\",s),e.attachEvent(\"onload\",s);var n=!1;try{n=null==e.frameElement&&re.documentElement}catch(r){}n&&n.doScroll&&!function i(){if(!pe.isReady){try{n.doScroll(\"left\")}catch(t){return e.setTimeout(i,50)}a(),pe.ready()}}()}return je.promise(t)},pe.ready.promise();var Le;for(Le in pe(fe))break;fe.ownFirst=\"0\"===Le,fe.inlineBlockNeedsLayout=!1,pe(function(){var e,t,n,r;n=re.getElementsByTagName(\"body\")[0],n&&n.style&&(t=re.createElement(\"div\"),r=re.createElement(\"div\"),r.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",n.appendChild(r).appendChild(t),\"undefined\"!=typeof t.style.zoom&&(t.style.cssText=\"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\",fe.inlineBlockNeedsLayout=e=3===t.offsetWidth,e&&(n.style.zoom=1)),n.removeChild(r))}),function(){var e=re.createElement(\"div\");fe.deleteExpando=!0;try{delete e.test}catch(t){fe.deleteExpando=!1}e=null}();var He=function(e){var t=pe.noData[(e.nodeName+\" \").toLowerCase()],n=+e.nodeType||1;return(1===n||9===n)&&(!t||t!==!0&&e.getAttribute(\"classid\")===t)},qe=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,_e=/([A-Z])/g;pe.extend({cache:{},noData:{\"applet \":!0,\"embed \":!0,\"object \":\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"},hasData:function(e){return e=e.nodeType?pe.cache[e[pe.expando]]:e[pe.expando],!!e&&!l(e)},data:function(e,t,n){return c(e,t,n)},removeData:function(e,t){return f(e,t)},_data:function(e,t,n){return c(e,t,n,!0)},_removeData:function(e,t){return f(e,t,!0)}}),pe.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=pe.data(o),1===o.nodeType&&!pe._data(o,\"parsedAttrs\"))){for(n=a.length;n--;)a[n]&&(r=a[n].name,0===r.indexOf(\"data-\")&&(r=pe.camelCase(r.slice(5)),u(o,r,i[r])));pe._data(o,\"parsedAttrs\",!0)}return i}return\"object\"==typeof e?this.each(function(){pe.data(this,e)}):arguments.length>1?this.each(function(){pe.data(this,e,t)}):o?u(o,e,pe.data(o,e)):void 0},removeData:function(e){return this.each(function(){pe.removeData(this,e)})}}),pe.extend({queue:function(e,t,n){var r;if(e)return t=(t||\"fx\")+\"queue\",r=pe._data(e,t),n&&(!r||pe.isArray(n)?r=pe._data(e,t,pe.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||\"fx\";var n=pe.queue(e,t),r=n.length,i=n.shift(),o=pe._queueHooks(e,t),a=function(){pe.dequeue(e,t)};\"inprogress\"===i&&(i=n.shift(),r--),i&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return pe._data(e,n)||pe._data(e,n,{empty:pe.Callbacks(\"once memory\").add(function(){pe._removeData(e,t+\"queue\"),pe._removeData(e,n)})})}}),pe.fn.extend({queue:function(e,t){var n=2;return\"string\"!=typeof e&&(t=e,e=\"fx\",n--),arguments.length<n?pe.queue(this[0],e):void 0===t?this:this.each(function(){var n=pe.queue(this,e,t);pe._queueHooks(this,e),\"fx\"===e&&\"inprogress\"!==n[0]&&pe.dequeue(this,e)})},dequeue:function(e){return this.each(function(){pe.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||\"fx\",[])},promise:function(e,t){var n,r=1,i=pe.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};for(\"string\"!=typeof e&&(t=e,e=void 0),e=e||\"fx\";a--;)n=pe._data(o[a],e+\"queueHooks\"),n&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}}),function(){var e;fe.shrinkWrapBlocks=function(){if(null!=e)return e;e=!1;var t,n,r;return n=re.getElementsByTagName(\"body\")[0],n&&n.style?(t=re.createElement(\"div\"),r=re.createElement(\"div\"),r.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",n.appendChild(r).appendChild(t),\"undefined\"!=typeof t.style.zoom&&(t.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1\",t.appendChild(re.createElement(\"div\")).style.width=\"5px\",e=3!==t.offsetWidth),n.removeChild(r),e):void 0}}();var Fe=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,Me=new RegExp(\"^(?:([+-])=|)(\"+Fe+\")([a-z%]*)$\",\"i\"),Oe=[\"Top\",\"Right\",\"Bottom\",\"Left\"],Re=function(e,t){return e=t||e,\"none\"===pe.css(e,\"display\")||!pe.contains(e.ownerDocument,e)},Pe=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if(\"object\"===pe.type(n)){i=!0;for(s in n)Pe(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,pe.isFunction(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(pe(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},Be=/^(?:checkbox|radio)$/i,We=/<([\\w:-]+)/,Ie=/^$|\\/(?:java|ecma)script/i,$e=/^\\s+/,ze=\"abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video\";!function(){var e=re.createElement(\"div\"),t=re.createDocumentFragment(),n=re.createElement(\"input\");e.innerHTML=\"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",fe.leadingWhitespace=3===e.firstChild.nodeType,fe.tbody=!e.getElementsByTagName(\"tbody\").length,fe.htmlSerialize=!!e.getElementsByTagName(\"link\").length,fe.html5Clone=\"<:nav></:nav>\"!==re.createElement(\"nav\").cloneNode(!0).outerHTML,n.type=\"checkbox\",n.checked=!0,t.appendChild(n),fe.appendChecked=n.checked,e.innerHTML=\"<textarea>x</textarea>\",fe.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue,t.appendChild(e),n=re.createElement(\"input\"),n.setAttribute(\"type\",\"radio\"),n.setAttribute(\"checked\",\"checked\"),n.setAttribute(\"name\",\"t\"),e.appendChild(n),fe.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,fe.noCloneEvent=!!e.addEventListener,e[pe.expando]=1,fe.attributes=!e.getAttribute(pe.expando)}();var Xe={option:[1,\"<select multiple='multiple'>\",\"</select>\"],legend:[1,\"<fieldset>\",\"</fieldset>\"],area:[1,\"<map>\",\"</map>\"],param:[1,\"<object>\",\"</object>\"],thead:[1,\"<table>\",\"</table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],col:[2,\"<table><tbody></tbody><colgroup>\",\"</colgroup></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:fe.htmlSerialize?[0,\"\",\"\"]:[1,\"X<div>\",\"</div>\"]};Xe.optgroup=Xe.option,Xe.tbody=Xe.tfoot=Xe.colgroup=Xe.caption=Xe.thead,Xe.th=Xe.td;var Ue=/<|&#?\\w+;/,Ve=/<tbody/i;!function(){var t,n,r=re.createElement(\"div\");for(t in{submit:!0,change:!0,focusin:!0})n=\"on\"+t,(fe[t]=n in e)||(r.setAttribute(n,\"t\"),fe[t]=r.attributes[n].expando===!1);r=null}();var Ye=/^(?:input|select|textarea)$/i,Je=/^key/,Ge=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ke=/^(?:focusinfocus|focusoutblur)$/,Qe=/^([^.]*)(?:\\.(.+)|)/;pe.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,m=pe._data(e);if(m){for(n.handler&&(u=n,n=u.handler,i=u.selector),n.guid||(n.guid=pe.guid++),(a=m.events)||(a=m.events={}),(c=m.handle)||(c=m.handle=function(e){return\"undefined\"==typeof pe||e&&pe.event.triggered===e.type?void 0:pe.event.dispatch.apply(c.elem,arguments)},c.elem=e),t=(t||\"\").match(De)||[\"\"],s=t.length;s--;)o=Qe.exec(t[s])||[],p=g=o[1],h=(o[2]||\"\").split(\".\").sort(),p&&(l=pe.event.special[p]||{},p=(i?l.delegateType:l.bindType)||p,l=pe.event.special[p]||{},f=pe.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&pe.expr.match.needsContext.test(i),namespace:h.join(\".\")},u),(d=a[p])||(d=a[p]=[],d.delegateCount=0,l.setup&&l.setup.call(e,r,h,c)!==!1||(e.addEventListener?e.addEventListener(p,c,!1):e.attachEvent&&e.attachEvent(\"on\"+p,c))),l.add&&(l.add.call(e,f),f.handler.guid||(f.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,f):d.push(f),pe.event.global[p]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,m=pe.hasData(e)&&pe._data(e);if(m&&(c=m.events)){for(t=(t||\"\").match(De)||[\"\"],l=t.length;l--;)if(s=Qe.exec(t[l])||[],p=g=s[1],h=(s[2]||\"\").split(\".\").sort(),p){for(f=pe.event.special[p]||{},p=(r?f.delegateType:f.bindType)||p,d=c[p]||[],s=s[2]&&new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),u=o=d.length;o--;)a=d[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&(\"**\"!==r||!a.selector)||(d.splice(o,1),a.selector&&d.delegateCount--,f.remove&&f.remove.call(e,a));u&&!d.length&&(f.teardown&&f.teardown.call(e,h,m.handle)!==!1||pe.removeEvent(e,p,m.handle),delete c[p])}else for(p in c)pe.event.remove(e,p+t[l],n,r,!0);pe.isEmptyObject(c)&&(delete m.handle,pe._removeData(e,\"events\"))}},trigger:function(t,n,r,i){var o,a,s,u,l,c,f,d=[r||re],p=ce.call(t,\"type\")?t.type:t,h=ce.call(t,\"namespace\")?t.namespace.split(\".\"):[];if(s=c=r=r||re,3!==r.nodeType&&8!==r.nodeType&&!Ke.test(p+pe.event.triggered)&&(p.indexOf(\".\")>-1&&(h=p.split(\".\"),p=h.shift(),h.sort()),a=p.indexOf(\":\")<0&&\"on\"+p,t=t[pe.expando]?t:new pe.Event(p,\"object\"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=h.join(\".\"),t.rnamespace=t.namespace?new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:pe.makeArray(n,[t]),l=pe.event.special[p]||{},i||!l.trigger||l.trigger.apply(r,n)!==!1)){if(!i&&!l.noBubble&&!pe.isWindow(r)){for(u=l.delegateType||p,Ke.test(u+p)||(s=s.parentNode);s;s=s.parentNode)d.push(s),c=s;c===(r.ownerDocument||re)&&d.push(c.defaultView||c.parentWindow||e)}for(f=0;(s=d[f++])&&!t.isPropagationStopped();)t.type=f>1?u:l.bindType||p,o=(pe._data(s,\"events\")||{})[t.type]&&pe._data(s,\"handle\"),o&&o.apply(s,n),o=a&&s[a],o&&o.apply&&He(s)&&(t.result=o.apply(s,n),t.result===!1&&t.preventDefault());if(t.type=p,!i&&!t.isDefaultPrevented()&&(!l._default||l._default.apply(d.pop(),n)===!1)&&He(r)&&a&&r[p]&&!pe.isWindow(r)){c=r[a],c&&(r[a]=null),pe.event.triggered=p;try{r[p]()}catch(g){}pe.event.triggered=void 0,c&&(r[a]=c)}return t.result}},dispatch:function(e){e=pe.event.fix(e);var t,n,r,i,o,a=[],s=ie.call(arguments),u=(pe._data(this,\"events\")||{})[e.type]||[],l=pe.event.special[e.type]||{};if(s[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){for(a=pe.event.handlers.call(this,e,u),t=0;(i=a[t++])&&!e.isPropagationStopped();)for(e.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!e.isImmediatePropagationStopped();)e.rnamespace&&!e.rnamespace.test(o.namespace)||(e.handleObj=o,e.data=o.data,r=((pe.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s),void 0!==r&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,a=[],s=t.delegateCount,u=e.target;if(s&&u.nodeType&&(\"click\"!==e.type||isNaN(e.button)||e.button<1))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||\"click\"!==e.type)){for(r=[],n=0;n<s;n++)o=t[n],i=o.selector+\" \",void 0===r[i]&&(r[i]=o.needsContext?pe(i,this).index(u)>-1:pe.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&a.push({elem:u,handlers:r})}return s<t.length&&a.push({elem:this,handlers:t.slice(s)}),a},fix:function(e){if(e[pe.expando])return e;var t,n,r,i=e.type,o=e,a=this.fixHooks[i];for(a||(this.fixHooks[i]=a=Ge.test(i)?this.mouseHooks:Je.test(i)?this.keyHooks:{}),r=a.props?this.props.concat(a.props):this.props,e=new pe.Event(o),t=r.length;t--;)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||re),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,a.filter?a.filter(e,o):e},props:\"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),fixHooks:{},keyHooks:{props:\"char charCode key keyCode\".split(\" \"),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:\"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),filter:function(e,t){var n,r,i,o=t.button,a=t.fromElement;return null==e.pageX&&null!=t.clientX&&(r=e.target.ownerDocument||re,i=r.documentElement,n=r.body,e.pageX=t.clientX+(i&&i.scrollLeft||n&&n.scrollLeft||0)-(i&&i.clientLeft||n&&n.clientLeft||0),e.pageY=t.clientY+(i&&i.scrollTop||n&&n.scrollTop||0)-(i&&i.clientTop||n&&n.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?t.toElement:a),e.which||void 0===o||(e.which=1&o?1:2&o?3:4&o?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==b()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:\"focusin\"},blur:{trigger:function(){if(this===b()&&this.blur)return this.blur(),!1},delegateType:\"focusout\"},click:{trigger:function(){if(pe.nodeName(this,\"input\")&&\"checkbox\"===this.type&&this.click)return this.click(),!1},_default:function(e){return pe.nodeName(e.target,\"a\")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n){var r=pe.extend(new pe.Event,n,{type:e,isSimulated:!0});pe.event.trigger(r,null,t),r.isDefaultPrevented()&&n.preventDefault()}},pe.removeEvent=re.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)}:function(e,t,n){var r=\"on\"+t;e.detachEvent&&(\"undefined\"==typeof e[r]&&(e[r]=null),e.detachEvent(r,n))},pe.Event=function(e,t){return this instanceof pe.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&e.returnValue===!1?v:x):this.type=e,t&&pe.extend(this,t),this.timeStamp=e&&e.timeStamp||pe.now(),void(this[pe.expando]=!0)):new pe.Event(e,t)},pe.Event.prototype={constructor:pe.Event,isDefaultPrevented:x,isPropagationStopped:x,isImmediatePropagationStopped:x,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=v,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=v,e&&!this.isSimulated&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=v,e&&e.stopImmediatePropagation&&e.stopImmediatePropagation(),this.stopPropagation()}},pe.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(e,t){pe.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return i&&(i===r||pe.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),fe.submit||(pe.event.special.submit={setup:function(){return!pe.nodeName(this,\"form\")&&void pe.event.add(this,\"click._submit keypress._submit\",function(e){var t=e.target,n=pe.nodeName(t,\"input\")||pe.nodeName(t,\"button\")?pe.prop(t,\"form\"):void 0;n&&!pe._data(n,\"submit\")&&(pe.event.add(n,\"submit._submit\",function(e){e._submitBubble=!0}),pe._data(n,\"submit\",!0))})},postDispatch:function(e){e._submitBubble&&(delete e._submitBubble,this.parentNode&&!e.isTrigger&&pe.event.simulate(\"submit\",this.parentNode,e))},teardown:function(){return!pe.nodeName(this,\"form\")&&void pe.event.remove(this,\"._submit\")}}),fe.change||(pe.event.special.change={setup:function(){return Ye.test(this.nodeName)?(\"checkbox\"!==this.type&&\"radio\"!==this.type||(pe.event.add(this,\"propertychange._change\",function(e){\"checked\"===e.originalEvent.propertyName&&(this._justChanged=!0)}),pe.event.add(this,\"click._change\",function(e){this._justChanged&&!e.isTrigger&&(this._justChanged=!1),pe.event.simulate(\"change\",this,e)})),!1):void pe.event.add(this,\"beforeactivate._change\",function(e){var t=e.target;Ye.test(t.nodeName)&&!pe._data(t,\"change\")&&(pe.event.add(t,\"change._change\",function(e){!this.parentNode||e.isSimulated||e.isTrigger||pe.event.simulate(\"change\",this.parentNode,e)}),pe._data(t,\"change\",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||\"radio\"!==t.type&&\"checkbox\"!==t.type)return e.handleObj.handler.apply(this,arguments)},teardown:function(){return pe.event.remove(this,\"._change\"),!Ye.test(this.nodeName)}}),fe.focusin||pe.each({focus:\"focusin\",blur:\"focusout\"},function(e,t){var n=function(e){pe.event.simulate(t,e.target,pe.event.fix(e))};pe.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=pe._data(r,t);i||r.addEventListener(e,n,!0),pe._data(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=pe._data(r,t)-1;i?pe._data(r,t,i):(r.removeEventListener(e,n,!0),pe._removeData(r,t))}}}),pe.fn.extend({on:function(e,t,n,r){return w(this,e,t,n,r)},one:function(e,t,n,r){return w(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,pe(e.delegateTarget).off(r.namespace?r.origType+\".\"+r.namespace:r.origType,r.selector,r.handler),this;if(\"object\"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return t!==!1&&\"function\"!=typeof t||(n=t,t=void 0),n===!1&&(n=x),this.each(function(){pe.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){pe.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return pe.event.trigger(e,t,n,!0)}});var Ze=/ jQuery\\d+=\"(?:null|\\d+)\"/g,et=new RegExp(\"<(?:\"+ze+\")[\\\\s/>]\",\"i\"),tt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:-]+)[^>]*)\\/>/gi,nt=/<script|<style|<link/i,rt=/checked\\s*(?:[^=]|=\\s*.checked.)/i,it=/^true\\/(.*)/,ot=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,at=p(re),st=at.appendChild(re.createElement(\"div\"));pe.extend({htmlPrefilter:function(e){return e.replace(tt,\"<$1></$2>\")},clone:function(e,t,n){var r,i,o,a,s,u=pe.contains(e.ownerDocument,e);if(fe.html5Clone||pe.isXMLDoc(e)||!et.test(\"<\"+e.nodeName+\">\")?o=e.cloneNode(!0):(st.innerHTML=e.outerHTML,st.removeChild(o=st.firstChild)),!(fe.noCloneEvent&&fe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||pe.isXMLDoc(e)))for(r=h(o),s=h(e),a=0;null!=(i=s[a]);++a)r[a]&&k(i,r[a]);if(t)if(n)for(s=s||h(e),r=r||h(o),a=0;null!=(i=s[a]);a++)N(i,r[a]);else N(e,o);return r=h(o,\"script\"),r.length>0&&g(r,!u&&h(e,\"script\")),r=s=i=null,o},cleanData:function(e,t){for(var n,r,i,o,a=0,s=pe.expando,u=pe.cache,l=fe.attributes,c=pe.event.special;null!=(n=e[a]);a++)if((t||He(n))&&(i=n[s],o=i&&u[i])){if(o.events)for(r in o.events)c[r]?pe.event.remove(n,r):pe.removeEvent(n,r,o.handle);u[i]&&(delete u[i],l||\"undefined\"==typeof n.removeAttribute?n[s]=void 0:n.removeAttribute(s),ne.push(i))}}}),pe.fn.extend({domManip:S,detach:function(e){return A(this,e,!0)},remove:function(e){return A(this,e)},text:function(e){return Pe(this,function(e){return void 0===e?pe.text(this):this.empty().append((this[0]&&this[0].ownerDocument||re).createTextNode(e))},null,e,arguments.length)},append:function(){return S(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=T(this,e);t.appendChild(e)}})},prepend:function(){return S(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=T(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return S(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return S(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++){for(1===e.nodeType&&pe.cleanData(h(e,!1));e.firstChild;)e.removeChild(e.firstChild);e.options&&pe.nodeName(e,\"select\")&&(e.options.length=0)}return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return pe.clone(this,e,t)})},html:function(e){return Pe(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e)return 1===t.nodeType?t.innerHTML.replace(Ze,\"\"):void 0;if(\"string\"==typeof e&&!nt.test(e)&&(fe.htmlSerialize||!et.test(e))&&(fe.leadingWhitespace||!$e.test(e))&&!Xe[(We.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=pe.htmlPrefilter(e);try{for(;n<r;n++)t=this[n]||{},1===t.nodeType&&(pe.cleanData(h(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return S(this,arguments,function(t){var n=this.parentNode;pe.inArray(this,e)<0&&(pe.cleanData(h(this)),\nn&&n.replaceChild(t,this))},e)}}),pe.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(e,t){pe.fn[e]=function(e){for(var n,r=0,i=[],o=pe(e),a=o.length-1;r<=a;r++)n=r===a?this:this.clone(!0),pe(o[r])[t](n),ae.apply(i,n.get());return this.pushStack(i)}});var ut,lt={HTML:\"block\",BODY:\"block\"},ct=/^margin/,ft=new RegExp(\"^(\"+Fe+\")(?!px)[a-z%]+$\",\"i\"),dt=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i},pt=re.documentElement;!function(){function t(){var t,c,f=re.documentElement;f.appendChild(u),l.style.cssText=\"-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%\",n=i=s=!1,r=a=!0,e.getComputedStyle&&(c=e.getComputedStyle(l),n=\"1%\"!==(c||{}).top,s=\"2px\"===(c||{}).marginLeft,i=\"4px\"===(c||{width:\"4px\"}).width,l.style.marginRight=\"50%\",r=\"4px\"===(c||{marginRight:\"4px\"}).marginRight,t=l.appendChild(re.createElement(\"div\")),t.style.cssText=l.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0\",t.style.marginRight=t.style.width=\"0\",l.style.width=\"1px\",a=!parseFloat((e.getComputedStyle(t)||{}).marginRight),l.removeChild(t)),l.style.display=\"none\",o=0===l.getClientRects().length,o&&(l.style.display=\"\",l.innerHTML=\"<table><tr><td></td><td>t</td></tr></table>\",t=l.getElementsByTagName(\"td\"),t[0].style.cssText=\"margin:0;border:0;padding:0;display:none\",o=0===t[0].offsetHeight,o&&(t[0].style.display=\"\",t[1].style.display=\"none\",o=0===t[0].offsetHeight)),f.removeChild(u)}var n,r,i,o,a,s,u=re.createElement(\"div\"),l=re.createElement(\"div\");l.style&&(l.style.cssText=\"float:left;opacity:.5\",fe.opacity=\"0.5\"===l.style.opacity,fe.cssFloat=!!l.style.cssFloat,l.style.backgroundClip=\"content-box\",l.cloneNode(!0).style.backgroundClip=\"\",fe.clearCloneStyle=\"content-box\"===l.style.backgroundClip,u=re.createElement(\"div\"),u.style.cssText=\"border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute\",l.innerHTML=\"\",u.appendChild(l),fe.boxSizing=\"\"===l.style.boxSizing||\"\"===l.style.MozBoxSizing||\"\"===l.style.WebkitBoxSizing,pe.extend(fe,{reliableHiddenOffsets:function(){return null==n&&t(),o},boxSizingReliable:function(){return null==n&&t(),i},pixelMarginRight:function(){return null==n&&t(),r},pixelPosition:function(){return null==n&&t(),n},reliableMarginRight:function(){return null==n&&t(),a},reliableMarginLeft:function(){return null==n&&t(),s}}))}();var ht,gt,mt=/^(top|right|bottom|left)$/;e.getComputedStyle?(ht=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},gt=function(e,t,n){var r,i,o,a,s=e.style;return n=n||ht(e),a=n?n.getPropertyValue(t)||n[t]:void 0,\"\"!==a&&void 0!==a||pe.contains(e.ownerDocument,e)||(a=pe.style(e,t)),n&&!fe.pixelMarginRight()&&ft.test(a)&&ct.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o),void 0===a?a:a+\"\"}):pt.currentStyle&&(ht=function(e){return e.currentStyle},gt=function(e,t,n){var r,i,o,a,s=e.style;return n=n||ht(e),a=n?n[t]:void 0,null==a&&s&&s[t]&&(a=s[t]),ft.test(a)&&!mt.test(t)&&(r=s.left,i=e.runtimeStyle,o=i&&i.left,o&&(i.left=e.currentStyle.left),s.left=\"fontSize\"===t?\"1em\":a,a=s.pixelLeft+\"px\",s.left=r,o&&(i.left=o)),void 0===a?a:a+\"\"||\"auto\"});var yt=/alpha\\([^)]*\\)/i,vt=/opacity\\s*=\\s*([^)]*)/i,xt=/^(none|table(?!-c[ea]).+)/,bt=new RegExp(\"^(\"+Fe+\")(.*)$\",\"i\"),wt={position:\"absolute\",visibility:\"hidden\",display:\"block\"},Tt={letterSpacing:\"0\",fontWeight:\"400\"},Ct=[\"Webkit\",\"O\",\"Moz\",\"ms\"],Et=re.createElement(\"div\").style;pe.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=gt(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{\"float\":fe.cssFloat?\"cssFloat\":\"styleFloat\"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=pe.camelCase(t),u=e.style;if(t=pe.cssProps[s]||(pe.cssProps[s]=H(s)||s),a=pe.cssHooks[t]||pe.cssHooks[s],void 0===n)return a&&\"get\"in a&&void 0!==(i=a.get(e,!1,r))?i:u[t];if(o=typeof n,\"string\"===o&&(i=Me.exec(n))&&i[1]&&(n=d(e,t,i),o=\"number\"),null!=n&&n===n&&(\"number\"===o&&(n+=i&&i[3]||(pe.cssNumber[s]?\"\":\"px\")),fe.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(u[t]=\"inherit\"),!(a&&\"set\"in a&&void 0===(n=a.set(e,n,r)))))try{u[t]=n}catch(l){}}},css:function(e,t,n,r){var i,o,a,s=pe.camelCase(t);return t=pe.cssProps[s]||(pe.cssProps[s]=H(s)||s),a=pe.cssHooks[t]||pe.cssHooks[s],a&&\"get\"in a&&(o=a.get(e,!0,n)),void 0===o&&(o=gt(e,t,r)),\"normal\"===o&&t in Tt&&(o=Tt[t]),\"\"===n||n?(i=parseFloat(o),n===!0||isFinite(i)?i||0:o):o}}),pe.each([\"height\",\"width\"],function(e,t){pe.cssHooks[t]={get:function(e,n,r){if(n)return xt.test(pe.css(e,\"display\"))&&0===e.offsetWidth?dt(e,wt,function(){return M(e,t,r)}):M(e,t,r)},set:function(e,n,r){var i=r&&ht(e);return _(e,n,r?F(e,t,r,fe.boxSizing&&\"border-box\"===pe.css(e,\"boxSizing\",!1,i),i):0)}}}),fe.opacity||(pe.cssHooks.opacity={get:function(e,t){return vt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||\"\")?.01*parseFloat(RegExp.$1)+\"\":t?\"1\":\"\"},set:function(e,t){var n=e.style,r=e.currentStyle,i=pe.isNumeric(t)?\"alpha(opacity=\"+100*t+\")\":\"\",o=r&&r.filter||n.filter||\"\";n.zoom=1,(t>=1||\"\"===t)&&\"\"===pe.trim(o.replace(yt,\"\"))&&n.removeAttribute&&(n.removeAttribute(\"filter\"),\"\"===t||r&&!r.filter)||(n.filter=yt.test(o)?o.replace(yt,i):o+\" \"+i)}}),pe.cssHooks.marginRight=L(fe.reliableMarginRight,function(e,t){if(t)return dt(e,{display:\"inline-block\"},gt,[e,\"marginRight\"])}),pe.cssHooks.marginLeft=L(fe.reliableMarginLeft,function(e,t){if(t)return(parseFloat(gt(e,\"marginLeft\"))||(pe.contains(e.ownerDocument,e)?e.getBoundingClientRect().left-dt(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}):0))+\"px\"}),pe.each({margin:\"\",padding:\"\",border:\"Width\"},function(e,t){pe.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o=\"string\"==typeof n?n.split(\" \"):[n];r<4;r++)i[e+Oe[r]+t]=o[r]||o[r-2]||o[0];return i}},ct.test(e)||(pe.cssHooks[e+t].set=_)}),pe.fn.extend({css:function(e,t){return Pe(this,function(e,t,n){var r,i,o={},a=0;if(pe.isArray(t)){for(r=ht(e),i=t.length;a<i;a++)o[t[a]]=pe.css(e,t[a],!1,r);return o}return void 0!==n?pe.style(e,t,n):pe.css(e,t)},e,t,arguments.length>1)},show:function(){return q(this,!0)},hide:function(){return q(this)},toggle:function(e){return\"boolean\"==typeof e?e?this.show():this.hide():this.each(function(){Re(this)?pe(this).show():pe(this).hide()})}}),pe.Tween=O,O.prototype={constructor:O,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||pe.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(pe.cssNumber[n]?\"\":\"px\")},cur:function(){var e=O.propHooks[this.prop];return e&&e.get?e.get(this):O.propHooks._default.get(this)},run:function(e){var t,n=O.propHooks[this.prop];return this.options.duration?this.pos=t=pe.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):O.propHooks._default.set(this),this}},O.prototype.init.prototype=O.prototype,O.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=pe.css(e.elem,e.prop,\"\"),t&&\"auto\"!==t?t:0)},set:function(e){pe.fx.step[e.prop]?pe.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[pe.cssProps[e.prop]]&&!pe.cssHooks[e.prop]?e.elem[e.prop]=e.now:pe.style(e.elem,e.prop,e.now+e.unit)}}},O.propHooks.scrollTop=O.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},pe.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:\"swing\"},pe.fx=O.prototype.init,pe.fx.step={};var Nt,kt,St=/^(?:toggle|show|hide)$/,At=/queueHooks$/;pe.Animation=pe.extend($,{tweeners:{\"*\":[function(e,t){var n=this.createTween(e,t);return d(n.elem,e,Me.exec(t),n),n}]},tweener:function(e,t){pe.isFunction(e)?(t=e,e=[\"*\"]):e=e.match(De);for(var n,r=0,i=e.length;r<i;r++)n=e[r],$.tweeners[n]=$.tweeners[n]||[],$.tweeners[n].unshift(t)},prefilters:[W],prefilter:function(e,t){t?$.prefilters.unshift(e):$.prefilters.push(e)}}),pe.speed=function(e,t,n){var r=e&&\"object\"==typeof e?pe.extend({},e):{complete:n||!n&&t||pe.isFunction(e)&&e,duration:e,easing:n&&t||t&&!pe.isFunction(t)&&t};return r.duration=pe.fx.off?0:\"number\"==typeof r.duration?r.duration:r.duration in pe.fx.speeds?pe.fx.speeds[r.duration]:pe.fx.speeds._default,null!=r.queue&&r.queue!==!0||(r.queue=\"fx\"),r.old=r.complete,r.complete=function(){pe.isFunction(r.old)&&r.old.call(this),r.queue&&pe.dequeue(this,r.queue)},r},pe.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Re).css(\"opacity\",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=pe.isEmptyObject(e),o=pe.speed(t,n,r),a=function(){var t=$(this,pe.extend({},e),o);(i||pe._data(this,\"finish\"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return\"string\"!=typeof e&&(n=t,t=e,e=void 0),t&&e!==!1&&this.queue(e||\"fx\",[]),this.each(function(){var t=!0,i=null!=e&&e+\"queueHooks\",o=pe.timers,a=pe._data(this);if(i)a[i]&&a[i].stop&&r(a[i]);else for(i in a)a[i]&&a[i].stop&&At.test(i)&&r(a[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||pe.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||\"fx\"),this.each(function(){var t,n=pe._data(this),r=n[e+\"queue\"],i=n[e+\"queueHooks\"],o=pe.timers,a=r?r.length:0;for(n.finish=!0,pe.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),pe.each([\"toggle\",\"show\",\"hide\"],function(e,t){var n=pe.fn[t];pe.fn[t]=function(e,r,i){return null==e||\"boolean\"==typeof e?n.apply(this,arguments):this.animate(P(t,!0),e,r,i)}}),pe.each({slideDown:P(\"show\"),slideUp:P(\"hide\"),slideToggle:P(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(e,t){pe.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),pe.timers=[],pe.fx.tick=function(){var e,t=pe.timers,n=0;for(Nt=pe.now();n<t.length;n++)e=t[n],e()||t[n]!==e||t.splice(n--,1);t.length||pe.fx.stop(),Nt=void 0},pe.fx.timer=function(e){pe.timers.push(e),e()?pe.fx.start():pe.timers.pop()},pe.fx.interval=13,pe.fx.start=function(){kt||(kt=e.setInterval(pe.fx.tick,pe.fx.interval))},pe.fx.stop=function(){e.clearInterval(kt),kt=null},pe.fx.speeds={slow:600,fast:200,_default:400},pe.fn.delay=function(t,n){return t=pe.fx?pe.fx.speeds[t]||t:t,n=n||\"fx\",this.queue(n,function(n,r){var i=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(i)}})},function(){var e,t=re.createElement(\"input\"),n=re.createElement(\"div\"),r=re.createElement(\"select\"),i=r.appendChild(re.createElement(\"option\"));n=re.createElement(\"div\"),n.setAttribute(\"className\",\"t\"),n.innerHTML=\"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",e=n.getElementsByTagName(\"a\")[0],t.setAttribute(\"type\",\"checkbox\"),n.appendChild(t),e=n.getElementsByTagName(\"a\")[0],e.style.cssText=\"top:1px\",fe.getSetAttribute=\"t\"!==n.className,fe.style=/top/.test(e.getAttribute(\"style\")),fe.hrefNormalized=\"/a\"===e.getAttribute(\"href\"),fe.checkOn=!!t.value,fe.optSelected=i.selected,fe.enctype=!!re.createElement(\"form\").enctype,r.disabled=!0,fe.optDisabled=!i.disabled,t=re.createElement(\"input\"),t.setAttribute(\"value\",\"\"),fe.input=\"\"===t.getAttribute(\"value\"),t.value=\"t\",t.setAttribute(\"type\",\"radio\"),fe.radioValue=\"t\"===t.value}();var Dt=/\\r/g,jt=/[\\x20\\t\\r\\n\\f]+/g;pe.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=pe.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,pe(this).val()):e,null==i?i=\"\":\"number\"==typeof i?i+=\"\":pe.isArray(i)&&(i=pe.map(i,function(e){return null==e?\"\":e+\"\"})),t=pe.valHooks[this.type]||pe.valHooks[this.nodeName.toLowerCase()],t&&\"set\"in t&&void 0!==t.set(this,i,\"value\")||(this.value=i))});if(i)return t=pe.valHooks[i.type]||pe.valHooks[i.nodeName.toLowerCase()],t&&\"get\"in t&&void 0!==(n=t.get(i,\"value\"))?n:(n=i.value,\"string\"==typeof n?n.replace(Dt,\"\"):null==n?\"\":n)}}}),pe.extend({valHooks:{option:{get:function(e){var t=pe.find.attr(e,\"value\");return null!=t?t:pe.trim(pe.text(e)).replace(jt,\" \")}},select:{get:function(e){for(var t,n,r=e.options,i=e.selectedIndex,o=\"select-one\"===e.type||i<0,a=o?null:[],s=o?i+1:r.length,u=i<0?s:o?i:0;u<s;u++)if(n=r[u],(n.selected||u===i)&&(fe.optDisabled?!n.disabled:null===n.getAttribute(\"disabled\"))&&(!n.parentNode.disabled||!pe.nodeName(n.parentNode,\"optgroup\"))){if(t=pe(n).val(),o)return t;a.push(t)}return a},set:function(e,t){for(var n,r,i=e.options,o=pe.makeArray(t),a=i.length;a--;)if(r=i[a],pe.inArray(pe.valHooks.option.get(r),o)>-1)try{r.selected=n=!0}catch(s){r.scrollHeight}else r.selected=!1;return n||(e.selectedIndex=-1),i}}}}),pe.each([\"radio\",\"checkbox\"],function(){pe.valHooks[this]={set:function(e,t){if(pe.isArray(t))return e.checked=pe.inArray(pe(e).val(),t)>-1}},fe.checkOn||(pe.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})});var Lt,Ht,qt=pe.expr.attrHandle,_t=/^(?:checked|selected)$/i,Ft=fe.getSetAttribute,Mt=fe.input;pe.fn.extend({attr:function(e,t){return Pe(this,pe.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){pe.removeAttr(this,e)})}}),pe.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return\"undefined\"==typeof e.getAttribute?pe.prop(e,t,n):(1===o&&pe.isXMLDoc(e)||(t=t.toLowerCase(),i=pe.attrHooks[t]||(pe.expr.match.bool.test(t)?Ht:Lt)),void 0!==n?null===n?void pe.removeAttr(e,t):i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+\"\"),n):i&&\"get\"in i&&null!==(r=i.get(e,t))?r:(r=pe.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!fe.radioValue&&\"radio\"===t&&pe.nodeName(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(De);if(o&&1===e.nodeType)for(;n=o[i++];)r=pe.propFix[n]||n,pe.expr.match.bool.test(n)?Mt&&Ft||!_t.test(n)?e[r]=!1:e[pe.camelCase(\"default-\"+n)]=e[r]=!1:pe.attr(e,n,\"\"),e.removeAttribute(Ft?n:r)}}),Ht={set:function(e,t,n){return t===!1?pe.removeAttr(e,n):Mt&&Ft||!_t.test(n)?e.setAttribute(!Ft&&pe.propFix[n]||n,n):e[pe.camelCase(\"default-\"+n)]=e[n]=!0,n}},pe.each(pe.expr.match.bool.source.match(/\\w+/g),function(e,t){var n=qt[t]||pe.find.attr;Mt&&Ft||!_t.test(t)?qt[t]=function(e,t,r){var i,o;return r||(o=qt[t],qt[t]=i,i=null!=n(e,t,r)?t.toLowerCase():null,qt[t]=o),i}:qt[t]=function(e,t,n){if(!n)return e[pe.camelCase(\"default-\"+t)]?t.toLowerCase():null}}),Mt&&Ft||(pe.attrHooks.value={set:function(e,t,n){return pe.nodeName(e,\"input\")?void(e.defaultValue=t):Lt&&Lt.set(e,t,n)}}),Ft||(Lt={set:function(e,t,n){var r=e.getAttributeNode(n);if(r||e.setAttributeNode(r=e.ownerDocument.createAttribute(n)),r.value=t+=\"\",\"value\"===n||t===e.getAttribute(n))return t}},qt.id=qt.name=qt.coords=function(e,t,n){var r;if(!n)return(r=e.getAttributeNode(t))&&\"\"!==r.value?r.value:null},pe.valHooks.button={get:function(e,t){var n=e.getAttributeNode(t);if(n&&n.specified)return n.value},set:Lt.set},pe.attrHooks.contenteditable={set:function(e,t,n){Lt.set(e,\"\"!==t&&t,n)}},pe.each([\"width\",\"height\"],function(e,t){pe.attrHooks[t]={set:function(e,n){if(\"\"===n)return e.setAttribute(t,\"auto\"),n}}})),fe.style||(pe.attrHooks.style={get:function(e){return e.style.cssText||void 0},set:function(e,t){return e.style.cssText=t+\"\"}});var Ot=/^(?:input|select|textarea|button|object)$/i,Rt=/^(?:a|area)$/i;pe.fn.extend({prop:function(e,t){return Pe(this,pe.prop,e,t,arguments.length>1)},removeProp:function(e){return e=pe.propFix[e]||e,this.each(function(){try{this[e]=void 0,delete this[e]}catch(t){}})}}),pe.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&pe.isXMLDoc(e)||(t=pe.propFix[t]||t,i=pe.propHooks[t]),void 0!==n?i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&\"get\"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=pe.find.attr(e,\"tabindex\");return t?parseInt(t,10):Ot.test(e.nodeName)||Rt.test(e.nodeName)&&e.href?0:-1}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"}}),fe.hrefNormalized||pe.each([\"href\",\"src\"],function(e,t){pe.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),fe.optSelected||(pe.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),pe.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){pe.propFix[this.toLowerCase()]=this}),fe.enctype||(pe.propFix.enctype=\"encoding\");var Pt=/[\\t\\r\\n\\f]/g;pe.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(pe.isFunction(e))return this.each(function(t){pe(this).addClass(e.call(this,t,z(this)))});if(\"string\"==typeof e&&e)for(t=e.match(De)||[];n=this[u++];)if(i=z(n),r=1===n.nodeType&&(\" \"+i+\" \").replace(Pt,\" \")){for(a=0;o=t[a++];)r.indexOf(\" \"+o+\" \")<0&&(r+=o+\" \");s=pe.trim(r),i!==s&&pe.attr(n,\"class\",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(pe.isFunction(e))return this.each(function(t){pe(this).removeClass(e.call(this,t,z(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if(\"string\"==typeof e&&e)for(t=e.match(De)||[];n=this[u++];)if(i=z(n),r=1===n.nodeType&&(\" \"+i+\" \").replace(Pt,\" \")){for(a=0;o=t[a++];)for(;r.indexOf(\" \"+o+\" \")>-1;)r=r.replace(\" \"+o+\" \",\" \");s=pe.trim(r),i!==s&&pe.attr(n,\"class\",s)}return this},toggleClass:function(e,t){var n=typeof e;return\"boolean\"==typeof t&&\"string\"===n?t?this.addClass(e):this.removeClass(e):pe.isFunction(e)?this.each(function(n){pe(this).toggleClass(e.call(this,n,z(this),t),t)}):this.each(function(){var t,r,i,o;if(\"string\"===n)for(r=0,i=pe(this),o=e.match(De)||[];t=o[r++];)i.hasClass(t)?i.removeClass(t):i.addClass(t);else void 0!==e&&\"boolean\"!==n||(t=z(this),t&&pe._data(this,\"__className__\",t),pe.attr(this,\"class\",t||e===!1?\"\":pe._data(this,\"__className__\")||\"\"))})},hasClass:function(e){var t,n,r=0;for(t=\" \"+e+\" \";n=this[r++];)if(1===n.nodeType&&(\" \"+z(n)+\" \").replace(Pt,\" \").indexOf(t)>-1)return!0;return!1}}),pe.each(\"blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu\".split(\" \"),function(e,t){pe.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),pe.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}});var Bt=e.location,Wt=pe.now(),It=/\\?/,$t=/(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;pe.parseJSON=function(t){if(e.JSON&&e.JSON.parse)return e.JSON.parse(t+\"\");var n,r=null,i=pe.trim(t+\"\");return i&&!pe.trim(i.replace($t,function(e,t,i,o){return n&&t&&(r=0),0===r?e:(n=i||t,r+=!o-!i,\"\")}))?Function(\"return \"+i)():pe.error(\"Invalid JSON: \"+t)},pe.parseXML=function(t){var n,r;if(!t||\"string\"!=typeof t)return null;try{e.DOMParser?(r=new e.DOMParser,n=r.parseFromString(t,\"text/xml\")):(n=new e.ActiveXObject(\"Microsoft.XMLDOM\"),n.async=\"false\",n.loadXML(t))}catch(i){n=void 0}return n&&n.documentElement&&!n.getElementsByTagName(\"parsererror\").length||pe.error(\"Invalid XML: \"+t),n};var zt=/#.*$/,Xt=/([?&])_=[^&]*/,Ut=/^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/gm,Vt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Yt=/^(?:GET|HEAD)$/,Jt=/^\\/\\//,Gt=/^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,Kt={},Qt={},Zt=\"*/\".concat(\"*\"),en=Bt.href,tn=Gt.exec(en.toLowerCase())||[];pe.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:en,type:\"GET\",isLocal:Vt.test(tn[1]),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Zt,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":pe.parseJSON,\"text xml\":pe.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?V(V(e,pe.ajaxSettings),t):V(pe.ajaxSettings,e)},ajaxPrefilter:X(Kt),ajaxTransport:X(Qt),ajax:function(t,n){function r(t,n,r,i){var o,f,v,x,w,C=n;2!==b&&(b=2,u&&e.clearTimeout(u),c=void 0,s=i||\"\",T.readyState=t>0?4:0,o=t>=200&&t<300||304===t,r&&(x=Y(d,T,r)),x=J(d,x,T,o),o?(d.ifModified&&(w=T.getResponseHeader(\"Last-Modified\"),w&&(pe.lastModified[a]=w),w=T.getResponseHeader(\"etag\"),w&&(pe.etag[a]=w)),204===t||\"HEAD\"===d.type?C=\"nocontent\":304===t?C=\"notmodified\":(C=x.state,f=x.data,v=x.error,o=!v)):(v=C,!t&&C||(C=\"error\",t<0&&(t=0))),T.status=t,T.statusText=(n||C)+\"\",o?g.resolveWith(p,[f,C,T]):g.rejectWith(p,[T,C,v]),T.statusCode(y),y=void 0,l&&h.trigger(o?\"ajaxSuccess\":\"ajaxError\",[T,d,o?f:v]),m.fireWith(p,[T,C]),l&&(h.trigger(\"ajaxComplete\",[T,d]),--pe.active||pe.event.trigger(\"ajaxStop\")))}\"object\"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,d=pe.ajaxSetup({},n),p=d.context||d,h=d.context&&(p.nodeType||p.jquery)?pe(p):pe.event,g=pe.Deferred(),m=pe.Callbacks(\"once memory\"),y=d.statusCode||{},v={},x={},b=0,w=\"canceled\",T={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!f)for(f={};t=Ut.exec(s);)f[t[1].toLowerCase()]=t[2];t=f[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?s:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=x[n]=x[n]||e,v[e]=t),this},overrideMimeType:function(e){return b||(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(b<2)for(t in e)y[t]=[y[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||w;return c&&c.abort(t),r(0,t),this}};if(g.promise(T).complete=m.add,T.success=T.done,T.error=T.fail,d.url=((t||d.url||en)+\"\").replace(zt,\"\").replace(Jt,tn[1]+\"//\"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=pe.trim(d.dataType||\"*\").toLowerCase().match(De)||[\"\"],null==d.crossDomain&&(i=Gt.exec(d.url.toLowerCase()),d.crossDomain=!(!i||i[1]===tn[1]&&i[2]===tn[2]&&(i[3]||(\"http:\"===i[1]?\"80\":\"443\"))===(tn[3]||(\"http:\"===tn[1]?\"80\":\"443\")))),d.data&&d.processData&&\"string\"!=typeof d.data&&(d.data=pe.param(d.data,d.traditional)),U(Kt,d,n,T),2===b)return T;l=pe.event&&d.global,l&&0===pe.active++&&pe.event.trigger(\"ajaxStart\"),d.type=d.type.toUpperCase(),d.hasContent=!Yt.test(d.type),a=d.url,d.hasContent||(d.data&&(a=d.url+=(It.test(a)?\"&\":\"?\")+d.data,delete d.data),d.cache===!1&&(d.url=Xt.test(a)?a.replace(Xt,\"$1_=\"+Wt++):a+(It.test(a)?\"&\":\"?\")+\"_=\"+Wt++)),d.ifModified&&(pe.lastModified[a]&&T.setRequestHeader(\"If-Modified-Since\",pe.lastModified[a]),pe.etag[a]&&T.setRequestHeader(\"If-None-Match\",pe.etag[a])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&T.setRequestHeader(\"Content-Type\",d.contentType),T.setRequestHeader(\"Accept\",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(\"*\"!==d.dataTypes[0]?\", \"+Zt+\"; q=0.01\":\"\"):d.accepts[\"*\"]);for(o in d.headers)T.setRequestHeader(o,d.headers[o]);if(d.beforeSend&&(d.beforeSend.call(p,T,d)===!1||2===b))return T.abort();w=\"abort\";for(o in{success:1,error:1,complete:1})T[o](d[o]);if(c=U(Qt,d,n,T)){if(T.readyState=1,l&&h.trigger(\"ajaxSend\",[T,d]),2===b)return T;d.async&&d.timeout>0&&(u=e.setTimeout(function(){T.abort(\"timeout\")},d.timeout));try{b=1,c.send(v,r)}catch(C){if(!(b<2))throw C;r(-1,C)}}else r(-1,\"No Transport\");return T},getJSON:function(e,t,n){return pe.get(e,t,n,\"json\")},getScript:function(e,t){return pe.get(e,void 0,t,\"script\")}}),pe.each([\"get\",\"post\"],function(e,t){pe[t]=function(e,n,r,i){return pe.isFunction(n)&&(i=i||r,r=n,n=void 0),pe.ajax(pe.extend({url:e,type:t,dataType:i,data:n,success:r},pe.isPlainObject(e)&&e))}}),pe._evalUrl=function(e){return pe.ajax({url:e,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,\"throws\":!0})},pe.fn.extend({wrapAll:function(e){if(pe.isFunction(e))return this.each(function(t){pe(this).wrapAll(e.call(this,t))});if(this[0]){var t=pe(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstChild&&1===e.firstChild.nodeType;)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return pe.isFunction(e)?this.each(function(t){pe(this).wrapInner(e.call(this,t))}):this.each(function(){var t=pe(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=pe.isFunction(e);return this.each(function(n){pe(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){pe.nodeName(this,\"body\")||pe(this).replaceWith(this.childNodes)}).end()}}),pe.expr.filters.hidden=function(e){return fe.reliableHiddenOffsets()?e.offsetWidth<=0&&e.offsetHeight<=0&&!e.getClientRects().length:K(e)},pe.expr.filters.visible=function(e){return!pe.expr.filters.hidden(e)};var nn=/%20/g,rn=/\\[\\]$/,on=/\\r?\\n/g,an=/^(?:submit|button|image|reset|file)$/i,sn=/^(?:input|select|textarea|keygen)/i;pe.param=function(e,t){var n,r=[],i=function(e,t){t=pe.isFunction(t)?t():null==t?\"\":t,r[r.length]=encodeURIComponent(e)+\"=\"+encodeURIComponent(t)};if(void 0===t&&(t=pe.ajaxSettings&&pe.ajaxSettings.traditional),pe.isArray(e)||e.jquery&&!pe.isPlainObject(e))pe.each(e,function(){i(this.name,this.value)});else for(n in e)Q(n,e[n],t,i);return r.join(\"&\").replace(nn,\"+\")},pe.fn.extend({serialize:function(){return pe.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=pe.prop(this,\"elements\");return e?pe.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!pe(this).is(\":disabled\")&&sn.test(this.nodeName)&&!an.test(e)&&(this.checked||!Be.test(e))}).map(function(e,t){var n=pe(this).val();return null==n?null:pe.isArray(n)?pe.map(n,function(e){return{name:t.name,value:e.replace(on,\"\\r\\n\")}}):{name:t.name,value:n.replace(on,\"\\r\\n\")}}).get()}}),pe.ajaxSettings.xhr=void 0!==e.ActiveXObject?function(){return this.isLocal?ee():re.documentMode>8?Z():/^(get|post|head|put|delete|options)$/i.test(this.type)&&Z()||ee()}:Z;var un=0,ln={},cn=pe.ajaxSettings.xhr();e.attachEvent&&e.attachEvent(\"onunload\",function(){for(var e in ln)ln[e](void 0,!0)}),fe.cors=!!cn&&\"withCredentials\"in cn,cn=fe.ajax=!!cn,cn&&pe.ajaxTransport(function(t){if(!t.crossDomain||fe.cors){var n;return{send:function(r,i){var o,a=t.xhr(),s=++un;if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(o in t.xhrFields)a[o]=t.xhrFields[o];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||r[\"X-Requested-With\"]||(r[\"X-Requested-With\"]=\"XMLHttpRequest\");for(o in r)void 0!==r[o]&&a.setRequestHeader(o,r[o]+\"\");a.send(t.hasContent&&t.data||null),n=function(e,r){var o,u,l;if(n&&(r||4===a.readyState))if(delete ln[s],n=void 0,a.onreadystatechange=pe.noop,r)4!==a.readyState&&a.abort();else{l={},o=a.status,\"string\"==typeof a.responseText&&(l.text=a.responseText);try{u=a.statusText}catch(c){u=\"\"}o||!t.isLocal||t.crossDomain?1223===o&&(o=204):o=l.text?200:404}l&&i(o,u,l,a.getAllResponseHeaders())},t.async?4===a.readyState?e.setTimeout(n):a.onreadystatechange=ln[s]=n:n()},abort:function(){n&&n(void 0,!0)}}}}),pe.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(e){return pe.globalEval(e),e}}}),pe.ajaxPrefilter(\"script\",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type=\"GET\",e.global=!1)}),pe.ajaxTransport(\"script\",function(e){if(e.crossDomain){var t,n=re.head||pe(\"head\")[0]||re.documentElement;return{send:function(r,i){t=re.createElement(\"script\"),t.async=!0,e.scriptCharset&&(t.charset=e.scriptCharset),t.src=e.url,t.onload=t.onreadystatechange=function(e,n){(n||!t.readyState||/loaded|complete/.test(t.readyState))&&(t.onload=t.onreadystatechange=null,t.parentNode&&t.parentNode.removeChild(t),t=null,n||i(200,\"success\"))},n.insertBefore(t,n.firstChild)},abort:function(){t&&t.onload(void 0,!0)}}}});var fn=[],dn=/(=)\\?(?=&|$)|\\?\\?/;pe.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=fn.pop()||pe.expando+\"_\"+Wt++;return this[e]=!0,e}}),pe.ajaxPrefilter(\"json jsonp\",function(t,n,r){var i,o,a,s=t.jsonp!==!1&&(dn.test(t.url)?\"url\":\"string\"==typeof t.data&&0===(t.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&dn.test(t.data)&&\"data\");if(s||\"jsonp\"===t.dataTypes[0])return i=t.jsonpCallback=pe.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(dn,\"$1\"+i):t.jsonp!==!1&&(t.url+=(It.test(t.url)?\"&\":\"?\")+t.jsonp+\"=\"+i),t.converters[\"script json\"]=function(){return a||pe.error(i+\" was not called\"),a[0]},t.dataTypes[0]=\"json\",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?pe(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,fn.push(i)),a&&pe.isFunction(o)&&o(a[0]),a=o=void 0}),\"script\"}),pe.parseHTML=function(e,t,n){if(!e||\"string\"!=typeof e)return null;\"boolean\"==typeof t&&(n=t,t=!1),t=t||re;var r=Te.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=y([e],t,i),i&&i.length&&pe(i).remove(),pe.merge([],r.childNodes))};var pn=pe.fn.load;return pe.fn.load=function(e,t,n){if(\"string\"!=typeof e&&pn)return pn.apply(this,arguments);var r,i,o,a=this,s=e.indexOf(\" \");return s>-1&&(r=pe.trim(e.slice(s,e.length)),e=e.slice(0,s)),pe.isFunction(t)?(n=t,t=void 0):t&&\"object\"==typeof t&&(i=\"POST\"),a.length>0&&pe.ajax({url:e,type:i||\"GET\",dataType:\"html\",data:t}).done(function(e){o=arguments,a.html(r?pe(\"<div>\").append(pe.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},pe.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){pe.fn[t]=function(e){return this.on(t,e)}}),pe.expr.filters.animated=function(e){return pe.grep(pe.timers,function(t){return e===t.elem}).length},pe.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l,c=pe.css(e,\"position\"),f=pe(e),d={};\"static\"===c&&(e.style.position=\"relative\"),s=f.offset(),o=pe.css(e,\"top\"),u=pe.css(e,\"left\"),l=(\"absolute\"===c||\"fixed\"===c)&&pe.inArray(\"auto\",[o,u])>-1,l?(r=f.position(),a=r.top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),pe.isFunction(t)&&(t=t.call(e,n,pe.extend({},s))),null!=t.top&&(d.top=t.top-s.top+a),null!=t.left&&(d.left=t.left-s.left+i),\"using\"in t?t.using.call(e,d):f.css(d)}},pe.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){pe.offset.setOffset(this,e,t)});var t,n,r={top:0,left:0},i=this[0],o=i&&i.ownerDocument;if(o)return t=o.documentElement,pe.contains(t,i)?(\"undefined\"!=typeof i.getBoundingClientRect&&(r=i.getBoundingClientRect()),n=te(o),{top:r.top+(n.pageYOffset||t.scrollTop)-(t.clientTop||0),left:r.left+(n.pageXOffset||t.scrollLeft)-(t.clientLeft||0)}):r},position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return\"fixed\"===pe.css(r,\"position\")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),pe.nodeName(e[0],\"html\")||(n=e.offset()),n.top+=pe.css(e[0],\"borderTopWidth\",!0),n.left+=pe.css(e[0],\"borderLeftWidth\",!0)),{top:t.top-n.top-pe.css(r,\"marginTop\",!0),left:t.left-n.left-pe.css(r,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){\nfor(var e=this.offsetParent;e&&!pe.nodeName(e,\"html\")&&\"static\"===pe.css(e,\"position\");)e=e.offsetParent;return e||pt})}}),pe.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(e,t){var n=/Y/.test(t);pe.fn[e]=function(r){return Pe(this,function(e,r,i){var o=te(e);return void 0===i?o?t in o?o[t]:o.document.documentElement[r]:e[r]:void(o?o.scrollTo(n?pe(o).scrollLeft():i,n?i:pe(o).scrollTop()):e[r]=i)},e,r,arguments.length,null)}}),pe.each([\"top\",\"left\"],function(e,t){pe.cssHooks[t]=L(fe.pixelPosition,function(e,n){if(n)return n=gt(e,t),ft.test(n)?pe(e).position()[t]+\"px\":n})}),pe.each({Height:\"height\",Width:\"width\"},function(e,t){pe.each({padding:\"inner\"+e,content:t,\"\":\"outer\"+e},function(n,r){pe.fn[r]=function(r,i){var o=arguments.length&&(n||\"boolean\"!=typeof r),a=n||(r===!0||i===!0?\"margin\":\"border\");return Pe(this,function(t,n,r){var i;return pe.isWindow(t)?t.document.documentElement[\"client\"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body[\"scroll\"+e],i[\"scroll\"+e],t.body[\"offset\"+e],i[\"offset\"+e],i[\"client\"+e])):void 0===r?pe.css(t,n,a):pe.style(t,n,r,a)},t,o?r:void 0,o,null)}})}),pe.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)}}),pe.fn.size=function(){return this.length},pe.fn.andSelf=pe.fn.addBack,layui.define(function(e){e(\"jquery\",pe)}),pe});!function(e,t){\"use strict\";var i,n,a=e.layui&&layui.define,o={getPath:function(){var e=document.scripts,t=e[e.length-1],i=t.src;if(!t.getAttribute(\"merge\"))return i.substring(0,i.lastIndexOf(\"/\")+1)}(),config:{},end:{},minIndex:0,minLeft:[],btn:[\"&#x786E;&#x5B9A;\",\"&#x53D6;&#x6D88;\"],type:[\"dialog\",\"page\",\"iframe\",\"loading\",\"tips\"]},r={v:\"3.0.1\",ie:function(){var t=navigator.userAgent.toLowerCase();return!!(e.ActiveXObject||\"ActiveXObject\"in e)&&((t.match(/msie\\s(\\d+)/)||[])[1]||\"11\")}(),index:e.layer&&e.layer.v?1e5:0,path:o.getPath,config:function(e,t){return e=e||{},r.cache=o.config=i.extend({},o.config,e),r.path=o.config.path||r.path,\"string\"==typeof e.extend&&(e.extend=[e.extend]),o.config.path&&r.ready(),e.extend?(a?layui.addcss(\"modules/layer/\"+e.extend):r.link(\"skin/\"+e.extend),this):this},link:function(t,n,a){if(r.path){var o=i(\"head\")[0],l=document.createElement(\"link\");\"string\"==typeof n&&(a=n);var s=(a||t).replace(/\\.|\\//g,\"\"),f=\"layuicss-\"+s,c=0;l.rel=\"stylesheet\",l.href=r.path+t,l.id=f,i(\"#\"+f)[0]||o.appendChild(l),\"function\"==typeof n&&!function d(){return++c>80?e.console&&console.error(\"layer.css: Invalid\"):void(1989===parseInt(i(\"#\"+f).css(\"width\"))?n():setTimeout(d,100))}()}},ready:function(e){var t=\"skinlayercss\",i=\"1110\";return a?layui.addcss(\"modules/layer/default/layer.css?v=\"+r.v+i,e,t):r.link(\"skin/default/layer.css?v=\"+r.v+i,e,t),this},alert:function(e,t,n){var a=\"function\"==typeof t;return a&&(n=t),r.open(i.extend({content:e,yes:n},a?{}:t))},confirm:function(e,t,n,a){var l=\"function\"==typeof t;return l&&(a=n,n=t),r.open(i.extend({content:e,btn:o.btn,yes:n,btn2:a},l?{}:t))},msg:function(e,n,a){var l=\"function\"==typeof n,f=o.config.skin,c=(f?f+\" \"+f+\"-msg\":\"\")||\"layui-layer-msg\",d=s.anim.length-1;return l&&(a=n),r.open(i.extend({content:e,time:3e3,shade:!1,skin:c,title:!1,closeBtn:!1,btn:!1,resize:!1,end:a},l&&!o.config.skin?{skin:c+\" layui-layer-hui\",anim:d}:function(){return n=n||{},(n.icon===-1||n.icon===t&&!o.config.skin)&&(n.skin=c+\" \"+(n.skin||\"layui-layer-hui\")),n}()))},load:function(e,t){return r.open(i.extend({type:3,icon:e||0,resize:!1,shade:.01},t))},tips:function(e,t,n){return r.open(i.extend({type:4,content:[e,t],closeBtn:!1,time:3e3,shade:!1,resize:!1,fixed:!1,maxWidth:210},n))}},l=function(e){var t=this;t.index=++r.index,t.config=i.extend({},t.config,o.config,e),document.body?t.creat():setTimeout(function(){t.creat()},50)};l.pt=l.prototype;var s=[\"layui-layer\",\".layui-layer-title\",\".layui-layer-main\",\".layui-layer-dialog\",\"layui-layer-iframe\",\"layui-layer-content\",\"layui-layer-btn\",\"layui-layer-close\"];s.anim=[\"layer-anim\",\"layer-anim-01\",\"layer-anim-02\",\"layer-anim-03\",\"layer-anim-04\",\"layer-anim-05\",\"layer-anim-06\"],l.pt.config={type:0,shade:.3,fixed:!0,move:s[1],title:\"&#x4FE1;&#x606F;\",offset:\"auto\",area:\"auto\",closeBtn:1,time:0,zIndex:19891014,maxWidth:360,anim:0,icon:-1,moveType:1,resize:!0,scrollbar:!0,tips:2},l.pt.vessel=function(e,t){var n=this,a=n.index,r=n.config,l=r.zIndex+a,f=\"object\"==typeof r.title,c=r.maxmin&&(1===r.type||2===r.type),d=r.title?'<div class=\"layui-layer-title\" style=\"'+(f?r.title[1]:\"\")+'\">'+(f?r.title[0]:r.title)+\"</div>\":\"\";return r.zIndex=l,t([r.shade?'<div class=\"layui-layer-shade\" id=\"layui-layer-shade'+a+'\" times=\"'+a+'\" style=\"'+(\"z-index:\"+(l-1)+\"; background-color:\"+(r.shade[1]||\"#000\")+\"; opacity:\"+(r.shade[0]||r.shade)+\"; filter:alpha(opacity=\"+(100*r.shade[0]||100*r.shade)+\");\")+'\"></div>':\"\",'<div class=\"'+s[0]+(\" layui-layer-\"+o.type[r.type])+(0!=r.type&&2!=r.type||r.shade?\"\":\" layui-layer-border\")+\" \"+(r.skin||\"\")+'\" id=\"'+s[0]+a+'\" type=\"'+o.type[r.type]+'\" times=\"'+a+'\" showtime=\"'+r.time+'\" conType=\"'+(e?\"object\":\"string\")+'\" style=\"z-index: '+l+\"; width:\"+r.area[0]+\";height:\"+r.area[1]+(r.fixed?\"\":\";position:absolute;\")+'\">'+(e&&2!=r.type?\"\":d)+'<div id=\"'+(r.id||\"\")+'\" class=\"layui-layer-content'+(0==r.type&&r.icon!==-1?\" layui-layer-padding\":\"\")+(3==r.type?\" layui-layer-loading\"+r.icon:\"\")+'\">'+(0==r.type&&r.icon!==-1?'<i class=\"layui-layer-ico layui-layer-ico'+r.icon+'\"></i>':\"\")+(1==r.type&&e?\"\":r.content||\"\")+'</div><span class=\"layui-layer-setwin\">'+function(){var e=c?'<a class=\"layui-layer-min\" href=\"javascript:;\"><cite></cite></a><a class=\"layui-layer-ico layui-layer-max\" href=\"javascript:;\"></a>':\"\";return r.closeBtn&&(e+='<a class=\"layui-layer-ico '+s[7]+\" \"+s[7]+(r.title?r.closeBtn:4==r.type?\"1\":\"2\")+'\" href=\"javascript:;\"></a>'),e}()+\"</span>\"+(r.btn?function(){var e=\"\";\"string\"==typeof r.btn&&(r.btn=[r.btn]);for(var t=0,i=r.btn.length;t<i;t++)e+='<a class=\"'+s[6]+t+'\">'+r.btn[t]+\"</a>\";return'<div class=\"'+s[6]+\" layui-layer-btn-\"+(r.btnAlign||\"\")+'\">'+e+\"</div>\"}():\"\")+(r.resize?'<span class=\"layui-layer-resize\"></span>':\"\")+\"</div>\"],d,i('<div class=\"layui-layer-move\"></div>')),n},l.pt.creat=function(){var e=this,t=e.config,a=e.index,l=t.content,f=\"object\"==typeof l,c=i(\"body\");if(!i(\"#\"+t.id)[0]){switch(\"string\"==typeof t.area&&(t.area=\"auto\"===t.area?[\"\",\"\"]:[t.area,\"\"]),t.shift&&(t.anim=t.shift),6==r.ie&&(t.fixed=!1),t.type){case 0:t.btn=\"btn\"in t?t.btn:o.btn[0],r.closeAll(\"dialog\");break;case 2:var l=t.content=f?t.content:[t.content||\"http://layer.layui.com\",\"auto\"];t.content='<iframe scrolling=\"'+(t.content[1]||\"auto\")+'\" allowtransparency=\"true\" id=\"'+s[4]+a+'\" name=\"'+s[4]+a+'\" onload=\"this.className=\\'\\';\" class=\"layui-layer-load\" frameborder=\"0\" src=\"'+t.content[0]+'\"></iframe>';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll(\"loading\");break;case 4:f||(t.content=[t.content,\"body\"]),t.follow=t.content[1],t.content=t.content[0]+'<i class=\"layui-layer-TipsG\"></i>',delete t.title,t.tips=\"object\"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll(\"tips\")}e.vessel(f,function(n,r,d){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i(\"body\").append(n[1])}():function(){l.parents(\".\"+s[0])[0]||(l.data(\"display\",l.css(\"display\")).show().addClass(\"layui-layer-wrap\").wrap(n[1]),i(\"#\"+s[0]+a).find(\".\"+s[5]).before(r))}()}():c.append(n[1]),i(\".layui-layer-move\")[0]||c.append(o.moveElem=d),e.layero=i(\"#\"+s[0]+a),t.scrollbar||s.html.css(\"overflow\",\"hidden\").attr(\"layer-full\",a)}).auto(a),2==t.type&&6==r.ie&&e.layero.find(\"iframe\").attr(\"src\",l[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on(\"resize\",function(){e.offset(),(/^\\d+%$/.test(t.area[0])||/^\\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),s.anim[t.anim]&&e.layero.addClass(s.anim[t.anim]).data(\"anim\",!0)}},l.pt.auto=function(e){function t(e){e=l.find(e),e.height(f[1]-c-d-2*(0|parseFloat(e.css(\"padding\"))))}var a=this,o=a.config,l=i(\"#\"+s[0]+e);\"\"===o.area[0]&&o.maxWidth>0&&(r.ie&&r.ie<8&&o.btn&&l.width(l.innerWidth()),l.outerWidth()>o.maxWidth&&l.width(o.maxWidth));var f=[l.innerWidth(),l.innerHeight()],c=l.find(s[1]).outerHeight()||0,d=l.find(\".\"+s[6]).outerHeight()||0;switch(o.type){case 2:t(\"iframe\");break;default:\"\"===o.area[1]?o.fixed&&f[1]>=n.height()&&(f[1]=n.height(),t(\".\"+s[5])):t(\".\"+s[5])}return a},l.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o=\"object\"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):\"auto\"!==t.offset&&(\"t\"===t.offset?e.offsetTop=0:\"r\"===t.offset?e.offsetLeft=n.width()-a[0]:\"b\"===t.offset?e.offsetTop=n.height()-a[1]:\"l\"===t.offset?e.offsetLeft=0:\"lt\"===t.offset?(e.offsetTop=0,e.offsetLeft=0):\"lb\"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):\"rt\"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):\"rb\"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr(\"minLeft\")&&(e.offsetTop=n.height()-(i.find(s[1]).outerHeight()||0),e.offsetLeft=i.css(\"left\")),i.css({top:e.offsetTop,left:e.offsetLeft})},l.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i(\"body\"));var l={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(\".layui-layer-TipsG\"),c=t.tips[0];t.tips[1]||f.remove(),l.autoLeft=function(){l.left+o[0]-n.width()>0?(l.tipLeft=l.left+l.width-o[0],f.css({right:12,left:\"auto\"})):l.tipLeft=l.left},l.where=[function(){l.autoLeft(),l.tipTop=l.top-o[1]-10,f.removeClass(\"layui-layer-TipsB\").addClass(\"layui-layer-TipsT\").css(\"border-right-color\",t.tips[1])},function(){l.tipLeft=l.left+l.width+10,l.tipTop=l.top,f.removeClass(\"layui-layer-TipsL\").addClass(\"layui-layer-TipsR\").css(\"border-bottom-color\",t.tips[1])},function(){l.autoLeft(),l.tipTop=l.top+l.height+10,f.removeClass(\"layui-layer-TipsT\").addClass(\"layui-layer-TipsB\").css(\"border-right-color\",t.tips[1])},function(){l.tipLeft=l.left-o[0]-10,l.tipTop=l.top,f.removeClass(\"layui-layer-TipsR\").addClass(\"layui-layer-TipsL\").css(\"border-bottom-color\",t.tips[1])}],l.where[c-1](),1===c?l.top-(n.scrollTop()+o[1]+16)<0&&l.where[2]():2===c?n.width()-(l.left+l.width+o[0]+16)>0||l.where[3]():3===c?l.top-n.scrollTop()+l.height+o[1]+16-n.height()>0&&l.where[0]():4===c&&o[0]+16-l.left>0&&l.where[1](),a.find(\".\"+s[5]).css({\"background-color\":t.tips[1],\"padding-right\":t.closeBtn?\"30px\":\"\"}),a.css({left:l.tipLeft-(t.fixed?n.scrollLeft():0),top:l.tipTop-(t.fixed?n.scrollTop():0)})},l.pt.move=function(){var e=this,t=e.config,a=i(document),l=e.layero,s=l.find(t.move),f=l.find(\".layui-layer-resize\"),c={};return t.move&&s.css(\"cursor\",\"move\"),s.on(\"mousedown\",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(l.css(\"left\")),e.clientY-parseFloat(l.css(\"top\"))],o.moveElem.css(\"cursor\",\"move\").show())}),f.on(\"mousedown\",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[l.outerWidth(),l.outerHeight()],o.moveElem.css(\"cursor\",\"se-resize\").show()}),a.on(\"mousemove\",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],s=\"fixed\"===l.css(\"position\");if(i.preventDefault(),c.stX=s?0:n.scrollLeft(),c.stY=s?0:n.scrollTop(),!t.moveOut){var f=n.width()-l.outerWidth()+c.stX,d=n.height()-l.outerHeight()+c.stY;a<c.stX&&(a=c.stX),a>f&&(a=f),o<c.stY&&(o=c.stY),o>d&&(o=d)}l.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0}}).on(\"mouseup\",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd()),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},l.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find(\"iframe\").on(\"load\",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find(\".\"+s[6]).children(\"a\").on(\"click\",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a[\"btn\"+(e+1)]&&a[\"btn\"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find(\".\"+s[7]).on(\"click\",e),a.shadeClose&&i(\"#layui-layer-shade\"+t.index).on(\"click\",function(){r.close(t.index)}),n.find(\".layui-layer-min\").on(\"click\",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(\".layui-layer-max\").on(\"click\",function(){i(this).hasClass(\"layui-layer-maxmin\")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i(\"select\"),function(e,t){var n=i(this);n.parents(\".\"+s[0])[0]||1==n.attr(\"layer\")&&i(\".\"+s[0]).length<1&&n.removeAttr(\"layer\").show(),n=null})},l.pt.IE6=function(e){i(\"select\").each(function(e,t){var n=i(this);n.parents(\".\"+s[0])[0]||\"none\"===n.css(\"display\")||n.attr({layer:\"1\"}).hide(),n=null})},l.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css(\"z-index\",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on(\"mousedown\",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css(\"margin-left\"))];e.find(\".layui-layer-max\").addClass(\"layui-layer-maxmin\"),e.attr({area:t})},o.rescollbar=function(e){s.html.attr(\"layer-full\")==e&&(s.html[0].style.removeProperty?s.html[0].style.removeProperty(\"overflow\"):s.html[0].style.removeAttribute(\"overflow\"),s.html.removeAttr(\"layer-full\"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i(\".\"+s[4]).attr(\"times\"),i(\"#\"+s[0]+t).find(\"iframe\").contents().find(e)},r.getFrameIndex=function(e){return i(\"#\"+e).parents(\".\"+s[4]).attr(\"times\")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame(\"html\",e).outerHeight(),n=i(\"#\"+s[0]+e),a=n.find(s[1]).outerHeight()||0,o=n.find(\".\"+s[6]).outerHeight()||0;n.css({height:t+a+o}),n.find(\"iframe\").css({height:t})}},r.iframeSrc=function(e,t){i(\"#\"+s[0]+e).find(\"iframe\").attr(\"src\",t)},r.style=function(e,t,n){var a=i(\"#\"+s[0]+e),r=a.find(\".layui-layer-content\"),l=a.attr(\"type\"),f=a.find(s[1]).outerHeight()||0,c=a.find(\".\"+s[6]).outerHeight()||0;a.attr(\"minLeft\");l!==o.type[3]&&l!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find(\".\"+s[6]).outerHeight(),l===o.type[2]?a.find(\"iframe\").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css(\"padding-top\"))-parseFloat(r.css(\"padding-bottom\"))}))},r.min=function(e,t){var a=i(\"#\"+s[0]+e),l=a.find(s[1]).outerHeight()||0,f=a.attr(\"minLeft\")||181*o.minIndex+\"px\",c=a.css(\"position\");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr(\"position\",c),r.style(e,{width:180,height:l,left:f,top:n.height()-l,position:\"fixed\",overflow:\"hidden\"},!0),a.find(\".layui-layer-min\").hide(),\"page\"===a.attr(\"type\")&&a.find(s[4]).hide(),o.rescollbar(e),a.attr(\"minLeft\")||o.minIndex++,a.attr(\"minLeft\",f)},r.restore=function(e){var t=i(\"#\"+s[0]+e),n=t.attr(\"area\").split(\",\");t.attr(\"type\");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr(\"position\"),overflow:\"visible\"},!0),t.find(\".layui-layer-max\").removeClass(\"layui-layer-maxmin\"),t.find(\".layui-layer-min\").show(),\"page\"===t.attr(\"type\")&&t.find(s[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i(\"#\"+s[0]+e);o.record(a),s.html.attr(\"layer-full\")||s.html.css(\"overflow\",\"hidden\").attr(\"layer-full\",e),clearTimeout(t),t=setTimeout(function(){var t=\"fixed\"===a.css(\"position\");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(\".layui-layer-min\").hide()},100)},r.title=function(e,t){var n=i(\"#\"+s[0]+(t||r.index)).find(s[1]);n.html(e)},r.close=function(e){var t=i(\"#\"+s[0]+e),n=t.attr(\"type\"),a=\"layer-anim-close\";if(t[0]){var l=\"layui-layer-wrap\",f=function(){if(n===o.type[1]&&\"object\"===t.attr(\"conType\")){t.children(\":not(.\"+s[5]+\")\").remove();for(var a=t.find(\".\"+l),r=0;r<2;r++)a.unwrap();a.css(\"display\",a.data(\"display\")).removeClass(l)}else{if(n===o.type[2])try{var f=i(\"#\"+s[4]+e)[0];f.contentWindow.document.write(\"\"),f.contentWindow.close(),t.find(\".\"+s[5])[0].removeChild(f)}catch(c){}t[0].innerHTML=\"\",t.remove()}\"function\"==typeof o.end[e]&&o.end[e](),delete o.end[e]};t.data(\"anim\")&&t.addClass(a),i(\"#layui-layer-moves, #layui-layer-shade\"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),t.attr(\"minLeft\")&&(o.minIndex--,o.minLeft.push(t.attr(\"minLeft\"))),setTimeout(function(){f()},r.ie&&r.ie<10||!t.data(\"anim\")?0:200)}},r.closeAll=function(e){i.each(i(\".\"+s[0]),function(){var t=i(this),n=e?t.attr(\"type\")===e:1;n&&r.close(t.attr(\"times\")),n=null})};var f=r.cache||{},c=function(e){return f.skin?\" \"+f.skin+\" \"+f.skin+\"-\"+e:\"\"};r.prompt=function(e,t){var a=\"\";if(e=e||{},\"function\"==typeof e&&(t=e),e.area){var o=e.area;a='style=\"width: '+o[0]+\"; height: \"+o[1]+';\"',delete e.area}var l,s=2==e.formType?'<textarea class=\"layui-layer-input\"'+a+\">\"+(e.value||\"\")+\"</textarea>\":function(){return'<input type=\"'+(1==e.formType?\"password\":\"text\")+'\" class=\"layui-layer-input\" value=\"'+(e.value||\"\")+'\">'}();return r.open(i.extend({type:1,btn:[\"&#x786E;&#x5B9A;\",\"&#x53D6;&#x6D88;\"],content:s,skin:\"layui-layer-prompt\"+c(\"prompt\"),maxWidth:n.width(),success:function(e){l=e.find(\".layui-layer-input\"),l.focus()},resize:!1,yes:function(i){var n=l.val();\"\"===n?l.focus():n.length>(e.maxlength||500)?r.tips(\"&#x6700;&#x591A;&#x8F93;&#x5165;\"+(e.maxlength||500)+\"&#x4E2A;&#x5B57;&#x6570;\",l,{tips:1}):t&&t(n,i,l)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{};return r.open(i.extend({type:1,skin:\"layui-layer-tab\"+c(\"tab\"),resize:!1,title:function(){var e=t.length,i=1,n=\"\";if(e>0)for(n='<span class=\"layui-layer-tabnow\">'+t[0].title+\"</span>\";i<e;i++)n+=\"<span>\"+t[i].title+\"</span>\";return n}(),content:'<ul class=\"layui-layer-tabmain\">'+function(){var e=t.length,i=1,n=\"\";if(e>0)for(n='<li class=\"layui-layer-tabli xubox_tab_layer\">'+(t[0].content||\"no content\")+\"</li>\";i<e;i++)n+='<li class=\"layui-layer-tabli\">'+(t[i].content||\"no  content\")+\"</li>\";return n}()+\"</ul>\",success:function(t){var n=t.find(\".layui-layer-title\").children(),a=t.find(\".layui-layer-tabmain\").children();n.on(\"mousedown\",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var n=i(this),o=n.index();n.addClass(\"layui-layer-tabnow\").siblings().removeClass(\"layui-layer-tabnow\"),a.eq(o).show().siblings().hide(),\"function\"==typeof e.change&&e.change(o)})}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var l={};if(t=t||{},t.photos){var s=t.photos.constructor===Object,f=s?t.photos:{},d=f.data||[],u=f.start||0;if(l.imgIndex=(0|u)+1,t.img=t.img||\"img\",s){if(0===d.length)return r.msg(\"&#x6CA1;&#x6709;&#x56FE;&#x7247;\")}else{var y=i(t.photos),p=function(){d=[],y.find(t.img).each(function(e){var t=i(this);t.attr(\"layer-index\",e),d.push({alt:t.attr(\"alt\"),pid:t.attr(\"layer-pid\"),src:t.attr(\"layer-src\")||t.attr(\"src\"),thumb:t.attr(\"src\")})})};if(p(),0===d.length)return;if(n||y.on(\"click\",t.img,function(){var e=i(this),n=e.attr(\"layer-index\");r.photos(i.extend(t,{photos:{start:n,data:d,tab:t.tab},full:t.full}),!0),p()}),!n)return}l.imgprev=function(e){l.imgIndex--,l.imgIndex<1&&(l.imgIndex=d.length),l.tabimg(e)},l.imgnext=function(e,t){l.imgIndex++,l.imgIndex>d.length&&(l.imgIndex=1,t)||l.tabimg(e)},l.keyup=function(e){if(!l.end){var t=e.keyCode;e.preventDefault(),37===t?l.imgprev(!0):39===t?l.imgnext(!0):27===t&&r.close(l.index)}},l.tabimg=function(e){d.length<=1||(f.start=l.imgIndex-1,r.close(l.index),r.photos(t,!0,e))},l.event=function(){l.bigimg.hover(function(){l.imgsee.show()},function(){l.imgsee.hide()}),l.bigimg.find(\".layui-layer-imgprev\").on(\"click\",function(e){e.preventDefault(),l.imgprev()}),l.bigimg.find(\".layui-layer-imgnext\").on(\"click\",function(e){e.preventDefault(),l.imgnext()}),i(document).on(\"keyup\",l.keyup)},l.loadi=r.load(1,{shade:!(\"shade\"in t)&&.9,scrollbar:!1}),o(d[u].src,function(n){r.close(l.loadi),l.index=r.open(i.extend({type:1,area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]<r[1]&&(a[0]=a[0]/r[1],a[1]=a[1]/r[1])}return[a[0]+\"px\",a[1]+\"px\"]}(),title:!1,shade:.9,shadeClose:!0,closeBtn:!1,move:\".layui-layer-phimg img\",moveType:1,scrollbar:!1,moveOut:!0,anim:5*Math.random()|0,skin:\"layui-layer-photos\"+c(\"photos\"),content:'<div class=\"layui-layer-phimg\"><img src=\"'+d[u].src+'\" alt=\"'+(d[u].alt||\"\")+'\" layer-pid=\"'+d[u].pid+'\"><div class=\"layui-layer-imgsee\">'+(d.length>1?'<span class=\"layui-layer-imguide\"><a href=\"javascript:;\" class=\"layui-layer-iconext layui-layer-imgprev\"></a><a href=\"javascript:;\" class=\"layui-layer-iconext layui-layer-imgnext\"></a></span>':\"\")+'<div class=\"layui-layer-imgbar\" style=\"display:'+(a?\"block\":\"\")+'\"><span class=\"layui-layer-imgtit\"><a href=\"javascript:;\">'+(d[u].alt||\"\")+\"</a><em>\"+l.imgIndex+\"/\"+d.length+\"</em></span></div></div></div>\",success:function(e,i){l.bigimg=e.find(\".layui-layer-phimg\"),l.imgsee=e.find(\".layui-layer-imguide,.layui-layer-imgbar\"),l.event(e),t.tab&&t.tab(d[u],e)},end:function(){l.end=!0,i(document).off(\"keyup\",l.keyup)}},t))},function(){r.close(l.loadi),r.msg(\"&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;<br>&#x662F;&#x5426;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4E0B;&#x4E00;&#x5F20;&#xFF1F;\",{time:3e4,btn:[\"&#x4E0B;&#x4E00;&#x5F20;\",\"&#x4E0D;&#x770B;&#x4E86;\"],yes:function(){d.length>1&&l.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),s.html=i(\"html\"),r.open=function(e){var t=new l(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define(\"jquery\",function(t){r.path=layui.cache.dir,o.run(layui.jquery),e.layer=r,t(\"layer\",r)})):\"function\"==typeof define?define([\"jquery\"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window);layui.define(\"jquery\",function(i){\"use strict\";var t=layui.jquery,a=(layui.hint(),layui.device()),e=\"element\",l=\"layui-this\",n=\"layui-show\",s=function(){this.config={}};s.prototype.set=function(i){var a=this;return t.extend(!0,a.config,i),a},s.prototype.on=function(i,t){return layui.onevent(e,i,t)},s.prototype.tabAdd=function(i,a){var e=t(\".layui-tab[lay-filter=\"+i+\"]\"),l=e.children(\".layui-tab-title\"),n=e.children(\".layui-tab-content\");return l.append(\"<li>\"+(a.title||\"unnaming\")+\"</li>\"),n.append('<div class=\"layui-tab-item\">'+(a.content||\"\")+\"</div>\"),y.tabAuto(),this},s.prototype.tabDelete=function(i,a){var e=t(\".layui-tab[lay-filter=\"+i+\"]\"),l=e.children(\".layui-tab-title\").find(\">li\").eq(a);return y.tabDelete(null,l),this},s.prototype.tabChange=function(i,a){var e=t(\".layui-tab[lay-filter=\"+i+\"]\"),l=e.children(\".layui-tab-title\").find(\">li\").eq(a);return y.tabClick(null,a,l),this};var o=\".layui-nav\",c=\"layui-nav-item\",r=\"layui-nav-bar\",u=\"layui-nav-tree\",d=\"layui-nav-child\",h=\"layui-nav-more\",f=\"layui-anim layui-anim-upbit\",y={tabClick:function(i,a,s){var o=s||t(this),a=a||o.index(),c=o.parents(\".layui-tab\"),r=c.children(\".layui-tab-content\").children(\".layui-tab-item\"),u=c.attr(\"lay-filter\");o.addClass(l).siblings().removeClass(l),r.eq(a).addClass(n).siblings().removeClass(n),layui.event.call(this,e,\"tab(\"+u+\")\",{elem:c,index:a})},tabDelete:function(i,a){var e=a||t(this).parent(),n=e.index(),s=e.parents(\".layui-tab\"),o=s.children(\".layui-tab-content\").children(\".layui-tab-item\");e.hasClass(l)&&(e.next()[0]?y.tabClick.call(e.next()[0],null,n+1):e.prev()[0]&&y.tabClick.call(e.prev()[0],null,n-1)),e.remove(),o.eq(n).remove()},tabAuto:function(){var i=\"layui-tab-more\",e=\"layui-tab-bar\",l=\"layui-tab-close\",n=this;t(\".layui-tab\").each(function(){var s=t(this),o=s.children(\".layui-tab-title\"),c=(s.children(\".layui-tab-content\").children(\".layui-tab-item\"),'lay-stope=\"tabmore\"'),r=t('<span class=\"layui-unselect layui-tab-bar\" '+c+\"><i \"+c+' class=\"layui-icon\">&#xe61a;</i></span>');if(n===window&&8!=a.ie&&y.hideTabMore(!0),s.attr(\"lay-allowClose\")&&o.find(\"li\").each(function(){var i=t(this);if(!i.find(\".\"+l)[0]){var a=t('<i class=\"layui-icon layui-unselect '+l+'\">&#x1006;</i>');a.on(\"click\",y.tabDelete),i.append(a)}}),o.prop(\"scrollWidth\")>o.outerWidth()+1){if(o.find(\".\"+e)[0])return;o.append(r),r.on(\"click\",function(t){o[this.title?\"removeClass\":\"addClass\"](i),this.title=this.title?\"\":\"收缩\"})}else o.find(\".\"+e).remove()})},hideTabMore:function(i){var a=t(\".layui-tab-title\");i!==!0&&\"tabmore\"===t(i.target).attr(\"lay-stope\")||(a.removeClass(\"layui-tab-more\"),a.find(\".layui-tab-bar\").attr(\"title\",\"\"))},clickThis:function(){var i=t(this),a=i.parents(o),n=a.attr(\"lay-filter\");i.find(\".\"+d)[0]||(a.find(\".\"+l).removeClass(l),i.addClass(l),layui.event.call(this,e,\"nav(\"+n+\")\",i))},clickChild:function(){var i=t(this),a=i.parents(o),n=a.attr(\"lay-filter\");a.find(\".\"+l).removeClass(l),i.addClass(l),layui.event.call(this,e,\"nav(\"+n+\")\",i)},showChild:function(){var i=t(this),a=i.parents(o),e=i.parent(),l=i.siblings(\".\"+d);a.hasClass(u)&&(l.removeClass(f),e[\"none\"===l.css(\"display\")?\"addClass\":\"removeClass\"](c+\"ed\"))}};s.prototype.init=function(i){var e={tab:function(){y.tabAuto.call({})},nav:function(){var i,e,l,s=200,p=function(o,c){var r=t(this),y=r.find(\".\"+d);c.hasClass(u)?o.css({top:r.position().top,height:r.children(\"a\").height(),opacity:1}):(y.addClass(f),o.css({left:r.position().left+parseFloat(r.css(\"marginLeft\")),top:r.position().top+r.height()-5}),i=setTimeout(function(){o.css({width:r.width(),opacity:1})},a.ie&&a.ie<10?0:s),clearTimeout(l),\"block\"===y.css(\"display\")&&clearTimeout(e),e=setTimeout(function(){y.addClass(n),r.find(\".\"+h).addClass(h+\"d\")},300))};t(o).each(function(){var a=t(this),o=t('<span class=\"'+r+'\"></span>'),f=a.find(\".\"+c);a.find(\".\"+r)[0]||(a.append(o),f.on(\"mouseenter\",function(){p.call(this,o,a)}).on(\"mouseleave\",function(){a.hasClass(u)||(clearTimeout(e),e=setTimeout(function(){a.find(\".\"+d).removeClass(n),a.find(\".\"+h).removeClass(h+\"d\")},300))}),a.on(\"mouseleave\",function(){clearTimeout(i),l=setTimeout(function(){a.hasClass(u)?o.css({height:0,top:o.position().top+o.height()/2,opacity:0}):o.css({width:0,left:o.position().left+o.width()/2,opacity:0})},s)})),f.each(function(){var i=t(this),a=i.find(\".\"+d);if(a[0]&&!i.find(\".\"+h)[0]){var e=i.children(\"a\");e.append('<span class=\"'+h+'\"></span>')}i.off(\"click\",y.clickThis).on(\"click\",y.clickThis),i.children(\"a\").off(\"click\",y.showChild).on(\"click\",y.showChild),a.children(\"dd\").off(\"click\",y.clickChild).on(\"click\",y.clickChild)})})},breadcrumb:function(){var i=\".layui-breadcrumb\";t(i).each(function(){var i=t(this),a=i.attr(\"lay-separator\")||\">\",e=i.find(\"a\");e.find(\".layui-box\")[0]||(e.each(function(i){i!==e.length-1&&t(this).append('<span class=\"layui-box\">'+a+\"</span>\")}),i.css(\"visibility\",\"visible\"))})}};return layui.each(e,function(i,t){t()})};var p=new s,b=t(document);p.init();var v=\".layui-tab-title li\";b.on(\"click\",v,y.tabClick),b.on(\"click\",y.hideTabMore),t(window).on(\"resize\",y.tabAuto),i(e,function(i){return p.set(i)})});layui.define(\"layer\",function(e){\"use strict\";var a=layui.jquery,t=layui.layer,i=(layui.device(),\"layui-upload-enter\"),n=\"layui-upload-iframe\",r={icon:2,shift:6},o={file:\"文件\",video:\"视频\",audio:\"音频\"},s=function(e){this.options=e};s.prototype.init=function(){var e=this,t=e.options,r=a(\"body\"),s=a(t.elem||\".layui-upload-file\"),u=a('<iframe id=\"'+n+'\" class=\"'+n+'\" name=\"'+n+'\"></iframe>');return a(\"#\"+n)[0]||r.append(u),s.each(function(r,s){s=a(s);var u='<form target=\"'+n+'\" method=\"'+(t.method||\"post\")+'\" key=\"set-mine\" enctype=\"multipart/form-data\" action=\"'+(t.url||\"\")+'\"></form>',l=s.attr(\"lay-type\")||t.type;t.unwrap||(u='<div class=\"layui-box layui-upload-button\">'+u+'<span class=\"layui-upload-icon\"><i class=\"layui-icon\">&#xe608;</i>'+(s.attr(\"lay-title\")||t.title||\"上传\"+(o[l]||\"图片\"))+\"</span></div>\"),u=a(u),t.unwrap||u.on(\"dragover\",function(e){e.preventDefault(),a(this).addClass(i)}).on(\"dragleave\",function(){a(this).removeClass(i)}).on(\"drop\",function(){a(this).removeClass(i)}),s.parent(\"form\").attr(\"target\")===n&&(t.unwrap?s.unwrap():(s.parent().next().remove(),s.unwrap().unwrap())),s.wrap(u),s.off(\"change\").on(\"change\",function(){e.action(this,l)})})},s.prototype.action=function(e,i){var o=this,s=o.options,u=e.value,l=a(e),p=l.attr(\"lay-ext\")||s.ext||\"\";if(u){switch(i){case\"file\":if(p&&!RegExp(\"\\\\w\\\\.(\"+p+\")$\",\"i\").test(escape(u)))return t.msg(\"不支持该文件格式\",r),e.value=\"\";break;case\"video\":if(!RegExp(\"\\\\w\\\\.(\"+(p||\"avi|mp4|wma|rmvb|rm|flash|3gp|flv\")+\")$\",\"i\").test(escape(u)))return t.msg(\"不支持该视频格式\",r),e.value=\"\";break;case\"audio\":if(!RegExp(\"\\\\w\\\\.(\"+(p||\"mp3|wav|mid\")+\")$\",\"i\").test(escape(u)))return t.msg(\"不支持该音频格式\",r),e.value=\"\";break;default:if(!RegExp(\"\\\\w\\\\.(\"+(p||\"jpg|png|gif|bmp|jpeg\")+\")$\",\"i\").test(escape(u)))return t.msg(\"不支持该图片格式\",r),e.value=\"\"}s.before&&s.before(e),l.parent().submit();var c=a(\"#\"+n),f=setInterval(function(){var a;try{a=c.contents().find(\"body\").text()}catch(i){t.msg(\"上传接口存在跨域\",r),clearInterval(f)}if(a){clearInterval(f),c.contents().find(\"body\").html(\"\");try{a=JSON.parse(a)}catch(i){return a={},t.msg(\"请对上传接口返回JSON字符\",r)}\"function\"==typeof s.success&&s.success(a,e)}},30);e.value=\"\"}},e(\"upload\",function(e){var a=new s(e=e||{});a.init()})});layui.define(\"layer\",function(e){\"use strict\";var i=layui.jquery,a=layui.layer,t=layui.hint(),n=layui.device(),l=\"form\",s=\".layui-form\",c=\"layui-this\",r=\"layui-disabled\",u=function(){this.config={verify:{required:[/[\\S]+/,\"必填项不能为空\"],phone:[/^1\\d{10}$/,\"请输入正确的手机号\"],email:[/^([a-zA-Z0-9_\\.\\-])+\\@(([a-zA-Z0-9\\-])+\\.)+([a-zA-Z0-9]{2,4})+$/,\"邮箱格式不正确\"],url:[/(^#)|(^http(s*):\\/\\/[^\\s]+\\.[^\\s]+)/,\"链接格式不正确\"],number:[/^\\d+$/,\"只能填写数字\"],date:[/^(\\d{4})[-\\/](\\d{1}|0\\d{1}|1[0-2])([-\\/](\\d{1}|0\\d{1}|[1-2][0-9]|3[0-1]))*$/,\"日期格式不正确\"],identity:[/(^\\d{15}$)|(^\\d{17}(x|X|\\d)$)/,\"请输入正确的身份证号\"]}}};u.prototype.set=function(e){var a=this;return i.extend(!0,a.config,e),a},u.prototype.verify=function(e){var a=this;return i.extend(!0,a.config.verify,e),a},u.prototype.on=function(e,i){return layui.onevent(l,e,i)},u.prototype.render=function(e){var a=this,n={select:function(){var e=\"请选择\",a=\"layui-form-select\",t=\"layui-select-title\",n=i(s).find(\"select\"),u=function(e,n){i(e.target).parent().hasClass(t)&&!n||i(\".\"+a).removeClass(a+\"ed\")},o=function(e,n){var s=i(this),o=e.find(\".\"+t);n||(o.on(\"click\",function(i){e.hasClass(a+\"ed\")?e.removeClass(a+\"ed\"):(u(i,!0),e.addClass(a+\"ed\"))}),e.find(\"dl>dd\").on(\"click\",function(){var e=i(this),a=e.attr(\"lay-value\"),t=s.attr(\"lay-filter\");return!e.hasClass(r)&&(s.val(a).removeClass(\"layui-form-danger\"),o.find(\"input\").val(e.text()),e.addClass(c).siblings().removeClass(c),void layui.event(l,\"select(\"+t+\")\",{elem:s[0],value:a}))}),e.find(\"dl>dt\").on(\"click\",function(e){return!1}),i(document).off(\"click\",u).on(\"click\",u))};n.each(function(n,l){var s=i(this),u=s.next(\".\"+a),d=this.disabled,f=l.value,y=i(l.options[l.selectedIndex]),v=i(['<div class=\"layui-unselect '+a+(d?\" layui-select-disabled\":\"\")+'\">','<div class=\"'+t+'\"><input type=\"text\" placeholder=\"'+(l.options[0].innerHTML?l.options[0].innerHTML:e)+'\" value=\"'+(f?y.html():\"\")+'\" readonly class=\"layui-input layui-unselect'+(d?\" \"+r:\"\")+'\">','<i class=\"layui-edge\"></i></div>','<dl class=\"layui-anim layui-anim-upbit'+(s.find(\"optgroup\")[0]?\" layui-select-group\":\"\")+'\">'+function(e){var i=[];return layui.each(e,function(e,a){(0!==e||a.value)&&(\"optgroup\"===a.tagName.toLowerCase()?i.push(\"<dt>\"+a.label+\"</dt>\"):i.push('<dd lay-value=\"'+a.value+'\" class=\"'+(f===a.value?c:\"\")+(a.disabled?\" \"+r:\"\")+'\">'+a.innerHTML+\"</dd>\"))}),i.join(\"\")}(s.find(\"*\"))+\"</dl>\",\"</div>\"].join(\"\"));u[0]&&u.remove(),s.after(v),o.call(this,v,d)})},checkbox:function(){var e={checkbox:[\"layui-form-checkbox\",\"layui-form-checked\",\"checkbox\"],_switch:[\"layui-form-switch\",\"layui-form-onswitch\",\"switch\"]},a=i(s).find(\"input[type=checkbox]\"),t=function(e,a){var t=i(this);e.on(\"click\",function(){var i=t.attr(\"lay-filter\");t[0].disabled||(t[0].checked?(t[0].checked=!1,e.removeClass(a[1])):(t[0].checked=!0,e.addClass(a[1])),layui.event(l,a[2]+\"(\"+i+\")\",{elem:t[0],value:t[0].value}))})};a.each(function(a,n){var l=i(this),s=l.attr(\"lay-skin\"),c=this.disabled;\"switch\"===s&&(s=\"_\"+s);var u=e[s]||e.checkbox,o=l.next(\".\"+u[0]),d=i(['<div class=\"layui-unselect '+u[0]+(n.checked?\" \"+u[1]:\"\")+(c?\" layui-checkbox-disbaled \"+r:\"\")+'\">',{_switch:\"<i></i>\"}[s]||\"<span>\"+(n.title||\"勾选\")+'</span><i class=\"layui-icon\">&#xe618;</i>',\"</div>\"].join(\"\"));o[0]&&o.remove(),l.after(d),t.call(this,d,u)})},radio:function(){var e=\"layui-form-radio\",a=[\"&#xe643;\",\"&#xe63f;\"],t=i(s).find(\"input[type=radio]\"),n=function(t){var n=i(this),c=\"layui-anim-scaleSpring\";t.on(\"click\",function(){var r=n[0].name,u=n.parents(s),o=n.attr(\"lay-filter\"),d=u.find(\"input[name=\"+r.replace(/(\\.|#|\\[|\\])/g,\"\\\\$1\")+\"]\");n[0].disabled||(layui.each(d,function(){var t=i(this).next(\".\"+e);this.checked=!1,t.removeClass(e+\"ed\"),t.find(\".layui-icon\").removeClass(c).html(a[1])}),n[0].checked=!0,t.addClass(e+\"ed\"),t.find(\".layui-icon\").addClass(c).html(a[0]),layui.event(l,\"radio(\"+o+\")\",{elem:n[0],value:n[0].value}))})};t.each(function(t,l){var s=i(this),c=s.next(\".\"+e),u=this.disabled,o=i(['<div class=\"layui-unselect '+e+(l.checked?\" \"+e+\"ed\":\"\")+(u?\" layui-radio-disbaled \"+r:\"\")+'\">','<i class=\"layui-anim layui-icon\">'+a[l.checked?0:1]+\"</i>\",\"<span>\"+(l.title||\"未命名\")+\"</span>\",\"</div>\"].join(\"\"));c[0]&&c.remove(),s.after(o),n.call(this,o)})}};return e?n[e]?n[e]():t.error(\"不支持的\"+e+\"表单渲染\"):layui.each(n,function(e,i){i()}),a};var o=function(){var e=i(this),t=d.config.verify,c=null,r=\"layui-form-danger\",u={},o=e.parents(s),f=o.find(\"*[lay-verify]\"),y=e.parents(\"form\")[0],v=o.find(\"input,select,textarea\"),h=e.attr(\"lay-filter\");return layui.each(f,function(e,l){var s=i(this),u=s.attr(\"lay-verify\"),o=\"\",d=s.val(),f=\"function\"==typeof t[u];if(s.removeClass(r),t[u]&&(f?o=t[u](d,l):!t[u][0].test(d)))return a.msg(o||t[u][1],{icon:5,shift:6}),n.android||n.ios||l.focus(),s.addClass(r),c=!0}),!c&&(layui.each(v,function(e,i){i.name&&(/^checkbox|radio$/.test(i.type)&&!i.checked||(u[i.name]=i.value))}),layui.event.call(this,l,\"submit(\"+h+\")\",{elem:this,form:y,field:u}))},d=new u,f=i(document);d.render(),f.on(\"reset\",s,function(){setTimeout(function(){d.render()},50)}),f.on(\"submit\",s,o).on(\"click\",\"*[lay-submit]\",o),e(l,function(e){return d.set(e)})});layui.define(\"jquery\",function(e){\"use strict\";var o=layui.jquery,a=layui.hint(),r=\"layui-tree-enter\",i=function(e){this.options=e},t={arrow:[\"&#xe623;\",\"&#xe625;\"],checkbox:[\"&#xe626;\",\"&#xe627;\"],radio:[\"&#xe62b;\",\"&#xe62a;\"],branch:[\"&#xe622;\",\"&#xe624;\"],leaf:\"&#xe621;\"};i.prototype.init=function(e){var o=this;e.addClass(\"layui-box layui-tree\"),o.options.skin&&e.addClass(\"layui-tree-skin-\"+o.options.skin),o.tree(e),o.on(e)},i.prototype.tree=function(e,a){var r=this,i=r.options,n=a||i.nodes;layui.each(n,function(a,n){var l=n.children&&n.children.length>0,c=o('<ul class=\"'+(n.spread?\"layui-show\":\"\")+'\"></ul>'),s=o([\"<li \"+(n.spread?'data-spread=\"'+n.spread+'\"':\"\")+\">\",function(){return l?'<i class=\"layui-icon layui-tree-spread\">'+(n.spread?t.arrow[1]:t.arrow[0])+\"</i>\":\"\"}(),function(){return i.check?'<i class=\"layui-icon layui-tree-check\">'+(\"checkbox\"===i.check?t.checkbox[0]:\"radio\"===i.check?t.radio[0]:\"\")+\"</i>\":\"\"}(),function(){return'<a href=\"'+(n.href||\"javascript:;\")+'\" '+(i.target&&n.href?'target=\"'+i.target+'\"':\"\")+\">\"+('<i class=\"layui-icon layui-tree-'+(l?\"branch\":\"leaf\")+'\">'+(l?n.spread?t.branch[1]:t.branch[0]:t.leaf)+\"</i>\")+(\"<cite>\"+(n.name||\"未命名\")+\"</cite></a>\")}(),\"</li>\"].join(\"\"));l&&(s.append(c),r.tree(c,n.children)),e.append(s),\"function\"==typeof i.click&&r.click(s,n),r.spread(s,n),i.drag&&r.drag(s,n)})},i.prototype.click=function(e,o){var a=this,r=a.options;e.children(\"a\").on(\"click\",function(e){layui.stope(e),r.click(o)})},i.prototype.spread=function(e,o){var a=this,r=(a.options,e.children(\".layui-tree-spread\")),i=e.children(\"ul\"),n=e.children(\"a\"),l=function(){e.data(\"spread\")?(e.data(\"spread\",null),i.removeClass(\"layui-show\"),r.html(t.arrow[0]),n.find(\".layui-icon\").html(t.branch[0])):(e.data(\"spread\",!0),i.addClass(\"layui-show\"),r.html(t.arrow[1]),n.find(\".layui-icon\").html(t.branch[1]))};i[0]&&(r.on(\"click\",l),n.on(\"dblclick\",l))},i.prototype.on=function(e){var a=this,i=a.options,t=\"layui-tree-drag\";e.find(\"i\").on(\"selectstart\",function(e){return!1}),i.drag&&o(document).on(\"mousemove\",function(e){var r=a.move;if(r.from){var i=(r.to,o('<div class=\"layui-box '+t+'\"></div>'));e.preventDefault(),o(\".\"+t)[0]||o(\"body\").append(i);var n=o(\".\"+t)[0]?o(\".\"+t):i;n.addClass(\"layui-show\").html(r.from.elem.children(\"a\").html()),n.css({left:e.pageX+10,top:e.pageY+10})}}).on(\"mouseup\",function(){var e=a.move;e.from&&(e.from.elem.children(\"a\").removeClass(r),e.to&&e.to.elem.children(\"a\").removeClass(r),a.move={},o(\".\"+t).remove())})},i.prototype.move={},i.prototype.drag=function(e,a){var i=this,t=(i.options,e.children(\"a\")),n=function(){var t=o(this),n=i.move;n.from&&(n.to={item:a,elem:e},t.addClass(r))};t.on(\"mousedown\",function(){var o=i.move;o.from={item:a,elem:e}}),t.on(\"mouseenter\",n).on(\"mousemove\",n).on(\"mouseleave\",function(){var e=o(this),a=i.move;a.from&&(delete a.to,e.removeClass(r))})},e(\"tree\",function(e){var r=new i(e=e||{}),t=o(e.elem);return t[0]?void r.init(t):a.error(\"layui.tree 没有找到\"+e.elem+\"元素\")})});layui.define(\"jquery\",function(l){\"use strict\";var o=layui.jquery,i={fixbar:function(l){l=l||{},l.bgcolor=l.bgcolor?\"background-color:\"+l.bgcolor:\"\";var i,a,c=\"layui-fixbar-top\",t=[l.bar1===!0?\"&#xe606;\":l.bar1,l.bar2===!0?\"&#xe607;\":l.bar2,\"&#xe604;\"],r=o(['<ul class=\"layui-fixbar\">',l.bar1?'<li class=\"layui-icon\" lay-type=\"bar1\" style=\"'+l.bgcolor+'\">'+t[0]+\"</li>\":\"\",l.bar2?'<li class=\"layui-icon\" lay-type=\"bar2\" style=\"'+l.bgcolor+'\">'+t[1]+\"</li>\":\"\",'<li class=\"layui-icon '+c+'\" lay-type=\"top\" style=\"'+l.bgcolor+'\">'+t[2]+\"</li>\",\"</ul>\"].join(\"\")),e=r.find(\".\"+c),s=function(){var i=o(document).scrollTop();i>=(l.showHeight||200)?a||(e.show(),a=1):a&&(e.hide(),a=0)};o(\".layui-fixbar\")[0]||(\"object\"==typeof l.css&&r.css(l.css),o(\"body\").append(r),s(),r.find(\"li\").on(\"click\",function(){var i=o(this),a=i.attr(\"lay-type\");\"top\"===a&&o(\"html,body\").animate({scrollTop:0},200),l.click&&l.click.call(this,a)}),o(document).on(\"scroll\",function(){i&&clearTimeout(i),i=setTimeout(function(){s()},100)}))}};l(\"util\",i)});layui.define(\"jquery\",function(e){\"use strict\";var l=layui.jquery,o=function(e){},t='<i class=\"layui-anim layui-anim-rotate layui-anim-loop layui-icon \">&#xe63e;</i>';o.prototype.load=function(e){var o,i,n,r,a=this,c=0;e=e||{};var u=l(e.elem);if(u[0]){var f=l(e.scrollElem||document),m=e.mb||50,s=!(\"isAuto\"in e)||e.isAuto,y=e.end||\"没有更多了\",v=e.scrollElem&&e.scrollElem!==document,d=\"<cite>加载更多</cite>\",h=l('<div class=\"layui-flow-more\"><a href=\"javascript:;\">'+d+\"</a></div>\");u.find(\".layui-flow-more\")[0]||u.append(h);var p=function(e,t){e=l(e),h.before(e),t=0==t||null,t?h.html(y):h.find(\"a\").html(d),i=t,o=null,n&&n()},g=function(){o=!0,h.find(\"a\").html(t),\"function\"==typeof e.done&&e.done(++c,p)};if(g(),h.find(\"a\").on(\"click\",function(){l(this);i||o||g()}),e.isLazyimg)var n=a.lazyimg({elem:e.elem+\" img\",scrollElem:e.scrollElem});return s?(f.on(\"scroll\",function(){var e=l(this),t=e.scrollTop();r&&clearTimeout(r),i||(r=setTimeout(function(){var i=v?e.height():l(window).height(),n=v?e.prop(\"scrollHeight\"):document.documentElement.scrollHeight;n-t-i<=m&&(o||g())},100))}),a):a}},o.prototype.lazyimg=function(e){var o,t=this,i=0;e=e||{};var n=l(e.scrollElem||document),r=e.elem||\"img\",a=e.scrollElem&&e.scrollElem!==document,c=function(e,l){var o=n.scrollTop(),r=o+l,c=a?function(){return e.offset().top-n.offset().top+o}():e.offset().top;if(c>=o&&c<=r&&!e.attr(\"src\")){var f=e.attr(\"lay-src\");layui.img(f,function(){var l=t.lazyimg.elem.eq(i);e.attr(\"src\",f).removeAttr(\"lay-src\"),l[0]&&u(l),i++})}},u=function(e,o){var u=a?(o||n).height():l(window).height(),f=n.scrollTop(),m=f+u;if(t.lazyimg.elem=l(r),e)c(e,u);else for(var s=0;s<t.lazyimg.elem.length;s++){var y=t.lazyimg.elem.eq(s),v=a?function(){return y.offset().top-n.offset().top+f}():y.offset().top;if(c(y,u),i=s,v>m)break}};if(u(),!o){var f;n.on(\"scroll\",function(){var e=l(this);f&&clearTimeout(f),f=setTimeout(function(){u(null,e)},50)}),o=!0}return u},e(\"flow\",new o)});layui.define([\"layer\",\"form\"],function(t){\"use strict\";var e=layui.jquery,i=layui.layer,a=layui.form(),l=(layui.hint(),layui.device()),n=\"layedit\",o=\"layui-show\",r=\"layui-disabled\",s=function(){var t=this;t.index=0,t.config={tool:[\"strong\",\"italic\",\"underline\",\"del\",\"|\",\"left\",\"center\",\"right\",\"|\",\"link\",\"unlink\",\"face\",\"image\"],hideTool:[],height:280}};s.prototype.set=function(t){var i=this;return e.extend(!0,i.config,t),i},s.prototype.on=function(t,e){return layui.onevent(n,t,e)},s.prototype.build=function(t,i){i=i||{};var a=this,n=a.config,r=\"layui-layedit\",s=e(\"#\"+t),u=\"LAY_layedit_\"+ ++a.index,d=s.next(\".\"+r),y=e.extend({},n,i),f=function(){var t=[],e={};return layui.each(y.hideTool,function(t,i){e[i]=!0}),layui.each(y.tool,function(i,a){C[a]&&!e[a]&&t.push(C[a])}),t.join(\"\")}(),m=e(['<div class=\"'+r+'\">','<div class=\"layui-unselect layui-layedit-tool\">'+f+\"</div>\",'<div class=\"layui-layedit-iframe\">','<iframe id=\"'+u+'\" name=\"'+u+'\" textarea=\"'+t+'\" frameborder=\"0\"></iframe>',\"</div>\",\"</div>\"].join(\"\"));return l.ie&&l.ie<8?s.removeClass(\"layui-hide\").addClass(o):(d[0]&&d.remove(),c.call(a,m,s[0],y),s.addClass(\"layui-hide\").after(m),a.index)},s.prototype.getContent=function(t){var e=u(t);if(e[0])return d(e[0].document.body.innerHTML)},s.prototype.getText=function(t){var i=u(t);if(i[0])return e(i[0].document.body).text()},s.prototype.sync=function(t){var i=u(t);if(i[0]){var a=e(\"#\"+i[1].attr(\"textarea\"));a.val(d(i[0].document.body.innerHTML))}},s.prototype.getSelection=function(t){var e=u(t);if(e[0]){var i=m(e[0].document);return document.selection?i.text:i.toString()}};var c=function(t,i,a){var l=this,n=t.find(\"iframe\");n.css({height:a.height}).on(\"load\",function(){var o=n.contents(),r=n.prop(\"contentWindow\"),s=o.find(\"head\"),c=e([\"<style>\",\"*{margin: 0; padding: 0;}\",\"body{padding: 10px; line-height: 20px; overflow-x: hidden; word-wrap: break-word; font: 14px Helvetica Neue,Helvetica,PingFang SC,Microsoft YaHei,Tahoma,Arial,sans-serif; -webkit-box-sizing: border-box !important; -moz-box-sizing: border-box !important; box-sizing: border-box !important;}\",\"a{color:#01AAED; text-decoration:none;}a:hover{color:#c00}\",\"p{margin-bottom: 10px;}\",\"img{display: inline-block; border: none; vertical-align: middle;}\",\"pre{margin: 10px 0; padding: 10px; line-height: 20px; border: 1px solid #ddd; border-left-width: 6px; background-color: #F2F2F2; color: #333; font-family: Courier New; font-size: 12px;}\",\"</style>\"].join(\"\")),u=o.find(\"body\");s.append(c),u.attr(\"contenteditable\",\"true\").css({\"min-height\":a.height}).html(i.value||\"\"),y.apply(l,[r,n,i,a]),g.call(l,r,t,a)})},u=function(t){var i=e(\"#LAY_layedit_\"+t),a=i.prop(\"contentWindow\");return[a,i]},d=function(t){return 8==l.ie&&(t=t.replace(/<.+>/g,function(t){return t.toLowerCase()})),t},y=function(t,a,n,o){var r=t.document,s=e(r.body);s.on(\"keydown\",function(t){var e=t.keyCode;if(13===e){var a=m(r),l=p(a),n=l.parentNode;if(\"pre\"===n.tagName.toLowerCase()){if(t.shiftKey)return;return i.msg(\"请暂时用shift+enter\"),!1}r.execCommand(\"formatBlock\",!1,\"<p>\")}}),e(n).parents(\"form\").on(\"submit\",function(){var t=s.html();8==l.ie&&(t=t.replace(/<.+>/g,function(t){return t.toLowerCase()})),n.value=t}),s.on(\"paste\",function(e){r.execCommand(\"formatBlock\",!1,\"<p>\"),setTimeout(function(){f.call(t,s),n.value=s.html()},100)})},f=function(t){var i=this;i.document;t.find(\"*[style]\").each(function(){var t=this.style.textAlign;this.removeAttribute(\"style\"),e(this).css({\"text-align\":t||\"\"})}),t.find(\"table\").addClass(\"layui-table\"),t.find(\"script,link\").remove()},m=function(t){return t.selection?t.selection.createRange():t.getSelection().getRangeAt(0)},p=function(t){return t.endContainer||t.parentElement().childNodes[0]},v=function(t,i,a){var l=this.document,n=document.createElement(t);for(var o in i)n.setAttribute(o,i[o]);if(n.removeAttribute(\"text\"),l.selection){var r=a.text||i.text;if(\"a\"===t&&!r)return;r&&(n.innerHTML=r),a.pasteHTML(e(n).prop(\"outerHTML\")),a.select()}else{var r=a.toString()||i.text;if(\"a\"===t&&!r)return;r&&(n.innerHTML=r),a.deleteContents(),a.insertNode(n)}},h=function(t,i){var a=this.document,l=\"layedit-tool-active\",n=p(m(a)),o=function(e){return t.find(\".layedit-tool-\"+e)};i&&i[i.hasClass(l)?\"removeClass\":\"addClass\"](l),t.find(\">i\").removeClass(l),o(\"unlink\").addClass(r),e(n).parents().each(function(){var t=this.tagName.toLowerCase(),e=this.style.textAlign;\"b\"!==t&&\"strong\"!==t||o(\"b\").addClass(l),\"i\"!==t&&\"em\"!==t||o(\"i\").addClass(l),\"u\"===t&&o(\"u\").addClass(l),\"strike\"===t&&o(\"d\").addClass(l),\"p\"===t&&(\"center\"===e?o(\"center\").addClass(l):\"right\"===e?o(\"right\").addClass(l):o(\"left\").addClass(l)),\"a\"===t&&(o(\"link\").addClass(l),o(\"unlink\").removeClass(r))})},g=function(t,a,l){var n=t.document,o=e(n.body),s={link:function(i){var a=p(i),l=e(a).parent();b.call(o,{href:l.attr(\"href\"),target:l.attr(\"target\")},function(e){var a=l[0];\"A\"===a.tagName?a.href=e.url:v.call(t,\"a\",{target:e.target,href:e.url,text:e.url},i)})},unlink:function(t){n.execCommand(\"unlink\")},face:function(e){x.call(this,function(i){v.call(t,\"img\",{src:i.src,alt:i.alt},e)})},image:function(a){var n=this;layui.use(\"upload\",function(o){var r=l.uploadImage||{};o({url:r.url,method:r.type,elem:e(n).find(\"input\")[0],unwrap:!0,success:function(e){0==e.code?(e.data=e.data||{},v.call(t,\"img\",{src:e.data.src,alt:e.data.title},a)):i.msg(e.msg||\"上传失败\")}})})},code:function(e){k.call(o,function(i){v.call(t,\"pre\",{text:i.code,\"lay-lang\":i.lang},e)})},help:function(){i.open({type:2,title:\"帮助\",area:[\"600px\",\"380px\"],shadeClose:!0,shade:.1,skin:\"layui-layer-msg\",content:[\"http://www.layui.com/about/layedit/help.html\",\"no\"]})}},c=a.find(\".layui-layedit-tool\"),u=function(){var i=e(this),a=i.attr(\"layedit-event\"),l=i.attr(\"lay-command\");if(!i.hasClass(r)){o.focus();var u=m(n);u.commonAncestorContainer;l?(n.execCommand(l),/justifyLeft|justifyCenter|justifyRight/.test(l)&&n.execCommand(\"formatBlock\",!1,\"<p>\"),setTimeout(function(){o.focus()},10)):s[a]&&s[a].call(this,u),h.call(t,c,i)}},d=/image/;c.find(\">i\").on(\"mousedown\",function(){var t=e(this),i=t.attr(\"layedit-event\");d.test(i)||u.call(this)}).on(\"click\",function(){var t=e(this),i=t.attr(\"layedit-event\");d.test(i)&&u.call(this)}),o.on(\"click\",function(){h.call(t,c),i.close(x.index)})},b=function(t,e){var l=this,n=i.open({type:1,id:\"LAY_layedit_link\",area:\"350px\",shade:.05,shadeClose:!0,moveType:1,title:\"超链接\",skin:\"layui-layer-msg\",content:['<ul class=\"layui-form\" style=\"margin: 15px;\">','<li class=\"layui-form-item\">','<label class=\"layui-form-label\" style=\"width: 60px;\">URL</label>','<div class=\"layui-input-block\" style=\"margin-left: 90px\">','<input name=\"url\" lay-verify=\"url\" value=\"'+(t.href||\"\")+'\" autofocus=\"true\" autocomplete=\"off\" class=\"layui-input\">',\"</div>\",\"</li>\",'<li class=\"layui-form-item\">','<label class=\"layui-form-label\" style=\"width: 60px;\">打开方式</label>','<div class=\"layui-input-block\" style=\"margin-left: 90px\">','<input type=\"radio\" name=\"target\" value=\"_self\" class=\"layui-input\" title=\"当前窗口\"'+(\"_self\"!==t.target&&t.target?\"\":\"checked\")+\">\",'<input type=\"radio\" name=\"target\" value=\"_blank\" class=\"layui-input\" title=\"新窗口\" '+(\"_blank\"===t.target?\"checked\":\"\")+\">\",\"</div>\",\"</li>\",'<li class=\"layui-form-item\" style=\"text-align: center;\">','<button type=\"button\" lay-submit lay-filter=\"layedit-link-yes\" class=\"layui-btn\"> 确定 </button>','<button style=\"margin-left: 20px;\" type=\"button\" class=\"layui-btn layui-btn-primary\"> 取消 </button>',\"</li>\",\"</ul>\"].join(\"\"),success:function(t,n){var o=\"submit(layedit-link-yes)\";a.render(\"radio\"),t.find(\".layui-btn-primary\").on(\"click\",function(){i.close(n),l.focus()}),a.on(o,function(t){i.close(b.index),e&&e(t.field)})}});b.index=n},x=function(t){var a=function(){var t=[\"[微笑]\",\"[嘻嘻]\",\"[哈哈]\",\"[可爱]\",\"[可怜]\",\"[挖鼻]\",\"[吃惊]\",\"[害羞]\",\"[挤眼]\",\"[闭嘴]\",\"[鄙视]\",\"[爱你]\",\"[泪]\",\"[偷笑]\",\"[亲亲]\",\"[生病]\",\"[太开心]\",\"[白眼]\",\"[右哼哼]\",\"[左哼哼]\",\"[嘘]\",\"[衰]\",\"[委屈]\",\"[吐]\",\"[哈欠]\",\"[抱抱]\",\"[怒]\",\"[疑问]\",\"[馋嘴]\",\"[拜拜]\",\"[思考]\",\"[汗]\",\"[困]\",\"[睡]\",\"[钱]\",\"[失望]\",\"[酷]\",\"[色]\",\"[哼]\",\"[鼓掌]\",\"[晕]\",\"[悲伤]\",\"[抓狂]\",\"[黑线]\",\"[阴险]\",\"[怒骂]\",\"[互粉]\",\"[心]\",\"[伤心]\",\"[猪头]\",\"[熊猫]\",\"[兔子]\",\"[ok]\",\"[耶]\",\"[good]\",\"[NO]\",\"[赞]\",\"[来]\",\"[弱]\",\"[草泥马]\",\"[神马]\",\"[囧]\",\"[浮云]\",\"[给力]\",\"[围观]\",\"[威武]\",\"[奥特曼]\",\"[礼物]\",\"[钟]\",\"[话筒]\",\"[蜡烛]\",\"[蛋糕]\"],e={};return layui.each(t,function(t,i){e[i]=layui.cache.dir+\"images/face/\"+t+\".gif\"}),e}();return x.hide=x.hide||function(t){\"face\"!==e(t.target).attr(\"layedit-event\")&&i.close(x.index)},x.index=i.tips(function(){var t=[];return layui.each(a,function(e,i){t.push('<li title=\"'+e+'\"><img src=\"'+i+'\" alt=\"'+e+'\"></li>')}),'<ul class=\"layui-clear\">'+t.join(\"\")+\"</ul>\"}(),this,{tips:1,time:0,skin:\"layui-box layui-util-face\",maxWidth:500,success:function(l,n){l.css({marginTop:-4,marginLeft:-10}).find(\".layui-clear>li\").on(\"click\",function(){t&&t({src:a[this.title],alt:this.title}),i.close(n)}),e(document).off(\"click\",x.hide).on(\"click\",x.hide)}})},k=function(t){var e=this,l=i.open({type:1,id:\"LAY_layedit_code\",area:\"550px\",shade:.05,shadeClose:!0,moveType:1,title:\"插入代码\",skin:\"layui-layer-msg\",content:['<ul class=\"layui-form layui-form-pane\" style=\"margin: 15px;\">','<li class=\"layui-form-item\">','<label class=\"layui-form-label\">请选择语言</label>','<div class=\"layui-input-block\">','<select name=\"lang\">','<option value=\"JavaScript\">JavaScript</option>','<option value=\"HTML\">HTML</option>','<option value=\"CSS\">CSS</option>','<option value=\"Java\">Java</option>','<option value=\"PHP\">PHP</option>','<option value=\"C#\">C#</option>','<option value=\"Python\">Python</option>','<option value=\"Ruby\">Ruby</option>','<option value=\"Go\">Go</option>',\"</select>\",\"</div>\",\"</li>\",'<li class=\"layui-form-item layui-form-text\">','<label class=\"layui-form-label\">代码</label>','<div class=\"layui-input-block\">','<textarea name=\"code\" lay-verify=\"required\" autofocus=\"true\" class=\"layui-textarea\" style=\"height: 200px;\"></textarea>',\"</div>\",\"</li>\",'<li class=\"layui-form-item\" style=\"text-align: center;\">','<button type=\"button\" lay-submit lay-filter=\"layedit-code-yes\" class=\"layui-btn\"> 确定 </button>','<button style=\"margin-left: 20px;\" type=\"button\" class=\"layui-btn layui-btn-primary\"> 取消 </button>',\"</li>\",\"</ul>\"].join(\"\"),success:function(l,n){var o=\"submit(layedit-code-yes)\";a.render(\"select\"),l.find(\".layui-btn-primary\").on(\"click\",function(){i.close(n),e.focus()}),a.on(o,function(e){i.close(k.index),t&&t(e.field)})}});k.index=l},C={html:'<i class=\"layui-icon layedit-tool-html\" title=\"HTML源代码\" lay-command=\"html\" layedit-event=\"html\"\">&#xe64b;</i><span class=\"layedit-tool-mid\"></span>',strong:'<i class=\"layui-icon layedit-tool-b\" title=\"加粗\" lay-command=\"Bold\" layedit-event=\"b\"\">&#xe62b;</i>',italic:'<i class=\"layui-icon layedit-tool-i\" title=\"斜体\" lay-command=\"italic\" layedit-event=\"i\"\">&#xe644;</i>',underline:'<i class=\"layui-icon layedit-tool-u\" title=\"下划线\" lay-command=\"underline\" layedit-event=\"u\"\">&#xe646;</i>',del:'<i class=\"layui-icon layedit-tool-d\" title=\"删除线\" lay-command=\"strikeThrough\" layedit-event=\"d\"\">&#xe64f;</i>',\"|\":'<span class=\"layedit-tool-mid\"></span>',left:'<i class=\"layui-icon layedit-tool-left\" title=\"左对齐\" lay-command=\"justifyLeft\" layedit-event=\"left\"\">&#xe649;</i>',center:'<i class=\"layui-icon layedit-tool-center\" title=\"居中对齐\" lay-command=\"justifyCenter\" layedit-event=\"center\"\">&#xe647;</i>',right:'<i class=\"layui-icon layedit-tool-right\" title=\"右对齐\" lay-command=\"justifyRight\" layedit-event=\"right\"\">&#xe648;</i>',link:'<i class=\"layui-icon layedit-tool-link\" title=\"插入链接\" layedit-event=\"link\"\">&#xe64c;</i>',unlink:'<i class=\"layui-icon layedit-tool-unlink layui-disabled\" title=\"清除链接\" lay-command=\"unlink\" layedit-event=\"unlink\"\">&#xe64d;</i>',face:'<i class=\"layui-icon layedit-tool-face\" title=\"表情\" layedit-event=\"face\"\">&#xe650;</i>',image:'<i class=\"layui-icon layedit-tool-image\" title=\"图片\" layedit-event=\"image\">&#xe64a;<input type=\"file\" name=\"file\"></i>',code:'<i class=\"layui-icon layedit-tool-code\" title=\"插入代码\" layedit-event=\"code\">&#xe64e;</i>',help:'<i class=\"layui-icon layedit-tool-help\" title=\"帮助\" layedit-event=\"help\">&#xe607;</i>'},w=new s;t(n,w)});layui.define(\"jquery\",function(e){\"use strict\";var a=layui.jquery,l=\"http://www.layui.com/doc/modules/code.html\";e(\"code\",function(e){var t=[];e=e||{},e.elem=a(e.elem||\".layui-code\"),e.about=!(\"about\"in e)||e.about,e.elem.each(function(){t.push(this)}),layui.each(t.reverse(),function(t,i){var c=a(i),o=c.html();(c.attr(\"lay-encode\")||e.encode)&&(o=o.replace(/&(?!#?[a-zA-Z0-9]+;)/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/'/g,\"&#39;\").replace(/\"/g,\"&quot;\")),c.html('<ol class=\"layui-code-ol\"><li>'+o.replace(/[\\r\\t\\n]+/g,\"</li><li>\")+\"</li></ol>\"),c.find(\">.layui-code-h3\")[0]||c.prepend('<h3 class=\"layui-code-h3\">'+(c.attr(\"lay-title\")||e.title||\"code\")+(e.about?'<a href=\"'+l+'\" target=\"_blank\">layui.code</a>':\"\")+\"</h3>\");var d=c.find(\">.layui-code-ol\");c.addClass(\"layui-box layui-code-view\"),(c.attr(\"lay-skin\")||e.skin)&&c.addClass(\"layui-code-\"+(c.attr(\"lay-skin\")||e.skin)),(d.find(\"li\").length/100|0)>0&&d.css(\"margin-left\",(d.find(\"li\").length/100|0)+\"px\"),(c.attr(\"lay-height\")||e.height)&&d.css(\"max-height\",c.attr(\"lay-height\")||e.height)})})}).addcss(\"modules/code.css\",\"skincodecss\");"
  },
  {
    "path": "public/static/layui/lay/lib/jquery.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;!function(e,t){\"object\"==typeof module&&\"object\"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error(\"jQuery requires a window with a document\");return t(e)}:t(e)}(\"undefined\"!=typeof window?window:this,function(e,t){function n(e){var t=!!e&&\"length\"in e&&e.length,n=pe.type(e);return\"function\"!==n&&!pe.isWindow(e)&&(\"array\"===n||0===t||\"number\"==typeof t&&t>0&&t-1 in e)}function r(e,t,n){if(pe.isFunction(t))return pe.grep(e,function(e,r){return!!t.call(e,r,e)!==n});if(t.nodeType)return pe.grep(e,function(e){return e===t!==n});if(\"string\"==typeof t){if(Ce.test(t))return pe.filter(t,e,n);t=pe.filter(t,e)}return pe.grep(e,function(e){return pe.inArray(e,t)>-1!==n})}function i(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}function o(e){var t={};return pe.each(e.match(De)||[],function(e,n){t[n]=!0}),t}function a(){re.addEventListener?(re.removeEventListener(\"DOMContentLoaded\",s),e.removeEventListener(\"load\",s)):(re.detachEvent(\"onreadystatechange\",s),e.detachEvent(\"onload\",s))}function s(){(re.addEventListener||\"load\"===e.event.type||\"complete\"===re.readyState)&&(a(),pe.ready())}function u(e,t,n){if(void 0===n&&1===e.nodeType){var r=\"data-\"+t.replace(_e,\"-$1\").toLowerCase();if(n=e.getAttribute(r),\"string\"==typeof n){try{n=\"true\"===n||\"false\"!==n&&(\"null\"===n?null:+n+\"\"===n?+n:qe.test(n)?pe.parseJSON(n):n)}catch(i){}pe.data(e,t,n)}else n=void 0}return n}function l(e){var t;for(t in e)if((\"data\"!==t||!pe.isEmptyObject(e[t]))&&\"toJSON\"!==t)return!1;return!0}function c(e,t,n,r){if(He(e)){var i,o,a=pe.expando,s=e.nodeType,u=s?pe.cache:e,l=s?e[a]:e[a]&&a;if(l&&u[l]&&(r||u[l].data)||void 0!==n||\"string\"!=typeof t)return l||(l=s?e[a]=ne.pop()||pe.guid++:a),u[l]||(u[l]=s?{}:{toJSON:pe.noop}),\"object\"!=typeof t&&\"function\"!=typeof t||(r?u[l]=pe.extend(u[l],t):u[l].data=pe.extend(u[l].data,t)),o=u[l],r||(o.data||(o.data={}),o=o.data),void 0!==n&&(o[pe.camelCase(t)]=n),\"string\"==typeof t?(i=o[t],null==i&&(i=o[pe.camelCase(t)])):i=o,i}}function f(e,t,n){if(He(e)){var r,i,o=e.nodeType,a=o?pe.cache:e,s=o?e[pe.expando]:pe.expando;if(a[s]){if(t&&(r=n?a[s]:a[s].data)){pe.isArray(t)?t=t.concat(pe.map(t,pe.camelCase)):t in r?t=[t]:(t=pe.camelCase(t),t=t in r?[t]:t.split(\" \")),i=t.length;for(;i--;)delete r[t[i]];if(n?!l(r):!pe.isEmptyObject(r))return}(n||(delete a[s].data,l(a[s])))&&(o?pe.cleanData([e],!0):fe.deleteExpando||a!=a.window?delete a[s]:a[s]=void 0)}}}function d(e,t,n,r){var i,o=1,a=20,s=r?function(){return r.cur()}:function(){return pe.css(e,t,\"\")},u=s(),l=n&&n[3]||(pe.cssNumber[t]?\"\":\"px\"),c=(pe.cssNumber[t]||\"px\"!==l&&+u)&&Me.exec(pe.css(e,t));if(c&&c[3]!==l){l=l||c[3],n=n||[],c=+u||1;do o=o||\".5\",c/=o,pe.style(e,t,c+l);while(o!==(o=s()/u)&&1!==o&&--a)}return n&&(c=+c||+u||0,i=n[1]?c+(n[1]+1)*n[2]:+n[2],r&&(r.unit=l,r.start=c,r.end=i)),i}function p(e){var t=ze.split(\"|\"),n=e.createDocumentFragment();if(n.createElement)for(;t.length;)n.createElement(t.pop());return n}function h(e,t){var n,r,i=0,o=\"undefined\"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||\"*\"):\"undefined\"!=typeof e.querySelectorAll?e.querySelectorAll(t||\"*\"):void 0;if(!o)for(o=[],n=e.childNodes||e;null!=(r=n[i]);i++)!t||pe.nodeName(r,t)?o.push(r):pe.merge(o,h(r,t));return void 0===t||t&&pe.nodeName(e,t)?pe.merge([e],o):o}function g(e,t){for(var n,r=0;null!=(n=e[r]);r++)pe._data(n,\"globalEval\",!t||pe._data(t[r],\"globalEval\"))}function m(e){Be.test(e.type)&&(e.defaultChecked=e.checked)}function y(e,t,n,r,i){for(var o,a,s,u,l,c,f,d=e.length,y=p(t),v=[],x=0;x<d;x++)if(a=e[x],a||0===a)if(\"object\"===pe.type(a))pe.merge(v,a.nodeType?[a]:a);else if(Ue.test(a)){for(u=u||y.appendChild(t.createElement(\"div\")),l=(We.exec(a)||[\"\",\"\"])[1].toLowerCase(),f=Xe[l]||Xe._default,u.innerHTML=f[1]+pe.htmlPrefilter(a)+f[2],o=f[0];o--;)u=u.lastChild;if(!fe.leadingWhitespace&&$e.test(a)&&v.push(t.createTextNode($e.exec(a)[0])),!fe.tbody)for(a=\"table\"!==l||Ve.test(a)?\"<table>\"!==f[1]||Ve.test(a)?0:u:u.firstChild,o=a&&a.childNodes.length;o--;)pe.nodeName(c=a.childNodes[o],\"tbody\")&&!c.childNodes.length&&a.removeChild(c);for(pe.merge(v,u.childNodes),u.textContent=\"\";u.firstChild;)u.removeChild(u.firstChild);u=y.lastChild}else v.push(t.createTextNode(a));for(u&&y.removeChild(u),fe.appendChecked||pe.grep(h(v,\"input\"),m),x=0;a=v[x++];)if(r&&pe.inArray(a,r)>-1)i&&i.push(a);else if(s=pe.contains(a.ownerDocument,a),u=h(y.appendChild(a),\"script\"),s&&g(u),n)for(o=0;a=u[o++];)Ie.test(a.type||\"\")&&n.push(a);return u=null,y}function v(){return!0}function x(){return!1}function b(){try{return re.activeElement}catch(e){}}function w(e,t,n,r,i,o){var a,s;if(\"object\"==typeof t){\"string\"!=typeof n&&(r=r||n,n=void 0);for(s in t)w(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&(\"string\"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),i===!1)i=x;else if(!i)return e;return 1===o&&(a=i,i=function(e){return pe().off(e),a.apply(this,arguments)},i.guid=a.guid||(a.guid=pe.guid++)),e.each(function(){pe.event.add(this,t,i,r,n)})}function T(e,t){return pe.nodeName(e,\"table\")&&pe.nodeName(11!==t.nodeType?t:t.firstChild,\"tr\")?e.getElementsByTagName(\"tbody\")[0]||e.appendChild(e.ownerDocument.createElement(\"tbody\")):e}function C(e){return e.type=(null!==pe.find.attr(e,\"type\"))+\"/\"+e.type,e}function E(e){var t=it.exec(e.type);return t?e.type=t[1]:e.removeAttribute(\"type\"),e}function N(e,t){if(1===t.nodeType&&pe.hasData(e)){var n,r,i,o=pe._data(e),a=pe._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;r<i;r++)pe.event.add(t,n,s[n][r])}a.data&&(a.data=pe.extend({},a.data))}}function k(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!fe.noCloneEvent&&t[pe.expando]){i=pe._data(t);for(r in i.events)pe.removeEvent(t,r,i.handle);t.removeAttribute(pe.expando)}\"script\"===n&&t.text!==e.text?(C(t).text=e.text,E(t)):\"object\"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),fe.html5Clone&&e.innerHTML&&!pe.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):\"input\"===n&&Be.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):\"option\"===n?t.defaultSelected=t.selected=e.defaultSelected:\"input\"!==n&&\"textarea\"!==n||(t.defaultValue=e.defaultValue)}}function S(e,t,n,r){t=oe.apply([],t);var i,o,a,s,u,l,c=0,f=e.length,d=f-1,p=t[0],g=pe.isFunction(p);if(g||f>1&&\"string\"==typeof p&&!fe.checkClone&&rt.test(p))return e.each(function(i){var o=e.eq(i);g&&(t[0]=p.call(this,i,o.html())),S(o,t,n,r)});if(f&&(l=y(t,e[0].ownerDocument,!1,e,r),i=l.firstChild,1===l.childNodes.length&&(l=i),i||r)){for(s=pe.map(h(l,\"script\"),C),a=s.length;c<f;c++)o=l,c!==d&&(o=pe.clone(o,!0,!0),a&&pe.merge(s,h(o,\"script\"))),n.call(e[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,pe.map(s,E),c=0;c<a;c++)o=s[c],Ie.test(o.type||\"\")&&!pe._data(o,\"globalEval\")&&pe.contains(u,o)&&(o.src?pe._evalUrl&&pe._evalUrl(o.src):pe.globalEval((o.text||o.textContent||o.innerHTML||\"\").replace(ot,\"\")));l=i=null}return e}function A(e,t,n){for(var r,i=t?pe.filter(t,e):e,o=0;null!=(r=i[o]);o++)n||1!==r.nodeType||pe.cleanData(h(r)),r.parentNode&&(n&&pe.contains(r.ownerDocument,r)&&g(h(r,\"script\")),r.parentNode.removeChild(r));return e}function D(e,t){var n=pe(t.createElement(e)).appendTo(t.body),r=pe.css(n[0],\"display\");return n.detach(),r}function j(e){var t=re,n=lt[e];return n||(n=D(e,t),\"none\"!==n&&n||(ut=(ut||pe(\"<iframe frameborder='0' width='0' height='0'/>\")).appendTo(t.documentElement),t=(ut[0].contentWindow||ut[0].contentDocument).document,t.write(),t.close(),n=D(e,t),ut.detach()),lt[e]=n),n}function L(e,t){return{get:function(){return e()?void delete this.get:(this.get=t).apply(this,arguments)}}}function H(e){if(e in Et)return e;for(var t=e.charAt(0).toUpperCase()+e.slice(1),n=Ct.length;n--;)if(e=Ct[n]+t,e in Et)return e}function q(e,t){for(var n,r,i,o=[],a=0,s=e.length;a<s;a++)r=e[a],r.style&&(o[a]=pe._data(r,\"olddisplay\"),n=r.style.display,t?(o[a]||\"none\"!==n||(r.style.display=\"\"),\"\"===r.style.display&&Re(r)&&(o[a]=pe._data(r,\"olddisplay\",j(r.nodeName)))):(i=Re(r),(n&&\"none\"!==n||!i)&&pe._data(r,\"olddisplay\",i?n:pe.css(r,\"display\"))));for(a=0;a<s;a++)r=e[a],r.style&&(t&&\"none\"!==r.style.display&&\"\"!==r.style.display||(r.style.display=t?o[a]||\"\":\"none\"));return e}function _(e,t,n){var r=bt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||\"px\"):t}function F(e,t,n,r,i){for(var o=n===(r?\"border\":\"content\")?4:\"width\"===t?1:0,a=0;o<4;o+=2)\"margin\"===n&&(a+=pe.css(e,n+Oe[o],!0,i)),r?(\"content\"===n&&(a-=pe.css(e,\"padding\"+Oe[o],!0,i)),\"margin\"!==n&&(a-=pe.css(e,\"border\"+Oe[o]+\"Width\",!0,i))):(a+=pe.css(e,\"padding\"+Oe[o],!0,i),\"padding\"!==n&&(a+=pe.css(e,\"border\"+Oe[o]+\"Width\",!0,i)));return a}function M(t,n,r){var i=!0,o=\"width\"===n?t.offsetWidth:t.offsetHeight,a=ht(t),s=fe.boxSizing&&\"border-box\"===pe.css(t,\"boxSizing\",!1,a);if(re.msFullscreenElement&&e.top!==e&&t.getClientRects().length&&(o=Math.round(100*t.getBoundingClientRect()[n])),o<=0||null==o){if(o=gt(t,n,a),(o<0||null==o)&&(o=t.style[n]),ft.test(o))return o;i=s&&(fe.boxSizingReliable()||o===t.style[n]),o=parseFloat(o)||0}return o+F(t,n,r||(s?\"border\":\"content\"),i,a)+\"px\"}function O(e,t,n,r,i){return new O.prototype.init(e,t,n,r,i)}function R(){return e.setTimeout(function(){Nt=void 0}),Nt=pe.now()}function P(e,t){var n,r={height:e},i=0;for(t=t?1:0;i<4;i+=2-t)n=Oe[i],r[\"margin\"+n]=r[\"padding\"+n]=e;return t&&(r.opacity=r.width=e),r}function B(e,t,n){for(var r,i=($.tweeners[t]||[]).concat($.tweeners[\"*\"]),o=0,a=i.length;o<a;o++)if(r=i[o].call(n,t,e))return r}function W(e,t,n){var r,i,o,a,s,u,l,c,f=this,d={},p=e.style,h=e.nodeType&&Re(e),g=pe._data(e,\"fxshow\");n.queue||(s=pe._queueHooks(e,\"fx\"),null==s.unqueued&&(s.unqueued=0,u=s.empty.fire,s.empty.fire=function(){s.unqueued||u()}),s.unqueued++,f.always(function(){f.always(function(){s.unqueued--,pe.queue(e,\"fx\").length||s.empty.fire()})})),1===e.nodeType&&(\"height\"in t||\"width\"in t)&&(n.overflow=[p.overflow,p.overflowX,p.overflowY],l=pe.css(e,\"display\"),c=\"none\"===l?pe._data(e,\"olddisplay\")||j(e.nodeName):l,\"inline\"===c&&\"none\"===pe.css(e,\"float\")&&(fe.inlineBlockNeedsLayout&&\"inline\"!==j(e.nodeName)?p.zoom=1:p.display=\"inline-block\")),n.overflow&&(p.overflow=\"hidden\",fe.shrinkWrapBlocks()||f.always(function(){p.overflow=n.overflow[0],p.overflowX=n.overflow[1],p.overflowY=n.overflow[2]}));for(r in t)if(i=t[r],St.exec(i)){if(delete t[r],o=o||\"toggle\"===i,i===(h?\"hide\":\"show\")){if(\"show\"!==i||!g||void 0===g[r])continue;h=!0}d[r]=g&&g[r]||pe.style(e,r)}else l=void 0;if(pe.isEmptyObject(d))\"inline\"===(\"none\"===l?j(e.nodeName):l)&&(p.display=l);else{g?\"hidden\"in g&&(h=g.hidden):g=pe._data(e,\"fxshow\",{}),o&&(g.hidden=!h),h?pe(e).show():f.done(function(){pe(e).hide()}),f.done(function(){var t;pe._removeData(e,\"fxshow\");for(t in d)pe.style(e,t,d[t])});for(r in d)a=B(h?g[r]:0,r,f),r in g||(g[r]=a.start,h&&(a.end=a.start,a.start=\"width\"===r||\"height\"===r?1:0))}}function I(e,t){var n,r,i,o,a;for(n in e)if(r=pe.camelCase(n),i=t[r],o=e[n],pe.isArray(o)&&(i=o[1],o=e[n]=o[0]),n!==r&&(e[r]=o,delete e[n]),a=pe.cssHooks[r],a&&\"expand\"in a){o=a.expand(o),delete e[r];for(n in o)n in e||(e[n]=o[n],t[n]=i)}else t[r]=i}function $(e,t,n){var r,i,o=0,a=$.prefilters.length,s=pe.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;for(var t=Nt||R(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;a<u;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),o<1&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:pe.extend({},t),opts:pe.extend(!0,{specialEasing:{},easing:pe.easing._default},n),originalProperties:t,originalOptions:n,startTime:Nt||R(),duration:n.duration,tweens:[],createTween:function(t,n){var r=pe.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;n<r;n++)l.tweens[n].run(1);return t?(s.notifyWith(e,[l,1,0]),s.resolveWith(e,[l,t])):s.rejectWith(e,[l,t]),this}}),c=l.props;for(I(c,l.opts.specialEasing);o<a;o++)if(r=$.prefilters[o].call(l,e,c,l.opts))return pe.isFunction(r.stop)&&(pe._queueHooks(l.elem,l.opts.queue).stop=pe.proxy(r.stop,r)),r;return pe.map(c,B,l),pe.isFunction(l.opts.start)&&l.opts.start.call(e,l),pe.fx.timer(pe.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function z(e){return pe.attr(e,\"class\")||\"\"}function X(e){return function(t,n){\"string\"!=typeof t&&(n=t,t=\"*\");var r,i=0,o=t.toLowerCase().match(De)||[];if(pe.isFunction(n))for(;r=o[i++];)\"+\"===r.charAt(0)?(r=r.slice(1)||\"*\",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function U(e,t,n,r){function i(s){var u;return o[s]=!0,pe.each(e[s]||[],function(e,s){var l=s(t,n,r);return\"string\"!=typeof l||a||o[l]?a?!(u=l):void 0:(t.dataTypes.unshift(l),i(l),!1)}),u}var o={},a=e===Qt;return i(t.dataTypes[0])||!o[\"*\"]&&i(\"*\")}function V(e,t){var n,r,i=pe.ajaxSettings.flatOptions||{};for(r in t)void 0!==t[r]&&((i[r]?e:n||(n={}))[r]=t[r]);return n&&pe.extend(!0,e,n),e}function Y(e,t,n){for(var r,i,o,a,s=e.contents,u=e.dataTypes;\"*\"===u[0];)u.shift(),void 0===i&&(i=e.mimeType||t.getResponseHeader(\"Content-Type\"));if(i)for(a in s)if(s[a]&&s[a].test(i)){u.unshift(a);break}if(u[0]in n)o=u[0];else{for(a in n){if(!u[0]||e.converters[a+\" \"+u[0]]){o=a;break}r||(r=a)}o=o||r}if(o)return o!==u[0]&&u.unshift(o),n[o]}function J(e,t,n,r){var i,o,a,s,u,l={},c=e.dataTypes.slice();if(c[1])for(a in e.converters)l[a.toLowerCase()]=e.converters[a];for(o=c.shift();o;)if(e.responseFields[o]&&(n[e.responseFields[o]]=t),!u&&r&&e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u=o,o=c.shift())if(\"*\"===o)o=u;else if(\"*\"!==u&&u!==o){if(a=l[u+\" \"+o]||l[\"* \"+o],!a)for(i in l)if(s=i.split(\" \"),s[1]===o&&(a=l[u+\" \"+s[0]]||l[\"* \"+s[0]])){a===!0?a=l[i]:l[i]!==!0&&(o=s[0],c.unshift(s[1]));break}if(a!==!0)if(a&&e[\"throws\"])t=a(t);else try{t=a(t)}catch(f){return{state:\"parsererror\",error:a?f:\"No conversion from \"+u+\" to \"+o}}}return{state:\"success\",data:t}}function G(e){return e.style&&e.style.display||pe.css(e,\"display\")}function K(e){for(;e&&1===e.nodeType;){if(\"none\"===G(e)||\"hidden\"===e.type)return!0;e=e.parentNode}return!1}function Q(e,t,n,r){var i;if(pe.isArray(t))pe.each(t,function(t,i){n||rn.test(e)?r(e,i):Q(e+\"[\"+(\"object\"==typeof i&&null!=i?t:\"\")+\"]\",i,n,r)});else if(n||\"object\"!==pe.type(t))r(e,t);else for(i in t)Q(e+\"[\"+i+\"]\",t[i],n,r)}function Z(){try{return new e.XMLHttpRequest}catch(t){}}function ee(){try{return new e.ActiveXObject(\"Microsoft.XMLHTTP\")}catch(t){}}function te(e){return pe.isWindow(e)?e:9===e.nodeType&&(e.defaultView||e.parentWindow)}var ne=[],re=e.document,ie=ne.slice,oe=ne.concat,ae=ne.push,se=ne.indexOf,ue={},le=ue.toString,ce=ue.hasOwnProperty,fe={},de=\"1.12.3\",pe=function(e,t){return new pe.fn.init(e,t)},he=/^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,ge=/^-ms-/,me=/-([\\da-z])/gi,ye=function(e,t){return t.toUpperCase()};pe.fn=pe.prototype={jquery:de,constructor:pe,selector:\"\",length:0,toArray:function(){return ie.call(this)},get:function(e){return null!=e?e<0?this[e+this.length]:this[e]:ie.call(this)},pushStack:function(e){var t=pe.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e){return pe.each(this,e)},map:function(e){return this.pushStack(pe.map(this,function(t,n){return e.call(t,n,t)}))},slice:function(){return this.pushStack(ie.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(e<0?t:0);return this.pushStack(n>=0&&n<t?[this[n]]:[])},end:function(){return this.prevObject||this.constructor()},push:ae,sort:ne.sort,splice:ne.splice},pe.extend=pe.fn.extend=function(){var e,t,n,r,i,o,a=arguments[0]||{},s=1,u=arguments.length,l=!1;for(\"boolean\"==typeof a&&(l=a,a=arguments[s]||{},s++),\"object\"==typeof a||pe.isFunction(a)||(a={}),s===u&&(a=this,s--);s<u;s++)if(null!=(i=arguments[s]))for(r in i)e=a[r],n=i[r],a!==n&&(l&&n&&(pe.isPlainObject(n)||(t=pe.isArray(n)))?(t?(t=!1,o=e&&pe.isArray(e)?e:[]):o=e&&pe.isPlainObject(e)?e:{},a[r]=pe.extend(l,o,n)):void 0!==n&&(a[r]=n));return a},pe.extend({expando:\"jQuery\"+(de+Math.random()).replace(/\\D/g,\"\"),isReady:!0,error:function(e){throw new Error(e)},noop:function(){},isFunction:function(e){return\"function\"===pe.type(e)},isArray:Array.isArray||function(e){return\"array\"===pe.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){var t=e&&e.toString();return!pe.isArray(e)&&t-parseFloat(t)+1>=0},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},isPlainObject:function(e){var t;if(!e||\"object\"!==pe.type(e)||e.nodeType||pe.isWindow(e))return!1;try{if(e.constructor&&!ce.call(e,\"constructor\")&&!ce.call(e.constructor.prototype,\"isPrototypeOf\"))return!1}catch(n){return!1}if(!fe.ownFirst)for(t in e)return ce.call(e,t);for(t in e);return void 0===t||ce.call(e,t)},type:function(e){return null==e?e+\"\":\"object\"==typeof e||\"function\"==typeof e?ue[le.call(e)]||\"object\":typeof e},globalEval:function(t){t&&pe.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(ge,\"ms-\").replace(me,ye)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t){var r,i=0;if(n(e))for(r=e.length;i<r&&t.call(e[i],i,e[i])!==!1;i++);else for(i in e)if(t.call(e[i],i,e[i])===!1)break;return e},trim:function(e){return null==e?\"\":(e+\"\").replace(he,\"\")},makeArray:function(e,t){var r=t||[];return null!=e&&(n(Object(e))?pe.merge(r,\"string\"==typeof e?[e]:e):ae.call(r,e)),r},inArray:function(e,t,n){var r;if(t){if(se)return se.call(t,e,n);for(r=t.length,n=n?n<0?Math.max(0,r+n):n:0;n<r;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,t){for(var n=+t.length,r=0,i=e.length;r<n;)e[i++]=t[r++];if(n!==n)for(;void 0!==t[r];)e[i++]=t[r++];return e.length=i,e},grep:function(e,t,n){for(var r,i=[],o=0,a=e.length,s=!n;o<a;o++)r=!t(e[o],o),r!==s&&i.push(e[o]);return i},map:function(e,t,r){var i,o,a=0,s=[];if(n(e))for(i=e.length;a<i;a++)o=t(e[a],a,r),null!=o&&s.push(o);else for(a in e)o=t(e[a],a,r),null!=o&&s.push(o);return oe.apply([],s)},guid:1,proxy:function(e,t){var n,r,i;if(\"string\"==typeof t&&(i=e[t],t=e,e=i),pe.isFunction(e))return n=ie.call(arguments,2),r=function(){return e.apply(t||this,n.concat(ie.call(arguments)))},r.guid=e.guid=e.guid||pe.guid++,r},now:function(){return+new Date},support:fe}),\"function\"==typeof Symbol&&(pe.fn[Symbol.iterator]=ne[Symbol.iterator]),pe.each(\"Boolean Number String Function Array Date RegExp Object Error Symbol\".split(\" \"),function(e,t){ue[\"[object \"+t+\"]\"]=t.toLowerCase()});var ve=function(e){function t(e,t,n,r){var i,o,a,s,u,l,f,p,h=t&&t.ownerDocument,g=t?t.nodeType:9;if(n=n||[],\"string\"!=typeof e||!e||1!==g&&9!==g&&11!==g)return n;if(!r&&((t?t.ownerDocument||t:B)!==H&&L(t),t=t||H,_)){if(11!==g&&(l=ye.exec(e)))if(i=l[1]){if(9===g){if(!(a=t.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(h&&(a=h.getElementById(i))&&R(t,a)&&a.id===i)return n.push(a),n}else{if(l[2])return Q.apply(n,t.getElementsByTagName(e)),n;if((i=l[3])&&w.getElementsByClassName&&t.getElementsByClassName)return Q.apply(n,t.getElementsByClassName(i)),n}if(w.qsa&&!X[e+\" \"]&&(!F||!F.test(e))){if(1!==g)h=t,p=e;else if(\"object\"!==t.nodeName.toLowerCase()){for((s=t.getAttribute(\"id\"))?s=s.replace(xe,\"\\\\$&\"):t.setAttribute(\"id\",s=P),f=N(e),o=f.length,u=de.test(s)?\"#\"+s:\"[id='\"+s+\"']\";o--;)f[o]=u+\" \"+d(f[o]);p=f.join(\",\"),h=ve.test(e)&&c(t.parentNode)||t}if(p)try{return Q.apply(n,h.querySelectorAll(p)),n}catch(m){}finally{s===P&&t.removeAttribute(\"id\")}}}return S(e.replace(se,\"$1\"),t,n,r)}function n(){function e(n,r){return t.push(n+\" \")>T.cacheLength&&delete e[t.shift()],e[n+\" \"]=r}var t=[];return e}function r(e){return e[P]=!0,e}function i(e){var t=H.createElement(\"div\");try{return!!e(t)}catch(n){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function o(e,t){for(var n=e.split(\"|\"),r=n.length;r--;)T.attrHandle[n[r]]=t}function a(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&(~t.sourceIndex||V)-(~e.sourceIndex||V);if(r)return r;if(n)for(;n=n.nextSibling;)if(n===t)return-1;return e?1:-1}function s(e){return function(t){var n=t.nodeName.toLowerCase();return\"input\"===n&&t.type===e}}function u(e){return function(t){var n=t.nodeName.toLowerCase();return(\"input\"===n||\"button\"===n)&&t.type===e}}function l(e){return r(function(t){return t=+t,r(function(n,r){for(var i,o=e([],n.length,t),a=o.length;a--;)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}function c(e){return e&&\"undefined\"!=typeof e.getElementsByTagName&&e}function f(){}function d(e){for(var t=0,n=e.length,r=\"\";t<n;t++)r+=e[t].value;return r}function p(e,t,n){var r=t.dir,i=n&&\"parentNode\"===r,o=I++;return t.first?function(t,n,o){for(;t=t[r];)if(1===t.nodeType||i)return e(t,n,o)}:function(t,n,a){var s,u,l,c=[W,o];if(a){for(;t=t[r];)if((1===t.nodeType||i)&&e(t,n,a))return!0}else for(;t=t[r];)if(1===t.nodeType||i){if(l=t[P]||(t[P]={}),u=l[t.uniqueID]||(l[t.uniqueID]={}),(s=u[r])&&s[0]===W&&s[1]===o)return c[2]=s[2];if(u[r]=c,c[2]=e(t,n,a))return!0}}}function h(e){return e.length>1?function(t,n,r){for(var i=e.length;i--;)if(!e[i](t,n,r))return!1;return!0}:e[0]}function g(e,n,r){for(var i=0,o=n.length;i<o;i++)t(e,n[i],r);return r}function m(e,t,n,r,i){for(var o,a=[],s=0,u=e.length,l=null!=t;s<u;s++)(o=e[s])&&(n&&!n(o,r,i)||(a.push(o),l&&t.push(s)));return a}function y(e,t,n,i,o,a){return i&&!i[P]&&(i=y(i)),o&&!o[P]&&(o=y(o,a)),r(function(r,a,s,u){var l,c,f,d=[],p=[],h=a.length,y=r||g(t||\"*\",s.nodeType?[s]:s,[]),v=!e||!r&&t?y:m(y,d,e,s,u),x=n?o||(r?e:h||i)?[]:a:v;if(n&&n(v,x,s,u),i)for(l=m(x,p),i(l,[],s,u),c=l.length;c--;)(f=l[c])&&(x[p[c]]=!(v[p[c]]=f));if(r){if(o||e){if(o){for(l=[],c=x.length;c--;)(f=x[c])&&l.push(v[c]=f);o(null,x=[],l,u)}for(c=x.length;c--;)(f=x[c])&&(l=o?ee(r,f):d[c])>-1&&(r[l]=!(a[l]=f))}}else x=m(x===a?x.splice(h,x.length):x),o?o(null,a,x,u):Q.apply(a,x)})}function v(e){for(var t,n,r,i=e.length,o=T.relative[e[0].type],a=o||T.relative[\" \"],s=o?1:0,u=p(function(e){return e===t},a,!0),l=p(function(e){return ee(t,e)>-1},a,!0),c=[function(e,n,r){var i=!o&&(r||n!==A)||((t=n).nodeType?u(e,n,r):l(e,n,r));return t=null,i}];s<i;s++)if(n=T.relative[e[s].type])c=[p(h(c),n)];else{if(n=T.filter[e[s].type].apply(null,e[s].matches),n[P]){for(r=++s;r<i&&!T.relative[e[r].type];r++);return y(s>1&&h(c),s>1&&d(e.slice(0,s-1).concat({value:\" \"===e[s-2].type?\"*\":\"\"})).replace(se,\"$1\"),n,s<r&&v(e.slice(s,r)),r<i&&v(e=e.slice(r)),r<i&&d(e))}c.push(n)}return h(c)}function x(e,n){var i=n.length>0,o=e.length>0,a=function(r,a,s,u,l){var c,f,d,p=0,h=\"0\",g=r&&[],y=[],v=A,x=r||o&&T.find.TAG(\"*\",l),b=W+=null==v?1:Math.random()||.1,w=x.length;for(l&&(A=a===H||a||l);h!==w&&null!=(c=x[h]);h++){if(o&&c){for(f=0,a||c.ownerDocument===H||(L(c),s=!_);d=e[f++];)if(d(c,a||H,s)){u.push(c);break}l&&(W=b)}i&&((c=!d&&c)&&p--,r&&g.push(c))}if(p+=h,i&&h!==p){for(f=0;d=n[f++];)d(g,y,a,s);if(r){if(p>0)for(;h--;)g[h]||y[h]||(y[h]=G.call(u));y=m(y)}Q.apply(u,y),l&&!r&&y.length>0&&p+n.length>1&&t.uniqueSort(u)}return l&&(W=b,A=v),g};return i?r(a):a}var b,w,T,C,E,N,k,S,A,D,j,L,H,q,_,F,M,O,R,P=\"sizzle\"+1*new Date,B=e.document,W=0,I=0,$=n(),z=n(),X=n(),U=function(e,t){return e===t&&(j=!0),0},V=1<<31,Y={}.hasOwnProperty,J=[],G=J.pop,K=J.push,Q=J.push,Z=J.slice,ee=function(e,t){for(var n=0,r=e.length;n<r;n++)if(e[n]===t)return n;return-1},te=\"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",ne=\"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",re=\"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",ie=\"\\\\[\"+ne+\"*(\"+re+\")(?:\"+ne+\"*([*^$|!~]?=)\"+ne+\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\"+re+\"))|)\"+ne+\"*\\\\]\",oe=\":(\"+re+\")(?:\\\\((('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\"+ie+\")*)|.*)\\\\)|)\",ae=new RegExp(ne+\"+\",\"g\"),se=new RegExp(\"^\"+ne+\"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\"+ne+\"+$\",\"g\"),ue=new RegExp(\"^\"+ne+\"*,\"+ne+\"*\"),le=new RegExp(\"^\"+ne+\"*([>+~]|\"+ne+\")\"+ne+\"*\"),ce=new RegExp(\"=\"+ne+\"*([^\\\\]'\\\"]*?)\"+ne+\"*\\\\]\",\"g\"),fe=new RegExp(oe),de=new RegExp(\"^\"+re+\"$\"),pe={ID:new RegExp(\"^#(\"+re+\")\"),CLASS:new RegExp(\"^\\\\.(\"+re+\")\"),TAG:new RegExp(\"^(\"+re+\"|[*])\"),ATTR:new RegExp(\"^\"+ie),PSEUDO:new RegExp(\"^\"+oe),CHILD:new RegExp(\"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\"+ne+\"*(even|odd|(([+-]|)(\\\\d*)n|)\"+ne+\"*(?:([+-]|)\"+ne+\"*(\\\\d+)|))\"+ne+\"*\\\\)|)\",\"i\"),bool:new RegExp(\"^(?:\"+te+\")$\",\"i\"),needsContext:new RegExp(\"^\"+ne+\"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\"+ne+\"*((?:-\\\\d)?\\\\d*)\"+ne+\"*\\\\)|)(?=[^-]|$)\",\"i\")},he=/^(?:input|select|textarea|button)$/i,ge=/^h\\d$/i,me=/^[^{]+\\{\\s*\\[native \\w/,ye=/^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,ve=/[+~]/,xe=/'|\\\\/g,be=new RegExp(\"\\\\\\\\([\\\\da-f]{1,6}\"+ne+\"?|(\"+ne+\")|.)\",\"ig\"),we=function(e,t,n){var r=\"0x\"+t-65536;return r!==r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},Te=function(){L()};try{Q.apply(J=Z.call(B.childNodes),B.childNodes),J[B.childNodes.length].nodeType}catch(Ce){Q={apply:J.length?function(e,t){K.apply(e,Z.call(t))}:function(e,t){for(var n=e.length,r=0;e[n++]=t[r++];);e.length=n-1}}}w=t.support={},E=t.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return!!t&&\"HTML\"!==t.nodeName},L=t.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:B;return r!==H&&9===r.nodeType&&r.documentElement?(H=r,q=H.documentElement,_=!E(H),(n=H.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener(\"unload\",Te,!1):n.attachEvent&&n.attachEvent(\"onunload\",Te)),w.attributes=i(function(e){return e.className=\"i\",!e.getAttribute(\"className\")}),w.getElementsByTagName=i(function(e){return e.appendChild(H.createComment(\"\")),!e.getElementsByTagName(\"*\").length}),w.getElementsByClassName=me.test(H.getElementsByClassName),w.getById=i(function(e){return q.appendChild(e).id=P,!H.getElementsByName||!H.getElementsByName(P).length}),w.getById?(T.find.ID=function(e,t){if(\"undefined\"!=typeof t.getElementById&&_){var n=t.getElementById(e);return n?[n]:[]}},T.filter.ID=function(e){var t=e.replace(be,we);return function(e){return e.getAttribute(\"id\")===t}}):(delete T.find.ID,T.filter.ID=function(e){var t=e.replace(be,we);return function(e){var n=\"undefined\"!=typeof e.getAttributeNode&&e.getAttributeNode(\"id\");return n&&n.value===t}}),T.find.TAG=w.getElementsByTagName?function(e,t){return\"undefined\"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):w.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if(\"*\"===e){for(;n=o[i++];)1===n.nodeType&&r.push(n);return r}return o},T.find.CLASS=w.getElementsByClassName&&function(e,t){if(\"undefined\"!=typeof t.getElementsByClassName&&_)return t.getElementsByClassName(e)},M=[],F=[],(w.qsa=me.test(H.querySelectorAll))&&(i(function(e){q.appendChild(e).innerHTML=\"<a id='\"+P+\"'></a><select id='\"+P+\"-\\r\\\\' msallowcapture=''><option selected=''></option></select>\",e.querySelectorAll(\"[msallowcapture^='']\").length&&F.push(\"[*^$]=\"+ne+\"*(?:''|\\\"\\\")\"),e.querySelectorAll(\"[selected]\").length||F.push(\"\\\\[\"+ne+\"*(?:value|\"+te+\")\"),e.querySelectorAll(\"[id~=\"+P+\"-]\").length||F.push(\"~=\"),e.querySelectorAll(\":checked\").length||F.push(\":checked\"),e.querySelectorAll(\"a#\"+P+\"+*\").length||F.push(\".#.+[+~]\")}),i(function(e){var t=H.createElement(\"input\");t.setAttribute(\"type\",\"hidden\"),e.appendChild(t).setAttribute(\"name\",\"D\"),e.querySelectorAll(\"[name=d]\").length&&F.push(\"name\"+ne+\"*[*^$|!~]?=\"),e.querySelectorAll(\":enabled\").length||F.push(\":enabled\",\":disabled\"),e.querySelectorAll(\"*,:x\"),F.push(\",.*:\")})),(w.matchesSelector=me.test(O=q.matches||q.webkitMatchesSelector||q.mozMatchesSelector||q.oMatchesSelector||q.msMatchesSelector))&&i(function(e){w.disconnectedMatch=O.call(e,\"div\"),O.call(e,\"[s!='']:x\"),M.push(\"!=\",oe)}),F=F.length&&new RegExp(F.join(\"|\")),M=M.length&&new RegExp(M.join(\"|\")),t=me.test(q.compareDocumentPosition),R=t||me.test(q.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)for(;t=t.parentNode;)if(t===e)return!0;return!1},U=t?function(e,t){if(e===t)return j=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n?n:(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1,1&n||!w.sortDetached&&t.compareDocumentPosition(e)===n?e===H||e.ownerDocument===B&&R(B,e)?-1:t===H||t.ownerDocument===B&&R(B,t)?1:D?ee(D,e)-ee(D,t):0:4&n?-1:1)}:function(e,t){if(e===t)return j=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,s=[e],u=[t];if(!i||!o)return e===H?-1:t===H?1:i?-1:o?1:D?ee(D,e)-ee(D,t):0;if(i===o)return a(e,t);for(n=e;n=n.parentNode;)s.unshift(n);for(n=t;n=n.parentNode;)u.unshift(n);for(;s[r]===u[r];)r++;return r?a(s[r],u[r]):s[r]===B?-1:u[r]===B?1:0},H):H},t.matches=function(e,n){return t(e,null,null,n)},t.matchesSelector=function(e,n){if((e.ownerDocument||e)!==H&&L(e),n=n.replace(ce,\"='$1']\"),w.matchesSelector&&_&&!X[n+\" \"]&&(!M||!M.test(n))&&(!F||!F.test(n)))try{var r=O.call(e,n);if(r||w.disconnectedMatch||e.document&&11!==e.document.nodeType)return r}catch(i){}return t(n,H,null,[e]).length>0},t.contains=function(e,t){return(e.ownerDocument||e)!==H&&L(e),R(e,t)},t.attr=function(e,t){(e.ownerDocument||e)!==H&&L(e);var n=T.attrHandle[t.toLowerCase()],r=n&&Y.call(T.attrHandle,t.toLowerCase())?n(e,t,!_):void 0;return void 0!==r?r:w.attributes||!_?e.getAttribute(t):(r=e.getAttributeNode(t))&&r.specified?r.value:null},t.error=function(e){throw new Error(\"Syntax error, unrecognized expression: \"+e)},t.uniqueSort=function(e){var t,n=[],r=0,i=0;if(j=!w.detectDuplicates,D=!w.sortStable&&e.slice(0),e.sort(U),j){for(;t=e[i++];)t===e[i]&&(r=n.push(i));for(;r--;)e.splice(n[r],1)}return D=null,e},C=t.getText=function(e){var t,n=\"\",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if(\"string\"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=C(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r++];)n+=C(t);return n},T=t.selectors={cacheLength:50,createPseudo:r,match:pe,attrHandle:{},find:{},relative:{\">\":{dir:\"parentNode\",first:!0},\" \":{dir:\"parentNode\"},\"+\":{dir:\"previousSibling\",first:!0},\"~\":{dir:\"previousSibling\"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(be,we),e[3]=(e[3]||e[4]||e[5]||\"\").replace(be,we),\"~=\"===e[2]&&(e[3]=\" \"+e[3]+\" \"),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),\"nth\"===e[1].slice(0,3)?(e[3]||t.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*(\"even\"===e[3]||\"odd\"===e[3])),e[5]=+(e[7]+e[8]||\"odd\"===e[3])):e[3]&&t.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return pe.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||\"\":n&&fe.test(n)&&(t=N(n,!0))&&(t=n.indexOf(\")\",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(be,we).toLowerCase();return\"*\"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=$[e+\" \"];return t||(t=new RegExp(\"(^|\"+ne+\")\"+e+\"(\"+ne+\"|$)\"))&&$(e,function(e){return t.test(\"string\"==typeof e.className&&e.className||\"undefined\"!=typeof e.getAttribute&&e.getAttribute(\"class\")||\"\")})},ATTR:function(e,n,r){return function(i){var o=t.attr(i,e);return null==o?\"!=\"===n:!n||(o+=\"\",\"=\"===n?o===r:\"!=\"===n?o!==r:\"^=\"===n?r&&0===o.indexOf(r):\"*=\"===n?r&&o.indexOf(r)>-1:\"$=\"===n?r&&o.slice(-r.length)===r:\"~=\"===n?(\" \"+o.replace(ae,\" \")+\" \").indexOf(r)>-1:\"|=\"===n&&(o===r||o.slice(0,r.length+1)===r+\"-\"))}},CHILD:function(e,t,n,r,i){var o=\"nth\"!==e.slice(0,3),a=\"last\"!==e.slice(-4),s=\"of-type\"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,f,d,p,h,g=o!==a?\"nextSibling\":\"previousSibling\",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s,x=!1;if(m){if(o){for(;g;){for(d=t;d=d[g];)if(s?d.nodeName.toLowerCase()===y:1===d.nodeType)return!1;h=g=\"only\"===e&&!h&&\"nextSibling\"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){for(d=m,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),\nl=c[e]||[],p=l[0]===W&&l[1],x=p&&l[2],d=p&&m.childNodes[p];d=++p&&d&&d[g]||(x=p=0)||h.pop();)if(1===d.nodeType&&++x&&d===t){c[e]=[W,p,x];break}}else if(v&&(d=t,f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),l=c[e]||[],p=l[0]===W&&l[1],x=p),x===!1)for(;(d=++p&&d&&d[g]||(x=p=0)||h.pop())&&((s?d.nodeName.toLowerCase()!==y:1!==d.nodeType)||!++x||(v&&(f=d[P]||(d[P]={}),c=f[d.uniqueID]||(f[d.uniqueID]={}),c[e]=[W,x]),d!==t)););return x-=i,x===r||x%r===0&&x/r>=0}}},PSEUDO:function(e,n){var i,o=T.pseudos[e]||T.setFilters[e.toLowerCase()]||t.error(\"unsupported pseudo: \"+e);return o[P]?o(n):o.length>1?(i=[e,e,\"\",n],T.setFilters.hasOwnProperty(e.toLowerCase())?r(function(e,t){for(var r,i=o(e,n),a=i.length;a--;)r=ee(e,i[a]),e[r]=!(t[r]=i[a])}):function(e){return o(e,0,i)}):o}},pseudos:{not:r(function(e){var t=[],n=[],i=k(e.replace(se,\"$1\"));return i[P]?r(function(e,t,n,r){for(var o,a=i(e,null,r,[]),s=e.length;s--;)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,r,o){return t[0]=e,i(t,null,o,n),t[0]=null,!n.pop()}}),has:r(function(e){return function(n){return t(e,n).length>0}}),contains:r(function(e){return e=e.replace(be,we),function(t){return(t.textContent||t.innerText||C(t)).indexOf(e)>-1}}),lang:r(function(e){return de.test(e||\"\")||t.error(\"unsupported lang: \"+e),e=e.replace(be,we).toLowerCase(),function(t){var n;do if(n=_?t.lang:t.getAttribute(\"xml:lang\")||t.getAttribute(\"lang\"))return n=n.toLowerCase(),n===e||0===n.indexOf(e+\"-\");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===q},focus:function(e){return e===H.activeElement&&(!H.hasFocus||H.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&!!e.checked||\"option\"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeType<6)return!1;return!0},parent:function(e){return!T.pseudos.empty(e)},header:function(e){return ge.test(e.nodeName)},input:function(e){return he.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return\"input\"===t&&\"button\"===e.type||\"button\"===t},text:function(e){var t;return\"input\"===e.nodeName.toLowerCase()&&\"text\"===e.type&&(null==(t=e.getAttribute(\"type\"))||\"text\"===t.toLowerCase())},first:l(function(){return[0]}),last:l(function(e,t){return[t-1]}),eq:l(function(e,t,n){return[n<0?n+t:n]}),even:l(function(e,t){for(var n=0;n<t;n+=2)e.push(n);return e}),odd:l(function(e,t){for(var n=1;n<t;n+=2)e.push(n);return e}),lt:l(function(e,t,n){for(var r=n<0?n+t:n;--r>=0;)e.push(r);return e}),gt:l(function(e,t,n){for(var r=n<0?n+t:n;++r<t;)e.push(r);return e})}},T.pseudos.nth=T.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})T.pseudos[b]=s(b);for(b in{submit:!0,reset:!0})T.pseudos[b]=u(b);return f.prototype=T.filters=T.pseudos,T.setFilters=new f,N=t.tokenize=function(e,n){var r,i,o,a,s,u,l,c=z[e+\" \"];if(c)return n?0:c.slice(0);for(s=e,u=[],l=T.preFilter;s;){r&&!(i=ue.exec(s))||(i&&(s=s.slice(i[0].length)||s),u.push(o=[])),r=!1,(i=le.exec(s))&&(r=i.shift(),o.push({value:r,type:i[0].replace(se,\" \")}),s=s.slice(r.length));for(a in T.filter)!(i=pe[a].exec(s))||l[a]&&!(i=l[a](i))||(r=i.shift(),o.push({value:r,type:a,matches:i}),s=s.slice(r.length));if(!r)break}return n?s.length:s?t.error(e):z(e,u).slice(0)},k=t.compile=function(e,t){var n,r=[],i=[],o=X[e+\" \"];if(!o){for(t||(t=N(e)),n=t.length;n--;)o=v(t[n]),o[P]?r.push(o):i.push(o);o=X(e,x(i,r)),o.selector=e}return o},S=t.select=function(e,t,n,r){var i,o,a,s,u,l=\"function\"==typeof e&&e,f=!r&&N(e=l.selector||e);if(n=n||[],1===f.length){if(o=f[0]=f[0].slice(0),o.length>2&&\"ID\"===(a=o[0]).type&&w.getById&&9===t.nodeType&&_&&T.relative[o[1].type]){if(t=(T.find.ID(a.matches[0].replace(be,we),t)||[])[0],!t)return n;l&&(t=t.parentNode),e=e.slice(o.shift().value.length)}for(i=pe.needsContext.test(e)?0:o.length;i--&&(a=o[i],!T.relative[s=a.type]);)if((u=T.find[s])&&(r=u(a.matches[0].replace(be,we),ve.test(o[0].type)&&c(t.parentNode)||t))){if(o.splice(i,1),e=r.length&&d(o),!e)return Q.apply(n,r),n;break}}return(l||k(e,f))(r,t,!_,n,!t||ve.test(e)&&c(t.parentNode)||t),n},w.sortStable=P.split(\"\").sort(U).join(\"\")===P,w.detectDuplicates=!!j,L(),w.sortDetached=i(function(e){return 1&e.compareDocumentPosition(H.createElement(\"div\"))}),i(function(e){return e.innerHTML=\"<a href='#'></a>\",\"#\"===e.firstChild.getAttribute(\"href\")})||o(\"type|href|height|width\",function(e,t,n){if(!n)return e.getAttribute(t,\"type\"===t.toLowerCase()?1:2)}),w.attributes&&i(function(e){return e.innerHTML=\"<input/>\",e.firstChild.setAttribute(\"value\",\"\"),\"\"===e.firstChild.getAttribute(\"value\")})||o(\"value\",function(e,t,n){if(!n&&\"input\"===e.nodeName.toLowerCase())return e.defaultValue}),i(function(e){return null==e.getAttribute(\"disabled\")})||o(te,function(e,t,n){var r;if(!n)return e[t]===!0?t.toLowerCase():(r=e.getAttributeNode(t))&&r.specified?r.value:null}),t}(e);pe.find=ve,pe.expr=ve.selectors,pe.expr[\":\"]=pe.expr.pseudos,pe.uniqueSort=pe.unique=ve.uniqueSort,pe.text=ve.getText,pe.isXMLDoc=ve.isXML,pe.contains=ve.contains;var xe=function(e,t,n){for(var r=[],i=void 0!==n;(e=e[t])&&9!==e.nodeType;)if(1===e.nodeType){if(i&&pe(e).is(n))break;r.push(e)}return r},be=function(e,t){for(var n=[];e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n},we=pe.expr.match.needsContext,Te=/^<([\\w-]+)\\s*\\/?>(?:<\\/\\1>|)$/,Ce=/^.[^:#\\[\\.,]*$/;pe.filter=function(e,t,n){var r=t[0];return n&&(e=\":not(\"+e+\")\"),1===t.length&&1===r.nodeType?pe.find.matchesSelector(r,e)?[r]:[]:pe.find.matches(e,pe.grep(t,function(e){return 1===e.nodeType}))},pe.fn.extend({find:function(e){var t,n=[],r=this,i=r.length;if(\"string\"!=typeof e)return this.pushStack(pe(e).filter(function(){for(t=0;t<i;t++)if(pe.contains(r[t],this))return!0}));for(t=0;t<i;t++)pe.find(e,r[t],n);return n=this.pushStack(i>1?pe.unique(n):n),n.selector=this.selector?this.selector+\" \"+e:e,n},filter:function(e){return this.pushStack(r(this,e||[],!1))},not:function(e){return this.pushStack(r(this,e||[],!0))},is:function(e){return!!r(this,\"string\"==typeof e&&we.test(e)?pe(e):e||[],!1).length}});var Ee,Ne=/^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,ke=pe.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||Ee,\"string\"==typeof e){if(r=\"<\"===e.charAt(0)&&\">\"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:Ne.exec(e),!r||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof pe?t[0]:t,pe.merge(this,pe.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:re,!0)),Te.test(r[1])&&pe.isPlainObject(t))for(r in t)pe.isFunction(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}if(i=re.getElementById(r[2]),i&&i.parentNode){if(i.id!==r[2])return Ee.find(e);this.length=1,this[0]=i}return this.context=re,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):pe.isFunction(e)?\"undefined\"!=typeof n.ready?n.ready(e):e(pe):(void 0!==e.selector&&(this.selector=e.selector,this.context=e.context),pe.makeArray(e,this))};ke.prototype=pe.fn,Ee=pe(re);var Se=/^(?:parents|prev(?:Until|All))/,Ae={children:!0,contents:!0,next:!0,prev:!0};pe.fn.extend({has:function(e){var t,n=pe(e,this),r=n.length;return this.filter(function(){for(t=0;t<r;t++)if(pe.contains(this,n[t]))return!0})},closest:function(e,t){for(var n,r=0,i=this.length,o=[],a=we.test(e)||\"string\"!=typeof e?pe(e,t||this.context):0;r<i;r++)for(n=this[r];n&&n!==t;n=n.parentNode)if(n.nodeType<11&&(a?a.index(n)>-1:1===n.nodeType&&pe.find.matchesSelector(n,e))){o.push(n);break}return this.pushStack(o.length>1?pe.uniqueSort(o):o)},index:function(e){return e?\"string\"==typeof e?pe.inArray(this[0],pe(e)):pe.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){return this.pushStack(pe.uniqueSort(pe.merge(this.get(),pe(e,t))))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),pe.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return xe(e,\"parentNode\")},parentsUntil:function(e,t,n){return xe(e,\"parentNode\",n)},next:function(e){return i(e,\"nextSibling\")},prev:function(e){return i(e,\"previousSibling\")},nextAll:function(e){return xe(e,\"nextSibling\")},prevAll:function(e){return xe(e,\"previousSibling\")},nextUntil:function(e,t,n){return xe(e,\"nextSibling\",n)},prevUntil:function(e,t,n){return xe(e,\"previousSibling\",n)},siblings:function(e){return be((e.parentNode||{}).firstChild,e)},children:function(e){return be(e.firstChild)},contents:function(e){return pe.nodeName(e,\"iframe\")?e.contentDocument||e.contentWindow.document:pe.merge([],e.childNodes)}},function(e,t){pe.fn[e]=function(n,r){var i=pe.map(this,t,n);return\"Until\"!==e.slice(-5)&&(r=n),r&&\"string\"==typeof r&&(i=pe.filter(r,i)),this.length>1&&(Ae[e]||(i=pe.uniqueSort(i)),Se.test(e)&&(i=i.reverse())),this.pushStack(i)}});var De=/\\S+/g;pe.Callbacks=function(e){e=\"string\"==typeof e?o(e):pe.extend({},e);var t,n,r,i,a=[],s=[],u=-1,l=function(){for(i=e.once,r=t=!0;s.length;u=-1)for(n=s.shift();++u<a.length;)a[u].apply(n[0],n[1])===!1&&e.stopOnFalse&&(u=a.length,n=!1);e.memory||(n=!1),t=!1,i&&(a=n?[]:\"\")},c={add:function(){return a&&(n&&!t&&(u=a.length-1,s.push(n)),function r(t){pe.each(t,function(t,n){pe.isFunction(n)?e.unique&&c.has(n)||a.push(n):n&&n.length&&\"string\"!==pe.type(n)&&r(n)})}(arguments),n&&!t&&l()),this},remove:function(){return pe.each(arguments,function(e,t){for(var n;(n=pe.inArray(t,a,n))>-1;)a.splice(n,1),n<=u&&u--}),this},has:function(e){return e?pe.inArray(e,a)>-1:a.length>0},empty:function(){return a&&(a=[]),this},disable:function(){return i=s=[],a=n=\"\",this},disabled:function(){return!a},lock:function(){return i=!0,n||c.disable(),this},locked:function(){return!!i},fireWith:function(e,n){return i||(n=n||[],n=[e,n.slice?n.slice():n],s.push(n),t||l()),this},fire:function(){return c.fireWith(this,arguments),this},fired:function(){return!!r}};return c},pe.extend({Deferred:function(e){var t=[[\"resolve\",\"done\",pe.Callbacks(\"once memory\"),\"resolved\"],[\"reject\",\"fail\",pe.Callbacks(\"once memory\"),\"rejected\"],[\"notify\",\"progress\",pe.Callbacks(\"memory\")]],n=\"pending\",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return pe.Deferred(function(n){pe.each(t,function(t,o){var a=pe.isFunction(e[t])&&e[t];i[o[1]](function(){var e=a&&a.apply(this,arguments);e&&pe.isFunction(e.promise)?e.promise().progress(n.notify).done(n.resolve).fail(n.reject):n[o[0]+\"With\"](this===r?n.promise():this,a?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?pe.extend(e,r):r}},i={};return r.pipe=r.then,pe.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+\"With\"](this===i?r:this,arguments),this},i[o[0]+\"With\"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t,n,r,i=0,o=ie.call(arguments),a=o.length,s=1!==a||e&&pe.isFunction(e.promise)?a:0,u=1===s?e:pe.Deferred(),l=function(e,n,r){return function(i){n[e]=this,r[e]=arguments.length>1?ie.call(arguments):i,r===t?u.notifyWith(n,r):--s||u.resolveWith(n,r)}};if(a>1)for(t=new Array(a),n=new Array(a),r=new Array(a);i<a;i++)o[i]&&pe.isFunction(o[i].promise)?o[i].promise().progress(l(i,n,t)).done(l(i,r,o)).fail(u.reject):--s;return s||u.resolveWith(r,o),u.promise()}});var je;pe.fn.ready=function(e){return pe.ready.promise().done(e),this},pe.extend({isReady:!1,readyWait:1,holdReady:function(e){e?pe.readyWait++:pe.ready(!0)},ready:function(e){(e===!0?--pe.readyWait:pe.isReady)||(pe.isReady=!0,e!==!0&&--pe.readyWait>0||(je.resolveWith(re,[pe]),pe.fn.triggerHandler&&(pe(re).triggerHandler(\"ready\"),pe(re).off(\"ready\"))))}}),pe.ready.promise=function(t){if(!je)if(je=pe.Deferred(),\"complete\"===re.readyState||\"loading\"!==re.readyState&&!re.documentElement.doScroll)e.setTimeout(pe.ready);else if(re.addEventListener)re.addEventListener(\"DOMContentLoaded\",s),e.addEventListener(\"load\",s);else{re.attachEvent(\"onreadystatechange\",s),e.attachEvent(\"onload\",s);var n=!1;try{n=null==e.frameElement&&re.documentElement}catch(r){}n&&n.doScroll&&!function i(){if(!pe.isReady){try{n.doScroll(\"left\")}catch(t){return e.setTimeout(i,50)}a(),pe.ready()}}()}return je.promise(t)},pe.ready.promise();var Le;for(Le in pe(fe))break;fe.ownFirst=\"0\"===Le,fe.inlineBlockNeedsLayout=!1,pe(function(){var e,t,n,r;n=re.getElementsByTagName(\"body\")[0],n&&n.style&&(t=re.createElement(\"div\"),r=re.createElement(\"div\"),r.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",n.appendChild(r).appendChild(t),\"undefined\"!=typeof t.style.zoom&&(t.style.cssText=\"display:inline;margin:0;border:0;padding:1px;width:1px;zoom:1\",fe.inlineBlockNeedsLayout=e=3===t.offsetWidth,e&&(n.style.zoom=1)),n.removeChild(r))}),function(){var e=re.createElement(\"div\");fe.deleteExpando=!0;try{delete e.test}catch(t){fe.deleteExpando=!1}e=null}();var He=function(e){var t=pe.noData[(e.nodeName+\" \").toLowerCase()],n=+e.nodeType||1;return(1===n||9===n)&&(!t||t!==!0&&e.getAttribute(\"classid\")===t)},qe=/^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,_e=/([A-Z])/g;pe.extend({cache:{},noData:{\"applet \":!0,\"embed \":!0,\"object \":\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"},hasData:function(e){return e=e.nodeType?pe.cache[e[pe.expando]]:e[pe.expando],!!e&&!l(e)},data:function(e,t,n){return c(e,t,n)},removeData:function(e,t){return f(e,t)},_data:function(e,t,n){return c(e,t,n,!0)},_removeData:function(e,t){return f(e,t,!0)}}),pe.fn.extend({data:function(e,t){var n,r,i,o=this[0],a=o&&o.attributes;if(void 0===e){if(this.length&&(i=pe.data(o),1===o.nodeType&&!pe._data(o,\"parsedAttrs\"))){for(n=a.length;n--;)a[n]&&(r=a[n].name,0===r.indexOf(\"data-\")&&(r=pe.camelCase(r.slice(5)),u(o,r,i[r])));pe._data(o,\"parsedAttrs\",!0)}return i}return\"object\"==typeof e?this.each(function(){pe.data(this,e)}):arguments.length>1?this.each(function(){pe.data(this,e,t)}):o?u(o,e,pe.data(o,e)):void 0},removeData:function(e){return this.each(function(){pe.removeData(this,e)})}}),pe.extend({queue:function(e,t,n){var r;if(e)return t=(t||\"fx\")+\"queue\",r=pe._data(e,t),n&&(!r||pe.isArray(n)?r=pe._data(e,t,pe.makeArray(n)):r.push(n)),r||[]},dequeue:function(e,t){t=t||\"fx\";var n=pe.queue(e,t),r=n.length,i=n.shift(),o=pe._queueHooks(e,t),a=function(){pe.dequeue(e,t)};\"inprogress\"===i&&(i=n.shift(),r--),i&&(\"fx\"===t&&n.unshift(\"inprogress\"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+\"queueHooks\";return pe._data(e,n)||pe._data(e,n,{empty:pe.Callbacks(\"once memory\").add(function(){pe._removeData(e,t+\"queue\"),pe._removeData(e,n)})})}}),pe.fn.extend({queue:function(e,t){var n=2;return\"string\"!=typeof e&&(t=e,e=\"fx\",n--),arguments.length<n?pe.queue(this[0],e):void 0===t?this:this.each(function(){var n=pe.queue(this,e,t);pe._queueHooks(this,e),\"fx\"===e&&\"inprogress\"!==n[0]&&pe.dequeue(this,e)})},dequeue:function(e){return this.each(function(){pe.dequeue(this,e)})},clearQueue:function(e){return this.queue(e||\"fx\",[])},promise:function(e,t){var n,r=1,i=pe.Deferred(),o=this,a=this.length,s=function(){--r||i.resolveWith(o,[o])};for(\"string\"!=typeof e&&(t=e,e=void 0),e=e||\"fx\";a--;)n=pe._data(o[a],e+\"queueHooks\"),n&&n.empty&&(r++,n.empty.add(s));return s(),i.promise(t)}}),function(){var e;fe.shrinkWrapBlocks=function(){if(null!=e)return e;e=!1;var t,n,r;return n=re.getElementsByTagName(\"body\")[0],n&&n.style?(t=re.createElement(\"div\"),r=re.createElement(\"div\"),r.style.cssText=\"position:absolute;border:0;width:0;height:0;top:0;left:-9999px\",n.appendChild(r).appendChild(t),\"undefined\"!=typeof t.style.zoom&&(t.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1\",t.appendChild(re.createElement(\"div\")).style.width=\"5px\",e=3!==t.offsetWidth),n.removeChild(r),e):void 0}}();var Fe=/[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,Me=new RegExp(\"^(?:([+-])=|)(\"+Fe+\")([a-z%]*)$\",\"i\"),Oe=[\"Top\",\"Right\",\"Bottom\",\"Left\"],Re=function(e,t){return e=t||e,\"none\"===pe.css(e,\"display\")||!pe.contains(e.ownerDocument,e)},Pe=function(e,t,n,r,i,o,a){var s=0,u=e.length,l=null==n;if(\"object\"===pe.type(n)){i=!0;for(s in n)Pe(e,t,s,n[s],!0,o,a)}else if(void 0!==r&&(i=!0,pe.isFunction(r)||(a=!0),l&&(a?(t.call(e,r),t=null):(l=t,t=function(e,t,n){return l.call(pe(e),n)})),t))for(;s<u;s++)t(e[s],n,a?r:r.call(e[s],s,t(e[s],n)));return i?e:l?t.call(e):u?t(e[0],n):o},Be=/^(?:checkbox|radio)$/i,We=/<([\\w:-]+)/,Ie=/^$|\\/(?:java|ecma)script/i,$e=/^\\s+/,ze=\"abbr|article|aside|audio|bdi|canvas|data|datalist|details|dialog|figcaption|figure|footer|header|hgroup|main|mark|meter|nav|output|picture|progress|section|summary|template|time|video\";!function(){var e=re.createElement(\"div\"),t=re.createDocumentFragment(),n=re.createElement(\"input\");e.innerHTML=\"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",fe.leadingWhitespace=3===e.firstChild.nodeType,fe.tbody=!e.getElementsByTagName(\"tbody\").length,fe.htmlSerialize=!!e.getElementsByTagName(\"link\").length,fe.html5Clone=\"<:nav></:nav>\"!==re.createElement(\"nav\").cloneNode(!0).outerHTML,n.type=\"checkbox\",n.checked=!0,t.appendChild(n),fe.appendChecked=n.checked,e.innerHTML=\"<textarea>x</textarea>\",fe.noCloneChecked=!!e.cloneNode(!0).lastChild.defaultValue,t.appendChild(e),n=re.createElement(\"input\"),n.setAttribute(\"type\",\"radio\"),n.setAttribute(\"checked\",\"checked\"),n.setAttribute(\"name\",\"t\"),e.appendChild(n),fe.checkClone=e.cloneNode(!0).cloneNode(!0).lastChild.checked,fe.noCloneEvent=!!e.addEventListener,e[pe.expando]=1,fe.attributes=!e.getAttribute(pe.expando)}();var Xe={option:[1,\"<select multiple='multiple'>\",\"</select>\"],legend:[1,\"<fieldset>\",\"</fieldset>\"],area:[1,\"<map>\",\"</map>\"],param:[1,\"<object>\",\"</object>\"],thead:[1,\"<table>\",\"</table>\"],tr:[2,\"<table><tbody>\",\"</tbody></table>\"],col:[2,\"<table><tbody></tbody><colgroup>\",\"</colgroup></table>\"],td:[3,\"<table><tbody><tr>\",\"</tr></tbody></table>\"],_default:fe.htmlSerialize?[0,\"\",\"\"]:[1,\"X<div>\",\"</div>\"]};Xe.optgroup=Xe.option,Xe.tbody=Xe.tfoot=Xe.colgroup=Xe.caption=Xe.thead,Xe.th=Xe.td;var Ue=/<|&#?\\w+;/,Ve=/<tbody/i;!function(){var t,n,r=re.createElement(\"div\");for(t in{submit:!0,change:!0,focusin:!0})n=\"on\"+t,(fe[t]=n in e)||(r.setAttribute(n,\"t\"),fe[t]=r.attributes[n].expando===!1);r=null}();var Ye=/^(?:input|select|textarea)$/i,Je=/^key/,Ge=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ke=/^(?:focusinfocus|focusoutblur)$/,Qe=/^([^.]*)(?:\\.(.+)|)/;pe.event={global:{},add:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,m=pe._data(e);if(m){for(n.handler&&(u=n,n=u.handler,i=u.selector),n.guid||(n.guid=pe.guid++),(a=m.events)||(a=m.events={}),(c=m.handle)||(c=m.handle=function(e){return\"undefined\"==typeof pe||e&&pe.event.triggered===e.type?void 0:pe.event.dispatch.apply(c.elem,arguments)},c.elem=e),t=(t||\"\").match(De)||[\"\"],s=t.length;s--;)o=Qe.exec(t[s])||[],p=g=o[1],h=(o[2]||\"\").split(\".\").sort(),p&&(l=pe.event.special[p]||{},p=(i?l.delegateType:l.bindType)||p,l=pe.event.special[p]||{},f=pe.extend({type:p,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&pe.expr.match.needsContext.test(i),namespace:h.join(\".\")},u),(d=a[p])||(d=a[p]=[],d.delegateCount=0,l.setup&&l.setup.call(e,r,h,c)!==!1||(e.addEventListener?e.addEventListener(p,c,!1):e.attachEvent&&e.attachEvent(\"on\"+p,c))),l.add&&(l.add.call(e,f),f.handler.guid||(f.handler.guid=n.guid)),i?d.splice(d.delegateCount++,0,f):d.push(f),pe.event.global[p]=!0);e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,d,p,h,g,m=pe.hasData(e)&&pe._data(e);if(m&&(c=m.events)){for(t=(t||\"\").match(De)||[\"\"],l=t.length;l--;)if(s=Qe.exec(t[l])||[],p=g=s[1],h=(s[2]||\"\").split(\".\").sort(),p){for(f=pe.event.special[p]||{},p=(r?f.delegateType:f.bindType)||p,d=c[p]||[],s=s[2]&&new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"),u=o=d.length;o--;)a=d[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&(\"**\"!==r||!a.selector)||(d.splice(o,1),a.selector&&d.delegateCount--,f.remove&&f.remove.call(e,a));u&&!d.length&&(f.teardown&&f.teardown.call(e,h,m.handle)!==!1||pe.removeEvent(e,p,m.handle),delete c[p])}else for(p in c)pe.event.remove(e,p+t[l],n,r,!0);pe.isEmptyObject(c)&&(delete m.handle,pe._removeData(e,\"events\"))}},trigger:function(t,n,r,i){var o,a,s,u,l,c,f,d=[r||re],p=ce.call(t,\"type\")?t.type:t,h=ce.call(t,\"namespace\")?t.namespace.split(\".\"):[];if(s=c=r=r||re,3!==r.nodeType&&8!==r.nodeType&&!Ke.test(p+pe.event.triggered)&&(p.indexOf(\".\")>-1&&(h=p.split(\".\"),p=h.shift(),h.sort()),a=p.indexOf(\":\")<0&&\"on\"+p,t=t[pe.expando]?t:new pe.Event(p,\"object\"==typeof t&&t),t.isTrigger=i?2:3,t.namespace=h.join(\".\"),t.rnamespace=t.namespace?new RegExp(\"(^|\\\\.)\"+h.join(\"\\\\.(?:.*\\\\.|)\")+\"(\\\\.|$)\"):null,t.result=void 0,t.target||(t.target=r),n=null==n?[t]:pe.makeArray(n,[t]),l=pe.event.special[p]||{},i||!l.trigger||l.trigger.apply(r,n)!==!1)){if(!i&&!l.noBubble&&!pe.isWindow(r)){for(u=l.delegateType||p,Ke.test(u+p)||(s=s.parentNode);s;s=s.parentNode)d.push(s),c=s;c===(r.ownerDocument||re)&&d.push(c.defaultView||c.parentWindow||e)}for(f=0;(s=d[f++])&&!t.isPropagationStopped();)t.type=f>1?u:l.bindType||p,o=(pe._data(s,\"events\")||{})[t.type]&&pe._data(s,\"handle\"),o&&o.apply(s,n),o=a&&s[a],o&&o.apply&&He(s)&&(t.result=o.apply(s,n),t.result===!1&&t.preventDefault());if(t.type=p,!i&&!t.isDefaultPrevented()&&(!l._default||l._default.apply(d.pop(),n)===!1)&&He(r)&&a&&r[p]&&!pe.isWindow(r)){c=r[a],c&&(r[a]=null),pe.event.triggered=p;try{r[p]()}catch(g){}pe.event.triggered=void 0,c&&(r[a]=c)}return t.result}},dispatch:function(e){e=pe.event.fix(e);var t,n,r,i,o,a=[],s=ie.call(arguments),u=(pe._data(this,\"events\")||{})[e.type]||[],l=pe.event.special[e.type]||{};if(s[0]=e,e.delegateTarget=this,!l.preDispatch||l.preDispatch.call(this,e)!==!1){for(a=pe.event.handlers.call(this,e,u),t=0;(i=a[t++])&&!e.isPropagationStopped();)for(e.currentTarget=i.elem,n=0;(o=i.handlers[n++])&&!e.isImmediatePropagationStopped();)e.rnamespace&&!e.rnamespace.test(o.namespace)||(e.handleObj=o,e.data=o.data,r=((pe.event.special[o.origType]||{}).handle||o.handler).apply(i.elem,s),void 0!==r&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()));return l.postDispatch&&l.postDispatch.call(this,e),e.result}},handlers:function(e,t){var n,r,i,o,a=[],s=t.delegateCount,u=e.target;if(s&&u.nodeType&&(\"click\"!==e.type||isNaN(e.button)||e.button<1))for(;u!=this;u=u.parentNode||this)if(1===u.nodeType&&(u.disabled!==!0||\"click\"!==e.type)){for(r=[],n=0;n<s;n++)o=t[n],i=o.selector+\" \",void 0===r[i]&&(r[i]=o.needsContext?pe(i,this).index(u)>-1:pe.find(i,this,null,[u]).length),r[i]&&r.push(o);r.length&&a.push({elem:u,handlers:r})}return s<t.length&&a.push({elem:this,handlers:t.slice(s)}),a},fix:function(e){if(e[pe.expando])return e;var t,n,r,i=e.type,o=e,a=this.fixHooks[i];for(a||(this.fixHooks[i]=a=Ge.test(i)?this.mouseHooks:Je.test(i)?this.keyHooks:{}),r=a.props?this.props.concat(a.props):this.props,e=new pe.Event(o),t=r.length;t--;)n=r[t],e[n]=o[n];return e.target||(e.target=o.srcElement||re),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,a.filter?a.filter(e,o):e},props:\"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),fixHooks:{},keyHooks:{props:\"char charCode key keyCode\".split(\" \"),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:\"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),filter:function(e,t){var n,r,i,o=t.button,a=t.fromElement;return null==e.pageX&&null!=t.clientX&&(r=e.target.ownerDocument||re,i=r.documentElement,n=r.body,e.pageX=t.clientX+(i&&i.scrollLeft||n&&n.scrollLeft||0)-(i&&i.clientLeft||n&&n.clientLeft||0),e.pageY=t.clientY+(i&&i.scrollTop||n&&n.scrollTop||0)-(i&&i.clientTop||n&&n.clientTop||0)),!e.relatedTarget&&a&&(e.relatedTarget=a===e.target?t.toElement:a),e.which||void 0===o||(e.which=1&o?1:2&o?3:4&o?2:0),e}},special:{load:{noBubble:!0},focus:{trigger:function(){if(this!==b()&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:\"focusin\"},blur:{trigger:function(){if(this===b()&&this.blur)return this.blur(),!1},delegateType:\"focusout\"},click:{trigger:function(){if(pe.nodeName(this,\"input\")&&\"checkbox\"===this.type&&this.click)return this.click(),!1},_default:function(e){return pe.nodeName(e.target,\"a\")}},beforeunload:{postDispatch:function(e){void 0!==e.result&&e.originalEvent&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n){var r=pe.extend(new pe.Event,n,{type:e,isSimulated:!0});pe.event.trigger(r,null,t),r.isDefaultPrevented()&&n.preventDefault()}},pe.removeEvent=re.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n)}:function(e,t,n){var r=\"on\"+t;e.detachEvent&&(\"undefined\"==typeof e[r]&&(e[r]=null),e.detachEvent(r,n))},pe.Event=function(e,t){return this instanceof pe.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||void 0===e.defaultPrevented&&e.returnValue===!1?v:x):this.type=e,t&&pe.extend(this,t),this.timeStamp=e&&e.timeStamp||pe.now(),void(this[pe.expando]=!0)):new pe.Event(e,t)},pe.Event.prototype={constructor:pe.Event,isDefaultPrevented:x,isPropagationStopped:x,isImmediatePropagationStopped:x,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=v,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=v,e&&!this.isSimulated&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){var e=this.originalEvent;this.isImmediatePropagationStopped=v,e&&e.stopImmediatePropagation&&e.stopImmediatePropagation(),this.stopPropagation()}},pe.each({mouseenter:\"mouseover\",mouseleave:\"mouseout\",pointerenter:\"pointerover\",pointerleave:\"pointerout\"},function(e,t){pe.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;return i&&(i===r||pe.contains(r,i))||(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),fe.submit||(pe.event.special.submit={setup:function(){return!pe.nodeName(this,\"form\")&&void pe.event.add(this,\"click._submit keypress._submit\",function(e){var t=e.target,n=pe.nodeName(t,\"input\")||pe.nodeName(t,\"button\")?pe.prop(t,\"form\"):void 0;n&&!pe._data(n,\"submit\")&&(pe.event.add(n,\"submit._submit\",function(e){e._submitBubble=!0}),pe._data(n,\"submit\",!0))})},postDispatch:function(e){e._submitBubble&&(delete e._submitBubble,this.parentNode&&!e.isTrigger&&pe.event.simulate(\"submit\",this.parentNode,e))},teardown:function(){return!pe.nodeName(this,\"form\")&&void pe.event.remove(this,\"._submit\")}}),fe.change||(pe.event.special.change={setup:function(){return Ye.test(this.nodeName)?(\"checkbox\"!==this.type&&\"radio\"!==this.type||(pe.event.add(this,\"propertychange._change\",function(e){\"checked\"===e.originalEvent.propertyName&&(this._justChanged=!0)}),pe.event.add(this,\"click._change\",function(e){this._justChanged&&!e.isTrigger&&(this._justChanged=!1),pe.event.simulate(\"change\",this,e)})),!1):void pe.event.add(this,\"beforeactivate._change\",function(e){var t=e.target;Ye.test(t.nodeName)&&!pe._data(t,\"change\")&&(pe.event.add(t,\"change._change\",function(e){!this.parentNode||e.isSimulated||e.isTrigger||pe.event.simulate(\"change\",this.parentNode,e)}),pe._data(t,\"change\",!0))})},handle:function(e){var t=e.target;if(this!==t||e.isSimulated||e.isTrigger||\"radio\"!==t.type&&\"checkbox\"!==t.type)return e.handleObj.handler.apply(this,arguments)},teardown:function(){return pe.event.remove(this,\"._change\"),!Ye.test(this.nodeName)}}),fe.focusin||pe.each({focus:\"focusin\",blur:\"focusout\"},function(e,t){var n=function(e){pe.event.simulate(t,e.target,pe.event.fix(e))};pe.event.special[t]={setup:function(){var r=this.ownerDocument||this,i=pe._data(r,t);i||r.addEventListener(e,n,!0),pe._data(r,t,(i||0)+1)},teardown:function(){var r=this.ownerDocument||this,i=pe._data(r,t)-1;i?pe._data(r,t,i):(r.removeEventListener(e,n,!0),pe._removeData(r,t))}}}),pe.fn.extend({on:function(e,t,n,r){return w(this,e,t,n,r)},one:function(e,t,n,r){return w(this,e,t,n,r,1)},off:function(e,t,n){var r,i;if(e&&e.preventDefault&&e.handleObj)return r=e.handleObj,pe(e.delegateTarget).off(r.namespace?r.origType+\".\"+r.namespace:r.origType,r.selector,r.handler),this;if(\"object\"==typeof e){for(i in e)this.off(i,t,e[i]);return this}return t!==!1&&\"function\"!=typeof t||(n=t,t=void 0),n===!1&&(n=x),this.each(function(){pe.event.remove(this,e,n,t)})},trigger:function(e,t){return this.each(function(){pe.event.trigger(e,t,this)})},triggerHandler:function(e,t){var n=this[0];if(n)return pe.event.trigger(e,t,n,!0)}});var Ze=/ jQuery\\d+=\"(?:null|\\d+)\"/g,et=new RegExp(\"<(?:\"+ze+\")[\\\\s/>]\",\"i\"),tt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:-]+)[^>]*)\\/>/gi,nt=/<script|<style|<link/i,rt=/checked\\s*(?:[^=]|=\\s*.checked.)/i,it=/^true\\/(.*)/,ot=/^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,at=p(re),st=at.appendChild(re.createElement(\"div\"));pe.extend({htmlPrefilter:function(e){return e.replace(tt,\"<$1></$2>\")},clone:function(e,t,n){var r,i,o,a,s,u=pe.contains(e.ownerDocument,e);if(fe.html5Clone||pe.isXMLDoc(e)||!et.test(\"<\"+e.nodeName+\">\")?o=e.cloneNode(!0):(st.innerHTML=e.outerHTML,st.removeChild(o=st.firstChild)),!(fe.noCloneEvent&&fe.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||pe.isXMLDoc(e)))for(r=h(o),s=h(e),a=0;null!=(i=s[a]);++a)r[a]&&k(i,r[a]);if(t)if(n)for(s=s||h(e),r=r||h(o),a=0;null!=(i=s[a]);a++)N(i,r[a]);else N(e,o);return r=h(o,\"script\"),r.length>0&&g(r,!u&&h(e,\"script\")),r=s=i=null,o},cleanData:function(e,t){for(var n,r,i,o,a=0,s=pe.expando,u=pe.cache,l=fe.attributes,c=pe.event.special;null!=(n=e[a]);a++)if((t||He(n))&&(i=n[s],o=i&&u[i])){if(o.events)for(r in o.events)c[r]?pe.event.remove(n,r):pe.removeEvent(n,r,o.handle);u[i]&&(delete u[i],l||\"undefined\"==typeof n.removeAttribute?n[s]=void 0:n.removeAttribute(s),ne.push(i))}}}),pe.fn.extend({domManip:S,detach:function(e){return A(this,e,!0)},remove:function(e){return A(this,e)},text:function(e){return Pe(this,function(e){return void 0===e?pe.text(this):this.empty().append((this[0]&&this[0].ownerDocument||re).createTextNode(e))},null,e,arguments.length)},append:function(){return S(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=T(this,e);t.appendChild(e)}})},prepend:function(){return S(this,arguments,function(e){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var t=T(this,e);t.insertBefore(e,t.firstChild)}})},before:function(){return S(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return S(this,arguments,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},empty:function(){for(var e,t=0;null!=(e=this[t]);t++){for(1===e.nodeType&&pe.cleanData(h(e,!1));e.firstChild;)e.removeChild(e.firstChild);e.options&&pe.nodeName(e,\"select\")&&(e.options.length=0)}return this},clone:function(e,t){return e=null!=e&&e,t=null==t?e:t,this.map(function(){return pe.clone(this,e,t)})},html:function(e){return Pe(this,function(e){var t=this[0]||{},n=0,r=this.length;if(void 0===e)return 1===t.nodeType?t.innerHTML.replace(Ze,\"\"):void 0;if(\"string\"==typeof e&&!nt.test(e)&&(fe.htmlSerialize||!et.test(e))&&(fe.leadingWhitespace||!$e.test(e))&&!Xe[(We.exec(e)||[\"\",\"\"])[1].toLowerCase()]){e=pe.htmlPrefilter(e);try{for(;n<r;n++)t=this[n]||{},1===t.nodeType&&(pe.cleanData(h(t,!1)),t.innerHTML=e);t=0}catch(i){}}t&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(){var e=[];return S(this,arguments,function(t){var n=this.parentNode;pe.inArray(this,e)<0&&(pe.cleanData(h(this)),\nn&&n.replaceChild(t,this))},e)}}),pe.each({appendTo:\"append\",prependTo:\"prepend\",insertBefore:\"before\",insertAfter:\"after\",replaceAll:\"replaceWith\"},function(e,t){pe.fn[e]=function(e){for(var n,r=0,i=[],o=pe(e),a=o.length-1;r<=a;r++)n=r===a?this:this.clone(!0),pe(o[r])[t](n),ae.apply(i,n.get());return this.pushStack(i)}});var ut,lt={HTML:\"block\",BODY:\"block\"},ct=/^margin/,ft=new RegExp(\"^(\"+Fe+\")(?!px)[a-z%]+$\",\"i\"),dt=function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i},pt=re.documentElement;!function(){function t(){var t,c,f=re.documentElement;f.appendChild(u),l.style.cssText=\"-webkit-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%\",n=i=s=!1,r=a=!0,e.getComputedStyle&&(c=e.getComputedStyle(l),n=\"1%\"!==(c||{}).top,s=\"2px\"===(c||{}).marginLeft,i=\"4px\"===(c||{width:\"4px\"}).width,l.style.marginRight=\"50%\",r=\"4px\"===(c||{marginRight:\"4px\"}).marginRight,t=l.appendChild(re.createElement(\"div\")),t.style.cssText=l.style.cssText=\"-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0\",t.style.marginRight=t.style.width=\"0\",l.style.width=\"1px\",a=!parseFloat((e.getComputedStyle(t)||{}).marginRight),l.removeChild(t)),l.style.display=\"none\",o=0===l.getClientRects().length,o&&(l.style.display=\"\",l.innerHTML=\"<table><tr><td></td><td>t</td></tr></table>\",t=l.getElementsByTagName(\"td\"),t[0].style.cssText=\"margin:0;border:0;padding:0;display:none\",o=0===t[0].offsetHeight,o&&(t[0].style.display=\"\",t[1].style.display=\"none\",o=0===t[0].offsetHeight)),f.removeChild(u)}var n,r,i,o,a,s,u=re.createElement(\"div\"),l=re.createElement(\"div\");l.style&&(l.style.cssText=\"float:left;opacity:.5\",fe.opacity=\"0.5\"===l.style.opacity,fe.cssFloat=!!l.style.cssFloat,l.style.backgroundClip=\"content-box\",l.cloneNode(!0).style.backgroundClip=\"\",fe.clearCloneStyle=\"content-box\"===l.style.backgroundClip,u=re.createElement(\"div\"),u.style.cssText=\"border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute\",l.innerHTML=\"\",u.appendChild(l),fe.boxSizing=\"\"===l.style.boxSizing||\"\"===l.style.MozBoxSizing||\"\"===l.style.WebkitBoxSizing,pe.extend(fe,{reliableHiddenOffsets:function(){return null==n&&t(),o},boxSizingReliable:function(){return null==n&&t(),i},pixelMarginRight:function(){return null==n&&t(),r},pixelPosition:function(){return null==n&&t(),n},reliableMarginRight:function(){return null==n&&t(),a},reliableMarginLeft:function(){return null==n&&t(),s}}))}();var ht,gt,mt=/^(top|right|bottom|left)$/;e.getComputedStyle?(ht=function(t){var n=t.ownerDocument.defaultView;return n&&n.opener||(n=e),n.getComputedStyle(t)},gt=function(e,t,n){var r,i,o,a,s=e.style;return n=n||ht(e),a=n?n.getPropertyValue(t)||n[t]:void 0,\"\"!==a&&void 0!==a||pe.contains(e.ownerDocument,e)||(a=pe.style(e,t)),n&&!fe.pixelMarginRight()&&ft.test(a)&&ct.test(t)&&(r=s.width,i=s.minWidth,o=s.maxWidth,s.minWidth=s.maxWidth=s.width=a,a=n.width,s.width=r,s.minWidth=i,s.maxWidth=o),void 0===a?a:a+\"\"}):pt.currentStyle&&(ht=function(e){return e.currentStyle},gt=function(e,t,n){var r,i,o,a,s=e.style;return n=n||ht(e),a=n?n[t]:void 0,null==a&&s&&s[t]&&(a=s[t]),ft.test(a)&&!mt.test(t)&&(r=s.left,i=e.runtimeStyle,o=i&&i.left,o&&(i.left=e.currentStyle.left),s.left=\"fontSize\"===t?\"1em\":a,a=s.pixelLeft+\"px\",s.left=r,o&&(i.left=o)),void 0===a?a:a+\"\"||\"auto\"});var yt=/alpha\\([^)]*\\)/i,vt=/opacity\\s*=\\s*([^)]*)/i,xt=/^(none|table(?!-c[ea]).+)/,bt=new RegExp(\"^(\"+Fe+\")(.*)$\",\"i\"),wt={position:\"absolute\",visibility:\"hidden\",display:\"block\"},Tt={letterSpacing:\"0\",fontWeight:\"400\"},Ct=[\"Webkit\",\"O\",\"Moz\",\"ms\"],Et=re.createElement(\"div\").style;pe.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=gt(e,\"opacity\");return\"\"===n?\"1\":n}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{\"float\":fe.cssFloat?\"cssFloat\":\"styleFloat\"},style:function(e,t,n,r){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var i,o,a,s=pe.camelCase(t),u=e.style;if(t=pe.cssProps[s]||(pe.cssProps[s]=H(s)||s),a=pe.cssHooks[t]||pe.cssHooks[s],void 0===n)return a&&\"get\"in a&&void 0!==(i=a.get(e,!1,r))?i:u[t];if(o=typeof n,\"string\"===o&&(i=Me.exec(n))&&i[1]&&(n=d(e,t,i),o=\"number\"),null!=n&&n===n&&(\"number\"===o&&(n+=i&&i[3]||(pe.cssNumber[s]?\"\":\"px\")),fe.clearCloneStyle||\"\"!==n||0!==t.indexOf(\"background\")||(u[t]=\"inherit\"),!(a&&\"set\"in a&&void 0===(n=a.set(e,n,r)))))try{u[t]=n}catch(l){}}},css:function(e,t,n,r){var i,o,a,s=pe.camelCase(t);return t=pe.cssProps[s]||(pe.cssProps[s]=H(s)||s),a=pe.cssHooks[t]||pe.cssHooks[s],a&&\"get\"in a&&(o=a.get(e,!0,n)),void 0===o&&(o=gt(e,t,r)),\"normal\"===o&&t in Tt&&(o=Tt[t]),\"\"===n||n?(i=parseFloat(o),n===!0||isFinite(i)?i||0:o):o}}),pe.each([\"height\",\"width\"],function(e,t){pe.cssHooks[t]={get:function(e,n,r){if(n)return xt.test(pe.css(e,\"display\"))&&0===e.offsetWidth?dt(e,wt,function(){return M(e,t,r)}):M(e,t,r)},set:function(e,n,r){var i=r&&ht(e);return _(e,n,r?F(e,t,r,fe.boxSizing&&\"border-box\"===pe.css(e,\"boxSizing\",!1,i),i):0)}}}),fe.opacity||(pe.cssHooks.opacity={get:function(e,t){return vt.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||\"\")?.01*parseFloat(RegExp.$1)+\"\":t?\"1\":\"\"},set:function(e,t){var n=e.style,r=e.currentStyle,i=pe.isNumeric(t)?\"alpha(opacity=\"+100*t+\")\":\"\",o=r&&r.filter||n.filter||\"\";n.zoom=1,(t>=1||\"\"===t)&&\"\"===pe.trim(o.replace(yt,\"\"))&&n.removeAttribute&&(n.removeAttribute(\"filter\"),\"\"===t||r&&!r.filter)||(n.filter=yt.test(o)?o.replace(yt,i):o+\" \"+i)}}),pe.cssHooks.marginRight=L(fe.reliableMarginRight,function(e,t){if(t)return dt(e,{display:\"inline-block\"},gt,[e,\"marginRight\"])}),pe.cssHooks.marginLeft=L(fe.reliableMarginLeft,function(e,t){if(t)return(parseFloat(gt(e,\"marginLeft\"))||(pe.contains(e.ownerDocument,e)?e.getBoundingClientRect().left-dt(e,{marginLeft:0},function(){return e.getBoundingClientRect().left}):0))+\"px\"}),pe.each({margin:\"\",padding:\"\",border:\"Width\"},function(e,t){pe.cssHooks[e+t]={expand:function(n){for(var r=0,i={},o=\"string\"==typeof n?n.split(\" \"):[n];r<4;r++)i[e+Oe[r]+t]=o[r]||o[r-2]||o[0];return i}},ct.test(e)||(pe.cssHooks[e+t].set=_)}),pe.fn.extend({css:function(e,t){return Pe(this,function(e,t,n){var r,i,o={},a=0;if(pe.isArray(t)){for(r=ht(e),i=t.length;a<i;a++)o[t[a]]=pe.css(e,t[a],!1,r);return o}return void 0!==n?pe.style(e,t,n):pe.css(e,t)},e,t,arguments.length>1)},show:function(){return q(this,!0)},hide:function(){return q(this)},toggle:function(e){return\"boolean\"==typeof e?e?this.show():this.hide():this.each(function(){Re(this)?pe(this).show():pe(this).hide()})}}),pe.Tween=O,O.prototype={constructor:O,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||pe.easing._default,this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(pe.cssNumber[n]?\"\":\"px\")},cur:function(){var e=O.propHooks[this.prop];return e&&e.get?e.get(this):O.propHooks._default.get(this)},run:function(e){var t,n=O.propHooks[this.prop];return this.options.duration?this.pos=t=pe.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):this.pos=t=e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):O.propHooks._default.set(this),this}},O.prototype.init.prototype=O.prototype,O.propHooks={_default:{get:function(e){var t;return 1!==e.elem.nodeType||null!=e.elem[e.prop]&&null==e.elem.style[e.prop]?e.elem[e.prop]:(t=pe.css(e.elem,e.prop,\"\"),t&&\"auto\"!==t?t:0)},set:function(e){pe.fx.step[e.prop]?pe.fx.step[e.prop](e):1!==e.elem.nodeType||null==e.elem.style[pe.cssProps[e.prop]]&&!pe.cssHooks[e.prop]?e.elem[e.prop]=e.now:pe.style(e.elem,e.prop,e.now+e.unit)}}},O.propHooks.scrollTop=O.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},pe.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2},_default:\"swing\"},pe.fx=O.prototype.init,pe.fx.step={};var Nt,kt,St=/^(?:toggle|show|hide)$/,At=/queueHooks$/;pe.Animation=pe.extend($,{tweeners:{\"*\":[function(e,t){var n=this.createTween(e,t);return d(n.elem,e,Me.exec(t),n),n}]},tweener:function(e,t){pe.isFunction(e)?(t=e,e=[\"*\"]):e=e.match(De);for(var n,r=0,i=e.length;r<i;r++)n=e[r],$.tweeners[n]=$.tweeners[n]||[],$.tweeners[n].unshift(t)},prefilters:[W],prefilter:function(e,t){t?$.prefilters.unshift(e):$.prefilters.push(e)}}),pe.speed=function(e,t,n){var r=e&&\"object\"==typeof e?pe.extend({},e):{complete:n||!n&&t||pe.isFunction(e)&&e,duration:e,easing:n&&t||t&&!pe.isFunction(t)&&t};return r.duration=pe.fx.off?0:\"number\"==typeof r.duration?r.duration:r.duration in pe.fx.speeds?pe.fx.speeds[r.duration]:pe.fx.speeds._default,null!=r.queue&&r.queue!==!0||(r.queue=\"fx\"),r.old=r.complete,r.complete=function(){pe.isFunction(r.old)&&r.old.call(this),r.queue&&pe.dequeue(this,r.queue)},r},pe.fn.extend({fadeTo:function(e,t,n,r){return this.filter(Re).css(\"opacity\",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=pe.isEmptyObject(e),o=pe.speed(t,n,r),a=function(){var t=$(this,pe.extend({},e),o);(i||pe._data(this,\"finish\"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,t,n){var r=function(e){var t=e.stop;delete e.stop,t(n)};return\"string\"!=typeof e&&(n=t,t=e,e=void 0),t&&e!==!1&&this.queue(e||\"fx\",[]),this.each(function(){var t=!0,i=null!=e&&e+\"queueHooks\",o=pe.timers,a=pe._data(this);if(i)a[i]&&a[i].stop&&r(a[i]);else for(i in a)a[i]&&a[i].stop&&At.test(i)&&r(a[i]);for(i=o.length;i--;)o[i].elem!==this||null!=e&&o[i].queue!==e||(o[i].anim.stop(n),t=!1,o.splice(i,1));!t&&n||pe.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||\"fx\"),this.each(function(){var t,n=pe._data(this),r=n[e+\"queue\"],i=n[e+\"queueHooks\"],o=pe.timers,a=r?r.length:0;for(n.finish=!0,pe.queue(this,e,[]),i&&i.stop&&i.stop.call(this,!0),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;t<a;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}}),pe.each([\"toggle\",\"show\",\"hide\"],function(e,t){var n=pe.fn[t];pe.fn[t]=function(e,r,i){return null==e||\"boolean\"==typeof e?n.apply(this,arguments):this.animate(P(t,!0),e,r,i)}}),pe.each({slideDown:P(\"show\"),slideUp:P(\"hide\"),slideToggle:P(\"toggle\"),fadeIn:{opacity:\"show\"},fadeOut:{opacity:\"hide\"},fadeToggle:{opacity:\"toggle\"}},function(e,t){pe.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),pe.timers=[],pe.fx.tick=function(){var e,t=pe.timers,n=0;for(Nt=pe.now();n<t.length;n++)e=t[n],e()||t[n]!==e||t.splice(n--,1);t.length||pe.fx.stop(),Nt=void 0},pe.fx.timer=function(e){pe.timers.push(e),e()?pe.fx.start():pe.timers.pop()},pe.fx.interval=13,pe.fx.start=function(){kt||(kt=e.setInterval(pe.fx.tick,pe.fx.interval))},pe.fx.stop=function(){e.clearInterval(kt),kt=null},pe.fx.speeds={slow:600,fast:200,_default:400},pe.fn.delay=function(t,n){return t=pe.fx?pe.fx.speeds[t]||t:t,n=n||\"fx\",this.queue(n,function(n,r){var i=e.setTimeout(n,t);r.stop=function(){e.clearTimeout(i)}})},function(){var e,t=re.createElement(\"input\"),n=re.createElement(\"div\"),r=re.createElement(\"select\"),i=r.appendChild(re.createElement(\"option\"));n=re.createElement(\"div\"),n.setAttribute(\"className\",\"t\"),n.innerHTML=\"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\",e=n.getElementsByTagName(\"a\")[0],t.setAttribute(\"type\",\"checkbox\"),n.appendChild(t),e=n.getElementsByTagName(\"a\")[0],e.style.cssText=\"top:1px\",fe.getSetAttribute=\"t\"!==n.className,fe.style=/top/.test(e.getAttribute(\"style\")),fe.hrefNormalized=\"/a\"===e.getAttribute(\"href\"),fe.checkOn=!!t.value,fe.optSelected=i.selected,fe.enctype=!!re.createElement(\"form\").enctype,r.disabled=!0,fe.optDisabled=!i.disabled,t=re.createElement(\"input\"),t.setAttribute(\"value\",\"\"),fe.input=\"\"===t.getAttribute(\"value\"),t.value=\"t\",t.setAttribute(\"type\",\"radio\"),fe.radioValue=\"t\"===t.value}();var Dt=/\\r/g,jt=/[\\x20\\t\\r\\n\\f]+/g;pe.fn.extend({val:function(e){var t,n,r,i=this[0];{if(arguments.length)return r=pe.isFunction(e),this.each(function(n){var i;1===this.nodeType&&(i=r?e.call(this,n,pe(this).val()):e,null==i?i=\"\":\"number\"==typeof i?i+=\"\":pe.isArray(i)&&(i=pe.map(i,function(e){return null==e?\"\":e+\"\"})),t=pe.valHooks[this.type]||pe.valHooks[this.nodeName.toLowerCase()],t&&\"set\"in t&&void 0!==t.set(this,i,\"value\")||(this.value=i))});if(i)return t=pe.valHooks[i.type]||pe.valHooks[i.nodeName.toLowerCase()],t&&\"get\"in t&&void 0!==(n=t.get(i,\"value\"))?n:(n=i.value,\"string\"==typeof n?n.replace(Dt,\"\"):null==n?\"\":n)}}}),pe.extend({valHooks:{option:{get:function(e){var t=pe.find.attr(e,\"value\");return null!=t?t:pe.trim(pe.text(e)).replace(jt,\" \")}},select:{get:function(e){for(var t,n,r=e.options,i=e.selectedIndex,o=\"select-one\"===e.type||i<0,a=o?null:[],s=o?i+1:r.length,u=i<0?s:o?i:0;u<s;u++)if(n=r[u],(n.selected||u===i)&&(fe.optDisabled?!n.disabled:null===n.getAttribute(\"disabled\"))&&(!n.parentNode.disabled||!pe.nodeName(n.parentNode,\"optgroup\"))){if(t=pe(n).val(),o)return t;a.push(t)}return a},set:function(e,t){for(var n,r,i=e.options,o=pe.makeArray(t),a=i.length;a--;)if(r=i[a],pe.inArray(pe.valHooks.option.get(r),o)>-1)try{r.selected=n=!0}catch(s){r.scrollHeight}else r.selected=!1;return n||(e.selectedIndex=-1),i}}}}),pe.each([\"radio\",\"checkbox\"],function(){pe.valHooks[this]={set:function(e,t){if(pe.isArray(t))return e.checked=pe.inArray(pe(e).val(),t)>-1}},fe.checkOn||(pe.valHooks[this].get=function(e){return null===e.getAttribute(\"value\")?\"on\":e.value})});var Lt,Ht,qt=pe.expr.attrHandle,_t=/^(?:checked|selected)$/i,Ft=fe.getSetAttribute,Mt=fe.input;pe.fn.extend({attr:function(e,t){return Pe(this,pe.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){pe.removeAttr(this,e)})}}),pe.extend({attr:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return\"undefined\"==typeof e.getAttribute?pe.prop(e,t,n):(1===o&&pe.isXMLDoc(e)||(t=t.toLowerCase(),i=pe.attrHooks[t]||(pe.expr.match.bool.test(t)?Ht:Lt)),void 0!==n?null===n?void pe.removeAttr(e,t):i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:(e.setAttribute(t,n+\"\"),n):i&&\"get\"in i&&null!==(r=i.get(e,t))?r:(r=pe.find.attr(e,t),null==r?void 0:r))},attrHooks:{type:{set:function(e,t){if(!fe.radioValue&&\"radio\"===t&&pe.nodeName(e,\"input\")){var n=e.value;return e.setAttribute(\"type\",t),n&&(e.value=n),t}}}},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(De);if(o&&1===e.nodeType)for(;n=o[i++];)r=pe.propFix[n]||n,pe.expr.match.bool.test(n)?Mt&&Ft||!_t.test(n)?e[r]=!1:e[pe.camelCase(\"default-\"+n)]=e[r]=!1:pe.attr(e,n,\"\"),e.removeAttribute(Ft?n:r)}}),Ht={set:function(e,t,n){return t===!1?pe.removeAttr(e,n):Mt&&Ft||!_t.test(n)?e.setAttribute(!Ft&&pe.propFix[n]||n,n):e[pe.camelCase(\"default-\"+n)]=e[n]=!0,n}},pe.each(pe.expr.match.bool.source.match(/\\w+/g),function(e,t){var n=qt[t]||pe.find.attr;Mt&&Ft||!_t.test(t)?qt[t]=function(e,t,r){var i,o;return r||(o=qt[t],qt[t]=i,i=null!=n(e,t,r)?t.toLowerCase():null,qt[t]=o),i}:qt[t]=function(e,t,n){if(!n)return e[pe.camelCase(\"default-\"+t)]?t.toLowerCase():null}}),Mt&&Ft||(pe.attrHooks.value={set:function(e,t,n){return pe.nodeName(e,\"input\")?void(e.defaultValue=t):Lt&&Lt.set(e,t,n)}}),Ft||(Lt={set:function(e,t,n){var r=e.getAttributeNode(n);if(r||e.setAttributeNode(r=e.ownerDocument.createAttribute(n)),r.value=t+=\"\",\"value\"===n||t===e.getAttribute(n))return t}},qt.id=qt.name=qt.coords=function(e,t,n){var r;if(!n)return(r=e.getAttributeNode(t))&&\"\"!==r.value?r.value:null},pe.valHooks.button={get:function(e,t){var n=e.getAttributeNode(t);if(n&&n.specified)return n.value},set:Lt.set},pe.attrHooks.contenteditable={set:function(e,t,n){Lt.set(e,\"\"!==t&&t,n)}},pe.each([\"width\",\"height\"],function(e,t){pe.attrHooks[t]={set:function(e,n){if(\"\"===n)return e.setAttribute(t,\"auto\"),n}}})),fe.style||(pe.attrHooks.style={get:function(e){return e.style.cssText||void 0},set:function(e,t){return e.style.cssText=t+\"\"}});var Ot=/^(?:input|select|textarea|button|object)$/i,Rt=/^(?:a|area)$/i;pe.fn.extend({prop:function(e,t){return Pe(this,pe.prop,e,t,arguments.length>1)},removeProp:function(e){return e=pe.propFix[e]||e,this.each(function(){try{this[e]=void 0,delete this[e]}catch(t){}})}}),pe.extend({prop:function(e,t,n){var r,i,o=e.nodeType;if(3!==o&&8!==o&&2!==o)return 1===o&&pe.isXMLDoc(e)||(t=pe.propFix[t]||t,i=pe.propHooks[t]),void 0!==n?i&&\"set\"in i&&void 0!==(r=i.set(e,n,t))?r:e[t]=n:i&&\"get\"in i&&null!==(r=i.get(e,t))?r:e[t]},propHooks:{tabIndex:{get:function(e){var t=pe.find.attr(e,\"tabindex\");return t?parseInt(t,10):Ot.test(e.nodeName)||Rt.test(e.nodeName)&&e.href?0:-1}}},propFix:{\"for\":\"htmlFor\",\"class\":\"className\"}}),fe.hrefNormalized||pe.each([\"href\",\"src\"],function(e,t){pe.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}}),fe.optSelected||(pe.propHooks.selected={get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null},set:function(e){var t=e.parentNode;t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex)}}),pe.each([\"tabIndex\",\"readOnly\",\"maxLength\",\"cellSpacing\",\"cellPadding\",\"rowSpan\",\"colSpan\",\"useMap\",\"frameBorder\",\"contentEditable\"],function(){pe.propFix[this.toLowerCase()]=this}),fe.enctype||(pe.propFix.enctype=\"encoding\");var Pt=/[\\t\\r\\n\\f]/g;pe.fn.extend({addClass:function(e){var t,n,r,i,o,a,s,u=0;if(pe.isFunction(e))return this.each(function(t){pe(this).addClass(e.call(this,t,z(this)))});if(\"string\"==typeof e&&e)for(t=e.match(De)||[];n=this[u++];)if(i=z(n),r=1===n.nodeType&&(\" \"+i+\" \").replace(Pt,\" \")){for(a=0;o=t[a++];)r.indexOf(\" \"+o+\" \")<0&&(r+=o+\" \");s=pe.trim(r),i!==s&&pe.attr(n,\"class\",s)}return this},removeClass:function(e){var t,n,r,i,o,a,s,u=0;if(pe.isFunction(e))return this.each(function(t){pe(this).removeClass(e.call(this,t,z(this)))});if(!arguments.length)return this.attr(\"class\",\"\");if(\"string\"==typeof e&&e)for(t=e.match(De)||[];n=this[u++];)if(i=z(n),r=1===n.nodeType&&(\" \"+i+\" \").replace(Pt,\" \")){for(a=0;o=t[a++];)for(;r.indexOf(\" \"+o+\" \")>-1;)r=r.replace(\" \"+o+\" \",\" \");s=pe.trim(r),i!==s&&pe.attr(n,\"class\",s)}return this},toggleClass:function(e,t){var n=typeof e;return\"boolean\"==typeof t&&\"string\"===n?t?this.addClass(e):this.removeClass(e):pe.isFunction(e)?this.each(function(n){pe(this).toggleClass(e.call(this,n,z(this),t),t)}):this.each(function(){var t,r,i,o;if(\"string\"===n)for(r=0,i=pe(this),o=e.match(De)||[];t=o[r++];)i.hasClass(t)?i.removeClass(t):i.addClass(t);else void 0!==e&&\"boolean\"!==n||(t=z(this),t&&pe._data(this,\"__className__\",t),pe.attr(this,\"class\",t||e===!1?\"\":pe._data(this,\"__className__\")||\"\"))})},hasClass:function(e){var t,n,r=0;for(t=\" \"+e+\" \";n=this[r++];)if(1===n.nodeType&&(\" \"+z(n)+\" \").replace(Pt,\" \").indexOf(t)>-1)return!0;return!1}}),pe.each(\"blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu\".split(\" \"),function(e,t){pe.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),pe.fn.extend({hover:function(e,t){return this.mouseenter(e).mouseleave(t||e)}});var Bt=e.location,Wt=pe.now(),It=/\\?/,$t=/(,)|(\\[|{)|(}|])|\"(?:[^\"\\\\\\r\\n]|\\\\[\"\\\\\\/bfnrt]|\\\\u[\\da-fA-F]{4})*\"\\s*:?|true|false|null|-?(?!0\\d)\\d+(?:\\.\\d+|)(?:[eE][+-]?\\d+|)/g;pe.parseJSON=function(t){if(e.JSON&&e.JSON.parse)return e.JSON.parse(t+\"\");var n,r=null,i=pe.trim(t+\"\");return i&&!pe.trim(i.replace($t,function(e,t,i,o){return n&&t&&(r=0),0===r?e:(n=i||t,r+=!o-!i,\"\")}))?Function(\"return \"+i)():pe.error(\"Invalid JSON: \"+t)},pe.parseXML=function(t){var n,r;if(!t||\"string\"!=typeof t)return null;try{e.DOMParser?(r=new e.DOMParser,n=r.parseFromString(t,\"text/xml\")):(n=new e.ActiveXObject(\"Microsoft.XMLDOM\"),n.async=\"false\",n.loadXML(t))}catch(i){n=void 0}return n&&n.documentElement&&!n.getElementsByTagName(\"parsererror\").length||pe.error(\"Invalid XML: \"+t),n};var zt=/#.*$/,Xt=/([?&])_=[^&]*/,Ut=/^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/gm,Vt=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Yt=/^(?:GET|HEAD)$/,Jt=/^\\/\\//,Gt=/^([\\w.+-]+:)(?:\\/\\/(?:[^\\/?#]*@|)([^\\/?#:]*)(?::(\\d+)|)|)/,Kt={},Qt={},Zt=\"*/\".concat(\"*\"),en=Bt.href,tn=Gt.exec(en.toLowerCase())||[];pe.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:en,type:\"GET\",isLocal:Vt.test(tn[1]),global:!0,processData:!0,async:!0,contentType:\"application/x-www-form-urlencoded; charset=UTF-8\",accepts:{\"*\":Zt,text:\"text/plain\",html:\"text/html\",xml:\"application/xml, text/xml\",json:\"application/json, text/javascript\"},contents:{xml:/\\bxml\\b/,html:/\\bhtml/,json:/\\bjson\\b/},responseFields:{xml:\"responseXML\",text:\"responseText\",json:\"responseJSON\"},converters:{\"* text\":String,\"text html\":!0,\"text json\":pe.parseJSON,\"text xml\":pe.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?V(V(e,pe.ajaxSettings),t):V(pe.ajaxSettings,e)},ajaxPrefilter:X(Kt),ajaxTransport:X(Qt),ajax:function(t,n){function r(t,n,r,i){var o,f,v,x,w,C=n;2!==b&&(b=2,u&&e.clearTimeout(u),c=void 0,s=i||\"\",T.readyState=t>0?4:0,o=t>=200&&t<300||304===t,r&&(x=Y(d,T,r)),x=J(d,x,T,o),o?(d.ifModified&&(w=T.getResponseHeader(\"Last-Modified\"),w&&(pe.lastModified[a]=w),w=T.getResponseHeader(\"etag\"),w&&(pe.etag[a]=w)),204===t||\"HEAD\"===d.type?C=\"nocontent\":304===t?C=\"notmodified\":(C=x.state,f=x.data,v=x.error,o=!v)):(v=C,!t&&C||(C=\"error\",t<0&&(t=0))),T.status=t,T.statusText=(n||C)+\"\",o?g.resolveWith(p,[f,C,T]):g.rejectWith(p,[T,C,v]),T.statusCode(y),y=void 0,l&&h.trigger(o?\"ajaxSuccess\":\"ajaxError\",[T,d,o?f:v]),m.fireWith(p,[T,C]),l&&(h.trigger(\"ajaxComplete\",[T,d]),--pe.active||pe.event.trigger(\"ajaxStop\")))}\"object\"==typeof t&&(n=t,t=void 0),n=n||{};var i,o,a,s,u,l,c,f,d=pe.ajaxSetup({},n),p=d.context||d,h=d.context&&(p.nodeType||p.jquery)?pe(p):pe.event,g=pe.Deferred(),m=pe.Callbacks(\"once memory\"),y=d.statusCode||{},v={},x={},b=0,w=\"canceled\",T={readyState:0,getResponseHeader:function(e){var t;if(2===b){if(!f)for(f={};t=Ut.exec(s);)f[t[1].toLowerCase()]=t[2];t=f[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===b?s:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return b||(e=x[n]=x[n]||e,v[e]=t),this},overrideMimeType:function(e){return b||(d.mimeType=e),this},statusCode:function(e){var t;if(e)if(b<2)for(t in e)y[t]=[y[t],e[t]];else T.always(e[T.status]);return this},abort:function(e){var t=e||w;return c&&c.abort(t),r(0,t),this}};if(g.promise(T).complete=m.add,T.success=T.done,T.error=T.fail,d.url=((t||d.url||en)+\"\").replace(zt,\"\").replace(Jt,tn[1]+\"//\"),d.type=n.method||n.type||d.method||d.type,d.dataTypes=pe.trim(d.dataType||\"*\").toLowerCase().match(De)||[\"\"],null==d.crossDomain&&(i=Gt.exec(d.url.toLowerCase()),d.crossDomain=!(!i||i[1]===tn[1]&&i[2]===tn[2]&&(i[3]||(\"http:\"===i[1]?\"80\":\"443\"))===(tn[3]||(\"http:\"===tn[1]?\"80\":\"443\")))),d.data&&d.processData&&\"string\"!=typeof d.data&&(d.data=pe.param(d.data,d.traditional)),U(Kt,d,n,T),2===b)return T;l=pe.event&&d.global,l&&0===pe.active++&&pe.event.trigger(\"ajaxStart\"),d.type=d.type.toUpperCase(),d.hasContent=!Yt.test(d.type),a=d.url,d.hasContent||(d.data&&(a=d.url+=(It.test(a)?\"&\":\"?\")+d.data,delete d.data),d.cache===!1&&(d.url=Xt.test(a)?a.replace(Xt,\"$1_=\"+Wt++):a+(It.test(a)?\"&\":\"?\")+\"_=\"+Wt++)),d.ifModified&&(pe.lastModified[a]&&T.setRequestHeader(\"If-Modified-Since\",pe.lastModified[a]),pe.etag[a]&&T.setRequestHeader(\"If-None-Match\",pe.etag[a])),(d.data&&d.hasContent&&d.contentType!==!1||n.contentType)&&T.setRequestHeader(\"Content-Type\",d.contentType),T.setRequestHeader(\"Accept\",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(\"*\"!==d.dataTypes[0]?\", \"+Zt+\"; q=0.01\":\"\"):d.accepts[\"*\"]);for(o in d.headers)T.setRequestHeader(o,d.headers[o]);if(d.beforeSend&&(d.beforeSend.call(p,T,d)===!1||2===b))return T.abort();w=\"abort\";for(o in{success:1,error:1,complete:1})T[o](d[o]);if(c=U(Qt,d,n,T)){if(T.readyState=1,l&&h.trigger(\"ajaxSend\",[T,d]),2===b)return T;d.async&&d.timeout>0&&(u=e.setTimeout(function(){T.abort(\"timeout\")},d.timeout));try{b=1,c.send(v,r)}catch(C){if(!(b<2))throw C;r(-1,C)}}else r(-1,\"No Transport\");return T},getJSON:function(e,t,n){return pe.get(e,t,n,\"json\")},getScript:function(e,t){return pe.get(e,void 0,t,\"script\")}}),pe.each([\"get\",\"post\"],function(e,t){pe[t]=function(e,n,r,i){return pe.isFunction(n)&&(i=i||r,r=n,n=void 0),pe.ajax(pe.extend({url:e,type:t,dataType:i,data:n,success:r},pe.isPlainObject(e)&&e))}}),pe._evalUrl=function(e){return pe.ajax({url:e,type:\"GET\",dataType:\"script\",cache:!0,async:!1,global:!1,\"throws\":!0})},pe.fn.extend({wrapAll:function(e){if(pe.isFunction(e))return this.each(function(t){pe(this).wrapAll(e.call(this,t))});if(this[0]){var t=pe(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){for(var e=this;e.firstChild&&1===e.firstChild.nodeType;)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return pe.isFunction(e)?this.each(function(t){pe(this).wrapInner(e.call(this,t))}):this.each(function(){var t=pe(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=pe.isFunction(e);return this.each(function(n){pe(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){pe.nodeName(this,\"body\")||pe(this).replaceWith(this.childNodes)}).end()}}),pe.expr.filters.hidden=function(e){return fe.reliableHiddenOffsets()?e.offsetWidth<=0&&e.offsetHeight<=0&&!e.getClientRects().length:K(e)},pe.expr.filters.visible=function(e){return!pe.expr.filters.hidden(e)};var nn=/%20/g,rn=/\\[\\]$/,on=/\\r?\\n/g,an=/^(?:submit|button|image|reset|file)$/i,sn=/^(?:input|select|textarea|keygen)/i;pe.param=function(e,t){var n,r=[],i=function(e,t){t=pe.isFunction(t)?t():null==t?\"\":t,r[r.length]=encodeURIComponent(e)+\"=\"+encodeURIComponent(t)};if(void 0===t&&(t=pe.ajaxSettings&&pe.ajaxSettings.traditional),pe.isArray(e)||e.jquery&&!pe.isPlainObject(e))pe.each(e,function(){i(this.name,this.value)});else for(n in e)Q(n,e[n],t,i);return r.join(\"&\").replace(nn,\"+\")},pe.fn.extend({serialize:function(){return pe.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=pe.prop(this,\"elements\");return e?pe.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!pe(this).is(\":disabled\")&&sn.test(this.nodeName)&&!an.test(e)&&(this.checked||!Be.test(e))}).map(function(e,t){var n=pe(this).val();return null==n?null:pe.isArray(n)?pe.map(n,function(e){return{name:t.name,value:e.replace(on,\"\\r\\n\")}}):{name:t.name,value:n.replace(on,\"\\r\\n\")}}).get()}}),pe.ajaxSettings.xhr=void 0!==e.ActiveXObject?function(){return this.isLocal?ee():re.documentMode>8?Z():/^(get|post|head|put|delete|options)$/i.test(this.type)&&Z()||ee()}:Z;var un=0,ln={},cn=pe.ajaxSettings.xhr();e.attachEvent&&e.attachEvent(\"onunload\",function(){for(var e in ln)ln[e](void 0,!0)}),fe.cors=!!cn&&\"withCredentials\"in cn,cn=fe.ajax=!!cn,cn&&pe.ajaxTransport(function(t){if(!t.crossDomain||fe.cors){var n;return{send:function(r,i){var o,a=t.xhr(),s=++un;if(a.open(t.type,t.url,t.async,t.username,t.password),t.xhrFields)for(o in t.xhrFields)a[o]=t.xhrFields[o];t.mimeType&&a.overrideMimeType&&a.overrideMimeType(t.mimeType),t.crossDomain||r[\"X-Requested-With\"]||(r[\"X-Requested-With\"]=\"XMLHttpRequest\");for(o in r)void 0!==r[o]&&a.setRequestHeader(o,r[o]+\"\");a.send(t.hasContent&&t.data||null),n=function(e,r){var o,u,l;if(n&&(r||4===a.readyState))if(delete ln[s],n=void 0,a.onreadystatechange=pe.noop,r)4!==a.readyState&&a.abort();else{l={},o=a.status,\"string\"==typeof a.responseText&&(l.text=a.responseText);try{u=a.statusText}catch(c){u=\"\"}o||!t.isLocal||t.crossDomain?1223===o&&(o=204):o=l.text?200:404}l&&i(o,u,l,a.getAllResponseHeaders())},t.async?4===a.readyState?e.setTimeout(n):a.onreadystatechange=ln[s]=n:n()},abort:function(){n&&n(void 0,!0)}}}}),pe.ajaxSetup({accepts:{script:\"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"},contents:{script:/\\b(?:java|ecma)script\\b/},converters:{\"text script\":function(e){return pe.globalEval(e),e}}}),pe.ajaxPrefilter(\"script\",function(e){void 0===e.cache&&(e.cache=!1),e.crossDomain&&(e.type=\"GET\",e.global=!1)}),pe.ajaxTransport(\"script\",function(e){if(e.crossDomain){var t,n=re.head||pe(\"head\")[0]||re.documentElement;return{send:function(r,i){t=re.createElement(\"script\"),t.async=!0,e.scriptCharset&&(t.charset=e.scriptCharset),t.src=e.url,t.onload=t.onreadystatechange=function(e,n){(n||!t.readyState||/loaded|complete/.test(t.readyState))&&(t.onload=t.onreadystatechange=null,t.parentNode&&t.parentNode.removeChild(t),t=null,n||i(200,\"success\"))},n.insertBefore(t,n.firstChild)},abort:function(){t&&t.onload(void 0,!0)}}}});var fn=[],dn=/(=)\\?(?=&|$)|\\?\\?/;pe.ajaxSetup({jsonp:\"callback\",jsonpCallback:function(){var e=fn.pop()||pe.expando+\"_\"+Wt++;return this[e]=!0,e}}),pe.ajaxPrefilter(\"json jsonp\",function(t,n,r){var i,o,a,s=t.jsonp!==!1&&(dn.test(t.url)?\"url\":\"string\"==typeof t.data&&0===(t.contentType||\"\").indexOf(\"application/x-www-form-urlencoded\")&&dn.test(t.data)&&\"data\");if(s||\"jsonp\"===t.dataTypes[0])return i=t.jsonpCallback=pe.isFunction(t.jsonpCallback)?t.jsonpCallback():t.jsonpCallback,s?t[s]=t[s].replace(dn,\"$1\"+i):t.jsonp!==!1&&(t.url+=(It.test(t.url)?\"&\":\"?\")+t.jsonp+\"=\"+i),t.converters[\"script json\"]=function(){return a||pe.error(i+\" was not called\"),a[0]},t.dataTypes[0]=\"json\",o=e[i],e[i]=function(){a=arguments},r.always(function(){void 0===o?pe(e).removeProp(i):e[i]=o,t[i]&&(t.jsonpCallback=n.jsonpCallback,fn.push(i)),a&&pe.isFunction(o)&&o(a[0]),a=o=void 0}),\"script\"}),pe.parseHTML=function(e,t,n){if(!e||\"string\"!=typeof e)return null;\"boolean\"==typeof t&&(n=t,t=!1),t=t||re;var r=Te.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=y([e],t,i),i&&i.length&&pe(i).remove(),pe.merge([],r.childNodes))};var pn=pe.fn.load;return pe.fn.load=function(e,t,n){if(\"string\"!=typeof e&&pn)return pn.apply(this,arguments);var r,i,o,a=this,s=e.indexOf(\" \");return s>-1&&(r=pe.trim(e.slice(s,e.length)),e=e.slice(0,s)),pe.isFunction(t)?(n=t,t=void 0):t&&\"object\"==typeof t&&(i=\"POST\"),a.length>0&&pe.ajax({url:e,type:i||\"GET\",dataType:\"html\",data:t}).done(function(e){o=arguments,a.html(r?pe(\"<div>\").append(pe.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},pe.each([\"ajaxStart\",\"ajaxStop\",\"ajaxComplete\",\"ajaxError\",\"ajaxSuccess\",\"ajaxSend\"],function(e,t){pe.fn[t]=function(e){return this.on(t,e)}}),pe.expr.filters.animated=function(e){return pe.grep(pe.timers,function(t){return e===t.elem}).length},pe.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l,c=pe.css(e,\"position\"),f=pe(e),d={};\"static\"===c&&(e.style.position=\"relative\"),s=f.offset(),o=pe.css(e,\"top\"),u=pe.css(e,\"left\"),l=(\"absolute\"===c||\"fixed\"===c)&&pe.inArray(\"auto\",[o,u])>-1,l?(r=f.position(),a=r.top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),pe.isFunction(t)&&(t=t.call(e,n,pe.extend({},s))),null!=t.top&&(d.top=t.top-s.top+a),null!=t.left&&(d.left=t.left-s.left+i),\"using\"in t?t.using.call(e,d):f.css(d)}},pe.fn.extend({offset:function(e){if(arguments.length)return void 0===e?this:this.each(function(t){pe.offset.setOffset(this,e,t)});var t,n,r={top:0,left:0},i=this[0],o=i&&i.ownerDocument;if(o)return t=o.documentElement,pe.contains(t,i)?(\"undefined\"!=typeof i.getBoundingClientRect&&(r=i.getBoundingClientRect()),n=te(o),{top:r.top+(n.pageYOffset||t.scrollTop)-(t.clientTop||0),left:r.left+(n.pageXOffset||t.scrollLeft)-(t.clientLeft||0)}):r},position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return\"fixed\"===pe.css(r,\"position\")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),pe.nodeName(e[0],\"html\")||(n=e.offset()),n.top+=pe.css(e[0],\"borderTopWidth\",!0),n.left+=pe.css(e[0],\"borderLeftWidth\",!0)),{top:t.top-n.top-pe.css(r,\"marginTop\",!0),left:t.left-n.left-pe.css(r,\"marginLeft\",!0)}}},offsetParent:function(){return this.map(function(){\nfor(var e=this.offsetParent;e&&!pe.nodeName(e,\"html\")&&\"static\"===pe.css(e,\"position\");)e=e.offsetParent;return e||pt})}}),pe.each({scrollLeft:\"pageXOffset\",scrollTop:\"pageYOffset\"},function(e,t){var n=/Y/.test(t);pe.fn[e]=function(r){return Pe(this,function(e,r,i){var o=te(e);return void 0===i?o?t in o?o[t]:o.document.documentElement[r]:e[r]:void(o?o.scrollTo(n?pe(o).scrollLeft():i,n?i:pe(o).scrollTop()):e[r]=i)},e,r,arguments.length,null)}}),pe.each([\"top\",\"left\"],function(e,t){pe.cssHooks[t]=L(fe.pixelPosition,function(e,n){if(n)return n=gt(e,t),ft.test(n)?pe(e).position()[t]+\"px\":n})}),pe.each({Height:\"height\",Width:\"width\"},function(e,t){pe.each({padding:\"inner\"+e,content:t,\"\":\"outer\"+e},function(n,r){pe.fn[r]=function(r,i){var o=arguments.length&&(n||\"boolean\"!=typeof r),a=n||(r===!0||i===!0?\"margin\":\"border\");return Pe(this,function(t,n,r){var i;return pe.isWindow(t)?t.document.documentElement[\"client\"+e]:9===t.nodeType?(i=t.documentElement,Math.max(t.body[\"scroll\"+e],i[\"scroll\"+e],t.body[\"offset\"+e],i[\"offset\"+e],i[\"client\"+e])):void 0===r?pe.css(t,n,a):pe.style(t,n,r,a)},t,o?r:void 0,o,null)}})}),pe.fn.extend({bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,\"**\"):this.off(t,e||\"**\",n)}}),pe.fn.size=function(){return this.length},pe.fn.andSelf=pe.fn.addBack,layui.define(function(e){e(\"jquery\",pe)}),pe});"
  },
  {
    "path": "public/static/layui/lay/modules/code.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;layui.define(\"jquery\",function(e){\"use strict\";var a=layui.jquery,l=\"http://www.layui.com/doc/modules/code.html\";e(\"code\",function(e){var t=[];e=e||{},e.elem=a(e.elem||\".layui-code\"),e.about=!(\"about\"in e)||e.about,e.elem.each(function(){t.push(this)}),layui.each(t.reverse(),function(t,i){var c=a(i),o=c.html();(c.attr(\"lay-encode\")||e.encode)&&(o=o.replace(/&(?!#?[a-zA-Z0-9]+;)/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/'/g,\"&#39;\").replace(/\"/g,\"&quot;\")),c.html('<ol class=\"layui-code-ol\"><li>'+o.replace(/[\\r\\t\\n]+/g,\"</li><li>\")+\"</li></ol>\"),c.find(\">.layui-code-h3\")[0]||c.prepend('<h3 class=\"layui-code-h3\">'+(c.attr(\"lay-title\")||e.title||\"code\")+(e.about?'<a href=\"'+l+'\" target=\"_blank\">layui.code</a>':\"\")+\"</h3>\");var d=c.find(\">.layui-code-ol\");c.addClass(\"layui-box layui-code-view\"),(c.attr(\"lay-skin\")||e.skin)&&c.addClass(\"layui-code-\"+(c.attr(\"lay-skin\")||e.skin)),(d.find(\"li\").length/100|0)>0&&d.css(\"margin-left\",(d.find(\"li\").length/100|0)+\"px\"),(c.attr(\"lay-height\")||e.height)&&d.css(\"max-height\",c.attr(\"lay-height\")||e.height)})})}).addcss(\"modules/code.css\",\"skincodecss\");"
  },
  {
    "path": "public/static/layui/lay/modules/element.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;layui.define(\"jquery\",function(i){\"use strict\";var t=layui.jquery,a=(layui.hint(),layui.device()),e=\"element\",l=\"layui-this\",n=\"layui-show\",s=function(){this.config={}};s.prototype.set=function(i){var a=this;return t.extend(!0,a.config,i),a},s.prototype.on=function(i,t){return layui.onevent(e,i,t)},s.prototype.tabAdd=function(i,a){var e=t(\".layui-tab[lay-filter=\"+i+\"]\"),l=e.children(\".layui-tab-title\"),n=e.children(\".layui-tab-content\");return l.append(\"<li>\"+(a.title||\"unnaming\")+\"</li>\"),n.append('<div class=\"layui-tab-item\">'+(a.content||\"\")+\"</div>\"),y.tabAuto(),this},s.prototype.tabDelete=function(i,a){var e=t(\".layui-tab[lay-filter=\"+i+\"]\"),l=e.children(\".layui-tab-title\").find(\">li\").eq(a);return y.tabDelete(null,l),this},s.prototype.tabChange=function(i,a){var e=t(\".layui-tab[lay-filter=\"+i+\"]\"),l=e.children(\".layui-tab-title\").find(\">li\").eq(a);return y.tabClick(null,a,l),this};var o=\".layui-nav\",c=\"layui-nav-item\",r=\"layui-nav-bar\",u=\"layui-nav-tree\",d=\"layui-nav-child\",h=\"layui-nav-more\",f=\"layui-anim layui-anim-upbit\",y={tabClick:function(i,a,s){var o=s||t(this),a=a||o.index(),c=o.parents(\".layui-tab\"),r=c.children(\".layui-tab-content\").children(\".layui-tab-item\"),u=c.attr(\"lay-filter\");o.addClass(l).siblings().removeClass(l),r.eq(a).addClass(n).siblings().removeClass(n),layui.event.call(this,e,\"tab(\"+u+\")\",{elem:c,index:a})},tabDelete:function(i,a){var e=a||t(this).parent(),n=e.index(),s=e.parents(\".layui-tab\"),o=s.children(\".layui-tab-content\").children(\".layui-tab-item\");e.hasClass(l)&&(e.next()[0]?y.tabClick.call(e.next()[0],null,n+1):e.prev()[0]&&y.tabClick.call(e.prev()[0],null,n-1)),e.remove(),o.eq(n).remove()},tabAuto:function(){var i=\"layui-tab-more\",e=\"layui-tab-bar\",l=\"layui-tab-close\",n=this;t(\".layui-tab\").each(function(){var s=t(this),o=s.children(\".layui-tab-title\"),c=(s.children(\".layui-tab-content\").children(\".layui-tab-item\"),'lay-stope=\"tabmore\"'),r=t('<span class=\"layui-unselect layui-tab-bar\" '+c+\"><i \"+c+' class=\"layui-icon\">&#xe61a;</i></span>');if(n===window&&8!=a.ie&&y.hideTabMore(!0),s.attr(\"lay-allowClose\")&&o.find(\"li\").each(function(){var i=t(this);if(!i.find(\".\"+l)[0]){var a=t('<i class=\"layui-icon layui-unselect '+l+'\">&#x1006;</i>');a.on(\"click\",y.tabDelete),i.append(a)}}),o.prop(\"scrollWidth\")>o.outerWidth()+1){if(o.find(\".\"+e)[0])return;o.append(r),r.on(\"click\",function(t){o[this.title?\"removeClass\":\"addClass\"](i),this.title=this.title?\"\":\"收缩\"})}else o.find(\".\"+e).remove()})},hideTabMore:function(i){var a=t(\".layui-tab-title\");i!==!0&&\"tabmore\"===t(i.target).attr(\"lay-stope\")||(a.removeClass(\"layui-tab-more\"),a.find(\".layui-tab-bar\").attr(\"title\",\"\"))},clickThis:function(){var i=t(this),a=i.parents(o),n=a.attr(\"lay-filter\");i.find(\".\"+d)[0]||(a.find(\".\"+l).removeClass(l),i.addClass(l),layui.event.call(this,e,\"nav(\"+n+\")\",i))},clickChild:function(){var i=t(this),a=i.parents(o),n=a.attr(\"lay-filter\");a.find(\".\"+l).removeClass(l),i.addClass(l),layui.event.call(this,e,\"nav(\"+n+\")\",i)},showChild:function(){var i=t(this),a=i.parents(o),e=i.parent(),l=i.siblings(\".\"+d);a.hasClass(u)&&(l.removeClass(f),e[\"none\"===l.css(\"display\")?\"addClass\":\"removeClass\"](c+\"ed\"))}};s.prototype.init=function(i){var e={tab:function(){y.tabAuto.call({})},nav:function(){var i,e,l,s=200,p=function(o,c){var r=t(this),y=r.find(\".\"+d);c.hasClass(u)?o.css({top:r.position().top,height:r.children(\"a\").height(),opacity:1}):(y.addClass(f),o.css({left:r.position().left+parseFloat(r.css(\"marginLeft\")),top:r.position().top+r.height()-5}),i=setTimeout(function(){o.css({width:r.width(),opacity:1})},a.ie&&a.ie<10?0:s),clearTimeout(l),\"block\"===y.css(\"display\")&&clearTimeout(e),e=setTimeout(function(){y.addClass(n),r.find(\".\"+h).addClass(h+\"d\")},300))};t(o).each(function(){var a=t(this),o=t('<span class=\"'+r+'\"></span>'),f=a.find(\".\"+c);a.find(\".\"+r)[0]||(a.append(o),f.on(\"mouseenter\",function(){p.call(this,o,a)}).on(\"mouseleave\",function(){a.hasClass(u)||(clearTimeout(e),e=setTimeout(function(){a.find(\".\"+d).removeClass(n),a.find(\".\"+h).removeClass(h+\"d\")},300))}),a.on(\"mouseleave\",function(){clearTimeout(i),l=setTimeout(function(){a.hasClass(u)?o.css({height:0,top:o.position().top+o.height()/2,opacity:0}):o.css({width:0,left:o.position().left+o.width()/2,opacity:0})},s)})),f.each(function(){var i=t(this),a=i.find(\".\"+d);if(a[0]&&!i.find(\".\"+h)[0]){var e=i.children(\"a\");e.append('<span class=\"'+h+'\"></span>')}i.off(\"click\",y.clickThis).on(\"click\",y.clickThis),i.children(\"a\").off(\"click\",y.showChild).on(\"click\",y.showChild),a.children(\"dd\").off(\"click\",y.clickChild).on(\"click\",y.clickChild)})})},breadcrumb:function(){var i=\".layui-breadcrumb\";t(i).each(function(){var i=t(this),a=i.attr(\"lay-separator\")||\">\",e=i.find(\"a\");e.find(\".layui-box\")[0]||(e.each(function(i){i!==e.length-1&&t(this).append('<span class=\"layui-box\">'+a+\"</span>\")}),i.css(\"visibility\",\"visible\"))})}};return layui.each(e,function(i,t){t()})};var p=new s,b=t(document);p.init();var v=\".layui-tab-title li\";b.on(\"click\",v,y.tabClick),b.on(\"click\",y.hideTabMore),t(window).on(\"resize\",y.tabAuto),i(e,function(i){return p.set(i)})});"
  },
  {
    "path": "public/static/layui/lay/modules/flow.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;layui.define(\"jquery\",function(e){\"use strict\";var l=layui.jquery,o=function(e){},t='<i class=\"layui-anim layui-anim-rotate layui-anim-loop layui-icon \">&#xe63e;</i>';o.prototype.load=function(e){var o,i,n,r,a=this,c=0;e=e||{};var u=l(e.elem);if(u[0]){var f=l(e.scrollElem||document),m=e.mb||50,s=!(\"isAuto\"in e)||e.isAuto,y=e.end||\"没有更多了\",v=e.scrollElem&&e.scrollElem!==document,d=\"<cite>加载更多</cite>\",h=l('<div class=\"layui-flow-more\"><a href=\"javascript:;\">'+d+\"</a></div>\");u.find(\".layui-flow-more\")[0]||u.append(h);var p=function(e,t){e=l(e),h.before(e),t=0==t||null,t?h.html(y):h.find(\"a\").html(d),i=t,o=null,n&&n()},g=function(){o=!0,h.find(\"a\").html(t),\"function\"==typeof e.done&&e.done(++c,p)};if(g(),h.find(\"a\").on(\"click\",function(){l(this);i||o||g()}),e.isLazyimg)var n=a.lazyimg({elem:e.elem+\" img\",scrollElem:e.scrollElem});return s?(f.on(\"scroll\",function(){var e=l(this),t=e.scrollTop();r&&clearTimeout(r),i||(r=setTimeout(function(){var i=v?e.height():l(window).height(),n=v?e.prop(\"scrollHeight\"):document.documentElement.scrollHeight;n-t-i<=m&&(o||g())},100))}),a):a}},o.prototype.lazyimg=function(e){var o,t=this,i=0;e=e||{};var n=l(e.scrollElem||document),r=e.elem||\"img\",a=e.scrollElem&&e.scrollElem!==document,c=function(e,l){var o=n.scrollTop(),r=o+l,c=a?function(){return e.offset().top-n.offset().top+o}():e.offset().top;if(c>=o&&c<=r&&!e.attr(\"src\")){var f=e.attr(\"lay-src\");layui.img(f,function(){var l=t.lazyimg.elem.eq(i);e.attr(\"src\",f).removeAttr(\"lay-src\"),l[0]&&u(l),i++})}},u=function(e,o){var u=a?(o||n).height():l(window).height(),f=n.scrollTop(),m=f+u;if(t.lazyimg.elem=l(r),e)c(e,u);else for(var s=0;s<t.lazyimg.elem.length;s++){var y=t.lazyimg.elem.eq(s),v=a?function(){return y.offset().top-n.offset().top+f}():y.offset().top;if(c(y,u),i=s,v>m)break}};if(u(),!o){var f;n.on(\"scroll\",function(){var e=l(this);f&&clearTimeout(f),f=setTimeout(function(){u(null,e)},50)}),o=!0}return u},e(\"flow\",new o)});"
  },
  {
    "path": "public/static/layui/lay/modules/form.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;layui.define(\"layer\",function(e){\"use strict\";var i=layui.jquery,a=layui.layer,t=layui.hint(),n=layui.device(),l=\"form\",s=\".layui-form\",c=\"layui-this\",r=\"layui-disabled\",u=function(){this.config={verify:{required:[/[\\S]+/,\"必填项不能为空\"],phone:[/^1\\d{10}$/,\"请输入正确的手机号\"],email:[/^([a-zA-Z0-9_\\.\\-])+\\@(([a-zA-Z0-9\\-])+\\.)+([a-zA-Z0-9]{2,4})+$/,\"邮箱格式不正确\"],url:[/(^#)|(^http(s*):\\/\\/[^\\s]+\\.[^\\s]+)/,\"链接格式不正确\"],number:[/^\\d+$/,\"只能填写数字\"],date:[/^(\\d{4})[-\\/](\\d{1}|0\\d{1}|1[0-2])([-\\/](\\d{1}|0\\d{1}|[1-2][0-9]|3[0-1]))*$/,\"日期格式不正确\"],identity:[/(^\\d{15}$)|(^\\d{17}(x|X|\\d)$)/,\"请输入正确的身份证号\"]}}};u.prototype.set=function(e){var a=this;return i.extend(!0,a.config,e),a},u.prototype.verify=function(e){var a=this;return i.extend(!0,a.config.verify,e),a},u.prototype.on=function(e,i){return layui.onevent(l,e,i)},u.prototype.render=function(e){var a=this,n={select:function(){var e=\"请选择\",a=\"layui-form-select\",t=\"layui-select-title\",n=i(s).find(\"select\"),u=function(e,n){i(e.target).parent().hasClass(t)&&!n||i(\".\"+a).removeClass(a+\"ed\")},o=function(e,n){var s=i(this),o=e.find(\".\"+t);n||(o.on(\"click\",function(i){e.hasClass(a+\"ed\")?e.removeClass(a+\"ed\"):(u(i,!0),e.addClass(a+\"ed\"))}),e.find(\"dl>dd\").on(\"click\",function(){var e=i(this),a=e.attr(\"lay-value\"),t=s.attr(\"lay-filter\");return!e.hasClass(r)&&(s.val(a).removeClass(\"layui-form-danger\"),o.find(\"input\").val(e.text()),e.addClass(c).siblings().removeClass(c),void layui.event(l,\"select(\"+t+\")\",{elem:s[0],value:a}))}),e.find(\"dl>dt\").on(\"click\",function(e){return!1}),i(document).off(\"click\",u).on(\"click\",u))};n.each(function(n,l){var s=i(this),u=s.next(\".\"+a),d=this.disabled,f=l.value,y=i(l.options[l.selectedIndex]),v=i(['<div class=\"layui-unselect '+a+(d?\" layui-select-disabled\":\"\")+'\">','<div class=\"'+t+'\"><input type=\"text\" placeholder=\"'+(l.options[0].innerHTML?l.options[0].innerHTML:e)+'\" value=\"'+(f?y.html():\"\")+'\" readonly class=\"layui-input layui-unselect'+(d?\" \"+r:\"\")+'\">','<i class=\"layui-edge\"></i></div>','<dl class=\"layui-anim layui-anim-upbit'+(s.find(\"optgroup\")[0]?\" layui-select-group\":\"\")+'\">'+function(e){var i=[];return layui.each(e,function(e,a){(0!==e||a.value)&&(\"optgroup\"===a.tagName.toLowerCase()?i.push(\"<dt>\"+a.label+\"</dt>\"):i.push('<dd lay-value=\"'+a.value+'\" class=\"'+(f===a.value?c:\"\")+(a.disabled?\" \"+r:\"\")+'\">'+a.innerHTML+\"</dd>\"))}),i.join(\"\")}(s.find(\"*\"))+\"</dl>\",\"</div>\"].join(\"\"));u[0]&&u.remove(),s.after(v),o.call(this,v,d)})},checkbox:function(){var e={checkbox:[\"layui-form-checkbox\",\"layui-form-checked\",\"checkbox\"],_switch:[\"layui-form-switch\",\"layui-form-onswitch\",\"switch\"]},a=i(s).find(\"input[type=checkbox]\"),t=function(e,a){var t=i(this);e.on(\"click\",function(){var i=t.attr(\"lay-filter\");t[0].disabled||(t[0].checked?(t[0].checked=!1,e.removeClass(a[1])):(t[0].checked=!0,e.addClass(a[1])),layui.event(l,a[2]+\"(\"+i+\")\",{elem:t[0],value:t[0].value}))})};a.each(function(a,n){var l=i(this),s=l.attr(\"lay-skin\"),c=this.disabled;\"switch\"===s&&(s=\"_\"+s);var u=e[s]||e.checkbox,o=l.next(\".\"+u[0]),d=i(['<div class=\"layui-unselect '+u[0]+(n.checked?\" \"+u[1]:\"\")+(c?\" layui-checkbox-disbaled \"+r:\"\")+'\">',{_switch:\"<i></i>\"}[s]||\"<span>\"+(n.title||\"勾选\")+'</span><i class=\"layui-icon\">&#xe618;</i>',\"</div>\"].join(\"\"));o[0]&&o.remove(),l.after(d),t.call(this,d,u)})},radio:function(){var e=\"layui-form-radio\",a=[\"&#xe643;\",\"&#xe63f;\"],t=i(s).find(\"input[type=radio]\"),n=function(t){var n=i(this),c=\"layui-anim-scaleSpring\";t.on(\"click\",function(){var r=n[0].name,u=n.parents(s),o=n.attr(\"lay-filter\"),d=u.find(\"input[name=\"+r.replace(/(\\.|#|\\[|\\])/g,\"\\\\$1\")+\"]\");n[0].disabled||(layui.each(d,function(){var t=i(this).next(\".\"+e);this.checked=!1,t.removeClass(e+\"ed\"),t.find(\".layui-icon\").removeClass(c).html(a[1])}),n[0].checked=!0,t.addClass(e+\"ed\"),t.find(\".layui-icon\").addClass(c).html(a[0]),layui.event(l,\"radio(\"+o+\")\",{elem:n[0],value:n[0].value}))})};t.each(function(t,l){var s=i(this),c=s.next(\".\"+e),u=this.disabled,o=i(['<div class=\"layui-unselect '+e+(l.checked?\" \"+e+\"ed\":\"\")+(u?\" layui-radio-disbaled \"+r:\"\")+'\">','<i class=\"layui-anim layui-icon\">'+a[l.checked?0:1]+\"</i>\",\"<span>\"+(l.title||\"未命名\")+\"</span>\",\"</div>\"].join(\"\"));c[0]&&c.remove(),s.after(o),n.call(this,o)})}};return e?n[e]?n[e]():t.error(\"不支持的\"+e+\"表单渲染\"):layui.each(n,function(e,i){i()}),a};var o=function(){var e=i(this),t=d.config.verify,c=null,r=\"layui-form-danger\",u={},o=e.parents(s),f=o.find(\"*[lay-verify]\"),y=e.parents(\"form\")[0],v=o.find(\"input,select,textarea\"),h=e.attr(\"lay-filter\");return layui.each(f,function(e,l){var s=i(this),u=s.attr(\"lay-verify\"),o=\"\",d=s.val(),f=\"function\"==typeof t[u];if(s.removeClass(r),t[u]&&(f?o=t[u](d,l):!t[u][0].test(d)))return a.msg(o||t[u][1],{icon:5,shift:6}),n.android||n.ios||l.focus(),s.addClass(r),c=!0}),!c&&(layui.each(v,function(e,i){i.name&&(/^checkbox|radio$/.test(i.type)&&!i.checked||(u[i.name]=i.value))}),layui.event.call(this,l,\"submit(\"+h+\")\",{elem:this,form:y,field:u}))},d=new u,f=i(document);d.render(),f.on(\"reset\",s,function(){setTimeout(function(){d.render()},50)}),f.on(\"submit\",s,o).on(\"click\",\"*[lay-submit]\",o),e(l,function(e){return d.set(e)})});"
  },
  {
    "path": "public/static/layui/lay/modules/laydate.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;layui.define(function(e){\"use strict\";var t=window,a={path:\"\",skin:\"default\",format:\"YYYY-MM-DD\",min:\"1900-01-01 00:00:00\",max:\"2099-12-31 23:59:59\",isv:!1,init:!0},n={},s=document,i=\"createElement\",o=\"getElementById\",l=\"getElementsByTagName\",d=[\"laydate_box\",\"laydate_void\",\"laydate_click\",\"LayDateSkin\",\"skins/\",\"/laydate.css\"];t.laydate=function(e){return e=e||{},n.run(e),laydate},laydate.v=\"1.1\",n.trim=function(e){return e=e||\"\",e.replace(/^\\s|\\s$/g,\"\").replace(/\\s+/g,\" \")},n.digit=function(e){return e<10?\"0\"+(0|e):e},n.stopmp=function(e){return e=e||t.event,e.stopPropagation?e.stopPropagation():e.cancelBubble=!0,this},n.each=function(e,t){for(var a=0,n=e.length;a<n&&t(a,e[a])!==!1;a++);},n.hasClass=function(e,t){return e=e||{},new RegExp(\"\\\\b\"+t+\"\\\\b\").test(e.className)},n.addClass=function(e,t){return e=e||{},n.hasClass(e,t)||(e.className+=\" \"+t),e.className=n.trim(e.className),this},n.removeClass=function(e,t){if(e=e||{},n.hasClass(e,t)){var a=new RegExp(\"\\\\b\"+t+\"\\\\b\");e.className=e.className.replace(a,\"\")}return this},n.removeCssAttr=function(e,t){var a=e.style;a.removeProperty?a.removeProperty(t):a.removeAttribute(t)},n.shde=function(e,t){e.style.display=t?\"none\":\"block\"},n.query=function(e){if(e&&1===e.nodeType){if(\"input\"!==e.tagName.toLowerCase())throw new Error(\"选择器elem错误\");return e}var t,e=n.trim(e).split(\" \"),a=s[o](e[0].substr(1));if(a){if(e[1]){if(/^\\./.test(e[1])){var i,d=e[1].substr(1),r=new RegExp(\"\\\\b\"+d+\"\\\\b\");return t=[],i=s.getElementsByClassName?a.getElementsByClassName(d):a[l](\"*\"),n.each(i,function(e,a){r.test(a.className)&&t.push(a)}),t[0]?t:\"\"}return t=a[l](e[1]),t[0]?a[l](e[1]):\"\"}return a}},n.on=function(e,a,s){return e.attachEvent?e.attachEvent(\"on\"+a,function(){s.call(e,t.even)}):e.addEventListener(a,s,!1),n},n.stopMosup=function(e,t){\"mouseup\"!==e&&n.on(t,\"mouseup\",function(e){n.stopmp(e)})},n.run=function(e){var t=(n.query,e.elem);t&&(d.elemv=/textarea|input/.test(t.tagName.toLocaleLowerCase())?\"value\":\"innerHTML\",(\"init\"in e?e.init:a.init)&&!t[d.elemv]&&(t[d.elemv]=laydate.now(null,e.format||a.format)),n.view(t,e),n.reshow())},n.scroll=function(e){return e=e?\"scrollLeft\":\"scrollTop\",s.body[e]|s.documentElement[e]},n.winarea=function(e){return document.documentElement[e?\"clientWidth\":\"clientHeight\"]},n.isleap=function(e){return e%4===0&&e%100!==0||e%400===0},n.checkVoid=function(e,t,a){var s=[];return e=0|e,t=0|t,a=0|a,e<n.mins[0]?s=[\"y\"]:e>n.maxs[0]?s=[\"y\",1]:e>=n.mins[0]&&e<=n.maxs[0]&&(e==n.mins[0]&&(t<n.mins[1]?s=[\"m\"]:t==n.mins[1]&&a<n.mins[2]&&(s=[\"d\"])),e==n.maxs[0]&&(t>n.maxs[1]?s=[\"m\",1]:t==n.maxs[1]&&a>n.maxs[2]&&(s=[\"d\",1]))),s},n.timeVoid=function(e,t){if(n.ymd[1]+1==n.mins[1]&&n.ymd[2]==n.mins[2]){if(0===t&&e<n.mins[3])return 1;if(1===t&&e<n.mins[4])return 1;if(2===t&&e<n.mins[5])return 1}else if(n.ymd[1]+1==n.maxs[1]&&n.ymd[2]==n.maxs[2]){if(0===t&&e>n.maxs[3])return 1;if(1===t&&e>n.maxs[4])return 1;if(2===t&&e>n.maxs[5])return 1}if(e>(t?59:23))return 1},n.check=function(){var e=n.options.format.replace(/YYYY|MM|DD|hh|mm|ss/g,\"\\\\d+\\\\\").replace(/\\\\$/g,\"\"),t=new RegExp(e),a=n.elem[d.elemv],s=a.match(/\\d+/g)||[],i=n.checkVoid(s[0],s[1],s[2]);if(\"\"!==a.replace(/\\s/g,\"\")){if(!t.test(a))return n.elem[d.elemv]=\"\",n.msg(\"日期不符合格式，请重新选择。\"),1;if(i[0])return n.elem[d.elemv]=\"\",n.msg(\"日期不在有效期内，请重新选择。\"),1;i.value=n.elem[d.elemv].match(t).join(),s=i.value.match(/\\d+/g),s[1]<1?(s[1]=1,i.auto=1):s[1]>12?(s[1]=12,i.auto=1):s[1].length<2&&(i.auto=1),s[2]<1?(s[2]=1,i.auto=1):s[2]>n.months[(0|s[1])-1]?(s[2]=31,i.auto=1):s[2].length<2&&(i.auto=1),s.length>3&&(n.timeVoid(s[3],0)&&(i.auto=1),n.timeVoid(s[4],1)&&(i.auto=1),n.timeVoid(s[5],2)&&(i.auto=1)),i.auto?n.creation([s[0],0|s[1],0|s[2]],1):i.value!==n.elem[d.elemv]&&(n.elem[d.elemv]=i.value)}},n.months=[31,null,31,30,31,30,31,31,30,31,30,31],n.viewDate=function(e,t,a){var s=(n.query,{}),i=new Date;e<(0|n.mins[0])&&(e=0|n.mins[0]),e>(0|n.maxs[0])&&(e=0|n.maxs[0]),i.setFullYear(e,t,a),s.ymd=[i.getFullYear(),i.getMonth(),i.getDate()],n.months[1]=n.isleap(s.ymd[0])?29:28,i.setFullYear(s.ymd[0],s.ymd[1],1),s.FDay=i.getDay(),s.PDay=n.months[0===t?11:t-1]-s.FDay+1,s.NDay=1,n.each(d.tds,function(e,t){var a,i=s.ymd[0],o=s.ymd[1]+1;t.className=\"\",e<s.FDay?(t.innerHTML=a=e+s.PDay,n.addClass(t,\"laydate_nothis\"),1===o&&(i-=1),o=1===o?12:o-1):e>=s.FDay&&e<s.FDay+n.months[s.ymd[1]]?(t.innerHTML=a=e-s.FDay+1,e-s.FDay+1===s.ymd[2]&&(n.addClass(t,d[2]),s.thisDay=t)):(t.innerHTML=a=s.NDay++,n.addClass(t,\"laydate_nothis\"),12===o&&(i+=1),o=12===o?1:o+1),n.checkVoid(i,o,a)[0]&&n.addClass(t,d[1]),n.options.festival&&n.festival(t,o+\".\"+a),t.setAttribute(\"y\",i),t.setAttribute(\"m\",o),t.setAttribute(\"d\",a),i=o=a=null}),n.valid=!n.hasClass(s.thisDay,d[1]),n.ymd=s.ymd,d.year.value=n.ymd[0]+\"年\",d.month.value=n.digit(n.ymd[1]+1)+\"月\",n.each(d.mms,function(e,t){var a=n.checkVoid(n.ymd[0],(0|t.getAttribute(\"m\"))+1);\"y\"===a[0]||\"m\"===a[0]?n.addClass(t,d[1]):n.removeClass(t,d[1]),n.removeClass(t,d[2]),a=null}),n.addClass(d.mms[n.ymd[1]],d[2]),s.times=[0|n.inymd[3]||0,0|n.inymd[4]||0,0|n.inymd[5]||0],n.each(new Array(3),function(e){n.hmsin[e].value=n.digit(n.timeVoid(s.times[e],e)?0|n.mins[e+3]:0|s.times[e])}),n[n.valid?\"removeClass\":\"addClass\"](d.ok,d[1])},n.festival=function(e,t){var a;switch(t){case\"1.1\":a=\"元旦\";break;case\"3.8\":a=\"妇女\";break;case\"4.5\":a=\"清明\";break;case\"5.1\":a=\"劳动\";break;case\"6.1\":a=\"儿童\";break;case\"9.10\":a=\"教师\";break;case\"10.1\":a=\"国庆\"}a&&(e.innerHTML=a),a=null},n.viewYears=function(e){var t=n.query,a=\"\";n.each(new Array(14),function(t){a+=7===t?\"<li \"+(parseInt(d.year.value)===e?'class=\"'+d[2]+'\"':\"\")+' y=\"'+e+'\">'+e+\"年</li>\":'<li y=\"'+(e-7+t)+'\">'+(e-7+t)+\"年</li>\"}),t(\"#laydate_ys\").innerHTML=a,n.each(t(\"#laydate_ys li\"),function(e,t){\"y\"===n.checkVoid(t.getAttribute(\"y\"))[0]?n.addClass(t,d[1]):n.on(t,\"click\",function(e){n.stopmp(e).reshow(),n.viewDate(0|this.getAttribute(\"y\"),n.ymd[1],n.ymd[2])})})},n.initDate=function(){var e=(n.query,new Date),t=n.elem[d.elemv].match(/\\d+/g)||[];t.length<3&&(t=n.options.start.match(/\\d+/g)||[],t.length<3&&(t=[e.getFullYear(),e.getMonth()+1,e.getDate()])),n.inymd=t,n.viewDate(t[0],t[1]-1,t[2])},n.iswrite=function(){var e=n.query,t={time:e(\"#laydate_hms\")};n.shde(t.time,!n.options.istime),n.shde(d.oclear,!(\"isclear\"in n.options?n.options.isclear:1)),n.shde(d.otoday,!(\"istoday\"in n.options?n.options.istoday:1)),n.shde(d.ok,!(\"issure\"in n.options?n.options.issure:1))},n.orien=function(e,t){var a,s=n.elem.getBoundingClientRect();e.style.left=s.left+(t?0:n.scroll(1))+\"px\",a=s.bottom+e.offsetHeight/1.5<=n.winarea()?s.bottom-1:s.top>e.offsetHeight/1.5?s.top-e.offsetHeight+1:n.winarea()-e.offsetHeight,e.style.top=Math.max(a+(t?0:n.scroll()),1)+\"px\"},n.follow=function(e){n.options.fixed?(e.style.position=\"fixed\",n.orien(e,1)):(e.style.position=\"absolute\",n.orien(e))},n.viewtb=function(){var e,t=[],a=[\"日\",\"一\",\"二\",\"三\",\"四\",\"五\",\"六\"],o={},d=s[i](\"table\"),r=s[i](\"thead\");return r.appendChild(s[i](\"tr\")),o.creath=function(e){var t=s[i](\"th\");t.innerHTML=a[e],r[l](\"tr\")[0].appendChild(t),t=null},n.each(new Array(6),function(a){t.push([]),e=d.insertRow(0),n.each(new Array(7),function(n){t[a][n]=0,0===a&&o.creath(n),e.insertCell(n)})}),d.insertBefore(r,d.children[0]),d.id=d.className=\"laydate_table\",e=t=null,d.outerHTML.toLowerCase()}(),n.view=function(e,t){var o,l=n.query,r={};t=t||e,n.elem=e,n.options=t,n.options.format||(n.options.format=a.format),n.options.start=n.options.start||\"\",n.mm=r.mm=[n.options.min||a.min,n.options.max||a.max],n.mins=r.mm[0].match(/\\d+/g),n.maxs=r.mm[1].match(/\\d+/g),n.box?n.shde(n.box):(o=s[i](\"div\"),o.id=d[0],o.className=d[0],o.style.cssText=\"position: absolute;\",o.setAttribute(\"name\",\"laydate-v\"+laydate.v),o.innerHTML=r.html='<div class=\"laydate_top\"><div class=\"laydate_ym laydate_y\" id=\"laydate_YY\"><a class=\"laydate_choose laydate_chprev laydate_tab\"><cite></cite></a><input id=\"laydate_y\" readonly><label></label><a class=\"laydate_choose laydate_chnext laydate_tab\"><cite></cite></a><div class=\"laydate_yms\"><a class=\"laydate_tab laydate_chtop\"><cite></cite></a><ul id=\"laydate_ys\"></ul><a class=\"laydate_tab laydate_chdown\"><cite></cite></a></div></div><div class=\"laydate_ym laydate_m\" id=\"laydate_MM\"><a class=\"laydate_choose laydate_chprev laydate_tab\"><cite></cite></a><input id=\"laydate_m\" readonly><label></label><a class=\"laydate_choose laydate_chnext laydate_tab\"><cite></cite></a><div class=\"laydate_yms\" id=\"laydate_ms\">'+function(){var e=\"\";return n.each(new Array(12),function(t){e+='<span m=\"'+t+'\">'+n.digit(t+1)+\"月</span>\"}),e}()+\"</div></div></div>\"+n.viewtb+'<div class=\"laydate_bottom\"><ul id=\"laydate_hms\"><li class=\"laydate_sj\">时间</li><li><input readonly>:</li><li><input readonly>:</li><li><input readonly></li></ul><div class=\"laydate_time\" id=\"laydate_time\"></div><div class=\"laydate_btn\"><a id=\"laydate_clear\">清空</a><a id=\"laydate_today\">今天</a><a id=\"laydate_ok\">确认</a></div>'+(a.isv?'<a href=\"http://sentsin.com/layui/laydate/\" class=\"laydate_v\" target=\"_blank\">laydate-v'+laydate.v+\"</a>\":\"\")+\"</div>\",s.body.appendChild(o),n.box=l(\"#\"+d[0]),n.events(),o=null),n.follow(n.box),t.zIndex?n.box.style.zIndex=t.zIndex:n.removeCssAttr(n.box,\"z-index\"),n.stopMosup(\"click\",n.box),n.initDate(),n.iswrite(),n.check()},n.reshow=function(){return n.each(n.query(\"#\"+d[0]+\" .laydate_show\"),function(e,t){n.removeClass(t,\"laydate_show\")}),this},n.close=function(){n.reshow(),n.shde(n.query(\"#\"+d[0]),1),n.elem=null},n.parse=function(e,t,s){return e=e.concat(t),s=s||(n.options?n.options.format:a.format),s.replace(/YYYY|MM|DD|hh|mm|ss/g,function(t,a){return e.index=0|++e.index,n.digit(e[e.index])})},n.creation=function(e,t){var a=(n.query,n.hmsin),s=n.parse(e,[a[0].value,a[1].value,a[2].value]);n.elem[d.elemv]=s,t||(n.close(),\"function\"==typeof n.options.choose&&n.options.choose(s))},n.events=function(){var e=n.query,a={box:\"#\"+d[0]};n.addClass(s.body,\"laydate_body\"),d.tds=e(\"#laydate_table td\"),d.mms=e(\"#laydate_ms span\"),d.year=e(\"#laydate_y\"),d.month=e(\"#laydate_m\"),n.each(e(a.box+\" .laydate_ym\"),function(e,t){n.on(t,\"click\",function(t){n.stopmp(t).reshow(),n.addClass(this[l](\"div\")[0],\"laydate_show\"),e||(a.YY=parseInt(d.year.value),n.viewYears(a.YY))})}),n.on(e(a.box),\"click\",function(){n.reshow()}),a.tabYear=function(e){0===e?n.ymd[0]--:1===e?n.ymd[0]++:2===e?a.YY-=14:a.YY+=14,e<2?(n.viewDate(n.ymd[0],n.ymd[1],n.ymd[2]),n.reshow()):n.viewYears(a.YY)},n.each(e(\"#laydate_YY .laydate_tab\"),function(e,t){n.on(t,\"click\",function(t){n.stopmp(t),a.tabYear(e)})}),a.tabMonth=function(e){e?(n.ymd[1]++,12===n.ymd[1]&&(n.ymd[0]++,n.ymd[1]=0)):(n.ymd[1]--,n.ymd[1]===-1&&(n.ymd[0]--,n.ymd[1]=11)),n.viewDate(n.ymd[0],n.ymd[1],n.ymd[2])},n.each(e(\"#laydate_MM .laydate_tab\"),function(e,t){n.on(t,\"click\",function(t){n.stopmp(t).reshow(),a.tabMonth(e)})}),n.each(e(\"#laydate_ms span\"),function(e,t){n.on(t,\"click\",function(e){n.stopmp(e).reshow(),n.hasClass(this,d[1])||n.viewDate(n.ymd[0],0|this.getAttribute(\"m\"),n.ymd[2])})}),n.each(e(\"#laydate_table td\"),function(e,t){n.on(t,\"click\",function(e){n.hasClass(this,d[1])||(n.stopmp(e),n.creation([0|this.getAttribute(\"y\"),0|this.getAttribute(\"m\"),0|this.getAttribute(\"d\")]))})}),d.oclear=e(\"#laydate_clear\"),n.on(d.oclear,\"click\",function(){n.elem[d.elemv]=\"\",n.close()}),d.otoday=e(\"#laydate_today\"),n.on(d.otoday,\"click\",function(){var e=new Date;n.creation([e.getFullYear(),e.getMonth()+1,e.getDate()])}),d.ok=e(\"#laydate_ok\"),n.on(d.ok,\"click\",function(){n.valid&&n.creation([n.ymd[0],n.ymd[1]+1,n.ymd[2]])}),a.times=e(\"#laydate_time\"),n.hmsin=a.hmsin=e(\"#laydate_hms input\"),a.hmss=[\"小时\",\"分钟\",\"秒数\"],a.hmsarr=[],n.msg=function(t,s){var i='<div class=\"laydte_hsmtex\">'+(s||\"提示\")+\"<span>×</span></div>\";\"string\"==typeof t?(i+=\"<p>\"+t+\"</p>\",n.shde(e(\"#\"+d[0])),n.removeClass(a.times,\"laydate_time1\").addClass(a.times,\"laydate_msg\")):(a.hmsarr[t]?i=a.hmsarr[t]:(i+='<div id=\"laydate_hmsno\" class=\"laydate_hmsno\">',n.each(new Array(0===t?24:60),function(e){i+=\"<span>\"+e+\"</span>\"}),i+=\"</div>\",a.hmsarr[t]=i),n.removeClass(a.times,\"laydate_msg\"),n[0===t?\"removeClass\":\"addClass\"](a.times,\"laydate_time1\")),n.addClass(a.times,\"laydate_show\"),a.times.innerHTML=i},a.hmson=function(t,a){var s=e(\"#laydate_hmsno span\"),i=n.valid?null:1;n.each(s,function(e,s){i?n.addClass(s,d[1]):n.timeVoid(e,a)?n.addClass(s,d[1]):n.on(s,\"click\",function(e){n.hasClass(this,d[1])||(t.value=n.digit(0|this.innerHTML))})}),n.addClass(s[0|t.value],\"laydate_click\")},n.each(a.hmsin,function(e,t){n.on(t,\"click\",function(t){n.stopmp(t).reshow(),n.msg(e,a.hmss[e]),a.hmson(this,e)})}),n.on(s,\"mouseup\",function(){var t=e(\"#\"+d[0]);t&&\"none\"!==t.style.display&&(n.check()||n.close())}).on(s,\"keydown\",function(e){e=e||t.event;var a=e.keyCode;13===a&&n.elem&&n.creation([n.ymd[0],n.ymd[1]+1,n.ymd[2]])})},laydate.reset=function(){n.box&&n.elem&&n.follow(n.box)},laydate.now=function(e,t){var a=new Date(0|e?function(e){return e<864e5?+new Date+864e5*e:e}(parseInt(e)):+new Date);return n.parse([a.getFullYear(),a.getMonth()+1,a.getDate()],[a.getHours(),a.getMinutes(),a.getSeconds()],t)},layui.addcss(\"modules/laydate/laydate.css\",function(){},\"laydatecss\"),e(\"laydate\",laydate)});"
  },
  {
    "path": "public/static/layui/lay/modules/layedit.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;layui.define([\"layer\",\"form\"],function(t){\"use strict\";var e=layui.jquery,i=layui.layer,a=layui.form(),l=(layui.hint(),layui.device()),n=\"layedit\",o=\"layui-show\",r=\"layui-disabled\",s=function(){var t=this;t.index=0,t.config={tool:[\"strong\",\"italic\",\"underline\",\"del\",\"|\",\"left\",\"center\",\"right\",\"|\",\"link\",\"unlink\",\"face\",\"image\"],hideTool:[],height:280}};s.prototype.set=function(t){var i=this;return e.extend(!0,i.config,t),i},s.prototype.on=function(t,e){return layui.onevent(n,t,e)},s.prototype.build=function(t,i){i=i||{};var a=this,n=a.config,r=\"layui-layedit\",s=e(\"#\"+t),u=\"LAY_layedit_\"+ ++a.index,d=s.next(\".\"+r),y=e.extend({},n,i),f=function(){var t=[],e={};return layui.each(y.hideTool,function(t,i){e[i]=!0}),layui.each(y.tool,function(i,a){C[a]&&!e[a]&&t.push(C[a])}),t.join(\"\")}(),m=e(['<div class=\"'+r+'\">','<div class=\"layui-unselect layui-layedit-tool\">'+f+\"</div>\",'<div class=\"layui-layedit-iframe\">','<iframe id=\"'+u+'\" name=\"'+u+'\" textarea=\"'+t+'\" frameborder=\"0\"></iframe>',\"</div>\",\"</div>\"].join(\"\"));return l.ie&&l.ie<8?s.removeClass(\"layui-hide\").addClass(o):(d[0]&&d.remove(),c.call(a,m,s[0],y),s.addClass(\"layui-hide\").after(m),a.index)},s.prototype.getContent=function(t){var e=u(t);if(e[0])return d(e[0].document.body.innerHTML)},s.prototype.getText=function(t){var i=u(t);if(i[0])return e(i[0].document.body).text()},s.prototype.sync=function(t){var i=u(t);if(i[0]){var a=e(\"#\"+i[1].attr(\"textarea\"));a.val(d(i[0].document.body.innerHTML))}},s.prototype.getSelection=function(t){var e=u(t);if(e[0]){var i=m(e[0].document);return document.selection?i.text:i.toString()}};var c=function(t,i,a){var l=this,n=t.find(\"iframe\");n.css({height:a.height}).on(\"load\",function(){var o=n.contents(),r=n.prop(\"contentWindow\"),s=o.find(\"head\"),c=e([\"<style>\",\"*{margin: 0; padding: 0;}\",\"body{padding: 10px; line-height: 20px; overflow-x: hidden; word-wrap: break-word; font: 14px Helvetica Neue,Helvetica,PingFang SC,Microsoft YaHei,Tahoma,Arial,sans-serif; -webkit-box-sizing: border-box !important; -moz-box-sizing: border-box !important; box-sizing: border-box !important;}\",\"a{color:#01AAED; text-decoration:none;}a:hover{color:#c00}\",\"p{margin-bottom: 10px;}\",\"img{display: inline-block; border: none; vertical-align: middle;}\",\"pre{margin: 10px 0; padding: 10px; line-height: 20px; border: 1px solid #ddd; border-left-width: 6px; background-color: #F2F2F2; color: #333; font-family: Courier New; font-size: 12px;}\",\"</style>\"].join(\"\")),u=o.find(\"body\");s.append(c),u.attr(\"contenteditable\",\"true\").css({\"min-height\":a.height}).html(i.value||\"\"),y.apply(l,[r,n,i,a]),g.call(l,r,t,a)})},u=function(t){var i=e(\"#LAY_layedit_\"+t),a=i.prop(\"contentWindow\");return[a,i]},d=function(t){return 8==l.ie&&(t=t.replace(/<.+>/g,function(t){return t.toLowerCase()})),t},y=function(t,a,n,o){var r=t.document,s=e(r.body);s.on(\"keydown\",function(t){var e=t.keyCode;if(13===e){var a=m(r),l=p(a),n=l.parentNode;if(\"pre\"===n.tagName.toLowerCase()){if(t.shiftKey)return;return i.msg(\"请暂时用shift+enter\"),!1}r.execCommand(\"formatBlock\",!1,\"<p>\")}}),e(n).parents(\"form\").on(\"submit\",function(){var t=s.html();8==l.ie&&(t=t.replace(/<.+>/g,function(t){return t.toLowerCase()})),n.value=t}),s.on(\"paste\",function(e){r.execCommand(\"formatBlock\",!1,\"<p>\"),setTimeout(function(){f.call(t,s),n.value=s.html()},100)})},f=function(t){var i=this;i.document;t.find(\"*[style]\").each(function(){var t=this.style.textAlign;this.removeAttribute(\"style\"),e(this).css({\"text-align\":t||\"\"})}),t.find(\"table\").addClass(\"layui-table\"),t.find(\"script,link\").remove()},m=function(t){return t.selection?t.selection.createRange():t.getSelection().getRangeAt(0)},p=function(t){return t.endContainer||t.parentElement().childNodes[0]},v=function(t,i,a){var l=this.document,n=document.createElement(t);for(var o in i)n.setAttribute(o,i[o]);if(n.removeAttribute(\"text\"),l.selection){var r=a.text||i.text;if(\"a\"===t&&!r)return;r&&(n.innerHTML=r),a.pasteHTML(e(n).prop(\"outerHTML\")),a.select()}else{var r=a.toString()||i.text;if(\"a\"===t&&!r)return;r&&(n.innerHTML=r),a.deleteContents(),a.insertNode(n)}},h=function(t,i){var a=this.document,l=\"layedit-tool-active\",n=p(m(a)),o=function(e){return t.find(\".layedit-tool-\"+e)};i&&i[i.hasClass(l)?\"removeClass\":\"addClass\"](l),t.find(\">i\").removeClass(l),o(\"unlink\").addClass(r),e(n).parents().each(function(){var t=this.tagName.toLowerCase(),e=this.style.textAlign;\"b\"!==t&&\"strong\"!==t||o(\"b\").addClass(l),\"i\"!==t&&\"em\"!==t||o(\"i\").addClass(l),\"u\"===t&&o(\"u\").addClass(l),\"strike\"===t&&o(\"d\").addClass(l),\"p\"===t&&(\"center\"===e?o(\"center\").addClass(l):\"right\"===e?o(\"right\").addClass(l):o(\"left\").addClass(l)),\"a\"===t&&(o(\"link\").addClass(l),o(\"unlink\").removeClass(r))})},g=function(t,a,l){var n=t.document,o=e(n.body),s={link:function(i){var a=p(i),l=e(a).parent();b.call(o,{href:l.attr(\"href\"),target:l.attr(\"target\")},function(e){var a=l[0];\"A\"===a.tagName?a.href=e.url:v.call(t,\"a\",{target:e.target,href:e.url,text:e.url},i)})},unlink:function(t){n.execCommand(\"unlink\")},face:function(e){x.call(this,function(i){v.call(t,\"img\",{src:i.src,alt:i.alt},e)})},image:function(a){var n=this;layui.use(\"upload\",function(o){var r=l.uploadImage||{};o({url:r.url,method:r.type,elem:e(n).find(\"input\")[0],unwrap:!0,success:function(e){0==e.code?(e.data=e.data||{},v.call(t,\"img\",{src:e.data.src,alt:e.data.title},a)):i.msg(e.msg||\"上传失败\")}})})},code:function(e){k.call(o,function(i){v.call(t,\"pre\",{text:i.code,\"lay-lang\":i.lang},e)})},help:function(){i.open({type:2,title:\"帮助\",area:[\"600px\",\"380px\"],shadeClose:!0,shade:.1,skin:\"layui-layer-msg\",content:[\"http://www.layui.com/about/layedit/help.html\",\"no\"]})}},c=a.find(\".layui-layedit-tool\"),u=function(){var i=e(this),a=i.attr(\"layedit-event\"),l=i.attr(\"lay-command\");if(!i.hasClass(r)){o.focus();var u=m(n);u.commonAncestorContainer;l?(n.execCommand(l),/justifyLeft|justifyCenter|justifyRight/.test(l)&&n.execCommand(\"formatBlock\",!1,\"<p>\"),setTimeout(function(){o.focus()},10)):s[a]&&s[a].call(this,u),h.call(t,c,i)}},d=/image/;c.find(\">i\").on(\"mousedown\",function(){var t=e(this),i=t.attr(\"layedit-event\");d.test(i)||u.call(this)}).on(\"click\",function(){var t=e(this),i=t.attr(\"layedit-event\");d.test(i)&&u.call(this)}),o.on(\"click\",function(){h.call(t,c),i.close(x.index)})},b=function(t,e){var l=this,n=i.open({type:1,id:\"LAY_layedit_link\",area:\"350px\",shade:.05,shadeClose:!0,moveType:1,title:\"超链接\",skin:\"layui-layer-msg\",content:['<ul class=\"layui-form\" style=\"margin: 15px;\">','<li class=\"layui-form-item\">','<label class=\"layui-form-label\" style=\"width: 60px;\">URL</label>','<div class=\"layui-input-block\" style=\"margin-left: 90px\">','<input name=\"url\" lay-verify=\"url\" value=\"'+(t.href||\"\")+'\" autofocus=\"true\" autocomplete=\"off\" class=\"layui-input\">',\"</div>\",\"</li>\",'<li class=\"layui-form-item\">','<label class=\"layui-form-label\" style=\"width: 60px;\">打开方式</label>','<div class=\"layui-input-block\" style=\"margin-left: 90px\">','<input type=\"radio\" name=\"target\" value=\"_self\" class=\"layui-input\" title=\"当前窗口\"'+(\"_self\"!==t.target&&t.target?\"\":\"checked\")+\">\",'<input type=\"radio\" name=\"target\" value=\"_blank\" class=\"layui-input\" title=\"新窗口\" '+(\"_blank\"===t.target?\"checked\":\"\")+\">\",\"</div>\",\"</li>\",'<li class=\"layui-form-item\" style=\"text-align: center;\">','<button type=\"button\" lay-submit lay-filter=\"layedit-link-yes\" class=\"layui-btn\"> 确定 </button>','<button style=\"margin-left: 20px;\" type=\"button\" class=\"layui-btn layui-btn-primary\"> 取消 </button>',\"</li>\",\"</ul>\"].join(\"\"),success:function(t,n){var o=\"submit(layedit-link-yes)\";a.render(\"radio\"),t.find(\".layui-btn-primary\").on(\"click\",function(){i.close(n),l.focus()}),a.on(o,function(t){i.close(b.index),e&&e(t.field)})}});b.index=n},x=function(t){var a=function(){var t=[\"[微笑]\",\"[嘻嘻]\",\"[哈哈]\",\"[可爱]\",\"[可怜]\",\"[挖鼻]\",\"[吃惊]\",\"[害羞]\",\"[挤眼]\",\"[闭嘴]\",\"[鄙视]\",\"[爱你]\",\"[泪]\",\"[偷笑]\",\"[亲亲]\",\"[生病]\",\"[太开心]\",\"[白眼]\",\"[右哼哼]\",\"[左哼哼]\",\"[嘘]\",\"[衰]\",\"[委屈]\",\"[吐]\",\"[哈欠]\",\"[抱抱]\",\"[怒]\",\"[疑问]\",\"[馋嘴]\",\"[拜拜]\",\"[思考]\",\"[汗]\",\"[困]\",\"[睡]\",\"[钱]\",\"[失望]\",\"[酷]\",\"[色]\",\"[哼]\",\"[鼓掌]\",\"[晕]\",\"[悲伤]\",\"[抓狂]\",\"[黑线]\",\"[阴险]\",\"[怒骂]\",\"[互粉]\",\"[心]\",\"[伤心]\",\"[猪头]\",\"[熊猫]\",\"[兔子]\",\"[ok]\",\"[耶]\",\"[good]\",\"[NO]\",\"[赞]\",\"[来]\",\"[弱]\",\"[草泥马]\",\"[神马]\",\"[囧]\",\"[浮云]\",\"[给力]\",\"[围观]\",\"[威武]\",\"[奥特曼]\",\"[礼物]\",\"[钟]\",\"[话筒]\",\"[蜡烛]\",\"[蛋糕]\"],e={};return layui.each(t,function(t,i){e[i]=layui.cache.dir+\"images/face/\"+t+\".gif\"}),e}();return x.hide=x.hide||function(t){\"face\"!==e(t.target).attr(\"layedit-event\")&&i.close(x.index)},x.index=i.tips(function(){var t=[];return layui.each(a,function(e,i){t.push('<li title=\"'+e+'\"><img src=\"'+i+'\" alt=\"'+e+'\"></li>')}),'<ul class=\"layui-clear\">'+t.join(\"\")+\"</ul>\"}(),this,{tips:1,time:0,skin:\"layui-box layui-util-face\",maxWidth:500,success:function(l,n){l.css({marginTop:-4,marginLeft:-10}).find(\".layui-clear>li\").on(\"click\",function(){t&&t({src:a[this.title],alt:this.title}),i.close(n)}),e(document).off(\"click\",x.hide).on(\"click\",x.hide)}})},k=function(t){var e=this,l=i.open({type:1,id:\"LAY_layedit_code\",area:\"550px\",shade:.05,shadeClose:!0,moveType:1,title:\"插入代码\",skin:\"layui-layer-msg\",content:['<ul class=\"layui-form layui-form-pane\" style=\"margin: 15px;\">','<li class=\"layui-form-item\">','<label class=\"layui-form-label\">请选择语言</label>','<div class=\"layui-input-block\">','<select name=\"lang\">','<option value=\"JavaScript\">JavaScript</option>','<option value=\"HTML\">HTML</option>','<option value=\"CSS\">CSS</option>','<option value=\"Java\">Java</option>','<option value=\"PHP\">PHP</option>','<option value=\"C#\">C#</option>','<option value=\"Python\">Python</option>','<option value=\"Ruby\">Ruby</option>','<option value=\"Go\">Go</option>',\"</select>\",\"</div>\",\"</li>\",'<li class=\"layui-form-item layui-form-text\">','<label class=\"layui-form-label\">代码</label>','<div class=\"layui-input-block\">','<textarea name=\"code\" lay-verify=\"required\" autofocus=\"true\" class=\"layui-textarea\" style=\"height: 200px;\"></textarea>',\"</div>\",\"</li>\",'<li class=\"layui-form-item\" style=\"text-align: center;\">','<button type=\"button\" lay-submit lay-filter=\"layedit-code-yes\" class=\"layui-btn\"> 确定 </button>','<button style=\"margin-left: 20px;\" type=\"button\" class=\"layui-btn layui-btn-primary\"> 取消 </button>',\"</li>\",\"</ul>\"].join(\"\"),success:function(l,n){var o=\"submit(layedit-code-yes)\";a.render(\"select\"),l.find(\".layui-btn-primary\").on(\"click\",function(){i.close(n),e.focus()}),a.on(o,function(e){i.close(k.index),t&&t(e.field)})}});k.index=l},C={html:'<i class=\"layui-icon layedit-tool-html\" title=\"HTML源代码\" lay-command=\"html\" layedit-event=\"html\"\">&#xe64b;</i><span class=\"layedit-tool-mid\"></span>',strong:'<i class=\"layui-icon layedit-tool-b\" title=\"加粗\" lay-command=\"Bold\" layedit-event=\"b\"\">&#xe62b;</i>',italic:'<i class=\"layui-icon layedit-tool-i\" title=\"斜体\" lay-command=\"italic\" layedit-event=\"i\"\">&#xe644;</i>',underline:'<i class=\"layui-icon layedit-tool-u\" title=\"下划线\" lay-command=\"underline\" layedit-event=\"u\"\">&#xe646;</i>',del:'<i class=\"layui-icon layedit-tool-d\" title=\"删除线\" lay-command=\"strikeThrough\" layedit-event=\"d\"\">&#xe64f;</i>',\"|\":'<span class=\"layedit-tool-mid\"></span>',left:'<i class=\"layui-icon layedit-tool-left\" title=\"左对齐\" lay-command=\"justifyLeft\" layedit-event=\"left\"\">&#xe649;</i>',center:'<i class=\"layui-icon layedit-tool-center\" title=\"居中对齐\" lay-command=\"justifyCenter\" layedit-event=\"center\"\">&#xe647;</i>',right:'<i class=\"layui-icon layedit-tool-right\" title=\"右对齐\" lay-command=\"justifyRight\" layedit-event=\"right\"\">&#xe648;</i>',link:'<i class=\"layui-icon layedit-tool-link\" title=\"插入链接\" layedit-event=\"link\"\">&#xe64c;</i>',unlink:'<i class=\"layui-icon layedit-tool-unlink layui-disabled\" title=\"清除链接\" lay-command=\"unlink\" layedit-event=\"unlink\"\">&#xe64d;</i>',face:'<i class=\"layui-icon layedit-tool-face\" title=\"表情\" layedit-event=\"face\"\">&#xe650;</i>',image:'<i class=\"layui-icon layedit-tool-image\" title=\"图片\" layedit-event=\"image\">&#xe64a;<input type=\"file\" name=\"file\"></i>',code:'<i class=\"layui-icon layedit-tool-code\" title=\"插入代码\" layedit-event=\"code\">&#xe64e;</i>',help:'<i class=\"layui-icon layedit-tool-help\" title=\"帮助\" layedit-event=\"help\">&#xe607;</i>'},w=new s;t(n,w)});"
  },
  {
    "path": "public/static/layui/lay/modules/layer.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;!function(e,t){\"use strict\";var i,n,a=e.layui&&layui.define,o={getPath:function(){var e=document.scripts,t=e[e.length-1],i=t.src;if(!t.getAttribute(\"merge\"))return i.substring(0,i.lastIndexOf(\"/\")+1)}(),config:{},end:{},minIndex:0,minLeft:[],btn:[\"&#x786E;&#x5B9A;\",\"&#x53D6;&#x6D88;\"],type:[\"dialog\",\"page\",\"iframe\",\"loading\",\"tips\"]},r={v:\"3.0.1\",ie:function(){var t=navigator.userAgent.toLowerCase();return!!(e.ActiveXObject||\"ActiveXObject\"in e)&&((t.match(/msie\\s(\\d+)/)||[])[1]||\"11\")}(),index:e.layer&&e.layer.v?1e5:0,path:o.getPath,config:function(e,t){return e=e||{},r.cache=o.config=i.extend({},o.config,e),r.path=o.config.path||r.path,\"string\"==typeof e.extend&&(e.extend=[e.extend]),o.config.path&&r.ready(),e.extend?(a?layui.addcss(\"modules/layer/\"+e.extend):r.link(\"skin/\"+e.extend),this):this},link:function(t,n,a){if(r.path){var o=i(\"head\")[0],l=document.createElement(\"link\");\"string\"==typeof n&&(a=n);var s=(a||t).replace(/\\.|\\//g,\"\"),f=\"layuicss-\"+s,c=0;l.rel=\"stylesheet\",l.href=r.path+t,l.id=f,i(\"#\"+f)[0]||o.appendChild(l),\"function\"==typeof n&&!function d(){return++c>80?e.console&&console.error(\"layer.css: Invalid\"):void(1989===parseInt(i(\"#\"+f).css(\"width\"))?n():setTimeout(d,100))}()}},ready:function(e){var t=\"skinlayercss\",i=\"1110\";return a?layui.addcss(\"modules/layer/default/layer.css?v=\"+r.v+i,e,t):r.link(\"skin/default/layer.css?v=\"+r.v+i,e,t),this},alert:function(e,t,n){var a=\"function\"==typeof t;return a&&(n=t),r.open(i.extend({content:e,yes:n},a?{}:t))},confirm:function(e,t,n,a){var l=\"function\"==typeof t;return l&&(a=n,n=t),r.open(i.extend({content:e,btn:o.btn,yes:n,btn2:a},l?{}:t))},msg:function(e,n,a){var l=\"function\"==typeof n,f=o.config.skin,c=(f?f+\" \"+f+\"-msg\":\"\")||\"layui-layer-msg\",d=s.anim.length-1;return l&&(a=n),r.open(i.extend({content:e,time:3e3,shade:!1,skin:c,title:!1,closeBtn:!1,btn:!1,resize:!1,end:a},l&&!o.config.skin?{skin:c+\" layui-layer-hui\",anim:d}:function(){return n=n||{},(n.icon===-1||n.icon===t&&!o.config.skin)&&(n.skin=c+\" \"+(n.skin||\"layui-layer-hui\")),n}()))},load:function(e,t){return r.open(i.extend({type:3,icon:e||0,resize:!1,shade:.01},t))},tips:function(e,t,n){return r.open(i.extend({type:4,content:[e,t],closeBtn:!1,time:3e3,shade:!1,resize:!1,fixed:!1,maxWidth:210},n))}},l=function(e){var t=this;t.index=++r.index,t.config=i.extend({},t.config,o.config,e),document.body?t.creat():setTimeout(function(){t.creat()},50)};l.pt=l.prototype;var s=[\"layui-layer\",\".layui-layer-title\",\".layui-layer-main\",\".layui-layer-dialog\",\"layui-layer-iframe\",\"layui-layer-content\",\"layui-layer-btn\",\"layui-layer-close\"];s.anim=[\"layer-anim\",\"layer-anim-01\",\"layer-anim-02\",\"layer-anim-03\",\"layer-anim-04\",\"layer-anim-05\",\"layer-anim-06\"],l.pt.config={type:0,shade:.3,fixed:!0,move:s[1],title:\"&#x4FE1;&#x606F;\",offset:\"auto\",area:\"auto\",closeBtn:1,time:0,zIndex:19891014,maxWidth:360,anim:0,icon:-1,moveType:1,resize:!0,scrollbar:!0,tips:2},l.pt.vessel=function(e,t){var n=this,a=n.index,r=n.config,l=r.zIndex+a,f=\"object\"==typeof r.title,c=r.maxmin&&(1===r.type||2===r.type),d=r.title?'<div class=\"layui-layer-title\" style=\"'+(f?r.title[1]:\"\")+'\">'+(f?r.title[0]:r.title)+\"</div>\":\"\";return r.zIndex=l,t([r.shade?'<div class=\"layui-layer-shade\" id=\"layui-layer-shade'+a+'\" times=\"'+a+'\" style=\"'+(\"z-index:\"+(l-1)+\"; background-color:\"+(r.shade[1]||\"#000\")+\"; opacity:\"+(r.shade[0]||r.shade)+\"; filter:alpha(opacity=\"+(100*r.shade[0]||100*r.shade)+\");\")+'\"></div>':\"\",'<div class=\"'+s[0]+(\" layui-layer-\"+o.type[r.type])+(0!=r.type&&2!=r.type||r.shade?\"\":\" layui-layer-border\")+\" \"+(r.skin||\"\")+'\" id=\"'+s[0]+a+'\" type=\"'+o.type[r.type]+'\" times=\"'+a+'\" showtime=\"'+r.time+'\" conType=\"'+(e?\"object\":\"string\")+'\" style=\"z-index: '+l+\"; width:\"+r.area[0]+\";height:\"+r.area[1]+(r.fixed?\"\":\";position:absolute;\")+'\">'+(e&&2!=r.type?\"\":d)+'<div id=\"'+(r.id||\"\")+'\" class=\"layui-layer-content'+(0==r.type&&r.icon!==-1?\" layui-layer-padding\":\"\")+(3==r.type?\" layui-layer-loading\"+r.icon:\"\")+'\">'+(0==r.type&&r.icon!==-1?'<i class=\"layui-layer-ico layui-layer-ico'+r.icon+'\"></i>':\"\")+(1==r.type&&e?\"\":r.content||\"\")+'</div><span class=\"layui-layer-setwin\">'+function(){var e=c?'<a class=\"layui-layer-min\" href=\"javascript:;\"><cite></cite></a><a class=\"layui-layer-ico layui-layer-max\" href=\"javascript:;\"></a>':\"\";return r.closeBtn&&(e+='<a class=\"layui-layer-ico '+s[7]+\" \"+s[7]+(r.title?r.closeBtn:4==r.type?\"1\":\"2\")+'\" href=\"javascript:;\"></a>'),e}()+\"</span>\"+(r.btn?function(){var e=\"\";\"string\"==typeof r.btn&&(r.btn=[r.btn]);for(var t=0,i=r.btn.length;t<i;t++)e+='<a class=\"'+s[6]+t+'\">'+r.btn[t]+\"</a>\";return'<div class=\"'+s[6]+\" layui-layer-btn-\"+(r.btnAlign||\"\")+'\">'+e+\"</div>\"}():\"\")+(r.resize?'<span class=\"layui-layer-resize\"></span>':\"\")+\"</div>\"],d,i('<div class=\"layui-layer-move\"></div>')),n},l.pt.creat=function(){var e=this,t=e.config,a=e.index,l=t.content,f=\"object\"==typeof l,c=i(\"body\");if(!i(\"#\"+t.id)[0]){switch(\"string\"==typeof t.area&&(t.area=\"auto\"===t.area?[\"\",\"\"]:[t.area,\"\"]),t.shift&&(t.anim=t.shift),6==r.ie&&(t.fixed=!1),t.type){case 0:t.btn=\"btn\"in t?t.btn:o.btn[0],r.closeAll(\"dialog\");break;case 2:var l=t.content=f?t.content:[t.content||\"http://layer.layui.com\",\"auto\"];t.content='<iframe scrolling=\"'+(t.content[1]||\"auto\")+'\" allowtransparency=\"true\" id=\"'+s[4]+a+'\" name=\"'+s[4]+a+'\" onload=\"this.className=\\'\\';\" class=\"layui-layer-load\" frameborder=\"0\" src=\"'+t.content[0]+'\"></iframe>';break;case 3:delete t.title,delete t.closeBtn,t.icon===-1&&0===t.icon,r.closeAll(\"loading\");break;case 4:f||(t.content=[t.content,\"body\"]),t.follow=t.content[1],t.content=t.content[0]+'<i class=\"layui-layer-TipsG\"></i>',delete t.title,t.tips=\"object\"==typeof t.tips?t.tips:[t.tips,!0],t.tipsMore||r.closeAll(\"tips\")}e.vessel(f,function(n,r,d){c.append(n[0]),f?function(){2==t.type||4==t.type?function(){i(\"body\").append(n[1])}():function(){l.parents(\".\"+s[0])[0]||(l.data(\"display\",l.css(\"display\")).show().addClass(\"layui-layer-wrap\").wrap(n[1]),i(\"#\"+s[0]+a).find(\".\"+s[5]).before(r))}()}():c.append(n[1]),i(\".layui-layer-move\")[0]||c.append(o.moveElem=d),e.layero=i(\"#\"+s[0]+a),t.scrollbar||s.html.css(\"overflow\",\"hidden\").attr(\"layer-full\",a)}).auto(a),2==t.type&&6==r.ie&&e.layero.find(\"iframe\").attr(\"src\",l[0]),4==t.type?e.tips():e.offset(),t.fixed&&n.on(\"resize\",function(){e.offset(),(/^\\d+%$/.test(t.area[0])||/^\\d+%$/.test(t.area[1]))&&e.auto(a),4==t.type&&e.tips()}),t.time<=0||setTimeout(function(){r.close(e.index)},t.time),e.move().callback(),s.anim[t.anim]&&e.layero.addClass(s.anim[t.anim]).data(\"anim\",!0)}},l.pt.auto=function(e){function t(e){e=l.find(e),e.height(f[1]-c-d-2*(0|parseFloat(e.css(\"padding\"))))}var a=this,o=a.config,l=i(\"#\"+s[0]+e);\"\"===o.area[0]&&o.maxWidth>0&&(r.ie&&r.ie<8&&o.btn&&l.width(l.innerWidth()),l.outerWidth()>o.maxWidth&&l.width(o.maxWidth));var f=[l.innerWidth(),l.innerHeight()],c=l.find(s[1]).outerHeight()||0,d=l.find(\".\"+s[6]).outerHeight()||0;switch(o.type){case 2:t(\"iframe\");break;default:\"\"===o.area[1]?o.fixed&&f[1]>=n.height()&&(f[1]=n.height(),t(\".\"+s[5])):t(\".\"+s[5])}return a},l.pt.offset=function(){var e=this,t=e.config,i=e.layero,a=[i.outerWidth(),i.outerHeight()],o=\"object\"==typeof t.offset;e.offsetTop=(n.height()-a[1])/2,e.offsetLeft=(n.width()-a[0])/2,o?(e.offsetTop=t.offset[0],e.offsetLeft=t.offset[1]||e.offsetLeft):\"auto\"!==t.offset&&(\"t\"===t.offset?e.offsetTop=0:\"r\"===t.offset?e.offsetLeft=n.width()-a[0]:\"b\"===t.offset?e.offsetTop=n.height()-a[1]:\"l\"===t.offset?e.offsetLeft=0:\"lt\"===t.offset?(e.offsetTop=0,e.offsetLeft=0):\"lb\"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=0):\"rt\"===t.offset?(e.offsetTop=0,e.offsetLeft=n.width()-a[0]):\"rb\"===t.offset?(e.offsetTop=n.height()-a[1],e.offsetLeft=n.width()-a[0]):e.offsetTop=t.offset),t.fixed||(e.offsetTop=/%$/.test(e.offsetTop)?n.height()*parseFloat(e.offsetTop)/100:parseFloat(e.offsetTop),e.offsetLeft=/%$/.test(e.offsetLeft)?n.width()*parseFloat(e.offsetLeft)/100:parseFloat(e.offsetLeft),e.offsetTop+=n.scrollTop(),e.offsetLeft+=n.scrollLeft()),i.attr(\"minLeft\")&&(e.offsetTop=n.height()-(i.find(s[1]).outerHeight()||0),e.offsetLeft=i.css(\"left\")),i.css({top:e.offsetTop,left:e.offsetLeft})},l.pt.tips=function(){var e=this,t=e.config,a=e.layero,o=[a.outerWidth(),a.outerHeight()],r=i(t.follow);r[0]||(r=i(\"body\"));var l={width:r.outerWidth(),height:r.outerHeight(),top:r.offset().top,left:r.offset().left},f=a.find(\".layui-layer-TipsG\"),c=t.tips[0];t.tips[1]||f.remove(),l.autoLeft=function(){l.left+o[0]-n.width()>0?(l.tipLeft=l.left+l.width-o[0],f.css({right:12,left:\"auto\"})):l.tipLeft=l.left},l.where=[function(){l.autoLeft(),l.tipTop=l.top-o[1]-10,f.removeClass(\"layui-layer-TipsB\").addClass(\"layui-layer-TipsT\").css(\"border-right-color\",t.tips[1])},function(){l.tipLeft=l.left+l.width+10,l.tipTop=l.top,f.removeClass(\"layui-layer-TipsL\").addClass(\"layui-layer-TipsR\").css(\"border-bottom-color\",t.tips[1])},function(){l.autoLeft(),l.tipTop=l.top+l.height+10,f.removeClass(\"layui-layer-TipsT\").addClass(\"layui-layer-TipsB\").css(\"border-right-color\",t.tips[1])},function(){l.tipLeft=l.left-o[0]-10,l.tipTop=l.top,f.removeClass(\"layui-layer-TipsR\").addClass(\"layui-layer-TipsL\").css(\"border-bottom-color\",t.tips[1])}],l.where[c-1](),1===c?l.top-(n.scrollTop()+o[1]+16)<0&&l.where[2]():2===c?n.width()-(l.left+l.width+o[0]+16)>0||l.where[3]():3===c?l.top-n.scrollTop()+l.height+o[1]+16-n.height()>0&&l.where[0]():4===c&&o[0]+16-l.left>0&&l.where[1](),a.find(\".\"+s[5]).css({\"background-color\":t.tips[1],\"padding-right\":t.closeBtn?\"30px\":\"\"}),a.css({left:l.tipLeft-(t.fixed?n.scrollLeft():0),top:l.tipTop-(t.fixed?n.scrollTop():0)})},l.pt.move=function(){var e=this,t=e.config,a=i(document),l=e.layero,s=l.find(t.move),f=l.find(\".layui-layer-resize\"),c={};return t.move&&s.css(\"cursor\",\"move\"),s.on(\"mousedown\",function(e){e.preventDefault(),t.move&&(c.moveStart=!0,c.offset=[e.clientX-parseFloat(l.css(\"left\")),e.clientY-parseFloat(l.css(\"top\"))],o.moveElem.css(\"cursor\",\"move\").show())}),f.on(\"mousedown\",function(e){e.preventDefault(),c.resizeStart=!0,c.offset=[e.clientX,e.clientY],c.area=[l.outerWidth(),l.outerHeight()],o.moveElem.css(\"cursor\",\"se-resize\").show()}),a.on(\"mousemove\",function(i){if(c.moveStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1],s=\"fixed\"===l.css(\"position\");if(i.preventDefault(),c.stX=s?0:n.scrollLeft(),c.stY=s?0:n.scrollTop(),!t.moveOut){var f=n.width()-l.outerWidth()+c.stX,d=n.height()-l.outerHeight()+c.stY;a<c.stX&&(a=c.stX),a>f&&(a=f),o<c.stY&&(o=c.stY),o>d&&(o=d)}l.css({left:a,top:o})}if(t.resize&&c.resizeStart){var a=i.clientX-c.offset[0],o=i.clientY-c.offset[1];i.preventDefault(),r.style(e.index,{width:c.area[0]+a,height:c.area[1]+o}),c.isResize=!0}}).on(\"mouseup\",function(e){c.moveStart&&(delete c.moveStart,o.moveElem.hide(),t.moveEnd&&t.moveEnd()),c.resizeStart&&(delete c.resizeStart,o.moveElem.hide())}),e},l.pt.callback=function(){function e(){var e=a.cancel&&a.cancel(t.index,n);e===!1||r.close(t.index)}var t=this,n=t.layero,a=t.config;t.openLayer(),a.success&&(2==a.type?n.find(\"iframe\").on(\"load\",function(){a.success(n,t.index)}):a.success(n,t.index)),6==r.ie&&t.IE6(n),n.find(\".\"+s[6]).children(\"a\").on(\"click\",function(){var e=i(this).index();if(0===e)a.yes?a.yes(t.index,n):a.btn1?a.btn1(t.index,n):r.close(t.index);else{var o=a[\"btn\"+(e+1)]&&a[\"btn\"+(e+1)](t.index,n);o===!1||r.close(t.index)}}),n.find(\".\"+s[7]).on(\"click\",e),a.shadeClose&&i(\"#layui-layer-shade\"+t.index).on(\"click\",function(){r.close(t.index)}),n.find(\".layui-layer-min\").on(\"click\",function(){var e=a.min&&a.min(n);e===!1||r.min(t.index,a)}),n.find(\".layui-layer-max\").on(\"click\",function(){i(this).hasClass(\"layui-layer-maxmin\")?(r.restore(t.index),a.restore&&a.restore(n)):(r.full(t.index,a),setTimeout(function(){a.full&&a.full(n)},100))}),a.end&&(o.end[t.index]=a.end)},o.reselect=function(){i.each(i(\"select\"),function(e,t){var n=i(this);n.parents(\".\"+s[0])[0]||1==n.attr(\"layer\")&&i(\".\"+s[0]).length<1&&n.removeAttr(\"layer\").show(),n=null})},l.pt.IE6=function(e){i(\"select\").each(function(e,t){var n=i(this);n.parents(\".\"+s[0])[0]||\"none\"===n.css(\"display\")||n.attr({layer:\"1\"}).hide(),n=null})},l.pt.openLayer=function(){var e=this;r.zIndex=e.config.zIndex,r.setTop=function(e){var t=function(){r.zIndex++,e.css(\"z-index\",r.zIndex+1)};return r.zIndex=parseInt(e[0].style.zIndex),e.on(\"mousedown\",t),r.zIndex}},o.record=function(e){var t=[e.width(),e.height(),e.position().top,e.position().left+parseFloat(e.css(\"margin-left\"))];e.find(\".layui-layer-max\").addClass(\"layui-layer-maxmin\"),e.attr({area:t})},o.rescollbar=function(e){s.html.attr(\"layer-full\")==e&&(s.html[0].style.removeProperty?s.html[0].style.removeProperty(\"overflow\"):s.html[0].style.removeAttribute(\"overflow\"),s.html.removeAttr(\"layer-full\"))},e.layer=r,r.getChildFrame=function(e,t){return t=t||i(\".\"+s[4]).attr(\"times\"),i(\"#\"+s[0]+t).find(\"iframe\").contents().find(e)},r.getFrameIndex=function(e){return i(\"#\"+e).parents(\".\"+s[4]).attr(\"times\")},r.iframeAuto=function(e){if(e){var t=r.getChildFrame(\"html\",e).outerHeight(),n=i(\"#\"+s[0]+e),a=n.find(s[1]).outerHeight()||0,o=n.find(\".\"+s[6]).outerHeight()||0;n.css({height:t+a+o}),n.find(\"iframe\").css({height:t})}},r.iframeSrc=function(e,t){i(\"#\"+s[0]+e).find(\"iframe\").attr(\"src\",t)},r.style=function(e,t,n){var a=i(\"#\"+s[0]+e),r=a.find(\".layui-layer-content\"),l=a.attr(\"type\"),f=a.find(s[1]).outerHeight()||0,c=a.find(\".\"+s[6]).outerHeight()||0;a.attr(\"minLeft\");l!==o.type[3]&&l!==o.type[4]&&(n||(parseFloat(t.width)<=260&&(t.width=260),parseFloat(t.height)-f-c<=64&&(t.height=64+f+c)),a.css(t),c=a.find(\".\"+s[6]).outerHeight(),l===o.type[2]?a.find(\"iframe\").css({height:parseFloat(t.height)-f-c}):r.css({height:parseFloat(t.height)-f-c-parseFloat(r.css(\"padding-top\"))-parseFloat(r.css(\"padding-bottom\"))}))},r.min=function(e,t){var a=i(\"#\"+s[0]+e),l=a.find(s[1]).outerHeight()||0,f=a.attr(\"minLeft\")||181*o.minIndex+\"px\",c=a.css(\"position\");o.record(a),o.minLeft[0]&&(f=o.minLeft[0],o.minLeft.shift()),a.attr(\"position\",c),r.style(e,{width:180,height:l,left:f,top:n.height()-l,position:\"fixed\",overflow:\"hidden\"},!0),a.find(\".layui-layer-min\").hide(),\"page\"===a.attr(\"type\")&&a.find(s[4]).hide(),o.rescollbar(e),a.attr(\"minLeft\")||o.minIndex++,a.attr(\"minLeft\",f)},r.restore=function(e){var t=i(\"#\"+s[0]+e),n=t.attr(\"area\").split(\",\");t.attr(\"type\");r.style(e,{width:parseFloat(n[0]),height:parseFloat(n[1]),top:parseFloat(n[2]),left:parseFloat(n[3]),position:t.attr(\"position\"),overflow:\"visible\"},!0),t.find(\".layui-layer-max\").removeClass(\"layui-layer-maxmin\"),t.find(\".layui-layer-min\").show(),\"page\"===t.attr(\"type\")&&t.find(s[4]).show(),o.rescollbar(e)},r.full=function(e){var t,a=i(\"#\"+s[0]+e);o.record(a),s.html.attr(\"layer-full\")||s.html.css(\"overflow\",\"hidden\").attr(\"layer-full\",e),clearTimeout(t),t=setTimeout(function(){var t=\"fixed\"===a.css(\"position\");r.style(e,{top:t?0:n.scrollTop(),left:t?0:n.scrollLeft(),width:n.width(),height:n.height()},!0),a.find(\".layui-layer-min\").hide()},100)},r.title=function(e,t){var n=i(\"#\"+s[0]+(t||r.index)).find(s[1]);n.html(e)},r.close=function(e){var t=i(\"#\"+s[0]+e),n=t.attr(\"type\"),a=\"layer-anim-close\";if(t[0]){var l=\"layui-layer-wrap\",f=function(){if(n===o.type[1]&&\"object\"===t.attr(\"conType\")){t.children(\":not(.\"+s[5]+\")\").remove();for(var a=t.find(\".\"+l),r=0;r<2;r++)a.unwrap();a.css(\"display\",a.data(\"display\")).removeClass(l)}else{if(n===o.type[2])try{var f=i(\"#\"+s[4]+e)[0];f.contentWindow.document.write(\"\"),f.contentWindow.close(),t.find(\".\"+s[5])[0].removeChild(f)}catch(c){}t[0].innerHTML=\"\",t.remove()}\"function\"==typeof o.end[e]&&o.end[e](),delete o.end[e]};t.data(\"anim\")&&t.addClass(a),i(\"#layui-layer-moves, #layui-layer-shade\"+e).remove(),6==r.ie&&o.reselect(),o.rescollbar(e),t.attr(\"minLeft\")&&(o.minIndex--,o.minLeft.push(t.attr(\"minLeft\"))),setTimeout(function(){f()},r.ie&&r.ie<10||!t.data(\"anim\")?0:200)}},r.closeAll=function(e){i.each(i(\".\"+s[0]),function(){var t=i(this),n=e?t.attr(\"type\")===e:1;n&&r.close(t.attr(\"times\")),n=null})};var f=r.cache||{},c=function(e){return f.skin?\" \"+f.skin+\" \"+f.skin+\"-\"+e:\"\"};r.prompt=function(e,t){var a=\"\";if(e=e||{},\"function\"==typeof e&&(t=e),e.area){var o=e.area;a='style=\"width: '+o[0]+\"; height: \"+o[1]+';\"',delete e.area}var l,s=2==e.formType?'<textarea class=\"layui-layer-input\"'+a+\">\"+(e.value||\"\")+\"</textarea>\":function(){return'<input type=\"'+(1==e.formType?\"password\":\"text\")+'\" class=\"layui-layer-input\" value=\"'+(e.value||\"\")+'\">'}();return r.open(i.extend({type:1,btn:[\"&#x786E;&#x5B9A;\",\"&#x53D6;&#x6D88;\"],content:s,skin:\"layui-layer-prompt\"+c(\"prompt\"),maxWidth:n.width(),success:function(e){l=e.find(\".layui-layer-input\"),l.focus()},resize:!1,yes:function(i){var n=l.val();\"\"===n?l.focus():n.length>(e.maxlength||500)?r.tips(\"&#x6700;&#x591A;&#x8F93;&#x5165;\"+(e.maxlength||500)+\"&#x4E2A;&#x5B57;&#x6570;\",l,{tips:1}):t&&t(n,i,l)}},e))},r.tab=function(e){e=e||{};var t=e.tab||{};return r.open(i.extend({type:1,skin:\"layui-layer-tab\"+c(\"tab\"),resize:!1,title:function(){var e=t.length,i=1,n=\"\";if(e>0)for(n='<span class=\"layui-layer-tabnow\">'+t[0].title+\"</span>\";i<e;i++)n+=\"<span>\"+t[i].title+\"</span>\";return n}(),content:'<ul class=\"layui-layer-tabmain\">'+function(){var e=t.length,i=1,n=\"\";if(e>0)for(n='<li class=\"layui-layer-tabli xubox_tab_layer\">'+(t[0].content||\"no content\")+\"</li>\";i<e;i++)n+='<li class=\"layui-layer-tabli\">'+(t[i].content||\"no  content\")+\"</li>\";return n}()+\"</ul>\",success:function(t){var n=t.find(\".layui-layer-title\").children(),a=t.find(\".layui-layer-tabmain\").children();n.on(\"mousedown\",function(t){t.stopPropagation?t.stopPropagation():t.cancelBubble=!0;var n=i(this),o=n.index();n.addClass(\"layui-layer-tabnow\").siblings().removeClass(\"layui-layer-tabnow\"),a.eq(o).show().siblings().hide(),\"function\"==typeof e.change&&e.change(o)})}},e))},r.photos=function(t,n,a){function o(e,t,i){var n=new Image;return n.src=e,n.complete?t(n):(n.onload=function(){n.onload=null,t(n)},void(n.onerror=function(e){n.onerror=null,i(e)}))}var l={};if(t=t||{},t.photos){var s=t.photos.constructor===Object,f=s?t.photos:{},d=f.data||[],u=f.start||0;if(l.imgIndex=(0|u)+1,t.img=t.img||\"img\",s){if(0===d.length)return r.msg(\"&#x6CA1;&#x6709;&#x56FE;&#x7247;\")}else{var y=i(t.photos),p=function(){d=[],y.find(t.img).each(function(e){var t=i(this);t.attr(\"layer-index\",e),d.push({alt:t.attr(\"alt\"),pid:t.attr(\"layer-pid\"),src:t.attr(\"layer-src\")||t.attr(\"src\"),thumb:t.attr(\"src\")})})};if(p(),0===d.length)return;if(n||y.on(\"click\",t.img,function(){var e=i(this),n=e.attr(\"layer-index\");r.photos(i.extend(t,{photos:{start:n,data:d,tab:t.tab},full:t.full}),!0),p()}),!n)return}l.imgprev=function(e){l.imgIndex--,l.imgIndex<1&&(l.imgIndex=d.length),l.tabimg(e)},l.imgnext=function(e,t){l.imgIndex++,l.imgIndex>d.length&&(l.imgIndex=1,t)||l.tabimg(e)},l.keyup=function(e){if(!l.end){var t=e.keyCode;e.preventDefault(),37===t?l.imgprev(!0):39===t?l.imgnext(!0):27===t&&r.close(l.index)}},l.tabimg=function(e){d.length<=1||(f.start=l.imgIndex-1,r.close(l.index),r.photos(t,!0,e))},l.event=function(){l.bigimg.hover(function(){l.imgsee.show()},function(){l.imgsee.hide()}),l.bigimg.find(\".layui-layer-imgprev\").on(\"click\",function(e){e.preventDefault(),l.imgprev()}),l.bigimg.find(\".layui-layer-imgnext\").on(\"click\",function(e){e.preventDefault(),l.imgnext()}),i(document).on(\"keyup\",l.keyup)},l.loadi=r.load(1,{shade:!(\"shade\"in t)&&.9,scrollbar:!1}),o(d[u].src,function(n){r.close(l.loadi),l.index=r.open(i.extend({type:1,area:function(){var a=[n.width,n.height],o=[i(e).width()-100,i(e).height()-100];if(!t.full&&(a[0]>o[0]||a[1]>o[1])){var r=[a[0]/o[0],a[1]/o[1]];r[0]>r[1]?(a[0]=a[0]/r[0],a[1]=a[1]/r[0]):r[0]<r[1]&&(a[0]=a[0]/r[1],a[1]=a[1]/r[1])}return[a[0]+\"px\",a[1]+\"px\"]}(),title:!1,shade:.9,shadeClose:!0,closeBtn:!1,move:\".layui-layer-phimg img\",moveType:1,scrollbar:!1,moveOut:!0,anim:5*Math.random()|0,skin:\"layui-layer-photos\"+c(\"photos\"),content:'<div class=\"layui-layer-phimg\"><img src=\"'+d[u].src+'\" alt=\"'+(d[u].alt||\"\")+'\" layer-pid=\"'+d[u].pid+'\"><div class=\"layui-layer-imgsee\">'+(d.length>1?'<span class=\"layui-layer-imguide\"><a href=\"javascript:;\" class=\"layui-layer-iconext layui-layer-imgprev\"></a><a href=\"javascript:;\" class=\"layui-layer-iconext layui-layer-imgnext\"></a></span>':\"\")+'<div class=\"layui-layer-imgbar\" style=\"display:'+(a?\"block\":\"\")+'\"><span class=\"layui-layer-imgtit\"><a href=\"javascript:;\">'+(d[u].alt||\"\")+\"</a><em>\"+l.imgIndex+\"/\"+d.length+\"</em></span></div></div></div>\",success:function(e,i){l.bigimg=e.find(\".layui-layer-phimg\"),l.imgsee=e.find(\".layui-layer-imguide,.layui-layer-imgbar\"),l.event(e),t.tab&&t.tab(d[u],e)},end:function(){l.end=!0,i(document).off(\"keyup\",l.keyup)}},t))},function(){r.close(l.loadi),r.msg(\"&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;<br>&#x662F;&#x5426;&#x7EE7;&#x7EED;&#x67E5;&#x770B;&#x4E0B;&#x4E00;&#x5F20;&#xFF1F;\",{time:3e4,btn:[\"&#x4E0B;&#x4E00;&#x5F20;\",\"&#x4E0D;&#x770B;&#x4E86;\"],yes:function(){d.length>1&&l.imgnext(!0,!0)}})})}},o.run=function(t){i=t,n=i(e),s.html=i(\"html\"),r.open=function(e){var t=new l(e);return t.index}},e.layui&&layui.define?(r.ready(),layui.define(\"jquery\",function(t){r.path=layui.cache.dir,o.run(layui.jquery),e.layer=r,t(\"layer\",r)})):\"function\"==typeof define?define([\"jquery\"],function(){return o.run(e.jQuery),r}):function(){o.run(e.jQuery),r.ready()}()}(window);"
  },
  {
    "path": "public/static/layui/lay/modules/laypage.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;layui.define(function(a){\"use strict\";function t(a){new p(a)}var e=document,r=\"getElementById\",n=\"getElementsByTagName\",s=0,p=function(a){var t=this,e=t.config=a||{};e.item=s++,t.render(!0)};p.on=function(a,t,e){return a.attachEvent?a.attachEvent(\"on\"+t,function(){e.call(a,window.even)}):a.addEventListener(t,e,!1),p},p.prototype.type=function(){var a=this.config;if(\"object\"==typeof a.cont)return void 0===a.cont.length?2:3},p.prototype.view=function(){var a=this,t=a.config,e=[],r={};if(t.pages=0|t.pages,t.curr=0|t.curr||1,t.groups=\"groups\"in t?0|t.groups:5,t.first=\"first\"in t?t.first:\"&#x9996;&#x9875;\",t.last=\"last\"in t?t.last:\"&#x672B;&#x9875;\",t.prev=\"prev\"in t?t.prev:\"&#x4E0A;&#x4E00;&#x9875;\",t.next=\"next\"in t?t.next:\"&#x4E0B;&#x4E00;&#x9875;\",t.pages<=1)return\"\";for(t.groups>t.pages&&(t.groups=t.pages),r.index=Math.ceil((t.curr+(t.groups>1&&t.groups!==t.pages?1:0))/(0===t.groups?1:t.groups)),t.curr>1&&t.prev&&e.push('<a href=\"javascript:;\" class=\"layui-laypage-prev\" data-page=\"'+(t.curr-1)+'\">'+t.prev+\"</a>\"),r.index>1&&t.first&&0!==t.groups&&e.push('<a href=\"javascript:;\" class=\"laypage_first\" data-page=\"1\"  title=\"&#x9996;&#x9875;\">'+t.first+\"</a><span>&#x2026;</span>\"),r.poor=Math.floor((t.groups-1)/2),r.start=r.index>1?t.curr-r.poor:1,r.end=r.index>1?function(){var a=t.curr+(t.groups-r.poor-1);return a>t.pages?t.pages:a}():t.groups,r.end-r.start<t.groups-1&&(r.start=r.end-t.groups+1);r.start<=r.end;r.start++)r.start===t.curr?e.push('<span class=\"layui-laypage-curr\"><em class=\"layui-laypage-em\" '+(/^#/.test(t.skin)?'style=\"background-color:'+t.skin+';\"':\"\")+\"></em><em>\"+r.start+\"</em></span>\"):e.push('<a href=\"javascript:;\" data-page=\"'+r.start+'\">'+r.start+\"</a>\");return t.pages>t.groups&&r.end<t.pages&&t.last&&0!==t.groups&&e.push('<span>&#x2026;</span><a href=\"javascript:;\" class=\"layui-laypage-last\" title=\"&#x5C3E;&#x9875;\"  data-page=\"'+t.pages+'\">'+t.last+\"</a>\"),r.flow=!t.prev&&0===t.groups,(t.curr!==t.pages&&t.next||r.flow)&&e.push(function(){return r.flow&&t.curr===t.pages?'<span class=\"layui-laypage-nomore\" title=\"&#x5DF2;&#x6CA1;&#x6709;&#x66F4;&#x591A;\">'+t.next+\"</span>\":'<a href=\"javascript:;\" class=\"layui-laypage-next\" data-page=\"'+(t.curr+1)+'\">'+t.next+\"</a>\"}()),'<div class=\"layui-box layui-laypage layui-laypage-'+(t.skin?function(a){return/^#/.test(a)?\"molv\":a}(t.skin):\"default\")+'\" id=\"layui-laypage-'+a.config.item+'\">'+e.join(\"\")+function(){return t.skip?'<span class=\"layui-laypage-total\">&#x5230;&#x7B2C; <input type=\"number\" min=\"1\" onkeyup=\"this.value=this.value.replace(/\\\\D/, \\'\\');\" value=\"'+t.curr+'\" class=\"layui-laypage-skip\"> &#x9875; <button type=\"button\" class=\"layui-laypage-btn\">&#x786e;&#x5b9a;</button></span>':\"\"}()+\"</div>\"},p.prototype.jump=function(a){if(a){for(var t=this,e=t.config,r=a.children,s=a[n](\"button\")[0],i=a[n](\"input\")[0],u=0,o=r.length;u<o;u++)\"a\"===r[u].nodeName.toLowerCase()&&p.on(r[u],\"click\",function(){var a=0|this.getAttribute(\"data-page\");e.curr=a,t.render()});s&&p.on(s,\"click\",function(){var a=0|i.value.replace(/\\s|\\D/g,\"\");a&&a<=e.pages&&(e.curr=a,t.render())})}},p.prototype.render=function(a){var t=this,n=t.config,s=t.type(),p=t.view();2===s?n.cont.innerHTML=p:3===s?n.cont.html(p):e[r](n.cont).innerHTML=p,n.jump&&n.jump(n,a),t.jump(e[r](\"layui-laypage-\"+n.item)),n.hash&&!a&&(location.hash=\"!\"+n.hash+\"=\"+n.curr)},a(\"laypage\",t)});"
  },
  {
    "path": "public/static/layui/lay/modules/laytpl.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;layui.define(function(e){\"use strict\";var r={open:\"{{\",close:\"}}\"},n={exp:function(e){return new RegExp(e,\"g\")},query:function(e,n,t){var o=[\"#([\\\\s\\\\S])+?\",\"([^{#}])*?\"][e||0];return c((n||\"\")+r.open+o+r.close+(t||\"\"))},escape:function(e){return String(e||\"\").replace(/&(?!#?[a-zA-Z0-9]+;)/g,\"&amp;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\").replace(/'/g,\"&#39;\").replace(/\"/g,\"&quot;\")},error:function(e,r){var n=\"Laytpl Error：\";return\"object\"==typeof console&&console.error(n+e+\"\\n\"+(r||\"\")),n+e}},c=n.exp,t=function(e){this.tpl=e};t.pt=t.prototype,window.errors=0,t.pt.parse=function(e,t){var o=this,p=e,a=c(\"^\"+r.open+\"#\",\"\"),l=c(r.close+\"$\",\"\");e=e.replace(/\\s+|\\r|\\t|\\n/g,\" \").replace(c(r.open+\"#\"),r.open+\"# \").replace(c(r.close+\"}\"),\"} \"+r.close).replace(/\\\\/g,\"\\\\\\\\\").replace(/(?=\"|')/g,\"\\\\\").replace(n.query(),function(e){return e=e.replace(a,\"\").replace(l,\"\"),'\";'+e.replace(/\\\\/g,\"\")+';view+=\"'}).replace(n.query(1),function(e){var n='\"+(';return e.replace(/\\s/g,\"\")===r.open+r.close?\"\":(e=e.replace(c(r.open+\"|\"+r.close),\"\"),/^=/.test(e)&&(e=e.replace(/^=/,\"\"),n='\"+_escape_('),n+e.replace(/\\\\/g,\"\")+')+\"')}),e='\"use strict\";var view = \"'+e+'\";return view;';try{return o.cache=e=new Function(\"d, _escape_\",e),e(t,n.escape)}catch(u){return delete o.cache,n.error(u,p)}},t.pt.render=function(e,r){var c,t=this;return e?(c=t.cache?t.cache(e,n.escape):t.parse(t.tpl,e),r?void r(c):c):n.error(\"no data\")};var o=function(e){return\"string\"!=typeof e?n.error(\"Template not found\"):new t(e)};o.config=function(e){e=e||{};for(var n in e)r[n]=e[n]},o.v=\"1.2.0\",e(\"laytpl\",o)});"
  },
  {
    "path": "public/static/layui/lay/modules/tree.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;layui.define(\"jquery\",function(e){\"use strict\";var o=layui.jquery,a=layui.hint(),r=\"layui-tree-enter\",i=function(e){this.options=e},t={arrow:[\"&#xe623;\",\"&#xe625;\"],checkbox:[\"&#xe626;\",\"&#xe627;\"],radio:[\"&#xe62b;\",\"&#xe62a;\"],branch:[\"&#xe622;\",\"&#xe624;\"],leaf:\"&#xe621;\"};i.prototype.init=function(e){var o=this;e.addClass(\"layui-box layui-tree\"),o.options.skin&&e.addClass(\"layui-tree-skin-\"+o.options.skin),o.tree(e),o.on(e)},i.prototype.tree=function(e,a){var r=this,i=r.options,n=a||i.nodes;layui.each(n,function(a,n){var l=n.children&&n.children.length>0,c=o('<ul class=\"'+(n.spread?\"layui-show\":\"\")+'\"></ul>'),s=o([\"<li \"+(n.spread?'data-spread=\"'+n.spread+'\"':\"\")+\">\",function(){return l?'<i class=\"layui-icon layui-tree-spread\">'+(n.spread?t.arrow[1]:t.arrow[0])+\"</i>\":\"\"}(),function(){return i.check?'<i class=\"layui-icon layui-tree-check\">'+(\"checkbox\"===i.check?t.checkbox[0]:\"radio\"===i.check?t.radio[0]:\"\")+\"</i>\":\"\"}(),function(){return'<a href=\"'+(n.href||\"javascript:;\")+'\" '+(i.target&&n.href?'target=\"'+i.target+'\"':\"\")+\">\"+('<i class=\"layui-icon layui-tree-'+(l?\"branch\":\"leaf\")+'\">'+(l?n.spread?t.branch[1]:t.branch[0]:t.leaf)+\"</i>\")+(\"<cite>\"+(n.name||\"未命名\")+\"</cite></a>\")}(),\"</li>\"].join(\"\"));l&&(s.append(c),r.tree(c,n.children)),e.append(s),\"function\"==typeof i.click&&r.click(s,n),r.spread(s,n),i.drag&&r.drag(s,n)})},i.prototype.click=function(e,o){var a=this,r=a.options;e.children(\"a\").on(\"click\",function(e){layui.stope(e),r.click(o)})},i.prototype.spread=function(e,o){var a=this,r=(a.options,e.children(\".layui-tree-spread\")),i=e.children(\"ul\"),n=e.children(\"a\"),l=function(){e.data(\"spread\")?(e.data(\"spread\",null),i.removeClass(\"layui-show\"),r.html(t.arrow[0]),n.find(\".layui-icon\").html(t.branch[0])):(e.data(\"spread\",!0),i.addClass(\"layui-show\"),r.html(t.arrow[1]),n.find(\".layui-icon\").html(t.branch[1]))};i[0]&&(r.on(\"click\",l),n.on(\"dblclick\",l))},i.prototype.on=function(e){var a=this,i=a.options,t=\"layui-tree-drag\";e.find(\"i\").on(\"selectstart\",function(e){return!1}),i.drag&&o(document).on(\"mousemove\",function(e){var r=a.move;if(r.from){var i=(r.to,o('<div class=\"layui-box '+t+'\"></div>'));e.preventDefault(),o(\".\"+t)[0]||o(\"body\").append(i);var n=o(\".\"+t)[0]?o(\".\"+t):i;n.addClass(\"layui-show\").html(r.from.elem.children(\"a\").html()),n.css({left:e.pageX+10,top:e.pageY+10})}}).on(\"mouseup\",function(){var e=a.move;e.from&&(e.from.elem.children(\"a\").removeClass(r),e.to&&e.to.elem.children(\"a\").removeClass(r),a.move={},o(\".\"+t).remove())})},i.prototype.move={},i.prototype.drag=function(e,a){var i=this,t=(i.options,e.children(\"a\")),n=function(){var t=o(this),n=i.move;n.from&&(n.to={item:a,elem:e},t.addClass(r))};t.on(\"mousedown\",function(){var o=i.move;o.from={item:a,elem:e}}),t.on(\"mouseenter\",n).on(\"mousemove\",n).on(\"mouseleave\",function(){var e=o(this),a=i.move;a.from&&(delete a.to,e.removeClass(r))})},e(\"tree\",function(e){var r=new i(e=e||{}),t=o(e.elem);return t[0]?void r.init(t):a.error(\"layui.tree 没有找到\"+e.elem+\"元素\")})});"
  },
  {
    "path": "public/static/layui/lay/modules/upload.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;layui.define(\"layer\",function(e){\"use strict\";var a=layui.jquery,t=layui.layer,i=(layui.device(),\"layui-upload-enter\"),n=\"layui-upload-iframe\",r={icon:2,shift:6},o={file:\"文件\",video:\"视频\",audio:\"音频\"},s=function(e){this.options=e};s.prototype.init=function(){var e=this,t=e.options,r=a(\"body\"),s=a(t.elem||\".layui-upload-file\"),u=a('<iframe id=\"'+n+'\" class=\"'+n+'\" name=\"'+n+'\"></iframe>');return a(\"#\"+n)[0]||r.append(u),s.each(function(r,s){s=a(s);var u='<form target=\"'+n+'\" method=\"'+(t.method||\"post\")+'\" key=\"set-mine\" enctype=\"multipart/form-data\" action=\"'+(t.url||\"\")+'\"></form>',l=s.attr(\"lay-type\")||t.type;t.unwrap||(u='<div class=\"layui-box layui-upload-button\">'+u+'<span class=\"layui-upload-icon\"><i class=\"layui-icon\">&#xe608;</i>'+(s.attr(\"lay-title\")||t.title||\"上传\"+(o[l]||\"图片\"))+\"</span></div>\"),u=a(u),t.unwrap||u.on(\"dragover\",function(e){e.preventDefault(),a(this).addClass(i)}).on(\"dragleave\",function(){a(this).removeClass(i)}).on(\"drop\",function(){a(this).removeClass(i)}),s.parent(\"form\").attr(\"target\")===n&&(t.unwrap?s.unwrap():(s.parent().next().remove(),s.unwrap().unwrap())),s.wrap(u),s.off(\"change\").on(\"change\",function(){e.action(this,l)})})},s.prototype.action=function(e,i){var o=this,s=o.options,u=e.value,l=a(e),p=l.attr(\"lay-ext\")||s.ext||\"\";if(u){switch(i){case\"file\":if(p&&!RegExp(\"\\\\w\\\\.(\"+p+\")$\",\"i\").test(escape(u)))return t.msg(\"不支持该文件格式\",r),e.value=\"\";break;case\"video\":if(!RegExp(\"\\\\w\\\\.(\"+(p||\"avi|mp4|wma|rmvb|rm|flash|3gp|flv\")+\")$\",\"i\").test(escape(u)))return t.msg(\"不支持该视频格式\",r),e.value=\"\";break;case\"audio\":if(!RegExp(\"\\\\w\\\\.(\"+(p||\"mp3|wav|mid\")+\")$\",\"i\").test(escape(u)))return t.msg(\"不支持该音频格式\",r),e.value=\"\";break;default:if(!RegExp(\"\\\\w\\\\.(\"+(p||\"jpg|png|gif|bmp|jpeg\")+\")$\",\"i\").test(escape(u)))return t.msg(\"不支持该图片格式\",r),e.value=\"\"}s.before&&s.before(e),l.parent().submit();var c=a(\"#\"+n),f=setInterval(function(){var a;try{a=c.contents().find(\"body\").text()}catch(i){t.msg(\"上传接口存在跨域\",r),clearInterval(f)}if(a){clearInterval(f),c.contents().find(\"body\").html(\"\");try{a=JSON.parse(a)}catch(i){return a={},t.msg(\"请对上传接口返回JSON字符\",r)}\"function\"==typeof s.success&&s.success(a,e)}},30);e.value=\"\"}},e(\"upload\",function(e){var a=new s(e=e||{});a.init()})});"
  },
  {
    "path": "public/static/layui/lay/modules/util.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;layui.define(\"jquery\",function(l){\"use strict\";var o=layui.jquery,i={fixbar:function(l){l=l||{},l.bgcolor=l.bgcolor?\"background-color:\"+l.bgcolor:\"\";var i,a,c=\"layui-fixbar-top\",t=[l.bar1===!0?\"&#xe606;\":l.bar1,l.bar2===!0?\"&#xe607;\":l.bar2,\"&#xe604;\"],r=o(['<ul class=\"layui-fixbar\">',l.bar1?'<li class=\"layui-icon\" lay-type=\"bar1\" style=\"'+l.bgcolor+'\">'+t[0]+\"</li>\":\"\",l.bar2?'<li class=\"layui-icon\" lay-type=\"bar2\" style=\"'+l.bgcolor+'\">'+t[1]+\"</li>\":\"\",'<li class=\"layui-icon '+c+'\" lay-type=\"top\" style=\"'+l.bgcolor+'\">'+t[2]+\"</li>\",\"</ul>\"].join(\"\")),e=r.find(\".\"+c),s=function(){var i=o(document).scrollTop();i>=(l.showHeight||200)?a||(e.show(),a=1):a&&(e.hide(),a=0)};o(\".layui-fixbar\")[0]||(\"object\"==typeof l.css&&r.css(l.css),o(\"body\").append(r),s(),r.find(\"li\").on(\"click\",function(){var i=o(this),a=i.attr(\"lay-type\");\"top\"===a&&o(\"html,body\").animate({scrollTop:0},200),l.click&&l.click.call(this,a)}),o(document).on(\"scroll\",function(){i&&clearTimeout(i),i=setTimeout(function(){s()},100)}))}};l(\"util\",i)});"
  },
  {
    "path": "public/static/layui/layui.js",
    "content": "/** layui-v1.0.7 LGPL License By http://www.layui.com */\n ;!function(e){\"use strict\";var t=function(){this.v=\"1.0.7\"};t.fn=t.prototype;var n=document,o=t.fn.cache={},i=function(){var e=n.scripts,t=e[e.length-1].src;return t.substring(0,t.lastIndexOf(\"/\")+1)}(),r=function(t){e.console&&console.error&&console.error(\"Layui hint: \"+t)},u=\"undefined\"!=typeof opera&&\"[object Opera]\"===opera.toString(),l={layer:\"modules/layer\",laydate:\"modules/laydate\",laypage:\"modules/laypage\",laytpl:\"modules/laytpl\",layim:\"modules/layim\",layedit:\"modules/layedit\",form:\"modules/form\",upload:\"modules/upload\",tree:\"modules/tree\",slide:\"modules/slide\",table:\"modules/table\",element:\"modules/element\",util:\"modules/util\",flow:\"modules/flow\",code:\"modules/code\",single:\"modules/single\",mobile:\"modules/mobile\",jquery:\"lib/jquery\",\"layui.mod\":\"dest/layui.mod\"};o.modules={},o.status={},o.timeout=10,o.event={},t.fn.define=function(e,t){var n=this,i=\"function\"==typeof e,r=function(){return\"function\"==typeof t&&t(function(e,t){layui[e]=t,o.status[e]=!0}),this};return i&&(t=e,e=[]),layui[\"layui.all\"]?r.call(n):(n.use(e,r),n)},t.fn.use=function(e,t,a){function s(e,t){var n=\"PLaySTATION 3\"===navigator.platform?/^complete$/:/^(complete|loaded)$/;(\"load\"===e.type||n.test((e.currentTarget||e.srcElement).readyState))&&(o.modules[m]=t,y.removeChild(v),function i(){return++p>1e3*o.timeout/4?r(m+\" is not a valid module\"):void(o.status[m]?c():setTimeout(i,4))}())}function c(){a.push(layui[m]),e.length>1?f.use(e.slice(1),t,a):\"function\"==typeof t&&t.apply(layui,a)}var f=this,d=o.dir=o.dir?o.dir:i,y=n.getElementsByTagName(\"head\")[0];e=\"string\"==typeof e?[e]:e,window.jQuery&&jQuery.fn.on&&(f.each(e,function(t,n){\"jquery\"===n&&e.splice(t,1)}),layui.jquery=jQuery);var m=e[0],p=0;if(a=a||[],o.host=o.host||(d.match(/\\/\\/([\\s\\S]+?)\\//)||[\"//\"+location.host+\"/\"])[0],0===e.length||layui[\"layui.all\"]&&l[m])return\"function\"==typeof t&&t.apply(layui,a),f;var v=n.createElement(\"script\"),h=(l[m]?d+\"lay/\":o.base||\"\")+(f.modules[m]||m)+\".js\";return v.async=!0,v.charset=\"utf-8\",v.src=h+function(){var e=o.version===!0?o.v||(new Date).getTime():o.version||\"\";return e?\"?v=\"+e:\"\"}(),o.modules[m]?!function g(){return++p>1e3*o.timeout/4?r(m+\" is not a valid module\"):void(\"string\"==typeof o.modules[m]&&o.status[m]?c():setTimeout(g,4))}():(y.appendChild(v),!v.attachEvent||v.attachEvent.toString&&v.attachEvent.toString().indexOf(\"[native code\")<0||u?v.addEventListener(\"load\",function(e){s(e,h)},!1):v.attachEvent(\"onreadystatechange\",function(e){s(e,h)})),o.modules[m]=h,f},t.fn.getStyle=function(t,n){var o=t.currentStyle?t.currentStyle:e.getComputedStyle(t,null);return o[o.getPropertyValue?\"getPropertyValue\":\"getAttribute\"](n)},t.fn.link=function(e,t,i){var u=this,l=n.createElement(\"link\"),a=n.getElementsByTagName(\"head\")[0];\"string\"==typeof t&&(i=t);var s=(i||e).replace(/\\.|\\//g,\"\"),c=l.id=\"layuicss-\"+s,f=0;l.rel=\"stylesheet\",l.href=e+(o.debug?\"?v=\"+(new Date).getTime():\"\"),l.media=\"all\",n.getElementById(c)||a.appendChild(l),\"function\"==typeof t&&!function d(){return++f>1e3*o.timeout/100?r(e+\" timeout\"):void(1989===parseInt(u.getStyle(n.getElementById(c),\"width\"))?function(){t()}():setTimeout(d,100))}()},t.fn.addcss=function(e,t,n){layui.link(o.dir+\"css/\"+e,t,n)},t.fn.img=function(e,t,n){var o=new Image;return o.src=e,o.complete?t(o):(o.onload=function(){o.onload=null,t(o)},void(o.onerror=function(e){o.onerror=null,n(e)}))},t.fn.config=function(e){e=e||{};for(var t in e)o[t]=e[t];return this},t.fn.modules=function(){var e={};for(var t in l)e[t]=l[t];return e}(),t.fn.extend=function(e){var t=this;e=e||{};for(var n in e)t[n]||t.modules[n]?r(\"模块名 \"+n+\" 已被占用\"):t.modules[n]=e[n];return t},t.fn.router=function(e){for(var t,n=(e||location.hash).replace(/^#/,\"\").split(\"/\")||[],o={dir:[]},i=0;i<n.length;i++)t=n[i].split(\"=\"),/^\\w+=/.test(n[i])?function(){\"dir\"!==t[0]&&(o[t[0]]=t[1])}():o.dir.push(n[i]),t=null;return o},t.fn.data=function(t,n){if(t=t||\"layui\",e.JSON&&e.JSON.parse){if(null===n)return delete localStorage[t];n=\"object\"==typeof n?n:{key:n};try{var o=JSON.parse(localStorage[t])}catch(i){var o={}}return n.value&&(o[n.key]=n.value),n.remove&&delete o[n.key],localStorage[t]=JSON.stringify(o),n.key?o[n.key]:o}},t.fn.device=function(t){var n=navigator.userAgent.toLowerCase(),o=function(e){var t=new RegExp(e+\"/([^\\\\s\\\\_\\\\-]+)\");return e=(n.match(t)||[])[1],e||!1},i={os:function(){return/windows/.test(n)?\"windows\":/linux/.test(n)?\"linux\":/iphone|ipod|ipad|ios/.test(n)?\"ios\":void 0}(),ie:function(){return!!(e.ActiveXObject||\"ActiveXObject\"in e)&&((n.match(/msie\\s(\\d+)/)||[])[1]||\"11\")}(),weixin:o(\"micromessenger\")};return t&&!i[t]&&(i[t]=o(t)),i.android=/android/.test(n),i.ios=\"ios\"===i.os,i},t.fn.hint=function(){return{error:r}},t.fn.each=function(e,t){var n,o=this;if(\"function\"!=typeof t)return o;if(e=e||[],e.constructor===Object){for(n in e)if(t.call(e[n],n,e[n]))break}else for(n=0;n<e.length&&!t.call(e[n],n,e[n]);n++);return o},t.fn.stope=function(t){t=t||e.event,t.stopPropagation?t.stopPropagation():t.cancelBubble=!0},t.fn.onevent=function(e,t,n){return\"string\"!=typeof e||\"function\"!=typeof n?this:(o.event[e+\".\"+t]=[n],this)},t.fn.event=function(e,t,n){var i=this,r=null,u=t.match(/\\(.*\\)$/)||[],l=(t=e+\".\"+t).replace(u,\"\"),a=function(e,t){var o=t&&t.call(i,n);o===!1&&null===r&&(r=!1)};return layui.each(o.event[l],a),u[0]&&layui.each(o.event[t],a),r},e.layui=new t}(window);"
  },
  {
    "path": "public/static/plugins/bootbox/bootbox.js",
    "content": "/**\n * bootbox.js [master branch]\n *\n * http://bootboxjs.com/license.txt\n */\n\n// @see https://github.com/makeusabrew/bootbox/issues/180\n// @see https://github.com/makeusabrew/bootbox/issues/186\n(function (root, factory) {\n\n  \"use strict\";\n  if (typeof define === \"function\" && define.amd) {\n    // AMD. Register as an anonymous module.\n    define([\"jquery\"], factory);\n  } else if (typeof exports === \"object\") {\n    // Node. Does not work with strict CommonJS, but\n    // only CommonJS-like environments that support module.exports,\n    // like Node.\n    module.exports = factory(require(\"jquery\"));\n  } else {\n    // Browser globals (root is window)\n    root.bootbox = factory(root.jQuery);\n  }\n\n}(this, function init($, undefined) {\n\n  \"use strict\";\n\n  // the base DOM structure needed to create a modal\n  var templates = {\n    dialog:\n      \"<div class='bootbox modal' tabindex='-1' role='dialog' aria-hidden='true'>\" +\n        \"<div class='modal-dialog'>\" +\n          \"<div class='modal-content'>\" +\n            \"<div class='modal-body'><div class='bootbox-body'></div></div>\" +\n          \"</div>\" +\n        \"</div>\" +\n      \"</div>\",\n    header:\n      \"<div class='modal-header'>\" +\n        \"<h4 class='modal-title'></h4>\" +\n      \"</div>\",\n    footer:\n      \"<div class='modal-footer'></div>\",\n    closeButton:\n      \"<button type='button' class='bootbox-close-button close' data-dismiss='modal' aria-hidden='true'>&times;</button>\",\n    form:\n      \"<form class='bootbox-form'></form>\",\n    inputs: {\n      text:\n        \"<input class='bootbox-input bootbox-input-text form-control' autocomplete=off type=text />\",\n      textarea:\n        \"<textarea class='bootbox-input bootbox-input-textarea form-control'></textarea>\",\n      email:\n        \"<input class='bootbox-input bootbox-input-email form-control' autocomplete='off' type='email' />\",\n      select:\n        \"<select class='bootbox-input bootbox-input-select form-control'></select>\",\n      checkbox:\n        \"<div class='checkbox'><label><input class='bootbox-input bootbox-input-checkbox' type='checkbox' /></label></div>\",\n      date:\n        \"<input class='bootbox-input bootbox-input-date form-control' autocomplete=off type='date' />\",\n      time:\n        \"<input class='bootbox-input bootbox-input-time form-control' autocomplete=off type='time' />\",\n      number:\n        \"<input class='bootbox-input bootbox-input-number form-control' autocomplete=off type='number' />\",\n      password:\n        \"<input class='bootbox-input bootbox-input-password form-control' autocomplete='off' type='password' />\"\n    }\n  };\n\n  var defaults = {\n    // default language\n    locale: \"en\",\n    // show backdrop or not. Default to static so user has to interact with dialog\n    backdrop: \"static\",\n    // animate the modal in/out\n    animate: true,\n    // additional class string applied to the top level dialog\n    className: null,\n    // whether or not to include a close button\n    closeButton: true,\n    // show the dialog immediately by default\n    show: true,\n    // dialog container\n    container: \"body\"\n  };\n\n  // our public object; augmented after our private API\n  var exports = {};\n\n  /**\n   * @private\n   */\n  function _t(key) {\n    var locale = locales[defaults.locale];\n    return locale ? locale[key] : locales.en[key];\n  }\n\n  function processCallback(e, dialog, callback) {\n    e.stopPropagation();\n    e.preventDefault();\n\n    // by default we assume a callback will get rid of the dialog,\n    // although it is given the opportunity to override this\n\n    // so, if the callback can be invoked and it *explicitly returns false*\n    // then we'll set a flag to keep the dialog active...\n    var preserveDialog = $.isFunction(callback) && callback.call(dialog, e) === false;\n\n    // ... otherwise we'll bin it\n    if (!preserveDialog) {\n      dialog.modal(\"hide\");\n    }\n  }\n\n  function getKeyLength(obj) {\n    // @TODO defer to Object.keys(x).length if available?\n    var k, t = 0;\n    for (k in obj) {\n      t ++;\n    }\n    return t;\n  }\n\n  function each(collection, iterator) {\n    var index = 0;\n    $.each(collection, function(key, value) {\n      iterator(key, value, index++);\n    });\n  }\n\n  function sanitize(options) {\n    var buttons;\n    var total;\n\n    if (typeof options !== \"object\") {\n      throw new Error(\"Please supply an object of options\");\n    }\n\n    if (!options.message) {\n      throw new Error(\"Please specify a message\");\n    }\n\n    // make sure any supplied options take precedence over defaults\n    options = $.extend({}, defaults, options);\n\n    if (!options.buttons) {\n      options.buttons = {};\n    }\n\n    buttons = options.buttons;\n\n    total = getKeyLength(buttons);\n\n    each(buttons, function(key, button, index) {\n\n      if ($.isFunction(button)) {\n        // short form, assume value is our callback. Since button\n        // isn't an object it isn't a reference either so re-assign it\n        button = buttons[key] = {\n          callback: button\n        };\n      }\n\n      // before any further checks make sure by now button is the correct type\n      if ($.type(button) !== \"object\") {\n        throw new Error(\"button with key \" + key + \" must be an object\");\n      }\n\n      if (!button.label) {\n        // the lack of an explicit label means we'll assume the key is good enough\n        button.label = key;\n      }\n\n      if (!button.className) {\n        if (total <= 2 && index === total-1) {\n          // always add a primary to the main option in a two-button dialog\n          button.className = \"btn-primary\";\n        } else {\n          button.className = \"btn-default\";\n        }\n      }\n    });\n\n    return options;\n  }\n\n  /**\n   * map a flexible set of arguments into a single returned object\n   * if args.length is already one just return it, otherwise\n   * use the properties argument to map the unnamed args to\n   * object properties\n   * so in the latter case:\n   * mapArguments([\"foo\", $.noop], [\"message\", \"callback\"])\n   * -> { message: \"foo\", callback: $.noop }\n   */\n  function mapArguments(args, properties) {\n    var argn = args.length;\n    var options = {};\n\n    if (argn < 1 || argn > 2) {\n      throw new Error(\"Invalid argument length\");\n    }\n\n    if (argn === 2 || typeof args[0] === \"string\") {\n      options[properties[0]] = args[0];\n      options[properties[1]] = args[1];\n    } else {\n      options = args[0];\n    }\n\n    return options;\n  }\n\n  /**\n   * merge a set of default dialog options with user supplied arguments\n   */\n  function mergeArguments(defaults, args, properties) {\n    return $.extend(\n      // deep merge\n      true,\n      // ensure the target is an empty, unreferenced object\n      {},\n      // the base options object for this type of dialog (often just buttons)\n      defaults,\n      // args could be an object or array; if it's an array properties will\n      // map it to a proper options object\n      mapArguments(\n        args,\n        properties\n      )\n    );\n  }\n\n  /**\n   * this entry-level method makes heavy use of composition to take a simple\n   * range of inputs and return valid options suitable for passing to bootbox.dialog\n   */\n  function mergeDialogOptions(className, labels, properties, args) {\n    //  build up a base set of dialog properties\n    var baseOptions = {\n      className: \"bootbox-\" + className,\n      buttons: createLabels.apply(null, labels)\n    };\n\n    // ensure the buttons properties generated, *after* merging\n    // with user args are still valid against the supplied labels\n    return validateButtons(\n      // merge the generated base properties with user supplied arguments\n      mergeArguments(\n        baseOptions,\n        args,\n        // if args.length > 1, properties specify how each arg maps to an object key\n        properties\n      ),\n      labels\n    );\n  }\n\n  /**\n   * from a given list of arguments return a suitable object of button labels\n   * all this does is normalise the given labels and translate them where possible\n   * e.g. \"ok\", \"confirm\" -> { ok: \"OK, cancel: \"Annuleren\" }\n   */\n  function createLabels() {\n    var buttons = {};\n\n    for (var i = 0, j = arguments.length; i < j; i++) {\n      var argument = arguments[i];\n      var key = argument.toLowerCase();\n      var value = argument.toUpperCase();\n\n      buttons[key] = {\n        label: _t(value)\n      };\n    }\n\n    return buttons;\n  }\n\n  function validateButtons(options, buttons) {\n    var allowedButtons = {};\n    each(buttons, function(key, value) {\n      allowedButtons[value] = true;\n    });\n\n    each(options.buttons, function(key) {\n      if (allowedButtons[key] === undefined) {\n        throw new Error(\"button key \" + key + \" is not allowed (options are \" + buttons.join(\"\\n\") + \")\");\n      }\n    });\n\n    return options;\n  }\n\n  exports.alert = function() {\n    var options;\n\n    options = mergeDialogOptions(\"alert\", [\"ok\"], [\"message\", \"callback\"], arguments);\n\n    if (options.callback && !$.isFunction(options.callback)) {\n      throw new Error(\"alert requires callback property to be a function when provided\");\n    }\n\n    /**\n     * overrides\n     */\n    options.buttons.ok.callback = options.onEscape = function() {\n      if ($.isFunction(options.callback)) {\n        return options.callback.call(this);\n      }\n      return true;\n    };\n\n    return exports.dialog(options);\n  };\n\n  exports.confirm = function() {\n    var options;\n\n    options = mergeDialogOptions(\"confirm\", [\"cancel\", \"confirm\"], [\"message\", \"callback\"], arguments);\n\n    /**\n     * overrides; undo anything the user tried to set they shouldn't have\n     */\n    options.buttons.cancel.callback = options.onEscape = function() {\n      return options.callback.call(this, false);\n    };\n\n    options.buttons.confirm.callback = function() {\n      return options.callback.call(this, true);\n    };\n\n    // confirm specific validation\n    if (!$.isFunction(options.callback)) {\n      throw new Error(\"confirm requires a callback\");\n    }\n\n    return exports.dialog(options);\n  };\n\n  exports.prompt = function() {\n    var options;\n    var defaults;\n    var dialog;\n    var form;\n    var input;\n    var shouldShow;\n    var inputOptions;\n\n    // we have to create our form first otherwise\n    // its value is undefined when gearing up our options\n    // @TODO this could be solved by allowing message to\n    // be a function instead...\n    form = $(templates.form);\n\n    // prompt defaults are more complex than others in that\n    // users can override more defaults\n    // @TODO I don't like that prompt has to do a lot of heavy\n    // lifting which mergeDialogOptions can *almost* support already\n    // just because of 'value' and 'inputType' - can we refactor?\n    defaults = {\n      className: \"bootbox-prompt\",\n      buttons: createLabels(\"cancel\", \"confirm\"),\n      value: \"\",\n      inputType: \"text\"\n    };\n\n    options = validateButtons(\n      mergeArguments(defaults, arguments, [\"title\", \"callback\"]),\n      [\"cancel\", \"confirm\"]\n    );\n\n    // capture the user's show value; we always set this to false before\n    // spawning the dialog to give us a chance to attach some handlers to\n    // it, but we need to make sure we respect a preference not to show it\n    shouldShow = (options.show === undefined) ? true : options.show;\n\n    /**\n     * overrides; undo anything the user tried to set they shouldn't have\n     */\n    options.message = form;\n\n    options.buttons.cancel.callback = options.onEscape = function() {\n      return options.callback.call(this, null);\n    };\n\n    options.buttons.confirm.callback = function() {\n      var value;\n\n      switch (options.inputType) {\n        case \"text\":\n        case \"textarea\":\n        case \"email\":\n        case \"select\":\n        case \"date\":\n        case \"time\":\n        case \"number\":\n        case \"password\":\n          value = input.val();\n          break;\n\n        case \"checkbox\":\n          var checkedItems = input.find(\"input:checked\");\n\n          // we assume that checkboxes are always multiple,\n          // hence we default to an empty array\n          value = [];\n\n          each(checkedItems, function(_, item) {\n            value.push($(item).val());\n          });\n          break;\n      }\n\n      return options.callback.call(this, value);\n    };\n\n    options.show = false;\n\n    // prompt specific validation\n    if (!options.title) {\n      throw new Error(\"prompt requires a title\");\n    }\n\n    if (!$.isFunction(options.callback)) {\n      throw new Error(\"prompt requires a callback\");\n    }\n\n    if (!templates.inputs[options.inputType]) {\n      throw new Error(\"invalid prompt type\");\n    }\n\n    // create the input based on the supplied type\n    input = $(templates.inputs[options.inputType]);\n\n    switch (options.inputType) {\n      case \"text\":\n      case \"textarea\":\n      case \"email\":\n      case \"date\":\n      case \"time\":\n      case \"number\":\n      case \"password\":\n        input.val(options.value);\n        break;\n\n      case \"select\":\n        var groups = {};\n        inputOptions = options.inputOptions || [];\n\n        if (!$.isArray(inputOptions)) {\n          throw new Error(\"Please pass an array of input options\");\n        }\n\n        if (!inputOptions.length) {\n          throw new Error(\"prompt with select requires options\");\n        }\n\n        each(inputOptions, function(_, option) {\n\n          // assume the element to attach to is the input...\n          var elem = input;\n\n          if (option.value === undefined || option.text === undefined) {\n            throw new Error(\"given options in wrong format\");\n          }\n\n          // ... but override that element if this option sits in a group\n\n          if (option.group) {\n            // initialise group if necessary\n            if (!groups[option.group]) {\n              groups[option.group] = $(\"<optgroup/>\").attr(\"label\", option.group);\n            }\n\n            elem = groups[option.group];\n          }\n\n          elem.append(\"<option value='\" + option.value + \"'>\" + option.text + \"</option>\");\n        });\n\n        each(groups, function(_, group) {\n          input.append(group);\n        });\n\n        // safe to set a select's value as per a normal input\n        input.val(options.value);\n        break;\n\n      case \"checkbox\":\n        var values   = $.isArray(options.value) ? options.value : [options.value];\n        inputOptions = options.inputOptions || [];\n\n        if (!inputOptions.length) {\n          throw new Error(\"prompt with checkbox requires options\");\n        }\n\n        if (!inputOptions[0].value || !inputOptions[0].text) {\n          throw new Error(\"given options in wrong format\");\n        }\n\n        // checkboxes have to nest within a containing element, so\n        // they break the rules a bit and we end up re-assigning\n        // our 'input' element to this container instead\n        input = $(\"<div/>\");\n\n        each(inputOptions, function(_, option) {\n          var checkbox = $(templates.inputs[options.inputType]);\n\n          checkbox.find(\"input\").attr(\"value\", option.value);\n          checkbox.find(\"label\").append(option.text);\n\n          // we've ensured values is an array so we can always iterate over it\n          each(values, function(_, value) {\n            if (value === option.value) {\n              checkbox.find(\"input\").prop(\"checked\", true);\n            }\n          });\n\n          input.append(checkbox);\n        });\n        break;\n    }\n\n    // @TODO provide an attributes option instead\n    // and simply map that as keys: vals\n    if (options.placeholder) {\n      input.attr(\"placeholder\", options.placeholder);\n    }\n\n    if (options.pattern) {\n      input.attr(\"pattern\", options.pattern);\n    }\n\n    if (options.maxlength) {\n      input.attr(\"maxlength\", options.maxlength);\n    }\n\n    // now place it in our form\n    form.append(input);\n\n    form.on(\"submit\", function(e) {\n      e.preventDefault();\n      // Fix for SammyJS (or similar JS routing library) hijacking the form post.\n      e.stopPropagation();\n      // @TODO can we actually click *the* button object instead?\n      // e.g. buttons.confirm.click() or similar\n      dialog.find(\".btn-primary\").click();\n    });\n\n    dialog = exports.dialog(options);\n\n    // clear the existing handler focusing the submit button...\n    dialog.off(\"shown.bs.modal\");\n\n    // ...and replace it with one focusing our input, if possible\n    dialog.on(\"shown.bs.modal\", function() {\n      // need the closure here since input isn't\n      // an object otherwise\n      input.focus();\n    });\n\n    if (shouldShow === true) {\n      dialog.modal(\"show\");\n    }\n\n    return dialog;\n  };\n\n  exports.dialog = function(options) {\n    options = sanitize(options);\n\n    var dialog = $(templates.dialog);\n    var innerDialog = dialog.find(\".modal-dialog\");\n    var body = dialog.find(\".modal-body\");\n    var buttons = options.buttons;\n    var buttonStr = \"\";\n    var callbacks = {\n      onEscape: options.onEscape\n    };\n\n    if ($.fn.modal === undefined) {\n      throw new Error(\n        \"$.fn.modal is not defined; please double check you have included \" +\n        \"the Bootstrap JavaScript library. See http://getbootstrap.com/javascript/ \" +\n        \"for more details.\"\n      );\n    }\n\n    each(buttons, function(key, button) {\n\n      // @TODO I don't like this string appending to itself; bit dirty. Needs reworking\n      // can we just build up button elements instead? slower but neater. Then button\n      // can just become a template too\n      buttonStr += \"<button data-bb-handler='\" + key + \"' type='button' class='btn \" + button.className + \"'>\" + button.label + \"</button>\";\n      callbacks[key] = button.callback;\n    });\n\n    body.find(\".bootbox-body\").html(options.message);\n\n    if (options.animate === true) {\n      dialog.addClass(\"fade\");\n    }\n\n    if (options.className) {\n      dialog.addClass(options.className);\n    }\n\n    if (options.size === \"large\") {\n      innerDialog.addClass(\"modal-lg\");\n    } else if (options.size === \"small\") {\n      innerDialog.addClass(\"modal-sm\");\n    }\n\n    if (options.title) {\n      body.before(templates.header);\n    }\n\n    if (options.closeButton) {\n      var closeButton = $(templates.closeButton);\n\n      if (options.title) {\n        dialog.find(\".modal-header\").prepend(closeButton);\n      } else {\n        closeButton.css(\"margin-top\", \"-10px\").prependTo(body);\n      }\n    }\n\n    if (options.title) {\n      dialog.find(\".modal-title\").html(options.title);\n    }\n\n    if (buttonStr.length) {\n      body.after(templates.footer);\n      dialog.find(\".modal-footer\").html(buttonStr);\n    }\n\n\n    /**\n     * Bootstrap event listeners; used handle extra\n     * setup & teardown required after the underlying\n     * modal has performed certain actions\n     */\n\n    dialog.on(\"hidden.bs.modal\", function(e) {\n      // ensure we don't accidentally intercept hidden events triggered\n      // by children of the current dialog. We shouldn't anymore now BS\n      // namespaces its events; but still worth doing\n      if (e.target === this) {\n        dialog.remove();\n      }\n    });\n\n    /*\n    dialog.on(\"show.bs.modal\", function() {\n      // sadly this doesn't work; show is called *just* before\n      // the backdrop is added so we'd need a setTimeout hack or\n      // otherwise... leaving in as would be nice\n      if (options.backdrop) {\n        dialog.next(\".modal-backdrop\").addClass(\"bootbox-backdrop\");\n      }\n    });\n    */\n\n    dialog.on(\"shown.bs.modal\", function() {\n      dialog.find(\".btn-primary:first\").focus();\n    });\n\n    /**\n     * Bootbox event listeners; experimental and may not last\n     * just an attempt to decouple some behaviours from their\n     * respective triggers\n     */\n\n    if (options.backdrop !== \"static\") {\n      // A boolean true/false according to the Bootstrap docs\n      // should show a dialog the user can dismiss by clicking on\n      // the background.\n      // We always only ever pass static/false to the actual\n      // $.modal function because with `true` we can't trap\n      // this event (the .modal-backdrop swallows it)\n      // However, we still want to sort of respect true\n      // and invoke the escape mechanism instead\n      dialog.on(\"click.dismiss.bs.modal\", function(e) {\n        // @NOTE: the target varies in >= 3.3.x releases since the modal backdrop\n        // moved *inside* the outer dialog rather than *alongside* it\n        if (dialog.children(\".modal-backdrop\").length) {\n          e.currentTarget = dialog.children(\".modal-backdrop\").get(0);\n        }\n\n        if (e.target !== e.currentTarget) {\n          return;\n        }\n\n        dialog.trigger(\"escape.close.bb\");\n      });\n    }\n\n    dialog.on(\"escape.close.bb\", function(e) {\n      if (callbacks.onEscape) {\n        processCallback(e, dialog, callbacks.onEscape);\n      }\n    });\n\n    /**\n     * Standard jQuery event listeners; used to handle user\n     * interaction with our dialog\n     */\n\n    dialog.on(\"click\", \".modal-footer button\", function(e) {\n      var callbackKey = $(this).data(\"bb-handler\");\n\n      processCallback(e, dialog, callbacks[callbackKey]);\n    });\n\n    dialog.on(\"click\", \".bootbox-close-button\", function(e) {\n      // onEscape might be falsy but that's fine; the fact is\n      // if the user has managed to click the close button we\n      // have to close the dialog, callback or not\n      processCallback(e, dialog, callbacks.onEscape);\n    });\n\n    dialog.on(\"keyup\", function(e) {\n      if (e.which === 27) {\n        dialog.trigger(\"escape.close.bb\");\n      }\n    });\n\n    // the remainder of this method simply deals with adding our\n    // dialogent to the DOM, augmenting it with Bootstrap's modal\n    // functionality and then giving the resulting object back\n    // to our caller\n\n    $(options.container).append(dialog);\n\n    dialog.modal({\n      backdrop: options.backdrop ? \"static\": false,\n      keyboard: false,\n      show: false\n    });\n\n    if (options.show) {\n      dialog.modal(\"show\");\n    }\n\n    // @TODO should we return the raw element here or should\n    // we wrap it in an object on which we can expose some neater\n    // methods, e.g. var d = bootbox.alert(); d.hide(); instead\n    // of d.modal(\"hide\");\n\n   /*\n    function BBDialog(elem) {\n      this.elem = elem;\n    }\n\n    BBDialog.prototype = {\n      hide: function() {\n        return this.elem.modal(\"hide\");\n      },\n      show: function() {\n        return this.elem.modal(\"show\");\n      }\n    };\n    */\n\n    return dialog;\n\n  };\n\n  exports.setDefaults = function() {\n    var values = {};\n\n    if (arguments.length === 2) {\n      // allow passing of single key/value...\n      values[arguments[0]] = arguments[1];\n    } else {\n      // ... and as an object too\n      values = arguments[0];\n    }\n\n    $.extend(defaults, values);\n  };\n\n  exports.hideAll = function() {\n    $(\".bootbox\").modal(\"hide\");\n\n    return exports;\n  };\n\n\n  /**\n   * standard locales. Please add more according to ISO 639-1 standard. Multiple language variants are\n   * unlikely to be required. If this gets too large it can be split out into separate JS files.\n   */\n  var locales = {\n    ar : {\n      OK      : \"موافق\",\n      CANCEL  : \"الغاء\",\n      CONFIRM : \"تأكيد\"\n    },\n    bg_BG : {\n      OK      : \"Ок\",\n      CANCEL  : \"Отказ\",\n      CONFIRM : \"Потвърждавам\"\n    },\n    br : {\n      OK      : \"OK\",\n      CANCEL  : \"Cancelar\",\n      CONFIRM : \"Sim\"\n    },\n    cs : {\n      OK      : \"OK\",\n      CANCEL  : \"Zrušit\",\n      CONFIRM : \"Potvrdit\"\n    },\n    da : {\n      OK      : \"OK\",\n      CANCEL  : \"Annuller\",\n      CONFIRM : \"Accepter\"\n    },\n    de : {\n      OK      : \"OK\",\n      CANCEL  : \"Abbrechen\",\n      CONFIRM : \"Akzeptieren\"\n    },\n    el : {\n      OK      : \"Εντάξει\",\n      CANCEL  : \"Ακύρωση\",\n      CONFIRM : \"Επιβεβαίωση\"\n    },\n    en : {\n      OK      : \"OK\",\n      CANCEL  : \"Cancel\",\n      CONFIRM : \"OK\"\n    },\n    es : {\n      OK      : \"OK\",\n      CANCEL  : \"Cancelar\",\n      CONFIRM : \"Aceptar\"\n    },\n    et : {\n      OK      : \"OK\",\n      CANCEL  : \"Katkesta\",\n      CONFIRM : \"OK\"\n    },\n    fa : {\n      OK      : \"قبول\",\n      CANCEL  : \"لغو\",\n      CONFIRM : \"تایید\"\n    },\n    fi : {\n      OK      : \"OK\",\n      CANCEL  : \"Peruuta\",\n      CONFIRM : \"OK\"\n    },\n    fr : {\n      OK      : \"OK\",\n      CANCEL  : \"Annuler\",\n      CONFIRM : \"Confirmer\"\n    },\n    he : {\n      OK      : \"אישור\",\n      CANCEL  : \"ביטול\",\n      CONFIRM : \"אישור\"\n    },\n    hu : {\n      OK      : \"OK\",\n      CANCEL  : \"Mégsem\",\n      CONFIRM : \"Megerősít\"\n    },\n    hr : {\n      OK      : \"OK\",\n      CANCEL  : \"Odustani\",\n      CONFIRM : \"Potvrdi\"\n    },\n    id : {\n      OK      : \"OK\",\n      CANCEL  : \"Batal\",\n      CONFIRM : \"OK\"\n    },\n    it : {\n      OK      : \"OK\",\n      CANCEL  : \"Annulla\",\n      CONFIRM : \"Conferma\"\n    },\n    ja : {\n      OK      : \"OK\",\n      CANCEL  : \"キャンセル\",\n      CONFIRM : \"確認\"\n    },\n    lt : {\n      OK      : \"Gerai\",\n      CANCEL  : \"Atšaukti\",\n      CONFIRM : \"Patvirtinti\"\n    },\n    lv : {\n      OK      : \"Labi\",\n      CANCEL  : \"Atcelt\",\n      CONFIRM : \"Apstiprināt\"\n    },\n    nl : {\n      OK      : \"OK\",\n      CANCEL  : \"Annuleren\",\n      CONFIRM : \"Accepteren\"\n    },\n    no : {\n      OK      : \"OK\",\n      CANCEL  : \"Avbryt\",\n      CONFIRM : \"OK\"\n    },\n    pl : {\n      OK      : \"OK\",\n      CANCEL  : \"Anuluj\",\n      CONFIRM : \"Potwierdź\"\n    },\n    pt : {\n      OK      : \"OK\",\n      CANCEL  : \"Cancelar\",\n      CONFIRM : \"Confirmar\"\n    },\n    ru : {\n      OK      : \"OK\",\n      CANCEL  : \"Отмена\",\n      CONFIRM : \"Применить\"\n    },\n    sq : {\n      OK : \"OK\",\n      CANCEL : \"Anulo\",\n      CONFIRM : \"Prano\"\n    },\n    sv : {\n      OK      : \"OK\",\n      CANCEL  : \"Avbryt\",\n      CONFIRM : \"OK\"\n    },\n    th : {\n      OK      : \"ตกลง\",\n      CANCEL  : \"ยกเลิก\",\n      CONFIRM : \"ยืนยัน\"\n    },\n    tr : {\n      OK      : \"Tamam\",\n      CANCEL  : \"İptal\",\n      CONFIRM : \"Onayla\"\n    },\n    zh_CN : {\n      OK      : \"OK\",\n      CANCEL  : \"取消\",\n      CONFIRM : \"确认\"\n    },\n    zh_TW : {\n      OK      : \"OK\",\n      CANCEL  : \"取消\",\n      CONFIRM : \"確認\"\n    }\n  };\n\n  exports.addLocale = function(name, values) {\n    $.each([\"OK\", \"CANCEL\", \"CONFIRM\"], function(_, v) {\n      if (!values[v]) {\n        throw new Error(\"Please supply a translation for '\" + v + \"'\");\n      }\n    });\n\n    locales[name] = {\n      OK: values.OK,\n      CANCEL: values.CANCEL,\n      CONFIRM: values.CONFIRM\n    };\n\n    return exports;\n  };\n\n  exports.removeLocale = function(name) {\n    delete locales[name];\n\n    return exports;\n  };\n\n  exports.setLocale = function(name) {\n    return exports.setDefaults(\"locale\", name);\n  };\n\n  exports.init = function(_$) {\n    return init(_$ || $);\n  };\n\n  return exports;\n}));\n"
  },
  {
    "path": "public/static/plugins/bootstrap/css/bootstrap.css",
    "content": "/*!\n * Bootstrap v3.3.6 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n */\n/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */\nhtml {\n  font-family: sans-serif;\n  -webkit-text-size-adjust: 100%;\n      -ms-text-size-adjust: 100%;\n}\nbody {\n  margin: 0;\n}\narticle,\naside,\ndetails,\nfigcaption,\nfigure,\nfooter,\nheader,\nhgroup,\nmain,\nmenu,\nnav,\nsection,\nsummary {\n  display: block;\n}\naudio,\ncanvas,\nprogress,\nvideo {\n  display: inline-block;\n  vertical-align: baseline;\n}\naudio:not([controls]) {\n  display: none;\n  height: 0;\n}\n[hidden],\ntemplate {\n  display: none;\n}\na {\n  background-color: transparent;\n}\na:active,\na:hover {\n  outline: 0;\n}\nabbr[title] {\n  border-bottom: 1px dotted;\n}\nb,\nstrong {\n  font-weight: bold;\n}\ndfn {\n  font-style: italic;\n}\nh1 {\n  margin: .67em 0;\n  font-size: 2em;\n}\nmark {\n  color: #000;\n  background: #ff0;\n}\nsmall {\n  font-size: 80%;\n}\nsub,\nsup {\n  position: relative;\n  font-size: 75%;\n  line-height: 0;\n  vertical-align: baseline;\n}\nsup {\n  top: -.5em;\n}\nsub {\n  bottom: -.25em;\n}\nimg {\n  border: 0;\n}\nsvg:not(:root) {\n  overflow: hidden;\n}\nfigure {\n  margin: 1em 40px;\n}\nhr {\n  height: 0;\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n}\npre {\n  overflow: auto;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: monospace, monospace;\n  font-size: 1em;\n}\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n  margin: 0;\n  font: inherit;\n  color: inherit;\n}\nbutton {\n  overflow: visible;\n}\nbutton,\nselect {\n  text-transform: none;\n}\nbutton,\nhtml input[type=\"button\"],\ninput[type=\"reset\"],\ninput[type=\"submit\"] {\n  -webkit-appearance: button;\n  cursor: pointer;\n}\nbutton[disabled],\nhtml input[disabled] {\n  cursor: default;\n}\nbutton::-moz-focus-inner,\ninput::-moz-focus-inner {\n  padding: 0;\n  border: 0;\n}\ninput {\n  line-height: normal;\n}\ninput[type=\"checkbox\"],\ninput[type=\"radio\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n  padding: 0;\n}\ninput[type=\"number\"]::-webkit-inner-spin-button,\ninput[type=\"number\"]::-webkit-outer-spin-button {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: content-box;\n     -moz-box-sizing: content-box;\n          box-sizing: content-box;\n  -webkit-appearance: textfield;\n}\ninput[type=\"search\"]::-webkit-search-cancel-button,\ninput[type=\"search\"]::-webkit-search-decoration {\n  -webkit-appearance: none;\n}\nfieldset {\n  padding: .35em .625em .75em;\n  margin: 0 2px;\n  border: 1px solid #c0c0c0;\n}\nlegend {\n  padding: 0;\n  border: 0;\n}\ntextarea {\n  overflow: auto;\n}\noptgroup {\n  font-weight: bold;\n}\ntable {\n  border-spacing: 0;\n  border-collapse: collapse;\n}\ntd,\nth {\n  padding: 0;\n}\n/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */\n@media print {\n  *,\n  *:before,\n  *:after {\n    color: #000 !important;\n    text-shadow: none !important;\n    background: transparent !important;\n    -webkit-box-shadow: none !important;\n            box-shadow: none !important;\n  }\n  a,\n  a:visited {\n    text-decoration: underline;\n  }\n  a[href]:after {\n    content: \" (\" attr(href) \")\";\n  }\n  abbr[title]:after {\n    content: \" (\" attr(title) \")\";\n  }\n  a[href^=\"#\"]:after,\n  a[href^=\"javascript:\"]:after {\n    content: \"\";\n  }\n  pre,\n  blockquote {\n    border: 1px solid #999;\n\n    page-break-inside: avoid;\n  }\n  thead {\n    display: table-header-group;\n  }\n  tr,\n  img {\n    page-break-inside: avoid;\n  }\n  img {\n    max-width: 100% !important;\n  }\n  p,\n  h2,\n  h3 {\n    orphans: 3;\n    widows: 3;\n  }\n  h2,\n  h3 {\n    page-break-after: avoid;\n  }\n  .navbar {\n    display: none;\n  }\n  .btn > .caret,\n  .dropup > .btn > .caret {\n    border-top-color: #000 !important;\n  }\n  .label {\n    border: 1px solid #000;\n  }\n  .table {\n    border-collapse: collapse !important;\n  }\n  .table td,\n  .table th {\n    background-color: #fff !important;\n  }\n  .table-bordered th,\n  .table-bordered td {\n    border: 1px solid #ddd !important;\n  }\n}\n@font-face {\n  font-family: 'Glyphicons Halflings';\n\n  src: url('../fonts/glyphicons-halflings-regular.eot');\n  src: url('../fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'), url('../fonts/glyphicons-halflings-regular.woff2') format('woff2'), url('../fonts/glyphicons-halflings-regular.woff') format('woff'), url('../fonts/glyphicons-halflings-regular.ttf') format('truetype'), url('../fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg');\n}\n.glyphicon {\n  position: relative;\n  top: 1px;\n  display: inline-block;\n  font-family: 'Glyphicons Halflings';\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1;\n\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.glyphicon-asterisk:before {\n  content: \"\\002a\";\n}\n.glyphicon-plus:before {\n  content: \"\\002b\";\n}\n.glyphicon-euro:before,\n.glyphicon-eur:before {\n  content: \"\\20ac\";\n}\n.glyphicon-minus:before {\n  content: \"\\2212\";\n}\n.glyphicon-cloud:before {\n  content: \"\\2601\";\n}\n.glyphicon-envelope:before {\n  content: \"\\2709\";\n}\n.glyphicon-pencil:before {\n  content: \"\\270f\";\n}\n.glyphicon-glass:before {\n  content: \"\\e001\";\n}\n.glyphicon-music:before {\n  content: \"\\e002\";\n}\n.glyphicon-search:before {\n  content: \"\\e003\";\n}\n.glyphicon-heart:before {\n  content: \"\\e005\";\n}\n.glyphicon-star:before {\n  content: \"\\e006\";\n}\n.glyphicon-star-empty:before {\n  content: \"\\e007\";\n}\n.glyphicon-user:before {\n  content: \"\\e008\";\n}\n.glyphicon-film:before {\n  content: \"\\e009\";\n}\n.glyphicon-th-large:before {\n  content: \"\\e010\";\n}\n.glyphicon-th:before {\n  content: \"\\e011\";\n}\n.glyphicon-th-list:before {\n  content: \"\\e012\";\n}\n.glyphicon-ok:before {\n  content: \"\\e013\";\n}\n.glyphicon-remove:before {\n  content: \"\\e014\";\n}\n.glyphicon-zoom-in:before {\n  content: \"\\e015\";\n}\n.glyphicon-zoom-out:before {\n  content: \"\\e016\";\n}\n.glyphicon-off:before {\n  content: \"\\e017\";\n}\n.glyphicon-signal:before {\n  content: \"\\e018\";\n}\n.glyphicon-cog:before {\n  content: \"\\e019\";\n}\n.glyphicon-trash:before {\n  content: \"\\e020\";\n}\n.glyphicon-home:before {\n  content: \"\\e021\";\n}\n.glyphicon-file:before {\n  content: \"\\e022\";\n}\n.glyphicon-time:before {\n  content: \"\\e023\";\n}\n.glyphicon-road:before {\n  content: \"\\e024\";\n}\n.glyphicon-download-alt:before {\n  content: \"\\e025\";\n}\n.glyphicon-download:before {\n  content: \"\\e026\";\n}\n.glyphicon-upload:before {\n  content: \"\\e027\";\n}\n.glyphicon-inbox:before {\n  content: \"\\e028\";\n}\n.glyphicon-play-circle:before {\n  content: \"\\e029\";\n}\n.glyphicon-repeat:before {\n  content: \"\\e030\";\n}\n.glyphicon-refresh:before {\n  content: \"\\e031\";\n}\n.glyphicon-list-alt:before {\n  content: \"\\e032\";\n}\n.glyphicon-lock:before {\n  content: \"\\e033\";\n}\n.glyphicon-flag:before {\n  content: \"\\e034\";\n}\n.glyphicon-headphones:before {\n  content: \"\\e035\";\n}\n.glyphicon-volume-off:before {\n  content: \"\\e036\";\n}\n.glyphicon-volume-down:before {\n  content: \"\\e037\";\n}\n.glyphicon-volume-up:before {\n  content: \"\\e038\";\n}\n.glyphicon-qrcode:before {\n  content: \"\\e039\";\n}\n.glyphicon-barcode:before {\n  content: \"\\e040\";\n}\n.glyphicon-tag:before {\n  content: \"\\e041\";\n}\n.glyphicon-tags:before {\n  content: \"\\e042\";\n}\n.glyphicon-book:before {\n  content: \"\\e043\";\n}\n.glyphicon-bookmark:before {\n  content: \"\\e044\";\n}\n.glyphicon-print:before {\n  content: \"\\e045\";\n}\n.glyphicon-camera:before {\n  content: \"\\e046\";\n}\n.glyphicon-font:before {\n  content: \"\\e047\";\n}\n.glyphicon-bold:before {\n  content: \"\\e048\";\n}\n.glyphicon-italic:before {\n  content: \"\\e049\";\n}\n.glyphicon-text-height:before {\n  content: \"\\e050\";\n}\n.glyphicon-text-width:before {\n  content: \"\\e051\";\n}\n.glyphicon-align-left:before {\n  content: \"\\e052\";\n}\n.glyphicon-align-center:before {\n  content: \"\\e053\";\n}\n.glyphicon-align-right:before {\n  content: \"\\e054\";\n}\n.glyphicon-align-justify:before {\n  content: \"\\e055\";\n}\n.glyphicon-list:before {\n  content: \"\\e056\";\n}\n.glyphicon-indent-left:before {\n  content: \"\\e057\";\n}\n.glyphicon-indent-right:before {\n  content: \"\\e058\";\n}\n.glyphicon-facetime-video:before {\n  content: \"\\e059\";\n}\n.glyphicon-picture:before {\n  content: \"\\e060\";\n}\n.glyphicon-map-marker:before {\n  content: \"\\e062\";\n}\n.glyphicon-adjust:before {\n  content: \"\\e063\";\n}\n.glyphicon-tint:before {\n  content: \"\\e064\";\n}\n.glyphicon-edit:before {\n  content: \"\\e065\";\n}\n.glyphicon-share:before {\n  content: \"\\e066\";\n}\n.glyphicon-check:before {\n  content: \"\\e067\";\n}\n.glyphicon-move:before {\n  content: \"\\e068\";\n}\n.glyphicon-step-backward:before {\n  content: \"\\e069\";\n}\n.glyphicon-fast-backward:before {\n  content: \"\\e070\";\n}\n.glyphicon-backward:before {\n  content: \"\\e071\";\n}\n.glyphicon-play:before {\n  content: \"\\e072\";\n}\n.glyphicon-pause:before {\n  content: \"\\e073\";\n}\n.glyphicon-stop:before {\n  content: \"\\e074\";\n}\n.glyphicon-forward:before {\n  content: \"\\e075\";\n}\n.glyphicon-fast-forward:before {\n  content: \"\\e076\";\n}\n.glyphicon-step-forward:before {\n  content: \"\\e077\";\n}\n.glyphicon-eject:before {\n  content: \"\\e078\";\n}\n.glyphicon-chevron-left:before {\n  content: \"\\e079\";\n}\n.glyphicon-chevron-right:before {\n  content: \"\\e080\";\n}\n.glyphicon-plus-sign:before {\n  content: \"\\e081\";\n}\n.glyphicon-minus-sign:before {\n  content: \"\\e082\";\n}\n.glyphicon-remove-sign:before {\n  content: \"\\e083\";\n}\n.glyphicon-ok-sign:before {\n  content: \"\\e084\";\n}\n.glyphicon-question-sign:before {\n  content: \"\\e085\";\n}\n.glyphicon-info-sign:before {\n  content: \"\\e086\";\n}\n.glyphicon-screenshot:before {\n  content: \"\\e087\";\n}\n.glyphicon-remove-circle:before {\n  content: \"\\e088\";\n}\n.glyphicon-ok-circle:before {\n  content: \"\\e089\";\n}\n.glyphicon-ban-circle:before {\n  content: \"\\e090\";\n}\n.glyphicon-arrow-left:before {\n  content: \"\\e091\";\n}\n.glyphicon-arrow-right:before {\n  content: \"\\e092\";\n}\n.glyphicon-arrow-up:before {\n  content: \"\\e093\";\n}\n.glyphicon-arrow-down:before {\n  content: \"\\e094\";\n}\n.glyphicon-share-alt:before {\n  content: \"\\e095\";\n}\n.glyphicon-resize-full:before {\n  content: \"\\e096\";\n}\n.glyphicon-resize-small:before {\n  content: \"\\e097\";\n}\n.glyphicon-exclamation-sign:before {\n  content: \"\\e101\";\n}\n.glyphicon-gift:before {\n  content: \"\\e102\";\n}\n.glyphicon-leaf:before {\n  content: \"\\e103\";\n}\n.glyphicon-fire:before {\n  content: \"\\e104\";\n}\n.glyphicon-eye-open:before {\n  content: \"\\e105\";\n}\n.glyphicon-eye-close:before {\n  content: \"\\e106\";\n}\n.glyphicon-warning-sign:before {\n  content: \"\\e107\";\n}\n.glyphicon-plane:before {\n  content: \"\\e108\";\n}\n.glyphicon-calendar:before {\n  content: \"\\e109\";\n}\n.glyphicon-random:before {\n  content: \"\\e110\";\n}\n.glyphicon-comment:before {\n  content: \"\\e111\";\n}\n.glyphicon-magnet:before {\n  content: \"\\e112\";\n}\n.glyphicon-chevron-up:before {\n  content: \"\\e113\";\n}\n.glyphicon-chevron-down:before {\n  content: \"\\e114\";\n}\n.glyphicon-retweet:before {\n  content: \"\\e115\";\n}\n.glyphicon-shopping-cart:before {\n  content: \"\\e116\";\n}\n.glyphicon-folder-close:before {\n  content: \"\\e117\";\n}\n.glyphicon-folder-open:before {\n  content: \"\\e118\";\n}\n.glyphicon-resize-vertical:before {\n  content: \"\\e119\";\n}\n.glyphicon-resize-horizontal:before {\n  content: \"\\e120\";\n}\n.glyphicon-hdd:before {\n  content: \"\\e121\";\n}\n.glyphicon-bullhorn:before {\n  content: \"\\e122\";\n}\n.glyphicon-bell:before {\n  content: \"\\e123\";\n}\n.glyphicon-certificate:before {\n  content: \"\\e124\";\n}\n.glyphicon-thumbs-up:before {\n  content: \"\\e125\";\n}\n.glyphicon-thumbs-down:before {\n  content: \"\\e126\";\n}\n.glyphicon-hand-right:before {\n  content: \"\\e127\";\n}\n.glyphicon-hand-left:before {\n  content: \"\\e128\";\n}\n.glyphicon-hand-up:before {\n  content: \"\\e129\";\n}\n.glyphicon-hand-down:before {\n  content: \"\\e130\";\n}\n.glyphicon-circle-arrow-right:before {\n  content: \"\\e131\";\n}\n.glyphicon-circle-arrow-left:before {\n  content: \"\\e132\";\n}\n.glyphicon-circle-arrow-up:before {\n  content: \"\\e133\";\n}\n.glyphicon-circle-arrow-down:before {\n  content: \"\\e134\";\n}\n.glyphicon-globe:before {\n  content: \"\\e135\";\n}\n.glyphicon-wrench:before {\n  content: \"\\e136\";\n}\n.glyphicon-tasks:before {\n  content: \"\\e137\";\n}\n.glyphicon-filter:before {\n  content: \"\\e138\";\n}\n.glyphicon-briefcase:before {\n  content: \"\\e139\";\n}\n.glyphicon-fullscreen:before {\n  content: \"\\e140\";\n}\n.glyphicon-dashboard:before {\n  content: \"\\e141\";\n}\n.glyphicon-paperclip:before {\n  content: \"\\e142\";\n}\n.glyphicon-heart-empty:before {\n  content: \"\\e143\";\n}\n.glyphicon-link:before {\n  content: \"\\e144\";\n}\n.glyphicon-phone:before {\n  content: \"\\e145\";\n}\n.glyphicon-pushpin:before {\n  content: \"\\e146\";\n}\n.glyphicon-usd:before {\n  content: \"\\e148\";\n}\n.glyphicon-gbp:before {\n  content: \"\\e149\";\n}\n.glyphicon-sort:before {\n  content: \"\\e150\";\n}\n.glyphicon-sort-by-alphabet:before {\n  content: \"\\e151\";\n}\n.glyphicon-sort-by-alphabet-alt:before {\n  content: \"\\e152\";\n}\n.glyphicon-sort-by-order:before {\n  content: \"\\e153\";\n}\n.glyphicon-sort-by-order-alt:before {\n  content: \"\\e154\";\n}\n.glyphicon-sort-by-attributes:before {\n  content: \"\\e155\";\n}\n.glyphicon-sort-by-attributes-alt:before {\n  content: \"\\e156\";\n}\n.glyphicon-unchecked:before {\n  content: \"\\e157\";\n}\n.glyphicon-expand:before {\n  content: \"\\e158\";\n}\n.glyphicon-collapse-down:before {\n  content: \"\\e159\";\n}\n.glyphicon-collapse-up:before {\n  content: \"\\e160\";\n}\n.glyphicon-log-in:before {\n  content: \"\\e161\";\n}\n.glyphicon-flash:before {\n  content: \"\\e162\";\n}\n.glyphicon-log-out:before {\n  content: \"\\e163\";\n}\n.glyphicon-new-window:before {\n  content: \"\\e164\";\n}\n.glyphicon-record:before {\n  content: \"\\e165\";\n}\n.glyphicon-save:before {\n  content: \"\\e166\";\n}\n.glyphicon-open:before {\n  content: \"\\e167\";\n}\n.glyphicon-saved:before {\n  content: \"\\e168\";\n}\n.glyphicon-import:before {\n  content: \"\\e169\";\n}\n.glyphicon-export:before {\n  content: \"\\e170\";\n}\n.glyphicon-send:before {\n  content: \"\\e171\";\n}\n.glyphicon-floppy-disk:before {\n  content: \"\\e172\";\n}\n.glyphicon-floppy-saved:before {\n  content: \"\\e173\";\n}\n.glyphicon-floppy-remove:before {\n  content: \"\\e174\";\n}\n.glyphicon-floppy-save:before {\n  content: \"\\e175\";\n}\n.glyphicon-floppy-open:before {\n  content: \"\\e176\";\n}\n.glyphicon-credit-card:before {\n  content: \"\\e177\";\n}\n.glyphicon-transfer:before {\n  content: \"\\e178\";\n}\n.glyphicon-cutlery:before {\n  content: \"\\e179\";\n}\n.glyphicon-header:before {\n  content: \"\\e180\";\n}\n.glyphicon-compressed:before {\n  content: \"\\e181\";\n}\n.glyphicon-earphone:before {\n  content: \"\\e182\";\n}\n.glyphicon-phone-alt:before {\n  content: \"\\e183\";\n}\n.glyphicon-tower:before {\n  content: \"\\e184\";\n}\n.glyphicon-stats:before {\n  content: \"\\e185\";\n}\n.glyphicon-sd-video:before {\n  content: \"\\e186\";\n}\n.glyphicon-hd-video:before {\n  content: \"\\e187\";\n}\n.glyphicon-subtitles:before {\n  content: \"\\e188\";\n}\n.glyphicon-sound-stereo:before {\n  content: \"\\e189\";\n}\n.glyphicon-sound-dolby:before {\n  content: \"\\e190\";\n}\n.glyphicon-sound-5-1:before {\n  content: \"\\e191\";\n}\n.glyphicon-sound-6-1:before {\n  content: \"\\e192\";\n}\n.glyphicon-sound-7-1:before {\n  content: \"\\e193\";\n}\n.glyphicon-copyright-mark:before {\n  content: \"\\e194\";\n}\n.glyphicon-registration-mark:before {\n  content: \"\\e195\";\n}\n.glyphicon-cloud-download:before {\n  content: \"\\e197\";\n}\n.glyphicon-cloud-upload:before {\n  content: \"\\e198\";\n}\n.glyphicon-tree-conifer:before {\n  content: \"\\e199\";\n}\n.glyphicon-tree-deciduous:before {\n  content: \"\\e200\";\n}\n.glyphicon-cd:before {\n  content: \"\\e201\";\n}\n.glyphicon-save-file:before {\n  content: \"\\e202\";\n}\n.glyphicon-open-file:before {\n  content: \"\\e203\";\n}\n.glyphicon-level-up:before {\n  content: \"\\e204\";\n}\n.glyphicon-copy:before {\n  content: \"\\e205\";\n}\n.glyphicon-paste:before {\n  content: \"\\e206\";\n}\n.glyphicon-alert:before {\n  content: \"\\e209\";\n}\n.glyphicon-equalizer:before {\n  content: \"\\e210\";\n}\n.glyphicon-king:before {\n  content: \"\\e211\";\n}\n.glyphicon-queen:before {\n  content: \"\\e212\";\n}\n.glyphicon-pawn:before {\n  content: \"\\e213\";\n}\n.glyphicon-bishop:before {\n  content: \"\\e214\";\n}\n.glyphicon-knight:before {\n  content: \"\\e215\";\n}\n.glyphicon-baby-formula:before {\n  content: \"\\e216\";\n}\n.glyphicon-tent:before {\n  content: \"\\26fa\";\n}\n.glyphicon-blackboard:before {\n  content: \"\\e218\";\n}\n.glyphicon-bed:before {\n  content: \"\\e219\";\n}\n.glyphicon-apple:before {\n  content: \"\\f8ff\";\n}\n.glyphicon-erase:before {\n  content: \"\\e221\";\n}\n.glyphicon-hourglass:before {\n  content: \"\\231b\";\n}\n.glyphicon-lamp:before {\n  content: \"\\e223\";\n}\n.glyphicon-duplicate:before {\n  content: \"\\e224\";\n}\n.glyphicon-piggy-bank:before {\n  content: \"\\e225\";\n}\n.glyphicon-scissors:before {\n  content: \"\\e226\";\n}\n.glyphicon-bitcoin:before {\n  content: \"\\e227\";\n}\n.glyphicon-btc:before {\n  content: \"\\e227\";\n}\n.glyphicon-xbt:before {\n  content: \"\\e227\";\n}\n.glyphicon-yen:before {\n  content: \"\\00a5\";\n}\n.glyphicon-jpy:before {\n  content: \"\\00a5\";\n}\n.glyphicon-ruble:before {\n  content: \"\\20bd\";\n}\n.glyphicon-rub:before {\n  content: \"\\20bd\";\n}\n.glyphicon-scale:before {\n  content: \"\\e230\";\n}\n.glyphicon-ice-lolly:before {\n  content: \"\\e231\";\n}\n.glyphicon-ice-lolly-tasted:before {\n  content: \"\\e232\";\n}\n.glyphicon-education:before {\n  content: \"\\e233\";\n}\n.glyphicon-option-horizontal:before {\n  content: \"\\e234\";\n}\n.glyphicon-option-vertical:before {\n  content: \"\\e235\";\n}\n.glyphicon-menu-hamburger:before {\n  content: \"\\e236\";\n}\n.glyphicon-modal-window:before {\n  content: \"\\e237\";\n}\n.glyphicon-oil:before {\n  content: \"\\e238\";\n}\n.glyphicon-grain:before {\n  content: \"\\e239\";\n}\n.glyphicon-sunglasses:before {\n  content: \"\\e240\";\n}\n.glyphicon-text-size:before {\n  content: \"\\e241\";\n}\n.glyphicon-text-color:before {\n  content: \"\\e242\";\n}\n.glyphicon-text-background:before {\n  content: \"\\e243\";\n}\n.glyphicon-object-align-top:before {\n  content: \"\\e244\";\n}\n.glyphicon-object-align-bottom:before {\n  content: \"\\e245\";\n}\n.glyphicon-object-align-horizontal:before {\n  content: \"\\e246\";\n}\n.glyphicon-object-align-left:before {\n  content: \"\\e247\";\n}\n.glyphicon-object-align-vertical:before {\n  content: \"\\e248\";\n}\n.glyphicon-object-align-right:before {\n  content: \"\\e249\";\n}\n.glyphicon-triangle-right:before {\n  content: \"\\e250\";\n}\n.glyphicon-triangle-left:before {\n  content: \"\\e251\";\n}\n.glyphicon-triangle-bottom:before {\n  content: \"\\e252\";\n}\n.glyphicon-triangle-top:before {\n  content: \"\\e253\";\n}\n.glyphicon-console:before {\n  content: \"\\e254\";\n}\n.glyphicon-superscript:before {\n  content: \"\\e255\";\n}\n.glyphicon-subscript:before {\n  content: \"\\e256\";\n}\n.glyphicon-menu-left:before {\n  content: \"\\e257\";\n}\n.glyphicon-menu-right:before {\n  content: \"\\e258\";\n}\n.glyphicon-menu-down:before {\n  content: \"\\e259\";\n}\n.glyphicon-menu-up:before {\n  content: \"\\e260\";\n}\n* {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\n*:before,\n*:after {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\nhtml {\n  font-size: 10px;\n\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\n}\nbody {\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #333;\n  background-color: #fff;\n}\ninput,\nbutton,\nselect,\ntextarea {\n  font-family: inherit;\n  font-size: inherit;\n  line-height: inherit;\n}\na {\n  color: #337ab7;\n  text-decoration: none;\n}\na:hover,\na:focus {\n  color: #23527c;\n  text-decoration: underline;\n}\na:focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\nfigure {\n  margin: 0;\n}\nimg {\n  vertical-align: middle;\n}\n.img-responsive,\n.thumbnail > img,\n.thumbnail a > img,\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  display: block;\n  max-width: 100%;\n  height: auto;\n}\n.img-rounded {\n  border-radius: 6px;\n}\n.img-thumbnail {\n  display: inline-block;\n  max-width: 100%;\n  height: auto;\n  padding: 4px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: all .2s ease-in-out;\n       -o-transition: all .2s ease-in-out;\n          transition: all .2s ease-in-out;\n}\n.img-circle {\n  border-radius: 50%;\n}\nhr {\n  margin-top: 20px;\n  margin-bottom: 20px;\n  border: 0;\n  border-top: 1px solid #eee;\n}\n.sr-only {\n  position: absolute;\n  width: 1px;\n  height: 1px;\n  padding: 0;\n  margin: -1px;\n  overflow: hidden;\n  clip: rect(0, 0, 0, 0);\n  border: 0;\n}\n.sr-only-focusable:active,\n.sr-only-focusable:focus {\n  position: static;\n  width: auto;\n  height: auto;\n  margin: 0;\n  overflow: visible;\n  clip: auto;\n}\n[role=\"button\"] {\n  cursor: pointer;\n}\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\n.h1,\n.h2,\n.h3,\n.h4,\n.h5,\n.h6 {\n  font-family: inherit;\n  font-weight: 500;\n  line-height: 1.1;\n  color: inherit;\n}\nh1 small,\nh2 small,\nh3 small,\nh4 small,\nh5 small,\nh6 small,\n.h1 small,\n.h2 small,\n.h3 small,\n.h4 small,\n.h5 small,\n.h6 small,\nh1 .small,\nh2 .small,\nh3 .small,\nh4 .small,\nh5 .small,\nh6 .small,\n.h1 .small,\n.h2 .small,\n.h3 .small,\n.h4 .small,\n.h5 .small,\n.h6 .small {\n  font-weight: normal;\n  line-height: 1;\n  color: #777;\n}\nh1,\n.h1,\nh2,\n.h2,\nh3,\n.h3 {\n  margin-top: 20px;\n  margin-bottom: 10px;\n}\nh1 small,\n.h1 small,\nh2 small,\n.h2 small,\nh3 small,\n.h3 small,\nh1 .small,\n.h1 .small,\nh2 .small,\n.h2 .small,\nh3 .small,\n.h3 .small {\n  font-size: 65%;\n}\nh4,\n.h4,\nh5,\n.h5,\nh6,\n.h6 {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\nh4 small,\n.h4 small,\nh5 small,\n.h5 small,\nh6 small,\n.h6 small,\nh4 .small,\n.h4 .small,\nh5 .small,\n.h5 .small,\nh6 .small,\n.h6 .small {\n  font-size: 75%;\n}\nh1,\n.h1 {\n  font-size: 36px;\n}\nh2,\n.h2 {\n  font-size: 30px;\n}\nh3,\n.h3 {\n  font-size: 24px;\n}\nh4,\n.h4 {\n  font-size: 18px;\n}\nh5,\n.h5 {\n  font-size: 14px;\n}\nh6,\n.h6 {\n  font-size: 12px;\n}\np {\n  margin: 0 0 10px;\n}\n.lead {\n  margin-bottom: 20px;\n  font-size: 16px;\n  font-weight: 300;\n  line-height: 1.4;\n}\n@media (min-width: 768px) {\n  .lead {\n    font-size: 21px;\n  }\n}\nsmall,\n.small {\n  font-size: 85%;\n}\nmark,\n.mark {\n  padding: .2em;\n  background-color: #fcf8e3;\n}\n.text-left {\n  text-align: left;\n}\n.text-right {\n  text-align: right;\n}\n.text-center {\n  text-align: center;\n}\n.text-justify {\n  text-align: justify;\n}\n.text-nowrap {\n  white-space: nowrap;\n}\n.text-lowercase {\n  text-transform: lowercase;\n}\n.text-uppercase {\n  text-transform: uppercase;\n}\n.text-capitalize {\n  text-transform: capitalize;\n}\n.text-muted {\n  color: #777;\n}\n.text-primary {\n  color: #337ab7;\n}\na.text-primary:hover,\na.text-primary:focus {\n  color: #286090;\n}\n.text-success {\n  color: #3c763d;\n}\na.text-success:hover,\na.text-success:focus {\n  color: #2b542c;\n}\n.text-info {\n  color: #31708f;\n}\na.text-info:hover,\na.text-info:focus {\n  color: #245269;\n}\n.text-warning {\n  color: #8a6d3b;\n}\na.text-warning:hover,\na.text-warning:focus {\n  color: #66512c;\n}\n.text-danger {\n  color: #a94442;\n}\na.text-danger:hover,\na.text-danger:focus {\n  color: #843534;\n}\n.bg-primary {\n  color: #fff;\n  background-color: #337ab7;\n}\na.bg-primary:hover,\na.bg-primary:focus {\n  background-color: #286090;\n}\n.bg-success {\n  background-color: #dff0d8;\n}\na.bg-success:hover,\na.bg-success:focus {\n  background-color: #c1e2b3;\n}\n.bg-info {\n  background-color: #d9edf7;\n}\na.bg-info:hover,\na.bg-info:focus {\n  background-color: #afd9ee;\n}\n.bg-warning {\n  background-color: #fcf8e3;\n}\na.bg-warning:hover,\na.bg-warning:focus {\n  background-color: #f7ecb5;\n}\n.bg-danger {\n  background-color: #f2dede;\n}\na.bg-danger:hover,\na.bg-danger:focus {\n  background-color: #e4b9b9;\n}\n.page-header {\n  padding-bottom: 9px;\n  margin: 40px 0 20px;\n  border-bottom: 1px solid #eee;\n}\nul,\nol {\n  margin-top: 0;\n  margin-bottom: 10px;\n}\nul ul,\nol ul,\nul ol,\nol ol {\n  margin-bottom: 0;\n}\n.list-unstyled {\n  padding-left: 0;\n  list-style: none;\n}\n.list-inline {\n  padding-left: 0;\n  margin-left: -5px;\n  list-style: none;\n}\n.list-inline > li {\n  display: inline-block;\n  padding-right: 5px;\n  padding-left: 5px;\n}\ndl {\n  margin-top: 0;\n  margin-bottom: 20px;\n}\ndt,\ndd {\n  line-height: 1.42857143;\n}\ndt {\n  font-weight: bold;\n}\ndd {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .dl-horizontal dt {\n    float: left;\n    width: 160px;\n    overflow: hidden;\n    clear: left;\n    text-align: right;\n    text-overflow: ellipsis;\n    white-space: nowrap;\n  }\n  .dl-horizontal dd {\n    margin-left: 180px;\n  }\n}\nabbr[title],\nabbr[data-original-title] {\n  cursor: help;\n  border-bottom: 1px dotted #777;\n}\n.initialism {\n  font-size: 90%;\n  text-transform: uppercase;\n}\nblockquote {\n  padding: 10px 20px;\n  margin: 0 0 20px;\n  font-size: 17.5px;\n  border-left: 5px solid #eee;\n}\nblockquote p:last-child,\nblockquote ul:last-child,\nblockquote ol:last-child {\n  margin-bottom: 0;\n}\nblockquote footer,\nblockquote small,\nblockquote .small {\n  display: block;\n  font-size: 80%;\n  line-height: 1.42857143;\n  color: #777;\n}\nblockquote footer:before,\nblockquote small:before,\nblockquote .small:before {\n  content: '\\2014 \\00A0';\n}\n.blockquote-reverse,\nblockquote.pull-right {\n  padding-right: 15px;\n  padding-left: 0;\n  text-align: right;\n  border-right: 5px solid #eee;\n  border-left: 0;\n}\n.blockquote-reverse footer:before,\nblockquote.pull-right footer:before,\n.blockquote-reverse small:before,\nblockquote.pull-right small:before,\n.blockquote-reverse .small:before,\nblockquote.pull-right .small:before {\n  content: '';\n}\n.blockquote-reverse footer:after,\nblockquote.pull-right footer:after,\n.blockquote-reverse small:after,\nblockquote.pull-right small:after,\n.blockquote-reverse .small:after,\nblockquote.pull-right .small:after {\n  content: '\\00A0 \\2014';\n}\naddress {\n  margin-bottom: 20px;\n  font-style: normal;\n  line-height: 1.42857143;\n}\ncode,\nkbd,\npre,\nsamp {\n  font-family: Menlo, Monaco, Consolas, \"Courier New\", monospace;\n}\ncode {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #c7254e;\n  background-color: #f9f2f4;\n  border-radius: 4px;\n}\nkbd {\n  padding: 2px 4px;\n  font-size: 90%;\n  color: #fff;\n  background-color: #333;\n  border-radius: 3px;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .25);\n}\nkbd kbd {\n  padding: 0;\n  font-size: 100%;\n  font-weight: bold;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\npre {\n  display: block;\n  padding: 9.5px;\n  margin: 0 0 10px;\n  font-size: 13px;\n  line-height: 1.42857143;\n  color: #333;\n  word-break: break-all;\n  word-wrap: break-word;\n  background-color: #f5f5f5;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\npre code {\n  padding: 0;\n  font-size: inherit;\n  color: inherit;\n  white-space: pre-wrap;\n  background-color: transparent;\n  border-radius: 0;\n}\n.pre-scrollable {\n  max-height: 340px;\n  overflow-y: scroll;\n}\n.container {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n@media (min-width: 768px) {\n  .container {\n    width: 750px;\n  }\n}\n@media (min-width: 992px) {\n  .container {\n    width: 970px;\n  }\n}\n@media (min-width: 1200px) {\n  .container {\n    width: 1170px;\n  }\n}\n.container-fluid {\n  padding-right: 15px;\n  padding-left: 15px;\n  margin-right: auto;\n  margin-left: auto;\n}\n.row {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n.col-xs-1, .col-sm-1, .col-md-1, .col-lg-1, .col-xs-2, .col-sm-2, .col-md-2, .col-lg-2, .col-xs-3, .col-sm-3, .col-md-3, .col-lg-3, .col-xs-4, .col-sm-4, .col-md-4, .col-lg-4, .col-xs-5, .col-sm-5, .col-md-5, .col-lg-5, .col-xs-6, .col-sm-6, .col-md-6, .col-lg-6, .col-xs-7, .col-sm-7, .col-md-7, .col-lg-7, .col-xs-8, .col-sm-8, .col-md-8, .col-lg-8, .col-xs-9, .col-sm-9, .col-md-9, .col-lg-9, .col-xs-10, .col-sm-10, .col-md-10, .col-lg-10, .col-xs-11, .col-sm-11, .col-md-11, .col-lg-11, .col-xs-12, .col-sm-12, .col-md-12, .col-lg-12 {\n  position: relative;\n  min-height: 1px;\n  padding-right: 15px;\n  padding-left: 15px;\n}\n.col-xs-1, .col-xs-2, .col-xs-3, .col-xs-4, .col-xs-5, .col-xs-6, .col-xs-7, .col-xs-8, .col-xs-9, .col-xs-10, .col-xs-11, .col-xs-12 {\n  float: left;\n}\n.col-xs-12 {\n  width: 100%;\n}\n.col-xs-11 {\n  width: 91.66666667%;\n}\n.col-xs-10 {\n  width: 83.33333333%;\n}\n.col-xs-9 {\n  width: 75%;\n}\n.col-xs-8 {\n  width: 66.66666667%;\n}\n.col-xs-7 {\n  width: 58.33333333%;\n}\n.col-xs-6 {\n  width: 50%;\n}\n.col-xs-5 {\n  width: 41.66666667%;\n}\n.col-xs-4 {\n  width: 33.33333333%;\n}\n.col-xs-3 {\n  width: 25%;\n}\n.col-xs-2 {\n  width: 16.66666667%;\n}\n.col-xs-1 {\n  width: 8.33333333%;\n}\n.col-xs-pull-12 {\n  right: 100%;\n}\n.col-xs-pull-11 {\n  right: 91.66666667%;\n}\n.col-xs-pull-10 {\n  right: 83.33333333%;\n}\n.col-xs-pull-9 {\n  right: 75%;\n}\n.col-xs-pull-8 {\n  right: 66.66666667%;\n}\n.col-xs-pull-7 {\n  right: 58.33333333%;\n}\n.col-xs-pull-6 {\n  right: 50%;\n}\n.col-xs-pull-5 {\n  right: 41.66666667%;\n}\n.col-xs-pull-4 {\n  right: 33.33333333%;\n}\n.col-xs-pull-3 {\n  right: 25%;\n}\n.col-xs-pull-2 {\n  right: 16.66666667%;\n}\n.col-xs-pull-1 {\n  right: 8.33333333%;\n}\n.col-xs-pull-0 {\n  right: auto;\n}\n.col-xs-push-12 {\n  left: 100%;\n}\n.col-xs-push-11 {\n  left: 91.66666667%;\n}\n.col-xs-push-10 {\n  left: 83.33333333%;\n}\n.col-xs-push-9 {\n  left: 75%;\n}\n.col-xs-push-8 {\n  left: 66.66666667%;\n}\n.col-xs-push-7 {\n  left: 58.33333333%;\n}\n.col-xs-push-6 {\n  left: 50%;\n}\n.col-xs-push-5 {\n  left: 41.66666667%;\n}\n.col-xs-push-4 {\n  left: 33.33333333%;\n}\n.col-xs-push-3 {\n  left: 25%;\n}\n.col-xs-push-2 {\n  left: 16.66666667%;\n}\n.col-xs-push-1 {\n  left: 8.33333333%;\n}\n.col-xs-push-0 {\n  left: auto;\n}\n.col-xs-offset-12 {\n  margin-left: 100%;\n}\n.col-xs-offset-11 {\n  margin-left: 91.66666667%;\n}\n.col-xs-offset-10 {\n  margin-left: 83.33333333%;\n}\n.col-xs-offset-9 {\n  margin-left: 75%;\n}\n.col-xs-offset-8 {\n  margin-left: 66.66666667%;\n}\n.col-xs-offset-7 {\n  margin-left: 58.33333333%;\n}\n.col-xs-offset-6 {\n  margin-left: 50%;\n}\n.col-xs-offset-5 {\n  margin-left: 41.66666667%;\n}\n.col-xs-offset-4 {\n  margin-left: 33.33333333%;\n}\n.col-xs-offset-3 {\n  margin-left: 25%;\n}\n.col-xs-offset-2 {\n  margin-left: 16.66666667%;\n}\n.col-xs-offset-1 {\n  margin-left: 8.33333333%;\n}\n.col-xs-offset-0 {\n  margin-left: 0;\n}\n@media (min-width: 768px) {\n  .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {\n    float: left;\n  }\n  .col-sm-12 {\n    width: 100%;\n  }\n  .col-sm-11 {\n    width: 91.66666667%;\n  }\n  .col-sm-10 {\n    width: 83.33333333%;\n  }\n  .col-sm-9 {\n    width: 75%;\n  }\n  .col-sm-8 {\n    width: 66.66666667%;\n  }\n  .col-sm-7 {\n    width: 58.33333333%;\n  }\n  .col-sm-6 {\n    width: 50%;\n  }\n  .col-sm-5 {\n    width: 41.66666667%;\n  }\n  .col-sm-4 {\n    width: 33.33333333%;\n  }\n  .col-sm-3 {\n    width: 25%;\n  }\n  .col-sm-2 {\n    width: 16.66666667%;\n  }\n  .col-sm-1 {\n    width: 8.33333333%;\n  }\n  .col-sm-pull-12 {\n    right: 100%;\n  }\n  .col-sm-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-sm-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-sm-pull-9 {\n    right: 75%;\n  }\n  .col-sm-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-sm-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-sm-pull-6 {\n    right: 50%;\n  }\n  .col-sm-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-sm-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-sm-pull-3 {\n    right: 25%;\n  }\n  .col-sm-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-sm-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-sm-pull-0 {\n    right: auto;\n  }\n  .col-sm-push-12 {\n    left: 100%;\n  }\n  .col-sm-push-11 {\n    left: 91.66666667%;\n  }\n  .col-sm-push-10 {\n    left: 83.33333333%;\n  }\n  .col-sm-push-9 {\n    left: 75%;\n  }\n  .col-sm-push-8 {\n    left: 66.66666667%;\n  }\n  .col-sm-push-7 {\n    left: 58.33333333%;\n  }\n  .col-sm-push-6 {\n    left: 50%;\n  }\n  .col-sm-push-5 {\n    left: 41.66666667%;\n  }\n  .col-sm-push-4 {\n    left: 33.33333333%;\n  }\n  .col-sm-push-3 {\n    left: 25%;\n  }\n  .col-sm-push-2 {\n    left: 16.66666667%;\n  }\n  .col-sm-push-1 {\n    left: 8.33333333%;\n  }\n  .col-sm-push-0 {\n    left: auto;\n  }\n  .col-sm-offset-12 {\n    margin-left: 100%;\n  }\n  .col-sm-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-sm-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-sm-offset-9 {\n    margin-left: 75%;\n  }\n  .col-sm-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-sm-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-sm-offset-6 {\n    margin-left: 50%;\n  }\n  .col-sm-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-sm-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-sm-offset-3 {\n    margin-left: 25%;\n  }\n  .col-sm-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-sm-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-sm-offset-0 {\n    margin-left: 0;\n  }\n}\n@media (min-width: 992px) {\n  .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, .col-md-9, .col-md-10, .col-md-11, .col-md-12 {\n    float: left;\n  }\n  .col-md-12 {\n    width: 100%;\n  }\n  .col-md-11 {\n    width: 91.66666667%;\n  }\n  .col-md-10 {\n    width: 83.33333333%;\n  }\n  .col-md-9 {\n    width: 75%;\n  }\n  .col-md-8 {\n    width: 66.66666667%;\n  }\n  .col-md-7 {\n    width: 58.33333333%;\n  }\n  .col-md-6 {\n    width: 50%;\n  }\n  .col-md-5 {\n    width: 41.66666667%;\n  }\n  .col-md-4 {\n    width: 33.33333333%;\n  }\n  .col-md-3 {\n    width: 25%;\n  }\n  .col-md-2 {\n    width: 16.66666667%;\n  }\n  .col-md-1 {\n    width: 8.33333333%;\n  }\n  .col-md-pull-12 {\n    right: 100%;\n  }\n  .col-md-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-md-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-md-pull-9 {\n    right: 75%;\n  }\n  .col-md-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-md-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-md-pull-6 {\n    right: 50%;\n  }\n  .col-md-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-md-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-md-pull-3 {\n    right: 25%;\n  }\n  .col-md-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-md-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-md-pull-0 {\n    right: auto;\n  }\n  .col-md-push-12 {\n    left: 100%;\n  }\n  .col-md-push-11 {\n    left: 91.66666667%;\n  }\n  .col-md-push-10 {\n    left: 83.33333333%;\n  }\n  .col-md-push-9 {\n    left: 75%;\n  }\n  .col-md-push-8 {\n    left: 66.66666667%;\n  }\n  .col-md-push-7 {\n    left: 58.33333333%;\n  }\n  .col-md-push-6 {\n    left: 50%;\n  }\n  .col-md-push-5 {\n    left: 41.66666667%;\n  }\n  .col-md-push-4 {\n    left: 33.33333333%;\n  }\n  .col-md-push-3 {\n    left: 25%;\n  }\n  .col-md-push-2 {\n    left: 16.66666667%;\n  }\n  .col-md-push-1 {\n    left: 8.33333333%;\n  }\n  .col-md-push-0 {\n    left: auto;\n  }\n  .col-md-offset-12 {\n    margin-left: 100%;\n  }\n  .col-md-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-md-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-md-offset-9 {\n    margin-left: 75%;\n  }\n  .col-md-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-md-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-md-offset-6 {\n    margin-left: 50%;\n  }\n  .col-md-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-md-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-md-offset-3 {\n    margin-left: 25%;\n  }\n  .col-md-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-md-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-md-offset-0 {\n    margin-left: 0;\n  }\n}\n@media (min-width: 1200px) {\n  .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, .col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12 {\n    float: left;\n  }\n  .col-lg-12 {\n    width: 100%;\n  }\n  .col-lg-11 {\n    width: 91.66666667%;\n  }\n  .col-lg-10 {\n    width: 83.33333333%;\n  }\n  .col-lg-9 {\n    width: 75%;\n  }\n  .col-lg-8 {\n    width: 66.66666667%;\n  }\n  .col-lg-7 {\n    width: 58.33333333%;\n  }\n  .col-lg-6 {\n    width: 50%;\n  }\n  .col-lg-5 {\n    width: 41.66666667%;\n  }\n  .col-lg-4 {\n    width: 33.33333333%;\n  }\n  .col-lg-3 {\n    width: 25%;\n  }\n  .col-lg-2 {\n    width: 16.66666667%;\n  }\n  .col-lg-1 {\n    width: 8.33333333%;\n  }\n  .col-lg-pull-12 {\n    right: 100%;\n  }\n  .col-lg-pull-11 {\n    right: 91.66666667%;\n  }\n  .col-lg-pull-10 {\n    right: 83.33333333%;\n  }\n  .col-lg-pull-9 {\n    right: 75%;\n  }\n  .col-lg-pull-8 {\n    right: 66.66666667%;\n  }\n  .col-lg-pull-7 {\n    right: 58.33333333%;\n  }\n  .col-lg-pull-6 {\n    right: 50%;\n  }\n  .col-lg-pull-5 {\n    right: 41.66666667%;\n  }\n  .col-lg-pull-4 {\n    right: 33.33333333%;\n  }\n  .col-lg-pull-3 {\n    right: 25%;\n  }\n  .col-lg-pull-2 {\n    right: 16.66666667%;\n  }\n  .col-lg-pull-1 {\n    right: 8.33333333%;\n  }\n  .col-lg-pull-0 {\n    right: auto;\n  }\n  .col-lg-push-12 {\n    left: 100%;\n  }\n  .col-lg-push-11 {\n    left: 91.66666667%;\n  }\n  .col-lg-push-10 {\n    left: 83.33333333%;\n  }\n  .col-lg-push-9 {\n    left: 75%;\n  }\n  .col-lg-push-8 {\n    left: 66.66666667%;\n  }\n  .col-lg-push-7 {\n    left: 58.33333333%;\n  }\n  .col-lg-push-6 {\n    left: 50%;\n  }\n  .col-lg-push-5 {\n    left: 41.66666667%;\n  }\n  .col-lg-push-4 {\n    left: 33.33333333%;\n  }\n  .col-lg-push-3 {\n    left: 25%;\n  }\n  .col-lg-push-2 {\n    left: 16.66666667%;\n  }\n  .col-lg-push-1 {\n    left: 8.33333333%;\n  }\n  .col-lg-push-0 {\n    left: auto;\n  }\n  .col-lg-offset-12 {\n    margin-left: 100%;\n  }\n  .col-lg-offset-11 {\n    margin-left: 91.66666667%;\n  }\n  .col-lg-offset-10 {\n    margin-left: 83.33333333%;\n  }\n  .col-lg-offset-9 {\n    margin-left: 75%;\n  }\n  .col-lg-offset-8 {\n    margin-left: 66.66666667%;\n  }\n  .col-lg-offset-7 {\n    margin-left: 58.33333333%;\n  }\n  .col-lg-offset-6 {\n    margin-left: 50%;\n  }\n  .col-lg-offset-5 {\n    margin-left: 41.66666667%;\n  }\n  .col-lg-offset-4 {\n    margin-left: 33.33333333%;\n  }\n  .col-lg-offset-3 {\n    margin-left: 25%;\n  }\n  .col-lg-offset-2 {\n    margin-left: 16.66666667%;\n  }\n  .col-lg-offset-1 {\n    margin-left: 8.33333333%;\n  }\n  .col-lg-offset-0 {\n    margin-left: 0;\n  }\n}\ntable {\n  background-color: transparent;\n}\ncaption {\n  padding-top: 8px;\n  padding-bottom: 8px;\n  color: #777;\n  text-align: left;\n}\nth {\n  text-align: left;\n}\n.table {\n  width: 100%;\n  max-width: 100%;\n  margin-bottom: 20px;\n}\n.table > thead > tr > th,\n.table > tbody > tr > th,\n.table > tfoot > tr > th,\n.table > thead > tr > td,\n.table > tbody > tr > td,\n.table > tfoot > tr > td {\n  padding: 8px;\n  line-height: 1.42857143;\n  vertical-align: top;\n  border-top: 1px solid #ddd;\n}\n.table > thead > tr > th {\n  vertical-align: bottom;\n  border-bottom: 2px solid #ddd;\n}\n.table > caption + thead > tr:first-child > th,\n.table > colgroup + thead > tr:first-child > th,\n.table > thead:first-child > tr:first-child > th,\n.table > caption + thead > tr:first-child > td,\n.table > colgroup + thead > tr:first-child > td,\n.table > thead:first-child > tr:first-child > td {\n  border-top: 0;\n}\n.table > tbody + tbody {\n  border-top: 2px solid #ddd;\n}\n.table .table {\n  background-color: #fff;\n}\n.table-condensed > thead > tr > th,\n.table-condensed > tbody > tr > th,\n.table-condensed > tfoot > tr > th,\n.table-condensed > thead > tr > td,\n.table-condensed > tbody > tr > td,\n.table-condensed > tfoot > tr > td {\n  padding: 5px;\n}\n.table-bordered {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > tbody > tr > th,\n.table-bordered > tfoot > tr > th,\n.table-bordered > thead > tr > td,\n.table-bordered > tbody > tr > td,\n.table-bordered > tfoot > tr > td {\n  border: 1px solid #ddd;\n}\n.table-bordered > thead > tr > th,\n.table-bordered > thead > tr > td {\n  border-bottom-width: 2px;\n}\n.table-striped > tbody > tr:nth-of-type(odd) {\n  background-color: #f9f9f9;\n}\n.table-hover > tbody > tr:hover {\n  background-color: #f5f5f5;\n}\ntable col[class*=\"col-\"] {\n  position: static;\n  display: table-column;\n  float: none;\n}\ntable td[class*=\"col-\"],\ntable th[class*=\"col-\"] {\n  position: static;\n  display: table-cell;\n  float: none;\n}\n.table > thead > tr > td.active,\n.table > tbody > tr > td.active,\n.table > tfoot > tr > td.active,\n.table > thead > tr > th.active,\n.table > tbody > tr > th.active,\n.table > tfoot > tr > th.active,\n.table > thead > tr.active > td,\n.table > tbody > tr.active > td,\n.table > tfoot > tr.active > td,\n.table > thead > tr.active > th,\n.table > tbody > tr.active > th,\n.table > tfoot > tr.active > th {\n  background-color: #f5f5f5;\n}\n.table-hover > tbody > tr > td.active:hover,\n.table-hover > tbody > tr > th.active:hover,\n.table-hover > tbody > tr.active:hover > td,\n.table-hover > tbody > tr:hover > .active,\n.table-hover > tbody > tr.active:hover > th {\n  background-color: #e8e8e8;\n}\n.table > thead > tr > td.success,\n.table > tbody > tr > td.success,\n.table > tfoot > tr > td.success,\n.table > thead > tr > th.success,\n.table > tbody > tr > th.success,\n.table > tfoot > tr > th.success,\n.table > thead > tr.success > td,\n.table > tbody > tr.success > td,\n.table > tfoot > tr.success > td,\n.table > thead > tr.success > th,\n.table > tbody > tr.success > th,\n.table > tfoot > tr.success > th {\n  background-color: #dff0d8;\n}\n.table-hover > tbody > tr > td.success:hover,\n.table-hover > tbody > tr > th.success:hover,\n.table-hover > tbody > tr.success:hover > td,\n.table-hover > tbody > tr:hover > .success,\n.table-hover > tbody > tr.success:hover > th {\n  background-color: #d0e9c6;\n}\n.table > thead > tr > td.info,\n.table > tbody > tr > td.info,\n.table > tfoot > tr > td.info,\n.table > thead > tr > th.info,\n.table > tbody > tr > th.info,\n.table > tfoot > tr > th.info,\n.table > thead > tr.info > td,\n.table > tbody > tr.info > td,\n.table > tfoot > tr.info > td,\n.table > thead > tr.info > th,\n.table > tbody > tr.info > th,\n.table > tfoot > tr.info > th {\n  background-color: #d9edf7;\n}\n.table-hover > tbody > tr > td.info:hover,\n.table-hover > tbody > tr > th.info:hover,\n.table-hover > tbody > tr.info:hover > td,\n.table-hover > tbody > tr:hover > .info,\n.table-hover > tbody > tr.info:hover > th {\n  background-color: #c4e3f3;\n}\n.table > thead > tr > td.warning,\n.table > tbody > tr > td.warning,\n.table > tfoot > tr > td.warning,\n.table > thead > tr > th.warning,\n.table > tbody > tr > th.warning,\n.table > tfoot > tr > th.warning,\n.table > thead > tr.warning > td,\n.table > tbody > tr.warning > td,\n.table > tfoot > tr.warning > td,\n.table > thead > tr.warning > th,\n.table > tbody > tr.warning > th,\n.table > tfoot > tr.warning > th {\n  background-color: #fcf8e3;\n}\n.table-hover > tbody > tr > td.warning:hover,\n.table-hover > tbody > tr > th.warning:hover,\n.table-hover > tbody > tr.warning:hover > td,\n.table-hover > tbody > tr:hover > .warning,\n.table-hover > tbody > tr.warning:hover > th {\n  background-color: #faf2cc;\n}\n.table > thead > tr > td.danger,\n.table > tbody > tr > td.danger,\n.table > tfoot > tr > td.danger,\n.table > thead > tr > th.danger,\n.table > tbody > tr > th.danger,\n.table > tfoot > tr > th.danger,\n.table > thead > tr.danger > td,\n.table > tbody > tr.danger > td,\n.table > tfoot > tr.danger > td,\n.table > thead > tr.danger > th,\n.table > tbody > tr.danger > th,\n.table > tfoot > tr.danger > th {\n  background-color: #f2dede;\n}\n.table-hover > tbody > tr > td.danger:hover,\n.table-hover > tbody > tr > th.danger:hover,\n.table-hover > tbody > tr.danger:hover > td,\n.table-hover > tbody > tr:hover > .danger,\n.table-hover > tbody > tr.danger:hover > th {\n  background-color: #ebcccc;\n}\n.table-responsive {\n  min-height: .01%;\n  overflow-x: auto;\n}\n@media screen and (max-width: 767px) {\n  .table-responsive {\n    width: 100%;\n    margin-bottom: 15px;\n    overflow-y: hidden;\n    -ms-overflow-style: -ms-autohiding-scrollbar;\n    border: 1px solid #ddd;\n  }\n  .table-responsive > .table {\n    margin-bottom: 0;\n  }\n  .table-responsive > .table > thead > tr > th,\n  .table-responsive > .table > tbody > tr > th,\n  .table-responsive > .table > tfoot > tr > th,\n  .table-responsive > .table > thead > tr > td,\n  .table-responsive > .table > tbody > tr > td,\n  .table-responsive > .table > tfoot > tr > td {\n    white-space: nowrap;\n  }\n  .table-responsive > .table-bordered {\n    border: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:first-child,\n  .table-responsive > .table-bordered > tbody > tr > th:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n  .table-responsive > .table-bordered > thead > tr > td:first-child,\n  .table-responsive > .table-bordered > tbody > tr > td:first-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n    border-left: 0;\n  }\n  .table-responsive > .table-bordered > thead > tr > th:last-child,\n  .table-responsive > .table-bordered > tbody > tr > th:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n  .table-responsive > .table-bordered > thead > tr > td:last-child,\n  .table-responsive > .table-bordered > tbody > tr > td:last-child,\n  .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n    border-right: 0;\n  }\n  .table-responsive > .table-bordered > tbody > tr:last-child > th,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > th,\n  .table-responsive > .table-bordered > tbody > tr:last-child > td,\n  .table-responsive > .table-bordered > tfoot > tr:last-child > td {\n    border-bottom: 0;\n  }\n}\nfieldset {\n  min-width: 0;\n  padding: 0;\n  margin: 0;\n  border: 0;\n}\nlegend {\n  display: block;\n  width: 100%;\n  padding: 0;\n  margin-bottom: 20px;\n  font-size: 21px;\n  line-height: inherit;\n  color: #333;\n  border: 0;\n  border-bottom: 1px solid #e5e5e5;\n}\nlabel {\n  display: inline-block;\n  max-width: 100%;\n  margin-bottom: 5px;\n  font-weight: bold;\n}\ninput[type=\"search\"] {\n  -webkit-box-sizing: border-box;\n     -moz-box-sizing: border-box;\n          box-sizing: border-box;\n}\ninput[type=\"radio\"],\ninput[type=\"checkbox\"] {\n  margin: 4px 0 0;\n  margin-top: 1px \\9;\n  line-height: normal;\n}\ninput[type=\"file\"] {\n  display: block;\n}\ninput[type=\"range\"] {\n  display: block;\n  width: 100%;\n}\nselect[multiple],\nselect[size] {\n  height: auto;\n}\ninput[type=\"file\"]:focus,\ninput[type=\"radio\"]:focus,\ninput[type=\"checkbox\"]:focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\noutput {\n  display: block;\n  padding-top: 7px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555;\n}\n.form-control {\n  display: block;\n  width: 100%;\n  height: 34px;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 1.42857143;\n  color: #555;\n  background-color: #fff;\n  background-image: none;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n  -webkit-transition: border-color ease-in-out .15s, -webkit-box-shadow ease-in-out .15s;\n       -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n          transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.form-control:focus {\n  border-color: #66afe9;\n  outline: 0;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n          box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, .6);\n}\n.form-control::-moz-placeholder {\n  color: #999;\n  opacity: 1;\n}\n.form-control:-ms-input-placeholder {\n  color: #999;\n}\n.form-control::-webkit-input-placeholder {\n  color: #999;\n}\n.form-control::-ms-expand {\n  background-color: transparent;\n  border: 0;\n}\n.form-control[disabled],\n.form-control[readonly],\nfieldset[disabled] .form-control {\n  background-color: #eee;\n  opacity: 1;\n}\n.form-control[disabled],\nfieldset[disabled] .form-control {\n  cursor: not-allowed;\n}\ntextarea.form-control {\n  height: auto;\n}\ninput[type=\"search\"] {\n  -webkit-appearance: none;\n}\n@media screen and (-webkit-min-device-pixel-ratio: 0) {\n  input[type=\"date\"].form-control,\n  input[type=\"time\"].form-control,\n  input[type=\"datetime-local\"].form-control,\n  input[type=\"month\"].form-control {\n    line-height: 34px;\n  }\n  input[type=\"date\"].input-sm,\n  input[type=\"time\"].input-sm,\n  input[type=\"datetime-local\"].input-sm,\n  input[type=\"month\"].input-sm,\n  .input-group-sm input[type=\"date\"],\n  .input-group-sm input[type=\"time\"],\n  .input-group-sm input[type=\"datetime-local\"],\n  .input-group-sm input[type=\"month\"] {\n    line-height: 30px;\n  }\n  input[type=\"date\"].input-lg,\n  input[type=\"time\"].input-lg,\n  input[type=\"datetime-local\"].input-lg,\n  input[type=\"month\"].input-lg,\n  .input-group-lg input[type=\"date\"],\n  .input-group-lg input[type=\"time\"],\n  .input-group-lg input[type=\"datetime-local\"],\n  .input-group-lg input[type=\"month\"] {\n    line-height: 46px;\n  }\n}\n.form-group {\n  margin-bottom: 15px;\n}\n.radio,\n.checkbox {\n  position: relative;\n  display: block;\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.radio label,\n.checkbox label {\n  min-height: 20px;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  cursor: pointer;\n}\n.radio input[type=\"radio\"],\n.radio-inline input[type=\"radio\"],\n.checkbox input[type=\"checkbox\"],\n.checkbox-inline input[type=\"checkbox\"] {\n  position: absolute;\n  margin-top: 4px \\9;\n  margin-left: -20px;\n}\n.radio + .radio,\n.checkbox + .checkbox {\n  margin-top: -5px;\n}\n.radio-inline,\n.checkbox-inline {\n  position: relative;\n  display: inline-block;\n  padding-left: 20px;\n  margin-bottom: 0;\n  font-weight: normal;\n  vertical-align: middle;\n  cursor: pointer;\n}\n.radio-inline + .radio-inline,\n.checkbox-inline + .checkbox-inline {\n  margin-top: 0;\n  margin-left: 10px;\n}\ninput[type=\"radio\"][disabled],\ninput[type=\"checkbox\"][disabled],\ninput[type=\"radio\"].disabled,\ninput[type=\"checkbox\"].disabled,\nfieldset[disabled] input[type=\"radio\"],\nfieldset[disabled] input[type=\"checkbox\"] {\n  cursor: not-allowed;\n}\n.radio-inline.disabled,\n.checkbox-inline.disabled,\nfieldset[disabled] .radio-inline,\nfieldset[disabled] .checkbox-inline {\n  cursor: not-allowed;\n}\n.radio.disabled label,\n.checkbox.disabled label,\nfieldset[disabled] .radio label,\nfieldset[disabled] .checkbox label {\n  cursor: not-allowed;\n}\n.form-control-static {\n  min-height: 34px;\n  padding-top: 7px;\n  padding-bottom: 7px;\n  margin-bottom: 0;\n}\n.form-control-static.input-lg,\n.form-control-static.input-sm {\n  padding-right: 0;\n  padding-left: 0;\n}\n.input-sm {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-sm {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-sm,\nselect[multiple].input-sm {\n  height: auto;\n}\n.form-group-sm .form-control {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.form-group-sm select.form-control {\n  height: 30px;\n  line-height: 30px;\n}\n.form-group-sm textarea.form-control,\n.form-group-sm select[multiple].form-control {\n  height: auto;\n}\n.form-group-sm .form-control-static {\n  height: 30px;\n  min-height: 32px;\n  padding: 6px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.input-lg {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-lg {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-lg,\nselect[multiple].input-lg {\n  height: auto;\n}\n.form-group-lg .form-control {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.form-group-lg select.form-control {\n  height: 46px;\n  line-height: 46px;\n}\n.form-group-lg textarea.form-control,\n.form-group-lg select[multiple].form-control {\n  height: auto;\n}\n.form-group-lg .form-control-static {\n  height: 46px;\n  min-height: 38px;\n  padding: 11px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.has-feedback {\n  position: relative;\n}\n.has-feedback .form-control {\n  padding-right: 42.5px;\n}\n.form-control-feedback {\n  position: absolute;\n  top: 0;\n  right: 0;\n  z-index: 2;\n  display: block;\n  width: 34px;\n  height: 34px;\n  line-height: 34px;\n  text-align: center;\n  pointer-events: none;\n}\n.input-lg + .form-control-feedback,\n.input-group-lg + .form-control-feedback,\n.form-group-lg .form-control + .form-control-feedback {\n  width: 46px;\n  height: 46px;\n  line-height: 46px;\n}\n.input-sm + .form-control-feedback,\n.input-group-sm + .form-control-feedback,\n.form-group-sm .form-control + .form-control-feedback {\n  width: 30px;\n  height: 30px;\n  line-height: 30px;\n}\n.has-success .help-block,\n.has-success .control-label,\n.has-success .radio,\n.has-success .checkbox,\n.has-success .radio-inline,\n.has-success .checkbox-inline,\n.has-success.radio label,\n.has-success.checkbox label,\n.has-success.radio-inline label,\n.has-success.checkbox-inline label {\n  color: #3c763d;\n}\n.has-success .form-control {\n  border-color: #3c763d;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-success .form-control:focus {\n  border-color: #2b542c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #67b168;\n}\n.has-success .input-group-addon {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #3c763d;\n}\n.has-success .form-control-feedback {\n  color: #3c763d;\n}\n.has-warning .help-block,\n.has-warning .control-label,\n.has-warning .radio,\n.has-warning .checkbox,\n.has-warning .radio-inline,\n.has-warning .checkbox-inline,\n.has-warning.radio label,\n.has-warning.checkbox label,\n.has-warning.radio-inline label,\n.has-warning.checkbox-inline label {\n  color: #8a6d3b;\n}\n.has-warning .form-control {\n  border-color: #8a6d3b;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-warning .form-control:focus {\n  border-color: #66512c;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #c0a16b;\n}\n.has-warning .input-group-addon {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #8a6d3b;\n}\n.has-warning .form-control-feedback {\n  color: #8a6d3b;\n}\n.has-error .help-block,\n.has-error .control-label,\n.has-error .radio,\n.has-error .checkbox,\n.has-error .radio-inline,\n.has-error .checkbox-inline,\n.has-error.radio label,\n.has-error.checkbox label,\n.has-error.radio-inline label,\n.has-error.checkbox-inline label {\n  color: #a94442;\n}\n.has-error .form-control {\n  border-color: #a94442;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\n}\n.has-error .form-control:focus {\n  border-color: #843534;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 6px #ce8483;\n}\n.has-error .input-group-addon {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #a94442;\n}\n.has-error .form-control-feedback {\n  color: #a94442;\n}\n.has-feedback label ~ .form-control-feedback {\n  top: 25px;\n}\n.has-feedback label.sr-only ~ .form-control-feedback {\n  top: 0;\n}\n.help-block {\n  display: block;\n  margin-top: 5px;\n  margin-bottom: 10px;\n  color: #737373;\n}\n@media (min-width: 768px) {\n  .form-inline .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .form-inline .form-control-static {\n    display: inline-block;\n  }\n  .form-inline .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .form-inline .input-group .input-group-addon,\n  .form-inline .input-group .input-group-btn,\n  .form-inline .input-group .form-control {\n    width: auto;\n  }\n  .form-inline .input-group > .form-control {\n    width: 100%;\n  }\n  .form-inline .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio,\n  .form-inline .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .form-inline .radio label,\n  .form-inline .checkbox label {\n    padding-left: 0;\n  }\n  .form-inline .radio input[type=\"radio\"],\n  .form-inline .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .form-inline .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox,\n.form-horizontal .radio-inline,\n.form-horizontal .checkbox-inline {\n  padding-top: 7px;\n  margin-top: 0;\n  margin-bottom: 0;\n}\n.form-horizontal .radio,\n.form-horizontal .checkbox {\n  min-height: 27px;\n}\n.form-horizontal .form-group {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .control-label {\n    padding-top: 7px;\n    margin-bottom: 0;\n    text-align: right;\n  }\n}\n.form-horizontal .has-feedback .form-control-feedback {\n  right: 15px;\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-lg .control-label {\n    padding-top: 11px;\n    font-size: 18px;\n  }\n}\n@media (min-width: 768px) {\n  .form-horizontal .form-group-sm .control-label {\n    padding-top: 6px;\n    font-size: 12px;\n  }\n}\n.btn {\n  display: inline-block;\n  padding: 6px 12px;\n  margin-bottom: 0;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  -ms-touch-action: manipulation;\n      touch-action: manipulation;\n  cursor: pointer;\n  -webkit-user-select: none;\n     -moz-user-select: none;\n      -ms-user-select: none;\n          user-select: none;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.btn:focus,\n.btn:active:focus,\n.btn.active:focus,\n.btn.focus,\n.btn:active.focus,\n.btn.active.focus {\n  outline: thin dotted;\n  outline: 5px auto -webkit-focus-ring-color;\n  outline-offset: -2px;\n}\n.btn:hover,\n.btn:focus,\n.btn.focus {\n  color: #333;\n  text-decoration: none;\n}\n.btn:active,\n.btn.active {\n  background-image: none;\n  outline: 0;\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn.disabled,\n.btn[disabled],\nfieldset[disabled] .btn {\n  cursor: not-allowed;\n  filter: alpha(opacity=65);\n  -webkit-box-shadow: none;\n          box-shadow: none;\n  opacity: .65;\n}\na.btn.disabled,\nfieldset[disabled] a.btn {\n  pointer-events: none;\n}\n.btn-default {\n  color: #333;\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default:focus,\n.btn-default.focus {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #8c8c8c;\n}\n.btn-default:hover {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  color: #333;\n  background-color: #e6e6e6;\n  border-color: #adadad;\n}\n.btn-default:active:hover,\n.btn-default.active:hover,\n.open > .dropdown-toggle.btn-default:hover,\n.btn-default:active:focus,\n.btn-default.active:focus,\n.open > .dropdown-toggle.btn-default:focus,\n.btn-default:active.focus,\n.btn-default.active.focus,\n.open > .dropdown-toggle.btn-default.focus {\n  color: #333;\n  background-color: #d4d4d4;\n  border-color: #8c8c8c;\n}\n.btn-default:active,\n.btn-default.active,\n.open > .dropdown-toggle.btn-default {\n  background-image: none;\n}\n.btn-default.disabled:hover,\n.btn-default[disabled]:hover,\nfieldset[disabled] .btn-default:hover,\n.btn-default.disabled:focus,\n.btn-default[disabled]:focus,\nfieldset[disabled] .btn-default:focus,\n.btn-default.disabled.focus,\n.btn-default[disabled].focus,\nfieldset[disabled] .btn-default.focus {\n  background-color: #fff;\n  border-color: #ccc;\n}\n.btn-default .badge {\n  color: #fff;\n  background-color: #333;\n}\n.btn-primary {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary:focus,\n.btn-primary.focus {\n  color: #fff;\n  background-color: #286090;\n  border-color: #122b40;\n}\n.btn-primary:hover {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  color: #fff;\n  background-color: #286090;\n  border-color: #204d74;\n}\n.btn-primary:active:hover,\n.btn-primary.active:hover,\n.open > .dropdown-toggle.btn-primary:hover,\n.btn-primary:active:focus,\n.btn-primary.active:focus,\n.open > .dropdown-toggle.btn-primary:focus,\n.btn-primary:active.focus,\n.btn-primary.active.focus,\n.open > .dropdown-toggle.btn-primary.focus {\n  color: #fff;\n  background-color: #204d74;\n  border-color: #122b40;\n}\n.btn-primary:active,\n.btn-primary.active,\n.open > .dropdown-toggle.btn-primary {\n  background-image: none;\n}\n.btn-primary.disabled:hover,\n.btn-primary[disabled]:hover,\nfieldset[disabled] .btn-primary:hover,\n.btn-primary.disabled:focus,\n.btn-primary[disabled]:focus,\nfieldset[disabled] .btn-primary:focus,\n.btn-primary.disabled.focus,\n.btn-primary[disabled].focus,\nfieldset[disabled] .btn-primary.focus {\n  background-color: #337ab7;\n  border-color: #2e6da4;\n}\n.btn-primary .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.btn-success {\n  color: #fff;\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success:focus,\n.btn-success.focus {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #255625;\n}\n.btn-success:hover {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  color: #fff;\n  background-color: #449d44;\n  border-color: #398439;\n}\n.btn-success:active:hover,\n.btn-success.active:hover,\n.open > .dropdown-toggle.btn-success:hover,\n.btn-success:active:focus,\n.btn-success.active:focus,\n.open > .dropdown-toggle.btn-success:focus,\n.btn-success:active.focus,\n.btn-success.active.focus,\n.open > .dropdown-toggle.btn-success.focus {\n  color: #fff;\n  background-color: #398439;\n  border-color: #255625;\n}\n.btn-success:active,\n.btn-success.active,\n.open > .dropdown-toggle.btn-success {\n  background-image: none;\n}\n.btn-success.disabled:hover,\n.btn-success[disabled]:hover,\nfieldset[disabled] .btn-success:hover,\n.btn-success.disabled:focus,\n.btn-success[disabled]:focus,\nfieldset[disabled] .btn-success:focus,\n.btn-success.disabled.focus,\n.btn-success[disabled].focus,\nfieldset[disabled] .btn-success.focus {\n  background-color: #5cb85c;\n  border-color: #4cae4c;\n}\n.btn-success .badge {\n  color: #5cb85c;\n  background-color: #fff;\n}\n.btn-info {\n  color: #fff;\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info:focus,\n.btn-info.focus {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #1b6d85;\n}\n.btn-info:hover {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  color: #fff;\n  background-color: #31b0d5;\n  border-color: #269abc;\n}\n.btn-info:active:hover,\n.btn-info.active:hover,\n.open > .dropdown-toggle.btn-info:hover,\n.btn-info:active:focus,\n.btn-info.active:focus,\n.open > .dropdown-toggle.btn-info:focus,\n.btn-info:active.focus,\n.btn-info.active.focus,\n.open > .dropdown-toggle.btn-info.focus {\n  color: #fff;\n  background-color: #269abc;\n  border-color: #1b6d85;\n}\n.btn-info:active,\n.btn-info.active,\n.open > .dropdown-toggle.btn-info {\n  background-image: none;\n}\n.btn-info.disabled:hover,\n.btn-info[disabled]:hover,\nfieldset[disabled] .btn-info:hover,\n.btn-info.disabled:focus,\n.btn-info[disabled]:focus,\nfieldset[disabled] .btn-info:focus,\n.btn-info.disabled.focus,\n.btn-info[disabled].focus,\nfieldset[disabled] .btn-info.focus {\n  background-color: #5bc0de;\n  border-color: #46b8da;\n}\n.btn-info .badge {\n  color: #5bc0de;\n  background-color: #fff;\n}\n.btn-warning {\n  color: #fff;\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning:focus,\n.btn-warning.focus {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #985f0d;\n}\n.btn-warning:hover {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  color: #fff;\n  background-color: #ec971f;\n  border-color: #d58512;\n}\n.btn-warning:active:hover,\n.btn-warning.active:hover,\n.open > .dropdown-toggle.btn-warning:hover,\n.btn-warning:active:focus,\n.btn-warning.active:focus,\n.open > .dropdown-toggle.btn-warning:focus,\n.btn-warning:active.focus,\n.btn-warning.active.focus,\n.open > .dropdown-toggle.btn-warning.focus {\n  color: #fff;\n  background-color: #d58512;\n  border-color: #985f0d;\n}\n.btn-warning:active,\n.btn-warning.active,\n.open > .dropdown-toggle.btn-warning {\n  background-image: none;\n}\n.btn-warning.disabled:hover,\n.btn-warning[disabled]:hover,\nfieldset[disabled] .btn-warning:hover,\n.btn-warning.disabled:focus,\n.btn-warning[disabled]:focus,\nfieldset[disabled] .btn-warning:focus,\n.btn-warning.disabled.focus,\n.btn-warning[disabled].focus,\nfieldset[disabled] .btn-warning.focus {\n  background-color: #f0ad4e;\n  border-color: #eea236;\n}\n.btn-warning .badge {\n  color: #f0ad4e;\n  background-color: #fff;\n}\n.btn-danger {\n  color: #fff;\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger:focus,\n.btn-danger.focus {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #761c19;\n}\n.btn-danger:hover {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  color: #fff;\n  background-color: #c9302c;\n  border-color: #ac2925;\n}\n.btn-danger:active:hover,\n.btn-danger.active:hover,\n.open > .dropdown-toggle.btn-danger:hover,\n.btn-danger:active:focus,\n.btn-danger.active:focus,\n.open > .dropdown-toggle.btn-danger:focus,\n.btn-danger:active.focus,\n.btn-danger.active.focus,\n.open > .dropdown-toggle.btn-danger.focus {\n  color: #fff;\n  background-color: #ac2925;\n  border-color: #761c19;\n}\n.btn-danger:active,\n.btn-danger.active,\n.open > .dropdown-toggle.btn-danger {\n  background-image: none;\n}\n.btn-danger.disabled:hover,\n.btn-danger[disabled]:hover,\nfieldset[disabled] .btn-danger:hover,\n.btn-danger.disabled:focus,\n.btn-danger[disabled]:focus,\nfieldset[disabled] .btn-danger:focus,\n.btn-danger.disabled.focus,\n.btn-danger[disabled].focus,\nfieldset[disabled] .btn-danger.focus {\n  background-color: #d9534f;\n  border-color: #d43f3a;\n}\n.btn-danger .badge {\n  color: #d9534f;\n  background-color: #fff;\n}\n.btn-link {\n  font-weight: normal;\n  color: #337ab7;\n  border-radius: 0;\n}\n.btn-link,\n.btn-link:active,\n.btn-link.active,\n.btn-link[disabled],\nfieldset[disabled] .btn-link {\n  background-color: transparent;\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn-link,\n.btn-link:hover,\n.btn-link:focus,\n.btn-link:active {\n  border-color: transparent;\n}\n.btn-link:hover,\n.btn-link:focus {\n  color: #23527c;\n  text-decoration: underline;\n  background-color: transparent;\n}\n.btn-link[disabled]:hover,\nfieldset[disabled] .btn-link:hover,\n.btn-link[disabled]:focus,\nfieldset[disabled] .btn-link:focus {\n  color: #777;\n  text-decoration: none;\n}\n.btn-lg,\n.btn-group-lg > .btn {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\n.btn-sm,\n.btn-group-sm > .btn {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-xs,\n.btn-group-xs > .btn {\n  padding: 1px 5px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\n.btn-block {\n  display: block;\n  width: 100%;\n}\n.btn-block + .btn-block {\n  margin-top: 5px;\n}\ninput[type=\"submit\"].btn-block,\ninput[type=\"reset\"].btn-block,\ninput[type=\"button\"].btn-block {\n  width: 100%;\n}\n.fade {\n  opacity: 0;\n  -webkit-transition: opacity .15s linear;\n       -o-transition: opacity .15s linear;\n          transition: opacity .15s linear;\n}\n.fade.in {\n  opacity: 1;\n}\n.collapse {\n  display: none;\n}\n.collapse.in {\n  display: block;\n}\ntr.collapse.in {\n  display: table-row;\n}\ntbody.collapse.in {\n  display: table-row-group;\n}\n.collapsing {\n  position: relative;\n  height: 0;\n  overflow: hidden;\n  -webkit-transition-timing-function: ease;\n       -o-transition-timing-function: ease;\n          transition-timing-function: ease;\n  -webkit-transition-duration: .35s;\n       -o-transition-duration: .35s;\n          transition-duration: .35s;\n  -webkit-transition-property: height, visibility;\n       -o-transition-property: height, visibility;\n          transition-property: height, visibility;\n}\n.caret {\n  display: inline-block;\n  width: 0;\n  height: 0;\n  margin-left: 2px;\n  vertical-align: middle;\n  border-top: 4px dashed;\n  border-top: 4px solid \\9;\n  border-right: 4px solid transparent;\n  border-left: 4px solid transparent;\n}\n.dropup,\n.dropdown {\n  position: relative;\n}\n.dropdown-toggle:focus {\n  outline: 0;\n}\n.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  display: none;\n  float: left;\n  min-width: 160px;\n  padding: 5px 0;\n  margin: 2px 0 0;\n  font-size: 14px;\n  text-align: left;\n  list-style: none;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .15);\n  border-radius: 4px;\n  -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n          box-shadow: 0 6px 12px rgba(0, 0, 0, .175);\n}\n.dropdown-menu.pull-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu .divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.dropdown-menu > li > a {\n  display: block;\n  padding: 3px 20px;\n  clear: both;\n  font-weight: normal;\n  line-height: 1.42857143;\n  color: #333;\n  white-space: nowrap;\n}\n.dropdown-menu > li > a:hover,\n.dropdown-menu > li > a:focus {\n  color: #262626;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\n.dropdown-menu > .active > a,\n.dropdown-menu > .active > a:hover,\n.dropdown-menu > .active > a:focus {\n  color: #fff;\n  text-decoration: none;\n  background-color: #337ab7;\n  outline: 0;\n}\n.dropdown-menu > .disabled > a,\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  color: #777;\n}\n.dropdown-menu > .disabled > a:hover,\n.dropdown-menu > .disabled > a:focus {\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n  background-image: none;\n  filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);\n}\n.open > .dropdown-menu {\n  display: block;\n}\n.open > a {\n  outline: 0;\n}\n.dropdown-menu-right {\n  right: 0;\n  left: auto;\n}\n.dropdown-menu-left {\n  right: auto;\n  left: 0;\n}\n.dropdown-header {\n  display: block;\n  padding: 3px 20px;\n  font-size: 12px;\n  line-height: 1.42857143;\n  color: #777;\n  white-space: nowrap;\n}\n.dropdown-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 990;\n}\n.pull-right > .dropdown-menu {\n  right: 0;\n  left: auto;\n}\n.dropup .caret,\n.navbar-fixed-bottom .dropdown .caret {\n  content: \"\";\n  border-top: 0;\n  border-bottom: 4px dashed;\n  border-bottom: 4px solid \\9;\n}\n.dropup .dropdown-menu,\n.navbar-fixed-bottom .dropdown .dropdown-menu {\n  top: auto;\n  bottom: 100%;\n  margin-bottom: 2px;\n}\n@media (min-width: 768px) {\n  .navbar-right .dropdown-menu {\n    right: 0;\n    left: auto;\n  }\n  .navbar-right .dropdown-menu-left {\n    right: auto;\n    left: 0;\n  }\n}\n.btn-group,\n.btn-group-vertical {\n  position: relative;\n  display: inline-block;\n  vertical-align: middle;\n}\n.btn-group > .btn,\n.btn-group-vertical > .btn {\n  position: relative;\n  float: left;\n}\n.btn-group > .btn:hover,\n.btn-group-vertical > .btn:hover,\n.btn-group > .btn:focus,\n.btn-group-vertical > .btn:focus,\n.btn-group > .btn:active,\n.btn-group-vertical > .btn:active,\n.btn-group > .btn.active,\n.btn-group-vertical > .btn.active {\n  z-index: 2;\n}\n.btn-group .btn + .btn,\n.btn-group .btn + .btn-group,\n.btn-group .btn-group + .btn,\n.btn-group .btn-group + .btn-group {\n  margin-left: -1px;\n}\n.btn-toolbar {\n  margin-left: -5px;\n}\n.btn-toolbar .btn,\n.btn-toolbar .btn-group,\n.btn-toolbar .input-group {\n  float: left;\n}\n.btn-toolbar > .btn,\n.btn-toolbar > .btn-group,\n.btn-toolbar > .input-group {\n  margin-left: 5px;\n}\n.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {\n  border-radius: 0;\n}\n.btn-group > .btn:first-child {\n  margin-left: 0;\n}\n.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn:last-child:not(:first-child),\n.btn-group > .dropdown-toggle:not(:first-child) {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group > .btn-group {\n  float: left;\n}\n.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group .dropdown-toggle:active,\n.btn-group.open .dropdown-toggle {\n  outline: 0;\n}\n.btn-group > .btn + .dropdown-toggle {\n  padding-right: 8px;\n  padding-left: 8px;\n}\n.btn-group > .btn-lg + .dropdown-toggle {\n  padding-right: 12px;\n  padding-left: 12px;\n}\n.btn-group.open .dropdown-toggle {\n  -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n          box-shadow: inset 0 3px 5px rgba(0, 0, 0, .125);\n}\n.btn-group.open .dropdown-toggle.btn-link {\n  -webkit-box-shadow: none;\n          box-shadow: none;\n}\n.btn .caret {\n  margin-left: 0;\n}\n.btn-lg .caret {\n  border-width: 5px 5px 0;\n  border-bottom-width: 0;\n}\n.dropup .btn-lg .caret {\n  border-width: 0 5px 5px;\n}\n.btn-group-vertical > .btn,\n.btn-group-vertical > .btn-group,\n.btn-group-vertical > .btn-group > .btn {\n  display: block;\n  float: none;\n  width: 100%;\n  max-width: 100%;\n}\n.btn-group-vertical > .btn-group > .btn {\n  float: none;\n}\n.btn-group-vertical > .btn + .btn,\n.btn-group-vertical > .btn + .btn-group,\n.btn-group-vertical > .btn-group + .btn,\n.btn-group-vertical > .btn-group + .btn-group {\n  margin-top: -1px;\n  margin-left: 0;\n}\n.btn-group-vertical > .btn:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn:first-child:not(:last-child) {\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn:last-child:not(:first-child) {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {\n  border-radius: 0;\n}\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,\n.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.btn-group-justified {\n  display: table;\n  width: 100%;\n  table-layout: fixed;\n  border-collapse: separate;\n}\n.btn-group-justified > .btn,\n.btn-group-justified > .btn-group {\n  display: table-cell;\n  float: none;\n  width: 1%;\n}\n.btn-group-justified > .btn-group .btn {\n  width: 100%;\n}\n.btn-group-justified > .btn-group .dropdown-menu {\n  left: auto;\n}\n[data-toggle=\"buttons\"] > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"radio\"],\n[data-toggle=\"buttons\"] > .btn input[type=\"checkbox\"],\n[data-toggle=\"buttons\"] > .btn-group > .btn input[type=\"checkbox\"] {\n  position: absolute;\n  clip: rect(0, 0, 0, 0);\n  pointer-events: none;\n}\n.input-group {\n  position: relative;\n  display: table;\n  border-collapse: separate;\n}\n.input-group[class*=\"col-\"] {\n  float: none;\n  padding-right: 0;\n  padding-left: 0;\n}\n.input-group .form-control {\n  position: relative;\n  z-index: 2;\n  float: left;\n  width: 100%;\n  margin-bottom: 0;\n}\n.input-group .form-control:focus {\n  z-index: 3;\n}\n.input-group-lg > .form-control,\n.input-group-lg > .input-group-addon,\n.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n  border-radius: 6px;\n}\nselect.input-group-lg > .form-control,\nselect.input-group-lg > .input-group-addon,\nselect.input-group-lg > .input-group-btn > .btn {\n  height: 46px;\n  line-height: 46px;\n}\ntextarea.input-group-lg > .form-control,\ntextarea.input-group-lg > .input-group-addon,\ntextarea.input-group-lg > .input-group-btn > .btn,\nselect[multiple].input-group-lg > .form-control,\nselect[multiple].input-group-lg > .input-group-addon,\nselect[multiple].input-group-lg > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-sm > .form-control,\n.input-group-sm > .input-group-addon,\n.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n  border-radius: 3px;\n}\nselect.input-group-sm > .form-control,\nselect.input-group-sm > .input-group-addon,\nselect.input-group-sm > .input-group-btn > .btn {\n  height: 30px;\n  line-height: 30px;\n}\ntextarea.input-group-sm > .form-control,\ntextarea.input-group-sm > .input-group-addon,\ntextarea.input-group-sm > .input-group-btn > .btn,\nselect[multiple].input-group-sm > .form-control,\nselect[multiple].input-group-sm > .input-group-addon,\nselect[multiple].input-group-sm > .input-group-btn > .btn {\n  height: auto;\n}\n.input-group-addon,\n.input-group-btn,\n.input-group .form-control {\n  display: table-cell;\n}\n.input-group-addon:not(:first-child):not(:last-child),\n.input-group-btn:not(:first-child):not(:last-child),\n.input-group .form-control:not(:first-child):not(:last-child) {\n  border-radius: 0;\n}\n.input-group-addon,\n.input-group-btn {\n  width: 1%;\n  white-space: nowrap;\n  vertical-align: middle;\n}\n.input-group-addon {\n  padding: 6px 12px;\n  font-size: 14px;\n  font-weight: normal;\n  line-height: 1;\n  color: #555;\n  text-align: center;\n  background-color: #eee;\n  border: 1px solid #ccc;\n  border-radius: 4px;\n}\n.input-group-addon.input-sm {\n  padding: 5px 10px;\n  font-size: 12px;\n  border-radius: 3px;\n}\n.input-group-addon.input-lg {\n  padding: 10px 16px;\n  font-size: 18px;\n  border-radius: 6px;\n}\n.input-group-addon input[type=\"radio\"],\n.input-group-addon input[type=\"checkbox\"] {\n  margin-top: 0;\n}\n.input-group .form-control:first-child,\n.input-group-addon:first-child,\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group > .btn,\n.input-group-btn:first-child > .dropdown-toggle,\n.input-group-btn:last-child > .btn:not(:last-child):not(.dropdown-toggle),\n.input-group-btn:last-child > .btn-group:not(:last-child) > .btn {\n  border-top-right-radius: 0;\n  border-bottom-right-radius: 0;\n}\n.input-group-addon:first-child {\n  border-right: 0;\n}\n.input-group .form-control:last-child,\n.input-group-addon:last-child,\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group > .btn,\n.input-group-btn:last-child > .dropdown-toggle,\n.input-group-btn:first-child > .btn:not(:first-child),\n.input-group-btn:first-child > .btn-group:not(:first-child) > .btn {\n  border-top-left-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.input-group-addon:last-child {\n  border-left: 0;\n}\n.input-group-btn {\n  position: relative;\n  font-size: 0;\n  white-space: nowrap;\n}\n.input-group-btn > .btn {\n  position: relative;\n}\n.input-group-btn > .btn + .btn {\n  margin-left: -1px;\n}\n.input-group-btn > .btn:hover,\n.input-group-btn > .btn:focus,\n.input-group-btn > .btn:active {\n  z-index: 2;\n}\n.input-group-btn:first-child > .btn,\n.input-group-btn:first-child > .btn-group {\n  margin-right: -1px;\n}\n.input-group-btn:last-child > .btn,\n.input-group-btn:last-child > .btn-group {\n  z-index: 2;\n  margin-left: -1px;\n}\n.nav {\n  padding-left: 0;\n  margin-bottom: 0;\n  list-style: none;\n}\n.nav > li {\n  position: relative;\n  display: block;\n}\n.nav > li > a {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n}\n.nav > li > a:hover,\n.nav > li > a:focus {\n  text-decoration: none;\n  background-color: #eee;\n}\n.nav > li.disabled > a {\n  color: #777;\n}\n.nav > li.disabled > a:hover,\n.nav > li.disabled > a:focus {\n  color: #777;\n  text-decoration: none;\n  cursor: not-allowed;\n  background-color: transparent;\n}\n.nav .open > a,\n.nav .open > a:hover,\n.nav .open > a:focus {\n  background-color: #eee;\n  border-color: #337ab7;\n}\n.nav .nav-divider {\n  height: 1px;\n  margin: 9px 0;\n  overflow: hidden;\n  background-color: #e5e5e5;\n}\n.nav > li > a > img {\n  max-width: none;\n}\n.nav-tabs {\n  border-bottom: 1px solid #ddd;\n}\n.nav-tabs > li {\n  float: left;\n  margin-bottom: -1px;\n}\n.nav-tabs > li > a {\n  margin-right: 2px;\n  line-height: 1.42857143;\n  border: 1px solid transparent;\n  border-radius: 4px 4px 0 0;\n}\n.nav-tabs > li > a:hover {\n  border-color: #eee #eee #ddd;\n}\n.nav-tabs > li.active > a,\n.nav-tabs > li.active > a:hover,\n.nav-tabs > li.active > a:focus {\n  color: #555;\n  cursor: default;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-bottom-color: transparent;\n}\n.nav-tabs.nav-justified {\n  width: 100%;\n  border-bottom: 0;\n}\n.nav-tabs.nav-justified > li {\n  float: none;\n}\n.nav-tabs.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n.nav-tabs.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-tabs.nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs.nav-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs.nav-justified > .active > a,\n.nav-tabs.nav-justified > .active > a:hover,\n.nav-tabs.nav-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs.nav-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs.nav-justified > .active > a,\n  .nav-tabs.nav-justified > .active > a:hover,\n  .nav-tabs.nav-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.nav-pills > li {\n  float: left;\n}\n.nav-pills > li > a {\n  border-radius: 4px;\n}\n.nav-pills > li + li {\n  margin-left: 2px;\n}\n.nav-pills > li.active > a,\n.nav-pills > li.active > a:hover,\n.nav-pills > li.active > a:focus {\n  color: #fff;\n  background-color: #337ab7;\n}\n.nav-stacked > li {\n  float: none;\n}\n.nav-stacked > li + li {\n  margin-top: 2px;\n  margin-left: 0;\n}\n.nav-justified {\n  width: 100%;\n}\n.nav-justified > li {\n  float: none;\n}\n.nav-justified > li > a {\n  margin-bottom: 5px;\n  text-align: center;\n}\n.nav-justified > .dropdown .dropdown-menu {\n  top: auto;\n  left: auto;\n}\n@media (min-width: 768px) {\n  .nav-justified > li {\n    display: table-cell;\n    width: 1%;\n  }\n  .nav-justified > li > a {\n    margin-bottom: 0;\n  }\n}\n.nav-tabs-justified {\n  border-bottom: 0;\n}\n.nav-tabs-justified > li > a {\n  margin-right: 0;\n  border-radius: 4px;\n}\n.nav-tabs-justified > .active > a,\n.nav-tabs-justified > .active > a:hover,\n.nav-tabs-justified > .active > a:focus {\n  border: 1px solid #ddd;\n}\n@media (min-width: 768px) {\n  .nav-tabs-justified > li > a {\n    border-bottom: 1px solid #ddd;\n    border-radius: 4px 4px 0 0;\n  }\n  .nav-tabs-justified > .active > a,\n  .nav-tabs-justified > .active > a:hover,\n  .nav-tabs-justified > .active > a:focus {\n    border-bottom-color: #fff;\n  }\n}\n.tab-content > .tab-pane {\n  display: none;\n}\n.tab-content > .active {\n  display: block;\n}\n.nav-tabs .dropdown-menu {\n  margin-top: -1px;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.navbar {\n  position: relative;\n  min-height: 50px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n}\n@media (min-width: 768px) {\n  .navbar {\n    border-radius: 4px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-header {\n    float: left;\n  }\n}\n.navbar-collapse {\n  padding-right: 15px;\n  padding-left: 15px;\n  overflow-x: visible;\n  -webkit-overflow-scrolling: touch;\n  border-top: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1);\n}\n.navbar-collapse.in {\n  overflow-y: auto;\n}\n@media (min-width: 768px) {\n  .navbar-collapse {\n    width: auto;\n    border-top: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-collapse.collapse {\n    display: block !important;\n    height: auto !important;\n    padding-bottom: 0;\n    overflow: visible !important;\n  }\n  .navbar-collapse.in {\n    overflow-y: visible;\n  }\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-static-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    padding-right: 0;\n    padding-left: 0;\n  }\n}\n.navbar-fixed-top .navbar-collapse,\n.navbar-fixed-bottom .navbar-collapse {\n  max-height: 340px;\n}\n@media (max-device-width: 480px) and (orientation: landscape) {\n  .navbar-fixed-top .navbar-collapse,\n  .navbar-fixed-bottom .navbar-collapse {\n    max-height: 200px;\n  }\n}\n.container > .navbar-header,\n.container-fluid > .navbar-header,\n.container > .navbar-collapse,\n.container-fluid > .navbar-collapse {\n  margin-right: -15px;\n  margin-left: -15px;\n}\n@media (min-width: 768px) {\n  .container > .navbar-header,\n  .container-fluid > .navbar-header,\n  .container > .navbar-collapse,\n  .container-fluid > .navbar-collapse {\n    margin-right: 0;\n    margin-left: 0;\n  }\n}\n.navbar-static-top {\n  z-index: 1000;\n  border-width: 0 0 1px;\n}\n@media (min-width: 768px) {\n  .navbar-static-top {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top,\n.navbar-fixed-bottom {\n  position: fixed;\n  right: 0;\n  left: 0;\n  z-index: 1030;\n}\n@media (min-width: 768px) {\n  .navbar-fixed-top,\n  .navbar-fixed-bottom {\n    border-radius: 0;\n  }\n}\n.navbar-fixed-top {\n  top: 0;\n  border-width: 0 0 1px;\n}\n.navbar-fixed-bottom {\n  bottom: 0;\n  margin-bottom: 0;\n  border-width: 1px 0 0;\n}\n.navbar-brand {\n  float: left;\n  height: 50px;\n  padding: 15px 15px;\n  font-size: 18px;\n  line-height: 20px;\n}\n.navbar-brand:hover,\n.navbar-brand:focus {\n  text-decoration: none;\n}\n.navbar-brand > img {\n  display: block;\n}\n@media (min-width: 768px) {\n  .navbar > .container .navbar-brand,\n  .navbar > .container-fluid .navbar-brand {\n    margin-left: -15px;\n  }\n}\n.navbar-toggle {\n  position: relative;\n  float: right;\n  padding: 9px 10px;\n  margin-top: 8px;\n  margin-right: 15px;\n  margin-bottom: 8px;\n  background-color: transparent;\n  background-image: none;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.navbar-toggle:focus {\n  outline: 0;\n}\n.navbar-toggle .icon-bar {\n  display: block;\n  width: 22px;\n  height: 2px;\n  border-radius: 1px;\n}\n.navbar-toggle .icon-bar + .icon-bar {\n  margin-top: 4px;\n}\n@media (min-width: 768px) {\n  .navbar-toggle {\n    display: none;\n  }\n}\n.navbar-nav {\n  margin: 7.5px -15px;\n}\n.navbar-nav > li > a {\n  padding-top: 10px;\n  padding-bottom: 10px;\n  line-height: 20px;\n}\n@media (max-width: 767px) {\n  .navbar-nav .open .dropdown-menu {\n    position: static;\n    float: none;\n    width: auto;\n    margin-top: 0;\n    background-color: transparent;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n  .navbar-nav .open .dropdown-menu > li > a,\n  .navbar-nav .open .dropdown-menu .dropdown-header {\n    padding: 5px 15px 5px 25px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a {\n    line-height: 20px;\n  }\n  .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-nav .open .dropdown-menu > li > a:focus {\n    background-image: none;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-nav {\n    float: left;\n    margin: 0;\n  }\n  .navbar-nav > li {\n    float: left;\n  }\n  .navbar-nav > li > a {\n    padding-top: 15px;\n    padding-bottom: 15px;\n  }\n}\n.navbar-form {\n  padding: 10px 15px;\n  margin-top: 8px;\n  margin-right: -15px;\n  margin-bottom: 8px;\n  margin-left: -15px;\n  border-top: 1px solid transparent;\n  border-bottom: 1px solid transparent;\n  -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n          box-shadow: inset 0 1px 0 rgba(255, 255, 255, .1), 0 1px 0 rgba(255, 255, 255, .1);\n}\n@media (min-width: 768px) {\n  .navbar-form .form-group {\n    display: inline-block;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control {\n    display: inline-block;\n    width: auto;\n    vertical-align: middle;\n  }\n  .navbar-form .form-control-static {\n    display: inline-block;\n  }\n  .navbar-form .input-group {\n    display: inline-table;\n    vertical-align: middle;\n  }\n  .navbar-form .input-group .input-group-addon,\n  .navbar-form .input-group .input-group-btn,\n  .navbar-form .input-group .form-control {\n    width: auto;\n  }\n  .navbar-form .input-group > .form-control {\n    width: 100%;\n  }\n  .navbar-form .control-label {\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio,\n  .navbar-form .checkbox {\n    display: inline-block;\n    margin-top: 0;\n    margin-bottom: 0;\n    vertical-align: middle;\n  }\n  .navbar-form .radio label,\n  .navbar-form .checkbox label {\n    padding-left: 0;\n  }\n  .navbar-form .radio input[type=\"radio\"],\n  .navbar-form .checkbox input[type=\"checkbox\"] {\n    position: relative;\n    margin-left: 0;\n  }\n  .navbar-form .has-feedback .form-control-feedback {\n    top: 0;\n  }\n}\n@media (max-width: 767px) {\n  .navbar-form .form-group {\n    margin-bottom: 5px;\n  }\n  .navbar-form .form-group:last-child {\n    margin-bottom: 0;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-form {\n    width: auto;\n    padding-top: 0;\n    padding-bottom: 0;\n    margin-right: 0;\n    margin-left: 0;\n    border: 0;\n    -webkit-box-shadow: none;\n            box-shadow: none;\n  }\n}\n.navbar-nav > li > .dropdown-menu {\n  margin-top: 0;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.navbar-fixed-bottom .navbar-nav > li > .dropdown-menu {\n  margin-bottom: 0;\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 0;\n  border-bottom-left-radius: 0;\n}\n.navbar-btn {\n  margin-top: 8px;\n  margin-bottom: 8px;\n}\n.navbar-btn.btn-sm {\n  margin-top: 10px;\n  margin-bottom: 10px;\n}\n.navbar-btn.btn-xs {\n  margin-top: 14px;\n  margin-bottom: 14px;\n}\n.navbar-text {\n  margin-top: 15px;\n  margin-bottom: 15px;\n}\n@media (min-width: 768px) {\n  .navbar-text {\n    float: left;\n    margin-right: 15px;\n    margin-left: 15px;\n  }\n}\n@media (min-width: 768px) {\n  .navbar-left {\n    float: left !important;\n  }\n  .navbar-right {\n    float: right !important;\n    margin-right: -15px;\n  }\n  .navbar-right ~ .navbar-right {\n    margin-right: 0;\n  }\n}\n.navbar-default {\n  background-color: #f8f8f8;\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-brand {\n  color: #777;\n}\n.navbar-default .navbar-brand:hover,\n.navbar-default .navbar-brand:focus {\n  color: #5e5e5e;\n  background-color: transparent;\n}\n.navbar-default .navbar-text {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a {\n  color: #777;\n}\n.navbar-default .navbar-nav > li > a:hover,\n.navbar-default .navbar-nav > li > a:focus {\n  color: #333;\n  background-color: transparent;\n}\n.navbar-default .navbar-nav > .active > a,\n.navbar-default .navbar-nav > .active > a:hover,\n.navbar-default .navbar-nav > .active > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .disabled > a,\n.navbar-default .navbar-nav > .disabled > a:hover,\n.navbar-default .navbar-nav > .disabled > a:focus {\n  color: #ccc;\n  background-color: transparent;\n}\n.navbar-default .navbar-toggle {\n  border-color: #ddd;\n}\n.navbar-default .navbar-toggle:hover,\n.navbar-default .navbar-toggle:focus {\n  background-color: #ddd;\n}\n.navbar-default .navbar-toggle .icon-bar {\n  background-color: #888;\n}\n.navbar-default .navbar-collapse,\n.navbar-default .navbar-form {\n  border-color: #e7e7e7;\n}\n.navbar-default .navbar-nav > .open > a,\n.navbar-default .navbar-nav > .open > a:hover,\n.navbar-default .navbar-nav > .open > a:focus {\n  color: #555;\n  background-color: #e7e7e7;\n}\n@media (max-width: 767px) {\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a {\n    color: #777;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #333;\n    background-color: transparent;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #555;\n    background-color: #e7e7e7;\n  }\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-default .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #ccc;\n    background-color: transparent;\n  }\n}\n.navbar-default .navbar-link {\n  color: #777;\n}\n.navbar-default .navbar-link:hover {\n  color: #333;\n}\n.navbar-default .btn-link {\n  color: #777;\n}\n.navbar-default .btn-link:hover,\n.navbar-default .btn-link:focus {\n  color: #333;\n}\n.navbar-default .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-default .btn-link:hover,\n.navbar-default .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-default .btn-link:focus {\n  color: #ccc;\n}\n.navbar-inverse {\n  background-color: #222;\n  border-color: #080808;\n}\n.navbar-inverse .navbar-brand {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-brand:hover,\n.navbar-inverse .navbar-brand:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-text {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-nav > li > a:hover,\n.navbar-inverse .navbar-nav > li > a:focus {\n  color: #fff;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-nav > .active > a,\n.navbar-inverse .navbar-nav > .active > a:hover,\n.navbar-inverse .navbar-nav > .active > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n.navbar-inverse .navbar-nav > .disabled > a,\n.navbar-inverse .navbar-nav > .disabled > a:hover,\n.navbar-inverse .navbar-nav > .disabled > a:focus {\n  color: #444;\n  background-color: transparent;\n}\n.navbar-inverse .navbar-toggle {\n  border-color: #333;\n}\n.navbar-inverse .navbar-toggle:hover,\n.navbar-inverse .navbar-toggle:focus {\n  background-color: #333;\n}\n.navbar-inverse .navbar-toggle .icon-bar {\n  background-color: #fff;\n}\n.navbar-inverse .navbar-collapse,\n.navbar-inverse .navbar-form {\n  border-color: #101010;\n}\n.navbar-inverse .navbar-nav > .open > a,\n.navbar-inverse .navbar-nav > .open > a:hover,\n.navbar-inverse .navbar-nav > .open > a:focus {\n  color: #fff;\n  background-color: #080808;\n}\n@media (max-width: 767px) {\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .dropdown-header {\n    border-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu .divider {\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a {\n    color: #9d9d9d;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > li > a:focus {\n    color: #fff;\n    background-color: transparent;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .active > a:focus {\n    color: #fff;\n    background-color: #080808;\n  }\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:hover,\n  .navbar-inverse .navbar-nav .open .dropdown-menu > .disabled > a:focus {\n    color: #444;\n    background-color: transparent;\n  }\n}\n.navbar-inverse .navbar-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .navbar-link:hover {\n  color: #fff;\n}\n.navbar-inverse .btn-link {\n  color: #9d9d9d;\n}\n.navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link:focus {\n  color: #fff;\n}\n.navbar-inverse .btn-link[disabled]:hover,\nfieldset[disabled] .navbar-inverse .btn-link:hover,\n.navbar-inverse .btn-link[disabled]:focus,\nfieldset[disabled] .navbar-inverse .btn-link:focus {\n  color: #444;\n}\n.breadcrumb {\n  padding: 8px 15px;\n  margin-bottom: 20px;\n  list-style: none;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n}\n.breadcrumb > li {\n  display: inline-block;\n}\n.breadcrumb > li + li:before {\n  padding: 0 5px;\n  color: #ccc;\n  content: \"/\\00a0\";\n}\n.breadcrumb > .active {\n  color: #777;\n}\n.pagination {\n  display: inline-block;\n  padding-left: 0;\n  margin: 20px 0;\n  border-radius: 4px;\n}\n.pagination > li {\n  display: inline;\n}\n.pagination > li > a,\n.pagination > li > span {\n  position: relative;\n  float: left;\n  padding: 6px 12px;\n  margin-left: -1px;\n  line-height: 1.42857143;\n  color: #337ab7;\n  text-decoration: none;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.pagination > li:first-child > a,\n.pagination > li:first-child > span {\n  margin-left: 0;\n  border-top-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\n.pagination > li:last-child > a,\n.pagination > li:last-child > span {\n  border-top-right-radius: 4px;\n  border-bottom-right-radius: 4px;\n}\n.pagination > li > a:hover,\n.pagination > li > span:hover,\n.pagination > li > a:focus,\n.pagination > li > span:focus {\n  z-index: 2;\n  color: #23527c;\n  background-color: #eee;\n  border-color: #ddd;\n}\n.pagination > .active > a,\n.pagination > .active > span,\n.pagination > .active > a:hover,\n.pagination > .active > span:hover,\n.pagination > .active > a:focus,\n.pagination > .active > span:focus {\n  z-index: 3;\n  color: #fff;\n  cursor: default;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.pagination > .disabled > span,\n.pagination > .disabled > span:hover,\n.pagination > .disabled > span:focus,\n.pagination > .disabled > a,\n.pagination > .disabled > a:hover,\n.pagination > .disabled > a:focus {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #fff;\n  border-color: #ddd;\n}\n.pagination-lg > li > a,\n.pagination-lg > li > span {\n  padding: 10px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.pagination-lg > li:first-child > a,\n.pagination-lg > li:first-child > span {\n  border-top-left-radius: 6px;\n  border-bottom-left-radius: 6px;\n}\n.pagination-lg > li:last-child > a,\n.pagination-lg > li:last-child > span {\n  border-top-right-radius: 6px;\n  border-bottom-right-radius: 6px;\n}\n.pagination-sm > li > a,\n.pagination-sm > li > span {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.pagination-sm > li:first-child > a,\n.pagination-sm > li:first-child > span {\n  border-top-left-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.pagination-sm > li:last-child > a,\n.pagination-sm > li:last-child > span {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.pager {\n  padding-left: 0;\n  margin: 20px 0;\n  text-align: center;\n  list-style: none;\n}\n.pager li {\n  display: inline;\n}\n.pager li > a,\n.pager li > span {\n  display: inline-block;\n  padding: 5px 14px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 15px;\n}\n.pager li > a:hover,\n.pager li > a:focus {\n  text-decoration: none;\n  background-color: #eee;\n}\n.pager .next > a,\n.pager .next > span {\n  float: right;\n}\n.pager .previous > a,\n.pager .previous > span {\n  float: left;\n}\n.pager .disabled > a,\n.pager .disabled > a:hover,\n.pager .disabled > a:focus,\n.pager .disabled > span {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #fff;\n}\n.label {\n  display: inline;\n  padding: .2em .6em .3em;\n  font-size: 75%;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: baseline;\n  border-radius: .25em;\n}\na.label:hover,\na.label:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.label:empty {\n  display: none;\n}\n.btn .label {\n  position: relative;\n  top: -1px;\n}\n.label-default {\n  background-color: #777;\n}\n.label-default[href]:hover,\n.label-default[href]:focus {\n  background-color: #5e5e5e;\n}\n.label-primary {\n  background-color: #337ab7;\n}\n.label-primary[href]:hover,\n.label-primary[href]:focus {\n  background-color: #286090;\n}\n.label-success {\n  background-color: #5cb85c;\n}\n.label-success[href]:hover,\n.label-success[href]:focus {\n  background-color: #449d44;\n}\n.label-info {\n  background-color: #5bc0de;\n}\n.label-info[href]:hover,\n.label-info[href]:focus {\n  background-color: #31b0d5;\n}\n.label-warning {\n  background-color: #f0ad4e;\n}\n.label-warning[href]:hover,\n.label-warning[href]:focus {\n  background-color: #ec971f;\n}\n.label-danger {\n  background-color: #d9534f;\n}\n.label-danger[href]:hover,\n.label-danger[href]:focus {\n  background-color: #c9302c;\n}\n.badge {\n  display: inline-block;\n  min-width: 10px;\n  padding: 3px 7px;\n  font-size: 12px;\n  font-weight: bold;\n  line-height: 1;\n  color: #fff;\n  text-align: center;\n  white-space: nowrap;\n  vertical-align: middle;\n  background-color: #777;\n  border-radius: 10px;\n}\n.badge:empty {\n  display: none;\n}\n.btn .badge {\n  position: relative;\n  top: -1px;\n}\n.btn-xs .badge,\n.btn-group-xs > .btn .badge {\n  top: 0;\n  padding: 1px 5px;\n}\na.badge:hover,\na.badge:focus {\n  color: #fff;\n  text-decoration: none;\n  cursor: pointer;\n}\n.list-group-item.active > .badge,\n.nav-pills > .active > a > .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.list-group-item > .badge {\n  float: right;\n}\n.list-group-item > .badge + .badge {\n  margin-right: 5px;\n}\n.nav-pills > li > a > .badge {\n  margin-left: 3px;\n}\n.jumbotron {\n  padding-top: 30px;\n  padding-bottom: 30px;\n  margin-bottom: 30px;\n  color: inherit;\n  background-color: #eee;\n}\n.jumbotron h1,\n.jumbotron .h1 {\n  color: inherit;\n}\n.jumbotron p {\n  margin-bottom: 15px;\n  font-size: 21px;\n  font-weight: 200;\n}\n.jumbotron > hr {\n  border-top-color: #d5d5d5;\n}\n.container .jumbotron,\n.container-fluid .jumbotron {\n  padding-right: 15px;\n  padding-left: 15px;\n  border-radius: 6px;\n}\n.jumbotron .container {\n  max-width: 100%;\n}\n@media screen and (min-width: 768px) {\n  .jumbotron {\n    padding-top: 48px;\n    padding-bottom: 48px;\n  }\n  .container .jumbotron,\n  .container-fluid .jumbotron {\n    padding-right: 60px;\n    padding-left: 60px;\n  }\n  .jumbotron h1,\n  .jumbotron .h1 {\n    font-size: 63px;\n  }\n}\n.thumbnail {\n  display: block;\n  padding: 4px;\n  margin-bottom: 20px;\n  line-height: 1.42857143;\n  background-color: #fff;\n  border: 1px solid #ddd;\n  border-radius: 4px;\n  -webkit-transition: border .2s ease-in-out;\n       -o-transition: border .2s ease-in-out;\n          transition: border .2s ease-in-out;\n}\n.thumbnail > img,\n.thumbnail a > img {\n  margin-right: auto;\n  margin-left: auto;\n}\na.thumbnail:hover,\na.thumbnail:focus,\na.thumbnail.active {\n  border-color: #337ab7;\n}\n.thumbnail .caption {\n  padding: 9px;\n  color: #333;\n}\n.alert {\n  padding: 15px;\n  margin-bottom: 20px;\n  border: 1px solid transparent;\n  border-radius: 4px;\n}\n.alert h4 {\n  margin-top: 0;\n  color: inherit;\n}\n.alert .alert-link {\n  font-weight: bold;\n}\n.alert > p,\n.alert > ul {\n  margin-bottom: 0;\n}\n.alert > p + p {\n  margin-top: 5px;\n}\n.alert-dismissable,\n.alert-dismissible {\n  padding-right: 35px;\n}\n.alert-dismissable .close,\n.alert-dismissible .close {\n  position: relative;\n  top: -2px;\n  right: -21px;\n  color: inherit;\n}\n.alert-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.alert-success hr {\n  border-top-color: #c9e2b3;\n}\n.alert-success .alert-link {\n  color: #2b542c;\n}\n.alert-info {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.alert-info hr {\n  border-top-color: #a6e1ec;\n}\n.alert-info .alert-link {\n  color: #245269;\n}\n.alert-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.alert-warning hr {\n  border-top-color: #f7e1b5;\n}\n.alert-warning .alert-link {\n  color: #66512c;\n}\n.alert-danger {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.alert-danger hr {\n  border-top-color: #e4b9c0;\n}\n.alert-danger .alert-link {\n  color: #843534;\n}\n@-webkit-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@-o-keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n@keyframes progress-bar-stripes {\n  from {\n    background-position: 40px 0;\n  }\n  to {\n    background-position: 0 0;\n  }\n}\n.progress {\n  height: 20px;\n  margin-bottom: 20px;\n  overflow: hidden;\n  background-color: #f5f5f5;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n          box-shadow: inset 0 1px 2px rgba(0, 0, 0, .1);\n}\n.progress-bar {\n  float: left;\n  width: 0;\n  height: 100%;\n  font-size: 12px;\n  line-height: 20px;\n  color: #fff;\n  text-align: center;\n  background-color: #337ab7;\n  -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n          box-shadow: inset 0 -1px 0 rgba(0, 0, 0, .15);\n  -webkit-transition: width .6s ease;\n       -o-transition: width .6s ease;\n          transition: width .6s ease;\n}\n.progress-striped .progress-bar,\n.progress-bar-striped {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  -webkit-background-size: 40px 40px;\n          background-size: 40px 40px;\n}\n.progress.active .progress-bar,\n.progress-bar.active {\n  -webkit-animation: progress-bar-stripes 2s linear infinite;\n       -o-animation: progress-bar-stripes 2s linear infinite;\n          animation: progress-bar-stripes 2s linear infinite;\n}\n.progress-bar-success {\n  background-color: #5cb85c;\n}\n.progress-striped .progress-bar-success {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-info {\n  background-color: #5bc0de;\n}\n.progress-striped .progress-bar-info {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-warning {\n  background-color: #f0ad4e;\n}\n.progress-striped .progress-bar-warning {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.progress-bar-danger {\n  background-color: #d9534f;\n}\n.progress-striped .progress-bar-danger {\n  background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:      -o-linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n  background-image:         linear-gradient(45deg, rgba(255, 255, 255, .15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .15) 50%, rgba(255, 255, 255, .15) 75%, transparent 75%, transparent);\n}\n.media {\n  margin-top: 15px;\n}\n.media:first-child {\n  margin-top: 0;\n}\n.media,\n.media-body {\n  overflow: hidden;\n  zoom: 1;\n}\n.media-body {\n  width: 10000px;\n}\n.media-object {\n  display: block;\n}\n.media-object.img-thumbnail {\n  max-width: none;\n}\n.media-right,\n.media > .pull-right {\n  padding-left: 10px;\n}\n.media-left,\n.media > .pull-left {\n  padding-right: 10px;\n}\n.media-left,\n.media-right,\n.media-body {\n  display: table-cell;\n  vertical-align: top;\n}\n.media-middle {\n  vertical-align: middle;\n}\n.media-bottom {\n  vertical-align: bottom;\n}\n.media-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.media-list {\n  padding-left: 0;\n  list-style: none;\n}\n.list-group {\n  padding-left: 0;\n  margin-bottom: 20px;\n}\n.list-group-item {\n  position: relative;\n  display: block;\n  padding: 10px 15px;\n  margin-bottom: -1px;\n  background-color: #fff;\n  border: 1px solid #ddd;\n}\n.list-group-item:first-child {\n  border-top-left-radius: 4px;\n  border-top-right-radius: 4px;\n}\n.list-group-item:last-child {\n  margin-bottom: 0;\n  border-bottom-right-radius: 4px;\n  border-bottom-left-radius: 4px;\n}\na.list-group-item,\nbutton.list-group-item {\n  color: #555;\n}\na.list-group-item .list-group-item-heading,\nbutton.list-group-item .list-group-item-heading {\n  color: #333;\n}\na.list-group-item:hover,\nbutton.list-group-item:hover,\na.list-group-item:focus,\nbutton.list-group-item:focus {\n  color: #555;\n  text-decoration: none;\n  background-color: #f5f5f5;\n}\nbutton.list-group-item {\n  width: 100%;\n  text-align: left;\n}\n.list-group-item.disabled,\n.list-group-item.disabled:hover,\n.list-group-item.disabled:focus {\n  color: #777;\n  cursor: not-allowed;\n  background-color: #eee;\n}\n.list-group-item.disabled .list-group-item-heading,\n.list-group-item.disabled:hover .list-group-item-heading,\n.list-group-item.disabled:focus .list-group-item-heading {\n  color: inherit;\n}\n.list-group-item.disabled .list-group-item-text,\n.list-group-item.disabled:hover .list-group-item-text,\n.list-group-item.disabled:focus .list-group-item-text {\n  color: #777;\n}\n.list-group-item.active,\n.list-group-item.active:hover,\n.list-group-item.active:focus {\n  z-index: 2;\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.list-group-item.active .list-group-item-heading,\n.list-group-item.active:hover .list-group-item-heading,\n.list-group-item.active:focus .list-group-item-heading,\n.list-group-item.active .list-group-item-heading > small,\n.list-group-item.active:hover .list-group-item-heading > small,\n.list-group-item.active:focus .list-group-item-heading > small,\n.list-group-item.active .list-group-item-heading > .small,\n.list-group-item.active:hover .list-group-item-heading > .small,\n.list-group-item.active:focus .list-group-item-heading > .small {\n  color: inherit;\n}\n.list-group-item.active .list-group-item-text,\n.list-group-item.active:hover .list-group-item-text,\n.list-group-item.active:focus .list-group-item-text {\n  color: #c7ddef;\n}\n.list-group-item-success {\n  color: #3c763d;\n  background-color: #dff0d8;\n}\na.list-group-item-success,\nbutton.list-group-item-success {\n  color: #3c763d;\n}\na.list-group-item-success .list-group-item-heading,\nbutton.list-group-item-success .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-success:hover,\nbutton.list-group-item-success:hover,\na.list-group-item-success:focus,\nbutton.list-group-item-success:focus {\n  color: #3c763d;\n  background-color: #d0e9c6;\n}\na.list-group-item-success.active,\nbutton.list-group-item-success.active,\na.list-group-item-success.active:hover,\nbutton.list-group-item-success.active:hover,\na.list-group-item-success.active:focus,\nbutton.list-group-item-success.active:focus {\n  color: #fff;\n  background-color: #3c763d;\n  border-color: #3c763d;\n}\n.list-group-item-info {\n  color: #31708f;\n  background-color: #d9edf7;\n}\na.list-group-item-info,\nbutton.list-group-item-info {\n  color: #31708f;\n}\na.list-group-item-info .list-group-item-heading,\nbutton.list-group-item-info .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-info:hover,\nbutton.list-group-item-info:hover,\na.list-group-item-info:focus,\nbutton.list-group-item-info:focus {\n  color: #31708f;\n  background-color: #c4e3f3;\n}\na.list-group-item-info.active,\nbutton.list-group-item-info.active,\na.list-group-item-info.active:hover,\nbutton.list-group-item-info.active:hover,\na.list-group-item-info.active:focus,\nbutton.list-group-item-info.active:focus {\n  color: #fff;\n  background-color: #31708f;\n  border-color: #31708f;\n}\n.list-group-item-warning {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n}\na.list-group-item-warning,\nbutton.list-group-item-warning {\n  color: #8a6d3b;\n}\na.list-group-item-warning .list-group-item-heading,\nbutton.list-group-item-warning .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-warning:hover,\nbutton.list-group-item-warning:hover,\na.list-group-item-warning:focus,\nbutton.list-group-item-warning:focus {\n  color: #8a6d3b;\n  background-color: #faf2cc;\n}\na.list-group-item-warning.active,\nbutton.list-group-item-warning.active,\na.list-group-item-warning.active:hover,\nbutton.list-group-item-warning.active:hover,\na.list-group-item-warning.active:focus,\nbutton.list-group-item-warning.active:focus {\n  color: #fff;\n  background-color: #8a6d3b;\n  border-color: #8a6d3b;\n}\n.list-group-item-danger {\n  color: #a94442;\n  background-color: #f2dede;\n}\na.list-group-item-danger,\nbutton.list-group-item-danger {\n  color: #a94442;\n}\na.list-group-item-danger .list-group-item-heading,\nbutton.list-group-item-danger .list-group-item-heading {\n  color: inherit;\n}\na.list-group-item-danger:hover,\nbutton.list-group-item-danger:hover,\na.list-group-item-danger:focus,\nbutton.list-group-item-danger:focus {\n  color: #a94442;\n  background-color: #ebcccc;\n}\na.list-group-item-danger.active,\nbutton.list-group-item-danger.active,\na.list-group-item-danger.active:hover,\nbutton.list-group-item-danger.active:hover,\na.list-group-item-danger.active:focus,\nbutton.list-group-item-danger.active:focus {\n  color: #fff;\n  background-color: #a94442;\n  border-color: #a94442;\n}\n.list-group-item-heading {\n  margin-top: 0;\n  margin-bottom: 5px;\n}\n.list-group-item-text {\n  margin-bottom: 0;\n  line-height: 1.3;\n}\n.panel {\n  margin-bottom: 20px;\n  background-color: #fff;\n  border: 1px solid transparent;\n  border-radius: 4px;\n  -webkit-box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n          box-shadow: 0 1px 1px rgba(0, 0, 0, .05);\n}\n.panel-body {\n  padding: 15px;\n}\n.panel-heading {\n  padding: 10px 15px;\n  border-bottom: 1px solid transparent;\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel-heading > .dropdown .dropdown-toggle {\n  color: inherit;\n}\n.panel-title {\n  margin-top: 0;\n  margin-bottom: 0;\n  font-size: 16px;\n  color: inherit;\n}\n.panel-title > a,\n.panel-title > small,\n.panel-title > .small,\n.panel-title > small > a,\n.panel-title > .small > a {\n  color: inherit;\n}\n.panel-footer {\n  padding: 10px 15px;\n  background-color: #f5f5f5;\n  border-top: 1px solid #ddd;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .list-group,\n.panel > .panel-collapse > .list-group {\n  margin-bottom: 0;\n}\n.panel > .list-group .list-group-item,\n.panel > .panel-collapse > .list-group .list-group-item {\n  border-width: 1px 0;\n  border-radius: 0;\n}\n.panel > .list-group:first-child .list-group-item:first-child,\n.panel > .panel-collapse > .list-group:first-child .list-group-item:first-child {\n  border-top: 0;\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .list-group:last-child .list-group-item:last-child,\n.panel > .panel-collapse > .list-group:last-child .list-group-item:last-child {\n  border-bottom: 0;\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .panel-heading + .panel-collapse > .list-group .list-group-item:first-child {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n}\n.panel-heading + .list-group .list-group-item:first-child {\n  border-top-width: 0;\n}\n.list-group + .panel-footer {\n  border-top-width: 0;\n}\n.panel > .table,\n.panel > .table-responsive > .table,\n.panel > .panel-collapse > .table {\n  margin-bottom: 0;\n}\n.panel > .table caption,\n.panel > .table-responsive > .table caption,\n.panel > .panel-collapse > .table caption {\n  padding-right: 15px;\n  padding-left: 15px;\n}\n.panel > .table:first-child,\n.panel > .table-responsive:first-child > .table:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child {\n  border-top-left-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:first-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:first-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:first-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:first-child {\n  border-top-left-radius: 3px;\n}\n.panel > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child td:last-child,\n.panel > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > thead:first-child > tr:first-child th:last-child,\n.panel > .table:first-child > tbody:first-child > tr:first-child th:last-child,\n.panel > .table-responsive:first-child > .table:first-child > tbody:first-child > tr:first-child th:last-child {\n  border-top-right-radius: 3px;\n}\n.panel > .table:last-child,\n.panel > .table-responsive:last-child > .table:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child {\n  border-bottom-right-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:first-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:first-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:first-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:first-child {\n  border-bottom-left-radius: 3px;\n}\n.panel > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child td:last-child,\n.panel > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tbody:last-child > tr:last-child th:last-child,\n.panel > .table:last-child > tfoot:last-child > tr:last-child th:last-child,\n.panel > .table-responsive:last-child > .table:last-child > tfoot:last-child > tr:last-child th:last-child {\n  border-bottom-right-radius: 3px;\n}\n.panel > .panel-body + .table,\n.panel > .panel-body + .table-responsive,\n.panel > .table + .panel-body,\n.panel > .table-responsive + .panel-body {\n  border-top: 1px solid #ddd;\n}\n.panel > .table > tbody:first-child > tr:first-child th,\n.panel > .table > tbody:first-child > tr:first-child td {\n  border-top: 0;\n}\n.panel > .table-bordered,\n.panel > .table-responsive > .table-bordered {\n  border: 0;\n}\n.panel > .table-bordered > thead > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:first-child,\n.panel > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:first-child,\n.panel > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:first-child,\n.panel > .table-bordered > thead > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:first-child,\n.panel > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:first-child,\n.panel > .table-bordered > tfoot > tr > td:first-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:first-child {\n  border-left: 0;\n}\n.panel > .table-bordered > thead > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > th:last-child,\n.panel > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > th:last-child,\n.panel > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > th:last-child,\n.panel > .table-bordered > thead > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > thead > tr > td:last-child,\n.panel > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tbody > tr > td:last-child,\n.panel > .table-bordered > tfoot > tr > td:last-child,\n.panel > .table-responsive > .table-bordered > tfoot > tr > td:last-child {\n  border-right: 0;\n}\n.panel > .table-bordered > thead > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > td,\n.panel > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > td,\n.panel > .table-bordered > thead > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > thead > tr:first-child > th,\n.panel > .table-bordered > tbody > tr:first-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:first-child > th {\n  border-bottom: 0;\n}\n.panel > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > td,\n.panel > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > td,\n.panel > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tbody > tr:last-child > th,\n.panel > .table-bordered > tfoot > tr:last-child > th,\n.panel > .table-responsive > .table-bordered > tfoot > tr:last-child > th {\n  border-bottom: 0;\n}\n.panel > .table-responsive {\n  margin-bottom: 0;\n  border: 0;\n}\n.panel-group {\n  margin-bottom: 20px;\n}\n.panel-group .panel {\n  margin-bottom: 0;\n  border-radius: 4px;\n}\n.panel-group .panel + .panel {\n  margin-top: 5px;\n}\n.panel-group .panel-heading {\n  border-bottom: 0;\n}\n.panel-group .panel-heading + .panel-collapse > .panel-body,\n.panel-group .panel-heading + .panel-collapse > .list-group {\n  border-top: 1px solid #ddd;\n}\n.panel-group .panel-footer {\n  border-top: 0;\n}\n.panel-group .panel-footer + .panel-collapse .panel-body {\n  border-bottom: 1px solid #ddd;\n}\n.panel-default {\n  border-color: #ddd;\n}\n.panel-default > .panel-heading {\n  color: #333;\n  background-color: #f5f5f5;\n  border-color: #ddd;\n}\n.panel-default > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ddd;\n}\n.panel-default > .panel-heading .badge {\n  color: #f5f5f5;\n  background-color: #333;\n}\n.panel-default > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ddd;\n}\n.panel-primary {\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading {\n  color: #fff;\n  background-color: #337ab7;\n  border-color: #337ab7;\n}\n.panel-primary > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #337ab7;\n}\n.panel-primary > .panel-heading .badge {\n  color: #337ab7;\n  background-color: #fff;\n}\n.panel-primary > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #337ab7;\n}\n.panel-success {\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading {\n  color: #3c763d;\n  background-color: #dff0d8;\n  border-color: #d6e9c6;\n}\n.panel-success > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #d6e9c6;\n}\n.panel-success > .panel-heading .badge {\n  color: #dff0d8;\n  background-color: #3c763d;\n}\n.panel-success > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #d6e9c6;\n}\n.panel-info {\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading {\n  color: #31708f;\n  background-color: #d9edf7;\n  border-color: #bce8f1;\n}\n.panel-info > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #bce8f1;\n}\n.panel-info > .panel-heading .badge {\n  color: #d9edf7;\n  background-color: #31708f;\n}\n.panel-info > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #bce8f1;\n}\n.panel-warning {\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading {\n  color: #8a6d3b;\n  background-color: #fcf8e3;\n  border-color: #faebcc;\n}\n.panel-warning > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #faebcc;\n}\n.panel-warning > .panel-heading .badge {\n  color: #fcf8e3;\n  background-color: #8a6d3b;\n}\n.panel-warning > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #faebcc;\n}\n.panel-danger {\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading {\n  color: #a94442;\n  background-color: #f2dede;\n  border-color: #ebccd1;\n}\n.panel-danger > .panel-heading + .panel-collapse > .panel-body {\n  border-top-color: #ebccd1;\n}\n.panel-danger > .panel-heading .badge {\n  color: #f2dede;\n  background-color: #a94442;\n}\n.panel-danger > .panel-footer + .panel-collapse > .panel-body {\n  border-bottom-color: #ebccd1;\n}\n.embed-responsive {\n  position: relative;\n  display: block;\n  height: 0;\n  padding: 0;\n  overflow: hidden;\n}\n.embed-responsive .embed-responsive-item,\n.embed-responsive iframe,\n.embed-responsive embed,\n.embed-responsive object,\n.embed-responsive video {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  border: 0;\n}\n.embed-responsive-16by9 {\n  padding-bottom: 56.25%;\n}\n.embed-responsive-4by3 {\n  padding-bottom: 75%;\n}\n.well {\n  min-height: 20px;\n  padding: 19px;\n  margin-bottom: 20px;\n  background-color: #f5f5f5;\n  border: 1px solid #e3e3e3;\n  border-radius: 4px;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n          box-shadow: inset 0 1px 1px rgba(0, 0, 0, .05);\n}\n.well blockquote {\n  border-color: #ddd;\n  border-color: rgba(0, 0, 0, .15);\n}\n.well-lg {\n  padding: 24px;\n  border-radius: 6px;\n}\n.well-sm {\n  padding: 9px;\n  border-radius: 3px;\n}\n.close {\n  float: right;\n  font-size: 21px;\n  font-weight: bold;\n  line-height: 1;\n  color: #000;\n  text-shadow: 0 1px 0 #fff;\n  filter: alpha(opacity=20);\n  opacity: .2;\n}\n.close:hover,\n.close:focus {\n  color: #000;\n  text-decoration: none;\n  cursor: pointer;\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\nbutton.close {\n  -webkit-appearance: none;\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n}\n.modal-open {\n  overflow: hidden;\n}\n.modal {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1050;\n  display: none;\n  overflow: hidden;\n  -webkit-overflow-scrolling: touch;\n  outline: 0;\n}\n.modal.fade .modal-dialog {\n  -webkit-transition: -webkit-transform .3s ease-out;\n       -o-transition:      -o-transform .3s ease-out;\n          transition:         transform .3s ease-out;\n  -webkit-transform: translate(0, -25%);\n      -ms-transform: translate(0, -25%);\n       -o-transform: translate(0, -25%);\n          transform: translate(0, -25%);\n}\n.modal.in .modal-dialog {\n  -webkit-transform: translate(0, 0);\n      -ms-transform: translate(0, 0);\n       -o-transform: translate(0, 0);\n          transform: translate(0, 0);\n}\n.modal-open .modal {\n  overflow-x: hidden;\n  overflow-y: auto;\n}\n.modal-dialog {\n  position: relative;\n  width: auto;\n  margin: 10px;\n}\n.modal-content {\n  position: relative;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #999;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  outline: 0;\n  -webkit-box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n          box-shadow: 0 3px 9px rgba(0, 0, 0, .5);\n}\n.modal-backdrop {\n  position: fixed;\n  top: 0;\n  right: 0;\n  bottom: 0;\n  left: 0;\n  z-index: 1040;\n  background-color: #000;\n}\n.modal-backdrop.fade {\n  filter: alpha(opacity=0);\n  opacity: 0;\n}\n.modal-backdrop.in {\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.modal-header {\n  padding: 15px;\n  border-bottom: 1px solid #e5e5e5;\n}\n.modal-header .close {\n  margin-top: -2px;\n}\n.modal-title {\n  margin: 0;\n  line-height: 1.42857143;\n}\n.modal-body {\n  position: relative;\n  padding: 15px;\n}\n.modal-footer {\n  padding: 15px;\n  text-align: right;\n  border-top: 1px solid #e5e5e5;\n}\n.modal-footer .btn + .btn {\n  margin-bottom: 0;\n  margin-left: 5px;\n}\n.modal-footer .btn-group .btn + .btn {\n  margin-left: -1px;\n}\n.modal-footer .btn-block + .btn-block {\n  margin-left: 0;\n}\n.modal-scrollbar-measure {\n  position: absolute;\n  top: -9999px;\n  width: 50px;\n  height: 50px;\n  overflow: scroll;\n}\n@media (min-width: 768px) {\n  .modal-dialog {\n    width: 600px;\n    margin: 30px auto;\n  }\n  .modal-content {\n    -webkit-box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n            box-shadow: 0 5px 15px rgba(0, 0, 0, .5);\n  }\n  .modal-sm {\n    width: 300px;\n  }\n}\n@media (min-width: 992px) {\n  .modal-lg {\n    width: 900px;\n  }\n}\n.tooltip {\n  position: absolute;\n  z-index: 1070;\n  display: block;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 12px;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  filter: alpha(opacity=0);\n  opacity: 0;\n\n  line-break: auto;\n}\n.tooltip.in {\n  filter: alpha(opacity=90);\n  opacity: .9;\n}\n.tooltip.top {\n  padding: 5px 0;\n  margin-top: -3px;\n}\n.tooltip.right {\n  padding: 0 5px;\n  margin-left: 3px;\n}\n.tooltip.bottom {\n  padding: 5px 0;\n  margin-top: 3px;\n}\n.tooltip.left {\n  padding: 0 5px;\n  margin-left: -3px;\n}\n.tooltip-inner {\n  max-width: 200px;\n  padding: 3px 8px;\n  color: #fff;\n  text-align: center;\n  background-color: #000;\n  border-radius: 4px;\n}\n.tooltip-arrow {\n  position: absolute;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.tooltip.top .tooltip-arrow {\n  bottom: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-left .tooltip-arrow {\n  right: 5px;\n  bottom: 0;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.top-right .tooltip-arrow {\n  bottom: 0;\n  left: 5px;\n  margin-bottom: -5px;\n  border-width: 5px 5px 0;\n  border-top-color: #000;\n}\n.tooltip.right .tooltip-arrow {\n  top: 50%;\n  left: 0;\n  margin-top: -5px;\n  border-width: 5px 5px 5px 0;\n  border-right-color: #000;\n}\n.tooltip.left .tooltip-arrow {\n  top: 50%;\n  right: 0;\n  margin-top: -5px;\n  border-width: 5px 0 5px 5px;\n  border-left-color: #000;\n}\n.tooltip.bottom .tooltip-arrow {\n  top: 0;\n  left: 50%;\n  margin-left: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-left .tooltip-arrow {\n  top: 0;\n  right: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.tooltip.bottom-right .tooltip-arrow {\n  top: 0;\n  left: 5px;\n  margin-top: -5px;\n  border-width: 0 5px 5px;\n  border-bottom-color: #000;\n}\n.popover {\n  position: absolute;\n  top: 0;\n  left: 0;\n  z-index: 1060;\n  display: none;\n  max-width: 276px;\n  padding: 1px;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 14px;\n  font-style: normal;\n  font-weight: normal;\n  line-height: 1.42857143;\n  text-align: left;\n  text-align: start;\n  text-decoration: none;\n  text-shadow: none;\n  text-transform: none;\n  letter-spacing: normal;\n  word-break: normal;\n  word-spacing: normal;\n  word-wrap: normal;\n  white-space: normal;\n  background-color: #fff;\n  -webkit-background-clip: padding-box;\n          background-clip: padding-box;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, .2);\n  border-radius: 6px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n          box-shadow: 0 5px 10px rgba(0, 0, 0, .2);\n\n  line-break: auto;\n}\n.popover.top {\n  margin-top: -10px;\n}\n.popover.right {\n  margin-left: 10px;\n}\n.popover.bottom {\n  margin-top: 10px;\n}\n.popover.left {\n  margin-left: -10px;\n}\n.popover-title {\n  padding: 8px 14px;\n  margin: 0;\n  font-size: 14px;\n  background-color: #f7f7f7;\n  border-bottom: 1px solid #ebebeb;\n  border-radius: 5px 5px 0 0;\n}\n.popover-content {\n  padding: 9px 14px;\n}\n.popover > .arrow,\n.popover > .arrow:after {\n  position: absolute;\n  display: block;\n  width: 0;\n  height: 0;\n  border-color: transparent;\n  border-style: solid;\n}\n.popover > .arrow {\n  border-width: 11px;\n}\n.popover > .arrow:after {\n  content: \"\";\n  border-width: 10px;\n}\n.popover.top > .arrow {\n  bottom: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-color: #999;\n  border-top-color: rgba(0, 0, 0, .25);\n  border-bottom-width: 0;\n}\n.popover.top > .arrow:after {\n  bottom: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-color: #fff;\n  border-bottom-width: 0;\n}\n.popover.right > .arrow {\n  top: 50%;\n  left: -11px;\n  margin-top: -11px;\n  border-right-color: #999;\n  border-right-color: rgba(0, 0, 0, .25);\n  border-left-width: 0;\n}\n.popover.right > .arrow:after {\n  bottom: -10px;\n  left: 1px;\n  content: \" \";\n  border-right-color: #fff;\n  border-left-width: 0;\n}\n.popover.bottom > .arrow {\n  top: -11px;\n  left: 50%;\n  margin-left: -11px;\n  border-top-width: 0;\n  border-bottom-color: #999;\n  border-bottom-color: rgba(0, 0, 0, .25);\n}\n.popover.bottom > .arrow:after {\n  top: 1px;\n  margin-left: -10px;\n  content: \" \";\n  border-top-width: 0;\n  border-bottom-color: #fff;\n}\n.popover.left > .arrow {\n  top: 50%;\n  right: -11px;\n  margin-top: -11px;\n  border-right-width: 0;\n  border-left-color: #999;\n  border-left-color: rgba(0, 0, 0, .25);\n}\n.popover.left > .arrow:after {\n  right: 1px;\n  bottom: -10px;\n  content: \" \";\n  border-right-width: 0;\n  border-left-color: #fff;\n}\n.carousel {\n  position: relative;\n}\n.carousel-inner {\n  position: relative;\n  width: 100%;\n  overflow: hidden;\n}\n.carousel-inner > .item {\n  position: relative;\n  display: none;\n  -webkit-transition: .6s ease-in-out left;\n       -o-transition: .6s ease-in-out left;\n          transition: .6s ease-in-out left;\n}\n.carousel-inner > .item > img,\n.carousel-inner > .item > a > img {\n  line-height: 1;\n}\n@media all and (transform-3d), (-webkit-transform-3d) {\n  .carousel-inner > .item {\n    -webkit-transition: -webkit-transform .6s ease-in-out;\n         -o-transition:      -o-transform .6s ease-in-out;\n            transition:         transform .6s ease-in-out;\n\n    -webkit-backface-visibility: hidden;\n            backface-visibility: hidden;\n    -webkit-perspective: 1000px;\n            perspective: 1000px;\n  }\n  .carousel-inner > .item.next,\n  .carousel-inner > .item.active.right {\n    left: 0;\n    -webkit-transform: translate3d(100%, 0, 0);\n            transform: translate3d(100%, 0, 0);\n  }\n  .carousel-inner > .item.prev,\n  .carousel-inner > .item.active.left {\n    left: 0;\n    -webkit-transform: translate3d(-100%, 0, 0);\n            transform: translate3d(-100%, 0, 0);\n  }\n  .carousel-inner > .item.next.left,\n  .carousel-inner > .item.prev.right,\n  .carousel-inner > .item.active {\n    left: 0;\n    -webkit-transform: translate3d(0, 0, 0);\n            transform: translate3d(0, 0, 0);\n  }\n}\n.carousel-inner > .active,\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  display: block;\n}\n.carousel-inner > .active {\n  left: 0;\n}\n.carousel-inner > .next,\n.carousel-inner > .prev {\n  position: absolute;\n  top: 0;\n  width: 100%;\n}\n.carousel-inner > .next {\n  left: 100%;\n}\n.carousel-inner > .prev {\n  left: -100%;\n}\n.carousel-inner > .next.left,\n.carousel-inner > .prev.right {\n  left: 0;\n}\n.carousel-inner > .active.left {\n  left: -100%;\n}\n.carousel-inner > .active.right {\n  left: 100%;\n}\n.carousel-control {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  width: 15%;\n  font-size: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n  background-color: rgba(0, 0, 0, 0);\n  filter: alpha(opacity=50);\n  opacity: .5;\n}\n.carousel-control.left {\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .5)), to(rgba(0, 0, 0, .0001)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .5) 0%, rgba(0, 0, 0, .0001) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control.right {\n  right: 0;\n  left: auto;\n  background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image:      -o-linear-gradient(left, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, .0001)), to(rgba(0, 0, 0, .5)));\n  background-image:         linear-gradient(to right, rgba(0, 0, 0, .0001) 0%, rgba(0, 0, 0, .5) 100%);\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1);\n  background-repeat: repeat-x;\n}\n.carousel-control:hover,\n.carousel-control:focus {\n  color: #fff;\n  text-decoration: none;\n  filter: alpha(opacity=90);\n  outline: 0;\n  opacity: .9;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-left,\n.carousel-control .glyphicon-chevron-right {\n  position: absolute;\n  top: 50%;\n  z-index: 5;\n  display: inline-block;\n  margin-top: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .glyphicon-chevron-left {\n  left: 50%;\n  margin-left: -10px;\n}\n.carousel-control .icon-next,\n.carousel-control .glyphicon-chevron-right {\n  right: 50%;\n  margin-right: -10px;\n}\n.carousel-control .icon-prev,\n.carousel-control .icon-next {\n  width: 20px;\n  height: 20px;\n  font-family: serif;\n  line-height: 1;\n}\n.carousel-control .icon-prev:before {\n  content: '\\2039';\n}\n.carousel-control .icon-next:before {\n  content: '\\203a';\n}\n.carousel-indicators {\n  position: absolute;\n  bottom: 10px;\n  left: 50%;\n  z-index: 15;\n  width: 60%;\n  padding-left: 0;\n  margin-left: -30%;\n  text-align: center;\n  list-style: none;\n}\n.carousel-indicators li {\n  display: inline-block;\n  width: 10px;\n  height: 10px;\n  margin: 1px;\n  text-indent: -999px;\n  cursor: pointer;\n  background-color: #000 \\9;\n  background-color: rgba(0, 0, 0, 0);\n  border: 1px solid #fff;\n  border-radius: 10px;\n}\n.carousel-indicators .active {\n  width: 12px;\n  height: 12px;\n  margin: 0;\n  background-color: #fff;\n}\n.carousel-caption {\n  position: absolute;\n  right: 15%;\n  bottom: 20px;\n  left: 15%;\n  z-index: 10;\n  padding-top: 20px;\n  padding-bottom: 20px;\n  color: #fff;\n  text-align: center;\n  text-shadow: 0 1px 2px rgba(0, 0, 0, .6);\n}\n.carousel-caption .btn {\n  text-shadow: none;\n}\n@media screen and (min-width: 768px) {\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-prev,\n  .carousel-control .icon-next {\n    width: 30px;\n    height: 30px;\n    margin-top: -10px;\n    font-size: 30px;\n  }\n  .carousel-control .glyphicon-chevron-left,\n  .carousel-control .icon-prev {\n    margin-left: -10px;\n  }\n  .carousel-control .glyphicon-chevron-right,\n  .carousel-control .icon-next {\n    margin-right: -10px;\n  }\n  .carousel-caption {\n    right: 20%;\n    left: 20%;\n    padding-bottom: 30px;\n  }\n  .carousel-indicators {\n    bottom: 20px;\n  }\n}\n.clearfix:before,\n.clearfix:after,\n.dl-horizontal dd:before,\n.dl-horizontal dd:after,\n.container:before,\n.container:after,\n.container-fluid:before,\n.container-fluid:after,\n.row:before,\n.row:after,\n.form-horizontal .form-group:before,\n.form-horizontal .form-group:after,\n.btn-toolbar:before,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:before,\n.btn-group-vertical > .btn-group:after,\n.nav:before,\n.nav:after,\n.navbar:before,\n.navbar:after,\n.navbar-header:before,\n.navbar-header:after,\n.navbar-collapse:before,\n.navbar-collapse:after,\n.pager:before,\n.pager:after,\n.panel-body:before,\n.panel-body:after,\n.modal-header:before,\n.modal-header:after,\n.modal-footer:before,\n.modal-footer:after {\n  display: table;\n  content: \" \";\n}\n.clearfix:after,\n.dl-horizontal dd:after,\n.container:after,\n.container-fluid:after,\n.row:after,\n.form-horizontal .form-group:after,\n.btn-toolbar:after,\n.btn-group-vertical > .btn-group:after,\n.nav:after,\n.navbar:after,\n.navbar-header:after,\n.navbar-collapse:after,\n.pager:after,\n.panel-body:after,\n.modal-header:after,\n.modal-footer:after {\n  clear: both;\n}\n.center-block {\n  display: block;\n  margin-right: auto;\n  margin-left: auto;\n}\n.pull-right {\n  float: right !important;\n}\n.pull-left {\n  float: left !important;\n}\n.hide {\n  display: none !important;\n}\n.show {\n  display: block !important;\n}\n.invisible {\n  visibility: hidden;\n}\n.text-hide {\n  font: 0/0 a;\n  color: transparent;\n  text-shadow: none;\n  background-color: transparent;\n  border: 0;\n}\n.hidden {\n  display: none !important;\n}\n.affix {\n  position: fixed;\n}\n@-ms-viewport {\n  width: device-width;\n}\n.visible-xs,\n.visible-sm,\n.visible-md,\n.visible-lg {\n  display: none !important;\n}\n.visible-xs-block,\n.visible-xs-inline,\n.visible-xs-inline-block,\n.visible-sm-block,\n.visible-sm-inline,\n.visible-sm-inline-block,\n.visible-md-block,\n.visible-md-inline,\n.visible-md-inline-block,\n.visible-lg-block,\n.visible-lg-inline,\n.visible-lg-inline-block {\n  display: none !important;\n}\n@media (max-width: 767px) {\n  .visible-xs {\n    display: block !important;\n  }\n  table.visible-xs {\n    display: table !important;\n  }\n  tr.visible-xs {\n    display: table-row !important;\n  }\n  th.visible-xs,\n  td.visible-xs {\n    display: table-cell !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-block {\n    display: block !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline {\n    display: inline !important;\n  }\n}\n@media (max-width: 767px) {\n  .visible-xs-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm {\n    display: block !important;\n  }\n  table.visible-sm {\n    display: table !important;\n  }\n  tr.visible-sm {\n    display: table-row !important;\n  }\n  th.visible-sm,\n  td.visible-sm {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-block {\n    display: block !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .visible-sm-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md {\n    display: block !important;\n  }\n  table.visible-md {\n    display: table !important;\n  }\n  tr.visible-md {\n    display: table-row !important;\n  }\n  th.visible-md,\n  td.visible-md {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-block {\n    display: block !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .visible-md-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg {\n    display: block !important;\n  }\n  table.visible-lg {\n    display: table !important;\n  }\n  tr.visible-lg {\n    display: table-row !important;\n  }\n  th.visible-lg,\n  td.visible-lg {\n    display: table-cell !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-block {\n    display: block !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline {\n    display: inline !important;\n  }\n}\n@media (min-width: 1200px) {\n  .visible-lg-inline-block {\n    display: inline-block !important;\n  }\n}\n@media (max-width: 767px) {\n  .hidden-xs {\n    display: none !important;\n  }\n}\n@media (min-width: 768px) and (max-width: 991px) {\n  .hidden-sm {\n    display: none !important;\n  }\n}\n@media (min-width: 992px) and (max-width: 1199px) {\n  .hidden-md {\n    display: none !important;\n  }\n}\n@media (min-width: 1200px) {\n  .hidden-lg {\n    display: none !important;\n  }\n}\n.visible-print {\n  display: none !important;\n}\n@media print {\n  .visible-print {\n    display: block !important;\n  }\n  table.visible-print {\n    display: table !important;\n  }\n  tr.visible-print {\n    display: table-row !important;\n  }\n  th.visible-print,\n  td.visible-print {\n    display: table-cell !important;\n  }\n}\n.visible-print-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-block {\n    display: block !important;\n  }\n}\n.visible-print-inline {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline {\n    display: inline !important;\n  }\n}\n.visible-print-inline-block {\n  display: none !important;\n}\n@media print {\n  .visible-print-inline-block {\n    display: inline-block !important;\n  }\n}\n@media print {\n  .hidden-print {\n    display: none !important;\n  }\n}\n/*# sourceMappingURL=bootstrap.css.map */\n"
  },
  {
    "path": "public/static/plugins/bootstrap/js/bootstrap.js",
    "content": "/*!\n * Bootstrap v3.3.6 (http://getbootstrap.com)\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under the MIT license\n */\n\nif (typeof jQuery === 'undefined') {\n  throw new Error('Bootstrap\\'s JavaScript requires jQuery')\n}\n\n+function ($) {\n  'use strict';\n  var version = $.fn.jquery.split(' ')[0].split('.')\n  if ((version[0] < 2 && version[1] < 9) || (version[0] == 1 && version[1] == 9 && version[2] < 1) || (version[0] > 2)) {\n    throw new Error('Bootstrap\\'s JavaScript requires jQuery version 1.9.1 or higher, but lower than version 3')\n  }\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: transition.js v3.3.6\n * http://getbootstrap.com/javascript/#transitions\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)\n  // ============================================================\n\n  function transitionEnd() {\n    var el = document.createElement('bootstrap')\n\n    var transEndEventNames = {\n      WebkitTransition : 'webkitTransitionEnd',\n      MozTransition    : 'transitionend',\n      OTransition      : 'oTransitionEnd otransitionend',\n      transition       : 'transitionend'\n    }\n\n    for (var name in transEndEventNames) {\n      if (el.style[name] !== undefined) {\n        return { end: transEndEventNames[name] }\n      }\n    }\n\n    return false // explicit for ie8 (  ._.)\n  }\n\n  // http://blog.alexmaccaw.com/css-transitions\n  $.fn.emulateTransitionEnd = function (duration) {\n    var called = false\n    var $el = this\n    $(this).one('bsTransitionEnd', function () { called = true })\n    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }\n    setTimeout(callback, duration)\n    return this\n  }\n\n  $(function () {\n    $.support.transition = transitionEnd()\n\n    if (!$.support.transition) return\n\n    $.event.special.bsTransitionEnd = {\n      bindType: $.support.transition.end,\n      delegateType: $.support.transition.end,\n      handle: function (e) {\n        if ($(e.target).is(this)) return e.handleObj.handler.apply(this, arguments)\n      }\n    }\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: alert.js v3.3.6\n * http://getbootstrap.com/javascript/#alerts\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // ALERT CLASS DEFINITION\n  // ======================\n\n  var dismiss = '[data-dismiss=\"alert\"]'\n  var Alert   = function (el) {\n    $(el).on('click', dismiss, this.close)\n  }\n\n  Alert.VERSION = '3.3.6'\n\n  Alert.TRANSITION_DURATION = 150\n\n  Alert.prototype.close = function (e) {\n    var $this    = $(this)\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = $(selector)\n\n    if (e) e.preventDefault()\n\n    if (!$parent.length) {\n      $parent = $this.closest('.alert')\n    }\n\n    $parent.trigger(e = $.Event('close.bs.alert'))\n\n    if (e.isDefaultPrevented()) return\n\n    $parent.removeClass('in')\n\n    function removeElement() {\n      // detach from parent, fire event then clean up data\n      $parent.detach().trigger('closed.bs.alert').remove()\n    }\n\n    $.support.transition && $parent.hasClass('fade') ?\n      $parent\n        .one('bsTransitionEnd', removeElement)\n        .emulateTransitionEnd(Alert.TRANSITION_DURATION) :\n      removeElement()\n  }\n\n\n  // ALERT PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.alert')\n\n      if (!data) $this.data('bs.alert', (data = new Alert(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  var old = $.fn.alert\n\n  $.fn.alert             = Plugin\n  $.fn.alert.Constructor = Alert\n\n\n  // ALERT NO CONFLICT\n  // =================\n\n  $.fn.alert.noConflict = function () {\n    $.fn.alert = old\n    return this\n  }\n\n\n  // ALERT DATA-API\n  // ==============\n\n  $(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: button.js v3.3.6\n * http://getbootstrap.com/javascript/#buttons\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // BUTTON PUBLIC CLASS DEFINITION\n  // ==============================\n\n  var Button = function (element, options) {\n    this.$element  = $(element)\n    this.options   = $.extend({}, Button.DEFAULTS, options)\n    this.isLoading = false\n  }\n\n  Button.VERSION  = '3.3.6'\n\n  Button.DEFAULTS = {\n    loadingText: 'loading...'\n  }\n\n  Button.prototype.setState = function (state) {\n    var d    = 'disabled'\n    var $el  = this.$element\n    var val  = $el.is('input') ? 'val' : 'html'\n    var data = $el.data()\n\n    state += 'Text'\n\n    if (data.resetText == null) $el.data('resetText', $el[val]())\n\n    // push to event loop to allow forms to submit\n    setTimeout($.proxy(function () {\n      $el[val](data[state] == null ? this.options[state] : data[state])\n\n      if (state == 'loadingText') {\n        this.isLoading = true\n        $el.addClass(d).attr(d, d)\n      } else if (this.isLoading) {\n        this.isLoading = false\n        $el.removeClass(d).removeAttr(d)\n      }\n    }, this), 0)\n  }\n\n  Button.prototype.toggle = function () {\n    var changed = true\n    var $parent = this.$element.closest('[data-toggle=\"buttons\"]')\n\n    if ($parent.length) {\n      var $input = this.$element.find('input')\n      if ($input.prop('type') == 'radio') {\n        if ($input.prop('checked')) changed = false\n        $parent.find('.active').removeClass('active')\n        this.$element.addClass('active')\n      } else if ($input.prop('type') == 'checkbox') {\n        if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false\n        this.$element.toggleClass('active')\n      }\n      $input.prop('checked', this.$element.hasClass('active'))\n      if (changed) $input.trigger('change')\n    } else {\n      this.$element.attr('aria-pressed', !this.$element.hasClass('active'))\n      this.$element.toggleClass('active')\n    }\n  }\n\n\n  // BUTTON PLUGIN DEFINITION\n  // ========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.button')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.button', (data = new Button(this, options)))\n\n      if (option == 'toggle') data.toggle()\n      else if (option) data.setState(option)\n    })\n  }\n\n  var old = $.fn.button\n\n  $.fn.button             = Plugin\n  $.fn.button.Constructor = Button\n\n\n  // BUTTON NO CONFLICT\n  // ==================\n\n  $.fn.button.noConflict = function () {\n    $.fn.button = old\n    return this\n  }\n\n\n  // BUTTON DATA-API\n  // ===============\n\n  $(document)\n    .on('click.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n      var $btn = $(e.target)\n      if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')\n      Plugin.call($btn, 'toggle')\n      if (!($(e.target).is('input[type=\"radio\"]') || $(e.target).is('input[type=\"checkbox\"]'))) e.preventDefault()\n    })\n    .on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^=\"button\"]', function (e) {\n      $(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))\n    })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: carousel.js v3.3.6\n * http://getbootstrap.com/javascript/#carousel\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // CAROUSEL CLASS DEFINITION\n  // =========================\n\n  var Carousel = function (element, options) {\n    this.$element    = $(element)\n    this.$indicators = this.$element.find('.carousel-indicators')\n    this.options     = options\n    this.paused      = null\n    this.sliding     = null\n    this.interval    = null\n    this.$active     = null\n    this.$items      = null\n\n    this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))\n\n    this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element\n      .on('mouseenter.bs.carousel', $.proxy(this.pause, this))\n      .on('mouseleave.bs.carousel', $.proxy(this.cycle, this))\n  }\n\n  Carousel.VERSION  = '3.3.6'\n\n  Carousel.TRANSITION_DURATION = 600\n\n  Carousel.DEFAULTS = {\n    interval: 5000,\n    pause: 'hover',\n    wrap: true,\n    keyboard: true\n  }\n\n  Carousel.prototype.keydown = function (e) {\n    if (/input|textarea/i.test(e.target.tagName)) return\n    switch (e.which) {\n      case 37: this.prev(); break\n      case 39: this.next(); break\n      default: return\n    }\n\n    e.preventDefault()\n  }\n\n  Carousel.prototype.cycle = function (e) {\n    e || (this.paused = false)\n\n    this.interval && clearInterval(this.interval)\n\n    this.options.interval\n      && !this.paused\n      && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))\n\n    return this\n  }\n\n  Carousel.prototype.getItemIndex = function (item) {\n    this.$items = item.parent().children('.item')\n    return this.$items.index(item || this.$active)\n  }\n\n  Carousel.prototype.getItemForDirection = function (direction, active) {\n    var activeIndex = this.getItemIndex(active)\n    var willWrap = (direction == 'prev' && activeIndex === 0)\n                || (direction == 'next' && activeIndex == (this.$items.length - 1))\n    if (willWrap && !this.options.wrap) return active\n    var delta = direction == 'prev' ? -1 : 1\n    var itemIndex = (activeIndex + delta) % this.$items.length\n    return this.$items.eq(itemIndex)\n  }\n\n  Carousel.prototype.to = function (pos) {\n    var that        = this\n    var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))\n\n    if (pos > (this.$items.length - 1) || pos < 0) return\n\n    if (this.sliding)       return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, \"slid\"\n    if (activeIndex == pos) return this.pause().cycle()\n\n    return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))\n  }\n\n  Carousel.prototype.pause = function (e) {\n    e || (this.paused = true)\n\n    if (this.$element.find('.next, .prev').length && $.support.transition) {\n      this.$element.trigger($.support.transition.end)\n      this.cycle(true)\n    }\n\n    this.interval = clearInterval(this.interval)\n\n    return this\n  }\n\n  Carousel.prototype.next = function () {\n    if (this.sliding) return\n    return this.slide('next')\n  }\n\n  Carousel.prototype.prev = function () {\n    if (this.sliding) return\n    return this.slide('prev')\n  }\n\n  Carousel.prototype.slide = function (type, next) {\n    var $active   = this.$element.find('.item.active')\n    var $next     = next || this.getItemForDirection(type, $active)\n    var isCycling = this.interval\n    var direction = type == 'next' ? 'left' : 'right'\n    var that      = this\n\n    if ($next.hasClass('active')) return (this.sliding = false)\n\n    var relatedTarget = $next[0]\n    var slideEvent = $.Event('slide.bs.carousel', {\n      relatedTarget: relatedTarget,\n      direction: direction\n    })\n    this.$element.trigger(slideEvent)\n    if (slideEvent.isDefaultPrevented()) return\n\n    this.sliding = true\n\n    isCycling && this.pause()\n\n    if (this.$indicators.length) {\n      this.$indicators.find('.active').removeClass('active')\n      var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])\n      $nextIndicator && $nextIndicator.addClass('active')\n    }\n\n    var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, \"slid\"\n    if ($.support.transition && this.$element.hasClass('slide')) {\n      $next.addClass(type)\n      $next[0].offsetWidth // force reflow\n      $active.addClass(direction)\n      $next.addClass(direction)\n      $active\n        .one('bsTransitionEnd', function () {\n          $next.removeClass([type, direction].join(' ')).addClass('active')\n          $active.removeClass(['active', direction].join(' '))\n          that.sliding = false\n          setTimeout(function () {\n            that.$element.trigger(slidEvent)\n          }, 0)\n        })\n        .emulateTransitionEnd(Carousel.TRANSITION_DURATION)\n    } else {\n      $active.removeClass('active')\n      $next.addClass('active')\n      this.sliding = false\n      this.$element.trigger(slidEvent)\n    }\n\n    isCycling && this.cycle()\n\n    return this\n  }\n\n\n  // CAROUSEL PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.carousel')\n      var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)\n      var action  = typeof option == 'string' ? option : options.slide\n\n      if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))\n      if (typeof option == 'number') data.to(option)\n      else if (action) data[action]()\n      else if (options.interval) data.pause().cycle()\n    })\n  }\n\n  var old = $.fn.carousel\n\n  $.fn.carousel             = Plugin\n  $.fn.carousel.Constructor = Carousel\n\n\n  // CAROUSEL NO CONFLICT\n  // ====================\n\n  $.fn.carousel.noConflict = function () {\n    $.fn.carousel = old\n    return this\n  }\n\n\n  // CAROUSEL DATA-API\n  // =================\n\n  var clickHandler = function (e) {\n    var href\n    var $this   = $(this)\n    var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '')) // strip for ie7\n    if (!$target.hasClass('carousel')) return\n    var options = $.extend({}, $target.data(), $this.data())\n    var slideIndex = $this.attr('data-slide-to')\n    if (slideIndex) options.interval = false\n\n    Plugin.call($target, options)\n\n    if (slideIndex) {\n      $target.data('bs.carousel').to(slideIndex)\n    }\n\n    e.preventDefault()\n  }\n\n  $(document)\n    .on('click.bs.carousel.data-api', '[data-slide]', clickHandler)\n    .on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)\n\n  $(window).on('load', function () {\n    $('[data-ride=\"carousel\"]').each(function () {\n      var $carousel = $(this)\n      Plugin.call($carousel, $carousel.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: collapse.js v3.3.6\n * http://getbootstrap.com/javascript/#collapse\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // COLLAPSE PUBLIC CLASS DEFINITION\n  // ================================\n\n  var Collapse = function (element, options) {\n    this.$element      = $(element)\n    this.options       = $.extend({}, Collapse.DEFAULTS, options)\n    this.$trigger      = $('[data-toggle=\"collapse\"][href=\"#' + element.id + '\"],' +\n                           '[data-toggle=\"collapse\"][data-target=\"#' + element.id + '\"]')\n    this.transitioning = null\n\n    if (this.options.parent) {\n      this.$parent = this.getParent()\n    } else {\n      this.addAriaAndCollapsedClass(this.$element, this.$trigger)\n    }\n\n    if (this.options.toggle) this.toggle()\n  }\n\n  Collapse.VERSION  = '3.3.6'\n\n  Collapse.TRANSITION_DURATION = 350\n\n  Collapse.DEFAULTS = {\n    toggle: true\n  }\n\n  Collapse.prototype.dimension = function () {\n    var hasWidth = this.$element.hasClass('width')\n    return hasWidth ? 'width' : 'height'\n  }\n\n  Collapse.prototype.show = function () {\n    if (this.transitioning || this.$element.hasClass('in')) return\n\n    var activesData\n    var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')\n\n    if (actives && actives.length) {\n      activesData = actives.data('bs.collapse')\n      if (activesData && activesData.transitioning) return\n    }\n\n    var startEvent = $.Event('show.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    if (actives && actives.length) {\n      Plugin.call(actives, 'hide')\n      activesData || actives.data('bs.collapse', null)\n    }\n\n    var dimension = this.dimension()\n\n    this.$element\n      .removeClass('collapse')\n      .addClass('collapsing')[dimension](0)\n      .attr('aria-expanded', true)\n\n    this.$trigger\n      .removeClass('collapsed')\n      .attr('aria-expanded', true)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.$element\n        .removeClass('collapsing')\n        .addClass('collapse in')[dimension]('')\n      this.transitioning = 0\n      this.$element\n        .trigger('shown.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    var scrollSize = $.camelCase(['scroll', dimension].join('-'))\n\n    this.$element\n      .one('bsTransitionEnd', $.proxy(complete, this))\n      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])\n  }\n\n  Collapse.prototype.hide = function () {\n    if (this.transitioning || !this.$element.hasClass('in')) return\n\n    var startEvent = $.Event('hide.bs.collapse')\n    this.$element.trigger(startEvent)\n    if (startEvent.isDefaultPrevented()) return\n\n    var dimension = this.dimension()\n\n    this.$element[dimension](this.$element[dimension]())[0].offsetHeight\n\n    this.$element\n      .addClass('collapsing')\n      .removeClass('collapse in')\n      .attr('aria-expanded', false)\n\n    this.$trigger\n      .addClass('collapsed')\n      .attr('aria-expanded', false)\n\n    this.transitioning = 1\n\n    var complete = function () {\n      this.transitioning = 0\n      this.$element\n        .removeClass('collapsing')\n        .addClass('collapse')\n        .trigger('hidden.bs.collapse')\n    }\n\n    if (!$.support.transition) return complete.call(this)\n\n    this.$element\n      [dimension](0)\n      .one('bsTransitionEnd', $.proxy(complete, this))\n      .emulateTransitionEnd(Collapse.TRANSITION_DURATION)\n  }\n\n  Collapse.prototype.toggle = function () {\n    this[this.$element.hasClass('in') ? 'hide' : 'show']()\n  }\n\n  Collapse.prototype.getParent = function () {\n    return $(this.options.parent)\n      .find('[data-toggle=\"collapse\"][data-parent=\"' + this.options.parent + '\"]')\n      .each($.proxy(function (i, element) {\n        var $element = $(element)\n        this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)\n      }, this))\n      .end()\n  }\n\n  Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {\n    var isOpen = $element.hasClass('in')\n\n    $element.attr('aria-expanded', isOpen)\n    $trigger\n      .toggleClass('collapsed', !isOpen)\n      .attr('aria-expanded', isOpen)\n  }\n\n  function getTargetFromTrigger($trigger) {\n    var href\n    var target = $trigger.attr('data-target')\n      || (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\\s]+$)/, '') // strip for ie7\n\n    return $(target)\n  }\n\n\n  // COLLAPSE PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.collapse')\n      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false\n      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.collapse\n\n  $.fn.collapse             = Plugin\n  $.fn.collapse.Constructor = Collapse\n\n\n  // COLLAPSE NO CONFLICT\n  // ====================\n\n  $.fn.collapse.noConflict = function () {\n    $.fn.collapse = old\n    return this\n  }\n\n\n  // COLLAPSE DATA-API\n  // =================\n\n  $(document).on('click.bs.collapse.data-api', '[data-toggle=\"collapse\"]', function (e) {\n    var $this   = $(this)\n\n    if (!$this.attr('data-target')) e.preventDefault()\n\n    var $target = getTargetFromTrigger($this)\n    var data    = $target.data('bs.collapse')\n    var option  = data ? 'toggle' : $this.data()\n\n    Plugin.call($target, option)\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: dropdown.js v3.3.6\n * http://getbootstrap.com/javascript/#dropdowns\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // DROPDOWN CLASS DEFINITION\n  // =========================\n\n  var backdrop = '.dropdown-backdrop'\n  var toggle   = '[data-toggle=\"dropdown\"]'\n  var Dropdown = function (element) {\n    $(element).on('click.bs.dropdown', this.toggle)\n  }\n\n  Dropdown.VERSION = '3.3.6'\n\n  function getParent($this) {\n    var selector = $this.attr('data-target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    var $parent = selector && $(selector)\n\n    return $parent && $parent.length ? $parent : $this.parent()\n  }\n\n  function clearMenus(e) {\n    if (e && e.which === 3) return\n    $(backdrop).remove()\n    $(toggle).each(function () {\n      var $this         = $(this)\n      var $parent       = getParent($this)\n      var relatedTarget = { relatedTarget: this }\n\n      if (!$parent.hasClass('open')) return\n\n      if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return\n\n      $parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))\n\n      if (e.isDefaultPrevented()) return\n\n      $this.attr('aria-expanded', 'false')\n      $parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))\n    })\n  }\n\n  Dropdown.prototype.toggle = function (e) {\n    var $this = $(this)\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    clearMenus()\n\n    if (!isActive) {\n      if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {\n        // if mobile we use a backdrop because click events don't delegate\n        $(document.createElement('div'))\n          .addClass('dropdown-backdrop')\n          .insertAfter($(this))\n          .on('click', clearMenus)\n      }\n\n      var relatedTarget = { relatedTarget: this }\n      $parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))\n\n      if (e.isDefaultPrevented()) return\n\n      $this\n        .trigger('focus')\n        .attr('aria-expanded', 'true')\n\n      $parent\n        .toggleClass('open')\n        .trigger($.Event('shown.bs.dropdown', relatedTarget))\n    }\n\n    return false\n  }\n\n  Dropdown.prototype.keydown = function (e) {\n    if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return\n\n    var $this = $(this)\n\n    e.preventDefault()\n    e.stopPropagation()\n\n    if ($this.is('.disabled, :disabled')) return\n\n    var $parent  = getParent($this)\n    var isActive = $parent.hasClass('open')\n\n    if (!isActive && e.which != 27 || isActive && e.which == 27) {\n      if (e.which == 27) $parent.find(toggle).trigger('focus')\n      return $this.trigger('click')\n    }\n\n    var desc = ' li:not(.disabled):visible a'\n    var $items = $parent.find('.dropdown-menu' + desc)\n\n    if (!$items.length) return\n\n    var index = $items.index(e.target)\n\n    if (e.which == 38 && index > 0)                 index--         // up\n    if (e.which == 40 && index < $items.length - 1) index++         // down\n    if (!~index)                                    index = 0\n\n    $items.eq(index).trigger('focus')\n  }\n\n\n  // DROPDOWN PLUGIN DEFINITION\n  // ==========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.dropdown')\n\n      if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))\n      if (typeof option == 'string') data[option].call($this)\n    })\n  }\n\n  var old = $.fn.dropdown\n\n  $.fn.dropdown             = Plugin\n  $.fn.dropdown.Constructor = Dropdown\n\n\n  // DROPDOWN NO CONFLICT\n  // ====================\n\n  $.fn.dropdown.noConflict = function () {\n    $.fn.dropdown = old\n    return this\n  }\n\n\n  // APPLY TO STANDARD DROPDOWN ELEMENTS\n  // ===================================\n\n  $(document)\n    .on('click.bs.dropdown.data-api', clearMenus)\n    .on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })\n    .on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)\n    .on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)\n    .on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: modal.js v3.3.6\n * http://getbootstrap.com/javascript/#modals\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // MODAL CLASS DEFINITION\n  // ======================\n\n  var Modal = function (element, options) {\n    this.options             = options\n    this.$body               = $(document.body)\n    this.$element            = $(element)\n    this.$dialog             = this.$element.find('.modal-dialog')\n    this.$backdrop           = null\n    this.isShown             = null\n    this.originalBodyPad     = null\n    this.scrollbarWidth      = 0\n    this.ignoreBackdropClick = false\n\n    if (this.options.remote) {\n      this.$element\n        .find('.modal-content')\n        .load(this.options.remote, $.proxy(function () {\n          this.$element.trigger('loaded.bs.modal')\n        }, this))\n    }\n  }\n\n  Modal.VERSION  = '3.3.6'\n\n  Modal.TRANSITION_DURATION = 300\n  Modal.BACKDROP_TRANSITION_DURATION = 150\n\n  Modal.DEFAULTS = {\n    backdrop: true,\n    keyboard: true,\n    show: true\n  }\n\n  Modal.prototype.toggle = function (_relatedTarget) {\n    return this.isShown ? this.hide() : this.show(_relatedTarget)\n  }\n\n  Modal.prototype.show = function (_relatedTarget) {\n    var that = this\n    var e    = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })\n\n    this.$element.trigger(e)\n\n    if (this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = true\n\n    this.checkScrollbar()\n    this.setScrollbar()\n    this.$body.addClass('modal-open')\n\n    this.escape()\n    this.resize()\n\n    this.$element.on('click.dismiss.bs.modal', '[data-dismiss=\"modal\"]', $.proxy(this.hide, this))\n\n    this.$dialog.on('mousedown.dismiss.bs.modal', function () {\n      that.$element.one('mouseup.dismiss.bs.modal', function (e) {\n        if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true\n      })\n    })\n\n    this.backdrop(function () {\n      var transition = $.support.transition && that.$element.hasClass('fade')\n\n      if (!that.$element.parent().length) {\n        that.$element.appendTo(that.$body) // don't move modals dom position\n      }\n\n      that.$element\n        .show()\n        .scrollTop(0)\n\n      that.adjustDialog()\n\n      if (transition) {\n        that.$element[0].offsetWidth // force reflow\n      }\n\n      that.$element.addClass('in')\n\n      that.enforceFocus()\n\n      var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })\n\n      transition ?\n        that.$dialog // wait for modal to slide in\n          .one('bsTransitionEnd', function () {\n            that.$element.trigger('focus').trigger(e)\n          })\n          .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n        that.$element.trigger('focus').trigger(e)\n    })\n  }\n\n  Modal.prototype.hide = function (e) {\n    if (e) e.preventDefault()\n\n    e = $.Event('hide.bs.modal')\n\n    this.$element.trigger(e)\n\n    if (!this.isShown || e.isDefaultPrevented()) return\n\n    this.isShown = false\n\n    this.escape()\n    this.resize()\n\n    $(document).off('focusin.bs.modal')\n\n    this.$element\n      .removeClass('in')\n      .off('click.dismiss.bs.modal')\n      .off('mouseup.dismiss.bs.modal')\n\n    this.$dialog.off('mousedown.dismiss.bs.modal')\n\n    $.support.transition && this.$element.hasClass('fade') ?\n      this.$element\n        .one('bsTransitionEnd', $.proxy(this.hideModal, this))\n        .emulateTransitionEnd(Modal.TRANSITION_DURATION) :\n      this.hideModal()\n  }\n\n  Modal.prototype.enforceFocus = function () {\n    $(document)\n      .off('focusin.bs.modal') // guard against infinite focus loop\n      .on('focusin.bs.modal', $.proxy(function (e) {\n        if (this.$element[0] !== e.target && !this.$element.has(e.target).length) {\n          this.$element.trigger('focus')\n        }\n      }, this))\n  }\n\n  Modal.prototype.escape = function () {\n    if (this.isShown && this.options.keyboard) {\n      this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {\n        e.which == 27 && this.hide()\n      }, this))\n    } else if (!this.isShown) {\n      this.$element.off('keydown.dismiss.bs.modal')\n    }\n  }\n\n  Modal.prototype.resize = function () {\n    if (this.isShown) {\n      $(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))\n    } else {\n      $(window).off('resize.bs.modal')\n    }\n  }\n\n  Modal.prototype.hideModal = function () {\n    var that = this\n    this.$element.hide()\n    this.backdrop(function () {\n      that.$body.removeClass('modal-open')\n      that.resetAdjustments()\n      that.resetScrollbar()\n      that.$element.trigger('hidden.bs.modal')\n    })\n  }\n\n  Modal.prototype.removeBackdrop = function () {\n    this.$backdrop && this.$backdrop.remove()\n    this.$backdrop = null\n  }\n\n  Modal.prototype.backdrop = function (callback) {\n    var that = this\n    var animate = this.$element.hasClass('fade') ? 'fade' : ''\n\n    if (this.isShown && this.options.backdrop) {\n      var doAnimate = $.support.transition && animate\n\n      this.$backdrop = $(document.createElement('div'))\n        .addClass('modal-backdrop ' + animate)\n        .appendTo(this.$body)\n\n      this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {\n        if (this.ignoreBackdropClick) {\n          this.ignoreBackdropClick = false\n          return\n        }\n        if (e.target !== e.currentTarget) return\n        this.options.backdrop == 'static'\n          ? this.$element[0].focus()\n          : this.hide()\n      }, this))\n\n      if (doAnimate) this.$backdrop[0].offsetWidth // force reflow\n\n      this.$backdrop.addClass('in')\n\n      if (!callback) return\n\n      doAnimate ?\n        this.$backdrop\n          .one('bsTransitionEnd', callback)\n          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n        callback()\n\n    } else if (!this.isShown && this.$backdrop) {\n      this.$backdrop.removeClass('in')\n\n      var callbackRemove = function () {\n        that.removeBackdrop()\n        callback && callback()\n      }\n      $.support.transition && this.$element.hasClass('fade') ?\n        this.$backdrop\n          .one('bsTransitionEnd', callbackRemove)\n          .emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :\n        callbackRemove()\n\n    } else if (callback) {\n      callback()\n    }\n  }\n\n  // these following methods are used to handle overflowing modals\n\n  Modal.prototype.handleUpdate = function () {\n    this.adjustDialog()\n  }\n\n  Modal.prototype.adjustDialog = function () {\n    var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight\n\n    this.$element.css({\n      paddingLeft:  !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',\n      paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''\n    })\n  }\n\n  Modal.prototype.resetAdjustments = function () {\n    this.$element.css({\n      paddingLeft: '',\n      paddingRight: ''\n    })\n  }\n\n  Modal.prototype.checkScrollbar = function () {\n    var fullWindowWidth = window.innerWidth\n    if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8\n      var documentElementRect = document.documentElement.getBoundingClientRect()\n      fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)\n    }\n    this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth\n    this.scrollbarWidth = this.measureScrollbar()\n  }\n\n  Modal.prototype.setScrollbar = function () {\n    var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)\n    this.originalBodyPad = document.body.style.paddingRight || ''\n    if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)\n  }\n\n  Modal.prototype.resetScrollbar = function () {\n    this.$body.css('padding-right', this.originalBodyPad)\n  }\n\n  Modal.prototype.measureScrollbar = function () { // thx walsh\n    var scrollDiv = document.createElement('div')\n    scrollDiv.className = 'modal-scrollbar-measure'\n    this.$body.append(scrollDiv)\n    var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth\n    this.$body[0].removeChild(scrollDiv)\n    return scrollbarWidth\n  }\n\n\n  // MODAL PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option, _relatedTarget) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.modal')\n      var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)\n\n      if (!data) $this.data('bs.modal', (data = new Modal(this, options)))\n      if (typeof option == 'string') data[option](_relatedTarget)\n      else if (options.show) data.show(_relatedTarget)\n    })\n  }\n\n  var old = $.fn.modal\n\n  $.fn.modal             = Plugin\n  $.fn.modal.Constructor = Modal\n\n\n  // MODAL NO CONFLICT\n  // =================\n\n  $.fn.modal.noConflict = function () {\n    $.fn.modal = old\n    return this\n  }\n\n\n  // MODAL DATA-API\n  // ==============\n\n  $(document).on('click.bs.modal.data-api', '[data-toggle=\"modal\"]', function (e) {\n    var $this   = $(this)\n    var href    = $this.attr('href')\n    var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\\s]+$)/, ''))) // strip for ie7\n    var option  = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())\n\n    if ($this.is('a')) e.preventDefault()\n\n    $target.one('show.bs.modal', function (showEvent) {\n      if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown\n      $target.one('hidden.bs.modal', function () {\n        $this.is(':visible') && $this.trigger('focus')\n      })\n    })\n    Plugin.call($target, option, this)\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tooltip.js v3.3.6\n * http://getbootstrap.com/javascript/#tooltip\n * Inspired by the original jQuery.tipsy by Jason Frame\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // TOOLTIP PUBLIC CLASS DEFINITION\n  // ===============================\n\n  var Tooltip = function (element, options) {\n    this.type       = null\n    this.options    = null\n    this.enabled    = null\n    this.timeout    = null\n    this.hoverState = null\n    this.$element   = null\n    this.inState    = null\n\n    this.init('tooltip', element, options)\n  }\n\n  Tooltip.VERSION  = '3.3.6'\n\n  Tooltip.TRANSITION_DURATION = 150\n\n  Tooltip.DEFAULTS = {\n    animation: true,\n    placement: 'top',\n    selector: false,\n    template: '<div class=\"tooltip\" role=\"tooltip\"><div class=\"tooltip-arrow\"></div><div class=\"tooltip-inner\"></div></div>',\n    trigger: 'hover focus',\n    title: '',\n    delay: 0,\n    html: false,\n    container: false,\n    viewport: {\n      selector: 'body',\n      padding: 0\n    }\n  }\n\n  Tooltip.prototype.init = function (type, element, options) {\n    this.enabled   = true\n    this.type      = type\n    this.$element  = $(element)\n    this.options   = this.getOptions(options)\n    this.$viewport = this.options.viewport && $($.isFunction(this.options.viewport) ? this.options.viewport.call(this, this.$element) : (this.options.viewport.selector || this.options.viewport))\n    this.inState   = { click: false, hover: false, focus: false }\n\n    if (this.$element[0] instanceof document.constructor && !this.options.selector) {\n      throw new Error('`selector` option must be specified when initializing ' + this.type + ' on the window.document object!')\n    }\n\n    var triggers = this.options.trigger.split(' ')\n\n    for (var i = triggers.length; i--;) {\n      var trigger = triggers[i]\n\n      if (trigger == 'click') {\n        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))\n      } else if (trigger != 'manual') {\n        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'\n        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'\n\n        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))\n        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))\n      }\n    }\n\n    this.options.selector ?\n      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :\n      this.fixTitle()\n  }\n\n  Tooltip.prototype.getDefaults = function () {\n    return Tooltip.DEFAULTS\n  }\n\n  Tooltip.prototype.getOptions = function (options) {\n    options = $.extend({}, this.getDefaults(), this.$element.data(), options)\n\n    if (options.delay && typeof options.delay == 'number') {\n      options.delay = {\n        show: options.delay,\n        hide: options.delay\n      }\n    }\n\n    return options\n  }\n\n  Tooltip.prototype.getDelegateOptions = function () {\n    var options  = {}\n    var defaults = this.getDefaults()\n\n    this._options && $.each(this._options, function (key, value) {\n      if (defaults[key] != value) options[key] = value\n    })\n\n    return options\n  }\n\n  Tooltip.prototype.enter = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget).data('bs.' + this.type)\n\n    if (!self) {\n      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n      $(obj.currentTarget).data('bs.' + this.type, self)\n    }\n\n    if (obj instanceof $.Event) {\n      self.inState[obj.type == 'focusin' ? 'focus' : 'hover'] = true\n    }\n\n    if (self.tip().hasClass('in') || self.hoverState == 'in') {\n      self.hoverState = 'in'\n      return\n    }\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'in'\n\n    if (!self.options.delay || !self.options.delay.show) return self.show()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'in') self.show()\n    }, self.options.delay.show)\n  }\n\n  Tooltip.prototype.isInStateTrue = function () {\n    for (var key in this.inState) {\n      if (this.inState[key]) return true\n    }\n\n    return false\n  }\n\n  Tooltip.prototype.leave = function (obj) {\n    var self = obj instanceof this.constructor ?\n      obj : $(obj.currentTarget).data('bs.' + this.type)\n\n    if (!self) {\n      self = new this.constructor(obj.currentTarget, this.getDelegateOptions())\n      $(obj.currentTarget).data('bs.' + this.type, self)\n    }\n\n    if (obj instanceof $.Event) {\n      self.inState[obj.type == 'focusout' ? 'focus' : 'hover'] = false\n    }\n\n    if (self.isInStateTrue()) return\n\n    clearTimeout(self.timeout)\n\n    self.hoverState = 'out'\n\n    if (!self.options.delay || !self.options.delay.hide) return self.hide()\n\n    self.timeout = setTimeout(function () {\n      if (self.hoverState == 'out') self.hide()\n    }, self.options.delay.hide)\n  }\n\n  Tooltip.prototype.show = function () {\n    var e = $.Event('show.bs.' + this.type)\n\n    if (this.hasContent() && this.enabled) {\n      this.$element.trigger(e)\n\n      var inDom = $.contains(this.$element[0].ownerDocument.documentElement, this.$element[0])\n      if (e.isDefaultPrevented() || !inDom) return\n      var that = this\n\n      var $tip = this.tip()\n\n      var tipId = this.getUID(this.type)\n\n      this.setContent()\n      $tip.attr('id', tipId)\n      this.$element.attr('aria-describedby', tipId)\n\n      if (this.options.animation) $tip.addClass('fade')\n\n      var placement = typeof this.options.placement == 'function' ?\n        this.options.placement.call(this, $tip[0], this.$element[0]) :\n        this.options.placement\n\n      var autoToken = /\\s?auto?\\s?/i\n      var autoPlace = autoToken.test(placement)\n      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'\n\n      $tip\n        .detach()\n        .css({ top: 0, left: 0, display: 'block' })\n        .addClass(placement)\n        .data('bs.' + this.type, this)\n\n      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)\n      this.$element.trigger('inserted.bs.' + this.type)\n\n      var pos          = this.getPosition()\n      var actualWidth  = $tip[0].offsetWidth\n      var actualHeight = $tip[0].offsetHeight\n\n      if (autoPlace) {\n        var orgPlacement = placement\n        var viewportDim = this.getPosition(this.$viewport)\n\n        placement = placement == 'bottom' && pos.bottom + actualHeight > viewportDim.bottom ? 'top'    :\n                    placement == 'top'    && pos.top    - actualHeight < viewportDim.top    ? 'bottom' :\n                    placement == 'right'  && pos.right  + actualWidth  > viewportDim.width  ? 'left'   :\n                    placement == 'left'   && pos.left   - actualWidth  < viewportDim.left   ? 'right'  :\n                    placement\n\n        $tip\n          .removeClass(orgPlacement)\n          .addClass(placement)\n      }\n\n      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)\n\n      this.applyPlacement(calculatedOffset, placement)\n\n      var complete = function () {\n        var prevHoverState = that.hoverState\n        that.$element.trigger('shown.bs.' + that.type)\n        that.hoverState = null\n\n        if (prevHoverState == 'out') that.leave(that)\n      }\n\n      $.support.transition && this.$tip.hasClass('fade') ?\n        $tip\n          .one('bsTransitionEnd', complete)\n          .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n        complete()\n    }\n  }\n\n  Tooltip.prototype.applyPlacement = function (offset, placement) {\n    var $tip   = this.tip()\n    var width  = $tip[0].offsetWidth\n    var height = $tip[0].offsetHeight\n\n    // manually read margins because getBoundingClientRect includes difference\n    var marginTop = parseInt($tip.css('margin-top'), 10)\n    var marginLeft = parseInt($tip.css('margin-left'), 10)\n\n    // we must check for NaN for ie 8/9\n    if (isNaN(marginTop))  marginTop  = 0\n    if (isNaN(marginLeft)) marginLeft = 0\n\n    offset.top  += marginTop\n    offset.left += marginLeft\n\n    // $.fn.offset doesn't round pixel values\n    // so we use setOffset directly with our own function B-0\n    $.offset.setOffset($tip[0], $.extend({\n      using: function (props) {\n        $tip.css({\n          top: Math.round(props.top),\n          left: Math.round(props.left)\n        })\n      }\n    }, offset), 0)\n\n    $tip.addClass('in')\n\n    // check to see if placing tip in new offset caused the tip to resize itself\n    var actualWidth  = $tip[0].offsetWidth\n    var actualHeight = $tip[0].offsetHeight\n\n    if (placement == 'top' && actualHeight != height) {\n      offset.top = offset.top + height - actualHeight\n    }\n\n    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)\n\n    if (delta.left) offset.left += delta.left\n    else offset.top += delta.top\n\n    var isVertical          = /top|bottom/.test(placement)\n    var arrowDelta          = isVertical ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight\n    var arrowOffsetPosition = isVertical ? 'offsetWidth' : 'offsetHeight'\n\n    $tip.offset(offset)\n    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], isVertical)\n  }\n\n  Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {\n    this.arrow()\n      .css(isVertical ? 'left' : 'top', 50 * (1 - delta / dimension) + '%')\n      .css(isVertical ? 'top' : 'left', '')\n  }\n\n  Tooltip.prototype.setContent = function () {\n    var $tip  = this.tip()\n    var title = this.getTitle()\n\n    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)\n    $tip.removeClass('fade in top bottom left right')\n  }\n\n  Tooltip.prototype.hide = function (callback) {\n    var that = this\n    var $tip = $(this.$tip)\n    var e    = $.Event('hide.bs.' + this.type)\n\n    function complete() {\n      if (that.hoverState != 'in') $tip.detach()\n      that.$element\n        .removeAttr('aria-describedby')\n        .trigger('hidden.bs.' + that.type)\n      callback && callback()\n    }\n\n    this.$element.trigger(e)\n\n    if (e.isDefaultPrevented()) return\n\n    $tip.removeClass('in')\n\n    $.support.transition && $tip.hasClass('fade') ?\n      $tip\n        .one('bsTransitionEnd', complete)\n        .emulateTransitionEnd(Tooltip.TRANSITION_DURATION) :\n      complete()\n\n    this.hoverState = null\n\n    return this\n  }\n\n  Tooltip.prototype.fixTitle = function () {\n    var $e = this.$element\n    if ($e.attr('title') || typeof $e.attr('data-original-title') != 'string') {\n      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')\n    }\n  }\n\n  Tooltip.prototype.hasContent = function () {\n    return this.getTitle()\n  }\n\n  Tooltip.prototype.getPosition = function ($element) {\n    $element   = $element || this.$element\n\n    var el     = $element[0]\n    var isBody = el.tagName == 'BODY'\n\n    var elRect    = el.getBoundingClientRect()\n    if (elRect.width == null) {\n      // width and height are missing in IE8, so compute them manually; see https://github.com/twbs/bootstrap/issues/14093\n      elRect = $.extend({}, elRect, { width: elRect.right - elRect.left, height: elRect.bottom - elRect.top })\n    }\n    var elOffset  = isBody ? { top: 0, left: 0 } : $element.offset()\n    var scroll    = { scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop() }\n    var outerDims = isBody ? { width: $(window).width(), height: $(window).height() } : null\n\n    return $.extend({}, elRect, scroll, outerDims, elOffset)\n  }\n\n  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {\n    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2 } :\n           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2 } :\n           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :\n        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width }\n\n  }\n\n  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {\n    var delta = { top: 0, left: 0 }\n    if (!this.$viewport) return delta\n\n    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0\n    var viewportDimensions = this.getPosition(this.$viewport)\n\n    if (/right|left/.test(placement)) {\n      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll\n      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight\n      if (topEdgeOffset < viewportDimensions.top) { // top overflow\n        delta.top = viewportDimensions.top - topEdgeOffset\n      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow\n        delta.top = viewportDimensions.top + viewportDimensions.height - bottomEdgeOffset\n      }\n    } else {\n      var leftEdgeOffset  = pos.left - viewportPadding\n      var rightEdgeOffset = pos.left + viewportPadding + actualWidth\n      if (leftEdgeOffset < viewportDimensions.left) { // left overflow\n        delta.left = viewportDimensions.left - leftEdgeOffset\n      } else if (rightEdgeOffset > viewportDimensions.right) { // right overflow\n        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset\n      }\n    }\n\n    return delta\n  }\n\n  Tooltip.prototype.getTitle = function () {\n    var title\n    var $e = this.$element\n    var o  = this.options\n\n    title = $e.attr('data-original-title')\n      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)\n\n    return title\n  }\n\n  Tooltip.prototype.getUID = function (prefix) {\n    do prefix += ~~(Math.random() * 1000000)\n    while (document.getElementById(prefix))\n    return prefix\n  }\n\n  Tooltip.prototype.tip = function () {\n    if (!this.$tip) {\n      this.$tip = $(this.options.template)\n      if (this.$tip.length != 1) {\n        throw new Error(this.type + ' `template` option must consist of exactly 1 top-level element!')\n      }\n    }\n    return this.$tip\n  }\n\n  Tooltip.prototype.arrow = function () {\n    return (this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow'))\n  }\n\n  Tooltip.prototype.enable = function () {\n    this.enabled = true\n  }\n\n  Tooltip.prototype.disable = function () {\n    this.enabled = false\n  }\n\n  Tooltip.prototype.toggleEnabled = function () {\n    this.enabled = !this.enabled\n  }\n\n  Tooltip.prototype.toggle = function (e) {\n    var self = this\n    if (e) {\n      self = $(e.currentTarget).data('bs.' + this.type)\n      if (!self) {\n        self = new this.constructor(e.currentTarget, this.getDelegateOptions())\n        $(e.currentTarget).data('bs.' + this.type, self)\n      }\n    }\n\n    if (e) {\n      self.inState.click = !self.inState.click\n      if (self.isInStateTrue()) self.enter(self)\n      else self.leave(self)\n    } else {\n      self.tip().hasClass('in') ? self.leave(self) : self.enter(self)\n    }\n  }\n\n  Tooltip.prototype.destroy = function () {\n    var that = this\n    clearTimeout(this.timeout)\n    this.hide(function () {\n      that.$element.off('.' + that.type).removeData('bs.' + that.type)\n      if (that.$tip) {\n        that.$tip.detach()\n      }\n      that.$tip = null\n      that.$arrow = null\n      that.$viewport = null\n    })\n  }\n\n\n  // TOOLTIP PLUGIN DEFINITION\n  // =========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.tooltip')\n      var options = typeof option == 'object' && option\n\n      if (!data && /destroy|hide/.test(option)) return\n      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.tooltip\n\n  $.fn.tooltip             = Plugin\n  $.fn.tooltip.Constructor = Tooltip\n\n\n  // TOOLTIP NO CONFLICT\n  // ===================\n\n  $.fn.tooltip.noConflict = function () {\n    $.fn.tooltip = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: popover.js v3.3.6\n * http://getbootstrap.com/javascript/#popovers\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // POPOVER PUBLIC CLASS DEFINITION\n  // ===============================\n\n  var Popover = function (element, options) {\n    this.init('popover', element, options)\n  }\n\n  if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')\n\n  Popover.VERSION  = '3.3.6'\n\n  Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {\n    placement: 'right',\n    trigger: 'click',\n    content: '',\n    template: '<div class=\"popover\" role=\"tooltip\"><div class=\"arrow\"></div><h3 class=\"popover-title\"></h3><div class=\"popover-content\"></div></div>'\n  })\n\n\n  // NOTE: POPOVER EXTENDS tooltip.js\n  // ================================\n\n  Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)\n\n  Popover.prototype.constructor = Popover\n\n  Popover.prototype.getDefaults = function () {\n    return Popover.DEFAULTS\n  }\n\n  Popover.prototype.setContent = function () {\n    var $tip    = this.tip()\n    var title   = this.getTitle()\n    var content = this.getContent()\n\n    $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)\n    $tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events\n      this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'\n    ](content)\n\n    $tip.removeClass('fade top bottom left right in')\n\n    // IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do\n    // this manually by checking the contents.\n    if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()\n  }\n\n  Popover.prototype.hasContent = function () {\n    return this.getTitle() || this.getContent()\n  }\n\n  Popover.prototype.getContent = function () {\n    var $e = this.$element\n    var o  = this.options\n\n    return $e.attr('data-content')\n      || (typeof o.content == 'function' ?\n            o.content.call($e[0]) :\n            o.content)\n  }\n\n  Popover.prototype.arrow = function () {\n    return (this.$arrow = this.$arrow || this.tip().find('.arrow'))\n  }\n\n\n  // POPOVER PLUGIN DEFINITION\n  // =========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.popover')\n      var options = typeof option == 'object' && option\n\n      if (!data && /destroy|hide/.test(option)) return\n      if (!data) $this.data('bs.popover', (data = new Popover(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.popover\n\n  $.fn.popover             = Plugin\n  $.fn.popover.Constructor = Popover\n\n\n  // POPOVER NO CONFLICT\n  // ===================\n\n  $.fn.popover.noConflict = function () {\n    $.fn.popover = old\n    return this\n  }\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: scrollspy.js v3.3.6\n * http://getbootstrap.com/javascript/#scrollspy\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // SCROLLSPY CLASS DEFINITION\n  // ==========================\n\n  function ScrollSpy(element, options) {\n    this.$body          = $(document.body)\n    this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)\n    this.options        = $.extend({}, ScrollSpy.DEFAULTS, options)\n    this.selector       = (this.options.target || '') + ' .nav li > a'\n    this.offsets        = []\n    this.targets        = []\n    this.activeTarget   = null\n    this.scrollHeight   = 0\n\n    this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))\n    this.refresh()\n    this.process()\n  }\n\n  ScrollSpy.VERSION  = '3.3.6'\n\n  ScrollSpy.DEFAULTS = {\n    offset: 10\n  }\n\n  ScrollSpy.prototype.getScrollHeight = function () {\n    return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)\n  }\n\n  ScrollSpy.prototype.refresh = function () {\n    var that          = this\n    var offsetMethod  = 'offset'\n    var offsetBase    = 0\n\n    this.offsets      = []\n    this.targets      = []\n    this.scrollHeight = this.getScrollHeight()\n\n    if (!$.isWindow(this.$scrollElement[0])) {\n      offsetMethod = 'position'\n      offsetBase   = this.$scrollElement.scrollTop()\n    }\n\n    this.$body\n      .find(this.selector)\n      .map(function () {\n        var $el   = $(this)\n        var href  = $el.data('target') || $el.attr('href')\n        var $href = /^#./.test(href) && $(href)\n\n        return ($href\n          && $href.length\n          && $href.is(':visible')\n          && [[$href[offsetMethod]().top + offsetBase, href]]) || null\n      })\n      .sort(function (a, b) { return a[0] - b[0] })\n      .each(function () {\n        that.offsets.push(this[0])\n        that.targets.push(this[1])\n      })\n  }\n\n  ScrollSpy.prototype.process = function () {\n    var scrollTop    = this.$scrollElement.scrollTop() + this.options.offset\n    var scrollHeight = this.getScrollHeight()\n    var maxScroll    = this.options.offset + scrollHeight - this.$scrollElement.height()\n    var offsets      = this.offsets\n    var targets      = this.targets\n    var activeTarget = this.activeTarget\n    var i\n\n    if (this.scrollHeight != scrollHeight) {\n      this.refresh()\n    }\n\n    if (scrollTop >= maxScroll) {\n      return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)\n    }\n\n    if (activeTarget && scrollTop < offsets[0]) {\n      this.activeTarget = null\n      return this.clear()\n    }\n\n    for (i = offsets.length; i--;) {\n      activeTarget != targets[i]\n        && scrollTop >= offsets[i]\n        && (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])\n        && this.activate(targets[i])\n    }\n  }\n\n  ScrollSpy.prototype.activate = function (target) {\n    this.activeTarget = target\n\n    this.clear()\n\n    var selector = this.selector +\n      '[data-target=\"' + target + '\"],' +\n      this.selector + '[href=\"' + target + '\"]'\n\n    var active = $(selector)\n      .parents('li')\n      .addClass('active')\n\n    if (active.parent('.dropdown-menu').length) {\n      active = active\n        .closest('li.dropdown')\n        .addClass('active')\n    }\n\n    active.trigger('activate.bs.scrollspy')\n  }\n\n  ScrollSpy.prototype.clear = function () {\n    $(this.selector)\n      .parentsUntil(this.options.target, '.active')\n      .removeClass('active')\n  }\n\n\n  // SCROLLSPY PLUGIN DEFINITION\n  // ===========================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.scrollspy')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.scrollspy\n\n  $.fn.scrollspy             = Plugin\n  $.fn.scrollspy.Constructor = ScrollSpy\n\n\n  // SCROLLSPY NO CONFLICT\n  // =====================\n\n  $.fn.scrollspy.noConflict = function () {\n    $.fn.scrollspy = old\n    return this\n  }\n\n\n  // SCROLLSPY DATA-API\n  // ==================\n\n  $(window).on('load.bs.scrollspy.data-api', function () {\n    $('[data-spy=\"scroll\"]').each(function () {\n      var $spy = $(this)\n      Plugin.call($spy, $spy.data())\n    })\n  })\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: tab.js v3.3.6\n * http://getbootstrap.com/javascript/#tabs\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // TAB CLASS DEFINITION\n  // ====================\n\n  var Tab = function (element) {\n    // jscs:disable requireDollarBeforejQueryAssignment\n    this.element = $(element)\n    // jscs:enable requireDollarBeforejQueryAssignment\n  }\n\n  Tab.VERSION = '3.3.6'\n\n  Tab.TRANSITION_DURATION = 150\n\n  Tab.prototype.show = function () {\n    var $this    = this.element\n    var $ul      = $this.closest('ul:not(.dropdown-menu)')\n    var selector = $this.data('target')\n\n    if (!selector) {\n      selector = $this.attr('href')\n      selector = selector && selector.replace(/.*(?=#[^\\s]*$)/, '') // strip for ie7\n    }\n\n    if ($this.parent('li').hasClass('active')) return\n\n    var $previous = $ul.find('.active:last a')\n    var hideEvent = $.Event('hide.bs.tab', {\n      relatedTarget: $this[0]\n    })\n    var showEvent = $.Event('show.bs.tab', {\n      relatedTarget: $previous[0]\n    })\n\n    $previous.trigger(hideEvent)\n    $this.trigger(showEvent)\n\n    if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) return\n\n    var $target = $(selector)\n\n    this.activate($this.closest('li'), $ul)\n    this.activate($target, $target.parent(), function () {\n      $previous.trigger({\n        type: 'hidden.bs.tab',\n        relatedTarget: $this[0]\n      })\n      $this.trigger({\n        type: 'shown.bs.tab',\n        relatedTarget: $previous[0]\n      })\n    })\n  }\n\n  Tab.prototype.activate = function (element, container, callback) {\n    var $active    = container.find('> .active')\n    var transition = callback\n      && $.support.transition\n      && ($active.length && $active.hasClass('fade') || !!container.find('> .fade').length)\n\n    function next() {\n      $active\n        .removeClass('active')\n        .find('> .dropdown-menu > .active')\n          .removeClass('active')\n        .end()\n        .find('[data-toggle=\"tab\"]')\n          .attr('aria-expanded', false)\n\n      element\n        .addClass('active')\n        .find('[data-toggle=\"tab\"]')\n          .attr('aria-expanded', true)\n\n      if (transition) {\n        element[0].offsetWidth // reflow for transition\n        element.addClass('in')\n      } else {\n        element.removeClass('fade')\n      }\n\n      if (element.parent('.dropdown-menu').length) {\n        element\n          .closest('li.dropdown')\n            .addClass('active')\n          .end()\n          .find('[data-toggle=\"tab\"]')\n            .attr('aria-expanded', true)\n      }\n\n      callback && callback()\n    }\n\n    $active.length && transition ?\n      $active\n        .one('bsTransitionEnd', next)\n        .emulateTransitionEnd(Tab.TRANSITION_DURATION) :\n      next()\n\n    $active.removeClass('in')\n  }\n\n\n  // TAB PLUGIN DEFINITION\n  // =====================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this = $(this)\n      var data  = $this.data('bs.tab')\n\n      if (!data) $this.data('bs.tab', (data = new Tab(this)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.tab\n\n  $.fn.tab             = Plugin\n  $.fn.tab.Constructor = Tab\n\n\n  // TAB NO CONFLICT\n  // ===============\n\n  $.fn.tab.noConflict = function () {\n    $.fn.tab = old\n    return this\n  }\n\n\n  // TAB DATA-API\n  // ============\n\n  var clickHandler = function (e) {\n    e.preventDefault()\n    Plugin.call($(this), 'show')\n  }\n\n  $(document)\n    .on('click.bs.tab.data-api', '[data-toggle=\"tab\"]', clickHandler)\n    .on('click.bs.tab.data-api', '[data-toggle=\"pill\"]', clickHandler)\n\n}(jQuery);\n\n/* ========================================================================\n * Bootstrap: affix.js v3.3.6\n * http://getbootstrap.com/javascript/#affix\n * ========================================================================\n * Copyright 2011-2015 Twitter, Inc.\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)\n * ======================================================================== */\n\n\n+function ($) {\n  'use strict';\n\n  // AFFIX CLASS DEFINITION\n  // ======================\n\n  var Affix = function (element, options) {\n    this.options = $.extend({}, Affix.DEFAULTS, options)\n\n    this.$target = $(this.options.target)\n      .on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))\n      .on('click.bs.affix.data-api',  $.proxy(this.checkPositionWithEventLoop, this))\n\n    this.$element     = $(element)\n    this.affixed      = null\n    this.unpin        = null\n    this.pinnedOffset = null\n\n    this.checkPosition()\n  }\n\n  Affix.VERSION  = '3.3.6'\n\n  Affix.RESET    = 'affix affix-top affix-bottom'\n\n  Affix.DEFAULTS = {\n    offset: 0,\n    target: window\n  }\n\n  Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {\n    var scrollTop    = this.$target.scrollTop()\n    var position     = this.$element.offset()\n    var targetHeight = this.$target.height()\n\n    if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false\n\n    if (this.affixed == 'bottom') {\n      if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'\n      return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'\n    }\n\n    var initializing   = this.affixed == null\n    var colliderTop    = initializing ? scrollTop : position.top\n    var colliderHeight = initializing ? targetHeight : height\n\n    if (offsetTop != null && scrollTop <= offsetTop) return 'top'\n    if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'\n\n    return false\n  }\n\n  Affix.prototype.getPinnedOffset = function () {\n    if (this.pinnedOffset) return this.pinnedOffset\n    this.$element.removeClass(Affix.RESET).addClass('affix')\n    var scrollTop = this.$target.scrollTop()\n    var position  = this.$element.offset()\n    return (this.pinnedOffset = position.top - scrollTop)\n  }\n\n  Affix.prototype.checkPositionWithEventLoop = function () {\n    setTimeout($.proxy(this.checkPosition, this), 1)\n  }\n\n  Affix.prototype.checkPosition = function () {\n    if (!this.$element.is(':visible')) return\n\n    var height       = this.$element.height()\n    var offset       = this.options.offset\n    var offsetTop    = offset.top\n    var offsetBottom = offset.bottom\n    var scrollHeight = Math.max($(document).height(), $(document.body).height())\n\n    if (typeof offset != 'object')         offsetBottom = offsetTop = offset\n    if (typeof offsetTop == 'function')    offsetTop    = offset.top(this.$element)\n    if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)\n\n    var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)\n\n    if (this.affixed != affix) {\n      if (this.unpin != null) this.$element.css('top', '')\n\n      var affixType = 'affix' + (affix ? '-' + affix : '')\n      var e         = $.Event(affixType + '.bs.affix')\n\n      this.$element.trigger(e)\n\n      if (e.isDefaultPrevented()) return\n\n      this.affixed = affix\n      this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null\n\n      this.$element\n        .removeClass(Affix.RESET)\n        .addClass(affixType)\n        .trigger(affixType.replace('affix', 'affixed') + '.bs.affix')\n    }\n\n    if (affix == 'bottom') {\n      this.$element.offset({\n        top: scrollHeight - height - offsetBottom\n      })\n    }\n  }\n\n\n  // AFFIX PLUGIN DEFINITION\n  // =======================\n\n  function Plugin(option) {\n    return this.each(function () {\n      var $this   = $(this)\n      var data    = $this.data('bs.affix')\n      var options = typeof option == 'object' && option\n\n      if (!data) $this.data('bs.affix', (data = new Affix(this, options)))\n      if (typeof option == 'string') data[option]()\n    })\n  }\n\n  var old = $.fn.affix\n\n  $.fn.affix             = Plugin\n  $.fn.affix.Constructor = Affix\n\n\n  // AFFIX NO CONFLICT\n  // =================\n\n  $.fn.affix.noConflict = function () {\n    $.fn.affix = old\n    return this\n  }\n\n\n  // AFFIX DATA-API\n  // ==============\n\n  $(window).on('load', function () {\n    $('[data-spy=\"affix\"]').each(function () {\n      var $spy = $(this)\n      var data = $spy.data()\n\n      data.offset = data.offset || {}\n\n      if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom\n      if (data.offsetTop    != null) data.offset.top    = data.offsetTop\n\n      Plugin.call($spy, data)\n    })\n  })\n\n}(jQuery);\n"
  },
  {
    "path": "public/static/plugins/bootstrap/js/npm.js",
    "content": "// This file is autogenerated via the `commonjs` Grunt task. You can require() this file in a CommonJS environment.\nrequire('../../js/transition.js')\nrequire('../../js/alert.js')\nrequire('../../js/button.js')\nrequire('../../js/carousel.js')\nrequire('../../js/collapse.js')\nrequire('../../js/dropdown.js')\nrequire('../../js/modal.js')\nrequire('../../js/tooltip.js')\nrequire('../../js/popover.js')\nrequire('../../js/scrollspy.js')\nrequire('../../js/tab.js')\nrequire('../../js/affix.js')"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/css/bootstrap-datetimepicker.css",
    "content": "/*!\n * Datetimepicker for Bootstrap\n *\n * Copyright 2012 Stefan Petre\n * Improvements by Andrew Rowls\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n */\n.datetimepicker {\n\tpadding: 4px;\n\tmargin-top: 1px;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px;\n\tdirection: ltr;\n}\n\n.datetimepicker-inline {\n\twidth: 220px;\n}\n\n.datetimepicker.datetimepicker-rtl {\n\tdirection: rtl;\n}\n\n.datetimepicker.datetimepicker-rtl table tr td span {\n\tfloat: right;\n}\n\n.datetimepicker-dropdown, .datetimepicker-dropdown-left {\n\ttop: 0;\n\tleft: 0;\n}\n\n[class*=\" datetimepicker-dropdown\"]:before {\n\tcontent: '';\n\tdisplay: inline-block;\n\tborder-left: 7px solid transparent;\n\tborder-right: 7px solid transparent;\n\tborder-bottom: 7px solid #cccccc;\n\tborder-bottom-color: rgba(0, 0, 0, 0.2);\n\tposition: absolute;\n}\n\n[class*=\" datetimepicker-dropdown\"]:after {\n\tcontent: '';\n\tdisplay: inline-block;\n\tborder-left: 6px solid transparent;\n\tborder-right: 6px solid transparent;\n\tborder-bottom: 6px solid #ffffff;\n\tposition: absolute;\n}\n\n[class*=\" datetimepicker-dropdown-top\"]:before {\n\tcontent: '';\n\tdisplay: inline-block;\n\tborder-left: 7px solid transparent;\n\tborder-right: 7px solid transparent;\n\tborder-top: 7px solid #cccccc;\n\tborder-top-color: rgba(0, 0, 0, 0.2);\n\tborder-bottom: 0;\n}\n\n[class*=\" datetimepicker-dropdown-top\"]:after {\n\tcontent: '';\n\tdisplay: inline-block;\n\tborder-left: 6px solid transparent;\n\tborder-right: 6px solid transparent;\n\tborder-top: 6px solid #ffffff;\n\tborder-bottom: 0;\n}\n\n.datetimepicker-dropdown-bottom-left:before {\n\ttop: -7px;\n\tright: 6px;\n}\n\n.datetimepicker-dropdown-bottom-left:after {\n\ttop: -6px;\n\tright: 7px;\n}\n\n.datetimepicker-dropdown-bottom-right:before {\n\ttop: -7px;\n\tleft: 6px;\n}\n\n.datetimepicker-dropdown-bottom-right:after {\n\ttop: -6px;\n\tleft: 7px;\n}\n\n.datetimepicker-dropdown-top-left:before {\n\tbottom: -7px;\n\tright: 6px;\n}\n\n.datetimepicker-dropdown-top-left:after {\n\tbottom: -6px;\n\tright: 7px;\n}\n\n.datetimepicker-dropdown-top-right:before {\n\tbottom: -7px;\n\tleft: 6px;\n}\n\n.datetimepicker-dropdown-top-right:after {\n\tbottom: -6px;\n\tleft: 7px;\n}\n\n.datetimepicker > div {\n\tdisplay: none;\n}\n\n.datetimepicker.minutes div.datetimepicker-minutes {\n\tdisplay: block;\n}\n\n.datetimepicker.hours div.datetimepicker-hours {\n\tdisplay: block;\n}\n\n.datetimepicker.days div.datetimepicker-days {\n\tdisplay: block;\n}\n\n.datetimepicker.months div.datetimepicker-months {\n\tdisplay: block;\n}\n\n.datetimepicker.years div.datetimepicker-years {\n\tdisplay: block;\n}\n\n.datetimepicker table {\n\tmargin: 0;\n}\n\n.datetimepicker  td,\n.datetimepicker th {\n\ttext-align: center;\n\twidth: 20px;\n\theight: 20px;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px;\n\tborder: none;\n}\n\n.table-striped .datetimepicker table tr td,\n.table-striped .datetimepicker table tr th {\n\tbackground-color: transparent;\n}\n\n.datetimepicker table tr td.minute:hover {\n\tbackground: #eeeeee;\n\tcursor: pointer;\n}\n\n.datetimepicker table tr td.hour:hover {\n\tbackground: #eeeeee;\n\tcursor: pointer;\n}\n\n.datetimepicker table tr td.day:hover {\n\tbackground: #eeeeee;\n\tcursor: pointer;\n}\n\n.datetimepicker table tr td.old,\n.datetimepicker table tr td.new {\n\tcolor: #999999;\n}\n\n.datetimepicker table tr td.disabled,\n.datetimepicker table tr td.disabled:hover {\n\tbackground: none;\n\tcolor: #999999;\n\tcursor: default;\n}\n\n.datetimepicker table tr td.today,\n.datetimepicker table tr td.today:hover,\n.datetimepicker table tr td.today.disabled,\n.datetimepicker table tr td.today.disabled:hover {\n\tbackground-color: #fde19a;\n\tbackground-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);\n\tbackground-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);\n\tbackground-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));\n\tbackground-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);\n\tbackground-image: -o-linear-gradient(top, #fdd49a, #fdf59a);\n\tbackground-image: linear-gradient(top, #fdd49a, #fdf59a);\n\tbackground-repeat: repeat-x;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);\n\tborder-color: #fdf59a #fdf59a #fbed50;\n\tborder-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n\tfilter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n}\n\n.datetimepicker table tr td.today:hover,\n.datetimepicker table tr td.today:hover:hover,\n.datetimepicker table tr td.today.disabled:hover,\n.datetimepicker table tr td.today.disabled:hover:hover,\n.datetimepicker table tr td.today:active,\n.datetimepicker table tr td.today:hover:active,\n.datetimepicker table tr td.today.disabled:active,\n.datetimepicker table tr td.today.disabled:hover:active,\n.datetimepicker table tr td.today.active,\n.datetimepicker table tr td.today:hover.active,\n.datetimepicker table tr td.today.disabled.active,\n.datetimepicker table tr td.today.disabled:hover.active,\n.datetimepicker table tr td.today.disabled,\n.datetimepicker table tr td.today:hover.disabled,\n.datetimepicker table tr td.today.disabled.disabled,\n.datetimepicker table tr td.today.disabled:hover.disabled,\n.datetimepicker table tr td.today[disabled],\n.datetimepicker table tr td.today:hover[disabled],\n.datetimepicker table tr td.today.disabled[disabled],\n.datetimepicker table tr td.today.disabled:hover[disabled] {\n\tbackground-color: #fdf59a;\n}\n\n.datetimepicker table tr td.today:active,\n.datetimepicker table tr td.today:hover:active,\n.datetimepicker table tr td.today.disabled:active,\n.datetimepicker table tr td.today.disabled:hover:active,\n.datetimepicker table tr td.today.active,\n.datetimepicker table tr td.today:hover.active,\n.datetimepicker table tr td.today.disabled.active,\n.datetimepicker table tr td.today.disabled:hover.active {\n\tbackground-color: #fbf069;\n}\n\n.datetimepicker table tr td.active,\n.datetimepicker table tr td.active:hover,\n.datetimepicker table tr td.active.disabled,\n.datetimepicker table tr td.active.disabled:hover {\n\tbackground-color: #006dcc;\n\tbackground-image: -moz-linear-gradient(top, #0088cc, #0044cc);\n\tbackground-image: -ms-linear-gradient(top, #0088cc, #0044cc);\n\tbackground-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));\n\tbackground-image: -webkit-linear-gradient(top, #0088cc, #0044cc);\n\tbackground-image: -o-linear-gradient(top, #0088cc, #0044cc);\n\tbackground-image: linear-gradient(top, #0088cc, #0044cc);\n\tbackground-repeat: repeat-x;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);\n\tborder-color: #0044cc #0044cc #002a80;\n\tborder-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n\tfilter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n\tcolor: #ffffff;\n\ttext-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n\n.datetimepicker table tr td.active:hover,\n.datetimepicker table tr td.active:hover:hover,\n.datetimepicker table tr td.active.disabled:hover,\n.datetimepicker table tr td.active.disabled:hover:hover,\n.datetimepicker table tr td.active:active,\n.datetimepicker table tr td.active:hover:active,\n.datetimepicker table tr td.active.disabled:active,\n.datetimepicker table tr td.active.disabled:hover:active,\n.datetimepicker table tr td.active.active,\n.datetimepicker table tr td.active:hover.active,\n.datetimepicker table tr td.active.disabled.active,\n.datetimepicker table tr td.active.disabled:hover.active,\n.datetimepicker table tr td.active.disabled,\n.datetimepicker table tr td.active:hover.disabled,\n.datetimepicker table tr td.active.disabled.disabled,\n.datetimepicker table tr td.active.disabled:hover.disabled,\n.datetimepicker table tr td.active[disabled],\n.datetimepicker table tr td.active:hover[disabled],\n.datetimepicker table tr td.active.disabled[disabled],\n.datetimepicker table tr td.active.disabled:hover[disabled] {\n\tbackground-color: #0044cc;\n}\n\n.datetimepicker table tr td.active:active,\n.datetimepicker table tr td.active:hover:active,\n.datetimepicker table tr td.active.disabled:active,\n.datetimepicker table tr td.active.disabled:hover:active,\n.datetimepicker table tr td.active.active,\n.datetimepicker table tr td.active:hover.active,\n.datetimepicker table tr td.active.disabled.active,\n.datetimepicker table tr td.active.disabled:hover.active {\n\tbackground-color: #003399;\n}\n\n.datetimepicker table tr td span {\n\tdisplay: block;\n\twidth: 23%;\n\theight: 54px;\n\tline-height: 54px;\n\tfloat: left;\n\tmargin: 1%;\n\tcursor: pointer;\n\t-webkit-border-radius: 4px;\n\t-moz-border-radius: 4px;\n\tborder-radius: 4px;\n}\n\n.datetimepicker .datetimepicker-hours span {\n\theight: 26px;\n\tline-height: 26px;\n}\n\n.datetimepicker .datetimepicker-hours table tr td span.hour_am,\n.datetimepicker .datetimepicker-hours table tr td span.hour_pm {\n\twidth: 14.6%;\n}\n\n.datetimepicker .datetimepicker-hours fieldset legend,\n.datetimepicker .datetimepicker-minutes fieldset legend {\n\tmargin-bottom: inherit;\n\tline-height: 30px;\n}\n\n.datetimepicker .datetimepicker-minutes span {\n\theight: 26px;\n\tline-height: 26px;\n}\n\n.datetimepicker table tr td span:hover {\n\tbackground: #eeeeee;\n}\n\n.datetimepicker table tr td span.disabled,\n.datetimepicker table tr td span.disabled:hover {\n\tbackground: none;\n\tcolor: #999999;\n\tcursor: default;\n}\n\n.datetimepicker table tr td span.active,\n.datetimepicker table tr td span.active:hover,\n.datetimepicker table tr td span.active.disabled,\n.datetimepicker table tr td span.active.disabled:hover {\n\tbackground-color: #006dcc;\n\tbackground-image: -moz-linear-gradient(top, #0088cc, #0044cc);\n\tbackground-image: -ms-linear-gradient(top, #0088cc, #0044cc);\n\tbackground-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));\n\tbackground-image: -webkit-linear-gradient(top, #0088cc, #0044cc);\n\tbackground-image: -o-linear-gradient(top, #0088cc, #0044cc);\n\tbackground-image: linear-gradient(top, #0088cc, #0044cc);\n\tbackground-repeat: repeat-x;\n\tfilter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);\n\tborder-color: #0044cc #0044cc #002a80;\n\tborder-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n\tfilter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\n\tcolor: #ffffff;\n\ttext-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n\n.datetimepicker table tr td span.active:hover,\n.datetimepicker table tr td span.active:hover:hover,\n.datetimepicker table tr td span.active.disabled:hover,\n.datetimepicker table tr td span.active.disabled:hover:hover,\n.datetimepicker table tr td span.active:active,\n.datetimepicker table tr td span.active:hover:active,\n.datetimepicker table tr td span.active.disabled:active,\n.datetimepicker table tr td span.active.disabled:hover:active,\n.datetimepicker table tr td span.active.active,\n.datetimepicker table tr td span.active:hover.active,\n.datetimepicker table tr td span.active.disabled.active,\n.datetimepicker table tr td span.active.disabled:hover.active,\n.datetimepicker table tr td span.active.disabled,\n.datetimepicker table tr td span.active:hover.disabled,\n.datetimepicker table tr td span.active.disabled.disabled,\n.datetimepicker table tr td span.active.disabled:hover.disabled,\n.datetimepicker table tr td span.active[disabled],\n.datetimepicker table tr td span.active:hover[disabled],\n.datetimepicker table tr td span.active.disabled[disabled],\n.datetimepicker table tr td span.active.disabled:hover[disabled] {\n\tbackground-color: #0044cc;\n}\n\n.datetimepicker table tr td span.active:active,\n.datetimepicker table tr td span.active:hover:active,\n.datetimepicker table tr td span.active.disabled:active,\n.datetimepicker table tr td span.active.disabled:hover:active,\n.datetimepicker table tr td span.active.active,\n.datetimepicker table tr td span.active:hover.active,\n.datetimepicker table tr td span.active.disabled.active,\n.datetimepicker table tr td span.active.disabled:hover.active {\n\tbackground-color: #003399;\n}\n\n.datetimepicker table tr td span.old {\n\tcolor: #999999;\n}\n\n.datetimepicker th.switch {\n\twidth: 145px;\n}\n\n.datetimepicker th span.glyphicon {\n\tpointer-events: none;\n}\n\n.datetimepicker thead tr:first-child th,\n.datetimepicker tfoot tr:first-child th {\n\tcursor: pointer;\n}\n\n.datetimepicker thead tr:first-child th:hover,\n.datetimepicker tfoot tr:first-child th:hover {\n\tbackground: #eeeeee;\n}\n\n.input-append.date .add-on i,\n.input-prepend.date .add-on i,\n.input-group.date .input-group-addon span {\n\tcursor: pointer;\n\twidth: 14px;\n\theight: 14px;\n}\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/bootstrap-datetimepicker.js",
    "content": "﻿/* =========================================================\n * bootstrap-datetimepicker.js\n * =========================================================\n * Copyright 2012 Stefan Petre\n *\n * Improvements by Andrew Rowls\n * Improvements by Sébastien Malot\n * Improvements by Yun Lai\n * Improvements by Kenneth Henderick\n * Improvements by CuGBabyBeaR\n * Improvements by Christian Vaas\n *\n * Project URL : http://www.malot.fr/bootstrap-datetimepicker\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================= */\n!function ($) {\n\n  // Add ECMA262-5 Array methods if not supported natively (IE8)\n  if (!('indexOf' in Array.prototype)) {\n    Array.prototype.indexOf = function (find, i) {\n      if (i === undefined) i = 0;\n      if (i < 0) i += this.length;\n      if (i < 0) i = 0;\n      for (var n = this.length; i < n; i++) {\n        if (i in this && this[i] === find) {\n          return i;\n        }\n      }\n      return -1;\n    }\n  }\n\n  function elementOrParentIsFixed (element) {\n    var $element = $(element);\n    var $checkElements = $element.add($element.parents());\n    var isFixed = false;\n    $checkElements.each(function(){\n      if ($(this).css('position') === 'fixed') {\n        isFixed = true;\n        return false;\n      }\n    });\n    return isFixed;\n  }\n\n  function UTCDate() {\n    return new Date(Date.UTC.apply(Date, arguments));\n  }\n\n  function UTCToday() {\n    var today = new Date();\n    return UTCDate(today.getUTCFullYear(), today.getUTCMonth(), today.getUTCDate(), today.getUTCHours(), today.getUTCMinutes(), today.getUTCSeconds(), 0);\n  }\n\n  // Picker object\n  var Datetimepicker = function (element, options) {\n    var that = this;\n\n    this.element = $(element);\n\n    // add container for single page application\n    // when page switch the datetimepicker div will be removed also.\n    this.container = options.container || 'body';\n\n    this.language = options.language || this.element.data('date-language') || 'en';\n    this.language = this.language in dates ? this.language : this.language.split('-')[0]; // fr-CA fallback to fr\n    this.language = this.language in dates ? this.language : 'en';\n    this.isRTL = dates[this.language].rtl || false;\n    this.formatType = options.formatType || this.element.data('format-type') || 'standard';\n    this.format = DPGlobal.parseFormat(options.format || this.element.data('date-format') || dates[this.language].format || DPGlobal.getDefaultFormat(this.formatType, 'input'), this.formatType);\n    this.isInline = false;\n    this.isVisible = false;\n    this.isInput = this.element.is('input');\n    this.fontAwesome = options.fontAwesome || this.element.data('font-awesome') || false;\n\n    this.bootcssVer = options.bootcssVer || (this.isInput ? (this.element.is('.form-control') ? 3 : 2) : ( this.bootcssVer = this.element.is('.input-group') ? 3 : 2 ));\n\n    this.component = this.element.is('.date') ? ( this.bootcssVer == 3 ? this.element.find('.input-group-addon .glyphicon-th, .input-group-addon .glyphicon-time, .input-group-addon .glyphicon-calendar, .input-group-addon .glyphicon-calendar, .input-group-addon .fa-calendar, .input-group-addon .fa-clock-o').parent() : this.element.find('.add-on .icon-th, .add-on .icon-time, .add-on .icon-calendar .fa-calendar .fa-clock-o').parent()) : false;\n    this.componentReset = this.element.is('.date') ? ( this.bootcssVer == 3 ? this.element.find('.input-group-addon .glyphicon-remove, .input-group-addon .fa-times').parent():this.element.find('.add-on .icon-remove, .add-on .fa-times').parent()) : false;\n    this.hasInput = this.component && this.element.find('input').length;\n    if (this.component && this.component.length === 0) {\n      this.component = false;\n    }\n    this.linkField = options.linkField || this.element.data('link-field') || false;\n    this.linkFormat = DPGlobal.parseFormat(options.linkFormat || this.element.data('link-format') || DPGlobal.getDefaultFormat(this.formatType, 'link'), this.formatType);\n    this.minuteStep = options.minuteStep || this.element.data('minute-step') || 5;\n    this.pickerPosition = options.pickerPosition || this.element.data('picker-position') || 'bottom-right';\n    this.showMeridian = options.showMeridian || this.element.data('show-meridian') || false;\n    this.initialDate = options.initialDate || new Date();\n    this.zIndex = options.zIndex || this.element.data('z-index') || undefined;\n\n    this.icons = {\n      leftArrow: this.fontAwesome ? 'fa-arrow-left' : (this.bootcssVer === 3 ? 'glyphicon-arrow-left' : 'icon-arrow-left'),\n      rightArrow: this.fontAwesome ? 'fa-arrow-right' : (this.bootcssVer === 3 ? 'glyphicon-arrow-right' : 'icon-arrow-right')\n    }\n    this.icontype = this.fontAwesome ? 'fa' : 'glyphicon';\n\n    this._attachEvents();\n\n    this.clickedOutside = function (e) {\n        // Clicked outside the datetimepicker, hide it\n        if ($(e.target).closest('.datetimepicker').length === 0) {\n            that.hide();\n        }\n    }\n\n    this.formatViewType = 'datetime';\n    if ('formatViewType' in options) {\n      this.formatViewType = options.formatViewType;\n    } else if ('formatViewType' in this.element.data()) {\n      this.formatViewType = this.element.data('formatViewType');\n    }\n\n    this.minView = 0;\n    if ('minView' in options) {\n      this.minView = options.minView;\n    } else if ('minView' in this.element.data()) {\n      this.minView = this.element.data('min-view');\n    }\n    this.minView = DPGlobal.convertViewMode(this.minView);\n\n    this.maxView = DPGlobal.modes.length - 1;\n    if ('maxView' in options) {\n      this.maxView = options.maxView;\n    } else if ('maxView' in this.element.data()) {\n      this.maxView = this.element.data('max-view');\n    }\n    this.maxView = DPGlobal.convertViewMode(this.maxView);\n\n    this.wheelViewModeNavigation = false;\n    if ('wheelViewModeNavigation' in options) {\n      this.wheelViewModeNavigation = options.wheelViewModeNavigation;\n    } else if ('wheelViewModeNavigation' in this.element.data()) {\n      this.wheelViewModeNavigation = this.element.data('view-mode-wheel-navigation');\n    }\n\n    this.wheelViewModeNavigationInverseDirection = false;\n\n    if ('wheelViewModeNavigationInverseDirection' in options) {\n      this.wheelViewModeNavigationInverseDirection = options.wheelViewModeNavigationInverseDirection;\n    } else if ('wheelViewModeNavigationInverseDirection' in this.element.data()) {\n      this.wheelViewModeNavigationInverseDirection = this.element.data('view-mode-wheel-navigation-inverse-dir');\n    }\n\n    this.wheelViewModeNavigationDelay = 100;\n    if ('wheelViewModeNavigationDelay' in options) {\n      this.wheelViewModeNavigationDelay = options.wheelViewModeNavigationDelay;\n    } else if ('wheelViewModeNavigationDelay' in this.element.data()) {\n      this.wheelViewModeNavigationDelay = this.element.data('view-mode-wheel-navigation-delay');\n    }\n\n    this.startViewMode = 2;\n    if ('startView' in options) {\n      this.startViewMode = options.startView;\n    } else if ('startView' in this.element.data()) {\n      this.startViewMode = this.element.data('start-view');\n    }\n    this.startViewMode = DPGlobal.convertViewMode(this.startViewMode);\n    this.viewMode = this.startViewMode;\n\n    this.viewSelect = this.minView;\n    if ('viewSelect' in options) {\n      this.viewSelect = options.viewSelect;\n    } else if ('viewSelect' in this.element.data()) {\n      this.viewSelect = this.element.data('view-select');\n    }\n    this.viewSelect = DPGlobal.convertViewMode(this.viewSelect);\n\n    this.forceParse = true;\n    if ('forceParse' in options) {\n      this.forceParse = options.forceParse;\n    } else if ('dateForceParse' in this.element.data()) {\n      this.forceParse = this.element.data('date-force-parse');\n    }\n    var template = this.bootcssVer === 3 ? DPGlobal.templateV3 : DPGlobal.template;\n    while (template.indexOf('{iconType}') !== -1) {\n      template = template.replace('{iconType}', this.icontype);\n    }\n    while (template.indexOf('{leftArrow}') !== -1) {\n      template = template.replace('{leftArrow}', this.icons.leftArrow);\n    }\n    while (template.indexOf('{rightArrow}') !== -1) {\n      template = template.replace('{rightArrow}', this.icons.rightArrow);\n    }\n    this.picker = $(template)\n      .appendTo(this.isInline ? this.element : this.container) // 'body')\n      .on({\n        click:     $.proxy(this.click, this),\n        mousedown: $.proxy(this.mousedown, this)\n      });\n\n    if (this.wheelViewModeNavigation) {\n      if ($.fn.mousewheel) {\n        this.picker.on({mousewheel: $.proxy(this.mousewheel, this)});\n      } else {\n        console.log('Mouse Wheel event is not supported. Please include the jQuery Mouse Wheel plugin before enabling this option');\n      }\n    }\n\n    if (this.isInline) {\n      this.picker.addClass('datetimepicker-inline');\n    } else {\n      this.picker.addClass('datetimepicker-dropdown-' + this.pickerPosition + ' dropdown-menu');\n    }\n    if (this.isRTL) {\n      this.picker.addClass('datetimepicker-rtl');\n      var selector = this.bootcssVer === 3 ? '.prev span, .next span' : '.prev i, .next i';\n      this.picker.find(selector).toggleClass(this.icons.leftArrow + ' ' + this.icons.rightArrow);\n    }\n\n    $(document).on('mousedown', this.clickedOutside);\n\n    this.autoclose = false;\n    if ('autoclose' in options) {\n      this.autoclose = options.autoclose;\n    } else if ('dateAutoclose' in this.element.data()) {\n      this.autoclose = this.element.data('date-autoclose');\n    }\n\n    this.keyboardNavigation = true;\n    if ('keyboardNavigation' in options) {\n      this.keyboardNavigation = options.keyboardNavigation;\n    } else if ('dateKeyboardNavigation' in this.element.data()) {\n      this.keyboardNavigation = this.element.data('date-keyboard-navigation');\n    }\n\n    this.todayBtn = (options.todayBtn || this.element.data('date-today-btn') || false);\n    this.todayHighlight = (options.todayHighlight || this.element.data('date-today-highlight') || false);\n\n    this.weekStart = ((options.weekStart || this.element.data('date-weekstart') || dates[this.language].weekStart || 0) % 7);\n    this.weekEnd = ((this.weekStart + 6) % 7);\n    this.startDate = -Infinity;\n    this.endDate = Infinity;\n    this.daysOfWeekDisabled = [];\n    this.setStartDate(options.startDate || this.element.data('date-startdate'));\n    this.setEndDate(options.endDate || this.element.data('date-enddate'));\n    this.setDaysOfWeekDisabled(options.daysOfWeekDisabled || this.element.data('date-days-of-week-disabled'));\n    this.setMinutesDisabled(options.minutesDisabled || this.element.data('date-minute-disabled'));\n    this.setHoursDisabled(options.hoursDisabled || this.element.data('date-hour-disabled'));\n    this.fillDow();\n    this.fillMonths();\n    this.update();\n    this.showMode();\n\n    if (this.isInline) {\n      this.show();\n    }\n  };\n\n  Datetimepicker.prototype = {\n    constructor: Datetimepicker,\n\n    _events:       [],\n    _attachEvents: function () {\n      this._detachEvents();\n      if (this.isInput) { // single input\n        this._events = [\n          [this.element, {\n            focus:   $.proxy(this.show, this),\n            keyup:   $.proxy(this.update, this),\n            keydown: $.proxy(this.keydown, this)\n          }]\n        ];\n      }\n      else if (this.component && this.hasInput) { // component: input + button\n        this._events = [\n          // For components that are not readonly, allow keyboard nav\n          [this.element.find('input'), {\n            focus:   $.proxy(this.show, this),\n            keyup:   $.proxy(this.update, this),\n            keydown: $.proxy(this.keydown, this)\n          }],\n          [this.component, {\n            click: $.proxy(this.show, this)\n          }]\n        ];\n        if (this.componentReset) {\n          this._events.push([\n            this.componentReset,\n            {click: $.proxy(this.reset, this)}\n          ]);\n        }\n      }\n      else if (this.element.is('div')) {  // inline datetimepicker\n        this.isInline = true;\n      }\n      else {\n        this._events = [\n          [this.element, {\n            click: $.proxy(this.show, this)\n          }]\n        ];\n      }\n      for (var i = 0, el, ev; i < this._events.length; i++) {\n        el = this._events[i][0];\n        ev = this._events[i][1];\n        el.on(ev);\n      }\n    },\n\n    _detachEvents: function () {\n      for (var i = 0, el, ev; i < this._events.length; i++) {\n        el = this._events[i][0];\n        ev = this._events[i][1];\n        el.off(ev);\n      }\n      this._events = [];\n    },\n\n    show: function (e) {\n      this.picker.show();\n      this.height = this.component ? this.component.outerHeight() : this.element.outerHeight();\n      if (this.forceParse) {\n        this.update();\n      }\n      this.place();\n      $(window).on('resize', $.proxy(this.place, this));\n      if (e) {\n        e.stopPropagation();\n        e.preventDefault();\n      }\n      this.isVisible = true;\n      this.element.trigger({\n        type: 'show',\n        date: this.date\n      });\n    },\n\n    hide: function (e) {\n      if (!this.isVisible) return;\n      if (this.isInline) return;\n      this.picker.hide();\n      $(window).off('resize', this.place);\n      this.viewMode = this.startViewMode;\n      this.showMode();\n      if (!this.isInput) {\n        $(document).off('mousedown', this.hide);\n      }\n\n      if (\n        this.forceParse &&\n          (\n            this.isInput && this.element.val() ||\n              this.hasInput && this.element.find('input').val()\n            )\n        )\n        this.setValue();\n      this.isVisible = false;\n      this.element.trigger({\n        type: 'hide',\n        date: this.date\n      });\n    },\n\n    remove: function () {\n      this._detachEvents();\n      $(document).off('mousedown', this.clickedOutside);\n      this.picker.remove();\n      delete this.picker;\n      delete this.element.data().datetimepicker;\n    },\n\n    getDate: function () {\n      var d = this.getUTCDate();\n      return new Date(d.getTime() + (d.getTimezoneOffset() * 60000));\n    },\n\n    getUTCDate: function () {\n      return this.date;\n    },\n\n    setDate: function (d) {\n      this.setUTCDate(new Date(d.getTime() - (d.getTimezoneOffset() * 60000)));\n    },\n\n    setUTCDate: function (d) {\n      if (d >= this.startDate && d <= this.endDate) {\n        this.date = d;\n        this.setValue();\n        this.viewDate = this.date;\n        this.fill();\n      } else {\n        this.element.trigger({\n          type:      'outOfRange',\n          date:      d,\n          startDate: this.startDate,\n          endDate:   this.endDate\n        });\n      }\n    },\n\n    setFormat: function (format) {\n      this.format = DPGlobal.parseFormat(format, this.formatType);\n      var element;\n      if (this.isInput) {\n        element = this.element;\n      } else if (this.component) {\n        element = this.element.find('input');\n      }\n      if (element && element.val()) {\n        this.setValue();\n      }\n    },\n\n    setValue: function () {\n      var formatted = this.getFormattedDate();\n      if (!this.isInput) {\n        if (this.component) {\n          this.element.find('input').val(formatted);\n        }\n        this.element.data('date', formatted);\n      } else {\n        this.element.val(formatted);\n      }\n      if (this.linkField) {\n        $('#' + this.linkField).val(this.getFormattedDate(this.linkFormat));\n      }\n    },\n\n    getFormattedDate: function (format) {\n      if (format == undefined) format = this.format;\n      return DPGlobal.formatDate(this.date, format, this.language, this.formatType);\n    },\n\n    setStartDate: function (startDate) {\n      this.startDate = startDate || -Infinity;\n      if (this.startDate !== -Infinity) {\n        this.startDate = DPGlobal.parseDate(this.startDate, this.format, this.language, this.formatType);\n      }\n      this.update();\n      this.updateNavArrows();\n    },\n\n    setEndDate: function (endDate) {\n      this.endDate = endDate || Infinity;\n      if (this.endDate !== Infinity) {\n        this.endDate = DPGlobal.parseDate(this.endDate, this.format, this.language, this.formatType);\n      }\n      this.update();\n      this.updateNavArrows();\n    },\n\n    setDaysOfWeekDisabled: function (daysOfWeekDisabled) {\n      this.daysOfWeekDisabled = daysOfWeekDisabled || [];\n      if (!$.isArray(this.daysOfWeekDisabled)) {\n        this.daysOfWeekDisabled = this.daysOfWeekDisabled.split(/,\\s*/);\n      }\n      this.daysOfWeekDisabled = $.map(this.daysOfWeekDisabled, function (d) {\n        return parseInt(d, 10);\n      });\n      this.update();\n      this.updateNavArrows();\n    },\n\n    setMinutesDisabled: function (minutesDisabled) {\n      this.minutesDisabled = minutesDisabled || [];\n      if (!$.isArray(this.minutesDisabled)) {\n        this.minutesDisabled = this.minutesDisabled.split(/,\\s*/);\n      }\n      this.minutesDisabled = $.map(this.minutesDisabled, function (d) {\n        return parseInt(d, 10);\n      });\n      this.update();\n      this.updateNavArrows();\n    },\n\n    setHoursDisabled: function (hoursDisabled) {\n      this.hoursDisabled = hoursDisabled || [];\n      if (!$.isArray(this.hoursDisabled)) {\n        this.hoursDisabled = this.hoursDisabled.split(/,\\s*/);\n      }\n      this.hoursDisabled = $.map(this.hoursDisabled, function (d) {\n        return parseInt(d, 10);\n      });\n      this.update();\n      this.updateNavArrows();\n    },\n\n    place: function () {\n      if (this.isInline) return;\n\n      if (!this.zIndex) {\n        var index_highest = 0;\n        $('div').each(function () {\n          var index_current = parseInt($(this).css('zIndex'), 10);\n          if (index_current > index_highest) {\n            index_highest = index_current;\n          }\n        });\n        this.zIndex = index_highest + 10;\n      }\n\n      var offset, top, left, containerOffset;\n      if (this.container instanceof $) {\n        containerOffset = this.container.offset();\n      } else {\n        containerOffset = $(this.container).offset();\n      }\n\n      if (this.component) {\n        offset = this.component.offset();\n        left = offset.left;\n        if (this.pickerPosition == 'bottom-left' || this.pickerPosition == 'top-left') {\n          left += this.component.outerWidth() - this.picker.outerWidth();\n        }\n      } else {\n        offset = this.element.offset();\n        left = offset.left;\n      }\n\n      var bodyWidth = document.body.clientWidth || window.innerWidth;\n      if (left + 220 > bodyWidth) {\n        left = bodyWidth - 220;\n      }\n\n      if (this.pickerPosition == 'top-left' || this.pickerPosition == 'top-right') {\n        top = offset.top - this.picker.outerHeight();\n      } else {\n        top = offset.top + this.height;\n      }\n\n      top = top - containerOffset.top;\n      left = left - containerOffset.left;\n\n      this.picker.css({\n        top:    top,\n        left:   left,\n        zIndex: this.zIndex\n      });\n    },\n\n    update: function () {\n      var date, fromArgs = false;\n      if (arguments && arguments.length && (typeof arguments[0] === 'string' || arguments[0] instanceof Date)) {\n        date = arguments[0];\n        fromArgs = true;\n      } else {\n        date = (this.isInput ? this.element.val() : this.element.find('input').val()) || this.element.data('date') || this.initialDate;\n        if (typeof date == 'string' || date instanceof String) {\n          date = date.replace(/^\\s+|\\s+$/g,'');\n        }\n      }\n\n      if (!date) {\n        date = new Date();\n        fromArgs = false;\n      }\n\n      this.date = DPGlobal.parseDate(date, this.format, this.language, this.formatType);\n\n      if (fromArgs) this.setValue();\n\n      if (this.date < this.startDate) {\n        this.viewDate = new Date(this.startDate);\n      } else if (this.date > this.endDate) {\n        this.viewDate = new Date(this.endDate);\n      } else {\n        this.viewDate = new Date(this.date);\n      }\n      this.fill();\n    },\n\n    fillDow: function () {\n      var dowCnt = this.weekStart,\n        html = '<tr>';\n      while (dowCnt < this.weekStart + 7) {\n        html += '<th class=\"dow\">' + dates[this.language].daysMin[(dowCnt++) % 7] + '</th>';\n      }\n      html += '</tr>';\n      this.picker.find('.datetimepicker-days thead').append(html);\n    },\n\n    fillMonths: function () {\n      var html = '',\n        i = 0;\n      while (i < 12) {\n        html += '<span class=\"month\">' + dates[this.language].monthsShort[i++] + '</span>';\n      }\n      this.picker.find('.datetimepicker-months td').html(html);\n    },\n\n    fill: function () {\n      if (this.date == null || this.viewDate == null) {\n        return;\n      }\n      var d = new Date(this.viewDate),\n        year = d.getUTCFullYear(),\n        month = d.getUTCMonth(),\n        dayMonth = d.getUTCDate(),\n        hours = d.getUTCHours(),\n        minutes = d.getUTCMinutes(),\n        startYear = this.startDate !== -Infinity ? this.startDate.getUTCFullYear() : -Infinity,\n        startMonth = this.startDate !== -Infinity ? this.startDate.getUTCMonth() + 1 : -Infinity,\n        endYear = this.endDate !== Infinity ? this.endDate.getUTCFullYear() : Infinity,\n        endMonth = this.endDate !== Infinity ? this.endDate.getUTCMonth() + 1 : Infinity,\n        currentDate = (new UTCDate(this.date.getUTCFullYear(), this.date.getUTCMonth(), this.date.getUTCDate())).valueOf(),\n        today = new Date();\n      this.picker.find('.datetimepicker-days thead th:eq(1)')\n        .text(dates[this.language].months[month] + ' ' + year);\n      if (this.formatViewType == 'time') {\n        var formatted = this.getFormattedDate();\n        this.picker.find('.datetimepicker-hours thead th:eq(1)').text(formatted);\n        this.picker.find('.datetimepicker-minutes thead th:eq(1)').text(formatted);\n      } else {\n        this.picker.find('.datetimepicker-hours thead th:eq(1)')\n          .text(dayMonth + ' ' + dates[this.language].months[month] + ' ' + year);\n        this.picker.find('.datetimepicker-minutes thead th:eq(1)')\n          .text(dayMonth + ' ' + dates[this.language].months[month] + ' ' + year);\n      }\n      this.picker.find('tfoot th.today')\n        .text(dates[this.language].today)\n        .toggle(this.todayBtn !== false);\n      this.updateNavArrows();\n      this.fillMonths();\n      /*var prevMonth = UTCDate(year, month, 0,0,0,0,0);\n       prevMonth.setUTCDate(prevMonth.getDate() - (prevMonth.getUTCDay() - this.weekStart + 7)%7);*/\n      var prevMonth = UTCDate(year, month - 1, 28, 0, 0, 0, 0),\n        day = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());\n      prevMonth.setUTCDate(day);\n      prevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.weekStart + 7) % 7);\n      var nextMonth = new Date(prevMonth);\n      nextMonth.setUTCDate(nextMonth.getUTCDate() + 42);\n      nextMonth = nextMonth.valueOf();\n      var html = [];\n      var clsName;\n      while (prevMonth.valueOf() < nextMonth) {\n        if (prevMonth.getUTCDay() == this.weekStart) {\n          html.push('<tr>');\n        }\n        clsName = '';\n        if (prevMonth.getUTCFullYear() < year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() < month)) {\n          clsName += ' old';\n        } else if (prevMonth.getUTCFullYear() > year || (prevMonth.getUTCFullYear() == year && prevMonth.getUTCMonth() > month)) {\n          clsName += ' new';\n        }\n        // Compare internal UTC date with local today, not UTC today\n        if (this.todayHighlight &&\n          prevMonth.getUTCFullYear() == today.getFullYear() &&\n          prevMonth.getUTCMonth() == today.getMonth() &&\n          prevMonth.getUTCDate() == today.getDate()) {\n          clsName += ' today';\n        }\n        if (prevMonth.valueOf() == currentDate) {\n          clsName += ' active';\n        }\n        if ((prevMonth.valueOf() + 86400000) <= this.startDate || prevMonth.valueOf() > this.endDate ||\n          $.inArray(prevMonth.getUTCDay(), this.daysOfWeekDisabled) !== -1) {\n          clsName += ' disabled';\n        }\n        html.push('<td class=\"day' + clsName + '\">' + prevMonth.getUTCDate() + '</td>');\n        if (prevMonth.getUTCDay() == this.weekEnd) {\n          html.push('</tr>');\n        }\n        prevMonth.setUTCDate(prevMonth.getUTCDate() + 1);\n      }\n      this.picker.find('.datetimepicker-days tbody').empty().append(html.join(''));\n\n      html = [];\n      var txt = '', meridian = '', meridianOld = '';\n      var hoursDisabled = this.hoursDisabled || [];\n      for (var i = 0; i < 24; i++) {\n        if (hoursDisabled.indexOf(i) !== -1) continue;\n        var actual = UTCDate(year, month, dayMonth, i);\n        clsName = '';\n        // We want the previous hour for the startDate\n        if ((actual.valueOf() + 3600000) <= this.startDate || actual.valueOf() > this.endDate) {\n          clsName += ' disabled';\n        } else if (hours == i) {\n          clsName += ' active';\n        }\n        if (this.showMeridian && dates[this.language].meridiem.length == 2) {\n          meridian = (i < 12 ? dates[this.language].meridiem[0] : dates[this.language].meridiem[1]);\n          if (meridian != meridianOld) {\n            if (meridianOld != '') {\n              html.push('</fieldset>');\n            }\n            html.push('<fieldset class=\"hour\"><legend>' + meridian.toUpperCase() + '</legend>');\n          }\n          meridianOld = meridian;\n          txt = (i % 12 ? i % 12 : 12);\n          html.push('<span class=\"hour' + clsName + ' hour_' + (i < 12 ? 'am' : 'pm') + '\">' + txt + '</span>');\n          if (i == 23) {\n            html.push('</fieldset>');\n          }\n        } else {\n          txt = i + ':00';\n          html.push('<span class=\"hour' + clsName + '\">' + txt + '</span>');\n        }\n      }\n      this.picker.find('.datetimepicker-hours td').html(html.join(''));\n\n      html = [];\n      txt = '', meridian = '', meridianOld = '';\n      var minutesDisabled = this.minutesDisabled || [];\n      for (var i = 0; i < 60; i += this.minuteStep) {\n        if (minutesDisabled.indexOf(i) !== -1) continue;\n        var actual = UTCDate(year, month, dayMonth, hours, i, 0);\n        clsName = '';\n        if (actual.valueOf() < this.startDate || actual.valueOf() > this.endDate) {\n          clsName += ' disabled';\n        } else if (Math.floor(minutes / this.minuteStep) == Math.floor(i / this.minuteStep)) {\n          clsName += ' active';\n        }\n        if (this.showMeridian && dates[this.language].meridiem.length == 2) {\n          meridian = (hours < 12 ? dates[this.language].meridiem[0] : dates[this.language].meridiem[1]);\n          if (meridian != meridianOld) {\n            if (meridianOld != '') {\n              html.push('</fieldset>');\n            }\n            html.push('<fieldset class=\"minute\"><legend>' + meridian.toUpperCase() + '</legend>');\n          }\n          meridianOld = meridian;\n          txt = (hours % 12 ? hours % 12 : 12);\n          //html.push('<span class=\"minute'+clsName+' minute_'+(hours<12?'am':'pm')+'\">'+txt+'</span>');\n          html.push('<span class=\"minute' + clsName + '\">' + txt + ':' + (i < 10 ? '0' + i : i) + '</span>');\n          if (i == 59) {\n            html.push('</fieldset>');\n          }\n        } else {\n          txt = i + ':00';\n          //html.push('<span class=\"hour'+clsName+'\">'+txt+'</span>');\n          html.push('<span class=\"minute' + clsName + '\">' + hours + ':' + (i < 10 ? '0' + i : i) + '</span>');\n        }\n      }\n      this.picker.find('.datetimepicker-minutes td').html(html.join(''));\n\n      var currentYear = this.date.getUTCFullYear();\n      var months = this.picker.find('.datetimepicker-months')\n        .find('th:eq(1)')\n        .text(year)\n        .end()\n        .find('span').removeClass('active');\n      if (currentYear == year) {\n        // getUTCMonths() returns 0 based, and we need to select the next one\n                // To cater bootstrap 2 we don't need to select the next one\n                var offset = months.length - 12;\n        months.eq(this.date.getUTCMonth() + offset).addClass('active');\n      }\n      if (year < startYear || year > endYear) {\n        months.addClass('disabled');\n      }\n      if (year == startYear) {\n        months.slice(0, startMonth + 1).addClass('disabled');\n      }\n      if (year == endYear) {\n        months.slice(endMonth).addClass('disabled');\n      }\n\n      html = '';\n      year = parseInt(year / 10, 10) * 10;\n      var yearCont = this.picker.find('.datetimepicker-years')\n        .find('th:eq(1)')\n        .text(year + '-' + (year + 9))\n        .end()\n        .find('td');\n      year -= 1;\n      for (var i = -1; i < 11; i++) {\n        html += '<span class=\"year' + (i == -1 || i == 10 ? ' old' : '') + (currentYear == year ? ' active' : '') + (year < startYear || year > endYear ? ' disabled' : '') + '\">' + year + '</span>';\n        year += 1;\n      }\n      yearCont.html(html);\n      this.place();\n    },\n\n    updateNavArrows: function () {\n      var d = new Date(this.viewDate),\n        year = d.getUTCFullYear(),\n        month = d.getUTCMonth(),\n        day = d.getUTCDate(),\n        hour = d.getUTCHours();\n      switch (this.viewMode) {\n        case 0:\n          if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()\n            && month <= this.startDate.getUTCMonth()\n            && day <= this.startDate.getUTCDate()\n            && hour <= this.startDate.getUTCHours()) {\n            this.picker.find('.prev').css({visibility: 'hidden'});\n          } else {\n            this.picker.find('.prev').css({visibility: 'visible'});\n          }\n          if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()\n            && month >= this.endDate.getUTCMonth()\n            && day >= this.endDate.getUTCDate()\n            && hour >= this.endDate.getUTCHours()) {\n            this.picker.find('.next').css({visibility: 'hidden'});\n          } else {\n            this.picker.find('.next').css({visibility: 'visible'});\n          }\n          break;\n        case 1:\n          if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()\n            && month <= this.startDate.getUTCMonth()\n            && day <= this.startDate.getUTCDate()) {\n            this.picker.find('.prev').css({visibility: 'hidden'});\n          } else {\n            this.picker.find('.prev').css({visibility: 'visible'});\n          }\n          if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()\n            && month >= this.endDate.getUTCMonth()\n            && day >= this.endDate.getUTCDate()) {\n            this.picker.find('.next').css({visibility: 'hidden'});\n          } else {\n            this.picker.find('.next').css({visibility: 'visible'});\n          }\n          break;\n        case 2:\n          if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()\n            && month <= this.startDate.getUTCMonth()) {\n            this.picker.find('.prev').css({visibility: 'hidden'});\n          } else {\n            this.picker.find('.prev').css({visibility: 'visible'});\n          }\n          if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()\n            && month >= this.endDate.getUTCMonth()) {\n            this.picker.find('.next').css({visibility: 'hidden'});\n          } else {\n            this.picker.find('.next').css({visibility: 'visible'});\n          }\n          break;\n        case 3:\n        case 4:\n          if (this.startDate !== -Infinity && year <= this.startDate.getUTCFullYear()) {\n            this.picker.find('.prev').css({visibility: 'hidden'});\n          } else {\n            this.picker.find('.prev').css({visibility: 'visible'});\n          }\n          if (this.endDate !== Infinity && year >= this.endDate.getUTCFullYear()) {\n            this.picker.find('.next').css({visibility: 'hidden'});\n          } else {\n            this.picker.find('.next').css({visibility: 'visible'});\n          }\n          break;\n      }\n    },\n\n    mousewheel: function (e) {\n\n      e.preventDefault();\n      e.stopPropagation();\n\n      if (this.wheelPause) {\n        return;\n      }\n\n      this.wheelPause = true;\n\n      var originalEvent = e.originalEvent;\n\n      var delta = originalEvent.wheelDelta;\n\n      var mode = delta > 0 ? 1 : (delta === 0) ? 0 : -1;\n\n      if (this.wheelViewModeNavigationInverseDirection) {\n        mode = -mode;\n      }\n\n      this.showMode(mode);\n\n      setTimeout($.proxy(function () {\n\n        this.wheelPause = false\n\n      }, this), this.wheelViewModeNavigationDelay);\n\n    },\n\n    click: function (e) {\n      e.stopPropagation();\n      e.preventDefault();\n      var target = $(e.target).closest('span, td, th, legend');\n      if (target.is('.' + this.icontype)) {\n        target = $(target).parent().closest('span, td, th, legend');\n      }\n      if (target.length == 1) {\n        if (target.is('.disabled')) {\n          this.element.trigger({\n            type:      'outOfRange',\n            date:      this.viewDate,\n            startDate: this.startDate,\n            endDate:   this.endDate\n          });\n          return;\n        }\n        switch (target[0].nodeName.toLowerCase()) {\n          case 'th':\n            switch (target[0].className) {\n              case 'switch':\n                this.showMode(1);\n                break;\n              case 'prev':\n              case 'next':\n                var dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className == 'prev' ? -1 : 1);\n                switch (this.viewMode) {\n                  case 0:\n                    this.viewDate = this.moveHour(this.viewDate, dir);\n                    break;\n                  case 1:\n                    this.viewDate = this.moveDate(this.viewDate, dir);\n                    break;\n                  case 2:\n                    this.viewDate = this.moveMonth(this.viewDate, dir);\n                    break;\n                  case 3:\n                  case 4:\n                    this.viewDate = this.moveYear(this.viewDate, dir);\n                    break;\n                }\n                this.fill();\n                this.element.trigger({\n                  type:      target[0].className + ':' + this.convertViewModeText(this.viewMode),\n                  date:      this.viewDate,\n                  startDate: this.startDate,\n                  endDate:   this.endDate\n                });\n                break;\n              case 'today':\n                var date = new Date();\n                date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), 0);\n\n                // Respect startDate and endDate.\n                if (date < this.startDate) date = this.startDate;\n                else if (date > this.endDate) date = this.endDate;\n\n                this.viewMode = this.startViewMode;\n                this.showMode(0);\n                this._setDate(date);\n                this.fill();\n                if (this.autoclose) {\n                  this.hide();\n                }\n                break;\n            }\n            break;\n          case 'span':\n            if (!target.is('.disabled')) {\n              var year = this.viewDate.getUTCFullYear(),\n                month = this.viewDate.getUTCMonth(),\n                day = this.viewDate.getUTCDate(),\n                hours = this.viewDate.getUTCHours(),\n                minutes = this.viewDate.getUTCMinutes(),\n                seconds = this.viewDate.getUTCSeconds();\n\n              if (target.is('.month')) {\n                this.viewDate.setUTCDate(1);\n                month = target.parent().find('span').index(target);\n                day = this.viewDate.getUTCDate();\n                this.viewDate.setUTCMonth(month);\n                this.element.trigger({\n                  type: 'changeMonth',\n                  date: this.viewDate\n                });\n                if (this.viewSelect >= 3) {\n                  this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));\n                }\n              } else if (target.is('.year')) {\n                this.viewDate.setUTCDate(1);\n                year = parseInt(target.text(), 10) || 0;\n                this.viewDate.setUTCFullYear(year);\n                this.element.trigger({\n                  type: 'changeYear',\n                  date: this.viewDate\n                });\n                if (this.viewSelect >= 4) {\n                  this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));\n                }\n              } else if (target.is('.hour')) {\n                hours = parseInt(target.text(), 10) || 0;\n                if (target.hasClass('hour_am') || target.hasClass('hour_pm')) {\n                  if (hours == 12 && target.hasClass('hour_am')) {\n                    hours = 0;\n                  } else if (hours != 12 && target.hasClass('hour_pm')) {\n                    hours += 12;\n                  }\n                }\n                this.viewDate.setUTCHours(hours);\n                this.element.trigger({\n                  type: 'changeHour',\n                  date: this.viewDate\n                });\n                if (this.viewSelect >= 1) {\n                  this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));\n                }\n              } else if (target.is('.minute')) {\n                minutes = parseInt(target.text().substr(target.text().indexOf(':') + 1), 10) || 0;\n                this.viewDate.setUTCMinutes(minutes);\n                this.element.trigger({\n                  type: 'changeMinute',\n                  date: this.viewDate\n                });\n                if (this.viewSelect >= 0) {\n                  this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));\n                }\n              }\n              if (this.viewMode != 0) {\n                var oldViewMode = this.viewMode;\n                this.showMode(-1);\n                this.fill();\n                if (oldViewMode == this.viewMode && this.autoclose) {\n                  this.hide();\n                }\n              } else {\n                this.fill();\n                if (this.autoclose) {\n                  this.hide();\n                }\n              }\n            }\n            break;\n          case 'td':\n            if (target.is('.day') && !target.is('.disabled')) {\n              var day = parseInt(target.text(), 10) || 1;\n              var year = this.viewDate.getUTCFullYear(),\n                month = this.viewDate.getUTCMonth(),\n                hours = this.viewDate.getUTCHours(),\n                minutes = this.viewDate.getUTCMinutes(),\n                seconds = this.viewDate.getUTCSeconds();\n              if (target.is('.old')) {\n                if (month === 0) {\n                  month = 11;\n                  year -= 1;\n                } else {\n                  month -= 1;\n                }\n              } else if (target.is('.new')) {\n                if (month == 11) {\n                  month = 0;\n                  year += 1;\n                } else {\n                  month += 1;\n                }\n              }\n              this.viewDate.setUTCFullYear(year);\n              this.viewDate.setUTCMonth(month, day);\n              this.element.trigger({\n                type: 'changeDay',\n                date: this.viewDate\n              });\n              if (this.viewSelect >= 2) {\n                this._setDate(UTCDate(year, month, day, hours, minutes, seconds, 0));\n              }\n            }\n            var oldViewMode = this.viewMode;\n            this.showMode(-1);\n            this.fill();\n            if (oldViewMode == this.viewMode && this.autoclose) {\n              this.hide();\n            }\n            break;\n        }\n      }\n    },\n\n    _setDate: function (date, which) {\n      if (!which || which == 'date')\n        this.date = date;\n      if (!which || which == 'view')\n        this.viewDate = date;\n      this.fill();\n      this.setValue();\n      var element;\n      if (this.isInput) {\n        element = this.element;\n      } else if (this.component) {\n        element = this.element.find('input');\n      }\n      if (element) {\n        element.change();\n        if (this.autoclose && (!which || which == 'date')) {\n          //this.hide();\n        }\n      }\n      this.element.trigger({\n        type: 'changeDate',\n        date: this.date\n      });\n      if(date == null)\n        this.date = this.viewDate;\n    },\n\n    moveMinute: function (date, dir) {\n      if (!dir) return date;\n      var new_date = new Date(date.valueOf());\n      //dir = dir > 0 ? 1 : -1;\n      new_date.setUTCMinutes(new_date.getUTCMinutes() + (dir * this.minuteStep));\n      return new_date;\n    },\n\n    moveHour: function (date, dir) {\n      if (!dir) return date;\n      var new_date = new Date(date.valueOf());\n      //dir = dir > 0 ? 1 : -1;\n      new_date.setUTCHours(new_date.getUTCHours() + dir);\n      return new_date;\n    },\n\n    moveDate: function (date, dir) {\n      if (!dir) return date;\n      var new_date = new Date(date.valueOf());\n      //dir = dir > 0 ? 1 : -1;\n      new_date.setUTCDate(new_date.getUTCDate() + dir);\n      return new_date;\n    },\n\n    moveMonth: function (date, dir) {\n      if (!dir) return date;\n      var new_date = new Date(date.valueOf()),\n        day = new_date.getUTCDate(),\n        month = new_date.getUTCMonth(),\n        mag = Math.abs(dir),\n        new_month, test;\n      dir = dir > 0 ? 1 : -1;\n      if (mag == 1) {\n        test = dir == -1\n          // If going back one month, make sure month is not current month\n          // (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)\n          ? function () {\n          return new_date.getUTCMonth() == month;\n        }\n          // If going forward one month, make sure month is as expected\n          // (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)\n          : function () {\n          return new_date.getUTCMonth() != new_month;\n        };\n        new_month = month + dir;\n        new_date.setUTCMonth(new_month);\n        // Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11\n        if (new_month < 0 || new_month > 11)\n          new_month = (new_month + 12) % 12;\n      } else {\n        // For magnitudes >1, move one month at a time...\n        for (var i = 0; i < mag; i++)\n          // ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...\n          new_date = this.moveMonth(new_date, dir);\n        // ...then reset the day, keeping it in the new month\n        new_month = new_date.getUTCMonth();\n        new_date.setUTCDate(day);\n        test = function () {\n          return new_month != new_date.getUTCMonth();\n        };\n      }\n      // Common date-resetting loop -- if date is beyond end of month, make it\n      // end of month\n      while (test()) {\n        new_date.setUTCDate(--day);\n        new_date.setUTCMonth(new_month);\n      }\n      return new_date;\n    },\n\n    moveYear: function (date, dir) {\n      return this.moveMonth(date, dir * 12);\n    },\n\n    dateWithinRange: function (date) {\n      return date >= this.startDate && date <= this.endDate;\n    },\n\n    keydown: function (e) {\n      if (this.picker.is(':not(:visible)')) {\n        if (e.keyCode == 27) // allow escape to hide and re-show picker\n          this.show();\n        return;\n      }\n      var dateChanged = false,\n        dir, day, month,\n        newDate, newViewDate;\n      switch (e.keyCode) {\n        case 27: // escape\n          this.hide();\n          e.preventDefault();\n          break;\n        case 37: // left\n        case 39: // right\n          if (!this.keyboardNavigation) break;\n          dir = e.keyCode == 37 ? -1 : 1;\n          viewMode = this.viewMode;\n          if (e.ctrlKey) {\n            viewMode += 2;\n          } else if (e.shiftKey) {\n            viewMode += 1;\n          }\n          if (viewMode == 4) {\n            newDate = this.moveYear(this.date, dir);\n            newViewDate = this.moveYear(this.viewDate, dir);\n          } else if (viewMode == 3) {\n            newDate = this.moveMonth(this.date, dir);\n            newViewDate = this.moveMonth(this.viewDate, dir);\n          } else if (viewMode == 2) {\n            newDate = this.moveDate(this.date, dir);\n            newViewDate = this.moveDate(this.viewDate, dir);\n          } else if (viewMode == 1) {\n            newDate = this.moveHour(this.date, dir);\n            newViewDate = this.moveHour(this.viewDate, dir);\n          } else if (viewMode == 0) {\n            newDate = this.moveMinute(this.date, dir);\n            newViewDate = this.moveMinute(this.viewDate, dir);\n          }\n          if (this.dateWithinRange(newDate)) {\n            this.date = newDate;\n            this.viewDate = newViewDate;\n            this.setValue();\n            this.update();\n            e.preventDefault();\n            dateChanged = true;\n          }\n          break;\n        case 38: // up\n        case 40: // down\n          if (!this.keyboardNavigation) break;\n          dir = e.keyCode == 38 ? -1 : 1;\n          viewMode = this.viewMode;\n          if (e.ctrlKey) {\n            viewMode += 2;\n          } else if (e.shiftKey) {\n            viewMode += 1;\n          }\n          if (viewMode == 4) {\n            newDate = this.moveYear(this.date, dir);\n            newViewDate = this.moveYear(this.viewDate, dir);\n          } else if (viewMode == 3) {\n            newDate = this.moveMonth(this.date, dir);\n            newViewDate = this.moveMonth(this.viewDate, dir);\n          } else if (viewMode == 2) {\n            newDate = this.moveDate(this.date, dir * 7);\n            newViewDate = this.moveDate(this.viewDate, dir * 7);\n          } else if (viewMode == 1) {\n            if (this.showMeridian) {\n              newDate = this.moveHour(this.date, dir * 6);\n              newViewDate = this.moveHour(this.viewDate, dir * 6);\n            } else {\n              newDate = this.moveHour(this.date, dir * 4);\n              newViewDate = this.moveHour(this.viewDate, dir * 4);\n            }\n          } else if (viewMode == 0) {\n            newDate = this.moveMinute(this.date, dir * 4);\n            newViewDate = this.moveMinute(this.viewDate, dir * 4);\n          }\n          if (this.dateWithinRange(newDate)) {\n            this.date = newDate;\n            this.viewDate = newViewDate;\n            this.setValue();\n            this.update();\n            e.preventDefault();\n            dateChanged = true;\n          }\n          break;\n        case 13: // enter\n          if (this.viewMode != 0) {\n            var oldViewMode = this.viewMode;\n            this.showMode(-1);\n            this.fill();\n            if (oldViewMode == this.viewMode && this.autoclose) {\n              this.hide();\n            }\n          } else {\n            this.fill();\n            if (this.autoclose) {\n              this.hide();\n            }\n          }\n          e.preventDefault();\n          break;\n        case 9: // tab\n          this.hide();\n          break;\n      }\n      if (dateChanged) {\n        var element;\n        if (this.isInput) {\n          element = this.element;\n        } else if (this.component) {\n          element = this.element.find('input');\n        }\n        if (element) {\n          element.change();\n        }\n        this.element.trigger({\n          type: 'changeDate',\n          date: this.date\n        });\n      }\n    },\n\n    showMode: function (dir) {\n      if (dir) {\n        var newViewMode = Math.max(0, Math.min(DPGlobal.modes.length - 1, this.viewMode + dir));\n        if (newViewMode >= this.minView && newViewMode <= this.maxView) {\n          this.element.trigger({\n            type:        'changeMode',\n            date:        this.viewDate,\n            oldViewMode: this.viewMode,\n            newViewMode: newViewMode\n          });\n\n          this.viewMode = newViewMode;\n        }\n      }\n      /*\n       vitalets: fixing bug of very special conditions:\n       jquery 1.7.1 + webkit + show inline datetimepicker in bootstrap popover.\n       Method show() does not set display css correctly and datetimepicker is not shown.\n       Changed to .css('display', 'block') solve the problem.\n       See https://github.com/vitalets/x-editable/issues/37\n\n       In jquery 1.7.2+ everything works fine.\n       */\n      //this.picker.find('>div').hide().filter('.datetimepicker-'+DPGlobal.modes[this.viewMode].clsName).show();\n      this.picker.find('>div').hide().filter('.datetimepicker-' + DPGlobal.modes[this.viewMode].clsName).css('display', 'block');\n      this.updateNavArrows();\n    },\n\n    reset: function (e) {\n      this._setDate(null, 'date');\n    },\n\n    convertViewModeText:  function (viewMode) {\n      switch (viewMode) {\n        case 4:\n          return 'decade';\n        case 3:\n          return 'year';\n        case 2:\n          return 'month';\n        case 1:\n          return 'day';\n        case 0:\n          return 'hour';\n      }\n    }\n  };\n\n  var old = $.fn.datetimepicker;\n  $.fn.datetimepicker = function (option) {\n    var args = Array.apply(null, arguments);\n    args.shift();\n    var internal_return;\n    this.each(function () {\n      var $this = $(this),\n        data = $this.data('datetimepicker'),\n        options = typeof option == 'object' && option;\n      if (!data) {\n        $this.data('datetimepicker', (data = new Datetimepicker(this, $.extend({}, $.fn.datetimepicker.defaults, options))));\n      }\n      if (typeof option == 'string' && typeof data[option] == 'function') {\n        internal_return = data[option].apply(data, args);\n        if (internal_return !== undefined) {\n          return false;\n        }\n      }\n    });\n    if (internal_return !== undefined)\n      return internal_return;\n    else\n      return this;\n  };\n\n  $.fn.datetimepicker.defaults = {\n  };\n  $.fn.datetimepicker.Constructor = Datetimepicker;\n  var dates = $.fn.datetimepicker.dates = {\n    en: {\n      days:        ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'],\n      daysShort:   ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'],\n      daysMin:     ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'],\n      months:      ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],\n      monthsShort: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n      meridiem:    ['am', 'pm'],\n      suffix:      ['st', 'nd', 'rd', 'th'],\n      today:       'Today'\n    }\n  };\n\n  var DPGlobal = {\n    modes:            [\n      {\n        clsName: 'minutes',\n        navFnc:  'Hours',\n        navStep: 1\n      },\n      {\n        clsName: 'hours',\n        navFnc:  'Date',\n        navStep: 1\n      },\n      {\n        clsName: 'days',\n        navFnc:  'Month',\n        navStep: 1\n      },\n      {\n        clsName: 'months',\n        navFnc:  'FullYear',\n        navStep: 1\n      },\n      {\n        clsName: 'years',\n        navFnc:  'FullYear',\n        navStep: 10\n      }\n    ],\n    isLeapYear:       function (year) {\n      return (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0))\n    },\n    getDaysInMonth:   function (year, month) {\n      return [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month]\n    },\n    getDefaultFormat: function (type, field) {\n      if (type == 'standard') {\n        if (field == 'input')\n          return 'yyyy-mm-dd hh:ii';\n        else\n          return 'yyyy-mm-dd hh:ii:ss';\n      } else if (type == 'php') {\n        if (field == 'input')\n          return 'Y-m-d H:i';\n        else\n          return 'Y-m-d H:i:s';\n      } else {\n        throw new Error('Invalid format type.');\n      }\n    },\n    validParts: function (type) {\n      if (type == 'standard') {\n        return /hh?|HH?|p|P|ii?|ss?|dd?|DD?|mm?|MM?|yy(?:yy)?/g;\n      } else if (type == 'php') {\n        return /[dDjlNwzFmMnStyYaABgGhHis]/g;\n      } else {\n        throw new Error('Invalid format type.');\n      }\n    },\n    nonpunctuation: /[^ -\\/:-@\\[-`{-~\\t\\n\\rTZ]+/g,\n    parseFormat: function (format, type) {\n      // IE treats \\0 as a string end in inputs (truncating the value),\n      // so it's a bad format delimiter, anyway\n      var separators = format.replace(this.validParts(type), '\\0').split('\\0'),\n        parts = format.match(this.validParts(type));\n      if (!separators || !separators.length || !parts || parts.length == 0) {\n        throw new Error('Invalid date format.');\n      }\n      return {separators: separators, parts: parts};\n    },\n    parseDate: function (date, format, language, type) {\n      if (date instanceof Date) {\n        var dateUTC = new Date(date.valueOf() - date.getTimezoneOffset() * 60000);\n        dateUTC.setMilliseconds(0);\n        return dateUTC;\n      }\n      if (/^\\d{4}\\-\\d{1,2}\\-\\d{1,2}$/.test(date)) {\n        format = this.parseFormat('yyyy-mm-dd', type);\n      }\n      if (/^\\d{4}\\-\\d{1,2}\\-\\d{1,2}[T ]\\d{1,2}\\:\\d{1,2}$/.test(date)) {\n        format = this.parseFormat('yyyy-mm-dd hh:ii', type);\n      }\n      if (/^\\d{4}\\-\\d{1,2}\\-\\d{1,2}[T ]\\d{1,2}\\:\\d{1,2}\\:\\d{1,2}[Z]{0,1}$/.test(date)) {\n        format = this.parseFormat('yyyy-mm-dd hh:ii:ss', type);\n      }\n      if (/^[-+]\\d+[dmwy]([\\s,]+[-+]\\d+[dmwy])*$/.test(date)) {\n        var part_re = /([-+]\\d+)([dmwy])/,\n          parts = date.match(/([-+]\\d+)([dmwy])/g),\n          part, dir;\n        date = new Date();\n        for (var i = 0; i < parts.length; i++) {\n          part = part_re.exec(parts[i]);\n          dir = parseInt(part[1]);\n          switch (part[2]) {\n            case 'd':\n              date.setUTCDate(date.getUTCDate() + dir);\n              break;\n            case 'm':\n              date = Datetimepicker.prototype.moveMonth.call(Datetimepicker.prototype, date, dir);\n              break;\n            case 'w':\n              date.setUTCDate(date.getUTCDate() + dir * 7);\n              break;\n            case 'y':\n              date = Datetimepicker.prototype.moveYear.call(Datetimepicker.prototype, date, dir);\n              break;\n          }\n        }\n        return UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), date.getUTCHours(), date.getUTCMinutes(), date.getUTCSeconds(), 0);\n      }\n      var parts = date && date.toString().match(this.nonpunctuation) || [],\n        date = new Date(0, 0, 0, 0, 0, 0, 0),\n        parsed = {},\n        setters_order = ['hh', 'h', 'ii', 'i', 'ss', 's', 'yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'D', 'DD', 'd', 'dd', 'H', 'HH', 'p', 'P'],\n        setters_map = {\n          hh:   function (d, v) {\n            return d.setUTCHours(v);\n          },\n          h:    function (d, v) {\n            return d.setUTCHours(v);\n          },\n          HH:   function (d, v) {\n            return d.setUTCHours(v == 12 ? 0 : v);\n          },\n          H:    function (d, v) {\n            return d.setUTCHours(v == 12 ? 0 : v);\n          },\n          ii:   function (d, v) {\n            return d.setUTCMinutes(v);\n          },\n          i:    function (d, v) {\n            return d.setUTCMinutes(v);\n          },\n          ss:   function (d, v) {\n            return d.setUTCSeconds(v);\n          },\n          s:    function (d, v) {\n            return d.setUTCSeconds(v);\n          },\n          yyyy: function (d, v) {\n            return d.setUTCFullYear(v);\n          },\n          yy:   function (d, v) {\n            return d.setUTCFullYear(2000 + v);\n          },\n          m:    function (d, v) {\n            v -= 1;\n            while (v < 0) v += 12;\n            v %= 12;\n            d.setUTCMonth(v);\n            while (d.getUTCMonth() != v)\n              if (isNaN(d.getUTCMonth()))\n                return d;\n              else\n                d.setUTCDate(d.getUTCDate() - 1);\n            return d;\n          },\n          d:    function (d, v) {\n            return d.setUTCDate(v);\n          },\n          p:    function (d, v) {\n            return d.setUTCHours(v == 1 ? d.getUTCHours() + 12 : d.getUTCHours());\n          }\n        },\n        val, filtered, part;\n      setters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];\n      setters_map['dd'] = setters_map['d'];\n      setters_map['P'] = setters_map['p'];\n      date = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds());\n      if (parts.length == format.parts.length) {\n        for (var i = 0, cnt = format.parts.length; i < cnt; i++) {\n          val = parseInt(parts[i], 10);\n          part = format.parts[i];\n          if (isNaN(val)) {\n            switch (part) {\n              case 'MM':\n                filtered = $(dates[language].months).filter(function () {\n                  var m = this.slice(0, parts[i].length),\n                    p = parts[i].slice(0, m.length);\n                  return m == p;\n                });\n                val = $.inArray(filtered[0], dates[language].months) + 1;\n                break;\n              case 'M':\n                filtered = $(dates[language].monthsShort).filter(function () {\n                  var m = this.slice(0, parts[i].length),\n                    p = parts[i].slice(0, m.length);\n                  return m.toLowerCase() == p.toLowerCase();\n                });\n                val = $.inArray(filtered[0], dates[language].monthsShort) + 1;\n                break;\n              case 'p':\n              case 'P':\n                val = $.inArray(parts[i].toLowerCase(), dates[language].meridiem);\n                break;\n            }\n          }\n          parsed[part] = val;\n        }\n        for (var i = 0, s; i < setters_order.length; i++) {\n          s = setters_order[i];\n          if (s in parsed && !isNaN(parsed[s]))\n            setters_map[s](date, parsed[s])\n        }\n      }\n      return date;\n    },\n    formatDate:       function (date, format, language, type) {\n      if (date == null) {\n        return '';\n      }\n      var val;\n      if (type == 'standard') {\n        val = {\n          // year\n          yy:   date.getUTCFullYear().toString().substring(2),\n          yyyy: date.getUTCFullYear(),\n          // month\n          m:    date.getUTCMonth() + 1,\n          M:    dates[language].monthsShort[date.getUTCMonth()],\n          MM:   dates[language].months[date.getUTCMonth()],\n          // day\n          d:    date.getUTCDate(),\n          D:    dates[language].daysShort[date.getUTCDay()],\n          DD:   dates[language].days[date.getUTCDay()],\n          p:    (dates[language].meridiem.length == 2 ? dates[language].meridiem[date.getUTCHours() < 12 ? 0 : 1] : ''),\n          // hour\n          h:    date.getUTCHours(),\n          // minute\n          i:    date.getUTCMinutes(),\n          // second\n          s:    date.getUTCSeconds()\n        };\n\n        if (dates[language].meridiem.length == 2) {\n          val.H = (val.h % 12 == 0 ? 12 : val.h % 12);\n        }\n        else {\n          val.H = val.h;\n        }\n        val.HH = (val.H < 10 ? '0' : '') + val.H;\n        val.P = val.p.toUpperCase();\n        val.hh = (val.h < 10 ? '0' : '') + val.h;\n        val.ii = (val.i < 10 ? '0' : '') + val.i;\n        val.ss = (val.s < 10 ? '0' : '') + val.s;\n        val.dd = (val.d < 10 ? '0' : '') + val.d;\n        val.mm = (val.m < 10 ? '0' : '') + val.m;\n      } else if (type == 'php') {\n        // php format\n        val = {\n          // year\n          y: date.getUTCFullYear().toString().substring(2),\n          Y: date.getUTCFullYear(),\n          // month\n          F: dates[language].months[date.getUTCMonth()],\n          M: dates[language].monthsShort[date.getUTCMonth()],\n          n: date.getUTCMonth() + 1,\n          t: DPGlobal.getDaysInMonth(date.getUTCFullYear(), date.getUTCMonth()),\n          // day\n          j: date.getUTCDate(),\n          l: dates[language].days[date.getUTCDay()],\n          D: dates[language].daysShort[date.getUTCDay()],\n          w: date.getUTCDay(), // 0 -> 6\n          N: (date.getUTCDay() == 0 ? 7 : date.getUTCDay()),       // 1 -> 7\n          S: (date.getUTCDate() % 10 <= dates[language].suffix.length ? dates[language].suffix[date.getUTCDate() % 10 - 1] : ''),\n          // hour\n          a: (dates[language].meridiem.length == 2 ? dates[language].meridiem[date.getUTCHours() < 12 ? 0 : 1] : ''),\n          g: (date.getUTCHours() % 12 == 0 ? 12 : date.getUTCHours() % 12),\n          G: date.getUTCHours(),\n          // minute\n          i: date.getUTCMinutes(),\n          // second\n          s: date.getUTCSeconds()\n        };\n        val.m = (val.n < 10 ? '0' : '') + val.n;\n        val.d = (val.j < 10 ? '0' : '') + val.j;\n        val.A = val.a.toString().toUpperCase();\n        val.h = (val.g < 10 ? '0' : '') + val.g;\n        val.H = (val.G < 10 ? '0' : '') + val.G;\n        val.i = (val.i < 10 ? '0' : '') + val.i;\n        val.s = (val.s < 10 ? '0' : '') + val.s;\n      } else {\n        throw new Error('Invalid format type.');\n      }\n      var date = [],\n        seps = $.extend([], format.separators);\n      for (var i = 0, cnt = format.parts.length; i < cnt; i++) {\n        if (seps.length) {\n          date.push(seps.shift());\n        }\n        date.push(val[format.parts[i]]);\n      }\n      if (seps.length) {\n        date.push(seps.shift());\n      }\n      return date.join('');\n    },\n    convertViewMode:  function (viewMode) {\n      switch (viewMode) {\n        case 4:\n        case 'decade':\n          viewMode = 4;\n          break;\n        case 3:\n        case 'year':\n          viewMode = 3;\n          break;\n        case 2:\n        case 'month':\n          viewMode = 2;\n          break;\n        case 1:\n        case 'day':\n          viewMode = 1;\n          break;\n        case 0:\n        case 'hour':\n          viewMode = 0;\n          break;\n      }\n\n      return viewMode;\n    },\n    headTemplate: '<thead>' +\n                '<tr>' +\n                '<th class=\"prev\"><i class=\"{iconType} {leftArrow}\"/></th>' +\n                '<th colspan=\"5\" class=\"switch\"></th>' +\n                '<th class=\"next\"><i class=\"{iconType} {rightArrow}\"/></th>' +\n                '</tr>' +\n      '</thead>',\n    headTemplateV3: '<thead>' +\n                '<tr>' +\n                '<th class=\"prev\"><span class=\"{iconType} {leftArrow}\"></span> </th>' +\n                '<th colspan=\"5\" class=\"switch\"></th>' +\n                '<th class=\"next\"><span class=\"{iconType} {rightArrow}\"></span> </th>' +\n                '</tr>' +\n      '</thead>',\n    contTemplate: '<tbody><tr><td colspan=\"7\"></td></tr></tbody>',\n    footTemplate: '<tfoot><tr><th colspan=\"7\" class=\"today\"></th></tr></tfoot>'\n  };\n  DPGlobal.template = '<div class=\"datetimepicker\">' +\n    '<div class=\"datetimepicker-minutes\">' +\n    '<table class=\" table-condensed\">' +\n    DPGlobal.headTemplate +\n    DPGlobal.contTemplate +\n    DPGlobal.footTemplate +\n    '</table>' +\n    '</div>' +\n    '<div class=\"datetimepicker-hours\">' +\n    '<table class=\" table-condensed\">' +\n    DPGlobal.headTemplate +\n    DPGlobal.contTemplate +\n    DPGlobal.footTemplate +\n    '</table>' +\n    '</div>' +\n    '<div class=\"datetimepicker-days\">' +\n    '<table class=\" table-condensed\">' +\n    DPGlobal.headTemplate +\n    '<tbody></tbody>' +\n    DPGlobal.footTemplate +\n    '</table>' +\n    '</div>' +\n    '<div class=\"datetimepicker-months\">' +\n    '<table class=\"table-condensed\">' +\n    DPGlobal.headTemplate +\n    DPGlobal.contTemplate +\n    DPGlobal.footTemplate +\n    '</table>' +\n    '</div>' +\n    '<div class=\"datetimepicker-years\">' +\n    '<table class=\"table-condensed\">' +\n    DPGlobal.headTemplate +\n    DPGlobal.contTemplate +\n    DPGlobal.footTemplate +\n    '</table>' +\n    '</div>' +\n    '</div>';\n  DPGlobal.templateV3 = '<div class=\"datetimepicker\">' +\n    '<div class=\"datetimepicker-minutes\">' +\n    '<table class=\" table-condensed\">' +\n    DPGlobal.headTemplateV3 +\n    DPGlobal.contTemplate +\n    DPGlobal.footTemplate +\n    '</table>' +\n    '</div>' +\n    '<div class=\"datetimepicker-hours\">' +\n    '<table class=\" table-condensed\">' +\n    DPGlobal.headTemplateV3 +\n    DPGlobal.contTemplate +\n    DPGlobal.footTemplate +\n    '</table>' +\n    '</div>' +\n    '<div class=\"datetimepicker-days\">' +\n    '<table class=\" table-condensed\">' +\n    DPGlobal.headTemplateV3 +\n    '<tbody></tbody>' +\n    DPGlobal.footTemplate +\n    '</table>' +\n    '</div>' +\n    '<div class=\"datetimepicker-months\">' +\n    '<table class=\"table-condensed\">' +\n    DPGlobal.headTemplateV3 +\n    DPGlobal.contTemplate +\n    DPGlobal.footTemplate +\n    '</table>' +\n    '</div>' +\n    '<div class=\"datetimepicker-years\">' +\n    '<table class=\"table-condensed\">' +\n    DPGlobal.headTemplateV3 +\n    DPGlobal.contTemplate +\n    DPGlobal.footTemplate +\n    '</table>' +\n    '</div>' +\n    '</div>';\n  $.fn.datetimepicker.DPGlobal = DPGlobal;\n\n  /* DATETIMEPICKER NO CONFLICT\n   * =================== */\n\n  $.fn.datetimepicker.noConflict = function () {\n    $.fn.datetimepicker = old;\n    return this;\n  };\n\n  /* DATETIMEPICKER DATA-API\n   * ================== */\n\n  $(document).on(\n    'focus.datetimepicker.data-api click.datetimepicker.data-api',\n    '[data-provide=\"datetimepicker\"]',\n    function (e) {\n      var $this = $(this);\n      if ($this.data('datetimepicker')) return;\n      e.preventDefault();\n      // component click requires us to explicitly show it\n      $this.datetimepicker('show');\n    }\n  );\n  $(function () {\n    $('[data-provide=\"datetimepicker-inline\"]').datetimepicker();\n  });\n\n}(window.jQuery);\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.ar.js",
    "content": "/**\n* Arabic translation for bootstrap-datetimepicker\n* Ala' Mohammad <amohammad@birzeit.ecu>\n*/\n;(function($){\n\t$.fn.datetimepicker.dates['ar'] = {\n\t\tdays: [\"الأحد\", \"الاثنين\", \"الثلاثاء\", \"الأربعاء\", \"الخميس\", \"الجمعة\", \"السبت\", \"الأحد\"],\n\t\tdaysShort: [\"أحد\", \"اثنين\", \"ثلاثاء\", \"أربعاء\", \"خميس\", \"جمعة\", \"سبت\", \"أحد\"],\n\t\tdaysMin: [\"أح\", \"إث\", \"ث\", \"أر\", \"خ\", \"ج\", \"س\", \"أح\"],\n\t\tmonths: [\"يناير\", \"فبراير\", \"مارس\", \"أبريل\", \"مايو\", \"يونيو\", \"يوليو\", \"أغسطس\", \"سبتمبر\", \"أكتوبر\", \"نوفمبر\", \"ديسمبر\"],\n\t\tmonthsShort: [\"يناير\", \"فبراير\", \"مارس\", \"أبريل\", \"مايو\", \"يونيو\", \"يوليو\", \"أغسطس\", \"سبتمبر\", \"أكتوبر\", \"نوفمبر\", \"ديسمبر\"],\n\t\ttoday: \"هذا اليوم\",\n\t\tsuffix: [],\n\t\tmeridiem: [],\n\t\trtl: true\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.bg.js",
    "content": "/**\n * Bulgarian translation for bootstrap-datetimepicker\n * Apostol Apostolov <apostol.s.apostolov@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['bg'] = {\n\t\tdays: [\"Неделя\", \"Понеделник\", \"Вторник\", \"Сряда\", \"Четвъртък\", \"Петък\", \"Събота\", \"Неделя\"],\n\t\tdaysShort: [\"Нед\", \"Пон\", \"Вто\", \"Сря\", \"Чет\", \"Пет\", \"Съб\", \"Нед\"],\n\t\tdaysMin: [\"Н\", \"П\", \"В\", \"С\", \"Ч\", \"П\", \"С\", \"Н\"],\n\t\tmonths: [\"Януари\", \"Февруари\", \"Март\", \"Април\", \"Май\", \"Юни\", \"Юли\", \"Август\", \"Септември\", \"Октомври\", \"Ноември\", \"Декември\"],\n\t\tmonthsShort: [\"Ян\", \"Фев\", \"Мар\", \"Апр\", \"Май\", \"Юни\", \"Юли\", \"Авг\", \"Сеп\", \"Окт\", \"Ное\", \"Дек\"],\n\t\ttoday: \"днес\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.ca.js",
    "content": "/**\n * Catalan translation for bootstrap-datetimepicker\n * J. Garcia <jogaco.en@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['ca'] = {\n\t\tdays: [\"Diumenge\", \"Dilluns\", \"Dimarts\", \"Dimecres\", \"Dijous\", \"Divendres\", \"Dissabte\", \"Diumenge\"],\n\t\tdaysShort: [\"Diu\",  \"Dil\", \"Dmt\", \"Dmc\", \"Dij\", \"Div\", \"Dis\", \"Diu\"],\n\t\tdaysMin: [\"dg\", \"dl\", \"dt\", \"dc\", \"dj\", \"dv\", \"ds\", \"dg\"],\n\t\tmonths: [\"Gener\", \"Febrer\", \"Març\", \"Abril\", \"Maig\", \"Juny\", \"Juliol\", \"Agost\", \"Setembre\", \"Octubre\", \"Novembre\", \"Desembre\"],\n\t\tmonthsShort: [\"Gen\", \"Feb\", \"Mar\", \"Abr\", \"Mai\", \"Jun\", \"Jul\", \"Ago\", \"Set\", \"Oct\", \"Nov\", \"Des\"],\n\t\ttoday: \"Avui\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.cs.js",
    "content": "/**\n * Czech translation for bootstrap-datetimepicker\n * Matěj Koubík <matej@koubik.name>\n * Fixes by Michal Remiš <michal.remis@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['cs'] = {\n\t\tdays: [\"Neděle\", \"Pondělí\", \"Úterý\", \"Středa\", \"Čtvrtek\", \"Pátek\", \"Sobota\", \"Neděle\"],\n\t\tdaysShort: [\"Ned\", \"Pon\", \"Úte\", \"Stř\", \"Čtv\", \"Pát\", \"Sob\", \"Ned\"],\n\t\tdaysMin: [\"Ne\", \"Po\", \"Út\", \"St\", \"Čt\", \"Pá\", \"So\", \"Ne\"],\n\t\tmonths: [\"Leden\", \"Únor\", \"Březen\", \"Duben\", \"Květen\", \"Červen\", \"Červenec\", \"Srpen\", \"Září\", \"Říjen\", \"Listopad\", \"Prosinec\"],\n\t\tmonthsShort: [\"Led\", \"Úno\", \"Bře\", \"Dub\", \"Kvě\", \"Čer\", \"Čnc\", \"Srp\", \"Zář\", \"Říj\", \"Lis\", \"Pro\"],\n\t\ttoday: \"Dnes\",\n\t\tsuffix: [],\n\t\tmeridiem: [],\n\t\tweekStart: 1,\n\t\tformat: \"dd.mm.yyyy\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.da.js",
    "content": "/**\n * Danish translation for bootstrap-datetimepicker\n * Christian Pedersen <http://github.com/chripede>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['da'] = {\n\t\tdays: [\"Søndag\", \"Mandag\", \"Tirsdag\", \"Onsdag\", \"Torsdag\", \"Fredag\", \"Lørdag\", \"Søndag\"],\n\t\tdaysShort: [\"Søn\", \"Man\", \"Tir\", \"Ons\", \"Tor\", \"Fre\", \"Lør\", \"Søn\"],\n\t\tdaysMin: [\"Sø\", \"Ma\", \"Ti\", \"On\", \"To\", \"Fr\", \"Lø\", \"Sø\"],\n\t\tmonths: [\"Januar\", \"Februar\", \"Marts\", \"April\", \"Maj\", \"Juni\", \"Juli\", \"August\", \"September\", \"Oktober\", \"November\", \"December\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Maj\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"I Dag\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.de.js",
    "content": "/**\n * German translation for bootstrap-datetimepicker\n * Sam Zurcher <sam@orelias.ch>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['de'] = {\n\t\tdays: [\"Sonntag\", \"Montag\", \"Dienstag\", \"Mittwoch\", \"Donnerstag\", \"Freitag\", \"Samstag\", \"Sonntag\"],\n\t\tdaysShort: [\"Son\", \"Mon\", \"Die\", \"Mit\", \"Don\", \"Fre\", \"Sam\", \"Son\"],\n\t\tdaysMin: [\"So\", \"Mo\", \"Di\", \"Mi\", \"Do\", \"Fr\", \"Sa\", \"So\"],\n\t\tmonths: [\"Januar\", \"Februar\", \"März\", \"April\", \"Mai\", \"Juni\", \"Juli\", \"August\", \"September\", \"Oktober\", \"November\", \"Dezember\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mär\", \"Apr\", \"Mai\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dez\"],\n\t\ttoday: \"Heute\",\n\t\tsuffix: [],\n\t\tmeridiem: [],\n\t\tweekStart: 1,\n\t\tformat: \"dd.mm.yyyy\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.ee.js",
    "content": "/**\n * Estonian translation for bootstrap-datetimepicker\n * Rene Korss <http://rene.korss.ee> \n */\n;(function($){\n\t$.fn.datetimepicker.dates['ee'] = {\n\t\tdays:        \t[\"Pühapäev\", \"Esmaspäev\", \"Teisipäev\", \"Kolmapäev\", \"Neljapäev\", \"Reede\", \"Laupäev\", \"Pühapäev\"],\n\t\tdaysShort:   \t[\"P\", \"E\", \"T\", \"K\", \"N\", \"R\", \"L\", \"P\"],\n\t\tdaysMin:     \t[\"P\", \"E\", \"T\", \"K\", \"N\", \"R\", \"L\", \"P\"],\n\t\tmonths:      \t[\"Jaanuar\", \"Veebruar\", \"Märts\", \"Aprill\", \"Mai\", \"Juuni\", \"Juuli\", \"August\", \"September\", \"Oktoober\", \"November\", \"Detsember\"],\n\t\tmonthsShort: \t[\"Jaan\", \"Veebr\", \"Märts\", \"Apr\", \"Mai\", \"Juuni\", \"Juuli\", \"Aug\", \"Sept\", \"Okt\", \"Nov\", \"Dets\"],\n\t\ttoday:       \t\"Täna\",\n\t\tsuffix:     \t[],\n\t\tmeridiem: \t\t[],\n\t\tweekStart: \t\t1,\n\t\tformat: \t\t\"dd.mm.yyyy hh:ii\"\n\t};\n}(jQuery));"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.el.js",
    "content": "/**\n* Greek translation for bootstrap-datetimepicker\n*/\n;(function($){\n  $.fn.datetimepicker.dates['el'] = {\n\t    days: [\"Κυριακή\", \"Δευτέρα\", \"Τρίτη\", \"Τετάρτη\", \"Πέμπτη\", \"Παρασκευή\", \"Σάββατο\", \"Κυριακή\"],\n\t    daysShort: [\"Κυρ\", \"Δευ\", \"Τρι\", \"Τετ\", \"Πεμ\", \"Παρ\", \"Σαβ\", \"Κυρ\"],\n\t    daysMin: [\"Κυ\", \"Δε\", \"Τρ\", \"Τε\", \"Πε\", \"Πα\", \"Σα\", \"Κυ\"],\n\t    months: [\"Ιανουάριος\", \"Φεβρουάριος\", \"Μάρτιος\", \"Απρίλιος\", \"Μάιος\", \"Ιούνιος\", \"Ιούλιος\", \"Αύγουστος\", \"Σεπτέμβριος\", \"Οκτώβριος\", \"Νοέμβριος\", \"Δεκέμβριος\"],\n\t    monthsShort: [\"Ιαν\", \"Φεβ\", \"Μαρ\", \"Απρ\", \"Μάι\", \"Ιουν\", \"Ιουλ\", \"Αυγ\", \"Σεπ\", \"Οκτ\", \"Νοε\", \"Δεκ\"],\n\t    today: \"Σήμερα\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n  };\n}(jQuery));"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.es.js",
    "content": "/**\n * Spanish translation for bootstrap-datetimepicker\n * Bruno Bonamin <bruno.bonamin@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['es'] = {\n\t\tdays: [\"Domingo\", \"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"],\n\t\tdaysShort: [\"Dom\", \"Lun\", \"Mar\", \"Mié\", \"Jue\", \"Vie\", \"Sáb\", \"Dom\"],\n\t\tdaysMin: [\"Do\", \"Lu\", \"Ma\", \"Mi\", \"Ju\", \"Vi\", \"Sa\", \"Do\"],\n\t\tmonths: [\"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\", \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"],\n\t\tmonthsShort: [\"Ene\", \"Feb\", \"Mar\", \"Abr\", \"May\", \"Jun\", \"Jul\", \"Ago\", \"Sep\", \"Oct\", \"Nov\", \"Dic\"],\n\t\ttoday: \"Hoy\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.fi.js",
    "content": "/**\n * Finnish translation for bootstrap-datetimepicker\n * Jaakko Salonen <https://github.com/jsalonen>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['fi'] = {\n\t\tdays: [\"sunnuntai\", \"maanantai\", \"tiistai\", \"keskiviikko\", \"torstai\", \"perjantai\", \"lauantai\", \"sunnuntai\"],\n\t\tdaysShort: [\"sun\", \"maa\", \"tii\", \"kes\", \"tor\", \"per\", \"lau\", \"sun\"],\n\t\tdaysMin: [\"su\", \"ma\", \"ti\", \"ke\", \"to\", \"pe\", \"la\", \"su\"],\n\t\tmonths: [\"tammikuu\", \"helmikuu\", \"maaliskuu\", \"huhtikuu\", \"toukokuu\", \"kesäkuu\", \"heinäkuu\", \"elokuu\", \"syyskuu\", \"lokakuu\", \"marraskuu\", \"joulukuu\"],\n\t\tmonthsShort: [\"tam\", \"hel\", \"maa\", \"huh\", \"tou\", \"kes\", \"hei\", \"elo\", \"syy\", \"lok\", \"mar\", \"jou\"],\n\t\ttoday: \"tänään\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.fr.js",
    "content": "/**\n * French translation for bootstrap-datetimepicker\n * Nico Mollet <nico.mollet@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['fr'] = {\n\t\tdays: [\"Dimanche\", \"Lundi\", \"Mardi\", \"Mercredi\", \"Jeudi\", \"Vendredi\", \"Samedi\", \"Dimanche\"],\n\t\tdaysShort: [\"Dim\", \"Lun\", \"Mar\", \"Mer\", \"Jeu\", \"Ven\", \"Sam\", \"Dim\"],\n\t\tdaysMin: [\"D\", \"L\", \"Ma\", \"Me\", \"J\", \"V\", \"S\", \"D\"],\n\t\tmonths: [\"Janvier\", \"Février\", \"Mars\", \"Avril\", \"Mai\", \"Juin\", \"Juillet\", \"Août\", \"Septembre\", \"Octobre\", \"Novembre\", \"Décembre\"],\n\t\tmonthsShort: [\"Jan\", \"Fev\", \"Mar\", \"Avr\", \"Mai\", \"Jui\", \"Jul\", \"Aou\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Aujourd'hui\",\n\t\tsuffix: [],\n\t\tmeridiem: [\"am\", \"pm\"],\n\t\tweekStart: 1,\n\t\tformat: \"dd/mm/yyyy hh:ii\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.he.js",
    "content": "/**\n * Hebrew translation for bootstrap-datetimepicker\n * Sagie Maoz <sagie@maoz.info>\n */\n;(function($){\n  $.fn.datetimepicker.dates['he'] = {\n      days: [\"ראשון\", \"שני\", \"שלישי\", \"רביעי\", \"חמישי\", \"שישי\", \"שבת\", \"ראשון\"],\n      daysShort: [\"א\", \"ב\", \"ג\", \"ד\", \"ה\", \"ו\", \"ש\", \"א\"],\n      daysMin: [\"א\", \"ב\", \"ג\", \"ד\", \"ה\", \"ו\", \"ש\", \"א\"],\n      months: [\"ינואר\", \"פברואר\", \"מרץ\", \"אפריל\", \"מאי\", \"יוני\", \"יולי\", \"אוגוסט\", \"ספטמבר\", \"אוקטובר\", \"נובמבר\", \"דצמבר\"],\n      monthsShort: [\"ינו\", \"פבר\", \"מרץ\", \"אפר\", \"מאי\", \"יונ\", \"יול\", \"אוג\", \"ספט\", \"אוק\", \"נוב\", \"דצמ\"],\n      today: \"היום\",\n\t  suffix: [],\n\t  meridiem: [],\n      rtl: true\n  };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.hr.js",
    "content": "/**\n * Croatian localisation\n */\n;(function($){\n\t$.fn.datetimepicker.dates['hr'] = {\n\t\tdays: [\"Nedjelja\", \"Ponedjelja\", \"Utorak\", \"Srijeda\", \"Četrtak\", \"Petak\", \"Subota\", \"Nedjelja\"],\n\t\tdaysShort: [\"Ned\", \"Pon\", \"Uto\", \"Srr\", \"Čet\", \"Pet\", \"Sub\", \"Ned\"],\n\t\tdaysMin: [\"Ne\", \"Po\", \"Ut\", \"Sr\", \"Če\", \"Pe\", \"Su\", \"Ne\"],\n\t\tmonths: [\"Siječanj\", \"Veljača\", \"Ožujak\", \"Travanj\", \"Svibanj\", \"Lipanj\", \"Srpanj\", \"Kolovoz\", \"Rujan\", \"Listopad\", \"Studeni\", \"Prosinac\"],\n\t\tmonthsShort: [\"Sije\", \"Velj\", \"Ožu\", \"Tra\", \"Svi\", \"Lip\", \"Jul\", \"Kol\", \"Ruj\", \"Lis\", \"Stu\", \"Pro\"],\n\t\ttoday: \"Danas\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.hu.js",
    "content": "/**\n * Hungarian translation for bootstrap-datetimepicker\n * darevish <http://github.com/darevish>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['hu'] = {\n\t\tdays: [\"Vasárnap\", \"Hétfő\", \"Kedd\", \"Szerda\", \"Csütörtök\", \"Péntek\", \"Szombat\", \"Vasárnap\"],\n\t\tdaysShort: [\"Vas\", \"Hét\", \"Ked\", \"Sze\", \"Csü\", \"Pén\", \"Szo\", \"Vas\"],\n\t\tdaysMin: [\"V\", \"H\", \"K\", \"Sze\", \"Cs\", \"P\", \"Szo\", \"V\"],\n\t\tmonths: [\"Január\", \"Február\", \"Március\", \"Április\", \"Május\", \"Június\", \"Július\", \"Augusztus\", \"Szeptember\", \"Október\", \"November\", \"December\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Már\", \"Ápr\", \"Máj\", \"Jún\", \"Júl\", \"Aug\", \"Sze\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Ma\",\n\t\tsuffix: [],\n\t\tmeridiem: [],\n\t\tweekStart: 1\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.hy.js",
    "content": "/**\n * Armenian translation for bootstrap-datepicker\n * Hayk Chamyan <hamshen@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['hy'] = {\n\t\tdays: [\"Կիրակի\", \"Երկուշաբթի\", \"Երեքշաբթի\", \"Չորեքշաբթի\", \"Հինգշաբթի\", \"Ուրբաթ\", \"Շաբաթ\", \"Կիրակի\"],\n\t\tdaysShort: [\"Կիր\", \"Երկ\", \"Երք\", \"Չոր\", \"Հնգ\", \"Ուր\", \"Շաբ\", \"Կիր\"],\n\t\tdaysMin: [\"Կի\", \"Եկ\", \"Եք\", \"Չո\", \"Հի\", \"Ու\", \"Շա\", \"Կի\"],\n\t\tmonths: [\"Հունվար\", \"Փետրվար\", \"Մարտ\", \"Ապրիլ\", \"Մայիս\", \"Հունիս\", \"Հուլիս\", \"Օգոստոս\", \"Սեպտեմբեր\", \"Հոկտեմբեր\", \"Նոյեմբեր\", \"Դեկտեմբեր\"],\n\t\tmonthsShort: [\"Հնվ\", \"Փետ\", \"Մար\", \"Ապր\", \"Մայ\", \"Հուն\", \"Հուլ\", \"Օգս\", \"Սեպ\", \"Հոկ\", \"Նոյ\", \"Դեկ\"],\n\t\ttoday: \"Այսօր\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.id.js",
    "content": "/**\n * Bahasa translation for bootstrap-datetimepicker\n * Azwar Akbar <azwar.akbar@gmail.com>\n * Addtional by Yulian Sutopo <yuliansutopo@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['id'] = {\n\t\tdays: [\"Minggu\", \"Senin\", \"Selasa\", \"Rabu\", \"Kamis\", \"Jumat\", \"Sabtu\", \"Minggu\"],\n\t\tdaysShort: [\"Mng\", \"Sen\", \"Sel\", \"Rab\", \"Kam\", \"Jum\", \"Sab\", \"Mng\"],\n\t\tdaysMin: [\"Mg\", \"Sn\", \"Sl\", \"Ra\", \"Ka\", \"Ju\", \"Sa\", \"Mg\"],\n\t\tmonths: [\"Januari\", \"Februari\", \"Maret\", \"April\", \"Mei\", \"Juni\", \"Juli\", \"Agustus\", \"September\", \"Oktober\", \"November\", \"Desember\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Mei\", \"Jun\", \"Jul\", \"Ags\", \"Sep\", \"Okt\", \"Nov\", \"Des\"],\n\t\ttoday: \"Hari Ini\",\n\t\tsuffix: [],\n\t\tmeridiem: [],\n\t\tweekStart: 1,\n\t\tformat: \"dd/mm/yyyy hh:ii:ss\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.is.js",
    "content": "/**\n * Icelandic translation for bootstrap-datetimepicker\n * Hinrik Örn Sigurðsson <hinrik.sig@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['is'] = {\n\t\tdays: [\"Sunnudagur\", \"Mánudagur\", \"Þriðjudagur\", \"Miðvikudagur\", \"Fimmtudagur\", \"Föstudagur\", \"Laugardagur\", \"Sunnudagur\"],\n\t\tdaysShort: [\"Sun\", \"Mán\", \"Þri\", \"Mið\", \"Fim\", \"Fös\", \"Lau\", \"Sun\"],\n\t\tdaysMin: [\"Su\", \"Má\", \"Þr\", \"Mi\", \"Fi\", \"Fö\", \"La\", \"Su\"],\n\t\tmonths: [\"Janúar\", \"Febrúar\", \"Mars\", \"Apríl\", \"Maí\", \"Júní\", \"Júlí\", \"Ágúst\", \"September\", \"Október\", \"Nóvember\", \"Desember\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Maí\", \"Jún\", \"Júl\", \"Ágú\", \"Sep\", \"Okt\", \"Nóv\", \"Des\"],\n\t\ttoday: \"Í Dag\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.it.js",
    "content": "/**\n * Italian translation for bootstrap-datetimepicker\n * Enrico Rubboli <rubboli@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['it'] = {\n\t\tdays: [\"Domenica\", \"Lunedi\", \"Martedi\", \"Mercoledi\", \"Giovedi\", \"Venerdi\", \"Sabato\", \"Domenica\"],\n\t\tdaysShort: [\"Dom\", \"Lun\", \"Mar\", \"Mer\", \"Gio\", \"Ven\", \"Sab\", \"Dom\"],\n\t\tdaysMin: [\"Do\", \"Lu\", \"Ma\", \"Me\", \"Gi\", \"Ve\", \"Sa\", \"Do\"],\n\t\tmonths: [\"Gennaio\", \"Febbraio\", \"Marzo\", \"Aprile\", \"Maggio\", \"Giugno\", \"Luglio\", \"Agosto\", \"Settembre\", \"Ottobre\", \"Novembre\", \"Dicembre\"],\n\t\tmonthsShort: [\"Gen\", \"Feb\", \"Mar\", \"Apr\", \"Mag\", \"Giu\", \"Lug\", \"Ago\", \"Set\", \"Ott\", \"Nov\", \"Dic\"],\n\t\ttoday: \"Oggi\",\n\t\tsuffix: [],\n\t\tmeridiem: [],\n\t\tweekStart: 1,\n\t\tformat: \"dd/mm/yyyy hh:ii:ss\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.ja.js",
    "content": "/**\n * Japanese translation for bootstrap-datetimepicker\n * Norio Suzuki <https://github.com/suzuki/>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['ja'] = {\n\t\tdays: [\"日曜\", \"月曜\", \"火曜\", \"水曜\", \"木曜\", \"金曜\", \"土曜\", \"日曜\"],\n\t\tdaysShort: [\"日\", \"月\", \"火\", \"水\", \"木\", \"金\", \"土\", \"日\"],\n\t\tdaysMin: [\"日\", \"月\", \"火\", \"水\", \"木\", \"金\", \"土\", \"日\"],\n\t\tmonths: [\"1月\", \"2月\", \"3月\", \"4月\", \"5月\", \"6月\", \"7月\", \"8月\", \"9月\", \"10月\", \"11月\", \"12月\"],\n\t\tmonthsShort: [\"1月\", \"2月\", \"3月\", \"4月\", \"5月\", \"6月\", \"7月\", \"8月\", \"9月\", \"10月\", \"11月\", \"12月\"],\n\t\ttoday: \"今日\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.ko.js",
    "content": "/**\n * Korean translation for bootstrap-datetimepicker\n * Gu Youn <http://github.com/guyoun>\n * Baekjoon Choi <http://github.com/Baekjoon>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['ko'] = {\n\t\tdays: [\"일요일\", \"월요일\", \"화요일\", \"수요일\", \"목요일\", \"금요일\", \"토요일\", \"일요일\"],\n\t\tdaysShort: [\"일\", \"월\", \"화\", \"수\", \"목\", \"금\", \"토\", \"일\"],\n\t\tdaysMin: [\"일\", \"월\", \"화\", \"수\", \"목\", \"금\", \"토\", \"일\"],\n\t\tmonths: [\"1월\", \"2월\", \"3월\", \"4월\", \"5월\", \"6월\", \"7월\", \"8월\", \"9월\", \"10월\", \"11월\", \"12월\"],\n\t\tmonthsShort: [\"1월\", \"2월\", \"3월\", \"4월\", \"5월\", \"6월\", \"7월\", \"8월\", \"9월\", \"10월\", \"11월\", \"12월\"],\n\t\tsuffix: [],\n\t\tmeridiem: [\"오전\", \"오후\"],\n        today: \"오늘\",\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.lt.js",
    "content": "﻿/**\n * Lithuanian translation for bootstrap-datetimepicker\n * Šarūnas Gliebus <ssharunas@yahoo.co.uk>\n */\n\n;(function($){\n    $.fn.datetimepicker.dates['lt'] = {\n        days: [\"Sekmadienis\", \"Pirmadienis\", \"Antradienis\", \"Trečiadienis\", \"Ketvirtadienis\", \"Penktadienis\", \"Šeštadienis\", \"Sekmadienis\"],\n        daysShort: [\"S\", \"Pr\", \"A\", \"T\", \"K\", \"Pn\", \"Š\", \"S\"],\n        daysMin: [\"Sk\", \"Pr\", \"An\", \"Tr\", \"Ke\", \"Pn\", \"Št\", \"Sk\"],\n        months: [\"Sausis\", \"Vasaris\", \"Kovas\", \"Balandis\", \"Gegužė\", \"Birželis\", \"Liepa\", \"Rugpjūtis\", \"Rugsėjis\", \"Spalis\", \"Lapkritis\", \"Gruodis\"],\n        monthsShort: [\"Sau\", \"Vas\", \"Kov\", \"Bal\", \"Geg\", \"Bir\", \"Lie\", \"Rugp\", \"Rugs\", \"Spa\", \"Lap\", \"Gru\"],\n        today: \"Šiandien\",\n\t\tsuffix: [],\n\t\tmeridiem: [],\n        weekStart: 1\n    };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.lv.js",
    "content": "/**\n * Latvian translation for bootstrap-datetimepicker\n * Artis Avotins <artis@apit.lv>\n */\n\n;(function($){\n    $.fn.datetimepicker.dates['lv'] = {\n        days: [\"Svētdiena\", \"Pirmdiena\", \"Otrdiena\", \"Trešdiena\", \"Ceturtdiena\", \"Piektdiena\", \"Sestdiena\", \"Svētdiena\"],\n        daysShort: [\"Sv\", \"P\", \"O\", \"T\", \"C\", \"Pk\", \"S\", \"Sv\"],\n        daysMin: [\"Sv\", \"Pr\", \"Ot\", \"Tr\", \"Ce\", \"Pk\", \"St\", \"Sv\"],\n        months: [\"Janvāris\", \"Februāris\", \"Marts\", \"Aprīlis\", \"Maijs\", \"Jūnijs\", \"Jūlijs\", \"Augusts\", \"Septembris\", \"Oktobris\", \"Novembris\", \"Decembris\"],\n        monthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Mai\", \"Jūn\", \"Jūl\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dec.\"],\n        today: \"Šodien\",\n\t\tsuffix: [],\n\t\tmeridiem: [],\n        weekStart: 1\n    };\n}(jQuery));"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.ms.js",
    "content": "/**\n * Malay translation for bootstrap-datetimepicker\n * Ateman Faiz <noorulfaiz@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['ms'] = {\n\t\tdays: [\"Ahad\", \"Isnin\", \"Selasa\", \"Rabu\", \"Khamis\", \"Jumaat\", \"Sabtu\", \"Ahad\"],\n\t\tdaysShort: [\"Aha\", \"Isn\", \"Sel\", \"Rab\", \"Kha\", \"Jum\", \"Sab\", \"Aha\"],\n\t\tdaysMin: [\"Ah\", \"Is\", \"Se\", \"Ra\", \"Kh\", \"Ju\", \"Sa\", \"Ah\"],\n\t\tmonths: [\"Januari\", \"Februari\", \"Mac\", \"April\", \"Mei\", \"Jun\", \"Julai\", \"Ogos\", \"September\", \"Oktober\", \"November\", \"Disember\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Mei\", \"Jun\", \"Jul\", \"Ogo\", \"Sep\", \"Okt\", \"Nov\", \"Dis\"],\n\t\ttoday: \"Hari Ini\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.nb.js",
    "content": "/**\n * Norwegian (bokmål) translation for bootstrap-datetimepicker\n * Fredrik Sundmyhr <http://github.com/fsundmyhr>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['nb'] = {\n\t\tdays: [\"Søndag\", \"Mandag\", \"Tirsdag\", \"Onsdag\", \"Torsdag\", \"Fredag\", \"Lørdag\", \"Søndag\"],\n\t\tdaysShort: [\"Søn\", \"Man\", \"Tir\", \"Ons\", \"Tor\", \"Fre\", \"Lør\", \"Søn\"],\n\t\tdaysMin: [\"Sø\", \"Ma\", \"Ti\", \"On\", \"To\", \"Fr\", \"Lø\", \"Sø\"],\n\t\tmonths: [\"Januar\", \"Februar\", \"Mars\", \"April\", \"Mai\", \"Juni\", \"Juli\", \"August\", \"September\", \"Oktober\", \"November\", \"Desember\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Mai\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Des\"],\n\t\ttoday: \"I Dag\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.nl.js",
    "content": "/**\n * Dutch translation for bootstrap-datetimepicker\n * Reinier Goltstein <mrgoltstein@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['nl'] = {\n\t\tdays: [\"Zondag\", \"Maandag\", \"Dinsdag\", \"Woensdag\", \"Donderdag\", \"Vrijdag\", \"Zaterdag\", \"Zondag\"],\n\t\tdaysShort: [\"Zo\", \"Ma\", \"Di\", \"Wo\", \"Do\", \"Vr\", \"Za\", \"Zo\"],\n\t\tdaysMin: [\"Zo\", \"Ma\", \"Di\", \"Wo\", \"Do\", \"Vr\", \"Za\", \"Zo\"],\n\t\tmonths: [\"Januari\", \"Februari\", \"Maart\", \"April\", \"Mei\", \"Juni\", \"Juli\", \"Augustus\", \"September\", \"Oktober\", \"November\", \"December\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mrt\", \"Apr\", \"Mei\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Vandaag\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.no.js",
    "content": "/**\n * Norwegian translation for bootstrap-datetimepicker\n * Rune Warhuus <rune@dinkdonkd.no>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['no'] = {\n\t\tdays: [\"Søndag\", \"Mandag\", \"Tirsdag\", \"Onsdag\", \"Torsdag\", \"Fredag\", \"Lørdag\", \"Søndag\"],\n\t\tdaysShort: [\"Søn\", \"Man\", \"Tir\", \"Ons\", \"Tor\", \"Fre\", \"Lør\", \"Søn\"],\n\t\tdaysMin: [\"Sø\", \"Ma\", \"Ti\", \"On\", \"To\", \"Fr\", \"Lø\", \"Sø\"],\n\t\tmonths: [\"Januar\", \"Februar\", \"Mars\", \"April\", \"Mai\", \"Juni\", \"Juli\", \"August\", \"September\", \"Oktober\", \"November\", \"Desember\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Mai\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Des\"],\n\t\ttoday: \"I Dag\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.pl.js",
    "content": "/**\n * Polish translation for bootstrap-datetimepicker\n * Robert <rtpm@gazeta.pl>\n */\n;(function($){\n$.fn.datetimepicker.dates['pl'] = {\n        days: [\"Niedziela\", \"Poniedziałek\", \"Wtorek\", \"Środa\", \"Czwartek\", \"Piątek\", \"Sobota\", \"Niedziela\"],\n        daysShort: [\"Nie\", \"Pn\", \"Wt\", \"Śr\", \"Czw\", \"Pt\", \"So\", \"Nie\"],\n        daysMin: [\"N\", \"Pn\", \"Wt\", \"Śr\", \"Cz\", \"Pt\", \"So\", \"N\"],\n        months: [\"Styczeń\", \"Luty\", \"Marzec\", \"Kwiecień\", \"Maj\", \"Czerwiec\", \"Lipiec\", \"Sierpień\", \"Wrzesień\", \"Październik\", \"Listopad\", \"Grudzień\"],\n        monthsShort: [\"Sty\", \"Lu\", \"Mar\", \"Kw\", \"Maj\", \"Cze\", \"Lip\", \"Sie\", \"Wrz\", \"Pa\", \"Lis\", \"Gru\"],\n        today: \"Dzisiaj\",\n\t\tsuffix: [],\n\t\tmeridiem: [],\n        weekStart: 1\n};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.pt-BR.js",
    "content": "/**\n * Brazilian translation for bootstrap-datetimepicker\n * Cauan Cabral <cauan@radig.com.br>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['pt-BR'] = {\n        format: 'dd/mm/yyyy',\n\t\tdays: [\"Domingo\", \"Segunda\", \"Terça\", \"Quarta\", \"Quinta\", \"Sexta\", \"Sábado\", \"Domingo\"],\n\t\tdaysShort: [\"Dom\", \"Seg\", \"Ter\", \"Qua\", \"Qui\", \"Sex\", \"Sáb\", \"Dom\"],\n\t\tdaysMin: [\"Do\", \"Se\", \"Te\", \"Qu\", \"Qu\", \"Se\", \"Sa\", \"Do\"],\n\t\tmonths: [\"Janeiro\", \"Fevereiro\", \"Março\", \"Abril\", \"Maio\", \"Junho\", \"Julho\", \"Agosto\", \"Setembro\", \"Outubro\", \"Novembro\", \"Dezembro\"],\n\t\tmonthsShort: [\"Jan\", \"Fev\", \"Mar\", \"Abr\", \"Mai\", \"Jun\", \"Jul\", \"Ago\", \"Set\", \"Out\", \"Nov\", \"Dez\"],\n\t\ttoday: \"Hoje\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.pt.js",
    "content": "/**\n * Portuguese translation for bootstrap-datetimepicker\n * Original code: Cauan Cabral <cauan@radig.com.br>\n * Tiago Melo <tiago.blackcode@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['pt'] = {\n\t\tdays: [\"Domingo\", \"Segunda\", \"Terça\", \"Quarta\", \"Quinta\", \"Sexta\", \"Sábado\", \"Domingo\"],\n\t\tdaysShort: [\"Dom\", \"Seg\", \"Ter\", \"Qua\", \"Qui\", \"Sex\", \"Sáb\", \"Dom\"],\n\t\tdaysMin: [\"Do\", \"Se\", \"Te\", \"Qu\", \"Qu\", \"Se\", \"Sa\", \"Do\"],\n\t\tmonths: [\"Janeiro\", \"Fevereiro\", \"Março\", \"Abril\", \"Maio\", \"Junho\", \"Julho\", \"Agosto\", \"Setembro\", \"Outubro\", \"Novembro\", \"Dezembro\"],\n\t\tmonthsShort: [\"Jan\", \"Fev\", \"Mar\", \"Abr\", \"Mai\", \"Jun\", \"Jul\", \"Ago\", \"Set\", \"Out\", \"Nov\", \"Dez\"],\n\t\tsuffix: [],\n\t\tmeridiem: [\"am\",\"pm\"],\n\t\ttoday: \"Hoje\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.ro.js",
    "content": "/**\n * Romanian translation for bootstrap-datetimepicker\n * Cristian Vasile <cristi.mie@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['ro'] = {\n\t\tdays: [\"Duminică\", \"Luni\", \"Marţi\", \"Miercuri\", \"Joi\", \"Vineri\", \"Sâmbătă\", \"Duminică\"],\n\t\tdaysShort: [\"Dum\", \"Lun\", \"Mar\", \"Mie\", \"Joi\", \"Vin\", \"Sâm\", \"Dum\"],\n\t\tdaysMin: [\"Du\", \"Lu\", \"Ma\", \"Mi\", \"Jo\", \"Vi\", \"Sâ\", \"Du\"],\n\t\tmonths: [\"Ianuarie\", \"Februarie\", \"Martie\", \"Aprilie\", \"Mai\", \"Iunie\", \"Iulie\", \"August\", \"Septembrie\", \"Octombrie\", \"Noiembrie\", \"Decembrie\"],\n\t\tmonthsShort: [\"Ian\", \"Feb\", \"Mar\", \"Apr\", \"Mai\", \"Iun\", \"Iul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Astăzi\",\n\t\tsuffix: [],\n\t\tmeridiem: [],\n\t\tweekStart: 1\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.rs-latin.js",
    "content": "/**\n * Serbian latin translation for bootstrap-datetimepicker\n * Bojan Milosavlević <milboj@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['rs'] = {\n\t\tdays: [\"Nedelja\",\"Ponedeljak\", \"Utorak\", \"Sreda\", \"Četvrtak\", \"Petak\", \"Subota\", \"Nedelja\"],\n\t\tdaysShort: [\"Ned\", \"Pon\", \"Uto\", \"Sre\", \"Čet\", \"Pet\", \"Sub\", \"Ned\"],\n\t\tdaysMin: [\"N\", \"Po\", \"U\", \"Sr\", \"Č\", \"Pe\", \"Su\", \"N\"],\n\t\tmonths: [\"Januar\", \"Februar\", \"Mart\", \"April\", \"Maj\", \"Jun\", \"Jul\", \"Avgust\", \"Septembar\", \"Oktobar\", \"Novembar\", \"Decembar\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Maj\", \"Jun\", \"Jul\", \"Avg\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Danas\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.rs.js",
    "content": "/**\n * Serbian cyrillic translation for bootstrap-datetimepicker\n * Bojan Milosavlević <milboj@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['rs'] = {\n\t\tdays: [\"Недеља\",\"Понедељак\", \"Уторак\", \"Среда\", \"Четвртак\", \"Петак\", \"Субота\", \"Недеља\"],\n\t\tdaysShort: [\"Нед\", \"Пон\", \"Уто\", \"Сре\", \"Чет\", \"Пет\", \"Суб\", \"Нед\"],\n\t\tdaysMin: [\"Н\", \"По\", \"У\", \"Ср\", \"Ч\", \"Пе\", \"Су\", \"Н\"],\n\t\tmonths: [\"Јануар\", \"Фебруар\", \"Март\", \"Април\", \"Мај\", \"Јун\", \"Јул\", \"Август\", \"Септембар\", \"Октобар\", \"Новембар\", \"Децембар\"],\n\t\tmonthsShort: [\"Јан\", \"Феб\", \"Мар\", \"Апр\", \"Мај\", \"Јун\", \"Јул\", \"Авг\", \"Сеп\", \"Окт\", \"Нов\", \"Дец\"],\n\t\ttoday: \"Данас\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.ru.js",
    "content": "/**\n * Russian translation for bootstrap-datetimepicker\n * Victor Taranenko <darwin@snowdale.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['ru'] = {\n\t\tdays: [\"Воскресенье\", \"Понедельник\", \"Вторник\", \"Среда\", \"Четверг\", \"Пятница\", \"Суббота\", \"Воскресенье\"],\n\t\tdaysShort: [\"Вск\", \"Пнд\", \"Втр\", \"Срд\", \"Чтв\", \"Птн\", \"Суб\", \"Вск\"],\n\t\tdaysMin: [\"Вс\", \"Пн\", \"Вт\", \"Ср\", \"Чт\", \"Пт\", \"Сб\", \"Вс\"],\n\t\tmonths: [\"Январь\", \"Февраль\", \"Март\", \"Апрель\", \"Май\", \"Июнь\", \"Июль\", \"Август\", \"Сентябрь\", \"Октябрь\", \"Ноябрь\", \"Декабрь\"],\n\t\tmonthsShort: [\"Янв\", \"Фев\", \"Мар\", \"Апр\", \"Май\", \"Июн\", \"Июл\", \"Авг\", \"Сен\", \"Окт\", \"Ноя\", \"Дек\"],\n\t\ttoday: \"Сегодня\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.sk.js",
    "content": "/**\n * Slovak translation for bootstrap-datetimepicker\n * Marek Lichtner <marek@licht.sk>\n * Fixes by Michal Remiš <michal.remis@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates[\"sk\"] = {\n\t\tdays: [\"Nedeľa\", \"Pondelok\", \"Utorok\", \"Streda\", \"Štvrtok\", \"Piatok\", \"Sobota\", \"Nedeľa\"],\n\t\tdaysShort: [\"Ned\", \"Pon\", \"Uto\", \"Str\", \"Štv\", \"Pia\", \"Sob\", \"Ned\"],\n\t\tdaysMin: [\"Ne\", \"Po\", \"Ut\", \"St\", \"Št\", \"Pia\", \"So\", \"Ne\"],\n\t\tmonths: [\"Január\", \"Február\", \"Marec\", \"Apríl\", \"Máj\", \"Jún\", \"Júl\", \"August\", \"September\", \"Október\", \"November\", \"December\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Máj\", \"Jún\", \"Júl\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Dnes\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.sl.js",
    "content": "/**\n * Slovene translation for bootstrap-datetimepicker\n * Gregor Rudolf <gregor.rudolf@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['sl'] = {\n\t\tdays: [\"Nedelja\", \"Ponedeljek\", \"Torek\", \"Sreda\", \"Četrtek\", \"Petek\", \"Sobota\", \"Nedelja\"],\n\t\tdaysShort: [\"Ned\", \"Pon\", \"Tor\", \"Sre\", \"Čet\", \"Pet\", \"Sob\", \"Ned\"],\n\t\tdaysMin: [\"Ne\", \"Po\", \"To\", \"Sr\", \"Če\", \"Pe\", \"So\", \"Ne\"],\n\t\tmonths: [\"Januar\", \"Februar\", \"Marec\", \"April\", \"Maj\", \"Junij\", \"Julij\", \"Avgust\", \"September\", \"Oktober\", \"November\", \"December\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Maj\", \"Jun\", \"Jul\", \"Avg\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Danes\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.sv.js",
    "content": "/**\n * Swedish translation for bootstrap-datetimepicker\n * Patrik Ragnarsson <patrik@starkast.net>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['sv'] = {\n\t\tdays: [\"Söndag\", \"Måndag\", \"Tisdag\", \"Onsdag\", \"Torsdag\", \"Fredag\", \"Lördag\", \"Söndag\"],\n\t\tdaysShort: [\"Sön\", \"Mån\", \"Tis\", \"Ons\", \"Tor\", \"Fre\", \"Lör\", \"Sön\"],\n\t\tdaysMin: [\"Sö\", \"Må\", \"Ti\", \"On\", \"To\", \"Fr\", \"Lö\", \"Sö\"],\n\t\tmonths: [\"Januari\", \"Februari\", \"Mars\", \"April\", \"Maj\", \"Juni\", \"Juli\", \"Augusti\", \"September\", \"Oktober\", \"November\", \"December\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Maj\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"I Dag\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.sw.js",
    "content": "/**\n * Swahili translation for bootstrap-datetimepicker\n * Edwin Mugendi <https://github.com/edwinmugendi>\n * Source: http://scriptsource.org/cms/scripts/page.php?item_id=entry_detail&uid=xnfaqyzcku\n */\n;(function($){\n    $.fn.datetimepicker.dates['sw'] = {\n        days: [\"Jumapili\", \"Jumatatu\", \"Jumanne\", \"Jumatano\", \"Alhamisi\", \"Ijumaa\", \"Jumamosi\", \"Jumapili\"],\n        daysShort: [\"J2\", \"J3\", \"J4\", \"J5\", \"Alh\", \"Ij\", \"J1\", \"J2\"],\n        daysMin: [\"2\", \"3\", \"4\", \"5\", \"A\", \"I\", \"1\", \"2\"],\n        months: [\"Januari\", \"Februari\", \"Machi\", \"Aprili\", \"Mei\", \"Juni\", \"Julai\", \"Agosti\", \"Septemba\", \"Oktoba\", \"Novemba\", \"Desemba\"],\n        monthsShort: [\"Jan\", \"Feb\", \"Mac\", \"Apr\", \"Mei\", \"Jun\", \"Jul\", \"Ago\", \"Sep\", \"Okt\", \"Nov\", \"Des\"],\n        today: \"Leo\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n    };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.th.js",
    "content": "/**\n * Thai translation for bootstrap-datetimepicker\n * Suchau Jiraprapot <seroz24@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['th'] = {\n\t\tdays: [\"อาทิตย์\", \"จันทร์\", \"อังคาร\", \"พุธ\", \"พฤหัส\", \"ศุกร์\", \"เสาร์\", \"อาทิตย์\"],\n\t\tdaysShort: [\"อา\", \"จ\", \"อ\", \"พ\", \"พฤ\", \"ศ\", \"ส\", \"อา\"],\n\t\tdaysMin: [\"อา\", \"จ\", \"อ\", \"พ\", \"พฤ\", \"ศ\", \"ส\", \"อา\"],\n\t\tmonths: [\"มกราคม\", \"กุมภาพันธ์\", \"มีนาคม\", \"เมษายน\", \"พฤษภาคม\", \"มิถุนายน\", \"กรกฎาคม\", \"สิงหาคม\", \"กันยายน\", \"ตุลาคม\", \"พฤศจิกายน\", \"ธันวาคม\"],\n\t\tmonthsShort: [\"ม.ค.\", \"ก.พ.\", \"มี.ค.\", \"เม.ย.\", \"พ.ค.\", \"มิ.ย.\", \"ก.ค.\", \"ส.ค.\", \"ก.ย.\", \"ต.ค.\", \"พ.ย.\", \"ธ.ค.\"],\n\t\ttoday: \"วันนี้\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.tr.js",
    "content": "/**\n * Turkish translation for bootstrap-datetimepicker\n * Serkan Algur <kaisercrazy_2@hotmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['tr'] = {\n\t\tdays: [\"Pazar\", \"Pazartesi\", \"Salı\", \"Çarşamba\", \"Perşembe\", \"Cuma\", \"Cumartesi\", \"Pazar\"],\n\t\tdaysShort: [\"Pz\", \"Pzt\", \"Sal\", \"Çrş\", \"Prş\", \"Cu\", \"Cts\", \"Pz\"],\n\t\tdaysMin: [\"Pz\", \"Pzt\", \"Sa\", \"Çr\", \"Pr\", \"Cu\", \"Ct\", \"Pz\"],\n\t\tmonths: [\"Ocak\", \"Şubat\", \"Mart\", \"Nisan\", \"Mayıs\", \"Haziran\", \"Temmuz\", \"Ağustos\", \"Eylül\", \"Ekim\", \"Kasım\", \"Aralık\"],\n\t\tmonthsShort: [\"Oca\", \"Şub\", \"Mar\", \"Nis\", \"May\", \"Haz\", \"Tem\", \"Ağu\", \"Eyl\", \"Eki\", \"Kas\", \"Ara\"],\n\t\ttoday: \"Bugün\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));\n\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.ua.js",
    "content": "/**\n * Ukrainian translation for bootstrap-datepicker\n * Igor Polynets\n */\n;(function($){\n\t$.fn.datetimepicker.dates['ua'] = {\n\t\tdays: [\"Неділя\", \"Понеділок\", \"Вівторок\", \"Середа\", \"Четверг\", \"П'ятниця\", \"Субота\", \"Неділя\"],\n\t\tdaysShort: [\"Нед\", \"Пнд\", \"Втр\", \"Срд\", \"Чтв\", \"Птн\", \"Суб\", \"Нед\"],\n\t\tdaysMin: [\"Нд\", \"Пн\", \"Вт\", \"Ср\", \"Чт\", \"Пт\", \"Сб\", \"Нд\"],\n\t\tmonths: [\"Cічень\", \"Лютий\", \"Березень\", \"Квітень\", \"Травень\", \"Червень\", \"Липень\", \"Серпень\", \"Вересень\", \"Жовтень\", \"Листопад\", \"Грудень\"],\n\t\tmonthsShort: [\"Січ\", \"Лют\", \"Бер\", \"Квт\", \"Трв\", \"Чер\", \"Лип\", \"Сер\", \"Вер\", \"Жов\", \"Лис\", \"Грд\"],\n\t\ttoday: \"Сьогодні\",\n\t\tweekStart: 1\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.uk.js",
    "content": "/**\n * Ukrainian translation for bootstrap-datetimepicker\n * Andrey Vityuk <andrey [dot] vityuk [at] gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['uk'] = {\n\t\tdays: [\"Неділя\", \"Понеділок\", \"Вівторок\", \"Середа\", \"Четвер\", \"П'ятниця\", \"Субота\", \"Неділя\"],\n\t\tdaysShort: [\"Нед\", \"Пнд\", \"Втр\", \"Срд\", \"Чтв\", \"Птн\", \"Суб\", \"Нед\"],\n\t\tdaysMin: [\"Нд\", \"Пн\", \"Вт\", \"Ср\", \"Чт\", \"Пт\", \"Сб\", \"Нд\"],\n\t\tmonths: [\"Січень\", \"Лютий\", \"Березень\", \"Квітень\", \"Травень\", \"Червень\", \"Липень\", \"Серпень\", \"Вересень\", \"Жовтень\", \"Листопад\", \"Грудень\"],\n\t\tmonthsShort: [\"Січ\", \"Лют\", \"Бер\", \"Кві\", \"Тра\", \"Чер\", \"Лип\", \"Сер\", \"Вер\", \"Жов\", \"Лис\", \"Гру\"],\n\t\ttoday: \"Сьогодні\",\n\t\tsuffix: [],\n\t\tmeridiem: []\n\t};\n}(jQuery));"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.zh-CN.js",
    "content": "/**\n * Simplified Chinese translation for bootstrap-datetimepicker\n * Yuan Cheung <advanimal@gmail.com>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['zh-CN'] = {\n\t\t\tdays: [\"星期日\", \"星期一\", \"星期二\", \"星期三\", \"星期四\", \"星期五\", \"星期六\", \"星期日\"],\n\t\t\tdaysShort: [\"周日\", \"周一\", \"周二\", \"周三\", \"周四\", \"周五\", \"周六\", \"周日\"],\n\t\t\tdaysMin:  [\"日\", \"一\", \"二\", \"三\", \"四\", \"五\", \"六\", \"日\"],\n\t\t\tmonths: [\"一月\", \"二月\", \"三月\", \"四月\", \"五月\", \"六月\", \"七月\", \"八月\", \"九月\", \"十月\", \"十一月\", \"十二月\"],\n\t\t\tmonthsShort: [\"一月\", \"二月\", \"三月\", \"四月\", \"五月\", \"六月\", \"七月\", \"八月\", \"九月\", \"十月\", \"十一月\", \"十二月\"],\n\t\t\ttoday: \"今天\",\n\t\t\tsuffix: [],\n\t\t\tmeridiem: [\"上午\", \"下午\"]\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-datetimepicker/js/locales/bootstrap-datetimepicker.zh-TW.js",
    "content": "/**\n * Traditional Chinese translation for bootstrap-datetimepicker\n * Rung-Sheng Jang <daniel@i-trend.co.cc>\n */\n;(function($){\n\t$.fn.datetimepicker.dates['zh-TW'] = {\n\tdays: [\"星期日\", \"星期一\", \"星期二\", \"星期三\", \"星期四\", \"星期五\", \"星期六\", \"星期日\"],\n\t  daysShort: [\"周日\", \"周一\", \"周二\", \"周三\", \"周四\", \"周五\", \"周六\", \"周日\"],\n\t\tdaysMin:  [\"日\", \"一\", \"二\", \"三\", \"四\", \"五\", \"六\", \"日\"],\n\t\tmonths: [\"一月\", \"二月\", \"三月\", \"四月\", \"五月\", \"六月\", \"七月\", \"八月\", \"九月\", \"十月\", \"十一月\", \"十二月\"],\n\t\tmonthsShort: [\"一月\", \"二月\", \"三月\", \"四月\", \"五月\", \"六月\", \"七月\", \"八月\", \"九月\", \"十月\", \"十一月\", \"十二月\"],\n\t\ttoday: \"今天\",\n    suffix: [],\n\t\tmeridiem: [\"上午\", \"下午\"]\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-slider/bootstrap-slider.js",
    "content": "/*! =========================================================\n * bootstrap-slider.js\n *\n * Maintainers:\n *\t\tKyle Kemp\n *\t\t\t- Twitter: @seiyria\n *\t\t\t- Github:  seiyria\n *\t\tRohit Kalkur\n *\t\t\t- Twitter: @Rovolutionary\n *\t\t\t- Github:  rovolution\n *\n * =========================================================\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================= */\n\n\n/**\n * Bridget makes jQuery widgets\n * v1.0.1\n * MIT license\n */\n\n(function(root, factory) {\n\tif(typeof define === \"function\" && define.amd) {\n\t\tdefine([\"jquery\"], factory);\n\t}\n\telse if(typeof module === \"object\" && module.exports) {\n\t\tvar jQuery;\n\t\ttry {\n\t\t\tjQuery = require(\"jquery\");\n\t\t}\n\t\tcatch (err) {\n\t\t\tjQuery = null;\n\t\t}\n\t\tmodule.exports = factory(jQuery);\n\t}\n\telse {\n\t\troot.Slider = factory(root.jQuery);\n\t}\n}(this, function($) {\n\t// Reference to Slider constructor\n\tvar Slider;\n\n\n\t(function( $ ) {\n\n\t\t'use strict';\n\n\t\t// -------------------------- utils -------------------------- //\n\n\t\tvar slice = Array.prototype.slice;\n\n\t\tfunction noop() {}\n\n\t\t// -------------------------- definition -------------------------- //\n\n\t\tfunction defineBridget( $ ) {\n\n\t\t\t// bail if no jQuery\n\t\t\tif ( !$ ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// -------------------------- addOptionMethod -------------------------- //\n\n\t\t\t/**\n\t\t\t * adds option method -> $().plugin('option', {...})\n\t\t\t * @param {Function} PluginClass - constructor class\n\t\t\t */\n\t\t\tfunction addOptionMethod( PluginClass ) {\n\t\t\t\t// don't overwrite original option method\n\t\t\t\tif ( PluginClass.prototype.option ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t  // option setter\n\t\t\t  PluginClass.prototype.option = function( opts ) {\n\t\t\t    // bail out if not an object\n\t\t\t    if ( !$.isPlainObject( opts ) ){\n\t\t\t      return;\n\t\t\t    }\n\t\t\t    this.options = $.extend( true, this.options, opts );\n\t\t\t  };\n\t\t\t}\n\n\n\t\t\t// -------------------------- plugin bridge -------------------------- //\n\n\t\t\t// helper function for logging errors\n\t\t\t// $.error breaks jQuery chaining\n\t\t\tvar logError = typeof console === 'undefined' ? noop :\n\t\t\t  function( message ) {\n\t\t\t    console.error( message );\n\t\t\t  };\n\n\t\t\t/**\n\t\t\t * jQuery plugin bridge, access methods like $elem.plugin('method')\n\t\t\t * @param {String} namespace - plugin name\n\t\t\t * @param {Function} PluginClass - constructor class\n\t\t\t */\n\t\t\tfunction bridge( namespace, PluginClass ) {\n\t\t\t  // add to jQuery fn namespace\n\t\t\t  $.fn[ namespace ] = function( options ) {\n\t\t\t    if ( typeof options === 'string' ) {\n\t\t\t      // call plugin method when first argument is a string\n\t\t\t      // get arguments for method\n\t\t\t      var args = slice.call( arguments, 1 );\n\n\t\t\t      for ( var i=0, len = this.length; i < len; i++ ) {\n\t\t\t        var elem = this[i];\n\t\t\t        var instance = $.data( elem, namespace );\n\t\t\t        if ( !instance ) {\n\t\t\t          logError( \"cannot call methods on \" + namespace + \" prior to initialization; \" +\n\t\t\t            \"attempted to call '\" + options + \"'\" );\n\t\t\t          continue;\n\t\t\t        }\n\t\t\t        if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) {\n\t\t\t          logError( \"no such method '\" + options + \"' for \" + namespace + \" instance\" );\n\t\t\t          continue;\n\t\t\t        }\n\n\t\t\t        // trigger method with arguments\n\t\t\t        var returnValue = instance[ options ].apply( instance, args);\n\n\t\t\t        // break look and return first value if provided\n\t\t\t        if ( returnValue !== undefined && returnValue !== instance) {\n\t\t\t          return returnValue;\n\t\t\t        }\n\t\t\t      }\n\t\t\t      // return this if no return value\n\t\t\t      return this;\n\t\t\t    } else {\n\t\t\t      var objects = this.map( function() {\n\t\t\t        var instance = $.data( this, namespace );\n\t\t\t        if ( instance ) {\n\t\t\t          // apply options & init\n\t\t\t          instance.option( options );\n\t\t\t          instance._init();\n\t\t\t        } else {\n\t\t\t          // initialize new instance\n\t\t\t          instance = new PluginClass( this, options );\n\t\t\t          $.data( this, namespace, instance );\n\t\t\t        }\n\t\t\t        return $(this);\n\t\t\t      });\n\n\t\t\t      if(!objects || objects.length > 1) {\n\t\t\t      \treturn objects;\n\t\t\t      } else {\n\t\t\t      \treturn objects[0];\n\t\t\t      }\n\t\t\t    }\n\t\t\t  };\n\n\t\t\t}\n\n\t\t\t// -------------------------- bridget -------------------------- //\n\n\t\t\t/**\n\t\t\t * converts a Prototypical class into a proper jQuery plugin\n\t\t\t *   the class must have a ._init method\n\t\t\t * @param {String} namespace - plugin name, used in $().pluginName\n\t\t\t * @param {Function} PluginClass - constructor class\n\t\t\t */\n\t\t\t$.bridget = function( namespace, PluginClass ) {\n\t\t\t  addOptionMethod( PluginClass );\n\t\t\t  bridge( namespace, PluginClass );\n\t\t\t};\n\n\t\t\treturn $.bridget;\n\n\t\t}\n\n\t  \t// get jquery from browser global\n\t  \tdefineBridget( $ );\n\n\t})( $ );\n\n\n\t/*************************************************\n\n\t\t\tBOOTSTRAP-SLIDER SOURCE CODE\n\n\t**************************************************/\n\n\t(function($) {\n\n\t\tvar ErrorMsgs = {\n\t\t\tformatInvalidInputErrorMsg : function(input) {\n\t\t\t\treturn \"Invalid input value '\" + input + \"' passed in\";\n\t\t\t},\n\t\t\tcallingContextNotSliderInstance : \"Calling context element does not have instance of Slider bound to it. Check your code to make sure the JQuery object returned from the call to the slider() initializer is calling the method\"\n\t\t};\n\n\t\tvar SliderScale = {\n\t\t\tlinear: {\n\t\t\t\ttoValue: function(percentage) {\n\t\t\t\t\tvar rawValue = percentage/100 * (this.options.max - this.options.min);\n\t\t\t\t\tif (this.options.ticks_positions.length > 0) {\n\t\t\t\t\t\tvar minv, maxv, minp, maxp = 0;\n\t\t\t\t\t\tfor (var i = 0; i < this.options.ticks_positions.length; i++) {\n\t\t\t\t\t\t\tif (percentage <= this.options.ticks_positions[i]) {\n\t\t\t\t\t\t\t\tminv = (i > 0) ? this.options.ticks[i-1] : 0;\n\t\t\t\t\t\t\t\tminp = (i > 0) ? this.options.ticks_positions[i-1] : 0;\n\t\t\t\t\t\t\t\tmaxv = this.options.ticks[i];\n\t\t\t\t\t\t\t\tmaxp = this.options.ticks_positions[i];\n\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (i > 0) {\n\t\t\t\t\t\t\tvar partialPercentage = (percentage - minp) / (maxp - minp);\n\t\t\t\t\t\t\trawValue = minv + partialPercentage * (maxv - minv);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tvar value = this.options.min + Math.round(rawValue / this.options.step) * this.options.step;\n\t\t\t\t\tif (value < this.options.min) {\n\t\t\t\t\t\treturn this.options.min;\n\t\t\t\t\t} else if (value > this.options.max) {\n\t\t\t\t\t\treturn this.options.max;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\ttoPercentage: function(value) {\n\t\t\t\t\tif (this.options.max === this.options.min) {\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.options.ticks_positions.length > 0) {\n\t\t\t\t\t\tvar minv, maxv, minp, maxp = 0;\n\t\t\t\t\t\tfor (var i = 0; i < this.options.ticks.length; i++) {\n\t\t\t\t\t\t\tif (value  <= this.options.ticks[i]) {\n\t\t\t\t\t\t\t\tminv = (i > 0) ? this.options.ticks[i-1] : 0;\n\t\t\t\t\t\t\t\tminp = (i > 0) ? this.options.ticks_positions[i-1] : 0;\n\t\t\t\t\t\t\t\tmaxv = this.options.ticks[i];\n\t\t\t\t\t\t\t\tmaxp = this.options.ticks_positions[i];\n\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (i > 0) {\n\t\t\t\t\t\t\tvar partialPercentage = (value - minv) / (maxv - minv);\n\t\t\t\t\t\t\treturn minp + partialPercentage * (maxp - minp);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn 100 * (value - this.options.min) / (this.options.max - this.options.min);\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tlogarithmic: {\n\t\t\t\t/* Based on http://stackoverflow.com/questions/846221/logarithmic-slider */\n\t\t\t\ttoValue: function(percentage) {\n\t\t\t\t\tvar min = (this.options.min === 0) ? 0 : Math.log(this.options.min);\n\t\t\t\t\tvar max = Math.log(this.options.max);\n\t\t\t\t\tvar value = Math.exp(min + (max - min) * percentage / 100);\n\t\t\t\t\tvalue = this.options.min + Math.round((value - this.options.min) / this.options.step) * this.options.step;\n\t\t\t\t\t/* Rounding to the nearest step could exceed the min or\n\t\t\t\t\t * max, so clip to those values. */\n\t\t\t\t\tif (value < this.options.min) {\n\t\t\t\t\t\treturn this.options.min;\n\t\t\t\t\t} else if (value > this.options.max) {\n\t\t\t\t\t\treturn this.options.max;\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\ttoPercentage: function(value) {\n\t\t\t\t\tif (this.options.max === this.options.min) {\n\t\t\t\t\t\treturn 0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvar max = Math.log(this.options.max);\n\t\t\t\t\t\tvar min = this.options.min === 0 ? 0 : Math.log(this.options.min);\n\t\t\t\t\t\tvar v = value === 0 ? 0 : Math.log(value);\n\t\t\t\t\t\treturn 100 * (v - min) / (max - min);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\n\t\t/*************************************************\n\n\t\t\t\t\t\t\tCONSTRUCTOR\n\n\t\t**************************************************/\n\t\tSlider = function(element, options) {\n\t\t\tcreateNewSlider.call(this, element, options);\n\t\t\treturn this;\n\t\t};\n\n\t\tfunction createNewSlider(element, options) {\n\n\t\t\t/*\n\t\t\t\tThe internal state object is used to store data about the current 'state' of slider.\n\n\t\t\t\tThis includes values such as the `value`, `enabled`, etc...\n\t\t\t*/\n\t\t\tthis._state = {\n\t\t\t\tvalue: null,\n\t\t\t\tenabled: null,\n\t\t\t\toffset: null,\n\t\t\t\tsize: null,\n\t\t\t\tpercentage: null,\n\t\t\t\tinDrag: false,\n\t\t\t\tover: false\n\t\t\t};\n\n\n\t\t\tif(typeof element === \"string\") {\n\t\t\t\tthis.element = document.querySelector(element);\n\t\t\t} else if(element instanceof HTMLElement) {\n\t\t\t\tthis.element = element;\n\t\t\t}\n\n\t\t\t/*************************************************\n\n\t\t\t\t\t\t\tProcess Options\n\n\t\t\t**************************************************/\n\t\t\toptions = options ? options : {};\n\t\t\tvar optionTypes = Object.keys(this.defaultOptions);\n\n\t\t\tfor(var i = 0; i < optionTypes.length; i++) {\n\t\t\t\tvar optName = optionTypes[i];\n\n\t\t\t\t// First check if an option was passed in via the constructor\n\t\t\t\tvar val = options[optName];\n\t\t\t\t// If no data attrib, then check data atrributes\n\t\t\t\tval = (typeof val !== 'undefined') ? val : getDataAttrib(this.element, optName);\n\t\t\t\t// Finally, if nothing was specified, use the defaults\n\t\t\t\tval = (val !== null) ? val : this.defaultOptions[optName];\n\n\t\t\t\t// Set all options on the instance of the Slider\n\t\t\t\tif(!this.options) {\n\t\t\t\t\tthis.options = {};\n\t\t\t\t}\n\t\t\t\tthis.options[optName] = val;\n\t\t\t}\n\n\t\t\t/*\n\t\t\t\tValidate `tooltip_position` against 'orientation`\n\t\t\t\t- if `tooltip_position` is incompatible with orientation, swith it to a default compatible with specified `orientation`\n\t\t\t\t\t-- default for \"vertical\" -> \"right\"\n\t\t\t\t\t-- default for \"horizontal\" -> \"left\"\n\t\t\t*/\n\t\t\tif(this.options.orientation === \"vertical\" && (this.options.tooltip_position === \"top\" || this.options.tooltip_position === \"bottom\")) {\n\n\t\t\t\tthis.options.tooltip_position\t= \"right\";\n\n\t\t\t}\n\t\t\telse if(this.options.orientation === \"horizontal\" && (this.options.tooltip_position === \"left\" || this.options.tooltip_position === \"right\")) {\n\n\t\t\t\tthis.options.tooltip_position\t= \"top\";\n\n\t\t\t}\n\n\t\t\tfunction getDataAttrib(element, optName) {\n\t\t\t\tvar dataName = \"data-slider-\" + optName.replace(/_/g, '-');\n\t\t\t\tvar dataValString = element.getAttribute(dataName);\n\n\t\t\t\ttry {\n\t\t\t\t\treturn JSON.parse(dataValString);\n\t\t\t\t}\n\t\t\t\tcatch(err) {\n\t\t\t\t\treturn dataValString;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t/*************************************************\n\n\t\t\t\t\t\t\tCreate Markup\n\n\t\t\t**************************************************/\n\n\t\t\tvar origWidth = this.element.style.width;\n\t\t\tvar updateSlider = false;\n\t\t\tvar parent = this.element.parentNode;\n\t\t\tvar sliderTrackSelection;\n\t\t\tvar sliderTrackLow, sliderTrackHigh;\n\t\t\tvar sliderMinHandle;\n\t\t\tvar sliderMaxHandle;\n\n\t\t\tif (this.sliderElem) {\n\t\t\t\tupdateSlider = true;\n\t\t\t} else {\n\t\t\t\t/* Create elements needed for slider */\n\t\t\t\tthis.sliderElem = document.createElement(\"div\");\n\t\t\t\tthis.sliderElem.className = \"slider\";\n\n\t\t\t\t/* Create slider track elements */\n\t\t\t\tvar sliderTrack = document.createElement(\"div\");\n\t\t\t\tsliderTrack.className = \"slider-track\";\n\n\t\t\t\tsliderTrackLow = document.createElement(\"div\");\n\t\t\t\tsliderTrackLow.className = \"slider-track-low\";\n\n\t\t\t\tsliderTrackSelection = document.createElement(\"div\");\n\t\t\t\tsliderTrackSelection.className = \"slider-selection\";\n\n\t\t\t\tsliderTrackHigh = document.createElement(\"div\");\n\t\t\t\tsliderTrackHigh.className = \"slider-track-high\";\n\n\t\t\t\tsliderMinHandle = document.createElement(\"div\");\n\t\t\t\tsliderMinHandle.className = \"slider-handle min-slider-handle\";\n\t\t\t\tsliderMinHandle.setAttribute('role', 'slider');\n\t\t\t\tsliderMinHandle.setAttribute('aria-valuemin', this.options.min);\n\t\t\t\tsliderMinHandle.setAttribute('aria-valuemax', this.options.max);\n\n\t\t\t\tsliderMaxHandle = document.createElement(\"div\");\n\t\t\t\tsliderMaxHandle.className = \"slider-handle max-slider-handle\";\n\t\t\t\tsliderMaxHandle.setAttribute('role', 'slider');\n\t\t\t\tsliderMaxHandle.setAttribute('aria-valuemin', this.options.min);\n\t\t\t\tsliderMaxHandle.setAttribute('aria-valuemax', this.options.max);\n\n\t\t\t\tsliderTrack.appendChild(sliderTrackLow);\n\t\t\t\tsliderTrack.appendChild(sliderTrackSelection);\n\t\t\t\tsliderTrack.appendChild(sliderTrackHigh);\n\n\t\t\t\t/* Add aria-labelledby to handle's */\n\t\t\t\tvar isLabelledbyArray = Array.isArray(this.options.labelledby);\n\t\t\t\tif (isLabelledbyArray && this.options.labelledby[0]) {\n\t\t\t\t\tsliderMinHandle.setAttribute('aria-labelledby', this.options.labelledby[0]);\n\t\t\t\t}\n\t\t\t\tif (isLabelledbyArray && this.options.labelledby[1]) {\n\t\t\t\t\tsliderMaxHandle.setAttribute('aria-labelledby', this.options.labelledby[1]);\n\t\t\t\t}\n\t\t\t\tif (!isLabelledbyArray && this.options.labelledby) {\n\t\t\t\t\tsliderMinHandle.setAttribute('aria-labelledby', this.options.labelledby);\n\t\t\t\t\tsliderMaxHandle.setAttribute('aria-labelledby', this.options.labelledby);\n\t\t\t\t}\n\n\t\t\t\t/* Create ticks */\n\t\t\t\tthis.ticks = [];\n\t\t\t\tif (Array.isArray(this.options.ticks) && this.options.ticks.length > 0) {\n\t\t\t\t\tfor (i = 0; i < this.options.ticks.length; i++) {\n\t\t\t\t\t\tvar tick = document.createElement('div');\n\t\t\t\t\t\ttick.className = 'slider-tick';\n\n\t\t\t\t\t\tthis.ticks.push(tick);\n\t\t\t\t\t\tsliderTrack.appendChild(tick);\n\t\t\t\t\t}\n\n\t\t\t\t\tsliderTrackSelection.className += \" tick-slider-selection\";\n\t\t\t\t}\n\n\t\t\t\tsliderTrack.appendChild(sliderMinHandle);\n\t\t\t\tsliderTrack.appendChild(sliderMaxHandle);\n\n\t\t\t\tthis.tickLabels = [];\n\t\t\t\tif (Array.isArray(this.options.ticks_labels) && this.options.ticks_labels.length > 0) {\n\t\t\t\t\tthis.tickLabelContainer = document.createElement('div');\n\t\t\t\t\tthis.tickLabelContainer.className = 'slider-tick-label-container';\n\n\t\t\t\t\tfor (i = 0; i < this.options.ticks_labels.length; i++) {\n\t\t\t\t\t\tvar label = document.createElement('div');\n\t\t\t\t\t\tvar noTickPositionsSpecified = this.options.ticks_positions.length === 0;\n\t\t\t\t\t\tvar tickLabelsIndex = (this.options.reversed && noTickPositionsSpecified) ? (this.options.ticks_labels.length - (i + 1)) : i;\n\t\t\t\t\t\tlabel.className = 'slider-tick-label';\n\t\t\t\t\t\tlabel.innerHTML = this.options.ticks_labels[tickLabelsIndex];\n\n\t\t\t\t\t\tthis.tickLabels.push(label);\n\t\t\t\t\t\tthis.tickLabelContainer.appendChild(label);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\n\t\t\t\tvar createAndAppendTooltipSubElements = function(tooltipElem) {\n\t\t\t\t\tvar arrow = document.createElement(\"div\");\n\t\t\t\t\tarrow.className = \"tooltip-arrow\";\n\n\t\t\t\t\tvar inner = document.createElement(\"div\");\n\t\t\t\t\tinner.className = \"tooltip-inner\";\n\n\t\t\t\t\ttooltipElem.appendChild(arrow);\n\t\t\t\t\ttooltipElem.appendChild(inner);\n\n\t\t\t\t};\n\n\t\t\t\t/* Create tooltip elements */\n\t\t\t\tvar sliderTooltip = document.createElement(\"div\");\n\t\t\t\tsliderTooltip.className = \"tooltip tooltip-main\";\n\t\t\t\tsliderTooltip.setAttribute('role', 'presentation');\n\t\t\t\tcreateAndAppendTooltipSubElements(sliderTooltip);\n\n\t\t\t\tvar sliderTooltipMin = document.createElement(\"div\");\n\t\t\t\tsliderTooltipMin.className = \"tooltip tooltip-min\";\n\t\t\t\tsliderTooltipMin.setAttribute('role', 'presentation');\n\t\t\t\tcreateAndAppendTooltipSubElements(sliderTooltipMin);\n\n\t\t\t\tvar sliderTooltipMax = document.createElement(\"div\");\n\t\t\t\tsliderTooltipMax.className = \"tooltip tooltip-max\";\n\t\t\t\tsliderTooltipMax.setAttribute('role', 'presentation');\n\t\t\t\tcreateAndAppendTooltipSubElements(sliderTooltipMax);\n\n\n\t\t\t\t/* Append components to sliderElem */\n\t\t\t\tthis.sliderElem.appendChild(sliderTrack);\n\t\t\t\tthis.sliderElem.appendChild(sliderTooltip);\n\t\t\t\tthis.sliderElem.appendChild(sliderTooltipMin);\n\t\t\t\tthis.sliderElem.appendChild(sliderTooltipMax);\n\n\t\t\t\tif (this.tickLabelContainer) {\n\t\t\t\t\tthis.sliderElem.appendChild(this.tickLabelContainer);\n\t\t\t\t}\n\n\t\t\t\t/* Append slider element to parent container, right before the original <input> element */\n\t\t\t\tparent.insertBefore(this.sliderElem, this.element);\n\n\t\t\t\t/* Hide original <input> element */\n\t\t\t\tthis.element.style.display = \"none\";\n\t\t\t}\n\t\t\t/* If JQuery exists, cache JQ references */\n\t\t\tif($) {\n\t\t\t\tthis.$element = $(this.element);\n\t\t\t\tthis.$sliderElem = $(this.sliderElem);\n\t\t\t}\n\n\t\t\t/*************************************************\n\n\t\t\t\t\t\t\t\tSetup\n\n\t\t\t**************************************************/\n\t\t\tthis.eventToCallbackMap = {};\n\t\t\tthis.sliderElem.id = this.options.id;\n\n\t\t\tthis.touchCapable = 'ontouchstart' in window || (window.DocumentTouch && document instanceof window.DocumentTouch);\n\n\t\t\tthis.tooltip = this.sliderElem.querySelector('.tooltip-main');\n\t\t\tthis.tooltipInner = this.tooltip.querySelector('.tooltip-inner');\n\n\t\t\tthis.tooltip_min = this.sliderElem.querySelector('.tooltip-min');\n\t\t\tthis.tooltipInner_min = this.tooltip_min.querySelector('.tooltip-inner');\n\n\t\t\tthis.tooltip_max = this.sliderElem.querySelector('.tooltip-max');\n\t\t\tthis.tooltipInner_max= this.tooltip_max.querySelector('.tooltip-inner');\n\n\t\t\tif (SliderScale[this.options.scale]) {\n\t\t\t\tthis.options.scale = SliderScale[this.options.scale];\n\t\t\t}\n\n\t\t\tif (updateSlider === true) {\n\t\t\t\t// Reset classes\n\t\t\t\tthis._removeClass(this.sliderElem, 'slider-horizontal');\n\t\t\t\tthis._removeClass(this.sliderElem, 'slider-vertical');\n\t\t\t\tthis._removeClass(this.tooltip, 'hide');\n\t\t\t\tthis._removeClass(this.tooltip_min, 'hide');\n\t\t\t\tthis._removeClass(this.tooltip_max, 'hide');\n\n\t\t\t\t// Undo existing inline styles for track\n\t\t\t\t[\"left\", \"top\", \"width\", \"height\"].forEach(function(prop) {\n\t\t\t\t\tthis._removeProperty(this.trackLow, prop);\n\t\t\t\t\tthis._removeProperty(this.trackSelection, prop);\n\t\t\t\t\tthis._removeProperty(this.trackHigh, prop);\n\t\t\t\t}, this);\n\n\t\t\t\t// Undo inline styles on handles\n\t\t\t\t[this.handle1, this.handle2].forEach(function(handle) {\n\t\t\t\t\tthis._removeProperty(handle, 'left');\n\t\t\t\t\tthis._removeProperty(handle, 'top');\n\t\t\t\t}, this);\n\n\t\t\t\t// Undo inline styles and classes on tooltips\n\t\t\t\t[this.tooltip, this.tooltip_min, this.tooltip_max].forEach(function(tooltip) {\n\t\t\t\t\tthis._removeProperty(tooltip, 'left');\n\t\t\t\t\tthis._removeProperty(tooltip, 'top');\n\t\t\t\t\tthis._removeProperty(tooltip, 'margin-left');\n\t\t\t\t\tthis._removeProperty(tooltip, 'margin-top');\n\n\t\t\t\t\tthis._removeClass(tooltip, 'right');\n\t\t\t\t\tthis._removeClass(tooltip, 'top');\n\t\t\t\t}, this);\n\t\t\t}\n\n\t\t\tif(this.options.orientation === 'vertical') {\n\t\t\t\tthis._addClass(this.sliderElem,'slider-vertical');\n\t\t\t\tthis.stylePos = 'top';\n\t\t\t\tthis.mousePos = 'pageY';\n\t\t\t\tthis.sizePos = 'offsetHeight';\n\t\t\t} else {\n\t\t\t\tthis._addClass(this.sliderElem, 'slider-horizontal');\n\t\t\t\tthis.sliderElem.style.width = origWidth;\n\t\t\t\tthis.options.orientation = 'horizontal';\n\t\t\t\tthis.stylePos = 'left';\n\t\t\t\tthis.mousePos = 'pageX';\n\t\t\t\tthis.sizePos = 'offsetWidth';\n\n\t\t\t}\n\t\t\tthis._setTooltipPosition();\n\t\t\t/* In case ticks are specified, overwrite the min and max bounds */\n\t\t\tif (Array.isArray(this.options.ticks) && this.options.ticks.length > 0) {\n\t\t\t\t\tthis.options.max = Math.max.apply(Math, this.options.ticks);\n\t\t\t\t\tthis.options.min = Math.min.apply(Math, this.options.ticks);\n\t\t\t}\n\n\t\t\tif (Array.isArray(this.options.value)) {\n\t\t\t\tthis.options.range = true;\n\t\t\t\tthis._state.value = this.options.value;\n\t\t\t}\n\t\t\telse if (this.options.range) {\n\t\t\t\t// User wants a range, but value is not an array\n\t\t\t\tthis._state.value = [this.options.value, this.options.max];\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis._state.value = this.options.value;\n\t\t\t}\n\n\t\t\tthis.trackLow = sliderTrackLow || this.trackLow;\n\t\t\tthis.trackSelection = sliderTrackSelection || this.trackSelection;\n\t\t\tthis.trackHigh = sliderTrackHigh || this.trackHigh;\n\n\t\t\tif (this.options.selection === 'none') {\n\t\t\t\tthis._addClass(this.trackLow, 'hide');\n\t\t\t\tthis._addClass(this.trackSelection, 'hide');\n\t\t\t\tthis._addClass(this.trackHigh, 'hide');\n\t\t\t}\n\n\t\t\tthis.handle1 = sliderMinHandle || this.handle1;\n\t\t\tthis.handle2 = sliderMaxHandle || this.handle2;\n\n\t\t\tif (updateSlider === true) {\n\t\t\t\t// Reset classes\n\t\t\t\tthis._removeClass(this.handle1, 'round triangle');\n\t\t\t\tthis._removeClass(this.handle2, 'round triangle hide');\n\n\t\t\t\tfor (i = 0; i < this.ticks.length; i++) {\n\t\t\t\t\tthis._removeClass(this.ticks[i], 'round triangle hide');\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar availableHandleModifiers = ['round', 'triangle', 'custom'];\n\t\t\tvar isValidHandleType = availableHandleModifiers.indexOf(this.options.handle) !== -1;\n\t\t\tif (isValidHandleType) {\n\t\t\t\tthis._addClass(this.handle1, this.options.handle);\n\t\t\t\tthis._addClass(this.handle2, this.options.handle);\n\n\t\t\t\tfor (i = 0; i < this.ticks.length; i++) {\n\t\t\t\t\tthis._addClass(this.ticks[i], this.options.handle);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis._state.offset = this._offset(this.sliderElem);\n\t\t\tthis._state.size = this.sliderElem[this.sizePos];\n\t\t\tthis.setValue(this._state.value);\n\n\t\t\t/******************************************\n\n\t\t\t\t\t\tBind Event Listeners\n\n\t\t\t******************************************/\n\n\t\t\t// Bind keyboard handlers\n\t\t\tthis.handle1Keydown = this._keydown.bind(this, 0);\n\t\t\tthis.handle1.addEventListener(\"keydown\", this.handle1Keydown, false);\n\n\t\t\tthis.handle2Keydown = this._keydown.bind(this, 1);\n\t\t\tthis.handle2.addEventListener(\"keydown\", this.handle2Keydown, false);\n\n\t\t\tthis.mousedown = this._mousedown.bind(this);\n\t\t\tif (this.touchCapable) {\n\t\t\t\t// Bind touch handlers\n\t\t\t\tthis.sliderElem.addEventListener(\"touchstart\", this.mousedown, false);\n\t\t\t}\n\t\t\tthis.sliderElem.addEventListener(\"mousedown\", this.mousedown, false);\n\n\n\t\t\t// Bind tooltip-related handlers\n\t\t\tif(this.options.tooltip === 'hide') {\n\t\t\t\tthis._addClass(this.tooltip, 'hide');\n\t\t\t\tthis._addClass(this.tooltip_min, 'hide');\n\t\t\t\tthis._addClass(this.tooltip_max, 'hide');\n\t\t\t}\n\t\t\telse if(this.options.tooltip === 'always') {\n\t\t\t\tthis._showTooltip();\n\t\t\t\tthis._alwaysShowTooltip = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.showTooltip = this._showTooltip.bind(this);\n\t\t\t\tthis.hideTooltip = this._hideTooltip.bind(this);\n\n\t\t\t\tthis.sliderElem.addEventListener(\"mouseenter\", this.showTooltip, false);\n\t\t\t\tthis.sliderElem.addEventListener(\"mouseleave\", this.hideTooltip, false);\n\n\t\t\t\tthis.handle1.addEventListener(\"focus\", this.showTooltip, false);\n\t\t\t\tthis.handle1.addEventListener(\"blur\", this.hideTooltip, false);\n\n\t\t\t\tthis.handle2.addEventListener(\"focus\", this.showTooltip, false);\n\t\t\t\tthis.handle2.addEventListener(\"blur\", this.hideTooltip, false);\n\t\t\t}\n\n\t\t\tif(this.options.enabled) {\n\t\t\t\tthis.enable();\n\t\t\t} else {\n\t\t\t\tthis.disable();\n\t\t\t}\n\t\t}\n\n\n\n\t\t/*************************************************\n\n\t\t\t\t\tINSTANCE PROPERTIES/METHODS\n\n\t\t- Any methods bound to the prototype are considered\n\t\tpart of the plugin's `public` interface\n\n\t\t**************************************************/\n\t\tSlider.prototype = {\n\t\t\t_init: function() {}, // NOTE: Must exist to support bridget\n\n\t\t\tconstructor: Slider,\n\n\t\t\tdefaultOptions: {\n\t\t\t\tid: \"\",\n\t\t\t  min: 0,\n\t\t\t\tmax: 10,\n\t\t\t\tstep: 1,\n\t\t\t\tprecision: 0,\n\t\t\t\torientation: 'horizontal',\n\t\t\t\tvalue: 5,\n\t\t\t\trange: false,\n\t\t\t\tselection: 'before',\n\t\t\t\ttooltip: 'show',\n\t\t\t\ttooltip_split: false,\n\t\t\t\thandle: 'round',\n\t\t\t\treversed: false,\n\t\t\t\tenabled: true,\n\t\t\t\tformatter: function(val) {\n\t\t\t\t\tif (Array.isArray(val)) {\n\t\t\t\t\t\treturn val[0] + \" : \" + val[1];\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn val;\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tnatural_arrow_keys: false,\n\t\t\t\tticks: [],\n\t\t\t\tticks_positions: [],\n\t\t\t\tticks_labels: [],\n\t\t\t\tticks_snap_bounds: 0,\n\t\t\t\tscale: 'linear',\n\t\t\t\tfocus: false,\n\t\t\t\ttooltip_position: null,\n\t\t\t\tlabelledby: null\n\t\t\t},\n\n\t\t\tgetElement: function() {\n\t\t\t\treturn this.sliderElem;\n\t\t\t},\n\n\t\t\tgetValue: function() {\n\t\t\t\tif (this.options.range) {\n\t\t\t\t\treturn this._state.value;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\treturn this._state.value[0];\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tsetValue: function(val, triggerSlideEvent, triggerChangeEvent) {\n\t\t\t\tif (!val) {\n\t\t\t\t\tval = 0;\n\t\t\t\t}\n\t\t\t\tvar oldValue = this.getValue();\n\t\t\t\tthis._state.value = this._validateInputValue(val);\n\t\t\t\tvar applyPrecision = this._applyPrecision.bind(this);\n\n\t\t\t\tif (this.options.range) {\n\t\t\t\t\tthis._state.value[0] = applyPrecision(this._state.value[0]);\n\t\t\t\t\tthis._state.value[1] = applyPrecision(this._state.value[1]);\n\n\t\t\t\t\tthis._state.value[0] = Math.max(this.options.min, Math.min(this.options.max, this._state.value[0]));\n\t\t\t\t\tthis._state.value[1] = Math.max(this.options.min, Math.min(this.options.max, this._state.value[1]));\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis._state.value = applyPrecision(this._state.value);\n\t\t\t\t\tthis._state.value = [ Math.max(this.options.min, Math.min(this.options.max, this._state.value))];\n\t\t\t\t\tthis._addClass(this.handle2, 'hide');\n\t\t\t\t\tif (this.options.selection === 'after') {\n\t\t\t\t\t\tthis._state.value[1] = this.options.max;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._state.value[1] = this.options.min;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (this.options.max > this.options.min) {\n\t\t\t\t\tthis._state.percentage = [\n\t\t\t\t\t\tthis._toPercentage(this._state.value[0]),\n\t\t\t\t\t\tthis._toPercentage(this._state.value[1]),\n\t\t\t\t\t\tthis.options.step * 100 / (this.options.max - this.options.min)\n\t\t\t\t\t];\n\t\t\t\t} else {\n\t\t\t\t\tthis._state.percentage = [0, 0, 100];\n\t\t\t\t}\n\n\t\t\t\tthis._layout();\n\t\t\t\tvar newValue = this.options.range ? this._state.value : this._state.value[0];\n\n\t\t\t\tif(triggerSlideEvent === true) {\n\t\t\t\t\tthis._trigger('slide', newValue);\n\t\t\t\t}\n\t\t\t\tif( (oldValue !== newValue) && (triggerChangeEvent === true) ) {\n\t\t\t\t\tthis._trigger('change', {\n\t\t\t\t\t\toldValue: oldValue,\n\t\t\t\t\t\tnewValue: newValue\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tthis._setDataVal(newValue);\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\tdestroy: function(){\n\t\t\t\t// Remove event handlers on slider elements\n\t\t\t\tthis._removeSliderEventHandlers();\n\n\t\t\t\t// Remove the slider from the DOM\n\t\t\t\tthis.sliderElem.parentNode.removeChild(this.sliderElem);\n\t\t\t\t/* Show original <input> element */\n\t\t\t\tthis.element.style.display = \"\";\n\n\t\t\t\t// Clear out custom event bindings\n\t\t\t\tthis._cleanUpEventCallbacksMap();\n\n\t\t\t\t// Remove data values\n\t\t\t\tthis.element.removeAttribute(\"data\");\n\n\t\t\t\t// Remove JQuery handlers/data\n\t\t\t\tif($) {\n\t\t\t\t\tthis._unbindJQueryEventHandlers();\n\t\t\t\t\tthis.$element.removeData('slider');\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tdisable: function() {\n\t\t\t\tthis._state.enabled = false;\n\t\t\t\tthis.handle1.removeAttribute(\"tabindex\");\n\t\t\t\tthis.handle2.removeAttribute(\"tabindex\");\n\t\t\t\tthis._addClass(this.sliderElem, 'slider-disabled');\n\t\t\t\tthis._trigger('slideDisabled');\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\tenable: function() {\n\t\t\t\tthis._state.enabled = true;\n\t\t\t\tthis.handle1.setAttribute(\"tabindex\", 0);\n\t\t\t\tthis.handle2.setAttribute(\"tabindex\", 0);\n\t\t\t\tthis._removeClass(this.sliderElem, 'slider-disabled');\n\t\t\t\tthis._trigger('slideEnabled');\n\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\ttoggle: function() {\n\t\t\t\tif(this._state.enabled) {\n\t\t\t\t\tthis.disable();\n\t\t\t\t} else {\n\t\t\t\t\tthis.enable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\tisEnabled: function() {\n\t\t\t\treturn this._state.enabled;\n\t\t\t},\n\n\t\t\ton: function(evt, callback) {\n\t\t\t\tthis._bindNonQueryEventHandler(evt, callback);\n\t\t\t\treturn this;\n\t\t\t},\n\n      off: function(evt, callback) {\n          if($) {\n              this.$element.off(evt, callback);\n              this.$sliderElem.off(evt, callback);\n          } else {\n              this._unbindNonQueryEventHandler(evt, callback);\n          }\n      },\n\n\t\t\tgetAttribute: function(attribute) {\n\t\t\t\tif(attribute) {\n\t\t\t\t\treturn this.options[attribute];\n\t\t\t\t} else {\n\t\t\t\t\treturn this.options;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tsetAttribute: function(attribute, value) {\n\t\t\t\tthis.options[attribute] = value;\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\trefresh: function() {\n\t\t\t\tthis._removeSliderEventHandlers();\n\t\t\t\tcreateNewSlider.call(this, this.element, this.options);\n\t\t\t\tif($) {\n\t\t\t\t\t// Bind new instance of slider to the element\n\t\t\t\t\t$.data(this.element, 'slider', this);\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\trelayout: function() {\n\t\t\t\tthis._layout();\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t/******************************+\n\n\t\t\t\t\t\tHELPERS\n\n\t\t\t- Any method that is not part of the public interface.\n\t\t\t- Place it underneath this comment block and write its signature like so:\n\n\t\t\t  \t\t\t\t\t_fnName : function() {...}\n\n\t\t\t********************************/\n\t\t\t_removeSliderEventHandlers: function() {\n\t\t\t\t// Remove keydown event listeners\n\t\t\t\tthis.handle1.removeEventListener(\"keydown\", this.handle1Keydown, false);\n\t\t\t\tthis.handle2.removeEventListener(\"keydown\", this.handle2Keydown, false);\n\n\t\t\t\tif (this.showTooltip) {\n\t\t\t\t\tthis.handle1.removeEventListener(\"focus\", this.showTooltip, false);\n\t\t\t\t\tthis.handle2.removeEventListener(\"focus\", this.showTooltip, false);\n\t\t\t\t}\n\t\t\t\tif (this.hideTooltip) {\n\t\t\t\t\tthis.handle1.removeEventListener(\"blur\", this.hideTooltip, false);\n\t\t\t\t\tthis.handle2.removeEventListener(\"blur\", this.hideTooltip, false);\n\t\t\t\t}\n\n\t\t\t\t// Remove event listeners from sliderElem\n\t\t\t\tif (this.showTooltip) {\n\t\t\t\t\tthis.sliderElem.removeEventListener(\"mouseenter\", this.showTooltip, false);\n\t\t\t\t}\n\t\t\t\tif (this.hideTooltip) {\n\t\t\t\t\tthis.sliderElem.removeEventListener(\"mouseleave\", this.hideTooltip, false);\n\t\t\t\t}\n\t\t\t\tthis.sliderElem.removeEventListener(\"touchstart\", this.mousedown, false);\n\t\t\t\tthis.sliderElem.removeEventListener(\"mousedown\", this.mousedown, false);\n\t\t\t},\n\t\t\t_bindNonQueryEventHandler: function(evt, callback) {\n\t\t\t\tif(this.eventToCallbackMap[evt] === undefined) {\n\t\t\t\t\tthis.eventToCallbackMap[evt] = [];\n\t\t\t\t}\n\t\t\t\tthis.eventToCallbackMap[evt].push(callback);\n\t\t\t},\n      _unbindNonQueryEventHandler: function(evt, callback) {\n          var callbacks = this.eventToCallbackMap[evt];\n          if(callbacks !== undefined) {\n              for (var i = 0; i < callbacks.length; i++) {\n                  if (callbacks[i] === callback) {\n                      callbacks.splice(i, 1);\n                      break;\n                  }\n              }\n          }\n      },\n\t\t\t_cleanUpEventCallbacksMap: function() {\n\t\t\t\tvar eventNames = Object.keys(this.eventToCallbackMap);\n\t\t\t\tfor(var i = 0; i < eventNames.length; i++) {\n\t\t\t\t\tvar eventName = eventNames[i];\n\t\t\t\t\tthis.eventToCallbackMap[eventName] = null;\n\t\t\t\t}\n\t\t\t},\n\t\t\t_showTooltip: function() {\n\t\t\t\tif (this.options.tooltip_split === false ){\n        \tthis._addClass(this.tooltip, 'in');\n        \tthis.tooltip_min.style.display = 'none';\n        \tthis.tooltip_max.style.display = 'none';\n\t\t    } else {\n          this._addClass(this.tooltip_min, 'in');\n          this._addClass(this.tooltip_max, 'in');\n          this.tooltip.style.display = 'none';\n\t\t    }\n\t\t\t\tthis._state.over = true;\n\t\t\t},\n\t\t\t_hideTooltip: function() {\n\t\t\t\tif (this._state.inDrag === false && this.alwaysShowTooltip !== true) {\n\t\t\t\t\tthis._removeClass(this.tooltip, 'in');\n\t\t\t\t\tthis._removeClass(this.tooltip_min, 'in');\n\t\t\t\t\tthis._removeClass(this.tooltip_max, 'in');\n\t\t\t\t}\n\t\t\t\tthis._state.over = false;\n\t\t\t},\n\t\t\t_layout: function() {\n\t\t\t\tvar positionPercentages;\n\n\t\t\t\tif(this.options.reversed) {\n\t\t\t\t\tpositionPercentages = [ 100 - this._state.percentage[0], this.options.range ? 100 - this._state.percentage[1] : this._state.percentage[1]];\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tpositionPercentages = [ this._state.percentage[0], this._state.percentage[1] ];\n\t\t\t\t}\n\n\t\t\t\tthis.handle1.style[this.stylePos] = positionPercentages[0]+'%';\n\t\t\t\tthis.handle1.setAttribute('aria-valuenow', this._state.value[0]);\n\n\t\t\t\tthis.handle2.style[this.stylePos] = positionPercentages[1]+'%';\n\t\t\t\tthis.handle2.setAttribute('aria-valuenow', this._state.value[1]);\n\n\t\t\t\t/* Position ticks and labels */\n\t\t\t\tif (Array.isArray(this.options.ticks) && this.options.ticks.length > 0) {\n\n\t\t\t\t\tvar styleSize = this.options.orientation === 'vertical' ? 'height' : 'width';\n\t\t\t\t\tvar styleMargin = this.options.orientation === 'vertical' ? 'marginTop' : 'marginLeft';\n\t\t\t\t\tvar labelSize = this._state.size / (this.options.ticks.length - 1);\n\n\t\t\t\t\tif (this.tickLabelContainer) {\n\t\t\t\t\t\tvar extraMargin = 0;\n\t\t\t\t\t\tif (this.options.ticks_positions.length === 0) {\n\t\t\t\t\t\t\tif (this.options.orientation !== 'vertical') {\n\t\t\t\t\t\t\t\tthis.tickLabelContainer.style[styleMargin] = -labelSize/2 + 'px';\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\textraMargin = this.tickLabelContainer.offsetHeight;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t/* Chidren are position absolute, calculate height by finding the max offsetHeight of a child */\n\t\t\t\t\t\t\tfor (i = 0 ; i < this.tickLabelContainer.childNodes.length; i++) {\n\t\t\t\t\t\t\t\tif (this.tickLabelContainer.childNodes[i].offsetHeight > extraMargin) {\n\t\t\t\t\t\t\t\t\textraMargin = this.tickLabelContainer.childNodes[i].offsetHeight;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (this.options.orientation === 'horizontal') {\n\t\t\t\t\t\t\tthis.sliderElem.style.marginBottom = extraMargin + 'px';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor (var i = 0; i < this.options.ticks.length; i++) {\n\n\t\t\t\t\t\tvar percentage = this.options.ticks_positions[i] || this._toPercentage(this.options.ticks[i]);\n\n\t\t\t\t\t\tif (this.options.reversed) {\n\t\t\t\t\t\t\tpercentage = 100 - percentage;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tthis.ticks[i].style[this.stylePos] = percentage + '%';\n\n\t\t\t\t\t\t/* Set class labels to denote whether ticks are in the selection */\n\t\t\t\t\t\tthis._removeClass(this.ticks[i], 'in-selection');\n\t\t\t\t\t\tif (!this.options.range) {\n\t\t\t\t\t\t\tif (this.options.selection === 'after' && percentage >= positionPercentages[0]){\n\t\t\t\t\t\t\t\tthis._addClass(this.ticks[i], 'in-selection');\n\t\t\t\t\t\t\t} else if (this.options.selection === 'before' && percentage <= positionPercentages[0]) {\n\t\t\t\t\t\t\t\tthis._addClass(this.ticks[i], 'in-selection');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (percentage >= positionPercentages[0] && percentage <= positionPercentages[1]) {\n\t\t\t\t\t\t\tthis._addClass(this.ticks[i], 'in-selection');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (this.tickLabels[i]) {\n\t\t\t\t\t\t\tthis.tickLabels[i].style[styleSize] = labelSize + 'px';\n\n\t\t\t\t\t\t\tif (this.options.orientation !== 'vertical' && this.options.ticks_positions[i] !== undefined) {\n\t\t\t\t\t\t\t\tthis.tickLabels[i].style.position = 'absolute';\n\t\t\t\t\t\t\t\tthis.tickLabels[i].style[this.stylePos] = percentage + '%';\n\t\t\t\t\t\t\t\tthis.tickLabels[i].style[styleMargin] = -labelSize/2 + 'px';\n\t\t\t\t\t\t\t} else if (this.options.orientation === 'vertical') {\n\t\t\t\t\t\t\t\tthis.tickLabels[i].style['marginLeft'] =  this.sliderElem.offsetWidth + 'px';\n\t\t\t\t\t\t\t\tthis.tickLabelContainer.style['marginTop'] = this.sliderElem.offsetWidth / 2 * -1 + 'px';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar formattedTooltipVal;\n\n\t\t\t\tif (this.options.range) {\n\t\t\t\t\tformattedTooltipVal = this.options.formatter(this._state.value);\n\t\t\t\t\tthis._setText(this.tooltipInner, formattedTooltipVal);\n\t\t\t\t\tthis.tooltip.style[this.stylePos] = (positionPercentages[1] + positionPercentages[0])/2 + '%';\n\n\t\t\t\t\tif (this.options.orientation === 'vertical') {\n\t\t\t\t\t\tthis._css(this.tooltip, 'margin-top', -this.tooltip.offsetHeight / 2 + 'px');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._css(this.tooltip, 'margin-left', -this.tooltip.offsetWidth / 2 + 'px');\n\t\t\t\t\t}\n\n\t\t\t\t\tif (this.options.orientation === 'vertical') {\n\t\t\t\t\t\tthis._css(this.tooltip, 'margin-top', -this.tooltip.offsetHeight / 2 + 'px');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._css(this.tooltip, 'margin-left', -this.tooltip.offsetWidth / 2 + 'px');\n\t\t\t\t\t}\n\n\t\t\t\t\tvar innerTooltipMinText = this.options.formatter(this._state.value[0]);\n\t\t\t\t\tthis._setText(this.tooltipInner_min, innerTooltipMinText);\n\n\t\t\t\t\tvar innerTooltipMaxText = this.options.formatter(this._state.value[1]);\n\t\t\t\t\tthis._setText(this.tooltipInner_max, innerTooltipMaxText);\n\n\t\t\t\t\tthis.tooltip_min.style[this.stylePos] = positionPercentages[0] + '%';\n\n\t\t\t\t\tif (this.options.orientation === 'vertical') {\n\t\t\t\t\t\tthis._css(this.tooltip_min, 'margin-top', -this.tooltip_min.offsetHeight / 2 + 'px');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._css(this.tooltip_min, 'margin-left', -this.tooltip_min.offsetWidth / 2 + 'px');\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.tooltip_max.style[this.stylePos] = positionPercentages[1] + '%';\n\n\t\t\t\t\tif (this.options.orientation === 'vertical') {\n\t\t\t\t\t\tthis._css(this.tooltip_max, 'margin-top', -this.tooltip_max.offsetHeight / 2 + 'px');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._css(this.tooltip_max, 'margin-left', -this.tooltip_max.offsetWidth / 2 + 'px');\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tformattedTooltipVal = this.options.formatter(this._state.value[0]);\n\t\t\t\t\tthis._setText(this.tooltipInner, formattedTooltipVal);\n\n\t\t\t\t\tthis.tooltip.style[this.stylePos] = positionPercentages[0] + '%';\n\t\t\t\t\tif (this.options.orientation === 'vertical') {\n\t\t\t\t\t\tthis._css(this.tooltip, 'margin-top', -this.tooltip.offsetHeight / 2 + 'px');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._css(this.tooltip, 'margin-left', -this.tooltip.offsetWidth / 2 + 'px');\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (this.options.orientation === 'vertical') {\n\t\t\t\t\tthis.trackLow.style.top = '0';\n\t\t\t\t\tthis.trackLow.style.height = Math.min(positionPercentages[0], positionPercentages[1]) +'%';\n\n\t\t\t\t\tthis.trackSelection.style.top = Math.min(positionPercentages[0], positionPercentages[1]) +'%';\n\t\t\t\t\tthis.trackSelection.style.height = Math.abs(positionPercentages[0] - positionPercentages[1]) +'%';\n\n\t\t\t\t\tthis.trackHigh.style.bottom = '0';\n\t\t\t\t\tthis.trackHigh.style.height = (100 - Math.min(positionPercentages[0], positionPercentages[1]) - Math.abs(positionPercentages[0] - positionPercentages[1])) +'%';\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tthis.trackLow.style.left = '0';\n\t\t\t\t\tthis.trackLow.style.width = Math.min(positionPercentages[0], positionPercentages[1]) +'%';\n\n\t\t\t\t\tthis.trackSelection.style.left = Math.min(positionPercentages[0], positionPercentages[1]) +'%';\n\t\t\t\t\tthis.trackSelection.style.width = Math.abs(positionPercentages[0] - positionPercentages[1]) +'%';\n\n\t\t\t\t\tthis.trackHigh.style.right = '0';\n\t\t\t\t\tthis.trackHigh.style.width = (100 - Math.min(positionPercentages[0], positionPercentages[1]) - Math.abs(positionPercentages[0] - positionPercentages[1])) +'%';\n\n\t\t\t        var offset_min = this.tooltip_min.getBoundingClientRect();\n\t\t\t        var offset_max = this.tooltip_max.getBoundingClientRect();\n\n\t\t\t        if (offset_min.right > offset_max.left) {\n\t\t\t            this._removeClass(this.tooltip_max, 'top');\n\t\t\t            this._addClass(this.tooltip_max, 'bottom');\n\t\t\t            this.tooltip_max.style.top = 18 + 'px';\n\t\t\t        } else {\n\t\t\t            this._removeClass(this.tooltip_max, 'bottom');\n\t\t\t            this._addClass(this.tooltip_max, 'top');\n\t\t\t            this.tooltip_max.style.top = this.tooltip_min.style.top;\n\t\t\t        }\n\t\t\t\t}\n\t\t\t},\n\t\t\t_removeProperty: function(element, prop) {\n\t\t\t\tif (element.style.removeProperty) {\n\t\t\t\t    element.style.removeProperty(prop);\n\t\t\t\t} else {\n\t\t\t\t    element.style.removeAttribute(prop);\n\t\t\t\t}\n\t\t\t},\n\t\t\t_mousedown: function(ev) {\n\t\t\t\tif(!this._state.enabled) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tthis._state.offset = this._offset(this.sliderElem);\n\t\t\t\tthis._state.size = this.sliderElem[this.sizePos];\n\n\t\t\t\tvar percentage = this._getPercentage(ev);\n\n\t\t\t\tif (this.options.range) {\n\t\t\t\t\tvar diff1 = Math.abs(this._state.percentage[0] - percentage);\n\t\t\t\t\tvar diff2 = Math.abs(this._state.percentage[1] - percentage);\n\t\t\t\t\tthis._state.dragged = (diff1 < diff2) ? 0 : 1;\n\t\t\t\t} else {\n\t\t\t\t\tthis._state.dragged = 0;\n\t\t\t\t}\n\n\t\t\t\tthis._state.percentage[this._state.dragged] = percentage;\n\t\t\t\tthis._layout();\n\n\t\t\t\tif (this.touchCapable) {\n\t\t\t\t\tdocument.removeEventListener(\"touchmove\", this.mousemove, false);\n\t\t\t\t\tdocument.removeEventListener(\"touchend\", this.mouseup, false);\n\t\t\t\t}\n\n\t\t\t\tif(this.mousemove){\n\t\t\t\t\tdocument.removeEventListener(\"mousemove\", this.mousemove, false);\n\t\t\t\t}\n\t\t\t\tif(this.mouseup){\n\t\t\t\t\tdocument.removeEventListener(\"mouseup\", this.mouseup, false);\n\t\t\t\t}\n\n\t\t\t\tthis.mousemove = this._mousemove.bind(this);\n\t\t\t\tthis.mouseup = this._mouseup.bind(this);\n\n\t\t\t\tif (this.touchCapable) {\n\t\t\t\t\t// Touch: Bind touch events:\n\t\t\t\t\tdocument.addEventListener(\"touchmove\", this.mousemove, false);\n\t\t\t\t\tdocument.addEventListener(\"touchend\", this.mouseup, false);\n\t\t\t\t}\n\t\t\t\t// Bind mouse events:\n\t\t\t\tdocument.addEventListener(\"mousemove\", this.mousemove, false);\n\t\t\t\tdocument.addEventListener(\"mouseup\", this.mouseup, false);\n\n\t\t\t\tthis._state.inDrag = true;\n\t\t\t\tvar newValue = this._calculateValue();\n\n\t\t\t\tthis._trigger('slideStart', newValue);\n\n\t\t\t\tthis._setDataVal(newValue);\n\t\t\t\tthis.setValue(newValue, false, true);\n\n\t\t\t\tthis._pauseEvent(ev);\n\n\t\t\t\tif (this.options.focus) {\n\t\t\t\t\tthis._triggerFocusOnHandle(this._state.dragged);\n\t\t\t\t}\n\n\t\t\t\treturn true;\n\t\t\t},\n\t\t\t_triggerFocusOnHandle: function(handleIdx) {\n\t\t\t\tif(handleIdx === 0) {\n\t\t\t\t\tthis.handle1.focus();\n\t\t\t\t}\n\t\t\t\tif(handleIdx === 1) {\n\t\t\t\t\tthis.handle2.focus();\n\t\t\t\t}\n\t\t\t},\n\t\t\t_keydown: function(handleIdx, ev) {\n\t\t\t\tif(!this._state.enabled) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tvar dir;\n\t\t\t\tswitch (ev.keyCode) {\n\t\t\t\t\tcase 37: // left\n\t\t\t\t\tcase 40: // down\n\t\t\t\t\t\tdir = -1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 39: // right\n\t\t\t\t\tcase 38: // up\n\t\t\t\t\t\tdir = 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (!dir) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// use natural arrow keys instead of from min to max\n\t\t\t\tif (this.options.natural_arrow_keys) {\n\t\t\t\t\tvar ifVerticalAndNotReversed = (this.options.orientation === 'vertical' && !this.options.reversed);\n\t\t\t\t\tvar ifHorizontalAndReversed = (this.options.orientation === 'horizontal' && this.options.reversed);\n\n\t\t\t\t\tif (ifVerticalAndNotReversed || ifHorizontalAndReversed) {\n\t\t\t\t\t\tdir = -dir;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tvar val = this._state.value[handleIdx] + dir * this.options.step;\n\t\t\t\tif (this.options.range) {\n\t\t\t\t\tval = [ (!handleIdx) ? val : this._state.value[0],\n\t\t\t\t\t\t    ( handleIdx) ? val : this._state.value[1]];\n\t\t\t\t}\n\n\t\t\t\tthis._trigger('slideStart', val);\n\t\t\t\tthis._setDataVal(val);\n\t\t\t\tthis.setValue(val, true, true);\n\n\t\t\t\tthis._setDataVal(val);\n\t\t\t\tthis._trigger('slideStop', val);\n\t\t\t\tthis._layout();\n\n\t\t\t\tthis._pauseEvent(ev);\n\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\t_pauseEvent: function(ev) {\n\t\t\t\tif(ev.stopPropagation) {\n\t\t\t\t\tev.stopPropagation();\n\t\t\t\t}\n\t\t\t    if(ev.preventDefault) {\n\t\t\t    \tev.preventDefault();\n\t\t\t    }\n\t\t\t    ev.cancelBubble=true;\n\t\t\t    ev.returnValue=false;\n\t\t\t},\n\t\t\t_mousemove: function(ev) {\n\t\t\t\tif(!this._state.enabled) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tvar percentage = this._getPercentage(ev);\n\t\t\t\tthis._adjustPercentageForRangeSliders(percentage);\n\t\t\t\tthis._state.percentage[this._state.dragged] = percentage;\n\t\t\t\tthis._layout();\n\n\t\t\t\tvar val = this._calculateValue(true);\n\t\t\t\tthis.setValue(val, true, true);\n\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\t_adjustPercentageForRangeSliders: function(percentage) {\n\t\t\t\tif (this.options.range) {\n\t\t\t\t\tvar precision = this._getNumDigitsAfterDecimalPlace(percentage);\n\t\t\t\t\tprecision = precision ? precision - 1 : 0;\n\t\t\t\t\tvar percentageWithAdjustedPrecision = this._applyToFixedAndParseFloat(percentage, precision);\n\t\t\t\t\tif (this._state.dragged === 0 && this._applyToFixedAndParseFloat(this._state.percentage[1], precision) < percentageWithAdjustedPrecision) {\n\t\t\t\t\t\tthis._state.percentage[0] = this._state.percentage[1];\n\t\t\t\t\t\tthis._state.dragged = 1;\n\t\t\t\t\t} else if (this._state.dragged === 1 && this._applyToFixedAndParseFloat(this._state.percentage[0], precision) > percentageWithAdjustedPrecision) {\n\t\t\t\t\t\tthis._state.percentage[1] = this._state.percentage[0];\n\t\t\t\t\t\tthis._state.dragged = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t_mouseup: function() {\n\t\t\t\tif(!this._state.enabled) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif (this.touchCapable) {\n\t\t\t\t\t// Touch: Unbind touch event handlers:\n\t\t\t\t\tdocument.removeEventListener(\"touchmove\", this.mousemove, false);\n\t\t\t\t\tdocument.removeEventListener(\"touchend\", this.mouseup, false);\n\t\t\t\t}\n                // Unbind mouse event handlers:\n                document.removeEventListener(\"mousemove\", this.mousemove, false);\n                document.removeEventListener(\"mouseup\", this.mouseup, false);\n\n\t\t\t\tthis._state.inDrag = false;\n\t\t\t\tif (this._state.over === false) {\n\t\t\t\t\tthis._hideTooltip();\n\t\t\t\t}\n\t\t\t\tvar val = this._calculateValue(true);\n\n\t\t\t\tthis._layout();\n\t\t\t\tthis._setDataVal(val);\n\t\t\t\tthis._trigger('slideStop', val);\n\n\t\t\t\treturn false;\n\t\t\t},\n\t\t\t_calculateValue: function(snapToClosestTick) {\n\t\t\t\tvar val;\n\t\t\t\tif (this.options.range) {\n\t\t\t\t\tval = [this.options.min,this.options.max];\n\t\t\t        if (this._state.percentage[0] !== 0){\n\t\t\t            val[0] = this._toValue(this._state.percentage[0]);\n\t\t\t            val[0] = this._applyPrecision(val[0]);\n\t\t\t        }\n\t\t\t        if (this._state.percentage[1] !== 100){\n\t\t\t            val[1] = this._toValue(this._state.percentage[1]);\n\t\t\t            val[1] = this._applyPrecision(val[1]);\n\t\t\t        }\n\t\t\t\t} else {\n\t\t            val = this._toValue(this._state.percentage[0]);\n\t\t\t\t\tval = parseFloat(val);\n\t\t\t\t\tval = this._applyPrecision(val);\n\t\t\t\t}\n\n\t\t\t\tif (snapToClosestTick) {\n\t\t\t\t\tvar min = [val, Infinity];\n\t\t\t\t\tfor (var i = 0; i < this.options.ticks.length; i++) {\n\t\t\t\t\t\tvar diff = Math.abs(this.options.ticks[i] - val);\n\t\t\t\t\t\tif (diff <= min[1]) {\n\t\t\t\t\t\t\tmin = [this.options.ticks[i], diff];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (min[1] <= this.options.ticks_snap_bounds) {\n\t\t\t\t\t\treturn min[0];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn val;\n\t\t\t},\n\t\t\t_applyPrecision: function(val) {\n\t\t\t\tvar precision = this.options.precision || this._getNumDigitsAfterDecimalPlace(this.options.step);\n\t\t\t\treturn this._applyToFixedAndParseFloat(val, precision);\n\t\t\t},\n\t\t\t_getNumDigitsAfterDecimalPlace: function(num) {\n\t\t\t\tvar match = (''+num).match(/(?:\\.(\\d+))?(?:[eE]([+-]?\\d+))?$/);\n\t\t\t\tif (!match) { return 0; }\n\t\t\t\treturn Math.max(0, (match[1] ? match[1].length : 0) - (match[2] ? +match[2] : 0));\n\t\t\t},\n\t\t\t_applyToFixedAndParseFloat: function(num, toFixedInput) {\n\t\t\t\tvar truncatedNum = num.toFixed(toFixedInput);\n\t\t\t\treturn parseFloat(truncatedNum);\n\t\t\t},\n\t\t\t/*\n\t\t\t\tCredits to Mike Samuel for the following method!\n\t\t\t\tSource: http://stackoverflow.com/questions/10454518/javascript-how-to-retrieve-the-number-of-decimals-of-a-string-number\n\t\t\t*/\n\t\t\t_getPercentage: function(ev) {\n\t\t\t\tif (this.touchCapable && (ev.type === 'touchstart' || ev.type === 'touchmove')) {\n\t\t\t\t\tev = ev.touches[0];\n\t\t\t\t}\n\n\t\t\t\tvar eventPosition = ev[this.mousePos];\n\t\t\t\tvar sliderOffset = this._state.offset[this.stylePos];\n\t\t\t\tvar distanceToSlide = eventPosition - sliderOffset;\n\t\t\t\t// Calculate what percent of the length the slider handle has slid\n\t\t\t\tvar percentage = (distanceToSlide / this._state.size) * 100;\n\t\t\t\tpercentage = Math.round(percentage / this._state.percentage[2]) * this._state.percentage[2];\n\t\t\t\tif (this.options.reversed) {\n\t\t\t\t\tpercentage = 100 - percentage;\n\t\t\t\t}\n\n\t\t\t\t// Make sure the percent is within the bounds of the slider.\n\t\t\t\t// 0% corresponds to the 'min' value of the slide\n\t\t\t\t// 100% corresponds to the 'max' value of the slide\n\t\t\t\treturn Math.max(0, Math.min(100, percentage));\n\t\t\t},\n\t\t\t_validateInputValue: function(val) {\n\t\t\t\tif (typeof val === 'number') {\n\t\t\t\t\treturn val;\n\t\t\t\t} else if (Array.isArray(val)) {\n\t\t\t\t\tthis._validateArray(val);\n\t\t\t\t\treturn val;\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error( ErrorMsgs.formatInvalidInputErrorMsg(val) );\n\t\t\t\t}\n\t\t\t},\n\t\t\t_validateArray: function(val) {\n\t\t\t\tfor(var i = 0; i < val.length; i++) {\n\t\t\t\t\tvar input =  val[i];\n\t\t\t\t\tif (typeof input !== 'number') { throw new Error( ErrorMsgs.formatInvalidInputErrorMsg(input) ); }\n\t\t\t\t}\n\t\t\t},\n\t\t\t_setDataVal: function(val) {\n\t\t\t\tthis.element.setAttribute('data-value', val);\n\t\t\t\tthis.element.setAttribute('value', val);\n        this.element.value = val;\n\t\t\t},\n\t\t\t_trigger: function(evt, val) {\n\t\t\t\tval = (val || val === 0) ? val : undefined;\n\n\t\t\t\tvar callbackFnArray = this.eventToCallbackMap[evt];\n\t\t\t\tif(callbackFnArray && callbackFnArray.length) {\n\t\t\t\t\tfor(var i = 0; i < callbackFnArray.length; i++) {\n\t\t\t\t\t\tvar callbackFn = callbackFnArray[i];\n\t\t\t\t\t\tcallbackFn(val);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* If JQuery exists, trigger JQuery events */\n\t\t\t\tif($) {\n\t\t\t\t\tthis._triggerJQueryEvent(evt, val);\n\t\t\t\t}\n\t\t\t},\n\t\t\t_triggerJQueryEvent: function(evt, val) {\n\t\t\t\tvar eventData = {\n\t\t\t\t\ttype: evt,\n\t\t\t\t\tvalue: val\n\t\t\t\t};\n\t\t\t\tthis.$element.trigger(eventData);\n\t\t\t\tthis.$sliderElem.trigger(eventData);\n\t\t\t},\n\t\t\t_unbindJQueryEventHandlers: function() {\n\t\t\t\tthis.$element.off();\n\t\t\t\tthis.$sliderElem.off();\n\t\t\t},\n\t\t\t_setText: function(element, text) {\n\t\t\t\tif(typeof element.innerText !== \"undefined\") {\n\t\t\t \t\telement.innerText = text;\n\t\t\t \t} else if(typeof element.textContent !== \"undefined\") {\n\t\t\t \t\telement.textContent = text;\n\t\t\t \t}\n\t\t\t},\n\t\t\t_removeClass: function(element, classString) {\n\t\t\t\tvar classes = classString.split(\" \");\n\t\t\t\tvar newClasses = element.className;\n\n\t\t\t\tfor(var i = 0; i < classes.length; i++) {\n\t\t\t\t\tvar classTag = classes[i];\n\t\t\t\t\tvar regex = new RegExp(\"(?:\\\\s|^)\" + classTag + \"(?:\\\\s|$)\");\n\t\t\t\t\tnewClasses = newClasses.replace(regex, \" \");\n\t\t\t\t}\n\n\t\t\t\telement.className = newClasses.trim();\n\t\t\t},\n\t\t\t_addClass: function(element, classString) {\n\t\t\t\tvar classes = classString.split(\" \");\n\t\t\t\tvar newClasses = element.className;\n\n\t\t\t\tfor(var i = 0; i < classes.length; i++) {\n\t\t\t\t\tvar classTag = classes[i];\n\t\t\t\t\tvar regex = new RegExp(\"(?:\\\\s|^)\" + classTag + \"(?:\\\\s|$)\");\n\t\t\t\t\tvar ifClassExists = regex.test(newClasses);\n\n\t\t\t\t\tif(!ifClassExists) {\n\t\t\t\t\t\tnewClasses += \" \" + classTag;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\telement.className = newClasses.trim();\n\t\t\t},\n\t\t\t_offsetLeft: function(obj){\n\t\t\t\treturn obj.getBoundingClientRect().left;\n\t\t\t},\n\t\t\t_offsetTop: function(obj){\n\t\t\t\tvar offsetTop = obj.offsetTop;\n\t\t\t\twhile((obj = obj.offsetParent) && !isNaN(obj.offsetTop)){\n\t\t\t\t\toffsetTop += obj.offsetTop;\n\t\t\t\t}\n\t\t\t\treturn offsetTop;\n\t\t\t},\n\t\t    _offset: function (obj) {\n\t\t\t\treturn {\n\t\t\t\t\tleft: this._offsetLeft(obj),\n\t\t\t\t\ttop: this._offsetTop(obj)\n\t\t\t\t};\n\t\t    },\n\t\t\t_css: function(elementRef, styleName, value) {\n                if ($) {\n                    $.style(elementRef, styleName, value);\n                } else {\n                    var style = styleName.replace(/^-ms-/, \"ms-\").replace(/-([\\da-z])/gi, function (all, letter) {\n                        return letter.toUpperCase();\n                    });\n                    elementRef.style[style] = value;\n                }\n\t\t\t},\n\t\t\t_toValue: function(percentage) {\n\t\t\t\treturn this.options.scale.toValue.apply(this, [percentage]);\n\t\t\t},\n\t\t\t_toPercentage: function(value) {\n\t\t\t\treturn this.options.scale.toPercentage.apply(this, [value]);\n\t\t\t},\n\t\t\t_setTooltipPosition: function(){\n\t\t\t\tvar tooltips = [this.tooltip, this.tooltip_min, this.tooltip_max];\n\t\t\t\tif (this.options.orientation === 'vertical'){\n\t\t\t\t\tvar tooltipPos = this.options.tooltip_position || 'right';\n\t\t\t\t\tvar oppositeSide = (tooltipPos === 'left') ? 'right' : 'left';\n\t\t\t\t\ttooltips.forEach(function(tooltip){\n\t\t\t\t\t\tthis._addClass(tooltip, tooltipPos);\n\t\t\t\t\t\ttooltip.style[oppositeSide] = '100%';\n\t\t\t\t\t}.bind(this));\n\t\t\t\t} else if(this.options.tooltip_position === 'bottom') {\n\t\t\t\t\ttooltips.forEach(function(tooltip){\n\t\t\t\t\t\tthis._addClass(tooltip, 'bottom');\n\t\t\t\t\t\ttooltip.style.top = 22 + 'px';\n\t\t\t\t\t}.bind(this));\n\t\t\t\t} else {\n\t\t\t\t\ttooltips.forEach(function(tooltip){\n\t\t\t\t\t\tthis._addClass(tooltip, 'top');\n\t\t\t\t\t\ttooltip.style.top = -this.tooltip.outerHeight - 14 + 'px';\n\t\t\t\t\t}.bind(this));\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t/*********************************\n\n\t\t\tAttach to global namespace\n\n\t\t*********************************/\n\t\tif($) {\n\t\t\tvar namespace = $.fn.slider ? 'bootstrapSlider' : 'slider';\n\t\t\t$.bridget(namespace, Slider);\n\t\t}\n\n\t})( $ );\n\n\treturn Slider;\n}));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-slider/slider.css",
    "content": "/*!\n * Slider for Bootstrap\n *\n * Copyright 2012 Stefan Petre\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n */\n.slider {\n    display: block;\n    vertical-align: middle;\n    position: relative;\n\n}\n.slider.slider-horizontal {\n    width: 100%;\n    height: 20px;\n    margin-bottom: 20px;\n}\n.slider.slider-horizontal:last-of-type {\n    margin-bottom: 0;\n}\n.slider.slider-horizontal .slider-track {\n    height: 10px;\n    width: 100%;\n    margin-top: -5px;\n    top: 50%;\n    left: 0;\n}\n.slider.slider-horizontal .slider-selection,\n.slider.slider-horizontal .slider-track-low,\n.slider.slider-horizontal .slider-track-high {\n    height: 100%;\n    top: 0;\n    bottom: 0;\n}\n.slider.slider-horizontal .slider-tick,\n.slider.slider-horizontal .slider-handle {\n    margin-left: -10px;\n    margin-top: -5px;\n}\n.slider.slider-horizontal .slider-tick.triangle,\n.slider.slider-horizontal .slider-handle.triangle {\n    border-width: 0 10px 10px 10px;\n    width: 0;\n    height: 0;\n    border-bottom-color: #0480be;\n    margin-top: 0;\n}\n.slider.slider-horizontal .slider-tick-label-container {\n    white-space: nowrap;\n    margin-top: 20px;\n}\n.slider.slider-horizontal .slider-tick-label-container .slider-tick-label {\n    padding-top: 4px;\n    display: inline-block;\n    text-align: center;\n}\n.slider.slider-vertical {\n    height: 230px;\n    width: 20px;\n    margin-right: 20px;\n    display: inline-block;\n}\n.slider.slider-vertical:last-of-type {\n    margin-right: 0;\n}\n.slider.slider-vertical .slider-track {\n    width: 10px;\n    height: 100%;\n    margin-left: -5px;\n    left: 50%;\n    top: 0;\n}\n.slider.slider-vertical .slider-selection {\n    width: 100%;\n    left: 0;\n    top: 0;\n    bottom: 0;\n}\n.slider.slider-vertical .slider-track-low,\n.slider.slider-vertical .slider-track-high {\n    width: 100%;\n    left: 0;\n    right: 0;\n}\n.slider.slider-vertical .slider-tick,\n.slider.slider-vertical .slider-handle {\n    margin-left: -5px;\n    margin-top: -10px;\n}\n.slider.slider-vertical .slider-tick.triangle,\n.slider.slider-vertical .slider-handle.triangle {\n    border-width: 10px 0 10px 10px;\n    width: 1px;\n    height: 1px;\n    border-left-color: #0480be;\n    margin-left: 0;\n}\n.slider.slider-vertical .slider-tick-label-container {\n    white-space: nowrap;\n}\n.slider.slider-vertical .slider-tick-label-container .slider-tick-label {\n    padding-left: 4px;\n}\n.slider.slider-disabled .slider-handle {\n    background-image: -webkit-linear-gradient(top, #dfdfdf 0%, #bebebe 100%);\n    background-image: -o-linear-gradient(top, #dfdfdf 0%, #bebebe 100%);\n    background-image: linear-gradient(to bottom, #dfdfdf 0%, #bebebe 100%);\n    background-repeat: repeat-x;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffdfdfdf', endColorstr='#ffbebebe', GradientType=0);\n}\n.slider.slider-disabled .slider-track {\n    background-image: -webkit-linear-gradient(top, #e5e5e5 0%, #e9e9e9 100%);\n    background-image: -o-linear-gradient(top, #e5e5e5 0%, #e9e9e9 100%);\n    background-image: linear-gradient(to bottom, #e5e5e5 0%, #e9e9e9 100%);\n    background-repeat: repeat-x;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffe5e5e5', endColorstr='#ffe9e9e9', GradientType=0);\n    cursor: not-allowed;\n}\n.slider input {\n    display: none;\n}\n.slider .tooltip.top {\n  margin-top: -36px;\n}\n.slider .tooltip-inner {\n    white-space: nowrap;\n}\n.slider .hide {\n  display: none;\n}\n.slider-track {\n    position: absolute;\n    cursor: pointer;\n    background-color: #f7f7f7;\n    background-image: -moz-linear-gradient(top, #f0f0f0, #f9f9f9);\n    background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f0f0f0), to(#f9f9f9));\n    background-image: -webkit-linear-gradient(top, #f0f0f0, #f9f9f9);\n    background-image: -o-linear-gradient(top, #f0f0f0, #f9f9f9);\n    background-image: linear-gradient(to bottom, #f0f0f0, #f9f9f9);\n    background-repeat: repeat-x;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff0f0f0', endColorstr='#fff9f9f9', GradientType=0);\n    -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n    -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n    box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);\n    -webkit-border-radius: 4px;\n    -moz-border-radius: 4px;\n    border-radius: 4px;\n}\n.slider-selection {\n    position: absolute;\n    background-color: #f7f7f7;\n    background-image: -moz-linear-gradient(top, #f9f9f9, #f5f5f5);\n    background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f9f9f9), to(#f5f5f5));\n    background-image: -webkit-linear-gradient(top, #f9f9f9, #f5f5f5);\n    background-image: -o-linear-gradient(top, #f9f9f9, #f5f5f5);\n    background-image: linear-gradient(to bottom, #f9f9f9, #f5f5f5);\n    background-repeat: repeat-x;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#fff5f5f5', GradientType=0);\n    -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n    -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n    box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n    -webkit-box-sizing: border-box;\n    -moz-box-sizing: border-box;\n    box-sizing: border-box;\n    -webkit-border-radius: 4px;\n    -moz-border-radius: 4px;\n    border-radius: 4px;\n}\n.slider-selection.tick-slider-selection {\n    background-image: -webkit-linear-gradient(top, #89cdef 0%, #81bfde 100%);\n    background-image: -o-linear-gradient(top, #89cdef 0%, #81bfde 100%);\n    background-image: linear-gradient(to bottom, #89cdef 0%, #81bfde 100%);\n    background-repeat: repeat-x;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff89cdef', endColorstr='#ff81bfde', GradientType=0);\n}\n.slider-track-low,\n.slider-track-high {\n    position: absolute;\n    background: transparent;\n    -webkit-box-sizing: border-box;\n    -moz-box-sizing: border-box;\n    box-sizing: border-box;\n    border-radius: 4px;\n}\n.slider-handle {\n    position: absolute;\n    width: 20px;\n    height: 20px;\n    background-color: #444;\n    -webkit-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);\n    -moz-box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);\n    box-shadow: inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);\n    opacity: 1;\n    border: 0px solid transparent;\n}\n.slider-handle.round {\n    -webkit-border-radius: 20px;\n    -moz-border-radius: 20px;\n    border-radius: 20px;\n}\n.slider-handle.triangle {\n    background: transparent none;\n}\n.slider-handle.custom {\n    background: transparent none;\n}\n.slider-handle.custom::before {\n    line-height: 20px;\n    font-size: 20px;\n    content: '\\2605';\n    color: #726204;\n}\n.slider-tick {\n    position: absolute;\n    width: 20px;\n    height: 20px;\n    background-image: -webkit-linear-gradient(top, #f9f9f9 0%, #f5f5f5 100%);\n    background-image: -o-linear-gradient(top, #f9f9f9 0%, #f5f5f5 100%);\n    background-image: linear-gradient(to bottom, #f9f9f9 0%, #f5f5f5 100%);\n    background-repeat: repeat-x;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff9f9f9', endColorstr='#fff5f5f5', GradientType=0);\n    -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n    box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);\n    -webkit-box-sizing: border-box;\n    -moz-box-sizing: border-box;\n    box-sizing: border-box;\n    filter: none;\n    opacity: 0.8;\n    border: 0px solid transparent;\n}\n.slider-tick.round {\n    border-radius: 50%;\n}\n.slider-tick.triangle {\n    background: transparent none;\n}\n.slider-tick.custom {\n    background: transparent none;\n}\n.slider-tick.custom::before {\n    line-height: 20px;\n    font-size: 20px;\n    content: '\\2605';\n    color: #726204;\n}\n.slider-tick.in-selection {\n    background-image: -webkit-linear-gradient(top, #89cdef 0%, #81bfde 100%);\n    background-image: -o-linear-gradient(top, #89cdef 0%, #81bfde 100%);\n    background-image: linear-gradient(to bottom, #89cdef 0%, #81bfde 100%);\n    background-repeat: repeat-x;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff89cdef', endColorstr='#ff81bfde', GradientType=0);\n    opacity: 1;\n}\n.slider-disabled .slider-selection {\n    opacity: 0.5;\n}\n\n#red .slider-selection {\n    background: #f56954;\n}\n\n#blue .slider-selection {\n    background: #3c8dbc;\n}\n\n#green .slider-selection {\n    background: #00a65a;\n}\n\n#yellow .slider-selection {\n    background: #f39c12;\n}\n\n#aqua .slider-selection {\n    background: #00c0ef;\n}\n\n#purple .slider-selection {\n    background: #932ab6;\n}"
  },
  {
    "path": "public/static/plugins/bootstrap-switch/css/bootstrap-switch.css",
    "content": "/* ========================================================================\n * bootstrap-switch - v3.3.2\n * http://www.bootstrap-switch.org\n * ========================================================================\n * Copyright 2012-2013 Mattia Larentis\n *\n * ========================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================================\n */\n\n.bootstrap-switch {\n  display: inline-block;\n  direction: ltr;\n  cursor: pointer;\n  border-radius: 4px;\n  border: 1px solid;\n  border-color: #cccccc;\n  position: relative;\n  text-align: left;\n  overflow: hidden;\n  line-height: 8px;\n  z-index: 0;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n  vertical-align: middle;\n  -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n  -o-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n  transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\n}\n.bootstrap-switch .bootstrap-switch-container {\n  display: inline-block;\n  top: 0;\n  border-radius: 4px;\n  -webkit-transform: translate3d(0, 0, 0);\n  transform: translate3d(0, 0, 0);\n}\n.bootstrap-switch .bootstrap-switch-handle-on,\n.bootstrap-switch .bootstrap-switch-handle-off,\n.bootstrap-switch .bootstrap-switch-label {\n  -webkit-box-sizing: border-box;\n  -moz-box-sizing: border-box;\n  box-sizing: border-box;\n  cursor: pointer;\n  display: inline-block !important;\n  height: 100%;\n  padding: 6px 12px;\n  font-size: 14px;\n  line-height: 20px;\n}\n.bootstrap-switch .bootstrap-switch-handle-on,\n.bootstrap-switch .bootstrap-switch-handle-off {\n  text-align: center;\n  z-index: 1;\n}\n.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-primary,\n.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-primary {\n  color: #fff;\n  background: #337ab7;\n}\n.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-info,\n.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-info {\n  color: #fff;\n  background: #5bc0de;\n}\n.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success,\n.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success {\n  color: #fff;\n  background: #5cb85c;\n}\n.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-warning,\n.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-warning {\n  background: #f0ad4e;\n  color: #fff;\n}\n.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-danger,\n.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger {\n  color: #fff;\n  background: #d9534f;\n}\n.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-default,\n.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default {\n  color: #000;\n  background: #eeeeee;\n}\n.bootstrap-switch .bootstrap-switch-label {\n  text-align: center;\n  margin-top: -1px;\n  margin-bottom: -1px;\n  z-index: 100;\n  color: #333333;\n  background: #ffffff;\n}\n.bootstrap-switch .bootstrap-switch-handle-on {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.bootstrap-switch .bootstrap-switch-handle-off {\n  border-bottom-right-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.bootstrap-switch input[type='radio'],\n.bootstrap-switch input[type='checkbox'] {\n  position: absolute !important;\n  top: 0;\n  left: 0;\n  margin: 0;\n  z-index: -1;\n  opacity: 0;\n  filter: alpha(opacity=0);\n}\n.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-on,\n.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-off,\n.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-label {\n  padding: 1px 5px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-on,\n.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-off,\n.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-label {\n  padding: 5px 10px;\n  font-size: 12px;\n  line-height: 1.5;\n}\n.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-on,\n.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-off,\n.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-label {\n  padding: 6px 16px;\n  font-size: 18px;\n  line-height: 1.3333333;\n}\n.bootstrap-switch.bootstrap-switch-disabled,\n.bootstrap-switch.bootstrap-switch-readonly,\n.bootstrap-switch.bootstrap-switch-indeterminate {\n  cursor: default !important;\n}\n.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-on,\n.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-on,\n.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-on,\n.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-off,\n.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-off,\n.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-off,\n.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-label,\n.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-label,\n.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-label {\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n  cursor: default !important;\n}\n.bootstrap-switch.bootstrap-switch-animate .bootstrap-switch-container {\n  -webkit-transition: margin-left 0.5s;\n  -o-transition: margin-left 0.5s;\n  transition: margin-left 0.5s;\n}\n.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-on {\n  border-bottom-left-radius: 0;\n  border-top-left-radius: 0;\n  border-bottom-right-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-off {\n  border-bottom-right-radius: 0;\n  border-top-right-radius: 0;\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n.bootstrap-switch.bootstrap-switch-focused {\n  border-color: #66afe9;\n  outline: 0;\n  -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n  box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(102, 175, 233, 0.6);\n}\n.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-label,\n.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-off .bootstrap-switch-label {\n  border-bottom-right-radius: 3px;\n  border-top-right-radius: 3px;\n}\n.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-label,\n.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-on .bootstrap-switch-label {\n  border-bottom-left-radius: 3px;\n  border-top-left-radius: 3px;\n}\n"
  },
  {
    "path": "public/static/plugins/bootstrap-switch/js/bootstrap-switch.js",
    "content": "/* ========================================================================\n * bootstrap-switch - v3.3.2\n * http://www.bootstrap-switch.org\n * ========================================================================\n * Copyright 2012-2013 Mattia Larentis\n *\n * ========================================================================\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *     http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================================\n */\n\n(function() {\n  var slice = [].slice;\n\n  (function($, window) {\n    \"use strict\";\n    var BootstrapSwitch;\n    BootstrapSwitch = (function() {\n      function BootstrapSwitch(element, options) {\n        if (options == null) {\n          options = {};\n        }\n        this.$element = $(element);\n        this.options = $.extend({}, $.fn.bootstrapSwitch.defaults, {\n          state: this.$element.is(\":checked\"),\n          size: this.$element.data(\"size\"),\n          animate: this.$element.data(\"animate\"),\n          disabled: this.$element.is(\":disabled\"),\n          readonly: this.$element.is(\"[readonly]\"),\n          indeterminate: this.$element.data(\"indeterminate\"),\n          inverse: this.$element.data(\"inverse\"),\n          radioAllOff: this.$element.data(\"radio-all-off\"),\n          onColor: this.$element.data(\"on-color\"),\n          offColor: this.$element.data(\"off-color\"),\n          onText: this.$element.data(\"on-text\"),\n          offText: this.$element.data(\"off-text\"),\n          labelText: this.$element.data(\"label-text\"),\n          handleWidth: this.$element.data(\"handle-width\"),\n          labelWidth: this.$element.data(\"label-width\"),\n          baseClass: this.$element.data(\"base-class\"),\n          wrapperClass: this.$element.data(\"wrapper-class\")\n        }, options);\n        this.prevOptions = {};\n        this.$wrapper = $(\"<div>\", {\n          \"class\": (function(_this) {\n            return function() {\n              var classes;\n              classes = [\"\" + _this.options.baseClass].concat(_this._getClasses(_this.options.wrapperClass));\n              classes.push(_this.options.state ? _this.options.baseClass + \"-on\" : _this.options.baseClass + \"-off\");\n              if (_this.options.size != null) {\n                classes.push(_this.options.baseClass + \"-\" + _this.options.size);\n              }\n              if (_this.options.disabled) {\n                classes.push(_this.options.baseClass + \"-disabled\");\n              }\n              if (_this.options.readonly) {\n                classes.push(_this.options.baseClass + \"-readonly\");\n              }\n              if (_this.options.indeterminate) {\n                classes.push(_this.options.baseClass + \"-indeterminate\");\n              }\n              if (_this.options.inverse) {\n                classes.push(_this.options.baseClass + \"-inverse\");\n              }\n              if (_this.$element.attr(\"id\")) {\n                classes.push(_this.options.baseClass + \"-id-\" + (_this.$element.attr(\"id\")));\n              }\n              return classes.join(\" \");\n            };\n          })(this)()\n        });\n        this.$container = $(\"<div>\", {\n          \"class\": this.options.baseClass + \"-container\"\n        });\n        this.$on = $(\"<span>\", {\n          html: this.options.onText,\n          \"class\": this.options.baseClass + \"-handle-on \" + this.options.baseClass + \"-\" + this.options.onColor\n        });\n        this.$off = $(\"<span>\", {\n          html: this.options.offText,\n          \"class\": this.options.baseClass + \"-handle-off \" + this.options.baseClass + \"-\" + this.options.offColor\n        });\n        this.$label = $(\"<span>\", {\n          html: this.options.labelText,\n          \"class\": this.options.baseClass + \"-label\"\n        });\n        this.$element.on(\"init.bootstrapSwitch\", (function(_this) {\n          return function() {\n            return _this.options.onInit.apply(element, arguments);\n          };\n        })(this));\n        this.$element.on(\"switchChange.bootstrapSwitch\", (function(_this) {\n          return function(e) {\n            if (false === _this.options.onSwitchChange.apply(element, arguments)) {\n              if (_this.$element.is(\":radio\")) {\n                return $(\"[name='\" + (_this.$element.attr('name')) + \"']\").trigger(\"previousState.bootstrapSwitch\", true);\n              } else {\n                return _this.$element.trigger(\"previousState.bootstrapSwitch\", true);\n              }\n            }\n          };\n        })(this));\n        this.$container = this.$element.wrap(this.$container).parent();\n        this.$wrapper = this.$container.wrap(this.$wrapper).parent();\n        this.$element.before(this.options.inverse ? this.$off : this.$on).before(this.$label).before(this.options.inverse ? this.$on : this.$off);\n        if (this.options.indeterminate) {\n          this.$element.prop(\"indeterminate\", true);\n        }\n        this._init();\n        this._elementHandlers();\n        this._handleHandlers();\n        this._labelHandlers();\n        this._formHandler();\n        this._externalLabelHandler();\n        this.$element.trigger(\"init.bootstrapSwitch\", this.options.state);\n      }\n\n      BootstrapSwitch.prototype._constructor = BootstrapSwitch;\n\n      BootstrapSwitch.prototype.setPrevOptions = function() {\n        return this.prevOptions = $.extend(true, {}, this.options);\n      };\n\n      BootstrapSwitch.prototype.state = function(value, skip) {\n        if (typeof value === \"undefined\") {\n          return this.options.state;\n        }\n        if (this.options.disabled || this.options.readonly) {\n          return this.$element;\n        }\n        if (this.options.state && !this.options.radioAllOff && this.$element.is(\":radio\")) {\n          return this.$element;\n        }\n        if (this.$element.is(\":radio\")) {\n          $(\"[name='\" + (this.$element.attr('name')) + \"']\").trigger(\"setPreviousOptions.bootstrapSwitch\");\n        } else {\n          this.$element.trigger(\"setPreviousOptions.bootstrapSwitch\");\n        }\n        if (this.options.indeterminate) {\n          this.indeterminate(false);\n        }\n        value = !!value;\n        this.$element.prop(\"checked\", value).trigger(\"change.bootstrapSwitch\", skip);\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.toggleState = function(skip) {\n        if (this.options.disabled || this.options.readonly) {\n          return this.$element;\n        }\n        if (this.options.indeterminate) {\n          this.indeterminate(false);\n          return this.state(true);\n        } else {\n          return this.$element.prop(\"checked\", !this.options.state).trigger(\"change.bootstrapSwitch\", skip);\n        }\n      };\n\n      BootstrapSwitch.prototype.size = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.size;\n        }\n        if (this.options.size != null) {\n          this.$wrapper.removeClass(this.options.baseClass + \"-\" + this.options.size);\n        }\n        if (value) {\n          this.$wrapper.addClass(this.options.baseClass + \"-\" + value);\n        }\n        this._width();\n        this._containerPosition();\n        this.options.size = value;\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.animate = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.animate;\n        }\n        value = !!value;\n        if (value === this.options.animate) {\n          return this.$element;\n        }\n        return this.toggleAnimate();\n      };\n\n      BootstrapSwitch.prototype.toggleAnimate = function() {\n        this.options.animate = !this.options.animate;\n        this.$wrapper.toggleClass(this.options.baseClass + \"-animate\");\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.disabled = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.disabled;\n        }\n        value = !!value;\n        if (value === this.options.disabled) {\n          return this.$element;\n        }\n        return this.toggleDisabled();\n      };\n\n      BootstrapSwitch.prototype.toggleDisabled = function() {\n        this.options.disabled = !this.options.disabled;\n        this.$element.prop(\"disabled\", this.options.disabled);\n        this.$wrapper.toggleClass(this.options.baseClass + \"-disabled\");\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.readonly = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.readonly;\n        }\n        value = !!value;\n        if (value === this.options.readonly) {\n          return this.$element;\n        }\n        return this.toggleReadonly();\n      };\n\n      BootstrapSwitch.prototype.toggleReadonly = function() {\n        this.options.readonly = !this.options.readonly;\n        this.$element.prop(\"readonly\", this.options.readonly);\n        this.$wrapper.toggleClass(this.options.baseClass + \"-readonly\");\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.indeterminate = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.indeterminate;\n        }\n        value = !!value;\n        if (value === this.options.indeterminate) {\n          return this.$element;\n        }\n        return this.toggleIndeterminate();\n      };\n\n      BootstrapSwitch.prototype.toggleIndeterminate = function() {\n        this.options.indeterminate = !this.options.indeterminate;\n        this.$element.prop(\"indeterminate\", this.options.indeterminate);\n        this.$wrapper.toggleClass(this.options.baseClass + \"-indeterminate\");\n        this._containerPosition();\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.inverse = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.inverse;\n        }\n        value = !!value;\n        if (value === this.options.inverse) {\n          return this.$element;\n        }\n        return this.toggleInverse();\n      };\n\n      BootstrapSwitch.prototype.toggleInverse = function() {\n        var $off, $on;\n        this.$wrapper.toggleClass(this.options.baseClass + \"-inverse\");\n        $on = this.$on.clone(true);\n        $off = this.$off.clone(true);\n        this.$on.replaceWith($off);\n        this.$off.replaceWith($on);\n        this.$on = $off;\n        this.$off = $on;\n        this.options.inverse = !this.options.inverse;\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.onColor = function(value) {\n        var color;\n        color = this.options.onColor;\n        if (typeof value === \"undefined\") {\n          return color;\n        }\n        if (color != null) {\n          this.$on.removeClass(this.options.baseClass + \"-\" + color);\n        }\n        this.$on.addClass(this.options.baseClass + \"-\" + value);\n        this.options.onColor = value;\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.offColor = function(value) {\n        var color;\n        color = this.options.offColor;\n        if (typeof value === \"undefined\") {\n          return color;\n        }\n        if (color != null) {\n          this.$off.removeClass(this.options.baseClass + \"-\" + color);\n        }\n        this.$off.addClass(this.options.baseClass + \"-\" + value);\n        this.options.offColor = value;\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.onText = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.onText;\n        }\n        this.$on.html(value);\n        this._width();\n        this._containerPosition();\n        this.options.onText = value;\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.offText = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.offText;\n        }\n        this.$off.html(value);\n        this._width();\n        this._containerPosition();\n        this.options.offText = value;\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.labelText = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.labelText;\n        }\n        this.$label.html(value);\n        this._width();\n        this.options.labelText = value;\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.handleWidth = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.handleWidth;\n        }\n        this.options.handleWidth = value;\n        this._width();\n        this._containerPosition();\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.labelWidth = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.labelWidth;\n        }\n        this.options.labelWidth = value;\n        this._width();\n        this._containerPosition();\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.baseClass = function(value) {\n        return this.options.baseClass;\n      };\n\n      BootstrapSwitch.prototype.wrapperClass = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.wrapperClass;\n        }\n        if (!value) {\n          value = $.fn.bootstrapSwitch.defaults.wrapperClass;\n        }\n        this.$wrapper.removeClass(this._getClasses(this.options.wrapperClass).join(\" \"));\n        this.$wrapper.addClass(this._getClasses(value).join(\" \"));\n        this.options.wrapperClass = value;\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.radioAllOff = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.radioAllOff;\n        }\n        value = !!value;\n        if (value === this.options.radioAllOff) {\n          return this.$element;\n        }\n        this.options.radioAllOff = value;\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.onInit = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.onInit;\n        }\n        if (!value) {\n          value = $.fn.bootstrapSwitch.defaults.onInit;\n        }\n        this.options.onInit = value;\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.onSwitchChange = function(value) {\n        if (typeof value === \"undefined\") {\n          return this.options.onSwitchChange;\n        }\n        if (!value) {\n          value = $.fn.bootstrapSwitch.defaults.onSwitchChange;\n        }\n        this.options.onSwitchChange = value;\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype.destroy = function() {\n        var $form;\n        $form = this.$element.closest(\"form\");\n        if ($form.length) {\n          $form.off(\"reset.bootstrapSwitch\").removeData(\"bootstrap-switch\");\n        }\n        this.$container.children().not(this.$element).remove();\n        this.$element.unwrap().unwrap().off(\".bootstrapSwitch\").removeData(\"bootstrap-switch\");\n        return this.$element;\n      };\n\n      BootstrapSwitch.prototype._width = function() {\n        var $handles, handleWidth;\n        $handles = this.$on.add(this.$off);\n        $handles.add(this.$label).css(\"width\", \"\");\n        handleWidth = this.options.handleWidth === \"auto\" ? Math.max(this.$on.width(), this.$off.width()) : this.options.handleWidth;\n        $handles.width(handleWidth);\n        this.$label.width((function(_this) {\n          return function(index, width) {\n            if (_this.options.labelWidth !== \"auto\") {\n              return _this.options.labelWidth;\n            }\n            if (width < handleWidth) {\n              return handleWidth;\n            } else {\n              return width;\n            }\n          };\n        })(this));\n        this._handleWidth = this.$on.outerWidth();\n        this._labelWidth = this.$label.outerWidth();\n        this.$container.width((this._handleWidth * 2) + this._labelWidth);\n        return this.$wrapper.width(this._handleWidth + this._labelWidth);\n      };\n\n      BootstrapSwitch.prototype._containerPosition = function(state, callback) {\n        if (state == null) {\n          state = this.options.state;\n        }\n        this.$container.css(\"margin-left\", (function(_this) {\n          return function() {\n            var values;\n            values = [0, \"-\" + _this._handleWidth + \"px\"];\n            if (_this.options.indeterminate) {\n              return \"-\" + (_this._handleWidth / 2) + \"px\";\n            }\n            if (state) {\n              if (_this.options.inverse) {\n                return values[1];\n              } else {\n                return values[0];\n              }\n            } else {\n              if (_this.options.inverse) {\n                return values[0];\n              } else {\n                return values[1];\n              }\n            }\n          };\n        })(this));\n        if (!callback) {\n          return;\n        }\n        return setTimeout(function() {\n          return callback();\n        }, 50);\n      };\n\n      BootstrapSwitch.prototype._init = function() {\n        var init, initInterval;\n        init = (function(_this) {\n          return function() {\n            _this.setPrevOptions();\n            _this._width();\n            return _this._containerPosition(null, function() {\n              if (_this.options.animate) {\n                return _this.$wrapper.addClass(_this.options.baseClass + \"-animate\");\n              }\n            });\n          };\n        })(this);\n        if (this.$wrapper.is(\":visible\")) {\n          return init();\n        }\n        return initInterval = window.setInterval((function(_this) {\n          return function() {\n            if (_this.$wrapper.is(\":visible\")) {\n              init();\n              return window.clearInterval(initInterval);\n            }\n          };\n        })(this), 50);\n      };\n\n      BootstrapSwitch.prototype._elementHandlers = function() {\n        return this.$element.on({\n          \"setPreviousOptions.bootstrapSwitch\": (function(_this) {\n            return function(e) {\n              return _this.setPrevOptions();\n            };\n          })(this),\n          \"previousState.bootstrapSwitch\": (function(_this) {\n            return function(e) {\n              _this.options = _this.prevOptions;\n              if (_this.options.indeterminate) {\n                _this.$wrapper.addClass(_this.options.baseClass + \"-indeterminate\");\n              }\n              return _this.$element.prop(\"checked\", _this.options.state).trigger(\"change.bootstrapSwitch\", true);\n            };\n          })(this),\n          \"change.bootstrapSwitch\": (function(_this) {\n            return function(e, skip) {\n              var state;\n              e.preventDefault();\n              e.stopImmediatePropagation();\n              state = _this.$element.is(\":checked\");\n              _this._containerPosition(state);\n              if (state === _this.options.state) {\n                return;\n              }\n              _this.options.state = state;\n              _this.$wrapper.toggleClass(_this.options.baseClass + \"-off\").toggleClass(_this.options.baseClass + \"-on\");\n              if (!skip) {\n                if (_this.$element.is(\":radio\")) {\n                  $(\"[name='\" + (_this.$element.attr('name')) + \"']\").not(_this.$element).prop(\"checked\", false).trigger(\"change.bootstrapSwitch\", true);\n                }\n                return _this.$element.trigger(\"switchChange.bootstrapSwitch\", [state]);\n              }\n            };\n          })(this),\n          \"focus.bootstrapSwitch\": (function(_this) {\n            return function(e) {\n              e.preventDefault();\n              return _this.$wrapper.addClass(_this.options.baseClass + \"-focused\");\n            };\n          })(this),\n          \"blur.bootstrapSwitch\": (function(_this) {\n            return function(e) {\n              e.preventDefault();\n              return _this.$wrapper.removeClass(_this.options.baseClass + \"-focused\");\n            };\n          })(this),\n          \"keydown.bootstrapSwitch\": (function(_this) {\n            return function(e) {\n              if (!e.which || _this.options.disabled || _this.options.readonly) {\n                return;\n              }\n              switch (e.which) {\n                case 37:\n                  e.preventDefault();\n                  e.stopImmediatePropagation();\n                  return _this.state(false);\n                case 39:\n                  e.preventDefault();\n                  e.stopImmediatePropagation();\n                  return _this.state(true);\n              }\n            };\n          })(this)\n        });\n      };\n\n      BootstrapSwitch.prototype._handleHandlers = function() {\n        this.$on.on(\"click.bootstrapSwitch\", (function(_this) {\n          return function(event) {\n            event.preventDefault();\n            event.stopPropagation();\n            _this.state(false);\n            return _this.$element.trigger(\"focus.bootstrapSwitch\");\n          };\n        })(this));\n        return this.$off.on(\"click.bootstrapSwitch\", (function(_this) {\n          return function(event) {\n            event.preventDefault();\n            event.stopPropagation();\n            _this.state(true);\n            return _this.$element.trigger(\"focus.bootstrapSwitch\");\n          };\n        })(this));\n      };\n\n      BootstrapSwitch.prototype._labelHandlers = function() {\n        return this.$label.on({\n          \"click\": function(e) {\n            return e.stopPropagation();\n          },\n          \"mousedown.bootstrapSwitch touchstart.bootstrapSwitch\": (function(_this) {\n            return function(e) {\n              if (_this._dragStart || _this.options.disabled || _this.options.readonly) {\n                return;\n              }\n              e.preventDefault();\n              e.stopPropagation();\n              _this._dragStart = (e.pageX || e.originalEvent.touches[0].pageX) - parseInt(_this.$container.css(\"margin-left\"), 10);\n              if (_this.options.animate) {\n                _this.$wrapper.removeClass(_this.options.baseClass + \"-animate\");\n              }\n              return _this.$element.trigger(\"focus.bootstrapSwitch\");\n            };\n          })(this),\n          \"mousemove.bootstrapSwitch touchmove.bootstrapSwitch\": (function(_this) {\n            return function(e) {\n              var difference;\n              if (_this._dragStart == null) {\n                return;\n              }\n              e.preventDefault();\n              difference = (e.pageX || e.originalEvent.touches[0].pageX) - _this._dragStart;\n              if (difference < -_this._handleWidth || difference > 0) {\n                return;\n              }\n              _this._dragEnd = difference;\n              return _this.$container.css(\"margin-left\", _this._dragEnd + \"px\");\n            };\n          })(this),\n          \"mouseup.bootstrapSwitch touchend.bootstrapSwitch\": (function(_this) {\n            return function(e) {\n              var state;\n              if (!_this._dragStart) {\n                return;\n              }\n              e.preventDefault();\n              if (_this.options.animate) {\n                _this.$wrapper.addClass(_this.options.baseClass + \"-animate\");\n              }\n              if (_this._dragEnd) {\n                state = _this._dragEnd > -(_this._handleWidth / 2);\n                _this._dragEnd = false;\n                _this.state(_this.options.inverse ? !state : state);\n              } else {\n                _this.state(!_this.options.state);\n              }\n              return _this._dragStart = false;\n            };\n          })(this),\n          \"mouseleave.bootstrapSwitch\": (function(_this) {\n            return function(e) {\n              return _this.$label.trigger(\"mouseup.bootstrapSwitch\");\n            };\n          })(this)\n        });\n      };\n\n      BootstrapSwitch.prototype._externalLabelHandler = function() {\n        var $externalLabel;\n        $externalLabel = this.$element.closest(\"label\");\n        return $externalLabel.on(\"click\", (function(_this) {\n          return function(event) {\n            event.preventDefault();\n            event.stopImmediatePropagation();\n            if (event.target === $externalLabel[0]) {\n              return _this.toggleState();\n            }\n          };\n        })(this));\n      };\n\n      BootstrapSwitch.prototype._formHandler = function() {\n        var $form;\n        $form = this.$element.closest(\"form\");\n        if ($form.data(\"bootstrap-switch\")) {\n          return;\n        }\n        return $form.on(\"reset.bootstrapSwitch\", function() {\n          return window.setTimeout(function() {\n            return $form.find(\"input\").filter(function() {\n              return $(this).data(\"bootstrap-switch\");\n            }).each(function() {\n              return $(this).bootstrapSwitch(\"state\", this.checked);\n            });\n          }, 1);\n        }).data(\"bootstrap-switch\", true);\n      };\n\n      BootstrapSwitch.prototype._getClasses = function(classes) {\n        var c, cls, i, len;\n        if (!$.isArray(classes)) {\n          return [this.options.baseClass + \"-\" + classes];\n        }\n        cls = [];\n        for (i = 0, len = classes.length; i < len; i++) {\n          c = classes[i];\n          cls.push(this.options.baseClass + \"-\" + c);\n        }\n        return cls;\n      };\n\n      return BootstrapSwitch;\n\n    })();\n    $.fn.bootstrapSwitch = function() {\n      var args, option, ret;\n      option = arguments[0], args = 2 <= arguments.length ? slice.call(arguments, 1) : [];\n      ret = this;\n      this.each(function() {\n        var $this, data;\n        $this = $(this);\n        data = $this.data(\"bootstrap-switch\");\n        if (!data) {\n          $this.data(\"bootstrap-switch\", data = new BootstrapSwitch(this, option));\n        }\n        if (typeof option === \"string\") {\n          return ret = data[option].apply(data, args);\n        }\n      });\n      return ret;\n    };\n    $.fn.bootstrapSwitch.Constructor = BootstrapSwitch;\n    return $.fn.bootstrapSwitch.defaults = {\n      state: true,\n      size: null,\n      animate: true,\n      disabled: false,\n      readonly: false,\n      indeterminate: false,\n      inverse: false,\n      radioAllOff: false,\n      onColor: \"primary\",\n      offColor: \"default\",\n      onText: \"ON\",\n      offText: \"OFF\",\n      labelText: \"&nbsp;\",\n      handleWidth: \"auto\",\n      labelWidth: \"auto\",\n      baseClass: \"bootstrap-switch\",\n      wrapperClass: \"wrapper\",\n      onInit: function() {},\n      onSwitchChange: function() {}\n    };\n  })(window.jQuery, window);\n\n}).call(this);\n"
  },
  {
    "path": "public/static/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.all.js",
    "content": "// TODO: in future try to replace most inline compability checks with polyfills for code readability \n\n// element.textContent polyfill.\n// Unsupporting browsers: IE8\n\nif (Object.defineProperty && Object.getOwnPropertyDescriptor && Object.getOwnPropertyDescriptor(Element.prototype, \"textContent\") && !Object.getOwnPropertyDescriptor(Element.prototype, \"textContent\").get) {\n\t(function() {\n\t\tvar innerText = Object.getOwnPropertyDescriptor(Element.prototype, \"innerText\");\n\t\tObject.defineProperty(Element.prototype, \"textContent\",\n\t\t\t{\n\t\t\t\tget: function() {\n\t\t\t\t\treturn innerText.get.call(this);\n\t\t\t\t},\n\t\t\t\tset: function(s) {\n\t\t\t\t\treturn innerText.set.call(this, s);\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t})();\n}\n\n// isArray polyfill for ie8\nif(!Array.isArray) {\n  Array.isArray = function(arg) {\n    return Object.prototype.toString.call(arg) === '[object Array]';\n  };\n};/**\n * @license wysihtml5x v0.4.15\n * https://github.com/Edicy/wysihtml5\n *\n * Author: Christopher Blum (https://github.com/tiff)\n * Secondary author of extended features: Oliver Pulges (https://github.com/pulges)\n *\n * Copyright (C) 2012 XING AG\n * Licensed under the MIT license (MIT)\n *\n */\nvar wysihtml5 = {\n  version: \"0.4.15\",\n\n  // namespaces\n  commands:   {},\n  dom:        {},\n  quirks:     {},\n  toolbar:    {},\n  lang:       {},\n  selection:  {},\n  views:      {},\n\n  INVISIBLE_SPACE: \"\\uFEFF\",\n\n  EMPTY_FUNCTION: function() {},\n\n  ELEMENT_NODE: 1,\n  TEXT_NODE:    3,\n\n  BACKSPACE_KEY:  8,\n  ENTER_KEY:      13,\n  ESCAPE_KEY:     27,\n  SPACE_KEY:      32,\n  DELETE_KEY:     46\n};\n;/**\n * Rangy, a cross-browser JavaScript range and selection library\n * http://code.google.com/p/rangy/\n *\n * Copyright 2014, Tim Down\n * Licensed under the MIT license.\n * Version: 1.3alpha.20140804\n * Build date: 4 August 2014\n */\n\n(function(factory, global) {\n    if (typeof define == \"function\" && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(factory);\n/*\n    TODO: look into this properly.\n    \n    } else if (typeof exports == \"object\") {\n        // Node/CommonJS style for Browserify\n        module.exports = factory;\n*/\n    } else {\n        // No AMD or CommonJS support so we place Rangy in a global variable\n        global.rangy = factory();\n    }\n})(function() {\n\n    var OBJECT = \"object\", FUNCTION = \"function\", UNDEFINED = \"undefined\";\n\n    // Minimal set of properties required for DOM Level 2 Range compliance. Comparison constants such as START_TO_START\n    // are omitted because ranges in KHTML do not have them but otherwise work perfectly well. See issue 113.\n    var domRangeProperties = [\"startContainer\", \"startOffset\", \"endContainer\", \"endOffset\", \"collapsed\",\n        \"commonAncestorContainer\"];\n\n    // Minimal set of methods required for DOM Level 2 Range compliance\n    var domRangeMethods = [\"setStart\", \"setStartBefore\", \"setStartAfter\", \"setEnd\", \"setEndBefore\",\n        \"setEndAfter\", \"collapse\", \"selectNode\", \"selectNodeContents\", \"compareBoundaryPoints\", \"deleteContents\",\n        \"extractContents\", \"cloneContents\", \"insertNode\", \"surroundContents\", \"cloneRange\", \"toString\", \"detach\"];\n\n    var textRangeProperties = [\"boundingHeight\", \"boundingLeft\", \"boundingTop\", \"boundingWidth\", \"htmlText\", \"text\"];\n\n    // Subset of TextRange's full set of methods that we're interested in\n    var textRangeMethods = [\"collapse\", \"compareEndPoints\", \"duplicate\", \"moveToElementText\", \"parentElement\", \"select\",\n        \"setEndPoint\", \"getBoundingClientRect\"];\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Trio of functions taken from Peter Michaux's article:\n    // http://peter.michaux.ca/articles/feature-detection-state-of-the-art-browser-scripting\n    function isHostMethod(o, p) {\n        var t = typeof o[p];\n        return t == FUNCTION || (!!(t == OBJECT && o[p])) || t == \"unknown\";\n    }\n\n    function isHostObject(o, p) {\n        return !!(typeof o[p] == OBJECT && o[p]);\n    }\n\n    function isHostProperty(o, p) {\n        return typeof o[p] != UNDEFINED;\n    }\n\n    // Creates a convenience function to save verbose repeated calls to tests functions\n    function createMultiplePropertyTest(testFunc) {\n        return function(o, props) {\n            var i = props.length;\n            while (i--) {\n                if (!testFunc(o, props[i])) {\n                    return false;\n                }\n            }\n            return true;\n        };\n    }\n\n    // Next trio of functions are a convenience to save verbose repeated calls to previous two functions\n    var areHostMethods = createMultiplePropertyTest(isHostMethod);\n    var areHostObjects = createMultiplePropertyTest(isHostObject);\n    var areHostProperties = createMultiplePropertyTest(isHostProperty);\n\n    function isTextRange(range) {\n        return range && areHostMethods(range, textRangeMethods) && areHostProperties(range, textRangeProperties);\n    }\n\n    function getBody(doc) {\n        return isHostObject(doc, \"body\") ? doc.body : doc.getElementsByTagName(\"body\")[0];\n    }\n\n    var modules = {};\n\n    var api = {\n        version: \"1.3alpha.20140804\",\n        initialized: false,\n        supported: true,\n\n        util: {\n            isHostMethod: isHostMethod,\n            isHostObject: isHostObject,\n            isHostProperty: isHostProperty,\n            areHostMethods: areHostMethods,\n            areHostObjects: areHostObjects,\n            areHostProperties: areHostProperties,\n            isTextRange: isTextRange,\n            getBody: getBody\n        },\n\n        features: {},\n\n        modules: modules,\n        config: {\n            alertOnFail: true,\n            alertOnWarn: false,\n            preferTextRange: false,\n            autoInitialize: (typeof rangyAutoInitialize == UNDEFINED) ? true : rangyAutoInitialize\n        }\n    };\n\n    function consoleLog(msg) {\n        if (isHostObject(window, \"console\") && isHostMethod(window.console, \"log\")) {\n            window.console.log(msg);\n        }\n    }\n\n    function alertOrLog(msg, shouldAlert) {\n        if (shouldAlert) {\n            window.alert(msg);\n        } else  {\n            consoleLog(msg);\n        }\n    }\n\n    function fail(reason) {\n        api.initialized = true;\n        api.supported = false;\n        alertOrLog(\"Rangy is not supported on this page in your browser. Reason: \" + reason, api.config.alertOnFail);\n    }\n\n    api.fail = fail;\n\n    function warn(msg) {\n        alertOrLog(\"Rangy warning: \" + msg, api.config.alertOnWarn);\n    }\n\n    api.warn = warn;\n\n    // Add utility extend() method\n    if ({}.hasOwnProperty) {\n        api.util.extend = function(obj, props, deep) {\n            var o, p;\n            for (var i in props) {\n                if (props.hasOwnProperty(i)) {\n                    o = obj[i];\n                    p = props[i];\n                    if (deep && o !== null && typeof o == \"object\" && p !== null && typeof p == \"object\") {\n                        api.util.extend(o, p, true);\n                    }\n                    obj[i] = p;\n                }\n            }\n            // Special case for toString, which does not show up in for...in loops in IE <= 8\n            if (props.hasOwnProperty(\"toString\")) {\n                obj.toString = props.toString;\n            }\n            return obj;\n        };\n    } else {\n        fail(\"hasOwnProperty not supported\");\n    }\n\n    // Test whether Array.prototype.slice can be relied on for NodeLists and use an alternative toArray() if not\n    (function() {\n        var el = document.createElement(\"div\");\n        el.appendChild(document.createElement(\"span\"));\n        var slice = [].slice;\n        var toArray;\n        try {\n            if (slice.call(el.childNodes, 0)[0].nodeType == 1) {\n                toArray = function(arrayLike) {\n                    return slice.call(arrayLike, 0);\n                };\n            }\n        } catch (e) {}\n\n        if (!toArray) {\n            toArray = function(arrayLike) {\n                var arr = [];\n                for (var i = 0, len = arrayLike.length; i < len; ++i) {\n                    arr[i] = arrayLike[i];\n                }\n                return arr;\n            };\n        }\n\n        api.util.toArray = toArray;\n    })();\n\n\n    // Very simple event handler wrapper function that doesn't attempt to solve issues such as \"this\" handling or\n    // normalization of event properties\n    var addListener;\n    if (isHostMethod(document, \"addEventListener\")) {\n        addListener = function(obj, eventType, listener) {\n            obj.addEventListener(eventType, listener, false);\n        };\n    } else if (isHostMethod(document, \"attachEvent\")) {\n        addListener = function(obj, eventType, listener) {\n            obj.attachEvent(\"on\" + eventType, listener);\n        };\n    } else {\n        fail(\"Document does not have required addEventListener or attachEvent method\");\n    }\n\n    api.util.addListener = addListener;\n\n    var initListeners = [];\n\n    function getErrorDesc(ex) {\n        return ex.message || ex.description || String(ex);\n    }\n\n    // Initialization\n    function init() {\n        if (api.initialized) {\n            return;\n        }\n        var testRange;\n        var implementsDomRange = false, implementsTextRange = false;\n\n        // First, perform basic feature tests\n\n        if (isHostMethod(document, \"createRange\")) {\n            testRange = document.createRange();\n            if (areHostMethods(testRange, domRangeMethods) && areHostProperties(testRange, domRangeProperties)) {\n                implementsDomRange = true;\n            }\n        }\n\n        var body = getBody(document);\n        if (!body || body.nodeName.toLowerCase() != \"body\") {\n            fail(\"No body element found\");\n            return;\n        }\n\n        if (body && isHostMethod(body, \"createTextRange\")) {\n            testRange = body.createTextRange();\n            if (isTextRange(testRange)) {\n                implementsTextRange = true;\n            }\n        }\n\n        if (!implementsDomRange && !implementsTextRange) {\n            fail(\"Neither Range nor TextRange are available\");\n            return;\n        }\n\n        api.initialized = true;\n        api.features = {\n            implementsDomRange: implementsDomRange,\n            implementsTextRange: implementsTextRange\n        };\n\n        // Initialize modules\n        var module, errorMessage;\n        for (var moduleName in modules) {\n            if ( (module = modules[moduleName]) instanceof Module ) {\n                module.init(module, api);\n            }\n        }\n\n        // Call init listeners\n        for (var i = 0, len = initListeners.length; i < len; ++i) {\n            try {\n                initListeners[i](api);\n            } catch (ex) {\n                errorMessage = \"Rangy init listener threw an exception. Continuing. Detail: \" + getErrorDesc(ex);\n                consoleLog(errorMessage);\n            }\n        }\n    }\n\n    // Allow external scripts to initialize this library in case it's loaded after the document has loaded\n    api.init = init;\n\n    // Execute listener immediately if already initialized\n    api.addInitListener = function(listener) {\n        if (api.initialized) {\n            listener(api);\n        } else {\n            initListeners.push(listener);\n        }\n    };\n\n    var shimListeners = [];\n\n    api.addShimListener = function(listener) {\n        shimListeners.push(listener);\n    };\n\n    function shim(win) {\n        win = win || window;\n        init();\n\n        // Notify listeners\n        for (var i = 0, len = shimListeners.length; i < len; ++i) {\n            shimListeners[i](win);\n        }\n    }\n\n    api.shim = api.createMissingNativeApi = shim;\n\n    function Module(name, dependencies, initializer) {\n        this.name = name;\n        this.dependencies = dependencies;\n        this.initialized = false;\n        this.supported = false;\n        this.initializer = initializer;\n    }\n\n    Module.prototype = {\n        init: function() {\n            var requiredModuleNames = this.dependencies || [];\n            for (var i = 0, len = requiredModuleNames.length, requiredModule, moduleName; i < len; ++i) {\n                moduleName = requiredModuleNames[i];\n\n                requiredModule = modules[moduleName];\n                if (!requiredModule || !(requiredModule instanceof Module)) {\n                    throw new Error(\"required module '\" + moduleName + \"' not found\");\n                }\n\n                requiredModule.init();\n\n                if (!requiredModule.supported) {\n                    throw new Error(\"required module '\" + moduleName + \"' not supported\");\n                }\n            }\n            \n            // Now run initializer\n            this.initializer(this);\n        },\n        \n        fail: function(reason) {\n            this.initialized = true;\n            this.supported = false;\n            throw new Error(\"Module '\" + this.name + \"' failed to load: \" + reason);\n        },\n\n        warn: function(msg) {\n            api.warn(\"Module \" + this.name + \": \" + msg);\n        },\n\n        deprecationNotice: function(deprecated, replacement) {\n            api.warn(\"DEPRECATED: \" + deprecated + \" in module \" + this.name + \"is deprecated. Please use \" +\n                replacement + \" instead\");\n        },\n\n        createError: function(msg) {\n            return new Error(\"Error in Rangy \" + this.name + \" module: \" + msg);\n        }\n    };\n    \n    function createModule(isCore, name, dependencies, initFunc) {\n        var newModule = new Module(name, dependencies, function(module) {\n            if (!module.initialized) {\n                module.initialized = true;\n                try {\n                    initFunc(api, module);\n                    module.supported = true;\n                } catch (ex) {\n                    var errorMessage = \"Module '\" + name + \"' failed to load: \" + getErrorDesc(ex);\n                    consoleLog(errorMessage);\n                }\n            }\n        });\n        modules[name] = newModule;\n    }\n\n    api.createModule = function(name) {\n        // Allow 2 or 3 arguments (second argument is an optional array of dependencies)\n        var initFunc, dependencies;\n        if (arguments.length == 2) {\n            initFunc = arguments[1];\n            dependencies = [];\n        } else {\n            initFunc = arguments[2];\n            dependencies = arguments[1];\n        }\n\n        var module = createModule(false, name, dependencies, initFunc);\n\n        // Initialize the module immediately if the core is already initialized\n        if (api.initialized) {\n            module.init();\n        }\n    };\n\n    api.createCoreModule = function(name, dependencies, initFunc) {\n        createModule(true, name, dependencies, initFunc);\n    };\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Ensure rangy.rangePrototype and rangy.selectionPrototype are available immediately\n\n    function RangePrototype() {}\n    api.RangePrototype = RangePrototype;\n    api.rangePrototype = new RangePrototype();\n\n    function SelectionPrototype() {}\n    api.selectionPrototype = new SelectionPrototype();\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Wait for document to load before running tests\n\n    var docReady = false;\n\n    var loadHandler = function(e) {\n        if (!docReady) {\n            docReady = true;\n            if (!api.initialized && api.config.autoInitialize) {\n                init();\n            }\n        }\n    };\n\n    // Test whether we have window and document objects that we will need\n    if (typeof window == UNDEFINED) {\n        fail(\"No window found\");\n        return;\n    }\n    if (typeof document == UNDEFINED) {\n        fail(\"No document found\");\n        return;\n    }\n\n    if (isHostMethod(document, \"addEventListener\")) {\n        document.addEventListener(\"DOMContentLoaded\", loadHandler, false);\n    }\n\n    // Add a fallback in case the DOMContentLoaded event isn't supported\n    addListener(window, \"load\", loadHandler);\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n    \n    // DOM utility methods used by Rangy\n    api.createCoreModule(\"DomUtil\", [], function(api, module) {\n        var UNDEF = \"undefined\";\n        var util = api.util;\n\n        // Perform feature tests\n        if (!util.areHostMethods(document, [\"createDocumentFragment\", \"createElement\", \"createTextNode\"])) {\n            module.fail(\"document missing a Node creation method\");\n        }\n\n        if (!util.isHostMethod(document, \"getElementsByTagName\")) {\n            module.fail(\"document missing getElementsByTagName method\");\n        }\n\n        var el = document.createElement(\"div\");\n        if (!util.areHostMethods(el, [\"insertBefore\", \"appendChild\", \"cloneNode\"] ||\n                !util.areHostObjects(el, [\"previousSibling\", \"nextSibling\", \"childNodes\", \"parentNode\"]))) {\n            module.fail(\"Incomplete Element implementation\");\n        }\n\n        // innerHTML is required for Range's createContextualFragment method\n        if (!util.isHostProperty(el, \"innerHTML\")) {\n            module.fail(\"Element is missing innerHTML property\");\n        }\n\n        var textNode = document.createTextNode(\"test\");\n        if (!util.areHostMethods(textNode, [\"splitText\", \"deleteData\", \"insertData\", \"appendData\", \"cloneNode\"] ||\n                !util.areHostObjects(el, [\"previousSibling\", \"nextSibling\", \"childNodes\", \"parentNode\"]) ||\n                !util.areHostProperties(textNode, [\"data\"]))) {\n            module.fail(\"Incomplete Text Node implementation\");\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Removed use of indexOf because of a bizarre bug in Opera that is thrown in one of the Acid3 tests. I haven't been\n        // able to replicate it outside of the test. The bug is that indexOf returns -1 when called on an Array that\n        // contains just the document as a single element and the value searched for is the document.\n        var arrayContains = /*Array.prototype.indexOf ?\n            function(arr, val) {\n                return arr.indexOf(val) > -1;\n            }:*/\n\n            function(arr, val) {\n                var i = arr.length;\n                while (i--) {\n                    if (arr[i] === val) {\n                        return true;\n                    }\n                }\n                return false;\n            };\n\n        // Opera 11 puts HTML elements in the null namespace, it seems, and IE 7 has undefined namespaceURI\n        function isHtmlNamespace(node) {\n            var ns;\n            return typeof node.namespaceURI == UNDEF || ((ns = node.namespaceURI) === null || ns == \"http://www.w3.org/1999/xhtml\");\n        }\n\n        function parentElement(node) {\n            var parent = node.parentNode;\n            return (parent.nodeType == 1) ? parent : null;\n        }\n\n        function getNodeIndex(node) {\n            var i = 0;\n            while( (node = node.previousSibling) ) {\n                ++i;\n            }\n            return i;\n        }\n\n        function getNodeLength(node) {\n            switch (node.nodeType) {\n                case 7:\n                case 10:\n                    return 0;\n                case 3:\n                case 8:\n                    return node.length;\n                default:\n                    return node.childNodes.length;\n            }\n        }\n\n        function getCommonAncestor(node1, node2) {\n            var ancestors = [], n;\n            for (n = node1; n; n = n.parentNode) {\n                ancestors.push(n);\n            }\n\n            for (n = node2; n; n = n.parentNode) {\n                if (arrayContains(ancestors, n)) {\n                    return n;\n                }\n            }\n\n            return null;\n        }\n\n        function isAncestorOf(ancestor, descendant, selfIsAncestor) {\n            var n = selfIsAncestor ? descendant : descendant.parentNode;\n            while (n) {\n                if (n === ancestor) {\n                    return true;\n                } else {\n                    n = n.parentNode;\n                }\n            }\n            return false;\n        }\n\n        function isOrIsAncestorOf(ancestor, descendant) {\n            return isAncestorOf(ancestor, descendant, true);\n        }\n\n        function getClosestAncestorIn(node, ancestor, selfIsAncestor) {\n            var p, n = selfIsAncestor ? node : node.parentNode;\n            while (n) {\n                p = n.parentNode;\n                if (p === ancestor) {\n                    return n;\n                }\n                n = p;\n            }\n            return null;\n        }\n\n        function isCharacterDataNode(node) {\n            var t = node.nodeType;\n            return t == 3 || t == 4 || t == 8 ; // Text, CDataSection or Comment\n        }\n\n        function isTextOrCommentNode(node) {\n            if (!node) {\n                return false;\n            }\n            var t = node.nodeType;\n            return t == 3 || t == 8 ; // Text or Comment\n        }\n\n        function insertAfter(node, precedingNode) {\n            var nextNode = precedingNode.nextSibling, parent = precedingNode.parentNode;\n            if (nextNode) {\n                parent.insertBefore(node, nextNode);\n            } else {\n                parent.appendChild(node);\n            }\n            return node;\n        }\n\n        // Note that we cannot use splitText() because it is bugridden in IE 9.\n        function splitDataNode(node, index, positionsToPreserve) {\n            var newNode = node.cloneNode(false);\n            newNode.deleteData(0, index);\n            node.deleteData(index, node.length - index);\n            insertAfter(newNode, node);\n\n            // Preserve positions\n            if (positionsToPreserve) {\n                for (var i = 0, position; position = positionsToPreserve[i++]; ) {\n                    // Handle case where position was inside the portion of node after the split point\n                    if (position.node == node && position.offset > index) {\n                        position.node = newNode;\n                        position.offset -= index;\n                    }\n                    // Handle the case where the position is a node offset within node's parent\n                    else if (position.node == node.parentNode && position.offset > getNodeIndex(node)) {\n                        ++position.offset;\n                    }\n                }\n            }\n            return newNode;\n        }\n\n        function getDocument(node) {\n            if (node.nodeType == 9) {\n                return node;\n            } else if (typeof node.ownerDocument != UNDEF) {\n                return node.ownerDocument;\n            } else if (typeof node.document != UNDEF) {\n                return node.document;\n            } else if (node.parentNode) {\n                return getDocument(node.parentNode);\n            } else {\n                throw module.createError(\"getDocument: no document found for node\");\n            }\n        }\n\n        function getWindow(node) {\n            var doc = getDocument(node);\n            if (typeof doc.defaultView != UNDEF) {\n                return doc.defaultView;\n            } else if (typeof doc.parentWindow != UNDEF) {\n                return doc.parentWindow;\n            } else {\n                throw module.createError(\"Cannot get a window object for node\");\n            }\n        }\n\n        function getIframeDocument(iframeEl) {\n            if (typeof iframeEl.contentDocument != UNDEF) {\n                return iframeEl.contentDocument;\n            } else if (typeof iframeEl.contentWindow != UNDEF) {\n                return iframeEl.contentWindow.document;\n            } else {\n                throw module.createError(\"getIframeDocument: No Document object found for iframe element\");\n            }\n        }\n\n        function getIframeWindow(iframeEl) {\n            if (typeof iframeEl.contentWindow != UNDEF) {\n                return iframeEl.contentWindow;\n            } else if (typeof iframeEl.contentDocument != UNDEF) {\n                return iframeEl.contentDocument.defaultView;\n            } else {\n                throw module.createError(\"getIframeWindow: No Window object found for iframe element\");\n            }\n        }\n\n        // This looks bad. Is it worth it?\n        function isWindow(obj) {\n            return obj && util.isHostMethod(obj, \"setTimeout\") && util.isHostObject(obj, \"document\");\n        }\n\n        function getContentDocument(obj, module, methodName) {\n            var doc;\n\n            if (!obj) {\n                doc = document;\n            }\n\n            // Test if a DOM node has been passed and obtain a document object for it if so\n            else if (util.isHostProperty(obj, \"nodeType\")) {\n                doc = (obj.nodeType == 1 && obj.tagName.toLowerCase() == \"iframe\") ?\n                    getIframeDocument(obj) : getDocument(obj);\n            }\n\n            // Test if the doc parameter appears to be a Window object\n            else if (isWindow(obj)) {\n                doc = obj.document;\n            }\n\n            if (!doc) {\n                throw module.createError(methodName + \"(): Parameter must be a Window object or DOM node\");\n            }\n\n            return doc;\n        }\n\n        function getRootContainer(node) {\n            var parent;\n            while ( (parent = node.parentNode) ) {\n                node = parent;\n            }\n            return node;\n        }\n\n        function comparePoints(nodeA, offsetA, nodeB, offsetB) {\n            // See http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Comparing\n            var nodeC, root, childA, childB, n;\n            if (nodeA == nodeB) {\n                // Case 1: nodes are the same\n                return offsetA === offsetB ? 0 : (offsetA < offsetB) ? -1 : 1;\n            } else if ( (nodeC = getClosestAncestorIn(nodeB, nodeA, true)) ) {\n                // Case 2: node C (container B or an ancestor) is a child node of A\n                return offsetA <= getNodeIndex(nodeC) ? -1 : 1;\n            } else if ( (nodeC = getClosestAncestorIn(nodeA, nodeB, true)) ) {\n                // Case 3: node C (container A or an ancestor) is a child node of B\n                return getNodeIndex(nodeC) < offsetB  ? -1 : 1;\n            } else {\n                root = getCommonAncestor(nodeA, nodeB);\n                if (!root) {\n                    throw new Error(\"comparePoints error: nodes have no common ancestor\");\n                }\n\n                // Case 4: containers are siblings or descendants of siblings\n                childA = (nodeA === root) ? root : getClosestAncestorIn(nodeA, root, true);\n                childB = (nodeB === root) ? root : getClosestAncestorIn(nodeB, root, true);\n\n                if (childA === childB) {\n                    // This shouldn't be possible\n                    throw module.createError(\"comparePoints got to case 4 and childA and childB are the same!\");\n                } else {\n                    n = root.firstChild;\n                    while (n) {\n                        if (n === childA) {\n                            return -1;\n                        } else if (n === childB) {\n                            return 1;\n                        }\n                        n = n.nextSibling;\n                    }\n                }\n            }\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Test for IE's crash (IE 6/7) or exception (IE >= 8) when a reference to garbage-collected text node is queried\n        var crashyTextNodes = false;\n\n        function isBrokenNode(node) {\n            var n;\n            try {\n                n = node.parentNode;\n                return false;\n            } catch (e) {\n                return true;\n            }\n        }\n\n        (function() {\n            var el = document.createElement(\"b\");\n            el.innerHTML = \"1\";\n            var textNode = el.firstChild;\n            el.innerHTML = \"<br>\";\n            crashyTextNodes = isBrokenNode(textNode);\n\n            api.features.crashyTextNodes = crashyTextNodes;\n        })();\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        function inspectNode(node) {\n            if (!node) {\n                return \"[No node]\";\n            }\n            if (crashyTextNodes && isBrokenNode(node)) {\n                return \"[Broken node]\";\n            }\n            if (isCharacterDataNode(node)) {\n                return '\"' + node.data + '\"';\n            }\n            if (node.nodeType == 1) {\n                var idAttr = node.id ? ' id=\"' + node.id + '\"' : \"\";\n                return \"<\" + node.nodeName + idAttr + \">[index:\" + getNodeIndex(node) + \",length:\" + node.childNodes.length + \"][\" + (node.innerHTML || \"[innerHTML not supported]\").slice(0, 25) + \"]\";\n            }\n            return node.nodeName;\n        }\n\n        function fragmentFromNodeChildren(node) {\n            var fragment = getDocument(node).createDocumentFragment(), child;\n            while ( (child = node.firstChild) ) {\n                fragment.appendChild(child);\n            }\n            return fragment;\n        }\n\n        var getComputedStyleProperty;\n        if (typeof window.getComputedStyle != UNDEF) {\n            getComputedStyleProperty = function(el, propName) {\n                return getWindow(el).getComputedStyle(el, null)[propName];\n            };\n        } else if (typeof document.documentElement.currentStyle != UNDEF) {\n            getComputedStyleProperty = function(el, propName) {\n                return el.currentStyle[propName];\n            };\n        } else {\n            module.fail(\"No means of obtaining computed style properties found\");\n        }\n\n        function NodeIterator(root) {\n            this.root = root;\n            this._next = root;\n        }\n\n        NodeIterator.prototype = {\n            _current: null,\n\n            hasNext: function() {\n                return !!this._next;\n            },\n\n            next: function() {\n                var n = this._current = this._next;\n                var child, next;\n                if (this._current) {\n                    child = n.firstChild;\n                    if (child) {\n                        this._next = child;\n                    } else {\n                        next = null;\n                        while ((n !== this.root) && !(next = n.nextSibling)) {\n                            n = n.parentNode;\n                        }\n                        this._next = next;\n                    }\n                }\n                return this._current;\n            },\n\n            detach: function() {\n                this._current = this._next = this.root = null;\n            }\n        };\n\n        function createIterator(root) {\n            return new NodeIterator(root);\n        }\n\n        function DomPosition(node, offset) {\n            this.node = node;\n            this.offset = offset;\n        }\n\n        DomPosition.prototype = {\n            equals: function(pos) {\n                return !!pos && this.node === pos.node && this.offset == pos.offset;\n            },\n\n            inspect: function() {\n                return \"[DomPosition(\" + inspectNode(this.node) + \":\" + this.offset + \")]\";\n            },\n\n            toString: function() {\n                return this.inspect();\n            }\n        };\n\n        function DOMException(codeName) {\n            this.code = this[codeName];\n            this.codeName = codeName;\n            this.message = \"DOMException: \" + this.codeName;\n        }\n\n        DOMException.prototype = {\n            INDEX_SIZE_ERR: 1,\n            HIERARCHY_REQUEST_ERR: 3,\n            WRONG_DOCUMENT_ERR: 4,\n            NO_MODIFICATION_ALLOWED_ERR: 7,\n            NOT_FOUND_ERR: 8,\n            NOT_SUPPORTED_ERR: 9,\n            INVALID_STATE_ERR: 11,\n            INVALID_NODE_TYPE_ERR: 24\n        };\n\n        DOMException.prototype.toString = function() {\n            return this.message;\n        };\n\n        api.dom = {\n            arrayContains: arrayContains,\n            isHtmlNamespace: isHtmlNamespace,\n            parentElement: parentElement,\n            getNodeIndex: getNodeIndex,\n            getNodeLength: getNodeLength,\n            getCommonAncestor: getCommonAncestor,\n            isAncestorOf: isAncestorOf,\n            isOrIsAncestorOf: isOrIsAncestorOf,\n            getClosestAncestorIn: getClosestAncestorIn,\n            isCharacterDataNode: isCharacterDataNode,\n            isTextOrCommentNode: isTextOrCommentNode,\n            insertAfter: insertAfter,\n            splitDataNode: splitDataNode,\n            getDocument: getDocument,\n            getWindow: getWindow,\n            getIframeWindow: getIframeWindow,\n            getIframeDocument: getIframeDocument,\n            getBody: util.getBody,\n            isWindow: isWindow,\n            getContentDocument: getContentDocument,\n            getRootContainer: getRootContainer,\n            comparePoints: comparePoints,\n            isBrokenNode: isBrokenNode,\n            inspectNode: inspectNode,\n            getComputedStyleProperty: getComputedStyleProperty,\n            fragmentFromNodeChildren: fragmentFromNodeChildren,\n            createIterator: createIterator,\n            DomPosition: DomPosition\n        };\n\n        api.DOMException = DOMException;\n    });\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Pure JavaScript implementation of DOM Range\n    api.createCoreModule(\"DomRange\", [\"DomUtil\"], function(api, module) {\n        var dom = api.dom;\n        var util = api.util;\n        var DomPosition = dom.DomPosition;\n        var DOMException = api.DOMException;\n\n        var isCharacterDataNode = dom.isCharacterDataNode;\n        var getNodeIndex = dom.getNodeIndex;\n        var isOrIsAncestorOf = dom.isOrIsAncestorOf;\n        var getDocument = dom.getDocument;\n        var comparePoints = dom.comparePoints;\n        var splitDataNode = dom.splitDataNode;\n        var getClosestAncestorIn = dom.getClosestAncestorIn;\n        var getNodeLength = dom.getNodeLength;\n        var arrayContains = dom.arrayContains;\n        var getRootContainer = dom.getRootContainer;\n        var crashyTextNodes = api.features.crashyTextNodes;\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Utility functions\n\n        function isNonTextPartiallySelected(node, range) {\n            return (node.nodeType != 3) &&\n                   (isOrIsAncestorOf(node, range.startContainer) || isOrIsAncestorOf(node, range.endContainer));\n        }\n\n        function getRangeDocument(range) {\n            return range.document || getDocument(range.startContainer);\n        }\n\n        function getBoundaryBeforeNode(node) {\n            return new DomPosition(node.parentNode, getNodeIndex(node));\n        }\n\n        function getBoundaryAfterNode(node) {\n            return new DomPosition(node.parentNode, getNodeIndex(node) + 1);\n        }\n\n        function insertNodeAtPosition(node, n, o) {\n            var firstNodeInserted = node.nodeType == 11 ? node.firstChild : node;\n            if (isCharacterDataNode(n)) {\n                if (o == n.length) {\n                    dom.insertAfter(node, n);\n                } else {\n                    n.parentNode.insertBefore(node, o == 0 ? n : splitDataNode(n, o));\n                }\n            } else if (o >= n.childNodes.length) {\n                n.appendChild(node);\n            } else {\n                n.insertBefore(node, n.childNodes[o]);\n            }\n            return firstNodeInserted;\n        }\n\n        function rangesIntersect(rangeA, rangeB, touchingIsIntersecting) {\n            assertRangeValid(rangeA);\n            assertRangeValid(rangeB);\n\n            if (getRangeDocument(rangeB) != getRangeDocument(rangeA)) {\n                throw new DOMException(\"WRONG_DOCUMENT_ERR\");\n            }\n\n            var startComparison = comparePoints(rangeA.startContainer, rangeA.startOffset, rangeB.endContainer, rangeB.endOffset),\n                endComparison = comparePoints(rangeA.endContainer, rangeA.endOffset, rangeB.startContainer, rangeB.startOffset);\n\n            return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0;\n        }\n\n        function cloneSubtree(iterator) {\n            var partiallySelected;\n            for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) {\n                partiallySelected = iterator.isPartiallySelectedSubtree();\n                node = node.cloneNode(!partiallySelected);\n                if (partiallySelected) {\n                    subIterator = iterator.getSubtreeIterator();\n                    node.appendChild(cloneSubtree(subIterator));\n                    subIterator.detach();\n                }\n\n                if (node.nodeType == 10) { // DocumentType\n                    throw new DOMException(\"HIERARCHY_REQUEST_ERR\");\n                }\n                frag.appendChild(node);\n            }\n            return frag;\n        }\n\n        function iterateSubtree(rangeIterator, func, iteratorState) {\n            var it, n;\n            iteratorState = iteratorState || { stop: false };\n            for (var node, subRangeIterator; node = rangeIterator.next(); ) {\n                if (rangeIterator.isPartiallySelectedSubtree()) {\n                    if (func(node) === false) {\n                        iteratorState.stop = true;\n                        return;\n                    } else {\n                        // The node is partially selected by the Range, so we can use a new RangeIterator on the portion of\n                        // the node selected by the Range.\n                        subRangeIterator = rangeIterator.getSubtreeIterator();\n                        iterateSubtree(subRangeIterator, func, iteratorState);\n                        subRangeIterator.detach();\n                        if (iteratorState.stop) {\n                            return;\n                        }\n                    }\n                } else {\n                    // The whole node is selected, so we can use efficient DOM iteration to iterate over the node and its\n                    // descendants\n                    it = dom.createIterator(node);\n                    while ( (n = it.next()) ) {\n                        if (func(n) === false) {\n                            iteratorState.stop = true;\n                            return;\n                        }\n                    }\n                }\n            }\n        }\n\n        function deleteSubtree(iterator) {\n            var subIterator;\n            while (iterator.next()) {\n                if (iterator.isPartiallySelectedSubtree()) {\n                    subIterator = iterator.getSubtreeIterator();\n                    deleteSubtree(subIterator);\n                    subIterator.detach();\n                } else {\n                    iterator.remove();\n                }\n            }\n        }\n\n        function extractSubtree(iterator) {\n            for (var node, frag = getRangeDocument(iterator.range).createDocumentFragment(), subIterator; node = iterator.next(); ) {\n\n                if (iterator.isPartiallySelectedSubtree()) {\n                    node = node.cloneNode(false);\n                    subIterator = iterator.getSubtreeIterator();\n                    node.appendChild(extractSubtree(subIterator));\n                    subIterator.detach();\n                } else {\n                    iterator.remove();\n                }\n                if (node.nodeType == 10) { // DocumentType\n                    throw new DOMException(\"HIERARCHY_REQUEST_ERR\");\n                }\n                frag.appendChild(node);\n            }\n            return frag;\n        }\n\n        function getNodesInRange(range, nodeTypes, filter) {\n            var filterNodeTypes = !!(nodeTypes && nodeTypes.length), regex;\n            var filterExists = !!filter;\n            if (filterNodeTypes) {\n                regex = new RegExp(\"^(\" + nodeTypes.join(\"|\") + \")$\");\n            }\n\n            var nodes = [];\n            iterateSubtree(new RangeIterator(range, false), function(node) {\n                if (filterNodeTypes && !regex.test(node.nodeType)) {\n                    return;\n                }\n                if (filterExists && !filter(node)) {\n                    return;\n                }\n                // Don't include a boundary container if it is a character data node and the range does not contain any\n                // of its character data. See issue 190.\n                var sc = range.startContainer;\n                if (node == sc && isCharacterDataNode(sc) && range.startOffset == sc.length) {\n                    return;\n                }\n\n                var ec = range.endContainer;\n                if (node == ec && isCharacterDataNode(ec) && range.endOffset == 0) {\n                    return;\n                }\n\n                nodes.push(node);\n            });\n            return nodes;\n        }\n\n        function inspect(range) {\n            var name = (typeof range.getName == \"undefined\") ? \"Range\" : range.getName();\n            return \"[\" + name + \"(\" + dom.inspectNode(range.startContainer) + \":\" + range.startOffset + \", \" +\n                    dom.inspectNode(range.endContainer) + \":\" + range.endOffset + \")]\";\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // RangeIterator code partially borrows from IERange by Tim Ryan (http://github.com/timcameronryan/IERange)\n\n        function RangeIterator(range, clonePartiallySelectedTextNodes) {\n            this.range = range;\n            this.clonePartiallySelectedTextNodes = clonePartiallySelectedTextNodes;\n\n\n            if (!range.collapsed) {\n                this.sc = range.startContainer;\n                this.so = range.startOffset;\n                this.ec = range.endContainer;\n                this.eo = range.endOffset;\n                var root = range.commonAncestorContainer;\n\n                if (this.sc === this.ec && isCharacterDataNode(this.sc)) {\n                    this.isSingleCharacterDataNode = true;\n                    this._first = this._last = this._next = this.sc;\n                } else {\n                    this._first = this._next = (this.sc === root && !isCharacterDataNode(this.sc)) ?\n                        this.sc.childNodes[this.so] : getClosestAncestorIn(this.sc, root, true);\n                    this._last = (this.ec === root && !isCharacterDataNode(this.ec)) ?\n                        this.ec.childNodes[this.eo - 1] : getClosestAncestorIn(this.ec, root, true);\n                }\n            }\n        }\n\n        RangeIterator.prototype = {\n            _current: null,\n            _next: null,\n            _first: null,\n            _last: null,\n            isSingleCharacterDataNode: false,\n\n            reset: function() {\n                this._current = null;\n                this._next = this._first;\n            },\n\n            hasNext: function() {\n                return !!this._next;\n            },\n\n            next: function() {\n                // Move to next node\n                var current = this._current = this._next;\n                if (current) {\n                    this._next = (current !== this._last) ? current.nextSibling : null;\n\n                    // Check for partially selected text nodes\n                    if (isCharacterDataNode(current) && this.clonePartiallySelectedTextNodes) {\n                        if (current === this.ec) {\n                            (current = current.cloneNode(true)).deleteData(this.eo, current.length - this.eo);\n                        }\n                        if (this._current === this.sc) {\n                            (current = current.cloneNode(true)).deleteData(0, this.so);\n                        }\n                    }\n                }\n\n                return current;\n            },\n\n            remove: function() {\n                var current = this._current, start, end;\n\n                if (isCharacterDataNode(current) && (current === this.sc || current === this.ec)) {\n                    start = (current === this.sc) ? this.so : 0;\n                    end = (current === this.ec) ? this.eo : current.length;\n                    if (start != end) {\n                        current.deleteData(start, end - start);\n                    }\n                } else {\n                    if (current.parentNode) {\n                        current.parentNode.removeChild(current);\n                    } else {\n                    }\n                }\n            },\n\n            // Checks if the current node is partially selected\n            isPartiallySelectedSubtree: function() {\n                var current = this._current;\n                return isNonTextPartiallySelected(current, this.range);\n            },\n\n            getSubtreeIterator: function() {\n                var subRange;\n                if (this.isSingleCharacterDataNode) {\n                    subRange = this.range.cloneRange();\n                    subRange.collapse(false);\n                } else {\n                    subRange = new Range(getRangeDocument(this.range));\n                    var current = this._current;\n                    var startContainer = current, startOffset = 0, endContainer = current, endOffset = getNodeLength(current);\n\n                    if (isOrIsAncestorOf(current, this.sc)) {\n                        startContainer = this.sc;\n                        startOffset = this.so;\n                    }\n                    if (isOrIsAncestorOf(current, this.ec)) {\n                        endContainer = this.ec;\n                        endOffset = this.eo;\n                    }\n\n                    updateBoundaries(subRange, startContainer, startOffset, endContainer, endOffset);\n                }\n                return new RangeIterator(subRange, this.clonePartiallySelectedTextNodes);\n            },\n\n            detach: function() {\n                this.range = this._current = this._next = this._first = this._last = this.sc = this.so = this.ec = this.eo = null;\n            }\n        };\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        var beforeAfterNodeTypes = [1, 3, 4, 5, 7, 8, 10];\n        var rootContainerNodeTypes = [2, 9, 11];\n        var readonlyNodeTypes = [5, 6, 10, 12];\n        var insertableNodeTypes = [1, 3, 4, 5, 7, 8, 10, 11];\n        var surroundNodeTypes = [1, 3, 4, 5, 7, 8];\n\n        function createAncestorFinder(nodeTypes) {\n            return function(node, selfIsAncestor) {\n                var t, n = selfIsAncestor ? node : node.parentNode;\n                while (n) {\n                    t = n.nodeType;\n                    if (arrayContains(nodeTypes, t)) {\n                        return n;\n                    }\n                    n = n.parentNode;\n                }\n                return null;\n            };\n        }\n\n        var getDocumentOrFragmentContainer = createAncestorFinder( [9, 11] );\n        var getReadonlyAncestor = createAncestorFinder(readonlyNodeTypes);\n        var getDocTypeNotationEntityAncestor = createAncestorFinder( [6, 10, 12] );\n\n        function assertNoDocTypeNotationEntityAncestor(node, allowSelf) {\n            if (getDocTypeNotationEntityAncestor(node, allowSelf)) {\n                throw new DOMException(\"INVALID_NODE_TYPE_ERR\");\n            }\n        }\n\n        function assertValidNodeType(node, invalidTypes) {\n            if (!arrayContains(invalidTypes, node.nodeType)) {\n                throw new DOMException(\"INVALID_NODE_TYPE_ERR\");\n            }\n        }\n\n        function assertValidOffset(node, offset) {\n            if (offset < 0 || offset > (isCharacterDataNode(node) ? node.length : node.childNodes.length)) {\n                throw new DOMException(\"INDEX_SIZE_ERR\");\n            }\n        }\n\n        function assertSameDocumentOrFragment(node1, node2) {\n            if (getDocumentOrFragmentContainer(node1, true) !== getDocumentOrFragmentContainer(node2, true)) {\n                throw new DOMException(\"WRONG_DOCUMENT_ERR\");\n            }\n        }\n\n        function assertNodeNotReadOnly(node) {\n            if (getReadonlyAncestor(node, true)) {\n                throw new DOMException(\"NO_MODIFICATION_ALLOWED_ERR\");\n            }\n        }\n\n        function assertNode(node, codeName) {\n            if (!node) {\n                throw new DOMException(codeName);\n            }\n        }\n\n        function isOrphan(node) {\n            return (crashyTextNodes && dom.isBrokenNode(node)) ||\n                !arrayContains(rootContainerNodeTypes, node.nodeType) && !getDocumentOrFragmentContainer(node, true);\n        }\n\n        function isValidOffset(node, offset) {\n            return offset <= (isCharacterDataNode(node) ? node.length : node.childNodes.length);\n        }\n\n        function isRangeValid(range) {\n            return (!!range.startContainer && !!range.endContainer &&\n                    !isOrphan(range.startContainer) &&\n                    !isOrphan(range.endContainer) &&\n                    isValidOffset(range.startContainer, range.startOffset) &&\n                    isValidOffset(range.endContainer, range.endOffset));\n        }\n\n        function assertRangeValid(range) {\n            if (!isRangeValid(range)) {\n                throw new Error(\"Range error: Range is no longer valid after DOM mutation (\" + range.inspect() + \")\");\n            }\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Test the browser's innerHTML support to decide how to implement createContextualFragment\n        var styleEl = document.createElement(\"style\");\n        var htmlParsingConforms = false;\n        try {\n            styleEl.innerHTML = \"<b>x</b>\";\n            htmlParsingConforms = (styleEl.firstChild.nodeType == 3); // Opera incorrectly creates an element node\n        } catch (e) {\n            // IE 6 and 7 throw\n        }\n\n        api.features.htmlParsingConforms = htmlParsingConforms;\n\n        var createContextualFragment = htmlParsingConforms ?\n\n            // Implementation as per HTML parsing spec, trusting in the browser's implementation of innerHTML. See\n            // discussion and base code for this implementation at issue 67.\n            // Spec: http://html5.org/specs/dom-parsing.html#extensions-to-the-range-interface\n            // Thanks to Aleks Williams.\n            function(fragmentStr) {\n                // \"Let node the context object's start's node.\"\n                var node = this.startContainer;\n                var doc = getDocument(node);\n\n                // \"If the context object's start's node is null, raise an INVALID_STATE_ERR\n                // exception and abort these steps.\"\n                if (!node) {\n                    throw new DOMException(\"INVALID_STATE_ERR\");\n                }\n\n                // \"Let element be as follows, depending on node's interface:\"\n                // Document, Document Fragment: null\n                var el = null;\n\n                // \"Element: node\"\n                if (node.nodeType == 1) {\n                    el = node;\n\n                // \"Text, Comment: node's parentElement\"\n                } else if (isCharacterDataNode(node)) {\n                    el = dom.parentElement(node);\n                }\n\n                // \"If either element is null or element's ownerDocument is an HTML document\n                // and element's local name is \"html\" and element's namespace is the HTML\n                // namespace\"\n                if (el === null || (\n                    el.nodeName == \"HTML\" &&\n                    dom.isHtmlNamespace(getDocument(el).documentElement) &&\n                    dom.isHtmlNamespace(el)\n                )) {\n\n                // \"let element be a new Element with \"body\" as its local name and the HTML\n                // namespace as its namespace.\"\"\n                    el = doc.createElement(\"body\");\n                } else {\n                    el = el.cloneNode(false);\n                }\n\n                // \"If the node's document is an HTML document: Invoke the HTML fragment parsing algorithm.\"\n                // \"If the node's document is an XML document: Invoke the XML fragment parsing algorithm.\"\n                // \"In either case, the algorithm must be invoked with fragment as the input\n                // and element as the context element.\"\n                el.innerHTML = fragmentStr;\n\n                // \"If this raises an exception, then abort these steps. Otherwise, let new\n                // children be the nodes returned.\"\n\n                // \"Let fragment be a new DocumentFragment.\"\n                // \"Append all new children to fragment.\"\n                // \"Return fragment.\"\n                return dom.fragmentFromNodeChildren(el);\n            } :\n\n            // In this case, innerHTML cannot be trusted, so fall back to a simpler, non-conformant implementation that\n            // previous versions of Rangy used (with the exception of using a body element rather than a div)\n            function(fragmentStr) {\n                var doc = getRangeDocument(this);\n                var el = doc.createElement(\"body\");\n                el.innerHTML = fragmentStr;\n\n                return dom.fragmentFromNodeChildren(el);\n            };\n\n        function splitRangeBoundaries(range, positionsToPreserve) {\n            assertRangeValid(range);\n\n            var sc = range.startContainer, so = range.startOffset, ec = range.endContainer, eo = range.endOffset;\n            var startEndSame = (sc === ec);\n\n            if (isCharacterDataNode(ec) && eo > 0 && eo < ec.length) {\n                splitDataNode(ec, eo, positionsToPreserve);\n            }\n\n            if (isCharacterDataNode(sc) && so > 0 && so < sc.length) {\n                sc = splitDataNode(sc, so, positionsToPreserve);\n                if (startEndSame) {\n                    eo -= so;\n                    ec = sc;\n                } else if (ec == sc.parentNode && eo >= getNodeIndex(sc)) {\n                    eo++;\n                }\n                so = 0;\n            }\n            range.setStartAndEnd(sc, so, ec, eo);\n        }\n        \n        function rangeToHtml(range) {\n            assertRangeValid(range);\n            var container = range.commonAncestorContainer.parentNode.cloneNode(false);\n            container.appendChild( range.cloneContents() );\n            return container.innerHTML;\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        var rangeProperties = [\"startContainer\", \"startOffset\", \"endContainer\", \"endOffset\", \"collapsed\",\n            \"commonAncestorContainer\"];\n\n        var s2s = 0, s2e = 1, e2e = 2, e2s = 3;\n        var n_b = 0, n_a = 1, n_b_a = 2, n_i = 3;\n\n        util.extend(api.rangePrototype, {\n            compareBoundaryPoints: function(how, range) {\n                assertRangeValid(this);\n                assertSameDocumentOrFragment(this.startContainer, range.startContainer);\n\n                var nodeA, offsetA, nodeB, offsetB;\n                var prefixA = (how == e2s || how == s2s) ? \"start\" : \"end\";\n                var prefixB = (how == s2e || how == s2s) ? \"start\" : \"end\";\n                nodeA = this[prefixA + \"Container\"];\n                offsetA = this[prefixA + \"Offset\"];\n                nodeB = range[prefixB + \"Container\"];\n                offsetB = range[prefixB + \"Offset\"];\n                return comparePoints(nodeA, offsetA, nodeB, offsetB);\n            },\n\n            insertNode: function(node) {\n                assertRangeValid(this);\n                assertValidNodeType(node, insertableNodeTypes);\n                assertNodeNotReadOnly(this.startContainer);\n\n                if (isOrIsAncestorOf(node, this.startContainer)) {\n                    throw new DOMException(\"HIERARCHY_REQUEST_ERR\");\n                }\n\n                // No check for whether the container of the start of the Range is of a type that does not allow\n                // children of the type of node: the browser's DOM implementation should do this for us when we attempt\n                // to add the node\n\n                var firstNodeInserted = insertNodeAtPosition(node, this.startContainer, this.startOffset);\n                this.setStartBefore(firstNodeInserted);\n            },\n\n            cloneContents: function() {\n                assertRangeValid(this);\n\n                var clone, frag;\n                if (this.collapsed) {\n                    return getRangeDocument(this).createDocumentFragment();\n                } else {\n                    if (this.startContainer === this.endContainer && isCharacterDataNode(this.startContainer)) {\n                        clone = this.startContainer.cloneNode(true);\n                        clone.data = clone.data.slice(this.startOffset, this.endOffset);\n                        frag = getRangeDocument(this).createDocumentFragment();\n                        frag.appendChild(clone);\n                        return frag;\n                    } else {\n                        var iterator = new RangeIterator(this, true);\n                        clone = cloneSubtree(iterator);\n                        iterator.detach();\n                    }\n                    return clone;\n                }\n            },\n\n            canSurroundContents: function() {\n                assertRangeValid(this);\n                assertNodeNotReadOnly(this.startContainer);\n                assertNodeNotReadOnly(this.endContainer);\n\n                // Check if the contents can be surrounded. Specifically, this means whether the range partially selects\n                // no non-text nodes.\n                var iterator = new RangeIterator(this, true);\n                var boundariesInvalid = (iterator._first && (isNonTextPartiallySelected(iterator._first, this)) ||\n                        (iterator._last && isNonTextPartiallySelected(iterator._last, this)));\n                iterator.detach();\n                return !boundariesInvalid;\n            },\n\n            surroundContents: function(node) {\n                assertValidNodeType(node, surroundNodeTypes);\n\n                if (!this.canSurroundContents()) {\n                    throw new DOMException(\"INVALID_STATE_ERR\");\n                }\n\n                // Extract the contents\n                var content = this.extractContents();\n\n                // Clear the children of the node\n                if (node.hasChildNodes()) {\n                    while (node.lastChild) {\n                        node.removeChild(node.lastChild);\n                    }\n                }\n\n                // Insert the new node and add the extracted contents\n                insertNodeAtPosition(node, this.startContainer, this.startOffset);\n                node.appendChild(content);\n\n                this.selectNode(node);\n            },\n\n            cloneRange: function() {\n                assertRangeValid(this);\n                var range = new Range(getRangeDocument(this));\n                var i = rangeProperties.length, prop;\n                while (i--) {\n                    prop = rangeProperties[i];\n                    range[prop] = this[prop];\n                }\n                return range;\n            },\n\n            toString: function() {\n                assertRangeValid(this);\n                var sc = this.startContainer;\n                if (sc === this.endContainer && isCharacterDataNode(sc)) {\n                    return (sc.nodeType == 3 || sc.nodeType == 4) ? sc.data.slice(this.startOffset, this.endOffset) : \"\";\n                } else {\n                    var textParts = [], iterator = new RangeIterator(this, true);\n                    iterateSubtree(iterator, function(node) {\n                        // Accept only text or CDATA nodes, not comments\n                        if (node.nodeType == 3 || node.nodeType == 4) {\n                            textParts.push(node.data);\n                        }\n                    });\n                    iterator.detach();\n                    return textParts.join(\"\");\n                }\n            },\n\n            // The methods below are all non-standard. The following batch were introduced by Mozilla but have since\n            // been removed from Mozilla.\n\n            compareNode: function(node) {\n                assertRangeValid(this);\n\n                var parent = node.parentNode;\n                var nodeIndex = getNodeIndex(node);\n\n                if (!parent) {\n                    throw new DOMException(\"NOT_FOUND_ERR\");\n                }\n\n                var startComparison = this.comparePoint(parent, nodeIndex),\n                    endComparison = this.comparePoint(parent, nodeIndex + 1);\n\n                if (startComparison < 0) { // Node starts before\n                    return (endComparison > 0) ? n_b_a : n_b;\n                } else {\n                    return (endComparison > 0) ? n_a : n_i;\n                }\n            },\n\n            comparePoint: function(node, offset) {\n                assertRangeValid(this);\n                assertNode(node, \"HIERARCHY_REQUEST_ERR\");\n                assertSameDocumentOrFragment(node, this.startContainer);\n\n                if (comparePoints(node, offset, this.startContainer, this.startOffset) < 0) {\n                    return -1;\n                } else if (comparePoints(node, offset, this.endContainer, this.endOffset) > 0) {\n                    return 1;\n                }\n                return 0;\n            },\n\n            createContextualFragment: createContextualFragment,\n\n            toHtml: function() {\n                return rangeToHtml(this);\n            },\n\n            // touchingIsIntersecting determines whether this method considers a node that borders a range intersects\n            // with it (as in WebKit) or not (as in Gecko pre-1.9, and the default)\n            intersectsNode: function(node, touchingIsIntersecting) {\n                assertRangeValid(this);\n                assertNode(node, \"NOT_FOUND_ERR\");\n                if (getDocument(node) !== getRangeDocument(this)) {\n                    return false;\n                }\n\n                var parent = node.parentNode, offset = getNodeIndex(node);\n                assertNode(parent, \"NOT_FOUND_ERR\");\n\n                var startComparison = comparePoints(parent, offset, this.endContainer, this.endOffset),\n                    endComparison = comparePoints(parent, offset + 1, this.startContainer, this.startOffset);\n\n                return touchingIsIntersecting ? startComparison <= 0 && endComparison >= 0 : startComparison < 0 && endComparison > 0;\n            },\n\n            isPointInRange: function(node, offset) {\n                assertRangeValid(this);\n                assertNode(node, \"HIERARCHY_REQUEST_ERR\");\n                assertSameDocumentOrFragment(node, this.startContainer);\n\n                return (comparePoints(node, offset, this.startContainer, this.startOffset) >= 0) &&\n                       (comparePoints(node, offset, this.endContainer, this.endOffset) <= 0);\n            },\n\n            // The methods below are non-standard and invented by me.\n\n            // Sharing a boundary start-to-end or end-to-start does not count as intersection.\n            intersectsRange: function(range) {\n                return rangesIntersect(this, range, false);\n            },\n\n            // Sharing a boundary start-to-end or end-to-start does count as intersection.\n            intersectsOrTouchesRange: function(range) {\n                return rangesIntersect(this, range, true);\n            },\n\n            intersection: function(range) {\n                if (this.intersectsRange(range)) {\n                    var startComparison = comparePoints(this.startContainer, this.startOffset, range.startContainer, range.startOffset),\n                        endComparison = comparePoints(this.endContainer, this.endOffset, range.endContainer, range.endOffset);\n\n                    var intersectionRange = this.cloneRange();\n                    if (startComparison == -1) {\n                        intersectionRange.setStart(range.startContainer, range.startOffset);\n                    }\n                    if (endComparison == 1) {\n                        intersectionRange.setEnd(range.endContainer, range.endOffset);\n                    }\n                    return intersectionRange;\n                }\n                return null;\n            },\n\n            union: function(range) {\n                if (this.intersectsOrTouchesRange(range)) {\n                    var unionRange = this.cloneRange();\n                    if (comparePoints(range.startContainer, range.startOffset, this.startContainer, this.startOffset) == -1) {\n                        unionRange.setStart(range.startContainer, range.startOffset);\n                    }\n                    if (comparePoints(range.endContainer, range.endOffset, this.endContainer, this.endOffset) == 1) {\n                        unionRange.setEnd(range.endContainer, range.endOffset);\n                    }\n                    return unionRange;\n                } else {\n                    throw new DOMException(\"Ranges do not intersect\");\n                }\n            },\n\n            containsNode: function(node, allowPartial) {\n                if (allowPartial) {\n                    return this.intersectsNode(node, false);\n                } else {\n                    return this.compareNode(node) == n_i;\n                }\n            },\n\n            containsNodeContents: function(node) {\n                return this.comparePoint(node, 0) >= 0 && this.comparePoint(node, getNodeLength(node)) <= 0;\n            },\n\n            containsRange: function(range) {\n                var intersection = this.intersection(range);\n                return intersection !== null && range.equals(intersection);\n            },\n\n            containsNodeText: function(node) {\n                var nodeRange = this.cloneRange();\n                nodeRange.selectNode(node);\n                var textNodes = nodeRange.getNodes([3]);\n                if (textNodes.length > 0) {\n                    nodeRange.setStart(textNodes[0], 0);\n                    var lastTextNode = textNodes.pop();\n                    nodeRange.setEnd(lastTextNode, lastTextNode.length);\n                    return this.containsRange(nodeRange);\n                } else {\n                    return this.containsNodeContents(node);\n                }\n            },\n\n            getNodes: function(nodeTypes, filter) {\n                assertRangeValid(this);\n                return getNodesInRange(this, nodeTypes, filter);\n            },\n\n            getDocument: function() {\n                return getRangeDocument(this);\n            },\n\n            collapseBefore: function(node) {\n                this.setEndBefore(node);\n                this.collapse(false);\n            },\n\n            collapseAfter: function(node) {\n                this.setStartAfter(node);\n                this.collapse(true);\n            },\n            \n            getBookmark: function(containerNode) {\n                var doc = getRangeDocument(this);\n                var preSelectionRange = api.createRange(doc);\n                containerNode = containerNode || dom.getBody(doc);\n                preSelectionRange.selectNodeContents(containerNode);\n                var range = this.intersection(preSelectionRange);\n                var start = 0, end = 0;\n                if (range) {\n                    preSelectionRange.setEnd(range.startContainer, range.startOffset);\n                    start = preSelectionRange.toString().length;\n                    end = start + range.toString().length;\n                }\n\n                return {\n                    start: start,\n                    end: end,\n                    containerNode: containerNode\n                };\n            },\n            \n            moveToBookmark: function(bookmark) {\n                var containerNode = bookmark.containerNode;\n                var charIndex = 0;\n                this.setStart(containerNode, 0);\n                this.collapse(true);\n                var nodeStack = [containerNode], node, foundStart = false, stop = false;\n                var nextCharIndex, i, childNodes;\n\n                while (!stop && (node = nodeStack.pop())) {\n                    if (node.nodeType == 3) {\n                        nextCharIndex = charIndex + node.length;\n                        if (!foundStart && bookmark.start >= charIndex && bookmark.start <= nextCharIndex) {\n                            this.setStart(node, bookmark.start - charIndex);\n                            foundStart = true;\n                        }\n                        if (foundStart && bookmark.end >= charIndex && bookmark.end <= nextCharIndex) {\n                            this.setEnd(node, bookmark.end - charIndex);\n                            stop = true;\n                        }\n                        charIndex = nextCharIndex;\n                    } else {\n                        childNodes = node.childNodes;\n                        i = childNodes.length;\n                        while (i--) {\n                            nodeStack.push(childNodes[i]);\n                        }\n                    }\n                }\n            },\n\n            getName: function() {\n                return \"DomRange\";\n            },\n\n            equals: function(range) {\n                return Range.rangesEqual(this, range);\n            },\n\n            isValid: function() {\n                return isRangeValid(this);\n            },\n            \n            inspect: function() {\n                return inspect(this);\n            },\n            \n            detach: function() {\n                // In DOM4, detach() is now a no-op.\n            }\n        });\n\n        function copyComparisonConstantsToObject(obj) {\n            obj.START_TO_START = s2s;\n            obj.START_TO_END = s2e;\n            obj.END_TO_END = e2e;\n            obj.END_TO_START = e2s;\n\n            obj.NODE_BEFORE = n_b;\n            obj.NODE_AFTER = n_a;\n            obj.NODE_BEFORE_AND_AFTER = n_b_a;\n            obj.NODE_INSIDE = n_i;\n        }\n\n        function copyComparisonConstants(constructor) {\n            copyComparisonConstantsToObject(constructor);\n            copyComparisonConstantsToObject(constructor.prototype);\n        }\n\n        function createRangeContentRemover(remover, boundaryUpdater) {\n            return function() {\n                assertRangeValid(this);\n\n                var sc = this.startContainer, so = this.startOffset, root = this.commonAncestorContainer;\n\n                var iterator = new RangeIterator(this, true);\n\n                // Work out where to position the range after content removal\n                var node, boundary;\n                if (sc !== root) {\n                    node = getClosestAncestorIn(sc, root, true);\n                    boundary = getBoundaryAfterNode(node);\n                    sc = boundary.node;\n                    so = boundary.offset;\n                }\n\n                // Check none of the range is read-only\n                iterateSubtree(iterator, assertNodeNotReadOnly);\n\n                iterator.reset();\n\n                // Remove the content\n                var returnValue = remover(iterator);\n                iterator.detach();\n\n                // Move to the new position\n                boundaryUpdater(this, sc, so, sc, so);\n\n                return returnValue;\n            };\n        }\n\n        function createPrototypeRange(constructor, boundaryUpdater) {\n            function createBeforeAfterNodeSetter(isBefore, isStart) {\n                return function(node) {\n                    assertValidNodeType(node, beforeAfterNodeTypes);\n                    assertValidNodeType(getRootContainer(node), rootContainerNodeTypes);\n\n                    var boundary = (isBefore ? getBoundaryBeforeNode : getBoundaryAfterNode)(node);\n                    (isStart ? setRangeStart : setRangeEnd)(this, boundary.node, boundary.offset);\n                };\n            }\n\n            function setRangeStart(range, node, offset) {\n                var ec = range.endContainer, eo = range.endOffset;\n                if (node !== range.startContainer || offset !== range.startOffset) {\n                    // Check the root containers of the range and the new boundary, and also check whether the new boundary\n                    // is after the current end. In either case, collapse the range to the new position\n                    if (getRootContainer(node) != getRootContainer(ec) || comparePoints(node, offset, ec, eo) == 1) {\n                        ec = node;\n                        eo = offset;\n                    }\n                    boundaryUpdater(range, node, offset, ec, eo);\n                }\n            }\n\n            function setRangeEnd(range, node, offset) {\n                var sc = range.startContainer, so = range.startOffset;\n                if (node !== range.endContainer || offset !== range.endOffset) {\n                    // Check the root containers of the range and the new boundary, and also check whether the new boundary\n                    // is after the current end. In either case, collapse the range to the new position\n                    if (getRootContainer(node) != getRootContainer(sc) || comparePoints(node, offset, sc, so) == -1) {\n                        sc = node;\n                        so = offset;\n                    }\n                    boundaryUpdater(range, sc, so, node, offset);\n                }\n            }\n\n            // Set up inheritance\n            var F = function() {};\n            F.prototype = api.rangePrototype;\n            constructor.prototype = new F();\n\n            util.extend(constructor.prototype, {\n                setStart: function(node, offset) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n                    assertValidOffset(node, offset);\n\n                    setRangeStart(this, node, offset);\n                },\n\n                setEnd: function(node, offset) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n                    assertValidOffset(node, offset);\n\n                    setRangeEnd(this, node, offset);\n                },\n\n                /**\n                 * Convenience method to set a range's start and end boundaries. Overloaded as follows:\n                 * - Two parameters (node, offset) creates a collapsed range at that position\n                 * - Three parameters (node, startOffset, endOffset) creates a range contained with node starting at\n                 *   startOffset and ending at endOffset\n                 * - Four parameters (startNode, startOffset, endNode, endOffset) creates a range starting at startOffset in\n                 *   startNode and ending at endOffset in endNode\n                 */\n                setStartAndEnd: function() {\n                    var args = arguments;\n                    var sc = args[0], so = args[1], ec = sc, eo = so;\n\n                    switch (args.length) {\n                        case 3:\n                            eo = args[2];\n                            break;\n                        case 4:\n                            ec = args[2];\n                            eo = args[3];\n                            break;\n                    }\n\n                    boundaryUpdater(this, sc, so, ec, eo);\n                },\n                \n                setBoundary: function(node, offset, isStart) {\n                    this[\"set\" + (isStart ? \"Start\" : \"End\")](node, offset);\n                },\n\n                setStartBefore: createBeforeAfterNodeSetter(true, true),\n                setStartAfter: createBeforeAfterNodeSetter(false, true),\n                setEndBefore: createBeforeAfterNodeSetter(true, false),\n                setEndAfter: createBeforeAfterNodeSetter(false, false),\n\n                collapse: function(isStart) {\n                    assertRangeValid(this);\n                    if (isStart) {\n                        boundaryUpdater(this, this.startContainer, this.startOffset, this.startContainer, this.startOffset);\n                    } else {\n                        boundaryUpdater(this, this.endContainer, this.endOffset, this.endContainer, this.endOffset);\n                    }\n                },\n\n                selectNodeContents: function(node) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n\n                    boundaryUpdater(this, node, 0, node, getNodeLength(node));\n                },\n\n                selectNode: function(node) {\n                    assertNoDocTypeNotationEntityAncestor(node, false);\n                    assertValidNodeType(node, beforeAfterNodeTypes);\n\n                    var start = getBoundaryBeforeNode(node), end = getBoundaryAfterNode(node);\n                    boundaryUpdater(this, start.node, start.offset, end.node, end.offset);\n                },\n\n                extractContents: createRangeContentRemover(extractSubtree, boundaryUpdater),\n\n                deleteContents: createRangeContentRemover(deleteSubtree, boundaryUpdater),\n\n                canSurroundContents: function() {\n                    assertRangeValid(this);\n                    assertNodeNotReadOnly(this.startContainer);\n                    assertNodeNotReadOnly(this.endContainer);\n\n                    // Check if the contents can be surrounded. Specifically, this means whether the range partially selects\n                    // no non-text nodes.\n                    var iterator = new RangeIterator(this, true);\n                    var boundariesInvalid = (iterator._first && isNonTextPartiallySelected(iterator._first, this) ||\n                            (iterator._last && isNonTextPartiallySelected(iterator._last, this)));\n                    iterator.detach();\n                    return !boundariesInvalid;\n                },\n\n                splitBoundaries: function() {\n                    splitRangeBoundaries(this);\n                },\n\n                splitBoundariesPreservingPositions: function(positionsToPreserve) {\n                    splitRangeBoundaries(this, positionsToPreserve);\n                },\n\n                normalizeBoundaries: function() {\n                    assertRangeValid(this);\n\n                    var sc = this.startContainer, so = this.startOffset, ec = this.endContainer, eo = this.endOffset;\n\n                    var mergeForward = function(node) {\n                        var sibling = node.nextSibling;\n                        if (sibling && sibling.nodeType == node.nodeType) {\n                            ec = node;\n                            eo = node.length;\n                            node.appendData(sibling.data);\n                            sibling.parentNode.removeChild(sibling);\n                        }\n                    };\n\n                    var mergeBackward = function(node) {\n                        var sibling = node.previousSibling;\n                        if (sibling && sibling.nodeType == node.nodeType) {\n                            sc = node;\n                            var nodeLength = node.length;\n                            so = sibling.length;\n                            node.insertData(0, sibling.data);\n                            sibling.parentNode.removeChild(sibling);\n                            if (sc == ec) {\n                                eo += so;\n                                ec = sc;\n                            } else if (ec == node.parentNode) {\n                                var nodeIndex = getNodeIndex(node);\n                                if (eo == nodeIndex) {\n                                    ec = node;\n                                    eo = nodeLength;\n                                } else if (eo > nodeIndex) {\n                                    eo--;\n                                }\n                            }\n                        }\n                    };\n\n                    var normalizeStart = true;\n\n                    if (isCharacterDataNode(ec)) {\n                        if (ec.length == eo) {\n                            mergeForward(ec);\n                        }\n                    } else {\n                        if (eo > 0) {\n                            var endNode = ec.childNodes[eo - 1];\n                            if (endNode && isCharacterDataNode(endNode)) {\n                                mergeForward(endNode);\n                            }\n                        }\n                        normalizeStart = !this.collapsed;\n                    }\n\n                    if (normalizeStart) {\n                        if (isCharacterDataNode(sc)) {\n                            if (so == 0) {\n                                mergeBackward(sc);\n                            }\n                        } else {\n                            if (so < sc.childNodes.length) {\n                                var startNode = sc.childNodes[so];\n                                if (startNode && isCharacterDataNode(startNode)) {\n                                    mergeBackward(startNode);\n                                }\n                            }\n                        }\n                    } else {\n                        sc = ec;\n                        so = eo;\n                    }\n\n                    boundaryUpdater(this, sc, so, ec, eo);\n                },\n\n                collapseToPoint: function(node, offset) {\n                    assertNoDocTypeNotationEntityAncestor(node, true);\n                    assertValidOffset(node, offset);\n                    this.setStartAndEnd(node, offset);\n                }\n            });\n\n            copyComparisonConstants(constructor);\n        }\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        // Updates commonAncestorContainer and collapsed after boundary change\n        function updateCollapsedAndCommonAncestor(range) {\n            range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset);\n            range.commonAncestorContainer = range.collapsed ?\n                range.startContainer : dom.getCommonAncestor(range.startContainer, range.endContainer);\n        }\n\n        function updateBoundaries(range, startContainer, startOffset, endContainer, endOffset) {\n            range.startContainer = startContainer;\n            range.startOffset = startOffset;\n            range.endContainer = endContainer;\n            range.endOffset = endOffset;\n            range.document = dom.getDocument(startContainer);\n\n            updateCollapsedAndCommonAncestor(range);\n        }\n\n        function Range(doc) {\n            this.startContainer = doc;\n            this.startOffset = 0;\n            this.endContainer = doc;\n            this.endOffset = 0;\n            this.document = doc;\n            updateCollapsedAndCommonAncestor(this);\n        }\n\n        createPrototypeRange(Range, updateBoundaries);\n\n        util.extend(Range, {\n            rangeProperties: rangeProperties,\n            RangeIterator: RangeIterator,\n            copyComparisonConstants: copyComparisonConstants,\n            createPrototypeRange: createPrototypeRange,\n            inspect: inspect,\n            toHtml: rangeToHtml,\n            getRangeDocument: getRangeDocument,\n            rangesEqual: function(r1, r2) {\n                return r1.startContainer === r2.startContainer &&\n                    r1.startOffset === r2.startOffset &&\n                    r1.endContainer === r2.endContainer &&\n                    r1.endOffset === r2.endOffset;\n            }\n        });\n\n        api.DomRange = Range;\n    });\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // Wrappers for the browser's native DOM Range and/or TextRange implementation \n    api.createCoreModule(\"WrappedRange\", [\"DomRange\"], function(api, module) {\n        var WrappedRange, WrappedTextRange;\n        var dom = api.dom;\n        var util = api.util;\n        var DomPosition = dom.DomPosition;\n        var DomRange = api.DomRange;\n        var getBody = dom.getBody;\n        var getContentDocument = dom.getContentDocument;\n        var isCharacterDataNode = dom.isCharacterDataNode;\n\n\n        /*----------------------------------------------------------------------------------------------------------------*/\n\n        if (api.features.implementsDomRange) {\n            // This is a wrapper around the browser's native DOM Range. It has two aims:\n            // - Provide workarounds for specific browser bugs\n            // - provide convenient extensions, which are inherited from Rangy's DomRange\n\n            (function() {\n                var rangeProto;\n                var rangeProperties = DomRange.rangeProperties;\n\n                function updateRangeProperties(range) {\n                    var i = rangeProperties.length, prop;\n                    while (i--) {\n                        prop = rangeProperties[i];\n                        range[prop] = range.nativeRange[prop];\n                    }\n                    // Fix for broken collapsed property in IE 9.\n                    range.collapsed = (range.startContainer === range.endContainer && range.startOffset === range.endOffset);\n                }\n\n                function updateNativeRange(range, startContainer, startOffset, endContainer, endOffset) {\n                    var startMoved = (range.startContainer !== startContainer || range.startOffset != startOffset);\n                    var endMoved = (range.endContainer !== endContainer || range.endOffset != endOffset);\n                    var nativeRangeDifferent = !range.equals(range.nativeRange);\n\n                    // Always set both boundaries for the benefit of IE9 (see issue 35)\n                    if (startMoved || endMoved || nativeRangeDifferent) {\n                        range.setEnd(endContainer, endOffset);\n                        range.setStart(startContainer, startOffset);\n                    }\n                }\n\n                var createBeforeAfterNodeSetter;\n\n                WrappedRange = function(range) {\n                    if (!range) {\n                        throw module.createError(\"WrappedRange: Range must be specified\");\n                    }\n                    this.nativeRange = range;\n                    updateRangeProperties(this);\n                };\n\n                DomRange.createPrototypeRange(WrappedRange, updateNativeRange);\n\n                rangeProto = WrappedRange.prototype;\n\n                rangeProto.selectNode = function(node) {\n                    this.nativeRange.selectNode(node);\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.cloneContents = function() {\n                    return this.nativeRange.cloneContents();\n                };\n\n                // Due to a long-standing Firefox bug that I have not been able to find a reliable way to detect,\n                // insertNode() is never delegated to the native range.\n\n                rangeProto.surroundContents = function(node) {\n                    this.nativeRange.surroundContents(node);\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.collapse = function(isStart) {\n                    this.nativeRange.collapse(isStart);\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.cloneRange = function() {\n                    return new WrappedRange(this.nativeRange.cloneRange());\n                };\n\n                rangeProto.refresh = function() {\n                    updateRangeProperties(this);\n                };\n\n                rangeProto.toString = function() {\n                    return this.nativeRange.toString();\n                };\n\n                // Create test range and node for feature detection\n\n                var testTextNode = document.createTextNode(\"test\");\n                getBody(document).appendChild(testTextNode);\n                var range = document.createRange();\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for Firefox 2 bug that prevents moving the start of a Range to a point after its current end and\n                // correct for it\n\n                range.setStart(testTextNode, 0);\n                range.setEnd(testTextNode, 0);\n\n                try {\n                    range.setStart(testTextNode, 1);\n\n                    rangeProto.setStart = function(node, offset) {\n                        this.nativeRange.setStart(node, offset);\n                        updateRangeProperties(this);\n                    };\n\n                    rangeProto.setEnd = function(node, offset) {\n                        this.nativeRange.setEnd(node, offset);\n                        updateRangeProperties(this);\n                    };\n\n                    createBeforeAfterNodeSetter = function(name) {\n                        return function(node) {\n                            this.nativeRange[name](node);\n                            updateRangeProperties(this);\n                        };\n                    };\n\n                } catch(ex) {\n\n                    rangeProto.setStart = function(node, offset) {\n                        try {\n                            this.nativeRange.setStart(node, offset);\n                        } catch (ex) {\n                            this.nativeRange.setEnd(node, offset);\n                            this.nativeRange.setStart(node, offset);\n                        }\n                        updateRangeProperties(this);\n                    };\n\n                    rangeProto.setEnd = function(node, offset) {\n                        try {\n                            this.nativeRange.setEnd(node, offset);\n                        } catch (ex) {\n                            this.nativeRange.setStart(node, offset);\n                            this.nativeRange.setEnd(node, offset);\n                        }\n                        updateRangeProperties(this);\n                    };\n\n                    createBeforeAfterNodeSetter = function(name, oppositeName) {\n                        return function(node) {\n                            try {\n                                this.nativeRange[name](node);\n                            } catch (ex) {\n                                this.nativeRange[oppositeName](node);\n                                this.nativeRange[name](node);\n                            }\n                            updateRangeProperties(this);\n                        };\n                    };\n                }\n\n                rangeProto.setStartBefore = createBeforeAfterNodeSetter(\"setStartBefore\", \"setEndBefore\");\n                rangeProto.setStartAfter = createBeforeAfterNodeSetter(\"setStartAfter\", \"setEndAfter\");\n                rangeProto.setEndBefore = createBeforeAfterNodeSetter(\"setEndBefore\", \"setStartBefore\");\n                rangeProto.setEndAfter = createBeforeAfterNodeSetter(\"setEndAfter\", \"setStartAfter\");\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Always use DOM4-compliant selectNodeContents implementation: it's simpler and less code than testing\n                // whether the native implementation can be trusted\n                rangeProto.selectNodeContents = function(node) {\n                    this.setStartAndEnd(node, 0, dom.getNodeLength(node));\n                };\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for and correct WebKit bug that has the behaviour of compareBoundaryPoints round the wrong way for\n                // constants START_TO_END and END_TO_START: https://bugs.webkit.org/show_bug.cgi?id=20738\n\n                range.selectNodeContents(testTextNode);\n                range.setEnd(testTextNode, 3);\n\n                var range2 = document.createRange();\n                range2.selectNodeContents(testTextNode);\n                range2.setEnd(testTextNode, 4);\n                range2.setStart(testTextNode, 2);\n\n                if (range.compareBoundaryPoints(range.START_TO_END, range2) == -1 &&\n                        range.compareBoundaryPoints(range.END_TO_START, range2) == 1) {\n                    // This is the wrong way round, so correct for it\n\n                    rangeProto.compareBoundaryPoints = function(type, range) {\n                        range = range.nativeRange || range;\n                        if (type == range.START_TO_END) {\n                            type = range.END_TO_START;\n                        } else if (type == range.END_TO_START) {\n                            type = range.START_TO_END;\n                        }\n                        return this.nativeRange.compareBoundaryPoints(type, range);\n                    };\n                } else {\n                    rangeProto.compareBoundaryPoints = function(type, range) {\n                        return this.nativeRange.compareBoundaryPoints(type, range.nativeRange || range);\n                    };\n                }\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for IE 9 deleteContents() and extractContents() bug and correct it. See issue 107.\n\n                var el = document.createElement(\"div\");\n                el.innerHTML = \"123\";\n                var textNode = el.firstChild;\n                var body = getBody(document);\n                body.appendChild(el);\n\n                range.setStart(textNode, 1);\n                range.setEnd(textNode, 2);\n                range.deleteContents();\n\n                if (textNode.data == \"13\") {\n                    // Behaviour is correct per DOM4 Range so wrap the browser's implementation of deleteContents() and\n                    // extractContents()\n                    rangeProto.deleteContents = function() {\n                        this.nativeRange.deleteContents();\n                        updateRangeProperties(this);\n                    };\n\n                    rangeProto.extractContents = function() {\n                        var frag = this.nativeRange.extractContents();\n                        updateRangeProperties(this);\n                        return frag;\n                    };\n                } else {\n                }\n\n                body.removeChild(el);\n                body = null;\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Test for existence of createContextualFragment and delegate to it if it exists\n                if (util.isHostMethod(range, \"createContextualFragment\")) {\n                    rangeProto.createContextualFragment = function(fragmentStr) {\n                        return this.nativeRange.createContextualFragment(fragmentStr);\n                    };\n                }\n\n                /*--------------------------------------------------------------------------------------------------------*/\n\n                // Clean up\n                getBody(document).removeChild(testTextNode);\n\n                rangeProto.getName = function() {\n                    return \"WrappedRange\";\n                };\n\n                api.WrappedRange = WrappedRange;\n\n                api.createNativeRange = function(doc) {\n                    doc = getContentDocument(doc, module, \"createNativeRange\");\n                    return doc.createRange();\n                };\n            })();\n        }\n        \n        if (api.features.implementsTextRange) {\n            /*\n            This is a workaround for a bug where IE returns the wrong container element from the TextRange's parentElement()\n            method. For example, in the following (where pipes denote the selection boundaries):\n\n            <ul id=\"ul\"><li id=\"a\">| a </li><li id=\"b\"> b |</li></ul>\n\n            var range = document.selection.createRange();\n            alert(range.parentElement().id); // Should alert \"ul\" but alerts \"b\"\n\n            This method returns the common ancestor node of the following:\n            - the parentElement() of the textRange\n            - the parentElement() of the textRange after calling collapse(true)\n            - the parentElement() of the textRange after calling collapse(false)\n            */\n            var getTextRangeContainerElement = function(textRange) {\n                var parentEl = textRange.parentElement();\n                var range = textRange.duplicate();\n                range.collapse(true);\n                var startEl = range.parentElement();\n                range = textRange.duplicate();\n                range.collapse(false);\n                var endEl = range.parentElement();\n                var startEndContainer = (startEl == endEl) ? startEl : dom.getCommonAncestor(startEl, endEl);\n\n                return startEndContainer == parentEl ? startEndContainer : dom.getCommonAncestor(parentEl, startEndContainer);\n            };\n\n            var textRangeIsCollapsed = function(textRange) {\n                return textRange.compareEndPoints(\"StartToEnd\", textRange) == 0;\n            };\n\n            // Gets the boundary of a TextRange expressed as a node and an offset within that node. This function started\n            // out as an improved version of code found in Tim Cameron Ryan's IERange (http://code.google.com/p/ierange/)\n            // but has grown, fixing problems with line breaks in preformatted text, adding workaround for IE TextRange\n            // bugs, handling for inputs and images, plus optimizations.\n            var getTextRangeBoundaryPosition = function(textRange, wholeRangeContainerElement, isStart, isCollapsed, startInfo) {\n                var workingRange = textRange.duplicate();\n                workingRange.collapse(isStart);\n                var containerElement = workingRange.parentElement();\n\n                // Sometimes collapsing a TextRange that's at the start of a text node can move it into the previous node, so\n                // check for that\n                if (!dom.isOrIsAncestorOf(wholeRangeContainerElement, containerElement)) {\n                    containerElement = wholeRangeContainerElement;\n                }\n\n\n                // Deal with nodes that cannot \"contain rich HTML markup\". In practice, this means form inputs, images and\n                // similar. See http://msdn.microsoft.com/en-us/library/aa703950%28VS.85%29.aspx\n                if (!containerElement.canHaveHTML) {\n                    var pos = new DomPosition(containerElement.parentNode, dom.getNodeIndex(containerElement));\n                    return {\n                        boundaryPosition: pos,\n                        nodeInfo: {\n                            nodeIndex: pos.offset,\n                            containerElement: pos.node\n                        }\n                    };\n                }\n\n                var workingNode = dom.getDocument(containerElement).createElement(\"span\");\n\n                // Workaround for HTML5 Shiv's insane violation of document.createElement(). See Rangy issue 104 and HTML5\n                // Shiv issue 64: https://github.com/aFarkas/html5shiv/issues/64\n                if (workingNode.parentNode) {\n                    workingNode.parentNode.removeChild(workingNode);\n                }\n\n                var comparison, workingComparisonType = isStart ? \"StartToStart\" : \"StartToEnd\";\n                var previousNode, nextNode, boundaryPosition, boundaryNode;\n                var start = (startInfo && startInfo.containerElement == containerElement) ? startInfo.nodeIndex : 0;\n                var childNodeCount = containerElement.childNodes.length;\n                var end = childNodeCount;\n\n                // Check end first. Code within the loop assumes that the endth child node of the container is definitely\n                // after the range boundary.\n                var nodeIndex = end;\n\n                while (true) {\n                    if (nodeIndex == childNodeCount) {\n                        containerElement.appendChild(workingNode);\n                    } else {\n                        containerElement.insertBefore(workingNode, containerElement.childNodes[nodeIndex]);\n                    }\n                    workingRange.moveToElementText(workingNode);\n                    comparison = workingRange.compareEndPoints(workingComparisonType, textRange);\n                    if (comparison == 0 || start == end) {\n                        break;\n                    } else if (comparison == -1) {\n                        if (end == start + 1) {\n                            // We know the endth child node is after the range boundary, so we must be done.\n                            break;\n                        } else {\n                            start = nodeIndex;\n                        }\n                    } else {\n                        end = (end == start + 1) ? start : nodeIndex;\n                    }\n                    nodeIndex = Math.floor((start + end) / 2);\n                    containerElement.removeChild(workingNode);\n                }\n\n\n                // We've now reached or gone past the boundary of the text range we're interested in\n                // so have identified the node we want\n                boundaryNode = workingNode.nextSibling;\n\n                if (comparison == -1 && boundaryNode && isCharacterDataNode(boundaryNode)) {\n                    // This is a character data node (text, comment, cdata). The working range is collapsed at the start of\n                    // the node containing the text range's boundary, so we move the end of the working range to the\n                    // boundary point and measure the length of its text to get the boundary's offset within the node.\n                    workingRange.setEndPoint(isStart ? \"EndToStart\" : \"EndToEnd\", textRange);\n\n                    var offset;\n\n                    if (/[\\r\\n]/.test(boundaryNode.data)) {\n                        /*\n                        For the particular case of a boundary within a text node containing rendered line breaks (within a\n                        <pre> element, for example), we need a slightly complicated approach to get the boundary's offset in\n                        IE. The facts:\n                        \n                        - Each line break is represented as \\r in the text node's data/nodeValue properties\n                        - Each line break is represented as \\r\\n in the TextRange's 'text' property\n                        - The 'text' property of the TextRange does not contain trailing line breaks\n                        \n                        To get round the problem presented by the final fact above, we can use the fact that TextRange's\n                        moveStart() and moveEnd() methods return the actual number of characters moved, which is not\n                        necessarily the same as the number of characters it was instructed to move. The simplest approach is\n                        to use this to store the characters moved when moving both the start and end of the range to the\n                        start of the document body and subtracting the start offset from the end offset (the\n                        \"move-negative-gazillion\" method). However, this is extremely slow when the document is large and\n                        the range is near the end of it. Clearly doing the mirror image (i.e. moving the range boundaries to\n                        the end of the document) has the same problem.\n                        \n                        Another approach that works is to use moveStart() to move the start boundary of the range up to the\n                        end boundary one character at a time and incrementing a counter with the value returned by the\n                        moveStart() call. However, the check for whether the start boundary has reached the end boundary is\n                        expensive, so this method is slow (although unlike \"move-negative-gazillion\" is largely unaffected\n                        by the location of the range within the document).\n                        \n                        The approach used below is a hybrid of the two methods above. It uses the fact that a string\n                        containing the TextRange's 'text' property with each \\r\\n converted to a single \\r character cannot\n                        be longer than the text of the TextRange, so the start of the range is moved that length initially\n                        and then a character at a time to make up for any trailing line breaks not contained in the 'text'\n                        property. This has good performance in most situations compared to the previous two methods.\n                        */\n                        var tempRange = workingRange.duplicate();\n                        var rangeLength = tempRange.text.replace(/\\r\\n/g, \"\\r\").length;\n\n                        offset = tempRange.moveStart(\"character\", rangeLength);\n                        while ( (comparison = tempRange.compareEndPoints(\"StartToEnd\", tempRange)) == -1) {\n                            offset++;\n                            tempRange.moveStart(\"character\", 1);\n                        }\n                    } else {\n                        offset = workingRange.text.length;\n                    }\n                    boundaryPosition = new DomPosition(boundaryNode, offset);\n                } else {\n\n                    // If the boundary immediately follows a character data node and this is the end boundary, we should favour\n                    // a position within that, and likewise for a start boundary preceding a character data node\n                    previousNode = (isCollapsed || !isStart) && workingNode.previousSibling;\n                    nextNode = (isCollapsed || isStart) && workingNode.nextSibling;\n                    if (nextNode && isCharacterDataNode(nextNode)) {\n                        boundaryPosition = new DomPosition(nextNode, 0);\n                    } else if (previousNode && isCharacterDataNode(previousNode)) {\n                        boundaryPosition = new DomPosition(previousNode, previousNode.data.length);\n                    } else {\n                        boundaryPosition = new DomPosition(containerElement, dom.getNodeIndex(workingNode));\n                    }\n                }\n\n                // Clean up\n                workingNode.parentNode.removeChild(workingNode);\n\n                return {\n                    boundaryPosition: boundaryPosition,\n                    nodeInfo: {\n                        nodeIndex: nodeIndex,\n                        containerElement: containerElement\n                    }\n                };\n            };\n\n            // Returns a TextRange representing the boundary of a TextRange expressed as a node and an offset within that\n            // node. This function started out as an optimized version of code found in Tim Cameron Ryan's IERange\n            // (http://code.google.com/p/ierange/)\n            var createBoundaryTextRange = function(boundaryPosition, isStart) {\n                var boundaryNode, boundaryParent, boundaryOffset = boundaryPosition.offset;\n                var doc = dom.getDocument(boundaryPosition.node);\n                var workingNode, childNodes, workingRange = getBody(doc).createTextRange();\n                var nodeIsDataNode = isCharacterDataNode(boundaryPosition.node);\n\n                if (nodeIsDataNode) {\n                    boundaryNode = boundaryPosition.node;\n                    boundaryParent = boundaryNode.parentNode;\n                } else {\n                    childNodes = boundaryPosition.node.childNodes;\n                    boundaryNode = (boundaryOffset < childNodes.length) ? childNodes[boundaryOffset] : null;\n                    boundaryParent = boundaryPosition.node;\n                }\n\n                // Position the range immediately before the node containing the boundary\n                workingNode = doc.createElement(\"span\");\n\n                // Making the working element non-empty element persuades IE to consider the TextRange boundary to be within\n                // the element rather than immediately before or after it\n                workingNode.innerHTML = \"&#feff;\";\n\n                // insertBefore is supposed to work like appendChild if the second parameter is null. However, a bug report\n                // for IERange suggests that it can crash the browser: http://code.google.com/p/ierange/issues/detail?id=12\n                if (boundaryNode) {\n                    boundaryParent.insertBefore(workingNode, boundaryNode);\n                } else {\n                    boundaryParent.appendChild(workingNode);\n                }\n\n                workingRange.moveToElementText(workingNode);\n                workingRange.collapse(!isStart);\n\n                // Clean up\n                boundaryParent.removeChild(workingNode);\n\n                // Move the working range to the text offset, if required\n                if (nodeIsDataNode) {\n                    workingRange[isStart ? \"moveStart\" : \"moveEnd\"](\"character\", boundaryOffset);\n                }\n\n                return workingRange;\n            };\n\n            /*------------------------------------------------------------------------------------------------------------*/\n\n            // This is a wrapper around a TextRange, providing full DOM Range functionality using rangy's DomRange as a\n            // prototype\n\n            WrappedTextRange = function(textRange) {\n                this.textRange = textRange;\n                this.refresh();\n            };\n\n            WrappedTextRange.prototype = new DomRange(document);\n\n            WrappedTextRange.prototype.refresh = function() {\n                var start, end, startBoundary;\n\n                // TextRange's parentElement() method cannot be trusted. getTextRangeContainerElement() works around that.\n                var rangeContainerElement = getTextRangeContainerElement(this.textRange);\n\n                if (textRangeIsCollapsed(this.textRange)) {\n                    end = start = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true,\n                        true).boundaryPosition;\n                } else {\n                    startBoundary = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, true, false);\n                    start = startBoundary.boundaryPosition;\n\n                    // An optimization used here is that if the start and end boundaries have the same parent element, the\n                    // search scope for the end boundary can be limited to exclude the portion of the element that precedes\n                    // the start boundary\n                    end = getTextRangeBoundaryPosition(this.textRange, rangeContainerElement, false, false,\n                        startBoundary.nodeInfo).boundaryPosition;\n                }\n\n                this.setStart(start.node, start.offset);\n                this.setEnd(end.node, end.offset);\n            };\n\n            WrappedTextRange.prototype.getName = function() {\n                return \"WrappedTextRange\";\n            };\n\n            DomRange.copyComparisonConstants(WrappedTextRange);\n\n            var rangeToTextRange = function(range) {\n                if (range.collapsed) {\n                    return createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);\n                } else {\n                    var startRange = createBoundaryTextRange(new DomPosition(range.startContainer, range.startOffset), true);\n                    var endRange = createBoundaryTextRange(new DomPosition(range.endContainer, range.endOffset), false);\n                    var textRange = getBody( DomRange.getRangeDocument(range) ).createTextRange();\n                    textRange.setEndPoint(\"StartToStart\", startRange);\n                    textRange.setEndPoint(\"EndToEnd\", endRange);\n                    return textRange;\n                }\n            };\n\n            WrappedTextRange.rangeToTextRange = rangeToTextRange;\n\n            WrappedTextRange.prototype.toTextRange = function() {\n                return rangeToTextRange(this);\n            };\n\n            api.WrappedTextRange = WrappedTextRange;\n\n            // IE 9 and above have both implementations and Rangy makes both available. The next few lines sets which\n            // implementation to use by default.\n            if (!api.features.implementsDomRange || api.config.preferTextRange) {\n                // Add WrappedTextRange as the Range property of the global object to allow expression like Range.END_TO_END to work\n                var globalObj = (function() { return this; })();\n                if (typeof globalObj.Range == \"undefined\") {\n                    globalObj.Range = WrappedTextRange;\n                }\n\n                api.createNativeRange = function(doc) {\n                    doc = getContentDocument(doc, module, \"createNativeRange\");\n                    return getBody(doc).createTextRange();\n                };\n\n                api.WrappedRange = WrappedTextRange;\n            }\n        }\n\n        api.createRange = function(doc) {\n            doc = getContentDocument(doc, module, \"createRange\");\n            return new api.WrappedRange(api.createNativeRange(doc));\n        };\n\n        api.createRangyRange = function(doc) {\n            doc = getContentDocument(doc, module, \"createRangyRange\");\n            return new DomRange(doc);\n        };\n\n        api.createIframeRange = function(iframeEl) {\n            module.deprecationNotice(\"createIframeRange()\", \"createRange(iframeEl)\");\n            return api.createRange(iframeEl);\n        };\n\n        api.createIframeRangyRange = function(iframeEl) {\n            module.deprecationNotice(\"createIframeRangyRange()\", \"createRangyRange(iframeEl)\");\n            return api.createRangyRange(iframeEl);\n        };\n\n        api.addShimListener(function(win) {\n            var doc = win.document;\n            if (typeof doc.createRange == \"undefined\") {\n                doc.createRange = function() {\n                    return api.createRange(doc);\n                };\n            }\n            doc = win = null;\n        });\n    });\n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    // This module creates a selection object wrapper that conforms as closely as possible to the Selection specification\n    // in the HTML Editing spec (http://dvcs.w3.org/hg/editing/raw-file/tip/editing.html#selections)\n    api.createCoreModule(\"WrappedSelection\", [\"DomRange\", \"WrappedRange\"], function(api, module) {\n        api.config.checkSelectionRanges = true;\n\n        var BOOLEAN = \"boolean\";\n        var NUMBER = \"number\";\n        var dom = api.dom;\n        var util = api.util;\n        var isHostMethod = util.isHostMethod;\n        var DomRange = api.DomRange;\n        var WrappedRange = api.WrappedRange;\n        var DOMException = api.DOMException;\n        var DomPosition = dom.DomPosition;\n        var getNativeSelection;\n        var selectionIsCollapsed;\n        var features = api.features;\n        var CONTROL = \"Control\";\n        var getDocument = dom.getDocument;\n        var getBody = dom.getBody;\n        var rangesEqual = DomRange.rangesEqual;\n\n\n        // Utility function to support direction parameters in the API that may be a string (\"backward\" or \"forward\") or a\n        // Boolean (true for backwards).\n        function isDirectionBackward(dir) {\n            return (typeof dir == \"string\") ? /^backward(s)?$/i.test(dir) : !!dir;\n        }\n\n        function getWindow(win, methodName) {\n            if (!win) {\n                return window;\n            } else if (dom.isWindow(win)) {\n                return win;\n            } else if (win instanceof WrappedSelection) {\n                return win.win;\n            } else {\n                var doc = dom.getContentDocument(win, module, methodName);\n                return dom.getWindow(doc);\n            }\n        }\n\n        function getWinSelection(winParam) {\n            return getWindow(winParam, \"getWinSelection\").getSelection();\n        }\n\n        function getDocSelection(winParam) {\n            return getWindow(winParam, \"getDocSelection\").document.selection;\n        }\n        \n        function winSelectionIsBackward(sel) {\n            var backward = false;\n            if (sel.anchorNode) {\n                backward = (dom.comparePoints(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset) == 1);\n            }\n            return backward;\n        }\n\n        // Test for the Range/TextRange and Selection features required\n        // Test for ability to retrieve selection\n        var implementsWinGetSelection = isHostMethod(window, \"getSelection\"),\n            implementsDocSelection = util.isHostObject(document, \"selection\");\n\n        features.implementsWinGetSelection = implementsWinGetSelection;\n        features.implementsDocSelection = implementsDocSelection;\n\n        var useDocumentSelection = implementsDocSelection && (!implementsWinGetSelection || api.config.preferTextRange);\n\n        if (useDocumentSelection) {\n            getNativeSelection = getDocSelection;\n            api.isSelectionValid = function(winParam) {\n                var doc = getWindow(winParam, \"isSelectionValid\").document, nativeSel = doc.selection;\n\n                // Check whether the selection TextRange is actually contained within the correct document\n                return (nativeSel.type != \"None\" || getDocument(nativeSel.createRange().parentElement()) == doc);\n            };\n        } else if (implementsWinGetSelection) {\n            getNativeSelection = getWinSelection;\n            api.isSelectionValid = function() {\n                return true;\n            };\n        } else {\n            module.fail(\"Neither document.selection or window.getSelection() detected.\");\n        }\n\n        api.getNativeSelection = getNativeSelection;\n\n        var testSelection = getNativeSelection();\n        var testRange = api.createNativeRange(document);\n        var body = getBody(document);\n\n        // Obtaining a range from a selection\n        var selectionHasAnchorAndFocus = util.areHostProperties(testSelection,\n            [\"anchorNode\", \"focusNode\", \"anchorOffset\", \"focusOffset\"]);\n\n        features.selectionHasAnchorAndFocus = selectionHasAnchorAndFocus;\n\n        // Test for existence of native selection extend() method\n        var selectionHasExtend = isHostMethod(testSelection, \"extend\");\n        features.selectionHasExtend = selectionHasExtend;\n        \n        // Test if rangeCount exists\n        var selectionHasRangeCount = (typeof testSelection.rangeCount == NUMBER);\n        features.selectionHasRangeCount = selectionHasRangeCount;\n\n        var selectionSupportsMultipleRanges = false;\n        var collapsedNonEditableSelectionsSupported = true;\n\n        var addRangeBackwardToNative = selectionHasExtend ?\n            function(nativeSelection, range) {\n                var doc = DomRange.getRangeDocument(range);\n                var endRange = api.createRange(doc);\n                endRange.collapseToPoint(range.endContainer, range.endOffset);\n                nativeSelection.addRange(getNativeRange(endRange));\n                nativeSelection.extend(range.startContainer, range.startOffset);\n            } : null;\n\n        if (util.areHostMethods(testSelection, [\"addRange\", \"getRangeAt\", \"removeAllRanges\"]) &&\n                typeof testSelection.rangeCount == NUMBER && features.implementsDomRange) {\n\n            (function() {\n                // Previously an iframe was used but this caused problems in some circumstances in IE, so tests are\n                // performed on the current document's selection. See issue 109.\n\n                // Note also that if a selection previously existed, it is wiped by these tests. This should usually be fine\n                // because initialization usually happens when the document loads, but could be a problem for a script that\n                // loads and initializes Rangy later. If anyone complains, code could be added to save and restore the\n                // selection.\n                var sel = window.getSelection();\n                if (sel) {\n                    // Store the current selection\n                    var originalSelectionRangeCount = sel.rangeCount;\n                    var selectionHasMultipleRanges = (originalSelectionRangeCount > 1);\n                    var originalSelectionRanges = [];\n                    var originalSelectionBackward = winSelectionIsBackward(sel); \n                    for (var i = 0; i < originalSelectionRangeCount; ++i) {\n                        originalSelectionRanges[i] = sel.getRangeAt(i);\n                    }\n                    \n                    // Create some test elements\n                    var body = getBody(document);\n                    var testEl = body.appendChild( document.createElement(\"div\") );\n                    testEl.contentEditable = \"false\";\n                    var textNode = testEl.appendChild( document.createTextNode(\"\\u00a0\\u00a0\\u00a0\") );\n\n                    // Test whether the native selection will allow a collapsed selection within a non-editable element\n                    var r1 = document.createRange();\n\n                    r1.setStart(textNode, 1);\n                    r1.collapse(true);\n                    sel.addRange(r1);\n                    collapsedNonEditableSelectionsSupported = (sel.rangeCount == 1);\n                    sel.removeAllRanges();\n\n                    // Test whether the native selection is capable of supporting multiple ranges.\n                    if (!selectionHasMultipleRanges) {\n                        // Doing the original feature test here in Chrome 36 (and presumably later versions) prints a\n                        // console error of \"Discontiguous selection is not supported.\" that cannot be suppressed. There's\n                        // nothing we can do about this while retaining the feature test so we have to resort to a browser\n                        // sniff. I'm not happy about it. See\n                        // https://code.google.com/p/chromium/issues/detail?id=399791\n                        var chromeMatch = window.navigator.appVersion.match(/Chrome\\/(.*?) /);\n                        if (chromeMatch && parseInt(chromeMatch[1]) >= 36) {\n                            selectionSupportsMultipleRanges = false;\n                        } else {\n                            var r2 = r1.cloneRange();\n                            r1.setStart(textNode, 0);\n                            r2.setEnd(textNode, 3);\n                            r2.setStart(textNode, 2);\n                            sel.addRange(r1);\n                            sel.addRange(r2);\n                            selectionSupportsMultipleRanges = (sel.rangeCount == 2);\n                        }\n                    }\n\n                    // Clean up\n                    body.removeChild(testEl);\n                    sel.removeAllRanges();\n\n                    for (i = 0; i < originalSelectionRangeCount; ++i) {\n                        if (i == 0 && originalSelectionBackward) {\n                            if (addRangeBackwardToNative) {\n                                addRangeBackwardToNative(sel, originalSelectionRanges[i]);\n                            } else {\n                                api.warn(\"Rangy initialization: original selection was backwards but selection has been restored forwards because the browser does not support Selection.extend\");\n                                sel.addRange(originalSelectionRanges[i]);\n                            }\n                        } else {\n                            sel.addRange(originalSelectionRanges[i]);\n                        }\n                    }\n                }\n            })();\n        }\n\n        features.selectionSupportsMultipleRanges = selectionSupportsMultipleRanges;\n        features.collapsedNonEditableSelectionsSupported = collapsedNonEditableSelectionsSupported;\n\n        // ControlRanges\n        var implementsControlRange = false, testControlRange;\n\n        if (body && isHostMethod(body, \"createControlRange\")) {\n            testControlRange = body.createControlRange();\n            if (util.areHostProperties(testControlRange, [\"item\", \"add\"])) {\n                implementsControlRange = true;\n            }\n        }\n        features.implementsControlRange = implementsControlRange;\n\n        // Selection collapsedness\n        if (selectionHasAnchorAndFocus) {\n            selectionIsCollapsed = function(sel) {\n                return sel.anchorNode === sel.focusNode && sel.anchorOffset === sel.focusOffset;\n            };\n        } else {\n            selectionIsCollapsed = function(sel) {\n                return sel.rangeCount ? sel.getRangeAt(sel.rangeCount - 1).collapsed : false;\n            };\n        }\n\n        function updateAnchorAndFocusFromRange(sel, range, backward) {\n            var anchorPrefix = backward ? \"end\" : \"start\", focusPrefix = backward ? \"start\" : \"end\";\n            sel.anchorNode = range[anchorPrefix + \"Container\"];\n            sel.anchorOffset = range[anchorPrefix + \"Offset\"];\n            sel.focusNode = range[focusPrefix + \"Container\"];\n            sel.focusOffset = range[focusPrefix + \"Offset\"];\n        }\n\n        function updateAnchorAndFocusFromNativeSelection(sel) {\n            var nativeSel = sel.nativeSelection;\n            sel.anchorNode = nativeSel.anchorNode;\n            sel.anchorOffset = nativeSel.anchorOffset;\n            sel.focusNode = nativeSel.focusNode;\n            sel.focusOffset = nativeSel.focusOffset;\n        }\n\n        function updateEmptySelection(sel) {\n            sel.anchorNode = sel.focusNode = null;\n            sel.anchorOffset = sel.focusOffset = 0;\n            sel.rangeCount = 0;\n            sel.isCollapsed = true;\n            sel._ranges.length = 0;\n        }\n\n        function getNativeRange(range) {\n            var nativeRange;\n            if (range instanceof DomRange) {\n                nativeRange = api.createNativeRange(range.getDocument());\n                nativeRange.setEnd(range.endContainer, range.endOffset);\n                nativeRange.setStart(range.startContainer, range.startOffset);\n            } else if (range instanceof WrappedRange) {\n                nativeRange = range.nativeRange;\n            } else if (features.implementsDomRange && (range instanceof dom.getWindow(range.startContainer).Range)) {\n                nativeRange = range;\n            }\n            return nativeRange;\n        }\n\n        function rangeContainsSingleElement(rangeNodes) {\n            if (!rangeNodes.length || rangeNodes[0].nodeType != 1) {\n                return false;\n            }\n            for (var i = 1, len = rangeNodes.length; i < len; ++i) {\n                if (!dom.isAncestorOf(rangeNodes[0], rangeNodes[i])) {\n                    return false;\n                }\n            }\n            return true;\n        }\n\n        function getSingleElementFromRange(range) {\n            var nodes = range.getNodes();\n            if (!rangeContainsSingleElement(nodes)) {\n                throw module.createError(\"getSingleElementFromRange: range \" + range.inspect() + \" did not consist of a single element\");\n            }\n            return nodes[0];\n        }\n\n        // Simple, quick test which only needs to distinguish between a TextRange and a ControlRange\n        function isTextRange(range) {\n            return !!range && typeof range.text != \"undefined\";\n        }\n\n        function updateFromTextRange(sel, range) {\n            // Create a Range from the selected TextRange\n            var wrappedRange = new WrappedRange(range);\n            sel._ranges = [wrappedRange];\n\n            updateAnchorAndFocusFromRange(sel, wrappedRange, false);\n            sel.rangeCount = 1;\n            sel.isCollapsed = wrappedRange.collapsed;\n        }\n\n        function updateControlSelection(sel) {\n            // Update the wrapped selection based on what's now in the native selection\n            sel._ranges.length = 0;\n            if (sel.docSelection.type == \"None\") {\n                updateEmptySelection(sel);\n            } else {\n                var controlRange = sel.docSelection.createRange();\n                if (isTextRange(controlRange)) {\n                    // This case (where the selection type is \"Control\" and calling createRange() on the selection returns\n                    // a TextRange) can happen in IE 9. It happens, for example, when all elements in the selected\n                    // ControlRange have been removed from the ControlRange and removed from the document.\n                    updateFromTextRange(sel, controlRange);\n                } else {\n                    sel.rangeCount = controlRange.length;\n                    var range, doc = getDocument(controlRange.item(0));\n                    for (var i = 0; i < sel.rangeCount; ++i) {\n                        range = api.createRange(doc);\n                        range.selectNode(controlRange.item(i));\n                        sel._ranges.push(range);\n                    }\n                    sel.isCollapsed = sel.rangeCount == 1 && sel._ranges[0].collapsed;\n                    updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], false);\n                }\n            }\n        }\n\n        function addRangeToControlSelection(sel, range) {\n            var controlRange = sel.docSelection.createRange();\n            var rangeElement = getSingleElementFromRange(range);\n\n            // Create a new ControlRange containing all the elements in the selected ControlRange plus the element\n            // contained by the supplied range\n            var doc = getDocument(controlRange.item(0));\n            var newControlRange = getBody(doc).createControlRange();\n            for (var i = 0, len = controlRange.length; i < len; ++i) {\n                newControlRange.add(controlRange.item(i));\n            }\n            try {\n                newControlRange.add(rangeElement);\n            } catch (ex) {\n                throw module.createError(\"addRange(): Element within the specified Range could not be added to control selection (does it have layout?)\");\n            }\n            newControlRange.select();\n\n            // Update the wrapped selection based on what's now in the native selection\n            updateControlSelection(sel);\n        }\n\n        var getSelectionRangeAt;\n\n        if (isHostMethod(testSelection, \"getRangeAt\")) {\n            // try/catch is present because getRangeAt() must have thrown an error in some browser and some situation.\n            // Unfortunately, I didn't write a comment about the specifics and am now scared to take it out. Let that be a\n            // lesson to us all, especially me.\n            getSelectionRangeAt = function(sel, index) {\n                try {\n                    return sel.getRangeAt(index);\n                } catch (ex) {\n                    return null;\n                }\n            };\n        } else if (selectionHasAnchorAndFocus) {\n            getSelectionRangeAt = function(sel) {\n                var doc = getDocument(sel.anchorNode);\n                var range = api.createRange(doc);\n                range.setStartAndEnd(sel.anchorNode, sel.anchorOffset, sel.focusNode, sel.focusOffset);\n\n                // Handle the case when the selection was selected backwards (from the end to the start in the\n                // document)\n                if (range.collapsed !== this.isCollapsed) {\n                    range.setStartAndEnd(sel.focusNode, sel.focusOffset, sel.anchorNode, sel.anchorOffset);\n                }\n\n                return range;\n            };\n        }\n\n        function WrappedSelection(selection, docSelection, win) {\n            this.nativeSelection = selection;\n            this.docSelection = docSelection;\n            this._ranges = [];\n            this.win = win;\n            this.refresh();\n        }\n\n        WrappedSelection.prototype = api.selectionPrototype;\n\n        function deleteProperties(sel) {\n            sel.win = sel.anchorNode = sel.focusNode = sel._ranges = null;\n            sel.rangeCount = sel.anchorOffset = sel.focusOffset = 0;\n            sel.detached = true;\n        }\n\n        var cachedRangySelections = [];\n\n        function actOnCachedSelection(win, action) {\n            var i = cachedRangySelections.length, cached, sel;\n            while (i--) {\n                cached = cachedRangySelections[i];\n                sel = cached.selection;\n                if (action == \"deleteAll\") {\n                    deleteProperties(sel);\n                } else if (cached.win == win) {\n                    if (action == \"delete\") {\n                        cachedRangySelections.splice(i, 1);\n                        return true;\n                    } else {\n                        return sel;\n                    }\n                }\n            }\n            if (action == \"deleteAll\") {\n                cachedRangySelections.length = 0;\n            }\n            return null;\n        }\n\n        var getSelection = function(win) {\n            // Check if the parameter is a Rangy Selection object\n            if (win && win instanceof WrappedSelection) {\n                win.refresh();\n                return win;\n            }\n\n            win = getWindow(win, \"getNativeSelection\");\n\n            var sel = actOnCachedSelection(win);\n            var nativeSel = getNativeSelection(win), docSel = implementsDocSelection ? getDocSelection(win) : null;\n            if (sel) {\n                sel.nativeSelection = nativeSel;\n                sel.docSelection = docSel;\n                sel.refresh();\n            } else {\n                sel = new WrappedSelection(nativeSel, docSel, win);\n                cachedRangySelections.push( { win: win, selection: sel } );\n            }\n            return sel;\n        };\n\n        api.getSelection = getSelection;\n\n        api.getIframeSelection = function(iframeEl) {\n            module.deprecationNotice(\"getIframeSelection()\", \"getSelection(iframeEl)\");\n            return api.getSelection(dom.getIframeWindow(iframeEl));\n        };\n\n        var selProto = WrappedSelection.prototype;\n\n        function createControlSelection(sel, ranges) {\n            // Ensure that the selection becomes of type \"Control\"\n            var doc = getDocument(ranges[0].startContainer);\n            var controlRange = getBody(doc).createControlRange();\n            for (var i = 0, el, len = ranges.length; i < len; ++i) {\n                el = getSingleElementFromRange(ranges[i]);\n                try {\n                    controlRange.add(el);\n                } catch (ex) {\n                    throw module.createError(\"setRanges(): Element within one of the specified Ranges could not be added to control selection (does it have layout?)\");\n                }\n            }\n            controlRange.select();\n\n            // Update the wrapped selection based on what's now in the native selection\n            updateControlSelection(sel);\n        }\n\n        // Selecting a range\n        if (!useDocumentSelection && selectionHasAnchorAndFocus && util.areHostMethods(testSelection, [\"removeAllRanges\", \"addRange\"])) {\n            selProto.removeAllRanges = function() {\n                this.nativeSelection.removeAllRanges();\n                updateEmptySelection(this);\n            };\n\n            var addRangeBackward = function(sel, range) {\n                addRangeBackwardToNative(sel.nativeSelection, range);\n                sel.refresh();\n            };\n\n            if (selectionHasRangeCount) {\n                selProto.addRange = function(range, direction) {\n                    if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {\n                        addRangeToControlSelection(this, range);\n                    } else {\n                        if (isDirectionBackward(direction) && selectionHasExtend) {\n                            addRangeBackward(this, range);\n                        } else {\n                            var previousRangeCount;\n                            if (selectionSupportsMultipleRanges) {\n                                previousRangeCount = this.rangeCount;\n                            } else {\n                                this.removeAllRanges();\n                                previousRangeCount = 0;\n                            }\n                            // Clone the native range so that changing the selected range does not affect the selection.\n                            // This is contrary to the spec but is the only way to achieve consistency between browsers. See\n                            // issue 80.\n                            this.nativeSelection.addRange(getNativeRange(range).cloneRange());\n\n                            // Check whether adding the range was successful\n                            this.rangeCount = this.nativeSelection.rangeCount;\n\n                            if (this.rangeCount == previousRangeCount + 1) {\n                                // The range was added successfully\n\n                                // Check whether the range that we added to the selection is reflected in the last range extracted from\n                                // the selection\n                                if (api.config.checkSelectionRanges) {\n                                    var nativeRange = getSelectionRangeAt(this.nativeSelection, this.rangeCount - 1);\n                                    if (nativeRange && !rangesEqual(nativeRange, range)) {\n                                        // Happens in WebKit with, for example, a selection placed at the start of a text node\n                                        range = new WrappedRange(nativeRange);\n                                    }\n                                }\n                                this._ranges[this.rangeCount - 1] = range;\n                                updateAnchorAndFocusFromRange(this, range, selectionIsBackward(this.nativeSelection));\n                                this.isCollapsed = selectionIsCollapsed(this);\n                            } else {\n                                // The range was not added successfully. The simplest thing is to refresh\n                                this.refresh();\n                            }\n                        }\n                    }\n                };\n            } else {\n                selProto.addRange = function(range, direction) {\n                    if (isDirectionBackward(direction) && selectionHasExtend) {\n                        addRangeBackward(this, range);\n                    } else {\n                        this.nativeSelection.addRange(getNativeRange(range));\n                        this.refresh();\n                    }\n                };\n            }\n\n            selProto.setRanges = function(ranges) {\n                if (implementsControlRange && implementsDocSelection && ranges.length > 1) {\n                    createControlSelection(this, ranges);\n                } else {\n                    this.removeAllRanges();\n                    for (var i = 0, len = ranges.length; i < len; ++i) {\n                        this.addRange(ranges[i]);\n                    }\n                }\n            };\n        } else if (isHostMethod(testSelection, \"empty\") && isHostMethod(testRange, \"select\") &&\n                   implementsControlRange && useDocumentSelection) {\n\n            selProto.removeAllRanges = function() {\n                // Added try/catch as fix for issue #21\n                try {\n                    this.docSelection.empty();\n\n                    // Check for empty() not working (issue #24)\n                    if (this.docSelection.type != \"None\") {\n                        // Work around failure to empty a control selection by instead selecting a TextRange and then\n                        // calling empty()\n                        var doc;\n                        if (this.anchorNode) {\n                            doc = getDocument(this.anchorNode);\n                        } else if (this.docSelection.type == CONTROL) {\n                            var controlRange = this.docSelection.createRange();\n                            if (controlRange.length) {\n                                doc = getDocument( controlRange.item(0) );\n                            }\n                        }\n                        if (doc) {\n                            var textRange = getBody(doc).createTextRange();\n                            textRange.select();\n                            this.docSelection.empty();\n                        }\n                    }\n                } catch(ex) {}\n                updateEmptySelection(this);\n            };\n\n            selProto.addRange = function(range) {\n                if (this.docSelection.type == CONTROL) {\n                    addRangeToControlSelection(this, range);\n                } else {\n                    api.WrappedTextRange.rangeToTextRange(range).select();\n                    this._ranges[0] = range;\n                    this.rangeCount = 1;\n                    this.isCollapsed = this._ranges[0].collapsed;\n                    updateAnchorAndFocusFromRange(this, range, false);\n                }\n            };\n\n            selProto.setRanges = function(ranges) {\n                this.removeAllRanges();\n                var rangeCount = ranges.length;\n                if (rangeCount > 1) {\n                    createControlSelection(this, ranges);\n                } else if (rangeCount) {\n                    this.addRange(ranges[0]);\n                }\n            };\n        } else {\n            module.fail(\"No means of selecting a Range or TextRange was found\");\n            return false;\n        }\n\n        selProto.getRangeAt = function(index) {\n            if (index < 0 || index >= this.rangeCount) {\n                throw new DOMException(\"INDEX_SIZE_ERR\");\n            } else {\n                // Clone the range to preserve selection-range independence. See issue 80.\n                return this._ranges[index].cloneRange();\n            }\n        };\n\n        var refreshSelection;\n\n        if (useDocumentSelection) {\n            refreshSelection = function(sel) {\n                var range;\n                if (api.isSelectionValid(sel.win)) {\n                    range = sel.docSelection.createRange();\n                } else {\n                    range = getBody(sel.win.document).createTextRange();\n                    range.collapse(true);\n                }\n\n                if (sel.docSelection.type == CONTROL) {\n                    updateControlSelection(sel);\n                } else if (isTextRange(range)) {\n                    updateFromTextRange(sel, range);\n                } else {\n                    updateEmptySelection(sel);\n                }\n            };\n        } else if (isHostMethod(testSelection, \"getRangeAt\") && typeof testSelection.rangeCount == NUMBER) {\n            refreshSelection = function(sel) {\n                if (implementsControlRange && implementsDocSelection && sel.docSelection.type == CONTROL) {\n                    updateControlSelection(sel);\n                } else {\n                    sel._ranges.length = sel.rangeCount = sel.nativeSelection.rangeCount;\n                    if (sel.rangeCount) {\n                        for (var i = 0, len = sel.rangeCount; i < len; ++i) {\n                            sel._ranges[i] = new api.WrappedRange(sel.nativeSelection.getRangeAt(i));\n                        }\n                        updateAnchorAndFocusFromRange(sel, sel._ranges[sel.rangeCount - 1], selectionIsBackward(sel.nativeSelection));\n                        sel.isCollapsed = selectionIsCollapsed(sel);\n                    } else {\n                        updateEmptySelection(sel);\n                    }\n                }\n            };\n        } else if (selectionHasAnchorAndFocus && typeof testSelection.isCollapsed == BOOLEAN && typeof testRange.collapsed == BOOLEAN && features.implementsDomRange) {\n            refreshSelection = function(sel) {\n                var range, nativeSel = sel.nativeSelection;\n                if (nativeSel.anchorNode) {\n                    range = getSelectionRangeAt(nativeSel, 0);\n                    sel._ranges = [range];\n                    sel.rangeCount = 1;\n                    updateAnchorAndFocusFromNativeSelection(sel);\n                    sel.isCollapsed = selectionIsCollapsed(sel);\n                } else {\n                    updateEmptySelection(sel);\n                }\n            };\n        } else {\n            module.fail(\"No means of obtaining a Range or TextRange from the user's selection was found\");\n            return false;\n        }\n\n        selProto.refresh = function(checkForChanges) {\n            var oldRanges = checkForChanges ? this._ranges.slice(0) : null;\n            var oldAnchorNode = this.anchorNode, oldAnchorOffset = this.anchorOffset;\n\n            refreshSelection(this);\n            if (checkForChanges) {\n                // Check the range count first\n                var i = oldRanges.length;\n                if (i != this._ranges.length) {\n                    return true;\n                }\n\n                // Now check the direction. Checking the anchor position is the same is enough since we're checking all the\n                // ranges after this\n                if (this.anchorNode != oldAnchorNode || this.anchorOffset != oldAnchorOffset) {\n                    return true;\n                }\n\n                // Finally, compare each range in turn\n                while (i--) {\n                    if (!rangesEqual(oldRanges[i], this._ranges[i])) {\n                        return true;\n                    }\n                }\n                return false;\n            }\n        };\n\n        // Removal of a single range\n        var removeRangeManually = function(sel, range) {\n            var ranges = sel.getAllRanges();\n            sel.removeAllRanges();\n            for (var i = 0, len = ranges.length; i < len; ++i) {\n                if (!rangesEqual(range, ranges[i])) {\n                    sel.addRange(ranges[i]);\n                }\n            }\n            if (!sel.rangeCount) {\n                updateEmptySelection(sel);\n            }\n        };\n\n        if (implementsControlRange && implementsDocSelection) {\n            selProto.removeRange = function(range) {\n                if (this.docSelection.type == CONTROL) {\n                    var controlRange = this.docSelection.createRange();\n                    var rangeElement = getSingleElementFromRange(range);\n\n                    // Create a new ControlRange containing all the elements in the selected ControlRange minus the\n                    // element contained by the supplied range\n                    var doc = getDocument(controlRange.item(0));\n                    var newControlRange = getBody(doc).createControlRange();\n                    var el, removed = false;\n                    for (var i = 0, len = controlRange.length; i < len; ++i) {\n                        el = controlRange.item(i);\n                        if (el !== rangeElement || removed) {\n                            newControlRange.add(controlRange.item(i));\n                        } else {\n                            removed = true;\n                        }\n                    }\n                    newControlRange.select();\n\n                    // Update the wrapped selection based on what's now in the native selection\n                    updateControlSelection(this);\n                } else {\n                    removeRangeManually(this, range);\n                }\n            };\n        } else {\n            selProto.removeRange = function(range) {\n                removeRangeManually(this, range);\n            };\n        }\n\n        // Detecting if a selection is backward\n        var selectionIsBackward;\n        if (!useDocumentSelection && selectionHasAnchorAndFocus && features.implementsDomRange) {\n            selectionIsBackward = winSelectionIsBackward;\n\n            selProto.isBackward = function() {\n                return selectionIsBackward(this);\n            };\n        } else {\n            selectionIsBackward = selProto.isBackward = function() {\n                return false;\n            };\n        }\n\n        // Create an alias for backwards compatibility. From 1.3, everything is \"backward\" rather than \"backwards\"\n        selProto.isBackwards = selProto.isBackward;\n\n        // Selection stringifier\n        // This is conformant to the old HTML5 selections draft spec but differs from WebKit and Mozilla's implementation.\n        // The current spec does not yet define this method.\n        selProto.toString = function() {\n            var rangeTexts = [];\n            for (var i = 0, len = this.rangeCount; i < len; ++i) {\n                rangeTexts[i] = \"\" + this._ranges[i];\n            }\n            return rangeTexts.join(\"\");\n        };\n\n        function assertNodeInSameDocument(sel, node) {\n            if (sel.win.document != getDocument(node)) {\n                throw new DOMException(\"WRONG_DOCUMENT_ERR\");\n            }\n        }\n\n        // No current browser conforms fully to the spec for this method, so Rangy's own method is always used\n        selProto.collapse = function(node, offset) {\n            assertNodeInSameDocument(this, node);\n            var range = api.createRange(node);\n            range.collapseToPoint(node, offset);\n            this.setSingleRange(range);\n            this.isCollapsed = true;\n        };\n\n        selProto.collapseToStart = function() {\n            if (this.rangeCount) {\n                var range = this._ranges[0];\n                this.collapse(range.startContainer, range.startOffset);\n            } else {\n                throw new DOMException(\"INVALID_STATE_ERR\");\n            }\n        };\n\n        selProto.collapseToEnd = function() {\n            if (this.rangeCount) {\n                var range = this._ranges[this.rangeCount - 1];\n                this.collapse(range.endContainer, range.endOffset);\n            } else {\n                throw new DOMException(\"INVALID_STATE_ERR\");\n            }\n        };\n\n        // The spec is very specific on how selectAllChildren should be implemented so the native implementation is\n        // never used by Rangy.\n        selProto.selectAllChildren = function(node) {\n            assertNodeInSameDocument(this, node);\n            var range = api.createRange(node);\n            range.selectNodeContents(node);\n            this.setSingleRange(range);\n        };\n\n        selProto.deleteFromDocument = function() {\n            // Sepcial behaviour required for IE's control selections\n            if (implementsControlRange && implementsDocSelection && this.docSelection.type == CONTROL) {\n                var controlRange = this.docSelection.createRange();\n                var element;\n                while (controlRange.length) {\n                    element = controlRange.item(0);\n                    controlRange.remove(element);\n                    element.parentNode.removeChild(element);\n                }\n                this.refresh();\n            } else if (this.rangeCount) {\n                var ranges = this.getAllRanges();\n                if (ranges.length) {\n                    this.removeAllRanges();\n                    for (var i = 0, len = ranges.length; i < len; ++i) {\n                        ranges[i].deleteContents();\n                    }\n                    // The spec says nothing about what the selection should contain after calling deleteContents on each\n                    // range. Firefox moves the selection to where the final selected range was, so we emulate that\n                    this.addRange(ranges[len - 1]);\n                }\n            }\n        };\n\n        // The following are non-standard extensions\n        selProto.eachRange = function(func, returnValue) {\n            for (var i = 0, len = this._ranges.length; i < len; ++i) {\n                if ( func( this.getRangeAt(i) ) ) {\n                    return returnValue;\n                }\n            }\n        };\n\n        selProto.getAllRanges = function() {\n            var ranges = [];\n            this.eachRange(function(range) {\n                ranges.push(range);\n            });\n            return ranges;\n        };\n\n        selProto.setSingleRange = function(range, direction) {\n            this.removeAllRanges();\n            this.addRange(range, direction);\n        };\n\n        selProto.callMethodOnEachRange = function(methodName, params) {\n            var results = [];\n            this.eachRange( function(range) {\n                results.push( range[methodName].apply(range, params) );\n            } );\n            return results;\n        };\n        \n        function createStartOrEndSetter(isStart) {\n            return function(node, offset) {\n                var range;\n                if (this.rangeCount) {\n                    range = this.getRangeAt(0);\n                    range[\"set\" + (isStart ? \"Start\" : \"End\")](node, offset);\n                } else {\n                    range = api.createRange(this.win.document);\n                    range.setStartAndEnd(node, offset);\n                }\n                this.setSingleRange(range, this.isBackward());\n            };\n        }\n\n        selProto.setStart = createStartOrEndSetter(true);\n        selProto.setEnd = createStartOrEndSetter(false);\n        \n        // Add select() method to Range prototype. Any existing selection will be removed.\n        api.rangePrototype.select = function(direction) {\n            getSelection( this.getDocument() ).setSingleRange(this, direction);\n        };\n\n        selProto.changeEachRange = function(func) {\n            var ranges = [];\n            var backward = this.isBackward();\n\n            this.eachRange(function(range) {\n                func(range);\n                ranges.push(range);\n            });\n\n            this.removeAllRanges();\n            if (backward && ranges.length == 1) {\n                this.addRange(ranges[0], \"backward\");\n            } else {\n                this.setRanges(ranges);\n            }\n        };\n\n        selProto.containsNode = function(node, allowPartial) {\n            return this.eachRange( function(range) {\n                return range.containsNode(node, allowPartial);\n            }, true ) || false;\n        };\n\n        selProto.getBookmark = function(containerNode) {\n            return {\n                backward: this.isBackward(),\n                rangeBookmarks: this.callMethodOnEachRange(\"getBookmark\", [containerNode])\n            };\n        };\n\n        selProto.moveToBookmark = function(bookmark) {\n            var selRanges = [];\n            for (var i = 0, rangeBookmark, range; rangeBookmark = bookmark.rangeBookmarks[i++]; ) {\n                range = api.createRange(this.win);\n                range.moveToBookmark(rangeBookmark);\n                selRanges.push(range);\n            }\n            if (bookmark.backward) {\n                this.setSingleRange(selRanges[0], \"backward\");\n            } else {\n                this.setRanges(selRanges);\n            }\n        };\n\n        selProto.toHtml = function() {\n            var rangeHtmls = [];\n            this.eachRange(function(range) {\n                rangeHtmls.push( DomRange.toHtml(range) );\n            });\n            return rangeHtmls.join(\"\");\n        };\n\n        if (features.implementsTextRange) {\n            selProto.getNativeTextRange = function() {\n                var sel, textRange;\n                if ( (sel = this.docSelection) ) {\n                    var range = sel.createRange();\n                    if (isTextRange(range)) {\n                        return range;\n                    } else {\n                        throw module.createError(\"getNativeTextRange: selection is a control selection\"); \n                    }\n                } else if (this.rangeCount > 0) {\n                    return api.WrappedTextRange.rangeToTextRange( this.getRangeAt(0) );\n                } else {\n                    throw module.createError(\"getNativeTextRange: selection contains no range\");\n                }\n            };\n        }\n\n        function inspect(sel) {\n            var rangeInspects = [];\n            var anchor = new DomPosition(sel.anchorNode, sel.anchorOffset);\n            var focus = new DomPosition(sel.focusNode, sel.focusOffset);\n            var name = (typeof sel.getName == \"function\") ? sel.getName() : \"Selection\";\n\n            if (typeof sel.rangeCount != \"undefined\") {\n                for (var i = 0, len = sel.rangeCount; i < len; ++i) {\n                    rangeInspects[i] = DomRange.inspect(sel.getRangeAt(i));\n                }\n            }\n            return \"[\" + name + \"(Ranges: \" + rangeInspects.join(\", \") +\n                    \")(anchor: \" + anchor.inspect() + \", focus: \" + focus.inspect() + \"]\";\n        }\n\n        selProto.getName = function() {\n            return \"WrappedSelection\";\n        };\n\n        selProto.inspect = function() {\n            return inspect(this);\n        };\n\n        selProto.detach = function() {\n            actOnCachedSelection(this.win, \"delete\");\n            deleteProperties(this);\n        };\n\n        WrappedSelection.detachAll = function() {\n            actOnCachedSelection(null, \"deleteAll\");\n        };\n\n        WrappedSelection.inspect = inspect;\n        WrappedSelection.isDirectionBackward = isDirectionBackward;\n\n        api.Selection = WrappedSelection;\n\n        api.selectionPrototype = selProto;\n\n        api.addShimListener(function(win) {\n            if (typeof win.getSelection == \"undefined\") {\n                win.getSelection = function() {\n                    return getSelection(win);\n                };\n            }\n            win = null;\n        });\n    });\n    \n\n    /*----------------------------------------------------------------------------------------------------------------*/\n\n    return api;\n}, this);;/**\n * Selection save and restore module for Rangy.\n * Saves and restores user selections using marker invisible elements in the DOM.\n *\n * Part of Rangy, a cross-browser JavaScript range and selection library\n * http://code.google.com/p/rangy/\n *\n * Depends on Rangy core.\n *\n * Copyright 2014, Tim Down\n * Licensed under the MIT license.\n * Version: 1.3alpha.20140804\n * Build date: 4 August 2014\n */\n(function(factory, global) {\n    if (typeof define == \"function\" && define.amd) {\n        // AMD. Register as an anonymous module with a dependency on Rangy.\n        define([\"rangy\"], factory);\n        /*\n         } else if (typeof exports == \"object\") {\n         // Node/CommonJS style for Browserify\n         module.exports = factory;\n         */\n    } else {\n        // No AMD or CommonJS support so we use the rangy global variable\n        factory(global.rangy);\n    }\n})(function(rangy) {\n    rangy.createModule(\"SaveRestore\", [\"WrappedRange\"], function(api, module) {\n        var dom = api.dom;\n\n        var markerTextChar = \"\\ufeff\";\n\n        function gEBI(id, doc) {\n            return (doc || document).getElementById(id);\n        }\n\n        function insertRangeBoundaryMarker(range, atStart) {\n            var markerId = \"selectionBoundary_\" + (+new Date()) + \"_\" + (\"\" + Math.random()).slice(2);\n            var markerEl;\n            var doc = dom.getDocument(range.startContainer);\n\n            // Clone the Range and collapse to the appropriate boundary point\n            var boundaryRange = range.cloneRange();\n            boundaryRange.collapse(atStart);\n\n            // Create the marker element containing a single invisible character using DOM methods and insert it\n            markerEl = doc.createElement(\"span\");\n            markerEl.id = markerId;\n            markerEl.style.lineHeight = \"0\";\n            markerEl.style.display = \"none\";\n            markerEl.className = \"rangySelectionBoundary\";\n            markerEl.appendChild(doc.createTextNode(markerTextChar));\n\n            boundaryRange.insertNode(markerEl);\n            return markerEl;\n        }\n\n        function setRangeBoundary(doc, range, markerId, atStart) {\n            var markerEl = gEBI(markerId, doc);\n            if (markerEl) {\n                range[atStart ? \"setStartBefore\" : \"setEndBefore\"](markerEl);\n                markerEl.parentNode.removeChild(markerEl);\n            } else {\n                module.warn(\"Marker element has been removed. Cannot restore selection.\");\n            }\n        }\n\n        function compareRanges(r1, r2) {\n            return r2.compareBoundaryPoints(r1.START_TO_START, r1);\n        }\n\n        function saveRange(range, backward) {\n            var startEl, endEl, doc = api.DomRange.getRangeDocument(range), text = range.toString();\n\n            if (range.collapsed) {\n                endEl = insertRangeBoundaryMarker(range, false);\n                return {\n                    document: doc,\n                    markerId: endEl.id,\n                    collapsed: true\n                };\n            } else {\n                endEl = insertRangeBoundaryMarker(range, false);\n                startEl = insertRangeBoundaryMarker(range, true);\n\n                return {\n                    document: doc,\n                    startMarkerId: startEl.id,\n                    endMarkerId: endEl.id,\n                    collapsed: false,\n                    backward: backward,\n                    toString: function() {\n                        return \"original text: '\" + text + \"', new text: '\" + range.toString() + \"'\";\n                    }\n                };\n            }\n        }\n\n        function restoreRange(rangeInfo, normalize) {\n            var doc = rangeInfo.document;\n            if (typeof normalize == \"undefined\") {\n                normalize = true;\n            }\n            var range = api.createRange(doc);\n            if (rangeInfo.collapsed) {\n                var markerEl = gEBI(rangeInfo.markerId, doc);\n                if (markerEl) {\n                    markerEl.style.display = \"inline\";\n                    var previousNode = markerEl.previousSibling;\n\n                    // Workaround for issue 17\n                    if (previousNode && previousNode.nodeType == 3) {\n                        markerEl.parentNode.removeChild(markerEl);\n                        range.collapseToPoint(previousNode, previousNode.length);\n                    } else {\n                        range.collapseBefore(markerEl);\n                        markerEl.parentNode.removeChild(markerEl);\n                    }\n                } else {\n                    module.warn(\"Marker element has been removed. Cannot restore selection.\");\n                }\n            } else {\n                setRangeBoundary(doc, range, rangeInfo.startMarkerId, true);\n                setRangeBoundary(doc, range, rangeInfo.endMarkerId, false);\n            }\n\n            if (normalize) {\n                range.normalizeBoundaries();\n            }\n\n            return range;\n        }\n\n        function saveRanges(ranges, backward) {\n            var rangeInfos = [], range, doc;\n\n            // Order the ranges by position within the DOM, latest first, cloning the array to leave the original untouched\n            ranges = ranges.slice(0);\n            ranges.sort(compareRanges);\n\n            for (var i = 0, len = ranges.length; i < len; ++i) {\n                rangeInfos[i] = saveRange(ranges[i], backward);\n            }\n\n            // Now that all the markers are in place and DOM manipulation over, adjust each range's boundaries to lie\n            // between its markers\n            for (i = len - 1; i >= 0; --i) {\n                range = ranges[i];\n                doc = api.DomRange.getRangeDocument(range);\n                if (range.collapsed) {\n                    range.collapseAfter(gEBI(rangeInfos[i].markerId, doc));\n                } else {\n                    range.setEndBefore(gEBI(rangeInfos[i].endMarkerId, doc));\n                    range.setStartAfter(gEBI(rangeInfos[i].startMarkerId, doc));\n                }\n            }\n\n            return rangeInfos;\n        }\n\n        function saveSelection(win) {\n            if (!api.isSelectionValid(win)) {\n                module.warn(\"Cannot save selection. This usually happens when the selection is collapsed and the selection document has lost focus.\");\n                return null;\n            }\n            var sel = api.getSelection(win);\n            var ranges = sel.getAllRanges();\n            var backward = (ranges.length == 1 && sel.isBackward());\n\n            var rangeInfos = saveRanges(ranges, backward);\n\n            // Ensure current selection is unaffected\n            if (backward) {\n                sel.setSingleRange(ranges[0], \"backward\");\n            } else {\n                sel.setRanges(ranges);\n            }\n\n            return {\n                win: win,\n                rangeInfos: rangeInfos,\n                restored: false\n            };\n        }\n\n        function restoreRanges(rangeInfos) {\n            var ranges = [];\n\n            // Ranges are in reverse order of appearance in the DOM. We want to restore earliest first to avoid\n            // normalization affecting previously restored ranges.\n            var rangeCount = rangeInfos.length;\n\n            for (var i = rangeCount - 1; i >= 0; i--) {\n                ranges[i] = restoreRange(rangeInfos[i], true);\n            }\n\n            return ranges;\n        }\n\n        function restoreSelection(savedSelection, preserveDirection) {\n            if (!savedSelection.restored) {\n                var rangeInfos = savedSelection.rangeInfos;\n                var sel = api.getSelection(savedSelection.win);\n                var ranges = restoreRanges(rangeInfos), rangeCount = rangeInfos.length;\n\n                if (rangeCount == 1 && preserveDirection && api.features.selectionHasExtend && rangeInfos[0].backward) {\n                    sel.removeAllRanges();\n                    sel.addRange(ranges[0], true);\n                } else {\n                    sel.setRanges(ranges);\n                }\n\n                savedSelection.restored = true;\n            }\n        }\n\n        function removeMarkerElement(doc, markerId) {\n            var markerEl = gEBI(markerId, doc);\n            if (markerEl) {\n                markerEl.parentNode.removeChild(markerEl);\n            }\n        }\n\n        function removeMarkers(savedSelection) {\n            var rangeInfos = savedSelection.rangeInfos;\n            for (var i = 0, len = rangeInfos.length, rangeInfo; i < len; ++i) {\n                rangeInfo = rangeInfos[i];\n                if (rangeInfo.collapsed) {\n                    removeMarkerElement(savedSelection.doc, rangeInfo.markerId);\n                } else {\n                    removeMarkerElement(savedSelection.doc, rangeInfo.startMarkerId);\n                    removeMarkerElement(savedSelection.doc, rangeInfo.endMarkerId);\n                }\n            }\n        }\n\n        api.util.extend(api, {\n            saveRange: saveRange,\n            restoreRange: restoreRange,\n            saveRanges: saveRanges,\n            restoreRanges: restoreRanges,\n            saveSelection: saveSelection,\n            restoreSelection: restoreSelection,\n            removeMarkerElement: removeMarkerElement,\n            removeMarkers: removeMarkers\n        });\n    });\n    \n}, this);;/*\n\tBase.js, version 1.1a\n\tCopyright 2006-2010, Dean Edwards\n\tLicense: http://www.opensource.org/licenses/mit-license.php\n*/\n\nvar Base = function() {\n\t// dummy\n};\n\nBase.extend = function(_instance, _static) { // subclass\n\tvar extend = Base.prototype.extend;\n\t\n\t// build the prototype\n\tBase._prototyping = true;\n\tvar proto = new this;\n\textend.call(proto, _instance);\n  proto.base = function() {\n    // call this method from any other method to invoke that method's ancestor\n  };\n\tdelete Base._prototyping;\n\t\n\t// create the wrapper for the constructor function\n\t//var constructor = proto.constructor.valueOf(); //-dean\n\tvar constructor = proto.constructor;\n\tvar klass = proto.constructor = function() {\n\t\tif (!Base._prototyping) {\n\t\t\tif (this._constructing || this.constructor == klass) { // instantiation\n\t\t\t\tthis._constructing = true;\n\t\t\t\tconstructor.apply(this, arguments);\n\t\t\t\tdelete this._constructing;\n\t\t\t} else if (arguments[0] != null) { // casting\n\t\t\t\treturn (arguments[0].extend || extend).call(arguments[0], proto);\n\t\t\t}\n\t\t}\n\t};\n\t\n\t// build the class interface\n\tklass.ancestor = this;\n\tklass.extend = this.extend;\n\tklass.forEach = this.forEach;\n\tklass.implement = this.implement;\n\tklass.prototype = proto;\n\tklass.toString = this.toString;\n\tklass.valueOf = function(type) {\n\t\t//return (type == \"object\") ? klass : constructor; //-dean\n\t\treturn (type == \"object\") ? klass : constructor.valueOf();\n\t};\n\textend.call(klass, _static);\n\t// class initialisation\n\tif (typeof klass.init == \"function\") klass.init();\n\treturn klass;\n};\n\nBase.prototype = {\t\n\textend: function(source, value) {\n\t\tif (arguments.length > 1) { // extending with a name/value pair\n\t\t\tvar ancestor = this[source];\n\t\t\tif (ancestor && (typeof value == \"function\") && // overriding a method?\n\t\t\t\t// the valueOf() comparison is to avoid circular references\n\t\t\t\t(!ancestor.valueOf || ancestor.valueOf() != value.valueOf()) &&\n\t\t\t\t/\\bbase\\b/.test(value)) {\n\t\t\t\t// get the underlying method\n\t\t\t\tvar method = value.valueOf();\n\t\t\t\t// override\n\t\t\t\tvalue = function() {\n\t\t\t\t\tvar previous = this.base || Base.prototype.base;\n\t\t\t\t\tthis.base = ancestor;\n\t\t\t\t\tvar returnValue = method.apply(this, arguments);\n\t\t\t\t\tthis.base = previous;\n\t\t\t\t\treturn returnValue;\n\t\t\t\t};\n\t\t\t\t// point to the underlying method\n\t\t\t\tvalue.valueOf = function(type) {\n\t\t\t\t\treturn (type == \"object\") ? value : method;\n\t\t\t\t};\n\t\t\t\tvalue.toString = Base.toString;\n\t\t\t}\n\t\t\tthis[source] = value;\n\t\t} else if (source) { // extending with an object literal\n\t\t\tvar extend = Base.prototype.extend;\n\t\t\t// if this object has a customised extend method then use it\n\t\t\tif (!Base._prototyping && typeof this != \"function\") {\n\t\t\t\textend = this.extend || extend;\n\t\t\t}\n\t\t\tvar proto = {toSource: null};\n\t\t\t// do the \"toString\" and other methods manually\n\t\t\tvar hidden = [\"constructor\", \"toString\", \"valueOf\"];\n\t\t\t// if we are prototyping then include the constructor\n\t\t\tvar i = Base._prototyping ? 0 : 1;\n\t\t\twhile (key = hidden[i++]) {\n\t\t\t\tif (source[key] != proto[key]) {\n\t\t\t\t\textend.call(this, key, source[key]);\n\n\t\t\t\t}\n\t\t\t}\n\t\t\t// copy each of the source object's properties to this object\n\t\t\tfor (var key in source) {\n\t\t\t\tif (!proto[key]) extend.call(this, key, source[key]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n};\n\n// initialise\nBase = Base.extend({\n\tconstructor: function() {\n\t\tthis.extend(arguments[0]);\n\t}\n}, {\n\tancestor: Object,\n\tversion: \"1.1\",\n\t\n\tforEach: function(object, block, context) {\n\t\tfor (var key in object) {\n\t\t\tif (this.prototype[key] === undefined) {\n\t\t\t\tblock.call(context, object[key], key, object);\n\t\t\t}\n\t\t}\n\t},\n\t\t\n\timplement: function() {\n\t\tfor (var i = 0; i < arguments.length; i++) {\n\t\t\tif (typeof arguments[i] == \"function\") {\n\t\t\t\t// if it's a function, call it\n\t\t\t\targuments[i](this.prototype);\n\t\t\t} else {\n\t\t\t\t// add the interface using the extend method\n\t\t\t\tthis.prototype.extend(arguments[i]);\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t},\n\t\n\ttoString: function() {\n\t\treturn String(this.valueOf());\n\t}\n});;/**\n * Detect browser support for specific features\n */\nwysihtml5.browser = (function() {\n  var userAgent   = navigator.userAgent,\n      testElement = document.createElement(\"div\"),\n      // Browser sniffing is unfortunately needed since some behaviors are impossible to feature detect\n      isGecko     = userAgent.indexOf(\"Gecko\")        !== -1 && userAgent.indexOf(\"KHTML\") === -1,\n      isWebKit    = userAgent.indexOf(\"AppleWebKit/\") !== -1,\n      isChrome    = userAgent.indexOf(\"Chrome/\")      !== -1,\n      isOpera     = userAgent.indexOf(\"Opera/\")       !== -1;\n\n  function iosVersion(userAgent) {\n    return +((/ipad|iphone|ipod/.test(userAgent) && userAgent.match(/ os (\\d+).+? like mac os x/)) || [undefined, 0])[1];\n  }\n\n  function androidVersion(userAgent) {\n    return +(userAgent.match(/android (\\d+)/) || [undefined, 0])[1];\n  }\n\n  function isIE(version, equation) {\n    var rv = -1,\n        re;\n\n    if (navigator.appName == 'Microsoft Internet Explorer') {\n      re = new RegExp(\"MSIE ([0-9]{1,}[\\.0-9]{0,})\");\n    } else if (navigator.appName == 'Netscape') {\n      re = new RegExp(\"Trident/.*rv:([0-9]{1,}[\\.0-9]{0,})\");\n    }\n\n    if (re && re.exec(navigator.userAgent) != null) {\n      rv = parseFloat(RegExp.$1);\n    }\n\n    if (rv === -1) { return false; }\n    if (!version) { return true; }\n    if (!equation) { return version === rv; }\n    if (equation === \"<\") { return version < rv; }\n    if (equation === \">\") { return version > rv; }\n    if (equation === \"<=\") { return version <= rv; }\n    if (equation === \">=\") { return version >= rv; }\n  }\n\n  return {\n    // Static variable needed, publicly accessible, to be able override it in unit tests\n    USER_AGENT: userAgent,\n\n    /**\n     * Exclude browsers that are not capable of displaying and handling\n     * contentEditable as desired:\n     *    - iPhone, iPad (tested iOS 4.2.2) and Android (tested 2.2) refuse to make contentEditables focusable\n     *    - IE < 8 create invalid markup and crash randomly from time to time\n     *\n     * @return {Boolean}\n     */\n    supported: function() {\n      var userAgent                   = this.USER_AGENT.toLowerCase(),\n          // Essential for making html elements editable\n          hasContentEditableSupport   = \"contentEditable\" in testElement,\n          // Following methods are needed in order to interact with the contentEditable area\n          hasEditingApiSupport        = document.execCommand && document.queryCommandSupported && document.queryCommandState,\n          // document selector apis are only supported by IE 8+, Safari 4+, Chrome and Firefox 3.5+\n          hasQuerySelectorSupport     = document.querySelector && document.querySelectorAll,\n          // contentEditable is unusable in mobile browsers (tested iOS 4.2.2, Android 2.2, Opera Mobile, WebOS 3.05)\n          isIncompatibleMobileBrowser = (this.isIos() && iosVersion(userAgent) < 5) || (this.isAndroid() && androidVersion(userAgent) < 4) || userAgent.indexOf(\"opera mobi\") !== -1 || userAgent.indexOf(\"hpwos/\") !== -1;\n      return hasContentEditableSupport\n        && hasEditingApiSupport\n        && hasQuerySelectorSupport\n        && !isIncompatibleMobileBrowser;\n    },\n\n    isTouchDevice: function() {\n      return this.supportsEvent(\"touchmove\");\n    },\n\n    isIos: function() {\n      return (/ipad|iphone|ipod/i).test(this.USER_AGENT);\n    },\n\n    isAndroid: function() {\n      return this.USER_AGENT.indexOf(\"Android\") !== -1;\n    },\n\n    /**\n     * Whether the browser supports sandboxed iframes\n     * Currently only IE 6+ offers such feature <iframe security=\"restricted\">\n     *\n     * http://msdn.microsoft.com/en-us/library/ms534622(v=vs.85).aspx\n     * http://blogs.msdn.com/b/ie/archive/2008/01/18/using-frames-more-securely.aspx\n     *\n     * HTML5 sandboxed iframes are still buggy and their DOM is not reachable from the outside (except when using postMessage)\n     */\n    supportsSandboxedIframes: function() {\n      return isIE();\n    },\n\n    /**\n     * IE6+7 throw a mixed content warning when the src of an iframe\n     * is empty/unset or about:blank\n     * window.querySelector is implemented as of IE8\n     */\n    throwsMixedContentWarningWhenIframeSrcIsEmpty: function() {\n      return !(\"querySelector\" in document);\n    },\n\n    /**\n     * Whether the caret is correctly displayed in contentEditable elements\n     * Firefox sometimes shows a huge caret in the beginning after focusing\n     */\n    displaysCaretInEmptyContentEditableCorrectly: function() {\n      return isIE();\n    },\n\n    /**\n     * Opera and IE are the only browsers who offer the css value\n     * in the original unit, thx to the currentStyle object\n     * All other browsers provide the computed style in px via window.getComputedStyle\n     */\n    hasCurrentStyleProperty: function() {\n      return \"currentStyle\" in testElement;\n    },\n\n    /**\n     * Firefox on OSX navigates through history when hitting CMD + Arrow right/left\n     */\n    hasHistoryIssue: function() {\n      return isGecko && navigator.platform.substr(0, 3) === \"Mac\";\n    },\n\n    /**\n     * Whether the browser inserts a <br> when pressing enter in a contentEditable element\n     */\n    insertsLineBreaksOnReturn: function() {\n      return isGecko;\n    },\n\n    supportsPlaceholderAttributeOn: function(element) {\n      return \"placeholder\" in element;\n    },\n\n    supportsEvent: function(eventName) {\n      return \"on\" + eventName in testElement || (function() {\n        testElement.setAttribute(\"on\" + eventName, \"return;\");\n        return typeof(testElement[\"on\" + eventName]) === \"function\";\n      })();\n    },\n\n    /**\n     * Opera doesn't correctly fire focus/blur events when clicking in- and outside of iframe\n     */\n    supportsEventsInIframeCorrectly: function() {\n      return !isOpera;\n    },\n\n    /**\n     * Everything below IE9 doesn't know how to treat HTML5 tags\n     *\n     * @param {Object} context The document object on which to check HTML5 support\n     *\n     * @example\n     *    wysihtml5.browser.supportsHTML5Tags(document);\n     */\n    supportsHTML5Tags: function(context) {\n      var element = context.createElement(\"div\"),\n          html5   = \"<article>foo</article>\";\n      element.innerHTML = html5;\n      return element.innerHTML.toLowerCase() === html5;\n    },\n\n    /**\n     * Checks whether a document supports a certain queryCommand\n     * In particular, Opera needs a reference to a document that has a contentEditable in it's dom tree\n     * in oder to report correct results\n     *\n     * @param {Object} doc Document object on which to check for a query command\n     * @param {String} command The query command to check for\n     * @return {Boolean}\n     *\n     * @example\n     *    wysihtml5.browser.supportsCommand(document, \"bold\");\n     */\n    supportsCommand: (function() {\n      // Following commands are supported but contain bugs in some browsers\n      var buggyCommands = {\n        // formatBlock fails with some tags (eg. <blockquote>)\n        \"formatBlock\":          isIE(10, \"<=\"),\n         // When inserting unordered or ordered lists in Firefox, Chrome or Safari, the current selection or line gets\n         // converted into a list (<ul><li>...</li></ul>, <ol><li>...</li></ol>)\n         // IE and Opera act a bit different here as they convert the entire content of the current block element into a list\n        \"insertUnorderedList\":  isIE(),\n        \"insertOrderedList\":    isIE()\n      };\n\n      // Firefox throws errors for queryCommandSupported, so we have to build up our own object of supported commands\n      var supported = {\n        \"insertHTML\": isGecko\n      };\n\n      return function(doc, command) {\n        var isBuggy = buggyCommands[command];\n        if (!isBuggy) {\n          // Firefox throws errors when invoking queryCommandSupported or queryCommandEnabled\n          try {\n            return doc.queryCommandSupported(command);\n          } catch(e1) {}\n\n          try {\n            return doc.queryCommandEnabled(command);\n          } catch(e2) {\n            return !!supported[command];\n          }\n        }\n        return false;\n      };\n    })(),\n\n    /**\n     * IE: URLs starting with:\n     *    www., http://, https://, ftp://, gopher://, mailto:, new:, snews:, telnet:, wasis:, file://,\n     *    nntp://, newsrc:, ldap://, ldaps://, outlook:, mic:// and url:\n     * will automatically be auto-linked when either the user inserts them via copy&paste or presses the\n     * space bar when the caret is directly after such an url.\n     * This behavior cannot easily be avoided in IE < 9 since the logic is hardcoded in the mshtml.dll\n     * (related blog post on msdn\n     * http://blogs.msdn.com/b/ieinternals/archive/2009/09/17/prevent-automatic-hyperlinking-in-contenteditable-html.aspx).\n     */\n    doesAutoLinkingInContentEditable: function() {\n      return isIE();\n    },\n\n    /**\n     * As stated above, IE auto links urls typed into contentEditable elements\n     * Since IE9 it's possible to prevent this behavior\n     */\n    canDisableAutoLinking: function() {\n      return this.supportsCommand(document, \"AutoUrlDetect\");\n    },\n\n    /**\n     * IE leaves an empty paragraph in the contentEditable element after clearing it\n     * Chrome/Safari sometimes an empty <div>\n     */\n    clearsContentEditableCorrectly: function() {\n      return isGecko || isOpera || isWebKit;\n    },\n\n    /**\n     * IE gives wrong results for getAttribute\n     */\n    supportsGetAttributeCorrectly: function() {\n      var td = document.createElement(\"td\");\n      return td.getAttribute(\"rowspan\") != \"1\";\n    },\n\n    /**\n     * When clicking on images in IE, Opera and Firefox, they are selected, which makes it easy to interact with them.\n     * Chrome and Safari both don't support this\n     */\n    canSelectImagesInContentEditable: function() {\n      return isGecko || isIE() || isOpera;\n    },\n\n    /**\n     * All browsers except Safari and Chrome automatically scroll the range/caret position into view\n     */\n    autoScrollsToCaret: function() {\n      return !isWebKit;\n    },\n\n    /**\n     * Check whether the browser automatically closes tags that don't need to be opened\n     */\n    autoClosesUnclosedTags: function() {\n      var clonedTestElement = testElement.cloneNode(false),\n          returnValue,\n          innerHTML;\n\n      clonedTestElement.innerHTML = \"<p><div></div>\";\n      innerHTML                   = clonedTestElement.innerHTML.toLowerCase();\n      returnValue                 = innerHTML === \"<p></p><div></div>\" || innerHTML === \"<p><div></div></p>\";\n\n      // Cache result by overwriting current function\n      this.autoClosesUnclosedTags = function() { return returnValue; };\n\n      return returnValue;\n    },\n\n    /**\n     * Whether the browser supports the native document.getElementsByClassName which returns live NodeLists\n     */\n    supportsNativeGetElementsByClassName: function() {\n      return String(document.getElementsByClassName).indexOf(\"[native code]\") !== -1;\n    },\n\n    /**\n     * As of now (19.04.2011) only supported by Firefox 4 and Chrome\n     * See https://developer.mozilla.org/en/DOM/Selection/modify\n     */\n    supportsSelectionModify: function() {\n      return \"getSelection\" in window && \"modify\" in window.getSelection();\n    },\n\n    /**\n     * Opera needs a white space after a <br> in order to position the caret correctly\n     */\n    needsSpaceAfterLineBreak: function() {\n      return isOpera;\n    },\n\n    /**\n     * Whether the browser supports the speech api on the given element\n     * See http://mikepultz.com/2011/03/accessing-google-speech-api-chrome-11/\n     *\n     * @example\n     *    var input = document.createElement(\"input\");\n     *    if (wysihtml5.browser.supportsSpeechApiOn(input)) {\n     *      // ...\n     *    }\n     */\n    supportsSpeechApiOn: function(input) {\n      var chromeVersion = userAgent.match(/Chrome\\/(\\d+)/) || [undefined, 0];\n      return chromeVersion[1] >= 11 && (\"onwebkitspeechchange\" in input || \"speech\" in input);\n    },\n\n    /**\n     * IE9 crashes when setting a getter via Object.defineProperty on XMLHttpRequest or XDomainRequest\n     * See https://connect.microsoft.com/ie/feedback/details/650112\n     * or try the POC http://tifftiff.de/ie9_crash/\n     */\n    crashesWhenDefineProperty: function(property) {\n      return isIE(9) && (property === \"XMLHttpRequest\" || property === \"XDomainRequest\");\n    },\n\n    /**\n     * IE is the only browser who fires the \"focus\" event not immediately when .focus() is called on an element\n     */\n    doesAsyncFocus: function() {\n      return isIE();\n    },\n\n    /**\n     * In IE it's impssible for the user and for the selection library to set the caret after an <img> when it's the lastChild in the document\n     */\n    hasProblemsSettingCaretAfterImg: function() {\n      return isIE();\n    },\n\n    hasUndoInContextMenu: function() {\n      return isGecko || isChrome || isOpera;\n    },\n\n    /**\n     * Opera sometimes doesn't insert the node at the right position when range.insertNode(someNode)\n     * is used (regardless if rangy or native)\n     * This especially happens when the caret is positioned right after a <br> because then\n     * insertNode() will insert the node right before the <br>\n     */\n    hasInsertNodeIssue: function() {\n      return isOpera;\n    },\n\n    /**\n     * IE 8+9 don't fire the focus event of the <body> when the iframe gets focused (even though the caret gets set into the <body>)\n     */\n    hasIframeFocusIssue: function() {\n      return isIE();\n    },\n\n    /**\n     * Chrome + Safari create invalid nested markup after paste\n     *\n     *  <p>\n     *    foo\n     *    <p>bar</p> <!-- BOO! -->\n     *  </p>\n     */\n    createsNestedInvalidMarkupAfterPaste: function() {\n      return isWebKit;\n    },\n\n    supportsMutationEvents: function() {\n        return (\"MutationEvent\" in window);\n    },\n\n    /**\n      IE (at least up to 11) does not support clipboardData on event.\n      It is on window but cannot return text/html\n      Should actually check for clipboardData on paste event, but cannot in firefox\n    */\n    supportsModenPaste: function () {\n      return !(\"clipboardData\" in window);\n    }\n  };\n})();\n;wysihtml5.lang.array = function(arr) {\n  return {\n    /**\n     * Check whether a given object exists in an array\n     *\n     * @example\n     *    wysihtml5.lang.array([1, 2]).contains(1);\n     *    // => true\n     *\n     * Can be used to match array with array. If intersection is found true is returned\n     */\n    contains: function(needle) {\n      if (Array.isArray(needle)) {\n        for (var i = needle.length; i--;) {\n          if (wysihtml5.lang.array(arr).indexOf(needle[i]) !== -1) {\n            return true;\n          }\n        }\n        return false;\n      } else {\n        return wysihtml5.lang.array(arr).indexOf(needle) !== -1;\n      }\n    },\n\n    /**\n     * Check whether a given object exists in an array and return index\n     * If no elelemt found returns -1\n     *\n     * @example\n     *    wysihtml5.lang.array([1, 2]).indexOf(2);\n     *    // => 1\n     */\n    indexOf: function(needle) {\n        if (arr.indexOf) {\n          return arr.indexOf(needle);\n        } else {\n          for (var i=0, length=arr.length; i<length; i++) {\n            if (arr[i] === needle) { return i; }\n          }\n          return -1;\n        }\n    },\n\n    /**\n     * Substract one array from another\n     *\n     * @example\n     *    wysihtml5.lang.array([1, 2, 3, 4]).without([3, 4]);\n     *    // => [1, 2]\n     */\n    without: function(arrayToSubstract) {\n      arrayToSubstract = wysihtml5.lang.array(arrayToSubstract);\n      var newArr  = [],\n          i       = 0,\n          length  = arr.length;\n      for (; i<length; i++) {\n        if (!arrayToSubstract.contains(arr[i])) {\n          newArr.push(arr[i]);\n        }\n      }\n      return newArr;\n    },\n\n    /**\n     * Return a clean native array\n     *\n     * Following will convert a Live NodeList to a proper Array\n     * @example\n     *    var childNodes = wysihtml5.lang.array(document.body.childNodes).get();\n     */\n    get: function() {\n      var i        = 0,\n          length   = arr.length,\n          newArray = [];\n      for (; i<length; i++) {\n        newArray.push(arr[i]);\n      }\n      return newArray;\n    },\n\n    /**\n     * Creates a new array with the results of calling a provided function on every element in this array.\n     * optionally this can be provided as second argument\n     *\n     * @example\n     *    var childNodes = wysihtml5.lang.array([1,2,3,4]).map(function (value, index, array) {\n            return value * 2;\n     *    });\n     *    // => [2,4,6,8]\n     */\n    map: function(callback, thisArg) {\n      if (Array.prototype.map) {\n        return arr.map(callback, thisArg);\n      } else {\n        var len = arr.length >>> 0,\n            A = new Array(len),\n            i = 0;\n        for (; i < len; i++) {\n           A[i] = callback.call(thisArg, arr[i], i, arr);\n        }\n        return A;\n      }\n    },\n\n    /* ReturnS new array without duplicate entries\n     *\n     * @example\n     *    var uniq = wysihtml5.lang.array([1,2,3,2,1,4]).unique();\n     *    // => [1,2,3,4]\n     */\n    unique: function() {\n      var vals = [],\n          max = arr.length,\n          idx = 0;\n\n      while (idx < max) {\n        if (!wysihtml5.lang.array(vals).contains(arr[idx])) {\n          vals.push(arr[idx]);\n        }\n        idx++;\n      }\n      return vals;\n    }\n\n  };\n};\n;wysihtml5.lang.Dispatcher = Base.extend(\n  /** @scope wysihtml5.lang.Dialog.prototype */ {\n  on: function(eventName, handler) {\n    this.events = this.events || {};\n    this.events[eventName] = this.events[eventName] || [];\n    this.events[eventName].push(handler);\n    return this;\n  },\n\n  off: function(eventName, handler) {\n    this.events = this.events || {};\n    var i = 0,\n        handlers,\n        newHandlers;\n    if (eventName) {\n      handlers    = this.events[eventName] || [],\n      newHandlers = [];\n      for (; i<handlers.length; i++) {\n        if (handlers[i] !== handler && handler) {\n          newHandlers.push(handlers[i]);\n        }\n      }\n      this.events[eventName] = newHandlers;\n    } else {\n      // Clean up all events\n      this.events = {};\n    }\n    return this;\n  },\n\n  fire: function(eventName, payload) {\n    this.events = this.events || {};\n    var handlers = this.events[eventName] || [],\n        i        = 0;\n    for (; i<handlers.length; i++) {\n      handlers[i].call(this, payload);\n    }\n    return this;\n  },\n\n  // deprecated, use .on()\n  observe: function() {\n    return this.on.apply(this, arguments);\n  },\n\n  // deprecated, use .off()\n  stopObserving: function() {\n    return this.off.apply(this, arguments);\n  }\n});\n;wysihtml5.lang.object = function(obj) {\n  return {\n    /**\n     * @example\n     *    wysihtml5.lang.object({ foo: 1, bar: 1 }).merge({ bar: 2, baz: 3 }).get();\n     *    // => { foo: 1, bar: 2, baz: 3 }\n     */\n    merge: function(otherObj) {\n      for (var i in otherObj) {\n        obj[i] = otherObj[i];\n      }\n      return this;\n    },\n\n    get: function() {\n      return obj;\n    },\n\n    /**\n     * @example\n     *    wysihtml5.lang.object({ foo: 1 }).clone();\n     *    // => { foo: 1 }\n     *\n     *    v0.4.14 adds options for deep clone : wysihtml5.lang.object({ foo: 1 }).clone(true);\n     */\n    clone: function(deep) {\n      var newObj = {},\n          i;\n\n      if (obj === null || !wysihtml5.lang.object(obj).isPlainObject()) {\n        return obj;\n      }\n\n      for (i in obj) {\n        if(obj.hasOwnProperty(i)) {\n          if (deep) {\n            newObj[i] = wysihtml5.lang.object(obj[i]).clone(deep);\n          } else {\n            newObj[i] = obj[i];\n          }\n        }\n      }\n      return newObj;\n    },\n\n    /**\n     * @example\n     *    wysihtml5.lang.object([]).isArray();\n     *    // => true\n     */\n    isArray: function() {\n      return Object.prototype.toString.call(obj) === \"[object Array]\";\n    },\n\n    /**\n     * @example\n     *    wysihtml5.lang.object(function() {}).isFunction();\n     *    // => true\n     */\n    isFunction: function() {\n      return Object.prototype.toString.call(obj) === '[object Function]';\n    },\n\n    isPlainObject: function () {\n      return Object.prototype.toString.call(obj) === '[object Object]';\n    }\n  };\n};\n;(function() {\n  var WHITE_SPACE_START = /^\\s+/,\n      WHITE_SPACE_END   = /\\s+$/,\n      ENTITY_REG_EXP    = /[&<>\\t\"]/g,\n      ENTITY_MAP = {\n        '&': '&amp;',\n        '<': '&lt;',\n        '>': '&gt;',\n        '\"': \"&quot;\",\n        '\\t':\"&nbsp; \"\n      };\n  wysihtml5.lang.string = function(str) {\n    str = String(str);\n    return {\n      /**\n       * @example\n       *    wysihtml5.lang.string(\"   foo   \").trim();\n       *    // => \"foo\"\n       */\n      trim: function() {\n        return str.replace(WHITE_SPACE_START, \"\").replace(WHITE_SPACE_END, \"\");\n      },\n\n      /**\n       * @example\n       *    wysihtml5.lang.string(\"Hello #{name}\").interpolate({ name: \"Christopher\" });\n       *    // => \"Hello Christopher\"\n       */\n      interpolate: function(vars) {\n        for (var i in vars) {\n          str = this.replace(\"#{\" + i + \"}\").by(vars[i]);\n        }\n        return str;\n      },\n\n      /**\n       * @example\n       *    wysihtml5.lang.string(\"Hello Tom\").replace(\"Tom\").with(\"Hans\");\n       *    // => \"Hello Hans\"\n       */\n      replace: function(search) {\n        return {\n          by: function(replace) {\n            return str.split(search).join(replace);\n          }\n        };\n      },\n\n      /**\n       * @example\n       *    wysihtml5.lang.string(\"hello<br>\").escapeHTML();\n       *    // => \"hello&lt;br&gt;\"\n       */\n      escapeHTML: function(linebreaks, convertSpaces) {\n        var html = str.replace(ENTITY_REG_EXP, function(c) { return ENTITY_MAP[c]; });\n        if (linebreaks) {\n          html = html.replace(/(?:\\r\\n|\\r|\\n)/g, '<br />');\n        }\n        if (convertSpaces) {\n          html = html.replace(/  /gi, \"&nbsp; \");\n        }\n        return html;\n      }\n    };\n  };\n})();\n;/**\n * Find urls in descendant text nodes of an element and auto-links them\n * Inspired by http://james.padolsey.com/javascript/find-and-replace-text-with-javascript/\n *\n * @param {Element} element Container element in which to search for urls\n *\n * @example\n *    <div id=\"text-container\">Please click here: www.google.com</div>\n *    <script>wysihtml5.dom.autoLink(document.getElementById(\"text-container\"));</script>\n */\n(function(wysihtml5) {\n  var /**\n       * Don't auto-link urls that are contained in the following elements:\n       */\n      IGNORE_URLS_IN        = wysihtml5.lang.array([\"CODE\", \"PRE\", \"A\", \"SCRIPT\", \"HEAD\", \"TITLE\", \"STYLE\"]),\n      /**\n       * revision 1:\n       *    /(\\S+\\.{1}[^\\s\\,\\.\\!]+)/g\n       *\n       * revision 2:\n       *    /(\\b(((https?|ftp):\\/\\/)|(www\\.))[-A-Z0-9+&@#\\/%?=~_|!:,.;\\[\\]]*[-A-Z0-9+&@#\\/%=~_|])/gim\n       *\n       * put this in the beginning if you don't wan't to match within a word\n       *    (^|[\\>\\(\\{\\[\\s\\>])\n       */\n      URL_REG_EXP           = /((https?:\\/\\/|www\\.)[^\\s<]{3,})/gi,\n      TRAILING_CHAR_REG_EXP = /([^\\w\\/\\-](,?))$/i,\n      MAX_DISPLAY_LENGTH    = 100,\n      BRACKETS              = { \")\": \"(\", \"]\": \"[\", \"}\": \"{\" };\n\n  function autoLink(element, ignoreInClasses) {\n    if (_hasParentThatShouldBeIgnored(element, ignoreInClasses)) {\n      return element;\n    }\n\n    if (element === element.ownerDocument.documentElement) {\n      element = element.ownerDocument.body;\n    }\n\n    return _parseNode(element, ignoreInClasses);\n  }\n\n  /**\n   * This is basically a rebuild of\n   * the rails auto_link_urls text helper\n   */\n  function _convertUrlsToLinks(str) {\n    return str.replace(URL_REG_EXP, function(match, url) {\n      var punctuation = (url.match(TRAILING_CHAR_REG_EXP) || [])[1] || \"\",\n          opening     = BRACKETS[punctuation];\n      url = url.replace(TRAILING_CHAR_REG_EXP, \"\");\n\n      if (url.split(opening).length > url.split(punctuation).length) {\n        url = url + punctuation;\n        punctuation = \"\";\n      }\n      var realUrl    = url,\n          displayUrl = url;\n      if (url.length > MAX_DISPLAY_LENGTH) {\n        displayUrl = displayUrl.substr(0, MAX_DISPLAY_LENGTH) + \"...\";\n      }\n      // Add http prefix if necessary\n      if (realUrl.substr(0, 4) === \"www.\") {\n        realUrl = \"http://\" + realUrl;\n      }\n\n      return '<a href=\"' + realUrl + '\">' + displayUrl + '</a>' + punctuation;\n    });\n  }\n\n  /**\n   * Creates or (if already cached) returns a temp element\n   * for the given document object\n   */\n  function _getTempElement(context) {\n    var tempElement = context._wysihtml5_tempElement;\n    if (!tempElement) {\n      tempElement = context._wysihtml5_tempElement = context.createElement(\"div\");\n    }\n    return tempElement;\n  }\n\n  /**\n   * Replaces the original text nodes with the newly auto-linked dom tree\n   */\n  function _wrapMatchesInNode(textNode) {\n    var parentNode  = textNode.parentNode,\n        nodeValue   = wysihtml5.lang.string(textNode.data).escapeHTML(),\n        tempElement = _getTempElement(parentNode.ownerDocument);\n\n    // We need to insert an empty/temporary <span /> to fix IE quirks\n    // Elsewise IE would strip white space in the beginning\n    tempElement.innerHTML = \"<span></span>\" + _convertUrlsToLinks(nodeValue);\n    tempElement.removeChild(tempElement.firstChild);\n\n    while (tempElement.firstChild) {\n      // inserts tempElement.firstChild before textNode\n      parentNode.insertBefore(tempElement.firstChild, textNode);\n    }\n    parentNode.removeChild(textNode);\n  }\n\n  function _hasParentThatShouldBeIgnored(node, ignoreInClasses) {\n    var nodeName;\n    while (node.parentNode) {\n      node = node.parentNode;\n      nodeName = node.nodeName;\n      if (node.className && wysihtml5.lang.array(node.className.split(' ')).contains(ignoreInClasses)) {\n        return true;\n      }\n      if (IGNORE_URLS_IN.contains(nodeName)) {\n        return true;\n      } else if (nodeName === \"body\") {\n        return false;\n      }\n    }\n    return false;\n  }\n\n  function _parseNode(element, ignoreInClasses) {\n    if (IGNORE_URLS_IN.contains(element.nodeName)) {\n      return;\n    }\n\n    if (element.className && wysihtml5.lang.array(element.className.split(' ')).contains(ignoreInClasses)) {\n      return;\n    }\n\n    if (element.nodeType === wysihtml5.TEXT_NODE && element.data.match(URL_REG_EXP)) {\n      _wrapMatchesInNode(element);\n      return;\n    }\n\n    var childNodes        = wysihtml5.lang.array(element.childNodes).get(),\n        childNodesLength  = childNodes.length,\n        i                 = 0;\n\n    for (; i<childNodesLength; i++) {\n      _parseNode(childNodes[i], ignoreInClasses);\n    }\n\n    return element;\n  }\n\n  wysihtml5.dom.autoLink = autoLink;\n\n  // Reveal url reg exp to the outside\n  wysihtml5.dom.autoLink.URL_REG_EXP = URL_REG_EXP;\n})(wysihtml5);\n;(function(wysihtml5) {\n  var api = wysihtml5.dom;\n\n  api.addClass = function(element, className) {\n    var classList = element.classList;\n    if (classList) {\n      return classList.add(className);\n    }\n    if (api.hasClass(element, className)) {\n      return;\n    }\n    element.className += \" \" + className;\n  };\n\n  api.removeClass = function(element, className) {\n    var classList = element.classList;\n    if (classList) {\n      return classList.remove(className);\n    }\n\n    element.className = element.className.replace(new RegExp(\"(^|\\\\s+)\" + className + \"(\\\\s+|$)\"), \" \");\n  };\n\n  api.hasClass = function(element, className) {\n    var classList = element.classList;\n    if (classList) {\n      return classList.contains(className);\n    }\n\n    var elementClassName = element.className;\n    return (elementClassName.length > 0 && (elementClassName == className || new RegExp(\"(^|\\\\s)\" + className + \"(\\\\s|$)\").test(elementClassName)));\n  };\n})(wysihtml5);\n;wysihtml5.dom.contains = (function() {\n  var documentElement = document.documentElement;\n  if (documentElement.contains) {\n    return function(container, element) {\n      if (element.nodeType !== wysihtml5.ELEMENT_NODE) {\n        element = element.parentNode;\n      }\n      return container !== element && container.contains(element);\n    };\n  } else if (documentElement.compareDocumentPosition) {\n    return function(container, element) {\n      // https://developer.mozilla.org/en/DOM/Node.compareDocumentPosition\n      return !!(container.compareDocumentPosition(element) & 16);\n    };\n  }\n})();\n;/**\n * Converts an HTML fragment/element into a unordered/ordered list\n *\n * @param {Element} element The element which should be turned into a list\n * @param {String} listType The list type in which to convert the tree (either \"ul\" or \"ol\")\n * @return {Element} The created list\n *\n * @example\n *    <!-- Assume the following dom: -->\n *    <span id=\"pseudo-list\">\n *      eminem<br>\n *      dr. dre\n *      <div>50 Cent</div>\n *    </span>\n *\n *    <script>\n *      wysihtml5.dom.convertToList(document.getElementById(\"pseudo-list\"), \"ul\");\n *    </script>\n *\n *    <!-- Will result in: -->\n *    <ul>\n *      <li>eminem</li>\n *      <li>dr. dre</li>\n *      <li>50 Cent</li>\n *    </ul>\n */\nwysihtml5.dom.convertToList = (function() {\n  function _createListItem(doc, list) {\n    var listItem = doc.createElement(\"li\");\n    list.appendChild(listItem);\n    return listItem;\n  }\n\n  function _createList(doc, type) {\n    return doc.createElement(type);\n  }\n\n  function convertToList(element, listType, uneditableClass) {\n    if (element.nodeName === \"UL\" || element.nodeName === \"OL\" || element.nodeName === \"MENU\") {\n      // Already a list\n      return element;\n    }\n\n    var doc               = element.ownerDocument,\n        list              = _createList(doc, listType),\n        lineBreaks        = element.querySelectorAll(\"br\"),\n        lineBreaksLength  = lineBreaks.length,\n        childNodes,\n        childNodesLength,\n        childNode,\n        lineBreak,\n        parentNode,\n        isBlockElement,\n        isLineBreak,\n        currentListItem,\n        i;\n\n    // First find <br> at the end of inline elements and move them behind them\n    for (i=0; i<lineBreaksLength; i++) {\n      lineBreak = lineBreaks[i];\n      while ((parentNode = lineBreak.parentNode) && parentNode !== element && parentNode.lastChild === lineBreak) {\n        if (wysihtml5.dom.getStyle(\"display\").from(parentNode) === \"block\") {\n          parentNode.removeChild(lineBreak);\n          break;\n        }\n        wysihtml5.dom.insert(lineBreak).after(lineBreak.parentNode);\n      }\n    }\n\n    childNodes        = wysihtml5.lang.array(element.childNodes).get();\n    childNodesLength  = childNodes.length;\n\n    for (i=0; i<childNodesLength; i++) {\n      currentListItem   = currentListItem || _createListItem(doc, list);\n      childNode         = childNodes[i];\n      isBlockElement    = wysihtml5.dom.getStyle(\"display\").from(childNode) === \"block\";\n      isLineBreak       = childNode.nodeName === \"BR\";\n\n      // consider uneditable as an inline element\n      if (isBlockElement && (!uneditableClass || !wysihtml5.dom.hasClass(childNode, uneditableClass))) {\n        // Append blockElement to current <li> if empty, otherwise create a new one\n        currentListItem = currentListItem.firstChild ? _createListItem(doc, list) : currentListItem;\n        currentListItem.appendChild(childNode);\n        currentListItem = null;\n        continue;\n      }\n\n      if (isLineBreak) {\n        // Only create a new list item in the next iteration when the current one has already content\n        currentListItem = currentListItem.firstChild ? null : currentListItem;\n        continue;\n      }\n\n      currentListItem.appendChild(childNode);\n    }\n\n    if (childNodes.length === 0) {\n      _createListItem(doc, list);\n    }\n\n    element.parentNode.replaceChild(list, element);\n    return list;\n  }\n\n  return convertToList;\n})();\n;/**\n * Copy a set of attributes from one element to another\n *\n * @param {Array} attributesToCopy List of attributes which should be copied\n * @return {Object} Returns an object which offers the \"from\" method which can be invoked with the element where to\n *    copy the attributes from., this again returns an object which provides a method named \"to\" which can be invoked\n *    with the element where to copy the attributes to (see example)\n *\n * @example\n *    var textarea    = document.querySelector(\"textarea\"),\n *        div         = document.querySelector(\"div[contenteditable=true]\"),\n *        anotherDiv  = document.querySelector(\"div.preview\");\n *    wysihtml5.dom.copyAttributes([\"spellcheck\", \"value\", \"placeholder\"]).from(textarea).to(div).andTo(anotherDiv);\n *\n */\nwysihtml5.dom.copyAttributes = function(attributesToCopy) {\n  return {\n    from: function(elementToCopyFrom) {\n      return {\n        to: function(elementToCopyTo) {\n          var attribute,\n              i         = 0,\n              length    = attributesToCopy.length;\n          for (; i<length; i++) {\n            attribute = attributesToCopy[i];\n            if (typeof(elementToCopyFrom[attribute]) !== \"undefined\" && elementToCopyFrom[attribute] !== \"\") {\n              elementToCopyTo[attribute] = elementToCopyFrom[attribute];\n            }\n          }\n          return { andTo: arguments.callee };\n        }\n      };\n    }\n  };\n};\n;/**\n * Copy a set of styles from one element to another\n * Please note that this only works properly across browsers when the element from which to copy the styles\n * is in the dom\n *\n * Interesting article on how to copy styles\n *\n * @param {Array} stylesToCopy List of styles which should be copied\n * @return {Object} Returns an object which offers the \"from\" method which can be invoked with the element where to\n *    copy the styles from., this again returns an object which provides a method named \"to\" which can be invoked\n *    with the element where to copy the styles to (see example)\n *\n * @example\n *    var textarea    = document.querySelector(\"textarea\"),\n *        div         = document.querySelector(\"div[contenteditable=true]\"),\n *        anotherDiv  = document.querySelector(\"div.preview\");\n *    wysihtml5.dom.copyStyles([\"overflow-y\", \"width\", \"height\"]).from(textarea).to(div).andTo(anotherDiv);\n *\n */\n(function(dom) {\n\n  /**\n   * Mozilla, WebKit and Opera recalculate the computed width when box-sizing: boder-box; is set\n   * So if an element has \"width: 200px; -moz-box-sizing: border-box; border: 1px;\" then\n   * its computed css width will be 198px\n   *\n   * See https://bugzilla.mozilla.org/show_bug.cgi?id=520992\n   */\n  var BOX_SIZING_PROPERTIES = [\"-webkit-box-sizing\", \"-moz-box-sizing\", \"-ms-box-sizing\", \"box-sizing\"];\n\n  var shouldIgnoreBoxSizingBorderBox = function(element) {\n    if (hasBoxSizingBorderBox(element)) {\n       return parseInt(dom.getStyle(\"width\").from(element), 10) < element.offsetWidth;\n    }\n    return false;\n  };\n\n  var hasBoxSizingBorderBox = function(element) {\n    var i       = 0,\n        length  = BOX_SIZING_PROPERTIES.length;\n    for (; i<length; i++) {\n      if (dom.getStyle(BOX_SIZING_PROPERTIES[i]).from(element) === \"border-box\") {\n        return BOX_SIZING_PROPERTIES[i];\n      }\n    }\n  };\n\n  dom.copyStyles = function(stylesToCopy) {\n    return {\n      from: function(element) {\n        if (shouldIgnoreBoxSizingBorderBox(element)) {\n          stylesToCopy = wysihtml5.lang.array(stylesToCopy).without(BOX_SIZING_PROPERTIES);\n        }\n\n        var cssText = \"\",\n            length  = stylesToCopy.length,\n            i       = 0,\n            property;\n        for (; i<length; i++) {\n          property = stylesToCopy[i];\n          cssText += property + \":\" + dom.getStyle(property).from(element) + \";\";\n        }\n\n        return {\n          to: function(element) {\n            dom.setStyles(cssText).on(element);\n            return { andTo: arguments.callee };\n          }\n        };\n      }\n    };\n  };\n})(wysihtml5.dom);\n;/**\n * Event Delegation\n *\n * @example\n *    wysihtml5.dom.delegate(document.body, \"a\", \"click\", function() {\n *      // foo\n *    });\n */\n(function(wysihtml5) {\n\n  wysihtml5.dom.delegate = function(container, selector, eventName, handler) {\n    return wysihtml5.dom.observe(container, eventName, function(event) {\n      var target    = event.target,\n          match     = wysihtml5.lang.array(container.querySelectorAll(selector));\n\n      while (target && target !== container) {\n        if (match.contains(target)) {\n          handler.call(target, event);\n          break;\n        }\n        target = target.parentNode;\n      }\n    });\n  };\n\n})(wysihtml5);\n;// TODO: Refactor dom tree traversing here\n(function(wysihtml5) {\n  wysihtml5.dom.domNode = function(node) {\n    var defaultNodeTypes = [wysihtml5.ELEMENT_NODE, wysihtml5.TEXT_NODE];\n\n    var _isBlankText = function(node) {\n      return node.nodeType === wysihtml5.TEXT_NODE && (/^\\s*$/g).test(node.data);\n    };\n\n    return {\n\n      // var node = wysihtml5.dom.domNode(element).prev({nodeTypes: [1,3], ignoreBlankTexts: true});\n      prev: function(options) {\n        var prevNode = node.previousSibling,\n            types = (options && options.nodeTypes) ? options.nodeTypes : defaultNodeTypes;\n        \n        if (!prevNode) {\n          return null;\n        }\n\n        if (\n          (!wysihtml5.lang.array(types).contains(prevNode.nodeType)) || // nodeTypes check.\n          (options && options.ignoreBlankTexts && _isBlankText(prevNode)) // Blank text nodes bypassed if set\n        ) {\n          return wysihtml5.dom.domNode(prevNode).prev(options);\n        }\n        \n        return prevNode;\n      },\n\n      // var node = wysihtml5.dom.domNode(element).next({nodeTypes: [1,3], ignoreBlankTexts: true});\n      next: function(options) {\n        var nextNode = node.nextSibling,\n            types = (options && options.nodeTypes) ? options.nodeTypes : defaultNodeTypes;\n        \n        if (!nextNode) {\n          return null;\n        }\n\n        if (\n          (!wysihtml5.lang.array(types).contains(nextNode.nodeType)) || // nodeTypes check.\n          (options && options.ignoreBlankTexts && _isBlankText(nextNode)) // blank text nodes bypassed if set\n        ) {\n          return wysihtml5.dom.domNode(nextNode).next(options);\n        }\n        \n        return nextNode;\n      }\n\n\n\n    };\n  };\n})(wysihtml5);;/**\n * Returns the given html wrapped in a div element\n *\n * Fixing IE's inability to treat unknown elements (HTML5 section, article, ...) correctly\n * when inserted via innerHTML\n *\n * @param {String} html The html which should be wrapped in a dom element\n * @param {Obejct} [context] Document object of the context the html belongs to\n *\n * @example\n *    wysihtml5.dom.getAsDom(\"<article>foo</article>\");\n */\nwysihtml5.dom.getAsDom = (function() {\n\n  var _innerHTMLShiv = function(html, context) {\n    var tempElement = context.createElement(\"div\");\n    tempElement.style.display = \"none\";\n    context.body.appendChild(tempElement);\n    // IE throws an exception when trying to insert <frameset></frameset> via innerHTML\n    try { tempElement.innerHTML = html; } catch(e) {}\n    context.body.removeChild(tempElement);\n    return tempElement;\n  };\n\n  /**\n   * Make sure IE supports HTML5 tags, which is accomplished by simply creating one instance of each element\n   */\n  var _ensureHTML5Compatibility = function(context) {\n    if (context._wysihtml5_supportsHTML5Tags) {\n      return;\n    }\n    for (var i=0, length=HTML5_ELEMENTS.length; i<length; i++) {\n      context.createElement(HTML5_ELEMENTS[i]);\n    }\n    context._wysihtml5_supportsHTML5Tags = true;\n  };\n\n\n  /**\n   * List of html5 tags\n   * taken from http://simon.html5.org/html5-elements\n   */\n  var HTML5_ELEMENTS = [\n    \"abbr\", \"article\", \"aside\", \"audio\", \"bdi\", \"canvas\", \"command\", \"datalist\", \"details\", \"figcaption\",\n    \"figure\", \"footer\", \"header\", \"hgroup\", \"keygen\", \"mark\", \"meter\", \"nav\", \"output\", \"progress\",\n    \"rp\", \"rt\", \"ruby\", \"svg\", \"section\", \"source\", \"summary\", \"time\", \"track\", \"video\", \"wbr\"\n  ];\n\n  return function(html, context) {\n    context = context || document;\n    var tempElement;\n    if (typeof(html) === \"object\" && html.nodeType) {\n      tempElement = context.createElement(\"div\");\n      tempElement.appendChild(html);\n    } else if (wysihtml5.browser.supportsHTML5Tags(context)) {\n      tempElement = context.createElement(\"div\");\n      tempElement.innerHTML = html;\n    } else {\n      _ensureHTML5Compatibility(context);\n      tempElement = _innerHTMLShiv(html, context);\n    }\n    return tempElement;\n  };\n})();\n;/**\n * Walks the dom tree from the given node up until it finds a match\n * Designed for optimal performance.\n *\n * @param {Element} node The from which to check the parent nodes\n * @param {Object} matchingSet Object to match against (possible properties: nodeName, className, classRegExp)\n * @param {Number} [levels] How many parents should the function check up from the current node (defaults to 50)\n * @return {null|Element} Returns the first element that matched the desiredNodeName(s)\n * @example\n *    var listElement = wysihtml5.dom.getParentElement(document.querySelector(\"li\"), { nodeName: [\"MENU\", \"UL\", \"OL\"] });\n *    // ... or ...\n *    var unorderedListElement = wysihtml5.dom.getParentElement(document.querySelector(\"li\"), { nodeName: \"UL\" });\n *    // ... or ...\n *    var coloredElement = wysihtml5.dom.getParentElement(myTextNode, { nodeName: \"SPAN\", className: \"wysiwyg-color-red\", classRegExp: /wysiwyg-color-[a-z]/g });\n */\nwysihtml5.dom.getParentElement = (function() {\n\n  function _isSameNodeName(nodeName, desiredNodeNames) {\n    if (!desiredNodeNames || !desiredNodeNames.length) {\n      return true;\n    }\n\n    if (typeof(desiredNodeNames) === \"string\") {\n      return nodeName === desiredNodeNames;\n    } else {\n      return wysihtml5.lang.array(desiredNodeNames).contains(nodeName);\n    }\n  }\n\n  function _isElement(node) {\n    return node.nodeType === wysihtml5.ELEMENT_NODE;\n  }\n\n  function _hasClassName(element, className, classRegExp) {\n    var classNames = (element.className || \"\").match(classRegExp) || [];\n    if (!className) {\n      return !!classNames.length;\n    }\n    return classNames[classNames.length - 1] === className;\n  }\n\n  function _hasStyle(element, cssStyle, styleRegExp) {\n    var styles = (element.getAttribute('style') || \"\").match(styleRegExp) || [];\n    if (!cssStyle) {\n      return !!styles.length;\n    }\n    return styles[styles.length - 1] === cssStyle;\n  }\n\n  return function(node, matchingSet, levels, container) {\n    var findByStyle = (matchingSet.cssStyle || matchingSet.styleRegExp),\n        findByClass = (matchingSet.className || matchingSet.classRegExp);\n\n    levels = levels || 50; // Go max 50 nodes upwards from current node\n\n    while (levels-- && node && node.nodeName !== \"BODY\" && (!container || node !== container)) {\n      if (_isElement(node) && _isSameNodeName(node.nodeName, matchingSet.nodeName) &&\n          (!findByStyle || _hasStyle(node, matchingSet.cssStyle, matchingSet.styleRegExp)) &&\n          (!findByClass || _hasClassName(node, matchingSet.className, matchingSet.classRegExp))\n      ) {\n        return node;\n      }\n      node = node.parentNode;\n    }\n    return null;\n  };\n})();\n;/**\n * Get element's style for a specific css property\n *\n * @param {Element} element The element on which to retrieve the style\n * @param {String} property The CSS property to retrieve (\"float\", \"display\", \"text-align\", ...)\n *\n * @example\n *    wysihtml5.dom.getStyle(\"display\").from(document.body);\n *    // => \"block\"\n */\nwysihtml5.dom.getStyle = (function() {\n  var stylePropertyMapping = {\n        \"float\": (\"styleFloat\" in document.createElement(\"div\").style) ? \"styleFloat\" : \"cssFloat\"\n      },\n      REG_EXP_CAMELIZE = /\\-[a-z]/g;\n\n  function camelize(str) {\n    return str.replace(REG_EXP_CAMELIZE, function(match) {\n      return match.charAt(1).toUpperCase();\n    });\n  }\n\n  return function(property) {\n    return {\n      from: function(element) {\n        if (element.nodeType !== wysihtml5.ELEMENT_NODE) {\n          return;\n        }\n\n        var doc               = element.ownerDocument,\n            camelizedProperty = stylePropertyMapping[property] || camelize(property),\n            style             = element.style,\n            currentStyle      = element.currentStyle,\n            styleValue        = style[camelizedProperty];\n        if (styleValue) {\n          return styleValue;\n        }\n\n        // currentStyle is no standard and only supported by Opera and IE but it has one important advantage over the standard-compliant\n        // window.getComputedStyle, since it returns css property values in their original unit:\n        // If you set an elements width to \"50%\", window.getComputedStyle will give you it's current width in px while currentStyle\n        // gives you the original \"50%\".\n        // Opera supports both, currentStyle and window.getComputedStyle, that's why checking for currentStyle should have higher prio\n        if (currentStyle) {\n          try {\n            return currentStyle[camelizedProperty];\n          } catch(e) {\n            //ie will occasionally fail for unknown reasons. swallowing exception\n          }\n        }\n\n        var win                 = doc.defaultView || doc.parentWindow,\n            needsOverflowReset  = (property === \"height\" || property === \"width\") && element.nodeName === \"TEXTAREA\",\n            originalOverflow,\n            returnValue;\n\n        if (win.getComputedStyle) {\n          // Chrome and Safari both calculate a wrong width and height for textareas when they have scroll bars\n          // therfore we remove and restore the scrollbar and calculate the value in between\n          if (needsOverflowReset) {\n            originalOverflow = style.overflow;\n            style.overflow = \"hidden\";\n          }\n          returnValue = win.getComputedStyle(element, null).getPropertyValue(property);\n          if (needsOverflowReset) {\n            style.overflow = originalOverflow || \"\";\n          }\n          return returnValue;\n        }\n      }\n    };\n  };\n})();\n;wysihtml5.dom.getTextNodes = function(node, ingoreEmpty){\n  var all = [];\n  for (node=node.firstChild;node;node=node.nextSibling){\n    if (node.nodeType == 3) {\n      if (!ingoreEmpty || !(/^\\s*$/).test(node.innerText || node.textContent)) {\n        all.push(node);\n      }\n    } else {\n      all = all.concat(wysihtml5.dom.getTextNodes(node, ingoreEmpty));\n    }\n  }\n  return all;\n};;/**\n * High performant way to check whether an element with a specific tag name is in the given document\n * Optimized for being heavily executed\n * Unleashes the power of live node lists\n *\n * @param {Object} doc The document object of the context where to check\n * @param {String} tagName Upper cased tag name\n * @example\n *    wysihtml5.dom.hasElementWithTagName(document, \"IMG\");\n */\nwysihtml5.dom.hasElementWithTagName = (function() {\n  var LIVE_CACHE          = {},\n      DOCUMENT_IDENTIFIER = 1;\n\n  function _getDocumentIdentifier(doc) {\n    return doc._wysihtml5_identifier || (doc._wysihtml5_identifier = DOCUMENT_IDENTIFIER++);\n  }\n\n  return function(doc, tagName) {\n    var key         = _getDocumentIdentifier(doc) + \":\" + tagName,\n        cacheEntry  = LIVE_CACHE[key];\n    if (!cacheEntry) {\n      cacheEntry = LIVE_CACHE[key] = doc.getElementsByTagName(tagName);\n    }\n\n    return cacheEntry.length > 0;\n  };\n})();\n;/**\n * High performant way to check whether an element with a specific class name is in the given document\n * Optimized for being heavily executed\n * Unleashes the power of live node lists\n *\n * @param {Object} doc The document object of the context where to check\n * @param {String} tagName Upper cased tag name\n * @example\n *    wysihtml5.dom.hasElementWithClassName(document, \"foobar\");\n */\n(function(wysihtml5) {\n  var LIVE_CACHE          = {},\n      DOCUMENT_IDENTIFIER = 1;\n\n  function _getDocumentIdentifier(doc) {\n    return doc._wysihtml5_identifier || (doc._wysihtml5_identifier = DOCUMENT_IDENTIFIER++);\n  }\n\n  wysihtml5.dom.hasElementWithClassName = function(doc, className) {\n    // getElementsByClassName is not supported by IE<9\n    // but is sometimes mocked via library code (which then doesn't return live node lists)\n    if (!wysihtml5.browser.supportsNativeGetElementsByClassName()) {\n      return !!doc.querySelector(\".\" + className);\n    }\n\n    var key         = _getDocumentIdentifier(doc) + \":\" + className,\n        cacheEntry  = LIVE_CACHE[key];\n    if (!cacheEntry) {\n      cacheEntry = LIVE_CACHE[key] = doc.getElementsByClassName(className);\n    }\n\n    return cacheEntry.length > 0;\n  };\n})(wysihtml5);\n;wysihtml5.dom.insert = function(elementToInsert) {\n  return {\n    after: function(element) {\n      element.parentNode.insertBefore(elementToInsert, element.nextSibling);\n    },\n\n    before: function(element) {\n      element.parentNode.insertBefore(elementToInsert, element);\n    },\n\n    into: function(element) {\n      element.appendChild(elementToInsert);\n    }\n  };\n};\n;wysihtml5.dom.insertCSS = function(rules) {\n  rules = rules.join(\"\\n\");\n\n  return {\n    into: function(doc) {\n      var styleElement = doc.createElement(\"style\");\n      styleElement.type = \"text/css\";\n\n      if (styleElement.styleSheet) {\n        styleElement.styleSheet.cssText = rules;\n      } else {\n        styleElement.appendChild(doc.createTextNode(rules));\n      }\n\n      var link = doc.querySelector(\"head link\");\n      if (link) {\n        link.parentNode.insertBefore(styleElement, link);\n        return;\n      } else {\n        var head = doc.querySelector(\"head\");\n        if (head) {\n          head.appendChild(styleElement);\n        }\n      }\n    }\n  };\n};\n;// TODO: Refactor dom tree traversing here\n(function(wysihtml5) {\n  wysihtml5.dom.lineBreaks = function(node) {\n\n    function _isLineBreak(n) {\n      return n.nodeName === \"BR\";\n    }\n\n    /**\n     * Checks whether the elment causes a visual line break\n     * (<br> or block elements)\n     */\n    function _isLineBreakOrBlockElement(element) {\n      if (_isLineBreak(element)) {\n        return true;\n      }\n\n      if (wysihtml5.dom.getStyle(\"display\").from(element) === \"block\") {\n        return true;\n      }\n\n      return false;\n    }\n\n    return {\n\n      /* wysihtml5.dom.lineBreaks(element).add();\n       *\n       * Adds line breaks before and after the given node if the previous and next siblings\n       * aren't already causing a visual line break (block element or <br>)\n       */\n      add: function(options) {\n        var doc             = node.ownerDocument,\n          nextSibling     = wysihtml5.dom.domNode(node).next({ignoreBlankTexts: true}),\n          previousSibling = wysihtml5.dom.domNode(node).prev({ignoreBlankTexts: true});\n\n        if (nextSibling && !_isLineBreakOrBlockElement(nextSibling)) {\n          wysihtml5.dom.insert(doc.createElement(\"br\")).after(node);\n        }\n        if (previousSibling && !_isLineBreakOrBlockElement(previousSibling)) {\n          wysihtml5.dom.insert(doc.createElement(\"br\")).before(node);\n        }\n      },\n\n      /* wysihtml5.dom.lineBreaks(element).remove();\n       *\n       * Removes line breaks before and after the given node\n       */\n      remove: function(options) {\n        var nextSibling     = wysihtml5.dom.domNode(node).next({ignoreBlankTexts: true}),\n            previousSibling = wysihtml5.dom.domNode(node).prev({ignoreBlankTexts: true});\n\n        if (nextSibling && _isLineBreak(nextSibling)) {\n          nextSibling.parentNode.removeChild(nextSibling);\n        }\n        if (previousSibling && _isLineBreak(previousSibling)) {\n          previousSibling.parentNode.removeChild(previousSibling);\n        }\n      }\n    };\n  };\n})(wysihtml5);;/**\n * Method to set dom events\n *\n * @example\n *    wysihtml5.dom.observe(iframe.contentWindow.document.body, [\"focus\", \"blur\"], function() { ... });\n */\nwysihtml5.dom.observe = function(element, eventNames, handler) {\n  eventNames = typeof(eventNames) === \"string\" ? [eventNames] : eventNames;\n\n  var handlerWrapper,\n      eventName,\n      i       = 0,\n      length  = eventNames.length;\n\n  for (; i<length; i++) {\n    eventName = eventNames[i];\n    if (element.addEventListener) {\n      element.addEventListener(eventName, handler, false);\n    } else {\n      handlerWrapper = function(event) {\n        if (!(\"target\" in event)) {\n          event.target = event.srcElement;\n        }\n        event.preventDefault = event.preventDefault || function() {\n          this.returnValue = false;\n        };\n        event.stopPropagation = event.stopPropagation || function() {\n          this.cancelBubble = true;\n        };\n        handler.call(element, event);\n      };\n      element.attachEvent(\"on\" + eventName, handlerWrapper);\n    }\n  }\n\n  return {\n    stop: function() {\n      var eventName,\n          i       = 0,\n          length  = eventNames.length;\n      for (; i<length; i++) {\n        eventName = eventNames[i];\n        if (element.removeEventListener) {\n          element.removeEventListener(eventName, handler, false);\n        } else {\n          element.detachEvent(\"on\" + eventName, handlerWrapper);\n        }\n      }\n    }\n  };\n};\n;/**\n * HTML Sanitizer\n * Rewrites the HTML based on given rules\n *\n * @param {Element|String} elementOrHtml HTML String to be sanitized OR element whose content should be sanitized\n * @param {Object} [rules] List of rules for rewriting the HTML, if there's no rule for an element it will\n *    be converted to a \"span\". Each rule is a key/value pair where key is the tag to convert, and value the\n *    desired substitution.\n * @param {Object} context Document object in which to parse the html, needed to sandbox the parsing\n *\n * @return {Element|String} Depends on the elementOrHtml parameter. When html then the sanitized html as string elsewise the element.\n *\n * @example\n *    var userHTML = '<div id=\"foo\" onclick=\"alert(1);\"><p><font color=\"red\">foo</font><script>alert(1);</script></p></div>';\n *    wysihtml5.dom.parse(userHTML, {\n *      tags {\n *        p:      \"div\",      // Rename p tags to div tags\n *        font:   \"span\"      // Rename font tags to span tags\n *        div:    true,       // Keep them, also possible (same result when passing: \"div\" or true)\n *        script: undefined   // Remove script elements\n *      }\n *    });\n *    // => <div><div><span>foo bar</span></div></div>\n *\n *    var userHTML = '<table><tbody><tr><td>I'm a table!</td></tr></tbody></table>';\n *    wysihtml5.dom.parse(userHTML);\n *    // => '<span><span><span><span>I'm a table!</span></span></span></span>'\n *\n *    var userHTML = '<div>foobar<br>foobar</div>';\n *    wysihtml5.dom.parse(userHTML, {\n *      tags: {\n *        div: undefined,\n *        br:  true\n *      }\n *    });\n *    // => ''\n *\n *    var userHTML = '<div class=\"red\">foo</div><div class=\"pink\">bar</div>';\n *    wysihtml5.dom.parse(userHTML, {\n *      classes: {\n *        red:    1,\n *        green:  1\n *      },\n *      tags: {\n *        div: {\n *          rename_tag:     \"p\"\n *        }\n *      }\n *    });\n *    // => '<p class=\"red\">foo</p><p>bar</p>'\n */\n\nwysihtml5.dom.parse = function(elementOrHtml_current, config_current) {\n  /* TODO: Currently escaped module pattern as otherwise folloowing default swill be shared among multiple editors.\n   * Refactor whole code as this method while workind is kind of awkward too */\n\n  /**\n   * It's not possible to use a XMLParser/DOMParser as HTML5 is not always well-formed XML\n   * new DOMParser().parseFromString('<img src=\"foo.gif\">') will cause a parseError since the\n   * node isn't closed\n   *\n   * Therefore we've to use the browser's ordinary HTML parser invoked by setting innerHTML.\n   */\n  var NODE_TYPE_MAPPING = {\n        \"1\": _handleElement,\n        \"3\": _handleText,\n        \"8\": _handleComment\n      },\n      // Rename unknown tags to this\n      DEFAULT_NODE_NAME   = \"span\",\n      WHITE_SPACE_REG_EXP = /\\s+/,\n      defaultRules        = { tags: {}, classes: {} },\n      currentRules        = {};\n\n  /**\n   * Iterates over all childs of the element, recreates them, appends them into a document fragment\n   * which later replaces the entire body content\n   */\n   function parse(elementOrHtml, config) {\n    wysihtml5.lang.object(currentRules).merge(defaultRules).merge(config.rules).get();\n\n    var context       = config.context || elementOrHtml.ownerDocument || document,\n        fragment      = context.createDocumentFragment(),\n        isString      = typeof(elementOrHtml) === \"string\",\n        clearInternals = false,\n        element,\n        newNode,\n        firstChild;\n\n    if (config.clearInternals === true) {\n      clearInternals = true;\n    }\n\n    if (isString) {\n      element = wysihtml5.dom.getAsDom(elementOrHtml, context);\n    } else {\n      element = elementOrHtml;\n    }\n\n    if (currentRules.selectors) {\n      _applySelectorRules(element, currentRules.selectors);\n    }\n\n    while (element.firstChild) {\n      firstChild = element.firstChild;\n      newNode = _convert(firstChild, config.cleanUp, clearInternals, config.uneditableClass);\n      if (newNode) {\n        fragment.appendChild(newNode);\n      }\n      if (firstChild !== newNode) {\n        element.removeChild(firstChild);\n      }\n    }\n\n    if (config.unjoinNbsps) {\n      // replace joined non-breakable spaces with unjoined\n      var txtnodes = wysihtml5.dom.getTextNodes(fragment);\n      for (var n = txtnodes.length; n--;) {\n        txtnodes[n].nodeValue = txtnodes[n].nodeValue.replace(/([\\S\\u00A0])\\u00A0/gi, \"$1 \");\n      }\n    }\n\n    // Clear element contents\n    element.innerHTML = \"\";\n\n    // Insert new DOM tree\n    element.appendChild(fragment);\n\n    return isString ? wysihtml5.quirks.getCorrectInnerHTML(element) : element;\n  }\n\n  function _convert(oldNode, cleanUp, clearInternals, uneditableClass) {\n    var oldNodeType     = oldNode.nodeType,\n        oldChilds       = oldNode.childNodes,\n        oldChildsLength = oldChilds.length,\n        method          = NODE_TYPE_MAPPING[oldNodeType],\n        i               = 0,\n        fragment,\n        newNode,\n        newChild;\n\n    // Passes directly elemets with uneditable class\n    if (uneditableClass && oldNodeType === 1 && wysihtml5.dom.hasClass(oldNode, uneditableClass)) {\n        return oldNode;\n    }\n\n    newNode = method && method(oldNode, clearInternals);\n\n    // Remove or unwrap node in case of return value null or false\n    if (!newNode) {\n        if (newNode === false) {\n            // false defines that tag should be removed but contents should remain (unwrap)\n            fragment = oldNode.ownerDocument.createDocumentFragment();\n\n            for (i = oldChildsLength; i--;) {\n              if (oldChilds[i]) {\n                newChild = _convert(oldChilds[i], cleanUp, clearInternals, uneditableClass);\n                if (newChild) {\n                  if (oldChilds[i] === newChild) {\n                    i--;\n                  }\n                  fragment.insertBefore(newChild, fragment.firstChild);\n                }\n              }\n            }\n\n            if (wysihtml5.dom.getStyle(\"display\").from(oldNode) === \"block\") {\n              fragment.appendChild(oldNode.ownerDocument.createElement(\"br\"));\n            }\n\n            // TODO: try to minimize surplus spaces\n            if (wysihtml5.lang.array([\n                \"div\", \"pre\", \"p\",\n                \"table\", \"td\", \"th\",\n                \"ul\", \"ol\", \"li\",\n                \"dd\", \"dl\",\n                \"footer\", \"header\", \"section\",\n                \"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\"\n            ]).contains(oldNode.nodeName.toLowerCase()) && oldNode.parentNode.lastChild !== oldNode) {\n                // add space at first when unwraping non-textflow elements\n                if (!oldNode.nextSibling || oldNode.nextSibling.nodeType !== 3 || !(/^\\s/).test(oldNode.nextSibling.nodeValue)) {\n                  fragment.appendChild(oldNode.ownerDocument.createTextNode(\" \"));\n                }\n            }\n\n            if (fragment.normalize) {\n              fragment.normalize();\n            }\n            return fragment;\n        } else {\n          // Remove\n          return null;\n        }\n    }\n\n    // Converts all childnodes\n    for (i=0; i<oldChildsLength; i++) {\n      if (oldChilds[i]) {\n        newChild = _convert(oldChilds[i], cleanUp, clearInternals, uneditableClass);\n        if (newChild) {\n          if (oldChilds[i] === newChild) {\n            i--;\n          }\n          newNode.appendChild(newChild);\n        }\n      }\n    }\n\n    // Cleanup senseless <span> elements\n    if (cleanUp &&\n        newNode.nodeName.toLowerCase() === DEFAULT_NODE_NAME &&\n        (!newNode.childNodes.length ||\n         ((/^\\s*$/gi).test(newNode.innerHTML) && (clearInternals || (oldNode.className !== \"_wysihtml5-temp-placeholder\" && oldNode.className !== \"rangySelectionBoundary\"))) ||\n         !newNode.attributes.length)\n        ) {\n      fragment = newNode.ownerDocument.createDocumentFragment();\n      while (newNode.firstChild) {\n        fragment.appendChild(newNode.firstChild);\n      }\n      if (fragment.normalize) {\n        fragment.normalize();\n      }\n      return fragment;\n    }\n\n    if (newNode.normalize) {\n      newNode.normalize();\n    }\n    return newNode;\n  }\n\n  function _applySelectorRules (element, selectorRules) {\n    var sel, method, els;\n\n    for (sel in selectorRules) {\n      if (selectorRules.hasOwnProperty(sel)) {\n        if (wysihtml5.lang.object(selectorRules[sel]).isFunction()) {\n          method = selectorRules[sel];\n        } else if (typeof(selectorRules[sel]) === \"string\" && elementHandlingMethods[selectorRules[sel]]) {\n          method = elementHandlingMethods[selectorRules[sel]];\n        }\n        els = element.querySelectorAll(sel);\n        for (var i = els.length; i--;) {\n          method(els[i]);\n        }\n      }\n    }\n  }\n\n  function _handleElement(oldNode, clearInternals) {\n    var rule,\n        newNode,\n        tagRules    = currentRules.tags,\n        nodeName    = oldNode.nodeName.toLowerCase(),\n        scopeName   = oldNode.scopeName,\n        renameTag;\n\n    /**\n     * We already parsed that element\n     * ignore it! (yes, this sometimes happens in IE8 when the html is invalid)\n     */\n    if (oldNode._wysihtml5) {\n      return null;\n    }\n    oldNode._wysihtml5 = 1;\n\n    if (oldNode.className === \"wysihtml5-temp\") {\n      return null;\n    }\n\n    /**\n     * IE is the only browser who doesn't include the namespace in the\n     * nodeName, that's why we have to prepend it by ourselves\n     * scopeName is a proprietary IE feature\n     * read more here http://msdn.microsoft.com/en-us/library/ms534388(v=vs.85).aspx\n     */\n    if (scopeName && scopeName != \"HTML\") {\n      nodeName = scopeName + \":\" + nodeName;\n    }\n    /**\n     * Repair node\n     * IE is a bit bitchy when it comes to invalid nested markup which includes unclosed tags\n     * A <p> doesn't need to be closed according HTML4-5 spec, we simply replace it with a <div> to preserve its content and layout\n     */\n    if (\"outerHTML\" in oldNode) {\n      if (!wysihtml5.browser.autoClosesUnclosedTags() &&\n          oldNode.nodeName === \"P\" &&\n          oldNode.outerHTML.slice(-4).toLowerCase() !== \"</p>\") {\n        nodeName = \"div\";\n      }\n    }\n\n    if (nodeName in tagRules) {\n      rule = tagRules[nodeName];\n      if (!rule || rule.remove) {\n        return null;\n      } else if (rule.unwrap) {\n        return false;\n      }\n      rule = typeof(rule) === \"string\" ? { rename_tag: rule } : rule;\n    } else if (oldNode.firstChild) {\n      rule = { rename_tag: DEFAULT_NODE_NAME };\n    } else {\n      // Remove empty unknown elements\n      return null;\n    }\n\n    // tests if type condition is met or node should be removed/unwrapped/renamed\n    if (rule.one_of_type && !_testTypes(oldNode, currentRules, rule.one_of_type, clearInternals)) {\n      if (rule.remove_action) {\n        if (rule.remove_action === \"unwrap\") {\n          return false;\n        } else if (rule.remove_action === \"rename\") {\n          renameTag = rule.remove_action_rename_to || DEFAULT_NODE_NAME;\n        } else {\n          return null;\n        }\n      } else {\n        return null;\n      }\n    }\n\n    newNode = oldNode.ownerDocument.createElement(renameTag || rule.rename_tag || nodeName);\n    _handleAttributes(oldNode, newNode, rule, clearInternals);\n    _handleStyles(oldNode, newNode, rule);\n\n    oldNode = null;\n\n    if (newNode.normalize) { newNode.normalize(); }\n    return newNode;\n  }\n\n  function _testTypes(oldNode, rules, types, clearInternals) {\n    var definition, type;\n\n    // do not interfere with placeholder span or pasting caret position is not maintained\n    if (oldNode.nodeName === \"SPAN\" && !clearInternals && (oldNode.className === \"_wysihtml5-temp-placeholder\" || oldNode.className === \"rangySelectionBoundary\")) {\n      return true;\n    }\n\n    for (type in types) {\n      if (types.hasOwnProperty(type) && rules.type_definitions && rules.type_definitions[type]) {\n        definition = rules.type_definitions[type];\n        if (_testType(oldNode, definition)) {\n          return true;\n        }\n      }\n    }\n    return false;\n  }\n\n  function array_contains(a, obj) {\n      var i = a.length;\n      while (i--) {\n         if (a[i] === obj) {\n             return true;\n         }\n      }\n      return false;\n  }\n\n  function _testType(oldNode, definition) {\n\n    var nodeClasses = oldNode.getAttribute(\"class\"),\n        nodeStyles =  oldNode.getAttribute(\"style\"),\n        classesLength, s, s_corrected, a, attr, currentClass, styleProp;\n\n    // test for methods\n    if (definition.methods) {\n      for (var m in definition.methods) {\n        if (definition.methods.hasOwnProperty(m) && typeCeckMethods[m]) {\n\n          if (typeCeckMethods[m](oldNode)) {\n            return true;\n          }\n        }\n      }\n    }\n\n    // test for classes, if one found return true\n    if (nodeClasses && definition.classes) {\n      nodeClasses = nodeClasses.replace(/^\\s+/g, '').replace(/\\s+$/g, '').split(WHITE_SPACE_REG_EXP);\n      classesLength = nodeClasses.length;\n      for (var i = 0; i < classesLength; i++) {\n        if (definition.classes[nodeClasses[i]]) {\n          return true;\n        }\n      }\n    }\n\n    // test for styles, if one found return true\n    if (nodeStyles && definition.styles) {\n\n      nodeStyles = nodeStyles.split(';');\n      for (s in definition.styles) {\n        if (definition.styles.hasOwnProperty(s)) {\n          for (var sp = nodeStyles.length; sp--;) {\n            styleProp = nodeStyles[sp].split(':');\n\n            if (styleProp[0].replace(/\\s/g, '').toLowerCase() === s) {\n              if (definition.styles[s] === true || definition.styles[s] === 1 || wysihtml5.lang.array(definition.styles[s]).contains(styleProp[1].replace(/\\s/g, '').toLowerCase()) ) {\n                return true;\n              }\n            }\n          }\n        }\n      }\n    }\n\n    // test for attributes in general against regex match\n    if (definition.attrs) {\n        for (a in definition.attrs) {\n            if (definition.attrs.hasOwnProperty(a)) {\n                attr = wysihtml5.dom.getAttribute(oldNode, a);\n                if (typeof(attr) === \"string\") {\n                    if (attr.search(definition.attrs[a]) > -1) {\n                        return true;\n                    }\n                }\n            }\n        }\n    }\n    return false;\n  }\n\n  function _handleStyles(oldNode, newNode, rule) {\n    var s, v;\n    if(rule && rule.keep_styles) {\n      for (s in rule.keep_styles) {\n        if (rule.keep_styles.hasOwnProperty(s)) {\n          v = (s === \"float\") ? oldNode.style.styleFloat || oldNode.style.cssFloat : oldNode.style[s];\n          // value can be regex and if so should match or style skipped\n          if (rule.keep_styles[s] instanceof RegExp && !(rule.keep_styles[s].test(v))) {\n            continue;\n          }\n          if (s === \"float\") {\n            // IE compability\n            newNode.style[(oldNode.style.styleFloat) ? 'styleFloat': 'cssFloat'] = v;\n           } else if (oldNode.style[s]) {\n             newNode.style[s] = v;\n           }\n        }\n      }\n    }\n  };\n\n  function _getAttributesBeginningWith(beginning, attributes) {\n    var returnAttributes = [];\n    for (var attr in attributes) {\n      if (attributes.hasOwnProperty(attr) && attr.indexOf(beginning) === 0) {\n        returnAttributes.push(attr);\n      }\n    }\n    return returnAttributes;\n  }\n\n  function _checkAttribute(attributeName, attributeValue, methodName, nodeName) {\n    var method = attributeCheckMethods[methodName],\n        newAttributeValue;\n\n    if (method) {\n      if (attributeValue || (attributeName === \"alt\" && nodeName == \"IMG\")) {\n        newAttributeValue = method(attributeValue);\n        if (typeof(newAttributeValue) === \"string\") {\n          return newAttributeValue;\n        }\n      }\n    }\n\n    return false;\n  }\n\n  function _checkAttributes(oldNode, local_attributes) {\n    var globalAttributes  = wysihtml5.lang.object(currentRules.attributes || {}).clone(), // global values for check/convert values of attributes\n        checkAttributes   = wysihtml5.lang.object(globalAttributes).merge( wysihtml5.lang.object(local_attributes || {}).clone()).get(),\n        attributes        = {},\n        oldAttributes     = wysihtml5.dom.getAttributes(oldNode),\n        attributeName, newValue, matchingAttributes;\n\n    for (attributeName in checkAttributes) {\n      if ((/\\*$/).test(attributeName)) {\n\n        matchingAttributes = _getAttributesBeginningWith(attributeName.slice(0,-1), oldAttributes);\n        for (var i = 0, imax = matchingAttributes.length; i < imax; i++) {\n\n          newValue = _checkAttribute(matchingAttributes[i], oldAttributes[matchingAttributes[i]], checkAttributes[attributeName], oldNode.nodeName);\n          if (newValue !== false) {\n            attributes[matchingAttributes[i]] = newValue;\n          }\n        }\n      } else {\n        newValue = _checkAttribute(attributeName, oldAttributes[attributeName], checkAttributes[attributeName], oldNode.nodeName);\n        if (newValue !== false) {\n          attributes[attributeName] = newValue;\n        }\n      }\n    }\n\n    return attributes;\n  }\n\n  // TODO: refactor. Too long to read\n  function _handleAttributes(oldNode, newNode, rule, clearInternals) {\n    var attributes          = {},                         // fresh new set of attributes to set on newNode\n        setClass            = rule.set_class,             // classes to set\n        addClass            = rule.add_class,             // add classes based on existing attributes\n        addStyle            = rule.add_style,             // add styles based on existing attributes\n        setAttributes       = rule.set_attributes,        // attributes to set on the current node\n        allowedClasses      = currentRules.classes,\n        i                   = 0,\n        classes             = [],\n        styles              = [],\n        newClasses          = [],\n        oldClasses          = [],\n        classesLength,\n        newClassesLength,\n        currentClass,\n        newClass,\n        attributeName,\n        method;\n\n    if (setAttributes) {\n      attributes = wysihtml5.lang.object(setAttributes).clone();\n    }\n\n    // check/convert values of attributes\n    attributes = wysihtml5.lang.object(attributes).merge(_checkAttributes(oldNode,  rule.check_attributes)).get();\n\n    if (setClass) {\n      classes.push(setClass);\n    }\n\n    if (addClass) {\n      for (attributeName in addClass) {\n        method = addClassMethods[addClass[attributeName]];\n        if (!method) {\n          continue;\n        }\n        newClass = method(wysihtml5.dom.getAttribute(oldNode, attributeName));\n        if (typeof(newClass) === \"string\") {\n          classes.push(newClass);\n        }\n      }\n    }\n\n    if (addStyle) {\n      for (attributeName in addStyle) {\n        method = addStyleMethods[addStyle[attributeName]];\n        if (!method) {\n          continue;\n        }\n\n        newStyle = method(wysihtml5.dom.getAttribute(oldNode, attributeName));\n        if (typeof(newStyle) === \"string\") {\n          styles.push(newStyle);\n        }\n      }\n    }\n\n\n    if (typeof(allowedClasses) === \"string\" && allowedClasses === \"any\" && oldNode.getAttribute(\"class\")) {\n      if (currentRules.classes_blacklist) {\n        oldClasses = oldNode.getAttribute(\"class\");\n        if (oldClasses) {\n          classes = classes.concat(oldClasses.split(WHITE_SPACE_REG_EXP));\n        }\n\n        classesLength = classes.length;\n        for (; i<classesLength; i++) {\n          currentClass = classes[i];\n          if (!currentRules.classes_blacklist[currentClass]) {\n            newClasses.push(currentClass);\n          }\n        }\n\n        if (newClasses.length) {\n          attributes[\"class\"] = wysihtml5.lang.array(newClasses).unique().join(\" \");\n        }\n\n      } else {\n        attributes[\"class\"] = oldNode.getAttribute(\"class\");\n      }\n    } else {\n      // make sure that wysihtml5 temp class doesn't get stripped out\n      if (!clearInternals) {\n        allowedClasses[\"_wysihtml5-temp-placeholder\"] = 1;\n        allowedClasses[\"_rangySelectionBoundary\"] = 1;\n        allowedClasses[\"wysiwyg-tmp-selected-cell\"] = 1;\n      }\n\n      // add old classes last\n      oldClasses = oldNode.getAttribute(\"class\");\n      if (oldClasses) {\n        classes = classes.concat(oldClasses.split(WHITE_SPACE_REG_EXP));\n      }\n      classesLength = classes.length;\n      for (; i<classesLength; i++) {\n        currentClass = classes[i];\n        if (allowedClasses[currentClass]) {\n          newClasses.push(currentClass);\n        }\n      }\n\n      if (newClasses.length) {\n        attributes[\"class\"] = wysihtml5.lang.array(newClasses).unique().join(\" \");\n      }\n    }\n\n    // remove table selection class if present\n    if (attributes[\"class\"] && clearInternals) {\n      attributes[\"class\"] = attributes[\"class\"].replace(\"wysiwyg-tmp-selected-cell\", \"\");\n      if ((/^\\s*$/g).test(attributes[\"class\"])) {\n        delete attributes[\"class\"];\n      }\n    }\n\n    if (styles.length) {\n      attributes[\"style\"] = wysihtml5.lang.array(styles).unique().join(\" \");\n    }\n\n    // set attributes on newNode\n    for (attributeName in attributes) {\n      // Setting attributes can cause a js error in IE under certain circumstances\n      // eg. on a <img> under https when it's new attribute value is non-https\n      // TODO: Investigate this further and check for smarter handling\n      try {\n        newNode.setAttribute(attributeName, attributes[attributeName]);\n      } catch(e) {}\n    }\n\n    // IE8 sometimes loses the width/height attributes when those are set before the \"src\"\n    // so we make sure to set them again\n    if (attributes.src) {\n      if (typeof(attributes.width) !== \"undefined\") {\n        newNode.setAttribute(\"width\", attributes.width);\n      }\n      if (typeof(attributes.height) !== \"undefined\") {\n        newNode.setAttribute(\"height\", attributes.height);\n      }\n    }\n  }\n\n  var INVISIBLE_SPACE_REG_EXP = /\\uFEFF/g;\n  function _handleText(oldNode) {\n    var nextSibling = oldNode.nextSibling;\n    if (nextSibling && nextSibling.nodeType === wysihtml5.TEXT_NODE) {\n      // Concatenate text nodes\n      nextSibling.data = oldNode.data.replace(INVISIBLE_SPACE_REG_EXP, \"\") + nextSibling.data.replace(INVISIBLE_SPACE_REG_EXP, \"\");\n    } else {\n      // \\uFEFF = wysihtml5.INVISIBLE_SPACE (used as a hack in certain rich text editing situations)\n      var data = oldNode.data.replace(INVISIBLE_SPACE_REG_EXP, \"\");\n      return oldNode.ownerDocument.createTextNode(data);\n    }\n  }\n\n  function _handleComment(oldNode) {\n    if (currentRules.comments) {\n      return oldNode.ownerDocument.createComment(oldNode.nodeValue);\n    }\n  }\n\n  // ------------ attribute checks ------------ \\\\\n  var attributeCheckMethods = {\n    url: (function() {\n      var REG_EXP = /^https?:\\/\\//i;\n      return function(attributeValue) {\n        if (!attributeValue || !attributeValue.match(REG_EXP)) {\n          return null;\n        }\n        return attributeValue.replace(REG_EXP, function(match) {\n          return match.toLowerCase();\n        });\n      };\n    })(),\n\n    src: (function() {\n      var REG_EXP = /^(\\/|https?:\\/\\/)/i;\n      return function(attributeValue) {\n        if (!attributeValue || !attributeValue.match(REG_EXP)) {\n          return null;\n        }\n        return attributeValue.replace(REG_EXP, function(match) {\n          return match.toLowerCase();\n        });\n      };\n    })(),\n\n    href: (function() {\n      var REG_EXP = /^(#|\\/|https?:\\/\\/|mailto:)/i;\n      return function(attributeValue) {\n        if (!attributeValue || !attributeValue.match(REG_EXP)) {\n          return null;\n        }\n        return attributeValue.replace(REG_EXP, function(match) {\n          return match.toLowerCase();\n        });\n      };\n    })(),\n\n    alt: (function() {\n      var REG_EXP = /[^ a-z0-9_\\-]/gi;\n      return function(attributeValue) {\n        if (!attributeValue) {\n          return \"\";\n        }\n        return attributeValue.replace(REG_EXP, \"\");\n      };\n    })(),\n\n    numbers: (function() {\n      var REG_EXP = /\\D/g;\n      return function(attributeValue) {\n        attributeValue = (attributeValue || \"\").replace(REG_EXP, \"\");\n        return attributeValue || null;\n      };\n    })(),\n\n    any: (function() {\n      return function(attributeValue) {\n        return attributeValue;\n      };\n    })()\n  };\n\n  // ------------ style converter (converts an html attribute to a style) ------------ \\\\\n  var addStyleMethods = {\n    align_text: (function() {\n      var mapping = {\n        left:     \"text-align: left;\",\n        right:    \"text-align: right;\",\n        center:   \"text-align: center;\"\n      };\n      return function(attributeValue) {\n        return mapping[String(attributeValue).toLowerCase()];\n      };\n    })(),\n  };\n\n  // ------------ class converter (converts an html attribute to a class name) ------------ \\\\\n  var addClassMethods = {\n    align_img: (function() {\n      var mapping = {\n        left:   \"wysiwyg-float-left\",\n        right:  \"wysiwyg-float-right\"\n      };\n      return function(attributeValue) {\n        return mapping[String(attributeValue).toLowerCase()];\n      };\n    })(),\n\n    align_text: (function() {\n      var mapping = {\n        left:     \"wysiwyg-text-align-left\",\n        right:    \"wysiwyg-text-align-right\",\n        center:   \"wysiwyg-text-align-center\",\n        justify:  \"wysiwyg-text-align-justify\"\n      };\n      return function(attributeValue) {\n        return mapping[String(attributeValue).toLowerCase()];\n      };\n    })(),\n\n    clear_br: (function() {\n      var mapping = {\n        left:   \"wysiwyg-clear-left\",\n        right:  \"wysiwyg-clear-right\",\n        both:   \"wysiwyg-clear-both\",\n        all:    \"wysiwyg-clear-both\"\n      };\n      return function(attributeValue) {\n        return mapping[String(attributeValue).toLowerCase()];\n      };\n    })(),\n\n    size_font: (function() {\n      var mapping = {\n        \"1\": \"wysiwyg-font-size-xx-small\",\n        \"2\": \"wysiwyg-font-size-small\",\n        \"3\": \"wysiwyg-font-size-medium\",\n        \"4\": \"wysiwyg-font-size-large\",\n        \"5\": \"wysiwyg-font-size-x-large\",\n        \"6\": \"wysiwyg-font-size-xx-large\",\n        \"7\": \"wysiwyg-font-size-xx-large\",\n        \"-\": \"wysiwyg-font-size-smaller\",\n        \"+\": \"wysiwyg-font-size-larger\"\n      };\n      return function(attributeValue) {\n        return mapping[String(attributeValue).charAt(0)];\n      };\n    })()\n  };\n\n  // checks if element is possibly visible\n  var typeCeckMethods = {\n    has_visible_contet: (function() {\n      var txt,\n          isVisible = false,\n          visibleElements = ['img', 'video', 'picture', 'br', 'script', 'noscript',\n                             'style', 'table', 'iframe', 'object', 'embed', 'audio',\n                             'svg', 'input', 'button', 'select','textarea', 'canvas'];\n\n      return function(el) {\n\n        // has visible innertext. so is visible\n        txt = (el.innerText || el.textContent).replace(/\\s/g, '');\n        if (txt && txt.length > 0) {\n          return true;\n        }\n\n        // matches list of visible dimensioned elements\n        for (var i = visibleElements.length; i--;) {\n          if (el.querySelector(visibleElements[i])) {\n            return true;\n          }\n        }\n\n        // try to measure dimesions in last resort. (can find only of elements in dom)\n        if (el.offsetWidth && el.offsetWidth > 0 && el.offsetHeight && el.offsetHeight > 0) {\n          return true;\n        }\n\n        return false;\n      };\n    })()\n  };\n\n  var elementHandlingMethods = {\n    unwrap: function (element) {\n      wysihtml5.dom.unwrap(element);\n    },\n\n    remove: function (element) {\n      element.parentNode.removeChild(element);\n    }\n  };\n\n  return parse(elementOrHtml_current, config_current);\n};\n;/**\n * Checks for empty text node childs and removes them\n *\n * @param {Element} node The element in which to cleanup\n * @example\n *    wysihtml5.dom.removeEmptyTextNodes(element);\n */\nwysihtml5.dom.removeEmptyTextNodes = function(node) {\n  var childNode,\n      childNodes        = wysihtml5.lang.array(node.childNodes).get(),\n      childNodesLength  = childNodes.length,\n      i                 = 0;\n  for (; i<childNodesLength; i++) {\n    childNode = childNodes[i];\n    if (childNode.nodeType === wysihtml5.TEXT_NODE && childNode.data === \"\") {\n      childNode.parentNode.removeChild(childNode);\n    }\n  }\n};\n;/**\n * Renames an element (eg. a <div> to a <p>) and keeps its childs\n *\n * @param {Element} element The list element which should be renamed\n * @param {Element} newNodeName The desired tag name\n *\n * @example\n *    <!-- Assume the following dom: -->\n *    <ul id=\"list\">\n *      <li>eminem</li>\n *      <li>dr. dre</li>\n *      <li>50 Cent</li>\n *    </ul>\n *\n *    <script>\n *      wysihtml5.dom.renameElement(document.getElementById(\"list\"), \"ol\");\n *    </script>\n *\n *    <!-- Will result in: -->\n *    <ol>\n *      <li>eminem</li>\n *      <li>dr. dre</li>\n *      <li>50 Cent</li>\n *    </ol>\n */\nwysihtml5.dom.renameElement = function(element, newNodeName) {\n  var newElement = element.ownerDocument.createElement(newNodeName),\n      firstChild;\n  while (firstChild = element.firstChild) {\n    newElement.appendChild(firstChild);\n  }\n  wysihtml5.dom.copyAttributes([\"align\", \"className\"]).from(element).to(newElement);\n  element.parentNode.replaceChild(newElement, element);\n  return newElement;\n};\n;/**\n * Takes an element, removes it and replaces it with it's childs\n *\n * @param {Object} node The node which to replace with it's child nodes\n * @example\n *    <div id=\"foo\">\n *      <span>hello</span>\n *    </div>\n *    <script>\n *      // Remove #foo and replace with it's children\n *      wysihtml5.dom.replaceWithChildNodes(document.getElementById(\"foo\"));\n *    </script>\n */\nwysihtml5.dom.replaceWithChildNodes = function(node) {\n  if (!node.parentNode) {\n    return;\n  }\n\n  if (!node.firstChild) {\n    node.parentNode.removeChild(node);\n    return;\n  }\n\n  var fragment = node.ownerDocument.createDocumentFragment();\n  while (node.firstChild) {\n    fragment.appendChild(node.firstChild);\n  }\n  node.parentNode.replaceChild(fragment, node);\n  node = fragment = null;\n};\n;/**\n * Unwraps an unordered/ordered list\n *\n * @param {Element} element The list element which should be unwrapped\n *\n * @example\n *    <!-- Assume the following dom: -->\n *    <ul id=\"list\">\n *      <li>eminem</li>\n *      <li>dr. dre</li>\n *      <li>50 Cent</li>\n *    </ul>\n *\n *    <script>\n *      wysihtml5.dom.resolveList(document.getElementById(\"list\"));\n *    </script>\n *\n *    <!-- Will result in: -->\n *    eminem<br>\n *    dr. dre<br>\n *    50 Cent<br>\n */\n(function(dom) {\n  function _isBlockElement(node) {\n    return dom.getStyle(\"display\").from(node) === \"block\";\n  }\n\n  function _isLineBreak(node) {\n    return node.nodeName === \"BR\";\n  }\n\n  function _appendLineBreak(element) {\n    var lineBreak = element.ownerDocument.createElement(\"br\");\n    element.appendChild(lineBreak);\n  }\n\n  function resolveList(list, useLineBreaks) {\n    if (!list.nodeName.match(/^(MENU|UL|OL)$/)) {\n      return;\n    }\n\n    var doc             = list.ownerDocument,\n        fragment        = doc.createDocumentFragment(),\n        previousSibling = wysihtml5.dom.domNode(list).prev({ignoreBlankTexts: true}),\n        firstChild,\n        lastChild,\n        isLastChild,\n        shouldAppendLineBreak,\n        paragraph,\n        listItem;\n\n    if (useLineBreaks) {\n      // Insert line break if list is after a non-block element\n      if (previousSibling && !_isBlockElement(previousSibling) && !_isLineBreak(previousSibling)) {\n        _appendLineBreak(fragment);\n      }\n\n      while (listItem = (list.firstElementChild || list.firstChild)) {\n        lastChild = listItem.lastChild;\n        while (firstChild = listItem.firstChild) {\n          isLastChild           = firstChild === lastChild;\n          // This needs to be done before appending it to the fragment, as it otherwise will lose style information\n          shouldAppendLineBreak = isLastChild && !_isBlockElement(firstChild) && !_isLineBreak(firstChild);\n          fragment.appendChild(firstChild);\n          if (shouldAppendLineBreak) {\n            _appendLineBreak(fragment);\n          }\n        }\n\n        listItem.parentNode.removeChild(listItem);\n      }\n    } else {\n      while (listItem = (list.firstElementChild || list.firstChild)) {\n        if (listItem.querySelector && listItem.querySelector(\"div, p, ul, ol, menu, blockquote, h1, h2, h3, h4, h5, h6\")) {\n          while (firstChild = listItem.firstChild) {\n            fragment.appendChild(firstChild);\n          }\n        } else {\n          paragraph = doc.createElement(\"p\");\n          while (firstChild = listItem.firstChild) {\n            paragraph.appendChild(firstChild);\n          }\n          fragment.appendChild(paragraph);\n        }\n        listItem.parentNode.removeChild(listItem);\n      }\n    }\n\n    list.parentNode.replaceChild(fragment, list);\n  }\n\n  dom.resolveList = resolveList;\n})(wysihtml5.dom);\n;/**\n * Sandbox for executing javascript, parsing css styles and doing dom operations in a secure way\n *\n * Browser Compatibility:\n *  - Secure in MSIE 6+, but only when the user hasn't made changes to his security level \"restricted\"\n *  - Partially secure in other browsers (Firefox, Opera, Safari, Chrome, ...)\n *\n * Please note that this class can't benefit from the HTML5 sandbox attribute for the following reasons:\n *    - sandboxing doesn't work correctly with inlined content (src=\"javascript:'<html>...</html>'\")\n *    - sandboxing of physical documents causes that the dom isn't accessible anymore from the outside (iframe.contentWindow, ...)\n *    - setting the \"allow-same-origin\" flag would fix that, but then still javascript and dom events refuse to fire\n *    - therefore the \"allow-scripts\" flag is needed, which then would deactivate any security, as the js executed inside the iframe\n *      can do anything as if the sandbox attribute wasn't set\n *\n * @param {Function} [readyCallback] Method that gets invoked when the sandbox is ready\n * @param {Object} [config] Optional parameters\n *\n * @example\n *    new wysihtml5.dom.Sandbox(function(sandbox) {\n *      sandbox.getWindow().document.body.innerHTML = '<img src=foo.gif onerror=\"alert(document.cookie)\">';\n *    });\n */\n(function(wysihtml5) {\n  var /**\n       * Default configuration\n       */\n      doc                 = document,\n      /**\n       * Properties to unset/protect on the window object\n       */\n      windowProperties    = [\n        \"parent\", \"top\", \"opener\", \"frameElement\", \"frames\",\n        \"localStorage\", \"globalStorage\", \"sessionStorage\", \"indexedDB\"\n      ],\n      /**\n       * Properties on the window object which are set to an empty function\n       */\n      windowProperties2   = [\n        \"open\", \"close\", \"openDialog\", \"showModalDialog\",\n        \"alert\", \"confirm\", \"prompt\",\n        \"openDatabase\", \"postMessage\",\n        \"XMLHttpRequest\", \"XDomainRequest\"\n      ],\n      /**\n       * Properties to unset/protect on the document object\n       */\n      documentProperties  = [\n        \"referrer\",\n        \"write\", \"open\", \"close\"\n      ];\n\n  wysihtml5.dom.Sandbox = Base.extend(\n    /** @scope wysihtml5.dom.Sandbox.prototype */ {\n\n    constructor: function(readyCallback, config) {\n      this.callback = readyCallback || wysihtml5.EMPTY_FUNCTION;\n      this.config   = wysihtml5.lang.object({}).merge(config).get();\n      this.editableArea   = this._createIframe();\n    },\n\n    insertInto: function(element) {\n      if (typeof(element) === \"string\") {\n        element = doc.getElementById(element);\n      }\n\n      element.appendChild(this.editableArea);\n    },\n\n    getIframe: function() {\n      return this.editableArea;\n    },\n\n    getWindow: function() {\n      this._readyError();\n    },\n\n    getDocument: function() {\n      this._readyError();\n    },\n\n    destroy: function() {\n      var iframe = this.getIframe();\n      iframe.parentNode.removeChild(iframe);\n    },\n\n    _readyError: function() {\n      throw new Error(\"wysihtml5.Sandbox: Sandbox iframe isn't loaded yet\");\n    },\n\n    /**\n     * Creates the sandbox iframe\n     *\n     * Some important notes:\n     *  - We can't use HTML5 sandbox for now:\n     *    setting it causes that the iframe's dom can't be accessed from the outside\n     *    Therefore we need to set the \"allow-same-origin\" flag which enables accessing the iframe's dom\n     *    But then there's another problem, DOM events (focus, blur, change, keypress, ...) aren't fired.\n     *    In order to make this happen we need to set the \"allow-scripts\" flag.\n     *    A combination of allow-scripts and allow-same-origin is almost the same as setting no sandbox attribute at all.\n     *  - Chrome & Safari, doesn't seem to support sandboxing correctly when the iframe's html is inlined (no physical document)\n     *  - IE needs to have the security=\"restricted\" attribute set before the iframe is\n     *    inserted into the dom tree\n     *  - Believe it or not but in IE \"security\" in document.createElement(\"iframe\") is false, even\n     *    though it supports it\n     *  - When an iframe has security=\"restricted\", in IE eval() & execScript() don't work anymore\n     *  - IE doesn't fire the onload event when the content is inlined in the src attribute, therefore we rely\n     *    on the onreadystatechange event\n     */\n    _createIframe: function() {\n      var that   = this,\n          iframe = doc.createElement(\"iframe\");\n      iframe.className = \"wysihtml5-sandbox\";\n      wysihtml5.dom.setAttributes({\n        \"security\":           \"restricted\",\n        \"allowtransparency\":  \"true\",\n        \"frameborder\":        0,\n        \"width\":              0,\n        \"height\":             0,\n        \"marginwidth\":        0,\n        \"marginheight\":       0\n      }).on(iframe);\n\n      // Setting the src like this prevents ssl warnings in IE6\n      if (wysihtml5.browser.throwsMixedContentWarningWhenIframeSrcIsEmpty()) {\n        iframe.src = \"javascript:'<html></html>'\";\n      }\n\n      iframe.onload = function() {\n        iframe.onreadystatechange = iframe.onload = null;\n        that._onLoadIframe(iframe);\n      };\n\n      iframe.onreadystatechange = function() {\n        if (/loaded|complete/.test(iframe.readyState)) {\n          iframe.onreadystatechange = iframe.onload = null;\n          that._onLoadIframe(iframe);\n        }\n      };\n\n      return iframe;\n    },\n\n    /**\n     * Callback for when the iframe has finished loading\n     */\n    _onLoadIframe: function(iframe) {\n      // don't resume when the iframe got unloaded (eg. by removing it from the dom)\n      if (!wysihtml5.dom.contains(doc.documentElement, iframe)) {\n        return;\n      }\n\n      var that           = this,\n          iframeWindow   = iframe.contentWindow,\n          iframeDocument = iframe.contentWindow.document,\n          charset        = doc.characterSet || doc.charset || \"utf-8\",\n          sandboxHtml    = this._getHtml({\n            charset:      charset,\n            stylesheets:  this.config.stylesheets\n          });\n\n      // Create the basic dom tree including proper DOCTYPE and charset\n      iframeDocument.open(\"text/html\", \"replace\");\n      iframeDocument.write(sandboxHtml);\n      iframeDocument.close();\n\n      this.getWindow = function() { return iframe.contentWindow; };\n      this.getDocument = function() { return iframe.contentWindow.document; };\n\n      // Catch js errors and pass them to the parent's onerror event\n      // addEventListener(\"error\") doesn't work properly in some browsers\n      // TODO: apparently this doesn't work in IE9!\n      iframeWindow.onerror = function(errorMessage, fileName, lineNumber) {\n        throw new Error(\"wysihtml5.Sandbox: \" + errorMessage, fileName, lineNumber);\n      };\n\n      if (!wysihtml5.browser.supportsSandboxedIframes()) {\n        // Unset a bunch of sensitive variables\n        // Please note: This isn't hack safe!\n        // It more or less just takes care of basic attacks and prevents accidental theft of sensitive information\n        // IE is secure though, which is the most important thing, since IE is the only browser, who\n        // takes over scripts & styles into contentEditable elements when copied from external websites\n        // or applications (Microsoft Word, ...)\n        var i, length;\n        for (i=0, length=windowProperties.length; i<length; i++) {\n          this._unset(iframeWindow, windowProperties[i]);\n        }\n        for (i=0, length=windowProperties2.length; i<length; i++) {\n          this._unset(iframeWindow, windowProperties2[i], wysihtml5.EMPTY_FUNCTION);\n        }\n        for (i=0, length=documentProperties.length; i<length; i++) {\n          this._unset(iframeDocument, documentProperties[i]);\n        }\n        // This doesn't work in Safari 5\n        // See http://stackoverflow.com/questions/992461/is-it-possible-to-override-document-cookie-in-webkit\n        this._unset(iframeDocument, \"cookie\", \"\", true);\n      }\n\n      this.loaded = true;\n\n      // Trigger the callback\n      setTimeout(function() { that.callback(that); }, 0);\n    },\n\n    _getHtml: function(templateVars) {\n      var stylesheets = templateVars.stylesheets,\n          html        = \"\",\n          i           = 0,\n          length;\n      stylesheets = typeof(stylesheets) === \"string\" ? [stylesheets] : stylesheets;\n      if (stylesheets) {\n        length = stylesheets.length;\n        for (; i<length; i++) {\n          html += '<link rel=\"stylesheet\" href=\"' + stylesheets[i] + '\">';\n        }\n      }\n      templateVars.stylesheets = html;\n\n      return wysihtml5.lang.string(\n        '<!DOCTYPE html><html><head>'\n        + '<meta charset=\"#{charset}\">#{stylesheets}</head>'\n        + '<body></body></html>'\n      ).interpolate(templateVars);\n    },\n\n    /**\n     * Method to unset/override existing variables\n     * @example\n     *    // Make cookie unreadable and unwritable\n     *    this._unset(document, \"cookie\", \"\", true);\n     */\n    _unset: function(object, property, value, setter) {\n      try { object[property] = value; } catch(e) {}\n\n      try { object.__defineGetter__(property, function() { return value; }); } catch(e) {}\n      if (setter) {\n        try { object.__defineSetter__(property, function() {}); } catch(e) {}\n      }\n\n      if (!wysihtml5.browser.crashesWhenDefineProperty(property)) {\n        try {\n          var config = {\n            get: function() { return value; }\n          };\n          if (setter) {\n            config.set = function() {};\n          }\n          Object.defineProperty(object, property, config);\n        } catch(e) {}\n      }\n    }\n  });\n})(wysihtml5);\n;(function(wysihtml5) {\n  var doc = document;\n  wysihtml5.dom.ContentEditableArea = Base.extend({\n      getContentEditable: function() {\n        return this.element;\n      },\n\n      getWindow: function() {\n        return this.element.ownerDocument.defaultView;\n      },\n\n      getDocument: function() {\n        return this.element.ownerDocument;\n      },\n\n      constructor: function(readyCallback, config, contentEditable) {\n        this.callback = readyCallback || wysihtml5.EMPTY_FUNCTION;\n        this.config   = wysihtml5.lang.object({}).merge(config).get();\n        if (contentEditable) {\n            this.element = this._bindElement(contentEditable);\n        } else {\n            this.element = this._createElement();\n        }\n      },\n\n      // creates a new contenteditable and initiates it\n      _createElement: function() {\n        var element = doc.createElement(\"div\");\n        element.className = \"wysihtml5-sandbox\";\n        this._loadElement(element);\n        return element;\n      },\n\n      // initiates an allready existent contenteditable\n      _bindElement: function(contentEditable) {\n        contentEditable.className = (contentEditable.className && contentEditable.className != '') ? contentEditable.className + \" wysihtml5-sandbox\" : \"wysihtml5-sandbox\";\n        this._loadElement(contentEditable, true);\n        return contentEditable;\n      },\n\n      _loadElement: function(element, contentExists) {\n          var that = this;\n        if (!contentExists) {\n            var sandboxHtml = this._getHtml();\n            element.innerHTML = sandboxHtml;\n        }\n\n        this.getWindow = function() { return element.ownerDocument.defaultView; };\n        this.getDocument = function() { return element.ownerDocument; };\n\n        // Catch js errors and pass them to the parent's onerror event\n        // addEventListener(\"error\") doesn't work properly in some browsers\n        // TODO: apparently this doesn't work in IE9!\n        // TODO: figure out and bind the errors logic for contenteditble mode\n        /*iframeWindow.onerror = function(errorMessage, fileName, lineNumber) {\n          throw new Error(\"wysihtml5.Sandbox: \" + errorMessage, fileName, lineNumber);\n        }\n        */\n        this.loaded = true;\n        // Trigger the callback\n        setTimeout(function() { that.callback(that); }, 0);\n      },\n\n      _getHtml: function(templateVars) {\n        return '';\n      }\n\n  });\n})(wysihtml5);\n;(function() {\n  var mapping = {\n    \"className\": \"class\"\n  };\n  wysihtml5.dom.setAttributes = function(attributes) {\n    return {\n      on: function(element) {\n        for (var i in attributes) {\n          element.setAttribute(mapping[i] || i, attributes[i]);\n        }\n      }\n    };\n  };\n})();\n;wysihtml5.dom.setStyles = function(styles) {\n  return {\n    on: function(element) {\n      var style = element.style;\n      if (typeof(styles) === \"string\") {\n        style.cssText += \";\" + styles;\n        return;\n      }\n      for (var i in styles) {\n        if (i === \"float\") {\n          style.cssFloat = styles[i];\n          style.styleFloat = styles[i];\n        } else {\n          style[i] = styles[i];\n        }\n      }\n    }\n  };\n};\n;/**\n * Simulate HTML5 placeholder attribute\n *\n * Needed since\n *    - div[contentEditable] elements don't support it\n *    - older browsers (such as IE8 and Firefox 3.6) don't support it at all\n *\n * @param {Object} parent Instance of main wysihtml5.Editor class\n * @param {Element} view Instance of wysihtml5.views.* class\n * @param {String} placeholderText\n *\n * @example\n *    wysihtml.dom.simulatePlaceholder(this, composer, \"Foobar\");\n */\n(function(dom) {\n  dom.simulatePlaceholder = function(editor, view, placeholderText) {\n    var CLASS_NAME = \"placeholder\",\n        unset = function() {\n          var composerIsVisible   = view.element.offsetWidth > 0 && view.element.offsetHeight > 0;\n          if (view.hasPlaceholderSet()) {\n            view.clear();\n            view.element.focus();\n            if (composerIsVisible ) {\n              setTimeout(function() {\n                var sel = view.selection.getSelection();\n                if (!sel.focusNode || !sel.anchorNode) {\n                  view.selection.selectNode(view.element.firstChild || view.element);\n                }\n              }, 0);\n            }\n          }\n          view.placeholderSet = false;\n          dom.removeClass(view.element, CLASS_NAME);\n        },\n        set = function() {\n          if (view.isEmpty()) {\n            view.placeholderSet = true;\n            view.setValue(placeholderText);\n            dom.addClass(view.element, CLASS_NAME);\n          }\n        };\n\n    editor\n      .on(\"set_placeholder\", set)\n      .on(\"unset_placeholder\", unset)\n      .on(\"focus:composer\", unset)\n      .on(\"paste:composer\", unset)\n      .on(\"blur:composer\", set);\n\n    set();\n  };\n})(wysihtml5.dom);\n;(function(dom) {\n  var documentElement = document.documentElement;\n  if (\"textContent\" in documentElement) {\n    dom.setTextContent = function(element, text) {\n      element.textContent = text;\n    };\n\n    dom.getTextContent = function(element) {\n      return element.textContent;\n    };\n  } else if (\"innerText\" in documentElement) {\n    dom.setTextContent = function(element, text) {\n      element.innerText = text;\n    };\n\n    dom.getTextContent = function(element) {\n      return element.innerText;\n    };\n  } else {\n    dom.setTextContent = function(element, text) {\n      element.nodeValue = text;\n    };\n\n    dom.getTextContent = function(element) {\n      return element.nodeValue;\n    };\n  }\n})(wysihtml5.dom);\n\n;/**\n * Get a set of attribute from one element\n *\n * IE gives wrong results for hasAttribute/getAttribute, for example:\n *    var td = document.createElement(\"td\");\n *    td.getAttribute(\"rowspan\"); // => \"1\" in IE\n *\n * Therefore we have to check the element's outerHTML for the attribute\n*/\n\nwysihtml5.dom.getAttribute = function(node, attributeName) {\n  var HAS_GET_ATTRIBUTE_BUG = !wysihtml5.browser.supportsGetAttributeCorrectly();\n  attributeName = attributeName.toLowerCase();\n  var nodeName = node.nodeName;\n  if (nodeName == \"IMG\" && attributeName == \"src\" && wysihtml5.dom.isLoadedImage(node) === true) {\n    // Get 'src' attribute value via object property since this will always contain the\n    // full absolute url (http://...)\n    // this fixes a very annoying bug in firefox (ver 3.6 & 4) and IE 8 where images copied from the same host\n    // will have relative paths, which the sanitizer strips out (see attributeCheckMethods.url)\n    return node.src;\n  } else if (HAS_GET_ATTRIBUTE_BUG && \"outerHTML\" in node) {\n    // Don't trust getAttribute/hasAttribute in IE 6-8, instead check the element's outerHTML\n    var outerHTML      = node.outerHTML.toLowerCase(),\n        // TODO: This might not work for attributes without value: <input disabled>\n        hasAttribute   = outerHTML.indexOf(\" \" + attributeName +  \"=\") != -1;\n\n    return hasAttribute ? node.getAttribute(attributeName) : null;\n  } else{\n    return node.getAttribute(attributeName);\n  }\n};\n;/**\n * Get all attributes of an element\n *\n * IE gives wrong results for hasAttribute/getAttribute, for example:\n *    var td = document.createElement(\"td\");\n *    td.getAttribute(\"rowspan\"); // => \"1\" in IE\n *\n * Therefore we have to check the element's outerHTML for the attribute\n*/\n\nwysihtml5.dom.getAttributes = function(node) {\n  var HAS_GET_ATTRIBUTE_BUG = !wysihtml5.browser.supportsGetAttributeCorrectly(),\n      nodeName = node.nodeName,\n      attributes = [],\n      attr;\n\n  for (attr in node.attributes) {\n    if ((node.attributes.hasOwnProperty && node.attributes.hasOwnProperty(attr)) || (!node.attributes.hasOwnProperty && Object.prototype.hasOwnProperty.call(node.attributes, attr)))  {\n      if (node.attributes[attr].specified) {\n        if (nodeName == \"IMG\" && node.attributes[attr].name.toLowerCase() == \"src\" && wysihtml5.dom.isLoadedImage(node) === true) {\n          attributes['src'] = node.src;\n        } else if (wysihtml5.lang.array(['rowspan', 'colspan']).contains(node.attributes[attr].name.toLowerCase()) && HAS_GET_ATTRIBUTE_BUG) {\n          if (node.attributes[attr].value !== 1) {\n            attributes[node.attributes[attr].name] = node.attributes[attr].value;\n          }\n        } else {\n          attributes[node.attributes[attr].name] = node.attributes[attr].value;\n        }\n      }\n    }\n  }\n  return attributes;\n};;/**\n   * Check whether the given node is a proper loaded image\n   * FIXME: Returns undefined when unknown (Chrome, Safari)\n*/\n\nwysihtml5.dom.isLoadedImage = function (node) {\n  try {\n    return node.complete && !node.mozMatchesSelector(\":-moz-broken\");\n  } catch(e) {\n    if (node.complete && node.readyState === \"complete\") {\n      return true;\n    }\n  }\n};\n;(function(wysihtml5) {\n\n    var api = wysihtml5.dom;\n\n    var MapCell = function(cell) {\n      this.el = cell;\n      this.isColspan= false;\n      this.isRowspan= false;\n      this.firstCol= true;\n      this.lastCol= true;\n      this.firstRow= true;\n      this.lastRow= true;\n      this.isReal= true;\n      this.spanCollection= [];\n      this.modified = false;\n    };\n\n    var TableModifyerByCell = function (cell, table) {\n        if (cell) {\n            this.cell = cell;\n            this.table = api.getParentElement(cell, { nodeName: [\"TABLE\"] });\n        } else if (table) {\n            this.table = table;\n            this.cell = this.table.querySelectorAll('th, td')[0];\n        }\n    };\n\n    function queryInList(list, query) {\n        var ret = [],\n            q;\n        for (var e = 0, len = list.length; e < len; e++) {\n            q = list[e].querySelectorAll(query);\n            if (q) {\n                for(var i = q.length; i--; ret.unshift(q[i]));\n            }\n        }\n        return ret;\n    }\n\n    function removeElement(el) {\n        el.parentNode.removeChild(el);\n    }\n\n    function insertAfter(referenceNode, newNode) {\n        referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling);\n    }\n\n    function nextNode(node, tag) {\n        var element = node.nextSibling;\n        while (element.nodeType !=1) {\n            element = element.nextSibling;\n            if (!tag || tag == element.tagName.toLowerCase()) {\n                return element;\n            }\n        }\n        return null;\n    }\n\n    TableModifyerByCell.prototype = {\n\n        addSpannedCellToMap: function(cell, map, r, c, cspan, rspan) {\n            var spanCollect = [],\n                rmax = r + ((rspan) ? parseInt(rspan, 10) - 1 : 0),\n                cmax = c + ((cspan) ? parseInt(cspan, 10) - 1 : 0);\n\n            for (var rr = r; rr <= rmax; rr++) {\n                if (typeof map[rr] == \"undefined\") { map[rr] = []; }\n                for (var cc = c; cc <= cmax; cc++) {\n                    map[rr][cc] = new MapCell(cell);\n                    map[rr][cc].isColspan = (cspan && parseInt(cspan, 10) > 1);\n                    map[rr][cc].isRowspan = (rspan && parseInt(rspan, 10) > 1);\n                    map[rr][cc].firstCol = cc == c;\n                    map[rr][cc].lastCol = cc == cmax;\n                    map[rr][cc].firstRow = rr == r;\n                    map[rr][cc].lastRow = rr == rmax;\n                    map[rr][cc].isReal = cc == c && rr == r;\n                    map[rr][cc].spanCollection = spanCollect;\n\n                    spanCollect.push(map[rr][cc]);\n                }\n            }\n        },\n\n        setCellAsModified: function(cell) {\n            cell.modified = true;\n            if (cell.spanCollection.length > 0) {\n              for (var s = 0, smax = cell.spanCollection.length; s < smax; s++) {\n                cell.spanCollection[s].modified = true;\n              }\n            }\n        },\n\n        setTableMap: function() {\n            var map = [];\n            var tableRows = this.getTableRows(),\n                ridx, row, cells, cidx, cell,\n                c,\n                cspan, rspan;\n\n            for (ridx = 0; ridx < tableRows.length; ridx++) {\n                row = tableRows[ridx];\n                cells = this.getRowCells(row);\n                c = 0;\n                if (typeof map[ridx] == \"undefined\") { map[ridx] = []; }\n                for (cidx = 0; cidx < cells.length; cidx++) {\n                    cell = cells[cidx];\n\n                    // If cell allready set means it is set by col or rowspan,\n                    // so increase cols index until free col is found\n                    while (typeof map[ridx][c] != \"undefined\") { c++; }\n\n                    cspan = api.getAttribute(cell, 'colspan');\n                    rspan = api.getAttribute(cell, 'rowspan');\n\n                    if (cspan || rspan) {\n                        this.addSpannedCellToMap(cell, map, ridx, c, cspan, rspan);\n                        c = c + ((cspan) ? parseInt(cspan, 10) : 1);\n                    } else {\n                        map[ridx][c] = new MapCell(cell);\n                        c++;\n                    }\n                }\n            }\n            this.map = map;\n            return map;\n        },\n\n        getRowCells: function(row) {\n            var inlineTables = this.table.querySelectorAll('table'),\n                inlineCells = (inlineTables) ? queryInList(inlineTables, 'th, td') : [],\n                allCells = row.querySelectorAll('th, td'),\n                tableCells = (inlineCells.length > 0) ? wysihtml5.lang.array(allCells).without(inlineCells) : allCells;\n\n            return tableCells;\n        },\n\n        getTableRows: function() {\n          var inlineTables = this.table.querySelectorAll('table'),\n              inlineRows = (inlineTables) ? queryInList(inlineTables, 'tr') : [],\n              allRows = this.table.querySelectorAll('tr'),\n              tableRows = (inlineRows.length > 0) ? wysihtml5.lang.array(allRows).without(inlineRows) : allRows;\n\n          return tableRows;\n        },\n\n        getMapIndex: function(cell) {\n          var r_length = this.map.length,\n              c_length = (this.map && this.map[0]) ? this.map[0].length : 0;\n\n          for (var r_idx = 0;r_idx < r_length; r_idx++) {\n              for (var c_idx = 0;c_idx < c_length; c_idx++) {\n                  if (this.map[r_idx][c_idx].el === cell) {\n                      return {'row': r_idx, 'col': c_idx};\n                  }\n              }\n          }\n          return false;\n        },\n\n        getElementAtIndex: function(idx) {\n            this.setTableMap();\n            if (this.map[idx.row] && this.map[idx.row][idx.col] && this.map[idx.row][idx.col].el) {\n                return this.map[idx.row][idx.col].el;\n            }\n            return null;\n        },\n\n        getMapElsTo: function(to_cell) {\n            var els = [];\n            this.setTableMap();\n            this.idx_start = this.getMapIndex(this.cell);\n            this.idx_end = this.getMapIndex(to_cell);\n\n            // switch indexes if start is bigger than end\n            if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {\n                var temp_idx = this.idx_start;\n                this.idx_start = this.idx_end;\n                this.idx_end = temp_idx;\n            }\n            if (this.idx_start.col > this.idx_end.col) {\n                var temp_cidx = this.idx_start.col;\n                this.idx_start.col = this.idx_end.col;\n                this.idx_end.col = temp_cidx;\n            }\n\n            if (this.idx_start != null && this.idx_end != null) {\n                for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {\n                    for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {\n                        els.push(this.map[row][col].el);\n                    }\n                }\n            }\n            return els;\n        },\n\n        orderSelectionEnds: function(secondcell) {\n            this.setTableMap();\n            this.idx_start = this.getMapIndex(this.cell);\n            this.idx_end = this.getMapIndex(secondcell);\n\n            // switch indexes if start is bigger than end\n            if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {\n                var temp_idx = this.idx_start;\n                this.idx_start = this.idx_end;\n                this.idx_end = temp_idx;\n            }\n            if (this.idx_start.col > this.idx_end.col) {\n                var temp_cidx = this.idx_start.col;\n                this.idx_start.col = this.idx_end.col;\n                this.idx_end.col = temp_cidx;\n            }\n\n            return {\n                \"start\": this.map[this.idx_start.row][this.idx_start.col].el,\n                \"end\": this.map[this.idx_end.row][this.idx_end.col].el\n            };\n        },\n\n        createCells: function(tag, nr, attrs) {\n            var doc = this.table.ownerDocument,\n                frag = doc.createDocumentFragment(),\n                cell;\n            for (var i = 0; i < nr; i++) {\n                cell = doc.createElement(tag);\n\n                if (attrs) {\n                    for (var attr in attrs) {\n                        if (attrs.hasOwnProperty(attr)) {\n                            cell.setAttribute(attr, attrs[attr]);\n                        }\n                    }\n                }\n\n                // add non breaking space\n                cell.appendChild(document.createTextNode(\"\\u00a0\"));\n\n                frag.appendChild(cell);\n            }\n            return frag;\n        },\n\n        // Returns next real cell (not part of spanned cell unless first) on row if selected index is not real. I no real cells -1 will be returned\n        correctColIndexForUnreals: function(col, row) {\n            var r = this.map[row],\n                corrIdx = -1;\n            for (var i = 0, max = col; i < col; i++) {\n                if (r[i].isReal){\n                    corrIdx++;\n                }\n            }\n            return corrIdx;\n        },\n\n        getLastNewCellOnRow: function(row, rowLimit) {\n            var cells = this.getRowCells(row),\n                cell, idx;\n\n            for (var cidx = 0, cmax = cells.length; cidx < cmax; cidx++) {\n                cell = cells[cidx];\n                idx = this.getMapIndex(cell);\n                if (idx === false || (typeof rowLimit != \"undefined\" && idx.row != rowLimit)) {\n                    return cell;\n                }\n            }\n            return null;\n        },\n\n        removeEmptyTable: function() {\n            var cells = this.table.querySelectorAll('td, th');\n            if (!cells || cells.length == 0) {\n                removeElement(this.table);\n                return true;\n            } else {\n                return false;\n            }\n        },\n\n        // Splits merged cell on row to unique cells\n        splitRowToCells: function(cell) {\n            if (cell.isColspan) {\n                var colspan = parseInt(api.getAttribute(cell.el, 'colspan') || 1, 10),\n                    cType = cell.el.tagName.toLowerCase();\n                if (colspan > 1) {\n                    var newCells = this.createCells(cType, colspan -1);\n                    insertAfter(cell.el, newCells);\n                }\n                cell.el.removeAttribute('colspan');\n            }\n        },\n\n        getRealRowEl: function(force, idx) {\n            var r = null,\n                c = null;\n\n            idx = idx || this.idx;\n\n            for (var cidx = 0, cmax = this.map[idx.row].length; cidx < cmax; cidx++) {\n                c = this.map[idx.row][cidx];\n                if (c.isReal) {\n                    r = api.getParentElement(c.el, { nodeName: [\"TR\"] });\n                    if (r) {\n                        return r;\n                    }\n                }\n            }\n\n            if (r === null && force) {\n                r = api.getParentElement(this.map[idx.row][idx.col].el, { nodeName: [\"TR\"] }) || null;\n            }\n\n            return r;\n        },\n\n        injectRowAt: function(row, col, colspan, cType, c) {\n            var r = this.getRealRowEl(false, {'row': row, 'col': col}),\n                new_cells = this.createCells(cType, colspan);\n\n            if (r) {\n                var n_cidx = this.correctColIndexForUnreals(col, row);\n                if (n_cidx >= 0) {\n                    insertAfter(this.getRowCells(r)[n_cidx], new_cells);\n                } else {\n                    r.insertBefore(new_cells, r.firstChild);\n                }\n            } else {\n                var rr = this.table.ownerDocument.createElement('tr');\n                rr.appendChild(new_cells);\n                insertAfter(api.getParentElement(c.el, { nodeName: [\"TR\"] }), rr);\n            }\n        },\n\n        canMerge: function(to) {\n            this.to = to;\n            this.setTableMap();\n            this.idx_start = this.getMapIndex(this.cell);\n            this.idx_end = this.getMapIndex(this.to);\n\n            // switch indexes if start is bigger than end\n            if (this.idx_start.row > this.idx_end.row || (this.idx_start.row == this.idx_end.row && this.idx_start.col > this.idx_end.col)) {\n                var temp_idx = this.idx_start;\n                this.idx_start = this.idx_end;\n                this.idx_end = temp_idx;\n            }\n            if (this.idx_start.col > this.idx_end.col) {\n                var temp_cidx = this.idx_start.col;\n                this.idx_start.col = this.idx_end.col;\n                this.idx_end.col = temp_cidx;\n            }\n\n            for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {\n                for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {\n                    if (this.map[row][col].isColspan || this.map[row][col].isRowspan) {\n                        return false;\n                    }\n                }\n            }\n            return true;\n        },\n\n        decreaseCellSpan: function(cell, span) {\n            var nr = parseInt(api.getAttribute(cell.el, span), 10) - 1;\n            if (nr >= 1) {\n                cell.el.setAttribute(span, nr);\n            } else {\n                cell.el.removeAttribute(span);\n                if (span == 'colspan') {\n                    cell.isColspan = false;\n                }\n                if (span == 'rowspan') {\n                    cell.isRowspan = false;\n                }\n                cell.firstCol = true;\n                cell.lastCol = true;\n                cell.firstRow = true;\n                cell.lastRow = true;\n                cell.isReal = true;\n            }\n        },\n\n        removeSurplusLines: function() {\n            var row, cell, ridx, rmax, cidx, cmax, allRowspan;\n\n            this.setTableMap();\n            if (this.map) {\n                ridx = 0;\n                rmax = this.map.length;\n                for (;ridx < rmax; ridx++) {\n                    row = this.map[ridx];\n                    allRowspan = true;\n                    cidx = 0;\n                    cmax = row.length;\n                    for (; cidx < cmax; cidx++) {\n                        cell = row[cidx];\n                        if (!(api.getAttribute(cell.el, \"rowspan\") && parseInt(api.getAttribute(cell.el, \"rowspan\"), 10) > 1 && cell.firstRow !== true)) {\n                            allRowspan = false;\n                            break;\n                        }\n                    }\n                    if (allRowspan) {\n                        cidx = 0;\n                        for (; cidx < cmax; cidx++) {\n                            this.decreaseCellSpan(row[cidx], 'rowspan');\n                        }\n                    }\n                }\n\n                // remove rows without cells\n                var tableRows = this.getTableRows();\n                ridx = 0;\n                rmax = tableRows.length;\n                for (;ridx < rmax; ridx++) {\n                    row = tableRows[ridx];\n                    if (row.childNodes.length == 0 && (/^\\s*$/.test(row.textContent || row.innerText))) {\n                        removeElement(row);\n                    }\n                }\n            }\n        },\n\n        fillMissingCells: function() {\n            var r_max = 0,\n                c_max = 0,\n                prevcell = null;\n\n            this.setTableMap();\n            if (this.map) {\n\n                // find maximal dimensions of broken table\n                r_max = this.map.length;\n                for (var ridx = 0; ridx < r_max; ridx++) {\n                    if (this.map[ridx].length > c_max) { c_max = this.map[ridx].length; }\n                }\n\n                for (var row = 0; row < r_max; row++) {\n                    for (var col = 0; col < c_max; col++) {\n                        if (this.map[row] && !this.map[row][col]) {\n                            if (col > 0) {\n                                this.map[row][col] = new MapCell(this.createCells('td', 1));\n                                prevcell = this.map[row][col-1];\n                                if (prevcell && prevcell.el && prevcell.el.parent) { // if parent does not exist element is removed from dom\n                                    insertAfter(this.map[row][col-1].el, this.map[row][col].el);\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        },\n\n        rectify: function() {\n            if (!this.removeEmptyTable()) {\n                this.removeSurplusLines();\n                this.fillMissingCells();\n                return true;\n            } else {\n                return false;\n            }\n        },\n\n        unmerge: function() {\n            if (this.rectify()) {\n                this.setTableMap();\n                this.idx = this.getMapIndex(this.cell);\n\n                if (this.idx) {\n                    var thisCell = this.map[this.idx.row][this.idx.col],\n                        colspan = (api.getAttribute(thisCell.el, \"colspan\")) ? parseInt(api.getAttribute(thisCell.el, \"colspan\"), 10) : 1,\n                        cType = thisCell.el.tagName.toLowerCase();\n\n                    if (thisCell.isRowspan) {\n                        var rowspan = parseInt(api.getAttribute(thisCell.el, \"rowspan\"), 10);\n                        if (rowspan > 1) {\n                            for (var nr = 1, maxr = rowspan - 1; nr <= maxr; nr++){\n                                this.injectRowAt(this.idx.row + nr, this.idx.col, colspan, cType, thisCell);\n                            }\n                        }\n                        thisCell.el.removeAttribute('rowspan');\n                    }\n                    this.splitRowToCells(thisCell);\n                }\n            }\n        },\n\n        // merges cells from start cell (defined in creating obj) to \"to\" cell\n        merge: function(to) {\n            if (this.rectify()) {\n                if (this.canMerge(to)) {\n                    var rowspan = this.idx_end.row - this.idx_start.row + 1,\n                        colspan = this.idx_end.col - this.idx_start.col + 1;\n\n                    for (var row = this.idx_start.row, maxr = this.idx_end.row; row <= maxr; row++) {\n                        for (var col = this.idx_start.col, maxc = this.idx_end.col; col <= maxc; col++) {\n\n                            if (row == this.idx_start.row && col == this.idx_start.col) {\n                                if (rowspan > 1) {\n                                    this.map[row][col].el.setAttribute('rowspan', rowspan);\n                                }\n                                if (colspan > 1) {\n                                    this.map[row][col].el.setAttribute('colspan', colspan);\n                                }\n                            } else {\n                                // transfer content\n                                if (!(/^\\s*<br\\/?>\\s*$/.test(this.map[row][col].el.innerHTML.toLowerCase()))) {\n                                    this.map[this.idx_start.row][this.idx_start.col].el.innerHTML += ' ' + this.map[row][col].el.innerHTML;\n                                }\n                                removeElement(this.map[row][col].el);\n                            }\n                        }\n                    }\n                    this.rectify();\n                } else {\n                    if (window.console) {\n                        console.log('Do not know how to merge allready merged cells.');\n                    }\n                }\n            }\n        },\n\n        // Decreases rowspan of a cell if it is done on first cell of rowspan row (real cell)\n        // Cell is moved to next row (if it is real)\n        collapseCellToNextRow: function(cell) {\n            var cellIdx = this.getMapIndex(cell.el),\n                newRowIdx = cellIdx.row + 1,\n                newIdx = {'row': newRowIdx, 'col': cellIdx.col};\n\n            if (newRowIdx < this.map.length) {\n\n                var row = this.getRealRowEl(false, newIdx);\n                if (row !== null) {\n                    var n_cidx = this.correctColIndexForUnreals(newIdx.col, newIdx.row);\n                    if (n_cidx >= 0) {\n                        insertAfter(this.getRowCells(row)[n_cidx], cell.el);\n                    } else {\n                        var lastCell = this.getLastNewCellOnRow(row, newRowIdx);\n                        if (lastCell !== null) {\n                            insertAfter(lastCell, cell.el);\n                        } else {\n                            row.insertBefore(cell.el, row.firstChild);\n                        }\n                    }\n                    if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {\n                        cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);\n                    } else {\n                        cell.el.removeAttribute('rowspan');\n                    }\n                }\n            }\n        },\n\n        // Removes a cell when removing a row\n        // If is rowspan cell then decreases the rowspan\n        // and moves cell to next row if needed (is first cell of rowspan)\n        removeRowCell: function(cell) {\n            if (cell.isReal) {\n               if (cell.isRowspan) {\n                   this.collapseCellToNextRow(cell);\n               } else {\n                   removeElement(cell.el);\n               }\n            } else {\n                if (parseInt(api.getAttribute(cell.el, 'rowspan'), 10) > 2) {\n                    cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) - 1);\n                } else {\n                    cell.el.removeAttribute('rowspan');\n                }\n            }\n        },\n\n        getRowElementsByCell: function() {\n            var cells = [];\n            this.setTableMap();\n            this.idx = this.getMapIndex(this.cell);\n            if (this.idx !== false) {\n                var modRow = this.map[this.idx.row];\n                for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {\n                    if (modRow[cidx].isReal) {\n                        cells.push(modRow[cidx].el);\n                    }\n                }\n            }\n            return cells;\n        },\n\n        getColumnElementsByCell: function() {\n            var cells = [];\n            this.setTableMap();\n            this.idx = this.getMapIndex(this.cell);\n            if (this.idx !== false) {\n                for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {\n                    if (this.map[ridx][this.idx.col] && this.map[ridx][this.idx.col].isReal) {\n                        cells.push(this.map[ridx][this.idx.col].el);\n                    }\n                }\n            }\n            return cells;\n        },\n\n        // Removes the row of selected cell\n        removeRow: function() {\n            var oldRow = api.getParentElement(this.cell, { nodeName: [\"TR\"] });\n            if (oldRow) {\n                this.setTableMap();\n                this.idx = this.getMapIndex(this.cell);\n                if (this.idx !== false) {\n                    var modRow = this.map[this.idx.row];\n                    for (var cidx = 0, cmax = modRow.length; cidx < cmax; cidx++) {\n                        if (!modRow[cidx].modified) {\n                            this.setCellAsModified(modRow[cidx]);\n                            this.removeRowCell(modRow[cidx]);\n                        }\n                    }\n                }\n                removeElement(oldRow);\n            }\n        },\n\n        removeColCell: function(cell) {\n            if (cell.isColspan) {\n                if (parseInt(api.getAttribute(cell.el, 'colspan'), 10) > 2) {\n                    cell.el.setAttribute('colspan', parseInt(api.getAttribute(cell.el, 'colspan'), 10) - 1);\n                } else {\n                    cell.el.removeAttribute('colspan');\n                }\n            } else if (cell.isReal) {\n                removeElement(cell.el);\n            }\n        },\n\n        removeColumn: function() {\n            this.setTableMap();\n            this.idx = this.getMapIndex(this.cell);\n            if (this.idx !== false) {\n                for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++) {\n                    if (!this.map[ridx][this.idx.col].modified) {\n                        this.setCellAsModified(this.map[ridx][this.idx.col]);\n                        this.removeColCell(this.map[ridx][this.idx.col]);\n                    }\n                }\n            }\n        },\n\n        // removes row or column by selected cell element\n        remove: function(what) {\n            if (this.rectify()) {\n                switch (what) {\n                    case 'row':\n                        this.removeRow();\n                    break;\n                    case 'column':\n                        this.removeColumn();\n                    break;\n                }\n                this.rectify();\n            }\n        },\n\n        addRow: function(where) {\n            var doc = this.table.ownerDocument;\n\n            this.setTableMap();\n            this.idx = this.getMapIndex(this.cell);\n            if (where == \"below\" && api.getAttribute(this.cell, 'rowspan')) {\n                this.idx.row = this.idx.row + parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1;\n            }\n\n            if (this.idx !== false) {\n                var modRow = this.map[this.idx.row],\n                    newRow = doc.createElement('tr');\n\n                for (var ridx = 0, rmax = modRow.length; ridx < rmax; ridx++) {\n                    if (!modRow[ridx].modified) {\n                        this.setCellAsModified(modRow[ridx]);\n                        this.addRowCell(modRow[ridx], newRow, where);\n                    }\n                }\n\n                switch (where) {\n                    case 'below':\n                        insertAfter(this.getRealRowEl(true), newRow);\n                    break;\n                    case 'above':\n                        var cr = api.getParentElement(this.map[this.idx.row][this.idx.col].el, { nodeName: [\"TR\"] });\n                        if (cr) {\n                            cr.parentNode.insertBefore(newRow, cr);\n                        }\n                    break;\n                }\n            }\n        },\n\n        addRowCell: function(cell, row, where) {\n            var colSpanAttr = (cell.isColspan) ? {\"colspan\" : api.getAttribute(cell.el, 'colspan')} : null;\n            if (cell.isReal) {\n                if (where != 'above' && cell.isRowspan) {\n                    cell.el.setAttribute('rowspan', parseInt(api.getAttribute(cell.el,'rowspan'), 10) + 1);\n                } else {\n                    row.appendChild(this.createCells('td', 1, colSpanAttr));\n                }\n            } else {\n                if (where != 'above' && cell.isRowspan && cell.lastRow) {\n                    row.appendChild(this.createCells('td', 1, colSpanAttr));\n                } else if (c.isRowspan) {\n                    cell.el.attr('rowspan', parseInt(api.getAttribute(cell.el, 'rowspan'), 10) + 1);\n                }\n            }\n        },\n\n        add: function(where) {\n            if (this.rectify()) {\n                if (where == 'below' || where == 'above') {\n                    this.addRow(where);\n                }\n                if (where == 'before' || where == 'after') {\n                    this.addColumn(where);\n                }\n            }\n        },\n\n        addColCell: function (cell, ridx, where) {\n            var doAdd,\n                cType = cell.el.tagName.toLowerCase();\n\n            // defines add cell vs expand cell conditions\n            // true means add\n            switch (where) {\n                case \"before\":\n                    doAdd = (!cell.isColspan || cell.firstCol);\n                break;\n                case \"after\":\n                    doAdd = (!cell.isColspan || cell.lastCol || (cell.isColspan && c.el == this.cell));\n                break;\n            }\n\n            if (doAdd){\n                // adds a cell before or after current cell element\n                switch (where) {\n                    case \"before\":\n                        cell.el.parentNode.insertBefore(this.createCells(cType, 1), cell.el);\n                    break;\n                    case \"after\":\n                        insertAfter(cell.el, this.createCells(cType, 1));\n                    break;\n                }\n\n                // handles if cell has rowspan\n                if (cell.isRowspan) {\n                    this.handleCellAddWithRowspan(cell, ridx+1, where);\n                }\n\n            } else {\n                // expands cell\n                cell.el.setAttribute('colspan',  parseInt(api.getAttribute(cell.el, 'colspan'), 10) + 1);\n            }\n        },\n\n        addColumn: function(where) {\n            var row, modCell;\n\n            this.setTableMap();\n            this.idx = this.getMapIndex(this.cell);\n            if (where == \"after\" && api.getAttribute(this.cell, 'colspan')) {\n              this.idx.col = this.idx.col + parseInt(api.getAttribute(this.cell, 'colspan'), 10) - 1;\n            }\n\n            if (this.idx !== false) {\n                for (var ridx = 0, rmax = this.map.length; ridx < rmax; ridx++ ) {\n                    row = this.map[ridx];\n                    if (row[this.idx.col]) {\n                        modCell = row[this.idx.col];\n                        if (!modCell.modified) {\n                            this.setCellAsModified(modCell);\n                            this.addColCell(modCell, ridx , where);\n                        }\n                    }\n                }\n            }\n        },\n\n        handleCellAddWithRowspan: function (cell, ridx, where) {\n            var addRowsNr = parseInt(api.getAttribute(this.cell, 'rowspan'), 10) - 1,\n                crow = api.getParentElement(cell.el, { nodeName: [\"TR\"] }),\n                cType = cell.el.tagName.toLowerCase(),\n                cidx, temp_r_cells,\n                doc = this.table.ownerDocument,\n                nrow;\n\n            for (var i = 0; i < addRowsNr; i++) {\n                cidx = this.correctColIndexForUnreals(this.idx.col, (ridx + i));\n                crow = nextNode(crow, 'tr');\n                if (crow) {\n                    if (cidx > 0) {\n                        switch (where) {\n                            case \"before\":\n                                temp_r_cells = this.getRowCells(crow);\n                                if (cidx > 0 && this.map[ridx + i][this.idx.col].el != temp_r_cells[cidx] && cidx == temp_r_cells.length - 1) {\n                                     insertAfter(temp_r_cells[cidx], this.createCells(cType, 1));\n                                } else {\n                                    temp_r_cells[cidx].parentNode.insertBefore(this.createCells(cType, 1), temp_r_cells[cidx]);\n                                }\n\n                            break;\n                            case \"after\":\n                                insertAfter(this.getRowCells(crow)[cidx], this.createCells(cType, 1));\n                            break;\n                        }\n                    } else {\n                        crow.insertBefore(this.createCells(cType, 1), crow.firstChild);\n                    }\n                } else {\n                    nrow = doc.createElement('tr');\n                    nrow.appendChild(this.createCells(cType, 1));\n                    this.table.appendChild(nrow);\n                }\n            }\n        }\n    };\n\n    api.table = {\n        getCellsBetween: function(cell1, cell2) {\n            var c1 = new TableModifyerByCell(cell1);\n            return c1.getMapElsTo(cell2);\n        },\n\n        addCells: function(cell, where) {\n            var c = new TableModifyerByCell(cell);\n            c.add(where);\n        },\n\n        removeCells: function(cell, what) {\n            var c = new TableModifyerByCell(cell);\n            c.remove(what);\n        },\n\n        mergeCellsBetween: function(cell1, cell2) {\n            var c1 = new TableModifyerByCell(cell1);\n            c1.merge(cell2);\n        },\n\n        unmergeCell: function(cell) {\n            var c = new TableModifyerByCell(cell);\n            c.unmerge();\n        },\n\n        orderSelectionEnds: function(cell, cell2) {\n            var c = new TableModifyerByCell(cell);\n            return c.orderSelectionEnds(cell2);\n        },\n\n        indexOf: function(cell) {\n            var c = new TableModifyerByCell(cell);\n            c.setTableMap();\n            return c.getMapIndex(cell);\n        },\n\n        findCell: function(table, idx) {\n            var c = new TableModifyerByCell(null, table);\n            return c.getElementAtIndex(idx);\n        },\n\n        findRowByCell: function(cell) {\n            var c = new TableModifyerByCell(cell);\n            return c.getRowElementsByCell();\n        },\n\n        findColumnByCell: function(cell) {\n            var c = new TableModifyerByCell(cell);\n            return c.getColumnElementsByCell();\n        },\n\n        canMerge: function(cell1, cell2) {\n            var c = new TableModifyerByCell(cell1);\n            return c.canMerge(cell2);\n        }\n    };\n\n\n\n})(wysihtml5);\n;// does a selector query on element or array of elements\n\nwysihtml5.dom.query = function(elements, query) {\n    var ret = [],\n        q;\n\n    if (elements.nodeType) {\n        elements = [elements];\n    }\n\n    for (var e = 0, len = elements.length; e < len; e++) {\n        q = elements[e].querySelectorAll(query);\n        if (q) {\n            for(var i = q.length; i--; ret.unshift(q[i]));\n        }\n    }\n    return ret;\n};\n;wysihtml5.dom.compareDocumentPosition = (function() {\n  var documentElement = document.documentElement;\n  if (documentElement.compareDocumentPosition) {\n    return function(container, element) {\n      return container.compareDocumentPosition(element);\n    };\n  } else {\n    return function( container, element ) {\n      // implementation borrowed from https://github.com/tmpvar/jsdom/blob/681a8524b663281a0f58348c6129c8c184efc62c/lib/jsdom/level3/core.js // MIT license\n      var thisOwner, otherOwner;\n\n      if( container.nodeType === 9) // Node.DOCUMENT_NODE\n        thisOwner = container;\n      else\n        thisOwner = container.ownerDocument;\n\n      if( element.nodeType === 9) // Node.DOCUMENT_NODE\n        otherOwner = element;\n      else\n        otherOwner = element.ownerDocument;\n\n      if( container === element ) return 0;\n      if( container === element.ownerDocument ) return 4 + 16; //Node.DOCUMENT_POSITION_FOLLOWING + Node.DOCUMENT_POSITION_CONTAINED_BY;\n      if( container.ownerDocument === element ) return 2 + 8;  //Node.DOCUMENT_POSITION_PRECEDING + Node.DOCUMENT_POSITION_CONTAINS;\n      if( thisOwner !== otherOwner ) return 1; // Node.DOCUMENT_POSITION_DISCONNECTED;\n\n      // Text nodes for attributes does not have a _parentNode. So we need to find them as attribute child.\n      if( container.nodeType === 2 /*Node.ATTRIBUTE_NODE*/ && container.childNodes && wysihtml5.lang.array(container.childNodes).indexOf( element ) !== -1)\n        return 4 + 16; //Node.DOCUMENT_POSITION_FOLLOWING + Node.DOCUMENT_POSITION_CONTAINED_BY;\n\n      if( element.nodeType === 2 /*Node.ATTRIBUTE_NODE*/ && element.childNodes && wysihtml5.lang.array(element.childNodes).indexOf( container ) !== -1)\n        return 2 + 8; //Node.DOCUMENT_POSITION_PRECEDING + Node.DOCUMENT_POSITION_CONTAINS;\n\n      var point = container;\n      var parents = [ ];\n      var previous = null;\n      while( point ) {\n        if( point == element ) return 2 + 8; //Node.DOCUMENT_POSITION_PRECEDING + Node.DOCUMENT_POSITION_CONTAINS;\n        parents.push( point );\n        point = point.parentNode;\n      }\n      point = element;\n      previous = null;\n      while( point ) {\n        if( point == container ) return 4 + 16; //Node.DOCUMENT_POSITION_FOLLOWING + Node.DOCUMENT_POSITION_CONTAINED_BY;\n        var location_index = wysihtml5.lang.array(parents).indexOf( point );\n        if( location_index !== -1) {\n         var smallest_common_ancestor = parents[ location_index ];\n         var this_index = wysihtml5.lang.array(smallest_common_ancestor.childNodes).indexOf( parents[location_index - 1]);//smallest_common_ancestor.childNodes.toArray().indexOf( parents[location_index - 1] );\n         var other_index = wysihtml5.lang.array(smallest_common_ancestor.childNodes).indexOf( previous ); //smallest_common_ancestor.childNodes.toArray().indexOf( previous );\n         if( this_index > other_index ) {\n               return 2; //Node.DOCUMENT_POSITION_PRECEDING;\n         }\n         else {\n           return 4; //Node.DOCUMENT_POSITION_FOLLOWING;\n         }\n        }\n        previous = point;\n        point = point.parentNode;\n      }\n      return 1; //Node.DOCUMENT_POSITION_DISCONNECTED;\n    };\n  }\n})();\n;wysihtml5.dom.unwrap = function(node) {\n  if (node.parentNode) {\n    while (node.lastChild) {\n      wysihtml5.dom.insert(node.lastChild).after(node);\n    }\n    node.parentNode.removeChild(node);\n  }\n};;/* \n * Methods for fetching pasted html before it gets inserted into content\n**/\n\n/* Modern event.clipboardData driven approach.\n * Advantage is that it does not have to loose selection or modify dom to catch the data. \n * IE does not support though.\n**/\nwysihtml5.dom.getPastedHtml = function(event) {\n  var html;\n  if (event.clipboardData) {\n    if (wysihtml5.lang.array(event.clipboardData.types).contains('text/html')) {\n      html = event.clipboardData.getData('text/html');\n    } else if (wysihtml5.lang.array(event.clipboardData.types).contains('text/plain')) {\n      html = wysihtml5.lang.string(event.clipboardData.getData('text/plain')).escapeHTML(true, true);\n    }\n  }\n  return html;\n};\n\n/* Older temprorary contenteditable as paste source catcher method for fallbacks */\nwysihtml5.dom.getPastedHtmlWithDiv = function (composer, f) {\n  var selBookmark = composer.selection.getBookmark(),\n      doc = composer.element.ownerDocument,\n      cleanerDiv = doc.createElement('DIV');\n  \n  doc.body.appendChild(cleanerDiv);\n\n  cleanerDiv.style.width = \"1px\";\n  cleanerDiv.style.height = \"1px\";\n  cleanerDiv.style.overflow = \"hidden\";\n\n  cleanerDiv.setAttribute('contenteditable', 'true');\n  cleanerDiv.focus();\n\n  setTimeout(function () {\n    composer.selection.setBookmark(selBookmark);\n    f(cleanerDiv.innerHTML);\n    cleanerDiv.parentNode.removeChild(cleanerDiv);\n  }, 0);\n};;/**\n * Fix most common html formatting misbehaviors of browsers implementation when inserting\n * content via copy & paste contentEditable\n *\n * @author Christopher Blum\n */\nwysihtml5.quirks.cleanPastedHTML = (function() {\n\n  var styleToRegex = function (styleStr) {\n    var trimmedStr = wysihtml5.lang.string(styleStr).trim(),\n        escapedStr = trimmedStr.replace(/[\\-\\[\\]\\/\\{\\}\\(\\)\\*\\+\\?\\.\\\\\\^\\$\\|]/g, \"\\\\$&\");\n\n    return new RegExp(\"^((?!^\" + escapedStr + \"$).)*$\", \"i\");\n  };\n\n  var extendRulesWithStyleExceptions = function (rules, exceptStyles) {\n    var newRules = wysihtml5.lang.object(rules).clone(true),\n        tag, style;\n\n    for (tag in newRules.tags) {\n\n      if (newRules.tags.hasOwnProperty(tag)) {\n        if (newRules.tags[tag].keep_styles) {\n          for (style in newRules.tags[tag].keep_styles) {\n            if (newRules.tags[tag].keep_styles.hasOwnProperty(style)) {\n              if (exceptStyles[style]) {\n                newRules.tags[tag].keep_styles[style] = styleToRegex(exceptStyles[style]);\n              }\n            }\n          }\n        }\n      }\n    }\n\n    return newRules;\n  };\n\n  var pickRuleset = function(ruleset, html) {\n    var pickedSet, defaultSet;\n\n    if (!ruleset) {\n      return null;\n    }\n\n    for (var i = 0, max = ruleset.length; i < max; i++) {\n      if (!ruleset[i].condition) {\n        defaultSet = ruleset[i].set;\n      }\n      if (ruleset[i].condition && ruleset[i].condition.test(html)) {\n        return ruleset[i].set;\n      }\n    }\n\n    return defaultSet;\n  };\n\n  return function(html, options) {\n    var exceptStyles = {\n          'color': wysihtml5.dom.getStyle(\"color\").from(options.referenceNode),\n          'fontSize': wysihtml5.dom.getStyle(\"font-size\").from(options.referenceNode)\n        },\n        rules = extendRulesWithStyleExceptions(pickRuleset(options.rules, html) || {}, exceptStyles),\n        newHtml;\n\n    newHtml = wysihtml5.dom.parse(html, {\n      \"rules\": rules,\n      \"cleanUp\": true, // <span> elements, empty or without attributes, should be removed/replaced with their content\n      \"context\": options.referenceNode.ownerDocument,\n      \"uneditableClass\": options.uneditableClass,\n      \"clearInternals\" : true, // don't paste temprorary selection and other markings\n      \"unjoinNbsps\" : true\n    });\n\n    return newHtml;\n  };\n\n})();;/**\n * IE and Opera leave an empty paragraph in the contentEditable element after clearing it\n *\n * @param {Object} contentEditableElement The contentEditable element to observe for clearing events\n * @exaple\n *    wysihtml5.quirks.ensureProperClearing(myContentEditableElement);\n */\nwysihtml5.quirks.ensureProperClearing = (function() {\n  var clearIfNecessary = function() {\n    var element = this;\n    setTimeout(function() {\n      var innerHTML = element.innerHTML.toLowerCase();\n      if (innerHTML == \"<p>&nbsp;</p>\" ||\n          innerHTML == \"<p>&nbsp;</p><p>&nbsp;</p>\") {\n        element.innerHTML = \"\";\n      }\n    }, 0);\n  };\n\n  return function(composer) {\n    wysihtml5.dom.observe(composer.element, [\"cut\", \"keydown\"], clearIfNecessary);\n  };\n})();\n;// See https://bugzilla.mozilla.org/show_bug.cgi?id=664398\n//\n// In Firefox this:\n//      var d = document.createElement(\"div\");\n//      d.innerHTML ='<a href=\"~\"></a>';\n//      d.innerHTML;\n// will result in:\n//      <a href=\"%7E\"></a>\n// which is wrong\n(function(wysihtml5) {\n  var TILDE_ESCAPED = \"%7E\";\n  wysihtml5.quirks.getCorrectInnerHTML = function(element) {\n    var innerHTML = element.innerHTML;\n    if (innerHTML.indexOf(TILDE_ESCAPED) === -1) {\n      return innerHTML;\n    }\n\n    var elementsWithTilde = element.querySelectorAll(\"[href*='~'], [src*='~']\"),\n        url,\n        urlToSearch,\n        length,\n        i;\n    for (i=0, length=elementsWithTilde.length; i<length; i++) {\n      url         = elementsWithTilde[i].href || elementsWithTilde[i].src;\n      urlToSearch = wysihtml5.lang.string(url).replace(\"~\").by(TILDE_ESCAPED);\n      innerHTML   = wysihtml5.lang.string(innerHTML).replace(urlToSearch).by(url);\n    }\n    return innerHTML;\n  };\n})(wysihtml5);\n;/**\n * Force rerendering of a given element\n * Needed to fix display misbehaviors of IE\n *\n * @param {Element} element The element object which needs to be rerendered\n * @example\n *    wysihtml5.quirks.redraw(document.body);\n */\n(function(wysihtml5) {\n  var CLASS_NAME = \"wysihtml5-quirks-redraw\";\n\n  wysihtml5.quirks.redraw = function(element) {\n    wysihtml5.dom.addClass(element, CLASS_NAME);\n    wysihtml5.dom.removeClass(element, CLASS_NAME);\n\n    // Following hack is needed for firefox to make sure that image resize handles are properly removed\n    try {\n      var doc = element.ownerDocument;\n      doc.execCommand(\"italic\", false, null);\n      doc.execCommand(\"italic\", false, null);\n    } catch(e) {}\n  };\n})(wysihtml5);\n;wysihtml5.quirks.tableCellsSelection = function(editable, editor) {\n\n    var dom = wysihtml5.dom,\n        select = {\n            table: null,\n            start: null,\n            end: null,\n            cells: null,\n            select: selectCells\n        },\n        selection_class = \"wysiwyg-tmp-selected-cell\",\n        moveHandler = null,\n        upHandler = null;\n\n    function init () {\n\n        dom.observe(editable, \"mousedown\", function(event) {\n          var target = wysihtml5.dom.getParentElement(event.target, { nodeName: [\"TD\", \"TH\"] });\n          if (target) {\n              handleSelectionMousedown(target);\n          }\n        });\n\n        return select;\n    }\n\n    function handleSelectionMousedown (target) {\n      select.start = target;\n      select.end = target;\n      select.cells = [target];\n      select.table = dom.getParentElement(select.start, { nodeName: [\"TABLE\"] });\n\n      if (select.table) {\n        removeCellSelections();\n        dom.addClass(target, selection_class);\n        moveHandler = dom.observe(editable, \"mousemove\", handleMouseMove);\n        upHandler = dom.observe(editable, \"mouseup\", handleMouseUp);\n        editor.fire(\"tableselectstart\").fire(\"tableselectstart:composer\");\n      }\n    }\n\n    // remove all selection classes\n    function removeCellSelections () {\n        if (editable) {\n            var selectedCells = editable.querySelectorAll('.' + selection_class);\n            if (selectedCells.length > 0) {\n              for (var i = 0; i < selectedCells.length; i++) {\n                  dom.removeClass(selectedCells[i], selection_class);\n              }\n            }\n        }\n    }\n\n    function addSelections (cells) {\n      for (var i = 0; i < cells.length; i++) {\n        dom.addClass(cells[i], selection_class);\n      }\n    }\n\n    function handleMouseMove (event) {\n      var curTable = null,\n          cell = dom.getParentElement(event.target, { nodeName: [\"TD\",\"TH\"] }),\n          oldEnd;\n\n      if (cell && select.table && select.start) {\n        curTable =  dom.getParentElement(cell, { nodeName: [\"TABLE\"] });\n        if (curTable && curTable === select.table) {\n          removeCellSelections();\n          oldEnd = select.end;\n          select.end = cell;\n          select.cells = dom.table.getCellsBetween(select.start, cell);\n          if (select.cells.length > 1) {\n            editor.composer.selection.deselect();\n          }\n          addSelections(select.cells);\n          if (select.end !== oldEnd) {\n            editor.fire(\"tableselectchange\").fire(\"tableselectchange:composer\");\n          }\n        }\n      }\n    }\n\n    function handleMouseUp (event) {\n      moveHandler.stop();\n      upHandler.stop();\n      editor.fire(\"tableselect\").fire(\"tableselect:composer\");\n      setTimeout(function() {\n        bindSideclick();\n      },0);\n    }\n\n    function bindSideclick () {\n        var sideClickHandler = dom.observe(editable.ownerDocument, \"click\", function(event) {\n          sideClickHandler.stop();\n          if (dom.getParentElement(event.target, { nodeName: [\"TABLE\"] }) != select.table) {\n              removeCellSelections();\n              select.table = null;\n              select.start = null;\n              select.end = null;\n              editor.fire(\"tableunselect\").fire(\"tableunselect:composer\");\n          }\n        });\n    }\n\n    function selectCells (start, end) {\n        select.start = start;\n        select.end = end;\n        select.table = dom.getParentElement(select.start, { nodeName: [\"TABLE\"] });\n        selectedCells = dom.table.getCellsBetween(select.start, select.end);\n        addSelections(selectedCells);\n        bindSideclick();\n        editor.fire(\"tableselect\").fire(\"tableselect:composer\");\n    }\n\n    return init();\n\n};\n;(function(wysihtml5) {\n  var RGBA_REGEX     = /^rgba\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*([\\d\\.]+)\\s*\\)/i,\n      RGB_REGEX      = /^rgb\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*\\)/i,\n      HEX6_REGEX     = /^#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])/i,\n      HEX3_REGEX     = /^#([0-9a-f])([0-9a-f])([0-9a-f])/i;\n\n  var param_REGX = function (p) {\n    return new RegExp(\"(^|\\\\s|;)\" + p + \"\\\\s*:\\\\s*[^;$]+\" , \"gi\");\n  };\n\n  wysihtml5.quirks.styleParser = {\n\n    parseColor: function(stylesStr, paramName) {\n      var paramRegex = param_REGX(paramName),\n          params = stylesStr.match(paramRegex),\n          radix = 10,\n          str, colorMatch;\n\n      if (params) {\n        for (var i = params.length; i--;) {\n          params[i] = wysihtml5.lang.string(params[i].split(':')[1]).trim();\n        }\n        str = params[params.length-1];\n\n        if (RGBA_REGEX.test(str)) {\n          colorMatch = str.match(RGBA_REGEX);\n        } else if (RGB_REGEX.test(str)) {\n          colorMatch = str.match(RGB_REGEX);\n        } else if (HEX6_REGEX.test(str)) {\n          colorMatch = str.match(HEX6_REGEX);\n          radix = 16;\n        } else if (HEX3_REGEX.test(str)) {\n          colorMatch = str.match(HEX3_REGEX);\n          colorMatch.shift();\n          colorMatch.push(1);\n          return wysihtml5.lang.array(colorMatch).map(function(d, idx) {\n            return (idx < 3) ? (parseInt(d, 16) * 16) + parseInt(d, 16): parseFloat(d);\n          });\n        }\n\n        if (colorMatch) {\n          colorMatch.shift();\n          if (!colorMatch[3]) {\n            colorMatch.push(1);\n          }\n          return wysihtml5.lang.array(colorMatch).map(function(d, idx) {\n            return (idx < 3) ? parseInt(d, radix): parseFloat(d);\n          });\n        }\n      }\n      return false;\n    },\n\n    unparseColor: function(val, props) {\n      if (props) {\n        if (props == \"hex\") {\n          return (val[0].toString(16).toUpperCase()) + (val[1].toString(16).toUpperCase()) + (val[2].toString(16).toUpperCase());\n        } else if (props == \"hash\") {\n          return \"#\" + (val[0].toString(16).toUpperCase()) + (val[1].toString(16).toUpperCase()) + (val[2].toString(16).toUpperCase());\n        } else if (props == \"rgb\") {\n          return \"rgb(\" + val[0] + \",\" + val[1] + \",\" + val[2] + \")\";\n        } else if (props == \"rgba\") {\n          return \"rgba(\" + val[0] + \",\" + val[1] + \",\" + val[2] + \",\" + val[3] + \")\";\n        } else if (props == \"csv\") {\n          return  val[0] + \",\" + val[1] + \",\" + val[2] + \",\" + val[3];\n        }\n      }\n\n      if (val[3] && val[3] !== 1) {\n        return \"rgba(\" + val[0] + \",\" + val[1] + \",\" + val[2] + \",\" + val[3] + \")\";\n      } else {\n        return \"rgb(\" + val[0] + \",\" + val[1] + \",\" + val[2] + \")\";\n      }\n    },\n\n    parseFontSize: function(stylesStr) {\n      var params = stylesStr.match(param_REGX('font-size'));\n      if (params) {\n        return wysihtml5.lang.string(params[params.length - 1].split(':')[1]).trim();\n      }\n      return false;\n    }\n  };\n\n})(wysihtml5);\n;/**\n * Selection API\n *\n * @example\n *    var selection = new wysihtml5.Selection(editor);\n */\n(function(wysihtml5) {\n  var dom = wysihtml5.dom;\n\n  function _getCumulativeOffsetTop(element) {\n    var top = 0;\n    if (element.parentNode) {\n      do {\n        top += element.offsetTop || 0;\n        element = element.offsetParent;\n      } while (element);\n    }\n    return top;\n  }\n\n  // Provides the depth of ``descendant`` relative to ``ancestor``\n  function getDepth(ancestor, descendant) {\n      var ret = 0;\n      while (descendant !== ancestor) {\n          ret++;\n          descendant = descendant.parentNode;\n          if (!descendant)\n              throw new Error(\"not a descendant of ancestor!\");\n      }\n      return ret;\n  }\n\n  // Should fix the obtained ranges that cannot surrond contents normally to apply changes upon\n  // Being considerate to firefox that sets range start start out of span and end inside on doubleclick initiated selection\n  function expandRangeToSurround(range) {\n      if (range.canSurroundContents()) return;\n\n      var common = range.commonAncestorContainer,\n          start_depth = getDepth(common, range.startContainer),\n          end_depth = getDepth(common, range.endContainer);\n\n      while(!range.canSurroundContents()) {\n        // In the following branches, we cannot just decrement the depth variables because the setStartBefore/setEndAfter may move the start or end of the range more than one level relative to ``common``. So we need to recompute the depth.\n        if (start_depth > end_depth) {\n            range.setStartBefore(range.startContainer);\n            start_depth = getDepth(common, range.startContainer);\n        }\n        else {\n            range.setEndAfter(range.endContainer);\n            end_depth = getDepth(common, range.endContainer);\n        }\n      }\n  }\n\n  wysihtml5.Selection = Base.extend(\n    /** @scope wysihtml5.Selection.prototype */ {\n    constructor: function(editor, contain, unselectableClass) {\n      // Make sure that our external range library is initialized\n      window.rangy.init();\n\n      this.editor   = editor;\n      this.composer = editor.composer;\n      this.doc      = this.composer.doc;\n      this.contain = contain;\n      this.unselectableClass = unselectableClass || false;\n    },\n\n    /**\n     * Get the current selection as a bookmark to be able to later restore it\n     *\n     * @return {Object} An object that represents the current selection\n     */\n    getBookmark: function() {\n      var range = this.getRange();\n      if (range) expandRangeToSurround(range);\n      return range && range.cloneRange();\n    },\n\n    /**\n     * Restore a selection retrieved via wysihtml5.Selection.prototype.getBookmark\n     *\n     * @param {Object} bookmark An object that represents the current selection\n     */\n    setBookmark: function(bookmark) {\n      if (!bookmark) {\n        return;\n      }\n\n      this.setSelection(bookmark);\n    },\n\n    /**\n     * Set the caret in front of the given node\n     *\n     * @param {Object} node The element or text node where to position the caret in front of\n     * @example\n     *    selection.setBefore(myElement);\n     */\n    setBefore: function(node) {\n      var range = rangy.createRange(this.doc);\n      range.setStartBefore(node);\n      range.setEndBefore(node);\n      return this.setSelection(range);\n    },\n\n    /**\n     * Set the caret after the given node\n     *\n     * @param {Object} node The element or text node where to position the caret in front of\n     * @example\n     *    selection.setBefore(myElement);\n     */\n    setAfter: function(node) {\n      var range = rangy.createRange(this.doc);\n\n      range.setStartAfter(node);\n      range.setEndAfter(node);\n      return this.setSelection(range);\n    },\n\n    /**\n     * Ability to select/mark nodes\n     *\n     * @param {Element} node The node/element to select\n     * @example\n     *    selection.selectNode(document.getElementById(\"my-image\"));\n     */\n    selectNode: function(node, avoidInvisibleSpace) {\n      var range           = rangy.createRange(this.doc),\n          isElement       = node.nodeType === wysihtml5.ELEMENT_NODE,\n          canHaveHTML     = \"canHaveHTML\" in node ? node.canHaveHTML : (node.nodeName !== \"IMG\"),\n          content         = isElement ? node.innerHTML : node.data,\n          isEmpty         = (content === \"\" || content === wysihtml5.INVISIBLE_SPACE),\n          displayStyle    = dom.getStyle(\"display\").from(node),\n          isBlockElement  = (displayStyle === \"block\" || displayStyle === \"list-item\");\n\n      if (isEmpty && isElement && canHaveHTML && !avoidInvisibleSpace) {\n        // Make sure that caret is visible in node by inserting a zero width no breaking space\n        try { node.innerHTML = wysihtml5.INVISIBLE_SPACE; } catch(e) {}\n      }\n\n      if (canHaveHTML) {\n        range.selectNodeContents(node);\n      } else {\n        range.selectNode(node);\n      }\n\n      if (canHaveHTML && isEmpty && isElement) {\n        range.collapse(isBlockElement);\n      } else if (canHaveHTML && isEmpty) {\n        range.setStartAfter(node);\n        range.setEndAfter(node);\n      }\n\n      this.setSelection(range);\n    },\n\n    /**\n     * Get the node which contains the selection\n     *\n     * @param {Boolean} [controlRange] (only IE) Whether it should return the selected ControlRange element when the selection type is a \"ControlRange\"\n     * @return {Object} The node that contains the caret\n     * @example\n     *    var nodeThatContainsCaret = selection.getSelectedNode();\n     */\n    getSelectedNode: function(controlRange) {\n      var selection,\n          range;\n\n      if (controlRange && this.doc.selection && this.doc.selection.type === \"Control\") {\n        range = this.doc.selection.createRange();\n        if (range && range.length) {\n          return range.item(0);\n        }\n      }\n\n      selection = this.getSelection(this.doc);\n      if (selection.focusNode === selection.anchorNode) {\n        return selection.focusNode;\n      } else {\n        range = this.getRange(this.doc);\n        return range ? range.commonAncestorContainer : this.doc.body;\n      }\n    },\n\n    fixSelBorders: function() {\n      var range = this.getRange();\n      expandRangeToSurround(range);\n      this.setSelection(range);\n    },\n\n    getSelectedOwnNodes: function(controlRange) {\n      var selection,\n          ranges = this.getOwnRanges(),\n          ownNodes = [];\n\n      for (var i = 0, maxi = ranges.length; i < maxi; i++) {\n          ownNodes.push(ranges[i].commonAncestorContainer || this.doc.body);\n      }\n      return ownNodes;\n    },\n\n    findNodesInSelection: function(nodeTypes) {\n      var ranges = this.getOwnRanges(),\n          nodes = [], curNodes;\n      for (var i = 0, maxi = ranges.length; i < maxi; i++) {\n        curNodes = ranges[i].getNodes([1], function(node) {\n            return wysihtml5.lang.array(nodeTypes).contains(node.nodeName);\n        });\n        nodes = nodes.concat(curNodes);\n      }\n      return nodes;\n    },\n\n    containsUneditable: function() {\n      var uneditables = this.getOwnUneditables(),\n          selection = this.getSelection();\n\n      for (var i = 0, maxi = uneditables.length; i < maxi; i++) {\n        if (selection.containsNode(uneditables[i])) {\n          return true;\n        }\n      }\n\n      return false;\n    },\n\n    deleteContents: function()  {\n      var ranges = this.getOwnRanges();\n      for (var i = ranges.length; i--;) {\n        ranges[i].deleteContents();\n      }\n      this.setSelection(ranges[0]);\n    },\n\n    getPreviousNode: function(node, ignoreEmpty) {\n      if (!node) {\n        var selection = this.getSelection();\n        node = selection.anchorNode;\n      }\n\n      if (node === this.contain) {\n          return false;\n      }\n\n      var ret = node.previousSibling,\n          parent;\n\n      if (ret === this.contain) {\n          return false;\n      }\n\n      if (ret && ret.nodeType !== 3 && ret.nodeType !== 1) {\n         // do not count comments and other node types\n         ret = this.getPreviousNode(ret, ignoreEmpty);\n      } else if (ret && ret.nodeType === 3 && (/^\\s*$/).test(ret.textContent)) {\n        // do not count empty textnodes as previus nodes\n        ret = this.getPreviousNode(ret, ignoreEmpty);\n      } else if (ignoreEmpty && ret && ret.nodeType === 1 && !wysihtml5.lang.array([\"BR\", \"HR\", \"IMG\"]).contains(ret.nodeName) && (/^[\\s]*$/).test(ret.innerHTML)) {\n        // Do not count empty nodes if param set.\n        // Contenteditable tends to bypass and delete these silently when deleting with caret\n        ret = this.getPreviousNode(ret, ignoreEmpty);\n      } else if (!ret && node !== this.contain) {\n        parent = node.parentNode;\n        if (parent !== this.contain) {\n            ret = this.getPreviousNode(parent, ignoreEmpty);\n        }\n      }\n\n      return (ret !== this.contain) ? ret : false;\n    },\n\n    getSelectionParentsByTag: function(tagName) {\n      var nodes = this.getSelectedOwnNodes(),\n          curEl, parents = [];\n\n      for (var i = 0, maxi = nodes.length; i < maxi; i++) {\n        curEl = (nodes[i].nodeName &&  nodes[i].nodeName === 'LI') ? nodes[i] : wysihtml5.dom.getParentElement(nodes[i], { nodeName: ['LI']}, false, this.contain);\n        if (curEl) {\n          parents.push(curEl);\n        }\n      }\n      return (parents.length) ? parents : null;\n    },\n\n    getRangeToNodeEnd: function() {\n      if (this.isCollapsed()) {\n        var range = this.getRange(),\n            sNode = range.startContainer,\n            pos = range.startOffset,\n            lastR = rangy.createRange(this.doc);\n\n        lastR.selectNodeContents(sNode);\n        lastR.setStart(sNode, pos);\n        return lastR;\n      }\n    },\n\n    caretIsLastInSelection: function() {\n      var r = rangy.createRange(this.doc),\n          s = this.getSelection(),\n          endc = this.getRangeToNodeEnd().cloneContents(),\n          endtxt = endc.textContent;\n\n      return (/^\\s*$/).test(endtxt);\n    },\n\n    caretIsFirstInSelection: function() {\n      var r = rangy.createRange(this.doc),\n          s = this.getSelection(),\n          range = this.getRange(),\n          startNode = range.startContainer;\n      \n      if (startNode.nodeType === wysihtml5.TEXT_NODE) {\n        return this.isCollapsed() && (startNode.nodeType === wysihtml5.TEXT_NODE && (/^\\s*$/).test(startNode.data.substr(0,range.startOffset)));\n      } else {\n        r.selectNodeContents(this.getRange().commonAncestorContainer);\n        r.collapse(true);\n        return (this.isCollapsed() && (r.startContainer === s.anchorNode || r.endContainer === s.anchorNode) && r.startOffset === s.anchorOffset);\n      }\n    },\n\n    caretIsInTheBeginnig: function(ofNode) {\n        var selection = this.getSelection(),\n            node = selection.anchorNode,\n            offset = selection.anchorOffset;\n        if (ofNode) {\n          return (offset === 0 && (node.nodeName && node.nodeName === ofNode.toUpperCase() || wysihtml5.dom.getParentElement(node.parentNode, { nodeName: ofNode }, 1)));\n        } else {\n          return (offset === 0 && !this.getPreviousNode(node, true));\n        }\n    },\n\n    caretIsBeforeUneditable: function() {\n      var selection = this.getSelection(),\n          node = selection.anchorNode,\n          offset = selection.anchorOffset;\n\n      if (offset === 0) {\n        var prevNode = this.getPreviousNode(node, true);\n        if (prevNode) {\n          var uneditables = this.getOwnUneditables();\n          for (var i = 0, maxi = uneditables.length; i < maxi; i++) {\n            if (prevNode === uneditables[i]) {\n              return uneditables[i];\n            }\n          }\n        }\n      }\n      return false;\n    },\n\n    // TODO: Figure out a method from following 2 that would work universally\n    executeAndRestoreRangy: function(method, restoreScrollPosition) {\n      var win = this.doc.defaultView || this.doc.parentWindow,\n          sel = rangy.saveSelection(win);\n\n      if (!sel) {\n        method();\n      } else {\n        try {\n          method();\n        } catch(e) {\n          setTimeout(function() { throw e; }, 0);\n        }\n      }\n      rangy.restoreSelection(sel);\n    },\n\n    // TODO: has problems in chrome 12. investigate block level and uneditable area inbetween\n    executeAndRestore: function(method, restoreScrollPosition) {\n      var body                  = this.doc.body,\n          oldScrollTop          = restoreScrollPosition && body.scrollTop,\n          oldScrollLeft         = restoreScrollPosition && body.scrollLeft,\n          className             = \"_wysihtml5-temp-placeholder\",\n          placeholderHtml       = '<span class=\"' + className + '\">' + wysihtml5.INVISIBLE_SPACE + '</span>',\n          range                 = this.getRange(true),\n          caretPlaceholder,\n          newCaretPlaceholder,\n          nextSibling, prevSibling,\n          node, node2, range2,\n          newRange;\n\n      // Nothing selected, execute and say goodbye\n      if (!range) {\n        method(body, body);\n        return;\n      }\n\n      if (!range.collapsed) {\n        range2 = range.cloneRange();\n        node2 = range2.createContextualFragment(placeholderHtml);\n        range2.collapse(false);\n        range2.insertNode(node2);\n        range2.detach();\n      }\n\n      node = range.createContextualFragment(placeholderHtml);\n      range.insertNode(node);\n\n      if (node2) {\n        caretPlaceholder = this.contain.querySelectorAll(\".\" + className);\n        range.setStartBefore(caretPlaceholder[0]);\n        range.setEndAfter(caretPlaceholder[caretPlaceholder.length -1]);\n      }\n      this.setSelection(range);\n\n      // Make sure that a potential error doesn't cause our placeholder element to be left as a placeholder\n      try {\n        method(range.startContainer, range.endContainer);\n      } catch(e) {\n        setTimeout(function() { throw e; }, 0);\n      }\n      caretPlaceholder = this.contain.querySelectorAll(\".\" + className);\n      if (caretPlaceholder && caretPlaceholder.length) {\n        newRange = rangy.createRange(this.doc);\n        nextSibling = caretPlaceholder[0].nextSibling;\n        if (caretPlaceholder.length > 1) {\n          prevSibling = caretPlaceholder[caretPlaceholder.length -1].previousSibling;\n        }\n        if (prevSibling && nextSibling) {\n          newRange.setStartBefore(nextSibling);\n          newRange.setEndAfter(prevSibling);\n        } else {\n          newCaretPlaceholder = this.doc.createTextNode(wysihtml5.INVISIBLE_SPACE);\n          dom.insert(newCaretPlaceholder).after(caretPlaceholder[0]);\n          newRange.setStartBefore(newCaretPlaceholder);\n          newRange.setEndAfter(newCaretPlaceholder);\n        }\n        this.setSelection(newRange);\n        for (var i = caretPlaceholder.length; i--;) {\n         caretPlaceholder[i].parentNode.removeChild(caretPlaceholder[i]);\n        }\n\n      } else {\n        // fallback for when all hell breaks loose\n        this.contain.focus();\n      }\n\n      if (restoreScrollPosition) {\n        body.scrollTop  = oldScrollTop;\n        body.scrollLeft = oldScrollLeft;\n      }\n\n      // Remove it again, just to make sure that the placeholder is definitely out of the dom tree\n      try {\n        caretPlaceholder.parentNode.removeChild(caretPlaceholder);\n      } catch(e2) {}\n    },\n\n    set: function(node, offset) {\n      var newRange = rangy.createRange(this.doc);\n      newRange.setStart(node, offset || 0);\n      this.setSelection(newRange);\n    },\n\n    /**\n     * Insert html at the caret position and move the cursor after the inserted html\n     *\n     * @param {String} html HTML string to insert\n     * @example\n     *    selection.insertHTML(\"<p>foobar</p>\");\n     */\n    insertHTML: function(html) {\n      var range     = rangy.createRange(this.doc),\n          node = this.doc.createElement('DIV'),\n          fragment = this.doc.createDocumentFragment(),\n          lastChild;\n\n      node.innerHTML = html;\n      lastChild = node.lastChild;\n\n      while (node.firstChild) {\n        fragment.appendChild(node.firstChild);\n      }\n      this.insertNode(fragment);\n\n      if (lastChild) {\n        this.setAfter(lastChild);\n      }\n    },\n\n    /**\n     * Insert a node at the caret position and move the cursor behind it\n     *\n     * @param {Object} node HTML string to insert\n     * @example\n     *    selection.insertNode(document.createTextNode(\"foobar\"));\n     */\n    insertNode: function(node) {\n      var range = this.getRange();\n      if (range) {\n        range.insertNode(node);\n      }\n    },\n\n    /**\n     * Wraps current selection with the given node\n     *\n     * @param {Object} node The node to surround the selected elements with\n     */\n    surround: function(nodeOptions) {\n      var ranges = this.getOwnRanges(),\n          node, nodes = [];\n      if (ranges.length == 0) {\n        return nodes;\n      }\n\n      for (var i = ranges.length; i--;) {\n        node = this.doc.createElement(nodeOptions.nodeName);\n        nodes.push(node);\n        if (nodeOptions.className) {\n          node.className = nodeOptions.className;\n        }\n        if (nodeOptions.cssStyle) {\n          node.setAttribute('style', nodeOptions.cssStyle);\n        }\n        try {\n          // This only works when the range boundaries are not overlapping other elements\n          ranges[i].surroundContents(node);\n          this.selectNode(node);\n        } catch(e) {\n          // fallback\n          node.appendChild(ranges[i].extractContents());\n          ranges[i].insertNode(node);\n        }\n      }\n      return nodes;\n    },\n\n    deblockAndSurround: function(nodeOptions) {\n      var tempElement = this.doc.createElement('div'),\n          range = rangy.createRange(this.doc),\n          tempDivElements,\n          tempElements,\n          firstChild;\n\n      tempElement.className = nodeOptions.className;\n\n      this.composer.commands.exec(\"formatBlock\", nodeOptions.nodeName, nodeOptions.className);\n      tempDivElements = this.contain.querySelectorAll(\".\" + nodeOptions.className);\n      if (tempDivElements[0]) {\n        tempDivElements[0].parentNode.insertBefore(tempElement, tempDivElements[0]);\n\n        range.setStartBefore(tempDivElements[0]);\n        range.setEndAfter(tempDivElements[tempDivElements.length - 1]);\n        tempElements = range.extractContents();\n\n        while (tempElements.firstChild) {\n          firstChild = tempElements.firstChild;\n          if (firstChild.nodeType == 1 && wysihtml5.dom.hasClass(firstChild, nodeOptions.className)) {\n            while (firstChild.firstChild) {\n              tempElement.appendChild(firstChild.firstChild);\n            }\n            if (firstChild.nodeName !== \"BR\") { tempElement.appendChild(this.doc.createElement('br')); }\n            tempElements.removeChild(firstChild);\n          } else {\n            tempElement.appendChild(firstChild);\n          }\n        }\n      } else {\n        tempElement = null;\n      }\n\n      return tempElement;\n    },\n\n    /**\n     * Scroll the current caret position into the view\n     * FIXME: This is a bit hacky, there might be a smarter way of doing this\n     *\n     * @example\n     *    selection.scrollIntoView();\n     */\n    scrollIntoView: function() {\n      var doc           = this.doc,\n          tolerance     = 5, // px\n          hasScrollBars = doc.documentElement.scrollHeight > doc.documentElement.offsetHeight,\n          tempElement   = doc._wysihtml5ScrollIntoViewElement = doc._wysihtml5ScrollIntoViewElement || (function() {\n            var element = doc.createElement(\"span\");\n            // The element needs content in order to be able to calculate it's position properly\n            element.innerHTML = wysihtml5.INVISIBLE_SPACE;\n            return element;\n          })(),\n          offsetTop;\n\n      if (hasScrollBars) {\n        this.insertNode(tempElement);\n        offsetTop = _getCumulativeOffsetTop(tempElement);\n        tempElement.parentNode.removeChild(tempElement);\n        if (offsetTop >= (doc.body.scrollTop + doc.documentElement.offsetHeight - tolerance)) {\n          doc.body.scrollTop = offsetTop;\n        }\n      }\n    },\n\n    /**\n     * Select line where the caret is in\n     */\n    selectLine: function() {\n      if (wysihtml5.browser.supportsSelectionModify()) {\n        this._selectLine_W3C();\n      } else if (this.doc.selection) {\n        this._selectLine_MSIE();\n      }\n    },\n\n    /**\n     * See https://developer.mozilla.org/en/DOM/Selection/modify\n     */\n    _selectLine_W3C: function() {\n      var win       = this.doc.defaultView,\n          selection = win.getSelection();\n      selection.modify(\"move\", \"left\", \"lineboundary\");\n      selection.modify(\"extend\", \"right\", \"lineboundary\");\n    },\n\n    _selectLine_MSIE: function() {\n      var range       = this.doc.selection.createRange(),\n          rangeTop    = range.boundingTop,\n          scrollWidth = this.doc.body.scrollWidth,\n          rangeBottom,\n          rangeEnd,\n          measureNode,\n          i,\n          j;\n\n      if (!range.moveToPoint) {\n        return;\n      }\n\n      if (rangeTop === 0) {\n        // Don't know why, but when the selection ends at the end of a line\n        // range.boundingTop is 0\n        measureNode = this.doc.createElement(\"span\");\n        this.insertNode(measureNode);\n        rangeTop = measureNode.offsetTop;\n        measureNode.parentNode.removeChild(measureNode);\n      }\n\n      rangeTop += 1;\n\n      for (i=-10; i<scrollWidth; i+=2) {\n        try {\n          range.moveToPoint(i, rangeTop);\n          break;\n        } catch(e1) {}\n      }\n\n      // Investigate the following in order to handle multi line selections\n      // rangeBottom = rangeTop + (rangeHeight ? (rangeHeight - 1) : 0);\n      rangeBottom = rangeTop;\n      rangeEnd = this.doc.selection.createRange();\n      for (j=scrollWidth; j>=0; j--) {\n        try {\n          rangeEnd.moveToPoint(j, rangeBottom);\n          break;\n        } catch(e2) {}\n      }\n\n      range.setEndPoint(\"EndToEnd\", rangeEnd);\n      range.select();\n    },\n\n    getText: function() {\n      var selection = this.getSelection();\n      return selection ? selection.toString() : \"\";\n    },\n\n    getNodes: function(nodeType, filter) {\n      var range = this.getRange();\n      if (range) {\n        return range.getNodes([nodeType], filter);\n      } else {\n        return [];\n      }\n    },\n\n    fixRangeOverflow: function(range) {\n      if (this.contain && this.contain.firstChild && range) {\n        var containment = range.compareNode(this.contain);\n        if (containment !== 2) {\n          if (containment === 1) {\n            range.setStartBefore(this.contain.firstChild);\n          }\n          if (containment === 0) {\n            range.setEndAfter(this.contain.lastChild);\n          }\n          if (containment === 3) {\n            range.setStartBefore(this.contain.firstChild);\n            range.setEndAfter(this.contain.lastChild);\n          }\n        } else if (this._detectInlineRangeProblems(range)) {\n          var previousElementSibling = range.endContainer.previousElementSibling;\n          if (previousElementSibling) {\n            range.setEnd(previousElementSibling, this._endOffsetForNode(previousElementSibling));\n          }\n        }\n      }\n    },\n\n    _endOffsetForNode: function(node) {\n      var range = document.createRange();\n      range.selectNodeContents(node);\n      return range.endOffset;\n    },\n\n    _detectInlineRangeProblems: function(range) {\n      var position = dom.compareDocumentPosition(range.startContainer, range.endContainer);\n      return (\n        range.endOffset == 0 &&\n        position & 4 //Node.DOCUMENT_POSITION_FOLLOWING\n      );\n    },\n\n    getRange: function(dontFix) {\n      var selection = this.getSelection(),\n          range = selection && selection.rangeCount && selection.getRangeAt(0);\n\n      if (dontFix !== true) {\n        this.fixRangeOverflow(range);\n      }\n\n      return range;\n    },\n\n    getOwnUneditables: function() {\n      var allUneditables = dom.query(this.contain, '.' + this.unselectableClass),\n          deepUneditables = dom.query(allUneditables, '.' + this.unselectableClass);\n\n      return wysihtml5.lang.array(allUneditables).without(deepUneditables);\n    },\n\n    // Returns an array of ranges that belong only to this editable\n    // Needed as uneditable block in contenteditabel can split range into pieces\n    // If manipulating content reverse loop is usually needed as manipulation can shift subsequent ranges\n    getOwnRanges: function()  {\n      var ranges = [],\n          r = this.getRange(),\n          tmpRanges;\n\n      if (r) { ranges.push(r); }\n\n      if (this.unselectableClass && this.contain && r) {\n          var uneditables = this.getOwnUneditables(),\n              tmpRange;\n          if (uneditables.length > 0) {\n            for (var i = 0, imax = uneditables.length; i < imax; i++) {\n              tmpRanges = [];\n              for (var j = 0, jmax = ranges.length; j < jmax; j++) {\n                if (ranges[j]) {\n                  switch (ranges[j].compareNode(uneditables[i])) {\n                    case 2:\n                      // all selection inside uneditable. remove\n                    break;\n                    case 3:\n                      //section begins before and ends after uneditable. spilt\n                      tmpRange = ranges[j].cloneRange();\n                      tmpRange.setEndBefore(uneditables[i]);\n                      tmpRanges.push(tmpRange);\n\n                      tmpRange = ranges[j].cloneRange();\n                      tmpRange.setStartAfter(uneditables[i]);\n                      tmpRanges.push(tmpRange);\n                    break;\n                    default:\n                      // in all other cases uneditable does not touch selection. dont modify\n                      tmpRanges.push(ranges[j]);\n                  }\n                }\n                ranges = tmpRanges;\n              }\n            }\n          }\n      }\n      return ranges;\n    },\n\n    getSelection: function() {\n      return rangy.getSelection(this.doc.defaultView || this.doc.parentWindow);\n    },\n\n    setSelection: function(range) {\n      var win       = this.doc.defaultView || this.doc.parentWindow,\n          selection = rangy.getSelection(win);\n      return selection.setSingleRange(range);\n    },\n\n    createRange: function() {\n      return rangy.createRange(this.doc);\n    },\n\n    isCollapsed: function() {\n        return this.getSelection().isCollapsed;\n    },\n\n    getHtml: function() {\n      return this.getSelection().toHtml();\n    },\n\n    isEndToEndInNode: function(nodeNames) {\n      var range = this.getRange(),\n          parentElement = range.commonAncestorContainer,\n          startNode = range.startContainer,\n          endNode = range.endContainer;\n\n\n        if (parentElement.nodeType === wysihtml5.TEXT_NODE) {\n          parentElement = parentElement.parentNode;\n        }\n\n        if (startNode.nodeType === wysihtml5.TEXT_NODE && !(/^\\s*$/).test(startNode.data.substr(range.startOffset))) {\n          return false;\n        }\n\n        if (endNode.nodeType === wysihtml5.TEXT_NODE && !(/^\\s*$/).test(endNode.data.substr(range.endOffset))) {\n          return false;\n        }\n\n        while (startNode && startNode !== parentElement) {\n          if (startNode.nodeType !== wysihtml5.TEXT_NODE && !wysihtml5.dom.contains(parentElement, startNode)) {\n            return false;\n          }\n          if (wysihtml5.dom.domNode(startNode).prev({ignoreBlankTexts: true})) {\n            return false;\n          }\n          startNode = startNode.parentNode;\n        }\n\n        while (endNode && endNode !== parentElement) {\n          if (endNode.nodeType !== wysihtml5.TEXT_NODE && !wysihtml5.dom.contains(parentElement, endNode)) {\n            return false;\n          }\n          if (wysihtml5.dom.domNode(endNode).next({ignoreBlankTexts: true})) {\n            return false;\n          }\n          endNode = endNode.parentNode;\n        }\n\n        return (wysihtml5.lang.array(nodeNames).contains(parentElement.nodeName)) ? parentElement : false;\n    },\n\n    deselect: function() {\n      var sel = this.getSelection();\n      sel && sel.removeAllRanges();\n    }\n  });\n\n})(wysihtml5);\n;/**\n * Inspired by the rangy CSS Applier module written by Tim Down and licensed under the MIT license.\n * http://code.google.com/p/rangy/\n *\n * changed in order to be able ...\n *    - to use custom tags\n *    - to detect and replace similar css classes via reg exp\n */\n(function(wysihtml5, rangy) {\n  var defaultTagName = \"span\";\n\n  var REG_EXP_WHITE_SPACE = /\\s+/g;\n\n  function hasClass(el, cssClass, regExp) {\n    if (!el.className) {\n      return false;\n    }\n\n    var matchingClassNames = el.className.match(regExp) || [];\n    return matchingClassNames[matchingClassNames.length - 1] === cssClass;\n  }\n\n  function hasStyleAttr(el, regExp) {\n    if (!el.getAttribute || !el.getAttribute('style')) {\n      return false;\n    }\n    var matchingStyles = el.getAttribute('style').match(regExp);\n    return  (el.getAttribute('style').match(regExp)) ? true : false;\n  }\n\n  function addStyle(el, cssStyle, regExp) {\n    if (el.getAttribute('style')) {\n      removeStyle(el, regExp);\n      if (el.getAttribute('style') && !(/^\\s*$/).test(el.getAttribute('style'))) {\n        el.setAttribute('style', cssStyle + \";\" + el.getAttribute('style'));\n      } else {\n        el.setAttribute('style', cssStyle);\n      }\n    } else {\n      el.setAttribute('style', cssStyle);\n    }\n  }\n\n  function addClass(el, cssClass, regExp) {\n    if (el.className) {\n      removeClass(el, regExp);\n      el.className += \" \" + cssClass;\n    } else {\n      el.className = cssClass;\n    }\n  }\n\n  function removeClass(el, regExp) {\n    if (el.className) {\n      el.className = el.className.replace(regExp, \"\");\n    }\n  }\n\n  function removeStyle(el, regExp) {\n    var s,\n        s2 = [];\n    if (el.getAttribute('style')) {\n      s = el.getAttribute('style').split(';');\n      for (var i = s.length; i--;) {\n        if (!s[i].match(regExp) && !(/^\\s*$/).test(s[i])) {\n          s2.push(s[i]);\n        }\n      }\n      if (s2.length) {\n        el.setAttribute('style', s2.join(';'));\n      } else {\n        el.removeAttribute('style');\n      }\n    }\n  }\n\n  function getMatchingStyleRegexp(el, style) {\n    var regexes = [],\n        sSplit = style.split(';'),\n        elStyle = el.getAttribute('style');\n\n    if (elStyle) {\n      elStyle = elStyle.replace(/\\s/gi, '').toLowerCase();\n      regexes.push(new RegExp(\"(^|\\\\s|;)\" + style.replace(/\\s/gi, '').replace(/([\\(\\)])/gi, \"\\\\$1\").toLowerCase().replace(\";\", \";?\").replace(/rgb\\\\\\((\\d+),(\\d+),(\\d+)\\\\\\)/gi, \"\\\\s?rgb\\\\($1,\\\\s?$2,\\\\s?$3\\\\)\"), \"gi\"));\n\n      for (var i = sSplit.length; i-- > 0;) {\n        if (!(/^\\s*$/).test(sSplit[i])) {\n          regexes.push(new RegExp(\"(^|\\\\s|;)\" + sSplit[i].replace(/\\s/gi, '').replace(/([\\(\\)])/gi, \"\\\\$1\").toLowerCase().replace(\";\", \";?\").replace(/rgb\\\\\\((\\d+),(\\d+),(\\d+)\\\\\\)/gi, \"\\\\s?rgb\\\\($1,\\\\s?$2,\\\\s?$3\\\\)\"), \"gi\"));\n        }\n      }\n      for (var j = 0, jmax = regexes.length; j < jmax; j++) {\n        if (elStyle.match(regexes[j])) {\n          return regexes[j];\n        }\n      }\n    }\n\n    return false;\n  }\n\n  function isMatchingAllready(node, tags, style, className) {\n    if (style) {\n      return getMatchingStyleRegexp(node, style);\n    } else if (className) {\n      return wysihtml5.dom.hasClass(node, className);\n    } else {\n      return rangy.dom.arrayContains(tags, node.tagName.toLowerCase());\n    }\n  }\n\n  function areMatchingAllready(nodes, tags, style, className) {\n    for (var i = nodes.length; i--;) {\n      if (!isMatchingAllready(nodes[i], tags, style, className)) {\n        return false;\n      }\n    }\n    return nodes.length ? true : false;\n  }\n\n  function removeOrChangeStyle(el, style, regExp) {\n\n    var exactRegex = getMatchingStyleRegexp(el, style);\n    if (exactRegex) {\n      // adding same style value on property again removes style\n      removeStyle(el, exactRegex);\n      return \"remove\";\n    } else {\n      // adding new style value changes value\n      addStyle(el, style, regExp);\n      return \"change\";\n    }\n  }\n\n  function hasSameClasses(el1, el2) {\n    return el1.className.replace(REG_EXP_WHITE_SPACE, \" \") == el2.className.replace(REG_EXP_WHITE_SPACE, \" \");\n  }\n\n  function replaceWithOwnChildren(el) {\n    var parent = el.parentNode;\n    while (el.firstChild) {\n      parent.insertBefore(el.firstChild, el);\n    }\n    parent.removeChild(el);\n  }\n\n  function elementsHaveSameNonClassAttributes(el1, el2) {\n    if (el1.attributes.length != el2.attributes.length) {\n      return false;\n    }\n    for (var i = 0, len = el1.attributes.length, attr1, attr2, name; i < len; ++i) {\n      attr1 = el1.attributes[i];\n      name = attr1.name;\n      if (name != \"class\") {\n        attr2 = el2.attributes.getNamedItem(name);\n        if (attr1.specified != attr2.specified) {\n          return false;\n        }\n        if (attr1.specified && attr1.nodeValue !== attr2.nodeValue) {\n          return false;\n        }\n      }\n    }\n    return true;\n  }\n\n  function isSplitPoint(node, offset) {\n    if (rangy.dom.isCharacterDataNode(node)) {\n      if (offset == 0) {\n        return !!node.previousSibling;\n      } else if (offset == node.length) {\n        return !!node.nextSibling;\n      } else {\n        return true;\n      }\n    }\n\n    return offset > 0 && offset < node.childNodes.length;\n  }\n\n  function splitNodeAt(node, descendantNode, descendantOffset, container) {\n    var newNode;\n    if (rangy.dom.isCharacterDataNode(descendantNode)) {\n      if (descendantOffset == 0) {\n        descendantOffset = rangy.dom.getNodeIndex(descendantNode);\n        descendantNode = descendantNode.parentNode;\n      } else if (descendantOffset == descendantNode.length) {\n        descendantOffset = rangy.dom.getNodeIndex(descendantNode) + 1;\n        descendantNode = descendantNode.parentNode;\n      } else {\n        newNode = rangy.dom.splitDataNode(descendantNode, descendantOffset);\n      }\n    }\n    if (!newNode) {\n      if (!container || descendantNode !== container) {\n\n        newNode = descendantNode.cloneNode(false);\n        if (newNode.id) {\n          newNode.removeAttribute(\"id\");\n        }\n        var child;\n        while ((child = descendantNode.childNodes[descendantOffset])) {\n          newNode.appendChild(child);\n        }\n        rangy.dom.insertAfter(newNode, descendantNode);\n\n      }\n    }\n    return (descendantNode == node) ? newNode :  splitNodeAt(node, newNode.parentNode, rangy.dom.getNodeIndex(newNode), container);\n  }\n\n  function Merge(firstNode) {\n    this.isElementMerge = (firstNode.nodeType == wysihtml5.ELEMENT_NODE);\n    this.firstTextNode = this.isElementMerge ? firstNode.lastChild : firstNode;\n    this.textNodes = [this.firstTextNode];\n  }\n\n  Merge.prototype = {\n    doMerge: function() {\n      var textBits = [], textNode, parent, text;\n      for (var i = 0, len = this.textNodes.length; i < len; ++i) {\n        textNode = this.textNodes[i];\n        parent = textNode.parentNode;\n        textBits[i] = textNode.data;\n        if (i) {\n          parent.removeChild(textNode);\n          if (!parent.hasChildNodes()) {\n            parent.parentNode.removeChild(parent);\n          }\n        }\n      }\n      this.firstTextNode.data = text = textBits.join(\"\");\n      return text;\n    },\n\n    getLength: function() {\n      var i = this.textNodes.length, len = 0;\n      while (i--) {\n        len += this.textNodes[i].length;\n      }\n      return len;\n    },\n\n    toString: function() {\n      var textBits = [];\n      for (var i = 0, len = this.textNodes.length; i < len; ++i) {\n        textBits[i] = \"'\" + this.textNodes[i].data + \"'\";\n      }\n      return \"[Merge(\" + textBits.join(\",\") + \")]\";\n    }\n  };\n\n  function HTMLApplier(tagNames, cssClass, similarClassRegExp, normalize, cssStyle, similarStyleRegExp, container) {\n    this.tagNames = tagNames || [defaultTagName];\n    this.cssClass = cssClass || ((cssClass === false) ? false : \"\");\n    this.similarClassRegExp = similarClassRegExp;\n    this.cssStyle = cssStyle || \"\";\n    this.similarStyleRegExp = similarStyleRegExp;\n    this.normalize = normalize;\n    this.applyToAnyTagName = false;\n    this.container = container;\n  }\n\n  HTMLApplier.prototype = {\n    getAncestorWithClass: function(node) {\n      var cssClassMatch;\n      while (node) {\n        cssClassMatch = this.cssClass ? hasClass(node, this.cssClass, this.similarClassRegExp) : (this.cssStyle !== \"\") ? false : true;\n        if (node.nodeType == wysihtml5.ELEMENT_NODE && node.getAttribute(\"contenteditable\") != \"false\" &&  rangy.dom.arrayContains(this.tagNames, node.tagName.toLowerCase()) && cssClassMatch) {\n          return node;\n        }\n        node = node.parentNode;\n      }\n      return false;\n    },\n\n    // returns parents of node with given style attribute\n    getAncestorWithStyle: function(node) {\n      var cssStyleMatch;\n      while (node) {\n        cssStyleMatch = this.cssStyle ? hasStyleAttr(node, this.similarStyleRegExp) : false;\n\n        if (node.nodeType == wysihtml5.ELEMENT_NODE && node.getAttribute(\"contenteditable\") != \"false\" && rangy.dom.arrayContains(this.tagNames, node.tagName.toLowerCase()) && cssStyleMatch) {\n          return node;\n        }\n        node = node.parentNode;\n      }\n      return false;\n    },\n\n    getMatchingAncestor: function(node) {\n      var ancestor = this.getAncestorWithClass(node),\n          matchType = false;\n\n      if (!ancestor) {\n        ancestor = this.getAncestorWithStyle(node);\n        if (ancestor) {\n          matchType = \"style\";\n        }\n      } else {\n        if (this.cssStyle) {\n          matchType = \"class\";\n        }\n      }\n\n      return {\n        \"element\": ancestor,\n        \"type\": matchType\n      };\n    },\n\n    // Normalizes nodes after applying a CSS class to a Range.\n    postApply: function(textNodes, range) {\n      var firstNode = textNodes[0], lastNode = textNodes[textNodes.length - 1];\n\n      var merges = [], currentMerge;\n\n      var rangeStartNode = firstNode, rangeEndNode = lastNode;\n      var rangeStartOffset = 0, rangeEndOffset = lastNode.length;\n\n      var textNode, precedingTextNode;\n\n      for (var i = 0, len = textNodes.length; i < len; ++i) {\n        textNode = textNodes[i];\n        precedingTextNode = null;\n        if (textNode && textNode.parentNode) {\n          precedingTextNode = this.getAdjacentMergeableTextNode(textNode.parentNode, false);\n        }\n        if (precedingTextNode) {\n          if (!currentMerge) {\n            currentMerge = new Merge(precedingTextNode);\n            merges.push(currentMerge);\n          }\n          currentMerge.textNodes.push(textNode);\n          if (textNode === firstNode) {\n            rangeStartNode = currentMerge.firstTextNode;\n            rangeStartOffset = rangeStartNode.length;\n          }\n          if (textNode === lastNode) {\n            rangeEndNode = currentMerge.firstTextNode;\n            rangeEndOffset = currentMerge.getLength();\n          }\n        } else {\n          currentMerge = null;\n        }\n      }\n      // Test whether the first node after the range needs merging\n      if(lastNode && lastNode.parentNode) {\n        var nextTextNode = this.getAdjacentMergeableTextNode(lastNode.parentNode, true);\n        if (nextTextNode) {\n          if (!currentMerge) {\n            currentMerge = new Merge(lastNode);\n            merges.push(currentMerge);\n          }\n          currentMerge.textNodes.push(nextTextNode);\n        }\n      }\n      // Do the merges\n      if (merges.length) {\n        for (i = 0, len = merges.length; i < len; ++i) {\n          merges[i].doMerge();\n        }\n        // Set the range boundaries\n        range.setStart(rangeStartNode, rangeStartOffset);\n        range.setEnd(rangeEndNode, rangeEndOffset);\n      }\n    },\n\n    getAdjacentMergeableTextNode: function(node, forward) {\n        var isTextNode = (node.nodeType == wysihtml5.TEXT_NODE);\n        var el = isTextNode ? node.parentNode : node;\n        var adjacentNode;\n        var propName = forward ? \"nextSibling\" : \"previousSibling\";\n        if (isTextNode) {\n          // Can merge if the node's previous/next sibling is a text node\n          adjacentNode = node[propName];\n          if (adjacentNode && adjacentNode.nodeType == wysihtml5.TEXT_NODE) {\n            return adjacentNode;\n          }\n        } else {\n          // Compare element with its sibling\n          adjacentNode = el[propName];\n          if (adjacentNode && this.areElementsMergeable(node, adjacentNode)) {\n            return adjacentNode[forward ? \"firstChild\" : \"lastChild\"];\n          }\n        }\n        return null;\n    },\n\n    areElementsMergeable: function(el1, el2) {\n      return rangy.dom.arrayContains(this.tagNames, (el1.tagName || \"\").toLowerCase())\n        && rangy.dom.arrayContains(this.tagNames, (el2.tagName || \"\").toLowerCase())\n        && hasSameClasses(el1, el2)\n        && elementsHaveSameNonClassAttributes(el1, el2);\n    },\n\n    createContainer: function(doc) {\n      var el = doc.createElement(this.tagNames[0]);\n      if (this.cssClass) {\n        el.className = this.cssClass;\n      }\n      if (this.cssStyle) {\n        el.setAttribute('style', this.cssStyle);\n      }\n      return el;\n    },\n\n    applyToTextNode: function(textNode) {\n      var parent = textNode.parentNode;\n      if (parent.childNodes.length == 1 && rangy.dom.arrayContains(this.tagNames, parent.tagName.toLowerCase())) {\n\n        if (this.cssClass) {\n          addClass(parent, this.cssClass, this.similarClassRegExp);\n        }\n        if (this.cssStyle) {\n          addStyle(parent, this.cssStyle, this.similarStyleRegExp);\n        }\n      } else {\n        var el = this.createContainer(rangy.dom.getDocument(textNode));\n        textNode.parentNode.insertBefore(el, textNode);\n        el.appendChild(textNode);\n      }\n    },\n\n    isRemovable: function(el) {\n      return rangy.dom.arrayContains(this.tagNames, el.tagName.toLowerCase()) &&\n              wysihtml5.lang.string(el.className).trim() === \"\" &&\n              (\n                !el.getAttribute('style') ||\n                wysihtml5.lang.string(el.getAttribute('style')).trim() === \"\"\n              );\n    },\n\n    undoToTextNode: function(textNode, range, ancestorWithClass, ancestorWithStyle) {\n      var styleMode = (ancestorWithClass) ? false : true,\n          ancestor = ancestorWithClass || ancestorWithStyle,\n          styleChanged = false;\n      if (!range.containsNode(ancestor)) {\n        // Split out the portion of the ancestor from which we can remove the CSS class\n        var ancestorRange = range.cloneRange();\n            ancestorRange.selectNode(ancestor);\n\n        if (ancestorRange.isPointInRange(range.endContainer, range.endOffset) && isSplitPoint(range.endContainer, range.endOffset)) {\n            splitNodeAt(ancestor, range.endContainer, range.endOffset, this.container);\n            range.setEndAfter(ancestor);\n        }\n        if (ancestorRange.isPointInRange(range.startContainer, range.startOffset) && isSplitPoint(range.startContainer, range.startOffset)) {\n            ancestor = splitNodeAt(ancestor, range.startContainer, range.startOffset, this.container);\n        }\n      }\n\n      if (!styleMode && this.similarClassRegExp) {\n        removeClass(ancestor, this.similarClassRegExp);\n      }\n\n      if (styleMode && this.similarStyleRegExp) {\n        styleChanged = (removeOrChangeStyle(ancestor, this.cssStyle, this.similarStyleRegExp) === \"change\");\n      }\n      if (this.isRemovable(ancestor) && !styleChanged) {\n        replaceWithOwnChildren(ancestor);\n      }\n    },\n\n    applyToRange: function(range) {\n        var textNodes;\n        for (var ri = range.length; ri--;) {\n            textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);\n\n            if (!textNodes.length) {\n              try {\n                var node = this.createContainer(range[ri].endContainer.ownerDocument);\n                range[ri].surroundContents(node);\n                this.selectNode(range[ri], node);\n                return;\n              } catch(e) {}\n            }\n\n            range[ri].splitBoundaries();\n            textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);\n            if (textNodes.length) {\n              var textNode;\n\n              for (var i = 0, len = textNodes.length; i < len; ++i) {\n                textNode = textNodes[i];\n                if (!this.getMatchingAncestor(textNode).element) {\n                  this.applyToTextNode(textNode);\n                }\n              }\n\n              range[ri].setStart(textNodes[0], 0);\n              textNode = textNodes[textNodes.length - 1];\n              range[ri].setEnd(textNode, textNode.length);\n\n              if (this.normalize) {\n                this.postApply(textNodes, range[ri]);\n              }\n            }\n\n        }\n    },\n\n    undoToRange: function(range) {\n      var textNodes, textNode, ancestorWithClass, ancestorWithStyle, ancestor;\n      for (var ri = range.length; ri--;) {\n\n          textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);\n          if (textNodes.length) {\n            range[ri].splitBoundaries();\n            textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);\n          } else {\n            var doc = range[ri].endContainer.ownerDocument,\n                node = doc.createTextNode(wysihtml5.INVISIBLE_SPACE);\n            range[ri].insertNode(node);\n            range[ri].selectNode(node);\n            textNodes = [node];\n          }\n\n          for (var i = 0, len = textNodes.length; i < len; ++i) {\n            if (range[ri].isValid()) {\n              textNode = textNodes[i];\n\n              ancestor = this.getMatchingAncestor(textNode);\n              if (ancestor.type === \"style\") {\n                this.undoToTextNode(textNode, range[ri], false, ancestor.element);\n              } else if (ancestor.element) {\n                this.undoToTextNode(textNode, range[ri], ancestor.element);\n              }\n            }\n          }\n\n          if (len == 1) {\n            this.selectNode(range[ri], textNodes[0]);\n          } else {\n            range[ri].setStart(textNodes[0], 0);\n            textNode = textNodes[textNodes.length - 1];\n            range[ri].setEnd(textNode, textNode.length);\n\n            if (this.normalize) {\n              this.postApply(textNodes, range[ri]);\n            }\n          }\n\n      }\n    },\n\n    selectNode: function(range, node) {\n      var isElement       = node.nodeType === wysihtml5.ELEMENT_NODE,\n          canHaveHTML     = \"canHaveHTML\" in node ? node.canHaveHTML : true,\n          content         = isElement ? node.innerHTML : node.data,\n          isEmpty         = (content === \"\" || content === wysihtml5.INVISIBLE_SPACE);\n\n      if (isEmpty && isElement && canHaveHTML) {\n        // Make sure that caret is visible in node by inserting a zero width no breaking space\n        try { node.innerHTML = wysihtml5.INVISIBLE_SPACE; } catch(e) {}\n      }\n      range.selectNodeContents(node);\n      if (isEmpty && isElement) {\n        range.collapse(false);\n      } else if (isEmpty) {\n        range.setStartAfter(node);\n        range.setEndAfter(node);\n      }\n    },\n\n    getTextSelectedByRange: function(textNode, range) {\n      var textRange = range.cloneRange();\n      textRange.selectNodeContents(textNode);\n\n      var intersectionRange = textRange.intersection(range);\n      var text = intersectionRange ? intersectionRange.toString() : \"\";\n      textRange.detach();\n\n      return text;\n    },\n\n    isAppliedToRange: function(range) {\n      var ancestors = [],\n          appliedType = \"full\",\n          ancestor, styleAncestor, textNodes;\n\n      for (var ri = range.length; ri--;) {\n\n        textNodes = range[ri].getNodes([wysihtml5.TEXT_NODE]);\n        if (!textNodes.length) {\n          ancestor = this.getMatchingAncestor(range[ri].startContainer).element;\n\n          return (ancestor) ? {\n            \"elements\": [ancestor],\n            \"coverage\": appliedType\n          } : false;\n        }\n\n        for (var i = 0, len = textNodes.length, selectedText; i < len; ++i) {\n          selectedText = this.getTextSelectedByRange(textNodes[i], range[ri]);\n          ancestor = this.getMatchingAncestor(textNodes[i]).element;\n          if (ancestor && selectedText != \"\") {\n            ancestors.push(ancestor);\n\n            if (wysihtml5.dom.getTextNodes(ancestor, true).length === 1) {\n              appliedType = \"full\";\n            } else if (appliedType === \"full\") {\n              appliedType = \"inline\";\n            }\n          } else if (!ancestor) {\n            appliedType = \"partial\";\n          }\n        }\n\n      }\n\n      return (ancestors.length) ? {\n        \"elements\": ancestors,\n        \"coverage\": appliedType\n      } : false;\n    },\n\n    toggleRange: function(range) {\n      var isApplied = this.isAppliedToRange(range),\n          parentsExactMatch;\n\n      if (isApplied) {\n        if (isApplied.coverage === \"full\") {\n          this.undoToRange(range);\n        } else if (isApplied.coverage === \"inline\") {\n          parentsExactMatch = areMatchingAllready(isApplied.elements, this.tagNames, this.cssStyle, this.cssClass);\n          this.undoToRange(range);\n          if (!parentsExactMatch) {\n            this.applyToRange(range);\n          }\n        } else {\n          // partial\n          if (!areMatchingAllready(isApplied.elements, this.tagNames, this.cssStyle, this.cssClass)) {\n            this.undoToRange(range);\n          }\n          this.applyToRange(range);\n        }\n      } else {\n        this.applyToRange(range);\n      }\n    }\n  };\n\n  wysihtml5.selection.HTMLApplier = HTMLApplier;\n\n})(wysihtml5, rangy);\n;/**\n * Rich Text Query/Formatting Commands\n *\n * @example\n *    var commands = new wysihtml5.Commands(editor);\n */\nwysihtml5.Commands = Base.extend(\n  /** @scope wysihtml5.Commands.prototype */ {\n  constructor: function(editor) {\n    this.editor   = editor;\n    this.composer = editor.composer;\n    this.doc      = this.composer.doc;\n  },\n\n  /**\n   * Check whether the browser supports the given command\n   *\n   * @param {String} command The command string which to check (eg. \"bold\", \"italic\", \"insertUnorderedList\")\n   * @example\n   *    commands.supports(\"createLink\");\n   */\n  support: function(command) {\n    return wysihtml5.browser.supportsCommand(this.doc, command);\n  },\n\n  /**\n   * Check whether the browser supports the given command\n   *\n   * @param {String} command The command string which to execute (eg. \"bold\", \"italic\", \"insertUnorderedList\")\n   * @param {String} [value] The command value parameter, needed for some commands (\"createLink\", \"insertImage\", ...), optional for commands that don't require one (\"bold\", \"underline\", ...)\n   * @example\n   *    commands.exec(\"insertImage\", \"http://a1.twimg.com/profile_images/113868655/schrei_twitter_reasonably_small.jpg\");\n   */\n  exec: function(command, value) {\n    var obj     = wysihtml5.commands[command],\n        args    = wysihtml5.lang.array(arguments).get(),\n        method  = obj && obj.exec,\n        result  = null;\n\n    this.editor.fire(\"beforecommand:composer\");\n\n    if (method) {\n      args.unshift(this.composer);\n      result = method.apply(obj, args);\n    } else {\n      try {\n        // try/catch for buggy firefox\n        result = this.doc.execCommand(command, false, value);\n      } catch(e) {}\n    }\n\n    this.editor.fire(\"aftercommand:composer\");\n    return result;\n  },\n\n  /**\n   * Check whether the current command is active\n   * If the caret is within a bold text, then calling this with command \"bold\" should return true\n   *\n   * @param {String} command The command string which to check (eg. \"bold\", \"italic\", \"insertUnorderedList\")\n   * @param {String} [commandValue] The command value parameter (eg. for \"insertImage\" the image src)\n   * @return {Boolean} Whether the command is active\n   * @example\n   *    var isCurrentSelectionBold = commands.state(\"bold\");\n   */\n  state: function(command, commandValue) {\n    var obj     = wysihtml5.commands[command],\n        args    = wysihtml5.lang.array(arguments).get(),\n        method  = obj && obj.state;\n    if (method) {\n      args.unshift(this.composer);\n      return method.apply(obj, args);\n    } else {\n      try {\n        // try/catch for buggy firefox\n        return this.doc.queryCommandState(command);\n      } catch(e) {\n        return false;\n      }\n    }\n  },\n\n  /* Get command state parsed value if command has stateValue parsing function */\n  stateValue: function(command) {\n    var obj     = wysihtml5.commands[command],\n        args    = wysihtml5.lang.array(arguments).get(),\n        method  = obj && obj.stateValue;\n    if (method) {\n      args.unshift(this.composer);\n      return method.apply(obj, args);\n    } else {\n      return false;\n    }\n  }\n});\n;wysihtml5.commands.bold = {\n  exec: function(composer, command) {\n    wysihtml5.commands.formatInline.execWithToggle(composer, command, \"b\");\n  },\n\n  state: function(composer, command) {\n    // element.ownerDocument.queryCommandState(\"bold\") results:\n    // firefox: only <b>\n    // chrome:  <b>, <strong>, <h1>, <h2>, ...\n    // ie:      <b>, <strong>\n    // opera:   <b>, <strong>\n    return wysihtml5.commands.formatInline.state(composer, command, \"b\");\n  }\n};\n\n;(function(wysihtml5) {\n  var undef,\n      NODE_NAME = \"A\",\n      dom       = wysihtml5.dom;\n\n  function _format(composer, attributes) {\n    var doc             = composer.doc,\n        tempClass       = \"_wysihtml5-temp-\" + (+new Date()),\n        tempClassRegExp = /non-matching-class/g,\n        i               = 0,\n        length,\n        anchors,\n        anchor,\n        hasElementChild,\n        isEmpty,\n        elementToSetCaretAfter,\n        textContent,\n        whiteSpace,\n        j;\n    wysihtml5.commands.formatInline.exec(composer, undef, NODE_NAME, tempClass, tempClassRegExp, undef, undef, true, true);\n    anchors = doc.querySelectorAll(NODE_NAME + \".\" + tempClass);\n    length  = anchors.length;\n    for (; i<length; i++) {\n      anchor = anchors[i];\n      anchor.removeAttribute(\"class\");\n      for (j in attributes) {\n        // Do not set attribute \"text\" as it is meant for setting string value if created link has no textual data\n        if (j !== \"text\") {\n          anchor.setAttribute(j, attributes[j]);\n        }\n      }\n    }\n\n    elementToSetCaretAfter = anchor;\n    if (length === 1) {\n      textContent = dom.getTextContent(anchor);\n      hasElementChild = !!anchor.querySelector(\"*\");\n      isEmpty = textContent === \"\" || textContent === wysihtml5.INVISIBLE_SPACE;\n      if (!hasElementChild && isEmpty) {\n        dom.setTextContent(anchor, attributes.text || anchor.href);\n        whiteSpace = doc.createTextNode(\" \");\n        composer.selection.setAfter(anchor);\n        dom.insert(whiteSpace).after(anchor);\n        elementToSetCaretAfter = whiteSpace;\n      }\n    }\n    composer.selection.setAfter(elementToSetCaretAfter);\n  }\n\n  // Changes attributes of links\n  function _changeLinks(composer, anchors, attributes) {\n    var oldAttrs;\n    for (var a = anchors.length; a--;) {\n\n      // Remove all old attributes\n      oldAttrs = anchors[a].attributes;\n      for (var oa = oldAttrs.length; oa--;) {\n        anchors[a].removeAttribute(oldAttrs.item(oa).name);\n      }\n\n      // Set new attributes\n      for (var j in attributes) {\n        if (attributes.hasOwnProperty(j)) {\n          anchors[a].setAttribute(j, attributes[j]);\n        }\n      }\n\n    }\n  }\n\n  wysihtml5.commands.createLink = {\n    /**\n     * TODO: Use HTMLApplier or formatInline here\n     *\n     * Turns selection into a link\n     * If selection is already a link, it just changes the attributes\n     *\n     * @example\n     *    // either ...\n     *    wysihtml5.commands.createLink.exec(composer, \"createLink\", \"http://www.google.de\");\n     *    // ... or ...\n     *    wysihtml5.commands.createLink.exec(composer, \"createLink\", { href: \"http://www.google.de\", target: \"_blank\" });\n     */\n    exec: function(composer, command, value) {\n      var anchors = this.state(composer, command);\n      if (anchors) {\n        // Selection contains links then change attributes of these links\n        composer.selection.executeAndRestore(function() {\n          _changeLinks(composer, anchors, value);\n        });\n      } else {\n        // Create links\n        value = typeof(value) === \"object\" ? value : { href: value };\n        _format(composer, value);\n      }\n    },\n\n    state: function(composer, command) {\n      return wysihtml5.commands.formatInline.state(composer, command, \"A\");\n    }\n  };\n})(wysihtml5);\n;(function(wysihtml5) {\n  var dom = wysihtml5.dom;\n\n  function _removeFormat(composer, anchors) {\n    var length  = anchors.length,\n        i       = 0,\n        anchor,\n        codeElement,\n        textContent;\n    for (; i<length; i++) {\n      anchor      = anchors[i];\n      codeElement = dom.getParentElement(anchor, { nodeName: \"code\" });\n      textContent = dom.getTextContent(anchor);\n\n      // if <a> contains url-like text content, rename it to <code> to prevent re-autolinking\n      // else replace <a> with its childNodes\n      if (textContent.match(dom.autoLink.URL_REG_EXP) && !codeElement) {\n        // <code> element is used to prevent later auto-linking of the content\n        codeElement = dom.renameElement(anchor, \"code\");\n      } else {\n        dom.replaceWithChildNodes(anchor);\n      }\n    }\n  }\n\n  wysihtml5.commands.removeLink = {\n    /*\n     * If selection is a link, it removes the link and wraps it with a <code> element\n     * The <code> element is needed to avoid auto linking\n     *\n     * @example\n     *    wysihtml5.commands.createLink.exec(composer, \"removeLink\");\n     */\n\n    exec: function(composer, command) {\n      var anchors = this.state(composer, command);\n      if (anchors) {\n        composer.selection.executeAndRestore(function() {\n          _removeFormat(composer, anchors);\n        });\n      }\n    },\n\n    state: function(composer, command) {\n      return wysihtml5.commands.formatInline.state(composer, command, \"A\");\n    }\n  };\n})(wysihtml5);\n;/**\n * document.execCommand(\"fontSize\") will create either inline styles (firefox, chrome) or use font tags\n * which we don't want\n * Instead we set a css class\n */\n(function(wysihtml5) {\n  var REG_EXP = /wysiwyg-font-size-[0-9a-z\\-]+/g;\n\n  wysihtml5.commands.fontSize = {\n    exec: function(composer, command, size) {\n        wysihtml5.commands.formatInline.execWithToggle(composer, command, \"span\", \"wysiwyg-font-size-\" + size, REG_EXP);\n    },\n\n    state: function(composer, command, size) {\n      return wysihtml5.commands.formatInline.state(composer, command, \"span\", \"wysiwyg-font-size-\" + size, REG_EXP);\n    }\n  };\n})(wysihtml5);\n;/* In case font size adjustment to any number defined by user is preferred, we cannot use classes and must use inline styles. */\n(function(wysihtml5) {\n  var REG_EXP = /(\\s|^)font-size\\s*:\\s*[^;\\s]+;?/gi;\n\n  wysihtml5.commands.fontSizeStyle = {\n    exec: function(composer, command, size) {\n      size = (typeof(size) == \"object\") ? size.size : size;\n      if (!(/^\\s*$/).test(size)) {\n        wysihtml5.commands.formatInline.execWithToggle(composer, command, \"span\", false, false, \"font-size:\" + size, REG_EXP);\n      }\n    },\n\n    state: function(composer, command, size) {\n      return wysihtml5.commands.formatInline.state(composer, command, \"span\", false, false, \"font-size\", REG_EXP);\n    },\n\n    stateValue: function(composer, command) {\n      var st = this.state(composer, command),\n          styleStr, fontsizeMatches,\n          val = false;\n\n      if (st && wysihtml5.lang.object(st).isArray()) {\n          st = st[0];\n      }\n      if (st) {\n        styleStr = st.getAttribute('style');\n        if (styleStr) {\n          return wysihtml5.quirks.styleParser.parseFontSize(styleStr);\n        }\n      }\n      return false;\n    }\n  };\n})(wysihtml5);\n;/**\n * document.execCommand(\"foreColor\") will create either inline styles (firefox, chrome) or use font tags\n * which we don't want\n * Instead we set a css class\n */\n(function(wysihtml5) {\n  var REG_EXP = /wysiwyg-color-[0-9a-z]+/g;\n\n  wysihtml5.commands.foreColor = {\n    exec: function(composer, command, color) {\n        wysihtml5.commands.formatInline.execWithToggle(composer, command, \"span\", \"wysiwyg-color-\" + color, REG_EXP);\n    },\n\n    state: function(composer, command, color) {\n      return wysihtml5.commands.formatInline.state(composer, command, \"span\", \"wysiwyg-color-\" + color, REG_EXP);\n    }\n  };\n})(wysihtml5);\n;/**\n * document.execCommand(\"foreColor\") will create either inline styles (firefox, chrome) or use font tags\n * which we don't want\n * Instead we set a css class\n */\n(function(wysihtml5) {\n  var REG_EXP = /(\\s|^)color\\s*:\\s*[^;\\s]+;?/gi;\n\n  wysihtml5.commands.foreColorStyle = {\n    exec: function(composer, command, color) {\n      var colorVals  = wysihtml5.quirks.styleParser.parseColor((typeof(color) == \"object\") ? \"color:\" + color.color : \"color:\" + color, \"color\"),\n          colString;\n\n      if (colorVals) {\n        colString = \"color: rgb(\" + colorVals[0] + ',' + colorVals[1] + ',' + colorVals[2] + ');';\n        if (colorVals[3] !== 1) {\n          colString += \"color: rgba(\" + colorVals[0] + ',' + colorVals[1] + ',' + colorVals[2] + ',' + colorVals[3] + ');';\n        }\n        wysihtml5.commands.formatInline.execWithToggle(composer, command, \"span\", false, false, colString, REG_EXP);\n      }\n    },\n\n    state: function(composer, command) {\n      return wysihtml5.commands.formatInline.state(composer, command, \"span\", false, false, \"color\", REG_EXP);\n    },\n\n    stateValue: function(composer, command, props) {\n      var st = this.state(composer, command),\n          colorStr;\n\n      if (st && wysihtml5.lang.object(st).isArray()) {\n        st = st[0];\n      }\n\n      if (st) {\n        colorStr = st.getAttribute('style');\n        if (colorStr) {\n          if (colorStr) {\n            val = wysihtml5.quirks.styleParser.parseColor(colorStr, \"color\");\n            return wysihtml5.quirks.styleParser.unparseColor(val, props);\n          }\n        }\n      }\n      return false;\n    }\n\n  };\n})(wysihtml5);\n;/* In case background adjustment to any color defined by user is preferred, we cannot use classes and must use inline styles. */\n(function(wysihtml5) {\n  var REG_EXP = /(\\s|^)background-color\\s*:\\s*[^;\\s]+;?/gi;\n\n  wysihtml5.commands.bgColorStyle = {\n    exec: function(composer, command, color) {\n      var colorVals  = wysihtml5.quirks.styleParser.parseColor((typeof(color) == \"object\") ? \"background-color:\" + color.color : \"background-color:\" + color, \"background-color\"),\n          colString;\n\n      if (colorVals) {\n        colString = \"background-color: rgb(\" + colorVals[0] + ',' + colorVals[1] + ',' + colorVals[2] + ');';\n        if (colorVals[3] !== 1) {\n          colString += \"background-color: rgba(\" + colorVals[0] + ',' + colorVals[1] + ',' + colorVals[2] + ',' + colorVals[3] + ');';\n        }\n        wysihtml5.commands.formatInline.execWithToggle(composer, command, \"span\", false, false, colString, REG_EXP);\n      }\n    },\n\n    state: function(composer, command) {\n      return wysihtml5.commands.formatInline.state(composer, command, \"span\", false, false, \"background-color\", REG_EXP);\n    },\n\n    stateValue: function(composer, command, props) {\n      var st = this.state(composer, command),\n          colorStr,\n          val = false;\n\n      if (st && wysihtml5.lang.object(st).isArray()) {\n        st = st[0];\n      }\n\n      if (st) {\n        colorStr = st.getAttribute('style');\n        if (colorStr) {\n          val = wysihtml5.quirks.styleParser.parseColor(colorStr, \"background-color\");\n          return wysihtml5.quirks.styleParser.unparseColor(val, props);\n        }\n      }\n      return false;\n    }\n\n  };\n})(wysihtml5);\n;(function(wysihtml5) {\n  var dom                     = wysihtml5.dom,\n      // Following elements are grouped\n      // when the caret is within a H1 and the H4 is invoked, the H1 should turn into H4\n      // instead of creating a H4 within a H1 which would result in semantically invalid html\n      BLOCK_ELEMENTS_GROUP    = [\"H1\", \"H2\", \"H3\", \"H4\", \"H5\", \"H6\", \"P\", \"PRE\", \"DIV\"];\n\n  /**\n   * Remove similiar classes (based on classRegExp)\n   * and add the desired class name\n   */\n  function _addClass(element, className, classRegExp) {\n    if (element.className) {\n      _removeClass(element, classRegExp);\n      element.className = wysihtml5.lang.string(element.className + \" \" + className).trim();\n    } else {\n      element.className = className;\n    }\n  }\n\n  function _addStyle(element, cssStyle, styleRegExp) {\n    _removeStyle(element, styleRegExp);\n    if (element.getAttribute('style')) {\n      element.setAttribute('style', wysihtml5.lang.string(element.getAttribute('style') + \" \" + cssStyle).trim());\n    } else {\n      element.setAttribute('style', cssStyle);\n    }\n  }\n\n  function _removeClass(element, classRegExp) {\n    var ret = classRegExp.test(element.className);\n    element.className = element.className.replace(classRegExp, \"\");\n    if (wysihtml5.lang.string(element.className).trim() == '') {\n        element.removeAttribute('class');\n    }\n    return ret;\n  }\n\n  function _removeStyle(element, styleRegExp) {\n    var ret = styleRegExp.test(element.getAttribute('style'));\n    element.setAttribute('style', (element.getAttribute('style') || \"\").replace(styleRegExp, \"\"));\n    if (wysihtml5.lang.string(element.getAttribute('style') || \"\").trim() == '') {\n      element.removeAttribute('style');\n    }\n    return ret;\n  }\n\n  function _removeLastChildIfLineBreak(node) {\n    var lastChild = node.lastChild;\n    if (lastChild && _isLineBreak(lastChild)) {\n      lastChild.parentNode.removeChild(lastChild);\n    }\n  }\n\n  function _isLineBreak(node) {\n    return node.nodeName === \"BR\";\n  }\n\n  /**\n   * Execute native query command\n   * and if necessary modify the inserted node's className\n   */\n  function _execCommand(doc, composer, command, nodeName, className) {\n    var ranges = composer.selection.getOwnRanges();\n    for (var i = ranges.length; i--;){\n      composer.selection.getSelection().removeAllRanges();\n      composer.selection.setSelection(ranges[i]);\n      if (className) {\n        var eventListener = dom.observe(doc, \"DOMNodeInserted\", function(event) {\n          var target = event.target,\n              displayStyle;\n          if (target.nodeType !== wysihtml5.ELEMENT_NODE) {\n            return;\n          }\n          displayStyle = dom.getStyle(\"display\").from(target);\n          if (displayStyle.substr(0, 6) !== \"inline\") {\n            // Make sure that only block elements receive the given class\n            target.className += \" \" + className;\n          }\n        });\n      }\n      doc.execCommand(command, false, nodeName);\n\n      if (eventListener) {\n        eventListener.stop();\n      }\n    }\n  }\n\n  function _selectionWrap(composer, options) {\n    if (composer.selection.isCollapsed()) {\n        composer.selection.selectLine();\n    }\n\n    var surroundedNodes = composer.selection.surround(options);\n    for (var i = 0, imax = surroundedNodes.length; i < imax; i++) {\n      wysihtml5.dom.lineBreaks(surroundedNodes[i]).remove();\n      _removeLastChildIfLineBreak(surroundedNodes[i]);\n    }\n\n    // rethink restoring selection\n    // composer.selection.selectNode(element, wysihtml5.browser.displaysCaretInEmptyContentEditableCorrectly());\n  }\n\n  function _hasClasses(element) {\n    return !!wysihtml5.lang.string(element.className).trim();\n  }\n\n  function _hasStyles(element) {\n    return !!wysihtml5.lang.string(element.getAttribute('style') || '').trim();\n  }\n\n  wysihtml5.commands.formatBlock = {\n    exec: function(composer, command, nodeName, className, classRegExp, cssStyle, styleRegExp) {\n      var doc             = composer.doc,\n          blockElements    = this.state(composer, command, nodeName, className, classRegExp, cssStyle, styleRegExp),\n          useLineBreaks   = composer.config.useLineBreaks,\n          defaultNodeName = useLineBreaks ? \"DIV\" : \"P\",\n          selectedNodes, classRemoveAction, blockRenameFound, styleRemoveAction, blockElement;\n      nodeName = typeof(nodeName) === \"string\" ? nodeName.toUpperCase() : nodeName;\n\n      if (blockElements.length) {\n        composer.selection.executeAndRestoreRangy(function() {\n          for (var b = blockElements.length; b--;) {\n            if (classRegExp) {\n              classRemoveAction = _removeClass(blockElements[b], classRegExp);\n            }\n            if (styleRegExp) {\n              styleRemoveAction = _removeStyle(blockElements[b], styleRegExp);\n            }\n\n            if ((styleRemoveAction || classRemoveAction) && nodeName === null && blockElements[b].nodeName != defaultNodeName) {\n              // dont rename or remove element when just setting block formating class or style\n              return;\n            }\n\n            var hasClasses = _hasClasses(blockElements[b]),\n                hasStyles = _hasStyles(blockElements[b]);\n\n            if (!hasClasses && !hasStyles && (useLineBreaks || nodeName === \"P\")) {\n              // Insert a line break afterwards and beforewards when there are siblings\n              // that are not of type line break or block element\n              wysihtml5.dom.lineBreaks(blockElements[b]).add();\n              dom.replaceWithChildNodes(blockElements[b]);\n            } else {\n              // Make sure that styling is kept by renaming the element to a <div> or <p> and copying over the class name\n              dom.renameElement(blockElements[b], nodeName === \"P\" ? \"DIV\" : defaultNodeName);\n            }\n          }\n        });\n\n        return;\n      }\n\n      // Find similiar block element and rename it (<h2 class=\"foo\"></h2>  =>  <h1 class=\"foo\"></h1>)\n      if (nodeName === null || wysihtml5.lang.array(BLOCK_ELEMENTS_GROUP).contains(nodeName)) {\n        selectedNodes = composer.selection.findNodesInSelection(BLOCK_ELEMENTS_GROUP).concat(composer.selection.getSelectedOwnNodes());\n        composer.selection.executeAndRestoreRangy(function() {\n          for (var n = selectedNodes.length; n--;) {\n            blockElement = dom.getParentElement(selectedNodes[n], {\n              nodeName: BLOCK_ELEMENTS_GROUP\n            });\n            if (blockElement == composer.element) {\n              blockElement = null;\n            }\n            if (blockElement) {\n                // Rename current block element to new block element and add class\n                if (nodeName) {\n                  blockElement = dom.renameElement(blockElement, nodeName);\n                }\n                if (className) {\n                  _addClass(blockElement, className, classRegExp);\n                }\n                if (cssStyle) {\n                  _addStyle(blockElement, cssStyle, styleRegExp);\n                }\n              blockRenameFound = true;\n            }\n          }\n\n        });\n\n        if (blockRenameFound) {\n          return;\n        }\n      }\n\n      _selectionWrap(composer, {\n        \"nodeName\": (nodeName || defaultNodeName),\n        \"className\": className || null,\n        \"cssStyle\": cssStyle || null\n      });\n    },\n\n    state: function(composer, command, nodeName, className, classRegExp, cssStyle, styleRegExp) {\n      var nodes = composer.selection.getSelectedOwnNodes(),\n          parents = [],\n          parent;\n\n      nodeName = typeof(nodeName) === \"string\" ? nodeName.toUpperCase() : nodeName;\n\n      //var selectedNode = composer.selection.getSelectedNode();\n      for (var i = 0, maxi = nodes.length; i < maxi; i++) {\n        parent = dom.getParentElement(nodes[i], {\n          nodeName:     nodeName,\n          className:    className,\n          classRegExp:  classRegExp,\n          cssStyle:     cssStyle,\n          styleRegExp:  styleRegExp\n        });\n        if (parent && wysihtml5.lang.array(parents).indexOf(parent) == -1) {\n          parents.push(parent);\n        }\n      }\n      if (parents.length == 0) {\n        return false;\n      }\n      return parents;\n    }\n\n\n  };\n})(wysihtml5);\n;/* Formats block for as a <pre><code class=\"classname\"></code></pre> block\n * Useful in conjuction for sytax highlight utility: highlight.js\n *\n * Usage:\n *\n * editorInstance.composer.commands.exec(\"formatCode\", \"language-html\");\n*/\n\nwysihtml5.commands.formatCode = {\n\n  exec: function(composer, command, classname) {\n    var pre = this.state(composer),\n        code, range, selectedNodes;\n    if (pre) {\n      // caret is already within a <pre><code>...</code></pre>\n      composer.selection.executeAndRestore(function() {\n        code = pre.querySelector(\"code\");\n        wysihtml5.dom.replaceWithChildNodes(pre);\n        if (code) {\n          wysihtml5.dom.replaceWithChildNodes(code);\n        }\n      });\n    } else {\n      // Wrap in <pre><code>...</code></pre>\n      range = composer.selection.getRange();\n      selectedNodes = range.extractContents();\n      pre = composer.doc.createElement(\"pre\");\n      code = composer.doc.createElement(\"code\");\n\n      if (classname) {\n        code.className = classname;\n      }\n\n      pre.appendChild(code);\n      code.appendChild(selectedNodes);\n      range.insertNode(pre);\n      composer.selection.selectNode(pre);\n    }\n  },\n\n  state: function(composer) {\n    var selectedNode = composer.selection.getSelectedNode();\n    if (selectedNode && selectedNode.nodeName && selectedNode.nodeName == \"PRE\"&&\n        selectedNode.firstChild && selectedNode.firstChild.nodeName && selectedNode.firstChild.nodeName == \"CODE\") {\n      return selectedNode;\n    } else {\n      return wysihtml5.dom.getParentElement(selectedNode, { nodeName: \"CODE\" }) && wysihtml5.dom.getParentElement(selectedNode, { nodeName: \"PRE\" });\n    }\n  }\n};;/**\n * formatInline scenarios for tag \"B\" (| = caret, |foo| = selected text)\n *\n *   #1 caret in unformatted text:\n *      abcdefg|\n *   output:\n *      abcdefg<b>|</b>\n *\n *   #2 unformatted text selected:\n *      abc|deg|h\n *   output:\n *      abc<b>|deg|</b>h\n *\n *   #3 unformatted text selected across boundaries:\n *      ab|c <span>defg|h</span>\n *   output:\n *      ab<b>|c </b><span><b>defg</b>|h</span>\n *\n *   #4 formatted text entirely selected\n *      <b>|abc|</b>\n *   output:\n *      |abc|\n *\n *   #5 formatted text partially selected\n *      <b>ab|c|</b>\n *   output:\n *      <b>ab</b>|c|\n *\n *   #6 formatted text selected across boundaries\n *      <span>ab|c</span> <b>de|fgh</b>\n *   output:\n *      <span>ab|c</span> de|<b>fgh</b>\n */\n(function(wysihtml5) {\n  var // Treat <b> as <strong> and vice versa\n      ALIAS_MAPPING = {\n        \"strong\": \"b\",\n        \"em\":     \"i\",\n        \"b\":      \"strong\",\n        \"i\":      \"em\"\n      },\n      htmlApplier = {};\n\n  function _getTagNames(tagName) {\n    var alias = ALIAS_MAPPING[tagName];\n    return alias ? [tagName.toLowerCase(), alias.toLowerCase()] : [tagName.toLowerCase()];\n  }\n\n  function _getApplier(tagName, className, classRegExp, cssStyle, styleRegExp, container) {\n    var identifier = tagName;\n    \n    if (className) {\n      identifier += \":\" + className;\n    }\n    if (cssStyle) {\n      identifier += \":\" + cssStyle;\n    }\n\n    if (!htmlApplier[identifier]) {\n      htmlApplier[identifier] = new wysihtml5.selection.HTMLApplier(_getTagNames(tagName), className, classRegExp, true, cssStyle, styleRegExp, container);\n    }\n\n    return htmlApplier[identifier];\n  }\n\n  wysihtml5.commands.formatInline = {\n    exec: function(composer, command, tagName, className, classRegExp, cssStyle, styleRegExp, dontRestoreSelect, noCleanup) {\n      var range = composer.selection.createRange(),\n          ownRanges = composer.selection.getOwnRanges();\n\n      if (!ownRanges || ownRanges.length == 0) {\n        return false;\n      }\n      composer.selection.getSelection().removeAllRanges();\n\n      _getApplier(tagName, className, classRegExp, cssStyle, styleRegExp, composer.element).toggleRange(ownRanges);\n\n      if (!dontRestoreSelect) {\n        range.setStart(ownRanges[0].startContainer,  ownRanges[0].startOffset);\n        range.setEnd(\n          ownRanges[ownRanges.length - 1].endContainer,\n          ownRanges[ownRanges.length - 1].endOffset\n        );\n        composer.selection.setSelection(range);\n        composer.selection.executeAndRestore(function() {\n          if (!noCleanup) {\n            composer.cleanUp();\n          }\n        }, true, true);\n      } else if (!noCleanup) {\n        composer.cleanUp();\n      }\n    },\n\n    // Executes so that if collapsed caret is in a state and executing that state it should unformat that state\n    // It is achieved by selecting the entire state element before executing.\n    // This works on built in contenteditable inline format commands\n    execWithToggle: function(composer, command, tagName, className, classRegExp, cssStyle, styleRegExp) {\n      var that = this;\n\n      if (this.state(composer, command, tagName, className, classRegExp, cssStyle, styleRegExp) &&\n        composer.selection.isCollapsed() &&\n        !composer.selection.caretIsLastInSelection() &&\n        !composer.selection.caretIsFirstInSelection()\n      ) {\n        var state_element = that.state(composer, command, tagName, className, classRegExp)[0];\n        composer.selection.executeAndRestoreRangy(function() {\n          var parent = state_element.parentNode;\n          composer.selection.selectNode(state_element, true);\n          wysihtml5.commands.formatInline.exec(composer, command, tagName, className, classRegExp, cssStyle, styleRegExp, true, true);\n        });\n      } else {\n        if (this.state(composer, command, tagName, className, classRegExp, cssStyle, styleRegExp) && !composer.selection.isCollapsed()) {\n          composer.selection.executeAndRestoreRangy(function() {\n            wysihtml5.commands.formatInline.exec(composer, command, tagName, className, classRegExp, cssStyle, styleRegExp, true, true);\n          });\n        } else {\n          wysihtml5.commands.formatInline.exec(composer, command, tagName, className, classRegExp, cssStyle, styleRegExp);\n        }\n      }\n    },\n\n    state: function(composer, command, tagName, className, classRegExp, cssStyle, styleRegExp) {\n      var doc           = composer.doc,\n          aliasTagName  = ALIAS_MAPPING[tagName] || tagName,\n          ownRanges, isApplied;\n\n      // Check whether the document contains a node with the desired tagName\n      if (!wysihtml5.dom.hasElementWithTagName(doc, tagName) &&\n          !wysihtml5.dom.hasElementWithTagName(doc, aliasTagName)) {\n        return false;\n      }\n\n       // Check whether the document contains a node with the desired className\n      if (className && !wysihtml5.dom.hasElementWithClassName(doc, className)) {\n         return false;\n      }\n\n      ownRanges = composer.selection.getOwnRanges();\n\n      if (!ownRanges || ownRanges.length === 0) {\n        return false;\n      }\n\n      isApplied = _getApplier(tagName, className, classRegExp, cssStyle, styleRegExp, composer.element).isAppliedToRange(ownRanges);\n\n      return (isApplied && isApplied.elements) ? isApplied.elements : false;\n    }\n  };\n})(wysihtml5);\n;(function(wysihtml5) {\n\n  wysihtml5.commands.insertBlockQuote = {\n    exec: function(composer, command) {\n      var state = this.state(composer, command),\n          endToEndParent = composer.selection.isEndToEndInNode(['H1', 'H2', 'H3', 'H4', 'H5', 'H6', 'P']),\n          prevNode, nextNode;\n\n      composer.selection.executeAndRestore(function() {\n        if (state) {\n          if (composer.config.useLineBreaks) {\n             wysihtml5.dom.lineBreaks(state).add();\n          }\n          wysihtml5.dom.unwrap(state);\n        } else {\n          if (composer.selection.isCollapsed()) {\n            composer.selection.selectLine();\n          }\n          \n          if (endToEndParent) {\n            var qouteEl = endToEndParent.ownerDocument.createElement('blockquote');\n            wysihtml5.dom.insert(qouteEl).after(endToEndParent);\n            qouteEl.appendChild(endToEndParent);\n          } else {\n            composer.selection.surround({nodeName: \"blockquote\"});\n          }\n        }\n      });\n    },\n    state: function(composer, command) {\n      var selectedNode  = composer.selection.getSelectedNode(),\n          node = wysihtml5.dom.getParentElement(selectedNode, { nodeName: \"BLOCKQUOTE\" }, false, composer.element);\n\n      return (node) ? node : false;\n    }\n  };\n\n})(wysihtml5);;wysihtml5.commands.insertHTML = {\n  exec: function(composer, command, html) {\n    if (composer.commands.support(command)) {\n      composer.doc.execCommand(command, false, html);\n    } else {\n      composer.selection.insertHTML(html);\n    }\n  },\n\n  state: function() {\n    return false;\n  }\n};\n;(function(wysihtml5) {\n  var NODE_NAME = \"IMG\";\n\n  wysihtml5.commands.insertImage = {\n    /**\n     * Inserts an <img>\n     * If selection is already an image link, it removes it\n     *\n     * @example\n     *    // either ...\n     *    wysihtml5.commands.insertImage.exec(composer, \"insertImage\", \"http://www.google.de/logo.jpg\");\n     *    // ... or ...\n     *    wysihtml5.commands.insertImage.exec(composer, \"insertImage\", { src: \"http://www.google.de/logo.jpg\", title: \"foo\" });\n     */\n    exec: function(composer, command, value) {\n      value = typeof(value) === \"object\" ? value : { src: value };\n\n      var doc     = composer.doc,\n          image   = this.state(composer),\n          textNode,\n          parent;\n\n      if (image) {\n        // Image already selected, set the caret before it and delete it\n        composer.selection.setBefore(image);\n        parent = image.parentNode;\n        parent.removeChild(image);\n\n        // and it's parent <a> too if it hasn't got any other relevant child nodes\n        wysihtml5.dom.removeEmptyTextNodes(parent);\n        if (parent.nodeName === \"A\" && !parent.firstChild) {\n          composer.selection.setAfter(parent);\n          parent.parentNode.removeChild(parent);\n        }\n\n        // firefox and ie sometimes don't remove the image handles, even though the image got removed\n        wysihtml5.quirks.redraw(composer.element);\n        return;\n      }\n\n      image = doc.createElement(NODE_NAME);\n\n      for (var i in value) {\n        image.setAttribute(i === \"className\" ? \"class\" : i, value[i]);\n      }\n\n      composer.selection.insertNode(image);\n      if (wysihtml5.browser.hasProblemsSettingCaretAfterImg()) {\n        textNode = doc.createTextNode(wysihtml5.INVISIBLE_SPACE);\n        composer.selection.insertNode(textNode);\n        composer.selection.setAfter(textNode);\n      } else {\n        composer.selection.setAfter(image);\n      }\n    },\n\n    state: function(composer) {\n      var doc = composer.doc,\n          selectedNode,\n          text,\n          imagesInSelection;\n\n      if (!wysihtml5.dom.hasElementWithTagName(doc, NODE_NAME)) {\n        return false;\n      }\n\n      selectedNode = composer.selection.getSelectedNode();\n      if (!selectedNode) {\n        return false;\n      }\n\n      if (selectedNode.nodeName === NODE_NAME) {\n        // This works perfectly in IE\n        return selectedNode;\n      }\n\n      if (selectedNode.nodeType !== wysihtml5.ELEMENT_NODE) {\n        return false;\n      }\n\n      text = composer.selection.getText();\n      text = wysihtml5.lang.string(text).trim();\n      if (text) {\n        return false;\n      }\n\n      imagesInSelection = composer.selection.getNodes(wysihtml5.ELEMENT_NODE, function(node) {\n        return node.nodeName === \"IMG\";\n      });\n\n      if (imagesInSelection.length !== 1) {\n        return false;\n      }\n\n      return imagesInSelection[0];\n    }\n  };\n})(wysihtml5);\n;(function(wysihtml5) {\n  var LINE_BREAK = \"<br>\" + (wysihtml5.browser.needsSpaceAfterLineBreak() ? \" \" : \"\");\n\n  wysihtml5.commands.insertLineBreak = {\n    exec: function(composer, command) {\n      if (composer.commands.support(command)) {\n        composer.doc.execCommand(command, false, null);\n        if (!wysihtml5.browser.autoScrollsToCaret()) {\n          composer.selection.scrollIntoView();\n        }\n      } else {\n        composer.commands.exec(\"insertHTML\", LINE_BREAK);\n      }\n    },\n\n    state: function() {\n      return false;\n    }\n  };\n})(wysihtml5);\n;wysihtml5.commands.insertOrderedList = {\n  exec: function(composer, command) {\n    wysihtml5.commands.insertList.exec(composer, command, \"OL\");\n  },\n\n  state: function(composer, command) {\n    return wysihtml5.commands.insertList.state(composer, command, \"OL\");\n  }\n};\n;wysihtml5.commands.insertUnorderedList = {\n  exec: function(composer, command) {\n    wysihtml5.commands.insertList.exec(composer, command, \"UL\");\n  },\n\n  state: function(composer, command) {\n    return wysihtml5.commands.insertList.state(composer, command, \"UL\");\n  }\n};\n;wysihtml5.commands.insertList = (function(wysihtml5) {\n\n  var isNode = function(node, name) {\n    if (node && node.nodeName) {\n      if (typeof name === 'string') {\n        name = [name];\n      }\n      for (var n = name.length; n--;) {\n        if (node.nodeName === name[n]) {\n          return true;\n        }\n      }\n    }\n    return false;\n  };\n\n  var findListEl = function(node, nodeName, composer) {\n    var ret = {\n          el: null,\n          other: false\n        };\n\n    if (node) {\n      var parentLi = wysihtml5.dom.getParentElement(node, { nodeName: \"LI\" }),\n          otherNodeName = (nodeName === \"UL\") ? \"OL\" : \"UL\";\n\n      if (isNode(node, nodeName)) {\n        ret.el = node;\n      } else if (isNode(node, otherNodeName)) {\n        ret = {\n          el: node,\n          other: true\n        };\n      } else if (parentLi) {\n        if (isNode(parentLi.parentNode, nodeName)) {\n          ret.el = parentLi.parentNode;\n        } else if (isNode(parentLi.parentNode, otherNodeName)) {\n          ret = {\n            el : parentLi.parentNode,\n            other: true\n          };\n        }\n      }\n    }\n\n    // do not count list elements outside of composer\n    if (ret.el && !composer.element.contains(ret.el)) {\n      ret.el = null;\n    }\n\n    return ret;\n  };\n\n  var handleSameTypeList = function(el, nodeName, composer) {\n    var otherNodeName = (nodeName === \"UL\") ? \"OL\" : \"UL\",\n        otherLists, innerLists;\n    // Unwrap list\n    // <ul><li>foo</li><li>bar</li></ul>\n    // becomes:\n    // foo<br>bar<br>\n    composer.selection.executeAndRestore(function() {\n      var otherLists = getListsInSelection(otherNodeName, composer);\n      if (otherLists.length) {\n        for (var l = otherLists.length; l--;) {\n          wysihtml5.dom.renameElement(otherLists[l], nodeName.toLowerCase());\n        }\n      } else {\n        innerLists = getListsInSelection(['OL', 'UL'], composer);\n        for (var i = innerLists.length; i--;) {\n          wysihtml5.dom.resolveList(innerLists[i], composer.config.useLineBreaks);\n        }\n        wysihtml5.dom.resolveList(el, composer.config.useLineBreaks);\n      }\n    });\n  };\n\n  var handleOtherTypeList =  function(el, nodeName, composer) {\n    var otherNodeName = (nodeName === \"UL\") ? \"OL\" : \"UL\";\n    // Turn an ordered list into an unordered list\n    // <ol><li>foo</li><li>bar</li></ol>\n    // becomes:\n    // <ul><li>foo</li><li>bar</li></ul>\n    // Also rename other lists in selection\n    composer.selection.executeAndRestore(function() {\n      var renameLists = [el].concat(getListsInSelection(otherNodeName, composer));\n\n      // All selection inner lists get renamed too\n      for (var l = renameLists.length; l--;) {\n        wysihtml5.dom.renameElement(renameLists[l], nodeName.toLowerCase());\n      }\n    });\n  };\n\n  var getListsInSelection = function(nodeName, composer) {\n      var ranges = composer.selection.getOwnRanges(),\n          renameLists = [];\n\n      for (var r = ranges.length; r--;) {\n        renameLists = renameLists.concat(ranges[r].getNodes([1], function(node) {\n          return isNode(node, nodeName);\n        }));\n      }\n\n      return renameLists;\n  };\n\n  var createListFallback = function(nodeName, composer) {\n    // Fallback for Create list\n    composer.selection.executeAndRestoreRangy(function() {\n      var tempClassName =  \"_wysihtml5-temp-\" + new Date().getTime(),\n          tempElement = composer.selection.deblockAndSurround({\n            \"nodeName\": \"div\",\n            \"className\": tempClassName\n          }),\n          isEmpty, list;\n\n      // This space causes new lists to never break on enter \n      var INVISIBLE_SPACE_REG_EXP = /\\uFEFF/g;\n      tempElement.innerHTML = tempElement.innerHTML.replace(INVISIBLE_SPACE_REG_EXP, \"\");\n      \n      if (tempElement) {\n        isEmpty = wysihtml5.lang.array([\"\", \"<br>\", wysihtml5.INVISIBLE_SPACE]).contains(tempElement.innerHTML);\n        list = wysihtml5.dom.convertToList(tempElement, nodeName.toLowerCase(), composer.parent.config.uneditableContainerClassname);\n        if (isEmpty) {\n          composer.selection.selectNode(list.querySelector(\"li\"), true);\n        }\n      }\n    });\n  };\n\n  return {\n    exec: function(composer, command, nodeName) {\n      var doc           = composer.doc,\n          cmd           = (nodeName === \"OL\") ? \"insertOrderedList\" : \"insertUnorderedList\",\n          selectedNode  = composer.selection.getSelectedNode(),\n          list          = findListEl(selectedNode, nodeName, composer);\n\n      if (!list.el) {\n        if (composer.commands.support(cmd)) {\n          doc.execCommand(cmd, false, null);\n        } else {\n          createListFallback(nodeName, composer);\n        }\n      } else if (list.other) {\n        handleOtherTypeList(list.el, nodeName, composer);\n      } else {\n        handleSameTypeList(list.el, nodeName, composer);\n      }\n    },\n\n    state: function(composer, command, nodeName) {\n      var selectedNode = composer.selection.getSelectedNode(),\n          list         = findListEl(selectedNode, nodeName, composer);\n\n      return (list.el && !list.other) ? list.el : false;\n    }\n  };\n\n})(wysihtml5);;wysihtml5.commands.italic = {\n  exec: function(composer, command) {\n    wysihtml5.commands.formatInline.execWithToggle(composer, command, \"i\");\n  },\n\n  state: function(composer, command) {\n    // element.ownerDocument.queryCommandState(\"italic\") results:\n    // firefox: only <i>\n    // chrome:  <i>, <em>, <blockquote>, ...\n    // ie:      <i>, <em>\n    // opera:   only <i>\n    return wysihtml5.commands.formatInline.state(composer, command, \"i\");\n  }\n};\n;(function(wysihtml5) {\n  var CLASS_NAME  = \"wysiwyg-text-align-center\",\n      REG_EXP     = /wysiwyg-text-align-[0-9a-z]+/g;\n\n  wysihtml5.commands.justifyCenter = {\n    exec: function(composer, command) {\n      return wysihtml5.commands.formatBlock.exec(composer, \"formatBlock\", null, CLASS_NAME, REG_EXP);\n    },\n\n    state: function(composer, command) {\n      return wysihtml5.commands.formatBlock.state(composer, \"formatBlock\", null, CLASS_NAME, REG_EXP);\n    }\n  };\n})(wysihtml5);\n;(function(wysihtml5) {\n  var CLASS_NAME  = \"wysiwyg-text-align-left\",\n      REG_EXP     = /wysiwyg-text-align-[0-9a-z]+/g;\n\n  wysihtml5.commands.justifyLeft = {\n    exec: function(composer, command) {\n      return wysihtml5.commands.formatBlock.exec(composer, \"formatBlock\", null, CLASS_NAME, REG_EXP);\n    },\n\n    state: function(composer, command) {\n      return wysihtml5.commands.formatBlock.state(composer, \"formatBlock\", null, CLASS_NAME, REG_EXP);\n    }\n  };\n})(wysihtml5);\n;(function(wysihtml5) {\n  var CLASS_NAME  = \"wysiwyg-text-align-right\",\n      REG_EXP     = /wysiwyg-text-align-[0-9a-z]+/g;\n\n  wysihtml5.commands.justifyRight = {\n    exec: function(composer, command) {\n      return wysihtml5.commands.formatBlock.exec(composer, \"formatBlock\", null, CLASS_NAME, REG_EXP);\n    },\n\n    state: function(composer, command) {\n      return wysihtml5.commands.formatBlock.state(composer, \"formatBlock\", null, CLASS_NAME, REG_EXP);\n    }\n  };\n})(wysihtml5);\n;(function(wysihtml5) {\n  var CLASS_NAME  = \"wysiwyg-text-align-justify\",\n      REG_EXP     = /wysiwyg-text-align-[0-9a-z]+/g;\n\n  wysihtml5.commands.justifyFull = {\n    exec: function(composer, command) {\n      return wysihtml5.commands.formatBlock.exec(composer, \"formatBlock\", null, CLASS_NAME, REG_EXP);\n    },\n\n    state: function(composer, command) {\n      return wysihtml5.commands.formatBlock.state(composer, \"formatBlock\", null, CLASS_NAME, REG_EXP);\n    }\n  };\n})(wysihtml5);\n;(function(wysihtml5) {\n  var STYLE_STR  = \"text-align: right;\",\n      REG_EXP = /(\\s|^)text-align\\s*:\\s*[^;\\s]+;?/gi;\n\n  wysihtml5.commands.alignRightStyle = {\n    exec: function(composer, command) {\n      return wysihtml5.commands.formatBlock.exec(composer, \"formatBlock\", null, null, null, STYLE_STR, REG_EXP);\n    },\n\n    state: function(composer, command) {\n      return wysihtml5.commands.formatBlock.state(composer, \"formatBlock\", null, null, null, STYLE_STR, REG_EXP);\n    }\n  };\n})(wysihtml5);\n;(function(wysihtml5) {\n  var STYLE_STR  = \"text-align: left;\",\n      REG_EXP = /(\\s|^)text-align\\s*:\\s*[^;\\s]+;?/gi;\n\n  wysihtml5.commands.alignLeftStyle = {\n    exec: function(composer, command) {\n      return wysihtml5.commands.formatBlock.exec(composer, \"formatBlock\", null, null, null, STYLE_STR, REG_EXP);\n    },\n\n    state: function(composer, command) {\n      return wysihtml5.commands.formatBlock.state(composer, \"formatBlock\", null, null, null, STYLE_STR, REG_EXP);\n    }\n  };\n})(wysihtml5);\n;(function(wysihtml5) {\n  var STYLE_STR  = \"text-align: center;\",\n      REG_EXP = /(\\s|^)text-align\\s*:\\s*[^;\\s]+;?/gi;\n\n  wysihtml5.commands.alignCenterStyle = {\n    exec: function(composer, command) {\n      return wysihtml5.commands.formatBlock.exec(composer, \"formatBlock\", null, null, null, STYLE_STR, REG_EXP);\n    },\n\n    state: function(composer, command) {\n      return wysihtml5.commands.formatBlock.state(composer, \"formatBlock\", null, null, null, STYLE_STR, REG_EXP);\n    }\n  };\n})(wysihtml5);\n;wysihtml5.commands.redo = {\n  exec: function(composer) {\n    return composer.undoManager.redo();\n  },\n\n  state: function(composer) {\n    return false;\n  }\n};\n;wysihtml5.commands.underline = {\n  exec: function(composer, command) {\n    wysihtml5.commands.formatInline.execWithToggle(composer, command, \"u\");\n  },\n\n  state: function(composer, command) {\n    return wysihtml5.commands.formatInline.state(composer, command, \"u\");\n  }\n};\n;wysihtml5.commands.undo = {\n  exec: function(composer) {\n    return composer.undoManager.undo();\n  },\n\n  state: function(composer) {\n    return false;\n  }\n};\n;wysihtml5.commands.createTable = {\n  exec: function(composer, command, value) {\n      var col, row, html;\n      if (value && value.cols && value.rows && parseInt(value.cols, 10) > 0 && parseInt(value.rows, 10) > 0) {\n          if (value.tableStyle) {\n            html = \"<table style=\\\"\" + value.tableStyle + \"\\\">\";\n          } else {\n            html = \"<table>\";\n          }\n          html += \"<tbody>\";\n          for (row = 0; row < value.rows; row ++) {\n              html += '<tr>';\n              for (col = 0; col < value.cols; col ++) {\n                  html += \"<td>&nbsp;</td>\";\n              }\n              html += '</tr>';\n          }\n          html += \"</tbody></table>\";\n          composer.commands.exec(\"insertHTML\", html);\n          //composer.selection.insertHTML(html);\n      }\n\n\n  },\n\n  state: function(composer, command) {\n      return false;\n  }\n};\n;wysihtml5.commands.mergeTableCells = {\n  exec: function(composer, command) {\n      if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {\n          if (this.state(composer, command)) {\n              wysihtml5.dom.table.unmergeCell(composer.tableSelection.start);\n          } else {\n              wysihtml5.dom.table.mergeCellsBetween(composer.tableSelection.start, composer.tableSelection.end);\n          }\n      }\n  },\n\n  state: function(composer, command) {\n      if (composer.tableSelection) {\n          var start = composer.tableSelection.start,\n              end = composer.tableSelection.end;\n          if (start && end && start == end &&\n              ((\n                  wysihtml5.dom.getAttribute(start, \"colspan\") &&\n                  parseInt(wysihtml5.dom.getAttribute(start, \"colspan\"), 10) > 1\n              ) || (\n                  wysihtml5.dom.getAttribute(start, \"rowspan\") &&\n                  parseInt(wysihtml5.dom.getAttribute(start, \"rowspan\"), 10) > 1\n              ))\n          ) {\n              return [start];\n          }\n      }\n      return false;\n  }\n};\n;wysihtml5.commands.addTableCells = {\n  exec: function(composer, command, value) {\n      if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {\n\n          // switches start and end if start is bigger than end (reverse selection)\n          var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end);\n          if (value == \"before\" || value == \"above\") {\n              wysihtml5.dom.table.addCells(tableSelect.start, value);\n          } else if (value == \"after\" || value == \"below\") {\n              wysihtml5.dom.table.addCells(tableSelect.end, value);\n          }\n          setTimeout(function() {\n              composer.tableSelection.select(tableSelect.start, tableSelect.end);\n          },0);\n      }\n  },\n\n  state: function(composer, command) {\n      return false;\n  }\n};\n;wysihtml5.commands.deleteTableCells = {\n  exec: function(composer, command, value) {\n      if (composer.tableSelection && composer.tableSelection.start && composer.tableSelection.end) {\n          var tableSelect = wysihtml5.dom.table.orderSelectionEnds(composer.tableSelection.start, composer.tableSelection.end),\n              idx = wysihtml5.dom.table.indexOf(tableSelect.start),\n              selCell,\n              table = composer.tableSelection.table;\n\n          wysihtml5.dom.table.removeCells(tableSelect.start, value);\n          setTimeout(function() {\n              // move selection to next or previous if not present\n              selCell = wysihtml5.dom.table.findCell(table, idx);\n\n              if (!selCell){\n                  if (value == \"row\") {\n                      selCell = wysihtml5.dom.table.findCell(table, {\n                          \"row\": idx.row - 1,\n                          \"col\": idx.col\n                      });\n                  }\n\n                  if (value == \"column\") {\n                      selCell = wysihtml5.dom.table.findCell(table, {\n                          \"row\": idx.row,\n                          \"col\": idx.col - 1\n                      });\n                  }\n              }\n              if (selCell) {\n                  composer.tableSelection.select(selCell, selCell);\n              }\n          }, 0);\n\n      }\n  },\n\n  state: function(composer, command) {\n      return false;\n  }\n};\n;wysihtml5.commands.indentList = {\n  exec: function(composer, command, value) {\n    var listEls = composer.selection.getSelectionParentsByTag('LI');\n    if (listEls) {\n      return this.tryToPushLiLevel(listEls, composer.selection);\n    }\n    return false;\n  },\n\n  state: function(composer, command) {\n      return false;\n  },\n\n  tryToPushLiLevel: function(liNodes, selection) {\n    var listTag, list, prevLi, liNode, prevLiList,\n        found = false;\n\n    selection.executeAndRestoreRangy(function() {\n\n      for (var i = liNodes.length; i--;) {\n        liNode = liNodes[i];\n        listTag = (liNode.parentNode.nodeName === 'OL') ? 'OL' : 'UL';\n        list = liNode.ownerDocument.createElement(listTag);\n        prevLi = wysihtml5.dom.domNode(liNode).prev({nodeTypes: [wysihtml5.ELEMENT_NODE]});\n        prevLiList = (prevLi) ? prevLi.querySelector('ul, ol') : null;\n\n        if (prevLi) {\n          if (prevLiList) {\n            prevLiList.appendChild(liNode);\n          } else {\n            list.appendChild(liNode);\n            prevLi.appendChild(list);\n          }\n          found = true;\n        }\n      }\n\n    });\n    return found;\n  }\n};\n;wysihtml5.commands.outdentList = {\n  exec: function(composer, command, value) {\n    var listEls = composer.selection.getSelectionParentsByTag('LI');\n    if (listEls) {\n      return this.tryToPullLiLevel(listEls, composer);\n    }\n    return false;\n  },\n\n  state: function(composer, command) {\n      return false;\n  },\n\n  tryToPullLiLevel: function(liNodes, composer) {\n    var listNode, outerListNode, outerLiNode, list, prevLi, liNode, afterList,\n        found = false,\n        that = this;\n\n    composer.selection.executeAndRestoreRangy(function() {\n\n      for (var i = liNodes.length; i--;) {\n        liNode = liNodes[i];\n        if (liNode.parentNode) {\n          listNode = liNode.parentNode;\n\n          if (listNode.tagName === 'OL' || listNode.tagName === 'UL') {\n            found = true;\n\n            outerListNode = wysihtml5.dom.getParentElement(listNode.parentNode, { nodeName: ['OL', 'UL']}, false, composer.element);\n            outerLiNode = wysihtml5.dom.getParentElement(listNode.parentNode, { nodeName: ['LI']}, false, composer.element);\n\n            if (outerListNode && outerLiNode) {\n\n              if (liNode.nextSibling) {\n                afterList = that.getAfterList(listNode, liNode);\n                liNode.appendChild(afterList);\n              }\n              outerListNode.insertBefore(liNode, outerLiNode.nextSibling);\n\n            } else {\n\n              if (liNode.nextSibling) {\n                afterList = that.getAfterList(listNode, liNode);\n                liNode.appendChild(afterList);\n              }\n\n              for (var j = liNode.childNodes.length; j--;) {\n                listNode.parentNode.insertBefore(liNode.childNodes[j], listNode.nextSibling);\n              }\n\n              listNode.parentNode.insertBefore(document.createElement('br'), listNode.nextSibling);\n              liNode.parentNode.removeChild(liNode);\n\n            }\n\n            // cleanup\n            if (listNode.childNodes.length === 0) {\n                listNode.parentNode.removeChild(listNode);\n            }\n          }\n        }\n      }\n\n    });\n    return found;\n  },\n\n  getAfterList: function(listNode, liNode) {\n    var nodeName = listNode.nodeName,\n        newList = document.createElement(nodeName);\n\n    while (liNode.nextSibling) {\n      newList.appendChild(liNode.nextSibling);\n    }\n    return newList;\n  }\n\n};;/**\n * Undo Manager for wysihtml5\n * slightly inspired by http://rniwa.com/editing/undomanager.html#the-undomanager-interface\n */\n(function(wysihtml5) {\n  var Z_KEY               = 90,\n      Y_KEY               = 89,\n      BACKSPACE_KEY       = 8,\n      DELETE_KEY          = 46,\n      MAX_HISTORY_ENTRIES = 25,\n      DATA_ATTR_NODE      = \"data-wysihtml5-selection-node\",\n      DATA_ATTR_OFFSET    = \"data-wysihtml5-selection-offset\",\n      UNDO_HTML           = '<span id=\"_wysihtml5-undo\" class=\"_wysihtml5-temp\">' + wysihtml5.INVISIBLE_SPACE + '</span>',\n      REDO_HTML           = '<span id=\"_wysihtml5-redo\" class=\"_wysihtml5-temp\">' + wysihtml5.INVISIBLE_SPACE + '</span>',\n      dom                 = wysihtml5.dom;\n\n  function cleanTempElements(doc) {\n    var tempElement;\n    while (tempElement = doc.querySelector(\"._wysihtml5-temp\")) {\n      tempElement.parentNode.removeChild(tempElement);\n    }\n  }\n\n  wysihtml5.UndoManager = wysihtml5.lang.Dispatcher.extend(\n    /** @scope wysihtml5.UndoManager.prototype */ {\n    constructor: function(editor) {\n      this.editor = editor;\n      this.composer = editor.composer;\n      this.element = this.composer.element;\n\n      this.position = 0;\n      this.historyStr = [];\n      this.historyDom = [];\n\n      this.transact();\n\n      this._observe();\n    },\n\n    _observe: function() {\n      var that      = this,\n          doc       = this.composer.sandbox.getDocument(),\n          lastKey;\n\n      // Catch CTRL+Z and CTRL+Y\n      dom.observe(this.element, \"keydown\", function(event) {\n        if (event.altKey || (!event.ctrlKey && !event.metaKey)) {\n          return;\n        }\n\n        var keyCode = event.keyCode,\n            isUndo = keyCode === Z_KEY && !event.shiftKey,\n            isRedo = (keyCode === Z_KEY && event.shiftKey) || (keyCode === Y_KEY);\n\n        if (isUndo) {\n          that.undo();\n          event.preventDefault();\n        } else if (isRedo) {\n          that.redo();\n          event.preventDefault();\n        }\n      });\n\n      // Catch delete and backspace\n      dom.observe(this.element, \"keydown\", function(event) {\n        var keyCode = event.keyCode;\n        if (keyCode === lastKey) {\n          return;\n        }\n\n        lastKey = keyCode;\n\n        if (keyCode === BACKSPACE_KEY || keyCode === DELETE_KEY) {\n          that.transact();\n        }\n      });\n\n      this.editor\n        .on(\"newword:composer\", function() {\n          that.transact();\n        })\n\n        .on(\"beforecommand:composer\", function() {\n          that.transact();\n        });\n    },\n\n    transact: function() {\n      var previousHtml      = this.historyStr[this.position - 1],\n          currentHtml       = this.composer.getValue(false, false),\n          composerIsVisible   = this.element.offsetWidth > 0 && this.element.offsetHeight > 0,\n          range, node, offset, element, position;\n\n      if (currentHtml === previousHtml) {\n        return;\n      }\n\n      var length = this.historyStr.length = this.historyDom.length = this.position;\n      if (length > MAX_HISTORY_ENTRIES) {\n        this.historyStr.shift();\n        this.historyDom.shift();\n        this.position--;\n      }\n\n      this.position++;\n\n      if (composerIsVisible) {\n        // Do not start saving selection if composer is not visible\n        range   = this.composer.selection.getRange();\n        node    = (range && range.startContainer) ? range.startContainer : this.element;\n        offset  = (range && range.startOffset) ? range.startOffset : 0;\n\n        if (node.nodeType === wysihtml5.ELEMENT_NODE) {\n          element = node;\n        } else {\n          element  = node.parentNode;\n          position = this.getChildNodeIndex(element, node);\n        }\n\n        element.setAttribute(DATA_ATTR_OFFSET, offset);\n        if (typeof(position) !== \"undefined\") {\n          element.setAttribute(DATA_ATTR_NODE, position);\n        }\n      }\n\n      var clone = this.element.cloneNode(!!currentHtml);\n      this.historyDom.push(clone);\n      this.historyStr.push(currentHtml);\n\n      if (element) {\n        element.removeAttribute(DATA_ATTR_OFFSET);\n        element.removeAttribute(DATA_ATTR_NODE);\n      }\n\n    },\n\n    undo: function() {\n      this.transact();\n\n      if (!this.undoPossible()) {\n        return;\n      }\n\n      this.set(this.historyDom[--this.position - 1]);\n      this.editor.fire(\"undo:composer\");\n    },\n\n    redo: function() {\n      if (!this.redoPossible()) {\n        return;\n      }\n\n      this.set(this.historyDom[++this.position - 1]);\n      this.editor.fire(\"redo:composer\");\n    },\n\n    undoPossible: function() {\n      return this.position > 1;\n    },\n\n    redoPossible: function() {\n      return this.position < this.historyStr.length;\n    },\n\n    set: function(historyEntry) {\n      this.element.innerHTML = \"\";\n\n      var i = 0,\n          childNodes = historyEntry.childNodes,\n          length = historyEntry.childNodes.length;\n\n      for (; i<length; i++) {\n        this.element.appendChild(childNodes[i].cloneNode(true));\n      }\n\n      // Restore selection\n      var offset,\n          node,\n          position;\n\n      if (historyEntry.hasAttribute(DATA_ATTR_OFFSET)) {\n        offset    = historyEntry.getAttribute(DATA_ATTR_OFFSET);\n        position  = historyEntry.getAttribute(DATA_ATTR_NODE);\n        node      = this.element;\n      } else {\n        node      = this.element.querySelector(\"[\" + DATA_ATTR_OFFSET + \"]\") || this.element;\n        offset    = node.getAttribute(DATA_ATTR_OFFSET);\n        position  = node.getAttribute(DATA_ATTR_NODE);\n        node.removeAttribute(DATA_ATTR_OFFSET);\n        node.removeAttribute(DATA_ATTR_NODE);\n      }\n\n      if (position !== null) {\n        node = this.getChildNodeByIndex(node, +position);\n      }\n\n      this.composer.selection.set(node, offset);\n    },\n\n    getChildNodeIndex: function(parent, child) {\n      var i           = 0,\n          childNodes  = parent.childNodes,\n          length      = childNodes.length;\n      for (; i<length; i++) {\n        if (childNodes[i] === child) {\n          return i;\n        }\n      }\n    },\n\n    getChildNodeByIndex: function(parent, index) {\n      return parent.childNodes[index];\n    }\n  });\n})(wysihtml5);\n;/**\n * TODO: the following methods still need unit test coverage\n */\nwysihtml5.views.View = Base.extend(\n  /** @scope wysihtml5.views.View.prototype */ {\n  constructor: function(parent, textareaElement, config) {\n    this.parent   = parent;\n    this.element  = textareaElement;\n    this.config   = config;\n    if (!this.config.noTextarea) {\n        this._observeViewChange();\n    }\n  },\n\n  _observeViewChange: function() {\n    var that = this;\n    this.parent.on(\"beforeload\", function() {\n      that.parent.on(\"change_view\", function(view) {\n        if (view === that.name) {\n          that.parent.currentView = that;\n          that.show();\n          // Using tiny delay here to make sure that the placeholder is set before focusing\n          setTimeout(function() { that.focus(); }, 0);\n        } else {\n          that.hide();\n        }\n      });\n    });\n  },\n\n  focus: function() {\n    if (this.element.ownerDocument.querySelector(\":focus\") === this.element) {\n      return;\n    }\n\n    try { this.element.focus(); } catch(e) {}\n  },\n\n  hide: function() {\n    this.element.style.display = \"none\";\n  },\n\n  show: function() {\n    this.element.style.display = \"\";\n  },\n\n  disable: function() {\n    this.element.setAttribute(\"disabled\", \"disabled\");\n  },\n\n  enable: function() {\n    this.element.removeAttribute(\"disabled\");\n  }\n});\n;(function(wysihtml5) {\n  var dom       = wysihtml5.dom,\n      browser   = wysihtml5.browser;\n\n  wysihtml5.views.Composer = wysihtml5.views.View.extend(\n    /** @scope wysihtml5.views.Composer.prototype */ {\n    name: \"composer\",\n\n    // Needed for firefox in order to display a proper caret in an empty contentEditable\n    CARET_HACK: \"<br>\",\n\n    constructor: function(parent, editableElement, config) {\n      this.base(parent, editableElement, config);\n      if (!this.config.noTextarea) {\n          this.textarea = this.parent.textarea;\n      } else {\n          this.editableArea = editableElement;\n      }\n      if (this.config.contentEditableMode) {\n          this._initContentEditableArea();\n      } else {\n          this._initSandbox();\n      }\n    },\n\n    clear: function() {\n      this.element.innerHTML = browser.displaysCaretInEmptyContentEditableCorrectly() ? \"\" : this.CARET_HACK;\n    },\n\n    getValue: function(parse, clearInternals) {\n      var value = this.isEmpty() ? \"\" : wysihtml5.quirks.getCorrectInnerHTML(this.element);\n      if (parse !== false) {\n        value = this.parent.parse(value, (clearInternals === false) ? false : true);\n      }\n\n      return value;\n    },\n\n    setValue: function(html, parse) {\n      if (parse) {\n        html = this.parent.parse(html);\n      }\n\n      try {\n        this.element.innerHTML = html;\n      } catch (e) {\n        this.element.innerText = html;\n      }\n    },\n\n    cleanUp: function() {\n        this.parent.parse(this.element);\n    },\n\n    show: function() {\n      this.editableArea.style.display = this._displayStyle || \"\";\n\n      if (!this.config.noTextarea && !this.textarea.element.disabled) {\n        // Firefox needs this, otherwise contentEditable becomes uneditable\n        this.disable();\n        this.enable();\n      }\n    },\n\n    hide: function() {\n      this._displayStyle = dom.getStyle(\"display\").from(this.editableArea);\n      if (this._displayStyle === \"none\") {\n        this._displayStyle = null;\n      }\n      this.editableArea.style.display = \"none\";\n    },\n\n    disable: function() {\n      this.parent.fire(\"disable:composer\");\n      this.element.removeAttribute(\"contentEditable\");\n    },\n\n    enable: function() {\n      this.parent.fire(\"enable:composer\");\n      this.element.setAttribute(\"contentEditable\", \"true\");\n    },\n\n    focus: function(setToEnd) {\n      // IE 8 fires the focus event after .focus()\n      // This is needed by our simulate_placeholder.js to work\n      // therefore we clear it ourselves this time\n      if (wysihtml5.browser.doesAsyncFocus() && this.hasPlaceholderSet()) {\n        this.clear();\n      }\n\n      this.base();\n\n      var lastChild = this.element.lastChild;\n      if (setToEnd && lastChild && this.selection) {\n        if (lastChild.nodeName === \"BR\") {\n          this.selection.setBefore(this.element.lastChild);\n        } else {\n          this.selection.setAfter(this.element.lastChild);\n        }\n      }\n    },\n\n    getTextContent: function() {\n      return dom.getTextContent(this.element);\n    },\n\n    hasPlaceholderSet: function() {\n      return this.getTextContent() == ((this.config.noTextarea) ? this.editableArea.getAttribute(\"data-placeholder\") : this.textarea.element.getAttribute(\"placeholder\")) && this.placeholderSet;\n    },\n\n    isEmpty: function() {\n      var innerHTML = this.element.innerHTML.toLowerCase();\n      return (/^(\\s|<br>|<\\/br>|<p>|<\\/p>)*$/i).test(innerHTML)  ||\n             innerHTML === \"\"            ||\n             innerHTML === \"<br>\"        ||\n             innerHTML === \"<p></p>\"     ||\n             innerHTML === \"<p><br></p>\" ||\n             this.hasPlaceholderSet();\n    },\n\n    _initContentEditableArea: function() {\n        var that = this;\n\n        if (this.config.noTextarea) {\n            this.sandbox = new dom.ContentEditableArea(function() {\n                that._create();\n            }, {}, this.editableArea);\n        } else {\n            this.sandbox = new dom.ContentEditableArea(function() {\n                that._create();\n            });\n            this.editableArea = this.sandbox.getContentEditable();\n            dom.insert(this.editableArea).after(this.textarea.element);\n            this._createWysiwygFormField();\n        }\n    },\n\n    _initSandbox: function() {\n      var that = this;\n\n      this.sandbox = new dom.Sandbox(function() {\n        that._create();\n      }, {\n        stylesheets:  this.config.stylesheets\n      });\n      this.editableArea  = this.sandbox.getIframe();\n\n      var textareaElement = this.textarea.element;\n      dom.insert(this.editableArea).after(textareaElement);\n\n      this._createWysiwygFormField();\n    },\n\n    // Creates hidden field which tells the server after submit, that the user used an wysiwyg editor\n    _createWysiwygFormField: function() {\n        if (this.textarea.element.form) {\n          var hiddenField = document.createElement(\"input\");\n          hiddenField.type   = \"hidden\";\n          hiddenField.name   = \"_wysihtml5_mode\";\n          hiddenField.value  = 1;\n          dom.insert(hiddenField).after(this.textarea.element);\n        }\n    },\n\n    _create: function() {\n      var that = this;\n      this.doc                = this.sandbox.getDocument();\n      this.element            = (this.config.contentEditableMode) ? this.sandbox.getContentEditable() : this.doc.body;\n      if (!this.config.noTextarea) {\n          this.textarea           = this.parent.textarea;\n          this.element.innerHTML  = this.textarea.getValue(true, false);\n      } else {\n          this.cleanUp(); // cleans contenteditable on initiation as it may contain html\n      }\n\n      // Make sure our selection handler is ready\n      this.selection = new wysihtml5.Selection(this.parent, this.element, this.config.uneditableContainerClassname);\n\n      // Make sure commands dispatcher is ready\n      this.commands  = new wysihtml5.Commands(this.parent);\n\n      if (!this.config.noTextarea) {\n          dom.copyAttributes([\n              \"className\", \"spellcheck\", \"title\", \"lang\", \"dir\", \"accessKey\"\n          ]).from(this.textarea.element).to(this.element);\n      }\n\n      dom.addClass(this.element, this.config.composerClassName);\n      //\n      // Make the editor look like the original textarea, by syncing styles\n      if (this.config.style && !this.config.contentEditableMode) {\n        this.style();\n      }\n\n      this.observe();\n\n      var name = this.config.name;\n      if (name) {\n        dom.addClass(this.element, name);\n        if (!this.config.contentEditableMode) { dom.addClass(this.editableArea, name); }\n      }\n\n      this.enable();\n\n      if (!this.config.noTextarea && this.textarea.element.disabled) {\n        this.disable();\n      }\n\n      // Simulate html5 placeholder attribute on contentEditable element\n      var placeholderText = typeof(this.config.placeholder) === \"string\"\n        ? this.config.placeholder\n        : ((this.config.noTextarea) ? this.editableArea.getAttribute(\"data-placeholder\") : this.textarea.element.getAttribute(\"placeholder\"));\n      if (placeholderText) {\n        dom.simulatePlaceholder(this.parent, this, placeholderText);\n      }\n\n      // Make sure that the browser avoids using inline styles whenever possible\n      this.commands.exec(\"styleWithCSS\", false);\n\n      this._initAutoLinking();\n      this._initObjectResizing();\n      this._initUndoManager();\n      this._initLineBreaking();\n\n      // Simulate html5 autofocus on contentEditable element\n      // This doesn't work on IOS (5.1.1)\n      if (!this.config.noTextarea && (this.textarea.element.hasAttribute(\"autofocus\") || document.querySelector(\":focus\") == this.textarea.element) && !browser.isIos()) {\n        setTimeout(function() { that.focus(true); }, 100);\n      }\n\n      // IE sometimes leaves a single paragraph, which can't be removed by the user\n      if (!browser.clearsContentEditableCorrectly()) {\n        wysihtml5.quirks.ensureProperClearing(this);\n      }\n\n      // Set up a sync that makes sure that textarea and editor have the same content\n      if (this.initSync && this.config.sync) {\n        this.initSync();\n      }\n\n      // Okay hide the textarea, we are ready to go\n      if (!this.config.noTextarea) { this.textarea.hide(); }\n\n      // Fire global (before-)load event\n      this.parent.fire(\"beforeload\").fire(\"load\");\n    },\n\n    _initAutoLinking: function() {\n      var that                           = this,\n          supportsDisablingOfAutoLinking = browser.canDisableAutoLinking(),\n          supportsAutoLinking            = browser.doesAutoLinkingInContentEditable();\n      if (supportsDisablingOfAutoLinking) {\n        this.commands.exec(\"autoUrlDetect\", false);\n      }\n\n      if (!this.config.autoLink) {\n        return;\n      }\n\n      // Only do the auto linking by ourselves when the browser doesn't support auto linking\n      // OR when he supports auto linking but we were able to turn it off (IE9+)\n      if (!supportsAutoLinking || (supportsAutoLinking && supportsDisablingOfAutoLinking)) {\n        this.parent.on(\"newword:composer\", function() {\n          if (dom.getTextContent(that.element).match(dom.autoLink.URL_REG_EXP)) {\n            that.selection.executeAndRestore(function(startContainer, endContainer) {\n              var uneditables = that.element.querySelectorAll(\".\" + that.config.uneditableContainerClassname),\n                  isInUneditable = false;\n\n              for (var i = uneditables.length; i--;) {\n                if (wysihtml5.dom.contains(uneditables[i], endContainer)) {\n                  isInUneditable = true;\n                }\n              }\n\n              if (!isInUneditable) dom.autoLink(endContainer.parentNode, [that.config.uneditableContainerClassname]);\n            });\n          }\n        });\n\n        dom.observe(this.element, \"blur\", function() {\n          dom.autoLink(that.element, [that.config.uneditableContainerClassname]);\n        });\n      }\n\n      // Assuming we have the following:\n      //  <a href=\"http://www.google.de\">http://www.google.de</a>\n      // If a user now changes the url in the innerHTML we want to make sure that\n      // it's synchronized with the href attribute (as long as the innerHTML is still a url)\n      var // Use a live NodeList to check whether there are any links in the document\n          links           = this.sandbox.getDocument().getElementsByTagName(\"a\"),\n          // The autoLink helper method reveals a reg exp to detect correct urls\n          urlRegExp       = dom.autoLink.URL_REG_EXP,\n          getTextContent  = function(element) {\n            var textContent = wysihtml5.lang.string(dom.getTextContent(element)).trim();\n            if (textContent.substr(0, 4) === \"www.\") {\n              textContent = \"http://\" + textContent;\n            }\n            return textContent;\n          };\n\n      dom.observe(this.element, \"keydown\", function(event) {\n        if (!links.length) {\n          return;\n        }\n\n        var selectedNode = that.selection.getSelectedNode(event.target.ownerDocument),\n            link         = dom.getParentElement(selectedNode, { nodeName: \"A\" }, 4),\n            textContent;\n\n        if (!link) {\n          return;\n        }\n\n        textContent = getTextContent(link);\n        // keydown is fired before the actual content is changed\n        // therefore we set a timeout to change the href\n        setTimeout(function() {\n          var newTextContent = getTextContent(link);\n          if (newTextContent === textContent) {\n            return;\n          }\n\n          // Only set href when new href looks like a valid url\n          if (newTextContent.match(urlRegExp)) {\n            link.setAttribute(\"href\", newTextContent);\n          }\n        }, 0);\n      });\n    },\n\n    _initObjectResizing: function() {\n      this.commands.exec(\"enableObjectResizing\", true);\n\n      // IE sets inline styles after resizing objects\n      // The following lines make sure that the width/height css properties\n      // are copied over to the width/height attributes\n      if (browser.supportsEvent(\"resizeend\")) {\n        var properties        = [\"width\", \"height\"],\n            propertiesLength  = properties.length,\n            element           = this.element;\n\n        dom.observe(element, \"resizeend\", function(event) {\n          var target = event.target || event.srcElement,\n              style  = target.style,\n              i      = 0,\n              property;\n\n          if (target.nodeName !== \"IMG\") {\n            return;\n          }\n\n          for (; i<propertiesLength; i++) {\n            property = properties[i];\n            if (style[property]) {\n              target.setAttribute(property, parseInt(style[property], 10));\n              style[property] = \"\";\n            }\n          }\n\n          // After resizing IE sometimes forgets to remove the old resize handles\n          wysihtml5.quirks.redraw(element);\n        });\n      }\n    },\n\n    _initUndoManager: function() {\n      this.undoManager = new wysihtml5.UndoManager(this.parent);\n    },\n\n    _initLineBreaking: function() {\n      var that                              = this,\n          USE_NATIVE_LINE_BREAK_INSIDE_TAGS = [\"LI\", \"P\", \"H1\", \"H2\", \"H3\", \"H4\", \"H5\", \"H6\"],\n          LIST_TAGS                         = [\"UL\", \"OL\", \"MENU\"];\n\n      function adjust(selectedNode) {\n        var parentElement = dom.getParentElement(selectedNode, { nodeName: [\"P\", \"DIV\"] }, 2);\n        if (parentElement && dom.contains(that.element, parentElement)) {\n          that.selection.executeAndRestore(function() {\n            if (that.config.useLineBreaks) {\n              dom.replaceWithChildNodes(parentElement);\n            } else if (parentElement.nodeName !== \"P\") {\n              dom.renameElement(parentElement, \"p\");\n            }\n          });\n        }\n      }\n\n      if (!this.config.useLineBreaks) {\n        dom.observe(this.element, [\"focus\", \"keydown\"], function() {\n          if (that.isEmpty()) {\n            var paragraph = that.doc.createElement(\"P\");\n            that.element.innerHTML = \"\";\n            that.element.appendChild(paragraph);\n            if (!browser.displaysCaretInEmptyContentEditableCorrectly()) {\n              paragraph.innerHTML = \"<br>\";\n              that.selection.setBefore(paragraph.firstChild);\n            } else {\n              that.selection.selectNode(paragraph, true);\n            }\n          }\n        });\n      }\n\n      // Under certain circumstances Chrome + Safari create nested <p> or <hX> tags after paste\n      // Inserting an invisible white space in front of it fixes the issue\n      // This is too hacky and causes selection not to replace content on paste in chrome\n     /* if (browser.createsNestedInvalidMarkupAfterPaste()) {\n        dom.observe(this.element, \"paste\", function(event) {\n          var invisibleSpace = that.doc.createTextNode(wysihtml5.INVISIBLE_SPACE);\n          that.selection.insertNode(invisibleSpace);\n        });\n      }*/\n\n\n      dom.observe(this.element, \"keydown\", function(event) {\n        var keyCode = event.keyCode;\n\n        if (event.shiftKey) {\n          return;\n        }\n\n        if (keyCode !== wysihtml5.ENTER_KEY && keyCode !== wysihtml5.BACKSPACE_KEY) {\n          return;\n        }\n        var blockElement = dom.getParentElement(that.selection.getSelectedNode(), { nodeName: USE_NATIVE_LINE_BREAK_INSIDE_TAGS }, 4);\n        if (blockElement) {\n          setTimeout(function() {\n            // Unwrap paragraph after leaving a list or a H1-6\n            var selectedNode = that.selection.getSelectedNode(),\n                list;\n\n            if (blockElement.nodeName === \"LI\") {\n              if (!selectedNode) {\n                return;\n              }\n\n              list = dom.getParentElement(selectedNode, { nodeName: LIST_TAGS }, 2);\n\n              if (!list) {\n                adjust(selectedNode);\n              }\n            }\n\n            if (keyCode === wysihtml5.ENTER_KEY && blockElement.nodeName.match(/^H[1-6]$/)) {\n              adjust(selectedNode);\n            }\n          }, 0);\n          return;\n        }\n\n        if (that.config.useLineBreaks && keyCode === wysihtml5.ENTER_KEY && !wysihtml5.browser.insertsLineBreaksOnReturn()) {\n          event.preventDefault();\n          that.commands.exec(\"insertLineBreak\");\n\n        }\n      });\n    }\n  });\n})(wysihtml5);\n;(function(wysihtml5) {\n  var dom             = wysihtml5.dom,\n      doc             = document,\n      win             = window,\n      HOST_TEMPLATE   = doc.createElement(\"div\"),\n      /**\n       * Styles to copy from textarea to the composer element\n       */\n      TEXT_FORMATTING = [\n        \"background-color\",\n        \"color\", \"cursor\",\n        \"font-family\", \"font-size\", \"font-style\", \"font-variant\", \"font-weight\",\n        \"line-height\", \"letter-spacing\",\n        \"text-align\", \"text-decoration\", \"text-indent\", \"text-rendering\",\n        \"word-break\", \"word-wrap\", \"word-spacing\"\n      ],\n      /**\n       * Styles to copy from textarea to the iframe\n       */\n      BOX_FORMATTING = [\n        \"background-color\",\n        \"border-collapse\",\n        \"border-bottom-color\", \"border-bottom-style\", \"border-bottom-width\",\n        \"border-left-color\", \"border-left-style\", \"border-left-width\",\n        \"border-right-color\", \"border-right-style\", \"border-right-width\",\n        \"border-top-color\", \"border-top-style\", \"border-top-width\",\n        \"clear\", \"display\", \"float\",\n        \"margin-bottom\", \"margin-left\", \"margin-right\", \"margin-top\",\n        \"outline-color\", \"outline-offset\", \"outline-width\", \"outline-style\",\n        \"padding-left\", \"padding-right\", \"padding-top\", \"padding-bottom\",\n        \"position\", \"top\", \"left\", \"right\", \"bottom\", \"z-index\",\n        \"vertical-align\", \"text-align\",\n        \"-webkit-box-sizing\", \"-moz-box-sizing\", \"-ms-box-sizing\", \"box-sizing\",\n        \"-webkit-box-shadow\", \"-moz-box-shadow\", \"-ms-box-shadow\",\"box-shadow\",\n        \"-webkit-border-top-right-radius\", \"-moz-border-radius-topright\", \"border-top-right-radius\",\n        \"-webkit-border-bottom-right-radius\", \"-moz-border-radius-bottomright\", \"border-bottom-right-radius\",\n        \"-webkit-border-bottom-left-radius\", \"-moz-border-radius-bottomleft\", \"border-bottom-left-radius\",\n        \"-webkit-border-top-left-radius\", \"-moz-border-radius-topleft\", \"border-top-left-radius\",\n        \"width\", \"height\"\n      ],\n      ADDITIONAL_CSS_RULES = [\n        \"html                 { height: 100%; }\",\n        \"body                 { height: 100%; padding: 1px 0 0 0; margin: -1px 0 0 0; }\",\n        \"body > p:first-child { margin-top: 0; }\",\n        \"._wysihtml5-temp     { display: none; }\",\n        wysihtml5.browser.isGecko ?\n          \"body.placeholder { color: graytext !important; }\" :\n          \"body.placeholder { color: #a9a9a9 !important; }\",\n        // Ensure that user see's broken images and can delete them\n        \"img:-moz-broken      { -moz-force-broken-image-icon: 1; height: 24px; width: 24px; }\"\n      ];\n\n  /**\n   * With \"setActive\" IE offers a smart way of focusing elements without scrolling them into view:\n   * http://msdn.microsoft.com/en-us/library/ms536738(v=vs.85).aspx\n   *\n   * Other browsers need a more hacky way: (pssst don't tell my mama)\n   * In order to prevent the element being scrolled into view when focusing it, we simply\n   * move it out of the scrollable area, focus it, and reset it's position\n   */\n  var focusWithoutScrolling = function(element) {\n    if (element.setActive) {\n      // Following line could cause a js error when the textarea is invisible\n      // See https://github.com/xing/wysihtml5/issues/9\n      try { element.setActive(); } catch(e) {}\n    } else {\n      var elementStyle = element.style,\n          originalScrollTop = doc.documentElement.scrollTop || doc.body.scrollTop,\n          originalScrollLeft = doc.documentElement.scrollLeft || doc.body.scrollLeft,\n          originalStyles = {\n            position:         elementStyle.position,\n            top:              elementStyle.top,\n            left:             elementStyle.left,\n            WebkitUserSelect: elementStyle.WebkitUserSelect\n          };\n\n      dom.setStyles({\n        position:         \"absolute\",\n        top:              \"-99999px\",\n        left:             \"-99999px\",\n        // Don't ask why but temporarily setting -webkit-user-select to none makes the whole thing performing smoother\n        WebkitUserSelect: \"none\"\n      }).on(element);\n\n      element.focus();\n\n      dom.setStyles(originalStyles).on(element);\n\n      if (win.scrollTo) {\n        // Some browser extensions unset this method to prevent annoyances\n        // \"Better PopUp Blocker\" for Chrome http://code.google.com/p/betterpopupblocker/source/browse/trunk/blockStart.js#100\n        // Issue: http://code.google.com/p/betterpopupblocker/issues/detail?id=1\n        win.scrollTo(originalScrollLeft, originalScrollTop);\n      }\n    }\n  };\n\n\n  wysihtml5.views.Composer.prototype.style = function() {\n    var that                  = this,\n        originalActiveElement = doc.querySelector(\":focus\"),\n        textareaElement       = this.textarea.element,\n        hasPlaceholder        = textareaElement.hasAttribute(\"placeholder\"),\n        originalPlaceholder   = hasPlaceholder && textareaElement.getAttribute(\"placeholder\"),\n        originalDisplayValue  = textareaElement.style.display,\n        originalDisabled      = textareaElement.disabled,\n        displayValueForCopying;\n\n    this.focusStylesHost      = HOST_TEMPLATE.cloneNode(false);\n    this.blurStylesHost       = HOST_TEMPLATE.cloneNode(false);\n    this.disabledStylesHost   = HOST_TEMPLATE.cloneNode(false);\n\n    // Remove placeholder before copying (as the placeholder has an affect on the computed style)\n    if (hasPlaceholder) {\n      textareaElement.removeAttribute(\"placeholder\");\n    }\n\n    if (textareaElement === originalActiveElement) {\n      textareaElement.blur();\n    }\n\n    // enable for copying styles\n    textareaElement.disabled = false;\n\n    // set textarea to display=\"none\" to get cascaded styles via getComputedStyle\n    textareaElement.style.display = displayValueForCopying = \"none\";\n\n    if ((textareaElement.getAttribute(\"rows\") && dom.getStyle(\"height\").from(textareaElement) === \"auto\") ||\n        (textareaElement.getAttribute(\"cols\") && dom.getStyle(\"width\").from(textareaElement) === \"auto\")) {\n      textareaElement.style.display = displayValueForCopying = originalDisplayValue;\n    }\n\n    // --------- iframe styles (has to be set before editor styles, otherwise IE9 sets wrong fontFamily on blurStylesHost) ---------\n    dom.copyStyles(BOX_FORMATTING).from(textareaElement).to(this.editableArea).andTo(this.blurStylesHost);\n\n    // --------- editor styles ---------\n    dom.copyStyles(TEXT_FORMATTING).from(textareaElement).to(this.element).andTo(this.blurStylesHost);\n\n    // --------- apply standard rules ---------\n    dom.insertCSS(ADDITIONAL_CSS_RULES).into(this.element.ownerDocument);\n\n    // --------- :disabled styles ---------\n    textareaElement.disabled = true;\n    dom.copyStyles(BOX_FORMATTING).from(textareaElement).to(this.disabledStylesHost);\n    dom.copyStyles(TEXT_FORMATTING).from(textareaElement).to(this.disabledStylesHost);\n    textareaElement.disabled = originalDisabled;\n\n    // --------- :focus styles ---------\n    textareaElement.style.display = originalDisplayValue;\n    focusWithoutScrolling(textareaElement);\n    textareaElement.style.display = displayValueForCopying;\n\n    dom.copyStyles(BOX_FORMATTING).from(textareaElement).to(this.focusStylesHost);\n    dom.copyStyles(TEXT_FORMATTING).from(textareaElement).to(this.focusStylesHost);\n\n    // reset textarea\n    textareaElement.style.display = originalDisplayValue;\n\n    dom.copyStyles([\"display\"]).from(textareaElement).to(this.editableArea);\n\n    // Make sure that we don't change the display style of the iframe when copying styles oblur/onfocus\n    // this is needed for when the change_view event is fired where the iframe is hidden and then\n    // the blur event fires and re-displays it\n    var boxFormattingStyles = wysihtml5.lang.array(BOX_FORMATTING).without([\"display\"]);\n\n    // --------- restore focus ---------\n    if (originalActiveElement) {\n      originalActiveElement.focus();\n    } else {\n      textareaElement.blur();\n    }\n\n    // --------- restore placeholder ---------\n    if (hasPlaceholder) {\n      textareaElement.setAttribute(\"placeholder\", originalPlaceholder);\n    }\n\n    // --------- Sync focus/blur styles ---------\n    this.parent.on(\"focus:composer\", function() {\n      dom.copyStyles(boxFormattingStyles) .from(that.focusStylesHost).to(that.editableArea);\n      dom.copyStyles(TEXT_FORMATTING)     .from(that.focusStylesHost).to(that.element);\n    });\n\n    this.parent.on(\"blur:composer\", function() {\n      dom.copyStyles(boxFormattingStyles) .from(that.blurStylesHost).to(that.editableArea);\n      dom.copyStyles(TEXT_FORMATTING)     .from(that.blurStylesHost).to(that.element);\n    });\n\n    this.parent.observe(\"disable:composer\", function() {\n      dom.copyStyles(boxFormattingStyles) .from(that.disabledStylesHost).to(that.editableArea);\n      dom.copyStyles(TEXT_FORMATTING)     .from(that.disabledStylesHost).to(that.element);\n    });\n\n    this.parent.observe(\"enable:composer\", function() {\n      dom.copyStyles(boxFormattingStyles) .from(that.blurStylesHost).to(that.editableArea);\n      dom.copyStyles(TEXT_FORMATTING)     .from(that.blurStylesHost).to(that.element);\n    });\n\n    return this;\n  };\n})(wysihtml5);\n;/**\n * Taking care of events\n *  - Simulating 'change' event on contentEditable element\n *  - Handling drag & drop logic\n *  - Catch paste events\n *  - Dispatch proprietary newword:composer event\n *  - Keyboard shortcuts\n */\n(function(wysihtml5) {\n  var dom       = wysihtml5.dom,\n      browser   = wysihtml5.browser,\n      /**\n       * Map keyCodes to query commands\n       */\n      shortcuts = {\n        \"66\": \"bold\",     // B\n        \"73\": \"italic\",   // I\n        \"85\": \"underline\" // U\n      };\n\n  var deleteAroundEditable = function(selection, uneditable, element) {\n    // merge node with previous node from uneditable\n    var prevNode = selection.getPreviousNode(uneditable, true),\n        curNode = selection.getSelectedNode();\n\n    if (curNode.nodeType !== 1 && curNode.parentNode !== element) { curNode = curNode.parentNode; }\n    if (prevNode) {\n      if (curNode.nodeType == 1) {\n        var first = curNode.firstChild;\n\n        if (prevNode.nodeType == 1) {\n          while (curNode.firstChild) {\n            prevNode.appendChild(curNode.firstChild);\n          }\n        } else {\n          while (curNode.firstChild) {\n            uneditable.parentNode.insertBefore(curNode.firstChild, uneditable);\n          }\n        }\n        if (curNode.parentNode) {\n          curNode.parentNode.removeChild(curNode);\n        }\n        selection.setBefore(first);\n      } else {\n        if (prevNode.nodeType == 1) {\n          prevNode.appendChild(curNode);\n        } else {\n          uneditable.parentNode.insertBefore(curNode, uneditable);\n        }\n        selection.setBefore(curNode);\n      }\n    }\n  };\n\n  var handleDeleteKeyPress = function(event, selection, element, composer) {\n    if (selection.isCollapsed()) {\n      if (selection.caretIsInTheBeginnig('LI')) {\n        event.preventDefault();\n        composer.commands.exec('outdentList');\n      } else if (selection.caretIsInTheBeginnig()) {\n        event.preventDefault();\n      } else {\n\n        if (selection.caretIsFirstInSelection() &&\n            selection.getPreviousNode() &&\n            selection.getPreviousNode().nodeName &&\n            (/^H\\d$/gi).test(selection.getPreviousNode().nodeName)\n        ) {\n          var prevNode = selection.getPreviousNode();\n          event.preventDefault();\n          if ((/^\\s*$/).test(prevNode.textContent || prevNode.innerText)) {\n            // heading is empty\n            prevNode.parentNode.removeChild(prevNode);\n          } else {\n            var range = prevNode.ownerDocument.createRange();\n            range.selectNodeContents(prevNode);\n            range.collapse(false);\n            selection.setSelection(range);\n          }\n        }\n\n        var beforeUneditable = selection.caretIsBeforeUneditable();\n        // Do a special delete if caret would delete uneditable\n        if (beforeUneditable) {\n          event.preventDefault();\n          deleteAroundEditable(selection, beforeUneditable, element);\n        }\n      }\n    } else {\n      if (selection.containsUneditable()) {\n        event.preventDefault();\n        selection.deleteContents();\n      }\n    }\n  };\n\n  var handleTabKeyDown = function(composer, element) {\n    if (!composer.selection.isCollapsed()) {\n      composer.selection.deleteContents();\n    } else if (composer.selection.caretIsInTheBeginnig('LI')) {\n      if (composer.commands.exec('indentList')) return;\n    }\n\n    // Is &emsp; close enough to tab. Could not find enough counter arguments for now.\n    composer.commands.exec(\"insertHTML\", \"&emsp;\");\n  };\n\n  wysihtml5.views.Composer.prototype.observe = function() {\n    var that                = this,\n        state               = this.getValue(false, false),\n        container           = (this.sandbox.getIframe) ? this.sandbox.getIframe() : this.sandbox.getContentEditable(),\n        element             = this.element,\n        focusBlurElement    = (browser.supportsEventsInIframeCorrectly() || this.sandbox.getContentEditable) ? element : this.sandbox.getWindow(),\n        pasteEvents         = [\"drop\", \"paste\", \"beforepaste\"],\n        interactionEvents   = [\"drop\", \"paste\", \"mouseup\", \"focus\", \"keyup\"];\n\n    // --------- destroy:composer event ---------\n    dom.observe(container, \"DOMNodeRemoved\", function() {\n      clearInterval(domNodeRemovedInterval);\n      that.parent.fire(\"destroy:composer\");\n    });\n\n    // DOMNodeRemoved event is not supported in IE 8\n    if (!browser.supportsMutationEvents()) {\n        var domNodeRemovedInterval = setInterval(function() {\n          if (!dom.contains(document.documentElement, container)) {\n            clearInterval(domNodeRemovedInterval);\n            that.parent.fire(\"destroy:composer\");\n          }\n        }, 250);\n    }\n\n    // --------- User interaction tracking --\n\n    dom.observe(focusBlurElement, interactionEvents, function() {\n      setTimeout(function() {\n        that.parent.fire(\"interaction\").fire(\"interaction:composer\");\n      }, 0);\n    });\n\n\n    if (this.config.handleTables) {\n      if(!this.tableClickHandle && this.doc.execCommand && wysihtml5.browser.supportsCommand(this.doc, \"enableObjectResizing\") && wysihtml5.browser.supportsCommand(this.doc, \"enableInlineTableEditing\")) {\n        if (this.sandbox.getIframe) {\n          this.tableClickHandle = dom.observe(container , [\"focus\", \"mouseup\", \"mouseover\"], function() {\n            that.doc.execCommand(\"enableObjectResizing\", false, \"false\");\n            that.doc.execCommand(\"enableInlineTableEditing\", false, \"false\");\n            that.tableClickHandle.stop();\n          });\n        } else {\n          setTimeout(function() {\n            that.doc.execCommand(\"enableObjectResizing\", false, \"false\");\n            that.doc.execCommand(\"enableInlineTableEditing\", false, \"false\");\n          }, 0);\n        }\n      }\n      this.tableSelection = wysihtml5.quirks.tableCellsSelection(element, that.parent);\n    }\n\n    // --------- Focus & blur logic ---------\n    dom.observe(focusBlurElement, \"focus\", function(event) {\n      that.parent.fire(\"focus\", event).fire(\"focus:composer\", event);\n\n      // Delay storing of state until all focus handler are fired\n      // especially the one which resets the placeholder\n      setTimeout(function() { state = that.getValue(false, false); }, 0);\n    });\n\n    dom.observe(focusBlurElement, \"blur\", function(event) {\n      if (state !== that.getValue(false, false)) {\n        //create change event if supported (all except IE8)\n        var changeevent = event;\n        if(typeof Object.create == 'function') {\n          changeevent = Object.create(event, { type: { value: 'change' } });\n        }\n        that.parent.fire(\"change\", changeevent).fire(\"change:composer\", changeevent);\n      }\n      that.parent.fire(\"blur\", event).fire(\"blur:composer\", event);\n    });\n\n    // --------- Drag & Drop logic ---------\n    dom.observe(element, \"dragenter\", function() {\n      that.parent.fire(\"unset_placeholder\");\n    });\n\n    dom.observe(element, pasteEvents, function(event) {\n      that.parent.fire(event.type, event).fire(event.type + \":composer\", event);\n    });\n\n\n    if (this.config.copyedFromMarking) {\n      // If supported the copied source is based directly on selection\n      // Very useful for webkit based browsers where copy will otherwise contain a lot of code and styles based on whatever and not actually in selection.\n      dom.observe(element, \"copy\", function(event) {\n        if (event.clipboardData) {\n          event.clipboardData.setData(\"text/html\", that.config.copyedFromMarking + that.selection.getHtml());\n          event.preventDefault();\n        }\n        that.parent.fire(event.type, event).fire(event.type + \":composer\", event);\n      });\n    }\n\n    // --------- neword event ---------\n    dom.observe(element, \"keyup\", function(event) {\n      var keyCode = event.keyCode;\n      if (keyCode === wysihtml5.SPACE_KEY || keyCode === wysihtml5.ENTER_KEY) {\n        that.parent.fire(\"newword:composer\");\n      }\n    });\n\n    this.parent.on(\"paste:composer\", function() {\n      setTimeout(function() { that.parent.fire(\"newword:composer\"); }, 0);\n    });\n\n    // --------- Make sure that images are selected when clicking on them ---------\n    if (!browser.canSelectImagesInContentEditable()) {\n      dom.observe(element, \"mousedown\", function(event) {\n        var target = event.target;\n        var allImages = element.querySelectorAll('img'),\n            notMyImages = element.querySelectorAll('.' + that.config.uneditableContainerClassname + ' img'),\n            myImages = wysihtml5.lang.array(allImages).without(notMyImages);\n\n        if (target.nodeName === \"IMG\" && wysihtml5.lang.array(myImages).contains(target)) {\n          that.selection.selectNode(target);\n        }\n      });\n    }\n\n    if (!browser.canSelectImagesInContentEditable()) {\n        dom.observe(element, \"drop\", function(event) {\n            // TODO: if I knew how to get dropped elements list from event I could limit it to only IMG element case\n            setTimeout(function() {\n                that.selection.getSelection().removeAllRanges();\n            }, 0);\n        });\n    }\n\n    if (browser.hasHistoryIssue() && browser.supportsSelectionModify()) {\n      dom.observe(element, \"keydown\", function(event) {\n        if (!event.metaKey && !event.ctrlKey) {\n          return;\n        }\n\n        var keyCode   = event.keyCode,\n            win       = element.ownerDocument.defaultView,\n            selection = win.getSelection();\n\n        if (keyCode === 37 || keyCode === 39) {\n          if (keyCode === 37) {\n            selection.modify(\"extend\", \"left\", \"lineboundary\");\n            if (!event.shiftKey) {\n              selection.collapseToStart();\n            }\n          }\n          if (keyCode === 39) {\n            selection.modify(\"extend\", \"right\", \"lineboundary\");\n            if (!event.shiftKey) {\n              selection.collapseToEnd();\n            }\n          }\n          event.preventDefault();\n        }\n      });\n    }\n\n    // --------- Shortcut logic ---------\n    dom.observe(element, \"keydown\", function(event) {\n      var keyCode  = event.keyCode,\n          command  = shortcuts[keyCode];\n      if ((event.ctrlKey || event.metaKey) && !event.altKey && command) {\n        that.commands.exec(command);\n        event.preventDefault();\n      }\n      if (keyCode === 8) {\n        // delete key\n        handleDeleteKeyPress(event, that.selection, element, that);\n      } else if (that.config.handleTabKey && keyCode === 9) {\n        event.preventDefault();\n        handleTabKeyDown(that, element);\n      }\n    });\n\n    // --------- Make sure that when pressing backspace/delete on selected images deletes the image and it's anchor ---------\n    dom.observe(element, \"keydown\", function(event) {\n      var target  = that.selection.getSelectedNode(true),\n          keyCode = event.keyCode,\n          parent;\n      if (target && target.nodeName === \"IMG\" && (keyCode === wysihtml5.BACKSPACE_KEY || keyCode === wysihtml5.DELETE_KEY)) { // 8 => backspace, 46 => delete\n        parent = target.parentNode;\n        // delete the <img>\n        parent.removeChild(target);\n        // and it's parent <a> too if it hasn't got any other child nodes\n        if (parent.nodeName === \"A\" && !parent.firstChild) {\n          parent.parentNode.removeChild(parent);\n        }\n\n        setTimeout(function() { wysihtml5.quirks.redraw(element); }, 0);\n        event.preventDefault();\n      }\n    });\n\n    // --------- IE 8+9 focus the editor when the iframe is clicked (without actually firing the 'focus' event on the <body>) ---------\n    if (!this.config.contentEditableMode && browser.hasIframeFocusIssue()) {\n      dom.observe(container, \"focus\", function() {\n        setTimeout(function() {\n          if (that.doc.querySelector(\":focus\") !== that.element) {\n            that.focus();\n          }\n        }, 0);\n      });\n\n      dom.observe(this.element, \"blur\", function() {\n        setTimeout(function() {\n          that.selection.getSelection().removeAllRanges();\n        }, 0);\n      });\n    }\n\n    // --------- Show url in tooltip when hovering links or images ---------\n    var titlePrefixes = {\n      IMG: \"Image: \",\n      A:   \"Link: \"\n    };\n\n    dom.observe(element, \"mouseover\", function(event) {\n      var target   = event.target,\n          nodeName = target.nodeName,\n          title;\n      if (nodeName !== \"A\" && nodeName !== \"IMG\") {\n        return;\n      }\n      var hasTitle = target.hasAttribute(\"title\");\n      if(!hasTitle){\n        title = titlePrefixes[nodeName] + (target.getAttribute(\"href\") || target.getAttribute(\"src\"));\n        target.setAttribute(\"title\", title);\n      }\n    });\n  };\n})(wysihtml5);\n;/**\n * Class that takes care that the value of the composer and the textarea is always in sync\n */\n(function(wysihtml5) {\n  var INTERVAL = 400;\n\n  wysihtml5.views.Synchronizer = Base.extend(\n    /** @scope wysihtml5.views.Synchronizer.prototype */ {\n\n    constructor: function(editor, textarea, composer) {\n      this.editor   = editor;\n      this.textarea = textarea;\n      this.composer = composer;\n\n      this._observe();\n    },\n\n    /**\n     * Sync html from composer to textarea\n     * Takes care of placeholders\n     * @param {Boolean} shouldParseHtml Whether the html should be sanitized before inserting it into the textarea\n     */\n    fromComposerToTextarea: function(shouldParseHtml) {\n      this.textarea.setValue(wysihtml5.lang.string(this.composer.getValue(false, false)).trim(), shouldParseHtml);\n    },\n\n    /**\n     * Sync value of textarea to composer\n     * Takes care of placeholders\n     * @param {Boolean} shouldParseHtml Whether the html should be sanitized before inserting it into the composer\n     */\n    fromTextareaToComposer: function(shouldParseHtml) {\n      var textareaValue = this.textarea.getValue(false, false);\n      if (textareaValue) {\n        this.composer.setValue(textareaValue, shouldParseHtml);\n      } else {\n        this.composer.clear();\n        this.editor.fire(\"set_placeholder\");\n      }\n    },\n\n    /**\n     * Invoke syncing based on view state\n     * @param {Boolean} shouldParseHtml Whether the html should be sanitized before inserting it into the composer/textarea\n     */\n    sync: function(shouldParseHtml) {\n      if (this.editor.currentView.name === \"textarea\") {\n        this.fromTextareaToComposer(shouldParseHtml);\n      } else {\n        this.fromComposerToTextarea(shouldParseHtml);\n      }\n    },\n\n    /**\n     * Initializes interval-based syncing\n     * also makes sure that on-submit the composer's content is synced with the textarea\n     * immediately when the form gets submitted\n     */\n    _observe: function() {\n      var interval,\n          that          = this,\n          form          = this.textarea.element.form,\n          startInterval = function() {\n            interval = setInterval(function() { that.fromComposerToTextarea(); }, INTERVAL);\n          },\n          stopInterval  = function() {\n            clearInterval(interval);\n            interval = null;\n          };\n\n      startInterval();\n\n      if (form) {\n        // If the textarea is in a form make sure that after onreset and onsubmit the composer\n        // has the correct state\n        wysihtml5.dom.observe(form, \"submit\", function() {\n          that.sync(true);\n        });\n        wysihtml5.dom.observe(form, \"reset\", function() {\n          setTimeout(function() { that.fromTextareaToComposer(); }, 0);\n        });\n      }\n\n      this.editor.on(\"change_view\", function(view) {\n        if (view === \"composer\" && !interval) {\n          that.fromTextareaToComposer(true);\n          startInterval();\n        } else if (view === \"textarea\") {\n          that.fromComposerToTextarea(true);\n          stopInterval();\n        }\n      });\n\n      this.editor.on(\"destroy:composer\", stopInterval);\n    }\n  });\n})(wysihtml5);\n;wysihtml5.views.Textarea = wysihtml5.views.View.extend(\n  /** @scope wysihtml5.views.Textarea.prototype */ {\n  name: \"textarea\",\n\n  constructor: function(parent, textareaElement, config) {\n    this.base(parent, textareaElement, config);\n\n    this._observe();\n  },\n\n  clear: function() {\n    this.element.value = \"\";\n  },\n\n  getValue: function(parse) {\n    var value = this.isEmpty() ? \"\" : this.element.value;\n    if (parse !== false) {\n      value = this.parent.parse(value);\n    }\n    return value;\n  },\n\n  setValue: function(html, parse) {\n    if (parse) {\n      html = this.parent.parse(html);\n    }\n    this.element.value = html;\n  },\n\n  cleanUp: function() {\n      var html = this.parent.parse(this.element.value);\n      this.element.value = html;\n  },\n\n  hasPlaceholderSet: function() {\n    var supportsPlaceholder = wysihtml5.browser.supportsPlaceholderAttributeOn(this.element),\n        placeholderText     = this.element.getAttribute(\"placeholder\") || null,\n        value               = this.element.value,\n        isEmpty             = !value;\n    return (supportsPlaceholder && isEmpty) || (value === placeholderText);\n  },\n\n  isEmpty: function() {\n    return !wysihtml5.lang.string(this.element.value).trim() || this.hasPlaceholderSet();\n  },\n\n  _observe: function() {\n    var element = this.element,\n        parent  = this.parent,\n        eventMapping = {\n          focusin:  \"focus\",\n          focusout: \"blur\"\n        },\n        /**\n         * Calling focus() or blur() on an element doesn't synchronously trigger the attached focus/blur events\n         * This is the case for focusin and focusout, so let's use them whenever possible, kkthxbai\n         */\n        events = wysihtml5.browser.supportsEvent(\"focusin\") ? [\"focusin\", \"focusout\", \"change\"] : [\"focus\", \"blur\", \"change\"];\n\n    parent.on(\"beforeload\", function() {\n      wysihtml5.dom.observe(element, events, function(event) {\n        var eventName = eventMapping[event.type] || event.type;\n        parent.fire(eventName).fire(eventName + \":textarea\");\n      });\n\n      wysihtml5.dom.observe(element, [\"paste\", \"drop\"], function() {\n        setTimeout(function() { parent.fire(\"paste\").fire(\"paste:textarea\"); }, 0);\n      });\n    });\n  }\n});\n;/**\n * WYSIHTML5 Editor\n *\n * @param {Element} editableElement Reference to the textarea which should be turned into a rich text interface\n * @param {Object} [config] See defaultConfig object below for explanation of each individual config option\n *\n * @events\n *    load\n *    beforeload (for internal use only)\n *    focus\n *    focus:composer\n *    focus:textarea\n *    blur\n *    blur:composer\n *    blur:textarea\n *    change\n *    change:composer\n *    change:textarea\n *    paste\n *    paste:composer\n *    paste:textarea\n *    newword:composer\n *    destroy:composer\n *    undo:composer\n *    redo:composer\n *    beforecommand:composer\n *    aftercommand:composer\n *    enable:composer\n *    disable:composer\n *    change_view\n */\n(function(wysihtml5) {\n  var undef;\n\n  var defaultConfig = {\n    // Give the editor a name, the name will also be set as class name on the iframe and on the iframe's body\n    name:                 undef,\n    // Whether the editor should look like the textarea (by adopting styles)\n    style:                true,\n    // Id of the toolbar element, pass falsey value if you don't want any toolbar logic\n    toolbar:              undef,\n    // Whether toolbar is displayed after init by script automatically.\n    // Can be set to false if toolobar is set to display only on editable area focus\n    showToolbarAfterInit: true,\n    // Whether urls, entered by the user should automatically become clickable-links\n    autoLink:             true,\n    // Includes table editing events and cell selection tracking\n    handleTables:         true,\n    // Tab key inserts tab into text as default behaviour. It can be disabled to regain keyboard navigation\n    handleTabKey:         true,\n    // Object which includes parser rules to apply when html gets cleaned\n    // See parser_rules/*.js for examples\n    parserRules:          { tags: { br: {}, span: {}, div: {}, p: {} }, classes: {} },\n    // Object which includes parser when the user inserts content via copy & paste. If null parserRules will be used instead\n    pasteParserRulesets: null,\n    // Parser method to use when the user inserts content\n    parser:               wysihtml5.dom.parse,\n    // Class name which should be set on the contentEditable element in the created sandbox iframe, can be styled via the 'stylesheets' option\n    composerClassName:    \"wysihtml5-editor\",\n    // Class name to add to the body when the wysihtml5 editor is supported\n    bodyClassName:        \"wysihtml5-supported\",\n    // By default wysihtml5 will insert a <br> for line breaks, set this to false to use <p>\n    useLineBreaks:        true,\n    // Array (or single string) of stylesheet urls to be loaded in the editor's iframe\n    stylesheets:          [],\n    // Placeholder text to use, defaults to the placeholder attribute on the textarea element\n    placeholderText:      undef,\n    // Whether the rich text editor should be rendered on touch devices (wysihtml5 >= 0.3.0 comes with basic support for iOS 5)\n    supportTouchDevices:  true,\n    // Whether senseless <span> elements (empty or without attributes) should be removed/replaced with their content\n    cleanUp:              true,\n    // Whether to use div instead of secure iframe\n    contentEditableMode: false,\n    // Classname of container that editor should not touch and pass through\n    // Pass false to disable\n    uneditableContainerClassname: \"wysihtml5-uneditable-container\",\n    // Browsers that support copied source handling will get a marking of the origin of the copied source (for determinig code cleanup rules on paste)\n    // Also copied source is based directly on selection - \n    // (very useful for webkit based browsers where copy will otherwise contain a lot of code and styles based on whatever and not actually in selection).\n    // If falsy value is passed source override is also disabled\n    copyedFromMarking: '<meta name=\"copied-from\" content=\"wysihtml5\">'\n  };\n\n  wysihtml5.Editor = wysihtml5.lang.Dispatcher.extend(\n    /** @scope wysihtml5.Editor.prototype */ {\n    constructor: function(editableElement, config) {\n      this.editableElement  = typeof(editableElement) === \"string\" ? document.getElementById(editableElement) : editableElement;\n      this.config           = wysihtml5.lang.object({}).merge(defaultConfig).merge(config).get();\n      this._isCompatible    = wysihtml5.browser.supported();\n\n      if (this.editableElement.nodeName.toLowerCase() != \"textarea\") {\n          this.config.contentEditableMode = true;\n          this.config.noTextarea = true;\n      }\n      if (!this.config.noTextarea) {\n          this.textarea         = new wysihtml5.views.Textarea(this, this.editableElement, this.config);\n          this.currentView      = this.textarea;\n      }\n\n      // Sort out unsupported/unwanted browsers here\n      if (!this._isCompatible || (!this.config.supportTouchDevices && wysihtml5.browser.isTouchDevice())) {\n        var that = this;\n        setTimeout(function() { that.fire(\"beforeload\").fire(\"load\"); }, 0);\n        return;\n      }\n\n      // Add class name to body, to indicate that the editor is supported\n      wysihtml5.dom.addClass(document.body, this.config.bodyClassName);\n\n      this.composer = new wysihtml5.views.Composer(this, this.editableElement, this.config);\n      this.currentView = this.composer;\n\n      if (typeof(this.config.parser) === \"function\") {\n        this._initParser();\n      }\n\n      this.on(\"beforeload\", this.handleBeforeLoad);\n    },\n\n    handleBeforeLoad: function() {\n        if (!this.config.noTextarea) {\n            this.synchronizer = new wysihtml5.views.Synchronizer(this, this.textarea, this.composer);\n        }\n        if (this.config.toolbar) {\n          this.toolbar = new wysihtml5.toolbar.Toolbar(this, this.config.toolbar, this.config.showToolbarAfterInit);\n        }\n    },\n\n    isCompatible: function() {\n      return this._isCompatible;\n    },\n\n    clear: function() {\n      this.currentView.clear();\n      return this;\n    },\n\n    getValue: function(parse, clearInternals) {\n      return this.currentView.getValue(parse, clearInternals);\n    },\n\n    setValue: function(html, parse) {\n      this.fire(\"unset_placeholder\");\n\n      if (!html) {\n        return this.clear();\n      }\n\n      this.currentView.setValue(html, parse);\n      return this;\n    },\n\n    cleanUp: function() {\n        this.currentView.cleanUp();\n    },\n\n    focus: function(setToEnd) {\n      this.currentView.focus(setToEnd);\n      return this;\n    },\n\n    /**\n     * Deactivate editor (make it readonly)\n     */\n    disable: function() {\n      this.currentView.disable();\n      return this;\n    },\n\n    /**\n     * Activate editor\n     */\n    enable: function() {\n      this.currentView.enable();\n      return this;\n    },\n\n    isEmpty: function() {\n      return this.currentView.isEmpty();\n    },\n\n    hasPlaceholderSet: function() {\n      return this.currentView.hasPlaceholderSet();\n    },\n\n    parse: function(htmlOrElement, clearInternals) {\n      var parseContext = (this.config.contentEditableMode) ? document : ((this.composer) ? this.composer.sandbox.getDocument() : null);\n      var returnValue = this.config.parser(htmlOrElement, {\n        \"rules\": this.config.parserRules,\n        \"cleanUp\": this.config.cleanUp,\n        \"context\": parseContext,\n        \"uneditableClass\": this.config.uneditableContainerClassname,\n        \"clearInternals\" : clearInternals\n      });\n      if (typeof(htmlOrElement) === \"object\") {\n        wysihtml5.quirks.redraw(htmlOrElement);\n      }\n      return returnValue;\n    },\n\n    /**\n     * Prepare html parser logic\n     *  - Observes for paste and drop\n     */\n    _initParser: function() {\n      var that = this,\n          oldHtml,\n          cleanHtml;\n\n      if (wysihtml5.browser.supportsModenPaste()) {\n        this.on(\"paste:composer\", function(event) {\n          event.preventDefault();\n          oldHtml = wysihtml5.dom.getPastedHtml(event);\n          if (oldHtml) {\n            that._cleanAndPaste(oldHtml);\n          }\n        });\n\n      } else {\n        this.on(\"beforepaste:composer\", function(event) {\n          event.preventDefault();\n          wysihtml5.dom.getPastedHtmlWithDiv(that.composer, function(pastedHTML) {\n            if (pastedHTML) {\n              that._cleanAndPaste(pastedHTML);\n            }\n          });\n        });\n\n      }\n    },\n\n    _cleanAndPaste: function (oldHtml) {\n      var cleanHtml = wysihtml5.quirks.cleanPastedHTML(oldHtml, {\n        \"referenceNode\": this.composer.element,\n        \"rules\": this.config.pasteParserRulesets || [{\"set\": this.config.parserRules}],\n        \"uneditableClass\": this.config.uneditableContainerClassname\n      });\n      this.composer.selection.deleteContents();\n      this.composer.selection.insertHTML(cleanHtml);\n    }\n  });\n})(wysihtml5);\n;/**\n * Toolbar Dialog\n *\n * @param {Element} link The toolbar link which causes the dialog to show up\n * @param {Element} container The dialog container\n *\n * @example\n *    <!-- Toolbar link -->\n *    <a data-wysihtml5-command=\"insertImage\">insert an image</a>\n *\n *    <!-- Dialog -->\n *    <div data-wysihtml5-dialog=\"insertImage\" style=\"display: none;\">\n *      <label>\n *        URL: <input data-wysihtml5-dialog-field=\"src\" value=\"http://\">\n *      </label>\n *      <label>\n *        Alternative text: <input data-wysihtml5-dialog-field=\"alt\" value=\"\">\n *      </label>\n *    </div>\n *\n *    <script>\n *      var dialog = new wysihtml5.toolbar.Dialog(\n *        document.querySelector(\"[data-wysihtml5-command='insertImage']\"),\n *        document.querySelector(\"[data-wysihtml5-dialog='insertImage']\")\n *      );\n *      dialog.observe(\"save\", function(attributes) {\n *        // do something\n *      });\n *    </script>\n */\n(function(wysihtml5) {\n  var dom                     = wysihtml5.dom,\n      CLASS_NAME_OPENED       = \"wysihtml5-command-dialog-opened\",\n      SELECTOR_FORM_ELEMENTS  = \"input, select, textarea\",\n      SELECTOR_FIELDS         = \"[data-wysihtml5-dialog-field]\",\n      ATTRIBUTE_FIELDS        = \"data-wysihtml5-dialog-field\";\n\n\n  wysihtml5.toolbar.Dialog = wysihtml5.lang.Dispatcher.extend(\n    /** @scope wysihtml5.toolbar.Dialog.prototype */ {\n    constructor: function(link, container) {\n      this.link       = link;\n      this.container  = container;\n    },\n\n    _observe: function() {\n      if (this._observed) {\n        return;\n      }\n\n      var that = this,\n          callbackWrapper = function(event) {\n            var attributes = that._serialize();\n            if (attributes == that.elementToChange) {\n              that.fire(\"edit\", attributes);\n            } else {\n              that.fire(\"save\", attributes);\n            }\n            that.hide();\n            event.preventDefault();\n            event.stopPropagation();\n          };\n\n      dom.observe(that.link, \"click\", function() {\n        if (dom.hasClass(that.link, CLASS_NAME_OPENED)) {\n          setTimeout(function() { that.hide(); }, 0);\n        }\n      });\n\n      dom.observe(this.container, \"keydown\", function(event) {\n        var keyCode = event.keyCode;\n        if (keyCode === wysihtml5.ENTER_KEY) {\n          callbackWrapper(event);\n        }\n        if (keyCode === wysihtml5.ESCAPE_KEY) {\n          that.fire(\"cancel\");\n          that.hide();\n        }\n      });\n\n      dom.delegate(this.container, \"[data-wysihtml5-dialog-action=save]\", \"click\", callbackWrapper);\n\n      dom.delegate(this.container, \"[data-wysihtml5-dialog-action=cancel]\", \"click\", function(event) {\n        that.fire(\"cancel\");\n        that.hide();\n        event.preventDefault();\n        event.stopPropagation();\n      });\n\n      var formElements  = this.container.querySelectorAll(SELECTOR_FORM_ELEMENTS),\n          i             = 0,\n          length        = formElements.length,\n          _clearInterval = function() { clearInterval(that.interval); };\n      for (; i<length; i++) {\n        dom.observe(formElements[i], \"change\", _clearInterval);\n      }\n\n      this._observed = true;\n    },\n\n    /**\n     * Grabs all fields in the dialog and puts them in key=>value style in an object which\n     * then gets returned\n     */\n    _serialize: function() {\n      var data    = this.elementToChange || {},\n          fields  = this.container.querySelectorAll(SELECTOR_FIELDS),\n          length  = fields.length,\n          i       = 0;\n\n      for (; i<length; i++) {\n        data[fields[i].getAttribute(ATTRIBUTE_FIELDS)] = fields[i].value;\n      }\n      return data;\n    },\n\n    /**\n     * Takes the attributes of the \"elementToChange\"\n     * and inserts them in their corresponding dialog input fields\n     *\n     * Assume the \"elementToChange\" looks like this:\n     *    <a href=\"http://www.google.com\" target=\"_blank\">foo</a>\n     *\n     * and we have the following dialog:\n     *    <input type=\"text\" data-wysihtml5-dialog-field=\"href\" value=\"\">\n     *    <input type=\"text\" data-wysihtml5-dialog-field=\"target\" value=\"\">\n     *\n     * after calling _interpolate() the dialog will look like this\n     *    <input type=\"text\" data-wysihtml5-dialog-field=\"href\" value=\"http://www.google.com\">\n     *    <input type=\"text\" data-wysihtml5-dialog-field=\"target\" value=\"_blank\">\n     *\n     * Basically it adopted the attribute values into the corresponding input fields\n     *\n     */\n    _interpolate: function(avoidHiddenFields) {\n      var field,\n          fieldName,\n          newValue,\n          focusedElement = document.querySelector(\":focus\"),\n          fields         = this.container.querySelectorAll(SELECTOR_FIELDS),\n          length         = fields.length,\n          i              = 0;\n      for (; i<length; i++) {\n        field = fields[i];\n\n        // Never change elements where the user is currently typing in\n        if (field === focusedElement) {\n          continue;\n        }\n\n        // Don't update hidden fields\n        // See https://github.com/xing/wysihtml5/pull/14\n        if (avoidHiddenFields && field.type === \"hidden\") {\n          continue;\n        }\n\n        fieldName = field.getAttribute(ATTRIBUTE_FIELDS);\n        newValue  = (this.elementToChange && typeof(this.elementToChange) !== 'boolean') ? (this.elementToChange.getAttribute(fieldName) || \"\") : field.defaultValue;\n        field.value = newValue;\n      }\n    },\n\n    /**\n     * Show the dialog element\n     */\n    show: function(elementToChange) {\n      if (dom.hasClass(this.link, CLASS_NAME_OPENED)) {\n        return;\n      }\n\n      var that        = this,\n          firstField  = this.container.querySelector(SELECTOR_FORM_ELEMENTS);\n      this.elementToChange = elementToChange;\n      this._observe();\n      this._interpolate();\n      if (elementToChange) {\n        this.interval = setInterval(function() { that._interpolate(true); }, 500);\n      }\n      dom.addClass(this.link, CLASS_NAME_OPENED);\n      this.container.style.display = \"\";\n      this.fire(\"show\");\n      if (firstField && !elementToChange) {\n        try {\n          firstField.focus();\n        } catch(e) {}\n      }\n    },\n\n    /**\n     * Hide the dialog element\n     */\n    hide: function() {\n      clearInterval(this.interval);\n      this.elementToChange = null;\n      dom.removeClass(this.link, CLASS_NAME_OPENED);\n      this.container.style.display = \"none\";\n      this.fire(\"hide\");\n    }\n  });\n})(wysihtml5);\n;/**\n * Converts speech-to-text and inserts this into the editor\n * As of now (2011/03/25) this only is supported in Chrome >= 11\n *\n * Note that it sends the recorded audio to the google speech recognition api:\n * http://stackoverflow.com/questions/4361826/does-chrome-have-buil-in-speech-recognition-for-input-type-text-x-webkit-speec\n *\n * Current HTML5 draft can be found here\n * http://lists.w3.org/Archives/Public/public-xg-htmlspeech/2011Feb/att-0020/api-draft.html\n *\n * \"Accessing Google Speech API Chrome 11\"\n * http://mikepultz.com/2011/03/accessing-google-speech-api-chrome-11/\n */\n(function(wysihtml5) {\n  var dom = wysihtml5.dom;\n\n  var linkStyles = {\n    position: \"relative\"\n  };\n\n  var wrapperStyles = {\n    left:     0,\n    margin:   0,\n    opacity:  0,\n    overflow: \"hidden\",\n    padding:  0,\n    position: \"absolute\",\n    top:      0,\n    zIndex:   1\n  };\n\n  var inputStyles = {\n    cursor:     \"inherit\",\n    fontSize:   \"50px\",\n    height:     \"50px\",\n    marginTop:  \"-25px\",\n    outline:    0,\n    padding:    0,\n    position:   \"absolute\",\n    right:      \"-4px\",\n    top:        \"50%\"\n  };\n\n  var inputAttributes = {\n    \"x-webkit-speech\": \"\",\n    \"speech\":          \"\"\n  };\n\n  wysihtml5.toolbar.Speech = function(parent, link) {\n    var input = document.createElement(\"input\");\n    if (!wysihtml5.browser.supportsSpeechApiOn(input)) {\n      link.style.display = \"none\";\n      return;\n    }\n    var lang = parent.editor.textarea.element.getAttribute(\"lang\");\n    if (lang) {\n      inputAttributes.lang = lang;\n    }\n\n    var wrapper = document.createElement(\"div\");\n\n    wysihtml5.lang.object(wrapperStyles).merge({\n      width:  link.offsetWidth  + \"px\",\n      height: link.offsetHeight + \"px\"\n    });\n\n    dom.insert(input).into(wrapper);\n    dom.insert(wrapper).into(link);\n\n    dom.setStyles(inputStyles).on(input);\n    dom.setAttributes(inputAttributes).on(input);\n\n    dom.setStyles(wrapperStyles).on(wrapper);\n    dom.setStyles(linkStyles).on(link);\n\n    var eventName = \"onwebkitspeechchange\" in input ? \"webkitspeechchange\" : \"speechchange\";\n    dom.observe(input, eventName, function() {\n      parent.execCommand(\"insertText\", input.value);\n      input.value = \"\";\n    });\n\n    dom.observe(input, \"click\", function(event) {\n      if (dom.hasClass(link, \"wysihtml5-command-disabled\")) {\n        event.preventDefault();\n      }\n\n      event.stopPropagation();\n    });\n  };\n})(wysihtml5);\n;/**\n * Toolbar\n *\n * @param {Object} parent Reference to instance of Editor instance\n * @param {Element} container Reference to the toolbar container element\n *\n * @example\n *    <div id=\"toolbar\">\n *      <a data-wysihtml5-command=\"createLink\">insert link</a>\n *      <a data-wysihtml5-command=\"formatBlock\" data-wysihtml5-command-value=\"h1\">insert h1</a>\n *    </div>\n *\n *    <script>\n *      var toolbar = new wysihtml5.toolbar.Toolbar(editor, document.getElementById(\"toolbar\"));\n *    </script>\n */\n(function(wysihtml5) {\n  var CLASS_NAME_COMMAND_DISABLED   = \"wysihtml5-command-disabled\",\n      CLASS_NAME_COMMANDS_DISABLED  = \"wysihtml5-commands-disabled\",\n      CLASS_NAME_COMMAND_ACTIVE     = \"wysihtml5-command-active\",\n      CLASS_NAME_ACTION_ACTIVE      = \"wysihtml5-action-active\",\n      dom                           = wysihtml5.dom;\n\n  wysihtml5.toolbar.Toolbar = Base.extend(\n    /** @scope wysihtml5.toolbar.Toolbar.prototype */ {\n    constructor: function(editor, container, showOnInit) {\n      this.editor     = editor;\n      this.container  = typeof(container) === \"string\" ? document.getElementById(container) : container;\n      this.composer   = editor.composer;\n\n      this._getLinks(\"command\");\n      this._getLinks(\"action\");\n\n      this._observe();\n      if (showOnInit) { this.show(); }\n\n      if (editor.config.classNameCommandDisabled != null) {\n        CLASS_NAME_COMMAND_DISABLED = editor.config.classNameCommandDisabled;\n      }\n      if (editor.config.classNameCommandsDisabled != null) {\n        CLASS_NAME_COMMANDS_DISABLED = editor.config.classNameCommandsDisabled;\n      }\n      if (editor.config.classNameCommandActive != null) {\n        CLASS_NAME_COMMAND_ACTIVE = editor.config.classNameCommandActive;\n      }\n      if (editor.config.classNameActionActive != null) {\n        CLASS_NAME_ACTION_ACTIVE = editor.config.classNameActionActive;\n      }\n\n      var speechInputLinks  = this.container.querySelectorAll(\"[data-wysihtml5-command=insertSpeech]\"),\n          length            = speechInputLinks.length,\n          i                 = 0;\n      for (; i<length; i++) {\n        new wysihtml5.toolbar.Speech(this, speechInputLinks[i]);\n      }\n    },\n\n    _getLinks: function(type) {\n      var links   = this[type + \"Links\"] = wysihtml5.lang.array(this.container.querySelectorAll(\"[data-wysihtml5-\" + type + \"]\")).get(),\n          length  = links.length,\n          i       = 0,\n          mapping = this[type + \"Mapping\"] = {},\n          link,\n          group,\n          name,\n          value,\n          dialog;\n      for (; i<length; i++) {\n        link    = links[i];\n        name    = link.getAttribute(\"data-wysihtml5-\" + type);\n        value   = link.getAttribute(\"data-wysihtml5-\" + type + \"-value\");\n        group   = this.container.querySelector(\"[data-wysihtml5-\" + type + \"-group='\" + name + \"']\");\n        dialog  = this._getDialog(link, name);\n\n        mapping[name + \":\" + value] = {\n          link:   link,\n          group:  group,\n          name:   name,\n          value:  value,\n          dialog: dialog,\n          state:  false\n        };\n      }\n    },\n\n    _getDialog: function(link, command) {\n      var that          = this,\n          dialogElement = this.container.querySelector(\"[data-wysihtml5-dialog='\" + command + \"']\"),\n          dialog,\n          caretBookmark;\n\n      if (dialogElement) {\n        if (wysihtml5.toolbar[\"Dialog_\" + command]) {\n            dialog = new wysihtml5.toolbar[\"Dialog_\" + command](link, dialogElement);\n        } else {\n            dialog = new wysihtml5.toolbar.Dialog(link, dialogElement);\n        }\n\n        dialog.on(\"show\", function() {\n          caretBookmark = that.composer.selection.getBookmark();\n\n          that.editor.fire(\"show:dialog\", { command: command, dialogContainer: dialogElement, commandLink: link });\n        });\n\n        dialog.on(\"save\", function(attributes) {\n          if (caretBookmark) {\n            that.composer.selection.setBookmark(caretBookmark);\n          }\n          that._execCommand(command, attributes);\n\n          that.editor.fire(\"save:dialog\", { command: command, dialogContainer: dialogElement, commandLink: link });\n        });\n\n        dialog.on(\"cancel\", function() {\n          that.editor.focus(false);\n          that.editor.fire(\"cancel:dialog\", { command: command, dialogContainer: dialogElement, commandLink: link });\n        });\n      }\n      return dialog;\n    },\n\n    /**\n     * @example\n     *    var toolbar = new wysihtml5.Toolbar();\n     *    // Insert a <blockquote> element or wrap current selection in <blockquote>\n     *    toolbar.execCommand(\"formatBlock\", \"blockquote\");\n     */\n    execCommand: function(command, commandValue) {\n      if (this.commandsDisabled) {\n        return;\n      }\n\n      var commandObj = this.commandMapping[command + \":\" + commandValue];\n\n      // Show dialog when available\n      if (commandObj && commandObj.dialog && !commandObj.state) {\n        commandObj.dialog.show();\n      } else {\n        this._execCommand(command, commandValue);\n      }\n    },\n\n    _execCommand: function(command, commandValue) {\n      // Make sure that composer is focussed (false => don't move caret to the end)\n      this.editor.focus(false);\n\n      this.composer.commands.exec(command, commandValue);\n      this._updateLinkStates();\n    },\n\n    execAction: function(action) {\n      var editor = this.editor;\n      if (action === \"change_view\") {\n        if (editor.textarea) {\n            if (editor.currentView === editor.textarea) {\n              editor.fire(\"change_view\", \"composer\");\n            } else {\n              editor.fire(\"change_view\", \"textarea\");\n            }\n        }\n      }\n      if (action == \"showSource\") {\n          editor.fire(\"showSource\");\n      }\n    },\n\n    _observe: function() {\n      var that      = this,\n          editor    = this.editor,\n          container = this.container,\n          links     = this.commandLinks.concat(this.actionLinks),\n          length    = links.length,\n          i         = 0;\n\n      for (; i<length; i++) {\n        // 'javascript:;' and unselectable=on Needed for IE, but done in all browsers to make sure that all get the same css applied\n        // (you know, a:link { ... } doesn't match anchors with missing href attribute)\n        if (links[i].nodeName === \"A\") {\n          dom.setAttributes({\n            href:         \"javascript:;\",\n            unselectable: \"on\"\n          }).on(links[i]);\n        } else {\n          dom.setAttributes({ unselectable: \"on\" }).on(links[i]);\n        }\n      }\n\n      // Needed for opera and chrome\n      dom.delegate(container, \"[data-wysihtml5-command], [data-wysihtml5-action]\", \"mousedown\", function(event) { event.preventDefault(); });\n\n      dom.delegate(container, \"[data-wysihtml5-command]\", \"click\", function(event) {\n        var link          = this,\n            command       = link.getAttribute(\"data-wysihtml5-command\"),\n            commandValue  = link.getAttribute(\"data-wysihtml5-command-value\");\n        that.execCommand(command, commandValue);\n        event.preventDefault();\n      });\n\n      dom.delegate(container, \"[data-wysihtml5-action]\", \"click\", function(event) {\n        var action = this.getAttribute(\"data-wysihtml5-action\");\n        that.execAction(action);\n        event.preventDefault();\n      });\n\n      editor.on(\"interaction:composer\", function() {\n          that._updateLinkStates();\n      });\n\n      editor.on(\"focus:composer\", function() {\n        that.bookmark = null;\n      });\n\n      if (this.editor.config.handleTables) {\n          editor.on(\"tableselect:composer\", function() {\n              that.container.querySelectorAll('[data-wysihtml5-hiddentools=\"table\"]')[0].style.display = \"\";\n          });\n          editor.on(\"tableunselect:composer\", function() {\n              that.container.querySelectorAll('[data-wysihtml5-hiddentools=\"table\"]')[0].style.display = \"none\";\n          });\n      }\n\n      editor.on(\"change_view\", function(currentView) {\n        // Set timeout needed in order to let the blur event fire first\n        if (editor.textarea) {\n            setTimeout(function() {\n              that.commandsDisabled = (currentView !== \"composer\");\n              that._updateLinkStates();\n              if (that.commandsDisabled) {\n                dom.addClass(container, CLASS_NAME_COMMANDS_DISABLED);\n              } else {\n                dom.removeClass(container, CLASS_NAME_COMMANDS_DISABLED);\n              }\n            }, 0);\n        }\n      });\n    },\n\n    _updateLinkStates: function() {\n\n      var commandMapping    = this.commandMapping,\n          actionMapping     = this.actionMapping,\n          i,\n          state,\n          action,\n          command;\n      // every millisecond counts... this is executed quite often\n      for (i in commandMapping) {\n        command = commandMapping[i];\n        if (this.commandsDisabled) {\n          state = false;\n          dom.removeClass(command.link, CLASS_NAME_COMMAND_ACTIVE);\n          if (command.group) {\n            dom.removeClass(command.group, CLASS_NAME_COMMAND_ACTIVE);\n          }\n          if (command.dialog) {\n            command.dialog.hide();\n          }\n        } else {\n          state = this.composer.commands.state(command.name, command.value);\n          dom.removeClass(command.link, CLASS_NAME_COMMAND_DISABLED);\n          if (command.group) {\n            dom.removeClass(command.group, CLASS_NAME_COMMAND_DISABLED);\n          }\n        }\n        if (command.state === state) {\n          continue;\n        }\n\n        command.state = state;\n        if (state) {\n          dom.addClass(command.link, CLASS_NAME_COMMAND_ACTIVE);\n          if (command.group) {\n            dom.addClass(command.group, CLASS_NAME_COMMAND_ACTIVE);\n          }\n          if (command.dialog) {\n            if (typeof(state) === \"object\" || wysihtml5.lang.object(state).isArray()) {\n\n              if (!command.dialog.multiselect && wysihtml5.lang.object(state).isArray()) {\n                // Grab first and only object/element in state array, otherwise convert state into boolean\n                // to avoid showing a dialog for multiple selected elements which may have different attributes\n                // eg. when two links with different href are selected, the state will be an array consisting of both link elements\n                // but the dialog interface can only update one\n                state = state.length === 1 ? state[0] : true;\n                command.state = state;\n              }\n              command.dialog.show(state);\n            } else {\n              command.dialog.hide();\n            }\n          }\n        } else {\n          dom.removeClass(command.link, CLASS_NAME_COMMAND_ACTIVE);\n          if (command.group) {\n            dom.removeClass(command.group, CLASS_NAME_COMMAND_ACTIVE);\n          }\n          if (command.dialog) {\n            command.dialog.hide();\n          }\n        }\n      }\n\n      for (i in actionMapping) {\n        action = actionMapping[i];\n\n        if (action.name === \"change_view\") {\n          action.state = this.editor.currentView === this.editor.textarea;\n          if (action.state) {\n            dom.addClass(action.link, CLASS_NAME_ACTION_ACTIVE);\n          } else {\n            dom.removeClass(action.link, CLASS_NAME_ACTION_ACTIVE);\n          }\n        }\n      }\n    },\n\n    show: function() {\n      this.container.style.display = \"\";\n    },\n\n    hide: function() {\n      this.container.style.display = \"none\";\n    }\n  });\n\n})(wysihtml5);\n;(function(wysihtml5) {\n    wysihtml5.toolbar.Dialog_createTable = wysihtml5.toolbar.Dialog.extend({\n        show: function(elementToChange) {\n            this.base(elementToChange);\n\n        }\n\n    });\n})(wysihtml5);\n;(function(wysihtml5) {\n  var dom                     = wysihtml5.dom,\n      SELECTOR_FIELDS         = \"[data-wysihtml5-dialog-field]\",\n      ATTRIBUTE_FIELDS        = \"data-wysihtml5-dialog-field\";\n\n  wysihtml5.toolbar.Dialog_foreColorStyle = wysihtml5.toolbar.Dialog.extend({\n    multiselect: true,\n\n    _serialize: function() {\n      var data    = {},\n          fields  = this.container.querySelectorAll(SELECTOR_FIELDS),\n          length  = fields.length,\n          i       = 0;\n\n      for (; i<length; i++) {\n        data[fields[i].getAttribute(ATTRIBUTE_FIELDS)] = fields[i].value;\n      }\n      return data;\n    },\n\n    _interpolate: function(avoidHiddenFields) {\n      var field,\n          fieldName,\n          newValue,\n          focusedElement = document.querySelector(\":focus\"),\n          fields         = this.container.querySelectorAll(SELECTOR_FIELDS),\n          length         = fields.length,\n          i              = 0,\n          firstElement   = (this.elementToChange) ? ((wysihtml5.lang.object(this.elementToChange).isArray()) ? this.elementToChange[0] : this.elementToChange) : null,\n          colorStr       = (firstElement) ? firstElement.getAttribute('style') : null,\n          color          = (colorStr) ? wysihtml5.quirks.styleParser.parseColor(colorStr, \"color\") : null;\n\n      for (; i<length; i++) {\n        field = fields[i];\n        // Never change elements where the user is currently typing in\n        if (field === focusedElement) {\n          continue;\n        }\n        // Don't update hidden fields3\n        if (avoidHiddenFields && field.type === \"hidden\") {\n          continue;\n        }\n        if (field.getAttribute(ATTRIBUTE_FIELDS) === \"color\") {\n          if (color) {\n            if (color[3] && color[3] != 1) {\n              field.value = \"rgba(\" + color[0] + \",\" + color[1] + \",\" + color[2] + \",\" + color[3] + \");\";\n            } else {\n              field.value = \"rgb(\" + color[0] + \",\" + color[1] + \",\" + color[2] + \");\";\n            }\n          } else {\n            field.value = \"rgb(0,0,0);\";\n          }\n        }\n      }\n    }\n\n  });\n})(wysihtml5);\n;(function(wysihtml5) {\n  var dom                     = wysihtml5.dom,\n      SELECTOR_FIELDS         = \"[data-wysihtml5-dialog-field]\",\n      ATTRIBUTE_FIELDS        = \"data-wysihtml5-dialog-field\";\n\n  wysihtml5.toolbar.Dialog_fontSizeStyle = wysihtml5.toolbar.Dialog.extend({\n    multiselect: true,\n\n    _serialize: function() {\n      return {\"size\" : this.container.querySelector('[data-wysihtml5-dialog-field=\"size\"]').value};\n    },\n\n    _interpolate: function(avoidHiddenFields) {\n      var focusedElement = document.querySelector(\":focus\"),\n          field          = this.container.querySelector(\"[data-wysihtml5-dialog-field='size']\"),\n          firstElement   = (this.elementToChange) ? ((wysihtml5.lang.object(this.elementToChange).isArray()) ? this.elementToChange[0] : this.elementToChange) : null,\n          styleStr       = (firstElement) ? firstElement.getAttribute('style') : null,\n          size           = (styleStr) ? wysihtml5.quirks.styleParser.parseFontSize(styleStr) : null;\n\n      if (field && field !== focusedElement && size && !(/^\\s*$/).test(size)) {\n        field.value = size;\n      }\n    }\n\n  });\n})(wysihtml5);\n/*!\n\n handlebars v1.3.0\n\nCopyright (C) 2011 by Yehuda Katz\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n@license\n*/\nvar Handlebars=function(){var a=function(){\"use strict\";function a(a){this.string=a}var b;return a.prototype.toString=function(){return\"\"+this.string},b=a}(),b=function(a){\"use strict\";function b(a){return h[a]||\"&amp;\"}function c(a,b){for(var c in b)Object.prototype.hasOwnProperty.call(b,c)&&(a[c]=b[c])}function d(a){return a instanceof g?a.toString():a||0===a?(a=\"\"+a,j.test(a)?a.replace(i,b):a):\"\"}function e(a){return a||0===a?m(a)&&0===a.length?!0:!1:!0}var f={},g=a,h={\"&\":\"&amp;\",\"<\":\"&lt;\",\">\":\"&gt;\",'\"':\"&quot;\",\"'\":\"&#x27;\",\"`\":\"&#x60;\"},i=/[&<>\"'`]/g,j=/[&<>\"'`]/;f.extend=c;var k=Object.prototype.toString;f.toString=k;var l=function(a){return\"function\"==typeof a};l(/x/)&&(l=function(a){return\"function\"==typeof a&&\"[object Function]\"===k.call(a)});var l;f.isFunction=l;var m=Array.isArray||function(a){return a&&\"object\"==typeof a?\"[object Array]\"===k.call(a):!1};return f.isArray=m,f.escapeExpression=d,f.isEmpty=e,f}(a),c=function(){\"use strict\";function a(a,b){var d;b&&b.firstLine&&(d=b.firstLine,a+=\" - \"+d+\":\"+b.firstColumn);for(var e=Error.prototype.constructor.call(this,a),f=0;f<c.length;f++)this[c[f]]=e[c[f]];d&&(this.lineNumber=d,this.column=b.firstColumn)}var b,c=[\"description\",\"fileName\",\"lineNumber\",\"message\",\"name\",\"number\",\"stack\"];return a.prototype=new Error,b=a}(),d=function(a,b){\"use strict\";function c(a,b){this.helpers=a||{},this.partials=b||{},d(this)}function d(a){a.registerHelper(\"helperMissing\",function(a){if(2===arguments.length)return void 0;throw new h(\"Missing helper: '\"+a+\"'\")}),a.registerHelper(\"blockHelperMissing\",function(b,c){var d=c.inverse||function(){},e=c.fn;return m(b)&&(b=b.call(this)),b===!0?e(this):b===!1||null==b?d(this):l(b)?b.length>0?a.helpers.each(b,c):d(this):e(b)}),a.registerHelper(\"each\",function(a,b){var c,d=b.fn,e=b.inverse,f=0,g=\"\";if(m(a)&&(a=a.call(this)),b.data&&(c=q(b.data)),a&&\"object\"==typeof a)if(l(a))for(var h=a.length;h>f;f++)c&&(c.index=f,c.first=0===f,c.last=f===a.length-1),g+=d(a[f],{data:c});else for(var i in a)a.hasOwnProperty(i)&&(c&&(c.key=i,c.index=f,c.first=0===f),g+=d(a[i],{data:c}),f++);return 0===f&&(g=e(this)),g}),a.registerHelper(\"if\",function(a,b){return m(a)&&(a=a.call(this)),!b.hash.includeZero&&!a||g.isEmpty(a)?b.inverse(this):b.fn(this)}),a.registerHelper(\"unless\",function(b,c){return a.helpers[\"if\"].call(this,b,{fn:c.inverse,inverse:c.fn,hash:c.hash})}),a.registerHelper(\"with\",function(a,b){return m(a)&&(a=a.call(this)),g.isEmpty(a)?void 0:b.fn(a)}),a.registerHelper(\"log\",function(b,c){var d=c.data&&null!=c.data.level?parseInt(c.data.level,10):1;a.log(d,b)})}function e(a,b){p.log(a,b)}var f={},g=a,h=b,i=\"1.3.0\";f.VERSION=i;var j=4;f.COMPILER_REVISION=j;var k={1:\"<= 1.0.rc.2\",2:\"== 1.0.0-rc.3\",3:\"== 1.0.0-rc.4\",4:\">= 1.0.0\"};f.REVISION_CHANGES=k;var l=g.isArray,m=g.isFunction,n=g.toString,o=\"[object Object]\";f.HandlebarsEnvironment=c,c.prototype={constructor:c,logger:p,log:e,registerHelper:function(a,b,c){if(n.call(a)===o){if(c||b)throw new h(\"Arg not supported with multiple helpers\");g.extend(this.helpers,a)}else c&&(b.not=c),this.helpers[a]=b},registerPartial:function(a,b){n.call(a)===o?g.extend(this.partials,a):this.partials[a]=b}};var p={methodMap:{0:\"debug\",1:\"info\",2:\"warn\",3:\"error\"},DEBUG:0,INFO:1,WARN:2,ERROR:3,level:3,log:function(a,b){if(p.level<=a){var c=p.methodMap[a];\"undefined\"!=typeof console&&console[c]&&console[c].call(console,b)}}};f.logger=p,f.log=e;var q=function(a){var b={};return g.extend(b,a),b};return f.createFrame=q,f}(b,c),e=function(a,b,c){\"use strict\";function d(a){var b=a&&a[0]||1,c=m;if(b!==c){if(c>b){var d=n[c],e=n[b];throw new l(\"Template was precompiled with an older version of Handlebars than the current runtime. Please update your precompiler to a newer version (\"+d+\") or downgrade your runtime to an older version (\"+e+\").\")}throw new l(\"Template was precompiled with a newer version of Handlebars than the current runtime. Please update your runtime to a newer version (\"+a[1]+\").\")}}function e(a,b){if(!b)throw new l(\"No environment passed to template\");var c=function(a,c,d,e,f,g){var h=b.VM.invokePartial.apply(this,arguments);if(null!=h)return h;if(b.compile){var i={helpers:e,partials:f,data:g};return f[c]=b.compile(a,{data:void 0!==g},b),f[c](d,i)}throw new l(\"The partial \"+c+\" could not be compiled when running in runtime-only mode\")},d={escapeExpression:k.escapeExpression,invokePartial:c,programs:[],program:function(a,b,c){var d=this.programs[a];return c?d=g(a,b,c):d||(d=this.programs[a]=g(a,b)),d},merge:function(a,b){var c=a||b;return a&&b&&a!==b&&(c={},k.extend(c,b),k.extend(c,a)),c},programWithDepth:b.VM.programWithDepth,noop:b.VM.noop,compilerInfo:null};return function(c,e){e=e||{};var f,g,h=e.partial?e:b;e.partial||(f=e.helpers,g=e.partials);var i=a.call(d,h,c,f,g,e.data);return e.partial||b.VM.checkRevision(d.compilerInfo),i}}function f(a,b,c){var d=Array.prototype.slice.call(arguments,3),e=function(a,e){return e=e||{},b.apply(this,[a,e.data||c].concat(d))};return e.program=a,e.depth=d.length,e}function g(a,b,c){var d=function(a,d){return d=d||{},b(a,d.data||c)};return d.program=a,d.depth=0,d}function h(a,b,c,d,e,f){var g={partial:!0,helpers:d,partials:e,data:f};if(void 0===a)throw new l(\"The partial \"+b+\" could not be found\");return a instanceof Function?a(c,g):void 0}function i(){return\"\"}var j={},k=a,l=b,m=c.COMPILER_REVISION,n=c.REVISION_CHANGES;return j.checkRevision=d,j.template=e,j.programWithDepth=f,j.program=g,j.invokePartial=h,j.noop=i,j}(b,c,d),f=function(a,b,c,d,e){\"use strict\";var f,g=a,h=b,i=c,j=d,k=e,l=function(){var a=new g.HandlebarsEnvironment;return j.extend(a,g),a.SafeString=h,a.Exception=i,a.Utils=j,a.VM=k,a.template=function(b){return k.template(b,a)},a},m=l();return m.create=l,f=m}(d,a,c,b,e);return f}();this[\"wysihtml5\"] = this[\"wysihtml5\"] || {};\nthis[\"wysihtml5\"][\"tpl\"] = this[\"wysihtml5\"][\"tpl\"] || {};\n\nthis[\"wysihtml5\"][\"tpl\"][\"blockquote\"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {\n  this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers, Handlebars.helpers); data = data || {};\n  var buffer = \"\", stack1, functionType=\"function\", escapeExpression=this.escapeExpression, self=this;\n\nfunction program1(depth0,data) {\n  \n  var buffer = \"\", stack1;\n  buffer += \"btn-\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1));\n  return buffer;\n  }\n\nfunction program3(depth0,data) {\n  \n  \n  return \" \\n      <span class=\\\"fa fa-quote-left\\\"></span>\\n    \";\n  }\n\nfunction program5(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"glyphicon glyphicon-quote\\\"></span>\\n    \";\n  }\n\n  buffer += \"<li>\\n  <a class=\\\"btn \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \" btn-default\\\" data-wysihtml5-command=\\\"formatBlock\\\" data-wysihtml5-command-value=\\\"blockquote\\\" data-wysihtml5-display-format-name=\\\"false\\\" tabindex=\\\"-1\\\">\\n    \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.fa), {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\n  </a>\\n</li>\\n\";\n  return buffer;\n  });\n\nthis[\"wysihtml5\"][\"tpl\"][\"color\"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {\n  this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers, Handlebars.helpers); data = data || {};\n  var buffer = \"\", stack1, functionType=\"function\", escapeExpression=this.escapeExpression, self=this;\n\nfunction program1(depth0,data) {\n  \n  var buffer = \"\", stack1;\n  buffer += \"btn-\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1));\n  return buffer;\n  }\n\n  buffer += \"<li class=\\\"dropdown\\\">\\n  <a class=\\\"btn btn-default dropdown-toggle \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\\" data-toggle=\\\"dropdown\\\" tabindex=\\\"-1\\\">\\n    <span class=\\\"current-color\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.colours)),stack1 == null || stack1 === false ? stack1 : stack1.black)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</span>\\n    <b class=\\\"caret\\\"></b>\\n  </a>\\n  <ul class=\\\"dropdown-menu\\\">\\n    <li><div class=\\\"wysihtml5-colors\\\" data-wysihtml5-command-value=\\\"black\\\"></div><a class=\\\"wysihtml5-colors-title\\\" data-wysihtml5-command=\\\"foreColor\\\" data-wysihtml5-command-value=\\\"black\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.colours)),stack1 == null || stack1 === false ? stack1 : stack1.black)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><div class=\\\"wysihtml5-colors\\\" data-wysihtml5-command-value=\\\"silver\\\"></div><a class=\\\"wysihtml5-colors-title\\\" data-wysihtml5-command=\\\"foreColor\\\" data-wysihtml5-command-value=\\\"silver\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.colours)),stack1 == null || stack1 === false ? stack1 : stack1.silver)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><div class=\\\"wysihtml5-colors\\\" data-wysihtml5-command-value=\\\"gray\\\"></div><a class=\\\"wysihtml5-colors-title\\\" data-wysihtml5-command=\\\"foreColor\\\" data-wysihtml5-command-value=\\\"gray\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.colours)),stack1 == null || stack1 === false ? stack1 : stack1.gray)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><div class=\\\"wysihtml5-colors\\\" data-wysihtml5-command-value=\\\"maroon\\\"></div><a class=\\\"wysihtml5-colors-title\\\" data-wysihtml5-command=\\\"foreColor\\\" data-wysihtml5-command-value=\\\"maroon\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.colours)),stack1 == null || stack1 === false ? stack1 : stack1.maroon)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><div class=\\\"wysihtml5-colors\\\" data-wysihtml5-command-value=\\\"red\\\"></div><a class=\\\"wysihtml5-colors-title\\\" data-wysihtml5-command=\\\"foreColor\\\" data-wysihtml5-command-value=\\\"red\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.colours)),stack1 == null || stack1 === false ? stack1 : stack1.red)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><div class=\\\"wysihtml5-colors\\\" data-wysihtml5-command-value=\\\"purple\\\"></div><a class=\\\"wysihtml5-colors-title\\\" data-wysihtml5-command=\\\"foreColor\\\" data-wysihtml5-command-value=\\\"purple\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.colours)),stack1 == null || stack1 === false ? stack1 : stack1.purple)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><div class=\\\"wysihtml5-colors\\\" data-wysihtml5-command-value=\\\"green\\\"></div><a class=\\\"wysihtml5-colors-title\\\" data-wysihtml5-command=\\\"foreColor\\\" data-wysihtml5-command-value=\\\"green\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.colours)),stack1 == null || stack1 === false ? stack1 : stack1.green)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><div class=\\\"wysihtml5-colors\\\" data-wysihtml5-command-value=\\\"olive\\\"></div><a class=\\\"wysihtml5-colors-title\\\" data-wysihtml5-command=\\\"foreColor\\\" data-wysihtml5-command-value=\\\"olive\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.colours)),stack1 == null || stack1 === false ? stack1 : stack1.olive)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><div class=\\\"wysihtml5-colors\\\" data-wysihtml5-command-value=\\\"navy\\\"></div><a class=\\\"wysihtml5-colors-title\\\" data-wysihtml5-command=\\\"foreColor\\\" data-wysihtml5-command-value=\\\"navy\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.colours)),stack1 == null || stack1 === false ? stack1 : stack1.navy)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><div class=\\\"wysihtml5-colors\\\" data-wysihtml5-command-value=\\\"blue\\\"></div><a class=\\\"wysihtml5-colors-title\\\" data-wysihtml5-command=\\\"foreColor\\\" data-wysihtml5-command-value=\\\"blue\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.colours)),stack1 == null || stack1 === false ? stack1 : stack1.blue)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><div class=\\\"wysihtml5-colors\\\" data-wysihtml5-command-value=\\\"orange\\\"></div><a class=\\\"wysihtml5-colors-title\\\" data-wysihtml5-command=\\\"foreColor\\\" data-wysihtml5-command-value=\\\"orange\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.colours)),stack1 == null || stack1 === false ? stack1 : stack1.orange)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n  </ul>\\n</li>\\n\";\n  return buffer;\n  });\n\nthis[\"wysihtml5\"][\"tpl\"][\"emphasis\"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {\n  this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers, Handlebars.helpers); data = data || {};\n  var buffer = \"\", stack1, functionType=\"function\", escapeExpression=this.escapeExpression, self=this;\n\nfunction program1(depth0,data) {\n  \n  var buffer = \"\", stack1;\n  buffer += \"btn-\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1));\n  return buffer;\n  }\n\nfunction program3(depth0,data) {\n  \n  var buffer = \"\", stack1;\n  buffer += \"\\n    <a class=\\\"btn \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \" btn-default\\\" data-wysihtml5-command=\\\"small\\\" title=\\\"CTRL+S\\\" tabindex=\\\"-1\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.emphasis)),stack1 == null || stack1 === false ? stack1 : stack1.small)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a>\\n    \";\n  return buffer;\n  }\n\n  buffer += \"<li>\\n  <div class=\\\"btn-group\\\">\\n    <a class=\\\"btn \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \" btn-default\\\" data-wysihtml5-command=\\\"bold\\\" title=\\\"CTRL+B\\\" tabindex=\\\"-1\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.emphasis)),stack1 == null || stack1 === false ? stack1 : stack1.bold)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a>\\n    <a class=\\\"btn \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \" btn-default\\\" data-wysihtml5-command=\\\"italic\\\" title=\\\"CTRL+I\\\" tabindex=\\\"-1\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.emphasis)),stack1 == null || stack1 === false ? stack1 : stack1.italic)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a>\\n    <a class=\\\"btn \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \" btn-default\\\" data-wysihtml5-command=\\\"underline\\\" title=\\\"CTRL+U\\\" tabindex=\\\"-1\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.emphasis)),stack1 == null || stack1 === false ? stack1 : stack1.underline)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a>\\n    \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.emphasis)),stack1 == null || stack1 === false ? stack1 : stack1.small), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\n  </div>\\n</li>\\n\";\n  return buffer;\n  });\n\nthis[\"wysihtml5\"][\"tpl\"][\"font-styles\"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {\n  this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers, Handlebars.helpers); data = data || {};\n  var buffer = \"\", stack1, functionType=\"function\", escapeExpression=this.escapeExpression, self=this;\n\nfunction program1(depth0,data) {\n  \n  var buffer = \"\", stack1;\n  buffer += \"btn-\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1));\n  return buffer;\n  }\n\nfunction program3(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"fa fa-font\\\"></span>\\n    \";\n  }\n\nfunction program5(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"glyphicon glyphicon-font\\\"></span>\\n    \";\n  }\n\n  buffer += \"<li class=\\\"dropdown\\\">\\n  <a class=\\\"btn btn-default dropdown-toggle \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\\" data-toggle=\\\"dropdown\\\">\\n    \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.fa), {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\n    <span class=\\\"current-font\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.font_styles)),stack1 == null || stack1 === false ? stack1 : stack1.normal)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</span>\\n    <b class=\\\"caret\\\"></b>\\n  </a>\\n  <ul class=\\\"dropdown-menu\\\">\\n    <li><a data-wysihtml5-command=\\\"formatBlock\\\" data-wysihtml5-command-value=\\\"p\\\" tabindex=\\\"-1\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.font_styles)),stack1 == null || stack1 === false ? stack1 : stack1.normal)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><a data-wysihtml5-command=\\\"formatBlock\\\" data-wysihtml5-command-value=\\\"h1\\\" tabindex=\\\"-1\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.font_styles)),stack1 == null || stack1 === false ? stack1 : stack1.h1)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><a data-wysihtml5-command=\\\"formatBlock\\\" data-wysihtml5-command-value=\\\"h2\\\" tabindex=\\\"-1\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.font_styles)),stack1 == null || stack1 === false ? stack1 : stack1.h2)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><a data-wysihtml5-command=\\\"formatBlock\\\" data-wysihtml5-command-value=\\\"h3\\\" tabindex=\\\"-1\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.font_styles)),stack1 == null || stack1 === false ? stack1 : stack1.h3)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><a data-wysihtml5-command=\\\"formatBlock\\\" data-wysihtml5-command-value=\\\"h4\\\" tabindex=\\\"-1\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.font_styles)),stack1 == null || stack1 === false ? stack1 : stack1.h4)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><a data-wysihtml5-command=\\\"formatBlock\\\" data-wysihtml5-command-value=\\\"h5\\\" tabindex=\\\"-1\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.font_styles)),stack1 == null || stack1 === false ? stack1 : stack1.h5)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n    <li><a data-wysihtml5-command=\\\"formatBlock\\\" data-wysihtml5-command-value=\\\"h6\\\" tabindex=\\\"-1\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.font_styles)),stack1 == null || stack1 === false ? stack1 : stack1.h6)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a></li>\\n  </ul>\\n</li>\\n\";\n  return buffer;\n  });\n\nthis[\"wysihtml5\"][\"tpl\"][\"html\"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {\n  this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers, Handlebars.helpers); data = data || {};\n  var buffer = \"\", stack1, functionType=\"function\", escapeExpression=this.escapeExpression, self=this;\n\nfunction program1(depth0,data) {\n  \n  var buffer = \"\", stack1;\n  buffer += \"btn-\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1));\n  return buffer;\n  }\n\nfunction program3(depth0,data) {\n  \n  \n  return \"\\n        <span class=\\\"fa fa-pencil\\\"></span>\\n      \";\n  }\n\nfunction program5(depth0,data) {\n  \n  \n  return \"\\n        <span class=\\\"glyphicon glyphicon-pencil\\\"></span>\\n      \";\n  }\n\n  buffer += \"<li>\\n  <div class=\\\"btn-group\\\">\\n    <a class=\\\"btn \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \" btn-default\\\" data-wysihtml5-action=\\\"change_view\\\" title=\\\"\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.html)),stack1 == null || stack1 === false ? stack1 : stack1.edit)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"\\\" tabindex=\\\"-1\\\">\\n      \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.fa), {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\n    </a>\\n  </div>\\n</li>\\n\";\n  return buffer;\n  });\n\nthis[\"wysihtml5\"][\"tpl\"][\"image\"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {\n  this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers, Handlebars.helpers); data = data || {};\n  var buffer = \"\", stack1, functionType=\"function\", escapeExpression=this.escapeExpression, self=this;\n\nfunction program1(depth0,data) {\n  \n  \n  return \"modal-sm\";\n  }\n\nfunction program3(depth0,data) {\n  \n  var buffer = \"\", stack1;\n  buffer += \"btn-\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1));\n  return buffer;\n  }\n\nfunction program5(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"fa fa-file-image-o\\\"></span>\\n    \";\n  }\n\nfunction program7(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"glyphicon glyphicon-picture\\\"></span>\\n    \";\n  }\n\n  buffer += \"<li>\\n  <div class=\\\"bootstrap-wysihtml5-insert-image-modal modal fade\\\" data-wysihtml5-dialog=\\\"insertImage\\\">\\n    <div class=\\\"modal-dialog \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.smallmodals), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\\">\\n      <div class=\\\"modal-content\\\">\\n        <div class=\\\"modal-header\\\">\\n          <a class=\\\"close\\\" data-dismiss=\\\"modal\\\">&times;</a>\\n          <h3>\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.image)),stack1 == null || stack1 === false ? stack1 : stack1.insert)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</h3>\\n        </div>\\n        <div class=\\\"modal-body\\\">\\n          <div class=\\\"form-group\\\">\\n            <input value=\\\"http://\\\" class=\\\"bootstrap-wysihtml5-insert-image-url form-control\\\" data-wysihtml5-dialog-field=\\\"src\\\">\\n          </div> \\n        </div>\\n        <div class=\\\"modal-footer\\\">\\n          <a class=\\\"btn btn-default\\\" data-dismiss=\\\"modal\\\" data-wysihtml5-dialog-action=\\\"cancel\\\" href=\\\"#\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.image)),stack1 == null || stack1 === false ? stack1 : stack1.cancel)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a>\\n          <a class=\\\"btn btn-primary\\\" data-dismiss=\\\"modal\\\"  data-wysihtml5-dialog-action=\\\"save\\\" href=\\\"#\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.image)),stack1 == null || stack1 === false ? stack1 : stack1.insert)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a>\\n        </div>\\n      </div>\\n    </div>\\n  </div>\\n  <a class=\\\"btn \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \" btn-default\\\" data-wysihtml5-command=\\\"insertImage\\\" title=\\\"\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.image)),stack1 == null || stack1 === false ? stack1 : stack1.insert)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"\\\" tabindex=\\\"-1\\\">\\n    \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.fa), {hash:{},inverse:self.program(7, program7, data),fn:self.program(5, program5, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\n  </a>\\n</li>\\n\";\n  return buffer;\n  });\n\nthis[\"wysihtml5\"][\"tpl\"][\"link\"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {\n  this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers, Handlebars.helpers); data = data || {};\n  var buffer = \"\", stack1, functionType=\"function\", escapeExpression=this.escapeExpression, self=this;\n\nfunction program1(depth0,data) {\n  \n  \n  return \"modal-sm\";\n  }\n\nfunction program3(depth0,data) {\n  \n  var buffer = \"\", stack1;\n  buffer += \"btn-\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1));\n  return buffer;\n  }\n\nfunction program5(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"fa fa-share-square-o\\\"></span>\\n    \";\n  }\n\nfunction program7(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"glyphicon glyphicon-share\\\"></span>\\n    \";\n  }\n\n  buffer += \"<li>\\n  <div class=\\\"bootstrap-wysihtml5-insert-link-modal modal fade\\\" data-wysihtml5-dialog=\\\"createLink\\\">\\n    <div class=\\\"modal-dialog \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.smallmodals), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\\">\\n      <div class=\\\"modal-content\\\">\\n        <div class=\\\"modal-header\\\">\\n          <a class=\\\"close\\\" data-dismiss=\\\"modal\\\">&times;</a>\\n          <h3>\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.link)),stack1 == null || stack1 === false ? stack1 : stack1.insert)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</h3>\\n        </div>\\n        <div class=\\\"modal-body\\\">\\n          <div class=\\\"form-group\\\">\\n            <input value=\\\"http://\\\" class=\\\"bootstrap-wysihtml5-insert-link-url form-control\\\" data-wysihtml5-dialog-field=\\\"href\\\">\\n          </div> \\n          <div class=\\\"checkbox\\\">\\n            <label> \\n              <input type=\\\"checkbox\\\" class=\\\"bootstrap-wysihtml5-insert-link-target\\\" checked>\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.link)),stack1 == null || stack1 === false ? stack1 : stack1.target)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"\\n            </label>\\n          </div>\\n        </div>\\n        <div class=\\\"modal-footer\\\">\\n          <a class=\\\"btn btn-default\\\" data-dismiss=\\\"modal\\\" data-wysihtml5-dialog-action=\\\"cancel\\\" href=\\\"#\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.link)),stack1 == null || stack1 === false ? stack1 : stack1.cancel)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a>\\n          <a href=\\\"#\\\" class=\\\"btn btn-primary\\\" data-dismiss=\\\"modal\\\" data-wysihtml5-dialog-action=\\\"save\\\">\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.link)),stack1 == null || stack1 === false ? stack1 : stack1.insert)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"</a>\\n        </div>\\n      </div>\\n    </div>\\n  </div>\\n  <a class=\\\"btn \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(3, program3, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \" btn-default\\\" data-wysihtml5-command=\\\"createLink\\\" title=\\\"\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.link)),stack1 == null || stack1 === false ? stack1 : stack1.insert)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"\\\" tabindex=\\\"-1\\\">\\n    \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.fa), {hash:{},inverse:self.program(7, program7, data),fn:self.program(5, program5, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\n  </a>\\n</li>\\n\";\n  return buffer;\n  });\n\nthis[\"wysihtml5\"][\"tpl\"][\"lists\"] = Handlebars.template(function (Handlebars,depth0,helpers,partials,data) {\n  this.compilerInfo = [4,'>= 1.0.0'];\nhelpers = this.merge(helpers, Handlebars.helpers); data = data || {};\n  var buffer = \"\", stack1, functionType=\"function\", escapeExpression=this.escapeExpression, self=this;\n\nfunction program1(depth0,data) {\n  \n  var buffer = \"\", stack1;\n  buffer += \"btn-\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1));\n  return buffer;\n  }\n\nfunction program3(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"fa fa-list-ul\\\"></span>\\n    \";\n  }\n\nfunction program5(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"glyphicon glyphicon-list\\\"></span>\\n    \";\n  }\n\nfunction program7(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"fa fa-list-ol\\\"></span>\\n    \";\n  }\n\nfunction program9(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"glyphicon glyphicon-th-list\\\"></span>\\n    \";\n  }\n\nfunction program11(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"fa fa-outdent\\\"></span>\\n    \";\n  }\n\nfunction program13(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"glyphicon glyphicon-indent-right\\\"></span>\\n    \";\n  }\n\nfunction program15(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"fa fa-indent\\\"></span>\\n    \";\n  }\n\nfunction program17(depth0,data) {\n  \n  \n  return \"\\n      <span class=\\\"glyphicon glyphicon-indent-left\\\"></span>\\n    \";\n  }\n\n  buffer += \"<li>\\n  <div class=\\\"btn-group\\\">\\n    <a class=\\\"btn \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \" btn-default\\\" data-wysihtml5-command=\\\"insertUnorderedList\\\" title=\\\"\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.lists)),stack1 == null || stack1 === false ? stack1 : stack1.unordered)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"\\\" tabindex=\\\"-1\\\">\\n    \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.fa), {hash:{},inverse:self.program(5, program5, data),fn:self.program(3, program3, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\n    </a>\\n    <a class=\\\"btn \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \" btn-default\\\" data-wysihtml5-command=\\\"insertOrderedList\\\" title=\\\"\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.lists)),stack1 == null || stack1 === false ? stack1 : stack1.ordered)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"\\\" tabindex=\\\"-1\\\">\\n    \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.fa), {hash:{},inverse:self.program(9, program9, data),fn:self.program(7, program7, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\n    </a>\\n    <a class=\\\"btn \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \" btn-default\\\" data-wysihtml5-command=\\\"Outdent\\\" title=\\\"\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.lists)),stack1 == null || stack1 === false ? stack1 : stack1.outdent)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"\\\" tabindex=\\\"-1\\\">\\n    \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.fa), {hash:{},inverse:self.program(13, program13, data),fn:self.program(11, program11, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\n    </a>\\n    <a class=\\\"btn \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.size), {hash:{},inverse:self.noop,fn:self.program(1, program1, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \" btn-default\\\" data-wysihtml5-command=\\\"Indent\\\" title=\\\"\"\n    + escapeExpression(((stack1 = ((stack1 = ((stack1 = (depth0 && depth0.locale)),stack1 == null || stack1 === false ? stack1 : stack1.lists)),stack1 == null || stack1 === false ? stack1 : stack1.indent)),typeof stack1 === functionType ? stack1.apply(depth0) : stack1))\n    + \"\\\" tabindex=\\\"-1\\\">\\n    \";\n  stack1 = helpers['if'].call(depth0, ((stack1 = ((stack1 = (depth0 && depth0.options)),stack1 == null || stack1 === false ? stack1 : stack1.toolbar)),stack1 == null || stack1 === false ? stack1 : stack1.fa), {hash:{},inverse:self.program(17, program17, data),fn:self.program(15, program15, data),data:data});\n  if(stack1 || stack1 === 0) { buffer += stack1; }\n  buffer += \"\\n    </a>\\n  </div>\\n</li>\\n\";\n  return buffer;\n  });(function (factory) {\n  'use strict';\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define('bootstrap.wysihtml5', ['jquery', 'wysihtml5', 'bootstrap', 'bootstrap.wysihtml5.templates', 'bootstrap.wysihtml5.commands'], factory);\n  } else {\n    // Browser globals\n    factory(jQuery, wysihtml5); // jshint ignore:line\n  }\n}(function ($, wysihtml5) {\n  'use strict';\n  var bsWysihtml5 = function($, wysihtml5) {\n\n    var templates = function(key, locale, options) {\n      if(wysihtml5.tpl[key]) {\n        return wysihtml5.tpl[key]({locale: locale, options: options});\n      }\n    };\n\n    var Wysihtml5 = function(el, options) {\n      this.el = el;\n      var toolbarOpts = $.extend(true, {}, defaultOptions, options);\n      for(var t in toolbarOpts.customTemplates) {\n        if (toolbarOpts.customTemplates.hasOwnProperty(t)) {\n          wysihtml5.tpl[t] = toolbarOpts.customTemplates[t];\n        }\n      }\n      this.toolbar = this.createToolbar(el, toolbarOpts);\n      this.editor =  this.createEditor(toolbarOpts);\n    };\n\n    Wysihtml5.prototype = {\n\n      constructor: Wysihtml5,\n\n      createEditor: function(options) {\n        options = options || {};\n\n        // Add the toolbar to a clone of the options object so multiple instances\n        // of the WYISYWG don't break because 'toolbar' is already defined\n        options = $.extend(true, {}, options);\n        options.toolbar = this.toolbar[0];\n        \n        this.initializeEditor(this.el[0], options);\n      },\n\n\n      initializeEditor: function(el, options) {\n        var editor = new wysihtml5.Editor(this.el[0], options);\n\n        editor.on('beforeload', this.syncBootstrapDialogEvents);\n        editor.on('beforeload', this.loadParserRules);\n\n        // #30 - body is in IE 10 not created by default, which leads to nullpointer\n        // 2014/02/13 - adapted to wysihtml5-0.4, does not work in IE\n        if(editor.composer.editableArea.contentDocument) {\n          this.addMoreShortcuts(editor, \n                                editor.composer.editableArea.contentDocument.body || editor.composer.editableArea.contentDocument, \n                                options.shortcuts);\n        } else {\n          this.addMoreShortcuts(editor, editor.composer.editableArea, options.shortcuts);    \n        }\n\n        if(options && options.events) {\n          for(var eventName in options.events) {\n            if (options.events.hasOwnProperty(eventName)) {\n              editor.on(eventName, options.events[eventName]);\n            }\n          }\n        }\n\n        return editor;\n      },\n\n      loadParserRules: function() {\n        if($.type(this.config.parserRules) === 'string') {\n          $.ajax({\n            dataType: 'json',\n            url: this.config.parserRules,\n            context: this,\n            error: function (jqXHR, textStatus, errorThrown) {\n              console.log(errorThrown);\n            },\n            success: function (parserRules) {\n              this.config.parserRules = parserRules;\n              console.log('parserrules loaded');\n            }\n          });\n        }\n\n        if(this.config.pasteParserRulesets && $.type(this.config.pasteParserRulesets) === 'string') {\n          $.ajax({\n            dataType: 'json',\n            url: this.config.pasteParserRulesets,\n            context: this,\n            error: function (jqXHR, textStatus, errorThrown) {\n              console.log(errorThrown);\n            },\n            success: function (pasteParserRulesets) {\n              this.config.pasteParserRulesets = pasteParserRulesets;\n            }\n          });\n        }\n      },\n\n      //sync wysihtml5 events for dialogs with bootstrap events\n      syncBootstrapDialogEvents: function() {\n        var editor = this;\n        $.map(this.toolbar.commandMapping, function(value) {\n          return [value];\n        }).filter(function(commandObj) {\n          return commandObj.dialog;\n        }).map(function(commandObj) {\n          return commandObj.dialog;\n        }).forEach(function(dialog) {\n          dialog.on('show', function() {\n            $(this.container).modal('show');\n          });\n          dialog.on('hide', function() {\n            $(this.container).modal('hide');\n            setTimeout(editor.composer.focus, 0);\n          });\n          $(dialog.container).on('shown.bs.modal', function () {\n            $(this).find('input, select, textarea').first().focus();\n          });\n        });\n        this.on('change_view', function() {\n          $(this.toolbar.container.children).find('a.btn').not('[data-wysihtml5-action=\"change_view\"]').toggleClass('disabled');\n        });\n      },\n\n      createToolbar: function(el, options) {\n        var self = this;\n        var toolbar = $('<ul/>', {\n          'class' : 'wysihtml5-toolbar',\n          'style': 'display:none'\n        });\n        var culture = options.locale || defaultOptions.locale || 'en';\n        if(!locale.hasOwnProperty(culture)) {\n          console.debug('Locale \\'' + culture + '\\' not found. Available locales are: ' + Object.keys(locale) + '. Falling back to \\'en\\'.');\n          culture = 'en';\n        }\n        var localeObject = $.extend(true, {}, locale.en, locale[culture]);\n        for(var key in options.toolbar) {\n          if(options.toolbar[key]) {\n            toolbar.append(templates(key, localeObject, options));\n          }\n        }\n\n        toolbar.find('a[data-wysihtml5-command=\"formatBlock\"]').click(function(e) {\n          var target = e.delegateTarget || e.target || e.srcElement,\n          el = $(target),\n          showformat = el.data('wysihtml5-display-format-name'),\n          formatname = el.data('wysihtml5-format-name') || el.html();\n          if(showformat === undefined || showformat === 'true') {\n            self.toolbar.find('.current-font').text(formatname);\n          }\n        });\n\n        toolbar.find('a[data-wysihtml5-command=\"foreColor\"]').click(function(e) {\n          var target = e.target || e.srcElement;\n          var el = $(target);\n          self.toolbar.find('.current-color').text(el.html());\n        });\n\n        this.el.before(toolbar);\n\n        return toolbar;\n      },\n\n      addMoreShortcuts: function(editor, el, shortcuts) {\n        /* some additional shortcuts */\n        wysihtml5.dom.observe(el, 'keydown', function(event) {\n          var keyCode  = event.keyCode,\n          command  = shortcuts[keyCode];\n          if ((event.ctrlKey || event.metaKey || event.altKey) && command && wysihtml5.commands[command]) {\n            var commandObj = editor.toolbar.commandMapping[command + ':null'];\n            if (commandObj && commandObj.dialog && !commandObj.state) {\n              commandObj.dialog.show();\n            } else {\n              wysihtml5.commands[command].exec(editor.composer, command);\n            }\n            event.preventDefault();\n          }\n        });\n      }\n    };\n\n    // these define our public api\n    var methods = {\n      resetDefaults: function() {\n        $.fn.wysihtml5.defaultOptions = $.extend(true, {}, $.fn.wysihtml5.defaultOptionsCache);\n      },\n      bypassDefaults: function(options) {\n        return this.each(function () {\n          var $this = $(this);\n          $this.data('wysihtml5', new Wysihtml5($this, options));\n        });\n      },\n      shallowExtend: function (options) {\n        var settings = $.extend({}, $.fn.wysihtml5.defaultOptions, options || {}, $(this).data());\n        var that = this;\n        return methods.bypassDefaults.apply(that, [settings]);\n      },\n      deepExtend: function(options) {\n        var settings = $.extend(true, {}, $.fn.wysihtml5.defaultOptions, options || {});\n        var that = this;\n        return methods.bypassDefaults.apply(that, [settings]);\n      },\n      init: function(options) {\n        var that = this;\n        return methods.shallowExtend.apply(that, [options]);\n      }\n    };\n\n    $.fn.wysihtml5 = function ( method ) {\n      if ( methods[method] ) {\n        return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));\n      } else if ( typeof method === 'object' || ! method ) {\n        return methods.init.apply( this, arguments );\n      } else {\n        $.error( 'Method ' +  method + ' does not exist on jQuery.wysihtml5' );\n      }    \n    };\n\n    $.fn.wysihtml5.Constructor = Wysihtml5;\n\n    var defaultOptions = $.fn.wysihtml5.defaultOptions = {\n      toolbar: {\n        'font-styles': true,\n        'color': false,\n        'emphasis': {\n          'small': true\n        },\n        'blockquote': true,\n        'lists': true,\n        'html': false,\n        'link': true,\n        'image': true,\n        'smallmodals': false\n      },\n      useLineBreaks: false,\n      parserRules: {\n        classes: {\n          'wysiwyg-color-silver' : 1,\n          'wysiwyg-color-gray' : 1,\n          'wysiwyg-color-white' : 1,\n          'wysiwyg-color-maroon' : 1,\n          'wysiwyg-color-red' : 1,\n          'wysiwyg-color-purple' : 1,\n          'wysiwyg-color-fuchsia' : 1,\n          'wysiwyg-color-green' : 1,\n          'wysiwyg-color-lime' : 1,\n          'wysiwyg-color-olive' : 1,\n          'wysiwyg-color-yellow' : 1,\n          'wysiwyg-color-navy' : 1,\n          'wysiwyg-color-blue' : 1,\n          'wysiwyg-color-teal' : 1,\n          'wysiwyg-color-aqua' : 1,\n          'wysiwyg-color-orange' : 1\n        },\n        tags: {\n          'b':  {},\n          'i':  {},\n          'strong': {},\n          'em': {},\n          'p': {},\n          'br': {},\n          'ol': {},\n          'ul': {},\n          'li': {},\n          'h1': {},\n          'h2': {},\n          'h3': {},\n          'h4': {},\n          'h5': {},\n          'h6': {},\n          'blockquote': {},\n          'u': 1,\n          'img': {\n            'check_attributes': {\n              'width': 'numbers',\n              'alt': 'alt',\n              'src': 'url',\n              'height': 'numbers'\n            }\n          },\n          'a':  {\n            'check_attributes': {\n              'href': 'url'\n            },\n            'set_attributes': {\n              'target': '_blank',\n              'rel': 'nofollow'\n            }\n          },\n          'span': 1,\n          'div': 1,\n          'small': 1,\n          'code': 1,\n          'pre': 1\n        }\n      },\n      locale: 'en',\n      shortcuts: {\n        '83': 'small',// S\n        '75': 'createLink'// K\n      }\n    };\n\n    if (typeof $.fn.wysihtml5.defaultOptionsCache === 'undefined') {\n      $.fn.wysihtml5.defaultOptionsCache = $.extend(true, {}, $.fn.wysihtml5.defaultOptions);\n    }\n\n    var locale = $.fn.wysihtml5.locale = {};\n  };\n  bsWysihtml5($, wysihtml5);\n}));\n(function(wysihtml5) {\n  wysihtml5.commands.small = {\n    exec: function(composer, command) {\n      return wysihtml5.commands.formatInline.exec(composer, command, \"small\");\n    },\n\n    state: function(composer, command) {\n      return wysihtml5.commands.formatInline.state(composer, command, \"small\");\n    }\n  };\n})(wysihtml5);\n\n/**\n * English translation for bootstrap-wysihtml5\n */\n(function (factory) {\n    if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define('bootstrap.wysihtml5.en-US', ['jquery', 'bootstrap.wysihtml5'], factory);\n    } else {\n        // Browser globals\n        factory(jQuery);\n    }\n}(function ($) {\n  $.fn.wysihtml5.locale.en = $.fn.wysihtml5.locale['en-US'] = {\n    font_styles: {\n      normal: '正常',\n      h1: 'h1',\n      h2: 'h2',\n      h3: 'h3',\n      h4: 'h4',\n      h5: 'h5',\n      h6: 'h6'\n    },\n    emphasis: {\n      bold: '粗体',\n      italic: '斜体',\n      underline: '下划线',\n      small: '小号字体'\n    },\n    lists: {\n      unordered: '无序列表',\n      ordered: '有序列表',\n      outdent: '减少缩进',\n      indent: '缩进'\n    },\n    link: {\n      insert: '添加链接',\n      cancel: '取消',\n      target: '在新窗口打开链接'\n    },\n    image: {\n      insert: '插入图像',\n      cancel: '取消'\n    },\n    html: {\n      edit: '编辑HTML'\n    },\n    colours: {\n      black: '黑色',\n      silver: '银色',\n      gray: '灰色',\n      maroon: '褐红色',\n      red: '红色',\n      purple: '紫色',\n      green: '绿色',\n      olive: '橄榄色',\n      navy: '深蓝色',\n      blue: '蓝色',\n      orange: '黄色'\n    }\n  };\n}));\n"
  },
  {
    "path": "public/static/plugins/bootstrap-wysihtml5/bootstrap3-wysihtml5.css",
    "content": "ul.wysihtml5-toolbar {\n\tmargin: 0;\n\tpadding: 0;\n\tdisplay: block;\n}\n\nul.wysihtml5-toolbar::after {\n\tclear: both;\n\tdisplay: table;\n\tcontent: \"\";\n}\n\nul.wysihtml5-toolbar > li {\n\tfloat: left;\n\tdisplay: list-item;\n\tlist-style: none;\n\tmargin: 0 5px 10px 0;\n}\n\nul.wysihtml5-toolbar a[data-wysihtml5-command=bold] {\n\tfont-weight: bold;\n}\n\nul.wysihtml5-toolbar a[data-wysihtml5-command=italic] {\n\tfont-style: italic;\n}\n\nul.wysihtml5-toolbar a[data-wysihtml5-command=underline] {\n\ttext-decoration: underline;\n}\n\nul.wysihtml5-toolbar a.btn.wysihtml5-command-active {\n\tbackground-image: none;\n\t-webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);\n\t-moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);\n\tbox-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15),0 1px 2px rgba(0, 0, 0, 0.05);\n\tbackground-color: #E6E6E6;\n\tbackground-color: #D9D9D9;\n\toutline: 0;\n}\n\nul.wysihtml5-commands-disabled .dropdown-menu {\n\tdisplay: none !important;\n}\n\nul.wysihtml5-toolbar div.wysihtml5-colors {\n  display:block;\n  width: 50px;\n  height: 20px;\n  margin-top: 2px;\n  margin-left: 5px;\n  position: absolute;\n  pointer-events: none;\n}\n\nul.wysihtml5-toolbar a.wysihtml5-colors-title {\n  padding-left: 70px;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"black\"] {\n  background: black !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"silver\"] {\n  background: silver !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"gray\"] {\n  background: gray !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"maroon\"] {\n  background: maroon !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"red\"] {\n  background: red !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"purple\"] {\n  background: purple !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"green\"] {\n  background: green !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"olive\"] {\n  background: olive !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"navy\"] {\n  background: navy !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"blue\"] {\n  background: blue !important;\n}\n\nul.wysihtml5-toolbar div[data-wysihtml5-command-value=\"orange\"] {\n  background: orange !important;\n}\n\n.glyphicon-quote:before {\n  content: \"\\201C\";\n  font-family: Georgia, serif;\n  font-size: 50px;\n  position: absolute;\n  top: -4px;\n  left: -3px;\n  max-height: 100%;\n}\n\n.glyphicon-quote:after {\n  content: \"\\0000a0\";\n}\n\n"
  },
  {
    "path": "public/static/plugins/chartjs/Chart.js",
    "content": "/*!\n * Chart.js\n * http://chartjs.org/\n * Version: 1.0.2\n *\n * Copyright 2015 Nick Downie\n * Released under the MIT license\n * https://github.com/nnnick/Chart.js/blob/master/LICENSE.md\n */\n\n\n(function(){\n\n\t\"use strict\";\n\n\t//Declare root variable - window in the browser, global on the server\n\tvar root = this,\n\t\tprevious = root.Chart;\n\n\t//Occupy the global variable of Chart, and create a simple base class\n\tvar Chart = function(context){\n\t\tvar chart = this;\n\t\tthis.canvas = context.canvas;\n\n\t\tthis.ctx = context;\n\n\t\t//Variables global to the chart\n\t\tvar computeDimension = function(element,dimension)\n\t\t{\n\t\t\tif (element['offset'+dimension])\n\t\t\t{\n\t\t\t\treturn element['offset'+dimension];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn document.defaultView.getComputedStyle(element).getPropertyValue(dimension);\n\t\t\t}\n\t\t}\n\n\t\tvar width = this.width = computeDimension(context.canvas,'Width');\n\t\tvar height = this.height = computeDimension(context.canvas,'Height');\n\n\t\t// Firefox requires this to work correctly\n\t\tcontext.canvas.width  = width;\n\t\tcontext.canvas.height = height;\n\n\t\tvar width = this.width = context.canvas.width;\n\t\tvar height = this.height = context.canvas.height;\n\t\tthis.aspectRatio = this.width / this.height;\n\t\t//High pixel density displays - multiply the size of the canvas height/width by the device pixel ratio, then scale.\n\t\thelpers.retinaScale(this);\n\n\t\treturn this;\n\t};\n\t//Globally expose the defaults to allow for user updating/changing\n\tChart.defaults = {\n\t\tglobal: {\n\t\t\t// Boolean - Whether to animate the chart\n\t\t\tanimation: true,\n\n\t\t\t// Number - Number of animation steps\n\t\t\tanimationSteps: 60,\n\n\t\t\t// String - Animation easing effect\n\t\t\tanimationEasing: \"easeOutQuart\",\n\n\t\t\t// Boolean - If we should show the scale at all\n\t\t\tshowScale: true,\n\n\t\t\t// Boolean - If we want to override with a hard coded scale\n\t\t\tscaleOverride: false,\n\n\t\t\t// ** Required if scaleOverride is true **\n\t\t\t// Number - The number of steps in a hard coded scale\n\t\t\tscaleSteps: null,\n\t\t\t// Number - The value jump in the hard coded scale\n\t\t\tscaleStepWidth: null,\n\t\t\t// Number - The scale starting value\n\t\t\tscaleStartValue: null,\n\n\t\t\t// String - Colour of the scale line\n\t\t\tscaleLineColor: \"rgba(0,0,0,.1)\",\n\n\t\t\t// Number - Pixel width of the scale line\n\t\t\tscaleLineWidth: 1,\n\n\t\t\t// Boolean - Whether to show labels on the scale\n\t\t\tscaleShowLabels: true,\n\n\t\t\t// Interpolated JS string - can access value\n\t\t\tscaleLabel: \"<%=value%>\",\n\n\t\t\t// Boolean - Whether the scale should stick to integers, and not show any floats even if drawing space is there\n\t\t\tscaleIntegersOnly: true,\n\n\t\t\t// Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value\n\t\t\tscaleBeginAtZero: false,\n\n\t\t\t// String - Scale label font declaration for the scale label\n\t\t\tscaleFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\n\t\t\t// Number - Scale label font size in pixels\n\t\t\tscaleFontSize: 12,\n\n\t\t\t// String - Scale label font weight style\n\t\t\tscaleFontStyle: \"normal\",\n\n\t\t\t// String - Scale label font colour\n\t\t\tscaleFontColor: \"#666\",\n\n\t\t\t// Boolean - whether or not the chart should be responsive and resize when the browser does.\n\t\t\tresponsive: false,\n\n\t\t\t// Boolean - whether to maintain the starting aspect ratio or not when responsive, if set to false, will take up entire container\n\t\t\tmaintainAspectRatio: true,\n\n\t\t\t// Boolean - Determines whether to draw tooltips on the canvas or not - attaches events to touchmove & mousemove\n\t\t\tshowTooltips: true,\n\n\t\t\t// Boolean - Determines whether to draw built-in tooltip or call custom tooltip function\n\t\t\tcustomTooltips: false,\n\n\t\t\t// Array - Array of string names to attach tooltip events\n\t\t\ttooltipEvents: [\"mousemove\", \"touchstart\", \"touchmove\", \"mouseout\"],\n\n\t\t\t// String - Tooltip background colour\n\t\t\ttooltipFillColor: \"rgba(0,0,0,0.8)\",\n\n\t\t\t// String - Tooltip label font declaration for the scale label\n\t\t\ttooltipFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\n\t\t\t// Number - Tooltip label font size in pixels\n\t\t\ttooltipFontSize: 14,\n\n\t\t\t// String - Tooltip font weight style\n\t\t\ttooltipFontStyle: \"normal\",\n\n\t\t\t// String - Tooltip label font colour\n\t\t\ttooltipFontColor: \"#fff\",\n\n\t\t\t// String - Tooltip title font declaration for the scale label\n\t\t\ttooltipTitleFontFamily: \"'Helvetica Neue', 'Helvetica', 'Arial', sans-serif\",\n\n\t\t\t// Number - Tooltip title font size in pixels\n\t\t\ttooltipTitleFontSize: 14,\n\n\t\t\t// String - Tooltip title font weight style\n\t\t\ttooltipTitleFontStyle: \"bold\",\n\n\t\t\t// String - Tooltip title font colour\n\t\t\ttooltipTitleFontColor: \"#fff\",\n\n\t\t\t// Number - pixel width of padding around tooltip text\n\t\t\ttooltipYPadding: 6,\n\n\t\t\t// Number - pixel width of padding around tooltip text\n\t\t\ttooltipXPadding: 6,\n\n\t\t\t// Number - Size of the caret on the tooltip\n\t\t\ttooltipCaretSize: 8,\n\n\t\t\t// Number - Pixel radius of the tooltip border\n\t\t\ttooltipCornerRadius: 6,\n\n\t\t\t// Number - Pixel offset from point x to tooltip edge\n\t\t\ttooltipXOffset: 10,\n\n\t\t\t// String - Template string for single tooltips\n\t\t\ttooltipTemplate: \"<%if (label){%><%=label%>: <%}%><%= value %>\",\n\n\t\t\t// String - Template string for single tooltips\n\t\t\tmultiTooltipTemplate: \"<%= value %>\",\n\n\t\t\t// String - Colour behind the legend colour block\n\t\t\tmultiTooltipKeyBackground: '#fff',\n\n\t\t\t// Function - Will fire on animation progression.\n\t\t\tonAnimationProgress: function(){},\n\n\t\t\t// Function - Will fire on animation completion.\n\t\t\tonAnimationComplete: function(){}\n\n\t\t}\n\t};\n\n\t//Create a dictionary of chart types, to allow for extension of existing types\n\tChart.types = {};\n\n\t//Global Chart helpers object for utility methods and classes\n\tvar helpers = Chart.helpers = {};\n\n\t\t//-- Basic js utility methods\n\tvar each = helpers.each = function(loopable,callback,self){\n\t\t\tvar additionalArgs = Array.prototype.slice.call(arguments, 3);\n\t\t\t// Check to see if null or undefined firstly.\n\t\t\tif (loopable){\n\t\t\t\tif (loopable.length === +loopable.length){\n\t\t\t\t\tvar i;\n\t\t\t\t\tfor (i=0; i<loopable.length; i++){\n\t\t\t\t\t\tcallback.apply(self,[loopable[i], i].concat(additionalArgs));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\tfor (var item in loopable){\n\t\t\t\t\t\tcallback.apply(self,[loopable[item],item].concat(additionalArgs));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tclone = helpers.clone = function(obj){\n\t\t\tvar objClone = {};\n\t\t\teach(obj,function(value,key){\n\t\t\t\tif (obj.hasOwnProperty(key)) objClone[key] = value;\n\t\t\t});\n\t\t\treturn objClone;\n\t\t},\n\t\textend = helpers.extend = function(base){\n\t\t\teach(Array.prototype.slice.call(arguments,1), function(extensionObject) {\n\t\t\t\teach(extensionObject,function(value,key){\n\t\t\t\t\tif (extensionObject.hasOwnProperty(key)) base[key] = value;\n\t\t\t\t});\n\t\t\t});\n\t\t\treturn base;\n\t\t},\n\t\tmerge = helpers.merge = function(base,master){\n\t\t\t//Merge properties in left object over to a shallow clone of object right.\n\t\t\tvar args = Array.prototype.slice.call(arguments,0);\n\t\t\targs.unshift({});\n\t\t\treturn extend.apply(null, args);\n\t\t},\n\t\tindexOf = helpers.indexOf = function(arrayToSearch, item){\n\t\t\tif (Array.prototype.indexOf) {\n\t\t\t\treturn arrayToSearch.indexOf(item);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tfor (var i = 0; i < arrayToSearch.length; i++) {\n\t\t\t\t\tif (arrayToSearch[i] === item) return i;\n\t\t\t\t}\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t},\n\t\twhere = helpers.where = function(collection, filterCallback){\n\t\t\tvar filtered = [];\n\n\t\t\thelpers.each(collection, function(item){\n\t\t\t\tif (filterCallback(item)){\n\t\t\t\t\tfiltered.push(item);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn filtered;\n\t\t},\n\t\tfindNextWhere = helpers.findNextWhere = function(arrayToSearch, filterCallback, startIndex){\n\t\t\t// Default to start of the array\n\t\t\tif (!startIndex){\n\t\t\t\tstartIndex = -1;\n\t\t\t}\n\t\t\tfor (var i = startIndex + 1; i < arrayToSearch.length; i++) {\n\t\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\t\tif (filterCallback(currentItem)){\n\t\t\t\t\treturn currentItem;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tfindPreviousWhere = helpers.findPreviousWhere = function(arrayToSearch, filterCallback, startIndex){\n\t\t\t// Default to end of the array\n\t\t\tif (!startIndex){\n\t\t\t\tstartIndex = arrayToSearch.length;\n\t\t\t}\n\t\t\tfor (var i = startIndex - 1; i >= 0; i--) {\n\t\t\t\tvar currentItem = arrayToSearch[i];\n\t\t\t\tif (filterCallback(currentItem)){\n\t\t\t\t\treturn currentItem;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tinherits = helpers.inherits = function(extensions){\n\t\t\t//Basic javascript inheritance based on the model created in Backbone.js\n\t\t\tvar parent = this;\n\t\t\tvar ChartElement = (extensions && extensions.hasOwnProperty(\"constructor\")) ? extensions.constructor : function(){ return parent.apply(this, arguments); };\n\n\t\t\tvar Surrogate = function(){ this.constructor = ChartElement;};\n\t\t\tSurrogate.prototype = parent.prototype;\n\t\t\tChartElement.prototype = new Surrogate();\n\n\t\t\tChartElement.extend = inherits;\n\n\t\t\tif (extensions) extend(ChartElement.prototype, extensions);\n\n\t\t\tChartElement.__super__ = parent.prototype;\n\n\t\t\treturn ChartElement;\n\t\t},\n\t\tnoop = helpers.noop = function(){},\n\t\tuid = helpers.uid = (function(){\n\t\t\tvar id=0;\n\t\t\treturn function(){\n\t\t\t\treturn \"chart-\" + id++;\n\t\t\t};\n\t\t})(),\n\t\twarn = helpers.warn = function(str){\n\t\t\t//Method for warning of errors\n\t\t\tif (window.console && typeof window.console.warn == \"function\") console.warn(str);\n\t\t},\n\t\tamd = helpers.amd = (typeof define == 'function' && define.amd),\n\t\t//-- Math methods\n\t\tisNumber = helpers.isNumber = function(n){\n\t\t\treturn !isNaN(parseFloat(n)) && isFinite(n);\n\t\t},\n\t\tmax = helpers.max = function(array){\n\t\t\treturn Math.max.apply( Math, array );\n\t\t},\n\t\tmin = helpers.min = function(array){\n\t\t\treturn Math.min.apply( Math, array );\n\t\t},\n\t\tcap = helpers.cap = function(valueToCap,maxValue,minValue){\n\t\t\tif(isNumber(maxValue)) {\n\t\t\t\tif( valueToCap > maxValue ) {\n\t\t\t\t\treturn maxValue;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if(isNumber(minValue)){\n\t\t\t\tif ( valueToCap < minValue ){\n\t\t\t\t\treturn minValue;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn valueToCap;\n\t\t},\n\t\tgetDecimalPlaces = helpers.getDecimalPlaces = function(num){\n\t\t\tif (num%1!==0 && isNumber(num)){\n\t\t\t\treturn num.toString().split(\".\")[1].length;\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t},\n\t\ttoRadians = helpers.radians = function(degrees){\n\t\t\treturn degrees * (Math.PI/180);\n\t\t},\n\t\t// Gets the angle from vertical upright to the point about a centre.\n\t\tgetAngleFromPoint = helpers.getAngleFromPoint = function(centrePoint, anglePoint){\n\t\t\tvar distanceFromXCenter = anglePoint.x - centrePoint.x,\n\t\t\t\tdistanceFromYCenter = anglePoint.y - centrePoint.y,\n\t\t\t\tradialDistanceFromCenter = Math.sqrt( distanceFromXCenter * distanceFromXCenter + distanceFromYCenter * distanceFromYCenter);\n\n\n\t\t\tvar angle = Math.PI * 2 + Math.atan2(distanceFromYCenter, distanceFromXCenter);\n\n\t\t\t//If the segment is in the top left quadrant, we need to add another rotation to the angle\n\t\t\tif (distanceFromXCenter < 0 && distanceFromYCenter < 0){\n\t\t\t\tangle += Math.PI*2;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tangle: angle,\n\t\t\t\tdistance: radialDistanceFromCenter\n\t\t\t};\n\t\t},\n\t\taliasPixel = helpers.aliasPixel = function(pixelWidth){\n\t\t\treturn (pixelWidth % 2 === 0) ? 0 : 0.5;\n\t\t},\n\t\tsplineCurve = helpers.splineCurve = function(FirstPoint,MiddlePoint,AfterPoint,t){\n\t\t\t//Props to Rob Spencer at scaled innovation for his post on splining between points\n\t\t\t//http://scaledinnovation.com/analytics/splines/aboutSplines.html\n\t\t\tvar d01=Math.sqrt(Math.pow(MiddlePoint.x-FirstPoint.x,2)+Math.pow(MiddlePoint.y-FirstPoint.y,2)),\n\t\t\t\td12=Math.sqrt(Math.pow(AfterPoint.x-MiddlePoint.x,2)+Math.pow(AfterPoint.y-MiddlePoint.y,2)),\n\t\t\t\tfa=t*d01/(d01+d12),// scaling factor for triangle Ta\n\t\t\t\tfb=t*d12/(d01+d12);\n\t\t\treturn {\n\t\t\t\tinner : {\n\t\t\t\t\tx : MiddlePoint.x-fa*(AfterPoint.x-FirstPoint.x),\n\t\t\t\t\ty : MiddlePoint.y-fa*(AfterPoint.y-FirstPoint.y)\n\t\t\t\t},\n\t\t\t\touter : {\n\t\t\t\t\tx: MiddlePoint.x+fb*(AfterPoint.x-FirstPoint.x),\n\t\t\t\t\ty : MiddlePoint.y+fb*(AfterPoint.y-FirstPoint.y)\n\t\t\t\t}\n\t\t\t};\n\t\t},\n\t\tcalculateOrderOfMagnitude = helpers.calculateOrderOfMagnitude = function(val){\n\t\t\treturn Math.floor(Math.log(val) / Math.LN10);\n\t\t},\n\t\tcalculateScaleRange = helpers.calculateScaleRange = function(valuesArray, drawingSize, textSize, startFromZero, integersOnly){\n\n\t\t\t//Set a minimum step of two - a point at the top of the graph, and a point at the base\n\t\t\tvar minSteps = 2,\n\t\t\t\tmaxSteps = Math.floor(drawingSize/(textSize * 1.5)),\n\t\t\t\tskipFitting = (minSteps >= maxSteps);\n\n\t\t\tvar maxValue = max(valuesArray),\n\t\t\t\tminValue = min(valuesArray);\n\n\t\t\t// We need some degree of seperation here to calculate the scales if all the values are the same\n\t\t\t// Adding/minusing 0.5 will give us a range of 1.\n\t\t\tif (maxValue === minValue){\n\t\t\t\tmaxValue += 0.5;\n\t\t\t\t// So we don't end up with a graph with a negative start value if we've said always start from zero\n\t\t\t\tif (minValue >= 0.5 && !startFromZero){\n\t\t\t\t\tminValue -= 0.5;\n\t\t\t\t}\n\t\t\t\telse{\n\t\t\t\t\t// Make up a whole number above the values\n\t\t\t\t\tmaxValue += 0.5;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tvar\tvalueRange = Math.abs(maxValue - minValue),\n\t\t\t\trangeOrderOfMagnitude = calculateOrderOfMagnitude(valueRange),\n\t\t\t\tgraphMax = Math.ceil(maxValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),\n\t\t\t\tgraphMin = (startFromZero) ? 0 : Math.floor(minValue / (1 * Math.pow(10, rangeOrderOfMagnitude))) * Math.pow(10, rangeOrderOfMagnitude),\n\t\t\t\tgraphRange = graphMax - graphMin,\n\t\t\t\tstepValue = Math.pow(10, rangeOrderOfMagnitude),\n\t\t\t\tnumberOfSteps = Math.round(graphRange / stepValue);\n\n\t\t\t//If we have more space on the graph we'll use it to give more definition to the data\n\t\t\twhile((numberOfSteps > maxSteps || (numberOfSteps * 2) < maxSteps) && !skipFitting) {\n\t\t\t\tif(numberOfSteps > maxSteps){\n\t\t\t\t\tstepValue *=2;\n\t\t\t\t\tnumberOfSteps = Math.round(graphRange/stepValue);\n\t\t\t\t\t// Don't ever deal with a decimal number of steps - cancel fitting and just use the minimum number of steps.\n\t\t\t\t\tif (numberOfSteps % 1 !== 0){\n\t\t\t\t\t\tskipFitting = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//We can fit in double the amount of scale points on the scale\n\t\t\t\telse{\n\t\t\t\t\t//If user has declared ints only, and the step value isn't a decimal\n\t\t\t\t\tif (integersOnly && rangeOrderOfMagnitude >= 0){\n\t\t\t\t\t\t//If the user has said integers only, we need to check that making the scale more granular wouldn't make it a float\n\t\t\t\t\t\tif(stepValue/2 % 1 === 0){\n\t\t\t\t\t\t\tstepValue /=2;\n\t\t\t\t\t\t\tnumberOfSteps = Math.round(graphRange/stepValue);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//If it would make it a float break out of the loop\n\t\t\t\t\t\telse{\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t//If the scale doesn't have to be an int, make the scale more granular anyway.\n\t\t\t\t\telse{\n\t\t\t\t\t\tstepValue /=2;\n\t\t\t\t\t\tnumberOfSteps = Math.round(graphRange/stepValue);\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (skipFitting){\n\t\t\t\tnumberOfSteps = minSteps;\n\t\t\t\tstepValue = graphRange / numberOfSteps;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tsteps : numberOfSteps,\n\t\t\t\tstepValue : stepValue,\n\t\t\t\tmin : graphMin,\n\t\t\t\tmax\t: graphMin + (numberOfSteps * stepValue)\n\t\t\t};\n\n\t\t},\n\t\t/* jshint ignore:start */\n\t\t// Blows up jshint errors based on the new Function constructor\n\t\t//Templating methods\n\t\t//Javascript micro templating by John Resig - source at http://ejohn.org/blog/javascript-micro-templating/\n\t\ttemplate = helpers.template = function(templateString, valuesObject){\n\n\t\t\t// If templateString is function rather than string-template - call the function for valuesObject\n\n\t\t\tif(templateString instanceof Function){\n\t\t\t \treturn templateString(valuesObject);\n\t\t \t}\n\n\t\t\tvar cache = {};\n\t\t\tfunction tmpl(str, data){\n\t\t\t\t// Figure out if we're getting a template, or if we need to\n\t\t\t\t// load the template - and be sure to cache the result.\n\t\t\t\tvar fn = !/\\W/.test(str) ?\n\t\t\t\tcache[str] = cache[str] :\n\n\t\t\t\t// Generate a reusable function that will serve as a template\n\t\t\t\t// generator (and which will be cached).\n\t\t\t\tnew Function(\"obj\",\n\t\t\t\t\t\"var p=[],print=function(){p.push.apply(p,arguments);};\" +\n\n\t\t\t\t\t// Introduce the data as local variables using with(){}\n\t\t\t\t\t\"with(obj){p.push('\" +\n\n\t\t\t\t\t// Convert the template into pure JavaScript\n\t\t\t\t\tstr\n\t\t\t\t\t\t.replace(/[\\r\\t\\n]/g, \" \")\n\t\t\t\t\t\t.split(\"<%\").join(\"\\t\")\n\t\t\t\t\t\t.replace(/((^|%>)[^\\t]*)'/g, \"$1\\r\")\n\t\t\t\t\t\t.replace(/\\t=(.*?)%>/g, \"',$1,'\")\n\t\t\t\t\t\t.split(\"\\t\").join(\"');\")\n\t\t\t\t\t\t.split(\"%>\").join(\"p.push('\")\n\t\t\t\t\t\t.split(\"\\r\").join(\"\\\\'\") +\n\t\t\t\t\t\"');}return p.join('');\"\n\t\t\t\t);\n\n\t\t\t\t// Provide some basic currying to the user\n\t\t\t\treturn data ? fn( data ) : fn;\n\t\t\t}\n\t\t\treturn tmpl(templateString,valuesObject);\n\t\t},\n\t\t/* jshint ignore:end */\n\t\tgenerateLabels = helpers.generateLabels = function(templateString,numberOfSteps,graphMin,stepValue){\n\t\t\tvar labelsArray = new Array(numberOfSteps);\n\t\t\tif (labelTemplateString){\n\t\t\t\teach(labelsArray,function(val,index){\n\t\t\t\t\tlabelsArray[index] = template(templateString,{value: (graphMin + (stepValue*(index+1)))});\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn labelsArray;\n\t\t},\n\t\t//--Animation methods\n\t\t//Easing functions adapted from Robert Penner's easing equations\n\t\t//http://www.robertpenner.com/easing/\n\t\teasingEffects = helpers.easingEffects = {\n\t\t\tlinear: function (t) {\n\t\t\t\treturn t;\n\t\t\t},\n\t\t\teaseInQuad: function (t) {\n\t\t\t\treturn t * t;\n\t\t\t},\n\t\t\teaseOutQuad: function (t) {\n\t\t\t\treturn -1 * t * (t - 2);\n\t\t\t},\n\t\t\teaseInOutQuad: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * t * t;\n\t\t\t\treturn -1 / 2 * ((--t) * (t - 2) - 1);\n\t\t\t},\n\t\t\teaseInCubic: function (t) {\n\t\t\t\treturn t * t * t;\n\t\t\t},\n\t\t\teaseOutCubic: function (t) {\n\t\t\t\treturn 1 * ((t = t / 1 - 1) * t * t + 1);\n\t\t\t},\n\t\t\teaseInOutCubic: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t;\n\t\t\t\treturn 1 / 2 * ((t -= 2) * t * t + 2);\n\t\t\t},\n\t\t\teaseInQuart: function (t) {\n\t\t\t\treturn t * t * t * t;\n\t\t\t},\n\t\t\teaseOutQuart: function (t) {\n\t\t\t\treturn -1 * ((t = t / 1 - 1) * t * t * t - 1);\n\t\t\t},\n\t\t\teaseInOutQuart: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t;\n\t\t\t\treturn -1 / 2 * ((t -= 2) * t * t * t - 2);\n\t\t\t},\n\t\t\teaseInQuint: function (t) {\n\t\t\t\treturn 1 * (t /= 1) * t * t * t * t;\n\t\t\t},\n\t\t\teaseOutQuint: function (t) {\n\t\t\t\treturn 1 * ((t = t / 1 - 1) * t * t * t * t + 1);\n\t\t\t},\n\t\t\teaseInOutQuint: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * t * t * t * t * t;\n\t\t\t\treturn 1 / 2 * ((t -= 2) * t * t * t * t + 2);\n\t\t\t},\n\t\t\teaseInSine: function (t) {\n\t\t\t\treturn -1 * Math.cos(t / 1 * (Math.PI / 2)) + 1;\n\t\t\t},\n\t\t\teaseOutSine: function (t) {\n\t\t\t\treturn 1 * Math.sin(t / 1 * (Math.PI / 2));\n\t\t\t},\n\t\t\teaseInOutSine: function (t) {\n\t\t\t\treturn -1 / 2 * (Math.cos(Math.PI * t / 1) - 1);\n\t\t\t},\n\t\t\teaseInExpo: function (t) {\n\t\t\t\treturn (t === 0) ? 1 : 1 * Math.pow(2, 10 * (t / 1 - 1));\n\t\t\t},\n\t\t\teaseOutExpo: function (t) {\n\t\t\t\treturn (t === 1) ? 1 : 1 * (-Math.pow(2, -10 * t / 1) + 1);\n\t\t\t},\n\t\t\teaseInOutExpo: function (t) {\n\t\t\t\tif (t === 0) return 0;\n\t\t\t\tif (t === 1) return 1;\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * Math.pow(2, 10 * (t - 1));\n\t\t\t\treturn 1 / 2 * (-Math.pow(2, -10 * --t) + 2);\n\t\t\t},\n\t\t\teaseInCirc: function (t) {\n\t\t\t\tif (t >= 1) return t;\n\t\t\t\treturn -1 * (Math.sqrt(1 - (t /= 1) * t) - 1);\n\t\t\t},\n\t\t\teaseOutCirc: function (t) {\n\t\t\t\treturn 1 * Math.sqrt(1 - (t = t / 1 - 1) * t);\n\t\t\t},\n\t\t\teaseInOutCirc: function (t) {\n\t\t\t\tif ((t /= 1 / 2) < 1) return -1 / 2 * (Math.sqrt(1 - t * t) - 1);\n\t\t\t\treturn 1 / 2 * (Math.sqrt(1 - (t -= 2) * t) + 1);\n\t\t\t},\n\t\t\teaseInElastic: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tvar p = 0;\n\t\t\t\tvar a = 1;\n\t\t\t\tif (t === 0) return 0;\n\t\t\t\tif ((t /= 1) == 1) return 1;\n\t\t\t\tif (!p) p = 1 * 0.3;\n\t\t\t\tif (a < Math.abs(1)) {\n\t\t\t\t\ta = 1;\n\t\t\t\t\ts = p / 4;\n\t\t\t\t} else s = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t\treturn -(a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\n\t\t\t},\n\t\t\teaseOutElastic: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tvar p = 0;\n\t\t\t\tvar a = 1;\n\t\t\t\tif (t === 0) return 0;\n\t\t\t\tif ((t /= 1) == 1) return 1;\n\t\t\t\tif (!p) p = 1 * 0.3;\n\t\t\t\tif (a < Math.abs(1)) {\n\t\t\t\t\ta = 1;\n\t\t\t\t\ts = p / 4;\n\t\t\t\t} else s = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t\treturn a * Math.pow(2, -10 * t) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) + 1;\n\t\t\t},\n\t\t\teaseInOutElastic: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tvar p = 0;\n\t\t\t\tvar a = 1;\n\t\t\t\tif (t === 0) return 0;\n\t\t\t\tif ((t /= 1 / 2) == 2) return 1;\n\t\t\t\tif (!p) p = 1 * (0.3 * 1.5);\n\t\t\t\tif (a < Math.abs(1)) {\n\t\t\t\t\ta = 1;\n\t\t\t\t\ts = p / 4;\n\t\t\t\t} else s = p / (2 * Math.PI) * Math.asin(1 / a);\n\t\t\t\tif (t < 1) return -0.5 * (a * Math.pow(2, 10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p));\n\t\t\t\treturn a * Math.pow(2, -10 * (t -= 1)) * Math.sin((t * 1 - s) * (2 * Math.PI) / p) * 0.5 + 1;\n\t\t\t},\n\t\t\teaseInBack: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\treturn 1 * (t /= 1) * t * ((s + 1) * t - s);\n\t\t\t},\n\t\t\teaseOutBack: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\treturn 1 * ((t = t / 1 - 1) * t * ((s + 1) * t + s) + 1);\n\t\t\t},\n\t\t\teaseInOutBack: function (t) {\n\t\t\t\tvar s = 1.70158;\n\t\t\t\tif ((t /= 1 / 2) < 1) return 1 / 2 * (t * t * (((s *= (1.525)) + 1) * t - s));\n\t\t\t\treturn 1 / 2 * ((t -= 2) * t * (((s *= (1.525)) + 1) * t + s) + 2);\n\t\t\t},\n\t\t\teaseInBounce: function (t) {\n\t\t\t\treturn 1 - easingEffects.easeOutBounce(1 - t);\n\t\t\t},\n\t\t\teaseOutBounce: function (t) {\n\t\t\t\tif ((t /= 1) < (1 / 2.75)) {\n\t\t\t\t\treturn 1 * (7.5625 * t * t);\n\t\t\t\t} else if (t < (2 / 2.75)) {\n\t\t\t\t\treturn 1 * (7.5625 * (t -= (1.5 / 2.75)) * t + 0.75);\n\t\t\t\t} else if (t < (2.5 / 2.75)) {\n\t\t\t\t\treturn 1 * (7.5625 * (t -= (2.25 / 2.75)) * t + 0.9375);\n\t\t\t\t} else {\n\t\t\t\t\treturn 1 * (7.5625 * (t -= (2.625 / 2.75)) * t + 0.984375);\n\t\t\t\t}\n\t\t\t},\n\t\t\teaseInOutBounce: function (t) {\n\t\t\t\tif (t < 1 / 2) return easingEffects.easeInBounce(t * 2) * 0.5;\n\t\t\t\treturn easingEffects.easeOutBounce(t * 2 - 1) * 0.5 + 1 * 0.5;\n\t\t\t}\n\t\t},\n\t\t//Request animation polyfill - http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/\n\t\trequestAnimFrame = helpers.requestAnimFrame = (function(){\n\t\t\treturn window.requestAnimationFrame ||\n\t\t\t\twindow.webkitRequestAnimationFrame ||\n\t\t\t\twindow.mozRequestAnimationFrame ||\n\t\t\t\twindow.oRequestAnimationFrame ||\n\t\t\t\twindow.msRequestAnimationFrame ||\n\t\t\t\tfunction(callback) {\n\t\t\t\t\treturn window.setTimeout(callback, 1000 / 60);\n\t\t\t\t};\n\t\t})(),\n\t\tcancelAnimFrame = helpers.cancelAnimFrame = (function(){\n\t\t\treturn window.cancelAnimationFrame ||\n\t\t\t\twindow.webkitCancelAnimationFrame ||\n\t\t\t\twindow.mozCancelAnimationFrame ||\n\t\t\t\twindow.oCancelAnimationFrame ||\n\t\t\t\twindow.msCancelAnimationFrame ||\n\t\t\t\tfunction(callback) {\n\t\t\t\t\treturn window.clearTimeout(callback, 1000 / 60);\n\t\t\t\t};\n\t\t})(),\n\t\tanimationLoop = helpers.animationLoop = function(callback,totalSteps,easingString,onProgress,onComplete,chartInstance){\n\n\t\t\tvar currentStep = 0,\n\t\t\t\teasingFunction = easingEffects[easingString] || easingEffects.linear;\n\n\t\t\tvar animationFrame = function(){\n\t\t\t\tcurrentStep++;\n\t\t\t\tvar stepDecimal = currentStep/totalSteps;\n\t\t\t\tvar easeDecimal = easingFunction(stepDecimal);\n\n\t\t\t\tcallback.call(chartInstance,easeDecimal,stepDecimal, currentStep);\n\t\t\t\tonProgress.call(chartInstance,easeDecimal,stepDecimal);\n\t\t\t\tif (currentStep < totalSteps){\n\t\t\t\t\tchartInstance.animationFrame = requestAnimFrame(animationFrame);\n\t\t\t\t} else{\n\t\t\t\t\tonComplete.apply(chartInstance);\n\t\t\t\t}\n\t\t\t};\n\t\t\trequestAnimFrame(animationFrame);\n\t\t},\n\t\t//-- DOM methods\n\t\tgetRelativePosition = helpers.getRelativePosition = function(evt){\n\t\t\tvar mouseX, mouseY;\n\t\t\tvar e = evt.originalEvent || evt,\n\t\t\t\tcanvas = evt.currentTarget || evt.srcElement,\n\t\t\t\tboundingRect = canvas.getBoundingClientRect();\n\n\t\t\tif (e.touches){\n\t\t\t\tmouseX = e.touches[0].clientX - boundingRect.left;\n\t\t\t\tmouseY = e.touches[0].clientY - boundingRect.top;\n\n\t\t\t}\n\t\t\telse{\n\t\t\t\tmouseX = e.clientX - boundingRect.left;\n\t\t\t\tmouseY = e.clientY - boundingRect.top;\n\t\t\t}\n\n\t\t\treturn {\n\t\t\t\tx : mouseX,\n\t\t\t\ty : mouseY\n\t\t\t};\n\n\t\t},\n\t\taddEvent = helpers.addEvent = function(node,eventType,method){\n\t\t\tif (node.addEventListener){\n\t\t\t\tnode.addEventListener(eventType,method);\n\t\t\t} else if (node.attachEvent){\n\t\t\t\tnode.attachEvent(\"on\"+eventType, method);\n\t\t\t} else {\n\t\t\t\tnode[\"on\"+eventType] = method;\n\t\t\t}\n\t\t},\n\t\tremoveEvent = helpers.removeEvent = function(node, eventType, handler){\n\t\t\tif (node.removeEventListener){\n\t\t\t\tnode.removeEventListener(eventType, handler, false);\n\t\t\t} else if (node.detachEvent){\n\t\t\t\tnode.detachEvent(\"on\"+eventType,handler);\n\t\t\t} else{\n\t\t\t\tnode[\"on\" + eventType] = noop;\n\t\t\t}\n\t\t},\n\t\tbindEvents = helpers.bindEvents = function(chartInstance, arrayOfEvents, handler){\n\t\t\t// Create the events object if it's not already present\n\t\t\tif (!chartInstance.events) chartInstance.events = {};\n\n\t\t\teach(arrayOfEvents,function(eventName){\n\t\t\t\tchartInstance.events[eventName] = function(){\n\t\t\t\t\thandler.apply(chartInstance, arguments);\n\t\t\t\t};\n\t\t\t\taddEvent(chartInstance.chart.canvas,eventName,chartInstance.events[eventName]);\n\t\t\t});\n\t\t},\n\t\tunbindEvents = helpers.unbindEvents = function (chartInstance, arrayOfEvents) {\n\t\t\teach(arrayOfEvents, function(handler,eventName){\n\t\t\t\tremoveEvent(chartInstance.chart.canvas, eventName, handler);\n\t\t\t});\n\t\t},\n\t\tgetMaximumWidth = helpers.getMaximumWidth = function(domNode){\n\t\t\tvar container = domNode.parentNode;\n\t\t\t// TODO = check cross browser stuff with this.\n\t\t\treturn container.clientWidth;\n\t\t},\n\t\tgetMaximumHeight = helpers.getMaximumHeight = function(domNode){\n\t\t\tvar container = domNode.parentNode;\n\t\t\t// TODO = check cross browser stuff with this.\n\t\t\treturn container.clientHeight;\n\t\t},\n\t\tgetMaximumSize = helpers.getMaximumSize = helpers.getMaximumWidth, // legacy support\n\t\tretinaScale = helpers.retinaScale = function(chart){\n\t\t\tvar ctx = chart.ctx,\n\t\t\t\twidth = chart.canvas.width,\n\t\t\t\theight = chart.canvas.height;\n\n\t\t\tif (window.devicePixelRatio) {\n\t\t\t\tctx.canvas.style.width = width + \"px\";\n\t\t\t\tctx.canvas.style.height = height + \"px\";\n\t\t\t\tctx.canvas.height = height * window.devicePixelRatio;\n\t\t\t\tctx.canvas.width = width * window.devicePixelRatio;\n\t\t\t\tctx.scale(window.devicePixelRatio, window.devicePixelRatio);\n\t\t\t}\n\t\t},\n\t\t//-- Canvas methods\n\t\tclear = helpers.clear = function(chart){\n\t\t\tchart.ctx.clearRect(0,0,chart.width,chart.height);\n\t\t},\n\t\tfontString = helpers.fontString = function(pixelSize,fontStyle,fontFamily){\n\t\t\treturn fontStyle + \" \" + pixelSize+\"px \" + fontFamily;\n\t\t},\n\t\tlongestText = helpers.longestText = function(ctx,font,arrayOfStrings){\n\t\t\tctx.font = font;\n\t\t\tvar longest = 0;\n\t\t\teach(arrayOfStrings,function(string){\n\t\t\t\tvar textWidth = ctx.measureText(string).width;\n\t\t\t\tlongest = (textWidth > longest) ? textWidth : longest;\n\t\t\t});\n\t\t\treturn longest;\n\t\t},\n\t\tdrawRoundedRectangle = helpers.drawRoundedRectangle = function(ctx,x,y,width,height,radius){\n\t\t\tctx.beginPath();\n\t\t\tctx.moveTo(x + radius, y);\n\t\t\tctx.lineTo(x + width - radius, y);\n\t\t\tctx.quadraticCurveTo(x + width, y, x + width, y + radius);\n\t\t\tctx.lineTo(x + width, y + height - radius);\n\t\t\tctx.quadraticCurveTo(x + width, y + height, x + width - radius, y + height);\n\t\t\tctx.lineTo(x + radius, y + height);\n\t\t\tctx.quadraticCurveTo(x, y + height, x, y + height - radius);\n\t\t\tctx.lineTo(x, y + radius);\n\t\t\tctx.quadraticCurveTo(x, y, x + radius, y);\n\t\t\tctx.closePath();\n\t\t};\n\n\n\t//Store a reference to each instance - allowing us to globally resize chart instances on window resize.\n\t//Destroy method on the chart will remove the instance of the chart from this reference.\n\tChart.instances = {};\n\n\tChart.Type = function(data,options,chart){\n\t\tthis.options = options;\n\t\tthis.chart = chart;\n\t\tthis.id = uid();\n\t\t//Add the chart instance to the global namespace\n\t\tChart.instances[this.id] = this;\n\n\t\t// Initialize is always called when a chart type is created\n\t\t// By default it is a no op, but it should be extended\n\t\tif (options.responsive){\n\t\t\tthis.resize();\n\t\t}\n\t\tthis.initialize.call(this,data);\n\t};\n\n\t//Core methods that'll be a part of every chart type\n\textend(Chart.Type.prototype,{\n\t\tinitialize : function(){return this;},\n\t\tclear : function(){\n\t\t\tclear(this.chart);\n\t\t\treturn this;\n\t\t},\n\t\tstop : function(){\n\t\t\t// Stops any current animation loop occuring\n\t\t\tcancelAnimFrame(this.animationFrame);\n\t\t\treturn this;\n\t\t},\n\t\tresize : function(callback){\n\t\t\tthis.stop();\n\t\t\tvar canvas = this.chart.canvas,\n\t\t\t\tnewWidth = getMaximumWidth(this.chart.canvas),\n\t\t\t\tnewHeight = this.options.maintainAspectRatio ? newWidth / this.chart.aspectRatio : getMaximumHeight(this.chart.canvas);\n\n\t\t\tcanvas.width = this.chart.width = newWidth;\n\t\t\tcanvas.height = this.chart.height = newHeight;\n\n\t\t\tretinaScale(this.chart);\n\n\t\t\tif (typeof callback === \"function\"){\n\t\t\t\tcallback.apply(this, Array.prototype.slice.call(arguments, 1));\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\treflow : noop,\n\t\trender : function(reflow){\n\t\t\tif (reflow){\n\t\t\t\tthis.reflow();\n\t\t\t}\n\t\t\tif (this.options.animation && !reflow){\n\t\t\t\thelpers.animationLoop(\n\t\t\t\t\tthis.draw,\n\t\t\t\t\tthis.options.animationSteps,\n\t\t\t\t\tthis.options.animationEasing,\n\t\t\t\t\tthis.options.onAnimationProgress,\n\t\t\t\t\tthis.options.onAnimationComplete,\n\t\t\t\t\tthis\n\t\t\t\t);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tthis.draw();\n\t\t\t\tthis.options.onAnimationComplete.call(this);\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\tgenerateLegend : function(){\n\t\t\treturn template(this.options.legendTemplate,this);\n\t\t},\n\t\tdestroy : function(){\n\t\t\tthis.clear();\n\t\t\tunbindEvents(this, this.events);\n\t\t\tvar canvas = this.chart.canvas;\n\n\t\t\t// Reset canvas height/width attributes starts a fresh with the canvas context\n\t\t\tcanvas.width = this.chart.width;\n\t\t\tcanvas.height = this.chart.height;\n\n\t\t\t// < IE9 doesn't support removeProperty\n\t\t\tif (canvas.style.removeProperty) {\n\t\t\t\tcanvas.style.removeProperty('width');\n\t\t\t\tcanvas.style.removeProperty('height');\n\t\t\t} else {\n\t\t\t\tcanvas.style.removeAttribute('width');\n\t\t\t\tcanvas.style.removeAttribute('height');\n\t\t\t}\n\n\t\t\tdelete Chart.instances[this.id];\n\t\t},\n\t\tshowTooltip : function(ChartElements, forceRedraw){\n\t\t\t// Only redraw the chart if we've actually changed what we're hovering on.\n\t\t\tif (typeof this.activeElements === 'undefined') this.activeElements = [];\n\n\t\t\tvar isChanged = (function(Elements){\n\t\t\t\tvar changed = false;\n\n\t\t\t\tif (Elements.length !== this.activeElements.length){\n\t\t\t\t\tchanged = true;\n\t\t\t\t\treturn changed;\n\t\t\t\t}\n\n\t\t\t\teach(Elements, function(element, index){\n\t\t\t\t\tif (element !== this.activeElements[index]){\n\t\t\t\t\t\tchanged = true;\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\t\t\t\treturn changed;\n\t\t\t}).call(this, ChartElements);\n\n\t\t\tif (!isChanged && !forceRedraw){\n\t\t\t\treturn;\n\t\t\t}\n\t\t\telse{\n\t\t\t\tthis.activeElements = ChartElements;\n\t\t\t}\n\t\t\tthis.draw();\n\t\t\tif(this.options.customTooltips){\n\t\t\t\tthis.options.customTooltips(false);\n\t\t\t}\n\t\t\tif (ChartElements.length > 0){\n\t\t\t\t// If we have multiple datasets, show a MultiTooltip for all of the data points at that index\n\t\t\t\tif (this.datasets && this.datasets.length > 1) {\n\t\t\t\t\tvar dataArray,\n\t\t\t\t\t\tdataIndex;\n\n\t\t\t\t\tfor (var i = this.datasets.length - 1; i >= 0; i--) {\n\t\t\t\t\t\tdataArray = this.datasets[i].points || this.datasets[i].bars || this.datasets[i].segments;\n\t\t\t\t\t\tdataIndex = indexOf(dataArray, ChartElements[0]);\n\t\t\t\t\t\tif (dataIndex !== -1){\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tvar tooltipLabels = [],\n\t\t\t\t\t\ttooltipColors = [],\n\t\t\t\t\t\tmedianPosition = (function(index) {\n\n\t\t\t\t\t\t\t// Get all the points at that particular index\n\t\t\t\t\t\t\tvar Elements = [],\n\t\t\t\t\t\t\t\tdataCollection,\n\t\t\t\t\t\t\t\txPositions = [],\n\t\t\t\t\t\t\t\tyPositions = [],\n\t\t\t\t\t\t\t\txMax,\n\t\t\t\t\t\t\t\tyMax,\n\t\t\t\t\t\t\t\txMin,\n\t\t\t\t\t\t\t\tyMin;\n\t\t\t\t\t\t\thelpers.each(this.datasets, function(dataset){\n\t\t\t\t\t\t\t\tdataCollection = dataset.points || dataset.bars || dataset.segments;\n\t\t\t\t\t\t\t\tif (dataCollection[dataIndex] && dataCollection[dataIndex].hasValue()){\n\t\t\t\t\t\t\t\t\tElements.push(dataCollection[dataIndex]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\thelpers.each(Elements, function(element) {\n\t\t\t\t\t\t\t\txPositions.push(element.x);\n\t\t\t\t\t\t\t\tyPositions.push(element.y);\n\n\n\t\t\t\t\t\t\t\t//Include any colour information about the element\n\t\t\t\t\t\t\t\ttooltipLabels.push(helpers.template(this.options.multiTooltipTemplate, element));\n\t\t\t\t\t\t\t\ttooltipColors.push({\n\t\t\t\t\t\t\t\t\tfill: element._saved.fillColor || element.fillColor,\n\t\t\t\t\t\t\t\t\tstroke: element._saved.strokeColor || element.strokeColor\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t}, this);\n\n\t\t\t\t\t\t\tyMin = min(yPositions);\n\t\t\t\t\t\t\tyMax = max(yPositions);\n\n\t\t\t\t\t\t\txMin = min(xPositions);\n\t\t\t\t\t\t\txMax = max(xPositions);\n\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tx: (xMin > this.chart.width/2) ? xMin : xMax,\n\t\t\t\t\t\t\t\ty: (yMin + yMax)/2\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}).call(this, dataIndex);\n\n\t\t\t\t\tnew Chart.MultiTooltip({\n\t\t\t\t\t\tx: medianPosition.x,\n\t\t\t\t\t\ty: medianPosition.y,\n\t\t\t\t\t\txPadding: this.options.tooltipXPadding,\n\t\t\t\t\t\tyPadding: this.options.tooltipYPadding,\n\t\t\t\t\t\txOffset: this.options.tooltipXOffset,\n\t\t\t\t\t\tfillColor: this.options.tooltipFillColor,\n\t\t\t\t\t\ttextColor: this.options.tooltipFontColor,\n\t\t\t\t\t\tfontFamily: this.options.tooltipFontFamily,\n\t\t\t\t\t\tfontStyle: this.options.tooltipFontStyle,\n\t\t\t\t\t\tfontSize: this.options.tooltipFontSize,\n\t\t\t\t\t\ttitleTextColor: this.options.tooltipTitleFontColor,\n\t\t\t\t\t\ttitleFontFamily: this.options.tooltipTitleFontFamily,\n\t\t\t\t\t\ttitleFontStyle: this.options.tooltipTitleFontStyle,\n\t\t\t\t\t\ttitleFontSize: this.options.tooltipTitleFontSize,\n\t\t\t\t\t\tcornerRadius: this.options.tooltipCornerRadius,\n\t\t\t\t\t\tlabels: tooltipLabels,\n\t\t\t\t\t\tlegendColors: tooltipColors,\n\t\t\t\t\t\tlegendColorBackground : this.options.multiTooltipKeyBackground,\n\t\t\t\t\t\ttitle: ChartElements[0].label,\n\t\t\t\t\t\tchart: this.chart,\n\t\t\t\t\t\tctx: this.chart.ctx,\n\t\t\t\t\t\tcustom: this.options.customTooltips\n\t\t\t\t\t}).draw();\n\n\t\t\t\t} else {\n\t\t\t\t\teach(ChartElements, function(Element) {\n\t\t\t\t\t\tvar tooltipPosition = Element.tooltipPosition();\n\t\t\t\t\t\tnew Chart.Tooltip({\n\t\t\t\t\t\t\tx: Math.round(tooltipPosition.x),\n\t\t\t\t\t\t\ty: Math.round(tooltipPosition.y),\n\t\t\t\t\t\t\txPadding: this.options.tooltipXPadding,\n\t\t\t\t\t\t\tyPadding: this.options.tooltipYPadding,\n\t\t\t\t\t\t\tfillColor: this.options.tooltipFillColor,\n\t\t\t\t\t\t\ttextColor: this.options.tooltipFontColor,\n\t\t\t\t\t\t\tfontFamily: this.options.tooltipFontFamily,\n\t\t\t\t\t\t\tfontStyle: this.options.tooltipFontStyle,\n\t\t\t\t\t\t\tfontSize: this.options.tooltipFontSize,\n\t\t\t\t\t\t\tcaretHeight: this.options.tooltipCaretSize,\n\t\t\t\t\t\t\tcornerRadius: this.options.tooltipCornerRadius,\n\t\t\t\t\t\t\ttext: template(this.options.tooltipTemplate, Element),\n\t\t\t\t\t\t\tchart: this.chart,\n\t\t\t\t\t\t\tcustom: this.options.customTooltips\n\t\t\t\t\t\t}).draw();\n\t\t\t\t\t}, this);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\ttoBase64Image : function(){\n\t\t\treturn this.chart.canvas.toDataURL.apply(this.chart.canvas, arguments);\n\t\t}\n\t});\n\n\tChart.Type.extend = function(extensions){\n\n\t\tvar parent = this;\n\n\t\tvar ChartType = function(){\n\t\t\treturn parent.apply(this,arguments);\n\t\t};\n\n\t\t//Copy the prototype object of the this class\n\t\tChartType.prototype = clone(parent.prototype);\n\t\t//Now overwrite some of the properties in the base class with the new extensions\n\t\textend(ChartType.prototype, extensions);\n\n\t\tChartType.extend = Chart.Type.extend;\n\n\t\tif (extensions.name || parent.prototype.name){\n\n\t\t\tvar chartName = extensions.name || parent.prototype.name;\n\t\t\t//Assign any potential default values of the new chart type\n\n\t\t\t//If none are defined, we'll use a clone of the chart type this is being extended from.\n\t\t\t//I.e. if we extend a line chart, we'll use the defaults from the line chart if our new chart\n\t\t\t//doesn't define some defaults of their own.\n\n\t\t\tvar baseDefaults = (Chart.defaults[parent.prototype.name]) ? clone(Chart.defaults[parent.prototype.name]) : {};\n\n\t\t\tChart.defaults[chartName] = extend(baseDefaults,extensions.defaults);\n\n\t\t\tChart.types[chartName] = ChartType;\n\n\t\t\t//Register this new chart type in the Chart prototype\n\t\t\tChart.prototype[chartName] = function(data,options){\n\t\t\t\tvar config = merge(Chart.defaults.global, Chart.defaults[chartName], options || {});\n\t\t\t\treturn new ChartType(data,config,this);\n\t\t\t};\n\t\t} else{\n\t\t\twarn(\"Name not provided for this chart, so it hasn't been registered\");\n\t\t}\n\t\treturn parent;\n\t};\n\n\tChart.Element = function(configuration){\n\t\textend(this,configuration);\n\t\tthis.initialize.apply(this,arguments);\n\t\tthis.save();\n\t};\n\textend(Chart.Element.prototype,{\n\t\tinitialize : function(){},\n\t\trestore : function(props){\n\t\t\tif (!props){\n\t\t\t\textend(this,this._saved);\n\t\t\t} else {\n\t\t\t\teach(props,function(key){\n\t\t\t\t\tthis[key] = this._saved[key];\n\t\t\t\t},this);\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\tsave : function(){\n\t\t\tthis._saved = clone(this);\n\t\t\tdelete this._saved._saved;\n\t\t\treturn this;\n\t\t},\n\t\tupdate : function(newProps){\n\t\t\teach(newProps,function(value,key){\n\t\t\t\tthis._saved[key] = this[key];\n\t\t\t\tthis[key] = value;\n\t\t\t},this);\n\t\t\treturn this;\n\t\t},\n\t\ttransition : function(props,ease){\n\t\t\teach(props,function(value,key){\n\t\t\t\tthis[key] = ((value - this._saved[key]) * ease) + this._saved[key];\n\t\t\t},this);\n\t\t\treturn this;\n\t\t},\n\t\ttooltipPosition : function(){\n\t\t\treturn {\n\t\t\t\tx : this.x,\n\t\t\t\ty : this.y\n\t\t\t};\n\t\t},\n\t\thasValue: function(){\n\t\t\treturn isNumber(this.value);\n\t\t}\n\t});\n\n\tChart.Element.extend = inherits;\n\n\n\tChart.Point = Chart.Element.extend({\n\t\tdisplay: true,\n\t\tinRange: function(chartX,chartY){\n\t\t\tvar hitDetectionRange = this.hitDetectionRadius + this.radius;\n\t\t\treturn ((Math.pow(chartX-this.x, 2)+Math.pow(chartY-this.y, 2)) < Math.pow(hitDetectionRange,2));\n\t\t},\n\t\tdraw : function(){\n\t\t\tif (this.display){\n\t\t\t\tvar ctx = this.ctx;\n\t\t\t\tctx.beginPath();\n\n\t\t\t\tctx.arc(this.x, this.y, this.radius, 0, Math.PI*2);\n\t\t\t\tctx.closePath();\n\n\t\t\t\tctx.strokeStyle = this.strokeColor;\n\t\t\t\tctx.lineWidth = this.strokeWidth;\n\n\t\t\t\tctx.fillStyle = this.fillColor;\n\n\t\t\t\tctx.fill();\n\t\t\t\tctx.stroke();\n\t\t\t}\n\n\n\t\t\t//Quick debug for bezier curve splining\n\t\t\t//Highlights control points and the line between them.\n\t\t\t//Handy for dev - stripped in the min version.\n\n\t\t\t// ctx.save();\n\t\t\t// ctx.fillStyle = \"black\";\n\t\t\t// ctx.strokeStyle = \"black\"\n\t\t\t// ctx.beginPath();\n\t\t\t// ctx.arc(this.controlPoints.inner.x,this.controlPoints.inner.y, 2, 0, Math.PI*2);\n\t\t\t// ctx.fill();\n\n\t\t\t// ctx.beginPath();\n\t\t\t// ctx.arc(this.controlPoints.outer.x,this.controlPoints.outer.y, 2, 0, Math.PI*2);\n\t\t\t// ctx.fill();\n\n\t\t\t// ctx.moveTo(this.controlPoints.inner.x,this.controlPoints.inner.y);\n\t\t\t// ctx.lineTo(this.x, this.y);\n\t\t\t// ctx.lineTo(this.controlPoints.outer.x,this.controlPoints.outer.y);\n\t\t\t// ctx.stroke();\n\n\t\t\t// ctx.restore();\n\n\n\n\t\t}\n\t});\n\n\tChart.Arc = Chart.Element.extend({\n\t\tinRange : function(chartX,chartY){\n\n\t\t\tvar pointRelativePosition = helpers.getAngleFromPoint(this, {\n\t\t\t\tx: chartX,\n\t\t\t\ty: chartY\n\t\t\t});\n\n\t\t\t//Check if within the range of the open/close angle\n\t\t\tvar betweenAngles = (pointRelativePosition.angle >= this.startAngle && pointRelativePosition.angle <= this.endAngle),\n\t\t\t\twithinRadius = (pointRelativePosition.distance >= this.innerRadius && pointRelativePosition.distance <= this.outerRadius);\n\n\t\t\treturn (betweenAngles && withinRadius);\n\t\t\t//Ensure within the outside of the arc centre, but inside arc outer\n\t\t},\n\t\ttooltipPosition : function(){\n\t\t\tvar centreAngle = this.startAngle + ((this.endAngle - this.startAngle) / 2),\n\t\t\t\trangeFromCentre = (this.outerRadius - this.innerRadius) / 2 + this.innerRadius;\n\t\t\treturn {\n\t\t\t\tx : this.x + (Math.cos(centreAngle) * rangeFromCentre),\n\t\t\t\ty : this.y + (Math.sin(centreAngle) * rangeFromCentre)\n\t\t\t};\n\t\t},\n\t\tdraw : function(animationPercent){\n\n\t\t\tvar easingDecimal = animationPercent || 1;\n\n\t\t\tvar ctx = this.ctx;\n\n\t\t\tctx.beginPath();\n\n\t\t\tctx.arc(this.x, this.y, this.outerRadius, this.startAngle, this.endAngle);\n\n\t\t\tctx.arc(this.x, this.y, this.innerRadius, this.endAngle, this.startAngle, true);\n\n\t\t\tctx.closePath();\n\t\t\tctx.strokeStyle = this.strokeColor;\n\t\t\tctx.lineWidth = this.strokeWidth;\n\n\t\t\tctx.fillStyle = this.fillColor;\n\n\t\t\tctx.fill();\n\t\t\tctx.lineJoin = 'bevel';\n\n\t\t\tif (this.showStroke){\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t}\n\t});\n\n\tChart.Rectangle = Chart.Element.extend({\n\t\tdraw : function(){\n\t\t\tvar ctx = this.ctx,\n\t\t\t\thalfWidth = this.width/2,\n\t\t\t\tleftX = this.x - halfWidth,\n\t\t\t\trightX = this.x + halfWidth,\n\t\t\t\ttop = this.base - (this.base - this.y),\n\t\t\t\thalfStroke = this.strokeWidth / 2;\n\n\t\t\t// Canvas doesn't allow us to stroke inside the width so we can\n\t\t\t// adjust the sizes to fit if we're setting a stroke on the line\n\t\t\tif (this.showStroke){\n\t\t\t\tleftX += halfStroke;\n\t\t\t\trightX -= halfStroke;\n\t\t\t\ttop += halfStroke;\n\t\t\t}\n\n\t\t\tctx.beginPath();\n\n\t\t\tctx.fillStyle = this.fillColor;\n\t\t\tctx.strokeStyle = this.strokeColor;\n\t\t\tctx.lineWidth = this.strokeWidth;\n\n\t\t\t// It'd be nice to keep this class totally generic to any rectangle\n\t\t\t// and simply specify which border to miss out.\n\t\t\tctx.moveTo(leftX, this.base);\n\t\t\tctx.lineTo(leftX, top);\n\t\t\tctx.lineTo(rightX, top);\n\t\t\tctx.lineTo(rightX, this.base);\n\t\t\tctx.fill();\n\t\t\tif (this.showStroke){\n\t\t\t\tctx.stroke();\n\t\t\t}\n\t\t},\n\t\theight : function(){\n\t\t\treturn this.base - this.y;\n\t\t},\n\t\tinRange : function(chartX,chartY){\n\t\t\treturn (chartX >= this.x - this.width/2 && chartX <= this.x + this.width/2) && (chartY >= this.y && chartY <= this.base);\n\t\t}\n\t});\n\n\tChart.Tooltip = Chart.Element.extend({\n\t\tdraw : function(){\n\n\t\t\tvar ctx = this.chart.ctx;\n\n\t\t\tctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);\n\n\t\t\tthis.xAlign = \"center\";\n\t\t\tthis.yAlign = \"above\";\n\n\t\t\t//Distance between the actual element.y position and the start of the tooltip caret\n\t\t\tvar caretPadding = this.caretPadding = 2;\n\n\t\t\tvar tooltipWidth = ctx.measureText(this.text).width + 2*this.xPadding,\n\t\t\t\ttooltipRectHeight = this.fontSize + 2*this.yPadding,\n\t\t\t\ttooltipHeight = tooltipRectHeight + this.caretHeight + caretPadding;\n\n\t\t\tif (this.x + tooltipWidth/2 >this.chart.width){\n\t\t\t\tthis.xAlign = \"left\";\n\t\t\t} else if (this.x - tooltipWidth/2 < 0){\n\t\t\t\tthis.xAlign = \"right\";\n\t\t\t}\n\n\t\t\tif (this.y - tooltipHeight < 0){\n\t\t\t\tthis.yAlign = \"below\";\n\t\t\t}\n\n\n\t\t\tvar tooltipX = this.x - tooltipWidth/2,\n\t\t\t\ttooltipY = this.y - tooltipHeight;\n\n\t\t\tctx.fillStyle = this.fillColor;\n\n\t\t\t// Custom Tooltips\n\t\t\tif(this.custom){\n\t\t\t\tthis.custom(this);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tswitch(this.yAlign)\n\t\t\t\t{\n\t\t\t\tcase \"above\":\n\t\t\t\t\t//Draw a caret above the x/y\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(this.x,this.y - caretPadding);\n\t\t\t\t\tctx.lineTo(this.x + this.caretHeight, this.y - (caretPadding + this.caretHeight));\n\t\t\t\t\tctx.lineTo(this.x - this.caretHeight, this.y - (caretPadding + this.caretHeight));\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tctx.fill();\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"below\":\n\t\t\t\t\ttooltipY = this.y + caretPadding + this.caretHeight;\n\t\t\t\t\t//Draw a caret below the x/y\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(this.x, this.y + caretPadding);\n\t\t\t\t\tctx.lineTo(this.x + this.caretHeight, this.y + caretPadding + this.caretHeight);\n\t\t\t\t\tctx.lineTo(this.x - this.caretHeight, this.y + caretPadding + this.caretHeight);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tctx.fill();\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tswitch(this.xAlign)\n\t\t\t\t{\n\t\t\t\tcase \"left\":\n\t\t\t\t\ttooltipX = this.x - tooltipWidth + (this.cornerRadius + this.caretHeight);\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"right\":\n\t\t\t\t\ttooltipX = this.x - (this.cornerRadius + this.caretHeight);\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tdrawRoundedRectangle(ctx,tooltipX,tooltipY,tooltipWidth,tooltipRectHeight,this.cornerRadius);\n\n\t\t\t\tctx.fill();\n\n\t\t\t\tctx.fillStyle = this.textColor;\n\t\t\t\tctx.textAlign = \"center\";\n\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\tctx.fillText(this.text, tooltipX + tooltipWidth/2, tooltipY + tooltipRectHeight/2);\n\t\t\t}\n\t\t}\n\t});\n\n\tChart.MultiTooltip = Chart.Element.extend({\n\t\tinitialize : function(){\n\t\t\tthis.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);\n\n\t\t\tthis.titleFont = fontString(this.titleFontSize,this.titleFontStyle,this.titleFontFamily);\n\n\t\t\tthis.height = (this.labels.length * this.fontSize) + ((this.labels.length-1) * (this.fontSize/2)) + (this.yPadding*2) + this.titleFontSize *1.5;\n\n\t\t\tthis.ctx.font = this.titleFont;\n\n\t\t\tvar titleWidth = this.ctx.measureText(this.title).width,\n\t\t\t\t//Label has a legend square as well so account for this.\n\t\t\t\tlabelWidth = longestText(this.ctx,this.font,this.labels) + this.fontSize + 3,\n\t\t\t\tlongestTextWidth = max([labelWidth,titleWidth]);\n\n\t\t\tthis.width = longestTextWidth + (this.xPadding*2);\n\n\n\t\t\tvar halfHeight = this.height/2;\n\n\t\t\t//Check to ensure the height will fit on the canvas\n\t\t\tif (this.y - halfHeight < 0 ){\n\t\t\t\tthis.y = halfHeight;\n\t\t\t} else if (this.y + halfHeight > this.chart.height){\n\t\t\t\tthis.y = this.chart.height - halfHeight;\n\t\t\t}\n\n\t\t\t//Decide whether to align left or right based on position on canvas\n\t\t\tif (this.x > this.chart.width/2){\n\t\t\t\tthis.x -= this.xOffset + this.width;\n\t\t\t} else {\n\t\t\t\tthis.x += this.xOffset;\n\t\t\t}\n\n\n\t\t},\n\t\tgetLineHeight : function(index){\n\t\t\tvar baseLineHeight = this.y - (this.height/2) + this.yPadding,\n\t\t\t\tafterTitleIndex = index-1;\n\n\t\t\t//If the index is zero, we're getting the title\n\t\t\tif (index === 0){\n\t\t\t\treturn baseLineHeight + this.titleFontSize/2;\n\t\t\t} else{\n\t\t\t\treturn baseLineHeight + ((this.fontSize*1.5*afterTitleIndex) + this.fontSize/2) + this.titleFontSize * 1.5;\n\t\t\t}\n\n\t\t},\n\t\tdraw : function(){\n\t\t\t// Custom Tooltips\n\t\t\tif(this.custom){\n\t\t\t\tthis.custom(this);\n\t\t\t}\n\t\t\telse{\n\t\t\t\tdrawRoundedRectangle(this.ctx,this.x,this.y - this.height/2,this.width,this.height,this.cornerRadius);\n\t\t\t\tvar ctx = this.ctx;\n\t\t\t\tctx.fillStyle = this.fillColor;\n\t\t\t\tctx.fill();\n\t\t\t\tctx.closePath();\n\n\t\t\t\tctx.textAlign = \"left\";\n\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\tctx.fillStyle = this.titleTextColor;\n\t\t\t\tctx.font = this.titleFont;\n\n\t\t\t\tctx.fillText(this.title,this.x + this.xPadding, this.getLineHeight(0));\n\n\t\t\t\tctx.font = this.font;\n\t\t\t\thelpers.each(this.labels,function(label,index){\n\t\t\t\t\tctx.fillStyle = this.textColor;\n\t\t\t\t\tctx.fillText(label,this.x + this.xPadding + this.fontSize + 3, this.getLineHeight(index + 1));\n\n\t\t\t\t\t//A bit gnarly, but clearing this rectangle breaks when using explorercanvas (clears whole canvas)\n\t\t\t\t\t//ctx.clearRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);\n\t\t\t\t\t//Instead we'll make a white filled block to put the legendColour palette over.\n\n\t\t\t\t\tctx.fillStyle = this.legendColorBackground;\n\t\t\t\t\tctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);\n\n\t\t\t\t\tctx.fillStyle = this.legendColors[index].fill;\n\t\t\t\t\tctx.fillRect(this.x + this.xPadding, this.getLineHeight(index + 1) - this.fontSize/2, this.fontSize, this.fontSize);\n\n\n\t\t\t\t},this);\n\t\t\t}\n\t\t}\n\t});\n\n\tChart.Scale = Chart.Element.extend({\n\t\tinitialize : function(){\n\t\t\tthis.fit();\n\t\t},\n\t\tbuildYLabels : function(){\n\t\t\tthis.yLabels = [];\n\n\t\t\tvar stepDecimalPlaces = getDecimalPlaces(this.stepValue);\n\n\t\t\tfor (var i=0; i<=this.steps; i++){\n\t\t\t\tthis.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));\n\t\t\t}\n\t\t\tthis.yLabelWidth = (this.display && this.showLabels) ? longestText(this.ctx,this.font,this.yLabels) : 0;\n\t\t},\n\t\taddXLabel : function(label){\n\t\t\tthis.xLabels.push(label);\n\t\t\tthis.valuesCount++;\n\t\t\tthis.fit();\n\t\t},\n\t\tremoveXLabel : function(){\n\t\t\tthis.xLabels.shift();\n\t\t\tthis.valuesCount--;\n\t\t\tthis.fit();\n\t\t},\n\t\t// Fitting loop to rotate x Labels and figure out what fits there, and also calculate how many Y steps to use\n\t\tfit: function(){\n\t\t\t// First we need the width of the yLabels, assuming the xLabels aren't rotated\n\n\t\t\t// To do that we need the base line at the top and base of the chart, assuming there is no x label rotation\n\t\t\tthis.startPoint = (this.display) ? this.fontSize : 0;\n\t\t\tthis.endPoint = (this.display) ? this.height - (this.fontSize * 1.5) - 5 : this.height; // -5 to pad labels\n\n\t\t\t// Apply padding settings to the start and end point.\n\t\t\tthis.startPoint += this.padding;\n\t\t\tthis.endPoint -= this.padding;\n\n\t\t\t// Cache the starting height, so can determine if we need to recalculate the scale yAxis\n\t\t\tvar cachedHeight = this.endPoint - this.startPoint,\n\t\t\t\tcachedYLabelWidth;\n\n\t\t\t// Build the current yLabels so we have an idea of what size they'll be to start\n\t\t\t/*\n\t\t\t *\tThis sets what is returned from calculateScaleRange as static properties of this class:\n\t\t\t *\n\t\t\t\tthis.steps;\n\t\t\t\tthis.stepValue;\n\t\t\t\tthis.min;\n\t\t\t\tthis.max;\n\t\t\t *\n\t\t\t */\n\t\t\tthis.calculateYRange(cachedHeight);\n\n\t\t\t// With these properties set we can now build the array of yLabels\n\t\t\t// and also the width of the largest yLabel\n\t\t\tthis.buildYLabels();\n\n\t\t\tthis.calculateXLabelRotation();\n\n\t\t\twhile((cachedHeight > this.endPoint - this.startPoint)){\n\t\t\t\tcachedHeight = this.endPoint - this.startPoint;\n\t\t\t\tcachedYLabelWidth = this.yLabelWidth;\n\n\t\t\t\tthis.calculateYRange(cachedHeight);\n\t\t\t\tthis.buildYLabels();\n\n\t\t\t\t// Only go through the xLabel loop again if the yLabel width has changed\n\t\t\t\tif (cachedYLabelWidth < this.yLabelWidth){\n\t\t\t\t\tthis.calculateXLabelRotation();\n\t\t\t\t}\n\t\t\t}\n\n\t\t},\n\t\tcalculateXLabelRotation : function(){\n\t\t\t//Get the width of each grid by calculating the difference\n\t\t\t//between x offsets between 0 and 1.\n\n\t\t\tthis.ctx.font = this.font;\n\n\t\t\tvar firstWidth = this.ctx.measureText(this.xLabels[0]).width,\n\t\t\t\tlastWidth = this.ctx.measureText(this.xLabels[this.xLabels.length - 1]).width,\n\t\t\t\tfirstRotated,\n\t\t\t\tlastRotated;\n\n\n\t\t\tthis.xScalePaddingRight = lastWidth/2 + 3;\n\t\t\tthis.xScalePaddingLeft = (firstWidth/2 > this.yLabelWidth + 10) ? firstWidth/2 : this.yLabelWidth + 10;\n\n\t\t\tthis.xLabelRotation = 0;\n\t\t\tif (this.display){\n\t\t\t\tvar originalLabelWidth = longestText(this.ctx,this.font,this.xLabels),\n\t\t\t\t\tcosRotation,\n\t\t\t\t\tfirstRotatedWidth;\n\t\t\t\tthis.xLabelWidth = originalLabelWidth;\n\t\t\t\t//Allow 3 pixels x2 padding either side for label readability\n\t\t\t\tvar xGridWidth = Math.floor(this.calculateX(1) - this.calculateX(0)) - 6;\n\n\t\t\t\t//Max label rotate should be 90 - also act as a loop counter\n\t\t\t\twhile ((this.xLabelWidth > xGridWidth && this.xLabelRotation === 0) || (this.xLabelWidth > xGridWidth && this.xLabelRotation <= 90 && this.xLabelRotation > 0)){\n\t\t\t\t\tcosRotation = Math.cos(toRadians(this.xLabelRotation));\n\n\t\t\t\t\tfirstRotated = cosRotation * firstWidth;\n\t\t\t\t\tlastRotated = cosRotation * lastWidth;\n\n\t\t\t\t\t// We're right aligning the text now.\n\t\t\t\t\tif (firstRotated + this.fontSize / 2 > this.yLabelWidth + 8){\n\t\t\t\t\t\tthis.xScalePaddingLeft = firstRotated + this.fontSize / 2;\n\t\t\t\t\t}\n\t\t\t\t\tthis.xScalePaddingRight = this.fontSize/2;\n\n\n\t\t\t\t\tthis.xLabelRotation++;\n\t\t\t\t\tthis.xLabelWidth = cosRotation * originalLabelWidth;\n\n\t\t\t\t}\n\t\t\t\tif (this.xLabelRotation > 0){\n\t\t\t\t\tthis.endPoint -= Math.sin(toRadians(this.xLabelRotation))*originalLabelWidth + 3;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse{\n\t\t\t\tthis.xLabelWidth = 0;\n\t\t\t\tthis.xScalePaddingRight = this.padding;\n\t\t\t\tthis.xScalePaddingLeft = this.padding;\n\t\t\t}\n\n\t\t},\n\t\t// Needs to be overidden in each Chart type\n\t\t// Otherwise we need to pass all the data into the scale class\n\t\tcalculateYRange: noop,\n\t\tdrawingArea: function(){\n\t\t\treturn this.startPoint - this.endPoint;\n\t\t},\n\t\tcalculateY : function(value){\n\t\t\tvar scalingFactor = this.drawingArea() / (this.min - this.max);\n\t\t\treturn this.endPoint - (scalingFactor * (value - this.min));\n\t\t},\n\t\tcalculateX : function(index){\n\t\t\tvar isRotated = (this.xLabelRotation > 0),\n\t\t\t\t// innerWidth = (this.offsetGridLines) ? this.width - offsetLeft - this.padding : this.width - (offsetLeft + halfLabelWidth * 2) - this.padding,\n\t\t\t\tinnerWidth = this.width - (this.xScalePaddingLeft + this.xScalePaddingRight),\n\t\t\t\tvalueWidth = innerWidth/Math.max((this.valuesCount - ((this.offsetGridLines) ? 0 : 1)), 1),\n\t\t\t\tvalueOffset = (valueWidth * index) + this.xScalePaddingLeft;\n\n\t\t\tif (this.offsetGridLines){\n\t\t\t\tvalueOffset += (valueWidth/2);\n\t\t\t}\n\n\t\t\treturn Math.round(valueOffset);\n\t\t},\n\t\tupdate : function(newProps){\n\t\t\thelpers.extend(this, newProps);\n\t\t\tthis.fit();\n\t\t},\n\t\tdraw : function(){\n\t\t\tvar ctx = this.ctx,\n\t\t\t\tyLabelGap = (this.endPoint - this.startPoint) / this.steps,\n\t\t\t\txStart = Math.round(this.xScalePaddingLeft);\n\t\t\tif (this.display){\n\t\t\t\tctx.fillStyle = this.textColor;\n\t\t\t\tctx.font = this.font;\n\t\t\t\teach(this.yLabels,function(labelString,index){\n\t\t\t\t\tvar yLabelCenter = this.endPoint - (yLabelGap * index),\n\t\t\t\t\t\tlinePositionY = Math.round(yLabelCenter),\n\t\t\t\t\t\tdrawHorizontalLine = this.showHorizontalLines;\n\n\t\t\t\t\tctx.textAlign = \"right\";\n\t\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\t\tif (this.showLabels){\n\t\t\t\t\t\tctx.fillText(labelString,xStart - 10,yLabelCenter);\n\t\t\t\t\t}\n\n\t\t\t\t\t// This is X axis, so draw it\n\t\t\t\t\tif (index === 0 && !drawHorizontalLine){\n\t\t\t\t\t\tdrawHorizontalLine = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawHorizontalLine){\n\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (index > 0){\n\t\t\t\t\t\t// This is a grid line in the centre, so drop that\n\t\t\t\t\t\tctx.lineWidth = this.gridLineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.gridLineColor;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// This is the first line on the scale\n\t\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\t}\n\n\t\t\t\t\tlinePositionY += helpers.aliasPixel(ctx.lineWidth);\n\n\t\t\t\t\tif(drawHorizontalLine){\n\t\t\t\t\t\tctx.moveTo(xStart, linePositionY);\n\t\t\t\t\t\tctx.lineTo(this.width, linePositionY);\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(xStart - 5, linePositionY);\n\t\t\t\t\tctx.lineTo(xStart, linePositionY);\n\t\t\t\t\tctx.stroke();\n\t\t\t\t\tctx.closePath();\n\n\t\t\t\t},this);\n\n\t\t\t\teach(this.xLabels,function(label,index){\n\t\t\t\t\tvar xPos = this.calculateX(index) + aliasPixel(this.lineWidth),\n\t\t\t\t\t\t// Check to see if line/bar here and decide where to place the line\n\t\t\t\t\t\tlinePos = this.calculateX(index - (this.offsetGridLines ? 0.5 : 0)) + aliasPixel(this.lineWidth),\n\t\t\t\t\t\tisRotated = (this.xLabelRotation > 0),\n\t\t\t\t\t\tdrawVerticalLine = this.showVerticalLines;\n\n\t\t\t\t\t// This is Y axis, so draw it\n\t\t\t\t\tif (index === 0 && !drawVerticalLine){\n\t\t\t\t\t\tdrawVerticalLine = true;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawVerticalLine){\n\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t}\n\n\t\t\t\t\tif (index > 0){\n\t\t\t\t\t\t// This is a grid line in the centre, so drop that\n\t\t\t\t\t\tctx.lineWidth = this.gridLineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.gridLineColor;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// This is the first line on the scale\n\t\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (drawVerticalLine){\n\t\t\t\t\t\tctx.moveTo(linePos,this.endPoint);\n\t\t\t\t\t\tctx.lineTo(linePos,this.startPoint - 3);\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t}\n\n\n\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\n\n\t\t\t\t\t// Small lines at the bottom of the base grid line\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(linePos,this.endPoint);\n\t\t\t\t\tctx.lineTo(linePos,this.endPoint + 5);\n\t\t\t\t\tctx.stroke();\n\t\t\t\t\tctx.closePath();\n\n\t\t\t\t\tctx.save();\n\t\t\t\t\tctx.translate(xPos,(isRotated) ? this.endPoint + 12 : this.endPoint + 8);\n\t\t\t\t\tctx.rotate(toRadians(this.xLabelRotation)*-1);\n\t\t\t\t\tctx.font = this.font;\n\t\t\t\t\tctx.textAlign = (isRotated) ? \"right\" : \"center\";\n\t\t\t\t\tctx.textBaseline = (isRotated) ? \"middle\" : \"top\";\n\t\t\t\t\tctx.fillText(label, 0, 0);\n\t\t\t\t\tctx.restore();\n\t\t\t\t},this);\n\n\t\t\t}\n\t\t}\n\n\t});\n\n\tChart.RadialScale = Chart.Element.extend({\n\t\tinitialize: function(){\n\t\t\tthis.size = min([this.height, this.width]);\n\t\t\tthis.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);\n\t\t},\n\t\tcalculateCenterOffset: function(value){\n\t\t\t// Take into account half font size + the yPadding of the top value\n\t\t\tvar scalingFactor = this.drawingArea / (this.max - this.min);\n\n\t\t\treturn (value - this.min) * scalingFactor;\n\t\t},\n\t\tupdate : function(){\n\t\t\tif (!this.lineArc){\n\t\t\t\tthis.setScaleSize();\n\t\t\t} else {\n\t\t\t\tthis.drawingArea = (this.display) ? (this.size/2) - (this.fontSize/2 + this.backdropPaddingY) : (this.size/2);\n\t\t\t}\n\t\t\tthis.buildYLabels();\n\t\t},\n\t\tbuildYLabels: function(){\n\t\t\tthis.yLabels = [];\n\n\t\t\tvar stepDecimalPlaces = getDecimalPlaces(this.stepValue);\n\n\t\t\tfor (var i=0; i<=this.steps; i++){\n\t\t\t\tthis.yLabels.push(template(this.templateString,{value:(this.min + (i * this.stepValue)).toFixed(stepDecimalPlaces)}));\n\t\t\t}\n\t\t},\n\t\tgetCircumference : function(){\n\t\t\treturn ((Math.PI*2) / this.valuesCount);\n\t\t},\n\t\tsetScaleSize: function(){\n\t\t\t/*\n\t\t\t * Right, this is really confusing and there is a lot of maths going on here\n\t\t\t * The gist of the problem is here: https://gist.github.com/nnnick/696cc9c55f4b0beb8fe9\n\t\t\t *\n\t\t\t * Reaction: https://dl.dropboxusercontent.com/u/34601363/toomuchscience.gif\n\t\t\t *\n\t\t\t * Solution:\n\t\t\t *\n\t\t\t * We assume the radius of the polygon is half the size of the canvas at first\n\t\t\t * at each index we check if the text overlaps.\n\t\t\t *\n\t\t\t * Where it does, we store that angle and that index.\n\t\t\t *\n\t\t\t * After finding the largest index and angle we calculate how much we need to remove\n\t\t\t * from the shape radius to move the point inwards by that x.\n\t\t\t *\n\t\t\t * We average the left and right distances to get the maximum shape radius that can fit in the box\n\t\t\t * along with labels.\n\t\t\t *\n\t\t\t * Once we have that, we can find the centre point for the chart, by taking the x text protrusion\n\t\t\t * on each side, removing that from the size, halving it and adding the left x protrusion width.\n\t\t\t *\n\t\t\t * This will mean we have a shape fitted to the canvas, as large as it can be with the labels\n\t\t\t * and position it in the most space efficient manner\n\t\t\t *\n\t\t\t * https://dl.dropboxusercontent.com/u/34601363/yeahscience.gif\n\t\t\t */\n\n\n\t\t\t// Get maximum radius of the polygon. Either half the height (minus the text width) or half the width.\n\t\t\t// Use this to calculate the offset + change. - Make sure L/R protrusion is at least 0 to stop issues with centre points\n\t\t\tvar largestPossibleRadius = min([(this.height/2 - this.pointLabelFontSize - 5), this.width/2]),\n\t\t\t\tpointPosition,\n\t\t\t\ti,\n\t\t\t\ttextWidth,\n\t\t\t\thalfTextWidth,\n\t\t\t\tfurthestRight = this.width,\n\t\t\t\tfurthestRightIndex,\n\t\t\t\tfurthestRightAngle,\n\t\t\t\tfurthestLeft = 0,\n\t\t\t\tfurthestLeftIndex,\n\t\t\t\tfurthestLeftAngle,\n\t\t\t\txProtrusionLeft,\n\t\t\t\txProtrusionRight,\n\t\t\t\tradiusReductionRight,\n\t\t\t\tradiusReductionLeft,\n\t\t\t\tmaxWidthRadius;\n\t\t\tthis.ctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);\n\t\t\tfor (i=0;i<this.valuesCount;i++){\n\t\t\t\t// 5px to space the text slightly out - similar to what we do in the draw function.\n\t\t\t\tpointPosition = this.getPointPosition(i, largestPossibleRadius);\n\t\t\t\ttextWidth = this.ctx.measureText(template(this.templateString, { value: this.labels[i] })).width + 5;\n\t\t\t\tif (i === 0 || i === this.valuesCount/2){\n\t\t\t\t\t// If we're at index zero, or exactly the middle, we're at exactly the top/bottom\n\t\t\t\t\t// of the radar chart, so text will be aligned centrally, so we'll half it and compare\n\t\t\t\t\t// w/left and right text sizes\n\t\t\t\t\thalfTextWidth = textWidth/2;\n\t\t\t\t\tif (pointPosition.x + halfTextWidth > furthestRight) {\n\t\t\t\t\t\tfurthestRight = pointPosition.x + halfTextWidth;\n\t\t\t\t\t\tfurthestRightIndex = i;\n\t\t\t\t\t}\n\t\t\t\t\tif (pointPosition.x - halfTextWidth < furthestLeft) {\n\t\t\t\t\t\tfurthestLeft = pointPosition.x - halfTextWidth;\n\t\t\t\t\t\tfurthestLeftIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (i < this.valuesCount/2) {\n\t\t\t\t\t// Less than half the values means we'll left align the text\n\t\t\t\t\tif (pointPosition.x + textWidth > furthestRight) {\n\t\t\t\t\t\tfurthestRight = pointPosition.x + textWidth;\n\t\t\t\t\t\tfurthestRightIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (i > this.valuesCount/2){\n\t\t\t\t\t// More than half the values means we'll right align the text\n\t\t\t\t\tif (pointPosition.x - textWidth < furthestLeft) {\n\t\t\t\t\t\tfurthestLeft = pointPosition.x - textWidth;\n\t\t\t\t\t\tfurthestLeftIndex = i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\txProtrusionLeft = furthestLeft;\n\n\t\t\txProtrusionRight = Math.ceil(furthestRight - this.width);\n\n\t\t\tfurthestRightAngle = this.getIndexAngle(furthestRightIndex);\n\n\t\t\tfurthestLeftAngle = this.getIndexAngle(furthestLeftIndex);\n\n\t\t\tradiusReductionRight = xProtrusionRight / Math.sin(furthestRightAngle + Math.PI/2);\n\n\t\t\tradiusReductionLeft = xProtrusionLeft / Math.sin(furthestLeftAngle + Math.PI/2);\n\n\t\t\t// Ensure we actually need to reduce the size of the chart\n\t\t\tradiusReductionRight = (isNumber(radiusReductionRight)) ? radiusReductionRight : 0;\n\t\t\tradiusReductionLeft = (isNumber(radiusReductionLeft)) ? radiusReductionLeft : 0;\n\n\t\t\tthis.drawingArea = largestPossibleRadius - (radiusReductionLeft + radiusReductionRight)/2;\n\n\t\t\t//this.drawingArea = min([maxWidthRadius, (this.height - (2 * (this.pointLabelFontSize + 5)))/2])\n\t\t\tthis.setCenterPoint(radiusReductionLeft, radiusReductionRight);\n\n\t\t},\n\t\tsetCenterPoint: function(leftMovement, rightMovement){\n\n\t\t\tvar maxRight = this.width - rightMovement - this.drawingArea,\n\t\t\t\tmaxLeft = leftMovement + this.drawingArea;\n\n\t\t\tthis.xCenter = (maxLeft + maxRight)/2;\n\t\t\t// Always vertically in the centre as the text height doesn't change\n\t\t\tthis.yCenter = (this.height/2);\n\t\t},\n\n\t\tgetIndexAngle : function(index){\n\t\t\tvar angleMultiplier = (Math.PI * 2) / this.valuesCount;\n\t\t\t// Start from the top instead of right, so remove a quarter of the circle\n\n\t\t\treturn index * angleMultiplier - (Math.PI/2);\n\t\t},\n\t\tgetPointPosition : function(index, distanceFromCenter){\n\t\t\tvar thisAngle = this.getIndexAngle(index);\n\t\t\treturn {\n\t\t\t\tx : (Math.cos(thisAngle) * distanceFromCenter) + this.xCenter,\n\t\t\t\ty : (Math.sin(thisAngle) * distanceFromCenter) + this.yCenter\n\t\t\t};\n\t\t},\n\t\tdraw: function(){\n\t\t\tif (this.display){\n\t\t\t\tvar ctx = this.ctx;\n\t\t\t\teach(this.yLabels, function(label, index){\n\t\t\t\t\t// Don't draw a centre value\n\t\t\t\t\tif (index > 0){\n\t\t\t\t\t\tvar yCenterOffset = index * (this.drawingArea/this.steps),\n\t\t\t\t\t\t\tyHeight = this.yCenter - yCenterOffset,\n\t\t\t\t\t\t\tpointPosition;\n\n\t\t\t\t\t\t// Draw circular lines around the scale\n\t\t\t\t\t\tif (this.lineWidth > 0){\n\t\t\t\t\t\t\tctx.strokeStyle = this.lineColor;\n\t\t\t\t\t\t\tctx.lineWidth = this.lineWidth;\n\n\t\t\t\t\t\t\tif(this.lineArc){\n\t\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\t\tctx.arc(this.xCenter, this.yCenter, yCenterOffset, 0, Math.PI*2);\n\t\t\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\t\t} else{\n\t\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\t\tfor (var i=0;i<this.valuesCount;i++)\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tpointPosition = this.getPointPosition(i, this.calculateCenterOffset(this.min + (index * this.stepValue)));\n\t\t\t\t\t\t\t\t\tif (i === 0){\n\t\t\t\t\t\t\t\t\t\tctx.moveTo(pointPosition.x, pointPosition.y);\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tctx.lineTo(pointPosition.x, pointPosition.y);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif(this.showLabels){\n\t\t\t\t\t\t\tctx.font = fontString(this.fontSize,this.fontStyle,this.fontFamily);\n\t\t\t\t\t\t\tif (this.showLabelBackdrop){\n\t\t\t\t\t\t\t\tvar labelWidth = ctx.measureText(label).width;\n\t\t\t\t\t\t\t\tctx.fillStyle = this.backdropColor;\n\t\t\t\t\t\t\t\tctx.fillRect(\n\t\t\t\t\t\t\t\t\tthis.xCenter - labelWidth/2 - this.backdropPaddingX,\n\t\t\t\t\t\t\t\t\tyHeight - this.fontSize/2 - this.backdropPaddingY,\n\t\t\t\t\t\t\t\t\tlabelWidth + this.backdropPaddingX*2,\n\t\t\t\t\t\t\t\t\tthis.fontSize + this.backdropPaddingY*2\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t\tctx.textBaseline = \"middle\";\n\t\t\t\t\t\t\tctx.fillStyle = this.fontColor;\n\t\t\t\t\t\t\tctx.fillText(label, this.xCenter, yHeight);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\n\t\t\t\tif (!this.lineArc){\n\t\t\t\t\tctx.lineWidth = this.angleLineWidth;\n\t\t\t\t\tctx.strokeStyle = this.angleLineColor;\n\t\t\t\t\tfor (var i = this.valuesCount - 1; i >= 0; i--) {\n\t\t\t\t\t\tif (this.angleLineWidth > 0){\n\t\t\t\t\t\t\tvar outerPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max));\n\t\t\t\t\t\t\tctx.beginPath();\n\t\t\t\t\t\t\tctx.moveTo(this.xCenter, this.yCenter);\n\t\t\t\t\t\t\tctx.lineTo(outerPosition.x, outerPosition.y);\n\t\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t\t\tctx.closePath();\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Extra 3px out for some label spacing\n\t\t\t\t\t\tvar pointLabelPosition = this.getPointPosition(i, this.calculateCenterOffset(this.max) + 5);\n\t\t\t\t\t\tctx.font = fontString(this.pointLabelFontSize,this.pointLabelFontStyle,this.pointLabelFontFamily);\n\t\t\t\t\t\tctx.fillStyle = this.pointLabelFontColor;\n\n\t\t\t\t\t\tvar labelsCount = this.labels.length,\n\t\t\t\t\t\t\thalfLabelsCount = this.labels.length/2,\n\t\t\t\t\t\t\tquarterLabelsCount = halfLabelsCount/2,\n\t\t\t\t\t\t\tupperHalf = (i < quarterLabelsCount || i > labelsCount - quarterLabelsCount),\n\t\t\t\t\t\t\texactQuarter = (i === quarterLabelsCount || i === labelsCount - quarterLabelsCount);\n\t\t\t\t\t\tif (i === 0){\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t} else if(i === halfLabelsCount){\n\t\t\t\t\t\t\tctx.textAlign = 'center';\n\t\t\t\t\t\t} else if (i < halfLabelsCount){\n\t\t\t\t\t\t\tctx.textAlign = 'left';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tctx.textAlign = 'right';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Set the correct text baseline based on outer positioning\n\t\t\t\t\t\tif (exactQuarter){\n\t\t\t\t\t\t\tctx.textBaseline = 'middle';\n\t\t\t\t\t\t} else if (upperHalf){\n\t\t\t\t\t\t\tctx.textBaseline = 'bottom';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tctx.textBaseline = 'top';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tctx.fillText(this.labels[i], pointLabelPosition.x, pointLabelPosition.y);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t});\n\n\t// Attach global event to resize each chart instance when the browser resizes\n\thelpers.addEvent(window, \"resize\", (function(){\n\t\t// Basic debounce of resize function so it doesn't hurt performance when resizing browser.\n\t\tvar timeout;\n\t\treturn function(){\n\t\t\tclearTimeout(timeout);\n\t\t\ttimeout = setTimeout(function(){\n\t\t\t\teach(Chart.instances,function(instance){\n\t\t\t\t\t// If the responsive flag is set in the chart instance config\n\t\t\t\t\t// Cascade the resize event down to the chart.\n\t\t\t\t\tif (instance.options.responsive){\n\t\t\t\t\t\tinstance.resize(instance.render, true);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}, 50);\n\t\t};\n\t})());\n\n\n\tif (amd) {\n\t\tdefine(function(){\n\t\t\treturn Chart;\n\t\t});\n\t} else if (typeof module === 'object' && module.exports) {\n\t\tmodule.exports = Chart;\n\t}\n\n\troot.Chart = Chart;\n\n\tChart.noConflict = function(){\n\t\troot.Chart = previous;\n\t\treturn Chart;\n\t};\n\n}).call(this);\n\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\thelpers = Chart.helpers;\n\n\n\tvar defaultConfig = {\n\t\t//Boolean - Whether the scale should start at zero, or an order of magnitude down from the lowest value\n\t\tscaleBeginAtZero : true,\n\n\t\t//Boolean - Whether grid lines are shown across the chart\n\t\tscaleShowGridLines : true,\n\n\t\t//String - Colour of the grid lines\n\t\tscaleGridLineColor : \"rgba(0,0,0,.05)\",\n\n\t\t//Number - Width of the grid lines\n\t\tscaleGridLineWidth : 1,\n\n\t\t//Boolean - Whether to show horizontal lines (except X axis)\n\t\tscaleShowHorizontalLines: true,\n\n\t\t//Boolean - Whether to show vertical lines (except Y axis)\n\t\tscaleShowVerticalLines: true,\n\n\t\t//Boolean - If there is a stroke on each bar\n\t\tbarShowStroke : true,\n\n\t\t//Number - Pixel width of the bar stroke\n\t\tbarStrokeWidth : 2,\n\n\t\t//Number - Spacing between each of the X value sets\n\t\tbarValueSpacing : 5,\n\n\t\t//Number - Spacing between data sets within X values\n\t\tbarDatasetSpacing : 1,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\\\"background-color:<%=datasets[i].fillColor%>\\\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>\"\n\n\t};\n\n\n\tChart.Type.extend({\n\t\tname: \"Bar\",\n\t\tdefaults : defaultConfig,\n\t\tinitialize:  function(data){\n\n\t\t\t//Expose options as a scope variable here so we can access it in the ScaleClass\n\t\t\tvar options = this.options;\n\n\t\t\tthis.ScaleClass = Chart.Scale.extend({\n\t\t\t\toffsetGridLines : true,\n\t\t\t\tcalculateBarX : function(datasetCount, datasetIndex, barIndex){\n\t\t\t\t\t//Reusable method for calculating the xPosition of a given bar based on datasetIndex & width of the bar\n\t\t\t\t\tvar xWidth = this.calculateBaseWidth(),\n\t\t\t\t\t\txAbsolute = this.calculateX(barIndex) - (xWidth/2),\n\t\t\t\t\t\tbarWidth = this.calculateBarWidth(datasetCount);\n\n\t\t\t\t\treturn xAbsolute + (barWidth * datasetIndex) + (datasetIndex * options.barDatasetSpacing) + barWidth/2;\n\t\t\t\t},\n\t\t\t\tcalculateBaseWidth : function(){\n\t\t\t\t\treturn (this.calculateX(1) - this.calculateX(0)) - (2*options.barValueSpacing);\n\t\t\t\t},\n\t\t\t\tcalculateBarWidth : function(datasetCount){\n\t\t\t\t\t//The padding between datasets is to the right of each bar, providing that there are more than 1 dataset\n\t\t\t\t\tvar baseWidth = this.calculateBaseWidth() - ((datasetCount - 1) * options.barDatasetSpacing);\n\n\t\t\t\t\treturn (baseWidth / datasetCount);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.datasets = [];\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activeBars = (evt.type !== 'mouseout') ? this.getBarsAtEvent(evt) : [];\n\n\t\t\t\t\tthis.eachBars(function(bar){\n\t\t\t\t\t\tbar.restore(['fillColor', 'strokeColor']);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activeBars, function(activeBar){\n\t\t\t\t\t\tactiveBar.fillColor = activeBar.highlightFill;\n\t\t\t\t\t\tactiveBar.strokeColor = activeBar.highlightStroke;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activeBars);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t//Declare the extension of the default point, to cater for the options passed in to the constructor\n\t\t\tthis.BarClass = Chart.Rectangle.extend({\n\t\t\t\tstrokeWidth : this.options.barStrokeWidth,\n\t\t\t\tshowStroke : this.options.barShowStroke,\n\t\t\t\tctx : this.chart.ctx\n\t\t\t});\n\n\t\t\t//Iterate through each of the datasets, and build this into a property of the chart\n\t\t\thelpers.each(data.datasets,function(dataset,datasetIndex){\n\n\t\t\t\tvar datasetObject = {\n\t\t\t\t\tlabel : dataset.label || null,\n\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\tbars : []\n\t\t\t\t};\n\n\t\t\t\tthis.datasets.push(datasetObject);\n\n\t\t\t\thelpers.each(dataset.data,function(dataPoint,index){\n\t\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\t\tdatasetObject.bars.push(new this.BarClass({\n\t\t\t\t\t\tvalue : dataPoint,\n\t\t\t\t\t\tlabel : data.labels[index],\n\t\t\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\t\thighlightFill : dataset.highlightFill || dataset.fillColor,\n\t\t\t\t\t\thighlightStroke : dataset.highlightStroke || dataset.strokeColor\n\t\t\t\t\t}));\n\t\t\t\t},this);\n\n\t\t\t},this);\n\n\t\t\tthis.buildScale(data.labels);\n\n\t\t\tthis.BarClass.prototype.base = this.scale.endPoint;\n\n\t\t\tthis.eachBars(function(bar, index, datasetIndex){\n\t\t\t\thelpers.extend(bar, {\n\t\t\t\t\twidth : this.scale.calculateBarWidth(this.datasets.length),\n\t\t\t\t\tx: this.scale.calculateBarX(this.datasets.length, datasetIndex, index),\n\t\t\t\t\ty: this.scale.endPoint\n\t\t\t\t});\n\t\t\t\tbar.save();\n\t\t\t}, this);\n\n\t\t\tthis.render();\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.scale.update();\n\t\t\t// Reset any highlight colours before updating.\n\t\t\thelpers.each(this.activeElements, function(activeElement){\n\t\t\t\tactiveElement.restore(['fillColor', 'strokeColor']);\n\t\t\t});\n\n\t\t\tthis.eachBars(function(bar){\n\t\t\t\tbar.save();\n\t\t\t});\n\t\t\tthis.render();\n\t\t},\n\t\teachBars : function(callback){\n\t\t\thelpers.each(this.datasets,function(dataset, datasetIndex){\n\t\t\t\thelpers.each(dataset.bars, callback, this, datasetIndex);\n\t\t\t},this);\n\t\t},\n\t\tgetBarsAtEvent : function(e){\n\t\t\tvar barsArray = [],\n\t\t\t\teventPosition = helpers.getRelativePosition(e),\n\t\t\t\tdatasetIterator = function(dataset){\n\t\t\t\t\tbarsArray.push(dataset.bars[barIndex]);\n\t\t\t\t},\n\t\t\t\tbarIndex;\n\n\t\t\tfor (var datasetIndex = 0; datasetIndex < this.datasets.length; datasetIndex++) {\n\t\t\t\tfor (barIndex = 0; barIndex < this.datasets[datasetIndex].bars.length; barIndex++) {\n\t\t\t\t\tif (this.datasets[datasetIndex].bars[barIndex].inRange(eventPosition.x,eventPosition.y)){\n\t\t\t\t\t\thelpers.each(this.datasets, datasetIterator);\n\t\t\t\t\t\treturn barsArray;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn barsArray;\n\t\t},\n\t\tbuildScale : function(labels){\n\t\t\tvar self = this;\n\n\t\t\tvar dataTotal = function(){\n\t\t\t\tvar values = [];\n\t\t\t\tself.eachBars(function(bar){\n\t\t\t\t\tvalues.push(bar.value);\n\t\t\t\t});\n\t\t\t\treturn values;\n\t\t\t};\n\n\t\t\tvar scaleOptions = {\n\t\t\t\ttemplateString : this.options.scaleLabel,\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttextColor : this.options.scaleFontColor,\n\t\t\t\tfontSize : this.options.scaleFontSize,\n\t\t\t\tfontStyle : this.options.scaleFontStyle,\n\t\t\t\tfontFamily : this.options.scaleFontFamily,\n\t\t\t\tvaluesCount : labels.length,\n\t\t\t\tbeginAtZero : this.options.scaleBeginAtZero,\n\t\t\t\tintegersOnly : this.options.scaleIntegersOnly,\n\t\t\t\tcalculateYRange: function(currentHeight){\n\t\t\t\t\tvar updatedRanges = helpers.calculateScaleRange(\n\t\t\t\t\t\tdataTotal(),\n\t\t\t\t\t\tcurrentHeight,\n\t\t\t\t\t\tthis.fontSize,\n\t\t\t\t\t\tthis.beginAtZero,\n\t\t\t\t\t\tthis.integersOnly\n\t\t\t\t\t);\n\t\t\t\t\thelpers.extend(this, updatedRanges);\n\t\t\t\t},\n\t\t\t\txLabels : labels,\n\t\t\t\tfont : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),\n\t\t\t\tlineWidth : this.options.scaleLineWidth,\n\t\t\t\tlineColor : this.options.scaleLineColor,\n\t\t\t\tshowHorizontalLines : this.options.scaleShowHorizontalLines,\n\t\t\t\tshowVerticalLines : this.options.scaleShowVerticalLines,\n\t\t\t\tgridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,\n\t\t\t\tgridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : \"rgba(0,0,0,0)\",\n\t\t\t\tpadding : (this.options.showScale) ? 0 : (this.options.barShowStroke) ? this.options.barStrokeWidth : 0,\n\t\t\t\tshowLabels : this.options.scaleShowLabels,\n\t\t\t\tdisplay : this.options.showScale\n\t\t\t};\n\n\t\t\tif (this.options.scaleOverride){\n\t\t\t\thelpers.extend(scaleOptions, {\n\t\t\t\t\tcalculateYRange: helpers.noop,\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.scale = new this.ScaleClass(scaleOptions);\n\t\t},\n\t\taddData : function(valuesArray,label){\n\t\t\t//Map the values array for each of the datasets\n\t\t\thelpers.each(valuesArray,function(value,datasetIndex){\n\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\tthis.datasets[datasetIndex].bars.push(new this.BarClass({\n\t\t\t\t\tvalue : value,\n\t\t\t\t\tlabel : label,\n\t\t\t\t\tx: this.scale.calculateBarX(this.datasets.length, datasetIndex, this.scale.valuesCount+1),\n\t\t\t\t\ty: this.scale.endPoint,\n\t\t\t\t\twidth : this.scale.calculateBarWidth(this.datasets.length),\n\t\t\t\t\tbase : this.scale.endPoint,\n\t\t\t\t\tstrokeColor : this.datasets[datasetIndex].strokeColor,\n\t\t\t\t\tfillColor : this.datasets[datasetIndex].fillColor\n\t\t\t\t}));\n\t\t\t},this);\n\n\t\t\tthis.scale.addXLabel(label);\n\t\t\t//Then re-render the chart.\n\t\t\tthis.update();\n\t\t},\n\t\tremoveData : function(){\n\t\t\tthis.scale.removeXLabel();\n\t\t\t//Then re-render the chart.\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tdataset.bars.shift();\n\t\t\t},this);\n\t\t\tthis.update();\n\t\t},\n\t\treflow : function(){\n\t\t\thelpers.extend(this.BarClass.prototype,{\n\t\t\t\ty: this.scale.endPoint,\n\t\t\t\tbase : this.scale.endPoint\n\t\t\t});\n\t\t\tvar newScaleProps = helpers.extend({\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width\n\t\t\t});\n\t\t\tthis.scale.update(newScaleProps);\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easingDecimal = ease || 1;\n\t\t\tthis.clear();\n\n\t\t\tvar ctx = this.chart.ctx;\n\n\t\t\tthis.scale.draw(easingDecimal);\n\n\t\t\t//Draw all the bars for each dataset\n\t\t\thelpers.each(this.datasets,function(dataset,datasetIndex){\n\t\t\t\thelpers.each(dataset.bars,function(bar,index){\n\t\t\t\t\tif (bar.hasValue()){\n\t\t\t\t\t\tbar.base = this.scale.endPoint;\n\t\t\t\t\t\t//Transition then draw\n\t\t\t\t\t\tbar.transition({\n\t\t\t\t\t\t\tx : this.scale.calculateBarX(this.datasets.length, datasetIndex, index),\n\t\t\t\t\t\t\ty : this.scale.calculateY(bar.value),\n\t\t\t\t\t\t\twidth : this.scale.calculateBarWidth(this.datasets.length)\n\t\t\t\t\t\t}, easingDecimal).draw();\n\t\t\t\t\t}\n\t\t\t\t},this);\n\n\t\t\t},this);\n\t\t}\n\t});\n\n\n}).call(this);\n\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\t//Cache a local reference to Chart.helpers\n\t\thelpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\t//Boolean - Whether we should show a stroke on each segment\n\t\tsegmentShowStroke : true,\n\n\t\t//String - The colour of each segment stroke\n\t\tsegmentStrokeColor : \"#fff\",\n\n\t\t//Number - The width of each segment stroke\n\t\tsegmentStrokeWidth : 2,\n\n\t\t//The percentage of the chart that we cut out of the middle.\n\t\tpercentageInnerCutout : 50,\n\n\t\t//Number - Amount of animation steps\n\t\tanimationSteps : 100,\n\n\t\t//String - Animation easing effect\n\t\tanimationEasing : \"easeOutBounce\",\n\n\t\t//Boolean - Whether we animate the rotation of the Doughnut\n\t\tanimateRotate : true,\n\n\t\t//Boolean - Whether we animate scaling the Doughnut from the centre\n\t\tanimateScale : false,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<segments.length; i++){%><li><span style=\\\"background-color:<%=segments[i].fillColor%>\\\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>\"\n\n\t};\n\n\n\tChart.Type.extend({\n\t\t//Passing in a name registers this chart in the Chart namespace\n\t\tname: \"Doughnut\",\n\t\t//Providing a defaults will also register the deafults in the chart namespace\n\t\tdefaults : defaultConfig,\n\t\t//Initialize is fired when the chart is initialized - Data is passed in as a parameter\n\t\t//Config is automatically merged by the core of Chart.js, and is available at this.options\n\t\tinitialize:  function(data){\n\n\t\t\t//Declare segments as a static property to prevent inheriting across the Chart type prototype\n\t\t\tthis.segments = [];\n\t\t\tthis.outerRadius = (helpers.min([this.chart.width,this.chart.height]) -\tthis.options.segmentStrokeWidth/2)/2;\n\n\t\t\tthis.SegmentArc = Chart.Arc.extend({\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];\n\n\t\t\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\t\t\tsegment.restore([\"fillColor\"]);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activeSegments,function(activeSegment){\n\t\t\t\t\t\tactiveSegment.fillColor = activeSegment.highlightColor;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activeSegments);\n\t\t\t\t});\n\t\t\t}\n\t\t\tthis.calculateTotal(data);\n\n\t\t\thelpers.each(data,function(datapoint, index){\n\t\t\t\tthis.addData(datapoint, index, true);\n\t\t\t},this);\n\n\t\t\tthis.render();\n\t\t},\n\t\tgetSegmentsAtEvent : function(e){\n\t\t\tvar segmentsArray = [];\n\n\t\t\tvar location = helpers.getRelativePosition(e);\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tif (segment.inRange(location.x,location.y)) segmentsArray.push(segment);\n\t\t\t},this);\n\t\t\treturn segmentsArray;\n\t\t},\n\t\taddData : function(segment, atIndex, silent){\n\t\t\tvar index = atIndex || this.segments.length;\n\t\t\tthis.segments.splice(index, 0, new this.SegmentArc({\n\t\t\t\tvalue : segment.value,\n\t\t\t\touterRadius : (this.options.animateScale) ? 0 : this.outerRadius,\n\t\t\t\tinnerRadius : (this.options.animateScale) ? 0 : (this.outerRadius/100) * this.options.percentageInnerCutout,\n\t\t\t\tfillColor : segment.color,\n\t\t\t\thighlightColor : segment.highlight || segment.color,\n\t\t\t\tshowStroke : this.options.segmentShowStroke,\n\t\t\t\tstrokeWidth : this.options.segmentStrokeWidth,\n\t\t\t\tstrokeColor : this.options.segmentStrokeColor,\n\t\t\t\tstartAngle : Math.PI * 1.5,\n\t\t\t\tcircumference : (this.options.animateRotate) ? 0 : this.calculateCircumference(segment.value),\n\t\t\t\tlabel : segment.label\n\t\t\t}));\n\t\t\tif (!silent){\n\t\t\t\tthis.reflow();\n\t\t\t\tthis.update();\n\t\t\t}\n\t\t},\n\t\tcalculateCircumference : function(value){\n\t\t\treturn (Math.PI*2)*(Math.abs(value) / this.total);\n\t\t},\n\t\tcalculateTotal : function(data){\n\t\t\tthis.total = 0;\n\t\t\thelpers.each(data,function(segment){\n\t\t\t\tthis.total += Math.abs(segment.value);\n\t\t\t},this);\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.calculateTotal(this.segments);\n\n\t\t\t// Reset any highlight colours before updating.\n\t\t\thelpers.each(this.activeElements, function(activeElement){\n\t\t\t\tactiveElement.restore(['fillColor']);\n\t\t\t});\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tsegment.save();\n\t\t\t});\n\t\t\tthis.render();\n\t\t},\n\n\t\tremoveData: function(atIndex){\n\t\t\tvar indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;\n\t\t\tthis.segments.splice(indexToDelete, 1);\n\t\t\tthis.reflow();\n\t\t\tthis.update();\n\t\t},\n\n\t\treflow : function(){\n\t\t\thelpers.extend(this.SegmentArc.prototype,{\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\t\t\tthis.outerRadius = (helpers.min([this.chart.width,this.chart.height]) -\tthis.options.segmentStrokeWidth/2)/2;\n\t\t\thelpers.each(this.segments, function(segment){\n\t\t\t\tsegment.update({\n\t\t\t\t\touterRadius : this.outerRadius,\n\t\t\t\t\tinnerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout\n\t\t\t\t});\n\t\t\t}, this);\n\t\t},\n\t\tdraw : function(easeDecimal){\n\t\t\tvar animDecimal = (easeDecimal) ? easeDecimal : 1;\n\t\t\tthis.clear();\n\t\t\thelpers.each(this.segments,function(segment,index){\n\t\t\t\tsegment.transition({\n\t\t\t\t\tcircumference : this.calculateCircumference(segment.value),\n\t\t\t\t\touterRadius : this.outerRadius,\n\t\t\t\t\tinnerRadius : (this.outerRadius/100) * this.options.percentageInnerCutout\n\t\t\t\t},animDecimal);\n\n\t\t\t\tsegment.endAngle = segment.startAngle + segment.circumference;\n\n\t\t\t\tsegment.draw();\n\t\t\t\tif (index === 0){\n\t\t\t\t\tsegment.startAngle = Math.PI * 1.5;\n\t\t\t\t}\n\t\t\t\t//Check to see if it's the last segment, if not get the next and update the start angle\n\t\t\t\tif (index < this.segments.length-1){\n\t\t\t\t\tthis.segments[index+1].startAngle = segment.endAngle;\n\t\t\t\t}\n\t\t\t},this);\n\n\t\t}\n\t});\n\n\tChart.types.Doughnut.extend({\n\t\tname : \"Pie\",\n\t\tdefaults : helpers.merge(defaultConfig,{percentageInnerCutout : 0})\n\t});\n\n}).call(this);\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\thelpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\n\t\t///Boolean - Whether grid lines are shown across the chart\n\t\tscaleShowGridLines : true,\n\n\t\t//String - Colour of the grid lines\n\t\tscaleGridLineColor : \"rgba(0,0,0,.05)\",\n\n\t\t//Number - Width of the grid lines\n\t\tscaleGridLineWidth : 1,\n\n\t\t//Boolean - Whether to show horizontal lines (except X axis)\n\t\tscaleShowHorizontalLines: true,\n\n\t\t//Boolean - Whether to show vertical lines (except Y axis)\n\t\tscaleShowVerticalLines: true,\n\n\t\t//Boolean - Whether the line is curved between points\n\t\tbezierCurve : true,\n\n\t\t//Number - Tension of the bezier curve between points\n\t\tbezierCurveTension : 0.4,\n\n\t\t//Boolean - Whether to show a dot for each point\n\t\tpointDot : true,\n\n\t\t//Number - Radius of each point dot in pixels\n\t\tpointDotRadius : 4,\n\n\t\t//Number - Pixel width of point dot stroke\n\t\tpointDotStrokeWidth : 1,\n\n\t\t//Number - amount extra to add to the radius to cater for hit detection outside the drawn point\n\t\tpointHitDetectionRadius : 20,\n\n\t\t//Boolean - Whether to show a stroke for datasets\n\t\tdatasetStroke : true,\n\n\t\t//Number - Pixel width of dataset stroke\n\t\tdatasetStrokeWidth : 2,\n\n\t\t//Boolean - Whether to fill the dataset with a colour\n\t\tdatasetFill : true,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\\\"background-color:<%=datasets[i].strokeColor%>\\\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>\"\n\n\t};\n\n\n\tChart.Type.extend({\n\t\tname: \"Line\",\n\t\tdefaults : defaultConfig,\n\t\tinitialize:  function(data){\n\t\t\t//Declare the extension of the default point, to cater for the options passed in to the constructor\n\t\t\tthis.PointClass = Chart.Point.extend({\n\t\t\t\tstrokeWidth : this.options.pointDotStrokeWidth,\n\t\t\t\tradius : this.options.pointDotRadius,\n\t\t\t\tdisplay: this.options.pointDot,\n\t\t\t\thitDetectionRadius : this.options.pointHitDetectionRadius,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\tinRange : function(mouseX){\n\t\t\t\t\treturn (Math.pow(mouseX-this.x, 2) < Math.pow(this.radius + this.hitDetectionRadius,2));\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.datasets = [];\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activePoints = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];\n\t\t\t\t\tthis.eachPoints(function(point){\n\t\t\t\t\t\tpoint.restore(['fillColor', 'strokeColor']);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activePoints, function(activePoint){\n\t\t\t\t\t\tactivePoint.fillColor = activePoint.highlightFill;\n\t\t\t\t\t\tactivePoint.strokeColor = activePoint.highlightStroke;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activePoints);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t//Iterate through each of the datasets, and build this into a property of the chart\n\t\t\thelpers.each(data.datasets,function(dataset){\n\n\t\t\t\tvar datasetObject = {\n\t\t\t\t\tlabel : dataset.label || null,\n\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\tpointColor : dataset.pointColor,\n\t\t\t\t\tpointStrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\tpoints : []\n\t\t\t\t};\n\n\t\t\t\tthis.datasets.push(datasetObject);\n\n\n\t\t\t\thelpers.each(dataset.data,function(dataPoint,index){\n\t\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\t\tdatasetObject.points.push(new this.PointClass({\n\t\t\t\t\t\tvalue : dataPoint,\n\t\t\t\t\t\tlabel : data.labels[index],\n\t\t\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\t\t\tstrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\t\tfillColor : dataset.pointColor,\n\t\t\t\t\t\thighlightFill : dataset.pointHighlightFill || dataset.pointColor,\n\t\t\t\t\t\thighlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor\n\t\t\t\t\t}));\n\t\t\t\t},this);\n\n\t\t\t\tthis.buildScale(data.labels);\n\n\n\t\t\t\tthis.eachPoints(function(point, index){\n\t\t\t\t\thelpers.extend(point, {\n\t\t\t\t\t\tx: this.scale.calculateX(index),\n\t\t\t\t\t\ty: this.scale.endPoint\n\t\t\t\t\t});\n\t\t\t\t\tpoint.save();\n\t\t\t\t}, this);\n\n\t\t\t},this);\n\n\n\t\t\tthis.render();\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.scale.update();\n\t\t\t// Reset any highlight colours before updating.\n\t\t\thelpers.each(this.activeElements, function(activeElement){\n\t\t\t\tactiveElement.restore(['fillColor', 'strokeColor']);\n\t\t\t});\n\t\t\tthis.eachPoints(function(point){\n\t\t\t\tpoint.save();\n\t\t\t});\n\t\t\tthis.render();\n\t\t},\n\t\teachPoints : function(callback){\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\thelpers.each(dataset.points,callback,this);\n\t\t\t},this);\n\t\t},\n\t\tgetPointsAtEvent : function(e){\n\t\t\tvar pointsArray = [],\n\t\t\t\teventPosition = helpers.getRelativePosition(e);\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\thelpers.each(dataset.points,function(point){\n\t\t\t\t\tif (point.inRange(eventPosition.x,eventPosition.y)) pointsArray.push(point);\n\t\t\t\t});\n\t\t\t},this);\n\t\t\treturn pointsArray;\n\t\t},\n\t\tbuildScale : function(labels){\n\t\t\tvar self = this;\n\n\t\t\tvar dataTotal = function(){\n\t\t\t\tvar values = [];\n\t\t\t\tself.eachPoints(function(point){\n\t\t\t\t\tvalues.push(point.value);\n\t\t\t\t});\n\n\t\t\t\treturn values;\n\t\t\t};\n\n\t\t\tvar scaleOptions = {\n\t\t\t\ttemplateString : this.options.scaleLabel,\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttextColor : this.options.scaleFontColor,\n\t\t\t\tfontSize : this.options.scaleFontSize,\n\t\t\t\tfontStyle : this.options.scaleFontStyle,\n\t\t\t\tfontFamily : this.options.scaleFontFamily,\n\t\t\t\tvaluesCount : labels.length,\n\t\t\t\tbeginAtZero : this.options.scaleBeginAtZero,\n\t\t\t\tintegersOnly : this.options.scaleIntegersOnly,\n\t\t\t\tcalculateYRange : function(currentHeight){\n\t\t\t\t\tvar updatedRanges = helpers.calculateScaleRange(\n\t\t\t\t\t\tdataTotal(),\n\t\t\t\t\t\tcurrentHeight,\n\t\t\t\t\t\tthis.fontSize,\n\t\t\t\t\t\tthis.beginAtZero,\n\t\t\t\t\t\tthis.integersOnly\n\t\t\t\t\t);\n\t\t\t\t\thelpers.extend(this, updatedRanges);\n\t\t\t\t},\n\t\t\t\txLabels : labels,\n\t\t\t\tfont : helpers.fontString(this.options.scaleFontSize, this.options.scaleFontStyle, this.options.scaleFontFamily),\n\t\t\t\tlineWidth : this.options.scaleLineWidth,\n\t\t\t\tlineColor : this.options.scaleLineColor,\n\t\t\t\tshowHorizontalLines : this.options.scaleShowHorizontalLines,\n\t\t\t\tshowVerticalLines : this.options.scaleShowVerticalLines,\n\t\t\t\tgridLineWidth : (this.options.scaleShowGridLines) ? this.options.scaleGridLineWidth : 0,\n\t\t\t\tgridLineColor : (this.options.scaleShowGridLines) ? this.options.scaleGridLineColor : \"rgba(0,0,0,0)\",\n\t\t\t\tpadding: (this.options.showScale) ? 0 : this.options.pointDotRadius + this.options.pointDotStrokeWidth,\n\t\t\t\tshowLabels : this.options.scaleShowLabels,\n\t\t\t\tdisplay : this.options.showScale\n\t\t\t};\n\n\t\t\tif (this.options.scaleOverride){\n\t\t\t\thelpers.extend(scaleOptions, {\n\t\t\t\t\tcalculateYRange: helpers.noop,\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t});\n\t\t\t}\n\n\n\t\t\tthis.scale = new Chart.Scale(scaleOptions);\n\t\t},\n\t\taddData : function(valuesArray,label){\n\t\t\t//Map the values array for each of the datasets\n\n\t\t\thelpers.each(valuesArray,function(value,datasetIndex){\n\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\tthis.datasets[datasetIndex].points.push(new this.PointClass({\n\t\t\t\t\tvalue : value,\n\t\t\t\t\tlabel : label,\n\t\t\t\t\tx: this.scale.calculateX(this.scale.valuesCount+1),\n\t\t\t\t\ty: this.scale.endPoint,\n\t\t\t\t\tstrokeColor : this.datasets[datasetIndex].pointStrokeColor,\n\t\t\t\t\tfillColor : this.datasets[datasetIndex].pointColor\n\t\t\t\t}));\n\t\t\t},this);\n\n\t\t\tthis.scale.addXLabel(label);\n\t\t\t//Then re-render the chart.\n\t\t\tthis.update();\n\t\t},\n\t\tremoveData : function(){\n\t\t\tthis.scale.removeXLabel();\n\t\t\t//Then re-render the chart.\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tdataset.points.shift();\n\t\t\t},this);\n\t\t\tthis.update();\n\t\t},\n\t\treflow : function(){\n\t\t\tvar newScaleProps = helpers.extend({\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth : this.chart.width\n\t\t\t});\n\t\t\tthis.scale.update(newScaleProps);\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easingDecimal = ease || 1;\n\t\t\tthis.clear();\n\n\t\t\tvar ctx = this.chart.ctx;\n\n\t\t\t// Some helper methods for getting the next/prev points\n\t\t\tvar hasValue = function(item){\n\t\t\t\treturn item.value !== null;\n\t\t\t},\n\t\t\tnextPoint = function(point, collection, index){\n\t\t\t\treturn helpers.findNextWhere(collection, hasValue, index) || point;\n\t\t\t},\n\t\t\tpreviousPoint = function(point, collection, index){\n\t\t\t\treturn helpers.findPreviousWhere(collection, hasValue, index) || point;\n\t\t\t};\n\n\t\t\tthis.scale.draw(easingDecimal);\n\n\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tvar pointsWithValues = helpers.where(dataset.points, hasValue);\n\n\t\t\t\t//Transition each point first so that the line and point drawing isn't out of sync\n\t\t\t\t//We can use this extra loop to calculate the control points of this dataset also in this loop\n\n\t\t\t\thelpers.each(dataset.points, function(point, index){\n\t\t\t\t\tif (point.hasValue()){\n\t\t\t\t\t\tpoint.transition({\n\t\t\t\t\t\t\ty : this.scale.calculateY(point.value),\n\t\t\t\t\t\t\tx : this.scale.calculateX(index)\n\t\t\t\t\t\t}, easingDecimal);\n\t\t\t\t\t}\n\t\t\t\t},this);\n\n\n\t\t\t\t// Control points need to be calculated in a seperate loop, because we need to know the current x/y of the point\n\t\t\t\t// This would cause issues when there is no animation, because the y of the next point would be 0, so beziers would be skewed\n\t\t\t\tif (this.options.bezierCurve){\n\t\t\t\t\thelpers.each(pointsWithValues, function(point, index){\n\t\t\t\t\t\tvar tension = (index > 0 && index < pointsWithValues.length - 1) ? this.options.bezierCurveTension : 0;\n\t\t\t\t\t\tpoint.controlPoints = helpers.splineCurve(\n\t\t\t\t\t\t\tpreviousPoint(point, pointsWithValues, index),\n\t\t\t\t\t\t\tpoint,\n\t\t\t\t\t\t\tnextPoint(point, pointsWithValues, index),\n\t\t\t\t\t\t\ttension\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t// Prevent the bezier going outside of the bounds of the graph\n\n\t\t\t\t\t\t// Cap puter bezier handles to the upper/lower scale bounds\n\t\t\t\t\t\tif (point.controlPoints.outer.y > this.scale.endPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.outer.y = this.scale.endPoint;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (point.controlPoints.outer.y < this.scale.startPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.outer.y = this.scale.startPoint;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Cap inner bezier handles to the upper/lower scale bounds\n\t\t\t\t\t\tif (point.controlPoints.inner.y > this.scale.endPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.inner.y = this.scale.endPoint;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (point.controlPoints.inner.y < this.scale.startPoint){\n\t\t\t\t\t\t\tpoint.controlPoints.inner.y = this.scale.startPoint;\n\t\t\t\t\t\t}\n\t\t\t\t\t},this);\n\t\t\t\t}\n\n\n\t\t\t\t//Draw the line between all the points\n\t\t\t\tctx.lineWidth = this.options.datasetStrokeWidth;\n\t\t\t\tctx.strokeStyle = dataset.strokeColor;\n\t\t\t\tctx.beginPath();\n\n\t\t\t\thelpers.each(pointsWithValues, function(point, index){\n\t\t\t\t\tif (index === 0){\n\t\t\t\t\t\tctx.moveTo(point.x, point.y);\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\tif(this.options.bezierCurve){\n\t\t\t\t\t\t\tvar previous = previousPoint(point, pointsWithValues, index);\n\n\t\t\t\t\t\t\tctx.bezierCurveTo(\n\t\t\t\t\t\t\t\tprevious.controlPoints.outer.x,\n\t\t\t\t\t\t\t\tprevious.controlPoints.outer.y,\n\t\t\t\t\t\t\t\tpoint.controlPoints.inner.x,\n\t\t\t\t\t\t\t\tpoint.controlPoints.inner.y,\n\t\t\t\t\t\t\t\tpoint.x,\n\t\t\t\t\t\t\t\tpoint.y\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse{\n\t\t\t\t\t\t\tctx.lineTo(point.x,point.y);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}, this);\n\n\t\t\t\tctx.stroke();\n\n\t\t\t\tif (this.options.datasetFill && pointsWithValues.length > 0){\n\t\t\t\t\t//Round off the line by going to the base of the chart, back to the start, then fill.\n\t\t\t\t\tctx.lineTo(pointsWithValues[pointsWithValues.length - 1].x, this.scale.endPoint);\n\t\t\t\t\tctx.lineTo(pointsWithValues[0].x, this.scale.endPoint);\n\t\t\t\t\tctx.fillStyle = dataset.fillColor;\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tctx.fill();\n\t\t\t\t}\n\n\t\t\t\t//Now draw the points over the line\n\t\t\t\t//A little inefficient double looping, but better than the line\n\t\t\t\t//lagging behind the point positions\n\t\t\t\thelpers.each(pointsWithValues,function(point){\n\t\t\t\t\tpoint.draw();\n\t\t\t\t});\n\t\t\t},this);\n\t\t}\n\t});\n\n\n}).call(this);\n\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\t//Cache a local reference to Chart.helpers\n\t\thelpers = Chart.helpers;\n\n\tvar defaultConfig = {\n\t\t//Boolean - Show a backdrop to the scale label\n\t\tscaleShowLabelBackdrop : true,\n\n\t\t//String - The colour of the label backdrop\n\t\tscaleBackdropColor : \"rgba(255,255,255,0.75)\",\n\n\t\t// Boolean - Whether the scale should begin at zero\n\t\tscaleBeginAtZero : true,\n\n\t\t//Number - The backdrop padding above & below the label in pixels\n\t\tscaleBackdropPaddingY : 2,\n\n\t\t//Number - The backdrop padding to the side of the label in pixels\n\t\tscaleBackdropPaddingX : 2,\n\n\t\t//Boolean - Show line for each value in the scale\n\t\tscaleShowLine : true,\n\n\t\t//Boolean - Stroke a line around each segment in the chart\n\t\tsegmentShowStroke : true,\n\n\t\t//String - The colour of the stroke on each segement.\n\t\tsegmentStrokeColor : \"#fff\",\n\n\t\t//Number - The width of the stroke value in pixels\n\t\tsegmentStrokeWidth : 2,\n\n\t\t//Number - Amount of animation steps\n\t\tanimationSteps : 100,\n\n\t\t//String - Animation easing effect.\n\t\tanimationEasing : \"easeOutBounce\",\n\n\t\t//Boolean - Whether to animate the rotation of the chart\n\t\tanimateRotate : true,\n\n\t\t//Boolean - Whether to animate scaling the chart from the centre\n\t\tanimateScale : false,\n\n\t\t//String - A legend template\n\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<segments.length; i++){%><li><span style=\\\"background-color:<%=segments[i].fillColor%>\\\"></span><%if(segments[i].label){%><%=segments[i].label%><%}%></li><%}%></ul>\"\n\t};\n\n\n\tChart.Type.extend({\n\t\t//Passing in a name registers this chart in the Chart namespace\n\t\tname: \"PolarArea\",\n\t\t//Providing a defaults will also register the deafults in the chart namespace\n\t\tdefaults : defaultConfig,\n\t\t//Initialize is fired when the chart is initialized - Data is passed in as a parameter\n\t\t//Config is automatically merged by the core of Chart.js, and is available at this.options\n\t\tinitialize:  function(data){\n\t\t\tthis.segments = [];\n\t\t\t//Declare segment class as a chart instance specific class, so it can share props for this instance\n\t\t\tthis.SegmentArc = Chart.Arc.extend({\n\t\t\t\tshowStroke : this.options.segmentShowStroke,\n\t\t\t\tstrokeWidth : this.options.segmentStrokeWidth,\n\t\t\t\tstrokeColor : this.options.segmentStrokeColor,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\tinnerRadius : 0,\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\t\t\tthis.scale = new Chart.RadialScale({\n\t\t\t\tdisplay: this.options.showScale,\n\t\t\t\tfontStyle: this.options.scaleFontStyle,\n\t\t\t\tfontSize: this.options.scaleFontSize,\n\t\t\t\tfontFamily: this.options.scaleFontFamily,\n\t\t\t\tfontColor: this.options.scaleFontColor,\n\t\t\t\tshowLabels: this.options.scaleShowLabels,\n\t\t\t\tshowLabelBackdrop: this.options.scaleShowLabelBackdrop,\n\t\t\t\tbackdropColor: this.options.scaleBackdropColor,\n\t\t\t\tbackdropPaddingY : this.options.scaleBackdropPaddingY,\n\t\t\t\tbackdropPaddingX: this.options.scaleBackdropPaddingX,\n\t\t\t\tlineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,\n\t\t\t\tlineColor: this.options.scaleLineColor,\n\t\t\t\tlineArc: true,\n\t\t\t\twidth: this.chart.width,\n\t\t\t\theight: this.chart.height,\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttemplateString: this.options.scaleLabel,\n\t\t\t\tvaluesCount: data.length\n\t\t\t});\n\n\t\t\tthis.updateScaleRange(data);\n\n\t\t\tthis.scale.update();\n\n\t\t\thelpers.each(data,function(segment,index){\n\t\t\t\tthis.addData(segment,index,true);\n\t\t\t},this);\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activeSegments = (evt.type !== 'mouseout') ? this.getSegmentsAtEvent(evt) : [];\n\t\t\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\t\t\tsegment.restore([\"fillColor\"]);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activeSegments,function(activeSegment){\n\t\t\t\t\t\tactiveSegment.fillColor = activeSegment.highlightColor;\n\t\t\t\t\t});\n\t\t\t\t\tthis.showTooltip(activeSegments);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.render();\n\t\t},\n\t\tgetSegmentsAtEvent : function(e){\n\t\t\tvar segmentsArray = [];\n\n\t\t\tvar location = helpers.getRelativePosition(e);\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tif (segment.inRange(location.x,location.y)) segmentsArray.push(segment);\n\t\t\t},this);\n\t\t\treturn segmentsArray;\n\t\t},\n\t\taddData : function(segment, atIndex, silent){\n\t\t\tvar index = atIndex || this.segments.length;\n\n\t\t\tthis.segments.splice(index, 0, new this.SegmentArc({\n\t\t\t\tfillColor: segment.color,\n\t\t\t\thighlightColor: segment.highlight || segment.color,\n\t\t\t\tlabel: segment.label,\n\t\t\t\tvalue: segment.value,\n\t\t\t\touterRadius: (this.options.animateScale) ? 0 : this.scale.calculateCenterOffset(segment.value),\n\t\t\t\tcircumference: (this.options.animateRotate) ? 0 : this.scale.getCircumference(),\n\t\t\t\tstartAngle: Math.PI * 1.5\n\t\t\t}));\n\t\t\tif (!silent){\n\t\t\t\tthis.reflow();\n\t\t\t\tthis.update();\n\t\t\t}\n\t\t},\n\t\tremoveData: function(atIndex){\n\t\t\tvar indexToDelete = (helpers.isNumber(atIndex)) ? atIndex : this.segments.length-1;\n\t\t\tthis.segments.splice(indexToDelete, 1);\n\t\t\tthis.reflow();\n\t\t\tthis.update();\n\t\t},\n\t\tcalculateTotal: function(data){\n\t\t\tthis.total = 0;\n\t\t\thelpers.each(data,function(segment){\n\t\t\t\tthis.total += segment.value;\n\t\t\t},this);\n\t\t\tthis.scale.valuesCount = this.segments.length;\n\t\t},\n\t\tupdateScaleRange: function(datapoints){\n\t\t\tvar valuesArray = [];\n\t\t\thelpers.each(datapoints,function(segment){\n\t\t\t\tvaluesArray.push(segment.value);\n\t\t\t});\n\n\t\t\tvar scaleSizes = (this.options.scaleOverride) ?\n\t\t\t\t{\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t} :\n\t\t\t\thelpers.calculateScaleRange(\n\t\t\t\t\tvaluesArray,\n\t\t\t\t\thelpers.min([this.chart.width, this.chart.height])/2,\n\t\t\t\t\tthis.options.scaleFontSize,\n\t\t\t\t\tthis.options.scaleBeginAtZero,\n\t\t\t\t\tthis.options.scaleIntegersOnly\n\t\t\t\t);\n\n\t\t\thelpers.extend(\n\t\t\t\tthis.scale,\n\t\t\t\tscaleSizes,\n\t\t\t\t{\n\t\t\t\t\tsize: helpers.min([this.chart.width, this.chart.height]),\n\t\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\t\tyCenter: this.chart.height/2\n\t\t\t\t}\n\t\t\t);\n\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.calculateTotal(this.segments);\n\n\t\t\thelpers.each(this.segments,function(segment){\n\t\t\t\tsegment.save();\n\t\t\t});\n\t\t\t\n\t\t\tthis.reflow();\n\t\t\tthis.render();\n\t\t},\n\t\treflow : function(){\n\t\t\thelpers.extend(this.SegmentArc.prototype,{\n\t\t\t\tx : this.chart.width/2,\n\t\t\t\ty : this.chart.height/2\n\t\t\t});\n\t\t\tthis.updateScaleRange(this.segments);\n\t\t\tthis.scale.update();\n\n\t\t\thelpers.extend(this.scale,{\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2\n\t\t\t});\n\n\t\t\thelpers.each(this.segments, function(segment){\n\t\t\t\tsegment.update({\n\t\t\t\t\touterRadius : this.scale.calculateCenterOffset(segment.value)\n\t\t\t\t});\n\t\t\t}, this);\n\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easingDecimal = ease || 1;\n\t\t\t//Clear & draw the canvas\n\t\t\tthis.clear();\n\t\t\thelpers.each(this.segments,function(segment, index){\n\t\t\t\tsegment.transition({\n\t\t\t\t\tcircumference : this.scale.getCircumference(),\n\t\t\t\t\touterRadius : this.scale.calculateCenterOffset(segment.value)\n\t\t\t\t},easingDecimal);\n\n\t\t\t\tsegment.endAngle = segment.startAngle + segment.circumference;\n\n\t\t\t\t// If we've removed the first segment we need to set the first one to\n\t\t\t\t// start at the top.\n\t\t\t\tif (index === 0){\n\t\t\t\t\tsegment.startAngle = Math.PI * 1.5;\n\t\t\t\t}\n\n\t\t\t\t//Check to see if it's the last segment, if not get the next and update the start angle\n\t\t\t\tif (index < this.segments.length - 1){\n\t\t\t\t\tthis.segments[index+1].startAngle = segment.endAngle;\n\t\t\t\t}\n\t\t\t\tsegment.draw();\n\t\t\t}, this);\n\t\t\tthis.scale.draw();\n\t\t}\n\t});\n\n}).call(this);\n(function(){\n\t\"use strict\";\n\n\tvar root = this,\n\t\tChart = root.Chart,\n\t\thelpers = Chart.helpers;\n\n\n\n\tChart.Type.extend({\n\t\tname: \"Radar\",\n\t\tdefaults:{\n\t\t\t//Boolean - Whether to show lines for each scale point\n\t\t\tscaleShowLine : true,\n\n\t\t\t//Boolean - Whether we show the angle lines out of the radar\n\t\t\tangleShowLineOut : true,\n\n\t\t\t//Boolean - Whether to show labels on the scale\n\t\t\tscaleShowLabels : false,\n\n\t\t\t// Boolean - Whether the scale should begin at zero\n\t\t\tscaleBeginAtZero : true,\n\n\t\t\t//String - Colour of the angle line\n\t\t\tangleLineColor : \"rgba(0,0,0,.1)\",\n\n\t\t\t//Number - Pixel width of the angle line\n\t\t\tangleLineWidth : 1,\n\n\t\t\t//String - Point label font declaration\n\t\t\tpointLabelFontFamily : \"'Arial'\",\n\n\t\t\t//String - Point label font weight\n\t\t\tpointLabelFontStyle : \"normal\",\n\n\t\t\t//Number - Point label font size in pixels\n\t\t\tpointLabelFontSize : 10,\n\n\t\t\t//String - Point label font colour\n\t\t\tpointLabelFontColor : \"#666\",\n\n\t\t\t//Boolean - Whether to show a dot for each point\n\t\t\tpointDot : true,\n\n\t\t\t//Number - Radius of each point dot in pixels\n\t\t\tpointDotRadius : 3,\n\n\t\t\t//Number - Pixel width of point dot stroke\n\t\t\tpointDotStrokeWidth : 1,\n\n\t\t\t//Number - amount extra to add to the radius to cater for hit detection outside the drawn point\n\t\t\tpointHitDetectionRadius : 20,\n\n\t\t\t//Boolean - Whether to show a stroke for datasets\n\t\t\tdatasetStroke : true,\n\n\t\t\t//Number - Pixel width of dataset stroke\n\t\t\tdatasetStrokeWidth : 2,\n\n\t\t\t//Boolean - Whether to fill the dataset with a colour\n\t\t\tdatasetFill : true,\n\n\t\t\t//String - A legend template\n\t\t\tlegendTemplate : \"<ul class=\\\"<%=name.toLowerCase()%>-legend\\\"><% for (var i=0; i<datasets.length; i++){%><li><span style=\\\"background-color:<%=datasets[i].strokeColor%>\\\"></span><%if(datasets[i].label){%><%=datasets[i].label%><%}%></li><%}%></ul>\"\n\n\t\t},\n\n\t\tinitialize: function(data){\n\t\t\tthis.PointClass = Chart.Point.extend({\n\t\t\t\tstrokeWidth : this.options.pointDotStrokeWidth,\n\t\t\t\tradius : this.options.pointDotRadius,\n\t\t\t\tdisplay: this.options.pointDot,\n\t\t\t\thitDetectionRadius : this.options.pointHitDetectionRadius,\n\t\t\t\tctx : this.chart.ctx\n\t\t\t});\n\n\t\t\tthis.datasets = [];\n\n\t\t\tthis.buildScale(data);\n\n\t\t\t//Set up tooltip events on the chart\n\t\t\tif (this.options.showTooltips){\n\t\t\t\thelpers.bindEvents(this, this.options.tooltipEvents, function(evt){\n\t\t\t\t\tvar activePointsCollection = (evt.type !== 'mouseout') ? this.getPointsAtEvent(evt) : [];\n\n\t\t\t\t\tthis.eachPoints(function(point){\n\t\t\t\t\t\tpoint.restore(['fillColor', 'strokeColor']);\n\t\t\t\t\t});\n\t\t\t\t\thelpers.each(activePointsCollection, function(activePoint){\n\t\t\t\t\t\tactivePoint.fillColor = activePoint.highlightFill;\n\t\t\t\t\t\tactivePoint.strokeColor = activePoint.highlightStroke;\n\t\t\t\t\t});\n\n\t\t\t\t\tthis.showTooltip(activePointsCollection);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t//Iterate through each of the datasets, and build this into a property of the chart\n\t\t\thelpers.each(data.datasets,function(dataset){\n\n\t\t\t\tvar datasetObject = {\n\t\t\t\t\tlabel: dataset.label || null,\n\t\t\t\t\tfillColor : dataset.fillColor,\n\t\t\t\t\tstrokeColor : dataset.strokeColor,\n\t\t\t\t\tpointColor : dataset.pointColor,\n\t\t\t\t\tpointStrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\tpoints : []\n\t\t\t\t};\n\n\t\t\t\tthis.datasets.push(datasetObject);\n\n\t\t\t\thelpers.each(dataset.data,function(dataPoint,index){\n\t\t\t\t\t//Add a new point for each piece of data, passing any required data to draw.\n\t\t\t\t\tvar pointPosition;\n\t\t\t\t\tif (!this.scale.animation){\n\t\t\t\t\t\tpointPosition = this.scale.getPointPosition(index, this.scale.calculateCenterOffset(dataPoint));\n\t\t\t\t\t}\n\t\t\t\t\tdatasetObject.points.push(new this.PointClass({\n\t\t\t\t\t\tvalue : dataPoint,\n\t\t\t\t\t\tlabel : data.labels[index],\n\t\t\t\t\t\tdatasetLabel: dataset.label,\n\t\t\t\t\t\tx: (this.options.animation) ? this.scale.xCenter : pointPosition.x,\n\t\t\t\t\t\ty: (this.options.animation) ? this.scale.yCenter : pointPosition.y,\n\t\t\t\t\t\tstrokeColor : dataset.pointStrokeColor,\n\t\t\t\t\t\tfillColor : dataset.pointColor,\n\t\t\t\t\t\thighlightFill : dataset.pointHighlightFill || dataset.pointColor,\n\t\t\t\t\t\thighlightStroke : dataset.pointHighlightStroke || dataset.pointStrokeColor\n\t\t\t\t\t}));\n\t\t\t\t},this);\n\n\t\t\t},this);\n\n\t\t\tthis.render();\n\t\t},\n\t\teachPoints : function(callback){\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\thelpers.each(dataset.points,callback,this);\n\t\t\t},this);\n\t\t},\n\n\t\tgetPointsAtEvent : function(evt){\n\t\t\tvar mousePosition = helpers.getRelativePosition(evt),\n\t\t\t\tfromCenter = helpers.getAngleFromPoint({\n\t\t\t\t\tx: this.scale.xCenter,\n\t\t\t\t\ty: this.scale.yCenter\n\t\t\t\t}, mousePosition);\n\n\t\t\tvar anglePerIndex = (Math.PI * 2) /this.scale.valuesCount,\n\t\t\t\tpointIndex = Math.round((fromCenter.angle - Math.PI * 1.5) / anglePerIndex),\n\t\t\t\tactivePointsCollection = [];\n\n\t\t\t// If we're at the top, make the pointIndex 0 to get the first of the array.\n\t\t\tif (pointIndex >= this.scale.valuesCount || pointIndex < 0){\n\t\t\t\tpointIndex = 0;\n\t\t\t}\n\n\t\t\tif (fromCenter.distance <= this.scale.drawingArea){\n\t\t\t\thelpers.each(this.datasets, function(dataset){\n\t\t\t\t\tactivePointsCollection.push(dataset.points[pointIndex]);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn activePointsCollection;\n\t\t},\n\n\t\tbuildScale : function(data){\n\t\t\tthis.scale = new Chart.RadialScale({\n\t\t\t\tdisplay: this.options.showScale,\n\t\t\t\tfontStyle: this.options.scaleFontStyle,\n\t\t\t\tfontSize: this.options.scaleFontSize,\n\t\t\t\tfontFamily: this.options.scaleFontFamily,\n\t\t\t\tfontColor: this.options.scaleFontColor,\n\t\t\t\tshowLabels: this.options.scaleShowLabels,\n\t\t\t\tshowLabelBackdrop: this.options.scaleShowLabelBackdrop,\n\t\t\t\tbackdropColor: this.options.scaleBackdropColor,\n\t\t\t\tbackdropPaddingY : this.options.scaleBackdropPaddingY,\n\t\t\t\tbackdropPaddingX: this.options.scaleBackdropPaddingX,\n\t\t\t\tlineWidth: (this.options.scaleShowLine) ? this.options.scaleLineWidth : 0,\n\t\t\t\tlineColor: this.options.scaleLineColor,\n\t\t\t\tangleLineColor : this.options.angleLineColor,\n\t\t\t\tangleLineWidth : (this.options.angleShowLineOut) ? this.options.angleLineWidth : 0,\n\t\t\t\t// Point labels at the edge of each line\n\t\t\t\tpointLabelFontColor : this.options.pointLabelFontColor,\n\t\t\t\tpointLabelFontSize : this.options.pointLabelFontSize,\n\t\t\t\tpointLabelFontFamily : this.options.pointLabelFontFamily,\n\t\t\t\tpointLabelFontStyle : this.options.pointLabelFontStyle,\n\t\t\t\theight : this.chart.height,\n\t\t\t\twidth: this.chart.width,\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2,\n\t\t\t\tctx : this.chart.ctx,\n\t\t\t\ttemplateString: this.options.scaleLabel,\n\t\t\t\tlabels: data.labels,\n\t\t\t\tvaluesCount: data.datasets[0].data.length\n\t\t\t});\n\n\t\t\tthis.scale.setScaleSize();\n\t\t\tthis.updateScaleRange(data.datasets);\n\t\t\tthis.scale.buildYLabels();\n\t\t},\n\t\tupdateScaleRange: function(datasets){\n\t\t\tvar valuesArray = (function(){\n\t\t\t\tvar totalDataArray = [];\n\t\t\t\thelpers.each(datasets,function(dataset){\n\t\t\t\t\tif (dataset.data){\n\t\t\t\t\t\ttotalDataArray = totalDataArray.concat(dataset.data);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\thelpers.each(dataset.points, function(point){\n\t\t\t\t\t\t\ttotalDataArray.push(point.value);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\treturn totalDataArray;\n\t\t\t})();\n\n\n\t\t\tvar scaleSizes = (this.options.scaleOverride) ?\n\t\t\t\t{\n\t\t\t\t\tsteps: this.options.scaleSteps,\n\t\t\t\t\tstepValue: this.options.scaleStepWidth,\n\t\t\t\t\tmin: this.options.scaleStartValue,\n\t\t\t\t\tmax: this.options.scaleStartValue + (this.options.scaleSteps * this.options.scaleStepWidth)\n\t\t\t\t} :\n\t\t\t\thelpers.calculateScaleRange(\n\t\t\t\t\tvaluesArray,\n\t\t\t\t\thelpers.min([this.chart.width, this.chart.height])/2,\n\t\t\t\t\tthis.options.scaleFontSize,\n\t\t\t\t\tthis.options.scaleBeginAtZero,\n\t\t\t\t\tthis.options.scaleIntegersOnly\n\t\t\t\t);\n\n\t\t\thelpers.extend(\n\t\t\t\tthis.scale,\n\t\t\t\tscaleSizes\n\t\t\t);\n\n\t\t},\n\t\taddData : function(valuesArray,label){\n\t\t\t//Map the values array for each of the datasets\n\t\t\tthis.scale.valuesCount++;\n\t\t\thelpers.each(valuesArray,function(value,datasetIndex){\n\t\t\t\tvar pointPosition = this.scale.getPointPosition(this.scale.valuesCount, this.scale.calculateCenterOffset(value));\n\t\t\t\tthis.datasets[datasetIndex].points.push(new this.PointClass({\n\t\t\t\t\tvalue : value,\n\t\t\t\t\tlabel : label,\n\t\t\t\t\tx: pointPosition.x,\n\t\t\t\t\ty: pointPosition.y,\n\t\t\t\t\tstrokeColor : this.datasets[datasetIndex].pointStrokeColor,\n\t\t\t\t\tfillColor : this.datasets[datasetIndex].pointColor\n\t\t\t\t}));\n\t\t\t},this);\n\n\t\t\tthis.scale.labels.push(label);\n\n\t\t\tthis.reflow();\n\n\t\t\tthis.update();\n\t\t},\n\t\tremoveData : function(){\n\t\t\tthis.scale.valuesCount--;\n\t\t\tthis.scale.labels.shift();\n\t\t\thelpers.each(this.datasets,function(dataset){\n\t\t\t\tdataset.points.shift();\n\t\t\t},this);\n\t\t\tthis.reflow();\n\t\t\tthis.update();\n\t\t},\n\t\tupdate : function(){\n\t\t\tthis.eachPoints(function(point){\n\t\t\t\tpoint.save();\n\t\t\t});\n\t\t\tthis.reflow();\n\t\t\tthis.render();\n\t\t},\n\t\treflow: function(){\n\t\t\thelpers.extend(this.scale, {\n\t\t\t\twidth : this.chart.width,\n\t\t\t\theight: this.chart.height,\n\t\t\t\tsize : helpers.min([this.chart.width, this.chart.height]),\n\t\t\t\txCenter: this.chart.width/2,\n\t\t\t\tyCenter: this.chart.height/2\n\t\t\t});\n\t\t\tthis.updateScaleRange(this.datasets);\n\t\t\tthis.scale.setScaleSize();\n\t\t\tthis.scale.buildYLabels();\n\t\t},\n\t\tdraw : function(ease){\n\t\t\tvar easeDecimal = ease || 1,\n\t\t\t\tctx = this.chart.ctx;\n\t\t\tthis.clear();\n\t\t\tthis.scale.draw();\n\n\t\t\thelpers.each(this.datasets,function(dataset){\n\n\t\t\t\t//Transition each point first so that the line and point drawing isn't out of sync\n\t\t\t\thelpers.each(dataset.points,function(point,index){\n\t\t\t\t\tif (point.hasValue()){\n\t\t\t\t\t\tpoint.transition(this.scale.getPointPosition(index, this.scale.calculateCenterOffset(point.value)), easeDecimal);\n\t\t\t\t\t}\n\t\t\t\t},this);\n\n\n\n\t\t\t\t//Draw the line between all the points\n\t\t\t\tctx.lineWidth = this.options.datasetStrokeWidth;\n\t\t\t\tctx.strokeStyle = dataset.strokeColor;\n\t\t\t\tctx.beginPath();\n\t\t\t\thelpers.each(dataset.points,function(point,index){\n\t\t\t\t\tif (index === 0){\n\t\t\t\t\t\tctx.moveTo(point.x,point.y);\n\t\t\t\t\t}\n\t\t\t\t\telse{\n\t\t\t\t\t\tctx.lineTo(point.x,point.y);\n\t\t\t\t\t}\n\t\t\t\t},this);\n\t\t\t\tctx.closePath();\n\t\t\t\tctx.stroke();\n\n\t\t\t\tctx.fillStyle = dataset.fillColor;\n\t\t\t\tctx.fill();\n\n\t\t\t\t//Now draw the points over the line\n\t\t\t\t//A little inefficient double looping, but better than the line\n\t\t\t\t//lagging behind the point positions\n\t\t\t\thelpers.each(dataset.points,function(point){\n\t\t\t\t\tif (point.hasValue()){\n\t\t\t\t\t\tpoint.draw();\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t},this);\n\n\t\t}\n\n\t});\n\n\n\n\n\n}).call(this);\n"
  },
  {
    "path": "public/static/plugins/ckeditor/CHANGES.md",
    "content": "CKEditor 4 Changelog\r\n====================\r\n\r\n## CKEditor 4.3.1\r\n\r\n**Important Notes:**\r\n\r\n* To match the naming convention, the `language` button is now `Language` ([#11201](http://dev.ckeditor.com/ticket/11201)).\r\n* [Enhanced Image](http://ckeditor.com/addon/image2) button, context menu, command, and icon names match those of the [Image](http://ckeditor.com/addon/image) plugin ([#11222](http://dev.ckeditor.com/ticket/11222)).\r\n\r\nFixed Issues:\r\n\r\n* [#11244](http://dev.ckeditor.com/ticket/11244): Changed: The [`widget.repository.checkWidgets()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-checkWidgets) method now fires the [`widget.repository.checkWidgets`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-event-checkWidgets) event, so from CKEditor 4.3.1 it is preferred to use the method rather than fire the event.\r\n* [#11171](http://dev.ckeditor.com/ticket/11171): Fixed: [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) and [`editor.insertText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertText) methods do not call the [`widget.repository.checkWidgets()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-checkWidgets) method.\r\n* [#11085](http://dev.ckeditor.com/ticket/11085): [IE8] Replaced preview generated by the [Mathematical Formulas](http://ckeditor.com/addon/mathjax) widget with a placeholder.\r\n* [#11044](http://dev.ckeditor.com/ticket/11044): Enhanced WAI-ARIA support for the [Language](http://ckeditor.com/addon/language) plugin drop-down menu.\r\n* [#11075](http://dev.ckeditor.com/ticket/11075): With drop-down menu button focused, pressing the *Down Arrow* key will now open the menu and focus its first option.\r\n* [#11165](http://dev.ckeditor.com/ticket/11165): Fixed: The [File Browser](http://ckeditor.com/addon/filebrowser) plugin cannot be removed from the editor.\r\n* [#11159](http://dev.ckeditor.com/ticket/11159): [IE9-10] [Enhanced Image](http://ckeditor.com/addon/image2): Fixed buggy discovery of image dimensions.\r\n* [#11101](http://dev.ckeditor.com/ticket/11101): Drop-down lists no longer break when given double quotes.\r\n* [#11077](http://dev.ckeditor.com/ticket/11077): [Enhanced Image](http://ckeditor.com/addon/image2): Empty undo step recorded when resizing the image.\r\n* [#10853](http://dev.ckeditor.com/ticket/10853): [Enhanced Image](http://ckeditor.com/addon/image2): Widget has paragraph wrapper when de-captioning unaligned image.\r\n* [#11198](http://dev.ckeditor.com/ticket/11198): Widgets: Drag handler is not fully visible when an inline widget is in a heading.\r\n* [#11132](http://dev.ckeditor.com/ticket/11132): [Firefox] Fixed: Caret is lost after drag and drop of an inline widget.\r\n* [#11182](http://dev.ckeditor.com/ticket/11182): [IE10-11] Fixed: Editor crashes (IE11) or works with minor issues (IE10) if a page is loaded in Quirks Mode. See [`env.quirks`](http://docs.ckeditor.com/#!/api/CKEDITOR.env-property-quirks) for more details.\r\n* [#11204](http://dev.ckeditor.com/ticket/11204): Added `figure` and `figcaption` styles to the `contents.css` file so [Enhanced Image](http://ckeditor.com/addon/image2) looks nicer.\r\n* [#11202](http://dev.ckeditor.com/ticket/11202): Fixed: No newline in [BBCode](http://ckeditor.com/addon/bbcode) mode.\r\n* [#10890](http://dev.ckeditor.com/ticket/10890): Fixed: Error thrown when pressing the *Delete* key in a list item.\r\n* [#10055](http://dev.ckeditor.com/ticket/10055): [IE8-10] Fixed: *Delete* pressed on a selected image causes the browser to go back.\r\n* [#11183](http://dev.ckeditor.com/ticket/11183): Fixed: Inserting a horizontal rule or a table in multiple row selection causes a browser crash. Additionally, the [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) method does not insert the element into every range of a selection any more.\r\n* [#11042](http://dev.ckeditor.com/ticket/11042): Fixed: Selection made on an element containing a non-editable element was not auto faked.\r\n* [#11125](http://dev.ckeditor.com/ticket/11125): Fixed: Keyboard navigation through menu and drop-down items will now cycle.\r\n* [#11011](http://dev.ckeditor.com/ticket/11011): Fixed: The [`editor.applyStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-applyStyle) method removes attributes from nested elements.\r\n* [#11179](http://dev.ckeditor.com/ticket/11179): Fixed: [`editor.destroy()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-destroy) does not cleanup content generated by the [Table Resize](http://ckeditor.com/addon/tableresize) plugin for inline editors.\r\n* [#11237](http://dev.ckeditor.com/ticket/11237): Fixed: Table border attribute value is deleted when pasting content from Microsoft Word.\r\n* [#11250](http://dev.ckeditor.com/ticket/11250): Fixed: HTML entities inside the `<textarea>` element are not encoded.\r\n* [#11260](http://dev.ckeditor.com/ticket/11260): Fixed: Initially disabled buttons are not read by JAWS as disabled.\r\n* [#11200](http://dev.ckeditor.com/ticket/11200):  Added [Clipboard](http://ckeditor.com/addon/clipboard) plugin as a dependency for [Widget](http://ckeditor.com/addon/widget) to fix drag and drop.\r\n\r\n## CKEditor 4.3\r\n\r\nNew Features:\r\n\r\n* [#10612](http://dev.ckeditor.com/ticket/10612): Internet Explorer 11 support.\r\n* [#10869](http://dev.ckeditor.com/ticket/10869): Widgets: Added better integration with the [Elements Path](http://ckeditor.com/addon/elementspath) plugin.\r\n* [#10886](http://dev.ckeditor.com/ticket/10886): Widgets: Added tooltip to the drag handle.\r\n* [#10933](http://dev.ckeditor.com/ticket/10933): Widgets: Introduced drag and drop of block widgets with the [Line Utilities](http://ckeditor.com/addon/lineutils) plugin.\r\n* [#10936](http://dev.ckeditor.com/ticket/10936): Widget System changes for easier integration with other dialog systems.\r\n* [#10895](http://dev.ckeditor.com/ticket/10895): [Enhanced Image](http://ckeditor.com/addon/image2): Added file browser integration.\r\n* [#11002](http://dev.ckeditor.com/ticket/11002): Added the [`draggable`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.definition-property-draggable) option to disable drag and drop support for widgets.\r\n* [#10937](http://dev.ckeditor.com/ticket/10937): [Mathematical Formulas](http://ckeditor.com/addon/mathjax) widget improvements:\r\n  * loading indicator ([#10948](http://dev.ckeditor.com/ticket/10948)),\r\n  * applying paragraph changes (like font color change) to iframe ([#10841](http://dev.ckeditor.com/ticket/10841)),\r\n  * Firefox and IE9 clipboard fixes ([#10857](http://dev.ckeditor.com/ticket/10857)),\r\n  * fixing same origin policy issue ([#10840](http://dev.ckeditor.com/ticket/10840)),\r\n  * fixing undo bugs ([#10842](http://dev.ckeditor.com/ticket/10842), [#10930](http://dev.ckeditor.com/ticket/10930)),\r\n  * fixing other minor bugs.\r\n* [#10862](http://dev.ckeditor.com/ticket/10862): [Placeholder](http://ckeditor.com/addon/placeholder) plugin was rewritten as a widget.\r\n* [#10822](http://dev.ckeditor.com/ticket/10822): Added styles system integration with non-editable elements (for example widgets) and their nested editables. Styles cannot change non-editable content and are applied in nested editable only if allowed by its type and content filter.\r\n* [#10856](http://dev.ckeditor.com/ticket/10856): Menu buttons will now toggle the visibility of their panels when clicked multiple times. [Language](http://ckeditor.com/addon/language) plugin fixes: Added active language highlighting, added an option to remove the language.\r\n* [#10028](http://dev.ckeditor.com/ticket/10028): New [`config.dialog_noConfirmCancel`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-dialog_noConfirmCancel) configuration option that eliminates the need to confirm closing of a dialog window when the user changed any of its fields.\r\n* [#10848](http://dev.ckeditor.com/ticket/10848): Integrate remaining plugins ([Styles](http://ckeditor.com/addon/stylescombo), [Format](http://ckeditor.com/addon/format), [Font](http://ckeditor.com/addon/font), [Color Button](http://ckeditor.com/addon/colorbutton), [Language](http://ckeditor.com/addon/language) and [Indent](http://ckeditor.com/addon/indent)) with [active filter](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeFilter).\r\n* [#10855](http://dev.ckeditor.com/ticket/10855): Change the extension of emoticons in the [BBCode](http://ckeditor.com/addon/bbcode) sample from GIF to PNG.\r\n\r\nFixed Issues:\r\n\r\n* [#10831](http://dev.ckeditor.com/ticket/10831): [Enhanced Image](http://ckeditor.com/addon/image2): Merged `image2inline` and `image2block` into one `image2` widget.\r\n* [#10835](http://dev.ckeditor.com/ticket/10835): [Enhanced Image](http://ckeditor.com/addon/image2): Improved visibility of the resize handle.\r\n* [#10836](http://dev.ckeditor.com/ticket/10836): [Enhanced Image](http://ckeditor.com/addon/image2): Preserve custom mouse cursor while resizing the image.\r\n* [#10939](http://dev.ckeditor.com/ticket/10939): [Firefox] [Enhanced Image](http://ckeditor.com/addon/image2): hovering the image causes it to change.\r\n* [#10866](http://dev.ckeditor.com/ticket/10866): Fixed: Broken *Tab* key navigation in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window.\r\n* [#10833](http://dev.ckeditor.com/ticket/10833): Fixed: *Lock ratio* option should be on by default in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window.\r\n* [#10881](http://dev.ckeditor.com/ticket/10881): Various improvements to *Enter* key behavior in nested editables.\r\n* [#10879](http://dev.ckeditor.com/ticket/10879): [Remove Format](http://ckeditor.com/addon/removeformat) should not leak from a nested editable.\r\n* [#10877](http://dev.ckeditor.com/ticket/10877): Fixed: [WebSpellChecker](http://ckeditor.com/addon/wsc) fails to apply changes if a nested editable was focused.\r\n* [#10877](http://dev.ckeditor.com/ticket/10877): Fixed: [SCAYT](http://ckeditor.com/addon/wsc) blocks typing in nested editables.\r\n* [#11079](http://dev.ckeditor.com/ticket/11079): Add button icons to the [Placeholder](http://ckeditor.com/addon/placeholder) sample.\r\n* [#10870](http://dev.ckeditor.com/ticket/10870): The `paste` command is no longer being disabled when the clipboard is empty.\r\n* [#10854](http://dev.ckeditor.com/ticket/10854): Fixed: Firefox prepends `<br>` to `<body>`, so it is stripped by the HTML data processor.\r\n* [#10823](http://dev.ckeditor.com/ticket/10823): Fixed: [Link](http://ckeditor.com/addon/link) plugin does not work with non-editable content.\r\n* [#10828](http://dev.ckeditor.com/ticket/10828): [Magic Line](http://ckeditor.com/addon/magicline) integration with the Widget System.\r\n* [#10865](http://dev.ckeditor.com/ticket/10865): Improved hiding copybin, so copying widgets works smoothly.\r\n* [#11066](http://dev.ckeditor.com/ticket/11066): Widget's private parts use CSS reset.\r\n* [#11027](http://dev.ckeditor.com/ticket/11027): Fixed: Block commands break on widgets; added the [`contentDomInvalidated`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-contentDomInvalidated) event.\r\n* [#10430](http://dev.ckeditor.com/ticket/10430): Resolve dependence of the [Image](http://ckeditor.com/addon/image) plugin on the [Form Elements](http://ckeditor.com/addon/forms) plugin.\r\n* [#10911](http://dev.ckeditor.com/ticket/10911): Fixed: Browser *Alt* hotkeys will no longer be blocked while a widget is focused.\r\n* [#11082](http://dev.ckeditor.com/ticket/11082): Fixed: Selected widget is not copied or cut when using toolbar buttons or context menu.\r\n* [#11083](http://dev.ckeditor.com/ticket/11083): Fixed list and div element application to block widgets.\r\n* [#10887](http://dev.ckeditor.com/ticket/10887): Internet Explorer 8 compatibility issues related to the Widget System.\r\n* [#11074](http://dev.ckeditor.com/ticket/11074): Temporarily disabled inline widget drag and drop, because of seriously buggy native `range#moveToPoint` method.\r\n* [#11098](http://dev.ckeditor.com/ticket/11098): Fixed: Wrong selection position after undoing widget drag and drop.\r\n* [#11110](http://dev.ckeditor.com/ticket/11110): Fixed: IFrame and Flash objects are being incorrectly pasted in certain conditions.\r\n* [#11129](http://dev.ckeditor.com/ticket/11129): Page break is lost when loading data.\r\n* [#11123](http://dev.ckeditor.com/ticket/11123): [Firefox] Widget is destroyed after being dragged outside of `<body>`.\r\n* [#11124](http://dev.ckeditor.com/ticket/11124): Fixed the [Elements Path](http://ckeditor.com/addon/elementspath) in an editor using the [Div Editing Area](http://ckeditor.com/addon/divarea).\r\n\r\n## CKEditor 4.3 Beta\r\n\r\nNew Features:\r\n\r\n* [#9764](http://dev.ckeditor.com/ticket/9764): Widget System.\r\n  * [Widget plugin](http://ckeditor.com/addon/widget) introducing the [Widget API](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget).\r\n  * New [`editor.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-enterMode) and [`editor.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-shiftEnterMode) properties &ndash; normalized versions of [`config.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) and [`config.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-shiftEnterMode).\r\n  * Dynamic editor settings. Starting from CKEditor 4.3 Beta, *Enter* mode values and [content filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) instances may be changed dynamically (for example when the caret was placed in an element in which editor features should be adjusted). When you are implementing a new editor feature, you should base its behavior on [dynamic](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeEnterMode) or [static](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-enterMode) *Enter* mode values depending on whether this feature works in selection context or globally on editor content.\r\n      * Dynamic *Enter* mode values &ndash; [`editor.setActiveEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setActiveEnterMode) method, [`editor.activeEnterModeChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-activeEnterModeChange) event, and two properties: [`editor.activeEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeEnterMode) and [`editor.activeShiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeShiftEnterMode).\r\n      * Dynamic content filter instances &ndash; [`editor.setActiveFilter`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setActiveFilter) method, [`editor.activeFilterChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-activeFilterChange) event, and [`editor.activeFilter`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeFilter) property.\r\n  * \"Fake\" selection was introduced. It makes it possible to virtually select any element when the real selection remains hidden. See the  [`selection.fake`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-fake) method.\r\n  * Default [`htmlParser.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter) rules are not applied to non-editable elements (elements with `contenteditable` attribute set to `false` and their descendants) anymore. To add a rule which will be applied to all elements you need to pass an additional argument to the [`filter.addRules`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter-method-addRules) method.\r\n  * Dozens of new methods were introduced &ndash; most interesting ones:\r\n      * [`document.find`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.document-method-find),\r\n      * [`document.findOne`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.document-method-findOne),\r\n      * [`editable.insertElementIntoRange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElementIntoRange),\r\n      * [`range.moveToClosestEditablePosition`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-moveToClosestEditablePosition),\r\n      * New methods for [`htmlParser.node`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.node) and [`htmlParser.element`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.element).\r\n* [#10659](http://dev.ckeditor.com/ticket/10659): New [Enhanced Image](http://ckeditor.com/addon/image2) plugin that introduces a widget with integrated image captions, an option to center images, and dynamic \"click and drag\" resizing.\r\n* [#10664](http://dev.ckeditor.com/ticket/10664): New [Mathematical Formulas](http://ckeditor.com/addon/mathjax) plugin that introduces the MathJax widget.\r\n* [#7987](https://dev.ckeditor.com/ticket/7987): New [Language](http://ckeditor.com/addon/language) plugin that implements Language toolbar button to support [WCAG 3.1.2 Language of Parts](http://www.w3.org/TR/UNDERSTANDING-WCAG20/meaning-other-lang-id.html).\r\n* [#10708](http://dev.ckeditor.com/ticket/10708): New [smileys](http://ckeditor.com/addon/smiley).\r\n\r\n## CKEditor 4.2.3\r\n\r\nFixed Issues:\r\n\r\n* [#10994](http://dev.ckeditor.com/ticket/10994): Fixed: Loading external jQuery library when opening the [jQuery Adapter](http://docs.ckeditor.com/#!/guide/dev_jquery) sample directly from file.\r\n* [#10975](http://dev.ckeditor.com/ticket/10975): [IE] Fixed: Error thrown while opening the color palette.\r\n* [#9929](http://dev.ckeditor.com/ticket/9929): [Blink/WebKit] Fixed: A non-breaking space is created once a character is deleted and a regular space is typed.\r\n* [#10963](http://dev.ckeditor.com/ticket/10963): Fixed: JAWS issue with the keyboard shortcut for [Magic Line](http://ckeditor.com/addon/magicline).\r\n* [#11096](http://dev.ckeditor.com/ticket/11096): Fixed: TypeError: Object has no method 'is'.\r\n\r\n## CKEditor 4.2.2\r\n\r\nFixed Issues:\r\n\r\n* [#9314](http://dev.ckeditor.com/ticket/9314): Fixed: Incorrect error message on closing a dialog window without saving changs.\r\n* [#10308](http://dev.ckeditor.com/ticket/10308): [IE10] Fixed: Unspecified error when deleting a row.\r\n* [#10945](http://dev.ckeditor.com/ticket/10945): [Chrome] Fixed: Clicking with a mouse inside the editor does not show the caret.\r\n* [#10912](http://dev.ckeditor.com/ticket/10912): Prevent default action when content of a non-editable link is clicked.\r\n* [#10913](http://dev.ckeditor.com/ticket/10913): Fixed [`CKEDITOR.plugins.addExternal`](http://docs.ckeditor.com/#!/api/CKEDITOR.resourceManager-method-addExternal) not handling paths including file name specified.\r\n* [#10666](http://dev.ckeditor.com/ticket/10666): Fixed [`CKEDITOR.tools.isArray`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-isArray) not working cross frame.\r\n* [#10910](http://dev.ckeditor.com/ticket/10910): [IE9] Fixed JavaScript error thrown in Compatibility Mode when clicking and/or typing in the editing area.\r\n* [#10868](http://dev.ckeditor.com/ticket/10868): [IE8] Prevent the browser from crashing when applying the Inline Quotation style.\r\n* [#10915](http://dev.ckeditor.com/ticket/10915): Fixed: Invalid CSS filter in the Kama skin.\r\n* [#10914](http://dev.ckeditor.com/ticket/10914): Plugins [Indent List](http://ckeditor.com/addon/indentlist) and [Indent Block](http://ckeditor.com/addon/indentblock) are now included in the build configuration.\r\n* [#10812](http://dev.ckeditor.com/ticket/10812): Fixed [`range#createBookmark2`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-createBookmark2) incorrectly normalizing offsets. This bug was causing many issues: [#10850](http://dev.ckeditor.com/ticket/10850), [#10842](http://dev.ckeditor.com/ticket/10842).\r\n* [#10951](http://dev.ckeditor.com/ticket/10951): Reviewed and optimized focus handling on panels (combo, menu buttons, color buttons, and context menu) to enhance accessibility. Fixed [#10705](http://dev.ckeditor.com/ticket/10705), [#10706](http://dev.ckeditor.com/ticket/10706) and [#10707](http://dev.ckeditor.com/ticket/10707).\r\n* [#10704](http://dev.ckeditor.com/ticket/10704): Fixed a JAWS issue with the Select Color dialog window title not being announced.\r\n* [#10753](http://dev.ckeditor.com/ticket/10753): The floating toolbar in inline instances now has a dedicated accessibility label.\r\n\r\n## CKEditor 4.2.1\r\n\r\nFixed Issues:\r\n\r\n* [#10301](http://dev.ckeditor.com/ticket/10301): [IE9-10] Undo fails after 3+ consecutive paste actions with a JavaScript error.\r\n* [#10689](http://dev.ckeditor.com/ticket/10689): Save toolbar button saves only the first editor instance.\r\n* [#10368](http://dev.ckeditor.com/ticket/10368): Move language reading direction definition (`dir`) from main language file to core.\r\n* [#9330](http://dev.ckeditor.com/ticket/9330): Fixed pasting anchors from MS Word.\r\n* [#8103](http://dev.ckeditor.com/ticket/8103): Fixed pasting nested lists from MS Word.\r\n* [#9958](http://dev.ckeditor.com/ticket/9958): [IE9] Pressing the \"OK\" button will trigger the `onbeforeunload` event in the popup dialog.\r\n* [#10662](http://dev.ckeditor.com/ticket/10662): Fixed styles from the Styles drop-down list not registering to the ACF in case when the [Shared Spaces plugin](http://ckeditor.com/addon/sharedspace) is used.\r\n* [#9654](http://dev.ckeditor.com/ticket/9654): Problems with Internet Explorer 10 Quirks Mode.\r\n* [#9816](http://dev.ckeditor.com/ticket/9816): Floating toolbar does not reposition vertically in several cases.\r\n* [#10646](http://dev.ckeditor.com/ticket/10646): Removing a selected sublist or nested table with *Backspace/Delete* removes the parent element.\r\n* [#10623](http://dev.ckeditor.com/ticket/10623): [WebKit] Page is scrolled when opening a drop-down list.\r\n* [#10004](http://dev.ckeditor.com/ticket/10004): [ChromeVox] Button names are not announced.\r\n* [#10731](http://dev.ckeditor.com/ticket/10731): [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin breaks cloning of editor configuration.\r\n* It is now possible to set per instance [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin configuration instead of setting the configuration globally.\r\n\r\n## CKEditor 4.2\r\n\r\n**Important Notes:**\r\n\r\n* Dropped compatibility support for Internet Explorer 7 and Firefox 3.6.\r\n\r\n* Both the Basic and the Standard distribution packages will not contain the new [Indent Block](http://ckeditor.com/addon/indentblock) plugin. Because of this the [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) might remove block indentations from existing contents. If you want to prevent this, either [add an appropriate ACF rule to your filter](http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules) or create a custom build based on the Basic/Standard package and add the Indent Block plugin in [CKBuilder](http://ckeditor.com/builder).\r\n\r\nNew Features:\r\n\r\n* [#10027](http://dev.ckeditor.com/ticket/10027): Separated list and block indentation into two plugins: [Indent List](http://ckeditor.com/addon/indentlist) and [Indent Block](http://ckeditor.com/addon/indentblock).\r\n* [#8244](http://dev.ckeditor.com/ticket/8244): Use *(Shift+)Tab* to indent and outdent lists.\r\n* [#10281](http://dev.ckeditor.com/ticket/10281): The [jQuery Adapter](http://docs.ckeditor.com/#!/guide/dev_jquery) is now available. Several jQuery-related issues fixed: [#8261](http://dev.ckeditor.com/ticket/8261), [#9077](http://dev.ckeditor.com/ticket/9077), [#8710](http://dev.ckeditor.com/ticket/8710), [#8530](http://dev.ckeditor.com/ticket/8530), [#9019](http://dev.ckeditor.com/ticket/9019), [#6181](http://dev.ckeditor.com/ticket/6181), [#7876](http://dev.ckeditor.com/ticket/7876), [#6906](http://dev.ckeditor.com/ticket/6906).\r\n* [#10042](http://dev.ckeditor.com/ticket/10042): Introduced [`config.title`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-title) setting to change the human-readable title of the editor.\r\n* [#9794](http://dev.ckeditor.com/ticket/9794): Added [`editor.onChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-change) event.\r\n* [#9923](http://dev.ckeditor.com/ticket/9923): HiDPI support in the editor UI. HiDPI icons for [Moono skin](http://ckeditor.com/addon/moono) added.\r\n* [#8031](http://dev.ckeditor.com/ticket/8031): Handle `required` attributes on `<textarea>` elements &mdash; introduced [`editor.required`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-required) event.\r\n* [#10280](http://dev.ckeditor.com/ticket/10280): Ability to replace `<textarea>` elements with the inline editor.\r\n\r\nFixed Issues:\r\n\r\n* [#10599](http://dev.ckeditor.com/ticket/10599): [Indent](http://ckeditor.com/addon/indent) plugin is no longer required by the [List](http://ckeditor.com/addon/list) plugin.\r\n* [#10370](http://dev.ckeditor.com/ticket/10370): Inconsistency in data events between framed and inline editors.\r\n* [#10438](http://dev.ckeditor.com/ticket/10438): [FF, IE] No selection is done on an editable element on executing [`editor.setData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setData).\r\n\r\n## CKEditor 4.1.3\r\n\r\nNew Features:\r\n\r\n* Added new translation: Indonesian.\r\n\r\nFixed Issues:\r\n\r\n* [#10644](http://dev.ckeditor.com/ticket/10644): Fixed a critical bug when pasting plain text in Blink-based browsers.\r\n* [#5189](http://dev.ckeditor.com/ticket/5189): [Find/Replace](http://ckeditor.com/addon/find) dialog window: rename \"Cancel\" button to \"Close\".\r\n* [#10562](http://dev.ckeditor.com/ticket/10562): [Housekeeping] Unified CSS gradient filter formats in the [Moono](http://ckeditor.com/addon/moono) skin.\r\n* [#10537](http://dev.ckeditor.com/ticket/10537): Advanced Content Filter should register a default rule for [`config.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-shiftEnterMode).\r\n* [#10610](http://dev.ckeditor.com/ticket/10610): [`CKEDITOR.dialog.addIframe()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dialog-static-method-addIframe) incorrectly sets the iframe size in dialog windows.\r\n\r\n## CKEditor 4.1.2\r\n\r\nNew Features:\r\n\r\n* Added new translation: Sinhala.\r\n\r\nFixed Issues:\r\n\r\n* [#10339](http://dev.ckeditor.com/ticket/10339): Fixed: Error thrown when inserted data was totally stripped out after filtering and processing.\r\n* [#10298](http://dev.ckeditor.com/ticket/10298): Fixed: Data processor breaks attributes containing protected parts.\r\n* [#10367](http://dev.ckeditor.com/ticket/10367): Fixed: [`editable.insertText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertText) loses characters when `RegExp` replace controls are being inserted.\r\n* [#10165](http://dev.ckeditor.com/ticket/10165): [IE] Access denied error when `document.domain` has been altered.\r\n* [#9761](http://dev.ckeditor.com/ticket/9761): Update the *Backspace* key state in [`keystrokeHandler.blockedKeystrokes`](http://docs.ckeditor.com/#!/api/CKEDITOR.keystrokeHandler-property-blockedKeystrokes) when calling [`editor.setReadOnly()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setReadOnly).\r\n* [#6504](http://dev.ckeditor.com/ticket/6504): Fixed: Race condition while loading several [`config.customConfig`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-customConfig) files.\r\n* [#10146](http://dev.ckeditor.com/ticket/10146): [Firefox] Empty lines are being removed while [`config.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) is [`CKEDITOR.ENTER_BR`](http://docs.ckeditor.com/#!/api/CKEDITOR-property-ENTER_BR).\r\n* [#10360](http://dev.ckeditor.com/ticket/10360): Fixed: ARIA `role=\"application\"` should not be used for dialog windows.\r\n* [#10361](http://dev.ckeditor.com/ticket/10361): Fixed: ARIA `role=\"application\"` should not be used for floating panels.\r\n* [#10510](http://dev.ckeditor.com/ticket/10510): Introduced unique voice labels to differentiate between different editor instances.\r\n* [#9945](http://dev.ckeditor.com/ticket/9945): [iOS] Scrolling not possible on iPad.\r\n* [#10389](http://dev.ckeditor.com/ticket/10389): Fixed: Invalid HTML in the \"Text and Table\" template.\r\n* [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin user interface was changed to match CKEditor 4 style.\r\n\r\n## CKEditor 4.1.1\r\n\r\nNew Features:\r\n\r\n* Added new translation: Albanian.\r\n\r\nFixed Issues:\r\n\r\n* [#10172](http://dev.ckeditor.com/ticket/10172): Pressing *Delete* or *Backspace* in an empty table cell moves the cursor to the next/previous cell.\r\n* [#10219](http://dev.ckeditor.com/ticket/10219): Error thrown when destroying an editor instance in parallel with a `mouseup` event.\r\n* [#10265](http://dev.ckeditor.com/ticket/10265): Wrong loop type in the [File Browser](http://ckeditor.com/addon/filebrowser) plugin.\r\n* [#10249](http://dev.ckeditor.com/ticket/10249): Wrong undo/redo states at start.\r\n* [#10268](http://dev.ckeditor.com/ticket/10268): [Show Blocks](http://ckeditor.com/addon/showblocks) does not recover after switching to Source view.\r\n* [#9995](http://dev.ckeditor.com/ticket/9995): HTML code in the `<textarea>` should not be modified by the [`htmlDataProcessor`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlDataProcessor).\r\n* [#10320](http://dev.ckeditor.com/ticket/10320): [Justify](http://ckeditor.com/addon/justify) plugin should add elements to Advanced Content Filter based on current [Enter mode](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode).\r\n* [#10260](http://dev.ckeditor.com/ticket/10260): Fixed: Advanced Content Filter blocks [`tabSpaces`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-tabSpaces). Unified `data-cke-*` attributes filtering.\r\n* [#10315](http://dev.ckeditor.com/ticket/10315): [WebKit] [Undo manager](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.undo.UndoManager) should not record snapshots after a filling character was added/removed.\r\n* [#10291](http://dev.ckeditor.com/ticket/10291): [WebKit] Space after a filling character should be secured.\r\n* [#10330](http://dev.ckeditor.com/ticket/10330): [WebKit] The filling character is not removed on `keydown` in specific cases.\r\n* [#10285](http://dev.ckeditor.com/ticket/10285): Fixed: Styled text pasted from MS Word causes an infinite loop.\r\n* [#10131](http://dev.ckeditor.com/ticket/10131): Fixed: [`undoManager.update()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.undo.UndoManager-method-update) does not refresh the command state.\r\n* [#10337](http://dev.ckeditor.com/ticket/10337): Fixed: Unable to remove `<s>` using [Remove Format](http://ckeditor.com/addon/removeformat).\r\n\r\n## CKEditor 4.1\r\n\r\nFixed Issues:\r\n\r\n* [#10192](http://dev.ckeditor.com/ticket/10192): Closing lists with the *Enter* key does not work with [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) in several cases.\r\n* [#10191](http://dev.ckeditor.com/ticket/10191): Fixed allowed content rules unification, so the [`filter.allowedContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter-property-allowedContent) property always contains rules in the same format.\r\n* [#10224](http://dev.ckeditor.com/ticket/10224): Advanced Content Filter does not remove non-empty `<a>` elements anymore.\r\n* Minor issues in plugin integration with Advanced Content Filter:\r\n  * [#10166](http://dev.ckeditor.com/ticket/10166): Added transformation from the `align` attribute to `float` style to preserve backward compatibility after the introduction of Advanced Content Filter.\r\n  * [#10195](http://dev.ckeditor.com/ticket/10195): [Image](http://ckeditor.com/addon/image) plugin no longer registers rules for links to Advanced Content Filter.\r\n  * [#10213](http://dev.ckeditor.com/ticket/10213): [Justify](http://ckeditor.com/addon/justify) plugin is now correctly registering rules to Advanced Content Filter when [`config.justifyClasses`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-justifyClasses) is defined.\r\n\r\n## CKEditor 4.1 RC\r\n\r\nNew Features:\r\n\r\n* [#9829](http://dev.ckeditor.com/ticket/9829): Advanced Content Filter - data and features activation based on editor configuration.\r\n\r\n  Brand new data filtering system that works in 2 modes:\r\n\r\n  * Based on loaded features (toolbar items, plugins) - the data will be filtered according to what the editor in its\r\n  current configuration can handle.\r\n  * Based on [`config.allowedContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent) rules - the data\r\n  will be filtered and the editor features (toolbar items, commands, keystrokes) will be enabled if they are allowed.\r\n\r\n  See the `datafiltering.html` sample, [guides](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) and [`CKEDITOR.filter` API documentation](http://docs.ckeditor.com/#!/api/CKEDITOR.filter).\r\n* [#9387](http://dev.ckeditor.com/ticket/9387): Reintroduced [Shared Spaces](http://ckeditor.com/addon/sharedspace) - the ability to display toolbar and bottom editor space in selected locations and to share them by different editor instances.\r\n* [#9907](http://dev.ckeditor.com/ticket/9907): Added the [`contentPreview`](http://docs.ckeditor.com/#!/api/CKEDITOR-event-contentPreview) event for preview data manipulation.\r\n* [#9713](http://dev.ckeditor.com/ticket/9713): Introduced the [Source Dialog](http://ckeditor.com/addon/sourcedialog) plugin that brings raw HTML editing for inline editor instances.\r\n* Included in [#9829](http://dev.ckeditor.com/ticket/9829): Introduced new events, [`toHtml`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-toHtml) and [`toDataFormat`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-toDataFormat), allowing for better integration with data processing.\r\n* [#9981](http://dev.ckeditor.com/ticket/9981): Added ability to filter [`htmlParser.fragment`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.fragment), [`htmlParser.element`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.element) etc. by many [`htmlParser.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter)s before writing structure to an HTML string.\r\n* Included in [#10103](http://dev.ckeditor.com/ticket/10103):\r\n  * Introduced the [`editor.status`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-status) property to make it easier to check the current status of the editor.\r\n  * Default [`command`](http://docs.ckeditor.com/#!/api/CKEDITOR.command) state is now [`CKEDITOR.TRISTATE_DISABLE`](http://docs.ckeditor.com/#!/api/CKEDITOR-property-TRISTATE_DISABLED). It will be activated on [`editor.instanceReady`](http://docs.ckeditor.com/#!/api/CKEDITOR-event-instanceReady) or immediately after being added if the editor is already initialized.\r\n* [#9796](http://dev.ckeditor.com/ticket/9796): Introduced `<s>` as a default tag for strikethrough, which replaces obsolete `<strike>` in HTML5.\r\n\r\n## CKEditor 4.0.3\r\n\r\nFixed Issues:\r\n\r\n* [#10196](http://dev.ckeditor.com/ticket/10196): Fixed context menus not opening with keyboard shortcuts when [Autogrow](http://ckeditor.com/addon/autogrow) is enabled.\r\n* [#10212](http://dev.ckeditor.com/ticket/10212): [IE7-10] Undo command throws errors after multiple switches between Source and WYSIWYG view.\r\n* [#10219](http://dev.ckeditor.com/ticket/10219): [Inline editor] Error thrown after calling [`editor.destroy()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-destroy).\r\n\r\n## CKEditor 4.0.2\r\n\r\nFixed Issues:\r\n\r\n* [#9779](http://dev.ckeditor.com/ticket/9779): Fixed overriding [`CKEDITOR.getUrl()`](http://docs.ckeditor.com/#!/api/CKEDITOR-method-getUrl) with `CKEDITOR_GETURL`.\r\n* [#9772](http://dev.ckeditor.com/ticket/9772): Custom buttons in the dialog window footer have different look and size ([Moono](http://ckeditor.com/addon/moono), [Kama](http://ckeditor.com/addon/kama) skins).\r\n* [#9029](http://dev.ckeditor.com/ticket/9029): Custom styles added with the [`stylesSet.add()`](http://docs.ckeditor.com/#!/api/CKEDITOR.stylesSet-method-add) are displayed in the wrong order.\r\n* [#9887](http://dev.ckeditor.com/ticket/9887): Disable [Magic Line](http://ckeditor.com/addon/magicline) when [`editor.readOnly`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) is set.\r\n* [#9882](http://dev.ckeditor.com/ticket/9882): Fixed empty document title on [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) if set via the Document Properties dialog window.\r\n* [#9773](http://dev.ckeditor.com/ticket/9773): Fixed rendering problems with selection fields in the Kama skin.\r\n* [#9851](http://dev.ckeditor.com/ticket/9851): The [`selectionChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-selectionChange) event is not fired when mouse selection ended outside editable.\r\n* [#9903](http://dev.ckeditor.com/ticket/9903): [Inline editor] Bad positioning of floating space with page horizontal scroll.\r\n* [#9872](http://dev.ckeditor.com/ticket/9872): [`editor.checkDirty()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty) returns `true` when called onload. Removed the obsolete `editor.mayBeDirty` flag.\r\n* [#9893](http://dev.ckeditor.com/ticket/9893): [IE] Fixed broken toolbar when editing mixed direction content in Quirks mode.\r\n* [#9845](http://dev.ckeditor.com/ticket/9845): Fixed TAB navigation in the [Link](http://ckeditor.com/addon/link) dialog window when the Anchor option is used and no anchors are available.\r\n* [#9883](http://dev.ckeditor.com/ticket/9883): Maximizing was making the entire page editable with [divarea](http://ckeditor.com/addon/divarea)-based editors.\r\n* [#9940](http://dev.ckeditor.com/ticket/9940): [Firefox] Navigating back to a page with the editor was making the entire page editable.\r\n* [#9966](http://dev.ckeditor.com/ticket/9966): Fixed: Unable to type square brackets with French keyboard layout. Changed [Magic Line](http://ckeditor.com/addon/magicline) keystrokes.\r\n* [#9507](http://dev.ckeditor.com/ticket/9507): [Firefox] Selection is moved before editable position when the editor is focused for the first time.\r\n* [#9947](http://dev.ckeditor.com/ticket/9947): [WebKit] Editor overflows parent container in some edge cases.\r\n* [#10105](http://dev.ckeditor.com/ticket/10105): Fixed: Broken [sourcearea](http://ckeditor.com/addon/sourcearea) view when an RTL language is set.\r\n* [#10123](http://dev.ckeditor.com/ticket/10123): [WebKit] Fixed: Several dialog windows have broken layout since the latest WebKit release.\r\n* [#10152](http://dev.ckeditor.com/ticket/10152): Fixed: Invalid ARIA property used on menu items.\r\n\r\n## CKEditor 4.0.1.1\r\n\r\nFixed Issues:\r\n\r\n* Security update: Added protection against XSS attack and possible path disclosure in the PHP sample.\r\n\r\n## CKEditor 4.0.1\r\n\r\nFixed Issues:\r\n\r\n* [#9655](http://dev.ckeditor.com/ticket/9655): Support for IE Quirks Mode in the new [Moono skin](http://ckeditor.com/addon/moono).\r\n* Accessibility issues (mainly in inline editor): [#9364](http://dev.ckeditor.com/ticket/9364), [#9368](http://dev.ckeditor.com/ticket/9368), [#9369](http://dev.ckeditor.com/ticket/9369), [#9370](http://dev.ckeditor.com/ticket/9370), [#9541](http://dev.ckeditor.com/ticket/9541), [#9543](http://dev.ckeditor.com/ticket/9543), [#9841](http://dev.ckeditor.com/ticket/9841), [#9844](http://dev.ckeditor.com/ticket/9844).\r\n* [Magic Line](http://ckeditor.com/addon/magicline) plugin:\r\n    * [#9481](http://dev.ckeditor.com/ticket/9481): Added accessibility support for Magic Line.\r\n    * [#9509](http://dev.ckeditor.com/ticket/9509): Added Magic Line support for forms.\r\n    * [#9573](http://dev.ckeditor.com/ticket/9573): Magic Line does not disappear on `mouseout` in a specific case.\r\n* [#9754](http://dev.ckeditor.com/ticket/9754): [WebKit] Cutting & pasting simple unformatted text generates an inline wrapper in WebKit browsers.\r\n* [#9456](http://dev.ckeditor.com/ticket/9456): [Chrome] Properly paste bullet list style from MS Word.\r\n* [#9699](http://dev.ckeditor.com/ticket/9699), [#9758](http://dev.ckeditor.com/ticket/9758): Improved selection locking when selecting by dragging.\r\n* Context menu:\r\n    * [#9712](http://dev.ckeditor.com/ticket/9712): Opening the context menu destroys editor focus.\r\n    * [#9366](http://dev.ckeditor.com/ticket/9366): Context menu should be displayed over the floating toolbar.\r\n    * [#9706](http://dev.ckeditor.com/ticket/9706): Context menu generates a JavaScript error in inline mode when the editor is attached to a header element.\r\n* [#9800](http://dev.ckeditor.com/ticket/9800): Hide float panel when resizing the window.\r\n* [#9721](http://dev.ckeditor.com/ticket/9721): Padding in content of div-based editor puts the editing area under the bottom UI space.\r\n* [#9528](http://dev.ckeditor.com/ticket/9528): Host page `box-sizing` style should not influence the editor UI elements.\r\n* [#9503](http://dev.ckeditor.com/ticket/9503): [Form Elements](http://ckeditor.com/addon/forms) plugin adds context menu listeners only on supported input types. Added support for `tel`, `email`, `search` and `url` input types.\r\n* [#9769](http://dev.ckeditor.com/ticket/9769): Improved floating toolbar positioning in a narrow window.\r\n* [#9875](http://dev.ckeditor.com/ticket/9875): Table dialog window does not populate width correctly.\r\n* [#8675](http://dev.ckeditor.com/ticket/8675): Deleting cells in a nested table removes the outer table cell.\r\n* [#9815](http://dev.ckeditor.com/ticket/9815): Cannot edit dialog window fields in an editor initialized in the jQuery UI modal dialog.\r\n* [#8888](http://dev.ckeditor.com/ticket/8888): CKEditor dialog windows do not show completely in a small window.\r\n* [#9360](http://dev.ckeditor.com/ticket/9360): [Inline editor] Blocks shown for a `<div>` element stay permanently even after the user exits editing the `<div>`.\r\n* [#9531](http://dev.ckeditor.com/ticket/9531): [Firefox & Inline editor] Toolbar is lost when closing the Format drop-down list by clicking its button.\r\n* [#9553](http://dev.ckeditor.com/ticket/9553): Table width incorrectly set when the `border-width` style is specified.\r\n* [#9594](http://dev.ckeditor.com/ticket/9594): Cannot tab past CKEditor when it is in read-only mode.\r\n* [#9658](http://dev.ckeditor.com/ticket/9658): [IE9] Justify not working on selected images.\r\n* [#9686](http://dev.ckeditor.com/ticket/9686): Added missing contents styles for `<pre>` elements.\r\n* [#9709](http://dev.ckeditor.com/ticket/9709): [Paste from Word](http://ckeditor.com/addon/pastefromword) should not depend on configuration from other styles.\r\n* [#9726](http://dev.ckeditor.com/ticket/9726): Removed [Color Dialog](http://ckeditor.com/addon/colordialog) plugin dependency from [Table Tools](http://ckeditor.com/addon/tabletools).\r\n* [#9765](http://dev.ckeditor.com/ticket/9765): Toolbar Collapse command documented incorrectly in the [Accessibility Instructions](http://ckeditor.com/addon/a11yhelp) dialog window.\r\n* [#9771](http://dev.ckeditor.com/ticket/9771): [WebKit & Opera] Fixed scrolling issues when pasting.\r\n* [#9787](http://dev.ckeditor.com/ticket/9787): [IE9] `onChange` is not fired for checkboxes in dialogs.\r\n* [#9842](http://dev.ckeditor.com/ticket/9842): [Firefox 17] When opening a toolbar menu for the first time and pressing the *Down Arrow* key, focus goes to the next toolbar button instead of the menu options.\r\n* [#9847](http://dev.ckeditor.com/ticket/9847): [Elements Path](http://ckeditor.com/addon/elementspath) should not be initialized in the inline editor.\r\n* [#9853](http://dev.ckeditor.com/ticket/9853): [`editor.addRemoveFormatFilter()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-addRemoveFormatFilter) is exposed before it really works.\r\n* [#8893](http://dev.ckeditor.com/ticket/8893): Value of the [`pasteFromWordCleanupFile`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordCleanupFile) configuration option is now taken from the instance configuration.\r\n* [#9693](http://dev.ckeditor.com/ticket/9693): Removed \"Live Preview\" checkbox from UI color picker.\r\n\r\n\r\n## CKEditor 4.0\r\n\r\nThe first stable release of the new CKEditor 4 code line.\r\n\r\nThe CKEditor JavaScript API has been kept compatible with CKEditor 4, whenever\r\npossible. The list of relevant changes can be found in the [API Changes page of\r\nthe CKEditor 4 documentation][1].\r\n\r\n[1]: http://docs.ckeditor.com/#!/guide/dev_api_changes \"API Changes\"\r\n"
  },
  {
    "path": "public/static/plugins/ckeditor/LICENSE.md",
    "content": "Software License Agreement\r\n==========================\r\n\r\nCKEditor - The text editor for Internet - http://ckeditor.com\r\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\r\n\r\nLicensed under the terms of any of the following licenses at your\r\nchoice:\r\n\r\n - GNU General Public License Version 2 or later (the \"GPL\")\r\n   http://www.gnu.org/licenses/gpl.html\r\n   (See Appendix A)\r\n\r\n - GNU Lesser General Public License Version 2.1 or later (the \"LGPL\")\r\n   http://www.gnu.org/licenses/lgpl.html\r\n   (See Appendix B)\r\n\r\n - Mozilla Public License Version 1.1 or later (the \"MPL\")\r\n   http://www.mozilla.org/MPL/MPL-1.1.html\r\n   (See Appendix C)\r\n\r\nYou are not required to, but if you want to explicitly declare the\r\nlicense you have chosen to be bound to when using, reproducing,\r\nmodifying and distributing this software, just include a text file\r\ntitled \"legal.txt\" in your version of this software, indicating your\r\nlicense choice. In any case, your choice will not restrict any\r\nrecipient of your version of this software to use, reproduce, modify\r\nand distribute this software under any of the above licenses.\r\n\r\nSources of Intellectual Property Included in CKEditor\r\n-----------------------------------------------------\r\n\r\nWhere not otherwise indicated, all CKEditor content is authored by\r\nCKSource engineers and consists of CKSource-owned intellectual\r\nproperty. In some specific instances, CKEditor will incorporate work\r\ndone by developers outside of CKSource with their express permission.\r\n\r\nTrademarks\r\n----------\r\n\r\nCKEditor is a trademark of CKSource - Frederico Knabben. All other brand\r\nand product names are trademarks, registered trademarks or service\r\nmarks of their respective holders.\r\n\r\n---\r\n\r\nAppendix A: The GPL License\r\n---------------------------\r\n\r\nGNU GENERAL PUBLIC LICENSE\r\nVersion 2, June 1991\r\n\r\n Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\r\n 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\r\n Everyone is permitted to copy and distribute verbatim copies\r\n of this license document, but changing it is not allowed.\r\n\r\nPreamble\r\n\r\n  The licenses for most software are designed to take away your\r\nfreedom to share and change it.  By contrast, the GNU General Public\r\nLicense is intended to guarantee your freedom to share and change free\r\nsoftware-to make sure the software is free for all its users.  This\r\nGeneral Public License applies to most of the Free Software\r\nFoundation's software and to any other program whose authors commit to\r\nusing it.  (Some other Free Software Foundation software is covered by\r\nthe GNU Lesser General Public License instead.)  You can apply it to\r\nyour programs, too.\r\n\r\n  When we speak of free software, we are referring to freedom, not\r\nprice.  Our General Public Licenses are designed to make sure that you\r\nhave the freedom to distribute copies of free software (and charge for\r\nthis service if you wish), that you receive source code or can get it\r\nif you want it, that you can change the software or use pieces of it\r\nin new free programs; and that you know you can do these things.\r\n\r\n  To protect your rights, we need to make restrictions that forbid\r\nanyone to deny you these rights or to ask you to surrender the rights.\r\nThese restrictions translate to certain responsibilities for you if you\r\ndistribute copies of the software, or if you modify it.\r\n\r\n  For example, if you distribute copies of such a program, whether\r\ngratis or for a fee, you must give the recipients all the rights that\r\nyou have.  You must make sure that they, too, receive or can get the\r\nsource code.  And you must show them these terms so they know their\r\nrights.\r\n\r\n  We protect your rights with two steps: (1) copyright the software, and\r\n(2) offer you this license which gives you legal permission to copy,\r\ndistribute and/or modify the software.\r\n\r\n  Also, for each author's protection and ours, we want to make certain\r\nthat everyone understands that there is no warranty for this free\r\nsoftware.  If the software is modified by someone else and passed on, we\r\nwant its recipients to know that what they have is not the original, so\r\nthat any problems introduced by others will not reflect on the original\r\nauthors' reputations.\r\n\r\n  Finally, any free program is threatened constantly by software\r\npatents.  We wish to avoid the danger that redistributors of a free\r\nprogram will individually obtain patent licenses, in effect making the\r\nprogram proprietary.  To prevent this, we have made it clear that any\r\npatent must be licensed for everyone's free use or not licensed at all.\r\n\r\n  The precise terms and conditions for copying, distribution and\r\nmodification follow.\r\n\r\nGNU GENERAL PUBLIC LICENSE\r\nTERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\r\n\r\n  0. This License applies to any program or other work which contains\r\na notice placed by the copyright holder saying it may be distributed\r\nunder the terms of this General Public License.  The \"Program\", below,\r\nrefers to any such program or work, and a \"work based on the Program\"\r\nmeans either the Program or any derivative work under copyright law:\r\nthat is to say, a work containing the Program or a portion of it,\r\neither verbatim or with modifications and/or translated into another\r\nlanguage.  (Hereinafter, translation is included without limitation in\r\nthe term \"modification\".)  Each licensee is addressed as \"you\".\r\n\r\nActivities other than copying, distribution and modification are not\r\ncovered by this License; they are outside its scope.  The act of\r\nrunning the Program is not restricted, and the output from the Program\r\nis covered only if its contents constitute a work based on the\r\nProgram (independent of having been made by running the Program).\r\nWhether that is true depends on what the Program does.\r\n\r\n  1. You may copy and distribute verbatim copies of the Program's\r\nsource code as you receive it, in any medium, provided that you\r\nconspicuously and appropriately publish on each copy an appropriate\r\ncopyright notice and disclaimer of warranty; keep intact all the\r\nnotices that refer to this License and to the absence of any warranty;\r\nand give any other recipients of the Program a copy of this License\r\nalong with the Program.\r\n\r\nYou may charge a fee for the physical act of transferring a copy, and\r\nyou may at your option offer warranty protection in exchange for a fee.\r\n\r\n  2. You may modify your copy or copies of the Program or any portion\r\nof it, thus forming a work based on the Program, and copy and\r\ndistribute such modifications or work under the terms of Section 1\r\nabove, provided that you also meet all of these conditions:\r\n\r\n    a) You must cause the modified files to carry prominent notices\r\n    stating that you changed the files and the date of any change.\r\n\r\n    b) You must cause any work that you distribute or publish, that in\r\n    whole or in part contains or is derived from the Program or any\r\n    part thereof, to be licensed as a whole at no charge to all third\r\n    parties under the terms of this License.\r\n\r\n    c) If the modified program normally reads commands interactively\r\n    when run, you must cause it, when started running for such\r\n    interactive use in the most ordinary way, to print or display an\r\n    announcement including an appropriate copyright notice and a\r\n    notice that there is no warranty (or else, saying that you provide\r\n    a warranty) and that users may redistribute the program under\r\n    these conditions, and telling the user how to view a copy of this\r\n    License.  (Exception: if the Program itself is interactive but\r\n    does not normally print such an announcement, your work based on\r\n    the Program is not required to print an announcement.)\r\n\r\nThese requirements apply to the modified work as a whole.  If\r\nidentifiable sections of that work are not derived from the Program,\r\nand can be reasonably considered independent and separate works in\r\nthemselves, then this License, and its terms, do not apply to those\r\nsections when you distribute them as separate works.  But when you\r\ndistribute the same sections as part of a whole which is a work based\r\non the Program, the distribution of the whole must be on the terms of\r\nthis License, whose permissions for other licensees extend to the\r\nentire whole, and thus to each and every part regardless of who wrote it.\r\n\r\nThus, it is not the intent of this section to claim rights or contest\r\nyour rights to work written entirely by you; rather, the intent is to\r\nexercise the right to control the distribution of derivative or\r\ncollective works based on the Program.\r\n\r\nIn addition, mere aggregation of another work not based on the Program\r\nwith the Program (or with a work based on the Program) on a volume of\r\na storage or distribution medium does not bring the other work under\r\nthe scope of this License.\r\n\r\n  3. You may copy and distribute the Program (or a work based on it,\r\nunder Section 2) in object code or executable form under the terms of\r\nSections 1 and 2 above provided that you also do one of the following:\r\n\r\n    a) Accompany it with the complete corresponding machine-readable\r\n    source code, which must be distributed under the terms of Sections\r\n    1 and 2 above on a medium customarily used for software interchange; or,\r\n\r\n    b) Accompany it with a written offer, valid for at least three\r\n    years, to give any third party, for a charge no more than your\r\n    cost of physically performing source distribution, a complete\r\n    machine-readable copy of the corresponding source code, to be\r\n    distributed under the terms of Sections 1 and 2 above on a medium\r\n    customarily used for software interchange; or,\r\n\r\n    c) Accompany it with the information you received as to the offer\r\n    to distribute corresponding source code.  (This alternative is\r\n    allowed only for noncommercial distribution and only if you\r\n    received the program in object code or executable form with such\r\n    an offer, in accord with Subsection b above.)\r\n\r\nThe source code for a work means the preferred form of the work for\r\nmaking modifications to it.  For an executable work, complete source\r\ncode means all the source code for all modules it contains, plus any\r\nassociated interface definition files, plus the scripts used to\r\ncontrol compilation and installation of the executable.  However, as a\r\nspecial exception, the source code distributed need not include\r\nanything that is normally distributed (in either source or binary\r\nform) with the major components (compiler, kernel, and so on) of the\r\noperating system on which the executable runs, unless that component\r\nitself accompanies the executable.\r\n\r\nIf distribution of executable or object code is made by offering\r\naccess to copy from a designated place, then offering equivalent\r\naccess to copy the source code from the same place counts as\r\ndistribution of the source code, even though third parties are not\r\ncompelled to copy the source along with the object code.\r\n\r\n  4. You may not copy, modify, sublicense, or distribute the Program\r\nexcept as expressly provided under this License.  Any attempt\r\notherwise to copy, modify, sublicense or distribute the Program is\r\nvoid, and will automatically terminate your rights under this License.\r\nHowever, parties who have received copies, or rights, from you under\r\nthis License will not have their licenses terminated so long as such\r\nparties remain in full compliance.\r\n\r\n  5. You are not required to accept this License, since you have not\r\nsigned it.  However, nothing else grants you permission to modify or\r\ndistribute the Program or its derivative works.  These actions are\r\nprohibited by law if you do not accept this License.  Therefore, by\r\nmodifying or distributing the Program (or any work based on the\r\nProgram), you indicate your acceptance of this License to do so, and\r\nall its terms and conditions for copying, distributing or modifying\r\nthe Program or works based on it.\r\n\r\n  6. Each time you redistribute the Program (or any work based on the\r\nProgram), the recipient automatically receives a license from the\r\noriginal licensor to copy, distribute or modify the Program subject to\r\nthese terms and conditions.  You may not impose any further\r\nrestrictions on the recipients' exercise of the rights granted herein.\r\nYou are not responsible for enforcing compliance by third parties to\r\nthis License.\r\n\r\n  7. If, as a consequence of a court judgment or allegation of patent\r\ninfringement or for any other reason (not limited to patent issues),\r\nconditions are imposed on you (whether by court order, agreement or\r\notherwise) that contradict the conditions of this License, they do not\r\nexcuse you from the conditions of this License.  If you cannot\r\ndistribute so as to satisfy simultaneously your obligations under this\r\nLicense and any other pertinent obligations, then as a consequence you\r\nmay not distribute the Program at all.  For example, if a patent\r\nlicense would not permit royalty-free redistribution of the Program by\r\nall those who receive copies directly or indirectly through you, then\r\nthe only way you could satisfy both it and this License would be to\r\nrefrain entirely from distribution of the Program.\r\n\r\nIf any portion of this section is held invalid or unenforceable under\r\nany particular circumstance, the balance of the section is intended to\r\napply and the section as a whole is intended to apply in other\r\ncircumstances.\r\n\r\nIt is not the purpose of this section to induce you to infringe any\r\npatents or other property right claims or to contest validity of any\r\nsuch claims; this section has the sole purpose of protecting the\r\nintegrity of the free software distribution system, which is\r\nimplemented by public license practices.  Many people have made\r\ngenerous contributions to the wide range of software distributed\r\nthrough that system in reliance on consistent application of that\r\nsystem; it is up to the author/donor to decide if he or she is willing\r\nto distribute software through any other system and a licensee cannot\r\nimpose that choice.\r\n\r\nThis section is intended to make thoroughly clear what is believed to\r\nbe a consequence of the rest of this License.\r\n\r\n  8. If the distribution and/or use of the Program is restricted in\r\ncertain countries either by patents or by copyrighted interfaces, the\r\noriginal copyright holder who places the Program under this License\r\nmay add an explicit geographical distribution limitation excluding\r\nthose countries, so that distribution is permitted only in or among\r\ncountries not thus excluded.  In such case, this License incorporates\r\nthe limitation as if written in the body of this License.\r\n\r\n  9. The Free Software Foundation may publish revised and/or new versions\r\nof the General Public License from time to time.  Such new versions will\r\nbe similar in spirit to the present version, but may differ in detail to\r\naddress new problems or concerns.\r\n\r\nEach version is given a distinguishing version number.  If the Program\r\nspecifies a version number of this License which applies to it and \"any\r\nlater version\", you have the option of following the terms and conditions\r\neither of that version or of any later version published by the Free\r\nSoftware Foundation.  If the Program does not specify a version number of\r\nthis License, you may choose any version ever published by the Free Software\r\nFoundation.\r\n\r\n  10. If you wish to incorporate parts of the Program into other free\r\nprograms whose distribution conditions are different, write to the author\r\nto ask for permission.  For software which is copyrighted by the Free\r\nSoftware Foundation, write to the Free Software Foundation; we sometimes\r\nmake exceptions for this.  Our decision will be guided by the two goals\r\nof preserving the free status of all derivatives of our free software and\r\nof promoting the sharing and reuse of software generally.\r\n\r\nNO WARRANTY\r\n\r\n  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\r\nFOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\r\nOTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\r\nPROVIDE THE PROGRAM \"AS IS\" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\r\nOR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r\nMERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\r\nTO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\r\nPROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\r\nREPAIR OR CORRECTION.\r\n\r\n  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\r\nWILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\r\nREDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\r\nINCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\r\nOUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\r\nTO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\r\nYOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\r\nPROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\r\nPOSSIBILITY OF SUCH DAMAGES.\r\n\r\nEND OF TERMS AND CONDITIONS\r\n\r\n\r\nAppendix B: The LGPL License\r\n----------------------------\r\n\r\nGNU LESSER GENERAL PUBLIC LICENSE\r\nVersion 2.1, February 1999\r\n\r\n Copyright (C) 1991, 1999 Free Software Foundation, Inc.\r\n     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r\n Everyone is permitted to copy and distribute verbatim copies\r\n of this license document, but changing it is not allowed.\r\n\r\n[This is the first released version of the Lesser GPL.  It also counts\r\n as the successor of the GNU Library Public License, version 2, hence\r\n the version number 2.1.]\r\n\r\nPreamble\r\n\r\n  The licenses for most software are designed to take away your\r\nfreedom to share and change it.  By contrast, the GNU General Public\r\nLicenses are intended to guarantee your freedom to share and change\r\nfree software-to make sure the software is free for all its users.\r\n\r\n  This license, the Lesser General Public License, applies to some\r\nspecially designated software packages-typically libraries-of the\r\nFree Software Foundation and other authors who decide to use it.  You\r\ncan use it too, but we suggest you first think carefully about whether\r\nthis license or the ordinary General Public License is the better\r\nstrategy to use in any particular case, based on the explanations below.\r\n\r\n  When we speak of free software, we are referring to freedom of use,\r\nnot price.  Our General Public Licenses are designed to make sure that\r\nyou have the freedom to distribute copies of free software (and charge\r\nfor this service if you wish); that you receive source code or can get\r\nit if you want it; that you can change the software and use pieces of\r\nit in new free programs; and that you are informed that you can do\r\nthese things.\r\n\r\n  To protect your rights, we need to make restrictions that forbid\r\ndistributors to deny you these rights or to ask you to surrender these\r\nrights.  These restrictions translate to certain responsibilities for\r\nyou if you distribute copies of the library or if you modify it.\r\n\r\n  For example, if you distribute copies of the library, whether gratis\r\nor for a fee, you must give the recipients all the rights that we gave\r\nyou.  You must make sure that they, too, receive or can get the source\r\ncode.  If you link other code with the library, you must provide\r\ncomplete object files to the recipients, so that they can relink them\r\nwith the library after making changes to the library and recompiling\r\nit.  And you must show them these terms so they know their rights.\r\n\r\n  We protect your rights with a two-step method: (1) we copyright the\r\nlibrary, and (2) we offer you this license, which gives you legal\r\npermission to copy, distribute and/or modify the library.\r\n\r\n  To protect each distributor, we want to make it very clear that\r\nthere is no warranty for the free library.  Also, if the library is\r\nmodified by someone else and passed on, the recipients should know\r\nthat what they have is not the original version, so that the original\r\nauthor's reputation will not be affected by problems that might be\r\nintroduced by others.\r\n\r\n  Finally, software patents pose a constant threat to the existence of\r\nany free program.  We wish to make sure that a company cannot\r\neffectively restrict the users of a free program by obtaining a\r\nrestrictive license from a patent holder.  Therefore, we insist that\r\nany patent license obtained for a version of the library must be\r\nconsistent with the full freedom of use specified in this license.\r\n\r\n  Most GNU software, including some libraries, is covered by the\r\nordinary GNU General Public License.  This license, the GNU Lesser\r\nGeneral Public License, applies to certain designated libraries, and\r\nis quite different from the ordinary General Public License.  We use\r\nthis license for certain libraries in order to permit linking those\r\nlibraries into non-free programs.\r\n\r\n  When a program is linked with a library, whether statically or using\r\na shared library, the combination of the two is legally speaking a\r\ncombined work, a derivative of the original library.  The ordinary\r\nGeneral Public License therefore permits such linking only if the\r\nentire combination fits its criteria of freedom.  The Lesser General\r\nPublic License permits more lax criteria for linking other code with\r\nthe library.\r\n\r\n  We call this license the \"Lesser\" General Public License because it\r\ndoes Less to protect the user's freedom than the ordinary General\r\nPublic License.  It also provides other free software developers Less\r\nof an advantage over competing non-free programs.  These disadvantages\r\nare the reason we use the ordinary General Public License for many\r\nlibraries.  However, the Lesser license provides advantages in certain\r\nspecial circumstances.\r\n\r\n  For example, on rare occasions, there may be a special need to\r\nencourage the widest possible use of a certain library, so that it becomes\r\na de-facto standard.  To achieve this, non-free programs must be\r\nallowed to use the library.  A more frequent case is that a free\r\nlibrary does the same job as widely used non-free libraries.  In this\r\ncase, there is little to gain by limiting the free library to free\r\nsoftware only, so we use the Lesser General Public License.\r\n\r\n  In other cases, permission to use a particular library in non-free\r\nprograms enables a greater number of people to use a large body of\r\nfree software.  For example, permission to use the GNU C Library in\r\nnon-free programs enables many more people to use the whole GNU\r\noperating system, as well as its variant, the GNU/Linux operating\r\nsystem.\r\n\r\n  Although the Lesser General Public License is Less protective of the\r\nusers' freedom, it does ensure that the user of a program that is\r\nlinked with the Library has the freedom and the wherewithal to run\r\nthat program using a modified version of the Library.\r\n\r\n  The precise terms and conditions for copying, distribution and\r\nmodification follow.  Pay close attention to the difference between a\r\n\"work based on the library\" and a \"work that uses the library\".  The\r\nformer contains code derived from the library, whereas the latter must\r\nbe combined with the library in order to run.\r\n\r\nGNU LESSER GENERAL PUBLIC LICENSE\r\nTERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\r\n\r\n  0. This License Agreement applies to any software library or other\r\nprogram which contains a notice placed by the copyright holder or\r\nother authorized party saying it may be distributed under the terms of\r\nthis Lesser General Public License (also called \"this License\").\r\nEach licensee is addressed as \"you\".\r\n\r\n  A \"library\" means a collection of software functions and/or data\r\nprepared so as to be conveniently linked with application programs\r\n(which use some of those functions and data) to form executables.\r\n\r\n  The \"Library\", below, refers to any such software library or work\r\nwhich has been distributed under these terms.  A \"work based on the\r\nLibrary\" means either the Library or any derivative work under\r\ncopyright law: that is to say, a work containing the Library or a\r\nportion of it, either verbatim or with modifications and/or translated\r\nstraightforwardly into another language.  (Hereinafter, translation is\r\nincluded without limitation in the term \"modification\".)\r\n\r\n  \"Source code\" for a work means the preferred form of the work for\r\nmaking modifications to it.  For a library, complete source code means\r\nall the source code for all modules it contains, plus any associated\r\ninterface definition files, plus the scripts used to control compilation\r\nand installation of the library.\r\n\r\n  Activities other than copying, distribution and modification are not\r\ncovered by this License; they are outside its scope.  The act of\r\nrunning a program using the Library is not restricted, and output from\r\nsuch a program is covered only if its contents constitute a work based\r\non the Library (independent of the use of the Library in a tool for\r\nwriting it).  Whether that is true depends on what the Library does\r\nand what the program that uses the Library does.\r\n\r\n  1. You may copy and distribute verbatim copies of the Library's\r\ncomplete source code as you receive it, in any medium, provided that\r\nyou conspicuously and appropriately publish on each copy an\r\nappropriate copyright notice and disclaimer of warranty; keep intact\r\nall the notices that refer to this License and to the absence of any\r\nwarranty; and distribute a copy of this License along with the\r\nLibrary.\r\n\r\n  You may charge a fee for the physical act of transferring a copy,\r\nand you may at your option offer warranty protection in exchange for a\r\nfee.\r\n\r\n  2. You may modify your copy or copies of the Library or any portion\r\nof it, thus forming a work based on the Library, and copy and\r\ndistribute such modifications or work under the terms of Section 1\r\nabove, provided that you also meet all of these conditions:\r\n\r\n    a) The modified work must itself be a software library.\r\n\r\n    b) You must cause the files modified to carry prominent notices\r\n    stating that you changed the files and the date of any change.\r\n\r\n    c) You must cause the whole of the work to be licensed at no\r\n    charge to all third parties under the terms of this License.\r\n\r\n    d) If a facility in the modified Library refers to a function or a\r\n    table of data to be supplied by an application program that uses\r\n    the facility, other than as an argument passed when the facility\r\n    is invoked, then you must make a good faith effort to ensure that,\r\n    in the event an application does not supply such function or\r\n    table, the facility still operates, and performs whatever part of\r\n    its purpose remains meaningful.\r\n\r\n    (For example, a function in a library to compute square roots has\r\n    a purpose that is entirely well-defined independent of the\r\n    application.  Therefore, Subsection 2d requires that any\r\n    application-supplied function or table used by this function must\r\n    be optional: if the application does not supply it, the square\r\n    root function must still compute square roots.)\r\n\r\nThese requirements apply to the modified work as a whole.  If\r\nidentifiable sections of that work are not derived from the Library,\r\nand can be reasonably considered independent and separate works in\r\nthemselves, then this License, and its terms, do not apply to those\r\nsections when you distribute them as separate works.  But when you\r\ndistribute the same sections as part of a whole which is a work based\r\non the Library, the distribution of the whole must be on the terms of\r\nthis License, whose permissions for other licensees extend to the\r\nentire whole, and thus to each and every part regardless of who wrote\r\nit.\r\n\r\nThus, it is not the intent of this section to claim rights or contest\r\nyour rights to work written entirely by you; rather, the intent is to\r\nexercise the right to control the distribution of derivative or\r\ncollective works based on the Library.\r\n\r\nIn addition, mere aggregation of another work not based on the Library\r\nwith the Library (or with a work based on the Library) on a volume of\r\na storage or distribution medium does not bring the other work under\r\nthe scope of this License.\r\n\r\n  3. You may opt to apply the terms of the ordinary GNU General Public\r\nLicense instead of this License to a given copy of the Library.  To do\r\nthis, you must alter all the notices that refer to this License, so\r\nthat they refer to the ordinary GNU General Public License, version 2,\r\ninstead of to this License.  (If a newer version than version 2 of the\r\nordinary GNU General Public License has appeared, then you can specify\r\nthat version instead if you wish.)  Do not make any other change in\r\nthese notices.\r\n\r\n  Once this change is made in a given copy, it is irreversible for\r\nthat copy, so the ordinary GNU General Public License applies to all\r\nsubsequent copies and derivative works made from that copy.\r\n\r\n  This option is useful when you wish to copy part of the code of\r\nthe Library into a program that is not a library.\r\n\r\n  4. You may copy and distribute the Library (or a portion or\r\nderivative of it, under Section 2) in object code or executable form\r\nunder the terms of Sections 1 and 2 above provided that you accompany\r\nit with the complete corresponding machine-readable source code, which\r\nmust be distributed under the terms of Sections 1 and 2 above on a\r\nmedium customarily used for software interchange.\r\n\r\n  If distribution of object code is made by offering access to copy\r\nfrom a designated place, then offering equivalent access to copy the\r\nsource code from the same place satisfies the requirement to\r\ndistribute the source code, even though third parties are not\r\ncompelled to copy the source along with the object code.\r\n\r\n  5. A program that contains no derivative of any portion of the\r\nLibrary, but is designed to work with the Library by being compiled or\r\nlinked with it, is called a \"work that uses the Library\".  Such a\r\nwork, in isolation, is not a derivative work of the Library, and\r\ntherefore falls outside the scope of this License.\r\n\r\n  However, linking a \"work that uses the Library\" with the Library\r\ncreates an executable that is a derivative of the Library (because it\r\ncontains portions of the Library), rather than a \"work that uses the\r\nlibrary\".  The executable is therefore covered by this License.\r\nSection 6 states terms for distribution of such executables.\r\n\r\n  When a \"work that uses the Library\" uses material from a header file\r\nthat is part of the Library, the object code for the work may be a\r\nderivative work of the Library even though the source code is not.\r\nWhether this is true is especially significant if the work can be\r\nlinked without the Library, or if the work is itself a library.  The\r\nthreshold for this to be true is not precisely defined by law.\r\n\r\n  If such an object file uses only numerical parameters, data\r\nstructure layouts and accessors, and small macros and small inline\r\nfunctions (ten lines or less in length), then the use of the object\r\nfile is unrestricted, regardless of whether it is legally a derivative\r\nwork.  (Executables containing this object code plus portions of the\r\nLibrary will still fall under Section 6.)\r\n\r\n  Otherwise, if the work is a derivative of the Library, you may\r\ndistribute the object code for the work under the terms of Section 6.\r\nAny executables containing that work also fall under Section 6,\r\nwhether or not they are linked directly with the Library itself.\r\n\r\n  6. As an exception to the Sections above, you may also combine or\r\nlink a \"work that uses the Library\" with the Library to produce a\r\nwork containing portions of the Library, and distribute that work\r\nunder terms of your choice, provided that the terms permit\r\nmodification of the work for the customer's own use and reverse\r\nengineering for debugging such modifications.\r\n\r\n  You must give prominent notice with each copy of the work that the\r\nLibrary is used in it and that the Library and its use are covered by\r\nthis License.  You must supply a copy of this License.  If the work\r\nduring execution displays copyright notices, you must include the\r\ncopyright notice for the Library among them, as well as a reference\r\ndirecting the user to the copy of this License.  Also, you must do one\r\nof these things:\r\n\r\n    a) Accompany the work with the complete corresponding\r\n    machine-readable source code for the Library including whatever\r\n    changes were used in the work (which must be distributed under\r\n    Sections 1 and 2 above); and, if the work is an executable linked\r\n    with the Library, with the complete machine-readable \"work that\r\n    uses the Library\", as object code and/or source code, so that the\r\n    user can modify the Library and then relink to produce a modified\r\n    executable containing the modified Library.  (It is understood\r\n    that the user who changes the contents of definitions files in the\r\n    Library will not necessarily be able to recompile the application\r\n    to use the modified definitions.)\r\n\r\n    b) Use a suitable shared library mechanism for linking with the\r\n    Library.  A suitable mechanism is one that (1) uses at run time a\r\n    copy of the library already present on the user's computer system,\r\n    rather than copying library functions into the executable, and (2)\r\n    will operate properly with a modified version of the library, if\r\n    the user installs one, as long as the modified version is\r\n    interface-compatible with the version that the work was made with.\r\n\r\n    c) Accompany the work with a written offer, valid for at\r\n    least three years, to give the same user the materials\r\n    specified in Subsection 6a, above, for a charge no more\r\n    than the cost of performing this distribution.\r\n\r\n    d) If distribution of the work is made by offering access to copy\r\n    from a designated place, offer equivalent access to copy the above\r\n    specified materials from the same place.\r\n\r\n    e) Verify that the user has already received a copy of these\r\n    materials or that you have already sent this user a copy.\r\n\r\n  For an executable, the required form of the \"work that uses the\r\nLibrary\" must include any data and utility programs needed for\r\nreproducing the executable from it.  However, as a special exception,\r\nthe materials to be distributed need not include anything that is\r\nnormally distributed (in either source or binary form) with the major\r\ncomponents (compiler, kernel, and so on) of the operating system on\r\nwhich the executable runs, unless that component itself accompanies\r\nthe executable.\r\n\r\n  It may happen that this requirement contradicts the license\r\nrestrictions of other proprietary libraries that do not normally\r\naccompany the operating system.  Such a contradiction means you cannot\r\nuse both them and the Library together in an executable that you\r\ndistribute.\r\n\r\n  7. You may place library facilities that are a work based on the\r\nLibrary side-by-side in a single library together with other library\r\nfacilities not covered by this License, and distribute such a combined\r\nlibrary, provided that the separate distribution of the work based on\r\nthe Library and of the other library facilities is otherwise\r\npermitted, and provided that you do these two things:\r\n\r\n    a) Accompany the combined library with a copy of the same work\r\n    based on the Library, uncombined with any other library\r\n    facilities.  This must be distributed under the terms of the\r\n    Sections above.\r\n\r\n    b) Give prominent notice with the combined library of the fact\r\n    that part of it is a work based on the Library, and explaining\r\n    where to find the accompanying uncombined form of the same work.\r\n\r\n  8. You may not copy, modify, sublicense, link with, or distribute\r\nthe Library except as expressly provided under this License.  Any\r\nattempt otherwise to copy, modify, sublicense, link with, or\r\ndistribute the Library is void, and will automatically terminate your\r\nrights under this License.  However, parties who have received copies,\r\nor rights, from you under this License will not have their licenses\r\nterminated so long as such parties remain in full compliance.\r\n\r\n  9. You are not required to accept this License, since you have not\r\nsigned it.  However, nothing else grants you permission to modify or\r\ndistribute the Library or its derivative works.  These actions are\r\nprohibited by law if you do not accept this License.  Therefore, by\r\nmodifying or distributing the Library (or any work based on the\r\nLibrary), you indicate your acceptance of this License to do so, and\r\nall its terms and conditions for copying, distributing or modifying\r\nthe Library or works based on it.\r\n\r\n  10. Each time you redistribute the Library (or any work based on the\r\nLibrary), the recipient automatically receives a license from the\r\noriginal licensor to copy, distribute, link with or modify the Library\r\nsubject to these terms and conditions.  You may not impose any further\r\nrestrictions on the recipients' exercise of the rights granted herein.\r\nYou are not responsible for enforcing compliance by third parties with\r\nthis License.\r\n\r\n  11. If, as a consequence of a court judgment or allegation of patent\r\ninfringement or for any other reason (not limited to patent issues),\r\nconditions are imposed on you (whether by court order, agreement or\r\notherwise) that contradict the conditions of this License, they do not\r\nexcuse you from the conditions of this License.  If you cannot\r\ndistribute so as to satisfy simultaneously your obligations under this\r\nLicense and any other pertinent obligations, then as a consequence you\r\nmay not distribute the Library at all.  For example, if a patent\r\nlicense would not permit royalty-free redistribution of the Library by\r\nall those who receive copies directly or indirectly through you, then\r\nthe only way you could satisfy both it and this License would be to\r\nrefrain entirely from distribution of the Library.\r\n\r\nIf any portion of this section is held invalid or unenforceable under any\r\nparticular circumstance, the balance of the section is intended to apply,\r\nand the section as a whole is intended to apply in other circumstances.\r\n\r\nIt is not the purpose of this section to induce you to infringe any\r\npatents or other property right claims or to contest validity of any\r\nsuch claims; this section has the sole purpose of protecting the\r\nintegrity of the free software distribution system which is\r\nimplemented by public license practices.  Many people have made\r\ngenerous contributions to the wide range of software distributed\r\nthrough that system in reliance on consistent application of that\r\nsystem; it is up to the author/donor to decide if he or she is willing\r\nto distribute software through any other system and a licensee cannot\r\nimpose that choice.\r\n\r\nThis section is intended to make thoroughly clear what is believed to\r\nbe a consequence of the rest of this License.\r\n\r\n  12. If the distribution and/or use of the Library is restricted in\r\ncertain countries either by patents or by copyrighted interfaces, the\r\noriginal copyright holder who places the Library under this License may add\r\nan explicit geographical distribution limitation excluding those countries,\r\nso that distribution is permitted only in or among countries not thus\r\nexcluded.  In such case, this License incorporates the limitation as if\r\nwritten in the body of this License.\r\n\r\n  13. The Free Software Foundation may publish revised and/or new\r\nversions of the Lesser General Public License from time to time.\r\nSuch new versions will be similar in spirit to the present version,\r\nbut may differ in detail to address new problems or concerns.\r\n\r\nEach version is given a distinguishing version number.  If the Library\r\nspecifies a version number of this License which applies to it and\r\n\"any later version\", you have the option of following the terms and\r\nconditions either of that version or of any later version published by\r\nthe Free Software Foundation.  If the Library does not specify a\r\nlicense version number, you may choose any version ever published by\r\nthe Free Software Foundation.\r\n\r\n  14. If you wish to incorporate parts of the Library into other free\r\nprograms whose distribution conditions are incompatible with these,\r\nwrite to the author to ask for permission.  For software which is\r\ncopyrighted by the Free Software Foundation, write to the Free\r\nSoftware Foundation; we sometimes make exceptions for this.  Our\r\ndecision will be guided by the two goals of preserving the free status\r\nof all derivatives of our free software and of promoting the sharing\r\nand reuse of software generally.\r\n\r\nNO WARRANTY\r\n\r\n  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO\r\nWARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\r\nEXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\r\nOTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY\r\nKIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE\r\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\r\nLIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME\r\nTHE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\r\n\r\n  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\r\nWRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\r\nAND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU\r\nFOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR\r\nCONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\r\nLIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\r\nRENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\r\nFAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF\r\nSUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\r\nDAMAGES.\r\n\r\nEND OF TERMS AND CONDITIONS\r\n\r\n\r\nAppendix C: The MPL License\r\n---------------------------\r\n\r\nMOZILLA PUBLIC LICENSE\r\nVersion 1.1\r\n\r\n1. Definitions.\r\n\r\n     1.0.1. \"Commercial Use\" means distribution or otherwise making the\r\n     Covered Code available to a third party.\r\n\r\n     1.1. \"Contributor\" means each entity that creates or contributes to\r\n     the creation of Modifications.\r\n\r\n     1.2. \"Contributor Version\" means the combination of the Original\r\n     Code, prior Modifications used by a Contributor, and the Modifications\r\n     made by that particular Contributor.\r\n\r\n     1.3. \"Covered Code\" means the Original Code or Modifications or the\r\n     combination of the Original Code and Modifications, in each case\r\n     including portions thereof.\r\n\r\n     1.4. \"Electronic Distribution Mechanism\" means a mechanism generally\r\n     accepted in the software development community for the electronic\r\n     transfer of data.\r\n\r\n     1.5. \"Executable\" means Covered Code in any form other than Source\r\n     Code.\r\n\r\n     1.6. \"Initial Developer\" means the individual or entity identified\r\n     as the Initial Developer in the Source Code notice required by Exhibit\r\n     A.\r\n\r\n     1.7. \"Larger Work\" means a work which combines Covered Code or\r\n     portions thereof with code not governed by the terms of this License.\r\n\r\n     1.8. \"License\" means this document.\r\n\r\n     1.8.1. \"Licensable\" means having the right to grant, to the maximum\r\n     extent possible, whether at the time of the initial grant or\r\n     subsequently acquired, any and all of the rights conveyed herein.\r\n\r\n     1.9. \"Modifications\" means any addition to or deletion from the\r\n     substance or structure of either the Original Code or any previous\r\n     Modifications. When Covered Code is released as a series of files, a\r\n     Modification is:\r\n          A. Any addition to or deletion from the contents of a file\r\n          containing Original Code or previous Modifications.\r\n\r\n          B. Any new file that contains any part of the Original Code or\r\n          previous Modifications.\r\n\r\n     1.10. \"Original Code\" means Source Code of computer software code\r\n     which is described in the Source Code notice required by Exhibit A as\r\n     Original Code, and which, at the time of its release under this\r\n     License is not already Covered Code governed by this License.\r\n\r\n     1.10.1. \"Patent Claims\" means any patent claim(s), now owned or\r\n     hereafter acquired, including without limitation,  method, process,\r\n     and apparatus claims, in any patent Licensable by grantor.\r\n\r\n     1.11. \"Source Code\" means the preferred form of the Covered Code for\r\n     making modifications to it, including all modules it contains, plus\r\n     any associated interface definition files, scripts used to control\r\n     compilation and installation of an Executable, or source code\r\n     differential comparisons against either the Original Code or another\r\n     well known, available Covered Code of the Contributor's choice. The\r\n     Source Code can be in a compressed or archival form, provided the\r\n     appropriate decompression or de-archiving software is widely available\r\n     for no charge.\r\n\r\n     1.12. \"You\" (or \"Your\")  means an individual or a legal entity\r\n     exercising rights under, and complying with all of the terms of, this\r\n     License or a future version of this License issued under Section 6.1.\r\n     For legal entities, \"You\" includes any entity which controls, is\r\n     controlled by, or is under common control with You. For purposes of\r\n     this definition, \"control\" means (a) the power, direct or indirect,\r\n     to cause the direction or management of such entity, whether by\r\n     contract or otherwise, or (b) ownership of more than fifty percent\r\n     (50%) of the outstanding shares or beneficial ownership of such\r\n     entity.\r\n\r\n2. Source Code License.\r\n\r\n     2.1. The Initial Developer Grant.\r\n     The Initial Developer hereby grants You a world-wide, royalty-free,\r\n     non-exclusive license, subject to third party intellectual property\r\n     claims:\r\n          (a)  under intellectual property rights (other than patent or\r\n          trademark) Licensable by Initial Developer to use, reproduce,\r\n          modify, display, perform, sublicense and distribute the Original\r\n          Code (or portions thereof) with or without Modifications, and/or\r\n          as part of a Larger Work; and\r\n\r\n          (b) under Patents Claims infringed by the making, using or\r\n          selling of Original Code, to make, have made, use, practice,\r\n          sell, and offer for sale, and/or otherwise dispose of the\r\n          Original Code (or portions thereof).\r\n\r\n          (c) the licenses granted in this Section 2.1(a) and (b) are\r\n          effective on the date Initial Developer first distributes\r\n          Original Code under the terms of this License.\r\n\r\n          (d) Notwithstanding Section 2.1(b) above, no patent license is\r\n          granted: 1) for code that You delete from the Original Code; 2)\r\n          separate from the Original Code;  or 3) for infringements caused\r\n          by: i) the modification of the Original Code or ii) the\r\n          combination of the Original Code with other software or devices.\r\n\r\n     2.2. Contributor Grant.\r\n     Subject to third party intellectual property claims, each Contributor\r\n     hereby grants You a world-wide, royalty-free, non-exclusive license\r\n\r\n          (a)  under intellectual property rights (other than patent or\r\n          trademark) Licensable by Contributor, to use, reproduce, modify,\r\n          display, perform, sublicense and distribute the Modifications\r\n          created by such Contributor (or portions thereof) either on an\r\n          unmodified basis, with other Modifications, as Covered Code\r\n          and/or as part of a Larger Work; and\r\n\r\n          (b) under Patent Claims infringed by the making, using, or\r\n          selling of  Modifications made by that Contributor either alone\r\n          and/or in combination with its Contributor Version (or portions\r\n          of such combination), to make, use, sell, offer for sale, have\r\n          made, and/or otherwise dispose of: 1) Modifications made by that\r\n          Contributor (or portions thereof); and 2) the combination of\r\n          Modifications made by that Contributor with its Contributor\r\n          Version (or portions of such combination).\r\n\r\n          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are\r\n          effective on the date Contributor first makes Commercial Use of\r\n          the Covered Code.\r\n\r\n          (d)    Notwithstanding Section 2.2(b) above, no patent license is\r\n          granted: 1) for any code that Contributor has deleted from the\r\n          Contributor Version; 2)  separate from the Contributor Version;\r\n          3)  for infringements caused by: i) third party modifications of\r\n          Contributor Version or ii)  the combination of Modifications made\r\n          by that Contributor with other software  (except as part of the\r\n          Contributor Version) or other devices; or 4) under Patent Claims\r\n          infringed by Covered Code in the absence of Modifications made by\r\n          that Contributor.\r\n\r\n3. Distribution Obligations.\r\n\r\n     3.1. Application of License.\r\n     The Modifications which You create or to which You contribute are\r\n     governed by the terms of this License, including without limitation\r\n     Section 2.2. The Source Code version of Covered Code may be\r\n     distributed only under the terms of this License or a future version\r\n     of this License released under Section 6.1, and You must include a\r\n     copy of this License with every copy of the Source Code You\r\n     distribute. You may not offer or impose any terms on any Source Code\r\n     version that alters or restricts the applicable version of this\r\n     License or the recipients' rights hereunder. However, You may include\r\n     an additional document offering the additional rights described in\r\n     Section 3.5.\r\n\r\n     3.2. Availability of Source Code.\r\n     Any Modification which You create or to which You contribute must be\r\n     made available in Source Code form under the terms of this License\r\n     either on the same media as an Executable version or via an accepted\r\n     Electronic Distribution Mechanism to anyone to whom you made an\r\n     Executable version available; and if made available via Electronic\r\n     Distribution Mechanism, must remain available for at least twelve (12)\r\n     months after the date it initially became available, or at least six\r\n     (6) months after a subsequent version of that particular Modification\r\n     has been made available to such recipients. You are responsible for\r\n     ensuring that the Source Code version remains available even if the\r\n     Electronic Distribution Mechanism is maintained by a third party.\r\n\r\n     3.3. Description of Modifications.\r\n     You must cause all Covered Code to which You contribute to contain a\r\n     file documenting the changes You made to create that Covered Code and\r\n     the date of any change. You must include a prominent statement that\r\n     the Modification is derived, directly or indirectly, from Original\r\n     Code provided by the Initial Developer and including the name of the\r\n     Initial Developer in (a) the Source Code, and (b) in any notice in an\r\n     Executable version or related documentation in which You describe the\r\n     origin or ownership of the Covered Code.\r\n\r\n     3.4. Intellectual Property Matters\r\n          (a) Third Party Claims.\r\n          If Contributor has knowledge that a license under a third party's\r\n          intellectual property rights is required to exercise the rights\r\n          granted by such Contributor under Sections 2.1 or 2.2,\r\n          Contributor must include a text file with the Source Code\r\n          distribution titled \"LEGAL\" which describes the claim and the\r\n          party making the claim in sufficient detail that a recipient will\r\n          know whom to contact. If Contributor obtains such knowledge after\r\n          the Modification is made available as described in Section 3.2,\r\n          Contributor shall promptly modify the LEGAL file in all copies\r\n          Contributor makes available thereafter and shall take other steps\r\n          (such as notifying appropriate mailing lists or newsgroups)\r\n          reasonably calculated to inform those who received the Covered\r\n          Code that new knowledge has been obtained.\r\n\r\n          (b) Contributor APIs.\r\n          If Contributor's Modifications include an application programming\r\n          interface and Contributor has knowledge of patent licenses which\r\n          are reasonably necessary to implement that API, Contributor must\r\n          also include this information in the LEGAL file.\r\n\r\n               (c)    Representations.\r\n          Contributor represents that, except as disclosed pursuant to\r\n          Section 3.4(a) above, Contributor believes that Contributor's\r\n          Modifications are Contributor's original creation(s) and/or\r\n          Contributor has sufficient rights to grant the rights conveyed by\r\n          this License.\r\n\r\n     3.5. Required Notices.\r\n     You must duplicate the notice in Exhibit A in each file of the Source\r\n     Code.  If it is not possible to put such notice in a particular Source\r\n     Code file due to its structure, then You must include such notice in a\r\n     location (such as a relevant directory) where a user would be likely\r\n     to look for such a notice.  If You created one or more Modification(s)\r\n     You may add your name as a Contributor to the notice described in\r\n     Exhibit A.  You must also duplicate this License in any documentation\r\n     for the Source Code where You describe recipients' rights or ownership\r\n     rights relating to Covered Code.  You may choose to offer, and to\r\n     charge a fee for, warranty, support, indemnity or liability\r\n     obligations to one or more recipients of Covered Code. However, You\r\n     may do so only on Your own behalf, and not on behalf of the Initial\r\n     Developer or any Contributor. You must make it absolutely clear than\r\n     any such warranty, support, indemnity or liability obligation is\r\n     offered by You alone, and You hereby agree to indemnify the Initial\r\n     Developer and every Contributor for any liability incurred by the\r\n     Initial Developer or such Contributor as a result of warranty,\r\n     support, indemnity or liability terms You offer.\r\n\r\n     3.6. Distribution of Executable Versions.\r\n     You may distribute Covered Code in Executable form only if the\r\n     requirements of Section 3.1-3.5 have been met for that Covered Code,\r\n     and if You include a notice stating that the Source Code version of\r\n     the Covered Code is available under the terms of this License,\r\n     including a description of how and where You have fulfilled the\r\n     obligations of Section 3.2. The notice must be conspicuously included\r\n     in any notice in an Executable version, related documentation or\r\n     collateral in which You describe recipients' rights relating to the\r\n     Covered Code. You may distribute the Executable version of Covered\r\n     Code or ownership rights under a license of Your choice, which may\r\n     contain terms different from this License, provided that You are in\r\n     compliance with the terms of this License and that the license for the\r\n     Executable version does not attempt to limit or alter the recipient's\r\n     rights in the Source Code version from the rights set forth in this\r\n     License. If You distribute the Executable version under a different\r\n     license You must make it absolutely clear that any terms which differ\r\n     from this License are offered by You alone, not by the Initial\r\n     Developer or any Contributor. You hereby agree to indemnify the\r\n     Initial Developer and every Contributor for any liability incurred by\r\n     the Initial Developer or such Contributor as a result of any such\r\n     terms You offer.\r\n\r\n     3.7. Larger Works.\r\n     You may create a Larger Work by combining Covered Code with other code\r\n     not governed by the terms of this License and distribute the Larger\r\n     Work as a single product. In such a case, You must make sure the\r\n     requirements of this License are fulfilled for the Covered Code.\r\n\r\n4. Inability to Comply Due to Statute or Regulation.\r\n\r\n     If it is impossible for You to comply with any of the terms of this\r\n     License with respect to some or all of the Covered Code due to\r\n     statute, judicial order, or regulation then You must: (a) comply with\r\n     the terms of this License to the maximum extent possible; and (b)\r\n     describe the limitations and the code they affect. Such description\r\n     must be included in the LEGAL file described in Section 3.4 and must\r\n     be included with all distributions of the Source Code. Except to the\r\n     extent prohibited by statute or regulation, such description must be\r\n     sufficiently detailed for a recipient of ordinary skill to be able to\r\n     understand it.\r\n\r\n5. Application of this License.\r\n\r\n     This License applies to code to which the Initial Developer has\r\n     attached the notice in Exhibit A and to related Covered Code.\r\n\r\n6. Versions of the License.\r\n\r\n     6.1. New Versions.\r\n     Netscape Communications Corporation (\"Netscape\") may publish revised\r\n     and/or new versions of the License from time to time. Each version\r\n     will be given a distinguishing version number.\r\n\r\n     6.2. Effect of New Versions.\r\n     Once Covered Code has been published under a particular version of the\r\n     License, You may always continue to use it under the terms of that\r\n     version. You may also choose to use such Covered Code under the terms\r\n     of any subsequent version of the License published by Netscape. No one\r\n     other than Netscape has the right to modify the terms applicable to\r\n     Covered Code created under this License.\r\n\r\n     6.3. Derivative Works.\r\n     If You create or use a modified version of this License (which you may\r\n     only do in order to apply it to code which is not already Covered Code\r\n     governed by this License), You must (a) rename Your license so that\r\n     the phrases \"Mozilla\", \"MOZILLAPL\", \"MOZPL\", \"Netscape\",\r\n     \"MPL\", \"NPL\" or any confusingly similar phrase do not appear in your\r\n     license (except to note that your license differs from this License)\r\n     and (b) otherwise make it clear that Your version of the license\r\n     contains terms which differ from the Mozilla Public License and\r\n     Netscape Public License. (Filling in the name of the Initial\r\n     Developer, Original Code or Contributor in the notice described in\r\n     Exhibit A shall not of themselves be deemed to be modifications of\r\n     this License.)\r\n\r\n7. DISCLAIMER OF WARRANTY.\r\n\r\n     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN \"AS IS\" BASIS,\r\n     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,\r\n     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF\r\n     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.\r\n     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE\r\n     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,\r\n     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE\r\n     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER\r\n     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF\r\n     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.\r\n\r\n8. TERMINATION.\r\n\r\n     8.1.  This License and the rights granted hereunder will terminate\r\n     automatically if You fail to comply with terms herein and fail to cure\r\n     such breach within 30 days of becoming aware of the breach. All\r\n     sublicenses to the Covered Code which are properly granted shall\r\n     survive any termination of this License. Provisions which, by their\r\n     nature, must remain in effect beyond the termination of this License\r\n     shall survive.\r\n\r\n     8.2.  If You initiate litigation by asserting a patent infringement\r\n     claim (excluding declatory judgment actions) against Initial Developer\r\n     or a Contributor (the Initial Developer or Contributor against whom\r\n     You file such action is referred to as \"Participant\")  alleging that:\r\n\r\n     (a)  such Participant's Contributor Version directly or indirectly\r\n     infringes any patent, then any and all rights granted by such\r\n     Participant to You under Sections 2.1 and/or 2.2 of this License\r\n     shall, upon 60 days notice from Participant terminate prospectively,\r\n     unless if within 60 days after receipt of notice You either: (i)\r\n     agree in writing to pay Participant a mutually agreeable reasonable\r\n     royalty for Your past and future use of Modifications made by such\r\n     Participant, or (ii) withdraw Your litigation claim with respect to\r\n     the Contributor Version against such Participant.  If within 60 days\r\n     of notice, a reasonable royalty and payment arrangement are not\r\n     mutually agreed upon in writing by the parties or the litigation claim\r\n     is not withdrawn, the rights granted by Participant to You under\r\n     Sections 2.1 and/or 2.2 automatically terminate at the expiration of\r\n     the 60 day notice period specified above.\r\n\r\n     (b)  any software, hardware, or device, other than such Participant's\r\n     Contributor Version, directly or indirectly infringes any patent, then\r\n     any rights granted to You by such Participant under Sections 2.1(b)\r\n     and 2.2(b) are revoked effective as of the date You first made, used,\r\n     sold, distributed, or had made, Modifications made by that\r\n     Participant.\r\n\r\n     8.3.  If You assert a patent infringement claim against Participant\r\n     alleging that such Participant's Contributor Version directly or\r\n     indirectly infringes any patent where such claim is resolved (such as\r\n     by license or settlement) prior to the initiation of patent\r\n     infringement litigation, then the reasonable value of the licenses\r\n     granted by such Participant under Sections 2.1 or 2.2 shall be taken\r\n     into account in determining the amount or value of any payment or\r\n     license.\r\n\r\n     8.4.  In the event of termination under Sections 8.1 or 8.2 above,\r\n     all end user license agreements (excluding distributors and resellers)\r\n     which have been validly granted by You or any distributor hereunder\r\n     prior to termination shall survive termination.\r\n\r\n9. LIMITATION OF LIABILITY.\r\n\r\n     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT\r\n     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL\r\n     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,\r\n     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR\r\n     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY\r\n     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,\r\n     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER\r\n     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN\r\n     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF\r\n     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY\r\n     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW\r\n     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE\r\n     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO\r\n     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.\r\n\r\n10. U.S. GOVERNMENT END USERS.\r\n\r\n     The Covered Code is a \"commercial item,\" as that term is defined in\r\n     48 C.F.R. 2.101 (Oct. 1995), consisting of \"commercial computer\r\n     software\" and \"commercial computer software documentation,\" as such\r\n     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48\r\n     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),\r\n     all U.S. Government End Users acquire Covered Code with only those\r\n     rights set forth herein.\r\n\r\n11. MISCELLANEOUS.\r\n\r\n     This License represents the complete agreement concerning subject\r\n     matter hereof. If any provision of this License is held to be\r\n     unenforceable, such provision shall be reformed only to the extent\r\n     necessary to make it enforceable. This License shall be governed by\r\n     California law provisions (except to the extent applicable law, if\r\n     any, provides otherwise), excluding its conflict-of-law provisions.\r\n     With respect to disputes in which at least one party is a citizen of,\r\n     or an entity chartered or registered to do business in the United\r\n     States of America, any litigation relating to this License shall be\r\n     subject to the jurisdiction of the Federal Courts of the Northern\r\n     District of California, with venue lying in Santa Clara County,\r\n     California, with the losing party responsible for costs, including\r\n     without limitation, court costs and reasonable attorneys' fees and\r\n     expenses. The application of the United Nations Convention on\r\n     Contracts for the International Sale of Goods is expressly excluded.\r\n     Any law or regulation which provides that the language of a contract\r\n     shall be construed against the drafter shall not apply to this\r\n     License.\r\n\r\n12. RESPONSIBILITY FOR CLAIMS.\r\n\r\n     As between Initial Developer and the Contributors, each party is\r\n     responsible for claims and damages arising, directly or indirectly,\r\n     out of its utilization of rights under this License and You agree to\r\n     work with Initial Developer and Contributors to distribute such\r\n     responsibility on an equitable basis. Nothing herein is intended or\r\n     shall be deemed to constitute any admission of liability.\r\n\r\n13. MULTIPLE-LICENSED CODE.\r\n\r\n     Initial Developer may designate portions of the Covered Code as\r\n     \"Multiple-Licensed\".  \"Multiple-Licensed\" means that the Initial\r\n     Developer permits you to utilize portions of the Covered Code under\r\n     Your choice of the NPL or the alternative licenses, if any, specified\r\n     by the Initial Developer in the file described in Exhibit A.\r\n\r\nEXHIBIT A -Mozilla Public License.\r\n\r\n     ``The contents of this file are subject to the Mozilla Public License\r\n     Version 1.1 (the \"License\"); you may not use this file except in\r\n     compliance with the License. You may obtain a copy of the License at\r\n     http://www.mozilla.org/MPL/\r\n\r\n     Software distributed under the License is distributed on an \"AS IS\"\r\n     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\r\n     License for the specific language governing rights and limitations\r\n     under the License.\r\n\r\n     The Original Code is ______________________________________.\r\n\r\n     The Initial Developer of the Original Code is ________________________.\r\n     Portions created by ______________________ are Copyright (C) ______\r\n     _______________________. All Rights Reserved.\r\n\r\n     Contributor(s): ______________________________________.\r\n\r\n     Alternatively, the contents of this file may be used under the terms\r\n     of the _____ license (the  \"[___] License\"), in which case the\r\n     provisions of [______] License are applicable instead of those\r\n     above.  If you wish to allow use of your version of this file only\r\n     under the terms of the [____] License and not to allow others to use\r\n     your version of this file under the MPL, indicate your decision by\r\n     deleting  the provisions above and replace  them with the notice and\r\n     other provisions required by the [___] License.  If you do not delete\r\n     the provisions above, a recipient may use your version of this file\r\n     under either the MPL or the [___] License.\"\r\n\r\n     [NOTE: The text of this Exhibit A may differ slightly from the text of\r\n     the notices in the Source Code files of the Original Code. You should\r\n     use the text of this Exhibit A rather than the text found in the\r\n     Original Code Source Code for Your Modifications.]\r\n"
  },
  {
    "path": "public/static/plugins/ckeditor/README.md",
    "content": "CKEditor 4\n==========\n\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.  \nhttp://ckeditor.com - See LICENSE.md for license information.\n\nCKEditor is a text editor to be used inside web pages. It's not a replacement\nfor desktop text editors like Word or OpenOffice, but a component to be used as\npart of web applications and websites.\n\n## Documentation\n\nThe full editor documentation is available online at the following address:\nhttp://docs.ckeditor.com\n\n## Installation\n\nInstalling CKEditor is an easy task. Just follow these simple steps:\n\n 1. **Download** the latest version from the CKEditor website:\n    http://ckeditor.com. You should have already completed this step, but be\n    sure you have the very latest version.\n 2. **Extract** (decompress) the downloaded file into the root of your website.\n\n**Note:** CKEditor is by default installed in the `ckeditor` folder. You can\nplace the files in whichever you want though.\n\n## Checking Your Installation\n\nThe editor comes with a few sample pages that can be used to verify that\ninstallation proceeded properly. Take a look at the `samples` directory.\n\nTo test your installation, just call the following page at your website:\n\n\thttp://<your site>/<CKEditor installation path>/samples/index.html\n\nFor example:\n\n\thttp://www.example.com/ckeditor/samples/index.html\n"
  },
  {
    "path": "public/static/plugins/ckeditor/adapters/jquery.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n(function(a){CKEDITOR.config.jqueryOverrideVal=\"undefined\"==typeof CKEDITOR.config.jqueryOverrideVal?!0:CKEDITOR.config.jqueryOverrideVal;\"undefined\"!=typeof a&&(a.extend(a.fn,{ckeditorGet:function(){var a=this.eq(0).data(\"ckeditorInstance\");if(!a)throw\"CKEditor is not initialized yet, use ckeditor() with a callback.\";return a},ckeditor:function(g,d){if(!CKEDITOR.env.isCompatible)throw Error(\"The environment is incompatible.\");if(!a.isFunction(g))var k=d,d=g,g=k;var i=[],d=d||{};this.each(function(){var b=\na(this),c=b.data(\"ckeditorInstance\"),f=b.data(\"_ckeditorInstanceLock\"),h=this,j=new a.Deferred;i.push(j.promise());if(c&&!f)g&&g.apply(c,[this]),j.resolve();else if(f)c.once(\"instanceReady\",function(){setTimeout(function(){c.element?(c.element.$==h&&g&&g.apply(c,[h]),j.resolve()):setTimeout(arguments.callee,100)},0)},null,null,9999);else{if(d.autoUpdateElement||\"undefined\"==typeof d.autoUpdateElement&&CKEDITOR.config.autoUpdateElement)d.autoUpdateElementJquery=!0;d.autoUpdateElement=!1;b.data(\"_ckeditorInstanceLock\",\n!0);c=a(this).is(\"textarea\")?CKEDITOR.replace(h,d):CKEDITOR.inline(h,d);b.data(\"ckeditorInstance\",c);c.on(\"instanceReady\",function(d){var e=d.editor;setTimeout(function(){if(e.element){d.removeListener();e.on(\"dataReady\",function(){b.trigger(\"dataReady.ckeditor\",[e])});e.on(\"setData\",function(a){b.trigger(\"setData.ckeditor\",[e,a.data])});e.on(\"getData\",function(a){b.trigger(\"getData.ckeditor\",[e,a.data])},999);e.on(\"destroy\",function(){b.trigger(\"destroy.ckeditor\",[e])});e.on(\"save\",function(){a(h.form).submit();\nreturn!1},null,null,20);if(e.config.autoUpdateElementJquery&&b.is(\"textarea\")&&a(h.form).length){var c=function(){b.ckeditor(function(){e.updateElement()})};a(h.form).submit(c);a(h.form).bind(\"form-pre-serialize\",c);b.bind(\"destroy.ckeditor\",function(){a(h.form).unbind(\"submit\",c);a(h.form).unbind(\"form-pre-serialize\",c)})}e.on(\"destroy\",function(){b.removeData(\"ckeditorInstance\")});b.removeData(\"_ckeditorInstanceLock\");b.trigger(\"instanceReady.ckeditor\",[e]);g&&g.apply(e,[h]);j.resolve()}else setTimeout(arguments.callee,\n100)},0)},null,null,9999)}});var f=new a.Deferred;this.promise=f.promise();a.when.apply(this,i).then(function(){f.resolve()});this.editor=this.eq(0).data(\"ckeditorInstance\");return this}}),CKEDITOR.config.jqueryOverrideVal&&(a.fn.val=CKEDITOR.tools.override(a.fn.val,function(g){return function(d){if(arguments.length){var k=this,i=[],f=this.each(function(){var b=a(this),c=b.data(\"ckeditorInstance\");if(b.is(\"textarea\")&&c){var f=new a.Deferred;c.setData(d,function(){f.resolve()});i.push(f.promise());\nreturn!0}return g.call(b,d)});if(i.length){var b=new a.Deferred;a.when.apply(this,i).done(function(){b.resolveWith(k)});return b.promise()}return f}var f=a(this).eq(0),c=f.data(\"ckeditorInstance\");return f.is(\"textarea\")&&c?c.getData():g.call(f)}})))})(window.jQuery);"
  },
  {
    "path": "public/static/plugins/ckeditor/build-config.js",
    "content": "﻿\n/**\n * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.html or http://ckeditor.com/license\n */\n\n/**\n * This file was added automatically by CKEditor builder.\n * You may re-use it at any time at http://ckeditor.com/builder to build CKEditor again.\n * \n * NOTE: \n *    This file is not used by CKEditor, you may remove it.\n *    Changing this file will not change your CKEditor configuration.\n */\n\nvar CKBUILDER_CONFIG = {\n\tskin: 'moono',\n\tpreset: 'standard',\n\tignore: [\n\t\t'dev',\n\t\t'.gitignore',\n\t\t'.gitattributes',\n\t\t'README.md',\n\t\t'.mailmap'\n\t],\n\tplugins : {\n\t\t'about' : 1,\n\t\t'a11yhelp' : 1,\n\t\t'basicstyles' : 1,\n\t\t'blockquote' : 1,\n\t\t'clipboard' : 1,\n\t\t'contextmenu' : 1,\n\t\t'resize' : 1,\n\t\t'toolbar' : 1,\n\t\t'elementspath' : 1,\n\t\t'enterkey' : 1,\n\t\t'entities' : 1,\n\t\t'filebrowser' : 1,\n\t\t'floatingspace' : 1,\n\t\t'format' : 1,\n\t\t'horizontalrule' : 1,\n\t\t'htmlwriter' : 1,\n\t\t'wysiwygarea' : 1,\n\t\t'image' : 1,\n\t\t'indentlist' : 1,\n\t\t'link' : 1,\n\t\t'list' : 1,\n\t\t'magicline' : 1,\n\t\t'maximize' : 1,\n\t\t'pastetext' : 1,\n\t\t'pastefromword' : 1,\n\t\t'removeformat' : 1,\n\t\t'sourcearea' : 1,\n\t\t'specialchar' : 1,\n\t\t'scayt' : 1,\n\t\t'stylescombo' : 1,\n\t\t'tab' : 1,\n\t\t'table' : 1,\n\t\t'tabletools' : 1,\n\t\t'undo' : 1,\n\t\t'wsc' : 1,\n\t\t'dialog' : 1,\n\t\t'dialogui' : 1,\n\t\t'menu' : 1,\n\t\t'floatpanel' : 1,\n\t\t'panel' : 1,\n\t\t'button' : 1,\n\t\t'popup' : 1,\n\t\t'richcombo' : 1,\n\t\t'listblock' : 1,\n\t\t'indent' : 1,\n\t\t'fakeobjects' : 1,\n\t\t'menubutton' : 1\n\t},\n\tlanguages : {\n\t\t'af' : 1,\n\t\t'sq' : 1,\n\t\t'ar' : 1,\n\t\t'eu' : 1,\n\t\t'bn' : 1,\n\t\t'bs' : 1,\n\t\t'bg' : 1,\n\t\t'ca' : 1,\n\t\t'zh-cn' : 1,\n\t\t'zh' : 1,\n\t\t'hr' : 1,\n\t\t'cs' : 1,\n\t\t'da' : 1,\n\t\t'nl' : 1,\n\t\t'en' : 1,\n\t\t'en-au' : 1,\n\t\t'en-ca' : 1,\n\t\t'en-gb' : 1,\n\t\t'eo' : 1,\n\t\t'et' : 1,\n\t\t'fo' : 1,\n\t\t'fi' : 1,\n\t\t'fr' : 1,\n\t\t'fr-ca' : 1,\n\t\t'gl' : 1,\n\t\t'ka' : 1,\n\t\t'de' : 1,\n\t\t'el' : 1,\n\t\t'gu' : 1,\n\t\t'he' : 1,\n\t\t'hi' : 1,\n\t\t'hu' : 1,\n\t\t'is' : 1,\n\t\t'id' : 1,\n\t\t'it' : 1,\n\t\t'ja' : 1,\n\t\t'km' : 1,\n\t\t'ko' : 1,\n\t\t'ku' : 1,\n\t\t'lv' : 1,\n\t\t'lt' : 1,\n\t\t'mk' : 1,\n\t\t'ms' : 1,\n\t\t'mn' : 1,\n\t\t'no' : 1,\n\t\t'nb' : 1,\n\t\t'fa' : 1,\n\t\t'pl' : 1,\n\t\t'pt-br' : 1,\n\t\t'pt' : 1,\n\t\t'ro' : 1,\n\t\t'ru' : 1,\n\t\t'sr' : 1,\n\t\t'sr-latn' : 1,\n\t\t'si' : 1,\n\t\t'sk' : 1,\n\t\t'sl' : 1,\n\t\t'es' : 1,\n\t\t'sv' : 1,\n\t\t'th' : 1,\n\t\t'tr' : 1,\n\t\t'ug' : 1,\n\t\t'uk' : 1,\n\t\t'vi' : 1,\n\t\t'cy' : 1\n\t}\n};"
  },
  {
    "path": "public/static/plugins/ckeditor/ckeditor.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\n(function(){if(window.CKEDITOR&&window.CKEDITOR.dom)return;window.CKEDITOR||(window.CKEDITOR=function(){var a={timestamp:\"DBAA\",version:\"4.3.1\",revision:\"3ecd0b8\",rnd:Math.floor(900*Math.random())+100,_:{pending:[]},status:\"unloaded\",basePath:function(){var b=window.CKEDITOR_BASEPATH||\"\";if(!b)for(var d=document.getElementsByTagName(\"script\"),a=0;a<d.length;a++){var e=d[a].src.match(/(^|.*[\\\\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\\?.*)?$/i);if(e){b=e[1];break}}-1==b.indexOf(\":/\")&&(b=0===b.indexOf(\"/\")?location.href.match(/^.*?:\\/\\/[^\\/]*/)[0]+b:location.href.match(/^[^\\?]*\\/(?:)/)[0]+\nb);if(!b)throw'The CKEditor installation path could not be automatically detected. Please set the global variable \"CKEDITOR_BASEPATH\" before creating editor instances.';return b}(),getUrl:function(b){-1==b.indexOf(\":/\")&&0!==b.indexOf(\"/\")&&(b=this.basePath+b);this.timestamp&&(\"/\"!=b.charAt(b.length-1)&&!/[&?]t=/.test(b))&&(b+=(0<=b.indexOf(\"?\")?\"&\":\"?\")+\"t=\"+this.timestamp);return b},domReady:function(){function b(){try{document.addEventListener?(document.removeEventListener(\"DOMContentLoaded\",b,\n!1),d()):document.attachEvent&&\"complete\"===document.readyState&&(document.detachEvent(\"onreadystatechange\",b),d())}catch(a){}}function d(){for(var d;d=a.shift();)d()}var a=[];return function(d){a.push(d);\"complete\"===document.readyState&&setTimeout(b,1);if(1==a.length)if(document.addEventListener)document.addEventListener(\"DOMContentLoaded\",b,!1),window.addEventListener(\"load\",b,!1);else if(document.attachEvent){document.attachEvent(\"onreadystatechange\",b);window.attachEvent(\"onload\",b);d=!1;try{d=\n!window.frameElement}catch(e){}if(document.documentElement.doScroll&&d){var i=function(){try{document.documentElement.doScroll(\"left\")}catch(d){setTimeout(i,1);return}b()};i()}}}}()},e=window.CKEDITOR_GETURL;if(e){var b=a.getUrl;a.getUrl=function(c){return e.call(a,c)||b.call(a,c)}}return a}());\nCKEDITOR.event||(CKEDITOR.event=function(){},CKEDITOR.event.implementOn=function(a){var e=CKEDITOR.event.prototype,b;for(b in e)a[b]==void 0&&(a[b]=e[b])},CKEDITOR.event.prototype=function(){function a(a){var d=e(this);return d[a]||(d[a]=new b(a))}var e=function(b){b=b.getPrivate&&b.getPrivate()||b._||(b._={});return b.events||(b.events={})},b=function(b){this.name=b;this.listeners=[]};b.prototype={getListenerIndex:function(b){for(var d=0,a=this.listeners;d<a.length;d++)if(a[d].fn==b)return d;return-1}};\nreturn{define:function(b,d){var h=a.call(this,b);CKEDITOR.tools.extend(h,d,true)},on:function(b,d,h,e,n){function i(a,f,o,q){a={name:b,sender:this,editor:a,data:f,listenerData:e,stop:o,cancel:q,removeListener:j};return d.call(h,a)===false?false:a.data}function j(){q.removeListener(b,d)}var o=a.call(this,b);if(o.getListenerIndex(d)<0){o=o.listeners;h||(h=this);isNaN(n)&&(n=10);var q=this;i.fn=d;i.priority=n;for(var s=o.length-1;s>=0;s--)if(o[s].priority<=n){o.splice(s+1,0,i);return{removeListener:j}}o.unshift(i)}return{removeListener:j}},\nonce:function(){var b=arguments[1];arguments[1]=function(d){d.removeListener();return b.apply(this,arguments)};return this.on.apply(this,arguments)},capture:function(){CKEDITOR.event.useCapture=1;var b=this.on.apply(this,arguments);CKEDITOR.event.useCapture=0;return b},fire:function(){var b=0,d=function(){b=1},a=0,g=function(){a=1};return function(n,i,j){var o=e(this)[n],n=b,q=a;b=a=0;if(o){var s=o.listeners;if(s.length)for(var s=s.slice(0),u,f=0;f<s.length;f++){if(o.errorProof)try{u=s[f].call(this,\nj,i,d,g)}catch(p){}else u=s[f].call(this,j,i,d,g);u===false?a=1:typeof u!=\"undefined\"&&(i=u);if(b||a)break}}i=a?false:typeof i==\"undefined\"?true:i;b=n;a=q;return i}}(),fireOnce:function(b,d,a){d=this.fire(b,d,a);delete e(this)[b];return d},removeListener:function(b,d){var a=e(this)[b];if(a){var g=a.getListenerIndex(d);g>=0&&a.listeners.splice(g,1)}},removeAllListeners:function(){var b=e(this),d;for(d in b)delete b[d]},hasListeners:function(b){return(b=e(this)[b])&&b.listeners.length>0}}}());\nCKEDITOR.editor||(CKEDITOR.editor=function(){CKEDITOR._.pending.push([this,arguments]);CKEDITOR.event.call(this)},CKEDITOR.editor.prototype.fire=function(a,e){a in{instanceReady:1,loaded:1}&&(this[a]=true);return CKEDITOR.event.prototype.fire.call(this,a,e,this)},CKEDITOR.editor.prototype.fireOnce=function(a,e){a in{instanceReady:1,loaded:1}&&(this[a]=true);return CKEDITOR.event.prototype.fireOnce.call(this,a,e,this)},CKEDITOR.event.implementOn(CKEDITOR.editor.prototype));\nCKEDITOR.env||(CKEDITOR.env=function(){var a=navigator.userAgent.toLowerCase(),e=window.opera,b={ie:a.indexOf(\"trident/\")>-1,opera:!!e&&e.version,webkit:a.indexOf(\" applewebkit/\")>-1,air:a.indexOf(\" adobeair/\")>-1,mac:a.indexOf(\"macintosh\")>-1,quirks:document.compatMode==\"BackCompat\"&&(!document.documentMode||document.documentMode<10),mobile:a.indexOf(\"mobile\")>-1,iOS:/(ipad|iphone|ipod)/.test(a),isCustomDomain:function(){if(!this.ie)return false;var d=document.domain,b=window.location.hostname;return d!=\nb&&d!=\"[\"+b+\"]\"},secure:location.protocol==\"https:\"};b.gecko=navigator.product==\"Gecko\"&&!b.webkit&&!b.opera&&!b.ie;if(b.webkit)a.indexOf(\"chrome\")>-1?b.chrome=true:b.safari=true;var c=0;if(b.ie){c=b.quirks||!document.documentMode?parseFloat(a.match(/msie (\\d+)/)[1]):document.documentMode;b.ie9Compat=c==9;b.ie8Compat=c==8;b.ie7Compat=c==7;b.ie6Compat=c<7||b.quirks}if(b.gecko){var d=a.match(/rv:([\\d\\.]+)/);if(d){d=d[1].split(\".\");c=d[0]*1E4+(d[1]||0)*100+(d[2]||0)*1}}b.opera&&(c=parseFloat(e.version()));\nb.air&&(c=parseFloat(a.match(/ adobeair\\/(\\d+)/)[1]));b.webkit&&(c=parseFloat(a.match(/ applewebkit\\/(\\d+)/)[1]));b.version=c;b.isCompatible=b.iOS&&c>=534||!b.mobile&&(b.ie&&c>6||b.gecko&&c>=10801||b.opera&&c>=9.5||b.air&&c>=1||b.webkit&&c>=522||false);b.hidpi=window.devicePixelRatio>=2;b.needsBrFiller=b.gecko||b.webkit||b.ie&&c>10;b.needsNbspFiller=b.ie&&c<11;b.cssClass=\"cke_browser_\"+(b.ie?\"ie\":b.gecko?\"gecko\":b.opera?\"opera\":b.webkit?\"webkit\":\"unknown\");if(b.quirks)b.cssClass=b.cssClass+\" cke_browser_quirks\";\nif(b.ie){b.cssClass=b.cssClass+(\" cke_browser_ie\"+(b.quirks||b.version<7?\"6\":b.version));if(b.quirks)b.cssClass=b.cssClass+\" cke_browser_iequirks\"}if(b.gecko)if(c<10900)b.cssClass=b.cssClass+\" cke_browser_gecko18\";else if(c<=11E3)b.cssClass=b.cssClass+\" cke_browser_gecko19\";if(b.air)b.cssClass=b.cssClass+\" cke_browser_air\";if(b.iOS)b.cssClass=b.cssClass+\" cke_browser_ios\";if(b.hidpi)b.cssClass=b.cssClass+\" cke_hidpi\";return b}());\n\"unloaded\"==CKEDITOR.status&&function(){CKEDITOR.event.implementOn(CKEDITOR);CKEDITOR.loadFullCore=function(){if(CKEDITOR.status!=\"basic_ready\")CKEDITOR.loadFullCore._load=1;else{delete CKEDITOR.loadFullCore;var a=document.createElement(\"script\");a.type=\"text/javascript\";a.src=CKEDITOR.basePath+\"ckeditor.js\";document.getElementsByTagName(\"head\")[0].appendChild(a)}};CKEDITOR.loadFullCoreTimeout=0;CKEDITOR.add=function(a){(this._.pending||(this._.pending=[])).push(a)};(function(){CKEDITOR.domReady(function(){var a=\nCKEDITOR.loadFullCore,e=CKEDITOR.loadFullCoreTimeout;if(a){CKEDITOR.status=\"basic_ready\";a&&a._load?a():e&&setTimeout(function(){CKEDITOR.loadFullCore&&CKEDITOR.loadFullCore()},e*1E3)}})})();CKEDITOR.status=\"basic_loaded\"}();CKEDITOR.dom={};\n(function(){var a=[],e=CKEDITOR.env.gecko?\"-moz-\":CKEDITOR.env.webkit?\"-webkit-\":CKEDITOR.env.opera?\"-o-\":CKEDITOR.env.ie?\"-ms-\":\"\";CKEDITOR.on(\"reset\",function(){a=[]});CKEDITOR.tools={arrayCompare:function(b,a){if(!b&&!a)return true;if(!b||!a||b.length!=a.length)return false;for(var d=0;d<b.length;d++)if(b[d]!=a[d])return false;return true},clone:function(b){var a;if(b&&b instanceof Array){a=[];for(var d=0;d<b.length;d++)a[d]=CKEDITOR.tools.clone(b[d]);return a}if(b===null||typeof b!=\"object\"||\nb instanceof String||b instanceof Number||b instanceof Boolean||b instanceof Date||b instanceof RegExp)return b;a=new b.constructor;for(d in b)a[d]=CKEDITOR.tools.clone(b[d]);return a},capitalize:function(b,a){return b.charAt(0).toUpperCase()+(a?b.slice(1):b.slice(1).toLowerCase())},extend:function(b){var a=arguments.length,d,h;if(typeof(d=arguments[a-1])==\"boolean\")a--;else if(typeof(d=arguments[a-2])==\"boolean\"){h=arguments[a-1];a=a-2}for(var e=1;e<a;e++){var n=arguments[e],i;for(i in n)if(d===\ntrue||b[i]==void 0)if(!h||i in h)b[i]=n[i]}return b},prototypedCopy:function(b){var a=function(){};a.prototype=b;return new a},copy:function(b){var a={},d;for(d in b)a[d]=b[d];return a},isArray:function(b){return Object.prototype.toString.call(b)==\"[object Array]\"},isEmpty:function(b){for(var a in b)if(b.hasOwnProperty(a))return false;return true},cssVendorPrefix:function(b,a,d){if(d)return e+b+\":\"+a+\";\"+b+\":\"+a;d={};d[b]=a;d[e+b]=a;return d},cssStyleToDomStyle:function(){var b=document.createElement(\"div\").style,\na=typeof b.cssFloat!=\"undefined\"?\"cssFloat\":typeof b.styleFloat!=\"undefined\"?\"styleFloat\":\"float\";return function(d){return d==\"float\"?a:d.replace(/-./g,function(d){return d.substr(1).toUpperCase()})}}(),buildStyleHtml:function(b){for(var b=[].concat(b),a,d=[],h=0;h<b.length;h++)if(a=b[h])/@import|[{}]/.test(a)?d.push(\"<style>\"+a+\"</style>\"):d.push('<link type=\"text/css\" rel=stylesheet href=\"'+a+'\">');return d.join(\"\")},htmlEncode:function(b){return(\"\"+b).replace(/&/g,\"&amp;\").replace(/>/g,\"&gt;\").replace(/</g,\n\"&lt;\")},htmlEncodeAttr:function(b){return b.replace(/\"/g,\"&quot;\").replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\")},htmlDecodeAttr:function(b){return b.replace(/&quot;/g,'\"').replace(/&lt;/g,\"<\").replace(/&gt;/g,\">\")},getNextNumber:function(){var b=0;return function(){return++b}}(),getNextId:function(){return\"cke_\"+this.getNextNumber()},override:function(b,a){var d=a(b);d.prototype=b.prototype;return d},setTimeout:function(b,a,d,h,e){e||(e=window);d||(d=e);return e.setTimeout(function(){h?b.apply(d,[].concat(h)):\nb.apply(d)},a||0)},trim:function(){var b=/(?:^[ \\t\\n\\r]+)|(?:[ \\t\\n\\r]+$)/g;return function(a){return a.replace(b,\"\")}}(),ltrim:function(){var b=/^[ \\t\\n\\r]+/g;return function(a){return a.replace(b,\"\")}}(),rtrim:function(){var b=/[ \\t\\n\\r]+$/g;return function(a){return a.replace(b,\"\")}}(),indexOf:function(b,a){if(typeof a==\"function\")for(var d=0,h=b.length;d<h;d++){if(a(b[d]))return d}else{if(b.indexOf)return b.indexOf(a);d=0;for(h=b.length;d<h;d++)if(b[d]===a)return d}return-1},search:function(b,\na){var d=CKEDITOR.tools.indexOf(b,a);return d>=0?b[d]:null},bind:function(b,a){return function(){return b.apply(a,arguments)}},createClass:function(b){var a=b.$,d=b.base,h=b.privates||b._,e=b.proto,b=b.statics;!a&&(a=function(){d&&this.base.apply(this,arguments)});if(h)var n=a,a=function(){var d=this._||(this._={}),a;for(a in h){var b=h[a];d[a]=typeof b==\"function\"?CKEDITOR.tools.bind(b,this):b}n.apply(this,arguments)};if(d){a.prototype=this.prototypedCopy(d.prototype);a.prototype.constructor=a;a.base=\nd;a.baseProto=d.prototype;a.prototype.base=function(){this.base=d.prototype.base;d.apply(this,arguments);this.base=arguments.callee}}e&&this.extend(a.prototype,e,true);b&&this.extend(a,b,true);return a},addFunction:function(b,c){return a.push(function(){return b.apply(c||this,arguments)})-1},removeFunction:function(b){a[b]=null},callFunction:function(b){var c=a[b];return c&&c.apply(window,Array.prototype.slice.call(arguments,1))},cssLength:function(){var a=/^-?\\d+\\.?\\d*px$/,c;return function(d){c=\nCKEDITOR.tools.trim(d+\"\")+\"px\";return a.test(c)?c:d||\"\"}}(),convertToPx:function(){var a;return function(c){if(!a){a=CKEDITOR.dom.element.createFromHtml('<div style=\"position:absolute;left:-9999px;top:-9999px;margin:0px;padding:0px;border:0px;\"></div>',CKEDITOR.document);CKEDITOR.document.getBody().append(a)}if(!/%$/.test(c)){a.setStyle(\"width\",c);return a.$.clientWidth}return c}}(),repeat:function(a,c){return Array(c+1).join(a)},tryThese:function(){for(var a,c=0,d=arguments.length;c<d;c++){var h=\narguments[c];try{a=h();break}catch(e){}}return a},genKey:function(){return Array.prototype.slice.call(arguments).join(\"-\")},defer:function(a){return function(){var c=arguments,d=this;window.setTimeout(function(){a.apply(d,c)},0)}},normalizeCssText:function(a,c){var d=[],h,e=CKEDITOR.tools.parseCssText(a,true,c);for(h in e)d.push(h+\":\"+e[h]);d.sort();return d.length?d.join(\";\")+\";\":\"\"},convertRgbToHex:function(a){return a.replace(/(?:rgb\\(\\s*(\\d+)\\s*,\\s*(\\d+)\\s*,\\s*(\\d+)\\s*\\))/gi,function(a,d,b,e){a=\n[d,b,e];for(d=0;d<3;d++)a[d]=(\"0\"+parseInt(a[d],10).toString(16)).slice(-2);return\"#\"+a.join(\"\")})},parseCssText:function(a,c,d){var h={};if(d){d=new CKEDITOR.dom.element(\"span\");d.setAttribute(\"style\",a);a=CKEDITOR.tools.convertRgbToHex(d.getAttribute(\"style\")||\"\")}if(!a||a==\";\")return h;a.replace(/&quot;/g,'\"').replace(/\\s*([^:;\\s]+)\\s*:\\s*([^;]+)\\s*(?=;|$)/g,function(a,d,b){if(c){d=d.toLowerCase();d==\"font-family\"&&(b=b.toLowerCase().replace(/[\"']/g,\"\").replace(/\\s*,\\s*/g,\",\"));b=CKEDITOR.tools.trim(b)}h[d]=\nb});return h},writeCssText:function(a,c){var d,h=[];for(d in a)h.push(d+\":\"+a[d]);c&&h.sort();return h.join(\"; \")},objectCompare:function(a,c,d){var h;if(!a&&!c)return true;if(!a||!c)return false;for(h in a)if(a[h]!=c[h])return false;if(!d)for(h in c)if(a[h]!=c[h])return false;return true},objectKeys:function(a){var c=[],d;for(d in a)c.push(d);return c},convertArrayToObject:function(a,c){var d={};arguments.length==1&&(c=true);for(var h=0,e=a.length;h<e;++h)d[a[h]]=c;return d},fixDomain:function(){for(var a;;)try{a=\nwindow.parent.document.domain;break}catch(c){a=a?a.replace(/.+?(?:\\.|$)/,\"\"):document.domain;if(!a)break;document.domain=a}return!!a},eventsBuffer:function(a,c){function d(){e=(new Date).getTime();h=false;c()}var h,e=0;return{input:function(){if(!h){var c=(new Date).getTime()-e;c<a?h=setTimeout(d,a-c):d()}},reset:function(){h&&clearTimeout(h);h=e=0}}},enableHtml5Elements:function(a,c){for(var d=[\"abbr\",\"article\",\"aside\",\"audio\",\"bdi\",\"canvas\",\"data\",\"datalist\",\"details\",\"figcaption\",\"figure\",\"footer\",\n\"header\",\"hgroup\",\"mark\",\"meter\",\"nav\",\"output\",\"progress\",\"section\",\"summary\",\"time\",\"video\"],h=d.length,e;h--;){e=a.createElement(d[h]);c&&a.appendChild(e)}}}})();\nCKEDITOR.dtd=function(){var a=CKEDITOR.tools.extend,e=function(a,d){for(var b=CKEDITOR.tools.clone(a),h=1;h<arguments.length;h++){var d=arguments[h],c;for(c in d)delete b[c]}return b},b={},c={},d={address:1,article:1,aside:1,blockquote:1,details:1,div:1,dl:1,fieldset:1,figure:1,footer:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,header:1,hgroup:1,hr:1,menu:1,nav:1,ol:1,p:1,pre:1,section:1,table:1,ul:1},h={command:1,link:1,meta:1,noscript:1,script:1,style:1},g={},n={\"#\":1},i={center:1,dir:1,noframes:1};\na(b,{a:1,abbr:1,area:1,audio:1,b:1,bdi:1,bdo:1,br:1,button:1,canvas:1,cite:1,code:1,command:1,datalist:1,del:1,dfn:1,em:1,embed:1,i:1,iframe:1,img:1,input:1,ins:1,kbd:1,keygen:1,label:1,map:1,mark:1,meter:1,noscript:1,object:1,output:1,progress:1,q:1,ruby:1,s:1,samp:1,script:1,select:1,small:1,span:1,strong:1,sub:1,sup:1,textarea:1,time:1,u:1,\"var\":1,video:1,wbr:1},n,{acronym:1,applet:1,basefont:1,big:1,font:1,isindex:1,strike:1,style:1,tt:1});a(c,d,b,i);e={a:e(b,{a:1,button:1}),abbr:b,address:c,\narea:g,article:a({style:1},c),aside:a({style:1},c),audio:a({source:1,track:1},c),b:b,base:g,bdi:b,bdo:b,blockquote:c,body:c,br:g,button:e(b,{a:1,button:1}),canvas:b,caption:c,cite:b,code:b,col:g,colgroup:{col:1},command:g,datalist:a({option:1},b),dd:c,del:b,details:a({summary:1},c),dfn:b,div:a({style:1},c),dl:{dt:1,dd:1},dt:c,em:b,embed:g,fieldset:a({legend:1},c),figcaption:c,figure:a({figcaption:1},c),footer:c,form:c,h1:b,h2:b,h3:b,h4:b,h5:b,h6:b,head:a({title:1,base:1},h),header:c,hgroup:{h1:1,\nh2:1,h3:1,h4:1,h5:1,h6:1},hr:g,html:a({head:1,body:1},c,h),i:b,iframe:n,img:g,input:g,ins:b,kbd:b,keygen:g,label:b,legend:b,li:c,link:g,map:c,mark:b,menu:a({li:1},c),meta:g,meter:e(b,{meter:1}),nav:c,noscript:a({link:1,meta:1,style:1},b),object:a({param:1},b),ol:{li:1},optgroup:{option:1},option:n,output:b,p:b,param:g,pre:b,progress:e(b,{progress:1}),q:b,rp:b,rt:b,ruby:a({rp:1,rt:1},b),s:b,samp:b,script:n,section:a({style:1},c),select:{optgroup:1,option:1},small:b,source:g,span:b,strong:b,style:n,\nsub:b,summary:b,sup:b,table:{caption:1,colgroup:1,thead:1,tfoot:1,tbody:1,tr:1},tbody:{tr:1},td:c,textarea:n,tfoot:{tr:1},th:c,thead:{tr:1},time:e(b,{time:1}),title:n,tr:{th:1,td:1},track:g,u:b,ul:{li:1},\"var\":b,video:a({source:1,track:1},c),wbr:g,acronym:b,applet:a({param:1},c),basefont:g,big:b,center:c,dialog:g,dir:{li:1},font:b,isindex:g,noframes:c,strike:b,tt:b};a(e,{$block:a({audio:1,dd:1,dt:1,figcaption:1,li:1,video:1},d,i),$blockLimit:{article:1,aside:1,audio:1,body:1,caption:1,details:1,dir:1,\ndiv:1,dl:1,fieldset:1,figcaption:1,figure:1,footer:1,form:1,header:1,hgroup:1,menu:1,nav:1,ol:1,section:1,table:1,td:1,th:1,tr:1,ul:1,video:1},$cdata:{script:1,style:1},$editable:{address:1,article:1,aside:1,blockquote:1,body:1,details:1,div:1,fieldset:1,figcaption:1,footer:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,header:1,hgroup:1,nav:1,p:1,pre:1,section:1},$empty:{area:1,base:1,basefont:1,br:1,col:1,command:1,dialog:1,embed:1,hr:1,img:1,input:1,isindex:1,keygen:1,link:1,meta:1,param:1,source:1,track:1,\nwbr:1},$inline:b,$list:{dl:1,ol:1,ul:1},$listItem:{dd:1,dt:1,li:1},$nonBodyContent:a({body:1,head:1,html:1},e.head),$nonEditable:{applet:1,audio:1,button:1,embed:1,iframe:1,map:1,object:1,option:1,param:1,script:1,textarea:1,video:1},$object:{applet:1,audio:1,button:1,hr:1,iframe:1,img:1,input:1,object:1,select:1,table:1,textarea:1,video:1},$removeEmpty:{abbr:1,acronym:1,b:1,bdi:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,mark:1,meter:1,output:1,q:1,ruby:1,s:1,samp:1,\nsmall:1,span:1,strike:1,strong:1,sub:1,sup:1,time:1,tt:1,u:1,\"var\":1},$tabIndex:{a:1,area:1,button:1,input:1,object:1,select:1,textarea:1},$tableContent:{caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1},$transparent:{a:1,audio:1,canvas:1,del:1,ins:1,map:1,noscript:1,object:1,video:1},$intermediate:{caption:1,colgroup:1,dd:1,dt:1,figcaption:1,legend:1,li:1,optgroup:1,option:1,rp:1,rt:1,summary:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1}});return e}();\nCKEDITOR.dom.event=function(a){this.$=a};\nCKEDITOR.dom.event.prototype={getKey:function(){return this.$.keyCode||this.$.which},getKeystroke:function(){var a=this.getKey();if(this.$.ctrlKey||this.$.metaKey)a=a+CKEDITOR.CTRL;this.$.shiftKey&&(a=a+CKEDITOR.SHIFT);this.$.altKey&&(a=a+CKEDITOR.ALT);return a},preventDefault:function(a){var e=this.$;e.preventDefault?e.preventDefault():e.returnValue=false;a&&this.stopPropagation()},stopPropagation:function(){var a=this.$;a.stopPropagation?a.stopPropagation():a.cancelBubble=true},getTarget:function(){var a=\nthis.$.target||this.$.srcElement;return a?new CKEDITOR.dom.node(a):null},getPhase:function(){return this.$.eventPhase||2},getPageOffset:function(){var a=this.getTarget().getDocument().$;return{x:this.$.pageX||this.$.clientX+(a.documentElement.scrollLeft||a.body.scrollLeft),y:this.$.pageY||this.$.clientY+(a.documentElement.scrollTop||a.body.scrollTop)}}};CKEDITOR.CTRL=1114112;CKEDITOR.SHIFT=2228224;CKEDITOR.ALT=4456448;CKEDITOR.EVENT_PHASE_CAPTURING=1;CKEDITOR.EVENT_PHASE_AT_TARGET=2;\nCKEDITOR.EVENT_PHASE_BUBBLING=3;CKEDITOR.dom.domObject=function(a){if(a)this.$=a};\nCKEDITOR.dom.domObject.prototype=function(){var a=function(a,b){return function(c){typeof CKEDITOR!=\"undefined\"&&a.fire(b,new CKEDITOR.dom.event(c))}};return{getPrivate:function(){var a;if(!(a=this.getCustomData(\"_\")))this.setCustomData(\"_\",a={});return a},on:function(e){var b=this.getCustomData(\"_cke_nativeListeners\");if(!b){b={};this.setCustomData(\"_cke_nativeListeners\",b)}if(!b[e]){b=b[e]=a(this,e);this.$.addEventListener?this.$.addEventListener(e,b,!!CKEDITOR.event.useCapture):this.$.attachEvent&&\nthis.$.attachEvent(\"on\"+e,b)}return CKEDITOR.event.prototype.on.apply(this,arguments)},removeListener:function(a){CKEDITOR.event.prototype.removeListener.apply(this,arguments);if(!this.hasListeners(a)){var b=this.getCustomData(\"_cke_nativeListeners\"),c=b&&b[a];if(c){this.$.removeEventListener?this.$.removeEventListener(a,c,false):this.$.detachEvent&&this.$.detachEvent(\"on\"+a,c);delete b[a]}}},removeAllListeners:function(){var a=this.getCustomData(\"_cke_nativeListeners\"),b;for(b in a){var c=a[b];this.$.detachEvent?\nthis.$.detachEvent(\"on\"+b,c):this.$.removeEventListener&&this.$.removeEventListener(b,c,false);delete a[b]}}}}();\n(function(a){var e={};CKEDITOR.on(\"reset\",function(){e={}});a.equals=function(a){try{return a&&a.$===this.$}catch(c){return false}};a.setCustomData=function(a,c){var d=this.getUniqueId();(e[d]||(e[d]={}))[a]=c;return this};a.getCustomData=function(a){var c=this.$[\"data-cke-expando\"];return(c=c&&e[c])&&a in c?c[a]:null};a.removeCustomData=function(a){var c=this.$[\"data-cke-expando\"],c=c&&e[c],d,h;if(c){d=c[a];h=a in c;delete c[a]}return h?d:null};a.clearCustomData=function(){this.removeAllListeners();\nvar a=this.$[\"data-cke-expando\"];a&&delete e[a]};a.getUniqueId=function(){return this.$[\"data-cke-expando\"]||(this.$[\"data-cke-expando\"]=CKEDITOR.tools.getNextNumber())};CKEDITOR.event.implementOn(a)})(CKEDITOR.dom.domObject.prototype);\nCKEDITOR.dom.node=function(a){return a?new CKEDITOR.dom[a.nodeType==CKEDITOR.NODE_DOCUMENT?\"document\":a.nodeType==CKEDITOR.NODE_ELEMENT?\"element\":a.nodeType==CKEDITOR.NODE_TEXT?\"text\":a.nodeType==CKEDITOR.NODE_COMMENT?\"comment\":a.nodeType==CKEDITOR.NODE_DOCUMENT_FRAGMENT?\"documentFragment\":\"domObject\"](a):this};CKEDITOR.dom.node.prototype=new CKEDITOR.dom.domObject;CKEDITOR.NODE_ELEMENT=1;CKEDITOR.NODE_DOCUMENT=9;CKEDITOR.NODE_TEXT=3;CKEDITOR.NODE_COMMENT=8;CKEDITOR.NODE_DOCUMENT_FRAGMENT=11;\nCKEDITOR.POSITION_IDENTICAL=0;CKEDITOR.POSITION_DISCONNECTED=1;CKEDITOR.POSITION_FOLLOWING=2;CKEDITOR.POSITION_PRECEDING=4;CKEDITOR.POSITION_IS_CONTAINED=8;CKEDITOR.POSITION_CONTAINS=16;\nCKEDITOR.tools.extend(CKEDITOR.dom.node.prototype,{appendTo:function(a,e){a.append(this,e);return a},clone:function(a,e){var b=this.$.cloneNode(a),c=function(d){d[\"data-cke-expando\"]&&(d[\"data-cke-expando\"]=false);if(d.nodeType==CKEDITOR.NODE_ELEMENT){e||d.removeAttribute(\"id\",false);if(a)for(var d=d.childNodes,b=0;b<d.length;b++)c(d[b])}};c(b);return new CKEDITOR.dom.node(b)},hasPrevious:function(){return!!this.$.previousSibling},hasNext:function(){return!!this.$.nextSibling},insertAfter:function(a){a.$.parentNode.insertBefore(this.$,\na.$.nextSibling);return a},insertBefore:function(a){a.$.parentNode.insertBefore(this.$,a.$);return a},insertBeforeMe:function(a){this.$.parentNode.insertBefore(a.$,this.$);return a},getAddress:function(a){for(var e=[],b=this.getDocument().$.documentElement,c=this.$;c&&c!=b;){var d=c.parentNode;d&&e.unshift(this.getIndex.call({$:c},a));c=d}return e},getDocument:function(){return new CKEDITOR.dom.document(this.$.ownerDocument||this.$.parentNode.ownerDocument)},getIndex:function(a){var e=this.$,b=-1,\nc;if(!this.$.parentNode)return b;do if(!a||!(e!=this.$&&e.nodeType==CKEDITOR.NODE_TEXT&&(c||!e.nodeValue))){b++;c=e.nodeType==CKEDITOR.NODE_TEXT}while(e=e.previousSibling);return b},getNextSourceNode:function(a,e,b){if(b&&!b.call)var c=b,b=function(a){return!a.equals(c)};var a=!a&&this.getFirst&&this.getFirst(),d;if(!a){if(this.type==CKEDITOR.NODE_ELEMENT&&b&&b(this,true)===false)return null;a=this.getNext()}for(;!a&&(d=(d||this).getParent());){if(b&&b(d,true)===false)return null;a=d.getNext()}return!a||\nb&&b(a)===false?null:e&&e!=a.type?a.getNextSourceNode(false,e,b):a},getPreviousSourceNode:function(a,e,b){if(b&&!b.call)var c=b,b=function(a){return!a.equals(c)};var a=!a&&this.getLast&&this.getLast(),d;if(!a){if(this.type==CKEDITOR.NODE_ELEMENT&&b&&b(this,true)===false)return null;a=this.getPrevious()}for(;!a&&(d=(d||this).getParent());){if(b&&b(d,true)===false)return null;a=d.getPrevious()}return!a||b&&b(a)===false?null:e&&a.type!=e?a.getPreviousSourceNode(false,e,b):a},getPrevious:function(a){var e=\nthis.$,b;do b=(e=e.previousSibling)&&e.nodeType!=10&&new CKEDITOR.dom.node(e);while(b&&a&&!a(b));return b},getNext:function(a){var e=this.$,b;do b=(e=e.nextSibling)&&new CKEDITOR.dom.node(e);while(b&&a&&!a(b));return b},getParent:function(a){var e=this.$.parentNode;return e&&(e.nodeType==CKEDITOR.NODE_ELEMENT||a&&e.nodeType==CKEDITOR.NODE_DOCUMENT_FRAGMENT)?new CKEDITOR.dom.node(e):null},getParents:function(a){var e=this,b=[];do b[a?\"push\":\"unshift\"](e);while(e=e.getParent());return b},getCommonAncestor:function(a){if(a.equals(this))return this;\nif(a.contains&&a.contains(this))return a;var e=this.contains?this:this.getParent();do if(e.contains(a))return e;while(e=e.getParent());return null},getPosition:function(a){var e=this.$,b=a.$;if(e.compareDocumentPosition)return e.compareDocumentPosition(b);if(e==b)return CKEDITOR.POSITION_IDENTICAL;if(this.type==CKEDITOR.NODE_ELEMENT&&a.type==CKEDITOR.NODE_ELEMENT){if(e.contains){if(e.contains(b))return CKEDITOR.POSITION_CONTAINS+CKEDITOR.POSITION_PRECEDING;if(b.contains(e))return CKEDITOR.POSITION_IS_CONTAINED+\nCKEDITOR.POSITION_FOLLOWING}if(\"sourceIndex\"in e)return e.sourceIndex<0||b.sourceIndex<0?CKEDITOR.POSITION_DISCONNECTED:e.sourceIndex<b.sourceIndex?CKEDITOR.POSITION_PRECEDING:CKEDITOR.POSITION_FOLLOWING}for(var e=this.getAddress(),a=a.getAddress(),b=Math.min(e.length,a.length),c=0;c<=b-1;c++)if(e[c]!=a[c]){if(c<b)return e[c]<a[c]?CKEDITOR.POSITION_PRECEDING:CKEDITOR.POSITION_FOLLOWING;break}return e.length<a.length?CKEDITOR.POSITION_CONTAINS+CKEDITOR.POSITION_PRECEDING:CKEDITOR.POSITION_IS_CONTAINED+\nCKEDITOR.POSITION_FOLLOWING},getAscendant:function(a,e){var b=this.$,c;if(!e)b=b.parentNode;for(;b;){if(b.nodeName&&(c=b.nodeName.toLowerCase(),typeof a==\"string\"?c==a:c in a))return new CKEDITOR.dom.node(b);try{b=b.parentNode}catch(d){b=null}}return null},hasAscendant:function(a,e){var b=this.$;if(!e)b=b.parentNode;for(;b;){if(b.nodeName&&b.nodeName.toLowerCase()==a)return true;b=b.parentNode}return false},move:function(a,e){a.append(this.remove(),e)},remove:function(a){var e=this.$,b=e.parentNode;\nif(b){if(a)for(;a=e.firstChild;)b.insertBefore(e.removeChild(a),e);b.removeChild(e)}return this},replace:function(a){this.insertBefore(a);a.remove()},trim:function(){this.ltrim();this.rtrim()},ltrim:function(){for(var a;this.getFirst&&(a=this.getFirst());){if(a.type==CKEDITOR.NODE_TEXT){var e=CKEDITOR.tools.ltrim(a.getText()),b=a.getLength();if(e){if(e.length<b){a.split(b-e.length);this.$.removeChild(this.$.firstChild)}}else{a.remove();continue}}break}},rtrim:function(){for(var a;this.getLast&&(a=\nthis.getLast());){if(a.type==CKEDITOR.NODE_TEXT){var e=CKEDITOR.tools.rtrim(a.getText()),b=a.getLength();if(e){if(e.length<b){a.split(e.length);this.$.lastChild.parentNode.removeChild(this.$.lastChild)}}else{a.remove();continue}}break}if(CKEDITOR.env.needsBrFiller)(a=this.$.lastChild)&&(a.type==1&&a.nodeName.toLowerCase()==\"br\")&&a.parentNode.removeChild(a)},isReadOnly:function(){var a=this;this.type!=CKEDITOR.NODE_ELEMENT&&(a=this.getParent());if(a&&typeof a.$.isContentEditable!=\"undefined\")return!(a.$.isContentEditable||\na.data(\"cke-editable\"));for(;a;){if(a.data(\"cke-editable\"))break;if(a.getAttribute(\"contentEditable\")==\"false\")return true;if(a.getAttribute(\"contentEditable\")==\"true\")break;a=a.getParent()}return!a}});CKEDITOR.dom.window=function(a){CKEDITOR.dom.domObject.call(this,a)};CKEDITOR.dom.window.prototype=new CKEDITOR.dom.domObject;\nCKEDITOR.tools.extend(CKEDITOR.dom.window.prototype,{focus:function(){this.$.focus()},getViewPaneSize:function(){var a=this.$.document,e=a.compatMode==\"CSS1Compat\";return{width:(e?a.documentElement.clientWidth:a.body.clientWidth)||0,height:(e?a.documentElement.clientHeight:a.body.clientHeight)||0}},getScrollPosition:function(){var a=this.$;if(\"pageXOffset\"in a)return{x:a.pageXOffset||0,y:a.pageYOffset||0};a=a.document;return{x:a.documentElement.scrollLeft||a.body.scrollLeft||0,y:a.documentElement.scrollTop||\na.body.scrollTop||0}},getFrame:function(){var a=this.$.frameElement;return a?new CKEDITOR.dom.element.get(a):null}});CKEDITOR.dom.document=function(a){CKEDITOR.dom.domObject.call(this,a)};CKEDITOR.dom.document.prototype=new CKEDITOR.dom.domObject;\nCKEDITOR.tools.extend(CKEDITOR.dom.document.prototype,{type:CKEDITOR.NODE_DOCUMENT,appendStyleSheet:function(a){if(this.$.createStyleSheet)this.$.createStyleSheet(a);else{var e=new CKEDITOR.dom.element(\"link\");e.setAttributes({rel:\"stylesheet\",type:\"text/css\",href:a});this.getHead().append(e)}},appendStyleText:function(a){if(this.$.createStyleSheet){var e=this.$.createStyleSheet(\"\");e.cssText=a}else{var b=new CKEDITOR.dom.element(\"style\",this);b.append(new CKEDITOR.dom.text(a,this));this.getHead().append(b)}return e||\nb.$.sheet},createElement:function(a,e){var b=new CKEDITOR.dom.element(a,this);if(e){e.attributes&&b.setAttributes(e.attributes);e.styles&&b.setStyles(e.styles)}return b},createText:function(a){return new CKEDITOR.dom.text(a,this)},focus:function(){this.getWindow().focus()},getActive:function(){return new CKEDITOR.dom.element(this.$.activeElement)},getById:function(a){return(a=this.$.getElementById(a))?new CKEDITOR.dom.element(a):null},getByAddress:function(a,e){for(var b=this.$.documentElement,c=\n0;b&&c<a.length;c++){var d=a[c];if(e)for(var h=-1,g=0;g<b.childNodes.length;g++){var n=b.childNodes[g];if(!(e===true&&n.nodeType==3&&n.previousSibling&&n.previousSibling.nodeType==3)){h++;if(h==d){b=n;break}}}else b=b.childNodes[d]}return b?new CKEDITOR.dom.node(b):null},getElementsByTag:function(a,e){if((!CKEDITOR.env.ie||document.documentMode>8)&&e)a=e+\":\"+a;return new CKEDITOR.dom.nodeList(this.$.getElementsByTagName(a))},getHead:function(){var a=this.$.getElementsByTagName(\"head\")[0];return a=\na?new CKEDITOR.dom.element(a):this.getDocumentElement().append(new CKEDITOR.dom.element(\"head\"),true)},getBody:function(){return new CKEDITOR.dom.element(this.$.body)},getDocumentElement:function(){return new CKEDITOR.dom.element(this.$.documentElement)},getWindow:function(){return new CKEDITOR.dom.window(this.$.parentWindow||this.$.defaultView)},write:function(a){this.$.open(\"text/html\",\"replace\");CKEDITOR.env.ie&&(a=a.replace(/(?:^\\s*<!DOCTYPE[^>]*?>)|^/i,'$&\\n<script data-cke-temp=\"1\">('+CKEDITOR.tools.fixDomain+\n\")();<\\/script>\"));this.$.write(a);this.$.close()},find:function(a){return new CKEDITOR.dom.nodeList(this.$.querySelectorAll(a))},findOne:function(a){return(a=this.$.querySelector(a))?new CKEDITOR.dom.element(a):null},_getHtml5ShivFrag:function(){var a=this.getCustomData(\"html5ShivFrag\");if(!a){a=this.$.createDocumentFragment();CKEDITOR.tools.enableHtml5Elements(a,true);this.setCustomData(\"html5ShivFrag\",a)}return a}});CKEDITOR.dom.nodeList=function(a){this.$=a};\nCKEDITOR.dom.nodeList.prototype={count:function(){return this.$.length},getItem:function(a){if(a<0||a>=this.$.length)return null;return(a=this.$[a])?new CKEDITOR.dom.node(a):null}};CKEDITOR.dom.element=function(a,e){typeof a==\"string\"&&(a=(e?e.$:document).createElement(a));CKEDITOR.dom.domObject.call(this,a)};CKEDITOR.dom.element.get=function(a){return(a=typeof a==\"string\"?document.getElementById(a)||document.getElementsByName(a)[0]:a)&&(a.$?a:new CKEDITOR.dom.element(a))};\nCKEDITOR.dom.element.prototype=new CKEDITOR.dom.node;CKEDITOR.dom.element.createFromHtml=function(a,e){var b=new CKEDITOR.dom.element(\"div\",e);b.setHtml(a);return b.getFirst().remove()};\nCKEDITOR.dom.element.setMarker=function(a,e,b,c){var d=e.getCustomData(\"list_marker_id\")||e.setCustomData(\"list_marker_id\",CKEDITOR.tools.getNextNumber()).getCustomData(\"list_marker_id\"),h=e.getCustomData(\"list_marker_names\")||e.setCustomData(\"list_marker_names\",{}).getCustomData(\"list_marker_names\");a[d]=e;h[b]=1;return e.setCustomData(b,c)};CKEDITOR.dom.element.clearAllMarkers=function(a){for(var e in a)CKEDITOR.dom.element.clearMarkers(a,a[e],1)};\nCKEDITOR.dom.element.clearMarkers=function(a,e,b){var c=e.getCustomData(\"list_marker_names\"),d=e.getCustomData(\"list_marker_id\"),h;for(h in c)e.removeCustomData(h);e.removeCustomData(\"list_marker_names\");if(b){e.removeCustomData(\"list_marker_id\");delete a[d]}};\n(function(){function a(a){var b=true;if(!a.$.id){a.$.id=\"cke_tmp_\"+CKEDITOR.tools.getNextNumber();b=false}return function(){b||a.removeAttribute(\"id\")}}function e(a,b){return\"#\"+a.$.id+\" \"+b.split(/,\\s*/).join(\", #\"+a.$.id+\" \")}function b(a){for(var b=0,e=0,n=c[a].length;e<n;e++)b=b+(parseInt(this.getComputedStyle(c[a][e])||0,10)||0);return b}CKEDITOR.tools.extend(CKEDITOR.dom.element.prototype,{type:CKEDITOR.NODE_ELEMENT,addClass:function(a){var b=this.$.className;b&&(RegExp(\"(?:^|\\\\s)\"+a+\"(?:\\\\s|$)\",\n\"\").test(b)||(b=b+(\" \"+a)));this.$.className=b||a},removeClass:function(a){var b=this.getAttribute(\"class\");if(b){a=RegExp(\"(?:^|\\\\s+)\"+a+\"(?=\\\\s|$)\",\"i\");if(a.test(b))(b=b.replace(a,\"\").replace(/^\\s+/,\"\"))?this.setAttribute(\"class\",b):this.removeAttribute(\"class\")}return this},hasClass:function(a){return RegExp(\"(?:^|\\\\s+)\"+a+\"(?=\\\\s|$)\",\"\").test(this.getAttribute(\"class\"))},append:function(a,b){typeof a==\"string\"&&(a=this.getDocument().createElement(a));b?this.$.insertBefore(a.$,this.$.firstChild):\nthis.$.appendChild(a.$);return a},appendHtml:function(a){if(this.$.childNodes.length){var b=new CKEDITOR.dom.element(\"div\",this.getDocument());b.setHtml(a);b.moveChildren(this)}else this.setHtml(a)},appendText:function(a){this.$.text!=void 0?this.$.text=this.$.text+a:this.append(new CKEDITOR.dom.text(a))},appendBogus:function(a){if(a||CKEDITOR.env.needsBrFiller||CKEDITOR.env.opera){for(a=this.getLast();a&&a.type==CKEDITOR.NODE_TEXT&&!CKEDITOR.tools.rtrim(a.getText());)a=a.getPrevious();if(!a||!a.is||\n!a.is(\"br\")){a=CKEDITOR.env.opera?this.getDocument().createText(\"\"):this.getDocument().createElement(\"br\");CKEDITOR.env.gecko&&a.setAttribute(\"type\",\"_moz\");this.append(a)}}},breakParent:function(a){var b=new CKEDITOR.dom.range(this.getDocument());b.setStartAfter(this);b.setEndAfter(a);a=b.extractContents();b.insertNode(this.remove());a.insertAfterNode(this)},contains:CKEDITOR.env.ie||CKEDITOR.env.webkit?function(a){var b=this.$;return a.type!=CKEDITOR.NODE_ELEMENT?b.contains(a.getParent().$):b!=\na.$&&b.contains(a.$)}:function(a){return!!(this.$.compareDocumentPosition(a.$)&16)},focus:function(){function a(){try{this.$.focus()}catch(b){}}return function(b){b?CKEDITOR.tools.setTimeout(a,100,this):a.call(this)}}(),getHtml:function(){var a=this.$.innerHTML;return CKEDITOR.env.ie?a.replace(/<\\?[^>]*>/g,\"\"):a},getOuterHtml:function(){if(this.$.outerHTML)return this.$.outerHTML.replace(/<\\?[^>]*>/,\"\");var a=this.$.ownerDocument.createElement(\"div\");a.appendChild(this.$.cloneNode(true));return a.innerHTML},\ngetClientRect:function(){var a=CKEDITOR.tools.extend({},this.$.getBoundingClientRect());!a.width&&(a.width=a.right-a.left);!a.height&&(a.height=a.bottom-a.top);return a},setHtml:CKEDITOR.env.ie&&CKEDITOR.env.version<9?function(a){try{var b=this.$;if(this.getParent())return b.innerHTML=a;var c=this.getDocument()._getHtml5ShivFrag();c.appendChild(b);b.innerHTML=a;c.removeChild(b);return a}catch(e){this.$.innerHTML=\"\";b=new CKEDITOR.dom.element(\"body\",this.getDocument());b.$.innerHTML=a;for(b=b.getChildren();b.count();)this.append(b.getItem(0));\nreturn a}}:function(a){return this.$.innerHTML=a},setText:function(a){CKEDITOR.dom.element.prototype.setText=this.$.innerText!=void 0?function(a){return this.$.innerText=a}:function(a){return this.$.textContent=a};return this.setText(a)},getAttribute:function(){var a=function(a){return this.$.getAttribute(a,2)};return CKEDITOR.env.ie&&(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat)?function(a){switch(a){case \"class\":a=\"className\";break;case \"http-equiv\":a=\"httpEquiv\";break;case \"name\":return this.$.name;\ncase \"tabindex\":a=this.$.getAttribute(a,2);a!==0&&this.$.tabIndex===0&&(a=null);return a;case \"checked\":a=this.$.attributes.getNamedItem(a);return(a.specified?a.nodeValue:this.$.checked)?\"checked\":null;case \"hspace\":case \"value\":return this.$[a];case \"style\":return this.$.style.cssText;case \"contenteditable\":case \"contentEditable\":return this.$.attributes.getNamedItem(\"contentEditable\").specified?this.$.getAttribute(\"contentEditable\"):null}return this.$.getAttribute(a,2)}:a}(),getChildren:function(){return new CKEDITOR.dom.nodeList(this.$.childNodes)},\ngetComputedStyle:CKEDITOR.env.ie?function(a){return this.$.currentStyle[CKEDITOR.tools.cssStyleToDomStyle(a)]}:function(a){var b=this.getWindow().$.getComputedStyle(this.$,null);return b?b.getPropertyValue(a):\"\"},getDtd:function(){var a=CKEDITOR.dtd[this.getName()];this.getDtd=function(){return a};return a},getElementsByTag:CKEDITOR.dom.document.prototype.getElementsByTag,getTabIndex:CKEDITOR.env.ie?function(){var a=this.$.tabIndex;a===0&&(!CKEDITOR.dtd.$tabIndex[this.getName()]&&parseInt(this.getAttribute(\"tabindex\"),\n10)!==0)&&(a=-1);return a}:CKEDITOR.env.webkit?function(){var a=this.$.tabIndex;if(a==void 0){a=parseInt(this.getAttribute(\"tabindex\"),10);isNaN(a)&&(a=-1)}return a}:function(){return this.$.tabIndex},getText:function(){return this.$.textContent||this.$.innerText||\"\"},getWindow:function(){return this.getDocument().getWindow()},getId:function(){return this.$.id||null},getNameAtt:function(){return this.$.name||null},getName:function(){var a=this.$.nodeName.toLowerCase();if(CKEDITOR.env.ie&&!(document.documentMode>\n8)){var b=this.$.scopeName;b!=\"HTML\"&&(a=b.toLowerCase()+\":\"+a)}return(this.getName=function(){return a})()},getValue:function(){return this.$.value},getFirst:function(a){var b=this.$.firstChild;(b=b&&new CKEDITOR.dom.node(b))&&(a&&!a(b))&&(b=b.getNext(a));return b},getLast:function(a){var b=this.$.lastChild;(b=b&&new CKEDITOR.dom.node(b))&&(a&&!a(b))&&(b=b.getPrevious(a));return b},getStyle:function(a){return this.$.style[CKEDITOR.tools.cssStyleToDomStyle(a)]},is:function(){var a=this.getName();\nif(typeof arguments[0]==\"object\")return!!arguments[0][a];for(var b=0;b<arguments.length;b++)if(arguments[b]==a)return true;return false},isEditable:function(a){var b=this.getName();if(this.isReadOnly()||this.getComputedStyle(\"display\")==\"none\"||this.getComputedStyle(\"visibility\")==\"hidden\"||CKEDITOR.dtd.$nonEditable[b]||CKEDITOR.dtd.$empty[b]||this.is(\"a\")&&(this.data(\"cke-saved-name\")||this.hasAttribute(\"name\"))&&!this.getChildCount())return false;if(a!==false){a=CKEDITOR.dtd[b]||CKEDITOR.dtd.span;\nreturn!(!a||!a[\"#\"])}return true},isIdentical:function(a){var b=this.clone(0,1),a=a.clone(0,1);b.removeAttributes([\"_moz_dirty\",\"data-cke-expando\",\"data-cke-saved-href\",\"data-cke-saved-name\"]);a.removeAttributes([\"_moz_dirty\",\"data-cke-expando\",\"data-cke-saved-href\",\"data-cke-saved-name\"]);if(b.$.isEqualNode){b.$.style.cssText=CKEDITOR.tools.normalizeCssText(b.$.style.cssText);a.$.style.cssText=CKEDITOR.tools.normalizeCssText(a.$.style.cssText);return b.$.isEqualNode(a.$)}b=b.getOuterHtml();a=a.getOuterHtml();\nif(CKEDITOR.env.ie&&CKEDITOR.env.version<9&&this.is(\"a\")){var c=this.getParent();if(c.type==CKEDITOR.NODE_ELEMENT){c=c.clone();c.setHtml(b);b=c.getHtml();c.setHtml(a);a=c.getHtml()}}return b==a},isVisible:function(){var a=(this.$.offsetHeight||this.$.offsetWidth)&&this.getComputedStyle(\"visibility\")!=\"hidden\",b,c;if(a&&(CKEDITOR.env.webkit||CKEDITOR.env.opera)){b=this.getWindow();if(!b.equals(CKEDITOR.document.getWindow())&&(c=b.$.frameElement))a=(new CKEDITOR.dom.element(c)).isVisible()}return!!a},\nisEmptyInlineRemoveable:function(){if(!CKEDITOR.dtd.$removeEmpty[this.getName()])return false;for(var a=this.getChildren(),b=0,c=a.count();b<c;b++){var e=a.getItem(b);if(!(e.type==CKEDITOR.NODE_ELEMENT&&e.data(\"cke-bookmark\"))&&(e.type==CKEDITOR.NODE_ELEMENT&&!e.isEmptyInlineRemoveable()||e.type==CKEDITOR.NODE_TEXT&&CKEDITOR.tools.trim(e.getText())))return false}return true},hasAttributes:CKEDITOR.env.ie&&(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat)?function(){for(var a=this.$.attributes,b=0;b<\na.length;b++){var c=a[b];switch(c.nodeName){case \"class\":if(this.getAttribute(\"class\"))return true;case \"data-cke-expando\":continue;default:if(c.specified)return true}}return false}:function(){var a=this.$.attributes,b=a.length,c={\"data-cke-expando\":1,_moz_dirty:1};return b>0&&(b>2||!c[a[0].nodeName]||b==2&&!c[a[1].nodeName])},hasAttribute:function(){function a(b){b=this.$.attributes.getNamedItem(b);return!(!b||!b.specified)}return CKEDITOR.env.ie&&CKEDITOR.env.version<8?function(b){return b==\"name\"?\n!!this.$.name:a.call(this,b)}:a}(),hide:function(){this.setStyle(\"display\",\"none\")},moveChildren:function(a,b){var c=this.$,a=a.$;if(c!=a){var e;if(b)for(;e=c.lastChild;)a.insertBefore(c.removeChild(e),a.firstChild);else for(;e=c.firstChild;)a.appendChild(c.removeChild(e))}},mergeSiblings:function(){function a(b,d,c){if(d&&d.type==CKEDITOR.NODE_ELEMENT){for(var e=[];d.data(\"cke-bookmark\")||d.isEmptyInlineRemoveable();){e.push(d);d=c?d.getNext():d.getPrevious();if(!d||d.type!=CKEDITOR.NODE_ELEMENT)return}if(b.isIdentical(d)){for(var j=\nc?b.getLast():b.getFirst();e.length;)e.shift().move(b,!c);d.moveChildren(b,!c);d.remove();j&&j.type==CKEDITOR.NODE_ELEMENT&&j.mergeSiblings()}}}return function(b){if(b===false||CKEDITOR.dtd.$removeEmpty[this.getName()]||this.is(\"a\")){a(this,this.getNext(),true);a(this,this.getPrevious())}}}(),show:function(){this.setStyles({display:\"\",visibility:\"\"})},setAttribute:function(){var a=function(a,b){this.$.setAttribute(a,b);return this};return CKEDITOR.env.ie&&(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat)?\nfunction(b,c){b==\"class\"?this.$.className=c:b==\"style\"?this.$.style.cssText=c:b==\"tabindex\"?this.$.tabIndex=c:b==\"checked\"?this.$.checked=c:b==\"contenteditable\"?a.call(this,\"contentEditable\",c):a.apply(this,arguments);return this}:CKEDITOR.env.ie8Compat&&CKEDITOR.env.secure?function(b,c){if(b==\"src\"&&c.match(/^http:\\/\\//))try{a.apply(this,arguments)}catch(e){}else a.apply(this,arguments);return this}:a}(),setAttributes:function(a){for(var b in a)this.setAttribute(b,a[b]);return this},setValue:function(a){this.$.value=\na;return this},removeAttribute:function(){var a=function(a){this.$.removeAttribute(a)};return CKEDITOR.env.ie&&(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat)?function(a){a==\"class\"?a=\"className\":a==\"tabindex\"?a=\"tabIndex\":a==\"contenteditable\"&&(a=\"contentEditable\");this.$.removeAttribute(a)}:a}(),removeAttributes:function(a){if(CKEDITOR.tools.isArray(a))for(var b=0;b<a.length;b++)this.removeAttribute(a[b]);else for(b in a)a.hasOwnProperty(b)&&this.removeAttribute(b)},removeStyle:function(a){var b=\nthis.$.style;if(!b.removeProperty&&(a==\"border\"||a==\"margin\"||a==\"padding\")){var c=[\"top\",\"left\",\"right\",\"bottom\"],e;a==\"border\"&&(e=[\"color\",\"style\",\"width\"]);for(var b=[],i=0;i<c.length;i++)if(e)for(var j=0;j<e.length;j++)b.push([a,c[i],e[j]].join(\"-\"));else b.push([a,c[i]].join(\"-\"));for(a=0;a<b.length;a++)this.removeStyle(b[a])}else{b.removeProperty?b.removeProperty(a):b.removeAttribute(CKEDITOR.tools.cssStyleToDomStyle(a));this.$.style.cssText||this.removeAttribute(\"style\")}},setStyle:function(a,\nb){this.$.style[CKEDITOR.tools.cssStyleToDomStyle(a)]=b;return this},setStyles:function(a){for(var b in a)this.setStyle(b,a[b]);return this},setOpacity:function(a){if(CKEDITOR.env.ie&&CKEDITOR.env.version<9){a=Math.round(a*100);this.setStyle(\"filter\",a>=100?\"\":\"progid:DXImageTransform.Microsoft.Alpha(opacity=\"+a+\")\")}else this.setStyle(\"opacity\",a)},unselectable:function(){this.setStyles(CKEDITOR.tools.cssVendorPrefix(\"user-select\",\"none\"));if(CKEDITOR.env.ie||CKEDITOR.env.opera){this.setAttribute(\"unselectable\",\n\"on\");for(var a,b=this.getElementsByTag(\"*\"),c=0,e=b.count();c<e;c++){a=b.getItem(c);a.setAttribute(\"unselectable\",\"on\")}}},getPositionedAncestor:function(){for(var a=this;a.getName()!=\"html\";){if(a.getComputedStyle(\"position\")!=\"static\")return a;a=a.getParent()}return null},getDocumentPosition:function(a){var b=0,c=0,e=this.getDocument(),i=e.getBody(),j=e.$.compatMode==\"BackCompat\";if(document.documentElement.getBoundingClientRect){var o=this.$.getBoundingClientRect(),q=e.$.documentElement,s=q.clientTop||\ni.$.clientTop||0,u=q.clientLeft||i.$.clientLeft||0,f=true;if(CKEDITOR.env.ie){f=e.getDocumentElement().contains(this);e=e.getBody().contains(this);f=j&&e||!j&&f}if(f){b=o.left+(!j&&q.scrollLeft||i.$.scrollLeft);b=b-u;c=o.top+(!j&&q.scrollTop||i.$.scrollTop);c=c-s}}else{i=this;for(e=null;i&&!(i.getName()==\"body\"||i.getName()==\"html\");){b=b+(i.$.offsetLeft-i.$.scrollLeft);c=c+(i.$.offsetTop-i.$.scrollTop);if(!i.equals(this)){b=b+(i.$.clientLeft||0);c=c+(i.$.clientTop||0)}for(;e&&!e.equals(i);){b=b-\ne.$.scrollLeft;c=c-e.$.scrollTop;e=e.getParent()}e=i;i=(o=i.$.offsetParent)?new CKEDITOR.dom.element(o):null}}if(a){i=this.getWindow();e=a.getWindow();if(!i.equals(e)&&i.$.frameElement){a=(new CKEDITOR.dom.element(i.$.frameElement)).getDocumentPosition(a);b=b+a.x;c=c+a.y}}if(!document.documentElement.getBoundingClientRect&&CKEDITOR.env.gecko&&!j){b=b+(this.$.clientLeft?1:0);c=c+(this.$.clientTop?1:0)}return{x:b,y:c}},scrollIntoView:function(a){var b=this.getParent();if(b){do{(b.$.clientWidth&&b.$.clientWidth<\nb.$.scrollWidth||b.$.clientHeight&&b.$.clientHeight<b.$.scrollHeight)&&!b.is(\"body\")&&this.scrollIntoParent(b,a,1);if(b.is(\"html\")){var c=b.getWindow();try{var e=c.$.frameElement;e&&(b=new CKEDITOR.dom.element(e))}catch(i){}}}while(b=b.getParent())}},scrollIntoParent:function(a,b,c){var e,i,j,o;function q(b,f){if(/body|html/.test(a.getName()))a.getWindow().$.scrollBy(b,f);else{a.$.scrollLeft=a.$.scrollLeft+b;a.$.scrollTop=a.$.scrollTop+f}}function s(a,b){var d={x:0,y:0};if(!a.is(f?\"body\":\"html\")){var c=\na.$.getBoundingClientRect();d.x=c.left;d.y=c.top}c=a.getWindow();if(!c.equals(b)){c=s(CKEDITOR.dom.element.get(c.$.frameElement),b);d.x=d.x+c.x;d.y=d.y+c.y}return d}function u(a,b){return parseInt(a.getComputedStyle(\"margin-\"+b)||0,10)||0}!a&&(a=this.getWindow());j=a.getDocument();var f=j.$.compatMode==\"BackCompat\";a instanceof CKEDITOR.dom.window&&(a=f?j.getBody():j.getDocumentElement());j=a.getWindow();i=s(this,j);var p=s(a,j),y=this.$.offsetHeight;e=this.$.offsetWidth;var m=a.$.clientHeight,k=\na.$.clientWidth;j=i.x-u(this,\"left\")-p.x||0;o=i.y-u(this,\"top\")-p.y||0;e=i.x+e+u(this,\"right\")-(p.x+k)||0;i=i.y+y+u(this,\"bottom\")-(p.y+m)||0;if(o<0||i>0)q(0,b===true?o:b===false?i:o<0?o:i);if(c&&(j<0||e>0))q(j<0?j:e,0)},setState:function(a,b,c){b=b||\"cke\";switch(a){case CKEDITOR.TRISTATE_ON:this.addClass(b+\"_on\");this.removeClass(b+\"_off\");this.removeClass(b+\"_disabled\");c&&this.setAttribute(\"aria-pressed\",true);c&&this.removeAttribute(\"aria-disabled\");break;case CKEDITOR.TRISTATE_DISABLED:this.addClass(b+\n\"_disabled\");this.removeClass(b+\"_off\");this.removeClass(b+\"_on\");c&&this.setAttribute(\"aria-disabled\",true);c&&this.removeAttribute(\"aria-pressed\");break;default:this.addClass(b+\"_off\");this.removeClass(b+\"_on\");this.removeClass(b+\"_disabled\");c&&this.removeAttribute(\"aria-pressed\");c&&this.removeAttribute(\"aria-disabled\")}},getFrameDocument:function(){var a=this.$;try{a.contentWindow.document}catch(b){a.src=a.src}return a&&new CKEDITOR.dom.document(a.contentWindow.document)},copyAttributes:function(a,\nb){for(var c=this.$.attributes,b=b||{},e=0;e<c.length;e++){var i=c[e],j=i.nodeName.toLowerCase(),o;if(!(j in b))if(j==\"checked\"&&(o=this.getAttribute(j)))a.setAttribute(j,o);else if(i.specified||CKEDITOR.env.ie&&i.nodeValue&&j==\"value\"){o=this.getAttribute(j);if(o===null)o=i.nodeValue;a.setAttribute(j,o)}}if(this.$.style.cssText!==\"\")a.$.style.cssText=this.$.style.cssText},renameNode:function(a){if(this.getName()!=a){var b=this.getDocument(),a=new CKEDITOR.dom.element(a,b);this.copyAttributes(a);\nthis.moveChildren(a);this.getParent()&&this.$.parentNode.replaceChild(a.$,this.$);a.$[\"data-cke-expando\"]=this.$[\"data-cke-expando\"];this.$=a.$}},getChild:function(){function a(b,c){var d=b.childNodes;if(c>=0&&c<d.length)return d[c]}return function(b){var c=this.$;if(b.slice)for(;b.length>0&&c;)c=a(c,b.shift());else c=a(c,b);return c?new CKEDITOR.dom.node(c):null}}(),getChildCount:function(){return this.$.childNodes.length},disableContextMenu:function(){this.on(\"contextmenu\",function(a){a.data.getTarget().hasClass(\"cke_enable_context_menu\")||\na.data.preventDefault()})},getDirection:function(a){return a?this.getComputedStyle(\"direction\")||this.getDirection()||this.getParent()&&this.getParent().getDirection(1)||this.getDocument().$.dir||\"ltr\":this.getStyle(\"direction\")||this.getAttribute(\"dir\")},data:function(a,b){a=\"data-\"+a;if(b===void 0)return this.getAttribute(a);b===false?this.removeAttribute(a):this.setAttribute(a,b);return null},getEditor:function(){var a=CKEDITOR.instances,b,c;for(b in a){c=a[b];if(c.element.equals(this)&&c.elementMode!=\nCKEDITOR.ELEMENT_MODE_APPENDTO)return c}return null},find:function(b){var c=a(this),b=new CKEDITOR.dom.nodeList(this.$.querySelectorAll(e(this,b)));c();return b},findOne:function(b){var c=a(this),b=this.$.querySelector(e(this,b));c();return b?new CKEDITOR.dom.element(b):null},forEach:function(a,b,c){if(!c&&(!b||this.type==b))var e=a(this);if(e!==false)for(var c=this.getChildren(),i=0;i<c.count();i++){e=c.getItem(i);e.type==CKEDITOR.NODE_ELEMENT?e.forEach(a,b):(!b||e.type==b)&&a(e)}}});var c={width:[\"border-left-width\",\n\"border-right-width\",\"padding-left\",\"padding-right\"],height:[\"border-top-width\",\"border-bottom-width\",\"padding-top\",\"padding-bottom\"]};CKEDITOR.dom.element.prototype.setSize=function(a,c,e){if(typeof c==\"number\"){if(e&&(!CKEDITOR.env.ie||!CKEDITOR.env.quirks))c=c-b.call(this,a);this.setStyle(a,c+\"px\")}};CKEDITOR.dom.element.prototype.getSize=function(a,c){var e=Math.max(this.$[\"offset\"+CKEDITOR.tools.capitalize(a)],this.$[\"client\"+CKEDITOR.tools.capitalize(a)])||0;c&&(e=e-b.call(this,a));return e}})();\nCKEDITOR.dom.documentFragment=function(a){a=a||CKEDITOR.document;this.$=a.type==CKEDITOR.NODE_DOCUMENT?a.$.createDocumentFragment():a};\nCKEDITOR.tools.extend(CKEDITOR.dom.documentFragment.prototype,CKEDITOR.dom.element.prototype,{type:CKEDITOR.NODE_DOCUMENT_FRAGMENT,insertAfterNode:function(a){a=a.$;a.parentNode.insertBefore(this.$,a.nextSibling)}},!0,{append:1,appendBogus:1,getFirst:1,getLast:1,getParent:1,getNext:1,getPrevious:1,appendTo:1,moveChildren:1,insertBefore:1,insertAfterNode:1,replace:1,trim:1,type:1,ltrim:1,rtrim:1,getDocument:1,getChildCount:1,getChild:1,getChildren:1});\n(function(){function a(a,b){var c=this.range;if(this._.end)return null;if(!this._.start){this._.start=1;if(c.collapsed){this.end();return null}c.optimize()}var f,d=c.startContainer;f=c.endContainer;var o=c.startOffset,e=c.endOffset,k,l=this.guard,t=this.type,h=a?\"getPreviousSourceNode\":\"getNextSourceNode\";if(!a&&!this._.guardLTR){var r=f.type==CKEDITOR.NODE_ELEMENT?f:f.getParent(),i=f.type==CKEDITOR.NODE_ELEMENT?f.getChild(e):f.getNext();this._.guardLTR=function(a,b){return(!b||!r.equals(a))&&(!i||\n!a.equals(i))&&(a.type!=CKEDITOR.NODE_ELEMENT||!b||!a.equals(c.root))}}if(a&&!this._.guardRTL){var g=d.type==CKEDITOR.NODE_ELEMENT?d:d.getParent(),j=d.type==CKEDITOR.NODE_ELEMENT?o?d.getChild(o-1):null:d.getPrevious();this._.guardRTL=function(a,b){return(!b||!g.equals(a))&&(!j||!a.equals(j))&&(a.type!=CKEDITOR.NODE_ELEMENT||!b||!a.equals(c.root))}}var n=a?this._.guardRTL:this._.guardLTR;k=l?function(a,b){return n(a,b)===false?false:l(a,b)}:n;if(this.current)f=this.current[h](false,t,k);else{if(a)f.type==\nCKEDITOR.NODE_ELEMENT&&(f=e>0?f.getChild(e-1):k(f,true)===false?null:f.getPreviousSourceNode(true,t,k));else{f=d;if(f.type==CKEDITOR.NODE_ELEMENT&&!(f=f.getChild(o)))f=k(d,true)===false?null:d.getNextSourceNode(true,t,k)}f&&k(f)===false&&(f=null)}for(;f&&!this._.end;){this.current=f;if(!this.evaluator||this.evaluator(f)!==false){if(!b)return f}else if(b&&this.evaluator)return false;f=f[h](false,t,k)}this.end();return this.current=null}function e(b){for(var c,d=null;c=a.call(this,b);)d=c;return d}\nfunction b(a){if(j(a))return false;if(a.type==CKEDITOR.NODE_TEXT)return true;if(a.type==CKEDITOR.NODE_ELEMENT){if(a.is(CKEDITOR.dtd.$inline)||a.getAttribute(\"contenteditable\")==\"false\")return true;var b;if(b=!CKEDITOR.env.needsBrFiller)if(b=a.is(o))a:{b=0;for(var c=a.getChildCount();b<c;++b)if(!j(a.getChild(b))){b=false;break a}b=true}if(b)return true}return false}CKEDITOR.dom.walker=CKEDITOR.tools.createClass({$:function(a){this.range=a;this._={}},proto:{end:function(){this._.end=1},next:function(){return a.call(this)},\nprevious:function(){return a.call(this,1)},checkForward:function(){return a.call(this,0,1)!==false},checkBackward:function(){return a.call(this,1,1)!==false},lastForward:function(){return e.call(this)},lastBackward:function(){return e.call(this,1)},reset:function(){delete this.current;this._={}}}});var c={block:1,\"list-item\":1,table:1,\"table-row-group\":1,\"table-header-group\":1,\"table-footer-group\":1,\"table-row\":1,\"table-column-group\":1,\"table-column\":1,\"table-cell\":1,\"table-caption\":1},d={absolute:1,\nfixed:1};CKEDITOR.dom.element.prototype.isBlockBoundary=function(a){return this.getComputedStyle(\"float\")==\"none\"&&!(this.getComputedStyle(\"position\")in d)&&c[this.getComputedStyle(\"display\")]?true:!!(this.is(CKEDITOR.dtd.$block)||a&&this.is(a))};CKEDITOR.dom.walker.blockBoundary=function(a){return function(b){return!(b.type==CKEDITOR.NODE_ELEMENT&&b.isBlockBoundary(a))}};CKEDITOR.dom.walker.listItemBoundary=function(){return this.blockBoundary({br:1})};CKEDITOR.dom.walker.bookmark=function(a,b){function c(a){return a&&\na.getName&&a.getName()==\"span\"&&a.data(\"cke-bookmark\")}return function(f){var d,o;d=f&&f.type!=CKEDITOR.NODE_ELEMENT&&(o=f.getParent())&&c(o);d=a?d:d||c(f);return!!(b^d)}};CKEDITOR.dom.walker.whitespaces=function(a){return function(b){var c;b&&b.type==CKEDITOR.NODE_TEXT&&(c=!CKEDITOR.tools.trim(b.getText())||CKEDITOR.env.webkit&&b.getText()==\"​\");return!!(a^c)}};CKEDITOR.dom.walker.invisible=function(a){var b=CKEDITOR.dom.walker.whitespaces();return function(c){if(b(c))c=1;else{c.type==CKEDITOR.NODE_TEXT&&\n(c=c.getParent());c=!c.$.offsetHeight}return!!(a^c)}};CKEDITOR.dom.walker.nodeType=function(a,b){return function(c){return!!(b^c.type==a)}};CKEDITOR.dom.walker.bogus=function(a){function b(a){return!g(a)&&!n(a)}return function(c){var f=CKEDITOR.env.needsBrFiller?c.is&&c.is(\"br\"):c.getText&&h.test(c.getText());if(f){f=c.getParent();c=c.getNext(b);f=f.isBlockBoundary()&&(!c||c.type==CKEDITOR.NODE_ELEMENT&&c.isBlockBoundary())}return!!(a^f)}};CKEDITOR.dom.walker.temp=function(a){return function(b){b.type!=\nCKEDITOR.NODE_ELEMENT&&(b=b.getParent());b=b&&b.hasAttribute(\"data-cke-temp\");return!!(a^b)}};var h=/^[\\t\\r\\n ]*(?:&nbsp;|\\xa0)$/,g=CKEDITOR.dom.walker.whitespaces(),n=CKEDITOR.dom.walker.bookmark(),i=CKEDITOR.dom.walker.temp();CKEDITOR.dom.walker.ignored=function(a){return function(b){b=g(b)||n(b)||i(b);return!!(a^b)}};var j=CKEDITOR.dom.walker.ignored(),o=function(a){var b={},c;for(c in a)CKEDITOR.dtd[c][\"#\"]&&(b[c]=1);return b}(CKEDITOR.dtd.$block);CKEDITOR.dom.walker.editable=function(a){return function(c){return!!(a^\nb(c))}};CKEDITOR.dom.element.prototype.getBogus=function(){var a=this;do a=a.getPreviousSourceNode();while(n(a)||g(a)||a.type==CKEDITOR.NODE_ELEMENT&&a.is(CKEDITOR.dtd.$inline)&&!a.is(CKEDITOR.dtd.$empty));return a&&(CKEDITOR.env.needsBrFiller?a.is&&a.is(\"br\"):a.getText&&h.test(a.getText()))?a:false}})();\nCKEDITOR.dom.range=function(a){this.endOffset=this.endContainer=this.startOffset=this.startContainer=null;this.collapsed=true;var e=a instanceof CKEDITOR.dom.document;this.document=e?a:a.getDocument();this.root=e?a.getBody():a};\n(function(){function a(){var a=false,b=CKEDITOR.dom.walker.whitespaces(),c=CKEDITOR.dom.walker.bookmark(true),d=CKEDITOR.dom.walker.bogus();return function(f){if(c(f)||b(f))return true;if(d(f)&&!a)return a=true;return f.type==CKEDITOR.NODE_TEXT&&(f.hasAscendant(\"pre\")||CKEDITOR.tools.trim(f.getText()).length)||f.type==CKEDITOR.NODE_ELEMENT&&!f.is(h)?false:true}}function e(a){var b=CKEDITOR.dom.walker.whitespaces(),c=CKEDITOR.dom.walker.bookmark(1);return function(d){return c(d)||b(d)?true:!a&&g(d)||\nd.type==CKEDITOR.NODE_ELEMENT&&d.is(CKEDITOR.dtd.$removeEmpty)}}function b(a){return function(){var b;return this[a?\"getPreviousNode\":\"getNextNode\"](function(a){!b&&j(a)&&(b=a);return i(a)&&!(g(a)&&a.equals(b))})}}var c=function(a){a.collapsed=a.startContainer&&a.endContainer&&a.startContainer.equals(a.endContainer)&&a.startOffset==a.endOffset},d=function(a,b,c,d){a.optimizeBookmark();var f=a.startContainer,e=a.endContainer,h=a.startOffset,m=a.endOffset,k,l;if(e.type==CKEDITOR.NODE_TEXT)e=e.split(m);\nelse if(e.getChildCount()>0)if(m>=e.getChildCount()){e=e.append(a.document.createText(\"\"));l=true}else e=e.getChild(m);if(f.type==CKEDITOR.NODE_TEXT){f.split(h);f.equals(e)&&(e=f.getNext())}else if(h)if(h>=f.getChildCount()){f=f.append(a.document.createText(\"\"));k=true}else f=f.getChild(h).getPrevious();else{f=f.append(a.document.createText(\"\"),1);k=true}var h=f.getParents(),m=e.getParents(),t,i,r;for(t=0;t<h.length;t++){i=h[t];r=m[t];if(!i.equals(r))break}for(var g=c,j,n,E,z=t;z<h.length;z++){j=\nh[z];g&&!j.equals(f)&&(n=g.append(j.clone()));for(j=j.getNext();j;){if(j.equals(m[z])||j.equals(e))break;E=j.getNext();if(b==2)g.append(j.clone(true));else{j.remove();b==1&&g.append(j)}j=E}g&&(g=n)}g=c;for(c=t;c<m.length;c++){j=m[c];b>0&&!j.equals(e)&&(n=g.append(j.clone()));if(!h[c]||j.$.parentNode!=h[c].$.parentNode)for(j=j.getPrevious();j;){if(j.equals(h[c])||j.equals(f))break;E=j.getPrevious();if(b==2)g.$.insertBefore(j.$.cloneNode(true),g.$.firstChild);else{j.remove();b==1&&g.$.insertBefore(j.$,\ng.$.firstChild)}j=E}g&&(g=n)}if(b==2){i=a.startContainer;if(i.type==CKEDITOR.NODE_TEXT){i.$.data=i.$.data+i.$.nextSibling.data;i.$.parentNode.removeChild(i.$.nextSibling)}a=a.endContainer;if(a.type==CKEDITOR.NODE_TEXT&&a.$.nextSibling){a.$.data=a.$.data+a.$.nextSibling.data;a.$.parentNode.removeChild(a.$.nextSibling)}}else{if(i&&r&&(f.$.parentNode!=i.$.parentNode||e.$.parentNode!=r.$.parentNode)){b=r.getIndex();k&&r.$.parentNode==f.$.parentNode&&b--;if(d&&i.type==CKEDITOR.NODE_ELEMENT){d=CKEDITOR.dom.element.createFromHtml('<span data-cke-bookmark=\"1\" style=\"display:none\">&nbsp;</span>',\na.document);d.insertAfter(i);i.mergeSiblings(false);a.moveToBookmark({startNode:d})}else a.setStart(r.getParent(),b)}a.collapse(true)}k&&f.remove();l&&e.$.parentNode&&e.remove()},h={abbr:1,acronym:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,\"var\":1},g=CKEDITOR.dom.walker.bogus(),n=/^[\\t\\r\\n ]*(?:&nbsp;|\\xa0)$/,i=CKEDITOR.dom.walker.editable(),j=CKEDITOR.dom.walker.ignored(true);CKEDITOR.dom.range.prototype=\n{clone:function(){var a=new CKEDITOR.dom.range(this.root);a.startContainer=this.startContainer;a.startOffset=this.startOffset;a.endContainer=this.endContainer;a.endOffset=this.endOffset;a.collapsed=this.collapsed;return a},collapse:function(a){if(a){this.endContainer=this.startContainer;this.endOffset=this.startOffset}else{this.startContainer=this.endContainer;this.startOffset=this.endOffset}this.collapsed=true},cloneContents:function(){var a=new CKEDITOR.dom.documentFragment(this.document);this.collapsed||\nd(this,2,a);return a},deleteContents:function(a){this.collapsed||d(this,0,null,a)},extractContents:function(a){var b=new CKEDITOR.dom.documentFragment(this.document);this.collapsed||d(this,1,b,a);return b},createBookmark:function(a){var b,c,d,f,e=this.collapsed;b=this.document.createElement(\"span\");b.data(\"cke-bookmark\",1);b.setStyle(\"display\",\"none\");b.setHtml(\"&nbsp;\");if(a){d=\"cke_bm_\"+CKEDITOR.tools.getNextNumber();b.setAttribute(\"id\",d+(e?\"C\":\"S\"))}if(!e){c=b.clone();c.setHtml(\"&nbsp;\");a&&c.setAttribute(\"id\",\nd+\"E\");f=this.clone();f.collapse();f.insertNode(c)}f=this.clone();f.collapse(true);f.insertNode(b);if(c){this.setStartAfter(b);this.setEndBefore(c)}else this.moveToPosition(b,CKEDITOR.POSITION_AFTER_END);return{startNode:a?d+(e?\"C\":\"S\"):b,endNode:a?d+\"E\":c,serializable:a,collapsed:e}},createBookmark2:function(){function a(b){var c=b.container,d=b.offset,f;f=c;var e=d;f=f.type!=CKEDITOR.NODE_ELEMENT||e===0||e==f.getChildCount()?0:f.getChild(e-1).type==CKEDITOR.NODE_TEXT&&f.getChild(e).type==CKEDITOR.NODE_TEXT;\nif(f){c=c.getChild(d-1);d=c.getLength()}c.type==CKEDITOR.NODE_ELEMENT&&d>1&&(d=c.getChild(d-1).getIndex(true)+1);if(c.type==CKEDITOR.NODE_TEXT){f=c;for(e=0;(f=f.getPrevious())&&f.type==CKEDITOR.NODE_TEXT;)e=e+f.getLength();d=d+e}b.container=c;b.offset=d}return function(b){var c=this.collapsed,d={container:this.startContainer,offset:this.startOffset},f={container:this.endContainer,offset:this.endOffset};if(b){a(d);c||a(f)}return{start:d.container.getAddress(b),end:c?null:f.container.getAddress(b),\nstartOffset:d.offset,endOffset:f.offset,normalized:b,collapsed:c,is2:true}}}(),moveToBookmark:function(a){if(a.is2){var b=this.document.getByAddress(a.start,a.normalized),c=a.startOffset,d=a.end&&this.document.getByAddress(a.end,a.normalized),a=a.endOffset;this.setStart(b,c);d?this.setEnd(d,a):this.collapse(true)}else{b=(c=a.serializable)?this.document.getById(a.startNode):a.startNode;a=c?this.document.getById(a.endNode):a.endNode;this.setStartBefore(b);b.remove();if(a){this.setEndBefore(a);a.remove()}else this.collapse(true)}},\ngetBoundaryNodes:function(){var a=this.startContainer,b=this.endContainer,c=this.startOffset,d=this.endOffset,f;if(a.type==CKEDITOR.NODE_ELEMENT){f=a.getChildCount();if(f>c)a=a.getChild(c);else if(f<1)a=a.getPreviousSourceNode();else{for(a=a.$;a.lastChild;)a=a.lastChild;a=new CKEDITOR.dom.node(a);a=a.getNextSourceNode()||a}}if(b.type==CKEDITOR.NODE_ELEMENT){f=b.getChildCount();if(f>d)b=b.getChild(d).getPreviousSourceNode(true);else if(f<1)b=b.getPreviousSourceNode();else{for(b=b.$;b.lastChild;)b=\nb.lastChild;b=new CKEDITOR.dom.node(b)}}a.getPosition(b)&CKEDITOR.POSITION_FOLLOWING&&(a=b);return{startNode:a,endNode:b}},getCommonAncestor:function(a,b){var c=this.startContainer,d=this.endContainer,c=c.equals(d)?a&&c.type==CKEDITOR.NODE_ELEMENT&&this.startOffset==this.endOffset-1?c.getChild(this.startOffset):c:c.getCommonAncestor(d);return b&&!c.is?c.getParent():c},optimize:function(){var a=this.startContainer,b=this.startOffset;a.type!=CKEDITOR.NODE_ELEMENT&&(b?b>=a.getLength()&&this.setStartAfter(a):\nthis.setStartBefore(a));a=this.endContainer;b=this.endOffset;a.type!=CKEDITOR.NODE_ELEMENT&&(b?b>=a.getLength()&&this.setEndAfter(a):this.setEndBefore(a))},optimizeBookmark:function(){var a=this.startContainer,b=this.endContainer;a.is&&(a.is(\"span\")&&a.data(\"cke-bookmark\"))&&this.setStartAt(a,CKEDITOR.POSITION_BEFORE_START);b&&(b.is&&b.is(\"span\")&&b.data(\"cke-bookmark\"))&&this.setEndAt(b,CKEDITOR.POSITION_AFTER_END)},trim:function(a,b){var c=this.startContainer,d=this.startOffset,f=this.collapsed;\nif((!a||f)&&c&&c.type==CKEDITOR.NODE_TEXT){if(d)if(d>=c.getLength()){d=c.getIndex()+1;c=c.getParent()}else{var e=c.split(d),d=c.getIndex()+1,c=c.getParent();if(this.startContainer.equals(this.endContainer))this.setEnd(e,this.endOffset-this.startOffset);else if(c.equals(this.endContainer))this.endOffset=this.endOffset+1}else{d=c.getIndex();c=c.getParent()}this.setStart(c,d);if(f){this.collapse(true);return}}c=this.endContainer;d=this.endOffset;if(!b&&!f&&c&&c.type==CKEDITOR.NODE_TEXT){if(d){d>=c.getLength()||\nc.split(d);d=c.getIndex()+1}else d=c.getIndex();c=c.getParent();this.setEnd(c,d)}},enlarge:function(a,b){function c(a){return a&&a.type==CKEDITOR.NODE_ELEMENT&&a.hasAttribute(\"contenteditable\")?null:a}switch(a){case CKEDITOR.ENLARGE_INLINE:var d=1;case CKEDITOR.ENLARGE_ELEMENT:if(this.collapsed)break;var f=this.getCommonAncestor(),e=this.root,h,m,k,l,t,i=false,r,j;r=this.startContainer;j=this.startOffset;if(r.type==CKEDITOR.NODE_TEXT){if(j){r=!CKEDITOR.tools.trim(r.substring(0,j)).length&&r;i=!!r}if(r&&\n!(l=r.getPrevious()))k=r.getParent()}else{j&&(l=r.getChild(j-1)||r.getLast());l||(k=r)}for(k=c(k);k||l;){if(k&&!l){!t&&k.equals(f)&&(t=true);if(d?k.isBlockBoundary():!e.contains(k))break;if(!i||k.getComputedStyle(\"display\")!=\"inline\"){i=false;t?h=k:this.setStartBefore(k)}l=k.getPrevious()}for(;l;){r=false;if(l.type==CKEDITOR.NODE_COMMENT)l=l.getPrevious();else{if(l.type==CKEDITOR.NODE_TEXT){j=l.getText();/[^\\s\\ufeff]/.test(j)&&(l=null);r=/[\\s\\ufeff]$/.test(j)}else if((l.$.offsetWidth>0||b&&l.is(\"br\"))&&\n!l.data(\"cke-bookmark\"))if(i&&CKEDITOR.dtd.$removeEmpty[l.getName()]){j=l.getText();if(/[^\\s\\ufeff]/.test(j))l=null;else for(var g=l.$.getElementsByTagName(\"*\"),n=0,E;E=g[n++];)if(!CKEDITOR.dtd.$removeEmpty[E.nodeName.toLowerCase()]){l=null;break}l&&(r=!!j.length)}else l=null;r&&(i?t?h=k:k&&this.setStartBefore(k):i=true);if(l){r=l.getPrevious();if(!k&&!r){k=l;l=null;break}l=r}else k=null}}k&&(k=c(k.getParent()))}r=this.endContainer;j=this.endOffset;k=l=null;t=i=false;if(r.type==CKEDITOR.NODE_TEXT){r=\n!CKEDITOR.tools.trim(r.substring(j)).length&&r;i=!(r&&r.getLength());if(r&&!(l=r.getNext()))k=r.getParent()}else(l=r.getChild(j))||(k=r);for(;k||l;){if(k&&!l){!t&&k.equals(f)&&(t=true);if(d?k.isBlockBoundary():!e.contains(k))break;if(!i||k.getComputedStyle(\"display\")!=\"inline\"){i=false;t?m=k:k&&this.setEndAfter(k)}l=k.getNext()}for(;l;){r=false;if(l.type==CKEDITOR.NODE_TEXT){j=l.getText();/[^\\s\\ufeff]/.test(j)&&(l=null);r=/^[\\s\\ufeff]/.test(j)}else if(l.type==CKEDITOR.NODE_ELEMENT){if((l.$.offsetWidth>\n0||b&&l.is(\"br\"))&&!l.data(\"cke-bookmark\"))if(i&&CKEDITOR.dtd.$removeEmpty[l.getName()]){j=l.getText();if(/[^\\s\\ufeff]/.test(j))l=null;else{g=l.$.getElementsByTagName(\"*\");for(n=0;E=g[n++];)if(!CKEDITOR.dtd.$removeEmpty[E.nodeName.toLowerCase()]){l=null;break}}l&&(r=!!j.length)}else l=null}else r=1;r&&i&&(t?m=k:this.setEndAfter(k));if(l){r=l.getNext();if(!k&&!r){k=l;l=null;break}l=r}else k=null}k&&(k=c(k.getParent()))}if(h&&m){f=h.contains(m)?m:h;this.setStartBefore(f);this.setEndAfter(f)}break;case CKEDITOR.ENLARGE_BLOCK_CONTENTS:case CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:k=\nnew CKEDITOR.dom.range(this.root);e=this.root;k.setStartAt(e,CKEDITOR.POSITION_AFTER_START);k.setEnd(this.startContainer,this.startOffset);k=new CKEDITOR.dom.walker(k);var z,M,Q=CKEDITOR.dom.walker.blockBoundary(a==CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS?{br:1}:null),v=null,w=function(a){if(a.type==CKEDITOR.NODE_ELEMENT&&a.getAttribute(\"contenteditable\")==\"false\")if(v){if(v.equals(a)){v=null;return}}else v=a;else if(v)return;var b=Q(a);b||(z=a);return b},d=function(a){var b=w(a);!b&&(a.is&&a.is(\"br\"))&&\n(M=a);return b};k.guard=w;k=k.lastBackward();z=z||e;this.setStartAt(z,!z.is(\"br\")&&(!k&&this.checkStartOfBlock()||k&&z.contains(k))?CKEDITOR.POSITION_AFTER_START:CKEDITOR.POSITION_AFTER_END);if(a==CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS){k=this.clone();k=new CKEDITOR.dom.walker(k);var H=CKEDITOR.dom.walker.whitespaces(),C=CKEDITOR.dom.walker.bookmark();k.evaluator=function(a){return!H(a)&&!C(a)};if((k=k.previous())&&k.type==CKEDITOR.NODE_ELEMENT&&k.is(\"br\"))break}k=this.clone();k.collapse();k.setEndAt(e,\nCKEDITOR.POSITION_BEFORE_END);k=new CKEDITOR.dom.walker(k);k.guard=a==CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS?d:w;z=null;k=k.lastForward();z=z||e;this.setEndAt(z,!k&&this.checkEndOfBlock()||k&&z.contains(k)?CKEDITOR.POSITION_BEFORE_END:CKEDITOR.POSITION_BEFORE_START);M&&this.setEndAfter(M)}},shrink:function(a,b,c){if(!this.collapsed){var a=a||CKEDITOR.SHRINK_TEXT,d=this.clone(),f=this.startContainer,e=this.endContainer,h=this.startOffset,m=this.endOffset,k=1,l=1;if(f&&f.type==CKEDITOR.NODE_TEXT)if(h)if(h>=\nf.getLength())d.setStartAfter(f);else{d.setStartBefore(f);k=0}else d.setStartBefore(f);if(e&&e.type==CKEDITOR.NODE_TEXT)if(m)if(m>=e.getLength())d.setEndAfter(e);else{d.setEndAfter(e);l=0}else d.setEndBefore(e);var d=new CKEDITOR.dom.walker(d),t=CKEDITOR.dom.walker.bookmark();d.evaluator=function(b){return b.type==(a==CKEDITOR.SHRINK_ELEMENT?CKEDITOR.NODE_ELEMENT:CKEDITOR.NODE_TEXT)};var j;d.guard=function(b,d){if(t(b))return true;if(a==CKEDITOR.SHRINK_ELEMENT&&b.type==CKEDITOR.NODE_TEXT||d&&b.equals(j)||\nc===false&&b.type==CKEDITOR.NODE_ELEMENT&&b.isBlockBoundary()||b.type==CKEDITOR.NODE_ELEMENT&&b.hasAttribute(\"contenteditable\"))return false;!d&&b.type==CKEDITOR.NODE_ELEMENT&&(j=b);return true};if(k)(f=d[a==CKEDITOR.SHRINK_ELEMENT?\"lastForward\":\"next\"]())&&this.setStartAt(f,b?CKEDITOR.POSITION_AFTER_START:CKEDITOR.POSITION_BEFORE_START);if(l){d.reset();(d=d[a==CKEDITOR.SHRINK_ELEMENT?\"lastBackward\":\"previous\"]())&&this.setEndAt(d,b?CKEDITOR.POSITION_BEFORE_END:CKEDITOR.POSITION_AFTER_END)}return!(!k&&\n!l)}},insertNode:function(a){this.optimizeBookmark();this.trim(false,true);var b=this.startContainer,c=b.getChild(this.startOffset);c?a.insertBefore(c):b.append(a);a.getParent()&&a.getParent().equals(this.endContainer)&&this.endOffset++;this.setStartBefore(a)},moveToPosition:function(a,b){this.setStartAt(a,b);this.collapse(true)},moveToRange:function(a){this.setStart(a.startContainer,a.startOffset);this.setEnd(a.endContainer,a.endOffset)},selectNodeContents:function(a){this.setStart(a,0);this.setEnd(a,\na.type==CKEDITOR.NODE_TEXT?a.getLength():a.getChildCount())},setStart:function(a,b){if(a.type==CKEDITOR.NODE_ELEMENT&&CKEDITOR.dtd.$empty[a.getName()]){b=a.getIndex();a=a.getParent()}this.startContainer=a;this.startOffset=b;if(!this.endContainer){this.endContainer=a;this.endOffset=b}c(this)},setEnd:function(a,b){if(a.type==CKEDITOR.NODE_ELEMENT&&CKEDITOR.dtd.$empty[a.getName()]){b=a.getIndex()+1;a=a.getParent()}this.endContainer=a;this.endOffset=b;if(!this.startContainer){this.startContainer=a;this.startOffset=\nb}c(this)},setStartAfter:function(a){this.setStart(a.getParent(),a.getIndex()+1)},setStartBefore:function(a){this.setStart(a.getParent(),a.getIndex())},setEndAfter:function(a){this.setEnd(a.getParent(),a.getIndex()+1)},setEndBefore:function(a){this.setEnd(a.getParent(),a.getIndex())},setStartAt:function(a,b){switch(b){case CKEDITOR.POSITION_AFTER_START:this.setStart(a,0);break;case CKEDITOR.POSITION_BEFORE_END:a.type==CKEDITOR.NODE_TEXT?this.setStart(a,a.getLength()):this.setStart(a,a.getChildCount());\nbreak;case CKEDITOR.POSITION_BEFORE_START:this.setStartBefore(a);break;case CKEDITOR.POSITION_AFTER_END:this.setStartAfter(a)}c(this)},setEndAt:function(a,b){switch(b){case CKEDITOR.POSITION_AFTER_START:this.setEnd(a,0);break;case CKEDITOR.POSITION_BEFORE_END:a.type==CKEDITOR.NODE_TEXT?this.setEnd(a,a.getLength()):this.setEnd(a,a.getChildCount());break;case CKEDITOR.POSITION_BEFORE_START:this.setEndBefore(a);break;case CKEDITOR.POSITION_AFTER_END:this.setEndAfter(a)}c(this)},fixBlock:function(a,b){var c=\nthis.createBookmark(),d=this.document.createElement(b);this.collapse(a);this.enlarge(CKEDITOR.ENLARGE_BLOCK_CONTENTS);this.extractContents().appendTo(d);d.trim();d.appendBogus();this.insertNode(d);this.moveToBookmark(c);return d},splitBlock:function(a){var b=new CKEDITOR.dom.elementPath(this.startContainer,this.root),c=new CKEDITOR.dom.elementPath(this.endContainer,this.root),d=b.block,f=c.block,e=null;if(!b.blockLimit.equals(c.blockLimit))return null;if(a!=\"br\"){if(!d){d=this.fixBlock(true,a);f=\n(new CKEDITOR.dom.elementPath(this.endContainer,this.root)).block}f||(f=this.fixBlock(false,a))}a=d&&this.checkStartOfBlock();b=f&&this.checkEndOfBlock();this.deleteContents();if(d&&d.equals(f))if(b){e=new CKEDITOR.dom.elementPath(this.startContainer,this.root);this.moveToPosition(f,CKEDITOR.POSITION_AFTER_END);f=null}else if(a){e=new CKEDITOR.dom.elementPath(this.startContainer,this.root);this.moveToPosition(d,CKEDITOR.POSITION_BEFORE_START);d=null}else{f=this.splitElement(d);d.is(\"ul\",\"ol\")||d.appendBogus()}return{previousBlock:d,\nnextBlock:f,wasStartOfBlock:a,wasEndOfBlock:b,elementPath:e}},splitElement:function(a){if(!this.collapsed)return null;this.setEndAt(a,CKEDITOR.POSITION_BEFORE_END);var b=this.extractContents(),c=a.clone(false);b.appendTo(c);c.insertAfter(a);this.moveToPosition(a,CKEDITOR.POSITION_AFTER_END);return c},removeEmptyBlocksAtEnd:function(){function a(d){return function(a){return b(a)||(c(a)||a.type==CKEDITOR.NODE_ELEMENT&&a.isEmptyInlineRemoveable())||d.is(\"table\")&&a.is(\"caption\")?false:true}}var b=CKEDITOR.dom.walker.whitespaces(),\nc=CKEDITOR.dom.walker.bookmark(false);return function(b){for(var c=this.createBookmark(),d=this[b?\"endPath\":\"startPath\"](),e=d.block||d.blockLimit,m;e&&!e.equals(d.root)&&!e.getFirst(a(e));){m=e.getParent();this[b?\"setEndAt\":\"setStartAt\"](e,CKEDITOR.POSITION_AFTER_END);e.remove(1);e=m}this.moveToBookmark(c)}}(),startPath:function(){return new CKEDITOR.dom.elementPath(this.startContainer,this.root)},endPath:function(){return new CKEDITOR.dom.elementPath(this.endContainer,this.root)},checkBoundaryOfElement:function(a,\nb){var c=b==CKEDITOR.START,d=this.clone();d.collapse(c);d[c?\"setStartAt\":\"setEndAt\"](a,c?CKEDITOR.POSITION_AFTER_START:CKEDITOR.POSITION_BEFORE_END);d=new CKEDITOR.dom.walker(d);d.evaluator=e(c);return d[c?\"checkBackward\":\"checkForward\"]()},checkStartOfBlock:function(){var b=this.startContainer,c=this.startOffset;if(CKEDITOR.env.ie&&c&&b.type==CKEDITOR.NODE_TEXT){b=CKEDITOR.tools.ltrim(b.substring(0,c));n.test(b)&&this.trim(0,1)}this.trim();b=new CKEDITOR.dom.elementPath(this.startContainer,this.root);\nc=this.clone();c.collapse(true);c.setStartAt(b.block||b.blockLimit,CKEDITOR.POSITION_AFTER_START);b=new CKEDITOR.dom.walker(c);b.evaluator=a();return b.checkBackward()},checkEndOfBlock:function(){var b=this.endContainer,c=this.endOffset;if(CKEDITOR.env.ie&&b.type==CKEDITOR.NODE_TEXT){b=CKEDITOR.tools.rtrim(b.substring(c));n.test(b)&&this.trim(1,0)}this.trim();b=new CKEDITOR.dom.elementPath(this.endContainer,this.root);c=this.clone();c.collapse(false);c.setEndAt(b.block||b.blockLimit,CKEDITOR.POSITION_BEFORE_END);\nb=new CKEDITOR.dom.walker(c);b.evaluator=a();return b.checkForward()},getPreviousNode:function(a,b,c){var d=this.clone();d.collapse(1);d.setStartAt(c||this.root,CKEDITOR.POSITION_AFTER_START);c=new CKEDITOR.dom.walker(d);c.evaluator=a;c.guard=b;return c.previous()},getNextNode:function(a,b,c){var d=this.clone();d.collapse();d.setEndAt(c||this.root,CKEDITOR.POSITION_BEFORE_END);c=new CKEDITOR.dom.walker(d);c.evaluator=a;c.guard=b;return c.next()},checkReadOnly:function(){function a(b,c){for(;b;){if(b.type==\nCKEDITOR.NODE_ELEMENT){if(b.getAttribute(\"contentEditable\")==\"false\"&&!b.data(\"cke-editable\"))return 0;if(b.is(\"html\")||b.getAttribute(\"contentEditable\")==\"true\"&&(b.contains(c)||b.equals(c)))break}b=b.getParent()}return 1}return function(){var b=this.startContainer,c=this.endContainer;return!(a(b,c)&&a(c,b))}}(),moveToElementEditablePosition:function(a,b){if(a.type==CKEDITOR.NODE_ELEMENT&&!a.isEditable(false)){this.moveToPosition(a,b?CKEDITOR.POSITION_AFTER_END:CKEDITOR.POSITION_BEFORE_START);return true}for(var c=\n0;a;){if(a.type==CKEDITOR.NODE_TEXT){b&&this.endContainer&&this.checkEndOfBlock()&&n.test(a.getText())?this.moveToPosition(a,CKEDITOR.POSITION_BEFORE_START):this.moveToPosition(a,b?CKEDITOR.POSITION_AFTER_END:CKEDITOR.POSITION_BEFORE_START);c=1;break}if(a.type==CKEDITOR.NODE_ELEMENT)if(a.isEditable()){this.moveToPosition(a,b?CKEDITOR.POSITION_BEFORE_END:CKEDITOR.POSITION_AFTER_START);c=1}else if(b&&a.is(\"br\")&&this.endContainer&&this.checkEndOfBlock())this.moveToPosition(a,CKEDITOR.POSITION_BEFORE_START);\nelse if(a.getAttribute(\"contenteditable\")==\"false\"&&a.is(CKEDITOR.dtd.$block)){this.setStartBefore(a);this.setEndAfter(a);return true}var d=a,f=c,e=void 0;d.type==CKEDITOR.NODE_ELEMENT&&d.isEditable(false)&&(e=d[b?\"getLast\":\"getFirst\"](j));!f&&!e&&(e=d[b?\"getPrevious\":\"getNext\"](j));a=e}return!!c},moveToClosestEditablePosition:function(a,b){var c=new CKEDITOR.dom.range(this.root),d=0,f,e=[CKEDITOR.POSITION_AFTER_END,CKEDITOR.POSITION_BEFORE_START];c.moveToPosition(a,e[b?0:1]);if(a.is(CKEDITOR.dtd.$block)){if(f=\nc[b?\"getNextEditableNode\":\"getPreviousEditableNode\"]()){d=1;if(f.type==CKEDITOR.NODE_ELEMENT&&f.is(CKEDITOR.dtd.$block)&&f.getAttribute(\"contenteditable\")==\"false\"){c.setStartAt(f,CKEDITOR.POSITION_BEFORE_START);c.setEndAt(f,CKEDITOR.POSITION_AFTER_END)}else c.moveToPosition(f,e[b?1:0])}}else d=1;d&&this.moveToRange(c);return!!d},moveToElementEditStart:function(a){return this.moveToElementEditablePosition(a)},moveToElementEditEnd:function(a){return this.moveToElementEditablePosition(a,true)},getEnclosedNode:function(){var a=\nthis.clone();a.optimize();if(a.startContainer.type!=CKEDITOR.NODE_ELEMENT||a.endContainer.type!=CKEDITOR.NODE_ELEMENT)return null;var a=new CKEDITOR.dom.walker(a),b=CKEDITOR.dom.walker.bookmark(false,true),c=CKEDITOR.dom.walker.whitespaces(true);a.evaluator=function(a){return c(a)&&b(a)};var d=a.next();a.reset();return d&&d.equals(a.previous())?d:null},getTouchedStartNode:function(){var a=this.startContainer;return this.collapsed||a.type!=CKEDITOR.NODE_ELEMENT?a:a.getChild(this.startOffset)||a},getTouchedEndNode:function(){var a=\nthis.endContainer;return this.collapsed||a.type!=CKEDITOR.NODE_ELEMENT?a:a.getChild(this.endOffset-1)||a},getNextEditableNode:b(),getPreviousEditableNode:b(1),scrollIntoView:function(){var a=new CKEDITOR.dom.element.createFromHtml(\"<span>&nbsp;</span>\",this.document),b,c,d,f=this.clone();f.optimize();if(d=f.startContainer.type==CKEDITOR.NODE_TEXT){c=f.startContainer.getText();b=f.startContainer.split(f.startOffset);a.insertAfter(f.startContainer)}else f.insertNode(a);a.scrollIntoView();if(d){f.startContainer.setText(c);\nb.remove()}a.remove()}}})();CKEDITOR.POSITION_AFTER_START=1;CKEDITOR.POSITION_BEFORE_END=2;CKEDITOR.POSITION_BEFORE_START=3;CKEDITOR.POSITION_AFTER_END=4;CKEDITOR.ENLARGE_ELEMENT=1;CKEDITOR.ENLARGE_BLOCK_CONTENTS=2;CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS=3;CKEDITOR.ENLARGE_INLINE=4;CKEDITOR.START=1;CKEDITOR.END=2;CKEDITOR.SHRINK_ELEMENT=1;CKEDITOR.SHRINK_TEXT=2;\"use strict\";\n(function(){function a(a){if(!(arguments.length<1)){this.range=a;this.forceBrBreak=0;this.enlargeBr=1;this.enforceRealBlocks=0;this._||(this._={})}}function e(a,b,c){for(a=a.getNextSourceNode(b,null,c);!h(a);)a=a.getNextSourceNode(b,null,c);return a}function b(a){var b=[];a.forEach(function(a){if(a.getAttribute(\"contenteditable\")==\"true\"){b.push(a);return false}},CKEDITOR.NODE_ELEMENT,true);return b}function c(a,d,e,h){a:{h==void 0&&(h=b(e));for(var g;g=h.shift();)if(g.getDtd().p){h={element:g,remaining:h};\nbreak a}h=null}if(!h)return 0;if((g=CKEDITOR.filter.instances[h.element.data(\"cke-filter\")])&&!g.check(d))return c(a,d,e,h.remaining);d=new CKEDITOR.dom.range(h.element);d.selectNodeContents(h.element);d=d.createIterator();d.enlargeBr=a.enlargeBr;d.enforceRealBlocks=a.enforceRealBlocks;d.activeFilter=d.filter=g;a._.nestedEditable={element:h.element,container:e,remaining:h.remaining,iterator:d};return 1}var d=/^[\\r\\n\\t ]+$/,h=CKEDITOR.dom.walker.bookmark(false,true),g=CKEDITOR.dom.walker.whitespaces(true),\nn=function(a){return h(a)&&g(a)};a.prototype={getNextParagraph:function(a){var b,g,q,s,u,a=a||\"p\";if(this._.nestedEditable){if(b=this._.nestedEditable.iterator.getNextParagraph(a)){this.activeFilter=this._.nestedEditable.iterator.activeFilter;return b}this.activeFilter=this.filter;if(c(this,a,this._.nestedEditable.container,this._.nestedEditable.remaining)){this.activeFilter=this._.nestedEditable.iterator.activeFilter;return this._.nestedEditable.iterator.getNextParagraph(a)}this._.nestedEditable=\nnull}if(!this.range.root.getDtd()[a])return null;if(!this._.started){var f=this.range.clone();f.shrink(CKEDITOR.SHRINK_ELEMENT,true);g=f.endContainer.hasAscendant(\"pre\",true)||f.startContainer.hasAscendant(\"pre\",true);f.enlarge(this.forceBrBreak&&!g||!this.enlargeBr?CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:CKEDITOR.ENLARGE_BLOCK_CONTENTS);if(!f.collapsed){g=new CKEDITOR.dom.walker(f.clone());var p=CKEDITOR.dom.walker.bookmark(true,true);g.evaluator=p;this._.nextNode=g.next();g=new CKEDITOR.dom.walker(f.clone());\ng.evaluator=p;g=g.previous();this._.lastNode=g.getNextSourceNode(true);if(this._.lastNode&&this._.lastNode.type==CKEDITOR.NODE_TEXT&&!CKEDITOR.tools.trim(this._.lastNode.getText())&&this._.lastNode.getParent().isBlockBoundary()){p=this.range.clone();p.moveToPosition(this._.lastNode,CKEDITOR.POSITION_AFTER_END);if(p.checkEndOfBlock()){p=new CKEDITOR.dom.elementPath(p.endContainer,p.root);this._.lastNode=(p.block||p.blockLimit).getNextSourceNode(true)}}if(!this._.lastNode||!f.root.contains(this._.lastNode)){this._.lastNode=\nthis._.docEndMarker=f.document.createText(\"\");this._.lastNode.insertAfter(g)}f=null}this._.started=1;g=f}p=this._.nextNode;f=this._.lastNode;for(this._.nextNode=null;p;){var y=0,m=p.hasAscendant(\"pre\"),k=p.type!=CKEDITOR.NODE_ELEMENT,l=0;if(k)p.type==CKEDITOR.NODE_TEXT&&d.test(p.getText())&&(k=0);else{var t=p.getName();if(CKEDITOR.dtd.$block[t]&&p.getAttribute(\"contenteditable\")==\"false\"){b=p;c(this,a,b);break}else if(p.isBlockBoundary(this.forceBrBreak&&!m&&{br:1})){if(t==\"br\")k=1;else if(!g&&!p.getChildCount()&&\nt!=\"hr\"){b=p;q=p.equals(f);break}if(g){g.setEndAt(p,CKEDITOR.POSITION_BEFORE_START);if(t!=\"br\")this._.nextNode=p}y=1}else{if(p.getFirst()){if(!g){g=this.range.clone();g.setStartAt(p,CKEDITOR.POSITION_BEFORE_START)}p=p.getFirst();continue}k=1}}if(k&&!g){g=this.range.clone();g.setStartAt(p,CKEDITOR.POSITION_BEFORE_START)}q=(!y||k)&&p.equals(f);if(g&&!y)for(;!p.getNext(n)&&!q;){t=p.getParent();if(t.isBlockBoundary(this.forceBrBreak&&!m&&{br:1})){y=1;k=0;q||t.equals(f);g.setEndAt(t,CKEDITOR.POSITION_BEFORE_END);\nbreak}p=t;k=1;q=p.equals(f);l=1}k&&g.setEndAt(p,CKEDITOR.POSITION_AFTER_END);p=e(p,l,f);if((q=!p)||y&&g)break}if(!b){if(!g){this._.docEndMarker&&this._.docEndMarker.remove();return this._.nextNode=null}b=new CKEDITOR.dom.elementPath(g.startContainer,g.root);p=b.blockLimit;y={div:1,th:1,td:1};b=b.block;if(!b&&p&&!this.enforceRealBlocks&&y[p.getName()]&&g.checkStartOfBlock()&&g.checkEndOfBlock()&&!p.equals(g.root))b=p;else if(!b||this.enforceRealBlocks&&b.getName()==\"li\"){b=this.range.document.createElement(a);\ng.extractContents().appendTo(b);b.trim();g.insertNode(b);s=u=true}else if(b.getName()!=\"li\"){if(!g.checkStartOfBlock()||!g.checkEndOfBlock()){b=b.clone(false);g.extractContents().appendTo(b);b.trim();u=g.splitBlock();s=!u.wasStartOfBlock;u=!u.wasEndOfBlock;g.insertNode(b)}}else if(!q)this._.nextNode=b.equals(f)?null:e(g.getBoundaryNodes().endNode,1,f)}if(s)(s=b.getPrevious())&&s.type==CKEDITOR.NODE_ELEMENT&&(s.getName()==\"br\"?s.remove():s.getLast()&&s.getLast().$.nodeName.toLowerCase()==\"br\"&&s.getLast().remove());\nif(u)(s=b.getLast())&&s.type==CKEDITOR.NODE_ELEMENT&&s.getName()==\"br\"&&(!CKEDITOR.env.needsBrFiller||s.getPrevious(h)||s.getNext(h))&&s.remove();if(!this._.nextNode)this._.nextNode=q||b.equals(f)||!f?null:e(b,1,f);return b}};CKEDITOR.dom.range.prototype.createIterator=function(){return new a(this)}})();\nCKEDITOR.command=function(a,e){this.uiItems=[];this.exec=function(b){if(this.state==CKEDITOR.TRISTATE_DISABLED||!this.checkAllowed())return false;this.editorFocus&&a.focus();return this.fire(\"exec\")===false?true:e.exec.call(this,a,b)!==false};this.refresh=function(a,b){if(!this.readOnly&&a.readOnly)return true;if(this.context&&!b.isContextFor(this.context)){this.disable();return true}if(!this.checkAllowed(true)){this.disable();return true}this.startDisabled||this.enable();this.modes&&!this.modes[a.mode]&&\nthis.disable();return this.fire(\"refresh\",{editor:a,path:b})===false?true:e.refresh&&e.refresh.apply(this,arguments)!==false};var b;this.checkAllowed=function(c){return!c&&typeof b==\"boolean\"?b:b=a.activeFilter.checkFeature(this)};CKEDITOR.tools.extend(this,e,{modes:{wysiwyg:1},editorFocus:1,contextSensitive:!!e.context,state:CKEDITOR.TRISTATE_DISABLED});CKEDITOR.event.call(this)};\nCKEDITOR.command.prototype={enable:function(){this.state==CKEDITOR.TRISTATE_DISABLED&&this.checkAllowed()&&this.setState(!this.preserveState||typeof this.previousState==\"undefined\"?CKEDITOR.TRISTATE_OFF:this.previousState)},disable:function(){this.setState(CKEDITOR.TRISTATE_DISABLED)},setState:function(a){if(this.state==a||a!=CKEDITOR.TRISTATE_DISABLED&&!this.checkAllowed())return false;this.previousState=this.state;this.state=a;this.fire(\"state\");return true},toggleState:function(){this.state==CKEDITOR.TRISTATE_OFF?\nthis.setState(CKEDITOR.TRISTATE_ON):this.state==CKEDITOR.TRISTATE_ON&&this.setState(CKEDITOR.TRISTATE_OFF)}};CKEDITOR.event.implementOn(CKEDITOR.command.prototype);CKEDITOR.ENTER_P=1;CKEDITOR.ENTER_BR=2;CKEDITOR.ENTER_DIV=3;\nCKEDITOR.config={customConfig:\"config.js\",autoUpdateElement:!0,language:\"\",defaultLanguage:\"en\",contentsLangDirection:\"\",enterMode:CKEDITOR.ENTER_P,forceEnterMode:!1,shiftEnterMode:CKEDITOR.ENTER_BR,docType:\"<!DOCTYPE html>\",bodyId:\"\",bodyClass:\"\",fullPage:!1,height:200,extraPlugins:\"\",removePlugins:\"\",protectedSource:[],tabIndex:0,width:\"\",baseFloatZIndex:1E4,blockedKeystrokes:[CKEDITOR.CTRL+66,CKEDITOR.CTRL+73,CKEDITOR.CTRL+85]};\n(function(){function a(a,b,c,f,k){var m=b.name;if((f||typeof a.elements!=\"function\"||a.elements(m))&&(!a.match||a.match(b))){if(f=!k){a:if(a.nothingRequired)f=true;else{if(k=a.requiredClasses){m=b.classes;for(f=0;f<k.length;++f)if(CKEDITOR.tools.indexOf(m,k[f])==-1){f=false;break a}}f=d(b.styles,a.requiredStyles)&&d(b.attributes,a.requiredAttributes)}f=!f}if(!f){if(!a.propertiesOnly)c.valid=true;if(!c.allAttributes)c.allAttributes=e(a.attributes,b.attributes,c.validAttributes);if(!c.allStyles)c.allStyles=\ne(a.styles,b.styles,c.validStyles);if(!c.allClasses){a=a.classes;b=b.classes;f=c.validClasses;if(a)if(a===true)b=true;else{for(var k=0,m=b.length,l;k<m;++k){l=b[k];f[l]||(f[l]=a(l))}b=false}else b=false;c.allClasses=b}}}}function e(a,b,c){if(!a)return false;if(a===true)return true;for(var d in b)c[d]||(c[d]=a(d,b[d]));return false}function b(a,b){if(!a)return false;if(a===true)return a;if(typeof a==\"string\"){a=r(a);return a==\"*\"?true:CKEDITOR.tools.convertArrayToObject(a.split(b))}if(CKEDITOR.tools.isArray(a))return a.length?\nCKEDITOR.tools.convertArrayToObject(a):false;var c={},d=0,f;for(f in a){c[f]=a[f];d++}return d?c:false}function c(b){if(b._.filterFunction)return b._.filterFunction;var c=/^cke:(object|embed|param)$/,d=/^(object|embed|param)$/;return b._.filterFunction=function(f,e,k,m,l,h,t){var g=f.name,r,y=false;if(l)f.name=g=g.replace(c,\"$1\");if(k=k&&k[g]){i(f);for(g=0;g<k.length;++g)p(b,f,k[g]);j(f)}if(e){var g=f.name,k=e.elements[g],x=e.generic,e={valid:false,validAttributes:{},validClasses:{},validStyles:{},\nallAttributes:false,allClasses:false,allStyles:false};if(!k&&!x){m.push(f);return true}i(f);if(k){g=0;for(r=k.length;g<r;++g)a(k[g],f,e,true,h)}if(x){g=0;for(r=x.length;g<r;++g)a(x[g],f,e,false,h)}if(!e.valid){m.push(f);return true}h=e.validAttributes;g=e.validStyles;k=e.validClasses;r=f.attributes;var x=f.styles,n=r[\"class\"],L=r.style,A,z,E=[],I=[],s=/^data-cke-/,q=false;delete r.style;delete r[\"class\"];if(!e.allAttributes)for(A in r)if(!h[A])if(s.test(A)){if(A!=(z=A.replace(/^data-cke-saved-/,\"\"))&&\n!h[z]){delete r[A];q=true}}else{delete r[A];q=true}if(e.allStyles){if(L)r.style=L}else{for(A in x)g[A]?E.push(A+\":\"+x[A]):q=true;if(E.length)r.style=E.sort().join(\"; \")}if(e.allClasses)n&&(r[\"class\"]=n);else{for(A in k)k[A]&&I.push(A);I.length&&(r[\"class\"]=I.sort().join(\" \"));n&&I.length<n.split(/\\s+/).length&&(q=true)}q&&(y=true);if(!t&&!o(f)){m.push(f);return true}}if(l)f.name=f.name.replace(d,\"cke:$1\");return y}}function d(a,b){if(!b)return true;for(var c=0;c<b.length;++c)if(!(b[c]in a))return false;\nreturn true}function h(a){if(!a)return{};for(var a=a.split(/\\s*,\\s*/).sort(),b={};a.length;)b[a.shift()]=L;return b}function g(a){for(var b,c,d,f,e={},k=1,a=r(a);b=a.match(z);){if(c=b[2]){d=n(c,\"styles\");f=n(c,\"attrs\");c=n(c,\"classes\")}else d=f=c=null;e[\"$\"+k++]={elements:b[1],classes:c,styles:d,attributes:f};a=a.slice(b[0].length)}return e}function n(a,b){var c=a.match(M[b]);return c?r(c[1]):null}function i(a){if(!a.styles)a.styles=CKEDITOR.tools.parseCssText(a.attributes.style||\"\",1);if(!a.classes)a.classes=\na.attributes[\"class\"]?a.attributes[\"class\"].split(/\\s+/):[]}function j(a){var b=a.attributes,c;delete b.style;delete b[\"class\"];if(c=CKEDITOR.tools.writeCssText(a.styles,true))b.style=c;a.classes.length&&(b[\"class\"]=a.classes.sort().join(\" \"))}function o(a){switch(a.name){case \"a\":if(!a.children.length&&!a.attributes.name)return false;break;case \"img\":if(!a.attributes.src)return false}return true}function q(a){return!a?false:a===true?true:function(b){return b in a}}function s(){return new CKEDITOR.htmlParser.element(\"br\")}\nfunction u(a){return a.type==CKEDITOR.NODE_ELEMENT&&(a.name==\"br\"||t.$block[a.name])}function f(a,b,c){var d=a.name;if(t.$empty[d]||!a.children.length)if(d==\"hr\"&&b==\"br\")a.replaceWith(s());else{a.parent&&c.push({check:\"it\",el:a.parent});a.remove()}else if(t.$block[d]||d==\"tr\")if(b==\"br\"){if(a.previous&&!u(a.previous)){b=s();b.insertBefore(a)}if(a.next&&!u(a.next)){b=s();b.insertAfter(a)}a.replaceWithChildren()}else{var d=a.children,f;b:{f=t[b];for(var e=0,k=d.length,m;e<k;++e){m=d[e];if(m.type==\nCKEDITOR.NODE_ELEMENT&&!f[m.name]){f=false;break b}}f=true}if(f){a.name=b;a.attributes={};c.push({check:\"parent-down\",el:a})}else{f=a.parent;for(var e=f.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT||f.name==\"body\",l,k=d.length;k>0;){m=d[--k];if(e&&(m.type==CKEDITOR.NODE_TEXT||m.type==CKEDITOR.NODE_ELEMENT&&t.$inline[m.name])){if(!l){l=new CKEDITOR.htmlParser.element(b);l.insertAfter(a);c.push({check:\"parent-down\",el:l})}l.add(m,0)}else{l=null;m.insertAfter(a);f.type!=CKEDITOR.NODE_DOCUMENT_FRAGMENT&&(m.type==\nCKEDITOR.NODE_ELEMENT&&!t[f.name][m.name])&&c.push({check:\"el-up\",el:m})}}a.remove()}}else if(d==\"style\")a.remove();else{a.parent&&c.push({check:\"it\",el:a.parent});a.replaceWithChildren()}}function p(a,b,c){var d,f;for(d=0;d<c.length;++d){f=c[d];if((!f.check||a.check(f.check,false))&&(!f.left||f.left(b))){f.right(b,Q);break}}}function y(a,b){var c=b.getDefinition(),d=c.attributes,f=c.styles,e,k,m,l;if(a.name!=c.element)return false;for(e in d)if(e==\"class\"){c=d[e].split(/\\s+/);for(m=a.classes.join(\"|\");l=\nc.pop();)if(m.indexOf(l)==-1)return false}else if(a.attributes[e]!=d[e])return false;for(k in f)if(a.styles[k]!=f[k])return false;return true}function m(a,b){var c,d;if(typeof a==\"string\")c=a;else if(a instanceof CKEDITOR.style)d=a;else{c=a[0];d=a[1]}return[{element:c,left:d,right:function(a,c){c.transform(a,b)}}]}function k(a){return function(b){return y(b,a)}}function l(a){return function(b,c){c[a](b)}}var t=CKEDITOR.dtd,x=CKEDITOR.tools.copy,r=CKEDITOR.tools.trim,L=\"cke-test\",A=[\"\",\"p\",\"br\",\"div\"];\nCKEDITOR.filter=function(a){this.allowedContent=[];this.disabled=false;this.editor=null;this.id=CKEDITOR.tools.getNextNumber();this._={rules:{},transformations:{},cachedTests:{}};CKEDITOR.filter.instances[this.id]=this;if(a instanceof CKEDITOR.editor){a=this.editor=a;this.customConfig=true;var b=a.config.allowedContent;if(b===true)this.disabled=true;else{if(!b)this.customConfig=false;this.allow(b,\"config\",1);this.allow(a.config.extraAllowedContent,\"extra\",1);this.allow(A[a.enterMode]+\" \"+A[a.shiftEnterMode],\n\"default\",1)}}else{this.customConfig=false;this.allow(a,\"default\",1)}};CKEDITOR.filter.instances={};CKEDITOR.filter.prototype={allow:function(a,c,d){if(this.disabled||this.customConfig&&!d||!a)return false;this._.cachedChecks={};var f,e;if(typeof a==\"string\")a=g(a);else if(a instanceof CKEDITOR.style){e=a.getDefinition();d={};a=e.attributes;d[e.element]=e={styles:e.styles,requiredStyles:e.styles&&CKEDITOR.tools.objectKeys(e.styles)};if(a){a=x(a);e.classes=a[\"class\"]?a[\"class\"].split(/\\s+/):null;e.requiredClasses=\ne.classes;delete a[\"class\"];e.attributes=a;e.requiredAttributes=a&&CKEDITOR.tools.objectKeys(a)}a=d}else if(CKEDITOR.tools.isArray(a)){for(f=0;f<a.length;++f)e=this.allow(a[f],c,d);return e}var k,d=[];for(k in a){e=a[k];e=typeof e==\"boolean\"?{}:typeof e==\"function\"?{match:e}:x(e);if(k.charAt(0)!=\"$\")e.elements=k;if(c)e.featureName=c.toLowerCase();var m=e;m.elements=b(m.elements,/\\s+/)||null;m.propertiesOnly=m.propertiesOnly||m.elements===true;var l=/\\s*,\\s*/,h=void 0;for(h in I){m[h]=b(m[h],l)||null;\nvar p=m,t=E[h],r=b(m[E[h]],l),i=m[h],j=[],y=true,n=void 0;r?y=false:r={};for(n in i)if(n.charAt(0)==\"!\"){n=n.slice(1);j.push(n);r[n]=true;y=false}for(;n=j.pop();){i[n]=i[\"!\"+n];delete i[\"!\"+n]}p[t]=(y?false:r)||null}m.match=m.match||null;this.allowedContent.push(e);d.push(e)}c=this._.rules;k=c.elements||{};a=c.generic||[];e=0;for(m=d.length;e<m;++e){l=x(d[e]);h=l.classes===true||l.styles===true||l.attributes===true;p=l;t=void 0;for(t in I)p[t]=q(p[t]);r=true;for(t in E){t=E[t];p[t]=CKEDITOR.tools.objectKeys(p[t]);\np[t]&&(r=false)}p.nothingRequired=r;if(l.elements===true||l.elements===null){l.elements=q(l.elements);a[h?\"unshift\":\"push\"](l)}else{p=l.elements;delete l.elements;for(f in p)if(k[f])k[f][h?\"unshift\":\"push\"](l);else k[f]=[l]}}c.elements=k;c.generic=a.length?a:null;return true},applyTo:function(a,b,d,e){if(this.disabled)return false;var k=[],m=!d&&this._.rules,l=this._.transformations,h=c(this),p=this.editor&&this.editor.config.protectedSource,g=false;a.forEach(function(a){if(a.type==CKEDITOR.NODE_ELEMENT){if(a.attributes[\"data-cke-filter\"]==\n\"off\")return false;if(!b||!(a.name==\"span\"&&~CKEDITOR.tools.objectKeys(a.attributes).join(\"|\").indexOf(\"data-cke-\")))h(a,m,l,k,b)&&(g=true)}else if(a.type==CKEDITOR.NODE_COMMENT&&a.value.match(/^\\{cke_protected\\}(?!\\{C\\})/)){var c;a:{var d=decodeURIComponent(a.value.replace(/^\\{cke_protected\\}/,\"\"));c=[];var f,e,C;if(p)for(e=0;e<p.length;++e)if((C=d.match(p[e]))&&C[0].length==d.length){c=true;break a}d=CKEDITOR.htmlParser.fragment.fromHtml(d);d.children.length==1&&(f=d.children[0]).type==CKEDITOR.NODE_ELEMENT&&\nh(f,m,l,c,b);c=!c.length}c||k.push(a)}},null,true);k.length&&(g=true);for(var r,a=[],e=A[e||(this.editor?this.editor.enterMode:CKEDITOR.ENTER_P)];d=k.pop();)d.type==CKEDITOR.NODE_ELEMENT?f(d,e,a):d.remove();for(;r=a.pop();){d=r.el;if(d.parent)switch(r.check){case \"it\":t.$removeEmpty[d.name]&&!d.children.length?f(d,e,a):o(d)||f(d,e,a);break;case \"el-up\":d.parent.type!=CKEDITOR.NODE_DOCUMENT_FRAGMENT&&!t[d.parent.name][d.name]&&f(d,e,a);break;case \"parent-down\":d.parent.type!=CKEDITOR.NODE_DOCUMENT_FRAGMENT&&\n!t[d.parent.name][d.name]&&f(d.parent,e,a)}}return g},checkFeature:function(a){if(this.disabled||!a)return true;a.toFeature&&(a=a.toFeature(this.editor));return!a.requiredContent||this.check(a.requiredContent)},disable:function(){this.disabled=true},addContentForms:function(a){if(!this.disabled&&a){var b,c,d=[],f;for(b=0;b<a.length&&!f;++b){c=a[b];if((typeof c==\"string\"||c instanceof CKEDITOR.style)&&this.check(c))f=c}if(f){for(b=0;b<a.length;++b)d.push(m(a[b],f));this.addTransformations(d)}}},addFeature:function(a){if(this.disabled||\n!a)return true;a.toFeature&&(a=a.toFeature(this.editor));this.allow(a.allowedContent,a.name);this.addTransformations(a.contentTransformations);this.addContentForms(a.contentForms);return this.customConfig&&a.requiredContent?this.check(a.requiredContent):true},addTransformations:function(a){var b,c;if(!this.disabled&&a){var d=this._.transformations,f;for(f=0;f<a.length;++f){b=a[f];var e=void 0,m=void 0,h=void 0,p=void 0,t=void 0,g=void 0;c=[];for(m=0;m<b.length;++m){h=b[m];if(typeof h==\"string\"){h=\nh.split(/\\s*:\\s*/);p=h[0];t=null;g=h[1]}else{p=h.check;t=h.left;g=h.right}if(!e){e=h;e=e.element?e.element:p?p.match(/^([a-z0-9]+)/i)[0]:e.left.getDefinition().element}t instanceof CKEDITOR.style&&(t=k(t));c.push({check:p==e?null:p,left:t,right:typeof g==\"string\"?l(g):g})}b=e;d[b]||(d[b]=[]);d[b].push(c)}}},check:function(a,b,d){if(this.disabled)return true;if(CKEDITOR.tools.isArray(a)){for(var f=a.length;f--;)if(this.check(a[f],b,d))return true;return false}var e,k;if(typeof a==\"string\"){k=a+\"<\"+\n(b===false?\"0\":\"1\")+(d?\"1\":\"0\")+\">\";if(k in this._.cachedChecks)return this._.cachedChecks[k];f=g(a).$1;e=f.styles;var m=f.classes;f.name=f.elements;f.classes=m=m?m.split(/\\s*,\\s*/):[];f.styles=h(e);f.attributes=h(f.attributes);f.children=[];m.length&&(f.attributes[\"class\"]=m.join(\" \"));if(e)f.attributes.style=CKEDITOR.tools.writeCssText(f.styles);e=f}else{f=a.getDefinition();e=f.styles;m=f.attributes||{};if(e){e=x(e);m.style=CKEDITOR.tools.writeCssText(e,true)}else e={};e={name:f.element,attributes:m,\nclasses:m[\"class\"]?m[\"class\"].split(/\\s+/):[],styles:e,children:[]}}var m=CKEDITOR.tools.clone(e),l=[],t;if(b!==false&&(t=this._.transformations[e.name])){for(f=0;f<t.length;++f)p(this,e,t[f]);j(e)}c(this)(m,this._.rules,b===false?false:this._.transformations,l,false,!d,!d);b=l.length>0?false:CKEDITOR.tools.objectCompare(e.attributes,m.attributes,true)?true:false;typeof a==\"string\"&&(this._.cachedChecks[k]=b);return b},getAllowedEnterMode:function(){var a=[\"p\",\"div\",\"br\"],b={p:CKEDITOR.ENTER_P,div:CKEDITOR.ENTER_DIV,\nbr:CKEDITOR.ENTER_BR};return function(c,d){var f=a.slice(),e;if(this.check(A[c]))return c;for(d||(f=f.reverse());e=f.pop();)if(this.check(e))return b[e];return CKEDITOR.ENTER_BR}}()};var I={styles:1,attributes:1,classes:1},E={styles:\"requiredStyles\",attributes:\"requiredAttributes\",classes:\"requiredClasses\"},z=/^([a-z0-9*\\s]+)((?:\\s*\\{[!\\w\\-,\\s\\*]+\\}\\s*|\\s*\\[[!\\w\\-,\\s\\*]+\\]\\s*|\\s*\\([!\\w\\-,\\s\\*]+\\)\\s*){0,3})(?:;\\s*|$)/i,M={styles:/{([^}]+)}/,attrs:/\\[([^\\]]+)\\]/,classes:/\\(([^\\)]+)\\)/},Q=CKEDITOR.filter.transformationsTools=\n{sizeToStyle:function(a){this.lengthToStyle(a,\"width\");this.lengthToStyle(a,\"height\")},sizeToAttribute:function(a){this.lengthToAttribute(a,\"width\");this.lengthToAttribute(a,\"height\")},lengthToStyle:function(a,b,c){c=c||b;if(!(c in a.styles)){var d=a.attributes[b];if(d){/^\\d+$/.test(d)&&(d=d+\"px\");a.styles[c]=d}}delete a.attributes[b]},lengthToAttribute:function(a,b,c){c=c||b;if(!(c in a.attributes)){var d=a.styles[b],f=d&&d.match(/^(\\d+)(?:\\.\\d*)?px$/);f?a.attributes[c]=f[1]:d==L&&(a.attributes[c]=\nL)}delete a.styles[b]},alignmentToStyle:function(a){if(!(\"float\"in a.styles)){var b=a.attributes.align;if(b==\"left\"||b==\"right\")a.styles[\"float\"]=b}delete a.attributes.align},alignmentToAttribute:function(a){if(!(\"align\"in a.attributes)){var b=a.styles[\"float\"];if(b==\"left\"||b==\"right\")a.attributes.align=b}delete a.styles[\"float\"]},matchesStyle:y,transform:function(a,b){if(typeof b==\"string\")a.name=b;else{var c=b.getDefinition(),d=c.styles,f=c.attributes,e,k,m,l;a.name=c.element;for(e in f)if(e==\n\"class\"){c=a.classes.join(\"|\");for(m=f[e].split(/\\s+/);l=m.pop();)c.indexOf(l)==-1&&a.classes.push(l)}else a.attributes[e]=f[e];for(k in d)a.styles[k]=d[k]}}}})();\n(function(){CKEDITOR.focusManager=function(a){if(a.focusManager)return a.focusManager;this.hasFocus=false;this.currentActive=null;this._={editor:a};return this};CKEDITOR.focusManager._={blurDelay:200};CKEDITOR.focusManager.prototype={focus:function(a){this._.timer&&clearTimeout(this._.timer);if(a)this.currentActive=a;if(!this.hasFocus&&!this._.locked){(a=CKEDITOR.currentInstance)&&a.focusManager.blur(1);this.hasFocus=true;(a=this._.editor.container)&&a.addClass(\"cke_focus\");this._.editor.fire(\"focus\")}},\nlock:function(){this._.locked=1},unlock:function(){delete this._.locked},blur:function(a){function e(){if(this.hasFocus){this.hasFocus=false;var a=this._.editor.container;a&&a.removeClass(\"cke_focus\");this._.editor.fire(\"blur\")}}if(!this._.locked){this._.timer&&clearTimeout(this._.timer);var b=CKEDITOR.focusManager._.blurDelay;a||!b?e.call(this):this._.timer=CKEDITOR.tools.setTimeout(function(){delete this._.timer;e.call(this)},b,this)}},add:function(a,e){var b=a.getCustomData(\"focusmanager\");if(!b||\nb!=this){b&&b.remove(a);var b=\"focus\",c=\"blur\";if(e)if(CKEDITOR.env.ie){b=\"focusin\";c=\"focusout\"}else CKEDITOR.event.useCapture=1;var d={blur:function(){a.equals(this.currentActive)&&this.blur()},focus:function(){this.focus(a)}};a.on(b,d.focus,this);a.on(c,d.blur,this);if(e)CKEDITOR.event.useCapture=0;a.setCustomData(\"focusmanager\",this);a.setCustomData(\"focusmanager_handlers\",d)}},remove:function(a){a.removeCustomData(\"focusmanager\");var e=a.removeCustomData(\"focusmanager_handlers\");a.removeListener(\"blur\",\ne.blur);a.removeListener(\"focus\",e.focus)}}})();CKEDITOR.keystrokeHandler=function(a){if(a.keystrokeHandler)return a.keystrokeHandler;this.keystrokes={};this.blockedKeystrokes={};this._={editor:a};return this};\n(function(){var a,e=function(b){var b=b.data,d=b.getKeystroke(),e=this.keystrokes[d],g=this._.editor;a=g.fire(\"key\",{keyCode:d})===false;if(!a){e&&(a=g.execCommand(e,{from:\"keystrokeHandler\"})!==false);a||(a=!!this.blockedKeystrokes[d])}a&&b.preventDefault(true);return!a},b=function(b){if(a){a=false;b.data.preventDefault(true)}};CKEDITOR.keystrokeHandler.prototype={attach:function(a){a.on(\"keydown\",e,this);if(CKEDITOR.env.opera||CKEDITOR.env.gecko&&CKEDITOR.env.mac)a.on(\"keypress\",b,this)}}})();\n(function(){CKEDITOR.lang={languages:{af:1,ar:1,bg:1,bn:1,bs:1,ca:1,cs:1,cy:1,da:1,de:1,el:1,\"en-au\":1,\"en-ca\":1,\"en-gb\":1,en:1,eo:1,es:1,et:1,eu:1,fa:1,fi:1,fo:1,\"fr-ca\":1,fr:1,gl:1,gu:1,he:1,hi:1,hr:1,hu:1,id:1,is:1,it:1,ja:1,ka:1,km:1,ko:1,ku:1,lt:1,lv:1,mk:1,mn:1,ms:1,nb:1,nl:1,no:1,pl:1,\"pt-br\":1,pt:1,ro:1,ru:1,si:1,sk:1,sl:1,sq:1,\"sr-latn\":1,sr:1,sv:1,th:1,tr:1,ug:1,uk:1,vi:1,\"zh-cn\":1,zh:1},rtl:{ar:1,fa:1,he:1,ku:1,ug:1},load:function(a,e,b){if(!a||!CKEDITOR.lang.languages[a])a=this.detect(e,\na);this[a]?b(a,this[a]):CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(\"lang/\"+a+\".js\"),function(){this[a].dir=this.rtl[a]?\"rtl\":\"ltr\";b(a,this[a])},this)},detect:function(a,e){var b=this.languages,e=e||navigator.userLanguage||navigator.language||a,c=e.toLowerCase().match(/([a-z]+)(?:-([a-z]+))?/),d=c[1],c=c[2];b[d+\"-\"+c]?d=d+\"-\"+c:b[d]||(d=null);CKEDITOR.lang.detect=d?function(){return d}:function(a){return a};return d||a}}})();\nCKEDITOR.scriptLoader=function(){var a={},e={};return{load:function(b,c,d,h){var g=typeof b==\"string\";g&&(b=[b]);d||(d=CKEDITOR);var n=b.length,i=[],j=[],o=function(a){c&&(g?c.call(d,a):c.call(d,i,j))};if(n===0)o(true);else{var q=function(a,b){(b?i:j).push(a);if(--n<=0){h&&CKEDITOR.document.getDocumentElement().removeStyle(\"cursor\");o(b)}},s=function(b,c){a[b]=1;var d=e[b];delete e[b];for(var f=0;f<d.length;f++)d[f](b,c)},u=function(b){if(a[b])q(b,true);else{var d=e[b]||(e[b]=[]);d.push(q);if(!(d.length>\n1)){var f=new CKEDITOR.dom.element(\"script\");f.setAttributes({type:\"text/javascript\",src:b});if(c)if(CKEDITOR.env.ie&&CKEDITOR.env.version<11)f.$.onreadystatechange=function(){if(f.$.readyState==\"loaded\"||f.$.readyState==\"complete\"){f.$.onreadystatechange=null;s(b,true)}};else{f.$.onload=function(){setTimeout(function(){s(b,true)},0)};f.$.onerror=function(){s(b,false)}}f.appendTo(CKEDITOR.document.getHead())}}};h&&CKEDITOR.document.getDocumentElement().setStyle(\"cursor\",\"wait\");for(var f=0;f<n;f++)u(b[f])}},\nqueue:function(){function a(){var b;(b=c[0])&&this.load(b.scriptUrl,b.callback,CKEDITOR,0)}var c=[];return function(d,e){var g=this;c.push({scriptUrl:d,callback:function(){e&&e.apply(this,arguments);c.shift();a.call(g)}});c.length==1&&a.call(this)}}()}}();CKEDITOR.resourceManager=function(a,e){this.basePath=a;this.fileName=e;this.registered={};this.loaded={};this.externals={};this._={waitingList:{}}};\nCKEDITOR.resourceManager.prototype={add:function(a,e){if(this.registered[a])throw'[CKEDITOR.resourceManager.add] The resource name \"'+a+'\" is already registered.';var b=this.registered[a]=e||{};b.name=a;b.path=this.getPath(a);CKEDITOR.fire(a+CKEDITOR.tools.capitalize(this.fileName)+\"Ready\",b);return this.get(a)},get:function(a){return this.registered[a]||null},getPath:function(a){var e=this.externals[a];return CKEDITOR.getUrl(e&&e.dir||this.basePath+a+\"/\")},getFilePath:function(a){var e=this.externals[a];\nreturn CKEDITOR.getUrl(this.getPath(a)+(e?e.file:this.fileName+\".js\"))},addExternal:function(a,e,b){for(var a=a.split(\",\"),c=0;c<a.length;c++){var d=a[c];b||(e=e.replace(/[^\\/]+$/,function(a){b=a;return\"\"}));this.externals[d]={dir:e,file:b||this.fileName+\".js\"}}},load:function(a,e,b){CKEDITOR.tools.isArray(a)||(a=a?[a]:[]);for(var c=this.loaded,d=this.registered,h=[],g={},n={},i=0;i<a.length;i++){var j=a[i];if(j)if(!c[j]&&!d[j]){var o=this.getFilePath(j);h.push(o);o in g||(g[o]=[]);g[o].push(j)}else n[j]=\nthis.get(j)}CKEDITOR.scriptLoader.load(h,function(a,d){if(d.length)throw'[CKEDITOR.resourceManager.load] Resource name \"'+g[d[0]].join(\",\")+'\" was not found at \"'+d[0]+'\".';for(var h=0;h<a.length;h++)for(var f=g[a[h]],p=0;p<f.length;p++){var i=f[p];n[i]=this.get(i);c[i]=1}e.call(b,n)},this)}};CKEDITOR.plugins=new CKEDITOR.resourceManager(\"plugins/\",\"plugin\");\nCKEDITOR.plugins.load=CKEDITOR.tools.override(CKEDITOR.plugins.load,function(a){var e={};return function(b,c,d){var h={},g=function(b){a.call(this,b,function(a){CKEDITOR.tools.extend(h,a);var b=[],n;for(n in a){var q=a[n],s=q&&q.requires;if(!e[n]){if(q.icons)for(var u=q.icons.split(\",\"),f=u.length;f--;)CKEDITOR.skin.addIcon(u[f],q.path+\"icons/\"+(CKEDITOR.env.hidpi&&q.hidpi?\"hidpi/\":\"\")+u[f]+\".png\");e[n]=1}if(s){s.split&&(s=s.split(\",\"));for(q=0;q<s.length;q++)h[s[q]]||b.push(s[q])}}if(b.length)g.call(this,\nb);else{for(n in h){q=h[n];if(q.onLoad&&!q.onLoad._called){q.onLoad()===false&&delete h[n];q.onLoad._called=1}}c&&c.call(d||window,h)}},this)};g.call(this,b)}});CKEDITOR.plugins.setLang=function(a,e,b){var c=this.get(a),a=c.langEntries||(c.langEntries={}),c=c.lang||(c.lang=[]);c.split&&(c=c.split(\",\"));CKEDITOR.tools.indexOf(c,e)==-1&&c.push(e);a[e]=b};CKEDITOR.ui=function(a){if(a.ui)return a.ui;this.items={};this.instances={};this.editor=a;this._={handlers:{}};return this};\nCKEDITOR.ui.prototype={add:function(a,e,b){b.name=a.toLowerCase();var c=this.items[a]={type:e,command:b.command||null,args:Array.prototype.slice.call(arguments,2)};CKEDITOR.tools.extend(c,b)},get:function(a){return this.instances[a]},create:function(a){var e=this.items[a],b=e&&this._.handlers[e.type],c=e&&e.command&&this.editor.getCommand(e.command),b=b&&b.create.apply(this,e.args);this.instances[a]=b;c&&c.uiItems.push(b);if(b&&!b.type)b.type=e.type;return b},addHandler:function(a,e){this._.handlers[a]=\ne},space:function(a){return CKEDITOR.document.getById(this.spaceId(a))},spaceId:function(a){return this.editor.id+\"_\"+a}};CKEDITOR.event.implementOn(CKEDITOR.ui);\n(function(){function a(a,c,h){CKEDITOR.event.call(this);a=a&&CKEDITOR.tools.clone(a);if(c!==void 0){if(c instanceof CKEDITOR.dom.element){if(!h)throw Error(\"One of the element modes must be specified.\");}else throw Error(\"Expect element of type CKEDITOR.dom.element.\");if(CKEDITOR.env.ie&&CKEDITOR.env.quirks&&h==CKEDITOR.ELEMENT_MODE_INLINE)throw Error(\"Inline element mode is not supported on IE quirks.\");if(!(h==CKEDITOR.ELEMENT_MODE_INLINE?c.is(CKEDITOR.dtd.$editable)||c.is(\"textarea\"):h==CKEDITOR.ELEMENT_MODE_REPLACE?\n!c.is(CKEDITOR.dtd.$nonBodyContent):1))throw Error('The specified element mode is not supported on element: \"'+c.getName()+'\".');this.element=c;this.elementMode=h;this.name=this.elementMode!=CKEDITOR.ELEMENT_MODE_APPENDTO&&(c.getId()||c.getNameAtt())}else this.elementMode=CKEDITOR.ELEMENT_MODE_NONE;this._={};this.commands={};this.templates={};this.name=this.name||e();this.id=CKEDITOR.tools.getNextId();this.status=\"unloaded\";this.config=CKEDITOR.tools.prototypedCopy(CKEDITOR.config);this.ui=new CKEDITOR.ui(this);\nthis.focusManager=new CKEDITOR.focusManager(this);this.keystrokeHandler=new CKEDITOR.keystrokeHandler(this);this.on(\"readOnly\",b);this.on(\"selectionChange\",function(a){d(this,a.data.path)});this.on(\"activeFilterChange\",function(){d(this,this.elementPath(),true)});this.on(\"mode\",b);this.on(\"instanceReady\",function(){this.config.startupFocus&&this.focus()});CKEDITOR.fire(\"instanceCreated\",null,this);CKEDITOR.add(this);CKEDITOR.tools.setTimeout(function(){g(this,a)},0,this)}function e(){do var a=\"editor\"+\n++s;while(CKEDITOR.instances[a]);return a}function b(){var a=this.commands,b;for(b in a)c(this,a[b])}function c(a,b){b[b.startDisabled?\"disable\":a.readOnly&&!b.readOnly?\"disable\":b.modes[a.mode]?\"enable\":\"disable\"]()}function d(a,b,c){if(b){var d,e,l=a.commands;for(e in l){d=l[e];(c||d.contextSensitive)&&d.refresh(a,b)}}}function h(a){var b=a.config.customConfig;if(!b)return false;var b=CKEDITOR.getUrl(b),c=u[b]||(u[b]={});if(c.fn){c.fn.call(a,a.config);(CKEDITOR.getUrl(a.config.customConfig)==b||\n!h(a))&&a.fireOnce(\"customConfigLoaded\")}else CKEDITOR.scriptLoader.queue(b,function(){c.fn=CKEDITOR.editorConfig?CKEDITOR.editorConfig:function(){};h(a)});return true}function g(a,b){a.on(\"customConfigLoaded\",function(){if(b){if(b.on)for(var c in b.on)a.on(c,b.on[c]);CKEDITOR.tools.extend(a.config,b,true);delete a.config.on}c=a.config;a.readOnly=!(!c.readOnly&&!(a.elementMode==CKEDITOR.ELEMENT_MODE_INLINE?a.element.is(\"textarea\")?a.element.hasAttribute(\"disabled\"):a.element.isReadOnly():a.elementMode==\nCKEDITOR.ELEMENT_MODE_REPLACE&&a.element.hasAttribute(\"disabled\")));a.blockless=a.elementMode==CKEDITOR.ELEMENT_MODE_INLINE?!(a.element.is(\"textarea\")||CKEDITOR.dtd[a.element.getName()].p):false;a.tabIndex=c.tabIndex||a.element&&a.element.getAttribute(\"tabindex\")||0;a.activeEnterMode=a.enterMode=a.blockless?CKEDITOR.ENTER_BR:c.enterMode;a.activeShiftEnterMode=a.shiftEnterMode=a.blockless?CKEDITOR.ENTER_BR:c.shiftEnterMode;if(c.skin)CKEDITOR.skinName=c.skin;a.fireOnce(\"configLoaded\");a.dataProcessor=\nnew CKEDITOR.htmlDataProcessor(a);a.filter=a.activeFilter=new CKEDITOR.filter(a);n(a)});if(b&&b.customConfig!=void 0)a.config.customConfig=b.customConfig;h(a)||a.fireOnce(\"customConfigLoaded\")}function n(a){CKEDITOR.skin.loadPart(\"editor\",function(){i(a)})}function i(a){CKEDITOR.lang.load(a.config.language,a.config.defaultLanguage,function(b,c){var d=a.config.title;a.langCode=b;a.lang=CKEDITOR.tools.prototypedCopy(c);a.title=typeof d==\"string\"||d===false?d:[a.lang.editor,a.name].join(\", \");if(CKEDITOR.env.gecko&&\nCKEDITOR.env.version<10900&&a.lang.dir==\"rtl\")a.lang.dir=\"ltr\";if(!a.config.contentsLangDirection)a.config.contentsLangDirection=a.elementMode==CKEDITOR.ELEMENT_MODE_INLINE?a.element.getDirection(1):a.lang.dir;a.fire(\"langLoaded\");j(a)})}function j(a){a.getStylesSet(function(b){a.once(\"loaded\",function(){a.fire(\"stylesSet\",{styles:b})},null,null,1);o(a)})}function o(a){var b=a.config,c=b.plugins,d=b.extraPlugins,e=b.removePlugins;if(d)var l=RegExp(\"(?:^|,)(?:\"+d.replace(/\\s*,\\s*/g,\"|\")+\")(?=,|$)\",\n\"g\"),c=c.replace(l,\"\"),c=c+(\",\"+d);if(e)var h=RegExp(\"(?:^|,)(?:\"+e.replace(/\\s*,\\s*/g,\"|\")+\")(?=,|$)\",\"g\"),c=c.replace(h,\"\");CKEDITOR.env.air&&(c=c+\",adobeair\");CKEDITOR.plugins.load(c.split(\",\"),function(c){var d=[],e=[],k=[];a.plugins=c;for(var l in c){var m=c[l],g=m.lang,i=null,j=m.requires,v;CKEDITOR.tools.isArray(j)&&(j=j.join(\",\"));if(j&&(v=j.match(h)))for(;j=v.pop();)CKEDITOR.tools.setTimeout(function(a,b){throw Error('Plugin \"'+a.replace(\",\",\"\")+'\" cannot be removed from the plugins list, because it\\'s required by \"'+\nb+'\" plugin.');},0,null,[j,l]);if(g&&!a.lang[l]){g.split&&(g=g.split(\",\"));if(CKEDITOR.tools.indexOf(g,a.langCode)>=0)i=a.langCode;else{i=a.langCode.replace(/-.*/,\"\");i=i!=a.langCode&&CKEDITOR.tools.indexOf(g,i)>=0?i:CKEDITOR.tools.indexOf(g,\"en\")>=0?\"en\":g[0]}if(!m.langEntries||!m.langEntries[i])k.push(CKEDITOR.getUrl(m.path+\"lang/\"+i+\".js\"));else{a.lang[l]=m.langEntries[i];i=null}}e.push(i);d.push(m)}CKEDITOR.scriptLoader.load(k,function(){for(var c=[\"beforeInit\",\"init\",\"afterInit\"],k=0;k<c.length;k++)for(var m=\n0;m<d.length;m++){var l=d[m];k===0&&(e[m]&&l.lang&&l.langEntries)&&(a.lang[l.name]=l.langEntries[e[m]]);if(l[c[k]])l[c[k]](a)}a.fireOnce(\"pluginsLoaded\");b.keystrokes&&a.setKeystroke(a.config.keystrokes);for(m=0;m<a.config.blockedKeystrokes.length;m++)a.keystrokeHandler.blockedKeystrokes[a.config.blockedKeystrokes[m]]=1;a.status=\"loaded\";a.fireOnce(\"loaded\");CKEDITOR.fire(\"instanceLoaded\",null,a)})})}function q(){var a=this.element;if(a&&this.elementMode!=CKEDITOR.ELEMENT_MODE_APPENDTO){var b=this.getData();\nthis.config.htmlEncodeOutput&&(b=CKEDITOR.tools.htmlEncode(b));a.is(\"textarea\")?a.setValue(b):a.setHtml(b);return true}return false}a.prototype=CKEDITOR.editor.prototype;CKEDITOR.editor=a;var s=0,u={};CKEDITOR.tools.extend(CKEDITOR.editor.prototype,{addCommand:function(a,b){b.name=a.toLowerCase();var d=new CKEDITOR.command(this,b);this.mode&&c(this,d);return this.commands[a]=d},_attachToForm:function(){var a=this,b=a.element,c=new CKEDITOR.dom.element(b.$.form);if(b.is(\"textarea\")&&c){var d=function(c){a.updateElement();\na._.required&&(!b.getValue()&&a.fire(\"required\")===false)&&c.data.preventDefault()};c.on(\"submit\",d);if(c.$.submit&&c.$.submit.call&&c.$.submit.apply)c.$.submit=CKEDITOR.tools.override(c.$.submit,function(a){return function(){d();a.apply?a.apply(this):a()}});a.on(\"destroy\",function(){c.removeListener(\"submit\",d)})}},destroy:function(a){this.fire(\"beforeDestroy\");!a&&q.call(this);this.editable(null);this.status=\"destroyed\";this.fire(\"destroy\");this.removeAllListeners();CKEDITOR.remove(this);CKEDITOR.fire(\"instanceDestroyed\",\nnull,this)},elementPath:function(a){return(a=a||this.getSelection().getStartElement())?new CKEDITOR.dom.elementPath(a,this.editable()):null},createRange:function(){var a=this.editable();return a?new CKEDITOR.dom.range(a):null},execCommand:function(a,b){var c=this.getCommand(a),d={name:a,commandData:b,command:c};if(c&&c.state!=CKEDITOR.TRISTATE_DISABLED&&this.fire(\"beforeCommandExec\",d)!==true){d.returnValue=c.exec(d.commandData);if(!c.async&&this.fire(\"afterCommandExec\",d)!==true)return d.returnValue}return false},\ngetCommand:function(a){return this.commands[a]},getData:function(a){!a&&this.fire(\"beforeGetData\");var b=this._.data;if(typeof b!=\"string\")b=(b=this.element)&&this.elementMode==CKEDITOR.ELEMENT_MODE_REPLACE?b.is(\"textarea\")?b.getValue():b.getHtml():\"\";b={dataValue:b};!a&&this.fire(\"getData\",b);return b.dataValue},getSnapshot:function(){var a=this.fire(\"getSnapshot\");if(typeof a!=\"string\"){var b=this.element;b&&this.elementMode==CKEDITOR.ELEMENT_MODE_REPLACE&&(a=b.is(\"textarea\")?b.getValue():b.getHtml())}return a},\nloadSnapshot:function(a){this.fire(\"loadSnapshot\",a)},setData:function(a,b,c){if(b)this.on(\"dataReady\",function(a){a.removeListener();b.call(a.editor)});a={dataValue:a};!c&&this.fire(\"setData\",a);this._.data=a.dataValue;!c&&this.fire(\"afterSetData\",a)},setReadOnly:function(a){a=a==void 0||a;if(this.readOnly!=a){this.readOnly=a;this.keystrokeHandler.blockedKeystrokes[8]=+a;this.editable().setReadOnly(a);this.fire(\"readOnly\")}},insertHtml:function(a,b){this.fire(\"insertHtml\",{dataValue:a,mode:b})},\ninsertText:function(a){this.fire(\"insertText\",a)},insertElement:function(a){this.fire(\"insertElement\",a)},focus:function(){this.fire(\"beforeFocus\")},checkDirty:function(){return this.status==\"ready\"&&this._.previousValue!==this.getSnapshot()},resetDirty:function(){this._.previousValue=this.getSnapshot()},updateElement:function(){return q.call(this)},setKeystroke:function(){for(var a=this.keystrokeHandler.keystrokes,b=CKEDITOR.tools.isArray(arguments[0])?arguments[0]:[[].slice.call(arguments,0)],c,\nd,e=b.length;e--;){c=b[e];d=0;if(CKEDITOR.tools.isArray(c)){d=c[1];c=c[0]}d?a[c]=d:delete a[c]}},addFeature:function(a){return this.filter.addFeature(a)},setActiveFilter:function(a){if(!a)a=this.filter;if(this.activeFilter!==a){this.activeFilter=a;this.fire(\"activeFilterChange\");a===this.filter?this.setActiveEnterMode(null,null):this.setActiveEnterMode(a.getAllowedEnterMode(this.enterMode),a.getAllowedEnterMode(this.shiftEnterMode,true))}},setActiveEnterMode:function(a,b){a=a?this.blockless?CKEDITOR.ENTER_BR:\na:this.enterMode;b=b?this.blockless?CKEDITOR.ENTER_BR:b:this.shiftEnterMode;if(this.activeEnterMode!=a||this.activeShiftEnterMode!=b){this.activeEnterMode=a;this.activeShiftEnterMode=b;this.fire(\"activeEnterModeChange\")}}})})();CKEDITOR.ELEMENT_MODE_NONE=0;CKEDITOR.ELEMENT_MODE_REPLACE=1;CKEDITOR.ELEMENT_MODE_APPENDTO=2;CKEDITOR.ELEMENT_MODE_INLINE=3;\nCKEDITOR.htmlParser=function(){this._={htmlPartsRegex:RegExp(\"<(?:(?:\\\\/([^>]+)>)|(?:!--([\\\\S|\\\\s]*?)--\\>)|(?:([^\\\\s>]+)\\\\s*((?:(?:\\\"[^\\\"]*\\\")|(?:'[^']*')|[^\\\"'>])*)\\\\/?>))\",\"g\")}};\n(function(){var a=/([\\w\\-:.]+)(?:(?:\\s*=\\s*(?:(?:\"([^\"]*)\")|(?:'([^']*)')|([^\\s>]+)))|(?=\\s|$))/g,e={checked:1,compact:1,declare:1,defer:1,disabled:1,ismap:1,multiple:1,nohref:1,noresize:1,noshade:1,nowrap:1,readonly:1,selected:1};CKEDITOR.htmlParser.prototype={onTagOpen:function(){},onTagClose:function(){},onText:function(){},onCDATA:function(){},onComment:function(){},parse:function(b){for(var c,d,h=0,g;c=this._.htmlPartsRegex.exec(b);){d=c.index;if(d>h){h=b.substring(h,d);if(g)g.push(h);else this.onText(h)}h=\nthis._.htmlPartsRegex.lastIndex;if(d=c[1]){d=d.toLowerCase();if(g&&CKEDITOR.dtd.$cdata[d]){this.onCDATA(g.join(\"\"));g=null}if(!g){this.onTagClose(d);continue}}if(g)g.push(c[0]);else if(d=c[3]){d=d.toLowerCase();if(!/=\"/.test(d)){var n={},i;c=c[4];var j=!!(c&&c.charAt(c.length-1)==\"/\");if(c)for(;i=a.exec(c);){var o=i[1].toLowerCase();i=i[2]||i[3]||i[4]||\"\";n[o]=!i&&e[o]?o:CKEDITOR.tools.htmlDecodeAttr(i)}this.onTagOpen(d,n,j);!g&&CKEDITOR.dtd.$cdata[d]&&(g=[])}}else if(d=c[2])this.onComment(d)}if(b.length>\nh)this.onText(b.substring(h,b.length))}}})();\nCKEDITOR.htmlParser.basicWriter=CKEDITOR.tools.createClass({$:function(){this._={output:[]}},proto:{openTag:function(a){this._.output.push(\"<\",a)},openTagClose:function(a,e){e?this._.output.push(\" />\"):this._.output.push(\">\")},attribute:function(a,e){typeof e==\"string\"&&(e=CKEDITOR.tools.htmlEncodeAttr(e));this._.output.push(\" \",a,'=\"',e,'\"')},closeTag:function(a){this._.output.push(\"</\",a,\">\")},text:function(a){this._.output.push(a)},comment:function(a){this._.output.push(\"<\\!--\",a,\"--\\>\")},write:function(a){this._.output.push(a)},\nreset:function(){this._.output=[];this._.indent=false},getHtml:function(a){var e=this._.output.join(\"\");a&&this.reset();return e}}});\"use strict\";\n(function(){CKEDITOR.htmlParser.node=function(){};CKEDITOR.htmlParser.node.prototype={remove:function(){var a=this.parent.children,e=CKEDITOR.tools.indexOf(a,this),b=this.previous,c=this.next;b&&(b.next=c);c&&(c.previous=b);a.splice(e,1);this.parent=null},replaceWith:function(a){var e=this.parent.children,b=CKEDITOR.tools.indexOf(e,this),c=a.previous=this.previous,d=a.next=this.next;c&&(c.next=a);d&&(d.previous=a);e[b]=a;a.parent=this.parent;this.parent=null},insertAfter:function(a){var e=a.parent.children,\nb=CKEDITOR.tools.indexOf(e,a),c=a.next;e.splice(b+1,0,this);this.next=a.next;this.previous=a;a.next=this;c&&(c.previous=this);this.parent=a.parent},insertBefore:function(a){var e=a.parent.children,b=CKEDITOR.tools.indexOf(e,a);e.splice(b,0,this);this.next=a;(this.previous=a.previous)&&(a.previous.next=this);a.previous=this;this.parent=a.parent},getAscendant:function(a){var e=typeof a==\"function\"?a:typeof a==\"string\"?function(b){return b.name==a}:function(b){return b.name in a},b=this.parent;for(;b&&\nb.type==CKEDITOR.NODE_ELEMENT;){if(e(b))return b;b=b.parent}return null},wrapWith:function(a){this.replaceWith(a);a.add(this);return a},getIndex:function(){return CKEDITOR.tools.indexOf(this.parent.children,this)},getFilterContext:function(a){return a||{}}}})();\"use strict\";CKEDITOR.htmlParser.comment=function(a){this.value=a;this._={isBlockLike:false}};\nCKEDITOR.htmlParser.comment.prototype=CKEDITOR.tools.extend(new CKEDITOR.htmlParser.node,{type:CKEDITOR.NODE_COMMENT,filter:function(a,e){var b=this.value;if(!(b=a.onComment(e,b,this))){this.remove();return false}if(typeof b!=\"string\"){this.replaceWith(b);return false}this.value=b;return true},writeHtml:function(a,e){e&&this.filter(e);a.comment(this.value)}});\"use strict\";\n(function(){CKEDITOR.htmlParser.text=function(a){this.value=a;this._={isBlockLike:false}};CKEDITOR.htmlParser.text.prototype=CKEDITOR.tools.extend(new CKEDITOR.htmlParser.node,{type:CKEDITOR.NODE_TEXT,filter:function(a,e){if(!(this.value=a.onText(e,this.value,this))){this.remove();return false}},writeHtml:function(a,e){e&&this.filter(e);a.text(this.value)}})})();\"use strict\";\n(function(){CKEDITOR.htmlParser.cdata=function(a){this.value=a};CKEDITOR.htmlParser.cdata.prototype=CKEDITOR.tools.extend(new CKEDITOR.htmlParser.node,{type:CKEDITOR.NODE_TEXT,filter:function(){},writeHtml:function(a){a.write(this.value)}})})();\"use strict\";CKEDITOR.htmlParser.fragment=function(){this.children=[];this.parent=null;this._={isBlockLike:true,hasInlineStarted:false}};\n(function(){function a(a){return a.attributes[\"data-cke-survive\"]?false:a.name==\"a\"&&a.attributes.href||CKEDITOR.dtd.$removeEmpty[a.name]}var e=CKEDITOR.tools.extend({table:1,ul:1,ol:1,dl:1},CKEDITOR.dtd.table,CKEDITOR.dtd.ul,CKEDITOR.dtd.ol,CKEDITOR.dtd.dl),b={ol:1,ul:1},c=CKEDITOR.tools.extend({},{html:1},CKEDITOR.dtd.html,CKEDITOR.dtd.body,CKEDITOR.dtd.head,{style:1,script:1});CKEDITOR.htmlParser.fragment.fromHtml=function(d,h,g){function n(a){var b;if(p.length>0)for(var c=0;c<p.length;c++){var d=\np[c],e=d.name,f=CKEDITOR.dtd[e],k=m.name&&CKEDITOR.dtd[m.name];if((!k||k[e])&&(!a||!f||f[a]||!CKEDITOR.dtd[a])){if(!b){i();b=1}d=d.clone();d.parent=m;m=d;p.splice(c,1);c--}else if(e==m.name){o(m,m.parent,1);c--}}}function i(){for(;y.length;)o(y.shift(),m)}function j(a){if(a._.isBlockLike&&a.name!=\"pre\"&&a.name!=\"textarea\"){var b=a.children.length,c=a.children[b-1],d;if(c&&c.type==CKEDITOR.NODE_TEXT)(d=CKEDITOR.tools.rtrim(c.value))?c.value=d:a.children.length=b-1}}function o(b,c,d){var c=c||m||f,\ne=m;if(b.previous===void 0){if(q(c,b)){m=c;u.onTagOpen(g,{});b.returnPoint=c=m}j(b);(!a(b)||b.children.length)&&c.add(b);b.name==\"pre\"&&(l=false);b.name==\"textarea\"&&(k=false)}if(b.returnPoint){m=b.returnPoint;delete b.returnPoint}else m=d?c:e}function q(a,b){if((a==f||a.name==\"body\")&&g&&(!a.name||CKEDITOR.dtd[a.name][g])){var c,d;return(c=b.attributes&&(d=b.attributes[\"data-cke-real-element-type\"])?d:b.name)&&c in CKEDITOR.dtd.$inline&&!(c in CKEDITOR.dtd.head)&&!b.isOrphan||b.type==CKEDITOR.NODE_TEXT}}\nfunction s(a,b){return a in CKEDITOR.dtd.$listItem||a in CKEDITOR.dtd.$tableContent?a==b||a==\"dt\"&&b==\"dd\"||a==\"dd\"&&b==\"dt\":false}var u=new CKEDITOR.htmlParser,f=h instanceof CKEDITOR.htmlParser.element?h:typeof h==\"string\"?new CKEDITOR.htmlParser.element(h):new CKEDITOR.htmlParser.fragment,p=[],y=[],m=f,k=f.name==\"textarea\",l=f.name==\"pre\";u.onTagOpen=function(d,f,h,g){f=new CKEDITOR.htmlParser.element(d,f);if(f.isUnknown&&h)f.isEmpty=true;f.isOptionalClose=g;if(a(f))p.push(f);else{if(d==\"pre\")l=\ntrue;else{if(d==\"br\"&&l){m.add(new CKEDITOR.htmlParser.text(\"\\n\"));return}d==\"textarea\"&&(k=true)}if(d==\"br\")y.push(f);else{for(;;){g=(h=m.name)?CKEDITOR.dtd[h]||(m._.isBlockLike?CKEDITOR.dtd.div:CKEDITOR.dtd.span):c;if(!f.isUnknown&&!m.isUnknown&&!g[d])if(m.isOptionalClose)u.onTagClose(h);else if(d in b&&h in b){h=m.children;(h=h[h.length-1])&&h.name==\"li\"||o(h=new CKEDITOR.htmlParser.element(\"li\"),m);!f.returnPoint&&(f.returnPoint=m);m=h}else if(d in CKEDITOR.dtd.$listItem&&!s(d,h))u.onTagOpen(d==\n\"li\"?\"ul\":\"dl\",{},0,1);else if(h in e&&!s(d,h)){!f.returnPoint&&(f.returnPoint=m);m=m.parent}else{h in CKEDITOR.dtd.$inline&&p.unshift(m);if(m.parent)o(m,m.parent,1);else{f.isOrphan=1;break}}else break}n(d);i();f.parent=m;f.isEmpty?o(f):m=f}}};u.onTagClose=function(a){for(var b=p.length-1;b>=0;b--)if(a==p[b].name){p.splice(b,1);return}for(var c=[],d=[],e=m;e!=f&&e.name!=a;){e._.isBlockLike||d.unshift(e);c.push(e);e=e.returnPoint||e.parent}if(e!=f){for(b=0;b<c.length;b++){var k=c[b];o(k,k.parent)}m=\ne;e._.isBlockLike&&i();o(e,e.parent);if(e==m)m=m.parent;p=p.concat(d)}a==\"body\"&&(g=false)};u.onText=function(a){if((!m._.hasInlineStarted||y.length)&&!l&&!k){a=CKEDITOR.tools.ltrim(a);if(a.length===0)return}var d=m.name,f=d?CKEDITOR.dtd[d]||(m._.isBlockLike?CKEDITOR.dtd.div:CKEDITOR.dtd.span):c;if(!k&&!f[\"#\"]&&d in e){u.onTagOpen(d in b?\"li\":d==\"dl\"?\"dd\":d==\"table\"?\"tr\":d==\"tr\"?\"td\":\"\");u.onText(a)}else{i();n();!l&&!k&&(a=a.replace(/[\\t\\r\\n ]{2,}|[\\t\\r\\n]/g,\" \"));a=new CKEDITOR.htmlParser.text(a);\nif(q(m,a))this.onTagOpen(g,{},0,1);m.add(a)}};u.onCDATA=function(a){m.add(new CKEDITOR.htmlParser.cdata(a))};u.onComment=function(a){i();n();m.add(new CKEDITOR.htmlParser.comment(a))};u.parse(d);for(i();m!=f;)o(m,m.parent,1);j(f);return f};CKEDITOR.htmlParser.fragment.prototype={type:CKEDITOR.NODE_DOCUMENT_FRAGMENT,add:function(a,b){isNaN(b)&&(b=this.children.length);var c=b>0?this.children[b-1]:null;if(c){if(a._.isBlockLike&&c.type==CKEDITOR.NODE_TEXT){c.value=CKEDITOR.tools.rtrim(c.value);if(c.value.length===\n0){this.children.pop();this.add(a);return}}c.next=a}a.previous=c;a.parent=this;this.children.splice(b,0,a);if(!this._.hasInlineStarted)this._.hasInlineStarted=a.type==CKEDITOR.NODE_TEXT||a.type==CKEDITOR.NODE_ELEMENT&&!a._.isBlockLike},filter:function(a,b){b=this.getFilterContext(b);a.onRoot(b,this);this.filterChildren(a,false,b)},filterChildren:function(a,b,c){if(this.childrenFilteredBy!=a.id){c=this.getFilterContext(c);if(b&&!this.parent)a.onRoot(c,this);this.childrenFilteredBy=a.id;for(b=0;b<this.children.length;b++)this.children[b].filter(a,\nc)===false&&b--}},writeHtml:function(a,b){b&&this.filter(b);this.writeChildrenHtml(a)},writeChildrenHtml:function(a,b,c){var e=this.getFilterContext();if(c&&!this.parent&&b)b.onRoot(e,this);b&&this.filterChildren(b,false,e);b=0;c=this.children;for(e=c.length;b<e;b++)c[b].writeHtml(a)},forEach:function(a,b,c){if(!c&&(!b||this.type==b))var e=a(this);if(e!==false)for(var c=this.children,i=0;i<c.length;i++){e=c[i];e.type==CKEDITOR.NODE_ELEMENT?e.forEach(a,b):(!b||e.type==b)&&a(e)}},getFilterContext:function(a){return a||\n{}}}})();\"use strict\";\n(function(){function a(){this.rules=[]}function e(b,c,d,e){var g,n;for(g in c){(n=b[g])||(n=b[g]=new a);n.add(c[g],d,e)}}CKEDITOR.htmlParser.filter=CKEDITOR.tools.createClass({$:function(b){this.id=CKEDITOR.tools.getNextNumber();this.elementNameRules=new a;this.attributeNameRules=new a;this.elementsRules={};this.attributesRules={};this.textRules=new a;this.commentRules=new a;this.rootRules=new a;b&&this.addRules(b,10)},proto:{addRules:function(a,c){var d;if(typeof c==\"number\")d=c;else if(c&&\"priority\"in\nc)d=c.priority;typeof d!=\"number\"&&(d=10);typeof c!=\"object\"&&(c={});a.elementNames&&this.elementNameRules.addMany(a.elementNames,d,c);a.attributeNames&&this.attributeNameRules.addMany(a.attributeNames,d,c);a.elements&&e(this.elementsRules,a.elements,d,c);a.attributes&&e(this.attributesRules,a.attributes,d,c);a.text&&this.textRules.add(a.text,d,c);a.comment&&this.commentRules.add(a.comment,d,c);a.root&&this.rootRules.add(a.root,d,c)},applyTo:function(a){a.filter(this)},onElementName:function(a,c){return this.elementNameRules.execOnName(a,\nc)},onAttributeName:function(a,c){return this.attributeNameRules.execOnName(a,c)},onText:function(a,c){return this.textRules.exec(a,c)},onComment:function(a,c,d){return this.commentRules.exec(a,c,d)},onRoot:function(a,c){return this.rootRules.exec(a,c)},onElement:function(a,c){for(var d=[this.elementsRules[\"^\"],this.elementsRules[c.name],this.elementsRules.$],e,g=0;g<3;g++)if(e=d[g]){e=e.exec(a,c,this);if(e===false)return null;if(e&&e!=c)return this.onNode(a,e);if(c.parent&&!c.name)break}return c},\nonNode:function(a,c){var d=c.type;return d==CKEDITOR.NODE_ELEMENT?this.onElement(a,c):d==CKEDITOR.NODE_TEXT?new CKEDITOR.htmlParser.text(this.onText(a,c.value)):d==CKEDITOR.NODE_COMMENT?new CKEDITOR.htmlParser.comment(this.onComment(a,c.value)):null},onAttribute:function(a,c,d,e){return(d=this.attributesRules[d])?d.exec(a,e,c,this):e}}});CKEDITOR.htmlParser.filterRulesGroup=a;a.prototype={add:function(a,c,d){this.rules.splice(this.findIndex(c),0,{value:a,priority:c,options:d})},addMany:function(a,\nc,d){for(var e=[this.findIndex(c),0],g=0,n=a.length;g<n;g++)e.push({value:a[g],priority:c,options:d});this.rules.splice.apply(this.rules,e)},findIndex:function(a){for(var c=this.rules,d=c.length-1;d>=0&&a<c[d].priority;)d--;return d+1},exec:function(a,c){var d=c instanceof CKEDITOR.htmlParser.node||c instanceof CKEDITOR.htmlParser.fragment,e=Array.prototype.slice.call(arguments,1),g=this.rules,n=g.length,i,j,o,q;for(q=0;q<n;q++){if(d){i=c.type;j=c.name}o=g[q];if(!a.nonEditable||o.options.applyToAll){o=\no.value.apply(null,e);if(o===false||d&&o&&(o.name!=j||o.type!=i))return o;o!=void 0&&(e[0]=c=o)}}return c},execOnName:function(a,c){for(var d=0,e=this.rules,g=e.length,n;c&&d<g;d++){n=e[d];if(!a.nonEditable||n.options.applyToAll)c=c.replace(n.value[0],n.value[1])}return c}}})();\n(function(){function a(a,e){function f(a){return a||CKEDITOR.env.needsNbspFiller?new CKEDITOR.htmlParser.text(\" \"):new CKEDITOR.htmlParser.element(\"br\",{\"data-cke-bogus\":1})}function l(a,d){return function(e){if(e.type!=CKEDITOR.NODE_DOCUMENT_FRAGMENT){var k=[],l=b(e),g,C;if(l)for(m(l,1)&&k.push(l);l;){if(h(l)&&(g=c(l))&&m(g))if((C=c(g))&&!h(C))k.push(g);else{f(v).insertAfter(g);g.remove()}l=l.previous}for(l=0;l<k.length;l++)k[l].remove();if(k=CKEDITOR.env.opera&&!a||(typeof d==\"function\"?d(e)!==\nfalse:d))if(!v&&!CKEDITOR.env.needsBrFiller&&e.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT)k=false;else if(!v&&!CKEDITOR.env.needsBrFiller&&(document.documentMode>7||e.name in CKEDITOR.dtd.tr||e.name in CKEDITOR.dtd.$listItem))k=false;else{k=b(e);k=!k||e.name==\"form\"&&k.name==\"input\"}k&&e.add(f(a))}}}function m(a,b){if((!v||CKEDITOR.env.needsBrFiller)&&a.type==CKEDITOR.NODE_ELEMENT&&a.name==\"br\"&&!a.attributes[\"data-cke-eol\"])return true;var c;if(a.type==CKEDITOR.NODE_TEXT&&(c=a.value.match(y))){if(c.index){(new CKEDITOR.htmlParser.text(a.value.substring(0,\nc.index))).insertBefore(a);a.value=c[0]}if(!CKEDITOR.env.needsBrFiller&&v&&(!b||a.parent.name in i))return true;if(!v)if((c=a.previous)&&c.name==\"br\"||!c||h(c))return true}return false}var r={elements:{}},v=e==\"html\",i=CKEDITOR.tools.extend({},t),p;for(p in i)\"#\"in k[p]||delete i[p];for(p in i)r.elements[p]=l(v,a.config.fillEmptyBlocks!==false);r.root=l(v);r.elements.br=function(a){return function(b){if(b.parent.type!=CKEDITOR.NODE_DOCUMENT_FRAGMENT){var e=b.attributes;if(\"data-cke-bogus\"in e||\"data-cke-eol\"in\ne)delete e[\"data-cke-bogus\"];else{for(e=b.next;e&&d(e);)e=e.next;var k=c(b);!e&&h(b.parent)?g(b.parent,f(a)):h(e)&&(k&&!h(k))&&f(a).insertBefore(e)}}}}(v);return r}function e(a,b){return a!=CKEDITOR.ENTER_BR&&b!==false?a==CKEDITOR.ENTER_DIV?\"div\":\"p\":false}function b(a){for(a=a.children[a.children.length-1];a&&d(a);)a=a.previous;return a}function c(a){for(a=a.previous;a&&d(a);)a=a.previous;return a}function d(a){return a.type==CKEDITOR.NODE_TEXT&&!CKEDITOR.tools.trim(a.value)||a.type==CKEDITOR.NODE_ELEMENT&&\na.attributes[\"data-cke-bookmark\"]}function h(a){return a&&(a.type==CKEDITOR.NODE_ELEMENT&&a.name in t||a.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT)}function g(a,b){var c=a.children[a.children.length-1];a.children.push(b);b.parent=a;if(c){c.next=b;b.previous=c}}function n(a){a=a.attributes;a.contenteditable!=\"false\"&&(a[\"data-cke-editable\"]=a.contenteditable?\"true\":1);a.contenteditable=\"false\"}function i(a){a=a.attributes;switch(a[\"data-cke-editable\"]){case \"true\":a.contenteditable=\"true\";break;case \"1\":delete a.contenteditable}}\nfunction j(a){return a.replace(I,function(a,b,c){return\"<\"+b+c.replace(E,function(a,b){if(!/^on/.test(b)&&c.indexOf(\"data-cke-saved-\"+b)==-1){a=a.slice(1);return\" data-cke-saved-\"+a+\" data-cke-\"+CKEDITOR.rnd+\"-\"+a}return a})+\">\"})}function o(a,b){return a.replace(b,function(a,b,c){a.indexOf(\"<textarea\")===0&&(a=b+u(c).replace(/</g,\"&lt;\").replace(/>/g,\"&gt;\")+\"</textarea>\");return\"<cke:encoded>\"+encodeURIComponent(a)+\"</cke:encoded>\"})}function q(a){return a.replace(Q,function(a,b){return decodeURIComponent(b)})}\nfunction s(a){return a.replace(/<\\!--(?!{cke_protected})[\\s\\S]+?--\\>/g,function(a){return\"<\\!--\"+m+\"{C}\"+encodeURIComponent(a).replace(/--/g,\"%2D%2D\")+\"--\\>\"})}function u(a){return a.replace(/<\\!--\\{cke_protected\\}\\{C\\}([\\s\\S]+?)--\\>/g,function(a,b){return decodeURIComponent(b)})}function f(a,b){var c=b._.dataStore;return a.replace(/<\\!--\\{cke_protected\\}([\\s\\S]+?)--\\>/g,function(a,b){return decodeURIComponent(b)}).replace(/\\{cke_protected_(\\d+)\\}/g,function(a,b){return c&&c[b]||\"\"})}function p(a,\nb){for(var c=[],d=b.config.protectedSource,e=b._.dataStore||(b._.dataStore={id:1}),f=/<\\!--\\{cke_temp(comment)?\\}(\\d*?)--\\>/g,d=[/<script[\\s\\S]*?<\\/script>/gi,/<noscript[\\s\\S]*?<\\/noscript>/gi].concat(d),a=a.replace(/<\\!--[\\s\\S]*?--\\>/g,function(a){return\"<\\!--{cke_tempcomment}\"+(c.push(a)-1)+\"--\\>\"}),k=0;k<d.length;k++)a=a.replace(d[k],function(a){a=a.replace(f,function(a,b,d){return c[d]});return/cke_temp(comment)?/.test(a)?a:\"<\\!--{cke_temp}\"+(c.push(a)-1)+\"--\\>\"});a=a.replace(f,function(a,b,d){return\"<\\!--\"+\nm+(b?\"{C}\":\"\")+encodeURIComponent(c[d]).replace(/--/g,\"%2D%2D\")+\"--\\>\"});return a.replace(/(['\"]).*?\\1/g,function(a){return a.replace(/<\\!--\\{cke_protected\\}([\\s\\S]+?)--\\>/g,function(a,b){e[e.id]=decodeURIComponent(b);return\"{cke_protected_\"+e.id++ +\"}\"})})}CKEDITOR.htmlDataProcessor=function(b){var c,d,k=this;this.editor=b;this.dataFilter=c=new CKEDITOR.htmlParser.filter;this.htmlFilter=d=new CKEDITOR.htmlParser.filter;this.writer=new CKEDITOR.htmlParser.basicWriter;c.addRules(x);c.addRules(r,{applyToAll:true});\nc.addRules(a(b,\"data\"),{applyToAll:true});d.addRules(L);d.addRules(A,{applyToAll:true});d.addRules(a(b,\"html\"),{applyToAll:true});b.on(\"toHtml\",function(a){var a=a.data,c=a.dataValue,c=p(c,b),c=o(c,M),c=j(c),c=o(c,z),c=c.replace(v,\"$1cke:$2\"),c=c.replace(H,\"<cke:$1$2></cke:$1>\"),c=CKEDITOR.env.opera?c:c.replace(/(<pre\\b[^>]*>)(\\r\\n|\\n)/g,\"$1$2$2\"),d=a.context||b.editable().getName(),f;if(CKEDITOR.env.ie&&CKEDITOR.env.version<9&&d==\"pre\"){d=\"div\";c=\"<pre>\"+c+\"</pre>\";f=1}d=b.document.createElement(d);\nd.setHtml(\"a\"+c);c=d.getHtml().substr(1);c=c.replace(RegExp(\" data-cke-\"+CKEDITOR.rnd+\"-\",\"ig\"),\" \");f&&(c=c.replace(/^<pre>|<\\/pre>$/gi,\"\"));c=c.replace(w,\"$1$2\");c=q(c);c=u(c);a.dataValue=CKEDITOR.htmlParser.fragment.fromHtml(c,a.context,a.fixForBody===false?false:e(a.enterMode,b.config.autoParagraph))},null,null,5);b.on(\"toHtml\",function(a){a.data.filter.applyTo(a.data.dataValue,true,a.data.dontFilter,a.data.enterMode)&&b.fire(\"dataFiltered\")},null,null,6);b.on(\"toHtml\",function(a){a.data.dataValue.filterChildren(k.dataFilter,\ntrue)},null,null,10);b.on(\"toHtml\",function(a){var a=a.data,b=a.dataValue,c=new CKEDITOR.htmlParser.basicWriter;b.writeChildrenHtml(c);b=c.getHtml(true);a.dataValue=s(b)},null,null,15);b.on(\"toDataFormat\",function(a){var c=a.data.dataValue;a.data.enterMode!=CKEDITOR.ENTER_BR&&(c=c.replace(/^<br *\\/?>/i,\"\"));a.data.dataValue=CKEDITOR.htmlParser.fragment.fromHtml(c,a.data.context,e(a.data.enterMode,b.config.autoParagraph))},null,null,5);b.on(\"toDataFormat\",function(a){a.data.dataValue.filterChildren(k.htmlFilter,\ntrue)},null,null,10);b.on(\"toDataFormat\",function(a){a.data.filter.applyTo(a.data.dataValue,false,true)},null,null,11);b.on(\"toDataFormat\",function(a){var c=a.data.dataValue,d=k.writer;d.reset();c.writeChildrenHtml(d);c=d.getHtml(true);c=u(c);c=f(c,b);a.data.dataValue=c},null,null,15)};CKEDITOR.htmlDataProcessor.prototype={toHtml:function(a,b,c,d){var e=this.editor,f,k,l;if(b&&typeof b==\"object\"){f=b.context;c=b.fixForBody;d=b.dontFilter;k=b.filter;l=b.enterMode}else f=b;!f&&f!==null&&(f=e.editable().getName());\nreturn e.fire(\"toHtml\",{dataValue:a,context:f,fixForBody:c,dontFilter:d,filter:k||e.filter,enterMode:l||e.enterMode}).dataValue},toDataFormat:function(a,b){var c,d,e;if(b){c=b.context;d=b.filter;e=b.enterMode}!c&&c!==null&&(c=this.editor.editable().getName());return this.editor.fire(\"toDataFormat\",{dataValue:a,filter:d||this.editor.filter,context:c,enterMode:e||this.editor.enterMode}).dataValue}};var y=/(?:&nbsp;|\\xa0)$/,m=\"{cke_protected}\",k=CKEDITOR.dtd,l=[\"caption\",\"colgroup\",\"col\",\"thead\",\"tfoot\",\n\"tbody\"],t=CKEDITOR.tools.extend({},k.$blockLimit,k.$block),x={elements:{input:n,textarea:n}},r={attributeNames:[[/^on/,\"data-cke-pa-on\"],[/^data-cke-expando$/,\"\"]]},L={elements:{embed:function(a){var b=a.parent;if(b&&b.name==\"object\"){var c=b.attributes.width,b=b.attributes.height;if(c)a.attributes.width=c;if(b)a.attributes.height=b}},a:function(a){if(!a.children.length&&!a.attributes.name&&!a.attributes[\"data-cke-saved-name\"])return false}}},A={elementNames:[[/^cke:/,\"\"],[/^\\?xml:namespace$/,\"\"]],\nattributeNames:[[/^data-cke-(saved|pa)-/,\"\"],[/^data-cke-.*/,\"\"],[\"hidefocus\",\"\"]],elements:{$:function(a){var b=a.attributes;if(b){if(b[\"data-cke-temp\"])return false;for(var c=[\"name\",\"href\",\"src\"],d,e=0;e<c.length;e++){d=\"data-cke-saved-\"+c[e];d in b&&delete b[c[e]]}}return a},table:function(a){a.children.slice(0).sort(function(a,b){var c,d;if(a.type==CKEDITOR.NODE_ELEMENT&&b.type==a.type){c=CKEDITOR.tools.indexOf(l,a.name);d=CKEDITOR.tools.indexOf(l,b.name)}if(!(c>-1&&d>-1&&c!=d)){c=a.parent?a.getIndex():\n-1;d=b.parent?b.getIndex():-1}return c>d?1:-1})},param:function(a){a.children=[];a.isEmpty=true;return a},span:function(a){a.attributes[\"class\"]==\"Apple-style-span\"&&delete a.name},html:function(a){delete a.attributes.contenteditable;delete a.attributes[\"class\"]},body:function(a){delete a.attributes.spellcheck;delete a.attributes.contenteditable},style:function(a){var b=a.children[0];if(b&&b.value)b.value=CKEDITOR.tools.trim(b.value);if(!a.attributes.type)a.attributes.type=\"text/css\"},title:function(a){var b=\na.children[0];!b&&g(a,b=new CKEDITOR.htmlParser.text);b.value=a.attributes[\"data-cke-title\"]||\"\"},input:i,textarea:i},attributes:{\"class\":function(a){return CKEDITOR.tools.ltrim(a.replace(/(?:^|\\s+)cke_[^\\s]*/g,\"\"))||false}}};if(CKEDITOR.env.ie)A.attributes.style=function(a){return a.replace(/(^|;)([^\\:]+)/g,function(a){return a.toLowerCase()})};var I=/<(a|area|img|input|source)\\b([^>]*)>/gi,E=/\\s(on\\w+|href|src|name)\\s*=\\s*(?:(?:\"[^\"]*\")|(?:'[^']*')|(?:[^ \"'>]+))/gi,z=/(?:<style(?=[ >])[^>]*>[\\s\\S]*?<\\/style>)|(?:<(:?link|meta|base)[^>]*>)/gi,\nM=/(<textarea(?=[ >])[^>]*>)([\\s\\S]*?)(?:<\\/textarea>)/gi,Q=/<cke:encoded>([^<]*)<\\/cke:encoded>/gi,v=/(<\\/?)((?:object|embed|param|html|body|head|title)[^>]*>)/gi,w=/(<\\/?)cke:((?:html|body|head|title)[^>]*>)/gi,H=/<cke:(param|embed)([^>]*?)\\/?>(?!\\s*<\\/cke:\\1)/gi})();\"use strict\";\nCKEDITOR.htmlParser.element=function(a,e){this.name=a;this.attributes=e||{};this.children=[];var b=a||\"\",c=b.match(/^cke:(.*)/);c&&(b=c[1]);b=!(!CKEDITOR.dtd.$nonBodyContent[b]&&!CKEDITOR.dtd.$block[b]&&!CKEDITOR.dtd.$listItem[b]&&!CKEDITOR.dtd.$tableContent[b]&&!(CKEDITOR.dtd.$nonEditable[b]||b==\"br\"));this.isEmpty=!!CKEDITOR.dtd.$empty[a];this.isUnknown=!CKEDITOR.dtd[a];this._={isBlockLike:b,hasInlineStarted:this.isEmpty||!b}};\nCKEDITOR.htmlParser.cssStyle=function(a){var e={};((a instanceof CKEDITOR.htmlParser.element?a.attributes.style:a)||\"\").replace(/&quot;/g,'\"').replace(/\\s*([^ :;]+)\\s*:\\s*([^;]+)\\s*(?=;|$)/g,function(a,c,d){c==\"font-family\"&&(d=d.replace(/[\"']/g,\"\"));e[c.toLowerCase()]=d});return{rules:e,populate:function(a){var c=this.toString();if(c)a instanceof CKEDITOR.dom.element?a.setAttribute(\"style\",c):a instanceof CKEDITOR.htmlParser.element?a.attributes.style=c:a.style=c},toString:function(){var a=[],c;\nfor(c in e)e[c]&&a.push(c,\":\",e[c],\";\");return a.join(\"\")}}};\n(function(){function a(a){return function(b){return b.type==CKEDITOR.NODE_ELEMENT&&(typeof a==\"string\"?b.name==a:b.name in a)}}var e=function(a,b){a=a[0];b=b[0];return a<b?-1:a>b?1:0},b=CKEDITOR.htmlParser.fragment.prototype;CKEDITOR.htmlParser.element.prototype=CKEDITOR.tools.extend(new CKEDITOR.htmlParser.node,{type:CKEDITOR.NODE_ELEMENT,add:b.add,clone:function(){return new CKEDITOR.htmlParser.element(this.name,this.attributes)},filter:function(a,b){var e=this,g,n,b=e.getFilterContext(b);if(b.off)return true;\nif(!e.parent)a.onRoot(b,e);for(;;){g=e.name;if(!(n=a.onElementName(b,g))){this.remove();return false}e.name=n;if(!(e=a.onElement(b,e))){this.remove();return false}if(e!==this){this.replaceWith(e);return false}if(e.name==g)break;if(e.type!=CKEDITOR.NODE_ELEMENT){this.replaceWith(e);return false}if(!e.name){this.replaceWithChildren();return false}}g=e.attributes;var i,j;for(i in g){j=i;for(n=g[i];;)if(j=a.onAttributeName(b,i))if(j!=i){delete g[i];i=j}else break;else{delete g[i];break}j&&((n=a.onAttribute(b,\ne,j,n))===false?delete g[j]:g[j]=n)}e.isEmpty||this.filterChildren(a,false,b);return true},filterChildren:b.filterChildren,writeHtml:function(a,b){b&&this.filter(b);var h=this.name,g=[],n=this.attributes,i,j;a.openTag(h,n);for(i in n)g.push([i,n[i]]);a.sortAttributes&&g.sort(e);i=0;for(j=g.length;i<j;i++){n=g[i];a.attribute(n[0],n[1])}a.openTagClose(h,this.isEmpty);this.writeChildrenHtml(a);this.isEmpty||a.closeTag(h)},writeChildrenHtml:b.writeChildrenHtml,replaceWithChildren:function(){for(var a=\nthis.children,b=a.length;b;)a[--b].insertAfter(this);this.remove()},forEach:b.forEach,getFirst:function(b){if(!b)return this.children.length?this.children[0]:null;typeof b!=\"function\"&&(b=a(b));for(var d=0,e=this.children.length;d<e;++d)if(b(this.children[d]))return this.children[d];return null},getHtml:function(){var a=new CKEDITOR.htmlParser.basicWriter;this.writeChildrenHtml(a);return a.getHtml()},setHtml:function(a){for(var a=this.children=CKEDITOR.htmlParser.fragment.fromHtml(a).children,b=0,\ne=a.length;b<e;++b)a[b].parent=this},getOuterHtml:function(){var a=new CKEDITOR.htmlParser.basicWriter;this.writeHtml(a);return a.getHtml()},split:function(a){for(var b=this.children.splice(a,this.children.length-a),e=this.clone(),g=0;g<b.length;++g)b[g].parent=e;e.children=b;if(b[0])b[0].previous=null;if(a>0)this.children[a-1].next=null;this.parent.add(e,this.getIndex()+1);return e},removeClass:function(a){var b=this.attributes[\"class\"];if(b)(b=CKEDITOR.tools.trim(b.replace(RegExp(\"(?:\\\\s+|^)\"+a+\n\"(?:\\\\s+|$)\"),\" \")))?this.attributes[\"class\"]=b:delete this.attributes[\"class\"]},hasClass:function(a){var b=this.attributes[\"class\"];return!b?false:RegExp(\"(?:^|\\\\s)\"+a+\"(?=\\\\s|$)\").test(b)},getFilterContext:function(a){var b=[];a||(a={off:false,nonEditable:false});!a.off&&this.attributes[\"data-cke-processor\"]==\"off\"&&b.push(\"off\",true);!a.nonEditable&&this.attributes.contenteditable==\"false\"&&b.push(\"nonEditable\",true);if(b.length)for(var a=CKEDITOR.tools.copy(a),e=0;e<b.length;e=e+2)a[b[e]]=b[e+\n1];return a}},true)})();(function(){var a={};CKEDITOR.template=function(e){if(a[e])this.output=a[e];else{var b=e.replace(/'/g,\"\\\\'\").replace(/{([^}]+)}/g,function(a,b){return\"',data['\"+b+\"']==undefined?'{\"+b+\"}':data['\"+b+\"'],'\"});this.output=a[e]=Function(\"data\",\"buffer\",\"return buffer?buffer.push('\"+b+\"'):['\"+b+\"'].join('');\")}}})();delete CKEDITOR.loadFullCore;CKEDITOR.instances={};CKEDITOR.document=new CKEDITOR.dom.document(document);\nCKEDITOR.add=function(a){CKEDITOR.instances[a.name]=a;a.on(\"focus\",function(){if(CKEDITOR.currentInstance!=a){CKEDITOR.currentInstance=a;CKEDITOR.fire(\"currentInstance\")}});a.on(\"blur\",function(){if(CKEDITOR.currentInstance==a){CKEDITOR.currentInstance=null;CKEDITOR.fire(\"currentInstance\")}});CKEDITOR.fire(\"instance\",null,a)};CKEDITOR.remove=function(a){delete CKEDITOR.instances[a.name]};\n(function(){var a={};CKEDITOR.addTemplate=function(e,b){var c=a[e];if(c)return c;c={name:e,source:b};CKEDITOR.fire(\"template\",c);return a[e]=new CKEDITOR.template(c.source)};CKEDITOR.getTemplate=function(e){return a[e]}})();(function(){var a=[];CKEDITOR.addCss=function(e){a.push(e)};CKEDITOR.getCss=function(){return a.join(\"\\n\")}})();CKEDITOR.on(\"instanceDestroyed\",function(){CKEDITOR.tools.isEmpty(this.instances)&&CKEDITOR.fire(\"reset\")});CKEDITOR.TRISTATE_ON=1;CKEDITOR.TRISTATE_OFF=2;\nCKEDITOR.TRISTATE_DISABLED=0;\n(function(){CKEDITOR.inline=function(a,e){if(!CKEDITOR.env.isCompatible)return null;a=CKEDITOR.dom.element.get(a);if(a.getEditor())throw'The editor instance \"'+a.getEditor().name+'\" is already attached to the provided element.';var b=new CKEDITOR.editor(e,a,CKEDITOR.ELEMENT_MODE_INLINE),c=a.is(\"textarea\")?a:null;if(c){b.setData(c.getValue(),null,true);a=CKEDITOR.dom.element.createFromHtml('<div contenteditable=\"'+!!b.readOnly+'\" class=\"cke_textarea_inline\">'+c.getValue()+\"</div>\",CKEDITOR.document);\na.insertAfter(c);c.hide();c.$.form&&b._attachToForm()}else b.setData(a.getHtml(),null,true);b.on(\"loaded\",function(){b.fire(\"uiReady\");b.editable(a);b.container=a;b.setData(b.getData(1));b.resetDirty();b.fire(\"contentDom\");b.mode=\"wysiwyg\";b.fire(\"mode\");b.status=\"ready\";b.fireOnce(\"instanceReady\");CKEDITOR.fire(\"instanceReady\",null,b)},null,null,1E4);b.on(\"destroy\",function(){if(c){b.container.clearCustomData();b.container.remove();c.show()}b.element.clearCustomData();delete b.element});return b};\nCKEDITOR.inlineAll=function(){var a,e,b;for(b in CKEDITOR.dtd.$editable)for(var c=CKEDITOR.document.getElementsByTag(b),d=0,h=c.count();d<h;d++){a=c.getItem(d);if(a.getAttribute(\"contenteditable\")==\"true\"){e={element:a,config:{}};CKEDITOR.fire(\"inline\",e)!==false&&CKEDITOR.inline(a,e.config)}}};CKEDITOR.domReady(function(){!CKEDITOR.disableAutoInline&&CKEDITOR.inlineAll()})})();CKEDITOR.replaceClass=\"ckeditor\";\n(function(){function a(a,c,g,n){if(!CKEDITOR.env.isCompatible)return null;a=CKEDITOR.dom.element.get(a);if(a.getEditor())throw'The editor instance \"'+a.getEditor().name+'\" is already attached to the provided element.';var i=new CKEDITOR.editor(c,a,n);if(n==CKEDITOR.ELEMENT_MODE_REPLACE){a.setStyle(\"visibility\",\"hidden\");i._.required=a.hasAttribute(\"required\");a.removeAttribute(\"required\")}g&&i.setData(g,null,true);i.on(\"loaded\",function(){b(i);n==CKEDITOR.ELEMENT_MODE_REPLACE&&(i.config.autoUpdateElement&&\na.$.form)&&i._attachToForm();i.setMode(i.config.startupMode,function(){i.resetDirty();i.status=\"ready\";i.fireOnce(\"instanceReady\");CKEDITOR.fire(\"instanceReady\",null,i)})});i.on(\"destroy\",e);return i}function e(){var a=this.container,b=this.element;if(a){a.clearCustomData();a.remove()}if(b){b.clearCustomData();if(this.elementMode==CKEDITOR.ELEMENT_MODE_REPLACE){b.show();this._.required&&b.setAttribute(\"required\",\"required\")}delete this.element}}function b(a){var b=a.name,e=a.element,n=a.elementMode,\ni=a.fire(\"uiSpace\",{space:\"top\",html:\"\"}).html,j=a.fire(\"uiSpace\",{space:\"bottom\",html:\"\"}).html;c||(c=CKEDITOR.addTemplate(\"maincontainer\",'<{outerEl} id=\"cke_{name}\" class=\"{id} cke cke_reset cke_chrome cke_editor_{name} cke_{langDir} '+CKEDITOR.env.cssClass+'\"  dir=\"{langDir}\" lang=\"{langCode}\" role=\"application\" aria-labelledby=\"cke_{name}_arialbl\"><span id=\"cke_{name}_arialbl\" class=\"cke_voice_label\">{voiceLabel}</span><{outerEl} class=\"cke_inner cke_reset\" role=\"presentation\">{topHtml}<{outerEl} id=\"{contentId}\" class=\"cke_contents cke_reset\" role=\"presentation\"></{outerEl}>{bottomHtml}</{outerEl}></{outerEl}>'));\nb=CKEDITOR.dom.element.createFromHtml(c.output({id:a.id,name:b,langDir:a.lang.dir,langCode:a.langCode,voiceLabel:[a.lang.editor,a.name].join(\", \"),topHtml:i?'<span id=\"'+a.ui.spaceId(\"top\")+'\" class=\"cke_top cke_reset_all\" role=\"presentation\" style=\"height:auto\">'+i+\"</span>\":\"\",contentId:a.ui.spaceId(\"contents\"),bottomHtml:j?'<span id=\"'+a.ui.spaceId(\"bottom\")+'\" class=\"cke_bottom cke_reset_all\" role=\"presentation\">'+j+\"</span>\":\"\",outerEl:CKEDITOR.env.ie?\"span\":\"div\"}));if(n==CKEDITOR.ELEMENT_MODE_REPLACE){e.hide();\nb.insertAfter(e)}else e.append(b);a.container=b;i&&a.ui.space(\"top\").unselectable();j&&a.ui.space(\"bottom\").unselectable();e=a.config.width;n=a.config.height;e&&b.setStyle(\"width\",CKEDITOR.tools.cssLength(e));n&&a.ui.space(\"contents\").setStyle(\"height\",CKEDITOR.tools.cssLength(n));b.disableContextMenu();CKEDITOR.env.webkit&&b.on(\"focus\",function(){a.focus()});a.fireOnce(\"uiReady\")}CKEDITOR.replace=function(b,c){return a(b,c,null,CKEDITOR.ELEMENT_MODE_REPLACE)};CKEDITOR.appendTo=function(b,c,e){return a(b,\nc,e,CKEDITOR.ELEMENT_MODE_APPENDTO)};CKEDITOR.replaceAll=function(){for(var a=document.getElementsByTagName(\"textarea\"),b=0;b<a.length;b++){var c=null,e=a[b];if(e.name||e.id){if(typeof arguments[0]==\"string\"){if(!RegExp(\"(?:^|\\\\s)\"+arguments[0]+\"(?:$|\\\\s)\").test(e.className))continue}else if(typeof arguments[0]==\"function\"){c={};if(arguments[0](e,c)===false)continue}this.replace(e,c)}}};CKEDITOR.editor.prototype.addMode=function(a,b){(this._.modes||(this._.modes={}))[a]=b};CKEDITOR.editor.prototype.setMode=\nfunction(a,b){var c=this,e=this._.modes;if(!(a==c.mode||!e||!e[a])){c.fire(\"beforeSetMode\",a);if(c.mode){var i=c.checkDirty();c._.previousMode=c.mode;c.fire(\"beforeModeUnload\");c.editable(0);c.ui.space(\"contents\").setHtml(\"\");c.mode=\"\"}this._.modes[a](function(){c.mode=a;i!==void 0&&!i&&c.resetDirty();setTimeout(function(){c.fire(\"mode\");b&&b.call(c)},0)})}};CKEDITOR.editor.prototype.resize=function(a,b,c,e){var i=this.container,j=this.ui.space(\"contents\"),o=CKEDITOR.env.webkit&&this.document&&this.document.getWindow().$.frameElement,\ne=e?i.getChild(1):i;e.setSize(\"width\",a,true);o&&(o.style.width=\"1%\");j.setStyle(\"height\",Math.max(b-(c?0:(e.$.offsetHeight||0)-(j.$.clientHeight||0)),0)+\"px\");o&&(o.style.width=\"100%\");this.fire(\"resize\")};CKEDITOR.editor.prototype.getResizable=function(a){return a?this.ui.space(\"contents\"):this.container};var c;CKEDITOR.domReady(function(){CKEDITOR.replaceClass&&CKEDITOR.replaceAll(CKEDITOR.replaceClass)})})();CKEDITOR.config.startupMode=\"wysiwyg\";\n(function(){function a(a){var b=a.editor,d=a.data.path,m=d.blockLimit,k=a.data.selection,l=k.getRanges()[0],g;if(CKEDITOR.env.gecko||CKEDITOR.env.ie&&CKEDITOR.env.needsBrFiller)if(k=e(k,d)){k.appendBogus();g=CKEDITOR.env.ie}if(b.config.autoParagraph!==false&&b.activeEnterMode!=CKEDITOR.ENTER_BR&&b.editable().equals(m)&&!d.block&&l.collapsed&&!l.getCommonAncestor().isReadOnly()){d=l.clone();d.enlarge(CKEDITOR.ENLARGE_BLOCK_CONTENTS);m=new CKEDITOR.dom.walker(d);m.guard=function(a){return!c(a)||a.type==\nCKEDITOR.NODE_COMMENT||a.isReadOnly()};if(!m.checkForward()||d.checkStartOfBlock()&&d.checkEndOfBlock()){b=l.fixBlock(true,b.activeEnterMode==CKEDITOR.ENTER_DIV?\"div\":\"p\");if(!CKEDITOR.env.needsBrFiller)(b=b.getFirst(c))&&(b.type==CKEDITOR.NODE_TEXT&&CKEDITOR.tools.trim(b.getText()).match(/^(?:&nbsp;|\\xa0)$/))&&b.remove();g=1;a.cancel()}}g&&l.select()}function e(a,b){if(a.isFake)return 0;var e=b.block||b.blockLimit,d=e&&e.getLast(c);if(e&&e.isBlockBoundary()&&(!d||!(d.type==CKEDITOR.NODE_ELEMENT&&\nd.isBlockBoundary()))&&!e.is(\"pre\")&&!e.getBogus())return e}function b(a){var b=a.data.getTarget();if(b.is(\"input\")){b=b.getAttribute(\"type\");(b==\"submit\"||b==\"reset\")&&a.data.preventDefault()}}function c(a){return o(a)&&q(a)}function d(a,b){return function(c){var e=CKEDITOR.dom.element.get(c.data.$.toElement||c.data.$.fromElement||c.data.$.relatedTarget);(!e||!b.equals(e)&&!b.contains(e))&&a.call(this,c)}}function h(a){var b,e=a.getRanges()[0],d=a.root,k={table:1,ul:1,ol:1,dl:1};if(e.startPath().contains(k)){var a=\nfunction(a){return function(e,d){d&&(e.type==CKEDITOR.NODE_ELEMENT&&e.is(k))&&(b=e);if(!d&&c(e)&&(!a||!i(e)))return false}},l=e.clone();l.collapse(1);l.setStartAt(d,CKEDITOR.POSITION_AFTER_START);d=new CKEDITOR.dom.walker(l);d.guard=a();d.checkBackward();if(b){l=e.clone();l.collapse();l.setEndAt(b,CKEDITOR.POSITION_AFTER_END);d=new CKEDITOR.dom.walker(l);d.guard=a(true);b=false;d.checkForward();return b}}return null}function g(a){a.editor.focus();a.editor.fire(\"saveSnapshot\")}function n(a,b){var c=\na.editor;!b&&c.getSelection().scrollIntoView();setTimeout(function(){c.fire(\"saveSnapshot\")},0)}CKEDITOR.editable=CKEDITOR.tools.createClass({base:CKEDITOR.dom.element,$:function(a,b){this.base(b.$||b);this.editor=a;this.hasFocus=false;this.setup()},proto:{focus:function(){var a;if(CKEDITOR.env.webkit&&!this.hasFocus){a=this.editor._.previousActive||this.getDocument().getActive();if(this.contains(a)){a.focus();return}}try{this.$[CKEDITOR.env.ie&&this.getDocument().equals(CKEDITOR.document)?\"setActive\":\n\"focus\"]()}catch(b){if(!CKEDITOR.env.ie)throw b;}if(CKEDITOR.env.safari&&!this.isInline()){a=CKEDITOR.document.getActive();a.equals(this.getWindow().getFrame())||this.getWindow().focus()}},on:function(a,b){var c=Array.prototype.slice.call(arguments,0);if(CKEDITOR.env.ie&&/^focus|blur$/.exec(a)){a=a==\"focus\"?\"focusin\":\"focusout\";b=d(b,this);c[0]=a;c[1]=b}return CKEDITOR.dom.element.prototype.on.apply(this,c)},attachListener:function(a,b,c,e,d,l){!this._.listeners&&(this._.listeners=[]);var g=Array.prototype.slice.call(arguments,\n1),g=a.on.apply(a,g);this._.listeners.push(g);return g},clearListeners:function(){var a=this._.listeners;try{for(;a.length;)a.pop().removeListener()}catch(b){}},restoreAttrs:function(){var a=this._.attrChanges,b,c;for(c in a)if(a.hasOwnProperty(c)){b=a[c];b!==null?this.setAttribute(c,b):this.removeAttribute(c)}},attachClass:function(a){var b=this.getCustomData(\"classes\");if(!this.hasClass(a)){!b&&(b=[]);b.push(a);this.setCustomData(\"classes\",b);this.addClass(a)}},changeAttr:function(a,b){var c=this.getAttribute(a);\nif(b!==c){!this._.attrChanges&&(this._.attrChanges={});a in this._.attrChanges||(this._.attrChanges[a]=c);this.setAttribute(a,b)}},insertHtml:function(a,b){g(this);s(this,b||\"html\",a)},insertText:function(a){g(this);var b=this.editor,c=b.getSelection().getStartElement().hasAscendant(\"pre\",true)?CKEDITOR.ENTER_BR:b.activeEnterMode,b=c==CKEDITOR.ENTER_BR,e=CKEDITOR.tools,a=e.htmlEncode(a.replace(/\\r\\n/g,\"\\n\")),a=a.replace(/\\t/g,\"&nbsp;&nbsp; &nbsp;\"),c=c==CKEDITOR.ENTER_P?\"p\":\"div\";if(!b){var d=/\\n{2}/g;\nif(d.test(a))var l=\"<\"+c+\">\",h=\"</\"+c+\">\",a=l+a.replace(d,function(){return h+l})+h}a=a.replace(/\\n/g,\"<br>\");b||(a=a.replace(RegExp(\"<br>(?=</\"+c+\">)\"),function(a){return e.repeat(a,2)}));a=a.replace(/^ | $/g,\"&nbsp;\");a=a.replace(/(>|\\s) /g,function(a,b){return b+\"&nbsp;\"}).replace(/ (?=<)/g,\"&nbsp;\");s(this,\"text\",a)},insertElement:function(a,b){b?this.insertElementIntoRange(a,b):this.insertElementIntoSelection(a)},insertElementIntoRange:function(a,b){var c=this.editor,e=c.config.enterMode,d=a.getName(),\nl=CKEDITOR.dtd.$block[d];if(b.checkReadOnly())return false;b.deleteContents(1);b.startContainer.type==CKEDITOR.NODE_ELEMENT&&b.startContainer.is({tr:1,table:1,tbody:1,thead:1,tfoot:1})&&u(b);var g,h;if(l)for(;(g=b.getCommonAncestor(0,1))&&(h=CKEDITOR.dtd[g.getName()])&&(!h||!h[d]);)if(g.getName()in CKEDITOR.dtd.span)b.splitElement(g);else if(b.checkStartOfBlock()&&b.checkEndOfBlock()){b.setStartBefore(g);b.collapse(true);g.remove()}else b.splitBlock(e==CKEDITOR.ENTER_DIV?\"div\":\"p\",c.editable());b.insertNode(a);\nreturn true},insertElementIntoSelection:function(a){var b=this.editor,e=b.activeEnterMode,b=b.getSelection(),d=b.getRanges()[0],k=a.getName(),k=CKEDITOR.dtd.$block[k];g(this);if(this.insertElementIntoRange(a,d)){d.moveToPosition(a,CKEDITOR.POSITION_AFTER_END);if(k)if((k=a.getNext(function(a){return c(a)&&!i(a)}))&&k.type==CKEDITOR.NODE_ELEMENT&&k.is(CKEDITOR.dtd.$block))k.getDtd()[\"#\"]?d.moveToElementEditStart(k):d.moveToElementEditEnd(a);else if(!k&&e!=CKEDITOR.ENTER_BR){k=d.fixBlock(true,e==CKEDITOR.ENTER_DIV?\n\"div\":\"p\");d.moveToElementEditStart(k)}}b.selectRanges([d]);n(this,CKEDITOR.env.opera)},setData:function(a,b){b||(a=this.editor.dataProcessor.toHtml(a));this.setHtml(a);this.editor.fire(\"dataReady\")},getData:function(a){var b=this.getHtml();a||(b=this.editor.dataProcessor.toDataFormat(b));return b},setReadOnly:function(a){this.setAttribute(\"contenteditable\",!a)},detach:function(){this.removeClass(\"cke_editable\");var a=this.editor;this._.detach();delete a.document;delete a.window},isInline:function(){return this.getDocument().equals(CKEDITOR.document)},\nsetup:function(){var a=this.editor;this.attachListener(a,\"beforeGetData\",function(){var b=this.getData();this.is(\"textarea\")||a.config.ignoreEmptyParagraph!==false&&(b=b.replace(j,function(a,b){return b}));a.setData(b,null,1)},this);this.attachListener(a,\"getSnapshot\",function(a){a.data=this.getData(1)},this);this.attachListener(a,\"afterSetData\",function(){this.setData(a.getData(1))},this);this.attachListener(a,\"loadSnapshot\",function(a){this.setData(a.data,1)},this);this.attachListener(a,\"beforeFocus\",\nfunction(){var b=a.getSelection();(b=b&&b.getNative())&&b.type==\"Control\"||this.focus()},this);this.attachListener(a,\"insertHtml\",function(a){this.insertHtml(a.data.dataValue,a.data.mode)},this);this.attachListener(a,\"insertElement\",function(a){this.insertElement(a.data)},this);this.attachListener(a,\"insertText\",function(a){this.insertText(a.data)},this);this.setReadOnly(a.readOnly);this.attachClass(\"cke_editable\");this.attachClass(a.elementMode==CKEDITOR.ELEMENT_MODE_INLINE?\"cke_editable_inline\":\na.elementMode==CKEDITOR.ELEMENT_MODE_REPLACE||a.elementMode==CKEDITOR.ELEMENT_MODE_APPENDTO?\"cke_editable_themed\":\"\");this.attachClass(\"cke_contents_\"+a.config.contentsLangDirection);a.keystrokeHandler.blockedKeystrokes[8]=+a.readOnly;a.keystrokeHandler.attach(this);this.on(\"blur\",function(a){CKEDITOR.env.opera&&CKEDITOR.document.getActive().equals(this.isInline()?this:this.getWindow().getFrame())?a.cancel():this.hasFocus=false},null,null,-1);this.on(\"focus\",function(){this.hasFocus=true},null,null,\n-1);a.focusManager.add(this);if(this.equals(CKEDITOR.document.getActive())){this.hasFocus=true;a.once(\"contentDom\",function(){a.focusManager.focus()})}this.isInline()&&this.changeAttr(\"tabindex\",a.tabIndex);if(!this.is(\"textarea\")){a.document=this.getDocument();a.window=this.getWindow();var e=a.document;this.changeAttr(\"spellcheck\",!a.config.disableNativeSpellChecker);var d=a.config.contentsLangDirection;this.getDirection(1)!=d&&this.changeAttr(\"dir\",d);var m=CKEDITOR.getCss();if(m){d=e.getHead();\nif(!d.getCustomData(\"stylesheet\")){m=e.appendStyleText(m);m=new CKEDITOR.dom.element(m.ownerNode||m.owningElement);d.setCustomData(\"stylesheet\",m);m.data(\"cke-temp\",1)}}d=e.getCustomData(\"stylesheet_ref\")||0;e.setCustomData(\"stylesheet_ref\",d+1);this.setCustomData(\"cke_includeReadonly\",!a.config.disableReadonlyStyling);this.attachListener(this,\"click\",function(a){var a=a.data,b=(new CKEDITOR.dom.elementPath(a.getTarget(),this)).contains(\"a\");b&&(a.$.button!=2&&b.isReadOnly())&&a.preventDefault()});\nvar k={8:1,46:1};this.attachListener(a,\"key\",function(b){if(a.readOnly)return true;var c=b.data.keyCode,e;if(c in k){var b=a.getSelection(),d,m=b.getRanges()[0],g=m.startPath(),i,j,n,c=c==8;if(CKEDITOR.env.ie&&CKEDITOR.env.version<11&&(d=b.getSelectedElement())||(d=h(b))){a.fire(\"saveSnapshot\");m.moveToPosition(d,CKEDITOR.POSITION_BEFORE_START);d.remove();m.select();a.fire(\"saveSnapshot\");e=1}else if(m.collapsed)if((i=g.block)&&(n=i[c?\"getPrevious\":\"getNext\"](o))&&n.type==CKEDITOR.NODE_ELEMENT&&n.is(\"table\")&&\nm[c?\"checkStartOfBlock\":\"checkEndOfBlock\"]()){a.fire(\"saveSnapshot\");m[c?\"checkEndOfBlock\":\"checkStartOfBlock\"]()&&i.remove();m[\"moveToElementEdit\"+(c?\"End\":\"Start\")](n);m.select();a.fire(\"saveSnapshot\");e=1}else if(g.blockLimit&&g.blockLimit.is(\"td\")&&(j=g.blockLimit.getAscendant(\"table\"))&&m.checkBoundaryOfElement(j,c?CKEDITOR.START:CKEDITOR.END)&&(n=j[c?\"getPrevious\":\"getNext\"](o))){a.fire(\"saveSnapshot\");m[\"moveToElementEdit\"+(c?\"End\":\"Start\")](n);m.checkStartOfBlock()&&m.checkEndOfBlock()?n.remove():\nm.select();a.fire(\"saveSnapshot\");e=1}else if((j=g.contains([\"td\",\"th\",\"caption\"]))&&m.checkBoundaryOfElement(j,c?CKEDITOR.START:CKEDITOR.END))e=1}return!e});a.blockless&&(CKEDITOR.env.ie&&CKEDITOR.env.needsBrFiller)&&this.attachListener(this,\"keyup\",function(b){if(b.data.getKeystroke()in k&&!this.getFirst(c)){this.appendBogus();b=a.createRange();b.moveToPosition(this,CKEDITOR.POSITION_AFTER_START);b.select()}});this.attachListener(this,\"dblclick\",function(b){if(a.readOnly)return false;b={element:b.data.getTarget()};\na.fire(\"doubleclick\",b)});CKEDITOR.env.ie&&this.attachListener(this,\"click\",b);!CKEDITOR.env.ie&&!CKEDITOR.env.opera&&this.attachListener(this,\"mousedown\",function(b){var c=b.data.getTarget();if(c.is(\"img\",\"hr\",\"input\",\"textarea\",\"select\")){a.getSelection().selectElement(c);c.is(\"input\",\"textarea\",\"select\")&&b.data.preventDefault()}});CKEDITOR.env.gecko&&this.attachListener(this,\"mouseup\",function(b){if(b.data.$.button==2){b=b.data.getTarget();if(!b.getOuterHtml().replace(j,\"\")){var c=a.createRange();\nc.moveToElementEditStart(b);c.select(true)}}});if(CKEDITOR.env.webkit){this.attachListener(this,\"click\",function(a){a.data.getTarget().is(\"input\",\"select\")&&a.data.preventDefault()});this.attachListener(this,\"mouseup\",function(a){a.data.getTarget().is(\"input\",\"textarea\")&&a.data.preventDefault()})}}}},_:{detach:function(){this.editor.setData(this.editor.getData(),0,1);this.clearListeners();this.restoreAttrs();var a;if(a=this.removeCustomData(\"classes\"))for(;a.length;)this.removeClass(a.pop());a=this.getDocument();\nvar b=a.getHead();if(b.getCustomData(\"stylesheet\")){var c=a.getCustomData(\"stylesheet_ref\");if(--c)a.setCustomData(\"stylesheet_ref\",c);else{a.removeCustomData(\"stylesheet_ref\");b.removeCustomData(\"stylesheet\").remove()}}delete this.editor}}});CKEDITOR.editor.prototype.editable=function(a){var b=this._.editable;if(b&&a)return 0;if(arguments.length)b=this._.editable=a?a instanceof CKEDITOR.editable?a:new CKEDITOR.editable(this,a):(b&&b.detach(),null);return b};var i=CKEDITOR.dom.walker.bogus(),j=/(^|<body\\b[^>]*>)\\s*<(p|div|address|h\\d|center|pre)[^>]*>\\s*(?:<br[^>]*>|&nbsp;|\\u00A0|&#160;)?\\s*(:?<\\/\\2>)?\\s*(?=$|<\\/body>)/gi,\no=CKEDITOR.dom.walker.whitespaces(true),q=CKEDITOR.dom.walker.bookmark(false,true);CKEDITOR.on(\"instanceLoaded\",function(b){var c=b.editor;c.on(\"insertElement\",function(a){a=a.data;if(a.type==CKEDITOR.NODE_ELEMENT&&(a.is(\"input\")||a.is(\"textarea\"))){a.getAttribute(\"contentEditable\")!=\"false\"&&a.data(\"cke-editable\",a.hasAttribute(\"contenteditable\")?\"true\":\"1\");a.setAttribute(\"contentEditable\",false)}});c.on(\"selectionChange\",function(b){if(!c.readOnly){var e=c.getSelection();if(e&&!e.isLocked){e=c.checkDirty();\nc.fire(\"lockSnapshot\");a(b);c.fire(\"unlockSnapshot\");!e&&c.resetDirty()}}})});CKEDITOR.on(\"instanceCreated\",function(a){var b=a.editor;b.on(\"mode\",function(){var a=b.editable();if(a&&a.isInline()){var c=b.title;a.changeAttr(\"role\",\"textbox\");a.changeAttr(\"aria-label\",c);c&&a.changeAttr(\"title\",c);if(c=this.ui.space(this.elementMode==CKEDITOR.ELEMENT_MODE_INLINE?\"top\":\"contents\")){var e=CKEDITOR.tools.getNextId(),d=CKEDITOR.dom.element.createFromHtml('<span id=\"'+e+'\" class=\"cke_voice_label\">'+this.lang.common.editorHelp+\n\"</span>\");c.append(d);a.changeAttr(\"aria-describedby\",e)}}})});CKEDITOR.addCss(\".cke_editable{cursor:text}.cke_editable img,.cke_editable input,.cke_editable textarea{cursor:default}\");var s=function(){function a(b){return b.type==CKEDITOR.NODE_ELEMENT}function b(c,e){var d,k,m,l,h=[],i=e.range.startContainer;d=e.range.startPath();for(var i=g[i.getName()],r=0,j=c.getChildren(),n=j.count(),o=-1,q=-1,x=0,s=d.contains(g.$list);r<n;++r){d=j.getItem(r);if(a(d)){m=d.getName();if(s&&m in CKEDITOR.dtd.$list)h=\nh.concat(b(d,e));else{l=!!i[m];if(m==\"br\"&&d.data(\"cke-eol\")&&(!r||r==n-1)){x=(k=r?h[r-1].node:j.getItem(r+1))&&(!a(k)||!k.is(\"br\"));k=k&&a(k)&&g.$block[k.getName()]}o==-1&&!l&&(o=r);l||(q=r);h.push({isElement:1,isLineBreak:x,isBlock:d.isBlockBoundary(),hasBlockSibling:k,node:d,name:m,allowed:l});k=x=0}}else h.push({isElement:0,node:d,allowed:1})}if(o>-1)h[o].firstNotAllowed=1;if(q>-1)h[q].lastNotAllowed=1;return h}function e(b,c){var d=[],k=b.getChildren(),m=k.count(),l,h=0,r=g[c],i=!b.is(g.$inline)||\nb.is(\"br\");for(i&&d.push(\" \");h<m;h++){l=k.getItem(h);a(l)&&!l.is(r)?d=d.concat(e(l,c)):d.push(l)}i&&d.push(\" \");return d}function d(b){return b&&a(b)&&(b.is(g.$removeEmpty)||b.is(\"a\")&&!b.isBlockBoundary())}function k(b,c,e,d){var l=b.clone(),m,g;l.setEndAt(c,CKEDITOR.POSITION_BEFORE_END);if((m=(new CKEDITOR.dom.walker(l)).next())&&a(m)&&h[m.getName()]&&(g=m.getPrevious())&&a(g)&&!g.getParent().equals(b.startContainer)&&e.contains(g)&&d.contains(m)&&m.isIdentical(g)){m.moveChildren(g);m.remove();\nk(b,c,e,d)}}function l(b,c){function e(b,c){if(c.isBlock&&c.isElement&&!c.node.is(\"br\")&&a(b)&&b.is(\"br\")){b.remove();return 1}}var d=c.endContainer.getChild(c.endOffset),k=c.endContainer.getChild(c.endOffset-1);d&&e(d,b[b.length-1]);if(k&&e(k,b[0])){c.setEnd(c.endContainer,c.endOffset-1);c.collapse()}}var g=CKEDITOR.dtd,h={p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,ul:1,ol:1,li:1,pre:1,dl:1,blockquote:1},r={p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1},i=CKEDITOR.tools.extend({},g.$inline);delete i.br;return function(h,\nj,o){var q=h.editor;h.getDocument();var x=q.getSelection().getRanges()[0],s=false;if(j==\"unfiltered_html\"){j=\"html\";s=true}if(!x.checkReadOnly()){var v=(new CKEDITOR.dom.elementPath(x.startContainer,x.root)).blockLimit||x.root,j={type:j,dontFilter:s,editable:h,editor:q,range:x,blockLimit:v,mergeCandidates:[],zombies:[]},q=j.range,s=j.mergeCandidates,w,H,C,D;if(j.type==\"text\"&&q.shrink(CKEDITOR.SHRINK_ELEMENT,true,false)){w=CKEDITOR.dom.element.createFromHtml(\"<span>&nbsp;</span>\",q.document);q.insertNode(w);\nq.setStartAfter(w)}H=new CKEDITOR.dom.elementPath(q.startContainer);j.endPath=C=new CKEDITOR.dom.elementPath(q.endContainer);if(!q.collapsed){var v=C.block||C.blockLimit,X=q.getCommonAncestor();v&&(!v.equals(X)&&!v.contains(X)&&q.checkEndOfBlock())&&j.zombies.push(v);q.deleteContents()}for(;(D=a(q.startContainer)&&q.startContainer.getChild(q.startOffset-1))&&a(D)&&D.isBlockBoundary()&&H.contains(D);)q.moveToPosition(D,CKEDITOR.POSITION_BEFORE_END);k(q,j.blockLimit,H,C);if(w){q.setEndBefore(w);q.collapse();\nw.remove()}w=q.startPath();if(v=w.contains(d,false,1)){q.splitElement(v);j.inlineStylesRoot=v;j.inlineStylesPeak=w.lastElement}w=q.createBookmark();(v=w.startNode.getPrevious(c))&&a(v)&&d(v)&&s.push(v);(v=w.startNode.getNext(c))&&a(v)&&d(v)&&s.push(v);for(v=w.startNode;(v=v.getParent())&&d(v);)s.push(v);q.moveToBookmark(w);if(w=o){w=j.range;if(j.type==\"text\"&&j.inlineStylesRoot){D=j.inlineStylesPeak;q=D.getDocument().createText(\"{cke-peak}\");for(s=j.inlineStylesRoot.getParent();!D.equals(s);){q=q.appendTo(D.clone());\nD=D.getParent()}o=q.getOuterHtml().split(\"{cke-peak}\").join(o)}D=j.blockLimit.getName();if(/^\\s+|\\s+$/.test(o)&&\"span\"in CKEDITOR.dtd[D])var u='<span data-cke-marker=\"1\">&nbsp;</span>',o=u+o+u;o=j.editor.dataProcessor.toHtml(o,{context:null,fixForBody:false,dontFilter:j.dontFilter,filter:j.editor.activeFilter,enterMode:j.editor.activeEnterMode});D=w.document.createElement(\"body\");D.setHtml(o);if(u){D.getFirst().remove();D.getLast().remove()}if((u=w.startPath().block)&&!(u.getChildCount()==1&&u.getBogus()))a:{var F;\nif(D.getChildCount()==1&&a(F=D.getFirst())&&F.is(r)){u=F.getElementsByTag(\"*\");w=0;for(s=u.count();w<s;w++){q=u.getItem(w);if(!q.is(i))break a}F.moveChildren(F.getParent(1));F.remove()}}j.dataWrapper=D;w=o}if(w){F=j.range;var u=F.document,B,o=j.blockLimit;w=0;var J;D=[];var G,O,s=q=0,K,R;H=F.startContainer;var v=j.endPath.elements[0],S;C=v.getPosition(H);X=!!v.getCommonAncestor(H)&&C!=CKEDITOR.POSITION_IDENTICAL&&!(C&CKEDITOR.POSITION_CONTAINS+CKEDITOR.POSITION_IS_CONTAINED);H=b(j.dataWrapper,j);\nfor(l(H,F);w<H.length;w++){C=H[w];if(B=C.isLineBreak){B=F;K=o;var N=void 0,U=void 0;if(C.hasBlockSibling)B=1;else{N=B.startContainer.getAscendant(g.$block,1);if(!N||!N.is({div:1,p:1}))B=0;else{U=N.getPosition(K);if(U==CKEDITOR.POSITION_IDENTICAL||U==CKEDITOR.POSITION_CONTAINS)B=0;else{K=B.splitElement(N);B.moveToPosition(K,CKEDITOR.POSITION_AFTER_START);B=1}}}}if(B)s=w>0;else{B=F.startPath();if(!C.isBlock&&j.editor.config.autoParagraph!==false&&(j.editor.activeEnterMode!=CKEDITOR.ENTER_BR&&j.editor.editable().equals(B.blockLimit)&&\n!B.block)&&(O=j.editor.activeEnterMode!=CKEDITOR.ENTER_BR&&j.editor.config.autoParagraph!==false?j.editor.activeEnterMode==CKEDITOR.ENTER_DIV?\"div\":\"p\":false)){O=u.createElement(O);O.appendBogus();F.insertNode(O);CKEDITOR.env.needsBrFiller&&(J=O.getBogus())&&J.remove();F.moveToPosition(O,CKEDITOR.POSITION_BEFORE_END)}if((B=F.startPath().block)&&!B.equals(G)){if(J=B.getBogus()){J.remove();D.push(B)}G=B}C.firstNotAllowed&&(q=1);if(q&&C.isElement){B=F.startContainer;for(K=null;B&&!g[B.getName()][C.name];){if(B.equals(o)){B=\nnull;break}K=B;B=B.getParent()}if(B){if(K){R=F.splitElement(K);j.zombies.push(R);j.zombies.push(K)}}else{K=o.getName();S=!w;B=w==H.length-1;K=e(C.node,K);for(var N=[],U=K.length,Y=0,$=void 0,aa=0,ba=-1;Y<U;Y++){$=K[Y];if($==\" \"){if(!aa&&(!S||Y)){N.push(new CKEDITOR.dom.text(\" \"));ba=N.length}aa=1}else{N.push($);aa=0}}B&&ba==N.length&&N.pop();S=N}}if(S){for(;B=S.pop();)F.insertNode(B);S=0}else F.insertNode(C.node);if(C.lastNotAllowed&&w<H.length-1){(R=X?v:R)&&F.setEndAt(R,CKEDITOR.POSITION_AFTER_START);\nq=0}F.collapse()}}j.dontMoveCaret=s;j.bogusNeededBlocks=D}J=j.range;var V;R=j.bogusNeededBlocks;for(S=J.createBookmark();G=j.zombies.pop();)if(G.getParent()){O=J.clone();O.moveToElementEditStart(G);O.removeEmptyBlocksAtEnd()}if(R)for(;G=R.pop();)CKEDITOR.env.needsBrFiller?G.appendBogus():G.append(J.document.createText(\" \"));for(;G=j.mergeCandidates.pop();)G.mergeSiblings();J.moveToBookmark(S);if(!j.dontMoveCaret){for(G=a(J.startContainer)&&J.startContainer.getChild(J.startOffset-1);G&&a(G)&&!G.is(g.$empty);){if(G.isBlockBoundary())J.moveToPosition(G,\nCKEDITOR.POSITION_BEFORE_END);else{if(d(G)&&G.getHtml().match(/(\\s|&nbsp;)$/g)){V=null;break}V=J.clone();V.moveToPosition(G,CKEDITOR.POSITION_BEFORE_END)}G=G.getLast(c)}V&&J.moveToRange(V)}x.select();n(h)}}}(),u=function(){function a(b){b=new CKEDITOR.dom.walker(b);b.guard=function(a,b){if(b)return false;if(a.type==CKEDITOR.NODE_ELEMENT)return a.is(CKEDITOR.dtd.$tableContent)};b.evaluator=function(a){return a.type==CKEDITOR.NODE_ELEMENT};return b}function b(a,c,e){c=a.getDocument().createElement(c);\na.append(c,e);return c}function c(a){var b=a.count(),e;for(b;b-- >0;){e=a.getItem(b);if(!CKEDITOR.tools.trim(e.getHtml())){e.appendBogus();CKEDITOR.env.ie&&(CKEDITOR.env.version<9&&e.getChildCount())&&e.getFirst().remove()}}}return function(e){var d=e.startContainer,l=d.getAscendant(\"table\",1),g=false;c(l.getElementsByTag(\"td\"));c(l.getElementsByTag(\"th\"));l=e.clone();l.setStart(d,0);l=a(l).lastBackward();if(!l){l=e.clone();l.setEndAt(d,CKEDITOR.POSITION_BEFORE_END);l=a(l).lastForward();g=true}l||\n(l=d);if(l.is(\"table\")){e.setStartAt(l,CKEDITOR.POSITION_BEFORE_START);e.collapse(true);l.remove()}else{l.is({tbody:1,thead:1,tfoot:1})&&(l=b(l,\"tr\",g));l.is(\"tr\")&&(l=b(l,l.getParent().is(\"thead\")?\"th\":\"td\",g));(d=l.getBogus())&&d.remove();e.moveToPosition(l,g?CKEDITOR.POSITION_AFTER_START:CKEDITOR.POSITION_BEFORE_END)}}}()})();\n(function(){function a(){var a=this._.fakeSelection,b;if(a){b=this.getSelection(1);if(!b||!b.isHidden()){a.reset();a=0}}if(!a){a=b||this.getSelection(1);if(!a||a.getType()==CKEDITOR.SELECTION_NONE)return}this.fire(\"selectionCheck\",a);b=this.elementPath();if(!b.compare(this._.selectionPreviousPath)){if(CKEDITOR.env.webkit)this._.previousActive=this.document.getActive();this._.selectionPreviousPath=b;this.fire(\"selectionChange\",{selection:a,path:b})}}function e(){q=true;if(!o){b.call(this);o=CKEDITOR.tools.setTimeout(b,\n200,this)}}function b(){o=null;if(q){CKEDITOR.tools.setTimeout(a,0,this);q=false}}function c(a){function b(c,e){return!c||c.type==CKEDITOR.NODE_TEXT?false:a.clone()[\"moveToElementEdit\"+(e?\"End\":\"Start\")](c)}if(!(a.root instanceof CKEDITOR.editable))return false;var c=a.startContainer,e=a.getPreviousNode(s,null,c),d=a.getNextNode(s,null,c);return b(e)||b(d,1)||!e&&!d&&!(c.type==CKEDITOR.NODE_ELEMENT&&c.isBlockBoundary()&&c.getBogus())?true:false}function d(a){return a.getCustomData(\"cke-fillingChar\")}\nfunction h(a,b){var c=a&&a.removeCustomData(\"cke-fillingChar\");if(c){if(b!==false){var e,d=a.getDocument().getSelection().getNative(),f=d&&d.type!=\"None\"&&d.getRangeAt(0);if(c.getLength()>1&&f&&f.intersectsNode(c.$)){e=[d.anchorOffset,d.focusOffset];f=d.focusNode==c.$&&d.focusOffset>0;d.anchorNode==c.$&&d.anchorOffset>0&&e[0]--;f&&e[1]--;var h;f=d;if(!f.isCollapsed){h=f.getRangeAt(0);h.setStart(f.anchorNode,f.anchorOffset);h.setEnd(f.focusNode,f.focusOffset);h=h.collapsed}h&&e.unshift(e.pop())}}c.setText(g(c.getText()));\nif(e){c=d.getRangeAt(0);c.setStart(c.startContainer,e[0]);c.setEnd(c.startContainer,e[1]);d.removeAllRanges();d.addRange(c)}}}function g(a){return a.replace(/\\u200B( )?/g,function(a){return a[1]?\" \":\"\"})}function n(a,b,c){var e=a.on(\"focus\",function(a){a.cancel()},null,null,-100);if(CKEDITOR.env.ie)var d=a.getDocument().on(\"selectionchange\",function(a){a.cancel()},null,null,-100);else{var f=new CKEDITOR.dom.range(a);f.moveToElementEditStart(a);var g=a.getDocument().$.createRange();g.setStart(f.startContainer.$,\nf.startOffset);g.collapse(1);b.removeAllRanges();b.addRange(g)}c&&a.focus();e.removeListener();d&&d.removeListener()}function i(a){var b=CKEDITOR.dom.element.createFromHtml('<div data-cke-hidden-sel=\"1\" data-cke-temp=\"1\" style=\"'+(CKEDITOR.env.ie?\"display:none\":\"position:fixed;top:0;left:-1000px\")+'\">&nbsp;</div>',a.document);a.fire(\"lockSnapshot\");a.editable().append(b);var c=a.getSelection(),e=a.createRange(),d=c.root.on(\"selectionchange\",function(a){a.cancel()},null,null,0);e.setStartAt(b,CKEDITOR.POSITION_AFTER_START);\ne.setEndAt(b,CKEDITOR.POSITION_BEFORE_END);c.selectRanges([e]);d.removeListener();a.fire(\"unlockSnapshot\");a._.hiddenSelectionContainer=b}function j(a){var b={37:1,39:1,8:1,46:1};return function(c){var e=c.data.getKeystroke();if(b[e]){var d=a.getSelection().getRanges(),f=d[0];if(d.length==1&&f.collapsed)if((e=f[e<38?\"getPreviousEditableNode\":\"getNextEditableNode\"]())&&e.type==CKEDITOR.NODE_ELEMENT&&e.getAttribute(\"contenteditable\")==\"false\"){a.getSelection().fake(e);c.data.preventDefault();c.cancel()}}}}\nvar o,q,s=CKEDITOR.dom.walker.invisible(1),u=function(){function a(b){return function(a){var c=a.editor.createRange();c.moveToClosestEditablePosition(a.selected,b)&&a.editor.getSelection().selectRanges([c]);return false}}function b(a){return function(b){var c=b.editor,e=c.createRange(),d;if(!(d=e.moveToClosestEditablePosition(b.selected,a)))d=e.moveToClosestEditablePosition(b.selected,!a);d&&c.getSelection().selectRanges([e]);c.fire(\"saveSnapshot\");b.selected.remove();if(!d){e.moveToElementEditablePosition(c.editable());\nc.getSelection().selectRanges([e])}c.fire(\"saveSnapshot\");return false}}var c=a(),e=a(1);return{37:c,38:c,39:e,40:e,8:b(),46:b(1)}}();CKEDITOR.on(\"instanceCreated\",function(b){function c(){var a=d.getSelection();a&&a.removeAllRanges()}var d=b.editor;d.on(\"contentDom\",function(){var b=d.document,c=CKEDITOR.document,k=d.editable(),m=b.getBody(),g=b.getDocumentElement(),i=k.isInline(),o,n;CKEDITOR.env.gecko&&k.attachListener(k,\"focus\",function(a){a.removeListener();if(o!==0)if((a=d.getSelection().getNative())&&\na.isCollapsed&&a.anchorNode==k.$){a=d.createRange();a.moveToElementEditStart(k);a.select()}},null,null,-2);k.attachListener(k,CKEDITOR.env.webkit?\"DOMFocusIn\":\"focus\",function(){o&&CKEDITOR.env.webkit&&(o=d._.previousActive&&d._.previousActive.equals(b.getActive()));d.unlockSelection(o);o=0},null,null,-1);k.attachListener(k,\"mousedown\",function(){o=0});if(CKEDITOR.env.ie||CKEDITOR.env.opera||i){var q=function(){n=new CKEDITOR.dom.selection(d.getSelection());n.lock()};f?k.attachListener(k,\"beforedeactivate\",\nq,null,null,-1):k.attachListener(d,\"selectionCheck\",q,null,null,-1);k.attachListener(k,CKEDITOR.env.webkit?\"DOMFocusOut\":\"blur\",function(){d.lockSelection(n);o=1},null,null,-1);k.attachListener(k,\"mousedown\",function(){o=0})}if(CKEDITOR.env.ie&&!i){var p;k.attachListener(k,\"mousedown\",function(a){if(a.data.$.button==2){a=d.document.getSelection();if(!a||a.getType()==CKEDITOR.SELECTION_NONE)p=d.window.getScrollPosition()}});k.attachListener(k,\"mouseup\",function(a){if(a.data.$.button==2&&p){d.document.$.documentElement.scrollLeft=\np.x;d.document.$.documentElement.scrollTop=p.y}p=null});if(b.$.compatMode!=\"BackCompat\"){if(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat)g.on(\"mousedown\",function(a){function b(a){a=a.data.$;if(e){var c=m.$.createTextRange();try{c.moveToPoint(a.x,a.y)}catch(d){}e.setEndPoint(f.compareEndPoints(\"StartToStart\",c)<0?\"EndToEnd\":\"StartToStart\",c);e.select()}}function d(){g.removeListener(\"mousemove\",b);c.removeListener(\"mouseup\",d);g.removeListener(\"mouseup\",d);e.select()}a=a.data;if(a.getTarget().is(\"html\")&&\na.$.y<g.$.clientHeight&&a.$.x<g.$.clientWidth){var e=m.$.createTextRange();try{e.moveToPoint(a.$.x,a.$.y)}catch(k){}var f=e.duplicate();g.on(\"mousemove\",b);c.on(\"mouseup\",d);g.on(\"mouseup\",d)}});if(CKEDITOR.env.version>7&&CKEDITOR.env.version<11){g.on(\"mousedown\",function(a){if(a.data.getTarget().is(\"html\")){c.on(\"mouseup\",v);g.on(\"mouseup\",v)}});var v=function(){c.removeListener(\"mouseup\",v);g.removeListener(\"mouseup\",v);var a=CKEDITOR.document.$.selection,d=a.createRange();a.type!=\"None\"&&d.parentElement().ownerDocument==\nb.$&&d.select()}}}}k.attachListener(k,\"selectionchange\",a,d);k.attachListener(k,\"keyup\",e,d);k.attachListener(k,CKEDITOR.env.webkit?\"DOMFocusIn\":\"focus\",function(){d.forceNextSelectionCheck();d.selectionChange(1)});if(i?CKEDITOR.env.webkit||CKEDITOR.env.gecko:CKEDITOR.env.opera){var w;k.attachListener(k,\"mousedown\",function(){w=1});k.attachListener(b.getDocumentElement(),\"mouseup\",function(){w&&e.call(d);w=0})}else k.attachListener(CKEDITOR.env.ie?k:b.getDocumentElement(),\"mouseup\",e,d);CKEDITOR.env.webkit&&\nk.attachListener(b,\"keydown\",function(a){switch(a.data.getKey()){case 13:case 33:case 34:case 35:case 36:case 37:case 39:case 8:case 45:case 46:h(k)}},null,null,-1);k.attachListener(k,\"keydown\",j(d),null,null,-1)});d.on(\"contentDomUnload\",d.forceNextSelectionCheck,d);d.on(\"dataReady\",function(){delete d._.fakeSelection;delete d._.hiddenSelectionContainer;d.selectionChange(1)});d.on(\"loadSnapshot\",function(){var a=d.editable().getLast(function(a){return a.type==CKEDITOR.NODE_ELEMENT});a&&a.hasAttribute(\"data-cke-hidden-sel\")&&\na.remove()},null,null,100);CKEDITOR.env.ie9Compat&&d.on(\"beforeDestroy\",c,null,null,9);CKEDITOR.env.webkit&&d.on(\"setData\",c);d.on(\"contentDomUnload\",function(){d.unlockSelection()});d.on(\"key\",function(a){if(d.mode==\"wysiwyg\"){var b=d.getSelection();if(b.isFake){var c=u[a.data.keyCode];if(c)return c({editor:d,selected:b.getSelectedElement(),selection:b,keyEvent:a})}}})});CKEDITOR.on(\"instanceReady\",function(a){var b=a.editor;if(CKEDITOR.env.webkit){b.on(\"selectionChange\",function(){var a=b.editable(),\nc=d(a);c&&(c.getCustomData(\"ready\")?h(a):c.setCustomData(\"ready\",1))},null,null,-1);b.on(\"beforeSetMode\",function(){h(b.editable())},null,null,-1);var c,e,a=function(){var a=b.editable();if(a)if(a=d(a)){var f=b.document.$.defaultView.getSelection();f.type==\"Caret\"&&f.anchorNode==a.$&&(e=1);c=a.getText();a.setText(g(c))}},f=function(){var a=b.editable();if(a)if(a=d(a)){a.setText(c);if(e){b.document.$.defaultView.getSelection().setPosition(a.$,a.getLength());e=0}}};b.on(\"beforeUndoImage\",a);b.on(\"afterUndoImage\",\nf);b.on(\"beforeGetData\",a,null,null,0);b.on(\"getData\",f)}});CKEDITOR.editor.prototype.selectionChange=function(b){(b?a:e).call(this)};CKEDITOR.editor.prototype.getSelection=function(a){if((this._.savedSelection||this._.fakeSelection)&&!a)return this._.savedSelection||this._.fakeSelection;return(a=this.editable())&&this.mode==\"wysiwyg\"?new CKEDITOR.dom.selection(a):null};CKEDITOR.editor.prototype.lockSelection=function(a){a=a||this.getSelection(1);if(a.getType()!=CKEDITOR.SELECTION_NONE){!a.isLocked&&\na.lock();this._.savedSelection=a;return true}return false};CKEDITOR.editor.prototype.unlockSelection=function(a){var b=this._.savedSelection;if(b){b.unlock(a);delete this._.savedSelection;return true}return false};CKEDITOR.editor.prototype.forceNextSelectionCheck=function(){delete this._.selectionPreviousPath};CKEDITOR.dom.document.prototype.getSelection=function(){return new CKEDITOR.dom.selection(this)};CKEDITOR.dom.range.prototype.select=function(){var a=this.root instanceof CKEDITOR.editable?\nthis.root.editor.getSelection():new CKEDITOR.dom.selection(this.root);a.selectRanges([this]);return a};CKEDITOR.SELECTION_NONE=1;CKEDITOR.SELECTION_TEXT=2;CKEDITOR.SELECTION_ELEMENT=3;var f=typeof window.getSelection!=\"function\",p=1;CKEDITOR.dom.selection=function(a){if(a instanceof CKEDITOR.dom.selection)var b=a,a=a.root;var c=a instanceof CKEDITOR.dom.element;this.rev=b?b.rev:p++;this.document=a instanceof CKEDITOR.dom.document?a:a.getDocument();this.root=a=c?a:this.document.getBody();this.isLocked=\n0;this._={cache:{}};if(b){CKEDITOR.tools.extend(this._.cache,b._.cache);this.isFake=b.isFake;this.isLocked=b.isLocked;return this}b=f?this.document.$.selection:this.document.getWindow().$.getSelection();if(CKEDITOR.env.webkit)(b.type==\"None\"&&this.document.getActive().equals(a)||b.type==\"Caret\"&&b.anchorNode.nodeType==CKEDITOR.NODE_DOCUMENT)&&n(a,b);else if(CKEDITOR.env.gecko)b&&(this.document.getActive().equals(a)&&b.anchorNode&&b.anchorNode.nodeType==CKEDITOR.NODE_DOCUMENT)&&n(a,b,true);else if(CKEDITOR.env.ie){var d;\ntry{d=this.document.getActive()}catch(e){}if(f)b.type==\"None\"&&(d&&d.equals(this.document.getDocumentElement()))&&n(a,null,true);else{(b=b&&b.anchorNode)&&(b=new CKEDITOR.dom.node(b));d&&(d.equals(this.document.getDocumentElement())&&b&&(a.equals(b)||a.contains(b)))&&n(a,null,true)}}d=this.getNative();var g,h;if(d)if(d.getRangeAt)g=(h=d.rangeCount&&d.getRangeAt(0))&&new CKEDITOR.dom.node(h.commonAncestorContainer);else{try{h=d.createRange()}catch(j){}g=h&&CKEDITOR.dom.element.get(h.item&&h.item(0)||\nh.parentElement())}if(!g||!(g.type==CKEDITOR.NODE_ELEMENT||g.type==CKEDITOR.NODE_TEXT)||!this.root.equals(g)&&!this.root.contains(g)){this._.cache.type=CKEDITOR.SELECTION_NONE;this._.cache.startElement=null;this._.cache.selectedElement=null;this._.cache.selectedText=\"\";this._.cache.ranges=new CKEDITOR.dom.rangeList}return this};var y={img:1,hr:1,li:1,table:1,tr:1,td:1,th:1,embed:1,object:1,ol:1,ul:1,a:1,input:1,form:1,select:1,textarea:1,button:1,fieldset:1,thead:1,tfoot:1};CKEDITOR.dom.selection.prototype=\n{getNative:function(){return this._.cache.nativeSel!==void 0?this._.cache.nativeSel:this._.cache.nativeSel=f?this.document.$.selection:this.document.getWindow().$.getSelection()},getType:f?function(){var a=this._.cache;if(a.type)return a.type;var b=CKEDITOR.SELECTION_NONE;try{var c=this.getNative(),d=c.type;if(d==\"Text\")b=CKEDITOR.SELECTION_TEXT;if(d==\"Control\")b=CKEDITOR.SELECTION_ELEMENT;if(c.createRange().parentElement())b=CKEDITOR.SELECTION_TEXT}catch(e){}return a.type=b}:function(){var a=this._.cache;\nif(a.type)return a.type;var b=CKEDITOR.SELECTION_TEXT,c=this.getNative();if(!c||!c.rangeCount)b=CKEDITOR.SELECTION_NONE;else if(c.rangeCount==1){var c=c.getRangeAt(0),d=c.startContainer;if(d==c.endContainer&&d.nodeType==1&&c.endOffset-c.startOffset==1&&y[d.childNodes[c.startOffset].nodeName.toLowerCase()])b=CKEDITOR.SELECTION_ELEMENT}return a.type=b},getRanges:function(){var a=f?function(){function a(b){return(new CKEDITOR.dom.node(b)).getIndex()}var b=function(b,c){b=b.duplicate();b.collapse(c);\nvar d=b.parentElement();if(!d.hasChildNodes())return{container:d,offset:0};for(var e=d.children,f,g,h=b.duplicate(),l=0,m=e.length-1,j=-1,i,o;l<=m;){j=Math.floor((l+m)/2);f=e[j];h.moveToElementText(f);i=h.compareEndPoints(\"StartToStart\",b);if(i>0)m=j-1;else if(i<0)l=j+1;else return{container:d,offset:a(f)}}if(j==-1||j==e.length-1&&i<0){h.moveToElementText(d);h.setEndPoint(\"StartToStart\",b);h=h.text.replace(/(\\r\\n|\\r)/g,\"\\n\").length;e=d.childNodes;if(!h){f=e[e.length-1];return f.nodeType!=CKEDITOR.NODE_TEXT?\n{container:d,offset:e.length}:{container:f,offset:f.nodeValue.length}}for(d=e.length;h>0&&d>0;){g=e[--d];if(g.nodeType==CKEDITOR.NODE_TEXT){o=g;h=h-g.nodeValue.length}}return{container:o,offset:-h}}h.collapse(i>0?true:false);h.setEndPoint(i>0?\"StartToStart\":\"EndToStart\",b);h=h.text.replace(/(\\r\\n|\\r)/g,\"\\n\").length;if(!h)return{container:d,offset:a(f)+(i>0?0:1)};for(;h>0;)try{g=f[i>0?\"previousSibling\":\"nextSibling\"];if(g.nodeType==CKEDITOR.NODE_TEXT){h=h-g.nodeValue.length;o=g}f=g}catch(n){return{container:d,\noffset:a(f)}}return{container:o,offset:i>0?-h:o.nodeValue.length+h}};return function(){var a=this.getNative(),c=a&&a.createRange(),d=this.getType();if(!a)return[];if(d==CKEDITOR.SELECTION_TEXT){a=new CKEDITOR.dom.range(this.root);d=b(c,true);a.setStart(new CKEDITOR.dom.node(d.container),d.offset);d=b(c);a.setEnd(new CKEDITOR.dom.node(d.container),d.offset);a.endContainer.getPosition(a.startContainer)&CKEDITOR.POSITION_PRECEDING&&a.endOffset<=a.startContainer.getIndex()&&a.collapse();return[a]}if(d==\nCKEDITOR.SELECTION_ELEMENT){for(var d=[],e=0;e<c.length;e++){for(var f=c.item(e),k=f.parentNode,g=0,a=new CKEDITOR.dom.range(this.root);g<k.childNodes.length&&k.childNodes[g]!=f;g++);a.setStart(new CKEDITOR.dom.node(k),g);a.setEnd(new CKEDITOR.dom.node(k),g+1);d.push(a)}return d}return[]}}():function(){var a=[],b,c=this.getNative();if(!c)return a;for(var d=0;d<c.rangeCount;d++){var e=c.getRangeAt(d);b=new CKEDITOR.dom.range(this.root);b.setStart(new CKEDITOR.dom.node(e.startContainer),e.startOffset);\nb.setEnd(new CKEDITOR.dom.node(e.endContainer),e.endOffset);a.push(b)}return a};return function(b){var c=this._.cache;if(c.ranges&&!b)return c.ranges;if(!c.ranges)c.ranges=new CKEDITOR.dom.rangeList(a.call(this));if(b)for(var d=c.ranges,e=0;e<d.length;e++){var f=d[e];f.getCommonAncestor().isReadOnly()&&d.splice(e,1);if(!f.collapsed){if(f.startContainer.isReadOnly())for(var b=f.startContainer,g;b;){if((g=b.type==CKEDITOR.NODE_ELEMENT)&&b.is(\"body\")||!b.isReadOnly())break;g&&b.getAttribute(\"contentEditable\")==\n\"false\"&&f.setStartAfter(b);b=b.getParent()}b=f.startContainer;g=f.endContainer;var h=f.startOffset,j=f.endOffset,i=f.clone();b&&b.type==CKEDITOR.NODE_TEXT&&(h>=b.getLength()?i.setStartAfter(b):i.setStartBefore(b));g&&g.type==CKEDITOR.NODE_TEXT&&(j?i.setEndAfter(g):i.setEndBefore(g));b=new CKEDITOR.dom.walker(i);b.evaluator=function(a){if(a.type==CKEDITOR.NODE_ELEMENT&&a.isReadOnly()){var b=f.clone();f.setEndBefore(a);f.collapsed&&d.splice(e--,1);if(!(a.getPosition(i.endContainer)&CKEDITOR.POSITION_CONTAINS)){b.setStartAfter(a);\nb.collapsed||d.splice(e+1,0,b)}return true}return false};b.next()}}return c.ranges}}(),getStartElement:function(){var a=this._.cache;if(a.startElement!==void 0)return a.startElement;var b;switch(this.getType()){case CKEDITOR.SELECTION_ELEMENT:return this.getSelectedElement();case CKEDITOR.SELECTION_TEXT:var c=this.getRanges()[0];if(c){if(c.collapsed){b=c.startContainer;b.type!=CKEDITOR.NODE_ELEMENT&&(b=b.getParent())}else{for(c.optimize();;){b=c.startContainer;if(c.startOffset==(b.getChildCount?b.getChildCount():\nb.getLength())&&!b.isBlockBoundary())c.setStartAfter(b);else break}b=c.startContainer;if(b.type!=CKEDITOR.NODE_ELEMENT)return b.getParent();b=b.getChild(c.startOffset);if(!b||b.type!=CKEDITOR.NODE_ELEMENT)b=c.startContainer;else for(c=b.getFirst();c&&c.type==CKEDITOR.NODE_ELEMENT;){b=c;c=c.getFirst()}}b=b.$}}return a.startElement=b?new CKEDITOR.dom.element(b):null},getSelectedElement:function(){var a=this._.cache;if(a.selectedElement!==void 0)return a.selectedElement;var b=this,c=CKEDITOR.tools.tryThese(function(){return b.getNative().createRange().item(0)},\nfunction(){for(var a=b.getRanges()[0].clone(),c,d,e=2;e&&(!(c=a.getEnclosedNode())||!(c.type==CKEDITOR.NODE_ELEMENT&&y[c.getName()]&&(d=c)));e--)a.shrink(CKEDITOR.SHRINK_ELEMENT);return d&&d.$});return a.selectedElement=c?new CKEDITOR.dom.element(c):null},getSelectedText:function(){var a=this._.cache;if(a.selectedText!==void 0)return a.selectedText;var b=this.getNative(),b=f?b.type==\"Control\"?\"\":b.createRange().text:b.toString();return a.selectedText=b},lock:function(){this.getRanges();this.getStartElement();\nthis.getSelectedElement();this.getSelectedText();this._.cache.nativeSel=null;this.isLocked=1},unlock:function(a){if(this.isLocked){if(a)var b=this.getSelectedElement(),c=!b&&this.getRanges(),d=this.isFake;this.isLocked=0;this.reset();if(a)(a=b||c[0]&&c[0].getCommonAncestor())&&a.getAscendant(\"body\",1)&&(d?this.fake(b):b?this.selectElement(b):this.selectRanges(c))}},reset:function(){this._.cache={};this.isFake=0;var a=this.root.editor;if(a&&a._.fakeSelection&&this.rev==a._.fakeSelection.rev){delete a._.fakeSelection;\nvar b=a._.hiddenSelectionContainer;if(b){a.fire(\"lockSnapshot\");b.remove();a.fire(\"unlockSnapshot\")}delete a._.hiddenSelectionContainer}this.rev=p++},selectElement:function(a){var b=new CKEDITOR.dom.range(this.root);b.setStartBefore(a);b.setEndAfter(a);this.selectRanges([b])},selectRanges:function(a){this.reset();if(a.length)if(this.isLocked){var b=CKEDITOR.document.getActive();this.unlock();this.selectRanges(a);this.lock();!b.equals(this.root)&&b.focus()}else{a:{var d,e;if(a.length==1&&!(e=a[0]).collapsed&&\n(b=e.getEnclosedNode())&&b.type==CKEDITOR.NODE_ELEMENT){e=e.clone();e.shrink(CKEDITOR.SHRINK_ELEMENT,true);if((d=e.getEnclosedNode())&&d.type==CKEDITOR.NODE_ELEMENT)b=d;if(b.getAttribute(\"contenteditable\")==\"false\")break a}b=void 0}if(b)this.fake(b);else{if(f){e=CKEDITOR.dom.walker.whitespaces(true);d=/\\ufeff|\\u00a0/;var g={table:1,tbody:1,tr:1};if(a.length>1){b=a[a.length-1];a[0].setEnd(b.endContainer,b.endOffset)}var b=a[0],a=b.collapsed,j,i,o,n=b.getEnclosedNode();if(n&&n.type==CKEDITOR.NODE_ELEMENT&&\nn.getName()in y&&(!n.is(\"a\")||!n.getText()))try{o=n.$.createControlRange();o.addElement(n.$);o.select();return}catch(q){}(b.startContainer.type==CKEDITOR.NODE_ELEMENT&&b.startContainer.getName()in g||b.endContainer.type==CKEDITOR.NODE_ELEMENT&&b.endContainer.getName()in g)&&b.shrink(CKEDITOR.NODE_ELEMENT,true);o=b.createBookmark();var g=o.startNode,p;if(!a)p=o.endNode;o=b.document.$.body.createTextRange();o.moveToElementText(g.$);o.moveStart(\"character\",1);if(p){d=b.document.$.body.createTextRange();\nd.moveToElementText(p.$);o.setEndPoint(\"EndToEnd\",d);o.moveEnd(\"character\",-1)}else{j=g.getNext(e);i=g.hasAscendant(\"pre\");j=!(j&&j.getText&&j.getText().match(d))&&(i||!g.hasPrevious()||g.getPrevious().is&&g.getPrevious().is(\"br\"));i=b.document.createElement(\"span\");i.setHtml(\"&#65279;\");i.insertBefore(g);j&&b.document.createText(\"﻿\").insertBefore(g)}b.setStartBefore(g);g.remove();if(a){if(j){o.moveStart(\"character\",-1);o.select();b.document.$.selection.clear()}else o.select();b.moveToPosition(i,\nCKEDITOR.POSITION_BEFORE_START);i.remove()}else{b.setEndBefore(p);p.remove();o.select()}}else{p=this.getNative();if(!p)return;if(CKEDITOR.env.opera){b=this.document.$.createRange();b.selectNodeContents(this.root.$);p.addRange(b)}this.removeAllRanges();for(o=0;o<a.length;o++){if(o<a.length-1){b=a[o];j=a[o+1];d=b.clone();d.setStart(b.endContainer,b.endOffset);d.setEnd(j.startContainer,j.startOffset);if(!d.collapsed){d.shrink(CKEDITOR.NODE_ELEMENT,true);i=d.getCommonAncestor();d=d.getEnclosedNode();\nif(i.isReadOnly()||d&&d.isReadOnly()){j.setStart(b.startContainer,b.startOffset);a.splice(o--,1);continue}}}b=a[o];i=this.document.$.createRange();j=b.startContainer;if(CKEDITOR.env.opera&&b.collapsed&&j.type==CKEDITOR.NODE_ELEMENT){d=j.getChild(b.startOffset-1);e=j.getChild(b.startOffset);if(!d&&!e&&j.is(CKEDITOR.dtd.$removeEmpty)||d&&d.type==CKEDITOR.NODE_ELEMENT||e&&e.type==CKEDITOR.NODE_ELEMENT){b.insertNode(this.document.createText(\"\"));b.collapse(1)}}if(b.collapsed&&CKEDITOR.env.webkit&&c(b)){j=\nthis.root;h(j,false);d=j.getDocument().createText(\"​\");j.setCustomData(\"cke-fillingChar\",d);b.insertNode(d);if((j=d.getNext())&&!d.getPrevious()&&j.type==CKEDITOR.NODE_ELEMENT&&j.getName()==\"br\"){h(this.root);b.moveToPosition(j,CKEDITOR.POSITION_BEFORE_START)}else b.moveToPosition(d,CKEDITOR.POSITION_AFTER_END)}i.setStart(b.startContainer.$,b.startOffset);try{i.setEnd(b.endContainer.$,b.endOffset)}catch(s){if(s.toString().indexOf(\"NS_ERROR_ILLEGAL_VALUE\")>=0){b.collapse(1);i.setEnd(b.endContainer.$,\nb.endOffset)}else throw s;}p.addRange(i)}}this.reset();this.root.fire(\"selectionchange\")}}},fake:function(a){var b=this.root.editor;this.reset();i(b);var c=this._.cache,d=new CKEDITOR.dom.range(this.root);d.setStartBefore(a);d.setEndAfter(a);c.ranges=new CKEDITOR.dom.rangeList(d);c.selectedElement=c.startElement=a;c.type=CKEDITOR.SELECTION_ELEMENT;c.selectedText=c.nativeSel=null;this.isFake=1;this.rev=p++;b._.fakeSelection=this;this.root.fire(\"selectionchange\")},isHidden:function(){var a=this.getCommonAncestor();\na&&a.type==CKEDITOR.NODE_TEXT&&(a=a.getParent());return!(!a||!a.data(\"cke-hidden-sel\"))},createBookmarks:function(a){a=this.getRanges().createBookmarks(a);this.isFake&&(a.isFake=1);return a},createBookmarks2:function(a){a=this.getRanges().createBookmarks2(a);this.isFake&&(a.isFake=1);return a},selectBookmarks:function(a){for(var b=[],c=0;c<a.length;c++){var d=new CKEDITOR.dom.range(this.root);d.moveToBookmark(a[c]);b.push(d)}a.isFake?this.fake(b[0].getEnclosedNode()):this.selectRanges(b);return this},\ngetCommonAncestor:function(){var a=this.getRanges();return!a.length?null:a[0].startContainer.getCommonAncestor(a[a.length-1].endContainer)},scrollIntoView:function(){this.type!=CKEDITOR.SELECTION_NONE&&this.getRanges()[0].scrollIntoView()},removeAllRanges:function(){var a=this.getNative();try{a&&a[f?\"empty\":\"removeAllRanges\"]()}catch(b){}this.reset()}}})();\"use strict\";\nCKEDITOR.editor.prototype.attachStyleStateChange=function(a,e){var b=this._.styleStateChangeCallbacks;if(!b){b=this._.styleStateChangeCallbacks=[];this.on(\"selectionChange\",function(a){for(var d=0;d<b.length;d++){var e=b[d],g=e.style.checkActive(a.data.path)?CKEDITOR.TRISTATE_ON:CKEDITOR.TRISTATE_OFF;e.fn.call(this,g)}})}b.push({style:a,fn:e})};CKEDITOR.STYLE_BLOCK=1;CKEDITOR.STYLE_INLINE=2;CKEDITOR.STYLE_OBJECT=3;\n(function(){function a(a,b){for(var c,d;a=a.getParent();){if(a.equals(b))break;if(a.getAttribute(\"data-nostyle\"))c=a;else if(!d){var e=a.getAttribute(\"contentEditable\");e==\"false\"?c=a:e==\"true\"&&(d=1)}}return c}function e(b){var d=b.document;if(b.collapsed){d=y(this,d);b.insertNode(d);b.moveToPosition(d,CKEDITOR.POSITION_BEFORE_END)}else{var f=this.element,g=this._.definition,h,j=g.ignoreReadonly,i=j||g.includeReadonly;i==void 0&&(i=b.root.getCustomData(\"cke_includeReadonly\"));var k=CKEDITOR.dtd[f];\nif(!k){h=true;k=CKEDITOR.dtd.span}b.enlarge(CKEDITOR.ENLARGE_INLINE,1);b.trim();var l=b.createBookmark(),m=l.startNode,o=l.endNode,n=m,q;if(!j){var p=b.getCommonAncestor(),j=a(m,p),p=a(o,p);j&&(n=j.getNextSourceNode(true));p&&(o=p)}for(n.getPosition(o)==CKEDITOR.POSITION_FOLLOWING&&(n=0);n;){j=false;if(n.equals(o)){n=null;j=true}else{var s=n.type==CKEDITOR.NODE_ELEMENT?n.getName():null,p=s&&n.getAttribute(\"contentEditable\")==\"false\",r=s&&n.getAttribute(\"data-nostyle\");if(s&&n.data(\"cke-bookmark\")){n=\nn.getNextSourceNode(true);continue}if(p&&i&&CKEDITOR.dtd.$block[s])for(var t=n,x=c(t),z=void 0,A=x.length,I=0,t=A&&new CKEDITOR.dom.range(t.getDocument());I<A;++I){var z=x[I],L=CKEDITOR.filter.instances[z.data(\"cke-filter\")];if(L?L.check(this):1){t.selectNodeContents(z);e.call(this,t)}}x=s?!k[s]||r?0:p&&!i?0:(n.getPosition(o)|M)==M&&(!g.childRule||g.childRule(n)):1;if(x)if((x=n.getParent())&&((x.getDtd()||CKEDITOR.dtd.span)[f]||h)&&(!g.parentRule||g.parentRule(x))){if(!q&&(!s||!CKEDITOR.dtd.$removeEmpty[s]||\n(n.getPosition(o)|M)==M)){q=b.clone();q.setStartBefore(n)}s=n.type;if(s==CKEDITOR.NODE_TEXT||p||s==CKEDITOR.NODE_ELEMENT&&!n.getChildCount()){for(var s=n,W;(j=!s.getNext(E))&&(W=s.getParent(),k[W.getName()])&&(W.getPosition(m)|Q)==Q&&(!g.childRule||g.childRule(W));)s=W;q.setEndAfter(s)}}else j=true;else j=true;n=n.getNextSourceNode(r||p)}if(j&&q&&!q.collapsed){for(var j=y(this,d),p=j.hasAttributes(),r=q.getCommonAncestor(),s={},x={},z={},A={},T,P,Z;j&&r;){if(r.getName()==f){for(T in g.attributes)if(!A[T]&&\n(Z=r.getAttribute(P)))j.getAttribute(T)==Z?x[T]=1:A[T]=1;for(P in g.styles)if(!z[P]&&(Z=r.getStyle(P)))j.getStyle(P)==Z?s[P]=1:z[P]=1}r=r.getParent()}for(T in x)j.removeAttribute(T);for(P in s)j.removeStyle(P);p&&!j.hasAttributes()&&(j=null);if(j){q.extractContents().appendTo(j);q.insertNode(j);u.call(this,j);j.mergeSiblings();CKEDITOR.env.ie||j.$.normalize()}else{j=new CKEDITOR.dom.element(\"span\");q.extractContents().appendTo(j);q.insertNode(j);u.call(this,j);j.remove(true)}q=null}}b.moveToBookmark(l);\nb.shrink(CKEDITOR.SHRINK_TEXT);b.shrink(CKEDITOR.NODE_ELEMENT,true)}}function b(a){function b(){for(var a=new CKEDITOR.dom.elementPath(d.getParent()),c=new CKEDITOR.dom.elementPath(k.getParent()),e=null,f=null,g=0;g<a.elements.length;g++){var h=a.elements[g];if(h==a.block||h==a.blockLimit)break;m.checkElementRemovable(h)&&(e=h)}for(g=0;g<c.elements.length;g++){h=c.elements[g];if(h==c.block||h==c.blockLimit)break;m.checkElementRemovable(h)&&(f=h)}f&&k.breakParent(f);e&&d.breakParent(e)}a.enlarge(CKEDITOR.ENLARGE_INLINE,\n1);var c=a.createBookmark(),d=c.startNode;if(a.collapsed){for(var e=new CKEDITOR.dom.elementPath(d.getParent(),a.root),g,j=0,h;j<e.elements.length&&(h=e.elements[j]);j++){if(h==e.block||h==e.blockLimit)break;if(this.checkElementRemovable(h)){var i;if(a.collapsed&&(a.checkBoundaryOfElement(h,CKEDITOR.END)||(i=a.checkBoundaryOfElement(h,CKEDITOR.START)))){g=h;g.match=i?\"start\":\"end\"}else{h.mergeSiblings();h.is(this.element)?s.call(this,h):f(h,l(this)[h.getName()])}}}if(g){h=d;for(j=0;;j++){i=e.elements[j];\nif(i.equals(g))break;else if(i.match)continue;else i=i.clone();i.append(h);h=i}h[g.match==\"start\"?\"insertBefore\":\"insertAfter\"](g)}}else{var k=c.endNode,m=this;b();for(e=d;!e.equals(k);){g=e.getNextSourceNode();if(e.type==CKEDITOR.NODE_ELEMENT&&this.checkElementRemovable(e)){e.getName()==this.element?s.call(this,e):f(e,l(this)[e.getName()]);if(g.type==CKEDITOR.NODE_ELEMENT&&g.contains(d)){b();g=d.getNext()}}e=g}}a.moveToBookmark(c);a.shrink(CKEDITOR.NODE_ELEMENT,true)}function c(a){var b=[];a.forEach(function(a){if(a.getAttribute(\"contenteditable\")==\n\"true\"){b.push(a);return false}},CKEDITOR.NODE_ELEMENT,true);return b}function d(a){var b=a.getEnclosedNode()||a.getCommonAncestor(false,true);(a=(new CKEDITOR.dom.elementPath(b,a.root)).contains(this.element,1))&&!a.isReadOnly()&&m(a,this)}function h(a){var b=a.getCommonAncestor(true,true);if(a=(new CKEDITOR.dom.elementPath(b,a.root)).contains(this.element,1)){var b=this._.definition,c=b.attributes;if(c)for(var d in c)a.removeAttribute(d,c[d]);if(b.styles)for(var e in b.styles)b.styles.hasOwnProperty(e)&&\na.removeStyle(e)}}function g(a){var b=a.createBookmark(true),c=a.createIterator();c.enforceRealBlocks=true;if(this._.enterMode)c.enlargeBr=this._.enterMode!=CKEDITOR.ENTER_BR;for(var d,e=a.document,f;d=c.getNextParagraph();)if(!d.isReadOnly()&&(c.activeFilter?c.activeFilter.check(this):1)){f=y(this,e,d);i(d,f)}a.moveToBookmark(b)}function n(a){var b=a.createBookmark(1),c=a.createIterator();c.enforceRealBlocks=true;c.enlargeBr=this._.enterMode!=CKEDITOR.ENTER_BR;for(var d,e;d=c.getNextParagraph();)if(this.checkElementRemovable(d))if(d.is(\"pre\")){(e=\nthis._.enterMode==CKEDITOR.ENTER_BR?null:a.document.createElement(this._.enterMode==CKEDITOR.ENTER_P?\"p\":\"div\"))&&d.copyAttributes(e);i(d,e)}else s.call(this,d);a.moveToBookmark(b)}function i(a,b){var c=!b;if(c){b=a.getDocument().createElement(\"div\");a.copyAttributes(b)}var d=b&&b.is(\"pre\"),e=a.is(\"pre\"),f=!d&&e;if(d&&!e){e=b;(f=a.getBogus())&&f.remove();f=a.getHtml();f=o(f,/(?:^[ \\t\\n\\r]+)|(?:[ \\t\\n\\r]+$)/g,\"\");f=f.replace(/[ \\t\\r\\n]*(<br[^>]*>)[ \\t\\r\\n]*/gi,\"$1\");f=f.replace(/([ \\t\\n\\r]+|&nbsp;)/g,\n\" \");f=f.replace(/<br\\b[^>]*>/gi,\"\\n\");if(CKEDITOR.env.ie){var g=a.getDocument().createElement(\"div\");g.append(e);e.$.outerHTML=\"<pre>\"+f+\"</pre>\";e.copyAttributes(g.getFirst());e=g.getFirst().remove()}else e.setHtml(f);b=e}else f?b=q(c?[a.getHtml()]:j(a),b):a.moveChildren(b);b.replace(a);if(d){var c=b,h;if((h=c.getPrevious(z))&&h.type==CKEDITOR.NODE_ELEMENT&&h.is(\"pre\")){d=o(h.getHtml(),/\\n$/,\"\")+\"\\n\\n\"+o(c.getHtml(),/^\\n/,\"\");CKEDITOR.env.ie?c.$.outerHTML=\"<pre>\"+d+\"</pre>\":c.setHtml(d);h.remove()}}else c&&\np(b)}function j(a){a.getName();var b=[];o(a.getOuterHtml(),/(\\S\\s*)\\n(?:\\s|(<span[^>]+data-cke-bookmark.*?\\/span>))*\\n(?!$)/gi,function(a,b,c){return b+\"</pre>\"+c+\"<pre>\"}).replace(/<pre\\b.*?>([\\s\\S]*?)<\\/pre>/gi,function(a,c){b.push(c)});return b}function o(a,b,c){var d=\"\",e=\"\",a=a.replace(/(^<span[^>]+data-cke-bookmark.*?\\/span>)|(<span[^>]+data-cke-bookmark.*?\\/span>$)/gi,function(a,b,c){b&&(d=b);c&&(e=c);return\"\"});return d+a.replace(b,c)+e}function q(a,b){var c;a.length>1&&(c=new CKEDITOR.dom.documentFragment(b.getDocument()));\nfor(var d=0;d<a.length;d++){var e=a[d],e=e.replace(/(\\r\\n|\\r)/g,\"\\n\"),e=o(e,/^[ \\t]*\\n/,\"\"),e=o(e,/\\n$/,\"\"),e=o(e,/^[ \\t]+|[ \\t]+$/g,function(a,b){return a.length==1?\"&nbsp;\":b?\" \"+CKEDITOR.tools.repeat(\"&nbsp;\",a.length-1):CKEDITOR.tools.repeat(\"&nbsp;\",a.length-1)+\" \"}),e=e.replace(/\\n/g,\"<br>\"),e=e.replace(/[ \\t]{2,}/g,function(a){return CKEDITOR.tools.repeat(\"&nbsp;\",a.length-1)+\" \"});if(c){var f=b.clone();f.setHtml(e);c.append(f)}else b.setHtml(e)}return c||b}function s(a,b){var c=this._.definition,\nd=c.attributes,c=c.styles,e=l(this)[a.getName()],g=CKEDITOR.tools.isEmpty(d)&&CKEDITOR.tools.isEmpty(c),h;for(h in d)if(!((h==\"class\"||this._.definition.fullMatch)&&a.getAttribute(h)!=t(h,d[h]))&&!(b&&h.slice(0,5)==\"data-\")){g=a.hasAttribute(h);a.removeAttribute(h)}for(var j in c)if(!(this._.definition.fullMatch&&a.getStyle(j)!=t(j,c[j],true))){g=g||!!a.getStyle(j);a.removeStyle(j)}f(a,e,r[a.getName()]);g&&(this._.definition.alwaysRemoveElement?p(a,1):!CKEDITOR.dtd.$block[a.getName()]||this._.enterMode==\nCKEDITOR.ENTER_BR&&!a.hasAttributes()?p(a):a.renameNode(this._.enterMode==CKEDITOR.ENTER_P?\"p\":\"div\"))}function u(a){for(var b=l(this),c=a.getElementsByTag(this.element),d,e=c.count();--e>=0;){d=c.getItem(e);d.isReadOnly()||s.call(this,d,true)}for(var g in b)if(g!=this.element){c=a.getElementsByTag(g);for(e=c.count()-1;e>=0;e--){d=c.getItem(e);d.isReadOnly()||f(d,b[g])}}}function f(a,b,c){if(b=b&&b.attributes)for(var d=0;d<b.length;d++){var e=b[d][0],f;if(f=a.getAttribute(e)){var g=b[d][1];(g===null||\ng.test&&g.test(f)||typeof g==\"string\"&&f==g)&&a.removeAttribute(e)}}c||p(a)}function p(a,b){if(!a.hasAttributes()||b)if(CKEDITOR.dtd.$block[a.getName()]){var c=a.getPrevious(z),d=a.getNext(z);c&&(c.type==CKEDITOR.NODE_TEXT||!c.isBlockBoundary({br:1}))&&a.append(\"br\",1);d&&(d.type==CKEDITOR.NODE_TEXT||!d.isBlockBoundary({br:1}))&&a.append(\"br\");a.remove(true)}else{c=a.getFirst();d=a.getLast();a.remove(true);if(c){c.type==CKEDITOR.NODE_ELEMENT&&c.mergeSiblings();d&&(!c.equals(d)&&d.type==CKEDITOR.NODE_ELEMENT)&&\nd.mergeSiblings()}}}function y(a,b,c){var d;d=a.element;d==\"*\"&&(d=\"span\");d=new CKEDITOR.dom.element(d,b);c&&c.copyAttributes(d);d=m(d,a);b.getCustomData(\"doc_processing_style\")&&d.hasAttribute(\"id\")?d.removeAttribute(\"id\"):b.setCustomData(\"doc_processing_style\",1);return d}function m(a,b){var c=b._.definition,d=c.attributes,c=CKEDITOR.style.getStyleText(c);if(d)for(var e in d)a.setAttribute(e,d[e]);c&&a.setAttribute(\"style\",c);return a}function k(a,b){for(var c in a)a[c]=a[c].replace(I,function(a,\nc){return b[c]})}function l(a){if(a._.overrides)return a._.overrides;var b=a._.overrides={},c=a._.definition.overrides;if(c){CKEDITOR.tools.isArray(c)||(c=[c]);for(var d=0;d<c.length;d++){var e=c[d],f,g;if(typeof e==\"string\")f=e.toLowerCase();else{f=e.element?e.element.toLowerCase():a.element;g=e.attributes}e=b[f]||(b[f]={});if(g){var e=e.attributes=e.attributes||[],h;for(h in g)e.push([h.toLowerCase(),g[h]])}}}return b}function t(a,b,c){var d=new CKEDITOR.dom.element(\"span\");d[c?\"setStyle\":\"setAttribute\"](a,\nb);return d[c?\"getStyle\":\"getAttribute\"](a)}function x(a,b){for(var c=a.document,d=a.getRanges(),e=b?this.removeFromRange:this.applyToRange,f,g=d.createIterator();f=g.getNextRange();)e.call(this,f);a.selectRanges(d);c.removeCustomData(\"doc_processing_style\")}var r={address:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,section:1,header:1,footer:1,nav:1,article:1,aside:1,figure:1,dialog:1,hgroup:1,time:1,meter:1,menu:1,command:1,keygen:1,output:1,progress:1,details:1,datagrid:1,datalist:1},L={a:1,\nembed:1,hr:1,img:1,li:1,object:1,ol:1,table:1,td:1,tr:1,th:1,ul:1,dl:1,dt:1,dd:1,form:1,audio:1,video:1},A=/\\s*(?:;\\s*|$)/,I=/#\\((.+?)\\)/g,E=CKEDITOR.dom.walker.bookmark(0,1),z=CKEDITOR.dom.walker.whitespaces(1);CKEDITOR.style=function(a,b){var c=a.attributes;if(c&&c.style){a.styles=CKEDITOR.tools.extend({},a.styles,CKEDITOR.tools.parseCssText(c.style));delete c.style}if(b){a=CKEDITOR.tools.clone(a);k(a.attributes,b);k(a.styles,b)}c=this.element=a.element?typeof a.element==\"string\"?a.element.toLowerCase():\na.element:\"*\";this.type=a.type||(r[c]?CKEDITOR.STYLE_BLOCK:L[c]?CKEDITOR.STYLE_OBJECT:CKEDITOR.STYLE_INLINE);if(typeof this.element==\"object\")this.type=CKEDITOR.STYLE_OBJECT;this._={definition:a}};CKEDITOR.editor.prototype.applyStyle=function(a){a.checkApplicable(this.elementPath())&&x.call(a,this.getSelection())};CKEDITOR.editor.prototype.removeStyle=function(a){a.checkApplicable(this.elementPath())&&x.call(a,this.getSelection(),1)};CKEDITOR.style.prototype={apply:function(a){x.call(this,a.getSelection())},\nremove:function(a){x.call(this,a.getSelection(),1)},applyToRange:function(a){return(this.applyToRange=this.type==CKEDITOR.STYLE_INLINE?e:this.type==CKEDITOR.STYLE_BLOCK?g:this.type==CKEDITOR.STYLE_OBJECT?d:null).call(this,a)},removeFromRange:function(a){return(this.removeFromRange=this.type==CKEDITOR.STYLE_INLINE?b:this.type==CKEDITOR.STYLE_BLOCK?n:this.type==CKEDITOR.STYLE_OBJECT?h:null).call(this,a)},applyToObject:function(a){m(a,this)},checkActive:function(a){switch(this.type){case CKEDITOR.STYLE_BLOCK:return this.checkElementRemovable(a.block||\na.blockLimit,true);case CKEDITOR.STYLE_OBJECT:case CKEDITOR.STYLE_INLINE:for(var b=a.elements,c=0,d;c<b.length;c++){d=b[c];if(!(this.type==CKEDITOR.STYLE_INLINE&&(d==a.block||d==a.blockLimit))){if(this.type==CKEDITOR.STYLE_OBJECT){var e=d.getName();if(!(typeof this.element==\"string\"?e==this.element:e in this.element))continue}if(this.checkElementRemovable(d,true))return true}}}return false},checkApplicable:function(a,b){if(b&&!b.check(this))return false;switch(this.type){case CKEDITOR.STYLE_OBJECT:return!!a.contains(this.element);\ncase CKEDITOR.STYLE_BLOCK:return!!a.blockLimit.getDtd()[this.element]}return true},checkElementMatch:function(a,b){var c=this._.definition;if(!a||!c.ignoreReadonly&&a.isReadOnly())return false;var d=a.getName();if(typeof this.element==\"string\"?d==this.element:d in this.element){if(!b&&!a.hasAttributes())return true;if(d=c._AC)c=d;else{var d={},e=0,f=c.attributes;if(f)for(var g in f){e++;d[g]=f[g]}if(g=CKEDITOR.style.getStyleText(c)){d.style||e++;d.style=g}d._length=e;c=c._AC=d}if(c._length){for(var h in c)if(h!=\n\"_length\"){e=a.getAttribute(h)||\"\";if(h==\"style\")a:{d=c[h];typeof d==\"string\"&&(d=CKEDITOR.tools.parseCssText(d));typeof e==\"string\"&&(e=CKEDITOR.tools.parseCssText(e,true));g=void 0;for(g in d)if(!(g in e&&(e[g]==d[g]||d[g]==\"inherit\"||e[g]==\"inherit\"))){d=false;break a}d=true}else d=c[h]==e;if(d){if(!b)return true}else if(b)return false}if(b)return true}else return true}return false},checkElementRemovable:function(a,b){if(this.checkElementMatch(a,b))return true;var c=l(this)[a.getName()];if(c){var d;\nif(!(c=c.attributes))return true;for(var e=0;e<c.length;e++){d=c[e][0];if(d=a.getAttribute(d)){var f=c[e][1];if(f===null||typeof f==\"string\"&&d==f||f.test(d))return true}}}return false},buildPreview:function(a){var b=this._.definition,c=[],d=b.element;d==\"bdo\"&&(d=\"span\");var c=[\"<\",d],e=b.attributes;if(e)for(var f in e)c.push(\" \",f,'=\"',e[f],'\"');(e=CKEDITOR.style.getStyleText(b))&&c.push(' style=\"',e,'\"');c.push(\">\",a||b.name,\"</\",d,\">\");return c.join(\"\")},getDefinition:function(){return this._.definition}};\nCKEDITOR.style.getStyleText=function(a){var b=a._ST;if(b)return b;var b=a.styles,c=a.attributes&&a.attributes.style||\"\",d=\"\";c.length&&(c=c.replace(A,\";\"));for(var e in b){var f=b[e],g=(e+\":\"+f).replace(A,\";\");f==\"inherit\"?d=d+g:c=c+g}c.length&&(c=CKEDITOR.tools.normalizeCssText(c,true));return a._ST=c+d};var M=CKEDITOR.POSITION_PRECEDING|CKEDITOR.POSITION_IDENTICAL|CKEDITOR.POSITION_IS_CONTAINED,Q=CKEDITOR.POSITION_FOLLOWING|CKEDITOR.POSITION_IDENTICAL|CKEDITOR.POSITION_IS_CONTAINED})();\nCKEDITOR.styleCommand=function(a,e){this.requiredContent=this.allowedContent=this.style=a;CKEDITOR.tools.extend(this,e,true)};CKEDITOR.styleCommand.prototype.exec=function(a){a.focus();this.state==CKEDITOR.TRISTATE_OFF?a.applyStyle(this.style):this.state==CKEDITOR.TRISTATE_ON&&a.removeStyle(this.style)};CKEDITOR.stylesSet=new CKEDITOR.resourceManager(\"\",\"stylesSet\");CKEDITOR.addStylesSet=CKEDITOR.tools.bind(CKEDITOR.stylesSet.add,CKEDITOR.stylesSet);\nCKEDITOR.loadStylesSet=function(a,e,b){CKEDITOR.stylesSet.addExternal(a,e,\"\");CKEDITOR.stylesSet.load(a,b)};\nCKEDITOR.editor.prototype.getStylesSet=function(a){if(this._.stylesDefinitions)a(this._.stylesDefinitions);else{var e=this,b=e.config.stylesCombo_stylesSet||e.config.stylesSet;if(b===false)a(null);else if(b instanceof Array){e._.stylesDefinitions=b;a(b)}else{b||(b=\"default\");var b=b.split(\":\"),c=b[0];CKEDITOR.stylesSet.addExternal(c,b[1]?b.slice(1).join(\":\"):CKEDITOR.getUrl(\"styles.js\"),\"\");CKEDITOR.stylesSet.load(c,function(b){e._.stylesDefinitions=b[c];a(e._.stylesDefinitions)})}}};\nCKEDITOR.dom.comment=function(a,e){typeof a==\"string\"&&(a=(e?e.$:document).createComment(a));CKEDITOR.dom.domObject.call(this,a)};CKEDITOR.dom.comment.prototype=new CKEDITOR.dom.node;CKEDITOR.tools.extend(CKEDITOR.dom.comment.prototype,{type:CKEDITOR.NODE_COMMENT,getOuterHtml:function(){return\"<\\!--\"+this.$.nodeValue+\"--\\>\"}});\"use strict\";\n(function(){var a={},e={},b;for(b in CKEDITOR.dtd.$blockLimit)b in CKEDITOR.dtd.$list||(a[b]=1);for(b in CKEDITOR.dtd.$block)b in CKEDITOR.dtd.$blockLimit||b in CKEDITOR.dtd.$empty||(e[b]=1);CKEDITOR.dom.elementPath=function(b,d){var h=null,g=null,n=[],i=b,j,d=d||b.getDocument().getBody();do if(i.type==CKEDITOR.NODE_ELEMENT){n.push(i);if(!this.lastElement){this.lastElement=i;if(i.is(CKEDITOR.dtd.$object)||i.getAttribute(\"contenteditable\")==\"false\")continue}if(i.equals(d))break;if(!g){j=i.getName();\ni.getAttribute(\"contenteditable\")==\"true\"?g=i:!h&&e[j]&&(h=i);if(a[j]){var o;if(o=!h){if(j=j==\"div\"){a:{j=i.getChildren();o=0;for(var q=j.count();o<q;o++){var s=j.getItem(o);if(s.type==CKEDITOR.NODE_ELEMENT&&CKEDITOR.dtd.$block[s.getName()]){j=true;break a}}j=false}j=!j}o=j}o?h=i:g=i}}}while(i=i.getParent());g||(g=d);this.block=h;this.blockLimit=g;this.root=d;this.elements=n}})();\nCKEDITOR.dom.elementPath.prototype={compare:function(a){var e=this.elements,a=a&&a.elements;if(!a||e.length!=a.length)return false;for(var b=0;b<e.length;b++)if(!e[b].equals(a[b]))return false;return true},contains:function(a,e,b){var c;typeof a==\"string\"&&(c=function(b){return b.getName()==a});a instanceof CKEDITOR.dom.element?c=function(b){return b.equals(a)}:CKEDITOR.tools.isArray(a)?c=function(b){return CKEDITOR.tools.indexOf(a,b.getName())>-1}:typeof a==\"function\"?c=a:typeof a==\"object\"&&(c=\nfunction(b){return b.getName()in a});var d=this.elements,h=d.length;e&&h--;if(b){d=Array.prototype.slice.call(d,0);d.reverse()}for(e=0;e<h;e++)if(c(d[e]))return d[e];return null},isContextFor:function(a){var e;if(a in CKEDITOR.dtd.$block){e=this.contains(CKEDITOR.dtd.$intermediate)||this.root.equals(this.block)&&this.block||this.blockLimit;return!!e.getDtd()[a]}return true},direction:function(){return(this.block||this.blockLimit||this.root).getDirection(1)}};\nCKEDITOR.dom.text=function(a,e){typeof a==\"string\"&&(a=(e?e.$:document).createTextNode(a));this.$=a};CKEDITOR.dom.text.prototype=new CKEDITOR.dom.node;\nCKEDITOR.tools.extend(CKEDITOR.dom.text.prototype,{type:CKEDITOR.NODE_TEXT,getLength:function(){return this.$.nodeValue.length},getText:function(){return this.$.nodeValue},setText:function(a){this.$.nodeValue=a},split:function(a){var e=this.$.parentNode,b=e.childNodes.length,c=this.getLength(),d=this.getDocument(),h=new CKEDITOR.dom.text(this.$.splitText(a),d);if(e.childNodes.length==b)if(a>=c){h=d.createText(\"\");h.insertAfter(this)}else{a=d.createText(\"\");a.insertAfter(h);a.remove()}return h},substring:function(a,\ne){return typeof e!=\"number\"?this.$.nodeValue.substr(a):this.$.nodeValue.substring(a,e)}});\n(function(){function a(a,c,d){var e=a.serializable,g=c[d?\"endContainer\":\"startContainer\"],n=d?\"endOffset\":\"startOffset\",i=e?c.document.getById(a.startNode):a.startNode,a=e?c.document.getById(a.endNode):a.endNode;if(g.equals(i.getPrevious())){c.startOffset=c.startOffset-g.getLength()-a.getPrevious().getLength();g=a.getNext()}else if(g.equals(a.getPrevious())){c.startOffset=c.startOffset-g.getLength();g=a.getNext()}g.equals(i.getParent())&&c[n]++;g.equals(a.getParent())&&c[n]++;c[d?\"endContainer\":\"startContainer\"]=\ng;return c}CKEDITOR.dom.rangeList=function(a){if(a instanceof CKEDITOR.dom.rangeList)return a;a?a instanceof CKEDITOR.dom.range&&(a=[a]):a=[];return CKEDITOR.tools.extend(a,e)};var e={createIterator:function(){var a=this,c=CKEDITOR.dom.walker.bookmark(),d=[],e;return{getNextRange:function(g){e=e==void 0?0:e+1;var n=a[e];if(n&&a.length>1){if(!e)for(var i=a.length-1;i>=0;i--)d.unshift(a[i].createBookmark(true));if(g)for(var j=0;a[e+j+1];){for(var o=n.document,g=0,i=o.getById(d[j].endNode),o=o.getById(d[j+\n1].startNode);;){i=i.getNextSourceNode(false);if(o.equals(i))g=1;else if(c(i)||i.type==CKEDITOR.NODE_ELEMENT&&i.isBlockBoundary())continue;break}if(!g)break;j++}for(n.moveToBookmark(d.shift());j--;){i=a[++e];i.moveToBookmark(d.shift());n.setEnd(i.endContainer,i.endOffset)}}return n}}},createBookmarks:function(b){for(var c=[],d,e=0;e<this.length;e++){c.push(d=this[e].createBookmark(b,true));for(var g=e+1;g<this.length;g++){this[g]=a(d,this[g]);this[g]=a(d,this[g],true)}}return c},createBookmarks2:function(a){for(var c=\n[],d=0;d<this.length;d++)c.push(this[d].createBookmark2(a));return c},moveToBookmarks:function(a){for(var c=0;c<this.length;c++)this[c].moveToBookmark(a[c])}}})();\n(function(){function a(){return CKEDITOR.getUrl(CKEDITOR.skinName.split(\",\")[1]||\"skins/\"+CKEDITOR.skinName.split(\",\")[0]+\"/\")}function e(b){var c=CKEDITOR.skin[\"ua_\"+b],d=CKEDITOR.env;if(c)for(var c=c.split(\",\").sort(function(a,b){return a>b?-1:1}),e=0,g;e<c.length;e++){g=c[e];if(d.ie&&(g.replace(/^ie/,\"\")==d.version||d.quirks&&g==\"iequirks\"))g=\"ie\";if(d[g]){b=b+(\"_\"+c[e]);break}}return CKEDITOR.getUrl(a()+b+\".css\")}function b(a,b){if(!h[a]){CKEDITOR.document.appendStyleSheet(e(a));h[a]=1}b&&b()}\nfunction c(a){var b=a.getById(g);if(!b){b=a.getHead().append(\"style\");b.setAttribute(\"id\",g);b.setAttribute(\"type\",\"text/css\")}return b}function d(a,b,c){var d,e,f;if(CKEDITOR.env.webkit){b=b.split(\"}\").slice(0,-1);for(e=0;e<b.length;e++)b[e]=b[e].split(\"{\")}for(var g=0;g<a.length;g++)if(CKEDITOR.env.webkit)for(e=0;e<b.length;e++){f=b[e][1];for(d=0;d<c.length;d++)f=f.replace(c[d][0],c[d][1]);a[g].$.sheet.addRule(b[e][0],f)}else{f=b;for(d=0;d<c.length;d++)f=f.replace(c[d][0],c[d][1]);CKEDITOR.env.ie&&\nCKEDITOR.env.version<11?a[g].$.styleSheet.cssText=a[g].$.styleSheet.cssText+f:a[g].$.innerHTML=a[g].$.innerHTML+f}}var h={};CKEDITOR.skin={path:a,loadPart:function(c,d){CKEDITOR.skin.name!=CKEDITOR.skinName.split(\",\")[0]?CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(a()+\"skin.js\"),function(){b(c,d)}):b(c,d)},getPath:function(a){return CKEDITOR.getUrl(e(a))},icons:{},addIcon:function(a,b,c,d){a=a.toLowerCase();this.icons[a]||(this.icons[a]={path:b,offset:c||0,bgsize:d||\"16px\"})},getIconStyle:function(a,\nb,c,d,e){var f;if(a){a=a.toLowerCase();b&&(f=this.icons[a+\"-rtl\"]);f||(f=this.icons[a])}a=c||f&&f.path||\"\";d=d||f&&f.offset;e=e||f&&f.bgsize||\"16px\";return a&&\"background-image:url(\"+CKEDITOR.getUrl(a)+\");background-position:0 \"+d+\"px;background-size:\"+e+\";\"}};CKEDITOR.tools.extend(CKEDITOR.editor.prototype,{getUiColor:function(){return this.uiColor},setUiColor:function(a){var b=c(CKEDITOR.document);return(this.setUiColor=function(a){var c=CKEDITOR.skin.chameleon,e=[[i,a]];this.uiColor=a;d([b],c(this,\n\"editor\"),e);d(n,c(this,\"panel\"),e)}).call(this,a)}});var g=\"cke_ui_color\",n=[],i=/\\$color/g;CKEDITOR.on(\"instanceLoaded\",function(a){if(!CKEDITOR.env.ie||!CKEDITOR.env.quirks){var b=a.editor,a=function(a){a=(a.data[0]||a.data).element.getElementsByTag(\"iframe\").getItem(0).getFrameDocument();if(!a.getById(\"cke_ui_color\")){a=c(a);n.push(a);var e=b.getUiColor();e&&d([a],CKEDITOR.skin.chameleon(b,\"panel\"),[[i,e]])}};b.on(\"panelShow\",a);b.on(\"menuShow\",a);b.config.uiColor&&b.setUiColor(b.config.uiColor)}})})();\n(function(){if(CKEDITOR.env.webkit)CKEDITOR.env.hc=false;else{var a=CKEDITOR.dom.element.createFromHtml('<div style=\"width:0px;height:0px;position:absolute;left:-10000px;border: 1px solid;border-color: red blue;\"></div>',CKEDITOR.document);a.appendTo(CKEDITOR.document.getHead());try{CKEDITOR.env.hc=a.getComputedStyle(\"border-top-color\")==a.getComputedStyle(\"border-right-color\")}catch(e){CKEDITOR.env.hc=false}a.remove()}if(CKEDITOR.env.hc)CKEDITOR.env.cssClass=CKEDITOR.env.cssClass+\" cke_hc\";CKEDITOR.document.appendStyleText(\".cke{visibility:hidden;}\");\nCKEDITOR.status=\"loaded\";CKEDITOR.fireOnce(\"loaded\");if(a=CKEDITOR._.pending){delete CKEDITOR._.pending;for(var b=0;b<a.length;b++){CKEDITOR.editor.prototype.constructor.apply(a[b][0],a[b][1]);CKEDITOR.add(a[b][0])}}})();/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.skin.name=\"moono\";CKEDITOR.skin.ua_editor=\"ie,iequirks,ie7,ie8,gecko\";CKEDITOR.skin.ua_dialog=\"ie,iequirks,ie7,ie8,opera\";\nCKEDITOR.skin.chameleon=function(){var b=function(){return function(b,e){for(var a=b.match(/[^#]./g),c=0;3>c;c++){var f=a,h=c,d;d=parseInt(a[c],16);d=(\"0\"+(0>e?0|d*(1+e):0|d+(255-d)*e).toString(16)).slice(-2);f[h]=d}return\"#\"+a.join(\"\")}}(),c=function(){var b=new CKEDITOR.template(\"background:#{to};background-image:-webkit-gradient(linear,lefttop,leftbottom,from({from}),to({to}));background-image:-moz-linear-gradient(top,{from},{to});background-image:-webkit-linear-gradient(top,{from},{to});background-image:-o-linear-gradient(top,{from},{to});background-image:-ms-linear-gradient(top,{from},{to});background-image:linear-gradient(top,{from},{to});filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='{from}',endColorstr='{to}');\");return function(c,\na){return b.output({from:c,to:a})}}(),f={editor:new CKEDITOR.template(\"{id}.cke_chrome [border-color:{defaultBorder};] {id} .cke_top [ {defaultGradient}border-bottom-color:{defaultBorder};] {id} .cke_bottom [{defaultGradient}border-top-color:{defaultBorder};] {id} .cke_resizer [border-right-color:{ckeResizer}] {id} .cke_dialog_title [{defaultGradient}border-bottom-color:{defaultBorder};] {id} .cke_dialog_footer [{defaultGradient}outline-color:{defaultBorder};border-top-color:{defaultBorder};] {id} .cke_dialog_tab [{lightGradient}border-color:{defaultBorder};] {id} .cke_dialog_tab:hover [{mediumGradient}] {id} .cke_dialog_contents [border-top-color:{defaultBorder};] {id} .cke_dialog_tab_selected, {id} .cke_dialog_tab_selected:hover [background:{dialogTabSelected};border-bottom-color:{dialogTabSelectedBorder};] {id} .cke_dialog_body [background:{dialogBody};border-color:{defaultBorder};] {id} .cke_toolgroup [{lightGradient}border-color:{defaultBorder};] {id} a.cke_button_off:hover, {id} a.cke_button_off:focus, {id} a.cke_button_off:active [{mediumGradient}] {id} .cke_button_on [{ckeButtonOn}] {id} .cke_toolbar_separator [background-color: {ckeToolbarSeparator};] {id} .cke_combo_button [border-color:{defaultBorder};{lightGradient}] {id} a.cke_combo_button:hover, {id} a.cke_combo_button:focus, {id} .cke_combo_on a.cke_combo_button [border-color:{defaultBorder};{mediumGradient}] {id} .cke_path_item [color:{elementsPathColor};] {id} a.cke_path_item:hover, {id} a.cke_path_item:focus, {id} a.cke_path_item:active [background-color:{elementsPathBg};] {id}.cke_panel [border-color:{defaultBorder};] \"),\npanel:new CKEDITOR.template(\".cke_panel_grouptitle [{lightGradient}border-color:{defaultBorder};] .cke_menubutton_icon [background-color:{menubuttonIcon};] .cke_menubutton:hover .cke_menubutton_icon, .cke_menubutton:focus .cke_menubutton_icon, .cke_menubutton:active .cke_menubutton_icon [background-color:{menubuttonIconHover};] .cke_menuseparator [background-color:{menubuttonIcon};] a:hover.cke_colorbox, a:focus.cke_colorbox, a:active.cke_colorbox [border-color:{defaultBorder};] a:hover.cke_colorauto, a:hover.cke_colormore, a:focus.cke_colorauto, a:focus.cke_colormore, a:active.cke_colorauto, a:active.cke_colormore [background-color:{ckeColorauto};border-color:{defaultBorder};] \")};\nreturn function(g,e){var a=g.uiColor,a={id:\".\"+g.id,defaultBorder:b(a,-0.1),defaultGradient:c(b(a,0.9),a),lightGradient:c(b(a,1),b(a,0.7)),mediumGradient:c(b(a,0.8),b(a,0.5)),ckeButtonOn:c(b(a,0.6),b(a,0.7)),ckeResizer:b(a,-0.4),ckeToolbarSeparator:b(a,0.5),ckeColorauto:b(a,0.8),dialogBody:b(a,0.7),dialogTabSelected:c(\"#FFFFFF\",\"#FFFFFF\"),dialogTabSelectedBorder:\"#FFF\",elementsPathColor:b(a,-0.6),elementsPathBg:a,menubuttonIcon:b(a,0.5),menubuttonIconHover:b(a,0.3)};return f[e].output(a).replace(/\\[/g,\n\"{\").replace(/\\]/g,\"}\")}}();CKEDITOR.plugins.add(\"dialogui\",{onLoad:function(){var i=function(b){this._||(this._={});this._[\"default\"]=this._.initValue=b[\"default\"]||\"\";this._.required=b.required||!1;for(var a=[this._],d=1;d<arguments.length;d++)a.push(arguments[d]);a.push(!0);CKEDITOR.tools.extend.apply(CKEDITOR.tools,a);return this._},r={build:function(b,a,d){return new CKEDITOR.ui.dialog.textInput(b,a,d)}},l={build:function(b,a,d){return new CKEDITOR.ui.dialog[a.type](b,a,d)}},n={isChanged:function(){return this.getValue()!=\nthis.getInitValue()},reset:function(b){this.setValue(this.getInitValue(),b)},setInitValue:function(){this._.initValue=this.getValue()},resetInitValue:function(){this._.initValue=this._[\"default\"]},getInitValue:function(){return this._.initValue}},o=CKEDITOR.tools.extend({},CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors,{onChange:function(b,a){this._.domOnChangeRegistered||(b.on(\"load\",function(){this.getInputElement().on(\"change\",function(){b.parts.dialog.isVisible()&&this.fire(\"change\",{value:this.getValue()})},\nthis)},this),this._.domOnChangeRegistered=!0);this.on(\"change\",a)}},!0),s=/^on([A-Z]\\w+)/,p=function(b){for(var a in b)(s.test(a)||\"title\"==a||\"type\"==a)&&delete b[a];return b};CKEDITOR.tools.extend(CKEDITOR.ui.dialog,{labeledElement:function(b,a,d,e){if(!(4>arguments.length)){var c=i.call(this,a);c.labelId=CKEDITOR.tools.getNextId()+\"_label\";this._.children=[];CKEDITOR.ui.dialog.uiElement.call(this,b,a,d,\"div\",null,{role:\"presentation\"},function(){var f=[],d=a.required?\" cke_required\":\"\";\"horizontal\"!=\na.labelLayout?f.push('<label class=\"cke_dialog_ui_labeled_label'+d+'\" ',' id=\"'+c.labelId+'\"',c.inputId?' for=\"'+c.inputId+'\"':\"\",(a.labelStyle?' style=\"'+a.labelStyle+'\"':\"\")+\">\",a.label,\"</label>\",'<div class=\"cke_dialog_ui_labeled_content\"',a.controlStyle?' style=\"'+a.controlStyle+'\"':\"\",' role=\"radiogroup\" aria-labelledby=\"'+c.labelId+'\">',e.call(this,b,a),\"</div>\"):(d={type:\"hbox\",widths:a.widths,padding:0,children:[{type:\"html\",html:'<label class=\"cke_dialog_ui_labeled_label'+d+'\" id=\"'+c.labelId+\n'\" for=\"'+c.inputId+'\"'+(a.labelStyle?' style=\"'+a.labelStyle+'\"':\"\")+\">\"+CKEDITOR.tools.htmlEncode(a.label)+\"</span>\"},{type:\"html\",html:'<span class=\"cke_dialog_ui_labeled_content\"'+(a.controlStyle?' style=\"'+a.controlStyle+'\"':\"\")+\">\"+e.call(this,b,a)+\"</span>\"}]},CKEDITOR.dialog._.uiElementBuilders.hbox.build(b,d,f));return f.join(\"\")})}},textInput:function(b,a,d){if(!(3>arguments.length)){i.call(this,a);var e=this._.inputId=CKEDITOR.tools.getNextId()+\"_textInput\",c={\"class\":\"cke_dialog_ui_input_\"+\na.type,id:e,type:a.type};a.validate&&(this.validate=a.validate);a.maxLength&&(c.maxlength=a.maxLength);a.size&&(c.size=a.size);a.inputStyle&&(c.style=a.inputStyle);var f=this,h=!1;b.on(\"load\",function(){f.getInputElement().on(\"keydown\",function(a){a.data.getKeystroke()==13&&(h=true)});f.getInputElement().on(\"keyup\",function(a){if(a.data.getKeystroke()==13&&h){b.getButton(\"ok\")&&setTimeout(function(){b.getButton(\"ok\").click()},0);h=false}},null,null,1E3)});CKEDITOR.ui.dialog.labeledElement.call(this,\nb,a,d,function(){var b=['<div class=\"cke_dialog_ui_input_',a.type,'\" role=\"presentation\"'];a.width&&b.push('style=\"width:'+a.width+'\" ');b.push(\"><input \");c[\"aria-labelledby\"]=this._.labelId;this._.required&&(c[\"aria-required\"]=this._.required);for(var d in c)b.push(d+'=\"'+c[d]+'\" ');b.push(\" /></div>\");return b.join(\"\")})}},textarea:function(b,a,d){if(!(3>arguments.length)){i.call(this,a);var e=this,c=this._.inputId=CKEDITOR.tools.getNextId()+\"_textarea\",f={};a.validate&&(this.validate=a.validate);\nf.rows=a.rows||5;f.cols=a.cols||20;f[\"class\"]=\"cke_dialog_ui_input_textarea \"+(a[\"class\"]||\"\");\"undefined\"!=typeof a.inputStyle&&(f.style=a.inputStyle);a.dir&&(f.dir=a.dir);CKEDITOR.ui.dialog.labeledElement.call(this,b,a,d,function(){f[\"aria-labelledby\"]=this._.labelId;this._.required&&(f[\"aria-required\"]=this._.required);var a=['<div class=\"cke_dialog_ui_input_textarea\" role=\"presentation\"><textarea id=\"',c,'\" '],b;for(b in f)a.push(b+'=\"'+CKEDITOR.tools.htmlEncode(f[b])+'\" ');a.push(\">\",CKEDITOR.tools.htmlEncode(e._[\"default\"]),\n\"</textarea></div>\");return a.join(\"\")})}},checkbox:function(b,a,d){if(!(3>arguments.length)){var e=i.call(this,a,{\"default\":!!a[\"default\"]});a.validate&&(this.validate=a.validate);CKEDITOR.ui.dialog.uiElement.call(this,b,a,d,\"span\",null,null,function(){var c=CKEDITOR.tools.extend({},a,{id:a.id?a.id+\"_checkbox\":CKEDITOR.tools.getNextId()+\"_checkbox\"},true),d=[],h=CKEDITOR.tools.getNextId()+\"_label\",g={\"class\":\"cke_dialog_ui_checkbox_input\",type:\"checkbox\",\"aria-labelledby\":h};p(c);if(a[\"default\"])g.checked=\n\"checked\";if(typeof c.inputStyle!=\"undefined\")c.style=c.inputStyle;e.checkbox=new CKEDITOR.ui.dialog.uiElement(b,c,d,\"input\",null,g);d.push(' <label id=\"',h,'\" for=\"',g.id,'\"'+(a.labelStyle?' style=\"'+a.labelStyle+'\"':\"\")+\">\",CKEDITOR.tools.htmlEncode(a.label),\"</label>\");return d.join(\"\")})}},radio:function(b,a,d){if(!(3>arguments.length)){i.call(this,a);this._[\"default\"]||(this._[\"default\"]=this._.initValue=a.items[0][1]);a.validate&&(this.validate=a.valdiate);var e=[],c=this;CKEDITOR.ui.dialog.labeledElement.call(this,\nb,a,d,function(){for(var d=[],h=[],g=(a.id?a.id:CKEDITOR.tools.getNextId())+\"_radio\",k=0;k<a.items.length;k++){var j=a.items[k],i=j[2]!==void 0?j[2]:j[0],l=j[1]!==void 0?j[1]:j[0],m=CKEDITOR.tools.getNextId()+\"_radio_input\",n=m+\"_label\",m=CKEDITOR.tools.extend({},a,{id:m,title:null,type:null},true),i=CKEDITOR.tools.extend({},m,{title:i},true),o={type:\"radio\",\"class\":\"cke_dialog_ui_radio_input\",name:g,value:l,\"aria-labelledby\":n},q=[];if(c._[\"default\"]==l)o.checked=\"checked\";p(m);p(i);if(typeof m.inputStyle!=\n\"undefined\")m.style=m.inputStyle;m.keyboardFocusable=true;e.push(new CKEDITOR.ui.dialog.uiElement(b,m,q,\"input\",null,o));q.push(\" \");new CKEDITOR.ui.dialog.uiElement(b,i,q,\"label\",null,{id:n,\"for\":o.id},j[0]);d.push(q.join(\"\"))}new CKEDITOR.ui.dialog.hbox(b,e,d,h);return h.join(\"\")});this._.children=e}},button:function(b,a,d){if(arguments.length){\"function\"==typeof a&&(a=a(b.getParentEditor()));i.call(this,a,{disabled:a.disabled||!1});CKEDITOR.event.implementOn(this);var e=this;b.on(\"load\",function(){var a=\nthis.getElement();(function(){a.on(\"click\",function(a){e.click();a.data.preventDefault()});a.on(\"keydown\",function(a){a.data.getKeystroke()in{32:1}&&(e.click(),a.data.preventDefault())})})();a.unselectable()},this);var c=CKEDITOR.tools.extend({},a);delete c.style;var f=CKEDITOR.tools.getNextId()+\"_label\";CKEDITOR.ui.dialog.uiElement.call(this,b,c,d,\"a\",null,{style:a.style,href:\"javascript:void(0)\",title:a.label,hidefocus:\"true\",\"class\":a[\"class\"],role:\"button\",\"aria-labelledby\":f},'<span id=\"'+f+\n'\" class=\"cke_dialog_ui_button\">'+CKEDITOR.tools.htmlEncode(a.label)+\"</span>\")}},select:function(b,a,d){if(!(3>arguments.length)){var e=i.call(this,a);a.validate&&(this.validate=a.validate);e.inputId=CKEDITOR.tools.getNextId()+\"_select\";CKEDITOR.ui.dialog.labeledElement.call(this,b,a,d,function(){var c=CKEDITOR.tools.extend({},a,{id:a.id?a.id+\"_select\":CKEDITOR.tools.getNextId()+\"_select\"},true),d=[],h=[],g={id:e.inputId,\"class\":\"cke_dialog_ui_input_select\",\"aria-labelledby\":this._.labelId};d.push('<div class=\"cke_dialog_ui_input_',\na.type,'\" role=\"presentation\"');a.width&&d.push('style=\"width:'+a.width+'\" ');d.push(\">\");if(a.size!=void 0)g.size=a.size;if(a.multiple!=void 0)g.multiple=a.multiple;p(c);for(var k=0,j;k<a.items.length&&(j=a.items[k]);k++)h.push('<option value=\"',CKEDITOR.tools.htmlEncode(j[1]!==void 0?j[1]:j[0]).replace(/\"/g,\"&quot;\"),'\" /> ',CKEDITOR.tools.htmlEncode(j[0]));if(typeof c.inputStyle!=\"undefined\")c.style=c.inputStyle;e.select=new CKEDITOR.ui.dialog.uiElement(b,c,d,\"select\",null,g,h.join(\"\"));d.push(\"</div>\");\nreturn d.join(\"\")})}},file:function(b,a,d){if(!(3>arguments.length)){void 0===a[\"default\"]&&(a[\"default\"]=\"\");var e=CKEDITOR.tools.extend(i.call(this,a),{definition:a,buttons:[]});a.validate&&(this.validate=a.validate);b.on(\"load\",function(){CKEDITOR.document.getById(e.frameId).getParent().addClass(\"cke_dialog_ui_input_file\")});CKEDITOR.ui.dialog.labeledElement.call(this,b,a,d,function(){e.frameId=CKEDITOR.tools.getNextId()+\"_fileInput\";var b=['<iframe frameborder=\"0\" allowtransparency=\"0\" class=\"cke_dialog_ui_input_file\" role=\"presentation\" id=\"',\ne.frameId,'\" title=\"',a.label,'\" src=\"javascript:void('];b.push(CKEDITOR.env.ie?\"(function(){\"+encodeURIComponent(\"document.open();(\"+CKEDITOR.tools.fixDomain+\")();document.close();\")+\"})()\":\"0\");b.push(')\"></iframe>');return b.join(\"\")})}},fileButton:function(b,a,d){if(!(3>arguments.length)){i.call(this,a);var e=this;a.validate&&(this.validate=a.validate);var c=CKEDITOR.tools.extend({},a),f=c.onClick;c.className=(c.className?c.className+\" \":\"\")+\"cke_dialog_ui_button\";c.onClick=function(c){var d=\na[\"for\"];if(!f||f.call(this,c)!==false){b.getContentElement(d[0],d[1]).submit();this.disable()}};b.on(\"load\",function(){b.getContentElement(a[\"for\"][0],a[\"for\"][1])._.buttons.push(e)});CKEDITOR.ui.dialog.button.call(this,b,c,d)}},html:function(){var b=/^\\s*<[\\w:]+\\s+([^>]*)?>/,a=/^(\\s*<[\\w:]+(?:\\s+[^>]*)?)((?:.|\\r|\\n)+)$/,d=/\\/$/;return function(e,c,f){if(!(3>arguments.length)){var h=[],g=c.html;\"<\"!=g.charAt(0)&&(g=\"<span>\"+g+\"</span>\");var k=c.focus;if(k){var j=this.focus;this.focus=function(){(\"function\"==\ntypeof k?k:j).call(this);this.fire(\"focus\")};c.isFocusable&&(this.isFocusable=this.isFocusable);this.keyboardFocusable=!0}CKEDITOR.ui.dialog.uiElement.call(this,e,c,h,\"span\",null,null,\"\");h=h.join(\"\").match(b);g=g.match(a)||[\"\",\"\",\"\"];d.test(g[1])&&(g[1]=g[1].slice(0,-1),g[2]=\"/\"+g[2]);f.push([g[1],\" \",h[1]||\"\",g[2]].join(\"\"))}}}(),fieldset:function(b,a,d,e,c){var f=c.label;this._={children:a};CKEDITOR.ui.dialog.uiElement.call(this,b,c,e,\"fieldset\",null,null,function(){var a=[];f&&a.push(\"<legend\"+\n(c.labelStyle?' style=\"'+c.labelStyle+'\"':\"\")+\">\"+f+\"</legend>\");for(var b=0;b<d.length;b++)a.push(d[b]);return a.join(\"\")})}},!0);CKEDITOR.ui.dialog.html.prototype=new CKEDITOR.ui.dialog.uiElement;CKEDITOR.ui.dialog.labeledElement.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.uiElement,{setLabel:function(b){var a=CKEDITOR.document.getById(this._.labelId);1>a.getChildCount()?(new CKEDITOR.dom.text(b,CKEDITOR.document)).appendTo(a):a.getChild(0).$.nodeValue=b;return this},getLabel:function(){var b=\nCKEDITOR.document.getById(this._.labelId);return!b||1>b.getChildCount()?\"\":b.getChild(0).getText()},eventProcessors:o},!0);CKEDITOR.ui.dialog.button.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.uiElement,{click:function(){return!this._.disabled?this.fire(\"click\",{dialog:this._.dialog}):!1},enable:function(){this._.disabled=!1;var b=this.getElement();b&&b.removeClass(\"cke_disabled\")},disable:function(){this._.disabled=!0;this.getElement().addClass(\"cke_disabled\")},isVisible:function(){return this.getElement().getFirst().isVisible()},\nisEnabled:function(){return!this._.disabled},eventProcessors:CKEDITOR.tools.extend({},CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors,{onClick:function(b,a){this.on(\"click\",function(){a.apply(this,arguments)})}},!0),accessKeyUp:function(){this.click()},accessKeyDown:function(){this.focus()},keyboardFocusable:!0},!0);CKEDITOR.ui.dialog.textInput.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.labeledElement,{getInputElement:function(){return CKEDITOR.document.getById(this._.inputId)},\nfocus:function(){var b=this.selectParentTab();setTimeout(function(){var a=b.getInputElement();a&&a.$.focus()},0)},select:function(){var b=this.selectParentTab();setTimeout(function(){var a=b.getInputElement();a&&(a.$.focus(),a.$.select())},0)},accessKeyUp:function(){this.select()},setValue:function(b){!b&&(b=\"\");return CKEDITOR.ui.dialog.uiElement.prototype.setValue.apply(this,arguments)},keyboardFocusable:!0},n,!0);CKEDITOR.ui.dialog.textarea.prototype=new CKEDITOR.ui.dialog.textInput;CKEDITOR.ui.dialog.select.prototype=\nCKEDITOR.tools.extend(new CKEDITOR.ui.dialog.labeledElement,{getInputElement:function(){return this._.select.getElement()},add:function(b,a,d){var e=new CKEDITOR.dom.element(\"option\",this.getDialog().getParentEditor().document),c=this.getInputElement().$;e.$.text=b;e.$.value=void 0===a||null===a?b:a;void 0===d||null===d?CKEDITOR.env.ie?c.add(e.$):c.add(e.$,null):c.add(e.$,d);return this},remove:function(b){this.getInputElement().$.remove(b);return this},clear:function(){for(var b=this.getInputElement().$;0<\nb.length;)b.remove(0);return this},keyboardFocusable:!0},n,!0);CKEDITOR.ui.dialog.checkbox.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.uiElement,{getInputElement:function(){return this._.checkbox.getElement()},setValue:function(b,a){this.getInputElement().$.checked=b;!a&&this.fire(\"change\",{value:b})},getValue:function(){return this.getInputElement().$.checked},accessKeyUp:function(){this.setValue(!this.getValue())},eventProcessors:{onChange:function(b,a){if(!CKEDITOR.env.ie||8<CKEDITOR.env.version)return o.onChange.apply(this,\narguments);b.on(\"load\",function(){var a=this._.checkbox.getElement();a.on(\"propertychange\",function(b){b=b.data.$;\"checked\"==b.propertyName&&this.fire(\"change\",{value:a.$.checked})},this)},this);this.on(\"change\",a);return null}},keyboardFocusable:!0},n,!0);CKEDITOR.ui.dialog.radio.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.uiElement,{setValue:function(b,a){for(var d=this._.children,e,c=0;c<d.length&&(e=d[c]);c++)e.getElement().$.checked=e.getValue()==b;!a&&this.fire(\"change\",{value:b})},\ngetValue:function(){for(var b=this._.children,a=0;a<b.length;a++)if(b[a].getElement().$.checked)return b[a].getValue();return null},accessKeyUp:function(){var b=this._.children,a;for(a=0;a<b.length;a++)if(b[a].getElement().$.checked){b[a].getElement().focus();return}b[0].getElement().focus()},eventProcessors:{onChange:function(b,a){if(CKEDITOR.env.ie)b.on(\"load\",function(){for(var a=this._.children,b=this,c=0;c<a.length;c++)a[c].getElement().on(\"propertychange\",function(a){a=a.data.$;\"checked\"==a.propertyName&&\nthis.$.checked&&b.fire(\"change\",{value:this.getAttribute(\"value\")})})},this),this.on(\"change\",a);else return o.onChange.apply(this,arguments);return null}}},n,!0);CKEDITOR.ui.dialog.file.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.labeledElement,n,{getInputElement:function(){var b=CKEDITOR.document.getById(this._.frameId).getFrameDocument();return 0<b.$.forms.length?new CKEDITOR.dom.element(b.$.forms[0].elements[0]):this.getElement()},submit:function(){this.getInputElement().getParent().$.submit();\nreturn this},getAction:function(){return this.getInputElement().getParent().$.action},registerEvents:function(b){var a=/^on([A-Z]\\w+)/,d,e=function(a,b,c,d){a.on(\"formLoaded\",function(){a.getInputElement().on(c,d,a)})},c;for(c in b)if(d=c.match(a))this.eventProcessors[c]?this.eventProcessors[c].call(this,this._.dialog,b[c]):e(this,this._.dialog,d[1].toLowerCase(),b[c]);return this},reset:function(){function b(){d.$.open();var b=\"\";e.size&&(b=e.size-(CKEDITOR.env.ie?7:0));var i=a.frameId+\"_input\";\nd.$.write(['<html dir=\"'+g+'\" lang=\"'+k+'\"><head><title></title></head><body style=\"margin: 0; overflow: hidden; background: transparent;\">','<form enctype=\"multipart/form-data\" method=\"POST\" dir=\"'+g+'\" lang=\"'+k+'\" action=\"',CKEDITOR.tools.htmlEncode(e.action),'\"><label id=\"',a.labelId,'\" for=\"',i,'\" style=\"display:none\">',CKEDITOR.tools.htmlEncode(e.label),'</label><input id=\"',i,'\" aria-labelledby=\"',a.labelId,'\" type=\"file\" name=\"',CKEDITOR.tools.htmlEncode(e.id||\"cke_upload\"),'\" size=\"',CKEDITOR.tools.htmlEncode(0<\nb?b:\"\"),'\" /></form></body></html><script>',CKEDITOR.env.ie?\"(\"+CKEDITOR.tools.fixDomain+\")();\":\"\",\"window.parent.CKEDITOR.tools.callFunction(\"+f+\");\",\"window.onbeforeunload = function() {window.parent.CKEDITOR.tools.callFunction(\"+h+\")}\",\"<\\/script>\"].join(\"\"));d.$.close();for(b=0;b<c.length;b++)c[b].enable()}var a=this._,d=CKEDITOR.document.getById(a.frameId).getFrameDocument(),e=a.definition,c=a.buttons,f=this.formLoadedNumber,h=this.formUnloadNumber,g=a.dialog._.editor.lang.dir,k=a.dialog._.editor.langCode;\nf||(f=this.formLoadedNumber=CKEDITOR.tools.addFunction(function(){this.fire(\"formLoaded\")},this),h=this.formUnloadNumber=CKEDITOR.tools.addFunction(function(){this.getInputElement().clearCustomData()},this),this.getDialog()._.editor.on(\"destroy\",function(){CKEDITOR.tools.removeFunction(f);CKEDITOR.tools.removeFunction(h)}));CKEDITOR.env.gecko?setTimeout(b,500):b()},getValue:function(){return this.getInputElement().$.value||\"\"},setInitValue:function(){this._.initValue=\"\"},eventProcessors:{onChange:function(b,\na){this._.domOnChangeRegistered||(this.on(\"formLoaded\",function(){this.getInputElement().on(\"change\",function(){this.fire(\"change\",{value:this.getValue()})},this)},this),this._.domOnChangeRegistered=!0);this.on(\"change\",a)}},keyboardFocusable:!0},!0);CKEDITOR.ui.dialog.fileButton.prototype=new CKEDITOR.ui.dialog.button;CKEDITOR.ui.dialog.fieldset.prototype=CKEDITOR.tools.clone(CKEDITOR.ui.dialog.hbox.prototype);CKEDITOR.dialog.addUIElement(\"text\",r);CKEDITOR.dialog.addUIElement(\"password\",r);CKEDITOR.dialog.addUIElement(\"textarea\",\nl);CKEDITOR.dialog.addUIElement(\"checkbox\",l);CKEDITOR.dialog.addUIElement(\"radio\",l);CKEDITOR.dialog.addUIElement(\"button\",l);CKEDITOR.dialog.addUIElement(\"select\",l);CKEDITOR.dialog.addUIElement(\"file\",l);CKEDITOR.dialog.addUIElement(\"fileButton\",l);CKEDITOR.dialog.addUIElement(\"html\",l);CKEDITOR.dialog.addUIElement(\"fieldset\",{build:function(b,a,d){for(var e=a.children,c,f=[],h=[],g=0;g<e.length&&(c=e[g]);g++){var i=[];f.push(i);h.push(CKEDITOR.dialog._.uiElementBuilders[c.type].build(b,c,i))}return new CKEDITOR.ui.dialog[a.type](b,\nh,f,d,a)}})}});CKEDITOR.DIALOG_RESIZE_NONE=0;CKEDITOR.DIALOG_RESIZE_WIDTH=1;CKEDITOR.DIALOG_RESIZE_HEIGHT=2;CKEDITOR.DIALOG_RESIZE_BOTH=3;\n(function(){function t(){for(var a=this._.tabIdList.length,b=CKEDITOR.tools.indexOf(this._.tabIdList,this._.currentTabId)+a,c=b-1;c>b-a;c--)if(this._.tabs[this._.tabIdList[c%a]][0].$.offsetHeight)return this._.tabIdList[c%a];return null}function u(){for(var a=this._.tabIdList.length,b=CKEDITOR.tools.indexOf(this._.tabIdList,this._.currentTabId),c=b+1;c<b+a;c++)if(this._.tabs[this._.tabIdList[c%a]][0].$.offsetHeight)return this._.tabIdList[c%a];return null}function G(a,b){for(var c=a.$.getElementsByTagName(\"input\"),\ne=0,d=c.length;e<d;e++){var g=new CKEDITOR.dom.element(c[e]);\"text\"==g.getAttribute(\"type\").toLowerCase()&&(b?(g.setAttribute(\"value\",g.getCustomData(\"fake_value\")||\"\"),g.removeCustomData(\"fake_value\")):(g.setCustomData(\"fake_value\",g.getAttribute(\"value\")),g.setAttribute(\"value\",\"\")))}}function P(a,b){var c=this.getInputElement();c&&(a?c.removeAttribute(\"aria-invalid\"):c.setAttribute(\"aria-invalid\",!0));a||(this.select?this.select():this.focus());b&&alert(b);this.fire(\"validated\",{valid:a,msg:b})}\nfunction Q(){var a=this.getInputElement();a&&a.removeAttribute(\"aria-invalid\")}function R(a){var a=CKEDITOR.dom.element.createFromHtml(CKEDITOR.addTemplate(\"dialog\",S).output({id:CKEDITOR.tools.getNextNumber(),editorId:a.id,langDir:a.lang.dir,langCode:a.langCode,editorDialogClass:\"cke_editor_\"+a.name.replace(/\\./g,\"\\\\.\")+\"_dialog\",closeTitle:a.lang.common.close,hidpi:CKEDITOR.env.hidpi?\"cke_hidpi\":\"\"})),b=a.getChild([0,0,0,0,0]),c=b.getChild(0),e=b.getChild(1);if(CKEDITOR.env.ie&&!CKEDITOR.env.ie6Compat){var d=\n\"javascript:void(function(){\"+encodeURIComponent(\"document.open();(\"+CKEDITOR.tools.fixDomain+\")();document.close();\")+\"}())\";CKEDITOR.dom.element.createFromHtml('<iframe frameBorder=\"0\" class=\"cke_iframe_shim\" src=\"'+d+'\" tabIndex=\"-1\"></iframe>').appendTo(b.getParent())}c.unselectable();e.unselectable();return{element:a,parts:{dialog:a.getChild(0),title:c,close:e,tabs:b.getChild(2),contents:b.getChild([3,0,0,0]),footer:b.getChild([3,0,1,0])}}}function H(a,b,c){this.element=b;this.focusIndex=c;this.tabIndex=\n0;this.isFocusable=function(){return!b.getAttribute(\"disabled\")&&b.isVisible()};this.focus=function(){a._.currentFocusIndex=this.focusIndex;this.element.focus()};b.on(\"keydown\",function(a){a.data.getKeystroke()in{32:1,13:1}&&this.fire(\"click\")});b.on(\"focus\",function(){this.fire(\"mouseover\")});b.on(\"blur\",function(){this.fire(\"mouseout\")})}function T(a){function b(){a.layout()}var c=CKEDITOR.document.getWindow();c.on(\"resize\",b);a.on(\"hide\",function(){c.removeListener(\"resize\",b)})}function I(a,b){this._=\n{dialog:a};CKEDITOR.tools.extend(this,b)}function U(a){function b(b){var c=a.getSize(),h=CKEDITOR.document.getWindow().getViewPaneSize(),o=b.data.$.screenX,j=b.data.$.screenY,n=o-e.x,m=j-e.y;e={x:o,y:j};d.x+=n;d.y+=m;a.move(d.x+i[3]<f?-i[3]:d.x-i[1]>h.width-c.width-f?h.width-c.width+(\"rtl\"==g.lang.dir?0:i[1]):d.x,d.y+i[0]<f?-i[0]:d.y-i[2]>h.height-c.height-f?h.height-c.height+i[2]:d.y,1);b.data.preventDefault()}function c(){CKEDITOR.document.removeListener(\"mousemove\",b);CKEDITOR.document.removeListener(\"mouseup\",\nc);if(CKEDITOR.env.ie6Compat){var a=q.getChild(0).getFrameDocument();a.removeListener(\"mousemove\",b);a.removeListener(\"mouseup\",c)}}var e=null,d=null;a.getElement().getFirst();var g=a.getParentEditor(),f=g.config.dialog_magnetDistance,i=CKEDITOR.skin.margins||[0,0,0,0];\"undefined\"==typeof f&&(f=20);a.parts.title.on(\"mousedown\",function(f){e={x:f.data.$.screenX,y:f.data.$.screenY};CKEDITOR.document.on(\"mousemove\",b);CKEDITOR.document.on(\"mouseup\",c);d=a.getPosition();if(CKEDITOR.env.ie6Compat){var k=\nq.getChild(0).getFrameDocument();k.on(\"mousemove\",b);k.on(\"mouseup\",c)}f.data.preventDefault()},a)}function V(a){var b,c;function e(d){var e=\"rtl\"==i.lang.dir,j=o.width,C=o.height,D=j+(d.data.$.screenX-b)*(e?-1:1)*(a._.moved?1:2),n=C+(d.data.$.screenY-c)*(a._.moved?1:2),x=a._.element.getFirst(),x=e&&x.getComputedStyle(\"right\"),y=a.getPosition();y.y+n>h.height&&(n=h.height-y.y);if((e?x:y.x)+D>h.width)D=h.width-(e?x:y.x);if(f==CKEDITOR.DIALOG_RESIZE_WIDTH||f==CKEDITOR.DIALOG_RESIZE_BOTH)j=Math.max(g.minWidth||\n0,D-l);if(f==CKEDITOR.DIALOG_RESIZE_HEIGHT||f==CKEDITOR.DIALOG_RESIZE_BOTH)C=Math.max(g.minHeight||0,n-k);a.resize(j,C);a._.moved||a.layout();d.data.preventDefault()}function d(){CKEDITOR.document.removeListener(\"mouseup\",d);CKEDITOR.document.removeListener(\"mousemove\",e);j&&(j.remove(),j=null);if(CKEDITOR.env.ie6Compat){var a=q.getChild(0).getFrameDocument();a.removeListener(\"mouseup\",d);a.removeListener(\"mousemove\",e)}}var g=a.definition,f=g.resizable;if(f!=CKEDITOR.DIALOG_RESIZE_NONE){var i=a.getParentEditor(),\nl,k,h,o,j,n=CKEDITOR.tools.addFunction(function(f){o=a.getSize();var g=a.parts.contents;g.$.getElementsByTagName(\"iframe\").length&&(j=CKEDITOR.dom.element.createFromHtml('<div class=\"cke_dialog_resize_cover\" style=\"height: 100%; position: absolute; width: 100%;\"></div>'),g.append(j));k=o.height-a.parts.contents.getSize(\"height\",!(CKEDITOR.env.gecko||CKEDITOR.env.opera||CKEDITOR.env.ie&&CKEDITOR.env.quirks));l=o.width-a.parts.contents.getSize(\"width\",1);b=f.screenX;c=f.screenY;h=CKEDITOR.document.getWindow().getViewPaneSize();\nCKEDITOR.document.on(\"mousemove\",e);CKEDITOR.document.on(\"mouseup\",d);CKEDITOR.env.ie6Compat&&(g=q.getChild(0).getFrameDocument(),g.on(\"mousemove\",e),g.on(\"mouseup\",d));f.preventDefault&&f.preventDefault()});a.on(\"load\",function(){var b=\"\";f==CKEDITOR.DIALOG_RESIZE_WIDTH?b=\" cke_resizer_horizontal\":f==CKEDITOR.DIALOG_RESIZE_HEIGHT&&(b=\" cke_resizer_vertical\");b=CKEDITOR.dom.element.createFromHtml('<div class=\"cke_resizer'+b+\" cke_resizer_\"+i.lang.dir+'\" title=\"'+CKEDITOR.tools.htmlEncode(i.lang.common.resize)+\n'\" onmousedown=\"CKEDITOR.tools.callFunction('+n+', event )\">'+(\"ltr\"==i.lang.dir?\"◢\":\"◣\")+\"</div>\");a.parts.footer.append(b,1)});i.on(\"destroy\",function(){CKEDITOR.tools.removeFunction(n)})}}function E(a){a.data.preventDefault(1)}function J(a){var b=CKEDITOR.document.getWindow(),c=a.config,e=c.dialog_backgroundCoverColor||\"white\",d=c.dialog_backgroundCoverOpacity,g=c.baseFloatZIndex,c=CKEDITOR.tools.genKey(e,d,g),f=w[c];f?f.show():(g=['<div tabIndex=\"-1\" style=\"position: ',CKEDITOR.env.ie6Compat?\n\"absolute\":\"fixed\",\"; z-index: \",g,\"; top: 0px; left: 0px; \",!CKEDITOR.env.ie6Compat?\"background-color: \"+e:\"\",'\" class=\"cke_dialog_background_cover\">'],CKEDITOR.env.ie6Compat&&(e=\"<html><body style=\\\\'background-color:\"+e+\";\\\\'></body></html>\",g.push('<iframe hidefocus=\"true\" frameborder=\"0\" id=\"cke_dialog_background_iframe\" src=\"javascript:'),g.push(\"void((function(){\"+encodeURIComponent(\"document.open();(\"+CKEDITOR.tools.fixDomain+\")();document.write( '\"+e+\"' );document.close();\")+\"})())\"),g.push('\" style=\"position:absolute;left:0;top:0;width:100%;height: 100%;filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0)\"></iframe>')),\ng.push(\"</div>\"),f=CKEDITOR.dom.element.createFromHtml(g.join(\"\")),f.setOpacity(void 0!=d?d:0.5),f.on(\"keydown\",E),f.on(\"keypress\",E),f.on(\"keyup\",E),f.appendTo(CKEDITOR.document.getBody()),w[c]=f);a.focusManager.add(f);q=f;var a=function(){var a=b.getViewPaneSize();f.setStyles({width:a.width+\"px\",height:a.height+\"px\"})},i=function(){var a=b.getScrollPosition(),c=CKEDITOR.dialog._.currentTop;f.setStyles({left:a.x+\"px\",top:a.y+\"px\"});if(c){do{a=c.getPosition();c.move(a.x,a.y)}while(c=c._.parentDialog)\n}};F=a;b.on(\"resize\",a);a();(!CKEDITOR.env.mac||!CKEDITOR.env.webkit)&&f.focus();if(CKEDITOR.env.ie6Compat){var l=function(){i();arguments.callee.prevScrollHandler.apply(this,arguments)};b.$.setTimeout(function(){l.prevScrollHandler=window.onscroll||function(){};window.onscroll=l},0);i()}}function K(a){q&&(a.focusManager.remove(q),a=CKEDITOR.document.getWindow(),q.hide(),a.removeListener(\"resize\",F),CKEDITOR.env.ie6Compat&&a.$.setTimeout(function(){window.onscroll=window.onscroll&&window.onscroll.prevScrollHandler||\nnull},0),F=null)}var r=CKEDITOR.tools.cssLength,S='<div class=\"cke_reset_all {editorId} {editorDialogClass} {hidpi}\" dir=\"{langDir}\" lang=\"{langCode}\" role=\"dialog\" aria-labelledby=\"cke_dialog_title_{id}\"><table class=\"cke_dialog '+CKEDITOR.env.cssClass+' cke_{langDir}\" style=\"position:absolute\" role=\"presentation\"><tr><td role=\"presentation\"><div class=\"cke_dialog_body\" role=\"presentation\"><div id=\"cke_dialog_title_{id}\" class=\"cke_dialog_title\" role=\"presentation\"></div><a id=\"cke_dialog_close_button_{id}\" class=\"cke_dialog_close_button\" href=\"javascript:void(0)\" title=\"{closeTitle}\" role=\"button\"><span class=\"cke_label\">X</span></a><div id=\"cke_dialog_tabs_{id}\" class=\"cke_dialog_tabs\" role=\"tablist\"></div><table class=\"cke_dialog_contents\" role=\"presentation\"><tr><td id=\"cke_dialog_contents_{id}\" class=\"cke_dialog_contents_body\" role=\"presentation\"></td></tr><tr><td id=\"cke_dialog_footer_{id}\" class=\"cke_dialog_footer\" role=\"presentation\"></td></tr></table></div></td></tr></table></div>';\nCKEDITOR.dialog=function(a,b){function c(){var a=m._.focusList;a.sort(function(a,b){return a.tabIndex!=b.tabIndex?b.tabIndex-a.tabIndex:a.focusIndex-b.focusIndex});for(var b=a.length,c=0;c<b;c++)a[c].focusIndex=c}function e(a){var b=m._.focusList,a=a||0;if(!(1>b.length)){var c=m._.currentFocusIndex;try{b[c].getInputElement().$.blur()}catch(f){}for(var d=c=(c+a+b.length)%b.length;a&&!b[d].isFocusable()&&!(d=(d+a+b.length)%b.length,d==c););b[d].focus();\"text\"==b[d].type&&b[d].select()}}function d(b){if(m==\nCKEDITOR.dialog._.currentTop){var c=b.data.getKeystroke(),d=\"rtl\"==a.lang.dir;o=j=0;if(9==c||c==CKEDITOR.SHIFT+9)c=c==CKEDITOR.SHIFT+9,m._.tabBarMode?(c=c?t.call(m):u.call(m),m.selectPage(c),m._.tabs[c][0].focus()):e(c?-1:1),o=1;else if(c==CKEDITOR.ALT+121&&!m._.tabBarMode&&1<m.getPageCount())m._.tabBarMode=!0,m._.tabs[m._.currentTabId][0].focus(),o=1;else if((37==c||39==c)&&m._.tabBarMode)c=c==(d?39:37)?t.call(m):u.call(m),m.selectPage(c),m._.tabs[c][0].focus(),o=1;else if((13==c||32==c)&&m._.tabBarMode)this.selectPage(this._.currentTabId),\nthis._.tabBarMode=!1,this._.currentFocusIndex=-1,e(1),o=1;else if(13==c){c=b.data.getTarget();if(!c.is(\"a\",\"button\",\"select\",\"textarea\")&&(!c.is(\"input\")||\"button\"!=c.$.type))(c=this.getButton(\"ok\"))&&CKEDITOR.tools.setTimeout(c.click,0,c),o=1;j=1}else if(27==c)(c=this.getButton(\"cancel\"))?CKEDITOR.tools.setTimeout(c.click,0,c):!1!==this.fire(\"cancel\",{hide:!0}).hide&&this.hide(),j=1;else return;g(b)}}function g(a){o?a.data.preventDefault(1):j&&a.data.stopPropagation()}var f=CKEDITOR.dialog._.dialogDefinitions[b],\ni=CKEDITOR.tools.clone(W),l=a.config.dialog_buttonsOrder||\"OS\",k=a.lang.dir,h={},o,j;(\"OS\"==l&&CKEDITOR.env.mac||\"rtl\"==l&&\"ltr\"==k||\"ltr\"==l&&\"rtl\"==k)&&i.buttons.reverse();f=CKEDITOR.tools.extend(f(a),i);f=CKEDITOR.tools.clone(f);f=new L(this,f);i=R(a);this._={editor:a,element:i.element,name:b,contentSize:{width:0,height:0},size:{width:0,height:0},contents:{},buttons:{},accessKeyMap:{},tabs:{},tabIdList:[],currentTabId:null,currentTabIndex:null,pageCount:0,lastTab:null,tabBarMode:!1,focusList:[],\ncurrentFocusIndex:0,hasFocus:!1};this.parts=i.parts;CKEDITOR.tools.setTimeout(function(){a.fire(\"ariaWidget\",this.parts.contents)},0,this);i={position:CKEDITOR.env.ie6Compat?\"absolute\":\"fixed\",top:0,visibility:\"hidden\"};i[\"rtl\"==k?\"right\":\"left\"]=0;this.parts.dialog.setStyles(i);CKEDITOR.event.call(this);this.definition=f=CKEDITOR.fire(\"dialogDefinition\",{name:b,definition:f},a).definition;if(!(\"removeDialogTabs\"in a._)&&a.config.removeDialogTabs){i=a.config.removeDialogTabs.split(\";\");for(k=0;k<\ni.length;k++)if(l=i[k].split(\":\"),2==l.length){var n=l[0];h[n]||(h[n]=[]);h[n].push(l[1])}a._.removeDialogTabs=h}if(a._.removeDialogTabs&&(h=a._.removeDialogTabs[b]))for(k=0;k<h.length;k++)f.removeContents(h[k]);if(f.onLoad)this.on(\"load\",f.onLoad);if(f.onShow)this.on(\"show\",f.onShow);if(f.onHide)this.on(\"hide\",f.onHide);if(f.onOk)this.on(\"ok\",function(b){a.fire(\"saveSnapshot\");setTimeout(function(){a.fire(\"saveSnapshot\")},0);!1===f.onOk.call(this,b)&&(b.data.hide=!1)});if(f.onCancel)this.on(\"cancel\",\nfunction(a){!1===f.onCancel.call(this,a)&&(a.data.hide=!1)});var m=this,p=function(a){var b=m._.contents,c=!1,d;for(d in b)for(var f in b[d])if(c=a.call(this,b[d][f]))return};this.on(\"ok\",function(a){p(function(b){if(b.validate){var c=b.validate(this),d=\"string\"==typeof c||!1===c;d&&(a.data.hide=!1,a.stop());P.call(b,!d,\"string\"==typeof c?c:void 0);return d}})},this,null,0);this.on(\"cancel\",function(b){p(function(c){if(c.isChanged())return!a.config.dialog_noConfirmCancel&&!confirm(a.lang.common.confirmCancel)&&\n(b.data.hide=!1),!0})},this,null,0);this.parts.close.on(\"click\",function(a){!1!==this.fire(\"cancel\",{hide:!0}).hide&&this.hide();a.data.preventDefault()},this);this.changeFocus=e;var v=this._.element;a.focusManager.add(v,1);this.on(\"show\",function(){v.on(\"keydown\",d,this);if(CKEDITOR.env.opera||CKEDITOR.env.gecko)v.on(\"keypress\",g,this)});this.on(\"hide\",function(){v.removeListener(\"keydown\",d);(CKEDITOR.env.opera||CKEDITOR.env.gecko)&&v.removeListener(\"keypress\",g);p(function(a){Q.apply(a)})});this.on(\"iframeAdded\",\nfunction(a){(new CKEDITOR.dom.document(a.data.iframe.$.contentWindow.document)).on(\"keydown\",d,this,null,0)});this.on(\"show\",function(){c();if(a.config.dialog_startupFocusTab&&1<m._.pageCount)m._.tabBarMode=!0,m._.tabs[m._.currentTabId][0].focus();else if(!this._.hasFocus)if(this._.currentFocusIndex=-1,f.onFocus){var b=f.onFocus.call(this);b&&b.focus()}else e(1)},this,null,4294967295);if(CKEDITOR.env.ie6Compat)this.on(\"load\",function(){var a=this.getElement(),b=a.getFirst();b.remove();b.appendTo(a)},\nthis);U(this);V(this);(new CKEDITOR.dom.text(f.title,CKEDITOR.document)).appendTo(this.parts.title);for(k=0;k<f.contents.length;k++)(h=f.contents[k])&&this.addPage(h);this.parts.tabs.on(\"click\",function(a){var b=a.data.getTarget();b.hasClass(\"cke_dialog_tab\")&&(b=b.$.id,this.selectPage(b.substring(4,b.lastIndexOf(\"_\"))),this._.tabBarMode&&(this._.tabBarMode=!1,this._.currentFocusIndex=-1,e(1)),a.data.preventDefault())},this);k=[];h=CKEDITOR.dialog._.uiElementBuilders.hbox.build(this,{type:\"hbox\",\nclassName:\"cke_dialog_footer_buttons\",widths:[],children:f.buttons},k).getChild();this.parts.footer.setHtml(k.join(\"\"));for(k=0;k<h.length;k++)this._.buttons[h[k].id]=h[k]};CKEDITOR.dialog.prototype={destroy:function(){this.hide();this._.element.remove()},resize:function(){return function(a,b){if(!this._.contentSize||!(this._.contentSize.width==a&&this._.contentSize.height==b))CKEDITOR.dialog.fire(\"resize\",{dialog:this,width:a,height:b},this._.editor),this.fire(\"resize\",{width:a,height:b},this._.editor),\nthis.parts.contents.setStyles({width:a+\"px\",height:b+\"px\"}),\"rtl\"==this._.editor.lang.dir&&this._.position&&(this._.position.x=CKEDITOR.document.getWindow().getViewPaneSize().width-this._.contentSize.width-parseInt(this._.element.getFirst().getStyle(\"right\"),10)),this._.contentSize={width:a,height:b}}}(),getSize:function(){var a=this._.element.getFirst();return{width:a.$.offsetWidth||0,height:a.$.offsetHeight||0}},move:function(a,b,c){var e=this._.element.getFirst(),d=\"rtl\"==this._.editor.lang.dir,\ng=\"fixed\"==e.getComputedStyle(\"position\");CKEDITOR.env.ie&&e.setStyle(\"zoom\",\"100%\");if(!g||!this._.position||!(this._.position.x==a&&this._.position.y==b))this._.position={x:a,y:b},g||(g=CKEDITOR.document.getWindow().getScrollPosition(),a+=g.x,b+=g.y),d&&(g=this.getSize(),a=CKEDITOR.document.getWindow().getViewPaneSize().width-g.width-a),b={top:(0<b?b:0)+\"px\"},b[d?\"right\":\"left\"]=(0<a?a:0)+\"px\",e.setStyles(b),c&&(this._.moved=1)},getPosition:function(){return CKEDITOR.tools.extend({},this._.position)},\nshow:function(){var a=this._.element,b=this.definition;!a.getParent()||!a.getParent().equals(CKEDITOR.document.getBody())?a.appendTo(CKEDITOR.document.getBody()):a.setStyle(\"display\",\"block\");if(CKEDITOR.env.gecko&&10900>CKEDITOR.env.version){var c=this.parts.dialog;c.setStyle(\"position\",\"absolute\");setTimeout(function(){c.setStyle(\"position\",\"fixed\")},0)}this.resize(this._.contentSize&&this._.contentSize.width||b.width||b.minWidth,this._.contentSize&&this._.contentSize.height||b.height||b.minHeight);\nthis.reset();this.selectPage(this.definition.contents[0].id);null===CKEDITOR.dialog._.currentZIndex&&(CKEDITOR.dialog._.currentZIndex=this._.editor.config.baseFloatZIndex);this._.element.getFirst().setStyle(\"z-index\",CKEDITOR.dialog._.currentZIndex+=10);null===CKEDITOR.dialog._.currentTop?(CKEDITOR.dialog._.currentTop=this,this._.parentDialog=null,J(this._.editor)):(this._.parentDialog=CKEDITOR.dialog._.currentTop,this._.parentDialog.getElement().getFirst().$.style.zIndex-=Math.floor(this._.editor.config.baseFloatZIndex/\n2),CKEDITOR.dialog._.currentTop=this);a.on(\"keydown\",M);a.on(CKEDITOR.env.opera?\"keypress\":\"keyup\",N);this._.hasFocus=!1;for(var e in b.contents)if(b.contents[e]){var a=b.contents[e],d=this._.tabs[a.id],g=a.requiredContent,f=0;if(d){for(var i in this._.contents[a.id]){var l=this._.contents[a.id][i];\"hbox\"==l.type||(\"vbox\"==l.type||!l.getInputElement())||(l.requiredContent&&!this._.editor.activeFilter.check(l.requiredContent)?l.disable():(l.enable(),f++))}!f||g&&!this._.editor.activeFilter.check(g)?\nd[0].addClass(\"cke_dialog_tab_disabled\"):d[0].removeClass(\"cke_dialog_tab_disabled\")}}CKEDITOR.tools.setTimeout(function(){this.layout();T(this);this.parts.dialog.setStyle(\"visibility\",\"\");this.fireOnce(\"load\",{});CKEDITOR.ui.fire(\"ready\",this);this.fire(\"show\",{});this._.editor.fire(\"dialogShow\",this);this._.parentDialog||this._.editor.focusManager.lock();this.foreach(function(a){a.setInitValue&&a.setInitValue()})},100,this)},layout:function(){var a=this.parts.dialog,b=this.getSize(),c=CKEDITOR.document.getWindow().getViewPaneSize(),\ne=(c.width-b.width)/2,d=(c.height-b.height)/2;CKEDITOR.env.ie6Compat||(b.height+(0<d?d:0)>c.height||b.width+(0<e?e:0)>c.width?a.setStyle(\"position\",\"absolute\"):a.setStyle(\"position\",\"fixed\"));this.move(this._.moved?this._.position.x:e,this._.moved?this._.position.y:d)},foreach:function(a){for(var b in this._.contents)for(var c in this._.contents[b])a.call(this,this._.contents[b][c]);return this},reset:function(){var a=function(a){a.reset&&a.reset(1)};return function(){this.foreach(a);return this}}(),\nsetupContent:function(){var a=arguments;this.foreach(function(b){b.setup&&b.setup.apply(b,a)})},commitContent:function(){var a=arguments;this.foreach(function(b){CKEDITOR.env.ie&&this._.currentFocusIndex==b.focusIndex&&b.getInputElement().$.blur();b.commit&&b.commit.apply(b,a)})},hide:function(){if(this.parts.dialog.isVisible()){this.fire(\"hide\",{});this._.editor.fire(\"dialogHide\",this);this.selectPage(this._.tabIdList[0]);var a=this._.element;a.setStyle(\"display\",\"none\");this.parts.dialog.setStyle(\"visibility\",\n\"hidden\");for(X(this);CKEDITOR.dialog._.currentTop!=this;)CKEDITOR.dialog._.currentTop.hide();if(this._.parentDialog){var b=this._.parentDialog.getElement().getFirst();b.setStyle(\"z-index\",parseInt(b.$.style.zIndex,10)+Math.floor(this._.editor.config.baseFloatZIndex/2))}else K(this._.editor);if(CKEDITOR.dialog._.currentTop=this._.parentDialog)CKEDITOR.dialog._.currentZIndex-=10;else{CKEDITOR.dialog._.currentZIndex=null;a.removeListener(\"keydown\",M);a.removeListener(CKEDITOR.env.opera?\"keypress\":\"keyup\",\nN);var c=this._.editor;c.focus();setTimeout(function(){c.focusManager.unlock()},0)}delete this._.parentDialog;this.foreach(function(a){a.resetInitValue&&a.resetInitValue()})}},addPage:function(a){if(!a.requiredContent||this._.editor.filter.check(a.requiredContent)){for(var b=[],c=a.label?' title=\"'+CKEDITOR.tools.htmlEncode(a.label)+'\"':\"\",e=CKEDITOR.dialog._.uiElementBuilders.vbox.build(this,{type:\"vbox\",className:\"cke_dialog_page_contents\",children:a.elements,expand:!!a.expand,padding:a.padding,\nstyle:a.style||\"width: 100%;\"},b),d=this._.contents[a.id]={},g=e.getChild(),f=0;e=g.shift();)!e.notAllowed&&(\"hbox\"!=e.type&&\"vbox\"!=e.type)&&f++,d[e.id]=e,\"function\"==typeof e.getChild&&g.push.apply(g,e.getChild());f||(a.hidden=!0);b=CKEDITOR.dom.element.createFromHtml(b.join(\"\"));b.setAttribute(\"role\",\"tabpanel\");e=CKEDITOR.env;d=\"cke_\"+a.id+\"_\"+CKEDITOR.tools.getNextNumber();c=CKEDITOR.dom.element.createFromHtml(['<a class=\"cke_dialog_tab\"',0<this._.pageCount?\" cke_last\":\"cke_first\",c,a.hidden?\n' style=\"display:none\"':\"\",' id=\"',d,'\"',e.gecko&&10900<=e.version&&!e.hc?\"\":' href=\"javascript:void(0)\"',' tabIndex=\"-1\" hidefocus=\"true\" role=\"tab\">',a.label,\"</a>\"].join(\"\"));b.setAttribute(\"aria-labelledby\",d);this._.tabs[a.id]=[c,b];this._.tabIdList.push(a.id);!a.hidden&&this._.pageCount++;this._.lastTab=c;this.updateStyle();b.setAttribute(\"name\",a.id);b.appendTo(this.parts.contents);c.unselectable();this.parts.tabs.append(c);a.accessKey&&(O(this,this,\"CTRL+\"+a.accessKey,Y,Z),this._.accessKeyMap[\"CTRL+\"+\na.accessKey]=a.id)}},selectPage:function(a){if(this._.currentTabId!=a&&!this._.tabs[a][0].hasClass(\"cke_dialog_tab_disabled\")&&!0!==this.fire(\"selectPage\",{page:a,currentPage:this._.currentTabId})){for(var b in this._.tabs){var c=this._.tabs[b][0],e=this._.tabs[b][1];b!=a&&(c.removeClass(\"cke_dialog_tab_selected\"),e.hide());e.setAttribute(\"aria-hidden\",b!=a)}var d=this._.tabs[a];d[0].addClass(\"cke_dialog_tab_selected\");CKEDITOR.env.ie6Compat||CKEDITOR.env.ie7Compat?(G(d[1]),d[1].show(),setTimeout(function(){G(d[1],\n1)},0)):d[1].show();this._.currentTabId=a;this._.currentTabIndex=CKEDITOR.tools.indexOf(this._.tabIdList,a)}},updateStyle:function(){this.parts.dialog[(1===this._.pageCount?\"add\":\"remove\")+\"Class\"](\"cke_single_page\")},hidePage:function(a){var b=this._.tabs[a]&&this._.tabs[a][0];b&&(1!=this._.pageCount&&b.isVisible())&&(a==this._.currentTabId&&this.selectPage(t.call(this)),b.hide(),this._.pageCount--,this.updateStyle())},showPage:function(a){if(a=this._.tabs[a]&&this._.tabs[a][0])a.show(),this._.pageCount++,\nthis.updateStyle()},getElement:function(){return this._.element},getName:function(){return this._.name},getContentElement:function(a,b){var c=this._.contents[a];return c&&c[b]},getValueOf:function(a,b){return this.getContentElement(a,b).getValue()},setValueOf:function(a,b,c){return this.getContentElement(a,b).setValue(c)},getButton:function(a){return this._.buttons[a]},click:function(a){return this._.buttons[a].click()},disableButton:function(a){return this._.buttons[a].disable()},enableButton:function(a){return this._.buttons[a].enable()},\ngetPageCount:function(){return this._.pageCount},getParentEditor:function(){return this._.editor},getSelectedElement:function(){return this.getParentEditor().getSelection().getSelectedElement()},addFocusable:function(a,b){if(\"undefined\"==typeof b)b=this._.focusList.length,this._.focusList.push(new H(this,a,b));else{this._.focusList.splice(b,0,new H(this,a,b));for(var c=b+1;c<this._.focusList.length;c++)this._.focusList[c].focusIndex++}}};CKEDITOR.tools.extend(CKEDITOR.dialog,{add:function(a,b){if(!this._.dialogDefinitions[a]||\n\"function\"==typeof b)this._.dialogDefinitions[a]=b},exists:function(a){return!!this._.dialogDefinitions[a]},getCurrent:function(){return CKEDITOR.dialog._.currentTop},isTabEnabled:function(a,b,c){a=a.config.removeDialogTabs;return!(a&&a.match(RegExp(\"(?:^|;)\"+b+\":\"+c+\"(?:$|;)\",\"i\")))},okButton:function(){var a=function(a,c){c=c||{};return CKEDITOR.tools.extend({id:\"ok\",type:\"button\",label:a.lang.common.ok,\"class\":\"cke_dialog_ui_button_ok\",onClick:function(a){a=a.data.dialog;!1!==a.fire(\"ok\",{hide:!0}).hide&&\na.hide()}},c,!0)};a.type=\"button\";a.override=function(b){return CKEDITOR.tools.extend(function(c){return a(c,b)},{type:\"button\"},!0)};return a}(),cancelButton:function(){var a=function(a,c){c=c||{};return CKEDITOR.tools.extend({id:\"cancel\",type:\"button\",label:a.lang.common.cancel,\"class\":\"cke_dialog_ui_button_cancel\",onClick:function(a){a=a.data.dialog;!1!==a.fire(\"cancel\",{hide:!0}).hide&&a.hide()}},c,!0)};a.type=\"button\";a.override=function(b){return CKEDITOR.tools.extend(function(c){return a(c,\nb)},{type:\"button\"},!0)};return a}(),addUIElement:function(a,b){this._.uiElementBuilders[a]=b}});CKEDITOR.dialog._={uiElementBuilders:{},dialogDefinitions:{},currentTop:null,currentZIndex:null};CKEDITOR.event.implementOn(CKEDITOR.dialog);CKEDITOR.event.implementOn(CKEDITOR.dialog.prototype);var W={resizable:CKEDITOR.DIALOG_RESIZE_BOTH,minWidth:600,minHeight:400,buttons:[CKEDITOR.dialog.okButton,CKEDITOR.dialog.cancelButton]},z=function(a,b,c){for(var e=0,d;d=a[e];e++)if(d.id==b||c&&d[c]&&(d=z(d[c],\nb,c)))return d;return null},A=function(a,b,c,e,d){if(c){for(var g=0,f;f=a[g];g++){if(f.id==c)return a.splice(g,0,b),b;if(e&&f[e]&&(f=A(f[e],b,c,e,!0)))return f}if(d)return null}a.push(b);return b},B=function(a,b,c){for(var e=0,d;d=a[e];e++){if(d.id==b)return a.splice(e,1);if(c&&d[c]&&(d=B(d[c],b,c)))return d}return null},L=function(a,b){this.dialog=a;for(var c=b.contents,e=0,d;d=c[e];e++)c[e]=d&&new I(a,d);CKEDITOR.tools.extend(this,b)};L.prototype={getContents:function(a){return z(this.contents,\na)},getButton:function(a){return z(this.buttons,a)},addContents:function(a,b){return A(this.contents,a,b)},addButton:function(a,b){return A(this.buttons,a,b)},removeContents:function(a){B(this.contents,a)},removeButton:function(a){B(this.buttons,a)}};I.prototype={get:function(a){return z(this.elements,a,\"children\")},add:function(a,b){return A(this.elements,a,b,\"children\")},remove:function(a){B(this.elements,a,\"children\")}};var F,w={},q,s={},M=function(a){var b=a.data.$.ctrlKey||a.data.$.metaKey,c=\na.data.$.altKey,e=a.data.$.shiftKey,d=String.fromCharCode(a.data.$.keyCode);if((b=s[(b?\"CTRL+\":\"\")+(c?\"ALT+\":\"\")+(e?\"SHIFT+\":\"\")+d])&&b.length)b=b[b.length-1],b.keydown&&b.keydown.call(b.uiElement,b.dialog,b.key),a.data.preventDefault()},N=function(a){var b=a.data.$.ctrlKey||a.data.$.metaKey,c=a.data.$.altKey,e=a.data.$.shiftKey,d=String.fromCharCode(a.data.$.keyCode);if((b=s[(b?\"CTRL+\":\"\")+(c?\"ALT+\":\"\")+(e?\"SHIFT+\":\"\")+d])&&b.length)b=b[b.length-1],b.keyup&&(b.keyup.call(b.uiElement,b.dialog,b.key),\na.data.preventDefault())},O=function(a,b,c,e,d){(s[c]||(s[c]=[])).push({uiElement:a,dialog:b,key:c,keyup:d||a.accessKeyUp,keydown:e||a.accessKeyDown})},X=function(a){for(var b in s){for(var c=s[b],e=c.length-1;0<=e;e--)(c[e].dialog==a||c[e].uiElement==a)&&c.splice(e,1);0===c.length&&delete s[b]}},Z=function(a,b){a._.accessKeyMap[b]&&a.selectPage(a._.accessKeyMap[b])},Y=function(){};(function(){CKEDITOR.ui.dialog={uiElement:function(a,b,c,e,d,g,f){if(!(4>arguments.length)){var i=(e.call?e(b):e)||\"div\",\nl=[\"<\",i,\" \"],k=(d&&d.call?d(b):d)||{},h=(g&&g.call?g(b):g)||{},o=(f&&f.call?f.call(this,a,b):f)||\"\",j=this.domId=h.id||CKEDITOR.tools.getNextId()+\"_uiElement\";this.id=b.id;b.requiredContent&&!a.getParentEditor().filter.check(b.requiredContent)&&(k.display=\"none\",this.notAllowed=!0);h.id=j;var n={};b.type&&(n[\"cke_dialog_ui_\"+b.type]=1);b.className&&(n[b.className]=1);b.disabled&&(n.cke_disabled=1);for(var m=h[\"class\"]&&h[\"class\"].split?h[\"class\"].split(\" \"):[],j=0;j<m.length;j++)m[j]&&(n[m[j]]=1);\nm=[];for(j in n)m.push(j);h[\"class\"]=m.join(\" \");b.title&&(h.title=b.title);n=(b.style||\"\").split(\";\");b.align&&(m=b.align,k[\"margin-left\"]=\"left\"==m?0:\"auto\",k[\"margin-right\"]=\"right\"==m?0:\"auto\");for(j in k)n.push(j+\":\"+k[j]);b.hidden&&n.push(\"display:none\");for(j=n.length-1;0<=j;j--)\"\"===n[j]&&n.splice(j,1);0<n.length&&(h.style=(h.style?h.style+\"; \":\"\")+n.join(\"; \"));for(j in h)l.push(j+'=\"'+CKEDITOR.tools.htmlEncode(h[j])+'\" ');l.push(\">\",o,\"</\",i,\">\");c.push(l.join(\"\"));(this._||(this._={})).dialog=\na;\"boolean\"==typeof b.isChanged&&(this.isChanged=function(){return b.isChanged});\"function\"==typeof b.isChanged&&(this.isChanged=b.isChanged);\"function\"==typeof b.setValue&&(this.setValue=CKEDITOR.tools.override(this.setValue,function(a){return function(c){a.call(this,b.setValue.call(this,c))}}));\"function\"==typeof b.getValue&&(this.getValue=CKEDITOR.tools.override(this.getValue,function(a){return function(){return b.getValue.call(this,a.call(this))}}));CKEDITOR.event.implementOn(this);this.registerEvents(b);\nthis.accessKeyUp&&(this.accessKeyDown&&b.accessKey)&&O(this,a,\"CTRL+\"+b.accessKey);var p=this;a.on(\"load\",function(){var b=p.getInputElement();if(b){var c=p.type in{checkbox:1,ratio:1}&&CKEDITOR.env.ie&&CKEDITOR.env.version<8?\"cke_dialog_ui_focused\":\"\";b.on(\"focus\",function(){a._.tabBarMode=false;a._.hasFocus=true;p.fire(\"focus\");c&&this.addClass(c)});b.on(\"blur\",function(){p.fire(\"blur\");c&&this.removeClass(c)})}});CKEDITOR.tools.extend(this,b);this.keyboardFocusable&&(this.tabIndex=b.tabIndex||\n0,this.focusIndex=a._.focusList.push(this)-1,this.on(\"focus\",function(){a._.currentFocusIndex=p.focusIndex}))}},hbox:function(a,b,c,e,d){if(!(4>arguments.length)){this._||(this._={});var g=this._.children=b,f=d&&d.widths||null,i=d&&d.height||null,l,k={role:\"presentation\"};d&&d.align&&(k.align=d.align);CKEDITOR.ui.dialog.uiElement.call(this,a,d||{type:\"hbox\"},e,\"table\",{},k,function(){var a=['<tbody><tr class=\"cke_dialog_ui_hbox\">'];for(l=0;l<c.length;l++){var b=\"cke_dialog_ui_hbox_child\",e=[];0===\nl&&(b=\"cke_dialog_ui_hbox_first\");l==c.length-1&&(b=\"cke_dialog_ui_hbox_last\");a.push('<td class=\"',b,'\" role=\"presentation\" ');f?f[l]&&e.push(\"width:\"+r(f[l])):e.push(\"width:\"+Math.floor(100/c.length)+\"%\");i&&e.push(\"height:\"+r(i));d&&void 0!=d.padding&&e.push(\"padding:\"+r(d.padding));CKEDITOR.env.ie&&(CKEDITOR.env.quirks&&g[l].align)&&e.push(\"text-align:\"+g[l].align);0<e.length&&a.push('style=\"'+e.join(\"; \")+'\" ');a.push(\">\",c[l],\"</td>\")}a.push(\"</tr></tbody>\");return a.join(\"\")})}},vbox:function(a,\nb,c,e,d){if(!(3>arguments.length)){this._||(this._={});var g=this._.children=b,f=d&&d.width||null,i=d&&d.heights||null;CKEDITOR.ui.dialog.uiElement.call(this,a,d||{type:\"vbox\"},e,\"div\",null,{role:\"presentation\"},function(){var b=['<table role=\"presentation\" cellspacing=\"0\" border=\"0\" '];b.push('style=\"');d&&d.expand&&b.push(\"height:100%;\");b.push(\"width:\"+r(f||\"100%\"),\";\");CKEDITOR.env.webkit&&b.push(\"float:none;\");b.push('\"');b.push('align=\"',CKEDITOR.tools.htmlEncode(d&&d.align||(\"ltr\"==a.getParentEditor().lang.dir?\n\"left\":\"right\")),'\" ');b.push(\"><tbody>\");for(var e=0;e<c.length;e++){var h=[];b.push('<tr><td role=\"presentation\" ');f&&h.push(\"width:\"+r(f||\"100%\"));i?h.push(\"height:\"+r(i[e])):d&&d.expand&&h.push(\"height:\"+Math.floor(100/c.length)+\"%\");d&&void 0!=d.padding&&h.push(\"padding:\"+r(d.padding));CKEDITOR.env.ie&&(CKEDITOR.env.quirks&&g[e].align)&&h.push(\"text-align:\"+g[e].align);0<h.length&&b.push('style=\"',h.join(\"; \"),'\" ');b.push(' class=\"cke_dialog_ui_vbox_child\">',c[e],\"</td></tr>\")}b.push(\"</tbody></table>\");\nreturn b.join(\"\")})}}}})();CKEDITOR.ui.dialog.uiElement.prototype={getElement:function(){return CKEDITOR.document.getById(this.domId)},getInputElement:function(){return this.getElement()},getDialog:function(){return this._.dialog},setValue:function(a,b){this.getInputElement().setValue(a);!b&&this.fire(\"change\",{value:a});return this},getValue:function(){return this.getInputElement().getValue()},isChanged:function(){return!1},selectParentTab:function(){for(var a=this.getInputElement();(a=a.getParent())&&\n-1==a.$.className.search(\"cke_dialog_page_contents\"););if(!a)return this;a=a.getAttribute(\"name\");this._.dialog._.currentTabId!=a&&this._.dialog.selectPage(a);return this},focus:function(){this.selectParentTab().getInputElement().focus();return this},registerEvents:function(a){var b=/^on([A-Z]\\w+)/,c,e=function(a,b,c,d){b.on(\"load\",function(){a.getInputElement().on(c,d,a)})},d;for(d in a)if(c=d.match(b))this.eventProcessors[d]?this.eventProcessors[d].call(this,this._.dialog,a[d]):e(this,this._.dialog,\nc[1].toLowerCase(),a[d]);return this},eventProcessors:{onLoad:function(a,b){a.on(\"load\",b,this)},onShow:function(a,b){a.on(\"show\",b,this)},onHide:function(a,b){a.on(\"hide\",b,this)}},accessKeyDown:function(){this.focus()},accessKeyUp:function(){},disable:function(){var a=this.getElement();this.getInputElement().setAttribute(\"disabled\",\"true\");a.addClass(\"cke_disabled\")},enable:function(){var a=this.getElement();this.getInputElement().removeAttribute(\"disabled\");a.removeClass(\"cke_disabled\")},isEnabled:function(){return!this.getElement().hasClass(\"cke_disabled\")},\nisVisible:function(){return this.getInputElement().isVisible()},isFocusable:function(){return!this.isEnabled()||!this.isVisible()?!1:!0}};CKEDITOR.ui.dialog.hbox.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.uiElement,{getChild:function(a){if(1>arguments.length)return this._.children.concat();a.splice||(a=[a]);return 2>a.length?this._.children[a[0]]:this._.children[a[0]]&&this._.children[a[0]].getChild?this._.children[a[0]].getChild(a.slice(1,a.length)):null}},!0);CKEDITOR.ui.dialog.vbox.prototype=\nnew CKEDITOR.ui.dialog.hbox;(function(){var a={build:function(a,c,e){for(var d=c.children,g,f=[],i=[],l=0;l<d.length&&(g=d[l]);l++){var k=[];f.push(k);i.push(CKEDITOR.dialog._.uiElementBuilders[g.type].build(a,g,k))}return new CKEDITOR.ui.dialog[c.type](a,i,f,e,c)}};CKEDITOR.dialog.addUIElement(\"hbox\",a);CKEDITOR.dialog.addUIElement(\"vbox\",a)})();CKEDITOR.dialogCommand=function(a,b){this.dialogName=a;CKEDITOR.tools.extend(this,b,!0)};CKEDITOR.dialogCommand.prototype={exec:function(a){CKEDITOR.env.opera?\nCKEDITOR.tools.setTimeout(function(){a.openDialog(this.dialogName)},0,this):a.openDialog(this.dialogName)},canUndo:!1,editorFocus:1};(function(){var a=/^([a]|[^a])+$/,b=/^\\d*$/,c=/^\\d*(?:\\.\\d+)?$/,e=/^(((\\d*(\\.\\d+))|(\\d*))(px|\\%)?)?$/,d=/^(((\\d*(\\.\\d+))|(\\d*))(px|em|ex|in|cm|mm|pt|pc|\\%)?)?$/i,g=/^(\\s*[\\w-]+\\s*:\\s*[^:;]+(?:;|$))*$/;CKEDITOR.VALIDATE_OR=1;CKEDITOR.VALIDATE_AND=2;CKEDITOR.dialog.validate={functions:function(){var a=arguments;return function(){var b=this&&this.getValue?this.getValue():\na[0],c=void 0,d=CKEDITOR.VALIDATE_AND,e=[],g;for(g=0;g<a.length;g++)if(\"function\"==typeof a[g])e.push(a[g]);else break;g<a.length&&\"string\"==typeof a[g]&&(c=a[g],g++);g<a.length&&\"number\"==typeof a[g]&&(d=a[g]);var j=d==CKEDITOR.VALIDATE_AND?!0:!1;for(g=0;g<e.length;g++)j=d==CKEDITOR.VALIDATE_AND?j&&e[g](b):j||e[g](b);return!j?c:!0}},regex:function(a,b){return function(c){c=this&&this.getValue?this.getValue():c;return!a.test(c)?b:!0}},notEmpty:function(b){return this.regex(a,b)},integer:function(a){return this.regex(b,\na)},number:function(a){return this.regex(c,a)},cssLength:function(a){return this.functions(function(a){return d.test(CKEDITOR.tools.trim(a))},a)},htmlLength:function(a){return this.functions(function(a){return e.test(CKEDITOR.tools.trim(a))},a)},inlineStyle:function(a){return this.functions(function(a){return g.test(CKEDITOR.tools.trim(a))},a)},equals:function(a,b){return this.functions(function(b){return b==a},b)},notEqual:function(a,b){return this.functions(function(b){return b!=a},b)}};CKEDITOR.on(\"instanceDestroyed\",\nfunction(a){if(CKEDITOR.tools.isEmpty(CKEDITOR.instances)){for(var b;b=CKEDITOR.dialog._.currentTop;)b.hide();for(var c in w)w[c].remove();w={}}var a=a.editor._.storedDialogs,d;for(d in a)a[d].destroy()})})();CKEDITOR.tools.extend(CKEDITOR.editor.prototype,{openDialog:function(a,b){var c=null,e=CKEDITOR.dialog._.dialogDefinitions[a];null===CKEDITOR.dialog._.currentTop&&J(this);if(\"function\"==typeof e)c=this._.storedDialogs||(this._.storedDialogs={}),c=c[a]||(c[a]=new CKEDITOR.dialog(this,a)),b&&b.call(c,\nc),c.show();else{if(\"failed\"==e)throw K(this),Error('[CKEDITOR.dialog.openDialog] Dialog \"'+a+'\" failed when loading definition.');\"string\"==typeof e&&CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(e),function(){\"function\"!=typeof CKEDITOR.dialog._.dialogDefinitions[a]&&(CKEDITOR.dialog._.dialogDefinitions[a]=\"failed\");this.openDialog(a,b)},this,0,1)}CKEDITOR.skin.loadPart(\"dialog\");return c}})})();\nCKEDITOR.plugins.add(\"dialog\",{requires:\"dialogui\",init:function(t){t.on(\"doubleclick\",function(u){u.data.dialog&&t.openDialog(u.data.dialog)},null,null,999)}});CKEDITOR.plugins.add(\"about\",{requires:\"dialog\",init:function(a){var b=a.addCommand(\"about\",new CKEDITOR.dialogCommand(\"about\"));b.modes={wysiwyg:1,source:1};b.canUndo=!1;b.readOnly=1;a.ui.addButton&&a.ui.addButton(\"About\",{label:a.lang.about.title,command:\"about\",toolbar:\"about\"});CKEDITOR.dialog.add(\"about\",this.path+\"dialogs/about.js\")}});(function(){CKEDITOR.plugins.add(\"a11yhelp\",{requires:\"dialog\",availableLangs:{ar:1,bg:1,ca:1,cs:1,cy:1,da:1,de:1,el:1,en:1,eo:1,es:1,et:1,fa:1,fi:1,fr:1,\"fr-ca\":1,gl:1,gu:1,he:1,hi:1,hr:1,hu:1,id:1,it:1,ja:1,km:1,ko:1,ku:1,lt:1,lv:1,mk:1,mn:1,nb:1,nl:1,no:1,pl:1,pt:1,\"pt-br\":1,ro:1,ru:1,si:1,sk:1,sl:1,sq:1,sr:1,\"sr-latn\":1,sv:1,th:1,tr:1,ug:1,uk:1,vi:1,zh:1,\"zh-cn\":1},init:function(b){var c=this;b.addCommand(\"a11yHelp\",{exec:function(){var a=b.langCode,a=c.availableLangs[a]?a:c.availableLangs[a.replace(/-.*/,\n\"\")]?a.replace(/-.*/,\"\"):\"en\";CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(c.path+\"dialogs/lang/\"+a+\".js\"),function(){b.lang.a11yhelp=c.langEntries[a];b.openDialog(\"a11yHelp\")})},modes:{wysiwyg:1,source:1},readOnly:1,canUndo:!1});b.setKeystroke(CKEDITOR.ALT+48,\"a11yHelp\");CKEDITOR.dialog.add(\"a11yHelp\",this.path+\"dialogs/a11yhelp.js\")}})})();CKEDITOR.plugins.add(\"basicstyles\",{init:function(c){var e=0,d=function(g,d,b,a){if(a){var a=new CKEDITOR.style(a),f=h[b];f.unshift(a);c.attachStyleStateChange(a,function(a){!c.readOnly&&c.getCommand(b).setState(a)});c.addCommand(b,new CKEDITOR.styleCommand(a,{contentForms:f}));c.ui.addButton&&c.ui.addButton(g,{label:d,command:b,toolbar:\"basicstyles,\"+(e+=10)})}},h={bold:[\"strong\",\"b\",[\"span\",function(a){a=a.styles[\"font-weight\"];return\"bold\"==a||700<=+a}]],italic:[\"em\",\"i\",[\"span\",function(a){return\"italic\"==\na.styles[\"font-style\"]}]],underline:[\"u\",[\"span\",function(a){return\"underline\"==a.styles[\"text-decoration\"]}]],strike:[\"s\",\"strike\",[\"span\",function(a){return\"line-through\"==a.styles[\"text-decoration\"]}]],subscript:[\"sub\"],superscript:[\"sup\"]},b=c.config,a=c.lang.basicstyles;d(\"Bold\",a.bold,\"bold\",b.coreStyles_bold);d(\"Italic\",a.italic,\"italic\",b.coreStyles_italic);d(\"Underline\",a.underline,\"underline\",b.coreStyles_underline);d(\"Strike\",a.strike,\"strike\",b.coreStyles_strike);d(\"Subscript\",a.subscript,\n\"subscript\",b.coreStyles_subscript);d(\"Superscript\",a.superscript,\"superscript\",b.coreStyles_superscript);c.setKeystroke([[CKEDITOR.CTRL+66,\"bold\"],[CKEDITOR.CTRL+73,\"italic\"],[CKEDITOR.CTRL+85,\"underline\"]])}});CKEDITOR.config.coreStyles_bold={element:\"strong\",overrides:\"b\"};CKEDITOR.config.coreStyles_italic={element:\"em\",overrides:\"i\"};CKEDITOR.config.coreStyles_underline={element:\"u\"};CKEDITOR.config.coreStyles_strike={element:\"s\",overrides:\"strike\"};CKEDITOR.config.coreStyles_subscript={element:\"sub\"};\nCKEDITOR.config.coreStyles_superscript={element:\"sup\"};(function(){var k={exec:function(g){var a=g.getCommand(\"blockquote\").state,i=g.getSelection(),c=i&&i.getRanges()[0];if(c){var h=i.createBookmarks();if(CKEDITOR.env.ie){var e=h[0].startNode,b=h[0].endNode,d;if(e&&\"blockquote\"==e.getParent().getName())for(d=e;d=d.getNext();)if(d.type==CKEDITOR.NODE_ELEMENT&&d.isBlockBoundary()){e.move(d,!0);break}if(b&&\"blockquote\"==b.getParent().getName())for(d=b;d=d.getPrevious();)if(d.type==CKEDITOR.NODE_ELEMENT&&d.isBlockBoundary()){b.move(d);break}}var f=c.createIterator();\nf.enlargeBr=g.config.enterMode!=CKEDITOR.ENTER_BR;if(a==CKEDITOR.TRISTATE_OFF){for(e=[];a=f.getNextParagraph();)e.push(a);1>e.length&&(a=g.document.createElement(g.config.enterMode==CKEDITOR.ENTER_P?\"p\":\"div\"),b=h.shift(),c.insertNode(a),a.append(new CKEDITOR.dom.text(\"﻿\",g.document)),c.moveToBookmark(b),c.selectNodeContents(a),c.collapse(!0),b=c.createBookmark(),e.push(a),h.unshift(b));d=e[0].getParent();c=[];for(b=0;b<e.length;b++)a=e[b],d=d.getCommonAncestor(a.getParent());for(a={table:1,tbody:1,\ntr:1,ol:1,ul:1};a[d.getName()];)d=d.getParent();for(b=null;0<e.length;){for(a=e.shift();!a.getParent().equals(d);)a=a.getParent();a.equals(b)||c.push(a);b=a}for(;0<c.length;)if(a=c.shift(),\"blockquote\"==a.getName()){for(b=new CKEDITOR.dom.documentFragment(g.document);a.getFirst();)b.append(a.getFirst().remove()),e.push(b.getLast());b.replace(a)}else e.push(a);c=g.document.createElement(\"blockquote\");for(c.insertBefore(e[0]);0<e.length;)a=e.shift(),c.append(a)}else if(a==CKEDITOR.TRISTATE_ON){b=[];\nfor(d={};a=f.getNextParagraph();){for(e=c=null;a.getParent();){if(\"blockquote\"==a.getParent().getName()){c=a.getParent();e=a;break}a=a.getParent()}c&&(e&&!e.getCustomData(\"blockquote_moveout\"))&&(b.push(e),CKEDITOR.dom.element.setMarker(d,e,\"blockquote_moveout\",!0))}CKEDITOR.dom.element.clearAllMarkers(d);a=[];e=[];for(d={};0<b.length;)f=b.shift(),c=f.getParent(),f.getPrevious()?f.getNext()?(f.breakParent(f.getParent()),e.push(f.getNext())):f.remove().insertAfter(c):f.remove().insertBefore(c),c.getCustomData(\"blockquote_processed\")||\n(e.push(c),CKEDITOR.dom.element.setMarker(d,c,\"blockquote_processed\",!0)),a.push(f);CKEDITOR.dom.element.clearAllMarkers(d);for(b=e.length-1;0<=b;b--){c=e[b];a:{d=c;for(var f=0,k=d.getChildCount(),j=void 0;f<k&&(j=d.getChild(f));f++)if(j.type==CKEDITOR.NODE_ELEMENT&&j.isBlockBoundary()){d=!1;break a}d=!0}d&&c.remove()}if(g.config.enterMode==CKEDITOR.ENTER_BR)for(c=!0;a.length;)if(f=a.shift(),\"div\"==f.getName()){b=new CKEDITOR.dom.documentFragment(g.document);c&&(f.getPrevious()&&!(f.getPrevious().type==\nCKEDITOR.NODE_ELEMENT&&f.getPrevious().isBlockBoundary()))&&b.append(g.document.createElement(\"br\"));for(c=f.getNext()&&!(f.getNext().type==CKEDITOR.NODE_ELEMENT&&f.getNext().isBlockBoundary());f.getFirst();)f.getFirst().remove().appendTo(b);c&&b.append(g.document.createElement(\"br\"));b.replace(f);c=!1}}i.selectBookmarks(h);g.focus()}},refresh:function(g,a){this.setState(g.elementPath(a.block||a.blockLimit).contains(\"blockquote\",1)?CKEDITOR.TRISTATE_ON:CKEDITOR.TRISTATE_OFF)},context:\"blockquote\",\nallowedContent:\"blockquote\",requiredContent:\"blockquote\"};CKEDITOR.plugins.add(\"blockquote\",{init:function(g){g.blockless||(g.addCommand(\"blockquote\",k),g.ui.addButton&&g.ui.addButton(\"Blockquote\",{label:g.lang.blockquote.toolbar,command:\"blockquote\",toolbar:\"blocks,10\"}))}})})();(function(){function w(b){function a(){var e=b.editable();e.on(q,function(b){(!CKEDITOR.env.ie||!n)&&u(b)});CKEDITOR.env.ie&&e.on(\"paste\",function(e){r||(f(),e.data.preventDefault(),u(e),l(\"paste\")||b.openDialog(\"paste\"))});CKEDITOR.env.ie&&(e.on(\"contextmenu\",h,null,null,0),e.on(\"beforepaste\",function(b){b.data&&!b.data.$.ctrlKey&&h()},null,null,0));e.on(\"beforecut\",function(){!n&&i(b)});var a;e.attachListener(CKEDITOR.env.ie?e:b.document.getDocumentElement(),\"mouseup\",function(){a=setTimeout(function(){s()},\n0)});b.on(\"destroy\",function(){clearTimeout(a)});e.on(\"keyup\",s)}function c(e){return{type:e,canUndo:\"cut\"==e,startDisabled:!0,exec:function(){\"cut\"==this.type&&i();var e;var a=this.type;if(CKEDITOR.env.ie)e=l(a);else try{e=b.document.$.execCommand(a,!1,null)}catch(d){e=!1}e||alert(b.lang.clipboard[this.type+\"Error\"]);return e}}}function d(){return{canUndo:!1,async:!0,exec:function(b,a){var d=function(a,d){a&&g(a.type,a.dataValue,!!d);b.fire(\"afterCommandExec\",{name:\"paste\",command:c,returnValue:!!a})},\nc=this;\"string\"==typeof a?d({type:\"auto\",dataValue:a},1):b.getClipboardData(d)}}}function f(){r=1;setTimeout(function(){r=0},100)}function h(){n=1;setTimeout(function(){n=0},10)}function l(e){var a=b.document,d=a.getBody(),c=!1,i=function(){c=!0};d.on(e,i);(7<CKEDITOR.env.version?a.$:a.$.selection.createRange()).execCommand(e);d.removeListener(e,i);return c}function g(e,a,d){e={type:e};if(d&&!b.fire(\"beforePaste\",e)||!a)return!1;e.dataValue=a;return b.fire(\"paste\",e)}function i(){if(CKEDITOR.env.ie&&\n!CKEDITOR.env.quirks){var e=b.getSelection(),a,d,c;if(e.getType()==CKEDITOR.SELECTION_ELEMENT&&(a=e.getSelectedElement()))d=e.getRanges()[0],c=b.document.createText(\"\"),c.insertBefore(a),d.setStartBefore(c),d.setEndAfter(a),e.selectRanges([d]),setTimeout(function(){a.getParent()&&(c.remove(),e.selectElement(a))},0)}}function k(a,d){var c=b.document,i=b.editable(),k=function(b){b.cancel()},f=CKEDITOR.env.gecko&&10902>=CKEDITOR.env.version,h;if(!c.getById(\"cke_pastebin\")){var o=b.getSelection(),v=o.createBookmarks(),\nj=new CKEDITOR.dom.element((CKEDITOR.env.webkit||i.is(\"body\"))&&!CKEDITOR.env.ie&&!CKEDITOR.env.opera?\"body\":\"div\",c);j.setAttributes({id:\"cke_pastebin\",\"data-cke-temp\":\"1\"});CKEDITOR.env.opera&&j.appendBogus();var g=0,c=c.getWindow();f?(j.insertAfter(v[0].startNode),j.setStyle(\"display\",\"inline\")):(CKEDITOR.env.webkit?(i.append(j),j.addClass(\"cke_editable\"),i.is(\"body\")||(f=\"static\"!=i.getComputedStyle(\"position\")?i:CKEDITOR.dom.element.get(i.$.offsetParent),g=f.getDocumentPosition().y)):i.getAscendant(CKEDITOR.env.ie||\nCKEDITOR.env.opera?\"body\":\"html\",1).append(j),j.setStyles({position:\"absolute\",top:c.getScrollPosition().y-g+10+\"px\",width:\"1px\",height:Math.max(1,c.getViewPaneSize().height-20)+\"px\",overflow:\"hidden\",margin:0,padding:0}));(f=j.getParent().isReadOnly())?(j.setOpacity(0),j.setAttribute(\"contenteditable\",!0)):j.setStyle(\"ltr\"==b.config.contentsLangDirection?\"left\":\"right\",\"-1000px\");b.on(\"selectionChange\",k,null,null,0);CKEDITOR.env.webkit&&(h=i.once(\"blur\",k,null,null,-100));f&&j.focus();f=new CKEDITOR.dom.range(j);\nf.selectNodeContents(j);var l=f.select();CKEDITOR.env.ie&&(h=i.once(\"blur\",function(){b.lockSelection(l)}));var m=CKEDITOR.document.getWindow().getScrollPosition().y;setTimeout(function(){if(CKEDITOR.env.webkit||CKEDITOR.env.opera)CKEDITOR.document[CKEDITOR.env.webkit?\"getBody\":\"getDocumentElement\"]().$.scrollTop=m;h&&h.removeListener();CKEDITOR.env.ie&&i.focus();o.selectBookmarks(v);j.remove();var a;if(CKEDITOR.env.webkit&&(a=j.getFirst())&&a.is&&a.hasClass(\"Apple-style-span\"))j=a;b.removeListener(\"selectionChange\",\nk);d(j.getHtml())},0)}}function o(){if(CKEDITOR.env.ie){b.focus();f();var a=b.focusManager;a.lock();if(b.editable().fire(q)&&!l(\"paste\"))return a.unlock(),!1;a.unlock()}else try{if(b.editable().fire(q)&&!b.document.$.execCommand(\"Paste\",!1,null))throw 0;}catch(d){return!1}return!0}function p(a){if(\"wysiwyg\"==b.mode)switch(a.data.keyCode){case CKEDITOR.CTRL+86:case CKEDITOR.SHIFT+45:a=b.editable();f();!CKEDITOR.env.ie&&a.fire(\"beforepaste\");(CKEDITOR.env.opera||CKEDITOR.env.gecko&&10900>CKEDITOR.env.version)&&\na.fire(\"paste\");break;case CKEDITOR.CTRL+88:case CKEDITOR.SHIFT+46:b.fire(\"saveSnapshot\"),setTimeout(function(){b.fire(\"saveSnapshot\")},0)}}function u(a){var d={type:\"auto\"},c=b.fire(\"beforePaste\",d);k(a,function(b){b=b.replace(/<span[^>]+data-cke-bookmark[^<]*?<\\/span>/ig,\"\");c&&g(d.type,b,0,1)})}function s(){if(\"wysiwyg\"==b.mode){var a=m(\"paste\");b.getCommand(\"cut\").setState(m(\"cut\"));b.getCommand(\"copy\").setState(m(\"copy\"));b.getCommand(\"paste\").setState(a);b.fire(\"pasteState\",a)}}function m(a){if(t&&\na in{paste:1,cut:1})return CKEDITOR.TRISTATE_DISABLED;if(\"paste\"==a)return CKEDITOR.TRISTATE_OFF;var a=b.getSelection(),d=a.getRanges();return a.getType()==CKEDITOR.SELECTION_NONE||1==d.length&&d[0].collapsed?CKEDITOR.TRISTATE_DISABLED:CKEDITOR.TRISTATE_OFF}var n=0,r=0,t=0,q=CKEDITOR.env.ie?\"beforepaste\":\"paste\";(function(){b.on(\"key\",p);b.on(\"contentDom\",a);b.on(\"selectionChange\",function(a){t=a.data.selection.getRanges()[0].checkReadOnly();s()});b.contextMenu&&b.contextMenu.addListener(function(a,\nb){t=b.getRanges()[0].checkReadOnly();return{cut:m(\"cut\"),copy:m(\"copy\"),paste:m(\"paste\")}})})();(function(){function a(d,c,i,e,f){var k=b.lang.clipboard[c];b.addCommand(c,i);b.ui.addButton&&b.ui.addButton(d,{label:k,command:c,toolbar:\"clipboard,\"+e});b.addMenuItems&&b.addMenuItem(c,{label:k,command:c,group:\"clipboard\",order:f})}a(\"Cut\",\"cut\",c(\"cut\"),10,1);a(\"Copy\",\"copy\",c(\"copy\"),20,4);a(\"Paste\",\"paste\",d(),30,8)})();b.getClipboardData=function(a,d){function c(a){a.removeListener();a.cancel();\nd(a.data)}function i(a){a.removeListener();a.cancel();g=!0;d({type:h,dataValue:a.data})}function f(){this.customTitle=a&&a.title}var k=!1,h=\"auto\",g=!1;d||(d=a,a=null);b.on(\"paste\",c,null,null,0);b.on(\"beforePaste\",function(a){a.removeListener();k=true;h=a.data.type},null,null,1E3);!1===o()&&(b.removeListener(\"paste\",c),k&&b.fire(\"pasteDialog\",f)?(b.on(\"pasteDialogCommit\",i),b.on(\"dialogHide\",function(a){a.removeListener();a.data.removeListener(\"pasteDialogCommit\",i);setTimeout(function(){g||d(null)},\n10)})):d(null))}}function x(b){if(CKEDITOR.env.webkit){if(!b.match(/^[^<]*$/g)&&!b.match(/^(<div><br( ?\\/)?><\\/div>|<div>[^<]*<\\/div>)*$/gi))return\"html\"}else if(CKEDITOR.env.ie){if(!b.match(/^([^<]|<br( ?\\/)?>)*$/gi)&&!b.match(/^(<p>([^<]|<br( ?\\/)?>)*<\\/p>|(\\r\\n))*$/gi))return\"html\"}else if(CKEDITOR.env.gecko||CKEDITOR.env.opera){if(!b.match(/^([^<]|<br( ?\\/)?>)*$/gi))return\"html\"}else return\"html\";return\"htmlifiedtext\"}function y(b,a){function c(a){return CKEDITOR.tools.repeat(\"</p><p>\",~~(a/2))+\n(1==a%2?\"<br>\":\"\")}a=a.replace(/\\s+/g,\" \").replace(/> +</g,\"><\").replace(/<br ?\\/>/gi,\"<br>\");a=a.replace(/<\\/?[A-Z]+>/g,function(a){return a.toLowerCase()});if(a.match(/^[^<]$/))return a;CKEDITOR.env.webkit&&-1<a.indexOf(\"<div>\")&&(a=a.replace(/^(<div>(<br>|)<\\/div>)(?!$|(<div>(<br>|)<\\/div>))/g,\"<br>\").replace(/^(<div>(<br>|)<\\/div>){2}(?!$)/g,\"<div></div>\"),a.match(/<div>(<br>|)<\\/div>/)&&(a=\"<p>\"+a.replace(/(<div>(<br>|)<\\/div>)+/g,function(a){return c(a.split(\"</div><div>\").length+1)})+\"</p>\"),\na=a.replace(/<\\/div><div>/g,\"<br>\"),a=a.replace(/<\\/?div>/g,\"\"));if((CKEDITOR.env.gecko||CKEDITOR.env.opera)&&b.enterMode!=CKEDITOR.ENTER_BR)CKEDITOR.env.gecko&&(a=a.replace(/^<br><br>$/,\"<br>\")),-1<a.indexOf(\"<br><br>\")&&(a=\"<p>\"+a.replace(/(<br>){2,}/g,function(a){return c(a.length/4)})+\"</p>\");return p(b,a)}function z(){var b=new CKEDITOR.htmlParser.filter,a={blockquote:1,dl:1,fieldset:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,ol:1,p:1,table:1,ul:1},c=CKEDITOR.tools.extend({br:0},CKEDITOR.dtd.$inline),d=\n{p:1,br:1,\"cke:br\":1},f=CKEDITOR.dtd,h=CKEDITOR.tools.extend({area:1,basefont:1,embed:1,iframe:1,map:1,object:1,param:1},CKEDITOR.dtd.$nonBodyContent,CKEDITOR.dtd.$cdata),l=function(a){delete a.name;a.add(new CKEDITOR.htmlParser.text(\" \"))},g=function(a){for(var b=a,c;(b=b.next)&&b.name&&b.name.match(/^h\\d$/);){c=new CKEDITOR.htmlParser.element(\"cke:br\");c.isEmpty=!0;for(a.add(c);c=b.children.shift();)a.add(c)}};b.addRules({elements:{h1:g,h2:g,h3:g,h4:g,h5:g,h6:g,img:function(a){var a=CKEDITOR.tools.trim(a.attributes.alt||\n\"\"),b=\" \";a&&!a.match(/(^http|\\.(jpe?g|gif|png))/i)&&(b=\" [\"+a+\"] \");return new CKEDITOR.htmlParser.text(b)},td:l,th:l,$:function(b){var k=b.name,g;if(h[k])return!1;b.attributes=[];if(\"br\"==k)return b;if(a[k])b.name=\"p\";else if(c[k])delete b.name;else if(f[k]){g=new CKEDITOR.htmlParser.element(\"cke:br\");g.isEmpty=!0;if(CKEDITOR.dtd.$empty[k])return g;b.add(g,0);g=g.clone();g.isEmpty=!0;b.add(g);delete b.name}d[b.name]||delete b.name;return b}}},{applyToAll:!0});return b}function A(b,a,c){var a=new CKEDITOR.htmlParser.fragment.fromHtml(a),\nd=new CKEDITOR.htmlParser.basicWriter;a.writeHtml(d,c);var a=d.getHtml(),a=a.replace(/\\s*(<\\/?[a-z:]+ ?\\/?>)\\s*/g,\"$1\").replace(/(<cke:br \\/>){2,}/g,\"<cke:br />\").replace(/(<cke:br \\/>)(<\\/?p>|<br \\/>)/g,\"$2\").replace(/(<\\/?p>|<br \\/>)(<cke:br \\/>)/g,\"$1\").replace(/<(cke:)?br( \\/)?>/g,\"<br>\").replace(/<p><\\/p>/g,\"\"),f=0,a=a.replace(/<\\/?p>/g,function(a){if(\"<p>\"==a){if(1<++f)return\"</p><p>\"}else if(0<--f)return\"</p><p>\";return a}).replace(/<p><\\/p>/g,\"\");return p(b,a)}function p(b,a){b.enterMode==\nCKEDITOR.ENTER_BR?a=a.replace(/(<\\/p><p>)+/g,function(a){return CKEDITOR.tools.repeat(\"<br>\",2*(a.length/7))}).replace(/<\\/?p>/g,\"\"):b.enterMode==CKEDITOR.ENTER_DIV&&(a=a.replace(/<(\\/)?p>/g,\"<$1div>\"));return a}CKEDITOR.plugins.add(\"clipboard\",{requires:\"dialog\",init:function(b){var a;w(b);CKEDITOR.dialog.add(\"paste\",CKEDITOR.getUrl(this.path+\"dialogs/paste.js\"));b.on(\"paste\",function(a){var b=a.data.dataValue,f=CKEDITOR.dtd.$block;-1<b.indexOf(\"Apple-\")&&(b=b.replace(/<span class=\"Apple-converted-space\">&nbsp;<\\/span>/gi,\n\" \"),\"html\"!=a.data.type&&(b=b.replace(/<span class=\"Apple-tab-span\"[^>]*>([^<]*)<\\/span>/gi,function(a,b){return b.replace(/\\t/g,\"&nbsp;&nbsp; &nbsp;\")})),-1<b.indexOf('<br class=\"Apple-interchange-newline\">')&&(a.data.startsWithEOL=1,a.data.preSniffing=\"html\",b=b.replace(/<br class=\"Apple-interchange-newline\">/,\"\")),b=b.replace(/(<[^>]+) class=\"Apple-[^\"]*\"/gi,\"$1\"));if(b.match(/^<[^<]+cke_(editable|contents)/i)){var h,l,g=new CKEDITOR.dom.element(\"div\");for(g.setHtml(b);1==g.getChildCount()&&(h=\ng.getFirst())&&h.type==CKEDITOR.NODE_ELEMENT&&(h.hasClass(\"cke_editable\")||h.hasClass(\"cke_contents\"));)g=l=h;l&&(b=l.getHtml().replace(/<br>$/i,\"\"))}CKEDITOR.env.ie?b=b.replace(/^&nbsp;(?: |\\r\\n)?<(\\w+)/g,function(b,d){if(d.toLowerCase()in f){a.data.preSniffing=\"html\";return\"<\"+d}return b}):CKEDITOR.env.webkit?b=b.replace(/<\\/(\\w+)><div><br><\\/div>$/,function(b,d){if(d in f){a.data.endsWithEOL=1;return\"</\"+d+\">\"}return b}):CKEDITOR.env.gecko&&(b=b.replace(/(\\s)<br>$/,\"$1\"));a.data.dataValue=b},null,\nnull,3);b.on(\"paste\",function(c){var c=c.data,d=c.type,f=c.dataValue,h,l=b.config.clipboard_defaultContentType||\"html\";h=\"html\"==d||\"html\"==c.preSniffing?\"html\":x(f);\"htmlifiedtext\"==h?f=y(b.config,f):\"text\"==d&&\"html\"==h&&(f=A(b.config,f,a||(a=z(b))));c.startsWithEOL&&(f='<br data-cke-eol=\"1\">'+f);c.endsWithEOL&&(f+='<br data-cke-eol=\"1\">');\"auto\"==d&&(d=\"html\"==h||\"html\"==l?\"html\":\"text\");c.type=d;c.dataValue=f;delete c.preSniffing;delete c.startsWithEOL;delete c.endsWithEOL},null,null,6);b.on(\"paste\",\nfunction(a){a=a.data;b.insertHtml(a.dataValue,a.type);setTimeout(function(){b.fire(\"afterPaste\")},0)},null,null,1E3);b.on(\"pasteDialog\",function(a){setTimeout(function(){b.openDialog(\"paste\",a.data)},0)})}})})();(function(){CKEDITOR.plugins.add(\"panel\",{beforeInit:function(a){a.ui.addHandler(CKEDITOR.UI_PANEL,CKEDITOR.ui.panel.handler)}});CKEDITOR.UI_PANEL=\"panel\";CKEDITOR.ui.panel=function(a,b){b&&CKEDITOR.tools.extend(this,b);CKEDITOR.tools.extend(this,{className:\"\",css:[]});this.id=CKEDITOR.tools.getNextId();this.document=a;this.isFramed=this.forceIFrame||this.css.length;this._={blocks:{}}};CKEDITOR.ui.panel.handler={create:function(a){return new CKEDITOR.ui.panel(a)}};var f=CKEDITOR.addTemplate(\"panel\",\n'<div lang=\"{langCode}\" id=\"{id}\" dir={dir} class=\"cke cke_reset_all {editorId} cke_panel cke_panel {cls} cke_{dir}\" style=\"z-index:{z-index}\" role=\"presentation\">{frame}</div>'),g=CKEDITOR.addTemplate(\"panel-frame\",'<iframe id=\"{id}\" class=\"cke_panel_frame\" role=\"presentation\" frameborder=\"0\" src=\"{src}\"></iframe>'),h=CKEDITOR.addTemplate(\"panel-frame-inner\",'<!DOCTYPE html><html class=\"cke_panel_container {env}\" dir=\"{dir}\" lang=\"{langCode}\"><head>{css}</head><body class=\"cke_{dir}\" style=\"margin:0;padding:0\" onload=\"{onload}\"></body></html>');\nCKEDITOR.ui.panel.prototype={render:function(a,b){this.getHolderElement=function(){var a=this._.holder;if(!a){if(this.isFramed){var a=this.document.getById(this.id+\"_frame\"),b=a.getParent(),a=a.getFrameDocument();CKEDITOR.env.iOS&&b.setStyles({overflow:\"scroll\",\"-webkit-overflow-scrolling\":\"touch\"});b=CKEDITOR.tools.addFunction(CKEDITOR.tools.bind(function(){this.isLoaded=!0;if(this.onLoad)this.onLoad()},this));a.write(h.output(CKEDITOR.tools.extend({css:CKEDITOR.tools.buildStyleHtml(this.css),onload:\"window.parent.CKEDITOR.tools.callFunction(\"+\nb+\");\"},d)));a.getWindow().$.CKEDITOR=CKEDITOR;a.on(\"key\"+(CKEDITOR.env.opera?\"press\":\"down\"),function(a){var b=a.data.getKeystroke(),c=this.document.getById(this.id).getAttribute(\"dir\");this._.onKeyDown&&!1===this._.onKeyDown(b)?a.data.preventDefault():(27==b||b==(\"rtl\"==c?39:37))&&this.onEscape&&!1===this.onEscape(b)&&a.data.preventDefault()},this);a=a.getBody();a.unselectable();CKEDITOR.env.air&&CKEDITOR.tools.callFunction(b)}else a=this.document.getById(this.id);this._.holder=a}return a};var d=\n{editorId:a.id,id:this.id,langCode:a.langCode,dir:a.lang.dir,cls:this.className,frame:\"\",env:CKEDITOR.env.cssClass,\"z-index\":a.config.baseFloatZIndex+1};if(this.isFramed){var e=CKEDITOR.env.air?\"javascript:void(0)\":CKEDITOR.env.ie?\"javascript:void(function(){\"+encodeURIComponent(\"document.open();(\"+CKEDITOR.tools.fixDomain+\")();document.close();\")+\"}())\":\"\";d.frame=g.output({id:this.id+\"_frame\",src:e})}e=f.output(d);b&&b.push(e);return e},addBlock:function(a,b){b=this._.blocks[a]=b instanceof CKEDITOR.ui.panel.block?\nb:new CKEDITOR.ui.panel.block(this.getHolderElement(),b);this._.currentBlock||this.showBlock(a);return b},getBlock:function(a){return this._.blocks[a]},showBlock:function(a){var a=this._.blocks[a],b=this._.currentBlock,d=!this.forceIFrame||CKEDITOR.env.ie?this._.holder:this.document.getById(this.id+\"_frame\");b&&b.hide();this._.currentBlock=a;CKEDITOR.fire(\"ariaWidget\",d);a._.focusIndex=-1;this._.onKeyDown=a.onKeyDown&&CKEDITOR.tools.bind(a.onKeyDown,a);a.show();return a},destroy:function(){this.element&&\nthis.element.remove()}};CKEDITOR.ui.panel.block=CKEDITOR.tools.createClass({$:function(a,b){this.element=a.append(a.getDocument().createElement(\"div\",{attributes:{tabindex:-1,\"class\":\"cke_panel_block\"},styles:{display:\"none\"}}));b&&CKEDITOR.tools.extend(this,b);this.element.setAttributes({role:this.attributes.role||\"presentation\",\"aria-label\":this.attributes[\"aria-label\"],title:this.attributes.title||this.attributes[\"aria-label\"]});this.keys={};this._.focusIndex=-1;this.element.disableContextMenu()},\n_:{markItem:function(a){-1!=a&&(a=this.element.getElementsByTag(\"a\").getItem(this._.focusIndex=a),(CKEDITOR.env.webkit||CKEDITOR.env.opera)&&a.getDocument().getWindow().focus(),a.focus(),this.onMark&&this.onMark(a))}},proto:{show:function(){this.element.setStyle(\"display\",\"\")},hide:function(){(!this.onHide||!0!==this.onHide.call(this))&&this.element.setStyle(\"display\",\"none\")},onKeyDown:function(a,b){var d=this.keys[a];switch(d){case \"next\":for(var e=this._.focusIndex,d=this.element.getElementsByTag(\"a\"),\nc;c=d.getItem(++e);)if(c.getAttribute(\"_cke_focus\")&&c.$.offsetWidth){this._.focusIndex=e;c.focus();break}return!c&&!b?(this._.focusIndex=-1,this.onKeyDown(a,1)):!1;case \"prev\":e=this._.focusIndex;for(d=this.element.getElementsByTag(\"a\");0<e&&(c=d.getItem(--e));){if(c.getAttribute(\"_cke_focus\")&&c.$.offsetWidth){this._.focusIndex=e;c.focus();break}c=null}return!c&&!b?(this._.focusIndex=d.count(),this.onKeyDown(a,1)):!1;case \"click\":case \"mouseup\":return e=this._.focusIndex,(c=0<=e&&this.element.getElementsByTag(\"a\").getItem(e))&&\n(c.$[d]?c.$[d]():c.$[\"on\"+d]()),!1}return!0}}})})();CKEDITOR.plugins.add(\"floatpanel\",{requires:\"panel\"});\n(function(){function q(a,b,c,i,f){var f=CKEDITOR.tools.genKey(b.getUniqueId(),c.getUniqueId(),a.lang.dir,a.uiColor||\"\",i.css||\"\",f||\"\"),h=g[f];h||(h=g[f]=new CKEDITOR.ui.panel(b,i),h.element=c.append(CKEDITOR.dom.element.createFromHtml(h.render(a),b)),h.element.setStyles({display:\"none\",position:\"absolute\"}));return h}var g={};CKEDITOR.ui.floatPanel=CKEDITOR.tools.createClass({$:function(a,b,c,i){function f(){d.hide()}c.forceIFrame=1;c.toolbarRelated&&a.elementMode==CKEDITOR.ELEMENT_MODE_INLINE&&\n(b=CKEDITOR.document.getById(\"cke_\"+a.name));var h=b.getDocument(),i=q(a,h,b,c,i||0),j=i.element,l=j.getFirst(),d=this;j.disableContextMenu();this.element=j;this._={editor:a,panel:i,parentElement:b,definition:c,document:h,iframe:l,children:[],dir:a.lang.dir};a.on(\"mode\",f);a.on(\"resize\",f);h.getWindow().on(\"resize\",f)},proto:{addBlock:function(a,b){return this._.panel.addBlock(a,b)},addListBlock:function(a,b){return this._.panel.addListBlock(a,b)},getBlock:function(a){return this._.panel.getBlock(a)},\nshowBlock:function(a,b,c,i,f,h){var j=this._.panel,l=j.showBlock(a);this.allowBlur(!1);a=this._.editor.editable();this._.returnFocus=a.hasFocus?a:new CKEDITOR.dom.element(CKEDITOR.document.$.activeElement);var d=this.element,a=this._.iframe,a=CKEDITOR.env.ie?a:new CKEDITOR.dom.window(a.$.contentWindow),g=d.getDocument(),o=this._.parentElement.getPositionedAncestor(),p=b.getDocumentPosition(g),g=o?o.getDocumentPosition(g):{x:0,y:0},m=\"rtl\"==this._.dir,e=p.x+(i||0)-g.x,k=p.y+(f||0)-g.y;if(m&&(1==c||\n4==c))e+=b.$.offsetWidth;else if(!m&&(2==c||3==c))e+=b.$.offsetWidth-1;if(3==c||4==c)k+=b.$.offsetHeight-1;this._.panel._.offsetParentId=b.getId();d.setStyles({top:k+\"px\",left:0,display:\"\"});d.setOpacity(0);d.getFirst().removeStyle(\"width\");this._.editor.focusManager.add(a);this._.blurSet||(CKEDITOR.event.useCapture=!0,a.on(\"blur\",function(a){this.allowBlur()&&a.data.getPhase()==CKEDITOR.EVENT_PHASE_AT_TARGET&&(this.visible&&!this._.activeChild)&&(delete this._.returnFocus,this.hide())},this),a.on(\"focus\",\nfunction(){this._.focused=!0;this.hideChild();this.allowBlur(!0)},this),CKEDITOR.event.useCapture=!1,this._.blurSet=1);j.onEscape=CKEDITOR.tools.bind(function(a){if(this.onEscape&&this.onEscape(a)===false)return false},this);CKEDITOR.tools.setTimeout(function(){var a=CKEDITOR.tools.bind(function(){d.removeStyle(\"width\");if(l.autoSize){var a=l.element.getDocument(),a=(CKEDITOR.env.webkit?l.element:a.getBody()).$.scrollWidth;CKEDITOR.env.ie&&(CKEDITOR.env.quirks&&a>0)&&(a=a+((d.$.offsetWidth||0)-(d.$.clientWidth||\n0)+3));d.setStyle(\"width\",a+10+\"px\");a=l.element.$.scrollHeight;CKEDITOR.env.ie&&(CKEDITOR.env.quirks&&a>0)&&(a=a+((d.$.offsetHeight||0)-(d.$.clientHeight||0)+3));d.setStyle(\"height\",a+\"px\");j._.currentBlock.element.setStyle(\"display\",\"none\").removeStyle(\"display\")}else d.removeStyle(\"height\");m&&(e=e-d.$.offsetWidth);d.setStyle(\"left\",e+\"px\");var b=j.element.getWindow(),a=d.$.getBoundingClientRect(),b=b.getViewPaneSize(),c=a.width||a.right-a.left,f=a.height||a.bottom-a.top,i=m?a.right:b.width-a.left,\ng=m?b.width-a.right:a.left;m?i<c&&(e=g>c?e+c:b.width>c?e-a.left:e-a.right+b.width):i<c&&(e=g>c?e-c:b.width>c?e-a.right+b.width:e-a.left);c=a.top;b.height-a.top<f&&(k=c>f?k-f:b.height>f?k-a.bottom+b.height:k-a.top);if(CKEDITOR.env.ie){b=a=new CKEDITOR.dom.element(d.$.offsetParent);b.getName()==\"html\"&&(b=b.getDocument().getBody());b.getComputedStyle(\"direction\")==\"rtl\"&&(e=CKEDITOR.env.ie8Compat?e-d.getDocument().getDocumentElement().$.scrollLeft*2:e-(a.$.scrollWidth-a.$.clientWidth))}var a=d.getFirst(),\nn;(n=a.getCustomData(\"activePanel\"))&&n.onHide&&n.onHide.call(this,1);a.setCustomData(\"activePanel\",this);d.setStyles({top:k+\"px\",left:e+\"px\"});d.setOpacity(1);h&&h()},this);j.isLoaded?a():j.onLoad=a;CKEDITOR.tools.setTimeout(function(){var a=CKEDITOR.env.webkit&&CKEDITOR.document.getWindow().getScrollPosition().y;this.focus();l.element.focus();if(CKEDITOR.env.webkit)CKEDITOR.document.getBody().$.scrollTop=a;this.allowBlur(true);this._.editor.fire(\"panelShow\",this)},0,this)},CKEDITOR.env.air?200:\n0,this);this.visible=1;this.onShow&&this.onShow.call(this)},focus:function(){if(CKEDITOR.env.webkit){var a=CKEDITOR.document.getActive();!a.equals(this._.iframe)&&a.$.blur()}(this._.lastFocused||this._.iframe.getFrameDocument().getWindow()).focus()},blur:function(){var a=this._.iframe.getFrameDocument().getActive();a.is(\"a\")&&(this._.lastFocused=a)},hide:function(a){if(this.visible&&(!this.onHide||!0!==this.onHide.call(this))){this.hideChild();CKEDITOR.env.gecko&&this._.iframe.getFrameDocument().$.activeElement.blur();\nthis.element.setStyle(\"display\",\"none\");this.visible=0;this.element.getFirst().removeCustomData(\"activePanel\");if(a=a&&this._.returnFocus)CKEDITOR.env.webkit&&a.type&&a.getWindow().$.focus(),a.focus();delete this._.lastFocused;this._.editor.fire(\"panelHide\",this)}},allowBlur:function(a){var b=this._.panel;void 0!=a&&(b.allowBlur=a);return b.allowBlur},showAsChild:function(a,b,c,g,f,h){this._.activeChild==a&&a._.panel._.offsetParentId==c.getId()||(this.hideChild(),a.onHide=CKEDITOR.tools.bind(function(){CKEDITOR.tools.setTimeout(function(){this._.focused||\nthis.hide()},0,this)},this),this._.activeChild=a,this._.focused=!1,a.showBlock(b,c,g,f,h),this.blur(),(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat)&&setTimeout(function(){a.element.getChild(0).$.style.cssText+=\"\"},100))},hideChild:function(a){var b=this._.activeChild;b&&(delete b.onHide,delete this._.activeChild,b.hide(),a&&this.focus())}}});CKEDITOR.on(\"instanceDestroyed\",function(){var a=CKEDITOR.tools.isEmpty(CKEDITOR.instances),b;for(b in g){var c=g[b];a?c.destroy():c.element.hide()}a&&(g=\n{})})})();CKEDITOR.plugins.add(\"menu\",{requires:\"floatpanel\",beforeInit:function(g){for(var h=g.config.menu_groups.split(\",\"),m=g._.menuGroups={},l=g._.menuItems={},a=0;a<h.length;a++)m[h[a]]=a+1;g.addMenuGroup=function(b,a){m[b]=a||100};g.addMenuItem=function(a,c){m[c.group]&&(l[a]=new CKEDITOR.menuItem(this,a,c))};g.addMenuItems=function(a){for(var c in a)this.addMenuItem(c,a[c])};g.getMenuItem=function(a){return l[a]};g.removeMenuItem=function(a){delete l[a]}}});\n(function(){function g(a){a.sort(function(a,c){return a.group<c.group?-1:a.group>c.group?1:a.order<c.order?-1:a.order>c.order?1:0})}var h='<span class=\"cke_menuitem\"><a id=\"{id}\" class=\"cke_menubutton cke_menubutton__{name} cke_menubutton_{state} {cls}\" href=\"{href}\" title=\"{title}\" tabindex=\"-1\"_cke_focus=1 hidefocus=\"true\" role=\"{role}\" aria-haspopup=\"{hasPopup}\" aria-disabled=\"{disabled}\" {ariaChecked}';if(CKEDITOR.env.opera||CKEDITOR.env.gecko&&CKEDITOR.env.mac)h+=' onkeypress=\"return false;\"';\nCKEDITOR.env.gecko&&(h+=' onblur=\"this.style.cssText = this.style.cssText;\"');var h=h+(' onmouseover=\"CKEDITOR.tools.callFunction({hoverFn},{index});\" onmouseout=\"CKEDITOR.tools.callFunction({moveOutFn},{index});\" '+(CKEDITOR.env.ie?'onclick=\"return false;\" onmouseup':\"onclick\")+'=\"CKEDITOR.tools.callFunction({clickFn},{index}); return false;\">'),m=CKEDITOR.addTemplate(\"menuItem\",h+'<span class=\"cke_menubutton_inner\"><span class=\"cke_menubutton_icon\"><span class=\"cke_button_icon cke_button__{iconName}_icon\" style=\"{iconStyle}\"></span></span><span class=\"cke_menubutton_label\">{label}</span>{arrowHtml}</span></a></span>'),\nl=CKEDITOR.addTemplate(\"menuArrow\",'<span class=\"cke_menuarrow\"><span>{label}</span></span>');CKEDITOR.menu=CKEDITOR.tools.createClass({$:function(a,b){b=this._.definition=b||{};this.id=CKEDITOR.tools.getNextId();this.editor=a;this.items=[];this._.listeners=[];this._.level=b.level||1;var c=CKEDITOR.tools.extend({},b.panel,{css:[CKEDITOR.skin.getPath(\"editor\")],level:this._.level-1,block:{}}),k=c.block.attributes=c.attributes||{};!k.role&&(k.role=\"menu\");this._.panelDefinition=c},_:{onShow:function(){var a=\nthis.editor.getSelection(),b=a&&a.getStartElement(),c=this.editor.elementPath(),k=this._.listeners;this.removeAll();for(var e=0;e<k.length;e++){var j=k[e](b,a,c);if(j)for(var i in j){var f=this.editor.getMenuItem(i);if(f&&(!f.command||this.editor.getCommand(f.command).state))f.state=j[i],this.add(f)}}},onClick:function(a){this.hide();if(a.onClick)a.onClick();else a.command&&this.editor.execCommand(a.command)},onEscape:function(a){var b=this.parent;b?b._.panel.hideChild(1):27==a&&this.hide(1);return!1},\nonHide:function(){this.onHide&&this.onHide()},showSubMenu:function(a){var b=this._.subMenu,c=this.items[a];if(c=c.getItems&&c.getItems()){b?b.removeAll():(b=this._.subMenu=new CKEDITOR.menu(this.editor,CKEDITOR.tools.extend({},this._.definition,{level:this._.level+1},!0)),b.parent=this,b._.onClick=CKEDITOR.tools.bind(this._.onClick,this));for(var k in c){var e=this.editor.getMenuItem(k);e&&(e.state=c[k],b.add(e))}var j=this._.panel.getBlock(this.id).element.getDocument().getById(this.id+(\"\"+a));setTimeout(function(){b.show(j,\n2)},0)}else this._.panel.hideChild(1)}},proto:{add:function(a){a.order||(a.order=this.items.length);this.items.push(a)},removeAll:function(){this.items=[]},show:function(a,b,c,k){if(!this.parent&&(this._.onShow(),!this.items.length))return;var b=b||(\"rtl\"==this.editor.lang.dir?2:1),e=this.items,j=this.editor,i=this._.panel,f=this._.element;if(!i){i=this._.panel=new CKEDITOR.ui.floatPanel(this.editor,CKEDITOR.document.getBody(),this._.panelDefinition,this._.level);i.onEscape=CKEDITOR.tools.bind(function(a){if(!1===\nthis._.onEscape(a))return!1},this);i.onShow=function(){i._.panel.getHolderElement().getParent().addClass(\"cke cke_reset_all\")};i.onHide=CKEDITOR.tools.bind(function(){this._.onHide&&this._.onHide()},this);f=i.addBlock(this.id,this._.panelDefinition.block);f.autoSize=!0;var d=f.keys;d[40]=\"next\";d[9]=\"next\";d[38]=\"prev\";d[CKEDITOR.SHIFT+9]=\"prev\";d[\"rtl\"==j.lang.dir?37:39]=CKEDITOR.env.ie?\"mouseup\":\"click\";d[32]=CKEDITOR.env.ie?\"mouseup\":\"click\";CKEDITOR.env.ie&&(d[13]=\"mouseup\");f=this._.element=\nf.element;d=f.getDocument();d.getBody().setStyle(\"overflow\",\"hidden\");d.getElementsByTag(\"html\").getItem(0).setStyle(\"overflow\",\"hidden\");this._.itemOverFn=CKEDITOR.tools.addFunction(function(a){clearTimeout(this._.showSubTimeout);this._.showSubTimeout=CKEDITOR.tools.setTimeout(this._.showSubMenu,j.config.menu_subMenuDelay||400,this,[a])},this);this._.itemOutFn=CKEDITOR.tools.addFunction(function(){clearTimeout(this._.showSubTimeout)},this);this._.itemClickFn=CKEDITOR.tools.addFunction(function(a){var b=\nthis.items[a];if(b.state==CKEDITOR.TRISTATE_DISABLED)this.hide(1);else if(b.getItems)this._.showSubMenu(a);else this._.onClick(b)},this)}g(e);for(var d=j.elementPath(),d=['<div class=\"cke_menu'+(d&&d.direction()!=j.lang.dir?\" cke_mixed_dir_content\":\"\")+'\" role=\"presentation\">'],h=e.length,m=h&&e[0].group,l=0;l<h;l++){var n=e[l];m!=n.group&&(d.push('<div class=\"cke_menuseparator\" role=\"separator\"></div>'),m=n.group);n.render(this,l,d)}d.push(\"</div>\");f.setHtml(d.join(\"\"));CKEDITOR.ui.fire(\"ready\",\nthis);this.parent?this.parent._.panel.showAsChild(i,this.id,a,b,c,k):i.showBlock(this.id,a,b,c,k);j.fire(\"menuShow\",[i])},addListener:function(a){this._.listeners.push(a)},hide:function(a){this._.onHide&&this._.onHide();this._.panel&&this._.panel.hide(a)}}});CKEDITOR.menuItem=CKEDITOR.tools.createClass({$:function(a,b,c){CKEDITOR.tools.extend(this,c,{order:0,className:\"cke_menubutton__\"+b});this.group=a._.menuGroups[this.group];this.editor=a;this.name=b},proto:{render:function(a,b,c){var h=a.id+(\"\"+\nb),e=\"undefined\"==typeof this.state?CKEDITOR.TRISTATE_OFF:this.state,j=\"\",i=e==CKEDITOR.TRISTATE_ON?\"on\":e==CKEDITOR.TRISTATE_DISABLED?\"disabled\":\"off\";this.role in{menuitemcheckbox:1,menuitemradio:1}&&(j=' aria-checked=\"'+(e==CKEDITOR.TRISTATE_ON?\"true\":\"false\")+'\"');var f=this.getItems,d=\"&#\"+(\"rtl\"==this.editor.lang.dir?\"9668\":\"9658\")+\";\",g=this.name;this.icon&&!/\\./.test(this.icon)&&(g=this.icon);a={id:h,name:this.name,iconName:g,label:this.label,cls:this.className||\"\",state:i,hasPopup:f?\"true\":\n\"false\",disabled:e==CKEDITOR.TRISTATE_DISABLED,title:this.label,href:\"javascript:void('\"+(this.label||\"\").replace(\"'\")+\"')\",hoverFn:a._.itemOverFn,moveOutFn:a._.itemOutFn,clickFn:a._.itemClickFn,index:b,iconStyle:CKEDITOR.skin.getIconStyle(g,\"rtl\"==this.editor.lang.dir,g==this.icon?null:this.icon,this.iconOffset),arrowHtml:f?l.output({label:d}):\"\",role:this.role?this.role:\"menuitem\",ariaChecked:j};m.output(a,c)}}})})();CKEDITOR.config.menu_groups=\"clipboard,form,tablecell,tablecellproperties,tablerow,tablecolumn,table,anchor,link,image,flash,checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea,div\";CKEDITOR.plugins.add(\"contextmenu\",{requires:\"menu\",onLoad:function(){CKEDITOR.plugins.contextMenu=CKEDITOR.tools.createClass({base:CKEDITOR.menu,$:function(a){this.base.call(this,a,{panel:{className:\"cke_menu_panel\",attributes:{\"aria-label\":a.lang.contextmenu.options}}})},proto:{addTarget:function(a,c){a.on(\"contextmenu\",function(a){var a=a.data,b=CKEDITOR.env.webkit?d:CKEDITOR.env.mac?a.$.metaKey:a.$.ctrlKey;if(!c||!b){a.preventDefault();var e=a.getTarget().getDocument(),f=a.getTarget().getDocument().getDocumentElement(),\nb=!e.equals(CKEDITOR.document),e=e.getWindow().getScrollPosition(),g=b?a.$.clientX:a.$.pageX||e.x+a.$.clientX,h=b?a.$.clientY:a.$.pageY||e.y+a.$.clientY;CKEDITOR.tools.setTimeout(function(){this.open(f,null,g,h)},CKEDITOR.env.ie?200:0,this)}},this);if(CKEDITOR.env.webkit){var d,b=function(){d=0};a.on(\"keydown\",function(a){d=CKEDITOR.env.mac?a.data.$.metaKey:a.data.$.ctrlKey});a.on(\"keyup\",b);a.on(\"contextmenu\",b)}},open:function(a,c,d,b){this.editor.focus();a=a||CKEDITOR.document.getDocumentElement();\nthis.editor.selectionChange(1);this.show(a,c,d,b)}}})},beforeInit:function(a){var c=a.contextMenu=new CKEDITOR.plugins.contextMenu(a);a.on(\"contentDom\",function(){c.addTarget(a.editable(),!1!==a.config.browserContextMenuOnCtrl)});a.addCommand(\"contextMenu\",{exec:function(){a.contextMenu.open(a.document.getBody())}});a.setKeystroke(CKEDITOR.SHIFT+121,\"contextMenu\");a.setKeystroke(CKEDITOR.CTRL+CKEDITOR.SHIFT+121,\"contextMenu\")}});CKEDITOR.plugins.add(\"resize\",{init:function(b){var f,g,n,o,a=b.config,q=b.ui.spaceId(\"resizer\"),h=b.element?b.element.getDirection(1):\"ltr\";!a.resize_dir&&(a.resize_dir=\"vertical\");void 0==a.resize_maxWidth&&(a.resize_maxWidth=3E3);void 0==a.resize_maxHeight&&(a.resize_maxHeight=3E3);void 0==a.resize_minWidth&&(a.resize_minWidth=750);void 0==a.resize_minHeight&&(a.resize_minHeight=250);if(!1!==a.resize_enabled){var c=null,i=(\"both\"==a.resize_dir||\"horizontal\"==a.resize_dir)&&a.resize_minWidth!=a.resize_maxWidth,\nl=(\"both\"==a.resize_dir||\"vertical\"==a.resize_dir)&&a.resize_minHeight!=a.resize_maxHeight,j=function(d){var e=f,m=g,c=e+(d.data.$.screenX-n)*(\"rtl\"==h?-1:1),d=m+(d.data.$.screenY-o);i&&(e=Math.max(a.resize_minWidth,Math.min(c,a.resize_maxWidth)));l&&(m=Math.max(a.resize_minHeight,Math.min(d,a.resize_maxHeight)));b.resize(i?e:null,m)},k=function(){CKEDITOR.document.removeListener(\"mousemove\",j);CKEDITOR.document.removeListener(\"mouseup\",k);b.document&&(b.document.removeListener(\"mousemove\",j),b.document.removeListener(\"mouseup\",\nk))},p=CKEDITOR.tools.addFunction(function(d){c||(c=b.getResizable());f=c.$.offsetWidth||0;g=c.$.offsetHeight||0;n=d.screenX;o=d.screenY;a.resize_minWidth>f&&(a.resize_minWidth=f);a.resize_minHeight>g&&(a.resize_minHeight=g);CKEDITOR.document.on(\"mousemove\",j);CKEDITOR.document.on(\"mouseup\",k);b.document&&(b.document.on(\"mousemove\",j),b.document.on(\"mouseup\",k));d.preventDefault&&d.preventDefault()});b.on(\"destroy\",function(){CKEDITOR.tools.removeFunction(p)});b.on(\"uiSpace\",function(a){if(\"bottom\"==\na.data.space){var e=\"\";i&&!l&&(e=\" cke_resizer_horizontal\");!i&&l&&(e=\" cke_resizer_vertical\");var c='<span id=\"'+q+'\" class=\"cke_resizer'+e+\" cke_resizer_\"+h+'\" title=\"'+CKEDITOR.tools.htmlEncode(b.lang.common.resize)+'\" onmousedown=\"CKEDITOR.tools.callFunction('+p+', event)\">'+(\"ltr\"==h?\"◢\":\"◣\")+\"</span>\";\"ltr\"==h&&\"ltr\"==e?a.data.html+=c:a.data.html=c+a.data.html}},b,null,100);b.on(\"maximize\",function(a){b.ui.space(\"resizer\")[a.data==CKEDITOR.TRISTATE_ON?\"hide\":\"show\"]()})}}});(function(){var c='<a id=\"{id}\" class=\"cke_button cke_button__{name} cke_button_{state} {cls}\"'+(CKEDITOR.env.gecko&&10900<=CKEDITOR.env.version&&!CKEDITOR.env.hc?\"\":\" href=\\\"javascript:void('{titleJs}')\\\"\")+' title=\"{title}\" tabindex=\"-1\" hidefocus=\"true\" role=\"button\" aria-labelledby=\"{id}_label\" aria-haspopup=\"{hasArrow}\" aria-disabled=\"{ariaDisabled}\"';if(CKEDITOR.env.opera||CKEDITOR.env.gecko&&CKEDITOR.env.mac)c+=' onkeypress=\"return false;\"';CKEDITOR.env.gecko&&(c+=' onblur=\"this.style.cssText = this.style.cssText;\"');\nvar c=c+(' onkeydown=\"return CKEDITOR.tools.callFunction({keydownFn},event);\" onfocus=\"return CKEDITOR.tools.callFunction({focusFn},event);\"  onmousedown=\"return CKEDITOR.tools.callFunction({mousedownFn},event);\" '+(CKEDITOR.env.ie?'onclick=\"return false;\" onmouseup':\"onclick\")+'=\"CKEDITOR.tools.callFunction({clickFn},this);return false;\"><span class=\"cke_button_icon cke_button__{iconName}_icon\" style=\"{style}\"'),c=c+'>&nbsp;</span><span id=\"{id}_label\" class=\"cke_button_label cke_button__{name}_label\" aria-hidden=\"false\">{label}</span>{arrowHtml}</a>',\nm=CKEDITOR.addTemplate(\"buttonArrow\",'<span class=\"cke_button_arrow\">'+(CKEDITOR.env.hc?\"&#9660;\":\"\")+\"</span>\"),n=CKEDITOR.addTemplate(\"button\",c);CKEDITOR.plugins.add(\"button\",{beforeInit:function(a){a.ui.addHandler(CKEDITOR.UI_BUTTON,CKEDITOR.ui.button.handler)}});CKEDITOR.UI_BUTTON=\"button\";CKEDITOR.ui.button=function(a){CKEDITOR.tools.extend(this,a,{title:a.label,click:a.click||function(b){b.execCommand(a.command)}});this._={}};CKEDITOR.ui.button.handler={create:function(a){return new CKEDITOR.ui.button(a)}};\nCKEDITOR.ui.button.prototype={render:function(a,b){var c=CKEDITOR.env,i=this._.id=CKEDITOR.tools.getNextId(),f=\"\",e=this.command,l;this._.editor=a;var d={id:i,button:this,editor:a,focus:function(){CKEDITOR.document.getById(i).focus()},execute:function(){this.button.click(a)},attach:function(a){this.button.attach(a)}},o=CKEDITOR.tools.addFunction(function(a){if(d.onkey)return a=new CKEDITOR.dom.event(a),!1!==d.onkey(d,a.getKeystroke())}),p=CKEDITOR.tools.addFunction(function(a){var b;d.onfocus&&(b=\n!1!==d.onfocus(d,new CKEDITOR.dom.event(a)));CKEDITOR.env.gecko&&10900>CKEDITOR.env.version&&a.preventBubble();return b}),j=0,q=CKEDITOR.tools.addFunction(function(){if(CKEDITOR.env.opera){var b=a.editable();b.isInline()&&b.hasFocus&&(a.lockSelection(),j=1)}});d.clickFn=l=CKEDITOR.tools.addFunction(function(){j&&(a.unlockSelection(1),j=0);d.execute()});if(this.modes){var k={},g=function(){var b=a.mode;b&&(b=this.modes[b]?void 0!=k[b]?k[b]:CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED,b=a.readOnly&&\n!this.readOnly?CKEDITOR.TRISTATE_DISABLED:b,this.setState(b),this.refresh&&this.refresh())};a.on(\"beforeModeUnload\",function(){a.mode&&this._.state!=CKEDITOR.TRISTATE_DISABLED&&(k[a.mode]=this._.state)},this);a.on(\"activeFilterChange\",g,this);a.on(\"mode\",g,this);!this.readOnly&&a.on(\"readOnly\",g,this)}else if(e&&(e=a.getCommand(e)))e.on(\"state\",function(){this.setState(e.state)},this),f+=e.state==CKEDITOR.TRISTATE_ON?\"on\":e.state==CKEDITOR.TRISTATE_DISABLED?\"disabled\":\"off\";if(this.directional)a.on(\"contentDirChanged\",\nfunction(b){var c=CKEDITOR.document.getById(this._.id),d=c.getFirst(),b=b.data;b!=a.lang.dir?c.addClass(\"cke_\"+b):c.removeClass(\"cke_ltr\").removeClass(\"cke_rtl\");d.setAttribute(\"style\",CKEDITOR.skin.getIconStyle(h,\"rtl\"==b,this.icon,this.iconOffset))},this);e||(f+=\"off\");var h=g=this.name||this.command;this.icon&&!/\\./.test(this.icon)&&(h=this.icon,this.icon=null);c={id:i,name:g,iconName:h,label:this.label,cls:this.className||\"\",state:f,ariaDisabled:\"disabled\"==f?\"true\":\"false\",title:this.title,titleJs:c.gecko&&\n10900<=c.version&&!c.hc?\"\":(this.title||\"\").replace(\"'\",\"\"),hasArrow:this.hasArrow?\"true\":\"false\",keydownFn:o,mousedownFn:q,focusFn:p,clickFn:l,style:CKEDITOR.skin.getIconStyle(h,\"rtl\"==a.lang.dir,this.icon,this.iconOffset),arrowHtml:this.hasArrow?m.output():\"\"};n.output(c,b);if(this.onRender)this.onRender();return d},setState:function(a){if(this._.state==a)return!1;this._.state=a;var b=CKEDITOR.document.getById(this._.id);return b?(b.setState(a,\"cke_button\"),a==CKEDITOR.TRISTATE_DISABLED?b.setAttribute(\"aria-disabled\",\n!0):b.removeAttribute(\"aria-disabled\"),a==CKEDITOR.TRISTATE_ON?b.setAttribute(\"aria-pressed\",!0):b.removeAttribute(\"aria-pressed\"),!0):!1},getState:function(){return this._.state},toFeature:function(a){if(this._.feature)return this._.feature;var b=this;!this.allowedContent&&(!this.requiredContent&&this.command)&&(b=a.getCommand(this.command)||b);return this._.feature=b}};CKEDITOR.ui.prototype.addButton=function(a,b){this.add(a,CKEDITOR.UI_BUTTON,b)}})();(function(){function w(a){function d(){for(var b=g(),e=CKEDITOR.tools.clone(a.config.toolbarGroups)||n(a),f=0;f<e.length;f++){var k=e[f];if(\"/\"!=k){\"string\"==typeof k&&(k=e[f]={name:k});var i,d=k.groups;if(d)for(var h=0;h<d.length;h++)i=d[h],(i=b[i])&&c(k,i);(i=b[k.name])&&c(k,i)}}return e}function g(){var b={},c,f,e;for(c in a.ui.items)f=a.ui.items[c],e=f.toolbar||\"others\",e=e.split(\",\"),f=e[0],e=parseInt(e[1]||-1,10),b[f]||(b[f]=[]),b[f].push({name:c,order:e});for(f in b)b[f]=b[f].sort(function(b,\na){return b.order==a.order?0:0>a.order?-1:0>b.order?1:b.order<a.order?-1:1});return b}function c(c,e){if(e.length){c.items?c.items.push(a.ui.create(\"-\")):c.items=[];for(var f;f=e.shift();)if(f=\"string\"==typeof f?f:f.name,!b||-1==CKEDITOR.tools.indexOf(b,f))(f=a.ui.create(f))&&a.addFeature(f)&&c.items.push(f)}}function h(b){var a=[],e,d,h;for(e=0;e<b.length;++e)d=b[e],h={},\"/\"==d?a.push(d):CKEDITOR.tools.isArray(d)?(c(h,CKEDITOR.tools.clone(d)),a.push(h)):d.items&&(c(h,CKEDITOR.tools.clone(d.items)),\nh.name=d.name,a.push(h));return a}var b=a.config.removeButtons,b=b&&b.split(\",\"),e=a.config.toolbar;\"string\"==typeof e&&(e=a.config[\"toolbar_\"+e]);return a.toolbar=e?h(e):d()}function n(a){return a._.toolbarGroups||(a._.toolbarGroups=[{name:\"document\",groups:[\"mode\",\"document\",\"doctools\"]},{name:\"clipboard\",groups:[\"clipboard\",\"undo\"]},{name:\"editing\",groups:[\"find\",\"selection\",\"spellchecker\"]},{name:\"forms\"},\"/\",{name:\"basicstyles\",groups:[\"basicstyles\",\"cleanup\"]},{name:\"paragraph\",groups:[\"list\",\n\"indent\",\"blocks\",\"align\",\"bidi\"]},{name:\"links\"},{name:\"insert\"},\"/\",{name:\"styles\"},{name:\"colors\"},{name:\"tools\"},{name:\"others\"},{name:\"about\"}])}var u=function(){this.toolbars=[];this.focusCommandExecuted=!1};u.prototype.focus=function(){for(var a=0,d;d=this.toolbars[a++];)for(var g=0,c;c=d.items[g++];)if(c.focus){c.focus();return}};var x={modes:{wysiwyg:1,source:1},readOnly:1,exec:function(a){a.toolbox&&(a.toolbox.focusCommandExecuted=!0,CKEDITOR.env.ie||CKEDITOR.env.air?setTimeout(function(){a.toolbox.focus()},\n100):a.toolbox.focus())}};CKEDITOR.plugins.add(\"toolbar\",{requires:\"button\",init:function(a){var d,g=function(c,h){var b,e=\"rtl\"==a.lang.dir,j=a.config.toolbarGroupCycling,o=e?37:39,e=e?39:37,j=void 0===j||j;switch(h){case 9:case CKEDITOR.SHIFT+9:for(;!b||!b.items.length;)if(b=9==h?(b?b.next:c.toolbar.next)||a.toolbox.toolbars[0]:(b?b.previous:c.toolbar.previous)||a.toolbox.toolbars[a.toolbox.toolbars.length-1],b.items.length)for(c=b.items[d?b.items.length-1:0];c&&!c.focus;)(c=d?c.previous:c.next)||\n(b=0);c&&c.focus();return!1;case o:b=c;do b=b.next,!b&&j&&(b=c.toolbar.items[0]);while(b&&!b.focus);b?b.focus():g(c,9);return!1;case 40:return c.button&&c.button.hasArrow?(a.once(\"panelShow\",function(b){b.data._.panel._.currentBlock.onKeyDown(40)}),c.execute()):g(c,40==h?o:e),!1;case e:case 38:b=c;do b=b.previous,!b&&j&&(b=c.toolbar.items[c.toolbar.items.length-1]);while(b&&!b.focus);b?b.focus():(d=1,g(c,CKEDITOR.SHIFT+9),d=0);return!1;case 27:return a.focus(),!1;case 13:case 32:return c.execute(),\n!1}return!0};a.on(\"uiSpace\",function(c){if(c.data.space==a.config.toolbarLocation){c.removeListener();a.toolbox=new u;var d=CKEDITOR.tools.getNextId(),b=['<span id=\"',d,'\" class=\"cke_voice_label\">',a.lang.toolbar.toolbars,\"</span>\",'<span id=\"'+a.ui.spaceId(\"toolbox\")+'\" class=\"cke_toolbox\" role=\"group\" aria-labelledby=\"',d,'\" onmousedown=\"return false;\">'],d=!1!==a.config.toolbarStartupExpanded,e,j;a.config.toolbarCanCollapse&&a.elementMode!=CKEDITOR.ELEMENT_MODE_INLINE&&b.push('<span class=\"cke_toolbox_main\"'+\n(d?\">\":' style=\"display:none\">'));for(var o=a.toolbox.toolbars,f=w(a),k=0;k<f.length;k++){var i,l=0,r,m=f[k],s;if(m)if(e&&(b.push(\"</span>\"),j=e=0),\"/\"===m)b.push('<span class=\"cke_toolbar_break\"></span>');else{s=m.items||m;for(var t=0;t<s.length;t++){var p=s[t],n;if(p)if(p.type==CKEDITOR.UI_SEPARATOR)j=e&&p;else{n=!1!==p.canGroup;if(!l){i=CKEDITOR.tools.getNextId();l={id:i,items:[]};r=m.name&&(a.lang.toolbar.toolbarGroups[m.name]||m.name);b.push('<span id=\"',i,'\" class=\"cke_toolbar\"',r?' aria-labelledby=\"'+\ni+'_label\"':\"\",' role=\"toolbar\">');r&&b.push('<span id=\"',i,'_label\" class=\"cke_voice_label\">',r,\"</span>\");b.push('<span class=\"cke_toolbar_start\"></span>');var q=o.push(l)-1;0<q&&(l.previous=o[q-1],l.previous.next=l)}n?e||(b.push('<span class=\"cke_toolgroup\" role=\"presentation\">'),e=1):e&&(b.push(\"</span>\"),e=0);i=function(c){c=c.render(a,b);q=l.items.push(c)-1;if(q>0){c.previous=l.items[q-1];c.previous.next=c}c.toolbar=l;c.onkey=g;c.onfocus=function(){a.toolbox.focusCommandExecuted||a.focus()}};\nj&&(i(j),j=0);i(p)}}e&&(b.push(\"</span>\"),j=e=0);l&&b.push('<span class=\"cke_toolbar_end\"></span></span>')}}a.config.toolbarCanCollapse&&b.push(\"</span>\");if(a.config.toolbarCanCollapse&&a.elementMode!=CKEDITOR.ELEMENT_MODE_INLINE){var v=CKEDITOR.tools.addFunction(function(){a.execCommand(\"toolbarCollapse\")});a.on(\"destroy\",function(){CKEDITOR.tools.removeFunction(v)});a.addCommand(\"toolbarCollapse\",{readOnly:1,exec:function(b){var a=b.ui.space(\"toolbar_collapser\"),c=a.getPrevious(),e=b.ui.space(\"contents\"),\nd=c.getParent(),f=parseInt(e.$.style.height,10),h=d.$.offsetHeight,g=a.hasClass(\"cke_toolbox_collapser_min\");g?(c.show(),a.removeClass(\"cke_toolbox_collapser_min\"),a.setAttribute(\"title\",b.lang.toolbar.toolbarCollapse)):(c.hide(),a.addClass(\"cke_toolbox_collapser_min\"),a.setAttribute(\"title\",b.lang.toolbar.toolbarExpand));a.getFirst().setText(g?\"▲\":\"◀\");e.setStyle(\"height\",f-(d.$.offsetHeight-h)+\"px\");b.fire(\"resize\")},modes:{wysiwyg:1,source:1}});a.setKeystroke(CKEDITOR.ALT+(CKEDITOR.env.ie||CKEDITOR.env.webkit?\n189:109),\"toolbarCollapse\");b.push('<a title=\"'+(d?a.lang.toolbar.toolbarCollapse:a.lang.toolbar.toolbarExpand)+'\" id=\"'+a.ui.spaceId(\"toolbar_collapser\")+'\" tabIndex=\"-1\" class=\"cke_toolbox_collapser');d||b.push(\" cke_toolbox_collapser_min\");b.push('\" onclick=\"CKEDITOR.tools.callFunction('+v+')\">','<span class=\"cke_arrow\">&#9650;</span>',\"</a>\")}b.push(\"</span>\");c.data.html+=b.join(\"\")}});a.on(\"destroy\",function(){if(this.toolbox){var a,d=0,b,e,g;for(a=this.toolbox.toolbars;d<a.length;d++){e=a[d].items;\nfor(b=0;b<e.length;b++)g=e[b],g.clickFn&&CKEDITOR.tools.removeFunction(g.clickFn),g.keyDownFn&&CKEDITOR.tools.removeFunction(g.keyDownFn)}}});a.on(\"uiReady\",function(){var c=a.ui.space(\"toolbox\");c&&a.focusManager.add(c,1)});a.addCommand(\"toolbarFocus\",x);a.setKeystroke(CKEDITOR.ALT+121,\"toolbarFocus\");a.ui.add(\"-\",CKEDITOR.UI_SEPARATOR,{});a.ui.addHandler(CKEDITOR.UI_SEPARATOR,{create:function(){return{render:function(a,d){d.push('<span class=\"cke_toolbar_separator\" role=\"separator\"></span>');return{}}}}})}});\nCKEDITOR.ui.prototype.addToolbarGroup=function(a,d,g){var c=n(this.editor),h=0===d,b={name:a};if(g){if(g=CKEDITOR.tools.search(c,function(a){return a.name==g})){!g.groups&&(g.groups=[]);if(d&&(d=CKEDITOR.tools.indexOf(g.groups,d),0<=d)){g.groups.splice(d+1,0,a);return}h?g.groups.splice(0,0,a):g.groups.push(a);return}d=null}d&&(d=CKEDITOR.tools.indexOf(c,function(a){return a.name==d}));h?c.splice(0,0,a):\"number\"==typeof d?c.splice(d+1,0,b):c.push(a)}})();CKEDITOR.UI_SEPARATOR=\"separator\";\nCKEDITOR.config.toolbarLocation=\"top\";(function(){var k;function n(a,c){function j(d){d=i.list[d];if(d.equals(a.editable())||\"true\"==d.getAttribute(\"contenteditable\")){var e=a.createRange();e.selectNodeContents(d);e.select()}else a.getSelection().selectElement(d);a.focus()}function s(){l&&l.setHtml(o);delete i.list}var m=a.ui.spaceId(\"path\"),l,i=a._.elementsPath,n=i.idBase;c.html+='<span id=\"'+m+'_label\" class=\"cke_voice_label\">'+a.lang.elementspath.eleLabel+'</span><span id=\"'+m+'\" class=\"cke_path\" role=\"group\" aria-labelledby=\"'+m+\n'_label\">'+o+\"</span>\";a.on(\"uiReady\",function(){var d=a.ui.space(\"path\");d&&a.focusManager.add(d,1)});i.onClick=j;var t=CKEDITOR.tools.addFunction(j),u=CKEDITOR.tools.addFunction(function(d,e){var g=i.idBase,b,e=new CKEDITOR.dom.event(e);b=\"rtl\"==a.lang.dir;switch(e.getKeystroke()){case b?39:37:case 9:return(b=CKEDITOR.document.getById(g+(d+1)))||(b=CKEDITOR.document.getById(g+\"0\")),b.focus(),!1;case b?37:39:case CKEDITOR.SHIFT+9:return(b=CKEDITOR.document.getById(g+(d-1)))||(b=CKEDITOR.document.getById(g+\n(i.list.length-1))),b.focus(),!1;case 27:return a.focus(),!1;case 13:case 32:return j(d),!1}return!0});a.on(\"selectionChange\",function(){a.editable();for(var d=[],e=i.list=[],g=[],b=i.filters,c=!0,j=a.elementPath().elements,f,k=j.length;k--;){var h=j[k],p=0;f=h.data(\"cke-display-name\")?h.data(\"cke-display-name\"):h.data(\"cke-real-element-type\")?h.data(\"cke-real-element-type\"):h.getName();c=h.hasAttribute(\"contenteditable\")?\"true\"==h.getAttribute(\"contenteditable\"):c;!c&&!h.hasAttribute(\"contenteditable\")&&\n(p=1);for(var q=0;q<b.length;q++){var r=b[q](h,f);if(!1===r){p=1;break}f=r||f}p||(e.unshift(h),g.unshift(f))}e=e.length;for(b=0;b<e;b++)f=g[b],c=a.lang.elementspath.eleTitle.replace(/%1/,f),f=v.output({id:n+b,label:c,text:f,jsTitle:\"javascript:void('\"+f+\"')\",index:b,keyDownFn:u,clickFn:t}),d.unshift(f);l||(l=CKEDITOR.document.getById(m));g=l;g.setHtml(d.join(\"\")+o);a.fire(\"elementsPathUpdate\",{space:g})});a.on(\"readOnly\",s);a.on(\"contentDomUnload\",s);a.addCommand(\"elementsPathFocus\",k);a.setKeystroke(CKEDITOR.ALT+\n122,\"elementsPathFocus\")}k={editorFocus:!1,readOnly:1,exec:function(a){(a=CKEDITOR.document.getById(a._.elementsPath.idBase+\"0\"))&&a.focus(CKEDITOR.env.ie||CKEDITOR.env.air)}};var o='<span class=\"cke_path_empty\">&nbsp;</span>',c=\"\";if(CKEDITOR.env.opera||CKEDITOR.env.gecko&&CKEDITOR.env.mac)c+=' onkeypress=\"return false;\"';CKEDITOR.env.gecko&&(c+=' onblur=\"this.style.cssText = this.style.cssText;\"');var v=CKEDITOR.addTemplate(\"pathItem\",'<a id=\"{id}\" href=\"{jsTitle}\" tabindex=\"-1\" class=\"cke_path_item\" title=\"{label}\"'+\n(CKEDITOR.env.gecko&&10900>CKEDITOR.env.version?' onfocus=\"event.preventBubble();\"':\"\")+c+' hidefocus=\"true\"  onkeydown=\"return CKEDITOR.tools.callFunction({keyDownFn},{index}, event );\" onclick=\"CKEDITOR.tools.callFunction({clickFn},{index}); return false;\" role=\"button\" aria-label=\"{label}\">{text}</a>');CKEDITOR.plugins.add(\"elementspath\",{init:function(a){a._.elementsPath={idBase:\"cke_elementspath_\"+CKEDITOR.tools.getNextNumber()+\"_\",filters:[]};a.on(\"uiSpace\",function(c){\"bottom\"==c.data.space&&\nn(a,c.data)})}})})();(function(){function l(e,c,b){b=e.config.forceEnterMode||b;\"wysiwyg\"==e.mode&&(c||(c=e.activeEnterMode),e.elementPath().isContextFor(\"p\")||(c=CKEDITOR.ENTER_BR,b=1),e.fire(\"saveSnapshot\"),c==CKEDITOR.ENTER_BR?o(e,c,null,b):p(e,c,null,b),e.fire(\"saveSnapshot\"))}function q(e){for(var e=e.getSelection().getRanges(!0),c=e.length-1;0<c;c--)e[c].deleteContents();return e[0]}CKEDITOR.plugins.add(\"enterkey\",{init:function(e){e.addCommand(\"enter\",{modes:{wysiwyg:1},editorFocus:!1,exec:function(c){l(c)}});\ne.addCommand(\"shiftEnter\",{modes:{wysiwyg:1},editorFocus:!1,exec:function(c){l(c,c.activeShiftEnterMode,1)}});e.setKeystroke([[13,\"enter\"],[CKEDITOR.SHIFT+13,\"shiftEnter\"]])}});var t=CKEDITOR.dom.walker.whitespaces(),u=CKEDITOR.dom.walker.bookmark();CKEDITOR.plugins.enterkey={enterBlock:function(e,c,b,i){if(b=b||q(e)){var f=b.document,j=b.checkStartOfBlock(),h=b.checkEndOfBlock(),a=e.elementPath(b.startContainer).block,k=c==CKEDITOR.ENTER_DIV?\"div\":\"p\",d;if(j&&h){if(a&&(a.is(\"li\")||a.getParent().is(\"li\"))){b=\na.getParent();d=b.getParent();var i=!a.hasPrevious(),m=!a.hasNext(),k=e.getSelection(),g=k.createBookmarks(),j=a.getDirection(1),h=a.getAttribute(\"class\"),n=a.getAttribute(\"style\"),l=d.getDirection(1)!=j,e=e.enterMode!=CKEDITOR.ENTER_BR||l||n||h;if(d.is(\"li\"))if(i||m)a[i?\"insertBefore\":\"insertAfter\"](d);else a.breakParent(d);else{if(e)if(d=f.createElement(c==CKEDITOR.ENTER_P?\"p\":\"div\"),l&&d.setAttribute(\"dir\",j),n&&d.setAttribute(\"style\",n),h&&d.setAttribute(\"class\",h),a.moveChildren(d),i||m)d[i?\n\"insertBefore\":\"insertAfter\"](b);else a.breakParent(b),d.insertAfter(b);else if(a.appendBogus(!0),i||m)for(;f=a[i?\"getFirst\":\"getLast\"]();)f[i?\"insertBefore\":\"insertAfter\"](b);else for(a.breakParent(b);f=a.getLast();)f.insertAfter(b);a.remove()}k.selectBookmarks(g);return}if(a&&a.getParent().is(\"blockquote\")){a.breakParent(a.getParent());a.getPrevious().getFirst(CKEDITOR.dom.walker.invisible(1))||a.getPrevious().remove();a.getNext().getFirst(CKEDITOR.dom.walker.invisible(1))||a.getNext().remove();\nb.moveToElementEditStart(a);b.select();return}}else if(a&&a.is(\"pre\")&&!h){o(e,c,b,i);return}if(h=b.splitBlock(k)){c=h.previousBlock;a=h.nextBlock;e=h.wasStartOfBlock;j=h.wasEndOfBlock;if(a)g=a.getParent(),g.is(\"li\")&&(a.breakParent(g),a.move(a.getNext(),1));else if(c&&(g=c.getParent())&&g.is(\"li\"))c.breakParent(g),g=c.getNext(),b.moveToElementEditStart(g),c.move(c.getPrevious());if(!e&&!j)a.is(\"li\")&&(d=b.clone(),d.selectNodeContents(a),d=new CKEDITOR.dom.walker(d),d.evaluator=function(a){return!(u(a)||\nt(a)||a.type==CKEDITOR.NODE_ELEMENT&&a.getName()in CKEDITOR.dtd.$inline&&!(a.getName()in CKEDITOR.dtd.$empty))},(g=d.next())&&(g.type==CKEDITOR.NODE_ELEMENT&&g.is(\"ul\",\"ol\"))&&(CKEDITOR.env.needsBrFiller?f.createElement(\"br\"):f.createText(\" \")).insertBefore(g)),a&&b.moveToElementEditStart(a);else{if(c){if(c.is(\"li\")||!r.test(c.getName())&&!c.is(\"pre\"))d=c.clone()}else a&&(d=a.clone());d?i&&!d.is(\"li\")&&d.renameNode(k):g&&g.is(\"li\")?d=g:(d=f.createElement(k),c&&(m=c.getDirection())&&d.setAttribute(\"dir\",\nm));if(f=h.elementPath){i=0;for(k=f.elements.length;i<k;i++){g=f.elements[i];if(g.equals(f.block)||g.equals(f.blockLimit))break;CKEDITOR.dtd.$removeEmpty[g.getName()]&&(g=g.clone(),d.moveChildren(g),d.append(g))}}d.appendBogus();d.getParent()||b.insertNode(d);d.is(\"li\")&&d.removeAttribute(\"value\");if(CKEDITOR.env.ie&&e&&(!j||!c.getChildCount()))b.moveToElementEditStart(j?c:d),b.select();b.moveToElementEditStart(e&&!j?a:d)}b.select();b.scrollIntoView()}}},enterBr:function(e,c,b,i){if(b=b||q(e)){var f=\nb.document,j=b.checkEndOfBlock(),h=new CKEDITOR.dom.elementPath(e.getSelection().getStartElement()),a=h.block,h=a&&h.block.getName();!i&&\"li\"==h?p(e,c,b,i):(!i&&j&&r.test(h)?(j=a.getDirection())?(f=f.createElement(\"div\"),f.setAttribute(\"dir\",j),f.insertAfter(a),b.setStart(f,0)):(f.createElement(\"br\").insertAfter(a),CKEDITOR.env.gecko&&f.createText(\"\").insertAfter(a),b.setStartAt(a.getNext(),CKEDITOR.env.ie?CKEDITOR.POSITION_BEFORE_START:CKEDITOR.POSITION_AFTER_START)):(a=\"pre\"==h&&CKEDITOR.env.ie&&\n8>CKEDITOR.env.version?f.createText(\"\\r\"):f.createElement(\"br\"),b.deleteContents(),b.insertNode(a),CKEDITOR.env.needsBrFiller?(f.createText(\"﻿\").insertAfter(a),j&&a.getParent().appendBogus(),a.getNext().$.nodeValue=\"\",b.setStartAt(a.getNext(),CKEDITOR.POSITION_AFTER_START)):b.setStartAt(a,CKEDITOR.POSITION_AFTER_END)),b.collapse(!0),b.select(),b.scrollIntoView())}}};var s=CKEDITOR.plugins.enterkey,o=s.enterBr,p=s.enterBlock,r=/^h[1-6]$/})();(function(){function j(a,b){var d={},e=[],f={nbsp:\" \",shy:\"­\",gt:\">\",lt:\"<\",amp:\"&\",apos:\"'\",quot:'\"'},a=a.replace(/\\b(nbsp|shy|gt|lt|amp|apos|quot)(?:,|$)/g,function(a,h){var c=b?\"&\"+h+\";\":f[h];d[c]=b?f[h]:\"&\"+h+\";\";e.push(c);return\"\"});if(!b&&a){var a=a.split(\",\"),c=document.createElement(\"div\"),g;c.innerHTML=\"&\"+a.join(\";&\")+\";\";g=c.innerHTML;c=null;for(c=0;c<g.length;c++){var i=g.charAt(c);d[i]=\"&\"+a[c]+\";\";e.push(i)}}d.regex=e.join(b?\"|\":\"\");return d}CKEDITOR.plugins.add(\"entities\",{afterInit:function(a){var b=\na.config;if(a=(a=a.dataProcessor)&&a.htmlFilter){var d=[];!1!==b.basicEntities&&d.push(\"nbsp,gt,lt,amp\");b.entities&&(d.length&&d.push(\"quot,iexcl,cent,pound,curren,yen,brvbar,sect,uml,copy,ordf,laquo,not,shy,reg,macr,deg,plusmn,sup2,sup3,acute,micro,para,middot,cedil,sup1,ordm,raquo,frac14,frac12,frac34,iquest,times,divide,fnof,bull,hellip,prime,Prime,oline,frasl,weierp,image,real,trade,alefsym,larr,uarr,rarr,darr,harr,crarr,lArr,uArr,rArr,dArr,hArr,forall,part,exist,empty,nabla,isin,notin,ni,prod,sum,minus,lowast,radic,prop,infin,ang,and,or,cap,cup,int,there4,sim,cong,asymp,ne,equiv,le,ge,sub,sup,nsub,sube,supe,oplus,otimes,perp,sdot,lceil,rceil,lfloor,rfloor,lang,rang,loz,spades,clubs,hearts,diams,circ,tilde,ensp,emsp,thinsp,zwnj,zwj,lrm,rlm,ndash,mdash,lsquo,rsquo,sbquo,ldquo,rdquo,bdquo,dagger,Dagger,permil,lsaquo,rsaquo,euro\"),\nb.entities_latin&&d.push(\"Agrave,Aacute,Acirc,Atilde,Auml,Aring,AElig,Ccedil,Egrave,Eacute,Ecirc,Euml,Igrave,Iacute,Icirc,Iuml,ETH,Ntilde,Ograve,Oacute,Ocirc,Otilde,Ouml,Oslash,Ugrave,Uacute,Ucirc,Uuml,Yacute,THORN,szlig,agrave,aacute,acirc,atilde,auml,aring,aelig,ccedil,egrave,eacute,ecirc,euml,igrave,iacute,icirc,iuml,eth,ntilde,ograve,oacute,ocirc,otilde,ouml,oslash,ugrave,uacute,ucirc,uuml,yacute,thorn,yuml,OElig,oelig,Scaron,scaron,Yuml\"),b.entities_greek&&d.push(\"Alpha,Beta,Gamma,Delta,Epsilon,Zeta,Eta,Theta,Iota,Kappa,Lambda,Mu,Nu,Xi,Omicron,Pi,Rho,Sigma,Tau,Upsilon,Phi,Chi,Psi,Omega,alpha,beta,gamma,delta,epsilon,zeta,eta,theta,iota,kappa,lambda,mu,nu,xi,omicron,pi,rho,sigmaf,sigma,tau,upsilon,phi,chi,psi,omega,thetasym,upsih,piv\"),\nb.entities_additional&&d.push(b.entities_additional));var e=j(d.join(\",\")),f=e.regex?\"[\"+e.regex+\"]\":\"a^\";delete e.regex;b.entities&&b.entities_processNumerical&&(f=\"[^ -~]|\"+f);var f=RegExp(f,\"g\"),c=function(a){return b.entities_processNumerical==\"force\"||!e[a]?\"&#\"+a.charCodeAt(0)+\";\":e[a]},g=j(\"nbsp,gt,lt,amp,shy\",!0),i=RegExp(g.regex,\"g\"),k=function(a){return g[a]};a.addRules({text:function(a){return a.replace(i,k).replace(f,c)}},{applyToAll:!0})}}})})();CKEDITOR.config.basicEntities=!0;\nCKEDITOR.config.entities=!0;CKEDITOR.config.entities_latin=!0;CKEDITOR.config.entities_greek=!0;CKEDITOR.config.entities_additional=\"#39\";CKEDITOR.plugins.add(\"popup\");\nCKEDITOR.tools.extend(CKEDITOR.editor.prototype,{popup:function(e,a,b,d){a=a||\"80%\";b=b||\"70%\";\"string\"==typeof a&&(1<a.length&&\"%\"==a.substr(a.length-1,1))&&(a=parseInt(window.screen.width*parseInt(a,10)/100,10));\"string\"==typeof b&&(1<b.length&&\"%\"==b.substr(b.length-1,1))&&(b=parseInt(window.screen.height*parseInt(b,10)/100,10));640>a&&(a=640);420>b&&(b=420);var f=parseInt((window.screen.height-b)/2,10),g=parseInt((window.screen.width-a)/2,10),d=(d||\"location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable=yes,scrollbars=yes\")+\",width=\"+\na+\",height=\"+b+\",top=\"+f+\",left=\"+g,c=window.open(\"\",null,d,!0);if(!c)return!1;try{-1==navigator.userAgent.toLowerCase().indexOf(\" chrome/\")&&(c.moveTo(g,f),c.resizeTo(a,b)),c.focus(),c.location.href=e}catch(h){window.open(e,null,d,!0)}return!0}});(function(){function g(a,c){var d=[];if(c)for(var b in c)d.push(b+\"=\"+encodeURIComponent(c[b]));else return a;return a+(-1!=a.indexOf(\"?\")?\"&\":\"?\")+d.join(\"&\")}function i(a){a+=\"\";return a.charAt(0).toUpperCase()+a.substr(1)}function k(){var a=this.getDialog(),c=a.getParentEditor();c._.filebrowserSe=this;var d=c.config[\"filebrowser\"+i(a.getName())+\"WindowWidth\"]||c.config.filebrowserWindowWidth||\"80%\",a=c.config[\"filebrowser\"+i(a.getName())+\"WindowHeight\"]||c.config.filebrowserWindowHeight||\"70%\",\nb=this.filebrowser.params||{};b.CKEditor=c.name;b.CKEditorFuncNum=c._.filebrowserFn;b.langCode||(b.langCode=c.langCode);b=g(this.filebrowser.url,b);c.popup(b,d,a,c.config.filebrowserWindowFeatures||c.config.fileBrowserWindowFeatures)}function l(){var a=this.getDialog();a.getParentEditor()._.filebrowserSe=this;return!a.getContentElement(this[\"for\"][0],this[\"for\"][1]).getInputElement().$.value||!a.getContentElement(this[\"for\"][0],this[\"for\"][1]).getAction()?!1:!0}function m(a,c,d){var b=d.params||{};\nb.CKEditor=a.name;b.CKEditorFuncNum=a._.filebrowserFn;b.langCode||(b.langCode=a.langCode);c.action=g(d.url,b);c.filebrowser=d}function j(a,c,d,b){if(b&&b.length)for(var e,g=b.length;g--;)if(e=b[g],(\"hbox\"==e.type||\"vbox\"==e.type||\"fieldset\"==e.type)&&j(a,c,d,e.children),e.filebrowser)if(\"string\"==typeof e.filebrowser&&(e.filebrowser={action:\"fileButton\"==e.type?\"QuickUpload\":\"Browse\",target:e.filebrowser}),\"Browse\"==e.filebrowser.action){var f=e.filebrowser.url;void 0===f&&(f=a.config[\"filebrowser\"+\ni(c)+\"BrowseUrl\"],void 0===f&&(f=a.config.filebrowserBrowseUrl));f&&(e.onClick=k,e.filebrowser.url=f,e.hidden=!1)}else if(\"QuickUpload\"==e.filebrowser.action&&e[\"for\"]&&(f=e.filebrowser.url,void 0===f&&(f=a.config[\"filebrowser\"+i(c)+\"UploadUrl\"],void 0===f&&(f=a.config.filebrowserUploadUrl)),f)){var h=e.onClick;e.onClick=function(a){var b=a.sender;return h&&h.call(b,a)===false?false:l.call(b,a)};e.filebrowser.url=f;e.hidden=!1;m(a,d.getContents(e[\"for\"][0]).get(e[\"for\"][1]),e.filebrowser)}}function h(a,\nc,d){if(-1!==d.indexOf(\";\")){for(var d=d.split(\";\"),b=0;b<d.length;b++)if(h(a,c,d[b]))return!0;return!1}return(a=a.getContents(c).get(d).filebrowser)&&a.url}function n(a,c){var d=this._.filebrowserSe.getDialog(),b=this._.filebrowserSe[\"for\"],e=this._.filebrowserSe.filebrowser.onSelect;b&&d.getContentElement(b[0],b[1]).reset();if(!(\"function\"==typeof c&&!1===c.call(this._.filebrowserSe))&&!(e&&!1===e.call(this._.filebrowserSe,a,c))&&(\"string\"==typeof c&&c&&alert(c),a&&(b=this._.filebrowserSe,d=b.getDialog(),\nb=b.filebrowser.target||null)))if(b=b.split(\":\"),e=d.getContentElement(b[0],b[1]))e.setValue(a),d.selectPage(b[0])}CKEDITOR.plugins.add(\"filebrowser\",{requires:\"popup\",init:function(a){a._.filebrowserFn=CKEDITOR.tools.addFunction(n,a);a.on(\"destroy\",function(){CKEDITOR.tools.removeFunction(this._.filebrowserFn)})}});CKEDITOR.on(\"dialogDefinition\",function(a){if(a.editor.plugins.filebrowser)for(var c=a.data.definition,d,b=0;b<c.contents.length;++b)if(d=c.contents[b])j(a.editor,a.data.name,c,d.elements),\nd.hidden&&d.filebrowser&&(d.hidden=!h(c,d.id,d.filebrowser))})})();(function(){function q(a){var i=a.config,l=a.fire(\"uiSpace\",{space:\"top\",html:\"\"}).html,o=function(){function f(a,c,e){b.setStyle(c,t(e));b.setStyle(\"position\",a)}function e(a){var b=r.getDocumentPosition();switch(a){case \"top\":f(\"absolute\",\"top\",b.y-m-n);break;case \"pin\":f(\"fixed\",\"top\",q);break;case \"bottom\":f(\"absolute\",\"top\",b.y+(c.height||c.bottom-c.top)+n)}j=a}var j,r,k,c,h,m,s,l=i.floatSpaceDockedOffsetX||0,n=i.floatSpaceDockedOffsetY||0,p=i.floatSpacePinnedOffsetX||0,q=i.floatSpacePinnedOffsetY||\n0;return function(d){if(r=a.editable())if(d&&\"focus\"==d.name&&b.show(),b.removeStyle(\"left\"),b.removeStyle(\"right\"),k=b.getClientRect(),c=r.getClientRect(),h=g.getViewPaneSize(),m=k.height,s=\"pageXOffset\"in g.$?g.$.pageXOffset:CKEDITOR.document.$.documentElement.scrollLeft,j){m+n<=c.top?e(\"top\"):m+n>h.height-c.bottom?e(\"pin\"):e(\"bottom\");var d=h.width/2,d=0<c.left&&c.right<h.width&&c.width>k.width?\"rtl\"==a.config.contentsLangDirection?\"right\":\"left\":d-c.left>c.right-d?\"left\":\"right\",f;k.width>h.width?\n(d=\"left\",f=0):(f=\"left\"==d?0<c.left?c.left:0:c.right<h.width?h.width-c.right:0,f+k.width>h.width&&(d=\"left\"==d?\"right\":\"left\",f=0));b.setStyle(d,t((\"pin\"==j?p:l)+f+(\"pin\"==j?0:\"left\"==d?s:-s)))}else j=\"pin\",e(\"pin\"),o(d)}}();if(l){var b=CKEDITOR.document.getBody().append(CKEDITOR.dom.element.createFromHtml(u.output({content:l,id:a.id,langDir:a.lang.dir,langCode:a.langCode,name:a.name,style:\"display:none;z-index:\"+(i.baseFloatZIndex-1),topId:a.ui.spaceId(\"top\"),voiceLabel:a.lang.editorPanel+\", \"+\na.name}))),p=CKEDITOR.tools.eventsBuffer(500,o),e=CKEDITOR.tools.eventsBuffer(100,o);b.unselectable();b.on(\"mousedown\",function(a){a=a.data;a.getTarget().hasAscendant(\"a\",1)||a.preventDefault()});a.on(\"focus\",function(b){o(b);a.on(\"change\",p.input);g.on(\"scroll\",e.input);g.on(\"resize\",e.input)});a.on(\"blur\",function(){b.hide();a.removeListener(\"change\",p.input);g.removeListener(\"scroll\",e.input);g.removeListener(\"resize\",e.input)});a.on(\"destroy\",function(){g.removeListener(\"scroll\",e.input);g.removeListener(\"resize\",\ne.input);b.clearCustomData();b.remove()});a.focusManager.hasFocus&&b.show();a.focusManager.add(b,1)}}var u=CKEDITOR.addTemplate(\"floatcontainer\",'<div id=\"cke_{name}\" class=\"cke {id} cke_reset_all cke_chrome cke_editor_{name} cke_float cke_{langDir} '+CKEDITOR.env.cssClass+'\" dir=\"{langDir}\" title=\"'+(CKEDITOR.env.gecko?\" \":\"\")+'\" lang=\"{langCode}\" role=\"application\" style=\"{style}\" aria-labelledby=\"cke_{name}_arialbl\"><span id=\"cke_{name}_arialbl\" class=\"cke_voice_label\">{voiceLabel}</span><div class=\"cke_inner\"><div id=\"{topId}\" class=\"cke_top\" role=\"presentation\">{content}</div></div></div>'),\ng=CKEDITOR.document.getWindow(),t=CKEDITOR.tools.cssLength;CKEDITOR.plugins.add(\"floatingspace\",{init:function(a){a.on(\"loaded\",function(){q(this)},null,null,20)}})})();CKEDITOR.plugins.add(\"listblock\",{requires:\"panel\",onLoad:function(){var f=CKEDITOR.addTemplate(\"panel-list\",'<ul role=\"presentation\" class=\"cke_panel_list\">{items}</ul>'),g=CKEDITOR.addTemplate(\"panel-list-item\",'<li id=\"{id}\" class=\"cke_panel_listItem\" role=presentation><a id=\"{id}_option\" _cke_focus=1 hidefocus=true title=\"{title}\" href=\"javascript:void(\\'{val}\\')\"  {onclick}=\"CKEDITOR.tools.callFunction({clickFn},\\'{val}\\'); return false;\" role=\"option\">{text}</a></li>'),h=CKEDITOR.addTemplate(\"panel-list-group\",\n'<h1 id=\"{id}\" class=\"cke_panel_grouptitle\" role=\"presentation\" >{label}</h1>'),i=/\\'/g;CKEDITOR.ui.panel.prototype.addListBlock=function(a,b){return this.addBlock(a,new CKEDITOR.ui.listBlock(this.getHolderElement(),b))};CKEDITOR.ui.listBlock=CKEDITOR.tools.createClass({base:CKEDITOR.ui.panel.block,$:function(a,b){var b=b||{},c=b.attributes||(b.attributes={});(this.multiSelect=!!b.multiSelect)&&(c[\"aria-multiselectable\"]=!0);!c.role&&(c.role=\"listbox\");this.base.apply(this,arguments);this.element.setAttribute(\"role\",\nc.role);c=this.keys;c[40]=\"next\";c[9]=\"next\";c[38]=\"prev\";c[CKEDITOR.SHIFT+9]=\"prev\";c[32]=CKEDITOR.env.ie?\"mouseup\":\"click\";CKEDITOR.env.ie&&(c[13]=\"mouseup\");this._.pendingHtml=[];this._.pendingList=[];this._.items={};this._.groups={}},_:{close:function(){if(this._.started){var a=f.output({items:this._.pendingList.join(\"\")});this._.pendingList=[];this._.pendingHtml.push(a);delete this._.started}},getClick:function(){this._.click||(this._.click=CKEDITOR.tools.addFunction(function(a){var b=this.toggle(a);\nif(this.onClick)this.onClick(a,b)},this));return this._.click}},proto:{add:function(a,b,c){var d=CKEDITOR.tools.getNextId();this._.started||(this._.started=1,this._.size=this._.size||0);this._.items[a]=d;var e;e=CKEDITOR.tools.htmlEncodeAttr(a).replace(i,\"\\\\'\");a={id:d,val:e,onclick:CKEDITOR.env.ie?'onclick=\"return false;\" onmouseup':\"onclick\",clickFn:this._.getClick(),title:CKEDITOR.tools.htmlEncodeAttr(c||a),text:b||a};this._.pendingList.push(g.output(a))},startGroup:function(a){this._.close();\nvar b=CKEDITOR.tools.getNextId();this._.groups[a]=b;this._.pendingHtml.push(h.output({id:b,label:a}))},commit:function(){this._.close();this.element.appendHtml(this._.pendingHtml.join(\"\"));delete this._.size;this._.pendingHtml=[]},toggle:function(a){var b=this.isMarked(a);b?this.unmark(a):this.mark(a);return!b},hideGroup:function(a){var b=(a=this.element.getDocument().getById(this._.groups[a]))&&a.getNext();a&&(a.setStyle(\"display\",\"none\"),b&&\"ul\"==b.getName()&&b.setStyle(\"display\",\"none\"))},hideItem:function(a){this.element.getDocument().getById(this._.items[a]).setStyle(\"display\",\n\"none\")},showAll:function(){var a=this._.items,b=this._.groups,c=this.element.getDocument(),d;for(d in a)c.getById(a[d]).setStyle(\"display\",\"\");for(var e in b)a=c.getById(b[e]),d=a.getNext(),a.setStyle(\"display\",\"\"),d&&\"ul\"==d.getName()&&d.setStyle(\"display\",\"\")},mark:function(a){this.multiSelect||this.unmarkAll();var a=this._.items[a],b=this.element.getDocument().getById(a);b.addClass(\"cke_selected\");this.element.getDocument().getById(a+\"_option\").setAttribute(\"aria-selected\",!0);this.onMark&&this.onMark(b)},\nunmark:function(a){var b=this.element.getDocument(),a=this._.items[a],c=b.getById(a);c.removeClass(\"cke_selected\");b.getById(a+\"_option\").removeAttribute(\"aria-selected\");this.onUnmark&&this.onUnmark(c)},unmarkAll:function(){var a=this._.items,b=this.element.getDocument(),c;for(c in a){var d=a[c];b.getById(d).removeClass(\"cke_selected\");b.getById(d+\"_option\").removeAttribute(\"aria-selected\")}this.onUnmark&&this.onUnmark()},isMarked:function(a){return this.element.getDocument().getById(this._.items[a]).hasClass(\"cke_selected\")},\nfocus:function(a){this._.focusIndex=-1;var b=this.element.getElementsByTag(\"a\"),c,d=-1;if(a)for(c=this.element.getDocument().getById(this._.items[a]).getFirst();a=b.getItem(++d);){if(a.equals(c)){this._.focusIndex=d;break}}else this.element.focus();c&&setTimeout(function(){c.focus()},0)}}})}});CKEDITOR.plugins.add(\"richcombo\",{requires:\"floatpanel,listblock,button\",beforeInit:function(d){d.ui.addHandler(CKEDITOR.UI_RICHCOMBO,CKEDITOR.ui.richCombo.handler)}});\n(function(){var d='<span id=\"{id}\" class=\"cke_combo cke_combo__{name} {cls}\" role=\"presentation\"><span id=\"{id}_label\" class=\"cke_combo_label\">{label}</span><a class=\"cke_combo_button\" hidefocus=true title=\"{title}\" tabindex=\"-1\"'+(CKEDITOR.env.gecko&&10900<=CKEDITOR.env.version&&!CKEDITOR.env.hc?\"\":'\" href=\"javascript:void(\\'{titleJs}\\')\"')+' hidefocus=\"true\" role=\"button\" aria-labelledby=\"{id}_label\" aria-haspopup=\"true\"';if(CKEDITOR.env.opera||CKEDITOR.env.gecko&&CKEDITOR.env.mac)d+=' onkeypress=\"return false;\"';\nCKEDITOR.env.gecko&&(d+=' onblur=\"this.style.cssText = this.style.cssText;\"');var d=d+(' onkeydown=\"return CKEDITOR.tools.callFunction({keydownFn},event,this);\" onmousedown=\"return CKEDITOR.tools.callFunction({mousedownFn},event);\"  onfocus=\"return CKEDITOR.tools.callFunction({focusFn},event);\" '+(CKEDITOR.env.ie?'onclick=\"return false;\" onmouseup':\"onclick\")+'=\"CKEDITOR.tools.callFunction({clickFn},this);return false;\"><span id=\"{id}_text\" class=\"cke_combo_text cke_combo_inlinelabel\">{label}</span><span class=\"cke_combo_open\"><span class=\"cke_combo_arrow\">'+\n(CKEDITOR.env.hc?\"&#9660;\":CKEDITOR.env.air?\"&nbsp;\":\"\")+\"</span></span></a></span>\"),i=CKEDITOR.addTemplate(\"combo\",d);CKEDITOR.UI_RICHCOMBO=\"richcombo\";CKEDITOR.ui.richCombo=CKEDITOR.tools.createClass({$:function(a){CKEDITOR.tools.extend(this,a,{canGroup:!1,title:a.label,modes:{wysiwyg:1},editorFocus:1});a=this.panel||{};delete this.panel;this.id=CKEDITOR.tools.getNextNumber();this.document=a.parent&&a.parent.getDocument()||CKEDITOR.document;a.className=\"cke_combopanel\";a.block={multiSelect:a.multiSelect,\nattributes:a.attributes};a.toolbarRelated=!0;this._={panelDefinition:a,items:{}}},proto:{renderHtml:function(a){var b=[];this.render(a,b);return b.join(\"\")},render:function(a,b){function g(){var c=this.modes[a.mode]?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED;a.readOnly&&!this.readOnly&&(c=CKEDITOR.TRISTATE_DISABLED);this.setState(c);this.setValue(\"\");c!=CKEDITOR.TRISTATE_DISABLED&&this.refresh&&this.refresh()}var d=CKEDITOR.env,h=\"cke_\"+this.id,e=CKEDITOR.tools.addFunction(function(b){j&&(a.unlockSelection(1),\nj=0);c.execute(b)},this),f=this,c={id:h,combo:this,focus:function(){CKEDITOR.document.getById(h).getChild(1).focus()},execute:function(c){var b=f._;if(b.state!=CKEDITOR.TRISTATE_DISABLED)if(f.createPanel(a),b.on)b.panel.hide();else{f.commit();var d=f.getValue();d?b.list.mark(d):b.list.unmarkAll();b.panel.showBlock(f.id,new CKEDITOR.dom.element(c),4)}},clickFn:e};a.on(\"activeFilterChange\",g,this);a.on(\"mode\",g,this);!this.readOnly&&a.on(\"readOnly\",g,this);var k=CKEDITOR.tools.addFunction(function(b,\nd){var b=new CKEDITOR.dom.event(b),g=b.getKeystroke();if(40==g)a.once(\"panelShow\",function(a){a.data._.panel._.currentBlock.onKeyDown(40)});switch(g){case 13:case 32:case 40:CKEDITOR.tools.callFunction(e,d);break;default:c.onkey(c,g)}b.preventDefault()}),l=CKEDITOR.tools.addFunction(function(){c.onfocus&&c.onfocus()}),j=0,m=CKEDITOR.tools.addFunction(function(){if(CKEDITOR.env.opera){var b=a.editable();b.isInline()&&b.hasFocus&&(a.lockSelection(),j=1)}});c.keyDownFn=k;d={id:h,name:this.name||this.command,\nlabel:this.label,title:this.title,cls:this.className||\"\",titleJs:d.gecko&&10900<=d.version&&!d.hc?\"\":(this.title||\"\").replace(\"'\",\"\"),keydownFn:k,mousedownFn:m,focusFn:l,clickFn:e};i.output(d,b);if(this.onRender)this.onRender();return c},createPanel:function(a){if(!this._.panel){var b=this._.panelDefinition,d=this._.panelDefinition.block,i=b.parent||CKEDITOR.document.getBody(),h=\"cke_combopanel__\"+this.name,e=new CKEDITOR.ui.floatPanel(a,i,b),f=e.addListBlock(this.id,d),c=this;e.onShow=function(){this.element.addClass(h);\nc.setState(CKEDITOR.TRISTATE_ON);c._.on=1;c.editorFocus&&!a.focusManager.hasFocus&&a.focus();if(c.onOpen)c.onOpen();a.once(\"panelShow\",function(){f.focus(!f.multiSelect&&c.getValue())})};e.onHide=function(b){this.element.removeClass(h);c.setState(c.modes&&c.modes[a.mode]?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED);c._.on=0;if(!b&&c.onClose)c.onClose()};e.onEscape=function(){e.hide(1)};f.onClick=function(a,b){c.onClick&&c.onClick.call(c,a,b);e.hide()};this._.panel=e;this._.list=f;e.getBlock(this.id).onHide=\nfunction(){c._.on=0;c.setState(CKEDITOR.TRISTATE_OFF)};this.init&&this.init()}},setValue:function(a,b){this._.value=a;var d=this.document.getById(\"cke_\"+this.id+\"_text\");d&&(!a&&!b?(b=this.label,d.addClass(\"cke_combo_inlinelabel\")):d.removeClass(\"cke_combo_inlinelabel\"),d.setText(\"undefined\"!=typeof b?b:a))},getValue:function(){return this._.value||\"\"},unmarkAll:function(){this._.list.unmarkAll()},mark:function(a){this._.list.mark(a)},hideItem:function(a){this._.list.hideItem(a)},hideGroup:function(a){this._.list.hideGroup(a)},\nshowAll:function(){this._.list.showAll()},add:function(a,b,d){this._.items[a]=d||a;this._.list.add(a,b,d)},startGroup:function(a){this._.list.startGroup(a)},commit:function(){this._.committed||(this._.list.commit(),this._.committed=1,CKEDITOR.ui.fire(\"ready\",this));this._.committed=1},setState:function(a){if(this._.state!=a){var b=this.document.getById(\"cke_\"+this.id);b.setState(a,\"cke_combo\");a==CKEDITOR.TRISTATE_DISABLED?b.setAttribute(\"aria-disabled\",!0):b.removeAttribute(\"aria-disabled\");this._.state=\na}},getState:function(){return this._.state},enable:function(){this._.state==CKEDITOR.TRISTATE_DISABLED&&this.setState(this._.lastState)},disable:function(){this._.state!=CKEDITOR.TRISTATE_DISABLED&&(this._.lastState=this._.state,this.setState(CKEDITOR.TRISTATE_DISABLED))}},statics:{handler:{create:function(a){return new CKEDITOR.ui.richCombo(a)}}}});CKEDITOR.ui.prototype.addRichCombo=function(a,b){this.add(a,CKEDITOR.UI_RICHCOMBO,b)}})();CKEDITOR.plugins.add(\"format\",{requires:\"richcombo\",init:function(a){if(!a.blockless){for(var f=a.config,c=a.lang.format,j=f.format_tags.split(\";\"),d={},k=0,l=[],g=0;g<j.length;g++){var h=j[g],i=new CKEDITOR.style(f[\"format_\"+h]);if(!a.filter.customConfig||a.filter.check(i))k++,d[h]=i,d[h]._.enterMode=a.config.enterMode,l.push(i)}0!==k&&a.ui.addRichCombo(\"Format\",{label:c.label,title:c.panelTitle,toolbar:\"styles,20\",allowedContent:l,panel:{css:[CKEDITOR.skin.getPath(\"editor\")].concat(f.contentsCss),\nmultiSelect:!1,attributes:{\"aria-label\":c.panelTitle}},init:function(){this.startGroup(c.panelTitle);for(var b in d){var a=c[\"tag_\"+b];this.add(b,d[b].buildPreview(a),a)}},onClick:function(b){a.focus();a.fire(\"saveSnapshot\");var b=d[b],c=a.elementPath();a[b.checkActive(c)?\"removeStyle\":\"applyStyle\"](b);setTimeout(function(){a.fire(\"saveSnapshot\")},0)},onRender:function(){a.on(\"selectionChange\",function(b){var c=this.getValue(),b=b.data.path;this.refresh();for(var e in d)if(d[e].checkActive(b)){e!=\nc&&this.setValue(e,a.lang.format[\"tag_\"+e]);return}this.setValue(\"\")},this)},onOpen:function(){this.showAll();for(var b in d)a.activeFilter.check(d[b])||this.hideItem(b)},refresh:function(){var b=a.elementPath();if(b){if(b.isContextFor(\"p\"))for(var c in d)if(a.activeFilter.check(d[c]))return;this.setState(CKEDITOR.TRISTATE_DISABLED)}}})}}});CKEDITOR.config.format_tags=\"p;h1;h2;h3;h4;h5;h6;pre;address;div\";CKEDITOR.config.format_p={element:\"p\"};CKEDITOR.config.format_div={element:\"div\"};\nCKEDITOR.config.format_pre={element:\"pre\"};CKEDITOR.config.format_address={element:\"address\"};CKEDITOR.config.format_h1={element:\"h1\"};CKEDITOR.config.format_h2={element:\"h2\"};CKEDITOR.config.format_h3={element:\"h3\"};CKEDITOR.config.format_h4={element:\"h4\"};CKEDITOR.config.format_h5={element:\"h5\"};CKEDITOR.config.format_h6={element:\"h6\"};(function(){var b={canUndo:!1,exec:function(a){var b=a.document.createElement(\"hr\");a.insertElement(b)},allowedContent:\"hr\",requiredContent:\"hr\"};CKEDITOR.plugins.add(\"horizontalrule\",{init:function(a){a.blockless||(a.addCommand(\"horizontalrule\",b),a.ui.addButton&&a.ui.addButton(\"HorizontalRule\",{label:a.lang.horizontalrule.toolbar,command:\"horizontalrule\",toolbar:\"insert,40\"}))}})})();CKEDITOR.plugins.add(\"htmlwriter\",{init:function(b){var a=new CKEDITOR.htmlWriter;a.forceSimpleAmpersand=b.config.forceSimpleAmpersand;a.indentationChars=b.config.dataIndentationChars||\"\\t\";b.dataProcessor.writer=a}});\nCKEDITOR.htmlWriter=CKEDITOR.tools.createClass({base:CKEDITOR.htmlParser.basicWriter,$:function(){this.base();this.indentationChars=\"\\t\";this.selfClosingEnd=\" />\";this.lineBreakChars=\"\\n\";this.sortAttributes=1;this._.indent=0;this._.indentation=\"\";this._.inPre=0;this._.rules={};var b=CKEDITOR.dtd,a;for(a in CKEDITOR.tools.extend({},b.$nonBodyContent,b.$block,b.$listItem,b.$tableContent))this.setRules(a,{indent:!b[a][\"#\"],breakBeforeOpen:1,breakBeforeClose:!b[a][\"#\"],breakAfterClose:1,needsSpace:a in\nb.$block&&!(a in{li:1,dt:1,dd:1})});this.setRules(\"br\",{breakAfterOpen:1});this.setRules(\"title\",{indent:0,breakAfterOpen:0});this.setRules(\"style\",{indent:0,breakBeforeClose:1});this.setRules(\"pre\",{breakAfterOpen:1,indent:0})},proto:{openTag:function(b){var a=this._.rules[b];this._.afterCloser&&(a&&a.needsSpace&&this._.needsSpace)&&this._.output.push(\"\\n\");this._.indent?this.indentation():a&&a.breakBeforeOpen&&(this.lineBreak(),this.indentation());this._.output.push(\"<\",b);this._.afterCloser=0},\nopenTagClose:function(b,a){var c=this._.rules[b];a?(this._.output.push(this.selfClosingEnd),c&&c.breakAfterClose&&(this._.needsSpace=c.needsSpace)):(this._.output.push(\">\"),c&&c.indent&&(this._.indentation+=this.indentationChars));c&&c.breakAfterOpen&&this.lineBreak();\"pre\"==b&&(this._.inPre=1)},attribute:function(b,a){\"string\"==typeof a&&(this.forceSimpleAmpersand&&(a=a.replace(/&amp;/g,\"&\")),a=CKEDITOR.tools.htmlEncodeAttr(a));this._.output.push(\" \",b,'=\"',a,'\"')},closeTag:function(b){var a=this._.rules[b];\na&&a.indent&&(this._.indentation=this._.indentation.substr(this.indentationChars.length));this._.indent?this.indentation():a&&a.breakBeforeClose&&(this.lineBreak(),this.indentation());this._.output.push(\"</\",b,\">\");\"pre\"==b&&(this._.inPre=0);a&&a.breakAfterClose&&(this.lineBreak(),this._.needsSpace=a.needsSpace);this._.afterCloser=1},text:function(b){this._.indent&&(this.indentation(),!this._.inPre&&(b=CKEDITOR.tools.ltrim(b)));this._.output.push(b)},comment:function(b){this._.indent&&this.indentation();\nthis._.output.push(\"<\\!--\",b,\"--\\>\")},lineBreak:function(){!this._.inPre&&0<this._.output.length&&this._.output.push(this.lineBreakChars);this._.indent=1},indentation:function(){!this._.inPre&&this._.indentation&&this._.output.push(this._.indentation);this._.indent=0},reset:function(){this._.output=[];this._.indent=0;this._.indentation=\"\";this._.afterCloser=0;this._.inPre=0},setRules:function(b,a){var c=this._.rules[b];c?CKEDITOR.tools.extend(c,a,!0):this._.rules[b]=a}}});(function(){function k(a){var d=this.editor,b=a.document,c=b.body;(a=b.getElementById(\"cke_actscrpt\"))&&a.parentNode.removeChild(a);(a=b.getElementById(\"cke_shimscrpt\"))&&a.parentNode.removeChild(a);CKEDITOR.env.gecko&&(c.contentEditable=!1,2E4>CKEDITOR.env.version&&(c.innerHTML=c.innerHTML.replace(/^.*<\\!-- cke-content-start --\\>/,\"\"),setTimeout(function(){var a=new CKEDITOR.dom.range(new CKEDITOR.dom.document(b));a.setStart(new CKEDITOR.dom.node(c),0);d.getSelection().selectRanges([a])},0)));c.contentEditable=\n!0;CKEDITOR.env.ie&&(c.hideFocus=!0,c.disabled=!0,c.removeAttribute(\"disabled\"));delete this._.isLoadingData;this.$=c;b=new CKEDITOR.dom.document(b);this.setup();CKEDITOR.env.ie&&(b.getDocumentElement().addClass(b.$.compatMode),d.config.enterMode!=CKEDITOR.ENTER_P&&this.attachListener(b,\"selectionchange\",function(){var a=b.getBody(),c=d.getSelection(),e=c&&c.getRanges()[0];e&&(a.getHtml().match(/^<p>(?:&nbsp;|<br>)<\\/p>$/i)&&e.startContainer.equals(a))&&setTimeout(function(){e=d.getSelection().getRanges()[0];\nif(!e.startContainer.equals(\"body\")){a.getFirst().remove(1);e.moveToElementEditEnd(a);e.select()}},0)}));if(CKEDITOR.env.webkit||CKEDITOR.env.ie&&10<CKEDITOR.env.version)b.getDocumentElement().on(\"mousedown\",function(a){a.data.getTarget().is(\"html\")&&setTimeout(function(){d.editable().focus()})});try{d.document.$.execCommand(\"2D-position\",!1,!0)}catch(e){}try{d.document.$.execCommand(\"enableInlineTableEditing\",!1,!d.config.disableNativeTableHandles)}catch(g){}if(d.config.disableObjectResizing)try{this.getDocument().$.execCommand(\"enableObjectResizing\",\n!1,!1)}catch(f){this.attachListener(this,CKEDITOR.env.ie?\"resizestart\":\"resize\",function(a){a.data.preventDefault()})}(CKEDITOR.env.gecko||CKEDITOR.env.ie&&\"CSS1Compat\"==d.document.$.compatMode)&&this.attachListener(this,\"keydown\",function(a){var b=a.data.getKeystroke();if(b==33||b==34)if(CKEDITOR.env.ie)setTimeout(function(){d.getSelection().scrollIntoView()},0);else if(d.window.$.innerHeight>this.$.offsetHeight){var c=d.createRange();c[b==33?\"moveToElementEditStart\":\"moveToElementEditEnd\"](this);\nc.select();a.data.preventDefault()}});CKEDITOR.env.ie&&this.attachListener(b,\"blur\",function(){try{b.$.selection.empty()}catch(a){}});d.document.getElementsByTag(\"title\").getItem(0).data(\"cke-title\",d.document.$.title);CKEDITOR.env.ie&&(d.document.$.title=this._.docTitle);CKEDITOR.tools.setTimeout(function(){d.fire(\"contentDom\");if(this._.isPendingFocus){d.focus();this._.isPendingFocus=false}setTimeout(function(){d.fire(\"dataReady\")},0);CKEDITOR.env.ie&&setTimeout(function(){if(d.document){var a=\nd.document.$.body;a.runtimeStyle.marginBottom=\"0px\";a.runtimeStyle.marginBottom=\"\"}},1E3)},0,this)}function l(){var a=[];if(8<=CKEDITOR.document.$.documentMode){a.push(\"html.CSS1Compat [contenteditable=false]{min-height:0 !important}\");var d=[],b;for(b in CKEDITOR.dtd.$removeEmpty)d.push(\"html.CSS1Compat \"+b+\"[contenteditable=false]\");a.push(d.join(\",\")+\"{display:inline-block}\")}else CKEDITOR.env.gecko&&(a.push(\"html{height:100% !important}\"),a.push(\"img:-moz-broken{-moz-force-broken-image-icon:1;min-width:24px;min-height:24px}\"));\na.push(\"html{cursor:text;*cursor:auto}\");a.push(\"img,input,textarea{cursor:default}\");return a.join(\"\\n\")}CKEDITOR.plugins.add(\"wysiwygarea\",{init:function(a){a.config.fullPage&&a.addFeature({allowedContent:\"html head title; style [media,type]; body (*)[id]; meta link [*]\",requiredContent:\"body\"});a.addMode(\"wysiwyg\",function(d){function b(b){b&&b.removeListener();a.editable(new j(a,e.$.contentWindow.document.body));a.setData(a.getData(1),d)}var c=\"document.open();\"+(CKEDITOR.env.ie?\"(\"+CKEDITOR.tools.fixDomain+\n\")();\":\"\")+\"document.close();\",c=CKEDITOR.env.air?\"javascript:void(0)\":CKEDITOR.env.ie?\"javascript:void(function(){\"+encodeURIComponent(c)+\"}())\":\"\",e=CKEDITOR.dom.element.createFromHtml('<iframe src=\"'+c+'\" frameBorder=\"0\"></iframe>');e.setStyles({width:\"100%\",height:\"100%\"});e.addClass(\"cke_wysiwyg_frame cke_reset\");var g=a.ui.space(\"contents\");g.append(e);if(c=CKEDITOR.env.ie||CKEDITOR.env.gecko)e.on(\"load\",b);var f=a.title,h=a.lang.common.editorHelp;f&&(CKEDITOR.env.ie&&(f+=\", \"+h),e.setAttribute(\"title\",\nf));var f=CKEDITOR.tools.getNextId(),i=CKEDITOR.dom.element.createFromHtml('<span id=\"'+f+'\" class=\"cke_voice_label\">'+h+\"</span>\");g.append(i,1);a.on(\"beforeModeUnload\",function(a){a.removeListener();i.remove()});e.setAttributes({\"aria-describedby\":f,tabIndex:a.tabIndex,allowTransparency:\"true\"});!c&&b();CKEDITOR.env.webkit&&(c=function(){g.setStyle(\"width\",\"100%\");e.hide();e.setSize(\"width\",g.getSize(\"width\"));g.removeStyle(\"width\");e.show()},e.setCustomData(\"onResize\",c),CKEDITOR.document.getWindow().on(\"resize\",\nc));a.fire(\"ariaWidget\",e)})}});var j=CKEDITOR.tools.createClass({$:function(a){this.base.apply(this,arguments);this._.frameLoadedHandler=CKEDITOR.tools.addFunction(function(a){CKEDITOR.tools.setTimeout(k,0,this,a)},this);this._.docTitle=this.getWindow().getFrame().getAttribute(\"title\")},base:CKEDITOR.editable,proto:{setData:function(a,d){var b=this.editor;if(d)this.setHtml(a),b.fire(\"dataReady\");else{this._.isLoadingData=!0;b._.dataStore={id:1};var c=b.config,e=c.fullPage,g=c.docType,f=CKEDITOR.tools.buildStyleHtml(l()).replace(/<style>/,\n'<style data-cke-temp=\"1\">');e||(f+=CKEDITOR.tools.buildStyleHtml(b.config.contentsCss));var h=c.baseHref?'<base href=\"'+c.baseHref+'\" data-cke-temp=\"1\" />':\"\";e&&(a=a.replace(/<!DOCTYPE[^>]*>/i,function(a){b.docType=g=a;return\"\"}).replace(/<\\?xml\\s[^\\?]*\\?>/i,function(a){b.xmlDeclaration=a;return\"\"}));a=b.dataProcessor.toHtml(a);e?(/<body[\\s|>]/.test(a)||(a=\"<body>\"+a),/<html[\\s|>]/.test(a)||(a=\"<html>\"+a+\"</html>\"),/<head[\\s|>]/.test(a)?/<title[\\s|>]/.test(a)||(a=a.replace(/<head[^>]*>/,\"$&<title></title>\")):\na=a.replace(/<html[^>]*>/,\"$&<head><title></title></head>\"),h&&(a=a.replace(/<head>/,\"$&\"+h)),a=a.replace(/<\\/head\\s*>/,f+\"$&\"),a=g+a):a=c.docType+'<html dir=\"'+c.contentsLangDirection+'\" lang=\"'+(c.contentsLanguage||b.langCode)+'\"><head><title>'+this._.docTitle+\"</title>\"+h+f+\"</head><body\"+(c.bodyId?' id=\"'+c.bodyId+'\"':\"\")+(c.bodyClass?' class=\"'+c.bodyClass+'\"':\"\")+\">\"+a+\"</body></html>\";CKEDITOR.env.gecko&&(a=a.replace(/<body/,'<body contenteditable=\"true\" '),2E4>CKEDITOR.env.version&&(a=a.replace(/<body[^>]*>/,\n\"$&<\\!-- cke-content-start --\\>\")));c='<script id=\"cke_actscrpt\" type=\"text/javascript\"'+(CKEDITOR.env.ie?' defer=\"defer\" ':\"\")+\">var wasLoaded=0;function onload(){if(!wasLoaded)window.parent.CKEDITOR.tools.callFunction(\"+this._.frameLoadedHandler+\",window);wasLoaded=1;}\"+(CKEDITOR.env.ie?\"onload();\":'document.addEventListener(\"DOMContentLoaded\", onload, false );')+\"<\\/script>\";CKEDITOR.env.ie&&9>CKEDITOR.env.version&&(c+='<script id=\"cke_shimscrpt\">window.parent.CKEDITOR.tools.enableHtml5Elements(document)<\\/script>');\na=a.replace(/(?=\\s*<\\/(:?head)>)/,c);this.clearCustomData();this.clearListeners();b.fire(\"contentDomUnload\");var i=this.getDocument();try{i.write(a)}catch(j){setTimeout(function(){i.write(a)},0)}}},getData:function(a){if(a)return this.getHtml();var a=this.editor,d=a.config,b=d.fullPage,c=b&&a.docType,e=b&&a.xmlDeclaration,g=this.getDocument(),b=b?g.getDocumentElement().getOuterHtml():g.getBody().getHtml();CKEDITOR.env.gecko&&d.enterMode!=CKEDITOR.ENTER_BR&&(b=b.replace(/<br>(?=\\s*(:?$|<\\/body>))/,\n\"\"));b=a.dataProcessor.toDataFormat(b);e&&(b=e+\"\\n\"+b);c&&(b=c+\"\\n\"+b);return b},focus:function(){this._.isLoadingData?this._.isPendingFocus=!0:j.baseProto.focus.call(this)},detach:function(){var a=this.editor,d=a.document,b=a.window.getFrame();j.baseProto.detach.call(this);this.clearCustomData();d.getDocumentElement().clearCustomData();b.clearCustomData();CKEDITOR.tools.removeFunction(this._.frameLoadedHandler);(d=b.removeCustomData(\"onResize\"))&&d.removeListener();a.fire(\"contentDomUnload\");b.remove()}}})})();\nCKEDITOR.config.disableObjectResizing=!1;CKEDITOR.config.disableNativeTableHandles=!0;CKEDITOR.config.disableNativeSpellChecker=!0;CKEDITOR.config.contentsCss=CKEDITOR.basePath+\"contents.css\";(function(){function e(b,a){a||(a=b.getSelection().getSelectedElement());if(a&&a.is(\"img\")&&!a.data(\"cke-realelement\")&&!a.isReadOnly())return a}function f(b){var a=b.getStyle(\"float\");if(\"inherit\"==a||\"none\"==a)a=0;a||(a=b.getAttribute(\"align\"));return a}CKEDITOR.plugins.add(\"image\",{requires:\"dialog\",init:function(b){if(!b.plugins.image2){CKEDITOR.dialog.add(\"image\",this.path+\"dialogs/image.js\");var a=\"img[alt,!src]{border-style,border-width,float,height,margin,margin-bottom,margin-left,margin-right,margin-top,width}\";\nCKEDITOR.dialog.isTabEnabled(b,\"image\",\"advanced\")&&(a=\"img[alt,dir,id,lang,longdesc,!src,title]{*}(*)\");b.addCommand(\"image\",new CKEDITOR.dialogCommand(\"image\",{allowedContent:a,requiredContent:\"img[alt,src]\",contentTransformations:[[\"img{width}: sizeToStyle\",\"img[width]: sizeToAttribute\"],[\"img{float}: alignmentToStyle\",\"img[align]: alignmentToAttribute\"]]}));b.ui.addButton&&b.ui.addButton(\"Image\",{label:b.lang.common.image,command:\"image\",toolbar:\"insert,10\"});b.on(\"doubleclick\",function(b){var a=\nb.data.element;a.is(\"img\")&&(!a.data(\"cke-realelement\")&&!a.isReadOnly())&&(b.data.dialog=\"image\")});b.addMenuItems&&b.addMenuItems({image:{label:b.lang.image.menu,command:\"image\",group:\"image\"}});b.contextMenu&&b.contextMenu.addListener(function(a){if(e(b,a))return{image:CKEDITOR.TRISTATE_OFF}})}},afterInit:function(b){function a(a){var d=b.getCommand(\"justify\"+a);if(d){if(\"left\"==a||\"right\"==a)d.on(\"exec\",function(d){var c=e(b),g;c&&(g=f(c),g==a?(c.removeStyle(\"float\"),a==f(c)&&c.removeAttribute(\"align\")):\nc.setStyle(\"float\",a),d.cancel())});d.on(\"refresh\",function(d){var c=e(b);c&&(c=f(c),this.setState(c==a?CKEDITOR.TRISTATE_ON:\"right\"==a||\"left\"==a?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED),d.cancel())})}}b.plugins.image2||(a(\"left\"),a(\"right\"),a(\"center\"),a(\"block\"))}})})();CKEDITOR.config.image_removeLinkByEmptyURL=!0;(function(){function k(a,b){var e,f;b.on(\"refresh\",function(a){var b=[i],c;for(c in a.data.states)b.push(a.data.states[c]);this.setState(CKEDITOR.tools.search(b,m)?m:i)},b,null,100);b.on(\"exec\",function(b){e=a.getSelection();f=e.createBookmarks(1);b.data||(b.data={});b.data.done=!1},b,null,0);b.on(\"exec\",function(){a.forceNextSelectionCheck();e.selectBookmarks(f)},b,null,100)}var i=CKEDITOR.TRISTATE_DISABLED,m=CKEDITOR.TRISTATE_OFF;CKEDITOR.plugins.add(\"indent\",{init:function(a){var b=CKEDITOR.plugins.indent.genericDefinition;\nk(a,a.addCommand(\"indent\",new b(!0)));k(a,a.addCommand(\"outdent\",new b));a.ui.addButton&&(a.ui.addButton(\"Indent\",{label:a.lang.indent.indent,command:\"indent\",directional:!0,toolbar:\"indent,20\"}),a.ui.addButton(\"Outdent\",{label:a.lang.indent.outdent,command:\"outdent\",directional:!0,toolbar:\"indent,10\"}));a.on(\"dirChanged\",function(b){var f=a.createRange(),j=b.data.node;f.setStartBefore(j);f.setEndAfter(j);for(var l=new CKEDITOR.dom.walker(f),c;c=l.next();)if(c.type==CKEDITOR.NODE_ELEMENT)if(!c.equals(j)&&\nc.getDirection()){f.setStartAfter(c);l=new CKEDITOR.dom.walker(f)}else{var d=a.config.indentClasses;if(d)for(var g=b.data.dir==\"ltr\"?[\"_rtl\",\"\"]:[\"\",\"_rtl\"],h=0;h<d.length;h++)if(c.hasClass(d[h]+g[0])){c.removeClass(d[h]+g[0]);c.addClass(d[h]+g[1])}d=c.getStyle(\"margin-right\");g=c.getStyle(\"margin-left\");d?c.setStyle(\"margin-left\",d):c.removeStyle(\"margin-left\");g?c.setStyle(\"margin-right\",g):c.removeStyle(\"margin-right\")}})}});CKEDITOR.plugins.indent={genericDefinition:function(a){this.isIndent=\n!!a;this.startDisabled=!this.isIndent},specificDefinition:function(a,b,e){this.name=b;this.editor=a;this.jobs={};this.enterBr=a.config.enterMode==CKEDITOR.ENTER_BR;this.isIndent=!!e;this.relatedGlobal=e?\"indent\":\"outdent\";this.indentKey=e?9:CKEDITOR.SHIFT+9;this.database={}},registerCommands:function(a,b){a.on(\"pluginsLoaded\",function(){for(var a in b)(function(a,b){var e=a.getCommand(b.relatedGlobal),c;for(c in b.jobs)e.on(\"exec\",function(d){d.data.done||(a.fire(\"lockSnapshot\"),b.execJob(a,c)&&(d.data.done=\n!0),a.fire(\"unlockSnapshot\"),CKEDITOR.dom.element.clearAllMarkers(b.database))},this,null,c),e.on(\"refresh\",function(d){d.data.states||(d.data.states={});d.data.states[b.name+\"@\"+c]=b.refreshJob(a,c,d.data.path)},this,null,c);a.addFeature(b)})(this,b[a])})}};CKEDITOR.plugins.indent.genericDefinition.prototype={context:\"p\",exec:function(){}};CKEDITOR.plugins.indent.specificDefinition.prototype={execJob:function(a,b){var e=this.jobs[b];if(e.state!=i)return e.exec.call(this,a)},refreshJob:function(a,\nb,e){b=this.jobs[b];b.state=a.activeFilter.checkFeature(this)?b.refresh.call(this,a,e):i;return b.state},getContext:function(a){return a.contains(this.context)}}})();(function(){function s(e){function g(b){for(var f=d.startContainer,a=d.endContainer;f&&!f.getParent().equals(b);)f=f.getParent();for(;a&&!a.getParent().equals(b);)a=a.getParent();if(!f||!a)return!1;for(var h=f,f=[],c=!1;!c;)h.equals(a)&&(c=!0),f.push(h),h=h.getNext();if(1>f.length)return!1;h=b.getParents(!0);for(a=0;a<h.length;a++)if(h[a].getName&&k[h[a].getName()]){b=h[a];break}for(var h=n.isIndent?1:-1,a=f[0],f=f[f.length-1],c=CKEDITOR.plugins.list.listToArray(b,o),g=c[f.getCustomData(\"listarray_index\")].indent,\na=a.getCustomData(\"listarray_index\");a<=f.getCustomData(\"listarray_index\");a++)if(c[a].indent+=h,0<h){var l=c[a].parent;c[a].parent=new CKEDITOR.dom.element(l.getName(),l.getDocument())}for(a=f.getCustomData(\"listarray_index\")+1;a<c.length&&c[a].indent>g;a++)c[a].indent+=h;f=CKEDITOR.plugins.list.arrayToList(c,o,null,e.config.enterMode,b.getDirection());if(!n.isIndent){var i;if((i=b.getParent())&&i.is(\"li\"))for(var h=f.listNode.getChildren(),m=[],j,a=h.count()-1;0<=a;a--)(j=h.getItem(a))&&(j.is&&\nj.is(\"li\"))&&m.push(j)}f&&f.listNode.replace(b);if(m&&m.length)for(a=0;a<m.length;a++){for(j=b=m[a];(j=j.getNext())&&j.is&&j.getName()in k;)CKEDITOR.env.needsNbspFiller&&!b.getFirst(t)&&b.append(d.document.createText(\" \")),b.append(j);b.insertAfter(i)}f&&e.fire(\"contentDomInvalidated\");return!0}for(var n=this,o=this.database,k=this.context,l=e.getSelection(),l=(l&&l.getRanges()).createIterator(),d;d=l.getNextRange();){for(var b=d.getCommonAncestor();b&&!(b.type==CKEDITOR.NODE_ELEMENT&&k[b.getName()]);)b=\nb.getParent();b||(b=d.startPath().contains(k))&&d.setEndAt(b,CKEDITOR.POSITION_BEFORE_END);if(!b){var c=d.getEnclosedNode();c&&(c.type==CKEDITOR.NODE_ELEMENT&&c.getName()in k)&&(d.setStartAt(c,CKEDITOR.POSITION_AFTER_START),d.setEndAt(c,CKEDITOR.POSITION_BEFORE_END),b=c)}b&&(d.startContainer.type==CKEDITOR.NODE_ELEMENT&&d.startContainer.getName()in k)&&(c=new CKEDITOR.dom.walker(d),c.evaluator=i,d.startContainer=c.next());b&&(d.endContainer.type==CKEDITOR.NODE_ELEMENT&&d.endContainer.getName()in k)&&\n(c=new CKEDITOR.dom.walker(d),c.evaluator=i,d.endContainer=c.previous());if(b)return g(b)}return 0}function p(e,g){g||(g=e.contains(this.context));return g&&e.block&&e.block.equals(g.getFirst(i))}function i(e){return e.type==CKEDITOR.NODE_ELEMENT&&e.is(\"li\")}function t(e){return u(e)&&v(e)}var u=CKEDITOR.dom.walker.whitespaces(!0),v=CKEDITOR.dom.walker.bookmark(!1,!0),q=CKEDITOR.TRISTATE_DISABLED,r=CKEDITOR.TRISTATE_OFF;CKEDITOR.plugins.add(\"indentlist\",{requires:\"indent\",init:function(e){function g(e,\ng){i.specificDefinition.apply(this,arguments);this.requiredContent=[\"ul\",\"ol\"];e.on(\"key\",function(g){if(\"wysiwyg\"==e.mode&&g.data.keyCode==this.indentKey){var d=this.getContext(e.elementPath());if(d&&(!this.isIndent||!p.call(this,e.elementPath(),d)))e.execCommand(this.relatedGlobal),g.cancel()}},this);this.jobs[this.isIndent?10:30]={refresh:this.isIndent?function(e,d){var b=this.getContext(d),c=p.call(this,d,b);return!b||!this.isIndent||c?q:r}:function(e,d){return!this.getContext(d)||this.isIndent?\nq:r},exec:CKEDITOR.tools.bind(s,this)}}var i=CKEDITOR.plugins.indent;i.registerCommands(e,{indentlist:new g(e,\"indentlist\",!0),outdentlist:new g(e,\"outdentlist\")});CKEDITOR.tools.extend(g.prototype,i.specificDefinition.prototype,{context:{ol:1,ul:1}})}})})();(function(){function g(a,b){var c=j.exec(a),d=j.exec(b);if(c){if(!c[2]&&\"px\"==d[2])return d[1];if(\"px\"==c[2]&&!d[2])return d[1]+\"px\"}return b}var i=CKEDITOR.htmlParser.cssStyle,h=CKEDITOR.tools.cssLength,j=/^((?:\\d*(?:\\.\\d+))|(?:\\d+))(.*)?$/i,l={elements:{$:function(a){var b=a.attributes;if((b=(b=(b=b&&b[\"data-cke-realelement\"])&&new CKEDITOR.htmlParser.fragment.fromHtml(decodeURIComponent(b)))&&b.children[0])&&a.attributes[\"data-cke-resizable\"]){var c=(new i(a)).rules,a=b.attributes,d=c.width,c=\nc.height;d&&(a.width=g(a.width,d));c&&(a.height=g(a.height,c))}return b}}},k=CKEDITOR.plugins.add(\"fakeobjects\",{init:function(a){a.filter.allow(\"img[!data-cke-realelement,src,alt,title](*){*}\",\"fakeobjects\")},afterInit:function(a){(a=(a=a.dataProcessor)&&a.htmlFilter)&&a.addRules(l)}});CKEDITOR.editor.prototype.createFakeElement=function(a,b,c,d){var e=this.lang.fakeobjects,e=e[c]||e.unknown,b={\"class\":b,\"data-cke-realelement\":encodeURIComponent(a.getOuterHtml()),\"data-cke-real-node-type\":a.type,\nalt:e,title:e,align:a.getAttribute(\"align\")||\"\"};CKEDITOR.env.hc||(b.src=CKEDITOR.getUrl(k.path+\"images/spacer.gif\"));c&&(b[\"data-cke-real-element-type\"]=c);d&&(b[\"data-cke-resizable\"]=d,c=new i,d=a.getAttribute(\"width\"),a=a.getAttribute(\"height\"),d&&(c.rules.width=h(d)),a&&(c.rules.height=h(a)),c.populate(b));return this.document.createElement(\"img\",{attributes:b})};CKEDITOR.editor.prototype.createFakeParserElement=function(a,b,c,d){var e=this.lang.fakeobjects,e=e[c]||e.unknown,f;f=new CKEDITOR.htmlParser.basicWriter;\na.writeHtml(f);f=f.getHtml();b={\"class\":b,\"data-cke-realelement\":encodeURIComponent(f),\"data-cke-real-node-type\":a.type,alt:e,title:e,align:a.attributes.align||\"\"};CKEDITOR.env.hc||(b.src=CKEDITOR.getUrl(k.path+\"images/spacer.gif\"));c&&(b[\"data-cke-real-element-type\"]=c);d&&(b[\"data-cke-resizable\"]=d,d=a.attributes,a=new i,c=d.width,d=d.height,void 0!=c&&(a.rules.width=h(c)),void 0!=d&&(a.rules.height=h(d)),a.populate(b));return new CKEDITOR.htmlParser.element(\"img\",b)};CKEDITOR.editor.prototype.restoreRealElement=\nfunction(a){if(a.data(\"cke-real-node-type\")!=CKEDITOR.NODE_ELEMENT)return null;var b=CKEDITOR.dom.element.createFromHtml(decodeURIComponent(a.data(\"cke-realelement\")),this.document);if(a.data(\"cke-resizable\")){var c=a.getStyle(\"width\"),a=a.getStyle(\"height\");c&&b.setAttribute(\"width\",g(b.getAttribute(\"width\"),c));a&&b.setAttribute(\"height\",g(b.getAttribute(\"height\"),a))}return b}})();CKEDITOR.plugins.add(\"link\",{requires:\"dialog,fakeobjects\",onLoad:function(){function b(b){return d.replace(/%1/g,\"rtl\"==b?\"right\":\"left\").replace(/%2/g,\"cke_contents_\"+b)}var a=\"background:url(\"+CKEDITOR.getUrl(this.path+\"images\"+(CKEDITOR.env.hidpi?\"/hidpi\":\"\")+\"/anchor.png\")+\") no-repeat %1 center;border:1px dotted #00f;background-size:16px;\",d=\".%2 a.cke_anchor,.%2 a.cke_anchor_empty,.cke_editable.%2 a[name],.cke_editable.%2 a[data-cke-saved-name]{\"+a+\"padding-%1:18px;cursor:auto;}\"+(CKEDITOR.plugins.link.synAnchorSelector?\n\"a.cke_anchor_empty{display:inline-block;}\":\"\")+\".%2 img.cke_anchor{\"+a+\"width:16px;min-height:15px;height:1.15em;vertical-align:\"+(CKEDITOR.env.opera?\"middle\":\"text-bottom\")+\";}\";CKEDITOR.addCss(b(\"ltr\")+b(\"rtl\"))},init:function(b){var a=\"a[!href]\";CKEDITOR.dialog.isTabEnabled(b,\"link\",\"advanced\")&&(a=a.replace(\"]\",\",accesskey,charset,dir,id,lang,name,rel,tabindex,title,type]{*}(*)\"));CKEDITOR.dialog.isTabEnabled(b,\"link\",\"target\")&&(a=a.replace(\"]\",\",target,onclick]\"));b.addCommand(\"link\",new CKEDITOR.dialogCommand(\"link\",\n{allowedContent:a,requiredContent:\"a[href]\"}));b.addCommand(\"anchor\",new CKEDITOR.dialogCommand(\"anchor\",{allowedContent:\"a[!name,id]\",requiredContent:\"a[name]\"}));b.addCommand(\"unlink\",new CKEDITOR.unlinkCommand);b.addCommand(\"removeAnchor\",new CKEDITOR.removeAnchorCommand);b.setKeystroke(CKEDITOR.CTRL+76,\"link\");b.ui.addButton&&(b.ui.addButton(\"Link\",{label:b.lang.link.toolbar,command:\"link\",toolbar:\"links,10\"}),b.ui.addButton(\"Unlink\",{label:b.lang.link.unlink,command:\"unlink\",toolbar:\"links,20\"}),\nb.ui.addButton(\"Anchor\",{label:b.lang.link.anchor.toolbar,command:\"anchor\",toolbar:\"links,30\"}));CKEDITOR.dialog.add(\"link\",this.path+\"dialogs/link.js\");CKEDITOR.dialog.add(\"anchor\",this.path+\"dialogs/anchor.js\");b.on(\"doubleclick\",function(a){var c=CKEDITOR.plugins.link.getSelectedLink(b)||a.data.element;if(!c.isReadOnly())if(c.is(\"a\")){a.data.dialog=c.getAttribute(\"name\")&&(!c.getAttribute(\"href\")||!c.getChildCount())?\"anchor\":\"link\";b.getSelection().selectElement(c)}else if(CKEDITOR.plugins.link.tryRestoreFakeAnchor(b,\nc))a.data.dialog=\"anchor\"});b.addMenuItems&&b.addMenuItems({anchor:{label:b.lang.link.anchor.menu,command:\"anchor\",group:\"anchor\",order:1},removeAnchor:{label:b.lang.link.anchor.remove,command:\"removeAnchor\",group:\"anchor\",order:5},link:{label:b.lang.link.menu,command:\"link\",group:\"link\",order:1},unlink:{label:b.lang.link.unlink,command:\"unlink\",group:\"link\",order:5}});b.contextMenu&&b.contextMenu.addListener(function(a){if(!a||a.isReadOnly())return null;a=CKEDITOR.plugins.link.tryRestoreFakeAnchor(b,\na);if(!a&&!(a=CKEDITOR.plugins.link.getSelectedLink(b)))return null;var c={};a.getAttribute(\"href\")&&a.getChildCount()&&(c={link:CKEDITOR.TRISTATE_OFF,unlink:CKEDITOR.TRISTATE_OFF});if(a&&a.hasAttribute(\"name\"))c.anchor=c.removeAnchor=CKEDITOR.TRISTATE_OFF;return c})},afterInit:function(b){var a=b.dataProcessor,d=a&&a.dataFilter,a=a&&a.htmlFilter,c=b._.elementsPath&&b._.elementsPath.filters;d&&d.addRules({elements:{a:function(a){var c=a.attributes;if(!c.name)return null;var d=!a.children.length;if(CKEDITOR.plugins.link.synAnchorSelector){var a=\nd?\"cke_anchor_empty\":\"cke_anchor\",e=c[\"class\"];if(c.name&&(!e||0>e.indexOf(a)))c[\"class\"]=(e||\"\")+\" \"+a;d&&CKEDITOR.plugins.link.emptyAnchorFix&&(c.contenteditable=\"false\",c[\"data-cke-editable\"]=1)}else if(CKEDITOR.plugins.link.fakeAnchor&&d)return b.createFakeParserElement(a,\"cke_anchor\",\"anchor\");return null}}});CKEDITOR.plugins.link.emptyAnchorFix&&a&&a.addRules({elements:{a:function(a){delete a.attributes.contenteditable}}});c&&c.push(function(a,c){if(\"a\"==c&&(CKEDITOR.plugins.link.tryRestoreFakeAnchor(b,\na)||a.getAttribute(\"name\")&&(!a.getAttribute(\"href\")||!a.getChildCount())))return\"anchor\"})}});\nCKEDITOR.plugins.link={getSelectedLink:function(b){var a=b.getSelection(),d=a.getSelectedElement();return d&&d.is(\"a\")?d:(a=a.getRanges()[0])?(a.shrink(CKEDITOR.SHRINK_TEXT),b.elementPath(a.getCommonAncestor()).contains(\"a\",1)):null},fakeAnchor:CKEDITOR.env.opera||CKEDITOR.env.webkit,synAnchorSelector:CKEDITOR.env.ie&&11>CKEDITOR.env.version,emptyAnchorFix:CKEDITOR.env.ie&&8>CKEDITOR.env.version,tryRestoreFakeAnchor:function(b,a){if(a&&a.data(\"cke-real-element-type\")&&\"anchor\"==a.data(\"cke-real-element-type\")){var d=\nb.restoreRealElement(a);if(d.data(\"cke-saved-name\"))return d}}};CKEDITOR.unlinkCommand=function(){};\nCKEDITOR.unlinkCommand.prototype={exec:function(b){var a=new CKEDITOR.style({element:\"a\",type:CKEDITOR.STYLE_INLINE,alwaysRemoveElement:1});b.removeStyle(a)},refresh:function(b,a){var d=a.lastElement&&a.lastElement.getAscendant(\"a\",!0);d&&\"a\"==d.getName()&&d.getAttribute(\"href\")&&d.getChildCount()?this.setState(CKEDITOR.TRISTATE_OFF):this.setState(CKEDITOR.TRISTATE_DISABLED)},contextSensitive:1,startDisabled:1,requiredContent:\"a[href]\"};CKEDITOR.removeAnchorCommand=function(){};\nCKEDITOR.removeAnchorCommand.prototype={exec:function(b){var a=b.getSelection(),d=a.createBookmarks(),c;if(a&&(c=a.getSelectedElement())&&(CKEDITOR.plugins.link.fakeAnchor&&!c.getChildCount()?CKEDITOR.plugins.link.tryRestoreFakeAnchor(b,c):c.is(\"a\")))c.remove(1);else if(c=CKEDITOR.plugins.link.getSelectedLink(b))c.hasAttribute(\"href\")?(c.removeAttributes({name:1,\"data-cke-saved-name\":1}),c.removeClass(\"cke_anchor\")):c.remove(1);a.selectBookmarks(d)},requiredContent:\"a[name]\"};\nCKEDITOR.tools.extend(CKEDITOR.config,{linkShowAdvancedTab:!0,linkShowTargetTab:!0});(function(){function E(c,k,e){function b(b){if((d=a[b?\"getFirst\":\"getLast\"]())&&(!d.is||!d.isBlockBoundary())&&(m=k.root[b?\"getPrevious\":\"getNext\"](CKEDITOR.dom.walker.invisible(!0)))&&(!m.is||!m.isBlockBoundary({br:1})))c.document.createElement(\"br\")[b?\"insertBefore\":\"insertAfter\"](d)}for(var j=CKEDITOR.plugins.list.listToArray(k.root,e),g=[],h=0;h<k.contents.length;h++){var f=k.contents[h];if((f=f.getAscendant(\"li\",!0))&&!f.getCustomData(\"list_item_processed\"))g.push(f),CKEDITOR.dom.element.setMarker(e,\nf,\"list_item_processed\",!0)}f=null;for(h=0;h<g.length;h++)f=g[h].getCustomData(\"listarray_index\"),j[f].indent=-1;for(h=f+1;h<j.length;h++)if(j[h].indent>j[h-1].indent+1){g=j[h-1].indent+1-j[h].indent;for(f=j[h].indent;j[h]&&j[h].indent>=f;)j[h].indent+=g,h++;h--}var a=CKEDITOR.plugins.list.arrayToList(j,e,null,c.config.enterMode,k.root.getAttribute(\"dir\")).listNode,d,m;b(!0);b();a.replace(k.root);c.fire(\"contentDomInvalidated\")}function x(c,k){this.name=c;this.context=this.type=k;this.allowedContent=\nk+\" li\";this.requiredContent=k}function A(c,k,e,b){for(var j,g;j=c[b?\"getLast\":\"getFirst\"](F);)(g=j.getDirection(1))!==k.getDirection(1)&&j.setAttribute(\"dir\",g),j.remove(),e?j[b?\"insertBefore\":\"insertAfter\"](e):k.append(j,b)}function B(c){var k;(k=function(e){var b=c[e?\"getPrevious\":\"getNext\"](q);b&&(b.type==CKEDITOR.NODE_ELEMENT&&b.is(c.getName()))&&(A(c,b,null,!e),c.remove(),c=b)})();k(1)}function C(c){return c.type==CKEDITOR.NODE_ELEMENT&&(c.getName()in CKEDITOR.dtd.$block||c.getName()in CKEDITOR.dtd.$listItem)&&\nCKEDITOR.dtd[c.getName()][\"#\"]}function y(c,k,e){c.fire(\"saveSnapshot\");e.enlarge(CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS);var b=e.extractContents();k.trim(!1,!0);var j=k.createBookmark(),g=new CKEDITOR.dom.elementPath(k.startContainer),h=g.block,g=g.lastElement.getAscendant(\"li\",1)||h,f=new CKEDITOR.dom.elementPath(e.startContainer),a=f.contains(CKEDITOR.dtd.$listItem),f=f.contains(CKEDITOR.dtd.$list);h?(h=h.getBogus())&&h.remove():f&&(h=f.getPrevious(q))&&v(h)&&h.remove();(h=b.getLast())&&(h.type==\nCKEDITOR.NODE_ELEMENT&&h.is(\"br\"))&&h.remove();(h=k.startContainer.getChild(k.startOffset))?b.insertBefore(h):k.startContainer.append(b);if(a&&(b=w(a)))g.contains(a)?(A(b,a.getParent(),a),b.remove()):g.append(b);for(;e.checkStartOfBlock()&&e.checkEndOfBlock();){f=e.startPath();b=f.block;if(!b)break;b.is(\"li\")&&(g=b.getParent(),b.equals(g.getLast(q))&&b.equals(g.getFirst(q))&&(b=g));e.moveToPosition(b,CKEDITOR.POSITION_BEFORE_START);b.remove()}e=e.clone();b=c.editable();e.setEndAt(b,CKEDITOR.POSITION_BEFORE_END);\ne=new CKEDITOR.dom.walker(e);e.evaluator=function(a){return q(a)&&!v(a)};(e=e.next())&&(e.type==CKEDITOR.NODE_ELEMENT&&e.getName()in CKEDITOR.dtd.$list)&&B(e);k.moveToBookmark(j);k.select();c.fire(\"saveSnapshot\")}function w(c){return(c=c.getLast(q))&&c.type==CKEDITOR.NODE_ELEMENT&&c.getName()in r?c:null}var r={ol:1,ul:1},G=CKEDITOR.dom.walker.whitespaces(),D=CKEDITOR.dom.walker.bookmark(),q=function(c){return!(G(c)||D(c))},v=CKEDITOR.dom.walker.bogus();CKEDITOR.plugins.list={listToArray:function(c,\nk,e,b,j){if(!r[c.getName()])return[];b||(b=0);e||(e=[]);for(var g=0,h=c.getChildCount();g<h;g++){var f=c.getChild(g);f.type==CKEDITOR.NODE_ELEMENT&&f.getName()in CKEDITOR.dtd.$list&&CKEDITOR.plugins.list.listToArray(f,k,e,b+1);if(\"li\"==f.$.nodeName.toLowerCase()){var a={parent:c,indent:b,element:f,contents:[]};j?a.grandparent=j:(a.grandparent=c.getParent(),a.grandparent&&\"li\"==a.grandparent.$.nodeName.toLowerCase()&&(a.grandparent=a.grandparent.getParent()));k&&CKEDITOR.dom.element.setMarker(k,f,\n\"listarray_index\",e.length);e.push(a);for(var d=0,m=f.getChildCount(),i;d<m;d++)i=f.getChild(d),i.type==CKEDITOR.NODE_ELEMENT&&r[i.getName()]?CKEDITOR.plugins.list.listToArray(i,k,e,b+1,a.grandparent):a.contents.push(i)}}return e},arrayToList:function(c,k,e,b,j){e||(e=0);if(!c||c.length<e+1)return null;for(var g,h=c[e].parent.getDocument(),f=new CKEDITOR.dom.documentFragment(h),a=null,d=e,m=Math.max(c[e].indent,0),i=null,n,l,p=b==CKEDITOR.ENTER_P?\"p\":\"div\";;){var o=c[d];g=o.grandparent;n=o.element.getDirection(1);\nif(o.indent==m){if(!a||c[d].parent.getName()!=a.getName())a=c[d].parent.clone(!1,1),j&&a.setAttribute(\"dir\",j),f.append(a);i=a.append(o.element.clone(0,1));n!=a.getDirection(1)&&i.setAttribute(\"dir\",n);for(g=0;g<o.contents.length;g++)i.append(o.contents[g].clone(1,1));d++}else if(o.indent==Math.max(m,0)+1)o=c[d-1].element.getDirection(1),d=CKEDITOR.plugins.list.arrayToList(c,null,d,b,o!=n?n:null),!i.getChildCount()&&(CKEDITOR.env.needsNbspFiller&&!(7<h.$.documentMode))&&i.append(h.createText(\" \")),\ni.append(d.listNode),d=d.nextIndex;else if(-1==o.indent&&!e&&g){r[g.getName()]?(i=o.element.clone(!1,!0),n!=g.getDirection(1)&&i.setAttribute(\"dir\",n)):i=new CKEDITOR.dom.documentFragment(h);var a=g.getDirection(1)!=n,u=o.element,z=u.getAttribute(\"class\"),v=u.getAttribute(\"style\"),w=i.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT&&(b!=CKEDITOR.ENTER_BR||a||v||z),s,x=o.contents.length,t;for(g=0;g<x;g++)if(s=o.contents[g],D(s)&&1<x)w?t=s.clone(1,1):i.append(s.clone(1,1));else if(s.type==CKEDITOR.NODE_ELEMENT&&\ns.isBlockBoundary()){a&&!s.getDirection()&&s.setAttribute(\"dir\",n);l=s;var y=u.getAttribute(\"style\");y&&l.setAttribute(\"style\",y.replace(/([^;])$/,\"$1;\")+(l.getAttribute(\"style\")||\"\"));z&&s.addClass(z);l=null;t&&(i.append(t),t=null);i.append(s.clone(1,1))}else w?(l||(l=h.createElement(p),i.append(l),a&&l.setAttribute(\"dir\",n)),v&&l.setAttribute(\"style\",v),z&&l.setAttribute(\"class\",z),t&&(l.append(t),t=null),l.append(s.clone(1,1))):i.append(s.clone(1,1));t&&((l||i).append(t),t=null);i.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT&&\nd!=c.length-1&&(CKEDITOR.env.needsBrFiller&&(n=i.getLast())&&(n.type==CKEDITOR.NODE_ELEMENT&&n.is(\"br\"))&&n.remove(),n=i.getLast(q),(!n||!(n.type==CKEDITOR.NODE_ELEMENT&&n.is(CKEDITOR.dtd.$block)))&&i.append(h.createElement(\"br\")));n=i.$.nodeName.toLowerCase();(\"div\"==n||\"p\"==n)&&i.appendBogus();f.append(i);a=null;d++}else return null;l=null;if(c.length<=d||Math.max(c[d].indent,0)<m)break}if(k)for(c=f.getFirst();c;){if(c.type==CKEDITOR.NODE_ELEMENT&&(CKEDITOR.dom.element.clearMarkers(k,c),c.getName()in\nCKEDITOR.dtd.$listItem&&(e=c,h=j=b=void 0,b=e.getDirection()))){for(j=e.getParent();j&&!(h=j.getDirection());)j=j.getParent();b==h&&e.removeAttribute(\"dir\")}c=c.getNextSourceNode()}return{listNode:f,nextIndex:d}}};var H=/^h[1-6]$/,F=CKEDITOR.dom.walker.nodeType(CKEDITOR.NODE_ELEMENT);x.prototype={exec:function(c){this.refresh(c,c.elementPath());var k=c.config,e=c.getSelection(),b=e&&e.getRanges();if(this.state==CKEDITOR.TRISTATE_OFF){var j=c.editable();if(j.getFirst(q)){var g=1==b.length&&b[0];(k=\ng&&g.getEnclosedNode())&&(k.is&&this.type==k.getName())&&this.setState(CKEDITOR.TRISTATE_ON)}else k.enterMode==CKEDITOR.ENTER_BR?j.appendBogus():b[0].fixBlock(1,k.enterMode==CKEDITOR.ENTER_P?\"p\":\"div\"),e.selectRanges(b)}for(var k=e.createBookmarks(!0),j=[],h={},b=b.createIterator(),f=0;(g=b.getNextRange())&&++f;){var a=g.getBoundaryNodes(),d=a.startNode,m=a.endNode;d.type==CKEDITOR.NODE_ELEMENT&&\"td\"==d.getName()&&g.setStartAt(a.startNode,CKEDITOR.POSITION_AFTER_START);m.type==CKEDITOR.NODE_ELEMENT&&\n\"td\"==m.getName()&&g.setEndAt(a.endNode,CKEDITOR.POSITION_BEFORE_END);g=g.createIterator();for(g.forceBrBreak=this.state==CKEDITOR.TRISTATE_OFF;a=g.getNextParagraph();)if(!a.getCustomData(\"list_block\")){CKEDITOR.dom.element.setMarker(h,a,\"list_block\",1);for(var i=c.elementPath(a),d=i.elements,m=0,i=i.blockLimit,n,l=d.length-1;0<=l&&(n=d[l]);l--)if(r[n.getName()]&&i.contains(n)){i.removeCustomData(\"list_group_object_\"+f);(d=n.getCustomData(\"list_group_object\"))?d.contents.push(a):(d={root:n,contents:[a]},\nj.push(d),CKEDITOR.dom.element.setMarker(h,n,\"list_group_object\",d));m=1;break}m||(m=i,m.getCustomData(\"list_group_object_\"+f)?m.getCustomData(\"list_group_object_\"+f).contents.push(a):(d={root:m,contents:[a]},CKEDITOR.dom.element.setMarker(h,m,\"list_group_object_\"+f,d),j.push(d)))}}for(n=[];0<j.length;)if(d=j.shift(),this.state==CKEDITOR.TRISTATE_OFF)if(r[d.root.getName()]){b=c;f=d;d=h;g=n;m=CKEDITOR.plugins.list.listToArray(f.root,d);i=[];for(a=0;a<f.contents.length;a++)if(l=f.contents[a],(l=l.getAscendant(\"li\",\n!0))&&!l.getCustomData(\"list_item_processed\"))i.push(l),CKEDITOR.dom.element.setMarker(d,l,\"list_item_processed\",!0);for(var l=f.root.getDocument(),p=void 0,o=void 0,a=0;a<i.length;a++){var u=i[a].getCustomData(\"listarray_index\"),p=m[u].parent;p.is(this.type)||(o=l.createElement(this.type),p.copyAttributes(o,{start:1,type:1}),o.removeStyle(\"list-style-type\"),m[u].parent=o)}d=CKEDITOR.plugins.list.arrayToList(m,d,null,b.config.enterMode);m=void 0;i=d.listNode.getChildCount();for(a=0;a<i&&(m=d.listNode.getChild(a));a++)m.getName()==\nthis.type&&g.push(m);d.listNode.replace(f.root);b.fire(\"contentDomInvalidated\")}else{m=c;a=d;g=n;i=a.contents;b=a.root.getDocument();f=[];1==i.length&&i[0].equals(a.root)&&(d=b.createElement(\"div\"),i[0].moveChildren&&i[0].moveChildren(d),i[0].append(d),i[0]=d);a=a.contents[0].getParent();for(l=0;l<i.length;l++)a=a.getCommonAncestor(i[l].getParent());p=m.config.useComputedState;m=d=void 0;p=void 0===p||p;for(l=0;l<i.length;l++)for(o=i[l];u=o.getParent();){if(u.equals(a)){f.push(o);!m&&o.getDirection()&&\n(m=1);o=o.getDirection(p);null!==d&&(d=d&&d!=o?null:o);break}o=u}if(!(1>f.length)){i=f[f.length-1].getNext();l=b.createElement(this.type);g.push(l);for(p=g=void 0;f.length;)g=f.shift(),p=b.createElement(\"li\"),g.is(\"pre\")||H.test(g.getName())||\"false\"==g.getAttribute(\"contenteditable\")?g.appendTo(p):(g.copyAttributes(p),d&&g.getDirection()&&(p.removeStyle(\"direction\"),p.removeAttribute(\"dir\")),g.moveChildren(p),g.remove()),p.appendTo(l);d&&m&&l.setAttribute(\"dir\",d);i?l.insertBefore(i):l.appendTo(a)}}else this.state==\nCKEDITOR.TRISTATE_ON&&r[d.root.getName()]&&E.call(this,c,d,h);for(l=0;l<n.length;l++)B(n[l]);CKEDITOR.dom.element.clearAllMarkers(h);e.selectBookmarks(k);c.focus()},refresh:function(c,k){var e=k.contains(r,1),b=k.blockLimit||k.root;e&&b.contains(e)?this.setState(e.is(this.type)?CKEDITOR.TRISTATE_ON:CKEDITOR.TRISTATE_OFF):this.setState(CKEDITOR.TRISTATE_OFF)}};CKEDITOR.plugins.add(\"list\",{requires:\"indentlist\",init:function(c){c.blockless||(c.addCommand(\"numberedlist\",new x(\"numberedlist\",\"ol\")),c.addCommand(\"bulletedlist\",\nnew x(\"bulletedlist\",\"ul\")),c.ui.addButton&&(c.ui.addButton(\"NumberedList\",{label:c.lang.list.numberedlist,command:\"numberedlist\",directional:!0,toolbar:\"list,10\"}),c.ui.addButton(\"BulletedList\",{label:c.lang.list.bulletedlist,command:\"bulletedlist\",directional:!0,toolbar:\"list,20\"})),c.on(\"key\",function(k){var e=k.data.keyCode;if(c.mode==\"wysiwyg\"&&e in{8:1,46:1}){var b=c.getSelection().getRanges()[0],j=b&&b.startPath();if(b&&b.collapsed){var j=new CKEDITOR.dom.elementPath(b.startContainer),g=e==\n8,h=c.editable(),f=new CKEDITOR.dom.walker(b.clone());f.evaluator=function(a){return q(a)&&!v(a)};f.guard=function(a,b){return!(b&&a.type==CKEDITOR.NODE_ELEMENT&&a.is(\"table\"))};e=b.clone();if(g){var a,d;if((a=j.contains(r))&&b.checkBoundaryOfElement(a,CKEDITOR.START)&&(a=a.getParent())&&a.is(\"li\")&&(a=w(a))){d=a;a=a.getPrevious(q);e.moveToPosition(a&&v(a)?a:d,CKEDITOR.POSITION_BEFORE_START)}else{f.range.setStartAt(h,CKEDITOR.POSITION_AFTER_START);f.range.setEnd(b.startContainer,b.startOffset);if((a=\nf.previous())&&a.type==CKEDITOR.NODE_ELEMENT&&(a.getName()in r||a.is(\"li\"))){if(!a.is(\"li\")){f.range.selectNodeContents(a);f.reset();f.evaluator=C;a=f.previous()}d=a;e.moveToElementEditEnd(d)}}if(d){y(c,e,b);k.cancel()}else if((e=j.contains(r))&&b.checkBoundaryOfElement(e,CKEDITOR.START)){d=e.getFirst(q);if(b.checkBoundaryOfElement(d,CKEDITOR.START)){a=e.getPrevious(q);if(w(d)){if(a){b.moveToElementEditEnd(a);b.select()}}else c.execCommand(\"outdent\");k.cancel()}}}else if(d=j.contains(\"li\")){f.range.setEndAt(h,\nCKEDITOR.POSITION_BEFORE_END);h=(j=d.getLast(q))&&C(j)?j:d;d=0;if((a=f.next())&&a.type==CKEDITOR.NODE_ELEMENT&&a.getName()in r&&a.equals(j)){d=1;a=f.next()}else b.checkBoundaryOfElement(h,CKEDITOR.END)&&(d=1);if(d&&a){b=b.clone();b.moveToElementEditStart(a);y(c,e,b);k.cancel()}}else{f.range.setEndAt(h,CKEDITOR.POSITION_BEFORE_END);if((a=f.next())&&a.type==CKEDITOR.NODE_ELEMENT&&a.is(r)){a=a.getFirst(q);if(j.block&&b.checkStartOfBlock()&&b.checkEndOfBlock()){j.block.remove();b.moveToElementEditStart(a);\nb.select()}else if(w(a)){b.moveToElementEditStart(a);b.select()}else{b=b.clone();b.moveToElementEditStart(a);y(c,e,b)}k.cancel()}}setTimeout(function(){c.selectionChange(1)})}}}))}})})();(function(){function Q(a,c,d){return m(c)&&m(d)&&d.equals(c.getNext(function(a){return!(z(a)||A(a)||p(a))}))}function u(a){this.upper=a[0];this.lower=a[1];this.set.apply(this,a.slice(2))}function J(a){var c=a.element;if(c&&m(c)&&(c=c.getAscendant(a.triggers,!0))&&a.editable.contains(c)){var d=K(c,!0);if(\"true\"==d.getAttribute(\"contenteditable\"))return c;if(d.is(a.triggers))return d}return null}function ga(a,c,d){o(a,c);o(a,d);a=c.size.bottom;d=d.size.top;return a&&d?0|(a+d)/2:a||d}function r(a,c,\nd){return c=c[d?\"getPrevious\":\"getNext\"](function(b){return b&&b.type==CKEDITOR.NODE_TEXT&&!z(b)||m(b)&&!p(b)&&!v(a,b)})}function K(a,c){if(a.data(\"cke-editable\"))return null;for(c||(a=a.getParent());a&&!a.data(\"cke-editable\");){if(a.hasAttribute(\"contenteditable\"))return a;a=a.getParent()}return null}function ha(a){var c=a.doc,d=B('<span contenteditable=\"false\" style=\"'+L+\"position:absolute;border-top:1px dashed \"+a.boxColor+'\"></span>',c),b=this.path+\"images/\"+(n.hidpi?\"hidpi/\":\"\")+\"icon.png\";q(d,\n{attach:function(){this.wrap.getParent()||this.wrap.appendTo(a.editable,!0);return this},lineChildren:[q(B('<span title=\"'+a.editor.lang.magicline.title+'\" contenteditable=\"false\">&#8629;</span>',c),{base:L+\"height:17px;width:17px;\"+(a.rtl?\"left\":\"right\")+\":17px;background:url(\"+b+\") center no-repeat \"+a.boxColor+\";cursor:pointer;\"+(n.hc?\"font-size: 15px;line-height:14px;border:1px solid #fff;text-align:center;\":\"\")+(n.hidpi?\"background-size: 9px 10px;\":\"\"),looks:[\"top:-8px;\"+CKEDITOR.tools.cssVendorPrefix(\"border-radius\",\n\"2px\",1),\"top:-17px;\"+CKEDITOR.tools.cssVendorPrefix(\"border-radius\",\"2px 2px 0px 0px\",1),\"top:-1px;\"+CKEDITOR.tools.cssVendorPrefix(\"border-radius\",\"0px 0px 2px 2px\",1)]}),q(B(R,c),{base:S+\"left:0px;border-left-color:\"+a.boxColor+\";\",looks:[\"border-width:8px 0 8px 8px;top:-8px\",\"border-width:8px 0 0 8px;top:-8px\",\"border-width:0 0 8px 8px;top:0px\"]}),q(B(R,c),{base:S+\"right:0px;border-right-color:\"+a.boxColor+\";\",looks:[\"border-width:8px 8px 8px 0;top:-8px\",\"border-width:8px 8px 0 0;top:-8px\",\"border-width:0 8px 8px 0;top:0px\"]})],\ndetach:function(){this.wrap.getParent()&&this.wrap.remove();return this},mouseNear:function(){o(a,this);var b=a.holdDistance,c=this.size;return c&&a.mouse.y>c.top-b&&a.mouse.y<c.bottom+b&&a.mouse.x>c.left-b&&a.mouse.x<c.right+b?!0:!1},place:function(){var b=a.view,c=a.editable,d=a.trigger,h=d.upper,g=d.lower,j=h||g,l=j.getParent(),k={};this.trigger=d;h&&o(a,h,!0);g&&o(a,g,!0);o(a,l,!0);a.inInlineMode&&C(a,!0);l.equals(c)?(k.left=b.scroll.x,k.right=-b.scroll.x,k.width=\"\"):(k.left=j.size.left-j.size.margin.left+\nb.scroll.x-(a.inInlineMode?b.editable.left+b.editable.border.left:0),k.width=j.size.outerWidth+j.size.margin.left+j.size.margin.right+b.scroll.x,k.right=\"\");h&&g?k.top=h.size.margin.bottom===g.size.margin.top?0|h.size.bottom+h.size.margin.bottom/2:h.size.margin.bottom<g.size.margin.top?h.size.bottom+h.size.margin.bottom:h.size.bottom+h.size.margin.bottom-g.size.margin.top:h?g||(k.top=h.size.bottom+h.size.margin.bottom):k.top=g.size.top-g.size.margin.top;d.is(x)||k.top>b.scroll.y-15&&k.top<b.scroll.y+\n5?(k.top=a.inInlineMode?0:b.scroll.y,this.look(x)):d.is(y)||k.top>b.pane.bottom-5&&k.top<b.pane.bottom+15?(k.top=a.inInlineMode?b.editable.height+b.editable.padding.top+b.editable.padding.bottom:b.pane.bottom-1,this.look(y)):(a.inInlineMode&&(k.top-=b.editable.top+b.editable.border.top),this.look(s));a.inInlineMode&&(k.top--,k.top+=b.editable.scroll.top,k.left+=b.editable.scroll.left);for(var T in k)k[T]=CKEDITOR.tools.cssLength(k[T]);this.setStyles(k)},look:function(a){if(this.oldLook!=a){for(var b=\nthis.lineChildren.length,c;b--;)(c=this.lineChildren[b]).setAttribute(\"style\",c.base+c.looks[0|a/2]);this.oldLook=a}},wrap:new M(\"span\",a.doc)});for(c=d.lineChildren.length;c--;)d.lineChildren[c].appendTo(d);d.look(s);d.appendTo(d.wrap);d.unselectable();d.lineChildren[0].on(\"mouseup\",function(b){d.detach();N(a,function(b){var c=a.line.trigger;b[c.is(D)?\"insertBefore\":\"insertAfter\"](c.is(D)?c.lower:c.upper)},!0);a.editor.focus();!n.ie&&a.enterMode!=CKEDITOR.ENTER_BR&&a.hotNode.scrollIntoView();b.data.preventDefault(!0)});\nd.on(\"mousedown\",function(a){a.data.preventDefault(!0)});a.line=d}function N(a,c,d){var b=new CKEDITOR.dom.range(a.doc),e=a.editor,f;n.ie&&a.enterMode==CKEDITOR.ENTER_BR?f=a.doc.createText(E):(f=(f=K(a.element,!0))&&f.data(\"cke-enter-mode\")||a.enterMode,f=new M(F[f],a.doc),f.is(\"br\")||a.doc.createText(E).appendTo(f));d&&e.fire(\"saveSnapshot\");c(f);b.moveToPosition(f,CKEDITOR.POSITION_AFTER_START);e.getSelection().selectRanges([b]);a.hotNode=f;d&&e.fire(\"saveSnapshot\")}function U(a,c){return{canUndo:!0,\nmodes:{wysiwyg:1},exec:function(){function d(b){var d=n.ie&&9>n.version?\" \":E,f=a.hotNode&&a.hotNode.getText()==d&&a.element.equals(a.hotNode)&&a.lastCmdDirection===!!c;N(a,function(d){f&&a.hotNode&&a.hotNode.remove();d[c?\"insertAfter\":\"insertBefore\"](b);d.setAttributes({\"data-cke-magicline-hot\":1,\"data-cke-magicline-dir\":!!c});a.lastCmdDirection=!!c});!n.ie&&a.enterMode!=CKEDITOR.ENTER_BR&&a.hotNode.scrollIntoView();a.line.detach()}return function(b){var b=b.getSelection().getStartElement(),e,b=\nb.getAscendant(V,1);if(!W(a,b)&&b&&!b.equals(a.editable)&&!b.contains(a.editable)){if((e=K(b))&&\"false\"==e.getAttribute(\"contenteditable\"))b=e;a.element=b;e=r(a,b,!c);var f;m(e)&&e.is(a.triggers)&&e.is(ia)&&(!r(a,e,!c)||(f=r(a,e,!c))&&m(f)&&f.is(a.triggers))?d(e):(f=J(a,b),m(f)&&(r(a,f,!c)?(b=r(a,f,!c))&&(m(b)&&b.is(a.triggers))&&d(f):d(f)))}}}()}}function v(a,c){if(!c||!(c.type==CKEDITOR.NODE_ELEMENT&&c.$))return!1;var d=a.line;return d.wrap.equals(c)||d.wrap.contains(c)}function m(a){return a&&\na.type==CKEDITOR.NODE_ELEMENT&&a.$}function p(a){if(!m(a))return!1;var c;if(!(c=X(a)))m(a)?(c={left:1,right:1,center:1},c=!(!c[a.getComputedStyle(\"float\")]&&!c[a.getAttribute(\"align\")])):c=!1;return c}function X(a){return!!{absolute:1,fixed:1}[a.getComputedStyle(\"position\")]}function G(a,c){return m(c)?c.is(a.triggers):null}function W(a,c){if(!c)return!1;for(var d=c.getParents(1),b=d.length;b--;)for(var e=a.tabuList.length;e--;)if(d[b].hasAttribute(a.tabuList[e]))return!0;return!1}function ja(a,c,\nd){c=c[d?\"getLast\":\"getFirst\"](function(b){return a.isRelevant(b)&&!b.is(ka)});if(!c)return!1;o(a,c);return d?c.size.top>a.mouse.y:c.size.bottom<a.mouse.y}function Y(a){var c=a.editable,d=a.mouse,b=a.view,e=a.triggerOffset;C(a);var f=d.y>(a.inInlineMode?b.editable.top+b.editable.height/2:Math.min(b.editable.height,b.pane.height)/2),c=c[f?\"getLast\":\"getFirst\"](function(a){return!(z(a)||A(a))});if(!c)return null;v(a,c)&&(c=a.line.wrap[f?\"getPrevious\":\"getNext\"](function(a){return!(z(a)||A(a))}));if(!m(c)||\np(c)||!G(a,c))return null;o(a,c);return!f&&0<=c.size.top&&0<d.y&&d.y<c.size.top+e?(a=a.inInlineMode||0===b.scroll.y?x:s,new u([null,c,D,H,a])):f&&c.size.bottom<=b.pane.height&&d.y>c.size.bottom-e&&d.y<b.pane.height?(a=a.inInlineMode||c.size.bottom>b.pane.height-e&&c.size.bottom<b.pane.height?y:s,new u([c,null,Z,H,a])):null}function $(a){var c=a.mouse,d=a.view,b=a.triggerOffset,e=J(a);if(!e)return null;o(a,e);var b=Math.min(b,0|e.size.outerHeight/2),f=[],i,h;if(c.y>e.size.top-1&&c.y<e.size.top+b)h=\n!1;else if(c.y>e.size.bottom-b&&c.y<e.size.bottom+1)h=!0;else return null;if(p(e)||ja(a,e,h)||e.getParent().is(aa))return null;var g=r(a,e,!h);if(g){if(g&&g.type==CKEDITOR.NODE_TEXT)return null;if(m(g)){if(p(g)||!G(a,g)||g.getParent().is(aa))return null;f=[g,e][h?\"reverse\":\"concat\"]().concat([O,H])}}else e.equals(a.editable[h?\"getLast\":\"getFirst\"](a.isRelevant))?(C(a),h&&c.y>e.size.bottom-b&&c.y<d.pane.height&&e.size.bottom>d.pane.height-b&&e.size.bottom<d.pane.height?i=y:0<c.y&&c.y<e.size.top+b&&\n(i=x)):i=s,f=[null,e][h?\"reverse\":\"concat\"]().concat([h?Z:D,H,i,e.equals(a.editable[h?\"getLast\":\"getFirst\"](a.isRelevant))?h?y:x:s]);return 0 in f?new u(f):null}function P(a,c,d,b){for(var e=function(){var b=n.ie?c.$.currentStyle:a.win.$.getComputedStyle(c.$,\"\");return n.ie?function(a){return b[CKEDITOR.tools.cssStyleToDomStyle(a)]}:function(a){return b.getPropertyValue(a)}}(),f=c.getDocumentPosition(),i={},h={},g={},j={},l=t.length;l--;)i[t[l]]=parseInt(e(\"border-\"+t[l]+\"-width\"),10)||0,g[t[l]]=\nparseInt(e(\"padding-\"+t[l]),10)||0,h[t[l]]=parseInt(e(\"margin-\"+t[l]),10)||0;(!d||b)&&I(a,b);j.top=f.y-(d?0:a.view.scroll.y);j.left=f.x-(d?0:a.view.scroll.x);j.outerWidth=c.$.offsetWidth;j.outerHeight=c.$.offsetHeight;j.height=j.outerHeight-(g.top+g.bottom+i.top+i.bottom);j.width=j.outerWidth-(g.left+g.right+i.left+i.right);j.bottom=j.top+j.outerHeight;j.right=j.left+j.outerWidth;a.inInlineMode&&(j.scroll={top:c.$.scrollTop,left:c.$.scrollLeft});return q({border:i,padding:g,margin:h,ignoreScroll:d},\nj,!0)}function o(a,c,d){if(!m(c))return c.size=null;if(c.size){if(c.size.ignoreScroll==d&&c.size.date>new Date-ba)return null}else c.size={};return q(c.size,P(a,c,d),{date:+new Date},!0)}function C(a,c){a.view.editable=P(a,a.editable,c,!0)}function I(a,c){a.view||(a.view={});var d=a.view;if(c||!(d&&d.date>new Date-ba)){var b=a.win,d=b.getScrollPosition(),b=b.getViewPaneSize();q(a.view,{scroll:{x:d.x,y:d.y,width:a.doc.$.documentElement.scrollWidth-b.width,height:a.doc.$.documentElement.scrollHeight-\nb.height},pane:{width:b.width,height:b.height,bottom:b.height+d.y},date:+new Date},!0)}}function la(a,c,d,b){for(var e=b,f=b,i=0,h=!1,g=!1,j=a.view.pane.height,l=a.mouse;l.y+i<j&&0<l.y-i;){h||(h=c(e,b));g||(g=c(f,b));!h&&0<l.y-i&&(e=d(a,{x:l.x,y:l.y-i}));!g&&l.y+i<j&&(f=d(a,{x:l.x,y:l.y+i}));if(h&&g)break;i+=2}return new u([e,f,null,null])}CKEDITOR.plugins.add(\"magicline\",{init:function(a){var c=a.config,d=c.magicline_triggerOffset||30,b={editor:a,enterMode:c.enterMode,triggerOffset:d,holdDistance:0|\nd*(c.magicline_holdDistance||0.5),boxColor:c.magicline_color||\"#ff0000\",rtl:\"rtl\"==c.contentsLangDirection,tabuList:[\"data-cke-hidden-sel\"].concat(c.magicline_tabuList||[]),triggers:c.magicline_everywhere?V:{table:1,hr:1,div:1,ul:1,ol:1,dl:1,form:1,blockquote:1}},e,f,i;b.isRelevant=function(a){return m(a)&&!v(b,a)&&!p(a)};a.on(\"contentDom\",function(){var d=a.editable(),g=a.document,j=a.window;q(b,{editable:d,inInlineMode:d.isInline(),doc:g,win:j,hotNode:null},!0);b.boundary=b.inInlineMode?b.editable:\nb.doc.getDocumentElement();d.is(w.$inline)||(b.inInlineMode&&!X(d)&&d.setStyles({position:\"relative\",top:null,left:null}),ha.call(this,b),I(b),d.attachListener(a,\"beforeUndoImage\",function(){b.line.detach()}),d.attachListener(a,\"beforeGetData\",function(){b.line.wrap.getParent()&&(b.line.detach(),a.once(\"getData\",function(){b.line.attach()},null,null,1E3))},null,null,0),d.attachListener(b.inInlineMode?g:g.getWindow().getFrame(),\"mouseout\",function(c){if(\"wysiwyg\"==a.mode)if(b.inInlineMode){var d=c.data.$.clientX,\nc=c.data.$.clientY;I(b);C(b,!0);var e=b.view.editable,f=b.view.scroll;if(!(d>e.left-f.x&&d<e.right-f.x)||!(c>e.top-f.y&&c<e.bottom-f.y))clearTimeout(i),i=null,b.line.detach()}else clearTimeout(i),i=null,b.line.detach()}),d.attachListener(d,\"keyup\",function(){b.hiddenMode=0}),d.attachListener(d,\"keydown\",function(c){if(\"wysiwyg\"==a.mode)switch(c=c.data.getKeystroke(),a.getSelection().getStartElement(),c){case 2228240:case 16:b.hiddenMode=1,b.line.detach()}}),d.attachListener(b.inInlineMode?d:g,\"mousemove\",\nfunction(c){f=!0;if(!(\"wysiwyg\"!=a.mode||a.readOnly||i)){var d={x:c.data.$.clientX,y:c.data.$.clientY};i=setTimeout(function(){b.mouse=d;i=b.trigger=null;I(b);if(f&&!b.hiddenMode&&a.focusManager.hasFocus&&!b.line.mouseNear()&&(b.element=ca(b,!0)))(b.trigger=Y(b)||$(b)||da(b))&&!W(b,b.trigger.upper||b.trigger.lower)?b.line.attach().place():(b.trigger=null,b.line.detach()),f=!1},30)}}),d.attachListener(j,\"scroll\",function(){\"wysiwyg\"==a.mode&&(b.line.detach(),n.webkit&&(b.hiddenMode=1,clearTimeout(e),\ne=setTimeout(function(){b.mouseDown||(b.hiddenMode=0)},50)))}),d.attachListener(ea?g:j,\"mousedown\",function(){\"wysiwyg\"==a.mode&&(b.line.detach(),b.hiddenMode=1,b.mouseDown=1)}),d.attachListener(ea?g:j,\"mouseup\",function(){b.hiddenMode=0;b.mouseDown=0}),a.addCommand(\"accessPreviousSpace\",U(b)),a.addCommand(\"accessNextSpace\",U(b,!0)),a.setKeystroke([[c.magicline_keystrokePrevious,\"accessPreviousSpace\"],[c.magicline_keystrokeNext,\"accessNextSpace\"]]),a.on(\"loadSnapshot\",function(){var c,d,e,f;for(f in{p:1,\nbr:1,div:1}){c=a.document.getElementsByTag(f);for(e=c.count();e--;)if((d=c.getItem(e)).data(\"cke-magicline-hot\")){b.hotNode=d;b.lastCmdDirection=\"true\"===d.data(\"cke-magicline-dir\")?!0:!1;return}}}),this.backdoor={accessFocusSpace:N,boxTrigger:u,isLine:v,getAscendantTrigger:J,getNonEmptyNeighbour:r,getSize:P,that:b,triggerEdge:$,triggerEditable:Y,triggerExpand:da})},this)}});var q=CKEDITOR.tools.extend,M=CKEDITOR.dom.element,B=M.createFromHtml,n=CKEDITOR.env,ea=CKEDITOR.env.ie&&9>CKEDITOR.env.version,\nw=CKEDITOR.dtd,F={},D=128,Z=64,O=32,H=16,fa=8,x=4,y=2,s=1,E=\" \",aa=w.$listItem,ka=w.$tableContent,ia=q({},w.$nonEditable,w.$empty),V=w.$block,ba=100,L=\"width:0px;height:0px;padding:0px;margin:0px;display:block;z-index:9999;color:#fff;position:absolute;font-size: 0px;line-height:0px;\",S=L+\"border-color:transparent;display:block;border-style:solid;\",R=\"<span>\"+E+\"</span>\";F[CKEDITOR.ENTER_BR]=\"br\";F[CKEDITOR.ENTER_P]=\"p\";F[CKEDITOR.ENTER_DIV]=\"div\";u.prototype={set:function(a,c,d){this.properties=a+\nc+(d||s);return this},is:function(a){return(this.properties&a)==a}};var ca=function(){return function(a,c,d){if(!a.mouse)return null;var b=a.doc,e=a.line.wrap,d=d||a.mouse,f=new CKEDITOR.dom.element(b.$.elementFromPoint(d.x,d.y));c&&v(a,f)&&(e.hide(),f=new CKEDITOR.dom.element(b.$.elementFromPoint(d.x,d.y)),e.show());return!f||!(f.type==CKEDITOR.NODE_ELEMENT&&f.$)||n.ie&&9>n.version&&!a.boundary.equals(f)&&!a.boundary.contains(f)?null:f}}(),z=CKEDITOR.dom.walker.whitespaces(),A=CKEDITOR.dom.walker.nodeType(CKEDITOR.NODE_COMMENT),\nda=function(){function a(a){var b=a.element,e,f,i;if(!m(b)||b.contains(a.editable)||b.isReadOnly())return null;i=la(a,function(a,b){return!b.equals(a)},function(a,b){return ca(a,!0,b)},b);e=i.upper;f=i.lower;if(Q(a,e,f))return i.set(O,fa);if(e&&b.contains(e))for(;!e.getParent().equals(b);)e=e.getParent();else e=b.getFirst(function(b){return c(a,b)});if(f&&b.contains(f))for(;!f.getParent().equals(b);)f=f.getParent();else f=b.getLast(function(b){return c(a,b)});if(!e||!f)return null;o(a,e);o(a,f);if(!(a.mouse.y>\ne.size.top&&a.mouse.y<f.size.bottom))return null;for(var b=Number.MAX_VALUE,h,g,j,l;f&&!f.equals(e)&&(g=e.getNext(a.isRelevant));)h=Math.abs(ga(a,e,g)-a.mouse.y),h<b&&(b=h,j=e,l=g),e=g,o(a,e);if(!j||!l||!(a.mouse.y>j.size.top&&a.mouse.y<l.size.bottom))return null;i.upper=j;i.lower=l;return i.set(O,fa)}function c(a,b){return!(b&&b.type==CKEDITOR.NODE_TEXT||A(b)||p(b)||v(a,b)||b.type==CKEDITOR.NODE_ELEMENT&&b.$&&b.is(\"br\"))}return function(c){var b=a(c),e;if(e=b){e=b.upper;var f=b.lower;e=!e||!f||p(f)||\np(e)||f.equals(e)||e.equals(f)||f.contains(e)||e.contains(f)?!1:G(c,e)&&G(c,f)&&Q(c,e,f)?!0:!1}return e?b:null}}(),t=[\"top\",\"left\",\"right\",\"bottom\"]})();CKEDITOR.config.magicline_keystrokePrevious=CKEDITOR.CTRL+CKEDITOR.SHIFT+51;CKEDITOR.config.magicline_keystrokeNext=CKEDITOR.CTRL+CKEDITOR.SHIFT+52;(function(){function l(a){if(!a||a.type!=CKEDITOR.NODE_ELEMENT||\"form\"!=a.getName())return[];for(var e=[],f=[\"style\",\"className\"],b=0;b<f.length;b++){var d=a.$.elements.namedItem(f[b]);d&&(d=new CKEDITOR.dom.element(d),e.push([d,d.nextSibling]),d.remove())}return e}function o(a,e){if(a&&!(a.type!=CKEDITOR.NODE_ELEMENT||\"form\"!=a.getName())&&0<e.length)for(var f=e.length-1;0<=f;f--){var b=e[f][0],d=e[f][1];d?b.insertBefore(d):b.appendTo(a)}}function n(a,e){var f=l(a),b={},d=a.$;e||(b[\"class\"]=d.className||\n\"\",d.className=\"\");b.inline=d.style.cssText||\"\";e||(d.style.cssText=\"position: static; overflow: visible\");o(f);return b}function p(a,e){var f=l(a),b=a.$;\"class\"in e&&(b.className=e[\"class\"]);\"inline\"in e&&(b.style.cssText=e.inline);o(f)}function q(a){if(!a.editable().isInline()){var e=CKEDITOR.instances,f;for(f in e){var b=e[f];\"wysiwyg\"==b.mode&&!b.readOnly&&(b=b.document.getBody(),b.setAttribute(\"contentEditable\",!1),b.setAttribute(\"contentEditable\",!0))}a.editable().hasFocus&&(a.toolbox.focus(),\na.focus())}}CKEDITOR.plugins.add(\"maximize\",{init:function(a){function e(){var b=d.getViewPaneSize();a.resize(b.width,b.height,null,!0)}if(a.elementMode!=CKEDITOR.ELEMENT_MODE_INLINE){var f=a.lang,b=CKEDITOR.document,d=b.getWindow(),j,k,m,l=CKEDITOR.TRISTATE_OFF;a.addCommand(\"maximize\",{modes:{wysiwyg:!CKEDITOR.env.iOS,source:!CKEDITOR.env.iOS},readOnly:1,editorFocus:!1,exec:function(){var h=a.container.getChild(1),g=a.ui.space(\"contents\");if(\"wysiwyg\"==a.mode){var c=a.getSelection();j=c&&c.getRanges();\nk=d.getScrollPosition()}else{var i=a.editable().$;j=!CKEDITOR.env.ie&&[i.selectionStart,i.selectionEnd];k=[i.scrollLeft,i.scrollTop]}if(this.state==CKEDITOR.TRISTATE_OFF){d.on(\"resize\",e);m=d.getScrollPosition();for(c=a.container;c=c.getParent();)c.setCustomData(\"maximize_saved_styles\",n(c)),c.setStyle(\"z-index\",a.config.baseFloatZIndex-5);g.setCustomData(\"maximize_saved_styles\",n(g,!0));h.setCustomData(\"maximize_saved_styles\",n(h,!0));g={overflow:CKEDITOR.env.webkit?\"\":\"hidden\",width:0,height:0};\nb.getDocumentElement().setStyles(g);!CKEDITOR.env.gecko&&b.getDocumentElement().setStyle(\"position\",\"fixed\");(!CKEDITOR.env.gecko||!CKEDITOR.env.quirks)&&b.getBody().setStyles(g);CKEDITOR.env.ie?setTimeout(function(){d.$.scrollTo(0,0)},0):d.$.scrollTo(0,0);h.setStyle(\"position\",CKEDITOR.env.gecko&&CKEDITOR.env.quirks?\"fixed\":\"absolute\");h.$.offsetLeft;h.setStyles({\"z-index\":a.config.baseFloatZIndex-5,left:\"0px\",top:\"0px\"});h.addClass(\"cke_maximized\");e();g=h.getDocumentPosition();h.setStyles({left:-1*\ng.x+\"px\",top:-1*g.y+\"px\"});CKEDITOR.env.gecko&&q(a)}else if(this.state==CKEDITOR.TRISTATE_ON){d.removeListener(\"resize\",e);g=[g,h];for(c=0;c<g.length;c++)p(g[c],g[c].getCustomData(\"maximize_saved_styles\")),g[c].removeCustomData(\"maximize_saved_styles\");for(c=a.container;c=c.getParent();)p(c,c.getCustomData(\"maximize_saved_styles\")),c.removeCustomData(\"maximize_saved_styles\");CKEDITOR.env.ie?setTimeout(function(){d.$.scrollTo(m.x,m.y)},0):d.$.scrollTo(m.x,m.y);h.removeClass(\"cke_maximized\");CKEDITOR.env.webkit&&\n(h.setStyle(\"display\",\"inline\"),setTimeout(function(){h.setStyle(\"display\",\"block\")},0));a.fire(\"resize\")}this.toggleState();if(c=this.uiItems[0])g=this.state==CKEDITOR.TRISTATE_OFF?f.maximize.maximize:f.maximize.minimize,c=CKEDITOR.document.getById(c._.id),c.getChild(1).setHtml(g),c.setAttribute(\"title\",g),c.setAttribute(\"href\",'javascript:void(\"'+g+'\");');\"wysiwyg\"==a.mode?j?(CKEDITOR.env.gecko&&q(a),a.getSelection().selectRanges(j),(i=a.getSelection().getStartElement())&&i.scrollIntoView(!0)):\nd.$.scrollTo(k.x,k.y):(j&&(i.selectionStart=j[0],i.selectionEnd=j[1]),i.scrollLeft=k[0],i.scrollTop=k[1]);j=k=null;l=this.state;a.fire(\"maximize\",this.state)},canUndo:!1});a.ui.addButton&&a.ui.addButton(\"Maximize\",{label:f.maximize.maximize,command:\"maximize\",toolbar:\"tools,10\"});a.on(\"mode\",function(){var b=a.getCommand(\"maximize\");b.setState(b.state==CKEDITOR.TRISTATE_DISABLED?CKEDITOR.TRISTATE_DISABLED:l)},null,null,100)}}})})();(function(){var c={canUndo:!1,async:!0,exec:function(a){a.getClipboardData({title:a.lang.pastetext.title},function(b){b&&a.fire(\"paste\",{type:\"text\",dataValue:b.dataValue});a.fire(\"afterCommandExec\",{name:\"pastetext\",command:c,returnValue:!!b})})}};CKEDITOR.plugins.add(\"pastetext\",{requires:\"clipboard\",init:function(a){a.addCommand(\"pastetext\",c);a.ui.addButton&&a.ui.addButton(\"PasteText\",{label:a.lang.pastetext.button,command:\"pastetext\",toolbar:\"clipboard,40\"});if(a.config.forcePasteAsPlainText)a.on(\"beforePaste\",\nfunction(a){\"html\"!=a.data.type&&(a.data.type=\"text\")});a.on(\"pasteState\",function(b){a.getCommand(\"pastetext\").setState(b.data)})}})})();(function(){function h(a,d,f){var b=CKEDITOR.cleanWord;b?f():(a=CKEDITOR.getUrl(a.config.pasteFromWordCleanupFile||d+\"filter/default.js\"),CKEDITOR.scriptLoader.load(a,f,null,!0));return!b}function i(a){a.data.type=\"html\"}CKEDITOR.plugins.add(\"pastefromword\",{requires:\"clipboard\",init:function(a){var d=0,f=this.path;a.addCommand(\"pastefromword\",{canUndo:!1,async:!0,exec:function(a){var e=this;d=1;a.once(\"beforePaste\",i);a.getClipboardData({title:a.lang.pastefromword.title},function(c){c&&a.fire(\"paste\",\n{type:\"html\",dataValue:c.dataValue});a.fire(\"afterCommandExec\",{name:\"pastefromword\",command:e,returnValue:!!c})})}});a.ui.addButton&&a.ui.addButton(\"PasteFromWord\",{label:a.lang.pastefromword.toolbar,command:\"pastefromword\",toolbar:\"clipboard,50\"});a.on(\"pasteState\",function(b){a.getCommand(\"pastefromword\").setState(b.data)});a.on(\"paste\",function(b){var e=b.data,c=e.dataValue;if(c&&(d||/(class=\\\"?Mso|style=\\\"[^\\\"]*\\bmso\\-|w:WordDocument)/.test(c))){var g=h(a,f,function(){if(g)a.fire(\"paste\",e);\nelse if(!a.config.pasteFromWordPromptCleanup||d||confirm(a.lang.pastefromword.confirmCleanup))e.dataValue=CKEDITOR.cleanWord(c,a)});g&&b.cancel()}},null,null,3)}})})();CKEDITOR.plugins.add(\"removeformat\",{init:function(a){a.addCommand(\"removeFormat\",CKEDITOR.plugins.removeformat.commands.removeformat);a.ui.addButton&&a.ui.addButton(\"RemoveFormat\",{label:a.lang.removeformat.toolbar,command:\"removeFormat\",toolbar:\"cleanup,10\"})}});\nCKEDITOR.plugins.removeformat={commands:{removeformat:{exec:function(a){for(var h=a._.removeFormatRegex||(a._.removeFormatRegex=RegExp(\"^(?:\"+a.config.removeFormatTags.replace(/,/g,\"|\")+\")$\",\"i\")),e=a._.removeAttributes||(a._.removeAttributes=a.config.removeFormatAttributes.split(\",\")),f=CKEDITOR.plugins.removeformat.filter,k=a.getSelection().getRanges(1),l=k.createIterator(),c;c=l.getNextRange();){c.collapsed||c.enlarge(CKEDITOR.ENLARGE_ELEMENT);var i=c.createBookmark(),b=i.startNode,j=i.endNode,\nd=function(b){for(var c=a.elementPath(b),e=c.elements,d=1,g;(g=e[d])&&!g.equals(c.block)&&!g.equals(c.blockLimit);d++)h.test(g.getName())&&f(a,g)&&b.breakParent(g)};d(b);if(j){d(j);for(b=b.getNextSourceNode(!0,CKEDITOR.NODE_ELEMENT);b&&!b.equals(j);)d=b.getNextSourceNode(!1,CKEDITOR.NODE_ELEMENT),!(\"img\"==b.getName()&&b.data(\"cke-realelement\"))&&f(a,b)&&(h.test(b.getName())?b.remove(1):(b.removeAttributes(e),a.fire(\"removeFormatCleanup\",b))),b=d}c.moveToBookmark(i)}a.forceNextSelectionCheck();a.getSelection().selectRanges(k)}}},\nfilter:function(a,h){for(var e=a._.removeFormatFilters||[],f=0;f<e.length;f++)if(!1===e[f](h))return!1;return!0}};CKEDITOR.editor.prototype.addRemoveFormatFilter=function(a){this._.removeFormatFilters||(this._.removeFormatFilters=[]);this._.removeFormatFilters.push(a)};CKEDITOR.config.removeFormatTags=\"b,big,code,del,dfn,em,font,i,ins,kbd,q,s,samp,small,span,strike,strong,sub,sup,tt,u,var\";CKEDITOR.config.removeFormatAttributes=\"class,style,lang,width,height,align,hspace,valign\";(function(){CKEDITOR.plugins.add(\"sourcearea\",{init:function(a){function d(){this.hide();this.setStyle(\"height\",this.getParent().$.clientHeight+\"px\");this.setStyle(\"width\",this.getParent().$.clientWidth+\"px\");this.show()}if(a.elementMode!=CKEDITOR.ELEMENT_MODE_INLINE){var e=CKEDITOR.plugins.sourcearea;a.addMode(\"source\",function(e){var b=a.ui.space(\"contents\").getDocument().createElement(\"textarea\");b.setStyles(CKEDITOR.tools.extend({width:CKEDITOR.env.ie7Compat?\"99%\":\"100%\",height:\"100%\",resize:\"none\",\noutline:\"none\",\"text-align\":\"left\"},CKEDITOR.tools.cssVendorPrefix(\"tab-size\",a.config.sourceAreaTabSize||4)));b.setAttribute(\"dir\",\"ltr\");b.addClass(\"cke_source cke_reset cke_enable_context_menu\");a.ui.space(\"contents\").append(b);b=a.editable(new c(a,b));b.setData(a.getData(1));CKEDITOR.env.ie&&(b.attachListener(a,\"resize\",d,b),b.attachListener(CKEDITOR.document.getWindow(),\"resize\",d,b),CKEDITOR.tools.setTimeout(d,0,b));a.fire(\"ariaWidget\",this);e()});a.addCommand(\"source\",e.commands.source);a.ui.addButton&&\na.ui.addButton(\"Source\",{label:a.lang.sourcearea.toolbar,command:\"source\",toolbar:\"mode,10\"});a.on(\"mode\",function(){a.getCommand(\"source\").setState(\"source\"==a.mode?CKEDITOR.TRISTATE_ON:CKEDITOR.TRISTATE_OFF)})}}});var c=CKEDITOR.tools.createClass({base:CKEDITOR.editable,proto:{setData:function(a){this.setValue(a);this.editor.fire(\"dataReady\")},getData:function(){return this.getValue()},insertHtml:function(){},insertElement:function(){},insertText:function(){},setReadOnly:function(a){this[(a?\"set\":\n\"remove\")+\"Attribute\"](\"readOnly\",\"readonly\")},detach:function(){c.baseProto.detach.call(this);this.clearCustomData();this.remove()}}})})();CKEDITOR.plugins.sourcearea={commands:{source:{modes:{wysiwyg:1,source:1},editorFocus:!1,readOnly:1,exec:function(c){\"wysiwyg\"==c.mode&&c.fire(\"saveSnapshot\");c.getCommand(\"source\").setState(CKEDITOR.TRISTATE_DISABLED);c.setMode(\"source\"==c.mode?\"wysiwyg\":\"source\")},canUndo:!1}}};CKEDITOR.plugins.add(\"specialchar\",{availableLangs:{ar:1,bg:1,ca:1,cs:1,cy:1,de:1,el:1,en:1,eo:1,es:1,et:1,fa:1,fi:1,fr:1,\"fr-ca\":1,gl:1,he:1,hr:1,hu:1,id:1,it:1,ja:1,km:1,ku:1,lv:1,nb:1,nl:1,no:1,pl:1,pt:1,\"pt-br\":1,ru:1,si:1,sk:1,sl:1,sq:1,sv:1,th:1,tr:1,ug:1,uk:1,vi:1,zh:1,\"zh-cn\":1},requires:\"dialog\",init:function(a){var c=this;CKEDITOR.dialog.add(\"specialchar\",this.path+\"dialogs/specialchar.js\");a.addCommand(\"specialchar\",{exec:function(){var b=a.langCode,b=c.availableLangs[b]?b:c.availableLangs[b.replace(/-.*/,\n\"\")]?b.replace(/-.*/,\"\"):\"en\";CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(c.path+\"dialogs/lang/\"+b+\".js\"),function(){CKEDITOR.tools.extend(a.lang.specialchar,c.langEntries[b]);a.openDialog(\"specialchar\")})},modes:{wysiwyg:1},canUndo:!1});a.ui.addButton&&a.ui.addButton(\"SpecialChar\",{label:a.lang.specialchar.toolbar,command:\"specialchar\",toolbar:\"insert,50\"})}});CKEDITOR.config.specialChars=\"! &quot; # $ % &amp; ' ( ) * + - . / 0 1 2 3 4 5 6 7 8 9 : ; &lt; = &gt; ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z [ ] ^ _ ` a b c d e f g h i j k l m n o p q r s t u v w x y z { | } ~ &euro; &lsquo; &rsquo; &ldquo; &rdquo; &ndash; &mdash; &iexcl; &cent; &pound; &curren; &yen; &brvbar; &sect; &uml; &copy; &ordf; &laquo; &not; &reg; &macr; &deg; &sup2; &sup3; &acute; &micro; &para; &middot; &cedil; &sup1; &ordm; &raquo; &frac14; &frac12; &frac34; &iquest; &Agrave; &Aacute; &Acirc; &Atilde; &Auml; &Aring; &AElig; &Ccedil; &Egrave; &Eacute; &Ecirc; &Euml; &Igrave; &Iacute; &Icirc; &Iuml; &ETH; &Ntilde; &Ograve; &Oacute; &Ocirc; &Otilde; &Ouml; &times; &Oslash; &Ugrave; &Uacute; &Ucirc; &Uuml; &Yacute; &THORN; &szlig; &agrave; &aacute; &acirc; &atilde; &auml; &aring; &aelig; &ccedil; &egrave; &eacute; &ecirc; &euml; &igrave; &iacute; &icirc; &iuml; &eth; &ntilde; &ograve; &oacute; &ocirc; &otilde; &ouml; &divide; &oslash; &ugrave; &uacute; &ucirc; &uuml; &yacute; &thorn; &yuml; &OElig; &oelig; &#372; &#374 &#373 &#375; &sbquo; &#8219; &bdquo; &hellip; &trade; &#9658; &bull; &rarr; &rArr; &hArr; &diams; &asymp;\".split(\" \");CKEDITOR.plugins.add(\"menubutton\",{requires:\"button,menu\",onLoad:function(){var d=function(c){var a=this._,b=a.menu;a.state!==CKEDITOR.TRISTATE_DISABLED&&(a.on&&b?b.hide():(a.previousState=a.state,b||(b=a.menu=new CKEDITOR.menu(c,{panel:{className:\"cke_menu_panel\",attributes:{\"aria-label\":c.lang.common.options}}}),b.onHide=CKEDITOR.tools.bind(function(){var b=this.command?c.getCommand(this.command).modes:this.modes;this.setState(!b||b[c.mode]?a.previousState:CKEDITOR.TRISTATE_DISABLED);a.on=0},this),\nthis.onMenu&&b.addListener(this.onMenu)),this.setState(CKEDITOR.TRISTATE_ON),a.on=1,setTimeout(function(){b.show(CKEDITOR.document.getById(a.id),4)},0)))};CKEDITOR.ui.menuButton=CKEDITOR.tools.createClass({base:CKEDITOR.ui.button,$:function(c){delete c.panel;this.base(c);this.hasArrow=!0;this.click=d},statics:{handler:{create:function(c){return new CKEDITOR.ui.menuButton(c)}}}})},beforeInit:function(d){d.ui.addHandler(CKEDITOR.UI_MENUBUTTON,CKEDITOR.ui.menuButton.handler)}});\nCKEDITOR.UI_MENUBUTTON=\"menubutton\";(function(){function o(a,c){var b=0,d;for(d in c)if(c[d]==a){b=1;break}return b}var j=\"\",r=function(){function a(){b.once(\"focus\",g);b.once(\"blur\",c)}function c(b){var b=b.editor,c=d.getScayt(b),g=b.elementMode==CKEDITOR.ELEMENT_MODE_INLINE;c&&(d.setPaused(b,!c.disabled),d.setControlId(b,c.id),c.destroy(!0),delete d.instances[b.name],g&&a())}var b=this,g=function(){if(!(\"undefined\"!=typeof d.instances[b.name]||null!=d.instances[b.name])){var a=b.config,c={};c.srcNodeRef=\"BODY\"==b.editable().$.nodeName?\nb.document.getWindow().$.frameElement:b.editable().$;c.assocApp=\"CKEDITOR.\"+CKEDITOR.version+\"@\"+CKEDITOR.revision;c.customerid=a.scayt_customerid||\"1:WvF0D4-UtPqN1-43nkD4-NKvUm2-daQqk3-LmNiI-z7Ysb4-mwry24-T8YrS3-Q2tpq2\";c.customDictionaryIds=a.scayt_customDictionaryIds||\"\";c.userDictionaryName=a.scayt_userDictionaryName||\"\";c.sLang=a.scayt_sLang||\"en_US\";c.onLoad=function(){CKEDITOR.env.ie&&8>CKEDITOR.env.version||this.addStyle(this.selectorCss(),\"padding-bottom: 2px !important;\");b.editable().hasFocus&&\n!d.isControlRestored(b)&&this.focus()};a=window.scayt_custom_params;if(\"object\"==typeof a)for(var g in a)c[g]=a[g];d.getControlId(b)&&(c.id=d.getControlId(b));var e=new window.scayt(c);e.afterMarkupRemove.push(function(a){(new CKEDITOR.dom.element(a,e.document)).mergeSiblings()});if(c=d.instances[b.name])e.sLang=c.sLang,e.option(c.option()),e.paused=c.paused;d.instances[b.name]=e;try{e.setDisabled(!1===d.isPaused(b))}catch(n){}b.fire(\"showScaytState\")}};b.elementMode==CKEDITOR.ELEMENT_MODE_INLINE?\na():b.on(\"contentDom\",g);b.on(\"contentDomUnload\",function(){for(var a=CKEDITOR.document.getElementsByTag(\"script\"),b=/^dojoIoScript(\\d+)$/i,c=/^https?:\\/\\/svc\\.webspellchecker\\.net\\/spellcheck\\/script\\/ssrv\\.cgi/i,d=0;d<a.count();d++){var g=a.getItem(d),e=g.getId(),f=g.getAttribute(\"src\");e&&(f&&e.match(b)&&f.match(c))&&g.remove()}});b.on(\"beforeCommandExec\",function(a){\"source\"==a.data.name&&\"source\"==b.mode&&d.markControlRestore(b)});b.on(\"afterCommandExec\",function(a){if(d.isScaytEnabled(b)&&\"wysiwyg\"==\nb.mode&&(\"undo\"==a.data.name||\"redo\"==a.data.name))d.getScayt(b).setDisabled(!0),d.refresh_timeout&&window.clearTimeout(d.refresh_timeout),d.refresh_timeout=window.setTimeout(function(){d.getScayt(b).setDisabled(!1);d.getScayt(b).focus();d.getScayt(b).refresh()},10)});b.on(\"destroy\",c);b.on(\"setData\",c);b.on(\"insertElement\",function(){var a=d.getScayt(b);d.isScaytEnabled(b)&&(CKEDITOR.env.ie&&b.getSelection().unlock(!0),window.setTimeout(function(){a.focus();a.refresh()},10))},this,null,50);b.on(\"insertHtml\",\nfunction(){var a=d.getScayt(b);d.isScaytEnabled(b)&&(CKEDITOR.env.ie&&b.getSelection().unlock(!0),window.setTimeout(function(){a.focus();a.refresh()},10))},this,null,50);b.on(\"scaytDialog\",function(a){a.data.djConfig=window.djConfig;a.data.scayt_control=d.getScayt(b);a.data.tab=j;a.data.scayt=window.scayt});var e=b.dataProcessor;(e=e&&e.htmlFilter)&&e.addRules({elements:{span:function(a){if(a.attributes[\"data-scayt_word\"]&&a.attributes[\"data-scaytid\"])return delete a.name,a}}});var e=CKEDITOR.plugins.undo.Image.prototype,\nf=\"function\"==typeof e.equalsContent?\"equalsContent\":\"equals\";e[f]=CKEDITOR.tools.override(e[f],function(a){return function(b){var c=this.contents,g=b.contents,e=d.getScayt(this.editor);e&&d.isScaytReady(this.editor)&&(this.contents=e.reset(c)||\"\",b.contents=e.reset(g)||\"\");e=a.apply(this,arguments);this.contents=c;b.contents=g;return e}});e=CKEDITOR.editor.prototype;e.checkDirty=CKEDITOR.tools.override(e.checkDirty,function(a){return function(){var b=null,c=d.getScayt(this);c&&d.isScaytReady(this)?\n(b=c.reset(this.getSnapshot()),c=c.reset(this._.previousValue),b=b!==c):b=a.apply(this);return b}});b.document&&(b.elementMode!=CKEDITOR.ELEMENT_MODE_INLINE||b.focusManager.hasFocus)&&g()};CKEDITOR.plugins.scayt={engineLoaded:!1,instances:{},controlInfo:{},setControlInfo:function(a,c){a&&(a.name&&\"object\"!=typeof this.controlInfo[a.name])&&(this.controlInfo[a.name]={});for(var b in c)this.controlInfo[a.name][b]=c[b]},isControlRestored:function(a){return a&&a.name&&this.controlInfo[a.name]?this.controlInfo[a.name].restored:\n!1},markControlRestore:function(a){this.setControlInfo(a,{restored:!0})},setControlId:function(a,c){this.setControlInfo(a,{id:c})},getControlId:function(a){return a&&a.name&&this.controlInfo[a.name]&&this.controlInfo[a.name].id?this.controlInfo[a.name].id:null},setPaused:function(a,c){this.setControlInfo(a,{paused:c})},isPaused:function(a){if(a&&a.name&&this.controlInfo[a.name])return this.controlInfo[a.name].paused},getScayt:function(a){return this.instances[a.name]},isScaytReady:function(a){return!0===\nthis.engineLoaded&&\"undefined\"!==typeof window.scayt&&this.getScayt(a)},isScaytEnabled:function(a){return(a=this.getScayt(a))?!1===a.disabled:!1},getUiTabs:function(a){var c=[],b=a.config.scayt_uiTabs||\"1,1,1\",b=b.split(\",\");b[3]=\"1\";for(var d=0;4>d;d++)c[d]=\"undefined\"!=typeof window.scayt&&\"undefined\"!=typeof window.scayt.uiTags?parseInt(b[d],10)&&window.scayt.uiTags[d]:parseInt(b[d],10);\"object\"==typeof a.plugins.wsc?c.push(1):c.push(0);return c},loadEngine:function(a){if(CKEDITOR.env.gecko&&10900>\nCKEDITOR.env.version||CKEDITOR.env.opera||CKEDITOR.env.air)return a.fire(\"showScaytState\");if(!0===this.engineLoaded)return r.apply(a);if(-1==this.engineLoaded)return CKEDITOR.on(\"scaytReady\",function(){r.apply(a)});CKEDITOR.on(\"scaytReady\",r,a);CKEDITOR.on(\"scaytReady\",function(){this.engineLoaded=!0},this,null,0);this.engineLoaded=-1;var c=document.location.protocol,c=-1!=c.search(/https?:/)?c:\"http:\",c=a.config.scayt_srcUrl||c+\"//svc.webspellchecker.net/scayt26/loader__base.js\",b=d.parseUrl(c).path+\n\"/\";void 0==window.scayt?(CKEDITOR._djScaytConfig={baseUrl:b,addOnLoad:[function(){CKEDITOR.fireOnce(\"scaytReady\")}],isDebug:!1},CKEDITOR.document.getHead().append(CKEDITOR.document.createElement(\"script\",{attributes:{type:\"text/javascript\",async:\"true\",src:c}}))):CKEDITOR.fireOnce(\"scaytReady\");return null},parseUrl:function(a){var c;return a.match&&(c=a.match(/(.*)[\\/\\\\](.*?\\.\\w+)$/))?{path:c[1],file:c[2]}:a}};var d=CKEDITOR.plugins.scayt,p=function(a,c,b,d,e,f,h){a.addCommand(d,e);a.addMenuItem(d,\n{label:b,command:d,group:f,order:h})},u={preserveState:!0,editorFocus:!1,canUndo:!1,exec:function(a){if(d.isScaytReady(a)){var c=d.isScaytEnabled(a);this.setState(c?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_ON);a=d.getScayt(a);a.focus();a.setDisabled(c)}else!a.config.scayt_autoStartup&&0<=d.engineLoaded&&(a.focus(),this.setState(CKEDITOR.TRISTATE_DISABLED),d.loadEngine(a))}};CKEDITOR.plugins.add(\"scayt\",{requires:\"menubutton,dialog\",beforeInit:function(a){var c=a.config.scayt_contextMenuItemsOrder||\n\"suggest|moresuggest|control\",b=\"\";if((c=c.split(\"|\"))&&c.length)for(var d=0;d<c.length;d++)b+=\"scayt_\"+c[d]+(c.length!=parseInt(d,10)+1?\",\":\"\");a.config.menu_groups=b+\",\"+a.config.menu_groups},checkEnvironment:function(){return CKEDITOR.env.opera||CKEDITOR.env.air?0:1},init:function(a){var c=a.dataProcessor&&a.dataProcessor.dataFilter,b={elements:{span:function(a){var b=a.attributes;b&&b[\"data-scaytid\"]&&delete a.name}}};c&&c.addRules(b);var g={},e={},f=a.addCommand(\"scaytcheck\",u);CKEDITOR.dialog.add(\"scaytcheck\",\nCKEDITOR.getUrl(this.path+\"dialogs/options.js\"));c=d.getUiTabs(a);a.addMenuGroup(\"scaytButton\");a.addMenuGroup(\"scayt_suggest\",-10);a.addMenuGroup(\"scayt_moresuggest\",-9);a.addMenuGroup(\"scayt_control\",-8);var b={},h=a.lang.scayt;b.scaytToggle={label:h.enable,command:\"scaytcheck\",group:\"scaytButton\"};1==c[0]&&(b.scaytOptions={label:h.options,group:\"scaytButton\",onClick:function(){j=\"options\";a.openDialog(\"scaytcheck\")}});1==c[1]&&(b.scaytLangs={label:h.langs,group:\"scaytButton\",onClick:function(){j=\n\"langs\";a.openDialog(\"scaytcheck\")}});1==c[2]&&(b.scaytDict={label:h.dictionariesTab,group:\"scaytButton\",onClick:function(){j=\"dictionaries\";a.openDialog(\"scaytcheck\")}});b.scaytAbout={label:a.lang.scayt.about,group:\"scaytButton\",onClick:function(){j=\"about\";a.openDialog(\"scaytcheck\")}};1==c[4]&&(b.scaytWSC={label:a.lang.wsc.toolbar,group:\"scaytButton\",command:\"checkspell\"});a.addMenuItems(b);a.ui.add(\"Scayt\",CKEDITOR.UI_MENUBUTTON,{label:h.title,title:CKEDITOR.env.opera?h.opera_title:h.title,modes:{wysiwyg:this.checkEnvironment()},\ntoolbar:\"spellchecker,20\",onRender:function(){f.on(\"state\",function(){this.setState(f.state)},this)},onMenu:function(){var b=d.isScaytEnabled(a);a.getMenuItem(\"scaytToggle\").label=h[b?\"disable\":\"enable\"];var c=d.getUiTabs(a);return{scaytToggle:CKEDITOR.TRISTATE_OFF,scaytOptions:b&&c[0]?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED,scaytLangs:b&&c[1]?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED,scaytDict:b&&c[2]?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED,scaytAbout:b&&c[3]?CKEDITOR.TRISTATE_OFF:\nCKEDITOR.TRISTATE_DISABLED,scaytWSC:c[4]?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED}}});a.contextMenu&&a.addMenuItems&&a.contextMenu.addListener(function(b,c){if(!d.isScaytEnabled(a)||c.getRanges()[0].checkReadOnly())return null;var f=d.getScayt(a),n=f.getScaytNode();if(!n)return null;var i=f.getWord(n);if(!i)return null;var j=f.getLang(),l=a.config.scayt_contextCommands||\"all\",i=window.scayt.getSuggestion(i,j),l=l.split(\"|\"),m;for(m in g){delete a._.menuItems[m];delete a.commands[m]}for(m in e){delete a._.menuItems[m];\ndelete a.commands[m]}if(!i||!i.length){p(a,\"no_sugg\",h.noSuggestions,\"scayt_no_sugg\",{exec:function(){}},\"scayt_control\",1,true);e.scayt_no_sugg=CKEDITOR.TRISTATE_OFF}else{g={};e={};m=a.config.scayt_moreSuggestions||\"on\";var j=false,s=a.config.scayt_maxSuggestions;typeof s!=\"number\"&&(s=5);!s&&(s=i.length);for(var k=0,r=i.length;k<r;k=k+1){var q=\"scayt_suggestion_\"+i[k].replace(\" \",\"_\"),t=function(a,b){return{exec:function(){f.replace(a,b)}}}(n,i[k]);if(k<s){p(a,\"button_\"+q,i[k],q,t,\"scayt_suggest\",\nk+1);e[q]=CKEDITOR.TRISTATE_OFF}else if(m==\"on\"){p(a,\"button_\"+q,i[k],q,t,\"scayt_moresuggest\",k+1);g[q]=CKEDITOR.TRISTATE_OFF;j=true}}if(j){a.addMenuItem(\"scayt_moresuggest\",{label:h.moreSuggestions,group:\"scayt_moresuggest\",order:10,getItems:function(){return g}});e.scayt_moresuggest=CKEDITOR.TRISTATE_OFF}}if(o(\"all\",l)||o(\"ignore\",l)){p(a,\"ignore\",h.ignore,\"scayt_ignore\",{exec:function(){f.ignore(n)}},\"scayt_control\",2);e.scayt_ignore=CKEDITOR.TRISTATE_OFF}if(o(\"all\",l)||o(\"ignoreall\",l)){p(a,\"ignore_all\",\nh.ignoreAll,\"scayt_ignore_all\",{exec:function(){f.ignoreAll(n)}},\"scayt_control\",3);e.scayt_ignore_all=CKEDITOR.TRISTATE_OFF}if(o(\"all\",l)||o(\"add\",l)){p(a,\"add_word\",h.addWord,\"scayt_add_word\",{exec:function(){window.scayt.addWordToUserDictionary(n)}},\"scayt_control\",4);e.scayt_add_word=CKEDITOR.TRISTATE_OFF}f.fireOnContextMenu&&f.fireOnContextMenu(a);return e});c=function(b){b.removeListener();CKEDITOR.env.opera||CKEDITOR.env.air?f.setState(CKEDITOR.TRISTATE_DISABLED):f.setState(d.isScaytEnabled(a)?\nCKEDITOR.TRISTATE_ON:CKEDITOR.TRISTATE_OFF)};a.on(\"showScaytState\",c);a.on(\"instanceReady\",c);if(a.config.scayt_autoStartup)a.on(\"instanceReady\",function(){d.loadEngine(a)})},afterInit:function(a){var c,b=function(a){if(a.hasAttribute(\"data-scaytid\"))return!1};a._.elementsPath&&(c=a._.elementsPath.filters)&&c.push(b);a.addRemoveFormatFilter&&a.addRemoveFormatFilter(b)}})})();(function(){CKEDITOR.plugins.add(\"stylescombo\",{requires:\"richcombo\",init:function(c){var j=c.config,f=c.lang.stylescombo,e={},i=[],k=[];c.on(\"stylesSet\",function(b){if(b=b.data.styles){for(var a,h,d=0,g=b.length;d<g;d++)if(a=b[d],!(c.blockless&&a.element in CKEDITOR.dtd.$block)&&(h=a.name,a=new CKEDITOR.style(a),!c.filter.customConfig||c.filter.check(a)))a._name=h,a._.enterMode=j.enterMode,a._.weight=d+1E3*(a.type==CKEDITOR.STYLE_OBJECT?1:a.type==CKEDITOR.STYLE_BLOCK?2:3),e[h]=a,i.push(a),k.push(a);\ni.sort(function(a,b){return a._.weight-b._.weight})}});c.ui.addRichCombo(\"Styles\",{label:f.label,title:f.panelTitle,toolbar:\"styles,10\",allowedContent:k,panel:{css:[CKEDITOR.skin.getPath(\"editor\")].concat(j.contentsCss),multiSelect:!0,attributes:{\"aria-label\":f.panelTitle}},init:function(){var b,a,c,d,g,e;g=0;for(e=i.length;g<e;g++)b=i[g],a=b._name,d=b.type,d!=c&&(this.startGroup(f[\"panelTitle\"+d]),c=d),this.add(a,b.type==CKEDITOR.STYLE_OBJECT?a:b.buildPreview(),a);this.commit()},onClick:function(b){c.focus();\nc.fire(\"saveSnapshot\");var b=e[b],a=c.elementPath();c[b.checkActive(a)?\"removeStyle\":\"applyStyle\"](b);c.fire(\"saveSnapshot\")},onRender:function(){c.on(\"selectionChange\",function(b){for(var a=this.getValue(),b=b.data.path.elements,c=0,d=b.length,g;c<d;c++){g=b[c];for(var f in e)if(e[f].checkElementRemovable(g,!0)){f!=a&&this.setValue(f);return}}this.setValue(\"\")},this)},onOpen:function(){var b=c.getSelection().getSelectedElement(),b=c.elementPath(b),a=[0,0,0,0];this.showAll();this.unmarkAll();for(var h in e){var d=\ne[h],g=d.type;d.checkApplicable(b,c.activeFilter)?a[g]++:this.hideItem(h);d.checkActive(b)&&this.mark(h)}a[CKEDITOR.STYLE_BLOCK]||this.hideGroup(f[\"panelTitle\"+CKEDITOR.STYLE_BLOCK]);a[CKEDITOR.STYLE_INLINE]||this.hideGroup(f[\"panelTitle\"+CKEDITOR.STYLE_INLINE]);a[CKEDITOR.STYLE_OBJECT]||this.hideGroup(f[\"panelTitle\"+CKEDITOR.STYLE_OBJECT])},refresh:function(){var b=c.elementPath();if(b){for(var a in e)if(e[a].checkApplicable(b,c.activeFilter))return;this.setState(CKEDITOR.TRISTATE_DISABLED)}},reset:function(){e=\n{};i=[]}})}})})();(function(){function i(c){return{editorFocus:!1,canUndo:!1,modes:{wysiwyg:1},exec:function(d){if(d.editable().hasFocus){var e=d.getSelection(),b;if(b=(new CKEDITOR.dom.elementPath(e.getCommonAncestor(),e.root)).contains({td:1,th:1},1)){var e=d.createRange(),a=CKEDITOR.tools.tryThese(function(){var a=b.getParent().$.cells[b.$.cellIndex+(c?-1:1)];a.parentNode.parentNode;return a},function(){var a=b.getParent(),a=a.getAscendant(\"table\").$.rows[a.$.rowIndex+(c?-1:1)];return a.cells[c?a.cells.length-1:\n0]});if(!a&&!c){for(var f=b.getAscendant(\"table\").$,a=b.getParent().$.cells,f=new CKEDITOR.dom.element(f.insertRow(-1),d.document),g=0,h=a.length;g<h;g++)f.append((new CKEDITOR.dom.element(a[g],d.document)).clone(!1,!1)).appendBogus();e.moveToElementEditStart(f)}else if(a)a=new CKEDITOR.dom.element(a),e.moveToElementEditStart(a),(!e.checkStartOfBlock()||!e.checkEndOfBlock())&&e.selectNodeContents(a);else return!0;e.select(!0);return!0}}return!1}}}var h={editorFocus:!1,modes:{wysiwyg:1,source:1}},\ng={exec:function(c){c.container.focusNext(!0,c.tabIndex)}},f={exec:function(c){c.container.focusPrevious(!0,c.tabIndex)}};CKEDITOR.plugins.add(\"tab\",{init:function(c){for(var d=!1!==c.config.enableTabKeyTools,e=c.config.tabSpaces||0,b=\"\";e--;)b+=\" \";if(b)c.on(\"key\",function(a){9==a.data.keyCode&&(c.insertHtml(b),a.cancel())});if(d)c.on(\"key\",function(a){(9==a.data.keyCode&&c.execCommand(\"selectNextCell\")||a.data.keyCode==CKEDITOR.SHIFT+9&&c.execCommand(\"selectPreviousCell\"))&&a.cancel()});c.addCommand(\"blur\",\nCKEDITOR.tools.extend(g,h));c.addCommand(\"blurBack\",CKEDITOR.tools.extend(f,h));c.addCommand(\"selectNextCell\",i());c.addCommand(\"selectPreviousCell\",i(!0))}})})();\nCKEDITOR.dom.element.prototype.focusNext=function(i,h){var g=void 0===h?this.getTabIndex():h,f,c,d,e,b,a;if(0>=g)for(b=this.getNextSourceNode(i,CKEDITOR.NODE_ELEMENT);b;){if(b.isVisible()&&0===b.getTabIndex()){d=b;break}b=b.getNextSourceNode(!1,CKEDITOR.NODE_ELEMENT)}else for(b=this.getDocument().getBody().getFirst();b=b.getNextSourceNode(!1,CKEDITOR.NODE_ELEMENT);){if(!f)if(!c&&b.equals(this)){if(c=!0,i){if(!(b=b.getNextSourceNode(!0,CKEDITOR.NODE_ELEMENT)))break;f=1}}else c&&!this.contains(b)&&\n(f=1);if(b.isVisible()&&!(0>(a=b.getTabIndex()))){if(f&&a==g){d=b;break}a>g&&(!d||!e||a<e)?(d=b,e=a):!d&&0===a&&(d=b,e=a)}}d&&d.focus()};\nCKEDITOR.dom.element.prototype.focusPrevious=function(i,h){for(var g=void 0===h?this.getTabIndex():h,f,c,d,e=0,b,a=this.getDocument().getBody().getLast();a=a.getPreviousSourceNode(!1,CKEDITOR.NODE_ELEMENT);){if(!f)if(!c&&a.equals(this)){if(c=!0,i){if(!(a=a.getPreviousSourceNode(!0,CKEDITOR.NODE_ELEMENT)))break;f=1}}else c&&!this.contains(a)&&(f=1);if(a.isVisible()&&!(0>(b=a.getTabIndex())))if(0>=g){if(f&&0===b){d=a;break}b>e&&(d=a,e=b)}else{if(f&&b==g){d=a;break}if(b<g&&(!d||b>e))d=a,e=b}}d&&d.focus()};CKEDITOR.plugins.add(\"table\",{requires:\"dialog\",init:function(a){function d(a){return CKEDITOR.tools.extend(a||{},{contextSensitive:1,refresh:function(a,e){this.setState(e.contains(\"table\",1)?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED)}})}if(!a.blockless){var b=a.lang.table;a.addCommand(\"table\",new CKEDITOR.dialogCommand(\"table\",{context:\"table\",allowedContent:\"table{width,height}[align,border,cellpadding,cellspacing,summary];caption tbody thead tfoot;th td tr[scope];\"+(a.plugins.dialogadvtab?\n\"table\"+a.plugins.dialogadvtab.allowedContent():\"\"),requiredContent:\"table\",contentTransformations:[[\"table{width}: sizeToStyle\",\"table[width]: sizeToAttribute\"]]}));a.addCommand(\"tableProperties\",new CKEDITOR.dialogCommand(\"tableProperties\",d()));a.addCommand(\"tableDelete\",d({exec:function(a){var c=a.elementPath().contains(\"table\",1);if(c){var b=c.getParent();1==b.getChildCount()&&!b.is(\"body\",\"td\",\"th\")&&(c=b);a=a.createRange();a.moveToPosition(c,CKEDITOR.POSITION_BEFORE_START);c.remove();a.select()}}}));\na.ui.addButton&&a.ui.addButton(\"Table\",{label:b.toolbar,command:\"table\",toolbar:\"insert,30\"});CKEDITOR.dialog.add(\"table\",this.path+\"dialogs/table.js\");CKEDITOR.dialog.add(\"tableProperties\",this.path+\"dialogs/table.js\");a.addMenuItems&&a.addMenuItems({table:{label:b.menu,command:\"tableProperties\",group:\"table\",order:5},tabledelete:{label:b.deleteTable,command:\"tableDelete\",group:\"table\",order:1}});a.on(\"doubleclick\",function(a){a.data.element.is(\"table\")&&(a.data.dialog=\"tableProperties\")});a.contextMenu&&\na.contextMenu.addListener(function(){return{tabledelete:CKEDITOR.TRISTATE_OFF,table:CKEDITOR.TRISTATE_OFF}})}}});(function(){function p(e){function d(a){!(0<b.length)&&(a.type==CKEDITOR.NODE_ELEMENT&&y.test(a.getName())&&!a.getCustomData(\"selected_cell\"))&&(CKEDITOR.dom.element.setMarker(c,a,\"selected_cell\",!0),b.push(a))}for(var e=e.getRanges(),b=[],c={},a=0;a<e.length;a++){var f=e[a];if(f.collapsed)f=f.getCommonAncestor(),(f=f.getAscendant(\"td\",!0)||f.getAscendant(\"th\",!0))&&b.push(f);else{var f=new CKEDITOR.dom.walker(f),g;for(f.guard=d;g=f.next();)if(g.type!=CKEDITOR.NODE_ELEMENT||!g.is(CKEDITOR.dtd.table))if((g=\ng.getAscendant(\"td\",!0)||g.getAscendant(\"th\",!0))&&!g.getCustomData(\"selected_cell\"))CKEDITOR.dom.element.setMarker(c,g,\"selected_cell\",!0),b.push(g)}}CKEDITOR.dom.element.clearAllMarkers(c);return b}function o(e,d){for(var b=p(e),c=b[0],a=c.getAscendant(\"table\"),c=c.getDocument(),f=b[0].getParent(),g=f.$.rowIndex,b=b[b.length-1],h=b.getParent().$.rowIndex+b.$.rowSpan-1,b=new CKEDITOR.dom.element(a.$.rows[h]),g=d?g:h,f=d?f:b,b=CKEDITOR.tools.buildTableMap(a),a=b[g],g=d?b[g-1]:b[g+1],b=b[0].length,\nc=c.createElement(\"tr\"),h=0;a[h]&&h<b;h++){var i;1<a[h].rowSpan&&g&&a[h]==g[h]?(i=a[h],i.rowSpan+=1):(i=(new CKEDITOR.dom.element(a[h])).clone(),i.removeAttribute(\"rowSpan\"),i.appendBogus(),c.append(i),i=i.$);h+=i.colSpan-1}d?c.insertBefore(f):c.insertAfter(f)}function q(e){if(e instanceof CKEDITOR.dom.selection){for(var d=p(e),b=d[0].getAscendant(\"table\"),c=CKEDITOR.tools.buildTableMap(b),e=d[0].getParent().$.rowIndex,d=d[d.length-1],a=d.getParent().$.rowIndex+d.$.rowSpan-1,d=[],f=e;f<=a;f++){for(var g=\nc[f],h=new CKEDITOR.dom.element(b.$.rows[f]),i=0;i<g.length;i++){var j=new CKEDITOR.dom.element(g[i]),l=j.getParent().$.rowIndex;1==j.$.rowSpan?j.remove():(j.$.rowSpan-=1,l==f&&(l=c[f+1],l[i-1]?j.insertAfter(new CKEDITOR.dom.element(l[i-1])):(new CKEDITOR.dom.element(b.$.rows[f+1])).append(j,1)));i+=j.$.colSpan-1}d.push(h)}c=b.$.rows;b=new CKEDITOR.dom.element(c[a+1]||(0<e?c[e-1]:null)||b.$.parentNode);for(f=d.length;0<=f;f--)q(d[f]);return b}e instanceof CKEDITOR.dom.element&&(b=e.getAscendant(\"table\"),\n1==b.$.rows.length?b.remove():e.remove());return null}function r(e,d){for(var b=d?Infinity:0,c=0;c<e.length;c++){var a;a=e[c];for(var f=d,g=a.getParent().$.cells,h=0,i=0;i<g.length;i++){var j=g[i],h=h+(f?1:j.colSpan);if(j==a.$)break}a=h-1;if(d?a<b:a>b)b=a}return b}function k(e,d){for(var b=p(e),c=b[0].getAscendant(\"table\"),a=r(b,1),b=r(b),a=d?a:b,f=CKEDITOR.tools.buildTableMap(c),c=[],b=[],g=f.length,h=0;h<g;h++)c.push(f[h][a]),b.push(d?f[h][a-1]:f[h][a+1]);for(h=0;h<g;h++)c[h]&&(1<c[h].colSpan&&\nb[h]==c[h]?(a=c[h],a.colSpan+=1):(a=(new CKEDITOR.dom.element(c[h])).clone(),a.removeAttribute(\"colSpan\"),a.appendBogus(),a[d?\"insertBefore\":\"insertAfter\"].call(a,new CKEDITOR.dom.element(c[h])),a=a.$),h+=a.rowSpan-1)}function u(e,d){var b=e.getStartElement();if(b=b.getAscendant(\"td\",1)||b.getAscendant(\"th\",1)){var c=b.clone();c.appendBogus();d?c.insertBefore(b):c.insertAfter(b)}}function t(e){if(e instanceof CKEDITOR.dom.selection){var e=p(e),d=e[0]&&e[0].getAscendant(\"table\"),b;a:{var c=0;b=e.length-\n1;for(var a={},f,g;f=e[c++];)CKEDITOR.dom.element.setMarker(a,f,\"delete_cell\",!0);for(c=0;f=e[c++];)if((g=f.getPrevious())&&!g.getCustomData(\"delete_cell\")||(g=f.getNext())&&!g.getCustomData(\"delete_cell\")){CKEDITOR.dom.element.clearAllMarkers(a);b=g;break a}CKEDITOR.dom.element.clearAllMarkers(a);g=e[0].getParent();(g=g.getPrevious())?b=g.getLast():(g=e[b].getParent(),b=(g=g.getNext())?g.getChild(0):null)}for(g=e.length-1;0<=g;g--)t(e[g]);b?m(b,!0):d&&d.remove()}else e instanceof CKEDITOR.dom.element&&\n(d=e.getParent(),1==d.getChildCount()?d.remove():e.remove())}function m(e,d){var b=e.getDocument(),c=CKEDITOR.document;CKEDITOR.env.ie&&11>CKEDITOR.env.version&&(c.focus(),b.focus());b=new CKEDITOR.dom.range(b);if(!b[\"moveToElementEdit\"+(d?\"End\":\"Start\")](e))b.selectNodeContents(e),b.collapse(d?!1:!0);b.select(!0)}function v(e,d,b){e=e[d];if(\"undefined\"==typeof b)return e;for(d=0;e&&d<e.length;d++){if(b.is&&e[d]==b.$)return d;if(d==b)return new CKEDITOR.dom.element(e[d])}return b.is?-1:null}function s(e,\nd,b){var c=p(e),a;if((d?1!=c.length:2>c.length)||(a=e.getCommonAncestor())&&a.type==CKEDITOR.NODE_ELEMENT&&a.is(\"table\"))return!1;var f,e=c[0];a=e.getAscendant(\"table\");var g=CKEDITOR.tools.buildTableMap(a),h=g.length,i=g[0].length,j=e.getParent().$.rowIndex,l=v(g,j,e);if(d){var n;try{var m=parseInt(e.getAttribute(\"rowspan\"),10)||1;f=parseInt(e.getAttribute(\"colspan\"),10)||1;n=g[\"up\"==d?j-m:\"down\"==d?j+m:j][\"left\"==d?l-f:\"right\"==d?l+f:l]}catch(z){return!1}if(!n||e.$==n)return!1;c[\"up\"==d||\"left\"==\nd?\"unshift\":\"push\"](new CKEDITOR.dom.element(n))}for(var d=e.getDocument(),o=j,m=n=0,q=!b&&new CKEDITOR.dom.documentFragment(d),s=0,d=0;d<c.length;d++){f=c[d];var k=f.getParent(),t=f.getFirst(),r=f.$.colSpan,u=f.$.rowSpan,k=k.$.rowIndex,w=v(g,k,f),s=s+r*u,m=Math.max(m,w-l+r);n=Math.max(n,k-j+u);if(!b){r=f;(u=r.getBogus())&&u.remove();r.trim();if(f.getChildren().count()){if(k!=o&&t&&(!t.isBlockBoundary||!t.isBlockBoundary({br:1})))(o=q.getLast(CKEDITOR.dom.walker.whitespaces(!0)))&&(!o.is||!o.is(\"br\"))&&\nq.append(\"br\");f.moveChildren(q)}d?f.remove():f.setHtml(\"\")}o=k}if(b)return n*m==s;q.moveChildren(e);e.appendBogus();m>=i?e.removeAttribute(\"rowSpan\"):e.$.rowSpan=n;n>=h?e.removeAttribute(\"colSpan\"):e.$.colSpan=m;b=new CKEDITOR.dom.nodeList(a.$.rows);c=b.count();for(d=c-1;0<=d;d--)a=b.getItem(d),a.$.cells.length||(a.remove(),c++);return e}function w(e,d){var b=p(e);if(1<b.length)return!1;if(d)return!0;var b=b[0],c=b.getParent(),a=c.getAscendant(\"table\"),f=CKEDITOR.tools.buildTableMap(a),g=c.$.rowIndex,\nh=v(f,g,b),i=b.$.rowSpan,j;if(1<i){j=Math.ceil(i/2);for(var i=Math.floor(i/2),c=g+j,a=new CKEDITOR.dom.element(a.$.rows[c]),f=v(f,c),l,c=b.clone(),g=0;g<f.length;g++)if(l=f[g],l.parentNode==a.$&&g>h){c.insertBefore(new CKEDITOR.dom.element(l));break}else l=null;l||a.append(c,!0)}else{i=j=1;a=c.clone();a.insertAfter(c);a.append(c=b.clone());l=v(f,g);for(h=0;h<l.length;h++)l[h].rowSpan++}c.appendBogus();b.$.rowSpan=j;c.$.rowSpan=i;1==j&&b.removeAttribute(\"rowSpan\");1==i&&c.removeAttribute(\"rowSpan\");\nreturn c}function x(e,d){var b=p(e);if(1<b.length)return!1;if(d)return!0;var b=b[0],c=b.getParent(),a=c.getAscendant(\"table\"),a=CKEDITOR.tools.buildTableMap(a),f=v(a,c.$.rowIndex,b),g=b.$.colSpan;if(1<g)c=Math.ceil(g/2),g=Math.floor(g/2);else{for(var g=c=1,h=[],i=0;i<a.length;i++){var j=a[i];h.push(j[f]);1<j[f].rowSpan&&(i+=j[f].rowSpan-1)}for(a=0;a<h.length;a++)h[a].colSpan++}a=b.clone();a.insertAfter(b);a.appendBogus();b.$.colSpan=c;a.$.colSpan=g;1==c&&b.removeAttribute(\"colSpan\");1==g&&a.removeAttribute(\"colSpan\");\nreturn a}var y=/^(?:td|th)$/;CKEDITOR.plugins.tabletools={requires:\"table,dialog,contextmenu\",init:function(e){function d(a){return CKEDITOR.tools.extend(a||{},{contextSensitive:1,refresh:function(a,b){this.setState(b.contains({td:1,th:1},1)?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED)}})}function b(a,b){var c=e.addCommand(a,b);e.addFeature(c)}var c=e.lang.table;b(\"cellProperties\",new CKEDITOR.dialogCommand(\"cellProperties\",d({allowedContent:\"td th{width,height,border-color,background-color,white-space,vertical-align,text-align}[colspan,rowspan]\",\nrequiredContent:\"table\"})));CKEDITOR.dialog.add(\"cellProperties\",this.path+\"dialogs/tableCell.js\");b(\"rowDelete\",d({requiredContent:\"table\",exec:function(a){a=a.getSelection();m(q(a))}}));b(\"rowInsertBefore\",d({requiredContent:\"table\",exec:function(a){a=a.getSelection();o(a,!0)}}));b(\"rowInsertAfter\",d({requiredContent:\"table\",exec:function(a){a=a.getSelection();o(a)}}));b(\"columnDelete\",d({requiredContent:\"table\",exec:function(a){for(var a=a.getSelection(),a=p(a),b=a[0],c=a[a.length-1],a=b.getAscendant(\"table\"),\nd=CKEDITOR.tools.buildTableMap(a),e,j,l=[],n=0,o=d.length;n<o;n++)for(var k=0,q=d[n].length;k<q;k++)d[n][k]==b.$&&(e=k),d[n][k]==c.$&&(j=k);for(n=e;n<=j;n++)for(k=0;k<d.length;k++)c=d[k],b=new CKEDITOR.dom.element(a.$.rows[k]),c=new CKEDITOR.dom.element(c[n]),c.$&&(1==c.$.colSpan?c.remove():c.$.colSpan-=1,k+=c.$.rowSpan-1,b.$.cells.length||l.push(b));j=a.$.rows[0]&&a.$.rows[0].cells;e=new CKEDITOR.dom.element(j[e]||(e?j[e-1]:a.$.parentNode));l.length==o&&a.remove();e&&m(e,!0)}}));b(\"columnInsertBefore\",\nd({requiredContent:\"table\",exec:function(a){a=a.getSelection();k(a,!0)}}));b(\"columnInsertAfter\",d({requiredContent:\"table\",exec:function(a){a=a.getSelection();k(a)}}));b(\"cellDelete\",d({requiredContent:\"table\",exec:function(a){a=a.getSelection();t(a)}}));b(\"cellMerge\",d({allowedContent:\"td[colspan,rowspan]\",requiredContent:\"td[colspan,rowspan]\",exec:function(a){m(s(a.getSelection()),!0)}}));b(\"cellMergeRight\",d({allowedContent:\"td[colspan]\",requiredContent:\"td[colspan]\",exec:function(a){m(s(a.getSelection(),\n\"right\"),!0)}}));b(\"cellMergeDown\",d({allowedContent:\"td[rowspan]\",requiredContent:\"td[rowspan]\",exec:function(a){m(s(a.getSelection(),\"down\"),!0)}}));b(\"cellVerticalSplit\",d({allowedContent:\"td[rowspan]\",requiredContent:\"td[rowspan]\",exec:function(a){m(w(a.getSelection()))}}));b(\"cellHorizontalSplit\",d({allowedContent:\"td[colspan]\",requiredContent:\"td[colspan]\",exec:function(a){m(x(a.getSelection()))}}));b(\"cellInsertBefore\",d({requiredContent:\"table\",exec:function(a){a=a.getSelection();u(a,!0)}}));\nb(\"cellInsertAfter\",d({requiredContent:\"table\",exec:function(a){a=a.getSelection();u(a)}}));e.addMenuItems&&e.addMenuItems({tablecell:{label:c.cell.menu,group:\"tablecell\",order:1,getItems:function(){var a=e.getSelection(),b=p(a);return{tablecell_insertBefore:CKEDITOR.TRISTATE_OFF,tablecell_insertAfter:CKEDITOR.TRISTATE_OFF,tablecell_delete:CKEDITOR.TRISTATE_OFF,tablecell_merge:s(a,null,!0)?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED,tablecell_merge_right:s(a,\"right\",!0)?CKEDITOR.TRISTATE_OFF:\nCKEDITOR.TRISTATE_DISABLED,tablecell_merge_down:s(a,\"down\",!0)?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED,tablecell_split_vertical:w(a,!0)?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED,tablecell_split_horizontal:x(a,!0)?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED,tablecell_properties:0<b.length?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED}}},tablecell_insertBefore:{label:c.cell.insertBefore,group:\"tablecell\",command:\"cellInsertBefore\",order:5},tablecell_insertAfter:{label:c.cell.insertAfter,\ngroup:\"tablecell\",command:\"cellInsertAfter\",order:10},tablecell_delete:{label:c.cell.deleteCell,group:\"tablecell\",command:\"cellDelete\",order:15},tablecell_merge:{label:c.cell.merge,group:\"tablecell\",command:\"cellMerge\",order:16},tablecell_merge_right:{label:c.cell.mergeRight,group:\"tablecell\",command:\"cellMergeRight\",order:17},tablecell_merge_down:{label:c.cell.mergeDown,group:\"tablecell\",command:\"cellMergeDown\",order:18},tablecell_split_horizontal:{label:c.cell.splitHorizontal,group:\"tablecell\",\ncommand:\"cellHorizontalSplit\",order:19},tablecell_split_vertical:{label:c.cell.splitVertical,group:\"tablecell\",command:\"cellVerticalSplit\",order:20},tablecell_properties:{label:c.cell.title,group:\"tablecellproperties\",command:\"cellProperties\",order:21},tablerow:{label:c.row.menu,group:\"tablerow\",order:1,getItems:function(){return{tablerow_insertBefore:CKEDITOR.TRISTATE_OFF,tablerow_insertAfter:CKEDITOR.TRISTATE_OFF,tablerow_delete:CKEDITOR.TRISTATE_OFF}}},tablerow_insertBefore:{label:c.row.insertBefore,\ngroup:\"tablerow\",command:\"rowInsertBefore\",order:5},tablerow_insertAfter:{label:c.row.insertAfter,group:\"tablerow\",command:\"rowInsertAfter\",order:10},tablerow_delete:{label:c.row.deleteRow,group:\"tablerow\",command:\"rowDelete\",order:15},tablecolumn:{label:c.column.menu,group:\"tablecolumn\",order:1,getItems:function(){return{tablecolumn_insertBefore:CKEDITOR.TRISTATE_OFF,tablecolumn_insertAfter:CKEDITOR.TRISTATE_OFF,tablecolumn_delete:CKEDITOR.TRISTATE_OFF}}},tablecolumn_insertBefore:{label:c.column.insertBefore,\ngroup:\"tablecolumn\",command:\"columnInsertBefore\",order:5},tablecolumn_insertAfter:{label:c.column.insertAfter,group:\"tablecolumn\",command:\"columnInsertAfter\",order:10},tablecolumn_delete:{label:c.column.deleteColumn,group:\"tablecolumn\",command:\"columnDelete\",order:15}});e.contextMenu&&e.contextMenu.addListener(function(a,b,c){return(a=c.contains({td:1,th:1},1))&&!a.isReadOnly()?{tablecell:CKEDITOR.TRISTATE_OFF,tablerow:CKEDITOR.TRISTATE_OFF,tablecolumn:CKEDITOR.TRISTATE_OFF}:null})},getSelectedCells:p};\nCKEDITOR.plugins.add(\"tabletools\",CKEDITOR.plugins.tabletools)})();CKEDITOR.tools.buildTableMap=function(p){for(var p=p.$.rows,o=-1,q=[],r=0;r<p.length;r++){o++;!q[o]&&(q[o]=[]);for(var k=-1,u=0;u<p[r].cells.length;u++){var t=p[r].cells[u];for(k++;q[o][k];)k++;for(var m=isNaN(t.colSpan)?1:t.colSpan,t=isNaN(t.rowSpan)?1:t.rowSpan,v=0;v<t;v++){q[o+v]||(q[o+v]=[]);for(var s=0;s<m;s++)q[o+v][k+s]=p[r].cells[u]}k+=m-1}}return q};(function(){function g(a){this.editor=a;this.reset()}CKEDITOR.plugins.add(\"undo\",{init:function(a){function c(a){b.enabled&&!1!==a.data.command.canUndo&&b.save()}function d(){b.enabled=a.readOnly?!1:\"wysiwyg\"==a.mode;b.onChange()}var b=a.undoManager=new g(a),e=a.addCommand(\"undo\",{exec:function(){b.undo()&&(a.selectionChange(),this.fire(\"afterUndo\"))},startDisabled:!0,canUndo:!1}),f=a.addCommand(\"redo\",{exec:function(){b.redo()&&(a.selectionChange(),this.fire(\"afterRedo\"))},startDisabled:!0,canUndo:!1});\na.setKeystroke([[CKEDITOR.CTRL+90,\"undo\"],[CKEDITOR.CTRL+89,\"redo\"],[CKEDITOR.CTRL+CKEDITOR.SHIFT+90,\"redo\"]]);b.onChange=function(){e.setState(b.undoable()?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED);f.setState(b.redoable()?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED)};a.on(\"beforeCommandExec\",c);a.on(\"afterCommandExec\",c);a.on(\"saveSnapshot\",function(a){b.save(a.data&&a.data.contentOnly)});a.on(\"contentDom\",function(){a.editable().on(\"keydown\",function(a){a=a.data.getKey();(8==a||46==\na)&&b.type(a,0)});a.editable().on(\"keypress\",function(a){b.type(a.data.getKey(),1)})});a.on(\"beforeModeUnload\",function(){\"wysiwyg\"==a.mode&&b.save(!0)});a.on(\"mode\",d);a.on(\"readOnly\",d);a.ui.addButton&&(a.ui.addButton(\"Undo\",{label:a.lang.undo.undo,command:\"undo\",toolbar:\"undo,10\"}),a.ui.addButton(\"Redo\",{label:a.lang.undo.redo,command:\"redo\",toolbar:\"undo,20\"}));a.resetUndo=function(){b.reset();a.fire(\"saveSnapshot\")};a.on(\"updateSnapshot\",function(){b.currentImage&&b.update()});a.on(\"lockSnapshot\",\nfunction(a){b.lock(a.data&&a.data.dontUpdate)});a.on(\"unlockSnapshot\",b.unlock,b)}});CKEDITOR.plugins.undo={};var f=CKEDITOR.plugins.undo.Image=function(a,c){this.editor=a;a.fire(\"beforeUndoImage\");var d=a.getSnapshot();CKEDITOR.env.ie&&d&&(d=d.replace(/\\s+data-cke-expando=\".*?\"/g,\"\"));this.contents=d;c||(this.bookmarks=(d=d&&a.getSelection())&&d.createBookmarks2(!0));a.fire(\"afterUndoImage\")},h=/\\b(?:href|src|name)=\"[^\"]*?\"/gi;f.prototype={equalsContent:function(a){var c=this.contents,a=a.contents;\nif(CKEDITOR.env.ie&&(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat))c=c.replace(h,\"\"),a=a.replace(h,\"\");return c!=a?!1:!0},equalsSelection:function(a){var c=this.bookmarks,a=a.bookmarks;if(c||a){if(!c||!a||c.length!=a.length)return!1;for(var d=0;d<c.length;d++){var b=c[d],e=a[d];if(b.startOffset!=e.startOffset||b.endOffset!=e.endOffset||!CKEDITOR.tools.arrayCompare(b.start,e.start)||!CKEDITOR.tools.arrayCompare(b.end,e.end))return!1}}return!0}};g.prototype={type:function(a,c){var d=!c&&a!=this.lastKeystroke,\nb=this.editor;if(!this.typing||c&&!this.wasCharacter||d){var e=new f(b),g=this.snapshots.length;CKEDITOR.tools.setTimeout(function(){var a=b.getSnapshot();CKEDITOR.env.ie&&(a=a.replace(/\\s+data-cke-expando=\".*?\"/g,\"\"));e.contents!=a&&g==this.snapshots.length&&(this.typing=!0,this.save(!1,e,!1)||this.snapshots.splice(this.index+1,this.snapshots.length-this.index-1),this.hasUndo=!0,this.hasRedo=!1,this.modifiersCount=this.typesCount=1,this.onChange())},0,this)}this.lastKeystroke=a;(this.wasCharacter=\nc)?(this.modifiersCount=0,this.typesCount++,25<this.typesCount?(this.save(!1,null,!1),this.typesCount=1):setTimeout(function(){b.fire(\"change\")},0)):(this.typesCount=0,this.modifiersCount++,25<this.modifiersCount?(this.save(!1,null,!1),this.modifiersCount=1):setTimeout(function(){b.fire(\"change\")},0))},reset:function(){this.lastKeystroke=0;this.snapshots=[];this.index=-1;this.limit=this.editor.config.undoStackSize||20;this.currentImage=null;this.hasRedo=this.hasUndo=!1;this.locked=null;this.resetType()},\nresetType:function(){this.typing=!1;delete this.lastKeystroke;this.modifiersCount=this.typesCount=0},fireChange:function(){this.hasUndo=!!this.getNextImage(!0);this.hasRedo=!!this.getNextImage(!1);this.resetType();this.onChange()},save:function(a,c,d){if(this.locked)return!1;var b=this.snapshots;c||(c=new f(this.editor));if(!1===c.contents)return!1;if(this.currentImage)if(c.equalsContent(this.currentImage)){if(a||c.equalsSelection(this.currentImage))return!1}else this.editor.fire(\"change\");b.splice(this.index+\n1,b.length-this.index-1);b.length==this.limit&&b.shift();this.index=b.push(c)-1;this.currentImage=c;!1!==d&&this.fireChange();return!0},restoreImage:function(a){var c=this.editor,d;a.bookmarks&&(c.focus(),d=c.getSelection());this.locked=1;this.editor.loadSnapshot(a.contents);a.bookmarks?d.selectBookmarks(a.bookmarks):CKEDITOR.env.ie&&(d=this.editor.document.getBody().$.createTextRange(),d.collapse(!0),d.select());this.locked=0;this.index=a.index;this.currentImage=this.snapshots[this.index];this.update();\nthis.fireChange();c.fire(\"change\")},getNextImage:function(a){var c=this.snapshots,d=this.currentImage,b;if(d)if(a)for(b=this.index-1;0<=b;b--){if(a=c[b],!d.equalsContent(a))return a.index=b,a}else for(b=this.index+1;b<c.length;b++)if(a=c[b],!d.equalsContent(a))return a.index=b,a;return null},redoable:function(){return this.enabled&&this.hasRedo},undoable:function(){return this.enabled&&this.hasUndo},undo:function(){if(this.undoable()){this.save(!0);var a=this.getNextImage(!0);if(a)return this.restoreImage(a),\n!0}return!1},redo:function(){if(this.redoable()&&(this.save(!0),this.redoable())){var a=this.getNextImage(!1);if(a)return this.restoreImage(a),!0}return!1},update:function(a){if(!this.locked){a||(a=new f(this.editor));for(var c=this.index,d=this.snapshots;0<c&&this.currentImage.equalsContent(d[c-1]);)c-=1;d.splice(c,this.index-c+1,a);this.index=c;this.currentImage=a}},lock:function(a){this.locked?this.locked.level++:a?this.locked={level:1}:(a=new f(this.editor,!0),this.locked={update:this.currentImage&&\nthis.currentImage.equalsContent(a)?a:null,level:1})},unlock:function(){if(this.locked&&!--this.locked.level){var a=this.locked.update,c=a&&new f(this.editor,!0);this.locked=null;a&&!a.equalsContent(c)&&this.update()}}}})();CKEDITOR.config.wsc_removeGlobalVariable=!0;\nCKEDITOR.plugins.add(\"wsc\",{requires:\"dialog\",parseApi:function(a){a.config.wsc_onFinish=\"function\"===typeof a.config.wsc_onFinish?a.config.wsc_onFinish:function(){};a.config.wsc_onClose=\"function\"===typeof a.config.wsc_onClose?a.config.wsc_onClose:function(){}},parseConfig:function(a){a.config.wsc_customerId=a.config.wsc_customerId||CKEDITOR.config.wsc_customerId||\"1:ua3xw1-2XyGJ3-GWruD3-6OFNT1-oXcuB1-nR6Bp4-hgQHc-EcYng3-sdRXG3-NOfFk\";a.config.wsc_customDictionaryIds=a.config.wsc_customDictionaryIds||\nCKEDITOR.config.wsc_customDictionaryIds||\"\";a.config.wsc_userDictionaryName=a.config.wsc_userDictionaryName||CKEDITOR.config.wsc_userDictionaryName||\"\";a.config.wsc_customLoaderScript=a.config.wsc_customLoaderScript||CKEDITOR.config.wsc_customLoaderScript;CKEDITOR.config.wsc_cmd=a.config.wsc_cmd||CKEDITOR.config.wsc_cmd||\"spell\";CKEDITOR.config.wsc_version=\"v4.3.0-1e748a6\"},init:function(a){this.parseConfig(a);this.parseApi(a);a.addCommand(\"checkspell\",new CKEDITOR.dialogCommand(\"checkspell\")).modes=\n{wysiwyg:!CKEDITOR.env.opera&&!CKEDITOR.env.air&&document.domain==window.location.hostname};\"undefined\"==typeof a.plugins.scayt&&a.ui.addButton&&a.ui.addButton(\"SpellChecker\",{label:a.lang.wsc.toolbar,command:\"checkspell\",toolbar:\"spellchecker,10\"});CKEDITOR.dialog.add(\"checkspell\",this.path+(CKEDITOR.env.ie&&8>=CKEDITOR.env.version?\"dialogs/wsc_ie.js\":window.postMessage?\"dialogs/wsc.js\":\"dialogs/wsc_ie.js\"))}});CKEDITOR.config.plugins='dialogui,dialog,about,a11yhelp,basicstyles,blockquote,clipboard,panel,floatpanel,menu,contextmenu,resize,button,toolbar,elementspath,enterkey,entities,popup,filebrowser,floatingspace,listblock,richcombo,format,horizontalrule,htmlwriter,wysiwygarea,image,indent,indentlist,fakeobjects,link,list,magicline,maximize,pastetext,pastefromword,removeformat,sourcearea,specialchar,menubutton,scayt,stylescombo,tab,table,tabletools,undo,wsc';CKEDITOR.config.skin='moono';(function() {var setIcons = function(icons, strip) {var path = CKEDITOR.getUrl( 'plugins/' + strip );icons = icons.split( ',' );for ( var i = 0; i < icons.length; i++ )CKEDITOR.skin.icons[ icons[ i ] ] = { path: path, offset: -icons[ ++i ], bgsize : icons[ ++i ] };};if (CKEDITOR.env.hidpi) setIcons('about,0,,bold,24,,italic,48,,strike,72,,subscript,96,,superscript,120,,underline,144,,blockquote,168,,copy-rtl,192,,copy,216,,cut-rtl,240,,cut,264,,paste-rtl,288,,paste,312,,horizontalrule,336,,image,360,,indent-rtl,384,,indent,408,,outdent-rtl,432,,outdent,456,,anchor-rtl,480,,anchor,504,,link,528,,unlink,552,,bulletedlist-rtl,576,,bulletedlist,600,,numberedlist-rtl,624,,numberedlist,648,,maximize,672,,pastetext-rtl,696,,pastetext,720,,pastefromword-rtl,744,,pastefromword,768,,removeformat,792,,source-rtl,816,,source,840,,specialchar,864,,scayt,888,,table,912,,redo-rtl,936,,redo,960,,undo-rtl,984,,undo,1008,,spellchecker,1032,','icons_hidpi.png');else setIcons('about,0,auto,bold,24,auto,italic,48,auto,strike,72,auto,subscript,96,auto,superscript,120,auto,underline,144,auto,blockquote,168,auto,copy-rtl,192,auto,copy,216,auto,cut-rtl,240,auto,cut,264,auto,paste-rtl,288,auto,paste,312,auto,horizontalrule,336,auto,image,360,auto,indent-rtl,384,auto,indent,408,auto,outdent-rtl,432,auto,outdent,456,auto,anchor-rtl,480,auto,anchor,504,auto,link,528,auto,unlink,552,auto,bulletedlist-rtl,576,auto,bulletedlist,600,auto,numberedlist-rtl,624,auto,numberedlist,648,auto,maximize,672,auto,pastetext-rtl,696,auto,pastetext,720,auto,pastefromword-rtl,744,auto,pastefromword,768,auto,removeformat,792,auto,source-rtl,816,auto,source,840,auto,specialchar,864,auto,scayt,888,auto,table,912,auto,redo-rtl,936,auto,redo,960,auto,undo-rtl,984,auto,undo,1008,auto,spellchecker,1032,auto','icons.png');})();CKEDITOR.lang.languages={\"af\":1,\"sq\":1,\"ar\":1,\"eu\":1,\"bn\":1,\"bs\":1,\"bg\":1,\"ca\":1,\"zh-cn\":1,\"zh\":1,\"hr\":1,\"cs\":1,\"da\":1,\"nl\":1,\"en\":1,\"en-au\":1,\"en-ca\":1,\"en-gb\":1,\"eo\":1,\"et\":1,\"fo\":1,\"fi\":1,\"fr\":1,\"fr-ca\":1,\"gl\":1,\"ka\":1,\"de\":1,\"el\":1,\"gu\":1,\"he\":1,\"hi\":1,\"hu\":1,\"is\":1,\"id\":1,\"it\":1,\"ja\":1,\"km\":1,\"ko\":1,\"ku\":1,\"lv\":1,\"lt\":1,\"mk\":1,\"ms\":1,\"mn\":1,\"no\":1,\"nb\":1,\"fa\":1,\"pl\":1,\"pt-br\":1,\"pt\":1,\"ro\":1,\"ru\":1,\"sr\":1,\"sr-latn\":1,\"si\":1,\"sk\":1,\"sl\":1,\"es\":1,\"sv\":1,\"th\":1,\"tr\":1,\"ug\":1,\"uk\":1,\"vi\":1,\"cy\":1};}());"
  },
  {
    "path": "public/static/plugins/ckeditor/config.js",
    "content": "/**\n * @license Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or http://ckeditor.com/license\n */\n\nCKEDITOR.editorConfig = function( config ) {\n\t// Define changes to default configuration here.\n\t// For the complete reference:\n\t// http://docs.ckeditor.com/#!/api/CKEDITOR.config\n\n\t// The toolbar groups arrangement, optimized for two toolbar rows.\n\tconfig.toolbarGroups = [\n\t\t{ name: 'clipboard',   groups: [ 'clipboard', 'undo' ] },\n\t\t{ name: 'editing',     groups: [ 'find', 'selection', 'spellchecker' ] },\n\t\t{ name: 'links' },\n\t\t{ name: 'insert' },\n\t\t{ name: 'forms' },\n\t\t{ name: 'tools' },\n\t\t{ name: 'document',\t   groups: [ 'mode', 'document', 'doctools' ] },\n\t\t{ name: 'others' },\n\t\t'/',\n\t\t{ name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },\n\t\t{ name: 'paragraph',   groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },\n\t\t{ name: 'styles' },\n\t\t{ name: 'colors' },\n\t\t{ name: 'about' }\n\t];\n\n\t// Remove some buttons, provided by the standard plugins, which we don't\n\t// need to have in the Standard(s) toolbar.\n\tconfig.removeButtons = 'Underline,Subscript,Superscript';\n\n\t// Se the most common block elements.\n\tconfig.format_tags = 'p;h1;h2;h3;pre';\n\n\t// Make dialogs simpler.\n\tconfig.removeDialogTabs = 'image:advanced;link:advanced';\n};\n"
  },
  {
    "path": "public/static/plugins/ckeditor/contents.css",
    "content": "/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n\nbody\n{\n\t/* Font */\n\tfont-family: sans-serif, Arial, Verdana, \"Trebuchet MS\";\n\tfont-size: 12px;\n\n\t/* Text color */\n\tcolor: #333;\n\n\t/* Remove the background color to make it transparent */\n\tbackground-color: #fff;\n\n\tmargin: 20px;\n}\n\n.cke_editable\n{\n\tfont-size: 13px;\n\tline-height: 1.6em;\n}\n\nblockquote\n{\n\tfont-style: italic;\n\tfont-family: Georgia, Times, \"Times New Roman\", serif;\n\tpadding: 2px 0;\n\tborder-style: solid;\n\tborder-color: #ccc;\n\tborder-width: 0;\n}\n\n.cke_contents_ltr blockquote\n{\n\tpadding-left: 20px;\n\tpadding-right: 8px;\n\tborder-left-width: 5px;\n}\n\n.cke_contents_rtl blockquote\n{\n\tpadding-left: 8px;\n\tpadding-right: 20px;\n\tborder-right-width: 5px;\n}\n\na\n{\n\tcolor: #0782C1;\n}\n\nol,ul,dl\n{\n\t/* IE7: reset rtl list margin. (#7334) */\n\t*margin-right: 0px;\n\t/* preserved spaces for list items with text direction other than the list. (#6249,#8049)*/\n\tpadding: 0 40px;\n}\n\nh1,h2,h3,h4,h5,h6\n{\n\tfont-weight: normal;\n\tline-height: 1.2em;\n}\n\nhr\n{\n\tborder: 0px;\n\tborder-top: 1px solid #ccc;\n}\n\nimg.right\n{\n\tborder: 1px solid #ccc;\n\tfloat: right;\n\tmargin-left: 15px;\n\tpadding: 5px;\n}\n\nimg.left\n{\n\tborder: 1px solid #ccc;\n\tfloat: left;\n\tmargin-right: 15px;\n\tpadding: 5px;\n}\n\npre\n{\n\twhite-space: pre-wrap; /* CSS 2.1 */\n\tword-wrap: break-word; /* IE7 */\n}\n\n.marker\n{\n\tbackground-color: Yellow;\n}\n\nspan[lang]\n{\n   font-style: italic;\n}\n\nfigure\n{\n\ttext-align: center;\n\tborder: solid 1px #ccc;\n\tborder-radius: 2px;\n\tbackground: rgba(0,0,0,0.05);\n\tpadding: 10px;\n\tmargin: 10px 20px;\n\tdisplay: block; /* For IE8 */\n}\n\nfigure figcaption\n{\n\ttext-align: center;\n\tdisplay: block; /* For IE8 */\n}\n"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/af.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['af']={\"editor\":\"Teksverwerker\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Druk op ALT 0 vir hulp\",\"browseServer\":\"Blaai op bediener\",\"url\":\"URL\",\"protocol\":\"Protokol\",\"upload\":\"Oplaai\",\"uploadSubmit\":\"Stuur na bediener\",\"image\":\"Afbeelding\",\"flash\":\"Flash\",\"form\":\"Vorm\",\"checkbox\":\"Merkhokkie\",\"radio\":\"Radioknoppie\",\"textField\":\"Teksveld\",\"textarea\":\"Teks-area\",\"hiddenField\":\"Blinde veld\",\"button\":\"Knop\",\"select\":\"Keuseveld\",\"imageButton\":\"Afbeeldingsknop\",\"notSet\":\"<geen instelling>\",\"id\":\"Id\",\"name\":\"Naam\",\"langDir\":\"Skryfrigting\",\"langDirLtr\":\"Links na regs (LTR)\",\"langDirRtl\":\"Regs na links (RTL)\",\"langCode\":\"Taalkode\",\"longDescr\":\"Lang beskrywing URL\",\"cssClass\":\"CSS klasse\",\"advisoryTitle\":\"Aanbevole titel\",\"cssStyle\":\"Styl\",\"ok\":\"OK\",\"cancel\":\"Kanselleer\",\"close\":\"Sluit\",\"preview\":\"Voorbeeld\",\"resize\":\"Sleep om te herskaal\",\"generalTab\":\"Algemeen\",\"advancedTab\":\"Gevorderd\",\"validateNumberFailed\":\"Hierdie waarde is nie 'n getal nie.\",\"confirmNewPage\":\"Alle wysiginge sal verlore gaan. Is u seker dat u 'n nuwe bladsy wil laai?\",\"confirmCancel\":\"Sommige opsies is gewysig. Is u seker dat u hierdie dialoogvenster wil sluit?\",\"options\":\"Opsies\",\"target\":\"Doel\",\"targetNew\":\"Nuwe venster (_blank)\",\"targetTop\":\"Boonste venster (_top)\",\"targetSelf\":\"Selfde venster (_self)\",\"targetParent\":\"Oorspronklike venster (_parent)\",\"langDirLTR\":\"Links na Regs (LTR)\",\"langDirRTL\":\"Regs na Links (RTL)\",\"styles\":\"Styl\",\"cssClasses\":\"CSS klasse\",\"width\":\"Breedte\",\"height\":\"Hoogte\",\"align\":\"Oplyn\",\"alignLeft\":\"Links\",\"alignRight\":\"Regs\",\"alignCenter\":\"Sentreer\",\"alignTop\":\"Bo\",\"alignMiddle\":\"Middel\",\"alignBottom\":\"Onder\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Hoogte moet 'n getal wees\",\"invalidWidth\":\"Breedte moet 'n getal wees.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, nie beskikbaar nie</span>\"},\"about\":{\"copy\":\"Kopiereg &copy; $1. Alle regte voorbehou.\",\"dlgTitle\":\"Info oor CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"Vir lisensie-informasie, besoek asb. ons webwerf:\",\"title\":\"Info oor CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Vet\",\"italic\":\"Skuins\",\"strike\":\"Deurstreep\",\"subscript\":\"Onderskrif\",\"superscript\":\"Bo-skrif\",\"underline\":\"Onderstreep\"},\"blockquote\":{\"toolbar\":\"Sitaatblok\"},\"clipboard\":{\"copy\":\"Kopiëer\",\"copyError\":\"U blaaier se sekuriteitsinstelling belet die kopiëringsaksie. Gebruik die sleutelbordkombinasie (Ctrl/Cmd+C).\",\"cut\":\"Knip\",\"cutError\":\"U blaaier se sekuriteitsinstelling belet die outomatiese knip-aksie. Gebruik die sleutelbordkombinasie (Ctrl/Cmd+X).\",\"paste\":\"Plak\",\"pasteArea\":\"Plak-area\",\"pasteMsg\":\"Plak die teks in die volgende teks-area met die sleutelbordkombinasie (<STRONG>Ctrl/Cmd+V</STRONG>) en druk <STRONG>OK</STRONG>.\",\"securityMsg\":\"Weens u blaaier se sekuriteitsinstelling is data op die knipbord nie toeganklik nie. U kan dit eers weer in hierdie venster plak.\",\"title\":\"Byvoeg\"},\"contextmenu\":{\"options\":\"Konteks Spyskaart-opsies\"},\"toolbar\":{\"toolbarCollapse\":\"Verklein werkbalk\",\"toolbarExpand\":\"Vergroot werkbalk\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editor toolbars\"},\"elementspath\":{\"eleLabel\":\"Elemente-pad\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Opmaak\",\"panelTitle\":\"Opmaak\",\"tag_address\":\"Adres\",\"tag_div\":\"Normaal (DIV)\",\"tag_h1\":\"Opskrif 1\",\"tag_h2\":\"Opskrif 2\",\"tag_h3\":\"Opskrif 3\",\"tag_h4\":\"Opskrif 4\",\"tag_h5\":\"Opskrif 5\",\"tag_h6\":\"Opskrif 6\",\"tag_p\":\"Normaal\",\"tag_pre\":\"Opgemaak\"},\"horizontalrule\":{\"toolbar\":\"Horisontale lyn invoeg\"},\"image\":{\"alertUrl\":\"Gee URL van afbeelding.\",\"alt\":\"Alternatiewe teks\",\"border\":\"Rand\",\"btnUpload\":\"Stuur na bediener\",\"button2Img\":\"Wil u die geselekteerde afbeeldingsknop vervang met 'n eenvoudige afbeelding?\",\"hSpace\":\"HSpasie\",\"img2Button\":\"Wil u die geselekteerde afbeelding vervang met 'n afbeeldingsknop?\",\"infoTab\":\"Afbeelding informasie\",\"linkTab\":\"Skakel\",\"lockRatio\":\"Vaste proporsie\",\"menu\":\"Afbeelding eienskappe\",\"resetSize\":\"Herstel grootte\",\"title\":\"Afbeelding eienskappe\",\"titleButton\":\"Afbeeldingsknop eienskappe\",\"upload\":\"Oplaai\",\"urlMissing\":\"Die URL na die afbeelding ontbreek.\",\"vSpace\":\"VSpasie\",\"validateBorder\":\"Rand moet 'n heelgetal wees.\",\"validateHSpace\":\"HSpasie moet 'n heelgetal wees.\",\"validateVSpace\":\"VSpasie moet 'n heelgetal wees.\"},\"indent\":{\"indent\":\"Vergroot inspring\",\"outdent\":\"Verklein inspring\"},\"fakeobjects\":{\"anchor\":\"Anker\",\"flash\":\"Flash animasie\",\"hiddenfield\":\"Verborge veld\",\"iframe\":\"IFrame\",\"unknown\":\"Onbekende objek\"},\"link\":{\"acccessKey\":\"Toegangsleutel\",\"advanced\":\"Gevorderd\",\"advisoryContentType\":\"Aanbevole inhoudstipe\",\"advisoryTitle\":\"Aanbevole titel\",\"anchor\":{\"toolbar\":\"Anker byvoeg/verander\",\"menu\":\"Anker-eienskappe\",\"title\":\"Anker-eienskappe\",\"name\":\"Ankernaam\",\"errorName\":\"Voltooi die ankernaam asseblief\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"Op element Id\",\"anchorName\":\"Op ankernaam\",\"charset\":\"Karakterstel van geskakelde bron\",\"cssClasses\":\"CSS klasse\",\"emailAddress\":\"E-posadres\",\"emailBody\":\"Berig-inhoud\",\"emailSubject\":\"Berig-onderwerp\",\"id\":\"Id\",\"info\":\"Skakel informasie\",\"langCode\":\"Taalkode\",\"langDir\":\"Skryfrigting\",\"langDirLTR\":\"Links na regs (LTR)\",\"langDirRTL\":\"Regs na links (RTL)\",\"menu\":\"Wysig skakel\",\"name\":\"Naam\",\"noAnchors\":\"(Geen ankers beskikbaar in dokument)\",\"noEmail\":\"Gee die e-posadres\",\"noUrl\":\"Gee die skakel se URL\",\"other\":\"<ander>\",\"popupDependent\":\"Afhanklik (Netscape)\",\"popupFeatures\":\"Eienskappe van opspringvenster\",\"popupFullScreen\":\"Volskerm (IE)\",\"popupLeft\":\"Posisie links\",\"popupLocationBar\":\"Adresbalk\",\"popupMenuBar\":\"Spyskaartbalk\",\"popupResizable\":\"Herskaalbaar\",\"popupScrollBars\":\"Skuifbalke\",\"popupStatusBar\":\"Statusbalk\",\"popupToolbar\":\"Werkbalk\",\"popupTop\":\"Posisie bo\",\"rel\":\"Relationship\",\"selectAnchor\":\"Kies 'n anker\",\"styles\":\"Styl\",\"tabIndex\":\"Tab indeks\",\"target\":\"Doel\",\"targetFrame\":\"<raam>\",\"targetFrameName\":\"Naam van doelraam\",\"targetPopup\":\"<opspringvenster>\",\"targetPopupName\":\"Naam van opspringvenster\",\"title\":\"Skakel\",\"toAnchor\":\"Anker in bladsy\",\"toEmail\":\"E-pos\",\"toUrl\":\"URL\",\"toolbar\":\"Skakel invoeg/wysig\",\"type\":\"Skakelsoort\",\"unlink\":\"Verwyder skakel\",\"upload\":\"Oplaai\"},\"list\":{\"bulletedlist\":\"Ongenommerde lys\",\"numberedlist\":\"Genommerde lys\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maksimaliseer\",\"minimize\":\"Minimaliseer\"},\"pastetext\":{\"button\":\"Plak as eenvoudige teks\",\"title\":\"Plak as eenvoudige teks\"},\"pastefromword\":{\"confirmCleanup\":\"Die teks wat u wil plak lyk asof dit uit Word gekopiëer is. Wil u dit eers skoonmaak voordat dit geplak word?\",\"error\":\"Die geplakte teks kon nie skoongemaak word nie, weens 'n interne fout\",\"title\":\"Plak vanuit Word\",\"toolbar\":\"Plak vanuit Word\"},\"removeformat\":{\"toolbar\":\"Verwyder opmaak\"},\"sourcearea\":{\"toolbar\":\"Bron\"},\"specialchar\":{\"options\":\"Spesiale karakter-opsies\",\"title\":\"Kies spesiale karakter\",\"toolbar\":\"Voeg spesiaale karakter in\"},\"scayt\":{\"about\":\"SCAYT info\",\"aboutTab\":\"Info\",\"addWord\":\"Voeg woord by\",\"allCaps\":\"Ignoreer woorde in hoofletters\",\"dic_create\":\"Skep\",\"dic_delete\":\"Verwijder\",\"dic_field_name\":\"Naam van woordeboek\",\"dic_info\":\"Aanvanklik word die gebruikerswoordeboek in 'n koekie gestoor. Koekies is egter beperk in grootte. Wanneer die gebruikerswoordeboek te groot vir 'n koekie geword het, kan dit op ons bediener gestoor word. Om u persoonlike woordeboek op ons bediener te stoor, gee asb. 'n naam vir u woordeboek. Indien u alreeds 'n gestoorde woordeboek het, tik die naam en kliek op die Herstel knop.\",\"dic_rename\":\"Hernoem\",\"dic_restore\":\"Herstel\",\"dictionariesTab\":\"Woordeboeke\",\"disable\":\"SCAYT af\",\"emptyDic\":\"Woordeboeknaam mag nie leeg wees nie.\",\"enable\":\"SCAYT aan\",\"ignore\":\"Ignoreer\",\"ignoreAll\":\"Ignoreer alles\",\"ignoreDomainNames\":\"Ignoreer domeinname\",\"langs\":\"Tale\",\"languagesTab\":\"Tale\",\"mixedCase\":\"Ignoreer woorde met hoof- en kleinletters\",\"mixedWithDigits\":\"Ignoreer woorde met syfers\",\"moreSuggestions\":\"Meer voorstelle\",\"opera_title\":\"Nie ondersteun deur Opera nie\",\"options\":\"Opsies\",\"optionsTab\":\"Opsies\",\"title\":\"Speltoets terwyl u tik\",\"toggle\":\"SCAYT wissel aan/af\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Styl\",\"panelTitle\":\"Opmaak style\",\"panelTitle1\":\"Blok style\",\"panelTitle2\":\"Inlyn style\",\"panelTitle3\":\"Objek style\"},\"table\":{\"border\":\"Randbreedte\",\"caption\":\"Naam\",\"cell\":{\"menu\":\"Sel\",\"insertBefore\":\"Voeg sel in voor\",\"insertAfter\":\"Voeg sel in na\",\"deleteCell\":\"Verwyder sel\",\"merge\":\"Voeg selle saam\",\"mergeRight\":\"Voeg saam na regs\",\"mergeDown\":\"Voeg saam ondertoe\",\"splitHorizontal\":\"Splits sel horisontaal\",\"splitVertical\":\"Splits sel vertikaal\",\"title\":\"Sel eienskappe\",\"cellType\":\"Sel tipe\",\"rowSpan\":\"Omspan rye\",\"colSpan\":\"Omspan kolomme\",\"wordWrap\":\"Woord terugloop\",\"hAlign\":\"Horisontale oplyning\",\"vAlign\":\"Vertikale oplyning\",\"alignBaseline\":\"Basislyn\",\"bgColor\":\"Agtergrondkleur\",\"borderColor\":\"Randkleur\",\"data\":\"Inhoud\",\"header\":\"Opskrif\",\"yes\":\"Ja\",\"no\":\"Nee\",\"invalidWidth\":\"Selbreedte moet 'n getal wees.\",\"invalidHeight\":\"Selhoogte moet 'n getal wees.\",\"invalidRowSpan\":\"Omspan rye moet 'n heelgetal wees.\",\"invalidColSpan\":\"Omspan kolomme moet 'n heelgetal wees.\",\"chooseColor\":\"Kies\"},\"cellPad\":\"Sel-spasie\",\"cellSpace\":\"Sel-afstand\",\"column\":{\"menu\":\"Kolom\",\"insertBefore\":\"Voeg kolom in voor\",\"insertAfter\":\"Voeg kolom in na\",\"deleteColumn\":\"Verwyder kolom\"},\"columns\":\"Kolomme\",\"deleteTable\":\"Verwyder tabel\",\"headers\":\"Opskrifte\",\"headersBoth\":\"Beide    \",\"headersColumn\":\"Eerste kolom\",\"headersNone\":\"Geen\",\"headersRow\":\"Eerste ry\",\"invalidBorder\":\"Randbreedte moet 'n getal wees.\",\"invalidCellPadding\":\"Sel-spasie moet 'n getal wees.\",\"invalidCellSpacing\":\"Sel-afstand moet 'n getal wees.\",\"invalidCols\":\"Aantal kolomme moet 'n getal groter as 0 wees.\",\"invalidHeight\":\"Tabelhoogte moet 'n getal wees.\",\"invalidRows\":\"Aantal rye moet 'n getal groter as 0 wees.\",\"invalidWidth\":\"Tabelbreedte moet 'n getal wees.\",\"menu\":\"Tabel eienskappe\",\"row\":{\"menu\":\"Ry\",\"insertBefore\":\"Voeg ry in voor\",\"insertAfter\":\"Voeg ry in na\",\"deleteRow\":\"Verwyder ry\"},\"rows\":\"Rye\",\"summary\":\"Opsomming\",\"title\":\"Tabel eienskappe\",\"toolbar\":\"Tabel\",\"widthPc\":\"persent\",\"widthPx\":\"piksels\",\"widthUnit\":\"breedte-eenheid\"},\"undo\":{\"redo\":\"Oordoen\",\"undo\":\"Ontdoen\"},\"wsc\":{\"btnIgnore\":\"Ignoreer\",\"btnIgnoreAll\":\"Ignoreer alles\",\"btnReplace\":\"Vervang\",\"btnReplaceAll\":\"vervang alles\",\"btnUndo\":\"Ontdoen\",\"changeTo\":\"Verander na\",\"errorLoading\":\"Fout by inlaai van diens: %s.\",\"ieSpellDownload\":\"Speltoetser is nie geïnstalleer nie. Wil u dit nou aflaai?\",\"manyChanges\":\"Klaar met speltoets: %1 woorde verander\",\"noChanges\":\"Klaar met speltoets: Geen woorde verander nie\",\"noMispell\":\"Klaar met speltoets: Geen foute nie\",\"noSuggestions\":\"- Geen voorstel -\",\"notAvailable\":\"Jammer, hierdie diens is nie nou beskikbaar nie.\",\"notInDic\":\"Nie in woordeboek nie\",\"oneChange\":\"Klaar met speltoets: Een woord verander\",\"progress\":\"Spelling word getoets...\",\"title\":\"Speltoetser\",\"toolbar\":\"Speltoets\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/ar.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['ar']={\"editor\":\"محرر النص الغني\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"إضغط على ALT + 0 للحصول على المساعدة.\",\"browseServer\":\"تصفح\",\"url\":\"الرابط\",\"protocol\":\"البروتوكول\",\"upload\":\"رفع\",\"uploadSubmit\":\"أرسل\",\"image\":\"صورة\",\"flash\":\"فلاش\",\"form\":\"نموذج\",\"checkbox\":\"خانة إختيار\",\"radio\":\"زر اختيار\",\"textField\":\"مربع نص\",\"textarea\":\"مساحة نصية\",\"hiddenField\":\"إدراج حقل خفي\",\"button\":\"زر ضغط\",\"select\":\"اختار\",\"imageButton\":\"زر صورة\",\"notSet\":\"<بدون تحديد>\",\"id\":\"الرقم\",\"name\":\"إسم\",\"langDir\":\"إتجاه النص\",\"langDirLtr\":\"اليسار لليمين (LTR)\",\"langDirRtl\":\"اليمين لليسار (RTL)\",\"langCode\":\"رمز اللغة\",\"longDescr\":\"الوصف التفصيلى\",\"cssClass\":\"فئات التنسيق\",\"advisoryTitle\":\"عنوان التقرير\",\"cssStyle\":\"نمط\",\"ok\":\"موافق\",\"cancel\":\"إلغاء الأمر\",\"close\":\"أغلق\",\"preview\":\"استعراض\",\"resize\":\"تغيير الحجم\",\"generalTab\":\"عام\",\"advancedTab\":\"متقدم\",\"validateNumberFailed\":\"لايوجد نتيجة\",\"confirmNewPage\":\"ستفقد أي متغييرات اذا لم تقم بحفظها اولا. هل أنت متأكد أنك تريد صفحة جديدة؟\",\"confirmCancel\":\"بعض الخيارات قد تغيرت. هل أنت متأكد من إغلاق مربع النص؟\",\"options\":\"خيارات\",\"target\":\"هدف الرابط\",\"targetNew\":\"نافذة جديدة\",\"targetTop\":\"النافذة الأعلى\",\"targetSelf\":\"داخل النافذة\",\"targetParent\":\"النافذة الأم\",\"langDirLTR\":\"اليسار لليمين (LTR)\",\"langDirRTL\":\"اليمين لليسار (RTL)\",\"styles\":\"نمط\",\"cssClasses\":\"فئات التنسيق\",\"width\":\"العرض\",\"height\":\"الإرتفاع\",\"align\":\"محاذاة\",\"alignLeft\":\"يسار\",\"alignRight\":\"يمين\",\"alignCenter\":\"وسط\",\"alignTop\":\"أعلى\",\"alignMiddle\":\"وسط\",\"alignBottom\":\"أسفل\",\"invalidValue\":\"قيمة غير مفبولة.\",\"invalidHeight\":\"الارتفاع يجب أن يكون عدداً.\",\"invalidWidth\":\"العرض يجب أن يكون عدداً.\",\"invalidCssLength\":\"قيمة الخانة المخصصة لـ \\\"%1\\\" يجب أن تكون رقما موجبا، باستخدام أو من غير استخدام وحدة CSS قياس مقبولة (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"قيمة الخانة المخصصة لـ \\\"%1\\\" يجب أن تكون رقما موجبا، باستخدام أو من غير استخدام وحدة HTML قياس مقبولة (px or %).\",\"invalidInlineStyle\":\"قيمة الخانة المخصصة لـ  Inline Style يجب أن تختوي على مجموع واحد أو أكثر بالشكل التالي: \\\"name : value\\\", مفصولة بفاصلة منقزطة.\",\"cssLengthTooltip\":\"أدخل رقما للقيمة بالبكسل أو رقما بوحدة CSS مقبولة (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, غير متاح</span>\"},\"about\":{\"copy\":\"حقوق النشر &copy; $1. جميع الحقوق محفوظة.\",\"dlgTitle\":\"عن CKEditor\",\"help\":\"راجع $1 من أجل المساعدة\",\"moreInfo\":\"للحصول على معلومات الترخيص ، يرجى زيارة موقعنا:\",\"title\":\"عن CKEditor\",\"userGuide\":\"دليل مستخدم CKEditor.\"},\"basicstyles\":{\"bold\":\"عريض\",\"italic\":\"مائل\",\"strike\":\"يتوسطه خط\",\"subscript\":\"منخفض\",\"superscript\":\"مرتفع\",\"underline\":\"تسطير\"},\"blockquote\":{\"toolbar\":\"اقتباس\"},\"clipboard\":{\"copy\":\"نسخ\",\"copyError\":\"الإعدادات الأمنية للمتصفح الذي تستخدمه تمنع عمليات النسخ التلقائي. فضلاً إستخدم لوحة المفاتيح لفعل ذلك (Ctrl/Cmd+C).\",\"cut\":\"قص\",\"cutError\":\"الإعدادات الأمنية للمتصفح الذي تستخدمه تمنع القص التلقائي. فضلاً إستخدم لوحة المفاتيح لفعل ذلك (Ctrl/Cmd+X).\",\"paste\":\"لصق\",\"pasteArea\":\"منطقة اللصق\",\"pasteMsg\":\"الصق داخل الصندوق بإستخدام زرائر (<STRONG>Ctrl/Cmd+V</STRONG>) في لوحة المفاتيح، ثم اضغط زر  <STRONG>موافق</STRONG>.\",\"securityMsg\":\"نظراً لإعدادات الأمان الخاصة بمتصفحك، لن يتمكن هذا المحرر من الوصول لمحتوى حافظتك، لذلك يجب عليك لصق المحتوى مرة أخرى في هذه النافذة.\",\"title\":\"لصق\"},\"contextmenu\":{\"options\":\"خصائص قائمة السياق\"},\"toolbar\":{\"toolbarCollapse\":\"تقليص شريط الأدوت\",\"toolbarExpand\":\"تمديد شريط الأدوات\",\"toolbarGroups\":{\"document\":\"مستند\",\"clipboard\":\"الحافظة/الرجوع\",\"editing\":\"تحرير\",\"forms\":\"نماذج\",\"basicstyles\":\"نمط بسيط\",\"paragraph\":\"فقرة\",\"links\":\"روابط\",\"insert\":\"إدراج\",\"styles\":\"أنماط\",\"colors\":\"ألوان\",\"tools\":\"أدوات\"},\"toolbars\":\"أشرطة أدوات المحرر\"},\"elementspath\":{\"eleLabel\":\"مسار العنصر\",\"eleTitle\":\"عنصر 1%\"},\"format\":{\"label\":\"تنسيق\",\"panelTitle\":\"تنسيق الفقرة\",\"tag_address\":\"عنوان\",\"tag_div\":\"عادي (DIV)\",\"tag_h1\":\"العنوان 1\",\"tag_h2\":\"العنوان  2\",\"tag_h3\":\"العنوان  3\",\"tag_h4\":\"العنوان  4\",\"tag_h5\":\"العنوان  5\",\"tag_h6\":\"العنوان  6\",\"tag_p\":\"عادي\",\"tag_pre\":\"منسّق\"},\"horizontalrule\":{\"toolbar\":\"خط فاصل\"},\"image\":{\"alertUrl\":\"فضلاً أكتب الموقع الذي توجد عليه هذه الصورة.\",\"alt\":\"عنوان الصورة\",\"border\":\"سمك الحدود\",\"btnUpload\":\"أرسلها للخادم\",\"button2Img\":\"هل تريد تحويل زر الصورة المختار إلى صورة بسيطة؟\",\"hSpace\":\"تباعد أفقي\",\"img2Button\":\"هل تريد تحويل الصورة المختارة إلى زر صورة؟\",\"infoTab\":\"معلومات الصورة\",\"linkTab\":\"الرابط\",\"lockRatio\":\"تناسق الحجم\",\"menu\":\"خصائص الصورة\",\"resetSize\":\"إستعادة الحجم الأصلي\",\"title\":\"خصائص الصورة\",\"titleButton\":\"خصائص زر الصورة\",\"upload\":\"رفع\",\"urlMissing\":\"عنوان مصدر الصورة مفقود\",\"vSpace\":\"تباعد عمودي\",\"validateBorder\":\"الإطار يجب أن يكون عددا\",\"validateHSpace\":\"HSpace يجب أن يكون عدداً.\",\"validateVSpace\":\"VSpace يجب أن يكون عدداً.\"},\"indent\":{\"indent\":\"زيادة المسافة البادئة\",\"outdent\":\"إنقاص المسافة البادئة\"},\"fakeobjects\":{\"anchor\":\"إرساء\",\"flash\":\"رسم متحرك بالفلاش\",\"hiddenfield\":\"إدراج حقل خفي\",\"iframe\":\"iframe\",\"unknown\":\"عنصر غير معروف\"},\"link\":{\"acccessKey\":\"مفاتيح الإختصار\",\"advanced\":\"متقدم\",\"advisoryContentType\":\"نوع التقرير\",\"advisoryTitle\":\"عنوان التقرير\",\"anchor\":{\"toolbar\":\"إشارة مرجعية\",\"menu\":\"تحرير الإشارة المرجعية\",\"title\":\"خصائص الإشارة المرجعية\",\"name\":\"اسم الإشارة المرجعية\",\"errorName\":\"الرجاء كتابة اسم الإشارة المرجعية\",\"remove\":\"إزالة الإشارة المرجعية\"},\"anchorId\":\"حسب رقم العنصر\",\"anchorName\":\"حسب إسم الإشارة المرجعية\",\"charset\":\"ترميز المادة المطلوبة\",\"cssClasses\":\"فئات التنسيق\",\"emailAddress\":\"البريد الإلكتروني\",\"emailBody\":\"محتوى الرسالة\",\"emailSubject\":\"موضوع الرسالة\",\"id\":\"هوية\",\"info\":\"معلومات الرابط\",\"langCode\":\"رمز اللغة\",\"langDir\":\"إتجاه نص اللغة\",\"langDirLTR\":\"اليسار لليمين (LTR)\",\"langDirRTL\":\"اليمين لليسار (RTL)\",\"menu\":\"تحرير الرابط\",\"name\":\"إسم\",\"noAnchors\":\"(لا توجد علامات مرجعية في هذا المستند)\",\"noEmail\":\"الرجاء كتابة الريد الإلكتروني\",\"noUrl\":\"الرجاء كتابة رابط الموقع\",\"other\":\"<أخرى>\",\"popupDependent\":\"تابع (Netscape)\",\"popupFeatures\":\"خصائص النافذة المنبثقة\",\"popupFullScreen\":\"ملئ الشاشة (IE)\",\"popupLeft\":\"التمركز لليسار\",\"popupLocationBar\":\"شريط العنوان\",\"popupMenuBar\":\"القوائم الرئيسية\",\"popupResizable\":\"قابلة التشكيل\",\"popupScrollBars\":\"أشرطة التمرير\",\"popupStatusBar\":\"شريط الحالة\",\"popupToolbar\":\"شريط الأدوات\",\"popupTop\":\"التمركز للأعلى\",\"rel\":\"العلاقة\",\"selectAnchor\":\"اختر علامة مرجعية\",\"styles\":\"نمط\",\"tabIndex\":\"الترتيب\",\"target\":\"هدف الرابط\",\"targetFrame\":\"<إطار>\",\"targetFrameName\":\"اسم الإطار المستهدف\",\"targetPopup\":\"<نافذة منبثقة>\",\"targetPopupName\":\"اسم النافذة المنبثقة\",\"title\":\"رابط\",\"toAnchor\":\"مكان في هذا المستند\",\"toEmail\":\"بريد إلكتروني\",\"toUrl\":\"الرابط\",\"toolbar\":\"رابط\",\"type\":\"نوع الربط\",\"unlink\":\"إزالة رابط\",\"upload\":\"رفع\"},\"list\":{\"bulletedlist\":\"ادخال/حذف تعداد نقطي\",\"numberedlist\":\"ادخال/حذف تعداد رقمي\"},\"magicline\":{\"title\":\"إدراج فقرة هنا\"},\"maximize\":{\"maximize\":\"تكبير\",\"minimize\":\"تصغير\"},\"pastetext\":{\"button\":\"لصق كنص بسيط\",\"title\":\"لصق كنص بسيط\"},\"pastefromword\":{\"confirmCleanup\":\"يبدو أن النص المراد لصقه منسوخ من برنامج وورد. هل تود تنظيفه قبل الشروع في عملية اللصق؟\",\"error\":\"لم يتم مسح المعلومات الملصقة لخلل داخلي\",\"title\":\"لصق من وورد\",\"toolbar\":\"لصق من وورد\"},\"removeformat\":{\"toolbar\":\"إزالة التنسيقات\"},\"sourcearea\":{\"toolbar\":\"المصدر\"},\"specialchar\":{\"options\":\"خيارات الأحرف الخاصة\",\"title\":\"اختر حرف خاص\",\"toolbar\":\"إدراج  حرف خاص\"},\"scayt\":{\"about\":\"عن SCAYT\",\"aboutTab\":\"عن\",\"addWord\":\"إضافة كلمة\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"قواميس\",\"disable\":\"تعطيل SCAYT\",\"emptyDic\":\"اسم القاموس يجب ألا يكون فارغاً.\",\"enable\":\"تفعيل SCAYT\",\"ignore\":\"تجاهل\",\"ignoreAll\":\"تجاهل الكل\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"لغات\",\"languagesTab\":\"لغات\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"المزيد من المقترحات\",\"opera_title\":\"Not supported by Opera\",\"options\":\"خيارات\",\"optionsTab\":\"خيارات\",\"title\":\"تدقيق إملائي أثناء الكتابة\",\"toggle\":\"تثبيت SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"أنماط\",\"panelTitle\":\"أنماط التنسيق\",\"panelTitle1\":\"أنماط الفقرة\",\"panelTitle2\":\"أنماط مضمنة\",\"panelTitle3\":\"أنماط الكائن\"},\"table\":{\"border\":\"الحدود\",\"caption\":\"الوصف\",\"cell\":{\"menu\":\"خلية\",\"insertBefore\":\"إدراج خلية قبل\",\"insertAfter\":\"إدراج خلية بعد\",\"deleteCell\":\"حذف خلية\",\"merge\":\"دمج خلايا\",\"mergeRight\":\"دمج لليمين\",\"mergeDown\":\"دمج للأسفل\",\"splitHorizontal\":\"تقسيم الخلية أفقياً\",\"splitVertical\":\"تقسيم الخلية عمودياً\",\"title\":\"خصائص الخلية\",\"cellType\":\"نوع الخلية\",\"rowSpan\":\"امتداد الصفوف\",\"colSpan\":\"امتداد الأعمدة\",\"wordWrap\":\"التفاف النص\",\"hAlign\":\"محاذاة أفقية\",\"vAlign\":\"محاذاة رأسية\",\"alignBaseline\":\"خط القاعدة\",\"bgColor\":\"لون الخلفية\",\"borderColor\":\"لون الحدود\",\"data\":\"بيانات\",\"header\":\"عنوان\",\"yes\":\"نعم\",\"no\":\"لا\",\"invalidWidth\":\"عرض الخلية يجب أن يكون عدداً.\",\"invalidHeight\":\"ارتفاع الخلية يجب أن يكون عدداً.\",\"invalidRowSpan\":\"امتداد الصفوف يجب أن يكون عدداً صحيحاً.\",\"invalidColSpan\":\"امتداد الأعمدة يجب أن يكون عدداً صحيحاً.\",\"chooseColor\":\"اختر\"},\"cellPad\":\"المسافة البادئة\",\"cellSpace\":\"تباعد الخلايا\",\"column\":{\"menu\":\"عمود\",\"insertBefore\":\"إدراج عمود قبل\",\"insertAfter\":\"إدراج عمود بعد\",\"deleteColumn\":\"حذف أعمدة\"},\"columns\":\"أعمدة\",\"deleteTable\":\"حذف الجدول\",\"headers\":\"العناوين\",\"headersBoth\":\"كلاهما\",\"headersColumn\":\"العمود الأول\",\"headersNone\":\"بدون\",\"headersRow\":\"الصف الأول\",\"invalidBorder\":\"حجم الحد يجب أن يكون عدداً.\",\"invalidCellPadding\":\"المسافة البادئة يجب أن تكون عدداً\",\"invalidCellSpacing\":\"المسافة بين الخلايا يجب أن تكون عدداً.\",\"invalidCols\":\"عدد الأعمدة يجب أن يكون عدداً أكبر من صفر.\",\"invalidHeight\":\"ارتفاع الجدول يجب أن يكون عدداً.\",\"invalidRows\":\"عدد الصفوف يجب أن يكون عدداً أكبر من صفر.\",\"invalidWidth\":\"عرض الجدول يجب أن يكون عدداً.\",\"menu\":\"خصائص الجدول\",\"row\":{\"menu\":\"صف\",\"insertBefore\":\"إدراج صف قبل\",\"insertAfter\":\"إدراج صف بعد\",\"deleteRow\":\"حذف صفوف\"},\"rows\":\"صفوف\",\"summary\":\"الخلاصة\",\"title\":\"خصائص الجدول\",\"toolbar\":\"جدول\",\"widthPc\":\"بالمئة\",\"widthPx\":\"بكسل\",\"widthUnit\":\"وحدة العرض\"},\"undo\":{\"redo\":\"إعادة\",\"undo\":\"تراجع\"},\"wsc\":{\"btnIgnore\":\"تجاهل\",\"btnIgnoreAll\":\"تجاهل الكل\",\"btnReplace\":\"تغيير\",\"btnReplaceAll\":\"تغيير الكل\",\"btnUndo\":\"تراجع\",\"changeTo\":\"التغيير إلى\",\"errorLoading\":\"خطأ في تحميل تطبيق خدمة الاستضافة: %s.\",\"ieSpellDownload\":\"المدقق الإملائي (الإنجليزي) غير مثبّت. هل تود تحميله الآن؟\",\"manyChanges\":\"تم إكمال التدقيق الإملائي: تم تغيير %1 من كلمات\",\"noChanges\":\"تم التدقيق الإملائي: لم يتم تغيير أي كلمة\",\"noMispell\":\"تم التدقيق الإملائي: لم يتم العثور على أي أخطاء إملائية\",\"noSuggestions\":\"- لا توجد إقتراحات -\",\"notAvailable\":\"عفواً، ولكن هذه الخدمة غير متاحة الان\",\"notInDic\":\"ليست في القاموس\",\"oneChange\":\"تم التدقيق الإملائي: تم تغيير كلمة واحدة فقط\",\"progress\":\"جاري التدقيق الاملائى\",\"title\":\"التدقيق الإملائي\",\"toolbar\":\"تدقيق إملائي\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/bg.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['bg']={\"editor\":\"Текстов редактор за форматиран текст\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"натиснете ALT 0 за помощ\",\"browseServer\":\"Избор от сървъра\",\"url\":\"URL\",\"protocol\":\"Протокол\",\"upload\":\"Качване\",\"uploadSubmit\":\"Изпращане към сървъра\",\"image\":\"Снимка\",\"flash\":\"Флаш\",\"form\":\"Форма\",\"checkbox\":\"Поле за избор\",\"radio\":\"Радио бутон\",\"textField\":\"Текстово поле\",\"textarea\":\"Текстова зона\",\"hiddenField\":\"Скрито поле\",\"button\":\"Бутон\",\"select\":\"Поле за избор\",\"imageButton\":\"Бутон за снимка\",\"notSet\":\"<не е избрано>\",\"id\":\"ID\",\"name\":\"Име\",\"langDir\":\"Посока на езика\",\"langDirLtr\":\"Ляво на дясно (ЛнД)\",\"langDirRtl\":\"Дясно на ляво (ДнЛ)\",\"langCode\":\"Код на езика\",\"longDescr\":\"Уеб адрес за дълго описание\",\"cssClass\":\"Класове за CSS\",\"advisoryTitle\":\"Препоръчително заглавие\",\"cssStyle\":\"Стил\",\"ok\":\"ОК\",\"cancel\":\"Отказ\",\"close\":\"Затвори\",\"preview\":\"Преглед\",\"resize\":\"Влачете за да оразмерите\",\"generalTab\":\"Общи\",\"advancedTab\":\"Разширено\",\"validateNumberFailed\":\"Тази стойност не е число\",\"confirmNewPage\":\"Всички незапазени промени ще бъдат изгубени. Сигурни ли сте, че желаете да заредите нова страница?\",\"confirmCancel\":\"Някои от опциите са променени. Сигурни ли сте, че желаете да затворите прозореца?\",\"options\":\"Опции\",\"target\":\"Цел\",\"targetNew\":\"Нов прозорец (_blank)\",\"targetTop\":\"Горна позиция (_top)\",\"targetSelf\":\"Текущия прозорец (_self)\",\"targetParent\":\"Основен прозорец (_parent)\",\"langDirLTR\":\"Ляво на дясно (ЛнД)\",\"langDirRTL\":\"Дясно на ляво (ДнЛ)\",\"styles\":\"Стил\",\"cssClasses\":\"Класове за CSS\",\"width\":\"Ширина\",\"height\":\"Височина\",\"align\":\"Подравняване\",\"alignLeft\":\"Ляво\",\"alignRight\":\"Дясно\",\"alignCenter\":\"Център\",\"alignTop\":\"Горе\",\"alignMiddle\":\"По средата\",\"alignBottom\":\"Долу\",\"invalidValue\":\"Невалидна стойност.\",\"invalidHeight\":\"Височината трябва да е число.\",\"invalidWidth\":\"Ширина требе да е число.\",\"invalidCssLength\":\"Стойността на полето \\\"%1\\\" трябва да бъде положително число с или без валидна CSS измервателна единица (px, %, in, cm, mm, em, ex, pt, или pc).\",\"invalidHtmlLength\":\"Стойността на полето \\\"%1\\\" трябва да бъде положително число с или без валидна HTML измервателна единица (px или %).\",\"invalidInlineStyle\":\"Стойността на стилa трябва да съдържат една или повече двойки във формат \\\"name : value\\\", разделени с двоеточие.\",\"cssLengthTooltip\":\"Въведете числена стойност в пиксели или друга валидна CSS единица (px, %, in, cm, mm, em, ex, pt, или pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, недостъпно</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"Относно CKEditor\",\"help\":\"Проверете $1 за помощ.\",\"moreInfo\":\"За лицензионна информация моля посетете сайта ни:\",\"title\":\"Относно CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Удебелен\",\"italic\":\"Наклонен\",\"strike\":\"Зачертан текст\",\"subscript\":\"Индексиран текст\",\"superscript\":\"Суперскрипт\",\"underline\":\"Подчертан\"},\"blockquote\":{\"toolbar\":\"Блок за цитат\"},\"clipboard\":{\"copy\":\"Копирай\",\"copyError\":\"Настройките за сигурност на вашия бразуър не разрешават на редактора да изпълни запаметяването. За целта използвайте клавиатурата (Ctrl/Cmd+C).\",\"cut\":\"Отрежи\",\"cutError\":\"Настройките за сигурност на Вашия браузър не позволяват на редактора автоматично да изъплни действията за отрязване. Моля ползвайте клавиатурните команди за целта (ctrl+x).\",\"paste\":\"Вмъкни\",\"pasteArea\":\"Зона за вмъкване\",\"pasteMsg\":\"Вмъкнете тук съдъжанието с клавиатуарата (<STRONG>Ctrl/Cmd+V</STRONG>) и натиснете <STRONG>OK</STRONG>.\",\"securityMsg\":\"Заради настройките за сигурност на Вашия браузър, редакторът не може да прочете данните от клипборда коректно.\",\"title\":\"Вмъкни\"},\"contextmenu\":{\"options\":\"Опции на контекстното меню\"},\"toolbar\":{\"toolbarCollapse\":\"Свиване на лентата с инструменти\",\"toolbarExpand\":\"Разширяване на лентата с инструменти\",\"toolbarGroups\":{\"document\":\"Документ\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Промяна\",\"forms\":\"Форми\",\"basicstyles\":\"Базови стилове\",\"paragraph\":\"Параграф\",\"links\":\"Връзки\",\"insert\":\"Вмъкване\",\"styles\":\"Стилове\",\"colors\":\"Цветове\",\"tools\":\"Инструменти\"},\"toolbars\":\"Ленти с инструменти\"},\"elementspath\":{\"eleLabel\":\"Път за елементите\",\"eleTitle\":\"%1 елемент\"},\"format\":{\"label\":\"Формат\",\"panelTitle\":\"Формат\",\"tag_address\":\"Адрес\",\"tag_div\":\"Параграф (DIV)\",\"tag_h1\":\"Заглавие 1\",\"tag_h2\":\"Заглавие 2\",\"tag_h3\":\"Заглавие 3\",\"tag_h4\":\"Заглавие 4\",\"tag_h5\":\"Заглавие 5\",\"tag_h6\":\"Заглавие 6\",\"tag_p\":\"Нормален\",\"tag_pre\":\"Форматиран\"},\"horizontalrule\":{\"toolbar\":\"Вмъкване на хоризонтална линия\"},\"image\":{\"alertUrl\":\"Моля, въведете пълния път до изображението\",\"alt\":\"Алтернативен текст\",\"border\":\"Рамка\",\"btnUpload\":\"Изпрати я на сървъра\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"Хоризонтален отстъп\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"Инфо за снимка\",\"linkTab\":\"Връзка\",\"lockRatio\":\"Заключване на съотношението\",\"menu\":\"Настройки за снимка\",\"resetSize\":\"Нулиране на размер\",\"title\":\"Настройки за снимка\",\"titleButton\":\"Настойки за бутон за снимка\",\"upload\":\"Качване\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"Вертикален отстъп\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"Увеличаване на отстъпа\",\"outdent\":\"Намаляване на отстъпа\"},\"fakeobjects\":{\"anchor\":\"Кука\",\"flash\":\"Флаш анимация\",\"hiddenfield\":\"Скрито поле\",\"iframe\":\"IFrame\",\"unknown\":\"Неизвестен обект\"},\"link\":{\"acccessKey\":\"Ключ за достъп\",\"advanced\":\"Разширено\",\"advisoryContentType\":\"Препоръчителен тип на съдържанието\",\"advisoryTitle\":\"Препоръчително заглавие\",\"anchor\":{\"toolbar\":\"Котва\",\"menu\":\"Промяна на котва\",\"title\":\"Настройки на котва\",\"name\":\"Име на котва\",\"errorName\":\"Моля въведете име на котвата\",\"remove\":\"Премахване на котва\"},\"anchorId\":\"По ID на елемент\",\"anchorName\":\"По име на котва\",\"charset\":\"Тип на свързания ресурс\",\"cssClasses\":\"Класове за CSS\",\"emailAddress\":\"E-mail aдрес\",\"emailBody\":\"Съдържание\",\"emailSubject\":\"Тема\",\"id\":\"ID\",\"info\":\"Инфо за връзката\",\"langCode\":\"Код за езика\",\"langDir\":\"Посока на езика\",\"langDirLTR\":\"Ляво на Дясно (ЛнД)\",\"langDirRTL\":\"Дясно на Ляво (ДнЛ)\",\"menu\":\"Промяна на връзка\",\"name\":\"Име\",\"noAnchors\":\"(Няма котви в текущия документ)\",\"noEmail\":\"Моля въведете e-mail aдрес\",\"noUrl\":\"Моля въведете URL адреса\",\"other\":\"<друго>\",\"popupDependent\":\"Зависимост (Netscape)\",\"popupFeatures\":\"Функции на изкачащ прозорец\",\"popupFullScreen\":\"Цял екран (IE)\",\"popupLeft\":\"Лява позиция\",\"popupLocationBar\":\"Лента с локацията\",\"popupMenuBar\":\"Лента за меню\",\"popupResizable\":\"Оразмеряем\",\"popupScrollBars\":\"Скролери\",\"popupStatusBar\":\"Статусна лента\",\"popupToolbar\":\"Лента с инструменти\",\"popupTop\":\"Горна позиция\",\"rel\":\"Връзка\",\"selectAnchor\":\"Изберете котва\",\"styles\":\"Стил\",\"tabIndex\":\"Ред на достъп\",\"target\":\"Цел\",\"targetFrame\":\"<frame>\",\"targetFrameName\":\"Име на целевият прозорец\",\"targetPopup\":\"<изкачащ прозорец>\",\"targetPopupName\":\"Име на изкачащ прозорец\",\"title\":\"Връзка\",\"toAnchor\":\"Връзка към котва в текста\",\"toEmail\":\"E-mail\",\"toUrl\":\"Уеб адрес\",\"toolbar\":\"Връзка\",\"type\":\"Тип на връзката\",\"unlink\":\"Премахни връзката\",\"upload\":\"Качване\"},\"list\":{\"bulletedlist\":\"Вмъкване/Премахване на точков списък\",\"numberedlist\":\"Вмъкване/Премахване на номериран списък\"},\"magicline\":{\"title\":\"Вмъкнете параграф тук\"},\"maximize\":{\"maximize\":\"Максимизиране\",\"minimize\":\"Минимизиране\"},\"pastetext\":{\"button\":\"Вмъкни като чист текст\",\"title\":\"Вмъкни като чист текст\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"Вмъкни от MS Word\",\"toolbar\":\"Вмъкни от MS Word\"},\"removeformat\":{\"toolbar\":\"Премахване на форматирането\"},\"sourcearea\":{\"toolbar\":\"Източник\"},\"specialchar\":{\"options\":\"Опции за специален знак\",\"title\":\"Избор на специален знак\",\"toolbar\":\"Вмъкване на специален знак\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"Относно\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Нов\",\"dic_delete\":\"Изтриване\",\"dic_field_name\":\"Име на речнк\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Преименуване\",\"dic_restore\":\"Възтановяване\",\"dictionariesTab\":\"Речници\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Езици\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Игнорирани думи и цифри\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Стилове\",\"panelTitle\":\"Стилове за форматиране\",\"panelTitle1\":\"Блокови стилове\",\"panelTitle2\":\"Вътрешни стилове\",\"panelTitle3\":\"Обектни стилове\"},\"table\":{\"border\":\"Размер на рамката\",\"caption\":\"Заглавие\",\"cell\":{\"menu\":\"Клетка\",\"insertBefore\":\"Вмъкване на клетка преди\",\"insertAfter\":\"Вмъкване на клетка след\",\"deleteCell\":\"Изтриване на клетки\",\"merge\":\"Сливане на клетки\",\"mergeRight\":\"Сливане в дясно\",\"mergeDown\":\"Merge Down\",\"splitHorizontal\":\"Split Cell Horizontally\",\"splitVertical\":\"Split Cell Vertically\",\"title\":\"Настройки на клетката\",\"cellType\":\"Тип на клетката\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Авто. пренос\",\"hAlign\":\"Хоризонтално подравняване\",\"vAlign\":\"Вертикално подравняване\",\"alignBaseline\":\"Базова линия\",\"bgColor\":\"Фон\",\"borderColor\":\"Цвят на рамката\",\"data\":\"Данни\",\"header\":\"Хедър\",\"yes\":\"Да\",\"no\":\"Не\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Изберете\"},\"cellPad\":\"Отделяне на клетките\",\"cellSpace\":\"Разтояние между клетките\",\"column\":{\"menu\":\"Колона\",\"insertBefore\":\"Вмъкване на колона преди\",\"insertAfter\":\"Вмъкване на колона след\",\"deleteColumn\":\"Изтриване на колони\"},\"columns\":\"Колони\",\"deleteTable\":\"Изтриване на таблица\",\"headers\":\"Хедъри\",\"headersBoth\":\"Заедно\",\"headersColumn\":\"Първа колона\",\"headersNone\":\"Няма\",\"headersRow\":\"Първи ред\",\"invalidBorder\":\"Размерът на рамката трябва да е число.\",\"invalidCellPadding\":\"Отстоянието на клетките трябва да е позитивно число.\",\"invalidCellSpacing\":\"Интервала в клетките трябва да е позитивно число.\",\"invalidCols\":\"Броят колони трябва да е по-голям от 0.\",\"invalidHeight\":\"Височината на таблицата трябва да е число.\",\"invalidRows\":\"Броят редове трябва да е по-голям от 0.\",\"invalidWidth\":\"Ширината на таблицата трябва да е число.\",\"menu\":\"Настройки на таблицата\",\"row\":{\"menu\":\"Ред\",\"insertBefore\":\"Вмъкване на ред преди\",\"insertAfter\":\"Вмъкване на ред след\",\"deleteRow\":\"Изтриване на редове\"},\"rows\":\"Редове\",\"summary\":\"Обща информация\",\"title\":\"Настройки на таблицата\",\"toolbar\":\"Таблица\",\"widthPc\":\"процент\",\"widthPx\":\"пиксела\",\"widthUnit\":\"единица за ширина\"},\"undo\":{\"redo\":\"Връщане на предишен статус\",\"undo\":\"Възтанови\"},\"wsc\":{\"btnIgnore\":\"Игнорирай\",\"btnIgnoreAll\":\"Игнорирай всичко\",\"btnReplace\":\"Препокриване\",\"btnReplaceAll\":\"Препокрий всичко\",\"btnUndo\":\"Възтанови\",\"changeTo\":\"Промени на\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Spell checker not installed. Do you want to download it now?\",\"manyChanges\":\"Spell check complete: %1 words changed\",\"noChanges\":\"Spell check complete: No words changed\",\"noMispell\":\"Spell check complete: No misspellings found\",\"noSuggestions\":\"- Няма препоръчани -\",\"notAvailable\":\"Съжаляваме, но услугата не е достъпна за момента\",\"notInDic\":\"Не е в речника\",\"oneChange\":\"Spell check complete: One word changed\",\"progress\":\"Проверява се правописа...\",\"title\":\"Проверка на правопис\",\"toolbar\":\"Проверка на правопис\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/bn.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['bn']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Press ALT 0 for help\",\"browseServer\":\"ব্রাউজ সার্ভার\",\"url\":\"URL\",\"protocol\":\"প্রোটোকল\",\"upload\":\"আপলোড\",\"uploadSubmit\":\"ইহাকে সার্ভারে প্রেরন কর\",\"image\":\"ছবির লেবেল যুক্ত কর\",\"flash\":\"ফ্লাশ লেবেল যুক্ত কর\",\"form\":\"ফর্ম\",\"checkbox\":\"চেক বাক্স\",\"radio\":\"রেডিও বাটন\",\"textField\":\"টেক্সট ফীল্ড\",\"textarea\":\"টেক্সট এরিয়া\",\"hiddenField\":\"গুপ্ত ফীল্ড\",\"button\":\"বাটন\",\"select\":\"বাছাই ফীল্ড\",\"imageButton\":\"ছবির বাটন\",\"notSet\":\"<সেট নেই>\",\"id\":\"আইডি\",\"name\":\"নাম\",\"langDir\":\"ভাষা লেখার দিক\",\"langDirLtr\":\"বাম থেকে ডান (LTR)\",\"langDirRtl\":\"ডান থেকে বাম (RTL)\",\"langCode\":\"ভাষা কোড\",\"longDescr\":\"URL এর লম্বা বর্ণনা\",\"cssClass\":\"স্টাইল-শীট ক্লাস\",\"advisoryTitle\":\"পরামর্শ শীর্ষক\",\"cssStyle\":\"স্টাইল\",\"ok\":\"ওকে\",\"cancel\":\"বাতিল\",\"close\":\"Close\",\"preview\":\"প্রিভিউ\",\"resize\":\"Resize\",\"generalTab\":\"General\",\"advancedTab\":\"এডভান্সড\",\"validateNumberFailed\":\"This value is not a number.\",\"confirmNewPage\":\"Any unsaved changes to this content will be lost. Are you sure you want to load new page?\",\"confirmCancel\":\"You have changed some options. Are you sure you want to close the dialog window?\",\"options\":\"Options\",\"target\":\"টার্গেট\",\"targetNew\":\"New Window (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Same Window (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"বাম থেকে ডান (LTR)\",\"langDirRTL\":\"ডান থেকে বাম (RTL)\",\"styles\":\"স্টাইল\",\"cssClasses\":\"স্টাইল-শীট ক্লাস\",\"width\":\"প্রস্থ\",\"height\":\"দৈর্ঘ্য\",\"align\":\"এলাইন\",\"alignLeft\":\"বামে\",\"alignRight\":\"ডানে\",\"alignCenter\":\"মাঝখানে\",\"alignTop\":\"উপর\",\"alignMiddle\":\"মধ্য\",\"alignBottom\":\"নীচে\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Height must be a number.\",\"invalidWidth\":\"Width must be a number.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"বোল্ড\",\"italic\":\"ইটালিক\",\"strike\":\"স্ট্রাইক থ্রু\",\"subscript\":\"অধোলেখ\",\"superscript\":\"অভিলেখ\",\"underline\":\"আন্ডারলাইন\"},\"blockquote\":{\"toolbar\":\"Block Quote\"},\"clipboard\":{\"copy\":\"কপি\",\"copyError\":\"আপনার ব্রাউজারের সুরক্ষা সেটিংস এডিটরকে অটোমেটিক কপি করার অনুমতি দেয়নি। দয়া করে এই কাজের জন্য কিবোর্ড ব্যবহার করুন (Ctrl/Cmd+C)।\",\"cut\":\"কাট\",\"cutError\":\"আপনার ব্রাউজারের সুরক্ষা সেটিংস এডিটরকে অটোমেটিক কাট করার অনুমতি দেয়নি। দয়া করে এই কাজের জন্য কিবোর্ড ব্যবহার করুন (Ctrl/Cmd+X)।\",\"paste\":\"পেস্ট\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"অনুগ্রহ করে নীচের বাক্সে কিবোর্ড ব্যবহার করে (<STRONG>Ctrl/Cmd+V</STRONG>) পেস্ট করুন এবং <STRONG>OK</STRONG> চাপ দিন\",\"securityMsg\":\"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.\",\"title\":\"পেস্ট\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Collapse Toolbar\",\"toolbarExpand\":\"Expand Toolbar\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editor toolbars\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"ফন্ট ফরমেট\",\"panelTitle\":\"ফন্ট ফরমেট\",\"tag_address\":\"ঠিকানা\",\"tag_div\":\"শীর্ষক (DIV)\",\"tag_h1\":\"শীর্ষক ১\",\"tag_h2\":\"শীর্ষক ২\",\"tag_h3\":\"শীর্ষক ৩\",\"tag_h4\":\"শীর্ষক ৪\",\"tag_h5\":\"শীর্ষক ৫\",\"tag_h6\":\"শীর্ষক ৬\",\"tag_p\":\"সাধারণ\",\"tag_pre\":\"ফর্মেটেড\"},\"horizontalrule\":{\"toolbar\":\"রেখা যুক্ত কর\"},\"image\":{\"alertUrl\":\"অনুগ্রহক করে ছবির URL টাইপ করুন\",\"alt\":\"বিকল্প টেক্সট\",\"border\":\"বর্ডার\",\"btnUpload\":\"ইহাকে সার্ভারে প্রেরন কর\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"হরাইজন্টাল স্পেস\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"ছবির তথ্য\",\"linkTab\":\"লিংক\",\"lockRatio\":\"অনুপাত লক কর\",\"menu\":\"ছবির প্রোপার্টি\",\"resetSize\":\"সাইজ পূর্বাবস্থায় ফিরিয়ে দাও\",\"title\":\"ছবির প্রোপার্টি\",\"titleButton\":\"ছবি বাটন প্রোপার্টি\",\"upload\":\"আপলোড\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"ভার্টিকেল স্পেস\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"ইনডেন্ট বাড়াও\",\"outdent\":\"ইনডেন্ট কমাও\"},\"fakeobjects\":{\"anchor\":\"Anchor\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Hidden Field\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"এক্সেস কী\",\"advanced\":\"এডভান্সড\",\"advisoryContentType\":\"পরামর্শ কন্টেন্টের প্রকার\",\"advisoryTitle\":\"পরামর্শ শীর্ষক\",\"anchor\":{\"toolbar\":\"নোঙ্গর\",\"menu\":\"নোঙর প্রোপার্টি\",\"title\":\"নোঙর প্রোপার্টি\",\"name\":\"নোঙরের নাম\",\"errorName\":\"নোঙরের নাম টাইপ করুন\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"নোঙরের আইডি দিয়ে\",\"anchorName\":\"নোঙরের নাম দিয়ে\",\"charset\":\"লিংক রিসোর্স ক্যারেক্টর সেট\",\"cssClasses\":\"স্টাইল-শীট ক্লাস\",\"emailAddress\":\"ইমেইল ঠিকানা\",\"emailBody\":\"মেসেজের দেহ\",\"emailSubject\":\"মেসেজের বিষয়\",\"id\":\"আইডি\",\"info\":\"লিংক তথ্য\",\"langCode\":\"ভাষা লেখার দিক\",\"langDir\":\"ভাষা লেখার দিক\",\"langDirLTR\":\"বাম থেকে ডান (LTR)\",\"langDirRTL\":\"ডান থেকে বাম (RTL)\",\"menu\":\"লিংক সম্পাদন\",\"name\":\"নাম\",\"noAnchors\":\"(No anchors available in the document)\",\"noEmail\":\"অনুগ্রহ করে ইমেইল এড্রেস টাইপ করুন\",\"noUrl\":\"অনুগ্রহ করে URL লিংক টাইপ করুন\",\"other\":\"<other>\",\"popupDependent\":\"ডিপেন্ডেন্ট (Netscape)\",\"popupFeatures\":\"পপআপ উইন্ডো ফীচার সমূহ\",\"popupFullScreen\":\"পূর্ণ পর্দা জুড়ে (IE)\",\"popupLeft\":\"বামের পজিশন\",\"popupLocationBar\":\"লোকেশন বার\",\"popupMenuBar\":\"মেন্যু বার\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"স্ক্রল বার\",\"popupStatusBar\":\"স্ট্যাটাস বার\",\"popupToolbar\":\"টুল বার\",\"popupTop\":\"ডানের পজিশন\",\"rel\":\"Relationship\",\"selectAnchor\":\"নোঙর বাছাই\",\"styles\":\"স্টাইল\",\"tabIndex\":\"ট্যাব ইন্ডেক্স\",\"target\":\"টার্গেট\",\"targetFrame\":\"<ফ্রেম>\",\"targetFrameName\":\"টার্গেট ফ্রেমের নাম\",\"targetPopup\":\"<পপআপ উইন্ডো>\",\"targetPopupName\":\"পপআপ উইন্ডোর নাম\",\"title\":\"লিংক\",\"toAnchor\":\"এই পেজে নোঙর কর\",\"toEmail\":\"ইমেইল\",\"toUrl\":\"URL\",\"toolbar\":\"লিংক যুক্ত কর\",\"type\":\"লিংক প্রকার\",\"unlink\":\"লিংক সরাও\",\"upload\":\"আপলোড\"},\"list\":{\"bulletedlist\":\"বুলেট লিস্ট লেবেল\",\"numberedlist\":\"সাংখ্যিক লিস্টের লেবেল\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maximize\",\"minimize\":\"Minimize\"},\"pastetext\":{\"button\":\"সাদা টেক্সট হিসেবে পেস্ট কর\",\"title\":\"সাদা টেক্সট হিসেবে পেস্ট কর\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"পেস্ট (শব্দ)\",\"toolbar\":\"পেস্ট (শব্দ)\"},\"removeformat\":{\"toolbar\":\"ফরমেট সরাও\"},\"sourcearea\":{\"toolbar\":\"সোর্স\"},\"specialchar\":{\"options\":\"Special Character Options\",\"title\":\"বিশেষ ক্যারেক্টার বাছাই কর\",\"toolbar\":\"বিশেষ অক্ষর যুক্ত কর\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"স্টাইল\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"বর্ডার সাইজ\",\"caption\":\"শীর্ষক\",\"cell\":{\"menu\":\"সেল\",\"insertBefore\":\"Insert Cell Before\",\"insertAfter\":\"Insert Cell After\",\"deleteCell\":\"সেল মুছে দাও\",\"merge\":\"সেল জোড়া দাও\",\"mergeRight\":\"Merge Right\",\"mergeDown\":\"Merge Down\",\"splitHorizontal\":\"Split Cell Horizontally\",\"splitVertical\":\"Split Cell Vertically\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"সেল প্যাডিং\",\"cellSpace\":\"সেল স্পেস\",\"column\":{\"menu\":\"কলাম\",\"insertBefore\":\"Insert Column Before\",\"insertAfter\":\"Insert Column After\",\"deleteColumn\":\"কলাম মুছে দাও\"},\"columns\":\"কলাম\",\"deleteTable\":\"টেবিল ডিলীট কর\",\"headers\":\"Headers\",\"headersBoth\":\"Both\",\"headersColumn\":\"First column\",\"headersNone\":\"None\",\"headersRow\":\"First Row\",\"invalidBorder\":\"Border size must be a number.\",\"invalidCellPadding\":\"Cell padding must be a positive number.\",\"invalidCellSpacing\":\"Cell spacing must be a positive number.\",\"invalidCols\":\"Number of columns must be a number greater than 0.\",\"invalidHeight\":\"Table height must be a number.\",\"invalidRows\":\"Number of rows must be a number greater than 0.\",\"invalidWidth\":\"Table width must be a number.\",\"menu\":\"টেবিল প্রোপার্টি\",\"row\":{\"menu\":\"রো\",\"insertBefore\":\"Insert Row Before\",\"insertAfter\":\"Insert Row After\",\"deleteRow\":\"রো মুছে দাও\"},\"rows\":\"রো\",\"summary\":\"সারাংশ\",\"title\":\"টেবিল প্রোপার্টি\",\"toolbar\":\"টেবিলের লেবেল যুক্ত কর\",\"widthPc\":\"শতকরা\",\"widthPx\":\"পিক্সেল\",\"widthUnit\":\"width unit\"},\"undo\":{\"redo\":\"রি-ডু\",\"undo\":\"আনডু\"},\"wsc\":{\"btnIgnore\":\"ইগনোর কর\",\"btnIgnoreAll\":\"সব ইগনোর কর\",\"btnReplace\":\"বদলে দাও\",\"btnReplaceAll\":\"সব বদলে দাও\",\"btnUndo\":\"আন্ডু\",\"changeTo\":\"এতে বদলাও\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"বানান পরীক্ষক ইনস্টল করা নেই। আপনি কি এখনই এটা ডাউনলোড করতে চান?\",\"manyChanges\":\"বানান পরীক্ষা শেষ: %1 গুলো শব্দ বদলে গ্যাছে\",\"noChanges\":\"বানান পরীক্ষা শেষ: কোন শব্দ পরিবর্তন করা হয়নি\",\"noMispell\":\"বানান পরীক্ষা শেষ: কোন ভুল বানান পাওয়া যায়নি\",\"noSuggestions\":\"- কোন সাজেশন নেই -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"শব্দকোষে নেই\",\"oneChange\":\"বানান পরীক্ষা শেষ: একটি মাত্র শব্দ পরিবর্তন করা হয়েছে\",\"progress\":\"বানান পরীক্ষা চলছে...\",\"title\":\"Spell Check\",\"toolbar\":\"বানান চেক\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/bs.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['bs']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Press ALT 0 for help\",\"browseServer\":\"Browse Server\",\"url\":\"URL\",\"protocol\":\"Protokol\",\"upload\":\"Šalji\",\"uploadSubmit\":\"Šalji na server\",\"image\":\"Slika\",\"flash\":\"Flash\",\"form\":\"Form\",\"checkbox\":\"Checkbox\",\"radio\":\"Radio Button\",\"textField\":\"Text Field\",\"textarea\":\"Textarea\",\"hiddenField\":\"Hidden Field\",\"button\":\"Button\",\"select\":\"Selection Field\",\"imageButton\":\"Image Button\",\"notSet\":\"<nije podešeno>\",\"id\":\"Id\",\"name\":\"Naziv\",\"langDir\":\"Smjer pisanja\",\"langDirLtr\":\"S lijeva na desno (LTR)\",\"langDirRtl\":\"S desna na lijevo (RTL)\",\"langCode\":\"Jezièni kôd\",\"longDescr\":\"Dugaèki opis URL-a\",\"cssClass\":\"Klase CSS stilova\",\"advisoryTitle\":\"Advisory title\",\"cssStyle\":\"Stil\",\"ok\":\"OK\",\"cancel\":\"Odustani\",\"close\":\"Close\",\"preview\":\"Prikaži\",\"resize\":\"Resize\",\"generalTab\":\"General\",\"advancedTab\":\"Naprednije\",\"validateNumberFailed\":\"This value is not a number.\",\"confirmNewPage\":\"Any unsaved changes to this content will be lost. Are you sure you want to load new page?\",\"confirmCancel\":\"You have changed some options. Are you sure you want to close the dialog window?\",\"options\":\"Options\",\"target\":\"Prozor\",\"targetNew\":\"New Window (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Same Window (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"S lijeva na desno (LTR)\",\"langDirRTL\":\"S desna na lijevo (RTL)\",\"styles\":\"Stil\",\"cssClasses\":\"Klase CSS stilova\",\"width\":\"Širina\",\"height\":\"Visina\",\"align\":\"Poravnanje\",\"alignLeft\":\"Lijevo\",\"alignRight\":\"Desno\",\"alignCenter\":\"Centar\",\"alignTop\":\"Vrh\",\"alignMiddle\":\"Sredina\",\"alignBottom\":\"Dno\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Height must be a number.\",\"invalidWidth\":\"Width must be a number.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Boldiraj\",\"italic\":\"Ukosi\",\"strike\":\"Precrtaj\",\"subscript\":\"Subscript\",\"superscript\":\"Superscript\",\"underline\":\"Podvuci\"},\"blockquote\":{\"toolbar\":\"Block Quote\"},\"clipboard\":{\"copy\":\"Kopiraj\",\"copyError\":\"Sigurnosne postavke Vašeg pretraživaèa ne dozvoljavaju operacije automatskog kopiranja. Molimo koristite kraticu na tastaturi (Ctrl/Cmd+C).\",\"cut\":\"Izreži\",\"cutError\":\"Sigurnosne postavke vašeg pretraživaèa ne dozvoljavaju operacije automatskog rezanja. Molimo koristite kraticu na tastaturi (Ctrl/Cmd+X).\",\"paste\":\"Zalijepi\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK\",\"securityMsg\":\"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.\",\"title\":\"Zalijepi\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Collapse Toolbar\",\"toolbarExpand\":\"Expand Toolbar\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editor toolbars\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Format\",\"tag_address\":\"Address\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatted\"},\"horizontalrule\":{\"toolbar\":\"Ubaci horizontalnu liniju\"},\"image\":{\"alertUrl\":\"Molimo ukucajte URL od slike.\",\"alt\":\"Tekst na slici\",\"border\":\"Okvir\",\"btnUpload\":\"Šalji na server\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"Info slike\",\"linkTab\":\"Link\",\"lockRatio\":\"Zakljuèaj odnos\",\"menu\":\"Svojstva slike\",\"resetSize\":\"Resetuj dimenzije\",\"title\":\"Svojstva slike\",\"titleButton\":\"Image Button Properties\",\"upload\":\"Šalji\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"Poveæaj uvod\",\"outdent\":\"Smanji uvod\"},\"fakeobjects\":{\"anchor\":\"Anchor\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Hidden Field\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"Pristupna tipka\",\"advanced\":\"Naprednije\",\"advisoryContentType\":\"Advisory vrsta sadržaja\",\"advisoryTitle\":\"Advisory title\",\"anchor\":{\"toolbar\":\"Anchor\",\"menu\":\"Edit Anchor\",\"title\":\"Anchor Properties\",\"name\":\"Anchor Name\",\"errorName\":\"Please type the anchor name\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"Po Id-u elementa\",\"anchorName\":\"Po nazivu sidra\",\"charset\":\"Linked Resource Charset\",\"cssClasses\":\"Klase CSS stilova\",\"emailAddress\":\"E-Mail Adresa\",\"emailBody\":\"Poruka\",\"emailSubject\":\"Subjekt poruke\",\"id\":\"Id\",\"info\":\"Link info\",\"langCode\":\"Smjer pisanja\",\"langDir\":\"Smjer pisanja\",\"langDirLTR\":\"S lijeva na desno (LTR)\",\"langDirRTL\":\"S desna na lijevo (RTL)\",\"menu\":\"Izmjeni link\",\"name\":\"Naziv\",\"noAnchors\":\"(Nema dostupnih sidra na stranici)\",\"noEmail\":\"Molimo ukucajte e-mail adresu\",\"noUrl\":\"Molimo ukucajte URL link\",\"other\":\"<other>\",\"popupDependent\":\"Ovisno (Netscape)\",\"popupFeatures\":\"Moguænosti popup prozora\",\"popupFullScreen\":\"Cijeli ekran (IE)\",\"popupLeft\":\"Lijeva pozicija\",\"popupLocationBar\":\"Traka za lokaciju\",\"popupMenuBar\":\"Izborna traka\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"Scroll traka\",\"popupStatusBar\":\"Statusna traka\",\"popupToolbar\":\"Traka sa alatima\",\"popupTop\":\"Gornja pozicija\",\"rel\":\"Relationship\",\"selectAnchor\":\"Izaberi sidro\",\"styles\":\"Stil\",\"tabIndex\":\"Tab indeks\",\"target\":\"Prozor\",\"targetFrame\":\"<frejm>\",\"targetFrameName\":\"Target Frame Name\",\"targetPopup\":\"<popup prozor>\",\"targetPopupName\":\"Naziv popup prozora\",\"title\":\"Link\",\"toAnchor\":\"Sidro na ovoj stranici\",\"toEmail\":\"E-Mail\",\"toUrl\":\"URL\",\"toolbar\":\"Ubaci/Izmjeni link\",\"type\":\"Tip linka\",\"unlink\":\"Izbriši link\",\"upload\":\"Šalji\"},\"list\":{\"bulletedlist\":\"Lista\",\"numberedlist\":\"Numerisana lista\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maximize\",\"minimize\":\"Minimize\"},\"pastetext\":{\"button\":\"Zalijepi kao obièan tekst\",\"title\":\"Zalijepi kao obièan tekst\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"Zalijepi iz Word-a\",\"toolbar\":\"Zalijepi iz Word-a\"},\"removeformat\":{\"toolbar\":\"Poništi format\"},\"sourcearea\":{\"toolbar\":\"HTML kôd\"},\"specialchar\":{\"options\":\"Special Character Options\",\"title\":\"Izaberi specijalni karakter\",\"toolbar\":\"Ubaci specijalni karater\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stil\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"Okvir\",\"caption\":\"Naslov\",\"cell\":{\"menu\":\"Cell\",\"insertBefore\":\"Insert Cell Before\",\"insertAfter\":\"Insert Cell After\",\"deleteCell\":\"Briši æelije\",\"merge\":\"Spoji æelije\",\"mergeRight\":\"Merge Right\",\"mergeDown\":\"Merge Down\",\"splitHorizontal\":\"Split Cell Horizontally\",\"splitVertical\":\"Split Cell Vertically\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"Uvod æelija\",\"cellSpace\":\"Razmak æelija\",\"column\":{\"menu\":\"Column\",\"insertBefore\":\"Insert Column Before\",\"insertAfter\":\"Insert Column After\",\"deleteColumn\":\"Briši kolone\"},\"columns\":\"Kolona\",\"deleteTable\":\"Delete Table\",\"headers\":\"Headers\",\"headersBoth\":\"Both\",\"headersColumn\":\"First column\",\"headersNone\":\"None\",\"headersRow\":\"First Row\",\"invalidBorder\":\"Border size must be a number.\",\"invalidCellPadding\":\"Cell padding must be a positive number.\",\"invalidCellSpacing\":\"Cell spacing must be a positive number.\",\"invalidCols\":\"Number of columns must be a number greater than 0.\",\"invalidHeight\":\"Table height must be a number.\",\"invalidRows\":\"Number of rows must be a number greater than 0.\",\"invalidWidth\":\"Table width must be a number.\",\"menu\":\"Svojstva tabele\",\"row\":{\"menu\":\"Row\",\"insertBefore\":\"Insert Row Before\",\"insertAfter\":\"Insert Row After\",\"deleteRow\":\"Briši redove\"},\"rows\":\"Redova\",\"summary\":\"Summary\",\"title\":\"Svojstva tabele\",\"toolbar\":\"Tabela\",\"widthPc\":\"posto\",\"widthPx\":\"piksela\",\"widthUnit\":\"width unit\"},\"undo\":{\"redo\":\"Ponovi\",\"undo\":\"Vrati\"},\"wsc\":{\"btnIgnore\":\"Ignore\",\"btnIgnoreAll\":\"Ignore All\",\"btnReplace\":\"Replace\",\"btnReplaceAll\":\"Replace All\",\"btnUndo\":\"Undo\",\"changeTo\":\"Change to\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Spell checker not installed. Do you want to download it now?\",\"manyChanges\":\"Spell check complete: %1 words changed\",\"noChanges\":\"Spell check complete: No words changed\",\"noMispell\":\"Spell check complete: No misspellings found\",\"noSuggestions\":\"- No suggestions -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Not in dictionary\",\"oneChange\":\"Spell check complete: One word changed\",\"progress\":\"Spell check in progress...\",\"title\":\"Spell Check\",\"toolbar\":\"Check Spelling\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/ca.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['ca']={\"editor\":\"Editor de text enriquit\",\"editorPanel\":\"Panell de l'editor de text enriquit\",\"common\":{\"editorHelp\":\"Premeu ALT 0 per ajuda\",\"browseServer\":\"Veure servidor\",\"url\":\"URL\",\"protocol\":\"Protocol\",\"upload\":\"Puja\",\"uploadSubmit\":\"Envia-la al servidor\",\"image\":\"Imatge\",\"flash\":\"Flash\",\"form\":\"Formulari\",\"checkbox\":\"Casella de verificació\",\"radio\":\"Botó d'opció\",\"textField\":\"Camp de text\",\"textarea\":\"Àrea de text\",\"hiddenField\":\"Camp ocult\",\"button\":\"Botó\",\"select\":\"Camp de selecció\",\"imageButton\":\"Botó d'imatge\",\"notSet\":\"<no definit>\",\"id\":\"Id\",\"name\":\"Nom\",\"langDir\":\"Direcció de l'idioma\",\"langDirLtr\":\"D'esquerra a dreta (LTR)\",\"langDirRtl\":\"De dreta a esquerra (RTL)\",\"langCode\":\"Codi d'idioma\",\"longDescr\":\"Descripció llarga de la URL\",\"cssClass\":\"Classes del full d'estil\",\"advisoryTitle\":\"Títol consultiu\",\"cssStyle\":\"Estil\",\"ok\":\"D'acord\",\"cancel\":\"Cancel·la\",\"close\":\"Tanca\",\"preview\":\"Previsualitza\",\"resize\":\"Arrossegueu per redimensionar\",\"generalTab\":\"General\",\"advancedTab\":\"Avançat\",\"validateNumberFailed\":\"Aquest valor no és un número.\",\"confirmNewPage\":\"Els canvis en aquest contingut que no es desin es perdran. Esteu segur que voleu carregar una pàgina nova?\",\"confirmCancel\":\"Algunes opcions s'han canviat. Esteu segur que voleu tancar el quadre de diàleg?\",\"options\":\"Opcions\",\"target\":\"Destí\",\"targetNew\":\"Nova finestra (_blank)\",\"targetTop\":\"Finestra superior (_top)\",\"targetSelf\":\"Mateixa finestra (_self)\",\"targetParent\":\"Finestra pare (_parent)\",\"langDirLTR\":\"D'esquerra a dreta (LTR)\",\"langDirRTL\":\"De dreta a esquerra (RTL)\",\"styles\":\"Estil\",\"cssClasses\":\"Classes del full d'estil\",\"width\":\"Amplada\",\"height\":\"Alçada\",\"align\":\"Alineació\",\"alignLeft\":\"Ajusta a l'esquerra\",\"alignRight\":\"Ajusta a la dreta\",\"alignCenter\":\"Centre\",\"alignTop\":\"Superior\",\"alignMiddle\":\"Centre\",\"alignBottom\":\"Inferior\",\"invalidValue\":\"Valor no vàlid.\",\"invalidHeight\":\"L'alçada ha de ser un número.\",\"invalidWidth\":\"L'amplada ha de ser un número.\",\"invalidCssLength\":\"El valor especificat per als \\\"%1\\\" camps ha de ser un número positiu amb o sense unitat de mesura vàlida de CSS (px, %, in, cm, mm, em, ex, pt o pc).\",\"invalidHtmlLength\":\"El valor especificat per als \\\"%1\\\" camps ha de ser un número positiu amb o sense unitat de mesura vàlida d'HTML (px o %).\",\"invalidInlineStyle\":\"El valor especificat per l'estil en línia ha de constar d'una o més tuples amb el format \\\"name: value\\\", separats per punt i coma.\",\"cssLengthTooltip\":\"Introduïu un número per un valor en píxels o un número amb una unitat vàlida de CSS (px, %, in, cm, mm, em, ex, pt o pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, no disponible</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Tots els drets reservats.\",\"dlgTitle\":\"Quant al CKEditor\",\"help\":\"Premi $1 per obtenir ajuda.\",\"moreInfo\":\"Per informació sobre llicències visiteu el nostre lloc web:\",\"title\":\"Quant al CKEditor\",\"userGuide\":\"Manual d'usuari de CKEditor\"},\"basicstyles\":{\"bold\":\"Negreta\",\"italic\":\"Cursiva\",\"strike\":\"Ratllat\",\"subscript\":\"Subíndex\",\"superscript\":\"Superíndex\",\"underline\":\"Subratllat\"},\"blockquote\":{\"toolbar\":\"Bloc de cita\"},\"clipboard\":{\"copy\":\"Copiar\",\"copyError\":\"La configuració de seguretat del vostre navegador no permet executar automàticament les operacions de copiar. Si us plau, utilitzeu el teclat (Ctrl/Cmd+C).\",\"cut\":\"Retallar\",\"cutError\":\"La configuració de seguretat del vostre navegador no permet executar automàticament les operacions de retallar. Si us plau, utilitzeu el teclat (Ctrl/Cmd+X).\",\"paste\":\"Enganxar\",\"pasteArea\":\"Àrea d'enganxat\",\"pasteMsg\":\"Si us plau, enganxi dins del següent camp utilitzant el teclat (<strong>Ctrl/Cmd+V</strong>) i premi OK.\",\"securityMsg\":\"A causa de la configuració de seguretat del vostre navegador, l'editor no pot accedir a les dades del porta-retalls directament. Enganxeu-ho un altre cop en aquesta finestra.\",\"title\":\"Enganxar\"},\"contextmenu\":{\"options\":\"Opcions del menú contextual\"},\"toolbar\":{\"toolbarCollapse\":\"Redueix la barra d'eines\",\"toolbarExpand\":\"Amplia la barra d'eines\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editor de barra d'eines\"},\"elementspath\":{\"eleLabel\":\"Ruta dels elements\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Format\",\"tag_address\":\"Adreça\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Encapçalament 1\",\"tag_h2\":\"Encapçalament 2\",\"tag_h3\":\"Encapçalament 3\",\"tag_h4\":\"Encapçalament 4\",\"tag_h5\":\"Encapçalament 5\",\"tag_h6\":\"Encapçalament 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatejat\"},\"horizontalrule\":{\"toolbar\":\"Insereix línia horitzontal\"},\"image\":{\"alertUrl\":\"Si us plau, escriviu la URL de la imatge\",\"alt\":\"Text alternatiu\",\"border\":\"Vora\",\"btnUpload\":\"Envia-la al servidor\",\"button2Img\":\"Voleu transformar el botó d'imatge seleccionat en una simple imatge?\",\"hSpace\":\"Espaiat horit.\",\"img2Button\":\"Voleu transformar la imatge seleccionada en un botó d'imatge?\",\"infoTab\":\"Informació de la imatge\",\"linkTab\":\"Enllaç\",\"lockRatio\":\"Bloqueja les proporcions\",\"menu\":\"Propietats de la imatge\",\"resetSize\":\"Restaura la mida\",\"title\":\"Propietats de la imatge\",\"titleButton\":\"Propietats del botó d'imatge\",\"upload\":\"Puja\",\"urlMissing\":\"Falta la URL de la imatge.\",\"vSpace\":\"Espaiat vert.\",\"validateBorder\":\"La vora ha de ser un nombre enter.\",\"validateHSpace\":\"HSpace ha de ser un nombre enter.\",\"validateVSpace\":\"VSpace ha de ser un nombre enter.\"},\"indent\":{\"indent\":\"Augmenta el sagnat\",\"outdent\":\"Redueix el sagnat\"},\"fakeobjects\":{\"anchor\":\"Àncora\",\"flash\":\"Animació Flash\",\"hiddenfield\":\"Camp ocult\",\"iframe\":\"IFrame\",\"unknown\":\"Objecte desconegut\"},\"link\":{\"acccessKey\":\"Clau d'accés\",\"advanced\":\"Avançat\",\"advisoryContentType\":\"Tipus de contingut consultiu\",\"advisoryTitle\":\"Títol consultiu\",\"anchor\":{\"toolbar\":\"Insereix/Edita àncora\",\"menu\":\"Propietats de l'àncora\",\"title\":\"Propietats de l'àncora\",\"name\":\"Nom de l'àncora\",\"errorName\":\"Si us plau, escriviu el nom de l'ancora\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"Per Id d'element\",\"anchorName\":\"Per nom d'àncora\",\"charset\":\"Conjunt de caràcters font enllaçat\",\"cssClasses\":\"Classes del full d'estil\",\"emailAddress\":\"Adreça de correu electrònic\",\"emailBody\":\"Cos del missatge\",\"emailSubject\":\"Assumpte del missatge\",\"id\":\"Id\",\"info\":\"Informació de l'enllaç\",\"langCode\":\"Direcció de l'idioma\",\"langDir\":\"Direcció de l'idioma\",\"langDirLTR\":\"D'esquerra a dreta (LTR)\",\"langDirRTL\":\"De dreta a esquerra (RTL)\",\"menu\":\"Edita l'enllaç\",\"name\":\"Nom\",\"noAnchors\":\"(No hi ha àncores disponibles en aquest document)\",\"noEmail\":\"Si us plau, escrigui l'adreça correu electrònic\",\"noUrl\":\"Si us plau, escrigui l'enllaç URL\",\"other\":\"<altre>\",\"popupDependent\":\"Depenent (Netscape)\",\"popupFeatures\":\"Característiques finestra popup\",\"popupFullScreen\":\"Pantalla completa (IE)\",\"popupLeft\":\"Posició esquerra\",\"popupLocationBar\":\"Barra d'adreça\",\"popupMenuBar\":\"Barra de menú\",\"popupResizable\":\"Redimensionable\",\"popupScrollBars\":\"Barres d'scroll\",\"popupStatusBar\":\"Barra d'estat\",\"popupToolbar\":\"Barra d'eines\",\"popupTop\":\"Posició dalt\",\"rel\":\"Relació\",\"selectAnchor\":\"Selecciona una àncora\",\"styles\":\"Estil\",\"tabIndex\":\"Index de Tab\",\"target\":\"Destí\",\"targetFrame\":\"<marc>\",\"targetFrameName\":\"Nom del marc de destí\",\"targetPopup\":\"<finestra emergent>\",\"targetPopupName\":\"Nom finestra popup\",\"title\":\"Enllaç\",\"toAnchor\":\"Àncora en aquesta pàgina\",\"toEmail\":\"Correu electrònic\",\"toUrl\":\"URL\",\"toolbar\":\"Insereix/Edita enllaç\",\"type\":\"Tipus d'enllaç\",\"unlink\":\"Elimina l'enllaç\",\"upload\":\"Puja\"},\"list\":{\"bulletedlist\":\"Llista de pics\",\"numberedlist\":\"Llista numerada\"},\"magicline\":{\"title\":\"Insereix el paràgraf aquí\"},\"maximize\":{\"maximize\":\"Maximitza\",\"minimize\":\"Minimitza\"},\"pastetext\":{\"button\":\"Enganxa com a text no formatat\",\"title\":\"Enganxa com a text no formatat\"},\"pastefromword\":{\"confirmCleanup\":\"El text que voleu enganxar sembla provenir de Word. Voleu netejar aquest text abans que sigui enganxat?\",\"error\":\"No ha estat possible netejar les dades enganxades degut a un error intern\",\"title\":\"Enganxa des del Word\",\"toolbar\":\"Enganxa des del Word\"},\"removeformat\":{\"toolbar\":\"Elimina Format\"},\"sourcearea\":{\"toolbar\":\"Codi font\"},\"specialchar\":{\"options\":\"Opcions de caràcters especials\",\"title\":\"Selecciona el caràcter especial\",\"toolbar\":\"Insereix caràcter especial\"},\"scayt\":{\"about\":\"Quant a l'SCAYT\",\"aboutTab\":\"Quant a\",\"addWord\":\"Afegeix una paraula\",\"allCaps\":\"Ignora paraules en majúscules\",\"dic_create\":\"Crea\",\"dic_delete\":\"Elimina\",\"dic_field_name\":\"Nom del diccionari\",\"dic_info\":\"Inicialment el diccionari d'usuari s'emmagatzema en una galeta. De totes maneres, les galetes tenen la mida limitada. Quan el diccionari creix massa, llavors el diccionari es pot emmagatzemar al nostre servidor. Per desar el vostre diccionari personal al nostre servidor heu d.'especificar un nom pel diccionari. Si ja heu desat un diccionari, teclegeu si us plau el seu nom i cliqueu el botó de restauració.\",\"dic_rename\":\"Canvia el nom\",\"dic_restore\":\"Restaura\",\"dictionariesTab\":\"Diccionaris\",\"disable\":\"Deshabilita SCAYT\",\"emptyDic\":\"El nom del diccionari no hauria d'estar buit.\",\"enable\":\"Habilitat l'SCAYT\",\"ignore\":\"Ignora\",\"ignoreAll\":\"Ignora'ls tots\",\"ignoreDomainNames\":\"Ignora els noms de domini\",\"langs\":\"Idiomes\",\"languagesTab\":\"Idiomes\",\"mixedCase\":\"Ignora paraules amb majúscules i minúscules\",\"mixedWithDigits\":\"Ignora paraules amb números \",\"moreSuggestions\":\"Més suggerències\",\"opera_title\":\"No és compatible amb l'Opera\",\"options\":\"Opcions\",\"optionsTab\":\"Opcions\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Commuta l'SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Estil\",\"panelTitle\":\"Estils de format\",\"panelTitle1\":\"Estils de bloc\",\"panelTitle2\":\"Estils incrustats\",\"panelTitle3\":\"Estils d'objecte\"},\"table\":{\"border\":\"Mida vora\",\"caption\":\"Títol\",\"cell\":{\"menu\":\"Cel·la\",\"insertBefore\":\"Insereix abans\",\"insertAfter\":\"Insereix després\",\"deleteCell\":\"Suprimeix\",\"merge\":\"Fusiona\",\"mergeRight\":\"Fusiona a la dreta\",\"mergeDown\":\"Fusiona avall\",\"splitHorizontal\":\"Divideix horitzontalment\",\"splitVertical\":\"Divideix verticalment\",\"title\":\"Propietats de la cel·la\",\"cellType\":\"Tipus de cel·la\",\"rowSpan\":\"Expansió de files\",\"colSpan\":\"Expansió de columnes\",\"wordWrap\":\"Ajustar al contingut\",\"hAlign\":\"Alineació Horizontal\",\"vAlign\":\"Alineació Vertical\",\"alignBaseline\":\"A la línia base\",\"bgColor\":\"Color de fons\",\"borderColor\":\"Color de la vora\",\"data\":\"Dades\",\"header\":\"Capçalera\",\"yes\":\"Sí\",\"no\":\"No\",\"invalidWidth\":\"L'amplada de cel·la ha de ser un nombre.\",\"invalidHeight\":\"L'alçada de cel·la ha de ser un nombre.\",\"invalidRowSpan\":\"L'expansió de files ha de ser un nombre enter.\",\"invalidColSpan\":\"L'expansió de columnes ha de ser un nombre enter.\",\"chooseColor\":\"Trieu\"},\"cellPad\":\"Encoixinament de cel·les\",\"cellSpace\":\"Espaiat de cel·les\",\"column\":{\"menu\":\"Columna\",\"insertBefore\":\"Insereix columna abans de\",\"insertAfter\":\"Insereix columna darrera\",\"deleteColumn\":\"Suprimeix una columna\"},\"columns\":\"Columnes\",\"deleteTable\":\"Suprimeix la taula\",\"headers\":\"Capçaleres\",\"headersBoth\":\"Ambdues\",\"headersColumn\":\"Primera columna\",\"headersNone\":\"Cap\",\"headersRow\":\"Primera fila\",\"invalidBorder\":\"El gruix de la vora ha de ser un nombre.\",\"invalidCellPadding\":\"L'encoixinament de cel·la  ha de ser un nombre.\",\"invalidCellSpacing\":\"L'espaiat de cel·la  ha de ser un nombre.\",\"invalidCols\":\"El nombre de columnes ha de ser un nombre major que 0.\",\"invalidHeight\":\"L'alçada de la taula  ha de ser un nombre.\",\"invalidRows\":\"El nombre de files ha de ser un nombre major que 0.\",\"invalidWidth\":\"L'amplada de la taula  ha de ser un nombre.\",\"menu\":\"Propietats de la taula\",\"row\":{\"menu\":\"Fila\",\"insertBefore\":\"Insereix fila abans de\",\"insertAfter\":\"Insereix fila darrera\",\"deleteRow\":\"Suprimeix una fila\"},\"rows\":\"Files\",\"summary\":\"Resum\",\"title\":\"Propietats de la taula\",\"toolbar\":\"Taula\",\"widthPc\":\"percentatge\",\"widthPx\":\"píxels\",\"widthUnit\":\"unitat d'amplada\"},\"undo\":{\"redo\":\"Refés\",\"undo\":\"Desfés\"},\"wsc\":{\"btnIgnore\":\"Ignora\",\"btnIgnoreAll\":\"Ignora-les totes\",\"btnReplace\":\"Canvia\",\"btnReplaceAll\":\"Canvia-les totes\",\"btnUndo\":\"Desfés\",\"changeTo\":\"Reemplaça amb\",\"errorLoading\":\"Error carregant el servidor: %s.\",\"ieSpellDownload\":\"Verificació ortogràfica no instal·lada. Voleu descarregar-ho ara?\",\"manyChanges\":\"Verificació ortogràfica: s'han canviat %1 paraules\",\"noChanges\":\"Verificació ortogràfica: no s'ha canviat cap paraula\",\"noMispell\":\"Verificació ortogràfica acabada: no hi ha cap paraula mal escrita\",\"noSuggestions\":\"Cap suggeriment\",\"notAvailable\":\"El servei no es troba disponible ara.\",\"notInDic\":\"No és al diccionari\",\"oneChange\":\"Verificació ortogràfica: s'ha canviat una paraula\",\"progress\":\"Verificació ortogràfica en curs...\",\"title\":\"Comprova l'ortografia\",\"toolbar\":\"Revisa l'ortografia\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/cs.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['cs']={\"editor\":\"Textový editor\",\"editorPanel\":\"Panel textového editoru\",\"common\":{\"editorHelp\":\"Stiskněte ALT 0 pro nápovědu\",\"browseServer\":\"Vybrat na serveru\",\"url\":\"URL\",\"protocol\":\"Protokol\",\"upload\":\"Odeslat\",\"uploadSubmit\":\"Odeslat na server\",\"image\":\"Obrázek\",\"flash\":\"Flash\",\"form\":\"Formulář\",\"checkbox\":\"Zaškrtávací políčko\",\"radio\":\"Přepínač\",\"textField\":\"Textové pole\",\"textarea\":\"Textová oblast\",\"hiddenField\":\"Skryté pole\",\"button\":\"Tlačítko\",\"select\":\"Seznam\",\"imageButton\":\"Obrázkové tlačítko\",\"notSet\":\"<nenastaveno>\",\"id\":\"Id\",\"name\":\"Jméno\",\"langDir\":\"Směr jazyka\",\"langDirLtr\":\"Zleva doprava (LTR)\",\"langDirRtl\":\"Zprava doleva (RTL)\",\"langCode\":\"Kód jazyka\",\"longDescr\":\"Dlouhý popis URL\",\"cssClass\":\"Třída stylu\",\"advisoryTitle\":\"Pomocný titulek\",\"cssStyle\":\"Styl\",\"ok\":\"OK\",\"cancel\":\"Zrušit\",\"close\":\"Zavřít\",\"preview\":\"Náhled\",\"resize\":\"Uchopit pro změnu velikosti\",\"generalTab\":\"Obecné\",\"advancedTab\":\"Rozšířené\",\"validateNumberFailed\":\"Zadaná hodnota není číselná.\",\"confirmNewPage\":\"Jakékoliv neuložené změny obsahu budou ztraceny. Skutečně chcete otevřít novou stránku?\",\"confirmCancel\":\"Některá z nastavení byla změněna. Skutečně chcete zavřít dialogové okno?\",\"options\":\"Nastavení\",\"target\":\"Cíl\",\"targetNew\":\"Nové okno (_blank)\",\"targetTop\":\"Okno nejvyšší úrovně (_top)\",\"targetSelf\":\"Stejné okno (_self)\",\"targetParent\":\"Rodičovské okno (_parent)\",\"langDirLTR\":\"Zleva doprava (LTR)\",\"langDirRTL\":\"Zprava doleva (RTL)\",\"styles\":\"Styly\",\"cssClasses\":\"Třídy stylů\",\"width\":\"Šířka\",\"height\":\"Výška\",\"align\":\"Zarovnání\",\"alignLeft\":\"Vlevo\",\"alignRight\":\"Vpravo\",\"alignCenter\":\"Na střed\",\"alignTop\":\"Nahoru\",\"alignMiddle\":\"Na střed\",\"alignBottom\":\"Dolů\",\"invalidValue\":\"Neplatná hodnota.\",\"invalidHeight\":\"Zadaná výška musí být číslo.\",\"invalidWidth\":\"Šířka musí být číslo.\",\"invalidCssLength\":\"Hodnota určená pro pole \\\"%1\\\" musí být kladné číslo bez nebo s platnou jednotkou míry CSS (px, %, in, cm, mm, em, ex, pt, nebo pc).\",\"invalidHtmlLength\":\"Hodnota určená pro pole \\\"%1\\\" musí být kladné číslo bez nebo s platnou jednotkou míry HTML (px nebo %).\",\"invalidInlineStyle\":\"Hodnota určená pro řádkový styl se musí skládat z jedné nebo více n-tic ve formátu \\\"název : hodnota\\\", oddělené středníky\",\"cssLengthTooltip\":\"Zadejte číslo jako hodnotu v pixelech nebo číslo s platnou jednotkou CSS (px, %, v cm, mm, em, ex, pt, nebo pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, nedostupné</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"O aplikaci CKEditor\",\"help\":\"Prohlédněte si $1 pro nápovědu.\",\"moreInfo\":\"Pro informace o lincenci navštivte naši webovou stránku:\",\"title\":\"O aplikaci CKEditor\",\"userGuide\":\"Uživatelská příručka CKEditor\"},\"basicstyles\":{\"bold\":\"Tučné\",\"italic\":\"Kurzíva\",\"strike\":\"Přeškrtnuté\",\"subscript\":\"Dolní index\",\"superscript\":\"Horní index\",\"underline\":\"Podtržené\"},\"blockquote\":{\"toolbar\":\"Citace\"},\"clipboard\":{\"copy\":\"Kopírovat\",\"copyError\":\"Bezpečnostní nastavení vašeho prohlížeče nedovolují editoru spustit funkci pro kopírování zvoleného textu do schránky. Prosím zkopírujte zvolený text do schránky pomocí klávesnice (Ctrl/Cmd+C).\",\"cut\":\"Vyjmout\",\"cutError\":\"Bezpečnostní nastavení vašeho prohlížeče nedovolují editoru spustit funkci pro vyjmutí zvoleného textu do schránky. Prosím vyjměte zvolený text do schránky pomocí klávesnice (Ctrl/Cmd+X).\",\"paste\":\"Vložit\",\"pasteArea\":\"Oblast vkládání\",\"pasteMsg\":\"Do následujícího pole vložte požadovaný obsah pomocí klávesnice (<STRONG>Ctrl/Cmd+V</STRONG>) a stiskněte <STRONG>OK</STRONG>.\",\"securityMsg\":\"Z důvodů nastavení bezpečnosti vašeho prohlížeče nemůže editor přistupovat přímo do schránky. Obsah schránky prosím vložte znovu do tohoto okna.\",\"title\":\"Vložit\"},\"contextmenu\":{\"options\":\"Nastavení kontextové nabídky\"},\"toolbar\":{\"toolbarCollapse\":\"Skrýt panel nástrojů\",\"toolbarExpand\":\"Zobrazit panel nástrojů\",\"toolbarGroups\":{\"document\":\"Dokument\",\"clipboard\":\"Schránka/Zpět\",\"editing\":\"Úpravy\",\"forms\":\"Formuláře\",\"basicstyles\":\"Základní styly\",\"paragraph\":\"Odstavec\",\"links\":\"Odkazy\",\"insert\":\"Vložit\",\"styles\":\"Styly\",\"colors\":\"Barvy\",\"tools\":\"Nástroje\"},\"toolbars\":\"Panely nástrojů editoru\"},\"elementspath\":{\"eleLabel\":\"Cesta objektu\",\"eleTitle\":\"%1 objekt\"},\"format\":{\"label\":\"Formát\",\"panelTitle\":\"Formát\",\"tag_address\":\"Adresa\",\"tag_div\":\"Normální (DIV)\",\"tag_h1\":\"Nadpis 1\",\"tag_h2\":\"Nadpis 2\",\"tag_h3\":\"Nadpis 3\",\"tag_h4\":\"Nadpis 4\",\"tag_h5\":\"Nadpis 5\",\"tag_h6\":\"Nadpis 6\",\"tag_p\":\"Normální\",\"tag_pre\":\"Naformátováno\"},\"horizontalrule\":{\"toolbar\":\"Vložit vodorovnou linku\"},\"image\":{\"alertUrl\":\"Zadejte prosím URL obrázku\",\"alt\":\"Alternativní text\",\"border\":\"Okraje\",\"btnUpload\":\"Odeslat na server\",\"button2Img\":\"Skutečně chcete převést zvolené obrázkové tlačítko na obyčejný obrázek?\",\"hSpace\":\"Horizontální mezera\",\"img2Button\":\"Skutečně chcete převést zvolený obrázek na obrázkové tlačítko?\",\"infoTab\":\"Informace o obrázku\",\"linkTab\":\"Odkaz\",\"lockRatio\":\"Zámek\",\"menu\":\"Vlastnosti obrázku\",\"resetSize\":\"Původní velikost\",\"title\":\"Vlastnosti obrázku\",\"titleButton\":\"Vlastností obrázkového tlačítka\",\"upload\":\"Odeslat\",\"urlMissing\":\"Zadané URL zdroje obrázku nebylo nalezeno.\",\"vSpace\":\"Vertikální mezera\",\"validateBorder\":\"Okraj musí být nastaven v celých číslech.\",\"validateHSpace\":\"Horizontální mezera musí být nastavena v celých číslech.\",\"validateVSpace\":\"Vertikální mezera musí být nastavena v celých číslech.\"},\"indent\":{\"indent\":\"Zvětšit odsazení\",\"outdent\":\"Zmenšit odsazení\"},\"fakeobjects\":{\"anchor\":\"Záložka\",\"flash\":\"Flash animace\",\"hiddenfield\":\"Skryté pole\",\"iframe\":\"IFrame\",\"unknown\":\"Neznámý objekt\"},\"link\":{\"acccessKey\":\"Přístupový klíč\",\"advanced\":\"Rozšířené\",\"advisoryContentType\":\"Pomocný typ obsahu\",\"advisoryTitle\":\"Pomocný titulek\",\"anchor\":{\"toolbar\":\"Záložka\",\"menu\":\"Vlastnosti záložky\",\"title\":\"Vlastnosti záložky\",\"name\":\"Název záložky\",\"errorName\":\"Zadejte prosím název záložky\",\"remove\":\"Odstranit záložku\"},\"anchorId\":\"Podle Id objektu\",\"anchorName\":\"Podle jména kotvy\",\"charset\":\"Přiřazená znaková sada\",\"cssClasses\":\"Třída stylu\",\"emailAddress\":\"E-mailová adresa\",\"emailBody\":\"Tělo zprávy\",\"emailSubject\":\"Předmět zprávy\",\"id\":\"Id\",\"info\":\"Informace o odkazu\",\"langCode\":\"Kód jazyka\",\"langDir\":\"Směr jazyka\",\"langDirLTR\":\"Zleva doprava (LTR)\",\"langDirRTL\":\"Zprava doleva (RTL)\",\"menu\":\"Změnit odkaz\",\"name\":\"Jméno\",\"noAnchors\":\"(Ve stránce není definována žádná kotva!)\",\"noEmail\":\"Zadejte prosím e-mailovou adresu\",\"noUrl\":\"Zadejte prosím URL odkazu\",\"other\":\"<jiný>\",\"popupDependent\":\"Závislost (Netscape)\",\"popupFeatures\":\"Vlastnosti vyskakovacího okna\",\"popupFullScreen\":\"Celá obrazovka (IE)\",\"popupLeft\":\"Levý okraj\",\"popupLocationBar\":\"Panel umístění\",\"popupMenuBar\":\"Panel nabídky\",\"popupResizable\":\"Umožňující měnit velikost\",\"popupScrollBars\":\"Posuvníky\",\"popupStatusBar\":\"Stavový řádek\",\"popupToolbar\":\"Panel nástrojů\",\"popupTop\":\"Horní okraj\",\"rel\":\"Vztah\",\"selectAnchor\":\"Vybrat kotvu\",\"styles\":\"Styl\",\"tabIndex\":\"Pořadí prvku\",\"target\":\"Cíl\",\"targetFrame\":\"<rámec>\",\"targetFrameName\":\"Název cílového rámu\",\"targetPopup\":\"<vyskakovací okno>\",\"targetPopupName\":\"Název vyskakovacího okna\",\"title\":\"Odkaz\",\"toAnchor\":\"Kotva v této stránce\",\"toEmail\":\"E-mail\",\"toUrl\":\"URL\",\"toolbar\":\"Odkaz\",\"type\":\"Typ odkazu\",\"unlink\":\"Odstranit odkaz\",\"upload\":\"Odeslat\"},\"list\":{\"bulletedlist\":\"Odrážky\",\"numberedlist\":\"Číslování\"},\"magicline\":{\"title\":\"zde vložit odstavec\"},\"maximize\":{\"maximize\":\"Maximalizovat\",\"minimize\":\"Minimalizovat\"},\"pastetext\":{\"button\":\"Vložit jako čistý text\",\"title\":\"Vložit jako čistý text\"},\"pastefromword\":{\"confirmCleanup\":\"Jak je vidět, vkládaný text je kopírován z Wordu. Chcete jej před vložením vyčistit?\",\"error\":\"Z důvodu vnitřní chyby nebylo možné provést vyčištění vkládaného textu.\",\"title\":\"Vložit z Wordu\",\"toolbar\":\"Vložit z Wordu\"},\"removeformat\":{\"toolbar\":\"Odstranit formátování\"},\"sourcearea\":{\"toolbar\":\"Zdroj\"},\"specialchar\":{\"options\":\"Nastavení speciálních znaků\",\"title\":\"Výběr speciálního znaku\",\"toolbar\":\"Vložit speciální znaky\"},\"scayt\":{\"about\":\"O aplikaci SCAYT\",\"aboutTab\":\"O aplikaci\",\"addWord\":\"Přidat slovo\",\"allCaps\":\"Ignorovat slova tvořená velkými písmeny\",\"dic_create\":\"Vytvořit\",\"dic_delete\":\"Smazat\",\"dic_field_name\":\"Název slovníku\",\"dic_info\":\"Zpočátku se uživatelský slovník ukládá do cookies ve vašem prohlížeči. Ovšem cookies mají omezenou velikost, takže když slovník dosáhne velikosti, kdy se již do cookies nevejde, může být uložen na našem serveru. Chcete-li uložit váš osobní slovník na našem serveru, je třeba slovník nejdříve pojmenovat. Máte-li již slovník pojmenován a uložen, zadejte jeho název a klepněte na tlačítko Obnovit.\",\"dic_rename\":\"Přejmenovat\",\"dic_restore\":\"Obnovit\",\"dictionariesTab\":\"Slovníky\",\"disable\":\"Vypnout SCAYT\",\"emptyDic\":\"Název slovníku nesmí být prázdný.\",\"enable\":\"Zapnout SCAYT\",\"ignore\":\"Přeskočit\",\"ignoreAll\":\"Přeskočit vše\",\"ignoreDomainNames\":\"Ignorovat doménová jména\",\"langs\":\"Jazyky\",\"languagesTab\":\"Jazyky\",\"mixedCase\":\"Ignorovat slova obsahující různou velikost písma\",\"mixedWithDigits\":\"Ignorovat slova obsahující čísla\",\"moreSuggestions\":\"Více návrhů\",\"opera_title\":\"Toto Opera nepodporuje\",\"options\":\"Nastavení\",\"optionsTab\":\"Nastavení\",\"title\":\"Kontrola pravopisu během psaní (SCAYT)\",\"toggle\":\"Vypínač SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Styl\",\"panelTitle\":\"Formátovací styly\",\"panelTitle1\":\"Blokové styly\",\"panelTitle2\":\"Řádkové styly\",\"panelTitle3\":\"Objektové styly\"},\"table\":{\"border\":\"Ohraničení\",\"caption\":\"Popis\",\"cell\":{\"menu\":\"Buňka\",\"insertBefore\":\"Vložit buňku před\",\"insertAfter\":\"Vložit buňku za\",\"deleteCell\":\"Smazat buňky\",\"merge\":\"Sloučit buňky\",\"mergeRight\":\"Sloučit doprava\",\"mergeDown\":\"Sloučit dolů\",\"splitHorizontal\":\"Rozdělit buňky vodorovně\",\"splitVertical\":\"Rozdělit buňky svisle\",\"title\":\"Vlastnosti buňky\",\"cellType\":\"Typ buňky\",\"rowSpan\":\"Spojit řádky\",\"colSpan\":\"Spojit sloupce\",\"wordWrap\":\"Zalamování\",\"hAlign\":\"Vodorovné zarovnání\",\"vAlign\":\"Svislé zarovnání\",\"alignBaseline\":\"Na účaří\",\"bgColor\":\"Barva pozadí\",\"borderColor\":\"Barva okraje\",\"data\":\"Data\",\"header\":\"Hlavička\",\"yes\":\"Ano\",\"no\":\"Ne\",\"invalidWidth\":\"Šířka buňky musí být číslo.\",\"invalidHeight\":\"Zadaná výška buňky musí být číslená.\",\"invalidRowSpan\":\"Zadaný počet sloučených řádků musí být celé číslo.\",\"invalidColSpan\":\"Zadaný počet sloučených sloupců musí být celé číslo.\",\"chooseColor\":\"Výběr\"},\"cellPad\":\"Odsazení obsahu v buňce\",\"cellSpace\":\"Vzdálenost buněk\",\"column\":{\"menu\":\"Sloupec\",\"insertBefore\":\"Vložit sloupec před\",\"insertAfter\":\"Vložit sloupec za\",\"deleteColumn\":\"Smazat sloupec\"},\"columns\":\"Sloupce\",\"deleteTable\":\"Smazat tabulku\",\"headers\":\"Záhlaví\",\"headersBoth\":\"Obojí\",\"headersColumn\":\"První sloupec\",\"headersNone\":\"Žádné\",\"headersRow\":\"První řádek\",\"invalidBorder\":\"Zdaná velikost okraje musí být číselná.\",\"invalidCellPadding\":\"Zadané odsazení obsahu v buňce musí být číselné.\",\"invalidCellSpacing\":\"Zadaná vzdálenost buněk musí být číselná.\",\"invalidCols\":\"Počet sloupců musí být číslo větší než 0.\",\"invalidHeight\":\"Zadaná výška tabulky musí být číselná.\",\"invalidRows\":\"Počet řádků musí být číslo větší než 0.\",\"invalidWidth\":\"Šířka tabulky musí být číslo.\",\"menu\":\"Vlastnosti tabulky\",\"row\":{\"menu\":\"Řádek\",\"insertBefore\":\"Vložit řádek před\",\"insertAfter\":\"Vložit řádek za\",\"deleteRow\":\"Smazat řádky\"},\"rows\":\"Řádky\",\"summary\":\"Souhrn\",\"title\":\"Vlastnosti tabulky\",\"toolbar\":\"Tabulka\",\"widthPc\":\"procent\",\"widthPx\":\"bodů\",\"widthUnit\":\"jednotka šířky\"},\"undo\":{\"redo\":\"Znovu\",\"undo\":\"Zpět\"},\"wsc\":{\"btnIgnore\":\"Přeskočit\",\"btnIgnoreAll\":\"Přeskakovat vše\",\"btnReplace\":\"Zaměnit\",\"btnReplaceAll\":\"Zaměňovat vše\",\"btnUndo\":\"Zpět\",\"changeTo\":\"Změnit na\",\"errorLoading\":\"Chyba nahrávání služby aplikace z: %s.\",\"ieSpellDownload\":\"Kontrola pravopisu není nainstalována. Chcete ji nyní stáhnout?\",\"manyChanges\":\"Kontrola pravopisu dokončena: %1 slov změněno\",\"noChanges\":\"Kontrola pravopisu dokončena: Beze změn\",\"noMispell\":\"Kontrola pravopisu dokončena: Žádné pravopisné chyby nenalezeny\",\"noSuggestions\":\"- žádné návrhy -\",\"notAvailable\":\"Omlouváme se, ale služba nyní není dostupná.\",\"notInDic\":\"Není ve slovníku\",\"oneChange\":\"Kontrola pravopisu dokončena: Jedno slovo změněno\",\"progress\":\"Probíhá kontrola pravopisu...\",\"title\":\"Kontrola pravopisu\",\"toolbar\":\"Zkontrolovat pravopis\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/cy.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['cy']={\"editor\":\"Golygydd Testun Cyfoethog\",\"editorPanel\":\"Panel Golygydd Testun Cyfoethog\",\"common\":{\"editorHelp\":\"Gwasgwch ALT 0 am gymorth\",\"browseServer\":\"Pori'r Gweinydd\",\"url\":\"URL\",\"protocol\":\"Protocol\",\"upload\":\"Lanlwytho\",\"uploadSubmit\":\"Anfon i'r Gweinydd\",\"image\":\"Delwedd\",\"flash\":\"Flash\",\"form\":\"Ffurflen\",\"checkbox\":\"Blwch ticio\",\"radio\":\"Botwm Radio\",\"textField\":\"Maes Testun\",\"textarea\":\"Ardal Testun\",\"hiddenField\":\"Maes Cudd\",\"button\":\"Botwm\",\"select\":\"Maes Dewis\",\"imageButton\":\"Botwm Delwedd\",\"notSet\":\"<heb osod>\",\"id\":\"Id\",\"name\":\"Name\",\"langDir\":\"Cyfeiriad Iaith\",\"langDirLtr\":\"Chwith i'r Dde (LTR)\",\"langDirRtl\":\"Dde i'r Chwith (RTL)\",\"langCode\":\"Cod Iaith\",\"longDescr\":\"URL Disgrifiad Hir\",\"cssClass\":\"Dosbarthiadau Dalen Arddull\",\"advisoryTitle\":\"Teitl Cynghorol\",\"cssStyle\":\"Arddull\",\"ok\":\"Iawn\",\"cancel\":\"Diddymu\",\"close\":\"Cau\",\"preview\":\"Rhagolwg\",\"resize\":\"Ailfeintio\",\"generalTab\":\"Cyffredinol\",\"advancedTab\":\"Uwch\",\"validateNumberFailed\":\"'Dyw'r gwerth hwn ddim yn rhif.\",\"confirmNewPage\":\"Byddwch chi'n colli unrhyw newidiadau i'r cynnwys sydd heb eu cadw. Ydych am barhau i lwytho tudalen newydd?\",\"confirmCancel\":\"Cafodd rhai o'r opsiynau eu newid. Ydych chi wir am gau'r deialog?\",\"options\":\"Opsiynau\",\"target\":\"Targed\",\"targetNew\":\"Ffenest Newydd (_blank)\",\"targetTop\":\"Ffenest ar y Brig (_top)\",\"targetSelf\":\"Yr un Ffenest (_self)\",\"targetParent\":\"Ffenest y Rhiant (_parent)\",\"langDirLTR\":\"Chwith i'r Dde (LTR)\",\"langDirRTL\":\"Dde i'r Chwith (RTL)\",\"styles\":\"Arddull\",\"cssClasses\":\"Dosbarthiadau Dalen Arddull\",\"width\":\"Lled\",\"height\":\"Uchder\",\"align\":\"Alinio\",\"alignLeft\":\"Chwith\",\"alignRight\":\"Dde\",\"alignCenter\":\"Canol\",\"alignTop\":\"Brig\",\"alignMiddle\":\"Canol\",\"alignBottom\":\"Gwaelod\",\"invalidValue\":\"Gwerth annilys.\",\"invalidHeight\":\"Mae'n rhaid i'r uchder fod yn rhif.\",\"invalidWidth\":\"Mae'n rhaid i'r lled fod yn rhif.\",\"invalidCssLength\":\"Mae'n rhaid i'r gwerth ar gyfer maes \\\"%1\\\" fod yn rhif positif gyda neu heb uned fesuriad CSS dilys (px, %, in, cm, mm, em, ex, pt, neu pc).\",\"invalidHtmlLength\":\"Mae'n rhaid i'r gwerth ar gyfer maes \\\"%1\\\" fod yn rhif positif gyda neu heb uned fesuriad HTML dilys (px neu %).\",\"invalidInlineStyle\":\"Mae'n rhaid i'r gwerth ar gyfer arddull mewn-llinell gynnwys un set neu fwy ar y fformat \\\"enw : gwerth\\\", wedi'u gwahanu gyda hanner colon.\",\"cssLengthTooltip\":\"Rhowch rif am werth mewn picsel neu rhif gydag uned CSS dilys (px, %, in, cm, mm, em, pt neu pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, ddim ar gael</span>\"},\"about\":{\"copy\":\"Hawlfraint &copy; $1. Cedwir pob hawl.\",\"dlgTitle\":\"Ynghylch CKEditor\",\"help\":\"Gwirio $1 am gymorth.\",\"moreInfo\":\"Am wybodaeth ynghylch trwyddedau, ewch i'n gwefan:\",\"title\":\"Ynghylch CKEditor\",\"userGuide\":\"Canllawiau Defnyddiwr CKEditor\"},\"basicstyles\":{\"bold\":\"Bras\",\"italic\":\"Italig\",\"strike\":\"Llinell Trwyddo\",\"subscript\":\"Is-sgript\",\"superscript\":\"Uwchsgript\",\"underline\":\"Tanlinellu\"},\"blockquote\":{\"toolbar\":\"Dyfyniad bloc\"},\"clipboard\":{\"copy\":\"Copïo\",\"copyError\":\"'Dyw gosodiadau diogelwch eich porwr ddim yn caniatàu'r golygydd i gynnal 'gweithredoedd copïo' yn awtomatig. Defnyddiwch y bysellfwrdd (Ctrl/Cmd+C).\",\"cut\":\"Torri\",\"cutError\":\"Nid yw gosodiadau diogelwch eich porwr yn caniatàu'r golygydd i gynnal 'gweithredoedd torri' yn awtomatig. Defnyddiwch y bysellfwrdd (Ctrl/Cmd+X).\",\"paste\":\"Gludo\",\"pasteArea\":\"Ardal Gludo\",\"pasteMsg\":\"Gludwch i mewn i'r blwch canlynol gan ddefnyddio'r bysellfwrdd (<strong>Ctrl/Cmd+V</strong>) a phwyso <strong>Iawn</strong>.\",\"securityMsg\":\"Oherwydd gosodiadau diogelwch eich porwr, 'dyw'r porwr ddim yn gallu ennill mynediad i'r data ar y clipfwrdd yn uniongyrchol. Mae angen i chi ei ludo eto i'r ffenestr hon.\",\"title\":\"Gludo\"},\"contextmenu\":{\"options\":\"Opsiynau Dewislen Cyd-destun\"},\"toolbar\":{\"toolbarCollapse\":\"Cyfangu'r Bar Offer\",\"toolbarExpand\":\"Ehangu'r Bar Offer\",\"toolbarGroups\":{\"document\":\"Dogfen\",\"clipboard\":\"Clipfwrdd/Dadwneud\",\"editing\":\"Golygu\",\"forms\":\"Ffurflenni\",\"basicstyles\":\"Arddulliau Sylfaenol\",\"paragraph\":\"Paragraff\",\"links\":\"Dolenni\",\"insert\":\"Mewnosod\",\"styles\":\"Arddulliau\",\"colors\":\"Lliwiau\",\"tools\":\"Offer\"},\"toolbars\":\"Bariau offer y golygydd\"},\"elementspath\":{\"eleLabel\":\"Llwybr elfennau\",\"eleTitle\":\"Elfen %1\"},\"format\":{\"label\":\"Fformat\",\"panelTitle\":\"Fformat Paragraff\",\"tag_address\":\"Cyfeiriad\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Pennawd 1\",\"tag_h2\":\"Pennawd 2\",\"tag_h3\":\"Pennawd 3\",\"tag_h4\":\"Pennawd 4\",\"tag_h5\":\"Pennawd 5\",\"tag_h6\":\"Pennawd 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Wedi'i Fformatio\"},\"horizontalrule\":{\"toolbar\":\"Mewnosod Llinell Lorweddol\"},\"image\":{\"alertUrl\":\"Rhowch URL y ddelwedd\",\"alt\":\"Testun Amgen\",\"border\":\"Ymyl\",\"btnUpload\":\"Anfon i'r Gweinydd\",\"button2Img\":\"Ydych am drawsffurfio'r botwm ddelwedd hwn ar ddelwedd syml?\",\"hSpace\":\"BwlchLl\",\"img2Button\":\"Ydych am drawsffurfio'r ddelwedd hon ar fotwm delwedd?\",\"infoTab\":\"Gwyb Delwedd\",\"linkTab\":\"Dolen\",\"lockRatio\":\"Cloi Cymhareb\",\"menu\":\"Priodweddau Delwedd\",\"resetSize\":\"Ailosod Maint\",\"title\":\"Priodweddau Delwedd\",\"titleButton\":\"Priodweddau Botwm Delwedd\",\"upload\":\"Lanlwytho\",\"urlMissing\":\"URL gwreiddiol y ddelwedd ar goll.\",\"vSpace\":\"BwlchF\",\"validateBorder\":\"Rhaid i'r ymyl fod yn gyfanrif.\",\"validateHSpace\":\"Rhaid i'r HSpace fod yn gyfanrif.\",\"validateVSpace\":\"Rhaid i'r VSpace fod yn gyfanrif.\"},\"indent\":{\"indent\":\"Cynyddu'r Mewnoliad\",\"outdent\":\"Lleihau'r Mewnoliad\"},\"fakeobjects\":{\"anchor\":\"Angor\",\"flash\":\"Animeiddiant Flash\",\"hiddenfield\":\"Maes Cudd\",\"iframe\":\"IFrame\",\"unknown\":\"Gwrthrych Anhysbys\"},\"link\":{\"acccessKey\":\"Allwedd Mynediad\",\"advanced\":\"Uwch\",\"advisoryContentType\":\"Math y Cynnwys Cynghorol\",\"advisoryTitle\":\"Teitl Cynghorol\",\"anchor\":{\"toolbar\":\"Angor\",\"menu\":\"Golygu'r Angor\",\"title\":\"Priodweddau'r Angor\",\"name\":\"Enw'r Angor\",\"errorName\":\"Teipiwch enw'r angor\",\"remove\":\"Tynnwch yr Angor\"},\"anchorId\":\"Gan Id yr Elfen\",\"anchorName\":\"Gan Enw'r Angor\",\"charset\":\"Set Nodau'r Adnodd Cysylltiedig\",\"cssClasses\":\"Dosbarthiadau Dalen Arddull\",\"emailAddress\":\"Cyfeiriad E-Bost\",\"emailBody\":\"Corff y Neges\",\"emailSubject\":\"Testun y Neges\",\"id\":\"Id\",\"info\":\"Gwyb y Ddolen\",\"langCode\":\"Cod Iaith\",\"langDir\":\"Cyfeiriad Iaith\",\"langDirLTR\":\"Chwith i'r Dde (LTR)\",\"langDirRTL\":\"Dde i'r Chwith (RTL)\",\"menu\":\"Golygu Dolen\",\"name\":\"Enw\",\"noAnchors\":\"(Dim angorau ar gael yn y ddogfen)\",\"noEmail\":\"Teipiwch gyfeiriad yr e-bost\",\"noUrl\":\"Teipiwch URL y ddolen\",\"other\":\"<eraill>\",\"popupDependent\":\"Dibynnol (Netscape)\",\"popupFeatures\":\"Nodweddion Ffenestr Bop\",\"popupFullScreen\":\"Sgrin Llawn (IE)\",\"popupLeft\":\"Safle Chwith\",\"popupLocationBar\":\"Bar Safle\",\"popupMenuBar\":\"Dewislen\",\"popupResizable\":\"Ailfeintiol\",\"popupScrollBars\":\"Barrau Sgrolio\",\"popupStatusBar\":\"Bar Statws\",\"popupToolbar\":\"Bar Offer\",\"popupTop\":\"Safle Top\",\"rel\":\"Perthynas\",\"selectAnchor\":\"Dewiswch Angor\",\"styles\":\"Arddull\",\"tabIndex\":\"Indecs Tab\",\"target\":\"Targed\",\"targetFrame\":\"<ffrâm>\",\"targetFrameName\":\"Enw Ffrâm y Targed\",\"targetPopup\":\"<ffenestr bop>\",\"targetPopupName\":\"Enw Ffenestr Bop\",\"title\":\"Dolen\",\"toAnchor\":\"Dolen at angor yn y testun\",\"toEmail\":\"E-bost\",\"toUrl\":\"URL\",\"toolbar\":\"Dolen\",\"type\":\"Math y Ddolen\",\"unlink\":\"Datgysylltu\",\"upload\":\"Lanlwytho\"},\"list\":{\"bulletedlist\":\"Mewnosod/Tynnu Rhestr Bwled\",\"numberedlist\":\"Mewnosod/Tynnu Rhestr Rhifol\"},\"magicline\":{\"title\":\"Mewnosod paragraff yma\"},\"maximize\":{\"maximize\":\"Mwyhau\",\"minimize\":\"Lleihau\"},\"pastetext\":{\"button\":\"Gludo fel testun plaen\",\"title\":\"Gludo fel Testun Plaen\"},\"pastefromword\":{\"confirmCleanup\":\"Mae'r testun rydych chi am ludo wedi'i gopïo o Word. Ydych chi am ei lanhau cyn ei ludo?\",\"error\":\"Doedd dim modd glanhau y data a ludwyd oherwydd gwall mewnol\",\"title\":\"Gludo o Word\",\"toolbar\":\"Gludo o Word\"},\"removeformat\":{\"toolbar\":\"Tynnu Fformat\"},\"sourcearea\":{\"toolbar\":\"HTML\"},\"specialchar\":{\"options\":\"Opsiynau Nodau Arbennig\",\"title\":\"Dewis Nod Arbennig\",\"toolbar\":\"Mewnosod Nod Arbennig\"},\"scayt\":{\"about\":\"Ynghylch SCAYT\",\"aboutTab\":\"Ynghylch\",\"addWord\":\"Ychwanegu Gair\",\"allCaps\":\"Anwybyddu Geiriau Nodau Uwch i Gyd\",\"dic_create\":\"Creu\",\"dic_delete\":\"Dileu\",\"dic_field_name\":\"Enw'r geiriadur\",\"dic_info\":\"Ar y cychwyn, caiff y Geiriadur ei storio mewn Cwci. Er, mae terfyn ar faint cwcis. Pan fydd Gweiriadur Defnyddiwr yn tyfu tu hwnt i gyfyngiadau maint Cwci, caiff y geiriadur ei storio ar ein gweinydd ni. er mwyn storio eich geiriadur poersonol chi ar ein gweinydd, bydd angen i chi osod enw ar gyfer y geiriadur. Os oes geiriadur 'da chi ar ein gweinydd yn barod, teipiwch ei enw a chliciwch y botwm Adfer.\",\"dic_rename\":\"Ailenwi\",\"dic_restore\":\"Adfer\",\"dictionariesTab\":\"Geiriaduron\",\"disable\":\"Analluogi SCAYT\",\"emptyDic\":\"Ni ddylai enw'r geiriadur fod yn wag.\",\"enable\":\"Galluogi SCAYT\",\"ignore\":\"Anwybyddu\",\"ignoreAll\":\"Anwybyddu pob\",\"ignoreDomainNames\":\"Anwybyddu Enwau Parth\",\"langs\":\"Ieithoedd\",\"languagesTab\":\"Ieithoedd\",\"mixedCase\":\"Anwybyddu Geiriau â Chymysgedd Nodau Uwch ac Is\",\"mixedWithDigits\":\"Anwybyddu Geiriau â Rhifau\",\"moreSuggestions\":\"Awgrymiadau pellach\",\"opera_title\":\"Heb ei gynnal gan Opera\",\"options\":\"Opsiynau\",\"optionsTab\":\"Opsiynau\",\"title\":\"Gwirio'r Sillafu Wrth Deipio\",\"toggle\":\"Togl SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Arddulliau\",\"panelTitle\":\"Arddulliau Fformatio\",\"panelTitle1\":\"Arddulliau Bloc\",\"panelTitle2\":\"Arddulliau Mewnol\",\"panelTitle3\":\"Arddulliau Gwrthrych\"},\"table\":{\"border\":\"Maint yr Ymyl\",\"caption\":\"Pennawd\",\"cell\":{\"menu\":\"Cell\",\"insertBefore\":\"Mewnosod Cell Cyn\",\"insertAfter\":\"Mewnosod Cell Ar Ôl\",\"deleteCell\":\"Dileu Celloedd\",\"merge\":\"Cyfuno Celloedd\",\"mergeRight\":\"Cyfuno i'r Dde\",\"mergeDown\":\"Cyfuno i Lawr\",\"splitHorizontal\":\"Hollti'r Gell yn Lorweddol\",\"splitVertical\":\"Hollti'r Gell yn Fertigol\",\"title\":\"Priodweddau'r Gell\",\"cellType\":\"Math y Gell\",\"rowSpan\":\"Rhychwant Rhesi\",\"colSpan\":\"Rhychwant Colofnau\",\"wordWrap\":\"Lapio Geiriau\",\"hAlign\":\"Aliniad Llorweddol\",\"vAlign\":\"Aliniad Fertigol\",\"alignBaseline\":\"Baslinell\",\"bgColor\":\"Lliw Cefndir\",\"borderColor\":\"Lliw Ymyl\",\"data\":\"Data\",\"header\":\"Pennyn\",\"yes\":\"Ie\",\"no\":\"Na\",\"invalidWidth\":\"Mae'n rhaid i led y gell fod yn rhif.\",\"invalidHeight\":\"Mae'n rhaid i uchder y gell fod yn rhif.\",\"invalidRowSpan\":\"Mae'n rhaid i rychwant y rhesi fod yn gyfanrif.\",\"invalidColSpan\":\"Mae'n rhaid i rychwant y colofnau fod yn gyfanrif.\",\"chooseColor\":\"Dewis\"},\"cellPad\":\"Padio'r gell\",\"cellSpace\":\"Bylchiad y gell\",\"column\":{\"menu\":\"Colofn\",\"insertBefore\":\"Mewnosod Colofn Cyn\",\"insertAfter\":\"Mewnosod Colofn Ar Ôl\",\"deleteColumn\":\"Dileu Colofnau\"},\"columns\":\"Colofnau\",\"deleteTable\":\"Dileu Tabl\",\"headers\":\"Penynnau\",\"headersBoth\":\"Y Ddau\",\"headersColumn\":\"Colofn gyntaf\",\"headersNone\":\"Dim\",\"headersRow\":\"Rhes gyntaf\",\"invalidBorder\":\"Mae'n rhaid i faint yr ymyl fod yn rhif.\",\"invalidCellPadding\":\"Mae'n rhaid i badiad y gell fod yn rhif positif.\",\"invalidCellSpacing\":\"Mae'n rhaid i fylchiad y gell fod yn rhif positif.\",\"invalidCols\":\"Mae'n rhaid cael o leiaf un golofn.\",\"invalidHeight\":\"Mae'n rhaid i uchder y tabl fod yn rhif.\",\"invalidRows\":\"Mae'n rhaid cael o leiaf un rhes.\",\"invalidWidth\":\"Mae'n rhaid i led y tabl fod yn rhif.\",\"menu\":\"Priodweddau'r Tabl\",\"row\":{\"menu\":\"Rhes\",\"insertBefore\":\"Mewnosod Rhes Cyn\",\"insertAfter\":\"Mewnosod Rhes Ar Ôl\",\"deleteRow\":\"Dileu Rhesi\"},\"rows\":\"Rhesi\",\"summary\":\"Crynodeb\",\"title\":\"Priodweddau'r Tabl\",\"toolbar\":\"Tabl\",\"widthPc\":\"y cant\",\"widthPx\":\"picsel\",\"widthUnit\":\"uned lled\"},\"undo\":{\"redo\":\"Ailwneud\",\"undo\":\"Dadwneud\"},\"wsc\":{\"btnIgnore\":\"Anwybyddu Un\",\"btnIgnoreAll\":\"Anwybyddu Pob\",\"btnReplace\":\"Amnewid Un\",\"btnReplaceAll\":\"Amnewid Pob\",\"btnUndo\":\"Dadwneud\",\"changeTo\":\"Newid i\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Gwirydd sillafu heb ei arsefydlu. A ydych am ei lawrlwytho nawr?\",\"manyChanges\":\"Gwirio sillafu wedi gorffen: Newidiwyd %1 gair\",\"noChanges\":\"Gwirio sillafu wedi gorffen: Dim newidiadau\",\"noMispell\":\"Gwirio sillafu wedi gorffen: Dim camsillaf.\",\"noSuggestions\":\"- Dim awgrymiadau -\",\"notAvailable\":\"Nid yw'r gwasanaeth hwn ar gael yn bresennol.\",\"notInDic\":\"Nid i'w gael yn y geiriadur\",\"oneChange\":\"Gwirio sillafu wedi gorffen: Newidiwyd 1 gair\",\"progress\":\"Gwirio sillafu yn ar y gweill...\",\"title\":\"Gwirio Sillafu\",\"toolbar\":\"Gwirio Sillafu\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/da.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['da']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Tryk ALT 0 for hjælp\",\"browseServer\":\"Gennemse...\",\"url\":\"URL\",\"protocol\":\"Protokol\",\"upload\":\"Upload\",\"uploadSubmit\":\"Upload\",\"image\":\"Indsæt billede\",\"flash\":\"Indsæt Flash\",\"form\":\"Indsæt formular\",\"checkbox\":\"Indsæt afkrydsningsfelt\",\"radio\":\"Indsæt alternativknap\",\"textField\":\"Indsæt tekstfelt\",\"textarea\":\"Indsæt tekstboks\",\"hiddenField\":\"Indsæt skjult felt\",\"button\":\"Indsæt knap\",\"select\":\"Indsæt liste\",\"imageButton\":\"Indsæt billedknap\",\"notSet\":\"<intet valgt>\",\"id\":\"Id\",\"name\":\"Navn\",\"langDir\":\"Tekstretning\",\"langDirLtr\":\"Fra venstre mod højre (LTR)\",\"langDirRtl\":\"Fra højre mod venstre (RTL)\",\"langCode\":\"Sprogkode\",\"longDescr\":\"Udvidet beskrivelse\",\"cssClass\":\"Typografiark (CSS)\",\"advisoryTitle\":\"Titel\",\"cssStyle\":\"Typografi (CSS)\",\"ok\":\"OK\",\"cancel\":\"Annullér\",\"close\":\"Luk\",\"preview\":\"Forhåndsvisning\",\"resize\":\"Træk for at skalere\",\"generalTab\":\"Generelt\",\"advancedTab\":\"Avanceret\",\"validateNumberFailed\":\"Værdien er ikke et tal.\",\"confirmNewPage\":\"Alt indhold, der ikke er blevet gemt, vil gå tabt. Er du sikker på, at du vil indlæse en ny side?\",\"confirmCancel\":\"Nogle af indstillingerne er blevet ændret. Er du sikker på, at du vil lukke vinduet?\",\"options\":\"Vis muligheder\",\"target\":\"Mål\",\"targetNew\":\"Nyt vindue (_blank)\",\"targetTop\":\"Øverste vindue (_top)\",\"targetSelf\":\"Samme vindue (_self)\",\"targetParent\":\"Samme vindue (_parent)\",\"langDirLTR\":\"Venstre til højre (LTR)\",\"langDirRTL\":\"Højre til venstre (RTL)\",\"styles\":\"Style\",\"cssClasses\":\"Stylesheetklasser\",\"width\":\"Bredde\",\"height\":\"Højde\",\"align\":\"Justering\",\"alignLeft\":\"Venstre\",\"alignRight\":\"Højre\",\"alignCenter\":\"Centreret\",\"alignTop\":\"Øverst\",\"alignMiddle\":\"Centreret\",\"alignBottom\":\"Nederst\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Højde skal være et tal.\",\"invalidWidth\":\"Bredde skal være et tal.\",\"invalidCssLength\":\"Værdien specificeret for \\\"%1\\\" feltet skal være et positivt nummer med eller uden en CSS måleenhed  (px, %, in, cm, mm, em, ex, pt, eller pc).\",\"invalidHtmlLength\":\"Værdien specificeret for \\\"%1\\\" feltet skal være et positivt nummer med eller uden en CSS måleenhed  (px eller %).\",\"invalidInlineStyle\":\"Værdien specificeret for inline style skal indeholde en eller flere elementer med et format som \\\"name:value\\\", separeret af semikoloner\",\"cssLengthTooltip\":\"Indsæt en numerisk værdi i pixel eller nummer med en gyldig CSS værdi (px, %, in, cm, mm, em, ex, pt, eller pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, ikke tilgængelig</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Alle rettigheder forbeholdes.\",\"dlgTitle\":\"Om CKEditor\",\"help\":\"Se $1 for at få hjælp.\",\"moreInfo\":\"For informationer omkring licens, se venligst vores hjemmeside (på engelsk):\",\"title\":\"Om CKEditor\",\"userGuide\":\"CKEditor-brugermanual\"},\"basicstyles\":{\"bold\":\"Fed\",\"italic\":\"Kursiv\",\"strike\":\"Gennemstreget\",\"subscript\":\"Sænket skrift\",\"superscript\":\"Hævet skrift\",\"underline\":\"Understreget\"},\"blockquote\":{\"toolbar\":\"Blokcitat\"},\"clipboard\":{\"copy\":\"Kopiér\",\"copyError\":\"Din browsers sikkerhedsindstillinger tillader ikke editoren at få automatisk adgang til udklipsholderen.<br><br>Brug i stedet tastaturet til at kopiere teksten (Ctrl/Cmd+C).\",\"cut\":\"Klip\",\"cutError\":\"Din browsers sikkerhedsindstillinger tillader ikke editoren at få automatisk adgang til udklipsholderen.<br><br>Brug i stedet tastaturet til at klippe teksten (Ctrl/Cmd+X).\",\"paste\":\"Indsæt\",\"pasteArea\":\"Indsæt område\",\"pasteMsg\":\"Indsæt i feltet herunder (<STRONG>Ctrl/Cmd+V</STRONG>) og klik på <STRONG>OK</STRONG>.\",\"securityMsg\":\"Din browsers sikkerhedsindstillinger tillader ikke editoren at få automatisk adgang til udklipsholderen.<br><br>Du skal indsætte udklipsholderens indhold i dette vindue igen.\",\"title\":\"Indsæt\"},\"contextmenu\":{\"options\":\"Muligheder for hjælpemenu\"},\"toolbar\":{\"toolbarCollapse\":\"Sammenklap værktøjslinje\",\"toolbarExpand\":\"Udvid værktøjslinje\",\"toolbarGroups\":{\"document\":\"Dokument\",\"clipboard\":\"Udklipsholder/Fortryd\",\"editing\":\"Redigering\",\"forms\":\"Formularer\",\"basicstyles\":\"Basis styles\",\"paragraph\":\"Paragraf\",\"links\":\"Links\",\"insert\":\"Indsæt\",\"styles\":\"Typografier\",\"colors\":\"Farver\",\"tools\":\"Værktøjer\"},\"toolbars\":\"Editors værktøjslinjer\"},\"elementspath\":{\"eleLabel\":\"Sti på element\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Formatering\",\"panelTitle\":\"Formatering\",\"tag_address\":\"Adresse\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Overskrift 1\",\"tag_h2\":\"Overskrift 2\",\"tag_h3\":\"Overskrift 3\",\"tag_h4\":\"Overskrift 4\",\"tag_h5\":\"Overskrift 5\",\"tag_h6\":\"Overskrift 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formateret\"},\"horizontalrule\":{\"toolbar\":\"Indsæt vandret streg\"},\"image\":{\"alertUrl\":\"Indtast stien til billedet\",\"alt\":\"Alternativ tekst\",\"border\":\"Ramme\",\"btnUpload\":\"Upload fil til serveren\",\"button2Img\":\"Vil du lave billedknappen om til et almindeligt billede?\",\"hSpace\":\"Vandret margen\",\"img2Button\":\"Vil du lave billedet om til en billedknap?\",\"infoTab\":\"Generelt\",\"linkTab\":\"Hyperlink\",\"lockRatio\":\"Lås størrelsesforhold\",\"menu\":\"Egenskaber for billede\",\"resetSize\":\"Nulstil størrelse\",\"title\":\"Egenskaber for billede\",\"titleButton\":\"Egenskaber for billedknap\",\"upload\":\"Upload\",\"urlMissing\":\"Kilde på billed-URL mangler\",\"vSpace\":\"Lodret margen\",\"validateBorder\":\"Kant skal være et helt nummer.\",\"validateHSpace\":\"HSpace skal være et helt nummer.\",\"validateVSpace\":\"VSpace skal være et helt nummer.\"},\"indent\":{\"indent\":\"Forøg indrykning\",\"outdent\":\"Formindsk indrykning\"},\"fakeobjects\":{\"anchor\":\"Anker\",\"flash\":\"Flashanimation\",\"hiddenfield\":\"Skjult felt\",\"iframe\":\"Iframe\",\"unknown\":\"Ukendt objekt\"},\"link\":{\"acccessKey\":\"Genvejstast\",\"advanced\":\"Avanceret\",\"advisoryContentType\":\"Indholdstype\",\"advisoryTitle\":\"Titel\",\"anchor\":{\"toolbar\":\"Indsæt/redigér bogmærke\",\"menu\":\"Egenskaber for bogmærke\",\"title\":\"Egenskaber for bogmærke\",\"name\":\"Bogmærkenavn\",\"errorName\":\"Indtast bogmærkenavn\",\"remove\":\"Fjern bogmærke\"},\"anchorId\":\"Efter element-Id\",\"anchorName\":\"Efter ankernavn\",\"charset\":\"Tegnsæt\",\"cssClasses\":\"Typografiark\",\"emailAddress\":\"E-mailadresse\",\"emailBody\":\"Besked\",\"emailSubject\":\"Emne\",\"id\":\"Id\",\"info\":\"Generelt\",\"langCode\":\"Tekstretning\",\"langDir\":\"Tekstretning\",\"langDirLTR\":\"Fra venstre mod højre (LTR)\",\"langDirRTL\":\"Fra højre mod venstre (RTL)\",\"menu\":\"Redigér hyperlink\",\"name\":\"Navn\",\"noAnchors\":\"(Ingen bogmærker i dokumentet)\",\"noEmail\":\"Indtast e-mailadresse!\",\"noUrl\":\"Indtast hyperlink-URL!\",\"other\":\"<anden>\",\"popupDependent\":\"Koblet/dependent (Netscape)\",\"popupFeatures\":\"Egenskaber for popup\",\"popupFullScreen\":\"Fuld skærm (IE)\",\"popupLeft\":\"Position fra venstre\",\"popupLocationBar\":\"Adresselinje\",\"popupMenuBar\":\"Menulinje\",\"popupResizable\":\"Justérbar\",\"popupScrollBars\":\"Scrollbar\",\"popupStatusBar\":\"Statuslinje\",\"popupToolbar\":\"Værktøjslinje\",\"popupTop\":\"Position fra toppen\",\"rel\":\"Relation\",\"selectAnchor\":\"Vælg et anker\",\"styles\":\"Typografi\",\"tabIndex\":\"Tabulatorindeks\",\"target\":\"Mål\",\"targetFrame\":\"<ramme>\",\"targetFrameName\":\"Destinationsvinduets navn\",\"targetPopup\":\"<popup vindue>\",\"targetPopupName\":\"Popupvinduets navn\",\"title\":\"Egenskaber for hyperlink\",\"toAnchor\":\"Bogmærke på denne side\",\"toEmail\":\"E-mail\",\"toUrl\":\"URL\",\"toolbar\":\"Indsæt/redigér hyperlink\",\"type\":\"Type\",\"unlink\":\"Fjern hyperlink\",\"upload\":\"Upload\"},\"list\":{\"bulletedlist\":\"Punktopstilling\",\"numberedlist\":\"Talopstilling\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maksimér\",\"minimize\":\"Minimér\"},\"pastetext\":{\"button\":\"Indsæt som ikke-formateret tekst\",\"title\":\"Indsæt som ikke-formateret tekst\"},\"pastefromword\":{\"confirmCleanup\":\"Den tekst du forsøger at indsætte ser ud til at komme fra Word. Vil du rense teksten før den indsættes?\",\"error\":\"Det var ikke muligt at fjerne formatteringen på den indsatte tekst grundet en intern fejl\",\"title\":\"Indsæt fra Word\",\"toolbar\":\"Indsæt fra Word\"},\"removeformat\":{\"toolbar\":\"Fjern formatering\"},\"sourcearea\":{\"toolbar\":\"Kilde\"},\"specialchar\":{\"options\":\"Muligheder for specialkarakterer\",\"title\":\"Vælg symbol\",\"toolbar\":\"Indsæt symbol\"},\"scayt\":{\"about\":\"Om SCAYT\",\"aboutTab\":\"Om\",\"addWord\":\"Tilføj ord\",\"allCaps\":\"Ignorer alle store bogstaver\",\"dic_create\":\"Opret\",\"dic_delete\":\"Slet\",\"dic_field_name\":\"Navn på ordbog\",\"dic_info\":\"Til start er brugerordbogen gemt i en Cookie. Dog har Cookies en begrænsning på størrelse. Når ordbogen når en bestemt størrelse kan den blive gemt på vores server. For at gemme din personlige ordbog på vores server skal du angive et navn for denne. Såfremt du allerede har gemt en ordbog, skriv navnet på denne og klik på Gendan knappen.\",\"dic_rename\":\"Omdøb\",\"dic_restore\":\"Gendan\",\"dictionariesTab\":\"Ordbøger\",\"disable\":\"Deaktivér SCAYT\",\"emptyDic\":\"Ordbogsnavn må ikke være tom.\",\"enable\":\"Aktivér SCAYT\",\"ignore\":\"Ignorér\",\"ignoreAll\":\"Ignorér alle\",\"ignoreDomainNames\":\"Ignorér domænenavne\",\"langs\":\"Sprog\",\"languagesTab\":\"Sprog\",\"mixedCase\":\"Ignorer ord med store og små bogstaver\",\"mixedWithDigits\":\"Ignorér ord med numre\",\"moreSuggestions\":\"Flere forslag\",\"opera_title\":\"Ikke supporteret af Opera\",\"options\":\"Indstillinger\",\"optionsTab\":\"Indstillinger\",\"title\":\"Stavekontrol mens du skriver\",\"toggle\":\"Skift/toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Typografi\",\"panelTitle\":\"Formattering på stylesheet\",\"panelTitle1\":\"Block typografi\",\"panelTitle2\":\"Inline typografi\",\"panelTitle3\":\"Object typografi\"},\"table\":{\"border\":\"Rammebredde\",\"caption\":\"Titel\",\"cell\":{\"menu\":\"Celle\",\"insertBefore\":\"Indsæt celle før\",\"insertAfter\":\"Indsæt celle efter\",\"deleteCell\":\"Slet celle\",\"merge\":\"Flet celler\",\"mergeRight\":\"Flet til højre\",\"mergeDown\":\"Flet nedad\",\"splitHorizontal\":\"Del celle vandret\",\"splitVertical\":\"Del celle lodret\",\"title\":\"Celleegenskaber\",\"cellType\":\"Celletype\",\"rowSpan\":\"Række span (rows span)\",\"colSpan\":\"Kolonne span (columns span)\",\"wordWrap\":\"Tekstombrydning\",\"hAlign\":\"Vandret justering\",\"vAlign\":\"Lodret justering\",\"alignBaseline\":\"Grundlinje\",\"bgColor\":\"Baggrundsfarve\",\"borderColor\":\"Rammefarve\",\"data\":\"Data\",\"header\":\"Hoved\",\"yes\":\"Ja\",\"no\":\"Nej\",\"invalidWidth\":\"Cellebredde skal være et tal.\",\"invalidHeight\":\"Cellehøjde skal være et tal.\",\"invalidRowSpan\":\"Række span skal være et heltal.\",\"invalidColSpan\":\"Kolonne span skal være et heltal.\",\"chooseColor\":\"Vælg\"},\"cellPad\":\"Cellemargen\",\"cellSpace\":\"Celleafstand\",\"column\":{\"menu\":\"Kolonne\",\"insertBefore\":\"Indsæt kolonne før\",\"insertAfter\":\"Indsæt kolonne efter\",\"deleteColumn\":\"Slet kolonne\"},\"columns\":\"Kolonner\",\"deleteTable\":\"Slet tabel\",\"headers\":\"Hoved\",\"headersBoth\":\"Begge\",\"headersColumn\":\"Første kolonne\",\"headersNone\":\"Ingen\",\"headersRow\":\"Første række\",\"invalidBorder\":\"Rammetykkelse skal være et tal.\",\"invalidCellPadding\":\"Cellemargen skal være et tal.\",\"invalidCellSpacing\":\"Celleafstand skal være et tal.\",\"invalidCols\":\"Antallet af kolonner skal være større end 0.\",\"invalidHeight\":\"Tabelhøjde skal være et tal.\",\"invalidRows\":\"Antallet af rækker skal være større end 0.\",\"invalidWidth\":\"Tabelbredde skal være et tal.\",\"menu\":\"Egenskaber for tabel\",\"row\":{\"menu\":\"Række\",\"insertBefore\":\"Indsæt række før\",\"insertAfter\":\"Indsæt række efter\",\"deleteRow\":\"Slet række\"},\"rows\":\"Rækker\",\"summary\":\"Resumé\",\"title\":\"Egenskaber for tabel\",\"toolbar\":\"Tabel\",\"widthPc\":\"procent\",\"widthPx\":\"pixels\",\"widthUnit\":\"Bredde på enhed\"},\"undo\":{\"redo\":\"Annullér fortryd\",\"undo\":\"Fortryd\"},\"wsc\":{\"btnIgnore\":\"Ignorér\",\"btnIgnoreAll\":\"Ignorér alle\",\"btnReplace\":\"Erstat\",\"btnReplaceAll\":\"Erstat alle\",\"btnUndo\":\"Tilbage\",\"changeTo\":\"Forslag\",\"errorLoading\":\"Fejl ved indlæsning af host: %s.\",\"ieSpellDownload\":\"Stavekontrol ikke installeret. Vil du installere den nu?\",\"manyChanges\":\"Stavekontrol færdig: %1 ord ændret\",\"noChanges\":\"Stavekontrol færdig: Ingen ord ændret\",\"noMispell\":\"Stavekontrol færdig: Ingen fejl fundet\",\"noSuggestions\":\"(ingen forslag)\",\"notAvailable\":\"Stavekontrol er desværre ikke tilgængelig.\",\"notInDic\":\"Ikke i ordbogen\",\"oneChange\":\"Stavekontrol færdig: Et ord ændret\",\"progress\":\"Stavekontrollen arbejder...\",\"title\":\"Stavekontrol\",\"toolbar\":\"Stavekontrol\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/de.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['de']={\"editor\":\"WYSIWYG-Editor\",\"editorPanel\":\"WYSIWYG-Editor-Leiste\",\"common\":{\"editorHelp\":\"Drücken Sie ALT 0 für Hilfe\",\"browseServer\":\"Server durchsuchen\",\"url\":\"URL\",\"protocol\":\"Protokoll\",\"upload\":\"Hochladen\",\"uploadSubmit\":\"Zum Server senden\",\"image\":\"Bild\",\"flash\":\"Flash\",\"form\":\"Formular\",\"checkbox\":\"Checkbox\",\"radio\":\"Radiobutton\",\"textField\":\"Textfeld einzeilig\",\"textarea\":\"Textfeld mehrzeilig\",\"hiddenField\":\"Verstecktes Feld\",\"button\":\"Klickbutton\",\"select\":\"Auswahlfeld\",\"imageButton\":\"Bildbutton\",\"notSet\":\"<nichts>\",\"id\":\"ID\",\"name\":\"Name\",\"langDir\":\"Schreibrichtung\",\"langDirLtr\":\"Links nach Rechts (LTR)\",\"langDirRtl\":\"Rechts nach Links (RTL)\",\"langCode\":\"Sprachenkürzel\",\"longDescr\":\"Langform URL\",\"cssClass\":\"Stylesheet Klasse\",\"advisoryTitle\":\"Titel Beschreibung\",\"cssStyle\":\"Style\",\"ok\":\"OK\",\"cancel\":\"Abbrechen\",\"close\":\"Schließen\",\"preview\":\"Vorschau\",\"resize\":\"Zum Vergrößern ziehen\",\"generalTab\":\"Allgemein\",\"advancedTab\":\"Erweitert\",\"validateNumberFailed\":\"Dieser Wert ist keine Nummer.\",\"confirmNewPage\":\"Alle nicht gespeicherten Änderungen gehen verlohren. Sind Sie sicher die neue Seite zu laden?\",\"confirmCancel\":\"Einige Optionen wurden geändert. Wollen Sie den Dialog dennoch schließen?\",\"options\":\"Optionen\",\"target\":\"Zielseite\",\"targetNew\":\"Neues Fenster (_blank)\",\"targetTop\":\"Oberstes Fenster (_top)\",\"targetSelf\":\"Gleiches Fenster (_self)\",\"targetParent\":\"Oberes Fenster (_parent)\",\"langDirLTR\":\"Links nach Rechts (LNR)\",\"langDirRTL\":\"Rechts nach Links (RNL)\",\"styles\":\"Style\",\"cssClasses\":\"Stylesheet Klasse\",\"width\":\"Breite\",\"height\":\"Höhe\",\"align\":\"Ausrichtung\",\"alignLeft\":\"Links\",\"alignRight\":\"Rechts\",\"alignCenter\":\"Zentriert\",\"alignTop\":\"Oben\",\"alignMiddle\":\"Mitte\",\"alignBottom\":\"Unten\",\"invalidValue\":\"Ungültiger Wert.\",\"invalidHeight\":\"Höhe muss eine Zahl sein.\",\"invalidWidth\":\"Breite muss eine Zahl sein.\",\"invalidCssLength\":\"Wert spezifiziert für \\\"%1\\\" Feld muss ein positiver numerischer Wert sein mit oder ohne korrekte CSS Messeinheit (px, %, in, cm, mm, em, ex, pt oder pc).\",\"invalidHtmlLength\":\"Wert spezifiziert für \\\"%1\\\" Feld muss ein positiver numerischer Wert sein mit oder ohne korrekte HTML Messeinheit (px oder %).\",\"invalidInlineStyle\":\"Wert spezifiziert für inline Stilart muss enthalten ein oder mehr Tupels mit dem Format \\\"Name : Wert\\\" getrennt mit Semikolons.\",\"cssLengthTooltip\":\"Gebe eine Zahl ein für ein Wert in pixels oder eine Zahl mit einer korrekten CSS Messeinheit (px, %, in, cm, mm, em, ex, pt oder pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, nicht verfügbar</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Alle Rechte vorbehalten.\",\"dlgTitle\":\"Über CKEditor\",\"help\":\"Prüfe $1 für Hilfe.\",\"moreInfo\":\"Für Informationen über unsere Lizenzbestimmungen besuchen sie bitte unsere Webseite:\",\"title\":\"Über CKEditor\",\"userGuide\":\"CKEditor Benutzerhandbuch\"},\"basicstyles\":{\"bold\":\"Fett\",\"italic\":\"Kursiv\",\"strike\":\"Durchgestrichen\",\"subscript\":\"Tiefgestellt\",\"superscript\":\"Hochgestellt\",\"underline\":\"Unterstrichen\"},\"blockquote\":{\"toolbar\":\"Zitatblock\"},\"clipboard\":{\"copy\":\"Kopieren\",\"copyError\":\"Die Sicherheitseinstellungen Ihres Browsers lassen es nicht zu, den Text automatisch kopieren. Bitte benutzen Sie die System-Zwischenablage über STRG-C (kopieren).\",\"cut\":\"Ausschneiden\",\"cutError\":\"Die Sicherheitseinstellungen Ihres Browsers lassen es nicht zu, den Text automatisch auszuschneiden. Bitte benutzen Sie die System-Zwischenablage über STRG-X (ausschneiden) und STRG-V (einfügen).\",\"paste\":\"Einfügen\",\"pasteArea\":\"Einfügebereich\",\"pasteMsg\":\"Bitte fügen Sie den Text in der folgenden Box über die Tastatur (mit <STRONG>Strg+V</STRONG>) ein und bestätigen Sie mit <STRONG>OK</STRONG>.\",\"securityMsg\":\"Aufgrund von Sicherheitsbeschränkungen Ihres Browsers kann der Editor nicht direkt auf die Zwischenablage zugreifen. Bitte fügen Sie den Inhalt erneut in diesem Fenster ein.\",\"title\":\"Einfügen\"},\"contextmenu\":{\"options\":\"Kontextmenü Optionen\"},\"toolbar\":{\"toolbarCollapse\":\"Symbolleiste einklappen\",\"toolbarExpand\":\"Symbolleiste ausklappen\",\"toolbarGroups\":{\"document\":\"Dokument\",\"clipboard\":\"Zwischenablage/Rückgängig\",\"editing\":\"Editieren\",\"forms\":\"Formularen\",\"basicstyles\":\"Grundstile\",\"paragraph\":\"Absatz\",\"links\":\"Links\",\"insert\":\"Einfügen\",\"styles\":\"Stile\",\"colors\":\"Farben\",\"tools\":\"Werkzeuge\"},\"toolbars\":\"Editor Symbolleisten\"},\"elementspath\":{\"eleLabel\":\"Elements Pfad\",\"eleTitle\":\"%1 Element\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Format\",\"tag_address\":\"Addresse\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Überschrift 1\",\"tag_h2\":\"Überschrift 2\",\"tag_h3\":\"Überschrift 3\",\"tag_h4\":\"Überschrift 4\",\"tag_h5\":\"Überschrift 5\",\"tag_h6\":\"Überschrift 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatiert\"},\"horizontalrule\":{\"toolbar\":\"Horizontale Linie einfügen\"},\"image\":{\"alertUrl\":\"Bitte geben Sie die Bild-URL an\",\"alt\":\"Alternativer Text\",\"border\":\"Rahmen\",\"btnUpload\":\"Zum Server senden\",\"button2Img\":\"Möchten Sie den gewählten Bild-Button in ein einfaches Bild umwandeln?\",\"hSpace\":\"Horizontal-Abstand\",\"img2Button\":\"Möchten Sie das gewählten Bild in einen Bild-Button umwandeln?\",\"infoTab\":\"Bild-Info\",\"linkTab\":\"Link\",\"lockRatio\":\"Größenverhältnis beibehalten\",\"menu\":\"Bild-Eigenschaften\",\"resetSize\":\"Größe zurücksetzen\",\"title\":\"Bild-Eigenschaften\",\"titleButton\":\"Bildbutton-Eigenschaften\",\"upload\":\"Hochladen\",\"urlMissing\":\"Imagequelle URL fehlt.\",\"vSpace\":\"Vertikal-Abstand\",\"validateBorder\":\"Rahmen muß eine ganze Zahl sein.\",\"validateHSpace\":\"Horizontal-Abstand muß eine ganze Zahl sein.\",\"validateVSpace\":\"Vertikal-Abstand muß eine ganze Zahl sein.\"},\"indent\":{\"indent\":\"Einzug erhöhen\",\"outdent\":\"Einzug verringern\"},\"fakeobjects\":{\"anchor\":\"Anker\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Verstecktes Feld\",\"iframe\":\"IFrame\",\"unknown\":\"Unbekanntes Objekt\"},\"link\":{\"acccessKey\":\"Zugriffstaste\",\"advanced\":\"Erweitert\",\"advisoryContentType\":\"Inhaltstyp\",\"advisoryTitle\":\"Titel Beschreibung\",\"anchor\":{\"toolbar\":\"Anker einfügen/editieren\",\"menu\":\"Anker-Eigenschaften\",\"title\":\"Anker-Eigenschaften\",\"name\":\"Anker Name\",\"errorName\":\"Bitte geben Sie den Namen des Ankers ein\",\"remove\":\"Anker entfernen\"},\"anchorId\":\"nach Element Id\",\"anchorName\":\"nach Anker Name\",\"charset\":\"Ziel-Zeichensatz\",\"cssClasses\":\"Stylesheet Klasse\",\"emailAddress\":\"E-Mail Adresse\",\"emailBody\":\"Nachrichtentext\",\"emailSubject\":\"Betreffzeile\",\"id\":\"Id\",\"info\":\"Link-Info\",\"langCode\":\"Sprachenkürzel\",\"langDir\":\"Schreibrichtung\",\"langDirLTR\":\"Links nach Rechts (LTR)\",\"langDirRTL\":\"Rechts nach Links (RTL)\",\"menu\":\"Link editieren\",\"name\":\"Name\",\"noAnchors\":\"(keine Anker im Dokument vorhanden)\",\"noEmail\":\"Bitte geben Sie e-Mail Adresse an\",\"noUrl\":\"Bitte geben Sie die Link-URL an\",\"other\":\"<andere>\",\"popupDependent\":\"Abhängig (Netscape)\",\"popupFeatures\":\"Pop-up Fenster-Eigenschaften\",\"popupFullScreen\":\"Vollbild (IE)\",\"popupLeft\":\"Linke Position\",\"popupLocationBar\":\"Adress-Leiste\",\"popupMenuBar\":\"Menü-Leiste\",\"popupResizable\":\"Größe änderbar\",\"popupScrollBars\":\"Rollbalken\",\"popupStatusBar\":\"Statusleiste\",\"popupToolbar\":\"Symbolleiste\",\"popupTop\":\"Obere Position\",\"rel\":\"Beziehung\",\"selectAnchor\":\"Anker auswählen\",\"styles\":\"Style\",\"tabIndex\":\"Tab-Index\",\"target\":\"Zielseite\",\"targetFrame\":\"<Frame>\",\"targetFrameName\":\"Ziel-Fenster-Name\",\"targetPopup\":\"<Pop-up Fenster>\",\"targetPopupName\":\"Pop-up Fenster-Name\",\"title\":\"Link\",\"toAnchor\":\"Anker in dieser Seite\",\"toEmail\":\"E-Mail\",\"toUrl\":\"URL\",\"toolbar\":\"Link einfügen/editieren\",\"type\":\"Link-Typ\",\"unlink\":\"Link entfernen\",\"upload\":\"Hochladen\"},\"list\":{\"bulletedlist\":\"Liste\",\"numberedlist\":\"Nummerierte Liste\"},\"magicline\":{\"title\":\"Absatz hier einfügen\"},\"maximize\":{\"maximize\":\"Maximieren\",\"minimize\":\"Minimieren\"},\"pastetext\":{\"button\":\"Als Text einfügen\",\"title\":\"Als Text einfügen\"},\"pastefromword\":{\"confirmCleanup\":\"Der Text, den Sie einfügen möchten, scheint aus MS-Word kopiert zu sein. Möchten Sie ihn zuvor bereinigen lassen?\",\"error\":\"Aufgrund eines internen Fehlers war es nicht möglich die eingefügten Daten zu bereinigen\",\"title\":\"Aus MS-Word einfügen\",\"toolbar\":\"Aus MS-Word einfügen\"},\"removeformat\":{\"toolbar\":\"Formatierungen entfernen\"},\"sourcearea\":{\"toolbar\":\"Quellcode\"},\"specialchar\":{\"options\":\"Sonderzeichen Optionen\",\"title\":\"Sonderzeichen auswählen\",\"toolbar\":\"Sonderzeichen einfügen/editieren\"},\"scayt\":{\"about\":\"Über SCAYT\",\"aboutTab\":\"Über\",\"addWord\":\"Wort hinzufügen\",\"allCaps\":\"Groß geschriebenen Wörter ignorieren\",\"dic_create\":\"Erzeugen\",\"dic_delete\":\"Löschen\",\"dic_field_name\":\"Wörterbuchname\",\"dic_info\":\"Anfangs wird das Benutzerwörterbuch in einem Cookie gespeichert. Allerdings sind Cookies in der Größe begrenzt. Wenn das Benutzerwörterbuch bis zu einem Punkt wächst, wo es nicht mehr in einem Cookie gespeichert werden kann, wird das Benutzerwörterbuch auf dem Server gespeichert. Um Ihr persönliches Wörterbuch auf dem Server zu speichern, müssen Sie einen Namen für das Wörterbuch angeben. Falls  Sie schon ein gespeicherte Wörterbuch haben, geben Sie bitte dessen Namen ein und klicken Sie auf die Schaltfläche Wiederherstellen.\",\"dic_rename\":\"Umbenennen\",\"dic_restore\":\"Wiederherstellen\",\"dictionariesTab\":\"Wörterbücher\",\"disable\":\"SCAYT ausschalten\",\"emptyDic\":\"Wörterbuchname sollte leer sein.\",\"enable\":\"SCAYT einschalten\",\"ignore\":\"Ignorieren\",\"ignoreAll\":\"Alle ignorieren\",\"ignoreDomainNames\":\"Domain-Namen ignorieren\",\"langs\":\"Sprachen\",\"languagesTab\":\"Sprachen\",\"mixedCase\":\"Wörter mit gemischte Setzkasten ignorieren\",\"mixedWithDigits\":\"Wörter mit Zahlen ignorieren\",\"moreSuggestions\":\"Mehr Vorschläge\",\"opera_title\":\"Nicht von Opera unterstützt\",\"options\":\"Optionen\",\"optionsTab\":\"Optionen\",\"title\":\"Rechtschreibprüfung während der Texteingabe (SCAYT)\",\"toggle\":\"SCAYT umschalten\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stil\",\"panelTitle\":\"Formatierungenstil\",\"panelTitle1\":\"Block Stilart\",\"panelTitle2\":\"Inline Stilart\",\"panelTitle3\":\"Objekt Stilart\"},\"table\":{\"border\":\"Rahmen\",\"caption\":\"Überschrift\",\"cell\":{\"menu\":\"Zelle\",\"insertBefore\":\"Zelle davor einfügen\",\"insertAfter\":\"Zelle danach einfügen\",\"deleteCell\":\"Zelle löschen\",\"merge\":\"Zellen verbinden\",\"mergeRight\":\"Nach rechts verbinden\",\"mergeDown\":\"Nach unten verbinden\",\"splitHorizontal\":\"Zelle horizontal teilen\",\"splitVertical\":\"Zelle vertikal teilen\",\"title\":\"Zellen-Eigenschaften\",\"cellType\":\"Zellart\",\"rowSpan\":\"Anzahl Zeilen verbinden\",\"colSpan\":\"Anzahl Spalten verbinden\",\"wordWrap\":\"Zeilenumbruch\",\"hAlign\":\"Horizontale Ausrichtung\",\"vAlign\":\"Vertikale Ausrichtung\",\"alignBaseline\":\"Grundlinie\",\"bgColor\":\"Hintergrundfarbe\",\"borderColor\":\"Rahmenfarbe\",\"data\":\"Daten\",\"header\":\"Überschrift\",\"yes\":\"Ja\",\"no\":\"Nein\",\"invalidWidth\":\"Zellenbreite muß eine Zahl sein.\",\"invalidHeight\":\"Zellenhöhe muß eine Zahl sein.\",\"invalidRowSpan\":\"\\\"Anzahl Zeilen verbinden\\\" muss eine Ganzzahl sein.\",\"invalidColSpan\":\"\\\"Anzahl Spalten verbinden\\\" muss eine Ganzzahl sein.\",\"chooseColor\":\"Wählen\"},\"cellPad\":\"Zellenabstand innen\",\"cellSpace\":\"Zellenabstand außen\",\"column\":{\"menu\":\"Spalte\",\"insertBefore\":\"Spalte links davor einfügen\",\"insertAfter\":\"Spalte rechts danach einfügen\",\"deleteColumn\":\"Spalte löschen\"},\"columns\":\"Spalte\",\"deleteTable\":\"Tabelle löschen\",\"headers\":\"Kopfzeile\",\"headersBoth\":\"Beide\",\"headersColumn\":\"Erste Spalte\",\"headersNone\":\"Keine\",\"headersRow\":\"Erste Zeile\",\"invalidBorder\":\"Die Rahmenbreite muß eine Zahl sein.\",\"invalidCellPadding\":\"Der Zellenabstand innen muß eine positive Zahl sein.\",\"invalidCellSpacing\":\"Der Zellenabstand außen muß eine positive Zahl sein.\",\"invalidCols\":\"Die Anzahl der Spalten muß größer als 0 sein..\",\"invalidHeight\":\"Die Tabellenbreite muß eine Zahl sein.\",\"invalidRows\":\"Die Anzahl der Zeilen muß größer als 0 sein.\",\"invalidWidth\":\"Die Tabellenbreite muss eine Zahl sein.\",\"menu\":\"Tabellen-Eigenschaften\",\"row\":{\"menu\":\"Zeile\",\"insertBefore\":\"Zeile oberhalb einfügen\",\"insertAfter\":\"Zeile unterhalb einfügen\",\"deleteRow\":\"Zeile entfernen\"},\"rows\":\"Zeile\",\"summary\":\"Inhaltsübersicht\",\"title\":\"Tabellen-Eigenschaften\",\"toolbar\":\"Tabelle\",\"widthPc\":\"%\",\"widthPx\":\"Pixel\",\"widthUnit\":\"Breite Einheit\"},\"undo\":{\"redo\":\"Wiederherstellen\",\"undo\":\"Rückgängig\"},\"wsc\":{\"btnIgnore\":\"Ignorieren\",\"btnIgnoreAll\":\"Alle Ignorieren\",\"btnReplace\":\"Ersetzen\",\"btnReplaceAll\":\"Alle Ersetzen\",\"btnUndo\":\"Rückgängig\",\"changeTo\":\"Ändern in\",\"errorLoading\":\"Fehler beim laden des Dienstanbieters: %s.\",\"ieSpellDownload\":\"Rechtschreibprüfung nicht installiert. Möchten Sie sie jetzt herunterladen?\",\"manyChanges\":\"Rechtschreibprüfung abgeschlossen - %1 Wörter geändert\",\"noChanges\":\"Rechtschreibprüfung abgeschlossen - keine Worte geändert\",\"noMispell\":\"Rechtschreibprüfung abgeschlossen - keine Fehler gefunden\",\"noSuggestions\":\" - keine Vorschläge - \",\"notAvailable\":\"Entschuldigung, aber dieser Dienst steht im Moment nicht zur Verfügung.\",\"notInDic\":\"Nicht im Wörterbuch\",\"oneChange\":\"Rechtschreibprüfung abgeschlossen - ein Wort geändert\",\"progress\":\"Rechtschreibprüfung läuft...\",\"title\":\"Rechtschreibprüfung\",\"toolbar\":\"Rechtschreibprüfung\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/el.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['el']={\"editor\":\"Επεξεργαστής Πλούσιου Κειμένου\",\"editorPanel\":\"Πίνακας Επεξεργαστή Πλούσιου Κειμένου\",\"common\":{\"editorHelp\":\"Πατήστε το ALT 0 για βοήθεια\",\"browseServer\":\"Εξερεύνηση Διακομιστή\",\"url\":\"URL\",\"protocol\":\"Πρωτόκολλο\",\"upload\":\"Αποστολή\",\"uploadSubmit\":\"Αποστολή στον Διακομιστή\",\"image\":\"Εικόνα\",\"flash\":\"Flash\",\"form\":\"Φόρμα\",\"checkbox\":\"Κουτί Επιλογής\",\"radio\":\"Κουμπί Επιλογής\",\"textField\":\"Πεδίο Κειμένου\",\"textarea\":\"Περιοχή Κειμένου\",\"hiddenField\":\"Κρυφό Πεδίο\",\"button\":\"Κουμπί\",\"select\":\"Πεδίο Επιλογής\",\"imageButton\":\"Κουμπί Εικόνας\",\"notSet\":\"<δεν έχει ρυθμιστεί>\",\"id\":\"Id\",\"name\":\"Όνομα\",\"langDir\":\"Κατεύθυνση Κειμένου\",\"langDirLtr\":\"Αριστερά προς Δεξιά (LTR)\",\"langDirRtl\":\"Δεξιά προς Αριστερά (RTL)\",\"langCode\":\"Κωδικός Γλώσσας\",\"longDescr\":\"Αναλυτική Περιγραφή URL\",\"cssClass\":\"Κλάσεις Φύλλων Στυλ\",\"advisoryTitle\":\"Ενδεικτικός Τίτλος\",\"cssStyle\":\"Μορφή Κειμένου\",\"ok\":\"OK\",\"cancel\":\"Ακύρωση\",\"close\":\"Κλείσιμο\",\"preview\":\"Προεπισκόπηση\",\"resize\":\"Αλλαγή Μεγέθους\",\"generalTab\":\"Γενικά\",\"advancedTab\":\"Για Προχωρημένους\",\"validateNumberFailed\":\"Αυτή η τιμή δεν είναι αριθμός.\",\"confirmNewPage\":\"Οι όποιες αλλαγές στο περιεχόμενο θα χαθούν. Είσαστε σίγουροι ότι θέλετε να φορτώσετε μια νέα σελίδα;\",\"confirmCancel\":\"Μερικές επιλογές έχουν αλλάξει. Είσαστε σίγουροι ότι θέλετε να κλείσετε το παράθυρο διαλόγου;\",\"options\":\"Επιλογές\",\"target\":\"Προορισμός\",\"targetNew\":\"Νέο Παράθυρο (_blank)\",\"targetTop\":\"Αρχική Περιοχή (_top)\",\"targetSelf\":\"Ίδιο Παράθυρο (_self)\",\"targetParent\":\"Γονεϊκό Παράθυρο (_parent)\",\"langDirLTR\":\"Αριστερά προς Δεξιά (LTR)\",\"langDirRTL\":\"Δεξιά προς Αριστερά (RTL)\",\"styles\":\"Μορφή\",\"cssClasses\":\"Κλάσεις Φύλλων Στυλ\",\"width\":\"Πλάτος\",\"height\":\"Ύψος\",\"align\":\"Στοίχιση\",\"alignLeft\":\"Αριστερά\",\"alignRight\":\"Δεξιά\",\"alignCenter\":\"Κέντρο\",\"alignTop\":\"Πάνω\",\"alignMiddle\":\"Μέση\",\"alignBottom\":\"Κάτω\",\"invalidValue\":\"Μη έγκυρη τιμή.\",\"invalidHeight\":\"Το ύψος πρέπει να είναι ένας αριθμός.\",\"invalidWidth\":\"Το πλάτος πρέπει να είναι ένας αριθμός.\",\"invalidCssLength\":\"Η τιμή που ορίζεται για το πεδίο \\\"%1\\\" πρέπει να είναι ένας θετικός αριθμός με ή χωρίς μια έγκυρη μονάδα μέτρησης CSS (px, %, in, cm, mm, em, ex, pt, ή pc).\",\"invalidHtmlLength\":\"Η τιμή που ορίζεται για το πεδίο \\\"%1\\\" πρέπει να είναι ένας θετικός αριθμός με ή χωρίς μια έγκυρη μονάδα μέτρησης HTML (px ή %).\",\"invalidInlineStyle\":\"Η τιμή για το εν σειρά στυλ πρέπει να περιέχει ένα ή περισσότερα ζεύγη με την μορφή \\\"όνομα: τιμή\\\" διαχωρισμένα με Ελληνικό ερωτηματικό.\",\"cssLengthTooltip\":\"Εισάγεται μια τιμή σε pixel ή έναν αριθμό μαζί με μια έγκυρη μονάδα μέτρησης CSS (px, %, in, cm, mm, em, ex, pt, ή pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, δεν είναι διαθέσιμο</span>\"},\"about\":{\"copy\":\"Πνευματικά δικαιώματα &copy; $1 Με επιφύλαξη παντός δικαιώματος.\",\"dlgTitle\":\"Περί του CKEditor\",\"help\":\"Ελέγξτε το $1 για βοήθεια.\",\"moreInfo\":\"Για πληροφορίες αδειών παρακαλούμε επισκεφθείτε την ιστοσελίδα μας:\",\"title\":\"Περί του CKEditor\",\"userGuide\":\"Οδηγίες Χρήστη CKEditor\"},\"basicstyles\":{\"bold\":\"Έντονη\",\"italic\":\"Πλάγια\",\"strike\":\"Διακριτή Διαγραφή\",\"subscript\":\"Δείκτης\",\"superscript\":\"Εκθέτης\",\"underline\":\"Υπογράμμιση\"},\"blockquote\":{\"toolbar\":\"Περιοχή Παράθεσης\"},\"clipboard\":{\"copy\":\"Αντιγραφή\",\"copyError\":\"Οι ρυθμίσεις ασφαλείας του περιηγητή σας δεν επιτρέπουν την επιλεγμένη εργασία αντιγραφής. Παρακαλώ χρησιμοποιείστε το πληκτρολόγιο (Ctrl/Cmd+C).\",\"cut\":\"Αποκοπή\",\"cutError\":\"Οι ρυθμίσεις ασφαλείας του περιηγητή σας δεν επιτρέπουν την επιλεγμένη εργασία αποκοπής. Παρακαλώ χρησιμοποιείστε το πληκτρολόγιο (Ctrl/Cmd+X).\",\"paste\":\"Επικόλληση\",\"pasteArea\":\"Περιοχή Επικόλλησης\",\"pasteMsg\":\"Παρακαλώ επικολλήστε στο ακόλουθο κουτί χρησιμοποιώντας το πληκτρολόγιο (<strong>Ctrl/Cmd+V</strong>) και πατήστε OK.\",\"securityMsg\":\"Λόγων των ρυθμίσεων ασφάλειας του περιηγητή σας, ο επεξεργαστής δεν μπορεί να έχει πρόσβαση στην μνήμη επικόλλησης. Χρειάζεται να επικολλήσετε ξανά σε αυτό το παράθυρο.\",\"title\":\"Επικόλληση\"},\"contextmenu\":{\"options\":\"Επιλογές Αναδυόμενου Μενού\"},\"toolbar\":{\"toolbarCollapse\":\"Σύμπτυξη Εργαλειοθήκης\",\"toolbarExpand\":\"Ανάπτυξη Εργαλειοθήκης\",\"toolbarGroups\":{\"document\":\"Έγγραφο\",\"clipboard\":\"Πρόχειρο/Αναίρεση\",\"editing\":\"Επεξεργασία\",\"forms\":\"Φόρμες\",\"basicstyles\":\"Βασικά Στυλ\",\"paragraph\":\"Παράγραφος\",\"links\":\"Σύνδεσμοι\",\"insert\":\"Εισαγωγή\",\"styles\":\"Στυλ\",\"colors\":\"Χρώματα\",\"tools\":\"Εργαλεία\"},\"toolbars\":\"Εργαλειοθήκες επεξεργαστή\"},\"elementspath\":{\"eleLabel\":\"Διαδρομή Στοιχείων\",\"eleTitle\":\"Στοιχείο %1\"},\"format\":{\"label\":\"Μορφοποίηση\",\"panelTitle\":\"Μορφοποίηση Παραγράφου\",\"tag_address\":\"Διεύθυνση\",\"tag_div\":\"Κανονική (DIV)\",\"tag_h1\":\"Κεφαλίδα 1\",\"tag_h2\":\"Κεφαλίδα 2\",\"tag_h3\":\"Κεφαλίδα 3\",\"tag_h4\":\"Κεφαλίδα 4\",\"tag_h5\":\"Κεφαλίδα 5\",\"tag_h6\":\"Κεφαλίδα 6\",\"tag_p\":\"Κανονική\",\"tag_pre\":\"Προ-μορφοποιημένη\"},\"horizontalrule\":{\"toolbar\":\"Εισαγωγή Οριζόντιας Γραμμής\"},\"image\":{\"alertUrl\":\"Εισάγετε την τοποθεσία (URL) της εικόνας\",\"alt\":\"Εναλλακτικό Κείμενο\",\"border\":\"Περίγραμμα\",\"btnUpload\":\"Αποστολή στον Διακομιστή\",\"button2Img\":\"Θέλετε να μετατρέψετε το επιλεγμένο κουμπί εικόνας σε απλή εικόνα;\",\"hSpace\":\"HSpace\",\"img2Button\":\"Θέλετε να μεταμορφώσετε την επιλεγμένη εικόνα που είναι πάνω σε ένα κουμπί;\",\"infoTab\":\"Πληροφορίες Εικόνας\",\"linkTab\":\"Σύνδεσμος\",\"lockRatio\":\"Κλείδωμα Αναλογίας\",\"menu\":\"Ιδιότητες Εικόνας\",\"resetSize\":\"Επαναφορά Αρχικού Μεγέθους\",\"title\":\"Ιδιότητες Εικόνας\",\"titleButton\":\"Ιδιότητες Κουμπιού Εικόνας\",\"upload\":\"Αποστολή\",\"urlMissing\":\"Το URL πηγής για την εικόνα λείπει.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Το περίγραμμα πρέπει να είναι ένας ακέραιος αριθμός.\",\"validateHSpace\":\"Το HSpace πρέπει να είναι ένας ακέραιος αριθμός.\",\"validateVSpace\":\"Το VSpace πρέπει να είναι ένας ακέραιος αριθμός.\"},\"indent\":{\"indent\":\"Αύξηση Εσοχής\",\"outdent\":\"Μείωση Εσοχής\"},\"fakeobjects\":{\"anchor\":\"Άγκυρα\",\"flash\":\"Ταινία Flash\",\"hiddenfield\":\"Κρυφό Πεδίο\",\"iframe\":\"IFrame\",\"unknown\":\"Άγνωστο Αντικείμενο\"},\"link\":{\"acccessKey\":\"Συντόμευση\",\"advanced\":\"Για Προχωρημένους\",\"advisoryContentType\":\"Ενδεικτικός Τύπος Περιεχομένου\",\"advisoryTitle\":\"Ενδεικτικός Τίτλος\",\"anchor\":{\"toolbar\":\"Εισαγωγή/επεξεργασία Άγκυρας\",\"menu\":\"Ιδιότητες άγκυρας\",\"title\":\"Ιδιότητες άγκυρας\",\"name\":\"Όνομα άγκυρας\",\"errorName\":\"Παρακαλούμε εισάγετε όνομα άγκυρας\",\"remove\":\"Αφαίρεση Άγκυρας\"},\"anchorId\":\"Βάσει του Element Id\",\"anchorName\":\"Βάσει του Ονόματος Άγκυρας\",\"charset\":\"Κωδικοποίηση Χαρακτήρων Προσαρτημένης Πηγής\",\"cssClasses\":\"Κλάσεις Φύλλων Στυλ\",\"emailAddress\":\"Διεύθυνση E-mail\",\"emailBody\":\"Κείμενο Μηνύματος\",\"emailSubject\":\"Θέμα Μηνύματος\",\"id\":\"Id\",\"info\":\"Πληροφορίες Συνδέσμου\",\"langCode\":\"Κατεύθυνση Κειμένου\",\"langDir\":\"Κατεύθυνση Κειμένου\",\"langDirLTR\":\"Αριστερά προς Δεξιά (LTR)\",\"langDirRTL\":\"Δεξιά προς Αριστερά (RTL)\",\"menu\":\"Επεξεργασία Συνδέσμου\",\"name\":\"Όνομα\",\"noAnchors\":\"(Δεν υπάρχουν άγκυρες στο κείμενο)\",\"noEmail\":\"Εισάγετε τη διεύθυνση ηλεκτρονικού ταχυδρομείου\",\"noUrl\":\"Εισάγετε την τοποθεσία (URL) του συνδέσμου\",\"other\":\"<άλλο>\",\"popupDependent\":\"Εξαρτημένο (Netscape)\",\"popupFeatures\":\"Επιλογές Αναδυόμενου Παραθύρου\",\"popupFullScreen\":\"Πλήρης Οθόνη (IE)\",\"popupLeft\":\"Θέση Αριστερά\",\"popupLocationBar\":\"Γραμμή Τοποθεσίας\",\"popupMenuBar\":\"Γραμμή Επιλογών\",\"popupResizable\":\"Προσαρμοζόμενο Μέγεθος\",\"popupScrollBars\":\"Μπάρες Κύλισης\",\"popupStatusBar\":\"Γραμμή Κατάστασης\",\"popupToolbar\":\"Εργαλειοθήκη\",\"popupTop\":\"Θέση Πάνω\",\"rel\":\"Σχέση\",\"selectAnchor\":\"Επιλέξτε μια Άγκυρα\",\"styles\":\"Μορφή\",\"tabIndex\":\"Σειρά Μεταπήδησης\",\"target\":\"Παράθυρο Προορισμού\",\"targetFrame\":\"<πλαίσιο>\",\"targetFrameName\":\"Όνομα Πλαισίου Προορισμού\",\"targetPopup\":\"<αναδυόμενο παράθυρο>\",\"targetPopupName\":\"Όνομα Αναδυόμενου Παραθύρου\",\"title\":\"Σύνδεσμος\",\"toAnchor\":\"Άγκυρα σε αυτήν τη σελίδα\",\"toEmail\":\"E-Mail\",\"toUrl\":\"URL\",\"toolbar\":\"Σύνδεσμος\",\"type\":\"Τύπος Συνδέσμου\",\"unlink\":\"Αφαίρεση Συνδέσμου\",\"upload\":\"Αποστολή\"},\"list\":{\"bulletedlist\":\"Εισαγωγή/Απομάκρυνση Λίστας Κουκκίδων\",\"numberedlist\":\"Εισαγωγή/Απομάκρυνση Αριθμημένης Λίστας\"},\"magicline\":{\"title\":\"Εισάγετε παράγραφο εδώ\"},\"maximize\":{\"maximize\":\"Μεγιστοποίηση\",\"minimize\":\"Ελαχιστοποίηση\"},\"pastetext\":{\"button\":\"Επικόλληση ως απλό κείμενο\",\"title\":\"Επικόλληση ως απλό κείμενο\"},\"pastefromword\":{\"confirmCleanup\":\"Το κείμενο που επικολλάται φαίνεται να είναι αντιγραμμένο από το Word. Μήπως θα θέλατε να καθαριστεί προτού επικολληθεί;\",\"error\":\"Δεν ήταν δυνατό να καθαριστούν τα δεδομένα λόγω ενός εσωτερικού σφάλματος\",\"title\":\"Επικόλληση από το Word\",\"toolbar\":\"Επικόλληση από το Word\"},\"removeformat\":{\"toolbar\":\"Εκκαθάριση Μορφοποίησης\"},\"sourcearea\":{\"toolbar\":\"Κώδικας\"},\"specialchar\":{\"options\":\"Επιλογές Ειδικών Χαρακτήρων\",\"title\":\"Επιλέξτε Έναν Ειδικό Χαρακτήρα\",\"toolbar\":\"Εισαγωγή Ειδικού Χαρακτήρα\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"Περί\",\"addWord\":\"Προσθήκη στο λεξικό\",\"allCaps\":\"Να αγνοούνται όλες οι λέξεις σε κεφαλαία\",\"dic_create\":\"Δημιουργία\",\"dic_delete\":\"Διαγραφή\",\"dic_field_name\":\"Όνομα λεξικού\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Μετονομασία\",\"dic_restore\":\"Ανάκτηση\",\"dictionariesTab\":\"Λεξικά\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Το όνομα του λεξικού δεν πρέπει να είναι κενό.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Αγνόησε το\",\"ignoreAll\":\"Να αγνοηθούν όλα\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Γλώσσες\",\"languagesTab\":\"Γλώσσες\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"Περισσότερες προτάσεις\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Επιλογές\",\"optionsTab\":\"Επιλογές\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Μορφές\",\"panelTitle\":\"Στυλ Μορφοποίησης\",\"panelTitle1\":\"Στυλ Τμημάτων\",\"panelTitle2\":\"Στυλ Εν Σειρά\",\"panelTitle3\":\"Στυλ Αντικειμένων\"},\"table\":{\"border\":\"Πάχος Περιγράμματος\",\"caption\":\"Λεζάντα\",\"cell\":{\"menu\":\"Κελί\",\"insertBefore\":\"Εισαγωγή Κελιού Πριν\",\"insertAfter\":\"Εισαγωγή Κελιού Μετά\",\"deleteCell\":\"Διαγραφή Κελιών\",\"merge\":\"Ενοποίηση Κελιών\",\"mergeRight\":\"Συγχώνευση Με Δεξιά\",\"mergeDown\":\"Συγχώνευση Με Κάτω\",\"splitHorizontal\":\"Οριζόντια Διαίρεση Κελιού\",\"splitVertical\":\"Κατακόρυφη Διαίρεση Κελιού\",\"title\":\"Ιδιότητες Κελιού\",\"cellType\":\"Τύπος Κελιού\",\"rowSpan\":\"Εύρος Γραμμών\",\"colSpan\":\"Εύρος Στηλών\",\"wordWrap\":\"Αναδίπλωση Λέξεων\",\"hAlign\":\"Οριζόντια Στοίχιση\",\"vAlign\":\"Κάθετη Στοίχιση\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Χρώμα Φόντου\",\"borderColor\":\"Χρώμα Περιγράμματος\",\"data\":\"Δεδομένα\",\"header\":\"Κεφαλίδα\",\"yes\":\"Ναι\",\"no\":\"Όχι\",\"invalidWidth\":\"Το πλάτος του κελιού πρέπει να είναι αριθμός.\",\"invalidHeight\":\"Το ύψος του κελιού πρέπει να είναι αριθμός.\",\"invalidRowSpan\":\"Το εύρος των γραμμών πρέπει να είναι ακέραιος αριθμός.\",\"invalidColSpan\":\"Το εύρος των στηλών πρέπει να είναι ακέραιος αριθμός.\",\"chooseColor\":\"Επιλέξτε\"},\"cellPad\":\"Αναπλήρωση κελιών\",\"cellSpace\":\"Απόσταση κελιών\",\"column\":{\"menu\":\"Στήλη\",\"insertBefore\":\"Εισαγωγή Στήλης Πριν\",\"insertAfter\":\"Εισαγωγή Στήλης Μετά\",\"deleteColumn\":\"Διαγραφή Στηλών\"},\"columns\":\"Στήλες\",\"deleteTable\":\"Διαγραφή Πίνακα\",\"headers\":\"Κεφαλίδες\",\"headersBoth\":\"Και τα δύο\",\"headersColumn\":\"Πρώτη στήλη\",\"headersNone\":\"Κανένα\",\"headersRow\":\"Πρώτη Γραμμή\",\"invalidBorder\":\"Το πάχος του περιγράμματος πρέπει να είναι ένας αριθμός.\",\"invalidCellPadding\":\"Η αναπλήρωση των κελιών πρέπει να είναι θετικός αριθμός.\",\"invalidCellSpacing\":\"Η απόσταση μεταξύ των κελιών πρέπει να είναι ένας θετικός αριθμός.\",\"invalidCols\":\"Ο αριθμός των στηλών πρέπει να είναι μεγαλύτερος από 0.\",\"invalidHeight\":\"Το ύψος του πίνακα πρέπει να είναι αριθμός.\",\"invalidRows\":\"Ο αριθμός των σειρών πρέπει να είναι μεγαλύτερος από 0.\",\"invalidWidth\":\"Το πλάτος του πίνακα πρέπει να είναι ένας αριθμός.\",\"menu\":\"Ιδιότητες Πίνακα\",\"row\":{\"menu\":\"Γραμμή\",\"insertBefore\":\"Εισαγωγή Γραμμής Πριν\",\"insertAfter\":\"Εισαγωγή Γραμμής Μετά\",\"deleteRow\":\"Διαγραφή Γραμμών\"},\"rows\":\"Γραμμές\",\"summary\":\"Περίληψη\",\"title\":\"Ιδιότητες Πίνακα\",\"toolbar\":\"Πίνακας\",\"widthPc\":\"τοις εκατό\",\"widthPx\":\"pixel\",\"widthUnit\":\"μονάδα πλάτους\"},\"undo\":{\"redo\":\"Επανάληψη\",\"undo\":\"Αναίρεση\"},\"wsc\":{\"btnIgnore\":\"Αγνόηση\",\"btnIgnoreAll\":\"Αγνόηση όλων\",\"btnReplace\":\"Αντικατάσταση\",\"btnReplaceAll\":\"Αντικατάσταση όλων\",\"btnUndo\":\"Αναίρεση\",\"changeTo\":\"Αλλαγή σε\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Δεν υπάρχει εγκατεστημένος ορθογράφος. Θέλετε να τον κατεβάσετε τώρα;\",\"manyChanges\":\"Ο ορθογραφικός έλεγχος ολοκληρώθηκε: Άλλαξαν %1 λέξεις\",\"noChanges\":\"Ο ορθογραφικός έλεγχος ολοκληρώθηκε: Δεν άλλαξαν λέξεις\",\"noMispell\":\"Ο ορθογραφικός έλεγχος ολοκληρώθηκε: Δεν βρέθηκαν λάθη\",\"noSuggestions\":\"- Δεν υπάρχουν προτάσεις -\",\"notAvailable\":\"Η υπηρεσία δεν είναι διαθέσιμη αυτήν την στιγμή.\",\"notInDic\":\"Δεν υπάρχει στο λεξικό\",\"oneChange\":\"Ο ορθογραφικός έλεγχος ολοκληρώθηκε: Άλλαξε μια λέξη\",\"progress\":\"Γίνεται ορθογραφικός έλεγχος...\",\"title\":\"Ορθογραφικός Έλεγχος\",\"toolbar\":\"Ορθογραφικός Έλεγχος\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/en-au.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['en-au']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Press ALT 0 for help\",\"browseServer\":\"Browse Server\",\"url\":\"URL\",\"protocol\":\"Protocol\",\"upload\":\"Upload\",\"uploadSubmit\":\"Send it to the Server\",\"image\":\"Image\",\"flash\":\"Flash\",\"form\":\"Form\",\"checkbox\":\"Checkbox\",\"radio\":\"Radio Button\",\"textField\":\"Text Field\",\"textarea\":\"Textarea\",\"hiddenField\":\"Hidden Field\",\"button\":\"Button\",\"select\":\"Selection Field\",\"imageButton\":\"Image Button\",\"notSet\":\"<not set>\",\"id\":\"Id\",\"name\":\"Name\",\"langDir\":\"Language Direction\",\"langDirLtr\":\"Left to Right (LTR)\",\"langDirRtl\":\"Right to Left (RTL)\",\"langCode\":\"Language Code\",\"longDescr\":\"Long Description URL\",\"cssClass\":\"Stylesheet Classes\",\"advisoryTitle\":\"Advisory Title\",\"cssStyle\":\"Style\",\"ok\":\"OK\",\"cancel\":\"Cancel\",\"close\":\"Close\",\"preview\":\"Preview\",\"resize\":\"Resize\",\"generalTab\":\"General\",\"advancedTab\":\"Advanced\",\"validateNumberFailed\":\"This value is not a number.\",\"confirmNewPage\":\"Any unsaved changes to this content will be lost. Are you sure you want to load new page?\",\"confirmCancel\":\"You have changed some options. Are you sure you want to close the dialog window?\",\"options\":\"Options\",\"target\":\"Target\",\"targetNew\":\"New Window (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Same Window (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"Left to Right (LTR)\",\"langDirRTL\":\"Right to Left (RTL)\",\"styles\":\"Style\",\"cssClasses\":\"Stylesheet Classes\",\"width\":\"Width\",\"height\":\"Height\",\"align\":\"Align\",\"alignLeft\":\"Left\",\"alignRight\":\"Right\",\"alignCenter\":\"Centre\",\"alignTop\":\"Top\",\"alignMiddle\":\"Middle\",\"alignBottom\":\"Bottom\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Height must be a number.\",\"invalidWidth\":\"Width must be a number.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Bold\",\"italic\":\"Italic\",\"strike\":\"Strike Through\",\"subscript\":\"Subscript\",\"superscript\":\"Superscript\",\"underline\":\"Underline\"},\"blockquote\":{\"toolbar\":\"Block Quote\"},\"clipboard\":{\"copy\":\"Copy\",\"copyError\":\"Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).\",\"cut\":\"Cut\",\"cutError\":\"Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).\",\"paste\":\"Paste\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK\",\"securityMsg\":\"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.\",\"title\":\"Paste\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Collapse Toolbar\",\"toolbarExpand\":\"Expand Toolbar\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editor toolbars\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Paragraph Format\",\"tag_address\":\"Address\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatted\"},\"horizontalrule\":{\"toolbar\":\"Insert Horizontal Line\"},\"image\":{\"alertUrl\":\"Please type the image URL\",\"alt\":\"Alternative Text\",\"border\":\"Border\",\"btnUpload\":\"Send it to the Server\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"Image Info\",\"linkTab\":\"Link\",\"lockRatio\":\"Lock Ratio\",\"menu\":\"Image Properties\",\"resetSize\":\"Reset Size\",\"title\":\"Image Properties\",\"titleButton\":\"Image Button Properties\",\"upload\":\"Upload\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"Increase Indent\",\"outdent\":\"Decrease Indent\"},\"fakeobjects\":{\"anchor\":\"Anchor\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Hidden Field\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"Access Key\",\"advanced\":\"Advanced\",\"advisoryContentType\":\"Advisory Content Type\",\"advisoryTitle\":\"Advisory Title\",\"anchor\":{\"toolbar\":\"Anchor\",\"menu\":\"Edit Anchor\",\"title\":\"Anchor Properties\",\"name\":\"Anchor Name\",\"errorName\":\"Please type the anchor name\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"By Element Id\",\"anchorName\":\"By Anchor Name\",\"charset\":\"Linked Resource Charset\",\"cssClasses\":\"Stylesheet Classes\",\"emailAddress\":\"E-Mail Address\",\"emailBody\":\"Message Body\",\"emailSubject\":\"Message Subject\",\"id\":\"Id\",\"info\":\"Link Info\",\"langCode\":\"Language Code\",\"langDir\":\"Language Direction\",\"langDirLTR\":\"Left to Right (LTR)\",\"langDirRTL\":\"Right to Left (RTL)\",\"menu\":\"Edit Link\",\"name\":\"Name\",\"noAnchors\":\"(No anchors available in the document)\",\"noEmail\":\"Please type the e-mail address\",\"noUrl\":\"Please type the link URL\",\"other\":\"<other>\",\"popupDependent\":\"Dependent (Netscape)\",\"popupFeatures\":\"Popup Window Features\",\"popupFullScreen\":\"Full Screen (IE)\",\"popupLeft\":\"Left Position\",\"popupLocationBar\":\"Location Bar\",\"popupMenuBar\":\"Menu Bar\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"Scroll Bars\",\"popupStatusBar\":\"Status Bar\",\"popupToolbar\":\"Toolbar\",\"popupTop\":\"Top Position\",\"rel\":\"Relationship\",\"selectAnchor\":\"Select an Anchor\",\"styles\":\"Style\",\"tabIndex\":\"Tab Index\",\"target\":\"Target\",\"targetFrame\":\"<frame>\",\"targetFrameName\":\"Target Frame Name\",\"targetPopup\":\"<popup window>\",\"targetPopupName\":\"Popup Window Name\",\"title\":\"Link\",\"toAnchor\":\"Link to anchor in the text\",\"toEmail\":\"E-mail\",\"toUrl\":\"URL\",\"toolbar\":\"Link\",\"type\":\"Link Type\",\"unlink\":\"Unlink\",\"upload\":\"Upload\"},\"list\":{\"bulletedlist\":\"Insert/Remove Bulleted List\",\"numberedlist\":\"Insert/Remove Numbered List\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maximize\",\"minimize\":\"Minimize\"},\"pastetext\":{\"button\":\"Paste as plain text\",\"title\":\"Paste as Plain Text\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"Paste from Word\",\"toolbar\":\"Paste from Word\"},\"removeformat\":{\"toolbar\":\"Remove Format\"},\"sourcearea\":{\"toolbar\":\"Source\"},\"specialchar\":{\"options\":\"Special Character Options\",\"title\":\"Select Special Character\",\"toolbar\":\"Insert Special Character\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Styles\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"Border size\",\"caption\":\"Caption\",\"cell\":{\"menu\":\"Cell\",\"insertBefore\":\"Insert Cell Before\",\"insertAfter\":\"Insert Cell After\",\"deleteCell\":\"Delete Cells\",\"merge\":\"Merge Cells\",\"mergeRight\":\"Merge Right\",\"mergeDown\":\"Merge Down\",\"splitHorizontal\":\"Split Cell Horizontally\",\"splitVertical\":\"Split Cell Vertically\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"Cell padding\",\"cellSpace\":\"Cell spacing\",\"column\":{\"menu\":\"Column\",\"insertBefore\":\"Insert Column Before\",\"insertAfter\":\"Insert Column After\",\"deleteColumn\":\"Delete Columns\"},\"columns\":\"Columns\",\"deleteTable\":\"Delete Table\",\"headers\":\"Headers\",\"headersBoth\":\"Both\",\"headersColumn\":\"First column\",\"headersNone\":\"None\",\"headersRow\":\"First Row\",\"invalidBorder\":\"Border size must be a number.\",\"invalidCellPadding\":\"Cell padding must be a number.\",\"invalidCellSpacing\":\"Cell spacing must be a number.\",\"invalidCols\":\"Number of columns must be a number greater than 0.\",\"invalidHeight\":\"Table height must be a number.\",\"invalidRows\":\"Number of rows must be a number greater than 0.\",\"invalidWidth\":\"Table width must be a number.\",\"menu\":\"Table Properties\",\"row\":{\"menu\":\"Row\",\"insertBefore\":\"Insert Row Before\",\"insertAfter\":\"Insert Row After\",\"deleteRow\":\"Delete Rows\"},\"rows\":\"Rows\",\"summary\":\"Summary\",\"title\":\"Table Properties\",\"toolbar\":\"Table\",\"widthPc\":\"percent\",\"widthPx\":\"pixels\",\"widthUnit\":\"width unit\"},\"undo\":{\"redo\":\"Redo\",\"undo\":\"Undo\"},\"wsc\":{\"btnIgnore\":\"Ignore\",\"btnIgnoreAll\":\"Ignore All\",\"btnReplace\":\"Replace\",\"btnReplaceAll\":\"Replace All\",\"btnUndo\":\"Undo\",\"changeTo\":\"Change to\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Spell checker not installed. Do you want to download it now?\",\"manyChanges\":\"Spell check complete: %1 words changed\",\"noChanges\":\"Spell check complete: No words changed\",\"noMispell\":\"Spell check complete: No misspellings found\",\"noSuggestions\":\"- No suggestions -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Not in dictionary\",\"oneChange\":\"Spell check complete: One word changed\",\"progress\":\"Spell check in progress...\",\"title\":\"Spell Check\",\"toolbar\":\"Check Spelling\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/en-ca.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['en-ca']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Press ALT 0 for help\",\"browseServer\":\"Browse Server\",\"url\":\"URL\",\"protocol\":\"Protocol\",\"upload\":\"Upload\",\"uploadSubmit\":\"Send it to the Server\",\"image\":\"Image\",\"flash\":\"Flash\",\"form\":\"Form\",\"checkbox\":\"Checkbox\",\"radio\":\"Radio Button\",\"textField\":\"Text Field\",\"textarea\":\"Textarea\",\"hiddenField\":\"Hidden Field\",\"button\":\"Button\",\"select\":\"Selection Field\",\"imageButton\":\"Image Button\",\"notSet\":\"<not set>\",\"id\":\"Id\",\"name\":\"Name\",\"langDir\":\"Language Direction\",\"langDirLtr\":\"Left to Right (LTR)\",\"langDirRtl\":\"Right to Left (RTL)\",\"langCode\":\"Language Code\",\"longDescr\":\"Long Description URL\",\"cssClass\":\"Stylesheet Classes\",\"advisoryTitle\":\"Advisory Title\",\"cssStyle\":\"Style\",\"ok\":\"OK\",\"cancel\":\"Cancel\",\"close\":\"Close\",\"preview\":\"Preview\",\"resize\":\"Resize\",\"generalTab\":\"General\",\"advancedTab\":\"Advanced\",\"validateNumberFailed\":\"This value is not a number.\",\"confirmNewPage\":\"Any unsaved changes to this content will be lost. Are you sure you want to load new page?\",\"confirmCancel\":\"You have changed some options. Are you sure you want to close the dialog window?\",\"options\":\"Options\",\"target\":\"Target\",\"targetNew\":\"New Window (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Same Window (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"Left to Right (LTR)\",\"langDirRTL\":\"Right to Left (RTL)\",\"styles\":\"Style\",\"cssClasses\":\"Stylesheet Classes\",\"width\":\"Width\",\"height\":\"Height\",\"align\":\"Align\",\"alignLeft\":\"Left\",\"alignRight\":\"Right\",\"alignCenter\":\"Centre\",\"alignTop\":\"Top\",\"alignMiddle\":\"Middle\",\"alignBottom\":\"Bottom\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Height must be a number.\",\"invalidWidth\":\"Width must be a number.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Bold\",\"italic\":\"Italic\",\"strike\":\"Strike Through\",\"subscript\":\"Subscript\",\"superscript\":\"Superscript\",\"underline\":\"Underline\"},\"blockquote\":{\"toolbar\":\"Block Quote\"},\"clipboard\":{\"copy\":\"Copy\",\"copyError\":\"Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).\",\"cut\":\"Cut\",\"cutError\":\"Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).\",\"paste\":\"Paste\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK\",\"securityMsg\":\"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.\",\"title\":\"Paste\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Collapse Toolbar\",\"toolbarExpand\":\"Expand Toolbar\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editor toolbars\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Paragraph Format\",\"tag_address\":\"Address\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatted\"},\"horizontalrule\":{\"toolbar\":\"Insert Horizontal Line\"},\"image\":{\"alertUrl\":\"Please type the image URL\",\"alt\":\"Alternative Text\",\"border\":\"Border\",\"btnUpload\":\"Send it to the Server\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"Image Info\",\"linkTab\":\"Link\",\"lockRatio\":\"Lock Ratio\",\"menu\":\"Image Properties\",\"resetSize\":\"Reset Size\",\"title\":\"Image Properties\",\"titleButton\":\"Image Button Properties\",\"upload\":\"Upload\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"Increase Indent\",\"outdent\":\"Decrease Indent\"},\"fakeobjects\":{\"anchor\":\"Anchor\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Hidden Field\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"Access Key\",\"advanced\":\"Advanced\",\"advisoryContentType\":\"Advisory Content Type\",\"advisoryTitle\":\"Advisory Title\",\"anchor\":{\"toolbar\":\"Anchor\",\"menu\":\"Edit Anchor\",\"title\":\"Anchor Properties\",\"name\":\"Anchor Name\",\"errorName\":\"Please type the anchor name\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"By Element Id\",\"anchorName\":\"By Anchor Name\",\"charset\":\"Linked Resource Charset\",\"cssClasses\":\"Stylesheet Classes\",\"emailAddress\":\"E-Mail Address\",\"emailBody\":\"Message Body\",\"emailSubject\":\"Message Subject\",\"id\":\"Id\",\"info\":\"Link Info\",\"langCode\":\"Language Code\",\"langDir\":\"Language Direction\",\"langDirLTR\":\"Left to Right (LTR)\",\"langDirRTL\":\"Right to Left (RTL)\",\"menu\":\"Edit Link\",\"name\":\"Name\",\"noAnchors\":\"(No anchors available in the document)\",\"noEmail\":\"Please type the e-mail address\",\"noUrl\":\"Please type the link URL\",\"other\":\"<other>\",\"popupDependent\":\"Dependent (Netscape)\",\"popupFeatures\":\"Popup Window Features\",\"popupFullScreen\":\"Full Screen (IE)\",\"popupLeft\":\"Left Position\",\"popupLocationBar\":\"Location Bar\",\"popupMenuBar\":\"Menu Bar\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"Scroll Bars\",\"popupStatusBar\":\"Status Bar\",\"popupToolbar\":\"Toolbar\",\"popupTop\":\"Top Position\",\"rel\":\"Relationship\",\"selectAnchor\":\"Select an Anchor\",\"styles\":\"Style\",\"tabIndex\":\"Tab Index\",\"target\":\"Target\",\"targetFrame\":\"<frame>\",\"targetFrameName\":\"Target Frame Name\",\"targetPopup\":\"<popup window>\",\"targetPopupName\":\"Popup Window Name\",\"title\":\"Link\",\"toAnchor\":\"Link to anchor in the text\",\"toEmail\":\"E-mail\",\"toUrl\":\"URL\",\"toolbar\":\"Link\",\"type\":\"Link Type\",\"unlink\":\"Unlink\",\"upload\":\"Upload\"},\"list\":{\"bulletedlist\":\"Insert/Remove Bulleted List\",\"numberedlist\":\"Insert/Remove Numbered List\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maximize\",\"minimize\":\"Minimize\"},\"pastetext\":{\"button\":\"Paste as plain text\",\"title\":\"Paste as Plain Text\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"Paste from Word\",\"toolbar\":\"Paste from Word\"},\"removeformat\":{\"toolbar\":\"Remove Format\"},\"sourcearea\":{\"toolbar\":\"Source\"},\"specialchar\":{\"options\":\"Special Character Options\",\"title\":\"Select Special Character\",\"toolbar\":\"Insert Special Character\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Styles\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"Border size\",\"caption\":\"Caption\",\"cell\":{\"menu\":\"Cell\",\"insertBefore\":\"Insert Cell Before\",\"insertAfter\":\"Insert Cell After\",\"deleteCell\":\"Delete Cells\",\"merge\":\"Merge Cells\",\"mergeRight\":\"Merge Right\",\"mergeDown\":\"Merge Down\",\"splitHorizontal\":\"Split Cell Horizontally\",\"splitVertical\":\"Split Cell Vertically\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"Cell padding\",\"cellSpace\":\"Cell spacing\",\"column\":{\"menu\":\"Column\",\"insertBefore\":\"Insert Column Before\",\"insertAfter\":\"Insert Column After\",\"deleteColumn\":\"Delete Columns\"},\"columns\":\"Columns\",\"deleteTable\":\"Delete Table\",\"headers\":\"Headers\",\"headersBoth\":\"Both\",\"headersColumn\":\"First column\",\"headersNone\":\"None\",\"headersRow\":\"First Row\",\"invalidBorder\":\"Border size must be a number.\",\"invalidCellPadding\":\"Cell padding must be a number.\",\"invalidCellSpacing\":\"Cell spacing must be a number.\",\"invalidCols\":\"Number of columns must be a number greater than 0.\",\"invalidHeight\":\"Table height must be a number.\",\"invalidRows\":\"Number of rows must be a number greater than 0.\",\"invalidWidth\":\"Table width must be a number.\",\"menu\":\"Table Properties\",\"row\":{\"menu\":\"Row\",\"insertBefore\":\"Insert Row Before\",\"insertAfter\":\"Insert Row After\",\"deleteRow\":\"Delete Rows\"},\"rows\":\"Rows\",\"summary\":\"Summary\",\"title\":\"Table Properties\",\"toolbar\":\"Table\",\"widthPc\":\"percent\",\"widthPx\":\"pixels\",\"widthUnit\":\"width unit\"},\"undo\":{\"redo\":\"Redo\",\"undo\":\"Undo\"},\"wsc\":{\"btnIgnore\":\"Ignore\",\"btnIgnoreAll\":\"Ignore All\",\"btnReplace\":\"Replace\",\"btnReplaceAll\":\"Replace All\",\"btnUndo\":\"Undo\",\"changeTo\":\"Change to\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Spell checker not installed. Do you want to download it now?\",\"manyChanges\":\"Spell check complete: %1 words changed\",\"noChanges\":\"Spell check complete: No words changed\",\"noMispell\":\"Spell check complete: No misspellings found\",\"noSuggestions\":\"- No suggestions -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Not in dictionary\",\"oneChange\":\"Spell check complete: One word changed\",\"progress\":\"Spell check in progress...\",\"title\":\"Spell Check\",\"toolbar\":\"Check Spelling\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/en-gb.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['en-gb']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Press ALT 0 for help\",\"browseServer\":\"Browse Server\",\"url\":\"URL\",\"protocol\":\"Protocol\",\"upload\":\"Upload\",\"uploadSubmit\":\"Send it to the Server\",\"image\":\"Image\",\"flash\":\"Flash\",\"form\":\"Form\",\"checkbox\":\"Checkbox\",\"radio\":\"Radio Button\",\"textField\":\"Text Field\",\"textarea\":\"Textarea\",\"hiddenField\":\"Hidden Field\",\"button\":\"Button\",\"select\":\"Selection Field\",\"imageButton\":\"Image Button\",\"notSet\":\"<not set>\",\"id\":\"Id\",\"name\":\"Name\",\"langDir\":\"Language Direction\",\"langDirLtr\":\"Left to Right (LTR)\",\"langDirRtl\":\"Right to Left (RTL)\",\"langCode\":\"Language Code\",\"longDescr\":\"Long Description URL\",\"cssClass\":\"Stylesheet Classes\",\"advisoryTitle\":\"Advisory Title\",\"cssStyle\":\"Style\",\"ok\":\"OK\",\"cancel\":\"Cancel\",\"close\":\"Close\",\"preview\":\"Preview\",\"resize\":\"Drag to resize\",\"generalTab\":\"General\",\"advancedTab\":\"Advanced\",\"validateNumberFailed\":\"This value is not a number.\",\"confirmNewPage\":\"Any unsaved changes to this content will be lost. Are you sure you want to load new page?\",\"confirmCancel\":\"You have changed some options. Are you sure you want to close the dialogue window?\",\"options\":\"Options\",\"target\":\"Target\",\"targetNew\":\"New Window (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Same Window (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"Left to Right (LTR)\",\"langDirRTL\":\"Right to Left (RTL)\",\"styles\":\"Style\",\"cssClasses\":\"Stylesheet Classes\",\"width\":\"Width\",\"height\":\"Height\",\"align\":\"Align\",\"alignLeft\":\"Left\",\"alignRight\":\"Right\",\"alignCenter\":\"Centre\",\"alignTop\":\"Top\",\"alignMiddle\":\"Middle\",\"alignBottom\":\"Bottom\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Height must be a number.\",\"invalidWidth\":\"Width must be a number.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Bold\",\"italic\":\"Italic\",\"strike\":\"Strike Through\",\"subscript\":\"Subscript\",\"superscript\":\"Superscript\",\"underline\":\"Underline\"},\"blockquote\":{\"toolbar\":\"Block Quote\"},\"clipboard\":{\"copy\":\"Copy\",\"copyError\":\"Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).\",\"cut\":\"Cut\",\"cutError\":\"Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).\",\"paste\":\"Paste\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK\",\"securityMsg\":\"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.\",\"title\":\"Paste\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Collapse Toolbar\",\"toolbarExpand\":\"Expand Toolbar\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editor toolbars\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Paragraph Format\",\"tag_address\":\"Address\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatted\"},\"horizontalrule\":{\"toolbar\":\"Insert Horizontal Line\"},\"image\":{\"alertUrl\":\"Please type the image URL\",\"alt\":\"Alternative Text\",\"border\":\"Border\",\"btnUpload\":\"Send it to the Server\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"Image Info\",\"linkTab\":\"Link\",\"lockRatio\":\"Lock Ratio\",\"menu\":\"Image Properties\",\"resetSize\":\"Reset Size\",\"title\":\"Image Properties\",\"titleButton\":\"Image Button Properties\",\"upload\":\"Upload\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"Increase Indent\",\"outdent\":\"Decrease Indent\"},\"fakeobjects\":{\"anchor\":\"Anchor\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Hidden Field\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"Access Key\",\"advanced\":\"Advanced\",\"advisoryContentType\":\"Advisory Content Type\",\"advisoryTitle\":\"Advisory Title\",\"anchor\":{\"toolbar\":\"Anchor\",\"menu\":\"Edit Anchor\",\"title\":\"Anchor Properties\",\"name\":\"Anchor Name\",\"errorName\":\"Please type the anchor name\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"By Element Id\",\"anchorName\":\"By Anchor Name\",\"charset\":\"Linked Resource Charset\",\"cssClasses\":\"Stylesheet Classes\",\"emailAddress\":\"E-Mail Address\",\"emailBody\":\"Message Body\",\"emailSubject\":\"Message Subject\",\"id\":\"Id\",\"info\":\"Link Info\",\"langCode\":\"Language Code\",\"langDir\":\"Language Direction\",\"langDirLTR\":\"Left to Right (LTR)\",\"langDirRTL\":\"Right to Left (RTL)\",\"menu\":\"Edit Link\",\"name\":\"Name\",\"noAnchors\":\"(No anchors available in the document)\",\"noEmail\":\"Please type the e-mail address\",\"noUrl\":\"Please type the link URL\",\"other\":\"<other>\",\"popupDependent\":\"Dependent (Netscape)\",\"popupFeatures\":\"Popup Window Features\",\"popupFullScreen\":\"Full Screen (IE)\",\"popupLeft\":\"Left Position\",\"popupLocationBar\":\"Location Bar\",\"popupMenuBar\":\"Menu Bar\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"Scroll Bars\",\"popupStatusBar\":\"Status Bar\",\"popupToolbar\":\"Toolbar\",\"popupTop\":\"Top Position\",\"rel\":\"Relationship\",\"selectAnchor\":\"Select an Anchor\",\"styles\":\"Style\",\"tabIndex\":\"Tab Index\",\"target\":\"Target\",\"targetFrame\":\"<frame>\",\"targetFrameName\":\"Target Frame Name\",\"targetPopup\":\"<popup window>\",\"targetPopupName\":\"Popup Window Name\",\"title\":\"Link\",\"toAnchor\":\"Link to anchor in the text\",\"toEmail\":\"E-mail\",\"toUrl\":\"URL\",\"toolbar\":\"Link\",\"type\":\"Link Type\",\"unlink\":\"Unlink\",\"upload\":\"Upload\"},\"list\":{\"bulletedlist\":\"Insert/Remove Bulleted List\",\"numberedlist\":\"Insert/Remove Numbered List\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maximise\",\"minimize\":\"Minimise\"},\"pastetext\":{\"button\":\"Paste as plain text\",\"title\":\"Paste as Plain Text\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"Paste from Word\",\"toolbar\":\"Paste from Word\"},\"removeformat\":{\"toolbar\":\"Remove Format\"},\"sourcearea\":{\"toolbar\":\"Source\"},\"specialchar\":{\"options\":\"Special Character Options\",\"title\":\"Select Special Character\",\"toolbar\":\"Insert Special Character\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Styles\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"Border size\",\"caption\":\"Caption\",\"cell\":{\"menu\":\"Cell\",\"insertBefore\":\"Insert Cell Before\",\"insertAfter\":\"Insert Cell After\",\"deleteCell\":\"Delete Cells\",\"merge\":\"Merge Cells\",\"mergeRight\":\"Merge Right\",\"mergeDown\":\"Merge Down\",\"splitHorizontal\":\"Split Cell Horizontally\",\"splitVertical\":\"Split Cell Vertically\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"Cell padding\",\"cellSpace\":\"Cell spacing\",\"column\":{\"menu\":\"Column\",\"insertBefore\":\"Insert Column Before\",\"insertAfter\":\"Insert Column After\",\"deleteColumn\":\"Delete Columns\"},\"columns\":\"Columns\",\"deleteTable\":\"Delete Table\",\"headers\":\"Headers\",\"headersBoth\":\"Both\",\"headersColumn\":\"First column\",\"headersNone\":\"None\",\"headersRow\":\"First Row\",\"invalidBorder\":\"Border size must be a number.\",\"invalidCellPadding\":\"Cell padding must be a number.\",\"invalidCellSpacing\":\"Cell spacing must be a number.\",\"invalidCols\":\"Number of columns must be a number greater than 0.\",\"invalidHeight\":\"Table height must be a number.\",\"invalidRows\":\"Number of rows must be a number greater than 0.\",\"invalidWidth\":\"Table width must be a number.\",\"menu\":\"Table Properties\",\"row\":{\"menu\":\"Row\",\"insertBefore\":\"Insert Row Before\",\"insertAfter\":\"Insert Row After\",\"deleteRow\":\"Delete Rows\"},\"rows\":\"Rows\",\"summary\":\"Summary\",\"title\":\"Table Properties\",\"toolbar\":\"Table\",\"widthPc\":\"percent\",\"widthPx\":\"pixels\",\"widthUnit\":\"width unit\"},\"undo\":{\"redo\":\"Redo\",\"undo\":\"Undo\"},\"wsc\":{\"btnIgnore\":\"Ignore\",\"btnIgnoreAll\":\"Ignore All\",\"btnReplace\":\"Replace\",\"btnReplaceAll\":\"Replace All\",\"btnUndo\":\"Undo\",\"changeTo\":\"Change to\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Spell checker not installed. Do you want to download it now?\",\"manyChanges\":\"Spell check complete: %1 words changed\",\"noChanges\":\"Spell check complete: No words changed\",\"noMispell\":\"Spell check complete: No misspellings found\",\"noSuggestions\":\"- No suggestions -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Not in dictionary\",\"oneChange\":\"Spell check complete: One word changed\",\"progress\":\"Spell check in progress...\",\"title\":\"Spell Check\",\"toolbar\":\"Check Spelling\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/en.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['en']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Press ALT 0 for help\",\"browseServer\":\"Browse Server\",\"url\":\"URL\",\"protocol\":\"Protocol\",\"upload\":\"Upload\",\"uploadSubmit\":\"Send it to the Server\",\"image\":\"Image\",\"flash\":\"Flash\",\"form\":\"Form\",\"checkbox\":\"Checkbox\",\"radio\":\"Radio Button\",\"textField\":\"Text Field\",\"textarea\":\"Textarea\",\"hiddenField\":\"Hidden Field\",\"button\":\"Button\",\"select\":\"Selection Field\",\"imageButton\":\"Image Button\",\"notSet\":\"<not set>\",\"id\":\"Id\",\"name\":\"Name\",\"langDir\":\"Language Direction\",\"langDirLtr\":\"Left to Right (LTR)\",\"langDirRtl\":\"Right to Left (RTL)\",\"langCode\":\"Language Code\",\"longDescr\":\"Long Description URL\",\"cssClass\":\"Stylesheet Classes\",\"advisoryTitle\":\"Advisory Title\",\"cssStyle\":\"Style\",\"ok\":\"OK\",\"cancel\":\"Cancel\",\"close\":\"Close\",\"preview\":\"Preview\",\"resize\":\"Resize\",\"generalTab\":\"General\",\"advancedTab\":\"Advanced\",\"validateNumberFailed\":\"This value is not a number.\",\"confirmNewPage\":\"Any unsaved changes to this content will be lost. Are you sure you want to load new page?\",\"confirmCancel\":\"You have changed some options. Are you sure you want to close the dialog window?\",\"options\":\"Options\",\"target\":\"Target\",\"targetNew\":\"New Window (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Same Window (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"Left to Right (LTR)\",\"langDirRTL\":\"Right to Left (RTL)\",\"styles\":\"Style\",\"cssClasses\":\"Stylesheet Classes\",\"width\":\"Width\",\"height\":\"Height\",\"align\":\"Alignment\",\"alignLeft\":\"Left\",\"alignRight\":\"Right\",\"alignCenter\":\"Center\",\"alignTop\":\"Top\",\"alignMiddle\":\"Middle\",\"alignBottom\":\"Bottom\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Height must be a number.\",\"invalidWidth\":\"Width must be a number.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Bold\",\"italic\":\"Italic\",\"strike\":\"Strike Through\",\"subscript\":\"Subscript\",\"superscript\":\"Superscript\",\"underline\":\"Underline\"},\"blockquote\":{\"toolbar\":\"Block Quote\"},\"clipboard\":{\"copy\":\"Copy\",\"copyError\":\"Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).\",\"cut\":\"Cut\",\"cutError\":\"Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).\",\"paste\":\"Paste\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK\",\"securityMsg\":\"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.\",\"title\":\"Paste\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Collapse Toolbar\",\"toolbarExpand\":\"Expand Toolbar\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editor toolbars\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Paragraph Format\",\"tag_address\":\"Address\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatted\"},\"horizontalrule\":{\"toolbar\":\"Insert Horizontal Line\"},\"image\":{\"alertUrl\":\"Please type the image URL\",\"alt\":\"Alternative Text\",\"border\":\"Border\",\"btnUpload\":\"Send it to the Server\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"Image Info\",\"linkTab\":\"Link\",\"lockRatio\":\"Lock Ratio\",\"menu\":\"Image Properties\",\"resetSize\":\"Reset Size\",\"title\":\"Image Properties\",\"titleButton\":\"Image Button Properties\",\"upload\":\"Upload\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"Increase Indent\",\"outdent\":\"Decrease Indent\"},\"fakeobjects\":{\"anchor\":\"Anchor\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Hidden Field\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"Access Key\",\"advanced\":\"Advanced\",\"advisoryContentType\":\"Advisory Content Type\",\"advisoryTitle\":\"Advisory Title\",\"anchor\":{\"toolbar\":\"Anchor\",\"menu\":\"Edit Anchor\",\"title\":\"Anchor Properties\",\"name\":\"Anchor Name\",\"errorName\":\"Please type the anchor name\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"By Element Id\",\"anchorName\":\"By Anchor Name\",\"charset\":\"Linked Resource Charset\",\"cssClasses\":\"Stylesheet Classes\",\"emailAddress\":\"E-Mail Address\",\"emailBody\":\"Message Body\",\"emailSubject\":\"Message Subject\",\"id\":\"Id\",\"info\":\"Link Info\",\"langCode\":\"Language Code\",\"langDir\":\"Language Direction\",\"langDirLTR\":\"Left to Right (LTR)\",\"langDirRTL\":\"Right to Left (RTL)\",\"menu\":\"Edit Link\",\"name\":\"Name\",\"noAnchors\":\"(No anchors available in the document)\",\"noEmail\":\"Please type the e-mail address\",\"noUrl\":\"Please type the link URL\",\"other\":\"<other>\",\"popupDependent\":\"Dependent (Netscape)\",\"popupFeatures\":\"Popup Window Features\",\"popupFullScreen\":\"Full Screen (IE)\",\"popupLeft\":\"Left Position\",\"popupLocationBar\":\"Location Bar\",\"popupMenuBar\":\"Menu Bar\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"Scroll Bars\",\"popupStatusBar\":\"Status Bar\",\"popupToolbar\":\"Toolbar\",\"popupTop\":\"Top Position\",\"rel\":\"Relationship\",\"selectAnchor\":\"Select an Anchor\",\"styles\":\"Style\",\"tabIndex\":\"Tab Index\",\"target\":\"Target\",\"targetFrame\":\"<frame>\",\"targetFrameName\":\"Target Frame Name\",\"targetPopup\":\"<popup window>\",\"targetPopupName\":\"Popup Window Name\",\"title\":\"Link\",\"toAnchor\":\"Link to anchor in the text\",\"toEmail\":\"E-mail\",\"toUrl\":\"URL\",\"toolbar\":\"Link\",\"type\":\"Link Type\",\"unlink\":\"Unlink\",\"upload\":\"Upload\"},\"list\":{\"bulletedlist\":\"Insert/Remove Bulleted List\",\"numberedlist\":\"Insert/Remove Numbered List\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maximize\",\"minimize\":\"Minimize\"},\"pastetext\":{\"button\":\"Paste as plain text\",\"title\":\"Paste as Plain Text\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"Paste from Word\",\"toolbar\":\"Paste from Word\"},\"removeformat\":{\"toolbar\":\"Remove Format\"},\"sourcearea\":{\"toolbar\":\"Source\"},\"specialchar\":{\"options\":\"Special Character Options\",\"title\":\"Select Special Character\",\"toolbar\":\"Insert Special Character\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Styles\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"Border size\",\"caption\":\"Caption\",\"cell\":{\"menu\":\"Cell\",\"insertBefore\":\"Insert Cell Before\",\"insertAfter\":\"Insert Cell After\",\"deleteCell\":\"Delete Cells\",\"merge\":\"Merge Cells\",\"mergeRight\":\"Merge Right\",\"mergeDown\":\"Merge Down\",\"splitHorizontal\":\"Split Cell Horizontally\",\"splitVertical\":\"Split Cell Vertically\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"Cell padding\",\"cellSpace\":\"Cell spacing\",\"column\":{\"menu\":\"Column\",\"insertBefore\":\"Insert Column Before\",\"insertAfter\":\"Insert Column After\",\"deleteColumn\":\"Delete Columns\"},\"columns\":\"Columns\",\"deleteTable\":\"Delete Table\",\"headers\":\"Headers\",\"headersBoth\":\"Both\",\"headersColumn\":\"First column\",\"headersNone\":\"None\",\"headersRow\":\"First Row\",\"invalidBorder\":\"Border size must be a number.\",\"invalidCellPadding\":\"Cell padding must be a positive number.\",\"invalidCellSpacing\":\"Cell spacing must be a positive number.\",\"invalidCols\":\"Number of columns must be a number greater than 0.\",\"invalidHeight\":\"Table height must be a number.\",\"invalidRows\":\"Number of rows must be a number greater than 0.\",\"invalidWidth\":\"Table width must be a number.\",\"menu\":\"Table Properties\",\"row\":{\"menu\":\"Row\",\"insertBefore\":\"Insert Row Before\",\"insertAfter\":\"Insert Row After\",\"deleteRow\":\"Delete Rows\"},\"rows\":\"Rows\",\"summary\":\"Summary\",\"title\":\"Table Properties\",\"toolbar\":\"Table\",\"widthPc\":\"percent\",\"widthPx\":\"pixels\",\"widthUnit\":\"width unit\"},\"undo\":{\"redo\":\"Redo\",\"undo\":\"Undo\"},\"wsc\":{\"btnIgnore\":\"Ignore\",\"btnIgnoreAll\":\"Ignore All\",\"btnReplace\":\"Replace\",\"btnReplaceAll\":\"Replace All\",\"btnUndo\":\"Undo\",\"changeTo\":\"Change to\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Spell checker not installed. Do you want to download it now?\",\"manyChanges\":\"Spell check complete: %1 words changed\",\"noChanges\":\"Spell check complete: No words changed\",\"noMispell\":\"Spell check complete: No misspellings found\",\"noSuggestions\":\"- No suggestions -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Not in dictionary\",\"oneChange\":\"Spell check complete: One word changed\",\"progress\":\"Spell check in progress...\",\"title\":\"Spell Check\",\"toolbar\":\"Check Spelling\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/eo.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['eo']={\"editor\":\"Redaktilo por Riĉiga Teksto\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Premu ALT 0 por helpilo\",\"browseServer\":\"Foliumi en la Servilo\",\"url\":\"URL\",\"protocol\":\"Protokolo\",\"upload\":\"Alŝuti\",\"uploadSubmit\":\"Sendu al Servilo\",\"image\":\"Bildo\",\"flash\":\"Flaŝo\",\"form\":\"Formularo\",\"checkbox\":\"Markobutono\",\"radio\":\"Radiobutono\",\"textField\":\"Teksta kampo\",\"textarea\":\"Teksta Areo\",\"hiddenField\":\"Kaŝita Kampo\",\"button\":\"Butono\",\"select\":\"Elekta Kampo\",\"imageButton\":\"Bildbutono\",\"notSet\":\"<Defaŭlta>\",\"id\":\"Id\",\"name\":\"Nomo\",\"langDir\":\"Skribdirekto\",\"langDirLtr\":\"De maldekstro dekstren (LTR)\",\"langDirRtl\":\"De dekstro maldekstren (RTL)\",\"langCode\":\"Lingva Kodo\",\"longDescr\":\"URL de Longa Priskribo\",\"cssClass\":\"Klasoj de Stilfolioj\",\"advisoryTitle\":\"Priskriba Titolo\",\"cssStyle\":\"Stilo\",\"ok\":\"Akcepti\",\"cancel\":\"Rezigni\",\"close\":\"Fermi\",\"preview\":\"Vidigi Aspekton\",\"resize\":\"Movigi por ŝanĝi la grandon\",\"generalTab\":\"Ĝenerala\",\"advancedTab\":\"Speciala\",\"validateNumberFailed\":\"Tiu valoro ne estas nombro.\",\"confirmNewPage\":\"La neregistritaj ŝanĝoj estas perdotaj. Ĉu vi certas, ke vi volas ŝargi novan paĝon?\",\"confirmCancel\":\"Iuj opcioj esta ŝanĝitaj. Ĉu vi certas, ke vi volas fermi la dialogon?\",\"options\":\"Opcioj\",\"target\":\"Celo\",\"targetNew\":\"Nova Fenestro (_blank)\",\"targetTop\":\"Supra Fenestro (_top)\",\"targetSelf\":\"Sama Fenestro (_self)\",\"targetParent\":\"Patra Fenestro (_parent)\",\"langDirLTR\":\"De maldekstro dekstren (LTR)\",\"langDirRTL\":\"De dekstro maldekstren (RTL)\",\"styles\":\"Stilo\",\"cssClasses\":\"Stilfoliaj Klasoj\",\"width\":\"Larĝo\",\"height\":\"Alto\",\"align\":\"Ĝisrandigo\",\"alignLeft\":\"Maldekstre\",\"alignRight\":\"Dekstre\",\"alignCenter\":\"Centre\",\"alignTop\":\"Supre\",\"alignMiddle\":\"Centre\",\"alignBottom\":\"Malsupre\",\"invalidValue\":\"Nevalida Valoro\",\"invalidHeight\":\"Alto devas esti nombro.\",\"invalidWidth\":\"Larĝo devas esti nombro.\",\"invalidCssLength\":\"La valoro indikita por la \\\"%1\\\" kampo devas esti pozitiva nombro kun aŭ sen valida CSSmezurunuo (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"La valoro indikita por la \\\"%1\\\" kampo devas esti pozitiva nombro kun aŭ sen valida HTMLmezurunuo (px or %).\",\"invalidInlineStyle\":\"La valoro indikita por la enlinia stilo devas konsisti el unu aŭ pluraj elementoj kun la formato de \\\"nomo : valoro\\\", apartigitaj per punktokomoj.\",\"cssLengthTooltip\":\"Entajpu nombron por rastrumera valoro aŭ nombron kun valida CSSunuo (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, nehavebla</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Ĉiuj rajtoj rezervitaj.\",\"dlgTitle\":\"Pri CKEditor\",\"help\":\"Kontroli $1 por helpo.\",\"moreInfo\":\"Por informoj pri licenco, bonvolu viziti nian retpaĝaron:\",\"title\":\"Pri CKEditor\",\"userGuide\":\"CKEditor Uzindikoj\"},\"basicstyles\":{\"bold\":\"Grasa\",\"italic\":\"Kursiva\",\"strike\":\"Trastreko\",\"subscript\":\"Suba indico\",\"superscript\":\"Supra indico\",\"underline\":\"Substreko\"},\"blockquote\":{\"toolbar\":\"Citaĵo\"},\"clipboard\":{\"copy\":\"Kopii\",\"copyError\":\"La sekurecagordo de via TTT-legilo ne permesas, ke la redaktilo faras kopiajn operaciojn. Bonvolu uzi la klavaron por tio (Ctrl/Cmd-C).\",\"cut\":\"Eltondi\",\"cutError\":\"La sekurecagordo de via TTT-legilo ne permesas, ke la redaktilo faras eltondajn operaciojn. Bonvolu uzi la klavaron por tio (Ctrl/Cmd-X).\",\"paste\":\"Interglui\",\"pasteArea\":\"Intergluoareo\",\"pasteMsg\":\"Bonvolu glui la tekston en la jenan areon per uzado de la klavaro (<strong>Ctrl/Cmd+V</strong>) kaj premu OK\",\"securityMsg\":\"Pro la sekurecagordo de via TTT-legilo, la redaktilo ne povas rekte atingi viajn datenojn en la poŝo. Bonvolu denove interglui la datenojn en tiun fenestron.\",\"title\":\"Interglui\"},\"contextmenu\":{\"options\":\"Opcioj de Kunteksta Menuo\"},\"toolbar\":{\"toolbarCollapse\":\"Faldi la ilbreton\",\"toolbarExpand\":\"Malfaldi la ilbreton\",\"toolbarGroups\":{\"document\":\"Dokumento\",\"clipboard\":\"Poŝo/Malfari\",\"editing\":\"Redaktado\",\"forms\":\"Formularoj\",\"basicstyles\":\"Bazaj stiloj\",\"paragraph\":\"Paragrafo\",\"links\":\"Ligiloj\",\"insert\":\"Enmeti\",\"styles\":\"Stiloj\",\"colors\":\"Koloroj\",\"tools\":\"Iloj\"},\"toolbars\":\"Ilobretoj de la redaktilo\"},\"elementspath\":{\"eleLabel\":\"Vojo al Elementoj\",\"eleTitle\":\"%1 elementoj\"},\"format\":{\"label\":\"Formato\",\"panelTitle\":\"ParagrafFormato\",\"tag_address\":\"Adreso\",\"tag_div\":\"Normala (DIV)\",\"tag_h1\":\"Titolo 1\",\"tag_h2\":\"Titolo 2\",\"tag_h3\":\"Titolo 3\",\"tag_h4\":\"Titolo 4\",\"tag_h5\":\"Titolo 5\",\"tag_h6\":\"Titolo 6\",\"tag_p\":\"Normala\",\"tag_pre\":\"Formatita\"},\"horizontalrule\":{\"toolbar\":\"Enmeti Horizontalan Linion\"},\"image\":{\"alertUrl\":\"Bonvolu tajpi la retadreson de la bildo\",\"alt\":\"Anstataŭiga Teksto\",\"border\":\"Bordero\",\"btnUpload\":\"Sendu al Servilo\",\"button2Img\":\"Ĉu vi volas transformi la selektitan bildbutonon en simplan bildon?\",\"hSpace\":\"Horizontala Spaco\",\"img2Button\":\"Ĉu vi volas transformi la selektitan bildon en bildbutonon?\",\"infoTab\":\"Informoj pri Bildo\",\"linkTab\":\"Ligilo\",\"lockRatio\":\"Konservi Proporcion\",\"menu\":\"Atributoj de Bildo\",\"resetSize\":\"Origina Grando\",\"title\":\"Atributoj de Bildo\",\"titleButton\":\"Bildbutonaj Atributoj\",\"upload\":\"Alŝuti\",\"urlMissing\":\"La fontretadreso de la bildo mankas.\",\"vSpace\":\"Vertikala Spaco\",\"validateBorder\":\"La bordero devas esti entjera nombro.\",\"validateHSpace\":\"La horizontala spaco devas esti entjera nombro.\",\"validateVSpace\":\"La vertikala spaco devas esti entjera nombro.\"},\"indent\":{\"indent\":\"Pligrandigi Krommarĝenon\",\"outdent\":\"Malpligrandigi Krommarĝenon\"},\"fakeobjects\":{\"anchor\":\"Ankro\",\"flash\":\"FlaŝAnimacio\",\"hiddenfield\":\"Kaŝita kampo\",\"iframe\":\"Enlinia Kadro (IFrame)\",\"unknown\":\"Nekonata objekto\"},\"link\":{\"acccessKey\":\"Fulmoklavo\",\"advanced\":\"Speciala\",\"advisoryContentType\":\"Enhavotipo\",\"advisoryTitle\":\"Priskriba Titolo\",\"anchor\":{\"toolbar\":\"Ankro\",\"menu\":\"Enmeti/Ŝanĝi Ankron\",\"title\":\"Ankraj Atributoj\",\"name\":\"Ankra Nomo\",\"errorName\":\"Bv entajpi la ankran nomon\",\"remove\":\"Forigi Ankron\"},\"anchorId\":\"Per Elementidentigilo\",\"anchorName\":\"Per Ankronomo\",\"charset\":\"Signaro de la Ligita Rimedo\",\"cssClasses\":\"Klasoj de Stilfolioj\",\"emailAddress\":\"Retpoŝto\",\"emailBody\":\"Mesaĝa korpo\",\"emailSubject\":\"Mesaĝa Temo\",\"id\":\"Id\",\"info\":\"Informoj pri la Ligilo\",\"langCode\":\"Lingva Kodo\",\"langDir\":\"Skribdirekto\",\"langDirLTR\":\"De maldekstro dekstren (LTR)\",\"langDirRTL\":\"De dekstro maldekstren (RTL)\",\"menu\":\"Ŝanĝi Ligilon\",\"name\":\"Nomo\",\"noAnchors\":\"<Ne disponeblas ankroj en la dokumento>\",\"noEmail\":\"Bonvolu entajpi la retpoŝtadreson\",\"noUrl\":\"Bonvolu entajpi la URL-on\",\"other\":\"<alia>\",\"popupDependent\":\"Dependa (Netscape)\",\"popupFeatures\":\"Atributoj de la Ŝprucfenestro\",\"popupFullScreen\":\"Tutekrane (IE)\",\"popupLeft\":\"Maldekstra Pozicio\",\"popupLocationBar\":\"Adresobreto\",\"popupMenuBar\":\"Menubreto\",\"popupResizable\":\"Dimensiŝanĝebla\",\"popupScrollBars\":\"Rulumskaloj\",\"popupStatusBar\":\"Statobreto\",\"popupToolbar\":\"Ilobreto\",\"popupTop\":\"Supra Pozicio\",\"rel\":\"Rilato\",\"selectAnchor\":\"Elekti Ankron\",\"styles\":\"Stilo\",\"tabIndex\":\"Taba Indekso\",\"target\":\"Celo\",\"targetFrame\":\"<kadro>\",\"targetFrameName\":\"Nomo de CelKadro\",\"targetPopup\":\"<ŝprucfenestro>\",\"targetPopupName\":\"Nomo de Ŝprucfenestro\",\"title\":\"Ligilo\",\"toAnchor\":\"Ankri en tiu ĉi paĝo\",\"toEmail\":\"Retpoŝto\",\"toUrl\":\"URL\",\"toolbar\":\"Enmeti/Ŝanĝi Ligilon\",\"type\":\"Tipo de Ligilo\",\"unlink\":\"Forigi Ligilon\",\"upload\":\"Alŝuti\"},\"list\":{\"bulletedlist\":\"Bula Listo\",\"numberedlist\":\"Numera Listo\"},\"magicline\":{\"title\":\"Enmeti paragrafon ĉi-tien\"},\"maximize\":{\"maximize\":\"Pligrandigi\",\"minimize\":\"Malgrandigi\"},\"pastetext\":{\"button\":\"Interglui kiel platan tekston\",\"title\":\"Interglui kiel platan tekston\"},\"pastefromword\":{\"confirmCleanup\":\"La teksto, kiun vi volas interglui, ŝajnas esti kopiita el Word. Ĉu vi deziras purigi ĝin antaŭ intergluo?\",\"error\":\"Ne eblis purigi la intergluitajn datenojn pro interna eraro\",\"title\":\"Interglui el Word\",\"toolbar\":\"Interglui el Word\"},\"removeformat\":{\"toolbar\":\"Forigi Formaton\"},\"sourcearea\":{\"toolbar\":\"Fonto\"},\"specialchar\":{\"options\":\"Opcioj pri Specialaj Signoj\",\"title\":\"Selekti Specialan Signon\",\"toolbar\":\"Enmeti Specialan Signon\"},\"scayt\":{\"about\":\"Pri OKDVT\",\"aboutTab\":\"Pri\",\"addWord\":\"Almeti la vorton\",\"allCaps\":\"Ignori la vortojn skribitajn nur per ĉefliteroj\",\"dic_create\":\"Krei\",\"dic_delete\":\"Forigi\",\"dic_field_name\":\"Vortaronomo\",\"dic_info\":\"Komence la vortaro de la uzanto estas konservita en kuketo. Tamen la kuketgrando estas limigita. Kiam la vortaro de la uzanto atingas grandon, kiu ne plu ebligas konservi ĝin en kuketo, tiam la vortaro povas esti konservata en niaj serviloj. Por konservi vian personan vortaron en nian servilon, vi devas indiki nomon por tiu vortaro. Se vi jam havas konservitan vortaron, bonvolu entajpi ties nomon kaj alklaki la restaŭrbutonon.\",\"dic_rename\":\"Renomi\",\"dic_restore\":\"Restaŭri\",\"dictionariesTab\":\"Vortaroj\",\"disable\":\"Malebligi OKDVT\",\"emptyDic\":\"La vortaronomo ne devus esti malplena.\",\"enable\":\"Ebligi OKDVT\",\"ignore\":\"Ignori\",\"ignoreAll\":\"Ignori ĉion\",\"ignoreDomainNames\":\"Ignori domajnajn nomojn\",\"langs\":\"Lingvoj\",\"languagesTab\":\"Lingvoj\",\"mixedCase\":\"Ignori vortojn kun miksa uskleco\",\"mixedWithDigits\":\"Ignori vortojn kun nombroj\",\"moreSuggestions\":\"Pli da sugestoj\",\"opera_title\":\"Ne subportata de Opera\",\"options\":\"Opcioj\",\"optionsTab\":\"Opcioj\",\"title\":\"OrtografiKontrolado Dum Vi Tajpas (OKDVT)\",\"toggle\":\"Baskuligi OKDVT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stiloj\",\"panelTitle\":\"Stiloj pri enpaĝigo\",\"panelTitle1\":\"Stiloj de blokoj\",\"panelTitle2\":\"Enliniaj Stiloj\",\"panelTitle3\":\"Stiloj de objektoj\"},\"table\":{\"border\":\"Bordero\",\"caption\":\"Tabeltitolo\",\"cell\":{\"menu\":\"Ĉelo\",\"insertBefore\":\"Enmeti Ĉelon Antaŭ\",\"insertAfter\":\"Enmeti Ĉelon Post\",\"deleteCell\":\"Forigi la Ĉelojn\",\"merge\":\"Kunfandi la Ĉelojn\",\"mergeRight\":\"Kunfandi dekstren\",\"mergeDown\":\"Kunfandi malsupren \",\"splitHorizontal\":\"Horizontale dividi\",\"splitVertical\":\"Vertikale dividi\",\"title\":\"Ĉelatributoj\",\"cellType\":\"Ĉeltipo\",\"rowSpan\":\"Kunfando de linioj\",\"colSpan\":\"Kunfando de kolumnoj\",\"wordWrap\":\"Cezuro\",\"hAlign\":\"Horizontala ĝisrandigo\",\"vAlign\":\"Vertikala ĝisrandigo\",\"alignBaseline\":\"Malsupro de la teksto\",\"bgColor\":\"Fonkoloro\",\"borderColor\":\"Borderkoloro\",\"data\":\"Datenoj\",\"header\":\"Supra paĝotitolo\",\"yes\":\"Jes\",\"no\":\"No\",\"invalidWidth\":\"Ĉellarĝo devas esti nombro.\",\"invalidHeight\":\"Ĉelalto devas esti nombro.\",\"invalidRowSpan\":\"Kunfando de linioj devas esti entjera nombro.\",\"invalidColSpan\":\"Kunfando de kolumnoj devas esti entjera nombro.\",\"chooseColor\":\"Elektu\"},\"cellPad\":\"Interna Marĝeno de la ĉeloj\",\"cellSpace\":\"Spaco inter la Ĉeloj\",\"column\":{\"menu\":\"Kolumno\",\"insertBefore\":\"Enmeti kolumnon antaŭ\",\"insertAfter\":\"Enmeti kolumnon post\",\"deleteColumn\":\"Forigi Kolumnojn\"},\"columns\":\"Kolumnoj\",\"deleteTable\":\"Forigi Tabelon\",\"headers\":\"Supraj Paĝotitoloj\",\"headersBoth\":\"Ambaŭ\",\"headersColumn\":\"Unua kolumno\",\"headersNone\":\"Neniu\",\"headersRow\":\"Unua linio\",\"invalidBorder\":\"La bordergrando devas esti nombro.\",\"invalidCellPadding\":\"La interna marĝeno en la ĉeloj devas esti pozitiva nombro.\",\"invalidCellSpacing\":\"La spaco inter la ĉeloj devas esti pozitiva nombro.\",\"invalidCols\":\"La nombro de la kolumnoj devas superi 0.\",\"invalidHeight\":\"La tabelalto devas esti nombro.\",\"invalidRows\":\"La nombro de la linioj devas superi 0.\",\"invalidWidth\":\"La tabellarĝo devas esti nombro.\",\"menu\":\"Atributoj de Tabelo\",\"row\":{\"menu\":\"Linio\",\"insertBefore\":\"Enmeti linion antaŭ\",\"insertAfter\":\"Enmeti linion post\",\"deleteRow\":\"Forigi Liniojn\"},\"rows\":\"Linioj\",\"summary\":\"Resumo\",\"title\":\"Atributoj de Tabelo\",\"toolbar\":\"Tabelo\",\"widthPc\":\"elcentoj\",\"widthPx\":\"Rastrumeroj\",\"widthUnit\":\"unuo de larĝo\"},\"undo\":{\"redo\":\"Refari\",\"undo\":\"Malfari\"},\"wsc\":{\"btnIgnore\":\"Ignori\",\"btnIgnoreAll\":\"Ignori Ĉion\",\"btnReplace\":\"Anstataŭigi\",\"btnReplaceAll\":\"Anstataŭigi Ĉion\",\"btnUndo\":\"Malfari\",\"changeTo\":\"Ŝanĝi al\",\"errorLoading\":\"Eraro en la servoelŝuto el la gastiga komputiko: %s.\",\"ieSpellDownload\":\"Ortografikontrolilo ne instalita. Ĉu vi volas elŝuti ĝin nun?\",\"manyChanges\":\"Ortografikontrolado finita: %1 vortoj korektitaj\",\"noChanges\":\"Ortografikontrolado finita: neniu vorto korektita\",\"noMispell\":\"Ortografikontrolado finita: neniu eraro trovita\",\"noSuggestions\":\"- Neniu propono -\",\"notAvailable\":\"Bedaŭrinde la servo ne funkcias nuntempe.\",\"notInDic\":\"Ne trovita en la vortaro\",\"oneChange\":\"Ortografikontrolado finita: unu vorto korektita\",\"progress\":\"La ortografio estas kontrolata...\",\"title\":\"Kontroli la ortografion\",\"toolbar\":\"Kontroli la ortografion\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/es.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['es']={\"editor\":\"Editor de texto enriquecido\",\"editorPanel\":\"Panel del Editor de Texto Enriquecido\",\"common\":{\"editorHelp\":\"Pulse ALT 0 para ayuda\",\"browseServer\":\"Ver Servidor\",\"url\":\"URL\",\"protocol\":\"Protocolo\",\"upload\":\"Cargar\",\"uploadSubmit\":\"Enviar al Servidor\",\"image\":\"Imagen\",\"flash\":\"Flash\",\"form\":\"Formulario\",\"checkbox\":\"Casilla de Verificación\",\"radio\":\"Botones de Radio\",\"textField\":\"Campo de Texto\",\"textarea\":\"Area de Texto\",\"hiddenField\":\"Campo Oculto\",\"button\":\"Botón\",\"select\":\"Campo de Selección\",\"imageButton\":\"Botón Imagen\",\"notSet\":\"<No definido>\",\"id\":\"Id\",\"name\":\"Nombre\",\"langDir\":\"Orientación\",\"langDirLtr\":\"Izquierda a Derecha (LTR)\",\"langDirRtl\":\"Derecha a Izquierda (RTL)\",\"langCode\":\"Cód. de idioma\",\"longDescr\":\"Descripción larga URL\",\"cssClass\":\"Clases de hojas de estilo\",\"advisoryTitle\":\"Título\",\"cssStyle\":\"Estilo\",\"ok\":\"Aceptar\",\"cancel\":\"Cancelar\",\"close\":\"Cerrar\",\"preview\":\"Previsualización\",\"resize\":\"Arrastre para redimensionar\",\"generalTab\":\"General\",\"advancedTab\":\"Avanzado\",\"validateNumberFailed\":\"El valor no es un número.\",\"confirmNewPage\":\"Cualquier cambio que no se haya guardado se perderá.\\r\\n¿Está seguro de querer crear una nueva página?\",\"confirmCancel\":\"Algunas de las opciones se han cambiado.\\r\\n¿Está seguro de querer cerrar el diálogo?\",\"options\":\"Opciones\",\"target\":\"Destino\",\"targetNew\":\"Nueva ventana (_blank)\",\"targetTop\":\"Ventana principal (_top)\",\"targetSelf\":\"Misma ventana (_self)\",\"targetParent\":\"Ventana padre (_parent)\",\"langDirLTR\":\"Izquierda a derecha (LTR)\",\"langDirRTL\":\"Derecha a izquierda (RTL)\",\"styles\":\"Estilos\",\"cssClasses\":\"Clase de la hoja de estilos\",\"width\":\"Anchura\",\"height\":\"Altura\",\"align\":\"Alineación\",\"alignLeft\":\"Izquierda\",\"alignRight\":\"Derecha\",\"alignCenter\":\"Centrado\",\"alignTop\":\"Tope\",\"alignMiddle\":\"Centro\",\"alignBottom\":\"Pie\",\"invalidValue\":\"Valor no válido\",\"invalidHeight\":\"Altura debe ser un número.\",\"invalidWidth\":\"Anchura debe ser un número.\",\"invalidCssLength\":\"El valor especificado para el campo \\\"%1\\\" debe ser un número positivo, incluyendo optionalmente una unidad de medida CSS válida (px, %, in, cm, mm, em, ex, pt, o pc).\",\"invalidHtmlLength\":\"El valor especificado para el campo \\\"%1\\\" debe ser un número positivo, incluyendo optionalmente una unidad de medida HTML válida (px o %).\",\"invalidInlineStyle\":\"El valor especificado para el estilo debe consistir en uno o más pares con el formato \\\"nombre: valor\\\", separados por punto y coma.\",\"cssLengthTooltip\":\"Introduca un número para el valor en pixels o un número con una unidad de medida CSS válida (px, %, in, cm, mm, em, ex, pt, o pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, no disponible</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Todos los derechos reservados.\",\"dlgTitle\":\"Acerca de CKEditor\",\"help\":\"Lea la  $1 para resolver sus dudas.\",\"moreInfo\":\"Para información de licencia, por favor visite nuestro sitio web:\",\"title\":\"Acerca de CKEditor\",\"userGuide\":\"Guía de usuario de CKEditor\"},\"basicstyles\":{\"bold\":\"Negrita\",\"italic\":\"Cursiva\",\"strike\":\"Tachado\",\"subscript\":\"Subíndice\",\"superscript\":\"Superíndice\",\"underline\":\"Subrayado\"},\"blockquote\":{\"toolbar\":\"Cita\"},\"clipboard\":{\"copy\":\"Copiar\",\"copyError\":\"La configuración de seguridad de este navegador no permite la ejecución automática de operaciones de copiado.\\r\\nPor favor use el teclado (Ctrl/Cmd+C).\",\"cut\":\"Cortar\",\"cutError\":\"La configuración de seguridad de este navegador no permite la ejecución automática de operaciones de cortado.\\r\\nPor favor use el teclado (Ctrl/Cmd+X).\",\"paste\":\"Pegar\",\"pasteArea\":\"Zona de pegado\",\"pasteMsg\":\"Por favor pegue dentro del cuadro utilizando el teclado (<STRONG>Ctrl/Cmd+V</STRONG>);\\r\\nluego presione <STRONG>Aceptar</STRONG>.\",\"securityMsg\":\"Debido a la configuración de seguridad de su navegador, el editor no tiene acceso al portapapeles.\\r\\nEs necesario que lo pegue de nuevo en esta ventana.\",\"title\":\"Pegar\"},\"contextmenu\":{\"options\":\"Opciones del menú contextual\"},\"toolbar\":{\"toolbarCollapse\":\"Contraer barra de herramientas\",\"toolbarExpand\":\"Expandir barra de herramientas\",\"toolbarGroups\":{\"document\":\"Documento\",\"clipboard\":\"Portapapeles/Deshacer\",\"editing\":\"Edición\",\"forms\":\"Formularios\",\"basicstyles\":\"Estilos básicos\",\"paragraph\":\"Párrafo\",\"links\":\"Enlaces\",\"insert\":\"Insertar\",\"styles\":\"Estilos\",\"colors\":\"Colores\",\"tools\":\"Herramientas\"},\"toolbars\":\"Barras de herramientas del editor\"},\"elementspath\":{\"eleLabel\":\"Ruta de los elementos\",\"eleTitle\":\"%1 elemento\"},\"format\":{\"label\":\"Formato\",\"panelTitle\":\"Formato\",\"tag_address\":\"Dirección\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Encabezado 1\",\"tag_h2\":\"Encabezado 2\",\"tag_h3\":\"Encabezado 3\",\"tag_h4\":\"Encabezado 4\",\"tag_h5\":\"Encabezado 5\",\"tag_h6\":\"Encabezado 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Con formato\"},\"horizontalrule\":{\"toolbar\":\"Insertar Línea Horizontal\"},\"image\":{\"alertUrl\":\"Por favor escriba la URL de la imagen\",\"alt\":\"Texto Alternativo\",\"border\":\"Borde\",\"btnUpload\":\"Enviar al Servidor\",\"button2Img\":\"¿Desea convertir el botón de imagen en una simple imagen?\",\"hSpace\":\"Esp.Horiz\",\"img2Button\":\"¿Desea convertir la imagen en un botón de imagen?\",\"infoTab\":\"Información de Imagen\",\"linkTab\":\"Vínculo\",\"lockRatio\":\"Proporcional\",\"menu\":\"Propiedades de Imagen\",\"resetSize\":\"Tamaño Original\",\"title\":\"Propiedades de Imagen\",\"titleButton\":\"Propiedades de Botón de Imagen\",\"upload\":\"Cargar\",\"urlMissing\":\"Debe indicar la URL de la imagen.\",\"vSpace\":\"Esp.Vert\",\"validateBorder\":\"El borde debe ser un número.\",\"validateHSpace\":\"El espaciado horizontal debe ser un número.\",\"validateVSpace\":\"El espaciado vertical debe ser un número.\"},\"indent\":{\"indent\":\"Aumentar Sangría\",\"outdent\":\"Disminuir Sangría\"},\"fakeobjects\":{\"anchor\":\"Ancla\",\"flash\":\"Animación flash\",\"hiddenfield\":\"Campo oculto\",\"iframe\":\"IFrame\",\"unknown\":\"Objeto desconocido\"},\"link\":{\"acccessKey\":\"Tecla de Acceso\",\"advanced\":\"Avanzado\",\"advisoryContentType\":\"Tipo de Contenido\",\"advisoryTitle\":\"Título\",\"anchor\":{\"toolbar\":\"Referencia\",\"menu\":\"Propiedades de Referencia\",\"title\":\"Propiedades de Referencia\",\"name\":\"Nombre de la Referencia\",\"errorName\":\"Por favor, complete el nombre de la Referencia\",\"remove\":\"Quitar Referencia\"},\"anchorId\":\"Por ID de elemento\",\"anchorName\":\"Por Nombre de Referencia\",\"charset\":\"Fuente de caracteres vinculado\",\"cssClasses\":\"Clases de hojas de estilo\",\"emailAddress\":\"Dirección de E-Mail\",\"emailBody\":\"Cuerpo del Mensaje\",\"emailSubject\":\"Título del Mensaje\",\"id\":\"Id\",\"info\":\"Información de Vínculo\",\"langCode\":\"Código idioma\",\"langDir\":\"Orientación\",\"langDirLTR\":\"Izquierda a Derecha (LTR)\",\"langDirRTL\":\"Derecha a Izquierda (RTL)\",\"menu\":\"Editar Vínculo\",\"name\":\"Nombre\",\"noAnchors\":\"(No hay referencias disponibles en el documento)\",\"noEmail\":\"Por favor escriba la dirección de e-mail\",\"noUrl\":\"Por favor escriba el vínculo URL\",\"other\":\"<otro>\",\"popupDependent\":\"Dependiente (Netscape)\",\"popupFeatures\":\"Características de Ventana Emergente\",\"popupFullScreen\":\"Pantalla Completa (IE)\",\"popupLeft\":\"Posición Izquierda\",\"popupLocationBar\":\"Barra de ubicación\",\"popupMenuBar\":\"Barra de Menú\",\"popupResizable\":\"Redimensionable\",\"popupScrollBars\":\"Barras de desplazamiento\",\"popupStatusBar\":\"Barra de Estado\",\"popupToolbar\":\"Barra de Herramientas\",\"popupTop\":\"Posición Derecha\",\"rel\":\"Relación\",\"selectAnchor\":\"Seleccionar una referencia\",\"styles\":\"Estilo\",\"tabIndex\":\"Indice de tabulación\",\"target\":\"Destino\",\"targetFrame\":\"<marco>\",\"targetFrameName\":\"Nombre del Marco Destino\",\"targetPopup\":\"<ventana emergente>\",\"targetPopupName\":\"Nombre de Ventana Emergente\",\"title\":\"Vínculo\",\"toAnchor\":\"Referencia en esta página\",\"toEmail\":\"E-Mail\",\"toUrl\":\"URL\",\"toolbar\":\"Insertar/Editar Vínculo\",\"type\":\"Tipo de vínculo\",\"unlink\":\"Eliminar Vínculo\",\"upload\":\"Cargar\"},\"list\":{\"bulletedlist\":\"Viñetas\",\"numberedlist\":\"Numeración\"},\"magicline\":{\"title\":\"Insertar párrafo aquí\"},\"maximize\":{\"maximize\":\"Maximizar\",\"minimize\":\"Minimizar\"},\"pastetext\":{\"button\":\"Pegar como Texto Plano\",\"title\":\"Pegar como Texto Plano\"},\"pastefromword\":{\"confirmCleanup\":\"El texto que desea parece provenir de Word.\\r\\n¿Desea depurarlo antes de pegarlo?\",\"error\":\"No ha sido posible limpiar los datos debido a un error interno\",\"title\":\"Pegar desde Word\",\"toolbar\":\"Pegar desde Word\"},\"removeformat\":{\"toolbar\":\"Eliminar Formato\"},\"sourcearea\":{\"toolbar\":\"Fuente HTML\"},\"specialchar\":{\"options\":\"Opciones de caracteres especiales\",\"title\":\"Seleccione un caracter especial\",\"toolbar\":\"Insertar Caracter Especial\"},\"scayt\":{\"about\":\"Acerca de Corrector\",\"aboutTab\":\"Acerca de\",\"addWord\":\"Añadir palabra\",\"allCaps\":\"Omitir palabras en MAYÚSCULAS\",\"dic_create\":\"Crear\",\"dic_delete\":\"Borrar\",\"dic_field_name\":\"Nombre del diccionario\",\"dic_info\":\"Inicialmente el Diccionario de usuario se guarda en una Cookie. Sin embargo, las cookies están limitadas en tamaño. Cuando el diccionario crece a un punto en el que no se puede guardar en una Cookie, el diccionario puede ser almacenado en nuestro servidor. Para almacenar su diccionario personalizado en nuestro servidor debe especificar un nombre para su diccionario. Si ya ha guardado un diccionaro, por favor, escriba su nombre y pulse el botón Recuperar\",\"dic_rename\":\"Renombrar\",\"dic_restore\":\"Recuperar\",\"dictionariesTab\":\"Diccionarios\",\"disable\":\"Desactivar Corrector\",\"emptyDic\":\"El nombre del diccionario no puede estar en blanco.\",\"enable\":\"Activar Corrector\",\"ignore\":\"Ignorar\",\"ignoreAll\":\"Ignorar Todas\",\"ignoreDomainNames\":\"Omitir nombres de dominio\",\"langs\":\"Idiomas\",\"languagesTab\":\"Idiomas\",\"mixedCase\":\"Ignorar palabras con combinación de mayúsculas y minúsculas\",\"mixedWithDigits\":\"Omitir palabras con números\",\"moreSuggestions\":\"Más sugerencias\",\"opera_title\":\"No soportado en Opera\",\"options\":\"Opciones\",\"optionsTab\":\"Opciones\",\"title\":\"Comprobar Ortografía Mientras Escribe\",\"toggle\":\"Cambiar Corrector\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Estilo\",\"panelTitle\":\"Estilos para formatear\",\"panelTitle1\":\"Estilos de párrafo\",\"panelTitle2\":\"Estilos de carácter\",\"panelTitle3\":\"Estilos de objeto\"},\"table\":{\"border\":\"Tamaño de Borde\",\"caption\":\"Título\",\"cell\":{\"menu\":\"Celda\",\"insertBefore\":\"Insertar celda a la izquierda\",\"insertAfter\":\"Insertar celda a la derecha\",\"deleteCell\":\"Eliminar Celdas\",\"merge\":\"Combinar Celdas\",\"mergeRight\":\"Combinar a la derecha\",\"mergeDown\":\"Combinar hacia abajo\",\"splitHorizontal\":\"Dividir la celda horizontalmente\",\"splitVertical\":\"Dividir la celda verticalmente\",\"title\":\"Propiedades de celda\",\"cellType\":\"Tipo de Celda\",\"rowSpan\":\"Expandir filas\",\"colSpan\":\"Expandir columnas\",\"wordWrap\":\"Ajustar al contenido\",\"hAlign\":\"Alineación Horizontal\",\"vAlign\":\"Alineación Vertical\",\"alignBaseline\":\"Linea de base\",\"bgColor\":\"Color de fondo\",\"borderColor\":\"Color de borde\",\"data\":\"Datos\",\"header\":\"Encabezado\",\"yes\":\"Sí\",\"no\":\"No\",\"invalidWidth\":\"La anchura de celda debe ser un número.\",\"invalidHeight\":\"La altura de celda debe ser un número.\",\"invalidRowSpan\":\"La expansión de filas debe ser un número entero.\",\"invalidColSpan\":\"La expansión de columnas debe ser un número entero.\",\"chooseColor\":\"Elegir\"},\"cellPad\":\"Esp. interior\",\"cellSpace\":\"Esp. e/celdas\",\"column\":{\"menu\":\"Columna\",\"insertBefore\":\"Insertar columna a la izquierda\",\"insertAfter\":\"Insertar columna a la derecha\",\"deleteColumn\":\"Eliminar Columnas\"},\"columns\":\"Columnas\",\"deleteTable\":\"Eliminar Tabla\",\"headers\":\"Encabezados\",\"headersBoth\":\"Ambas\",\"headersColumn\":\"Primera columna\",\"headersNone\":\"Ninguno\",\"headersRow\":\"Primera fila\",\"invalidBorder\":\"El tamaño del borde debe ser un número.\",\"invalidCellPadding\":\"El espaciado interior debe ser un número.\",\"invalidCellSpacing\":\"El espaciado entre celdas debe ser un número.\",\"invalidCols\":\"El número de columnas debe ser un número mayor que 0.\",\"invalidHeight\":\"La altura de tabla debe ser un número.\",\"invalidRows\":\"El número de filas debe ser un número mayor que 0.\",\"invalidWidth\":\"La anchura de tabla debe ser un número.\",\"menu\":\"Propiedades de Tabla\",\"row\":{\"menu\":\"Fila\",\"insertBefore\":\"Insertar fila en la parte superior\",\"insertAfter\":\"Insertar fila en la parte inferior\",\"deleteRow\":\"Eliminar Filas\"},\"rows\":\"Filas\",\"summary\":\"Síntesis\",\"title\":\"Propiedades de Tabla\",\"toolbar\":\"Tabla\",\"widthPc\":\"porcentaje\",\"widthPx\":\"pixeles\",\"widthUnit\":\"unidad de la anchura\"},\"undo\":{\"redo\":\"Rehacer\",\"undo\":\"Deshacer\"},\"wsc\":{\"btnIgnore\":\"Ignorar\",\"btnIgnoreAll\":\"Ignorar Todo\",\"btnReplace\":\"Reemplazar\",\"btnReplaceAll\":\"Reemplazar Todo\",\"btnUndo\":\"Deshacer\",\"changeTo\":\"Cambiar a\",\"errorLoading\":\"Error cargando la aplicación del servidor: %s.\",\"ieSpellDownload\":\"Módulo de Control de Ortografía no instalado.\\r\\n¿Desea descargarlo ahora?\",\"manyChanges\":\"Control finalizado: se ha cambiado %1 palabras\",\"noChanges\":\"Control finalizado: no se ha cambiado ninguna palabra\",\"noMispell\":\"Control finalizado: no se encontraron errores\",\"noSuggestions\":\"- No hay sugerencias -\",\"notAvailable\":\"Lo sentimos pero el servicio no está disponible.\",\"notInDic\":\"No se encuentra en el Diccionario\",\"oneChange\":\"Control finalizado: se ha cambiado una palabra\",\"progress\":\"Control de Ortografía en progreso...\",\"title\":\"Comprobar ortografía\",\"toolbar\":\"Ortografía\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/et.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['et']={\"editor\":\"Rikkalik tekstiredaktor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Abi saamiseks vajuta ALT 0\",\"browseServer\":\"Serveri sirvimine\",\"url\":\"URL\",\"protocol\":\"Protokoll\",\"upload\":\"Laadi üles\",\"uploadSubmit\":\"Saada serverisse\",\"image\":\"Pilt\",\"flash\":\"Flash\",\"form\":\"Vorm\",\"checkbox\":\"Märkeruut\",\"radio\":\"Raadionupp\",\"textField\":\"Tekstilahter\",\"textarea\":\"Tekstiala\",\"hiddenField\":\"Varjatud lahter\",\"button\":\"Nupp\",\"select\":\"Valiklahter\",\"imageButton\":\"Piltnupp\",\"notSet\":\"<määramata>\",\"id\":\"ID\",\"name\":\"Nimi\",\"langDir\":\"Keele suund\",\"langDirLtr\":\"Vasakult paremale (LTR)\",\"langDirRtl\":\"Paremalt vasakule (RTL)\",\"langCode\":\"Keele kood\",\"longDescr\":\"Pikk kirjeldus URL\",\"cssClass\":\"Stiilistiku klassid\",\"advisoryTitle\":\"Soovituslik pealkiri\",\"cssStyle\":\"Laad\",\"ok\":\"OK\",\"cancel\":\"Loobu\",\"close\":\"Sulge\",\"preview\":\"Eelvaade\",\"resize\":\"Suuruse muutmiseks lohista\",\"generalTab\":\"Üldine\",\"advancedTab\":\"Täpsemalt\",\"validateNumberFailed\":\"See väärtus pole number.\",\"confirmNewPage\":\"Kõik salvestamata muudatused lähevad kaotsi. Kas oled kindel, et tahad laadida uue lehe?\",\"confirmCancel\":\"Mõned valikud on muudetud. Kas oled kindel, et tahad dialoogi sulgeda?\",\"options\":\"Valikud\",\"target\":\"Sihtkoht\",\"targetNew\":\"Uus aken (_blank)\",\"targetTop\":\"Kõige ülemine aken (_top)\",\"targetSelf\":\"Sama aken (_self)\",\"targetParent\":\"Vanemaken (_parent)\",\"langDirLTR\":\"Vasakult paremale (LTR)\",\"langDirRTL\":\"Paremalt vasakule (RTL)\",\"styles\":\"Stiili\",\"cssClasses\":\"Stiililehe klassid\",\"width\":\"Laius\",\"height\":\"Kõrgus\",\"align\":\"Joondus\",\"alignLeft\":\"Vasak\",\"alignRight\":\"Paremale\",\"alignCenter\":\"Kesk\",\"alignTop\":\"Üles\",\"alignMiddle\":\"Keskele\",\"alignBottom\":\"Alla\",\"invalidValue\":\"Vigane väärtus.\",\"invalidHeight\":\"Kõrgus peab olema number.\",\"invalidWidth\":\"Laius peab olema number.\",\"invalidCssLength\":\"\\\"%1\\\" välja jaoks määratud väärtus peab olema positiivne täisarv CSS ühikuga (px, %, in, cm, mm, em, ex, pt või pc) või ilma.\",\"invalidHtmlLength\":\"\\\"%1\\\" välja jaoks määratud väärtus peab olema positiivne täisarv HTML ühikuga (px või %) või ilma.\",\"invalidInlineStyle\":\"Reasisese stiili määrangud peavad koosnema paarisväärtustest (tuples), mis on semikoolonitega eraldatult järgnevas vormingus: \\\"nimi : väärtus\\\".\",\"cssLengthTooltip\":\"Sisesta väärtus pikslites või number koos sobiva CSS-i ühikuga (px, %, in, cm, mm, em, ex, pt või pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, pole saadaval</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Kõik õigused kaitstud.\",\"dlgTitle\":\"CKEditorist\",\"help\":\"Abi jaoks vaata $1.\",\"moreInfo\":\"Litsentsi andmed leiab meie veebilehelt:\",\"title\":\"CKEditorist\",\"userGuide\":\"CKEditori kasutusjuhendit\"},\"basicstyles\":{\"bold\":\"Paks\",\"italic\":\"Kursiiv\",\"strike\":\"Läbijoonitud\",\"subscript\":\"Allindeks\",\"superscript\":\"Ülaindeks\",\"underline\":\"Allajoonitud\"},\"blockquote\":{\"toolbar\":\"Blokktsitaat\"},\"clipboard\":{\"copy\":\"Kopeeri\",\"copyError\":\"Sinu veebisirvija turvaseaded ei luba redaktoril automaatselt kopeerida. Palun kasutage selleks klaviatuuri klahvikombinatsiooni (Ctrl/Cmd+C).\",\"cut\":\"Lõika\",\"cutError\":\"Sinu veebisirvija turvaseaded ei luba redaktoril automaatselt lõigata. Palun kasutage selleks klaviatuuri klahvikombinatsiooni (Ctrl/Cmd+X).\",\"paste\":\"Aseta\",\"pasteArea\":\"Asetamise ala\",\"pasteMsg\":\"Palun aseta tekst järgnevasse kasti kasutades klaviatuuri klahvikombinatsiooni (<STRONG>Ctrl/Cmd+V</STRONG>) ja vajuta seejärel <STRONG>OK</STRONG>.\",\"securityMsg\":\"Sinu veebisirvija turvaseadete tõttu ei oma redaktor otsest ligipääsu lõikelaua andmetele. Sa pead asetama need uuesti siia aknasse.\",\"title\":\"Asetamine\"},\"contextmenu\":{\"options\":\"Kontekstimenüü valikud\"},\"toolbar\":{\"toolbarCollapse\":\"Tööriistariba peitmine\",\"toolbarExpand\":\"Tööriistariba näitamine\",\"toolbarGroups\":{\"document\":\"Dokument\",\"clipboard\":\"Lõikelaud/tagasivõtmine\",\"editing\":\"Muutmine\",\"forms\":\"Vormid\",\"basicstyles\":\"Põhistiilid\",\"paragraph\":\"Lõik\",\"links\":\"Lingid\",\"insert\":\"Sisesta\",\"styles\":\"Stiilid\",\"colors\":\"Värvid\",\"tools\":\"Tööriistad\"},\"toolbars\":\"Redaktori tööriistaribad\"},\"elementspath\":{\"eleLabel\":\"Elementide asukoht\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Vorming\",\"panelTitle\":\"Vorming\",\"tag_address\":\"Aadress\",\"tag_div\":\"Tavaline (DIV)\",\"tag_h1\":\"Pealkiri 1\",\"tag_h2\":\"Pealkiri 2\",\"tag_h3\":\"Pealkiri 3\",\"tag_h4\":\"Pealkiri 4\",\"tag_h5\":\"Pealkiri 5\",\"tag_h6\":\"Pealkiri 6\",\"tag_p\":\"Tavaline\",\"tag_pre\":\"Vormindatud\"},\"horizontalrule\":{\"toolbar\":\"Horisontaaljoone sisestamine\"},\"image\":{\"alertUrl\":\"Palun kirjuta pildi URL\",\"alt\":\"Alternatiivne tekst\",\"border\":\"Joon\",\"btnUpload\":\"Saada serverisse\",\"button2Img\":\"Kas tahad teisendada valitud pildiga nupu tavaliseks pildiks?\",\"hSpace\":\"H. vaheruum\",\"img2Button\":\"Kas tahad teisendada valitud tavalise pildi pildiga nupuks?\",\"infoTab\":\"Pildi info\",\"linkTab\":\"Link\",\"lockRatio\":\"Lukusta kuvasuhe\",\"menu\":\"Pildi omadused\",\"resetSize\":\"Lähtesta suurus\",\"title\":\"Pildi omadused\",\"titleButton\":\"Piltnupu omadused\",\"upload\":\"Lae üles\",\"urlMissing\":\"Pildi lähte-URL on puudu.\",\"vSpace\":\"V. vaheruum\",\"validateBorder\":\"Äärise laius peab olema täisarv.\",\"validateHSpace\":\"Horisontaalne vaheruum peab olema täisarv.\",\"validateVSpace\":\"Vertikaalne vaheruum peab olema täisarv.\"},\"indent\":{\"indent\":\"Taande suurendamine\",\"outdent\":\"Taande vähendamine\"},\"fakeobjects\":{\"anchor\":\"Ankur\",\"flash\":\"Flashi animatsioon\",\"hiddenfield\":\"Varjatud väli\",\"iframe\":\"IFrame\",\"unknown\":\"Tundmatu objekt\"},\"link\":{\"acccessKey\":\"Juurdepääsu võti\",\"advanced\":\"Täpsemalt\",\"advisoryContentType\":\"Juhendava sisu tüüp\",\"advisoryTitle\":\"Juhendav tiitel\",\"anchor\":{\"toolbar\":\"Ankru sisestamine/muutmine\",\"menu\":\"Ankru omadused\",\"title\":\"Ankru omadused\",\"name\":\"Ankru nimi\",\"errorName\":\"Palun sisesta ankru nimi\",\"remove\":\"Eemalda ankur\"},\"anchorId\":\"Elemendi id järgi\",\"anchorName\":\"Ankru nime järgi\",\"charset\":\"Lingitud ressursi märgistik\",\"cssClasses\":\"Stiilistiku klassid\",\"emailAddress\":\"E-posti aadress\",\"emailBody\":\"Sõnumi tekst\",\"emailSubject\":\"Sõnumi teema\",\"id\":\"ID\",\"info\":\"Lingi info\",\"langCode\":\"Keele suund\",\"langDir\":\"Keele suund\",\"langDirLTR\":\"Vasakult paremale (LTR)\",\"langDirRTL\":\"Paremalt vasakule (RTL)\",\"menu\":\"Muuda linki\",\"name\":\"Nimi\",\"noAnchors\":\"(Selles dokumendis pole ankruid)\",\"noEmail\":\"Palun kirjuta e-posti aadress\",\"noUrl\":\"Palun kirjuta lingi URL\",\"other\":\"<muu>\",\"popupDependent\":\"Sõltuv (Netscape)\",\"popupFeatures\":\"Hüpikakna omadused\",\"popupFullScreen\":\"Täisekraan (IE)\",\"popupLeft\":\"Vasak asukoht\",\"popupLocationBar\":\"Aadressiriba\",\"popupMenuBar\":\"Menüüriba\",\"popupResizable\":\"Suurust saab muuta\",\"popupScrollBars\":\"Kerimisribad\",\"popupStatusBar\":\"Olekuriba\",\"popupToolbar\":\"Tööriistariba\",\"popupTop\":\"Ülemine asukoht\",\"rel\":\"Suhe\",\"selectAnchor\":\"Vali ankur\",\"styles\":\"Laad\",\"tabIndex\":\"Tab indeks\",\"target\":\"Sihtkoht\",\"targetFrame\":\"<raam>\",\"targetFrameName\":\"Sihtmärk raami nimi\",\"targetPopup\":\"<hüpikaken>\",\"targetPopupName\":\"Hüpikakna nimi\",\"title\":\"Link\",\"toAnchor\":\"Ankur sellel lehel\",\"toEmail\":\"E-post\",\"toUrl\":\"URL\",\"toolbar\":\"Lingi lisamine/muutmine\",\"type\":\"Lingi liik\",\"unlink\":\"Lingi eemaldamine\",\"upload\":\"Lae üles\"},\"list\":{\"bulletedlist\":\"Punktloend\",\"numberedlist\":\"Numberloend\"},\"magicline\":{\"title\":\"Sisesta siia lõigu tekst\"},\"maximize\":{\"maximize\":\"Maksimeerimine\",\"minimize\":\"Minimeerimine\"},\"pastetext\":{\"button\":\"Asetamine tavalise tekstina\",\"title\":\"Asetamine tavalise tekstina\"},\"pastefromword\":{\"confirmCleanup\":\"Tekst, mida tahad asetada näib pärinevat Wordist. Kas tahad selle enne asetamist puhastada?\",\"error\":\"Asetatud andmete puhastamine ei olnud sisemise vea tõttu võimalik\",\"title\":\"Asetamine Wordist\",\"toolbar\":\"Asetamine Wordist\"},\"removeformat\":{\"toolbar\":\"Vormingu eemaldamine\"},\"sourcearea\":{\"toolbar\":\"Lähtekood\"},\"specialchar\":{\"options\":\"Erimärkide valikud\",\"title\":\"Erimärgi valimine\",\"toolbar\":\"Erimärgi sisestamine\"},\"scayt\":{\"about\":\"SCAYT-ist lähemalt\",\"aboutTab\":\"Lähemalt\",\"addWord\":\"Lisa sõna\",\"allCaps\":\"Läbivate suurtähtedega sõnade eiramine\",\"dic_create\":\"Loo\",\"dic_delete\":\"Kustuta\",\"dic_field_name\":\"Sõnaraamatu nimi\",\"dic_info\":\"Alguses säilitatakse kasutaja sõnaraamatut küpsises. Küpsise suurus on piiratud. Pärast sõnaraamatu kasvamist nii suureks, et see küpsisesse ei mahu, võib sõnaraamatut hoida meie serveris. Oma isikliku sõnaraamatu hoidmiseks meie serveris pead andma sellele nime. Kui sa juba oled sõnaraamatu salvestanud, sisesta selle nimi ja klõpsa taastamise nupule.\",\"dic_rename\":\"Nimeta ümber\",\"dic_restore\":\"Taasta\",\"dictionariesTab\":\"Sõnaraamatud\",\"disable\":\"SCAYT keelatud\",\"emptyDic\":\"Sõnaraamatu nimi ei tohi olla tühi.\",\"enable\":\"SCAYT lubatud\",\"ignore\":\"Eira\",\"ignoreAll\":\"Eira kõiki\",\"ignoreDomainNames\":\"Domeeninimede eiramine\",\"langs\":\"Keeled\",\"languagesTab\":\"Keeled\",\"mixedCase\":\"Tavapäratu tõstuga sõnade eiramine\",\"mixedWithDigits\":\"Numbreid sisaldavate sõnade eiramine\",\"moreSuggestions\":\"Veel soovitusi\",\"opera_title\":\"Operas pole toetatud\",\"options\":\"Valikud\",\"optionsTab\":\"Valikud\",\"title\":\"Õigekirjakontroll kirjutamise ajal\",\"toggle\":\"SCAYT sisse/välja lülitamine\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stiil\",\"panelTitle\":\"Vormindusstiilid\",\"panelTitle1\":\"Blokkstiilid\",\"panelTitle2\":\"Reasisesed stiilid\",\"panelTitle3\":\"Objektistiilid\"},\"table\":{\"border\":\"Joone suurus\",\"caption\":\"Tabeli tiitel\",\"cell\":{\"menu\":\"Lahter\",\"insertBefore\":\"Sisesta lahter enne\",\"insertAfter\":\"Sisesta lahter peale\",\"deleteCell\":\"Eemalda lahtrid\",\"merge\":\"Ühenda lahtrid\",\"mergeRight\":\"Ühenda paremale\",\"mergeDown\":\"Ühenda alla\",\"splitHorizontal\":\"Poolita lahter horisontaalselt\",\"splitVertical\":\"Poolita lahter vertikaalselt\",\"title\":\"Lahtri omadused\",\"cellType\":\"Lahtri liik\",\"rowSpan\":\"Ridade vahe\",\"colSpan\":\"Tulpade vahe\",\"wordWrap\":\"Sõnade murdmine\",\"hAlign\":\"Horisontaalne joondus\",\"vAlign\":\"Vertikaalne joondus\",\"alignBaseline\":\"Baasjoon\",\"bgColor\":\"Tausta värv\",\"borderColor\":\"Äärise värv\",\"data\":\"Andmed\",\"header\":\"Päis\",\"yes\":\"Jah\",\"no\":\"Ei\",\"invalidWidth\":\"Lahtri laius peab olema number.\",\"invalidHeight\":\"Lahtri kõrgus peab olema number.\",\"invalidRowSpan\":\"Ridade vahe peab olema täisarv.\",\"invalidColSpan\":\"Tulpade vahe peab olema täisarv.\",\"chooseColor\":\"Vali\"},\"cellPad\":\"Lahtri täidis\",\"cellSpace\":\"Lahtri vahe\",\"column\":{\"menu\":\"Veerg\",\"insertBefore\":\"Sisesta veerg enne\",\"insertAfter\":\"Sisesta veerg peale\",\"deleteColumn\":\"Eemalda veerud\"},\"columns\":\"Veerud\",\"deleteTable\":\"Kustuta tabel\",\"headers\":\"Päised\",\"headersBoth\":\"Mõlemad\",\"headersColumn\":\"Esimene tulp\",\"headersNone\":\"Puudub\",\"headersRow\":\"Esimene rida\",\"invalidBorder\":\"Äärise suurus peab olema number.\",\"invalidCellPadding\":\"Lahtrite polsterdus (padding) peab olema positiivne arv.\",\"invalidCellSpacing\":\"Lahtrite vahe peab olema positiivne arv.\",\"invalidCols\":\"Tulpade arv peab olema nullist suurem.\",\"invalidHeight\":\"Tabeli kõrgus peab olema number.\",\"invalidRows\":\"Ridade arv peab olema nullist suurem.\",\"invalidWidth\":\"Tabeli laius peab olema number.\",\"menu\":\"Tabeli omadused\",\"row\":{\"menu\":\"Rida\",\"insertBefore\":\"Sisesta rida enne\",\"insertAfter\":\"Sisesta rida peale\",\"deleteRow\":\"Eemalda read\"},\"rows\":\"Read\",\"summary\":\"Kokkuvõte\",\"title\":\"Tabeli omadused\",\"toolbar\":\"Tabel\",\"widthPc\":\"protsenti\",\"widthPx\":\"pikslit\",\"widthUnit\":\"laiuse ühik\"},\"undo\":{\"redo\":\"Toimingu kordamine\",\"undo\":\"Tagasivõtmine\"},\"wsc\":{\"btnIgnore\":\"Ignoreeri\",\"btnIgnoreAll\":\"Ignoreeri kõiki\",\"btnReplace\":\"Asenda\",\"btnReplaceAll\":\"Asenda kõik\",\"btnUndo\":\"Võta tagasi\",\"changeTo\":\"Muuda\",\"errorLoading\":\"Viga rakenduse teenushosti laadimisel: %s.\",\"ieSpellDownload\":\"Õigekirja kontrollija ei ole paigaldatud. Soovid sa selle alla laadida?\",\"manyChanges\":\"Õigekirja kontroll sooritatud: %1 sõna muudetud\",\"noChanges\":\"Õigekirja kontroll sooritatud: ühtegi sõna ei muudetud\",\"noMispell\":\"Õigekirja kontroll sooritatud: õigekirjuvigu ei leitud\",\"noSuggestions\":\"- Soovitused puuduvad -\",\"notAvailable\":\"Kahjuks ei ole teenus praegu saadaval.\",\"notInDic\":\"Puudub sõnastikust\",\"oneChange\":\"Õigekirja kontroll sooritatud: üks sõna muudeti\",\"progress\":\"Toimub õigekirja kontroll...\",\"title\":\"Õigekirjakontroll\",\"toolbar\":\"Õigekirjakontroll\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/eu.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['eu']={\"editor\":\"Testu Aberastuko Editorea\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"ALT 0 sakatu laguntza jasotzeko\",\"browseServer\":\"Zerbitzaria arakatu\",\"url\":\"URL\",\"protocol\":\"Protokoloa\",\"upload\":\"Gora kargatu\",\"uploadSubmit\":\"Zerbitzarira bidali\",\"image\":\"Irudia\",\"flash\":\"Flasha\",\"form\":\"Formularioa\",\"checkbox\":\"Kontrol-laukia\",\"radio\":\"Aukera-botoia\",\"textField\":\"Testu Eremua\",\"textarea\":\"Testu-area\",\"hiddenField\":\"Ezkutuko Eremua\",\"button\":\"Botoia\",\"select\":\"Hautespen Eremua\",\"imageButton\":\"Irudi Botoia\",\"notSet\":\"<Ezarri gabe>\",\"id\":\"Id\",\"name\":\"Izena\",\"langDir\":\"Hizkuntzaren Norabidea\",\"langDirLtr\":\"Ezkerretik Eskumara(LTR)\",\"langDirRtl\":\"Eskumatik Ezkerrera (RTL)\",\"langCode\":\"Hizkuntza Kodea\",\"longDescr\":\"URL Deskribapen Luzea\",\"cssClass\":\"Estilo-orriko Klaseak\",\"advisoryTitle\":\"Izenburua\",\"cssStyle\":\"Estiloa\",\"ok\":\"Ados\",\"cancel\":\"Utzi\",\"close\":\"Itxi\",\"preview\":\"Aurrebista\",\"resize\":\"Arrastatu tamaina aldatzeko\",\"generalTab\":\"Orokorra\",\"advancedTab\":\"Aurreratua\",\"validateNumberFailed\":\"Balio hau ez da zenbaki bat.\",\"confirmNewPage\":\"Eduki honetan gorde gabe dauden aldaketak galduko dira. Ziur zaude orri berri bat kargatu nahi duzula?\",\"confirmCancel\":\"Aukera batzuk aldatu egin dira. Ziur zaude elkarrizketa-koadroa itxi nahi duzula?\",\"options\":\"Aukerak\",\"target\":\"Target (Helburua)\",\"targetNew\":\"Leiho Berria (_blank)\",\"targetTop\":\"Goieneko Leihoan (_top)\",\"targetSelf\":\"Leiho Berdinean (_self)\",\"targetParent\":\"Leiho Gurasoan (_parent)\",\"langDirLTR\":\"Ezkerretik Eskumara(LTR)\",\"langDirRTL\":\"Eskumatik Ezkerrera (RTL)\",\"styles\":\"Estiloa\",\"cssClasses\":\"Estilo-orriko Klaseak\",\"width\":\"Zabalera\",\"height\":\"Altuera\",\"align\":\"Lerrokatu\",\"alignLeft\":\"Ezkerrera\",\"alignRight\":\"Eskuman\",\"alignCenter\":\"Erdian\",\"alignTop\":\"Goian\",\"alignMiddle\":\"Erdian\",\"alignBottom\":\"Behean\",\"invalidValue\":\"Balio ezegokia.\",\"invalidHeight\":\"Altuera zenbaki bat izan behar da.\",\"invalidWidth\":\"Zabalera zenbaki bat izan behar da.\",\"invalidCssLength\":\"\\\"%1\\\" eremurako zehaztutako balioa zenbaki positibo bat izan behar du, aukeran CSS neurri unitate batekin (px, %, in, cm, mm, em, ex, pt edo pc).\",\"invalidHtmlLength\":\"\\\"%1\\\" eremurako zehaztutako balioa zenbaki positibo bat izan behar du, aukeran HTML neurri unitate batekin (px edo %).\",\"invalidInlineStyle\":\"Lerroko estiloan zehazten dena tupla \\\"name : value\\\" formatuko eta puntu eta komaz bereiztutako tupla bat edo gehiago izan behar dira.\",\"cssLengthTooltip\":\"Zenbakia bakarrik zehazten bada pixeletan egongo da. CSS neurri unitatea ere zehaztu ahal da (px, %, in, cm, mm, em, ex, pt, edo pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, erabilezina</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Eskubide guztiak erreserbaturik.\",\"dlgTitle\":\"CKEditor(r)i buruz\",\"help\":\"$1 aztertu laguntza jasotzeko.\",\"moreInfo\":\"Lizentziari buruzko informazioa gure webgunean:\",\"title\":\"CKEditor(r)i buruz\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Lodia\",\"italic\":\"Etzana\",\"strike\":\"Marratua\",\"subscript\":\"Azpi-indize\",\"superscript\":\"Goi-indize\",\"underline\":\"Azpimarratu\"},\"blockquote\":{\"toolbar\":\"Aipamen blokea\"},\"clipboard\":{\"copy\":\"Kopiatu\",\"copyError\":\"Zure web nabigatzailearen segurtasun ezarpenak testuak automatikoki kopiatzea ez dute baimentzen. Mesedez teklatua erabili ezazu (Ctrl/Cmd+C).\",\"cut\":\"Ebaki\",\"cutError\":\"Zure web nabigatzailearen segurtasun ezarpenak testuak automatikoki moztea ez dute baimentzen. Mesedez teklatua erabili ezazu (Ctrl/Cmd+X).\",\"paste\":\"Itsatsi\",\"pasteArea\":\"Itsasteko Area\",\"pasteMsg\":\"Mesedez teklatua erabilita (<STRONG>Ctrl/Cmd+V</STRONG>) ondorego eremuan testua itsatsi eta <STRONG>OK</STRONG> sakatu.\",\"securityMsg\":\"Nabigatzailearen segurtasun ezarpenak direla eta, editoreak ezin du arbela zuzenean erabili. Leiho honetan berriro itsatsi behar duzu.\",\"title\":\"Itsatsi\"},\"contextmenu\":{\"options\":\"Testuingurko Menuaren Aukerak\"},\"toolbar\":{\"toolbarCollapse\":\"Tresna-barra Txikitu\",\"toolbarExpand\":\"Tresna-barra Luzatu\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editorearen Tresna-barra\"},\"elementspath\":{\"eleLabel\":\"Elementu bidea\",\"eleTitle\":\"%1 elementua\"},\"format\":{\"label\":\"Formatua\",\"panelTitle\":\"Formatua\",\"tag_address\":\"Helbidea\",\"tag_div\":\"Paragrafoa (DIV)\",\"tag_h1\":\"Izenburua 1\",\"tag_h2\":\"Izenburua 2\",\"tag_h3\":\"Izenburua 3\",\"tag_h4\":\"Izenburua 4\",\"tag_h5\":\"Izenburua 5\",\"tag_h6\":\"Izenburua 6\",\"tag_p\":\"Arrunta\",\"tag_pre\":\"Formateatua\"},\"horizontalrule\":{\"toolbar\":\"Txertatu Marra Horizontala\"},\"image\":{\"alertUrl\":\"Mesedez Irudiaren URLa idatzi\",\"alt\":\"Ordezko Testua\",\"border\":\"Ertza\",\"btnUpload\":\"Zerbitzarira bidalia\",\"button2Img\":\"Aukeratutako irudi botoia, irudi normal batean eraldatu nahi duzu?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Aukeratutako irudia, irudi botoi batean eraldatu nahi duzu?\",\"infoTab\":\"Irudi informazioa\",\"linkTab\":\"Esteka\",\"lockRatio\":\"Erlazioa Blokeatu\",\"menu\":\"Irudi Ezaugarriak\",\"resetSize\":\"Tamaina Berrezarri\",\"title\":\"Irudi Ezaugarriak\",\"titleButton\":\"Irudi Botoiaren Ezaugarriak\",\"upload\":\"Gora Kargatu\",\"urlMissing\":\"Irudiaren iturburu URL-a falta da.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Ertza zenbaki oso bat izan behar da.\",\"validateHSpace\":\"HSpace zenbaki oso bat izan behar da.\",\"validateVSpace\":\"VSpace zenbaki oso bat izan behar da.\"},\"indent\":{\"indent\":\"Handitu Koska\",\"outdent\":\"Txikitu Koska\"},\"fakeobjects\":{\"anchor\":\"Aingura\",\"flash\":\"Flash Animazioa\",\"hiddenfield\":\"Ezkutuko Eremua\",\"iframe\":\"IFrame\",\"unknown\":\"Objektu ezezaguna\"},\"link\":{\"acccessKey\":\"Sarbide-gakoa\",\"advanced\":\"Aurreratua\",\"advisoryContentType\":\"Eduki Mota (Content Type)\",\"advisoryTitle\":\"Izenburua\",\"anchor\":{\"toolbar\":\"Aingura\",\"menu\":\"Ainguraren Ezaugarriak\",\"title\":\"Ainguraren Ezaugarriak\",\"name\":\"Ainguraren Izena\",\"errorName\":\"Idatzi ainguraren izena\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"Elementuaren ID-gatik\",\"anchorName\":\"Aingura izenagatik\",\"charset\":\"Estekatutako Karaktere Multzoa\",\"cssClasses\":\"Estilo-orriko Klaseak\",\"emailAddress\":\"ePosta Helbidea\",\"emailBody\":\"Mezuaren Gorputza\",\"emailSubject\":\"Mezuaren Gaia\",\"id\":\"Id\",\"info\":\"Estekaren Informazioa\",\"langCode\":\"Hizkuntzaren Norabidea\",\"langDir\":\"Hizkuntzaren Norabidea\",\"langDirLTR\":\"Ezkerretik Eskumara(LTR)\",\"langDirRTL\":\"Eskumatik Ezkerrera (RTL)\",\"menu\":\"Aldatu Esteka\",\"name\":\"Izena\",\"noAnchors\":\"(Ez daude aingurak eskuragarri dokumentuan)\",\"noEmail\":\"Mesedez ePosta helbidea idatzi\",\"noUrl\":\"Mesedez URL esteka idatzi\",\"other\":\"<bestelakoa>\",\"popupDependent\":\"Menpekoa (Netscape)\",\"popupFeatures\":\"Popup Leihoaren Ezaugarriak\",\"popupFullScreen\":\"Pantaila Osoa (IE)\",\"popupLeft\":\"Ezkerreko  Posizioa\",\"popupLocationBar\":\"Kokaleku Barra\",\"popupMenuBar\":\"Menu Barra\",\"popupResizable\":\"Tamaina Aldakorra\",\"popupScrollBars\":\"Korritze Barrak\",\"popupStatusBar\":\"Egoera Barra\",\"popupToolbar\":\"Tresna Barra\",\"popupTop\":\"Goiko Posizioa\",\"rel\":\"Erlazioa\",\"selectAnchor\":\"Aingura bat hautatu\",\"styles\":\"Estiloa\",\"tabIndex\":\"Tabulazio Indizea\",\"target\":\"Target (Helburua)\",\"targetFrame\":\"<marko>\",\"targetFrameName\":\"Marko Helburuaren Izena\",\"targetPopup\":\"<popup leihoa>\",\"targetPopupName\":\"Popup Leihoaren Izena\",\"title\":\"Esteka\",\"toAnchor\":\"Aingura orrialde honetan\",\"toEmail\":\"ePosta\",\"toUrl\":\"URL\",\"toolbar\":\"Txertatu/Editatu Esteka\",\"type\":\"Esteka Mota\",\"unlink\":\"Kendu Esteka\",\"upload\":\"Gora kargatu\"},\"list\":{\"bulletedlist\":\"Buletdun Zerrenda\",\"numberedlist\":\"Zenbakidun Zerrenda\"},\"magicline\":{\"title\":\"Txertatu paragrafoa hemen\"},\"maximize\":{\"maximize\":\"Maximizatu\",\"minimize\":\"Minimizatu\"},\"pastetext\":{\"button\":\"Testu Arrunta bezala Itsatsi\",\"title\":\"Testu Arrunta bezala Itsatsi\"},\"pastefromword\":{\"confirmCleanup\":\"Itsatsi nahi duzun testua Wordetik hartua dela dirudi. Itsatsi baino lehen garbitu nahi duzu?\",\"error\":\"Barneko errore bat dela eta ezin izan da testua garbitu\",\"title\":\"Itsatsi Word-etik\",\"toolbar\":\"Itsatsi Word-etik\"},\"removeformat\":{\"toolbar\":\"Kendu Formatua\"},\"sourcearea\":{\"toolbar\":\"HTML Iturburua\"},\"specialchar\":{\"options\":\"Karaktere Berezien Aukerak\",\"title\":\"Karaktere Berezia Aukeratu\",\"toolbar\":\"Txertatu Karaktere Berezia\"},\"scayt\":{\"about\":\"SCAYTi buruz\",\"aboutTab\":\"Honi buruz\",\"addWord\":\"Hitza Gehitu\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Hiztegiak\",\"disable\":\"Desgaitu SCAYT\",\"emptyDic\":\"Hiztegiaren izena ezin da hutsik egon.\",\"enable\":\"Gaitu SCAYT\",\"ignore\":\"Baztertu\",\"ignoreAll\":\"Denak baztertu\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Hizkuntzak\",\"languagesTab\":\"Hizkuntzak\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"Iradokizun gehiago\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Aukerak\",\"optionsTab\":\"Aukerak\",\"title\":\"Ortografia Zuzenketa Idatzi Ahala (SCAYT)\",\"toggle\":\"SCAYT aldatu\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Estiloa\",\"panelTitle\":\"Formatu Estiloak\",\"panelTitle1\":\"Bloke Estiloak\",\"panelTitle2\":\"Inline Estiloak\",\"panelTitle3\":\"Objektu Estiloak\"},\"table\":{\"border\":\"Ertzaren Zabalera\",\"caption\":\"Epigrafea\",\"cell\":{\"menu\":\"Gelaxka\",\"insertBefore\":\"Txertatu Gelaxka Aurretik\",\"insertAfter\":\"Txertatu Gelaxka Ostean\",\"deleteCell\":\"Kendu Gelaxkak\",\"merge\":\"Batu Gelaxkak\",\"mergeRight\":\"Elkartu Eskumara\",\"mergeDown\":\"Elkartu Behera\",\"splitHorizontal\":\"Banatu Gelaxkak Horizontalki\",\"splitVertical\":\"Banatu Gelaxkak Bertikalki\",\"title\":\"Gelaxken Ezaugarriak\",\"cellType\":\"Gelaxka Mota\",\"rowSpan\":\"Hedatutako Lerroak\",\"colSpan\":\"Hedatutako Zutabeak\",\"wordWrap\":\"Itzulbira\",\"hAlign\":\"Lerrokatze Horizontala\",\"vAlign\":\"Lerrokatze Bertikala\",\"alignBaseline\":\"Oinarri-lerroan\",\"bgColor\":\"Fondoaren Kolorea\",\"borderColor\":\"Ertzaren Kolorea\",\"data\":\"Data\",\"header\":\"Goiburua\",\"yes\":\"Bai\",\"no\":\"Ez\",\"invalidWidth\":\"Gelaxkaren zabalera zenbaki bat izan behar da.\",\"invalidHeight\":\"Gelaxkaren altuera zenbaki bat izan behar da.\",\"invalidRowSpan\":\"Lerroen hedapena zenbaki osoa izan behar da.\",\"invalidColSpan\":\"Zutabeen hedapena zenbaki osoa izan behar da.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"Gelaxken betegarria\",\"cellSpace\":\"Gelaxka arteko tartea\",\"column\":{\"menu\":\"Zutabea\",\"insertBefore\":\"Txertatu Zutabea Aurretik\",\"insertAfter\":\"Txertatu Zutabea Ostean\",\"deleteColumn\":\"Ezabatu Zutabeak\"},\"columns\":\"Zutabeak\",\"deleteTable\":\"Ezabatu Taula\",\"headers\":\"Goiburuak\",\"headersBoth\":\"Biak\",\"headersColumn\":\"Lehen zutabea\",\"headersNone\":\"Bat ere ez\",\"headersRow\":\"Lehen lerroa\",\"invalidBorder\":\"Ertzaren tamaina zenbaki bat izan behar da.\",\"invalidCellPadding\":\"Gelaxken betegarria zenbaki bat izan behar da.\",\"invalidCellSpacing\":\"Gelaxka arteko tartea zenbaki bat izan behar da.\",\"invalidCols\":\"Zutabe kopurua 0 baino handiagoa den zenbakia izan behar da.\",\"invalidHeight\":\"Taularen altuera zenbaki bat izan behar da.\",\"invalidRows\":\"Lerro kopurua 0 baino handiagoa den zenbakia izan behar da.\",\"invalidWidth\":\"Taularen zabalera zenbaki bat izan behar da.\",\"menu\":\"Taularen Ezaugarriak\",\"row\":{\"menu\":\"Lerroa\",\"insertBefore\":\"Txertatu Lerroa Aurretik\",\"insertAfter\":\"Txertatu Lerroa Ostean\",\"deleteRow\":\"Ezabatu Lerroak\"},\"rows\":\"Lerroak\",\"summary\":\"Laburpena\",\"title\":\"Taularen Ezaugarriak\",\"toolbar\":\"Taula\",\"widthPc\":\"ehuneko\",\"widthPx\":\"pixel\",\"widthUnit\":\"zabalera unitatea\"},\"undo\":{\"redo\":\"Berregin\",\"undo\":\"Desegin\"},\"wsc\":{\"btnIgnore\":\"Ezikusi\",\"btnIgnoreAll\":\"Denak Ezikusi\",\"btnReplace\":\"Ordezkatu\",\"btnReplaceAll\":\"Denak Ordezkatu\",\"btnUndo\":\"Desegin\",\"changeTo\":\"Honekin ordezkatu\",\"errorLoading\":\"Errorea gertatu da aplikazioa zerbitzaritik kargatzean: %s.\",\"ieSpellDownload\":\"Zuzentzaile ortografikoa ez dago instalatuta. Deskargatu nahi duzu?\",\"manyChanges\":\"Zuzenketa ortografikoa bukatuta: %1 hitz aldatu dira\",\"noChanges\":\"Zuzenketa ortografikoa bukatuta: Ez da ezer aldatu\",\"noMispell\":\"Zuzenketa ortografikoa bukatuta: Akatsik ez\",\"noSuggestions\":\"- Iradokizunik ez -\",\"notAvailable\":\"Barkatu baina momentu honetan zerbitzua ez dago erabilgarri.\",\"notInDic\":\"Ez dago hiztegian\",\"oneChange\":\"Zuzenketa ortografikoa bukatuta: Hitz bat aldatu da\",\"progress\":\"Zuzenketa ortografikoa martxan...\",\"title\":\"Ortografia zuzenketa\",\"toolbar\":\"Ortografia\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/fa.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['fa']={\"editor\":\"ویرایشگر متن کامل\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"کلید Alt+0 را برای راهنمایی بفشارید\",\"browseServer\":\"فهرستنمایی سرور\",\"url\":\"URL\",\"protocol\":\"پروتکل\",\"upload\":\"آپلود\",\"uploadSubmit\":\"به سرور بفرست\",\"image\":\"تصویر\",\"flash\":\"فلش\",\"form\":\"فرم\",\"checkbox\":\"چکباکس\",\"radio\":\"دکمهی رادیویی\",\"textField\":\"فیلد متنی\",\"textarea\":\"ناحیهٴ متنی\",\"hiddenField\":\"فیلد پنهان\",\"button\":\"دکمه\",\"select\":\"فیلد انتخاب چند گزینهای\",\"imageButton\":\"دکمهی تصویری\",\"notSet\":\"<تعین نشده>\",\"id\":\"شناسه\",\"name\":\"نام\",\"langDir\":\"جهتنمای زبان\",\"langDirLtr\":\"چپ به راست\",\"langDirRtl\":\"راست به چپ\",\"langCode\":\"کد زبان\",\"longDescr\":\"URL توصیف طولانی\",\"cssClass\":\"کلاسهای شیوهنامه (Stylesheet)\",\"advisoryTitle\":\"عنوان کمکی\",\"cssStyle\":\"شیوه (style)\",\"ok\":\"پذیرش\",\"cancel\":\"انصراف\",\"close\":\"بستن\",\"preview\":\"پیشنمایش\",\"resize\":\"تغییر اندازه\",\"generalTab\":\"عمومی\",\"advancedTab\":\"پیشرفته\",\"validateNumberFailed\":\"این مقدار یک عدد نیست.\",\"confirmNewPage\":\"هر تغییر ایجاد شدهی ذخیره نشده از بین خواهد رفت. آیا اطمینان دارید که قصد بارگیری صفحه جدیدی را دارید؟\",\"confirmCancel\":\"برخی از گزینهها تغییر کردهاند. آیا واقعا قصد بستن این پنجره را دارید؟\",\"options\":\"گزینهها\",\"target\":\"نحوه باز کردن\",\"targetNew\":\"پنجره جدید\",\"targetTop\":\"بالاترین پنجره\",\"targetSelf\":\"همان پنجره\",\"targetParent\":\"پنجره والد\",\"langDirLTR\":\"چپ به راست\",\"langDirRTL\":\"راست به چپ\",\"styles\":\"سبک\",\"cssClasses\":\"کلاسهای شیوهنامه\",\"width\":\"عرض\",\"height\":\"طول\",\"align\":\"چینش\",\"alignLeft\":\"چپ\",\"alignRight\":\"راست\",\"alignCenter\":\"مرکز\",\"alignTop\":\"بالا\",\"alignMiddle\":\"وسط\",\"alignBottom\":\"پائین\",\"invalidValue\":\"مقدار نامعتبر.\",\"invalidHeight\":\"ارتفاع باید یک عدد باشد.\",\"invalidWidth\":\"عرض باید یک عدد باشد.\",\"invalidCssLength\":\"عدد تعیین شده برای فیلد \\\"%1\\\" باید یک عدد مثبت با یا بدون یک واحد اندازه گیری CSS معتبر باشد (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"عدد تعیین شده برای فیلد \\\"%1\\\" باید یک عدد مثبت با یا بدون یک واحد اندازه گیری HTML معتبر باشد (px or %).\",\"invalidInlineStyle\":\"عدد تعیین شده برای سبک درونخطی -Inline Style- باید دارای یک یا چند چندتایی با شکلی شبیه \\\"name : value\\\" که باید با یک \\\";\\\" از هم جدا شوند.\",\"cssLengthTooltip\":\"یک عدد برای یک مقدار بر حسب پیکسل و یا یک عدد با یک واحد CSS معتبر وارد کنید (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">، غیر قابل دسترس</span>\"},\"about\":{\"copy\":\"حق نشر &copy; $1. کلیه حقوق محفوظ است.\",\"dlgTitle\":\"درباره CKEditor\",\"help\":\" برای راهنمایی $1 را بررسی کنید.\",\"moreInfo\":\"برای کسب اطلاعات مجوز لطفا به وب سایت ما مراجعه کنید:\",\"title\":\"درباره CKEditor\",\"userGuide\":\"راهنمای کاربران CKEditor\"},\"basicstyles\":{\"bold\":\"درشت\",\"italic\":\"خمیده\",\"strike\":\"میانخط\",\"subscript\":\"زیرنویس\",\"superscript\":\"بالانویس\",\"underline\":\"زیرخطدار\"},\"blockquote\":{\"toolbar\":\"بلوک نقل قول\"},\"clipboard\":{\"copy\":\"رونوشت\",\"copyError\":\"تنظیمات امنیتی مرورگر شما اجازه نمیدهد که ویرایشگر به طور خودکار عملکردهای کپی کردن را انجام دهد. لطفا با دکمههای صفحه کلید این کار را انجام دهید (Ctrl/Cmd+C).\",\"cut\":\"برش\",\"cutError\":\"تنظیمات امنیتی مرورگر شما اجازه نمیدهد که ویرایشگر به طور خودکار عملکردهای برش را انجام دهد. لطفا با دکمههای صفحه کلید این کار را انجام دهید (Ctrl/Cmd+X).\",\"paste\":\"چسباندن\",\"pasteArea\":\"محل چسباندن\",\"pasteMsg\":\"لطفا متن را با کلیدهای (<STRONG>Ctrl/Cmd+V</STRONG>) در این جعبهٴ متنی بچسبانید و <STRONG>پذیرش</STRONG> را بزنید.\",\"securityMsg\":\"به خاطر تنظیمات امنیتی مرورگر شما، ویرایشگر نمیتواند دسترسی مستقیم به دادههای clipboard داشته باشد. شما باید دوباره آنرا در این پنجره بچسبانید.\",\"title\":\"چسباندن\"},\"contextmenu\":{\"options\":\"گزینههای منوی زمینه\"},\"toolbar\":{\"toolbarCollapse\":\"بستن نوار ابزار\",\"toolbarExpand\":\"بازکردن نوار ابزار\",\"toolbarGroups\":{\"document\":\"سند\",\"clipboard\":\"حافظه موقت/برگشت\",\"editing\":\"در حال ویرایش\",\"forms\":\"فرمها\",\"basicstyles\":\"شیوههای پایه\",\"paragraph\":\"بند\",\"links\":\"پیوندها\",\"insert\":\"ورود\",\"styles\":\"شیوهها\",\"colors\":\"رنگها\",\"tools\":\"ابزارها\"},\"toolbars\":\"نوار ابزار\"},\"elementspath\":{\"eleLabel\":\"مسیر عناصر\",\"eleTitle\":\"%1 عنصر\"},\"format\":{\"label\":\"فرمت\",\"panelTitle\":\"فرمت\",\"tag_address\":\"آدرس\",\"tag_div\":\"بند\",\"tag_h1\":\"سرنویس 1\",\"tag_h2\":\"سرنویس 2\",\"tag_h3\":\"سرنویس 3\",\"tag_h4\":\"سرنویس 4\",\"tag_h5\":\"سرنویس 5\",\"tag_h6\":\"سرنویس 6\",\"tag_p\":\"نرمال\",\"tag_pre\":\"فرمت شده\"},\"horizontalrule\":{\"toolbar\":\"گنجاندن خط افقی\"},\"image\":{\"alertUrl\":\"لطفا URL تصویر را بنویسید\",\"alt\":\"متن جایگزین\",\"border\":\"لبه\",\"btnUpload\":\"به سرور بفرست\",\"button2Img\":\"آیا مایلید از یک تصویر ساده روی دکمه تصویری انتخاب شده استفاده کنید؟\",\"hSpace\":\"فاصلهٴ افقی\",\"img2Button\":\"آیا مایلید از یک دکمه تصویری روی تصویر انتخاب شده استفاده کنید؟\",\"infoTab\":\"اطلاعات تصویر\",\"linkTab\":\"پیوند\",\"lockRatio\":\"قفل کردن نسبت\",\"menu\":\"ویژگیهای تصویر\",\"resetSize\":\"بازنشانی اندازه\",\"title\":\"ویژگیهای تصویر\",\"titleButton\":\"ویژگیهای دکمهٴ تصویری\",\"upload\":\"انتقال به سرور\",\"urlMissing\":\"آدرس URL اصلی تصویر یافت نشد.\",\"vSpace\":\"فاصلهٴ عمودی\",\"validateBorder\":\"مقدار خطوط باید یک عدد باشد.\",\"validateHSpace\":\"مقدار فاصله گذاری افقی باید یک عدد باشد.\",\"validateVSpace\":\"مقدار فاصله گذاری عمودی باید یک عدد باشد.\"},\"indent\":{\"indent\":\"افزایش تورفتگی\",\"outdent\":\"کاهش تورفتگی\"},\"fakeobjects\":{\"anchor\":\"لنگر\",\"flash\":\"انیمشن فلش\",\"hiddenfield\":\"فیلد پنهان\",\"iframe\":\"IFrame\",\"unknown\":\"شیء ناشناخته\"},\"link\":{\"acccessKey\":\"کلید دستیابی\",\"advanced\":\"پیشرفته\",\"advisoryContentType\":\"نوع محتوای کمکی\",\"advisoryTitle\":\"عنوان کمکی\",\"anchor\":{\"toolbar\":\"گنجاندن/ویرایش لنگر\",\"menu\":\"ویژگیهای لنگر\",\"title\":\"ویژگیهای لنگر\",\"name\":\"نام لنگر\",\"errorName\":\"لطفا نام لنگر را بنویسید\",\"remove\":\"حذف لنگر\"},\"anchorId\":\"با شناسهٴ المان\",\"anchorName\":\"با نام لنگر\",\"charset\":\"نویسهگان منبع پیوند شده\",\"cssClasses\":\"کلاسهای شیوهنامه(Stylesheet)\",\"emailAddress\":\"نشانی پست الکترونیکی\",\"emailBody\":\"متن پیام\",\"emailSubject\":\"موضوع پیام\",\"id\":\"شناسه\",\"info\":\"اطلاعات پیوند\",\"langCode\":\"جهتنمای زبان\",\"langDir\":\"جهتنمای زبان\",\"langDirLTR\":\"چپ به راست (LTR)\",\"langDirRTL\":\"راست به چپ (RTL)\",\"menu\":\"ویرایش پیوند\",\"name\":\"نام\",\"noAnchors\":\"(در این سند لنگری دردسترس نیست)\",\"noEmail\":\"لطفا نشانی پست الکترونیکی را بنویسید\",\"noUrl\":\"لطفا URL پیوند را بنویسید\",\"other\":\"<سایر>\",\"popupDependent\":\"وابسته (Netscape)\",\"popupFeatures\":\"ویژگیهای پنجرهٴ پاپاپ\",\"popupFullScreen\":\"تمام صفحه (IE)\",\"popupLeft\":\"موقعیت چپ\",\"popupLocationBar\":\"نوار موقعیت\",\"popupMenuBar\":\"نوار منو\",\"popupResizable\":\"قابل تغییر اندازه\",\"popupScrollBars\":\"میلههای پیمایش\",\"popupStatusBar\":\"نوار وضعیت\",\"popupToolbar\":\"نوار ابزار\",\"popupTop\":\"موقعیت بالا\",\"rel\":\"وابستگی\",\"selectAnchor\":\"یک لنگر برگزینید\",\"styles\":\"شیوه (style)\",\"tabIndex\":\"نمایهٴ دسترسی با برگه\",\"target\":\"مقصد\",\"targetFrame\":\"<فریم>\",\"targetFrameName\":\"نام فریم مقصد\",\"targetPopup\":\"<پنجرهٴ پاپاپ>\",\"targetPopupName\":\"نام پنجرهٴ پاپاپ\",\"title\":\"پیوند\",\"toAnchor\":\"لنگر در همین صفحه\",\"toEmail\":\"پست الکترونیکی\",\"toUrl\":\"URL\",\"toolbar\":\"گنجاندن/ویرایش پیوند\",\"type\":\"نوع پیوند\",\"unlink\":\"برداشتن پیوند\",\"upload\":\"انتقال به سرور\"},\"list\":{\"bulletedlist\":\"فهرست نقطهای\",\"numberedlist\":\"فهرست شمارهدار\"},\"magicline\":{\"title\":\"قرار دادن بند در اینجا\"},\"maximize\":{\"maximize\":\"بیشنه کردن\",\"minimize\":\"کمینه کردن\"},\"pastetext\":{\"button\":\"چسباندن به عنوان متن ساده\",\"title\":\"چسباندن به عنوان متن ساده\"},\"pastefromword\":{\"confirmCleanup\":\"متنی که میخواهید بچسبانید به نظر میرسد که از Word کپی شده است. آیا میخواهید قبل از چسباندن آن را پاکسازی کنید؟\",\"error\":\"به دلیل بروز خطای داخلی امکان پاکسازی اطلاعات بازنشانی شده وجود ندارد.\",\"title\":\"چسباندن از Word\",\"toolbar\":\"چسباندن از Word\"},\"removeformat\":{\"toolbar\":\"برداشتن فرمت\"},\"sourcearea\":{\"toolbar\":\"منبع\"},\"specialchar\":{\"options\":\"گزینههای نویسههای ویژه\",\"title\":\"گزینش نویسهی ویژه\",\"toolbar\":\"گنجاندن نویسهی ویژه\"},\"scayt\":{\"about\":\"درباره SCAYT\",\"aboutTab\":\"درباره\",\"addWord\":\"افزودن Word\",\"allCaps\":\"نادیده گرفتن همه کلاه-واژهها\",\"dic_create\":\"ایجاد\",\"dic_delete\":\"حذف\",\"dic_field_name\":\"نام دیکشنری\",\"dic_info\":\"در ابتدا دیکشنری کاربر در کوکی ذخیره میشود. با این حال، کوکیها در اندازه محدود شدهاند. وقتی که دیکشنری کاربری بزرگ میشود و به نقطهای که نمیتواند در کوکی ذخیره شود، پس از آن دیکشنری ممکن است بر روی سرور ما ذخیره شود. برای ذخیره دیکشنری شخصی شما بر روی سرور ما، باید یک نام برای دیکشنری خود مشخص نمایید. اگر شما قبلا یک دیکشنری روی سرور ما ذخیره کردهاید، لطفا نام آنرا درج و روی دکمه بازیافت کلیک نمایید.\",\"dic_rename\":\"تغییر نام\",\"dic_restore\":\"بازیافت\",\"dictionariesTab\":\"دیکشنریها\",\"disable\":\"غیرفعالسازی SCAYT\",\"emptyDic\":\"نام دیکشنری نباید خالی باشد.\",\"enable\":\"فعالسازی SCAYT\",\"ignore\":\"عبور کردن\",\"ignoreAll\":\"عبور کردن از همه\",\"ignoreDomainNames\":\"عبور از نامهای دامنه\",\"langs\":\"زبانها\",\"languagesTab\":\"زبانها\",\"mixedCase\":\"عبور از کلماتی مرکب از حروف بزرگ و کوچک\",\"mixedWithDigits\":\"عبور از کلمات به همراه عدد\",\"moreSuggestions\":\"پیشنهادهای بیشتر\",\"opera_title\":\"توسط اپرا پشتیبانی نمیشود\",\"options\":\"گزینهها\",\"optionsTab\":\"گزینهها\",\"title\":\"بررسی املای تایپ شما\",\"toggle\":\"ضامن SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"سبک\",\"panelTitle\":\"سبکهای قالببندی\",\"panelTitle1\":\"سبکهای بلوک\",\"panelTitle2\":\"سبکهای درونخطی\",\"panelTitle3\":\"سبکهای شیء\"},\"table\":{\"border\":\"اندازهٴ لبه\",\"caption\":\"عنوان\",\"cell\":{\"menu\":\"سلول\",\"insertBefore\":\"افزودن سلول قبل از\",\"insertAfter\":\"افزودن سلول بعد از\",\"deleteCell\":\"حذف سلولها\",\"merge\":\"ادغام سلولها\",\"mergeRight\":\"ادغام به راست\",\"mergeDown\":\"ادغام به پایین\",\"splitHorizontal\":\"جدا کردن افقی سلول\",\"splitVertical\":\"جدا کردن عمودی سلول\",\"title\":\"ویژگیهای سلول\",\"cellType\":\"نوع سلول\",\"rowSpan\":\"محدوده ردیفها\",\"colSpan\":\"محدوده ستونها\",\"wordWrap\":\"شکستن کلمه\",\"hAlign\":\"چینش افقی\",\"vAlign\":\"چینش عمودی\",\"alignBaseline\":\"خط مبنا\",\"bgColor\":\"رنگ زمینه\",\"borderColor\":\"رنگ خطوط\",\"data\":\"اطلاعات\",\"header\":\"سرنویس\",\"yes\":\"بله\",\"no\":\"خیر\",\"invalidWidth\":\"عرض سلول باید یک عدد باشد.\",\"invalidHeight\":\"ارتفاع سلول باید عدد باشد.\",\"invalidRowSpan\":\"مقدار محدوده ردیفها باید یک عدد باشد.\",\"invalidColSpan\":\"مقدار محدوده ستونها باید یک عدد باشد.\",\"chooseColor\":\"انتخاب\"},\"cellPad\":\"فاصلهٴ پرشده در سلول\",\"cellSpace\":\"فاصلهٴ میان سلولها\",\"column\":{\"menu\":\"ستون\",\"insertBefore\":\"افزودن ستون قبل از\",\"insertAfter\":\"افزودن ستون بعد از\",\"deleteColumn\":\"حذف ستونها\"},\"columns\":\"ستونها\",\"deleteTable\":\"پاک کردن جدول\",\"headers\":\"سرنویسها\",\"headersBoth\":\"هردو\",\"headersColumn\":\"اولین ستون\",\"headersNone\":\"هیچ\",\"headersRow\":\"اولین ردیف\",\"invalidBorder\":\"مقدار اندازه خطوط باید یک عدد باشد.\",\"invalidCellPadding\":\"بالشتک سلول باید یک عدد باشد.\",\"invalidCellSpacing\":\"مقدار فاصلهگذاری سلول باید یک عدد باشد.\",\"invalidCols\":\"تعداد ستونها باید یک عدد بزرگتر از 0 باشد.\",\"invalidHeight\":\"مقدار ارتفاع  جدول باید یک عدد باشد.\",\"invalidRows\":\"تعداد ردیفها باید یک عدد بزرگتر از 0 باشد.\",\"invalidWidth\":\"مقدار پهنای جدول باید یک عدد باشد.\",\"menu\":\"ویژگیهای جدول\",\"row\":{\"menu\":\"سطر\",\"insertBefore\":\"افزودن سطر قبل از\",\"insertAfter\":\"افزودن سطر بعد از\",\"deleteRow\":\"حذف سطرها\"},\"rows\":\"سطرها\",\"summary\":\"خلاصه\",\"title\":\"ویژگیهای جدول\",\"toolbar\":\"جدول\",\"widthPc\":\"درصد\",\"widthPx\":\"پیکسل\",\"widthUnit\":\"واحد پهنا\"},\"undo\":{\"redo\":\"بازچیدن\",\"undo\":\"واچیدن\"},\"wsc\":{\"btnIgnore\":\"چشمپوشی\",\"btnIgnoreAll\":\"چشمپوشی همه\",\"btnReplace\":\"جایگزینی\",\"btnReplaceAll\":\"جایگزینی همه\",\"btnUndo\":\"واچینش\",\"changeTo\":\"تغییر به\",\"errorLoading\":\"خطا در بارگیری برنامه خدمات میزبان: %s.\",\"ieSpellDownload\":\"بررسی کنندهٴ املا نصب نشده است. آیا میخواهید آن را هماکنون دریافت کنید؟\",\"manyChanges\":\"بررسی املا انجام شد. %1 واژه تغییر یافت\",\"noChanges\":\"بررسی املا انجام شد. هیچ واژهای تغییر نیافت\",\"noMispell\":\"بررسی املا انجام شد. هیچ غلط املائی یافت نشد\",\"noSuggestions\":\"- پیشنهادی نیست -\",\"notAvailable\":\"با عرض پوزش خدمات الان در دسترس نیستند.\",\"notInDic\":\"در واژه~نامه یافت نشد\",\"oneChange\":\"بررسی املا انجام شد. یک واژه تغییر یافت\",\"progress\":\"بررسی املا در حال انجام...\",\"title\":\"بررسی املا\",\"toolbar\":\"بررسی املا\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/fi.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['fi']={\"editor\":\"Rikastekstieditori\",\"editorPanel\":\"Rikastekstieditoripaneeli\",\"common\":{\"editorHelp\":\"Paina ALT 0 nähdäksesi ohjeen\",\"browseServer\":\"Selaa palvelinta\",\"url\":\"Osoite\",\"protocol\":\"Protokolla\",\"upload\":\"Lisää tiedosto\",\"uploadSubmit\":\"Lähetä palvelimelle\",\"image\":\"Kuva\",\"flash\":\"Flash-animaatio\",\"form\":\"Lomake\",\"checkbox\":\"Valintaruutu\",\"radio\":\"Radiopainike\",\"textField\":\"Tekstikenttä\",\"textarea\":\"Tekstilaatikko\",\"hiddenField\":\"Piilokenttä\",\"button\":\"Painike\",\"select\":\"Valintakenttä\",\"imageButton\":\"Kuvapainike\",\"notSet\":\"<ei asetettu>\",\"id\":\"Tunniste\",\"name\":\"Nimi\",\"langDir\":\"Kielen suunta\",\"langDirLtr\":\"Vasemmalta oikealle (LTR)\",\"langDirRtl\":\"Oikealta vasemmalle (RTL)\",\"langCode\":\"Kielikoodi\",\"longDescr\":\"Pitkän kuvauksen URL\",\"cssClass\":\"Tyyliluokat\",\"advisoryTitle\":\"Avustava otsikko\",\"cssStyle\":\"Tyyli\",\"ok\":\"OK\",\"cancel\":\"Peruuta\",\"close\":\"Sulje\",\"preview\":\"Esikatselu\",\"resize\":\"Raahaa muuttaaksesi kokoa\",\"generalTab\":\"Yleinen\",\"advancedTab\":\"Lisäominaisuudet\",\"validateNumberFailed\":\"Arvon pitää olla numero.\",\"confirmNewPage\":\"Kaikki tallentamattomat muutokset tähän sisältöön menetetään. Oletko varma, että haluat ladata uuden sivun?\",\"confirmCancel\":\"Jotkut asetuksista on muuttuneet. Oletko varma, että haluat sulkea valintaikkunan?\",\"options\":\"Asetukset\",\"target\":\"Kohde\",\"targetNew\":\"Uusi ikkuna (_blank)\",\"targetTop\":\"Päällimmäinen ikkuna (_top)\",\"targetSelf\":\"Sama ikkuna (_self)\",\"targetParent\":\"Ylemmän tason ikkuna (_parent)\",\"langDirLTR\":\"Vasemmalta oikealle (LTR)\",\"langDirRTL\":\"Oikealta vasemmalle (RTL)\",\"styles\":\"Tyyli\",\"cssClasses\":\"Tyylitiedoston luokat\",\"width\":\"Leveys\",\"height\":\"Korkeus\",\"align\":\"Kohdistus\",\"alignLeft\":\"Vasemmalle\",\"alignRight\":\"Oikealle\",\"alignCenter\":\"Keskelle\",\"alignTop\":\"Ylös\",\"alignMiddle\":\"Keskelle\",\"alignBottom\":\"Alas\",\"invalidValue\":\"Virheellinen arvo.\",\"invalidHeight\":\"Korkeuden täytyy olla numero.\",\"invalidWidth\":\"Leveyden täytyy olla numero.\",\"invalidCssLength\":\"Kentän \\\"%1\\\" arvon täytyy olla positiivinen luku CSS mittayksikön (px, %, in, cm, mm, em, ex, pt tai pc) kanssa tai ilman.\",\"invalidHtmlLength\":\"Kentän \\\"%1\\\" arvon täytyy olla positiivinen luku HTML mittayksikön (px tai %) kanssa tai ilman.\",\"invalidInlineStyle\":\"Tyylille annetun arvon täytyy koostua yhdestä tai useammasta \\\"nimi : arvo\\\" parista, jotka ovat eroteltuna toisistaan puolipisteillä.\",\"cssLengthTooltip\":\"Anna numeroarvo pikseleinä tai numeroarvo CSS mittayksikön kanssa (px, %, in, cm, mm, em, ex, pt, tai pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, ei saatavissa</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Kaikki oikeuden pidätetään.\",\"dlgTitle\":\"Tietoa CKEditorista\",\"help\":\"Katso ohjeet: $1.\",\"moreInfo\":\"Lisenssitiedot löytyvät kotisivuiltamme:\",\"title\":\"Tietoa CKEditorista\",\"userGuide\":\"CKEditorin käyttäjäopas\"},\"basicstyles\":{\"bold\":\"Lihavoitu\",\"italic\":\"Kursivoitu\",\"strike\":\"Yliviivattu\",\"subscript\":\"Alaindeksi\",\"superscript\":\"Yläindeksi\",\"underline\":\"Alleviivattu\"},\"blockquote\":{\"toolbar\":\"Lainaus\"},\"clipboard\":{\"copy\":\"Kopioi\",\"copyError\":\"Selaimesi turva-asetukset eivät salli editorin toteuttaa kopioimista. Käytä näppäimistöä kopioimiseen (Ctrl+C).\",\"cut\":\"Leikkaa\",\"cutError\":\"Selaimesi turva-asetukset eivät salli editorin toteuttaa leikkaamista. Käytä näppäimistöä leikkaamiseen (Ctrl+X).\",\"paste\":\"Liitä\",\"pasteArea\":\"Leikealue\",\"pasteMsg\":\"Liitä painamalla (<STRONG>Ctrl+V</STRONG>) ja painamalla <STRONG>OK</STRONG>.\",\"securityMsg\":\"Selaimesi turva-asetukset eivät salli editorin käyttää leikepöytää suoraan. Sinun pitää suorittaa liittäminen tässä ikkunassa.\",\"title\":\"Liitä\"},\"contextmenu\":{\"options\":\"Pikavalikon ominaisuudet\"},\"toolbar\":{\"toolbarCollapse\":\"Kutista työkalupalkki\",\"toolbarExpand\":\"Laajenna työkalupalkki\",\"toolbarGroups\":{\"document\":\"Dokumentti\",\"clipboard\":\"Leikepöytä/Kumoa\",\"editing\":\"Muokkaus\",\"forms\":\"Lomakkeet\",\"basicstyles\":\"Perustyylit\",\"paragraph\":\"Kappale\",\"links\":\"Linkit\",\"insert\":\"Lisää\",\"styles\":\"Tyylit\",\"colors\":\"Värit\",\"tools\":\"Työkalut\"},\"toolbars\":\"Editorin työkalupalkit\"},\"elementspath\":{\"eleLabel\":\"Elementin polku\",\"eleTitle\":\"%1 elementti\"},\"format\":{\"label\":\"Muotoilu\",\"panelTitle\":\"Muotoilu\",\"tag_address\":\"Osoite\",\"tag_div\":\"Normaali (DIV)\",\"tag_h1\":\"Otsikko 1\",\"tag_h2\":\"Otsikko 2\",\"tag_h3\":\"Otsikko 3\",\"tag_h4\":\"Otsikko 4\",\"tag_h5\":\"Otsikko 5\",\"tag_h6\":\"Otsikko 6\",\"tag_p\":\"Normaali\",\"tag_pre\":\"Muotoiltu\"},\"horizontalrule\":{\"toolbar\":\"Lisää murtoviiva\"},\"image\":{\"alertUrl\":\"Kirjoita kuvan osoite (URL)\",\"alt\":\"Vaihtoehtoinen teksti\",\"border\":\"Kehys\",\"btnUpload\":\"Lähetä palvelimelle\",\"button2Img\":\"Haluatko muuntaa valitun kuvanäppäimen kuvaksi?\",\"hSpace\":\"Vaakatila\",\"img2Button\":\"Haluatko muuntaa valitun kuvan kuvanäppäimeksi?\",\"infoTab\":\"Kuvan tiedot\",\"linkTab\":\"Linkki\",\"lockRatio\":\"Lukitse suhteet\",\"menu\":\"Kuvan ominaisuudet\",\"resetSize\":\"Alkuperäinen koko\",\"title\":\"Kuvan ominaisuudet\",\"titleButton\":\"Kuvapainikkeen ominaisuudet\",\"upload\":\"Lisää kuva\",\"urlMissing\":\"Kuvan lähdeosoite puuttuu.\",\"vSpace\":\"Pystytila\",\"validateBorder\":\"Kehyksen täytyy olla kokonaisluku.\",\"validateHSpace\":\"HSpace-määrityksen täytyy olla kokonaisluku.\",\"validateVSpace\":\"VSpace-määrityksen täytyy olla kokonaisluku.\"},\"indent\":{\"indent\":\"Suurenna sisennystä\",\"outdent\":\"Pienennä sisennystä\"},\"fakeobjects\":{\"anchor\":\"Ankkuri\",\"flash\":\"Flash animaatio\",\"hiddenfield\":\"Piilokenttä\",\"iframe\":\"IFrame-kehys\",\"unknown\":\"Tuntematon objekti\"},\"link\":{\"acccessKey\":\"Pikanäppäin\",\"advanced\":\"Lisäominaisuudet\",\"advisoryContentType\":\"Avustava sisällön tyyppi\",\"advisoryTitle\":\"Avustava otsikko\",\"anchor\":{\"toolbar\":\"Lisää ankkuri/muokkaa ankkuria\",\"menu\":\"Ankkurin ominaisuudet\",\"title\":\"Ankkurin ominaisuudet\",\"name\":\"Nimi\",\"errorName\":\"Ankkurille on kirjoitettava nimi\",\"remove\":\"Poista ankkuri\"},\"anchorId\":\"Ankkurin ID:n mukaan\",\"anchorName\":\"Ankkurin nimen mukaan\",\"charset\":\"Linkitetty kirjaimisto\",\"cssClasses\":\"Tyyliluokat\",\"emailAddress\":\"Sähköpostiosoite\",\"emailBody\":\"Viesti\",\"emailSubject\":\"Aihe\",\"id\":\"Tunniste\",\"info\":\"Linkin tiedot\",\"langCode\":\"Kielen suunta\",\"langDir\":\"Kielen suunta\",\"langDirLTR\":\"Vasemmalta oikealle (LTR)\",\"langDirRTL\":\"Oikealta vasemmalle (RTL)\",\"menu\":\"Muokkaa linkkiä\",\"name\":\"Nimi\",\"noAnchors\":\"(Ei ankkureita tässä dokumentissa)\",\"noEmail\":\"Kirjoita sähköpostiosoite\",\"noUrl\":\"Linkille on kirjoitettava URL\",\"other\":\"<muu>\",\"popupDependent\":\"Riippuva (Netscape)\",\"popupFeatures\":\"Popup ikkunan ominaisuudet\",\"popupFullScreen\":\"Täysi ikkuna (IE)\",\"popupLeft\":\"Vasemmalta (px)\",\"popupLocationBar\":\"Osoiterivi\",\"popupMenuBar\":\"Valikkorivi\",\"popupResizable\":\"Venytettävä\",\"popupScrollBars\":\"Vierityspalkit\",\"popupStatusBar\":\"Tilarivi\",\"popupToolbar\":\"Vakiopainikkeet\",\"popupTop\":\"Ylhäältä (px)\",\"rel\":\"Suhde\",\"selectAnchor\":\"Valitse ankkuri\",\"styles\":\"Tyyli\",\"tabIndex\":\"Tabulaattori indeksi\",\"target\":\"Kohde\",\"targetFrame\":\"<kehys>\",\"targetFrameName\":\"Kohdekehyksen nimi\",\"targetPopup\":\"<popup ikkuna>\",\"targetPopupName\":\"Popup ikkunan nimi\",\"title\":\"Linkki\",\"toAnchor\":\"Ankkuri tässä sivussa\",\"toEmail\":\"Sähköposti\",\"toUrl\":\"Osoite\",\"toolbar\":\"Lisää linkki/muokkaa linkkiä\",\"type\":\"Linkkityyppi\",\"unlink\":\"Poista linkki\",\"upload\":\"Lisää tiedosto\"},\"list\":{\"bulletedlist\":\"Luettelomerkit\",\"numberedlist\":\"Numerointi\"},\"magicline\":{\"title\":\"Lisää kappale tähän.\"},\"maximize\":{\"maximize\":\"Suurenna\",\"minimize\":\"Pienennä\"},\"pastetext\":{\"button\":\"Liitä tekstinä\",\"title\":\"Liitä tekstinä\"},\"pastefromword\":{\"confirmCleanup\":\"Liittämäsi teksti näyttäisi olevan Word-dokumentista. Haluatko siivota sen ennen liittämistä? (Suositus: Kyllä)\",\"error\":\"Liitetyn tiedon siivoaminen ei onnistunut sisäisen virheen takia\",\"title\":\"Liitä Word-dokumentista\",\"toolbar\":\"Liitä Word-dokumentista\"},\"removeformat\":{\"toolbar\":\"Poista muotoilu\"},\"sourcearea\":{\"toolbar\":\"Koodi\"},\"specialchar\":{\"options\":\"Erikoismerkin ominaisuudet\",\"title\":\"Valitse erikoismerkki\",\"toolbar\":\"Lisää erikoismerkki\"},\"scayt\":{\"about\":\"Tietoja oikoluvusta kirjoitetaessa\",\"aboutTab\":\"Tietoa\",\"addWord\":\"Lisää sana\",\"allCaps\":\"Ohita sanat, jotka on kirjoitettu kokonaan isoilla kirjaimilla\",\"dic_create\":\"Luo\",\"dic_delete\":\"Poista\",\"dic_field_name\":\"Sanakirjan nimi\",\"dic_info\":\"Oletuksena sanakirjat tallennetaan evästeeseen, mutta evästeiden koko on kuitenkin rajallinen. Sanakirjan kasvaessa niin suureksi, ettei se enää mahdu evästeeseen, sanakirja täytyy tallentaa palvelimellemme. Tallentaaksesi sanakirjasi palvelimellemme tulee sinun antaa sille nimi. Jos olet jo tallentanut sanakirjan, anna sen nimi ja klikkaa Palauta-painiketta\",\"dic_rename\":\"Nimeä uudelleen\",\"dic_restore\":\"Palauta\",\"dictionariesTab\":\"Sanakirjat\",\"disable\":\"Poista käytöstä oikoluku kirjoitetaessa\",\"emptyDic\":\"Sanakirjan nimi on annettava.\",\"enable\":\"Ota käyttöön oikoluku kirjoitettaessa\",\"ignore\":\"Ohita\",\"ignoreAll\":\"Ohita kaikki\",\"ignoreDomainNames\":\"Ohita verkkotunnukset\",\"langs\":\"Kielet\",\"languagesTab\":\"Kielet\",\"mixedCase\":\"Ohita sanat, joissa on sekoitettu isoja ja pieniä kirjaimia\",\"mixedWithDigits\":\"Ohita sanat, joissa on numeroita\",\"moreSuggestions\":\"Lisää ehdotuksia\",\"opera_title\":\"Opera ei tue tätä ominaisuutta\",\"options\":\"Asetukset\",\"optionsTab\":\"Asetukset\",\"title\":\"Oikolue kirjoitettaessa\",\"toggle\":\"Vaihda oikoluku kirjoittaessa tilaa\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Tyyli\",\"panelTitle\":\"Muotoilujen tyylit\",\"panelTitle1\":\"Lohkojen tyylit\",\"panelTitle2\":\"Rivinsisäiset tyylit\",\"panelTitle3\":\"Objektien tyylit\"},\"table\":{\"border\":\"Rajan paksuus\",\"caption\":\"Otsikko\",\"cell\":{\"menu\":\"Solu\",\"insertBefore\":\"Lisää solu eteen\",\"insertAfter\":\"Lisää solu perään\",\"deleteCell\":\"Poista solut\",\"merge\":\"Yhdistä solut\",\"mergeRight\":\"Yhdistä oikealla olevan kanssa\",\"mergeDown\":\"Yhdistä alla olevan kanssa\",\"splitHorizontal\":\"Jaa solu vaakasuunnassa\",\"splitVertical\":\"Jaa solu pystysuunnassa\",\"title\":\"Solun ominaisuudet\",\"cellType\":\"Solun tyyppi\",\"rowSpan\":\"Rivin jatkuvuus\",\"colSpan\":\"Solun jatkuvuus\",\"wordWrap\":\"Rivitys\",\"hAlign\":\"Horisontaali kohdistus\",\"vAlign\":\"Vertikaali kohdistus\",\"alignBaseline\":\"Alas (teksti)\",\"bgColor\":\"Taustan väri\",\"borderColor\":\"Reunan väri\",\"data\":\"Data\",\"header\":\"Ylätunniste\",\"yes\":\"Kyllä\",\"no\":\"Ei\",\"invalidWidth\":\"Solun leveyden täytyy olla numero.\",\"invalidHeight\":\"Solun korkeuden täytyy olla numero.\",\"invalidRowSpan\":\"Rivin jatkuvuuden täytyy olla kokonaisluku.\",\"invalidColSpan\":\"Solun jatkuvuuden täytyy olla kokonaisluku.\",\"chooseColor\":\"Valitse\"},\"cellPad\":\"Solujen sisennys\",\"cellSpace\":\"Solujen väli\",\"column\":{\"menu\":\"Sarake\",\"insertBefore\":\"Lisää sarake vasemmalle\",\"insertAfter\":\"Lisää sarake oikealle\",\"deleteColumn\":\"Poista sarakkeet\"},\"columns\":\"Sarakkeet\",\"deleteTable\":\"Poista taulu\",\"headers\":\"Ylätunnisteet\",\"headersBoth\":\"Molemmat\",\"headersColumn\":\"Ensimmäinen sarake\",\"headersNone\":\"Ei\",\"headersRow\":\"Ensimmäinen rivi\",\"invalidBorder\":\"Reunan koon täytyy olla numero.\",\"invalidCellPadding\":\"Solujen sisennyksen täytyy olla numero.\",\"invalidCellSpacing\":\"Solujen välin täytyy olla numero.\",\"invalidCols\":\"Sarakkeiden määrän täytyy olla suurempi kuin 0.\",\"invalidHeight\":\"Taulun korkeuden täytyy olla numero.\",\"invalidRows\":\"Rivien määrän täytyy olla suurempi kuin 0.\",\"invalidWidth\":\"Taulun leveyden täytyy olla numero.\",\"menu\":\"Taulun ominaisuudet\",\"row\":{\"menu\":\"Rivi\",\"insertBefore\":\"Lisää rivi yläpuolelle\",\"insertAfter\":\"Lisää rivi alapuolelle\",\"deleteRow\":\"Poista rivit\"},\"rows\":\"Rivit\",\"summary\":\"Yhteenveto\",\"title\":\"Taulun ominaisuudet\",\"toolbar\":\"Taulu\",\"widthPc\":\"prosenttia\",\"widthPx\":\"pikseliä\",\"widthUnit\":\"leveysyksikkö\"},\"undo\":{\"redo\":\"Toista\",\"undo\":\"Kumoa\"},\"wsc\":{\"btnIgnore\":\"Jätä huomioimatta\",\"btnIgnoreAll\":\"Jätä kaikki huomioimatta\",\"btnReplace\":\"Korvaa\",\"btnReplaceAll\":\"Korvaa kaikki\",\"btnUndo\":\"Kumoa\",\"changeTo\":\"Vaihda\",\"errorLoading\":\"Virhe ladattaessa oikolukupalvelua isännältä: %s.\",\"ieSpellDownload\":\"Oikeinkirjoituksen tarkistusta ei ole asennettu. Haluatko ladata sen nyt?\",\"manyChanges\":\"Tarkistus valmis: %1 sanaa muutettiin\",\"noChanges\":\"Tarkistus valmis: Yhtään sanaa ei muutettu\",\"noMispell\":\"Tarkistus valmis: Ei virheitä\",\"noSuggestions\":\"Ei ehdotuksia\",\"notAvailable\":\"Valitettavasti oikoluku ei ole käytössä tällä hetkellä.\",\"notInDic\":\"Ei sanakirjassa\",\"oneChange\":\"Tarkistus valmis: Yksi sana muutettiin\",\"progress\":\"Tarkistus käynnissä...\",\"title\":\"Oikoluku\",\"toolbar\":\"Tarkista oikeinkirjoitus\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/fo.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['fo']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Trýst ALT og 0 fyri vegleiðing\",\"browseServer\":\"Ambætarakagi\",\"url\":\"URL\",\"protocol\":\"Protokoll\",\"upload\":\"Send til ambætaran\",\"uploadSubmit\":\"Send til ambætaran\",\"image\":\"Myndir\",\"flash\":\"Flash\",\"form\":\"Formur\",\"checkbox\":\"Flugubein\",\"radio\":\"Radioknøttur\",\"textField\":\"Tekstteigur\",\"textarea\":\"Tekstumráði\",\"hiddenField\":\"Fjaldur teigur\",\"button\":\"Knøttur\",\"select\":\"Valskrá\",\"imageButton\":\"Myndaknøttur\",\"notSet\":\"<ikki sett>\",\"id\":\"Id\",\"name\":\"Navn\",\"langDir\":\"Tekstkós\",\"langDirLtr\":\"Frá vinstru til høgru (LTR)\",\"langDirRtl\":\"Frá høgru til vinstru (RTL)\",\"langCode\":\"Málkoda\",\"longDescr\":\"Víðkað URL frágreiðing\",\"cssClass\":\"Typografi klassar\",\"advisoryTitle\":\"Vegleiðandi heiti\",\"cssStyle\":\"Typografi\",\"ok\":\"Góðkent\",\"cancel\":\"Avlýst\",\"close\":\"Lat aftur\",\"preview\":\"Frumsýn\",\"resize\":\"Drag fyri at broyta stødd\",\"generalTab\":\"Generelt\",\"advancedTab\":\"Fjølbroytt\",\"validateNumberFailed\":\"Hetta er ikki eitt tal.\",\"confirmNewPage\":\"Allar ikki goymdar broytingar í hesum innihaldið hvørva. Skal nýggj síða lesast kortini?\",\"confirmCancel\":\"Nakrir valmøguleikar eru broyttir. Ert tú vísur í, at dialogurin skal latast aftur?\",\"options\":\"Options\",\"target\":\"Target\",\"targetNew\":\"Nýtt vindeyga (_blank)\",\"targetTop\":\"Vindeyga ovast (_top)\",\"targetSelf\":\"Sama vindeyga (_self)\",\"targetParent\":\"Upphavligt vindeyga (_parent)\",\"langDirLTR\":\"Frá vinstru til høgru (LTR)\",\"langDirRTL\":\"Frá høgru til vinstru (RTL)\",\"styles\":\"Style\",\"cssClasses\":\"Stylesheet Classes\",\"width\":\"Breidd\",\"height\":\"Hædd\",\"align\":\"Justering\",\"alignLeft\":\"Vinstra\",\"alignRight\":\"Høgra\",\"alignCenter\":\"Miðsett\",\"alignTop\":\"Ovast\",\"alignMiddle\":\"Miðja\",\"alignBottom\":\"Botnur\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Hædd má vera eitt tal.\",\"invalidWidth\":\"Breidd má vera eitt tal.\",\"invalidCssLength\":\"Virðið sett í \\\"%1\\\" feltið má vera eitt positivt tal, við ella uttan gyldugum CSS mátieind (px, %, in, cm, mm, em, ex, pt, ella pc).\",\"invalidHtmlLength\":\"Virðið sett í \\\"%1\\\" feltiðield má vera eitt positivt tal, við ella uttan gyldugum CSS mátieind (px ella %).\",\"invalidInlineStyle\":\"Virði specifiserað fyri inline style má hava eitt ella fleiri pør (tuples) skrivað sum \\\"name : value\\\", hvørt parið sundurskilt við semi-colon.\",\"cssLengthTooltip\":\"Skriva eitt tal fyri eitt virði í pixels ella eitt tal við gyldigum CSS eind (px, %, in, cm, mm, em, ex, pt, ella pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, ikki tøkt</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"Um CKEditor\",\"help\":\"Kekka $1 fyri hjálp.\",\"moreInfo\":\"Licens upplýsingar finnast á heimasíðu okkara:\",\"title\":\"Um CKEditor\",\"userGuide\":\"CKEditor Brúkaravegleiðing\"},\"basicstyles\":{\"bold\":\"Feit skrift\",\"italic\":\"Skráskrift\",\"strike\":\"Yvirstrikað\",\"subscript\":\"Lækkað skrift\",\"superscript\":\"Hækkað skrift\",\"underline\":\"Undirstrikað\"},\"blockquote\":{\"toolbar\":\"Blockquote\"},\"clipboard\":{\"copy\":\"Avrita\",\"copyError\":\"Trygdaruppseting alnótskagans forðar tekstviðgeranum í at avrita tekstin. Vinarliga nýt knappaborðið til at avrita tekstin (Ctrl/Cmd+C).\",\"cut\":\"Kvett\",\"cutError\":\"Trygdaruppseting alnótskagans forðar tekstviðgeranum í at kvetta tekstin. Vinarliga nýt knappaborðið til at kvetta tekstin (Ctrl/Cmd+X).\",\"paste\":\"Innrita\",\"pasteArea\":\"Avritingarumráði\",\"pasteMsg\":\"Vinarliga koyr tekstin í hendan rútin við knappaborðinum (<strong>Ctrl/Cmd+V</strong>) og klikk á <strong>Góðtak</strong>.\",\"securityMsg\":\"Trygdaruppseting alnótskagans forðar tekstviðgeranum í beinleiðis atgongd til avritingarminnið. Tygum mugu royna aftur í hesum rútinum.\",\"title\":\"Innrita\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Lat Toolbar aftur\",\"toolbarExpand\":\"Vís Toolbar\",\"toolbarGroups\":{\"document\":\"Dokument\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editering\",\"forms\":\"Formar\",\"basicstyles\":\"Grundleggjandi Styles\",\"paragraph\":\"Reglubrot\",\"links\":\"Leinkjur\",\"insert\":\"Set inn\",\"styles\":\"Styles\",\"colors\":\"Litir\",\"tools\":\"Tól\"},\"toolbars\":\"Editor toolbars\"},\"elementspath\":{\"eleLabel\":\"Slóð til elementir\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Skriftsnið\",\"panelTitle\":\"Skriftsnið\",\"tag_address\":\"Adressa\",\"tag_div\":\"Vanligt (DIV)\",\"tag_h1\":\"Yvirskrift 1\",\"tag_h2\":\"Yvirskrift 2\",\"tag_h3\":\"Yvirskrift 3\",\"tag_h4\":\"Yvirskrift 4\",\"tag_h5\":\"Yvirskrift 5\",\"tag_h6\":\"Yvirskrift 6\",\"tag_p\":\"Vanligt\",\"tag_pre\":\"Sniðgivið\"},\"horizontalrule\":{\"toolbar\":\"Ger vatnrætta linju\"},\"image\":{\"alertUrl\":\"Rita slóðina til myndina\",\"alt\":\"Alternativur tekstur\",\"border\":\"Bordi\",\"btnUpload\":\"Send til ambætaran\",\"button2Img\":\"Skal valdi myndaknøttur gerast til vanliga mynd?\",\"hSpace\":\"Høgri breddi\",\"img2Button\":\"Skal valda mynd gerast til myndaknøtt?\",\"infoTab\":\"Myndaupplýsingar\",\"linkTab\":\"Tilknýti\",\"lockRatio\":\"Læs lutfallið\",\"menu\":\"Myndaeginleikar\",\"resetSize\":\"Upprunastødd\",\"title\":\"Myndaeginleikar\",\"titleButton\":\"Eginleikar fyri myndaknøtt\",\"upload\":\"Send\",\"urlMissing\":\"URL til mynd manglar.\",\"vSpace\":\"Vinstri breddi\",\"validateBorder\":\"Bordi má vera eitt heiltal.\",\"validateHSpace\":\"HSpace má vera eitt heiltal.\",\"validateVSpace\":\"VSpace má vera eitt heiltal.\"},\"indent\":{\"indent\":\"Økja reglubrotarinntriv\",\"outdent\":\"Minka reglubrotarinntriv\"},\"fakeobjects\":{\"anchor\":\"Anchor\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Fjaldur teigur\",\"iframe\":\"IFrame\",\"unknown\":\"Ókent Object\"},\"link\":{\"acccessKey\":\"Snarvegisknöttur\",\"advanced\":\"Fjølbroytt\",\"advisoryContentType\":\"Vegleiðandi innihaldsslag\",\"advisoryTitle\":\"Vegleiðandi heiti\",\"anchor\":{\"toolbar\":\"Ger/broyt marknastein\",\"menu\":\"Eginleikar fyri marknastein\",\"title\":\"Eginleikar fyri marknastein\",\"name\":\"Heiti marknasteinsins\",\"errorName\":\"Vinarliga rita marknasteinsins heiti\",\"remove\":\"Strika marknastein\"},\"anchorId\":\"Eftir element Id\",\"anchorName\":\"Eftir navni á marknasteini\",\"charset\":\"Atknýtt teknsett\",\"cssClasses\":\"Typografi klassar\",\"emailAddress\":\"Teldupost-adressa\",\"emailBody\":\"Breyðtekstur\",\"emailSubject\":\"Evni\",\"id\":\"Id\",\"info\":\"Tilknýtis upplýsingar\",\"langCode\":\"Tekstkós\",\"langDir\":\"Tekstkós\",\"langDirLTR\":\"Frá vinstru til høgru (LTR)\",\"langDirRTL\":\"Frá høgru til vinstru (RTL)\",\"menu\":\"Broyt tilknýti\",\"name\":\"Navn\",\"noAnchors\":\"(Eingir marknasteinar eru í hesum dokumentið)\",\"noEmail\":\"Vinarliga skriva teldupost-adressu\",\"noUrl\":\"Vinarliga skriva tilknýti (URL)\",\"other\":\"<annað>\",\"popupDependent\":\"Bundið (Netscape)\",\"popupFeatures\":\"Popup vindeygans víðkaðu eginleikar\",\"popupFullScreen\":\"Fullur skermur (IE)\",\"popupLeft\":\"Frástøða frá vinstru\",\"popupLocationBar\":\"Adressulinja\",\"popupMenuBar\":\"Skrábjálki\",\"popupResizable\":\"Stødd kann broytast\",\"popupScrollBars\":\"Rullibjálki\",\"popupStatusBar\":\"Støðufrágreiðingarbjálki\",\"popupToolbar\":\"Amboðsbjálki\",\"popupTop\":\"Frástøða frá íerva\",\"rel\":\"Relatión\",\"selectAnchor\":\"Vel ein marknastein\",\"styles\":\"Typografi\",\"tabIndex\":\"Tabulator indeks\",\"target\":\"Target\",\"targetFrame\":\"<ramma>\",\"targetFrameName\":\"Vís navn vindeygans\",\"targetPopup\":\"<popup vindeyga>\",\"targetPopupName\":\"Popup vindeygans navn\",\"title\":\"Tilknýti\",\"toAnchor\":\"Tilknýti til marknastein í tekstinum\",\"toEmail\":\"Teldupostur\",\"toUrl\":\"URL\",\"toolbar\":\"Ger/broyt tilknýti\",\"type\":\"Tilknýtisslag\",\"unlink\":\"Strika tilknýti\",\"upload\":\"Send til ambætaran\"},\"list\":{\"bulletedlist\":\"Punktmerktur listi\",\"numberedlist\":\"Talmerktur listi\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maksimera\",\"minimize\":\"Minimera\"},\"pastetext\":{\"button\":\"Innrita som reinan tekst\",\"title\":\"Innrita som reinan tekst\"},\"pastefromword\":{\"confirmCleanup\":\"Teksturin, tú roynir at seta inn, sýnist at stava frá Word. Skal teksturin reinsast fyrst?\",\"error\":\"Tað eydnaðist ikki at reinsa tekstin vegna ein internan feil\",\"title\":\"Innrita frá Word\",\"toolbar\":\"Innrita frá Word\"},\"removeformat\":{\"toolbar\":\"Strika sniðgeving\"},\"sourcearea\":{\"toolbar\":\"Kelda\"},\"specialchar\":{\"options\":\"Møguleikar við serteknum\",\"title\":\"Vel sertekn\",\"toolbar\":\"Set inn sertekn\"},\"scayt\":{\"about\":\"Um SCAYT\",\"aboutTab\":\"Um\",\"addWord\":\"Legg orð afturat\",\"allCaps\":\"Loyp orð við bert stórum stavum um\",\"dic_create\":\"Upprætta nýggja\",\"dic_delete\":\"Strika\",\"dic_field_name\":\"Orðabókanavn\",\"dic_info\":\"Upprunaliga er brúkara-orðabókin goymd í eini cookie í tínum egna kaga. Men hesar cookies eru avmarkaðar í stødd. Tá brúkara-orðabókin veksur seg ov stóra til eina cookie, so er møguligt at goyma hana á ambætara okkara. Fyri at goyma persónligu orðabókina á ambætaranum eigur tú at velja eitt navn til tína skuffu. Hevur tú longu goymt eina orðabók, so vinarliga skriva navnið og klikk á knøttin Endurskapa.\",\"dic_rename\":\"Broyt\",\"dic_restore\":\"Endurskapa\",\"dictionariesTab\":\"Orðabøkur\",\"disable\":\"Nokta SCAYT\",\"emptyDic\":\"Heiti á orðabók eigur ikki at vera tómt.\",\"enable\":\"Loyv SCAYT\",\"ignore\":\"Ignorera\",\"ignoreAll\":\"Ignorera alt\",\"ignoreDomainNames\":\"loyp økisnøvn um\",\"langs\":\"Tungumál\",\"languagesTab\":\"Tungumál\",\"mixedCase\":\"Loyp orð við blandaðum smáum og stórum stavum um\",\"mixedWithDigits\":\"Loyp orð við tølum um\",\"moreSuggestions\":\"Fleiri tilráðingar\",\"opera_title\":\"Ikki stuðlað í Opera\",\"options\":\"Uppseting\",\"optionsTab\":\"Uppseting\",\"title\":\"Kanna stavseting, meðan tú skrivar\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Typografi\",\"panelTitle\":\"Formatterings stílir\",\"panelTitle1\":\"Blokk stílir\",\"panelTitle2\":\"Inline stílir\",\"panelTitle3\":\"Object stílir\"},\"table\":{\"border\":\"Bordabreidd\",\"caption\":\"Tabellfrágreiðing\",\"cell\":{\"menu\":\"Meski\",\"insertBefore\":\"Set meska inn áðrenn\",\"insertAfter\":\"Set meska inn aftaná\",\"deleteCell\":\"Strika meskar\",\"merge\":\"Flætta meskar\",\"mergeRight\":\"Flætta meskar til høgru\",\"mergeDown\":\"Flætta saman\",\"splitHorizontal\":\"Kloyv meska vatnrætt\",\"splitVertical\":\"Kloyv meska loddrætt\",\"title\":\"Mesku eginleikar\",\"cellType\":\"Mesku slag\",\"rowSpan\":\"Ræð spenni\",\"colSpan\":\"Kolonnu spenni\",\"wordWrap\":\"Orðkloyving\",\"hAlign\":\"Horisontal plasering\",\"vAlign\":\"Loddrøtt plasering\",\"alignBaseline\":\"Basislinja\",\"bgColor\":\"Bakgrundslitur\",\"borderColor\":\"Bordalitur\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Ja\",\"no\":\"Nei\",\"invalidWidth\":\"Meskubreidd má vera eitt tal.\",\"invalidHeight\":\"Meskuhædd má vera eitt tal.\",\"invalidRowSpan\":\"Raðspennið má vera eitt heiltal.\",\"invalidColSpan\":\"Kolonnuspennið má vera eitt heiltal.\",\"chooseColor\":\"Vel\"},\"cellPad\":\"Meskubreddi\",\"cellSpace\":\"Fjarstøða millum meskar\",\"column\":{\"menu\":\"Kolonna\",\"insertBefore\":\"Set kolonnu inn áðrenn\",\"insertAfter\":\"Set kolonnu inn aftaná\",\"deleteColumn\":\"Strika kolonnur\"},\"columns\":\"Kolonnur\",\"deleteTable\":\"Strika tabell\",\"headers\":\"Yvirskriftir\",\"headersBoth\":\"Báðir\",\"headersColumn\":\"Fyrsta kolonna\",\"headersNone\":\"Eingin\",\"headersRow\":\"Fyrsta rað\",\"invalidBorder\":\"Borda-stødd má vera eitt tal.\",\"invalidCellPadding\":\"Cell padding má vera eitt tal.\",\"invalidCellSpacing\":\"Cell spacing má vera eitt tal.\",\"invalidCols\":\"Talið av kolonnum má vera eitt tal størri enn 0.\",\"invalidHeight\":\"Tabell-hædd má vera eitt tal.\",\"invalidRows\":\"Talið av røðum má vera eitt tal størri enn 0.\",\"invalidWidth\":\"Tabell-breidd má vera eitt tal.\",\"menu\":\"Eginleikar fyri tabell\",\"row\":{\"menu\":\"Rað\",\"insertBefore\":\"Set rað inn áðrenn\",\"insertAfter\":\"Set rað inn aftaná\",\"deleteRow\":\"Strika røðir\"},\"rows\":\"Røðir\",\"summary\":\"Samandráttur\",\"title\":\"Eginleikar fyri tabell\",\"toolbar\":\"Tabell\",\"widthPc\":\"prosent\",\"widthPx\":\"pixels\",\"widthUnit\":\"breiddar unit\"},\"undo\":{\"redo\":\"Vend aftur\",\"undo\":\"Angra\"},\"wsc\":{\"btnIgnore\":\"Forfjóna\",\"btnIgnoreAll\":\"Forfjóna alt\",\"btnReplace\":\"Yvirskriva\",\"btnReplaceAll\":\"Yvirskriva alt\",\"btnUndo\":\"Angra\",\"changeTo\":\"Broyt til\",\"errorLoading\":\"Feilur við innlesing av application service host: %s.\",\"ieSpellDownload\":\"Rættstavarin er ikki tøkur í tekstviðgeranum. Vilt tú heinta hann nú?\",\"manyChanges\":\"Rættstavarin liðugur: %1 orð broytt\",\"noChanges\":\"Rættstavarin liðugur: Einki orð varð broytt\",\"noMispell\":\"Rættstavarin liðugur: Eingin feilur funnin\",\"noSuggestions\":\"- Einki uppskot -\",\"notAvailable\":\"Tíverri, ikki tøkt í løtuni.\",\"notInDic\":\"Finst ikki í orðabókini\",\"oneChange\":\"Rættstavarin liðugur: Eitt orð er broytt\",\"progress\":\"Rættstavarin arbeiðir...\",\"title\":\"Kanna stavseting\",\"toolbar\":\"Kanna stavseting\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/fr-ca.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['fr-ca']={\"editor\":\"Éditeur de texte enrichi\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Appuyez sur 0 pour de l'aide\",\"browseServer\":\"Parcourir le serveur\",\"url\":\"URL\",\"protocol\":\"Protocole\",\"upload\":\"Envoyer\",\"uploadSubmit\":\"Envoyer au serveur\",\"image\":\"Image\",\"flash\":\"Animation Flash\",\"form\":\"Formulaire\",\"checkbox\":\"Case à cocher\",\"radio\":\"Bouton radio\",\"textField\":\"Champ texte\",\"textarea\":\"Zone de texte\",\"hiddenField\":\"Champ caché\",\"button\":\"Bouton\",\"select\":\"Liste déroulante\",\"imageButton\":\"Bouton image\",\"notSet\":\"<Par défaut>\",\"id\":\"Id\",\"name\":\"Nom\",\"langDir\":\"Sens d'écriture\",\"langDirLtr\":\"De gauche à droite (LTR)\",\"langDirRtl\":\"De droite à gauche (RTL)\",\"langCode\":\"Code langue\",\"longDescr\":\"URL de description longue\",\"cssClass\":\"Classes CSS\",\"advisoryTitle\":\"Titre\",\"cssStyle\":\"Style\",\"ok\":\"OK\",\"cancel\":\"Annuler\",\"close\":\"Fermer\",\"preview\":\"Aperçu\",\"resize\":\"Redimensionner\",\"generalTab\":\"Général\",\"advancedTab\":\"Avancé\",\"validateNumberFailed\":\"Cette valeur n'est pas un nombre.\",\"confirmNewPage\":\"Les changements non sauvegardés seront perdus. Êtes-vous certain de vouloir charger une nouvelle page?\",\"confirmCancel\":\"Certaines options ont été modifiées.  Êtes-vous certain de vouloir fermer?\",\"options\":\"Options\",\"target\":\"Cible\",\"targetNew\":\"Nouvelle fenêtre (_blank)\",\"targetTop\":\"Fenêtre supérieur (_top)\",\"targetSelf\":\"Cette fenêtre (_self)\",\"targetParent\":\"Fenêtre parent (_parent)\",\"langDirLTR\":\"De gauche à droite (LTR)\",\"langDirRTL\":\"De droite à gauche (RTL)\",\"styles\":\"Style\",\"cssClasses\":\"Classe CSS\",\"width\":\"Largeur\",\"height\":\"Hauteur\",\"align\":\"Alignement\",\"alignLeft\":\"Gauche\",\"alignRight\":\"Droite\",\"alignCenter\":\"Centré\",\"alignTop\":\"Haut\",\"alignMiddle\":\"Milieu\",\"alignBottom\":\"Bas\",\"invalidValue\":\"Valeur invalide.\",\"invalidHeight\":\"La hauteur doit être un nombre.\",\"invalidWidth\":\"La largeur doit être un nombre.\",\"invalidCssLength\":\"La valeur spécifiée pour le champ \\\"%1\\\" doit être un nombre positif avec ou sans unité de mesure CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).\",\"invalidHtmlLength\":\"La valeur spécifiée pour le champ \\\"%1\\\" doit être un nombre positif avec ou sans unité de mesure HTML valide (px ou %).\",\"invalidInlineStyle\":\"La valeur spécifiée pour le style intégré doit être composée d'un ou plusieurs couples de valeur au format \\\"nom : valeur\\\", separés par des points-virgules.\",\"cssLengthTooltip\":\"Entrer un nombre pour la valeur en pixel ou un nombre avec une unité CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, indisponible</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Tous droits réservés.\",\"dlgTitle\":\"À propos de CKEditor\",\"help\":\"Consulter $1 pour l'aide.\",\"moreInfo\":\"Pour les informations de licence, consulter notre site internet:\",\"title\":\"À propos de CKEditor\",\"userGuide\":\"Guide utilisateur de CKEditor\"},\"basicstyles\":{\"bold\":\"Gras\",\"italic\":\"Italique\",\"strike\":\"Barré\",\"subscript\":\"Indice\",\"superscript\":\"Exposant\",\"underline\":\"Souligné\"},\"blockquote\":{\"toolbar\":\"Citation\"},\"clipboard\":{\"copy\":\"Copier\",\"copyError\":\"Les paramètres de sécurité de votre navigateur empêchent l'éditeur de copier automatiquement vos données. Veuillez utiliser les équivalents claviers (Ctrl/Cmd+C).\",\"cut\":\"Couper\",\"cutError\":\"Les paramètres de sécurité de votre navigateur empêchent l'éditeur de couper automatiquement vos données. Veuillez utiliser les équivalents claviers (Ctrl/Cmd+X).\",\"paste\":\"Coller\",\"pasteArea\":\"Coller la zone\",\"pasteMsg\":\"Veuillez coller dans la zone ci-dessous en utilisant le clavier (<STRONG>Ctrl/Cmd+V</STRONG>) et appuyer sur <STRONG>OK</STRONG>.\",\"securityMsg\":\"A cause des paramètres de sécurité de votre navigateur, l'éditeur ne peut accéder au presse-papier directement. Vous devez coller à nouveau le contenu dans cette fenêtre.\",\"title\":\"Coller\"},\"contextmenu\":{\"options\":\"Options du menu contextuel\"},\"toolbar\":{\"toolbarCollapse\":\"Enrouler la barre d'outils\",\"toolbarExpand\":\"Dérouler la barre d'outils\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Presse papier/Annuler\",\"editing\":\"Édition\",\"forms\":\"Formulaires\",\"basicstyles\":\"Styles de base\",\"paragraph\":\"Paragraphe\",\"links\":\"Liens\",\"insert\":\"Insérer\",\"styles\":\"Styles\",\"colors\":\"Couleurs\",\"tools\":\"Outils\"},\"toolbars\":\"Barre d'outils de l'éditeur\"},\"elementspath\":{\"eleLabel\":\"Chemin d'éléments\",\"eleTitle\":\"element %1\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Format de paragraphe\",\"tag_address\":\"Adresse\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"En-tête 1\",\"tag_h2\":\"En-tête 2\",\"tag_h3\":\"En-tête 3\",\"tag_h4\":\"En-tête 4\",\"tag_h5\":\"En-tête 5\",\"tag_h6\":\"En-tête 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formaté\"},\"horizontalrule\":{\"toolbar\":\"Insérer un séparateur horizontale\"},\"image\":{\"alertUrl\":\"Veuillez saisir l'URL de l'image\",\"alt\":\"Texte alternatif\",\"border\":\"Bordure\",\"btnUpload\":\"Envoyer sur le serveur\",\"button2Img\":\"Désirez-vous transformer l'image sélectionnée en image simple?\",\"hSpace\":\"Espacement horizontal\",\"img2Button\":\"Désirez-vous transformer l'image sélectionnée en bouton image?\",\"infoTab\":\"Informations sur l'image\",\"linkTab\":\"Lien\",\"lockRatio\":\"Verrouiller les proportions\",\"menu\":\"Propriétés de l'image\",\"resetSize\":\"Taille originale\",\"title\":\"Propriétés de l'image\",\"titleButton\":\"Propriétés du bouton image\",\"upload\":\"Téléverser\",\"urlMissing\":\"L'URL de la source de l'image est manquant.\",\"vSpace\":\"Espacement vertical\",\"validateBorder\":\"La bordure doit être un entier.\",\"validateHSpace\":\"L'espacement horizontal doit être un entier.\",\"validateVSpace\":\"L'espacement vertical doit être un entier.\"},\"indent\":{\"indent\":\"Augmenter le retrait\",\"outdent\":\"Diminuer le retrait\"},\"fakeobjects\":{\"anchor\":\"Ancre\",\"flash\":\"Animation Flash\",\"hiddenfield\":\"Champ caché\",\"iframe\":\"IFrame\",\"unknown\":\"Objet inconnu\"},\"link\":{\"acccessKey\":\"Touche d'accessibilité\",\"advanced\":\"Avancé\",\"advisoryContentType\":\"Type de contenu\",\"advisoryTitle\":\"Description\",\"anchor\":{\"toolbar\":\"Ancre\",\"menu\":\"Modifier l'ancre\",\"title\":\"Propriétés de l'ancre\",\"name\":\"Nom de l'ancre\",\"errorName\":\"Veuillez saisir le nom de l'ancre\",\"remove\":\"Supprimer l'ancre\"},\"anchorId\":\"Par ID\",\"anchorName\":\"Par nom\",\"charset\":\"Encodage de la cible\",\"cssClasses\":\"Classes CSS\",\"emailAddress\":\"Courriel\",\"emailBody\":\"Corps du message\",\"emailSubject\":\"Objet du message\",\"id\":\"ID\",\"info\":\"Informations sur le lien\",\"langCode\":\"Code de langue\",\"langDir\":\"Sens d'écriture\",\"langDirLTR\":\"De gauche à droite (LTR)\",\"langDirRTL\":\"De droite à gauche (RTL)\",\"menu\":\"Modifier le lien\",\"name\":\"Nom\",\"noAnchors\":\"(Pas d'ancre disponible dans le document)\",\"noEmail\":\"Veuillez saisir le courriel\",\"noUrl\":\"Veuillez saisir l'URL\",\"other\":\"<autre>\",\"popupDependent\":\"Dépendante (Netscape)\",\"popupFeatures\":\"Caractéristiques de la fenêtre popup\",\"popupFullScreen\":\"Plein écran (IE)\",\"popupLeft\":\"Position de la gauche\",\"popupLocationBar\":\"Barre d'adresse\",\"popupMenuBar\":\"Barre de menu\",\"popupResizable\":\"Redimensionnable\",\"popupScrollBars\":\"Barres de défilement\",\"popupStatusBar\":\"Barre d'état\",\"popupToolbar\":\"Barre d'outils\",\"popupTop\":\"Position à partir du haut\",\"rel\":\"Relation\",\"selectAnchor\":\"Sélectionner une ancre\",\"styles\":\"Style\",\"tabIndex\":\"Ordre de tabulation\",\"target\":\"Destination\",\"targetFrame\":\"<Cadre>\",\"targetFrameName\":\"Nom du cadre de destination\",\"targetPopup\":\"<fenêtre popup>\",\"targetPopupName\":\"Nom de la fenêtre popup\",\"title\":\"Lien\",\"toAnchor\":\"Ancre dans cette page\",\"toEmail\":\"Courriel\",\"toUrl\":\"URL\",\"toolbar\":\"Lien\",\"type\":\"Type de lien\",\"unlink\":\"Supprimer le lien\",\"upload\":\"Téléverser\"},\"list\":{\"bulletedlist\":\"Liste à puces\",\"numberedlist\":\"Liste numérotée\"},\"magicline\":{\"title\":\"Insérer le paragraphe ici\"},\"maximize\":{\"maximize\":\"Maximizer\",\"minimize\":\"Minimizer\"},\"pastetext\":{\"button\":\"Coller comme texte\",\"title\":\"Coller comme texte\"},\"pastefromword\":{\"confirmCleanup\":\"Le texte que vous tentez de coller semble provenir de Word.  Désirez vous le nettoyer avant de coller?\",\"error\":\"Il n'a pas été possible de nettoyer les données collées du à une erreur interne\",\"title\":\"Coller de Word\",\"toolbar\":\"Coller de Word\"},\"removeformat\":{\"toolbar\":\"Supprimer le formatage\"},\"sourcearea\":{\"toolbar\":\"Source\"},\"specialchar\":{\"options\":\"Option des caractères spéciaux\",\"title\":\"Sélectionner un caractère spécial\",\"toolbar\":\"Insérer un caractère spécial\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Styles\",\"panelTitle\":\"Styles de formattage\",\"panelTitle1\":\"Styles de block\",\"panelTitle2\":\"Styles en ligne\",\"panelTitle3\":\"Styles d'objet\"},\"table\":{\"border\":\"Taille de la bordure\",\"caption\":\"Titre\",\"cell\":{\"menu\":\"Cellule\",\"insertBefore\":\"Insérer une cellule avant\",\"insertAfter\":\"Insérer une cellule après\",\"deleteCell\":\"Supprimer des cellules\",\"merge\":\"Fusionner les cellules\",\"mergeRight\":\"Fusionner à droite\",\"mergeDown\":\"Fusionner en bas\",\"splitHorizontal\":\"Scinder la cellule horizontalement\",\"splitVertical\":\"Scinder la cellule verticalement\",\"title\":\"Propriétés de la cellule\",\"cellType\":\"Type de cellule\",\"rowSpan\":\"Fusion de lignes\",\"colSpan\":\"Fusion de colonnes\",\"wordWrap\":\"Retour à la ligne\",\"hAlign\":\"Alignement horizontal\",\"vAlign\":\"Alignement vertical\",\"alignBaseline\":\"Bas du texte\",\"bgColor\":\"Couleur d'arrière plan\",\"borderColor\":\"Couleur de bordure\",\"data\":\"Données\",\"header\":\"En-tête\",\"yes\":\"Oui\",\"no\":\"Non\",\"invalidWidth\":\"La largeur de cellule doit être un nombre.\",\"invalidHeight\":\"La hauteur de cellule doit être un nombre.\",\"invalidRowSpan\":\"La fusion de lignes doit être un nombre entier.\",\"invalidColSpan\":\"La fusion de colonnes doit être un nombre entier.\",\"chooseColor\":\"Sélectionner\"},\"cellPad\":\"Marge interne des cellules\",\"cellSpace\":\"Espacement des cellules\",\"column\":{\"menu\":\"Colonne\",\"insertBefore\":\"Insérer une colonne avant\",\"insertAfter\":\"Insérer une colonne après\",\"deleteColumn\":\"Supprimer des colonnes\"},\"columns\":\"Colonnes\",\"deleteTable\":\"Supprimer le tableau\",\"headers\":\"En-têtes\",\"headersBoth\":\"Les deux.\",\"headersColumn\":\"Première colonne\",\"headersNone\":\"Aucun\",\"headersRow\":\"Première ligne\",\"invalidBorder\":\"La taille de bordure doit être un nombre.\",\"invalidCellPadding\":\"La marge interne des cellules doit être un nombre positif.\",\"invalidCellSpacing\":\"L'espacement des cellules doit être un nombre positif.\",\"invalidCols\":\"Le nombre de colonnes doit être supérieur à 0.\",\"invalidHeight\":\"La hauteur du tableau doit être un nombre.\",\"invalidRows\":\"Le nombre de lignes doit être supérieur à 0.\",\"invalidWidth\":\"La largeur du tableau doit être un nombre.\",\"menu\":\"Propriétés du tableau\",\"row\":{\"menu\":\"Ligne\",\"insertBefore\":\"Insérer une ligne avant\",\"insertAfter\":\"Insérer une ligne après\",\"deleteRow\":\"Supprimer des lignes\"},\"rows\":\"Lignes\",\"summary\":\"Résumé\",\"title\":\"Propriétés du tableau\",\"toolbar\":\"Tableau\",\"widthPc\":\"pourcentage\",\"widthPx\":\"pixels\",\"widthUnit\":\"unité de largeur\"},\"undo\":{\"redo\":\"Refaire\",\"undo\":\"Annuler\"},\"wsc\":{\"btnIgnore\":\"Ignorer\",\"btnIgnoreAll\":\"Ignorer tout\",\"btnReplace\":\"Remplacer\",\"btnReplaceAll\":\"Remplacer tout\",\"btnUndo\":\"Annuler\",\"changeTo\":\"Changer en\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Le Correcteur d'orthographe n'est pas installé. Souhaitez-vous le télécharger maintenant?\",\"manyChanges\":\"Vérification d'orthographe terminée: %1 mots modifiés\",\"noChanges\":\"Vérification d'orthographe terminée: Pas de modifications\",\"noMispell\":\"Vérification d'orthographe terminée: pas d'erreur trouvée\",\"noSuggestions\":\"- Pas de suggestion -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Pas dans le dictionnaire\",\"oneChange\":\"Vérification d'orthographe terminée: Un mot modifié\",\"progress\":\"Vérification d'orthographe en cours...\",\"title\":\"Spell Check\",\"toolbar\":\"Orthographe\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/fr.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['fr']={\"editor\":\"Éditeur de Texte Enrichi\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Appuyez sur ALT-0 pour l'aide\",\"browseServer\":\"Explorer le serveur\",\"url\":\"URL\",\"protocol\":\"Protocole\",\"upload\":\"Envoyer\",\"uploadSubmit\":\"Envoyer sur le serveur\",\"image\":\"Image\",\"flash\":\"Flash\",\"form\":\"Formulaire\",\"checkbox\":\"Case à cocher\",\"radio\":\"Bouton Radio\",\"textField\":\"Champ texte\",\"textarea\":\"Zone de texte\",\"hiddenField\":\"Champ caché\",\"button\":\"Bouton\",\"select\":\"Liste déroulante\",\"imageButton\":\"Bouton image\",\"notSet\":\"<non défini>\",\"id\":\"Id\",\"name\":\"Nom\",\"langDir\":\"Sens d'écriture\",\"langDirLtr\":\"Gauche à droite (LTR)\",\"langDirRtl\":\"Droite à gauche (RTL)\",\"langCode\":\"Code de langue\",\"longDescr\":\"URL de description longue (longdesc => malvoyant)\",\"cssClass\":\"Classe CSS\",\"advisoryTitle\":\"Description (title)\",\"cssStyle\":\"Style\",\"ok\":\"OK\",\"cancel\":\"Annuler\",\"close\":\"Fermer\",\"preview\":\"Aperçu\",\"resize\":\"Déplacer pour modifier la taille\",\"generalTab\":\"Général\",\"advancedTab\":\"Avancé\",\"validateNumberFailed\":\"Cette valeur n'est pas un nombre.\",\"confirmNewPage\":\"Les changements non sauvegardés seront perdus. Êtes-vous sûr de vouloir charger une nouvelle page?\",\"confirmCancel\":\"Certaines options ont été modifiées. Êtes-vous sûr de vouloir fermer?\",\"options\":\"Options\",\"target\":\"Cible (Target)\",\"targetNew\":\"Nouvelle fenêtre (_blank)\",\"targetTop\":\"Fenêtre supérieure (_top)\",\"targetSelf\":\"Même fenêtre (_self)\",\"targetParent\":\"Fenêtre parent (_parent)\",\"langDirLTR\":\"Gauche à Droite (LTR)\",\"langDirRTL\":\"Droite à Gauche (RTL)\",\"styles\":\"Style\",\"cssClasses\":\"Classes de style\",\"width\":\"Largeur\",\"height\":\"Hauteur\",\"align\":\"Alignement\",\"alignLeft\":\"Gauche\",\"alignRight\":\"Droite\",\"alignCenter\":\"Centré\",\"alignTop\":\"Haut\",\"alignMiddle\":\"Milieu\",\"alignBottom\":\"Bas\",\"invalidValue\":\"Valeur incorrecte.\",\"invalidHeight\":\"La hauteur doit être un nombre.\",\"invalidWidth\":\"La largeur doit être un nombre.\",\"invalidCssLength\":\"La valeur spécifiée pour le champ \\\"%1\\\" doit être un nombre positif avec ou sans unité de mesure CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).\",\"invalidHtmlLength\":\"La valeur spécifiée pour le champ \\\"%1\\\" doit être un nombre positif avec ou sans unité de mesure HTML valide (px ou %).\",\"invalidInlineStyle\":\"La valeur spécifiée pour le style inline doit être composée d'un ou plusieurs couples de valeur au format \\\"nom : valeur\\\", separés par des points-virgules.\",\"cssLengthTooltip\":\"Entrer un nombre pour une valeur en pixels ou un nombre avec une unité de mesure CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, Indisponible</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Tous droits réservés.\",\"dlgTitle\":\"À propos de CKEditor\",\"help\":\"Consulter $1 pour l'aide.\",\"moreInfo\":\"Pour les informations de licence, veuillez visiter notre site web:\",\"title\":\"À propos de CKEditor\",\"userGuide\":\"Guide de l'utilisateur CKEditor en anglais\"},\"basicstyles\":{\"bold\":\"Gras\",\"italic\":\"Italique\",\"strike\":\"Barré\",\"subscript\":\"Indice\",\"superscript\":\"Exposant\",\"underline\":\"Souligné\"},\"blockquote\":{\"toolbar\":\"Citation\"},\"clipboard\":{\"copy\":\"Copier\",\"copyError\":\"Les paramètres de sécurité de votre navigateur ne permettent pas à l'éditeur d'exécuter automatiquement des opérations de copie. Veuillez utiliser le raccourci clavier (Ctrl/Cmd+C).\",\"cut\":\"Couper\",\"cutError\":\"Les paramètres de sécurité de votre navigateur ne permettent pas à l'éditeur d'exécuter automatiquement l'opération \\\"couper\\\". Veuillez utiliser le raccourci clavier (Ctrl/Cmd+X).\",\"paste\":\"Coller\",\"pasteArea\":\"Coller la zone\",\"pasteMsg\":\"Veuillez coller le texte dans la zone suivante en utilisant le raccourci clavier (<strong>Ctrl/Cmd+V</strong>) et cliquez sur OK.\",\"securityMsg\":\"A cause des paramètres de sécurité de votre navigateur, l'éditeur n'est pas en mesure d'accéder directement à vos données contenues dans le presse-papier. Vous devriez réessayer de coller les données dans la fenêtre.\",\"title\":\"Coller\"},\"contextmenu\":{\"options\":\"Options du menu contextuel\"},\"toolbar\":{\"toolbarCollapse\":\"Enrouler la barre d'outils\",\"toolbarExpand\":\"Dérouler la barre d'outils\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Presse-papier/Défaire\",\"editing\":\"Editer\",\"forms\":\"Formulaires\",\"basicstyles\":\"Styles de base\",\"paragraph\":\"Paragraphe\",\"links\":\"Liens\",\"insert\":\"Insérer\",\"styles\":\"Styles\",\"colors\":\"Couleurs\",\"tools\":\"Outils\"},\"toolbars\":\"Barre d'outils de l'éditeur\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 éléments\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Format de paragraphe\",\"tag_address\":\"Adresse\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Titre 1\",\"tag_h2\":\"Titre 2\",\"tag_h3\":\"Titre 3\",\"tag_h4\":\"Titre 4\",\"tag_h5\":\"Titre 5\",\"tag_h6\":\"Titre 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formaté\"},\"horizontalrule\":{\"toolbar\":\"Ligne horizontale\"},\"image\":{\"alertUrl\":\"Veuillez entrer l'adresse de l'image\",\"alt\":\"Texte de remplacement\",\"border\":\"Bordure\",\"btnUpload\":\"Envoyer sur le serveur\",\"button2Img\":\"Voulez-vous transformer le bouton image sélectionné en simple image?\",\"hSpace\":\"Espacement horizontal\",\"img2Button\":\"Voulez-vous transformer l'image en bouton image?\",\"infoTab\":\"Informations sur l'image\",\"linkTab\":\"Lien\",\"lockRatio\":\"Conserver les proportions\",\"menu\":\"Propriétés de l'image\",\"resetSize\":\"Taille d'origine\",\"title\":\"Propriétés de l'image\",\"titleButton\":\"Propriétés du bouton image\",\"upload\":\"Envoyer\",\"urlMissing\":\"L'adresse source de l'image est manquante.\",\"vSpace\":\"Espacement vertical\",\"validateBorder\":\"Bordure doit être un entier.\",\"validateHSpace\":\"HSpace doit être un entier.\",\"validateVSpace\":\"VSpace doit être un entier.\"},\"indent\":{\"indent\":\"Augmenter le retrait (tabulation)\",\"outdent\":\"Diminuer le retrait (tabulation)\"},\"fakeobjects\":{\"anchor\":\"Ancre\",\"flash\":\"Animation Flash\",\"hiddenfield\":\"Champ caché\",\"iframe\":\"IFrame\",\"unknown\":\"Objet inconnu\"},\"link\":{\"acccessKey\":\"Touche d'accessibilité\",\"advanced\":\"Avancé\",\"advisoryContentType\":\"Type de contenu (ex: text/html)\",\"advisoryTitle\":\"Description (title)\",\"anchor\":{\"toolbar\":\"Ancre\",\"menu\":\"Editer l'ancre\",\"title\":\"Propriétés de l'ancre\",\"name\":\"Nom de l'ancre\",\"errorName\":\"Veuillez entrer le nom de l'ancre.\",\"remove\":\"Supprimer l'ancre\"},\"anchorId\":\"Par ID d'élément\",\"anchorName\":\"Par nom d'ancre\",\"charset\":\"Charset de la cible\",\"cssClasses\":\"Classe CSS\",\"emailAddress\":\"Adresse E-Mail\",\"emailBody\":\"Corps du message\",\"emailSubject\":\"Sujet du message\",\"id\":\"Id\",\"info\":\"Infos sur le lien\",\"langCode\":\"Code de langue\",\"langDir\":\"Sens d'écriture\",\"langDirLTR\":\"Gauche à droite\",\"langDirRTL\":\"Droite à gauche\",\"menu\":\"Editer le lien\",\"name\":\"Nom\",\"noAnchors\":\"(Aucune ancre disponible dans ce document)\",\"noEmail\":\"Veuillez entrer l'adresse e-mail\",\"noUrl\":\"Veuillez entrer l'adresse du lien\",\"other\":\"<autre>\",\"popupDependent\":\"Dépendante (Netscape)\",\"popupFeatures\":\"Options de la fenêtre popup\",\"popupFullScreen\":\"Plein écran (IE)\",\"popupLeft\":\"Position gauche\",\"popupLocationBar\":\"Barre d'adresse\",\"popupMenuBar\":\"Barre de menu\",\"popupResizable\":\"Redimensionnable\",\"popupScrollBars\":\"Barres de défilement\",\"popupStatusBar\":\"Barre de status\",\"popupToolbar\":\"Barre d'outils\",\"popupTop\":\"Position haute\",\"rel\":\"Relation\",\"selectAnchor\":\"Sélectionner l'ancre\",\"styles\":\"Style\",\"tabIndex\":\"Index de tabulation\",\"target\":\"Cible\",\"targetFrame\":\"<cadre>\",\"targetFrameName\":\"Nom du Cadre destination\",\"targetPopup\":\"<fenêtre popup>\",\"targetPopupName\":\"Nom de la fenêtre popup\",\"title\":\"Lien\",\"toAnchor\":\"Transformer le lien en ancre dans le texte\",\"toEmail\":\"E-mail\",\"toUrl\":\"URL\",\"toolbar\":\"Lien\",\"type\":\"Type de lien\",\"unlink\":\"Supprimer le lien\",\"upload\":\"Envoyer\"},\"list\":{\"bulletedlist\":\"Insérer/Supprimer la liste à puces\",\"numberedlist\":\"Insérer/Supprimer la liste numérotée\"},\"magicline\":{\"title\":\"Insérez un paragraphe ici\"},\"maximize\":{\"maximize\":\"Agrandir\",\"minimize\":\"Minimiser\"},\"pastetext\":{\"button\":\"Coller comme texte sans mise en forme\",\"title\":\"Coller comme texte sans mise en forme\"},\"pastefromword\":{\"confirmCleanup\":\"Le texte à coller semble provenir de Word. Désirez-vous le nettoyer avant de coller?\",\"error\":\"Il n'a pas été possible de nettoyer les données collées à la suite d'une erreur interne.\",\"title\":\"Coller depuis Word\",\"toolbar\":\"Coller depuis Word\"},\"removeformat\":{\"toolbar\":\"Supprimer la mise en forme\"},\"sourcearea\":{\"toolbar\":\"Source\"},\"specialchar\":{\"options\":\"Options des caractères spéciaux\",\"title\":\"Sélectionnez un caractère\",\"toolbar\":\"Insérer un caractère spécial\"},\"scayt\":{\"about\":\"A propos de SCAYT\",\"aboutTab\":\"À propos de\",\"addWord\":\"Ajouter le mot\",\"allCaps\":\"Ignorer les mots entièrement en majuscules\",\"dic_create\":\"Créer\",\"dic_delete\":\"Effacer\",\"dic_field_name\":\"Nom du dictionnaire\",\"dic_info\":\"Initialement, le dictionnaire de l'utilisateur est stocké dans un cookie. Cependant, les cookies sont limités en taille. Quand le dictionnaire atteint une taille qu'il n'est plus possible de stocker dans un cookie, il peut alors être stocké sur nos serveurs. Afin de stocker votre dictionnaire personnel sur nos serveurs, vous devez spécifier un nom pour ce dictionnaire. Si vous avez déjà un dictionnaire stocké, merci de taper son nom puis cliquer sur Restaurer pour le récupérer.\",\"dic_rename\":\"Renommer\",\"dic_restore\":\"Restaurer\",\"dictionariesTab\":\"Dictionnaires\",\"disable\":\"Désactiver SCAYT\",\"emptyDic\":\"Le nom du dictionnaire ne devrait pas être vide.\",\"enable\":\"Activer SCAYT\",\"ignore\":\"Ignorer\",\"ignoreAll\":\"Ignorer Tout\",\"ignoreDomainNames\":\"Ignorer les noms de domaines\",\"langs\":\"Langues\",\"languagesTab\":\"Langues\",\"mixedCase\":\"Ignorer les mots à casse multiple\",\"mixedWithDigits\":\"Ignorer les mots contenant des chiffres\",\"moreSuggestions\":\"Plus de suggestions\",\"opera_title\":\"Non supporté par Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Vérification de l'Orthographe en Cours de Frappe (SCAYT)\",\"toggle\":\"Activer/Désactiver SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Styles\",\"panelTitle\":\"Styles de mise en page\",\"panelTitle1\":\"Styles de blocs\",\"panelTitle2\":\"Styles en ligne\",\"panelTitle3\":\"Styles d'objet\"},\"table\":{\"border\":\"Taille de la bordure\",\"caption\":\"Titre du tableau\",\"cell\":{\"menu\":\"Cellule\",\"insertBefore\":\"Insérer une cellule avant\",\"insertAfter\":\"Insérer une cellule après\",\"deleteCell\":\"Supprimer les cellules\",\"merge\":\"Fusionner les cellules\",\"mergeRight\":\"Fusionner à droite\",\"mergeDown\":\"Fusionner en bas\",\"splitHorizontal\":\"Fractionner horizontalement\",\"splitVertical\":\"Fractionner verticalement\",\"title\":\"Propriétés de la cellule\",\"cellType\":\"Type de cellule\",\"rowSpan\":\"Fusion de lignes\",\"colSpan\":\"Fusion de colonnes\",\"wordWrap\":\"Césure\",\"hAlign\":\"Alignement Horizontal\",\"vAlign\":\"Alignement Vertical\",\"alignBaseline\":\"Bas du texte\",\"bgColor\":\"Couleur d'arrière-plan\",\"borderColor\":\"Couleur de Bordure\",\"data\":\"Données\",\"header\":\"Entête\",\"yes\":\"Oui\",\"no\":\"Non\",\"invalidWidth\":\"La Largeur de Cellule doit être un nombre.\",\"invalidHeight\":\"La Hauteur de Cellule doit être un nombre.\",\"invalidRowSpan\":\"La fusion de lignes doit être un nombre entier.\",\"invalidColSpan\":\"La fusion de colonnes doit être un nombre entier.\",\"chooseColor\":\"Choisissez\"},\"cellPad\":\"Marge interne des cellules\",\"cellSpace\":\"Espacement des cellules\",\"column\":{\"menu\":\"Colonnes\",\"insertBefore\":\"Insérer une colonne avant\",\"insertAfter\":\"Insérer une colonne après\",\"deleteColumn\":\"Supprimer les colonnes\"},\"columns\":\"Colonnes\",\"deleteTable\":\"Supprimer le tableau\",\"headers\":\"En-Têtes\",\"headersBoth\":\"Les deux\",\"headersColumn\":\"Première colonne\",\"headersNone\":\"Aucunes\",\"headersRow\":\"Première ligne\",\"invalidBorder\":\"La taille de la bordure doit être un nombre.\",\"invalidCellPadding\":\"La marge intérieure des cellules doit être un nombre positif.\",\"invalidCellSpacing\":\"L'espacement des cellules doit être un nombre positif.\",\"invalidCols\":\"Le nombre de colonnes doit être supérieur à 0.\",\"invalidHeight\":\"La hauteur du tableau doit être un nombre.\",\"invalidRows\":\"Le nombre de lignes doit être supérieur à 0.\",\"invalidWidth\":\"La largeur du tableau doit être un nombre.\",\"menu\":\"Propriétés du tableau\",\"row\":{\"menu\":\"Ligne\",\"insertBefore\":\"Insérer une ligne avant\",\"insertAfter\":\"Insérer une ligne après\",\"deleteRow\":\"Supprimer les lignes\"},\"rows\":\"Lignes\",\"summary\":\"Résumé (description)\",\"title\":\"Propriétés du tableau\",\"toolbar\":\"Tableau\",\"widthPc\":\"% pourcents\",\"widthPx\":\"pixels\",\"widthUnit\":\"unité de largeur\"},\"undo\":{\"redo\":\"Rétablir\",\"undo\":\"Annuler\"},\"wsc\":{\"btnIgnore\":\"Ignorer\",\"btnIgnoreAll\":\"Ignorer tout\",\"btnReplace\":\"Remplacer\",\"btnReplaceAll\":\"Remplacer tout\",\"btnUndo\":\"Annuler\",\"changeTo\":\"Modifier pour\",\"errorLoading\":\"Erreur du chargement du service depuis l'hôte : %s.\",\"ieSpellDownload\":\"La vérification d'orthographe n'est pas installée. Voulez-vous la télécharger maintenant?\",\"manyChanges\":\"Vérification de l'orthographe terminée : %1 mots corrigés.\",\"noChanges\":\"Vérification de l'orthographe terminée : Aucun mot corrigé.\",\"noMispell\":\"Vérification de l'orthographe terminée : aucune erreur trouvée.\",\"noSuggestions\":\"- Aucune suggestion -\",\"notAvailable\":\"Désolé, le service est indisponible actuellement.\",\"notInDic\":\"N'existe pas dans le dictionnaire.\",\"oneChange\":\"Vérification de l'orthographe terminée : Un seul mot corrigé.\",\"progress\":\"Vérification de l'orthographe en cours...\",\"title\":\"Vérifier l'orthographe\",\"toolbar\":\"Vérifier l'orthographe\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/gl.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['gl']={\"editor\":\"Editor de texto mellorado\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Prema ALT 0 para obter axuda\",\"browseServer\":\"Examinar o servidor\",\"url\":\"URL\",\"protocol\":\"Protocolo\",\"upload\":\"Enviar\",\"uploadSubmit\":\"Enviar ao servidor\",\"image\":\"Imaxe\",\"flash\":\"Flash\",\"form\":\"Formulario\",\"checkbox\":\"Caixa de selección\",\"radio\":\"Botón de opción\",\"textField\":\"Campo de texto\",\"textarea\":\"Área de texto\",\"hiddenField\":\"Campo agochado\",\"button\":\"Botón\",\"select\":\"Campo de selección\",\"imageButton\":\"Botón de imaxe\",\"notSet\":\"<sen estabelecer>\",\"id\":\"ID\",\"name\":\"Nome\",\"langDir\":\"Dirección de escritura do idioma\",\"langDirLtr\":\"Esquerda a dereita (LTR)\",\"langDirRtl\":\"Dereita a esquerda (RTL)\",\"langCode\":\"Código do idioma\",\"longDescr\":\"Descrición completa do URL\",\"cssClass\":\"Clases da folla de estilos\",\"advisoryTitle\":\"Título\",\"cssStyle\":\"Estilo\",\"ok\":\"Aceptar\",\"cancel\":\"Cancelar\",\"close\":\"Pechar\",\"preview\":\"Vista previa\",\"resize\":\"Redimensionar\",\"generalTab\":\"Xeral\",\"advancedTab\":\"Avanzado\",\"validateNumberFailed\":\"Este valor non é un número.\",\"confirmNewPage\":\"Calquera cambio que non gardara neste contido perderase.\\r\\nConfirma que quere cargar unha páxina nova?\",\"confirmCancel\":\"Algunhas das opcións foron cambiadas.\\r\\nConfirma que quere pechar o diálogo?\",\"options\":\"Opcións\",\"target\":\"Destino\",\"targetNew\":\"Nova xanela (_blank)\",\"targetTop\":\"Xanela principal (_top)\",\"targetSelf\":\"Mesma xanela (_self)\",\"targetParent\":\"Xanela superior (_parent)\",\"langDirLTR\":\"Esquerda a dereita (LTR)\",\"langDirRTL\":\"Dereita a esquerda (RTL)\",\"styles\":\"Estilo\",\"cssClasses\":\"Clases da folla de estilos\",\"width\":\"Largo\",\"height\":\"Alto\",\"align\":\"Aliñamento\",\"alignLeft\":\"Esquerda\",\"alignRight\":\"Dereita\",\"alignCenter\":\"Centro\",\"alignTop\":\"Arriba\",\"alignMiddle\":\"Centro\",\"alignBottom\":\"Abaixo\",\"invalidValue\":\"Valor incorrecto.\",\"invalidHeight\":\"O alto debe ser un número.\",\"invalidWidth\":\"O largo debe ser un número.\",\"invalidCssLength\":\"O valor especificado para o campo «%1» debe ser un número positivo con ou sen unha unidade de medida CSS correcta (px, %, in, cm, mm, em, ex, pt, ou pc).\",\"invalidHtmlLength\":\"O valor especificado para o campo «%1» debe ser un número positivo con ou sen unha unidade de medida HTML correcta (px ou %).\",\"invalidInlineStyle\":\"O valor especificado no estilo en liña debe consistir nunha ou máis tuplas co formato «nome : valor», separadas por punto e coma.\",\"cssLengthTooltip\":\"Escriba un número para o valor en píxeles ou un número cunha unidade CSS correcta (px, %, in, cm, mm, em, ex, pt, ou pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, non dispoñíbel</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Todos os dereitos reservados.\",\"dlgTitle\":\"Sobre o CKEditor\",\"help\":\"Consulte $1 para obter axuda.\",\"moreInfo\":\"Para obter  información sobre a licenza, visite o noso sitio web:\",\"title\":\"Sobre o CKEditor\",\"userGuide\":\"Guía do usuario do CKEditor\"},\"basicstyles\":{\"bold\":\"Negra\",\"italic\":\"Cursiva\",\"strike\":\"Riscado\",\"subscript\":\"Subíndice\",\"superscript\":\"Superíndice\",\"underline\":\"Subliñado\"},\"blockquote\":{\"toolbar\":\"Cita\"},\"clipboard\":{\"copy\":\"Copiar\",\"copyError\":\"Os axustes de seguranza do seu navegador non permiten que o editor realice automaticamente as tarefas de copia. Use o teclado para iso (Ctrl/Cmd+C).\",\"cut\":\"Cortar\",\"cutError\":\"Os axustes de seguranza do seu navegador non permiten que o editor realice automaticamente as tarefas de corte. Use o teclado para iso (Ctrl/Cmd+X).\",\"paste\":\"Pegar\",\"pasteArea\":\"Zona de pegado\",\"pasteMsg\":\"Pegue dentro do seguinte cadro usando o teclado (<STRONG>Ctrl/Cmd+V</STRONG>) e prema en Aceptar\",\"securityMsg\":\"Por mor da configuración de seguranza do seu navegador, o editor non ten acceso ao portapapeis. É necesario pegalo novamente nesta xanela.\",\"title\":\"Pegar\"},\"contextmenu\":{\"options\":\"Opcións do menú contextual\"},\"toolbar\":{\"toolbarCollapse\":\"Contraer a barra de ferramentas\",\"toolbarExpand\":\"Expandir a barra de ferramentas\",\"toolbarGroups\":{\"document\":\"Documento\",\"clipboard\":\"Portapapeis/desfacer\",\"editing\":\"Edición\",\"forms\":\"Formularios\",\"basicstyles\":\"Estilos básicos\",\"paragraph\":\"Paragrafo\",\"links\":\"Ligazóns\",\"insert\":\"Inserir\",\"styles\":\"Estilos\",\"colors\":\"Cores\",\"tools\":\"Ferramentas\"},\"toolbars\":\"Barras de ferramentas do editor\"},\"elementspath\":{\"eleLabel\":\"Ruta dos elementos\",\"eleTitle\":\"Elemento %1\"},\"format\":{\"label\":\"Formato\",\"panelTitle\":\"Formato do parágrafo\",\"tag_address\":\"Enderezo\",\"tag_div\":\"Normal  (DIV)\",\"tag_h1\":\"Enacabezado 1\",\"tag_h2\":\"Encabezado 2\",\"tag_h3\":\"Encabezado 3\",\"tag_h4\":\"Encabezado 4\",\"tag_h5\":\"Encabezado 5\",\"tag_h6\":\"Encabezado 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatado\"},\"horizontalrule\":{\"toolbar\":\"Inserir unha liña horizontal\"},\"image\":{\"alertUrl\":\"Escriba o URL da imaxe\",\"alt\":\"Texto alternativo\",\"border\":\"Bordo\",\"btnUpload\":\"Enviar ao servidor\",\"button2Img\":\"Quere converter o botón da imaxe seleccionada nunha imaxe sinxela?\",\"hSpace\":\"Esp.Horiz.\",\"img2Button\":\"Quere converter a imaxe seleccionada nun botón de imaxe?\",\"infoTab\":\"Información da imaxe\",\"linkTab\":\"Ligazón\",\"lockRatio\":\"Proporcional\",\"menu\":\"Propiedades da imaxe\",\"resetSize\":\"Tamaño orixinal\",\"title\":\"Propiedades da imaxe\",\"titleButton\":\"Propiedades do botón de imaxe\",\"upload\":\"Cargar\",\"urlMissing\":\"Non se atopa o URL da imaxe.\",\"vSpace\":\"Esp.Vert.\",\"validateBorder\":\"O bordo debe ser un número.\",\"validateHSpace\":\"O espazado horizontal debe ser un número.\",\"validateVSpace\":\"O espazado vertical debe ser un número.\"},\"indent\":{\"indent\":\"Aumentar a sangría\",\"outdent\":\"Reducir a sangría\"},\"fakeobjects\":{\"anchor\":\"Ancoraxe\",\"flash\":\"Animación «Flash»\",\"hiddenfield\":\"Campo agochado\",\"iframe\":\"IFrame\",\"unknown\":\"Obxecto descoñecido\"},\"link\":{\"acccessKey\":\"Chave de acceso\",\"advanced\":\"Avanzado\",\"advisoryContentType\":\"Tipo de contido informativo\",\"advisoryTitle\":\"Título\",\"anchor\":{\"toolbar\":\"Ancoraxe\",\"menu\":\"Editar a ancoraxe\",\"title\":\"Propiedades da ancoraxe\",\"name\":\"Nome da ancoraxe\",\"errorName\":\"Escriba o nome da ancoraxe\",\"remove\":\"Retirar a ancoraxe\"},\"anchorId\":\"Polo ID do elemento\",\"anchorName\":\"Polo nome da ancoraxe\",\"charset\":\"Codificación do recurso ligado\",\"cssClasses\":\"Clases da folla de estilos\",\"emailAddress\":\"Enderezo de correo\",\"emailBody\":\"Corpo da mensaxe\",\"emailSubject\":\"Asunto da mensaxe\",\"id\":\"ID\",\"info\":\"Información da ligazón\",\"langCode\":\"Código do idioma\",\"langDir\":\"Dirección de escritura do idioma\",\"langDirLTR\":\"Esquerda a dereita (LTR)\",\"langDirRTL\":\"Dereita a esquerda (RTL)\",\"menu\":\"Editar a ligazón\",\"name\":\"Nome\",\"noAnchors\":\"(Non hai ancoraxes dispoñíbeis no documento)\",\"noEmail\":\"Escriba o enderezo de correo\",\"noUrl\":\"Escriba a ligazón URL\",\"other\":\"<outro>\",\"popupDependent\":\"Dependente (Netscape)\",\"popupFeatures\":\"Características da xanela emerxente\",\"popupFullScreen\":\"Pantalla completa (IE)\",\"popupLeft\":\"Posición esquerda\",\"popupLocationBar\":\"Barra de localización\",\"popupMenuBar\":\"Barra do menú\",\"popupResizable\":\"Redimensionábel\",\"popupScrollBars\":\"Barras de desprazamento\",\"popupStatusBar\":\"Barra de estado\",\"popupToolbar\":\"Barra de ferramentas\",\"popupTop\":\"Posición superior\",\"rel\":\"Relación\",\"selectAnchor\":\"Seleccionar unha ancoraxe\",\"styles\":\"Estilo\",\"tabIndex\":\"Índice de tabulación\",\"target\":\"Destino\",\"targetFrame\":\"<marco>\",\"targetFrameName\":\"Nome do marco de destino\",\"targetPopup\":\"<xanela emerxente>\",\"targetPopupName\":\"Nome da xanela emerxente\",\"title\":\"Ligazón\",\"toAnchor\":\"Ligar coa ancoraxe no testo\",\"toEmail\":\"Correo\",\"toUrl\":\"URL\",\"toolbar\":\"Ligazón\",\"type\":\"Tipo de ligazón\",\"unlink\":\"Eliminar a ligazón\",\"upload\":\"Enviar\"},\"list\":{\"bulletedlist\":\"Inserir/retirar lista viñeteada\",\"numberedlist\":\"Inserir/retirar lista numerada\"},\"magicline\":{\"title\":\"Inserir aquí o parágrafo\"},\"maximize\":{\"maximize\":\"Maximizar\",\"minimize\":\"Minimizar\"},\"pastetext\":{\"button\":\"Pegar como texto simple\",\"title\":\"Pegar como texto simple\"},\"pastefromword\":{\"confirmCleanup\":\"O texto que quere pegar semella ser copiado desde o Word. Quere depuralo antes de pegalo?\",\"error\":\"Non foi posíbel depurar os datos pegados por mor dun erro interno\",\"title\":\"Pegar desde Word\",\"toolbar\":\"Pegar desde Word\"},\"removeformat\":{\"toolbar\":\"Retirar o formato\"},\"sourcearea\":{\"toolbar\":\"Orixe\"},\"specialchar\":{\"options\":\"Opcións de caracteres especiais\",\"title\":\"Seleccione un carácter especial\",\"toolbar\":\"Inserir un carácter especial\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Estilos\",\"panelTitle\":\"Estilos de formatando\",\"panelTitle1\":\"Estilos de bloque\",\"panelTitle2\":\"Estilos de carácter\",\"panelTitle3\":\"Estilos de obxecto\"},\"table\":{\"border\":\"Tamaño do bordo\",\"caption\":\"Título\",\"cell\":{\"menu\":\"Cela\",\"insertBefore\":\"Inserir a cela á esquerda\",\"insertAfter\":\"Inserir a cela á dereita\",\"deleteCell\":\"Eliminar celas\",\"merge\":\"Combinar celas\",\"mergeRight\":\"Combinar á dereita\",\"mergeDown\":\"Combinar cara abaixo\",\"splitHorizontal\":\"Dividir a cela en horizontal\",\"splitVertical\":\"Dividir a cela en vertical\",\"title\":\"Propiedades da cela\",\"cellType\":\"Tipo de cela\",\"rowSpan\":\"Expandir filas\",\"colSpan\":\"Expandir columnas\",\"wordWrap\":\"Axustar ao contido\",\"hAlign\":\"Aliñación horizontal\",\"vAlign\":\"Aliñación vertical\",\"alignBaseline\":\"Liña de base\",\"bgColor\":\"Cor do fondo\",\"borderColor\":\"Cor do bordo\",\"data\":\"Datos\",\"header\":\"Cabeceira\",\"yes\":\"Si\",\"no\":\"Non\",\"invalidWidth\":\"O largo da cela debe ser un número.\",\"invalidHeight\":\"O alto da cela debe ser un número.\",\"invalidRowSpan\":\"A expansión de filas debe ser un número enteiro.\",\"invalidColSpan\":\"A expansión de columnas debe ser un número enteiro.\",\"chooseColor\":\"Escoller\"},\"cellPad\":\"Marxe interior da cela\",\"cellSpace\":\"Marxe entre celas\",\"column\":{\"menu\":\"Columna\",\"insertBefore\":\"Inserir a columna á esquerda\",\"insertAfter\":\"Inserir a columna á dereita\",\"deleteColumn\":\"Borrar Columnas\"},\"columns\":\"Columnas\",\"deleteTable\":\"Borrar Táboa\",\"headers\":\"Cabeceiras\",\"headersBoth\":\"Ambas\",\"headersColumn\":\"Primeira columna\",\"headersNone\":\"Ningún\",\"headersRow\":\"Primeira fila\",\"invalidBorder\":\"O tamaño do bordo debe ser un número.\",\"invalidCellPadding\":\"A marxe interior debe ser un número positivo.\",\"invalidCellSpacing\":\"A marxe entre celas debe ser un número positivo.\",\"invalidCols\":\"O número de columnas debe ser un número maior que 0.\",\"invalidHeight\":\"O alto da táboa debe ser un número.\",\"invalidRows\":\"O número de filas debe ser un número maior que 0\",\"invalidWidth\":\"O largo da táboa debe ser un número.\",\"menu\":\"Propiedades da táboa\",\"row\":{\"menu\":\"Fila\",\"insertBefore\":\"Inserir a fila por riba\",\"insertAfter\":\"Inserir a fila por baixo\",\"deleteRow\":\"Eliminar filas\"},\"rows\":\"Filas\",\"summary\":\"Resumo\",\"title\":\"Propiedades da táboa\",\"toolbar\":\"Taboa\",\"widthPc\":\"porcentaxe\",\"widthPx\":\"píxeles\",\"widthUnit\":\"unidade do largo\"},\"undo\":{\"redo\":\"Refacer\",\"undo\":\"Desfacer\"},\"wsc\":{\"btnIgnore\":\"Ignorar\",\"btnIgnoreAll\":\"Ignorar Todas\",\"btnReplace\":\"Substituir\",\"btnReplaceAll\":\"Substituir Todas\",\"btnUndo\":\"Desfacer\",\"changeTo\":\"Cambiar a\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"O corrector ortográfico non está instalado. ¿Quere descargalo agora?\",\"manyChanges\":\"Corrección ortográfica rematada: %1 verbas substituidas\",\"noChanges\":\"Corrección ortográfica rematada: Non se substituiu nengunha verba\",\"noMispell\":\"Corrección ortográfica rematada: Non se atoparon erros\",\"noSuggestions\":\"- Sen candidatos -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Non está no diccionario\",\"oneChange\":\"Corrección ortográfica rematada: Unha verba substituida\",\"progress\":\"Corrección ortográfica en progreso...\",\"title\":\"Spell Check\",\"toolbar\":\"Corrección Ortográfica\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/gu.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['gu']={\"editor\":\"રીચ ટેક્ષ્ત્ એડીટર\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"પ્રેસ ALT 0 મદદ માટ\",\"browseServer\":\"સર્વર બ્રાઉઝ કરો\",\"url\":\"URL\",\"protocol\":\"પ્રોટોકૉલ\",\"upload\":\"અપલોડ\",\"uploadSubmit\":\"આ સર્વરને મોકલવું\",\"image\":\"ચિત્ર\",\"flash\":\"ફ્લૅશ\",\"form\":\"ફૉર્મ/પત્રક\",\"checkbox\":\"ચેક બોક્સ\",\"radio\":\"રેડિઓ બટન\",\"textField\":\"ટેક્સ્ટ ફીલ્ડ, શબ્દ ક્ષેત્ર\",\"textarea\":\"ટેક્સ્ટ એરિઆ, શબ્દ વિસ્તાર\",\"hiddenField\":\"ગુપ્ત ક્ષેત્ર\",\"button\":\"બટન\",\"select\":\"પસંદગી ક્ષેત્ર\",\"imageButton\":\"ચિત્ર બટન\",\"notSet\":\"<સેટ નથી>\",\"id\":\"Id\",\"name\":\"નામ\",\"langDir\":\"ભાષા લેખવાની પદ્ધતિ\",\"langDirLtr\":\"ડાબે થી જમણે (LTR)\",\"langDirRtl\":\"જમણે થી ડાબે (RTL)\",\"langCode\":\"ભાષા કોડ\",\"longDescr\":\"વધારે માહિતી માટે URL\",\"cssClass\":\"સ્ટાઇલ-શીટ ક્લાસ\",\"advisoryTitle\":\"મુખ્ય મથાળું\",\"cssStyle\":\"સ્ટાઇલ\",\"ok\":\"ઠીક છે\",\"cancel\":\"રદ કરવું\",\"close\":\"બંધ કરવું\",\"preview\":\"જોવું\",\"resize\":\"ખેંચી ને યોગ્ય કરવું\",\"generalTab\":\"જનરલ\",\"advancedTab\":\"અડ્વાન્સડ\",\"validateNumberFailed\":\"આ રકમ આકડો નથી.\",\"confirmNewPage\":\"સવે કાર્ય વગરનું ફકરો ખોવાઈ જશે. તમને ખાતરી છે કે તમને નવું પાનું ખોલવું છે?\",\"confirmCancel\":\"ઘણા વિકલ્પો બદલાયા છે. તમારે આ બોક્ષ્ બંધ કરવું છે?\",\"options\":\"વિકલ્પો\",\"target\":\"લક્ષ્ય\",\"targetNew\":\"નવી વિન્ડો (_blank)\",\"targetTop\":\"ઉપરની વિન્ડો (_top)\",\"targetSelf\":\"એજ વિન્ડો (_self)\",\"targetParent\":\"પેરનટ વિન્ડો (_parent)\",\"langDirLTR\":\"ડાબે થી જમણે (LTR)\",\"langDirRTL\":\"જમણે થી ડાબે (RTL)\",\"styles\":\"શૈલી\",\"cssClasses\":\"શૈલી કલાસીસ\",\"width\":\"પહોળાઈ\",\"height\":\"ઊંચાઈ\",\"align\":\"લાઇનદોરીમાં ગોઠવવું\",\"alignLeft\":\"ડાબી બાજુ ગોઠવવું\",\"alignRight\":\"જમણી\",\"alignCenter\":\"મધ્ય સેન્ટર\",\"alignTop\":\"ઉપર\",\"alignMiddle\":\"વચ્ચે\",\"alignBottom\":\"નીચે\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"ઉંચાઈ એક આંકડો હોવો જોઈએ.\",\"invalidWidth\":\"પોહળ ઈ એક આંકડો હોવો જોઈએ.\",\"invalidCssLength\":\"\\\"%1\\\" ની વેલ્યુ એક પોસીટીવ આંકડો હોવો જોઈએ અથવા CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc) વગર.\",\"invalidHtmlLength\":\"\\\"%1\\\" ની વેલ્યુ એક પોસીટીવ આંકડો હોવો જોઈએ અથવા HTML measurement unit (px or %) વગર.\",\"invalidInlineStyle\":\"ઈનલાઈન  સ્ટાઈલ ની વેલ્યુ  \\\"name : value\\\" ના ફોર્મેટ માં હોવી જોઈએ, વચ્ચે સેમી-કોલોન જોઈએ.\",\"cssLengthTooltip\":\"પિક્ષ્લ્ નો આંકડો CSS unit (px, %, in, cm, mm, em, ex, pt, or pc) માં નાખો.\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, નથી મળતું</span>\"},\"about\":{\"copy\":\"કોપીરાઈટ &copy; $1. ઓલ રાઈટ્સ \",\"dlgTitle\":\"CKEditor વિષે\",\"help\":\"મદદ માટે $1 તપાસો\",\"moreInfo\":\"લાયસનસની માહિતી માટે અમારી વેબ સાઈટ\",\"title\":\"CKEditor વિષે\",\"userGuide\":\"CKEditor યુઝર્સ ગાઈડ\"},\"basicstyles\":{\"bold\":\"બોલ્ડ/સ્પષ્ટ\",\"italic\":\"ઇટેલિક, ત્રાંસા\",\"strike\":\"છેકી નાખવું\",\"subscript\":\"એક ચિહ્નની નીચે કરેલું બીજું ચિહ્ન\",\"superscript\":\"એક ચિહ્ન ઉપર કરેલું બીજું ચિહ્ન.\",\"underline\":\"અન્ડર્લાઇન, નીચે લીટી\"},\"blockquote\":{\"toolbar\":\"બ્લૉક-કોટ, અવતરણચિહ્નો\"},\"clipboard\":{\"copy\":\"નકલ\",\"copyError\":\"તમારા બ્રાઉઝર ની સુરક્ષિત સેટિંગસ કોપી કરવાની પરવાનગી નથી આપતી.  (Ctrl/Cmd+C) का प्रयोग करें।\",\"cut\":\"કાપવું\",\"cutError\":\"તમારા બ્રાઉઝર ની સુરક્ષિત સેટિંગસ કટ કરવાની પરવાનગી નથી આપતી. (Ctrl/Cmd+X) નો ઉપયોગ કરો.\",\"paste\":\"પેસ્ટ\",\"pasteArea\":\"પેસ્ટ કરવાની જગ્યા\",\"pasteMsg\":\"Ctrl/Cmd+V નો પ્રયોગ કરી પેસ્ટ કરો\",\"securityMsg\":\"તમારા બ્રાઉઝર ની સુરક્ષિત સેટિંગસના કારણે,એડિટર તમારા કિલ્પબોર્ડ ડેટા ને કોપી નથી કરી શકતો. તમારે આ વિન્ડોમાં ફરીથી પેસ્ટ કરવું પડશે.\",\"title\":\"પેસ્ટ\"},\"contextmenu\":{\"options\":\"કોન્તેક્ષ્ત્ મેનુના વિકલ્પો\"},\"toolbar\":{\"toolbarCollapse\":\"ટૂલબાર નાનું કરવું\",\"toolbarExpand\":\"ટૂલબાર મોટું કરવું\",\"toolbarGroups\":{\"document\":\"દસ્તાવેજ\",\"clipboard\":\"ક્લિપબોર્ડ/અન\",\"editing\":\"એડીટ કરવું\",\"forms\":\"ફોર્મ\",\"basicstyles\":\"બેસિક્ સ્ટાઇલ\",\"paragraph\":\"ફકરો\",\"links\":\"લીંક\",\"insert\":\"ઉમેરવું\",\"styles\":\"સ્ટાઇલ\",\"colors\":\"રંગ\",\"tools\":\"ટૂલ્સ\"},\"toolbars\":\"એડીટર ટૂલ બાર\"},\"elementspath\":{\"eleLabel\":\"એલીમેન્ટ્સ નો \",\"eleTitle\":\"એલીમેન્ટ %1\"},\"format\":{\"label\":\"ફૉન્ટ ફૉર્મટ, રચનાની શૈલી\",\"panelTitle\":\"ફૉન્ટ ફૉર્મટ, રચનાની શૈલી\",\"tag_address\":\"સરનામું\",\"tag_div\":\"શીર્ષક (DIV)\",\"tag_h1\":\"શીર્ષક 1\",\"tag_h2\":\"શીર્ષક 2\",\"tag_h3\":\"શીર્ષક 3\",\"tag_h4\":\"શીર્ષક 4\",\"tag_h5\":\"શીર્ષક 5\",\"tag_h6\":\"શીર્ષક 6\",\"tag_p\":\"સામાન્ય\",\"tag_pre\":\"ફૉર્મટેડ\"},\"horizontalrule\":{\"toolbar\":\"સમસ્તરીય રેખા ઇન્સર્ટ/દાખલ કરવી\"},\"image\":{\"alertUrl\":\"ચિત્રની URL ટાઇપ કરો\",\"alt\":\"ઑલ્ટર્નટ ટેક્સ્ટ\",\"border\":\"બોર્ડર\",\"btnUpload\":\"આ સર્વરને મોકલવું\",\"button2Img\":\"તમારે ઈમેજ બટનને સાદી ઈમેજમાં બદલવું છે.\",\"hSpace\":\"સમસ્તરીય જગ્યા\",\"img2Button\":\"તમારે સાદી ઈમેજને ઈમેજ બટનમાં બદલવું છે.\",\"infoTab\":\"ચિત્ર ની જાણકારી\",\"linkTab\":\"લિંક\",\"lockRatio\":\"લૉક ગુણોત્તર\",\"menu\":\"ચિત્રના ગુણ\",\"resetSize\":\"રીસેટ સાઇઝ\",\"title\":\"ચિત્રના ગુણ\",\"titleButton\":\"ચિત્ર બટનના ગુણ\",\"upload\":\"અપલોડ\",\"urlMissing\":\"ઈમેજની મૂળ URL છે નહી.\",\"vSpace\":\"લંબરૂપ જગ્યા\",\"validateBorder\":\"બોર્ડેર આંકડો હોવો જોઈએ.\",\"validateHSpace\":\"HSpaceઆંકડો હોવો જોઈએ.\",\"validateVSpace\":\"VSpace આંકડો હોવો જોઈએ. \"},\"indent\":{\"indent\":\"ઇન્ડેન્ટ, લીટીના આરંભમાં જગ્યા વધારવી\",\"outdent\":\"ઇન્ડેન્ટ લીટીના આરંભમાં જગ્યા ઘટાડવી\"},\"fakeobjects\":{\"anchor\":\"અનકર\",\"flash\":\"ફ્લેશ \",\"hiddenfield\":\"હિડન \",\"iframe\":\"IFrame\",\"unknown\":\"અનનોન ઓબ્જેક્ટ\"},\"link\":{\"acccessKey\":\"ઍક્સેસ કી\",\"advanced\":\"અડ્વાન્સડ\",\"advisoryContentType\":\"મુખ્ય કન્ટેન્ટ પ્રકાર\",\"advisoryTitle\":\"મુખ્ય મથાળું\",\"anchor\":{\"toolbar\":\"ઍંકર ઇન્સર્ટ/દાખલ કરવી\",\"menu\":\"ઍંકરના ગુણ\",\"title\":\"ઍંકરના ગુણ\",\"name\":\"ઍંકરનું નામ\",\"errorName\":\"ઍંકરનું નામ ટાઈપ કરો\",\"remove\":\"સ્થિર નકરવું\"},\"anchorId\":\"ઍંકર એલિમન્ટ Id થી પસંદ કરો\",\"anchorName\":\"ઍંકર નામથી પસંદ કરો\",\"charset\":\"લિંક રિસૉર્સ કૅરિક્ટર સેટ\",\"cssClasses\":\"સ્ટાઇલ-શીટ ક્લાસ\",\"emailAddress\":\"ઈ-મેલ સરનામું\",\"emailBody\":\"સંદેશ\",\"emailSubject\":\"ઈ-મેલ વિષય\",\"id\":\"Id\",\"info\":\"લિંક ઇન્ફૉ ટૅબ\",\"langCode\":\"ભાષા લેખવાની પદ્ધતિ\",\"langDir\":\"ભાષા લેખવાની પદ્ધતિ\",\"langDirLTR\":\"ડાબે થી જમણે (LTR)\",\"langDirRTL\":\"જમણે થી ડાબે (RTL)\",\"menu\":\" લિંક એડિટ/માં ફેરફાર કરવો\",\"name\":\"નામ\",\"noAnchors\":\"(ડૉક્યુમન્ટમાં ઍંકરની સંખ્યા)\",\"noEmail\":\"ઈ-મેલ સરનામું ટાઇપ કરો\",\"noUrl\":\"લિંક  URL ટાઇપ કરો\",\"other\":\"<other> <અન્ય>\",\"popupDependent\":\"ડિપેન્ડન્ટ (Netscape)\",\"popupFeatures\":\"પૉપ-અપ વિન્ડો ફીચરસૅ\",\"popupFullScreen\":\"ફુલ સ્ક્રીન (IE)\",\"popupLeft\":\"ડાબી બાજુ\",\"popupLocationBar\":\"લોકેશન બાર\",\"popupMenuBar\":\"મેન્યૂ બાર\",\"popupResizable\":\"રીસાઈઝએબલ\",\"popupScrollBars\":\"સ્ક્રોલ બાર\",\"popupStatusBar\":\"સ્ટૅટસ બાર\",\"popupToolbar\":\"ટૂલ બાર\",\"popupTop\":\"જમણી બાજુ\",\"rel\":\"સંબંધની સ્થિતિ\",\"selectAnchor\":\"ઍંકર પસંદ કરો\",\"styles\":\"સ્ટાઇલ\",\"tabIndex\":\"ટૅબ ઇન્ડેક્સ\",\"target\":\"ટાર્ગેટ/લક્ષ્ય\",\"targetFrame\":\"<ફ્રેમ>\",\"targetFrameName\":\"ટાર્ગેટ ફ્રેમ નું નામ\",\"targetPopup\":\"<પૉપ-અપ વિન્ડો>\",\"targetPopupName\":\"પૉપ-અપ વિન્ડો નું નામ\",\"title\":\"લિંક\",\"toAnchor\":\"આ પેજનો ઍંકર\",\"toEmail\":\"ઈ-મેલ\",\"toUrl\":\"URL\",\"toolbar\":\"લિંક ઇન્સર્ટ/દાખલ કરવી\",\"type\":\"લિંક પ્રકાર\",\"unlink\":\"લિંક કાઢવી\",\"upload\":\"અપલોડ\"},\"list\":{\"bulletedlist\":\"બુલેટ સૂચિ\",\"numberedlist\":\"સંખ્યાંકન સૂચિ\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"મોટું કરવું\",\"minimize\":\"નાનું કરવું\"},\"pastetext\":{\"button\":\"પેસ્ટ (ટેક્સ્ટ)\",\"title\":\"પેસ્ટ (ટેક્સ્ટ)\"},\"pastefromword\":{\"confirmCleanup\":\"તમે જે ટેક્ષ્ત્ કોપી કરી રહ્યા છો ટે વર્ડ ની છે. કોપી કરતા પેહલા સાફ કરવી છે?\",\"error\":\"પેસ્ટ કરેલો ડેટા ઇન્ટરનલ એરર ના લીથે સાફ કરી શકાયો નથી.\",\"title\":\"પેસ્ટ (વડૅ ટેક્સ્ટ)\",\"toolbar\":\"પેસ્ટ (વડૅ ટેક્સ્ટ)\"},\"removeformat\":{\"toolbar\":\"ફૉર્મટ કાઢવું\"},\"sourcearea\":{\"toolbar\":\"મૂળ કે પ્રાથમિક દસ્તાવેજ\"},\"specialchar\":{\"options\":\"સ્પેશિઅલ કરેક્ટરના વિકલ્પો\",\"title\":\"સ્પેશિઅલ વિશિષ્ટ અક્ષર પસંદ કરો\",\"toolbar\":\"વિશિષ્ટ અક્ષર ઇન્સર્ટ/દાખલ કરવું\"},\"scayt\":{\"about\":\"SCAYT વિષે\",\"aboutTab\":\"વિષે\",\"addWord\":\"શબ્દ ઉમેરવો\",\"allCaps\":\"ઓલ-કેપ્સ વર્ડ છોડી દો.\",\"dic_create\":\"બનાવવું\",\"dic_delete\":\"કાઢી નાખવું\",\"dic_field_name\":\"શબ્દકોશ નામ\",\"dic_info\":\"પેહલા User Dictionary, Cookie તરીકે સ્ટોર થાય છે. પણ Cookie ની સમતા ઓછી છે. જયારે User Dictionary, Cookie તરીકે સ્ટોર ના કરી શકાય, ત્યારે તે અમારા સર્વર પર સ્ટોર થાય છે. તમારી વ્યતિગત ડીકસ્નરી ને સર્વર પર સ્ટોર કરવા માટે તમારે તેનું નામ આપવું પડશે. જો તમે તમારી ડીકસ્નરી નું નામ આપેલું હોય તો તમે રિસ્ટોર બટન ક્લીક કરી શકો.\",\"dic_rename\":\"નવું નામ આપવું\",\"dic_restore\":\"પાછું \",\"dictionariesTab\":\"શબ્દકોશ\",\"disable\":\"SCAYT ડિસેબલ કરવું\",\"emptyDic\":\"ડિક્સનરીનું નામ ખાલી ના હોય.\",\"enable\":\"SCAYT એનેબલ કરવું\",\"ignore\":\"ઇગ્નોર\",\"ignoreAll\":\"બધા ઇગ્નોર \",\"ignoreDomainNames\":\"ડોમેન નામ છોડી દો.\",\"langs\":\"ભાષાઓ\",\"languagesTab\":\"ભાષા\",\"mixedCase\":\"મિક્સ કેસ વર્ડ છોડી દો.\",\"mixedWithDigits\":\"આંકડા વાળા શબ્દ છોડી દો.\",\"moreSuggestions\":\"વધારે વિકલ્પો\",\"opera_title\":\"ઓપેરામાં સપોર્ટ નથી\",\"options\":\"વિકલ્પો\",\"optionsTab\":\"વિકલ્પો\",\"title\":\"ટાઈપ કરતા સ્પેલ તપાસો\",\"toggle\":\"SCAYT ટોગલ\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"શૈલી/રીત\",\"panelTitle\":\"ફોર્મેટ \",\"panelTitle1\":\"બ્લોક \",\"panelTitle2\":\"ઈનલાઈન \",\"panelTitle3\":\"ઓબ્જેક્ટ પદ્ધતિ\"},\"table\":{\"border\":\"કોઠાની બાજુ(બોર્ડર) સાઇઝ\",\"caption\":\"મથાળું/કૅપ્શન \",\"cell\":{\"menu\":\"કોષના ખાના\",\"insertBefore\":\"પહેલાં કોષ ઉમેરવો\",\"insertAfter\":\"પછી કોષ ઉમેરવો\",\"deleteCell\":\"કોષ ડિલીટ/કાઢી નાખવો\",\"merge\":\"કોષ ભેગા કરવા\",\"mergeRight\":\"જમણી બાજુ ભેગા કરવા\",\"mergeDown\":\"નીચે ભેગા કરવા\",\"splitHorizontal\":\"કોષને સમસ્તરીય વિભાજન કરવું\",\"splitVertical\":\"કોષને સીધું ને ઊભું વિભાજન કરવું\",\"title\":\"સેલના ગુણ\",\"cellType\":\"સેલનો પ્રકાર\",\"rowSpan\":\"આડી કટારની જગ્યા\",\"colSpan\":\"ઊભી કતારની જગ્યા\",\"wordWrap\":\"વર્ડ રેપ\",\"hAlign\":\"સપાટ લાઈનદોરી\",\"vAlign\":\"ઊભી લાઈનદોરી\",\"alignBaseline\":\"બસે લાઈન\",\"bgColor\":\"પાછાળનો રંગ\",\"borderColor\":\"બોર્ડેર રંગ\",\"data\":\"સ્વીકૃત માહિતી\",\"header\":\"મથાળું\",\"yes\":\"હા\",\"no\":\"ના\",\"invalidWidth\":\"સેલની પોહલાઈ આંકડો હોવો જોઈએ.\",\"invalidHeight\":\"સેલની ઊંચાઈ આંકડો હોવો જોઈએ.\",\"invalidRowSpan\":\"રો સ્પાન આંકડો હોવો જોઈએ.\",\"invalidColSpan\":\"કોલમ સ્પાન આંકડો હોવો જોઈએ.\",\"chooseColor\":\"પસંદ કરવું\"},\"cellPad\":\"સેલ પૅડિંગ\",\"cellSpace\":\"સેલ અંતર\",\"column\":{\"menu\":\"કૉલમ/ઊભી કટાર\",\"insertBefore\":\"પહેલાં કૉલમ/ઊભી કટાર ઉમેરવી\",\"insertAfter\":\"પછી કૉલમ/ઊભી કટાર ઉમેરવી\",\"deleteColumn\":\"કૉલમ/ઊભી કટાર ડિલીટ/કાઢી નાખવી\"},\"columns\":\"કૉલમ/ઊભી કટાર\",\"deleteTable\":\"કોઠો ડિલીટ/કાઢી નાખવું\",\"headers\":\"મથાળા\",\"headersBoth\":\"બેવું\",\"headersColumn\":\"પહેલી ઊભી કટાર\",\"headersNone\":\"નથી \",\"headersRow\":\"પહેલી  કટાર\",\"invalidBorder\":\"બોર્ડર એક આંકડો હોવો જોઈએ\",\"invalidCellPadding\":\"સેલની અંદરની જગ્યા સુન્ય કરતા વધારે હોવી જોઈએ.\",\"invalidCellSpacing\":\"સેલ વચ્ચેની જગ્યા સુન્ય કરતા વધારે હોવી જોઈએ.\",\"invalidCols\":\"ઉભી કટાર, 0 કરતા વધારે હોવી જોઈએ.\",\"invalidHeight\":\"ટેબલની ઊંચાઈ આંકડો હોવો જોઈએ.\",\"invalidRows\":\"આડી કટાર, 0 કરતા વધારે હોવી જોઈએ.\",\"invalidWidth\":\"ટેબલની પોહલાઈ આંકડો હોવો જોઈએ.\",\"menu\":\"ટેબલ, કોઠાનું મથાળું\",\"row\":{\"menu\":\"પંક્તિના ખાના\",\"insertBefore\":\"પહેલાં પંક્તિ ઉમેરવી\",\"insertAfter\":\"પછી પંક્તિ ઉમેરવી\",\"deleteRow\":\"પંક્તિઓ ડિલીટ/કાઢી નાખવી\"},\"rows\":\"પંક્તિના ખાના\",\"summary\":\"ટૂંકો એહેવાલ\",\"title\":\"ટેબલ, કોઠાનું મથાળું\",\"toolbar\":\"ટેબલ, કોઠો\",\"widthPc\":\"પ્રતિશત\",\"widthPx\":\"પિકસલ\",\"widthUnit\":\"પોહાલાઈ એકમ\"},\"undo\":{\"redo\":\"રિડૂ; પછી હતી એવી સ્થિતિ પાછી લાવવી\",\"undo\":\"રદ કરવું; પહેલાં હતી એવી સ્થિતિ પાછી લાવવી\"},\"wsc\":{\"btnIgnore\":\"ઇગ્નોર/અવગણના કરવી\",\"btnIgnoreAll\":\"બધાની ઇગ્નોર/અવગણના કરવી\",\"btnReplace\":\"બદલવું\",\"btnReplaceAll\":\"બધા બદલી કરો\",\"btnUndo\":\"અન્ડૂ\",\"changeTo\":\"આનાથી બદલવું\",\"errorLoading\":\"સર્વિસ એપ્લીકેશન લોડ નથી થ: %s.\",\"ieSpellDownload\":\"સ્પેલ-ચેકર ઇન્સ્ટોલ નથી. શું તમે ડાઉનલોડ કરવા માંગો છો?\",\"manyChanges\":\"શબ્દની જોડણી/સ્પેલ ચેક પૂર્ણ: %1 શબ્દ બદલયા છે\",\"noChanges\":\"શબ્દની જોડણી/સ્પેલ ચેક પૂર્ણ: એકપણ શબ્દ બદલયો નથી\",\"noMispell\":\"શબ્દની જોડણી/સ્પેલ ચેક પૂર્ણ: ખોટી જોડણી મળી નથી\",\"noSuggestions\":\"- કઇ સજેશન નથી -\",\"notAvailable\":\"માફ કરશો, આ સુવિધા ઉપલબ્ધ નથી\",\"notInDic\":\"શબ્દકોશમાં નથી\",\"oneChange\":\"શબ્દની જોડણી/સ્પેલ ચેક પૂર્ણ: એક શબ્દ બદલયો છે\",\"progress\":\"શબ્દની જોડણી/સ્પેલ ચેક ચાલુ છે...\",\"title\":\"સ્પેલ \",\"toolbar\":\"જોડણી (સ્પેલિંગ) તપાસવી\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/he.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['he']={\"editor\":\"עורך טקסט עשיר\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"לחץ אלט ALT + 0 לעזרה\",\"browseServer\":\"סייר השרת\",\"url\":\"כתובת (URL)\",\"protocol\":\"פרוטוקול\",\"upload\":\"העלאה\",\"uploadSubmit\":\"שליחה לשרת\",\"image\":\"תמונה\",\"flash\":\"פלאש\",\"form\":\"טופס\",\"checkbox\":\"תיבת סימון\",\"radio\":\"לחצן אפשרויות\",\"textField\":\"שדה טקסט\",\"textarea\":\"איזור טקסט\",\"hiddenField\":\"שדה חבוי\",\"button\":\"כפתור\",\"select\":\"שדה בחירה\",\"imageButton\":\"כפתור תמונה\",\"notSet\":\"<לא נקבע>\",\"id\":\"זיהוי (ID)\",\"name\":\"שם\",\"langDir\":\"כיוון שפה\",\"langDirLtr\":\"שמאל לימין (LTR)\",\"langDirRtl\":\"ימין לשמאל (RTL)\",\"langCode\":\"קוד שפה\",\"longDescr\":\"קישור לתיאור מפורט\",\"cssClass\":\"מחלקת עיצוב (CSS Class)\",\"advisoryTitle\":\"כותרת מוצעת\",\"cssStyle\":\"סגנון\",\"ok\":\"אישור\",\"cancel\":\"ביטול\",\"close\":\"סגירה\",\"preview\":\"תצוגה מקדימה\",\"resize\":\"יש לגרור בכדי לשנות את הגודל\",\"generalTab\":\"כללי\",\"advancedTab\":\"אפשרויות מתקדמות\",\"validateNumberFailed\":\"הערך חייב להיות מספרי.\",\"confirmNewPage\":\"כל השינויים שלא נשמרו יאבדו. האם להעלות דף חדש?\",\"confirmCancel\":\"חלק מהאפשרויות שונו, האם לסגור את הדיאלוג?\",\"options\":\"אפשרויות\",\"target\":\"מטרה\",\"targetNew\":\"חלון חדש (_blank)\",\"targetTop\":\"החלון העליון ביותר (_top)\",\"targetSelf\":\"אותו חלון (_self)\",\"targetParent\":\"חלון האב (_parent)\",\"langDirLTR\":\"שמאל לימין (LTR)\",\"langDirRTL\":\"ימין לשמאל (RTL)\",\"styles\":\"סגנון\",\"cssClasses\":\"מחלקות גליונות סגנון\",\"width\":\"רוחב\",\"height\":\"גובה\",\"align\":\"יישור\",\"alignLeft\":\"לשמאל\",\"alignRight\":\"לימין\",\"alignCenter\":\"מרכז\",\"alignTop\":\"למעלה\",\"alignMiddle\":\"לאמצע\",\"alignBottom\":\"לתחתית\",\"invalidValue\":\"ערך לא חוקי.\",\"invalidHeight\":\"הגובה חייב להיות מספר.\",\"invalidWidth\":\"הרוחב חייב להיות מספר.\",\"invalidCssLength\":\"הערך שצוין לשדה \\\"%1\\\" חייב להיות מספר חיובי עם או ללא יחידת מידה חוקית של CSS (px, %, in, cm, mm, em, ex, pt, או pc).\",\"invalidHtmlLength\":\"הערך שצוין לשדה \\\"%1\\\" חייב להיות מספר חיובי עם או ללא יחידת מידה חוקית של HTML (px או %).\",\"invalidInlineStyle\":\"הערך שצויין לשדה הסגנון חייב להכיל זוג ערכים אחד או יותר בפורמט \\\"שם : ערך\\\", מופרדים על ידי נקודה-פסיק.\",\"cssLengthTooltip\":\"יש להכניס מספר המייצג פיקסלים או מספר עם יחידת גליונות סגנון תקינה (px, %, in, cm, mm, em, ex, pt, או pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, לא זמין</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. כל הזכויות שמורות.\",\"dlgTitle\":\"אודות CKEditor\",\"help\":\"היכנסו ל$1 לעזרה.\",\"moreInfo\":\"למידע נוסף בקרו באתרנו:\",\"title\":\"אודות CKEditor\",\"userGuide\":\"מדריך המשתמש של CKEditor\"},\"basicstyles\":{\"bold\":\"מודגש\",\"italic\":\"נטוי\",\"strike\":\"כתיב מחוק\",\"subscript\":\"כתיב תחתון\",\"superscript\":\"כתיב עליון\",\"underline\":\"קו תחתון\"},\"blockquote\":{\"toolbar\":\"בלוק ציטוט\"},\"clipboard\":{\"copy\":\"העתקה\",\"copyError\":\"הגדרות האבטחה בדפדפן שלך לא מאפשרות לעורך לבצע פעולות העתקה אוטומטיות. יש להשתמש במקלדת לשם כך (Ctrl/Cmd+C).\",\"cut\":\"גזירה\",\"cutError\":\"הגדרות האבטחה בדפדפן שלך לא מאפשרות לעורך לבצע פעולות גזירה אוטומטיות. יש להשתמש במקלדת לשם כך (Ctrl/Cmd+X).\",\"paste\":\"הדבקה\",\"pasteArea\":\"איזור הדבקה\",\"pasteMsg\":\"נא להדביק בתוך הקופסה באמצעות (<b>Ctrl/Cmd+V</b>) וללחוץ על <b>אישור</b>.\",\"securityMsg\":\"עקב הגדרות אבטחה בדפדפן, לא ניתן לגשת אל לוח הגזירים (Clipboard) בצורה ישירה. נא להדביק שוב בחלון זה.\",\"title\":\"הדבקה\"},\"contextmenu\":{\"options\":\"אפשרויות תפריט ההקשר\"},\"toolbar\":{\"toolbarCollapse\":\"מזעור סרגל כלים\",\"toolbarExpand\":\"הרחבת סרגל כלים\",\"toolbarGroups\":{\"document\":\"מסמך\",\"clipboard\":\"לוח הגזירים (Clipboard)/צעד אחרון\",\"editing\":\"עריכה\",\"forms\":\"טפסים\",\"basicstyles\":\"עיצוב בסיסי\",\"paragraph\":\"פסקה\",\"links\":\"קישורים\",\"insert\":\"הכנסה\",\"styles\":\"עיצוב\",\"colors\":\"צבעים\",\"tools\":\"כלים\"},\"toolbars\":\"סרגלי כלים של העורך\"},\"elementspath\":{\"eleLabel\":\"עץ האלמנטים\",\"eleTitle\":\"%1 אלמנט\"},\"format\":{\"label\":\"עיצוב\",\"panelTitle\":\"עיצוב\",\"tag_address\":\"כתובת\",\"tag_div\":\"נורמלי (DIV)\",\"tag_h1\":\"כותרת\",\"tag_h2\":\"כותרת 2\",\"tag_h3\":\"כותרת 3\",\"tag_h4\":\"כותרת 4\",\"tag_h5\":\"כותרת 5\",\"tag_h6\":\"כותרת 6\",\"tag_p\":\"נורמלי\",\"tag_pre\":\"קוד\"},\"horizontalrule\":{\"toolbar\":\"הוספת קו אופקי\"},\"image\":{\"alertUrl\":\"יש להקליד את כתובת התמונה\",\"alt\":\"טקסט חלופי\",\"border\":\"מסגרת\",\"btnUpload\":\"שליחה לשרת\",\"button2Img\":\"האם להפוך את תמונת הכפתור לתמונה פשוטה?\",\"hSpace\":\"מרווח אופקי\",\"img2Button\":\"האם להפוך את התמונה לכפתור תמונה?\",\"infoTab\":\"מידע על התמונה\",\"linkTab\":\"קישור\",\"lockRatio\":\"נעילת היחס\",\"menu\":\"תכונות התמונה\",\"resetSize\":\"איפוס הגודל\",\"title\":\"מאפייני התמונה\",\"titleButton\":\"מאפיני כפתור תמונה\",\"upload\":\"העלאה\",\"urlMissing\":\"כתובת התמונה חסרה.\",\"vSpace\":\"מרווח אנכי\",\"validateBorder\":\"שדה המסגרת חייב להיות מספר שלם.\",\"validateHSpace\":\"שדה המרווח האופקי חייב להיות מספר שלם.\",\"validateVSpace\":\"שדה המרווח האנכי חייב להיות מספר שלם.\"},\"indent\":{\"indent\":\"הגדלת הזחה\",\"outdent\":\"הקטנת הזחה\"},\"fakeobjects\":{\"anchor\":\"עוגן\",\"flash\":\"סרטון פלאש\",\"hiddenfield\":\"שדה חבוי\",\"iframe\":\"חלון פנימי (iframe)\",\"unknown\":\"אובייקט לא ידוע\"},\"link\":{\"acccessKey\":\"מקש גישה\",\"advanced\":\"אפשרויות מתקדמות\",\"advisoryContentType\":\"Content Type מוצע\",\"advisoryTitle\":\"כותרת מוצעת\",\"anchor\":{\"toolbar\":\"הוספת/עריכת נקודת עיגון\",\"menu\":\"מאפייני נקודת עיגון\",\"title\":\"מאפייני נקודת עיגון\",\"name\":\"שם לנקודת עיגון\",\"errorName\":\"יש להקליד שם לנקודת עיגון\",\"remove\":\"מחיקת נקודת עיגון\"},\"anchorId\":\"עפ\\\"י זיהוי (ID) האלמנט\",\"anchorName\":\"עפ\\\"י שם העוגן\",\"charset\":\"קידוד המשאב המקושר\",\"cssClasses\":\"גיליונות עיצוב קבוצות\",\"emailAddress\":\"כתובת הדוא\\\"ל\",\"emailBody\":\"גוף ההודעה\",\"emailSubject\":\"נושא ההודעה\",\"id\":\"זיהוי (ID)\",\"info\":\"מידע על הקישור\",\"langCode\":\"קוד שפה\",\"langDir\":\"כיוון שפה\",\"langDirLTR\":\"שמאל לימין (LTR)\",\"langDirRTL\":\"ימין לשמאל (RTL)\",\"menu\":\"מאפייני קישור\",\"name\":\"שם\",\"noAnchors\":\"(אין עוגנים זמינים בדף)\",\"noEmail\":\"יש להקליד את כתובת הדוא\\\"ל\",\"noUrl\":\"יש להקליד את כתובת הקישור (URL)\",\"other\":\"<אחר>\",\"popupDependent\":\"תלוי (Netscape)\",\"popupFeatures\":\"תכונות החלון הקופץ\",\"popupFullScreen\":\"מסך מלא (IE)\",\"popupLeft\":\"מיקום צד שמאל\",\"popupLocationBar\":\"סרגל כתובת\",\"popupMenuBar\":\"סרגל תפריט\",\"popupResizable\":\"שינוי גודל\",\"popupScrollBars\":\"ניתן לגלילה\",\"popupStatusBar\":\"סרגל חיווי\",\"popupToolbar\":\"סרגל הכלים\",\"popupTop\":\"מיקום צד עליון\",\"rel\":\"קשר גומלין\",\"selectAnchor\":\"בחירת עוגן\",\"styles\":\"סגנון\",\"tabIndex\":\"מספר טאב\",\"target\":\"מטרה\",\"targetFrame\":\"<מסגרת>\",\"targetFrameName\":\"שם מסגרת היעד\",\"targetPopup\":\"<חלון קופץ>\",\"targetPopupName\":\"שם החלון הקופץ\",\"title\":\"קישור\",\"toAnchor\":\"עוגן בעמוד זה\",\"toEmail\":\"דוא\\\"ל\",\"toUrl\":\"כתובת (URL)\",\"toolbar\":\"הוספת/עריכת קישור\",\"type\":\"סוג קישור\",\"unlink\":\"הסרת הקישור\",\"upload\":\"העלאה\"},\"list\":{\"bulletedlist\":\"רשימת נקודות\",\"numberedlist\":\"רשימה ממוספרת\"},\"magicline\":{\"title\":\"הכנס פסקה כאן\"},\"maximize\":{\"maximize\":\"הגדלה למקסימום\",\"minimize\":\"הקטנה למינימום\"},\"pastetext\":{\"button\":\"הדבקה כטקסט פשוט\",\"title\":\"הדבקה כטקסט פשוט\"},\"pastefromword\":{\"confirmCleanup\":\"נראה הטקסט שבכוונתך להדביק מקורו בקובץ וורד. האם ברצונך לנקות אותו טרם ההדבקה?\",\"error\":\"לא ניתן היה לנקות את המידע בשל תקלה פנימית.\",\"title\":\"הדבקה מ-Word\",\"toolbar\":\"הדבקה מ-Word\"},\"removeformat\":{\"toolbar\":\"הסרת העיצוב\"},\"sourcearea\":{\"toolbar\":\"מקור\"},\"specialchar\":{\"options\":\"אפשרויות תווים מיוחדים\",\"title\":\"בחירת תו מיוחד\",\"toolbar\":\"הוספת תו מיוחד\"},\"scayt\":{\"about\":\"אודות SCAYT\",\"aboutTab\":\"אודות\",\"addWord\":\"הוספת מילה\",\"allCaps\":\"התעלם ממילים שכל אותיותיהן גדולות\",\"dic_create\":\"יצירה\",\"dic_delete\":\"מחיקה\",\"dic_field_name\":\"שם המילון\",\"dic_info\":\"בהתחלה מילון המשתמש מאוחסן בעוגיה, אך עוגיות מוגבלות במקום. כאשר המילון מגיע לגודל בו הוא אינו יכול להתאכסן בעוגיה, המילון צריך להתאכסן בשרתנו. לשם כך עליך לתת שם למילון. אם כבר יש לך מילון מאוחסן, יש להכניס את שמו וללחוץ על כפתור השחזור.\",\"dic_rename\":\"שינוי שם\",\"dic_restore\":\"שחזור\",\"dictionariesTab\":\"מילון\",\"disable\":\"בטל SCAYT\",\"emptyDic\":\"יש לבחור מילון.\",\"enable\":\"אפשר SCAYT\",\"ignore\":\"התעלמות\",\"ignoreAll\":\"התעלמות מהכל\",\"ignoreDomainNames\":\"התעלם משמות מתחם\",\"langs\":\"שפות\",\"languagesTab\":\"שפות\",\"mixedCase\":\"התעלם ממילים עם אותיות גדולות וקטנות ביחד\",\"mixedWithDigits\":\"התעלם ממילים עם מספרים\",\"moreSuggestions\":\"הצעות נוספות\",\"opera_title\":\"לא זמין בדפדפן אופרה\",\"options\":\"אפשרויות\",\"optionsTab\":\"אפשרויות\",\"title\":\"בדיקת איות בזמן כתיבה (SCAYT)\",\"toggle\":\"שינוי SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"סגנון\",\"panelTitle\":\"סגנונות פורמט\",\"panelTitle1\":\"סגנונות בלוק\",\"panelTitle2\":\"סגנונות רצף\",\"panelTitle3\":\"סגנונות אובייקט\"},\"table\":{\"border\":\"גודל מסגרת\",\"caption\":\"כיתוב\",\"cell\":{\"menu\":\"מאפייני תא\",\"insertBefore\":\"הוספת תא לפני\",\"insertAfter\":\"הוספת תא אחרי\",\"deleteCell\":\"מחיקת תאים\",\"merge\":\"מיזוג תאים\",\"mergeRight\":\"מזג ימינה\",\"mergeDown\":\"מזג למטה\",\"splitHorizontal\":\"פיצול תא אופקית\",\"splitVertical\":\"פיצול תא אנכית\",\"title\":\"תכונות התא\",\"cellType\":\"סוג התא\",\"rowSpan\":\"מתיחת השורות\",\"colSpan\":\"מתיחת התאים\",\"wordWrap\":\"מניעת גלישת שורות\",\"hAlign\":\"יישור אופקי\",\"vAlign\":\"יישור אנכי\",\"alignBaseline\":\"שורת בסיס\",\"bgColor\":\"צבע רקע\",\"borderColor\":\"צבע מסגרת\",\"data\":\"מידע\",\"header\":\"כותרת\",\"yes\":\"כן\",\"no\":\"לא\",\"invalidWidth\":\"שדה רוחב התא חייב להיות מספר.\",\"invalidHeight\":\"שדה גובה התא חייב להיות מספר.\",\"invalidRowSpan\":\"שדה מתיחת השורות חייב להיות מספר שלם.\",\"invalidColSpan\":\"שדה מתיחת העמודות חייב להיות מספר שלם.\",\"chooseColor\":\"בחר\"},\"cellPad\":\"ריפוד תא\",\"cellSpace\":\"מרווח תא\",\"column\":{\"menu\":\"עמודה\",\"insertBefore\":\"הוספת עמודה לפני\",\"insertAfter\":\"הוספת עמודה אחרי\",\"deleteColumn\":\"מחיקת עמודות\"},\"columns\":\"עמודות\",\"deleteTable\":\"מחק טבלה\",\"headers\":\"כותרות\",\"headersBoth\":\"שניהם\",\"headersColumn\":\"עמודה ראשונה\",\"headersNone\":\"אין\",\"headersRow\":\"שורה ראשונה\",\"invalidBorder\":\"שדה גודל המסגרת חייב להיות מספר.\",\"invalidCellPadding\":\"שדה ריפוד התאים חייב להיות מספר חיובי.\",\"invalidCellSpacing\":\"שדה ריווח התאים חייב להיות מספר חיובי.\",\"invalidCols\":\"שדה מספר העמודות חייב להיות מספר גדול מ 0.\",\"invalidHeight\":\"שדה גובה הטבלה חייב להיות מספר.\",\"invalidRows\":\"שדה מספר השורות חייב להיות מספר גדול מ 0.\",\"invalidWidth\":\"שדה רוחב הטבלה חייב להיות מספר.\",\"menu\":\"מאפייני טבלה\",\"row\":{\"menu\":\"שורה\",\"insertBefore\":\"הוספת שורה לפני\",\"insertAfter\":\"הוספת שורה אחרי\",\"deleteRow\":\"מחיקת שורות\"},\"rows\":\"שורות\",\"summary\":\"תקציר\",\"title\":\"מאפייני טבלה\",\"toolbar\":\"טבלה\",\"widthPc\":\"אחוז\",\"widthPx\":\"פיקסלים\",\"widthUnit\":\"יחידת רוחב\"},\"undo\":{\"redo\":\"חזרה על צעד אחרון\",\"undo\":\"ביטול צעד אחרון\"},\"wsc\":{\"btnIgnore\":\"התעלמות\",\"btnIgnoreAll\":\"התעלמות מהכל\",\"btnReplace\":\"החלפה\",\"btnReplaceAll\":\"החלפת הכל\",\"btnUndo\":\"החזרה\",\"changeTo\":\"שינוי ל\",\"errorLoading\":\"שגיאה בהעלאת השירות: %s.\",\"ieSpellDownload\":\"בודק האיות לא מותקן, האם להורידו?\",\"manyChanges\":\"בדיקות איות הסתיימה: %1 מילים שונו\",\"noChanges\":\"בדיקות איות הסתיימה: לא שונתה אף מילה\",\"noMispell\":\"בדיקות איות הסתיימה: לא נמצאו שגיאות כתיב\",\"noSuggestions\":\"- אין הצעות -\",\"notAvailable\":\"לא נמצא שירות זמין.\",\"notInDic\":\"לא נמצא במילון\",\"oneChange\":\"בדיקות איות הסתיימה: שונתה מילה אחת\",\"progress\":\"בודק האיות בתהליך בדיקה....\",\"title\":\"בדיקת איות\",\"toolbar\":\"בדיקת איות\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/hi.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['hi']={\"editor\":\"रिच टेक्स्ट एडिटर\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"मदद के लिये ALT 0 दबाए\",\"browseServer\":\"सर्वर ब्राउज़ करें\",\"url\":\"URL\",\"protocol\":\"प्रोटोकॉल\",\"upload\":\"अपलोड\",\"uploadSubmit\":\"इसे सर्वर को भेजें\",\"image\":\"तस्वीर\",\"flash\":\"फ़्लैश\",\"form\":\"फ़ॉर्म\",\"checkbox\":\"चॅक बॉक्स\",\"radio\":\"रेडिओ बटन\",\"textField\":\"टेक्स्ट फ़ील्ड\",\"textarea\":\"टेक्स्ट एरिया\",\"hiddenField\":\"गुप्त फ़ील्ड\",\"button\":\"बटन\",\"select\":\"चुनाव फ़ील्ड\",\"imageButton\":\"तस्वीर बटन\",\"notSet\":\"<सॅट नहीं>\",\"id\":\"Id\",\"name\":\"नाम\",\"langDir\":\"भाषा लिखने की दिशा\",\"langDirLtr\":\"बायें से दायें (LTR)\",\"langDirRtl\":\"दायें से बायें (RTL)\",\"langCode\":\"भाषा कोड\",\"longDescr\":\"अधिक विवरण के लिए URL\",\"cssClass\":\"स्टाइल-शीट क्लास\",\"advisoryTitle\":\"परामर्श शीर्शक\",\"cssStyle\":\"स्टाइल\",\"ok\":\"ठीक है\",\"cancel\":\"रद्द करें\",\"close\":\"Close\",\"preview\":\"प्रीव्यू\",\"resize\":\"Resize\",\"generalTab\":\"सामान्य\",\"advancedTab\":\"ऍड्वान्स्ड\",\"validateNumberFailed\":\"This value is not a number.\",\"confirmNewPage\":\"Any unsaved changes to this content will be lost. Are you sure you want to load new page?\",\"confirmCancel\":\"You have changed some options. Are you sure you want to close the dialog window?\",\"options\":\"Options\",\"target\":\"टार्गेट\",\"targetNew\":\"New Window (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Same Window (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"बायें से दायें (LTR)\",\"langDirRTL\":\"दायें से बायें (RTL)\",\"styles\":\"स्टाइल\",\"cssClasses\":\"स्टाइल-शीट क्लास\",\"width\":\"चौड़ाई\",\"height\":\"ऊँचाई\",\"align\":\"ऍलाइन\",\"alignLeft\":\"दायें\",\"alignRight\":\"दायें\",\"alignCenter\":\"बीच में\",\"alignTop\":\"ऊपर\",\"alignMiddle\":\"मध्य\",\"alignBottom\":\"नीचे\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Height must be a number.\",\"invalidWidth\":\"Width must be a number.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"बोल्ड\",\"italic\":\"इटैलिक\",\"strike\":\"स्ट्राइक थ्रू\",\"subscript\":\"अधोलेख\",\"superscript\":\"अभिलेख\",\"underline\":\"रेखांकण\"},\"blockquote\":{\"toolbar\":\"ब्लॉक-कोट\"},\"clipboard\":{\"copy\":\"कॉपी\",\"copyError\":\"आपके ब्राआउज़र की सुरक्षा सॅटिन्ग्स ने कॉपी करने की अनुमति नहीं प्रदान की है। (Ctrl/Cmd+C) का प्रयोग करें।\",\"cut\":\"कट\",\"cutError\":\"आपके ब्राउज़र की सुरक्षा सॅटिन्ग्स ने कट करने की अनुमति नहीं प्रदान की है। (Ctrl/Cmd+X) का प्रयोग करें।\",\"paste\":\"पेस्ट\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"Ctrl/Cmd+V का प्रयोग करके पेस्ट करें और ठीक है करें.\",\"securityMsg\":\"आपके ब्राउज़र की सुरक्षा आपके ब्राउज़र की सुरKश सैटिंग के कारण, एडिटर आपके क्लिपबोर्ड डेटा को नहीं पा सकता है. आपको उसे इस विन्डो में दोबारा पेस्ट करना होगा.\",\"title\":\"पेस्ट\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Collapse Toolbar\",\"toolbarExpand\":\"Expand Toolbar\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"एडिटर टूलबार\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"फ़ॉर्मैट\",\"panelTitle\":\"फ़ॉर्मैट\",\"tag_address\":\"पता\",\"tag_div\":\"शीर्षक (DIV)\",\"tag_h1\":\"शीर्षक 1\",\"tag_h2\":\"शीर्षक 2\",\"tag_h3\":\"शीर्षक 3\",\"tag_h4\":\"शीर्षक 4\",\"tag_h5\":\"शीर्षक 5\",\"tag_h6\":\"शीर्षक 6\",\"tag_p\":\"साधारण\",\"tag_pre\":\"फ़ॉर्मैटॅड\"},\"horizontalrule\":{\"toolbar\":\"हॉरिज़ॉन्टल रेखा इन्सर्ट करें\"},\"image\":{\"alertUrl\":\"तस्वीर का URL टाइप करें \",\"alt\":\"वैकल्पिक टेक्स्ट\",\"border\":\"बॉर्डर\",\"btnUpload\":\"इसे सर्वर को भेजें\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"हॉरिज़ॉन्टल स्पेस\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"तस्वीर की जानकारी\",\"linkTab\":\"लिंक\",\"lockRatio\":\"लॉक अनुपात\",\"menu\":\"तस्वीर प्रॉपर्टीज़\",\"resetSize\":\"रीसॅट साइज़\",\"title\":\"तस्वीर प्रॉपर्टीज़\",\"titleButton\":\"तस्वीर बटन प्रॉपर्टीज़\",\"upload\":\"अपलोड\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"वर्टिकल स्पेस\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"इन्डॅन्ट बढ़ायें\",\"outdent\":\"इन्डॅन्ट कम करें\"},\"fakeobjects\":{\"anchor\":\"ऐंकर इन्सर्ट/संपादन\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"गुप्त फ़ील्ड\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"ऍक्सॅस की\",\"advanced\":\"ऍड्वान्स्ड\",\"advisoryContentType\":\"परामर्श कन्टॅन्ट प्रकार\",\"advisoryTitle\":\"परामर्श शीर्शक\",\"anchor\":{\"toolbar\":\"ऐंकर इन्सर्ट/संपादन\",\"menu\":\"ऐंकर प्रॉपर्टीज़\",\"title\":\"ऐंकर प्रॉपर्टीज़\",\"name\":\"ऐंकर का नाम\",\"errorName\":\"ऐंकर का नाम टाइप करें\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"ऍलीमॅन्ट Id से\",\"anchorName\":\"ऐंकर नाम से\",\"charset\":\"लिंक रिसोर्स करॅक्टर सॅट\",\"cssClasses\":\"स्टाइल-शीट क्लास\",\"emailAddress\":\"ई-मेल पता\",\"emailBody\":\"संदेश\",\"emailSubject\":\"संदेश विषय\",\"id\":\"Id\",\"info\":\"लिंक  \",\"langCode\":\"भाषा लिखने की दिशा\",\"langDir\":\"भाषा लिखने की दिशा\",\"langDirLTR\":\"बायें से दायें (LTR)\",\"langDirRTL\":\"दायें से बायें (RTL)\",\"menu\":\"लिंक संपादन\",\"name\":\"नाम\",\"noAnchors\":\"(डॉक्यूमॅन्ट में ऐंकर्स की संख्या)\",\"noEmail\":\"ई-मेल पता टाइप करें\",\"noUrl\":\"लिंक URL टाइप करें\",\"other\":\"<अन्य>\",\"popupDependent\":\"डिपेन्डॅन्ट (Netscape)\",\"popupFeatures\":\"पॉप-अप विन्डो फ़ीचर्स\",\"popupFullScreen\":\"फ़ुल स्क्रीन (IE)\",\"popupLeft\":\"बायीं तरफ\",\"popupLocationBar\":\"लोकेशन बार\",\"popupMenuBar\":\"मॅन्यू बार\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"स्क्रॉल बार\",\"popupStatusBar\":\"स्टेटस बार\",\"popupToolbar\":\"टूल बार\",\"popupTop\":\"दायीं तरफ\",\"rel\":\"Relationship\",\"selectAnchor\":\"ऐंकर चुनें\",\"styles\":\"स्टाइल\",\"tabIndex\":\"टैब इन्डॅक्स\",\"target\":\"टार्गेट\",\"targetFrame\":\"<फ़्रेम>\",\"targetFrameName\":\"टार्गेट फ़्रेम का नाम\",\"targetPopup\":\"<पॉप-अप विन्डो>\",\"targetPopupName\":\"पॉप-अप विन्डो का नाम\",\"title\":\"लिंक\",\"toAnchor\":\"इस पेज का ऐंकर\",\"toEmail\":\"ई-मेल\",\"toUrl\":\"URL\",\"toolbar\":\"लिंक इन्सर्ट/संपादन\",\"type\":\"लिंक प्रकार\",\"unlink\":\"लिंक हटायें\",\"upload\":\"अपलोड\"},\"list\":{\"bulletedlist\":\"बुलॅट सूची\",\"numberedlist\":\"अंकीय सूची\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"मेक्सिमाईज़\",\"minimize\":\"मिनिमाईज़\"},\"pastetext\":{\"button\":\"पेस्ट (सादा टॅक्स्ट)\",\"title\":\"पेस्ट (सादा टॅक्स्ट)\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"पेस्ट (वर्ड से)\",\"toolbar\":\"पेस्ट (वर्ड से)\"},\"removeformat\":{\"toolbar\":\"फ़ॉर्मैट हटायें\"},\"sourcearea\":{\"toolbar\":\"सोर्स\"},\"specialchar\":{\"options\":\"Special Character Options\",\"title\":\"विशेष करॅक्टर चुनें\",\"toolbar\":\"विशेष करॅक्टर इन्सर्ट करें\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"स्टाइल\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"बॉर्डर साइज़\",\"caption\":\"शीर्षक\",\"cell\":{\"menu\":\"खाना\",\"insertBefore\":\"पहले सैल डालें\",\"insertAfter\":\"बाद में सैल डालें\",\"deleteCell\":\"सैल डिलीट करें\",\"merge\":\"सैल मिलायें\",\"mergeRight\":\"बाँया विलय\",\"mergeDown\":\"नीचे विलय करें\",\"splitHorizontal\":\"सैल को क्षैतिज स्थिति में विभाजित करें\",\"splitVertical\":\"सैल को लम्बाकार में विभाजित करें\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"सैल पैडिंग\",\"cellSpace\":\"सैल अंतर\",\"column\":{\"menu\":\"कालम\",\"insertBefore\":\"पहले कालम डालें\",\"insertAfter\":\"बाद में कालम डालें\",\"deleteColumn\":\"कालम डिलीट करें\"},\"columns\":\"कालम\",\"deleteTable\":\"टेबल डिलीट करें\",\"headers\":\"Headers\",\"headersBoth\":\"Both\",\"headersColumn\":\"First column\",\"headersNone\":\"None\",\"headersRow\":\"First Row\",\"invalidBorder\":\"Border size must be a number.\",\"invalidCellPadding\":\"Cell padding must be a positive number.\",\"invalidCellSpacing\":\"Cell spacing must be a positive number.\",\"invalidCols\":\"Number of columns must be a number greater than 0.\",\"invalidHeight\":\"Table height must be a number.\",\"invalidRows\":\"Number of rows must be a number greater than 0.\",\"invalidWidth\":\"Table width must be a number.\",\"menu\":\"टेबल प्रॉपर्टीज़\",\"row\":{\"menu\":\"पंक्ति\",\"insertBefore\":\"पहले पंक्ति डालें\",\"insertAfter\":\"बाद में पंक्ति डालें\",\"deleteRow\":\"पंक्तियाँ डिलीट करें\"},\"rows\":\"पंक्तियाँ\",\"summary\":\"सारांश\",\"title\":\"टेबल प्रॉपर्टीज़\",\"toolbar\":\"टेबल\",\"widthPc\":\"प्रतिशत\",\"widthPx\":\"पिक्सैल\",\"widthUnit\":\"width unit\"},\"undo\":{\"redo\":\"रीडू\",\"undo\":\"अन्डू\"},\"wsc\":{\"btnIgnore\":\"इग्नोर\",\"btnIgnoreAll\":\"सभी इग्नोर करें\",\"btnReplace\":\"रिप्लेस\",\"btnReplaceAll\":\"सभी रिप्लेस करें\",\"btnUndo\":\"अन्डू\",\"changeTo\":\"इसमें बदलें\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"स्पॅल-चॅकर इन्स्टाल नहीं किया गया है। क्या आप इसे डाउनलोड करना चाहेंगे?\",\"manyChanges\":\"वर्तनी की जाँच : %1 शब्द बदले गये\",\"noChanges\":\"वर्तनी की जाँच :कोई शब्द नहीं बदला गया\",\"noMispell\":\"वर्तनी की जाँच : कोई गलत वर्तनी (स्पॅलिंग) नहीं पाई गई\",\"noSuggestions\":\"- कोई सुझाव नहीं -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"शब्दकोश में नहीं\",\"oneChange\":\"वर्तनी की जाँच : एक शब्द बदला गया\",\"progress\":\"वर्तनी की जाँच (स्पॅल-चॅक) जारी है...\",\"title\":\"Spell Check\",\"toolbar\":\"वर्तनी (स्पेलिंग) जाँच\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/hr.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['hr']={\"editor\":\"Bogati uređivač teksta\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Pritisni ALT 0 za pomoć\",\"browseServer\":\"Pretraži server\",\"url\":\"URL\",\"protocol\":\"Protokol\",\"upload\":\"Pošalji\",\"uploadSubmit\":\"Pošalji na server\",\"image\":\"Slika\",\"flash\":\"Flash\",\"form\":\"Forma\",\"checkbox\":\"Checkbox\",\"radio\":\"Radio Button\",\"textField\":\"Text Field\",\"textarea\":\"Textarea\",\"hiddenField\":\"Hidden Field\",\"button\":\"Button\",\"select\":\"Selection Field\",\"imageButton\":\"Image Button\",\"notSet\":\"<nije postavljeno>\",\"id\":\"Id\",\"name\":\"Naziv\",\"langDir\":\"Smjer jezika\",\"langDirLtr\":\"S lijeva na desno (LTR)\",\"langDirRtl\":\"S desna na lijevo (RTL)\",\"langCode\":\"Kôd jezika\",\"longDescr\":\"Dugački opis URL\",\"cssClass\":\"Klase stilova\",\"advisoryTitle\":\"Advisory naslov\",\"cssStyle\":\"Stil\",\"ok\":\"OK\",\"cancel\":\"Poništi\",\"close\":\"Zatvori\",\"preview\":\"Pregledaj\",\"resize\":\"Povuci za promjenu veličine\",\"generalTab\":\"Općenito\",\"advancedTab\":\"Napredno\",\"validateNumberFailed\":\"Ova vrijednost nije broj.\",\"confirmNewPage\":\"Sve napravljene promjene će biti izgubljene ukoliko ih niste snimili. Sigurno želite učitati novu stranicu?\",\"confirmCancel\":\"Neke od opcija su promjenjene. Sigurno želite zatvoriti ovaj prozor?\",\"options\":\"Opcije\",\"target\":\"Odredište\",\"targetNew\":\"Novi prozor (_blank)\",\"targetTop\":\"Vršni prozor (_top)\",\"targetSelf\":\"Isti prozor (_self)\",\"targetParent\":\"Roditeljski prozor (_parent)\",\"langDirLTR\":\"S lijeva na desno (LTR)\",\"langDirRTL\":\"S desna na lijevo (RTL)\",\"styles\":\"Stil\",\"cssClasses\":\"Klase stilova\",\"width\":\"Širina\",\"height\":\"Visina\",\"align\":\"Poravnanje\",\"alignLeft\":\"Lijevo\",\"alignRight\":\"Desno\",\"alignCenter\":\"Središnje\",\"alignTop\":\"Vrh\",\"alignMiddle\":\"Sredina\",\"alignBottom\":\"Dolje\",\"invalidValue\":\"Neispravna vrijednost.\",\"invalidHeight\":\"Visina mora biti broj.\",\"invalidWidth\":\"Širina mora biti broj.\",\"invalidCssLength\":\"Vrijednost određena za \\\"%1\\\" polje mora biti pozitivni broj sa ili bez važećih CSS mjernih jedinica (px, %, in, cm, mm, em, ex, pt ili pc).\",\"invalidHtmlLength\":\"Vrijednost određena za \\\"%1\\\" polje mora biti pozitivni broj sa ili bez važećih HTML mjernih jedinica (px ili %).\",\"invalidInlineStyle\":\"Vrijednost za linijski stil mora sadržavati jednu ili više definicija s formatom \\\"naziv:vrijednost\\\", odvojenih točka-zarezom.\",\"cssLengthTooltip\":\"Unesite broj za vrijednost u pikselima ili broj s važećim CSS mjernim jedinicama (px, %, in, cm, mm, em, ex, pt ili pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, nedostupno</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"O CKEditoru\",\"help\":\"Provjeri $1 za pomoć.\",\"moreInfo\":\"Za informacije o licencama posjetite našu web stranicu:\",\"title\":\"O CKEditoru\",\"userGuide\":\"Vodič za CKEditor korisnike\"},\"basicstyles\":{\"bold\":\"Podebljaj\",\"italic\":\"Ukosi\",\"strike\":\"Precrtano\",\"subscript\":\"Subscript\",\"superscript\":\"Superscript\",\"underline\":\"Potcrtano\"},\"blockquote\":{\"toolbar\":\"Blockquote\"},\"clipboard\":{\"copy\":\"Kopiraj\",\"copyError\":\"Sigurnosne postavke Vašeg pretraživača ne dozvoljavaju operacije automatskog kopiranja. Molimo koristite kraticu na tipkovnici (Ctrl/Cmd+C).\",\"cut\":\"Izreži\",\"cutError\":\"Sigurnosne postavke Vašeg pretraživača ne dozvoljavaju operacije automatskog izrezivanja. Molimo koristite kraticu na tipkovnici (Ctrl/Cmd+X).\",\"paste\":\"Zalijepi\",\"pasteArea\":\"Prostor za ljepljenje\",\"pasteMsg\":\"Molimo zaljepite unutar doljnjeg okvira koristeći tipkovnicu (<STRONG>Ctrl/Cmd+V</STRONG>) i kliknite <STRONG>OK</STRONG>.\",\"securityMsg\":\"Zbog sigurnosnih postavki Vašeg pretraživača, editor nema direktan pristup Vašem međuspremniku. Potrebno je ponovno zalijepiti tekst u ovaj prozor.\",\"title\":\"Zalijepi\"},\"contextmenu\":{\"options\":\"Opcije izbornika\"},\"toolbar\":{\"toolbarCollapse\":\"Smanji alatnu traku\",\"toolbarExpand\":\"Proširi alatnu traku\",\"toolbarGroups\":{\"document\":\"Dokument\",\"clipboard\":\"Međuspremnik/Poništi\",\"editing\":\"Uređivanje\",\"forms\":\"Forme\",\"basicstyles\":\"Osnovni stilovi\",\"paragraph\":\"Paragraf\",\"links\":\"Veze\",\"insert\":\"Umetni\",\"styles\":\"Stilovi\",\"colors\":\"Boje\",\"tools\":\"Alatke\"},\"toolbars\":\"Alatne trake uređivača teksta\"},\"elementspath\":{\"eleLabel\":\"Putanja elemenata\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Format\",\"tag_address\":\"Address\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatirano\"},\"horizontalrule\":{\"toolbar\":\"Ubaci vodoravnu liniju\"},\"image\":{\"alertUrl\":\"Unesite URL slike\",\"alt\":\"Alternativni tekst\",\"border\":\"Okvir\",\"btnUpload\":\"Pošalji na server\",\"button2Img\":\"Želite li promijeniti odabrani gumb u jednostavnu sliku?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Želite li promijeniti odabranu sliku u gumb?\",\"infoTab\":\"Info slike\",\"linkTab\":\"Link\",\"lockRatio\":\"Zaključaj odnos\",\"menu\":\"Svojstva slika\",\"resetSize\":\"Obriši veličinu\",\"title\":\"Svojstva slika\",\"titleButton\":\"Image Button svojstva\",\"upload\":\"Pošalji\",\"urlMissing\":\"Nedostaje URL slike.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Okvir mora biti cijeli broj.\",\"validateHSpace\":\"HSpace mora biti cijeli broj\",\"validateVSpace\":\"VSpace mora biti cijeli broj.\"},\"indent\":{\"indent\":\"Pomakni udesno\",\"outdent\":\"Pomakni ulijevo\"},\"fakeobjects\":{\"anchor\":\"Sidro\",\"flash\":\"Flash animacija\",\"hiddenfield\":\"Sakriveno polje\",\"iframe\":\"IFrame\",\"unknown\":\"Nepoznati objekt\"},\"link\":{\"acccessKey\":\"Pristupna tipka\",\"advanced\":\"Napredno\",\"advisoryContentType\":\"Advisory vrsta sadržaja\",\"advisoryTitle\":\"Advisory naslov\",\"anchor\":{\"toolbar\":\"Ubaci/promijeni sidro\",\"menu\":\"Svojstva sidra\",\"title\":\"Svojstva sidra\",\"name\":\"Ime sidra\",\"errorName\":\"Molimo unesite ime sidra\",\"remove\":\"Ukloni sidro\"},\"anchorId\":\"Po Id elementa\",\"anchorName\":\"Po nazivu sidra\",\"charset\":\"Kodna stranica povezanih resursa\",\"cssClasses\":\"Stylesheet klase\",\"emailAddress\":\"E-Mail adresa\",\"emailBody\":\"Sadržaj poruke\",\"emailSubject\":\"Naslov\",\"id\":\"Id\",\"info\":\"Link Info\",\"langCode\":\"Smjer jezika\",\"langDir\":\"Smjer jezika\",\"langDirLTR\":\"S lijeva na desno (LTR)\",\"langDirRTL\":\"S desna na lijevo (RTL)\",\"menu\":\"Promijeni link\",\"name\":\"Naziv\",\"noAnchors\":\"(Nema dostupnih sidra)\",\"noEmail\":\"Molimo upišite e-mail adresu\",\"noUrl\":\"Molimo upišite URL link\",\"other\":\"<drugi>\",\"popupDependent\":\"Ovisno (Netscape)\",\"popupFeatures\":\"Mogućnosti popup prozora\",\"popupFullScreen\":\"Cijeli ekran (IE)\",\"popupLeft\":\"Lijeva pozicija\",\"popupLocationBar\":\"Traka za lokaciju\",\"popupMenuBar\":\"Izborna traka\",\"popupResizable\":\"Promjenjiva veličina\",\"popupScrollBars\":\"Scroll traka\",\"popupStatusBar\":\"Statusna traka\",\"popupToolbar\":\"Traka s alatima\",\"popupTop\":\"Gornja pozicija\",\"rel\":\"Veza\",\"selectAnchor\":\"Odaberi sidro\",\"styles\":\"Stil\",\"tabIndex\":\"Tab Indeks\",\"target\":\"Meta\",\"targetFrame\":\"<okvir>\",\"targetFrameName\":\"Ime ciljnog okvira\",\"targetPopup\":\"<popup prozor>\",\"targetPopupName\":\"Naziv popup prozora\",\"title\":\"Link\",\"toAnchor\":\"Sidro na ovoj stranici\",\"toEmail\":\"E-Mail\",\"toUrl\":\"URL\",\"toolbar\":\"Ubaci/promijeni link\",\"type\":\"Link vrsta\",\"unlink\":\"Ukloni link\",\"upload\":\"Pošalji\"},\"list\":{\"bulletedlist\":\"Obična lista\",\"numberedlist\":\"Brojčana lista\"},\"magicline\":{\"title\":\"Ubaci paragraf ovdje\"},\"maximize\":{\"maximize\":\"Povećaj\",\"minimize\":\"Smanji\"},\"pastetext\":{\"button\":\"Zalijepi kao čisti tekst\",\"title\":\"Zalijepi kao čisti tekst\"},\"pastefromword\":{\"confirmCleanup\":\"Tekst koji želite zalijepiti čini se da je kopiran iz Worda. Želite li prije očistiti tekst?\",\"error\":\"Nije moguće očistiti podatke za ljepljenje zbog interne greške\",\"title\":\"Zalijepi iz Worda\",\"toolbar\":\"Zalijepi iz Worda\"},\"removeformat\":{\"toolbar\":\"Ukloni formatiranje\"},\"sourcearea\":{\"toolbar\":\"Kôd\"},\"specialchar\":{\"options\":\"Opcije specijalnih znakova\",\"title\":\"Odaberite posebni karakter\",\"toolbar\":\"Ubaci posebne znakove\"},\"scayt\":{\"about\":\"O SCAYT\",\"aboutTab\":\"O SCAYT\",\"addWord\":\"Dodaj riječ\",\"allCaps\":\"Ignoriraj riječi s velikim slovima\",\"dic_create\":\"Napravi\",\"dic_delete\":\"Obriši\",\"dic_field_name\":\"Naziv riječnika\",\"dic_info\":\"Na početku se korisnički Riječnik sprema u Cookie. Nažalost, veličina im je ograničena. Kada korisnički Riječnik naraste preko te veličine, Riječnik će biti smješten na naš server. Kako bi se korisnički Riječnik spremio na naš server morate odabrati naziv Vašeg Riječnika. Ukoliko ste već prije spremali Riječnik na naše servere, unesite naziv Riječnika i pritisnite na Povrati.\",\"dic_rename\":\"Promijeni naziv\",\"dic_restore\":\"Povrati\",\"dictionariesTab\":\"Rječnici\",\"disable\":\"Onemogući SCAYT\",\"emptyDic\":\"Naziv rječnika ne smije biti prazno.\",\"enable\":\"Omogući SCAYT\",\"ignore\":\"Zanemari\",\"ignoreAll\":\"Zanemari sve\",\"ignoreDomainNames\":\"Ignoriraj nazive domena\",\"langs\":\"Jezici\",\"languagesTab\":\"Jezici\",\"mixedCase\":\"Ignoriraj riječi s miješanim slovima\",\"mixedWithDigits\":\"Ignoriraj riječi s brojevima\",\"moreSuggestions\":\"Više prijedloga\",\"opera_title\":\"Nije podržano u Operi\",\"options\":\"Opcije\",\"optionsTab\":\"Opcije\",\"title\":\"Provjeri pravopis tijekom tipkanja (SCAYT)\",\"toggle\":\"Omoguću/Onemogući SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stil\",\"panelTitle\":\"Stilovi formatiranja\",\"panelTitle1\":\"Block stilovi\",\"panelTitle2\":\"Inline stilovi\",\"panelTitle3\":\"Object stilovi\"},\"table\":{\"border\":\"Veličina okvira\",\"caption\":\"Naslov\",\"cell\":{\"menu\":\"Ćelija\",\"insertBefore\":\"Ubaci ćeliju prije\",\"insertAfter\":\"Ubaci ćeliju poslije\",\"deleteCell\":\"Izbriši ćelije\",\"merge\":\"Spoji ćelije\",\"mergeRight\":\"Spoji desno\",\"mergeDown\":\"Spoji dolje\",\"splitHorizontal\":\"Podijeli ćeliju vodoravno\",\"splitVertical\":\"Podijeli ćeliju okomito\",\"title\":\"Svojstva ćelije\",\"cellType\":\"Vrsta ćelije\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Prelazak u novi red\",\"hAlign\":\"Vodoravno poravnanje\",\"vAlign\":\"Okomito poravnanje\",\"alignBaseline\":\"Osnovna linija\",\"bgColor\":\"Boja pozadine\",\"borderColor\":\"Boja ruba\",\"data\":\"Podatak\",\"header\":\"Zaglavlje\",\"yes\":\"Da\",\"no\":\"ne\",\"invalidWidth\":\"Širina ćelije mora biti broj.\",\"invalidHeight\":\"Visina ćelije mora biti broj.\",\"invalidRowSpan\":\"Rows span mora biti cijeli broj.\",\"invalidColSpan\":\"Columns span mora biti cijeli broj.\",\"chooseColor\":\"Odaberi\"},\"cellPad\":\"Razmak ćelija\",\"cellSpace\":\"Prostornost ćelija\",\"column\":{\"menu\":\"Kolona\",\"insertBefore\":\"Ubaci kolonu prije\",\"insertAfter\":\"Ubaci kolonu poslije\",\"deleteColumn\":\"Izbriši kolone\"},\"columns\":\"Kolona\",\"deleteTable\":\"Izbriši tablicu\",\"headers\":\"Zaglavlje\",\"headersBoth\":\"Oba\",\"headersColumn\":\"Prva kolona\",\"headersNone\":\"Ništa\",\"headersRow\":\"Prvi red\",\"invalidBorder\":\"Debljina ruba mora biti broj.\",\"invalidCellPadding\":\"Razmak ćelija mora biti broj.\",\"invalidCellSpacing\":\"Prostornost ćelija mora biti broj.\",\"invalidCols\":\"Broj kolona mora biti broj veći od 0.\",\"invalidHeight\":\"Visina tablice mora biti broj.\",\"invalidRows\":\"Broj redova mora biti broj veći od 0.\",\"invalidWidth\":\"Širina tablice mora biti broj.\",\"menu\":\"Svojstva tablice\",\"row\":{\"menu\":\"Red\",\"insertBefore\":\"Ubaci red prije\",\"insertAfter\":\"Ubaci red poslije\",\"deleteRow\":\"Izbriši redove\"},\"rows\":\"Redova\",\"summary\":\"Sažetak\",\"title\":\"Svojstva tablice\",\"toolbar\":\"Tablica\",\"widthPc\":\"postotaka\",\"widthPx\":\"piksela\",\"widthUnit\":\"jedinica širine\"},\"undo\":{\"redo\":\"Ponovi\",\"undo\":\"Poništi\"},\"wsc\":{\"btnIgnore\":\"Zanemari\",\"btnIgnoreAll\":\"Zanemari sve\",\"btnReplace\":\"Zamijeni\",\"btnReplaceAll\":\"Zamijeni sve\",\"btnUndo\":\"Vrati\",\"changeTo\":\"Promijeni u\",\"errorLoading\":\"Greška učitavanja aplikacije: %s.\",\"ieSpellDownload\":\"Provjera pravopisa nije instalirana. Želite li skinuti provjeru pravopisa?\",\"manyChanges\":\"Provjera završena: Promijenjeno %1 riječi\",\"noChanges\":\"Provjera završena: Nije napravljena promjena\",\"noMispell\":\"Provjera završena: Nema grešaka\",\"noSuggestions\":\"-Nema preporuke-\",\"notAvailable\":\"Žao nam je, ali usluga trenutno nije dostupna.\",\"notInDic\":\"Nije u rječniku\",\"oneChange\":\"Provjera završena: Jedna riječ promjenjena\",\"progress\":\"Provjera u tijeku...\",\"title\":\"Provjera pravopisa\",\"toolbar\":\"Provjeri pravopis\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/hu.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['hu']={\"editor\":\"HTML szerkesztő\",\"editorPanel\":\"Rich Text szerkesztő panel\",\"common\":{\"editorHelp\":\"Segítségért nyomjon ALT 0\",\"browseServer\":\"Böngészés a szerveren\",\"url\":\"Hivatkozás\",\"protocol\":\"Protokoll\",\"upload\":\"Feltöltés\",\"uploadSubmit\":\"Küldés a szerverre\",\"image\":\"Kép\",\"flash\":\"Flash\",\"form\":\"Űrlap\",\"checkbox\":\"Jelölőnégyzet\",\"radio\":\"Választógomb\",\"textField\":\"Szövegmező\",\"textarea\":\"Szövegterület\",\"hiddenField\":\"Rejtettmező\",\"button\":\"Gomb\",\"select\":\"Legördülő lista\",\"imageButton\":\"Képgomb\",\"notSet\":\"<nincs beállítva>\",\"id\":\"Azonosító\",\"name\":\"Név\",\"langDir\":\"Írás iránya\",\"langDirLtr\":\"Balról jobbra\",\"langDirRtl\":\"Jobbról balra\",\"langCode\":\"Nyelv kódja\",\"longDescr\":\"Részletes leírás webcíme\",\"cssClass\":\"Stíluskészlet\",\"advisoryTitle\":\"Súgócimke\",\"cssStyle\":\"Stílus\",\"ok\":\"Rendben\",\"cancel\":\"Mégsem\",\"close\":\"Bezárás\",\"preview\":\"Előnézet\",\"resize\":\"Húzza az átméretezéshez\",\"generalTab\":\"Általános\",\"advancedTab\":\"További opciók\",\"validateNumberFailed\":\"A mezőbe csak számokat írhat.\",\"confirmNewPage\":\"Minden nem mentett változás el fog veszni! Biztosan be szeretné tölteni az oldalt?\",\"confirmCancel\":\"Az űrlap tartalma megváltozott, ám a változásokat nem rögzítette. Biztosan be szeretné zárni az űrlapot?\",\"options\":\"Beállítások\",\"target\":\"Cél\",\"targetNew\":\"Új ablak (_blank)\",\"targetTop\":\"Legfelső ablak (_top)\",\"targetSelf\":\"Aktuális ablakban (_self)\",\"targetParent\":\"Szülő ablak (_parent)\",\"langDirLTR\":\"Balról jobbra (LTR)\",\"langDirRTL\":\"Jobbról balra (RTL)\",\"styles\":\"Stílus\",\"cssClasses\":\"Stíluslap osztály\",\"width\":\"Szélesség\",\"height\":\"Magasság\",\"align\":\"Igazítás\",\"alignLeft\":\"Bal\",\"alignRight\":\"Jobbra\",\"alignCenter\":\"Középre\",\"alignTop\":\"Tetejére\",\"alignMiddle\":\"Középre\",\"alignBottom\":\"Aljára\",\"invalidValue\":\"Érvénytelen érték.\",\"invalidHeight\":\"A magasság mezőbe csak számokat írhat.\",\"invalidWidth\":\"A szélesség mezőbe csak számokat írhat.\",\"invalidCssLength\":\"\\\"%1\\\"-hez megadott érték csakis egy pozitív szám lehet, esetleg egy érvényes CSS egységgel megjelölve(px, %, in, cm, mm, em, ex, pt vagy pc).\",\"invalidHtmlLength\":\"\\\"%1\\\"-hez megadott érték csakis egy pozitív szám lehet, esetleg egy érvényes HTML egységgel megjelölve(px vagy %).\",\"invalidInlineStyle\":\"Az inline stílusnak megadott értéknek tartalmaznia kell egy vagy több rekordot a \\\"name : value\\\" formátumban, pontosvesszővel elválasztva.\",\"cssLengthTooltip\":\"Adjon meg egy számot értéknek pixelekben vagy egy számot érvényes CSS mértékegységben (px, %, in, cm, mm, em, ex, pt, vagy pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, nem elérhető</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Minden jog fenntartva.\",\"dlgTitle\":\"CKEditor névjegy\",\"help\":\"Itt találsz segítséget: $1\",\"moreInfo\":\"Licenszelési információkért kérjük látogassa meg weboldalunkat:\",\"title\":\"CKEditor névjegy\",\"userGuide\":\"CKEditor Felhasználói útmutató\"},\"basicstyles\":{\"bold\":\"Félkövér\",\"italic\":\"Dőlt\",\"strike\":\"Áthúzott\",\"subscript\":\"Alsó index\",\"superscript\":\"Felső index\",\"underline\":\"Aláhúzott\"},\"blockquote\":{\"toolbar\":\"Idézet blokk\"},\"clipboard\":{\"copy\":\"Másolás\",\"copyError\":\"A böngésző biztonsági beállításai nem engedélyezik a szerkesztőnek, hogy végrehajtsa a másolás műveletet. Használja az alábbi billentyűkombinációt (Ctrl/Cmd+X).\",\"cut\":\"Kivágás\",\"cutError\":\"A böngésző biztonsági beállításai nem engedélyezik a szerkesztőnek, hogy végrehajtsa a kivágás műveletet. Használja az alábbi billentyűkombinációt (Ctrl/Cmd+X).\",\"paste\":\"Beillesztés\",\"pasteArea\":\"Beszúrás mező\",\"pasteMsg\":\"Másolja be az alábbi mezőbe a <STRONG>Ctrl/Cmd+V</STRONG> billentyűk lenyomásával, majd nyomjon <STRONG>Rendben</STRONG>-t.\",\"securityMsg\":\"A böngésző biztonsági beállításai miatt a szerkesztő nem képes hozzáférni a vágólap adataihoz. Illeszd be újra ebben az ablakban.\",\"title\":\"Beillesztés\"},\"contextmenu\":{\"options\":\"Helyi menü opciók\"},\"toolbar\":{\"toolbarCollapse\":\"Eszköztár összecsukása\",\"toolbarExpand\":\"Eszköztár szétnyitása\",\"toolbarGroups\":{\"document\":\"Dokumentum\",\"clipboard\":\"Vágólap/Visszavonás\",\"editing\":\"Szerkesztés\",\"forms\":\"Űrlapok\",\"basicstyles\":\"Alapstílusok\",\"paragraph\":\"Bekezdés\",\"links\":\"Hivatkozások\",\"insert\":\"Beszúrás\",\"styles\":\"Stílusok\",\"colors\":\"Színek\",\"tools\":\"Eszközök\"},\"toolbars\":\"Szerkesztő Eszköztár\"},\"elementspath\":{\"eleLabel\":\"Elem utak\",\"eleTitle\":\"%1 elem\"},\"format\":{\"label\":\"Formátum\",\"panelTitle\":\"Formátum\",\"tag_address\":\"Címsor\",\"tag_div\":\"Bekezdés (DIV)\",\"tag_h1\":\"Fejléc 1\",\"tag_h2\":\"Fejléc 2\",\"tag_h3\":\"Fejléc 3\",\"tag_h4\":\"Fejléc 4\",\"tag_h5\":\"Fejléc 5\",\"tag_h6\":\"Fejléc 6\",\"tag_p\":\"Normál\",\"tag_pre\":\"Formázott\"},\"horizontalrule\":{\"toolbar\":\"Elválasztóvonal beillesztése\"},\"image\":{\"alertUrl\":\"Töltse ki a kép webcímét\",\"alt\":\"Buborék szöveg\",\"border\":\"Keret\",\"btnUpload\":\"Küldés a szerverre\",\"button2Img\":\"A kiválasztott képgombból sima képet szeretne csinálni?\",\"hSpace\":\"Vízsz. táv\",\"img2Button\":\"A kiválasztott képből képgombot szeretne csinálni?\",\"infoTab\":\"Alaptulajdonságok\",\"linkTab\":\"Hivatkozás\",\"lockRatio\":\"Arány megtartása\",\"menu\":\"Kép tulajdonságai\",\"resetSize\":\"Eredeti méret\",\"title\":\"Kép tulajdonságai\",\"titleButton\":\"Képgomb tulajdonságai\",\"upload\":\"Feltöltés\",\"urlMissing\":\"Hiányzik a kép URL-je\",\"vSpace\":\"Függ. táv\",\"validateBorder\":\"A keret méretének egész számot kell beírni!\",\"validateHSpace\":\"Vízszintes távolságnak egész számot kell beírni!\",\"validateVSpace\":\"Függőleges távolságnak egész számot kell beírni!\"},\"indent\":{\"indent\":\"Behúzás növelése\",\"outdent\":\"Behúzás csökkentése\"},\"fakeobjects\":{\"anchor\":\"Horgony\",\"flash\":\"Flash animáció\",\"hiddenfield\":\"Rejtett mezõ\",\"iframe\":\"IFrame\",\"unknown\":\"Ismeretlen objektum\"},\"link\":{\"acccessKey\":\"Billentyűkombináció\",\"advanced\":\"További opciók\",\"advisoryContentType\":\"Súgó tartalomtípusa\",\"advisoryTitle\":\"Súgócimke\",\"anchor\":{\"toolbar\":\"Horgony beillesztése/szerkesztése\",\"menu\":\"Horgony tulajdonságai\",\"title\":\"Horgony tulajdonságai\",\"name\":\"Horgony neve\",\"errorName\":\"Kérem adja meg a horgony nevét\",\"remove\":\"Horgony eltávolítása\"},\"anchorId\":\"Azonosító szerint\",\"anchorName\":\"Horgony név szerint\",\"charset\":\"Hivatkozott tartalom kódlapja\",\"cssClasses\":\"Stíluskészlet\",\"emailAddress\":\"E-Mail cím\",\"emailBody\":\"Üzenet\",\"emailSubject\":\"Üzenet tárgya\",\"id\":\"Id\",\"info\":\"Alaptulajdonságok\",\"langCode\":\"Írás iránya\",\"langDir\":\"Írás iránya\",\"langDirLTR\":\"Balról jobbra\",\"langDirRTL\":\"Jobbról balra\",\"menu\":\"Hivatkozás módosítása\",\"name\":\"Név\",\"noAnchors\":\"(Nincs horgony a dokumentumban)\",\"noEmail\":\"Adja meg az E-Mail címet\",\"noUrl\":\"Adja meg a hivatkozás webcímét\",\"other\":\"<más>\",\"popupDependent\":\"Szülőhöz kapcsolt (csak Netscape)\",\"popupFeatures\":\"Felugró ablak jellemzői\",\"popupFullScreen\":\"Teljes képernyő (csak IE)\",\"popupLeft\":\"Bal pozíció\",\"popupLocationBar\":\"Címsor\",\"popupMenuBar\":\"Menü sor\",\"popupResizable\":\"Átméretezés\",\"popupScrollBars\":\"Gördítősáv\",\"popupStatusBar\":\"Állapotsor\",\"popupToolbar\":\"Eszköztár\",\"popupTop\":\"Felső pozíció\",\"rel\":\"Kapcsolat típusa\",\"selectAnchor\":\"Horgony választása\",\"styles\":\"Stílus\",\"tabIndex\":\"Tabulátor index\",\"target\":\"Tartalom megjelenítése\",\"targetFrame\":\"<keretben>\",\"targetFrameName\":\"Keret neve\",\"targetPopup\":\"<felugró ablakban>\",\"targetPopupName\":\"Felugró ablak neve\",\"title\":\"Hivatkozás tulajdonságai\",\"toAnchor\":\"Horgony az oldalon\",\"toEmail\":\"E-Mail\",\"toUrl\":\"URL\",\"toolbar\":\"Hivatkozás beillesztése/módosítása\",\"type\":\"Hivatkozás típusa\",\"unlink\":\"Hivatkozás törlése\",\"upload\":\"Feltöltés\"},\"list\":{\"bulletedlist\":\"Felsorolás\",\"numberedlist\":\"Számozás\"},\"magicline\":{\"title\":\"Szúrja be a bekezdést ide\"},\"maximize\":{\"maximize\":\"Teljes méret\",\"minimize\":\"Kis méret\"},\"pastetext\":{\"button\":\"Beillesztés formázatlan szövegként\",\"title\":\"Beillesztés formázatlan szövegként\"},\"pastefromword\":{\"confirmCleanup\":\"Úgy tűnik a beillesztett szöveget Word-ből másolt át. Meg szeretné tisztítani a szöveget? (ajánlott)\",\"error\":\"Egy belső hiba miatt nem sikerült megtisztítani a szöveget\",\"title\":\"Beillesztés Word-ből\",\"toolbar\":\"Beillesztés Word-ből\"},\"removeformat\":{\"toolbar\":\"Formázás eltávolítása\"},\"sourcearea\":{\"toolbar\":\"Forráskód\"},\"specialchar\":{\"options\":\"Speciális karakter opciók\",\"title\":\"Speciális karakter választása\",\"toolbar\":\"Speciális karakter beillesztése\"},\"scayt\":{\"about\":\"SCAYT névjegy\",\"aboutTab\":\"Névjegy\",\"addWord\":\"Szó hozzáadása\",\"allCaps\":\"Nagybetűs szavak kihagyása\",\"dic_create\":\"Létrehozás\",\"dic_delete\":\"Törlés\",\"dic_field_name\":\"Szótár neve\",\"dic_info\":\"Kezdetben a felhasználói szótár böngésző sütiben tárolódik. Azonban a sütik maximális mérete korlátozott. Amikora a szótár akkora lesz, hogy már sütiben nem lehet tárolni, akkor a szótárat tárolhatja a szerveren is. Ehhez egy nevet kell megadni a szótárhoz. Amennyiben már van szerveren tárolt szótára, adja meg a nevét és kattintson a visszaállítás gombra.\",\"dic_rename\":\"Átnevezés\",\"dic_restore\":\"Visszaállítás\",\"dictionariesTab\":\"Szótár\",\"disable\":\"SCAYT letiltása\",\"emptyDic\":\"A szótár nevét meg kell adni.\",\"enable\":\"SCAYT engedélyezése\",\"ignore\":\"Kihagy\",\"ignoreAll\":\"Összes kihagyása\",\"ignoreDomainNames\":\"Domain nevek kihagyása\",\"langs\":\"Nyelvek\",\"languagesTab\":\"Nyelvek\",\"mixedCase\":\"Kis és nagybetűt is tartalmazó szavak kihagyása\",\"mixedWithDigits\":\"Számokat tartalmazó szavak kihagyása\",\"moreSuggestions\":\"További javaslatok\",\"opera_title\":\"Az Opera nem támogatja\",\"options\":\"Beállítások\",\"optionsTab\":\"Beállítások\",\"title\":\"Helyesírás ellenőrzés gépelés közben\",\"toggle\":\"SCAYT kapcsolása\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stílus\",\"panelTitle\":\"Formázási stílusok\",\"panelTitle1\":\"Blokk stílusok\",\"panelTitle2\":\"Inline stílusok\",\"panelTitle3\":\"Objektum stílusok\"},\"table\":{\"border\":\"Szegélyméret\",\"caption\":\"Felirat\",\"cell\":{\"menu\":\"Cella\",\"insertBefore\":\"Beszúrás balra\",\"insertAfter\":\"Beszúrás jobbra\",\"deleteCell\":\"Cellák törlése\",\"merge\":\"Cellák egyesítése\",\"mergeRight\":\"Cellák egyesítése jobbra\",\"mergeDown\":\"Cellák egyesítése lefelé\",\"splitHorizontal\":\"Cellák szétválasztása vízszintesen\",\"splitVertical\":\"Cellák szétválasztása függőlegesen\",\"title\":\"Cella tulajdonságai\",\"cellType\":\"Cella típusa\",\"rowSpan\":\"Függőleges egyesítés\",\"colSpan\":\"Vízszintes egyesítés\",\"wordWrap\":\"Hosszú sorok törése\",\"hAlign\":\"Vízszintes igazítás\",\"vAlign\":\"Függőleges igazítás\",\"alignBaseline\":\"Alapvonalra\",\"bgColor\":\"Háttér színe\",\"borderColor\":\"Keret színe\",\"data\":\"Adat\",\"header\":\"Fejléc\",\"yes\":\"Igen\",\"no\":\"Nem\",\"invalidWidth\":\"A szélesség mezőbe csak számokat írhat.\",\"invalidHeight\":\"A magasság mezőbe csak számokat írhat.\",\"invalidRowSpan\":\"A függőleges egyesítés mezőbe csak számokat írhat.\",\"invalidColSpan\":\"A vízszintes egyesítés mezőbe csak számokat írhat.\",\"chooseColor\":\"Válasszon\"},\"cellPad\":\"Cella belső margó\",\"cellSpace\":\"Cella térköz\",\"column\":{\"menu\":\"Oszlop\",\"insertBefore\":\"Beszúrás balra\",\"insertAfter\":\"Beszúrás jobbra\",\"deleteColumn\":\"Oszlopok törlése\"},\"columns\":\"Oszlopok\",\"deleteTable\":\"Táblázat törlése\",\"headers\":\"Fejlécek\",\"headersBoth\":\"Mindkettő\",\"headersColumn\":\"Első oszlop\",\"headersNone\":\"Nincsenek\",\"headersRow\":\"Első sor\",\"invalidBorder\":\"A szegélyméret mezőbe csak számokat írhat.\",\"invalidCellPadding\":\"A cella belső margó mezőbe csak számokat írhat.\",\"invalidCellSpacing\":\"A cella térköz mezőbe csak számokat írhat.\",\"invalidCols\":\"Az oszlopok számának nagyobbnak kell lenni mint 0.\",\"invalidHeight\":\"A magasság mezőbe csak számokat írhat.\",\"invalidRows\":\"A sorok számának nagyobbnak kell lenni mint 0.\",\"invalidWidth\":\"A szélesség mezőbe csak számokat írhat.\",\"menu\":\"Táblázat tulajdonságai\",\"row\":{\"menu\":\"Sor\",\"insertBefore\":\"Beszúrás fölé\",\"insertAfter\":\"Beszúrás alá\",\"deleteRow\":\"Sorok törlése\"},\"rows\":\"Sorok\",\"summary\":\"Leírás\",\"title\":\"Táblázat tulajdonságai\",\"toolbar\":\"Táblázat\",\"widthPc\":\"százalék\",\"widthPx\":\"képpont\",\"widthUnit\":\"Szélesség egység\"},\"undo\":{\"redo\":\"Ismétlés\",\"undo\":\"Visszavonás\"},\"wsc\":{\"btnIgnore\":\"Kihagyja\",\"btnIgnoreAll\":\"Mindet kihagyja\",\"btnReplace\":\"Csere\",\"btnReplaceAll\":\"Összes cseréje\",\"btnUndo\":\"Visszavonás\",\"changeTo\":\"Módosítás\",\"errorLoading\":\"Hiba a szolgáltatás host betöltése közben: %s.\",\"ieSpellDownload\":\"A helyesírás-ellenőrző nincs telepítve. Szeretné letölteni most?\",\"manyChanges\":\"Helyesírás-ellenőrzés kész: %1 szó cserélve\",\"noChanges\":\"Helyesírás-ellenőrzés kész: Nincs változtatott szó\",\"noMispell\":\"Helyesírás-ellenőrzés kész: Nem találtam hibát\",\"noSuggestions\":\"Nincs javaslat\",\"notAvailable\":\"Sajnálom, de a szolgáltatás jelenleg nem elérhető.\",\"notInDic\":\"Nincs a szótárban\",\"oneChange\":\"Helyesírás-ellenőrzés kész: Egy szó cserélve\",\"progress\":\"Helyesírás-ellenőrzés folyamatban...\",\"title\":\"Helyesírás ellenörző\",\"toolbar\":\"Helyesírás-ellenőrzés\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/id.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['id']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Tekan ALT 0 untuk bantuan.\",\"browseServer\":\"Jelajah Server\",\"url\":\"URL\",\"protocol\":\"Protokol\",\"upload\":\"Unggah\",\"uploadSubmit\":\"Kirim ke Server\",\"image\":\"Gambar\",\"flash\":\"Flash\",\"form\":\"Formulir\",\"checkbox\":\"Kotak Cek\",\"radio\":\"Tombol Radio\",\"textField\":\"Kolom Teks\",\"textarea\":\"Area Teks\",\"hiddenField\":\"Kolom Tersembunyi\",\"button\":\"Tombol\",\"select\":\"Kolom Seleksi\",\"imageButton\":\"Tombol Gambar\",\"notSet\":\"<tidak diatur>\",\"id\":\"Id\",\"name\":\"Nama\",\"langDir\":\"Arah Bahasa\",\"langDirLtr\":\"Kiri ke Kanan (LTR)\",\"langDirRtl\":\"Kanan ke Kiri\",\"langCode\":\"Kode Bahasa\",\"longDescr\":\"Deskripsi URL Panjang\",\"cssClass\":\"Kelas Stylesheet\",\"advisoryTitle\":\"Penasehat Judul\",\"cssStyle\":\"Gaya\",\"ok\":\"OK\",\"cancel\":\"Batal\",\"close\":\"Tutup\",\"preview\":\"Pratinjau\",\"resize\":\"Ubah ukuran\",\"generalTab\":\"Umum\",\"advancedTab\":\"Advanced\",\"validateNumberFailed\":\"Nilai ini tidak sebuah angka\",\"confirmNewPage\":\"Semua perubahan yang tidak disimpan di konten ini akan hilang. Apakah anda yakin ingin memuat halaman baru?\",\"confirmCancel\":\"Beberapa opsi telah berubah. Apakah anda yakin ingin menutup dialog?\",\"options\":\"Opsi\",\"target\":\"Sasaran\",\"targetNew\":\"Jendela Baru (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Jendela yang Sama (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"Kiri ke Kanan (LTR)\",\"langDirRTL\":\"Kanan ke Kiri (RTL)\",\"styles\":\"Gaya\",\"cssClasses\":\"Kelas Stylesheet\",\"width\":\"Lebar\",\"height\":\"Tinggi\",\"align\":\"Penjajaran\",\"alignLeft\":\"Kiri\",\"alignRight\":\"Kanan\",\"alignCenter\":\"Tengah\",\"alignTop\":\"Atas\",\"alignMiddle\":\"Tengah\",\"alignBottom\":\"Bawah\",\"invalidValue\":\"Nilai tidak sah.\",\"invalidHeight\":\"Tinggi harus sebuah angka.\",\"invalidWidth\":\"Lebar harus sebuah angka.\",\"invalidCssLength\":\"Nilai untuk \\\"%1\\\" harus sebuah angkat positif dengan atau tanpa pengukuran unit CSS yang sah (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Nilai yang dispesifikasian untuk kolom \\\"%1\\\" harus sebuah angka positif dengan atau tanpa sebuah unit pengukuran HTML (px atau %) yang valid.\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Masukkan sebuah angka untuk sebuah nilai dalam pixel atau sebuah angka dengan unit CSS yang sah (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, tidak tersedia</span>\"},\"about\":{\"copy\":\"Hak cipta &copy; $1. All rights reserved.\",\"dlgTitle\":\"Tentang CKEditor\",\"help\":\"Cel $1 untuk bantuan.\",\"moreInfo\":\"Untuk informasi lisensi silahkan kunjungi web site kami:\",\"title\":\"Tentang CKEditor\",\"userGuide\":\"Petunjuk Pengguna CKEditor\"},\"basicstyles\":{\"bold\":\"Huruf Tebal\",\"italic\":\"Huruf Miring\",\"strike\":\"Strike Through\",\"subscript\":\"Subscript\",\"superscript\":\"Superscript\",\"underline\":\"Garis Bawah\"},\"blockquote\":{\"toolbar\":\"Kutipan Blok\"},\"clipboard\":{\"copy\":\"Salin\",\"copyError\":\"Pengaturan keamanan peramban anda tidak mengizinkan editor untuk mengeksekusi operasi menyalin secara otomatis. Mohon gunakan papan tuts (Ctrl/Cmd+C)\",\"cut\":\"Potong\",\"cutError\":\"Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).\",\"paste\":\"Tempel\",\"pasteArea\":\"Area Tempel\",\"pasteMsg\":\"Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK\",\"securityMsg\":\"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.\",\"title\":\"Tempel\"},\"contextmenu\":{\"options\":\"Opsi Konteks Pilihan\"},\"toolbar\":{\"toolbarCollapse\":\"Ciutkan Toolbar\",\"toolbarExpand\":\"Bentangkan Toolbar\",\"toolbarGroups\":{\"document\":\"Dokumen\",\"clipboard\":\"Papan klip / Kembalikan perlakuan\",\"editing\":\"Sunting\",\"forms\":\"Formulir\",\"basicstyles\":\"Gaya Dasar\",\"paragraph\":\"Paragraf\",\"links\":\"Tautan\",\"insert\":\"Sisip\",\"styles\":\"Gaya\",\"colors\":\"Warna\",\"tools\":\"Alat\"},\"toolbars\":\"Editor toolbars\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Bentuk\",\"panelTitle\":\"Bentuk Paragraf\",\"tag_address\":\"Alamat\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Membentuk\"},\"horizontalrule\":{\"toolbar\":\"Sisip Garis Horisontal\"},\"image\":{\"alertUrl\":\"Mohon tulis URL gambar\",\"alt\":\"Teks alternatif\",\"border\":\"Batas\",\"btnUpload\":\"Kirim ke Server\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"Info Gambar\",\"linkTab\":\"Tautan\",\"lockRatio\":\"Lock Ratio\",\"menu\":\"Image Properties\",\"resetSize\":\"Reset Size\",\"title\":\"Image Properties\",\"titleButton\":\"Image Button Properties\",\"upload\":\"Unggah\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"Tingkatkan Lekuk\",\"outdent\":\"Kurangi Lekuk\"},\"fakeobjects\":{\"anchor\":\"Anchor\",\"flash\":\"Animasi Flash\",\"hiddenfield\":\"Kolom Tersembunyi\",\"iframe\":\"IFrame\",\"unknown\":\"Obyek Tak Dikenal\"},\"link\":{\"acccessKey\":\"Access Key\",\"advanced\":\"Advanced\",\"advisoryContentType\":\"Advisory Content Type\",\"advisoryTitle\":\"Penasehat Judul\",\"anchor\":{\"toolbar\":\"Anchor\",\"menu\":\"Edit Anchor\",\"title\":\"Anchor Properties\",\"name\":\"Anchor Name\",\"errorName\":\"Please type the anchor name\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"By Element Id\",\"anchorName\":\"By Anchor Name\",\"charset\":\"Linked Resource Charset\",\"cssClasses\":\"Kelas Stylesheet\",\"emailAddress\":\"E-Mail Address\",\"emailBody\":\"Message Body\",\"emailSubject\":\"Message Subject\",\"id\":\"Id\",\"info\":\"Link Info\",\"langCode\":\"Kode Bahasa\",\"langDir\":\"Arah Bahasa\",\"langDirLTR\":\"Kiri ke Kanan (LTR)\",\"langDirRTL\":\"Kanan ke Kiri (RTL)\",\"menu\":\"Edit Link\",\"name\":\"Nama\",\"noAnchors\":\"(No anchors available in the document)\",\"noEmail\":\"Please type the e-mail address\",\"noUrl\":\"Please type the link URL\",\"other\":\"<other>\",\"popupDependent\":\"Dependent (Netscape)\",\"popupFeatures\":\"Popup Window Features\",\"popupFullScreen\":\"Full Screen (IE)\",\"popupLeft\":\"Left Position\",\"popupLocationBar\":\"Location Bar\",\"popupMenuBar\":\"Menu Bar\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"Scroll Bars\",\"popupStatusBar\":\"Status Bar\",\"popupToolbar\":\"Toolbar\",\"popupTop\":\"Top Position\",\"rel\":\"Relationship\",\"selectAnchor\":\"Select an Anchor\",\"styles\":\"Gaya\",\"tabIndex\":\"Tab Index\",\"target\":\"Sasaran\",\"targetFrame\":\"<frame>\",\"targetFrameName\":\"Target Frame Name\",\"targetPopup\":\"<popup window>\",\"targetPopupName\":\"Popup Window Name\",\"title\":\"Tautan\",\"toAnchor\":\"Link to anchor in the text\",\"toEmail\":\"E-mail\",\"toUrl\":\"URL\",\"toolbar\":\"Tautan\",\"type\":\"Link Type\",\"unlink\":\"Unlink\",\"upload\":\"Unggah\"},\"list\":{\"bulletedlist\":\"Sisip/Hapus Daftar Bullet\",\"numberedlist\":\"Sisip/Hapus Daftar Bernomor\"},\"magicline\":{\"title\":\"Masukkan paragraf disini\"},\"maximize\":{\"maximize\":\"Memperbesar\",\"minimize\":\"Memperkecil\"},\"pastetext\":{\"button\":\"Tempel sebagai teks polos\",\"title\":\"Tempel sebagai Teks Polos\"},\"pastefromword\":{\"confirmCleanup\":\"Teks yang ingin anda tempel sepertinya di salin dari Word. Apakah anda mau membersihkannya sebelum menempel?\",\"error\":\"Tidak mungkin membersihkan data yang ditempel dikerenakan kesalahan internal\",\"title\":\"Tempel dari Word\",\"toolbar\":\"Tempel dari Word\"},\"removeformat\":{\"toolbar\":\"Hapus Format\"},\"sourcearea\":{\"toolbar\":\"Sumber\"},\"specialchar\":{\"options\":\"Opsi spesial karakter\",\"title\":\"Pilih spesial karakter\",\"toolbar\":\"Sisipkan spesial karakter\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Gaya\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"Ukuran batas\",\"caption\":\"Judul halaman\",\"cell\":{\"menu\":\"Sel\",\"insertBefore\":\"Sisip Sel Sebelum\",\"insertAfter\":\"Sisip Sel Setelah\",\"deleteCell\":\"Hapus Sel\",\"merge\":\"Gabungkan Sel\",\"mergeRight\":\"Gabungkan ke Kanan\",\"mergeDown\":\"Gabungkan ke Bawah\",\"splitHorizontal\":\"Pisahkan Sel Secara Horisontal\",\"splitVertical\":\"Pisahkan Sel Secara Vertikal\",\"title\":\"Properti Sel\",\"cellType\":\"Tipe Sel\",\"rowSpan\":\"Rentang antar baris\",\"colSpan\":\"Rentang antar kolom\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Jajaran Horisontal\",\"vAlign\":\"Jajaran Vertikal\",\"alignBaseline\":\"Dasar\",\"bgColor\":\"Warna Latar Belakang\",\"borderColor\":\"Warna Batasan\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Ya\",\"no\":\"Tidak\",\"invalidWidth\":\"Lebar sel harus sebuah angka.\",\"invalidHeight\":\"Tinggi sel harus sebuah angka\",\"invalidRowSpan\":\"Rentang antar baris harus angka seluruhnya.\",\"invalidColSpan\":\"Rentang antar kolom harus angka seluruhnya\",\"chooseColor\":\"Pilih\"},\"cellPad\":\"Sel spasi dalam\",\"cellSpace\":\"Spasi antar sel\",\"column\":{\"menu\":\"Kolom\",\"insertBefore\":\"Sisip Kolom Sebelum\",\"insertAfter\":\"Sisip Kolom Sesudah\",\"deleteColumn\":\"Hapus Kolom\"},\"columns\":\"Kolom\",\"deleteTable\":\"Hapus Tabel\",\"headers\":\"Headers\",\"headersBoth\":\"Keduanya\",\"headersColumn\":\"Kolom pertama\",\"headersNone\":\"Tidak ada\",\"headersRow\":\"Baris Pertama\",\"invalidBorder\":\"Ukuran batasan harus sebuah angka\",\"invalidCellPadding\":\"'Spasi dalam' sel harus angka positif.\",\"invalidCellSpacing\":\"Spasi antar sel harus angka positif.\",\"invalidCols\":\"Jumlah kolom harus sebuah angka lebih besar dari 0\",\"invalidHeight\":\"Tinggi tabel harus sebuah angka.\",\"invalidRows\":\"Jumlah barus harus sebuah angka dan lebih besar dari 0.\",\"invalidWidth\":\"Lebar tabel harus sebuah angka.\",\"menu\":\"Properti Tabel\",\"row\":{\"menu\":\"Baris\",\"insertBefore\":\"Sisip Baris Sebelum\",\"insertAfter\":\"Sisip Baris Sesudah\",\"deleteRow\":\"Hapus Baris\"},\"rows\":\"Baris\",\"summary\":\"Intisari\",\"title\":\"Properti Tabel\",\"toolbar\":\"Tabe\",\"widthPc\":\"persen\",\"widthPx\":\"piksel\",\"widthUnit\":\"lebar satuan\"},\"undo\":{\"redo\":\"Kembali lakukan\",\"undo\":\"Batalkan perlakuan\"},\"wsc\":{\"btnIgnore\":\"Ignore\",\"btnIgnoreAll\":\"Ignore All\",\"btnReplace\":\"Replace\",\"btnReplaceAll\":\"Replace All\",\"btnUndo\":\"Undo\",\"changeTo\":\"Change to\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Spell checker not installed. Do you want to download it now?\",\"manyChanges\":\"Spell check complete: %1 words changed\",\"noChanges\":\"Spell check complete: No words changed\",\"noMispell\":\"Spell check complete: No misspellings found\",\"noSuggestions\":\"- No suggestions -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Not in dictionary\",\"oneChange\":\"Spell check complete: One word changed\",\"progress\":\"Spell check in progress...\",\"title\":\"Spell Check\",\"toolbar\":\"Check Spelling\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/is.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['is']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Press ALT 0 for help\",\"browseServer\":\"Fletta í skjalasafni\",\"url\":\"Vefslóð\",\"protocol\":\"Samskiptastaðall\",\"upload\":\"Senda upp\",\"uploadSubmit\":\"Hlaða upp\",\"image\":\"Setja inn mynd\",\"flash\":\"Flash\",\"form\":\"Setja inn innsláttarform\",\"checkbox\":\"Setja inn hökunarreit\",\"radio\":\"Setja inn valhnapp\",\"textField\":\"Setja inn textareit\",\"textarea\":\"Setja inn textasvæði\",\"hiddenField\":\"Setja inn falið svæði\",\"button\":\"Setja inn hnapp\",\"select\":\"Setja inn lista\",\"imageButton\":\"Setja inn myndahnapp\",\"notSet\":\"<ekkert valið>\",\"id\":\"Auðkenni\",\"name\":\"Nafn\",\"langDir\":\"Lesstefna\",\"langDirLtr\":\"Frá vinstri til hægri (LTR)\",\"langDirRtl\":\"Frá hægri til vinstri (RTL)\",\"langCode\":\"Tungumálakóði\",\"longDescr\":\"Nánari lýsing\",\"cssClass\":\"Stílsniðsflokkur\",\"advisoryTitle\":\"Titill\",\"cssStyle\":\"Stíll\",\"ok\":\"Í lagi\",\"cancel\":\"Hætta við\",\"close\":\"Close\",\"preview\":\"Forskoða\",\"resize\":\"Resize\",\"generalTab\":\"Almennt\",\"advancedTab\":\"Tæknilegt\",\"validateNumberFailed\":\"This value is not a number.\",\"confirmNewPage\":\"Any unsaved changes to this content will be lost. Are you sure you want to load new page?\",\"confirmCancel\":\"You have changed some options. Are you sure you want to close the dialog window?\",\"options\":\"Options\",\"target\":\"Mark\",\"targetNew\":\"New Window (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Same Window (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"Frá vinstri til hægri (LTR)\",\"langDirRTL\":\"Frá hægri til vinstri (RTL)\",\"styles\":\"Stíll\",\"cssClasses\":\"Stílsniðsflokkur\",\"width\":\"Breidd\",\"height\":\"Hæð\",\"align\":\"Jöfnun\",\"alignLeft\":\"Vinstri\",\"alignRight\":\"Hægri\",\"alignCenter\":\"Miðjað\",\"alignTop\":\"Efst\",\"alignMiddle\":\"Miðjuð\",\"alignBottom\":\"Neðst\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Height must be a number.\",\"invalidWidth\":\"Width must be a number.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Feitletrað\",\"italic\":\"Skáletrað\",\"strike\":\"Yfirstrikað\",\"subscript\":\"Niðurskrifað\",\"superscript\":\"Uppskrifað\",\"underline\":\"Undirstrikað\"},\"blockquote\":{\"toolbar\":\"Inndráttur\"},\"clipboard\":{\"copy\":\"Afrita\",\"copyError\":\"Öryggisstillingar vafrans þíns leyfa ekki afritun texta með músaraðgerð. Notaðu lyklaborðið í afrita (Ctrl/Cmd+C).\",\"cut\":\"Klippa\",\"cutError\":\"Öryggisstillingar vafrans þíns leyfa ekki klippingu texta með músaraðgerð. Notaðu lyklaborðið í klippa (Ctrl/Cmd+X).\",\"paste\":\"Líma\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"Límdu í svæðið hér að neðan og (<STRONG>Ctrl/Cmd+V</STRONG>) og smelltu á <STRONG>OK</STRONG>.\",\"securityMsg\":\"Vegna öryggisstillinga í vafranum þínum fær ritillinn ekki beinan aðgang að klippuborðinu. Þú verður að líma innihaldið aftur inn í þennan glugga.\",\"title\":\"Líma\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Collapse Toolbar\",\"toolbarExpand\":\"Expand Toolbar\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editor toolbars\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Stílsnið\",\"panelTitle\":\"Stílsnið\",\"tag_address\":\"Vistfang\",\"tag_div\":\"Venjulegt (DIV)\",\"tag_h1\":\"Fyrirsögn 1\",\"tag_h2\":\"Fyrirsögn 2\",\"tag_h3\":\"Fyrirsögn 3\",\"tag_h4\":\"Fyrirsögn 4\",\"tag_h5\":\"Fyrirsögn 5\",\"tag_h6\":\"Fyrirsögn 6\",\"tag_p\":\"Venjulegt letur\",\"tag_pre\":\"Forsniðið\"},\"horizontalrule\":{\"toolbar\":\"Lóðrétt lína\"},\"image\":{\"alertUrl\":\"Sláðu inn slóðina að myndinni\",\"alt\":\"Baklægur texti\",\"border\":\"Rammi\",\"btnUpload\":\"Hlaða upp\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"Vinstri bil\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"Almennt\",\"linkTab\":\"Stikla\",\"lockRatio\":\"Festa stærðarhlutfall\",\"menu\":\"Eigindi myndar\",\"resetSize\":\"Reikna stærð\",\"title\":\"Eigindi myndar\",\"titleButton\":\"Eigindi myndahnapps\",\"upload\":\"Hlaða upp\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"Hægri bil\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"Minnka inndrátt\",\"outdent\":\"Auka inndrátt\"},\"fakeobjects\":{\"anchor\":\"Anchor\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Hidden Field\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"Skammvalshnappur\",\"advanced\":\"Tæknilegt\",\"advisoryContentType\":\"Tegund innihalds\",\"advisoryTitle\":\"Titill\",\"anchor\":{\"toolbar\":\"Stofna/breyta kaflamerki\",\"menu\":\"Eigindi kaflamerkis\",\"title\":\"Eigindi kaflamerkis\",\"name\":\"Nafn bókamerkis\",\"errorName\":\"Sláðu inn nafn bókamerkis!\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"Eftir auðkenni einingar\",\"anchorName\":\"Eftir akkerisnafni\",\"charset\":\"Táknróf\",\"cssClasses\":\"Stílsniðsflokkur\",\"emailAddress\":\"Netfang\",\"emailBody\":\"Meginmál\",\"emailSubject\":\"Efni\",\"id\":\"Auðkenni\",\"info\":\"Almennt\",\"langCode\":\"Lesstefna\",\"langDir\":\"Lesstefna\",\"langDirLTR\":\"Frá vinstri til hægri (LTR)\",\"langDirRTL\":\"Frá hægri til vinstri (RTL)\",\"menu\":\"Breyta stiklu\",\"name\":\"Nafn\",\"noAnchors\":\"<Engin bókamerki á skrá>\",\"noEmail\":\"Sláðu inn netfang!\",\"noUrl\":\"Sláðu inn veffang stiklunnar!\",\"other\":\"<annar>\",\"popupDependent\":\"Háð venslum (Netscape)\",\"popupFeatures\":\"Eigindi sprettiglugga\",\"popupFullScreen\":\"Heilskjár (IE)\",\"popupLeft\":\"Fjarlægð frá vinstri\",\"popupLocationBar\":\"Fanglína\",\"popupMenuBar\":\"Vallína\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"Skrunstikur\",\"popupStatusBar\":\"Stöðustika\",\"popupToolbar\":\"Verkfærastika\",\"popupTop\":\"Fjarlægð frá efri brún\",\"rel\":\"Relationship\",\"selectAnchor\":\"Veldu akkeri\",\"styles\":\"Stíll\",\"tabIndex\":\"Raðnúmer innsláttarreits\",\"target\":\"Mark\",\"targetFrame\":\"<rammi>\",\"targetFrameName\":\"Nafn markglugga\",\"targetPopup\":\"<sprettigluggi>\",\"targetPopupName\":\"Nafn sprettiglugga\",\"title\":\"Stikla\",\"toAnchor\":\"Bókamerki á þessari síðu\",\"toEmail\":\"Netfang\",\"toUrl\":\"Vefslóð\",\"toolbar\":\"Stofna/breyta stiklu\",\"type\":\"Stikluflokkur\",\"unlink\":\"Fjarlægja stiklu\",\"upload\":\"Senda upp\"},\"list\":{\"bulletedlist\":\"Punktalisti\",\"numberedlist\":\"Númeraður listi\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maximize\",\"minimize\":\"Minimize\"},\"pastetext\":{\"button\":\"Líma sem ósniðinn texta\",\"title\":\"Líma sem ósniðinn texta\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"Líma úr Word\",\"toolbar\":\"Líma úr Word\"},\"removeformat\":{\"toolbar\":\"Fjarlægja snið\"},\"sourcearea\":{\"toolbar\":\"Kóði\"},\"specialchar\":{\"options\":\"Special Character Options\",\"title\":\"Velja tákn\",\"toolbar\":\"Setja inn merki\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stílflokkur\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"Breidd ramma\",\"caption\":\"Titill\",\"cell\":{\"menu\":\"Reitur\",\"insertBefore\":\"Skjóta inn reiti fyrir aftan\",\"insertAfter\":\"Skjóta inn reiti fyrir framan\",\"deleteCell\":\"Fella reit\",\"merge\":\"Sameina reiti\",\"mergeRight\":\"Sameina til hægri\",\"mergeDown\":\"Sameina niður á við\",\"splitHorizontal\":\"Kljúfa reit lárétt\",\"splitVertical\":\"Kljúfa reit lóðrétt\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"Reitaspássía\",\"cellSpace\":\"Bil milli reita\",\"column\":{\"menu\":\"Dálkur\",\"insertBefore\":\"Skjóta inn dálki vinstra megin\",\"insertAfter\":\"Skjóta inn dálki hægra megin\",\"deleteColumn\":\"Fella dálk\"},\"columns\":\"Dálkar\",\"deleteTable\":\"Fella töflu\",\"headers\":\"Fyrirsagnir\",\"headersBoth\":\"Hvort tveggja\",\"headersColumn\":\"Fyrsti dálkur\",\"headersNone\":\"Engar\",\"headersRow\":\"Fyrsta röð\",\"invalidBorder\":\"Border size must be a number.\",\"invalidCellPadding\":\"Cell padding must be a positive number.\",\"invalidCellSpacing\":\"Cell spacing must be a positive number.\",\"invalidCols\":\"Number of columns must be a number greater than 0.\",\"invalidHeight\":\"Table height must be a number.\",\"invalidRows\":\"Number of rows must be a number greater than 0.\",\"invalidWidth\":\"Table width must be a number.\",\"menu\":\"Eigindi töflu\",\"row\":{\"menu\":\"Röð\",\"insertBefore\":\"Skjóta inn röð fyrir ofan\",\"insertAfter\":\"Skjóta inn röð fyrir neðan\",\"deleteRow\":\"Eyða röð\"},\"rows\":\"Raðir\",\"summary\":\"Áfram\",\"title\":\"Eigindi töflu\",\"toolbar\":\"Tafla\",\"widthPc\":\"prósent\",\"widthPx\":\"myndeindir\",\"widthUnit\":\"width unit\"},\"undo\":{\"redo\":\"Hætta við afturköllun\",\"undo\":\"Afturkalla\"},\"wsc\":{\"btnIgnore\":\"Hunsa\",\"btnIgnoreAll\":\"Hunsa allt\",\"btnReplace\":\"Skipta\",\"btnReplaceAll\":\"Skipta öllu\",\"btnUndo\":\"Til baka\",\"changeTo\":\"Tillaga\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Villuleit ekki sett upp.<br>Viltu setja hana upp?\",\"manyChanges\":\"Villuleit lokið: %1 orðum breytt\",\"noChanges\":\"Villuleit lokið: Engu orði breytt\",\"noMispell\":\"Villuleit lokið: Engin villa fannst\",\"noSuggestions\":\"- engar tillögur -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Ekki í orðabókinni\",\"oneChange\":\"Villuleit lokið: Einu orði breytt\",\"progress\":\"Villuleit í gangi...\",\"title\":\"Spell Check\",\"toolbar\":\"Villuleit\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/it.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['it']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Pannello Rich Text Editor\",\"common\":{\"editorHelp\":\"Premi ALT 0 per aiuto\",\"browseServer\":\"Cerca sul server\",\"url\":\"URL\",\"protocol\":\"Protocollo\",\"upload\":\"Carica\",\"uploadSubmit\":\"Invia al server\",\"image\":\"Immagine\",\"flash\":\"Oggetto Flash\",\"form\":\"Modulo\",\"checkbox\":\"Checkbox\",\"radio\":\"Radio Button\",\"textField\":\"Campo di testo\",\"textarea\":\"Area di testo\",\"hiddenField\":\"Campo nascosto\",\"button\":\"Bottone\",\"select\":\"Menu di selezione\",\"imageButton\":\"Bottone immagine\",\"notSet\":\"<non impostato>\",\"id\":\"Id\",\"name\":\"Nome\",\"langDir\":\"Direzione scrittura\",\"langDirLtr\":\"Da Sinistra a Destra (LTR)\",\"langDirRtl\":\"Da Destra a Sinistra (RTL)\",\"langCode\":\"Codice Lingua\",\"longDescr\":\"URL descrizione estesa\",\"cssClass\":\"Nome classe CSS\",\"advisoryTitle\":\"Titolo\",\"cssStyle\":\"Stile\",\"ok\":\"OK\",\"cancel\":\"Annulla\",\"close\":\"Chiudi\",\"preview\":\"Anteprima\",\"resize\":\"Trascina per ridimensionare\",\"generalTab\":\"Generale\",\"advancedTab\":\"Avanzate\",\"validateNumberFailed\":\"Il valore inserito non è un numero.\",\"confirmNewPage\":\"Ogni modifica non salvata sarà persa. Sei sicuro di voler caricare una nuova pagina?\",\"confirmCancel\":\"Alcune delle opzioni sono state cambiate. Sei sicuro di voler chiudere la finestra di dialogo?\",\"options\":\"Opzioni\",\"target\":\"Destinazione\",\"targetNew\":\"Nuova finestra (_blank)\",\"targetTop\":\"Finestra in primo piano (_top)\",\"targetSelf\":\"Stessa finestra (_self)\",\"targetParent\":\"Finestra Padre (_parent)\",\"langDirLTR\":\"Da sinistra a destra (LTR)\",\"langDirRTL\":\"Da destra a sinistra (RTL)\",\"styles\":\"Stile\",\"cssClasses\":\"Classi di stile\",\"width\":\"Larghezza\",\"height\":\"Altezza\",\"align\":\"Allineamento\",\"alignLeft\":\"Sinistra\",\"alignRight\":\"Destra\",\"alignCenter\":\"Centrato\",\"alignTop\":\"In Alto\",\"alignMiddle\":\"Centrato\",\"alignBottom\":\"In Basso\",\"invalidValue\":\"Valore non valido.\",\"invalidHeight\":\"L'altezza dev'essere un numero\",\"invalidWidth\":\"La Larghezza dev'essere un numero\",\"invalidCssLength\":\"Il valore indicato per il campo \\\"%1\\\" deve essere un numero positivo con o senza indicazione di una valida unità di misura per le classi CSS (px, %, in, cm, mm, em, ex, pt, o pc).\",\"invalidHtmlLength\":\"Il valore indicato per il campo \\\"%1\\\" deve essere un numero positivo con o senza indicazione di una valida unità di misura per le pagine HTML (px o %).\",\"invalidInlineStyle\":\"Il valore specificato per lo stile inline deve consistere in una o più tuple con il formato di \\\"name : value\\\", separati da semicolonne.\",\"cssLengthTooltip\":\"Inserisci un numero per il valore in pixel oppure un numero con una valida unità CSS (px, %, in, cm, mm, ex, pt, o pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, non disponibile</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Tutti i diritti riservati.\",\"dlgTitle\":\"Riguardo CKEditor\",\"help\":\"Vedi $1 per l'aiuto.\",\"moreInfo\":\"Per le informazioni sulla licenza si prega di visitare il nostro sito:\",\"title\":\"Riguardo CKEditor\",\"userGuide\":\"Guida Utente CKEditor\"},\"basicstyles\":{\"bold\":\"Grassetto\",\"italic\":\"Corsivo\",\"strike\":\"Barrato\",\"subscript\":\"Pedice\",\"superscript\":\"Apice\",\"underline\":\"Sottolineato\"},\"blockquote\":{\"toolbar\":\"Citazione\"},\"clipboard\":{\"copy\":\"Copia\",\"copyError\":\"Le impostazioni di sicurezza del browser non permettono di copiare automaticamente il testo. Usa la tastiera (Ctrl/Cmd+C).\",\"cut\":\"Taglia\",\"cutError\":\"Le impostazioni di sicurezza del browser non permettono di tagliare automaticamente il testo. Usa la tastiera (Ctrl/Cmd+X).\",\"paste\":\"Incolla\",\"pasteArea\":\"Incolla\",\"pasteMsg\":\"Incolla il testo all'interno dell'area sottostante usando la scorciatoia di tastiere (<STRONG>Ctrl/Cmd+V</STRONG>) e premi <STRONG>OK</STRONG>.\",\"securityMsg\":\"A causa delle impostazioni di sicurezza del browser,l'editor non è in grado di accedere direttamente agli appunti. E' pertanto necessario incollarli di nuovo in questa finestra.\",\"title\":\"Incolla\"},\"contextmenu\":{\"options\":\"Opzioni del menù contestuale\"},\"toolbar\":{\"toolbarCollapse\":\"Minimizza Toolbar\",\"toolbarExpand\":\"Espandi Toolbar\",\"toolbarGroups\":{\"document\":\"Documento\",\"clipboard\":\"Copia negli appunti/Annulla\",\"editing\":\"Modifica\",\"forms\":\"Form\",\"basicstyles\":\"Stili di base\",\"paragraph\":\"Paragrafo\",\"links\":\"Link\",\"insert\":\"Inserisci\",\"styles\":\"Stili\",\"colors\":\"Colori\",\"tools\":\"Strumenti\"},\"toolbars\":\"Editor toolbar\"},\"elementspath\":{\"eleLabel\":\"Percorso degli elementi\",\"eleTitle\":\"%1 elemento\"},\"format\":{\"label\":\"Formato\",\"panelTitle\":\"Formato\",\"tag_address\":\"Indirizzo\",\"tag_div\":\"Paragrafo (DIV)\",\"tag_h1\":\"Titolo 1\",\"tag_h2\":\"Titolo 2\",\"tag_h3\":\"Titolo 3\",\"tag_h4\":\"Titolo 4\",\"tag_h5\":\"Titolo 5\",\"tag_h6\":\"Titolo 6\",\"tag_p\":\"Normale\",\"tag_pre\":\"Formattato\"},\"horizontalrule\":{\"toolbar\":\"Inserisci riga orizzontale\"},\"image\":{\"alertUrl\":\"Devi inserire l'URL per l'immagine\",\"alt\":\"Testo alternativo\",\"border\":\"Bordo\",\"btnUpload\":\"Invia al server\",\"button2Img\":\"Vuoi trasformare il bottone immagine selezionato in un'immagine semplice?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Vuoi trasferomare l'immagine selezionata in un bottone immagine?\",\"infoTab\":\"Informazioni immagine\",\"linkTab\":\"Collegamento\",\"lockRatio\":\"Blocca rapporto\",\"menu\":\"Proprietà immagine\",\"resetSize\":\"Reimposta dimensione\",\"title\":\"Proprietà immagine\",\"titleButton\":\"Proprietà bottone immagine\",\"upload\":\"Carica\",\"urlMissing\":\"Manca l'URL dell'immagine.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Il campo Bordo deve essere un numero intero.\",\"validateHSpace\":\"Il campo HSpace deve essere un numero intero.\",\"validateVSpace\":\"Il campo VSpace deve essere un numero intero.\"},\"indent\":{\"indent\":\"Aumenta rientro\",\"outdent\":\"Riduci rientro\"},\"fakeobjects\":{\"anchor\":\"Ancora\",\"flash\":\"Animazione Flash\",\"hiddenfield\":\"Campo Nascosto\",\"iframe\":\"IFrame\",\"unknown\":\"Oggetto sconosciuto\"},\"link\":{\"acccessKey\":\"Scorciatoia da tastiera\",\"advanced\":\"Avanzate\",\"advisoryContentType\":\"Tipo della risorsa collegata\",\"advisoryTitle\":\"Titolo\",\"anchor\":{\"toolbar\":\"Inserisci/Modifica Ancora\",\"menu\":\"Proprietà ancora\",\"title\":\"Proprietà ancora\",\"name\":\"Nome ancora\",\"errorName\":\"Inserici il nome dell'ancora\",\"remove\":\"Rimuovi l'ancora\"},\"anchorId\":\"Per id elemento\",\"anchorName\":\"Per Nome\",\"charset\":\"Set di caretteri della risorsa collegata\",\"cssClasses\":\"Nome classe CSS\",\"emailAddress\":\"Indirizzo E-Mail\",\"emailBody\":\"Corpo del messaggio\",\"emailSubject\":\"Oggetto del messaggio\",\"id\":\"Id\",\"info\":\"Informazioni collegamento\",\"langCode\":\"Direzione scrittura\",\"langDir\":\"Direzione scrittura\",\"langDirLTR\":\"Da Sinistra a Destra (LTR)\",\"langDirRTL\":\"Da Destra a Sinistra (RTL)\",\"menu\":\"Modifica collegamento\",\"name\":\"Nome\",\"noAnchors\":\"(Nessuna ancora disponibile nel documento)\",\"noEmail\":\"Devi inserire un'indirizzo e-mail\",\"noUrl\":\"Devi inserire l'URL del collegamento\",\"other\":\"<altro>\",\"popupDependent\":\"Dipendente (Netscape)\",\"popupFeatures\":\"Caratteristiche finestra popup\",\"popupFullScreen\":\"A tutto schermo (IE)\",\"popupLeft\":\"Posizione da sinistra\",\"popupLocationBar\":\"Barra degli indirizzi\",\"popupMenuBar\":\"Barra del menu\",\"popupResizable\":\"Ridimensionabile\",\"popupScrollBars\":\"Barre di scorrimento\",\"popupStatusBar\":\"Barra di stato\",\"popupToolbar\":\"Barra degli strumenti\",\"popupTop\":\"Posizione dall'alto\",\"rel\":\"Relazioni\",\"selectAnchor\":\"Scegli Ancora\",\"styles\":\"Stile\",\"tabIndex\":\"Ordine di tabulazione\",\"target\":\"Destinazione\",\"targetFrame\":\"<riquadro>\",\"targetFrameName\":\"Nome del riquadro di destinazione\",\"targetPopup\":\"<finestra popup>\",\"targetPopupName\":\"Nome finestra popup\",\"title\":\"Collegamento\",\"toAnchor\":\"Ancora nel testo\",\"toEmail\":\"E-Mail\",\"toUrl\":\"URL\",\"toolbar\":\"Collegamento\",\"type\":\"Tipo di Collegamento\",\"unlink\":\"Elimina collegamento\",\"upload\":\"Carica\"},\"list\":{\"bulletedlist\":\"Inserisci/Rimuovi Elenco Puntato\",\"numberedlist\":\"Inserisci/Rimuovi Elenco Numerato\"},\"magicline\":{\"title\":\"Inserisci paragrafo qui\"},\"maximize\":{\"maximize\":\"Massimizza\",\"minimize\":\"Minimizza\"},\"pastetext\":{\"button\":\"Incolla come testo semplice\",\"title\":\"Incolla come testo semplice\"},\"pastefromword\":{\"confirmCleanup\":\"Il testo da incollare sembra provenire da Word. Desideri pulirlo prima di incollare?\",\"error\":\"Non è stato possibile eliminare il testo incollato a causa di un errore interno.\",\"title\":\"Incolla da Word\",\"toolbar\":\"Incolla da Word\"},\"removeformat\":{\"toolbar\":\"Elimina formattazione\"},\"sourcearea\":{\"toolbar\":\"Sorgente\"},\"specialchar\":{\"options\":\"Opzioni carattere speciale\",\"title\":\"Seleziona carattere speciale\",\"toolbar\":\"Inserisci carattere speciale\"},\"scayt\":{\"about\":\"About COMS\",\"aboutTab\":\"Info\",\"addWord\":\"Aggiungi Parola\",\"allCaps\":\"Ignora Parole in maiuscolo\",\"dic_create\":\"Crea\",\"dic_delete\":\"Cancella\",\"dic_field_name\":\"Nome del dizionario\",\"dic_info\":\"Inizialmente il dizionario utente è memorizzato in un Cookie. I Cookie però hanno una dimensioni massima limitata. Quando il dizionario utente creasce a tal punto da non poter più essere memorizzato in un Cookie, allora il dizionario può essere memorizzato sul nostro server. Per memorizzare il proprio dizionario personale sul nostro server, è necessario specificare un nome per il proprio dizionario. Se avete già memorizzato un dizionario, inserite il nome che gli avete dato e premete il pulsante Ripristina.\",\"dic_rename\":\"Rinomina\",\"dic_restore\":\"Ripristina\",\"dictionariesTab\":\"Dizionari\",\"disable\":\"Disabilita COMS\",\"emptyDic\":\"Il nome del dizionario non può essere vuoto.\",\"enable\":\"Abilita COMS\",\"ignore\":\"Ignora\",\"ignoreAll\":\"Ignora tutti\",\"ignoreDomainNames\":\"Ignora nomi di dominio\",\"langs\":\"Lingue\",\"languagesTab\":\"Lingue\",\"mixedCase\":\"Ignora parole con maiuscole e minuscole\",\"mixedWithDigits\":\"Ignora parole con numeri\",\"moreSuggestions\":\"Altri suggerimenti\",\"opera_title\":\"Non supportato da Opera\",\"options\":\"Opzioni\",\"optionsTab\":\"Opzioni\",\"title\":\"Controllo Ortografico Mentre Scrivi\",\"toggle\":\"Inverti abilitazione SCOMS\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stili\",\"panelTitle\":\"Stili di formattazione\",\"panelTitle1\":\"Stili per blocchi\",\"panelTitle2\":\"Stili in linea\",\"panelTitle3\":\"Stili per oggetti\"},\"table\":{\"border\":\"Dimensione bordo\",\"caption\":\"Intestazione\",\"cell\":{\"menu\":\"Cella\",\"insertBefore\":\"Inserisci Cella Prima\",\"insertAfter\":\"Inserisci Cella Dopo\",\"deleteCell\":\"Elimina celle\",\"merge\":\"Unisce celle\",\"mergeRight\":\"Unisci a Destra\",\"mergeDown\":\"Unisci in Basso\",\"splitHorizontal\":\"Dividi Cella Orizzontalmente\",\"splitVertical\":\"Dividi Cella Verticalmente\",\"title\":\"Proprietà della cella\",\"cellType\":\"Tipo di cella\",\"rowSpan\":\"Su più righe\",\"colSpan\":\"Su più colonne\",\"wordWrap\":\"Ritorno a capo\",\"hAlign\":\"Allineamento orizzontale\",\"vAlign\":\"Allineamento verticale\",\"alignBaseline\":\"Linea Base\",\"bgColor\":\"Colore di Sfondo\",\"borderColor\":\"Colore del Bordo\",\"data\":\"Dati\",\"header\":\"Intestazione\",\"yes\":\"Si\",\"no\":\"No\",\"invalidWidth\":\"La larghezza della cella dev'essere un numero.\",\"invalidHeight\":\"L'altezza della cella dev'essere un numero.\",\"invalidRowSpan\":\"Il numero di righe dev'essere un numero intero.\",\"invalidColSpan\":\"Il numero di colonne dev'essere un numero intero.\",\"chooseColor\":\"Scegli\"},\"cellPad\":\"Padding celle\",\"cellSpace\":\"Spaziatura celle\",\"column\":{\"menu\":\"Colonna\",\"insertBefore\":\"Inserisci Colonna Prima\",\"insertAfter\":\"Inserisci Colonna Dopo\",\"deleteColumn\":\"Elimina colonne\"},\"columns\":\"Colonne\",\"deleteTable\":\"Cancella Tabella\",\"headers\":\"Intestazione\",\"headersBoth\":\"Entrambe\",\"headersColumn\":\"Prima Colonna\",\"headersNone\":\"Nessuna\",\"headersRow\":\"Prima Riga\",\"invalidBorder\":\"La dimensione del bordo dev'essere un numero.\",\"invalidCellPadding\":\"Il paging delle celle dev'essere un numero\",\"invalidCellSpacing\":\"La spaziatura tra le celle dev'essere un numero.\",\"invalidCols\":\"Il numero di colonne dev'essere un numero maggiore di 0.\",\"invalidHeight\":\"L'altezza della tabella dev'essere un numero.\",\"invalidRows\":\"Il numero di righe dev'essere un numero maggiore di 0.\",\"invalidWidth\":\"La larghezza della tabella dev'essere un numero.\",\"menu\":\"Proprietà tabella\",\"row\":{\"menu\":\"Riga\",\"insertBefore\":\"Inserisci Riga Prima\",\"insertAfter\":\"Inserisci Riga Dopo\",\"deleteRow\":\"Elimina righe\"},\"rows\":\"Righe\",\"summary\":\"Indice\",\"title\":\"Proprietà tabella\",\"toolbar\":\"Tabella\",\"widthPc\":\"percento\",\"widthPx\":\"pixel\",\"widthUnit\":\"unità larghezza\"},\"undo\":{\"redo\":\"Ripristina\",\"undo\":\"Annulla\"},\"wsc\":{\"btnIgnore\":\"Ignora\",\"btnIgnoreAll\":\"Ignora tutto\",\"btnReplace\":\"Cambia\",\"btnReplaceAll\":\"Cambia tutto\",\"btnUndo\":\"Annulla\",\"changeTo\":\"Cambia in\",\"errorLoading\":\"Errore nel caricamento dell'host col servizio applicativo: %s.\",\"ieSpellDownload\":\"Contollo ortografico non installato. Lo vuoi scaricare ora?\",\"manyChanges\":\"Controllo ortografico completato: %1 parole cambiate\",\"noChanges\":\"Controllo ortografico completato: nessuna parola cambiata\",\"noMispell\":\"Controllo ortografico completato: nessun errore trovato\",\"noSuggestions\":\"- Nessun suggerimento -\",\"notAvailable\":\"Il servizio non è momentaneamente disponibile.\",\"notInDic\":\"Non nel dizionario\",\"oneChange\":\"Controllo ortografico completato: 1 parola cambiata\",\"progress\":\"Controllo ortografico in corso\",\"title\":\"Controllo ortografico\",\"toolbar\":\"Correttore ortografico\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/ja.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['ja']={\"editor\":\"リッチテキストエディタ\",\"editorPanel\":\"リッチテキストエディタパネル\",\"common\":{\"editorHelp\":\"ヘルプは ALT 0 を押してください\",\"browseServer\":\"サーバブラウザ\",\"url\":\"URL\",\"protocol\":\"プロトコル\",\"upload\":\"アップロード\",\"uploadSubmit\":\"サーバーに送信\",\"image\":\"イメージ\",\"flash\":\"Flash\",\"form\":\"フォーム\",\"checkbox\":\"チェックボックス\",\"radio\":\"ラジオボタン\",\"textField\":\"１行テキスト\",\"textarea\":\"テキストエリア\",\"hiddenField\":\"不可視フィールド\",\"button\":\"ボタン\",\"select\":\"選択フィールド\",\"imageButton\":\"画像ボタン\",\"notSet\":\"<なし>\",\"id\":\"Id\",\"name\":\"Name属性\",\"langDir\":\"文字表記の方向\",\"langDirLtr\":\"左から右 (LTR)\",\"langDirRtl\":\"右から左 (RTL)\",\"langCode\":\"言語コード\",\"longDescr\":\"longdesc属性(長文説明)\",\"cssClass\":\"スタイルシートクラス\",\"advisoryTitle\":\"Title属性\",\"cssStyle\":\"スタイルシート\",\"ok\":\"OK\",\"cancel\":\"キャンセル\",\"close\":\"閉じる\",\"preview\":\"プレビュー\",\"resize\":\"ドラッグしてリサイズ\",\"generalTab\":\"全般\",\"advancedTab\":\"高度な設定\",\"validateNumberFailed\":\"値が数ではありません\",\"confirmNewPage\":\"変更内容を保存せず、 新しいページを開いてもよろしいでしょうか？\",\"confirmCancel\":\"オプション設定を変更しました。ダイアログを閉じてもよろしいでしょうか？\",\"options\":\"オプション\",\"target\":\"ターゲット\",\"targetNew\":\"新しいウインドウ (_blank)\",\"targetTop\":\"最上部ウィンドウ (_top)\",\"targetSelf\":\"同じウィンドウ (_self)\",\"targetParent\":\"親ウィンドウ (_parent)\",\"langDirLTR\":\"左から右 (LTR)\",\"langDirRTL\":\"右から左 (RTL)\",\"styles\":\"スタイル\",\"cssClasses\":\"スタイルシートクラス\",\"width\":\"幅\",\"height\":\"高さ\",\"align\":\"行揃え\",\"alignLeft\":\"左\",\"alignRight\":\"右\",\"alignCenter\":\"中央\",\"alignTop\":\"上\",\"alignMiddle\":\"中央\",\"alignBottom\":\"下\",\"invalidValue\":\"不正な値です。\",\"invalidHeight\":\"高さは数値で入力してください。\",\"invalidWidth\":\"幅は数値で入力してください。\",\"invalidCssLength\":\"入力された \\\"%1\\\" 項目の値は、CSSの大きさ(px, %, in, cm, mm, em, ex, pt, または pc)が正しいものである/ないに関わらず、正の値である必要があります。\",\"invalidHtmlLength\":\"入力された \\\"%1\\\" 項目の値は、HTMLの大きさ(px または %)が正しいものである/ないに関わらず、正の値である必要があります。\",\"invalidInlineStyle\":\"入力されたインラインスタイルの値は、\\\"名前 : 値\\\" のフォーマットのセットで、複数の場合はセミコロンで区切られている形式である必要があります。\",\"cssLengthTooltip\":\"ピクセル数もしくはCSSにセットできる数値を入力してください。(px,%,in,cm,mm,em,ex,pt,or pc)\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, 利用不可能</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"CKEditorについて\",\"help\":\"$1 のヘルプを見てください。\",\"moreInfo\":\"ライセンス情報の詳細はウェブサイトにて確認してください:\",\"title\":\"CKEditorについて\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"太字\",\"italic\":\"斜体\",\"strike\":\"打ち消し線\",\"subscript\":\"下付き\",\"superscript\":\"上付き\",\"underline\":\"下線\"},\"blockquote\":{\"toolbar\":\"ブロック引用文\"},\"clipboard\":{\"copy\":\"コピー\",\"copyError\":\"ブラウザーのセキュリティ設定によりエディタのコピー操作を自動で実行することができません。実行するには手動でキーボードの(Ctrl/Cmd+C)を使用してください。\",\"cut\":\"切り取り\",\"cutError\":\"ブラウザーのセキュリティ設定によりエディタの切り取り操作を自動で実行することができません。実行するには手動でキーボードの(Ctrl/Cmd+X)を使用してください。\",\"paste\":\"貼り付け\",\"pasteArea\":\"貼り付け場所\",\"pasteMsg\":\"キーボード(<STRONG>Ctrl/Cmd+V</STRONG>)を使用して、次の入力エリア内で貼り付けて、<STRONG>OK</STRONG>を押してください。\",\"securityMsg\":\"ブラウザのセキュリティ設定により、エディタはクリップボードデータに直接アクセスすることができません。このウィンドウは貼り付け操作を行う度に表示されます。\",\"title\":\"貼り付け\"},\"contextmenu\":{\"options\":\"コンテキストメニューオプション\"},\"toolbar\":{\"toolbarCollapse\":\"ツールバーを閉じる\",\"toolbarExpand\":\"ツールバーを開く\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"編集ツールバー\"},\"elementspath\":{\"eleLabel\":\"要素パス\",\"eleTitle\":\"%1 要素\"},\"format\":{\"label\":\"書式\",\"panelTitle\":\"段落の書式\",\"tag_address\":\"アドレス\",\"tag_div\":\"標準 (DIV)\",\"tag_h1\":\"見出し 1\",\"tag_h2\":\"見出し 2\",\"tag_h3\":\"見出し 3\",\"tag_h4\":\"見出し 4\",\"tag_h5\":\"見出し 5\",\"tag_h6\":\"見出し 6\",\"tag_p\":\"標準\",\"tag_pre\":\"書式付き\"},\"horizontalrule\":{\"toolbar\":\"水平線\"},\"image\":{\"alertUrl\":\"画像のURLを入力してください\",\"alt\":\"代替テキスト\",\"border\":\"枠線の幅\",\"btnUpload\":\"サーバーに送信\",\"button2Img\":\"選択した画像ボタンを画像に変換しますか？\",\"hSpace\":\"水平間隔\",\"img2Button\":\"選択した画像を画像ボタンに変換しますか？\",\"infoTab\":\"画像情報\",\"linkTab\":\"リンク\",\"lockRatio\":\"比率を固定\",\"menu\":\"画像のプロパティ\",\"resetSize\":\"サイズをリセット\",\"title\":\"画像のプロパティ\",\"titleButton\":\"画像ボタンのプロパティ\",\"upload\":\"アップロード\",\"urlMissing\":\"画像のURLを入力してください。\",\"vSpace\":\"垂直間隔\",\"validateBorder\":\"枠線の幅は数値で入力してください。\",\"validateHSpace\":\"水平間隔は数値で入力してください。\",\"validateVSpace\":\"垂直間隔は数値で入力してください。\"},\"indent\":{\"indent\":\"インデント\",\"outdent\":\"インデント解除\"},\"fakeobjects\":{\"anchor\":\"アンカー\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"不可視フィールド\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"アクセスキー\",\"advanced\":\"高度な設定\",\"advisoryContentType\":\"Content Type属性\",\"advisoryTitle\":\"Title属性\",\"anchor\":{\"toolbar\":\"アンカー挿入/編集\",\"menu\":\"アンカーの編集\",\"title\":\"アンカーのプロパティ\",\"name\":\"アンカー名\",\"errorName\":\"アンカー名を入力してください。\",\"remove\":\"アンカーを削除\"},\"anchorId\":\"エレメントID\",\"anchorName\":\"アンカー名\",\"charset\":\"リンク先のcharset\",\"cssClasses\":\"スタイルシートクラス\",\"emailAddress\":\"E-Mail アドレス\",\"emailBody\":\"本文\",\"emailSubject\":\"件名\",\"id\":\"Id\",\"info\":\"ハイパーリンク情報\",\"langCode\":\"言語コード\",\"langDir\":\"文字表記の方向\",\"langDirLTR\":\"左から右 (LTR)\",\"langDirRTL\":\"右から左 (RTL)\",\"menu\":\"リンクを編集\",\"name\":\"Name属性\",\"noAnchors\":\"(このドキュメント内にアンカーはありません)\",\"noEmail\":\"メールアドレスを入力してください。\",\"noUrl\":\"リンクURLを入力してください。\",\"other\":\"<その他の>\",\"popupDependent\":\"開いたウィンドウに連動して閉じる (Netscape)\",\"popupFeatures\":\"ポップアップウィンドウ特徴\",\"popupFullScreen\":\"全画面モード(IE)\",\"popupLeft\":\"左端からの座標で指定\",\"popupLocationBar\":\"ロケーションバー\",\"popupMenuBar\":\"メニューバー\",\"popupResizable\":\"サイズ可変\",\"popupScrollBars\":\"スクロールバー\",\"popupStatusBar\":\"ステータスバー\",\"popupToolbar\":\"ツールバー\",\"popupTop\":\"上端からの座標で指定\",\"rel\":\"関連リンク\",\"selectAnchor\":\"アンカーを選択\",\"styles\":\"スタイルシート\",\"tabIndex\":\"タブインデックス\",\"target\":\"ターゲット\",\"targetFrame\":\"<フレーム>\",\"targetFrameName\":\"ターゲットのフレーム名\",\"targetPopup\":\"<ポップアップウィンドウ>\",\"targetPopupName\":\"ポップアップウィンドウ名\",\"title\":\"ハイパーリンク\",\"toAnchor\":\"ページ内のアンカー\",\"toEmail\":\"E-Mail\",\"toUrl\":\"URL\",\"toolbar\":\"リンク挿入/編集\",\"type\":\"リンクタイプ\",\"unlink\":\"リンクを削除\",\"upload\":\"アップロード\"},\"list\":{\"bulletedlist\":\"番号無しリスト\",\"numberedlist\":\"番号付きリスト\"},\"magicline\":{\"title\":\"ここに段落を挿入\"},\"maximize\":{\"maximize\":\"最大化\",\"minimize\":\"最小化\"},\"pastetext\":{\"button\":\"プレーンテキストとして貼り付け\",\"title\":\"プレーンテキストとして貼り付け\"},\"pastefromword\":{\"confirmCleanup\":\"貼り付けを行うテキストはワード文章からコピーされようとしています。貼り付ける前にクリーニングを行いますか？\",\"error\":\"内部エラーにより貼り付けたデータをクリアできませんでした\",\"title\":\"ワード文章から貼り付け\",\"toolbar\":\"ワード文章から貼り付け\"},\"removeformat\":{\"toolbar\":\"書式を解除\"},\"sourcearea\":{\"toolbar\":\"ソース\"},\"specialchar\":{\"options\":\"特殊文字オプション\",\"title\":\"特殊文字の選択\",\"toolbar\":\"特殊文字を挿入\"},\"scayt\":{\"about\":\"SCAYTﾊﾞｰｼﾞｮﾝ\",\"aboutTab\":\"バージョン情報\",\"addWord\":\"語句追加\",\"allCaps\":\"全て大文字の単語を無視\",\"dic_create\":\"登録\",\"dic_delete\":\"削除\",\"dic_field_name\":\"辞書名\",\"dic_info\":\"始めユーザーディレクトリは、Cookieに保存されます。但し Cookie はサイズに制限があります。ユーザーディレクトリがCookieに保存できないサイズに到達するとディレクトリはサーバー上に保存されます。個人のディレクトリをサーバー上に保存するには、ディレクトリ名を明示する必要があります。もし既に保存されたディレクトリがある場合、その名前を入力し、元に戻すボタンを押してください。\",\"dic_rename\":\"名前変更\",\"dic_restore\":\"元に戻す\",\"dictionariesTab\":\"辞書\",\"disable\":\"SCAYT無効\",\"emptyDic\":\"辞書名は必ず入力してください\",\"enable\":\"SCAYT有効\",\"ignore\":\"無視\",\"ignoreAll\":\"すべて無視\",\"ignoreDomainNames\":\"ドメイン名を無視\",\"langs\":\"言語\",\"languagesTab\":\"言語\",\"mixedCase\":\"大文字小文字混在の単語を無視\",\"mixedWithDigits\":\"数字付き単語を無視\",\"moreSuggestions\":\"他の候補\",\"opera_title\":\"Operaではサポートされません\",\"options\":\"オプション\",\"optionsTab\":\"オプション\",\"title\":\"スペルチェック設定(SCAYT)\",\"toggle\":\"SCAYT切替\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"スタイル\",\"panelTitle\":\"スタイル\",\"panelTitle1\":\"ブロックスタイル\",\"panelTitle2\":\"インラインスタイル\",\"panelTitle3\":\"オブジェクトスタイル\"},\"table\":{\"border\":\"枠線の幅\",\"caption\":\"キャプション\",\"cell\":{\"menu\":\"セル\",\"insertBefore\":\"セルを前に挿入\",\"insertAfter\":\"セルを後に挿入\",\"deleteCell\":\"セルを削除\",\"merge\":\"セルを結合\",\"mergeRight\":\"右に結合\",\"mergeDown\":\"下に結合\",\"splitHorizontal\":\"セルを水平方向に分割\",\"splitVertical\":\"セルを垂直方向に分割\",\"title\":\"セルのプロパティ\",\"cellType\":\"セルの種類\",\"rowSpan\":\"行の結合数\",\"colSpan\":\"列の結合数\",\"wordWrap\":\"単語の折り返し\",\"hAlign\":\"水平方向の配置\",\"vAlign\":\"垂直方向の配置\",\"alignBaseline\":\"ベースライン\",\"bgColor\":\"背景色\",\"borderColor\":\"ボーダーカラー\",\"data\":\"テーブルデータ (td)\",\"header\":\"ヘッダ\",\"yes\":\"はい\",\"no\":\"いいえ\",\"invalidWidth\":\"セル幅は数値で入力してください。\",\"invalidHeight\":\"セル高さは数値で入力してください。\",\"invalidRowSpan\":\"縦幅(行数)は数値で入力してください。\",\"invalidColSpan\":\"横幅(列数)は数値で入力してください。\",\"chooseColor\":\"色の選択\"},\"cellPad\":\"セル内間隔\",\"cellSpace\":\"セル内余白\",\"column\":{\"menu\":\"列\",\"insertBefore\":\"列を左に挿入\",\"insertAfter\":\"列を右に挿入\",\"deleteColumn\":\"列を削除\"},\"columns\":\"列数\",\"deleteTable\":\"表を削除\",\"headers\":\"ヘッダ (th)\",\"headersBoth\":\"両方\",\"headersColumn\":\"最初の列のみ\",\"headersNone\":\"なし\",\"headersRow\":\"最初の行のみ\",\"invalidBorder\":\"枠線の幅は数値で入力してください。\",\"invalidCellPadding\":\"セル内余白は数値で入力してください。\",\"invalidCellSpacing\":\"セル間余白は数値で入力してください。\",\"invalidCols\":\"列数は0より大きな数値を入力してください。\",\"invalidHeight\":\"高さは数値で入力してください。\",\"invalidRows\":\"行数は0より大きな数値を入力してください。\",\"invalidWidth\":\"幅は数値で入力してください。\",\"menu\":\"表のプロパティ\",\"row\":{\"menu\":\"行\",\"insertBefore\":\"行を上に挿入\",\"insertAfter\":\"行を下に挿入\",\"deleteRow\":\"行を削除\"},\"rows\":\"行数\",\"summary\":\"表の概要\",\"title\":\"表のプロパティ\",\"toolbar\":\"表\",\"widthPc\":\"パーセント\",\"widthPx\":\"ピクセル\",\"widthUnit\":\"幅の単位\"},\"undo\":{\"redo\":\"やり直す\",\"undo\":\"元に戻す\"},\"wsc\":{\"btnIgnore\":\"無視\",\"btnIgnoreAll\":\"すべて無視\",\"btnReplace\":\"置換\",\"btnReplaceAll\":\"すべて置換\",\"btnUndo\":\"やり直し\",\"changeTo\":\"変更\",\"errorLoading\":\"アプリケーションサービスホスト読込みエラー: %s.\",\"ieSpellDownload\":\"スペルチェッカーがインストールされていません。今すぐダウンロードしますか?\",\"manyChanges\":\"スペルチェック完了: %1 語句変更されました\",\"noChanges\":\"スペルチェック完了: 語句は変更されませんでした\",\"noMispell\":\"スペルチェック完了: スペルの誤りはありませんでした\",\"noSuggestions\":\"- 該当なし -\",\"notAvailable\":\"申し訳ありません、現在サービスを利用することができません\",\"notInDic\":\"辞書にありません\",\"oneChange\":\"スペルチェック完了: １語句変更されました\",\"progress\":\"スペルチェック処理中...\",\"title\":\"スペルチェック\",\"toolbar\":\"スペルチェック\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/ka.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['ka']={\"editor\":\"ტექსტის რედაქტორი\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"დააჭირეთ ALT 0-ს დახმარების მისაღებად\",\"browseServer\":\"სერვერზე დათვალიერება\",\"url\":\"URL\",\"protocol\":\"პროტოკოლი\",\"upload\":\"ატვირთვა\",\"uploadSubmit\":\"სერვერზე გაგზავნა\",\"image\":\"სურათი\",\"flash\":\"Flash\",\"form\":\"ფორმა\",\"checkbox\":\"მონიშვნის ღილაკი\",\"radio\":\"ამორჩევის ღილაკი\",\"textField\":\"ტექსტური ველი\",\"textarea\":\"ტექსტური არე\",\"hiddenField\":\"მალული ველი\",\"button\":\"ღილაკი\",\"select\":\"არჩევის ველი\",\"imageButton\":\"სურათიანი ღილაკი\",\"notSet\":\"<არაფერი>\",\"id\":\"Id\",\"name\":\"სახელი\",\"langDir\":\"ენის მიმართულება\",\"langDirLtr\":\"მარცხნიდან მარჯვნივ (LTR)\",\"langDirRtl\":\"მარჯვნიდან მარცხნივ (RTL)\",\"langCode\":\"ენის კოდი\",\"longDescr\":\"დიდი აღწერის URL\",\"cssClass\":\"CSS კლასი\",\"advisoryTitle\":\"სათაური\",\"cssStyle\":\"CSS სტილი\",\"ok\":\"დიახ\",\"cancel\":\"გაუქმება\",\"close\":\"დახურვა\",\"preview\":\"გადახედვა\",\"resize\":\"გაწიე ზომის შესაცვლელად\",\"generalTab\":\"ინფორმაცია\",\"advancedTab\":\"გაფართოებული\",\"validateNumberFailed\":\"ეს მნიშვნელობა არაა რიცხვი.\",\"confirmNewPage\":\"ამ დოკუმენტში ყველა ჩაუწერელი ცვლილება დაიკარგება. დარწმუნებული ხართ რომ ახალი გვერდის ჩატვირთვა გინდათ?\",\"confirmCancel\":\"ზოგიერთი პარამეტრი შეცვლილია, დარწმუნებულილ ხართ რომ ფანჯრის დახურვა გსურთ?\",\"options\":\"პარამეტრები\",\"target\":\"გახსნის ადგილი\",\"targetNew\":\"ახალი ფანჯარა (_blank)\",\"targetTop\":\"ზედა ფანჯარა (_top)\",\"targetSelf\":\"იგივე ფანჯარა (_self)\",\"targetParent\":\"მშობელი ფანჯარა (_parent)\",\"langDirLTR\":\"მარცხნიდან მარჯვნივ (LTR)\",\"langDirRTL\":\"მარჯვნიდან მარცხნივ (RTL)\",\"styles\":\"სტილი\",\"cssClasses\":\"CSS კლასი\",\"width\":\"სიგანე\",\"height\":\"სიმაღლე\",\"align\":\"სწორება\",\"alignLeft\":\"მარცხენა\",\"alignRight\":\"მარჯვენა\",\"alignCenter\":\"შუა\",\"alignTop\":\"ზემოთა\",\"alignMiddle\":\"შუა\",\"alignBottom\":\"ქვემოთა\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"სიმაღლე რიცხვით უნდა იყოს წარმოდგენილი.\",\"invalidWidth\":\"სიგანე რიცხვით უნდა იყოს წარმოდგენილი.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, მიუწვდომელია</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. ყველა უფლება დაცულია.\",\"dlgTitle\":\"CKEditor-ის შესახებ\",\"help\":\"დახმარებისთვის იხილეთ $1.\",\"moreInfo\":\"ლიცენზიის ინფორმაციისთვის ეწვიეთ ჩვენს საიტს:\",\"title\":\"CKEditor-ის შესახებ\",\"userGuide\":\"CKEditor-ის მომხმარებლის სახელმძღვანელო\"},\"basicstyles\":{\"bold\":\"მსხვილი\",\"italic\":\"დახრილი\",\"strike\":\"გადახაზული\",\"subscript\":\"ინდექსი\",\"superscript\":\"ხარისხი\",\"underline\":\"გახაზული\"},\"blockquote\":{\"toolbar\":\"ციტატა\"},\"clipboard\":{\"copy\":\"ასლი\",\"copyError\":\"თქვენი ბროუზერის უსაფრთხოების პარამეტრები არ იძლევა ასლის ოპერაციის ავტომატურად განხორციელების საშუალებას. გამოიყენეთ კლავიატურა ამისთვის (Ctrl/Cmd+C).\",\"cut\":\"ამოჭრა\",\"cutError\":\"თქვენი ბროუზერის უსაფრთხოების პარამეტრები არ იძლევა ამოჭრის ოპერაციის ავტომატურად განხორციელების საშუალებას. გამოიყენეთ კლავიატურა ამისთვის (Ctrl/Cmd+X).\",\"paste\":\"ჩასმა\",\"pasteArea\":\"ჩასმის არე\",\"pasteMsg\":\"ჩასვით ამ არის შიგნით კლავიატურის გამოყენებით (<strong>Ctrl/Cmd+V</strong>) და დააჭირეთ OK-ს\",\"securityMsg\":\"თქვენი ბროუზერის უსაფრთხოების პარამეტრები არ იძლევა clipboard-ის მონაცემების წვდომის უფლებას. კიდევ უნდა ჩასვათ ტექსტი ამ ფანჯარაში.\",\"title\":\"ჩასმა\"},\"contextmenu\":{\"options\":\"კონტექსტური მენიუს პარამეტრები\"},\"toolbar\":{\"toolbarCollapse\":\"ხელსაწყოთა ზოლის შეწევა\",\"toolbarExpand\":\"ხელსაწყოთა ზოლის გამოწევა\",\"toolbarGroups\":{\"document\":\"დოკუმენტი\",\"clipboard\":\"Clipboard/გაუქმება\",\"editing\":\"რედაქტირება\",\"forms\":\"ფორმები\",\"basicstyles\":\"ძირითადი სტილები\",\"paragraph\":\"აბზაცი\",\"links\":\"ბმულები\",\"insert\":\"ჩასმა\",\"styles\":\"სტილები\",\"colors\":\"ფერები\",\"tools\":\"ხელსაწყოები\"},\"toolbars\":\"Editor toolbars\"},\"elementspath\":{\"eleLabel\":\"ელემეტის გზა\",\"eleTitle\":\"%1 ელემენტი\"},\"format\":{\"label\":\"ფიორმატირება\",\"panelTitle\":\"ფორმატირება\",\"tag_address\":\"მისამართი\",\"tag_div\":\"ჩვეულებრივი (DIV)\",\"tag_h1\":\"სათაური 1\",\"tag_h2\":\"სათაური 2\",\"tag_h3\":\"სათაური 3\",\"tag_h4\":\"სათაური 4\",\"tag_h5\":\"სათაური 5\",\"tag_h6\":\"სათაური 6\",\"tag_p\":\"ჩვეულებრივი\",\"tag_pre\":\"ფორმატირებული\"},\"horizontalrule\":{\"toolbar\":\"ჰორიზონტალური ხაზის ჩასმა\"},\"image\":{\"alertUrl\":\"აკრიფეთ სურათის URL\",\"alt\":\"სანაცვლო ტექსტი\",\"border\":\"ჩარჩო\",\"btnUpload\":\"სერვერისთვის გაგზავნა\",\"button2Img\":\"გსურთ არჩეული სურათიანი ღილაკის გადაქცევა ჩვეულებრივ ღილაკად?\",\"hSpace\":\"ჰორიზონტალური სივრცე\",\"img2Button\":\"გსურთ არჩეული ჩვეულებრივი ღილაკის გადაქცევა სურათიან ღილაკად?\",\"infoTab\":\"სურათის ინფორმცია\",\"linkTab\":\"ბმული\",\"lockRatio\":\"პროპორციის შენარჩუნება\",\"menu\":\"სურათის პარამეტრები\",\"resetSize\":\"ზომის დაბრუნება\",\"title\":\"სურათის პარამეტრები\",\"titleButton\":\"სურათიანი ღილაკის პარამეტრები\",\"upload\":\"ატვირთვა\",\"urlMissing\":\"სურათის URL არაა შევსებული.\",\"vSpace\":\"ვერტიკალური სივრცე\",\"validateBorder\":\"ჩარჩო მთელი რიცხვი უნდა იყოს.\",\"validateHSpace\":\"ჰორიზონტალური სივრცე მთელი რიცხვი უნდა იყოს.\",\"validateVSpace\":\"ვერტიკალური სივრცე მთელი რიცხვი უნდა იყოს.\"},\"indent\":{\"indent\":\"მეტად შეწევა\",\"outdent\":\"ნაკლებად შეწევა\"},\"fakeobjects\":{\"anchor\":\"ღუზა\",\"flash\":\"Flash ანიმაცია\",\"hiddenfield\":\"მალული ველი\",\"iframe\":\"IFrame\",\"unknown\":\"უცნობი ობიექტი\"},\"link\":{\"acccessKey\":\"წვდომის ღილაკი\",\"advanced\":\"დაწვრილებით\",\"advisoryContentType\":\"შიგთავსის ტიპი\",\"advisoryTitle\":\"სათაური\",\"anchor\":{\"toolbar\":\"ღუზა\",\"menu\":\"ღუზის რედაქტირება\",\"title\":\"ღუზის პარამეტრები\",\"name\":\"ღუზუს სახელი\",\"errorName\":\"აკრიფეთ ღუზის სახელი\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"ელემენტის Id-თ\",\"anchorName\":\"ღუზის სახელით\",\"charset\":\"კოდირება\",\"cssClasses\":\"CSS კლასი\",\"emailAddress\":\"ელფოსტის მისამართები\",\"emailBody\":\"წერილის ტექსტი\",\"emailSubject\":\"წერილის სათაური\",\"id\":\"Id\",\"info\":\"ბმულის ინფორმაცია\",\"langCode\":\"ენის კოდი\",\"langDir\":\"ენის მიმართულება\",\"langDirLTR\":\"მარცხნიდან მარჯვნივ (LTR)\",\"langDirRTL\":\"მარჯვნიდან მარცხნივ (RTL)\",\"menu\":\"ბმულის რედაქტირება\",\"name\":\"სახელი\",\"noAnchors\":\"(ამ დოკუმენტში ღუზა არაა)\",\"noEmail\":\"აკრიფეთ ელფოსტის მისამართი\",\"noUrl\":\"აკრიფეთ ბმულის URL\",\"other\":\"<სხვა>\",\"popupDependent\":\"დამოკიდებული (Netscape)\",\"popupFeatures\":\"Popup ფანჯრის პარამეტრები\",\"popupFullScreen\":\"მთელი ეკრანი (IE)\",\"popupLeft\":\"მარცხენა პოზიცია\",\"popupLocationBar\":\"ნავიგაციის ზოლი\",\"popupMenuBar\":\"მენიუს ზოლი\",\"popupResizable\":\"ცვალებადი ზომით\",\"popupScrollBars\":\"გადახვევის ზოლები\",\"popupStatusBar\":\"სტატუსის ზოლი\",\"popupToolbar\":\"ხელსაწყოთა ზოლი\",\"popupTop\":\"ზედა პოზიცია\",\"rel\":\"კავშირი\",\"selectAnchor\":\"აირჩიეთ ღუზა\",\"styles\":\"CSS სტილი\",\"tabIndex\":\"Tab-ის ინდექსი\",\"target\":\"გახსნის ადგილი\",\"targetFrame\":\"<frame>\",\"targetFrameName\":\"Frame-ის სახელი\",\"targetPopup\":\"<popup ფანჯარა>\",\"targetPopupName\":\"Popup ფანჯრის სახელი\",\"title\":\"ბმული\",\"toAnchor\":\"ბმული ტექსტში ღუზაზე\",\"toEmail\":\"ელფოსტა\",\"toUrl\":\"URL\",\"toolbar\":\"ბმული\",\"type\":\"ბმულის ტიპი\",\"unlink\":\"ბმულის მოხსნა\",\"upload\":\"აქაჩვა\"},\"list\":{\"bulletedlist\":\"ღილიანი სია\",\"numberedlist\":\"გადანომრილი სია\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"გადიდება\",\"minimize\":\"დაპატარავება\"},\"pastetext\":{\"button\":\"მხოლოდ ტექსტის ჩასმა\",\"title\":\"მხოლოდ ტექსტის ჩასმა\"},\"pastefromword\":{\"confirmCleanup\":\"ჩასასმელი ტექსტი ვორდიდან გადმოტანილს გავს - გინდათ მისი წინასწარ გაწმენდა?\",\"error\":\"შიდა შეცდომის გამო ვერ მოხერხდა ტექსტის გაწმენდა\",\"title\":\"ვორდიდან ჩასმა\",\"toolbar\":\"ვორდიდან ჩასმა\"},\"removeformat\":{\"toolbar\":\"ფორმატირების მოხსნა\"},\"sourcearea\":{\"toolbar\":\"კოდები\"},\"specialchar\":{\"options\":\"სპეციალური სიმბოლოს პარამეტრები\",\"title\":\"სპეციალური სიმბოლოს არჩევა\",\"toolbar\":\"სპეციალური სიმბოლოს ჩასმა\"},\"scayt\":{\"about\":\"SCAYT-ის შესახებ\",\"aboutTab\":\"ინფორმაცია\",\"addWord\":\"სიტყვის დამატება\",\"allCaps\":\"დიდი ასოებით დაწერილი სიტყვების უგულებელყოფა\",\"dic_create\":\"შექმნა\",\"dic_delete\":\"წაშლა\",\"dic_field_name\":\"ლექსიკონის სახელი\",\"dic_info\":\"თავდაპირველად მომხმარებლის ლექსიკონი ინახება Cookie-ში. თუმცა Cookie შეზღუდულია ზომაში. როცა ლექსიკონის ზომა გაიზრდება საკმაოდ ის შეიძლება შევინახოთ ჩვენს სერვერზე. ჩვენს სერვერზე ლექსიკონს შესანახად უნდა მიუთითოთ მისი სახელი. თუ უკე გაქვთ ლექსიკონი, აკრიფეთ მისი სახელი და დააჭირეთ \\\"დაბრუნების\\\" ღილაკს.\",\"dic_rename\":\"გადარქმევა\",\"dic_restore\":\"დაბრუნება\",\"dictionariesTab\":\"ლექსიკონები\",\"disable\":\"SCAYT-ის გამორთვა\",\"emptyDic\":\"ლექსიკონის სიტყვა არ უნდა იყოს ცარიელი.\",\"enable\":\"SCAYT-ის ჩართვა\",\"ignore\":\"უგულებელყოფა\",\"ignoreAll\":\"ყველას უგულებელყოფა\",\"ignoreDomainNames\":\"დომენური სახელების უგულებელყოფა\",\"langs\":\"ენები\",\"languagesTab\":\"ენები\",\"mixedCase\":\"შერეული ასოებანი სიტყვების უგულებელყოფა\",\"mixedWithDigits\":\"ციფრებიანი სიტყვების უგულებელყოფა\",\"moreSuggestions\":\"მეტი შემოთავაზება\",\"opera_title\":\"არაა მხარდაჭერილი Opera-ს მიერ\",\"options\":\"პარამეტრები\",\"optionsTab\":\"პარამეტრები\",\"title\":\"მართლწერის შემოწმება კრეფისას\",\"toggle\":\"SCAYT-ის გადართვა\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"სტილები\",\"panelTitle\":\"ფორმატირების სტილები\",\"panelTitle1\":\"არის სტილები\",\"panelTitle2\":\"თანდართული სტილები\",\"panelTitle3\":\"ობიექტის სტილები\"},\"table\":{\"border\":\"ჩარჩოს ზომა\",\"caption\":\"სათაური\",\"cell\":{\"menu\":\"უჯრა\",\"insertBefore\":\"უჯრის ჩასმა მანამდე\",\"insertAfter\":\"უჯრის ჩასმა მერე\",\"deleteCell\":\"უჯრების წაშლა\",\"merge\":\"უჯრების შეერთება\",\"mergeRight\":\"შეერთება მარჯვენასთან\",\"mergeDown\":\"შეერთება ქვემოთასთან\",\"splitHorizontal\":\"გაყოფა ჰორიზონტალურად\",\"splitVertical\":\"გაყოფა ვერტიკალურად\",\"title\":\"უჯრის პარამეტრები\",\"cellType\":\"უჯრის ტიპი\",\"rowSpan\":\"სტრიქონების ოდენობა\",\"colSpan\":\"სვეტების ოდენობა\",\"wordWrap\":\"სტრიქონის გადატანა (Word Wrap)\",\"hAlign\":\"ჰორიზონტალური სწორება\",\"vAlign\":\"ვერტიკალური სწორება\",\"alignBaseline\":\"ძირითადი ხაზის გასწვრივ\",\"bgColor\":\"ფონის ფერი\",\"borderColor\":\"ჩარჩოს ფერი\",\"data\":\"მონაცემები\",\"header\":\"სათაური\",\"yes\":\"დიახ\",\"no\":\"არა\",\"invalidWidth\":\"უჯრის სიგანე რიცხვით უნდა იყოს წარმოდგენილი.\",\"invalidHeight\":\"უჯრის სიმაღლე რიცხვით უნდა იყოს წარმოდგენილი.\",\"invalidRowSpan\":\"სტრიქონების რაოდენობა მთელი რიცხვი უნდა იყოს.\",\"invalidColSpan\":\"სვეტების რაოდენობა მთელი რიცხვი უნდა იყოს.\",\"chooseColor\":\"არჩევა\"},\"cellPad\":\"უჯრის კიდე (padding)\",\"cellSpace\":\"უჯრის სივრცე (spacing)\",\"column\":{\"menu\":\"სვეტი\",\"insertBefore\":\"სვეტის ჩამატება წინ\",\"insertAfter\":\"სვეტის ჩამატება მერე\",\"deleteColumn\":\"სვეტების წაშლა\"},\"columns\":\"სვეტი\",\"deleteTable\":\"ცხრილის წაშლა\",\"headers\":\"სათაურები\",\"headersBoth\":\"ორივე\",\"headersColumn\":\"პირველი სვეტი\",\"headersNone\":\"არაფერი\",\"headersRow\":\"პირველი სტრიქონი\",\"invalidBorder\":\"ჩარჩოს ზომა რიცხვით უდნა იყოს წარმოდგენილი.\",\"invalidCellPadding\":\"უჯრის კიდე (padding) რიცხვით უნდა იყოს წარმოდგენილი.\",\"invalidCellSpacing\":\"უჯრის სივრცე (spacing) რიცხვით უნდა იყოს წარმოდგენილი.\",\"invalidCols\":\"სვეტების რაოდენობა დადებითი რიცხვი უნდა იყოს.\",\"invalidHeight\":\"ცხრილის სიმაღლე რიცხვით უნდა იყოს წარმოდგენილი.\",\"invalidRows\":\"სტრიქონების რაოდენობა დადებითი რიცხვი უნდა იყოს.\",\"invalidWidth\":\"ცხრილის სიგანე რიცხვით უნდა იყოს წარმოდგენილი.\",\"menu\":\"ცხრილის პარამეტრები\",\"row\":{\"menu\":\"სტრიქონი\",\"insertBefore\":\"სტრიქონის ჩამატება წინ\",\"insertAfter\":\"სტრიქონის ჩამატება მერე\",\"deleteRow\":\"სტრიქონების წაშლა\"},\"rows\":\"სტრიქონი\",\"summary\":\"შეჯამება\",\"title\":\"ცხრილის პარამეტრები\",\"toolbar\":\"ცხრილი\",\"widthPc\":\"პროცენტი\",\"widthPx\":\"წერტილი\",\"widthUnit\":\"საზომი ერთეული\"},\"undo\":{\"redo\":\"გამეორება\",\"undo\":\"გაუქმება\"},\"wsc\":{\"btnIgnore\":\"უგულებელყოფა\",\"btnIgnoreAll\":\"ყველას უგულებელყოფა\",\"btnReplace\":\"შეცვლა\",\"btnReplaceAll\":\"ყველას შეცვლა\",\"btnUndo\":\"გაუქმება\",\"changeTo\":\"შეცვლელი\",\"errorLoading\":\"სერვისის გამოძახების შეცდომა: %s.\",\"ieSpellDownload\":\"მართლწერის შემოწმება არაა დაინსტალირებული. ჩამოვქაჩოთ ინტერნეტიდან?\",\"manyChanges\":\"მართლწერის შემოწმება: %1 სიტყვა შეიცვალა\",\"noChanges\":\"მართლწერის შემოწმება: არაფერი შეცვლილა\",\"noMispell\":\"მართლწერის შემოწმება: შეცდომა არ მოიძებნა\",\"noSuggestions\":\"- არაა შემოთავაზება -\",\"notAvailable\":\"უკაცრავად, ეს სერვისი ამჟამად მიუწვდომელია.\",\"notInDic\":\"არაა ლექსიკონში\",\"oneChange\":\"მართლწერის შემოწმება: ერთი სიტყვა შეიცვალა\",\"progress\":\"მიმდინარეობს მართლწერის შემოწმება...\",\"title\":\"მართლწერა\",\"toolbar\":\"მართლწერა\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/km.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['km']={\"editor\":\"ឧបករណ៍សរសេរអត្ថបទសម្បូរបែប\",\"editorPanel\":\"ផ្ទាំងឧបករណ៍សរសេរអត្ថបទសម្បូរបែប\",\"common\":{\"editorHelp\":\"ចុច ALT 0 សម្រាប់ជំនួយ\",\"browseServer\":\"រកមើលក្នុងម៉ាស៊ីនបម្រើ\",\"url\":\"URL\",\"protocol\":\"ពិធីការ\",\"upload\":\"ផ្ទុកឡើង\",\"uploadSubmit\":\"បញ្ជូនទៅកាន់ម៉ាស៊ីនបម្រើ\",\"image\":\"រូបភាព\",\"flash\":\"Flash\",\"form\":\"បែបបទ\",\"checkbox\":\"ប្រអប់ធីក\",\"radio\":\"ប៊ូតុងមូល\",\"textField\":\"វាលអត្ថបទ\",\"textarea\":\"Textarea\",\"hiddenField\":\"វាលកំបាំង\",\"button\":\"ប៊ូតុង\",\"select\":\"វាលជម្រើស\",\"imageButton\":\"ប៊ូតុងរូបភាព\",\"notSet\":\"<មិនកំណត់>\",\"id\":\"Id\",\"name\":\"ឈ្មោះ\",\"langDir\":\"ទិសដៅភាសា\",\"langDirLtr\":\"ពីឆ្វេងទៅស្តាំ (LTR)\",\"langDirRtl\":\"ពីស្តាំទៅឆ្វេង (RTL)\",\"langCode\":\"លេខកូដភាសា\",\"longDescr\":\"URL អធិប្បាយវែង\",\"cssClass\":\"Stylesheet Classes\",\"advisoryTitle\":\"ចំណងជើងណែនាំ\",\"cssStyle\":\"រចនាបថ\",\"ok\":\"ព្រម\",\"cancel\":\"បោះបង់\",\"close\":\"បិទ\",\"preview\":\"មើលជាមុន\",\"resize\":\"ប្ដូរទំហំ\",\"generalTab\":\"ទូទៅ\",\"advancedTab\":\"កម្រិតខ្ពស់\",\"validateNumberFailed\":\"តម្លៃនេះពុំមែនជាលេខទេ។\",\"confirmNewPage\":\"រាល់បន្លាស់ប្ដូរនានាដែលមិនទាន់រក្សាទុកក្នុងមាតិកានេះ នឹងត្រូវបាត់បង់។ តើអ្នកពិតជាចង់ផ្ទុកទំព័រថ្មីមែនទេ?\",\"confirmCancel\":\"ការកំណត់មួយចំនួនត្រូវបានផ្លាស់ប្ដូរ។ តើអ្នកពិតជាចង់បិទប្រអប់នេះមែនទេ?\",\"options\":\"ការកំណត់\",\"target\":\"គោលដៅ\",\"targetNew\":\"វីនដូថ្មី (_blank)\",\"targetTop\":\"វីនដូលើគេ (_top)\",\"targetSelf\":\"វីនដូដូចគ្នា (_self)\",\"targetParent\":\"វីនដូមេ (_parent)\",\"langDirLTR\":\"ពីឆ្វេងទៅស្តាំ(LTR)\",\"langDirRTL\":\"ពីស្តាំទៅឆ្វេង(RTL)\",\"styles\":\"រចនាបថ\",\"cssClasses\":\"Stylesheet Classes\",\"width\":\"ទទឹង\",\"height\":\"កំពស់\",\"align\":\"កំណត់ទីតាំង\",\"alignLeft\":\"ខាងឆ្វង\",\"alignRight\":\"ខាងស្តាំ\",\"alignCenter\":\"កណ្តាល\",\"alignTop\":\"ខាងលើ\",\"alignMiddle\":\"កណ្តាល\",\"alignBottom\":\"ខាងក្រោម\",\"invalidValue\":\"តម្លៃមិនត្រឹមត្រូវ។\",\"invalidHeight\":\"តម្លៃកំពស់ត្រូវតែជាលេខ។\",\"invalidWidth\":\"តម្លៃទទឹងត្រូវតែជាលេខ។\",\"invalidCssLength\":\"តម្លៃកំណត់សម្រាប់វាល \\\"%1\\\" ត្រូវតែជាលេខវិជ្ជមាន ដោយភ្ជាប់ឬមិនភ្ជាប់ជាមួយនឹងឯកតារង្វាស់របស់ CSS (px, %, in, cm, mm, em, ex, pt ឬ pc) ។\",\"invalidHtmlLength\":\"តម្លៃកំណត់សម្រាប់វាល \\\"%1\\\" ត្រូវតែជាលេខវិជ្ជមាន ដោយភ្ជាប់ឬមិនភ្ជាប់ជាមួយនឹងឯកតារង្វាស់របស់ HTML (px ឬ %) ។\",\"invalidInlineStyle\":\"តម្លៃកំណត់សម្រាប់រចនាបថក្នុងតួ ត្រូវតែមានមួយឬធាតុច្រើនដោយមានទ្រង់ទ្រាយជា \\\"ឈ្មោះ : តម្លៃ\\\" ហើយញែកចេញពីគ្នាដោយចុចក្បៀស។\",\"cssLengthTooltip\":\"បញ្ចូលលេខសម្រាប់តម្លៃជាភិចសែល ឬលេខដែលមានឯកតាត្រឹមត្រូវរបស់ CSS (px, %, in, cm, mm, em, ex, pt ឬ pc) ។\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, មិនមាន</span>\"},\"about\":{\"copy\":\"រក្សាសិទ្ធិ &copy; $1។ រក្សាសិទ្ធិគ្រប់បែបយ៉ាង។\",\"dlgTitle\":\"អំពី CKEditor\",\"help\":\"ពិនិត្យ $1 សម្រាប់ជំនួយ។\",\"moreInfo\":\"សម្រាប់ព័ត៌មានអំពីអាជ្ញាបណញណ សូមមើលក្នុងគេហទំព័ររបស់យើង៖\",\"title\":\"អំពី CKEditor\",\"userGuide\":\"វិធីប្រើប្រាស់ CKEditor\"},\"basicstyles\":{\"bold\":\"ដិត\",\"italic\":\"ទ្រេត\",\"strike\":\"គូសបន្ទាត់ចំកណ្ដាល\",\"subscript\":\"អក្សរតូចក្រោម\",\"superscript\":\"អក្សរតូចលើ\",\"underline\":\"គូសបន្ទាត់ក្រោម\"},\"blockquote\":{\"toolbar\":\"ប្លក់ពាក្យសម្រង់\"},\"clipboard\":{\"copy\":\"ចម្លង\",\"copyError\":\"ការកំណត់សុវត្ថភាពរបស់កម្មវិធីរុករករបស់លោកអ្នក នេះមិនអាចធ្វើកម្មវិធីតាក់តែងអត្ថបទ ចំលងអត្ថបទយកដោយស្វ័យប្រវត្តបានឡើយ ។ សូមប្រើប្រាស់បន្សំ ឃីដូចនេះ (Ctrl/Cmd+C)។\",\"cut\":\"កាត់យក\",\"cutError\":\"ការកំណត់សុវត្ថភាពរបស់កម្មវិធីរុករករបស់លោកអ្នក នេះមិនអាចធ្វើកម្មវិធីតាក់តែងអត្ថបទ កាត់អត្ថបទយកដោយស្វ័យប្រវត្តបានឡើយ ។ សូមប្រើប្រាស់បន្សំ ឃីដូចនេះ  (Ctrl/Cmd+X) ។\",\"paste\":\"បិទភ្ជាប់\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"សូមចំលងអត្ថបទទៅដាក់ក្នុងប្រអប់ដូចខាងក្រោមដោយប្រើប្រាស់ ឃី (<STRONG>Ctrl/Cmd+V</STRONG>) ហើយចុច <STRONG>OK</STRONG> ។\",\"securityMsg\":\"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.\",\"title\":\"បិទភ្ជាប់\"},\"contextmenu\":{\"options\":\"ជម្រើសម៉ឺនុយបរិបទ\"},\"toolbar\":{\"toolbarCollapse\":\"បង្រួមរបារឧបករណ៍\",\"toolbarExpand\":\"ពង្រីករបារឧបករណ៍\",\"toolbarGroups\":{\"document\":\"ឯកសារ\",\"clipboard\":\"Clipboard/មិនធ្វើវិញ\",\"editing\":\"ការកែសម្រួល\",\"forms\":\"បែបបទ\",\"basicstyles\":\"រចនាបថមូលដ្ឋាន\",\"paragraph\":\"កថាខណ្ឌ\",\"links\":\"តំណ\",\"insert\":\"បញ្ចូល\",\"styles\":\"រចនាបថ\",\"colors\":\"ពណ៌\",\"tools\":\"ឧបករណ៍\"},\"toolbars\":\"របារឧបករណ៍កែសម្រួល\"},\"elementspath\":{\"eleLabel\":\"ទីតាំងធាតុ\",\"eleTitle\":\"ធាតុ %1\"},\"format\":{\"label\":\"ទម្រង់\",\"panelTitle\":\"ទម្រង់កថាខណ្ឌ\",\"tag_address\":\"អាសយដ្ឋាន\",\"tag_div\":\"ធម្មតា (DIV)\",\"tag_h1\":\"ចំណងជើង 1\",\"tag_h2\":\"ចំណងជើង 2\",\"tag_h3\":\"ចំណងជើង 3\",\"tag_h4\":\"ចំណងជើង 4\",\"tag_h5\":\"ចំណងជើង 5\",\"tag_h6\":\"ចំណងជើង 6\",\"tag_p\":\"ធម្មតា\",\"tag_pre\":\"Formatted\"},\"horizontalrule\":{\"toolbar\":\"បន្ថែមបន្ទាត់ផ្តេក\"},\"image\":{\"alertUrl\":\"សូមសរសេរងាស័យដ្ឋានរបស់រូបភាព\",\"alt\":\"អត្ថបទជំនួស\",\"border\":\"ស៊ុម\",\"btnUpload\":\"បញ្ជូនទៅកាន់ម៉ាស៊ីនផ្តល់សេវា\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"គំលាតទទឹង\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"ពត៌មានអំពីរូបភាព\",\"linkTab\":\"ឈ្នាប់\",\"lockRatio\":\"អត្រាឡុក\",\"menu\":\"ការកំណត់រូបភាព\",\"resetSize\":\"កំណត់ទំហំឡើងវិញ\",\"title\":\"ការកំណត់រូបភាព\",\"titleButton\":\"ការកំណត់ប៉ូតុនរូបភាព\",\"upload\":\"ទាញយក\",\"urlMissing\":\"ខ្វះ URL ប្រភពរូបភាព។\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"បន្ថែមការចូលបន្ទាត់\",\"outdent\":\"បន្ថយការចូលបន្ទាត់\"},\"fakeobjects\":{\"anchor\":\"យុថ្កា\",\"flash\":\"Flash មានចលនា\",\"hiddenfield\":\"វាលកំបាំង\",\"iframe\":\"IFrame\",\"unknown\":\"វត្ថុមិនស្គាល់\"},\"link\":{\"acccessKey\":\"សោរចូល\",\"advanced\":\"កម្រិតខ្ពស់\",\"advisoryContentType\":\"ប្រភេទអត្ថបទប្រឹក្សា\",\"advisoryTitle\":\"ចំណងជើងប្រឹក្សា\",\"anchor\":{\"toolbar\":\"យុថ្កា\",\"menu\":\"កែយុថ្កា\",\"title\":\"លក្ខណៈយុថ្កា\",\"name\":\"ឈ្មោះយុថ្កា\",\"errorName\":\"សូមបញ្ចូលឈ្មោះយុថ្កា\",\"remove\":\"ដកយុថ្កាចេញ\"},\"anchorId\":\"តាម ID ធាតុ\",\"anchorName\":\"តាមឈ្មោះយុថ្កា\",\"charset\":\"Linked Resource Charset\",\"cssClasses\":\"Stylesheet Classes\",\"emailAddress\":\"អាសយដ្ឋានអ៊ីមែល\",\"emailBody\":\"តួអត្ថបទ\",\"emailSubject\":\"ប្រធានបទសារ\",\"id\":\"Id\",\"info\":\"ព័ត៌មានពីតំណ\",\"langCode\":\"កូដភាសា\",\"langDir\":\"ទិសដៅភាសា\",\"langDirLTR\":\"ពីឆ្វេងទៅស្តាំ(LTR)\",\"langDirRTL\":\"ពីស្តាំទៅឆ្វេង(RTL)\",\"menu\":\"កែតំណ\",\"name\":\"ឈ្មោះ\",\"noAnchors\":\"(មិនមានយុថ្កានៅក្នុងឯកសារអត្ថថបទទេ)\",\"noEmail\":\"សូមបញ្ចូលអាសយដ្ឋានអ៊ីមែល\",\"noUrl\":\"សូមបញ្ចូលតំណ URL\",\"other\":\"<ផ្សេងទៀត>\",\"popupDependent\":\"Dependent (Netscape)\",\"popupFeatures\":\"Popup Window Features\",\"popupFullScreen\":\"ពេញអេក្រង់ (IE)\",\"popupLeft\":\"ទីតាំងខាងឆ្វេង\",\"popupLocationBar\":\"របារទីតាំង\",\"popupMenuBar\":\"របារម៉ឺនុយ\",\"popupResizable\":\"អាចប្ដូរទំហំ\",\"popupScrollBars\":\"របាររំកិល\",\"popupStatusBar\":\"របារស្ថានភាព\",\"popupToolbar\":\"របារឧបករណ៍\",\"popupTop\":\"ទីតាំងកំពូល\",\"rel\":\"សម្ពន្ធភាព\",\"selectAnchor\":\"រើសយកយុថ្កាមួយ\",\"styles\":\"ស្ទីល\",\"tabIndex\":\"Tab Index\",\"target\":\"គោលដៅ\",\"targetFrame\":\"<ស៊ុម>\",\"targetFrameName\":\"ឈ្មោះស៊ុមជាគោលដៅ\",\"targetPopup\":\"<វីនដូផុសឡើង>\",\"targetPopupName\":\"ឈ្មោះវីនដូតផុសឡើង\",\"title\":\"តំណ\",\"toAnchor\":\"តភ្ជាប់ទៅយុថ្កាក្នុងអត្ថបទ\",\"toEmail\":\"អ៊ីមែល\",\"toUrl\":\"URL\",\"toolbar\":\"តំណ\",\"type\":\"ប្រភេទតំណ\",\"unlink\":\"ផ្ដាច់តំណ\",\"upload\":\"ផ្ទុកឡើង\"},\"list\":{\"bulletedlist\":\"បញ្ចូល / លុបបញ្ជីជាចំណុចមូល\",\"numberedlist\":\"បញ្ចូល / លុបបញ្ជីជាលេខ\"},\"magicline\":{\"title\":\"បញ្ចូលកថាខណ្ឌនៅទីនេះ\"},\"maximize\":{\"maximize\":\"ពង្រីកអតិបរមា\",\"minimize\":\"បង្រួមអប្បបរមា\"},\"pastetext\":{\"button\":\"បិទភ្ជាប់ជាអត្ថបទធម្មតា\",\"title\":\"បិទភ្ជាប់ជាអត្ថបទធម្មតា\"},\"pastefromword\":{\"confirmCleanup\":\"អត្ថបទដែលអ្នកចង់បិទភ្ជាប់នេះ ទំនងដូចជាចម្លងមកពី Word។ តើអ្នកចង់សម្អាតវាមុនបិទភ្ជាប់ទេ?\",\"error\":\"ដោយសារមានបញ្ហាផ្នែកក្នុងធ្វើឲ្យមិនអាចសម្អាតទិន្នន័យដែលបានបិទភ្ជាប់\",\"title\":\"បិទភ្ជាប់ពី Word\",\"toolbar\":\"បិទភ្ជាប់ពី Word\"},\"removeformat\":{\"toolbar\":\"ជម្រះទ្រង់ទ្រាយ\"},\"sourcearea\":{\"toolbar\":\"អក្សរកូដ\"},\"specialchar\":{\"options\":\"ជម្រើសតួអក្សរពិសេស\",\"title\":\"រើសតួអក្សរពិសេស\",\"toolbar\":\"បន្ថែមអក្សរពិសេស\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"រចនាបថ\",\"panelTitle\":\"ទ្រង់ទ្រាយរចនាបថ\",\"panelTitle1\":\"រចនាបថប្លក់\",\"panelTitle2\":\"រចនាបថក្នុងជួរ\",\"panelTitle3\":\"រចនាបថវត្ថុ\"},\"table\":{\"border\":\"ទំហំបន្ទាត់ស៊ុម\",\"caption\":\"ចំណងជើង\",\"cell\":{\"menu\":\"ក្រឡា\",\"insertBefore\":\"បញ្ចូលក្រឡាពីមុខ\",\"insertAfter\":\"បញ្ចូលក្រឡាពីក្រោយ\",\"deleteCell\":\"លុបក្រឡា\",\"merge\":\"បញ្ចូលក្រឡាចូលគ្នា\",\"mergeRight\":\"បញ្ចូលគ្នាខាងស្ដាំ\",\"mergeDown\":\"បញ្ចូលគ្នាចុះក្រោម\",\"splitHorizontal\":\"ពុះក្រឡាផ្ដេក\",\"splitVertical\":\"ពុះក្រឡាបញ្ឈរ\",\"title\":\"លក្ខណៈក្រឡា\",\"cellType\":\"ប្រភេទក្រឡា\",\"rowSpan\":\"ចំនួនជួរដេកលាយចូលគ្នា\",\"colSpan\":\"ចំនួនជួរឈរលាយចូលគ្នា\",\"wordWrap\":\"រុំពាក្យ\",\"hAlign\":\"ការតម្រឹមផ្ដេក\",\"vAlign\":\"ការតម្រឹមបញ្ឈរ\",\"alignBaseline\":\"ខ្សែបន្ទាត់គោល\",\"bgColor\":\"ពណ៌ផ្ទៃក្រោយ\",\"borderColor\":\"ពណ៌បន្ទាត់ស៊ុម\",\"data\":\"ទិន្នន័យ\",\"header\":\"ក្បាល\",\"yes\":\"ព្រម\",\"no\":\"ទេ\",\"invalidWidth\":\"ទទឹងក្រឡាត្រូវតែជាលេខ។\",\"invalidHeight\":\"កម្ពស់ក្រឡាត្រូវតែជាលេខ។\",\"invalidRowSpan\":\"ចំនួនជួរដេកលាយចូលគ្នាត្រូវតែជាលេខទាំងអស់។\",\"invalidColSpan\":\"ចំនួនជួរឈរលាយចូលគ្នាត្រូវតែជាលេខទាំងអស់។\",\"chooseColor\":\"រើស\"},\"cellPad\":\"ចន្លោះក្រឡា\",\"cellSpace\":\"គម្លាតក្រឡា\",\"column\":{\"menu\":\"ជួរឈរ\",\"insertBefore\":\"បញ្ចូលជួរឈរពីមុខ\",\"insertAfter\":\"បញ្ចូលជួរឈរពីក្រោយ\",\"deleteColumn\":\"លុបជួរឈរ\"},\"columns\":\"ជួរឈរ\",\"deleteTable\":\"លុបតារាង\",\"headers\":\"ក្បាល\",\"headersBoth\":\"ទាំងពីរ\",\"headersColumn\":\"ជួរឈរដំបូង\",\"headersNone\":\"មិនមាន\",\"headersRow\":\"ជួរដេកដំបូង\",\"invalidBorder\":\"ទំហំបន្ទាត់ស៊ុមត្រូវតែជាលេខ។\",\"invalidCellPadding\":\"ចន្លោះក្រឡាត្រូវតែជាលេខវិជ្ជមាន។\",\"invalidCellSpacing\":\"គម្លាតក្រឡាត្រូវតែជាលេខវិជ្ជមាន។\",\"invalidCols\":\"ចំនួនជួរឈរត្រូវតែជាលេខធំជាង 0។\",\"invalidHeight\":\"កម្ពស់តារាងត្រូវតែជាលេខ\",\"invalidRows\":\"ចំនួនជួរដេកត្រូវតែជាលេខធំជាង 0។\",\"invalidWidth\":\"ទទឹងតារាងត្រូវតែជាលេខ។\",\"menu\":\"លក្ខណៈតារាង\",\"row\":{\"menu\":\"ជួរដេក\",\"insertBefore\":\"បញ្ចូលជួរដេកពីមុខ\",\"insertAfter\":\"បញ្ចូលជួរដេកពីក្រោយ\",\"deleteRow\":\"លុបជួរដេក\"},\"rows\":\"ជួរដេក\",\"summary\":\"សេចក្តីសង្ខេប\",\"title\":\"លក្ខណៈតារាង\",\"toolbar\":\"តារាង\",\"widthPc\":\"ភាគរយ\",\"widthPx\":\"ភីកសែល\",\"widthUnit\":\"ឯកតាទទឹង\"},\"undo\":{\"redo\":\"ធ្វើឡើងវិញ\",\"undo\":\"មិនធ្វើវិញ\"},\"wsc\":{\"btnIgnore\":\"មិនផ្លាស់ប្តូរ\",\"btnIgnoreAll\":\"មិនផ្លាស់ប្តូរ ទាំងអស់\",\"btnReplace\":\"ជំនួស\",\"btnReplaceAll\":\"ជំនួសទាំងអស់\",\"btnUndo\":\"សារឡើងវិញ\",\"changeTo\":\"ផ្លាស់ប្តូរទៅ\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"ពុំមានកម្មវិធីពិនិត្យអក្ខរាវិរុទ្ធ ។ តើចង់ទាញយកពីណា?\",\"manyChanges\":\"ការពិនិត្យអក្ខរាវិរុទ្ធបានចប់: %1 ពាក្យបានផ្លាស់ប្តូរ\",\"noChanges\":\"ការពិនិត្យអក្ខរាវិរុទ្ធបានចប់: ពុំមានផ្លាស់ប្តូរ\",\"noMispell\":\"ការពិនិត្យអក្ខរាវិរុទ្ធបានចប់: គ្មានកំហុស\",\"noSuggestions\":\"- គ្មានសំណើរ -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"គ្មានក្នុងវចនានុក្រម\",\"oneChange\":\"ការពិនិត្យអក្ខរាវិរុទ្ធបានចប់: ពាក្យមួយត្រូចបានផ្លាស់ប្តូរ\",\"progress\":\"កំពុងពិនិត្យអក្ខរាវិរុទ្ធ...\",\"title\":\"Spell Check\",\"toolbar\":\"ពិនិត្យអក្ខរាវិរុទ្ធ\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/ko.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['ko']={\"editor\":\"리치 텍스트 편집기\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"도움이 필요하시면 ALT 0 을 누르세요\",\"browseServer\":\"서버 보기\",\"url\":\"URL\",\"protocol\":\"프로토콜\",\"upload\":\"업로드\",\"uploadSubmit\":\"서버로 전송\",\"image\":\"이미지\",\"flash\":\"플래쉬\",\"form\":\"폼\",\"checkbox\":\"체크박스\",\"radio\":\"라디오버튼\",\"textField\":\"입력필드\",\"textarea\":\"입력영역\",\"hiddenField\":\"숨김필드\",\"button\":\"버튼\",\"select\":\"펼침목록\",\"imageButton\":\"이미지버튼\",\"notSet\":\"<설정되지 않음>\",\"id\":\"ID\",\"name\":\"Name\",\"langDir\":\"쓰기 방향\",\"langDirLtr\":\"왼쪽에서 오른쪽 (LTR)\",\"langDirRtl\":\"오른쪽에서 왼쪽 (RTL)\",\"langCode\":\"언어 코드\",\"longDescr\":\"URL 설명\",\"cssClass\":\"Stylesheet Classes\",\"advisoryTitle\":\"Advisory Title\",\"cssStyle\":\"Style\",\"ok\":\"예\",\"cancel\":\"아니오\",\"close\":\"닫기\",\"preview\":\"미리보기\",\"resize\":\"크기 조절\",\"generalTab\":\"General\",\"advancedTab\":\"자세히\",\"validateNumberFailed\":\"이 값은 숫자가 아닙니다.\",\"confirmNewPage\":\"저장하지 않은 모든 변경사항은 유실됩니다. 정말로 새로운 페이지를 부르겠습니까?\",\"confirmCancel\":\"몇몇개의 옵션이 바꼈습니다. 정말로 창을 닫으시겠습니까?\",\"options\":\"옵션\",\"target\":\"타겟\",\"targetNew\":\"새로운 창 (_blank)\",\"targetTop\":\"최상위 창 (_top)\",\"targetSelf\":\"같은 창 (_self)\",\"targetParent\":\"부모 창 (_parent)\",\"langDirLTR\":\"왼쪽에서 오른쪽 (LTR)\",\"langDirRTL\":\"오른쪽에서 왼쪽 (RTL)\",\"styles\":\"Style\",\"cssClasses\":\"Stylesheet Classes\",\"width\":\"너비\",\"height\":\"높이\",\"align\":\"정렬\",\"alignLeft\":\"왼쪽\",\"alignRight\":\"오른쪽\",\"alignCenter\":\"가운데\",\"alignTop\":\"위\",\"alignMiddle\":\"중간\",\"alignBottom\":\"아래\",\"invalidValue\":\"잘못된 값.\",\"invalidHeight\":\"높이는 숫자여야 합니다.\",\"invalidWidth\":\"넓이는 숫자여야 합니다.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, 사용할 수 없음</span>\"},\"about\":{\"copy\":\"저작권 &copy; $1 . 판권 소유.\",\"dlgTitle\":\"CKEditor 에 대하여\",\"help\":\"도움이 필요하시면 $1 를 확인하세요\",\"moreInfo\":\"라이센스에 대한  정보를 보고싶다면 우리의 웹 사이트를 방문하세요:\",\"title\":\"CKEditor에 대하여\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"진하게\",\"italic\":\"이텔릭\",\"strike\":\"취소선\",\"subscript\":\"아래 첨자\",\"superscript\":\"위 첨자\",\"underline\":\"밑줄\"},\"blockquote\":{\"toolbar\":\"인용 블록\"},\"clipboard\":{\"copy\":\"복사하기\",\"copyError\":\"브라우저의 보안설정때문에 복사하기 기능을 실행할 수 없습니다. 키보드 명령을 사용하십시요.  (Ctrl/Cmd+C).\",\"cut\":\"잘라내기\",\"cutError\":\"브라우저의 보안설정때문에 잘라내기 기능을 실행할 수 없습니다. 키보드 명령을 사용하십시요. (Ctrl/Cmd+X).\",\"paste\":\"붙여넣기\",\"pasteArea\":\"범위 붙여넣기\",\"pasteMsg\":\"키보드의 (<STRONG>Ctrl/Cmd+V</STRONG>) 를 이용해서 상자안에 붙여넣고 <STRONG>OK</STRONG> 를 누르세요.\",\"securityMsg\":\"브러우저 보안 설정으로 인해, 클립보드의 자료를 직접 접근할 수 없습니다. 이 창에 다시 붙여넣기 하십시오.\",\"title\":\"붙여넣기\"},\"contextmenu\":{\"options\":\"컨텍스트 메뉴 옵션\"},\"toolbar\":{\"toolbarCollapse\":\"툴바 삭제\",\"toolbarExpand\":\"확장 툴바\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"편집자용 툴바들\"},\"elementspath\":{\"eleLabel\":\"요소 위치\",\"eleTitle\":\"%1 요소\"},\"format\":{\"label\":\"포맷\",\"panelTitle\":\"포맷\",\"tag_address\":\"Address\",\"tag_div\":\"기본 (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatted\"},\"horizontalrule\":{\"toolbar\":\"수평선 삽입\"},\"image\":{\"alertUrl\":\"이미지 URL을 입력하십시요\",\"alt\":\"이미지 설명\",\"border\":\"테두리\",\"btnUpload\":\"서버로 전송\",\"button2Img\":\"단순 이미지에서 선택한 이미지 버튼을 변환하시겠습니까?\",\"hSpace\":\"수평여백\",\"img2Button\":\"이미지 버튼에 선택한 이미지를 변환하시겠습니까?\",\"infoTab\":\"이미지 정보\",\"linkTab\":\"링크\",\"lockRatio\":\"비율 유지\",\"menu\":\"이미지 설정\",\"resetSize\":\"원래 크기로\",\"title\":\"이미지 설정\",\"titleButton\":\"이미지버튼 속성\",\"upload\":\"업로드\",\"urlMissing\":\"이미지 소스 URL이 없습니다.\",\"vSpace\":\"수직여백\",\"validateBorder\":\"테두리는 정수여야 합니다.\",\"validateHSpace\":\"가로 길이는 정수여야 합니다.\",\"validateVSpace\":\"세로 길이는 정수여야 합니다.\"},\"indent\":{\"indent\":\"들여쓰기\",\"outdent\":\"내어쓰기\"},\"fakeobjects\":{\"anchor\":\"책갈피 삽입/변경\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"숨김필드\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"엑세스 키\",\"advanced\":\"자세히\",\"advisoryContentType\":\"Advisory Content Type\",\"advisoryTitle\":\"Advisory Title\",\"anchor\":{\"toolbar\":\"책갈피 삽입/변경\",\"menu\":\"책갈피 속성\",\"title\":\"책갈피 속성\",\"name\":\"책갈피 이름\",\"errorName\":\"책갈피 이름을 입력하십시요.\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"책갈피 ID\",\"anchorName\":\"책갈피 이름\",\"charset\":\"Linked Resource Charset\",\"cssClasses\":\"Stylesheet Classes\",\"emailAddress\":\"이메일 주소\",\"emailBody\":\"내용\",\"emailSubject\":\"제목\",\"id\":\"ID\",\"info\":\"링크 정보\",\"langCode\":\"쓰기 방향\",\"langDir\":\"쓰기 방향\",\"langDirLTR\":\"왼쪽에서 오른쪽 (LTR)\",\"langDirRTL\":\"오른쪽에서 왼쪽 (RTL)\",\"menu\":\"링크 수정\",\"name\":\"Name\",\"noAnchors\":\"(문서에 책갈피가 없습니다.)\",\"noEmail\":\"이메일주소를 입력하십시요.\",\"noUrl\":\"링크 URL을 입력하십시요.\",\"other\":\"<기타>\",\"popupDependent\":\"Dependent (Netscape)\",\"popupFeatures\":\"팝업창 설정\",\"popupFullScreen\":\"전체화면 (IE)\",\"popupLeft\":\"왼쪽 위치\",\"popupLocationBar\":\"주소표시줄\",\"popupMenuBar\":\"메뉴바\",\"popupResizable\":\"크기 조절 가능\",\"popupScrollBars\":\"스크롤바\",\"popupStatusBar\":\"상태바\",\"popupToolbar\":\"툴바\",\"popupTop\":\"윗쪽 위치\",\"rel\":\"Relationship\",\"selectAnchor\":\"책갈피 선택\",\"styles\":\"Style\",\"tabIndex\":\"탭 순서\",\"target\":\"타겟\",\"targetFrame\":\"<프레임>\",\"targetFrameName\":\"타겟 프레임 이름\",\"targetPopup\":\"<팝업창>\",\"targetPopupName\":\"팝업창 이름\",\"title\":\"링크\",\"toAnchor\":\"책갈피\",\"toEmail\":\"이메일\",\"toUrl\":\"URL\",\"toolbar\":\"링크 삽입/변경\",\"type\":\"링크 종류\",\"unlink\":\"링크 삭제\",\"upload\":\"업로드\"},\"list\":{\"bulletedlist\":\"순서없는 목록\",\"numberedlist\":\"순서있는 목록\"},\"magicline\":{\"title\":\"여기에 그래프 삽입\"},\"maximize\":{\"maximize\":\"최대\",\"minimize\":\"최소\"},\"pastetext\":{\"button\":\"텍스트로 붙여넣기\",\"title\":\"텍스트로 붙여넣기\"},\"pastefromword\":{\"confirmCleanup\":\"붙여 넣기 할 텍스트는 MS Word에서 복사 한 것입니다. 붙여 넣기 전에 MS Word 포멧을 삭제 하시겠습니까?\",\"error\":\"내부 오류로 붙여 넣은 데이터를 정리 할 수 없습니다.\",\"title\":\"MS Word 형식에서 붙여넣기\",\"toolbar\":\"MS Word 형식에서 붙여넣기\"},\"removeformat\":{\"toolbar\":\"포맷 지우기\"},\"sourcearea\":{\"toolbar\":\"소스\"},\"specialchar\":{\"options\":\"특수문자 옵션\",\"title\":\"특수문자 선택\",\"toolbar\":\"특수문자 삽입\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"스타일\",\"panelTitle\":\"전체 구성 스타일\",\"panelTitle1\":\"블록 스타일\",\"panelTitle2\":\"인라인 스타일\",\"panelTitle3\":\"오브젝트 스타일\"},\"table\":{\"border\":\"테두리 크기\",\"caption\":\"캡션\",\"cell\":{\"menu\":\"셀/칸(Cell)\",\"insertBefore\":\"앞에 셀/칸 삽입\",\"insertAfter\":\"뒤에 셀/칸 삽입\",\"deleteCell\":\"셀 삭제\",\"merge\":\"셀 합치기\",\"mergeRight\":\"오른쪽 뭉치기\",\"mergeDown\":\"왼쪽 뭉치기\",\"splitHorizontal\":\"수평 나누기\",\"splitVertical\":\"수직 나누기\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"셀 여백\",\"cellSpace\":\"셀 간격\",\"column\":{\"menu\":\"열(Column)\",\"insertBefore\":\"앞에 열 삽입\",\"insertAfter\":\"뒤에 열 삽입\",\"deleteColumn\":\"세로줄 삭제\"},\"columns\":\"세로줄\",\"deleteTable\":\"표 삭제\",\"headers\":\"해더\",\"headersBoth\":\"모두\",\"headersColumn\":\"첫 열\",\"headersNone\":\"None\",\"headersRow\":\"첫 행\",\"invalidBorder\":\"테두리 크기는 숫자여야 합니다.\",\"invalidCellPadding\":\"셀 안쪽의 여백은 0 이상이어야 합니다.\",\"invalidCellSpacing\":\"셀 간격은 0 이상이어야 합니다.\",\"invalidCols\":\"행 번호는 0보다 큰 숫자여야 합니다.\",\"invalidHeight\":\"표 높이는 숫자여야 합니다.\",\"invalidRows\":\"행 번호는 0보다 큰 숫자여야 합니다.\",\"invalidWidth\":\"표의 폭은 숫자여야 합니다.\",\"menu\":\"표 설정\",\"row\":{\"menu\":\"행(Row)\",\"insertBefore\":\"앞에 행 삽입\",\"insertAfter\":\"뒤에 행 삽입\",\"deleteRow\":\"가로줄 삭제\"},\"rows\":\"가로줄\",\"summary\":\"요약\",\"title\":\"표 설정\",\"toolbar\":\"표\",\"widthPc\":\"퍼센트\",\"widthPx\":\"픽셀\",\"widthUnit\":\"폭 단위\"},\"undo\":{\"redo\":\"재실행\",\"undo\":\"취소\"},\"wsc\":{\"btnIgnore\":\"건너뜀\",\"btnIgnoreAll\":\"모두 건너뜀\",\"btnReplace\":\"변경\",\"btnReplaceAll\":\"모두 변경\",\"btnUndo\":\"취소\",\"changeTo\":\"변경할 단어\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"철자 검사기가 철치되지 않았습니다. 지금 다운로드하시겠습니까?\",\"manyChanges\":\"철자검사 완료: %1 단어가 변경되었습니다.\",\"noChanges\":\"철자검사 완료: 변경된 단어가 없습니다.\",\"noMispell\":\"철자검사 완료: 잘못된 철자가 없습니다.\",\"noSuggestions\":\"- 추천단어 없음 -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"사전에 없는 단어\",\"oneChange\":\"철자검사 완료: 단어가 변경되었습니다.\",\"progress\":\"철자검사를 진행중입니다...\",\"title\":\"Spell Check\",\"toolbar\":\"철자검사\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/ku.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['ku']={\"editor\":\"سەرنووسەی دەقی بە پیت\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"کلیکی ALT لەگەڵ 0 بکه بۆ یارمەتی\",\"browseServer\":\"هێنانی ڕاژە\",\"url\":\"ناونیشانی بەستەر\",\"protocol\":\"پڕۆتۆکۆڵ\",\"upload\":\"بارکردن\",\"uploadSubmit\":\"ناردنی بۆ ڕاژە\",\"image\":\"وێنە\",\"flash\":\"فلاش\",\"form\":\"داڕشتە\",\"checkbox\":\"خانەی نیشانکردن\",\"radio\":\"جێگرەوەی دوگمە\",\"textField\":\"خانەی دەق\",\"textarea\":\"ڕووبەری دەق\",\"hiddenField\":\"شاردنەوی خانە\",\"button\":\"دوگمە\",\"select\":\"هەڵبژاردەی خانە\",\"imageButton\":\"دوگمەی وێنە\",\"notSet\":\"<هیچ دانەدراوە>\",\"id\":\"ناسنامە\",\"name\":\"ناو\",\"langDir\":\"ئاراستەی زمان\",\"langDirLtr\":\"چەپ بۆ ڕاست (LTR)\",\"langDirRtl\":\"ڕاست بۆ چەپ (RTL)\",\"langCode\":\"هێمای زمان\",\"longDescr\":\"پێناسەی درێژی بەستەر\",\"cssClass\":\"شێوازی چینی پهڕە\",\"advisoryTitle\":\"ڕاوێژکاری سەردێڕ\",\"cssStyle\":\"شێواز\",\"ok\":\"باشە\",\"cancel\":\"هەڵوەشاندن\",\"close\":\"داخستن\",\"preview\":\"پێشبینین\",\"resize\":\"گۆڕینی ئەندازە\",\"generalTab\":\"گشتی\",\"advancedTab\":\"پەرەسەندوو\",\"validateNumberFailed\":\"ئەم نرخە ژمارە نیە، تکایە نرخێکی ژمارە بنووسە.\",\"confirmNewPage\":\"سەرجەم گۆڕانکاریەکان و پێکهاتەکانی ناووەوە لەدەست دەدەی گەر بێتوو پاشکەوتی نەکەی یەکەم جار، تۆ هەر دڵنیایی لەکردنەوەی پەنجەرەکی نوێ؟\",\"confirmCancel\":\"هەندێك هەڵبژاردە گۆڕدراوە. تۆ دڵنیایی لە داخستنی ئەم دیالۆگە؟\",\"options\":\"هەڵبژاردەکان\",\"target\":\"ئامانج\",\"targetNew\":\"پەنجەرەیەکی نوێ (_blank)\",\"targetTop\":\"لووتکەی پەنجەرە (_top)\",\"targetSelf\":\"لەهەمان پەنجەرە (_self)\",\"targetParent\":\"پەنجەرەی باوان (_parent)\",\"langDirLTR\":\"چەپ بۆ ڕاست (LTR)\",\"langDirRTL\":\"ڕاست بۆ چەپ (RTL)\",\"styles\":\"شێواز\",\"cssClasses\":\"شێوازی چینی پەڕە\",\"width\":\"پانی\",\"height\":\"درێژی\",\"align\":\"ڕێککەرەوە\",\"alignLeft\":\"چەپ\",\"alignRight\":\"ڕاست\",\"alignCenter\":\"ناوەڕاست\",\"alignTop\":\"سەرەوە\",\"alignMiddle\":\"ناوەند\",\"alignBottom\":\"ژێرەوە\",\"invalidValue\":\"نرخێکی نادرووست.\",\"invalidHeight\":\"درێژی دەبێت ژمارە بێت.\",\"invalidWidth\":\"پانی دەبێت ژمارە بێت.\",\"invalidCssLength\":\"ئەم نرخەی دراوە بۆ خانەی \\\"%1\\\" دەبێت ژمارەکی درووست بێت یان بێ ناونیشانی ئامرازی (px, %, in, cm, mm, em, ex, pt, یان pc).\",\"invalidHtmlLength\":\"ئەم نرخەی دراوە بۆ خانەی \\\"%1\\\" دەبێت ژمارەکی درووست بێت یان بێ ناونیشانی ئامرازی HTML (px یان %).\",\"invalidInlineStyle\":\"دانەی نرخی شێوازی ناوهێڵ دەبێت پێکهاتبێت لەیەك یان زیاتری داڕشتە \\\"ناو : نرخ\\\", جیاکردنەوەی بە فاریزە و خاڵ\",\"cssLengthTooltip\":\"ژمارەیەك بنووسه بۆ نرخی piksel یان ئامرازێکی درووستی CSS (px, %, in, cm, mm, em, ex, pt, یان pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, ئامادە نیە</span>\"},\"about\":{\"copy\":\"مافی لەبەرگەرتنەوەی &copy; $1. گشتی پارێزراوه. ورگێڕانی بۆ کوردی لەلایەن هۆژە کۆیی.\",\"dlgTitle\":\"دەربارەی CKEditor\",\"help\":\"سەیری $1 بکه بۆ یارمەتی.\",\"moreInfo\":\"بۆ زانیاری زیاتر دەربارەی مۆڵەتی بەکارهێنان، تکایه سەردانی ماڵپەڕەکەمان بکه:\",\"title\":\"دەربارەی CKEditor\",\"userGuide\":\"ڕێپیشاندەری CKEditors\"},\"basicstyles\":{\"bold\":\"قەڵەو\",\"italic\":\"لار\",\"strike\":\"لێدان\",\"subscript\":\"ژێرنووس\",\"superscript\":\"سەرنووس\",\"underline\":\"ژێرهێڵ\"},\"blockquote\":{\"toolbar\":\"بەربەستکردنی ووتەی وەرگیراو\"},\"clipboard\":{\"copy\":\"لەبەرگرتنەوە\",\"copyError\":\"پارێزی وێبگەڕەکەت ڕێگەنادات بەسەرنووسەکە لە لکاندنی دەقی خۆکارارنە. تکایە لەبری ئەمە ئەم فەرمانە بەکاربهێنە بەداگرتنی کلیلی (Ctrl/Cmd+C).\",\"cut\":\"بڕین\",\"cutError\":\"پارێزی وێبگەڕەکەت ڕێگەنادات بە سەرنووسەکە لەبڕینی خۆکارانە. تکایە لەبری ئەمە ئەم فەرمانە بەکاربهێنە بەداگرتنی کلیلی (Ctrl/Cmd+X).\",\"paste\":\"لکاندن\",\"pasteArea\":\"ناوچەی لکاندن\",\"pasteMsg\":\"تکایە بیلکێنە لەناوەوەی ئەم سنوقە لەڕێی تەختەکلیلەکەت بە بەکارهێنانی کلیلی (<STRONG>Ctrl/Cmd+V</STRONG>) دووای کلیکی باشە بکە.\",\"securityMsg\":\"بەهۆی شێوەپێدانی پارێزی وێبگەڕەکەت، سەرنووسەکه ناتوانێت دەستبگەیەنێت بەهەڵگیراوەکە ڕاستەوخۆ. بۆیه پێویسته دووباره بیلکێنیت لەم پەنجەرەیه.\",\"title\":\"لکاندن\"},\"contextmenu\":{\"options\":\"هەڵبژاردەی لیستەی کلیکی دەستی ڕاست\"},\"toolbar\":{\"toolbarCollapse\":\"شاردنەوی هێڵی تووڵامراز\",\"toolbarExpand\":\"نیشاندانی هێڵی تووڵامراز\",\"toolbarGroups\":{\"document\":\"پەڕه\",\"clipboard\":\"بڕین/پووچکردنەوە\",\"editing\":\"چاکسازی\",\"forms\":\"داڕشتە\",\"basicstyles\":\"شێوازی بنچینەیی\",\"paragraph\":\"بڕگە\",\"links\":\"بەستەر\",\"insert\":\"خستنە ناو\",\"styles\":\"شێواز\",\"colors\":\"ڕەنگەکان\",\"tools\":\"ئامرازەکان\"},\"toolbars\":\"تووڵامرازی دەسکاریکەر\"},\"elementspath\":{\"eleLabel\":\"ڕێڕەوی توخمەکان\",\"eleTitle\":\"%1 توخم\"},\"format\":{\"label\":\"ڕازاندنەوە\",\"panelTitle\":\"بەشی ڕازاندنەوه\",\"tag_address\":\"ناونیشان\",\"tag_div\":\"(DIV)-ی ئاسایی\",\"tag_h1\":\"سەرنووسەی ١\",\"tag_h2\":\"سەرنووسەی ٢\",\"tag_h3\":\"سەرنووسەی ٣\",\"tag_h4\":\"سەرنووسەی ٤\",\"tag_h5\":\"سەرنووسەی ٥\",\"tag_h6\":\"سەرنووسەی ٦\",\"tag_p\":\"ئاسایی\",\"tag_pre\":\"شێوازکراو\"},\"horizontalrule\":{\"toolbar\":\"دانانی هێلی ئاسۆیی\"},\"image\":{\"alertUrl\":\"تکایه ناونیشانی بەستەری وێنه بنووسه\",\"alt\":\"جێگرەوەی دەق\",\"border\":\"پەراوێز\",\"btnUpload\":\"ناردنی بۆ ڕاژه\",\"button2Img\":\"تۆ دەتەوێت دوگمەی وێنەی دیاریکراو بگۆڕیت بۆ وێنەیەکی ئاسایی؟\",\"hSpace\":\"بۆشایی ئاسۆیی\",\"img2Button\":\"تۆ دەتەوێت وێنەی دیاریکراو بگۆڕیت بۆ دوگمەی وێنه؟\",\"infoTab\":\"زانیاری وێنه\",\"linkTab\":\"بەستەر\",\"lockRatio\":\"داخستنی ڕێژه\",\"menu\":\"خاسیەتی وێنه\",\"resetSize\":\"ڕێکخستنەوەی قەباره\",\"title\":\"خاسیەتی وێنه\",\"titleButton\":\"خاسیەتی دوگمەی وێنه\",\"upload\":\"بارکردن\",\"urlMissing\":\"سەرچاوەی بەستەری وێنه بزره\",\"vSpace\":\"بۆشایی ئەستونی\",\"validateBorder\":\"پەراوێز دەبێت بەتەواوی تەنها ژماره بێت.\",\"validateHSpace\":\"بۆشایی ئاسۆیی دەبێت بەتەواوی تەنها ژمارە بێت.\",\"validateVSpace\":\"بۆشایی ئەستونی دەبێت بەتەواوی تەنها ژماره بێت.\"},\"indent\":{\"indent\":\"زیادکردنی بۆشایی\",\"outdent\":\"کەمکردنەوەی بۆشایی\"},\"fakeobjects\":{\"anchor\":\"لەنگەر\",\"flash\":\"فلاش\",\"hiddenfield\":\"شاردنەوەی خانه\",\"iframe\":\"لەچوارچێوە\",\"unknown\":\"بەرکارێکی نەناسراو\"},\"link\":{\"acccessKey\":\"کلیلی دەستپێگەیشتن\",\"advanced\":\"پێشکەوتوو\",\"advisoryContentType\":\"جۆری ناوەڕۆکی ڕاویژکار\",\"advisoryTitle\":\"ڕاوێژکاری سەردێڕ\",\"anchor\":{\"toolbar\":\"دانان/چاکسازی لەنگەر\",\"menu\":\"چاکسازی لەنگەر\",\"title\":\"خاسیەتی لەنگەر\",\"name\":\"ناوی لەنگەر\",\"errorName\":\"تکایه ناوی لەنگەر بنووسه\",\"remove\":\"لابردنی لەنگەر\"},\"anchorId\":\"بەپێی ناسنامەی توخم\",\"anchorName\":\"بەپێی ناوی لەنگەر\",\"charset\":\"بەستەری سەرچاوەی نووسە\",\"cssClasses\":\"شێوازی چینی پەڕه\",\"emailAddress\":\"ناونیشانی ئیمەیل\",\"emailBody\":\"ناوەڕۆکی نامە\",\"emailSubject\":\"بابەتی نامە\",\"id\":\"ناسنامە\",\"info\":\"زانیاری بەستەر\",\"langCode\":\"هێمای زمان\",\"langDir\":\"ئاراستەی زمان\",\"langDirLTR\":\"چەپ بۆ ڕاست (LTR)\",\"langDirRTL\":\"ڕاست بۆ چەپ (RTL)\",\"menu\":\"چاکسازی بەستەر\",\"name\":\"ناو\",\"noAnchors\":\"(هیچ جۆرێکی لەنگەر ئامادە نیە لەم پەڕەیه)\",\"noEmail\":\"تکایە ناونیشانی ئیمەیل بنووسە\",\"noUrl\":\"تکایە ناونیشانی بەستەر بنووسە\",\"other\":\"<هیتر>\",\"popupDependent\":\"پێوەبەستراو (Netscape)\",\"popupFeatures\":\"خاسیەتی پەنجەرەی سەرهەڵدەر\",\"popupFullScreen\":\"پڕ بەپڕی شاشە (IE)\",\"popupLeft\":\"جێگای چەپ\",\"popupLocationBar\":\"هێڵی ناونیشانی بەستەر\",\"popupMenuBar\":\"هێڵی لیسته\",\"popupResizable\":\"توانای گۆڕینی قەباره\",\"popupScrollBars\":\"هێڵی هاتووچۆپێکردن\",\"popupStatusBar\":\"هێڵی دۆخ\",\"popupToolbar\":\"هێڵی تووڵامراز\",\"popupTop\":\"جێگای سەرەوە\",\"rel\":\"پەیوەندی\",\"selectAnchor\":\"هەڵبژاردنی لەنگەرێك\",\"styles\":\"شێواز\",\"tabIndex\":\"بازدەری تابی  ئیندێکس\",\"target\":\"ئامانج\",\"targetFrame\":\"<چووارچێوە>\",\"targetFrameName\":\"ناوی ئامانجی چووارچێوە\",\"targetPopup\":\"<پەنجەرەی سەرهەڵدەر>\",\"targetPopupName\":\"ناوی پەنجەرەی سەرهەڵدەر\",\"title\":\"بەستەر\",\"toAnchor\":\"بەستەر بۆ لەنگەر له دەق\",\"toEmail\":\"ئیمەیل\",\"toUrl\":\"ناونیشانی بەستەر\",\"toolbar\":\"دانان/ڕێکخستنی بەستەر\",\"type\":\"جۆری بەستەر\",\"unlink\":\"لابردنی بەستەر\",\"upload\":\"بارکردن\"},\"list\":{\"bulletedlist\":\"دانان/لابردنی خاڵی لیست\",\"numberedlist\":\"دانان/لابردنی ژمارەی لیست\"},\"magicline\":{\"title\":\"بڕگە لێرە دابنێ\"},\"maximize\":{\"maximize\":\"ئەوپەڕی گەورەیی\",\"minimize\":\"ئەوپەڕی بچووکی\"},\"pastetext\":{\"button\":\"لکاندنی وەك دەقی ڕوون\",\"title\":\"لکاندنی وەك دەقی ڕوون\"},\"pastefromword\":{\"confirmCleanup\":\"ئەم دەقەی بەتەمای بیلکێنی پێدەچێت له word هێنرابێت. دەتەوێت پاکی بکەیوه پێش ئەوەی بیلکێنی؟\",\"error\":\"هیچ ڕێگەیەك نەبوو لەلکاندنی دەقەکه بەهۆی هەڵەیەکی ناوەخۆیی\",\"title\":\"لکاندنی لەلایەن Word\",\"toolbar\":\"لکاندنی لەڕێی Word\"},\"removeformat\":{\"toolbar\":\"لابردنی داڕشتەکە\"},\"sourcearea\":{\"toolbar\":\"سەرچاوە\"},\"specialchar\":{\"options\":\"هەڵبژاردەی نووسەی تایبەتی\",\"title\":\"هەڵبژاردنی نووسەی تایبەتی\",\"toolbar\":\"دانانی نووسەی تایبەتی\"},\"scayt\":{\"about\":\"دهربارهی SCAYT\",\"aboutTab\":\"دهربارهی\",\"addWord\":\"زیادکردنی ووشه\",\"allCaps\":\"پشتگوێخستنی وشانهی پێکهاتووه لهپیتی گهوره\",\"dic_create\":\"درووستکردن\",\"dic_delete\":\"سڕینهوه\",\"dic_field_name\":\"ناوی فهرههنگ\",\"dic_info\":\"لهبنچینهدا فهرههنگی بهکارهێنهر کۆگاکردن کراوه له شهکرۆکه Cookie, ههرچۆنێك بێت شهکۆرکه سنووردار کراوه له قهباره کۆگاکردن.کاتێك فهرههنگی بهکارهێنهر گهیشته ئهم خاڵهی کهناتوانرێت زیاتر کۆگاکردن بکرێت له شهکرۆکه، ئهوسا فهرههنگهکه پێویسته کۆگابکرێت له ڕاژهکهی ئێمه. بۆ کۆگاکردنی زانیاری تایبهتی فهرههنگهکه له ڕاژهکهی ئێمه, پێویسته ناوێك ههڵبژێریت بۆ فهرههنگهکه. گهر تۆ فهرههنگێکی کۆگاکراوت ههیه, تکایه ناوی فهرههنگهکه بنووسه وه کلیکی دوگمهی گهڕاندنهوه بکه.\",\"dic_rename\":\"گۆڕینی ناو\",\"dic_restore\":\"گهڕاندنهوه\",\"dictionariesTab\":\"فهرههنگهکان\",\"disable\":\"ناچالاککردنی SCAYT\",\"emptyDic\":\"ناوی فهرههنگ نابێت خاڵی بێت.\",\"enable\":\"چالاککردنی SCAYT\",\"ignore\":\"پشتگوێخستن\",\"ignoreAll\":\"پشتگوێخستنی ههمووی\",\"ignoreDomainNames\":\"پشتگوێخستنی دۆمهین\",\"langs\":\"زمانهکان\",\"languagesTab\":\"زمانهکان\",\"mixedCase\":\"پشتگوێخستنی وشانهی پێکهاتووه لهپیتی گهورهو بچووك\",\"mixedWithDigits\":\"پشتگوێخستنی وشانهی پێکهاتووه لهژماره\",\"moreSuggestions\":\"پێشنیاری زیاتر\",\"opera_title\":\"پشتیوانی نهکراوه لهلایهن Opera\",\"options\":\"ههڵبژارده\",\"optionsTab\":\"ههڵبژارده\",\"title\":\"پشکنینی نووسه لهکاتی نووسین\",\"toggle\":\"گۆڕینی SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"شێواز\",\"panelTitle\":\"شێوازی ڕازاندنەوە\",\"panelTitle1\":\"شێوازی خشت\",\"panelTitle2\":\"شێوازی ناوهێڵ\",\"panelTitle3\":\"شێوازی بەرکار\"},\"table\":{\"border\":\"گەورەیی پەراوێز\",\"caption\":\"سەردێڕ\",\"cell\":{\"menu\":\"خانه\",\"insertBefore\":\"دانانی خانه لەپێش\",\"insertAfter\":\"دانانی خانه لەپاش\",\"deleteCell\":\"سڕینەوەی خانه\",\"merge\":\"تێکەڵکردنی خانە\",\"mergeRight\":\"تێکەڵکردنی لەگەڵ ڕاست\",\"mergeDown\":\"تێکەڵکردنی لەگەڵ خوارەوە\",\"splitHorizontal\":\"دابەشکردنی خانەی ئاسۆیی\",\"splitVertical\":\"دابەشکردنی خانەی ئەستونی\",\"title\":\"خاسیەتی خانه\",\"cellType\":\"جۆری خانه\",\"rowSpan\":\"ماوەی نێوان ڕیز\",\"colSpan\":\"بستی ئەستونی\",\"wordWrap\":\"پێچانەوەی وشە\",\"hAlign\":\"ڕیزکردنی ئاسۆیی\",\"vAlign\":\"ڕیزکردنی ئەستونی\",\"alignBaseline\":\"هێڵەبنەڕەت\",\"bgColor\":\"ڕەنگی پاشبنەما\",\"borderColor\":\"ڕەنگی پەراوێز\",\"data\":\"داتا\",\"header\":\"سەرپەڕه\",\"yes\":\"بەڵێ\",\"no\":\"نەخێر\",\"invalidWidth\":\"پانی خانه دەبێت بەتەواوی ژماره بێت.\",\"invalidHeight\":\"درێژی خانه بەتەواوی دەبێت ژمارە بێت.\",\"invalidRowSpan\":\"ماوەی نێوان ڕیز بەتەواوی دەبێت ژمارە بێت.\",\"invalidColSpan\":\"ماوەی نێوان ئەستونی بەتەواوی دەبێت ژمارە بێت.\",\"chooseColor\":\"هەڵبژێرە\"},\"cellPad\":\"بۆشایی ناوپۆش\",\"cellSpace\":\"بۆشایی خانه\",\"column\":{\"menu\":\"ئەستون\",\"insertBefore\":\"دانانی ئەستون لەپێش\",\"insertAfter\":\"دانانی ئەستوون لەپاش\",\"deleteColumn\":\"سڕینەوەی ئەستوون\"},\"columns\":\"ستوونەکان\",\"deleteTable\":\"سڕینەوەی خشتە\",\"headers\":\"سەرپەڕه\",\"headersBoth\":\"هەردووك\",\"headersColumn\":\"یەکەم ئەستوون\",\"headersNone\":\"هیچ\",\"headersRow\":\"یەکەم ڕیز\",\"invalidBorder\":\"ژمارەی پەراوێز دەبێت تەنها ژماره بێت.\",\"invalidCellPadding\":\"ناوپۆشی خانه دەبێت ژمارەکی درووست بێت.\",\"invalidCellSpacing\":\"بۆشایی خانه دەبێت ژمارەکی درووست بێت.\",\"invalidCols\":\"ژمارەی ئەستوونی دەبێت گەورەتر بێت لەژمارەی 0.\",\"invalidHeight\":\"درێژی خشته دهبێت تهنها ژماره بێت.\",\"invalidRows\":\"ژمارەی ڕیز دەبێت گەورەتر بێت لەژمارەی 0.\",\"invalidWidth\":\"پانی خشته دەبێت تەنها ژماره بێت.\",\"menu\":\"خاسیەتی خشتە\",\"row\":{\"menu\":\"ڕیز\",\"insertBefore\":\"دانانی ڕیز لەپێش\",\"insertAfter\":\"دانانی ڕیز لەپاش\",\"deleteRow\":\"سڕینەوەی ڕیز\"},\"rows\":\"ڕیز\",\"summary\":\"کورتە\",\"title\":\"خاسیەتی خشتە\",\"toolbar\":\"خشتە\",\"widthPc\":\"لەسەدا\",\"widthPx\":\"وێنەخاڵ - پیکسل\",\"widthUnit\":\"پانی یەکە\"},\"undo\":{\"redo\":\"هەڵگەڕاندنەوە\",\"undo\":\"پووچکردنەوە\"},\"wsc\":{\"btnIgnore\":\"پشتگوێ کردن\",\"btnIgnoreAll\":\"پشتگوێکردنی ههمووی\",\"btnReplace\":\"لهبریدانن\",\"btnReplaceAll\":\"لهبریدانانی ههمووی\",\"btnUndo\":\"پووچکردنهوه\",\"changeTo\":\"گۆڕینی بۆ\",\"errorLoading\":\"ههڵه لههێنانی داخوازینامهی خانهخۆێی ڕاژه: %s.\",\"ieSpellDownload\":\"پشکنینی ڕێنووس دانهمزراوه. دهتهوێت ئێستا دایبگریت?\",\"manyChanges\":\"پشکنینی ڕێنووس کۆتای هات: لهسهدا %1 ی وشهکان گۆڕدرا\",\"noChanges\":\"پشکنینی ڕێنووس کۆتای هات: هیچ وشهیهك نۆگۆڕدرا\",\"noMispell\":\"پشکنینی ڕێنووس کۆتای هات: هیچ ههڵهیهکی ڕێنووس نهدۆزراوه\",\"noSuggestions\":\"- هیچ پێشنیارێك -\",\"notAvailable\":\"ببووره، لهمکاتهدا ڕاژهکه لهبهردهستا نیه.\",\"notInDic\":\"لهفهرههنگ دانیه\",\"oneChange\":\"پشکنینی ڕێنووس کۆتای هات: یهك وشه گۆڕدرا\",\"progress\":\"پشکنینی ڕێنووس لهبهردهوامبوون دایه...\",\"title\":\"پشکنینی ڕێنووس\",\"toolbar\":\"پشکنینی ڕێنووس\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/lt.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['lt']={\"editor\":\"Pilnas redaktorius\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Spauskite ALT 0 dėl pagalbos\",\"browseServer\":\"Naršyti po serverį\",\"url\":\"URL\",\"protocol\":\"Protokolas\",\"upload\":\"Siųsti\",\"uploadSubmit\":\"Siųsti į serverį\",\"image\":\"Vaizdas\",\"flash\":\"Flash\",\"form\":\"Forma\",\"checkbox\":\"Žymimasis langelis\",\"radio\":\"Žymimoji akutė\",\"textField\":\"Teksto laukas\",\"textarea\":\"Teksto sritis\",\"hiddenField\":\"Nerodomas laukas\",\"button\":\"Mygtukas\",\"select\":\"Atrankos laukas\",\"imageButton\":\"Vaizdinis mygtukas\",\"notSet\":\"<nėra nustatyta>\",\"id\":\"Id\",\"name\":\"Vardas\",\"langDir\":\"Teksto kryptis\",\"langDirLtr\":\"Iš kairės į dešinę (LTR)\",\"langDirRtl\":\"Iš dešinės į kairę (RTL)\",\"langCode\":\"Kalbos kodas\",\"longDescr\":\"Ilgas aprašymas URL\",\"cssClass\":\"Stilių lentelės klasės\",\"advisoryTitle\":\"Konsultacinė antraštė\",\"cssStyle\":\"Stilius\",\"ok\":\"OK\",\"cancel\":\"Nutraukti\",\"close\":\"Uždaryti\",\"preview\":\"Peržiūrėti\",\"resize\":\"Pavilkite, kad pakeistumėte dydį\",\"generalTab\":\"Bendros savybės\",\"advancedTab\":\"Papildomas\",\"validateNumberFailed\":\"Ši reikšmė nėra skaičius.\",\"confirmNewPage\":\"Visas neišsaugotas turinys bus prarastas. Ar tikrai norite įkrauti naują puslapį?\",\"confirmCancel\":\"Kai kurie parametrai pasikeitė. Ar tikrai norite užverti langą?\",\"options\":\"Parametrai\",\"target\":\"Tikslinė nuoroda\",\"targetNew\":\"Naujas langas (_blank)\",\"targetTop\":\"Viršutinis langas (_top)\",\"targetSelf\":\"Esamas langas (_self)\",\"targetParent\":\"Paskutinis langas (_parent)\",\"langDirLTR\":\"Iš kairės į dešinę (LTR)\",\"langDirRTL\":\"Iš dešinės į kairę (RTL)\",\"styles\":\"Stilius\",\"cssClasses\":\"Stilių klasės\",\"width\":\"Plotis\",\"height\":\"Aukštis\",\"align\":\"Lygiuoti\",\"alignLeft\":\"Kairę\",\"alignRight\":\"Dešinę\",\"alignCenter\":\"Centrą\",\"alignTop\":\"Viršūnę\",\"alignMiddle\":\"Vidurį\",\"alignBottom\":\"Apačią\",\"invalidValue\":\"Neteisinga reikšmė.\",\"invalidHeight\":\"Aukštis turi būti nurodytas skaičiais.\",\"invalidWidth\":\"Plotis turi būti nurodytas skaičiais.\",\"invalidCssLength\":\"Reikšmė nurodyta \\\"%1\\\" laukui, turi būti teigiamas skaičius su arba be tinkamo CSS matavimo vieneto (px, %, in, cm, mm, em, ex, pt arba pc).\",\"invalidHtmlLength\":\"Reikšmė nurodyta \\\"%1\\\" laukui, turi būti teigiamas skaičius su arba be tinkamo HTML matavimo vieneto (px arba %).\",\"invalidInlineStyle\":\"Reikšmė nurodyta vidiniame stiliuje turi būti sudaryta iš vieno šių reikšmių \\\"vardas : reikšmė\\\", atskirta kabliataškiais.\",\"cssLengthTooltip\":\"Įveskite reikšmę pikseliais arba skaičiais su tinkamu CSS vienetu (px, %, in, cm, mm, em, ex, pt arba pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, netinkamas</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Visos teiss saugomos.\",\"dlgTitle\":\"Apie CKEditor\",\"help\":\"Patikrinkite $1 dėl pagalbos.\",\"moreInfo\":\"Dėl licencijavimo apsilankykite mūsų svetainėje:\",\"title\":\"Apie CKEditor\",\"userGuide\":\"CKEditor Vartotojo Gidas\"},\"basicstyles\":{\"bold\":\"Pusjuodis\",\"italic\":\"Kursyvas\",\"strike\":\"Perbrauktas\",\"subscript\":\"Apatinis indeksas\",\"superscript\":\"Viršutinis indeksas\",\"underline\":\"Pabrauktas\"},\"blockquote\":{\"toolbar\":\"Citata\"},\"clipboard\":{\"copy\":\"Kopijuoti\",\"copyError\":\"Jūsų naršyklės saugumo nustatymai neleidžia redaktoriui automatiškai įvykdyti kopijavimo operacijų. Tam prašome naudoti klaviatūrą (Ctrl/Cmd+C).\",\"cut\":\"Iškirpti\",\"cutError\":\"Jūsų naršyklės saugumo nustatymai neleidžia redaktoriui automatiškai įvykdyti iškirpimo operacijų. Tam prašome naudoti klaviatūrą (Ctrl/Cmd+X).\",\"paste\":\"Įdėti\",\"pasteArea\":\"Įkelti dalį\",\"pasteMsg\":\"Žemiau esančiame įvedimo lauke įdėkite tekstą, naudodami klaviatūrą (<STRONG>Ctrl/Cmd+V</STRONG>) ir paspauskite mygtuką <STRONG>OK</STRONG>.\",\"securityMsg\":\"Dėl jūsų naršyklės saugumo nustatymų, redaktorius negali tiesiogiai pasiekti laikinosios atminties. Jums reikia nukopijuoti dar kartą į šį langą.\",\"title\":\"Įdėti\"},\"contextmenu\":{\"options\":\"Kontekstinio meniu parametrai\"},\"toolbar\":{\"toolbarCollapse\":\"Apjungti įrankių juostą\",\"toolbarExpand\":\"Išplėsti įrankių juostą\",\"toolbarGroups\":{\"document\":\"Dokumentas\",\"clipboard\":\"Atmintinė/Atgal\",\"editing\":\"Redagavimas\",\"forms\":\"Formos\",\"basicstyles\":\"Pagrindiniai stiliai\",\"paragraph\":\"Paragrafas\",\"links\":\"Nuorodos\",\"insert\":\"Įterpti\",\"styles\":\"Stiliai\",\"colors\":\"Spalvos\",\"tools\":\"Įrankiai\"},\"toolbars\":\"Redaktoriaus įrankiai\"},\"elementspath\":{\"eleLabel\":\"Elemento kelias\",\"eleTitle\":\"%1 elementas\"},\"format\":{\"label\":\"Šrifto formatas\",\"panelTitle\":\"Šrifto formatas\",\"tag_address\":\"Kreipinio\",\"tag_div\":\"Normalus (DIV)\",\"tag_h1\":\"Antraštinis 1\",\"tag_h2\":\"Antraštinis 2\",\"tag_h3\":\"Antraštinis 3\",\"tag_h4\":\"Antraštinis 4\",\"tag_h5\":\"Antraštinis 5\",\"tag_h6\":\"Antraštinis 6\",\"tag_p\":\"Normalus\",\"tag_pre\":\"Formuotas\"},\"horizontalrule\":{\"toolbar\":\"Įterpti horizontalią liniją\"},\"image\":{\"alertUrl\":\"Prašome įvesti vaizdo URL\",\"alt\":\"Alternatyvus Tekstas\",\"border\":\"Rėmelis\",\"btnUpload\":\"Siųsti į serverį\",\"button2Img\":\"Ar norite mygtuką paversti paprastu paveiksliuku?\",\"hSpace\":\"Hor.Erdvė\",\"img2Button\":\"Ar norite paveiksliuką paversti mygtuku?\",\"infoTab\":\"Vaizdo informacija\",\"linkTab\":\"Nuoroda\",\"lockRatio\":\"Išlaikyti proporciją\",\"menu\":\"Vaizdo savybės\",\"resetSize\":\"Atstatyti dydį\",\"title\":\"Vaizdo savybės\",\"titleButton\":\"Vaizdinio mygtuko savybės\",\"upload\":\"Nusiųsti\",\"urlMissing\":\"Paveiksliuko nuorodos nėra.\",\"vSpace\":\"Vert.Erdvė\",\"validateBorder\":\"Reikšmė turi būti sveikas skaičius.\",\"validateHSpace\":\"Reikšmė turi būti sveikas skaičius.\",\"validateVSpace\":\"Reikšmė turi būti sveikas skaičius.\"},\"indent\":{\"indent\":\"Padidinti įtrauką\",\"outdent\":\"Sumažinti įtrauką\"},\"fakeobjects\":{\"anchor\":\"Žymė\",\"flash\":\"Flash animacija\",\"hiddenfield\":\"Paslėptas laukas\",\"iframe\":\"IFrame\",\"unknown\":\"Nežinomas objektas\"},\"link\":{\"acccessKey\":\"Prieigos raktas\",\"advanced\":\"Papildomas\",\"advisoryContentType\":\"Konsultacinio turinio tipas\",\"advisoryTitle\":\"Konsultacinė antraštė\",\"anchor\":{\"toolbar\":\"Įterpti/modifikuoti žymę\",\"menu\":\"Žymės savybės\",\"title\":\"Žymės savybės\",\"name\":\"Žymės vardas\",\"errorName\":\"Prašome įvesti žymės vardą\",\"remove\":\"Pašalinti žymę\"},\"anchorId\":\"Pagal žymės Id\",\"anchorName\":\"Pagal žymės vardą\",\"charset\":\"Susietų išteklių simbolių lentelė\",\"cssClasses\":\"Stilių lentelės klasės\",\"emailAddress\":\"El.pašto adresas\",\"emailBody\":\"Žinutės turinys\",\"emailSubject\":\"Žinutės tema\",\"id\":\"Id\",\"info\":\"Nuorodos informacija\",\"langCode\":\"Teksto kryptis\",\"langDir\":\"Teksto kryptis\",\"langDirLTR\":\"Iš kairės į dešinę (LTR)\",\"langDirRTL\":\"Iš dešinės į kairę (RTL)\",\"menu\":\"Taisyti nuorodą\",\"name\":\"Vardas\",\"noAnchors\":\"(Šiame dokumente žymių nėra)\",\"noEmail\":\"Prašome įvesti el.pašto adresą\",\"noUrl\":\"Prašome įvesti nuorodos URL\",\"other\":\"<kitas>\",\"popupDependent\":\"Priklausomas (Netscape)\",\"popupFeatures\":\"Išskleidžiamo lango savybės\",\"popupFullScreen\":\"Visas ekranas (IE)\",\"popupLeft\":\"Kairė pozicija\",\"popupLocationBar\":\"Adreso juosta\",\"popupMenuBar\":\"Meniu juosta\",\"popupResizable\":\"Kintamas dydis\",\"popupScrollBars\":\"Slinkties juostos\",\"popupStatusBar\":\"Būsenos juosta\",\"popupToolbar\":\"Mygtukų juosta\",\"popupTop\":\"Viršutinė pozicija\",\"rel\":\"Sąsajos\",\"selectAnchor\":\"Pasirinkite žymę\",\"styles\":\"Stilius\",\"tabIndex\":\"Tabuliavimo indeksas\",\"target\":\"Paskirties vieta\",\"targetFrame\":\"<kadras>\",\"targetFrameName\":\"Paskirties kadro vardas\",\"targetPopup\":\"<išskleidžiamas langas>\",\"targetPopupName\":\"Paskirties lango vardas\",\"title\":\"Nuoroda\",\"toAnchor\":\"Žymė šiame puslapyje\",\"toEmail\":\"El.paštas\",\"toUrl\":\"Nuoroda\",\"toolbar\":\"Įterpti/taisyti nuorodą\",\"type\":\"Nuorodos tipas\",\"unlink\":\"Panaikinti nuorodą\",\"upload\":\"Siųsti\"},\"list\":{\"bulletedlist\":\"Suženklintas sąrašas\",\"numberedlist\":\"Numeruotas sąrašas\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Išdidinti\",\"minimize\":\"Sumažinti\"},\"pastetext\":{\"button\":\"Įdėti kaip gryną tekstą\",\"title\":\"Įdėti kaip gryną tekstą\"},\"pastefromword\":{\"confirmCleanup\":\"Tekstas, kurį įkeliate yra kopijuojamas iš Word. Ar norite jį išvalyti prieš įkeliant?\",\"error\":\"Dėl vidinių sutrikimų, nepavyko išvalyti įkeliamo teksto\",\"title\":\"Įdėti iš Word\",\"toolbar\":\"Įdėti iš Word\"},\"removeformat\":{\"toolbar\":\"Panaikinti formatą\"},\"sourcearea\":{\"toolbar\":\"Šaltinis\"},\"specialchar\":{\"options\":\"Specialaus simbolio nustatymai\",\"title\":\"Pasirinkite specialų simbolį\",\"toolbar\":\"Įterpti specialų simbolį\"},\"scayt\":{\"about\":\"Apie SCAYT\",\"aboutTab\":\"Apie\",\"addWord\":\"Pridėti žodį\",\"allCaps\":\"Ignoruoti visas didžiąsias raides\",\"dic_create\":\"Sukurti\",\"dic_delete\":\"Ištrinti\",\"dic_field_name\":\"Žodyno pavadinimas\",\"dic_info\":\"Paprastai žodynas yra saugojamas sausainėliuose (cookies), kurių dydis, bet kokiu atveju, yra apribotas. Esant sausainėlių apimties pervišiui, viskas bus saugoma serveryje. Jei norite iš kart viską saugoti serveryje, turite sugalvoti žodynui pavadinimą. Jei jau turite žodyną, įrašykite pavadinimą ir nuspauskite Atstatyti mygtuką.\",\"dic_rename\":\"Pervadinti\",\"dic_restore\":\"Atstatyti\",\"dictionariesTab\":\"Žodynai\",\"disable\":\"Išjungti SCAYT\",\"emptyDic\":\"Žodyno vardas neturėtų būti tuščias.\",\"enable\":\"Įjungti SCAYT\",\"ignore\":\"Ignoruoti\",\"ignoreAll\":\"Ignoruoti viską\",\"ignoreDomainNames\":\"Ignoruoti domenų vardus\",\"langs\":\"Kalbos\",\"languagesTab\":\"Kalbos\",\"mixedCase\":\"Ignoruoti maišyto dydžio raides\",\"mixedWithDigits\":\"Ignoruoti raides su skaičiais\",\"moreSuggestions\":\"Daugiau patarimų\",\"opera_title\":\"Nepalaikoma naršyklėje Opera\",\"options\":\"Parametrai\",\"optionsTab\":\"Parametrai\",\"title\":\"Tikrinti klaidas kai rašoma\",\"toggle\":\"Perjungti SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stilius\",\"panelTitle\":\"Stilių formatavimas\",\"panelTitle1\":\"Blokų stiliai\",\"panelTitle2\":\"Vidiniai stiliai\",\"panelTitle3\":\"Objektų stiliai\"},\"table\":{\"border\":\"Rėmelio dydis\",\"caption\":\"Antraštė\",\"cell\":{\"menu\":\"Langelis\",\"insertBefore\":\"Įterpti langelį prieš\",\"insertAfter\":\"Įterpti langelį po\",\"deleteCell\":\"Šalinti langelius\",\"merge\":\"Sujungti langelius\",\"mergeRight\":\"Sujungti su dešine\",\"mergeDown\":\"Sujungti su apačia\",\"splitHorizontal\":\"Skaidyti langelį horizontaliai\",\"splitVertical\":\"Skaidyti langelį vertikaliai\",\"title\":\"Cell nustatymai\",\"cellType\":\"Cell rūšis\",\"rowSpan\":\"Eilučių Span\",\"colSpan\":\"Stulpelių Span\",\"wordWrap\":\"Sutraukti raides\",\"hAlign\":\"Horizontalus lygiavimas\",\"vAlign\":\"Vertikalus lygiavimas\",\"alignBaseline\":\"Apatinė linija\",\"bgColor\":\"Fono spalva\",\"borderColor\":\"Rėmelio spalva\",\"data\":\"Data\",\"header\":\"Antraštė\",\"yes\":\"Taip\",\"no\":\"Ne\",\"invalidWidth\":\"Reikšmė turi būti skaičius.\",\"invalidHeight\":\"Reikšmė turi būti skaičius.\",\"invalidRowSpan\":\"Reikšmė turi būti skaičius.\",\"invalidColSpan\":\"Reikšmė turi būti skaičius.\",\"chooseColor\":\"Pasirinkite\"},\"cellPad\":\"Tarpas nuo langelio rėmo iki teksto\",\"cellSpace\":\"Tarpas tarp langelių\",\"column\":{\"menu\":\"Stulpelis\",\"insertBefore\":\"Įterpti stulpelį prieš\",\"insertAfter\":\"Įterpti stulpelį po\",\"deleteColumn\":\"Šalinti stulpelius\"},\"columns\":\"Stulpeliai\",\"deleteTable\":\"Šalinti lentelę\",\"headers\":\"Antraštės\",\"headersBoth\":\"Abu\",\"headersColumn\":\"Pirmas stulpelis\",\"headersNone\":\"Nėra\",\"headersRow\":\"Pirma eilutė\",\"invalidBorder\":\"Reikšmė turi būti nurodyta skaičiumi.\",\"invalidCellPadding\":\"Reikšmė turi būti nurodyta skaičiumi.\",\"invalidCellSpacing\":\"Reikšmė turi būti nurodyta skaičiumi.\",\"invalidCols\":\"Skaičius turi būti didesnis nei 0.\",\"invalidHeight\":\"Reikšmė turi būti nurodyta skaičiumi.\",\"invalidRows\":\"Skaičius turi būti didesnis nei 0.\",\"invalidWidth\":\"Reikšmė turi būti nurodyta skaičiumi.\",\"menu\":\"Lentelės savybės\",\"row\":{\"menu\":\"Eilutė\",\"insertBefore\":\"Įterpti eilutę prieš\",\"insertAfter\":\"Įterpti eilutę po\",\"deleteRow\":\"Šalinti eilutes\"},\"rows\":\"Eilutės\",\"summary\":\"Santrauka\",\"title\":\"Lentelės savybės\",\"toolbar\":\"Lentelė\",\"widthPc\":\"procentais\",\"widthPx\":\"taškais\",\"widthUnit\":\"pločio vienetas\"},\"undo\":{\"redo\":\"Atstatyti\",\"undo\":\"Atšaukti\"},\"wsc\":{\"btnIgnore\":\"Ignoruoti\",\"btnIgnoreAll\":\"Ignoruoti visus\",\"btnReplace\":\"Pakeisti\",\"btnReplaceAll\":\"Pakeisti visus\",\"btnUndo\":\"Atšaukti\",\"changeTo\":\"Pakeisti į\",\"errorLoading\":\"Klaida įkraunant servisą: %s.\",\"ieSpellDownload\":\"Rašybos tikrinimas neinstaliuotas. Ar Jūs norite jį dabar atsisiųsti?\",\"manyChanges\":\"Rašybos tikrinimas baigtas: Pakeista %1 žodžių\",\"noChanges\":\"Rašybos tikrinimas baigtas: Nėra pakeistų žodžių\",\"noMispell\":\"Rašybos tikrinimas baigtas: Nerasta rašybos klaidų\",\"noSuggestions\":\"- Nėra pasiūlymų -\",\"notAvailable\":\"Atleiskite, šiuo metu servisas neprieinamas.\",\"notInDic\":\"Žodyne nerastas\",\"oneChange\":\"Rašybos tikrinimas baigtas: Vienas žodis pakeistas\",\"progress\":\"Vyksta rašybos tikrinimas...\",\"title\":\"Tikrinti klaidas\",\"toolbar\":\"Rašybos tikrinimas\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/lv.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['lv']={\"editor\":\"Bagātinātā teksta redaktors\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Palīdzībai, nospiediet ALT 0 \",\"browseServer\":\"Skatīt servera saturu\",\"url\":\"URL\",\"protocol\":\"Protokols\",\"upload\":\"Augšupielādēt\",\"uploadSubmit\":\"Nosūtīt serverim\",\"image\":\"Attēls\",\"flash\":\"Flash\",\"form\":\"Forma\",\"checkbox\":\"Atzīmēšanas kastīte\",\"radio\":\"Izvēles poga\",\"textField\":\"Teksta rinda\",\"textarea\":\"Teksta laukums\",\"hiddenField\":\"Paslēpta teksta rinda\",\"button\":\"Poga\",\"select\":\"Iezīmēšanas lauks\",\"imageButton\":\"Attēlpoga\",\"notSet\":\"<nav iestatīts>\",\"id\":\"Id\",\"name\":\"Nosaukums\",\"langDir\":\"Valodas lasīšanas virziens\",\"langDirLtr\":\"No kreisās uz labo (LTR)\",\"langDirRtl\":\"No labās uz kreiso (RTL)\",\"langCode\":\"Valodas kods\",\"longDescr\":\"Gara apraksta Hipersaite\",\"cssClass\":\"Stilu saraksta klases\",\"advisoryTitle\":\"Konsultatīvs virsraksts\",\"cssStyle\":\"Stils\",\"ok\":\"Darīts!\",\"cancel\":\"Atcelt\",\"close\":\"Aizvērt\",\"preview\":\"Priekšskatījums\",\"resize\":\"Mērogot\",\"generalTab\":\"Vispārīgi\",\"advancedTab\":\"Izvērstais\",\"validateNumberFailed\":\"Šī vērtība nav skaitlis\",\"confirmNewPage\":\"Jebkuras nesaglabātās izmaiņas tiks zaudētas. Vai tiešām vēlaties atvērt jaunu lapu?\",\"confirmCancel\":\"Daži no uzstādījumiem ir mainīti. Vai tiešām vēlaties aizvērt šo dialogu?\",\"options\":\"Uzstādījumi\",\"target\":\"Mērķis\",\"targetNew\":\"Jauns logs (_blank)\",\"targetTop\":\"Virsējais logs (_top)\",\"targetSelf\":\"Tas pats logs (_self)\",\"targetParent\":\"Avota logs (_parent)\",\"langDirLTR\":\"Kreisais uz Labo (LTR)\",\"langDirRTL\":\"Labais uz Kreiso (RTL)\",\"styles\":\"Stils\",\"cssClasses\":\"Stilu klases\",\"width\":\"Platums\",\"height\":\"Augstums\",\"align\":\"Nolīdzināt\",\"alignLeft\":\"Pa kreisi\",\"alignRight\":\"Pa labi\",\"alignCenter\":\"Centrēti\",\"alignTop\":\"Augšā\",\"alignMiddle\":\"Vertikāli centrēts\",\"alignBottom\":\"Apakšā\",\"invalidValue\":\"Nekorekta vērtība\",\"invalidHeight\":\"Augstumam jābūt skaitlim.\",\"invalidWidth\":\"Platumam jābūt skaitlim\",\"invalidCssLength\":\"Laukam \\\"%1\\\" norādītajai vērtībai jābūt pozitīvam skaitlim ar vai bez korektām CSS mērvienībām (px, %, in, cm, mm, em, ex, pt, vai pc).\",\"invalidHtmlLength\":\"Laukam \\\"%1\\\" norādītajai vērtībai jābūt pozitīvam skaitlim ar vai bez korektām HTML mērvienībām (px vai %).\",\"invalidInlineStyle\":\"Iekļautajā stilā norādītajai vērtībai jāsastāv no viena vai vairākiem pāriem pēc forma'ta \\\"nosaukums: vērtība\\\", atdalītiem ar semikolu.\",\"cssLengthTooltip\":\"Ievadiet vērtību pikseļos vai skaitli ar derīgu CSS mērvienību (px, %, in, cm, mm, em, ex, pt, vai pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, nav pieejams</span>\"},\"about\":{\"copy\":\"Kopēšanas tiesības &copy; $1. Visas tiesības rezervētas.\",\"dlgTitle\":\"Par CKEditor\",\"help\":\"Pārbaudiet $1 palīdzībai.\",\"moreInfo\":\"Informācijai par licenzēšanu apmeklējiet mūsu mājas lapu:\",\"title\":\"Par CKEditor\",\"userGuide\":\"CKEditor Lietotāja pamācība\"},\"basicstyles\":{\"bold\":\"Treknināts\",\"italic\":\"Kursīvs\",\"strike\":\"Pārsvītrots\",\"subscript\":\"Apakšrakstā\",\"superscript\":\"Augšrakstā\",\"underline\":\"Pasvītrots\"},\"blockquote\":{\"toolbar\":\"Bloka citāts\"},\"clipboard\":{\"copy\":\"Kopēt\",\"copyError\":\"Jūsu pārlūkprogrammas drošības iestatījumi nepieļauj redaktoram automātiski veikt kopēšanas darbību.  Lūdzu, izmantojiet (Ctrl/Cmd+C), lai veiktu šo darbību.\",\"cut\":\"Izgriezt\",\"cutError\":\"Jūsu pārlūkprogrammas drošības iestatījumi nepieļauj redaktoram automātiski veikt izgriezšanas darbību.  Lūdzu, izmantojiet (Ctrl/Cmd+X), lai veiktu šo darbību.\",\"paste\":\"Ielīmēt\",\"pasteArea\":\"Ielīmēšanas zona\",\"pasteMsg\":\"Lūdzu, ievietojiet tekstu šajā laukumā, izmantojot klaviatūru (<STRONG>Ctrl/Cmd+V</STRONG>) un apstipriniet ar <STRONG>Darīts!</STRONG>.\",\"securityMsg\":\"Jūsu pārlūka drošības uzstādījumu dēļ, nav iespējams tieši piekļūt jūsu starpliktuvei. Jums jāielīmē atkārtoti šajā logā.\",\"title\":\"Ievietot\"},\"contextmenu\":{\"options\":\"Uznirstošās izvēlnes uzstādījumi\"},\"toolbar\":{\"toolbarCollapse\":\"Aizvērt rīkjoslu\",\"toolbarExpand\":\"Atvērt rīkjoslu\",\"toolbarGroups\":{\"document\":\"Dokuments\",\"clipboard\":\"Starpliktuve/Atcelt\",\"editing\":\"Labošana\",\"forms\":\"Formas\",\"basicstyles\":\"Pamata stili\",\"paragraph\":\"Paragrāfs\",\"links\":\"Saites\",\"insert\":\"Ievietot\",\"styles\":\"Stili\",\"colors\":\"Krāsas\",\"tools\":\"Rīki\"},\"toolbars\":\"Redaktora rīkjoslas\"},\"elementspath\":{\"eleLabel\":\"Elementa ceļš\",\"eleTitle\":\"%1 elements\"},\"format\":{\"label\":\"Formāts\",\"panelTitle\":\"Formāts\",\"tag_address\":\"Adrese\",\"tag_div\":\"Rindkopa (DIV)\",\"tag_h1\":\"Virsraksts 1\",\"tag_h2\":\"Virsraksts 2\",\"tag_h3\":\"Virsraksts 3\",\"tag_h4\":\"Virsraksts 4\",\"tag_h5\":\"Virsraksts 5\",\"tag_h6\":\"Virsraksts 6\",\"tag_p\":\"Normāls teksts\",\"tag_pre\":\"Formatēts teksts\"},\"horizontalrule\":{\"toolbar\":\"Ievietot horizontālu Atdalītājsvītru\"},\"image\":{\"alertUrl\":\"Lūdzu norādīt attēla hipersaiti\",\"alt\":\"Alternatīvais teksts\",\"border\":\"Rāmis\",\"btnUpload\":\"Nosūtīt serverim\",\"button2Img\":\"Vai vēlaties pārveidot izvēlēto attēla pogu uz attēla?\",\"hSpace\":\"Horizontālā telpa\",\"img2Button\":\"Vai vēlaties pārveidot izvēlēto attēlu uz attēla pogas?\",\"infoTab\":\"Informācija par attēlu\",\"linkTab\":\"Hipersaite\",\"lockRatio\":\"Nemainīga Augstuma/Platuma attiecība\",\"menu\":\"Attēla īpašības\",\"resetSize\":\"Atjaunot sākotnējo izmēru\",\"title\":\"Attēla īpašības\",\"titleButton\":\"Attēlpogas īpašības\",\"upload\":\"Augšupielādēt\",\"urlMissing\":\"Trūkst attēla atrašanās adrese.\",\"vSpace\":\"Vertikālā telpa\",\"validateBorder\":\"Apmalei jābūt veselam skaitlim\",\"validateHSpace\":\"HSpace jābūt veselam skaitlim\",\"validateVSpace\":\"VSpace jābūt veselam skaitlim\"},\"indent\":{\"indent\":\"Palielināt atkāpi\",\"outdent\":\"Samazināt atkāpi\"},\"fakeobjects\":{\"anchor\":\"Iezīme\",\"flash\":\"Flash animācija\",\"hiddenfield\":\"Slēpts lauks\",\"iframe\":\"Iframe\",\"unknown\":\"Nezināms objekts\"},\"link\":{\"acccessKey\":\"Pieejas taustiņš\",\"advanced\":\"Izvērstais\",\"advisoryContentType\":\"Konsultatīvs satura tips\",\"advisoryTitle\":\"Konsultatīvs virsraksts\",\"anchor\":{\"toolbar\":\"Ievietot/Labot iezīmi\",\"menu\":\"Labot iezīmi\",\"title\":\"Iezīmes uzstādījumi\",\"name\":\"Iezīmes nosaukums\",\"errorName\":\"Lūdzu norādiet iezīmes nosaukumu\",\"remove\":\"Noņemt iezīmi\"},\"anchorId\":\"Pēc elementa ID\",\"anchorName\":\"Pēc iezīmes nosaukuma\",\"charset\":\"Pievienotā resursa kodējums\",\"cssClasses\":\"Stilu saraksta klases\",\"emailAddress\":\"E-pasta adrese\",\"emailBody\":\"Ziņas saturs\",\"emailSubject\":\"Ziņas tēma\",\"id\":\"ID\",\"info\":\"Hipersaites informācija\",\"langCode\":\"Valodas kods\",\"langDir\":\"Valodas lasīšanas virziens\",\"langDirLTR\":\"No kreisās uz labo (LTR)\",\"langDirRTL\":\"No labās uz kreiso (RTL)\",\"menu\":\"Labot hipersaiti\",\"name\":\"Nosaukums\",\"noAnchors\":\"(Šajā dokumentā nav iezīmju)\",\"noEmail\":\"Lūdzu norādi e-pasta adresi\",\"noUrl\":\"Lūdzu norādi hipersaiti\",\"other\":\"<cits>\",\"popupDependent\":\"Atkarīgs (Netscape)\",\"popupFeatures\":\"Uznirstošā loga nosaukums īpašības\",\"popupFullScreen\":\"Pilnā ekrānā (IE)\",\"popupLeft\":\"Kreisā koordināte\",\"popupLocationBar\":\"Atrašanās vietas josla\",\"popupMenuBar\":\"Izvēlnes josla\",\"popupResizable\":\"Mērogojams\",\"popupScrollBars\":\"Ritjoslas\",\"popupStatusBar\":\"Statusa josla\",\"popupToolbar\":\"Rīku josla\",\"popupTop\":\"Augšējā koordināte\",\"rel\":\"Relācija\",\"selectAnchor\":\"Izvēlēties iezīmi\",\"styles\":\"Stils\",\"tabIndex\":\"Ciļņu indekss\",\"target\":\"Mērķis\",\"targetFrame\":\"<ietvars>\",\"targetFrameName\":\"Mērķa ietvara nosaukums\",\"targetPopup\":\"<uznirstošā logā>\",\"targetPopupName\":\"Uznirstošā loga nosaukums\",\"title\":\"Hipersaite\",\"toAnchor\":\"Iezīme šajā lapā\",\"toEmail\":\"E-pasts\",\"toUrl\":\"Adrese\",\"toolbar\":\"Ievietot/Labot hipersaiti\",\"type\":\"Hipersaites tips\",\"unlink\":\"Noņemt hipersaiti\",\"upload\":\"Augšupielādēt\"},\"list\":{\"bulletedlist\":\"Pievienot/Noņemt vienkāršu sarakstu\",\"numberedlist\":\"Numurēts saraksts\"},\"magicline\":{\"title\":\"Ievietot šeit rindkopu\"},\"maximize\":{\"maximize\":\"Maksimizēt\",\"minimize\":\"Minimizēt\"},\"pastetext\":{\"button\":\"Ievietot kā vienkāršu tekstu\",\"title\":\"Ievietot kā vienkāršu tekstu\"},\"pastefromword\":{\"confirmCleanup\":\"Teksts, kuru vēlaties ielīmēt, izskatās ir nokopēts no Word. Vai vēlaties to iztīrīt pirms ielīmēšanas?\",\"error\":\"Iekšējas kļūdas dēļ, neizdevās iztīrīt ielīmētos datus.\",\"title\":\"Ievietot no Worda\",\"toolbar\":\"Ievietot no Worda\"},\"removeformat\":{\"toolbar\":\"Noņemt stilus\"},\"sourcearea\":{\"toolbar\":\"HTML kods\"},\"specialchar\":{\"options\":\"Speciālo simbolu uzstādījumi\",\"title\":\"Ievietot īpašu simbolu\",\"toolbar\":\"Ievietot speciālo simbolu\"},\"scayt\":{\"about\":\"Par SCAYT\",\"aboutTab\":\"Par\",\"addWord\":\"Pievienot vārdu\",\"allCaps\":\"Ignorēt vārdus ar lielajiem burtiem\",\"dic_create\":\"Izveidot\",\"dic_delete\":\"Dzēst\",\"dic_field_name\":\"Vārdnīcas nosaukums\",\"dic_info\":\"Sākumā lietotāja vārdnīca tiek glabāta Cookie. Diemžēl, Cookie ir ierobežots izmērs. Kad vārdnīca sasniegs izmēru, ka to vairs nevar glabāt Cookie, tā tiks noglabāta uz servera. Lai saglabātu personīgo vārdnīcu uz jūsu servera, jums jānorāda tās nosaukums. Ja jūs jau esiet noglabājuši vārdnīcu, lūdzu ierakstiet tās nosaukum un nospiediet Atjaunot pogu.\",\"dic_rename\":\"Pārsaukt\",\"dic_restore\":\"Atjaunot\",\"dictionariesTab\":\"Vārdnīcas\",\"disable\":\"Atslēgt SCAYT\",\"emptyDic\":\"Vārdnīcas nosaukums nevar būt tukšs.\",\"enable\":\"Ieslēgt SCAYT\",\"ignore\":\"Ignorēt\",\"ignoreAll\":\"Ignorēt visu\",\"ignoreDomainNames\":\"Ignorēt domēnu nosaukumus\",\"langs\":\"Valodas\",\"languagesTab\":\"Valodas\",\"mixedCase\":\"Ignorēt vārdus ar jauktu reģistru burtiem\",\"mixedWithDigits\":\"Ignorēt vārdus ar skaitļiem\",\"moreSuggestions\":\"Vairāk ieteikumi\",\"opera_title\":\"Opera neatbalsta\",\"options\":\"Uzstādījumi\",\"optionsTab\":\"Uzstādījumi\",\"title\":\"Pārbaudīt gramatiku rakstot\",\"toggle\":\"Pārslēgt SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stils\",\"panelTitle\":\"Formatēšanas stili\",\"panelTitle1\":\"Bloka stili\",\"panelTitle2\":\"iekļautie stili\",\"panelTitle3\":\"Objekta stili\"},\"table\":{\"border\":\"Rāmja izmērs\",\"caption\":\"Leģenda\",\"cell\":{\"menu\":\"Šūna\",\"insertBefore\":\"Pievienot šūnu pirms\",\"insertAfter\":\"Pievienot šūnu pēc\",\"deleteCell\":\"Dzēst rūtiņas\",\"merge\":\"Apvienot rūtiņas\",\"mergeRight\":\"Apvieno pa labi\",\"mergeDown\":\"Apvienot uz leju\",\"splitHorizontal\":\"Sadalīt šūnu horizontāli\",\"splitVertical\":\"Sadalīt šūnu vertikāli\",\"title\":\"Šūnas uzstādījumi\",\"cellType\":\"Šūnas tips\",\"rowSpan\":\"Apvienotas rindas\",\"colSpan\":\"Apvienotas kolonas\",\"wordWrap\":\"Vārdu pārnese\",\"hAlign\":\"Horizontālais novietojums\",\"vAlign\":\"Vertikālais novietojums\",\"alignBaseline\":\"Pamatrinda\",\"bgColor\":\"Fona krāsa\",\"borderColor\":\"Rāmja krāsa\",\"data\":\"Dati\",\"header\":\"Virsraksts\",\"yes\":\"Jā\",\"no\":\"Nē\",\"invalidWidth\":\"Šūnas platumam jābūt skaitlim\",\"invalidHeight\":\"Šūnas augstumam jābūt skaitlim\",\"invalidRowSpan\":\"Apvienojamo rindu skaitam jābūt veselam skaitlim\",\"invalidColSpan\":\"Apvienojamo kolonu skaitam jābūt veselam skaitlim\",\"chooseColor\":\"Izvēlēties\"},\"cellPad\":\"Rūtiņu nobīde\",\"cellSpace\":\"Rūtiņu atstatums\",\"column\":{\"menu\":\"Kolonna\",\"insertBefore\":\"Ievietot kolonu pirms\",\"insertAfter\":\"Ievieto kolonu pēc\",\"deleteColumn\":\"Dzēst kolonnas\"},\"columns\":\"Kolonnas\",\"deleteTable\":\"Dzēst tabulu\",\"headers\":\"Virsraksti\",\"headersBoth\":\"Abi\",\"headersColumn\":\"Pirmā kolona\",\"headersNone\":\"Nekas\",\"headersRow\":\"Pirmā rinda\",\"invalidBorder\":\"Rāmju izmēram jābūt skaitlim\",\"invalidCellPadding\":\"Šūnu atkāpēm jābūt pozitīvam skaitlim\",\"invalidCellSpacing\":\"Šūnu atstarpēm jābūt pozitīvam skaitlim\",\"invalidCols\":\"Kolonu skaitam jābūt lielākam par 0\",\"invalidHeight\":\"Tabulas augstumam jābūt skaitlim\",\"invalidRows\":\"Rindu skaitam jābūt lielākam par 0\",\"invalidWidth\":\"Tabulas platumam jābūt skaitlim\",\"menu\":\"Tabulas īpašības\",\"row\":{\"menu\":\"Rinda\",\"insertBefore\":\"Ievietot rindu pirms\",\"insertAfter\":\"Ievietot rindu pēc\",\"deleteRow\":\"Dzēst rindas\"},\"rows\":\"Rindas\",\"summary\":\"Anotācija\",\"title\":\"Tabulas īpašības\",\"toolbar\":\"Tabula\",\"widthPc\":\"procentuāli\",\"widthPx\":\"pikseļos\",\"widthUnit\":\"platuma mērvienība\"},\"undo\":{\"redo\":\"Atkārtot\",\"undo\":\"Atcelt\"},\"wsc\":{\"btnIgnore\":\"Ignorēt\",\"btnIgnoreAll\":\"Ignorēt visu\",\"btnReplace\":\"Aizvietot\",\"btnReplaceAll\":\"Aizvietot visu\",\"btnUndo\":\"Atcelt\",\"changeTo\":\"Nomainīt uz\",\"errorLoading\":\"Kļūda ielādējot aplikācijas servisa adresi: %s.\",\"ieSpellDownload\":\"Pareizrakstības pārbaudītājs nav pievienots. Vai vēlaties to lejupielādēt tagad?\",\"manyChanges\":\"Pareizrakstības pārbaude pabeigta: %1 vārdi tika mainīti\",\"noChanges\":\"Pareizrakstības pārbaude pabeigta: nekas netika labots\",\"noMispell\":\"Pareizrakstības pārbaude pabeigta: kļūdas netika atrastas\",\"noSuggestions\":\"- Nav ieteikumu -\",\"notAvailable\":\"Atvainojiet, bet serviss šobrīd nav pieejams.\",\"notInDic\":\"Netika atrasts vārdnīcā\",\"oneChange\":\"Pareizrakstības pārbaude pabeigta: 1 vārds izmainīts\",\"progress\":\"Notiek pareizrakstības pārbaude...\",\"title\":\"Pārbaudīt gramatiku\",\"toolbar\":\"Pareizrakstības pārbaude\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/mk.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['mk']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Press ALT 0 for help\",\"browseServer\":\"Browse Server\",\"url\":\"URL\",\"protocol\":\"Protocol\",\"upload\":\"Upload\",\"uploadSubmit\":\"Send it to the Server\",\"image\":\"Image\",\"flash\":\"Flash\",\"form\":\"Form\",\"checkbox\":\"Checkbox\",\"radio\":\"Radio Button\",\"textField\":\"Text Field\",\"textarea\":\"Textarea\",\"hiddenField\":\"Hidden Field\",\"button\":\"Button\",\"select\":\"Selection Field\",\"imageButton\":\"Image Button\",\"notSet\":\"<not set>\",\"id\":\"Id\",\"name\":\"Name\",\"langDir\":\"Language Direction\",\"langDirLtr\":\"Left to Right (LTR)\",\"langDirRtl\":\"Right to Left (RTL)\",\"langCode\":\"Language Code\",\"longDescr\":\"Long Description URL\",\"cssClass\":\"Stylesheet Classes\",\"advisoryTitle\":\"Advisory Title\",\"cssStyle\":\"Style\",\"ok\":\"OK\",\"cancel\":\"Cancel\",\"close\":\"Close\",\"preview\":\"Preview\",\"resize\":\"Resize\",\"generalTab\":\"Општо\",\"advancedTab\":\"Advanced\",\"validateNumberFailed\":\"This value is not a number.\",\"confirmNewPage\":\"Any unsaved changes to this content will be lost. Are you sure you want to load new page?\",\"confirmCancel\":\"You have changed some options. Are you sure you want to close the dialog window?\",\"options\":\"Options\",\"target\":\"Target\",\"targetNew\":\"New Window (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Same Window (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"Left to Right (LTR)\",\"langDirRTL\":\"Right to Left (RTL)\",\"styles\":\"Style\",\"cssClasses\":\"Stylesheet Classes\",\"width\":\"Width\",\"height\":\"Height\",\"align\":\"Alignment\",\"alignLeft\":\"Left\",\"alignRight\":\"Right\",\"alignCenter\":\"Center\",\"alignTop\":\"Top\",\"alignMiddle\":\"Middle\",\"alignBottom\":\"Bottom\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Height must be a number.\",\"invalidWidth\":\"Width must be a number.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Bold\",\"italic\":\"Italic\",\"strike\":\"Strike Through\",\"subscript\":\"Subscript\",\"superscript\":\"Superscript\",\"underline\":\"Underline\"},\"blockquote\":{\"toolbar\":\"Block Quote\"},\"clipboard\":{\"copy\":\"Copy\",\"copyError\":\"Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).\",\"cut\":\"Cut\",\"cutError\":\"Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).\",\"paste\":\"Paste\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK\",\"securityMsg\":\"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.\",\"title\":\"Paste\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Collapse Toolbar\",\"toolbarExpand\":\"Expand Toolbar\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editor toolbars\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Paragraph Format\",\"tag_address\":\"Address\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatted\"},\"horizontalrule\":{\"toolbar\":\"Insert Horizontal Line\"},\"image\":{\"alertUrl\":\"Please type the image URL\",\"alt\":\"Alternative Text\",\"border\":\"Border\",\"btnUpload\":\"Send it to the Server\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"Image Info\",\"linkTab\":\"Link\",\"lockRatio\":\"Lock Ratio\",\"menu\":\"Image Properties\",\"resetSize\":\"Reset Size\",\"title\":\"Image Properties\",\"titleButton\":\"Image Button Properties\",\"upload\":\"Upload\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"Increase Indent\",\"outdent\":\"Decrease Indent\"},\"fakeobjects\":{\"anchor\":\"Anchor\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Hidden Field\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"Access Key\",\"advanced\":\"Advanced\",\"advisoryContentType\":\"Advisory Content Type\",\"advisoryTitle\":\"Advisory Title\",\"anchor\":{\"toolbar\":\"Anchor\",\"menu\":\"Edit Anchor\",\"title\":\"Anchor Properties\",\"name\":\"Anchor Name\",\"errorName\":\"Please type the anchor name\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"By Element Id\",\"anchorName\":\"By Anchor Name\",\"charset\":\"Linked Resource Charset\",\"cssClasses\":\"Stylesheet Classes\",\"emailAddress\":\"E-Mail Address\",\"emailBody\":\"Message Body\",\"emailSubject\":\"Message Subject\",\"id\":\"Id\",\"info\":\"Link Info\",\"langCode\":\"Language Code\",\"langDir\":\"Language Direction\",\"langDirLTR\":\"Left to Right (LTR)\",\"langDirRTL\":\"Right to Left (RTL)\",\"menu\":\"Edit Link\",\"name\":\"Name\",\"noAnchors\":\"(No anchors available in the document)\",\"noEmail\":\"Please type the e-mail address\",\"noUrl\":\"Please type the link URL\",\"other\":\"<other>\",\"popupDependent\":\"Dependent (Netscape)\",\"popupFeatures\":\"Popup Window Features\",\"popupFullScreen\":\"Full Screen (IE)\",\"popupLeft\":\"Left Position\",\"popupLocationBar\":\"Location Bar\",\"popupMenuBar\":\"Menu Bar\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"Scroll Bars\",\"popupStatusBar\":\"Status Bar\",\"popupToolbar\":\"Toolbar\",\"popupTop\":\"Top Position\",\"rel\":\"Relationship\",\"selectAnchor\":\"Select an Anchor\",\"styles\":\"Style\",\"tabIndex\":\"Tab Index\",\"target\":\"Target\",\"targetFrame\":\"<frame>\",\"targetFrameName\":\"Target Frame Name\",\"targetPopup\":\"<popup window>\",\"targetPopupName\":\"Popup Window Name\",\"title\":\"Link\",\"toAnchor\":\"Link to anchor in the text\",\"toEmail\":\"E-mail\",\"toUrl\":\"URL\",\"toolbar\":\"Link\",\"type\":\"Link Type\",\"unlink\":\"Unlink\",\"upload\":\"Upload\"},\"list\":{\"bulletedlist\":\"Insert/Remove Bulleted List\",\"numberedlist\":\"Insert/Remove Numbered List\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maximize\",\"minimize\":\"Minimize\"},\"pastetext\":{\"button\":\"Paste as plain text\",\"title\":\"Paste as Plain Text\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"Paste from Word\",\"toolbar\":\"Paste from Word\"},\"removeformat\":{\"toolbar\":\"Remove Format\"},\"sourcearea\":{\"toolbar\":\"Source\"},\"specialchar\":{\"options\":\"Special Character Options\",\"title\":\"Select Special Character\",\"toolbar\":\"Insert Special Character\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Styles\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"Border size\",\"caption\":\"Caption\",\"cell\":{\"menu\":\"Cell\",\"insertBefore\":\"Insert Cell Before\",\"insertAfter\":\"Insert Cell After\",\"deleteCell\":\"Delete Cells\",\"merge\":\"Merge Cells\",\"mergeRight\":\"Merge Right\",\"mergeDown\":\"Merge Down\",\"splitHorizontal\":\"Split Cell Horizontally\",\"splitVertical\":\"Split Cell Vertically\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"Cell padding\",\"cellSpace\":\"Cell spacing\",\"column\":{\"menu\":\"Column\",\"insertBefore\":\"Insert Column Before\",\"insertAfter\":\"Insert Column After\",\"deleteColumn\":\"Delete Columns\"},\"columns\":\"Columns\",\"deleteTable\":\"Delete Table\",\"headers\":\"Headers\",\"headersBoth\":\"Both\",\"headersColumn\":\"First column\",\"headersNone\":\"None\",\"headersRow\":\"First Row\",\"invalidBorder\":\"Border size must be a number.\",\"invalidCellPadding\":\"Cell padding must be a positive number.\",\"invalidCellSpacing\":\"Cell spacing must be a positive number.\",\"invalidCols\":\"Number of columns must be a number greater than 0.\",\"invalidHeight\":\"Table height must be a number.\",\"invalidRows\":\"Number of rows must be a number greater than 0.\",\"invalidWidth\":\"Table width must be a number.\",\"menu\":\"Table Properties\",\"row\":{\"menu\":\"Row\",\"insertBefore\":\"Insert Row Before\",\"insertAfter\":\"Insert Row After\",\"deleteRow\":\"Delete Rows\"},\"rows\":\"Rows\",\"summary\":\"Summary\",\"title\":\"Table Properties\",\"toolbar\":\"Table\",\"widthPc\":\"percent\",\"widthPx\":\"pixels\",\"widthUnit\":\"width unit\"},\"undo\":{\"redo\":\"Redo\",\"undo\":\"Undo\"},\"wsc\":{\"btnIgnore\":\"Ignore\",\"btnIgnoreAll\":\"Ignore All\",\"btnReplace\":\"Replace\",\"btnReplaceAll\":\"Replace All\",\"btnUndo\":\"Undo\",\"changeTo\":\"Change to\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Spell checker not installed. Do you want to download it now?\",\"manyChanges\":\"Spell check complete: %1 words changed\",\"noChanges\":\"Spell check complete: No words changed\",\"noMispell\":\"Spell check complete: No misspellings found\",\"noSuggestions\":\"- No suggestions -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Not in dictionary\",\"oneChange\":\"Spell check complete: One word changed\",\"progress\":\"Spell check in progress...\",\"title\":\"Spell Check\",\"toolbar\":\"Check Spelling\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/mn.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['mn']={\"editor\":\"Хэлбэрт бичвэр боловсруулагч\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Press ALT 0 for help\",\"browseServer\":\"Үйлчлэгч тооцоолуур (сервэр)-ийг үзэх\",\"url\":\"цахим хуудасны хаяг (URL)\",\"protocol\":\"Протокол\",\"upload\":\"Илгээж ачаалах\",\"uploadSubmit\":\"Үүнийг үйлчлэгч тооцоолуур (сервер) лүү илгээх\",\"image\":\"Зураг\",\"flash\":\"Флаш хөдөлгөөнтэй зураг\",\"form\":\"Маягт\",\"checkbox\":\"Тэмдэглээний нүд\",\"radio\":\"Радио товчлуур\",\"textField\":\"Бичвэрийн талбар\",\"textarea\":\"Бичвэрийн зай\",\"hiddenField\":\"Далд талбар\",\"button\":\"Товчлуур\",\"select\":\"Сонголтын талбар\",\"imageButton\":\"Зургий товчуур\",\"notSet\":\"<тохируулаагүй>\",\"id\":\"Id (техникийн нэр)\",\"name\":\"Нэр\",\"langDir\":\"Хэлний чиглэл\",\"langDirLtr\":\"Зүүнээс баруун (LTR)\",\"langDirRtl\":\"Баруунаас зүүн (RTL)\",\"langCode\":\"Хэлний код\",\"longDescr\":\"Урт тайлбарын вэб хаяг\",\"cssClass\":\"Хэлбэрийн хуудасны ангиуд\",\"advisoryTitle\":\"Зөвлөх гарчиг\",\"cssStyle\":\"Загвар\",\"ok\":\"За\",\"cancel\":\"Болих\",\"close\":\"Хаах\",\"preview\":\"Урьдчилан харах\",\"resize\":\"Resize\",\"generalTab\":\"Ерөнхий\",\"advancedTab\":\"Гүнзгий\",\"validateNumberFailed\":\"This value is not a number.\",\"confirmNewPage\":\"Any unsaved changes to this content will be lost. Are you sure you want to load new page?\",\"confirmCancel\":\"You have changed some options. Are you sure you want to close the dialog window?\",\"options\":\"Сонголт\",\"target\":\"Бай\",\"targetNew\":\"New Window (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Same Window (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"Зүүн талаас баруун тийшээ (LTR)\",\"langDirRTL\":\"Баруун талаас зүүн тийшээ (RTL)\",\"styles\":\"Загвар\",\"cssClasses\":\"Хэлбэрийн хуудасны ангиуд\",\"width\":\"Өргөн\",\"height\":\"Өндөр\",\"align\":\"Эгнээ\",\"alignLeft\":\"Зүүн\",\"alignRight\":\"Баруун\",\"alignCenter\":\"Төвд\",\"alignTop\":\"Дээд талд\",\"alignMiddle\":\"Дунд\",\"alignBottom\":\"Доод талд\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Өндөр нь тоо байх ёстой.\",\"invalidWidth\":\"Өргөн нь тоо байх ёстой.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Тод бүдүүн\",\"italic\":\"Налуу\",\"strike\":\"Дундуур нь зураастай болгох\",\"subscript\":\"Суурь болгох\",\"superscript\":\"Зэрэг болгох\",\"underline\":\"Доогуур нь зураастай болгох\"},\"blockquote\":{\"toolbar\":\"Ишлэл хэсэг\"},\"clipboard\":{\"copy\":\"Хуулах\",\"copyError\":\"Таны browser-ын хамгаалалтын тохиргоо editor-д автоматаар хуулах үйлдэлийг зөвшөөрөхгүй байна. (Ctrl/Cmd+C) товчны хослолыг ашиглана уу.\",\"cut\":\"Хайчлах\",\"cutError\":\"Таны browser-ын хамгаалалтын тохиргоо editor-д автоматаар хайчлах үйлдэлийг зөвшөөрөхгүй байна. (Ctrl/Cmd+X) товчны хослолыг ашиглана уу.\",\"paste\":\"Буулгах\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"(<strong>Ctrl/Cmd+V</strong>) товчийг ашиглан paste хийнэ үү. Мөн <strong>OK</strong> дар.\",\"securityMsg\":\"Таны үзүүлэгч/browser/-н хамгаалалтын тохиргооноос болоод editor clipboard өгөгдөлрүү шууд хандах боломжгүй. Энэ цонход дахин paste хийхийг оролд.\",\"title\":\"Буулгах\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Collapse Toolbar\",\"toolbarExpand\":\"Expand Toolbar\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Холбоосууд\",\"insert\":\"Оруулах\",\"styles\":\"Загварууд\",\"colors\":\"Онгөнүүд\",\"tools\":\"Хэрэгслүүд\"},\"toolbars\":\"Болосруулагчийн хэрэгслийн самбар\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Параргафын загвар\",\"panelTitle\":\"Параргафын загвар\",\"tag_address\":\"Хаяг\",\"tag_div\":\"Paragraph (DIV)\",\"tag_h1\":\"Гарчиг 1\",\"tag_h2\":\"Гарчиг 2\",\"tag_h3\":\"Гарчиг 3\",\"tag_h4\":\"Гарчиг 4\",\"tag_h5\":\"Гарчиг 5\",\"tag_h6\":\"Гарчиг 6\",\"tag_p\":\"Хэвийн\",\"tag_pre\":\"Formatted\"},\"horizontalrule\":{\"toolbar\":\"Хөндлөн зураас оруулах\"},\"image\":{\"alertUrl\":\"Зурагны URL-ын төрлийн сонгоно уу\",\"alt\":\"Зургийг орлох бичвэр\",\"border\":\"Хүрээ\",\"btnUpload\":\"Үүнийг сервэррүү илгээ\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"Хөндлөн зай\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"Зурагны мэдээлэл\",\"linkTab\":\"Холбоос\",\"lockRatio\":\"Радио түгжих\",\"menu\":\"Зураг\",\"resetSize\":\"хэмжээ дахин оноох\",\"title\":\"Зураг\",\"titleButton\":\"Зурган товчны шинж чанар\",\"upload\":\"Хуулах\",\"urlMissing\":\"Зургийн эх сурвалжийн хаяг (URL) байхгүй байна.\",\"vSpace\":\"Босоо зай\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"Догол мөр хасах\",\"outdent\":\"Догол мөр нэмэх\"},\"fakeobjects\":{\"anchor\":\"Зангуу\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Нууц талбар\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"Холбох түлхүүр\",\"advanced\":\"Нэмэлт\",\"advisoryContentType\":\"Зөвлөлдөх төрлийн агуулга\",\"advisoryTitle\":\"Зөвлөлдөх гарчиг\",\"anchor\":{\"toolbar\":\"Зангуу\",\"menu\":\"Зангууг болосруулах\",\"title\":\"Зангуугийн шинж чанар\",\"name\":\"Зангуугийн нэр\",\"errorName\":\"Зангуугийн нэрийг оруулна уу\",\"remove\":\"Зангууг устгах\"},\"anchorId\":\"Элемэнтйн Id нэрээр\",\"anchorName\":\"Зангуугийн нэрээр\",\"charset\":\"Тэмдэгт оноох нөөцөд холбогдсон\",\"cssClasses\":\"Stylesheet классууд\",\"emailAddress\":\"Э-шуудангийн хаяг\",\"emailBody\":\"Зурвасны их бие\",\"emailSubject\":\"Зурвасны гарчиг\",\"id\":\"Id\",\"info\":\"Холбоосын тухай мэдээлэл\",\"langCode\":\"Хэлний код\",\"langDir\":\"Хэлний чиглэл\",\"langDirLTR\":\"Зүүнээс баруун (LTR)\",\"langDirRTL\":\"Баруунаас зүүн (RTL)\",\"menu\":\"Холбоос засварлах\",\"name\":\"Нэр\",\"noAnchors\":\"(Баримт бичиг зангуугүй байна)\",\"noEmail\":\"Э-шуудангий хаягаа шивнэ үү\",\"noUrl\":\"Холбоосны URL хаягийг шивнэ үү\",\"other\":\"<other>\",\"popupDependent\":\"Хамаатай (Netscape)\",\"popupFeatures\":\"Popup цонхны онцлог\",\"popupFullScreen\":\"Цонх дүүргэх (Internet Explorer)\",\"popupLeft\":\"Зүүн байрлал\",\"popupLocationBar\":\"Location хэсэг\",\"popupMenuBar\":\"Цэсний самбар\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"Скрол хэсэгүүд\",\"popupStatusBar\":\"Статус хэсэг\",\"popupToolbar\":\"Багажны самбар\",\"popupTop\":\"Дээд байрлал\",\"rel\":\"Relationship\",\"selectAnchor\":\"Нэг зангууг сонгоно уу\",\"styles\":\"Загвар\",\"tabIndex\":\"Tab индекс\",\"target\":\"Байрлал\",\"targetFrame\":\"<Агуулах хүрээ>\",\"targetFrameName\":\"Очих фремын нэр\",\"targetPopup\":\"<popup цонх>\",\"targetPopupName\":\"Popup цонхны нэр\",\"title\":\"Холбоос\",\"toAnchor\":\"Энэ бичвэр дэх зангуу руу очих холбоос\",\"toEmail\":\"Э-захиа\",\"toUrl\":\"цахим хуудасны хаяг (URL)\",\"toolbar\":\"Холбоос\",\"type\":\"Линкийн төрөл\",\"unlink\":\"Холбоос авч хаях\",\"upload\":\"Хуулах\"},\"list\":{\"bulletedlist\":\"Цэгтэй жагсаалт\",\"numberedlist\":\"Дугаарлагдсан жагсаалт\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Дэлгэц дүүргэх\",\"minimize\":\"Цонхыг багсгаж харуулах\"},\"pastetext\":{\"button\":\"Энгийн бичвэрээр буулгах\",\"title\":\"Энгийн бичвэрээр буулгах\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"Word-оос буулгах\",\"toolbar\":\"Word-оос буулгах\"},\"removeformat\":{\"toolbar\":\"Параргафын загварыг авч хаях\"},\"sourcearea\":{\"toolbar\":\"Код\"},\"specialchar\":{\"options\":\"Special Character Options\",\"title\":\"Онцгой тэмдэгт сонгох\",\"toolbar\":\"Онцгой тэмдэгт оруулах\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Бий болгох\",\"dic_delete\":\"Устгах\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Нэрийг солих\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Толь бичгүүд\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Хэлүүд\",\"languagesTab\":\"Хэлүүд\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Сонголт\",\"optionsTab\":\"Сонголт\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Загвар\",\"panelTitle\":\"Загвар хэлбэржүүлэх\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"Хүрээний хэмжээ\",\"caption\":\"Тайлбар\",\"cell\":{\"menu\":\"Нүх/зай\",\"insertBefore\":\"Нүх/зай өмнө нь оруулах\",\"insertAfter\":\"Нүх/зай дараа нь оруулах\",\"deleteCell\":\"Нүх устгах\",\"merge\":\"Нүх нэгтэх\",\"mergeRight\":\"Баруун тийш нэгтгэх\",\"mergeDown\":\"Доош нэгтгэх\",\"splitHorizontal\":\"Нүх/зайг босоогоор нь тусгаарлах\",\"splitVertical\":\"Нүх/зайг хөндлөнгөөр нь тусгаарлах\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Хэвтээд тэгшлэх арга\",\"vAlign\":\"Босоод тэгшлэх арга\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Дэвсгэр өнгө\",\"borderColor\":\"Хүрээний өнгө\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Тийм\",\"no\":\"Үгүй\",\"invalidWidth\":\"Нүдний өргөн нь тоо байх ёстой.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Сонгох\"},\"cellPad\":\"Нүх доторлох(padding)\",\"cellSpace\":\"Нүх хоорондын зай (spacing)\",\"column\":{\"menu\":\"Багана\",\"insertBefore\":\"Багана өмнө нь оруулах\",\"insertAfter\":\"Багана дараа нь оруулах\",\"deleteColumn\":\"Багана устгах\"},\"columns\":\"Багана\",\"deleteTable\":\"Хүснэгт устгах\",\"headers\":\"Headers\",\"headersBoth\":\"Both\",\"headersColumn\":\"First column\",\"headersNone\":\"None\",\"headersRow\":\"First Row\",\"invalidBorder\":\"Border size must be a number.\",\"invalidCellPadding\":\"Cell padding must be a positive number.\",\"invalidCellSpacing\":\"Cell spacing must be a positive number.\",\"invalidCols\":\"Number of columns must be a number greater than 0.\",\"invalidHeight\":\"Table height must be a number.\",\"invalidRows\":\"Number of rows must be a number greater than 0.\",\"invalidWidth\":\"Хүснэгтийн өргөн нь тоо байх ёстой.\",\"menu\":\"Хүснэгт\",\"row\":{\"menu\":\"Мөр\",\"insertBefore\":\"Мөр өмнө нь оруулах\",\"insertAfter\":\"Мөр дараа нь оруулах\",\"deleteRow\":\"Мөр устгах\"},\"rows\":\"Мөр\",\"summary\":\"Тайлбар\",\"title\":\"Хүснэгт\",\"toolbar\":\"Хүснэгт\",\"widthPc\":\"хувь\",\"widthPx\":\"цэг\",\"widthUnit\":\"өргөний нэгж\"},\"undo\":{\"redo\":\"Өмнөх үйлдлээ сэргээх\",\"undo\":\"Хүчингүй болгох\"},\"wsc\":{\"btnIgnore\":\"Зөвшөөрөх\",\"btnIgnoreAll\":\"Бүгдийг зөвшөөрөх\",\"btnReplace\":\"Солих\",\"btnReplaceAll\":\"Бүгдийг Дарж бичих\",\"btnUndo\":\"Буцаах\",\"changeTo\":\"Өөрчлөх\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Дүрэм шалгагч суугаагүй байна. Татаж авахыг хүсч байна уу?\",\"manyChanges\":\"Дүрэм шалгаад дууссан: %1 үг өөрчлөгдсөн\",\"noChanges\":\"Дүрэм шалгаад дууссан: үг өөрчлөгдөөгүй\",\"noMispell\":\"Дүрэм шалгаад дууссан: Алдаа олдсонгүй\",\"noSuggestions\":\"- Тайлбаргүй -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Толь бичиггүй\",\"oneChange\":\"Дүрэм шалгаад дууссан: 1 үг өөрчлөгдсөн\",\"progress\":\"Дүрэм шалгаж байгаа үйл явц...\",\"title\":\"Spell Check\",\"toolbar\":\"Үгийн дүрэх шалгах\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/ms.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['ms']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Press ALT 0 for help\",\"browseServer\":\"Browse Server\",\"url\":\"URL\",\"protocol\":\"Protokol\",\"upload\":\"Muat Naik\",\"uploadSubmit\":\"Hantar ke Server\",\"image\":\"Gambar\",\"flash\":\"Flash\",\"form\":\"Borang\",\"checkbox\":\"Checkbox\",\"radio\":\"Butang Radio\",\"textField\":\"Text Field\",\"textarea\":\"Textarea\",\"hiddenField\":\"Field Tersembunyi\",\"button\":\"Butang\",\"select\":\"Field Pilihan\",\"imageButton\":\"Butang Bergambar\",\"notSet\":\"<tidak di set>\",\"id\":\"Id\",\"name\":\"Nama\",\"langDir\":\"Arah Tulisan\",\"langDirLtr\":\"Kiri ke Kanan (LTR)\",\"langDirRtl\":\"Kanan ke Kiri (RTL)\",\"langCode\":\"Kod Bahasa\",\"longDescr\":\"Butiran Panjang URL\",\"cssClass\":\"Kelas-kelas Stylesheet\",\"advisoryTitle\":\"Tajuk Makluman\",\"cssStyle\":\"Stail\",\"ok\":\"OK\",\"cancel\":\"Batal\",\"close\":\"Close\",\"preview\":\"Prebiu\",\"resize\":\"Resize\",\"generalTab\":\"General\",\"advancedTab\":\"Advanced\",\"validateNumberFailed\":\"This value is not a number.\",\"confirmNewPage\":\"Any unsaved changes to this content will be lost. Are you sure you want to load new page?\",\"confirmCancel\":\"You have changed some options. Are you sure you want to close the dialog window?\",\"options\":\"Options\",\"target\":\"Sasaran\",\"targetNew\":\"New Window (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Same Window (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"Kiri ke Kanan (LTR)\",\"langDirRTL\":\"Kanan ke Kiri (RTL)\",\"styles\":\"Stail\",\"cssClasses\":\"Kelas-kelas Stylesheet\",\"width\":\"Lebar\",\"height\":\"Tinggi\",\"align\":\"Jajaran\",\"alignLeft\":\"Kiri\",\"alignRight\":\"Kanan\",\"alignCenter\":\"Tengah\",\"alignTop\":\"Atas\",\"alignMiddle\":\"Pertengahan\",\"alignBottom\":\"Bawah\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Height must be a number.\",\"invalidWidth\":\"Width must be a number.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Bold\",\"italic\":\"Italic\",\"strike\":\"Strike Through\",\"subscript\":\"Subscript\",\"superscript\":\"Superscript\",\"underline\":\"Underline\"},\"blockquote\":{\"toolbar\":\"Block Quote\"},\"clipboard\":{\"copy\":\"Salin\",\"copyError\":\"Keselamatan perisian browser anda tidak membenarkan operasi salinan text/imej. Sila gunakan papan kekunci (Ctrl/Cmd+C).\",\"cut\":\"Potong\",\"cutError\":\"Keselamatan perisian browser anda tidak membenarkan operasi suntingan text/imej. Sila gunakan papan kekunci (Ctrl/Cmd+X).\",\"paste\":\"Tampal\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK\",\"securityMsg\":\"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.\",\"title\":\"Tampal\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Collapse Toolbar\",\"toolbarExpand\":\"Expand Toolbar\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editor toolbars\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Format\",\"tag_address\":\"Alamat\",\"tag_div\":\"Perenggan (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Telah Diformat\"},\"horizontalrule\":{\"toolbar\":\"Masukkan Garisan Membujur\"},\"image\":{\"alertUrl\":\"Sila taip URL untuk fail gambar\",\"alt\":\"Text Alternatif\",\"border\":\"Border\",\"btnUpload\":\"Hantar ke Server\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"Ruang Melintang\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"Info Imej\",\"linkTab\":\"Sambungan\",\"lockRatio\":\"Tetapkan Nisbah\",\"menu\":\"Ciri-ciri Imej\",\"resetSize\":\"Saiz Set Semula\",\"title\":\"Ciri-ciri Imej\",\"titleButton\":\"Ciri-ciri Butang Bergambar\",\"upload\":\"Muat Naik\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"Ruang Menegak\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"Tambahkan Inden\",\"outdent\":\"Kurangkan Inden\"},\"fakeobjects\":{\"anchor\":\"Anchor\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Hidden Field\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"Kunci Akses\",\"advanced\":\"Advanced\",\"advisoryContentType\":\"Jenis Kandungan Makluman\",\"advisoryTitle\":\"Tajuk Makluman\",\"anchor\":{\"toolbar\":\"Masukkan/Sunting Pautan\",\"menu\":\"Ciri-ciri Pautan\",\"title\":\"Ciri-ciri Pautan\",\"name\":\"Nama Pautan\",\"errorName\":\"Sila taip nama pautan\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"dengan menggunakan ID elemen\",\"anchorName\":\"dengan menggunakan nama pautan\",\"charset\":\"Linked Resource Charset\",\"cssClasses\":\"Kelas-kelas Stylesheet\",\"emailAddress\":\"Alamat E-Mail\",\"emailBody\":\"Isi Kandungan Mesej\",\"emailSubject\":\"Subjek Mesej\",\"id\":\"Id\",\"info\":\"Butiran Sambungan\",\"langCode\":\"Arah Tulisan\",\"langDir\":\"Arah Tulisan\",\"langDirLTR\":\"Kiri ke Kanan (LTR)\",\"langDirRTL\":\"Kanan ke Kiri (RTL)\",\"menu\":\"Sunting Sambungan\",\"name\":\"Nama\",\"noAnchors\":\"(Tiada pautan terdapat dalam dokumen ini)\",\"noEmail\":\"Sila taip alamat e-mail\",\"noUrl\":\"Sila taip sambungan URL\",\"other\":\"<lain>\",\"popupDependent\":\"Bergantungan (Netscape)\",\"popupFeatures\":\"Ciri Tetingkap Popup\",\"popupFullScreen\":\"Skrin Penuh (IE)\",\"popupLeft\":\"Posisi Kiri\",\"popupLocationBar\":\"Bar Lokasi\",\"popupMenuBar\":\"Bar Menu\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"Bar-bar skrol\",\"popupStatusBar\":\"Bar Status\",\"popupToolbar\":\"Toolbar\",\"popupTop\":\"Posisi Atas\",\"rel\":\"Relationship\",\"selectAnchor\":\"Sila pilih pautan\",\"styles\":\"Stail\",\"tabIndex\":\"Indeks Tab \",\"target\":\"Sasaran\",\"targetFrame\":\"<bingkai>\",\"targetFrameName\":\"Nama Bingkai Sasaran\",\"targetPopup\":\"<tetingkap popup>\",\"targetPopupName\":\"Nama Tetingkap Popup\",\"title\":\"Sambungan\",\"toAnchor\":\"Pautan dalam muka surat ini\",\"toEmail\":\"E-Mail\",\"toUrl\":\"URL\",\"toolbar\":\"Masukkan/Sunting Sambungan\",\"type\":\"Jenis Sambungan\",\"unlink\":\"Buang Sambungan\",\"upload\":\"Muat Naik\"},\"list\":{\"bulletedlist\":\"Senarai tidak bernombor\",\"numberedlist\":\"Senarai bernombor\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maximize\",\"minimize\":\"Minimize\"},\"pastetext\":{\"button\":\"Tampal sebagai text biasa\",\"title\":\"Tampal sebagai text biasa\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"Tampal dari Word\",\"toolbar\":\"Tampal dari Word\"},\"removeformat\":{\"toolbar\":\"Buang Format\"},\"sourcearea\":{\"toolbar\":\"Sumber\"},\"specialchar\":{\"options\":\"Special Character Options\",\"title\":\"Sila pilih huruf istimewa\",\"toolbar\":\"Masukkan Huruf Istimewa\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stail\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"Saiz Border\",\"caption\":\"Keterangan\",\"cell\":{\"menu\":\"Cell\",\"insertBefore\":\"Insert Cell Before\",\"insertAfter\":\"Insert Cell After\",\"deleteCell\":\"Buangkan Sel-sel\",\"merge\":\"Cantumkan Sel-sel\",\"mergeRight\":\"Merge Right\",\"mergeDown\":\"Merge Down\",\"splitHorizontal\":\"Split Cell Horizontally\",\"splitVertical\":\"Split Cell Vertically\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"Tambahan Ruang Sel\",\"cellSpace\":\"Ruangan Antara Sel\",\"column\":{\"menu\":\"Column\",\"insertBefore\":\"Insert Column Before\",\"insertAfter\":\"Insert Column After\",\"deleteColumn\":\"Buangkan Lajur\"},\"columns\":\"Jaluran\",\"deleteTable\":\"Delete Table\",\"headers\":\"Headers\",\"headersBoth\":\"Both\",\"headersColumn\":\"First column\",\"headersNone\":\"None\",\"headersRow\":\"First Row\",\"invalidBorder\":\"Border size must be a number.\",\"invalidCellPadding\":\"Cell padding must be a positive number.\",\"invalidCellSpacing\":\"Cell spacing must be a positive number.\",\"invalidCols\":\"Number of columns must be a number greater than 0.\",\"invalidHeight\":\"Table height must be a number.\",\"invalidRows\":\"Number of rows must be a number greater than 0.\",\"invalidWidth\":\"Table width must be a number.\",\"menu\":\"Ciri-ciri Jadual\",\"row\":{\"menu\":\"Row\",\"insertBefore\":\"Insert Row Before\",\"insertAfter\":\"Insert Row After\",\"deleteRow\":\"Buangkan Baris\"},\"rows\":\"Barisan\",\"summary\":\"Summary\",\"title\":\"Ciri-ciri Jadual\",\"toolbar\":\"Jadual\",\"widthPc\":\"peratus\",\"widthPx\":\"piksel-piksel\",\"widthUnit\":\"width unit\"},\"undo\":{\"redo\":\"Ulangkan\",\"undo\":\"Batalkan\"},\"wsc\":{\"btnIgnore\":\"Biar\",\"btnIgnoreAll\":\"Biarkan semua\",\"btnReplace\":\"Ganti\",\"btnReplaceAll\":\"Gantikan Semua\",\"btnUndo\":\"Batalkan\",\"changeTo\":\"Tukarkan kepada\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Pemeriksa ejaan tidak dipasang. Adakah anda mahu muat turun sekarang?\",\"manyChanges\":\"Pemeriksaan ejaan siap: %1 perkataan diubah\",\"noChanges\":\"Pemeriksaan ejaan siap: Tiada perkataan diubah\",\"noMispell\":\"Pemeriksaan ejaan siap: Tiada salah ejaan\",\"noSuggestions\":\"- Tiada cadangan -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Tidak terdapat didalam kamus\",\"oneChange\":\"Pemeriksaan ejaan siap: Satu perkataan telah diubah\",\"progress\":\"Pemeriksaan ejaan sedang diproses...\",\"title\":\"Spell Check\",\"toolbar\":\"Semak Ejaan\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/nb.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['nb']={\"editor\":\"Rikteksteditor\",\"editorPanel\":\"Panel for rikteksteditor\",\"common\":{\"editorHelp\":\"Trykk ALT 0 for hjelp\",\"browseServer\":\"Bla igjennom server\",\"url\":\"URL\",\"protocol\":\"Protokoll\",\"upload\":\"Last opp\",\"uploadSubmit\":\"Send det til serveren\",\"image\":\"Bilde\",\"flash\":\"Flash\",\"form\":\"Skjema\",\"checkbox\":\"Avmerkingsboks\",\"radio\":\"Alternativknapp\",\"textField\":\"Tekstboks\",\"textarea\":\"Tekstområde\",\"hiddenField\":\"Skjult felt\",\"button\":\"Knapp\",\"select\":\"Rullegardinliste\",\"imageButton\":\"Bildeknapp\",\"notSet\":\"<ikke satt>\",\"id\":\"Id\",\"name\":\"Navn\",\"langDir\":\"Språkretning\",\"langDirLtr\":\"Venstre til høyre (VTH)\",\"langDirRtl\":\"Høyre til venstre (HTV)\",\"langCode\":\"Språkkode\",\"longDescr\":\"Utvidet beskrivelse\",\"cssClass\":\"Stilarkklasser\",\"advisoryTitle\":\"Tittel\",\"cssStyle\":\"Stil\",\"ok\":\"OK\",\"cancel\":\"Avbryt\",\"close\":\"Lukk\",\"preview\":\"Forhåndsvis\",\"resize\":\"Dra for å skalere\",\"generalTab\":\"Generelt\",\"advancedTab\":\"Avansert\",\"validateNumberFailed\":\"Denne verdien er ikke et tall.\",\"confirmNewPage\":\"Alle ulagrede endringer som er gjort i dette innholdet vil bli tapt. Er du sikker på at du vil laste en ny side?\",\"confirmCancel\":\"Noen av valgene har blitt endret. Er du sikker på at du vil lukke dialogen?\",\"options\":\"Valg\",\"target\":\"Mål\",\"targetNew\":\"Nytt vindu (_blank)\",\"targetTop\":\"Hele vindu (_top)\",\"targetSelf\":\"Samme vindu (_self)\",\"targetParent\":\"Foreldrevindu (_parent)\",\"langDirLTR\":\"Venstre til høyre (VTH)\",\"langDirRTL\":\"Høyre til venstre (HTV)\",\"styles\":\"Stil\",\"cssClasses\":\"Stilarkklasser\",\"width\":\"Bredde\",\"height\":\"Høyde\",\"align\":\"Juster\",\"alignLeft\":\"Venstre\",\"alignRight\":\"Høyre\",\"alignCenter\":\"Midtjuster\",\"alignTop\":\"Topp\",\"alignMiddle\":\"Midten\",\"alignBottom\":\"Bunn\",\"invalidValue\":\"Ugyldig verdi.\",\"invalidHeight\":\"Høyde må være et tall.\",\"invalidWidth\":\"Bredde må være et tall.\",\"invalidCssLength\":\"Den angitte verdien for feltet \\\"%1\\\" må være et positivt tall med eller uten en gyldig CSS-målingsenhet (px, %, in, cm, mm, em, ex, pt, eller pc).\",\"invalidHtmlLength\":\"Den angitte verdien for feltet \\\"%1\\\" må være et positivt tall med eller uten en gyldig HTML-målingsenhet (px eller %).\",\"invalidInlineStyle\":\"Verdi angitt for inline stil må bestå av en eller flere sett med formatet \\\"navn : verdi\\\", separert med semikolon\",\"cssLengthTooltip\":\"Skriv inn et tall for en piksel-verdi eller et tall med en gyldig CSS-enhet (px, %, in, cm, mm, em, ex, pt, eller pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, utilgjenglig</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Alle rettigheter reservert.\",\"dlgTitle\":\"Om CKEditor\",\"help\":\"Se $1 for hjelp.\",\"moreInfo\":\"For lisensieringsinformasjon, vennligst besøk vårt nettsted:\",\"title\":\"Om CKEditor\",\"userGuide\":\"CKEditors brukerveiledning\"},\"basicstyles\":{\"bold\":\"Fet\",\"italic\":\"Kursiv\",\"strike\":\"Gjennomstreking\",\"subscript\":\"Senket skrift\",\"superscript\":\"Hevet skrift\",\"underline\":\"Understreking\"},\"blockquote\":{\"toolbar\":\"Blokksitat\"},\"clipboard\":{\"copy\":\"Kopier\",\"copyError\":\"Din nettlesers sikkerhetsinstillinger tillater ikke automatisk kopiering av tekst. Vennligst bruk tastatursnarveien (Ctrl/Cmd+C).\",\"cut\":\"Klipp ut\",\"cutError\":\"Din nettlesers sikkerhetsinstillinger tillater ikke automatisk utklipping av tekst. Vennligst bruk tastatursnarveien (Ctrl/Cmd+X).\",\"paste\":\"Lim inn\",\"pasteArea\":\"Innlimingsområde\",\"pasteMsg\":\"Vennligst lim inn i følgende boks med tastaturet (<strong>Ctrl/Cmd+V</strong>) og trykk <strong>OK</strong>.\",\"securityMsg\":\"Din nettlesers sikkerhetsinstillinger gir ikke redigeringsverktøyet direkte tilgang til utklippstavlen. Du må derfor lime det inn på nytt i dette vinduet.\",\"title\":\"Lim inn\"},\"contextmenu\":{\"options\":\"Alternativer for høyreklikkmeny\"},\"toolbar\":{\"toolbarCollapse\":\"Skjul verktøylinje\",\"toolbarExpand\":\"Vis verktøylinje\",\"toolbarGroups\":{\"document\":\"Dokument\",\"clipboard\":\"Utklippstavle/Angre\",\"editing\":\"Redigering\",\"forms\":\"Skjema\",\"basicstyles\":\"Basisstiler\",\"paragraph\":\"Avsnitt\",\"links\":\"Lenker\",\"insert\":\"Innsetting\",\"styles\":\"Stiler\",\"colors\":\"Farger\",\"tools\":\"Verktøy\"},\"toolbars\":\"Verktøylinjer for editor\"},\"elementspath\":{\"eleLabel\":\"Element-sti\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Avsnittsformat\",\"tag_address\":\"Adresse\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Overskrift 1\",\"tag_h2\":\"Overskrift 2\",\"tag_h3\":\"Overskrift 3\",\"tag_h4\":\"Overskrift 4\",\"tag_h5\":\"Overskrift 5\",\"tag_h6\":\"Overskrift 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatert\"},\"horizontalrule\":{\"toolbar\":\"Sett inn horisontal linje\"},\"image\":{\"alertUrl\":\"Vennligst skriv bilde-urlen\",\"alt\":\"Alternativ tekst\",\"border\":\"Ramme\",\"btnUpload\":\"Send det til serveren\",\"button2Img\":\"Vil du endre den valgte bildeknappen til et vanlig bilde?\",\"hSpace\":\"HMarg\",\"img2Button\":\"Vil du endre det valgte bildet til en bildeknapp?\",\"infoTab\":\"Bildeinformasjon\",\"linkTab\":\"Lenke\",\"lockRatio\":\"Lås forhold\",\"menu\":\"Bildeegenskaper\",\"resetSize\":\"Tilbakestill størrelse\",\"title\":\"Bildeegenskaper\",\"titleButton\":\"Egenskaper for bildeknapp\",\"upload\":\"Last opp\",\"urlMissing\":\"Bildets adresse mangler.\",\"vSpace\":\"VMarg\",\"validateBorder\":\"Ramme må være et heltall.\",\"validateHSpace\":\"HMarg må være et heltall.\",\"validateVSpace\":\"VMarg må være et heltall.\"},\"indent\":{\"indent\":\"Øk innrykk\",\"outdent\":\"Reduser innrykk\"},\"fakeobjects\":{\"anchor\":\"Anker\",\"flash\":\"Flash-animasjon\",\"hiddenfield\":\"Skjult felt\",\"iframe\":\"IFrame\",\"unknown\":\"Ukjent objekt\"},\"link\":{\"acccessKey\":\"Aksessknapp\",\"advanced\":\"Avansert\",\"advisoryContentType\":\"Type\",\"advisoryTitle\":\"Tittel\",\"anchor\":{\"toolbar\":\"Sett inn/Rediger anker\",\"menu\":\"Egenskaper for anker\",\"title\":\"Egenskaper for anker\",\"name\":\"Ankernavn\",\"errorName\":\"Vennligst skriv inn ankernavnet\",\"remove\":\"Fjern anker\"},\"anchorId\":\"Element etter ID\",\"anchorName\":\"Anker etter navn\",\"charset\":\"Lenket tegnsett\",\"cssClasses\":\"Stilarkklasser\",\"emailAddress\":\"E-postadresse\",\"emailBody\":\"Melding\",\"emailSubject\":\"Meldingsemne\",\"id\":\"Id\",\"info\":\"Lenkeinfo\",\"langCode\":\"Språkkode\",\"langDir\":\"Språkretning\",\"langDirLTR\":\"Venstre til høyre (VTH)\",\"langDirRTL\":\"Høyre til venstre (HTV)\",\"menu\":\"Rediger lenke\",\"name\":\"Navn\",\"noAnchors\":\"(Ingen anker i dokumentet)\",\"noEmail\":\"Vennligst skriv inn e-postadressen\",\"noUrl\":\"Vennligst skriv inn lenkens URL\",\"other\":\"<annen>\",\"popupDependent\":\"Avhenging (Netscape)\",\"popupFeatures\":\"Egenskaper for popup-vindu\",\"popupFullScreen\":\"Fullskjerm (IE)\",\"popupLeft\":\"Venstre posisjon\",\"popupLocationBar\":\"Adresselinje\",\"popupMenuBar\":\"Menylinje\",\"popupResizable\":\"Skalerbar\",\"popupScrollBars\":\"Scrollbar\",\"popupStatusBar\":\"Statuslinje\",\"popupToolbar\":\"Verktøylinje\",\"popupTop\":\"Topp-posisjon\",\"rel\":\"Relasjon (rel)\",\"selectAnchor\":\"Velg et anker\",\"styles\":\"Stil\",\"tabIndex\":\"Tabindeks\",\"target\":\"Mål\",\"targetFrame\":\"<ramme>\",\"targetFrameName\":\"Målramme\",\"targetPopup\":\"<popup-vindu>\",\"targetPopupName\":\"Navn på popup-vindu\",\"title\":\"Lenke\",\"toAnchor\":\"Lenke til anker i teksten\",\"toEmail\":\"E-post\",\"toUrl\":\"URL\",\"toolbar\":\"Sett inn/Rediger lenke\",\"type\":\"Lenketype\",\"unlink\":\"Fjern lenke\",\"upload\":\"Last opp\"},\"list\":{\"bulletedlist\":\"Legg til/Fjern punktmerket liste\",\"numberedlist\":\"Legg til/Fjern nummerert liste\"},\"magicline\":{\"title\":\"Sett inn nytt avsnitt her\"},\"maximize\":{\"maximize\":\"Maksimer\",\"minimize\":\"Minimer\"},\"pastetext\":{\"button\":\"Lim inn som ren tekst\",\"title\":\"Lim inn som ren tekst\"},\"pastefromword\":{\"confirmCleanup\":\"Teksten du limer inn ser ut til å være kopiert fra Word. Vil du renske den før du limer den inn?\",\"error\":\"Det var ikke mulig å renske den innlimte teksten på grunn av en intern feil\",\"title\":\"Lim inn fra Word\",\"toolbar\":\"Lim inn fra Word\"},\"removeformat\":{\"toolbar\":\"Fjern formatering\"},\"sourcearea\":{\"toolbar\":\"Kilde\"},\"specialchar\":{\"options\":\"Alternativer for spesialtegn\",\"title\":\"Velg spesialtegn\",\"toolbar\":\"Sett inn spesialtegn\"},\"scayt\":{\"about\":\"Om SCAYT\",\"aboutTab\":\"Om\",\"addWord\":\"Legg til ord\",\"allCaps\":\"Ikke kontroller ord med kun store bokstaver\",\"dic_create\":\"Opprett\",\"dic_delete\":\"Slett\",\"dic_field_name\":\"Ordboknavn\",\"dic_info\":\"Brukerordboken lagres først i en informasjonskapsel på din maskin, men det er en begrensning på hvor mye som kan lagres her. Når ordboken blir for stor til å lagres i en informasjonskapsel, vil vi i stedet lagre ordboken på vår server. For å lagre din personlige ordbok på vår server, burde du velge et navn for ordboken din. Hvis du allerede har lagret en ordbok, vennligst skriv inn ordbokens navn og klikk på Gjenopprett-knappen.\",\"dic_rename\":\"Gi nytt navn\",\"dic_restore\":\"Gjenopprett\",\"dictionariesTab\":\"Ordbøker\",\"disable\":\"Slå av SCAYT\",\"emptyDic\":\"Ordboknavn bør ikke være tom.\",\"enable\":\"Slå på SCAYT\",\"ignore\":\"Ignorer\",\"ignoreAll\":\"Ignorer Alle\",\"ignoreDomainNames\":\"Ikke kontroller domenenavn\",\"langs\":\"Språk\",\"languagesTab\":\"Språk\",\"mixedCase\":\"Ikke kontroller ord med blandet små og store bokstaver\",\"mixedWithDigits\":\"Ikke kontroller ord som inneholder tall\",\"moreSuggestions\":\"Flere forslag\",\"opera_title\":\"Ikke støttet av Opera\",\"options\":\"Valg\",\"optionsTab\":\"Valg\",\"title\":\"Stavekontroll mens du skriver\",\"toggle\":\"Veksle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stil\",\"panelTitle\":\"Stilformater\",\"panelTitle1\":\"Blokkstiler\",\"panelTitle2\":\"Inlinestiler\",\"panelTitle3\":\"Objektstiler\"},\"table\":{\"border\":\"Rammestørrelse\",\"caption\":\"Tittel\",\"cell\":{\"menu\":\"Celle\",\"insertBefore\":\"Sett inn celle før\",\"insertAfter\":\"Sett inn celle etter\",\"deleteCell\":\"Slett celler\",\"merge\":\"Slå sammen celler\",\"mergeRight\":\"Slå sammen høyre\",\"mergeDown\":\"Slå sammen ned\",\"splitHorizontal\":\"Del celle horisontalt\",\"splitVertical\":\"Del celle vertikalt\",\"title\":\"Celleegenskaper\",\"cellType\":\"Celletype\",\"rowSpan\":\"Radspenn\",\"colSpan\":\"Kolonnespenn\",\"wordWrap\":\"Tekstbrytning\",\"hAlign\":\"Horisontal justering\",\"vAlign\":\"Vertikal justering\",\"alignBaseline\":\"Grunnlinje\",\"bgColor\":\"Bakgrunnsfarge\",\"borderColor\":\"Rammefarge\",\"data\":\"Data\",\"header\":\"Overskrift\",\"yes\":\"Ja\",\"no\":\"Nei\",\"invalidWidth\":\"Cellebredde må være et tall.\",\"invalidHeight\":\"Cellehøyde må være et tall.\",\"invalidRowSpan\":\"Radspenn må være et heltall.\",\"invalidColSpan\":\"Kolonnespenn må være et heltall.\",\"chooseColor\":\"Velg\"},\"cellPad\":\"Cellepolstring\",\"cellSpace\":\"Cellemarg\",\"column\":{\"menu\":\"Kolonne\",\"insertBefore\":\"Sett inn kolonne før\",\"insertAfter\":\"Sett inn kolonne etter\",\"deleteColumn\":\"Slett kolonner\"},\"columns\":\"Kolonner\",\"deleteTable\":\"Slett tabell\",\"headers\":\"Overskrifter\",\"headersBoth\":\"Begge\",\"headersColumn\":\"Første kolonne\",\"headersNone\":\"Ingen\",\"headersRow\":\"Første rad\",\"invalidBorder\":\"Rammestørrelse må være et tall.\",\"invalidCellPadding\":\"Cellepolstring må være et positivt tall.\",\"invalidCellSpacing\":\"Cellemarg må være et positivt tall.\",\"invalidCols\":\"Antall kolonner må være et tall større enn 0.\",\"invalidHeight\":\"Tabellhøyde må være et tall.\",\"invalidRows\":\"Antall rader må være et tall større enn 0.\",\"invalidWidth\":\"Tabellbredde må være et tall.\",\"menu\":\"Egenskaper for tabell\",\"row\":{\"menu\":\"Rader\",\"insertBefore\":\"Sett inn rad før\",\"insertAfter\":\"Sett inn rad etter\",\"deleteRow\":\"Slett rader\"},\"rows\":\"Rader\",\"summary\":\"Sammendrag\",\"title\":\"Egenskaper for tabell\",\"toolbar\":\"Tabell\",\"widthPc\":\"prosent\",\"widthPx\":\"piksler\",\"widthUnit\":\"Bredde-enhet\"},\"undo\":{\"redo\":\"Gjør om\",\"undo\":\"Angre\"},\"wsc\":{\"btnIgnore\":\"Ignorer\",\"btnIgnoreAll\":\"Ignorer alle\",\"btnReplace\":\"Erstatt\",\"btnReplaceAll\":\"Erstatt alle\",\"btnUndo\":\"Angre\",\"changeTo\":\"Endre til\",\"errorLoading\":\"Feil under lasting av applikasjonstjenestetjener: %s.\",\"ieSpellDownload\":\"Stavekontroll er ikke installert. Vil du laste den ned nå?\",\"manyChanges\":\"Stavekontroll fullført: %1 ord endret\",\"noChanges\":\"Stavekontroll fullført: ingen ord endret\",\"noMispell\":\"Stavekontroll fullført: ingen feilstavinger funnet\",\"noSuggestions\":\"- Ingen forslag -\",\"notAvailable\":\"Beklager, tjenesten er utilgjenglig nå.\",\"notInDic\":\"Ikke i ordboken\",\"oneChange\":\"Stavekontroll fullført: Ett ord endret\",\"progress\":\"Stavekontroll pågår...\",\"title\":\"Stavekontroll\",\"toolbar\":\"Stavekontroll\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/nl.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['nl']={\"editor\":\"Tekstverwerker\",\"editorPanel\":\"Tekstverwerker beheerpaneel\",\"common\":{\"editorHelp\":\"Druk ALT 0 voor hulp\",\"browseServer\":\"Bladeren op server\",\"url\":\"URL\",\"protocol\":\"Protocol\",\"upload\":\"Upload\",\"uploadSubmit\":\"Naar server verzenden\",\"image\":\"Afbeelding\",\"flash\":\"Flash\",\"form\":\"Formulier\",\"checkbox\":\"Selectievinkje\",\"radio\":\"Keuzerondje\",\"textField\":\"Tekstveld\",\"textarea\":\"Tekstvak\",\"hiddenField\":\"Verborgen veld\",\"button\":\"Knop\",\"select\":\"Selectieveld\",\"imageButton\":\"Afbeeldingsknop\",\"notSet\":\"<niet ingevuld>\",\"id\":\"Id\",\"name\":\"Naam\",\"langDir\":\"Schrijfrichting\",\"langDirLtr\":\"Links naar rechts (LTR)\",\"langDirRtl\":\"Rechts naar links (RTL)\",\"langCode\":\"Taalcode\",\"longDescr\":\"Lange URL-omschrijving\",\"cssClass\":\"Stylesheet-klassen\",\"advisoryTitle\":\"Adviserende titel\",\"cssStyle\":\"Stijl\",\"ok\":\"OK\",\"cancel\":\"Annuleren\",\"close\":\"Sluiten\",\"preview\":\"Voorbeeld\",\"resize\":\"Sleep om te herschalen\",\"generalTab\":\"Algemeen\",\"advancedTab\":\"Geavanceerd\",\"validateNumberFailed\":\"Deze waarde is geen geldig getal.\",\"confirmNewPage\":\"Alle aangebrachte wijzigingen gaan verloren. Weet u zeker dat u een nieuwe pagina wilt openen?\",\"confirmCancel\":\"Enkele opties zijn gewijzigd. Weet u zeker dat u dit dialoogvenster wilt sluiten?\",\"options\":\"Opties\",\"target\":\"Doelvenster\",\"targetNew\":\"Nieuw venster (_blank)\",\"targetTop\":\"Hele venster (_top)\",\"targetSelf\":\"Zelfde venster (_self)\",\"targetParent\":\"Origineel venster (_parent)\",\"langDirLTR\":\"Links naar rechts (LTR)\",\"langDirRTL\":\"Rechts naar links (RTL)\",\"styles\":\"Stijl\",\"cssClasses\":\"Stylesheet-klassen\",\"width\":\"Breedte\",\"height\":\"Hoogte\",\"align\":\"Uitlijning\",\"alignLeft\":\"Links\",\"alignRight\":\"Rechts\",\"alignCenter\":\"Centreren\",\"alignTop\":\"Boven\",\"alignMiddle\":\"Midden\",\"alignBottom\":\"Onder\",\"invalidValue\":\"Ongeldige waarde.\",\"invalidHeight\":\"De hoogte moet een getal zijn.\",\"invalidWidth\":\"De breedte moet een getal zijn.\",\"invalidCssLength\":\"Waarde in veld \\\"%1\\\" moet een positief nummer zijn, met of zonder een geldige CSS meeteenheid (px, %, in, cm, mm, em, ex, pt of pc).\",\"invalidHtmlLength\":\"Waarde in veld \\\"%1\\\" moet een positief nummer zijn, met of zonder een geldige HTML meeteenheid (px of %).\",\"invalidInlineStyle\":\"Waarde voor de online stijl moet bestaan uit een of meerdere tupels met het formaat \\\"naam : waarde\\\", gescheiden door puntkomma's.\",\"cssLengthTooltip\":\"Geef een nummer in voor een waarde in pixels of geef een nummer in met een geldige CSS eenheid (px, %, in, cm, mm, em, ex, pt, of pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, niet beschikbaar</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Alle rechten voorbehouden.\",\"dlgTitle\":\"Over CKEditor\",\"help\":\"Bekijk de $1 voor hulp.\",\"moreInfo\":\"Bezoek onze website voor licentieinformatie:\",\"title\":\"Over CKEditor\",\"userGuide\":\"CKEditor gebruiksaanwijzing\"},\"basicstyles\":{\"bold\":\"Vet\",\"italic\":\"Cursief\",\"strike\":\"Doorhalen\",\"subscript\":\"Subscript\",\"superscript\":\"Superscript\",\"underline\":\"Onderstrepen\"},\"blockquote\":{\"toolbar\":\"Citaatblok\"},\"clipboard\":{\"copy\":\"Kopiëren\",\"copyError\":\"De beveiligingsinstelling van de browser verhinderen het automatisch kopiëren. Gebruik de sneltoets Ctrl/Cmd+C van het toetsenbord.\",\"cut\":\"Knippen\",\"cutError\":\"De beveiligingsinstelling van de browser verhinderen het automatisch knippen. Gebruik de sneltoets Ctrl/Cmd+X van het toetsenbord.\",\"paste\":\"Plakken\",\"pasteArea\":\"Plakgebied\",\"pasteMsg\":\"Plak de tekst in het volgende vak gebruikmakend van uw toetsenbord (<strong>Ctrl/Cmd+V</strong>) en klik op OK.\",\"securityMsg\":\"Door de beveiligingsinstellingen van uw browser is het niet mogelijk om direct vanuit het klembord in de editor te plakken. Middels opnieuw plakken in dit venster kunt u de tekst alsnog plakken in de editor.\",\"title\":\"Plakken\"},\"contextmenu\":{\"options\":\"Contextmenu opties\"},\"toolbar\":{\"toolbarCollapse\":\"Werkbalk inklappen\",\"toolbarExpand\":\"Werkbalk uitklappen\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Klembord/Ongedaan maken\",\"editing\":\"Bewerken\",\"forms\":\"Formulieren\",\"basicstyles\":\"Basisstijlen\",\"paragraph\":\"Paragraaf\",\"links\":\"Links\",\"insert\":\"Invoegen\",\"styles\":\"Stijlen\",\"colors\":\"Kleuren\",\"tools\":\"Toepassingen\"},\"toolbars\":\"Werkbalken\"},\"elementspath\":{\"eleLabel\":\"Elementenpad\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Opmaak\",\"panelTitle\":\"Opmaak\",\"tag_address\":\"Adres\",\"tag_div\":\"Normaal (DIV)\",\"tag_h1\":\"Kop 1\",\"tag_h2\":\"Kop 2\",\"tag_h3\":\"Kop 3\",\"tag_h4\":\"Kop 4\",\"tag_h5\":\"Kop 5\",\"tag_h6\":\"Kop 6\",\"tag_p\":\"Normaal\",\"tag_pre\":\"Met opmaak\"},\"horizontalrule\":{\"toolbar\":\"Horizontale lijn invoegen\"},\"image\":{\"alertUrl\":\"Geef de URL van de afbeelding\",\"alt\":\"Alternatieve tekst\",\"border\":\"Rand\",\"btnUpload\":\"Naar server verzenden\",\"button2Img\":\"Wilt u de geselecteerde afbeeldingsknop vervangen door een eenvoudige afbeelding?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Wilt u de geselecteerde afbeelding vervangen door een afbeeldingsknop?\",\"infoTab\":\"Informatie afbeelding\",\"linkTab\":\"Link\",\"lockRatio\":\"Afmetingen vergrendelen\",\"menu\":\"Eigenschappen afbeelding\",\"resetSize\":\"Afmetingen resetten\",\"title\":\"Eigenschappen afbeelding\",\"titleButton\":\"Eigenschappen afbeeldingsknop\",\"upload\":\"Upload\",\"urlMissing\":\"De URL naar de afbeelding ontbreekt.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Rand moet een heel nummer zijn.\",\"validateHSpace\":\"HSpace moet een heel nummer zijn.\",\"validateVSpace\":\"VSpace moet een heel nummer zijn.\"},\"indent\":{\"indent\":\"Inspringing vergroten\",\"outdent\":\"Inspringing verkleinen\"},\"fakeobjects\":{\"anchor\":\"Interne link\",\"flash\":\"Flash animatie\",\"hiddenfield\":\"Verborgen veld\",\"iframe\":\"IFrame\",\"unknown\":\"Onbekend object\"},\"link\":{\"acccessKey\":\"Toegangstoets\",\"advanced\":\"Geavanceerd\",\"advisoryContentType\":\"Aanbevolen content-type\",\"advisoryTitle\":\"Adviserende titel\",\"anchor\":{\"toolbar\":\"Interne link\",\"menu\":\"Eigenschappen interne link\",\"title\":\"Eigenschappen interne link\",\"name\":\"Naam interne link\",\"errorName\":\"Geef de naam van de interne link op\",\"remove\":\"Interne link verwijderen\"},\"anchorId\":\"Op kenmerk interne link\",\"anchorName\":\"Op naam interne link\",\"charset\":\"Karakterset van gelinkte bron\",\"cssClasses\":\"Stylesheet-klassen\",\"emailAddress\":\"E-mailadres\",\"emailBody\":\"Inhoud bericht\",\"emailSubject\":\"Onderwerp bericht\",\"id\":\"Id\",\"info\":\"Linkomschrijving\",\"langCode\":\"Taalcode\",\"langDir\":\"Schrijfrichting\",\"langDirLTR\":\"Links naar rechts (LTR)\",\"langDirRTL\":\"Rechts naar links (RTL)\",\"menu\":\"Link wijzigen\",\"name\":\"Naam\",\"noAnchors\":\"(Geen interne links in document gevonden)\",\"noEmail\":\"Geef een e-mailadres\",\"noUrl\":\"Geef de link van de URL\",\"other\":\"<ander>\",\"popupDependent\":\"Afhankelijk (Netscape)\",\"popupFeatures\":\"Instellingen popupvenster\",\"popupFullScreen\":\"Volledig scherm (IE)\",\"popupLeft\":\"Positie links\",\"popupLocationBar\":\"Locatiemenu\",\"popupMenuBar\":\"Menubalk\",\"popupResizable\":\"Herschaalbaar\",\"popupScrollBars\":\"Schuifbalken\",\"popupStatusBar\":\"Statusbalk\",\"popupToolbar\":\"Werkbalk\",\"popupTop\":\"Positie boven\",\"rel\":\"Relatie\",\"selectAnchor\":\"Kies een interne link\",\"styles\":\"Stijl\",\"tabIndex\":\"Tabvolgorde\",\"target\":\"Doelvenster\",\"targetFrame\":\"<frame>\",\"targetFrameName\":\"Naam doelframe\",\"targetPopup\":\"<popupvenster>\",\"targetPopupName\":\"Naam popupvenster\",\"title\":\"Link\",\"toAnchor\":\"Interne link in pagina\",\"toEmail\":\"E-mail\",\"toUrl\":\"URL\",\"toolbar\":\"Link invoegen/wijzigen\",\"type\":\"Linktype\",\"unlink\":\"Link verwijderen\",\"upload\":\"Upload\"},\"list\":{\"bulletedlist\":\"Opsomming invoegen\",\"numberedlist\":\"Genummerde lijst invoegen\"},\"magicline\":{\"title\":\"Hier paragraaf invoeren\"},\"maximize\":{\"maximize\":\"Maximaliseren\",\"minimize\":\"Minimaliseren\"},\"pastetext\":{\"button\":\"Plakken als platte tekst\",\"title\":\"Plakken als platte tekst\"},\"pastefromword\":{\"confirmCleanup\":\"De tekst die u wilt plakken lijkt gekopieerd te zijn vanuit Word. Wilt u de tekst opschonen voordat deze geplakt wordt?\",\"error\":\"Het was niet mogelijk om de geplakte tekst op te schonen door een interne fout\",\"title\":\"Plakken vanuit Word\",\"toolbar\":\"Plakken vanuit Word\"},\"removeformat\":{\"toolbar\":\"Opmaak verwijderen\"},\"sourcearea\":{\"toolbar\":\"Broncode\"},\"specialchar\":{\"options\":\"Speciale tekens opties\",\"title\":\"Selecteer speciaal teken\",\"toolbar\":\"Speciaal teken invoegen\"},\"scayt\":{\"about\":\"Over SCAYT\",\"aboutTab\":\"Over\",\"addWord\":\"Woord toevoegen\",\"allCaps\":\"Negeer woorden helemaal in hoofdletters\",\"dic_create\":\"Aanmaken\",\"dic_delete\":\"Verwijderen\",\"dic_field_name\":\"Naam woordenboek\",\"dic_info\":\"Initieel wordt het gebruikerswoordenboek opgeslagen in een cookie. Cookies zijn echter beperkt in grootte. Zodra het gebruikerswoordenboek het punt bereikt waarop het niet meer in een cookie opgeslagen kan worden, dan wordt het woordenboek op de server opgeslagen. Om je persoonlijke woordenboek op je eigen server op te slaan, moet je een mapnaam opgeven. Indien je al een woordenboek hebt opgeslagen, typ dan de naam en klik op de Terugzetten knop.\",\"dic_rename\":\"Hernoemen\",\"dic_restore\":\"Terugzetten\",\"dictionariesTab\":\"Woordenboeken\",\"disable\":\"SCAYT uitschakelen\",\"emptyDic\":\"De naam van het woordenboek mag niet leeg zijn.\",\"enable\":\"SCAYT inschakelen\",\"ignore\":\"Negeren\",\"ignoreAll\":\"Alles negeren\",\"ignoreDomainNames\":\"Negeer domeinnamen\",\"langs\":\"Talen\",\"languagesTab\":\"Talen\",\"mixedCase\":\"Negeer woorden met hoofd- en kleine letters\",\"mixedWithDigits\":\"Negeer woorden met cijfers\",\"moreSuggestions\":\"Meer suggesties\",\"opera_title\":\"Niet ondersteund door Opera\",\"options\":\"Opties\",\"optionsTab\":\"Opties\",\"title\":\"Controleer de spelling tijdens het typen\",\"toggle\":\"SCAYT in/uitschakelen\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stijl\",\"panelTitle\":\"Opmaakstijlen\",\"panelTitle1\":\"Blok stijlen\",\"panelTitle2\":\"Inline stijlen\",\"panelTitle3\":\"Object stijlen\"},\"table\":{\"border\":\"Randdikte\",\"caption\":\"Onderschrift\",\"cell\":{\"menu\":\"Cel\",\"insertBefore\":\"Voeg cel in voor\",\"insertAfter\":\"Voeg cel in na\",\"deleteCell\":\"Cellen verwijderen\",\"merge\":\"Cellen samenvoegen\",\"mergeRight\":\"Voeg samen naar rechts\",\"mergeDown\":\"Voeg samen naar beneden\",\"splitHorizontal\":\"Splits cel horizontaal\",\"splitVertical\":\"Splits cel vertikaal\",\"title\":\"Celeigenschappen\",\"cellType\":\"Celtype\",\"rowSpan\":\"Rijen samenvoegen\",\"colSpan\":\"Kolommen samenvoegen\",\"wordWrap\":\"Automatische terugloop\",\"hAlign\":\"Horizontale uitlijning\",\"vAlign\":\"Verticale uitlijning\",\"alignBaseline\":\"Tekstregel\",\"bgColor\":\"Achtergrondkleur\",\"borderColor\":\"Randkleur\",\"data\":\"Gegevens\",\"header\":\"Kop\",\"yes\":\"Ja\",\"no\":\"Nee\",\"invalidWidth\":\"De celbreedte moet een getal zijn.\",\"invalidHeight\":\"De celhoogte moet een getal zijn.\",\"invalidRowSpan\":\"Rijen samenvoegen moet een heel getal zijn.\",\"invalidColSpan\":\"Kolommen samenvoegen moet een heel getal zijn.\",\"chooseColor\":\"Kies\"},\"cellPad\":\"Celopvulling\",\"cellSpace\":\"Celafstand\",\"column\":{\"menu\":\"Kolom\",\"insertBefore\":\"Voeg kolom in voor\",\"insertAfter\":\"Voeg kolom in na\",\"deleteColumn\":\"Kolommen verwijderen\"},\"columns\":\"Kolommen\",\"deleteTable\":\"Tabel verwijderen\",\"headers\":\"Koppen\",\"headersBoth\":\"Beide\",\"headersColumn\":\"Eerste kolom\",\"headersNone\":\"Geen\",\"headersRow\":\"Eerste rij\",\"invalidBorder\":\"De randdikte moet een getal zijn.\",\"invalidCellPadding\":\"Celopvulling moet een getal zijn.\",\"invalidCellSpacing\":\"Celafstand moet een getal zijn.\",\"invalidCols\":\"Het aantal kolommen moet een getal zijn groter dan 0.\",\"invalidHeight\":\"De tabelhoogte moet een getal zijn.\",\"invalidRows\":\"Het aantal rijen moet een getal zijn groter dan 0.\",\"invalidWidth\":\"De tabelbreedte moet een getal zijn.\",\"menu\":\"Tabeleigenschappen\",\"row\":{\"menu\":\"Rij\",\"insertBefore\":\"Voeg rij in voor\",\"insertAfter\":\"Voeg rij in na\",\"deleteRow\":\"Rijen verwijderen\"},\"rows\":\"Rijen\",\"summary\":\"Samenvatting\",\"title\":\"Tabeleigenschappen\",\"toolbar\":\"Tabel\",\"widthPc\":\"procent\",\"widthPx\":\"pixels\",\"widthUnit\":\"eenheid breedte\"},\"undo\":{\"redo\":\"Opnieuw uitvoeren\",\"undo\":\"Ongedaan maken\"},\"wsc\":{\"btnIgnore\":\"Negeren\",\"btnIgnoreAll\":\"Alles negeren\",\"btnReplace\":\"Vervangen\",\"btnReplaceAll\":\"Alles vervangen\",\"btnUndo\":\"Ongedaan maken\",\"changeTo\":\"Wijzig in\",\"errorLoading\":\"Er is een fout opgetreden bij het laden van de dienst: %s.\",\"ieSpellDownload\":\"De spellingscontrole is niet geïnstalleerd. Wilt u deze nu downloaden?\",\"manyChanges\":\"Klaar met spellingscontrole: %1 woorden aangepast\",\"noChanges\":\"Klaar met spellingscontrole: geen woorden aangepast\",\"noMispell\":\"Klaar met spellingscontrole: geen fouten gevonden\",\"noSuggestions\":\"- Geen suggesties -\",\"notAvailable\":\"Excuses, deze dienst is momenteel niet beschikbaar.\",\"notInDic\":\"Niet in het woordenboek\",\"oneChange\":\"Klaar met spellingscontrole: één woord aangepast\",\"progress\":\"Bezig met spellingscontrole...\",\"title\":\"Spellingscontrole\",\"toolbar\":\"Spellingscontrole\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/no.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['no']={\"editor\":\"Rikteksteditor\",\"editorPanel\":\"Panel for rikteksteditor\",\"common\":{\"editorHelp\":\"Trykk ALT 0 for hjelp\",\"browseServer\":\"Bla igjennom server\",\"url\":\"URL\",\"protocol\":\"Protokoll\",\"upload\":\"Last opp\",\"uploadSubmit\":\"Send det til serveren\",\"image\":\"Bilde\",\"flash\":\"Flash\",\"form\":\"Skjema\",\"checkbox\":\"Avmerkingsboks\",\"radio\":\"Alternativknapp\",\"textField\":\"Tekstboks\",\"textarea\":\"Tekstområde\",\"hiddenField\":\"Skjult felt\",\"button\":\"Knapp\",\"select\":\"Rullegardinliste\",\"imageButton\":\"Bildeknapp\",\"notSet\":\"<ikke satt>\",\"id\":\"Id\",\"name\":\"Navn\",\"langDir\":\"Språkretning\",\"langDirLtr\":\"Venstre til høyre (VTH)\",\"langDirRtl\":\"Høyre til venstre (HTV)\",\"langCode\":\"Språkkode\",\"longDescr\":\"Utvidet beskrivelse\",\"cssClass\":\"Stilarkklasser\",\"advisoryTitle\":\"Tittel\",\"cssStyle\":\"Stil\",\"ok\":\"OK\",\"cancel\":\"Avbryt\",\"close\":\"Lukk\",\"preview\":\"Forhåndsvis\",\"resize\":\"Dra for å skalere\",\"generalTab\":\"Generelt\",\"advancedTab\":\"Avansert\",\"validateNumberFailed\":\"Denne verdien er ikke et tall.\",\"confirmNewPage\":\"Alle ulagrede endringer som er gjort i dette innholdet vil bli tapt. Er du sikker på at du vil laste en ny side?\",\"confirmCancel\":\"Noen av valgene har blitt endret. Er du sikker på at du vil lukke dialogen?\",\"options\":\"Valg\",\"target\":\"Mål\",\"targetNew\":\"Nytt vindu (_blank)\",\"targetTop\":\"Hele vindu (_top)\",\"targetSelf\":\"Samme vindu (_self)\",\"targetParent\":\"Foreldrevindu (_parent)\",\"langDirLTR\":\"Venstre til høyre (VTH)\",\"langDirRTL\":\"Høyre til venstre (HTV)\",\"styles\":\"Stil\",\"cssClasses\":\"Stilarkklasser\",\"width\":\"Bredde\",\"height\":\"Høyde\",\"align\":\"Juster\",\"alignLeft\":\"Venstre\",\"alignRight\":\"Høyre\",\"alignCenter\":\"Midtjuster\",\"alignTop\":\"Topp\",\"alignMiddle\":\"Midten\",\"alignBottom\":\"Bunn\",\"invalidValue\":\"Ugyldig verdi.\",\"invalidHeight\":\"Høyde må være et tall.\",\"invalidWidth\":\"Bredde må være et tall.\",\"invalidCssLength\":\"Den angitte verdien for feltet \\\"%1\\\" må være et positivt tall med eller uten en gyldig CSS-målingsenhet (px, %, in, cm, mm, em, ex, pt, eller pc).\",\"invalidHtmlLength\":\"Den angitte verdien for feltet \\\"%1\\\" må være et positivt tall med eller uten en gyldig HTML-målingsenhet (px eller %).\",\"invalidInlineStyle\":\"Verdi angitt for inline stil må bestå av en eller flere sett med formatet \\\"navn : verdi\\\", separert med semikolon\",\"cssLengthTooltip\":\"Skriv inn et tall for en piksel-verdi eller et tall med en gyldig CSS-enhet (px, %, in, cm, mm, em, ex, pt, eller pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, utilgjenglig</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Alle rettigheter reservert.\",\"dlgTitle\":\"Om CKEditor\",\"help\":\"Se $1 for hjelp.\",\"moreInfo\":\"For lisensieringsinformasjon, vennligst besøk vårt nettsted:\",\"title\":\"Om CKEditor\",\"userGuide\":\"CKEditors brukerveiledning\"},\"basicstyles\":{\"bold\":\"Fet\",\"italic\":\"Kursiv\",\"strike\":\"Gjennomstreking\",\"subscript\":\"Senket skrift\",\"superscript\":\"Hevet skrift\",\"underline\":\"Understreking\"},\"blockquote\":{\"toolbar\":\"Blokksitat\"},\"clipboard\":{\"copy\":\"Kopier\",\"copyError\":\"Din nettlesers sikkerhetsinstillinger tillater ikke automatisk kopiering av tekst. Vennligst bruk snarveien (Ctrl/Cmd+C).\",\"cut\":\"Klipp ut\",\"cutError\":\"Din nettlesers sikkerhetsinstillinger tillater ikke automatisk utklipping av tekst. Vennligst bruk snarveien (Ctrl/Cmd+X).\",\"paste\":\"Lim inn\",\"pasteArea\":\"Innlimingsområde\",\"pasteMsg\":\"Vennligst lim inn i følgende boks med tastaturet (<STRONG>Ctrl/Cmd+V</STRONG>) og trykk <STRONG>OK</STRONG>.\",\"securityMsg\":\"Din nettlesers sikkerhetsinstillinger gir ikke redigeringsverktøyet direkte tilgang til utklippstavlen. Du må derfor lime det inn på nytt i dette vinduet.\",\"title\":\"Lim inn\"},\"contextmenu\":{\"options\":\"Alternativer for høyreklikkmeny\"},\"toolbar\":{\"toolbarCollapse\":\"Skjul verktøylinje\",\"toolbarExpand\":\"Vis verktøylinje\",\"toolbarGroups\":{\"document\":\"Dokument\",\"clipboard\":\"Utklippstavle/Angre\",\"editing\":\"Redigering\",\"forms\":\"Skjema\",\"basicstyles\":\"Basisstiler\",\"paragraph\":\"Avsnitt\",\"links\":\"Lenker\",\"insert\":\"Innsetting\",\"styles\":\"Stiler\",\"colors\":\"Farger\",\"tools\":\"Verktøy\"},\"toolbars\":\"Verktøylinjer for editor\"},\"elementspath\":{\"eleLabel\":\"Element-sti\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Avsnittsformat\",\"tag_address\":\"Adresse\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Overskrift 1\",\"tag_h2\":\"Overskrift 2\",\"tag_h3\":\"Overskrift 3\",\"tag_h4\":\"Overskrift 4\",\"tag_h5\":\"Overskrift 5\",\"tag_h6\":\"Overskrift 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatert\"},\"horizontalrule\":{\"toolbar\":\"Sett inn horisontal linje\"},\"image\":{\"alertUrl\":\"Vennligst skriv bilde-urlen\",\"alt\":\"Alternativ tekst\",\"border\":\"Ramme\",\"btnUpload\":\"Send det til serveren\",\"button2Img\":\"Vil du endre den valgte bildeknappen til et vanlig bilde?\",\"hSpace\":\"HMarg\",\"img2Button\":\"Vil du endre det valgte bildet til en bildeknapp?\",\"infoTab\":\"Bildeinformasjon\",\"linkTab\":\"Lenke\",\"lockRatio\":\"Lås forhold\",\"menu\":\"Bildeegenskaper\",\"resetSize\":\"Tilbakestill størrelse\",\"title\":\"Bildeegenskaper\",\"titleButton\":\"Egenskaper for bildeknapp\",\"upload\":\"Last opp\",\"urlMissing\":\"Bildets adresse mangler.\",\"vSpace\":\"VMarg\",\"validateBorder\":\"Ramme må være et heltall.\",\"validateHSpace\":\"HMarg må være et heltall.\",\"validateVSpace\":\"VMarg må være et heltall.\"},\"indent\":{\"indent\":\"Øk innrykk\",\"outdent\":\"Reduser innrykk\"},\"fakeobjects\":{\"anchor\":\"Anker\",\"flash\":\"Flash-animasjon\",\"hiddenfield\":\"Skjult felt\",\"iframe\":\"IFrame\",\"unknown\":\"Ukjent objekt\"},\"link\":{\"acccessKey\":\"Aksessknapp\",\"advanced\":\"Avansert\",\"advisoryContentType\":\"Type\",\"advisoryTitle\":\"Tittel\",\"anchor\":{\"toolbar\":\"Sett inn/Rediger anker\",\"menu\":\"Egenskaper for anker\",\"title\":\"Egenskaper for anker\",\"name\":\"Ankernavn\",\"errorName\":\"Vennligst skriv inn ankernavnet\",\"remove\":\"Fjern anker\"},\"anchorId\":\"Element etter ID\",\"anchorName\":\"Anker etter navn\",\"charset\":\"Lenket tegnsett\",\"cssClasses\":\"Stilarkklasser\",\"emailAddress\":\"E-postadresse\",\"emailBody\":\"Melding\",\"emailSubject\":\"Meldingsemne\",\"id\":\"Id\",\"info\":\"Lenkeinfo\",\"langCode\":\"Språkkode\",\"langDir\":\"Språkretning\",\"langDirLTR\":\"Venstre til høyre (VTH)\",\"langDirRTL\":\"Høyre til venstre (HTV)\",\"menu\":\"Rediger lenke\",\"name\":\"Navn\",\"noAnchors\":\"(Ingen anker i dokumentet)\",\"noEmail\":\"Vennligst skriv inn e-postadressen\",\"noUrl\":\"Vennligst skriv inn lenkens URL\",\"other\":\"<annen>\",\"popupDependent\":\"Avhenging (Netscape)\",\"popupFeatures\":\"Egenskaper for popup-vindu\",\"popupFullScreen\":\"Fullskjerm (IE)\",\"popupLeft\":\"Venstre posisjon\",\"popupLocationBar\":\"Adresselinje\",\"popupMenuBar\":\"Menylinje\",\"popupResizable\":\"Skalerbar\",\"popupScrollBars\":\"Scrollbar\",\"popupStatusBar\":\"Statuslinje\",\"popupToolbar\":\"Verktøylinje\",\"popupTop\":\"Topp-posisjon\",\"rel\":\"Relasjon (rel)\",\"selectAnchor\":\"Velg et anker\",\"styles\":\"Stil\",\"tabIndex\":\"Tabindeks\",\"target\":\"Mål\",\"targetFrame\":\"<ramme>\",\"targetFrameName\":\"Målramme\",\"targetPopup\":\"<popup-vindu>\",\"targetPopupName\":\"Navn på popup-vindu\",\"title\":\"Lenke\",\"toAnchor\":\"Lenke til anker i teksten\",\"toEmail\":\"E-post\",\"toUrl\":\"URL\",\"toolbar\":\"Sett inn/Rediger lenke\",\"type\":\"Lenketype\",\"unlink\":\"Fjern lenke\",\"upload\":\"Last opp\"},\"list\":{\"bulletedlist\":\"Legg til/Fjern punktmerket liste\",\"numberedlist\":\"Legg til/Fjern nummerert liste\"},\"magicline\":{\"title\":\"Sett inn nytt avsnitt her\"},\"maximize\":{\"maximize\":\"Maksimer\",\"minimize\":\"Minimer\"},\"pastetext\":{\"button\":\"Lim inn som ren tekst\",\"title\":\"Lim inn som ren tekst\"},\"pastefromword\":{\"confirmCleanup\":\"Teksten du limer inn ser ut til å være kopiert fra Word. Vil du renske den før du limer den inn?\",\"error\":\"Det var ikke mulig å renske den innlimte teksten på grunn av en intern feil\",\"title\":\"Lim inn fra Word\",\"toolbar\":\"Lim inn fra Word\"},\"removeformat\":{\"toolbar\":\"Fjern formatering\"},\"sourcearea\":{\"toolbar\":\"Kilde\"},\"specialchar\":{\"options\":\"Alternativer for spesialtegn\",\"title\":\"Velg spesialtegn\",\"toolbar\":\"Sett inn spesialtegn\"},\"scayt\":{\"about\":\"Om SCAYT\",\"aboutTab\":\"Om\",\"addWord\":\"Legg til ord\",\"allCaps\":\"Ikke kontroller ord med kun store bokstaver\",\"dic_create\":\"Opprett\",\"dic_delete\":\"Slett\",\"dic_field_name\":\"Ordboknavn\",\"dic_info\":\"Brukerordboken lagres først i en informasjonskapsel på din maskin, men det er en begrensning på hvor mye som kan lagres her. Når ordboken blir for stor til å lagres i en informasjonskapsel, vil vi i stedet lagre ordboken på vår server. For å lagre din personlige ordbok på vår server, burde du velge et navn for ordboken din. Hvis du allerede har lagret en ordbok, vennligst skriv inn ordbokens navn og klikk på Gjenopprett-knappen.\",\"dic_rename\":\"Gi nytt navn\",\"dic_restore\":\"Gjenopprett\",\"dictionariesTab\":\"Ordbøker\",\"disable\":\"Slå av SCAYT\",\"emptyDic\":\"Ordboknavn bør ikke være tom.\",\"enable\":\"Slå på SCAYT\",\"ignore\":\"Ignorer\",\"ignoreAll\":\"Ignorer Alle\",\"ignoreDomainNames\":\"Ikke kontroller domenenavn\",\"langs\":\"Språk\",\"languagesTab\":\"Språk\",\"mixedCase\":\"Ikke kontroller ord med blandet små og store bokstaver\",\"mixedWithDigits\":\"Ikke kontroller ord som inneholder tall\",\"moreSuggestions\":\"Flere forslag\",\"opera_title\":\"Ikke støttet av Opera\",\"options\":\"Valg\",\"optionsTab\":\"Valg\",\"title\":\"Stavekontroll mens du skriver\",\"toggle\":\"Veksle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stil\",\"panelTitle\":\"Stilformater\",\"panelTitle1\":\"Blokkstiler\",\"panelTitle2\":\"Inlinestiler\",\"panelTitle3\":\"Objektstiler\"},\"table\":{\"border\":\"Rammestørrelse\",\"caption\":\"Tittel\",\"cell\":{\"menu\":\"Celle\",\"insertBefore\":\"Sett inn celle før\",\"insertAfter\":\"Sett inn celle etter\",\"deleteCell\":\"Slett celler\",\"merge\":\"Slå sammen celler\",\"mergeRight\":\"Slå sammen høyre\",\"mergeDown\":\"Slå sammen ned\",\"splitHorizontal\":\"Del celle horisontalt\",\"splitVertical\":\"Del celle vertikalt\",\"title\":\"Celleegenskaper\",\"cellType\":\"Celletype\",\"rowSpan\":\"Radspenn\",\"colSpan\":\"Kolonnespenn\",\"wordWrap\":\"Tekstbrytning\",\"hAlign\":\"Horisontal justering\",\"vAlign\":\"Vertikal justering\",\"alignBaseline\":\"Grunnlinje\",\"bgColor\":\"Bakgrunnsfarge\",\"borderColor\":\"Rammefarge\",\"data\":\"Data\",\"header\":\"Overskrift\",\"yes\":\"Ja\",\"no\":\"Nei\",\"invalidWidth\":\"Cellebredde må være et tall.\",\"invalidHeight\":\"Cellehøyde må være et tall.\",\"invalidRowSpan\":\"Radspenn må være et heltall.\",\"invalidColSpan\":\"Kolonnespenn må være et heltall.\",\"chooseColor\":\"Velg\"},\"cellPad\":\"Cellepolstring\",\"cellSpace\":\"Cellemarg\",\"column\":{\"menu\":\"Kolonne\",\"insertBefore\":\"Sett inn kolonne før\",\"insertAfter\":\"Sett inn kolonne etter\",\"deleteColumn\":\"Slett kolonner\"},\"columns\":\"Kolonner\",\"deleteTable\":\"Slett tabell\",\"headers\":\"Overskrifter\",\"headersBoth\":\"Begge\",\"headersColumn\":\"Første kolonne\",\"headersNone\":\"Ingen\",\"headersRow\":\"Første rad\",\"invalidBorder\":\"Rammestørrelse må være et tall.\",\"invalidCellPadding\":\"Cellepolstring må være et positivt tall.\",\"invalidCellSpacing\":\"Cellemarg må være et positivt tall.\",\"invalidCols\":\"Antall kolonner må være et tall større enn 0.\",\"invalidHeight\":\"Tabellhøyde må være et tall.\",\"invalidRows\":\"Antall rader må være et tall større enn 0.\",\"invalidWidth\":\"Tabellbredde må være et tall.\",\"menu\":\"Egenskaper for tabell\",\"row\":{\"menu\":\"Rader\",\"insertBefore\":\"Sett inn rad før\",\"insertAfter\":\"Sett inn rad etter\",\"deleteRow\":\"Slett rader\"},\"rows\":\"Rader\",\"summary\":\"Sammendrag\",\"title\":\"Egenskaper for tabell\",\"toolbar\":\"Tabell\",\"widthPc\":\"prosent\",\"widthPx\":\"piksler\",\"widthUnit\":\"Bredde-enhet\"},\"undo\":{\"redo\":\"Gjør om\",\"undo\":\"Angre\"},\"wsc\":{\"btnIgnore\":\"Ignorer\",\"btnIgnoreAll\":\"Ignorer alle\",\"btnReplace\":\"Erstatt\",\"btnReplaceAll\":\"Erstatt alle\",\"btnUndo\":\"Angre\",\"changeTo\":\"Endre til\",\"errorLoading\":\"Feil under lasting av applikasjonstjenestetjener: %s.\",\"ieSpellDownload\":\"Stavekontroll er ikke installert. Vil du laste den ned nå?\",\"manyChanges\":\"Stavekontroll fullført: %1 ord endret\",\"noChanges\":\"Stavekontroll fullført: ingen ord endret\",\"noMispell\":\"Stavekontroll fullført: ingen feilstavinger funnet\",\"noSuggestions\":\"- Ingen forslag -\",\"notAvailable\":\"Beklager, tjenesten er utilgjenglig nå.\",\"notInDic\":\"Ikke i ordboken\",\"oneChange\":\"Stavekontroll fullført: Ett ord endret\",\"progress\":\"Stavekontroll pågår...\",\"title\":\"Stavekontroll\",\"toolbar\":\"Stavekontroll\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/pl.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['pl']={\"editor\":\"Edytor tekstu sformatowanego\",\"editorPanel\":\"Panel edytora tekstu sformatowanego\",\"common\":{\"editorHelp\":\"W celu uzyskania pomocy naciśnij ALT 0\",\"browseServer\":\"Przeglądaj\",\"url\":\"Adres URL\",\"protocol\":\"Protokół\",\"upload\":\"Wyślij\",\"uploadSubmit\":\"Wyślij\",\"image\":\"Obrazek\",\"flash\":\"Flash\",\"form\":\"Formularz\",\"checkbox\":\"Pole wyboru (checkbox)\",\"radio\":\"Przycisk opcji (radio)\",\"textField\":\"Pole tekstowe\",\"textarea\":\"Obszar tekstowy\",\"hiddenField\":\"Pole ukryte\",\"button\":\"Przycisk\",\"select\":\"Lista wyboru\",\"imageButton\":\"Przycisk graficzny\",\"notSet\":\"<nie ustawiono>\",\"id\":\"Id\",\"name\":\"Nazwa\",\"langDir\":\"Kierunek tekstu\",\"langDirLtr\":\"Od lewej do prawej (LTR)\",\"langDirRtl\":\"Od prawej do lewej (RTL)\",\"langCode\":\"Kod języka\",\"longDescr\":\"Adres URL długiego opisu\",\"cssClass\":\"Nazwa klasy CSS\",\"advisoryTitle\":\"Opis obiektu docelowego\",\"cssStyle\":\"Styl\",\"ok\":\"OK\",\"cancel\":\"Anuluj\",\"close\":\"Zamknij\",\"preview\":\"Podgląd\",\"resize\":\"Przeciągnij, aby zmienić rozmiar\",\"generalTab\":\"Ogólne\",\"advancedTab\":\"Zaawansowane\",\"validateNumberFailed\":\"Ta wartość nie jest liczbą.\",\"confirmNewPage\":\"Wszystkie niezapisane zmiany zostaną utracone. Czy na pewno wczytać nową stronę?\",\"confirmCancel\":\"Pewne opcje zostały zmienione. Czy na pewno zamknąć okno dialogowe?\",\"options\":\"Opcje\",\"target\":\"Obiekt docelowy\",\"targetNew\":\"Nowe okno (_blank)\",\"targetTop\":\"Okno najwyżej w hierarchii (_top)\",\"targetSelf\":\"To samo okno (_self)\",\"targetParent\":\"Okno nadrzędne (_parent)\",\"langDirLTR\":\"Od lewej do prawej (LTR)\",\"langDirRTL\":\"Od prawej do lewej (RTL)\",\"styles\":\"Style\",\"cssClasses\":\"Klasy arkusza stylów\",\"width\":\"Szerokość\",\"height\":\"Wysokość\",\"align\":\"Wyrównaj\",\"alignLeft\":\"Do lewej\",\"alignRight\":\"Do prawej\",\"alignCenter\":\"Do środka\",\"alignTop\":\"Do góry\",\"alignMiddle\":\"Do środka\",\"alignBottom\":\"Do dołu\",\"invalidValue\":\"Nieprawidłowa wartość.\",\"invalidHeight\":\"Wysokość musi być liczbą.\",\"invalidWidth\":\"Szerokość musi być liczbą.\",\"invalidCssLength\":\"Wartość podana dla pola \\\"%1\\\" musi być liczbą dodatnią bez jednostki lub z poprawną jednostką długości zgodną z CSS (px, %, in, cm, mm, em, ex, pt lub pc).\",\"invalidHtmlLength\":\"Wartość podana dla pola \\\"%1\\\" musi być liczbą dodatnią bez jednostki lub z poprawną jednostką długości zgodną z HTML (px lub %).\",\"invalidInlineStyle\":\"Wartość podana dla stylu musi składać się z jednej lub większej liczby krotek w formacie \\\"nazwa : wartość\\\", rozdzielonych średnikami.\",\"cssLengthTooltip\":\"Wpisz liczbę dla wartości w pikselach lub liczbę wraz z jednostką długości zgodną z CSS (px, %, in, cm, mm, em, ex, pt lub pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, niedostępne</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Wszelkie prawa zastrzeżone.\",\"dlgTitle\":\"Informacje o programie CKEditor\",\"help\":\"Pomoc znajdziesz w $1.\",\"moreInfo\":\"Informacje na temat licencji można znaleźć na naszej stronie:\",\"title\":\"Informacje o programie CKEditor\",\"userGuide\":\"podręczniku użytkownika programu CKEditor\"},\"basicstyles\":{\"bold\":\"Pogrubienie\",\"italic\":\"Kursywa\",\"strike\":\"Przekreślenie\",\"subscript\":\"Indeks dolny\",\"superscript\":\"Indeks górny\",\"underline\":\"Podkreślenie\"},\"blockquote\":{\"toolbar\":\"Cytat\"},\"clipboard\":{\"copy\":\"Kopiuj\",\"copyError\":\"Ustawienia bezpieczeństwa Twojej przeglądarki nie pozwalają na automatyczne kopiowanie tekstu. Użyj skrótu klawiszowego Ctrl/Cmd+C.\",\"cut\":\"Wytnij\",\"cutError\":\"Ustawienia bezpieczeństwa Twojej przeglądarki nie pozwalają na automatyczne wycinanie tekstu. Użyj skrótu klawiszowego Ctrl/Cmd+X.\",\"paste\":\"Wklej\",\"pasteArea\":\"Obszar wklejania\",\"pasteMsg\":\"Wklej tekst w poniższym polu, używając skrótu klawiaturowego (<STRONG>Ctrl/Cmd+V</STRONG>), i kliknij <STRONG>OK</STRONG>.\",\"securityMsg\":\"Zabezpieczenia przeglądarki uniemożliwiają wklejenie danych bezpośrednio do edytora. Proszę ponownie wkleić dane w tym oknie.\",\"title\":\"Wklej\"},\"contextmenu\":{\"options\":\"Opcje menu kontekstowego\"},\"toolbar\":{\"toolbarCollapse\":\"Zwiń pasek narzędzi\",\"toolbarExpand\":\"Rozwiń pasek narzędzi\",\"toolbarGroups\":{\"document\":\"Dokument\",\"clipboard\":\"Schowek/Wstecz\",\"editing\":\"Edycja\",\"forms\":\"Formularze\",\"basicstyles\":\"Style podstawowe\",\"paragraph\":\"Akapit\",\"links\":\"Hiperłącza\",\"insert\":\"Wstawianie\",\"styles\":\"Style\",\"colors\":\"Kolory\",\"tools\":\"Narzędzia\"},\"toolbars\":\"Paski narzędzi edytora\"},\"elementspath\":{\"eleLabel\":\"Ścieżka elementów\",\"eleTitle\":\"element %1\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Format\",\"tag_address\":\"Adres\",\"tag_div\":\"Normalny (DIV)\",\"tag_h1\":\"Nagłówek 1\",\"tag_h2\":\"Nagłówek 2\",\"tag_h3\":\"Nagłówek 3\",\"tag_h4\":\"Nagłówek 4\",\"tag_h5\":\"Nagłówek 5\",\"tag_h6\":\"Nagłówek 6\",\"tag_p\":\"Normalny\",\"tag_pre\":\"Tekst sformatowany\"},\"horizontalrule\":{\"toolbar\":\"Wstaw poziomą linię\"},\"image\":{\"alertUrl\":\"Podaj adres obrazka.\",\"alt\":\"Tekst zastępczy\",\"border\":\"Obramowanie\",\"btnUpload\":\"Wyślij\",\"button2Img\":\"Czy chcesz przekonwertować zaznaczony przycisk graficzny do zwykłego obrazka?\",\"hSpace\":\"Odstęp poziomy\",\"img2Button\":\"Czy chcesz przekonwertować zaznaczony obrazek do przycisku graficznego?\",\"infoTab\":\"Informacje o obrazku\",\"linkTab\":\"Hiperłącze\",\"lockRatio\":\"Zablokuj proporcje\",\"menu\":\"Właściwości obrazka\",\"resetSize\":\"Przywróć rozmiar\",\"title\":\"Właściwości obrazka\",\"titleButton\":\"Właściwości przycisku graficznego\",\"upload\":\"Wyślij\",\"urlMissing\":\"Podaj adres URL obrazka.\",\"vSpace\":\"Odstęp pionowy\",\"validateBorder\":\"Wartość obramowania musi być liczbą całkowitą.\",\"validateHSpace\":\"Wartość odstępu poziomego musi być liczbą całkowitą.\",\"validateVSpace\":\"Wartość odstępu pionowego musi być liczbą całkowitą.\"},\"indent\":{\"indent\":\"Zwiększ wcięcie\",\"outdent\":\"Zmniejsz wcięcie\"},\"fakeobjects\":{\"anchor\":\"Kotwica\",\"flash\":\"Animacja Flash\",\"hiddenfield\":\"Pole ukryte\",\"iframe\":\"IFrame\",\"unknown\":\"Nieznany obiekt\"},\"link\":{\"acccessKey\":\"Klawisz dostępu\",\"advanced\":\"Zaawansowane\",\"advisoryContentType\":\"Typ MIME obiektu docelowego\",\"advisoryTitle\":\"Opis obiektu docelowego\",\"anchor\":{\"toolbar\":\"Wstaw/edytuj kotwicę\",\"menu\":\"Właściwości kotwicy\",\"title\":\"Właściwości kotwicy\",\"name\":\"Nazwa kotwicy\",\"errorName\":\"Wpisz nazwę kotwicy\",\"remove\":\"Usuń kotwicę\"},\"anchorId\":\"Wg identyfikatora\",\"anchorName\":\"Wg nazwy\",\"charset\":\"Kodowanie znaków obiektu docelowego\",\"cssClasses\":\"Nazwa klasy CSS\",\"emailAddress\":\"Adres e-mail\",\"emailBody\":\"Treść\",\"emailSubject\":\"Temat\",\"id\":\"Id\",\"info\":\"Informacje \",\"langCode\":\"Kod języka\",\"langDir\":\"Kierunek tekstu\",\"langDirLTR\":\"Od lewej do prawej (LTR)\",\"langDirRTL\":\"Od prawej do lewej (RTL)\",\"menu\":\"Edytuj odnośnik\",\"name\":\"Nazwa\",\"noAnchors\":\"(W dokumencie nie zdefiniowano żadnych kotwic)\",\"noEmail\":\"Podaj adres e-mail\",\"noUrl\":\"Podaj adres URL\",\"other\":\"<inny>\",\"popupDependent\":\"Okno zależne (Netscape)\",\"popupFeatures\":\"Właściwości wyskakującego okna\",\"popupFullScreen\":\"Pełny ekran (IE)\",\"popupLeft\":\"Pozycja w poziomie\",\"popupLocationBar\":\"Pasek adresu\",\"popupMenuBar\":\"Pasek menu\",\"popupResizable\":\"Skalowalny\",\"popupScrollBars\":\"Paski przewijania\",\"popupStatusBar\":\"Pasek statusu\",\"popupToolbar\":\"Pasek narzędzi\",\"popupTop\":\"Pozycja w pionie\",\"rel\":\"Relacja\",\"selectAnchor\":\"Wybierz kotwicę\",\"styles\":\"Styl\",\"tabIndex\":\"Indeks kolejności\",\"target\":\"Obiekt docelowy\",\"targetFrame\":\"<ramka>\",\"targetFrameName\":\"Nazwa ramki docelowej\",\"targetPopup\":\"<wyskakujące okno>\",\"targetPopupName\":\"Nazwa wyskakującego okna\",\"title\":\"Odnośnik\",\"toAnchor\":\"Odnośnik wewnątrz strony (kotwica)\",\"toEmail\":\"Adres e-mail\",\"toUrl\":\"Adres URL\",\"toolbar\":\"Wstaw/edytuj odnośnik\",\"type\":\"Typ odnośnika\",\"unlink\":\"Usuń odnośnik\",\"upload\":\"Wyślij\"},\"list\":{\"bulletedlist\":\"Lista wypunktowana\",\"numberedlist\":\"Lista numerowana\"},\"magicline\":{\"title\":\"Wstaw nowy akapit\"},\"maximize\":{\"maximize\":\"Maksymalizuj\",\"minimize\":\"Minimalizuj\"},\"pastetext\":{\"button\":\"Wklej jako czysty tekst\",\"title\":\"Wklej jako czysty tekst\"},\"pastefromword\":{\"confirmCleanup\":\"Tekst, który chcesz wkleić, prawdopodobnie pochodzi z programu Microsoft Word. Czy chcesz go wyczyścić przed wklejeniem?\",\"error\":\"Wyczyszczenie wklejonych danych nie było możliwe z powodu wystąpienia błędu.\",\"title\":\"Wklej z programu MS Word\",\"toolbar\":\"Wklej z programu MS Word\"},\"removeformat\":{\"toolbar\":\"Usuń formatowanie\"},\"sourcearea\":{\"toolbar\":\"Źródło dokumentu\"},\"specialchar\":{\"options\":\"Opcje znaków specjalnych\",\"title\":\"Wybierz znak specjalny\",\"toolbar\":\"Wstaw znak specjalny\"},\"scayt\":{\"about\":\"Informacje o SCAYT\",\"aboutTab\":\"Informacje o SCAYT\",\"addWord\":\"Dodaj słowo\",\"allCaps\":\"Ignoruj wyrazy pisane dużymi literami\",\"dic_create\":\"Utwórz\",\"dic_delete\":\"Usuń\",\"dic_field_name\":\"Nazwa słownika\",\"dic_info\":\"Początkowo słownik użytkownika przechowywany jest w cookie. Pliki cookie mają jednak ograniczoną pojemność. Jeśli słownik użytkownika przekroczy wielkość dopuszczalną dla pliku cookie, możliwe jest przechowanie go na naszym serwerze. W celu zapisania słownika na serwerze niezbędne jest nadanie mu nazwy. Jeśli słownik został już zapisany na serwerze, wystarczy podać jego nazwę i nacisnąć przycisk Przywróć.\",\"dic_rename\":\"Zmień nazwę\",\"dic_restore\":\"Przywróć\",\"dictionariesTab\":\"Słowniki\",\"disable\":\"Wyłącz SCAYT\",\"emptyDic\":\"Nazwa słownika nie może być pusta.\",\"enable\":\"Włącz SCAYT\",\"ignore\":\"Ignoruj\",\"ignoreAll\":\"Ignoruj wszystkie\",\"ignoreDomainNames\":\"Ignoruj nazwy domen\",\"langs\":\"Języki\",\"languagesTab\":\"Języki\",\"mixedCase\":\"Ignoruj wyrazy pisane dużymi i małymi literami\",\"mixedWithDigits\":\"Ignoruj wyrazy zawierające cyfry\",\"moreSuggestions\":\"Więcej sugestii\",\"opera_title\":\"Funkcja nie jest obsługiwana przez przeglądarkę Opera\",\"options\":\"Opcje\",\"optionsTab\":\"Opcje\",\"title\":\"Sprawdź pisownię podczas pisania (SCAYT)\",\"toggle\":\"Przełącz SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Styl\",\"panelTitle\":\"Style formatujące\",\"panelTitle1\":\"Style blokowe\",\"panelTitle2\":\"Style liniowe\",\"panelTitle3\":\"Style obiektowe\"},\"table\":{\"border\":\"Grubość obramowania\",\"caption\":\"Tytuł\",\"cell\":{\"menu\":\"Komórka\",\"insertBefore\":\"Wstaw komórkę z lewej\",\"insertAfter\":\"Wstaw komórkę z prawej\",\"deleteCell\":\"Usuń komórki\",\"merge\":\"Połącz komórki\",\"mergeRight\":\"Połącz z komórką z prawej\",\"mergeDown\":\"Połącz z komórką poniżej\",\"splitHorizontal\":\"Podziel komórkę poziomo\",\"splitVertical\":\"Podziel komórkę pionowo\",\"title\":\"Właściwości komórki\",\"cellType\":\"Typ komórki\",\"rowSpan\":\"Scalenie wierszy\",\"colSpan\":\"Scalenie komórek\",\"wordWrap\":\"Zawijanie słów\",\"hAlign\":\"Wyrównanie poziome\",\"vAlign\":\"Wyrównanie pionowe\",\"alignBaseline\":\"Linia bazowa\",\"bgColor\":\"Kolor tła\",\"borderColor\":\"Kolor obramowania\",\"data\":\"Dane\",\"header\":\"Nagłówek\",\"yes\":\"Tak\",\"no\":\"Nie\",\"invalidWidth\":\"Szerokość komórki musi być liczbą.\",\"invalidHeight\":\"Wysokość komórki musi być liczbą.\",\"invalidRowSpan\":\"Scalenie wierszy musi być liczbą całkowitą.\",\"invalidColSpan\":\"Scalenie komórek musi być liczbą całkowitą.\",\"chooseColor\":\"Wybierz\"},\"cellPad\":\"Dopełnienie komórek\",\"cellSpace\":\"Odstęp pomiędzy komórkami\",\"column\":{\"menu\":\"Kolumna\",\"insertBefore\":\"Wstaw kolumnę z lewej\",\"insertAfter\":\"Wstaw kolumnę z prawej\",\"deleteColumn\":\"Usuń kolumny\"},\"columns\":\"Liczba kolumn\",\"deleteTable\":\"Usuń tabelę\",\"headers\":\"Nagłówki\",\"headersBoth\":\"Oba\",\"headersColumn\":\"Pierwsza kolumna\",\"headersNone\":\"Brak\",\"headersRow\":\"Pierwszy wiersz\",\"invalidBorder\":\"Wartość obramowania musi być liczbą.\",\"invalidCellPadding\":\"Dopełnienie komórek musi być liczbą dodatnią.\",\"invalidCellSpacing\":\"Odstęp pomiędzy komórkami musi być liczbą dodatnią.\",\"invalidCols\":\"Liczba kolumn musi być większa niż 0.\",\"invalidHeight\":\"Wysokość tabeli musi być liczbą.\",\"invalidRows\":\"Liczba wierszy musi być większa niż 0.\",\"invalidWidth\":\"Szerokość tabeli musi być liczbą.\",\"menu\":\"Właściwości tabeli\",\"row\":{\"menu\":\"Wiersz\",\"insertBefore\":\"Wstaw wiersz powyżej\",\"insertAfter\":\"Wstaw wiersz poniżej\",\"deleteRow\":\"Usuń wiersze\"},\"rows\":\"Liczba wierszy\",\"summary\":\"Podsumowanie\",\"title\":\"Właściwości tabeli\",\"toolbar\":\"Tabela\",\"widthPc\":\"%\",\"widthPx\":\"piksele\",\"widthUnit\":\"jednostka szerokości\"},\"undo\":{\"redo\":\"Ponów\",\"undo\":\"Cofnij\"},\"wsc\":{\"btnIgnore\":\"Ignoruj\",\"btnIgnoreAll\":\"Ignoruj wszystkie\",\"btnReplace\":\"Zmień\",\"btnReplaceAll\":\"Zmień wszystkie\",\"btnUndo\":\"Cofnij\",\"changeTo\":\"Zmień na\",\"errorLoading\":\"Błąd wczytywania hosta aplikacji usługi: %s.\",\"ieSpellDownload\":\"Słownik nie jest zainstalowany. Czy chcesz go pobrać?\",\"manyChanges\":\"Sprawdzanie zakończone: zmieniono %l słów\",\"noChanges\":\"Sprawdzanie zakończone: nie zmieniono żadnego słowa\",\"noMispell\":\"Sprawdzanie zakończone: nie znaleziono błędów\",\"noSuggestions\":\"- Brak sugestii -\",\"notAvailable\":\"Przepraszamy, ale usługa jest obecnie niedostępna.\",\"notInDic\":\"Słowa nie ma w słowniku\",\"oneChange\":\"Sprawdzanie zakończone: zmieniono jedno słowo\",\"progress\":\"Trwa sprawdzanie...\",\"title\":\"Sprawdź pisownię\",\"toolbar\":\"Sprawdź pisownię\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/pt-br.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['pt-br']={\"editor\":\"Editor de Rich Text\",\"editorPanel\":\"Painel do editor de Rich Text\",\"common\":{\"editorHelp\":\"Pressione ALT+0 para ajuda\",\"browseServer\":\"Localizar no Servidor\",\"url\":\"URL\",\"protocol\":\"Protocolo\",\"upload\":\"Enviar ao Servidor\",\"uploadSubmit\":\"Enviar para o Servidor\",\"image\":\"Imagem\",\"flash\":\"Flash\",\"form\":\"Formulário\",\"checkbox\":\"Caixa de Seleção\",\"radio\":\"Botão de Opção\",\"textField\":\"Caixa de Texto\",\"textarea\":\"Área de Texto\",\"hiddenField\":\"Campo Oculto\",\"button\":\"Botão\",\"select\":\"Caixa de Listagem\",\"imageButton\":\"Botão de Imagem\",\"notSet\":\"<não ajustado>\",\"id\":\"Id\",\"name\":\"Nome\",\"langDir\":\"Direção do idioma\",\"langDirLtr\":\"Esquerda para Direita (LTR)\",\"langDirRtl\":\"Direita para Esquerda (RTL)\",\"langCode\":\"Idioma\",\"longDescr\":\"Descrição da URL\",\"cssClass\":\"Classe de CSS\",\"advisoryTitle\":\"Título\",\"cssStyle\":\"Estilos\",\"ok\":\"OK\",\"cancel\":\"Cancelar\",\"close\":\"Fechar\",\"preview\":\"Visualizar\",\"resize\":\"Arraste para redimensionar\",\"generalTab\":\"Geral\",\"advancedTab\":\"Avançado\",\"validateNumberFailed\":\"Este valor não é um número.\",\"confirmNewPage\":\"Todas as mudanças não salvas serão perdidas. Tem certeza de que quer abrir uma nova página?\",\"confirmCancel\":\"Algumas opções foram alteradas. Tem certeza de que quer fechar a caixa de diálogo?\",\"options\":\"Opções\",\"target\":\"Destino\",\"targetNew\":\"Nova Janela (_blank)\",\"targetTop\":\"Janela de Cima (_top)\",\"targetSelf\":\"Mesma Janela (_self)\",\"targetParent\":\"Janela Pai (_parent)\",\"langDirLTR\":\"Esquerda para Direita (LTR)\",\"langDirRTL\":\"Direita para Esquerda (RTL)\",\"styles\":\"Estilo\",\"cssClasses\":\"Classes\",\"width\":\"Largura\",\"height\":\"Altura\",\"align\":\"Alinhamento\",\"alignLeft\":\"Esquerda\",\"alignRight\":\"Direita\",\"alignCenter\":\"Centralizado\",\"alignTop\":\"Superior\",\"alignMiddle\":\"Centralizado\",\"alignBottom\":\"Inferior\",\"invalidValue\":\"Valor inválido.\",\"invalidHeight\":\"A altura tem que ser um número\",\"invalidWidth\":\"A largura tem que ser um número.\",\"invalidCssLength\":\"O valor do campo \\\"%1\\\" deve ser um número positivo opcionalmente seguido por uma válida unidade de medida de CSS (px, %, in, cm, mm, em, ex, pt ou pc).\",\"invalidHtmlLength\":\"O valor do campo \\\"%1\\\" deve ser um número positivo opcionalmente seguido por uma válida unidade de medida de HTML (px ou %).\",\"invalidInlineStyle\":\"O valor válido para estilo deve conter uma ou mais tuplas no formato \\\"nome : valor\\\", separados por ponto e vírgula.\",\"cssLengthTooltip\":\"Insira um número para valor em pixels ou um número seguido de uma válida unidade de medida de CSS (px, %, in, cm, mm, em, ex, pt ou pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, indisponível</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Todos os direitos reservados.\",\"dlgTitle\":\"Sobre o CKEditor\",\"help\":\"Verifique o $1 para obter ajuda.\",\"moreInfo\":\"Para informações sobre a licença por favor visite o nosso site:\",\"title\":\"Sobre o CKEditor\",\"userGuide\":\"Guia do Usuário do CKEditor\"},\"basicstyles\":{\"bold\":\"Negrito\",\"italic\":\"Itálico\",\"strike\":\"Tachado\",\"subscript\":\"Subscrito\",\"superscript\":\"Sobrescrito\",\"underline\":\"Sublinhado\"},\"blockquote\":{\"toolbar\":\"Citação\"},\"clipboard\":{\"copy\":\"Copiar\",\"copyError\":\"As configurações de segurança do seu navegador não permitem que o editor execute operações de copiar automaticamente. Por favor, utilize o teclado para copiar (Ctrl/Cmd+C).\",\"cut\":\"Recortar\",\"cutError\":\"As configurações de segurança do seu navegador não permitem que o editor execute operações de recortar automaticamente. Por favor, utilize o teclado para recortar (Ctrl/Cmd+X).\",\"paste\":\"Colar\",\"pasteArea\":\"Área para Colar\",\"pasteMsg\":\"Transfira o link usado na caixa usando o teclado com (<STRONG>Ctrl/Cmd+V</STRONG>) e <STRONG>OK</STRONG>.\",\"securityMsg\":\"As configurações de segurança do seu navegador não permitem que o editor acesse os dados da área de transferência diretamente. Por favor cole o conteúdo manualmente nesta janela.\",\"title\":\"Colar\"},\"contextmenu\":{\"options\":\"Opções Menu de Contexto\"},\"toolbar\":{\"toolbarCollapse\":\"Diminuir Barra de Ferramentas\",\"toolbarExpand\":\"Aumentar Barra de Ferramentas\",\"toolbarGroups\":{\"document\":\"Documento\",\"clipboard\":\"Clipboard/Desfazer\",\"editing\":\"Edição\",\"forms\":\"Formulários\",\"basicstyles\":\"Estilos Básicos\",\"paragraph\":\"Paragrafo\",\"links\":\"Links\",\"insert\":\"Inserir\",\"styles\":\"Estilos\",\"colors\":\"Cores\",\"tools\":\"Ferramentas\"},\"toolbars\":\"Barra de Ferramentas do Editor\"},\"elementspath\":{\"eleLabel\":\"Caminho dos Elementos\",\"eleTitle\":\"Elemento %1\"},\"format\":{\"label\":\"Formatação\",\"panelTitle\":\"Formatação\",\"tag_address\":\"Endereço\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Título 1\",\"tag_h2\":\"Título 2\",\"tag_h3\":\"Título 3\",\"tag_h4\":\"Título 4\",\"tag_h5\":\"Título 5\",\"tag_h6\":\"Título 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatado\"},\"horizontalrule\":{\"toolbar\":\"Inserir Linha Horizontal\"},\"image\":{\"alertUrl\":\"Por favor, digite a URL da imagem.\",\"alt\":\"Texto Alternativo\",\"border\":\"Borda\",\"btnUpload\":\"Enviar para o Servidor\",\"button2Img\":\"Deseja transformar o botão de imagem em uma imagem comum?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Deseja transformar a imagem em um botão de imagem?\",\"infoTab\":\"Informações da Imagem\",\"linkTab\":\"Link\",\"lockRatio\":\"Travar Proporções\",\"menu\":\"Formatar Imagem\",\"resetSize\":\"Redefinir para o Tamanho Original\",\"title\":\"Formatar Imagem\",\"titleButton\":\"Formatar Botão de Imagem\",\"upload\":\"Enviar\",\"urlMissing\":\"URL da imagem está faltando.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"A borda deve ser um número inteiro.\",\"validateHSpace\":\"O HSpace deve ser um número inteiro.\",\"validateVSpace\":\"O VSpace deve ser um número inteiro.\"},\"indent\":{\"indent\":\"Aumentar Recuo\",\"outdent\":\"Diminuir Recuo\"},\"fakeobjects\":{\"anchor\":\"Âncora\",\"flash\":\"Animação em Flash\",\"hiddenfield\":\"Campo Oculto\",\"iframe\":\"IFrame\",\"unknown\":\"Objeto desconhecido\"},\"link\":{\"acccessKey\":\"Chave de Acesso\",\"advanced\":\"Avançado\",\"advisoryContentType\":\"Tipo de Conteúdo\",\"advisoryTitle\":\"Título\",\"anchor\":{\"toolbar\":\"Inserir/Editar Âncora\",\"menu\":\"Formatar Âncora\",\"title\":\"Formatar Âncora\",\"name\":\"Nome da Âncora\",\"errorName\":\"Por favor, digite o nome da âncora\",\"remove\":\"Remover Âncora\"},\"anchorId\":\"Id da âncora\",\"anchorName\":\"Nome da âncora\",\"charset\":\"Charset do Link\",\"cssClasses\":\"Classe de CSS\",\"emailAddress\":\"Endereço E-Mail\",\"emailBody\":\"Corpo da Mensagem\",\"emailSubject\":\"Assunto da Mensagem\",\"id\":\"Id\",\"info\":\"Informações\",\"langCode\":\"Direção do idioma\",\"langDir\":\"Direção do idioma\",\"langDirLTR\":\"Esquerda para Direita (LTR)\",\"langDirRTL\":\"Direita para Esquerda (RTL)\",\"menu\":\"Editar Link\",\"name\":\"Nome\",\"noAnchors\":\"(Não há âncoras no documento)\",\"noEmail\":\"Por favor, digite o endereço de e-mail\",\"noUrl\":\"Por favor, digite o endereço do Link\",\"other\":\"<outro>\",\"popupDependent\":\"Dependente (Netscape)\",\"popupFeatures\":\"Propriedades da Janela Pop-up\",\"popupFullScreen\":\"Modo Tela Cheia (IE)\",\"popupLeft\":\"Esquerda\",\"popupLocationBar\":\"Barra de Endereços\",\"popupMenuBar\":\"Barra de Menus\",\"popupResizable\":\"Redimensionável\",\"popupScrollBars\":\"Barras de Rolagem\",\"popupStatusBar\":\"Barra de Status\",\"popupToolbar\":\"Barra de Ferramentas\",\"popupTop\":\"Topo\",\"rel\":\"Tipo de Relação\",\"selectAnchor\":\"Selecione uma âncora\",\"styles\":\"Estilos\",\"tabIndex\":\"Índice de Tabulação\",\"target\":\"Destino\",\"targetFrame\":\"<frame>\",\"targetFrameName\":\"Nome do Frame de Destino\",\"targetPopup\":\"<janela popup>\",\"targetPopupName\":\"Nome da Janela Pop-up\",\"title\":\"Editar Link\",\"toAnchor\":\"Âncora nesta página\",\"toEmail\":\"E-Mail\",\"toUrl\":\"URL\",\"toolbar\":\"Inserir/Editar Link\",\"type\":\"Tipo de hiperlink\",\"unlink\":\"Remover Link\",\"upload\":\"Enviar ao Servidor\"},\"list\":{\"bulletedlist\":\"Lista sem números\",\"numberedlist\":\"Lista numerada\"},\"magicline\":{\"title\":\"Insera um parágrafo aqui\"},\"maximize\":{\"maximize\":\"Maximizar\",\"minimize\":\"Minimize\"},\"pastetext\":{\"button\":\"Colar como Texto sem Formatação\",\"title\":\"Colar como Texto sem Formatação\"},\"pastefromword\":{\"confirmCleanup\":\"O texto que você deseja colar parece ter sido copiado do Word. Você gostaria de remover a formatação antes de colar?\",\"error\":\"Não foi possível limpar os dados colados devido a um erro interno\",\"title\":\"Colar do Word\",\"toolbar\":\"Colar do Word\"},\"removeformat\":{\"toolbar\":\"Remover Formatação\"},\"sourcearea\":{\"toolbar\":\"Código-Fonte\"},\"specialchar\":{\"options\":\"Opções de Caractere Especial\",\"title\":\"Selecione um Caractere Especial\",\"toolbar\":\"Inserir Caractere Especial\"},\"scayt\":{\"about\":\"Sobre a correção ortográfica durante a digitação\",\"aboutTab\":\"Sobre\",\"addWord\":\"Adicionar palavra\",\"allCaps\":\"Ignorar palavras maiúsculas\",\"dic_create\":\"Criar\",\"dic_delete\":\"Excluir\",\"dic_field_name\":\"Nome do Dicionário\",\"dic_info\":\"Inicialmente, o dicionário do usuário fica armazenado em um Cookie. Porém, Cookies tem tamanho limitado, portanto quand o dicionário do usuário atingir o tamanho limite poderá ser armazenado no nosso servidor. Para armazenar seu dicionário pessoal no nosso servidor deverá especificar um nome para ele. Se já tiver um dicionário armazenado por favor especifique o seu nome e clique em Restaurar.\",\"dic_rename\":\"Renomear\",\"dic_restore\":\"Restaurar\",\"dictionariesTab\":\"Dicionários\",\"disable\":\"Desabilitar correção ortográfica durante a digitação\",\"emptyDic\":\"O nome do dicionário não deveria estar vazio.\",\"enable\":\"Habilitar correção ortográfica durante a digitação\",\"ignore\":\"Ignorar\",\"ignoreAll\":\"Ignorar todas\",\"ignoreDomainNames\":\"Ignorar nomes de domínio\",\"langs\":\"Idiomas\",\"languagesTab\":\"Idiomas\",\"mixedCase\":\"Ignorar palavras com maiúsculas e minúsculas misturadas\",\"mixedWithDigits\":\"Ignorar palavras com números\",\"moreSuggestions\":\"Mais sugestões\",\"opera_title\":\"Não suportado no Opera\",\"options\":\"Opções\",\"optionsTab\":\"Opções\",\"title\":\"Correção ortográfica durante a digitação\",\"toggle\":\"Ativar/desativar correção ortográfica durante a digitação\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Estilo\",\"panelTitle\":\"Estilos de Formatação\",\"panelTitle1\":\"Estilos de bloco\",\"panelTitle2\":\"Estilos de texto corrido\",\"panelTitle3\":\"Estilos de objeto\"},\"table\":{\"border\":\"Borda\",\"caption\":\"Legenda\",\"cell\":{\"menu\":\"Célula\",\"insertBefore\":\"Inserir célula a esquerda\",\"insertAfter\":\"Inserir célula a direita\",\"deleteCell\":\"Remover Células\",\"merge\":\"Mesclar Células\",\"mergeRight\":\"Mesclar com célula a direita\",\"mergeDown\":\"Mesclar com célula abaixo\",\"splitHorizontal\":\"Dividir célula horizontalmente\",\"splitVertical\":\"Dividir célula verticalmente\",\"title\":\"Propriedades da célula\",\"cellType\":\"Tipo de célula\",\"rowSpan\":\"Linhas cobertas\",\"colSpan\":\"Colunas cobertas\",\"wordWrap\":\"Quebra de palavra\",\"hAlign\":\"Alinhamento horizontal\",\"vAlign\":\"Alinhamento vertical\",\"alignBaseline\":\"Patamar de alinhamento\",\"bgColor\":\"Cor de fundo\",\"borderColor\":\"Cor das bordas\",\"data\":\"Dados\",\"header\":\"Cabeçalho\",\"yes\":\"Sim\",\"no\":\"Não\",\"invalidWidth\":\"A largura da célula tem que ser um número.\",\"invalidHeight\":\"A altura da célula tem que ser um número.\",\"invalidRowSpan\":\"Linhas cobertas tem que ser um número inteiro.\",\"invalidColSpan\":\"Colunas cobertas tem que ser um número inteiro.\",\"chooseColor\":\"Escolher\"},\"cellPad\":\"Margem interna\",\"cellSpace\":\"Espaçamento\",\"column\":{\"menu\":\"Coluna\",\"insertBefore\":\"Inserir coluna a esquerda\",\"insertAfter\":\"Inserir coluna a direita\",\"deleteColumn\":\"Remover Colunas\"},\"columns\":\"Colunas\",\"deleteTable\":\"Apagar Tabela\",\"headers\":\"Cabeçalho\",\"headersBoth\":\"Ambos\",\"headersColumn\":\"Primeira coluna\",\"headersNone\":\"Nenhum\",\"headersRow\":\"Primeira linha\",\"invalidBorder\":\"O tamanho da borda tem que ser um número.\",\"invalidCellPadding\":\"A margem interna das células tem que ser um número.\",\"invalidCellSpacing\":\"O espaçamento das células tem que ser um número.\",\"invalidCols\":\"O número de colunas tem que ser um número maior que 0.\",\"invalidHeight\":\"A altura da tabela tem que ser um número.\",\"invalidRows\":\"O número de linhas tem que ser um número maior que 0.\",\"invalidWidth\":\"A largura da tabela tem que ser um número.\",\"menu\":\"Formatar Tabela\",\"row\":{\"menu\":\"Linha\",\"insertBefore\":\"Inserir linha acima\",\"insertAfter\":\"Inserir linha abaixo\",\"deleteRow\":\"Remover Linhas\"},\"rows\":\"Linhas\",\"summary\":\"Resumo\",\"title\":\"Formatar Tabela\",\"toolbar\":\"Tabela\",\"widthPc\":\"%\",\"widthPx\":\"pixels\",\"widthUnit\":\"unidade largura\"},\"undo\":{\"redo\":\"Refazer\",\"undo\":\"Desfazer\"},\"wsc\":{\"btnIgnore\":\"Ignorar uma vez\",\"btnIgnoreAll\":\"Ignorar Todas\",\"btnReplace\":\"Alterar\",\"btnReplaceAll\":\"Alterar Todas\",\"btnUndo\":\"Desfazer\",\"changeTo\":\"Alterar para\",\"errorLoading\":\"Erro carregando servidor de aplicação: %s.\",\"ieSpellDownload\":\"A verificação ortográfica não foi instalada. Você gostaria de realizar o download agora?\",\"manyChanges\":\"Verificação ortográfica encerrada: %1 palavras foram alteradas\",\"noChanges\":\"Verificação ortográfica encerrada: Não houve alterações\",\"noMispell\":\"Verificação encerrada: Não foram encontrados erros de ortografia\",\"noSuggestions\":\"-sem sugestões de ortografia-\",\"notAvailable\":\"Desculpe, o serviço não está disponível no momento.\",\"notInDic\":\"Não encontrada\",\"oneChange\":\"Verificação ortográfica encerrada: Uma palavra foi alterada\",\"progress\":\"Verificação ortográfica em andamento...\",\"title\":\"Corretor Ortográfico\",\"toolbar\":\"Verificar Ortografia\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/pt.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['pt']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Pressione ALT+0 para ajuda\",\"browseServer\":\"Explorar Servidor\",\"url\":\"URL\",\"protocol\":\"Protocolo\",\"upload\":\"Enviar\",\"uploadSubmit\":\"Enviar para o Servidor\",\"image\":\"Imagem\",\"flash\":\"Flash\",\"form\":\"Formulário\",\"checkbox\":\"Caixa de Seleção\",\"radio\":\"Botão de Opção\",\"textField\":\"Campo de Texto\",\"textarea\":\"Área de Texto\",\"hiddenField\":\"Campo Ocultado\",\"button\":\"Botão\",\"select\":\"Campo de Seleção\",\"imageButton\":\"Botão de Imagem\",\"notSet\":\"<Não definido>\",\"id\":\"Id.\",\"name\":\"Nome\",\"langDir\":\"Orientação do Idioma\",\"langDirLtr\":\"Esquerda para a Direita (EPD)\",\"langDirRtl\":\"Direita para a Esquerda (DPE)\",\"langCode\":\"Código de Idioma\",\"longDescr\":\"Descrição Completa do URL\",\"cssClass\":\"Classes de Estilo de Folhas\",\"advisoryTitle\":\"Título Consultivo\",\"cssStyle\":\"Estilo\",\"ok\":\"OK\",\"cancel\":\"Cancelar\",\"close\":\"Fechar\",\"preview\":\"Pré-visualização\",\"resize\":\"Redimensionar\",\"generalTab\":\"Geral\",\"advancedTab\":\"Avançado\",\"validateNumberFailed\":\"Este valor não é um numero.\",\"confirmNewPage\":\"Irão ser perdidas quaisquer alterações não guardadas. Tem certeza que deseja carregar a página nova?\",\"confirmCancel\":\"Foram alteradas algumas das opções. Tem a certeza que deseja fechar a janela?\",\"options\":\"Opções\",\"target\":\"Destino\",\"targetNew\":\"Nova Janela (_blank)\",\"targetTop\":\"Janela Superior (_top)\",\"targetSelf\":\"Mesma Janela (_self)\",\"targetParent\":\"Janela Parente (_parent)\",\"langDirLTR\":\"Esquerda para a Direita (EPD)\",\"langDirRTL\":\"Direita para a Esquerda (DPE)\",\"styles\":\"Estilo\",\"cssClasses\":\"Classes de Estilo de Folhas\",\"width\":\"Largura\",\"height\":\"Altura\",\"align\":\"Alinhamento\",\"alignLeft\":\"Esquerda\",\"alignRight\":\"Direita\",\"alignCenter\":\"Centrado\",\"alignTop\":\"Topo\",\"alignMiddle\":\"Centro\",\"alignBottom\":\"Fundo\",\"invalidValue\":\"Valor inválido.\",\"invalidHeight\":\"A altura tem de ser um número.\",\"invalidWidth\":\"A largura tem de ser um número. \",\"invalidCssLength\":\"Valor especificado para o campo \\\"1%\\\" deve ser um número positivo, com ou sem uma unidade de medida CSS válida (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Valor especificado para o campo \\\"1%\\\" deve ser um número positivo, com ou sem uma unidade de medida HTML válida (px ou %).\",\"invalidInlineStyle\":\"Valor especificado para o estilo em embutido deve ser constituído por uma ou mais tuplas com o formato de \\\"nome : valor\\\", separados por ponto e vírgula.\",\"cssLengthTooltip\":\"Digite um número para um valor em pixels ou um número com uma unidade CSS válida (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, indisponível</span>\"},\"about\":{\"copy\":\"Direitos de Autor &copy; $1. Todos os direitos reservados.\",\"dlgTitle\":\"Sobre o CKEditor\",\"help\":\"Doar $1 para ajudar.\",\"moreInfo\":\"Para informação sobre o licenciamento, visite o nosso site da web:\",\"title\":\"Sobre o CKEditor\",\"userGuide\":\"CKEditor - Guia do Utilizador\"},\"basicstyles\":{\"bold\":\"Negrito\",\"italic\":\"Itálico\",\"strike\":\"Rasurado\",\"subscript\":\"Superior à Linha\",\"superscript\":\"Inferior à Linha\",\"underline\":\"Sublinhado\"},\"blockquote\":{\"toolbar\":\"Bloco de citação\"},\"clipboard\":{\"copy\":\"Copiar\",\"copyError\":\"A configuração de segurança do navegador não permite a execução automática de operações de copiar. Por favor use o teclado (Ctrl/Cmd+C).\",\"cut\":\"Cortar\",\"cutError\":\"A configuração de segurança do navegador não permite a execução automática de operações de cortar. Por favor use o teclado (Ctrl/Cmd+X).\",\"paste\":\"Colar\",\"pasteArea\":\"Colar Área\",\"pasteMsg\":\"Por favor, cole dentro da seguinte caixa usando o teclado (<STRONG>Ctrl/Cmd+V</STRONG>) e prima <STRONG>OK</STRONG>.\",\"securityMsg\":\"Devido ás definições de segurança do teu browser, o editor não pode aceder ao clipboard diretamente. É necessário que voltes a colar as informações nesta janela.\",\"title\":\"Colar\"},\"contextmenu\":{\"options\":\"Menu de opções de contexto\"},\"toolbar\":{\"toolbarCollapse\":\"Colapsar Barra\",\"toolbarExpand\":\"Expandir Barra\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editor de barras de ferramentas\"},\"elementspath\":{\"eleLabel\":\"Camninho dos Elementos\",\"eleTitle\":\"Elemento %1\"},\"format\":{\"label\":\"Formatar\",\"panelTitle\":\"Formatar Parágrafo\",\"tag_address\":\"Endereço\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Título 1\",\"tag_h2\":\"Título 2\",\"tag_h3\":\"Título 3\",\"tag_h4\":\"Título 4\",\"tag_h5\":\"Título 5\",\"tag_h6\":\"Título 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatado\"},\"horizontalrule\":{\"toolbar\":\"Inserir Linha Horizontal\"},\"image\":{\"alertUrl\":\"Por favor introduza o URL da imagem\",\"alt\":\"Texto Alternativo\",\"border\":\"Limite\",\"btnUpload\":\"Enviar para o Servidor\",\"button2Img\":\"Deseja transformar o botão com imagem selecionado em uma imagem?\",\"hSpace\":\"Esp.Horiz\",\"img2Button\":\"Deseja transformar a imagem selecionada em um botão com imagem?\",\"infoTab\":\"Informação da Imagem\",\"linkTab\":\"Hiperligação\",\"lockRatio\":\"Proporcional\",\"menu\":\"Propriedades da Imagem\",\"resetSize\":\"Tamanho Original\",\"title\":\"Propriedades da Imagem\",\"titleButton\":\"Propriedades do Botão de imagens\",\"upload\":\"Carregar\",\"urlMissing\":\"O URL da fonte da imagem está em falta.\",\"vSpace\":\"Esp.Vert\",\"validateBorder\":\"A borda tem de ser um numero.\",\"validateHSpace\":\"HSpace tem de ser um numero.\",\"validateVSpace\":\"VSpace tem de ser um numero.\"},\"indent\":{\"indent\":\"Aumentar Avanço\",\"outdent\":\"Diminuir Avanço\"},\"fakeobjects\":{\"anchor\":\" Inserir/Editar Âncora\",\"flash\":\"Animação Flash\",\"hiddenfield\":\"Campo Ocultado\",\"iframe\":\"IFrame\",\"unknown\":\"Objeto Desconhecido\"},\"link\":{\"acccessKey\":\"Chave de Acesso\",\"advanced\":\"Avançado\",\"advisoryContentType\":\"Tipo de Conteúdo\",\"advisoryTitle\":\"Título\",\"anchor\":{\"toolbar\":\" Inserir/Editar Âncora\",\"menu\":\"Propriedades da Âncora\",\"title\":\"Propriedades da Âncora\",\"name\":\"Nome da Âncora\",\"errorName\":\"Por favor, introduza o nome da âncora\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"Por ID de elemento\",\"anchorName\":\"Por Nome de Referência\",\"charset\":\"Fonte de caracteres vinculado\",\"cssClasses\":\"Classes de Estilo de Folhas Classes\",\"emailAddress\":\"Endereço de E-Mail\",\"emailBody\":\"Corpo da Mensagem\",\"emailSubject\":\"Título de Mensagem\",\"id\":\"ID\",\"info\":\"Informação de Hiperligação\",\"langCode\":\"Orientação de idioma\",\"langDir\":\"Orientação de idioma\",\"langDirLTR\":\"Esquerda à Direita (LTR)\",\"langDirRTL\":\"Direita a Esquerda (RTL)\",\"menu\":\"Editar Hiperligação\",\"name\":\"Nome\",\"noAnchors\":\"(Não há referências disponíveis no documento)\",\"noEmail\":\"Por favor introduza o endereço de e-mail\",\"noUrl\":\"Por favor introduza a hiperligação URL\",\"other\":\"<outro>\",\"popupDependent\":\"Dependente (Netscape)\",\"popupFeatures\":\"Características de Janela de Popup\",\"popupFullScreen\":\"Janela Completa (IE)\",\"popupLeft\":\"Posição Esquerda\",\"popupLocationBar\":\"Barra de localização\",\"popupMenuBar\":\"Barra de Menu\",\"popupResizable\":\"Redimensionável\",\"popupScrollBars\":\"Barras de deslocamento\",\"popupStatusBar\":\"Barra de Estado\",\"popupToolbar\":\"Barra de Ferramentas\",\"popupTop\":\"Posição Direita\",\"rel\":\"Relação\",\"selectAnchor\":\"Seleccionar una referência\",\"styles\":\"Estilo\",\"tabIndex\":\"Índice de Tubulação\",\"target\":\"Destino\",\"targetFrame\":\"<Frame>\",\"targetFrameName\":\"Nome do Frame Destino\",\"targetPopup\":\"<Janela de popup>\",\"targetPopupName\":\"Nome da Janela de Popup\",\"title\":\"Hiperligação\",\"toAnchor\":\"Referência a esta página\",\"toEmail\":\"E-Mail\",\"toUrl\":\"URL\",\"toolbar\":\"Inserir/Editar Hiperligação\",\"type\":\"Tipo de Hiperligação\",\"unlink\":\"Eliminar Hiperligação\",\"upload\":\"Carregar\"},\"list\":{\"bulletedlist\":\"Marcas\",\"numberedlist\":\"Numeração\"},\"magicline\":{\"title\":\"Insira aqui o parágrafo\"},\"maximize\":{\"maximize\":\"Maximizar\",\"minimize\":\"Minimizar\"},\"pastetext\":{\"button\":\"Colar como Texto Simples\",\"title\":\"Colar como Texto Simples\"},\"pastefromword\":{\"confirmCleanup\":\"O texto que pretende colar parece ter sido copiado do Word. Deseja limpá-lo antes de colar?\",\"error\":\"Não foi possivel limpar a informação colada decido a um erro interno.\",\"title\":\"Colar do Word\",\"toolbar\":\"Colar do Word\"},\"removeformat\":{\"toolbar\":\"Eliminar Formato\"},\"sourcearea\":{\"toolbar\":\"Fonte\"},\"specialchar\":{\"options\":\"Opções de caracteres especiais\",\"title\":\"Selecione um caracter especial\",\"toolbar\":\"Inserir Caracter Especial\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Estilo\",\"panelTitle\":\"Estilos de Formatação\",\"panelTitle1\":\"Estilos de Bloco\",\"panelTitle2\":\"Estilos de Linha\",\"panelTitle3\":\"Estilos de Objeto\"},\"table\":{\"border\":\"Tamanho da Margem\",\"caption\":\"Título\",\"cell\":{\"menu\":\"Célula\",\"insertBefore\":\"Inserir Célula Antes\",\"insertAfter\":\"Inserir Célula Depois\",\"deleteCell\":\"Eliminar Célula\",\"merge\":\"Unir Células\",\"mergeRight\":\"Unir à Direita\",\"mergeDown\":\"Unir abaixo\",\"splitHorizontal\":\"Dividir Célula Horizontalmente\",\"splitVertical\":\"Dividir Célula Verticalmente\",\"title\":\"Propriedades da Célula\",\"cellType\":\"Tipo de Célula\",\"rowSpan\":\"Filas na Célula\",\"colSpan\":\"Colunas na Célula\",\"wordWrap\":\"Continuar\",\"hAlign\":\"Alinhamento Horizontal\",\"vAlign\":\"Alinhamento Vertical\",\"alignBaseline\":\"Base\",\"bgColor\":\"Cor de Fundo\",\"borderColor\":\"Cor da Margem\",\"data\":\"Dados\",\"header\":\"Cabeçalho\",\"yes\":\"Sim\",\"no\":\"Não\",\"invalidWidth\":\"A largura da célula deve ser um número.\",\"invalidHeight\":\"A altura da célula deve ser um número.\",\"invalidRowSpan\":\"As filas da célula deve ter um número inteiro.\",\"invalidColSpan\":\"As colunas da célula deve ter um número inteiro.\",\"chooseColor\":\"Escolher\"},\"cellPad\":\"Criação de Espaço\",\"cellSpace\":\"Espaçamento Célula\",\"column\":{\"menu\":\"Coluna\",\"insertBefore\":\"Inserir Coluna Antes\",\"insertAfter\":\"Inserir Coluna Depois\",\"deleteColumn\":\"Apagar Colunas\"},\"columns\":\"Colunas\",\"deleteTable\":\"Apagar Tabela\",\"headers\":\"Cabeçalhos\",\"headersBoth\":\"Ambos\",\"headersColumn\":\"Primeira coluna\",\"headersNone\":\"Nenhum\",\"headersRow\":\"Primeira Linha\",\"invalidBorder\":\"O tamanho da borda tem de ser um número.\",\"invalidCellPadding\":\"A criação do espaço na célula deve ser um número positivo.\",\"invalidCellSpacing\":\"O espaçamento da célula deve ser um número positivo.\",\"invalidCols\":\"O número de colunas tem de ser um número maior que 0.\",\"invalidHeight\":\"A altura da tabela tem de ser um número.\",\"invalidRows\":\"O número das linhas tem de ser um número maior que 0.\",\"invalidWidth\":\"A largura da tabela tem de ser um número.\",\"menu\":\"Propriedades da Tabela\",\"row\":{\"menu\":\"Linha\",\"insertBefore\":\"Inserir Linha Antes\",\"insertAfter\":\"Inserir Linha Depois\",\"deleteRow\":\"Apagar Linhas\"},\"rows\":\"Linhas\",\"summary\":\"Sumário\",\"title\":\"Propriedades da Tabela\",\"toolbar\":\"Tabela\",\"widthPc\":\"percentagem\",\"widthPx\":\"pixels\",\"widthUnit\":\"unidade da largura\"},\"undo\":{\"redo\":\"Repetir\",\"undo\":\"Anular\"},\"wsc\":{\"btnIgnore\":\"Ignorar\",\"btnIgnoreAll\":\"Ignorar Tudo\",\"btnReplace\":\"Substituir\",\"btnReplaceAll\":\"Substituir Tudo\",\"btnUndo\":\"Anular\",\"changeTo\":\"Mudar para\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\" Verificação ortográfica não instalada. Quer descarregar agora?\",\"manyChanges\":\"Verificação ortográfica completa: %1 palavras alteradas\",\"noChanges\":\"Verificação ortográfica completa: não houve alteração de palavras\",\"noMispell\":\"Verificação ortográfica completa: não foram encontrados erros\",\"noSuggestions\":\"- Sem sugestões -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Não está num directório\",\"oneChange\":\"Verificação ortográfica completa: uma palavra alterada\",\"progress\":\"Verificação ortográfica em progresso…\",\"title\":\"Spell Check\",\"toolbar\":\"Verificação Ortográfica\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/ro.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['ro']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Apasă ALT 0 pentru ajutor\",\"browseServer\":\"Răsfoieşte server\",\"url\":\"URL\",\"protocol\":\"Protocol\",\"upload\":\"Încarcă\",\"uploadSubmit\":\"Trimite la server\",\"image\":\"Imagine\",\"flash\":\"Flash\",\"form\":\"Formular (Form)\",\"checkbox\":\"Bifă (Checkbox)\",\"radio\":\"Buton radio (RadioButton)\",\"textField\":\"Câmp text (TextField)\",\"textarea\":\"Suprafaţă text (Textarea)\",\"hiddenField\":\"Câmp ascuns (HiddenField)\",\"button\":\"Buton\",\"select\":\"Câmp selecţie (SelectionField)\",\"imageButton\":\"Buton imagine (ImageButton)\",\"notSet\":\"<nesetat>\",\"id\":\"Id\",\"name\":\"Nume\",\"langDir\":\"Direcţia cuvintelor\",\"langDirLtr\":\"stânga-dreapta (LTR)\",\"langDirRtl\":\"dreapta-stânga (RTL)\",\"langCode\":\"Codul limbii\",\"longDescr\":\"Descrierea lungă URL\",\"cssClass\":\"Clasele cu stilul paginii (CSS)\",\"advisoryTitle\":\"Titlul consultativ\",\"cssStyle\":\"Stil\",\"ok\":\"OK\",\"cancel\":\"Anulare\",\"close\":\"Închide\",\"preview\":\"Previzualizare\",\"resize\":\"Trage pentru a redimensiona\",\"generalTab\":\"General\",\"advancedTab\":\"Avansat\",\"validateNumberFailed\":\"Această valoare nu este un număr.\",\"confirmNewPage\":\"Orice modificări nesalvate ale acestui conținut, vor fi pierdute. Sigur doriți încărcarea unei noi pagini?\",\"confirmCancel\":\"Câteva opțiuni au fost schimbate. Sigur doriți să închideți dialogul?\",\"options\":\"Opțiuni\",\"target\":\"Țintă\",\"targetNew\":\"Fereastră nouă (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"În aceeași fereastră (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"Stânga spre Dreapta (LTR)\",\"langDirRTL\":\"Dreapta spre Stânga (RTL)\",\"styles\":\"Stil\",\"cssClasses\":\"Stylesheet Classes\",\"width\":\"Lăţime\",\"height\":\"Înălţime\",\"align\":\"Aliniere\",\"alignLeft\":\"Mărește Bara\",\"alignRight\":\"Dreapta\",\"alignCenter\":\"Centru\",\"alignTop\":\"Sus\",\"alignMiddle\":\"Mijloc\",\"alignBottom\":\"Jos\",\"invalidValue\":\"Varloare invalida\",\"invalidHeight\":\"Înălțimea trebuie să fie un număr.\",\"invalidWidth\":\"Lățimea trebuie să fie un număr.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, nu este disponibil</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Îngroşat (bold)\",\"italic\":\"Înclinat (italic)\",\"strike\":\"Tăiat (strike through)\",\"subscript\":\"Indice (subscript)\",\"superscript\":\"Putere (superscript)\",\"underline\":\"Subliniat (underline)\"},\"blockquote\":{\"toolbar\":\"Citat\"},\"clipboard\":{\"copy\":\"Copiază\",\"copyError\":\"Setările de securitate ale navigatorului (browser) pe care îl folosiţi nu permit editorului să execute automat operaţiunea de copiere. Vă rugăm folosiţi tastatura (Ctrl/Cmd+C).\",\"cut\":\"Taie\",\"cutError\":\"Setările de securitate ale navigatorului (browser) pe care îl folosiţi nu permit editorului să execute automat operaţiunea de tăiere. Vă rugăm folosiţi tastatura (Ctrl/Cmd+X).\",\"paste\":\"Adaugă\",\"pasteArea\":\"Suprafața de adăugare\",\"pasteMsg\":\"Vă rugăm adăugaţi în căsuţa următoare folosind tastatura (<strong>Ctrl/Cmd+V</strong>) şi apăsaţi OK\",\"securityMsg\":\"Din cauza setărilor de securitate ale programului dvs. cu care navigaţi pe internet (browser), editorul nu poate accesa direct datele din clipboard. Va trebui să adăugaţi din nou datele în această fereastră.\",\"title\":\"Adaugă\"},\"contextmenu\":{\"options\":\"Opțiuni Meniu Contextual\"},\"toolbar\":{\"toolbarCollapse\":\"Micșorează Bara\",\"toolbarExpand\":\"Mărește Bara\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Editează bara de unelte\"},\"elementspath\":{\"eleLabel\":\"Calea elementelor\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Formatare\",\"panelTitle\":\"Formatare\",\"tag_address\":\"Adresă\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatat\"},\"horizontalrule\":{\"toolbar\":\"Inserează linie orizontală\"},\"image\":{\"alertUrl\":\"Vă rugăm să scrieţi URL-ul imaginii\",\"alt\":\"Text alternativ\",\"border\":\"Margine\",\"btnUpload\":\"Trimite la server\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"Informaţii despre imagine\",\"linkTab\":\"Link (Legătură web)\",\"lockRatio\":\"Păstrează proporţiile\",\"menu\":\"Proprietăţile imaginii\",\"resetSize\":\"Resetează mărimea\",\"title\":\"Proprietăţile imaginii\",\"titleButton\":\"Proprietăţi buton imagine (Image Button)\",\"upload\":\"Încarcă\",\"urlMissing\":\"Sursa URL a imaginii lipsește.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Bordura trebuie să fie un număr întreg.\",\"validateHSpace\":\"Hspace trebuie să fie un număr întreg.\",\"validateVSpace\":\"Vspace trebuie să fie un număr întreg.\"},\"indent\":{\"indent\":\"Creşte indentarea\",\"outdent\":\"Scade indentarea\"},\"fakeobjects\":{\"anchor\":\"Inserează/Editează ancoră\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Câmp ascuns (HiddenField)\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"Tasta de acces\",\"advanced\":\"Avansat\",\"advisoryContentType\":\"Tipul consultativ al titlului\",\"advisoryTitle\":\"Titlul consultativ\",\"anchor\":{\"toolbar\":\"Inserează/Editează ancoră\",\"menu\":\"Proprietăţi ancoră\",\"title\":\"Proprietăţi ancoră\",\"name\":\"Numele ancorei\",\"errorName\":\"Vă rugăm scrieţi numele ancorei\",\"remove\":\"Elimină ancora\"},\"anchorId\":\"după Id-ul elementului\",\"anchorName\":\"după numele ancorei\",\"charset\":\"Setul de caractere al resursei legate\",\"cssClasses\":\"Clasele cu stilul paginii (CSS)\",\"emailAddress\":\"Adresă de e-mail\",\"emailBody\":\"Opțiuni Meniu Contextual\",\"emailSubject\":\"Subiectul mesajului\",\"id\":\"Id\",\"info\":\"Informaţii despre link (Legătură web)\",\"langCode\":\"Direcţia cuvintelor\",\"langDir\":\"Direcţia cuvintelor\",\"langDirLTR\":\"stânga-dreapta (LTR)\",\"langDirRTL\":\"dreapta-stânga (RTL)\",\"menu\":\"Editează Link\",\"name\":\"Nume\",\"noAnchors\":\"(Nicio ancoră disponibilă în document)\",\"noEmail\":\"Vă rugăm să scrieţi adresa de e-mail\",\"noUrl\":\"Vă rugăm să scrieţi URL-ul\",\"other\":\"<alt>\",\"popupDependent\":\"Dependent (Netscape)\",\"popupFeatures\":\"Proprietăţile ferestrei popup\",\"popupFullScreen\":\"Tot ecranul (Full Screen)(IE)\",\"popupLeft\":\"Poziţia la stânga\",\"popupLocationBar\":\"Bara de locaţie\",\"popupMenuBar\":\"Bara de meniu\",\"popupResizable\":\"Redimensionabil\",\"popupScrollBars\":\"Bare de derulare\",\"popupStatusBar\":\"Bara de status\",\"popupToolbar\":\"Bara de opţiuni\",\"popupTop\":\"Poziţia la dreapta\",\"rel\":\"Relație\",\"selectAnchor\":\"Selectaţi o ancoră\",\"styles\":\"Stil\",\"tabIndex\":\"Indexul tabului\",\"target\":\"Ţintă (Target)\",\"targetFrame\":\"<frame>\",\"targetFrameName\":\"Numele frameului ţintă\",\"targetPopup\":\"<fereastra popup>\",\"targetPopupName\":\"Numele ferestrei popup\",\"title\":\"Link (Legătură web)\",\"toAnchor\":\"Ancoră în această pagină\",\"toEmail\":\"E-Mail\",\"toUrl\":\"URL\",\"toolbar\":\"Inserează/Editează link (legătură web)\",\"type\":\"Tipul link-ului (al legăturii web)\",\"unlink\":\"Înlătură link (legătură web)\",\"upload\":\"Încarcă\"},\"list\":{\"bulletedlist\":\"Inserează / Elimină Listă cu puncte\",\"numberedlist\":\"Inserează / Elimină Listă numerotată\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Mărește\",\"minimize\":\"Micșorează\"},\"pastetext\":{\"button\":\"Adaugă ca text simplu (Plain Text)\",\"title\":\"Adaugă ca text simplu (Plain Text)\"},\"pastefromword\":{\"confirmCleanup\":\"Textul pe care doriți să-l lipiți este din Word. Doriți curățarea textului înante de a-l adăuga?\",\"error\":\"Nu a fost posibilă curățarea datelor adăugate datorită unei erori interne\",\"title\":\"Adaugă din Word\",\"toolbar\":\"Adaugă din Word\"},\"removeformat\":{\"toolbar\":\"Înlătură formatarea\"},\"sourcearea\":{\"toolbar\":\"Sursa\"},\"specialchar\":{\"options\":\"Opțiuni caractere speciale\",\"title\":\"Selectează caracter special\",\"toolbar\":\"Inserează caracter special\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stil\",\"panelTitle\":\"Formatarea stilurilor\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"Mărimea marginii\",\"caption\":\"Titlu (Caption)\",\"cell\":{\"menu\":\"Celulă\",\"insertBefore\":\"Inserează celulă înainte\",\"insertAfter\":\"Inserează celulă după\",\"deleteCell\":\"Şterge celule\",\"merge\":\"Uneşte celule\",\"mergeRight\":\"Uneşte la dreapta\",\"mergeDown\":\"Uneşte jos\",\"splitHorizontal\":\"Împarte celula pe orizontală\",\"splitVertical\":\"Împarte celula pe verticală\",\"title\":\"Proprietăți celulă\",\"cellType\":\"Tipul celulei\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Aliniament orizontal\",\"vAlign\":\"Aliniament vertical\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Culoare fundal\",\"borderColor\":\"Culoare bordură\",\"data\":\"Data\",\"header\":\"Antet\",\"yes\":\"Da\",\"no\":\"Nu\",\"invalidWidth\":\"Lățimea celulei trebuie să fie un număr.\",\"invalidHeight\":\"Înălțimea celulei trebuie să fie un număr.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Alege\"},\"cellPad\":\"Spaţiu în cadrul celulei\",\"cellSpace\":\"Spaţiu între celule\",\"column\":{\"menu\":\"Coloană\",\"insertBefore\":\"Inserează coloană înainte\",\"insertAfter\":\"Inserează coloană după\",\"deleteColumn\":\"Şterge celule\"},\"columns\":\"Coloane\",\"deleteTable\":\"Şterge tabel\",\"headers\":\"Antente\",\"headersBoth\":\"Ambele\",\"headersColumn\":\"Prima coloană\",\"headersNone\":\"Nimic\",\"headersRow\":\"Primul rând\",\"invalidBorder\":\"Dimensiunea bordurii trebuie să aibe un număr.\",\"invalidCellPadding\":\"Cell padding must be a positive number.\",\"invalidCellSpacing\":\"Spațierea celului trebuie să fie un număr pozitiv.\",\"invalidCols\":\"Numărul coloanelor trebuie să fie mai mare decât 0.\",\"invalidHeight\":\"Inaltimea celulei trebuie sa fie un numar.\",\"invalidRows\":\"Numărul rândurilor trebuie să fie mai mare decât 0.\",\"invalidWidth\":\"Lățimea tabelului trebuie să fie un număr.\",\"menu\":\"Proprietăţile tabelului\",\"row\":{\"menu\":\"Rând\",\"insertBefore\":\"Inserează rând înainte\",\"insertAfter\":\"Inserează rând după\",\"deleteRow\":\"Şterge rânduri\"},\"rows\":\"Rânduri\",\"summary\":\"Rezumat\",\"title\":\"Proprietăţile tabelului\",\"toolbar\":\"Tabel\",\"widthPc\":\"procente\",\"widthPx\":\"pixeli\",\"widthUnit\":\"unitate lățime\"},\"undo\":{\"redo\":\"Starea ulterioară (redo)\",\"undo\":\"Starea anterioară (undo)\"},\"wsc\":{\"btnIgnore\":\"Ignoră\",\"btnIgnoreAll\":\"Ignoră toate\",\"btnReplace\":\"Înlocuieşte\",\"btnReplaceAll\":\"Înlocuieşte tot\",\"btnUndo\":\"Starea anterioară (undo)\",\"changeTo\":\"Schimbă în\",\"errorLoading\":\"Eroare în lansarea aplicației service host %s.\",\"ieSpellDownload\":\"Unealta pentru verificat textul (Spell checker) neinstalată. Doriţi să o descărcaţi acum?\",\"manyChanges\":\"Verificarea textului terminată: 1% cuvinte modificate\",\"noChanges\":\"Verificarea textului terminată: Niciun cuvânt modificat\",\"noMispell\":\"Verificarea textului terminată: Nicio greşeală găsită\",\"noSuggestions\":\"- Fără sugestii -\",\"notAvailable\":\"Scuzați, dar serviciul nu este disponibil momentan.\",\"notInDic\":\"Nu e în dicţionar\",\"oneChange\":\"Verificarea textului terminată: Un cuvânt modificat\",\"progress\":\"Verificarea textului în desfăşurare...\",\"title\":\"Spell Check\",\"toolbar\":\"Verifică scrierea textului\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/ru.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['ru']={\"editor\":\"Визуальный текстовый редактор\",\"editorPanel\":\"Визуальный редактор текста\",\"common\":{\"editorHelp\":\"Нажмите ALT-0 для открытия справки\",\"browseServer\":\"Выбор на сервере\",\"url\":\"Ссылка\",\"protocol\":\"Протокол\",\"upload\":\"Загрузка файла\",\"uploadSubmit\":\"Загрузить на сервер\",\"image\":\"Изображение\",\"flash\":\"Flash\",\"form\":\"Форма\",\"checkbox\":\"Чекбокс\",\"radio\":\"Радиокнопка\",\"textField\":\"Текстовое поле\",\"textarea\":\"Многострочное текстовое поле\",\"hiddenField\":\"Скрытое поле\",\"button\":\"Кнопка\",\"select\":\"Выпадающий список\",\"imageButton\":\"Кнопка-изображение\",\"notSet\":\"<не указано>\",\"id\":\"Идентификатор\",\"name\":\"Имя\",\"langDir\":\"Направление текста\",\"langDirLtr\":\"Слева направо (LTR)\",\"langDirRtl\":\"Справа налево (RTL)\",\"langCode\":\"Код языка\",\"longDescr\":\"Длинное описание ссылки\",\"cssClass\":\"Класс CSS\",\"advisoryTitle\":\"Заголовок\",\"cssStyle\":\"Стиль\",\"ok\":\"ОК\",\"cancel\":\"Отмена\",\"close\":\"Закрыть\",\"preview\":\"Предпросмотр\",\"resize\":\"Перетащите для изменения размера\",\"generalTab\":\"Основное\",\"advancedTab\":\"Дополнительно\",\"validateNumberFailed\":\"Это значение не является числом.\",\"confirmNewPage\":\"Несохранённые изменения будут потеряны! Вы действительно желаете перейти на другую страницу?\",\"confirmCancel\":\"Некоторые параметры были изменены. Вы уверены, что желаете закрыть без сохранения?\",\"options\":\"Параметры\",\"target\":\"Цель\",\"targetNew\":\"Новое окно (_blank)\",\"targetTop\":\"Главное окно (_top)\",\"targetSelf\":\"Текущее окно (_self)\",\"targetParent\":\"Родительское окно (_parent)\",\"langDirLTR\":\"Слева направо (LTR)\",\"langDirRTL\":\"Справа налево (RTL)\",\"styles\":\"Стиль\",\"cssClasses\":\"CSS классы\",\"width\":\"Ширина\",\"height\":\"Высота\",\"align\":\"Выравнивание\",\"alignLeft\":\"По левому краю\",\"alignRight\":\"По правому краю\",\"alignCenter\":\"По центру\",\"alignTop\":\"Поверху\",\"alignMiddle\":\"Посередине\",\"alignBottom\":\"Понизу\",\"invalidValue\":\"Недопустимое значение.\",\"invalidHeight\":\"Высота задается числом.\",\"invalidWidth\":\"Ширина задается числом.\",\"invalidCssLength\":\"Значение, указанное в поле \\\"%1\\\", должно быть положительным целым числом. Допускается указание единиц меры CSS (px, %, in, cm, mm, em, ex, pt или pc).\",\"invalidHtmlLength\":\"Значение, указанное в поле \\\"%1\\\", должно быть положительным целым числом. Допускается указание единиц меры HTML (px или %).\",\"invalidInlineStyle\":\"Значение, указанное для стиля элемента, должно состоять из одной или нескольких пар данных в формате \\\"параметр : значение\\\", разделённых точкой с запятой.\",\"cssLengthTooltip\":\"Введите значение в пикселях, либо число с корректной единицей меры CSS (px, %, in, cm, mm, em, ex, pt или pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, недоступно</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Все права защищены.\",\"dlgTitle\":\"О CKEditor\",\"help\":\"$1 содержит подробную справку по использованию.\",\"moreInfo\":\"Для получения информации о лицензии, пожалуйста, перейдите на наш сайт:\",\"title\":\"О CKEditor\",\"userGuide\":\"Руководство пользователя CKEditor\"},\"basicstyles\":{\"bold\":\"Полужирный\",\"italic\":\"Курсив\",\"strike\":\"Зачеркнутый\",\"subscript\":\"Подстрочный индекс\",\"superscript\":\"Надстрочный индекс\",\"underline\":\"Подчеркнутый\"},\"blockquote\":{\"toolbar\":\"Цитата\"},\"clipboard\":{\"copy\":\"Копировать\",\"copyError\":\"Настройки безопасности вашего браузера не разрешают редактору выполнять операции по копированию текста. Пожалуйста, используйте для этого клавиатуру (Ctrl/Cmd+C).\",\"cut\":\"Вырезать\",\"cutError\":\"Настройки безопасности вашего браузера не разрешают редактору выполнять операции по вырезке текста. Пожалуйста, используйте для этого клавиатуру (Ctrl/Cmd+X).\",\"paste\":\"Вставить\",\"pasteArea\":\"Зона для вставки\",\"pasteMsg\":\"Пожалуйста, вставьте текст в зону ниже, используя клавиатуру (<strong>Ctrl/Cmd+V</strong>) и нажмите кнопку \\\"OK\\\".\",\"securityMsg\":\"Настройки безопасности вашего браузера не разрешают редактору напрямую обращаться к буферу обмена. Вы должны вставить текст снова в это окно.\",\"title\":\"Вставить\"},\"contextmenu\":{\"options\":\"Параметры контекстного меню\"},\"toolbar\":{\"toolbarCollapse\":\"Свернуть панель инструментов\",\"toolbarExpand\":\"Развернуть панель инструментов\",\"toolbarGroups\":{\"document\":\"Документ\",\"clipboard\":\"Буфер обмена / Отмена действий\",\"editing\":\"Корректировка\",\"forms\":\"Формы\",\"basicstyles\":\"Простые стили\",\"paragraph\":\"Абзац\",\"links\":\"Ссылки\",\"insert\":\"Вставка\",\"styles\":\"Стили\",\"colors\":\"Цвета\",\"tools\":\"Инструменты\"},\"toolbars\":\"Панели инструментов редактора\"},\"elementspath\":{\"eleLabel\":\"Путь элементов\",\"eleTitle\":\"Элемент %1\"},\"format\":{\"label\":\"Форматирование\",\"panelTitle\":\"Форматирование\",\"tag_address\":\"Адрес\",\"tag_div\":\"Обычное (div)\",\"tag_h1\":\"Заголовок 1\",\"tag_h2\":\"Заголовок 2\",\"tag_h3\":\"Заголовок 3\",\"tag_h4\":\"Заголовок 4\",\"tag_h5\":\"Заголовок 5\",\"tag_h6\":\"Заголовок 6\",\"tag_p\":\"Обычное\",\"tag_pre\":\"Моноширинное\"},\"horizontalrule\":{\"toolbar\":\"Вставить горизонтальную линию\"},\"image\":{\"alertUrl\":\"Пожалуйста, введите ссылку на изображение\",\"alt\":\"Альтернативный текст\",\"border\":\"Граница\",\"btnUpload\":\"Загрузить на сервер\",\"button2Img\":\"Вы желаете преобразовать это изображение-кнопку в обычное изображение?\",\"hSpace\":\"Гориз. отступ\",\"img2Button\":\"Вы желаете преобразовать это обычное изображение в изображение-кнопку?\",\"infoTab\":\"Данные об изображении\",\"linkTab\":\"Ссылка\",\"lockRatio\":\"Сохранять пропорции\",\"menu\":\"Свойства изображения\",\"resetSize\":\"Вернуть обычные размеры\",\"title\":\"Свойства изображения\",\"titleButton\":\"Свойства изображения-кнопки\",\"upload\":\"Загрузить\",\"urlMissing\":\"Не указана ссылка на изображение.\",\"vSpace\":\"Вертик. отступ\",\"validateBorder\":\"Размер границ должен быть задан числом.\",\"validateHSpace\":\"Горизонтальный отступ должен быть задан числом.\",\"validateVSpace\":\"Вертикальный отступ должен быть задан числом.\"},\"indent\":{\"indent\":\"Увеличить отступ\",\"outdent\":\"Уменьшить отступ\"},\"fakeobjects\":{\"anchor\":\"Якорь\",\"flash\":\"Flash анимация\",\"hiddenfield\":\"Скрытое поле\",\"iframe\":\"iFrame\",\"unknown\":\"Неизвестный объект\"},\"link\":{\"acccessKey\":\"Клавиша доступа\",\"advanced\":\"Дополнительно\",\"advisoryContentType\":\"Тип содержимого\",\"advisoryTitle\":\"Заголовок\",\"anchor\":{\"toolbar\":\"Вставить / редактировать якорь\",\"menu\":\"Изменить якорь\",\"title\":\"Свойства якоря\",\"name\":\"Имя якоря\",\"errorName\":\"Пожалуйста, введите имя якоря\",\"remove\":\"Удалить якорь\"},\"anchorId\":\"По идентификатору\",\"anchorName\":\"По имени\",\"charset\":\"Кодировка ресурса\",\"cssClasses\":\"Классы CSS\",\"emailAddress\":\"Email адрес\",\"emailBody\":\"Текст сообщения\",\"emailSubject\":\"Тема сообщения\",\"id\":\"Идентификатор\",\"info\":\"Информация о ссылке\",\"langCode\":\"Код языка\",\"langDir\":\"Направление текста\",\"langDirLTR\":\"Слева направо (LTR)\",\"langDirRTL\":\"Справа налево (RTL)\",\"menu\":\"Редактировать ссылку\",\"name\":\"Имя\",\"noAnchors\":\"(В документе нет ни одного якоря)\",\"noEmail\":\"Пожалуйста, введите email адрес\",\"noUrl\":\"Пожалуйста, введите ссылку\",\"other\":\"<другой>\",\"popupDependent\":\"Зависимое (Netscape)\",\"popupFeatures\":\"Параметры всплывающего окна\",\"popupFullScreen\":\"Полноэкранное (IE)\",\"popupLeft\":\"Отступ слева\",\"popupLocationBar\":\"Панель адреса\",\"popupMenuBar\":\"Панель меню\",\"popupResizable\":\"Изменяемый размер\",\"popupScrollBars\":\"Полосы прокрутки\",\"popupStatusBar\":\"Строка состояния\",\"popupToolbar\":\"Панель инструментов\",\"popupTop\":\"Отступ сверху\",\"rel\":\"Отношение\",\"selectAnchor\":\"Выберите якорь\",\"styles\":\"Стиль\",\"tabIndex\":\"Последовательность перехода\",\"target\":\"Цель\",\"targetFrame\":\"<фрейм>\",\"targetFrameName\":\"Имя целевого фрейма\",\"targetPopup\":\"<всплывающее окно>\",\"targetPopupName\":\"Имя всплывающего окна\",\"title\":\"Ссылка\",\"toAnchor\":\"Ссылка на якорь в тексте\",\"toEmail\":\"Email\",\"toUrl\":\"Ссылка\",\"toolbar\":\"Вставить/Редактировать ссылку\",\"type\":\"Тип ссылки\",\"unlink\":\"Убрать ссылку\",\"upload\":\"Загрузка\"},\"list\":{\"bulletedlist\":\"Вставить / удалить маркированный список\",\"numberedlist\":\"Вставить / удалить нумерованный список\"},\"magicline\":{\"title\":\"Вставить здесь параграф\"},\"maximize\":{\"maximize\":\"Развернуть\",\"minimize\":\"Свернуть\"},\"pastetext\":{\"button\":\"Вставить только текст\",\"title\":\"Вставить только текст\"},\"pastefromword\":{\"confirmCleanup\":\"Текст, который вы желаете вставить, по всей видимости, был скопирован из Word. Следует ли очистить его перед вставкой?\",\"error\":\"Невозможно очистить вставленные данные из-за внутренней ошибки\",\"title\":\"Вставить из Word\",\"toolbar\":\"Вставить из Word\"},\"removeformat\":{\"toolbar\":\"Убрать форматирование\"},\"sourcearea\":{\"toolbar\":\"Источник\"},\"specialchar\":{\"options\":\"Выбор специального символа\",\"title\":\"Выберите специальный символ\",\"toolbar\":\"Вставить специальный символ\"},\"scayt\":{\"about\":\"О SCAYT\",\"aboutTab\":\"О SCAYT\",\"addWord\":\"Добавить слово\",\"allCaps\":\"Игнорировать слова из заглавных букв\",\"dic_create\":\"Создать\",\"dic_delete\":\"Удалить\",\"dic_field_name\":\"Название словаря\",\"dic_info\":\"Изначально, пользовательский словарь хранится в cookie, которые ограничены в размере. Когда словарь пользователя вырастает до размеров, что его невозможно хранить в cookie, он переносится на хранение на наш сервер. Чтобы сохранить ваш словарь на нашем сервере, вам следует указать название вашего словаря. Если у вас уже был словарь, который вы сохраняли на нашем сервере, то укажите здесь его название и нажмите кнопку Восстановить.\",\"dic_rename\":\"Переименовать\",\"dic_restore\":\"Восстановить\",\"dictionariesTab\":\"Словари\",\"disable\":\"Отключить SCAYT\",\"emptyDic\":\"Вы должны указать название словаря.\",\"enable\":\"Включить SCAYT\",\"ignore\":\"Пропустить\",\"ignoreAll\":\"Пропустить всё\",\"ignoreDomainNames\":\"Игнорировать доменные имена\",\"langs\":\"Языки\",\"languagesTab\":\"Языки\",\"mixedCase\":\"Игнорировать слова из букв в разном регистре\",\"mixedWithDigits\":\"Игнорировать слова, содержащие цифры\",\"moreSuggestions\":\"Ещё варианты\",\"opera_title\":\"Не поддерживается Opera\",\"options\":\"Настройки\",\"optionsTab\":\"Параметры\",\"title\":\"Проверка орфографии по мере ввода (SCAYT)\",\"toggle\":\"Переключить SCAYT\",\"noSuggestions\":\"Нет вариантов\"},\"stylescombo\":{\"label\":\"Стили\",\"panelTitle\":\"Стили форматирования\",\"panelTitle1\":\"Стили блока\",\"panelTitle2\":\"Стили элемента\",\"panelTitle3\":\"Стили объекта\"},\"table\":{\"border\":\"Размер границ\",\"caption\":\"Заголовок\",\"cell\":{\"menu\":\"Ячейка\",\"insertBefore\":\"Вставить ячейку слева\",\"insertAfter\":\"Вставить ячейку справа\",\"deleteCell\":\"Удалить ячейки\",\"merge\":\"Объединить ячейки\",\"mergeRight\":\"Объединить с правой\",\"mergeDown\":\"Объединить с нижней\",\"splitHorizontal\":\"Разделить ячейку по горизонтали\",\"splitVertical\":\"Разделить ячейку по вертикали\",\"title\":\"Свойства ячейки\",\"cellType\":\"Тип ячейки\",\"rowSpan\":\"Объединяет строк\",\"colSpan\":\"Объединяет колонок\",\"wordWrap\":\"Перенос по словам\",\"hAlign\":\"Горизонтальное выравнивание\",\"vAlign\":\"Вертикальное выравнивание\",\"alignBaseline\":\"По базовой линии\",\"bgColor\":\"Цвет фона\",\"borderColor\":\"Цвет границ\",\"data\":\"Данные\",\"header\":\"Заголовок\",\"yes\":\"Да\",\"no\":\"Нет\",\"invalidWidth\":\"Ширина ячейки должна быть числом.\",\"invalidHeight\":\"Высота ячейки должна быть числом.\",\"invalidRowSpan\":\"Количество объединяемых строк должно быть задано числом.\",\"invalidColSpan\":\"Количество объединяемых колонок должно быть задано числом.\",\"chooseColor\":\"Выберите\"},\"cellPad\":\"Внутренний отступ ячеек\",\"cellSpace\":\"Внешний отступ ячеек\",\"column\":{\"menu\":\"Колонка\",\"insertBefore\":\"Вставить колонку слева\",\"insertAfter\":\"Вставить колонку справа\",\"deleteColumn\":\"Удалить колонки\"},\"columns\":\"Колонки\",\"deleteTable\":\"Удалить таблицу\",\"headers\":\"Заголовки\",\"headersBoth\":\"Сверху и слева\",\"headersColumn\":\"Левая колонка\",\"headersNone\":\"Без заголовков\",\"headersRow\":\"Верхняя строка\",\"invalidBorder\":\"Размер границ должен быть числом.\",\"invalidCellPadding\":\"Внутренний отступ ячеек (cellpadding) должен быть числом.\",\"invalidCellSpacing\":\"Внешний отступ ячеек (cellspacing) должен быть числом.\",\"invalidCols\":\"Количество столбцов должно быть больше 0.\",\"invalidHeight\":\"Высота таблицы должна быть числом.\",\"invalidRows\":\"Количество строк должно быть больше 0.\",\"invalidWidth\":\"Ширина таблицы должна быть числом.\",\"menu\":\"Свойства таблицы\",\"row\":{\"menu\":\"Строка\",\"insertBefore\":\"Вставить строку сверху\",\"insertAfter\":\"Вставить строку снизу\",\"deleteRow\":\"Удалить строки\"},\"rows\":\"Строки\",\"summary\":\"Итоги\",\"title\":\"Свойства таблицы\",\"toolbar\":\"Таблица\",\"widthPc\":\"процентов\",\"widthPx\":\"пикселей\",\"widthUnit\":\"единица измерения\"},\"undo\":{\"redo\":\"Повторить\",\"undo\":\"Отменить\"},\"wsc\":{\"btnIgnore\":\"Пропустить\",\"btnIgnoreAll\":\"Пропустить всё\",\"btnReplace\":\"Заменить\",\"btnReplaceAll\":\"Заменить всё\",\"btnUndo\":\"Отменить\",\"changeTo\":\"Изменить на\",\"errorLoading\":\"Произошла ошибка при подключении к серверу проверки орфографии: %s.\",\"ieSpellDownload\":\"Модуль проверки орфографии не установлен. Хотите скачать его?\",\"manyChanges\":\"Проверка орфографии завершена. Изменено слов: %1\",\"noChanges\":\"Проверка орфографии завершена. Не изменено ни одного слова\",\"noMispell\":\"Проверка орфографии завершена. Ошибок не найдено\",\"noSuggestions\":\"- Варианты отсутствуют -\",\"notAvailable\":\"Извините, но в данный момент сервис недоступен.\",\"notInDic\":\"Отсутствует в словаре\",\"oneChange\":\"Проверка орфографии завершена. Изменено одно слово\",\"progress\":\"Орфография проверяется...\",\"title\":\"Проверка орфографии\",\"toolbar\":\"Проверить орфографию\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/si.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['si']={\"editor\":\"පොහොසත් වචන සංස්කරණ\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"උදව් ලබා ගැනීමට  ALT බොත්තම ඔබන්න\",\"browseServer\":\"සෙවුම් සේවාදායකය\",\"url\":\"URL\",\"protocol\":\"මුලාපත්රය\",\"upload\":\"උඩුගතකිරීම\",\"uploadSubmit\":\"සේවාදායකය වෙත යොමුකිරිම\",\"image\":\"රුපය\",\"flash\":\"දීප්තිය\",\"form\":\"පෝරමය\",\"checkbox\":\"ලකුණුකිරීමේ කොටුව\",\"radio\":\"තේරීම් \",\"textField\":\"ලියන ප්රදේශය\",\"textarea\":\"අකුරු \",\"hiddenField\":\"සැඟවුණු ප්රදේශය\",\"button\":\"බොත්තම\",\"select\":\"තෝරන්න \",\"imageButton\":\"රුප \",\"notSet\":\"<යොදා >\",\"id\":\"අංකය\",\"name\":\"නම\",\"langDir\":\"භාෂා දිශාව\",\"langDirLtr\":\"වමේසිට දකුණුට\",\"langDirRtl\":\"දකුණේ සිට වමට\",\"langCode\":\"භාෂා කේතය\",\"longDescr\":\"සම්පුර්න පැහැදිලි කිරීම\",\"cssClass\":\"විලාශ පත්ර පන්තිය\",\"advisoryTitle\":\"උපදෙස් \",\"cssStyle\":\"විලාසය\",\"ok\":\"නිරදි\",\"cancel\":\"අවලංගු කිරීම\",\"close\":\"වැසීම\",\"preview\":\"නැවත \",\"resize\":\"විශාලත්වය නැවත වෙනස් කිරීම\",\"generalTab\":\"පොදු කරුණු.\",\"advancedTab\":\"දීය\",\"validateNumberFailed\":\"මෙම වටිනාකම අංකයක් නොවේ\",\"confirmNewPage\":\"ආරක්ෂා නොකළ සියලුම දත්තයන් මැකියනුලැබේ. ඔබට නව පිටුවක් ලබා ගැනීමට අවශ්යද?\",\"confirmCancel\":\"ඇතම් විකල්පයන් වෙනස් කර ඇත. ඔබට මින් නික්මීමට අවශ්යද?\",\"options\":\" විකල්ප\",\"target\":\"අරමුණ\",\"targetNew\":\"නව කව්ළුව\",\"targetTop\":\"වැදගත් කව්ළුව\",\"targetSelf\":\"එම කව්ළුව(_තම\\\\\\\\)\",\"targetParent\":\"මව් කව්ළුව(_)\",\"langDirLTR\":\"වමේසිට දකුණුට\",\"langDirRTL\":\"දකුණේ සිට වමට\",\"styles\":\"විලාසය\",\"cssClasses\":\"විලාසපත්ර පන්තිය\",\"width\":\"පළල\",\"height\":\"උස\",\"align\":\"ගැලපුම\",\"alignLeft\":\"වම\",\"alignRight\":\"දකුණ\",\"alignCenter\":\"මධ්ය\",\"alignTop\":\"ඉ\",\"alignMiddle\":\"මැද\",\"alignBottom\":\"පහල\",\"invalidValue\":\"වැරදී වටිනාකමකි\",\"invalidHeight\":\"උස අංකයක් විය යුතුය\",\"invalidWidth\":\"පළල අංකයක් විය යුතුය\",\"invalidCssLength\":\"වටිනාකමක් නිරූපණය කිරීම \\\"%1\\\" ප්රදේශය ධන සංක්යාත්මක වටිනාකමක් හෝ  නිවරදි නොවන  CSS මිනුම් එකක(px, %, in, cm, mm, em, ex, pt, pc)\",\"invalidHtmlLength\":\"වටිනාකමක් නිරූපණය කිරීම \\\"%1\\\" ප්රදේශය ධන සංක්යාත්මක වටිනාකමක් හෝ  නිවරදි නොවන  HTML මිනුම් එකක (px හෝ %).\",\"invalidInlineStyle\":\"වටිනාකමක් නිරූපණය කිරීම  පේළි විලාසයයට ආකෘතිය  අනතර්ග විය යුතය  \\\"නම : වටිනාකම\\\", තිත් කොමාවකින් වෙන් වෙන ලද.\",\"cssLengthTooltip\":\"සංක්යා ඇතුලත් කිරීමේදී වටිනාකම තිත් ප්රමාණය නිවරදි CSS  ඒකක(තිත්, %, අඟල්,සෙමි, mm, em, ex, pt, pc)\",\"unavailable\":\"%1<span පන්තිය=\\\"ළඟා වියහැකි ද බලන්න\\\">, නොමැතිනම්</span>\"},\"about\":{\"copy\":\"පිටපත් අයිතිය සහ පිටපත් කිරීම;$1 .සියලුම හිමිකම් ඇවිරිණි.\",\"dlgTitle\":\"CKEditor ගැන විස්තර\",\"help\":\"උදව් සඳහා $1 \",\"moreInfo\":\"බලපත්ර තොරතුරු සදහා කරුණාකර අපගේ විද්යුත් ලිපිනයට පිවිසෙන්න:\",\"title\":\"CKEditor ගැන විස්තර\",\"userGuide\":\"CKEditor භාවිතා කිරීම පිළිබඳ \"},\"basicstyles\":{\"bold\":\"තද අකුරින් ලියනලද\",\"italic\":\"බැධීඅකුරින් ලියන ලද\",\"strike\":\"Strike Through\",\"subscript\":\"Subscript\",\"superscript\":\"Superscript\",\"underline\":\"යටින් ඉරි අදින ලද\"},\"blockquote\":{\"toolbar\":\"උද්ධෘත කොටස\"},\"clipboard\":{\"copy\":\"පිටපත් කරන්න\",\"copyError\":\"Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).\",\"cut\":\"කපාගන්න\",\"cutError\":\"Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).\",\"paste\":\"අලවන්න\",\"pasteArea\":\"අලවන ප්රදේශ\",\"pasteMsg\":\"Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK\",\"securityMsg\":\"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.\",\"title\":\"අලවන්න\"},\"contextmenu\":{\"options\":\"අනතර්ග ලේඛණ  විකල්ප\"},\"toolbar\":{\"toolbarCollapse\":\"මෙවලම් තීරුව හැකුලුම.\",\"toolbarExpand\":\"මෙවලම් තීරුව දීගහැරුම\",\"toolbarGroups\":{\"document\":\"ලිපිය\",\"clipboard\":\"ඇමිණුම වෙනස් කිරීම\",\"editing\":\"සංස්කරණය\",\"forms\":\"පෝරමය\",\"basicstyles\":\"මුලික විලාසය\",\"paragraph\":\"චේදය\",\"links\":\"සබැඳිය\",\"insert\":\"ඇතුලත් කිරීම\",\"styles\":\"විලාසය\",\"colors\":\"වර්ණය\",\"tools\":\"මෙවලම්\"},\"toolbars\":\"සංස්කරණ මෙවලම් තීරුව\"},\"elementspath\":{\"eleLabel\":\"මුලද්රව්ය මාර්ගය\",\"eleTitle\":\"%1 මුල\"},\"format\":{\"label\":\"ආකෘතිය\",\"panelTitle\":\"චේදයේ \",\"tag_address\":\"ලිපිනය\",\"tag_div\":\"සාමාන්ය(DIV)\",\"tag_h1\":\"ශීර්ෂය 1\",\"tag_h2\":\"ශීර්ෂය 2\",\"tag_h3\":\"ශීර්ෂය 3\",\"tag_h4\":\"ශීර්ෂය 4\",\"tag_h5\":\"ශීර්ෂය 5\",\"tag_h6\":\"ශීර්ෂය 6\",\"tag_p\":\"සාමාන්ය\",\"tag_pre\":\"ආකෘතියන්\"},\"horizontalrule\":{\"toolbar\":\"තිරස් රේඛාවක් ඇතුලත් කරන්න\"},\"image\":{\"alertUrl\":\"කරුණාකර රුපයේ URL ලියන්න\",\"alt\":\"විකල්ප \",\"border\":\"සීමාවවල \",\"btnUpload\":\"සේවාදායකය වෙත යොමුකිරිම\",\"button2Img\":\"ඔබට තෝරන ලද රුපය පරිවර්තනය කිරීමට අවශ්යද?\",\"hSpace\":\"HSpace\",\"img2Button\":\"ඔබට තෝරන ලද රුපය පරිවර්තනය කිරීමට අවශ්යද?\",\"infoTab\":\"රුපයේ තොරතුරු\",\"linkTab\":\"සබැඳිය\",\"lockRatio\":\"නවතන අනුපාතය \",\"menu\":\"රුපයේ ගුණ\",\"resetSize\":\"නැවතත් විශාලත්වය වෙනස් කිරීම\",\"title\":\"රුපයේ \",\"titleButton\":\"රුප බොත්තමේ ගුණ\",\"upload\":\"උඩුගතකිරීම\",\"urlMissing\":\"රුප මුලාශ්ර URL නැත.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"මාඉම් සම්පුර්ණ සංක්යාවක් විය යුතුය.\",\"validateHSpace\":\"HSpace  සම්පුර්ණ සංක්යාවක් විය යුතුය\",\"validateVSpace\":\"VSpace සම්පුර්ණ සංක්යාවක් විය යුතුය.\"},\"indent\":{\"indent\":\"අතර පරතරය වැඩිකරන්න\",\"outdent\":\"අතර පරතරය අඩුකරන්න\"},\"fakeobjects\":{\"anchor\":\"ආධාරය\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"සැඟවුණු ප්රදේශය\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"ප්රවේශ  යතුර\",\"advanced\":\"දීය\",\"advisoryContentType\":\"උපදේශාත්මක අන්තර්ගත ආකාරය\",\"advisoryTitle\":\"උපදේශාත්මක නාමය\",\"anchor\":{\"toolbar\":\"ආධාරය\",\"menu\":\"ආධාරය වෙනස් කිරීම\",\"title\":\"ආධාරක \",\"name\":\"ආධාරකයේ නාමය\",\"errorName\":\"කරුණාකර ආධාරකයේ නාමය ඇතුල් කරන්න\",\"remove\":\"ආධාරකය ඉවත් කිරීම\"},\"anchorId\":\"By Element Id\",\"anchorName\":\"By Anchor Name\",\"charset\":\"Linked Resource Charset\",\"cssClasses\":\"විලාසපත්ර පන්තිය\",\"emailAddress\":\"E-Mail Address\",\"emailBody\":\"Message Body\",\"emailSubject\":\"Message Subject\",\"id\":\"අංකය\",\"info\":\"Link Info\",\"langCode\":\"භාෂා කේතය\",\"langDir\":\"භාෂා දිශාව\",\"langDirLTR\":\"වමේසිට දකුණුට\",\"langDirRTL\":\"දකුණේ සිට වමට\",\"menu\":\"Edit Link\",\"name\":\"නම\",\"noAnchors\":\"(No anchors available in the document)\",\"noEmail\":\"Please type the e-mail address\",\"noUrl\":\"Please type the link URL\",\"other\":\"<other>\",\"popupDependent\":\"Dependent (Netscape)\",\"popupFeatures\":\"Popup Window Features\",\"popupFullScreen\":\"Full Screen (IE)\",\"popupLeft\":\"Left Position\",\"popupLocationBar\":\"Location Bar\",\"popupMenuBar\":\"Menu Bar\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"Scroll Bars\",\"popupStatusBar\":\"Status Bar\",\"popupToolbar\":\"Toolbar\",\"popupTop\":\"Top Position\",\"rel\":\"Relationship\",\"selectAnchor\":\"Select an Anchor\",\"styles\":\"විලාසය\",\"tabIndex\":\"Tab Index\",\"target\":\"අරමුණ\",\"targetFrame\":\"<frame>\",\"targetFrameName\":\"Target Frame Name\",\"targetPopup\":\"<popup window>\",\"targetPopupName\":\"Popup Window Name\",\"title\":\"සබැඳිය\",\"toAnchor\":\"Link to anchor in the text\",\"toEmail\":\"E-mail\",\"toUrl\":\"URL\",\"toolbar\":\"සබැඳිය\",\"type\":\"Link Type\",\"unlink\":\"Unlink\",\"upload\":\"උඩුගතකිරීම\"},\"list\":{\"bulletedlist\":\"ඇතුලත් / ඉවත් කිරීම ලඉස්තුව\",\"numberedlist\":\"ඇතුලත් / ඉවත් කිරීම අන්න්කිත ලඉස්තුව\"},\"magicline\":{\"title\":\"චේදය ඇතුලත් කරන්න\"},\"maximize\":{\"maximize\":\"විශාල කිරීම\",\"minimize\":\"කුඩා කිරීම\"},\"pastetext\":{\"button\":\"සාමාන්ය අක්ෂර ලෙස අලවන්න\",\"title\":\"සාමාන්ය අක්ෂර ලෙස අලවන්න\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"වචන වලින් අලවන්න\",\"toolbar\":\"වචන වලින් අලවන්න\"},\"removeformat\":{\"toolbar\":\"සැකසීම වෙනස් කරන්න\"},\"sourcearea\":{\"toolbar\":\"මුලාශ්රය\"},\"specialchar\":{\"options\":\"විශේෂ  ගුණාංග වීකල්ප\",\"title\":\"විශේෂ  ගුණාංග \",\"toolbar\":\"විශේෂ ගුණාංග ඇතුලත් \"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"විලාසය\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"සීමාවවල විශාලත්වය\",\"caption\":\"Caption\",\"cell\":{\"menu\":\"කොටුව\",\"insertBefore\":\"පෙර කොටුවක් ඇතුල්කිරිම\",\"insertAfter\":\"පසුව කොටුවක් ඇතුලත් \",\"deleteCell\":\"කොටුව මැකීම\",\"merge\":\"කොටු එකට යාකිරිම\",\"mergeRight\":\"දකුණට \",\"mergeDown\":\"පහලට \",\"splitHorizontal\":\"තිරස්ව කොටු පැතිරීම\",\"splitVertical\":\"සිරස්ව කොටු පැතිරීම\",\"title\":\"කොටු \",\"cellType\":\"කොටු වර්ගය\",\"rowSpan\":\"පේළි පළල\",\"colSpan\":\"සිරස් පළල\",\"wordWrap\":\"වචන ගැලපුම\",\"hAlign\":\"තිරස්ව \",\"vAlign\":\"සිරස්ව \",\"alignBaseline\":\"පාද රේඛාව\",\"bgColor\":\"පසුබිම් වර්ණය\",\"borderColor\":\"මායිම් \",\"data\":\"Data\",\"header\":\"ශීර්ෂක\",\"yes\":\"ඔව්\",\"no\":\"නැත\",\"invalidWidth\":\"කොටු පළල සංඛ්ය්ත්මක වටිනාකමක් විය යුතුය\",\"invalidHeight\":\"කොටු උස සංඛ්ය්ත්මක වටිනාකමක් විය යුතුය\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"තෝරන්න\"},\"cellPad\":\"Cell padding\",\"cellSpace\":\"Cell spacing\",\"column\":{\"menu\":\"Column\",\"insertBefore\":\"Insert Column Before\",\"insertAfter\":\"Insert Column After\",\"deleteColumn\":\"Delete Columns\"},\"columns\":\"සිරස් \",\"deleteTable\":\"වගුව මකන්න\",\"headers\":\"ශීර්ෂක\",\"headersBoth\":\"දෙකම\",\"headersColumn\":\"පළමූ සිරස් තීරුව\",\"headersNone\":\"කිසිවක්ම නොවේ\",\"headersRow\":\"පළමූ පේළිය\",\"invalidBorder\":\"Border size must be a number.\",\"invalidCellPadding\":\"Cell padding must be a positive number.\",\"invalidCellSpacing\":\"Cell spacing must be a positive number.\",\"invalidCols\":\"Number of columns must be a number greater than 0.\",\"invalidHeight\":\"Table height must be a number.\",\"invalidRows\":\"Number of rows must be a number greater than 0.\",\"invalidWidth\":\"Table width must be a number.\",\"menu\":\"Table Properties\",\"row\":{\"menu\":\"Row\",\"insertBefore\":\"Insert Row Before\",\"insertAfter\":\"Insert Row After\",\"deleteRow\":\"Delete Rows\"},\"rows\":\"Rows\",\"summary\":\"Summary\",\"title\":\"Table Properties\",\"toolbar\":\"Table\",\"widthPc\":\"percent\",\"widthPx\":\"pixels\",\"widthUnit\":\"width unit\"},\"undo\":{\"redo\":\"නැවත කිරීම\",\"undo\":\"වෙනස් කිරීම\"},\"wsc\":{\"btnIgnore\":\"Ignore\",\"btnIgnoreAll\":\"Ignore All\",\"btnReplace\":\"Replace\",\"btnReplaceAll\":\"Replace All\",\"btnUndo\":\"Undo\",\"changeTo\":\"Change to\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Spell checker not installed. Do you want to download it now?\",\"manyChanges\":\"Spell check complete: %1 words changed\",\"noChanges\":\"Spell check complete: No words changed\",\"noMispell\":\"Spell check complete: No misspellings found\",\"noSuggestions\":\"- No suggestions -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Not in dictionary\",\"oneChange\":\"Spell check complete: One word changed\",\"progress\":\"Spell check in progress...\",\"title\":\"Spell Check\",\"toolbar\":\"Check Spelling\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/sk.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['sk']={\"editor\":\"Editor formátovaného textu\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Stlačte ALT 0 pre nápovedu\",\"browseServer\":\"Prechádzať server\",\"url\":\"URL\",\"protocol\":\"Protokol\",\"upload\":\"Odoslať\",\"uploadSubmit\":\"Odoslať na server\",\"image\":\"Obrázok\",\"flash\":\"Flash\",\"form\":\"Formulár\",\"checkbox\":\"Zaškrtávacie políčko\",\"radio\":\"Prepínač\",\"textField\":\"Textové pole\",\"textarea\":\"Textová oblasť\",\"hiddenField\":\"Skryté pole\",\"button\":\"Tlačidlo\",\"select\":\"Rozbaľovací zoznam\",\"imageButton\":\"Obrázkové tlačidlo\",\"notSet\":\"<nenastavené>\",\"id\":\"Id\",\"name\":\"Meno\",\"langDir\":\"Orientácia jazyka\",\"langDirLtr\":\"Zľava doprava (LTR)\",\"langDirRtl\":\"Sprava doľava (RTL)\",\"langCode\":\"Kód jazyka\",\"longDescr\":\"Dlhý popis URL\",\"cssClass\":\"Trieda štýlu\",\"advisoryTitle\":\"Pomocný titulok\",\"cssStyle\":\"Štýl\",\"ok\":\"OK\",\"cancel\":\"Zrušiť\",\"close\":\"Zatvorit\",\"preview\":\"Náhľad\",\"resize\":\"Zmeniť veľkosť\",\"generalTab\":\"Hlavné\",\"advancedTab\":\"Rozšírené\",\"validateNumberFailed\":\"Hodnota nieje číslo.\",\"confirmNewPage\":\"Prajete si načítat novú stránku? Všetky neuložené zmeny budú stratené. \",\"confirmCancel\":\"Niektore možnosti boli zmenené. Naozaj chcete zavrieť okno?\",\"options\":\"Možnosti\",\"target\":\"Cieľ\",\"targetNew\":\"Nové okno (_blank)\",\"targetTop\":\"Najvrchnejšie okno (_top)\",\"targetSelf\":\"To isté okno (_self)\",\"targetParent\":\"Rodičovské okno (_parent)\",\"langDirLTR\":\"Zľava doprava (LTR)\",\"langDirRTL\":\"Sprava doľava (RTL)\",\"styles\":\"Štýl\",\"cssClasses\":\"Triedy štýlu\",\"width\":\"Šírka\",\"height\":\"Výška\",\"align\":\"Zarovnanie\",\"alignLeft\":\"Vľavo\",\"alignRight\":\"Vpravo\",\"alignCenter\":\"Na stred\",\"alignTop\":\"Nahor\",\"alignMiddle\":\"Na stred\",\"alignBottom\":\"Dole\",\"invalidValue\":\"Neplatná hodnota.\",\"invalidHeight\":\"Výška musí byť číslo.\",\"invalidWidth\":\"Šírka musí byť číslo.\",\"invalidCssLength\":\"Špecifikovaná hodnota pre pole \\\"%1\\\" musí byť kladné číslo s alebo bez platnej CSS mernej jednotky (px, %, in, cm, mm, em, ex, pt alebo pc).\",\"invalidHtmlLength\":\"Špecifikovaná hodnota pre pole \\\"%1\\\" musí byť kladné číslo s alebo bez platnej HTML mernej jednotky (px alebo %).\",\"invalidInlineStyle\":\"Zadaná hodnota pre inline štýl musí pozostávať s jedného, alebo viac dvojíc formátu \\\"názov: hodnota\\\", oddelených bodkočiarkou.\",\"cssLengthTooltip\":\"Vložte číslo pre hodnotu v pixeloch alebo číslo so správnou CSS jednotou (px, %, in, cm, mm, em, ex, pt alebo pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, nedostupný</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Všetky práva vyhradené.\",\"dlgTitle\":\"O CKEditor-e\",\"help\":\"Zaškrtnite $1 pre pomoc.\",\"moreInfo\":\"Pre informácie o licenciách, prosíme, navštívte našu web stránku:\",\"title\":\"O CKEditor-e\",\"userGuide\":\"Používateľská príručka KCEditor-a\"},\"basicstyles\":{\"bold\":\"Tučné\",\"italic\":\"Kurzíva\",\"strike\":\"Prečiarknuté\",\"subscript\":\"Dolný index\",\"superscript\":\"Horný index\",\"underline\":\"Podčiarknuté\"},\"blockquote\":{\"toolbar\":\"Citácia\"},\"clipboard\":{\"copy\":\"Kopírovať\",\"copyError\":\"Bezpečnostné nastavenia Vášho prehliadača nedovoľujú editoru automaticky spustiť operáciu kopírovania. Prosím, použite na to klávesnicu (Ctrl/Cmd+C).\",\"cut\":\"Vystrihnúť\",\"cutError\":\"Bezpečnostné nastavenia Vášho prehliadača nedovoľujú editoru automaticky spustiť operáciu vystrihnutia. Prosím, použite na to klávesnicu (Ctrl/Cmd+X).\",\"paste\":\"Vložiť\",\"pasteArea\":\"Miesto pre vloženie\",\"pasteMsg\":\"Prosím, vložte nasledovný rámček použitím klávesnice (<STRONG>Ctrl/Cmd+V</STRONG>) a stlačte OK.\",\"securityMsg\":\"Kvôli vašim bezpečnostným nastaveniam prehliadača editor nie je schopný pristupovať k vašej schránke na kopírovanie priamo. Vložte to preto do tohto okna.\",\"title\":\"Vložiť\"},\"contextmenu\":{\"options\":\"Možnosti kontextového menu\"},\"toolbar\":{\"toolbarCollapse\":\"Zbaliť lištu nástrojov\",\"toolbarExpand\":\"Rozbaliť lištu nástrojov\",\"toolbarGroups\":{\"document\":\"Dokument\",\"clipboard\":\"Schránka pre kopírovanie/Späť\",\"editing\":\"Upravovanie\",\"forms\":\"Formuláre\",\"basicstyles\":\"Základné štýly\",\"paragraph\":\"Odstavec\",\"links\":\"Odkazy\",\"insert\":\"Vložiť\",\"styles\":\"Štýly\",\"colors\":\"Farby\",\"tools\":\"Nástroje\"},\"toolbars\":\"Lišty nástrojov editora\"},\"elementspath\":{\"eleLabel\":\"Cesta prvkov\",\"eleTitle\":\"%1 prvok\"},\"format\":{\"label\":\"Formát\",\"panelTitle\":\"Formát\",\"tag_address\":\"Adresa\",\"tag_div\":\"Normálny (DIV)\",\"tag_h1\":\"Nadpis 1\",\"tag_h2\":\"Nadpis 2\",\"tag_h3\":\"Nadpis 3\",\"tag_h4\":\"Nadpis 4\",\"tag_h5\":\"Nadpis 5\",\"tag_h6\":\"Nadpis 6\",\"tag_p\":\"Normálny\",\"tag_pre\":\"Formátovaný\"},\"horizontalrule\":{\"toolbar\":\"Vložiť vodorovnú čiaru\"},\"image\":{\"alertUrl\":\"Zadajte prosím URL obrázka\",\"alt\":\"Alternatívny text\",\"border\":\"Rám (border)\",\"btnUpload\":\"Odoslať to na server\",\"button2Img\":\"Chcete zmeniť vybrané obrázkové tlačidlo na jednoduchý obrázok?\",\"hSpace\":\"H-medzera\",\"img2Button\":\"Chcete zmeniť vybraný obrázok na obrázkové tlačidlo?\",\"infoTab\":\"Informácie o obrázku\",\"linkTab\":\"Odkaz\",\"lockRatio\":\"Pomer zámky\",\"menu\":\"Vlastnosti obrázka\",\"resetSize\":\"Pôvodná veľkosť\",\"title\":\"Vlastnosti obrázka\",\"titleButton\":\"Vlastnosti obrázkového tlačidla\",\"upload\":\"Nahrať\",\"urlMissing\":\"Chýba URL zdroja obrázka.\",\"vSpace\":\"V-medzera\",\"validateBorder\":\"Rám (border) musí byť celé číslo.\",\"validateHSpace\":\"H-medzera musí byť celé číslo.\",\"validateVSpace\":\"V-medzera musí byť celé číslo.\"},\"indent\":{\"indent\":\"Zväčšiť odsadenie\",\"outdent\":\"Zmenšiť odsadenie\"},\"fakeobjects\":{\"anchor\":\"Kotva\",\"flash\":\"Flash animácia\",\"hiddenfield\":\"Skryté pole\",\"iframe\":\"IFrame\",\"unknown\":\"Neznámy objekt\"},\"link\":{\"acccessKey\":\"Prístupový kľúč\",\"advanced\":\"Rozšírené\",\"advisoryContentType\":\"Pomocný typ obsahu\",\"advisoryTitle\":\"Pomocný titulok\",\"anchor\":{\"toolbar\":\"Kotva\",\"menu\":\"Upraviť kotvu\",\"title\":\"Vlastnosti kotvy\",\"name\":\"Názov kotvy\",\"errorName\":\"Zadajte prosím názov kotvy\",\"remove\":\"Odstrániť kotvu\"},\"anchorId\":\"Podľa Id objektu\",\"anchorName\":\"Podľa mena kotvy\",\"charset\":\"Priradená znaková sada\",\"cssClasses\":\"Triedy štýlu\",\"emailAddress\":\"E-Mailová adresa\",\"emailBody\":\"Telo správy\",\"emailSubject\":\"Predmet správy\",\"id\":\"Id\",\"info\":\"Informácie o odkaze\",\"langCode\":\"Orientácia jazyka\",\"langDir\":\"Orientácia jazyka\",\"langDirLTR\":\"Zľava doprava (LTR)\",\"langDirRTL\":\"Sprava doľava (RTL)\",\"menu\":\"Upraviť odkaz\",\"name\":\"Názov\",\"noAnchors\":\"(V dokumente nie sú dostupné žiadne kotvy)\",\"noEmail\":\"Zadajte prosím e-mailovú adresu\",\"noUrl\":\"Zadajte prosím URL odkazu\",\"other\":\"<iný>\",\"popupDependent\":\"Závislosť (Netscape)\",\"popupFeatures\":\"Vlastnosti vyskakovacieho okna\",\"popupFullScreen\":\"Celá obrazovka (IE)\",\"popupLeft\":\"Ľavý okraj\",\"popupLocationBar\":\"Panel umiestnenia (location bar)\",\"popupMenuBar\":\"Panel ponuky (menu bar)\",\"popupResizable\":\"Meniteľná veľkosť (resizable)\",\"popupScrollBars\":\"Posuvníky (scroll bars)\",\"popupStatusBar\":\"Stavový riadok (status bar)\",\"popupToolbar\":\"Panel nástrojov (toolbar)\",\"popupTop\":\"Horný okraj\",\"rel\":\"Vzťah (rel)\",\"selectAnchor\":\"Vybrať kotvu\",\"styles\":\"Štýl\",\"tabIndex\":\"Poradie prvku (tab index)\",\"target\":\"Cieľ\",\"targetFrame\":\"<rámec>\",\"targetFrameName\":\"Názov rámu cieľa\",\"targetPopup\":\"<vyskakovacie okno>\",\"targetPopupName\":\"Názov vyskakovacieho okna\",\"title\":\"Odkaz\",\"toAnchor\":\"Odkaz na kotvu v texte\",\"toEmail\":\"E-mail\",\"toUrl\":\"URL\",\"toolbar\":\"Odkaz\",\"type\":\"Typ odkazu\",\"unlink\":\"Odstrániť odkaz\",\"upload\":\"Nahrať\"},\"list\":{\"bulletedlist\":\"Vložiť/Odstrániť zoznam s odrážkami\",\"numberedlist\":\"Vložiť/Odstrániť číslovaný zoznam\"},\"magicline\":{\"title\":\"Sem vložte paragraf\"},\"maximize\":{\"maximize\":\"Maximalizovať\",\"minimize\":\"Minimalizovať\"},\"pastetext\":{\"button\":\"Vložiť ako čistý text\",\"title\":\"Vložiť ako čistý text\"},\"pastefromword\":{\"confirmCleanup\":\"Vkladaný text vyzerá byť skopírovaný z Wordu. Chcete ho automaticky vyčistiť pred vkladaním?\",\"error\":\"Nebolo možné vyčistiť vložené dáta kvôli internej chybe\",\"title\":\"Vložiť z Wordu\",\"toolbar\":\"Vložiť z Wordu\"},\"removeformat\":{\"toolbar\":\"Odstrániť formátovanie\"},\"sourcearea\":{\"toolbar\":\"Zdroj\"},\"specialchar\":{\"options\":\"Možnosti špeciálneho znaku\",\"title\":\"Výber špeciálneho znaku\",\"toolbar\":\"Vložiť špeciálny znak\"},\"scayt\":{\"about\":\"O KPPP (Kontrola pravopisu počas písania)\",\"aboutTab\":\"O\",\"addWord\":\"Pridať slovo\",\"allCaps\":\"Ignorovať slová písané veľkými písmenami\",\"dic_create\":\"Vytvoriť\",\"dic_delete\":\"Vymazať\",\"dic_field_name\":\"Názov slovníka\",\"dic_info\":\"Spočiatku je užívateľský slovník uložený v cookie. Cookie však majú obmedzenú veľkosť. Keď užívateľský slovník narastie do bodu, kedy nemôže byť uložený v cookie, potom musí byť slovník uložený na našom serveri. Pre uloženie vášho osobného slovníka na náš server by ste mali zadať názov pre váš slovník. Ak už máte uložený slovník, prosíme, napíšte jeho názov a kliknite tlačidlo Obnoviť.\",\"dic_rename\":\"Premenovať\",\"dic_restore\":\"Obnoviť\",\"dictionariesTab\":\"Slovníky\",\"disable\":\"Zakázať  KPPP (Kontrola pravopisu počas písania)\",\"emptyDic\":\"Názov slovníka by nemal byť prázdny.\",\"enable\":\"Povoliť KPPP (Kontrola pravopisu počas písania)\",\"ignore\":\"Ignorovať\",\"ignoreAll\":\"Ignorovať všetko\",\"ignoreDomainNames\":\"Iznorovať názvy domén\",\"langs\":\"Jazyky\",\"languagesTab\":\"Jazyky\",\"mixedCase\":\"Ignorovať slová so smiešanými veľkými a malými písmenami\",\"mixedWithDigits\":\"Ignorovať slová s číslami\",\"moreSuggestions\":\"Viac návrhov\",\"opera_title\":\"Nepodporované Operou\",\"options\":\"Možnosti\",\"optionsTab\":\"Možnosti\",\"title\":\"Kontrola pravopisu počas písania\",\"toggle\":\"Prepnúť KPPP (Kontrola pravopisu počas písania)\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Štýly\",\"panelTitle\":\"Formátovanie štýlov\",\"panelTitle1\":\"Štýly bloku\",\"panelTitle2\":\"Vnútroriadkové (inline) štýly\",\"panelTitle3\":\"Štýly objeku\"},\"table\":{\"border\":\"Šírka rámu (border)\",\"caption\":\"Popis\",\"cell\":{\"menu\":\"Bunka\",\"insertBefore\":\"Vložiť bunku pred\",\"insertAfter\":\"Vložiť bunku za\",\"deleteCell\":\"Vymazať bunky\",\"merge\":\"Zlúčiť bunky\",\"mergeRight\":\"Zlúčiť doprava\",\"mergeDown\":\"Zlúčiť dole\",\"splitHorizontal\":\"Rozdeliť bunky horizontálne\",\"splitVertical\":\"Rozdeliť bunky vertikálne\",\"title\":\"Vlastnosti bunky\",\"cellType\":\"Typ bunky\",\"rowSpan\":\"Rozsah riadkov\",\"colSpan\":\"Rozsah stĺpcov\",\"wordWrap\":\"Zalomovanie riadkov\",\"hAlign\":\"Horizontálne zarovnanie\",\"vAlign\":\"Vertikálne zarovnanie\",\"alignBaseline\":\"Základná čiara (baseline)\",\"bgColor\":\"Farba pozadia\",\"borderColor\":\"Farba rámu\",\"data\":\"Dáta\",\"header\":\"Hlavička\",\"yes\":\"Áno\",\"no\":\"Nie\",\"invalidWidth\":\"Šírka bunky musí byť číslo.\",\"invalidHeight\":\"Výška bunky musí byť číslo.\",\"invalidRowSpan\":\"Rozsah riadkov musí byť celé číslo.\",\"invalidColSpan\":\"Rozsah stĺpcov musí byť celé číslo.\",\"chooseColor\":\"Vybrať\"},\"cellPad\":\"Odsadenie obsahu (cell padding)\",\"cellSpace\":\"Vzdialenosť buniek (cell spacing)\",\"column\":{\"menu\":\"Stĺpec\",\"insertBefore\":\"Vložiť stĺpec pred\",\"insertAfter\":\"Vložiť stĺpec po\",\"deleteColumn\":\"Zmazať stĺpce\"},\"columns\":\"Stĺpce\",\"deleteTable\":\"Vymazať tabuľku\",\"headers\":\"Hlavička\",\"headersBoth\":\"Obe\",\"headersColumn\":\"Prvý stĺpec\",\"headersNone\":\"Žiadne\",\"headersRow\":\"Prvý riadok\",\"invalidBorder\":\"Širka rámu musí byť číslo.\",\"invalidCellPadding\":\"Odsadenie v bunkách (cell padding) musí byť kladné číslo.\",\"invalidCellSpacing\":\"Medzera mädzi bunkami (cell spacing) musí byť kladné číslo.\",\"invalidCols\":\"Počet stĺpcov musí byť číslo väčšie ako 0.\",\"invalidHeight\":\"Výška tabuľky musí byť číslo.\",\"invalidRows\":\"Počet riadkov musí byť číslo väčšie ako 0.\",\"invalidWidth\":\"Širka tabuľky musí byť číslo.\",\"menu\":\"Vlastnosti tabuľky\",\"row\":{\"menu\":\"Riadok\",\"insertBefore\":\"Vložiť riadok pred\",\"insertAfter\":\"Vložiť riadok po\",\"deleteRow\":\"Vymazať riadky\"},\"rows\":\"Riadky\",\"summary\":\"Prehľad\",\"title\":\"Vlastnosti tabuľky\",\"toolbar\":\"Tabuľka\",\"widthPc\":\"percent\",\"widthPx\":\"pixelov\",\"widthUnit\":\"jednotka šírky\"},\"undo\":{\"redo\":\"Znovu\",\"undo\":\"Späť\"},\"wsc\":{\"btnIgnore\":\"Ignorovať\",\"btnIgnoreAll\":\"Ignorovať všetko\",\"btnReplace\":\"Prepísat\",\"btnReplaceAll\":\"Prepísat všetko\",\"btnUndo\":\"Späť\",\"changeTo\":\"Zmeniť na\",\"errorLoading\":\"Chyba pri načítaní slovníka z adresy: %s.\",\"ieSpellDownload\":\"Kontrola pravopisu nie je naištalovaná. Chcete ju teraz stiahnuť?\",\"manyChanges\":\"Kontrola pravopisu dokončená: Bolo zmenených %1 slov\",\"noChanges\":\"Kontrola pravopisu dokončená: Neboli zmenené žiadne slová\",\"noMispell\":\"Kontrola pravopisu dokončená: Neboli nájdené žiadne chyby pravopisu\",\"noSuggestions\":\"- Žiadny návrh -\",\"notAvailable\":\"Prepáčte, ale služba je momentálne nedostupná.\",\"notInDic\":\"Nie je v slovníku\",\"oneChange\":\"Kontrola pravopisu dokončená: Bolo zmenené jedno slovo\",\"progress\":\"Prebieha kontrola pravopisu...\",\"title\":\"Skontrolovať pravopis\",\"toolbar\":\"Kontrola pravopisu\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/sl.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['sl']={\"editor\":\"Bogat Urejevalnik Besedila\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Pritisnite ALT 0 za pomoč\",\"browseServer\":\"Prebrskaj na strežniku\",\"url\":\"URL\",\"protocol\":\"Protokol\",\"upload\":\"Naloži\",\"uploadSubmit\":\"Pošlji na strežnik\",\"image\":\"Slika\",\"flash\":\"Flash\",\"form\":\"Obrazec\",\"checkbox\":\"Potrditveno polje\",\"radio\":\"Izbirno polje\",\"textField\":\"Vnosno polje\",\"textarea\":\"Vnosno območje\",\"hiddenField\":\"Skrito polje\",\"button\":\"Gumb\",\"select\":\"Spustno Polje\",\"imageButton\":\"Slikovni Gumb\",\"notSet\":\"<ni določen>\",\"id\":\"Id\",\"name\":\"Ime\",\"langDir\":\"Smer jezika\",\"langDirLtr\":\"Od leve proti desni (LTR)\",\"langDirRtl\":\"Od desne proti levi (RTL)\",\"langCode\":\"Koda Jezika\",\"longDescr\":\"Dolg opis URL-ja\",\"cssClass\":\"Razred stilne predloge\",\"advisoryTitle\":\"Predlagani naslov\",\"cssStyle\":\"Slog\",\"ok\":\"V redu\",\"cancel\":\"Prekliči\",\"close\":\"Zapri\",\"preview\":\"Predogled\",\"resize\":\"Potegni za spremembo velikosti\",\"generalTab\":\"Splošno\",\"advancedTab\":\"Napredno\",\"validateNumberFailed\":\"Ta vrednost ni število.\",\"confirmNewPage\":\"Vse neshranjene spremembe te vsebine bodo izgubljene. Ali res želite naložiti novo stran?\",\"confirmCancel\":\"Nekaj možnosti je bilo spremenjenih. Ali res želite zapreti okno?\",\"options\":\"Možnosti\",\"target\":\"Cilj\",\"targetNew\":\"Novo Okno (_blank)\",\"targetTop\":\"Vrhovno Okno (_top)\",\"targetSelf\":\"Enako Okno (_self)\",\"targetParent\":\"Matično Okno (_parent)\",\"langDirLTR\":\"Od leve proti desni (LTR)\",\"langDirRTL\":\"Od desne proti levi (RTL)\",\"styles\":\"Slog\",\"cssClasses\":\"Razred stilne predloge\",\"width\":\"Širina\",\"height\":\"Višina\",\"align\":\"Poravnava\",\"alignLeft\":\"Levo\",\"alignRight\":\"Desno\",\"alignCenter\":\"Sredinsko\",\"alignTop\":\"Na vrh\",\"alignMiddle\":\"V sredino\",\"alignBottom\":\"Na dno\",\"invalidValue\":\"Neveljavna vrednost.\",\"invalidHeight\":\"Višina mora biti število.\",\"invalidWidth\":\"Širina mora biti število.\",\"invalidCssLength\":\"Vrednost določena za \\\"%1\\\" polje mora biti pozitivna številka z ali brez veljavne CSS enote za merjenje (px, %, in, cm, mm, em, ex, pt, ali pc).\",\"invalidHtmlLength\":\"Vrednost določena za \\\"%1\\\" polje mora biti pozitivna številka z ali brez veljavne HTML enote za merjenje (px ali %).\",\"invalidInlineStyle\":\"Vrednost določena za inline slog mora biti sestavljena iz ene ali več tork (tuples) z obliko \\\"ime : vrednost\\\", ločenih z podpičji.\",\"cssLengthTooltip\":\"Vnesite številko za vrednost v slikovnih pikah (pixels) ali številko z veljavno CSS enoto (px, %, in, cm, mm, em, ex, pt, ali pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, nedosegljiv</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Vse pravice pridržane.\",\"dlgTitle\":\"O programu CKEditor\",\"help\":\"Preverite $1 za pomoč.\",\"moreInfo\":\"Za informacijo o licenci prosim obiščite našo spletno stran:\",\"title\":\"O programu CKEditor\",\"userGuide\":\"CKEditor Navodila za Uporabo\"},\"basicstyles\":{\"bold\":\"Krepko\",\"italic\":\"Ležeče\",\"strike\":\"Prečrtano\",\"subscript\":\"Podpisano\",\"superscript\":\"Nadpisano\",\"underline\":\"Podčrtano\"},\"blockquote\":{\"toolbar\":\"Citat\"},\"clipboard\":{\"copy\":\"Kopiraj\",\"copyError\":\"Varnostne nastavitve brskalnika ne dopuščajo samodejnega kopiranja. Uporabite kombinacijo tipk na tipkovnici (Ctrl/Cmd+C).\",\"cut\":\"Izreži\",\"cutError\":\"Varnostne nastavitve brskalnika ne dopuščajo samodejnega izrezovanja. Uporabite kombinacijo tipk na tipkovnici (Ctrl/Cmd+X).\",\"paste\":\"Prilepi\",\"pasteArea\":\"Prilepi Prostor\",\"pasteMsg\":\"Prosim prilepite v sleči okvir s pomočjo tipkovnice (<STRONG>Ctrl/Cmd+V</STRONG>) in pritisnite <STRONG>V redu</STRONG>.\",\"securityMsg\":\"Zaradi varnostnih nastavitev vašega brskalnika urejevalnik ne more neposredno dostopati do odložišča. Vsebino odložišča ponovno prilepite v to okno.\",\"title\":\"Prilepi\"},\"contextmenu\":{\"options\":\"Možnosti Kontekstnega Menija\"},\"toolbar\":{\"toolbarCollapse\":\"Skrči Orodno Vrstico\",\"toolbarExpand\":\"Razširi Orodno Vrstico\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Urejevalnik orodne vrstice\"},\"elementspath\":{\"eleLabel\":\"Pot elementov\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Oblika\",\"panelTitle\":\"Oblika\",\"tag_address\":\"Napis\",\"tag_div\":\"Navaden (DIV)\",\"tag_h1\":\"Naslov 1\",\"tag_h2\":\"Naslov 2\",\"tag_h3\":\"Naslov 3\",\"tag_h4\":\"Naslov 4\",\"tag_h5\":\"Naslov 5\",\"tag_h6\":\"Naslov 6\",\"tag_p\":\"Navaden\",\"tag_pre\":\"Oblikovan\"},\"horizontalrule\":{\"toolbar\":\"Vstavi vodoravno črto\"},\"image\":{\"alertUrl\":\"Vnesite URL slike\",\"alt\":\"Nadomestno besedilo\",\"border\":\"Obroba\",\"btnUpload\":\"Pošlji na strežnik\",\"button2Img\":\"Želiš pretvoriti izbrani gumb s sliko v preprosto sliko?\",\"hSpace\":\"Vodoravni razmik\",\"img2Button\":\"Želiš pretvoriti izbrano sliko v gumb s sliko?\",\"infoTab\":\"Podatki o sliki\",\"linkTab\":\"Povezava\",\"lockRatio\":\"Zakleni razmerje\",\"menu\":\"Lastnosti slike\",\"resetSize\":\"Ponastavi velikost\",\"title\":\"Lastnosti slike\",\"titleButton\":\"Lastnosti gumba s sliko\",\"upload\":\"Pošlji\",\"urlMissing\":\"Manjka vir (URL) slike.\",\"vSpace\":\"Navpični razmik\",\"validateBorder\":\"Meja mora biti celo število.\",\"validateHSpace\":\"HSpace mora biti celo število.\",\"validateVSpace\":\"VSpace mora biti celo število.\"},\"indent\":{\"indent\":\"Povečaj zamik\",\"outdent\":\"Zmanjšaj zamik\"},\"fakeobjects\":{\"anchor\":\"Sidro\",\"flash\":\"Flash animacija\",\"hiddenfield\":\"Skrito polje\",\"iframe\":\"IFrame\",\"unknown\":\"Neznan objekt\"},\"link\":{\"acccessKey\":\"Dostopno Geslo\",\"advanced\":\"Napredno\",\"advisoryContentType\":\"Predlagani tip vsebine (content-type)\",\"advisoryTitle\":\"Predlagani naslov\",\"anchor\":{\"toolbar\":\"Vstavi/uredi zaznamek\",\"menu\":\"Lastnosti zaznamka\",\"title\":\"Lastnosti zaznamka\",\"name\":\"Ime zaznamka\",\"errorName\":\"Prosim vnesite ime zaznamka\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"Po ID-ju elementa\",\"anchorName\":\"Po imenu zaznamka\",\"charset\":\"Kodna tabela povezanega vira\",\"cssClasses\":\"Razred stilne predloge\",\"emailAddress\":\"Elektronski naslov\",\"emailBody\":\"Vsebina sporočila\",\"emailSubject\":\"Predmet sporočila\",\"id\":\"Id\",\"info\":\"Podatki o povezavi\",\"langCode\":\"Smer jezika\",\"langDir\":\"Smer jezika\",\"langDirLTR\":\"Od leve proti desni (LTR)\",\"langDirRTL\":\"Od desne proti levi (RTL)\",\"menu\":\"Uredi povezavo\",\"name\":\"Ime\",\"noAnchors\":\"(V tem dokumentu ni zaznamkov)\",\"noEmail\":\"Vnesite elektronski naslov\",\"noUrl\":\"Vnesite URL povezave\",\"other\":\"<drug>\",\"popupDependent\":\"Podokno (Netscape)\",\"popupFeatures\":\"Značilnosti pojavnega okna\",\"popupFullScreen\":\"Celozaslonska slika (IE)\",\"popupLeft\":\"Lega levo\",\"popupLocationBar\":\"Naslovna vrstica\",\"popupMenuBar\":\"Menijska vrstica\",\"popupResizable\":\"Spremenljive velikosti\",\"popupScrollBars\":\"Drsniki\",\"popupStatusBar\":\"Vrstica stanja\",\"popupToolbar\":\"Orodna vrstica\",\"popupTop\":\"Lega na vrhu\",\"rel\":\"Odnos\",\"selectAnchor\":\"Izberi zaznamek\",\"styles\":\"Slog\",\"tabIndex\":\"Številka tabulatorja\",\"target\":\"Cilj\",\"targetFrame\":\"<okvir>\",\"targetFrameName\":\"Ime ciljnega okvirja\",\"targetPopup\":\"<pojavno okno>\",\"targetPopupName\":\"Ime pojavnega okna\",\"title\":\"Povezava\",\"toAnchor\":\"Zaznamek na tej strani\",\"toEmail\":\"Elektronski naslov\",\"toUrl\":\"URL\",\"toolbar\":\"Vstavi/uredi povezavo\",\"type\":\"Vrsta povezave\",\"unlink\":\"Odstrani povezavo\",\"upload\":\"Prenesi\"},\"list\":{\"bulletedlist\":\"Označen seznam\",\"numberedlist\":\"Oštevilčen seznam\"},\"magicline\":{\"title\":\"Vstavite odstavek tukaj\"},\"maximize\":{\"maximize\":\"Maksimiraj\",\"minimize\":\"Minimiraj\"},\"pastetext\":{\"button\":\"Prilepi kot golo besedilo\",\"title\":\"Prilepi kot golo besedilo\"},\"pastefromword\":{\"confirmCleanup\":\"Besedilo, ki ga želite prilepiti je kopirano iz Word-a. Ali ga želite očistiti, preden ga prilepite?\",\"error\":\"Ni bilo mogoče očistiti prilepljenih podatkov zaradi notranje napake\",\"title\":\"Prilepi iz Worda\",\"toolbar\":\"Prilepi iz Worda\"},\"removeformat\":{\"toolbar\":\"Odstrani oblikovanje\"},\"sourcearea\":{\"toolbar\":\"Izvorna koda\"},\"specialchar\":{\"options\":\"Možnosti Posebnega Znaka\",\"title\":\"Izberi Posebni Znak\",\"toolbar\":\"Vstavi posebni znak\"},\"scayt\":{\"about\":\"O storitvi SCAYT\",\"aboutTab\":\"O storitvi\",\"addWord\":\"Dodaj besedo\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Slovarji\",\"disable\":\"Onemogoči SCAYT\",\"emptyDic\":\"Ime slovarja ne more biti prazno.\",\"enable\":\"Omogoči SCAYT\",\"ignore\":\"Prezri\",\"ignoreAll\":\"Prezri vse\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Jeziki\",\"languagesTab\":\"Jeziki\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"Več predlogov\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Možnosti\",\"optionsTab\":\"Možnosti\",\"title\":\"Črkovanje med tipkanjem\",\"toggle\":\"Preklopi SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Slog\",\"panelTitle\":\"Oblikovalni Stili\",\"panelTitle1\":\"Slogi odstavkov\",\"panelTitle2\":\"Slogi besedila\",\"panelTitle3\":\"Slogi objektov\"},\"table\":{\"border\":\"Velikost obrobe\",\"caption\":\"Naslov\",\"cell\":{\"menu\":\"Celica\",\"insertBefore\":\"Vstavi celico pred\",\"insertAfter\":\"Vstavi celico za\",\"deleteCell\":\"Izbriši celice\",\"merge\":\"Združi celice\",\"mergeRight\":\"Združi desno\",\"mergeDown\":\"Druži navzdol\",\"splitHorizontal\":\"Razdeli celico vodoravno\",\"splitVertical\":\"Razdeli celico navpično\",\"title\":\"Lastnosti celice\",\"cellType\":\"Vrsta celice\",\"rowSpan\":\"Razpon vrstic\",\"colSpan\":\"Razpon stolpcev\",\"wordWrap\":\"Prelom besedila\",\"hAlign\":\"Vodoravna poravnava\",\"vAlign\":\"Navpična poravnava\",\"alignBaseline\":\"Osnovnica\",\"bgColor\":\"Barva ozadja\",\"borderColor\":\"Barva obrobe\",\"data\":\"Podatki\",\"header\":\"Glava\",\"yes\":\"Da\",\"no\":\"Ne\",\"invalidWidth\":\"Širina celice mora biti število.\",\"invalidHeight\":\"Višina celice mora biti število.\",\"invalidRowSpan\":\"Razpon vrstic mora biti celo število.\",\"invalidColSpan\":\"Razpon stolpcev mora biti celo število.\",\"chooseColor\":\"Izberi\"},\"cellPad\":\"Polnilo med celicami\",\"cellSpace\":\"Razmik med celicami\",\"column\":{\"menu\":\"Stolpec\",\"insertBefore\":\"Vstavi stolpec pred\",\"insertAfter\":\"Vstavi stolpec za\",\"deleteColumn\":\"Izbriši stolpce\"},\"columns\":\"Stolpci\",\"deleteTable\":\"Izbriši tabelo\",\"headers\":\"Glave\",\"headersBoth\":\"Oboje\",\"headersColumn\":\"Prvi stolpec\",\"headersNone\":\"Brez\",\"headersRow\":\"Prva vrstica\",\"invalidBorder\":\"Širina obrobe mora biti število.\",\"invalidCellPadding\":\"Zamik celic mora biti število\",\"invalidCellSpacing\":\"Razmik med celicami mora biti število.\",\"invalidCols\":\"Število stolpcev mora biti večje od 0.\",\"invalidHeight\":\"Višina tabele mora biti število.\",\"invalidRows\":\"Število vrstic mora biti večje od 0.\",\"invalidWidth\":\"Širina tabele mora biti število.\",\"menu\":\"Lastnosti tabele\",\"row\":{\"menu\":\"Vrstica\",\"insertBefore\":\"Vstavi vrstico pred\",\"insertAfter\":\"Vstavi vrstico za\",\"deleteRow\":\"Izbriši vrstice\"},\"rows\":\"Vrstice\",\"summary\":\"Povzetek\",\"title\":\"Lastnosti tabele\",\"toolbar\":\"Tabela\",\"widthPc\":\"procentov\",\"widthPx\":\"pik\",\"widthUnit\":\"enota širine\"},\"undo\":{\"redo\":\"Ponovi\",\"undo\":\"Razveljavi\"},\"wsc\":{\"btnIgnore\":\"Prezri\",\"btnIgnoreAll\":\"Prezri vse\",\"btnReplace\":\"Zamenjaj\",\"btnReplaceAll\":\"Zamenjaj vse\",\"btnUndo\":\"Razveljavi\",\"changeTo\":\"Spremeni v\",\"errorLoading\":\"Napaka pri nalaganju storitve programa na naslovu %s.\",\"ieSpellDownload\":\"Črkovalnik ni nameščen. Ali ga želite prenesti sedaj?\",\"manyChanges\":\"Črkovanje je končano: Spremenjenih je bilo %1 besed\",\"noChanges\":\"Črkovanje je končano: Nobena beseda ni bila spremenjena\",\"noMispell\":\"Črkovanje je končano: Brez napak\",\"noSuggestions\":\"- Ni predlogov -\",\"notAvailable\":\"Oprostite, storitev trenutno ni dosegljiva.\",\"notInDic\":\"Ni v slovarju\",\"oneChange\":\"Črkovanje je končano: Spremenjena je bila ena beseda\",\"progress\":\"Preverjanje črkovanja se izvaja...\",\"title\":\"Črkovalnik\",\"toolbar\":\"Preveri črkovanje\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/sq.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['sq']={\"editor\":\"Redaktues i Pasur Teksti\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Shtyp ALT 0 për ndihmë\",\"browseServer\":\"Shfleto në Server\",\"url\":\"URL\",\"protocol\":\"Protokolli\",\"upload\":\"Ngarko\",\"uploadSubmit\":\"Dërgo në server\",\"image\":\"Imazh\",\"flash\":\"Objekt flash\",\"form\":\"Formular\",\"checkbox\":\"Checkbox\",\"radio\":\"Buton radio\",\"textField\":\"Fushë tekst\",\"textarea\":\"Hapësirë tekst\",\"hiddenField\":\"Fushë e fshehur\",\"button\":\"Buton\",\"select\":\"Menu zgjedhjeje\",\"imageButton\":\"Buton imazhi\",\"notSet\":\"<e pazgjedhur>\",\"id\":\"Id\",\"name\":\"Emër\",\"langDir\":\"Kod gjuhe\",\"langDirLtr\":\"Nga e majta në të djathtë (LTR)\",\"langDirRtl\":\"Nga e djathta në të majtë (RTL)\",\"langCode\":\"Kod gjuhe\",\"longDescr\":\"Përshkrim i hollësishëm\",\"cssClass\":\"Klasa stili CSS\",\"advisoryTitle\":\"Titull\",\"cssStyle\":\"Stil\",\"ok\":\"OK\",\"cancel\":\"Anulo\",\"close\":\"Mbyll\",\"preview\":\"Parashiko\",\"resize\":\"Ripërmaso\",\"generalTab\":\"Të përgjithshme\",\"advancedTab\":\"Të përparuara\",\"validateNumberFailed\":\"Vlera e futur nuk është një numër\",\"confirmNewPage\":\"Çdo ndryshim që nuk është ruajtur do humbasë. Je i sigurtë që dëshiron të krijosh një faqe të re?\",\"confirmCancel\":\"Disa opsione kanë ndryshuar. Je i sigurtë që dëshiron ta mbyllësh dritaren?\",\"options\":\"Opsione\",\"target\":\"Objektivi\",\"targetNew\":\"Dritare e re (_blank)\",\"targetTop\":\"Dritare në plan të parë (_top)\",\"targetSelf\":\"E njëjta dritare (_self)\",\"targetParent\":\"Dritarja prind (_parent)\",\"langDirLTR\":\"Nga e majta në të djathë (LTR)\",\"langDirRTL\":\"Nga e djathta në të majtë (RTL)\",\"styles\":\"Stil\",\"cssClasses\":\"Klasa Stili CSS\",\"width\":\"Gjerësi\",\"height\":\"Lartësi\",\"align\":\"Rreshtim\",\"alignLeft\":\"Majtas\",\"alignRight\":\"Djathtas\",\"alignCenter\":\"Qendër\",\"alignTop\":\"Lart\",\"alignMiddle\":\"Në mes\",\"alignBottom\":\"Poshtë\",\"invalidValue\":\"Vlerë e pavlefshme\",\"invalidHeight\":\"Lartësia duhet të jetë një numër\",\"invalidWidth\":\"Gjerësia duhet të jetë një numër\",\"invalidCssLength\":\"Vlera e fushës \\\"%1\\\" duhet të jetë një numër pozitiv me apo pa njësi matëse të vlefshme CSS (px, %, in, cm, mm, em, ex, pt ose pc).\",\"invalidHtmlLength\":\"Vlera e fushës \\\"%1\\\" duhet të jetë një numër pozitiv me apo pa njësi matëse të vlefshme HTML (px ose %)\",\"invalidInlineStyle\":\"Stili inline duhet të jetë një apo disa vlera të formatit \\\"emër: vlerë\\\", ndarë nga pikëpresje.\",\"cssLengthTooltip\":\"Fut një numër për vlerën në pixel apo një numër me një njësi të vlefshme CSS (px, %, in, cm, mm, ex, pt, ose pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, i padisponueshëm</span>\"},\"about\":{\"copy\":\"Të drejtat  e kopjimit &copy; $1. Të gjitha të drejtat e rezervuara.\",\"dlgTitle\":\"Rreth CKEditor\",\"help\":\"Kontrollo $1 për ndihmë.\",\"moreInfo\":\"Për informacione rreth licencave shih faqen tonë:\",\"title\":\"Rreth CKEditor\",\"userGuide\":\"Udhëzuesi i Shfrytëzuesit të CKEditor\"},\"basicstyles\":{\"bold\":\"Trash\",\"italic\":\"Pjerrët\",\"strike\":\"Nëpërmes\",\"subscript\":\"Nën-skriptë\",\"superscript\":\"Super-skriptë\",\"underline\":\"Nënvijëzuar\"},\"blockquote\":{\"toolbar\":\"Citatet\"},\"clipboard\":{\"copy\":\"Kopjo\",\"copyError\":\"Të dhënat e sigurisë së shfletuesit tuaj nuk lejojnë që redaktuesi automatikisht të kryej veprimin e kopjimit. Ju lutemi shfrytëzoni tastierën për këtë veprim (Ctrl/Cmd+C).\",\"cut\":\"Preje\",\"cutError\":\"Të dhënat e sigurisë së shfletuesit tuaj nuk lejojnë që redaktuesi automatikisht të kryej veprimin e prerjes. Ju lutemi shfrytëzoni tastierën për këtë veprim (Ctrl/Cmd+X).\",\"paste\":\"Hidhe\",\"pasteArea\":\"Hapësira Hedhëse\",\"pasteMsg\":\"Ju lutemi hidhni brenda kutizës në vijim duke shfrytëzuar tastierën (<strong>Ctrl/Cmd+V</strong>) dhe shtypni Mirë.\",\"securityMsg\":\"Për shkak të dhënave të sigurisë së shfletuesit tuaj, redaktuesi nuk është në gjendje të i qaset drejtpërdrejtë të dhanve të tabelës suaj të punës. Ju duhet të hidhni atë përsëri në këtë dritare.\",\"title\":\"Hidhe\"},\"contextmenu\":{\"options\":\"Mundësitë e Menysë së Kontekstit\"},\"toolbar\":{\"toolbarCollapse\":\"Zvogëlo Shiritin\",\"toolbarExpand\":\"Zgjero Shiritin\",\"toolbarGroups\":{\"document\":\"Dokument\",\"clipboard\":\"Tabela Punës/Ribëje\",\"editing\":\"Duke Redaktuar\",\"forms\":\"Formular\",\"basicstyles\":\"Stili Bazë\",\"paragraph\":\"Paragraf\",\"links\":\"Nyjet\",\"insert\":\"Shto\",\"styles\":\"Stil\",\"colors\":\"Ngjyrat\",\"tools\":\"Mjetet\"},\"toolbars\":\"Shiritet e Redaktuesit\"},\"elementspath\":{\"eleLabel\":\"Rruga e elementeve\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Formati\",\"panelTitle\":\"Formati i Paragrafit\",\"tag_address\":\"Adresa\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Titulli 1\",\"tag_h2\":\"Titulli 2\",\"tag_h3\":\"Titulli 3\",\"tag_h4\":\"Titulli 4\",\"tag_h5\":\"Titulli 5\",\"tag_h6\":\"Titulli 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatuar\"},\"horizontalrule\":{\"toolbar\":\"Vendos Vijë Horizontale\"},\"image\":{\"alertUrl\":\"Ju lutemi shkruani URL-në e fotos\",\"alt\":\"Tekst Alternativ\",\"border\":\"Korniza\",\"btnUpload\":\"Dërgo në server\",\"button2Img\":\"Dëshironi të e ndërroni pullën e fotos së selektuar në një foto të thjeshtë?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Dëshironi të ndryshoni foton e përzgjedhur në pullë?\",\"infoTab\":\"Informacione mbi Fotografinë\",\"linkTab\":\"Nyja\",\"lockRatio\":\"Mbyll Racionin\",\"menu\":\"Karakteristikat e Fotografisë\",\"resetSize\":\"Rikthe Madhësinë\",\"title\":\"Karakteristikat e Fotografisë\",\"titleButton\":\"Karakteristikat e Pullës së Fotografisë\",\"upload\":\"Ngarko\",\"urlMissing\":\"Mungon URL e burimit të fotografisë.\",\"vSpace\":\"Hapësira Vertikale\",\"validateBorder\":\"Korniza duhet të jetë numër i plotë.\",\"validateHSpace\":\"Hapësira horizontale duhet të jetë numër i plotë.\",\"validateVSpace\":\"Hapësira vertikale duhet të jetë numër i plotë.\"},\"indent\":{\"indent\":\"Rrite Identin\",\"outdent\":\"Zvogëlo Identin\"},\"fakeobjects\":{\"anchor\":\"Spirancë\",\"flash\":\"Objekt flash\",\"hiddenfield\":\"Fushë e fshehur\",\"iframe\":\"IFrame\",\"unknown\":\"Objekt i Panjohur\"},\"link\":{\"acccessKey\":\"Sipas ID-së së Elementit\",\"advanced\":\"Të përparuara\",\"advisoryContentType\":\"Lloji i Përmbajtjes Këshillimore\",\"advisoryTitle\":\"Titull\",\"anchor\":{\"toolbar\":\"Spirancë\",\"menu\":\"Redakto Spirancën\",\"title\":\"Anchor Properties\",\"name\":\"Emri i Spirancës\",\"errorName\":\"Ju lutemi shkruani emrin e spirancës\",\"remove\":\"Largo Spirancën\"},\"anchorId\":\"Sipas ID-së së Elementit\",\"anchorName\":\"Sipas Emrit të Spirancës\",\"charset\":\"Seti i Karaktereve të Burimeve të Nëdlidhura\",\"cssClasses\":\"Klasa stili CSS\",\"emailAddress\":\"Posta Elektronike\",\"emailBody\":\"Trupi i Porosisë\",\"emailSubject\":\"Titulli i Porosisë\",\"id\":\"Id\",\"info\":\"Informacione të Nyjes\",\"langCode\":\"Kod gjuhe\",\"langDir\":\"Drejtim teksti\",\"langDirLTR\":\"Nga e majta në të djathë (LTR)\",\"langDirRTL\":\"Nga e djathta në të majtë (RTL)\",\"menu\":\"Redakto Nyjen\",\"name\":\"Emër\",\"noAnchors\":\"(Nuk ka asnjë spirancë në dokument)\",\"noEmail\":\"Ju lutemi shkruani postën elektronike\",\"noUrl\":\"Ju lutemi shkruani URL-në e nyjes\",\"other\":\"<tjetër>\",\"popupDependent\":\"E Varur (Netscape)\",\"popupFeatures\":\"Karakteristikat e Dritares së Dialogut\",\"popupFullScreen\":\"Ekran i Plotë  (IE)\",\"popupLeft\":\"Pozita Majtas\",\"popupLocationBar\":\"Shiriti i Lokacionit\",\"popupMenuBar\":\"Shiriti i Menysë\",\"popupResizable\":\"I ndryshueshëm\",\"popupScrollBars\":\"Scroll Bars\",\"popupStatusBar\":\"Shiriti i Statutit\",\"popupToolbar\":\"Shiriti i Mejteve\",\"popupTop\":\"Top Pozita\",\"rel\":\"Marrëdhëniet\",\"selectAnchor\":\"Përzgjidh një Spirancë\",\"styles\":\"Stil\",\"tabIndex\":\"Tab Index\",\"target\":\"Objektivi\",\"targetFrame\":\"<frame>\",\"targetFrameName\":\"Emri i Kornizës së Synuar\",\"targetPopup\":\"<popup window>\",\"targetPopupName\":\"Emri i Dritares së Dialogut\",\"title\":\"Nyja\",\"toAnchor\":\"Lidhu me spirancën në tekst\",\"toEmail\":\"Posta Elektronike\",\"toUrl\":\"URL\",\"toolbar\":\"Nyja\",\"type\":\"Lloji i Nyjes\",\"unlink\":\"Largo Nyjen\",\"upload\":\"Ngarko\"},\"list\":{\"bulletedlist\":\"Vendos/Largo Listën me Pika\",\"numberedlist\":\"Vendos/Largo Listën me Numra\"},\"magicline\":{\"title\":\"Vendos paragraf këtu\"},\"maximize\":{\"maximize\":\"Zmadho\",\"minimize\":\"Zvogëlo\"},\"pastetext\":{\"button\":\"Hidhe si tekst të thjeshtë\",\"title\":\"Hidhe si Tekst të Thjeshtë\"},\"pastefromword\":{\"confirmCleanup\":\"Teksti që dëshironi të e hidhni siç duket është kopjuar nga Word-i. Dëshironi të e pastroni para se të e hidhni?\",\"error\":\"Nuk ishte e mundur të fshiheshin të dhënat e hedhura për shkak të një gabimi të brendshëm\",\"title\":\"Hidhe nga Word-i\",\"toolbar\":\"Hidhe nga Word-i\"},\"removeformat\":{\"toolbar\":\"Largo Formatin\"},\"sourcearea\":{\"toolbar\":\"Burimi\"},\"specialchar\":{\"options\":\"Mundësitë për Karaktere Speciale\",\"title\":\"Përzgjidh Karakter Special\",\"toolbar\":\"Vendos Karakter Special\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stil\",\"panelTitle\":\"Stilet e Formatimit\",\"panelTitle1\":\"Stilet e Bllokut\",\"panelTitle2\":\"Stili i Brendshëm\",\"panelTitle3\":\"Stilet e Objektit\"},\"table\":{\"border\":\"Madhësia e kornizave\",\"caption\":\"Titull\",\"cell\":{\"menu\":\"Qeli\",\"insertBefore\":\"Shto Qeli Para\",\"insertAfter\":\"Shto Qeli Prapa\",\"deleteCell\":\"Gris Qelitë\",\"merge\":\"Bashko Qelitë\",\"mergeRight\":\"Bashko Djathtas\",\"mergeDown\":\"Bashko Poshtë\",\"splitHorizontal\":\"Ndaj Qelinë Horizontalisht\",\"splitVertical\":\"Ndaj Qelinë Vertikalisht\",\"title\":\"Rekuizitat e Qelisë\",\"cellType\":\"Lloji i Qelisë\",\"rowSpan\":\"Bashko Rreshtat\",\"colSpan\":\"Bashko Kolonat\",\"wordWrap\":\"Fund i Fjalës\",\"hAlign\":\"Bashkimi Horizontal\",\"vAlign\":\"Bashkimi Vertikal\",\"alignBaseline\":\"Baza\",\"bgColor\":\"Ngjyra e Prapavijës\",\"borderColor\":\"Ngjyra e Kornizave\",\"data\":\"Të dhënat\",\"header\":\"Koka\",\"yes\":\"Po\",\"no\":\"Jo\",\"invalidWidth\":\"Gjerësia e qelisë duhet të jetë numër.\",\"invalidHeight\":\"Lartësia e qelisë duhet të jetë numër.\",\"invalidRowSpan\":\"Hapësira e rreshtave duhet të jetë numër i plotë.\",\"invalidColSpan\":\"Hapësira e kolonave duhet të jetë numër i plotë.\",\"chooseColor\":\"Përzgjidh\"},\"cellPad\":\"Mbushja e qelisë\",\"cellSpace\":\"Hapësira e qelisë\",\"column\":{\"menu\":\"Kolona\",\"insertBefore\":\"Vendos Kolonë Para\",\"insertAfter\":\"Vendos Kolonë Pas\",\"deleteColumn\":\"Gris Kolonat\"},\"columns\":\"Kolonat\",\"deleteTable\":\"Gris Tabelën\",\"headers\":\"Kokat\",\"headersBoth\":\"Së bashku\",\"headersColumn\":\"Kolona e parë\",\"headersNone\":\"Asnjë\",\"headersRow\":\"Rreshti i Parë\",\"invalidBorder\":\"Madhësia e kufinjve duhet të jetë numër.\",\"invalidCellPadding\":\"Mbushja e qelisë duhet të jetë numër pozitiv.\",\"invalidCellSpacing\":\"Hapësira e qelisë duhet të jetë numër pozitiv.\",\"invalidCols\":\"Numri i kolonave duhet të jetë numër më i madh se 0.\",\"invalidHeight\":\"Lartësia e tabelës duhet të jetë numër.\",\"invalidRows\":\"Numri i rreshtave duhet të jetë numër më i madh se 0.\",\"invalidWidth\":\"Gjerësia e tabelës duhet të jetë numër.\",\"menu\":\"Karakteristikat e Tabelës\",\"row\":{\"menu\":\"Rreshti\",\"insertBefore\":\"Shto Rresht Para\",\"insertAfter\":\"Shto Rresht Prapa\",\"deleteRow\":\"Gris Rreshtat\"},\"rows\":\"Rreshtat\",\"summary\":\"Përmbledhje\",\"title\":\"Karakteristikat e Tabelës\",\"toolbar\":\"Tabela\",\"widthPc\":\"përqind\",\"widthPx\":\"piksell\",\"widthUnit\":\"njësia e gjerësisë\"},\"undo\":{\"redo\":\"Ribëje\",\"undo\":\"Rizhbëje\"},\"wsc\":{\"btnIgnore\":\"Ignore\",\"btnIgnoreAll\":\"Ignore All\",\"btnReplace\":\"Replace\",\"btnReplaceAll\":\"Replace All\",\"btnUndo\":\"Undo\",\"changeTo\":\"Change to\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Spell checker not installed. Do you want to download it now?\",\"manyChanges\":\"Spell check complete: %1 words changed\",\"noChanges\":\"Spell check complete: No words changed\",\"noMispell\":\"Spell check complete: No misspellings found\",\"noSuggestions\":\"- No suggestions -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Not in dictionary\",\"oneChange\":\"Spell check complete: One word changed\",\"progress\":\"Spell check in progress...\",\"title\":\"Spell Check\",\"toolbar\":\"Check Spelling\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/sr-latn.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['sr-latn']={\"editor\":\"Bogati uređivač teksta\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Press ALT 0 for help\",\"browseServer\":\"Pretraži server\",\"url\":\"URL\",\"protocol\":\"Protokol\",\"upload\":\"Pošalji\",\"uploadSubmit\":\"Pošalji na server\",\"image\":\"Slika\",\"flash\":\"Fleš\",\"form\":\"Forma\",\"checkbox\":\"Polje za potvrdu\",\"radio\":\"Radio-dugme\",\"textField\":\"Tekstualno polje\",\"textarea\":\"Zona teksta\",\"hiddenField\":\"Skriveno polje\",\"button\":\"Dugme\",\"select\":\"Izborno polje\",\"imageButton\":\"Dugme sa slikom\",\"notSet\":\"<nije postavljeno>\",\"id\":\"Id\",\"name\":\"Naziv\",\"langDir\":\"Smer jezika\",\"langDirLtr\":\"S leva na desno (LTR)\",\"langDirRtl\":\"S desna na levo (RTL)\",\"langCode\":\"Kôd jezika\",\"longDescr\":\"Pun opis URL\",\"cssClass\":\"Stylesheet klase\",\"advisoryTitle\":\"Advisory naslov\",\"cssStyle\":\"Stil\",\"ok\":\"OK\",\"cancel\":\"Otkaži\",\"close\":\"Zatvori\",\"preview\":\"Izgled stranice\",\"resize\":\"Resize\",\"generalTab\":\"Opšte\",\"advancedTab\":\"Napredni tagovi\",\"validateNumberFailed\":\"Ova vrednost nije broj.\",\"confirmNewPage\":\"Nesačuvane promene ovog sadržaja će biti izgubljene. Jeste li sigurni da želita da učitate novu stranu?\",\"confirmCancel\":\"You have changed some options. Are you sure you want to close the dialog window?\",\"options\":\"Opcije\",\"target\":\"Meta\",\"targetNew\":\"Novi prozor (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Isti prozor (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"S leva na desno (LTR)\",\"langDirRTL\":\"S desna na levo (RTL)\",\"styles\":\"Stil\",\"cssClasses\":\"Stylesheet klase\",\"width\":\"Širina\",\"height\":\"Visina\",\"align\":\"Ravnanje\",\"alignLeft\":\"Levo\",\"alignRight\":\"Desno\",\"alignCenter\":\"Sredina\",\"alignTop\":\"Vrh\",\"alignMiddle\":\"Sredina\",\"alignBottom\":\"Dole\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Visina mora biti broj.\",\"invalidWidth\":\"Širina mora biti broj.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Podebljano\",\"italic\":\"Kurziv\",\"strike\":\"Precrtano\",\"subscript\":\"Indeks\",\"superscript\":\"Stepen\",\"underline\":\"Podvučeno\"},\"blockquote\":{\"toolbar\":\"Block Quote\"},\"clipboard\":{\"copy\":\"Kopiraj\",\"copyError\":\"Sigurnosna podešavanja Vašeg pretraživača ne dozvoljavaju operacije automatskog kopiranja teksta. Molimo Vas da koristite prečicu sa tastature (Ctrl/Cmd+C).\",\"cut\":\"Iseci\",\"cutError\":\"Sigurnosna podešavanja Vašeg pretraživača ne dozvoljavaju operacije automatskog isecanja teksta. Molimo Vas da koristite prečicu sa tastature (Ctrl/Cmd+X).\",\"paste\":\"Zalepi\",\"pasteArea\":\"Prostor za lepljenje\",\"pasteMsg\":\"Molimo Vas da zalepite unutar donje povrine koristeći tastaturnu prečicu (<STRONG>Ctrl/Cmd+V</STRONG>) i da pritisnete <STRONG>OK</STRONG>.\",\"securityMsg\":\"Zbog sigurnosnih postavki vašeg pregledača, editor nije u mogućnosti da direktno pristupi podacima u klipbordu. Potrebno je da zalepite još jednom u ovom prozoru.\",\"title\":\"Zalepi\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Suzi alatnu traku\",\"toolbarExpand\":\"Proširi alatnu traku\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Alatne trake\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Format\",\"panelTitle\":\"Format\",\"tag_address\":\"Adresa\",\"tag_div\":\"Normalno (DIV)\",\"tag_h1\":\"Naslov 1\",\"tag_h2\":\"Naslov 2\",\"tag_h3\":\"Naslov 3\",\"tag_h4\":\"Naslov 4\",\"tag_h5\":\"Naslov 5\",\"tag_h6\":\"Naslov 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatirano\"},\"horizontalrule\":{\"toolbar\":\"Unesi horizontalnu liniju\"},\"image\":{\"alertUrl\":\"Unesite URL slike\",\"alt\":\"Alternativni tekst\",\"border\":\"Okvir\",\"btnUpload\":\"Pošalji na server\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"Info slike\",\"linkTab\":\"Link\",\"lockRatio\":\"Zaključaj odnos\",\"menu\":\"Osobine slika\",\"resetSize\":\"Resetuj veličinu\",\"title\":\"Osobine slika\",\"titleButton\":\"Osobine dugmeta sa slikom\",\"upload\":\"Pošalji\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"Uvećaj levu marginu\",\"outdent\":\"Smanji levu marginu\"},\"fakeobjects\":{\"anchor\":\"Unesi/izmeni sidro\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Skriveno polje\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"Pristupni taster\",\"advanced\":\"Napredni tagovi\",\"advisoryContentType\":\"Advisory vrsta sadržaja\",\"advisoryTitle\":\"Advisory naslov\",\"anchor\":{\"toolbar\":\"Unesi/izmeni sidro\",\"menu\":\"Osobine sidra\",\"title\":\"Osobine sidra\",\"name\":\"Naziv sidra\",\"errorName\":\"Unesite naziv sidra\",\"remove\":\"Ukloni sidro\"},\"anchorId\":\"Po Id-u elementa\",\"anchorName\":\"Po nazivu sidra\",\"charset\":\"Linked Resource Charset\",\"cssClasses\":\"Stylesheet klase\",\"emailAddress\":\"E-Mail adresa\",\"emailBody\":\"Sadržaj poruke\",\"emailSubject\":\"Naslov\",\"id\":\"Id\",\"info\":\"Link Info\",\"langCode\":\"Smer jezika\",\"langDir\":\"Smer jezika\",\"langDirLTR\":\"S leva na desno (LTR)\",\"langDirRTL\":\"S desna na levo (RTL)\",\"menu\":\"Izmeni link\",\"name\":\"Naziv\",\"noAnchors\":\"(Nema dostupnih sidra)\",\"noEmail\":\"Otkucajte adresu elektronske pote\",\"noUrl\":\"Unesite URL linka\",\"other\":\"<остало>\",\"popupDependent\":\"Zavisno (Netscape)\",\"popupFeatures\":\"Mogućnosti popup prozora\",\"popupFullScreen\":\"Prikaz preko celog ekrana (IE)\",\"popupLeft\":\"Od leve ivice ekrana (px)\",\"popupLocationBar\":\"Lokacija\",\"popupMenuBar\":\"Kontekstni meni\",\"popupResizable\":\"Promenljive veličine\",\"popupScrollBars\":\"Scroll bar\",\"popupStatusBar\":\"Statusna linija\",\"popupToolbar\":\"Toolbar\",\"popupTop\":\"Od vrha ekrana (px)\",\"rel\":\"Odnos\",\"selectAnchor\":\"Odaberi sidro\",\"styles\":\"Stil\",\"tabIndex\":\"Tab indeks\",\"target\":\"Meta\",\"targetFrame\":\"<okvir>\",\"targetFrameName\":\"Naziv odredišnog frejma\",\"targetPopup\":\"<popup prozor>\",\"targetPopupName\":\"Naziv popup prozora\",\"title\":\"Link\",\"toAnchor\":\"Sidro na ovoj stranici\",\"toEmail\":\"E-Mail\",\"toUrl\":\"URL\",\"toolbar\":\"Unesi/izmeni link\",\"type\":\"Vrsta linka\",\"unlink\":\"Ukloni link\",\"upload\":\"Pošalji\"},\"list\":{\"bulletedlist\":\"Nenabrojiva lista\",\"numberedlist\":\"Nabrojiva lista\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maximize\",\"minimize\":\"Minimize\"},\"pastetext\":{\"button\":\"Zalepi kao čist tekst\",\"title\":\"Zalepi kao čist tekst\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"Zalepi iz Worda\",\"toolbar\":\"Zalepi iz Worda\"},\"removeformat\":{\"toolbar\":\"Ukloni formatiranje\"},\"sourcearea\":{\"toolbar\":\"Kôd\"},\"specialchar\":{\"options\":\"Special Character Options\",\"title\":\"Odaberite specijalni karakter\",\"toolbar\":\"Unesi specijalni karakter\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Stil\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"Veličina okvira\",\"caption\":\"Naslov tabele\",\"cell\":{\"menu\":\"Cell\",\"insertBefore\":\"Insert Cell Before\",\"insertAfter\":\"Insert Cell After\",\"deleteCell\":\"Obriši ćelije\",\"merge\":\"Spoj celije\",\"mergeRight\":\"Merge Right\",\"mergeDown\":\"Merge Down\",\"splitHorizontal\":\"Split Cell Horizontally\",\"splitVertical\":\"Split Cell Vertically\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"Razmak ćelija\",\"cellSpace\":\"Ćelijski prostor\",\"column\":{\"menu\":\"Column\",\"insertBefore\":\"Insert Column Before\",\"insertAfter\":\"Insert Column After\",\"deleteColumn\":\"Obriši kolone\"},\"columns\":\"Kolona\",\"deleteTable\":\"Izbriši tabelu\",\"headers\":\"Zaglavlja\",\"headersBoth\":\"Oba\",\"headersColumn\":\"Prva kolona\",\"headersNone\":\"None\",\"headersRow\":\"Prvi red\",\"invalidBorder\":\"Veličina okvira mora biti broj.\",\"invalidCellPadding\":\"Padding polja mora biti pozitivan broj.\",\"invalidCellSpacing\":\"Razmak između ćelija mora biti pozitivan broj.\",\"invalidCols\":\"Broj kolona mora biti broj veći od 0.\",\"invalidHeight\":\"Visina tabele mora biti broj.\",\"invalidRows\":\"Broj redova mora biti veći od 0.\",\"invalidWidth\":\"Širina tabele mora biti broj.\",\"menu\":\"Osobine tabele\",\"row\":{\"menu\":\"Row\",\"insertBefore\":\"Insert Row Before\",\"insertAfter\":\"Insert Row After\",\"deleteRow\":\"Obriši redove\"},\"rows\":\"Redova\",\"summary\":\"Sažetak\",\"title\":\"Osobine tabele\",\"toolbar\":\"Tabela\",\"widthPc\":\"procenata\",\"widthPx\":\"piksela\",\"widthUnit\":\"jedinica za širinu\"},\"undo\":{\"redo\":\"Ponovi akciju\",\"undo\":\"Poni�ti akciju\"},\"wsc\":{\"btnIgnore\":\"Ignoriši\",\"btnIgnoreAll\":\"Ignoriši sve\",\"btnReplace\":\"Zameni\",\"btnReplaceAll\":\"Zameni sve\",\"btnUndo\":\"Vrati akciju\",\"changeTo\":\"Izmeni\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Provera spelovanja nije instalirana. Da li želite da je skinete sa Interneta?\",\"manyChanges\":\"Provera spelovanja završena: %1 reč(i) je izmenjeno\",\"noChanges\":\"Provera spelovanja završena: Nije izmenjena nijedna rec\",\"noMispell\":\"Provera spelovanja završena: greške nisu pronadene\",\"noSuggestions\":\"- Bez sugestija -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Nije u rečniku\",\"oneChange\":\"Provera spelovanja završena: Izmenjena je jedna reč\",\"progress\":\"Provera spelovanja u toku...\",\"title\":\"Spell Check\",\"toolbar\":\"Proveri spelovanje\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/sr.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['sr']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Press ALT 0 for help\",\"browseServer\":\"Претражи сервер\",\"url\":\"УРЛ\",\"protocol\":\"Протокол\",\"upload\":\"Пошаљи\",\"uploadSubmit\":\"Пошаљи на сервер\",\"image\":\"Слика\",\"flash\":\"Флеш елемент\",\"form\":\"Форма\",\"checkbox\":\"Поље за потврду\",\"radio\":\"Радио-дугме\",\"textField\":\"Текстуално поље\",\"textarea\":\"Зона текста\",\"hiddenField\":\"Скривено поље\",\"button\":\"Дугме\",\"select\":\"Изборно поље\",\"imageButton\":\"Дугме са сликом\",\"notSet\":\"<није постављено>\",\"id\":\"Ид\",\"name\":\"Назив\",\"langDir\":\"Смер језика\",\"langDirLtr\":\"С лева на десно (LTR)\",\"langDirRtl\":\"С десна на лево (RTL)\",\"langCode\":\"Kôд језика\",\"longDescr\":\"Пун опис УРЛ\",\"cssClass\":\"Stylesheet класе\",\"advisoryTitle\":\"Advisory наслов\",\"cssStyle\":\"Стил\",\"ok\":\"OK\",\"cancel\":\"Oткажи\",\"close\":\"Затвори\",\"preview\":\"Изглед странице\",\"resize\":\"Resize\",\"generalTab\":\"Опште\",\"advancedTab\":\"Напредни тагови\",\"validateNumberFailed\":\"Ова вредност није цигра.\",\"confirmNewPage\":\"Any unsaved changes to this content will be lost. Are you sure you want to load new page?\",\"confirmCancel\":\"You have changed some options. Are you sure you want to close the dialog window?\",\"options\":\"Опције\",\"target\":\"Meтa\",\"targetNew\":\"New Window (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"Same Window (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"С лева на десно (LTR)\",\"langDirRTL\":\"С десна на лево (RTL)\",\"styles\":\"Стил\",\"cssClasses\":\"Stylesheet класе\",\"width\":\"Ширина\",\"height\":\"Висина\",\"align\":\"Равнање\",\"alignLeft\":\"Лево\",\"alignRight\":\"Десно\",\"alignCenter\":\"Средина\",\"alignTop\":\"Врх\",\"alignMiddle\":\"Средина\",\"alignBottom\":\"Доле\",\"invalidValue\":\"Invalid value.\",\"invalidHeight\":\"Height must be a number.\",\"invalidWidth\":\"Width must be a number.\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Подебљано\",\"italic\":\"Курзив\",\"strike\":\"Прецртано\",\"subscript\":\"Индекс\",\"superscript\":\"Степен\",\"underline\":\"Подвучено\"},\"blockquote\":{\"toolbar\":\"Block Quote\"},\"clipboard\":{\"copy\":\"Копирај\",\"copyError\":\"Сигурносна подешавања Вашег претраживача не дозвољавају операције аутоматског копирања текста. Молимо Вас да користите пречицу са тастатуре (Ctrl/Cmd+C).\",\"cut\":\"Исеци\",\"cutError\":\"Сигурносна подешавања Вашег претраживача не дозвољавају операције аутоматског исецања текста. Молимо Вас да користите пречицу са тастатуре (Ctrl/Cmd+X).\",\"paste\":\"Залепи\",\"pasteArea\":\"Залепи зону\",\"pasteMsg\":\"Молимо Вас да залепите унутар доње површине користећи тастатурну пречицу (<STRONG>Ctrl/Cmd+V</STRONG>) и да притиснете <STRONG>OK</STRONG>.\",\"securityMsg\":\"Због сигурносних подешавања претраживача, едитор не може да приступи оставу. Требате да га поново залепите у овом прозору.\",\"title\":\"Залепи\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Склопи алатну траку\",\"toolbarExpand\":\"Прошири алатну траку\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Едитор алатне траке\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Формат\",\"panelTitle\":\"Формат\",\"tag_address\":\"Adresa\",\"tag_div\":\"Нормално (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatirano\"},\"horizontalrule\":{\"toolbar\":\"Унеси хоризонталну линију\"},\"image\":{\"alertUrl\":\"Унесите УРЛ слике\",\"alt\":\"Алтернативни текст\",\"border\":\"Оквир\",\"btnUpload\":\"Пошаљи на сервер\",\"button2Img\":\"Да ли желите да промените одабрану слику дугмета као једноставну слику?\",\"hSpace\":\"HSpace\",\"img2Button\":\"Да ли желите да промените одабрану слику у слику дугмета?\",\"infoTab\":\"Инфо слике\",\"linkTab\":\"Линк\",\"lockRatio\":\"Закључај однос\",\"menu\":\"Особине слика\",\"resetSize\":\"Ресетуј величину\",\"title\":\"Особине слика\",\"titleButton\":\"Особине дугмета са сликом\",\"upload\":\"Пошаљи\",\"urlMissing\":\"Недостаје УРЛ слике.\",\"vSpace\":\"VSpace\",\"validateBorder\":\"Ивица треба да буде цифра.\",\"validateHSpace\":\"HSpace треба да буде цифра.\",\"validateVSpace\":\"VSpace треба да буде цифра.\"},\"indent\":{\"indent\":\"Увећај леву маргину\",\"outdent\":\"Смањи леву маргину\"},\"fakeobjects\":{\"anchor\":\"Anchor\",\"flash\":\"Flash Animation\",\"hiddenfield\":\"Hidden Field\",\"iframe\":\"IFrame\",\"unknown\":\"Unknown Object\"},\"link\":{\"acccessKey\":\"Приступни тастер\",\"advanced\":\"Напредни тагови\",\"advisoryContentType\":\"Advisory врста садржаја\",\"advisoryTitle\":\"Advisory наслов\",\"anchor\":{\"toolbar\":\"Унеси/измени сидро\",\"menu\":\"Особине сидра\",\"title\":\"Особине сидра\",\"name\":\"Име сидра\",\"errorName\":\"Молимо Вас да унесете име сидра\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"Пo Ид-jу елемента\",\"anchorName\":\"По називу сидра\",\"charset\":\"Linked Resource Charset\",\"cssClasses\":\"Stylesheet класе\",\"emailAddress\":\"Адреса електронске поште\",\"emailBody\":\"Садржај поруке\",\"emailSubject\":\"Наслов\",\"id\":\"Ид\",\"info\":\"Линк инфо\",\"langCode\":\"Смер језика\",\"langDir\":\"Смер језика\",\"langDirLTR\":\"С лева на десно (LTR)\",\"langDirRTL\":\"С десна на лево (RTL)\",\"menu\":\"Промени линк\",\"name\":\"Назив\",\"noAnchors\":\"(Нема доступних сидра)\",\"noEmail\":\"Откуцајте адресу електронске поште\",\"noUrl\":\"Унесите УРЛ линка\",\"other\":\"<друго>\",\"popupDependent\":\"Зависно (Netscape)\",\"popupFeatures\":\"Могућности искачућег прозора\",\"popupFullScreen\":\"Приказ преко целог екрана (ИE)\",\"popupLeft\":\"Од леве ивице екрана (пиксела)\",\"popupLocationBar\":\"Локација\",\"popupMenuBar\":\"Контекстни мени\",\"popupResizable\":\"Величина се мења\",\"popupScrollBars\":\"Скрол бар\",\"popupStatusBar\":\"Статусна линија\",\"popupToolbar\":\"Toolbar\",\"popupTop\":\"Од врха екрана (пиксела)\",\"rel\":\"Однос\",\"selectAnchor\":\"Одабери сидро\",\"styles\":\"Стил\",\"tabIndex\":\"Таб индекс\",\"target\":\"Meтa\",\"targetFrame\":\"<оквир>\",\"targetFrameName\":\"Назив одредишног фрејма\",\"targetPopup\":\"<искачући прозор>\",\"targetPopupName\":\"Назив искачућег прозора\",\"title\":\"Линк\",\"toAnchor\":\"Сидро на овој страници\",\"toEmail\":\"Eлектронска пошта\",\"toUrl\":\"УРЛ\",\"toolbar\":\"Унеси/измени линк\",\"type\":\"Врста линка\",\"unlink\":\"Уклони линк\",\"upload\":\"Пошаљи\"},\"list\":{\"bulletedlist\":\"Ненабројива листа\",\"numberedlist\":\"Набројиву листу\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"Maximize\",\"minimize\":\"Minimize\"},\"pastetext\":{\"button\":\"Залепи као чист текст\",\"title\":\"Залепи као чист текст\"},\"pastefromword\":{\"confirmCleanup\":\"The text you want to paste seems to be copied from Word. Do you want to clean it before pasting?\",\"error\":\"It was not possible to clean up the pasted data due to an internal error\",\"title\":\"Залепи из Worda\",\"toolbar\":\"Залепи из Worda\"},\"removeformat\":{\"toolbar\":\"Уклони форматирање\"},\"sourcearea\":{\"toolbar\":\"Kôд\"},\"specialchar\":{\"options\":\"Опције специјалног карактера\",\"title\":\"Одаберите специјални карактер\",\"toolbar\":\"Унеси специјални карактер\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Стил\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"Величина оквира\",\"caption\":\"Наслов табеле\",\"cell\":{\"menu\":\"Cell\",\"insertBefore\":\"Insert Cell Before\",\"insertAfter\":\"Insert Cell After\",\"deleteCell\":\"Обриши ћелије\",\"merge\":\"Спој ћелије\",\"mergeRight\":\"Merge Right\",\"mergeDown\":\"Merge Down\",\"splitHorizontal\":\"Split Cell Horizontally\",\"splitVertical\":\"Split Cell Vertically\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"Размак ћелија\",\"cellSpace\":\"Ћелијски простор\",\"column\":{\"menu\":\"Column\",\"insertBefore\":\"Insert Column Before\",\"insertAfter\":\"Insert Column After\",\"deleteColumn\":\"Обриши колоне\"},\"columns\":\"Kолона\",\"deleteTable\":\"Обриши таблу\",\"headers\":\"Поглавља\",\"headersBoth\":\"Оба\",\"headersColumn\":\"Прва колона\",\"headersNone\":\"None\",\"headersRow\":\"Први ред\",\"invalidBorder\":\"Величина ивице треба да буде цифра.\",\"invalidCellPadding\":\"Пуњење ћелије треба да буде позитивна цифра.\",\"invalidCellSpacing\":\"Размак ћелије треба да буде позитивна цифра.\",\"invalidCols\":\"Број колона треба да буде цифра већа од 0.\",\"invalidHeight\":\"Висина табеле треба да буде цифра.\",\"invalidRows\":\"Број реда треба да буде цифра већа од 0.\",\"invalidWidth\":\"Ширина табеле треба да буде цифра.\",\"menu\":\"Особине табеле\",\"row\":{\"menu\":\"Row\",\"insertBefore\":\"Insert Row Before\",\"insertAfter\":\"Insert Row After\",\"deleteRow\":\"Обриши редове\"},\"rows\":\"Редова\",\"summary\":\"Резиме\",\"title\":\"Особине табеле\",\"toolbar\":\"Табела\",\"widthPc\":\"процената\",\"widthPx\":\"пиксела\",\"widthUnit\":\"јединица ширине\"},\"undo\":{\"redo\":\"Понови акцију\",\"undo\":\"Поништи акцију\"},\"wsc\":{\"btnIgnore\":\"Игнориши\",\"btnIgnoreAll\":\"Игнориши све\",\"btnReplace\":\"Замени\",\"btnReplaceAll\":\"Замени све\",\"btnUndo\":\"Врати акцију\",\"changeTo\":\"Измени\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"Провера спеловања није инсталирана. Да ли желите да је скинете са Интернета?\",\"manyChanges\":\"Провера спеловања завршена:  %1 реч(и) је измењено\",\"noChanges\":\"Провера спеловања завршена: Није измењена ниједна реч\",\"noMispell\":\"Провера спеловања завршена: грешке нису пронађене\",\"noSuggestions\":\"- Без сугестија -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"Није у речнику\",\"oneChange\":\"Провера спеловања завршена: Измењена је једна реч\",\"progress\":\"Провера спеловања у току...\",\"title\":\"Spell Check\",\"toolbar\":\"Провери спеловање\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/sv.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['sv']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Tryck ALT 0 för hjälp\",\"browseServer\":\"Bläddra på server\",\"url\":\"URL\",\"protocol\":\"Protokoll\",\"upload\":\"Ladda upp\",\"uploadSubmit\":\"Skicka till server\",\"image\":\"Bild\",\"flash\":\"Flash\",\"form\":\"Formulär\",\"checkbox\":\"Kryssruta\",\"radio\":\"Alternativknapp\",\"textField\":\"Textfält\",\"textarea\":\"Textruta\",\"hiddenField\":\"Dolt fält\",\"button\":\"Knapp\",\"select\":\"Flervalslista\",\"imageButton\":\"Bildknapp\",\"notSet\":\"<ej angivet>\",\"id\":\"Id\",\"name\":\"Namn\",\"langDir\":\"Språkriktning\",\"langDirLtr\":\"Vänster till Höger (VTH)\",\"langDirRtl\":\"Höger till Vänster (HTV)\",\"langCode\":\"Språkkod\",\"longDescr\":\"URL-beskrivning\",\"cssClass\":\"Stilmall\",\"advisoryTitle\":\"Titel\",\"cssStyle\":\"Stilmall\",\"ok\":\"OK\",\"cancel\":\"Avbryt\",\"close\":\"Stäng\",\"preview\":\"Förhandsgranska\",\"resize\":\"Dra för att ändra storlek\",\"generalTab\":\"Allmänt\",\"advancedTab\":\"Avancerad\",\"validateNumberFailed\":\"Värdet är inte ett nummer.\",\"confirmNewPage\":\"Alla ändringar i innehållet kommer att förloras. Är du säker på att du vill ladda en ny sida?\",\"confirmCancel\":\"Några av alternativen har ändrats. Är du säker på att du vill stänga dialogrutan?\",\"options\":\"Alternativ\",\"target\":\"Mål\",\"targetNew\":\"Nytt fönster (_blank)\",\"targetTop\":\"Översta fönstret (_top)\",\"targetSelf\":\"Samma fönster (_self)\",\"targetParent\":\"Föregående fönster (_parent)\",\"langDirLTR\":\"Vänster till höger (LTR)\",\"langDirRTL\":\"Höger till vänster (RTL)\",\"styles\":\"Stil\",\"cssClasses\":\"Stilmallar\",\"width\":\"Bredd\",\"height\":\"Höjd\",\"align\":\"Justering\",\"alignLeft\":\"Vänster\",\"alignRight\":\"Höger\",\"alignCenter\":\"Centrerad\",\"alignTop\":\"Överkant\",\"alignMiddle\":\"Mitten\",\"alignBottom\":\"Nederkant\",\"invalidValue\":\"Felaktigt värde.\",\"invalidHeight\":\"Höjd måste vara ett nummer.\",\"invalidWidth\":\"Bredd måste vara ett nummer.\",\"invalidCssLength\":\"Värdet för fältet \\\"%1\\\" måste vara ett positivt nummer med eller utan CSS-mätenheter (px, %, in, cm, mm, em, ex, pt, eller pc).\",\"invalidHtmlLength\":\"Värdet för fältet \\\"%1\\\" måste vara ett positivt nummer med eller utan godkända HTML-mätenheter (px eller %).\",\"invalidInlineStyle\":\"Det angivna värdet för style måste innehålla en eller flera tupler separerade med semikolon i följande format: \\\"name : value\\\"\",\"cssLengthTooltip\":\"Ange ett nummer i pixlar eller ett nummer men godkänd CSS-mätenhet (px, %, in, cm, mm, em, ex, pt, eller pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, Ej tillgänglig</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Alla rättigheter reserverade.\",\"dlgTitle\":\"Om CKEditor\",\"help\":\"Se $1 för hjälp.\",\"moreInfo\":\"För information av licensiering besök vår hemsida:\",\"title\":\"Om CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"Fet\",\"italic\":\"Kursiv\",\"strike\":\"Genomstruken\",\"subscript\":\"Nedsänkta tecken\",\"superscript\":\"Upphöjda tecken\",\"underline\":\"Understruken\"},\"blockquote\":{\"toolbar\":\"Blockcitat\"},\"clipboard\":{\"copy\":\"Kopiera\",\"copyError\":\"Säkerhetsinställningar i Er webbläsare tillåter inte åtgärden kopiera. Använd (Ctrl/Cmd+C) istället.\",\"cut\":\"Klipp ut\",\"cutError\":\"Säkerhetsinställningar i Er webbläsare tillåter inte åtgärden klipp ut. Använd (Ctrl/Cmd+X) istället.\",\"paste\":\"Klistra in\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"Var god och klistra in Er text i rutan nedan genom att använda (<strong>Ctrl/Cmd+V</strong>) klicka sen på OK.\",\"securityMsg\":\"På grund av din webbläsares säkerhetsinställningar kan verktyget inte få åtkomst till urklippsdatan. Var god och använd detta fönster istället.\",\"title\":\"Klistra in\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"Dölj verktygsfält\",\"toolbarExpand\":\"Visa verktygsfält\",\"toolbarGroups\":{\"document\":\"Dokument\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"Redigera verktygsfält\"},\"elementspath\":{\"eleLabel\":\"Elementets sökväg\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"Teckenformat\",\"panelTitle\":\"Teckenformat\",\"tag_address\":\"Adress\",\"tag_div\":\"Normal (DIV)\",\"tag_h1\":\"Rubrik 1\",\"tag_h2\":\"Rubrik 2\",\"tag_h3\":\"Rubrik 3\",\"tag_h4\":\"Rubrik 4\",\"tag_h5\":\"Rubrik 5\",\"tag_h6\":\"Rubrik 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formaterad\"},\"horizontalrule\":{\"toolbar\":\"Infoga horisontal linje\"},\"image\":{\"alertUrl\":\"Var god och ange bildens URL\",\"alt\":\"Alternativ text\",\"border\":\"Kant\",\"btnUpload\":\"Skicka till server\",\"button2Img\":\"Vill du omvandla den valda bildknappen på en enkel bild?\",\"hSpace\":\"Horis. marginal\",\"img2Button\":\"Vill du omvandla den valda bildknappen på en enkel bild?\",\"infoTab\":\"Bildinformation\",\"linkTab\":\"Länk\",\"lockRatio\":\"Lås höjd/bredd förhållanden\",\"menu\":\"Bildegenskaper\",\"resetSize\":\"Återställ storlek\",\"title\":\"Bildegenskaper\",\"titleButton\":\"Egenskaper för bildknapp\",\"upload\":\"Ladda upp\",\"urlMissing\":\"Bildkällans URL saknas.\",\"vSpace\":\"Vert. marginal\",\"validateBorder\":\"Kantlinje måste vara ett heltal.\",\"validateHSpace\":\"HSpace måste vara ett heltal.\",\"validateVSpace\":\"VSpace måste vara ett heltal.\"},\"indent\":{\"indent\":\"Öka indrag\",\"outdent\":\"Minska indrag\"},\"fakeobjects\":{\"anchor\":\"Ankare\",\"flash\":\"Flashanimation\",\"hiddenfield\":\"Gömt fält\",\"iframe\":\"iFrame\",\"unknown\":\"Okänt objekt\"},\"link\":{\"acccessKey\":\"Behörighetsnyckel\",\"advanced\":\"Avancerad\",\"advisoryContentType\":\"Innehållstyp\",\"advisoryTitle\":\"Titel\",\"anchor\":{\"toolbar\":\"Infoga/Redigera ankarlänk\",\"menu\":\"Egenskaper för ankarlänk\",\"title\":\"Egenskaper för ankarlänk\",\"name\":\"Ankarnamn\",\"errorName\":\"Var god ange ett ankarnamn\",\"remove\":\"Radera ankare\"},\"anchorId\":\"Efter element-id\",\"anchorName\":\"Efter ankarnamn\",\"charset\":\"Teckenuppställning\",\"cssClasses\":\"Stilmall\",\"emailAddress\":\"E-postadress\",\"emailBody\":\"Innehåll\",\"emailSubject\":\"Ämne\",\"id\":\"Id\",\"info\":\"Länkinformation\",\"langCode\":\"Språkkod\",\"langDir\":\"Språkriktning\",\"langDirLTR\":\"Vänster till höger (VTH)\",\"langDirRTL\":\"Höger till vänster (HTV)\",\"menu\":\"Redigera länk\",\"name\":\"Namn\",\"noAnchors\":\"(Inga ankare kunde hittas)\",\"noEmail\":\"Var god ange e-postadress\",\"noUrl\":\"Var god ange länkens URL\",\"other\":\"<annan>\",\"popupDependent\":\"Beroende (endast Netscape)\",\"popupFeatures\":\"Popup-fönstrets egenskaper\",\"popupFullScreen\":\"Helskärm (endast IE)\",\"popupLeft\":\"Position från vänster\",\"popupLocationBar\":\"Adressfält\",\"popupMenuBar\":\"Menyfält\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"Scrolllista\",\"popupStatusBar\":\"Statusfält\",\"popupToolbar\":\"Verktygsfält\",\"popupTop\":\"Position från sidans topp\",\"rel\":\"Förhållande\",\"selectAnchor\":\"Välj ett ankare\",\"styles\":\"Stilmall\",\"tabIndex\":\"Tabindex\",\"target\":\"Mål\",\"targetFrame\":\"<ram>\",\"targetFrameName\":\"Målets ramnamn\",\"targetPopup\":\"<popup-fönster>\",\"targetPopupName\":\"Popup-fönstrets namn\",\"title\":\"Länk\",\"toAnchor\":\"Länk till ankare i texten\",\"toEmail\":\"E-post\",\"toUrl\":\"URL\",\"toolbar\":\"Infoga/Redigera länk\",\"type\":\"Länktyp\",\"unlink\":\"Radera länk\",\"upload\":\"Ladda upp\"},\"list\":{\"bulletedlist\":\"Punktlista\",\"numberedlist\":\"Numrerad lista\"},\"magicline\":{\"title\":\"Infoga paragraf här\"},\"maximize\":{\"maximize\":\"Maximera\",\"minimize\":\"Minimera\"},\"pastetext\":{\"button\":\"Klistra in som vanlig text\",\"title\":\"Klistra in som vanlig text\"},\"pastefromword\":{\"confirmCleanup\":\"Texten du vill klistra in verkar vara kopierad från Word. Vill du rensa den innan du klistrar in den?\",\"error\":\"Det var inte möjligt att städa upp den inklistrade data på grund av ett internt fel\",\"title\":\"Klistra in från Word\",\"toolbar\":\"Klistra in från Word\"},\"removeformat\":{\"toolbar\":\"Radera formatering\"},\"sourcearea\":{\"toolbar\":\"Källa\"},\"specialchar\":{\"options\":\"Alternativ för utökade tecken\",\"title\":\"Välj utökat tecken\",\"toolbar\":\"Klistra in utökat tecken\"},\"scayt\":{\"about\":\"Om SCAYT\",\"aboutTab\":\"Om\",\"addWord\":\"Lägg till ord\",\"allCaps\":\"Ignorera alla ord med enbart versaler\",\"dic_create\":\"Skapa\",\"dic_delete\":\"Ta bort\",\"dic_field_name\":\"Ordlistans namn\",\"dic_info\":\"Inledningsvis lagras ordlistan i en cookie. När ordlista växer till en punkt där det inte kan lagras i en cookie, lagras den på vår server. För att lagra din personliga ordlista på vår server du ska ange ett namn för din ordbok. Om du redan har en lagrad ordbok, skriv namnet och klicka på knappen Återställ.\",\"dic_rename\":\"Byt namn\",\"dic_restore\":\"Återställ\",\"dictionariesTab\":\"Ordlistor\",\"disable\":\"Inaktivera SCAYT\",\"emptyDic\":\"Ordlistans namn får ej vara tomt.\",\"enable\":\"Aktivera SCAYT\",\"ignore\":\"Ignorera\",\"ignoreAll\":\"Ignorera alla\",\"ignoreDomainNames\":\"Ignorera domännamn\",\"langs\":\"Språk\",\"languagesTab\":\"Språk\",\"mixedCase\":\"Ignorera ord med blandat shiftläge\",\"mixedWithDigits\":\"Ignorera ord med nummer\",\"moreSuggestions\":\"Fler förslag\",\"opera_title\":\"Stöds ej av Opera\",\"options\":\"Inställningar\",\"optionsTab\":\"Inställningar\",\"title\":\"Stavningskontroll medan du skriver\",\"toggle\":\"Växla SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Anpassad stil\",\"panelTitle\":\"Formatmallar\",\"panelTitle1\":\"Blockstil\",\"panelTitle2\":\"Inbäddad stil\",\"panelTitle3\":\"Objektets stil\"},\"table\":{\"border\":\"Kantstorlek\",\"caption\":\"Rubrik\",\"cell\":{\"menu\":\"Cell\",\"insertBefore\":\"Lägg till cell före\",\"insertAfter\":\"Lägg till cell efter\",\"deleteCell\":\"Radera celler\",\"merge\":\"Sammanfoga celler\",\"mergeRight\":\"Sammanfoga höger\",\"mergeDown\":\"Sammanfoga ner\",\"splitHorizontal\":\"Dela cell horisontellt\",\"splitVertical\":\"Dela cell vertikalt\",\"title\":\"Egenskaper för cell\",\"cellType\":\"Celltyp\",\"rowSpan\":\"Rad spann\",\"colSpan\":\"Kolumnen spann\",\"wordWrap\":\"Radbrytning\",\"hAlign\":\"Horisontell justering\",\"vAlign\":\"Vertikal justering\",\"alignBaseline\":\"Baslinje\",\"bgColor\":\"Bakgrundsfärg\",\"borderColor\":\"Ramfärg\",\"data\":\"Data\",\"header\":\"Rubrik\",\"yes\":\"Ja\",\"no\":\"Nej\",\"invalidWidth\":\"Cellens bredd måste vara ett nummer.\",\"invalidHeight\":\"Cellens höjd måste vara ett nummer.\",\"invalidRowSpan\":\"Radutvidgning måste vara ett heltal.\",\"invalidColSpan\":\"Kolumn måste vara ett heltal.\",\"chooseColor\":\"Välj\"},\"cellPad\":\"Cellutfyllnad\",\"cellSpace\":\"Cellavstånd\",\"column\":{\"menu\":\"Kolumn\",\"insertBefore\":\"Lägg till kolumn före\",\"insertAfter\":\"Lägg till kolumn efter\",\"deleteColumn\":\"Radera kolumn\"},\"columns\":\"Kolumner\",\"deleteTable\":\"Radera tabell\",\"headers\":\"Rubriker\",\"headersBoth\":\"Båda\",\"headersColumn\":\"Första kolumnen\",\"headersNone\":\"Ingen\",\"headersRow\":\"Första raden\",\"invalidBorder\":\"Ram måste vara ett nummer.\",\"invalidCellPadding\":\"Luft i cell måste vara ett nummer.\",\"invalidCellSpacing\":\"Luft i cell måste vara ett nummer.\",\"invalidCols\":\"Antal kolumner måste vara ett nummer större än 0.\",\"invalidHeight\":\"Tabellens höjd måste vara ett nummer.\",\"invalidRows\":\"Antal rader måste vara större än 0.\",\"invalidWidth\":\"Tabell måste vara ett nummer.\",\"menu\":\"Tabellegenskaper\",\"row\":{\"menu\":\"Rad\",\"insertBefore\":\"Lägg till rad före\",\"insertAfter\":\"Lägg till rad efter\",\"deleteRow\":\"Radera rad\"},\"rows\":\"Rader\",\"summary\":\"Sammanfattning\",\"title\":\"Tabellegenskaper\",\"toolbar\":\"Tabell\",\"widthPc\":\"procent\",\"widthPx\":\"pixlar\",\"widthUnit\":\"enhet bredd\"},\"undo\":{\"redo\":\"Gör om\",\"undo\":\"Ångra\"},\"wsc\":{\"btnIgnore\":\"Ignorera\",\"btnIgnoreAll\":\"Ignorera alla\",\"btnReplace\":\"Ersätt\",\"btnReplaceAll\":\"Ersätt alla\",\"btnUndo\":\"Ångra\",\"changeTo\":\"Ändra till\",\"errorLoading\":\"Tjänsten är ej tillgänglig: %s.\",\"ieSpellDownload\":\"Stavningskontrollen är ej installerad. Vill du göra det nu?\",\"manyChanges\":\"Stavningskontroll slutförd: %1 ord rättades.\",\"noChanges\":\"Stavningskontroll slutförd: Inga ord rättades.\",\"noMispell\":\"Stavningskontroll slutförd: Inga stavfel påträffades.\",\"noSuggestions\":\"- Förslag saknas -\",\"notAvailable\":\"Tyvärr är tjänsten ej tillgänglig nu\",\"notInDic\":\"Saknas i ordlistan\",\"oneChange\":\"Stavningskontroll slutförd: Ett ord rättades.\",\"progress\":\"Stavningskontroll pågår...\",\"title\":\"Kontrollera stavning\",\"toolbar\":\"Stavningskontroll\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/th.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['th']={\"editor\":\"Rich Text Editor\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"กด ALT 0 หากต้องการความช่วยเหลือ\",\"browseServer\":\"เปิดหน้าต่างจัดการไฟล์อัพโหลด\",\"url\":\"ที่อยู่อ้างอิง URL\",\"protocol\":\"โปรโตคอล\",\"upload\":\"อัพโหลดไฟล์\",\"uploadSubmit\":\"อัพโหลดไฟล์ไปเก็บไว้ที่เครื่องแม่ข่าย (เซิร์ฟเวอร์)\",\"image\":\"รูปภาพ\",\"flash\":\"ไฟล์ Flash\",\"form\":\"แบบฟอร์ม\",\"checkbox\":\"เช็คบ๊อก\",\"radio\":\"เรดิโอบัตตอน\",\"textField\":\"เท็กซ์ฟิลด์\",\"textarea\":\"เท็กซ์แอเรีย\",\"hiddenField\":\"ฮิดเดนฟิลด์\",\"button\":\"ปุ่ม\",\"select\":\"แถบตัวเลือก\",\"imageButton\":\"ปุ่มแบบรูปภาพ\",\"notSet\":\"<ไม่ระบุ>\",\"id\":\"ไอดี\",\"name\":\"ชื่อ\",\"langDir\":\"การเขียน-อ่านภาษา\",\"langDirLtr\":\"จากซ้ายไปขวา (LTR)\",\"langDirRtl\":\"จากขวามาซ้าย (RTL)\",\"langCode\":\"รหัสภาษา\",\"longDescr\":\"คำอธิบายประกอบ URL\",\"cssClass\":\"คลาสของไฟล์กำหนดลักษณะการแสดงผล\",\"advisoryTitle\":\"คำเกริ่นนำ\",\"cssStyle\":\"ลักษณะการแสดงผล\",\"ok\":\"ตกลง\",\"cancel\":\"ยกเลิก\",\"close\":\"ปิด\",\"preview\":\"ดูหน้าเอกสารตัวอย่าง\",\"resize\":\"ปรับขนาด\",\"generalTab\":\"ทั่วไป\",\"advancedTab\":\"ขั้นสูง\",\"validateNumberFailed\":\"ค่านี้ไม่ใช่ตัวเลข\",\"confirmNewPage\":\"การเปลี่ยนแปลงใดๆ ในเนื้อหานี้ ที่ไม่ได้ถูกบันทึกไว้ จะสูญหายทั้งหมด คุณแน่ใจว่าจะเรียกหน้าใหม่?\",\"confirmCancel\":\"ตัวเลือกบางตัวมีการเปลี่ยนแปลง คุณแน่ใจว่าจะปิดกล่องโต้ตอบนี้?\",\"options\":\"ตัวเลือก\",\"target\":\"การเปิดหน้าลิงค์\",\"targetNew\":\"หน้าต่างใหม่ (_blank)\",\"targetTop\":\"Topmost Window (_top)\",\"targetSelf\":\"หน้าต่างเดียวกัน (_self)\",\"targetParent\":\"Parent Window (_parent)\",\"langDirLTR\":\"จากซ้ายไปขวา (LTR)\",\"langDirRTL\":\"จากขวามาซ้าย (RTL)\",\"styles\":\"ลักษณะการแสดงผล\",\"cssClasses\":\"คลาสของไฟล์กำหนดลักษณะการแสดงผล\",\"width\":\"ความกว้าง\",\"height\":\"ความสูง\",\"align\":\"การจัดวาง\",\"alignLeft\":\"ชิดซ้าย\",\"alignRight\":\"ชิดขวา\",\"alignCenter\":\"กึ่งกลาง\",\"alignTop\":\"บนสุด\",\"alignMiddle\":\"กึ่งกลางแนวตั้ง\",\"alignBottom\":\"ชิดด้านล่าง\",\"invalidValue\":\"ค่าไม่ถูกต้อง\",\"invalidHeight\":\"ความสูงต้องเป็นตัวเลข\",\"invalidWidth\":\"ความกว้างต้องเป็นตัวเลข\",\"invalidCssLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"invalidHtmlLength\":\"Value specified for the \\\"%1\\\" field must be a positive number with or without a valid HTML measurement unit (px or %).\",\"invalidInlineStyle\":\"Value specified for the inline style must consist of one or more tuples with the format of \\\"name : value\\\", separated by semi-colons.\",\"cssLengthTooltip\":\"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, unavailable</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"About CKEditor\",\"help\":\"Check $1 for help.\",\"moreInfo\":\"For licensing information please visit our web site:\",\"title\":\"About CKEditor\",\"userGuide\":\"CKEditor User's Guide\"},\"basicstyles\":{\"bold\":\"ตัวหนา\",\"italic\":\"ตัวเอียง\",\"strike\":\"ตัวขีดเส้นทับ\",\"subscript\":\"ตัวห้อย\",\"superscript\":\"ตัวยก\",\"underline\":\"ตัวขีดเส้นใต้\"},\"blockquote\":{\"toolbar\":\"Block Quote\"},\"clipboard\":{\"copy\":\"สำเนา\",\"copyError\":\"ไม่สามารถสำเนาข้อความที่เลือกไว้ได้เนื่องจากการกำหนดค่าระดับความปลอดภัย. กรุณาใช้ปุ่มลัดเพื่อวางข้อความแทน (กดปุ่ม Ctrl/Cmd และตัว C พร้อมกัน).\",\"cut\":\"ตัด\",\"cutError\":\"ไม่สามารถตัดข้อความที่เลือกไว้ได้เนื่องจากการกำหนดค่าระดับความปลอดภัย. กรุณาใช้ปุ่มลัดเพื่อวางข้อความแทน (กดปุ่ม Ctrl/Cmd และตัว X พร้อมกัน).\",\"paste\":\"วาง\",\"pasteArea\":\"Paste Area\",\"pasteMsg\":\"กรุณาใช้คีย์บอร์ดเท่านั้น โดยกดปุ๋ม (<strong>Ctrl/Cmd และ V</strong>)พร้อมๆกัน และกด <strong>OK</strong>.\",\"securityMsg\":\"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.\",\"title\":\"วาง\"},\"contextmenu\":{\"options\":\"Context Menu Options\"},\"toolbar\":{\"toolbarCollapse\":\"ซ่อนแถบเครื่องมือ\",\"toolbarExpand\":\"เปิดแถบเครื่องมือ\",\"toolbarGroups\":{\"document\":\"Document\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Editing\",\"forms\":\"Forms\",\"basicstyles\":\"Basic Styles\",\"paragraph\":\"Paragraph\",\"links\":\"Links\",\"insert\":\"Insert\",\"styles\":\"Styles\",\"colors\":\"Colors\",\"tools\":\"Tools\"},\"toolbars\":\"แถบเครื่องมือช่วยพิมพ์ข้อความ\"},\"elementspath\":{\"eleLabel\":\"Elements path\",\"eleTitle\":\"%1 element\"},\"format\":{\"label\":\"รูปแบบ\",\"panelTitle\":\"รูปแบบ\",\"tag_address\":\"Address\",\"tag_div\":\"Paragraph (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Formatted\"},\"horizontalrule\":{\"toolbar\":\"แทรกเส้นคั่นบรรทัด\"},\"image\":{\"alertUrl\":\"กรุณาระบุที่อยู่อ้างอิงออนไลน์ของไฟล์รูปภาพ (URL)\",\"alt\":\"คำประกอบรูปภาพ\",\"border\":\"ขนาดขอบรูป\",\"btnUpload\":\"อัพโหลดไฟล์ไปเก็บไว้ที่เครื่องแม่ข่าย (เซิร์ฟเวอร์)\",\"button2Img\":\"Do you want to transform the selected image button on a simple image?\",\"hSpace\":\"ระยะแนวนอน\",\"img2Button\":\"Do you want to transform the selected image on a image button?\",\"infoTab\":\"ข้อมูลของรูปภาพ\",\"linkTab\":\"ลิ้งค์\",\"lockRatio\":\"กำหนดอัตราส่วน กว้าง-สูง แบบคงที่\",\"menu\":\"คุณสมบัติของ รูปภาพ\",\"resetSize\":\"กำหนดรูปเท่าขนาดจริง\",\"title\":\"คุณสมบัติของ รูปภาพ\",\"titleButton\":\"คุณสมบัติของ ปุ่มแบบรูปภาพ\",\"upload\":\"อัพโหลดไฟล์\",\"urlMissing\":\"Image source URL is missing.\",\"vSpace\":\"ระยะแนวตั้ง\",\"validateBorder\":\"Border must be a whole number.\",\"validateHSpace\":\"HSpace must be a whole number.\",\"validateVSpace\":\"VSpace must be a whole number.\"},\"indent\":{\"indent\":\"เพิ่มระยะย่อหน้า\",\"outdent\":\"ลดระยะย่อหน้า\"},\"fakeobjects\":{\"anchor\":\"แทรก/แก้ไข Anchor\",\"flash\":\"ภาพอนิเมชั่นแฟลช\",\"hiddenfield\":\"ฮิดเดนฟิลด์\",\"iframe\":\"IFrame\",\"unknown\":\"วัตถุไม่ทราบชนิด\"},\"link\":{\"acccessKey\":\"แอคเซส คีย์\",\"advanced\":\"ขั้นสูง\",\"advisoryContentType\":\"ชนิดของคำเกริ่นนำ\",\"advisoryTitle\":\"คำเกริ่นนำ\",\"anchor\":{\"toolbar\":\"แทรก/แก้ไข Anchor\",\"menu\":\"รายละเอียด Anchor\",\"title\":\"รายละเอียด Anchor\",\"name\":\"ชื่อ Anchor\",\"errorName\":\"กรุณาระบุชื่อของ Anchor\",\"remove\":\"Remove Anchor\"},\"anchorId\":\"ไอดี\",\"anchorName\":\"ชื่อ\",\"charset\":\"ลิงค์เชื่อมโยงไปยังชุดตัวอักษร\",\"cssClasses\":\"คลาสของไฟล์กำหนดลักษณะการแสดงผล\",\"emailAddress\":\"อีเมล์ (E-Mail)\",\"emailBody\":\"ข้อความ\",\"emailSubject\":\"หัวเรื่อง\",\"id\":\"ไอดี\",\"info\":\"รายละเอียด\",\"langCode\":\"การเขียน-อ่านภาษา\",\"langDir\":\"การเขียน-อ่านภาษา\",\"langDirLTR\":\"จากซ้ายไปขวา (LTR)\",\"langDirRTL\":\"จากขวามาซ้าย (RTL)\",\"menu\":\"แก้ไข ลิงค์\",\"name\":\"ชื่อ\",\"noAnchors\":\"(ยังไม่มีจุดเชื่อมโยงภายในหน้าเอกสารนี้)\",\"noEmail\":\"กรุณาระบุอีเมล์ (E-mail)\",\"noUrl\":\"กรุณาระบุที่อยู่อ้างอิงออนไลน์ (URL)\",\"other\":\"<อื่น ๆ>\",\"popupDependent\":\"แสดงเต็มหน้าจอ (Netscape)\",\"popupFeatures\":\"คุณสมบัติของหน้าจอเล็ก (Pop-up)\",\"popupFullScreen\":\"แสดงเต็มหน้าจอ (IE5.5++ เท่านั้น)\",\"popupLeft\":\"พิกัดซ้าย (Left Position)\",\"popupLocationBar\":\"แสดงที่อยู่ของไฟล์\",\"popupMenuBar\":\"แสดงแถบเมนู\",\"popupResizable\":\"สามารถปรับขนาดได้\",\"popupScrollBars\":\"แสดงแถบเลื่อน\",\"popupStatusBar\":\"แสดงแถบสถานะ\",\"popupToolbar\":\"แสดงแถบเครื่องมือ\",\"popupTop\":\"พิกัดบน (Top Position)\",\"rel\":\"ความสัมพันธ์\",\"selectAnchor\":\"ระบุข้อมูลของจุดเชื่อมโยง (Anchor)\",\"styles\":\"ลักษณะการแสดงผล\",\"tabIndex\":\"ลำดับของ แท็บ\",\"target\":\"การเปิดหน้าลิงค์\",\"targetFrame\":\"<เปิดในเฟรม>\",\"targetFrameName\":\"ชื่อทาร์เก็ตเฟรม\",\"targetPopup\":\"<เปิดหน้าจอเล็ก (Pop-up)>\",\"targetPopupName\":\"ระบุชื่อหน้าจอเล็ก (Pop-up)\",\"title\":\"ลิงค์เชื่อมโยงเว็บ อีเมล์ รูปภาพ หรือไฟล์อื่นๆ\",\"toAnchor\":\"จุดเชื่อมโยง (Anchor)\",\"toEmail\":\"ส่งอีเมล์ (E-Mail)\",\"toUrl\":\"ที่อยู่อ้างอิง URL\",\"toolbar\":\"แทรก/แก้ไข ลิงค์\",\"type\":\"ประเภทของลิงค์\",\"unlink\":\"ลบ ลิงค์\",\"upload\":\"อัพโหลดไฟล์\"},\"list\":{\"bulletedlist\":\"ลำดับรายการแบบสัญลักษณ์\",\"numberedlist\":\"ลำดับรายการแบบตัวเลข\"},\"magicline\":{\"title\":\"Insert paragraph here\"},\"maximize\":{\"maximize\":\"ขยายใหญ่\",\"minimize\":\"ย่อขนาด\"},\"pastetext\":{\"button\":\"วางแบบตัวอักษรธรรมดา\",\"title\":\"วางแบบตัวอักษรธรรมดา\"},\"pastefromword\":{\"confirmCleanup\":\"ข้อความที่คุณต้องการวางลงไปเป็นข้อความที่คัดลอกมาจากโปรแกรมไมโครซอฟท์เวิร์ด คุณต้องการล้างค่าข้อความดังกล่าวก่อนวางลงไปหรือไม่?\",\"error\":\"ไม่สามารถล้างข้อมูลที่ต้องการวางได้เนื่องจากเกิดข้อผิดพลาดภายในระบบ\",\"title\":\"วางสำเนาจากตัวอักษรเวิร์ด\",\"toolbar\":\"วางสำเนาจากตัวอักษรเวิร์ด\"},\"removeformat\":{\"toolbar\":\"ล้างรูปแบบ\"},\"sourcearea\":{\"toolbar\":\"ดูรหัส HTML\"},\"specialchar\":{\"options\":\"Special Character Options\",\"title\":\"แทรกตัวอักษรพิเศษ\",\"toolbar\":\"แทรกตัวอักษรพิเศษ\"},\"scayt\":{\"about\":\"About SCAYT\",\"aboutTab\":\"About\",\"addWord\":\"Add Word\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"Dictionaries\",\"disable\":\"Disable SCAYT\",\"emptyDic\":\"Dictionary name should not be empty.\",\"enable\":\"Enable SCAYT\",\"ignore\":\"Ignore\",\"ignoreAll\":\"Ignore All\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"Languages\",\"languagesTab\":\"Languages\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"More suggestions\",\"opera_title\":\"Not supported by Opera\",\"options\":\"Options\",\"optionsTab\":\"Options\",\"title\":\"Spell Check As You Type\",\"toggle\":\"Toggle SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"ลักษณะ\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"Block Styles\",\"panelTitle2\":\"Inline Styles\",\"panelTitle3\":\"Object Styles\"},\"table\":{\"border\":\"ขนาดเส้นขอบ\",\"caption\":\"หัวเรื่องของตาราง\",\"cell\":{\"menu\":\"ช่องตาราง\",\"insertBefore\":\"Insert Cell Before\",\"insertAfter\":\"Insert Cell After\",\"deleteCell\":\"ลบช่อง\",\"merge\":\"ผสานช่อง\",\"mergeRight\":\"Merge Right\",\"mergeDown\":\"Merge Down\",\"splitHorizontal\":\"Split Cell Horizontally\",\"splitVertical\":\"Split Cell Vertically\",\"title\":\"Cell Properties\",\"cellType\":\"Cell Type\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"Word Wrap\",\"hAlign\":\"Horizontal Alignment\",\"vAlign\":\"Vertical Alignment\",\"alignBaseline\":\"Baseline\",\"bgColor\":\"Background Color\",\"borderColor\":\"Border Color\",\"data\":\"Data\",\"header\":\"Header\",\"yes\":\"Yes\",\"no\":\"No\",\"invalidWidth\":\"Cell width must be a number.\",\"invalidHeight\":\"Cell height must be a number.\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"Choose\"},\"cellPad\":\"ระยะแนวตั้ง\",\"cellSpace\":\"ระยะแนวนอนน\",\"column\":{\"menu\":\"คอลัมน์\",\"insertBefore\":\"Insert Column Before\",\"insertAfter\":\"Insert Column After\",\"deleteColumn\":\"ลบสดมน์\"},\"columns\":\"สดมน์\",\"deleteTable\":\"ลบตาราง\",\"headers\":\"ส่วนหัว\",\"headersBoth\":\"ทั้งสองอย่าง\",\"headersColumn\":\"คอลัมน์แรก\",\"headersNone\":\"None\",\"headersRow\":\"แถวแรก\",\"invalidBorder\":\"ขนาดเส้นกรอบต้องเป็นจำนวนตัวเลข\",\"invalidCellPadding\":\"ช่องว่างภายในเซลล์ต้องเลขจำนวนบวก\",\"invalidCellSpacing\":\"ช่องว่างภายในเซลล์ต้องเป็นเลขจำนวนบวก\",\"invalidCols\":\"จำนวนคอลัมน์ต้องเป็นจำนวนมากกว่า 0\",\"invalidHeight\":\"ส่วนสูงของตารางต้องเป็นตัวเลข\",\"invalidRows\":\"จำนวนของแถวต้องเป็นจำนวนมากกว่า 0\",\"invalidWidth\":\"ความกว้างตารางต้องเป็นตัวเลข\",\"menu\":\"คุณสมบัติของ ตาราง\",\"row\":{\"menu\":\"แถว\",\"insertBefore\":\"Insert Row Before\",\"insertAfter\":\"Insert Row After\",\"deleteRow\":\"ลบแถว\"},\"rows\":\"แถว\",\"summary\":\"สรุปความ\",\"title\":\"คุณสมบัติของ ตาราง\",\"toolbar\":\"ตาราง\",\"widthPc\":\"เปอร์เซ็น\",\"widthPx\":\"จุดสี\",\"widthUnit\":\"หน่วยความกว้าง\"},\"undo\":{\"redo\":\"ทำซ้ำคำสั่ง\",\"undo\":\"ยกเลิกคำสั่ง\"},\"wsc\":{\"btnIgnore\":\"ยกเว้น\",\"btnIgnoreAll\":\"ยกเว้นทั้งหมด\",\"btnReplace\":\"แทนที่\",\"btnReplaceAll\":\"แทนที่ทั้งหมด\",\"btnUndo\":\"ยกเลิก\",\"changeTo\":\"แก้ไขเป็น\",\"errorLoading\":\"Error loading application service host: %s.\",\"ieSpellDownload\":\"ไม่ได้ติดตั้งระบบตรวจสอบคำสะกด. ต้องการติดตั้งไหมครับ?\",\"manyChanges\":\"ตรวจสอบคำสะกดเสร็จสิ้น:: แก้ไข %1 คำ\",\"noChanges\":\"ตรวจสอบคำสะกดเสร็จสิ้น: ไม่มีการแก้คำใดๆ\",\"noMispell\":\"ตรวจสอบคำสะกดเสร็จสิ้น: ไม่พบคำสะกดผิด\",\"noSuggestions\":\"- ไม่มีคำแนะนำใดๆ -\",\"notAvailable\":\"Sorry, but service is unavailable now.\",\"notInDic\":\"ไม่พบในดิกชันนารี\",\"oneChange\":\"ตรวจสอบคำสะกดเสร็จสิ้น: แก้ไข1คำ\",\"progress\":\"กำลังตรวจสอบคำสะกด...\",\"title\":\"Spell Check\",\"toolbar\":\"ตรวจการสะกดคำ\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/tr.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['tr']={\"editor\":\"Zengin Metin Editörü\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Yardım için ALT 0 tuşlarına basın\",\"browseServer\":\"Sunucuya Gözat\",\"url\":\"URL\",\"protocol\":\"Protokol\",\"upload\":\"Karşıya Yükle\",\"uploadSubmit\":\"Sunucuya Gönder\",\"image\":\"Resim\",\"flash\":\"Flash\",\"form\":\"Form\",\"checkbox\":\"Onay Kutusu\",\"radio\":\"Seçenek Düğmesi\",\"textField\":\"Metin Kutusu\",\"textarea\":\"Metin Alanı\",\"hiddenField\":\"Gizli Alan\",\"button\":\"Düğme\",\"select\":\"Seçme Alanı\",\"imageButton\":\"Resim Düğmesi\",\"notSet\":\"<tanımlanmamış>\",\"id\":\"Kimlik\",\"name\":\"İsim\",\"langDir\":\"Dil Yönü\",\"langDirLtr\":\"Soldan Sağa (LTR)\",\"langDirRtl\":\"Sağdan Sola (RTL)\",\"langCode\":\"Dil Kodlaması\",\"longDescr\":\"Uzun Tanımlı URL\",\"cssClass\":\"Biçem Sayfası Sınıfları\",\"advisoryTitle\":\"Öneri Başlığı\",\"cssStyle\":\"Biçem\",\"ok\":\"Tamam\",\"cancel\":\"İptal\",\"close\":\"Kapat\",\"preview\":\"Önizleme\",\"resize\":\"Yeniden Boyutlandır\",\"generalTab\":\"Genel\",\"advancedTab\":\"Gelişmiş\",\"validateNumberFailed\":\"Bu değer bir sayı değildir.\",\"confirmNewPage\":\"Bu içerikle ilgili kaydedilmemiş tüm bilgiler kaybolacaktır. Yeni bir sayfa yüklemek istediğinizden emin misiniz?\",\"confirmCancel\":\"Bazı seçenekleri değiştirdiniz. İletişim penceresini kapatmak istediğinizden emin misiniz?\",\"options\":\"Seçenekler\",\"target\":\"Hedef\",\"targetNew\":\"Yeni Pencere (_blank)\",\"targetTop\":\"En Üstteki Pencere (_top)\",\"targetSelf\":\"Aynı Pencere (_self)\",\"targetParent\":\"Üst Pencere (_parent)\",\"langDirLTR\":\"Soldan Sağa (LTR)\",\"langDirRTL\":\"Sağdan Sola (RTL)\",\"styles\":\"Biçem\",\"cssClasses\":\"Biçem Sayfası Sınıfları\",\"width\":\"Genişlik\",\"height\":\"Yükseklik\",\"align\":\"Hizalama\",\"alignLeft\":\"Sol\",\"alignRight\":\"Sağ\",\"alignCenter\":\"Ortala\",\"alignTop\":\"Üst\",\"alignMiddle\":\"Orta\",\"alignBottom\":\"Alt\",\"invalidValue\":\"Geçersiz değer.\",\"invalidHeight\":\"Yükseklik değeri bir sayı olmalıdır.\",\"invalidWidth\":\"Genişlik değeri bir sayı olmalıdır.\",\"invalidCssLength\":\"\\\"%1\\\" alanı için verilen değer, geçerli bir CSS ölçü birimi (px, %, in, cm, mm, em, ex, pt, veya pc) içeren veya içermeyen pozitif bir sayı olmalıdır.\",\"invalidHtmlLength\":\"Belirttiğiniz sayı \\\"%1\\\" alanı için pozitif bir sayı HTML birim değeri olmalıdır (px veya %).\",\"invalidInlineStyle\":\"Satıriçi biçem için verilen değer, \\\"isim : değer\\\" biçiminde birbirinden noktalı virgüllerle ayrılan bir veya daha fazla değişkenler grubundan oluşmalıdır.\",\"cssLengthTooltip\":\"Piksel türünde bir sayı veya geçerli bir CSS ölçü birimi (px, %, in, cm, mm, em, ex, pt veya pc) içeren bir sayı girin.\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, kullanılamaz</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Tüm hakları saklıdır.\",\"dlgTitle\":\"CKEditor Hakkında\",\"help\":\"Yardım için $1 kontrol edin.\",\"moreInfo\":\"Lisanslama hakkında daha fazla bilgi almak için lütfen sitemizi ziyaret edin:\",\"title\":\"CKEditor Hakkında\",\"userGuide\":\"CKEditor Kullanıcı Kılavuzu\"},\"basicstyles\":{\"bold\":\"Kalın\",\"italic\":\"İtalik\",\"strike\":\"Üstü Çizgili\",\"subscript\":\"Alt Simge\",\"superscript\":\"Üst Simge\",\"underline\":\"Altı Çizgili\"},\"blockquote\":{\"toolbar\":\"Blok Oluştur\"},\"clipboard\":{\"copy\":\"Kopyala\",\"copyError\":\"Gezgin yazılımınızın güvenlik ayarları düzenleyicinin otomatik kopyalama işlemine izin vermiyor. İşlem için (Ctrl/Cmd+C) tuşlarını kullanın.\",\"cut\":\"Kes\",\"cutError\":\"Gezgin yazılımınızın güvenlik ayarları düzenleyicinin otomatik kesme işlemine izin vermiyor. İşlem için (Ctrl/Cmd+X) tuşlarını kullanın.\",\"paste\":\"Yapıştır\",\"pasteArea\":\"Yapıştırma Alanı\",\"pasteMsg\":\"Lütfen aşağıdaki kutunun içine yapıştırın. (<STRONG>Ctrl/Cmd+V</STRONG>) ve <STRONG>Tamam</STRONG> butonunu tıklayın.\",\"securityMsg\":\"Gezgin yazılımınızın güvenlik ayarları düzenleyicinin direkt olarak panoya erişimine izin vermiyor. Bu pencere içine tekrar yapıştırmalısınız..\",\"title\":\"Yapıştır\"},\"contextmenu\":{\"options\":\"İçerik Menüsü Seçenekleri\"},\"toolbar\":{\"toolbarCollapse\":\"Araç çubuklarını topla\",\"toolbarExpand\":\"Araç çubuklarını aç\",\"toolbarGroups\":{\"document\":\"Belge\",\"clipboard\":\"Pano/Geri al\",\"editing\":\"Düzenleme\",\"forms\":\"Formlar\",\"basicstyles\":\"Temel Stiller\",\"paragraph\":\"Paragraf\",\"links\":\"Bağlantılar\",\"insert\":\"Ekle\",\"styles\":\"Stiller\",\"colors\":\"Renkler\",\"tools\":\"Araçlar\"},\"toolbars\":\"Araç çubukları Editörü\"},\"elementspath\":{\"eleLabel\":\"Elementlerin yolu\",\"eleTitle\":\"%1 elementi\"},\"format\":{\"label\":\"Biçim\",\"panelTitle\":\"Biçim\",\"tag_address\":\"Adres\",\"tag_div\":\"Paragraf (DIV)\",\"tag_h1\":\"Başlık 1\",\"tag_h2\":\"Başlık 2\",\"tag_h3\":\"Başlık 3\",\"tag_h4\":\"Başlık 4\",\"tag_h5\":\"Başlık 5\",\"tag_h6\":\"Başlık 6\",\"tag_p\":\"Normal\",\"tag_pre\":\"Biçimli\"},\"horizontalrule\":{\"toolbar\":\"Yatay Satır Ekle\"},\"image\":{\"alertUrl\":\"Lütfen resmin URL'sini yazınız\",\"alt\":\"Alternatif Yazı\",\"border\":\"Kenar\",\"btnUpload\":\"Sunucuya Yolla\",\"button2Img\":\"Seçili resim butonunu basit resime çevirmek istermisiniz?\",\"hSpace\":\"Yatay Boşluk\",\"img2Button\":\"Seçili olan resimi, resimli butona çevirmek istermisiniz?\",\"infoTab\":\"Resim Bilgisi\",\"linkTab\":\"Köprü\",\"lockRatio\":\"Oranı Kilitle\",\"menu\":\"Resim Özellikleri\",\"resetSize\":\"Boyutu Başa Döndür\",\"title\":\"Resim Özellikleri\",\"titleButton\":\"Resimli Düğme Özellikleri\",\"upload\":\"Karşıya Yükle\",\"urlMissing\":\"Resmin URL kaynağı eksiktir.\",\"vSpace\":\"Dikey Boşluk\",\"validateBorder\":\"Çerçeve tam sayı olmalıdır.\",\"validateHSpace\":\"HSpace tam sayı olmalıdır.\",\"validateVSpace\":\"VSpace tam sayı olmalıdır.\"},\"indent\":{\"indent\":\"Sekme Arttır\",\"outdent\":\"Sekme Azalt\"},\"fakeobjects\":{\"anchor\":\"Bağlantı\",\"flash\":\"Flash Animasyonu\",\"hiddenfield\":\"Gizli Alan\",\"iframe\":\"IFrame\",\"unknown\":\"Bilinmeyen Nesne\"},\"link\":{\"acccessKey\":\"Erişim Tuşu\",\"advanced\":\"Gelişmiş\",\"advisoryContentType\":\"Danışma İçerik Türü\",\"advisoryTitle\":\"Danışma Başlığı\",\"anchor\":{\"toolbar\":\"Bağlantı Ekle/Düzenle\",\"menu\":\"Bağlantı Özellikleri\",\"title\":\"Bağlantı Özellikleri\",\"name\":\"Bağlantı Adı\",\"errorName\":\"Lütfen bağlantı için ad giriniz\",\"remove\":\"Bağlantıyı Kaldır\"},\"anchorId\":\"Eleman Kimlik Numarası ile\",\"anchorName\":\"Bağlantı Adı ile\",\"charset\":\"Bağlı Kaynak Karakter Gurubu\",\"cssClasses\":\"Biçem Sayfası Sınıfları\",\"emailAddress\":\"E-Posta Adresi\",\"emailBody\":\"İleti Gövdesi\",\"emailSubject\":\"İleti Konusu\",\"id\":\"Id\",\"info\":\"Link Bilgisi\",\"langCode\":\"Dil Yönü\",\"langDir\":\"Dil Yönü\",\"langDirLTR\":\"Soldan Sağa (LTR)\",\"langDirRTL\":\"Sağdan Sola (RTL)\",\"menu\":\"Link Düzenle\",\"name\":\"Ad\",\"noAnchors\":\"(Bu belgede hiç çapa yok)\",\"noEmail\":\"Lütfen E-posta adresini yazın\",\"noUrl\":\"Lütfen Link URL'sini yazın\",\"other\":\"<diğer>\",\"popupDependent\":\"Bağımlı (Netscape)\",\"popupFeatures\":\"Yeni Açılan Pencere Özellikleri\",\"popupFullScreen\":\"Tam Ekran (IE)\",\"popupLeft\":\"Sola Göre Konum\",\"popupLocationBar\":\"Yer Çubuğu\",\"popupMenuBar\":\"Menü Çubuğu\",\"popupResizable\":\"Resizable\",\"popupScrollBars\":\"Kaydırma Çubukları\",\"popupStatusBar\":\"Durum Çubuğu\",\"popupToolbar\":\"Araç Çubuğu\",\"popupTop\":\"Yukarıya Göre Konum\",\"rel\":\"İlişki\",\"selectAnchor\":\"Bağlantı Seç\",\"styles\":\"Biçem\",\"tabIndex\":\"Sekme İndeksi\",\"target\":\"Hedef\",\"targetFrame\":\"<çerçeve>\",\"targetFrameName\":\"Hedef Çerçeve Adı\",\"targetPopup\":\"<yeni açılan pencere>\",\"targetPopupName\":\"Yeni Açılan Pencere Adı\",\"title\":\"Link\",\"toAnchor\":\"Bu sayfada çapa\",\"toEmail\":\"E-Posta\",\"toUrl\":\"URL\",\"toolbar\":\"Link Ekle/Düzenle\",\"type\":\"Link Türü\",\"unlink\":\"Köprü Kaldır\",\"upload\":\"Karşıya Yükle\"},\"list\":{\"bulletedlist\":\"Simgeli Liste\",\"numberedlist\":\"Numaralı Liste\"},\"magicline\":{\"title\":\"Parağrafı buraya ekle\"},\"maximize\":{\"maximize\":\"Büyült\",\"minimize\":\"Küçült\"},\"pastetext\":{\"button\":\"Düz Metin Olarak Yapıştır\",\"title\":\"Düz Metin Olarak Yapıştır\"},\"pastefromword\":{\"confirmCleanup\":\"Yapıştırmaya çalıştığınız metin Word'den kopyalanmıştır. Yapıştırmadan önce silmek istermisiniz?\",\"error\":\"Yapıştırmadaki veri bilgisi hata düzelene kadar silinmeyecektir\",\"title\":\"Word'den Yapıştır\",\"toolbar\":\"Word'den Yapıştır\"},\"removeformat\":{\"toolbar\":\"Biçimi Kaldır\"},\"sourcearea\":{\"toolbar\":\"Kaynak\"},\"specialchar\":{\"options\":\"Özel Karakter Seçenekleri\",\"title\":\"Özel Karakter Seç\",\"toolbar\":\"Özel Karakter Ekle\"},\"scayt\":{\"about\":\"SCAYT'ı hakkında\",\"aboutTab\":\"Hakkında\",\"addWord\":\"Kelime Ekle\",\"allCaps\":\"Tüm büyük küçük kelimeleri yoksay\",\"dic_create\":\"Oluştur\",\"dic_delete\":\"Sil\",\"dic_field_name\":\"Sözlük adı\",\"dic_info\":\"Başlangıçta Kullanıcı Sözlüğü bir çerezde saklanır. Ancak, Çerezler boyutu sınırlıdır. Kullanıcı Sözlüğü, çerezin içinde saklanamayacağı bir noktada, bizim sunucularımızın içindeki sözlükte saklanabilir. Bizim sunucu üzerinde kişisel Sözlük saklamanız için, Sözlüğe bir ad belirtmelisiniz. Eğer zaten bir saklı Sözlük varsa, lütfen adını yazın ve Geri Yükle düğmesini tıklayın.\",\"dic_rename\":\"Yeniden adlandır\",\"dic_restore\":\"Geri al\",\"dictionariesTab\":\"Sözlükler\",\"disable\":\"SCAYT'ı pasifleştir\",\"emptyDic\":\"Sözlük adı boş olamaz.\",\"enable\":\"SCAYT'ı etkinleştir\",\"ignore\":\"Yoksay\",\"ignoreAll\":\"Tümünü Yoksay\",\"ignoreDomainNames\":\"Domain adlarını yoksay\",\"langs\":\"Diller\",\"languagesTab\":\"Diller\",\"mixedCase\":\"Karışık büyüklük ile Sözcükler yoksay\",\"mixedWithDigits\":\"Sayılarla Kelimeler yoksay\",\"moreSuggestions\":\"Daha fazla öneri\",\"opera_title\":\"Opera tarafından desteklenmemektedir\",\"options\":\"Seçenekler\",\"optionsTab\":\"Seçenekler\",\"title\":\"Girmiş olduğunuz kelime denetimi\",\"toggle\":\"SCAYT'ı değiştir\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Biçem\",\"panelTitle\":\"Stilleri Düzenliyor\",\"panelTitle1\":\"Blok Stilleri\",\"panelTitle2\":\"Inline Stilleri\",\"panelTitle3\":\"Nesne Stilleri\"},\"table\":{\"border\":\"Kenar Kalınlığı\",\"caption\":\"Başlık\",\"cell\":{\"menu\":\"Hücre\",\"insertBefore\":\"Hücre Ekle - Önce\",\"insertAfter\":\"Hücre Ekle - Sonra\",\"deleteCell\":\"Hücre Sil\",\"merge\":\"Hücreleri Birleştir\",\"mergeRight\":\"Birleştir - Sağdaki İle \",\"mergeDown\":\"Birleştir - Aşağıdaki İle \",\"splitHorizontal\":\"Hücreyi Yatay Böl\",\"splitVertical\":\"Hücreyi Dikey Böl\",\"title\":\"Hücre Özellikleri\",\"cellType\":\"Hücre Tipi\",\"rowSpan\":\"Satırlar Mesafesi (Span)\",\"colSpan\":\"Sütünlar Mesafesi (Span)\",\"wordWrap\":\"Kelime Kaydırma\",\"hAlign\":\"Düşey Hizalama\",\"vAlign\":\"Yataş Hizalama\",\"alignBaseline\":\"Tabana\",\"bgColor\":\"Arkaplan Rengi\",\"borderColor\":\"Çerçeve Rengi\",\"data\":\"Veri\",\"header\":\"Başlık\",\"yes\":\"Evet\",\"no\":\"Hayır\",\"invalidWidth\":\"Hücre genişliği sayı olmalıdır.\",\"invalidHeight\":\"Hücre yüksekliği sayı olmalıdır.\",\"invalidRowSpan\":\"Satırların mesafesi tam sayı olmalıdır.\",\"invalidColSpan\":\"Sütünların mesafesi tam sayı olmalıdır.\",\"chooseColor\":\"Seçiniz\"},\"cellPad\":\"Izgara yazı arası\",\"cellSpace\":\"Izgara kalınlığı\",\"column\":{\"menu\":\"Sütun\",\"insertBefore\":\"Kolon Ekle - Önce\",\"insertAfter\":\"Kolon Ekle - Sonra\",\"deleteColumn\":\"Sütun Sil\"},\"columns\":\"Sütunlar\",\"deleteTable\":\"Tabloyu Sil\",\"headers\":\"Başlıklar\",\"headersBoth\":\"Her İkisi\",\"headersColumn\":\"İlk Sütun\",\"headersNone\":\"Yok\",\"headersRow\":\"İlk Satır\",\"invalidBorder\":\"Çerceve büyüklüklüğü sayı olmalıdır.\",\"invalidCellPadding\":\"Hücre aralığı (padding) sayı olmalıdır.\",\"invalidCellSpacing\":\"Hücre boşluğu (spacing) sayı olmalıdır.\",\"invalidCols\":\"Sütün sayısı 0 sayısından büyük olmalıdır.\",\"invalidHeight\":\"Tablo yüksekliği sayı olmalıdır.\",\"invalidRows\":\"Satır sayısı 0 sayısından büyük olmalıdır.\",\"invalidWidth\":\"Tablo genişliği sayı olmalıdır.\",\"menu\":\"Tablo Özellikleri\",\"row\":{\"menu\":\"Satır\",\"insertBefore\":\"Satır Ekle - Önce\",\"insertAfter\":\"Satır Ekle - Sonra\",\"deleteRow\":\"Satır Sil\"},\"rows\":\"Satırlar\",\"summary\":\"Özet\",\"title\":\"Tablo Özellikleri\",\"toolbar\":\"Tablo\",\"widthPc\":\"yüzde\",\"widthPx\":\"piksel\",\"widthUnit\":\"genişlik birimi\"},\"undo\":{\"redo\":\"Tekrarla\",\"undo\":\"Geri Al\"},\"wsc\":{\"btnIgnore\":\"Yoksay\",\"btnIgnoreAll\":\"Tümünü Yoksay\",\"btnReplace\":\"Değiştir\",\"btnReplaceAll\":\"Tümünü Değiştir\",\"btnUndo\":\"Geri Al\",\"changeTo\":\"Şuna değiştir:\",\"errorLoading\":\"Uygulamada yüklerken hata oluştu: %s.\",\"ieSpellDownload\":\"Yazım denetimi yüklenmemiş. Şimdi yüklemek ister misiniz?\",\"manyChanges\":\"Yazım denetimi tamamlandı: %1 kelime değiştirildi\",\"noChanges\":\"Yazım denetimi tamamlandı: Hiçbir kelime değiştirilmedi\",\"noMispell\":\"Yazım denetimi tamamlandı: Yanlış yazıma rastlanmadı\",\"noSuggestions\":\"- Öneri Yok -\",\"notAvailable\":\"Üzügünüz, bu servis şuanda hizmet dışıdır.\",\"notInDic\":\"Sözlükte Yok\",\"oneChange\":\"Yazım denetimi tamamlandı: Bir kelime değiştirildi\",\"progress\":\"Yazım denetimi işlemde...\",\"title\":\"Yazımı Denetle\",\"toolbar\":\"Yazım Denetimi\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/ug.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['ug']={\"editor\":\"تەھرىرلىگۈچ\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"ALT+0 نى بېسىپ ياردەمنى كۆرۈڭ\",\"browseServer\":\"كۆرسىتىش مۇلازىمېتىر\",\"url\":\"ئەسلى ھۆججەت\",\"protocol\":\"كېلىشىم\",\"upload\":\"يۈكلە\",\"uploadSubmit\":\"مۇلازىمېتىرغا يۈكلە\",\"image\":\"سۈرەت\",\"flash\":\"Flash\",\"form\":\"جەدۋەل\",\"checkbox\":\"كۆپ تاللاش رامكىسى\",\"radio\":\"يەككە تاللاش توپچىسى\",\"textField\":\"يەككە قۇر تېكىست\",\"textarea\":\"كۆپ قۇر تېكىست\",\"hiddenField\":\"يوشۇرۇن دائىرە\",\"button\":\"توپچا\",\"select\":\"تىزىم/تىزىملىك\",\"imageButton\":\"سۈرەت دائىرە\",\"notSet\":\"‹تەڭشەلمىگەن›\",\"id\":\"ID\",\"name\":\"ئات\",\"langDir\":\"تىل يۆنىلىشى\",\"langDirLtr\":\"سولدىن ئوڭغا (LTR)\",\"langDirRtl\":\"ئوڭدىن سولغا (RTL)\",\"langCode\":\"تىل كودى\",\"longDescr\":\"تەپسىلىي چۈشەندۈرۈش ئادرېسى\",\"cssClass\":\"ئۇسلۇب خىلىنىڭ ئاتى\",\"advisoryTitle\":\"ماۋزۇ\",\"cssStyle\":\"قۇر ئىچىدىكى ئۇسلۇبى\",\"ok\":\"جەزملە\",\"cancel\":\"ۋاز كەچ\",\"close\":\"تاقا\",\"preview\":\"ئالدىن كۆزەت\",\"resize\":\"چوڭلۇقىنى ئۆزگەرت\",\"generalTab\":\"ئادەتتىكى\",\"advancedTab\":\"ئالىي\",\"validateNumberFailed\":\"سان پىچىمىدا كىرگۈزۈش زۆرۈر\",\"confirmNewPage\":\"نۆۋەتتىكى پۈتۈك مەزمۇنى ساقلانمىدى، يېڭى پۈتۈك قۇرامسىز؟\",\"confirmCancel\":\"قىسمەن ئۆزگەرتىش ساقلانمىدى، بۇ سۆزلەشكۈنى تاقامسىز؟\",\"options\":\"تاللانما\",\"target\":\"نىشان كۆزنەك\",\"targetNew\":\"يېڭى كۆزنەك (_blank)\",\"targetTop\":\"پۈتۈن بەت (_top)\",\"targetSelf\":\"مەزكۇر كۆزنەك (_self)\",\"targetParent\":\"ئاتا كۆزنەك (_parent)\",\"langDirLTR\":\"سولدىن ئوڭغا (LTR)\",\"langDirRTL\":\"ئوڭدىن سولغا (RTL)\",\"styles\":\"ئۇسلۇبلار\",\"cssClasses\":\"ئۇسلۇب خىللىرى\",\"width\":\"كەڭلىك\",\"height\":\"ئېگىزلىك\",\"align\":\"توغرىلىنىشى\",\"alignLeft\":\"سول\",\"alignRight\":\"ئوڭ\",\"alignCenter\":\"ئوتتۇرا\",\"alignTop\":\"ئۈستى\",\"alignMiddle\":\"ئوتتۇرا\",\"alignBottom\":\"ئاستى\",\"invalidValue\":\"ئىناۋەتسىز قىممەت.\",\"invalidHeight\":\"ئېگىزلىك چوقۇم رەقەم پىچىمىدا بولۇشى زۆرۈر\",\"invalidWidth\":\"كەڭلىك چوقۇم رەقەم پىچىمىدا بولۇشى زۆرۈر\",\"invalidCssLength\":\"بۇ سۆز بۆلىكى چوقۇم مۇۋاپىق بولغان CSS ئۇزۇنلۇق قىممىتى بولۇشى زۆرۈر، بىرلىكى (px, %, in, cm, mm, em, ex, pt ياكى pc)\",\"invalidHtmlLength\":\"بۇ سۆز بۆلىكى چوقۇم بىرىكمە HTML ئۇزۇنلۇق قىممىتى بولۇشى كېرەك. ئۆز ئىچىگە ئالىدىغان بىرلىك (px ياكى %)\",\"invalidInlineStyle\":\"ئىچكى باغلانما ئۇسلۇبى چوقۇم چېكىتلىك پەش بىلەن ئايرىلغان بىر ياكى كۆپ «خاسلىق ئاتى:خاسلىق قىممىتى» پىچىمىدا بولۇشى لازىم\",\"cssLengthTooltip\":\"بۇ سۆز بۆلىكى بىرىكمە CSS ئۇزۇنلۇق قىممىتى بولۇشى كېرەك. ئۆز ئىچىگە ئالىدىغان بىرلىك (px, %, in, cm, mm, em, ex, pt ياكى pc)\",\"unavailable\":\"%1<span class=\\\\\\\\\\\"cke_accessibility\\\\\\\\\\\">، ئىشلەتكىلى بولمايدۇ</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. نەشر ھوقۇقىغا ئىگە\",\"dlgTitle\":\"CKEditor ھەققىدە\",\"help\":\"$1 نى زىيارەت قىلىپ ياردەمگە ئېرىشىڭ\",\"moreInfo\":\"تور تۇرايىمىزنى زىيارەت قىلىپ كېلىشىمگە ئائىت تېخىمۇ كۆپ ئۇچۇرغا ئېرىشىڭ\",\"title\":\"CKEditor ھەققىدە\",\"userGuide\":\"CKEditor ئىشلەتكۈچى قوللانمىسى\"},\"basicstyles\":{\"bold\":\"توم\",\"italic\":\"يانتۇ\",\"strike\":\"ئۆچۈرۈش سىزىقى\",\"subscript\":\"تۆۋەن ئىندېكس\",\"superscript\":\"يۇقىرى ئىندېكس\",\"underline\":\"ئاستى سىزىق\"},\"blockquote\":{\"toolbar\":\"بۆلەك نەقىل\"},\"clipboard\":{\"copy\":\"نەشر ھوقۇقىغا ئىگە بەلگىسى\",\"copyError\":\"تور كۆرگۈڭىزنىڭ بىخەتەرلىك تەڭشىكى تەھرىرلىگۈچنىڭ كۆچۈر مەشغۇلاتىنى ئۆزلۈكىدىن ئىجرا قىلىشىغا يول قويمايدۇ، ھەرپتاختا تېز كۇنۇپكا (Ctrl/Cmd+C) ئارقىلىق تاماملاڭ\",\"cut\":\"كەس\",\"cutError\":\"تور كۆرگۈڭىزنىڭ بىخەتەرلىك تەڭشىكى تەھرىرلىگۈچنىڭ كەس مەشغۇلاتىنى ئۆزلۈكىدىن ئىجرا قىلىشىغا يول قويمايدۇ، ھەرپتاختا تېز كۇنۇپكا (Ctrl/Cmd+X) ئارقىلىق تاماملاڭ\",\"paste\":\"چاپلا\",\"pasteArea\":\"چاپلاش دائىرىسى\",\"pasteMsg\":\"ھەرپتاختا تېز كۇنۇپكا (<STRONG>Ctrl/Cmd+V</STRONG>) نى ئىشلىتىپ مەزمۇننى تۆۋەندىكى رامكىغا كۆچۈرۈڭ، ئاندىن <STRONG>جەزملە</STRONG>نى بېسىڭ\",\"securityMsg\":\"توركۆرگۈڭىزنىڭ بىخەتەرلىك تەڭشىكى سەۋەبىدىن بۇ تەھرىرلىگۈچ چاپلاش تاختىسىدىكى مەزمۇننى بىۋاستە زىيارەت قىلالمايدۇ، بۇ كۆزنەكتە قايتا بىر قېتىم چاپلىشىڭىز كېرەك.\",\"title\":\"چاپلا\"},\"contextmenu\":{\"options\":\"قىسقا يول تىزىملىك تاللانمىسى\"},\"toolbar\":{\"toolbarCollapse\":\"قورال بالداقنى قاتلا\",\"toolbarExpand\":\"قورال بالداقنى ياي\",\"toolbarGroups\":{\"document\":\"پۈتۈك\",\"clipboard\":\"چاپلاش تاختىسى/يېنىۋال\",\"editing\":\"تەھرىر\",\"forms\":\"جەدۋەل\",\"basicstyles\":\"ئاساسىي ئۇسلۇب\",\"paragraph\":\"ئابزاس\",\"links\":\"ئۇلانما\",\"insert\":\"قىستۇر\",\"styles\":\"ئۇسلۇب\",\"colors\":\"رەڭ\",\"tools\":\"قورال\"},\"toolbars\":\"قورال بالداق\"},\"elementspath\":{\"eleLabel\":\"ئېلېمېنت يولى\",\"eleTitle\":\"%1 ئېلېمېنت\"},\"format\":{\"label\":\"پىچىم\",\"panelTitle\":\"پىچىم\",\"tag_address\":\"ئادرېس\",\"tag_div\":\"ئابزاس (DIV)\",\"tag_h1\":\"ماۋزۇ 1\",\"tag_h2\":\"ماۋزۇ 2\",\"tag_h3\":\"ماۋزۇ 3\",\"tag_h4\":\"ماۋزۇ 4\",\"tag_h5\":\"ماۋزۇ 5\",\"tag_h6\":\"ماۋزۇ 6\",\"tag_p\":\"ئادەتتىكى\",\"tag_pre\":\"تىزىلغان پىچىم\"},\"horizontalrule\":{\"toolbar\":\"توغرا سىزىق قىستۇر\"},\"image\":{\"alertUrl\":\"سۈرەت ئادرېسىنى كىرگۈزۈڭ\",\"alt\":\"تېكىست ئالماشتۇر\",\"border\":\"گىرۋەك چوڭلۇقى\",\"btnUpload\":\"مۇلازىمېتىرغا يۈكلە\",\"button2Img\":\"نۆۋەتتىكى توپچىنى سۈرەتكە ئۆزگەرتەمسىز؟\",\"hSpace\":\"توغرىسىغا ئارىلىقى\",\"img2Button\":\"نۆۋەتتىكى سۈرەتنى توپچىغا ئۆزگەرتەمسىز؟\",\"infoTab\":\"سۈرەت\",\"linkTab\":\"ئۇلانما\",\"lockRatio\":\"نىسبەتنى قۇلۇپلا\",\"menu\":\"سۈرەت خاسلىقى\",\"resetSize\":\"ئەسلى چوڭلۇق\",\"title\":\"سۈرەت خاسلىقى\",\"titleButton\":\"سۈرەت دائىرە خاسلىقى\",\"upload\":\"يۈكلە\",\"urlMissing\":\"سۈرەتنىڭ ئەسلى ھۆججەت ئادرېسى كەم\",\"vSpace\":\"بويىغا ئارىلىقى\",\"validateBorder\":\"گىرۋەك چوڭلۇقى چوقۇم سان بولىدۇ\",\"validateHSpace\":\"توغرىسىغا ئارىلىق چوقۇم پۈتۈن سان بولىدۇ\",\"validateVSpace\":\"بويىغا ئارىلىق چوقۇم پۈتۈن سان بولىدۇ\"},\"indent\":{\"indent\":\"تارايت\",\"outdent\":\"كەڭەيت\"},\"fakeobjects\":{\"anchor\":\"لەڭگەرلىك نۇقتا\",\"flash\":\"Flash جانلاندۇرۇم\",\"hiddenfield\":\"يوشۇرۇن دائىرە\",\"iframe\":\"IFrame\",\"unknown\":\"يوچۇن نەڭ\"},\"link\":{\"acccessKey\":\"زىيارەت كۇنۇپكا\",\"advanced\":\"ئالىي\",\"advisoryContentType\":\"مەزمۇن تىپى\",\"advisoryTitle\":\"ماۋزۇ\",\"anchor\":{\"toolbar\":\"لەڭگەرلىك نۇقتا ئۇلانمىسى قىستۇر/تەھرىرلە\",\"menu\":\"لەڭگەرلىك نۇقتا ئۇلانما خاسلىقى\",\"title\":\"لەڭگەرلىك نۇقتا ئۇلانما خاسلىقى\",\"name\":\"لەڭگەرلىك نۇقتا ئاتى\",\"errorName\":\"لەڭگەرلىك نۇقتا ئاتىنى كىرگۈزۈڭ\",\"remove\":\"لەڭگەرلىك نۇقتا ئۆچۈر\"},\"anchorId\":\"لەڭگەرلىك نۇقتا ID سى بويىچە\",\"anchorName\":\"لەڭگەرلىك نۇقتا ئاتى بويىچە\",\"charset\":\"ھەرپ كودلىنىشى\",\"cssClasses\":\"ئۇسلۇب خىلى ئاتى\",\"emailAddress\":\"ئادرېس\",\"emailBody\":\"مەزمۇن\",\"emailSubject\":\"ماۋزۇ\",\"id\":\"ID\",\"info\":\"ئۇلانما ئۇچۇرى\",\"langCode\":\"تىل كودى\",\"langDir\":\"تىل يۆنىلىشى\",\"langDirLTR\":\"سولدىن ئوڭغا (LTR)\",\"langDirRTL\":\"ئوڭدىن سولغا (RTL)\",\"menu\":\"ئۇلانما تەھرىر\",\"name\":\"ئات\",\"noAnchors\":\"(بۇ پۈتۈكتە ئىشلەتكىلى بولىدىغان لەڭگەرلىك نۇقتا يوق)\",\"noEmail\":\"ئېلخەت ئادرېسىنى كىرگۈزۈڭ\",\"noUrl\":\"ئۇلانما ئادرېسىنى كىرگۈزۈڭ\",\"other\":\"‹باشقا›\",\"popupDependent\":\"تەۋە (NS)\",\"popupFeatures\":\"قاڭقىش كۆزنەك خاسلىقى\",\"popupFullScreen\":\"پۈتۈن ئېكران (IE)\",\"popupLeft\":\"سول\",\"popupLocationBar\":\"ئادرېس بالداق\",\"popupMenuBar\":\"تىزىملىك بالداق\",\"popupResizable\":\"چوڭلۇقى ئۆزگەرتىشچان\",\"popupScrollBars\":\"دومىلىما سۈرگۈچ\",\"popupStatusBar\":\"ھالەت بالداق\",\"popupToolbar\":\"قورال بالداق\",\"popupTop\":\"ئوڭ\",\"rel\":\"باغلىنىش\",\"selectAnchor\":\"بىر لەڭگەرلىك نۇقتا تاللاڭ\",\"styles\":\"قۇر ئىچىدىكى ئۇسلۇبى\",\"tabIndex\":\"Tab تەرتىپى\",\"target\":\"نىشان\",\"targetFrame\":\"‹كاندۇك›\",\"targetFrameName\":\"نىشان كاندۇك ئاتى\",\"targetPopup\":\"‹قاڭقىش كۆزنەك›\",\"targetPopupName\":\"قاڭقىش كۆزنەك ئاتى\",\"title\":\"ئۇلانما\",\"toAnchor\":\"بەت ئىچىدىكى لەڭگەرلىك نۇقتا ئۇلانمىسى\",\"toEmail\":\"ئېلخەت\",\"toUrl\":\"ئادرېس\",\"toolbar\":\"ئۇلانما قىستۇر/تەھرىرلە\",\"type\":\"ئۇلانما تىپى\",\"unlink\":\"ئۇلانما بىكار قىل\",\"upload\":\"يۈكلە\"},\"list\":{\"bulletedlist\":\"تۈر بەلگە تىزىمى\",\"numberedlist\":\"تەرتىپ نومۇر تىزىمى\"},\"magicline\":{\"title\":\"بۇ جايغا ئابزاس قىستۇر\"},\"maximize\":{\"maximize\":\"چوڭايت\",\"minimize\":\"كىچىكلەت\"},\"pastetext\":{\"button\":\"پىچىمى يوق تېكىست سۈپىتىدە چاپلا\",\"title\":\"پىچىمى يوق تېكىست سۈپىتىدە چاپلا\"},\"pastefromword\":{\"confirmCleanup\":\"سىز چاپلىماقچى بولغان مەزمۇن MS Word تىن كەلگەندەك قىلىدۇ، MS Word پىچىمىنى تازىلىۋەتكەندىن كېيىن ئاندىن چاپلامدۇ؟\",\"error\":\"ئىچكى خاتالىق سەۋەبىدىن چاپلايدىغان سانلىق مەلۇماتنى تازىلىيالمايدۇ\",\"title\":\"MS Word تىن چاپلا\",\"toolbar\":\"MS Word تىن چاپلا\"},\"removeformat\":{\"toolbar\":\"پىچىمنى چىقىرىۋەت\"},\"sourcearea\":{\"toolbar\":\"مەنبە\"},\"specialchar\":{\"options\":\"ئالاھىدە ھەرپ تاللانمىسى\",\"title\":\"ئالاھىدە ھەرپ تاللاڭ\",\"toolbar\":\"ئالاھىدە ھەرپ قىستۇر\"},\"scayt\":{\"about\":\"شۇئان ئىملا تەكشۈرۈش ھەققىدە\",\"aboutTab\":\"ھەققىدە\",\"addWord\":\"سۆز قوش\",\"allCaps\":\"چوڭ ھەرپتە يېزىلغان ھەممە سۆزگە پەرۋا قىلما\",\"dic_create\":\"قۇر\",\"dic_delete\":\"ئۆچۈر\",\"dic_field_name\":\"لۇغەت ئاتى\",\"dic_info\":\"باشلىنىشتا ئىشلەتكۈچى لۇغىتى Cookie  غا ساقلىنىدۇ ئەمما Cookie نىڭ سىغىمى چەكلىك بولغاچقا، ئىشلەتكۈچى لۇغىتى كۆپىيىپ Cookie  چەكلىمىسىدىن ئېشىپ كەتكەندە ساقلىغىلى بولمايدۇ، بۇ چاغدا لۇغىتىڭىزنى مۇلازىمېتىرىمىزغا ساقلىسىڭىز بولىدۇ. شەخسىي لۇغىتىڭىزنى مۇلازىمېتىرىمىزغا ساقلىماقچى بولسىڭىز لۇغىتىڭىزگە ئاتتىن بىرنى قويۇڭ، ئەگەر مۇلازىمتېرىمىزدا سىزنىڭ لۇغىتىڭىزدىن بىرسى بولسا لۇغەت ئاتىنى كىرگۈزۈپ ئەسلىگە قايتۇر توپچىسىنى بېسىڭ.\",\"dic_rename\":\"ئات ئۆزگەرت\",\"dic_restore\":\"ئەسلىگە كەلتۈر\",\"dictionariesTab\":\"لۇغەت\",\"disable\":\"شۇئان ئىملا تەكشۈرۈشنى چەكلە\",\"emptyDic\":\"لۇغەت ئاتى بوش قالمايدۇ\",\"enable\":\"شۇئان ئىملا تەكشۈرۈشنى قوزغات\",\"ignore\":\"پەرۋا قىلما\",\"ignoreAll\":\"ھەممىسىگە پەرۋا قىلما\",\"ignoreDomainNames\":\"دائىرە ئاتىغا پەرۋا قىلما\",\"langs\":\"تىل\",\"languagesTab\":\"تىل\",\"mixedCase\":\"چوڭ كىچىك ھەرپ بىلەن ئارىلاش يېزىلغان سۆزگە پەرۋا قىلما\",\"mixedWithDigits\":\"سان بار سۆزگە پەرۋا قىلما\",\"moreSuggestions\":\"تېخىمۇ كۆپ ئىملا تەۋسىيەسى\",\"opera_title\":\"Opera توركۆرگۈنى قوللىمايدۇ\",\"options\":\"تاللانما\",\"optionsTab\":\"تاللانما\",\"title\":\"شۇئان ئىملا تەكشۈر\",\"toggle\":\"شۇئان ئىملا تەكشۈرۈشنى ۋاقىتلىق توختات/قوزغات\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"ئۇسلۇب\",\"panelTitle\":\"ئۇسلۇب\",\"panelTitle1\":\"بۆلەك دەرىجىسىدىكى ئېلېمېنت ئۇسلۇبى\",\"panelTitle2\":\"ئىچكى باغلانما ئېلېمېنت ئۇسلۇبى\",\"panelTitle3\":\"نەڭ (Object) ئېلېمېنت ئۇسلۇبى\"},\"table\":{\"border\":\"گىرۋەك\",\"caption\":\"ماۋزۇ\",\"cell\":{\"menu\":\"كاتەكچە\",\"insertBefore\":\"سولغا كاتەكچە قىستۇر\",\"insertAfter\":\"ئوڭغا كاتەكچە قىستۇر\",\"deleteCell\":\"كەتەكچە ئۆچۈر\",\"merge\":\"كاتەكچە بىرلەشتۈر\",\"mergeRight\":\"كاتەكچىنى ئوڭغا بىرلەشتۈر\",\"mergeDown\":\"كاتەكچىنى ئاستىغا بىرلەشتۈر\",\"splitHorizontal\":\"كاتەكچىنى توغرىسىغا بىرلەشتۈر\",\"splitVertical\":\"كاتەكچىنى بويىغا بىرلەشتۈر\",\"title\":\"كاتەكچە خاسلىقى\",\"cellType\":\"كاتەكچە تىپى\",\"rowSpan\":\"بويىغا چات ئارىسى قۇر سانى\",\"colSpan\":\"توغرىسىغا چات ئارىسى ئىستون سانى\",\"wordWrap\":\"ئۆزلۈكىدىن قۇر قاتلا\",\"hAlign\":\"توغرىسىغا توغرىلا\",\"vAlign\":\"بويىغا توغرىلا\",\"alignBaseline\":\"ئاساسىي سىزىق\",\"bgColor\":\"تەگلىك رەڭگى\",\"borderColor\":\"گىرۋەك رەڭگى\",\"data\":\"سانلىق مەلۇمات\",\"header\":\"جەدۋەل باشى\",\"yes\":\"ھەئە\",\"no\":\"ياق\",\"invalidWidth\":\"كاتەكچە كەڭلىكى چوقۇم سان بولىدۇ\",\"invalidHeight\":\"كاتەكچە ئېگىزلىكى چوقۇم سان بولىدۇ\",\"invalidRowSpan\":\"قۇر چات ئارىسى چوقۇم پۈتۈن سان بولىدۇ \",\"invalidColSpan\":\"ئىستون چات ئارىسى چوقۇم پۈتۈن سان بولىدۇ\",\"chooseColor\":\"تاللاڭ\"},\"cellPad\":\"يان ئارىلىق\",\"cellSpace\":\"ئارىلىق\",\"column\":{\"menu\":\"ئىستون\",\"insertBefore\":\"سولغا ئىستون قىستۇر\",\"insertAfter\":\"ئوڭغا ئىستون قىستۇر\",\"deleteColumn\":\"ئىستون ئۆچۈر\"},\"columns\":\"ئىستون سانى\",\"deleteTable\":\"جەدۋەل ئۆچۈر\",\"headers\":\"ماۋزۇ كاتەكچە\",\"headersBoth\":\"بىرىنچى ئىستون ۋە بىرىنچى قۇر\",\"headersColumn\":\"بىرىنچى ئىستون\",\"headersNone\":\"يوق\",\"headersRow\":\"بىرىنچى قۇر\",\"invalidBorder\":\"گىرۋەك توملۇقى چوقۇم سان بولىدۇ\",\"invalidCellPadding\":\"كاتەكچىگە چوقۇم سان تولدۇرۇلىدۇ\",\"invalidCellSpacing\":\"كاتەكچە ئارىلىقى چوقۇم سان بولىدۇ\",\"invalidCols\":\"بەلگىلەنگەن قۇر سانى چوقۇم نۆلدىن چوڭ بولىدۇ\",\"invalidHeight\":\"جەدۋەل ئېگىزلىكى چوقۇم سان بولىدۇ\",\"invalidRows\":\"بەلگىلەنگەن ئىستون سانى چوقۇم نۆلدىن چوڭ بولىدۇ\",\"invalidWidth\":\"جەدۋەل كەڭلىكى چوقۇم سان بولىدۇ\",\"menu\":\"جەدۋەل خاسلىقى\",\"row\":{\"menu\":\"قۇر\",\"insertBefore\":\"ئۈستىگە قۇر قىستۇر\",\"insertAfter\":\"ئاستىغا قۇر قىستۇر\",\"deleteRow\":\"قۇر ئۆچۈر\"},\"rows\":\"قۇر سانى\",\"summary\":\"ئۈزۈندە\",\"title\":\"جەدۋەل خاسلىقى\",\"toolbar\":\"جەدۋەل\",\"widthPc\":\"پىرسەنت\",\"widthPx\":\"پىكسېل\",\"widthUnit\":\"كەڭلىك بىرلىكى\"},\"undo\":{\"redo\":\"قايتىلا \",\"undo\":\"يېنىۋال\"},\"wsc\":{\"btnIgnore\":\"پەرۋا قىلما\",\"btnIgnoreAll\":\"ھەممىگە پەرۋا قىلما\",\"btnReplace\":\"ئالماشتۇر\",\"btnReplaceAll\":\"ھەممىنى ئالماشتۇر\",\"btnUndo\":\"يېنىۋال\",\"changeTo\":\"ئۆزگەرت\",\"errorLoading\":\"لازىملىق مۇلازىمېتىرنى يۈكلىگەندە خاتالىق كۆرۈلدى: %s.\",\"ieSpellDownload\":\"ئىملا تەكشۈرۈش قىستۇرمىسى تېخى ئورنىتىلمىغان، ھازىرلا چۈشۈرەمسىز؟\",\"manyChanges\":\"ئىملا تەكشۈرۈش تامام: %1  سۆزنى ئۆزگەرتتى\",\"noChanges\":\"ئىملا تەكشۈرۈش تامام: ھېچقانداق سۆزنى ئۆزگەرتمىدى\",\"noMispell\":\"ئىملا تەكشۈرۈش تامام: ئىملا خاتالىقى بايقالمىدى\",\"noSuggestions\":\"-تەكلىپ يوق-\",\"notAvailable\":\"كەچۈرۈڭ، مۇلازىمېتىرنى ۋاقتىنچە ئىشلەتكىلى بولمايدۇ\",\"notInDic\":\"لۇغەتتە يوق\",\"oneChange\":\"ئىملا تەكشۈرۈش تامام: بىر سۆزنى ئۆزگەرتتى\",\"progress\":\"ئىملا تەكشۈرۈۋاتىدۇ…\",\"title\":\"ئىملا تەكشۈر\",\"toolbar\":\"ئىملا تەكشۈر\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/uk.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['uk']={\"editor\":\"Текстовий редактор\",\"editorPanel\":\"Панель текстового редактора\",\"common\":{\"editorHelp\":\"натисніть ALT 0 для довідки\",\"browseServer\":\"Огляд Сервера\",\"url\":\"URL\",\"protocol\":\"Протокол\",\"upload\":\"Надіслати\",\"uploadSubmit\":\"Надіслати на сервер\",\"image\":\"Зображення\",\"flash\":\"Flash\",\"form\":\"Форма\",\"checkbox\":\"Галочка\",\"radio\":\"Кнопка вибору\",\"textField\":\"Текстове поле\",\"textarea\":\"Текстова область\",\"hiddenField\":\"Приховане поле\",\"button\":\"Кнопка\",\"select\":\"Список\",\"imageButton\":\"Кнопка із зображенням\",\"notSet\":\"<не визначено>\",\"id\":\"Ідентифікатор\",\"name\":\"Ім'я\",\"langDir\":\"Напрямок мови\",\"langDirLtr\":\"Зліва направо (LTR)\",\"langDirRtl\":\"Справа наліво (RTL)\",\"langCode\":\"Код мови\",\"longDescr\":\"Довгий опис URL\",\"cssClass\":\"Клас CSS\",\"advisoryTitle\":\"Заголовок\",\"cssStyle\":\"Стиль CSS\",\"ok\":\"ОК\",\"cancel\":\"Скасувати\",\"close\":\"Закрити\",\"preview\":\"Попередній перегляд\",\"resize\":\"Потягніть для зміни розмірів\",\"generalTab\":\"Основне\",\"advancedTab\":\"Додаткове\",\"validateNumberFailed\":\"Значення не є цілим числом.\",\"confirmNewPage\":\"Всі незбережені зміни будуть втрачені. Ви впевнені, що хочете завантажити нову сторінку?\",\"confirmCancel\":\"Деякі опції змінено. Закрити вікно без збереження змін?\",\"options\":\"Опції\",\"target\":\"Ціль\",\"targetNew\":\"Нове вікно (_blank)\",\"targetTop\":\"Поточне вікно (_top)\",\"targetSelf\":\"Поточний фрейм/вікно (_self)\",\"targetParent\":\"Батьківський фрейм/вікно (_parent)\",\"langDirLTR\":\"Зліва направо (LTR)\",\"langDirRTL\":\"Справа наліво (RTL)\",\"styles\":\"Стиль CSS\",\"cssClasses\":\"Клас CSS\",\"width\":\"Ширина\",\"height\":\"Висота\",\"align\":\"Вирівнювання\",\"alignLeft\":\"По лівому краю\",\"alignRight\":\"По правому краю\",\"alignCenter\":\"По центру\",\"alignTop\":\"По верхньому краю\",\"alignMiddle\":\"По середині\",\"alignBottom\":\"По нижньому краю\",\"invalidValue\":\"Невірне значення.\",\"invalidHeight\":\"Висота повинна бути цілим числом.\",\"invalidWidth\":\"Ширина повинна бути цілим числом.\",\"invalidCssLength\":\"Значення, вказане для \\\"%1\\\" в полі повинно бути позитивним числом або без дійсного виміру CSS блоку (px, %, in, cm, mm, em, ex, pt або pc).\",\"invalidHtmlLength\":\"Значення, вказане для \\\"%1\\\" в полі повинно бути позитивним числом або без дійсного виміру HTML блоку (px або %).\",\"invalidInlineStyle\":\"Значення, вказане для вбудованого стилю повинне складатися з одного чи кількох кортежів у форматі \\\"ім'я : значення\\\", розділених крапкою з комою.\",\"cssLengthTooltip\":\"Введіть номер значення в пікселях або число з дійсною одиниці CSS (px, %, in, cm, mm, em, ex, pt або pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, не доступне</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. Всі права застережено.\",\"dlgTitle\":\"Про CKEditor\",\"help\":\"Перевірте $1 для допомоги.\",\"moreInfo\":\"Щодо інформації з ліцензування завітайте на наш сайт:\",\"title\":\"Про CKEditor\",\"userGuide\":\"Інструкція Користувача для CKEditor\"},\"basicstyles\":{\"bold\":\"Жирний\",\"italic\":\"Курсив\",\"strike\":\"Закреслений\",\"subscript\":\"Нижній індекс\",\"superscript\":\"Верхній індекс\",\"underline\":\"Підкреслений\"},\"blockquote\":{\"toolbar\":\"Цитата\"},\"clipboard\":{\"copy\":\"Копіювати\",\"copyError\":\"Налаштування безпеки Вашого браузера не дозволяють редактору автоматично виконувати операції копіювання. Будь ласка, використовуйте клавіатуру для цього (Ctrl/Cmd+C).\",\"cut\":\"Вирізати\",\"cutError\":\"Налаштування безпеки Вашого браузера не дозволяють редактору автоматично виконувати операції вирізування. Будь ласка, використовуйте клавіатуру для цього (Ctrl/Cmd+X)\",\"paste\":\"Вставити\",\"pasteArea\":\"Область вставки\",\"pasteMsg\":\"Будь ласка, вставте інформацію з буфера обміну в цю область, користуючись комбінацією клавіш (<STRONG>Ctrl/Cmd+V</STRONG>), та натисніть <STRONG>OK</STRONG>.\",\"securityMsg\":\"Редактор не може отримати прямий доступ до буферу обміну у зв'язку з налаштуваннями Вашого браузера. Вам потрібно вставити інформацію в це вікно.\",\"title\":\"Вставити\"},\"contextmenu\":{\"options\":\"Опції контекстного меню\"},\"toolbar\":{\"toolbarCollapse\":\"Згорнути панель інструментів\",\"toolbarExpand\":\"Розгорнути панель інструментів\",\"toolbarGroups\":{\"document\":\"Документ\",\"clipboard\":\"Буфер обміну / Скасувати\",\"editing\":\"Редагування\",\"forms\":\"Форми\",\"basicstyles\":\"Основний Стиль\",\"paragraph\":\"Параграф\",\"links\":\"Посилання\",\"insert\":\"Вставити\",\"styles\":\"Стилі\",\"colors\":\"Кольори\",\"tools\":\"Інструменти\"},\"toolbars\":\"Панель інструментів редактора\"},\"elementspath\":{\"eleLabel\":\"Шлях\",\"eleTitle\":\"%1 елемент\"},\"format\":{\"label\":\"Форматування\",\"panelTitle\":\"Форматування параграфа\",\"tag_address\":\"Адреса\",\"tag_div\":\"Нормальний (div)\",\"tag_h1\":\"Заголовок 1\",\"tag_h2\":\"Заголовок 2\",\"tag_h3\":\"Заголовок 3\",\"tag_h4\":\"Заголовок 4\",\"tag_h5\":\"Заголовок 5\",\"tag_h6\":\"Заголовок 6\",\"tag_p\":\"Нормальний\",\"tag_pre\":\"Форматований\"},\"horizontalrule\":{\"toolbar\":\"Горизонтальна лінія\"},\"image\":{\"alertUrl\":\"Будь ласка, вкажіть URL зображення\",\"alt\":\"Альтернативний текст\",\"border\":\"Рамка\",\"btnUpload\":\"Надіслати на сервер\",\"button2Img\":\"Бажаєте перетворити обрану кнопку-зображення на просте зображення?\",\"hSpace\":\"Гориз. відступ\",\"img2Button\":\"Бажаєте перетворити обране зображення на кнопку-зображення?\",\"infoTab\":\"Інформація про зображення\",\"linkTab\":\"Посилання\",\"lockRatio\":\"Зберегти пропорції\",\"menu\":\"Властивості зображення\",\"resetSize\":\"Очистити поля розмірів\",\"title\":\"Властивості зображення\",\"titleButton\":\"Властивості кнопки із зображенням\",\"upload\":\"Надіслати\",\"urlMissing\":\"Вкажіть URL зображення.\",\"vSpace\":\"Верт. відступ\",\"validateBorder\":\"Ширина рамки повинна бути цілим числом.\",\"validateHSpace\":\"Гориз. відступ повинен бути цілим числом.\",\"validateVSpace\":\"Верт. відступ повинен бути цілим числом.\"},\"indent\":{\"indent\":\"Збільшити відступ\",\"outdent\":\"Зменшити відступ\"},\"fakeobjects\":{\"anchor\":\"Якір\",\"flash\":\"Flash-анімація\",\"hiddenfield\":\"Приховані Поля\",\"iframe\":\"IFrame\",\"unknown\":\"Невідомий об'єкт\"},\"link\":{\"acccessKey\":\"Гаряча клавіша\",\"advanced\":\"Додаткове\",\"advisoryContentType\":\"Тип вмісту\",\"advisoryTitle\":\"Заголовок\",\"anchor\":{\"toolbar\":\"Вставити/Редагувати якір\",\"menu\":\"Властивості якоря\",\"title\":\"Властивості якоря\",\"name\":\"Ім'я якоря\",\"errorName\":\"Будь ласка, вкажіть ім'я якоря\",\"remove\":\"Прибрати якір\"},\"anchorId\":\"За ідентифікатором елементу\",\"anchorName\":\"За ім'ям елементу\",\"charset\":\"Кодування\",\"cssClasses\":\"Клас CSS\",\"emailAddress\":\"Адреса ел. пошти\",\"emailBody\":\"Тіло повідомлення\",\"emailSubject\":\"Тема листа\",\"id\":\"Ідентифікатор\",\"info\":\"Інформація посилання\",\"langCode\":\"Код мови\",\"langDir\":\"Напрямок мови\",\"langDirLTR\":\"Зліва направо (LTR)\",\"langDirRTL\":\"Справа наліво (RTL)\",\"menu\":\"Вставити посилання\",\"name\":\"Ім'я\",\"noAnchors\":\"(В цьому документі немає якорів)\",\"noEmail\":\"Будь ласка, вкажіть адрес ел. пошти\",\"noUrl\":\"Будь ласка, вкажіть URL посилання\",\"other\":\"<інший>\",\"popupDependent\":\"Залежний (Netscape)\",\"popupFeatures\":\"Властивості випливаючого вікна\",\"popupFullScreen\":\"Повний екран (IE)\",\"popupLeft\":\"Позиція зліва\",\"popupLocationBar\":\"Панель локації\",\"popupMenuBar\":\"Панель меню\",\"popupResizable\":\"Масштабоване\",\"popupScrollBars\":\"Стрічки прокрутки\",\"popupStatusBar\":\"Рядок статусу\",\"popupToolbar\":\"Панель інструментів\",\"popupTop\":\"Позиція зверху\",\"rel\":\"Зв'язок\",\"selectAnchor\":\"Оберіть якір\",\"styles\":\"Стиль CSS\",\"tabIndex\":\"Послідовність переходу\",\"target\":\"Ціль\",\"targetFrame\":\"<фрейм>\",\"targetFrameName\":\"Ім'я цільового фрейму\",\"targetPopup\":\"<випливаюче вікно>\",\"targetPopupName\":\"Ім'я випливаючого вікна\",\"title\":\"Посилання\",\"toAnchor\":\"Якір на цю сторінку\",\"toEmail\":\"Ел. пошта\",\"toUrl\":\"URL\",\"toolbar\":\"Вставити/Редагувати посилання\",\"type\":\"Тип посилання\",\"unlink\":\"Видалити посилання\",\"upload\":\"Надіслати\"},\"list\":{\"bulletedlist\":\"Маркірований список\",\"numberedlist\":\"Нумерований список\"},\"magicline\":{\"title\":\"Вставити абзац\"},\"maximize\":{\"maximize\":\"Максимізувати\",\"minimize\":\"Мінімізувати\"},\"pastetext\":{\"button\":\"Вставити тільки текст\",\"title\":\"Вставити тільки текст\"},\"pastefromword\":{\"confirmCleanup\":\"Текст, що Ви намагаєтесь вставити, схожий на скопійований з Word. Бажаєте очистити його форматування перед вставлянням?\",\"error\":\"Неможливо очистити форматування через внутрішню помилку.\",\"title\":\"Вставити з Word\",\"toolbar\":\"Вставити з Word\"},\"removeformat\":{\"toolbar\":\"Очистити форматування\"},\"sourcearea\":{\"toolbar\":\"Джерело\"},\"specialchar\":{\"options\":\"Опції\",\"title\":\"Оберіть спеціальний символ\",\"toolbar\":\"Спеціальний символ\"},\"scayt\":{\"about\":\"Про SCAYT\",\"aboutTab\":\"Про SCAYT\",\"addWord\":\"Додати слово\",\"allCaps\":\"Пропустити прописні слова\",\"dic_create\":\"Створити\",\"dic_delete\":\"Видалити\",\"dic_field_name\":\"Назва словника\",\"dic_info\":\"Як правило, користувацькі словники зберігаються у cookie-файлах. Однак, cookie-файли мають обмеження на розмір. Якщо користувацький словник зростає в обсязі настільки, що вже не може бути збережений у cookie-файлі, тоді його можна зберегти на нашому сервері. Щоб зберегти Ваш персональний словник на нашому сервері необхідно вказати назву словника. Якщо Ви вже зберігали словник на сервері, будь ласка, вкажіть назву збереженого словника і натисніть кнопку Відновити.\",\"dic_rename\":\"Перейменувати\",\"dic_restore\":\"Відновити\",\"dictionariesTab\":\"Словники\",\"disable\":\"Вимкнути SCAYT\",\"emptyDic\":\"Назва словника повинна бути вказана.\",\"enable\":\"Ввімкнути SCAYT\",\"ignore\":\"Пропустити\",\"ignoreAll\":\"Пропустити всі\",\"ignoreDomainNames\":\"Пропустити доменні назви\",\"langs\":\"Мови\",\"languagesTab\":\"Мови\",\"mixedCase\":\"Пропустити слова зі змішаним регістром\",\"mixedWithDigits\":\"Пропустити слова, що містять цифри\",\"moreSuggestions\":\"Більше варіантів\",\"opera_title\":\"Не підтримується в Opera\",\"options\":\"Опції\",\"optionsTab\":\"Опції\",\"title\":\"Перефірка орфографії по мірі набору\",\"toggle\":\"Перемкнути SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Стиль\",\"panelTitle\":\"Стилі форматування\",\"panelTitle1\":\"Блочні стилі\",\"panelTitle2\":\"Рядкові стилі\",\"panelTitle3\":\"Об'єктні стилі\"},\"table\":{\"border\":\"Розмір рамки\",\"caption\":\"Заголовок таблиці\",\"cell\":{\"menu\":\"Комірки\",\"insertBefore\":\"Вставити комірку перед\",\"insertAfter\":\"Вставити комірку після\",\"deleteCell\":\"Видалити комірки\",\"merge\":\"Об'єднати комірки\",\"mergeRight\":\"Об'єднати справа\",\"mergeDown\":\"Об'єднати донизу\",\"splitHorizontal\":\"Розділити комірку по горизонталі\",\"splitVertical\":\"Розділити комірку по вертикалі\",\"title\":\"Властивості комірки\",\"cellType\":\"Тип комірки\",\"rowSpan\":\"Об'єднання рядків\",\"colSpan\":\"Об'єднання стовпців\",\"wordWrap\":\"Автоперенесення тексту\",\"hAlign\":\"Гориз. вирівнювання\",\"vAlign\":\"Верт. вирівнювання\",\"alignBaseline\":\"По базовій лінії\",\"bgColor\":\"Колір фону\",\"borderColor\":\"Колір рамки\",\"data\":\"Дані\",\"header\":\"Заголовок\",\"yes\":\"Так\",\"no\":\"Ні\",\"invalidWidth\":\"Ширина комірки повинна бути цілим числом.\",\"invalidHeight\":\"Висота комірки повинна бути цілим числом.\",\"invalidRowSpan\":\"Кількість об'єднуваних рядків повинна бути цілим числом.\",\"invalidColSpan\":\"Кількість об'єднуваних стовбців повинна бути цілим числом.\",\"chooseColor\":\"Обрати\"},\"cellPad\":\"Внутр. відступ\",\"cellSpace\":\"Проміжок\",\"column\":{\"menu\":\"Стовбці\",\"insertBefore\":\"Вставити стовбець перед\",\"insertAfter\":\"Вставити стовбець після\",\"deleteColumn\":\"Видалити стовбці\"},\"columns\":\"Стовбці\",\"deleteTable\":\"Видалити таблицю\",\"headers\":\"Заголовки стовбців/рядків\",\"headersBoth\":\"Стовбці і рядки\",\"headersColumn\":\"Стовбці\",\"headersNone\":\"Без заголовків\",\"headersRow\":\"Рядки\",\"invalidBorder\":\"Розмір рамки повинен бути цілим числом.\",\"invalidCellPadding\":\"Внутр. відступ комірки повинен бути цілим числом.\",\"invalidCellSpacing\":\"Проміжок між комірками повинен бути цілим числом.\",\"invalidCols\":\"Кількість стовбців повинна бути більшою 0.\",\"invalidHeight\":\"Висота таблиці повинна бути цілим числом.\",\"invalidRows\":\"Кількість рядків повинна бути більшою 0.\",\"invalidWidth\":\"Ширина таблиці повинна бути цілим числом.\",\"menu\":\"Властивості таблиці\",\"row\":{\"menu\":\"Рядки\",\"insertBefore\":\"Вставити рядок перед\",\"insertAfter\":\"Вставити рядок після\",\"deleteRow\":\"Видалити рядки\"},\"rows\":\"Рядки\",\"summary\":\"Детальний опис заголовку таблиці\",\"title\":\"Властивості таблиці\",\"toolbar\":\"Таблиця\",\"widthPc\":\"відсотків\",\"widthPx\":\"пікселів\",\"widthUnit\":\"Одиниці вимір.\"},\"undo\":{\"redo\":\"Повторити\",\"undo\":\"Повернути\"},\"wsc\":{\"btnIgnore\":\"Пропустити\",\"btnIgnoreAll\":\"Пропустити все\",\"btnReplace\":\"Замінити\",\"btnReplaceAll\":\"Замінити все\",\"btnUndo\":\"Назад\",\"changeTo\":\"Замінити на\",\"errorLoading\":\"Помилка завантаження : %s.\",\"ieSpellDownload\":\"Модуль перевірки орфографії не встановлено. Бажаєте завантажити його зараз?\",\"manyChanges\":\"Перевірку орфографії завершено: 1% слів(ова) змінено\",\"noChanges\":\"Перевірку орфографії завершено: жодне слово не змінено\",\"noMispell\":\"Перевірку орфографії завершено: помилок не знайдено\",\"noSuggestions\":\"- немає варіантів -\",\"notAvailable\":\"Вибачте, але сервіс наразі недоступний.\",\"notInDic\":\"Немає в словнику\",\"oneChange\":\"Перевірку орфографії завершено: змінено одне слово\",\"progress\":\"Виконується перевірка орфографії...\",\"title\":\"Перевірка орфографії\",\"toolbar\":\"Перевірити орфографію\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/vi.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['vi']={\"editor\":\"Bộ soạn thảo văn bản có định dạng\",\"editorPanel\":\"Rich Text Editor panel\",\"common\":{\"editorHelp\":\"Nhấn ALT + 0 để được giúp đỡ\",\"browseServer\":\"Duyệt máy chủ\",\"url\":\"URL\",\"protocol\":\"Giao thức\",\"upload\":\"Tải lên\",\"uploadSubmit\":\"Tải lên máy chủ\",\"image\":\"Hình ảnh\",\"flash\":\"Flash\",\"form\":\"Biểu mẫu\",\"checkbox\":\"Nút kiểm\",\"radio\":\"Nút chọn\",\"textField\":\"Trường văn bản\",\"textarea\":\"Vùng văn bản\",\"hiddenField\":\"Trường ẩn\",\"button\":\"Nút\",\"select\":\"Ô chọn\",\"imageButton\":\"Nút hình ảnh\",\"notSet\":\"<không thiết lập>\",\"id\":\"Định danh\",\"name\":\"Tên\",\"langDir\":\"Hướng ngôn ngữ\",\"langDirLtr\":\"Trái sang phải (LTR)\",\"langDirRtl\":\"Phải sang trái (RTL)\",\"langCode\":\"Mã ngôn ngữ\",\"longDescr\":\"Mô tả URL\",\"cssClass\":\"Lớp Stylesheet\",\"advisoryTitle\":\"Nhan đề hướng dẫn\",\"cssStyle\":\"Kiểu (style)\",\"ok\":\"Đồng ý\",\"cancel\":\"Bỏ qua\",\"close\":\"Đóng\",\"preview\":\"Xem trước\",\"resize\":\"Kéo rê để thay đổi kích cỡ\",\"generalTab\":\"Tab chung\",\"advancedTab\":\"Tab mở rộng\",\"validateNumberFailed\":\"Giá trị này không phải là số.\",\"confirmNewPage\":\"Mọi thay đổi không được lưu lại, nội dung này sẽ bị mất. Bạn có chắc chắn muốn tải một trang mới?\",\"confirmCancel\":\"Một vài tùy chọn đã bị thay đổi. Bạn có chắc chắn muốn đóng hộp thoại?\",\"options\":\"Tùy chọn\",\"target\":\"Đích đến\",\"targetNew\":\"Cửa sổ mới (_blank)\",\"targetTop\":\"Cửa sổ trên cùng (_top)\",\"targetSelf\":\"Tại trang (_self)\",\"targetParent\":\"Cửa sổ cha (_parent)\",\"langDirLTR\":\"Trái sang phải (LTR)\",\"langDirRTL\":\"Phải sang trái (RTL)\",\"styles\":\"Kiểu\",\"cssClasses\":\"Lớp CSS\",\"width\":\"Chiều rộng\",\"height\":\"chiều cao\",\"align\":\"Vị trí\",\"alignLeft\":\"Trái\",\"alignRight\":\"Phải\",\"alignCenter\":\"Giữa\",\"alignTop\":\"Trên\",\"alignMiddle\":\"Giữa\",\"alignBottom\":\"Dưới\",\"invalidValue\":\"Giá trị không hợp lệ.\",\"invalidHeight\":\"Chiều cao phải là số nguyên.\",\"invalidWidth\":\"Chiều rộng phải là số nguyên.\",\"invalidCssLength\":\"Giá trị quy định cho trường \\\"%1\\\" phải là một số dương có hoặc không có một đơn vị đo CSS hợp lệ (px, %, in, cm, mm, em, ex, pt, hoặc pc).\",\"invalidHtmlLength\":\"Giá trị quy định cho trường \\\"%1\\\" phải là một số dương có hoặc không có một đơn vị đo HTML hợp lệ (px hoặc %).\",\"invalidInlineStyle\":\"Giá trị quy định cho kiểu nội tuyến phải bao gồm một hoặc nhiều dữ liệu với định dạng \\\"tên:giá trị\\\", cách nhau bằng dấu chấm phẩy.\",\"cssLengthTooltip\":\"Nhập một giá trị theo pixel hoặc một số với một đơn vị CSS hợp lệ (px, %, in, cm, mm, em, ex, pt, hoặc pc).\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">, không có</span>\"},\"about\":{\"copy\":\"Bản quyền &copy; $1. Giữ toàn quyền.\",\"dlgTitle\":\"Thông tin về CKEditor\",\"help\":\"Kiểm tra $1 để được giúp đỡ.\",\"moreInfo\":\"Vui lòng ghé thăm trang web của chúng tôi để có thông tin về giấy phép:\",\"title\":\"Thông tin về CKEditor\",\"userGuide\":\"Hướng dẫn sử dụng CKEditor\"},\"basicstyles\":{\"bold\":\"Đậm\",\"italic\":\"Nghiêng\",\"strike\":\"Gạch xuyên ngang\",\"subscript\":\"Chỉ số dưới\",\"superscript\":\"Chỉ số trên\",\"underline\":\"Gạch chân\"},\"blockquote\":{\"toolbar\":\"Khối trích dẫn\"},\"clipboard\":{\"copy\":\"Sao chép\",\"copyError\":\"Các thiết lập bảo mật của trình duyệt không cho phép trình biên tập tự động thực thi lệnh sao chép. Hãy sử dụng bàn phím cho lệnh này (Ctrl/Cmd+C).\",\"cut\":\"Cắt\",\"cutError\":\"Các thiết lập bảo mật của trình duyệt không cho phép trình biên tập tự động thực thi lệnh cắt. Hãy sử dụng bàn phím cho lệnh này (Ctrl/Cmd+X).\",\"paste\":\"Dán\",\"pasteArea\":\"Khu vực dán\",\"pasteMsg\":\"Hãy dán nội dung vào trong khung bên dưới, sử dụng tổ hợp phím (<STRONG>Ctrl/Cmd+V</STRONG>) và nhấn vào nút <STRONG>Đồng ý</STRONG>.\",\"securityMsg\":\"Do thiết lập bảo mật của trình duyệt nên trình biên tập không thể truy cập trực tiếp vào nội dung đã sao chép. Bạn cần phải dán lại nội dung vào cửa sổ này.\",\"title\":\"Dán\"},\"contextmenu\":{\"options\":\"Tùy chọn menu bổ xung\"},\"toolbar\":{\"toolbarCollapse\":\"Thu gọn thanh công cụ\",\"toolbarExpand\":\"Mở rộng thnah công cụ\",\"toolbarGroups\":{\"document\":\"Tài liệu\",\"clipboard\":\"Clipboard/Undo\",\"editing\":\"Chỉnh sửa\",\"forms\":\"Bảng biểu\",\"basicstyles\":\"Kiểu cơ bản\",\"paragraph\":\"Đoạn\",\"links\":\"Liên kết\",\"insert\":\"Chèn\",\"styles\":\"Kiểu\",\"colors\":\"Màu sắc\",\"tools\":\"Công cụ\"},\"toolbars\":\"Thanh công cụ\"},\"elementspath\":{\"eleLabel\":\"Nhãn thành phần\",\"eleTitle\":\"%1 thành phần\"},\"format\":{\"label\":\"Định dạng\",\"panelTitle\":\"Định dạng\",\"tag_address\":\"Address\",\"tag_div\":\"Bình thường (DIV)\",\"tag_h1\":\"Heading 1\",\"tag_h2\":\"Heading 2\",\"tag_h3\":\"Heading 3\",\"tag_h4\":\"Heading 4\",\"tag_h5\":\"Heading 5\",\"tag_h6\":\"Heading 6\",\"tag_p\":\"Bình thường (P)\",\"tag_pre\":\"Đã thiết lập\"},\"horizontalrule\":{\"toolbar\":\"Chèn đường phân cách ngang\"},\"image\":{\"alertUrl\":\"Hãy đưa vào đường dẫn của ảnh\",\"alt\":\"Chú thích ảnh\",\"border\":\"Đường viền\",\"btnUpload\":\"Tải lên máy chủ\",\"button2Img\":\"Bạn có muốn chuyển nút bấm bằng ảnh được chọn thành ảnh?\",\"hSpace\":\"Khoảng đệm ngang\",\"img2Button\":\"Bạn có muốn chuyển đổi ảnh được chọn thành nút bấm bằng ảnh?\",\"infoTab\":\"Thông tin của ảnh\",\"linkTab\":\"Tab liên kết\",\"lockRatio\":\"Giữ nguyên tỷ lệ\",\"menu\":\"Thuộc tính của ảnh\",\"resetSize\":\"Kích thước gốc\",\"title\":\"Thuộc tính của ảnh\",\"titleButton\":\"Thuộc tính nút của ảnh\",\"upload\":\"Tải lên\",\"urlMissing\":\"Thiếu đường dẫn hình ảnh\",\"vSpace\":\"Khoảng đệm dọc\",\"validateBorder\":\"Chiều rộng của đường viền phải là một số nguyên dương\",\"validateHSpace\":\"Khoảng đệm ngang phải là một số nguyên dương\",\"validateVSpace\":\"Khoảng đệm dọc phải là một số nguyên dương\"},\"indent\":{\"indent\":\"Dịch vào trong\",\"outdent\":\"Dịch ra ngoài\"},\"fakeobjects\":{\"anchor\":\"Điểm neo\",\"flash\":\"Flash\",\"hiddenfield\":\"Trường ẩn\",\"iframe\":\"IFrame\",\"unknown\":\"Đối tượng không rõ ràng\"},\"link\":{\"acccessKey\":\"Phím hỗ trợ truy cập\",\"advanced\":\"Mở rộng\",\"advisoryContentType\":\"Nội dung hướng dẫn\",\"advisoryTitle\":\"Nhan đề hướng dẫn\",\"anchor\":{\"toolbar\":\"Chèn/Sửa điểm neo\",\"menu\":\"Thuộc tính điểm neo\",\"title\":\"Thuộc tính điểm neo\",\"name\":\"Tên của điểm neo\",\"errorName\":\"Hãy nhập vào tên của điểm neo\",\"remove\":\"Xóa neo\"},\"anchorId\":\"Theo định danh thành phần\",\"anchorName\":\"Theo tên điểm neo\",\"charset\":\"Bảng mã của tài nguyên được liên kết đến\",\"cssClasses\":\"Lớp Stylesheet\",\"emailAddress\":\"Thư điện tử\",\"emailBody\":\"Nội dung thông điệp\",\"emailSubject\":\"Tiêu đề thông điệp\",\"id\":\"Định danh\",\"info\":\"Thông tin liên kết\",\"langCode\":\"Mã ngôn ngữ\",\"langDir\":\"Hướng ngôn ngữ\",\"langDirLTR\":\"Trái sang phải (LTR)\",\"langDirRTL\":\"Phải sang trái (RTL)\",\"menu\":\"Sửa liên kết\",\"name\":\"Tên\",\"noAnchors\":\"(Không có điểm neo nào trong tài liệu)\",\"noEmail\":\"Hãy đưa vào địa chỉ thư điện tử\",\"noUrl\":\"Hãy đưa vào đường dẫn liên kết (URL)\",\"other\":\"<khác>\",\"popupDependent\":\"Phụ thuộc (Netscape)\",\"popupFeatures\":\"Đặc điểm của cửa sổ Popup\",\"popupFullScreen\":\"Toàn màn hình (IE)\",\"popupLeft\":\"Vị trí bên trái\",\"popupLocationBar\":\"Thanh vị trí\",\"popupMenuBar\":\"Thanh Menu\",\"popupResizable\":\"Có thể thay đổi kích cỡ\",\"popupScrollBars\":\"Thanh cuộn\",\"popupStatusBar\":\"Thanh trạng thái\",\"popupToolbar\":\"Thanh công cụ\",\"popupTop\":\"Vị trí phía trên\",\"rel\":\"Quan hệ\",\"selectAnchor\":\"Chọn một điểm neo\",\"styles\":\"Kiểu (style)\",\"tabIndex\":\"Chỉ số của Tab\",\"target\":\"Đích\",\"targetFrame\":\"<khung>\",\"targetFrameName\":\"Tên khung đích\",\"targetPopup\":\"<cửa sổ popup>\",\"targetPopupName\":\"Tên cửa sổ Popup\",\"title\":\"Liên kết\",\"toAnchor\":\"Neo trong trang này\",\"toEmail\":\"Thư điện tử\",\"toUrl\":\"URL\",\"toolbar\":\"Chèn/Sửa liên kết\",\"type\":\"Kiểu liên kết\",\"unlink\":\"Xoá liên kết\",\"upload\":\"Tải lên\"},\"list\":{\"bulletedlist\":\"Chèn/Xoá Danh sách không thứ tự\",\"numberedlist\":\"Chèn/Xoá Danh sách có thứ tự\"},\"magicline\":{\"title\":\"Chèn đoạn vào đây\"},\"maximize\":{\"maximize\":\"Phóng to tối đa\",\"minimize\":\"Thu nhỏ\"},\"pastetext\":{\"button\":\"Dán theo định dạng văn bản thuần\",\"title\":\"Dán theo định dạng văn bản thuần\"},\"pastefromword\":{\"confirmCleanup\":\"Văn bản bạn muốn dán có kèm định dạng của Word. Bạn có muốn loại bỏ định dạng Word trước khi dán?\",\"error\":\"Không thể để làm sạch các dữ liệu dán do một lỗi nội bộ\",\"title\":\"Dán với định dạng Word\",\"toolbar\":\"Dán với định dạng Word\"},\"removeformat\":{\"toolbar\":\"Xoá định dạng\"},\"sourcearea\":{\"toolbar\":\"Mã HTML\"},\"specialchar\":{\"options\":\"Tùy chọn các ký tự đặc biệt\",\"title\":\"Hãy chọn ký tự đặc biệt\",\"toolbar\":\"Chèn ký tự đặc biệt\"},\"scayt\":{\"about\":\"Thông tin về SCAYT\",\"aboutTab\":\"Thông tin\",\"addWord\":\"Thêm từ\",\"allCaps\":\"Không phân biệt chữ HOA chữ thường\",\"dic_create\":\"Tạo\",\"dic_delete\":\"Xóa\",\"dic_field_name\":\"Tên từ điển\",\"dic_info\":\"Ban đầu, từ điển người dùng được lưu trữ trong một cookie. Tuy nhiên, kích thước cookie bị giới hạn. Khi người sử dụng từ điển phát triển đến điểm không thể được lưu trữ trong cookie, từ điển sẽ được lưu trữ trên máy chủ của chúng tôi. Để lưu trữ từ điển cá nhân của bạn trên máy chủ của chúng tôi, bạn nên xác định một tên cho từ điển của bạn. Nếu bạn đã có một cuốn từ điển được lưu trữ, xin vui lòng gõ tên của nó và nhấn vào nút Khôi phục.\",\"dic_rename\":\"Thay tên\",\"dic_restore\":\"Phục hồi\",\"dictionariesTab\":\"Từ điển\",\"disable\":\"Tắt SCAYT\",\"emptyDic\":\"Tên của từ điển không được để trống.\",\"enable\":\"Bật SCAYT\",\"ignore\":\"Bỏ qua\",\"ignoreAll\":\"Bỏ qua tất cả\",\"ignoreDomainNames\":\"Bỏ qua tên miền\",\"langs\":\"Ngôn ngữ\",\"languagesTab\":\"Tab ngôn ngữ\",\"mixedCase\":\"Không phân biệt loại chữ\",\"mixedWithDigits\":\"Không phân biệt chữ và số\",\"moreSuggestions\":\"Đề xuất thêm\",\"opera_title\":\"Không hỗ trợ trên trình duyệt Opera\",\"options\":\"Tùy chọn\",\"optionsTab\":\"Tùy chọn\",\"title\":\"Kiểm tra chính tả ngay khi gõ chữ (SCAYT)\",\"toggle\":\"Bật tắt SCAYT\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"Kiểu\",\"panelTitle\":\"Phong cách định dạng\",\"panelTitle1\":\"Kiểu khối\",\"panelTitle2\":\"Kiểu trực tiếp\",\"panelTitle3\":\"Kiểu đối tượng\"},\"table\":{\"border\":\"Kích thước đường viền\",\"caption\":\"Đầu đề\",\"cell\":{\"menu\":\"Ô\",\"insertBefore\":\"Chèn ô Phía trước\",\"insertAfter\":\"Chèn ô Phía sau\",\"deleteCell\":\"Xoá ô\",\"merge\":\"Kết hợp ô\",\"mergeRight\":\"Kết hợp sang phải\",\"mergeDown\":\"Kết hợp xuống dưới\",\"splitHorizontal\":\"Phân tách ô theo chiều ngang\",\"splitVertical\":\"Phân tách ô theo chiều dọc\",\"title\":\"Thuộc tính của ô\",\"cellType\":\"Kiểu của ô\",\"rowSpan\":\"Kết hợp hàng\",\"colSpan\":\"Kết hợp cột\",\"wordWrap\":\"Chữ liền hàng\",\"hAlign\":\"Canh lề ngang\",\"vAlign\":\"Canh lề dọc\",\"alignBaseline\":\"Đường cơ sở\",\"bgColor\":\"Màu nền\",\"borderColor\":\"Màu viền\",\"data\":\"Dữ liệu\",\"header\":\"Đầu đề\",\"yes\":\"Có\",\"no\":\"Không\",\"invalidWidth\":\"Chiều rộng của ô phải là một số nguyên.\",\"invalidHeight\":\"Chiều cao của ô phải là một số nguyên.\",\"invalidRowSpan\":\"Số hàng kết hợp phải là một số nguyên.\",\"invalidColSpan\":\"Số cột kết hợp phải là một số nguyên.\",\"chooseColor\":\"Chọn màu\"},\"cellPad\":\"Khoảng đệm giữ ô và nội dung\",\"cellSpace\":\"Khoảng cách giữa các ô\",\"column\":{\"menu\":\"Cột\",\"insertBefore\":\"Chèn cột phía trước\",\"insertAfter\":\"Chèn cột phía sau\",\"deleteColumn\":\"Xoá cột\"},\"columns\":\"Số cột\",\"deleteTable\":\"Xóa bảng\",\"headers\":\"Đầu đề\",\"headersBoth\":\"Cả hai\",\"headersColumn\":\"Cột đầu tiên\",\"headersNone\":\"Không có\",\"headersRow\":\"Hàng đầu tiên\",\"invalidBorder\":\"Kích cỡ của đường biên phải là một số nguyên.\",\"invalidCellPadding\":\"Khoảng đệm giữa ô và nội dung phải là một số nguyên.\",\"invalidCellSpacing\":\"Khoảng cách giữa các ô phải là một số nguyên.\",\"invalidCols\":\"Số lượng cột phải là một số lớn hơn 0.\",\"invalidHeight\":\"Chiều cao của bảng phải là một số nguyên.\",\"invalidRows\":\"Số lượng hàng phải là một số lớn hơn 0.\",\"invalidWidth\":\"Chiều rộng của bảng phải là một số nguyên.\",\"menu\":\"Thuộc tính bảng\",\"row\":{\"menu\":\"Hàng\",\"insertBefore\":\"Chèn hàng phía trước\",\"insertAfter\":\"Chèn hàng phía sau\",\"deleteRow\":\"Xoá hàng\"},\"rows\":\"Số hàng\",\"summary\":\"Tóm lược\",\"title\":\"Thuộc tính bảng\",\"toolbar\":\"Bảng\",\"widthPc\":\"Phần trăm (%)\",\"widthPx\":\"Điểm ảnh (px)\",\"widthUnit\":\"Đơn vị\"},\"undo\":{\"redo\":\"Làm lại thao tác\",\"undo\":\"Khôi phục thao tác\"},\"wsc\":{\"btnIgnore\":\"Bỏ qua\",\"btnIgnoreAll\":\"Bỏ qua tất cả\",\"btnReplace\":\"Thay thế\",\"btnReplaceAll\":\"Thay thế tất cả\",\"btnUndo\":\"Phục hồi lại\",\"changeTo\":\"Chuyển thành\",\"errorLoading\":\"Lỗi khi đang nạp dịch vụ ứng dụng: %s.\",\"ieSpellDownload\":\"Chức năng kiểm tra chính tả chưa được cài đặt. Bạn có muốn tải về ngay bây giờ?\",\"manyChanges\":\"Hoàn tất kiểm tra chính tả: %1 từ đã được thay đổi\",\"noChanges\":\"Hoàn tất kiểm tra chính tả: Không có từ nào được thay đổi\",\"noMispell\":\"Hoàn tất kiểm tra chính tả: Không có lỗi chính tả\",\"noSuggestions\":\"- Không đưa ra gợi ý về từ -\",\"notAvailable\":\"Xin lỗi, dịch vụ này hiện tại không có.\",\"notInDic\":\"Không có trong từ điển\",\"oneChange\":\"Hoàn tất kiểm tra chính tả: Một từ đã được thay đổi\",\"progress\":\"Đang tiến hành kiểm tra chính tả...\",\"title\":\"Kiểm tra chính tả\",\"toolbar\":\"Kiểm tra chính tả\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/zh-cn.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['zh-cn']={\"editor\":\"所见即所得编辑器\",\"editorPanel\":\"所见即所得编辑器面板\",\"common\":{\"editorHelp\":\"按 ALT+0 获得帮助\",\"browseServer\":\"浏览服务器\",\"url\":\"URL\",\"protocol\":\"协议\",\"upload\":\"上传\",\"uploadSubmit\":\"上传到服务器\",\"image\":\"图像\",\"flash\":\"Flash\",\"form\":\"表单\",\"checkbox\":\"复选框\",\"radio\":\"单选按钮\",\"textField\":\"单行文本\",\"textarea\":\"多行文本\",\"hiddenField\":\"隐藏域\",\"button\":\"按钮\",\"select\":\"列表/菜单\",\"imageButton\":\"图像按钮\",\"notSet\":\"<没有设置>\",\"id\":\"ID\",\"name\":\"名称\",\"langDir\":\"语言方向\",\"langDirLtr\":\"从左到右 (LTR)\",\"langDirRtl\":\"从右到左 (RTL)\",\"langCode\":\"语言代码\",\"longDescr\":\"详细说明 URL\",\"cssClass\":\"样式类名称\",\"advisoryTitle\":\"标题\",\"cssStyle\":\"行内样式\",\"ok\":\"确定\",\"cancel\":\"取消\",\"close\":\"关闭\",\"preview\":\"预览\",\"resize\":\"拖拽以改变大小\",\"generalTab\":\"常规\",\"advancedTab\":\"高级\",\"validateNumberFailed\":\"需要输入数字格式\",\"confirmNewPage\":\"当前文档内容未保存，是否确认新建文档？\",\"confirmCancel\":\"部分修改尚未保存，是否确认关闭对话框？\",\"options\":\"选项\",\"target\":\"目标窗口\",\"targetNew\":\"新窗口 (_blank)\",\"targetTop\":\"整页 (_top)\",\"targetSelf\":\"本窗口 (_self)\",\"targetParent\":\"父窗口 (_parent)\",\"langDirLTR\":\"从左到右 (LTR)\",\"langDirRTL\":\"从右到左 (RTL)\",\"styles\":\"样式\",\"cssClasses\":\"样式类\",\"width\":\"宽度\",\"height\":\"高度\",\"align\":\"对齐方式\",\"alignLeft\":\"左对齐\",\"alignRight\":\"右对齐\",\"alignCenter\":\"居中\",\"alignTop\":\"顶端\",\"alignMiddle\":\"居中\",\"alignBottom\":\"底部\",\"invalidValue\":\"无效的值。\",\"invalidHeight\":\"高度必须为数字格式\",\"invalidWidth\":\"宽度必须为数字格式\",\"invalidCssLength\":\"此“%1”字段的值必须为正数，可以包含或不包含一个有效的 CSS 长度单位(px, %, in, cm, mm, em, ex, pt 或 pc)\",\"invalidHtmlLength\":\"此“%1”字段的值必须为正数，可以包含或不包含一个有效的 HTML 长度单位(px 或 %)\",\"invalidInlineStyle\":\"内联样式必须为格式是以分号分隔的一个或多个“属性名 : 属性值”。\",\"cssLengthTooltip\":\"输入一个表示像素值的数字，或加上一个有效的 CSS 长度单位(px, %, in, cm, mm, em, ex, pt 或 pc)。\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">，不可用</span>\"},\"about\":{\"copy\":\"版权所有 &copy; $1。<br />保留所有权利。\",\"dlgTitle\":\"关于 CKEditor\",\"help\":\"访问 $1 以获取帮助。\",\"moreInfo\":\"相关授权许可信息请访问我们的网站：\",\"title\":\"关于 CKEditor\",\"userGuide\":\"CKEditor 用户向导\"},\"basicstyles\":{\"bold\":\"加粗\",\"italic\":\"倾斜\",\"strike\":\"删除线\",\"subscript\":\"下标\",\"superscript\":\"上标\",\"underline\":\"下划线\"},\"blockquote\":{\"toolbar\":\"块引用\"},\"clipboard\":{\"copy\":\"复制\",\"copyError\":\"您的浏览器安全设置不允许编辑器自动执行复制操作，请使用键盘快捷键(Ctrl/Cmd+C)来完成。\",\"cut\":\"剪切\",\"cutError\":\"您的浏览器安全设置不允许编辑器自动执行剪切操作，请使用键盘快捷键(Ctrl/Cmd+X)来完成。\",\"paste\":\"粘贴\",\"pasteArea\":\"粘贴区域\",\"pasteMsg\":\"请使用键盘快捷键(<STRONG>Ctrl/Cmd+V</STRONG>)把内容粘贴到下面的方框里，再按 <STRONG>确定</STRONG>\",\"securityMsg\":\"因为您的浏览器的安全设置原因，本编辑器不能直接访问您的剪贴板内容，你需要在本窗口重新粘贴一次。\",\"title\":\"粘贴\"},\"contextmenu\":{\"options\":\"快捷菜单选项\"},\"toolbar\":{\"toolbarCollapse\":\"折叠工具栏\",\"toolbarExpand\":\"展开工具栏\",\"toolbarGroups\":{\"document\":\"文档\",\"clipboard\":\"剪贴板/撤销\",\"editing\":\"编辑\",\"forms\":\"表单\",\"basicstyles\":\"基本格式\",\"paragraph\":\"段落\",\"links\":\"链接\",\"insert\":\"插入\",\"styles\":\"样式\",\"colors\":\"颜色\",\"tools\":\"工具\"},\"toolbars\":\"工具栏\"},\"elementspath\":{\"eleLabel\":\"元素路径\",\"eleTitle\":\"%1 元素\"},\"format\":{\"label\":\"格式\",\"panelTitle\":\"格式\",\"tag_address\":\"地址\",\"tag_div\":\"段落(DIV)\",\"tag_h1\":\"标题 1\",\"tag_h2\":\"标题 2\",\"tag_h3\":\"标题 3\",\"tag_h4\":\"标题 4\",\"tag_h5\":\"标题 5\",\"tag_h6\":\"标题 6\",\"tag_p\":\"普通\",\"tag_pre\":\"已编排格式\"},\"horizontalrule\":{\"toolbar\":\"插入水平线\"},\"image\":{\"alertUrl\":\"请输入图像地址\",\"alt\":\"替换文本\",\"border\":\"边框大小\",\"btnUpload\":\"上传到服务器\",\"button2Img\":\"确定要把当前图像按钮转换为普通图像吗？\",\"hSpace\":\"水平间距\",\"img2Button\":\"确定要把当前图像改变为图像按钮吗？\",\"infoTab\":\"图像信息\",\"linkTab\":\"链接\",\"lockRatio\":\"锁定比例\",\"menu\":\"图像属性\",\"resetSize\":\"原始尺寸\",\"title\":\"图像属性\",\"titleButton\":\"图像域属性\",\"upload\":\"上传\",\"urlMissing\":\"缺少图像源文件地址\",\"vSpace\":\"垂直间距\",\"validateBorder\":\"边框大小必须为整数格式\",\"validateHSpace\":\"水平间距必须为整数格式\",\"validateVSpace\":\"垂直间距必须为整数格式\"},\"indent\":{\"indent\":\"增加缩进量\",\"outdent\":\"减少缩进量\"},\"fakeobjects\":{\"anchor\":\"锚点\",\"flash\":\"Flash 动画\",\"hiddenfield\":\"隐藏域\",\"iframe\":\"IFrame\",\"unknown\":\"未知对象\"},\"link\":{\"acccessKey\":\"访问键\",\"advanced\":\"高级\",\"advisoryContentType\":\"内容类型\",\"advisoryTitle\":\"标题\",\"anchor\":{\"toolbar\":\"插入/编辑锚点链接\",\"menu\":\"锚点链接属性\",\"title\":\"锚点链接属性\",\"name\":\"锚点名称\",\"errorName\":\"请输入锚点名称\",\"remove\":\"删除锚点\"},\"anchorId\":\"按锚点 ID\",\"anchorName\":\"按锚点名称\",\"charset\":\"字符编码\",\"cssClasses\":\"样式类名称\",\"emailAddress\":\"地址\",\"emailBody\":\"内容\",\"emailSubject\":\"主题\",\"id\":\"ID\",\"info\":\"超链接信息\",\"langCode\":\"语言代码\",\"langDir\":\"语言方向\",\"langDirLTR\":\"从左到右 (LTR)\",\"langDirRTL\":\"从右到左 (RTL)\",\"menu\":\"编辑超链接\",\"name\":\"名称\",\"noAnchors\":\"(此文档没有可用的锚点)\",\"noEmail\":\"请输入电子邮件地址\",\"noUrl\":\"请输入超链接地址\",\"other\":\"<其他>\",\"popupDependent\":\"依附 (NS)\",\"popupFeatures\":\"弹出窗口属性\",\"popupFullScreen\":\"全屏 (IE)\",\"popupLeft\":\"左\",\"popupLocationBar\":\"地址栏\",\"popupMenuBar\":\"菜单栏\",\"popupResizable\":\"可缩放\",\"popupScrollBars\":\"滚动条\",\"popupStatusBar\":\"状态栏\",\"popupToolbar\":\"工具栏\",\"popupTop\":\"右\",\"rel\":\"关联\",\"selectAnchor\":\"选择一个锚点\",\"styles\":\"行内样式\",\"tabIndex\":\"Tab 键次序\",\"target\":\"目标\",\"targetFrame\":\"<框架>\",\"targetFrameName\":\"目标框架名称\",\"targetPopup\":\"<弹出窗口>\",\"targetPopupName\":\"弹出窗口名称\",\"title\":\"超链接\",\"toAnchor\":\"页内锚点链接\",\"toEmail\":\"电子邮件\",\"toUrl\":\"地址\",\"toolbar\":\"插入/编辑超链接\",\"type\":\"超链接类型\",\"unlink\":\"取消超链接\",\"upload\":\"上传\"},\"list\":{\"bulletedlist\":\"项目列表\",\"numberedlist\":\"编号列表\"},\"magicline\":{\"title\":\"在这插入段落\"},\"maximize\":{\"maximize\":\"全屏\",\"minimize\":\"最小化\"},\"pastetext\":{\"button\":\"粘贴为无格式文本\",\"title\":\"粘贴为无格式文本\"},\"pastefromword\":{\"confirmCleanup\":\"您要粘贴的内容好像是来自 MS Word，是否要清除 MS Word 格式后再粘贴？\",\"error\":\"由于内部错误无法清理要粘贴的数据\",\"title\":\"从 MS Word 粘贴\",\"toolbar\":\"从 MS Word 粘贴\"},\"removeformat\":{\"toolbar\":\"清除格式\"},\"sourcearea\":{\"toolbar\":\"源码\"},\"specialchar\":{\"options\":\"特殊符号选项\",\"title\":\"选择特殊符号\",\"toolbar\":\"插入特殊符号\"},\"scayt\":{\"about\":\"关于即时拼写检查\",\"aboutTab\":\"关于\",\"addWord\":\"添加单词\",\"allCaps\":\"忽略所有大写单词\",\"dic_create\":\"创建\",\"dic_delete\":\"删除\",\"dic_field_name\":\"字典名称\",\"dic_info\":\"一开始用户词典储存在 Cookie 中, 但是 Cookies 的容量是有限的, 当用户词典增长到超出 Cookie 限制时就无法再储存了, 这时您可以将词典储存到我们的服务器上. 要把您的个人词典到储存到我们的服务器上的话, 需要为您的词典指定一个名称, 如果您在我们的服务器上已经有储存有一个词典, 请输入词典名称并按还原按钮.\",\"dic_rename\":\"重命名\",\"dic_restore\":\"还原\",\"dictionariesTab\":\"字典\",\"disable\":\"禁用即时拼写检查\",\"emptyDic\":\"字典名不应为空.\",\"enable\":\"启用即时拼写检查\",\"ignore\":\"忽略\",\"ignoreAll\":\"全部忽略\",\"ignoreDomainNames\":\"忽略域名\",\"langs\":\"语言\",\"languagesTab\":\"语言\",\"mixedCase\":\"忽略大小写混合的单词\",\"mixedWithDigits\":\"忽略带数字的单词\",\"moreSuggestions\":\"更多拼写建议\",\"opera_title\":\"不支持 Opera 浏览器\",\"options\":\"选项\",\"optionsTab\":\"选项\",\"title\":\"即时拼写检查\",\"toggle\":\"暂停/启用即时拼写检查\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"样式\",\"panelTitle\":\"样式\",\"panelTitle1\":\"块级元素样式\",\"panelTitle2\":\"内联元素样式\",\"panelTitle3\":\"对象元素样式\"},\"table\":{\"border\":\"边框\",\"caption\":\"标题\",\"cell\":{\"menu\":\"单元格\",\"insertBefore\":\"在左侧插入单元格\",\"insertAfter\":\"在右侧插入单元格\",\"deleteCell\":\"删除单元格\",\"merge\":\"合并单元格\",\"mergeRight\":\"向右合并单元格\",\"mergeDown\":\"向下合并单元格\",\"splitHorizontal\":\"水平拆分单元格\",\"splitVertical\":\"垂直拆分单元格\",\"title\":\"单元格属性\",\"cellType\":\"单元格类型\",\"rowSpan\":\"纵跨行数\",\"colSpan\":\"横跨列数\",\"wordWrap\":\"自动换行\",\"hAlign\":\"水平对齐\",\"vAlign\":\"垂直对齐\",\"alignBaseline\":\"基线\",\"bgColor\":\"背景颜色\",\"borderColor\":\"边框颜色\",\"data\":\"数据\",\"header\":\"表头\",\"yes\":\"是\",\"no\":\"否\",\"invalidWidth\":\"单元格宽度必须为数字格式\",\"invalidHeight\":\"单元格高度必须为数字格式\",\"invalidRowSpan\":\"行跨度必须为整数格式\",\"invalidColSpan\":\"列跨度必须为整数格式\",\"chooseColor\":\"选择\"},\"cellPad\":\"边距\",\"cellSpace\":\"间距\",\"column\":{\"menu\":\"列\",\"insertBefore\":\"在左侧插入列\",\"insertAfter\":\"在右侧插入列\",\"deleteColumn\":\"删除列\"},\"columns\":\"列数\",\"deleteTable\":\"删除表格\",\"headers\":\"标题单元格\",\"headersBoth\":\"第一列和第一行\",\"headersColumn\":\"第一列\",\"headersNone\":\"无\",\"headersRow\":\"第一行\",\"invalidBorder\":\"边框粗细必须为数字格式\",\"invalidCellPadding\":\"单元格填充必须为数字格式\",\"invalidCellSpacing\":\"单元格间距必须为数字格式\",\"invalidCols\":\"指定的行数必须大于零\",\"invalidHeight\":\"表格高度必须为数字格式\",\"invalidRows\":\"指定的列数必须大于零\",\"invalidWidth\":\"表格宽度必须为数字格式\",\"menu\":\"表格属性\",\"row\":{\"menu\":\"行\",\"insertBefore\":\"在上方插入行\",\"insertAfter\":\"在下方插入行\",\"deleteRow\":\"删除行\"},\"rows\":\"行数\",\"summary\":\"摘要\",\"title\":\"表格属性\",\"toolbar\":\"表格\",\"widthPc\":\"百分比\",\"widthPx\":\"像素\",\"widthUnit\":\"宽度单位\"},\"undo\":{\"redo\":\"重做\",\"undo\":\"撤消\"},\"wsc\":{\"btnIgnore\":\"忽略\",\"btnIgnoreAll\":\"全部忽略\",\"btnReplace\":\"替换\",\"btnReplaceAll\":\"全部替换\",\"btnUndo\":\"撤消\",\"changeTo\":\"更改为\",\"errorLoading\":\"加载应该服务主机时出错: %s.\",\"ieSpellDownload\":\"拼写检查插件还没安装, 您是否想现在就下载?\",\"manyChanges\":\"拼写检查完成: 更改了 %1 个单词\",\"noChanges\":\"拼写检查完成: 没有更改任何单词\",\"noMispell\":\"拼写检查完成: 没有发现拼写错误\",\"noSuggestions\":\"- 没有建议 -\",\"notAvailable\":\"抱歉, 服务目前暂不可用\",\"notInDic\":\"没有在字典里\",\"oneChange\":\"拼写检查完成: 更改了一个单词\",\"progress\":\"正在进行拼写检查...\",\"title\":\"拼写检查\",\"toolbar\":\"拼写检查\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/lang/zh.js",
    "content": "﻿/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.lang['zh']={\"editor\":\"RTF 編輯器\",\"editorPanel\":\"RTF 編輯器面板\",\"common\":{\"editorHelp\":\"按下 ALT 0 取得說明。\",\"browseServer\":\"瀏覽伺服器\",\"url\":\"URL\",\"protocol\":\"通訊協定\",\"upload\":\"上傳\",\"uploadSubmit\":\"傳送至伺服器\",\"image\":\"圖片\",\"flash\":\"Flash\",\"form\":\"表格\",\"checkbox\":\"核取方塊\",\"radio\":\"選項按鈕\",\"textField\":\"文字欄位\",\"textarea\":\"文字區域\",\"hiddenField\":\"隱藏欄位\",\"button\":\"按鈕\",\"select\":\"選取欄位\",\"imageButton\":\"影像按鈕\",\"notSet\":\"<未設定>\",\"id\":\"ID\",\"name\":\"名稱\",\"langDir\":\"語言方向\",\"langDirLtr\":\"從左至右 (LTR)\",\"langDirRtl\":\"從右至左 (RTL)\",\"langCode\":\"語言代碼\",\"longDescr\":\"完整描述 URL\",\"cssClass\":\"樣式表類別\",\"advisoryTitle\":\"標題\",\"cssStyle\":\"樣式\",\"ok\":\"確定\",\"cancel\":\"取消\",\"close\":\"關閉\",\"preview\":\"預覽\",\"resize\":\"調整大小\",\"generalTab\":\"一般\",\"advancedTab\":\"進階\",\"validateNumberFailed\":\"此值不是數值。\",\"confirmNewPage\":\"現存的修改尚未儲存，要開新檔案？\",\"confirmCancel\":\"部份選項尚未儲存，要關閉對話框？\",\"options\":\"選項\",\"target\":\"目標\",\"targetNew\":\"開新視窗 (_blank)\",\"targetTop\":\"最上層視窗 (_top)\",\"targetSelf\":\"相同視窗 (_self)\",\"targetParent\":\"父視窗 (_parent)\",\"langDirLTR\":\"由左至右 (LTR)\",\"langDirRTL\":\"由右至左 (RTL)\",\"styles\":\"樣式\",\"cssClasses\":\"樣式表類別\",\"width\":\"寬度\",\"height\":\"高度\",\"align\":\"對齊方式\",\"alignLeft\":\"靠左對齊\",\"alignRight\":\"靠右對齊\",\"alignCenter\":\"置中對齊\",\"alignTop\":\"頂端\",\"alignMiddle\":\"中間對齊\",\"alignBottom\":\"底端\",\"invalidValue\":\"無效值。\",\"invalidHeight\":\"高度必須為數字。\",\"invalidWidth\":\"寬度必須為數字。\",\"invalidCssLength\":\"「%1」的值應為正數，並可包含有效的 CSS 單位 (px, %, in, cm, mm, em, ex, pt, 或 pc)。\",\"invalidHtmlLength\":\"「%1」的值應為正數，並可包含有效的 HTML 單位 (px 或 %)。\",\"invalidInlineStyle\":\"行內樣式的值應包含一個以上的變數值組，其格式如「名稱:值」，並以分號區隔之。\",\"cssLengthTooltip\":\"請輸入數值，單位是像素或有效的 CSS 單位 (px, %, in, cm, mm, em, ex, pt, 或 pc)。\",\"unavailable\":\"%1<span class=\\\"cke_accessibility\\\">，無法使用</span>\"},\"about\":{\"copy\":\"Copyright &copy; $1. All rights reserved.\",\"dlgTitle\":\"關於 CKEditor\",\"help\":\"檢閱 $1 尋求幫助。\",\"moreInfo\":\"關於授權資訊，請參閱我們的網站：\",\"title\":\"關於 CKEditor\",\"userGuide\":\"CKEditor 使用者手冊\"},\"basicstyles\":{\"bold\":\"粗體\",\"italic\":\"斜體\",\"strike\":\"刪除線\",\"subscript\":\"下標\",\"superscript\":\"上標\",\"underline\":\"底線\"},\"blockquote\":{\"toolbar\":\"引用段落\"},\"clipboard\":{\"copy\":\"複製\",\"copyError\":\"瀏覽器的安全性設定不允許編輯器自動執行複製動作。請使用鍵盤快捷鍵 (Ctrl/Cmd+C) 複製。\",\"cut\":\"剪下\",\"cutError\":\"瀏覽器的安全性設定不允許編輯器自動執行剪下動作。請使用鏐盤快捷鍵 (Ctrl/Cmd+X) 剪下。\",\"paste\":\"貼上\",\"pasteArea\":\"貼上區\",\"pasteMsg\":\"請使用鍵盤快捷鍵 (<strong>Ctrl/Cmd+V</strong>) 貼到下方區域中並按下「確定」。\",\"securityMsg\":\"因為瀏覽器的安全性設定，本編輯器無法直接存取您的剪貼簿資料，請您自行在本視窗進行貼上動作。\",\"title\":\"貼上\"},\"contextmenu\":{\"options\":\"內容功能表選項\"},\"toolbar\":{\"toolbarCollapse\":\"摺疊工具列\",\"toolbarExpand\":\"展開工具列\",\"toolbarGroups\":{\"document\":\"文件\",\"clipboard\":\"剪貼簿/復原\",\"editing\":\"編輯選項\",\"forms\":\"格式\",\"basicstyles\":\"基本樣式\",\"paragraph\":\"段落\",\"links\":\"連結\",\"insert\":\"插入\",\"styles\":\"樣式\",\"colors\":\"顏色\",\"tools\":\"工具\"},\"toolbars\":\"編輯器工具列\"},\"elementspath\":{\"eleLabel\":\"元件路徑\",\"eleTitle\":\"%1 個元件\"},\"format\":{\"label\":\"格式\",\"panelTitle\":\"段落格式\",\"tag_address\":\"地址\",\"tag_div\":\"標準 (DIV)\",\"tag_h1\":\"標題 1\",\"tag_h2\":\"標題 2\",\"tag_h3\":\"標題 3\",\"tag_h4\":\"標題 4\",\"tag_h5\":\"標題 5\",\"tag_h6\":\"標題 6\",\"tag_p\":\"標準\",\"tag_pre\":\"格式設定\"},\"horizontalrule\":{\"toolbar\":\"插入水平線\"},\"image\":{\"alertUrl\":\"請輸入圖片 URL\",\"alt\":\"替代文字\",\"border\":\"框線\",\"btnUpload\":\"傳送到伺服器\",\"button2Img\":\"請問您確定要將「圖片按鈕」轉換成「圖片」嗎？\",\"hSpace\":\"HSpace\",\"img2Button\":\"請問您確定要將「圖片」轉換成「圖片按鈕」嗎？\",\"infoTab\":\"影像資訊\",\"linkTab\":\"連結\",\"lockRatio\":\"固定比例\",\"menu\":\"影像屬性\",\"resetSize\":\"重設大小\",\"title\":\"影像屬性\",\"titleButton\":\"影像按鈕屬性\",\"upload\":\"上傳\",\"urlMissing\":\"遺失圖片來源之 URL \",\"vSpace\":\"VSpace\",\"validateBorder\":\"框線必須是整數。\",\"validateHSpace\":\"HSpace 必須是整數。\",\"validateVSpace\":\"VSpace 必須是整數。\"},\"indent\":{\"indent\":\"增加縮排\",\"outdent\":\"減少縮排\"},\"fakeobjects\":{\"anchor\":\"錨點\",\"flash\":\"Flash 動畫\",\"hiddenfield\":\"隱藏欄位\",\"iframe\":\"IFrame\",\"unknown\":\"無法辨識的物件\"},\"link\":{\"acccessKey\":\"便捷鍵\",\"advanced\":\"進階\",\"advisoryContentType\":\"建議內容類型\",\"advisoryTitle\":\"標題\",\"anchor\":{\"toolbar\":\"錨點\",\"menu\":\"編輯錨點\",\"title\":\"錨點內容\",\"name\":\"錨點名稱\",\"errorName\":\"請輸入錨點名稱\",\"remove\":\"移除錨點\"},\"anchorId\":\"依元件編號\",\"anchorName\":\"依錨點名稱\",\"charset\":\"連結資源的字元集\",\"cssClasses\":\"樣式表類別\",\"emailAddress\":\"電子郵件地址\",\"emailBody\":\"郵件本文\",\"emailSubject\":\"郵件主旨\",\"id\":\"ID\",\"info\":\"連結資訊\",\"langCode\":\"語言碼\",\"langDir\":\"語言方向\",\"langDirLTR\":\"由左至右 (LTR)\",\"langDirRTL\":\"由右至左 (RTL)\",\"menu\":\"編輯連結\",\"name\":\"名稱\",\"noAnchors\":\"(本文件中無可用之錨點)\",\"noEmail\":\"請輸入電子郵件\",\"noUrl\":\"請輸入連結 URL\",\"other\":\"<其他>\",\"popupDependent\":\"獨立 (Netscape)\",\"popupFeatures\":\"快顯視窗功能\",\"popupFullScreen\":\"全螢幕 (IE)\",\"popupLeft\":\"左側位置\",\"popupLocationBar\":\"位置列\",\"popupMenuBar\":\"功能表列\",\"popupResizable\":\"可調大小\",\"popupScrollBars\":\"捲軸\",\"popupStatusBar\":\"狀態列\",\"popupToolbar\":\"工具列\",\"popupTop\":\"頂端位置\",\"rel\":\"關係\",\"selectAnchor\":\"選取一個錨點\",\"styles\":\"樣式\",\"tabIndex\":\"定位順序\",\"target\":\"目標\",\"targetFrame\":\"<框架>\",\"targetFrameName\":\"目標框架名稱\",\"targetPopup\":\"<快顯視窗>\",\"targetPopupName\":\"快顯視窗名稱\",\"title\":\"連結\",\"toAnchor\":\"文字中的錨點連結\",\"toEmail\":\"電子郵件\",\"toUrl\":\"網址\",\"toolbar\":\"連結\",\"type\":\"連結類型\",\"unlink\":\"取消連結\",\"upload\":\"上傳\"},\"list\":{\"bulletedlist\":\"插入/移除項目符號清單\",\"numberedlist\":\"插入/移除編號清單清單\"},\"magicline\":{\"title\":\"在此插入段落\"},\"maximize\":{\"maximize\":\"最大化\",\"minimize\":\"最小化\"},\"pastetext\":{\"button\":\"貼成純文字\",\"title\":\"貼成純文字\"},\"pastefromword\":{\"confirmCleanup\":\"您想貼上的文字似乎是自 Word 複製而來，請問您是否要先清除 Word 的格式後再行貼上？\",\"error\":\"由於發生內部錯誤，無法清除清除 Word 的格式。\",\"title\":\"自 Word 貼上\",\"toolbar\":\"自 Word 貼上\"},\"removeformat\":{\"toolbar\":\"移除格式\"},\"sourcearea\":{\"toolbar\":\"原始碼\"},\"specialchar\":{\"options\":\"特殊字元選項\",\"title\":\"選取特殊字元\",\"toolbar\":\"插入特殊字元\"},\"scayt\":{\"about\":\"關於即時拼寫檢查\",\"aboutTab\":\"關於\",\"addWord\":\"添加單詞\",\"allCaps\":\"Ignore All-Caps Words\",\"dic_create\":\"Create\",\"dic_delete\":\"Delete\",\"dic_field_name\":\"Dictionary name\",\"dic_info\":\"Initially the User Dictionary is stored in a Cookie. However, Cookies are limited in size. When the User Dictionary grows to a point where it cannot be stored in a Cookie, then the dictionary may be stored on our server. To store your personal dictionary on our server you should specify a name for your dictionary. If you already have a stored dictionary, please type its name and click the Restore button.\",\"dic_rename\":\"Rename\",\"dic_restore\":\"Restore\",\"dictionariesTab\":\"字典\",\"disable\":\"關閉即時拼寫檢查\",\"emptyDic\":\"字典名不應為空.\",\"enable\":\"啟用即時拼寫檢查\",\"ignore\":\"忽略\",\"ignoreAll\":\"全部忽略\",\"ignoreDomainNames\":\"Ignore Domain Names\",\"langs\":\"語言\",\"languagesTab\":\"語言\",\"mixedCase\":\"Ignore Words with Mixed Case\",\"mixedWithDigits\":\"Ignore Words with Numbers\",\"moreSuggestions\":\"更多拼寫建議\",\"opera_title\":\"Not supported by Opera\",\"options\":\"選項\",\"optionsTab\":\"選項\",\"title\":\"即時拼寫檢查\",\"toggle\":\"啟用／關閉即時拼寫檢查\",\"noSuggestions\":\"No suggestion\"},\"stylescombo\":{\"label\":\"樣式\",\"panelTitle\":\"Formatting Styles\",\"panelTitle1\":\"區塊樣式\",\"panelTitle2\":\"內嵌樣式\",\"panelTitle3\":\"物件樣式\"},\"table\":{\"border\":\"框線大小\",\"caption\":\"標題\",\"cell\":{\"menu\":\"儲存格\",\"insertBefore\":\"前方插入儲存格\",\"insertAfter\":\"後方插入儲存格\",\"deleteCell\":\"刪除儲存格\",\"merge\":\"合併儲存格\",\"mergeRight\":\"向右合併\",\"mergeDown\":\"向下合併\",\"splitHorizontal\":\"水平分割儲存格\",\"splitVertical\":\"垂直分割儲存格\",\"title\":\"儲存格屬性\",\"cellType\":\"儲存格類型\",\"rowSpan\":\"Rows Span\",\"colSpan\":\"Columns Span\",\"wordWrap\":\"自動斷行\",\"hAlign\":\"水平對齊\",\"vAlign\":\"垂直對齊\",\"alignBaseline\":\"基準線\",\"bgColor\":\"背景顏色\",\"borderColor\":\"框線顏色\",\"data\":\"資料\",\"header\":\"Header\",\"yes\":\"是\",\"no\":\"否\",\"invalidWidth\":\"儲存格寬度必須為數字。\",\"invalidHeight\":\"儲存格高度必須為數字。\",\"invalidRowSpan\":\"Rows span must be a whole number.\",\"invalidColSpan\":\"Columns span must be a whole number.\",\"chooseColor\":\"選擇\"},\"cellPad\":\"Cell padding\",\"cellSpace\":\"Cell spacing\",\"column\":{\"menu\":\"行\",\"insertBefore\":\"Insert Column Before\",\"insertAfter\":\"Insert Column After\",\"deleteColumn\":\"Delete Columns\"},\"columns\":\"行\",\"deleteTable\":\"Delete Table\",\"headers\":\"Headers\",\"headersBoth\":\"Both\",\"headersColumn\":\"First column\",\"headersNone\":\"無\",\"headersRow\":\"First Row\",\"invalidBorder\":\"框線大小必須是整數。\",\"invalidCellPadding\":\"Cell padding must be a positive number.\",\"invalidCellSpacing\":\"Cell spacing must be a positive number.\",\"invalidCols\":\"Number of columns must be a number greater than 0.\",\"invalidHeight\":\"Table height must be a number.\",\"invalidRows\":\"Number of rows must be a number greater than 0.\",\"invalidWidth\":\"Table width must be a number.\",\"menu\":\"Table Properties\",\"row\":{\"menu\":\"列\",\"insertBefore\":\"Insert Row Before\",\"insertAfter\":\"Insert Row After\",\"deleteRow\":\"Delete Rows\"},\"rows\":\"列\",\"summary\":\"Summary\",\"title\":\"Table Properties\",\"toolbar\":\"Table\",\"widthPc\":\"百分比\",\"widthPx\":\"像素\",\"widthUnit\":\"寬度單位\"},\"undo\":{\"redo\":\"取消復原\",\"undo\":\"復原\"},\"wsc\":{\"btnIgnore\":\"忽略\",\"btnIgnoreAll\":\"全部忽略\",\"btnReplace\":\"取代\",\"btnReplaceAll\":\"全部取代\",\"btnUndo\":\"復原\",\"changeTo\":\"更改為\",\"errorLoading\":\"無法聯系侍服器: %s.\",\"ieSpellDownload\":\"尚未安裝拼字檢查元件。您是否想要現在下載？\",\"manyChanges\":\"拼字檢查完成：更改了 %1 個單字\",\"noChanges\":\"拼字檢查完成：未更改任何單字\",\"noMispell\":\"拼字檢查完成：未發現拼字錯誤\",\"noSuggestions\":\"- 無建議值 -\",\"notAvailable\":\"抱歉，服務目前暫不可用\",\"notInDic\":\"不在字典中\",\"oneChange\":\"拼字檢查完成：更改了 1 個單字\",\"progress\":\"進行拼字檢查中…\",\"title\":\"拼字檢查\",\"toolbar\":\"拼字檢查\"}};"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/a11yhelp.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.dialog.add(\"a11yHelp\",function(j){var l=j.lang.a11yhelp,m=CKEDITOR.tools.getNextId(),d={8:\"BACKSPACE\",9:\"TAB\",13:\"ENTER\",16:\"SHIFT\",17:\"CTRL\",18:\"ALT\",19:\"PAUSE\",20:\"CAPSLOCK\",27:\"ESCAPE\",33:\"PAGE UP\",34:\"PAGE DOWN\",35:\"END\",36:\"HOME\",37:\"LEFT ARROW\",38:\"UP ARROW\",39:\"RIGHT ARROW\",40:\"DOWN ARROW\",45:\"INSERT\",46:\"DELETE\",91:\"LEFT WINDOW KEY\",92:\"RIGHT WINDOW KEY\",93:\"SELECT KEY\",96:\"NUMPAD  0\",97:\"NUMPAD  1\",98:\"NUMPAD  2\",99:\"NUMPAD  3\",100:\"NUMPAD  4\",101:\"NUMPAD  5\",102:\"NUMPAD  6\",103:\"NUMPAD  7\",\n104:\"NUMPAD  8\",105:\"NUMPAD  9\",106:\"MULTIPLY\",107:\"ADD\",109:\"SUBTRACT\",110:\"DECIMAL POINT\",111:\"DIVIDE\",112:\"F1\",113:\"F2\",114:\"F3\",115:\"F4\",116:\"F5\",117:\"F6\",118:\"F7\",119:\"F8\",120:\"F9\",121:\"F10\",122:\"F11\",123:\"F12\",144:\"NUM LOCK\",145:\"SCROLL LOCK\",186:\"SEMI-COLON\",187:\"EQUAL SIGN\",188:\"COMMA\",189:\"DASH\",190:\"PERIOD\",191:\"FORWARD SLASH\",192:\"GRAVE ACCENT\",219:\"OPEN BRACKET\",220:\"BACK SLASH\",221:\"CLOSE BRAKET\",222:\"SINGLE QUOTE\"};d[CKEDITOR.ALT]=\"ALT\";d[CKEDITOR.SHIFT]=\"SHIFT\";d[CKEDITOR.CTRL]=\"CTRL\";\nvar e=[CKEDITOR.ALT,CKEDITOR.SHIFT,CKEDITOR.CTRL],n=/\\$\\{(.*?)\\}/g,q=function(){var o=j.keystrokeHandler.keystrokes,f={},b;for(b in o)f[o[b]]=b;return function(b,g){var a;if(f[g]){a=f[g];for(var h,i,k=[],c=0;c<e.length;c++)i=e[c],h=a/e[c],1<h&&2>=h&&(a-=i,k.push(d[i]));k.push(d[a]||String.fromCharCode(a));a=k.join(\"+\")}else a=b;return a}}();return{title:l.title,minWidth:600,minHeight:400,contents:[{id:\"info\",label:j.lang.common.generalTab,expand:!0,elements:[{type:\"html\",id:\"legends\",style:\"white-space:normal;\",\nfocus:function(){this.getElement().focus()},html:function(){for(var d='<div class=\"cke_accessibility_legend\" role=\"document\" aria-labelledby=\"'+m+'_arialbl\" tabIndex=\"-1\">%1</div><span id=\"'+m+'_arialbl\" class=\"cke_voice_label\">'+l.contents+\" </span>\",f=[],b=l.legend,j=b.length,g=0;g<j;g++){for(var a=b[g],h=[],i=a.items,k=i.length,c=0;c<k;c++){var e=i[c],p=e.legend.replace(n,q);p.match(n)||h.push(\"<dt>%1</dt><dd>%2</dd>\".replace(\"%1\",e.name).replace(\"%2\",p))}f.push(\"<h1>%1</h1><dl>%2</dl>\".replace(\"%1\",\na.name).replace(\"%2\",h.join(\"\")))}return d.replace(\"%1\",f.join(\"\"))}()+'<style type=\"text/css\">.cke_accessibility_legend{width:600px;height:400px;padding-right:5px;overflow-y:auto;overflow-x:hidden;}.cke_browser_quirks .cke_accessibility_legend,.cke_browser_ie6 .cke_accessibility_legend{height:390px}.cke_accessibility_legend *{white-space:normal;}.cke_accessibility_legend h1{font-size: 20px;border-bottom: 1px solid #AAA;margin: 5px 0px 15px;}.cke_accessibility_legend dl{margin-left: 5px;}.cke_accessibility_legend dt{font-size: 13px;font-weight: bold;}.cke_accessibility_legend dd{margin:10px}</style>'}]}],\nbuttons:[CKEDITOR.dialog.cancelButton]}});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/_translationstatus.txt",
    "content": "Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n\ncs.js      Found: 30 Missing: 0\ncy.js      Found: 30 Missing: 0\nda.js      Found: 12 Missing: 18\nde.js      Found: 30 Missing: 0\nel.js      Found: 25 Missing: 5\neo.js      Found: 30 Missing: 0\nfa.js      Found: 30 Missing: 0\nfi.js      Found: 30 Missing: 0\nfr.js      Found: 30 Missing: 0\ngu.js      Found: 12 Missing: 18\nhe.js      Found: 30 Missing: 0\nit.js      Found: 30 Missing: 0\nmk.js      Found: 5 Missing: 25\nnb.js      Found: 30 Missing: 0\nnl.js      Found: 30 Missing: 0\nno.js      Found: 30 Missing: 0\npt-br.js   Found: 30 Missing: 0\nro.js      Found: 6 Missing: 24\ntr.js      Found: 30 Missing: 0\nug.js      Found: 27 Missing: 3\nvi.js      Found: 6 Missing: 24\nzh-cn.js   Found: 30 Missing: 0\n"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ar.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"ar\",{title:\"Accessibility Instructions\",contents:\"Help Contents. To close this dialog press ESC.\",legend:[{name:\"عام\",items:[{name:\"Editor Toolbar\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Editor Dialog\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Commands\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/bg.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"bg\",{title:\"Accessibility Instructions\",contents:\"Help Contents. To close this dialog press ESC.\",legend:[{name:\"Общо\",items:[{name:\"Editor Toolbar\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Editor Dialog\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Commands\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ca.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"ca\",{title:\"Instruccions d'Accessibilitat\",contents:\"Continguts de l'Ajuda. Per tancar aquest quadre de diàleg premi ESC.\",legend:[{name:\"General\",items:[{name:\"Editor de barra d'eines\",legend:\"Premi ${toolbarFocus} per desplaçar-se per la barra d'eines. Vagi en el següent i anterior grup de barra d'eines amb TAB i SHIFT-TAB. Vagi en el següent i anterior botó de la barra d'eines amb RIGHT ARROW i LEFT ARROW. Premi SPACE o ENTER per activar el botó de la barra d'eines.\"},\n{name:\"Editor de quadre de diàleg\",legend:\"Dins d'un quadre de diàleg, premi la tecla TAB per desplaçar-se al següent camp del quadre de diàleg, premi SHIFT + TAB per desplaçar-se a l'anterior camp, premi ENTER per acceptar el quadre de diàleg, premi ESC per cancel·lar el quadre de diàleg. Per els quadres de diàleg que tenen diverses pestanyes, premi ALT + F10 per anar a la llista de pestanyes. Després podrà desplaçar-se a la següent pestanya amb TAB o RIGHT ARROW. Anar a la pestanya anterior amb SHIFT + TAB o LEFT ARROW. Premi SPACE o ENTER per seleccionar la pestanya.\"},\n{name:\"Editor de menú contextual\",legend:\"Premi ${contextMenu} o APPLICATION KEY per obrir el menú contextual. Després desplacis a la següent opció del menú amb TAB o DOWN ARROW. Desplacis a l'anterior opció amb SHIFT+TAB o UP ARROW. Premi SPACE o ENTER per seleccionar l'opció del menú. Obri el submenú de l'actual opció utilitzant SPACE o ENTER o RIGHT ARROW. Pot tornar a l'opció del menú pare amb ESC o LEFT ARROW. Tanqui el menú contextual amb ESC.\"},{name:\"Editor de caixa de llista\",legend:\"Dins d'un quadre de llista, desplacis al següent element de la llista amb TAB o DOWN ARROW. Desplacis a l'anterior element de la llista amb SHIFT + TAB o UP ARROW. Premi SPACE o ENTER per seleccionar l'opció de la llista. Premi ESC per tancar el quadre de llista.\"},\n{name:\"Editor de barra de ruta de l'element\",legend:\"Premi ${elementsPathFocus} per anar als elements de la barra de ruta. Desplacis al botó de l'element següent amb TAB o RIGHT ARROW. Desplacis a l'anterior botó amb  SHIFT+TAB o LEFT ARROW. Premi SPACE o ENTER per seleccionar l'element a l'editor.\"}]},{name:\"Ordres\",items:[{name:\"Desfer ordre\",legend:\"Premi ${undo}\"},{name:\"Refer ordre\",legend:\"Premi ${redo}\"},{name:\"Ordre negreta\",legend:\"Premi ${bold}\"},{name:\"Ordre cursiva\",legend:\"Premi ${italic}\"},\n{name:\"Ordre subratllat\",legend:\"Premi ${underline}\"},{name:\"Ordre enllaç\",legend:\"Premi ${link}\"},{name:\"Ordre amagar barra d'eines\",legend:\"Premi ${toolbarCollapse}\"},{name:\"Ordre per accedir a l'anterior espai enfocat\",legend:\"Premi ${accessPreviousSpace} per accedir a l'enfocament d'espai més proper inabastable abans del símbol d'intercalació, per exemple: dos elements HR adjacents. Repetiu la combinació de tecles per arribar a enfocaments d'espais distants.\"},{name:\"Ordre per accedir al següent espai enfocat\",\nlegend:\"Premi ${accessNextSpace} per accedir a l'enfocament d'espai més proper inabastable després del símbol d'intercalació, per exemple: dos elements HR adjacents. Repetiu la combinació de tecles per arribar a enfocaments d'espais distants.\"},{name:\"Ajuda d'accessibilitat\",legend:\"Premi ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/cs.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"cs\",{title:\"Instrukce pro přístupnost\",contents:\"Obsah nápovědy. Pro uzavření tohoto dialogu stiskněte klávesu ESC.\",legend:[{name:\"Obecné\",items:[{name:\"Panel nástrojů editoru\",legend:\"Stiskněte${toolbarFocus} k procházení panelu nástrojů. Přejděte na další a předchozí skupiny pomocí TAB a SHIFT-TAB. Přechod na další a předchozí tlačítko panelu nástrojů je pomocí ŠIPKA VPRAVO nebo ŠIPKA VLEVO. Stisknutím mezerníku nebo klávesy ENTER tlačítko aktivujete.\"},{name:\"Dialogové okno editoru\",\nlegend:\"Uvnitř dialogového okna stiskněte TAB pro přesunutí na další pole, stiskněte SHIFT + TAB pro přesun na předchozí pole, stiskněte ENTER pro odeslání dialogu, stiskněte ESC pro jeho zrušení. Pro dialogová okna, která mají mnoho karet stiskněte ALT + F10 pr oprocházení seznamu karet. Pak se přesuňte na další kartu pomocí TAB nebo ŠIPKA VPRAVO. Pro přesun na předchozí stiskněte SHIFT + TAB nebo ŠIPKA VLEVO. Stiskněte MEZERNÍK nebo ENTER pro vybrání stránky karet.\"},{name:\"Kontextové menu editoru\",\nlegend:\"Stiskněte ${contextMenu} nebo klávesu APPLICATION k otevření kontextového menu. Pak se přesuňte na další možnost menu pomocí TAB nebo ŠIPKY DOLŮ. Přesuňte se na předchozí možnost pomocí  SHIFT+TAB nebo ŠIPKY NAHORU. Stiskněte MEZERNÍK nebo ENTER pro zvolení možnosti menu. Podmenu současné možnosti otevřete pomocí MEZERNÍKU nebo ENTER či ŠIPKY DOLEVA. Kontextové menu uzavřete stiskem ESC.\"},{name:\"Rámeček seznamu editoru\",legend:\"Uvnitř rámečku seznamu se přesunete na další položku menu pomocí TAB nebo ŠIPKA DOLŮ. Na předchozí položku se přesunete SHIFT + TAB nebo ŠIPKA NAHORU. Stiskněte MEZERNÍK nebo ENTER pro zvolení možnosti seznamu. Stiskněte ESC pro uzavření seznamu.\"},\n{name:\"Lišta cesty prvku v editoru\",legend:\"Stiskněte ${elementsPathFocus} pro procházení lišty cesty prvku. Na další tlačítko prvku se přesunete pomocí TAB nebo ŠIPKA VPRAVO. Na předchozí položku se přesunete pomocí SHIFT + TAB nebo ŠIPKA VLEVO. Stiskněte MEZERNÍK nebo ENTER pro vybrání prvku v editoru.\"}]},{name:\"Příkazy\",items:[{name:\" Příkaz Zpět\",legend:\"Stiskněte ${undo}\"},{name:\" Příkaz Znovu\",legend:\"Stiskněte ${redo}\"},{name:\" Příkaz Tučné\",legend:\"Stiskněte ${bold}\"},{name:\" Příkaz Kurzíva\",\nlegend:\"Stiskněte ${italic}\"},{name:\" Příkaz Podtržení\",legend:\"Stiskněte ${underline}\"},{name:\" Příkaz Odkaz\",legend:\"Stiskněte ${link}\"},{name:\" Příkaz Skrýt panel nástrojů\",legend:\"Stiskněte ${toolbarCollapse}\"},{name:\"Příkaz pro přístup k předchozímu prostoru zaměření\",legend:\"Stiskněte ${accessPreviousSpace} pro přístup k nejbližšímu nedosažitelnému prostoru zaměření před stříškou, například: dva přilehlé prvky HR. Pro dosažení vzdálených prostorů zaměření tuto kombinaci kláves opakujte.\"},{name:\"Příkaz pro přístup k dalšímu prostoru zaměření\",\nlegend:\"Stiskněte ${accessNextSpace} pro přístup k nejbližšímu nedosažitelnému prostoru zaměření po stříšce, například: dva přilehlé prvky HR. Pro dosažení vzdálených prostorů zaměření tuto kombinaci kláves opakujte.\"},{name:\" Nápověda přístupnosti\",legend:\"Stiskněte ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/cy.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"cy\",{title:\"Canllawiau Hygyrchedd\",contents:\"Cynnwys Cymorth. I gau y deialog hwn, pwyswch ESC.\",legend:[{name:\"Cyffredinol\",items:[{name:\"Bar Offer y Golygydd\",legend:\"Pwyswch $ {toolbarFocus} i fynd at y bar offer. Symudwch i'r grŵp bar offer nesaf a blaenorol gyda TAB a SHIFT-TAB. Symudwch i'r botwm bar offer nesaf a blaenorol gyda SAETH DDE neu SAETH CHWITH. Pwyswch SPACE neu ENTER i wneud botwm y bar offer yn weithredol.\"},{name:\"Deialog y Golygydd\",legend:\"Tu mewn i'r deialog, pwyswch TAB i fynd i'r maes nesaf ar y deialog, pwyswch SHIFT + TAB i symud i faes blaenorol, pwyswch ENTER i gyflwyno'r deialog, pwyswch ESC i ddiddymu'r deialog. Ar gyfer deialogau sydd â thudalennau aml-tab, pwyswch ALT + F10 i lywio'r tab-restr. Yna symudwch i'r tab nesaf gyda TAB neu SAETH DDE. Symudwch i dab blaenorol gyda SHIFT + TAB neu'r SAETH CHWITH. Pwyswch SPACE neu ENTER i ddewis y dudalen tab.\"},\n{name:\"Dewislen Cyd-destun y Golygydd\",legend:\"Pwyswch $ {contextMenu} neu'r ALLWEDD 'APPLICATION' i agor y ddewislen cyd-destun. Yna symudwch i'r opsiwn ddewislen nesaf gyda'r TAB neu'r SAETH I LAWR. Symudwch i'r opsiwn blaenorol gyda SHIFT + TAB neu'r SAETH I FYNY. Pwyswch SPACE neu ENTER i ddewis yr opsiwn ddewislen. Agorwch is-dewislen yr opsiwn cyfredol gyda SPACE neu ENTER neu SAETH DDE. Ewch yn ôl i'r eitem ar y ddewislen uwch gydag ESC neu SAETH CHWITH. Ceuwch y ddewislen cyd-destun gydag ESC.\"},\n{name:\"Blwch Rhestr y Golygydd\",legend:\"Tu mewn y blwch rhestr, ewch i'r eitem rhestr nesaf gyda TAB neu'r SAETH I LAWR. Symudwch i restr eitem flaenorol gyda SHIFT + TAB neu SAETH I FYNY. Pwyswch SPACE neu ENTER i ddewis yr opsiwn o'r rhestr. Pwyswch ESC i gau'r rhestr.\"},{name:\"Bar Llwybr Elfen y Golygydd\",legend:\"Pwyswch ${elementsPathFocus} i fynd i'r bar llwybr elfennau. Symudwch i fotwm yr elfen nesaf gyda TAB neu SAETH DDE. Symudwch i fotwm blaenorol gyda SHIFT + TAB neu SAETH CHWITH. Pwyswch SPACE neu ENTER i ddewis yr elfen yn y golygydd.\"}]},\n{name:\"Gorchmynion\",items:[{name:\"Gorchymyn dadwneud\",legend:\"Pwyswch ${undo}\"},{name:\"Gorchymyn ailadrodd\",legend:\"Pwyswch ${redo}\"},{name:\"Gorchymyn Bras\",legend:\"Pwyswch ${bold}\"},{name:\"Gorchymyn italig\",legend:\"Pwyswch ${italig}\"},{name:\"Gorchymyn tanlinellu\",legend:\"Pwyso ${underline}\"},{name:\"Gorchymyn dolen\",legend:\"Pwyswch ${link}\"},{name:\"Gorchymyn Cwympo'r Dewislen\",legend:\"Pwyswch ${toolbarCollapse}\"},{name:\"Myned i orchymyn bwlch ffocws blaenorol\",legend:\"Pwyswch ${accessPreviousSpace} i fyned i'r \\\"blwch ffocws sydd methu ei gyrraedd\\\" cyn y caret, er enghraifft: dwy elfen HR drws nesaf i'w gilydd. AIladroddwch y cyfuniad allwedd i gyrraedd bylchau ffocws pell.\"},\n{name:\"Ewch i'r gorchymyn blwch ffocws nesaf\",legend:\"Pwyswch ${accessNextSpace} i fyned i'r blwch ffocws agosaf nad oes modd ei gyrraedd ar ôl y caret, er enghraifft: dwy elfen HR drws nesaf i'w gilydd. Ailadroddwch y cyfuniad allwedd i gyrraedd blychau ffocws pell.\"},{name:\"Cymorth Hygyrchedd\",legend:\"Pwyswch ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/da.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"da\",{title:\"Tilgængelighedsinstrukser\",contents:\"Onlinehjælp. For at lukke dette vindue klik ESC\",legend:[{name:\"Generelt\",items:[{name:\"Editor værktøjslinje\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Editor Dialog\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Kommandoer\",items:[{name:\"Fortryd kommando\",legend:\"Klik på ${undo}\"},{name:\"Gentag kommando\",legend:\"Klik ${redo}\"},{name:\" Bold command\",legend:\"Klik ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Klik ${underline}\"},{name:\" Link command\",legend:\"Klik ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Kilk ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/de.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"de\",{title:\"Barrierefreiheitinformationen\",contents:\"Hilfeinhalt. Um den Dialog zu schliessen die Taste 'ESC' drücken.\",legend:[{name:\"Allgemein\",items:[{name:\"Editor Symbolleiste\",legend:\"Drücken Sie ${toolbarFocus} auf der Symbolleiste. Gehen Sie zur nächsten oder vorherigen Symbolleistengruppe mit TAB und SHIFT-TAB. Gehen Sie zur nächsten oder vorherigen Symbolleiste auf die Schaltfläche mit dem RECHTS- oder LINKS-Pfeil. Drücken Sie die Leertaste oder Eingabetaste, um die Schaltfläche in der Symbolleiste aktivieren.\"},\n{name:\"Editor Dialog\",legend:\"Innerhalb des Dialogs drücken Sie TAB um zum nächsten Dialogfeld zu gelangen, drücken Sie SHIFT-TAG um zum vorherigen Feld zu wechseln, drücken Sie ENTER um den Dialog abzusenden und ESC um den Dialog zu abzubrechen. Um zwischen den Reitern innerhalb eines Dialogs zu wechseln drücken sie ALT-F10. Um zum nächsten Reiter zu gelangen können Sie TAB oder die rechte Pfeiltaste. Zurück gelangt man mit SHIFT-TAB oder der linken Pfeiltaste. Mit der Leertaste oder Enter kann man den Reiter auswählen.\"},\n{name:\"Editor Kontextmenü\",legend:\"Dürcken Sie ${contextMenu} oder die Anwendungstaste um das Kontextmenü zu öffnen. Man kann die Pfeiltasten zum Wechsel benutzen. Mit der Leertaste oder der Enter-Taste kann man den Menüpunkt aufrufen. Schliessen Sie das Kontextmenü mit der ESC-Taste.\"},{name:\"Editor Listen\",legend:\"Innerhalb einer Listenbox kann man mit der TAB-Taste oder den Pfeilrunter-Taste den nächsten Menüeintrag wählen. Mit der Shift-TAB Tastenkombination oder der Pfeilhoch-Taste gelangt man zum vorherigen Menüpunkt. Mit der Leertaste oder Enter kann man den Menüpunkt auswählen. Drücken Sie ESC zum Verlassen des Menüs.\"},\n{name:\"Editor Elementpfadleiste\",legend:\"Drücken Sie ${elementsPathFocus} um sich durch die Pfadleiste zu bewegen. Um zum nächsten Element zu gelangen drücken Sie TAB oder die Pfeilrechts-Taste. Zum vorherigen Element gelangen Sie mit der SHIFT-TAB oder der Pfeillinks-Taste. Drücken Sie die Leertaste oder Enter um das Element auszuwählen.\"}]},{name:\"Befehle\",items:[{name:\"Wiederholen Befehl\",legend:\"Drücken Sie ${undo}\"},{name:\"Rückgängig Befehl\",legend:\"Drücken Sie ${redo}\"},{name:\"Fettschrift Befehl\",\nlegend:\"Drücken Sie ${bold}\"},{name:\"Italic Befehl\",legend:\"Drücken Sie ${italic}\"},{name:\"Unterstreichung Befehl\",legend:\"Drücken Sie ${underline}\"},{name:\"Link Befehl\",legend:\"Drücken Sie ${link}\"},{name:\"Symbolleiste zuammenklappen Befehl\",legend:\"Drücken Sie ${toolbarCollapse}\"},{name:\"Zugang bisheriger Fokussierung Raumbefehl \",legend:\"Drücken Sie ${accessPreviousSpace}  auf den am nächsten nicht erreichbar Fokus-Abstand vor die Einfügemarke zugreifen: zwei benachbarte HR-Elemente. Wiederholen Sie die Tastenkombination um entfernte Fokusräume zu erreichen. \"},\n{name:\"Zugang nächster Schwerpunkt Raumbefehl \",legend:\"Drücken Sie $ { accessNextSpace }, um den nächsten unerreichbar Fokus Leerzeichen nach dem Cursor zum Beispiel auf: zwei benachbarten HR Elemente. Wiederholen Sie die Tastenkombination zum fernen Fokus Bereiche zu erreichen. \"},{name:\"Eingabehilfen\",legend:\"Drücken Sie ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/el.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"el\",{title:\"Οδηγίες Προσβασιμότητας\",contents:\"Περιεχόμενα Βοήθειας. Πατήστε ESC για κλείσιμο.\",legend:[{name:\"Γενικά\",items:[{name:\"Εργαλειοθήκη Επεξεργαστή\",legend:\"Πατήστε ${toolbarFocus} για να περιηγηθείτε στην γραμμή εργαλείων. Μετακινηθείτε ανάμεσα στις ομάδες της γραμμής εργαλείων με TAB και SHIFT-TAB. Μετακινηθείτε ανάμεσα στα κουμπιά εργαλείων με το ΔΕΞΙ ή ΑΡΙΣΤΕΡΟ ΒΕΛΑΚΙ. Πατήστε ΔΙΑΣΤΗΜΑ ή ENTER για να ενεργοποιήσετε το ενεργό κουμπί εργαλείου.\"},{name:\"Παράθυρο Διαλόγου Επεξεργαστή\",\nlegend:\"Μέσα σε ένα παράθυρο διαλόγου, πατήστε TAB για να μεταβείτε στο επόμενο πεδίο ή SHIFT + TAB για να μεταβείτε στο προηγούμενο. Πατήστε ENTER για να υποβάλετε την φόρμα. Πατήστε ESC για να ακυρώσετε την διαδικασία της φόρμας. Για παράθυρα διαλόγων που έχουν πολλές σελίδες σε καρτέλες πατήστε ALT + F10 για να μεταβείτε στην λίστα των καρτελών. Στην συνέχεια μπορείτε να μεταβείτε στην επόμενη καρτέλα πατώντας το TAB ή το ΔΕΞΙ ΒΕΛΑΚΙ. Μπορείτε να μεταβείτε στην προηγούμενη καρτέλα πατώντας SHIFT + TAB ή το ΑΡΙΣΤΕΡΟ ΒΕΛΑΚΙ. Πατήστε ΔΙΑΣΤΗΜΑ ή ENTER για να επιλέξτε την καρτέλα για προβολή.\"},\n{name:\"Αναδυόμενο Μενού Επεξεργαστή\",legend:\"Πατήστε ${contextMenu} ή APPLICATION KEY για να ανοίξετε το αναδυόμενο μενού. Μετά μετακινηθείτε στην επόμενη επιλογή του μενού με  TAB ή ΚΑΤΩ ΒΕΛΑΚΙ. Μετακινηθείτε στην προηγούμενη επιλογή με SHIFT+TAB ή το ΠΑΝΩ ΒΕΛΑΚΙ. Πατήστε ΔΙΑΣΤΗΜΑ ή ENTER για να επιλέξτε το τρέχων στοιχείο. Ανοίξτε το αναδυόμενο μενού της τρέχουσας επιλογής με ΔΙΑΣΤΗΜΑ ή ENTER ή το ΔΕΞΙ ΒΕΛΑΚΙ. Μεταβείτε πίσω στο αρχικό στοιχείο μενού με το ESC ή το ΑΡΙΣΤΕΡΟ ΒΕΛΑΚΙ. Κλείστε το αναδυόμενο μενού με ESC.\"},\n{name:\"Κουτί Λίστας Επεξεργαστών\",legend:\"Μέσα σε ένα κουτί λίστας, μετακινηθείτε στο επόμενο στοιχείο με TAB ή ΚΑΤΩ ΒΕΛΑΚΙ. Μετακινηθείτε στο προηγούμενο στοιχείο με SHIFT + TAB ή το ΠΑΝΩ ΒΕΛΑΚΙ. Πατήστε ΔΙΑΣΤΗΜΑ ή ENTER για να επιλέξετε ένα στοιχείο. Πατήστε ESC για να κλείσετε το κουτί της λίστας.\"},{name:\"Μπάρα Διαδρομών Στοιχείων Επεξεργαστή\",legend:\"Πατήστε ${elementsPathFocus} για να περιηγηθείτε στην μπάρα διαδρομών στοιχείων του επεξεργαστή. Μετακινηθείτε στο κουμπί του επόμενου στοιχείου με το TAB ή το ΔΕΞΙ ΒΕΛΑΚΙ. Μετακινηθείτε στο κουμπί του προηγούμενου στοιχείου με το SHIFT+TAB ή το ΑΡΙΣΤΕΡΟ ΒΕΛΑΚΙ. Πατήστε ΔΙΑΣΤΗΜΑ ή ENTER για να επιλέξετε το στοιχείο στον επεξεργαστή.\"}]},\n{name:\"Εντολές\",items:[{name:\"Εντολή αναίρεσης\",legend:\"Πατήστε ${undo}\"},{name:\"Εντολή επανάληψης\",legend:\"Πατήστε ${redo}\"},{name:\"Εντολή έντονης γραφής\",legend:\"Πατήστε ${bold}\"},{name:\"Εντολή πλάγιας γραφής\",legend:\"Πατήστε ${italic}\"},{name:\"Εντολή υπογράμμισης\",legend:\"Πατήστε ${underline}\"},{name:\"Εντολή συνδέσμου\",legend:\"Πατήστε ${link}\"},{name:\"Εντολή Σύμπτηξης Εργαλειοθήκης\",legend:\"Πατήστε ${toolbarCollapse}\"},{name:\"Πρόσβαση στην προηγούμενη εντολή του χώρου εστίασης \",legend:\"Πατήστε ${accessPreviousSpace} για να έχετε πρόσβαση στον πιο κοντινό χώρο εστίασης πριν το δρομέα, για παράδειγμα: δύο παρακείμενα στοιχεία ΥΕ. Επαναλάβετε το συνδυασμό πλήκτρων για να φθάσετε στους χώρους μακρινής εστίασης. \"},\n{name:\"Πρόσβαση στην επόμενη εντολή του χώρου εστίασης\",legend:\"Πατήστε ${accessNextSpace} για να έχετε πρόσβαση στον πιο κοντινό χώρο εστίασης μετά το δρομέα, για παράδειγμα: δύο παρακείμενα στοιχεία ΥΕ. Επαναλάβετε το συνδυασμό πλήκτρων για τους χώρους μακρινής εστίασης. \"},{name:\"Βοήθεια Προσβασιμότητας\",legend:\"Πατήστε ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/en.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"en\",{title:\"Accessibility Instructions\",contents:\"Help Contents. To close this dialog press ESC.\",legend:[{name:\"General\",items:[{name:\"Editor Toolbar\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Editor Dialog\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Commands\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/eo.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"eo\",{title:\"Uzindikoj pri atingeblo\",contents:\"Helpilenhavo. Por fermi tiun dialogon, premu la ESKAPAN klavon.\",legend:[{name:\"Ĝeneralaĵoj\",items:[{name:\"Ilbreto de la redaktilo\",legend:\"Premu ${toolbarFocus} por atingi la ilbreton. Moviĝu al la sekva aŭ antaŭa grupoj de la ilbreto per la klavoj TABA kaj MAJUSKLIGA-TABA. Moviĝu al la sekva aŭ antaŭa butonoj de la ilbreto per la klavoj SAGO DEKSTREN kaj SAGO MALDEKSTREN. Premu la SPACETklavon aŭ la ENENklavon por aktivigi la ilbretbutonon.\"},\n{name:\"Redaktildialogo\",legend:\"En dialogo, premu la TABAN klavon por navigi al la sekva dialogkampo, premu la MAJUSKLIGAN + TABAN klavojn por reveni al la antaŭa kampo, premu la ENENklavon por sendi la dialogon, premu la ESKAPAN klavon por nuligi la dialogon. Por dialogoj kun pluraj retpaĝoj sub langetoj, premu ALT + F10 por navigi al la langetlisto. Poste moviĝu al la sekva langeto per la klavo TABA aŭ SAGO DEKSTREN. Moviĝu al la antaŭa langeto per la klavoj MAJUSKLIGA + TABA aŭ  SAGO MALDEKSTREN. Premu la SPACETklavon aŭ la ENENklavon por selekti la langetretpaĝon.\"},\n{name:\"Kunteksta menuo de la redaktilo\",legend:\"Premu ${contextMenu} aŭ entajpu la KLAVKOMBINAĴON por malfermi la kuntekstan menuon. Poste moviĝu al la sekva opcio de la menuo per la klavoj TABA aŭ SAGO SUBEN. Moviĝu al la antaŭa opcio per la klavoj MAJUSKLGA + TABA aŭ SAGO SUPREN. Premu la SPACETklavon aŭ ENENklavon por selekti la menuopcion. Malfermu la submenuon de la kuranta opcio per la SPACETklavo aŭ la ENENklavo aŭ la SAGO DEKSTREN. Revenu al la elemento de la patra menuo per la klavoj ESKAPA aŭ SAGO MALDEKSTREN. Fermu la kuntekstan menuon per la ESKAPA klavo.\"},\n{name:\"Fallisto de la redaktilo\",legend:\"En fallisto, moviĝu al la sekva listelemento per la klavoj TABA aŭ SAGO SUBEN. Moviĝu al la antaŭa listelemento per la klavoj MAJUSKLIGA + TABA aŭ SAGO SUPREN. Premu la SPACETklavon aŭ ENENklavon por selekti la opcion en la listo. Premu la ESKAPAN klavon por fermi la falmenuon.\"},{name:\"Breto indikanta la vojon al la redaktilelementoj\",legend:\"Premu ${elementsPathFocus} por navigi al la breto indikanta la vojon al la redaktilelementoj. Moviĝu al la butono de la sekva elemento per la klavoj TABA aŭ SAGO DEKSTREN. Moviĝu al la butono de la antaŭa elemento per la klavoj MAJUSKLIGA + TABA aŭ SAGO MALDEKSTREN. Premu la SPACETklavon aŭ ENENklavon por selekti la elementon en la redaktilo.\"}]},\n{name:\"Komandoj\",items:[{name:\"Komando malfari\",legend:\"Premu ${undo}\"},{name:\"Komando refari\",legend:\"Premu ${redo}\"},{name:\"Komando grasa\",legend:\"Premu ${bold}\"},{name:\"Komando kursiva\",legend:\"Premu ${italic}\"},{name:\"Komando substreki\",legend:\"Premu ${underline}\"},{name:\"Komando ligilo\",legend:\"Premu ${link}\"},{name:\"Komando faldi la ilbreton\",legend:\"Premu ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\"Helpilo pri atingeblo\",legend:\"Premu ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/es.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"es\",{title:\"Instrucciones de accesibilidad\",contents:\"Ayuda. Para cerrar presione ESC.\",legend:[{name:\"General\",items:[{name:\"Barra de herramientas del editor\",legend:'Presiona ${toolbarFocus} para navegar por la barra de herramientas. Para moverse por los distintos grupos de herramientas usa las teclas TAB y MAY-TAB. Para moverse por las distintas herramientas usa FLECHA DERECHA o FECHA IZQUIERDA. Presiona \"espacio\" o \"intro\" para activar la herramienta.'},{name:\"Editor de diálogo\",\nlegend:\"Dentro de un cuadro de diálogo, presione la tecla TAB para desplazarse al campo siguiente del cuadro de diálogo, pulse SHIFT + TAB para desplazarse al campo anterior, pulse ENTER para presentar cuadro de diálogo, pulse la tecla ESC para cancelar el diálogo. Para los diálogos que tienen varias páginas, presione ALT + F10 para navegar a la pestaña de la lista. Luego pasar a la siguiente pestaña con TAB o FLECHA DERECHA. Para ir a la ficha anterior con SHIFT + TAB o FLECHA IZQUIERDA. Presione ESPACIO o ENTRAR para seleccionar la página de ficha.\"},\n{name:\"Editor del menú contextual\",legend:\"Presiona ${contextMenu} o TECLA MENÚ para abrir el menú contextual. Entonces muévete a la siguiente opción del menú con TAB o FLECHA ABAJO. Muévete a la opción previa con SHIFT + TAB o FLECHA ARRIBA. Presiona ESPACIO o ENTER para seleccionar la opción del menú. Abre el submenú de la opción actual con ESPACIO o ENTER o FLECHA DERECHA. Regresa al elemento padre del menú con ESC o FLECHA IZQUIERDA. Cierra el menú contextual con ESC.\"},{name:\"Lista del Editor\",\nlegend:\"Dentro de una lista, te mueves al siguiente elemento de la lista con TAB o FLECHA ABAJO. Te mueves al elemento previo de la lista con SHIFT + TAB o FLECHA ARRIBA. Presiona ESPACIO o ENTER para elegir la opción de la lista. Presiona ESC para cerrar la lista.\"},{name:\"Barra de Ruta del Elemento en el Editor\",legend:\"Presiona ${elementsPathFocus} para navegar a los elementos de la barra de ruta. Te mueves al siguiente elemento botón con TAB o FLECHA DERECHA. Te mueves al botón previo con SHIFT + TAB o FLECHA IZQUIERDA. Presiona ESPACIO o ENTER para seleccionar el elemento en el editor.\"}]},\n{name:\"Comandos\",items:[{name:\"Comando deshacer\",legend:\"Presiona ${undo}\"},{name:\"Comando rehacer\",legend:\"Presiona ${redo}\"},{name:\"Comando negrita\",legend:\"Presiona ${bold}\"},{name:\"Comando itálica\",legend:\"Presiona ${italic}\"},{name:\"Comando subrayar\",legend:\"Presiona ${underline}\"},{name:\"Comando liga\",legend:\"Presiona ${liga}\"},{name:\"Comando colapsar barra de herramientas\",legend:\"Presiona ${toolbarCollapse}\"},{name:\"Comando accesar el anterior espacio de foco\",legend:\"Presiona ${accessPreviousSpace} para accesar el espacio de foco no disponible más cercano anterior al cursor, por ejemplo: dos elementos HR adyacentes. Repite la combinación de teclas para alcanzar espacios de foco distantes.\"},\n{name:\"Comando accesar el siguiente spacio de foco\",legend:\"Presiona ${accessNextSpace} para accesar el espacio de foco no disponible más cercano después del cursor, por ejemplo: dos elementos HR adyacentes. Repite la combinación de teclas para alcanzar espacios de foco distantes.\"},{name:\"Ayuda de Accesibilidad\",legend:\"Presiona ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/et.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"et\",{title:\"Accessibility Instructions\",contents:\"Abi sisu. Selle dialoogi sulgemiseks vajuta ESC klahvi.\",legend:[{name:\"Üldine\",items:[{name:\"Editor Toolbar\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Editor Dialog\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Commands\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/fa.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"fa\",{title:\"دستورالعمل‌های دسترسی\",contents:\"راهنمای فهرست مطالب. برای بستن این کادر محاوره‌ای ESC را فشار دهید.\",legend:[{name:\"عمومی\",items:[{name:\"نوار ابزار ویرایشگر\",legend:\"${toolbarFocus} را برای باز کردن نوار ابزار بفشارید. با کلید Tab و Shif-Tab در مجموعه نوار ابزار بعدی و قبلی حرکت کنید. برای حرکت در کلید نوار ابزار قبلی و بعدی با کلید جهت‌نمای راست و چپ جابجا شوید. کلید Space یا Enter را برای فعال کردن کلید نوار ابزار بفشارید.\"},{name:\"پنجره محاورهای ویرایشگر\",\nlegend:\"در داخل یک پنجره محاورهای، کلید Tab را بفشارید تا به پنجرهی بعدی بروید، Shift+Tab برای حرکت به فیلد قبلی، فشردن Enter برای ثبت اطلاعات پنجره، فشردن Esc برای لغو پنجره محاورهای و برای پنجرههایی که چندین برگه دارند، فشردن Alt+F10 جهت رفتن به Tab-List. در نهایت حرکت به برگه بعدی با Tab یا کلید جهتنمای راست. حرکت به برگه قبلی با Shift+Tab یا کلید جهتنمای چپ. فشردن Space یا Enter برای انتخاب یک برگه.\"},{name:\"منوی متنی ویرایشگر\",legend:\"${contextMenu} یا کلید برنامههای کاربردی را برای باز کردن منوی متن را بفشارید. سپس میتوانید برای حرکت به گزینه بعدی منو با کلید Tab و یا کلید جهتنمای پایین جابجا شوید. حرکت به گزینه قبلی با Shift+Tab یا کلید جهتنمای بالا. فشردن Space یا Enter برای انتخاب یک گزینه از منو. باز کردن زیر شاخه گزینه منو جاری با کلید Space یا Enter و یا کلید جهتنمای راست و چپ. بازگشت به منوی والد با کلید Esc یا کلید جهتنمای چپ. بستن منوی متن با Esc.\"},\n{name:\"جعبه فهرست ویرایشگر\",legend:\"در داخل جعبه لیست، قلم دوم از اقلام لیست بعدی را با TAB و یا Arrow Down حرکت دهید. انتقال به قلم دوم از اقلام لیست قبلی را با SHIFT + TAB یا UP ARROW. کلید Space یا ENTER را برای انتخاب گزینه لیست بفشارید. کلید ESC را برای بستن جعبه لیست بفشارید.\"},{name:\"ویرایشگر عنصر نوار راه\",legend:\"برای رفتن به مسیر عناصر ${elementsPathFocus} را بفشارید. حرکت به کلید عنصر بعدی با کلید Tab یا  کلید جهت‌نمای راست. برگشت به کلید قبلی با Shift+Tab یا کلید جهت‌نمای چپ. فشردن Space یا Enter برای انتخاب یک عنصر در ویرایشگر.\"}]},\n{name:\"فرمان‌ها\",items:[{name:\"بازگشت به آخرین فرمان\",legend:\"فشردن ${undo}\"},{name:\"انجام مجدد فرمان\",legend:\"فشردن ${redo}\"},{name:\"فرمان درشت کردن متن\",legend:\"فشردن ${bold}\"},{name:\"فرمان کج کردن متن\",legend:\"فشردن ${italic}\"},{name:\"فرمان زیرخطدار کردن متن\",legend:\"فشردن ${underline}\"},{name:\"فرمان پیوند دادن\",legend:\"فشردن ${link}\"},{name:\"بستن نوار ابزار فرمان\",legend:\"فشردن ${toolbarCollapse}\"},{name:\"دسترسی به فرمان محل تمرکز قبلی\",legend:\"فشردن ${accessPreviousSpace} برای دسترسی به نزدیک‌ترین فضای قابل دسترسی تمرکز قبل از هشتک، برای مثال: دو عنصر مجاور HR -خط افقی-. تکرار کلید ترکیبی برای رسیدن به فضاهای تمرکز از راه دور.\"},\n{name:\"دسترسی به فضای دستور بعدی\",legend:\"برای دسترسی به نزدیک‌ترین فضای تمرکز غیر قابل دسترس، ${accessNextSpace} را پس از علامت هشتک بفشارید، برای مثال:  دو عنصر مجاور HR -خط افقی-. کلید ترکیبی را برای رسیدن به فضای تمرکز تکرار کنید.\"},{name:\"راهنمای دسترسی\",legend:\"فشردن ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/fi.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"fi\",{title:\"Saavutettavuus ohjeet\",contents:\"Ohjeen sisällöt. Sulkeaksesi tämän dialogin paina ESC.\",legend:[{name:\"Yleinen\",items:[{name:\"Editorin työkalupalkki\",legend:\"Paina ${toolbarFocus} siirtyäksesi työkalupalkkiin. Siirry seuraavaan ja edelliseen työkalupalkin ryhmään TAB ja SHIFT-TAB näppäimillä. Siirry seuraavaan ja edelliseen työkalupainikkeeseen käyttämällä NUOLI OIKEALLE tai NUOLI VASEMMALLE näppäimillä. Paina VÄLILYÖNTI tai ENTER näppäintä aktivoidaksesi työkalupainikkeen.\"},\n{name:\"Editorin dialogi\",legend:\"Dialogin sisällä, painamalla TAB siirryt seuraavaan dialogin kenttään, painamalla SHIFT+TAB siirryt aiempaan kenttään, painamalla ENTER lähetät dialogin, painamalla ESC peruutat dialogin. Dialogeille joissa on useita välilehtiä, paina ALT+F10 siirtyäksesi välillehtilistaan. Siirtyäksesi seuraavaan välilehteen paina TAB tai NUOLI OIKEALLE. Siirry edelliseen välilehteen painamalla SHIFT+TAB tai nuoli vasemmalle. Paina VÄLILYÖNTI tai ENTER valitaksesi välilehden.\"},{name:\"Editorin oheisvalikko\",\nlegend:\"Paina ${contextMenu} tai SOVELLUSPAINIKETTA avataksesi oheisvalikon. Liiku seuraavaan valikon vaihtoehtoon TAB tai NUOLI ALAS näppäimillä. Siirry edelliseen vaihtoehtoon SHIFT+TAB tai NUOLI YLÖS näppäimillä. Paina VÄLILYÖNTI tai ENTER valitaksesi valikon kohdan. Avataksesi nykyisen kohdan alivalikon paina VÄLILYÖNTI tai ENTER tai NUOLI OIKEALLE painiketta. Siirtyäksesi takaisin valikon ylemmälle tasolle paina ESC tai NUOLI vasemmalle. Oheisvalikko suljetaan ESC painikkeella.\"},{name:\"Editorin listalaatikko\",\nlegend:\"Listalaatikon sisällä siirry seuraavaan listan kohtaan TAB tai NUOLI ALAS painikkeilla. Siirry edelliseen listan kohtaan SHIFT+TAB tai NUOLI YLÖS painikkeilla. Paina VÄLILYÖNTI tai ENTER valitaksesi listan vaihtoehdon. Paina ESC sulkeaksesi listalaatikon.\"},{name:\"Editorin elementtipolun palkki\",legend:\"Paina ${elementsPathFocus} siirtyäksesi elementtipolun palkkiin. Siirry seuraavaan elementtipainikkeeseen TAB tai NUOLI OIKEALLE painikkeilla. Siirry aiempaan painikkeeseen SHIFT+TAB tai NUOLI VASEMMALLE painikkeilla. Paina VÄLILYÖNTI tai ENTER valitaksesi elementin editorissa.\"}]},\n{name:\"Komennot\",items:[{name:\"Peruuta komento\",legend:\"Paina ${undo}\"},{name:\"Tee uudelleen komento\",legend:\"Paina ${redo}\"},{name:\"Lihavoi komento\",legend:\"Paina ${bold}\"},{name:\"Kursivoi komento\",legend:\"Paina ${italic}\"},{name:\"Alleviivaa komento\",legend:\"Paina ${underline}\"},{name:\"Linkki komento\",legend:\"Paina ${link}\"},{name:\"Pienennä työkalupalkki komento\",legend:\"Paina ${toolbarCollapse}\"},{name:\"Siirry aiempaan fokustilaan komento\",legend:\"Paina ${accessPreviousSpace} siiryäksesi lähimpään kursorin edellä olevaan saavuttamattomaan fokustilaan, esimerkiksi: kaksi vierekkäistä HR elementtiä. Toista näppäinyhdistelmää päästäksesi kauempana oleviin fokustiloihin.\"},\n{name:\"Siirry seuraavaan fokustilaan komento\",legend:\"Paina ${accessPreviousSpace} siiryäksesi lähimpään kursorin jälkeen olevaan saavuttamattomaan fokustilaan, esimerkiksi: kaksi vierekkäistä HR elementtiä. Toista näppäinyhdistelmää päästäksesi kauempana oleviin fokustiloihin.\"},{name:\"Saavutettavuus ohjeet\",legend:\"Paina ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/fr-ca.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"fr-ca\",{title:\"Instructions d'accessibilité\",contents:\"Contenu de l'aide.  Pour fermer cette fenêtre, appuyez sur ESC.\",legend:[{name:\"Général\",items:[{name:\"Barre d'outil de l'éditeur\",legend:\"Appuyer sur ${toolbarFocus} pour accéder à la barre d'outils. Se déplacer vers les groupes suivant ou précédent de la barre d'outil avec les touches TAB et SHIFT-TAB. Se déplacer vers les boutons suivant ou précédent de la barre d'outils avec les touches FLECHE DROITE et FLECHE GAUCHE. Appuyer sur la barre d'espace ou la touche ENTRER pour activer le bouton de barre d'outils.\"},\n{name:\"Dialogue de l'éditeur\",legend:\"A l'intérieur d'un dialogue, appuyer sur la touche TAB pour naviguer jusqu'au champ de dalogue suivant, appuyez sur les touches SHIFT + TAB pour revenir au champ précédent, appuyez sur la touche ENTRER pour soumettre le dialogue, appuyer sur la touche ESC pour annuler le dialogue. Pour les dialogues avec plusieurs pages d'onglets, appuyer sur ALT + F10 pour naviguer jusqu'à la liste des onglets. Puis se déplacer vers l'onglet suivant avec la touche TAB ou FLECHE DROITE. Se déplacer vers l'onglet précédent avec les touches SHIFT + TAB ou FLECHE GAUCHE. Appuyer sur la barre d'espace ou la touche ENTRER pour sélectionner la page de l'onglet.\"},\n{name:\"Menu contextuel de l'éditeur\",legend:\"Appuyer sur ${contextMenu} ou entrer le RACCOURCI CLAVIER pour ouvrir le menu contextuel. Puis se déplacer vers l'option suivante du menu avec les touches TAB ou FLECHE BAS. Se déplacer vers l'option précédente avec les touches SHIFT+TAB ou FLECHE HAUT. appuyer sur la BARRE D'ESPACE ou la touche ENTREE pour sélectionner l'option du menu. Oovrir le sous-menu de l'option courante avec la BARRE D'ESPACE ou les touches ENTREE ou FLECHE DROITE. Revenir à l'élément de menu parent avec les touches ESC ou FLECHE GAUCHE. Fermer le menu contextuel avec ESC.\"},\n{name:\"Menu déroulant de l'éditeur\",legend:\"A l'intérieur d'une liste en menu déroulant, se déplacer vers l'élément suivant de la liste avec les touches TAB ou FLECHE BAS. Se déplacer vers l'élément précédent de la liste avec les touches SHIFT + TAB ou FLECHE HAUT. Appuyer sur la BARRE D'ESPACE ou sur ENTREE pour sélectionner l'option dans la liste. Appuyer sur ESC pour fermer le menu déroulant.\"},{name:\"Barre d'emplacement des éléments de l'éditeur\",legend:\"Appuyer sur ${elementsPathFocus} pour naviguer vers la barre d'emplacement des éléments de léditeur. Se déplacer vers le bouton d'élément suivant avec les touches TAB ou FLECHE DROITE. Se déplacer vers le bouton d'élément précédent avec les touches SHIFT+TAB ou FLECHE GAUCHE. Appuyer sur la BARRE D'ESPACE ou sur ENTREE pour sélectionner l'élément dans l'éditeur.\"}]},\n{name:\"Commandes\",items:[{name:\"Annuler\",legend:\"Appuyer sur ${undo}\"},{name:\"Refaire\",legend:\"Appuyer sur ${redo}\"},{name:\"Gras\",legend:\"Appuyer sur ${bold}\"},{name:\"Italique\",legend:\"Appuyer sur ${italic}\"},{name:\"Souligné\",legend:\"Appuyer sur ${underline}\"},{name:\"Lien\",legend:\"Appuyer sur ${link}\"},{name:\"Enrouler la barre d'outils\",legend:\"Appuyer sur ${toolbarCollapse}\"},{name:\"Accéder à l'objet de focus précédent\",legend:\"Appuyer ${accessPreviousSpace} pour accéder au prochain espace disponible avant le curseur, par exemple: deux éléments HR adjacents.  Répéter la combinaison pour joindre les éléments d'espaces distantes.\"},\n{name:\"Accéder au prochain objet de focus\",legend:\"Appuyer ${accessNextSpace} pour accéder au prochain espace disponible après le curseur, par exemple: deux éléments HR adjacents.  Répéter la combinaison pour joindre les éléments d'espaces distantes.\"},{name:\"Aide d'accessibilité\",legend:\"Appuyer sur ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/fr.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"fr\",{title:\"Instructions d'accessibilité\",contents:\"Contenu de l'aide. Pour fermer ce dialogue, appuyez sur la touche Ech (Echappement).\",legend:[{name:\"Général\",items:[{name:\"Barre d'outils de l'éditeur\",legend:\"Appuyer sur ${toolbarFocus} pour accéder à la barre d'outils. Se déplacer vers les groupes suivant ou précédent de la barre d'outil avec les touches TAB et SHIFT-TAB. Se déplacer vers les boutons suivant ou précédent de la barre d'outils avec les touches FLECHE DROITE et FLECHE GAUCHE. Appuyer sur la barre d'espace ou la touche ENTRER pour activer le bouton de barre d'outils.\"},\n{name:\"Dialogue de l'éditeur\",legend:\"A l'intérieur d'un dialogue, appuyer sur la touche TAB pour naviguer jusqu'au champ de dalogue suivant, appuyez sur les touches SHIFT + TAB pour revenir au champ précédent, appuyez sur la touche ENTRER pour soumettre le dialogue, appuyer sur la touche ESC pour annuler le dialogue. Pour les dialogues avec plusieurs pages d'onglets, appuyer sur ALT + F10 pour naviguer jusqu'à la liste des onglets. Puis se déplacer vers l'onglet suivant avec la touche TAB ou FLECHE DROITE. Se déplacer vers l'onglet précédent avec les touches SHIFT + TAB ou FLECHE GAUCHE. Appuyer sur la barre d'espace ou la touche ENTRER pour sélectionner la page de l'onglet.\"},\n{name:\"Menu contextuel de l'éditeur\",legend:\"Appuyer sur ${contextMenu} ou entrer le RACCOURCI CLAVIER pour ouvrir le menu contextuel. Puis se déplacer vers l'option suivante du menu avec les touches TAB ou FLECHE BAS. Se déplacer vers l'option précédente avec les touches  SHIFT+TAB ou FLECHE HAUT. appuyer sur la BARRE D'ESPACE ou la touche ENTREE pour sélectionner l'option du menu. Oovrir le sous-menu de l'option courante avec la BARRE D'ESPACE ou les touches ENTREE ou FLECHE DROITE. Revenir à l'élément de menu parent avec les touches Ech ou FLECHE GAUCHE. Fermer le menu contextuel avec Ech.\"},\n{name:\"Zone de liste de l'éditeur\",legend:\"Dans la liste en menu déroulant, se déplacer vers l'élément suivant de la liste avec les touches TAB ou FLECHE BAS. Se déplacer vers l'élément précédent de la liste avec les touches MAJ + TAB ou FLECHE HAUT. Appuyer sur la BARRE D'ESPACE ou sur ENTREE pour sélectionner l'option dans la liste. Appuyer sur ESC pour fermer le menu déroulant.\"},{name:\"Barre d'emplacement des éléments de l'éditeur\",legend:\"Appuyer sur ${elementsPathFocus} pour naviguer vers la barre d'emplacement des éléments de l'éditeur. Se déplacer vers le bouton d'élément suivant avec les touches TAB ou FLECHE DROITE. Se déplacer vers le bouton d'élément précédent avec les touches MAJ+TAB ou FLECHE GAUCHE. Appuyer sur la BARRE D'ESPACE ou sur ENTREE pour sélectionner l'élément dans l'éditeur.\"}]},\n{name:\"Commandes\",items:[{name:\" Annuler la commande\",legend:\"Appuyer sur ${undo}\"},{name:\"Refaire la commande\",legend:\"Appuyer sur ${redo}\"},{name:\" Commande gras\",legend:\"Appuyer sur ${bold}\"},{name:\" Commande italique\",legend:\"Appuyer sur ${italic}\"},{name:\" Commande souligné\",legend:\"Appuyer sur ${underline}\"},{name:\" Commande lien\",legend:\"Appuyer sur ${link}\"},{name:\" Commande enrouler la barre d'outils\",legend:\"Appuyer sur ${toolbarCollapse}\"},{name:\"Accéder à la précédente commande d'espace de mise au point\",\nlegend:\"Appuyez sur ${accessPreviousSpace} pour accéder à l'espace hors d'atteinte le plus proche avant le caret, par exemple: deux éléments HR adjacents. Répétez la combinaison de touches pour atteindre les espaces de mise au point distants.\"},{name:\"Accès à la prochaine commande de l'espace de mise au point\",legend:\"Appuyez sur ${accessNextSpace} pour accéder au plus proche espace de mise au point hors d'atteinte après le caret, par exemple: deux éléments HR adjacents. répétez la combinaison de touches pour atteindre les espace de mise au point distants.\"},\n{name:\" Aide Accessibilité\",legend:\"Appuyer sur ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/gl.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"gl\",{title:\"Instrucións de accesibilidade\",contents:\"Axuda. Para pechar este diálogo prema ESC.\",legend:[{name:\"Xeral\",items:[{name:\"Barra de ferramentas do editor\",legend:\"Prema ${toolbarFocus} para navegar pola barra de ferramentas. Para moverse polos distintos grupos de ferramentas use as teclas TAB e MAIÚS+TAB. Para moverse polas distintas ferramentas use FRECHA DEREITA ou FRECHA ESQUERDA. Prema ESPAZO ou INTRO para activar o botón da barra de ferramentas.\"},\n{name:\"Editor de diálogo\",legend:\"Dentro dun cadro de diálogo, prema a tecla TAB para desprazarse ao campo seguinte do cadro de diálogo, prema MAIÚS + TAB para desprazarse ao campo anterior, prema INTRO para presentar o cadro de diálogo, prema a tecla ESC para cancelar o diálogo. Para os diálogos que teñen varias páxinas, prema ALT + F10 para navegar á lapela da lista. Despois pasar á seguinte lapela con TAB ou FRECHA DEREITA. Para ir á lapela anterior con SHIFT + TAB ou FRECHA ESQUERDA. Prema ESPAZO ou INTRO para seleccionar a lapela da páxina.\"},\n{name:\"Editor do menú contextual\",legend:\"Prema ${contextMenu} ou a TECLA MENÚ para abrir o menú contextual. A seguir móvase á seguinte opción do menú con TAB ou FRECHA ABAIXO. Móvase á opción anterior con MAIÚS + TAB ou FRECHA ARRIBA. Prema ESPAZO ou INTRO para seleccionar a opción do menú. Abra o submenú da opción actual con ESPAZO ou INTRO ou FRECHA DEREITA. Regrese ao elemento principal do menú con ESC ou FRECHA ESQUERDA. Peche o menú contextual con ESC.\"},{name:\"Lista do editor\",legend:\"Dentro dunha lista, móvase ao seguinte elemento da lista con TAB ou FRECHA ABAIXO. Móvase ao elemento anterior da lista con MAIÚS + TAB ou FRECHA ARRIBA. Prema ESPAZO ou INTRO para escoller a opción da lista. Prema ESC para pechar a lista.\"},\n{name:\"Barra da ruta ao elemento no editor\",legend:\"Prema ${elementsPathFocus} para navegar ata os elementos da barra de ruta. Móvase ao seguinte elemento botón con TAB ou FRECHA DEREITA. Móvase ao botón anterior con MAIÚS + TAB ou FRECHA ESQUERDA. Prema ESPAZO ou INTRO para seleccionar o elemento no editor.\"}]},{name:\"Ordes\",items:[{name:\"Orde «desfacer»\",legend:\"Prema ${undo}\"},{name:\"Orde «refacer»\",legend:\"Prema ${redo}\"},{name:\"Orde «negra»\",legend:\"Prema ${bold}\"},{name:\"Orde «cursiva»\",legend:\"Prema ${italic}\"},\n{name:\"Orde «subliñar»\",legend:\"Prema ${underline}\"},{name:\"Orde «ligazón»\",legend:\"Prema ${link}\"},{name:\"Orde «contraer a barra de ferramentas»\",legend:\"Prema ${toolbarCollapse}\"},{name:\"Orde «acceder ao anterior espazo en foco»\",legend:\"Prema ${accessPreviousSpace} para acceder ao espazo máis próximo de foco inalcanzábel anterior ao cursor, por exemplo: dous elementos HR adxacentes. Repita a combinación de teclas para chegar a espazos de foco distantes.\"},{name:\"Orde «acceder ao seguinte espazo en foco»\",\nlegend:\"Prema ${accessNextSpace} para acceder ao espazo máis próximo de foco inalcanzábel posterior ao cursor, por exemplo: dous elementos HR adxacentes. Repita a combinación de teclas para chegar a espazos de foco distantes.\"},{name:\"Axuda da accesibilidade\",legend:\"Prema ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/gu.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"gu\",{title:\"એક્ક્ષેબિલિટી ની વિગતો\",contents:\"હેલ્પ. આ બંધ કરવા ESC દબાવો.\",legend:[{name:\"જનરલ\",items:[{name:\"એડિટર ટૂલબાર\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"એડિટર ડાયલોગ\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"કમાંડસ\",items:[{name:\"અન્ડું કમાંડ\",legend:\"$ દબાવો {undo}\"},{name:\"ફરી કરો કમાંડ\",legend:\"$ દબાવો {redo}\"},{name:\"બોલ્દનો કમાંડ\",legend:\"$ દબાવો {bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/he.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"he\",{title:\"הוראות נגישות\",contents:\"הוראות נגישות. לסגירה לחץ אסקייפ (ESC).\",legend:[{name:\"כללי\",items:[{name:\"סרגל הכלים\",legend:\"לחץ על ${toolbarFocus} כדי לנווט לסרגל הכלים. עבור לכפתור הבא עם מקש הטאב (TAB) או חץ שמאלי. עבור לכפתור הקודם עם מקש השיפט (SHIFT) + טאב (TAB) או חץ ימני. לחץ רווח או אנטר (ENTER) כדי להפעיל את הכפתור הנבחר.\"},{name:\"דיאלוגים (חלונות תשאול)\",legend:\"בתוך דיאלוג, לחץ טאב (TAB) כדי לנווט לשדה הבא, לחץ שיפט (SHIFT) + טאב (TAB) כדי לנווט לשדה הקודם, לחץ אנטר (ENTER) כדי לשלוח את הדיאלוג, לחץ אסקייפ (ESC) כדי לבטל. בתוך דיאלוגים בעלי מספר טאבים (לשוניות), לחץ אלט (ALT) + F10 כדי לנווט לשורת הטאבים. נווט לטאב הבא עם טאב (TAB) או חץ שמאלי. עבור לטאב הקודם עם שיפט (SHIFT) + טאב (TAB) או חץ שמאלי. לחץ רווח או אנטר (ENTER) כדי להיכנס לטאב.\"},\n{name:\"תפריט ההקשר (Context Menu)\",legend:\"לחץ ${contextMenu} או APPLICATION KEYכדי לפתוח את תפריט ההקשר. עבור לאפשרות הבאה עם טאב (TAB) או חץ למטה. עבור לאפשרות הקודמת עם שיפט (SHIFT) + טאב (TAB) או חץ למעלה. לחץ רווח או אנטר (ENTER) כדי לבחור את האפשרות. פתח את תת התפריט (Sub-menu) של האפשרות הנוכחית עם רווח או אנטר (ENTER) או חץ שמאלי. חזור לתפריט האב עם אסקייפ (ESC) או חץ שמאלי. סגור את תפריט ההקשר עם אסקייפ (ESC).\"},{name:\"תפריטים צפים (List boxes)\",legend:\"בתוך תפריט צף, עבור לפריט הבא עם טאב (TAB) או חץ למטה. עבור לתפריט הקודם עם שיפט (SHIFT) + טאב (TAB) or חץ עליון. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"עץ אלמנטים (Elements Path)\",legend:\"לחץ ${elementsPathFocus} כדי לנווט לעץ האלמנטים. עבור לפריט הבא עם טאב (TAB) או חץ ימני. עבור לפריט הקודם עם שיפט (SHIFT) + טאב (TAB) או חץ שמאלי. לחץ רווח או אנטר (ENTER) כדי לבחור את האלמנט בעורך.\"}]},{name:\"פקודות\",items:[{name:\" ביטול צעד אחרון\",legend:\"לחץ ${undo}\"},{name:\" חזרה על צעד אחרון\",legend:\"לחץ ${redo}\"},{name:\" הדגשה\",legend:\"לחץ ${bold}\"},{name:\" הטייה\",legend:\"לחץ ${italic}\"},{name:\" הוספת קו תחתון\",legend:\"לחץ ${underline}\"},{name:\" הוספת לינק\",\nlegend:\"לחץ ${link}\"},{name:\" כיווץ סרגל הכלים\",legend:\"לחץ ${toolbarCollapse}\"},{name:\"גישה למיקום המיקוד הקודם\",legend:\"לחץ ${accessPreviousSpace} כדי לגשת למיקום המיקוד הלא-נגיש הקרוב לפני הסמן, למשל בין שני אלמנטים סמוכים מסוג HR. חזור על צירוף מקשים זה כדי להגיע למקומות מיקוד רחוקים יותר.\"},{name:\"גישה למיקום המיקוד הבא\",legend:\"לחץ ${accessNextSpace} כדי לגשת למיקום המיקוד הלא-נגיש הקרוב אחרי הסמן, למשל בין שני אלמנטים סמוכים מסוג HR. חזור על צירוף מקשים זה כדי להגיע למקומות מיקוד רחוקים יותר.\"},\n{name:\" הוראות נגישות\",legend:\"לחץ ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/hi.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"hi\",{title:\"Accessibility Instructions\",contents:\"Help Contents. To close this dialog press ESC.\",legend:[{name:\"सामान्य\",items:[{name:\"Editor Toolbar\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Editor Dialog\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Commands\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/hr.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"hr\",{title:\"Upute dostupnosti\",contents:\"Sadržaj pomoći. Za zatvaranje pritisnite ESC.\",legend:[{name:\"Općenito\",items:[{name:\"Alatna traka\",legend:\"Pritisni ${toolbarFocus} za navigaciju do alatne trake. Pomicanje do prethodne ili sljedeće alatne grupe vrši se pomoću SHIFT-TAB i TAB. Pomicanje do prethodnog ili sljedećeg gumba u alatnoj traci vrši se pomoću lijeve i desne strelice kursora. Pritisnite SPACE ili ENTER za aktivaciju alatne trake.\"},{name:\"Dijalog\",\nlegend:\"Unutar dijaloga, pritisnite TAB za navigaciju do sljedećeg polja, pritisnite SHIFT + TAB za vraćanje na prethodno polje, pritisnite ENTER za slanje dijaloga ili ESC za zatvaranje dijaloga. Za dijaloge koji imaju višestruke kartice, pritisnite ALT + F10 za na navigaciju i zatim TAB ili lijeva strelica kursora ili SHIFT + TAB i desna strelica kursora. SPACE ili ENTER odabiru karticu.\"},{name:\"Kontekstni izbornik\",legend:\"Pritisnite ${contextMenu} ili APPLICATION tipku za otvaranje kontekstnog izbornika. Pomicanje se vrši TAB ili strelicom kursora prema dolje ili SHIFT+TAB ili strelica kursora prema gore. SPACE ili ENTER odabiru opciju izbornika. Otvorite podizbornik trenutne opcije sa  SPACE, ENTER ili desna strelica kursora. Povratak na prethodni izbornik vrši se sa ESC ili lijevom strelicom kursora. Zatvaranje se vrši pritiskom na tipku ESC.\"},\n{name:\"Lista\",legend:\"Unutar list-boxa, pomicanje na sljedeću stavku vrši se sa TAB ili strelica kursora prema dolje. Na prethodnu sa SHIFT + TAB ili strelica prema gore. Pritiskom na SPACE ili ENTER odabire se stavka ili ESC za zatvaranje.\"},{name:\"Traka putanje elemenata\",legend:\"Pritisnite ${elementsPathFocus} za navigaciju po putanji elemenata. Pritisnite TAB ili desnu strelicu kursora za pomicanje na sljedeći element ili SHIFT + TAB ili lijeva strelica kursora za pomicanje na prethodni element. Pritiskom na SPACE ili ENTER vrši se odabir elementa.\"}]},\n{name:\"Naredbe\",items:[{name:\"Vrati naredbu\",legend:\"Pritisni ${undo}\"},{name:\"Ponovi naredbu\",legend:\"Pritisni ${redo}\"},{name:\"Bold naredba\",legend:\"Pritisni ${bold}\"},{name:\"Italic naredba\",legend:\"Pritisni ${italic}\"},{name:\"Underline naredba\",legend:\"Pritisni ${underline}\"},{name:\"Link naredba\",legend:\"Pritisni ${link}\"},{name:\"Smanji alatnu traku naredba\",legend:\"Pritisni ${toolbarCollapse}\"},{name:\"Access previous focus space naredba\",legend:\"Pritisni ${accessPreviousSpace} za pristup najbližem nedostupnom razmaku prije kursora, npr.: dva spojena HR elementa. Ponovnim pritiskom dohvatiti će se sljedeći nedostupni razmak.\"},\n{name:\"Access next focus space naredba\",legend:\"Pritisni ${accessNextSpace} za pristup najbližem nedostupnom razmaku nakon kursora, npr.: dva spojena HR elementa. Ponovnim pritiskom dohvatiti će se sljedeći nedostupni razmak.\"},{name:\"Pomoć za dostupnost\",legend:\"Pritisni ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/hu.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"hu\",{title:\"Kisegítő utasítások\",contents:\"Súgó tartalmak. A párbeszédablak bezárásához nyomjon ESC-et.\",legend:[{name:\"Általános\",items:[{name:\"Szerkesztő Eszköztár\",legend:\"Nyomjon ${toolbarFocus} hogy kijelölje az eszköztárat. A következő és előző eszköztár csoporthoz a TAB és SHIFT TAB-al juthat el. A következő és előző eszköztár gombhoz a BAL NYÍL vagy JOBB NYÍL gombbal juthat el. Nyomjon SPACE-t vagy ENTER-t hogy aktiválja az eszköztár gombot.\"},{name:\"Szerkesző párbeszéd ablak\",\nlegend:\"Párbeszédablakban nyomjon TAB-ot a következő párbeszédmezőhöz ugráshoz, nyomjon SHIFT + TAB-ot az előző mezőhöz ugráshoz, nyomjon ENTER-t a párbeszédablak elfogadásához, nyomjon ESC-et a párbeszédablak elvetéséhez. Azokhoz a párbeszédablakokhoz, amik több fület tartalmaznak, nyomjon ALT + F10-et hogy a fülekre ugorjon. Ezután a TAB-al vagy a JOBB NYÍLLAL a következő fülre ugorhat. Az előző fülre ugráshoz használja a SHIFT + TAB-ot vagy a BAL NYILAT. Nyomjon SPACE-t vagy ENTER-t hogy kijelölje a fület.\"},\n{name:\"Szerkesztő helyi menü\",legend:\"Nyomjon ${contextMenu}-t vagy ALKALMAZÁS BILLENTYŰT a helyi menü megnyitásához. Ezután a következő menüpontra léphet a TAB vagy LEFELÉ NYÍLLAL. Az előző opciót a SHIFT+TAB vagy FELFELÉ NYÍLLAL érheti el. Nyomjon SPACE-t vagy ENTER-t a menüpont kiválasztásához. A jelenlegi menüpont almenüjének megnyitásához nyomjon SPACE-t vagy ENTER-t, vagy JOBB NYILAT. A főmenühöz való visszatéréshez nyomjon ESC-et vagy BAL NYILAT. A helyi menü bezárása az ESC billentyűvel lehetséges.\"},\n{name:\"Szerkesztő lista\",legend:\"A listán belül a következő elemre a TAB vagy LEFELÉ NYÍLLAL mozoghat. Az előző elem kiválasztásához nyomjon SHIFT+TAB-ot vagy FELFELÉ NYILAT. Nyomjon SPACE-t vagy ENTER-t az elem kiválasztásához. Az ESC billentyű megnyomásával bezárhatja a listát.\"},{name:\"Szerkesztő elem utak sáv\",legend:\"Nyomj ${elementsPathFocus} hogy kijelöld a elemek út sávját. A következő elem gombhoz a TAB-al vagy a JOBB NYÍLLAL juthatsz el. Az előző gombhoz a SHIFT+TAB vagy BAL NYÍLLAL mehetsz. A SPACE vagy ENTER billentyűvel kiválaszthatod az elemet a szerkesztőben.\"}]},\n{name:\"Parancsok\",items:[{name:\"Parancs visszavonása\",legend:\"Nyomj ${undo}\"},{name:\"Parancs megismétlése\",legend:\"Nyomjon ${redo}\"},{name:\"Félkövér parancs\",legend:\"Nyomjon ${bold}\"},{name:\"Dőlt parancs\",legend:\"Nyomjon ${italic}\"},{name:\"Aláhúzott parancs\",legend:\"Nyomjon ${underline}\"},{name:\"Link parancs\",legend:\"Nyomjon ${link}\"},{name:\"Szerkesztősáv összecsukása parancs\",legend:\"Nyomjon ${toolbarCollapse}\"},{name:\"Hozzáférés az előző fókusz helyhez parancs\",legend:\"Nyomj ${accessNextSpace} hogy hozzáférj a legközelebbi elérhetetlen fókusz helyhez a hiányjel előtt, például: két szomszédos HR elemhez. Ismételd meg a billentyűkombinációt hogy megtaláld a távolabbi fókusz helyeket.\"},\n{name:\"Hozzáférés a következő fókusz helyhez parancs\",legend:\"Nyomj ${accessNextSpace} hogy hozzáférj a legközelebbi elérhetetlen fókusz helyhez a hiányjel után, például: két szomszédos HR elemhez. Ismételd meg a billentyűkombinációt hogy megtaláld a távolabbi fókusz helyeket.\"},{name:\"Kisegítő súgó\",legend:\"Nyomjon ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/id.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"id\",{title:\"Accessibility Instructions\",contents:\"Bantuan. Tekan ESC untuk menutup dialog ini.\",legend:[{name:\"Umum\",items:[{name:\"Editor Toolbar\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Editor Dialog\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Commands\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/it.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"it\",{title:\"Istruzioni di Accessibilità\",contents:\"Contenuti di Aiuto. Per chiudere questa finestra premi ESC.\",legend:[{name:\"Generale\",items:[{name:\"Barra degli strumenti Editor\",legend:\"Premi ${toolbarFocus} per navigare fino alla barra degli strumenti. Muoviti tra i gruppi della barra degli strumenti con i tasti Tab e Maiusc-Tab. Spostati tra il successivo ed il precedente pulsante della barra degli strumenti usando le frecce direzionali Destra e Sinistra. Premi Spazio o Invio per attivare il pulsante della barra degli strumenti.\"},\n{name:\"Finestra Editor\",legend:\"All'interno di una finestra di dialogo, premi Tab per navigare fino al campo successivo della finestra di dialogo, premi Maiusc-Tab per tornare al campo precedente, premi Invio per inviare la finestra di dialogo, premi Esc per uscire. Per le finestre che hanno schede multiple, premi Alt+F10 per navigare nella lista delle schede. Quindi spostati alla scheda successiva con il tasto Tab oppure con la Freccia Destra. Torna alla scheda precedente con Maiusc+Tab oppure con la Freccia Sinistra. Premi Spazio o Invio per scegliere la scheda.\"},\n{name:\"Menù contestuale Editor\",legend:\"Premi ${contextMenu} o TASTO APPLICAZIONE per aprire il menu contestuale. Dunque muoviti all'opzione successiva del menu con il tasto TAB o con la Freccia Sotto. Muoviti all'opzione precedente con  MAIUSC+TAB o con Freccia Sopra. Premi SPAZIO o INVIO per scegliere l'opzione di menu. Apri il sottomenu dell'opzione corrente con SPAZIO o INVIO oppure con la Freccia Destra. Torna indietro al menu superiore con ESC oppure Freccia Sinistra. Chiudi il menu contestuale con ESC.\"},\n{name:\"Box Lista Editor\",legend:\"Dentro un box-lista, muoviti al prossimo elemento della lista con TAB o con la Freccia direzionale giù. Spostati all'elemento precedente con MAIUSC+TAB oppure con Freccia direzionale sopra. Premi SPAZIO o INVIO per scegliere l'opzione della lista. Premi ESC per chiudere il box-lista.\"},{name:\"Barra percorso elementi editor\",legend:\"Premi ${elementsPathFocus} per navigare tra gli elementi della barra percorso. Muoviti al prossimo pulsante di elemento con TAB o la Freccia direzionale destra. Muoviti al pulsante precedente con MAIUSC+TAB o la Freccia Direzionale Sinistra. Premi SPAZIO o INVIO per scegliere l'elemento nell'editor.\"}]},\n{name:\"Comandi\",items:[{name:\" Annulla comando\",legend:\"Premi ${undo}\"},{name:\" Ripeti comando\",legend:\"Premi ${redo}\"},{name:\" Comando Grassetto\",legend:\"Premi ${bold}\"},{name:\" Comando Corsivo\",legend:\"Premi ${italic}\"},{name:\" Comando Sottolineato\",legend:\"Premi ${underline}\"},{name:\" Comando Link\",legend:\"Premi ${link}\"},{name:\" Comando riduci barra degli strumenti\",legend:\"Premi ${toolbarCollapse}\"},{name:\"Comando di accesso al precedente spazio di focus\",legend:\"Premi ${accessPreviousSpace} per accedere il più vicino spazio di focus non raggiungibile prima del simbolo caret, per esempio due elementi HR adiacenti. Ripeti la combinazione di tasti per raggiungere spazi di focus distanti.\"},\n{name:\"Comando di accesso al prossimo spazio di focus\",legend:\"Premi ${accessNextSpace} per accedere il più vicino spazio di focus non raggiungibile dopo il simbolo caret, per esempio due elementi HR adiacenti. Ripeti la combinazione di tasti per raggiungere spazi di focus distanti.\"},{name:\" Aiuto Accessibilità\",legend:\"Premi ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ja.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"ja\",{title:\"ユーザー補助の説明\",contents:\"ヘルプ　このダイアログを閉じるには ESCを押してください。\",legend:[{name:\"全般\",items:[{name:\"エディターツールバー\",legend:\"${toolbarFocus} を押すとツールバーのオン/オフ操作ができます。カーソルをツールバーのグループで移動させるにはTabかSHIFT+Tabを押します。グループ内でカーソルを移動させるには、右カーソルか左カーソルを押します。スペースキーやエンターを押すとボタンを有効/無効にすることができます。\"},{name:\"編集ダイアログ\",legend:\"ダイヤログ内では、ダイアログの次の選択肢に移動するにはTabを押します。前の選択肢に移動するには、SHIFT+Tabを押します。ダイアログを決定するには、ENTERを押します。ESCでダイアログをキャンセルできます。複数のタブがあるダイアログではタブリストを操作するにはALT+F10を押します。次のタブに移動するにはTabか右カーソル、前のタブに戻るにはSHIFT+Tabか左カーソルです。タブページを決定するにはスペースもしくは、ENTERキーを押してください。\"},\n{name:\"エディターのメニュー\",legend:\"${contextMenu} キーかAPPLICATION KEYを押すとコンテキストメニューが開きます。Tabか下カーソルでメニューのオプション選択が下に移動します。戻るには、SHIFT+Tabか上カーソルです。スペースもしくはENTERキーでメニューオプションを決定できます。現在選んでいるオプションのサブメニューを開くには、スペース、もしくは右カーソルを押します。サブメニューから親メニューに戻るには、ESCか左カーソルを押してください。ESCでコンテキストメニュー自体をキャンセルできます。\"},{name:\"エディターリストボックス\",legend:\"リストボックス内で移動するには、Tabか下カーソルで次のアイテムへ移動します。SHIFT+Tabで前のアイテムに戻ります。リストのオプションを選択するには、スペースもしくは、ENTERを押してください。リストボックスを閉じるには、ESCを押してください。\"},{name:\"エディター要素パスバー\",legend:\"${elementsPathFocus} を押すとエレメントパスバーを操作出来ます。Tabか右カーソルで次のエレメントを選択できます。前のエレメントを選択するには、SHIFT+Tabか左カーソルです。スペースもしくは、ENTERでエディタ内の対象エレメントを選択出来ます。\"}]},\n{name:\"コマンド\",items:[{name:\"元に戻す\",legend:\"${undo} をクリック\"},{name:\"やり直し\",legend:\"${redo} をクリック\"},{name:\"太字\",legend:\"${bold} をクリック\"},{name:\"斜体 \",legend:\"${italic} をクリック\"},{name:\"下線\",legend:\"${underline} をクリック\"},{name:\"リンク\",legend:\"${link} をクリック\"},{name:\"ツールバーを縮める\",legend:\"${toolbarCollapse} をクリック\"},{name:\"前のカーソル移動のできないポイントへ\",legend:\"${accessPreviousSpace} を押すとカーソルより前にあるカーソルキーで入り込めないスペースへ移動できます。例えば、HRエレメントが2つ接している場合などです。離れた場所へは、複数回キーを押します。\"},{name:\"次のカーソル移動のできないポイントへ\",legend:\"${accessNextSpace} を押すとカーソルより後ろにあるカーソルキーで入り込めないスペースへ移動できます。例えば、HRエレメントが2つ接している場合などです。離れた場所へは、複数回キーを押します。\"},\n{name:\"ユーザー補助ヘルプ\",legend:\"${a11yHelp} をクリック\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/km.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"km\",{title:\"Accessibility Instructions\",contents:\"Help Contents. To close this dialog press ESC.\",legend:[{name:\"ទូទៅ\",items:[{name:\"Editor Toolbar\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Editor Dialog\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Commands\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ko.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"ko\",{title:\"Accessibility Instructions\",contents:\"Help Contents. To close this dialog press ESC.\",legend:[{name:\"General\",items:[{name:\"편집기 툴바\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"편집기 다이얼로그\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"편집기 환경 메뉴\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"편집기 목록 박스\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"명령\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ku.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"ku\",{title:\"ڕێنمای لەبەردەستدابوون\",contents:\"پێکهاتەی یارمەتی. کلیك ESC بۆ داخستنی ئەم دیالۆگه.\",legend:[{name:\"گشتی\",items:[{name:\"تووڵامرازی دەستكاریكەر\",legend:\"کلیك ${toolbarFocus} بۆ ڕابەری تووڵامراز. بۆ گواستنەوەی پێشوو داهاتووی گرووپی تووڵامرازی داگرتنی کلیلی TAB لەگەڵ‌ SHIFT-TAB. بۆ گواستنەوەی پێشوو داهاتووی دووگمەی تووڵامرازی لەڕێی کلیلی تیری دەستی ڕاست یان کلیلی تیری دەستی چەپ. کلیکی کلیلی SPACE یان ENTER بۆ چالاککردنی دووگمەی تووڵامراز.\"},{name:\"دیالۆگی دەستكاریكەر\",\nlegend:\"لەهەمانکاتدا کە تۆ لەدیالۆگی, کلیکی کلیلی TAB بۆ ڕابەری خانەی دیالۆگێکی تر, داگرتنی کلیلی SHIFT + TAB بۆ گواستنەوەی بۆ خانەی پێشووتر, کلیكی کلیلی ENTER بۆ ڕازیکردنی دیالۆگەکە, کلیكی کلیلی ESC بۆ هەڵوەشاندنەوەی دیالۆگەکە. بۆ دیالۆگی لەبازدەری (تابی) زیاتر, کلیكی کلیلی ALT + F10 بۆ ڕابەری لیستی بازدەرەکان. بۆ چوونە بازدەری تابی داهاتوو کلیكی کلیلی TAB یان کلیلی تیری دەستی ڕاست. بۆچوونە بازدەری تابی پێشوو داگرتنی کلیلی SHIFT + TAB یان کلیلی تیری دەستی چەپ. کلیی کلیلی SPACE یان ENTER بۆ هه‌ڵبژاردنی بازدەر (تاب).\"},\n{name:\"پێڕستی سەرنووسەر\",legend:\"کلیك ${contextMenu} یان دوگمەی لیسته‌(Menu) بۆ کردنەوەی لیستەی دەق. بۆ چوونە هەڵبژاردەیەکی تر له‌ لیسته‌ کلیکی کلیلی TAB یان کلیلی تیری ڕوو لەخوارەوه‌ بۆ چوون بۆ هەڵبژاردەی پێشوو کلیکی کلیلی SHIFT+TAB یان کلیلی تیری ڕوو له‌ سەرەوە. داگرتنی کلیلی SPACE یان ENTER بۆ هەڵبژاردنی هەڵبژاردەی لیسته‌. بۆ کردنەوەی لقی ژێر لیسته‌ لەهەڵبژاردەی لیستە کلیکی کلیلی SPACE یان ENTER یان کلیلی تیری دەستی ڕاست. بۆ گەڕانەوه بۆ سەرەوەی لیسته‌ کلیکی کلیلی ESC یان کلیلی تیری دەستی چەپ. بۆ داخستنی لیستە کلیكی کلیلی ESC بکە.\"},\n{name:\"لیستی سنووقی سەرنووسەر\",legend:\"لەناو سنوقی لیست, چۆن بۆ هەڵنبژاردەی لیستێکی تر کلیکی کلیلی TAB یان کلیلی تیری ڕوو لەخوار. چوون بۆ هەڵبژاردەی لیستی پێشوو کلیکی کلیلی SHIFT + TAB یان کلیلی تیری ڕوو لەسەرەوه‌. کلیکی کلیلی SPACE یان ENTER بۆ دیاریکردنی ‌هەڵبژاردەی لیست. کلیکی کلیلی ESC بۆ داخستنی سنوقی لیست.\"},{name:\"تووڵامرازی توخم\",legend:\"کلیك ${elementsPathFocus} بۆ ڕابەری تووڵامرازی توخمەکان. چوون بۆ دوگمەی توخمێکی تر کلیکی کلیلی TAB یان کلیلی تیری دەستی ڕاست. چوون بۆ دوگمەی توخمی پێشوو کلیلی SHIFT+TAB یان کلیکی کلیلی تیری دەستی چەپ. داگرتنی کلیلی SPACE یان ENTER بۆ دیاریکردنی توخمەکه‌ لەسەرنووسه.\"}]},\n{name:\"فەرمانەکان\",items:[{name:\"پووچکردنەوەی فەرمان\",legend:\"کلیك ${undo}\"},{name:\"هەڵگەڕانەوەی فەرمان\",legend:\"کلیك ${redo}\"},{name:\"فەرمانی دەقی قەڵەو\",legend:\"کلیك ${bold}\"},{name:\"فەرمانی دەقی لار\",legend:\"کلیك ${italic}\"},{name:\"فەرمانی ژێرهێڵ\",legend:\"کلیك ${underline}\"},{name:\"فەرمانی به‌ستەر\",legend:\"کلیك ${link}\"},{name:\"شاردەنەوەی تووڵامراز\",legend:\"کلیك ${toolbarCollapse}\"},{name:\"چوونەناو سەرنجدانی پێشوی فەرمانی بۆشایی\",legend:\"کلیک ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\"چوونەناو سەرنجدانی داهاتووی فەرمانی بۆشایی\",legend:\"کلیک ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\"دەستپێگەیشتنی یارمەتی\",legend:\"کلیك ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/lt.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"lt\",{title:\"Accessibility Instructions\",contents:\"Help Contents. To close this dialog press ESC.\",legend:[{name:\"Bendros savybės\",items:[{name:\"Editor Toolbar\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Editor Dialog\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Commands\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/lv.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"lv\",{title:\"Pieejamības instrukcija\",contents:\"Palīdzības saturs. Lai aizvērtu ciet šo dialogu nospiediet ESC.\",legend:[{name:\"Galvenais\",items:[{name:\"Redaktora rīkjosla\",legend:\"Nospiediet ${toolbarFocus} lai pārvietotos uz rīkjoslu. Lai pārvietotos uz nākošo vai iepriekšējo rīkjoslas grupu izmantojiet pogu TAB un SHIFT+TAB.  Lai pārvietotos uz nākošo vai iepriekšējo rīkjoslas pogu izmantojiet Kreiso vai Labo bultiņu. Nospiediet Atstarpi vai ENTER lai aktivizētu rīkjosla pogu.\"},\n{name:\"Redaktora dialoga  logs\",legend:\"Dialoga logā nospiediet pogu TAB lai pārvietotos uz nākošo dialoga loga lauku, nospiediet SHIFT+TAB lai atgrieztos iepriekšējā laukā, nospiediet ENTER lai apstiprinātu dialoga datus, nospiediet ESC lai aizvērtu šo dialogu. Dialogam kuram ir vairākas cilnes, nospiediet ALT+F10 lai pārvietotos uz nepieciešamo cilni.  Lai pārvietotos uz nākošo cilni izmantojiet pogu TAB vai Labo bultiņu. Lai pārvietotos uz iepriekšējo cilni nospiediet SHIFT+TAB vai kreiso bultiņu. Nospiediet SPACE vai ENTER lai izvēlētos lapas cilni.\"},\n{name:\"Redaktora satura izvēle\",legend:\"Nospiediet ${contextMenu} vai APPLICATION KEY lai atvērtu satura izvēlni. Lai pārvietotos uz nākošo izvēlnes opciju izmantojiet pogu TAB vai pogu Bultiņu uz leju. Lai pārvietotos uz iepriekšējo opciju izmantojiet  SHIFT+TAB vai pogu Bultiņa uz augšu. Nospiediet SPACE vai ENTER lai izvelētos izvēlnes opciju. Atveriet tekošajā opcija apakšizvēlni ar SAPCE vai ENTER ka ari to var izdarīt ar Labo bultiņu. Lai atgrieztos atpakaļ uz sakuma izvēlni nospiediet ESC vai Kreiso bultiņu. Lai aizvērtu ciet izvēlnes saturu nospiediet ESC.\"},\n{name:\"Redaktora saraksta lauks\",legend:\"Saraksta laukā, lai pārvietotos uz nākošo saraksta elementu nospiediet TAB vai pogu Bultiņa uz leju. Lai pārvietotos uz iepriekšējo saraksta elementu nospiediet SHIFT+TAB vai pogu Bultiņa uz augšu. Nospiediet SPACE vai ENTER lai izvēlētos saraksta opcijas. Nospiediet ESC lai aizvērtu saraksta lauku. \"},{name:\"Redaktora elementa ceļa josla\",legend:\"Nospiediet ${elementsPathFocus} lai pārvietotos uz  elementa ceļa joslu. Lai pārvietotos uz nākošo elementa pogu izmantojiet TAB vai Labo bultiņu. Lai pārvietotos uz iepriekšējo elementa pogu  izmantojiet SHIFT + TAB vai Kreiso bultiņu. Nospiediet SPACE vai ENTER lai izvēlētos elementu redaktorā.\"}]},\n{name:\"Komandas\",items:[{name:\"Komanda atcelt darbību\",legend:\"Nospiediet ${undo}\"},{name:\"Komanda atkārtot darbību\",legend:\"Nospiediet ${redo}\"},{name:\"Treknraksta komanda\",legend:\"Nospiediet ${bold}\"},{name:\"Kursīva komanda\",legend:\"Nospiediet ${italic}\"},{name:\"Apakšsvītras komanda \",legend:\"Nospiediet ${underline}\"},{name:\"Hipersaites komanda\",legend:\"Nospiediet ${link}\"},{name:\"Rīkjoslas aizvēršanas komanda\",legend:\"Nospiediet ${toolbarCollapse}\"},{name:\"Piekļūt iepriekšējai fokusa vietas komandai\",\nlegend:\"Nospiediet ${accessPreviousSpace} lai piekļūtu tuvākajai nepieejamajai fokusa vietai pirms kursora. Piemēram: diviem blakus esošiem līnijas HR elementiem. Atkārtojiet taustiņu kombināciju lai piekļūtu pie tālākām vietām.\"},{name:\"Piekļūt nākošā fokusa apgabala komandai\",legend:\"Nospiediet ${accessNextSpace} lai piekļūtu tuvākajai nepieejamajai fokusa vietai pēc kursora. Piemēram: diviem blakus esošiem līnijas HR elementiem. Atkārtojiet taustiņu kombināciju lai piekļūtu pie tālākām vietām.\"},\n{name:\"Pieejamības palīdzība\",legend:\"Nospiediet ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/mk.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"mk\",{title:\"Инструкции за пристапност\",contents:\"Содржина на делот за помош. За да го затворите овој дијалот притиснете ESC.\",legend:[{name:\"Општо\",items:[{name:\"Мени за едиторот\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Дијалот за едиторот\",\nlegend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},\n{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},\n{name:\"Commands\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",legend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/mn.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"mn\",{title:\"Accessibility Instructions\",contents:\"Help Contents. To close this dialog press ESC.\",legend:[{name:\"Ерөнхий\",items:[{name:\"Editor Toolbar\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Editor Dialog\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Commands\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/nb.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"nb\",{title:\"Instruksjoner for tilgjengelighet\",contents:\"Innhold for hjelp. Trykk ESC for å lukke denne dialogen.\",legend:[{name:\"Generelt\",items:[{name:\"Verktøylinje for editor\",legend:\"Trykk ${toolbarFocus} for å navigere til verktøylinjen. Flytt til neste og forrige verktøylinjegruppe med TAB og SHIFT-TAB. Flytt til neste og forrige verktøylinjeknapp med HØYRE PILTAST og VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å aktivere verktøylinjeknappen.\"},{name:\"Dialog for editor\",\nlegend:\"Mens du er i en dialog, trykk TAB for å navigere til neste dialogfelt, press SHIFT + TAB for å flytte til forrige felt, trykk ENTER for å akseptere dialogen, trykk ESC for å avbryte dialogen. For dialoger med flere faner, trykk ALT + F10 for å navigere til listen over faner. Gå til neste fane med TAB eller HØYRE PILTAST. Gå til forrige fane med SHIFT + TAB eller VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å velge fanen.\"},{name:\"Kontekstmeny for editor\",legend:\"Trykk ${contextMenu} eller MENYKNAPP for å åpne kontekstmeny. Gå til neste alternativ i menyen med TAB eller PILTAST NED. Gå til forrige alternativ med SHIFT+TAB eller PILTAST OPP. Trykk MELLOMROM eller ENTER for å velge menyalternativet. Åpne undermenyen på valgt alternativ med MELLOMROM eller ENTER eller HØYRE PILTAST. Gå tilbake til overordnet menyelement med ESC eller VENSTRE PILTAST. Lukk kontekstmenyen med ESC.\"},\n{name:\"Listeboks for editor\",legend:\"I en listeboks, gå til neste alternativ i listen med TAB eller PILTAST NED. Gå til forrige alternativ i listen med SHIFT + TAB eller PILTAST OPP. Trykk MELLOMROM eller ENTER for å velge alternativet i listen. Trykk ESC for å lukke listeboksen.\"},{name:\"Verktøylinje for elementsti\",legend:\"Trykk ${elementsPathFocus} for å navigere til verktøylinjen som viser elementsti. Gå til neste elementknapp med TAB eller HØYRE PILTAST. Gå til forrige elementknapp med SHIFT+TAB eller VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å velge elementet i editoren.\"}]},\n{name:\"Hurtigtaster\",items:[{name:\"Angre\",legend:\"Trykk ${undo}\"},{name:\"Gjør om\",legend:\"Trykk ${redo}\"},{name:\"Fet tekst\",legend:\"Trykk ${bold}\"},{name:\"Kursiv tekst\",legend:\"Trykk ${italic}\"},{name:\"Understreking\",legend:\"Trykk ${underline}\"},{name:\"Lenke\",legend:\"Trykk ${link}\"},{name:\"Skjul verktøylinje\",legend:\"Trykk ${toolbarCollapse}\"},{name:\"Gå til forrige fokusområde\",legend:\"Trykk ${accessPreviousSpace} for å komme til nærmeste fokusområde før skrivemarkøren som ikke kan nås på vanlig måte, for eksempel to tilstøtende HR-elementer. Gjenta tastekombinasjonen for å komme til fokusområder lenger unna i dokumentet.\"},\n{name:\"Gå til neste fokusområde\",legend:\"Trykk ${accessNextSpace} for å komme til nærmeste fokusområde etter skrivemarkøren som ikke kan nås på vanlig måte, for eksempel to tilstøtende HR-elementer. Gjenta tastekombinasjonen for å komme til fokusområder lenger unna i dokumentet.\"},{name:\"Hjelp for tilgjengelighet\",legend:\"Trykk ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/nl.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"nl\",{title:\"Toegankelijkheidsinstructies\",contents:\"Help inhoud. Druk op ESC om dit dialoog te sluiten.\",legend:[{name:\"Algemeen\",items:[{name:\"Werkbalk tekstverwerker\",legend:\"Druk op ${toolbarFocus} om naar de werkbalk te navigeren. Om te schakelen naar de volgende en vorige werkbalkgroep, gebruik TAB en SHIFT+TAB. Om te schakelen naar de volgende en vorige werkbalkknop, gebruik de PIJL RECHTS en PIJL LINKS. Druk op SPATIE of ENTER om een werkbalkknop te activeren.\"},\n{name:\"Dialoog tekstverwerker\",legend:\"In een dialoogvenster, druk op TAB om te navigeren naar het volgende veld. Druk op SHIFT+TAB om naar het vorige veld te navigeren. Druk op ENTER om het dialoogvenster te verzenden. Druk op ESC om het dialoogvenster te sluiten. Voor dialoogvensters met meerdere tabbladen, druk op ALT+F10 om naar de tabset te navigeren. Schakel naar het volgende tabblad met TAB of PIJL RECHTS. Schakel naar het vorige tabblad met SHIFT+TAB of PIJL LINKS. Druk op SPATIE of ENTER om het tabblad te selecteren.\"},\n{name:\"Contextmenu tekstverwerker\",legend:\"Druk op ${contextMenu} of APPLICATION KEY om het contextmenu te openen. Schakel naar de volgende menuoptie met TAB of PIJL OMLAAG. Schakel naar de vorige menuoptie met SHIFT+TAB of PIJL OMHOOG. Druk op SPATIE of ENTER om een menuoptie te selecteren. Op een submenu van de huidige optie met SPATIE, ENTER of PIJL RECHTS. Ga terug naar de bovenliggende menuoptie met ESC of PIJL LINKS. Sluit het contextmenu met ESC.\"},{name:\"Keuzelijst tekstverwerker\",legend:\"In een keuzelijst, schakel naar het volgende item met TAB of PIJL OMLAAG. Schakel naar het vorige item met SHIFT+TAB of PIJL OMHOOG. Druk op SPATIE of ENTER om het item te selecteren. Druk op ESC om de keuzelijst te sluiten.\"},\n{name:\"Elementenpad werkbalk tekstverwerker\",legend:\"Druk op ${elementsPathFocus} om naar het elementenpad te navigeren. Om te schakelen naar het volgende element, gebruik TAB of PIJL RECHTS. Om te schakelen naar het vorige element, gebruik SHIFT+TAB or PIJL LINKS. Druk op SPATIE of ENTER om een element te selecteren in de tekstverwerker.\"}]},{name:\"Opdrachten\",items:[{name:\"Ongedaan maken opdracht\",legend:\"Druk op ${undo}\"},{name:\"Opnieuw uitvoeren opdracht\",legend:\"Druk op ${redo}\"},{name:\"Vetgedrukt opdracht\",\nlegend:\"Druk op ${bold}\"},{name:\"Cursief opdracht\",legend:\"Druk op ${italic}\"},{name:\"Onderstrepen opdracht\",legend:\"Druk op ${underline}\"},{name:\"Link opdracht\",legend:\"Druk op ${link}\"},{name:\"Werkbalk inklappen opdracht\",legend:\"Druk op ${toolbarCollapse}\"},{name:\"Ga naar vorige focus spatie commando\",legend:\"Druk ${accessPreviousSpace} om toegang te verkrijgen tot de dichtstbijzijnde onbereikbare focus spatie voor de caret, bijvoorbeeld: twee aangrenzende HR elementen. Herhaal de toetscombinatie om de verste focus spatie te bereiken.\"},\n{name:\"Ga naar volgende focus spatie commando\",legend:\"Druk ${accessNextSpace} om toegang te verkrijgen tot de dichtstbijzijnde onbereikbare focus spatie na de caret, bijvoorbeeld: twee aangrenzende HR elementen. Herhaal de toetscombinatie om de verste focus spatie te bereiken.\"},{name:\"Toegankelijkheidshulp\",legend:\"Druk op ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/no.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"no\",{title:\"Instruksjoner for tilgjengelighet\",contents:\"Innhold for hjelp. Trykk ESC for å lukke denne dialogen.\",legend:[{name:\"Generelt\",items:[{name:\"Verktøylinje for editor\",legend:\"Trykk ${toolbarFocus} for å navigere til verktøylinjen. Flytt til neste og forrige verktøylinjegruppe med TAB og SHIFT-TAB. Flytt til neste og forrige verktøylinjeknapp med HØYRE PILTAST og VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å aktivere verktøylinjeknappen.\"},{name:\"Dialog for editor\",\nlegend:\"Mens du er i en dialog, trykk TAB for å navigere til neste dialogfelt, press SHIFT + TAB for å flytte til forrige felt, trykk ENTER for å akseptere dialogen, trykk ESC for å avbryte dialogen. For dialoger med flere faner, trykk ALT + F10 for å navigere til listen over faner. Gå til neste fane med TAB eller HØYRE PILTAST. Gå til forrige fane med SHIFT + TAB eller VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å velge fanen.\"},{name:\"Kontekstmeny for editor\",legend:\"Trykk ${contextMenu} eller MENYKNAPP for å åpne kontekstmeny. Gå til neste alternativ i menyen med TAB eller PILTAST NED. Gå til forrige alternativ med SHIFT+TAB eller PILTAST OPP. Trykk MELLOMROM eller ENTER for å velge menyalternativet. Åpne undermenyen på valgt alternativ med MELLOMROM eller ENTER eller HØYRE PILTAST. Gå tilbake til overordnet menyelement med ESC eller VENSTRE PILTAST. Lukk kontekstmenyen med ESC.\"},\n{name:\"Listeboks for editor\",legend:\"I en listeboks, gå til neste alternativ i listen med TAB eller PILTAST NED. Gå til forrige alternativ i listen med SHIFT + TAB eller PILTAST OPP. Trykk MELLOMROM eller ENTER for å velge alternativet i listen. Trykk ESC for å lukke listeboksen.\"},{name:\"Verktøylinje for elementsti\",legend:\"Trykk ${elementsPathFocus} for å navigere til verktøylinjen som viser elementsti. Gå til neste elementknapp med TAB eller HØYRE PILTAST. Gå til forrige elementknapp med SHIFT+TAB eller VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å velge elementet i editoren.\"}]},\n{name:\"Kommandoer\",items:[{name:\"Angre\",legend:\"Trykk ${undo}\"},{name:\"Gjør om\",legend:\"Trykk ${redo}\"},{name:\"Fet tekst\",legend:\"Trykk ${bold}\"},{name:\"Kursiv tekst\",legend:\"Trykk ${italic}\"},{name:\"Understreking\",legend:\"Trykk ${underline}\"},{name:\"Link\",legend:\"Trykk ${link}\"},{name:\"Skjul verktøylinje\",legend:\"Trykk ${toolbarCollapse}\"},{name:\"Gå til forrige fokusområde\",legend:\"Trykk ${accessPreviousSpace} for å komme til nærmeste fokusområde før skrivemarkøren som ikke kan nås på vanlig måte, for eksempel to tilstøtende HR-elementer. Gjenta tastekombinasjonen for å komme til fokusområder lenger unna i dokumentet.\"},\n{name:\"Gå til neste fokusområde\",legend:\"Trykk ${accessNextSpace} for å komme til nærmeste fokusområde etter skrivemarkøren som ikke kan nås på vanlig måte, for eksempel to tilstøtende HR-elementer. Gjenta tastekombinasjonen for å komme til fokusområder lenger unna i dokumentet.\"},{name:\"Hjelp for tilgjengelighet\",legend:\"Trykk ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/pl.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"pl\",{title:\"Instrukcje dotyczące dostępności\",contents:\"Zawartość pomocy. Wciśnij ESC, aby zamknąć to okno.\",legend:[{name:\"Informacje ogólne\",items:[{name:\"Pasek narzędzi edytora\",legend:\"Wciśnij ${toolbarFocus} aby przejść do paska narzędzi. Przejdź do następnej i poprzedniej grupy narzędzi używając TAB oraz SHIFT-TAB. Przejdź do następnego i poprzedniego narzędzia używając STRZAŁKI W PRAWO lub STRZAŁKI W LEWO. Wciśnij SPACJĘ lub ENTER, aby aktywować zaznaczone narzędzie.\"},\n{name:\"Okno dialogowe edytora\",legend:\"Będąc w oknie dialogowym wciśnij TAB aby przejść do następnego pola dialogowego, wciśnij SHIFT + TAB aby przejść do poprzedniego pola, wciśnij ENTER aby wysłać dialog, wciśnij ESC aby anulować dialog. Dla okien dialogowych z wieloma zakładkami, wciśnij ALT + F10 aby przejść do listy zakładek. Gdy to zrobisz przejdź do następnej zakładki wciskając TAB lub STRZAŁKĘ W PRAWO. Przejdź do poprzedniej zakładki wciskając SHIFT + TAB lub STRZAŁKĘ W LEWO. Wciśnij SPACJĘ lub ENTER aby wybrać zakładkę.\"},\n{name:\"Menu kontekstowe edytora\",legend:\"Wciśnij ${contextMenu} lub PRZYCISK APLIKACJI aby otworzyć menu kontekstowe. Przejdź do następnej pozycji menu wciskając TAB lub STRZAŁKĘ W DÓŁ. Przejdź do poprzedniej pozycji menu wciskając SHIFT + TAB lub STRZAŁKĘ W GÓRĘ. Wciśnij SPACJĘ lub ENTER aby wygrać pozycję menu. Otwórz pod-menu obecnej pozycji wciskając SPACJĘ lub ENTER lub STRZAŁKĘ W PRAWO. Wróć do pozycji nadrzędnego menu wciskając ESC lub STRZAŁKĘ W LEWO. Zamknij menu wciskając ESC.\"},{name:\"Lista w edytorze\",\nlegend:\"W polu listy możesz przechodzić do następnego elementu za pomocą klawisza TAB lub STRZAŁKI W DÓŁ. Poprzedni element osiągniesz za pomocą SHIFT+TAB lub STRZAŁKI W GÓRĘ. Za pomocą SPACJI lub ENTERA wybierzesz daną opcję z listy, a za pomocą klawisza ESC opuścisz listę.\"},{name:\"Pasek ścieżki elementów edytora\",legend:\"Naciśnij ${elementsPathFocus} w celu przejścia do paska ścieżki elementów edytora. W celu przejścia do kolejnego elementu naciśnij klawisz Tab lub Strzałki w prawo. W celu przejścia do poprzedniego elementu naciśnij klawisze Shift+Tab lub Strzałki w lewo. By wybrać element w edytorze, użyj klawisza Spacji lub Enter.\"}]},\n{name:\"Polecenia\",items:[{name:\"Polecenie Cofnij\",legend:\"Naciśnij ${undo}\"},{name:\"Polecenie Ponów\",legend:\"Naciśnij ${redo}\"},{name:\"Polecenie Pogrubienie\",legend:\"Naciśnij ${bold}\"},{name:\"Polecenie Kursywa\",legend:\"Naciśnij ${italic}\"},{name:\"Polecenie Podkreślenie\",legend:\"Naciśnij ${underline}\"},{name:\"Polecenie Wstaw/ edytuj odnośnik\",legend:\"Naciśnij ${link}\"},{name:\"Polecenie schowaj pasek narzędzi\",legend:\"Naciśnij ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\"Pomoc dotycząca dostępności\",legend:\"Naciśnij ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/pt-br.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"pt-br\",{title:\"Instruções de Acessibilidade\",contents:\"Conteúdo da Ajuda. Para fechar este diálogo pressione ESC.\",legend:[{name:\"Geral\",items:[{name:\"Barra de Ferramentas do Editor\",legend:\"Pressione ${toolbarFocus} para navegar para a barra de ferramentas. Mova para o anterior ou próximo grupo de ferramentas com TAB e SHIFT-TAB. Mova para o anterior ou próximo botão com SETA PARA DIREITA or SETA PARA ESQUERDA. Pressione ESPAÇO ou ENTER para ativar o botão da barra de ferramentas.\"},\n{name:\"Diálogo do Editor\",legend:\"Dentro de um diálogo, pressione TAB para navegar para o próximo campo, pressione SHIFT + TAB para mover para o campo anterior, pressione ENTER para enviar o diálogo, pressione ESC para cancelar o diálogo. Para diálogos que tem múltiplas abas, pressione ALT + F10 para navegar para a lista de abas, então mova para a próxima aba com SHIFT + TAB ou SETA PARA ESQUERDA. Pressione ESPAÇO ou ENTER para selecionar a aba.\"},{name:\"Menu de Contexto do Editor\",legend:\"Pressione ${contextMenu} ou TECLA DE MENU para abrir o menu de contexto, então mova para a próxima opção com TAB ou SETA PARA BAIXO. Mova para a anterior com SHIFT+TAB ou SETA PARA CIMA. Pressione ESPAÇO ou ENTER para selecionar a opção do menu. Abra o submenu da opção atual com ESPAÇO ou ENTER ou SETA PARA DIREITA. Volte para o menu pai com ESC ou SETA PARA ESQUERDA. Feche o menu de contexto com ESC.\"},\n{name:\"Caixa de Lista do Editor\",legend:\"Dentro de uma caixa de lista, mova para o próximo item com TAB ou SETA PARA BAIXO. Mova para o item anterior com SHIFT + TAB ou SETA PARA CIMA. Pressione ESPAÇO ou ENTER para selecionar uma opção na lista. Pressione ESC para fechar a caixa de lista.\"},{name:\"Barra de Caminho do Elementos do Editor\",legend:\"Pressione ${elementsPathFocus} para a barra de caminho dos elementos. Mova para o próximo botão de elemento com TAB ou SETA PARA DIREITA. Mova para o botão anterior com  SHIFT+TAB ou SETA PARA ESQUERDA. Pressione ESPAÇO ou ENTER para selecionar o elemento no editor.\"}]},\n{name:\"Comandos\",items:[{name:\" Comando Desfazer\",legend:\"Pressione ${undo}\"},{name:\" Comando Refazer\",legend:\"Pressione ${redo}\"},{name:\" Comando Negrito\",legend:\"Pressione ${bold}\"},{name:\" Comando Itálico\",legend:\"Pressione ${italic}\"},{name:\" Comando Sublinhado\",legend:\"Pressione ${underline}\"},{name:\" Comando Link\",legend:\"Pressione ${link}\"},{name:\" Comando Fechar Barra de Ferramentas\",legend:\"Pressione ${toolbarCollapse}\"},{name:\"Acessar o comando anterior de spaço de foco\",legend:\"Pressione ${accessNextSpace} para acessar o espaço de foco não alcançável mais próximo antes do cursor, por exemplo: dois elementos HR adjacentes. Repita a combinação de teclas para alcançar espaços de foco distantes.\"},\n{name:\"Acessar próximo fomando de spaço de foco\",legend:\"Pressione ${accessNextSpace} para acessar o espaço de foco não alcançável mais próximo após o cursor, por exemplo: dois elementos HR adjacentes. Repita a combinação de teclas para alcançar espaços de foco distantes.\"},{name:\" Ajuda de Acessibilidade\",legend:\"Pressione ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/pt.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"pt\",{title:\"Instruções de Acessibilidade\",contents:\"Conteúdos da Ajuda. Pressione em 'ESC' para fechar esta janela.\",legend:[{name:\"Geral\",items:[{name:\"Barra de Ferramentas do Editor\",legend:\"Clique em ${toolbarFocus} para navegar para a barra de ferramentas. Vá para o grupo da barra de ferramentas anterior e seguinte com TAB e SHIFT+TAB. Vá para o botão da barra de ferramentas anterior com a SETA DIREITA ou ESQUERDA. Pressione ESPAÇO ou ENTER para ativar o botão da barra de ferramentas.\"},\n{name:\"Janela do Editor\",legend:\"Dentro de uma janela, pressione TAB para navigar para o campo da janela seguinte, pressione SHIFT + TAB para mover para o campo anterior, pressione ENTER para submeter a janela, pressione ESC para cancelar a janela. Para as janelas que têm múltiplos páginas com separadores, pressione ALT + F10 para navegar para a lista do separador. Depois mova para o seguinte separador com TAB ou SETA DIREITA. Mover para o separador anterior com SHIFT + TAB ou SETA ESQUERDA. Pressione ESPAÇO ou ENTER para selecionar o separador da página.\"},\n{name:\"Menu de Contexto do Editor\",legend:\"Clique em ${contextMenu} ou TECLA APLICAÇÃO para abrir o menu de contexto. Depois vá para a opção do menu seguinte com TAB ou SETA PARA BAIXO. Vá para a opção anterior com  SHIFT+TAB ou SETA PARA CIMA. Pressione ESPAÇO ou ENTER para selecionar a opção do menu.  Abra o submenu da opção atual com ESPAÇO, ENTER ou SETA DIREITA. GVá para o item do menu parente  com ESC ou SETA ESQUERDA. Feche o menu de contexto com ESC.\"},{name:\"Caixa Lista Editor\",legend:\"Dentro da caixa da lista, vá para o itemda lista seguinte com TAB ou SETA PARA BAIXO. Move Vá parao item da lista anterior com SHIFT+TAB ou SETA PARA BAIXO. Pressione ESPAÇO ou ENTER para selecionar a opção da lista. Pressione ESC para fechar a caisa da lista.\"},\n{name:\"Caminho Barra Elemento Editor\",legend:\"Clique em ${elementsPathFocus} para navegar para a barra do caminho dos elementos. Vá para o botão do elemento seguinte com TAB ou SETA DIREITA. Vá para o botão anterior com   SHIFT+TAB ou SETA ESQUERDA. Pressione ESPAÇO ou ENTER para selecionar o elemento no editor.\"}]},{name:\"Comandos\",items:[{name:\"Comando de Anular\",legend:\"Pressione ${undo}\"},{name:\"Comando de Refazer\",legend:\"Pressione ${redo}\"},{name:\"Comando de Negrito\",legend:\"Pressione ${bold}\"},\n{name:\"Comando de Itálico\",legend:\"Pressione ${italic}\"},{name:\"Comando de Sublinhado\",legend:\"Pressione ${underline}\"},{name:\"Comando de Hiperligação\",legend:\"Pressione ${link}\"},{name:\"Comando de Ocultar Barra de Ferramentas\",legend:\"Pressione ${toolbarCollapse}\"},{name:\"Acesso comando do espaço focus anterior\",legend:\"Clique em ${accessPreviousSpace} para aceder ao espaço do focos inalcançável mais perto antes do sinal de omissão, por exemplo: dois elementos HR adjacentes. Repetir a combinação da chave para alcançar os espaços dos focos distantes.\"},\n{name:\"Acesso comando do espaço focus seguinte\",legend:\"Pressione ${accessNextSpace} para aceder ao espaço do focos inalcançável mais perto depois do sinal de omissão, por exemplo: dois elementos HR adjacentes. Repetir a combinação da chave para alcançar os espaços dos focos distantes.\"},{name:\"Ajuda de Acessibilidade\",legend:\"Pressione ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ro.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"ro\",{title:\"Instrucțiuni de accesibilitate\",contents:\"Cuprins. Pentru a închide acest dialog, apăsați tasta ESC.\",legend:[{name:\"General\",items:[{name:\"Editează bara.\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Dialog editor\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor meniu contextual\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Commands\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ru.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"ru\",{title:\"Горячие клавиши\",contents:\"Помощь. Для закрытия этого окна нажмите ESC.\",legend:[{name:\"Основное\",items:[{name:\"Панель инструментов\",legend:\"Нажмите ${toolbarFocus} для перехода к панели инструментов. Для перемещения между группами панели инструментов используйте TAB и SHIFT-TAB. Для перемещения между кнопками панели иструментов используйте кнопки ВПРАВО или ВЛЕВО. Нажмите ПРОБЕЛ или ENTER для запуска кнопки панели инструментов.\"},{name:\"Диалоги\",legend:\"В диалоговом окне, нажмите клавишу TAB для перехода к следующему диалоговому полю, нажмите клавиши SHIFT + TAB, чтобы перейти к предыдущему полю, нажмите ENTER, чтобы отправить данные, нажмите клавишу ESC, для отмены. Для окон, которые имеют несколько вкладок, нажмите ALT + F10 для перехода к списку вкладок. Переход к следующей вкладке TAB ИЛИ ПРАВУЮ СТРЕЛКУ. Переход к предыдущей вкладке с помощью SHIFT + TAB или ЛЕВАЯ СТРЕЛКА. Нажмите ПРОБЕЛ или ENTER, чтобы выбрать вкладку.\"},\n{name:\"Контекстное меню\",legend:'Нажмите ${contextMenu} или клавишу APPLICATION, чтобы открыть контекстное меню. Затем перейдите к следующему пункту меню с помощью TAB или стрелкой \"ВНИЗ\". Переход к предыдущей опции - SHIFT+TAB или стрелкой \"ВВЕРХ\". Нажмите SPACE, или ENTER, чтобы задействовать опцию меню. Открыть подменю текущей опции - SPACE или ENTER или стрелкой \"ВПРАВО\". Возврат к родительскому пункту меню - ESC или стрелкой \"ВЛЕВО\". Закрытие контекстного меню - ESC.'},{name:\"Редактор списка\",\nlegend:'Внутри окна списка, переход к следующему пункту списка - TAB или стрелкой \"ВНИЗ\". Переход к предыдущему пункту списка - SHIFT + TAB или стрелкой \"ВВЕРХ\". Нажмите SPACE, или ENTER, чтобы задействовать опцию списка. Нажмите ESC, чтобы закрыть окно списка.'},{name:\"Путь к элементу\",legend:'Нажмите ${elementsPathFocus}, чтобы перейти к панели пути элементов. Переход к следующей кнопке элемента - TAB или стрелкой \"ВПРАВО\". Переход к предыдущей кнопку - SHIFT+TAB или стрелкой \"ВЛЕВО\". Нажмите SPACE, или ENTER, чтобы выбрать элемент в редакторе.'}]},\n{name:\"Команды\",items:[{name:\"Отменить\",legend:\"Нажмите ${undo}\"},{name:\"Повторить\",legend:\"Нажмите ${redo}\"},{name:\"Полужирный\",legend:\"Нажмите ${bold}\"},{name:\"Курсив\",legend:\"Нажмите ${italic}\"},{name:\"Подчеркнутый\",legend:\"Нажмите ${underline}\"},{name:\"Гиперссылка\",legend:\"Нажмите ${link}\"},{name:\"Свернуть панель инструментов\",legend:\"Нажмите ${toolbarCollapse}\"},{name:\"Команды доступа к предыдущему фокусному пространству\",legend:'Нажмите ${accessPreviousSpace}, чтобы обратиться к ближайшему недостижимому фокусному пространству перед символом \"^\", например: два смежных HR элемента. Повторите комбинацию клавиш, чтобы достичь отдаленных фокусных пространств.'},\n{name:\"Команды доступа к следующему фокусному пространству\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\"Справка по горячим клавишам\",legend:\"Нажмите ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/si.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"si\",{title:\"ළඟා වියහැකි \",contents:\"උදව් සඳහා අන්තර්ගතය.නික්මයෙමට ESC බොත්තම ඔබන්න\",legend:[{name:\"පොදු කරුණු\",items:[{name:\"සංස්කරණ මෙවලම් \",legend:\"ඔබන්න ${මෙවලම් තීරු අවධානය} මෙවලම් තීරුවේ එහා මෙහා යෑමට.ඉදිරියට යෑමට හා ආපසු යෑමට මෙවලම් තීරුකාණ්ඩය හා TAB හා SHIFT-TAB .ඉදිරියට යෑමට හා ආපසු යෑමට මෙවලම් තීරු බොත්තම සමග RIGHT ARROW හෝ LEFT ARROW.මෙවලම් තීරු බොත්තම සක්‍රිය කර ගැනීමට  SPACE හෝ  ENTER බොත්තම ඔබන්න.\"},{name:\"සංස්කරණ \",legend:\"දෙබසක් තුළ, ඊළඟ දෙබස් පෙදෙසට යෑමට TAB බොත්තම ඔබන්න, කලින් පෙදෙසට යෑමට SHIFT + TAB බොත්තම ද, දෙබස් ඉදිරිපත් කිරීමට ENTER බොත්තම ද, දෙබස් නැවතීමට  ESCබොත්තම ද, දෙබස් සහිත ගොනු, පිටු වැඩි සංක්‍යයාවක් ලබා ගෙනිමට,ගොනු තුළ එහාමෙහා යෑමට ALT + F10 බොත්තම් ද, ඊළඟ ගොනුවට යෑමට TAB හෝ RIGTH ARROW බොත්තම ඔබන්න. පෙර ගොනුවට යෑමට SHIFT + TAB හෝ LEFT ARROW බොත්තම් ද ,ගොනු පිටු තේරීමට  SPACE හෝ ENTER බොත්තම් ද ඔබන්න.\"},\n{name:\"සංස්කරණ අඩංගුවට \",legend:\"ඔබන්න ${අන්තර්ගත මෙනුව} හෝ  APPLICATION KEY  අන්තර්ගත-මෙනුව විවුරතකිරීමට. ඊළඟ මෙනුව-ව්කල්පයන්ට යෑමට TAB හෝ DOWN ARROW බොත්තම ද, පෙර විකල්පයන්ටයෑමට SHIFT+TAB හෝ  UP ARROW බොත්තම ද, මෙනුව-ව්කල්පයන් තේරීමට SPACE හෝ ENTER බොත්තම ද,  දැනට විවුර්තව ඇති උප-මෙනුවක වීකල්ප තේරීමට SPACE හෝ ENTER හෝ RIGHT ARROW ද, නැවත පෙර ප්‍රධාන මෙනුවට යෑමට  ESC හෝ LEFT ARROW බොත්තම ද.  අන්තර්ගත-මෙනුව වැසීමට  ESC බොත්තම ද ඔබන්න.\"},{name:\"සංස්කරණ තේරුම් \",legend:\"තේරුම් කොටුව තුළ , ඊළඟ අයිතමයට යෑමට TAB හෝ DOWN ARROW , පෙර අයිතමයට යෑමට  SHIFT + TAB හෝ UP ARROW . අයිතම විකල්පයන් තේරීමට  SPACE හෝ  ENTER ,තේරුම් කොටුව වැසීමට ESC බොත්තම් ද ඔබන්න.\"},\n{name:\"සංස්කරණ අංග සහිත \",legend:\"ඔබන්න ${මෙවලම් තීරු අවධානය} මෙවලම් තීරුවේ එහා මෙහා යෑමට.ඉදිරියට යෑමට හා ආපසු යෑමට මෙවලම් තීරුකාණ්ඩය හා TAB හා SHIFT-TAB .ඉදිරියට යෑමට හා ආපසු යෑමට මෙවලම් තීරු බොත්තම සමග RIGHT ARROW හෝ LEFT ARROW.මෙවලම් තීරු බොත්තම සක්‍රිය කර ගැනීමට  SPACE හෝ  ENTER බොත්තම ඔබන්න.\"}]},{name:\"විධාන\",items:[{name:\"විධානය වෙනස් \",legend:\"ඔබන්න ${වෙනස් කිරීම}\"},{name:\"විධාන නැවත් පෙර පරිදිම වෙනස්කර ගැනීම.\",legend:\"ඔබන්න ${නැවත් පෙර පරිදිම වෙනස්කර ගැනීම}\"},{name:\"තද අකුරින් විධාන\",legend:\"ඔබන්න ${තද }\"},\n{name:\"බැධී අකුරු විධාන\",legend:\"ඔබන්න ${බැධී අකුරු }\"},{name:\"යටින් ඉරි ඇද ඇති විධාන.\",legend:\"ඔබන්න ${යටින් ඉරි ඇද ඇති}\"},{name:\"සම්බන්ධිත විධාන\",legend:\"ඔබන්න ${සම්බන්ධ }\"},{name:\"මෙවලම් තීරු හැකුලුම් විධාන\",legend:\"ඔබන්න ${මෙවලම් තීරු හැකුලුම් }\"},{name:\"යොමුවීමට පෙර  වැදගත්  විධාන\",legend:\"ඔබන්න ${යොමුවීමට ඊළඟ }\"},{name:\"යොමුවීමට ඊළග වැදගත්  විධාන\",legend:\"ඔබන්න ${යොමුවීමට ඊළඟ }\"},{name:\"ප්‍රවේශ \",legend:\"ඔබන්න  ${a11y }\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/sk.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"sk\",{title:\"Inštrukcie prístupnosti\",contents:\"Pomocný obsah. Pre zatvorenie tohto okna, stlačte ESC.\",legend:[{name:\"Všeobecne\",items:[{name:\"Lišta nástrojov editora\",legend:\"Stlačte ${toolbarFocus} pre navigáciu na lištu nástrojov. Medzi ďalšou a predchádzajúcou lištou nástrojov sa pohybujete s TAB a SHIFT-TAB. Medzi ďalším a predchádzajúcim tlačidlom na lište nástrojov sa pohybujete s pravou šípkou a ľavou šípkou. Stlačte medzerník alebo ENTER pre aktiváciu tlačidla lišty nástrojov.\"},\n{name:\"Editorový dialóg\",legend:\"V dialogu, stlačte TAB pre navigáciu na ďalšie dialógové pole, stlačte STIFT + TAB pre presun na predchádzajúce pole, stlačte ENTER pre odoslanie dialógu, stlačte ESC pre zrušenie dialógu. Pre dialógy, ktoré majú viac záložiek, stlačte ALT + F10 pre navigácou do zoznamu záložiek. Potom sa posúvajte k ďalšej žáložke pomocou TAB alebo pravou šípkou. Pre presun k predchádzajúcej záložke, stlačte SHIFT + TAB alebo ľavú šípku. Stlačte medzerník alebo ENTER pre vybranie záložky.\"},\n{name:\"Editorové kontextové menu\",legend:\"Stlačte ${contextMenu} alebo APPLICATION KEY pre otvorenie kontextového menu. Potom sa presúvajte na ďalšie možnosti menu s TAB alebo dolnou šípkou. Presunte sa k predchádzajúcej možnosti s SHIFT + TAB alebo hornou šípkou. Stlačte medzerník alebo ENTER pre výber možnosti menu. Otvorte pod-menu danej možnosti s medzerníkom, alebo ENTER, alebo pravou šípkou. Vráťte sa späť do položky rodičovského menu s ESC alebo ľavou šípkou. Zatvorte kontextové menu s ESC.\"},\n{name:\"Editorov box zoznamu\",legend:\"V boxe zoznamu, presuňte sa na ďalšiu položku v zozname s TAB alebo dolnou šípkou. Presuňte sa k predchádzajúcej položke v zozname so SHIFT + TAB alebo hornou šípkou. Stlačte medzerník alebo ENTER pre výber možnosti zoznamu. Stlačte ESC pre zatvorenie boxu zoznamu.\"},{name:\"Editorove pásmo cesty prvku\",legend:\"Stlačte ${elementsPathFocus} pre navigovanie na pásmo cesty elementu. Presuňte sa na tlačidlo ďalšieho prvku s TAB alebo pravou šípkou. Presuňte sa k predchádzajúcemu tlačidlu s SHIFT + TAB alebo ľavou šípkou. Stlačte medzerník alebo ENTER pre výber prvku v editore.\"}]},\n{name:\"Príkazy\",items:[{name:\"Vrátiť príkazy\",legend:\"Stlačte ${undo}\"},{name:\"Nanovo vrátiť príkaz\",legend:\"Stlačte ${redo}\"},{name:\"Príkaz na stučnenie\",legend:\"Stlačte ${bold}\"},{name:\"Príkaz na kurzívu\",legend:\"Stlačte ${italic}\"},{name:\"Príkaz na podčiarknutie\",legend:\"Stlačte ${underline}\"},{name:\"Príkaz na odkaz\",legend:\"Stlačte ${link}\"},{name:\"Príkaz na zbalenie lišty nástrojov\",legend:\"Stlačte ${toolbarCollapse}\"},{name:\"Prejsť na predchádzajúcu zamerateľnú medzeru príkazu\",legend:\"Stlačte ${accessPreviousSpace} pre prístup na najbližšie nedosiahnuteľné zamerateľné medzery pred vsuvkuo. Napríklad: dve za sebou idúce horizontálne čiary. Opakujte kombináciu klávesov pre dosiahnutie vzdialených zamerateľných medzier.\"},\n{name:\"Prejsť na ďalší \",legend:\"Stlačte ${accessNextSpace} pre prístup na najbližšie nedosiahnuteľné zamerateľné medzery po vsuvke. Napríklad: dve za sebou idúce horizontálne čiary. Opakujte kombináciu klávesov pre dosiahnutie vzdialených zamerateľných medzier.\"},{name:\"Pomoc prístupnosti\",legend:\"Stlačte ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/sl.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"sl\",{title:\"Navodila Dostopnosti\",contents:\"Vsebina Pomoči. Če želite zapreti to pogovorno okno pritisnite ESC.\",legend:[{name:\"Splošno\",items:[{name:\"Urejevalna Orodna Vrstica\",legend:\"Pritisnite ${toolbarFocus} za pomik v orodno vrstico. Z TAB in SHIFT-TAB se pomikate na naslednjo in prejšnjo skupino orodne vrstice. Z DESNO PUŠČICO ali LEVO PUŠČICO se pomikate na naslednji in prejšnji gumb orodne vrstice. Pritisnite SPACE ali ENTER, da aktivirate gumb orodne vrstice.\"},\n{name:\"Urejevalno Pogovorno Okno\",legend:\"Znotraj pogovornega okna, pritisnite tipko TAB za pomik na naslednjo pogovorno polje, pritisnite SHIFT + TAB za pomik v prejšnje polje, pritisnite tipko ENTER za predložitev pogovornega okna, pritisnite tipko ESC, da prekličete okno. Za okna, ki imajo več zavihkov, pritisnite ALT + F10, da pojdete na seznam zavihkov. Na naslednji zavihek se premaknete s tipko TAB ali DESNO PUŠČICO. Z SHIFT + TAB ali LEVO PUŠČICO pa se premaknete na prejšnji zavihek. Pritisnite tipko SPACE ali ENTER za izbiro zavihka.\"},\n{name:\"Urejevalni Kontekstni Meni\",legend:\"Pritisnite ${contextMenu} ali APPLICATION KEY, da odprete kontekstni meni. Nato se premaknite na naslednjo možnost menija s tipko TAB ali PUŠČICA DOL. Premakniti se na prejšnjo možnost z SHIFT + TAB ali PUŠČICA GOR. Pritisnite SPACE ali ENTER za izbiro možnosti menija. Odprite podmeni trenutne možnosti menija s tipko SPACE ali ENTER ali DESNA PUŠČICA. Vrnite se na matični element menija s tipko ESC ali LEVA PUŠČICA. Zaprite kontekstni meni z ESC.\"},{name:\"Urejevalno Seznamsko Polje\",\nlegend:\"Znotraj seznama, se premaknete na naslednji element seznama s tipko TAB ali PUŠČICO DOL. Z SHIFT + TAB ali PUŠČICO GOR se premaknete na prejšnji element seznama. Pritisnite tipko SPACE ali ENTER za izbiro elementa. Pritisnite tipko ESC, da zaprete seznam.\"},{name:\"Urejevalna vrstica poti elementa\",legend:\"Pritisnite ${elementsPathFocus} za pomikanje po vrstici elementnih poti. S TAB ali DESNA PUŠČICA se premaknete na naslednji gumb elementa. Z SHIFT + TAB ali LEVO PUŠČICO se premaknete na prejšnji gumb elementa. Pritisnite SPACE ali ENTER za izbiro elementa v urejevalniku.\"}]},\n{name:\"Ukazi\",items:[{name:\"Razveljavi ukaz\",legend:\"Pritisnite ${undo}\"},{name:\"Ponovi ukaz\",legend:\"Pritisnite ${redo}\"},{name:\"Krepki ukaz\",legend:\"Pritisnite ${bold}\"},{name:\"Ležeči ukaz\",legend:\"Pritisnite ${italic}\"},{name:\"Poudarni ukaz\",legend:\"Pritisnite ${underline}\"},{name:\"Ukaz povezave\",legend:\"Pritisnite ${link}\"},{name:\"Skrči Orodno Vrstico Ukaz\",legend:\"Pritisnite ${toolbarCollapse}\"},{name:\"Dostop do prejšnjega ukaza ostrenja\",legend:\"Pritisnite ${accessPreviousSpace} za dostop do najbližjega nedosegljivega osredotočenega prostora pred strešico, npr.: dva sosednja HR elementa. Ponovite kombinacijo tipk, da dosežete oddaljene osredotočene prostore.\"},\n{name:\"Dostop do naslednjega ukaza ostrenja\",legend:\"Pritisnite ${accessNextSpace} za dostop do najbližjega nedosegljivega osredotočenega prostora po strešici, npr.: dva sosednja HR elementa. Ponovite kombinacijo tipk, da dosežete oddaljene osredotočene prostore.\"},{name:\"Pomoč Dostopnosti\",legend:\"Pritisnite ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/sq.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"sq\",{title:\"Udhëzimet e Qasjes\",contents:\"Përmbajtja ndihmëse. Për ta mbyllur dialogun shtyp ESC.\",legend:[{name:\"Të përgjithshme\",items:[{name:\"Shiriti i Redaktuesit\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Dialogu i Redaktuesit\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Komandat\",items:[{name:\"Rikthe komandën\",legend:\"Shtyp ${undo}\"},{name:\"Ribëj komandën\",legend:\"Shtyp ${redo}\"},{name:\"Komanda e trashjes së tekstit\",legend:\"Shtyp ${bold}\"},{name:\"Komanda kursive\",legend:\"Shtyp ${italic}\"},\n{name:\"Komanda e nënvijëzimit\",legend:\"Shtyp ${underline}\"},{name:\"Komanda e Nyjes\",legend:\"Shtyp ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Shtyp ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\"Ndihmë Qasjeje\",legend:\"Shtyp ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/sr-latn.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"sr-latn\",{title:\"Accessibility Instructions\",contents:\"Help Contents. To close this dialog press ESC.\",legend:[{name:\"Opšte\",items:[{name:\"Editor Toolbar\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Editor Dialog\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Commands\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/sr.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"sr\",{title:\"Accessibility Instructions\",contents:\"Help Contents. To close this dialog press ESC.\",legend:[{name:\"Опште\",items:[{name:\"Editor Toolbar\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Editor Dialog\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"Commands\",items:[{name:\" Undo command\",legend:\"Press ${undo}\"},{name:\" Redo command\",legend:\"Press ${redo}\"},{name:\" Bold command\",legend:\"Press ${bold}\"},{name:\" Italic command\",legend:\"Press ${italic}\"},{name:\" Underline command\",\nlegend:\"Press ${underline}\"},{name:\" Link command\",legend:\"Press ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/sv.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"sv\",{title:\"Hjälpmedelsinstruktioner\",contents:\"Hjälpinnehåll. För att stänga denna dialogruta trycker du på ESC.\",legend:[{name:\"Allmänt\",items:[{name:\"Editor verktygsfält\",legend:\"Tryck på ${toolbarFocus} för att navigera till verktygsfältet. Flytta till nästa och föregående verktygsfältsgrupp med TAB och SHIFT-TAB. Flytta till nästa och föregående knapp i verktygsfältet med HÖGERPIL eller VÄNSTERPIL. Tryck Space eller ENTER för att aktivera knappen i verktygsfältet.\"},\n{name:\"Dialogeditor\",legend:\"Inuti en dialogruta, tryck TAB för att navigera till nästa fält i dialogrutan. Du trycker SKIFT + TAB för att flytta till föregående fält. Tryck ENTER för att skicka. Du avbryter och stänger dialogen med ESC. För dialogrutor som har flera flikar, tryck ALT + F10 navigera till fliklistan. Flytta sedan till nästa flik med HÖGERPIL. Flytta till föregående flik med SHIFT + TAB eller VÄNSTERPIL. Tryck Space eller ENTER för att välja fliken.\"},{name:\"Editor för innehållsmeny\",\nlegend:\"Tryck på $ {contextMenu} eller PROGRAMTANGENTEN för att öppna snabbmenyn. Flytta sedan till nästa menyalternativ med TAB eller NEDPIL. Flytta till föregående alternativ med SHIFT + TABB eller UPPIL. Tryck Space eller ENTER för att välja menyalternativ. Öppna undermeny av nuvarande alternativ med SPACE eller ENTER eller HÖGERPIL. Gå tillbaka till överordnade menyalternativ med ESC eller VÄNSTERPIL. Stäng snabbmenyn med ESC.\"},{name:\"Editor för List Box\",legend:\"Inuti en list-box, gå till nästa listobjekt med TAB eller NEDPIL. Flytta till föregående listobjekt med SHIFT + TAB eller UPPIL. Tryck Space eller ENTER för att välja listan alternativet. Tryck ESC för att stänga listan-boxen.\"},\n{name:\"Editor för elementens sökväg\",legend:\"Tryck på $ {elementsPathFocus} för att navigera till verktygsfältet för elementens sökvägar. Flytta till nästa elementknapp med TAB eller HÖGERPIL. Flytta till föregående knapp med SKIFT + TAB eller VÄNSTERPIL. Tryck Space eller ENTER för att välja element i redigeraren.\"}]},{name:\"Kommandon\",items:[{name:\"Kommandot ångra\",legend:\"Tryck på ${undo}\"},{name:\"Kommandot gör om\",legend:\"Tryck på ${redo}\"},{name:\"Kommandot fet stil\",legend:\"Tryck på ${bold}\"},\n{name:\"Kommandot kursiv\",legend:\"Tryck på ${italic}\"},{name:\"Kommandot understruken\",legend:\"Tryck på ${underline}\"},{name:\"kommandot länk\",legend:\"Tryck på ${link}\"},{name:\"Verktygsfält Dölj kommandot\",legend:\"Tryck på ${toolbarCollapse}\"},{name:\"Gå till föregående fokus plats\",legend:\"Tryck på ${accessPreviousSpace} för att gå till närmast onåbara utrymme före markören, exempel: två intilliggande HR element. Repetera tangentkombinationen för att gå till nästa.\"},{name:\"Tillgå nästa fokuskommandots utrymme\",\nlegend:\"Tryck ${accessNextSpace} på för att komma åt den närmaste onåbar fokus utrymme efter cirkumflex, till exempel: två intilliggande HR element. Upprepa tangentkombinationen för att nå avlägsna fokus utrymmen.\"},{name:\"Hjälp om tillgänglighet\",legend:\"Tryck ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/th.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"th\",{title:\"Accessibility Instructions\",contents:\"Help Contents. To close this dialog press ESC.\",legend:[{name:\"ทั่วไป\",items:[{name:\"แถบเครื่องมือสำหรับเครื่องมือช่วยพิมพ์\",legend:\"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT-TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.\"},{name:\"Editor Dialog\",legend:\"Inside a dialog, press TAB to navigate to next dialog field, press SHIFT + TAB to move to previous field, press ENTER to submit dialog, press ESC to cancel dialog. For dialogs that have multiple tab pages, press ALT + F10 to navigate to tab-list. Then move to next tab with TAB OR RIGTH ARROW. Move to previous tab with SHIFT + TAB or LEFT ARROW. Press SPACE or ENTER to select the tab page.\"},\n{name:\"Editor Context Menu\",legend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.\"},{name:\"Editor List Box\",legend:\"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT + TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.\"},\n{name:\"Editor Element Path Bar\",legend:\"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with  SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.\"}]},{name:\"คำสั่ง\",items:[{name:\"เลิกทำคำสั่ง\",legend:\"วาง ${undo}\"},{name:\"คำสั่งสำหรับทำซ้ำ\",legend:\"วาง ${redo}\"},{name:\"คำสั่งสำหรับตัวหนา\",legend:\"วาง ${bold}\"},{name:\"คำสั่งสำหรับตัวเอียง\",legend:\"วาง ${italic}\"},{name:\"คำสั่งสำหรับขีดเส้นใต้\",\nlegend:\"วาง ${underline}\"},{name:\"คำสั่งสำหรับลิงก์\",legend:\"วาง ${link}\"},{name:\" Toolbar Collapse command\",legend:\"Press ${toolbarCollapse}\"},{name:\" Access previous focus space command\",legend:\"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},{name:\" Access next focus space command\",legend:\"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.\"},\n{name:\" Accessibility Help\",legend:\"Press ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/tr.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"tr\",{title:\"Erişilebilirlik Talimatları\",contents:\"Yardım içeriği. Bu pencereyi kapatmak için ESC tuşuna basın.\",legend:[{name:\"Genel\",items:[{name:\"Düzenleyici Araç Çubuğu\",legend:\"Araç çubuğunda gezinmek için ${toolbarFocus} basın. TAB ve SHIFT-TAB ile önceki ve sonraki araç çubuğu grubuna taşıyın. SAĞ OK veya SOL OK ile önceki ve sonraki bir araç çubuğu düğmesini hareket ettirin. SPACE tuşuna basın veya araç çubuğu düğmesini etkinleştirmek için ENTER tuşna basın.\"},\n{name:\"Diyalog Düzenleyici\",legend:\"Dialog penceresi içinde, sonraki iletişim alanına gitmek için SEKME tuşuna basın, önceki alana geçmek için SHIFT + TAB tuşuna basın, pencereyi göndermek için ENTER tuşuna basın, dialog penceresini iptal etmek için ESC tuşuna basın. Birden çok sekme sayfaları olan diyalogların, sekme listesine gitmek için ALT + F10 tuşlarına basın. Sonra TAB veya SAĞ OK sonraki sekmeye taşıyın. SHIFT + TAB veya SOL OK ile önceki sekmeye geçin. Sekme sayfayı seçmek için SPACE veya ENTER tuşuna basın.\"},\n{name:\"İçerik Menü Editörü\",legend:\"İçerik menüsünü açmak için ${contextMenu} veya UYGULAMA TUŞU'na basın. Daha sonra SEKME veya AŞAĞI OK ile bir sonraki menü seçeneği taşıyın. SHIFT + TAB veya YUKARI OK ile önceki seçeneğe gider. Menü seçeneğini seçmek için SPACE veya ENTER tuşuna basın. Seçili seçeneğin alt menüsünü SPACE ya da ENTER veya SAĞ OK açın. Üst menü öğesini geçmek için ESC veya SOL OK ile geri dönün. ESC ile bağlam menüsünü kapatın.\"},{name:\"Liste Kutusu Editörü\",legend:\"Liste kutusu içinde, bir sonraki liste öğesine SEKME VEYA AŞAĞI OK ile taşıyın. SHIFT + TAB veya YUKARI önceki liste öğesi taşıyın. Liste seçeneği seçmek için SPACE veya ENTER tuşuna basın. Liste kutusunu kapatmak için ESC tuşuna basın.\"},\n{name:\"Element Yol Çubuğu Editörü\",legend:\"Elementlerin yol çubuğunda gezinmek için ${ElementsPathFocus} basın. SEKME veya SAĞ OK ile sonraki element düğmesine taşıyın. SHIFT + TAB veya SOL OK önceki düğmeye hareket ettirin. Editör içindeki elementi seçmek için ENTER veya SPACE tuşuna basın.\"}]},{name:\"Komutlar\",items:[{name:\"Komutu geri al\",legend:\"$(undo)'ya basın\"},{name:\"Komutu geri al\",legend:\"${redo} basın\"},{name:\" Kalın komut\",legend:\"${bold} basın\"},{name:\" İtalik komutu\",legend:\"${italic} basın\"},\n{name:\" Alttan çizgi komutu\",legend:\"${underline} basın\"},{name:\" Bağlantı komutu\",legend:\"${link} basın\"},{name:\" Araç çubuğu Toplama komutu\",legend:\"${toolbarCollapse} basın\"},{name:\"Önceki komut alanına odaklan\",legend:\"Düzeltme imleçinden önce, en yakın uzaktaki alana erişmek için ${accessPreviousSpace} basın, örneğin: iki birleşik HR elementleri. Aynı tuş kombinasyonu tekrarıyla diğer alanlarada ulaşın.\"},{name:\"Sonraki komut alanına odaklan\",legend:\"Düzeltme imleçinden sonra, en yakın uzaktaki alana erişmek için ${accessNextSpace} basın, örneğin: iki birleşik HR elementleri. Aynı tuş kombinasyonu tekrarıyla diğer alanlarada ulaşın.\"},\n{name:\"Erişilebilirlik Yardımı\",legend:\"${a11yHelp}'e basın\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/ug.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"ug\",{title:\"قوشۇمچە چۈشەندۈرۈش\",contents:\"ياردەم مەزمۇنى. بۇ سۆزلەشكۈنى ياپماقچى بولسىڭىز ESC نى بېسىڭ.\",legend:[{name:\"ئادەتتىكى\",items:[{name:\"قورال بالداق تەھرىر\",legend:\"${toolbarFocus} بېسىلسا قورال بالداققا يېتەكلەيدۇ، TAB ياكى SHIFT+TAB ئارقىلىق قورال بالداق گۇرۇپپىسى تاللىنىدۇ، ئوڭ سول يا ئوقتا توپچا تاللىنىدۇ، بوشلۇق ياكى Enter كۇنۇپكىسىدا تاللانغان توپچىنى قوللىنىدۇ.\"},{name:\"تەھرىرلىگۈچ سۆزلەشكۈسى\",legend:\"سۆزلەشكۈدە TAB كۇنۇپكىسىدا كېيىنكى سۆز بۆلىكىگە يۆتكىلىدۇ، SHIFT + TAB بىرىكمە كۇنۇپكىسىدا ئالدىنقى سۆز بۆلىكىگە يۆتكىلىدۇ، ENTER كۇنۇپكىسىدا سۆزلەشكۈنى تاپشۇرىدۇ، ESC كۇنۇپكىسى سۆزلەشكۈدىن ۋاز كېچىدۇ. كۆپ بەتكۈچلۈك سۆزلەشكۈگە نىسبەتەن، ALT + F10 دا بەتكۈچ تىزىمىغا يۆتكەيدۇ. ئاندىن TAB كۇنۇپكىسى ياكى ئوڭ يا ئوق كۇنۇپكىسى كېيىنكى بەتكۈچكە يۆتكەيدۇ؛ SHIFT + TAB كۇنۇپكىسى ياكى سول يا ئوق كۇنۇپكىسى ئالدىنقى بەتكۈچكە يۆتكەيدۇ. بوشلۇق كۇنۇپكىسى ياكى ENTER كۇنۇپكىسى بەتكۈچنى تاللايدۇ.\"},\n{name:\"تەھرىرلىگۈچ تىل مۇھىت تىزىملىكى\",legend:\"${contextMenu} ياكى ئەپ كۇنۇپكىسىدا تىل مۇھىت تىزىملىكىنى ئاچىدۇ. ئاندىن TAB ياكى ئاستى يا ئوق كۇنۇپكىسىدا كېيىنكى تىزىملىك تۈرىگە يۆتكەيدۇ؛ SHIFT+TAB ياكى ئۈستى يا ئوق كۇنۇپكىسىدا ئالدىنقى تىزىملىك تۈرىگە يۆتكەيدۇ. بوشلۇق ياكى ENTER كۇنۇپكىسىدا تىزىملىك تۈرىنى تاللايدۇ. بوشلۇق، ENTER ياكى ئوڭ يا ئوق كۇنۇپكىسىدا تارماق تىزىملىكنى ئاچىدۇ. قايتىش تىزىملىكىگە ESC ياكى سول يا ئوق كۇنۇپكىسى ئىشلىتىلىدۇ. ESC كۇنۇپكىسىدا تىل مۇھىت تىزىملىكى تاقىلىدۇ.\"},{name:\"تەھرىرلىگۈچ تىزىمى\",\nlegend:\"تىزىم قۇتىسىدا، كېيىنكى تىزىم تۈرىگە يۆتكەشتە  TAB ياكى ئاستى يا ئوق كۇنۇپكىسى ئىشلىتىلىدۇ. ئالدىنقى تىزىم تۈرىگە يۆتكەشتە  SHIFT + TAB ياكى ئۈستى يا ئوق كۇنۇپكىسى ئىشلىتىلىدۇ. بوشلۇق ياكى ENTER كۇنۇپكىسىدا تىزىم تۈرىنى تاللايدۇ.ESC كۇنۇپكىسىدا تىزىم قۇتىسىنى يىغىدۇ.\"},{name:\"تەھرىرلىگۈچ ئېلېمېنت يول بالداق\",legend:\"${elementsPathFocus} بېسىلسا ئېلېمېنت يول بالداققا يېتەكلەيدۇ، TAB ياكى ئوڭ يا ئوقتا كېيىنكى ئېلېمېنت تاللىنىدۇ،  SHIFT+TAB ياكى سول يا ئوقتا ئالدىنقى ئېلېمېنت تاللىنىدۇ،  بوشلۇق ياكى Enter كۇنۇپكىسىدا تەھرىرلىگۈچتىكى ئېلېمېنت تاللىنىدۇ.\"}]},\n{name:\"بۇيرۇق\",items:[{name:\"بۇيرۇقتىن يېنىۋال\",legend:\"${undo} نى بېسىڭ\"},{name:\"قايتىلاش بۇيرۇقى\",legend:\"${redo} نى بېسىڭ\"},{name:\"توملىتىش بۇيرۇقى\",legend:\"${bold} نى بېسىڭ\"},{name:\"يانتۇ بۇيرۇقى\",legend:\"${italic} نى بېسىڭ\"},{name:\"ئاستى سىزىق بۇيرۇقى\",legend:\"${underline} نى بېسىڭ\"},{name:\"ئۇلانما بۇيرۇقى\",legend:\"${link} نى بېسىڭ\"},{name:\"قورال بالداق قاتلاش بۇيرۇقى\",legend:\"${toolbarCollapse} نى بېسىڭ\"},{name:\"ئالدىنقى فوكۇس نۇقتىسىنى زىيارەت قىلىدىغان بۇيرۇق\",legend:\"${accessPreviousSpace} بېسىپ ^ بەلگىسىگە ئەڭ يېقىن زىيارەت قىلغىلى بولمايدىغان فوكۇس نۇقتا رايونىنىڭ ئالدىنى زىيارەت قىلىدۇ، مەسىلەن: ئۆز ئارا قوشنا ئىككى HR ئېلېمېنت. بۇ بىرىكمە كۇنۇپكا تەكرارلانسا يىراقتىكى فوكۇس نۇقتا رايونىغا يەتكىلى بولىدۇ.\"},\n{name:\"كېيىنكى فوكۇس نۇقتىسىنى زىيارەت قىلىدىغان بۇيرۇق\",legend:\"${accessNextSpace} بېسىپ ^ بەلگىسىگە ئەڭ يېقىن زىيارەت قىلغىلى بولمايدىغان فوكۇس نۇقتا رايونىنىڭ كەينىنى زىيارەت قىلىدۇ، مەسىلەن: ئۆز ئارا قوشنا ئىككى HR ئېلېمېنت. بۇ بىرىكمە كۇنۇپكا تەكرارلانسا يىراقتىكى فوكۇس نۇقتا رايونىغا يەتكىلى بولىدۇ.\"},{name:\"توسالغۇسىز لايىھە چۈشەندۈرۈشى\",legend:\"${a11yHelp} نى بېسىڭ\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/uk.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"uk\",{title:\"Спеціальні Інструкції\",contents:\"Довідка. Натисніть ESC і вона зникне.\",legend:[{name:\"Основне\",items:[{name:\"Панель Редактора\",legend:\"Натисніть ${toolbarFocus} для переходу до панелі інструментів. Для переміщення між групами панелі інструментів використовуйте TAB і SHIFT-TAB. Для переміщення між кнопками панелі іструментів використовуйте кнопки СТРІЛКА ВПРАВО або ВЛІВО. Натисніть ПРОПУСК або ENTER для запуску кнопки панелі інструментів\"},{name:\"Діалог Редактора\",\nlegend:\"У діалозі натисніть клавішу TAB для переходу до наступного поля, натисніть SHIFT + TAB, щоб перейти до попереднього поля, натисніть ENTER, щоб відправити дані, натисніть ESC, щоб скасувати. Для вікон, які мають кілька вкладок, натисніть ALT + F10 для переходу до списку вкладок. Перехід до наступної вкладки TAB АБО СТРІЛКА ВПРАВО. Перехід до попередньої вкладки за допомогою SHIFT + TAB або СТРІЛКА ВЛІВО. Натисніть ПРОПУСК або ENTER, щоб вибрати вкладку.\"},{name:\"Контекстне Меню Редактора\",\nlegend:\"Press ${contextMenu} or APPLICATION KEY to open context-menu. Потім перейдіть до наступного пункту меню за допомогою TAB або СТРІЛКИ ВНИЗ. Натисніть ПРОПУСК або ENTER для вибору параметру меню. Відкрийте підменю поточного параметру, натиснувши ПРОПУСК або ENTER або СТРІЛКУ ВПРАВО. Перейдіть до батьківського елемента меню, натиснувши ESC або СТРІЛКУ ВЛІВО. Закрийте контекстне меню, натиснувши ESC.\"},{name:\"Скринька Списків Редактора\",legend:\"Всередині списку переходимо до наступного пункту списку  клавішею TAB або СТРІЛКА ВНИЗ. Перейти до попереднього елемента списку можна SHIFT + TAB або СТРІЛКА ВГОРУ. Натисніть ПРОПУСК або ENTER, щоб вибрати параметр списку. Натисніть клавішу ESC, щоб закрити список.\"},\n{name:\"Шлях до елемента редактора\",legend:\"Натисніть ${elementsPathFocus} для навігації між елементами панелі. Перейдіть до наступного елемента кнопкою TAB або СТРІЛКА ВПРАВО. Перейдіть до попереднього елемента кнопкою SHIFT+TAB або СТРІЛКА ВЛІВО. Натисніть ПРОПУСК або ENTER для вибору елемента в редакторі.\"}]},{name:\"Команди\",items:[{name:\"Відмінити команду\",legend:\"Натисніть ${undo}\"},{name:\"Повторити\",legend:\"Натисніть ${redo}\"},{name:\"Жирний\",legend:\"Натисніть ${bold}\"},{name:\"Курсив\",legend:\"Натисніть ${italic}\"},\n{name:\"Підкреслений\",legend:\"Натисніть ${underline}\"},{name:\"Посилання\",legend:\"Натисніть ${link}\"},{name:\"Згорнути панель інструментів\",legend:\"Натисніть ${toolbarCollapse}\"},{name:\"Доступ до попереднього місця фокусування\",legend:\"Натисніть ${accessNextSpace} для доступу до найближчої недосяжної області фокусування перед кареткою, наприклад: два сусідні елементи HR. Повторіть комбінацію клавіш для досягнення віддалених областей фокусування.\"},{name:\"Доступ до наступного місця фокусування\",legend:\"Натисніть ${accessNextSpace} для доступу до найближчої недосяжної області фокусування після каретки, наприклад: два сусідні елементи HR. Повторіть комбінацію клавіш для досягнення віддалених областей фокусування.\"},\n{name:\"Допомога з доступності\",legend:\"Натисніть ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/vi.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"vi\",{title:\"Hướng dẫn trợ năng\",contents:\"Nội dung Hỗ trợ. Nhấn ESC để đóng hộp thoại.\",legend:[{name:\"Chung\",items:[{name:\"Thanh công cụ soạn thảo\",legend:\"Nhấn ${toolbarFocus} để điều hướng đến thanh công cụ. Nhấn TAB và SHIFT-TAB để chuyển đến nhóm thanh công cụ khác. Nhấn MŨI TÊN PHẢI hoặc MŨI TÊN TRÁI để chuyển sang nút khác trên thanh công cụ. Nhấn PHÍM CÁCH hoặc ENTER để kích hoạt nút trên thanh công cụ.\"},{name:\"Hộp thoại Biên t\",legend:\"Bên trong một hộp thoại, nhấn TAB để chuyển sang trường tiếp theo, nhấn SHIFT + TAB để quay lại trường phía trước, nhấn ENTER để chấp nhận, nhấn ESC để đóng hộp thoại. Đối với các hộp thoại có nhiều tab, nhấn ALT + F10 để chuyển đến danh sách các tab. Sau đó nhấn TAB hoặc MŨI TÊN SANG PHẢI để chuyển sang tab tiếp theo. Nhấn SHIFT + TAB hoặc MŨI TÊN SANG TRÁI để chuyển sang tab trước đó. Nhấn DẤU CÁCH hoặc ENTER để chọn tab.\"},\n{name:\"Trình đơn Ngữ cảnh cBộ soạn thảo\",legend:\"Nhấn ${contextMenu} hoặc PHÍM ỨNG DỤNG để mở thực đơn ngữ cảnh. Sau đó nhấn TAB hoặc MŨI TÊN XUỐNG để di chuyển đến tuỳ chọn tiếp theo của thực đơn. Nhấn SHIFT+TAB hoặc MŨI TÊN LÊN để quay lại tuỳ chọn trước. Nhấn DẤU CÁCH hoặc ENTER để chọn tuỳ chọn của thực đơn. Nhấn DẤU CÁCH hoặc ENTER hoặc MŨI TÊN SANG PHẢI để mở thực đơn con của tuỳ chọn hiện tại. Nhấn ESC hoặc MŨI TÊN SANG TRÁI để quay trở lại thực đơn gốc. Nhấn ESC để đóng thực đơn ngữ cảnh.\"},\n{name:\"Hộp danh sách trình biên tập\",legend:\"Trong một danh sách chọn, di chuyển đối tượng tiếp theo với phím Tab hoặc phím mũi tên hướng xuống. Di chuyển đến đối tượng trước đó bằng cách nhấn tổ hợp phím Shift+Tab hoặc mũi tên hướng lên. Phím khoảng cách hoặc phím Enter để chọn các tùy chọn trong danh sách. Nhấn phím Esc để đóng lại danh sách chọn.\"},{name:\"Thanh đường dẫn các đối tượng\",legend:\"Nhấn ${elementsPathFocus} để điều hướng các đối tượng trong thanh đường dẫn. Di chuyển đến đối tượng tiếp theo bằng phím Tab hoặc phím mũi tên bên phải. Di chuyển đến đối tượng trước đó bằng tổ hợp phím Shift+Tab hoặc phím mũi tên bên trái. Nhấn phím khoảng cách hoặc Enter để chọn đối tượng trong trình soạn thảo.\"}]},\n{name:\"Lệnh\",items:[{name:\"Làm lại lện\",legend:\"Ấn ${undo}\"},{name:\"Làm lại lệnh\",legend:\"Ấn ${redo}\"},{name:\"Lệnh in đậm\",legend:\"Ấn ${bold}\"},{name:\"Lệnh in nghiêng\",legend:\"Ấn ${italic}\"},{name:\"Lệnh gạch dưới\",legend:\"Ấn ${underline}\"},{name:\"Lệnh liên kết\",legend:\"Nhấn ${link}\"},{name:\"Lệnh hiển thị thanh công cụ\",legend:\"Nhấn${toolbarCollapse}\"},{name:\"Truy cập đến lệnh tập trung vào khoảng cách trước đó\",legend:\"Ấn ${accessPreviousSpace} để truy cập đến phần tập trung khoảng cách sau phần còn sót lại của khoảng cách gần nhất vốn không tác động đến được , thí dụ: hai yếu tố điều chỉnh HR. Lặp lại các phím kết họep này để vươn đến phần khoảng cách.\"},\n{name:\"Truy cập phần đối tượng lệnh khoảng trống\",legend:\"Ấn ${accessNextSpace} để truy cập đến phần tập trung khoảng cách sau phần còn sót lại của khoảng cách gần nhất vốn không tác động đến được , thí dụ: hai yếu tố điều chỉnh HR. Lặp lại các phím kết họep này để vươn đến phần khoảng cách.\"},{name:\"Trợ giúp liên quan\",legend:\"Nhấn ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/zh-cn.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"zh-cn\",{title:\"辅助功能说明\",contents:\"帮助内容。要关闭此对话框请按 ESC 键。\",legend:[{name:\"常规\",items:[{name:\"编辑器工具栏\",legend:\"按 ${toolbarFocus} 导航到工具栏，使用 TAB 键和 SHIFT+TAB 组合键移动到上一个和下一个工具栏组。使用左右箭头键移动到上一个和下一个工具栏按钮。按空格键或回车键以选中工具栏按钮。\"},{name:\"编辑器对话框\",legend:\"在对话框内，TAB 键移动到下一个字段，SHIFT + TAB 组合键移动到上一个字段，ENTER 键提交对话框，ESC 键取消对话框。对于有多选项卡的对话框，用ALT + F10来移到选项卡列表。然后用 TAB 键或者向右箭头来移动到下一个选项卡；SHIFT + TAB 组合键或者向左箭头移动到上一个选项卡。用 SPACE 键或者 ENTER 键选择选项卡。\"},{name:\"编辑器上下文菜单\",legend:\"用 ${contextMenu} 或者“应用程序键”打开上下文菜单。然后用 TAB 键或者下箭头键来移动到下一个菜单项；SHIFT + TAB 组合键或者上箭头键移动到上一个菜单项。用 SPACE 键或者 ENTER 键选择菜单项。用 SPACE 键，ENTER 键或者右箭头键打开子菜单。返回菜单用 ESC 键或者左箭头键。用 ESC 键关闭上下文菜单。\"},\n{name:\"编辑器列表框\",legend:\"在列表框中，移到下一列表项用 TAB 键或者下箭头键。移到上一列表项用SHIFT + TAB 组合键或者上箭头键，用 SPACE 键或者 ENTER 键选择列表项。用 ESC 键收起列表框。\"},{name:\"编辑器元素路径栏\",legend:\"按 ${elementsPathFocus} 以导航到元素路径栏，使用 TAB 键或右箭头键选择下一个元素，使用 SHIFT+TAB 组合键或左箭头键选择上一个元素，按空格键或回车键以选定编辑器里的元素。\"}]},{name:\"命令\",items:[{name:\" 撤消命令\",legend:\"按 ${undo}\"},{name:\" 重做命令\",legend:\"按 ${redo}\"},{name:\" 加粗命令\",legend:\"按 ${bold}\"},{name:\" 倾斜命令\",legend:\"按 ${italic}\"},{name:\" 下划线命令\",legend:\"按 ${underline}\"},{name:\" 链接命令\",legend:\"按 ${link}\"},{name:\" 工具栏折叠命令\",legend:\"按 ${toolbarCollapse}\"},\n{name:\"访问前一个焦点区域的命令\",legend:\"按 ${accessPreviousSpace} 访问^符号前最近的不可访问的焦点区域，例如：两个相邻的 HR 元素。重复此组合按键可以到达远处的焦点区域。\"},{name:\"访问下一个焦点区域命令\",legend:\"按 ${accessNextSpace} 以访问^符号后最近的不可访问的焦点区域。例如：两个相邻的 HR 元素。重复此组合按键可以到达远处的焦点区域。\"},{name:\"辅助功能帮助\",legend:\"按 ${a11yHelp}\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/a11yhelp/dialogs/lang/zh.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"a11yhelp\",\"zh\",{title:\"輔助工具指南\",contents:\"說明內容。若要關閉此對話框請按「ESC」。\",legend:[{name:\"一般\",items:[{name:\"編輯器工具列\",legend:\"請按「${toolbarFocus}」以瀏覽工具列。\\r\\n利用「TAB」或「SHIFT+TAB」以便移動到下一個或前一個工具列群組。\\r\\n利用「→」或「←」以便移動到下一個或前一個工具列按鈕。\\r\\n請按下「空白鍵」或「ENTER」鍵啟動工具列按鈕。\"},{name:\"編輯器對話方塊\",legend:\"在對話框中，請按 TAB 鍵以便移動到下個欄位，請按 SHIFT + TAB 以便移動到前個欄位；請按 ENTER 以提交對話框資料，或按下 ESC 取消對話框。\\r\\n若是有多個頁框的對話框，請按 ALT + F10 以移動到頁框列表，並以 TAB 或是 → 方向鍵移動到下個頁框。以 SHIFT + TAB 或是 ← 方向鍵移動到前個頁框。按下 空白鍵 或是 ENTER 以選取頁框。\"},{name:\"編輯器內容功能表\",\nlegend:\"請按下「${contextMenu}」或是「應用程式鍵」以開啟內容選單。以「TAB」或是「↓」鍵移動到下一個選單選項。以「SHIFT + TAB」或是「↑」鍵移動到上一個選單選項。按下「空白鍵」或是「ENTER」鍵以選取選單選項。以「空白鍵」或「ENTER」或「→」開啟目前選項之子選單。以「ESC」或「←」回到父選單。以「ESC」鍵關閉內容選單」。\"},{name:\"編輯器清單方塊\",legend:\"在列表中，請利用 TAB  或  ↓ 方向鍵以移動到下一個項目；或利用 SHIFT + TAB 或 ↑ 方向鍵移動到前一個項目。請按下 空白鍵 或是 ENTER 以選取項目。請按 ESC 關閉列表。\"},{name:\"編輯器元件路徑工具列\",legend:\"請按「${elementsPathFocus}」以瀏覽元素路徑工具列。\\r\\n利用「TAB」或「→」以便移動到下一個元素按鈕。\\r\\n利用「SHIFT+TAB」或「←」以便移動到前一個元素按鈕。\\r\\n請按下「空白鍵」或「ENTER」鍵選擇編輯器中的元素。\"}]},{name:\"命令\",items:[{name:\"復原命令\",\nlegend:\"請按下「${undo}」\"},{name:\"重複命令\",legend:\"請按下「 ${redo}」\"},{name:\"粗體命令\",legend:\"請按下「${bold}」\"},{name:\"斜體\",legend:\"請按下「${italic}」\"},{name:\"底線命令\",legend:\"請按下「${underline}」\"},{name:\"連結\",legend:\"請按下「${link}」\"},{name:\"隱藏工具列\",legend:\"請按下「${toolbarCollapse}」\"},{name:\"存取前一個焦點空間命令\",legend:\"請按下 ${accessPreviousSpace} 以存取最近但無法靠近之插字符號前的焦點空間。舉例：二個相鄰的 HR 元素。\\r\\n重複按鍵以存取較遠的焦點空間。\"},{name:\"存取下一個焦點空間命令\",legend:\"請按下 ${accessNextSpace} 以存取最近但無法靠近之插字符號後的焦點空間。舉例：二個相鄰的 HR 元素。\\r\\n重複按鍵以存取較遠的焦點空間。\"},{name:\"協助工具說明\",legend:\"請按下「${a11yHelp}」\"}]}]});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/about/dialogs/about.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.dialog.add(\"about\",function(a){var a=a.lang.about,b=CKEDITOR.plugins.get(\"about\").path+\"dialogs/\"+(CKEDITOR.env.hidpi?\"hidpi/\":\"\")+\"logo_ckeditor.png\";return{title:CKEDITOR.env.ie?a.dlgTitle:a.title,minWidth:390,minHeight:230,contents:[{id:\"tab1\",label:\"\",title:\"\",expand:!0,padding:0,elements:[{type:\"html\",html:'<style type=\"text/css\">.cke_about_container{color:#000 !important;padding:10px 10px 0;margin-top:5px}.cke_about_container p{margin: 0 0 10px;}.cke_about_container .cke_about_logo{height:81px;background-color:#fff;background-image:url('+\nb+\");\"+(CKEDITOR.env.hidpi?\"background-size:163px 58px;\":\"\")+'background-position:center; background-repeat:no-repeat;margin-bottom:10px;}.cke_about_container a{cursor:pointer !important;color:#00B2CE !important;text-decoration:underline !important;}</style><div class=\"cke_about_container\"><div class=\"cke_about_logo\"></div><p>CKEditor '+CKEDITOR.version+\" (revision \"+CKEDITOR.revision+')<br><a href=\"http://ckeditor.com/\">http://ckeditor.com</a></p><p>'+a.help.replace(\"$1\",'<a href=\"http://docs.ckeditor.com/user\">'+\na.userGuide+\"</a>\")+\"</p><p>\"+a.moreInfo+'<br><a href=\"http://ckeditor.com/about/license\">http://ckeditor.com/about/license</a></p><p>'+a.copy.replace(\"$1\",'<a href=\"http://cksource.com/\">CKSource</a> - Frederico Knabben')+\"</p></div>\"}]}],buttons:[CKEDITOR.dialog.cancelButton]}});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/clipboard/dialogs/paste.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.dialog.add(\"paste\",function(c){function h(a){var b=new CKEDITOR.dom.document(a.document),f=b.getBody(),d=b.getById(\"cke_actscrpt\");d&&d.remove();f.setAttribute(\"contenteditable\",!0);if(CKEDITOR.env.ie&&8>CKEDITOR.env.version)b.getWindow().on(\"blur\",function(){b.$.selection.empty()});b.on(\"keydown\",function(a){var a=a.data,b;switch(a.getKeystroke()){case 27:this.hide();b=1;break;case 9:case CKEDITOR.SHIFT+9:this.changeFocus(1),b=1}b&&a.preventDefault()},this);c.fire(\"ariaWidget\",new CKEDITOR.dom.element(a.frameElement));\nb.getWindow().getFrame().removeCustomData(\"pendingFocus\")&&f.focus()}var e=c.lang.clipboard;c.on(\"pasteDialogCommit\",function(a){a.data&&c.fire(\"paste\",{type:\"auto\",dataValue:a.data})},null,null,1E3);return{title:e.title,minWidth:CKEDITOR.env.ie&&CKEDITOR.env.quirks?370:350,minHeight:CKEDITOR.env.quirks?250:245,onShow:function(){this.parts.dialog.$.offsetHeight;this.setupContent();this.parts.title.setHtml(this.customTitle||e.title);this.customTitle=null},onLoad:function(){(CKEDITOR.env.ie7Compat||\nCKEDITOR.env.ie6Compat)&&\"rtl\"==c.lang.dir&&this.parts.contents.setStyle(\"overflow\",\"hidden\")},onOk:function(){this.commitContent()},contents:[{id:\"general\",label:c.lang.common.generalTab,elements:[{type:\"html\",id:\"securityMsg\",html:'<div style=\"white-space:normal;width:340px\">'+e.securityMsg+\"</div>\"},{type:\"html\",id:\"pasteMsg\",html:'<div style=\"white-space:normal;width:340px\">'+e.pasteMsg+\"</div>\"},{type:\"html\",id:\"editing_area\",style:\"width:100%;height:100%\",html:\"\",focus:function(){var a=this.getInputElement(),\nb=a.getFrameDocument().getBody();!b||b.isReadOnly()?a.setCustomData(\"pendingFocus\",1):b.focus()},setup:function(){var a=this.getDialog(),b='<html dir=\"'+c.config.contentsLangDirection+'\" lang=\"'+(c.config.contentsLanguage||c.langCode)+'\"><head><style>body{margin:3px;height:95%}</style></head><body><script id=\"cke_actscrpt\" type=\"text/javascript\">window.parent.CKEDITOR.tools.callFunction('+CKEDITOR.tools.addFunction(h,a)+\",this);<\\/script></body></html>\",f=CKEDITOR.env.air?\"javascript:void(0)\":CKEDITOR.env.ie?\n\"javascript:void((function(){\"+encodeURIComponent(\"document.open();(\"+CKEDITOR.tools.fixDomain+\")();document.close();\")+'})())\"':\"\",d=CKEDITOR.dom.element.createFromHtml('<iframe class=\"cke_pasteframe\" frameborder=\"0\"  allowTransparency=\"true\" src=\"'+f+'\" role=\"region\" aria-label=\"'+e.pasteArea+'\" aria-describedby=\"'+a.getContentElement(\"general\",\"pasteMsg\").domId+'\" aria-multiple=\"true\"></iframe>');d.on(\"load\",function(a){a.removeListener();a=d.getFrameDocument();a.write(b);c.focusManager.add(a.getBody());\nCKEDITOR.env.air&&h.call(this,a.getWindow().$)},a);d.setCustomData(\"dialog\",a);a=this.getElement();a.setHtml(\"\");a.append(d);if(CKEDITOR.env.ie){var g=CKEDITOR.dom.element.createFromHtml('<span tabindex=\"-1\" style=\"position:absolute\" role=\"presentation\"></span>');g.on(\"focus\",function(){setTimeout(function(){d.$.contentWindow.focus()})});a.append(g);this.focus=function(){g.focus();this.fire(\"focus\")}}this.getInputElement=function(){return d};CKEDITOR.env.ie&&(a.setStyle(\"display\",\"block\"),a.setStyle(\"height\",\nd.$.offsetHeight+2+\"px\"))},commit:function(){var a=this.getDialog().getParentEditor(),b=this.getInputElement().getFrameDocument().getBody(),c=b.getBogus(),d;c&&c.remove();d=b.getHtml();setTimeout(function(){a.fire(\"pasteDialogCommit\",d)},0)}}]}]}});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/dialog/dialogDefinition.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/image/dialogs/image.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n(function(){var r=function(c,j){function r(){var a=arguments,b=this.getContentElement(\"advanced\",\"txtdlgGenStyle\");b&&b.commit.apply(b,a);this.foreach(function(b){b.commit&&\"txtdlgGenStyle\"!=b.id&&b.commit.apply(b,a)})}function i(a){if(!s){s=1;var b=this.getDialog(),d=b.imageElement;if(d){this.commit(f,d);for(var a=[].concat(a),e=a.length,c,g=0;g<e;g++)(c=b.getContentElement.apply(b,a[g].split(\":\")))&&c.setup(f,d)}s=0}}var f=1,k=/^\\s*(\\d+)((px)|\\%)?\\s*$/i,v=/(^\\s*(\\d+)((px)|\\%)?\\s*$)|^$/i,o=/^\\d+px$/,\nw=function(){var a=this.getValue(),b=this.getDialog(),d=a.match(k);d&&(\"%\"==d[2]&&l(b,!1),a=d[1]);b.lockRatio&&(d=b.originalElement,\"true\"==d.getCustomData(\"isReady\")&&(\"txtHeight\"==this.id?(a&&\"0\"!=a&&(a=Math.round(d.$.width*(a/d.$.height))),isNaN(a)||b.setValueOf(\"info\",\"txtWidth\",a)):(a&&\"0\"!=a&&(a=Math.round(d.$.height*(a/d.$.width))),isNaN(a)||b.setValueOf(\"info\",\"txtHeight\",a))));g(b)},g=function(a){if(!a.originalElement||!a.preview)return 1;a.commitContent(4,a.preview);return 0},s,l=function(a,\nb){if(!a.getContentElement(\"info\",\"ratioLock\"))return null;var d=a.originalElement;if(!d)return null;if(\"check\"==b){if(!a.userlockRatio&&\"true\"==d.getCustomData(\"isReady\")){var e=a.getValueOf(\"info\",\"txtWidth\"),c=a.getValueOf(\"info\",\"txtHeight\"),d=1E3*d.$.width/d.$.height,f=1E3*e/c;a.lockRatio=!1;!e&&!c?a.lockRatio=!0:!isNaN(d)&&!isNaN(f)&&Math.round(d)==Math.round(f)&&(a.lockRatio=!0)}}else void 0!=b?a.lockRatio=b:(a.userlockRatio=1,a.lockRatio=!a.lockRatio);e=CKEDITOR.document.getById(p);a.lockRatio?\ne.removeClass(\"cke_btn_unlocked\"):e.addClass(\"cke_btn_unlocked\");e.setAttribute(\"aria-checked\",a.lockRatio);CKEDITOR.env.hc&&e.getChild(0).setHtml(a.lockRatio?CKEDITOR.env.ie?\"■\":\"▣\":CKEDITOR.env.ie?\"□\":\"▢\");return a.lockRatio},x=function(a){var b=a.originalElement;if(\"true\"==b.getCustomData(\"isReady\")){var d=a.getContentElement(\"info\",\"txtWidth\"),e=a.getContentElement(\"info\",\"txtHeight\");d&&d.setValue(b.$.width);e&&e.setValue(b.$.height)}g(a)},y=function(a,b){function d(a,b){var d=a.match(k);return d?\n(\"%\"==d[2]&&(d[1]+=\"%\",l(e,!1)),d[1]):b}if(a==f){var e=this.getDialog(),c=\"\",g=\"txtWidth\"==this.id?\"width\":\"height\",h=b.getAttribute(g);h&&(c=d(h,c));c=d(b.getStyle(g),c);this.setValue(c)}},t,q=function(){var a=this.originalElement;a.setCustomData(\"isReady\",\"true\");a.removeListener(\"load\",q);a.removeListener(\"error\",h);a.removeListener(\"abort\",h);CKEDITOR.document.getById(m).setStyle(\"display\",\"none\");this.dontResetSize||x(this);this.firstLoad&&CKEDITOR.tools.setTimeout(function(){l(this,\"check\")},\n0,this);this.dontResetSize=this.firstLoad=!1},h=function(){var a=this.originalElement;a.removeListener(\"load\",q);a.removeListener(\"error\",h);a.removeListener(\"abort\",h);a=CKEDITOR.getUrl(CKEDITOR.plugins.get(\"image\").path+\"images/noimage.png\");this.preview&&this.preview.setAttribute(\"src\",a);CKEDITOR.document.getById(m).setStyle(\"display\",\"none\");l(this,!1)},n=function(a){return CKEDITOR.tools.getNextId()+\"_\"+a},p=n(\"btnLockSizes\"),u=n(\"btnResetSize\"),m=n(\"ImagePreviewLoader\"),A=n(\"previewLink\"),\nz=n(\"previewImage\");return{title:c.lang.image[\"image\"==j?\"title\":\"titleButton\"],minWidth:420,minHeight:360,onShow:function(){this.linkEditMode=this.imageEditMode=this.linkElement=this.imageElement=!1;this.lockRatio=!0;this.userlockRatio=0;this.dontResetSize=!1;this.firstLoad=!0;this.addLink=!1;var a=this.getParentEditor(),b=a.getSelection(),d=(b=b&&b.getSelectedElement())&&a.elementPath(b).contains(\"a\",1);CKEDITOR.document.getById(m).setStyle(\"display\",\"none\");t=new CKEDITOR.dom.element(\"img\",a.document);\nthis.preview=CKEDITOR.document.getById(z);this.originalElement=a.document.createElement(\"img\");this.originalElement.setAttribute(\"alt\",\"\");this.originalElement.setCustomData(\"isReady\",\"false\");if(d){this.linkElement=d;this.linkEditMode=!0;var c=d.getChildren();if(1==c.count()){var g=c.getItem(0).getName();if(\"img\"==g||\"input\"==g)this.imageElement=c.getItem(0),\"img\"==this.imageElement.getName()?this.imageEditMode=\"img\":\"input\"==this.imageElement.getName()&&(this.imageEditMode=\"input\")}\"image\"==j&&\nthis.setupContent(2,d)}if(this.customImageElement)this.imageEditMode=\"img\",this.imageElement=this.customImageElement,delete this.customImageElement;else if(b&&\"img\"==b.getName()&&!b.data(\"cke-realelement\")||b&&\"input\"==b.getName()&&\"image\"==b.getAttribute(\"type\"))this.imageEditMode=b.getName(),this.imageElement=b;this.imageEditMode?(this.cleanImageElement=this.imageElement,this.imageElement=this.cleanImageElement.clone(!0,!0),this.setupContent(f,this.imageElement)):this.imageElement=a.document.createElement(\"img\");\nl(this,!0);CKEDITOR.tools.trim(this.getValueOf(\"info\",\"txtUrl\"))||(this.preview.removeAttribute(\"src\"),this.preview.setStyle(\"display\",\"none\"))},onOk:function(){if(this.imageEditMode){var a=this.imageEditMode;\"image\"==j&&\"input\"==a&&confirm(c.lang.image.button2Img)?(this.imageElement=c.document.createElement(\"img\"),this.imageElement.setAttribute(\"alt\",\"\"),c.insertElement(this.imageElement)):\"image\"!=j&&\"img\"==a&&confirm(c.lang.image.img2Button)?(this.imageElement=c.document.createElement(\"input\"),\nthis.imageElement.setAttributes({type:\"image\",alt:\"\"}),c.insertElement(this.imageElement)):(this.imageElement=this.cleanImageElement,delete this.cleanImageElement)}else\"image\"==j?this.imageElement=c.document.createElement(\"img\"):(this.imageElement=c.document.createElement(\"input\"),this.imageElement.setAttribute(\"type\",\"image\")),this.imageElement.setAttribute(\"alt\",\"\");this.linkEditMode||(this.linkElement=c.document.createElement(\"a\"));this.commitContent(f,this.imageElement);this.commitContent(2,this.linkElement);\nthis.imageElement.getAttribute(\"style\")||this.imageElement.removeAttribute(\"style\");this.imageEditMode?!this.linkEditMode&&this.addLink?(c.insertElement(this.linkElement),this.imageElement.appendTo(this.linkElement)):this.linkEditMode&&!this.addLink&&(c.getSelection().selectElement(this.linkElement),c.insertElement(this.imageElement)):this.addLink?this.linkEditMode?c.insertElement(this.imageElement):(c.insertElement(this.linkElement),this.linkElement.append(this.imageElement,!1)):c.insertElement(this.imageElement)},\nonLoad:function(){\"image\"!=j&&this.hidePage(\"Link\");var a=this._.element.getDocument();this.getContentElement(\"info\",\"ratioLock\")&&(this.addFocusable(a.getById(u),5),this.addFocusable(a.getById(p),5));this.commitContent=r},onHide:function(){this.preview&&this.commitContent(8,this.preview);this.originalElement&&(this.originalElement.removeListener(\"load\",q),this.originalElement.removeListener(\"error\",h),this.originalElement.removeListener(\"abort\",h),this.originalElement.remove(),this.originalElement=\n!1);delete this.imageElement},contents:[{id:\"info\",label:c.lang.image.infoTab,accessKey:\"I\",elements:[{type:\"vbox\",padding:0,children:[{type:\"hbox\",widths:[\"280px\",\"110px\"],align:\"right\",children:[{id:\"txtUrl\",type:\"text\",label:c.lang.common.url,required:!0,onChange:function(){var a=this.getDialog(),b=this.getValue();if(0<b.length){var a=this.getDialog(),d=a.originalElement;a.preview.removeStyle(\"display\");d.setCustomData(\"isReady\",\"false\");var c=CKEDITOR.document.getById(m);c&&c.setStyle(\"display\",\n\"\");d.on(\"load\",q,a);d.on(\"error\",h,a);d.on(\"abort\",h,a);d.setAttribute(\"src\",b);t.setAttribute(\"src\",b);a.preview.setAttribute(\"src\",t.$.src);g(a)}else a.preview&&(a.preview.removeAttribute(\"src\"),a.preview.setStyle(\"display\",\"none\"))},setup:function(a,b){if(a==f){var d=b.data(\"cke-saved-src\")||b.getAttribute(\"src\");this.getDialog().dontResetSize=!0;this.setValue(d);this.setInitValue()}},commit:function(a,b){a==f&&(this.getValue()||this.isChanged())?(b.data(\"cke-saved-src\",this.getValue()),b.setAttribute(\"src\",\nthis.getValue())):8==a&&(b.setAttribute(\"src\",\"\"),b.removeAttribute(\"src\"))},validate:CKEDITOR.dialog.validate.notEmpty(c.lang.image.urlMissing)},{type:\"button\",id:\"browse\",style:\"display:inline-block;margin-top:10px;\",align:\"center\",label:c.lang.common.browseServer,hidden:!0,filebrowser:\"info:txtUrl\"}]}]},{id:\"txtAlt\",type:\"text\",label:c.lang.image.alt,accessKey:\"T\",\"default\":\"\",onChange:function(){g(this.getDialog())},setup:function(a,b){a==f&&this.setValue(b.getAttribute(\"alt\"))},commit:function(a,\nb){a==f?(this.getValue()||this.isChanged())&&b.setAttribute(\"alt\",this.getValue()):4==a?b.setAttribute(\"alt\",this.getValue()):8==a&&b.removeAttribute(\"alt\")}},{type:\"hbox\",children:[{id:\"basic\",type:\"vbox\",children:[{type:\"hbox\",requiredContent:\"img{width,height}\",widths:[\"50%\",\"50%\"],children:[{type:\"vbox\",padding:1,children:[{type:\"text\",width:\"45px\",id:\"txtWidth\",label:c.lang.common.width,onKeyUp:w,onChange:function(){i.call(this,\"advanced:txtdlgGenStyle\")},validate:function(){var a=this.getValue().match(v);\n(a=!!(a&&0!==parseInt(a[1],10)))||alert(c.lang.common.invalidWidth);return a},setup:y,commit:function(a,b,d){var c=this.getValue();a==f?(c?b.setStyle(\"width\",CKEDITOR.tools.cssLength(c)):b.removeStyle(\"width\"),!d&&b.removeAttribute(\"width\")):4==a?c.match(k)?b.setStyle(\"width\",CKEDITOR.tools.cssLength(c)):(a=this.getDialog().originalElement,\"true\"==a.getCustomData(\"isReady\")&&b.setStyle(\"width\",a.$.width+\"px\")):8==a&&(b.removeAttribute(\"width\"),b.removeStyle(\"width\"))}},{type:\"text\",id:\"txtHeight\",\nwidth:\"45px\",label:c.lang.common.height,onKeyUp:w,onChange:function(){i.call(this,\"advanced:txtdlgGenStyle\")},validate:function(){var a=this.getValue().match(v);(a=!!(a&&0!==parseInt(a[1],10)))||alert(c.lang.common.invalidHeight);return a},setup:y,commit:function(a,b,d){var c=this.getValue();a==f?(c?b.setStyle(\"height\",CKEDITOR.tools.cssLength(c)):b.removeStyle(\"height\"),!d&&b.removeAttribute(\"height\")):4==a?c.match(k)?b.setStyle(\"height\",CKEDITOR.tools.cssLength(c)):(a=this.getDialog().originalElement,\n\"true\"==a.getCustomData(\"isReady\")&&b.setStyle(\"height\",a.$.height+\"px\")):8==a&&(b.removeAttribute(\"height\"),b.removeStyle(\"height\"))}}]},{id:\"ratioLock\",type:\"html\",style:\"margin-top:30px;width:40px;height:40px;\",onLoad:function(){var a=CKEDITOR.document.getById(u),b=CKEDITOR.document.getById(p);a&&(a.on(\"click\",function(a){x(this);a.data&&a.data.preventDefault()},this.getDialog()),a.on(\"mouseover\",function(){this.addClass(\"cke_btn_over\")},a),a.on(\"mouseout\",function(){this.removeClass(\"cke_btn_over\")},\na));b&&(b.on(\"click\",function(a){l(this);var b=this.originalElement,c=this.getValueOf(\"info\",\"txtWidth\");if(b.getCustomData(\"isReady\")==\"true\"&&c){b=b.$.height/b.$.width*c;if(!isNaN(b)){this.setValueOf(\"info\",\"txtHeight\",Math.round(b));g(this)}}a.data&&a.data.preventDefault()},this.getDialog()),b.on(\"mouseover\",function(){this.addClass(\"cke_btn_over\")},b),b.on(\"mouseout\",function(){this.removeClass(\"cke_btn_over\")},b))},html:'<div><a href=\"javascript:void(0)\" tabindex=\"-1\" title=\"'+c.lang.image.lockRatio+\n'\" class=\"cke_btn_locked\" id=\"'+p+'\" role=\"checkbox\"><span class=\"cke_icon\"></span><span class=\"cke_label\">'+c.lang.image.lockRatio+'</span></a><a href=\"javascript:void(0)\" tabindex=\"-1\" title=\"'+c.lang.image.resetSize+'\" class=\"cke_btn_reset\" id=\"'+u+'\" role=\"button\"><span class=\"cke_label\">'+c.lang.image.resetSize+\"</span></a></div>\"}]},{type:\"vbox\",padding:1,children:[{type:\"text\",id:\"txtBorder\",requiredContent:\"img{border-width}\",width:\"60px\",label:c.lang.image.border,\"default\":\"\",onKeyUp:function(){g(this.getDialog())},\nonChange:function(){i.call(this,\"advanced:txtdlgGenStyle\")},validate:CKEDITOR.dialog.validate.integer(c.lang.image.validateBorder),setup:function(a,b){if(a==f){var d;d=(d=(d=b.getStyle(\"border-width\"))&&d.match(/^(\\d+px)(?: \\1 \\1 \\1)?$/))&&parseInt(d[1],10);isNaN(parseInt(d,10))&&(d=b.getAttribute(\"border\"));this.setValue(d)}},commit:function(a,b,d){var c=parseInt(this.getValue(),10);a==f||4==a?(isNaN(c)?!c&&this.isChanged()&&b.removeStyle(\"border\"):(b.setStyle(\"border-width\",CKEDITOR.tools.cssLength(c)),\nb.setStyle(\"border-style\",\"solid\")),!d&&a==f&&b.removeAttribute(\"border\")):8==a&&(b.removeAttribute(\"border\"),b.removeStyle(\"border-width\"),b.removeStyle(\"border-style\"),b.removeStyle(\"border-color\"))}},{type:\"text\",id:\"txtHSpace\",requiredContent:\"img{margin-left,margin-right}\",width:\"60px\",label:c.lang.image.hSpace,\"default\":\"\",onKeyUp:function(){g(this.getDialog())},onChange:function(){i.call(this,\"advanced:txtdlgGenStyle\")},validate:CKEDITOR.dialog.validate.integer(c.lang.image.validateHSpace),\nsetup:function(a,b){if(a==f){var d,c;d=b.getStyle(\"margin-left\");c=b.getStyle(\"margin-right\");d=d&&d.match(o);c=c&&c.match(o);d=parseInt(d,10);c=parseInt(c,10);d=d==c&&d;isNaN(parseInt(d,10))&&(d=b.getAttribute(\"hspace\"));this.setValue(d)}},commit:function(a,b,c){var e=parseInt(this.getValue(),10);a==f||4==a?(isNaN(e)?!e&&this.isChanged()&&(b.removeStyle(\"margin-left\"),b.removeStyle(\"margin-right\")):(b.setStyle(\"margin-left\",CKEDITOR.tools.cssLength(e)),b.setStyle(\"margin-right\",CKEDITOR.tools.cssLength(e))),\n!c&&a==f&&b.removeAttribute(\"hspace\")):8==a&&(b.removeAttribute(\"hspace\"),b.removeStyle(\"margin-left\"),b.removeStyle(\"margin-right\"))}},{type:\"text\",id:\"txtVSpace\",requiredContent:\"img{margin-top,margin-bottom}\",width:\"60px\",label:c.lang.image.vSpace,\"default\":\"\",onKeyUp:function(){g(this.getDialog())},onChange:function(){i.call(this,\"advanced:txtdlgGenStyle\")},validate:CKEDITOR.dialog.validate.integer(c.lang.image.validateVSpace),setup:function(a,b){if(a==f){var c,e;c=b.getStyle(\"margin-top\");e=\nb.getStyle(\"margin-bottom\");c=c&&c.match(o);e=e&&e.match(o);c=parseInt(c,10);e=parseInt(e,10);c=c==e&&c;isNaN(parseInt(c,10))&&(c=b.getAttribute(\"vspace\"));this.setValue(c)}},commit:function(a,b,c){var e=parseInt(this.getValue(),10);a==f||4==a?(isNaN(e)?!e&&this.isChanged()&&(b.removeStyle(\"margin-top\"),b.removeStyle(\"margin-bottom\")):(b.setStyle(\"margin-top\",CKEDITOR.tools.cssLength(e)),b.setStyle(\"margin-bottom\",CKEDITOR.tools.cssLength(e))),!c&&a==f&&b.removeAttribute(\"vspace\")):8==a&&(b.removeAttribute(\"vspace\"),\nb.removeStyle(\"margin-top\"),b.removeStyle(\"margin-bottom\"))}},{id:\"cmbAlign\",requiredContent:\"img{float}\",type:\"select\",widths:[\"35%\",\"65%\"],style:\"width:90px\",label:c.lang.common.align,\"default\":\"\",items:[[c.lang.common.notSet,\"\"],[c.lang.common.alignLeft,\"left\"],[c.lang.common.alignRight,\"right\"]],onChange:function(){g(this.getDialog());i.call(this,\"advanced:txtdlgGenStyle\")},setup:function(a,b){if(a==f){var c=b.getStyle(\"float\");switch(c){case \"inherit\":case \"none\":c=\"\"}!c&&(c=(b.getAttribute(\"align\")||\n\"\").toLowerCase());this.setValue(c)}},commit:function(a,b,c){var e=this.getValue();if(a==f||4==a){if(e?b.setStyle(\"float\",e):b.removeStyle(\"float\"),!c&&a==f)switch(e=(b.getAttribute(\"align\")||\"\").toLowerCase(),e){case \"left\":case \"right\":b.removeAttribute(\"align\")}}else 8==a&&b.removeStyle(\"float\")}}]}]},{type:\"vbox\",height:\"250px\",children:[{type:\"html\",id:\"htmlPreview\",style:\"width:95%;\",html:\"<div>\"+CKEDITOR.tools.htmlEncode(c.lang.common.preview)+'<br><div id=\"'+m+'\" class=\"ImagePreviewLoader\" style=\"display:none\"><div class=\"loading\">&nbsp;</div></div><div class=\"ImagePreviewBox\"><table><tr><td><a href=\"javascript:void(0)\" target=\"_blank\" onclick=\"return false;\" id=\"'+\nA+'\"><img id=\"'+z+'\" alt=\"\" /></a>'+(c.config.image_previewText||\"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, nulla. Aenean dictum lacinia tortor. Nunc iaculis, nibh non iaculis aliquam, orci felis euismod neque, sed ornare massa mauris sed velit. Nulla pretium mi et risus. Fusce mi pede, tempor id, cursus ac, ullamcorper nec, enim. Sed tortor. Curabitur molestie. Duis velit augue, condimentum at, ultrices a, luctus ut, orci. Donec pellentesque egestas eros. Integer cursus, augue in cursus faucibus, eros pede bibendum sem, in tempus tellus justo quis ligula. Etiam eget tortor. Vestibulum rutrum, est ut placerat elementum, lectus nisl aliquam velit, tempor aliquam eros nunc nonummy metus. In eros metus, gravida a, gravida sed, lobortis id, turpis. Ut ultrices, ipsum at venenatis fringilla, sem nulla lacinia tellus, eget aliquet turpis mauris non enim. Nam turpis. Suspendisse lacinia. Curabitur ac tortor ut ipsum egestas elementum. Nunc imperdiet gravida mauris.\")+\n\"</td></tr></table></div></div>\"}]}]}]},{id:\"Link\",requiredContent:\"a[href]\",label:c.lang.image.linkTab,padding:0,elements:[{id:\"txtUrl\",type:\"text\",label:c.lang.common.url,style:\"width: 100%\",\"default\":\"\",setup:function(a,b){if(2==a){var c=b.data(\"cke-saved-href\");c||(c=b.getAttribute(\"href\"));this.setValue(c)}},commit:function(a,b){if(2==a&&(this.getValue()||this.isChanged())){var d=decodeURI(this.getValue());b.data(\"cke-saved-href\",d);b.setAttribute(\"href\",d);if(this.getValue()||!c.config.image_removeLinkByEmptyURL)this.getDialog().addLink=\n!0}}},{type:\"button\",id:\"browse\",filebrowser:{action:\"Browse\",target:\"Link:txtUrl\",url:c.config.filebrowserImageBrowseLinkUrl},style:\"float:right\",hidden:!0,label:c.lang.common.browseServer},{id:\"cmbTarget\",type:\"select\",requiredContent:\"a[target]\",label:c.lang.common.target,\"default\":\"\",items:[[c.lang.common.notSet,\"\"],[c.lang.common.targetNew,\"_blank\"],[c.lang.common.targetTop,\"_top\"],[c.lang.common.targetSelf,\"_self\"],[c.lang.common.targetParent,\"_parent\"]],setup:function(a,b){2==a&&this.setValue(b.getAttribute(\"target\")||\n\"\")},commit:function(a,b){2==a&&(this.getValue()||this.isChanged())&&b.setAttribute(\"target\",this.getValue())}}]},{id:\"Upload\",hidden:!0,filebrowser:\"uploadButton\",label:c.lang.image.upload,elements:[{type:\"file\",id:\"upload\",label:c.lang.image.btnUpload,style:\"height:40px\",size:38},{type:\"fileButton\",id:\"uploadButton\",filebrowser:\"info:txtUrl\",label:c.lang.image.btnUpload,\"for\":[\"Upload\",\"upload\"]}]},{id:\"advanced\",label:c.lang.common.advancedTab,elements:[{type:\"hbox\",widths:[\"50%\",\"25%\",\"25%\"],\nchildren:[{type:\"text\",id:\"linkId\",requiredContent:\"img[id]\",label:c.lang.common.id,setup:function(a,b){a==f&&this.setValue(b.getAttribute(\"id\"))},commit:function(a,b){a==f&&(this.getValue()||this.isChanged())&&b.setAttribute(\"id\",this.getValue())}},{id:\"cmbLangDir\",type:\"select\",requiredContent:\"img[dir]\",style:\"width : 100px;\",label:c.lang.common.langDir,\"default\":\"\",items:[[c.lang.common.notSet,\"\"],[c.lang.common.langDirLtr,\"ltr\"],[c.lang.common.langDirRtl,\"rtl\"]],setup:function(a,b){a==f&&this.setValue(b.getAttribute(\"dir\"))},\ncommit:function(a,b){a==f&&(this.getValue()||this.isChanged())&&b.setAttribute(\"dir\",this.getValue())}},{type:\"text\",id:\"txtLangCode\",requiredContent:\"img[lang]\",label:c.lang.common.langCode,\"default\":\"\",setup:function(a,b){a==f&&this.setValue(b.getAttribute(\"lang\"))},commit:function(a,b){a==f&&(this.getValue()||this.isChanged())&&b.setAttribute(\"lang\",this.getValue())}}]},{type:\"text\",id:\"txtGenLongDescr\",requiredContent:\"img[longdesc]\",label:c.lang.common.longDescr,setup:function(a,b){a==f&&this.setValue(b.getAttribute(\"longDesc\"))},\ncommit:function(a,b){a==f&&(this.getValue()||this.isChanged())&&b.setAttribute(\"longDesc\",this.getValue())}},{type:\"hbox\",widths:[\"50%\",\"50%\"],children:[{type:\"text\",id:\"txtGenClass\",requiredContent:\"img(cke-xyz)\",label:c.lang.common.cssClass,\"default\":\"\",setup:function(a,b){a==f&&this.setValue(b.getAttribute(\"class\"))},commit:function(a,b){a==f&&(this.getValue()||this.isChanged())&&b.setAttribute(\"class\",this.getValue())}},{type:\"text\",id:\"txtGenTitle\",requiredContent:\"img[title]\",label:c.lang.common.advisoryTitle,\n\"default\":\"\",onChange:function(){g(this.getDialog())},setup:function(a,b){a==f&&this.setValue(b.getAttribute(\"title\"))},commit:function(a,b){a==f?(this.getValue()||this.isChanged())&&b.setAttribute(\"title\",this.getValue()):4==a?b.setAttribute(\"title\",this.getValue()):8==a&&b.removeAttribute(\"title\")}}]},{type:\"text\",id:\"txtdlgGenStyle\",requiredContent:\"img{cke-xyz}\",label:c.lang.common.cssStyle,validate:CKEDITOR.dialog.validate.inlineStyle(c.lang.common.invalidInlineStyle),\"default\":\"\",setup:function(a,\nb){if(a==f){var c=b.getAttribute(\"style\");!c&&b.$.style.cssText&&(c=b.$.style.cssText);this.setValue(c);var e=b.$.style.height,c=b.$.style.width,e=(e?e:\"\").match(k),c=(c?c:\"\").match(k);this.attributesInStyle={height:!!e,width:!!c}}},onChange:function(){i.call(this,\"info:cmbFloat info:cmbAlign info:txtVSpace info:txtHSpace info:txtBorder info:txtWidth info:txtHeight\".split(\" \"));g(this)},commit:function(a,b){a==f&&(this.getValue()||this.isChanged())&&b.setAttribute(\"style\",this.getValue())}}]}]}};\nCKEDITOR.dialog.add(\"image\",function(c){return r(c,\"image\")});CKEDITOR.dialog.add(\"imagebutton\",function(c){return r(c,\"imagebutton\")})})();"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/link/dialogs/anchor.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.dialog.add(\"anchor\",function(c){var d=function(a){this._.selectedElement=a;this.setValueOf(\"info\",\"txtName\",a.data(\"cke-saved-name\")||\"\")};return{title:c.lang.link.anchor.title,minWidth:300,minHeight:60,onOk:function(){var a=CKEDITOR.tools.trim(this.getValueOf(\"info\",\"txtName\")),a={id:a,name:a,\"data-cke-saved-name\":a};if(this._.selectedElement)this._.selectedElement.data(\"cke-realelement\")?(a=c.document.createElement(\"a\",{attributes:a}),c.createFakeElement(a,\"cke_anchor\",\"anchor\").replace(this._.selectedElement)):\nthis._.selectedElement.setAttributes(a);else{var b=c.getSelection(),b=b&&b.getRanges()[0];b.collapsed?(CKEDITOR.plugins.link.synAnchorSelector&&(a[\"class\"]=\"cke_anchor_empty\"),CKEDITOR.plugins.link.emptyAnchorFix&&(a.contenteditable=\"false\",a[\"data-cke-editable\"]=1),a=c.document.createElement(\"a\",{attributes:a}),CKEDITOR.plugins.link.fakeAnchor&&(a=c.createFakeElement(a,\"cke_anchor\",\"anchor\")),b.insertNode(a)):(CKEDITOR.env.ie&&9>CKEDITOR.env.version&&(a[\"class\"]=\"cke_anchor\"),a=new CKEDITOR.style({element:\"a\",\nattributes:a}),a.type=CKEDITOR.STYLE_INLINE,c.applyStyle(a))}},onHide:function(){delete this._.selectedElement},onShow:function(){var a=c.getSelection(),b=a.getSelectedElement();if(b)CKEDITOR.plugins.link.fakeAnchor?((a=CKEDITOR.plugins.link.tryRestoreFakeAnchor(c,b))&&d.call(this,a),this._.selectedElement=b):b.is(\"a\")&&b.hasAttribute(\"name\")&&d.call(this,b);else if(b=CKEDITOR.plugins.link.getSelectedLink(c))d.call(this,b),a.selectElement(b);this.getContentElement(\"info\",\"txtName\").focus()},contents:[{id:\"info\",\nlabel:c.lang.link.anchor.title,accessKey:\"I\",elements:[{type:\"text\",id:\"txtName\",label:c.lang.link.anchor.name,required:!0,validate:function(){return!this.getValue()?(alert(c.lang.link.anchor.errorName),!1):!0}}]}]}});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/link/dialogs/link.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.dialog.add(\"link\",function(n){var p,q;function r(a){return a.replace(/'/g,\"\\\\$&\")}function t(a){var g,c=p,d,e;g=[q,\"(\"];for(var b=0;b<c.length;b++)d=c[b].toLowerCase(),e=a[d],0<b&&g.push(\",\"),g.push(\"'\",e?r(encodeURIComponent(a[d])):\"\",\"'\");g.push(\")\");return g.join(\"\")}function u(a){for(var g,c=a.length,d=[],e=0;e<c;e++)g=a.charCodeAt(e),d.push(g);return\"String.fromCharCode(\"+d.join(\",\")+\")\"}function v(a){return(a=a.getAttribute(\"class\"))?a.replace(/\\s*(?:cke_anchor_empty|cke_anchor)(?:\\s*$)?/g,\n\"\"):\"\"}var w=CKEDITOR.plugins.link,s=function(){var a=this.getDialog(),g=a.getContentElement(\"target\",\"popupFeatures\"),a=a.getContentElement(\"target\",\"linkTargetName\"),c=this.getValue();if(g&&a)switch(g=g.getElement(),g.hide(),a.setValue(\"\"),c){case \"frame\":a.setLabel(n.lang.link.targetFrameName);a.getElement().show();break;case \"popup\":g.show();a.setLabel(n.lang.link.targetPopupName);a.getElement().show();break;default:a.setValue(c),a.getElement().hide()}},x=/^javascript:/,y=/^mailto:([^?]+)(?:\\?(.+))?$/,\nz=/subject=([^;?:@&=$,\\/]*)/,A=/body=([^;?:@&=$,\\/]*)/,B=/^#(.*)$/,C=/^((?:http|https|ftp|news):\\/\\/)?(.*)$/,D=/^(_(?:self|top|parent|blank))$/,E=/^javascript:void\\(location\\.href='mailto:'\\+String\\.fromCharCode\\(([^)]+)\\)(?:\\+'(.*)')?\\)$/,F=/^javascript:([^(]+)\\(([^)]+)\\)$/,G=/\\s*window.open\\(\\s*this\\.href\\s*,\\s*(?:'([^']*)'|null)\\s*,\\s*'([^']*)'\\s*\\)\\s*;\\s*return\\s*false;*\\s*/,H=/(?:^|,)([^=]+)=(\\d+|yes|no)/gi,I=function(a,g){var c=g&&(g.data(\"cke-saved-href\")||g.getAttribute(\"href\"))||\"\",d,e,b=\n{};c.match(x)&&(\"encode\"==o?c=c.replace(E,function(a,c,b){return\"mailto:\"+String.fromCharCode.apply(String,c.split(\",\"))+(b&&b.replace(/\\\\'/g,\"'\"))}):o&&c.replace(F,function(a,c,d){if(c==q){b.type=\"email\";for(var a=b.email={},c=/(^')|('$)/g,d=d.match(/[^,\\s]+/g),e=d.length,g,f,h=0;h<e;h++)g=decodeURIComponent,f=d[h].replace(c,\"\").replace(/\\\\'/g,\"'\"),f=g(f),g=p[h].toLowerCase(),a[g]=f;a.address=[a.name,a.domain].join(\"@\")}}));if(!b.type)if(d=c.match(B))b.type=\"anchor\",b.anchor={},b.anchor.name=b.anchor.id=\nd[1];else if(d=c.match(y)){e=c.match(z);c=c.match(A);b.type=\"email\";var f=b.email={};f.address=d[1];e&&(f.subject=decodeURIComponent(e[1]));c&&(f.body=decodeURIComponent(c[1]))}else c&&(e=c.match(C))?(b.type=\"url\",b.url={},b.url.protocol=e[1],b.url.url=e[2]):b.type=\"url\";if(g){d=g.getAttribute(\"target\");b.target={};b.adv={};if(d)d.match(D)?b.target.type=b.target.name=d:(b.target.type=\"frame\",b.target.name=d);else if(d=(d=g.data(\"cke-pa-onclick\")||g.getAttribute(\"onclick\"))&&d.match(G)){b.target.type=\n\"popup\";for(b.target.name=d[1];c=H.exec(d[2]);)(\"yes\"==c[2]||\"1\"==c[2])&&!(c[1]in{height:1,width:1,top:1,left:1})?b.target[c[1]]=!0:isFinite(c[2])&&(b.target[c[1]]=c[2])}d=function(a,c){var d=g.getAttribute(c);null!==d&&(b.adv[a]=d||\"\")};d(\"advId\",\"id\");d(\"advLangDir\",\"dir\");d(\"advAccessKey\",\"accessKey\");b.adv.advName=g.data(\"cke-saved-name\")||g.getAttribute(\"name\")||\"\";d(\"advLangCode\",\"lang\");d(\"advTabIndex\",\"tabindex\");d(\"advTitle\",\"title\");d(\"advContentType\",\"type\");CKEDITOR.plugins.link.synAnchorSelector?\nb.adv.advCSSClasses=v(g):d(\"advCSSClasses\",\"class\");d(\"advCharset\",\"charset\");d(\"advStyles\",\"style\");d(\"advRel\",\"rel\")}d=b.anchors=[];var h;if(CKEDITOR.plugins.link.emptyAnchorFix){f=a.document.getElementsByTag(\"a\");c=0;for(e=f.count();c<e;c++)if(h=f.getItem(c),h.data(\"cke-saved-name\")||h.hasAttribute(\"name\"))d.push({name:h.data(\"cke-saved-name\")||h.getAttribute(\"name\"),id:h.getAttribute(\"id\")})}else{f=new CKEDITOR.dom.nodeList(a.document.$.anchors);c=0;for(e=f.count();c<e;c++)h=f.getItem(c),d[c]=\n{name:h.getAttribute(\"name\"),id:h.getAttribute(\"id\")}}if(CKEDITOR.plugins.link.fakeAnchor){f=a.document.getElementsByTag(\"img\");c=0;for(e=f.count();c<e;c++)(h=CKEDITOR.plugins.link.tryRestoreFakeAnchor(a,f.getItem(c)))&&d.push({name:h.getAttribute(\"name\"),id:h.getAttribute(\"id\")})}this._.selectedElement=g;return b},j=function(a){a.target&&this.setValue(a.target[this.id]||\"\")},k=function(a){a.adv&&this.setValue(a.adv[this.id]||\"\")},l=function(a){a.target||(a.target={});a.target[this.id]=this.getValue()||\n\"\"},m=function(a){a.adv||(a.adv={});a.adv[this.id]=this.getValue()||\"\"},o=n.config.emailProtection||\"\";o&&\"encode\"!=o&&(q=p=void 0,o.replace(/^([^(]+)\\(([^)]+)\\)$/,function(a,b,c){q=b;p=[];c.replace(/[^,\\s]+/g,function(a){p.push(a)})}));var i=n.lang.common,b=n.lang.link;return{title:b.title,minWidth:350,minHeight:230,contents:[{id:\"info\",label:b.info,title:b.info,elements:[{id:\"linkType\",type:\"select\",label:b.type,\"default\":\"url\",items:[[b.toUrl,\"url\"],[b.toAnchor,\"anchor\"],[b.toEmail,\"email\"]],onChange:function(){var a=\nthis.getDialog(),b=[\"urlOptions\",\"anchorOptions\",\"emailOptions\"],c=this.getValue(),d=a.definition.getContents(\"upload\"),d=d&&d.hidden;if(c==\"url\"){n.config.linkShowTargetTab&&a.showPage(\"target\");d||a.showPage(\"upload\")}else{a.hidePage(\"target\");d||a.hidePage(\"upload\")}for(d=0;d<b.length;d++){var e=a.getContentElement(\"info\",b[d]);if(e){e=e.getElement().getParent().getParent();b[d]==c+\"Options\"?e.show():e.hide()}}a.layout()},setup:function(a){a.type&&this.setValue(a.type)},commit:function(a){a.type=\nthis.getValue()}},{type:\"vbox\",id:\"urlOptions\",children:[{type:\"hbox\",widths:[\"25%\",\"75%\"],children:[{id:\"protocol\",type:\"select\",label:i.protocol,\"default\":\"http://\",items:[[\"http://‎\",\"http://\"],[\"https://‎\",\"https://\"],[\"ftp://‎\",\"ftp://\"],[\"news://‎\",\"news://\"],[b.other,\"\"]],setup:function(a){a.url&&this.setValue(a.url.protocol||\"\")},commit:function(a){if(!a.url)a.url={};a.url.protocol=this.getValue()}},{type:\"text\",id:\"url\",label:i.url,required:!0,onLoad:function(){this.allowOnChange=true},onKeyUp:function(){this.allowOnChange=\nfalse;var a=this.getDialog().getContentElement(\"info\",\"protocol\"),b=this.getValue(),c=/^((javascript:)|[#\\/\\.\\?])/i,d=/^(http|https|ftp|news):\\/\\/(?=.)/i.exec(b);if(d){this.setValue(b.substr(d[0].length));a.setValue(d[0].toLowerCase())}else c.test(b)&&a.setValue(\"\");this.allowOnChange=true},onChange:function(){if(this.allowOnChange)this.onKeyUp()},validate:function(){var a=this.getDialog();if(a.getContentElement(\"info\",\"linkType\")&&a.getValueOf(\"info\",\"linkType\")!=\"url\")return true;if(/javascript\\:/.test(this.getValue())){alert(i.invalidValue);\nreturn false}return this.getDialog().fakeObj?true:CKEDITOR.dialog.validate.notEmpty(b.noUrl).apply(this)},setup:function(a){this.allowOnChange=false;a.url&&this.setValue(a.url.url);this.allowOnChange=true},commit:function(a){this.onChange();if(!a.url)a.url={};a.url.url=this.getValue();this.allowOnChange=false}}],setup:function(){this.getDialog().getContentElement(\"info\",\"linkType\")||this.getElement().show()}},{type:\"button\",id:\"browse\",hidden:\"true\",filebrowser:\"info:url\",label:i.browseServer}]},\n{type:\"vbox\",id:\"anchorOptions\",width:260,align:\"center\",padding:0,children:[{type:\"fieldset\",id:\"selectAnchorText\",label:b.selectAnchor,setup:function(a){a.anchors.length>0?this.getElement().show():this.getElement().hide()},children:[{type:\"hbox\",id:\"selectAnchor\",children:[{type:\"select\",id:\"anchorName\",\"default\":\"\",label:b.anchorName,style:\"width: 100%;\",items:[[\"\"]],setup:function(a){this.clear();this.add(\"\");for(var b=0;b<a.anchors.length;b++)a.anchors[b].name&&this.add(a.anchors[b].name);a.anchor&&\nthis.setValue(a.anchor.name);(a=this.getDialog().getContentElement(\"info\",\"linkType\"))&&a.getValue()==\"email\"&&this.focus()},commit:function(a){if(!a.anchor)a.anchor={};a.anchor.name=this.getValue()}},{type:\"select\",id:\"anchorId\",\"default\":\"\",label:b.anchorId,style:\"width: 100%;\",items:[[\"\"]],setup:function(a){this.clear();this.add(\"\");for(var b=0;b<a.anchors.length;b++)a.anchors[b].id&&this.add(a.anchors[b].id);a.anchor&&this.setValue(a.anchor.id)},commit:function(a){if(!a.anchor)a.anchor={};a.anchor.id=\nthis.getValue()}}],setup:function(a){a.anchors.length>0?this.getElement().show():this.getElement().hide()}}]},{type:\"html\",id:\"noAnchors\",style:\"text-align: center;\",html:'<div role=\"note\" tabIndex=\"-1\">'+CKEDITOR.tools.htmlEncode(b.noAnchors)+\"</div>\",focus:!0,setup:function(a){a.anchors.length<1?this.getElement().show():this.getElement().hide()}}],setup:function(){this.getDialog().getContentElement(\"info\",\"linkType\")||this.getElement().hide()}},{type:\"vbox\",id:\"emailOptions\",padding:1,children:[{type:\"text\",\nid:\"emailAddress\",label:b.emailAddress,required:!0,validate:function(){var a=this.getDialog();return!a.getContentElement(\"info\",\"linkType\")||a.getValueOf(\"info\",\"linkType\")!=\"email\"?true:CKEDITOR.dialog.validate.notEmpty(b.noEmail).apply(this)},setup:function(a){a.email&&this.setValue(a.email.address);(a=this.getDialog().getContentElement(\"info\",\"linkType\"))&&a.getValue()==\"email\"&&this.select()},commit:function(a){if(!a.email)a.email={};a.email.address=this.getValue()}},{type:\"text\",id:\"emailSubject\",\nlabel:b.emailSubject,setup:function(a){a.email&&this.setValue(a.email.subject)},commit:function(a){if(!a.email)a.email={};a.email.subject=this.getValue()}},{type:\"textarea\",id:\"emailBody\",label:b.emailBody,rows:3,\"default\":\"\",setup:function(a){a.email&&this.setValue(a.email.body)},commit:function(a){if(!a.email)a.email={};a.email.body=this.getValue()}}],setup:function(){this.getDialog().getContentElement(\"info\",\"linkType\")||this.getElement().hide()}}]},{id:\"target\",requiredContent:\"a[target]\",label:b.target,\ntitle:b.target,elements:[{type:\"hbox\",widths:[\"50%\",\"50%\"],children:[{type:\"select\",id:\"linkTargetType\",label:i.target,\"default\":\"notSet\",style:\"width : 100%;\",items:[[i.notSet,\"notSet\"],[b.targetFrame,\"frame\"],[b.targetPopup,\"popup\"],[i.targetNew,\"_blank\"],[i.targetTop,\"_top\"],[i.targetSelf,\"_self\"],[i.targetParent,\"_parent\"]],onChange:s,setup:function(a){a.target&&this.setValue(a.target.type||\"notSet\");s.call(this)},commit:function(a){if(!a.target)a.target={};a.target.type=this.getValue()}},{type:\"text\",\nid:\"linkTargetName\",label:b.targetFrameName,\"default\":\"\",setup:function(a){a.target&&this.setValue(a.target.name)},commit:function(a){if(!a.target)a.target={};a.target.name=this.getValue().replace(/\\W/gi,\"\")}}]},{type:\"vbox\",width:\"100%\",align:\"center\",padding:2,id:\"popupFeatures\",children:[{type:\"fieldset\",label:b.popupFeatures,children:[{type:\"hbox\",children:[{type:\"checkbox\",id:\"resizable\",label:b.popupResizable,setup:j,commit:l},{type:\"checkbox\",id:\"status\",label:b.popupStatusBar,setup:j,commit:l}]},\n{type:\"hbox\",children:[{type:\"checkbox\",id:\"location\",label:b.popupLocationBar,setup:j,commit:l},{type:\"checkbox\",id:\"toolbar\",label:b.popupToolbar,setup:j,commit:l}]},{type:\"hbox\",children:[{type:\"checkbox\",id:\"menubar\",label:b.popupMenuBar,setup:j,commit:l},{type:\"checkbox\",id:\"fullscreen\",label:b.popupFullScreen,setup:j,commit:l}]},{type:\"hbox\",children:[{type:\"checkbox\",id:\"scrollbars\",label:b.popupScrollBars,setup:j,commit:l},{type:\"checkbox\",id:\"dependent\",label:b.popupDependent,setup:j,commit:l}]},\n{type:\"hbox\",children:[{type:\"text\",widths:[\"50%\",\"50%\"],labelLayout:\"horizontal\",label:i.width,id:\"width\",setup:j,commit:l},{type:\"text\",labelLayout:\"horizontal\",widths:[\"50%\",\"50%\"],label:b.popupLeft,id:\"left\",setup:j,commit:l}]},{type:\"hbox\",children:[{type:\"text\",labelLayout:\"horizontal\",widths:[\"50%\",\"50%\"],label:i.height,id:\"height\",setup:j,commit:l},{type:\"text\",labelLayout:\"horizontal\",label:b.popupTop,widths:[\"50%\",\"50%\"],id:\"top\",setup:j,commit:l}]}]}]}]},{id:\"upload\",label:b.upload,title:b.upload,\nhidden:!0,filebrowser:\"uploadButton\",elements:[{type:\"file\",id:\"upload\",label:i.upload,style:\"height:40px\",size:29},{type:\"fileButton\",id:\"uploadButton\",label:i.uploadSubmit,filebrowser:\"info:url\",\"for\":[\"upload\",\"upload\"]}]},{id:\"advanced\",label:b.advanced,title:b.advanced,elements:[{type:\"vbox\",padding:1,children:[{type:\"hbox\",widths:[\"45%\",\"35%\",\"20%\"],children:[{type:\"text\",id:\"advId\",requiredContent:\"a[id]\",label:b.id,setup:k,commit:m},{type:\"select\",id:\"advLangDir\",requiredContent:\"a[dir]\",\nlabel:b.langDir,\"default\":\"\",style:\"width:110px\",items:[[i.notSet,\"\"],[b.langDirLTR,\"ltr\"],[b.langDirRTL,\"rtl\"]],setup:k,commit:m},{type:\"text\",id:\"advAccessKey\",requiredContent:\"a[accesskey]\",width:\"80px\",label:b.acccessKey,maxLength:1,setup:k,commit:m}]},{type:\"hbox\",widths:[\"45%\",\"35%\",\"20%\"],children:[{type:\"text\",label:b.name,id:\"advName\",requiredContent:\"a[name]\",setup:k,commit:m},{type:\"text\",label:b.langCode,id:\"advLangCode\",requiredContent:\"a[lang]\",width:\"110px\",\"default\":\"\",setup:k,commit:m},\n{type:\"text\",label:b.tabIndex,id:\"advTabIndex\",requiredContent:\"a[tabindex]\",width:\"80px\",maxLength:5,setup:k,commit:m}]}]},{type:\"vbox\",padding:1,children:[{type:\"hbox\",widths:[\"45%\",\"55%\"],children:[{type:\"text\",label:b.advisoryTitle,requiredContent:\"a[title]\",\"default\":\"\",id:\"advTitle\",setup:k,commit:m},{type:\"text\",label:b.advisoryContentType,requiredContent:\"a[type]\",\"default\":\"\",id:\"advContentType\",setup:k,commit:m}]},{type:\"hbox\",widths:[\"45%\",\"55%\"],children:[{type:\"text\",label:b.cssClasses,\nrequiredContent:\"a(cke-xyz)\",\"default\":\"\",id:\"advCSSClasses\",setup:k,commit:m},{type:\"text\",label:b.charset,requiredContent:\"a[charset]\",\"default\":\"\",id:\"advCharset\",setup:k,commit:m}]},{type:\"hbox\",widths:[\"45%\",\"55%\"],children:[{type:\"text\",label:b.rel,requiredContent:\"a[rel]\",\"default\":\"\",id:\"advRel\",setup:k,commit:m},{type:\"text\",label:b.styles,requiredContent:\"a{cke-xyz}\",\"default\":\"\",id:\"advStyles\",validate:CKEDITOR.dialog.validate.inlineStyle(n.lang.common.invalidInlineStyle),setup:k,commit:m}]}]}]}],\nonShow:function(){var a=this.getParentEditor(),b=a.getSelection(),c=null;(c=w.getSelectedLink(a))&&c.hasAttribute(\"href\")?b.getSelectedElement()||b.selectElement(c):c=null;this.setupContent(I.apply(this,[a,c]))},onOk:function(){var a={},b=[],c={},d=this.getParentEditor();this.commitContent(c);switch(c.type||\"url\"){case \"url\":var e=c.url&&c.url.protocol!=void 0?c.url.protocol:\"http://\",i=c.url&&CKEDITOR.tools.trim(c.url.url)||\"\";a[\"data-cke-saved-href\"]=i.indexOf(\"/\")===0?i:e+i;break;case \"anchor\":e=\nc.anchor&&c.anchor.id;a[\"data-cke-saved-href\"]=\"#\"+(c.anchor&&c.anchor.name||e||\"\");break;case \"email\":var f=c.email,e=f.address;switch(o){case \"\":case \"encode\":var i=encodeURIComponent(f.subject||\"\"),h=encodeURIComponent(f.body||\"\"),f=[];i&&f.push(\"subject=\"+i);h&&f.push(\"body=\"+h);f=f.length?\"?\"+f.join(\"&\"):\"\";if(o==\"encode\"){e=[\"javascript:void(location.href='mailto:'+\",u(e)];f&&e.push(\"+'\",r(f),\"'\");e.push(\")\")}else e=[\"mailto:\",e,f];break;default:e=e.split(\"@\",2);f.name=e[0];f.domain=e[1];e=\n[\"javascript:\",t(f)]}a[\"data-cke-saved-href\"]=e.join(\"\")}if(c.target)if(c.target.type==\"popup\"){for(var e=[\"window.open(this.href, '\",c.target.name||\"\",\"', '\"],j=[\"resizable\",\"status\",\"location\",\"toolbar\",\"menubar\",\"fullscreen\",\"scrollbars\",\"dependent\"],i=j.length,f=function(a){c.target[a]&&j.push(a+\"=\"+c.target[a])},h=0;h<i;h++)j[h]=j[h]+(c.target[j[h]]?\"=yes\":\"=no\");f(\"width\");f(\"left\");f(\"height\");f(\"top\");e.push(j.join(\",\"),\"'); return false;\");a[\"data-cke-pa-onclick\"]=e.join(\"\");b.push(\"target\")}else{c.target.type!=\n\"notSet\"&&c.target.name?a.target=c.target.name:b.push(\"target\");b.push(\"data-cke-pa-onclick\",\"onclick\")}if(c.adv){e=function(d,e){var f=c.adv[d];f?a[e]=f:b.push(e)};e(\"advId\",\"id\");e(\"advLangDir\",\"dir\");e(\"advAccessKey\",\"accessKey\");c.adv.advName?a.name=a[\"data-cke-saved-name\"]=c.adv.advName:b=b.concat([\"data-cke-saved-name\",\"name\"]);e(\"advLangCode\",\"lang\");e(\"advTabIndex\",\"tabindex\");e(\"advTitle\",\"title\");e(\"advContentType\",\"type\");e(\"advCSSClasses\",\"class\");e(\"advCharset\",\"charset\");e(\"advStyles\",\n\"style\");e(\"advRel\",\"rel\")}e=d.getSelection();a.href=a[\"data-cke-saved-href\"];if(this._.selectedElement){d=this._.selectedElement;i=d.data(\"cke-saved-href\");f=d.getHtml();d.setAttributes(a);d.removeAttributes(b);c.adv&&(c.adv.advName&&CKEDITOR.plugins.link.synAnchorSelector)&&d.addClass(d.getChildCount()?\"cke_anchor\":\"cke_anchor_empty\");if(i==f||c.type==\"email\"&&f.indexOf(\"@\")!=-1){d.setHtml(c.type==\"email\"?c.email.address:a[\"data-cke-saved-href\"]);e.selectElement(d)}delete this._.selectedElement}else{e=\ne.getRanges()[0];if(e.collapsed){d=new CKEDITOR.dom.text(c.type==\"email\"?c.email.address:a[\"data-cke-saved-href\"],d.document);e.insertNode(d);e.selectNodeContents(d)}d=new CKEDITOR.style({element:\"a\",attributes:a});d.type=CKEDITOR.STYLE_INLINE;d.applyToRange(e);e.select()}},onLoad:function(){n.config.linkShowAdvancedTab||this.hidePage(\"advanced\");n.config.linkShowTargetTab||this.hidePage(\"target\")},onFocus:function(){var a=this.getContentElement(\"info\",\"linkType\");if(a&&a.getValue()==\"url\"){a=this.getContentElement(\"info\",\n\"url\");a.select()}}}});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/pastefromword/filter/default.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n(function(){function y(a){for(var a=a.toUpperCase(),c=z.length,b=0,f=0;f<c;++f)for(var d=z[f],e=d[1].length;a.substr(0,e)==d[1];a=a.substr(e))b+=d[0];return b}function A(a){for(var a=a.toUpperCase(),c=B.length,b=1,f=1;0<a.length;f*=c)b+=B.indexOf(a.charAt(a.length-1))*f,a=a.substr(0,a.length-1);return b}var C=CKEDITOR.htmlParser.fragment.prototype,o=CKEDITOR.htmlParser.element.prototype;C.onlyChild=o.onlyChild=function(){var a=this.children;return 1==a.length&&a[0]||null};o.removeAnyChildWithName=\nfunction(a){for(var c=this.children,b=[],f,d=0;d<c.length;d++)f=c[d],f.name&&(f.name==a&&(b.push(f),c.splice(d--,1)),b=b.concat(f.removeAnyChildWithName(a)));return b};o.getAncestor=function(a){for(var c=this.parent;c&&(!c.name||!c.name.match(a));)c=c.parent;return c};C.firstChild=o.firstChild=function(a){for(var c,b=0;b<this.children.length;b++)if(c=this.children[b],a(c)||c.name&&(c=c.firstChild(a)))return c;return null};o.addStyle=function(a,c,b){var f=\"\";if(\"string\"==typeof c)f+=a+\":\"+c+\";\";else{if(\"object\"==\ntypeof a)for(var d in a)a.hasOwnProperty(d)&&(f+=d+\":\"+a[d]+\";\");else f+=a;b=c}this.attributes||(this.attributes={});a=this.attributes.style||\"\";a=(b?[f,a]:[a,f]).join(\";\");this.attributes.style=a.replace(/^;|;(?=;)/,\"\")};o.getStyle=function(a){var c=this.attributes.style;if(c)return c=CKEDITOR.tools.parseCssText(c,1),c[a]};CKEDITOR.dtd.parentOf=function(a){var c={},b;for(b in this)-1==b.indexOf(\"$\")&&this[b][a]&&(c[b]=1);return c};var H=/^([.\\d]*)+(em|ex|px|gd|rem|vw|vh|vm|ch|mm|cm|in|pt|pc|deg|rad|ms|s|hz|khz){1}?/i,\nD=/^(?:\\b0[^\\s]*\\s*){1,4}$/,x={ol:{decimal:/\\d+/,\"lower-roman\":/^m{0,4}(cm|cd|d?c{0,3})(xc|xl|l?x{0,3})(ix|iv|v?i{0,3})$/,\"upper-roman\":/^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/,\"lower-alpha\":/^[a-z]+$/,\"upper-alpha\":/^[A-Z]+$/},ul:{disc:/[l\\u00B7\\u2002]/,circle:/[\\u006F\\u00D8]/,square:/[\\u006E\\u25C6]/}},z=[[1E3,\"M\"],[900,\"CM\"],[500,\"D\"],[400,\"CD\"],[100,\"C\"],[90,\"XC\"],[50,\"L\"],[40,\"XL\"],[10,\"X\"],[9,\"IX\"],[5,\"V\"],[4,\"IV\"],[1,\"I\"]],B=\"ABCDEFGHIJKLMNOPQRSTUVWXYZ\",s=0,t=null,w,E=CKEDITOR.plugins.pastefromword=\n{utils:{createListBulletMarker:function(a,c){var b=new CKEDITOR.htmlParser.element(\"cke:listbullet\");b.attributes={\"cke:listsymbol\":a[0]};b.add(new CKEDITOR.htmlParser.text(c));return b},isListBulletIndicator:function(a){if(/mso-list\\s*:\\s*Ignore/i.test(a.attributes&&a.attributes.style))return!0},isContainingOnlySpaces:function(a){var c;return(c=a.onlyChild())&&/^(:?\\s|&nbsp;)+$/.test(c.value)},resolveList:function(a){var c=a.attributes,b;if((b=a.removeAnyChildWithName(\"cke:listbullet\"))&&b.length&&\n(b=b[0]))return a.name=\"cke:li\",c.style&&(c.style=E.filters.stylesFilter([[\"text-indent\"],[\"line-height\"],[/^margin(:?-left)?$/,null,function(a){a=a.split(\" \");a=CKEDITOR.tools.convertToPx(a[3]||a[1]||a[0]);!s&&(null!==t&&a>t)&&(s=a-t);t=a;c[\"cke:indent\"]=s&&Math.ceil(a/s)+1||1}],[/^mso-list$/,null,function(a){var a=a.split(\" \"),b=Number(a[0].match(/\\d+/)),a=Number(a[1].match(/\\d+/));1==a&&(b!==w&&(c[\"cke:reset\"]=1),w=b);c[\"cke:indent\"]=a}]])(c.style,a)||\"\"),c[\"cke:indent\"]||(t=0,c[\"cke:indent\"]=\n1),CKEDITOR.tools.extend(c,b.attributes),!0;w=t=s=null;return!1},getStyleComponents:function(){var a=CKEDITOR.dom.element.createFromHtml('<div style=\"position:absolute;left:-9999px;top:-9999px;\"></div>',CKEDITOR.document);CKEDITOR.document.getBody().append(a);return function(c,b,f){a.setStyle(c,b);for(var c={},b=f.length,d=0;d<b;d++)c[f[d]]=a.getStyle(f[d]);return c}}(),listDtdParents:CKEDITOR.dtd.parentOf(\"ol\")},filters:{flattenList:function(a,c){var c=\"number\"==typeof c?c:1,b=a.attributes,f;switch(b.type){case \"a\":f=\n\"lower-alpha\";break;case \"1\":f=\"decimal\"}for(var d=a.children,e,h=0;h<d.length;h++)if(e=d[h],e.name in CKEDITOR.dtd.$listItem){var j=e.attributes,g=e.children,m=g[g.length-1];m.name in CKEDITOR.dtd.$list&&(a.add(m,h+1),--g.length||d.splice(h--,1));e.name=\"cke:li\";b.start&&!h&&(j.value=b.start);E.filters.stylesFilter([[\"tab-stops\",null,function(a){(a=a.split(\" \")[1].match(H))&&(t=CKEDITOR.tools.convertToPx(a[0]))}],1==c?[\"mso-list\",null,function(a){a=a.split(\" \");a=Number(a[0].match(/\\d+/));a!==w&&\n(j[\"cke:reset\"]=1);w=a}]:null])(j.style);j[\"cke:indent\"]=c;j[\"cke:listtype\"]=a.name;j[\"cke:list-style-type\"]=f}else if(e.name in CKEDITOR.dtd.$list){arguments.callee.apply(this,[e,c+1]);d=d.slice(0,h).concat(e.children).concat(d.slice(h+1));a.children=[];e=0;for(g=d.length;e<g;e++)a.add(d[e]);d=a.children}delete a.name;b[\"cke:list\"]=1},assembleList:function(a){for(var c=a.children,b,f,d,e,h,j,a=[],g,m,i,l,k,p,n=0;n<c.length;n++)if(b=c[n],\"cke:li\"==b.name)if(b.name=\"li\",f=b.attributes,i=(i=f[\"cke:listsymbol\"])&&\ni.match(/^(?:[(]?)([^\\s]+?)([.)]?)$/),l=k=p=null,f[\"cke:ignored\"])c.splice(n--,1);else{f[\"cke:reset\"]&&(j=e=h=null);d=Number(f[\"cke:indent\"]);d!=e&&(m=g=null);if(i){if(m&&x[m][g].test(i[1]))l=m,k=g;else for(var q in x)for(var u in x[q])if(x[q][u].test(i[1]))if(\"ol\"==q&&/alpha|roman/.test(u)){if(g=/roman/.test(u)?y(i[1]):A(i[1]),!p||g<p)p=g,l=q,k=u}else{l=q;k=u;break}!l&&(l=i[2]?\"ol\":\"ul\")}else l=f[\"cke:listtype\"]||\"ol\",k=f[\"cke:list-style-type\"];m=l;g=k||(\"ol\"==l?\"decimal\":\"disc\");k&&k!=(\"ol\"==l?\n\"decimal\":\"disc\")&&b.addStyle(\"list-style-type\",k);if(\"ol\"==l&&i){switch(k){case \"decimal\":p=Number(i[1]);break;case \"lower-roman\":case \"upper-roman\":p=y(i[1]);break;case \"lower-alpha\":case \"upper-alpha\":p=A(i[1])}b.attributes.value=p}if(j){if(d>e)a.push(j=new CKEDITOR.htmlParser.element(l)),j.add(b),h.add(j);else{if(d<e){e-=d;for(var r;e--&&(r=j.parent);)j=r.parent}j.add(b)}c.splice(n--,1)}else a.push(j=new CKEDITOR.htmlParser.element(l)),j.add(b),c[n]=j;h=b;e=d}else j&&(j=e=h=null);for(n=0;n<a.length;n++)if(j=\na[n],q=j.children,g=g=void 0,u=j.children.length,r=g=void 0,c=/list-style-type:(.*?)(?:;|$)/,e=CKEDITOR.plugins.pastefromword.filters.stylesFilter,g=j.attributes,!c.exec(g.style)){for(h=0;h<u;h++)if(g=q[h],g.attributes.value&&Number(g.attributes.value)==h+1&&delete g.attributes.value,g=c.exec(g.attributes.style))if(g[1]==r||!r)r=g[1];else{r=null;break}if(r){for(h=0;h<u;h++)g=q[h].attributes,g.style&&(g.style=e([[\"list-style-type\"]])(g.style)||\"\");j.addStyle(\"list-style-type\",r)}}w=t=s=null},falsyFilter:function(){return!1},\nstylesFilter:function(a,c){return function(b,f){var d=[];(b||\"\").replace(/&quot;/g,'\"').replace(/\\s*([^ :;]+)\\s*:\\s*([^;]+)\\s*(?=;|$)/g,function(b,e,g){e=e.toLowerCase();\"font-family\"==e&&(g=g.replace(/[\"']/g,\"\"));for(var m,i,l,k=0;k<a.length;k++)if(a[k]&&(b=a[k][0],m=a[k][1],i=a[k][2],l=a[k][3],e.match(b)&&(!m||g.match(m)))){e=l||e;c&&(i=i||g);\"function\"==typeof i&&(i=i(g,f,e));i&&i.push&&(e=i[0],i=i[1]);\"string\"==typeof i&&d.push([e,i]);return}!c&&d.push([e,g])});for(var e=0;e<d.length;e++)d[e]=\nd[e].join(\":\");return d.length?d.join(\";\")+\";\":!1}},elementMigrateFilter:function(a,c){return a?function(b){var f=c?(new CKEDITOR.style(a,c))._.definition:a;b.name=f.element;CKEDITOR.tools.extend(b.attributes,CKEDITOR.tools.clone(f.attributes));b.addStyle(CKEDITOR.style.getStyleText(f))}:function(){}},styleMigrateFilter:function(a,c){var b=this.elementMigrateFilter;return a?function(f,d){var e=new CKEDITOR.htmlParser.element(null),h={};h[c]=f;b(a,h)(e);e.children=d.children;d.children=[e];e.filter=\nfunction(){};e.parent=d}:function(){}},bogusAttrFilter:function(a,c){if(-1==c.name.indexOf(\"cke:\"))return!1},applyStyleFilter:null},getRules:function(a,c){var b=CKEDITOR.dtd,f=CKEDITOR.tools.extend({},b.$block,b.$listItem,b.$tableContent),d=a.config,e=this.filters,h=e.falsyFilter,j=e.stylesFilter,g=e.elementMigrateFilter,m=CKEDITOR.tools.bind(this.filters.styleMigrateFilter,this.filters),i=this.utils.createListBulletMarker,l=e.flattenList,k=e.assembleList,p=this.utils.isListBulletIndicator,n=this.utils.isContainingOnlySpaces,\nq=this.utils.resolveList,u=function(a){a=CKEDITOR.tools.convertToPx(a);return isNaN(a)?a:a+\"px\"},r=this.utils.getStyleComponents,t=this.utils.listDtdParents,o=!1!==d.pasteFromWordRemoveFontStyles,s=!1!==d.pasteFromWordRemoveStyles;return{elementNames:[[/meta|link|script/,\"\"]],root:function(a){a.filterChildren(c);k(a)},elements:{\"^\":function(a){var c;CKEDITOR.env.gecko&&(c=e.applyStyleFilter)&&c(a)},$:function(a){var v=a.name||\"\",e=a.attributes;v in f&&e.style&&(e.style=j([[/^(:?width|height)$/,null,\nu]])(e.style)||\"\");if(v.match(/h\\d/)){a.filterChildren(c);if(q(a))return;g(d[\"format_\"+v])(a)}else if(v in b.$inline)a.filterChildren(c),n(a)&&delete a.name;else if(-1!=v.indexOf(\":\")&&-1==v.indexOf(\"cke\")){a.filterChildren(c);if(\"v:imagedata\"==v){if(v=a.attributes[\"o:href\"])a.attributes.src=v;a.name=\"img\";return}delete a.name}v in t&&(a.filterChildren(c),k(a))},style:function(a){if(CKEDITOR.env.gecko){var a=(a=a.onlyChild().value.match(/\\/\\* Style Definitions \\*\\/([\\s\\S]*?)\\/\\*/))&&a[1],c={};a&&\n(a.replace(/[\\n\\r]/g,\"\").replace(/(.+?)\\{(.+?)\\}/g,function(a,b,F){for(var b=b.split(\",\"),a=b.length,d=0;d<a;d++)CKEDITOR.tools.trim(b[d]).replace(/^(\\w+)(\\.[\\w-]+)?$/g,function(a,b,d){b=b||\"*\";d=d.substring(1,d.length);d.match(/MsoNormal/)||(c[b]||(c[b]={}),d?c[b][d]=F:c[b]=F)})}),e.applyStyleFilter=function(a){var b=c[\"*\"]?\"*\":a.name,d=a.attributes&&a.attributes[\"class\"];b in c&&(b=c[b],\"object\"==typeof b&&(b=b[d]),b&&a.addStyle(b,!0))})}return!1},p:function(a){if(/MsoListParagraph/i.exec(a.attributes[\"class\"])||\na.getStyle(\"mso-list\")){var b=a.firstChild(function(a){return a.type==CKEDITOR.NODE_TEXT&&!n(a.parent)});(b=b&&b.parent)&&b.addStyle(\"mso-list\",\"Ignore\")}a.filterChildren(c);q(a)||(d.enterMode==CKEDITOR.ENTER_BR?(delete a.name,a.add(new CKEDITOR.htmlParser.element(\"br\"))):g(d[\"format_\"+(d.enterMode==CKEDITOR.ENTER_P?\"p\":\"div\")])(a))},div:function(a){var c=a.onlyChild();if(c&&\"table\"==c.name){var b=a.attributes;c.attributes=CKEDITOR.tools.extend(c.attributes,b);b.style&&c.addStyle(b.style);c=new CKEDITOR.htmlParser.element(\"div\");\nc.addStyle(\"clear\",\"both\");a.add(c);delete a.name}},td:function(a){a.getAncestor(\"thead\")&&(a.name=\"th\")},ol:l,ul:l,dl:l,font:function(a){if(p(a.parent))delete a.name;else{a.filterChildren(c);var b=a.attributes,d=b.style,e=a.parent;\"font\"==e.name?(CKEDITOR.tools.extend(e.attributes,a.attributes),d&&e.addStyle(d),delete a.name):(d=d||\"\",b.color&&(\"#000000\"!=b.color&&(d+=\"color:\"+b.color+\";\"),delete b.color),b.face&&(d+=\"font-family:\"+b.face+\";\",delete b.face),b.size&&(d+=\"font-size:\"+(3<b.size?\"large\":\n3>b.size?\"small\":\"medium\")+\";\",delete b.size),a.name=\"span\",a.addStyle(d))}},span:function(a){if(p(a.parent))return!1;a.filterChildren(c);if(n(a))return delete a.name,null;if(p(a)){var b=a.firstChild(function(a){return a.value||\"img\"==a.name}),e=(b=b&&(b.value||\"l.\"))&&b.match(/^(?:[(]?)([^\\s]+?)([.)]?)$/);if(e)return b=i(e,b),(a=a.getAncestor(\"span\"))&&/ mso-hide:\\s*all|display:\\s*none /.test(a.attributes.style)&&(b.attributes[\"cke:ignored\"]=1),b}if(e=(b=a.attributes)&&b.style)b.style=j([[\"line-height\"],\n[/^font-family$/,null,!o?m(d.font_style,\"family\"):null],[/^font-size$/,null,!o?m(d.fontSize_style,\"size\"):null],[/^color$/,null,!o?m(d.colorButton_foreStyle,\"color\"):null],[/^background-color$/,null,!o?m(d.colorButton_backStyle,\"color\"):null]])(e,a)||\"\";b.style||delete b.style;CKEDITOR.tools.isEmpty(b)&&delete a.name;return null},b:g(d.coreStyles_bold),i:g(d.coreStyles_italic),u:g(d.coreStyles_underline),s:g(d.coreStyles_strike),sup:g(d.coreStyles_superscript),sub:g(d.coreStyles_subscript),a:function(a){a=\na.attributes;a.href&&a.href.match(/^file:\\/\\/\\/[\\S]+#/i)&&(a.href=a.href.replace(/^file:\\/\\/\\/[^#]+/i,\"\"))},\"cke:listbullet\":function(a){a.getAncestor(/h\\d/)&&!d.pasteFromWordNumberedHeadingToList&&delete a.name}},attributeNames:[[/^onmouse(:?out|over)/,\"\"],[/^onload$/,\"\"],[/(?:v|o):\\w+/,\"\"],[/^lang/,\"\"]],attributes:{style:j(s?[[/^list-style-type$/,null],[/^margin$|^margin-(?!bottom|top)/,null,function(a,b,c){if(b.name in{p:1,div:1}){b=\"ltr\"==d.contentsLangDirection?\"margin-left\":\"margin-right\";if(\"margin\"==\nc)a=r(c,a,[b])[b];else if(c!=b)return null;if(a&&!D.test(a))return[b,a]}return null}],[/^clear$/],[/^border.*|margin.*|vertical-align|float$/,null,function(a,b){if(\"img\"==b.name)return a}],[/^width|height$/,null,function(a,b){if(b.name in{table:1,td:1,th:1,img:1})return a}]]:[[/^mso-/],[/-color$/,null,function(a){if(\"transparent\"==a)return!1;if(CKEDITOR.env.gecko)return a.replace(/-moz-use-text-color/g,\"transparent\")}],[/^margin$/,D],[\"text-indent\",\"0cm\"],[\"page-break-before\"],[\"tab-stops\"],[\"display\",\n\"none\"],o?[/font-?/]:null],s),width:function(a,c){if(c.name in b.$tableContent)return!1},border:function(a,c){if(c.name in b.$tableContent)return!1},\"class\":h,bgcolor:h,valign:s?h:function(a,b){b.addStyle(\"vertical-align\",a);return!1}},comment:!CKEDITOR.env.ie?function(a,b){var c=a.match(/<img.*?>/),d=a.match(/^\\[if !supportLists\\]([\\s\\S]*?)\\[endif\\]$/);return d?(d=(c=d[1]||c&&\"l.\")&&c.match(/>(?:[(]?)([^\\s]+?)([.)]?)</),i(d,c)):CKEDITOR.env.gecko&&c?(c=CKEDITOR.htmlParser.fragment.fromHtml(c[0]).children[0],\n(d=(d=(d=b.previous)&&d.value.match(/<v:imagedata[^>]*o:href=['\"](.*?)['\"]/))&&d[1])&&(c.attributes.src=d),c):!1}:h}}},G=function(){this.dataFilter=new CKEDITOR.htmlParser.filter};G.prototype={toHtml:function(a){var a=CKEDITOR.htmlParser.fragment.fromHtml(a),c=new CKEDITOR.htmlParser.basicWriter;a.writeHtml(c,this.dataFilter);return c.getHtml(!0)}};CKEDITOR.cleanWord=function(a,c){CKEDITOR.env.gecko&&(a=a.replace(/(<\\!--\\[if[^<]*?\\])--\\>([\\S\\s]*?)<\\!--(\\[endif\\]--\\>)/gi,\"$1$2$3\"));CKEDITOR.env.webkit&&\n(a=a.replace(/(class=\"MsoListParagraph[^>]+><\\!--\\[if !supportLists\\]--\\>)([^<]+<span[^<]+<\\/span>)(<\\!--\\[endif\\]--\\>)/gi,\"$1<span>$2</span>$3\"));var b=new G,f=b.dataFilter;f.addRules(CKEDITOR.plugins.pastefromword.getRules(c,f));c.fire(\"beforeCleanWord\",{filter:f});try{a=b.toHtml(a)}catch(d){alert(c.lang.pastefromword.error)}a=a.replace(/cke:.*?\".*?\"/g,\"\");a=a.replace(/style=\"\"/g,\"\");return a=a.replace(/<span>/g,\"\")}})();"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/scayt/LICENSE.md",
    "content": "Software License Agreement\r\n==========================\r\n\r\n**CKEditor SCAYT Plugin**\r\nCopyright &copy; 2012, [CKSource](http://cksource.com) - Frederico Knabben. All rights reserved.\r\n\r\nLicensed under the terms of any of the following licenses at your choice:\r\n\r\n*   GNU General Public License Version 2 or later (the \"GPL\"):\r\n    http://www.gnu.org/licenses/gpl.html\r\n\r\n*   GNU Lesser General Public License Version 2.1 or later (the \"LGPL\"):\r\n    http://www.gnu.org/licenses/lgpl.html\r\n\r\n*   Mozilla Public License Version 1.1 or later (the \"MPL\"):\r\n    http://www.mozilla.org/MPL/MPL-1.1.html\r\n\r\nYou are not required to, but if you want to explicitly declare the license you have chosen to be bound to when using, reproducing, modifying and distributing this software, just include a text file titled \"legal.txt\" in your version of this software, indicating your license choice.\r\n\r\nSources of Intellectual Property Included in this plugin\r\n--------------------------------------------------------\r\n\r\nWhere not otherwise indicated, all plugin content is authored by CKSource engineers and consists of CKSource-owned intellectual property. In some specific instances, the plugin will incorporate work done by developers outside of CKSource with their express permission.\r\n\r\nTrademarks\r\n----------\r\n\r\nCKEditor is a trademark of CKSource - Frederico Knabben. All other brand and product names are trademarks, registered trademarks or service marks of their respective holders.\r\n"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/scayt/README.md",
    "content": "CKEditor SCAYT Plugin\r\n=====================\r\n\r\nThis plugin brings Spell Check As You Type (SCAYT) into CKEditor.\r\n\r\nSCAYT is a \"installation-less\", using the web-services of [WebSpellChecker.net](http://www.webspellchecker.net/). It's an out of the box solution.\r\n\r\nInstallation\r\n------------\r\n\r\n1. Clone/copy this repository contents in a new \"plugins/scayt\" folder in your CKEditor installation.\r\n2. Enable the \"scayt\" plugin in the CKEditor configuration file (config.js):\r\n\r\n        config.extraPlugins = 'scayt';\r\n\r\nThat's all. SCAYT will appear on the editor toolbar and will be ready to use.\r\n\r\nLicense\r\n-------\r\n\r\nLicensed under the terms of any of the following licenses at your choice: [GPL](http://www.gnu.org/licenses/gpl.html), [LGPL](http://www.gnu.org/licenses/lgpl.html) and [MPL](http://www.mozilla.org/MPL/MPL-1.1.html).\r\n\r\nSee LICENSE.md for more information.\r\n\r\nDeveloped in cooperation with [WebSpellChecker.net](http://www.webspellchecker.net/).\r\n"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/scayt/dialogs/options.js",
    "content": "﻿/*\n Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.dialog.add(\"scaytcheck\",function(j){function w(){return\"undefined\"!=typeof document.forms[\"optionsbar_\"+b]?document.forms[\"optionsbar_\"+b].options:[]}function x(a,b){if(a){var e=a.length;if(void 0==e)a.checked=a.value==b.toString();else for(var d=0;d<e;d++)a[d].checked=!1,a[d].value==b.toString()&&(a[d].checked=!0)}}function n(a){f.getById(\"dic_message_\"+b).setHtml('<span style=\"color:red;\">'+a+\"</span>\")}function o(a){f.getById(\"dic_message_\"+b).setHtml('<span style=\"color:blue;\">'+a+\"</span>\")}\nfunction p(a){for(var a=(\"\"+a).split(\",\"),b=0,e=a.length;b<e;b+=1)f.getById(a[b]).$.style.display=\"inline\"}function q(a){for(var a=(\"\"+a).split(\",\"),b=0,e=a.length;b<e;b+=1)f.getById(a[b]).$.style.display=\"none\"}function r(a){f.getById(\"dic_name_\"+b).$.value=a}var s=!0,h,f=CKEDITOR.document,b=j.name,l=CKEDITOR.plugins.scayt.getUiTabs(j),g,t=[],u=0,m=[\"dic_create_\"+b+\",dic_restore_\"+b,\"dic_rename_\"+b+\",dic_delete_\"+b],v=[\"mixedCase\",\"mixedWithDigits\",\"allCaps\",\"ignoreDomainNames\"];g=j.lang.scayt;var z=\n[{id:\"options\",label:g.optionsTab,elements:[{type:\"html\",id:\"options\",html:'<form name=\"optionsbar_'+b+'\"><div class=\"inner_options\">\\t<div class=\"messagebox\"></div>\\t<div style=\"display:none;\">\\t\\t<input type=\"checkbox\" name=\"options\"  id=\"allCaps_'+b+'\" />\\t\\t<label style = \"display: inline\" for=\"allCaps\" id=\"label_allCaps_'+b+'\"></label>\\t</div>\\t<div style=\"display:none;\">\\t\\t<input name=\"options\" type=\"checkbox\"  id=\"ignoreDomainNames_'+b+'\" />\\t\\t<label style = \"display: inline\" for=\"ignoreDomainNames\" id=\"label_ignoreDomainNames_'+\nb+'\"></label>\\t</div>\\t<div style=\"display:none;\">\\t<input name=\"options\" type=\"checkbox\"  id=\"mixedCase_'+b+'\" />\\t\\t<label style = \"display: inline\" for=\"mixedCase\" id=\"label_mixedCase_'+b+'\"></label>\\t</div>\\t<div style=\"display:none;\">\\t\\t<input name=\"options\" type=\"checkbox\"  id=\"mixedWithDigits_'+b+'\" />\\t\\t<label style = \"display: inline\" for=\"mixedWithDigits\" id=\"label_mixedWithDigits_'+b+'\"></label>\\t</div></div></form>'}]},{id:\"langs\",label:g.languagesTab,elements:[{type:\"html\",id:\"langs\",\nhtml:'<div class=\"inner_langs\">\\t<div class=\"messagebox\"></div>\\t   <div style=\"float:left;width:45%;margin-left:5px;\" id=\"scayt_lcol_'+b+'\" ></div>   <div style=\"float:left;width:45%;margin-left:15px;\" id=\"scayt_rcol_'+b+'\"></div></div>'}]},{id:\"dictionaries\",label:g.dictionariesTab,elements:[{type:\"html\",style:\"\",id:\"dictionaries\",html:'<form name=\"dictionarybar_'+b+'\"><div class=\"inner_dictionary\" style=\"text-align:left; white-space:normal; width:320px; overflow: hidden;\">\\t<div style=\"margin:5px auto; width:95%;white-space:normal; overflow:hidden;\" id=\"dic_message_'+\nb+'\"> </div>\\t<div style=\"margin:5px auto; width:95%;white-space:normal;\">        <span class=\"cke_dialog_ui_labeled_label\" >Dictionary name</span><br>\\t\\t<span class=\"cke_dialog_ui_labeled_content\" >\\t\\t\\t<div class=\"cke_dialog_ui_input_text\">\\t\\t\\t\\t<input id=\"dic_name_'+b+'\" type=\"text\" class=\"cke_dialog_ui_input_text\" style = \"height: 25px; background: none; padding: 0;\"/>\\t\\t</div></span></div>\\t\\t<div style=\"margin:5px auto; width:95%;white-space:normal;\">\\t\\t\\t<a style=\"display:none;\" class=\"cke_dialog_ui_button\" href=\"javascript:void(0)\" id=\"dic_create_'+\nb+'\">\\t\\t\\t\\t</a>\\t\\t\\t<a  style=\"display:none;\" class=\"cke_dialog_ui_button\" href=\"javascript:void(0)\" id=\"dic_delete_'+b+'\">\\t\\t\\t\\t</a>\\t\\t\\t<a  style=\"display:none;\" class=\"cke_dialog_ui_button\" href=\"javascript:void(0)\" id=\"dic_rename_'+b+'\">\\t\\t\\t\\t</a>\\t\\t\\t<a  style=\"display:none;\" class=\"cke_dialog_ui_button\" href=\"javascript:void(0)\" id=\"dic_restore_'+b+'\">\\t\\t\\t\\t</a>\\t\\t</div>\\t<div style=\"margin:5px auto; width:95%;white-space:normal;\" id=\"dic_info_'+b+'\"></div></div></form>'}]},{id:\"about\",\nlabel:g.aboutTab,elements:[{type:\"html\",id:\"about\",style:\"margin: 5px 5px;\",html:'<div><div id=\"scayt_about_'+b+'\"></div></div>'}]}],B={title:g.title,minWidth:360,minHeight:220,onShow:function(){var a=this;a.data=j.fire(\"scaytDialog\",{});a.options=a.data.scayt_control.option();a.chosed_lang=a.sLang=a.data.scayt_control.sLang;if(!a.data||!a.data.scayt||!a.data.scayt_control)alert(\"Error loading application service\"),a.hide();else{var b=0;s?a.data.scayt.getCaption(j.langCode||\"en\",function(e){0<b++||\n(h=e,A.apply(a),y.apply(a),s=!1)}):y.apply(a);a.selectPage(a.data.tab)}},onOk:function(){var a=this.data.scayt_control;a.option(this.options);a.setLang(this.chosed_lang);a.refresh()},onCancel:function(){var a=w(),f;for(f in a)a[f].checked=!1;a=\"undefined\"!=typeof document.forms[\"languagesbar_\"+b]?document.forms[\"languagesbar_\"+b].scayt_lang:[];x(a,\"\")},contents:t};CKEDITOR.plugins.scayt.getScayt(j);for(g=0;g<l.length;g++)1==l[g]&&(t[t.length]=z[g]);1==l[2]&&(u=1);var A=function(){function a(a){var c=\nf.getById(\"dic_name_\"+b).getValue();if(!c)return n(\" Dictionary name should not be empty. \"),!1;try{var d=a.data.getTarget().getParent(),e=/(dic_\\w+)_[\\w\\d]+/.exec(d.getId())[1];j[e].apply(null,[d,c,m])}catch(C){n(\" Dictionary error. \")}return!0}var k=this,e=k.data.scayt.getLangList(),d=[\"dic_create\",\"dic_delete\",\"dic_rename\",\"dic_restore\"],g=[],i=[],c;if(u){for(c=0;c<d.length;c++)g[c]=d[c]+\"_\"+b,f.getById(g[c]).setHtml('<span class=\"cke_dialog_ui_button\">'+h[\"button_\"+d[c]]+\"</span>\");f.getById(\"dic_info_\"+\nb).setHtml(h.dic_info)}if(1==l[0])for(c in v)d=\"label_\"+v[c],g=f.getById(d+\"_\"+b),\"undefined\"!=typeof g&&(\"undefined\"!=typeof h[d]&&\"undefined\"!=typeof k.options[v[c]])&&(g.setHtml(h[d]),g.getParent().$.style.display=\"block\");d='<p><img src=\"'+window.scayt.getAboutInfo().logoURL+'\" /></p><p>'+h.version+window.scayt.getAboutInfo().version.toString()+\"</p><p>\"+h.about_throwt_copy+\"</p>\";f.getById(\"scayt_about_\"+b).setHtml(d);d=function(a,b){var c=f.createElement(\"label\");c.setAttribute(\"for\",\"cke_option\"+\na);c.setStyle(\"display\",\"inline\");c.setHtml(b[a]);k.sLang==a&&(k.chosed_lang=a);var d=f.createElement(\"div\"),e=CKEDITOR.dom.element.createFromHtml('<input class = \"cke_dialog_ui_radio_input\" id=\"cke_option'+a+'\" type=\"radio\" '+(k.sLang==a?'checked=\"checked\"':\"\")+' value=\"'+a+'\" name=\"scayt_lang\" />');e.on(\"click\",function(){this.$.checked=true;k.chosed_lang=a});d.append(e);d.append(c);return{lang:b[a],code:a,radio:d}};if(1==l[1]){for(c in e.rtl)i[i.length]=d(c,e.ltr);for(c in e.ltr)i[i.length]=d(c,\ne.ltr);i.sort(function(a,b){return b.lang>a.lang?-1:1});e=f.getById(\"scayt_lcol_\"+b);d=f.getById(\"scayt_rcol_\"+b);for(c=0;c<i.length;c++)(c<i.length/2?e:d).append(i[c].radio)}var j={dic_create:function(a,b,c){var d=c[0]+\",\"+c[1],e=h.err_dic_create,f=h.succ_dic_create;window.scayt.createUserDictionary(b,function(a){q(d);p(c[1]);f=f.replace(\"%s\",a.dname);o(f)},function(a){e=e.replace(\"%s\",a.dname);n(e+\"( \"+(a.message||\"\")+\")\")})},dic_rename:function(a,b){var c=h.err_dic_rename||\"\",d=h.succ_dic_rename||\n\"\";window.scayt.renameUserDictionary(b,function(a){d=d.replace(\"%s\",a.dname);r(b);o(d)},function(a){c=c.replace(\"%s\",a.dname);r(b);n(c+\"( \"+(a.message||\"\")+\" )\")})},dic_delete:function(a,b,c){var d=c[0]+\",\"+c[1],e=h.err_dic_delete,f=h.succ_dic_delete;window.scayt.deleteUserDictionary(function(a){f=f.replace(\"%s\",a.dname);q(d);p(c[0]);r(\"\");o(f)},function(a){e=e.replace(\"%s\",a.dname);n(e)})}};j.dic_restore=k.dic_restore||function(a,b,c){var d=c[0]+\",\"+c[1],e=h.err_dic_restore,f=h.succ_dic_restore;\nwindow.scayt.restoreUserDictionary(b,function(a){f=f.replace(\"%s\",a.dname);q(d);p(c[1]);o(f)},function(a){e=e.replace(\"%s\",a.dname);n(e)})};i=(m[0]+\",\"+m[1]).split(\",\");c=0;for(e=i.length;c<e;c+=1)if(d=f.getById(i[c]))d.on(\"click\",a,this)},y=function(){var a=this;if(1==l[0])for(var g=w(),e=0,d=g.length;e<d;e++){var h=g[e].id,i=f.getById(h);if(i&&(g[e].checked=!1,1==a.options[h.split(\"_\")[0]]&&(g[e].checked=!0),s))i.on(\"click\",function(){a.options[this.getId().split(\"_\")[0]]=this.$.checked?1:0})}1==\nl[1]&&(g=f.getById(\"cke_option\"+a.sLang),x(g.$,a.sLang));u&&(window.scayt.getNameUserDictionary(function(a){a=a.dname;q(m[0]+\",\"+m[1]);if(a){f.getById(\"dic_name_\"+b).setValue(a);p(m[1])}else p(m[0])},function(){f.getById(\"dic_name_\"+b).setValue(\"\")}),o(\"\"))};return B});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/scayt/dialogs/toolbar.css",
    "content": "a\n{\n\ttext-decoration:none;\n\tpadding: 2px 4px 4px 6px;\n\tdisplay : block;\n\tborder-width: 1px;\n\tborder-style: solid;\n\tmargin : 0px;\n}\n\na.cke_scayt_toogle:hover,\na.cke_scayt_toogle:focus,\na.cke_scayt_toogle:active\n{\n\tborder-color: #316ac5;\n\tbackground-color: #dff1ff;\n\tcolor : #000;\n\tcursor: pointer;\n\tmargin : 0px;\n}\na.cke_scayt_toogle {\n\tcolor : #316ac5;\n\tborder-color: #fff;\n}\n.scayt_enabled a.cke_scayt_item {\n\tcolor : #316ac5;\n\tborder-color: #fff;\n\tmargin : 0px;\n}\n.scayt_disabled a.cke_scayt_item {\n\tcolor : gray;\n\tborder-color : #fff;\n}\n.scayt_enabled a.cke_scayt_item:hover,\n.scayt_enabled a.cke_scayt_item:focus,\n.scayt_enabled a.cke_scayt_item:active\n{\n\tborder-color: #316ac5;\n\tbackground-color: #dff1ff;\n\tcolor : #000;\n\tcursor: pointer;\n}\n.scayt_disabled a.cke_scayt_item:hover,\n.scayt_disabled a.cke_scayt_item:focus,\n.scayt_disabled a.cke_scayt_item:active\n{\n\tborder-color: gray;\n\tbackground-color: #dff1ff;\n\tcolor : gray;\n\tcursor: no-drop;\n}\n.cke_scayt_set_on, .cke_scayt_set_off\n{\n\tdisplay: none;\n}\n.scayt_enabled .cke_scayt_set_on\n{\n\tdisplay: none;\n}\n.scayt_disabled .cke_scayt_set_on\n{\n\tdisplay: inline;\n}\n.scayt_disabled .cke_scayt_set_off\n{\n\tdisplay: none;\n}\n.scayt_enabled  .cke_scayt_set_off\n{\n\tdisplay: inline;\n}\n"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/_translationstatus.txt",
    "content": "Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n\ncs.js      Found: 118 Missing: 0\ncy.js      Found: 118 Missing: 0\nde.js      Found: 118 Missing: 0\nel.js      Found: 16 Missing: 102\neo.js      Found: 118 Missing: 0\net.js      Found: 31 Missing: 87\nfa.js      Found: 24 Missing: 94\nfi.js      Found: 23 Missing: 95\nfr.js      Found: 118 Missing: 0\nhr.js      Found: 23 Missing: 95\nit.js      Found: 118 Missing: 0\nnb.js      Found: 118 Missing: 0\nnl.js      Found: 118 Missing: 0\nno.js      Found: 118 Missing: 0\ntr.js      Found: 118 Missing: 0\nug.js      Found: 39 Missing: 79\nzh-cn.js   Found: 118 Missing: 0\n"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/ar.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"ar\",{euro:\"رمز اليورو\",lsquo:\"علامة تنصيص علي اليسار\",rsquo:\"علامة تنصيص علي اليمين\",ldquo:\"علامة تنصيص مزدوجة علي اليسار\",rdquo:\"علامة تنصيص مزدوجة علي اليمين\",ndash:\"En dash –\",mdash:\"Em dash —\",iexcl:\"علامة تعجب مقلوبة\",cent:\"رمز سنتيم\",pound:\"رمز الاسترليني\",curren:\"رمز العملة\",yen:\"رمز الين الياباني\",brvbar:\"خط عمودي مكسور\",sect:\"رمز الفصيلة\",uml:\"Diaeresis\",copy:\"علامة حقوق الطبع\",ordf:\"Feminine ordinal indicator\",laquo:\"Left-pointing double angle quotation mark\",\nnot:\"ليست علامة\",reg:\"علامة مسجّلة\",macr:\"Macron\",deg:\"Degree sign\",sup2:\"Superscript two\",sup3:\"Superscript three\",acute:\"Acute accent\",micro:\"Micro sign\",para:\"Pilcrow sign\",middot:\"Middle dot\",cedil:\"Cedilla\",sup1:\"Superscript one\",ordm:\"Masculine ordinal indicator\",raquo:\"Right-pointing double angle quotation mark\",frac14:\"Vulgar fraction one quarter\",frac12:\"Vulgar fraction one half\",frac34:\"Vulgar fraction three quarters\",iquest:\"علامة الإستفهام غير صحيحة\",Agrave:\"Latin capital letter A with grave accent\",\nAacute:\"Latin capital letter A with acute accent\",Acirc:\"Latin capital letter A with circumflex\",Atilde:\"Latin capital letter A with tilde\",Auml:\"Latin capital letter A with diaeresis\",Aring:\"Latin capital letter A with ring above\",AElig:\"Latin Capital letter Æ\",Ccedil:\"Latin capital letter C with cedilla\",Egrave:\"Latin capital letter E with grave accent\",Eacute:\"Latin capital letter E with acute accent\",Ecirc:\"Latin capital letter E with circumflex\",Euml:\"Latin capital letter E with diaeresis\",Igrave:\"Latin capital letter I with grave accent\",\nIacute:\"Latin capital letter I with acute accent\",Icirc:\"Latin capital letter I with circumflex\",Iuml:\"Latin capital letter I with diaeresis\",ETH:\"Latin capital letter Eth\",Ntilde:\"Latin capital letter N with tilde\",Ograve:\"Latin capital letter O with grave accent\",Oacute:\"Latin capital letter O with acute accent\",Ocirc:\"Latin capital letter O with circumflex\",Otilde:\"Latin capital letter O with tilde\",Ouml:\"Latin capital letter O with diaeresis\",times:\"Multiplication sign\",Oslash:\"Latin capital letter O with stroke\",\nUgrave:\"Latin capital letter U with grave accent\",Uacute:\"Latin capital letter U with acute accent\",Ucirc:\"Latin capital letter U with circumflex\",Uuml:\"Latin capital letter U with diaeresis\",Yacute:\"Latin capital letter Y with acute accent\",THORN:\"Latin capital letter Thorn\",szlig:\"Latin small letter sharp s\",agrave:\"Latin small letter a with grave accent\",aacute:\"Latin small letter a with acute accent\",acirc:\"Latin small letter a with circumflex\",atilde:\"Latin small letter a with tilde\",auml:\"Latin small letter a with diaeresis\",\naring:\"Latin small letter a with ring above\",aelig:\"Latin small letter æ\",ccedil:\"Latin small letter c with cedilla\",egrave:\"Latin small letter e with grave accent\",eacute:\"Latin small letter e with acute accent\",ecirc:\"Latin small letter e with circumflex\",euml:\"Latin small letter e with diaeresis\",igrave:\"Latin small letter i with grave accent\",iacute:\"Latin small letter i with acute accent\",icirc:\"Latin small letter i with circumflex\",iuml:\"Latin small letter i with diaeresis\",eth:\"Latin small letter eth\",\nntilde:\"Latin small letter n with tilde\",ograve:\"Latin small letter o with grave accent\",oacute:\"Latin small letter o with acute accent\",ocirc:\"Latin small letter o with circumflex\",otilde:\"Latin small letter o with tilde\",ouml:\"Latin small letter o with diaeresis\",divide:\"Division sign\",oslash:\"Latin small letter o with stroke\",ugrave:\"Latin small letter u with grave accent\",uacute:\"Latin small letter u with acute accent\",ucirc:\"Latin small letter u with circumflex\",uuml:\"Latin small letter u with diaeresis\",\nyacute:\"Latin small letter y with acute accent\",thorn:\"Latin small letter thorn\",yuml:\"Latin small letter y with diaeresis\",OElig:\"Latin capital ligature OE\",oelig:\"Latin small ligature oe\",372:\"Latin capital letter W with circumflex\",374:\"Latin capital letter Y with circumflex\",373:\"Latin small letter w with circumflex\",375:\"Latin small letter y with circumflex\",sbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",hellip:\"Horizontal ellipsis\",\ntrade:\"Trade mark sign\",9658:\"Black right-pointing pointer\",bull:\"Bullet\",rarr:\"Rightwards arrow\",rArr:\"Rightwards double arrow\",hArr:\"Left right double arrow\",diams:\"Black diamond suit\",asymp:\"Almost equal to\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/bg.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"bg\",{euro:\"Евро знак\",lsquo:\"Лява маркировка за цитат\",rsquo:\"Дясна маркировка за цитат\",ldquo:\"Лява двойна кавичка за цитат\",rdquo:\"Дясна двойна кавичка за цитат\",ndash:\"\\\\\\\\\",mdash:\"/\",iexcl:\"Обърната питанка\",cent:\"Знак за цент\",pound:\"Знак за паунд\",curren:\"Валутен знак\",yen:\"Знак за йена\",brvbar:\"Прекъсната линия\",sect:\"Знак за секция\",uml:\"Diaeresis\",copy:\"Знак за Copyright\",ordf:\"Feminine ordinal indicator\",laquo:\"Left-pointing double angle quotation mark\",\nnot:\"Not sign\",reg:\"Registered sign\",macr:\"Macron\",deg:\"Degree sign\",sup2:\"Superscript two\",sup3:\"Superscript three\",acute:\"Acute accent\",micro:\"Micro sign\",para:\"Pilcrow sign\",middot:\"Middle dot\",cedil:\"Cedilla\",sup1:\"Superscript one\",ordm:\"Masculine ordinal indicator\",raquo:\"Right-pointing double angle quotation mark\",frac14:\"Vulgar fraction one quarter\",frac12:\"Vulgar fraction one half\",frac34:\"Vulgar fraction three quarters\",iquest:\"Inverted question mark\",Agrave:\"Latin capital letter A with grave accent\",\nAacute:\"Latin capital letter A with acute accent\",Acirc:\"Latin capital letter A with circumflex\",Atilde:\"Latin capital letter A with tilde\",Auml:\"Latin capital letter A with diaeresis\",Aring:\"Latin capital letter A with ring above\",AElig:\"Latin Capital letter Æ\",Ccedil:\"Latin capital letter C with cedilla\",Egrave:\"Latin capital letter E with grave accent\",Eacute:\"Latin capital letter E with acute accent\",Ecirc:\"Latin capital letter E with circumflex\",Euml:\"Latin capital letter E with diaeresis\",Igrave:\"Latin capital letter I with grave accent\",\nIacute:\"Latin capital letter I with acute accent\",Icirc:\"Latin capital letter I with circumflex\",Iuml:\"Latin capital letter I with diaeresis\",ETH:\"Latin capital letter Eth\",Ntilde:\"Latin capital letter N with tilde\",Ograve:\"Latin capital letter O with grave accent\",Oacute:\"Latin capital letter O with acute accent\",Ocirc:\"Latin capital letter O with circumflex\",Otilde:\"Latin capital letter O with tilde\",Ouml:\"Latin capital letter O with diaeresis\",times:\"Multiplication sign\",Oslash:\"Latin capital letter O with stroke\",\nUgrave:\"Latin capital letter U with grave accent\",Uacute:\"Latin capital letter U with acute accent\",Ucirc:\"Latin capital letter U with circumflex\",Uuml:\"Latin capital letter U with diaeresis\",Yacute:\"Latin capital letter Y with acute accent\",THORN:\"Latin capital letter Thorn\",szlig:\"Latin small letter sharp s\",agrave:\"Latin small letter a with grave accent\",aacute:\"Latin small letter a with acute accent\",acirc:\"Latin small letter a with circumflex\",atilde:\"Latin small letter a with tilde\",auml:\"Latin small letter a with diaeresis\",\naring:\"Latin small letter a with ring above\",aelig:\"Latin small letter æ\",ccedil:\"Latin small letter c with cedilla\",egrave:\"Latin small letter e with grave accent\",eacute:\"Latin small letter e with acute accent\",ecirc:\"Latin small letter e with circumflex\",euml:\"Latin small letter e with diaeresis\",igrave:\"Latin small letter i with grave accent\",iacute:\"Latin small letter i with acute accent\",icirc:\"Latin small letter i with circumflex\",iuml:\"Latin small letter i with diaeresis\",eth:\"Latin small letter eth\",\nntilde:\"Latin small letter n with tilde\",ograve:\"Latin small letter o with grave accent\",oacute:\"Latin small letter o with acute accent\",ocirc:\"Latin small letter o with circumflex\",otilde:\"Latin small letter o with tilde\",ouml:\"Latin small letter o with diaeresis\",divide:\"Division sign\",oslash:\"Latin small letter o with stroke\",ugrave:\"Latin small letter u with grave accent\",uacute:\"Latin small letter u with acute accent\",ucirc:\"Latin small letter u with circumflex\",uuml:\"Latin small letter u with diaeresis\",\nyacute:\"Latin small letter y with acute accent\",thorn:\"Latin small letter thorn\",yuml:\"Latin small letter y with diaeresis\",OElig:\"Latin capital ligature OE\",oelig:\"Latin small ligature oe\",372:\"Latin capital letter W with circumflex\",374:\"Latin capital letter Y with circumflex\",373:\"Latin small letter w with circumflex\",375:\"Latin small letter y with circumflex\",sbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",hellip:\"Horizontal ellipsis\",\ntrade:\"Trade mark sign\",9658:\"Black right-pointing pointer\",bull:\"Bullet\",rarr:\"Rightwards arrow\",rArr:\"Rightwards double arrow\",hArr:\"Left right double arrow\",diams:\"Black diamond suit\",asymp:\"Almost equal to\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/ca.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"ca\",{euro:\"Símbol d'euro\",lsquo:\"Signe de cometa simple esquerra\",rsquo:\"Signe de cometa simple dreta\",ldquo:\"Signe de cometa doble esquerra\",rdquo:\"Signe de cometa doble dreta\",ndash:\"Guió\",mdash:\"Guió baix\",iexcl:\"Signe d'exclamació inversa\",cent:\"Símbol de percentatge\",pound:\"Símbol de lliura\",curren:\"Símbol de moneda\",yen:\"Símbol de Yen\",brvbar:\"Barra trencada\",sect:\"Símbol de secció\",uml:\"Dièresi\",copy:\"Símbol de Copyright\",ordf:\"Indicador ordinal femení\",\nlaquo:\"Signe de cometes angulars esquerra\",not:\"Símbol de negació\",reg:\"Símbol registrat\",macr:\"Macron\",deg:\"Símbol de grau\",sup2:\"Superíndex dos\",sup3:\"Superíndex tres\",acute:\"Accent agut\",micro:\"Símbol de micro\",para:\"Símbol de calderó\",middot:\"Punt volat\",cedil:\"Ce trencada\",sup1:\"Superíndex u\",ordm:\"Indicador ordinal masculí\",raquo:\"Signe de cometes angulars dreta\",frac14:\"Fracció vulgar un quart\",frac12:\"Fracció vulgar una meitat\",frac34:\"Fracció vulgar tres quarts\",iquest:\"Símbol d'interrogació invertit\",\nAgrave:\"Lletra majúscula llatina A amb accent greu\",Aacute:\"Lletra majúscula llatina A amb accent agut\",Acirc:\"Lletra majúscula llatina A amb circumflex\",Atilde:\"Lletra majúscula llatina A amb titlla\",Auml:\"Lletra majúscula llatina A amb dièresi\",Aring:\"Lletra majúscula llatina A amb anell superior\",AElig:\"Lletra majúscula llatina Æ\",Ccedil:\"Lletra majúscula llatina C amb ce trencada\",Egrave:\"Lletra majúscula llatina E amb accent greu\",Eacute:\"Lletra majúscula llatina E amb accent agut\",Ecirc:\"Lletra majúscula llatina E amb circumflex\",\nEuml:\"Lletra majúscula llatina E amb dièresi\",Igrave:\"Lletra majúscula llatina I amb accent greu\",Iacute:\"Lletra majúscula llatina I amb accent agut\",Icirc:\"Lletra majúscula llatina I amb circumflex\",Iuml:\"Lletra majúscula llatina I amb dièresi\",ETH:\"Lletra majúscula llatina Eth\",Ntilde:\"Lletra majúscula llatina N amb titlla\",Ograve:\"Lletra majúscula llatina O amb accent greu\",Oacute:\"Lletra majúscula llatina O amb accent agut\",Ocirc:\"Lletra majúscula llatina O amb circumflex\",Otilde:\"Lletra majúscula llatina O amb titlla\",\nOuml:\"Lletra majúscula llatina O amb dièresi\",times:\"Símbol de multiplicació\",Oslash:\"Lletra majúscula llatina O amb barra\",Ugrave:\"Lletra majúscula llatina U amb accent greu\",Uacute:\"Lletra majúscula llatina U amb accent agut\",Ucirc:\"Lletra majúscula llatina U amb circumflex\",Uuml:\"Lletra majúscula llatina U amb dièresi\",Yacute:\"Lletra majúscula llatina Y amb accent agut\",THORN:\"Lletra majúscula llatina Thorn\",szlig:\"Lletra minúscula llatina sharp s\",agrave:\"Lletra minúscula llatina a amb accent greu\",\naacute:\"Lletra minúscula llatina a amb accent agut\",acirc:\"Lletra minúscula llatina a amb circumflex\",atilde:\"Lletra minúscula llatina a amb titlla\",auml:\"Lletra minúscula llatina a amb dièresi\",aring:\"Lletra minúscula llatina a amb anell superior\",aelig:\"Lletra minúscula llatina æ\",ccedil:\"Lletra minúscula llatina c amb ce trencada\",egrave:\"Lletra minúscula llatina e amb accent greu\",eacute:\"Lletra minúscula llatina e amb accent agut\",ecirc:\"Lletra minúscula llatina e amb circumflex\",euml:\"Lletra minúscula llatina e amb dièresi\",\nigrave:\"Lletra minúscula llatina i amb accent greu\",iacute:\"Lletra minúscula llatina i amb accent agut\",icirc:\"Lletra minúscula llatina i amb circumflex\",iuml:\"Lletra minúscula llatina i amb dièresi\",eth:\"Lletra minúscula llatina eth\",ntilde:\"Lletra minúscula llatina n amb titlla\",ograve:\"Lletra minúscula llatina o amb accent greu\",oacute:\"Lletra minúscula llatina o amb accent agut\",ocirc:\"Lletra minúscula llatina o amb circumflex\",otilde:\"Lletra minúscula llatina o amb titlla\",ouml:\"Lletra minúscula llatina o amb dièresi\",\ndivide:\"Símbol de divisió\",oslash:\"Lletra minúscula llatina o amb barra\",ugrave:\"Lletra minúscula llatina u amb accent greu\",uacute:\"Lletra minúscula llatina u amb accent agut\",ucirc:\"Lletra minúscula llatina u amb circumflex\",uuml:\"Lletra minúscula llatina u amb dièresi\",yacute:\"Lletra minúscula llatina y amb accent agut\",thorn:\"Lletra minúscula llatina thorn\",yuml:\"Lletra minúscula llatina y amb dièresi\",OElig:\"Lligadura majúscula llatina OE\",oelig:\"Lligadura minúscula llatina oe\",372:\"Lletra majúscula llatina W amb circumflex\",\n374:\"Lletra majúscula llatina Y amb circumflex\",373:\"Lletra minúscula llatina w amb circumflex\",375:\"Lletra minúscula llatina y amb circumflex\",sbquo:\"Signe de cita simple baixa-9\",8219:\"Signe de cita simple alta-invertida-9\",bdquo:\"Signe de cita doble baixa-9\",hellip:\"Punts suspensius\",trade:\"Símbol de marca registrada\",9658:\"Punter negre apuntant cap a la dreta\",bull:\"Vinyeta\",rarr:\"Fletxa cap a la dreta\",rArr:\"Doble fletxa cap a la dreta\",hArr:\"Doble fletxa esquerra dreta\",diams:\"Vestit negre diamant\",\nasymp:\"Gairebé igual a\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/cs.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"cs\",{euro:\"Znak eura\",lsquo:\"Počáteční uvozovka jednoduchá\",rsquo:\"Koncová uvozovka jednoduchá\",ldquo:\"Počáteční uvozovka dvojitá\",rdquo:\"Koncová uvozovka dvojitá\",ndash:\"En pomlčka\",mdash:\"Em pomlčka\",iexcl:\"Obrácený vykřičník\",cent:\"Znak centu\",pound:\"Znak libry\",curren:\"Znak měny\",yen:\"Znak jenu\",brvbar:\"Přerušená svislá čára\",sect:\"Znak oddílu\",uml:\"Přehláska\",copy:\"Znak copyrightu\",ordf:\"Ženský indikátor rodu\",laquo:\"Znak dvojitých lomených uvozovek vlevo\",\nnot:\"Logistický zápor\",reg:\"Znak registrace\",macr:\"Pomlčka nad\",deg:\"Znak stupně\",sup2:\"Dvojka jako horní index\",sup3:\"Trojka jako horní index\",acute:\"Čárka nad vpravo\",micro:\"Znak mikro\",para:\"Znak odstavce\",middot:\"Tečka uprostřed\",cedil:\"Ocásek vlevo\",sup1:\"Jednička jako horní index\",ordm:\"Mužský indikátor rodu\",raquo:\"Znak dvojitých lomených uvozovek vpravo\",frac14:\"Obyčejný zlomek jedna čtvrtina\",frac12:\"Obyčejný zlomek jedna polovina\",frac34:\"Obyčejný zlomek tři čtvrtiny\",iquest:\"Znak obráceného otazníku\",\nAgrave:\"Velké písmeno latinky A s čárkou nad vlevo\",Aacute:\"Velké písmeno latinky A s čárkou nad vpravo\",Acirc:\"Velké písmeno latinky A s vokáněm\",Atilde:\"Velké písmeno latinky A s tildou\",Auml:\"Velké písmeno latinky A s dvěma tečkami\",Aring:\"Velké písmeno latinky A s kroužkem nad\",AElig:\"Velké písmeno latinky Ae\",Ccedil:\"Velké písmeno latinky C s ocáskem vlevo\",Egrave:\"Velké písmeno latinky E s čárkou nad vlevo\",Eacute:\"Velké písmeno latinky E s čárkou nad vpravo\",Ecirc:\"Velké písmeno latinky E s vokáněm\",\nEuml:\"Velké písmeno latinky E s dvěma tečkami\",Igrave:\"Velké písmeno latinky I s čárkou nad vlevo\",Iacute:\"Velké písmeno latinky I s čárkou nad vpravo\",Icirc:\"Velké písmeno latinky I s vokáněm\",Iuml:\"Velké písmeno latinky I s dvěma tečkami\",ETH:\"Velké písmeno latinky Eth\",Ntilde:\"Velké písmeno latinky N s tildou\",Ograve:\"Velké písmeno latinky O s čárkou nad vlevo\",Oacute:\"Velké písmeno latinky O s čárkou nad vpravo\",Ocirc:\"Velké písmeno latinky O s vokáněm\",Otilde:\"Velké písmeno latinky O s tildou\",\nOuml:\"Velké písmeno latinky O s dvěma tečkami\",times:\"Znak násobení\",Oslash:\"Velké písmeno latinky O přeškrtnuté\",Ugrave:\"Velké písmeno latinky U s čárkou nad vlevo\",Uacute:\"Velké písmeno latinky U s čárkou nad vpravo\",Ucirc:\"Velké písmeno latinky U s vokáněm\",Uuml:\"Velké písmeno latinky U s dvěma tečkami\",Yacute:\"Velké písmeno latinky Y s čárkou nad vpravo\",THORN:\"Velké písmeno latinky Thorn\",szlig:\"Malé písmeno latinky ostré s\",agrave:\"Malé písmeno latinky a s čárkou nad vlevo\",aacute:\"Malé písmeno latinky a s čárkou nad vpravo\",\nacirc:\"Malé písmeno latinky a s vokáněm\",atilde:\"Malé písmeno latinky a s tildou\",auml:\"Malé písmeno latinky a s dvěma tečkami\",aring:\"Malé písmeno latinky a s kroužkem nad\",aelig:\"Malé písmeno latinky ae\",ccedil:\"Malé písmeno latinky c s ocáskem vlevo\",egrave:\"Malé písmeno latinky e s čárkou nad vlevo\",eacute:\"Malé písmeno latinky e s čárkou nad vpravo\",ecirc:\"Malé písmeno latinky e s vokáněm\",euml:\"Malé písmeno latinky e s dvěma tečkami\",igrave:\"Malé písmeno latinky i s čárkou nad vlevo\",iacute:\"Malé písmeno latinky i s čárkou nad vpravo\",\nicirc:\"Malé písmeno latinky i s vokáněm\",iuml:\"Malé písmeno latinky i s dvěma tečkami\",eth:\"Malé písmeno latinky eth\",ntilde:\"Malé písmeno latinky n s tildou\",ograve:\"Malé písmeno latinky o s čárkou nad vlevo\",oacute:\"Malé písmeno latinky o s čárkou nad vpravo\",ocirc:\"Malé písmeno latinky o s vokáněm\",otilde:\"Malé písmeno latinky o s tildou\",ouml:\"Malé písmeno latinky o s dvěma tečkami\",divide:\"Znak dělení\",oslash:\"Malé písmeno latinky o přeškrtnuté\",ugrave:\"Malé písmeno latinky u s čárkou nad vlevo\",\nuacute:\"Malé písmeno latinky u s čárkou nad vpravo\",ucirc:\"Malé písmeno latinky u s vokáněm\",uuml:\"Malé písmeno latinky u s dvěma tečkami\",yacute:\"Malé písmeno latinky y s čárkou nad vpravo\",thorn:\"Malé písmeno latinky thorn\",yuml:\"Malé písmeno latinky y s dvěma tečkami\",OElig:\"Velká ligatura latinky OE\",oelig:\"Malá ligatura latinky OE\",372:\"Velké písmeno latinky W s vokáněm\",374:\"Velké písmeno latinky Y s vokáněm\",373:\"Malé písmeno latinky w s vokáněm\",375:\"Malé písmeno latinky y s vokáněm\",sbquo:\"Dolní 9 uvozovka jednoduchá\",\n8219:\"Horní obrácená 9 uvozovka jednoduchá\",bdquo:\"Dolní 9 uvozovka dvojitá\",hellip:\"Trojtečkový úvod\",trade:\"Obchodní značka\",9658:\"Černý ukazatel směřující vpravo\",bull:\"Kolečko\",rarr:\"Šipka vpravo\",rArr:\"Dvojitá šipka vpravo\",hArr:\"Dvojitá šipka vlevo a vpravo\",diams:\"Černé piky\",asymp:\"Téměř se rovná\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/cy.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"cy\",{euro:\"Arwydd yr Ewro\",lsquo:\"Dyfynnod chwith unigol\",rsquo:\"Dyfynnod dde unigol\",ldquo:\"Dyfynnod chwith dwbl\",rdquo:\"Dyfynnod dde dwbl\",ndash:\"Cysylltnod en\",mdash:\"Cysylltnod em\",iexcl:\"Ebychnod gwrthdro\",cent:\"Arwydd sent\",pound:\"Arwydd punt\",curren:\"Arwydd arian cyfred\",yen:\"Arwydd yen\",brvbar:\"Bar toriedig\",sect:\"Arwydd adran\",uml:\"Didolnod\",copy:\"Arwydd hawlfraint\",ordf:\"Dangosydd benywaidd\",laquo:\"Dyfynnod dwbl ar ongl i'r chwith\",not:\"Arwydd Nid\",\nreg:\"Arwydd cofrestredig\",macr:\"Macron\",deg:\"Arwydd gradd\",sup2:\"Dau uwchsgript\",sup3:\"Tri uwchsgript\",acute:\"Acen ddyrchafedig\",micro:\"Arwydd micro\",para:\"Arwydd pilcrow\",middot:\"Dot canol\",cedil:\"Sedila\",sup1:\"Un uwchsgript\",ordm:\"Dangosydd gwrywaidd\",raquo:\"Dyfynnod dwbl ar ongl i'r dde\",frac14:\"Ffracsiwn cyffredin un cwarter\",frac12:\"Ffracsiwn cyffredin un hanner\",frac34:\"Ffracsiwn cyffredin tri chwarter\",iquest:\"Marc cwestiwn gwrthdroëdig\",Agrave:\"Priflythyren A Lladinaidd gydag acen ddisgynedig\",\nAacute:\"Priflythyren A Lladinaidd gydag acen ddyrchafedig\",Acirc:\"Priflythyren A Lladinaidd gydag acen grom\",Atilde:\"Priflythyren A Lladinaidd gyda thild\",Auml:\"Priflythyren A Lladinaidd gyda didolnod\",Aring:\"Priflythyren A Lladinaidd gyda chylch uwchben\",AElig:\"Priflythyren Æ Lladinaidd\",Ccedil:\"Priflythyren C Lladinaidd gyda sedila\",Egrave:\"Priflythyren E Lladinaidd gydag acen ddisgynedig\",Eacute:\"Priflythyren E Lladinaidd gydag acen ddyrchafedig\",Ecirc:\"Priflythyren E Lladinaidd gydag acen grom\",\nEuml:\"Priflythyren E Lladinaidd gyda didolnod\",Igrave:\"Priflythyren I Lladinaidd gydag acen ddisgynedig\",Iacute:\"Priflythyren I Lladinaidd gydag acen ddyrchafedig\",Icirc:\"Priflythyren I Lladinaidd gydag acen grom\",Iuml:\"Priflythyren I Lladinaidd gyda didolnod\",ETH:\"Priflythyren Eth\",Ntilde:\"Priflythyren N Lladinaidd gyda thild\",Ograve:\"Priflythyren O Lladinaidd gydag acen ddisgynedig\",Oacute:\"Priflythyren O Lladinaidd gydag acen ddyrchafedig\",Ocirc:\"Priflythyren O Lladinaidd gydag acen grom\",Otilde:\"Priflythyren O Lladinaidd gyda thild\",\nOuml:\"Priflythyren O Lladinaidd gyda didolnod\",times:\"Arwydd lluosi\",Oslash:\"Priflythyren O Lladinaidd gyda strôc\",Ugrave:\"Priflythyren U Lladinaidd gydag acen ddisgynedig\",Uacute:\"Priflythyren U Lladinaidd gydag acen ddyrchafedig\",Ucirc:\"Priflythyren U Lladinaidd gydag acen grom\",Uuml:\"Priflythyren U Lladinaidd gyda didolnod\",Yacute:\"Priflythyren Y Lladinaidd gydag acen ddyrchafedig\",THORN:\"Priflythyren Thorn\",szlig:\"Llythyren s fach Lladinaidd siarp \",agrave:\"Llythyren a fach Lladinaidd gydag acen ddisgynedig\",\naacute:\"Llythyren a fach Lladinaidd gydag acen ddyrchafedig\",acirc:\"Llythyren a fach Lladinaidd gydag acen grom\",atilde:\"Llythyren a fach Lladinaidd gyda thild\",auml:\"Llythyren a fach Lladinaidd gyda didolnod\",aring:\"Llythyren a fach Lladinaidd gyda chylch uwchben\",aelig:\"Llythyren æ fach Lladinaidd\",ccedil:\"Llythyren c fach Lladinaidd gyda sedila\",egrave:\"Llythyren e fach Lladinaidd gydag acen ddisgynedig\",eacute:\"Llythyren e fach Lladinaidd gydag acen ddyrchafedig\",ecirc:\"Llythyren e fach Lladinaidd gydag acen grom\",\neuml:\"Llythyren e fach Lladinaidd gyda didolnod\",igrave:\"Llythyren i fach Lladinaidd gydag acen ddisgynedig\",iacute:\"Llythyren i fach Lladinaidd gydag acen ddyrchafedig\",icirc:\"Llythyren i fach Lladinaidd gydag acen grom\",iuml:\"Llythyren i fach Lladinaidd gyda didolnod\",eth:\"Llythyren eth fach\",ntilde:\"Llythyren n fach Lladinaidd gyda thild\",ograve:\"Llythyren o fach Lladinaidd gydag acen ddisgynedig\",oacute:\"Llythyren o fach Lladinaidd gydag acen ddyrchafedig\",ocirc:\"Llythyren o fach Lladinaidd gydag acen grom\",\notilde:\"Llythyren o fach Lladinaidd gyda thild\",ouml:\"Llythyren o fach Lladinaidd gyda didolnod\",divide:\"Arwydd rhannu\",oslash:\"Llythyren o fach Lladinaidd gyda strôc\",ugrave:\"Llythyren u fach Lladinaidd gydag acen ddisgynedig\",uacute:\"Llythyren u fach Lladinaidd gydag acen ddyrchafedig\",ucirc:\"Llythyren u fach Lladinaidd gydag acen grom\",uuml:\"Llythyren u fach Lladinaidd gyda didolnod\",yacute:\"Llythyren y fach Lladinaidd gydag acen ddisgynedig\",thorn:\"Llythyren o fach Lladinaidd gyda strôc\",yuml:\"Llythyren y fach Lladinaidd gyda didolnod\",\nOElig:\"Priflythyren cwlwm OE Lladinaidd \",oelig:\"Priflythyren cwlwm oe Lladinaidd \",372:\"Priflythyren W gydag acen grom\",374:\"Priflythyren Y gydag acen grom\",373:\"Llythyren w fach gydag acen grom\",375:\"Llythyren y fach gydag acen grom\",sbquo:\"Dyfynnod sengl 9-isel\",8219:\"Dyfynnod sengl 9-uchel cildro\",bdquo:\"Dyfynnod dwbl 9-isel\",hellip:\"Coll geiriau llorweddol\",trade:\"Arwydd marc masnachol\",9658:\"Pwyntydd du i'r dde\",bull:\"Bwled\",rarr:\"Saeth i'r dde\",rArr:\"Saeth ddwbl i'r dde\",hArr:\"Saeth ddwbl i'r chwith\",\ndiams:\"Siwt diemwnt du\",asymp:\"Bron yn hafal iddo\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/de.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"de\",{euro:\"Euro Zeichen\",lsquo:\"Hochkomma links\",rsquo:\"Hochkomma rechts\",ldquo:\"Anführungszeichen links\",rdquo:\"Anführungszeichen rechts\",ndash:\"kleiner Strich\",mdash:\"mittlerer Strich\",iexcl:\"invertiertes Ausrufezeichen\",cent:\"Cent\",pound:\"Pfund\",curren:\"Währung\",yen:\"Yen\",brvbar:\"gestrichelte Linie\",sect:\"§ Zeichen\",uml:\"Diäresis\",copy:\"Copyright\",ordf:\"Feminine ordinal Anzeige\",laquo:\"Nach links zeigenden Doppel-Winkel Anführungszeichen\",not:\"Not-Zeichen\",\nreg:\"Registriert\",macr:\"Längezeichen\",deg:\"Grad\",sup2:\"Hoch 2\",sup3:\"Hoch 3\",acute:\"Akzentzeichen \",micro:\"Micro\",para:\"Pilcrow-Zeichen\",middot:\"Mittelpunkt\",cedil:\"Cedilla\",sup1:\"Hoch 1\",ordm:\"Männliche Ordnungszahl Anzeige\",raquo:\"Nach rechts zeigenden Doppel-Winkel Anführungszeichen\",frac14:\"ein Viertel\",frac12:\"Hälfte\",frac34:\"Dreiviertel\",iquest:\"Umgekehrtes Fragezeichen\",Agrave:\"Lateinischer Buchstabe A mit AkzentGrave\",Aacute:\"Lateinischer Buchstabe A mit Akutakzent\",Acirc:\"Lateinischer Buchstabe A mit Zirkumflex\",\nAtilde:\"Lateinischer Buchstabe A mit Tilde\",Auml:\"Lateinischer Buchstabe A mit Trema\",Aring:\"Lateinischer Buchstabe A mit Ring oben\",AElig:\"Lateinischer Buchstabe Æ\",Ccedil:\"Lateinischer Buchstabe C mit Cedille\",Egrave:\"Lateinischer Buchstabe E mit AkzentGrave\",Eacute:\"Lateinischer Buchstabe E mit Akutakzent\",Ecirc:\"Lateinischer Buchstabe E mit Zirkumflex\",Euml:\"Lateinischer Buchstabe E Trema\",Igrave:\"Lateinischer Buchstabe I mit AkzentGrave\",Iacute:\"Lateinischer Buchstabe I mit Akutakzent\",Icirc:\"Lateinischer Buchstabe I mit Zirkumflex\",\nIuml:\"Lateinischer Buchstabe I mit Trema\",ETH:\"Lateinischer Buchstabe Eth\",Ntilde:\"Lateinischer Buchstabe N mit Tilde\",Ograve:\"Lateinischer Buchstabe O mit AkzentGrave\",Oacute:\"Lateinischer Buchstabe O mit Akutakzent\",Ocirc:\"Lateinischer Buchstabe O mit Zirkumflex\",Otilde:\"Lateinischer Buchstabe O mit Tilde\",Ouml:\"Lateinischer Buchstabe O mit Trema\",times:\"Multiplikation\",Oslash:\"Lateinischer Buchstabe O durchgestrichen\",Ugrave:\"Lateinischer Buchstabe U mit Akzentgrave\",Uacute:\"Lateinischer Buchstabe U mit Akutakzent\",\nUcirc:\"Lateinischer Buchstabe U mit Zirkumflex\",Uuml:\"Lateinischer Buchstabe a mit Trema\",Yacute:\"Lateinischer Buchstabe a mit Akzent\",THORN:\"Lateinischer Buchstabe mit Dorn\",szlig:\"Kleiner lateinischer Buchstabe scharfe s\",agrave:\"Kleiner lateinischer Buchstabe a mit Accent grave\",aacute:\"Kleiner lateinischer Buchstabe a mit Akut\",acirc:\"Lateinischer Buchstabe a mit Zirkumflex\",atilde:\"Lateinischer Buchstabe a mit Tilde\",auml:\"Kleiner lateinischer Buchstabe a mit Trema\",aring:\"Kleiner lateinischer Buchstabe a mit Ring oben\",\naelig:\"Lateinischer Buchstabe æ\",ccedil:\"Kleiner lateinischer Buchstabe c mit Cedille\",egrave:\"Kleiner lateinischer Buchstabe e mit Accent grave\",eacute:\"Kleiner lateinischer Buchstabe e mit Akut\",ecirc:\"Kleiner lateinischer Buchstabe e mit Zirkumflex\",euml:\"Kleiner lateinischer Buchstabe e mit Trema\",igrave:\"Kleiner lateinischer Buchstabe i mit AkzentGrave\",iacute:\"Kleiner lateinischer Buchstabe i mit Akzent\",icirc:\"Kleiner lateinischer Buchstabe i mit Zirkumflex\",iuml:\"Kleiner lateinischer Buchstabe i mit Trema\",\neth:\"Kleiner lateinischer Buchstabe eth\",ntilde:\"Kleiner lateinischer Buchstabe n mit Tilde\",ograve:\"Kleiner lateinischer Buchstabe o mit Accent grave\",oacute:\"Kleiner lateinischer Buchstabe o mit Akzent\",ocirc:\"Kleiner lateinischer Buchstabe o mit Zirkumflex\",otilde:\"Lateinischer Buchstabe i mit Tilde\",ouml:\"Kleiner lateinischer Buchstabe o mit Trema\",divide:\"Divisionszeichen\",oslash:\"Kleiner lateinischer Buchstabe o durchgestrichen\",ugrave:\"Kleiner lateinischer Buchstabe u mit Accent grave\",uacute:\"Kleiner lateinischer Buchstabe u mit Akut\",\nucirc:\"Kleiner lateinischer Buchstabe u mit Zirkumflex\",uuml:\"Kleiner lateinischer Buchstabe u mit Trema\",yacute:\"Kleiner lateinischer Buchstabe y mit Akut\",thorn:\"Kleiner lateinischer Buchstabe Dorn\",yuml:\"Kleiner lateinischer Buchstabe y mit Trema\",OElig:\"Lateinischer Buchstabe Ligatur OE\",oelig:\"Kleiner lateinischer Buchstabe Ligatur OE\",372:\"Lateinischer Buchstabe W mit Zirkumflex\",374:\"Lateinischer Buchstabe Y mit Zirkumflex\",373:\"Kleiner lateinischer Buchstabe w mit Zirkumflex\",375:\"Kleiner lateinischer Buchstabe y mit Zirkumflex\",\nsbquo:\"Tiefergestelltes Komma\",8219:\"Rumgedrehtes Komma\",bdquo:\"Doppeltes Anführungszeichen unten\",hellip:\"horizontale Auslassungspunkte\",trade:\"Handelszeichen\",9658:\"Dreickspfeil rechts\",bull:\"Bullet\",rarr:\"Pfeil rechts\",rArr:\"Doppelpfeil rechts\",hArr:\"Doppelpfeil links\",diams:\"Karo\",asymp:\"Ungefähr\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/el.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"el\",{euro:\"Σύμβολο Ευρώ\",lsquo:\"Αριστερός χαρακτήρας μονού εισαγωγικού\",rsquo:\"Δεξιός χαρακτήρας μονού εισαγωγικού\",ldquo:\"Αριστερός χαρακτήρας διπλού εισαγωγικού\",rdquo:\"Δεξιός χαρακτήρας διπλού εισαγωγικού\",ndash:\"Παύλα en\",mdash:\"Παύλα em\",iexcl:\"Ανάποδο θαυμαστικό\",cent:\"Σύμβολο σεντ\",pound:\"Σύμβολο λίρας\",curren:\"Σύμβολο συναλλαγματικής μονάδας\",yen:\"Σύμβολο Γιεν\",brvbar:\"Σπασμένη μπάρα\",sect:\"Σύμβολο τμήματος\",uml:\"Διαίρεση\",copy:\"Σύμβολο πνευματικών δικαιωμάτων\",\nordf:\"Feminine ordinal indicator\",laquo:\"Αριστερός χαρακτήρας διπλού εισαγωγικού\",not:\"Not sign\",reg:\"Σύμβολο σημάτων κατατεθέν\",macr:\"Μακρόν\",deg:\"Σύμβολο βαθμού\",sup2:\"Εκτεθειμένο δύο\",sup3:\"Εκτεθειμένο τρία\",acute:\"Οξεία\",micro:\"Σύμβολο μικρού\",para:\"Σύμβολο παραγράφου\",middot:\"Μέση τελεία\",cedil:\"Υπογεγραμμένη\",sup1:\"Εκτεθειμένο ένα\",ordm:\"Masculine ordinal indicator\",raquo:\"Right-pointing double angle quotation mark\",frac14:\"Γνήσιο κλάσμα ενός τετάρτου\",frac12:\"Γνήσιο κλάσμα ενός δεύτερου\",frac34:\"Γνήσιο κλάσμα τριών τετάρτων\",\niquest:\"Ανάποδο θαυμαστικό\",Agrave:\"Λατινικό κεφαλαίο γράμμα A με βαρεία\",Aacute:\"Λατινικό κεφαλαίο γράμμα A με οξεία\",Acirc:\"Λατινικό κεφαλαίο γράμμα A με περισπωμένη\",Atilde:\"Λατινικό κεφαλαίο γράμμα A με περισπωμένη\",Auml:\"Λατινικό κεφαλαίο γράμμα A με διαλυτικά\",Aring:\"Λατινικό κεφαλαίο γράμμα A με δακτύλιο επάνω\",AElig:\"Λατινικό κεφαλαίο γράμμα Æ\",Ccedil:\"Λατινικό κεφαλαίο γράμμα C με υπογεγραμμένη\",Egrave:\"Λατινικό κεφαλαίο γράμμα E με βαρεία\",Eacute:\"Λατινικό κεφαλαίο γράμμα E με οξεία\",Ecirc:\"Λατινικό κεφαλαίο γράμμα Ε με περισπωμένη \",\nEuml:\"Λατινικό κεφαλαίο γράμμα Ε με διαλυτικά\",Igrave:\"Λατινικό κεφαλαίο γράμμα I με βαρεία\",Iacute:\"Λατινικό κεφαλαίο γράμμα I με οξεία\",Icirc:\"Λατινικό κεφαλαίο γράμμα I  με περισπωμένη\",Iuml:\"Λατινικό κεφαλαίο γράμμα I με διαλυτικά \",ETH:\"Λατινικό κεφαλαίο γράμμα Eth\",Ntilde:\"Λατινικό κεφαλαίο γράμμα N με περισπωμένη\",Ograve:\"Λατινικό κεφαλαίο γράμμα O με βαρεία\",Oacute:\"Λατινικό κεφαλαίο γράμμα O με οξεία\",Ocirc:\"Λατινικό κεφαλαίο γράμμα O με περισπωμένη \",Otilde:\"Λατινικό κεφαλαίο γράμμα O με περισπωμένη\",\nOuml:\"Λατινικό κεφαλαίο γράμμα O με διαλυτικά\",times:\"Σύμβολο πολλαπλασιασμού\",Oslash:\"Λατινικό κεφαλαίο γράμμα O με μολυβιά\",Ugrave:\"Λατινικό κεφαλαίο γράμμα U με βαρεία\",Uacute:\"Λατινικό κεφαλαίο γράμμα U με οξεία\",Ucirc:\"Λατινικό κεφαλαίο γράμμα U με περισπωμένη\",Uuml:\"Λατινικό κεφαλαίο γράμμα U με διαλυτικά\",Yacute:\"Λατινικό κεφαλαίο γράμμα Y με οξεία\",THORN:\"Λατινικό κεφαλαίο γράμμα Thorn\",szlig:\"Λατινικό μικρό γράμμα απότομο s\",agrave:\"Λατινικό μικρό γράμμα a με βαρεία\",aacute:\"Λατινικό μικρό γράμμα a με οξεία\",\nacirc:\"Λατινικό μικρό γράμμα a με περισπωμένη\",atilde:\"Λατινικό μικρό γράμμα a με περισπωμένη\",auml:\"Λατινικό μικρό γράμμα a με διαλυτικά\",aring:\"Λατινικό μικρό γράμμα a με δακτύλιο πάνω\",aelig:\"Λατινικό μικρό γράμμα æ\",ccedil:\"Λατινικό μικρό γράμμα c με υπογεγραμμένη\",egrave:\"Λατινικό μικρό γράμμα ε με βαρεία\",eacute:\"Λατινικό μικρό γράμμα e με οξεία\",ecirc:\"Λατινικό μικρό γράμμα e με περισπωμένη\",euml:\"Λατινικό μικρό γράμμα e με διαλυτικά\",igrave:\"Λατινικό μικρό γράμμα i με βαρεία\",iacute:\"Λατινικό μικρό γράμμα i με οξεία\",\nicirc:\"Λατινικό μικρό γράμμα i με περισπωμένη\",iuml:\"Λατινικό μικρό γράμμα i με διαλυτικά\",eth:\"Λατινικό μικρό γράμμα eth\",ntilde:\"Λατινικό μικρό γράμμα n με περισπωμένη\",ograve:\"Λατινικό μικρό γράμμα o με βαρεία\",oacute:\"Λατινικό μικρό γράμμα o με οξεία \",ocirc:\"Λατινικό πεζό γράμμα o με περισπωμένη\",otilde:\"Λατινικό μικρό γράμμα o με περισπωμένη \",ouml:\"Λατινικό μικρό γράμμα o με διαλυτικά\",divide:\"Σύμβολο διαίρεσης\",oslash:\"Λατινικό μικρό γράμμα o με περισπωμένη\",ugrave:\"Λατινικό μικρό γράμμα u με βαρεία\",\nuacute:\"Λατινικό μικρό γράμμα u με οξεία\",ucirc:\"Λατινικό μικρό γράμμα u με περισπωμένη\",uuml:\"Λατινικό μικρό γράμμα u με διαλυτικά\",yacute:\"Λατινικό μικρό γράμμα y με οξεία\",thorn:\"Λατινικό μικρό γράμμα thorn\",yuml:\"Λατινικό μικρό γράμμα y με διαλυτικά\",OElig:\"Λατινικό κεφαλαίο σύμπλεγμα ΟΕ\",oelig:\"Λατινικό μικρό σύμπλεγμα oe\",372:\"Λατινικό κεφαλαίο γράμμα W με περισπωμένη\",374:\"Λατινικό κεφαλαίο γράμμα Y με περισπωμένη\",373:\"Λατινικό μικρό γράμμα w με περισπωμένη\",375:\"Λατινικό μικρό γράμμα y με περισπωμένη\",\nsbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",hellip:\"Οριζόντια αποσιωπητικά\",trade:\"Σύμβολο εμπορικού κατατεθέν\",9658:\"Μαύρος δείκτης που δείχνει προς τα δεξιά\",bull:\"Κουκκίδα\",rarr:\"Δεξί βελάκι\",rArr:\"Διπλό δεξί βελάκι\",hArr:\"Διπλό βελάκι αριστερά-δεξιά\",diams:\"Μαύρο διαμάντι\",asymp:\"Σχεδόν ίσο με\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/en.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"en\",{euro:\"Euro sign\",lsquo:\"Left single quotation mark\",rsquo:\"Right single quotation mark\",ldquo:\"Left double quotation mark\",rdquo:\"Right double quotation mark\",ndash:\"En dash\",mdash:\"Em dash\",iexcl:\"Inverted exclamation mark\",cent:\"Cent sign\",pound:\"Pound sign\",curren:\"Currency sign\",yen:\"Yen sign\",brvbar:\"Broken bar\",sect:\"Section sign\",uml:\"Diaeresis\",copy:\"Copyright sign\",ordf:\"Feminine ordinal indicator\",laquo:\"Left-pointing double angle quotation mark\",\nnot:\"Not sign\",reg:\"Registered sign\",macr:\"Macron\",deg:\"Degree sign\",sup2:\"Superscript two\",sup3:\"Superscript three\",acute:\"Acute accent\",micro:\"Micro sign\",para:\"Pilcrow sign\",middot:\"Middle dot\",cedil:\"Cedilla\",sup1:\"Superscript one\",ordm:\"Masculine ordinal indicator\",raquo:\"Right-pointing double angle quotation mark\",frac14:\"Vulgar fraction one quarter\",frac12:\"Vulgar fraction one half\",frac34:\"Vulgar fraction three quarters\",iquest:\"Inverted question mark\",Agrave:\"Latin capital letter A with grave accent\",\nAacute:\"Latin capital letter A with acute accent\",Acirc:\"Latin capital letter A with circumflex\",Atilde:\"Latin capital letter A with tilde\",Auml:\"Latin capital letter A with diaeresis\",Aring:\"Latin capital letter A with ring above\",AElig:\"Latin Capital letter Æ\",Ccedil:\"Latin capital letter C with cedilla\",Egrave:\"Latin capital letter E with grave accent\",Eacute:\"Latin capital letter E with acute accent\",Ecirc:\"Latin capital letter E with circumflex\",Euml:\"Latin capital letter E with diaeresis\",Igrave:\"Latin capital letter I with grave accent\",\nIacute:\"Latin capital letter I with acute accent\",Icirc:\"Latin capital letter I with circumflex\",Iuml:\"Latin capital letter I with diaeresis\",ETH:\"Latin capital letter Eth\",Ntilde:\"Latin capital letter N with tilde\",Ograve:\"Latin capital letter O with grave accent\",Oacute:\"Latin capital letter O with acute accent\",Ocirc:\"Latin capital letter O with circumflex\",Otilde:\"Latin capital letter O with tilde\",Ouml:\"Latin capital letter O with diaeresis\",times:\"Multiplication sign\",Oslash:\"Latin capital letter O with stroke\",\nUgrave:\"Latin capital letter U with grave accent\",Uacute:\"Latin capital letter U with acute accent\",Ucirc:\"Latin capital letter U with circumflex\",Uuml:\"Latin capital letter U with diaeresis\",Yacute:\"Latin capital letter Y with acute accent\",THORN:\"Latin capital letter Thorn\",szlig:\"Latin small letter sharp s\",agrave:\"Latin small letter a with grave accent\",aacute:\"Latin small letter a with acute accent\",acirc:\"Latin small letter a with circumflex\",atilde:\"Latin small letter a with tilde\",auml:\"Latin small letter a with diaeresis\",\naring:\"Latin small letter a with ring above\",aelig:\"Latin small letter æ\",ccedil:\"Latin small letter c with cedilla\",egrave:\"Latin small letter e with grave accent\",eacute:\"Latin small letter e with acute accent\",ecirc:\"Latin small letter e with circumflex\",euml:\"Latin small letter e with diaeresis\",igrave:\"Latin small letter i with grave accent\",iacute:\"Latin small letter i with acute accent\",icirc:\"Latin small letter i with circumflex\",iuml:\"Latin small letter i with diaeresis\",eth:\"Latin small letter eth\",\nntilde:\"Latin small letter n with tilde\",ograve:\"Latin small letter o with grave accent\",oacute:\"Latin small letter o with acute accent\",ocirc:\"Latin small letter o with circumflex\",otilde:\"Latin small letter o with tilde\",ouml:\"Latin small letter o with diaeresis\",divide:\"Division sign\",oslash:\"Latin small letter o with stroke\",ugrave:\"Latin small letter u with grave accent\",uacute:\"Latin small letter u with acute accent\",ucirc:\"Latin small letter u with circumflex\",uuml:\"Latin small letter u with diaeresis\",\nyacute:\"Latin small letter y with acute accent\",thorn:\"Latin small letter thorn\",yuml:\"Latin small letter y with diaeresis\",OElig:\"Latin capital ligature OE\",oelig:\"Latin small ligature oe\",372:\"Latin capital letter W with circumflex\",374:\"Latin capital letter Y with circumflex\",373:\"Latin small letter w with circumflex\",375:\"Latin small letter y with circumflex\",sbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",hellip:\"Horizontal ellipsis\",\ntrade:\"Trade mark sign\",9658:\"Black right-pointing pointer\",bull:\"Bullet\",rarr:\"Rightwards arrow\",rArr:\"Rightwards double arrow\",hArr:\"Left right double arrow\",diams:\"Black diamond suit\",asymp:\"Almost equal to\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/eo.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"eo\",{euro:\"Eŭrosigno\",lsquo:\"Supra 6-citilo\",rsquo:\"Supra 9-citilo\",ldquo:\"Supra 66-citilo\",rdquo:\"Supra 99-citilo\",ndash:\"Streketo\",mdash:\"Substreko\",iexcl:\"Renversita krisigno\",cent:\"Cendosigno\",pound:\"Pundosigno\",curren:\"Monersigno\",yen:\"Enosigno\",brvbar:\"Rompita vertikala streko\",sect:\"Kurba paragrafo\",uml:\"Tremao\",copy:\"Kopirajtosigno\",ordf:\"Adjektiva numerfinaĵo\",laquo:\"Duobla malplio-citilo\",not:\"Negohoko\",reg:\"Registrita marko\",macr:\"Superstreko\",deg:\"Gradosigno\",\nsup2:\"Supra indico 2\",sup3:\"Supra indico 3\",acute:\"Dekstra korno\",micro:\"Mikrosigno\",para:\"Rekta paragrafo\",middot:\"Meza punkto\",cedil:\"Zoeto\",sup1:\"Supra indico 1\",ordm:\"Substantiva numerfinaĵo\",raquo:\"Duobla plio-citilo\",frac14:\"Kvaronosigno\",frac12:\"Duonosigno\",frac34:\"Trikvaronosigno\",iquest:\"renversita demandosigno\",Agrave:\"Latina ĉeflitero A kun liva korno\",Aacute:\"Latina ĉeflitero A kun dekstra korno\",Acirc:\"Latina ĉeflitero A kun ĉapelo\",Atilde:\"Latina ĉeflitero A kun tildo\",Auml:\"Latina ĉeflitero A kun tremao\",\nAring:\"Latina ĉeflitero A kun superringo\",AElig:\"Latina ĉeflitera ligaturo Æ\",Ccedil:\"Latina ĉeflitero C kun zoeto\",Egrave:\"Latina ĉeflitero E kun liva korno\",Eacute:\"Latina ĉeflitero E kun dekstra korno\",Ecirc:\"Latina ĉeflitero E kun ĉapelo\",Euml:\"Latina ĉeflitero E kun tremao\",Igrave:\"Latina ĉeflitero I kun liva korno\",Iacute:\"Latina ĉeflitero I kun dekstra korno\",Icirc:\"Latina ĉeflitero I kun ĉapelo\",Iuml:\"Latina ĉeflitero I kun tremao\",ETH:\"Latina ĉeflitero islanda edo\",Ntilde:\"Latina ĉeflitero N kun tildo\",\nOgrave:\"Latina ĉeflitero O kun liva korno\",Oacute:\"Latina ĉeflitero O kun dekstra korno\",Ocirc:\"Latina ĉeflitero O kun ĉapelo\",Otilde:\"Latina ĉeflitero O kun tildo\",Ouml:\"Latina ĉeflitero O kun tremao\",times:\"Multipliko\",Oslash:\"Latina ĉeflitero O trastrekita\",Ugrave:\"Latina ĉeflitero U kun liva korno\",Uacute:\"Latina ĉeflitero U kun dekstra korno\",Ucirc:\"Latina ĉeflitero U kun ĉapelo\",Uuml:\"Latina ĉeflitero U kun tremao\",Yacute:\"Latina ĉeflitero Y kun dekstra korno\",THORN:\"Latina ĉeflitero islanda dorno\",\nszlig:\"Latina etlitero germana sozo (akra s)\",agrave:\"Latina etlitero a kun liva korno\",aacute:\"Latina etlitero a kun dekstra korno\",acirc:\"Latina etlitero a kun ĉapelo\",atilde:\"Latina etlitero a kun tildo\",auml:\"Latina etlitero a kun tremao\",aring:\"Latina etlitero a kun superringo\",aelig:\"Latina etlitera ligaturo æ\",ccedil:\"Latina etlitero c kun zoeto\",egrave:\"Latina etlitero e kun liva korno\",eacute:\"Latina etlitero e kun dekstra korno\",ecirc:\"Latina etlitero e kun ĉapelo\",euml:\"Latina etlitero e kun tremao\",\nigrave:\"Latina etlitero i kun liva korno\",iacute:\"Latina etlitero i kun dekstra korno\",icirc:\"Latina etlitero i kun ĉapelo\",iuml:\"Latina etlitero i kun tremao\",eth:\"Latina etlitero islanda edo\",ntilde:\"Latina etlitero n kun tildo\",ograve:\"Latina etlitero o kun liva korno\",oacute:\"Latina etlitero o kun dekstra korno\",ocirc:\"Latina etlitero o kun ĉapelo\",otilde:\"Latina etlitero o kun tildo\",ouml:\"Latina etlitero o kun tremao\",divide:\"Dividosigno\",oslash:\"Latina etlitero o trastrekita\",ugrave:\"Latina etlitero u kun liva korno\",\nuacute:\"Latina etlitero u kun dekstra korno\",ucirc:\"Latina etlitero u kun ĉapelo\",uuml:\"Latina etlitero u kun tremao\",yacute:\"Latina etlitero y kun dekstra korno\",thorn:\"Latina etlitero islanda dorno\",yuml:\"Latina etlitero y kun tremao\",OElig:\"Latina ĉeflitera ligaturo Œ\",oelig:\"Latina etlitera ligaturo œ\",372:\"Latina ĉeflitero W kun ĉapelo\",374:\"Latina ĉeflitero Y kun ĉapelo\",373:\"Latina etlitero w kun ĉapelo\",375:\"Latina etlitero y kun ĉapelo\",sbquo:\"Suba 9-citilo\",8219:\"Supra renversita 9-citilo\",\nbdquo:\"Suba 99-citilo\",hellip:\"Tripunkto\",trade:\"Varmarka signo\",9658:\"Nigra sago dekstren\",bull:\"Bulmarko\",rarr:\"Sago dekstren\",rArr:\"Duobla sago dekstren\",hArr:\"Duobla sago maldekstren\",diams:\"Nigra kvadrato\",asymp:\"Preskaŭ egala\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/es.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"es\",{euro:\"Símbolo de euro\",lsquo:\"Comilla simple izquierda\",rsquo:\"Comilla simple derecha\",ldquo:\"Comilla doble izquierda\",rdquo:\"Comilla doble derecha\",ndash:\"Guión corto\",mdash:\"Guión medio largo\",iexcl:\"Signo de admiración invertido\",cent:\"Símbolo centavo\",pound:\"Símbolo libra\",curren:\"Símbolo moneda\",yen:\"Símbolo yen\",brvbar:\"Barra vertical rota\",sect:\"Símbolo sección\",uml:\"Diéresis\",copy:\"Signo de derechos de autor\",ordf:\"Indicador ordinal femenino\",laquo:\"Abre comillas angulares\",\nnot:\"Signo negación\",reg:\"Signo de marca registrada\",macr:\"Guión alto\",deg:\"Signo de grado\",sup2:\"Superíndice dos\",sup3:\"Superíndice tres\",acute:\"Acento agudo\",micro:\"Signo micro\",para:\"Signo de pi\",middot:\"Punto medio\",cedil:\"Cedilla\",sup1:\"Superíndice uno\",ordm:\"Indicador orginal masculino\",raquo:\"Cierra comillas angulares\",frac14:\"Fracción ordinaria de un quarto\",frac12:\"Fracción ordinaria de una mitad\",frac34:\"Fracción ordinaria de tres cuartos\",iquest:\"Signo de interrogación invertido\",Agrave:\"Letra A latina mayúscula con acento grave\",\nAacute:\"Letra A latina  mayúscula con acento agudo\",Acirc:\"Letra A latina mayúscula con acento circunflejo\",Atilde:\"Letra A latina mayúscula con tilde\",Auml:\"Letra A latina mayúscula con diéresis\",Aring:\"Letra A latina mayúscula con aro arriba\",AElig:\"Letra Æ latina mayúscula\",Ccedil:\"Letra C latina mayúscula con cedilla\",Egrave:\"Letra E latina mayúscula con acento grave\",Eacute:\"Letra E latina mayúscula con acento agudo\",Ecirc:\"Letra E latina mayúscula con acento circunflejo\",Euml:\"Letra E latina mayúscula con diéresis\",\nIgrave:\"Letra I latina mayúscula con acento grave\",Iacute:\"Letra I latina mayúscula con acento agudo\",Icirc:\"Letra I latina mayúscula con acento circunflejo\",Iuml:\"Letra I latina mayúscula con diéresis\",ETH:\"Letra Eth latina mayúscula\",Ntilde:\"Letra N latina mayúscula con tilde\",Ograve:\"Letra O latina mayúscula con acento grave\",Oacute:\"Letra O latina mayúscula con acento agudo\",Ocirc:\"Letra O latina mayúscula con acento circunflejo\",Otilde:\"Letra O latina mayúscula con tilde\",Ouml:\"Letra O latina mayúscula con diéresis\",\ntimes:\"Signo de multiplicación\",Oslash:\"Letra O latina mayúscula con barra inclinada\",Ugrave:\"Letra U latina mayúscula con acento grave\",Uacute:\"Letra U latina mayúscula con acento agudo\",Ucirc:\"Letra U latina mayúscula con acento circunflejo\",Uuml:\"Letra U latina mayúscula con diéresis\",Yacute:\"Letra Y latina mayúscula con acento agudo\",THORN:\"Letra Thorn latina mayúscula\",szlig:\"Letra s latina fuerte pequeña\",agrave:\"Letra a latina pequeña con acento grave\",aacute:\"Letra a latina pequeña con acento agudo\",\nacirc:\"Letra a latina pequeña con acento circunflejo\",atilde:\"Letra a latina pequeña con tilde\",auml:\"Letra a latina pequeña con diéresis\",aring:\"Letra a latina pequeña con aro arriba\",aelig:\"Letra æ latina pequeña\",ccedil:\"Letra c latina pequeña con cedilla\",egrave:\"Letra e latina pequeña con acento grave\",eacute:\"Letra e latina pequeña con acento agudo\",ecirc:\"Letra e latina pequeña con acento circunflejo\",euml:\"Letra e latina pequeña con diéresis\",igrave:\"Letra i latina pequeña con acento grave\",\niacute:\"Letra i latina pequeña con acento agudo\",icirc:\"Letra i latina pequeña con acento circunflejo\",iuml:\"Letra i latina pequeña con diéresis\",eth:\"Letra eth latina pequeña\",ntilde:\"Letra n latina pequeña con tilde\",ograve:\"Letra o latina pequeña con acento grave\",oacute:\"Letra o latina pequeña con acento agudo\",ocirc:\"Letra o latina pequeña con acento circunflejo\",otilde:\"Letra o latina pequeña con tilde\",ouml:\"Letra o latina pequeña con diéresis\",divide:\"Signo de división\",oslash:\"Letra o latina minúscula con barra inclinada\",\nugrave:\"Letra u latina pequeña con acento grave\",uacute:\"Letra u latina pequeña con acento agudo\",ucirc:\"Letra u latina pequeña con acento circunflejo\",uuml:\"Letra u latina pequeña con diéresis\",yacute:\"Letra u latina pequeña con acento agudo\",thorn:\"Letra thorn latina minúscula\",yuml:\"Letra y latina pequeña con diéresis\",OElig:\"Diptongo OE latino en mayúscula\",oelig:\"Diptongo oe latino en minúscula\",372:\"Letra W latina mayúscula con acento circunflejo\",374:\"Letra Y latina mayúscula con acento circunflejo\",\n373:\"Letra w latina pequeña con acento circunflejo\",375:\"Letra y latina pequeña con acento circunflejo\",sbquo:\"Comilla simple baja-9\",8219:\"Comilla simple alta invertida-9\",bdquo:\"Comillas dobles bajas-9\",hellip:\"Puntos suspensivos horizontales\",trade:\"Signo de marca registrada\",9658:\"Apuntador negro apuntando a la derecha\",bull:\"Viñeta\",rarr:\"Flecha a la derecha\",rArr:\"Flecha doble a la derecha\",hArr:\"Flecha izquierda derecha doble\",diams:\"Diamante negro\",asymp:\"Casi igual a\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/et.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"et\",{euro:\"Euromärk\",lsquo:\"Alustav ühekordne jutumärk\",rsquo:\"Lõpetav ühekordne jutumärk\",ldquo:\"Alustav kahekordne jutumärk\",rdquo:\"Lõpetav kahekordne jutumärk\",ndash:\"Enn-kriips\",mdash:\"Emm-kriips\",iexcl:\"Pööratud hüüumärk\",cent:\"Sendimärk\",pound:\"Naela märk\",curren:\"Valuutamärk\",yen:\"Jeeni märk\",brvbar:\"Katkestatud kriips\",sect:\"Lõigu märk\",uml:\"Täpid\",copy:\"Autoriõiguse märk\",ordf:\"Feminine ordinal indicator\",laquo:\"Left-pointing double angle quotation mark\",\nnot:\"Ei-märk\",reg:\"Registered sign\",macr:\"Macron\",deg:\"Kraadimärk\",sup2:\"Ülaindeks kaks\",sup3:\"Ülaindeks kolm\",acute:\"Acute accent\",micro:\"Mikro-märk\",para:\"Pilcrow sign\",middot:\"Keskpunkt\",cedil:\"Cedilla\",sup1:\"Ülaindeks üks\",ordm:\"Masculine ordinal indicator\",raquo:\"Right-pointing double angle quotation mark\",frac14:\"Vulgar fraction one quarter\",frac12:\"Vulgar fraction one half\",frac34:\"Vulgar fraction three quarters\",iquest:\"Inverted question mark\",Agrave:\"Latin capital letter A with grave accent\",\nAacute:\"Latin capital letter A with acute accent\",Acirc:\"Latin capital letter A with circumflex\",Atilde:\"Ladina suur A tildega\",Auml:\"Latin capital letter A with diaeresis\",Aring:\"Latin capital letter A with ring above\",AElig:\"Latin Capital letter Æ\",Ccedil:\"Latin capital letter C with cedilla\",Egrave:\"Latin capital letter E with grave accent\",Eacute:\"Latin capital letter E with acute accent\",Ecirc:\"Latin capital letter E with circumflex\",Euml:\"Latin capital letter E with diaeresis\",Igrave:\"Latin capital letter I with grave accent\",\nIacute:\"Latin capital letter I with acute accent\",Icirc:\"Latin capital letter I with circumflex\",Iuml:\"Latin capital letter I with diaeresis\",ETH:\"Latin capital letter Eth\",Ntilde:\"Latin capital letter N with tilde\",Ograve:\"Latin capital letter O with grave accent\",Oacute:\"Latin capital letter O with acute accent\",Ocirc:\"Latin capital letter O with circumflex\",Otilde:\"Latin capital letter O with tilde\",Ouml:\"Täppidega ladina suur O\",times:\"Multiplication sign\",Oslash:\"Latin capital letter O with stroke\",\nUgrave:\"Latin capital letter U with grave accent\",Uacute:\"Latin capital letter U with acute accent\",Ucirc:\"Kandilise katusega suur ladina U\",Uuml:\"Täppidega ladina suur U\",Yacute:\"Latin capital letter Y with acute accent\",THORN:\"Latin capital letter Thorn\",szlig:\"Ladina väike terav s\",agrave:\"Latin small letter a with grave accent\",aacute:\"Latin small letter a with acute accent\",acirc:\"Kandilise katusega ladina väike a\",atilde:\"Tildega ladina väike a\",auml:\"Täppidega ladina väike a\",aring:\"Latin small letter a with ring above\",\naelig:\"Latin small letter æ\",ccedil:\"Latin small letter c with cedilla\",egrave:\"Latin small letter e with grave accent\",eacute:\"Latin small letter e with acute accent\",ecirc:\"Latin small letter e with circumflex\",euml:\"Latin small letter e with diaeresis\",igrave:\"Latin small letter i with grave accent\",iacute:\"Latin small letter i with acute accent\",icirc:\"Latin small letter i with circumflex\",iuml:\"Latin small letter i with diaeresis\",eth:\"Latin small letter eth\",ntilde:\"Latin small letter n with tilde\",\nograve:\"Latin small letter o with grave accent\",oacute:\"Latin small letter o with acute accent\",ocirc:\"Latin small letter o with circumflex\",otilde:\"Latin small letter o with tilde\",ouml:\"Latin small letter o with diaeresis\",divide:\"Jagamismärk\",oslash:\"Latin small letter o with stroke\",ugrave:\"Latin small letter u with grave accent\",uacute:\"Latin small letter u with acute accent\",ucirc:\"Latin small letter u with circumflex\",uuml:\"Latin small letter u with diaeresis\",yacute:\"Latin small letter y with acute accent\",\nthorn:\"Latin small letter thorn\",yuml:\"Latin small letter y with diaeresis\",OElig:\"Latin capital ligature OE\",oelig:\"Latin small ligature oe\",372:\"Latin capital letter W with circumflex\",374:\"Latin capital letter Y with circumflex\",373:\"Latin small letter w with circumflex\",375:\"Latin small letter y with circumflex\",sbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",hellip:\"Horizontal ellipsis\",trade:\"Kaubamärgi märk\",9658:\"Black right-pointing pointer\",\nbull:\"Kuul\",rarr:\"Nool paremale\",rArr:\"Topeltnool paremale\",hArr:\"Topeltnool vasakule\",diams:\"Black diamond suit\",asymp:\"Ligikaudu võrdne\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/fa.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"fa\",{euro:\"نشان یورو\",lsquo:\"علامت نقل قول تکی چپ\",rsquo:\"علامت نقل قول تکی راست\",ldquo:\"علامت نقل قول دوتایی چپ\",rdquo:\"علامت نقل قول دوتایی راست\",ndash:\"خط تیره En\",mdash:\"خط تیره Em\",iexcl:\"علامت تعجب وارونه\",cent:\"نشان سنت\",pound:\"نشان پوند\",curren:\"نشان ارز\",yen:\"نشان ین\",brvbar:\"نوار شکسته\",sect:\"نشان بخش\",uml:\"نشان سواگیری\",copy:\"نشان کپی رایت\",ordf:\"شاخص ترتیبی مونث\",laquo:\"اشاره چپ مکرر برای زاویه علامت نقل قول\",not:\"نشان ثبت نشده\",reg:\"نشان ثبت شده\",\nmacr:\"نشان خط بالای حرف\",deg:\"نشان درجه\",sup2:\"بالانویس دو\",sup3:\"بالانویس سه\",acute:\"لهجه غلیظ\",micro:\"نشان مایکرو\",para:\"نشان محل بند\",middot:\"نقطه میانی\",cedil:\"سدیل\",sup1:\"بالانویس 1\",ordm:\"شاخص ترتیبی مذکر\",raquo:\"نشان زاویه‌دار دوتایی نقل قول راست چین\",frac14:\"واحد عامیانه 1/4\",frac12:\"واحد عامینه نصف\",frac34:\"واحد عامیانه 3/4\",iquest:\"علامت سوال معکوس\",Agrave:\"حرف A بزرگ لاتین با تلفظ غلیظ\",Aacute:\"حرف A بزرگ لاتین با تلفظ شدید\",Acirc:\"حرف A بزرگ لاتین با دور\",Atilde:\"حرف A بزرگ لاتین با صدای کامی\",\nAuml:\"حرف A بزرگ لاتین با نشان سواگیری\",Aring:\"حرف A بزرگ لاتین با حلقه بالا\",AElig:\"حرف Æ بزرگ لاتین\",Ccedil:\"حرف C بزرگ لاتین با نشان سواگیری\",Egrave:\"حرف E بزرگ لاتین با تلفظ درشت\",Eacute:\"حرف E بزرگ لاتین با تلفظ زیر\",Ecirc:\"حرف E بزرگ لاتین با خمان\",Euml:\"حرف E بزرگ لاتین با نشان سواگیری\",Igrave:\"حرف I بزرگ لاتین با تلفظ درشت\",Iacute:\"حرف I بزرگ لاتین با تلفظ ریز\",Icirc:\"حرف I بزرگ لاتین با خمان\",Iuml:\"حرف I بزرگ لاتین با نشان سواگیری\",ETH:\"حرف لاتین بزرگ واکه ترتیبی\",Ntilde:\"حرف N بزرگ لاتین با مد\",\nOgrave:\"حرف O بزرگ لاتین با تلفظ درشت\",Oacute:\"حرف O بزرگ لاتین با تلفظ ریز\",Ocirc:\"حرف O بزرگ لاتین با خمان\",Otilde:\"حرف O بزرگ لاتین با مد\",Ouml:\"حرف O بزرگ لاتین با نشان سواگیری\",times:\"نشان ضربدر\",Oslash:\"حرف O بزرگ لاتین با میان خط\",Ugrave:\"حرف U بزرگ لاتین با تلفظ درشت\",Uacute:\"حرف U بزرگ لاتین با تلفظ ریز\",Ucirc:\"حرف U بزرگ لاتین با خمان\",Uuml:\"حرف U بزرگ لاتین با نشان سواگیری\",Yacute:\"حرف Y بزرگ لاتین با تلفظ ریز\",THORN:\"حرف بزرگ لاتین خاردار\",szlig:\"حرف کوچک لاتین شارپ s\",agrave:\"حرف a کوچک لاتین با تلفظ درشت\",\naacute:\"حرف a کوچک لاتین با تلفظ ریز\",acirc:\"حرف a کوچک لاتین با خمان\",atilde:\"حرف a کوچک لاتین با صدای کامی\",auml:\"حرف a کوچک لاتین با نشان سواگیری\",aring:\"حرف a کوچک لاتین گوشواره دار\",aelig:\"حرف کوچک لاتین æ\",ccedil:\"حرف c کوچک لاتین با نشان سدیل\",egrave:\"حرف e کوچک لاتین با تلفظ درشت\",eacute:\"حرف e کوچک لاتین با تلفظ ریز\",ecirc:\"حرف e کوچک لاتین با خمان\",euml:\"حرف e کوچک لاتین با نشان سواگیری\",igrave:\"حرف i کوچک لاتین با تلفظ درشت\",iacute:\"حرف i کوچک لاتین با تلفظ ریز\",icirc:\"حرف i کوچک لاتین با خمان\",\niuml:\"حرف i کوچک لاتین با نشان سواگیری\",eth:\"حرف کوچک لاتین eth\",ntilde:\"حرف n کوچک لاتین با صدای کامی\",ograve:\"حرف o کوچک لاتین با تلفظ درشت\",oacute:\"حرف o کوچک لاتین با تلفظ زیر\",ocirc:\"حرف o کوچک لاتین با خمان\",otilde:\"حرف o کوچک لاتین با صدای کامی\",ouml:\"حرف o کوچک لاتین با نشان سواگیری\",divide:\"نشان بخش\",oslash:\"حرف o کوچک لاتین با میان خط\",ugrave:\"حرف u کوچک لاتین با تلفظ درشت\",uacute:\"حرف u کوچک لاتین با تلفظ ریز\",ucirc:\"حرف u کوچک لاتین با خمان\",uuml:\"حرف u کوچک لاتین با نشان سواگیری\",yacute:\"حرف y کوچک لاتین با تلفظ ریز\",\nthorn:\"حرف کوچک لاتین خاردار\",yuml:\"حرف y کوچک لاتین با نشان سواگیری\",OElig:\"بند بزرگ لاتین OE\",oelig:\"بند کوچک لاتین oe\",372:\"حرف W بزرگ لاتین با خمان\",374:\"حرف Y بزرگ لاتین با خمان\",373:\"حرف w کوچک لاتین با خمان\",375:\"حرف y کوچک لاتین با خمان\",sbquo:\"نشان نقل قول تکی زیر-9\",8219:\"نشان نقل قول تکی high-reversed-9\",bdquo:\"نقل قول دوتایی پایین-9\",hellip:\"حذف افقی\",trade:\"نشان تجاری\",9658:\"نشانگر سیاه جهت راست\",bull:\"گلوله\",rarr:\"فلش راست\",rArr:\"فلش دوتایی راست\",hArr:\"فلش دوتایی چپ راست\",diams:\"نشان الماس سیاه\",\nasymp:\"تقریبا برابر با\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/fi.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"fi\",{euro:\"Euron merkki\",lsquo:\"Vasen yksittäinen lainausmerkki\",rsquo:\"Oikea yksittäinen lainausmerkki\",ldquo:\"Vasen kaksoislainausmerkki\",rdquo:\"Oikea kaksoislainausmerkki\",ndash:\"En dash\",mdash:\"Em dash\",iexcl:\"Inverted exclamation mark\",cent:\"Sentin merkki\",pound:\"Punnan merkki\",curren:\"Valuuttamerkki\",yen:\"Yenin merkki\",brvbar:\"Broken bar\",sect:\"Section sign\",uml:\"Diaeresis\",copy:\"Copyright sign\",ordf:\"Feminine ordinal indicator\",laquo:\"Left-pointing double angle quotation mark\",\nnot:\"Not sign\",reg:\"Rekisteröity merkki\",macr:\"Macron\",deg:\"Asteen merkki\",sup2:\"Yläindeksi kaksi\",sup3:\"Yläindeksi kolme\",acute:\"Acute accent\",micro:\"Mikron merkki\",para:\"Pilcrow sign\",middot:\"Middle dot\",cedil:\"Cedilla\",sup1:\"Yläindeksi yksi\",ordm:\"Masculine ordinal indicator\",raquo:\"Right-pointing double angle quotation mark\",frac14:\"Vulgar fraction one quarter\",frac12:\"Vulgar fraction one half\",frac34:\"Vulgar fraction three quarters\",iquest:\"Ylösalaisin oleva kysymysmerkki\",Agrave:\"Latin capital letter A with grave accent\",\nAacute:\"Latin capital letter A with acute accent\",Acirc:\"Latin capital letter A with circumflex\",Atilde:\"Latin capital letter A with tilde\",Auml:\"Latin capital letter A with diaeresis\",Aring:\"Latin capital letter A with ring above\",AElig:\"Latin Capital letter Æ\",Ccedil:\"Latin capital letter C with cedilla\",Egrave:\"Latin capital letter E with grave accent\",Eacute:\"Latin capital letter E with acute accent\",Ecirc:\"Latin capital letter E with circumflex\",Euml:\"Latin capital letter E with diaeresis\",Igrave:\"Latin capital letter I with grave accent\",\nIacute:\"Latin capital letter I with acute accent\",Icirc:\"Latin capital letter I with circumflex\",Iuml:\"Latin capital letter I with diaeresis\",ETH:\"Latin capital letter Eth\",Ntilde:\"Latin capital letter N with tilde\",Ograve:\"Latin capital letter O with grave accent\",Oacute:\"Latin capital letter O with acute accent\",Ocirc:\"Latin capital letter O with circumflex\",Otilde:\"Latin capital letter O with tilde\",Ouml:\"Latin capital letter O with diaeresis\",times:\"Kertomerkki\",Oslash:\"Latin capital letter O with stroke\",\nUgrave:\"Latin capital letter U with grave accent\",Uacute:\"Latin capital letter U with acute accent\",Ucirc:\"Latin capital letter U with circumflex\",Uuml:\"Latin capital letter U with diaeresis\",Yacute:\"Latin capital letter Y with acute accent\",THORN:\"Latin capital letter Thorn\",szlig:\"Latin small letter sharp s\",agrave:\"Latin small letter a with grave accent\",aacute:\"Latin small letter a with acute accent\",acirc:\"Latin small letter a with circumflex\",atilde:\"Latin small letter a with tilde\",auml:\"Latin small letter a with diaeresis\",\naring:\"Latin small letter a with ring above\",aelig:\"Latin small letter æ\",ccedil:\"Latin small letter c with cedilla\",egrave:\"Latin small letter e with grave accent\",eacute:\"Latin small letter e with acute accent\",ecirc:\"Latin small letter e with circumflex\",euml:\"Latin small letter e with diaeresis\",igrave:\"Latin small letter i with grave accent\",iacute:\"Latin small letter i with acute accent\",icirc:\"Latin small letter i with circumflex\",iuml:\"Latin small letter i with diaeresis\",eth:\"Latin small letter eth\",\nntilde:\"Latin small letter n with tilde\",ograve:\"Latin small letter o with grave accent\",oacute:\"Latin small letter o with acute accent\",ocirc:\"Latin small letter o with circumflex\",otilde:\"Latin small letter o with tilde\",ouml:\"Latin small letter o with diaeresis\",divide:\"Jakomerkki\",oslash:\"Latin small letter o with stroke\",ugrave:\"Latin small letter u with grave accent\",uacute:\"Latin small letter u with acute accent\",ucirc:\"Latin small letter u with circumflex\",uuml:\"Latin small letter u with diaeresis\",\nyacute:\"Latin small letter y with acute accent\",thorn:\"Latin small letter thorn\",yuml:\"Latin small letter y with diaeresis\",OElig:\"Latin capital ligature OE\",oelig:\"Latin small ligature oe\",372:\"Latin capital letter W with circumflex\",374:\"Latin capital letter Y with circumflex\",373:\"Latin small letter w with circumflex\",375:\"Latin small letter y with circumflex\",sbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",hellip:\"Horizontal ellipsis\",\ntrade:\"Tavaramerkki merkki\",9658:\"Black right-pointing pointer\",bull:\"Bullet\",rarr:\"Nuoli oikealle\",rArr:\"Kaksoisnuoli oikealle\",hArr:\"Kaksoisnuoli oikealle ja vasemmalle\",diams:\"Black diamond suit\",asymp:\"Noin\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/fr-ca.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"fr-ca\",{euro:\"Symbole Euro\",lsquo:\"Guillemet simple ouvrant\",rsquo:\"Guillemet simple fermant\",ldquo:\"Guillemet double ouvrant\",rdquo:\"Guillemet double fermant\",ndash:\"Tiret haut\",mdash:\"Tiret\",iexcl:\"Point d'exclamation inversé\",cent:\"Symbole de cent\",pound:\"Symbole de Livre Sterling\",curren:\"Symbole monétaire\",yen:\"Symbole du Yen\",brvbar:\"Barre scindée\",sect:\"Symbole de section\",uml:\"Tréma\",copy:\"Symbole de copyright\",ordf:\"Indicateur ordinal féminin\",laquo:\"Guillemet français ouvrant\",\nnot:\"Indicateur de négation\",reg:\"Symbole de marque déposée\",macr:\"Macron\",deg:\"Degré\",sup2:\"Exposant 2\",sup3:\"Exposant 3\",acute:\"Accent aigüe\",micro:\"Symbole micro\",para:\"Paragraphe\",middot:\"Point médian\",cedil:\"Cédille\",sup1:\"Exposant 1\",ordm:\"Indicateur ordinal masculin\",raquo:\"Guillemet français fermant\",frac14:\"Un quart\",frac12:\"Une demi\",frac34:\"Trois quart\",iquest:\"Point d'interrogation inversé\",Agrave:\"A accent grave\",Aacute:\"A accent aigüe\",Acirc:\"A circonflexe\",Atilde:\"A tilde\",Auml:\"A tréma\",\nAring:\"A avec un rond au dessus\",AElig:\"Æ majuscule\",Ccedil:\"C cédille\",Egrave:\"E accent grave\",Eacute:\"E accent aigüe\",Ecirc:\"E accent circonflexe\",Euml:\"E tréma\",Igrave:\"I accent grave\",Iacute:\"I accent aigüe\",Icirc:\"I accent circonflexe\",Iuml:\"I tréma\",ETH:\"Lettre majuscule islandaise ED\",Ntilde:\"N tilde\",Ograve:\"O accent grave\",Oacute:\"O accent aigüe\",Ocirc:\"O accent circonflexe\",Otilde:\"O tilde\",Ouml:\"O tréma\",times:\"Symbole de multiplication\",Oslash:\"O barré\",Ugrave:\"U accent grave\",Uacute:\"U accent aigüe\",\nUcirc:\"U accent circonflexe\",Uuml:\"U tréma\",Yacute:\"Y accent aigüe\",THORN:\"Lettre islandaise Thorn majuscule\",szlig:\"Lettre minuscule allemande s dur\",agrave:\"a accent grave\",aacute:\"a accent aigüe\",acirc:\"a accent circonflexe\",atilde:\"a tilde\",auml:\"a tréma\",aring:\"a avec un cercle au dessus\",aelig:\"æ\",ccedil:\"c cédille\",egrave:\"e accent grave\",eacute:\"e accent aigüe\",ecirc:\"e accent circonflexe\",euml:\"e tréma\",igrave:\"i accent grave\",iacute:\"i accent aigüe\",icirc:\"i accent circonflexe\",iuml:\"i tréma\",\neth:\"Lettre minuscule islandaise ED\",ntilde:\"n tilde\",ograve:\"o accent grave\",oacute:\"o accent aigüe\",ocirc:\"O accent circonflexe\",otilde:\"O tilde\",ouml:\"O tréma\",divide:\"Symbole de division\",oslash:\"o barré\",ugrave:\"u accent grave\",uacute:\"u accent aigüe\",ucirc:\"u accent circonflexe\",uuml:\"u tréma\",yacute:\"y accent aigüe\",thorn:\"Lettre islandaise thorn minuscule\",yuml:\"y tréma\",OElig:\"ligature majuscule latine Œ\",oelig:\"ligature minuscule latine œ\",372:\"W accent circonflexe\",374:\"Y accent circonflexe\",\n373:\"w accent circonflexe\",375:\"y accent circonflexe\",sbquo:\"Guillemet simple fermant\",8219:\"Guillemet-virgule supérieur culbuté\",bdquo:\"Guillemet-virgule double inférieur\",hellip:\"Points de suspension\",trade:\"Symbole de marque déposée\",9658:\"Flèche noire pointant vers la droite\",bull:\"Puce\",rarr:\"Flèche vers la droite\",rArr:\"Flèche double vers la droite\",hArr:\"Flèche double vers la gauche\",diams:\"Carreau\",asymp:\"Presque égal\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/fr.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"fr\",{euro:\"Symbole Euro\",lsquo:\"Guillemet simple ouvrant\",rsquo:\"Guillemet simple fermant\",ldquo:\"Guillemet double ouvrant\",rdquo:\"Guillemet double fermant\",ndash:\"Tiret haut\",mdash:\"Tiret cadratin\",iexcl:\"Point d'exclamation inversé\",cent:\"Symbole Cent\",pound:\"Symbole Livre Sterling\",curren:\"Symbole monétaire\",yen:\"Symbole Yen\",brvbar:\"Barre verticale scindée\",sect:\"Section\",uml:\"Tréma\",copy:\"Symbole Copyright\",ordf:\"Indicateur ordinal féminin\",laquo:\"Guillemet français ouvrant\",\nnot:\"Crochet de négation\",reg:\"Marque déposée\",macr:\"Macron\",deg:\"Degré\",sup2:\"Exposant 2\",sup3:\"\\\\tExposant 3\",acute:\"Accent aigu\",micro:\"Omicron\",para:\"Paragraphe\",middot:\"Point médian\",cedil:\"Cédille\",sup1:\"\\\\tExposant 1\",ordm:\"Indicateur ordinal masculin\",raquo:\"Guillemet français fermant\",frac14:\"Un quart\",frac12:\"Un demi\",frac34:\"Trois quarts\",iquest:\"Point d'interrogation inversé\",Agrave:\"A majuscule accent grave\",Aacute:\"A majuscule accent aigu\",Acirc:\"A majuscule accent circonflexe\",Atilde:\"A majuscule avec caron\",\nAuml:\"A majuscule tréma\",Aring:\"A majuscule avec un rond au-dessus\",AElig:\"Æ majuscule ligaturés\",Ccedil:\"C majuscule cédille\",Egrave:\"E majuscule accent grave\",Eacute:\"E majuscule accent aigu\",Ecirc:\"E majuscule accent circonflexe\",Euml:\"E majuscule tréma\",Igrave:\"I majuscule accent grave\",Iacute:\"I majuscule accent aigu\",Icirc:\"I majuscule accent circonflexe\",Iuml:\"I majuscule tréma\",ETH:\"Lettre majuscule islandaise ED\",Ntilde:\"N majuscule avec caron\",Ograve:\"O majuscule accent grave\",Oacute:\"O majuscule accent aigu\",\nOcirc:\"O majuscule accent circonflexe\",Otilde:\"O majuscule avec caron\",Ouml:\"O majuscule tréma\",times:\"Multiplication\",Oslash:\"O majuscule barré\",Ugrave:\"U majuscule accent grave\",Uacute:\"U majuscule accent aigu\",Ucirc:\"U majuscule accent circonflexe\",Uuml:\"U majuscule tréma\",Yacute:\"Y majuscule accent aigu\",THORN:\"Lettre islandaise Thorn majuscule\",szlig:\"Lettre minuscule allemande s dur\",agrave:\"a minuscule accent grave\",aacute:\"a minuscule accent aigu\",acirc:\"a minuscule accent circonflexe\",atilde:\"a minuscule avec caron\",\nauml:\"a minuscule tréma\",aring:\"a minuscule avec un rond au-dessus\",aelig:\"æ minuscule ligaturés\",ccedil:\"c minuscule cédille\",egrave:\"e minuscule accent grave\",eacute:\"e minuscule accent aigu\",ecirc:\"e minuscule accent circonflexe\",euml:\"e minuscule tréma\",igrave:\"i minuscule accent grave\",iacute:\"i minuscule accent aigu\",icirc:\"i minuscule accent circonflexe\",iuml:\"i minuscule tréma\",eth:\"Lettre minuscule islandaise ED\",ntilde:\"n minuscule avec caron\",ograve:\"o minuscule accent grave\",oacute:\"o minuscule accent aigu\",\nocirc:\"o minuscule accent circonflexe\",otilde:\"o minuscule avec caron\",ouml:\"o minuscule tréma\",divide:\"Division\",oslash:\"o minuscule barré\",ugrave:\"u minuscule accent grave\",uacute:\"u minuscule accent aigu\",ucirc:\"u minuscule accent circonflexe\",uuml:\"u minuscule tréma\",yacute:\"y minuscule accent aigu\",thorn:\"Lettre islandaise thorn minuscule\",yuml:\"y minuscule tréma\",OElig:\"ligature majuscule latine Œ\",oelig:\"ligature minuscule latine œ\",372:\"W majuscule accent circonflexe\",374:\"Y majuscule accent circonflexe\",\n373:\"w minuscule accent circonflexe\",375:\"y minuscule accent circonflexe\",sbquo:\"Guillemet simple fermant (anglais)\",8219:\"Guillemet-virgule supérieur culbuté\",bdquo:\"Guillemet-virgule double inférieur\",hellip:\"Points de suspension\",trade:\"Marque commerciale (trade mark)\",9658:\"Flèche noire pointant vers la droite\",bull:\"Gros point médian\",rarr:\"Flèche vers la droite\",rArr:\"Double flèche vers la droite\",hArr:\"Double flèche vers la gauche\",diams:\"Carreau noir\",asymp:\"Presque égal\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/gl.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"gl\",{euro:\"Símbolo do euro\",lsquo:\"Comiña simple esquerda\",rsquo:\"Comiña simple dereita\",ldquo:\"Comiñas dobres esquerda\",rdquo:\"Comiñas dobres dereita\",ndash:\"Guión\",mdash:\"Raia\",iexcl:\"Signo de admiración invertido\",cent:\"Símbolo do centavo\",pound:\"Símbolo da libra\",curren:\"Símbolo de moeda\",yen:\"Símbolo do yen\",brvbar:\"Barra vertical rota\",sect:\"Símbolo de sección\",uml:\"Diérese\",copy:\"Símbolo de dereitos de autoría\",ordf:\"Indicador ordinal feminino\",laquo:\"Comiñas latinas, apertura\",\nnot:\"Signo negación\",reg:\"Símbolo de marca rexistrada\",macr:\"Guión alto\",deg:\"Signo de grao\",sup2:\"Superíndice dous\",sup3:\"Superíndice tres\",acute:\"Acento agudo\",micro:\"Signo de micro\",para:\"Signo de pi\",middot:\"Punto medio\",cedil:\"Cedilla\",sup1:\"Superíndice un\",ordm:\"Indicador ordinal masculino\",raquo:\"Comiñas latinas, peche\",frac14:\"Fracción ordinaria de un cuarto\",frac12:\"Fracción ordinaria de un medio\",frac34:\"Fracción ordinaria de tres cuartos\",iquest:\"Signo de interrogación invertido\",Agrave:\"Letra A latina maiúscula con acento grave\",\nAacute:\"Letra A latina maiúscula con acento agudo\",Acirc:\"Letra A latina maiúscula con acento circunflexo\",Atilde:\"Letra A latina maiúscula con til\",Auml:\"Letra A latina maiúscula con diérese\",Aring:\"Letra A latina maiúscula con aro enriba\",AElig:\"Letra Æ latina maiúscula\",Ccedil:\"Letra C latina maiúscula con cedilla\",Egrave:\"Letra E latina maiúscula con acento grave\",Eacute:\"Letra E latina maiúscula con acento agudo\",Ecirc:\"Letra E latina maiúscula con acento circunflexo\",Euml:\"Letra E latina maiúscula con diérese\",\nIgrave:\"Letra I latina maiúscula con acento grave\",Iacute:\"Letra I latina maiúscula con acento agudo\",Icirc:\"Letra I latina maiúscula con acento circunflexo\",Iuml:\"Letra I latina maiúscula con diérese\",ETH:\"Letra Ed latina maiúscula\",Ntilde:\"Letra N latina maiúscula con til\",Ograve:\"Letra O latina maiúscula con acento grave\",Oacute:\"Letra O latina maiúscula con acento agudo\",Ocirc:\"Letra O latina maiúscula con acento circunflexo\",Otilde:\"Letra O latina maiúscula con til\",Ouml:\"Letra O latina maiúscula con diérese\",\ntimes:\"Signo de multiplicación\",Oslash:\"Letra O latina maiúscula con barra transversal\",Ugrave:\"Letra U latina maiúscula con acento grave\",Uacute:\"Letra U latina maiúscula con acento agudo\",Ucirc:\"Letra U latina maiúscula con acento circunflexo\",Uuml:\"Letra U latina maiúscula con diérese\",Yacute:\"Letra Y latina maiúscula con acento agudo\",THORN:\"Letra Thorn latina maiúscula\",szlig:\"Letra s latina forte minúscula\",agrave:\"Letra a latina minúscula con acento grave\",aacute:\"Letra a latina minúscula con acento agudo\",\nacirc:\"Letra a latina minúscula con acento circunflexo\",atilde:\"Letra a latina minúscula con til\",auml:\"Letra a latina minúscula con diérese\",aring:\"Letra a latina minúscula con aro enriba\",aelig:\"Letra æ latina minúscula\",ccedil:\"Letra c latina minúscula con cedilla\",egrave:\"Letra e latina minúscula con acento grave\",eacute:\"Letra e latina minúscula con acento agudo\",ecirc:\"Letra e latina minúscula con acento circunflexo\",euml:\"Letra e latina minúscula con diérese\",igrave:\"Letra i latina minúscula con acento grave\",\niacute:\"Letra i latina minúscula con acento agudo\",icirc:\"Letra i latina minúscula con acento circunflexo\",iuml:\"Letra i latina minúscula con diérese\",eth:\"Letra ed latina minúscula\",ntilde:\"Letra n latina minúscula con til\",ograve:\"Letra o latina minúscula con acento grave\",oacute:\"Letra o latina minúscula con acento agudo\",ocirc:\"Letra o latina minúscula con acento circunflexo\",otilde:\"Letra o latina minúscula con til\",ouml:\"Letra o latina minúscula con diérese\",divide:\"Signo de división\",oslash:\"Letra o latina minúscula con barra transversal\",\nugrave:\"Letra u latina minúscula con acento grave\",uacute:\"Letra u latina minúscula con acento agudo\",ucirc:\"Letra u latina minúscula con acento circunflexo\",uuml:\"Letra u latina minúscula con diérese\",yacute:\"Letra y latina minúscula con acento agudo\",thorn:\"Letra Thorn latina minúscula\",yuml:\"Letra y latina minúscula con diérese\",OElig:\"Ligadura OE latina maiúscula\",oelig:\"Ligadura oe latina minúscula\",372:\"Letra W latina maiúscula con acento circunflexo\",374:\"Letra Y latina maiúscula con acento circunflexo\",\n373:\"Letra w latina minúscula con acento circunflexo\",375:\"Letra y latina minúscula con acento circunflexo\",sbquo:\"Comiña simple baixa, de apertura\",8219:\"Comiña simple alta, de peche\",bdquo:\"Comiñas dobres baixas, de apertura\",hellip:\"Elipse, puntos suspensivos\",trade:\"Signo de marca rexistrada\",9658:\"Apuntador negro apuntando á dereita\",bull:\"Viñeta\",rarr:\"Frecha á dereita\",rArr:\"Frecha dobre á dereita\",hArr:\"Frecha dobre da esquerda á dereita\",diams:\"Diamante negro\",asymp:\"Case igual a\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/he.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"he\",{euro:\"יורו\",lsquo:\"סימן ציטוט יחיד שמאלי\",rsquo:\"סימן ציטוט יחיד ימני\",ldquo:\"סימן ציטוט כפול שמאלי\",rdquo:\"סימן ציטוט כפול ימני\",ndash:\"קו מפריד קצר\",mdash:\"קו מפריד ארוך\",iexcl:\"סימן קריאה הפוך\",cent:\"סנט\",pound:\"פאונד\",curren:\"מטבע\",yen:\"ין\",brvbar:\"קו שבור\",sect:\"סימן מקטע\",uml:\"שתי נקודות אופקיות (Diaeresis)\",copy:\"סימן זכויות יוצרים (Copyright)\",ordf:\"סימן אורדינאלי נקבי\",laquo:\"סימן ציטוט זווית כפולה לשמאל\",not:\"סימן שלילה מתמטי\",reg:\"סימן רשום\",\nmacr:\"מקרון (הגיה ארוכה)\",deg:\"מעלות\",sup2:\"2 בכתיב עילי\",sup3:\"3 בכתיב עילי\",acute:\"סימן דגוש (Acute)\",micro:\"מיקרו\",para:\"סימון פסקה\",middot:\"נקודה אמצעית\",cedil:\"סדיליה\",sup1:\"1 בכתיב עילי\",ordm:\"סימן אורדינאלי זכרי\",raquo:\"סימן ציטוט זווית כפולה לימין\",frac14:\"רבע בשבר פשוט\",frac12:\"חצי בשבר פשוט\",frac34:\"שלושה רבעים בשבר פשוט\",iquest:\"סימן שאלה הפוך\",Agrave:\"אות לטינית A עם גרש (Grave)\",Aacute:\"Latin capital letter A with acute accent\",Acirc:\"Latin capital letter A with circumflex\",Atilde:\"Latin capital letter A with tilde\",\nAuml:\"Latin capital letter A with diaeresis\",Aring:\"Latin capital letter A with ring above\",AElig:\"אות לטינית Æ גדולה\",Ccedil:\"Latin capital letter C with cedilla\",Egrave:\"אות לטינית E עם גרש (Grave)\",Eacute:\"Latin capital letter E with acute accent\",Ecirc:\"Latin capital letter E with circumflex\",Euml:\"Latin capital letter E with diaeresis\",Igrave:\"אות לטינית I עם גרש (Grave)\",Iacute:\"Latin capital letter I with acute accent\",Icirc:\"Latin capital letter I with circumflex\",Iuml:\"Latin capital letter I with diaeresis\",\nETH:\"אות לטינית Eth גדולה\",Ntilde:\"Latin capital letter N with tilde\",Ograve:\"אות לטינית O עם גרש (Grave)\",Oacute:\"Latin capital letter O with acute accent\",Ocirc:\"Latin capital letter O with circumflex\",Otilde:\"Latin capital letter O with tilde\",Ouml:\"Latin capital letter O with diaeresis\",times:\"סימן כפל\",Oslash:\"Latin capital letter O with stroke\",Ugrave:\"אות לטינית U עם גרש (Grave)\",Uacute:\"Latin capital letter U with acute accent\",Ucirc:\"Latin capital letter U with circumflex\",Uuml:\"Latin capital letter U with diaeresis\",\nYacute:\"Latin capital letter Y with acute accent\",THORN:\"אות לטינית Thorn גדולה\",szlig:\"אות לטינית s חדה קטנה\",agrave:\"אות לטינית a עם גרש (Grave)\",aacute:\"Latin small letter a with acute accent\",acirc:\"Latin small letter a with circumflex\",atilde:\"Latin small letter a with tilde\",auml:\"Latin small letter a with diaeresis\",aring:\"Latin small letter a with ring above\",aelig:\"אות לטינית æ קטנה\",ccedil:\"Latin small letter c with cedilla\",egrave:\"אות לטינית e עם גרש (Grave)\",eacute:\"Latin small letter e with acute accent\",\necirc:\"Latin small letter e with circumflex\",euml:\"Latin small letter e with diaeresis\",igrave:\"אות לטינית i עם גרש (Grave)\",iacute:\"Latin small letter i with acute accent\",icirc:\"Latin small letter i with circumflex\",iuml:\"Latin small letter i with diaeresis\",eth:\"אות לטינית eth קטנה\",ntilde:\"Latin small letter n with tilde\",ograve:\"אות לטינית o עם גרש (Grave)\",oacute:\"Latin small letter o with acute accent\",ocirc:\"Latin small letter o with circumflex\",otilde:\"Latin small letter o with tilde\",ouml:\"Latin small letter o with diaeresis\",\ndivide:\"סימן חלוקה\",oslash:\"Latin small letter o with stroke\",ugrave:\"אות לטינית u עם גרש (Grave)\",uacute:\"Latin small letter u with acute accent\",ucirc:\"Latin small letter u with circumflex\",uuml:\"Latin small letter u with diaeresis\",yacute:\"Latin small letter y with acute accent\",thorn:\"אות לטינית thorn קטנה\",yuml:\"Latin small letter y with diaeresis\",OElig:\"Latin capital ligature OE\",oelig:\"Latin small ligature oe\",372:\"Latin capital letter W with circumflex\",374:\"Latin capital letter Y with circumflex\",\n373:\"Latin small letter w with circumflex\",375:\"Latin small letter y with circumflex\",sbquo:\"סימן ציטוט נמוך יחיד\",8219:\"סימן ציטוט\",bdquo:\"סימן ציטוט נמוך כפול\",hellip:\"שלוש נקודות\",trade:\"סימן טריידמארק\",9658:\"סמן שחור לצד ימין\",bull:\"תבליט (רשימה)\",rarr:\"חץ לימין\",rArr:\"חץ כפול לימין\",hArr:\"חץ כפול לימין ושמאל\",diams:\"יהלום מלא\",asymp:\"כמעט שווה\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/hr.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"hr\",{euro:\"Euro znak\",lsquo:\"Lijevi jednostruki navodnik\",rsquo:\"Desni jednostruki navodnik\",ldquo:\"Lijevi dvostruki navodnik\",rdquo:\"Desni dvostruki navodnik\",ndash:\"En crtica\",mdash:\"Em crtica\",iexcl:\"Naopaki uskličnik\",cent:\"Cent znak\",pound:\"Funta znak\",curren:\"Znak valute\",yen:\"Yen znak\",brvbar:\"Potrgana prečka\",sect:\"Znak odjeljka\",uml:\"Prijeglasi\",copy:\"Copyright znak\",ordf:\"Feminine ordinal indicator\",laquo:\"Lijevi dvostruki uglati navodnik\",not:\"Not znak\",\nreg:\"Registered znak\",macr:\"Macron\",deg:\"Stupanj znak\",sup2:\"Superscript two\",sup3:\"Superscript three\",acute:\"Acute accent\",micro:\"Mikro znak\",para:\"Pilcrow sign\",middot:\"Srednja točka\",cedil:\"Cedilla\",sup1:\"Superscript one\",ordm:\"Masculine ordinal indicator\",raquo:\"Desni dvostruku uglati navodnik\",frac14:\"Vulgar fraction one quarter\",frac12:\"Vulgar fraction one half\",frac34:\"Vulgar fraction three quarters\",iquest:\"Naopaki upitnik\",Agrave:\"Veliko latinsko slovo A s akcentom\",Aacute:\"Latin capital letter A with acute accent\",\nAcirc:\"Latin capital letter A with circumflex\",Atilde:\"Latin capital letter A with tilde\",Auml:\"Latin capital letter A with diaeresis\",Aring:\"Latin capital letter A with ring above\",AElig:\"Latin Capital letter Æ\",Ccedil:\"Latin capital letter C with cedilla\",Egrave:\"Latin capital letter E with grave accent\",Eacute:\"Latin capital letter E with acute accent\",Ecirc:\"Latin capital letter E with circumflex\",Euml:\"Latin capital letter E with diaeresis\",Igrave:\"Latin capital letter I with grave accent\",Iacute:\"Latin capital letter I with acute accent\",\nIcirc:\"Latin capital letter I with circumflex\",Iuml:\"Latin capital letter I with diaeresis\",ETH:\"Latin capital letter Eth\",Ntilde:\"Latin capital letter N with tilde\",Ograve:\"Latin capital letter O with grave accent\",Oacute:\"Latin capital letter O with acute accent\",Ocirc:\"Latin capital letter O with circumflex\",Otilde:\"Latin capital letter O with tilde\",Ouml:\"Latin capital letter O with diaeresis\",times:\"Multiplication sign\",Oslash:\"Latin capital letter O with stroke\",Ugrave:\"Latin capital letter U with grave accent\",\nUacute:\"Latin capital letter U with acute accent\",Ucirc:\"Latin capital letter U with circumflex\",Uuml:\"Latin capital letter U with diaeresis\",Yacute:\"Latin capital letter Y with acute accent\",THORN:\"Latin capital letter Thorn\",szlig:\"Latin small letter sharp s\",agrave:\"Latin small letter a with grave accent\",aacute:\"Latin small letter a with acute accent\",acirc:\"Latin small letter a with circumflex\",atilde:\"Latin small letter a with tilde\",auml:\"Latin small letter a with diaeresis\",aring:\"Latin small letter a with ring above\",\naelig:\"Latin small letter æ\",ccedil:\"Latin small letter c with cedilla\",egrave:\"Latin small letter e with grave accent\",eacute:\"Latin small letter e with acute accent\",ecirc:\"Latin small letter e with circumflex\",euml:\"Latin small letter e with diaeresis\",igrave:\"Latin small letter i with grave accent\",iacute:\"Latin small letter i with acute accent\",icirc:\"Latin small letter i with circumflex\",iuml:\"Latin small letter i with diaeresis\",eth:\"Latin small letter eth\",ntilde:\"Latin small letter n with tilde\",\nograve:\"Latin small letter o with grave accent\",oacute:\"Latin small letter o with acute accent\",ocirc:\"Latin small letter o with circumflex\",otilde:\"Latin small letter o with tilde\",ouml:\"Latin small letter o with diaeresis\",divide:\"Division sign\",oslash:\"Latin small letter o with stroke\",ugrave:\"Latin small letter u with grave accent\",uacute:\"Latin small letter u with acute accent\",ucirc:\"Latin small letter u with circumflex\",uuml:\"Latin small letter u with diaeresis\",yacute:\"Latin small letter y with acute accent\",\nthorn:\"Latin small letter thorn\",yuml:\"Latin small letter y with diaeresis\",OElig:\"Latin capital ligature OE\",oelig:\"Latin small ligature oe\",372:\"Latin capital letter W with circumflex\",374:\"Latin capital letter Y with circumflex\",373:\"Latin small letter w with circumflex\",375:\"Latin small letter y with circumflex\",sbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",hellip:\"Horizontal ellipsis\",trade:\"Trade mark sign\",9658:\"Black right-pointing pointer\",\nbull:\"Bullet\",rarr:\"Rightwards arrow\",rArr:\"Rightwards double arrow\",hArr:\"Left right double arrow\",diams:\"Black diamond suit\",asymp:\"Almost equal to\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/hu.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"hu\",{euro:\"Euró jel\",lsquo:\"Bal szimpla idézőjel\",rsquo:\"Jobb szimpla idézőjel\",ldquo:\"Bal dupla idézőjel\",rdquo:\"Jobb dupla idézőjel\",ndash:\"Rövid gondolatjel\",mdash:\"Hosszú gondolatjel\",iexcl:\"Fordított felkiáltójel\",cent:\"Cent jel\",pound:\"Font jel\",curren:\"Valuta jel\",yen:\"Yen jel\",brvbar:\"Hosszú kettőspont\",sect:\"Paragrafus jel\",uml:\"Kettős hangzó jel\",copy:\"Szerzői jog jel\",ordf:\"Női sorrend mutatója\",laquo:\"Balra mutató duplanyíl\",not:\"Feltételes kötőjel\",\nreg:\"Bejegyzett védjegy jele\",macr:\"Hosszúsági jel\",deg:\"Fok jel\",sup2:\"Négyzeten jel\",sup3:\"Köbön jel\",acute:\"Éles ékezet\",micro:\"Mikro-jel\",para:\"Bekezdés jel\",middot:\"Közép pont\",cedil:\"Cédille\",sup1:\"Elsőn jel\",ordm:\"Férfi sorrend mutatója\",raquo:\"Jobbra mutató duplanyíl\",frac14:\"Egy negyed jel\",frac12:\"Egy ketted jel\",frac34:\"Három negyed jel\",iquest:\"Fordított kérdőjel\",Agrave:\"Latin nagy A fordított ékezettel\",Aacute:\"Latin nagy A normál ékezettel\",Acirc:\"Latin nagy A hajtott ékezettel\",Atilde:\"Latin nagy A hullámjellel\",\nAuml:\"Latin nagy A kettőspont ékezettel\",Aring:\"Latin nagy A gyűrű ékezettel\",AElig:\"Latin nagy Æ betű\",Ccedil:\"Latin nagy C cedillával\",Egrave:\"Latin nagy E fordított ékezettel\",Eacute:\"Latin nagy E normál ékezettel\",Ecirc:\"Latin nagy E hajtott ékezettel\",Euml:\"Latin nagy E dupla kettőspont ékezettel\",Igrave:\"Latin nagy I fordított ékezettel\",Iacute:\"Latin nagy I normál ékezettel\",Icirc:\"Latin nagy I hajtott ékezettel\",Iuml:\"Latin nagy I kettőspont ékezettel\",ETH:\"Latin nagy Eth betű\",Ntilde:\"Latin nagy N hullámjellel\",\nOgrave:\"Latin nagy O fordított ékezettel\",Oacute:\"Latin nagy O normál ékezettel\",Ocirc:\"Latin nagy O hajtott ékezettel\",Otilde:\"Latin nagy O hullámjellel\",Ouml:\"Latin nagy O kettőspont ékezettel\",times:\"Szorzás jel\",Oslash:\"Latin O betű áthúzással\",Ugrave:\"Latin nagy U fordított ékezettel\",Uacute:\"Latin nagy U normál ékezettel\",Ucirc:\"Latin nagy U hajtott ékezettel\",Uuml:\"Latin nagy U kettőspont ékezettel\",Yacute:\"Latin nagy Y normál ékezettel\",THORN:\"Latin nagy Thorn betű\",szlig:\"Latin kis s betű\",\nagrave:\"Latin kis a fordított ékezettel\",aacute:\"Latin kis a normál ékezettel\",acirc:\"Latin kis a hajtott ékezettel\",atilde:\"Latin kis a hullámjellel\",auml:\"Latin kis a kettőspont ékezettel\",aring:\"Latin kis a gyűrű ékezettel\",aelig:\"Latin kis æ betű\",ccedil:\"Latin kis c cedillával\",egrave:\"Latin kis e fordított ékezettel\",eacute:\"Latin kis e normál ékezettel\",ecirc:\"Latin kis e hajtott ékezettel\",euml:\"Latin kis e dupla kettőspont ékezettel\",igrave:\"Latin kis i fordított ékezettel\",iacute:\"Latin kis i normál ékezettel\",\nicirc:\"Latin kis i hajtott ékezettel\",iuml:\"Latin kis i kettőspont ékezettel\",eth:\"Latin kis eth betű\",ntilde:\"Latin kis n hullámjellel\",ograve:\"Latin kis o fordított ékezettel\",oacute:\"Latin kis o normál ékezettel\",ocirc:\"Latin kis o hajtott ékezettel\",otilde:\"Latin kis o hullámjellel\",ouml:\"Latin kis o kettőspont ékezettel\",divide:\"Osztásjel\",oslash:\"Latin kis o betű áthúzással\",ugrave:\"Latin kis u fordított ékezettel\",uacute:\"Latin kis u normál ékezettel\",ucirc:\"Latin kis u hajtott ékezettel\",\nuuml:\"Latin kis u kettőspont ékezettel\",yacute:\"Latin kis y normál ékezettel\",thorn:\"Latin kis thorn jel\",yuml:\"Latin kis y kettőspont ékezettel\",OElig:\"Latin nagy OE-jel\",oelig:\"Latin kis oe-jel\",372:\"Latin nagy W hajtott ékezettel\",374:\"Latin nagy Y hajtott ékezettel\",373:\"Latin kis w hajtott ékezettel\",375:\"Latin kis y hajtott ékezettel\",sbquo:\"Nyitó nyomdai szimpla idézőjel\",8219:\"Záró nyomdai záró idézőjel\",bdquo:\"Nyitó nyomdai dupla idézőjel\",hellip:\"Három pont\",trade:\"Kereskedelmi védjegy jele\",\n9658:\"Jobbra mutató fekete mutató\",bull:\"Golyó\",rarr:\"Jobbra mutató nyíl\",rArr:\"Jobbra mutató duplanyíl\",hArr:\"Bal-jobb duplanyíl\",diams:\"Fekete gyémánt jel\",asymp:\"Majdnem egyenlő jel\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/id.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"id\",{euro:\"Tanda Euro\",lsquo:\"Left single quotation mark\",rsquo:\"Right single quotation mark\",ldquo:\"Left double quotation mark\",rdquo:\"Right double quotation mark\",ndash:\"En dash\",mdash:\"Em dash\",iexcl:\"Inverted exclamation mark\",cent:\"Cent sign\",pound:\"Pound sign\",curren:\"Currency sign\",yen:\"Tanda Yen\",brvbar:\"Broken bar\",sect:\"Section sign\",uml:\"Diaeresis\",copy:\"Tanda Hak Cipta\",ordf:\"Feminine ordinal indicator\",laquo:\"Left-pointing double angle quotation mark\",\nnot:\"Not sign\",reg:\"Tanda Telah Terdaftar\",macr:\"Macron\",deg:\"Degree sign\",sup2:\"Superscript two\",sup3:\"Superscript three\",acute:\"Acute accent\",micro:\"Micro sign\",para:\"Pilcrow sign\",middot:\"Middle dot\",cedil:\"Cedilla\",sup1:\"Superscript one\",ordm:\"Masculine ordinal indicator\",raquo:\"Right-pointing double angle quotation mark\",frac14:\"Vulgar fraction one quarter\",frac12:\"Vulgar fraction one half\",frac34:\"Vulgar fraction three quarters\",iquest:\"Inverted question mark\",Agrave:\"Latin capital letter A with grave accent\",\nAacute:\"Latin capital letter A with acute accent\",Acirc:\"Latin capital letter A with circumflex\",Atilde:\"Latin capital letter A with tilde\",Auml:\"Latin capital letter A with diaeresis\",Aring:\"Latin capital letter A with ring above\",AElig:\"Latin Capital letter Æ\",Ccedil:\"Latin capital letter C with cedilla\",Egrave:\"Latin capital letter E with grave accent\",Eacute:\"Latin capital letter E with acute accent\",Ecirc:\"Latin capital letter E with circumflex\",Euml:\"Latin capital letter E with diaeresis\",Igrave:\"Latin capital letter I with grave accent\",\nIacute:\"Latin capital letter I with acute accent\",Icirc:\"Latin capital letter I with circumflex\",Iuml:\"Latin capital letter I with diaeresis\",ETH:\"Latin capital letter Eth\",Ntilde:\"Latin capital letter N with tilde\",Ograve:\"Latin capital letter O with grave accent\",Oacute:\"Latin capital letter O with acute accent\",Ocirc:\"Latin capital letter O with circumflex\",Otilde:\"Latin capital letter O with tilde\",Ouml:\"Latin capital letter O with diaeresis\",times:\"Multiplication sign\",Oslash:\"Latin capital letter O with stroke\",\nUgrave:\"Latin capital letter U with grave accent\",Uacute:\"Latin capital letter U with acute accent\",Ucirc:\"Latin capital letter U with circumflex\",Uuml:\"Latin capital letter U with diaeresis\",Yacute:\"Latin capital letter Y with acute accent\",THORN:\"Latin capital letter Thorn\",szlig:\"Latin small letter sharp s\",agrave:\"Latin small letter a with grave accent\",aacute:\"Latin small letter a with acute accent\",acirc:\"Latin small letter a with circumflex\",atilde:\"Latin small letter a with tilde\",auml:\"Latin small letter a with diaeresis\",\naring:\"Latin small letter a with ring above\",aelig:\"Latin small letter æ\",ccedil:\"Latin small letter c with cedilla\",egrave:\"Latin small letter e with grave accent\",eacute:\"Latin small letter e with acute accent\",ecirc:\"Latin small letter e with circumflex\",euml:\"Latin small letter e with diaeresis\",igrave:\"Latin small letter i with grave accent\",iacute:\"Latin small letter i with acute accent\",icirc:\"Latin small letter i with circumflex\",iuml:\"Latin small letter i with diaeresis\",eth:\"Latin small letter eth\",\nntilde:\"Latin small letter n with tilde\",ograve:\"Latin small letter o with grave accent\",oacute:\"Latin small letter o with acute accent\",ocirc:\"Latin small letter o with circumflex\",otilde:\"Latin small letter o with tilde\",ouml:\"Latin small letter o with diaeresis\",divide:\"Division sign\",oslash:\"Latin small letter o with stroke\",ugrave:\"Latin small letter u with grave accent\",uacute:\"Latin small letter u with acute accent\",ucirc:\"Latin small letter u with circumflex\",uuml:\"Latin small letter u with diaeresis\",\nyacute:\"Latin small letter y with acute accent\",thorn:\"Latin small letter thorn\",yuml:\"Latin small letter y with diaeresis\",OElig:\"Latin capital ligature OE\",oelig:\"Latin small ligature oe\",372:\"Latin capital letter W with circumflex\",374:\"Latin capital letter Y with circumflex\",373:\"Latin small letter w with circumflex\",375:\"Latin small letter y with circumflex\",sbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",hellip:\"Horizontal ellipsis\",\ntrade:\"Trade mark sign\",9658:\"Black right-pointing pointer\",bull:\"Bullet\",rarr:\"Rightwards arrow\",rArr:\"Rightwards double arrow\",hArr:\"Left right double arrow\",diams:\"Black diamond suit\",asymp:\"Almost equal to\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/it.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"it\",{euro:\"Simbolo Euro\",lsquo:\"Virgoletta singola sinistra\",rsquo:\"Virgoletta singola destra\",ldquo:\"Virgolette aperte\",rdquo:\"Virgolette chiuse\",ndash:\"Trattino\",mdash:\"Trattino lungo\",iexcl:\"Punto esclavamativo invertito\",cent:\"Simbolo Cent\",pound:\"Simbolo Sterlina\",curren:\"Simbolo Moneta\",yen:\"Simbolo Yen\",brvbar:\"Barra interrotta\",sect:\"Simbolo di sezione\",uml:\"Dieresi\",copy:\"Simbolo Copyright\",ordf:\"Indicatore ordinale femminile\",laquo:\"Virgolette basse aperte\",\nnot:\"Nessun segno\",reg:\"Simbolo Registrato\",macr:\"Macron\",deg:\"Simbolo Grado\",sup2:\"Apice Due\",sup3:\"Apice Tre\",acute:\"Accento acuto\",micro:\"Simbolo Micro\",para:\"Simbolo Paragrafo\",middot:\"Punto centrale\",cedil:\"Cediglia\",sup1:\"Apice Uno\",ordm:\"Indicatore ordinale maschile\",raquo:\"Virgolette basse chiuse\",frac14:\"Frazione volgare un quarto\",frac12:\"Frazione volgare un mezzo\",frac34:\"Frazione volgare tre quarti\",iquest:\"Punto interrogativo invertito\",Agrave:\"Lettera maiuscola latina A con accento grave\",\nAacute:\"Lettera maiuscola latina A con accento acuto\",Acirc:\"Lettera maiuscola latina A con accento circonflesso\",Atilde:\"Lettera maiuscola latina A con tilde\",Auml:\"Lettera maiuscola latina A con dieresi\",Aring:\"Lettera maiuscola latina A con anello sopra\",AElig:\"Lettera maiuscola latina AE\",Ccedil:\"Lettera maiuscola latina C con cediglia\",Egrave:\"Lettera maiuscola latina E con accento grave\",Eacute:\"Lettera maiuscola latina E con accento acuto\",Ecirc:\"Lettera maiuscola latina E con accento circonflesso\",\nEuml:\"Lettera maiuscola latina E con dieresi\",Igrave:\"Lettera maiuscola latina I con accento grave\",Iacute:\"Lettera maiuscola latina I con accento acuto\",Icirc:\"Lettera maiuscola latina I con accento circonflesso\",Iuml:\"Lettera maiuscola latina I con dieresi\",ETH:\"Lettera maiuscola latina Eth\",Ntilde:\"Lettera maiuscola latina N con tilde\",Ograve:\"Lettera maiuscola latina O con accento grave\",Oacute:\"Lettera maiuscola latina O con accento acuto\",Ocirc:\"Lettera maiuscola latina O con accento circonflesso\",\nOtilde:\"Lettera maiuscola latina O con tilde\",Ouml:\"Lettera maiuscola latina O con dieresi\",times:\"Simbolo di moltiplicazione\",Oslash:\"Lettera maiuscola latina O barrata\",Ugrave:\"Lettera maiuscola latina U con accento grave\",Uacute:\"Lettera maiuscola latina U con accento acuto\",Ucirc:\"Lettera maiuscola latina U con accento circonflesso\",Uuml:\"Lettera maiuscola latina U con accento circonflesso\",Yacute:\"Lettera maiuscola latina Y con accento acuto\",THORN:\"Lettera maiuscola latina Thorn\",szlig:\"Lettera latina minuscola doppia S\",\nagrave:\"Lettera minuscola latina a con accento grave\",aacute:\"Lettera minuscola latina a con accento acuto\",acirc:\"Lettera minuscola latina a con accento circonflesso\",atilde:\"Lettera minuscola latina a con tilde\",auml:\"Lettera minuscola latina a con dieresi\",aring:\"Lettera minuscola latina a con anello superiore\",aelig:\"Lettera minuscola latina ae\",ccedil:\"Lettera minuscola latina c con cediglia\",egrave:\"Lettera minuscola latina e con accento grave\",eacute:\"Lettera minuscola latina e con accento acuto\",\necirc:\"Lettera minuscola latina e con accento circonflesso\",euml:\"Lettera minuscola latina e con dieresi\",igrave:\"Lettera minuscola latina i con accento grave\",iacute:\"Lettera minuscola latina i con accento acuto\",icirc:\"Lettera minuscola latina i con accento circonflesso\",iuml:\"Lettera minuscola latina i con dieresi\",eth:\"Lettera minuscola latina eth\",ntilde:\"Lettera minuscola latina n con tilde\",ograve:\"Lettera minuscola latina o con accento grave\",oacute:\"Lettera minuscola latina o con accento acuto\",\nocirc:\"Lettera minuscola latina o con accento circonflesso\",otilde:\"Lettera minuscola latina o con tilde\",ouml:\"Lettera minuscola latina o con dieresi\",divide:\"Simbolo di divisione\",oslash:\"Lettera minuscola latina o barrata\",ugrave:\"Lettera minuscola latina u con accento grave\",uacute:\"Lettera minuscola latina u con accento acuto\",ucirc:\"Lettera minuscola latina u con accento circonflesso\",uuml:\"Lettera minuscola latina u con dieresi\",yacute:\"Lettera minuscola latina y con accento acuto\",thorn:\"Lettera minuscola latina thorn\",\nyuml:\"Lettera minuscola latina y con dieresi\",OElig:\"Legatura maiuscola latina OE\",oelig:\"Legatura minuscola latina oe\",372:\"Lettera maiuscola latina W con accento circonflesso\",374:\"Lettera maiuscola latina Y con accento circonflesso\",373:\"Lettera minuscola latina w con accento circonflesso\",375:\"Lettera minuscola latina y con accento circonflesso\",sbquo:\"Singola virgoletta bassa low-9\",8219:\"Singola virgoletta bassa low-9 inversa\",bdquo:\"Doppia virgoletta bassa low-9\",hellip:\"Ellissi orizzontale\",\ntrade:\"Simbolo TM\",9658:\"Puntatore nero rivolto verso destra\",bull:\"Punto\",rarr:\"Freccia verso destra\",rArr:\"Doppia freccia verso destra\",hArr:\"Doppia freccia sinistra destra\",diams:\"Simbolo nero diamante\",asymp:\"Quasi uguale a\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/ja.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"ja\",{euro:\"ユーロ記号\",lsquo:\"左シングル引用符\",rsquo:\"右シングル引用符\",ldquo:\"左ダブル引用符\",rdquo:\"右ダブル引用符\",ndash:\"半角ダッシュ\",mdash:\"全角ダッシュ\",iexcl:\"逆さ感嘆符\",cent:\"セント記号\",pound:\"ポンド記号\",curren:\"通貨記号\",yen:\"円記号\",brvbar:\"上下に分かれた縦棒\",sect:\"節記号\",uml:\"分音記号(ウムラウト)\",copy:\"著作権表示記号\",ordf:\"女性序数標識\",laquo:\" 始め二重山括弧引用記号\",not:\"論理否定記号\",reg:\"登録商標記号\",macr:\"長音符\",deg:\"度記号\",sup2:\"上つき2, 2乗\",sup3:\"上つき3, 3乗\",acute:\"揚音符\",micro:\"ミクロン記号\",para:\"段落記号\",middot:\"中黒\",cedil:\"セディラ\",sup1:\"上つき1\",ordm:\"男性序数標識\",raquo:\"終わり二重山括弧引用記号\",\nfrac14:\"四分の一\",frac12:\"二分の一\",frac34:\"四分の三\",iquest:\"逆疑問符\",Agrave:\"抑音符つき大文字A\",Aacute:\"揚音符つき大文字A\",Acirc:\"曲折アクセントつき大文字A\",Atilde:\"チルダつき大文字A\",Auml:\"分音記号つき大文字A\",Aring:\"リングつき大文字A\",AElig:\"AとEの合字\",Ccedil:\"セディラつき大文字C\",Egrave:\"抑音符つき大文字E\",Eacute:\"揚音符つき大文字E\",Ecirc:\"曲折アクセントつき大文字E\",Euml:\"分音記号つき大文字E\",Igrave:\"抑音符つき大文字I\",Iacute:\"揚音符つき大文字I\",Icirc:\"曲折アクセントつき大文字I\",Iuml:\"分音記号つき大文字I\",ETH:\"[アイスランド語]大文字ETH\",Ntilde:\"チルダつき大文字N\",Ograve:\"抑音符つき大文字O\",Oacute:\"揚音符つき大文字O\",Ocirc:\"曲折アクセントつき大文字O\",Otilde:\"チルダつき大文字O\",Ouml:\" 分音記号つき大文字O\",\ntimes:\"乗算記号\",Oslash:\"打ち消し線つき大文字O\",Ugrave:\"抑音符つき大文字U\",Uacute:\"揚音符つき大文字U\",Ucirc:\"曲折アクセントつき大文字U\",Uuml:\"分音記号つき大文字U\",Yacute:\"揚音符つき大文字Y\",THORN:\"[アイスランド語]大文字THORN\",szlig:\"ドイツ語エスツェット\",agrave:\"抑音符つき小文字a\",aacute:\"揚音符つき小文字a\",acirc:\"曲折アクセントつき小文字a\",atilde:\"チルダつき小文字a\",auml:\"分音記号つき小文字a\",aring:\"リングつき小文字a\",aelig:\"aとeの合字\",ccedil:\"セディラつき小文字c\",egrave:\"抑音符つき小文字e\",eacute:\"揚音符つき小文字e\",ecirc:\"曲折アクセントつき小文字e\",euml:\"分音記号つき小文字e\",igrave:\"抑音符つき小文字i\",iacute:\"揚音符つき小文字i\",icirc:\"曲折アクセントつき小文字i\",iuml:\"分音記号つき小文字i\",eth:\"アイスランド語小文字eth\",\nntilde:\"チルダつき小文字n\",ograve:\"抑音符つき小文字o\",oacute:\"揚音符つき小文字o\",ocirc:\"曲折アクセントつき小文字o\",otilde:\"チルダつき小文字o\",ouml:\"分音記号つき小文字o\",divide:\"除算記号\",oslash:\"打ち消し線つき小文字o\",ugrave:\"抑音符つき小文字u\",uacute:\"揚音符つき小文字u\",ucirc:\"曲折アクセントつき小文字u\",uuml:\"分音記号つき小文字u\",yacute:\"揚音符つき小文字y\",thorn:\"アイスランド語小文字thorn\",yuml:\"分音記号つき小文字y\",OElig:\"OとEの合字\",oelig:\"oとeの合字\",372:\"曲折アクセントつき大文字W\",374:\"曲折アクセントつき大文字Y\",373:\"曲折アクセントつき小文字w\",375:\"曲折アクセントつき小文字y\",sbquo:\"シングル下引用符\",8219:\"左右逆の左引用符\",bdquo:\"ダブル下引用符\",hellip:\"三点リーダ\",trade:\"商標記号\",9658:\"右黒三角ポインタ\",bull:\"黒丸\",\nrarr:\"右矢印\",rArr:\"右二重矢印\",hArr:\"左右二重矢印\",diams:\"ダイヤ\",asymp:\"漸近\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/km.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"km\",{euro:\"សញ្ញា​អឺរ៉ូ\",lsquo:\"Left single quotation mark\",rsquo:\"Right single quotation mark\",ldquo:\"Left double quotation mark\",rdquo:\"Right double quotation mark\",ndash:\"En dash\",mdash:\"Em dash\",iexcl:\"Inverted exclamation mark\",cent:\"សញ្ញា​សេន\",pound:\"សញ្ញា​ផោន\",curren:\"សញ្ញា​រូបិយបណ្ណ\",yen:\"សញ្ញា​យ៉េន\",brvbar:\"Broken bar\",sect:\"Section sign\",uml:\"Diaeresis\",copy:\"សញ្ញា​រក្សា​សិទ្ធិ\",ordf:\"Feminine ordinal indicator\",laquo:\"Left-pointing double angle quotation mark\",\nnot:\"Not sign\",reg:\"Registered sign\",macr:\"Macron\",deg:\"សញ្ញា​ដឺក្រេ\",sup2:\"Superscript two\",sup3:\"Superscript three\",acute:\"Acute accent\",micro:\"សញ្ញា​មីក្រូ\",para:\"Pilcrow sign\",middot:\"Middle dot\",cedil:\"Cedilla\",sup1:\"Superscript one\",ordm:\"Masculine ordinal indicator\",raquo:\"Right-pointing double angle quotation mark\",frac14:\"Vulgar fraction one quarter\",frac12:\"Vulgar fraction one half\",frac34:\"Vulgar fraction three quarters\",iquest:\"Inverted question mark\",Agrave:\"Latin capital letter A with grave accent\",\nAacute:\"Latin capital letter A with acute accent\",Acirc:\"Latin capital letter A with circumflex\",Atilde:\"Latin capital letter A with tilde\",Auml:\"Latin capital letter A with diaeresis\",Aring:\"Latin capital letter A with ring above\",AElig:\"Latin Capital letter Æ\",Ccedil:\"Latin capital letter C with cedilla\",Egrave:\"Latin capital letter E with grave accent\",Eacute:\"Latin capital letter E with acute accent\",Ecirc:\"Latin capital letter E with circumflex\",Euml:\"Latin capital letter E with diaeresis\",Igrave:\"Latin capital letter I with grave accent\",\nIacute:\"Latin capital letter I with acute accent\",Icirc:\"Latin capital letter I with circumflex\",Iuml:\"Latin capital letter I with diaeresis\",ETH:\"Latin capital letter Eth\",Ntilde:\"Latin capital letter N with tilde\",Ograve:\"Latin capital letter O with grave accent\",Oacute:\"Latin capital letter O with acute accent\",Ocirc:\"Latin capital letter O with circumflex\",Otilde:\"Latin capital letter O with tilde\",Ouml:\"Latin capital letter O with diaeresis\",times:\"Multiplication sign\",Oslash:\"Latin capital letter O with stroke\",\nUgrave:\"Latin capital letter U with grave accent\",Uacute:\"Latin capital letter U with acute accent\",Ucirc:\"Latin capital letter U with circumflex\",Uuml:\"Latin capital letter U with diaeresis\",Yacute:\"Latin capital letter Y with acute accent\",THORN:\"Latin capital letter Thorn\",szlig:\"Latin small letter sharp s\",agrave:\"Latin small letter a with grave accent\",aacute:\"Latin small letter a with acute accent\",acirc:\"Latin small letter a with circumflex\",atilde:\"Latin small letter a with tilde\",auml:\"Latin small letter a with diaeresis\",\naring:\"Latin small letter a with ring above\",aelig:\"Latin small letter æ\",ccedil:\"Latin small letter c with cedilla\",egrave:\"Latin small letter e with grave accent\",eacute:\"Latin small letter e with acute accent\",ecirc:\"Latin small letter e with circumflex\",euml:\"Latin small letter e with diaeresis\",igrave:\"Latin small letter i with grave accent\",iacute:\"Latin small letter i with acute accent\",icirc:\"Latin small letter i with circumflex\",iuml:\"Latin small letter i with diaeresis\",eth:\"Latin small letter eth\",\nntilde:\"Latin small letter n with tilde\",ograve:\"Latin small letter o with grave accent\",oacute:\"Latin small letter o with acute accent\",ocirc:\"Latin small letter o with circumflex\",otilde:\"Latin small letter o with tilde\",ouml:\"Latin small letter o with diaeresis\",divide:\"Division sign\",oslash:\"Latin small letter o with stroke\",ugrave:\"Latin small letter u with grave accent\",uacute:\"Latin small letter u with acute accent\",ucirc:\"Latin small letter u with circumflex\",uuml:\"Latin small letter u with diaeresis\",\nyacute:\"Latin small letter y with acute accent\",thorn:\"Latin small letter thorn\",yuml:\"Latin small letter y with diaeresis\",OElig:\"Latin capital ligature OE\",oelig:\"Latin small ligature oe\",372:\"Latin capital letter W with circumflex\",374:\"Latin capital letter Y with circumflex\",373:\"Latin small letter w with circumflex\",375:\"Latin small letter y with circumflex\",sbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",hellip:\"Horizontal ellipsis\",\ntrade:\"Trade mark sign\",9658:\"Black right-pointing pointer\",bull:\"Bullet\",rarr:\"Rightwards arrow\",rArr:\"Rightwards double arrow\",hArr:\"Left right double arrow\",diams:\"Black diamond suit\",asymp:\"Almost equal to\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/ku.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"ku\",{euro:\"نیشانەی یۆرۆ\",lsquo:\"نیشانەی فاریزەی سەرووژێری تاکی چەپ\",rsquo:\"نیشانەی فاریزەی سەرووژێری تاکی ڕاست\",ldquo:\"نیشانەی فاریزەی سەرووژێری دووهێندەی چه‌پ\",rdquo:\"نیشانەی فاریزەی سەرووژێری دووهێندەی ڕاست\",ndash:\"تەقەڵی کورت\",mdash:\"تەقەڵی درێژ\",iexcl:\"نیشانەی هەڵەوگێڕی سەرسوڕهێنەر\",cent:\"نیشانەی سەنت\",pound:\"نیشانەی پاوەند\",curren:\"نیشانەی دراو\",yen:\"نیشانەی یەنی ژاپۆنی\",brvbar:\"شریتی ئەستوونی پچڕاو\",sect:\"نیشانەی دوو s لەسەریەک\",uml:\"خاڵ\",copy:\"نیشانەی مافی چاپ\",\nordf:\"هێڵ لەسەر پیتی a\",laquo:\"دوو تیری بەدووایەکی چەپ\",not:\"نیشانەی نەخێر\",reg:\"نیشانەی R لەناو بازنەدا\",macr:\"ماکڕۆن\",deg:\"نیشانەی پلە\",sup2:\"سەرنووسی دوو\",sup3:\"سەرنووسی سێ\",acute:\"لاری تیژ\",micro:\"نیشانەی u لق درێژی چەپی خواروو\",para:\"نیشانەی پەڕەگراف\",middot:\"ناوەڕاستی خاڵ\",cedil:\"نیشانەی c ژێر چووکرە\",sup1:\"سەرنووسی یەک\",ordm:\"هێڵ لەژێر پیتی o\",raquo:\"دوو تیری بەدووایەکی ڕاست\",frac14:\"یەک لەسەر چووار\",frac12:\"یەک لەسەر دوو\",frac34:\"سێ لەسەر چووار\",iquest:\"هێمای هەڵەوگێری پرسیار\",Agrave:\"پیتی لاتینی A-ی گەورە لەگەڵ ڕوومەتداری لار\",\nAacute:\"پیتی لاتینی A-ی گەورە لەگەڵ ڕوومەتداری تیژ\",Acirc:\"پیتی لاتینی A-ی گەورە لەگەڵ نیشانە لەسەری\",Atilde:\"پیتی لاتینی A-ی گەورە لەگەڵ زەڕە\",Auml:\"پیتی لاتینی A-ی گەورە لەگەڵ نیشانە لەسەری\",Aring:\"پیتی لاتینی گەورەی Å\",AElig:\"پیتی لاتینی گەورەی Æ\",Ccedil:\"پیتی لاتینی C-ی گەورە لەگەڵ ژێر چووکرە\",Egrave:\"پیتی لاتینی E-ی گەورە لەگەڵ ڕوومەتداری لار\",Eacute:\"پیتی لاتینی E-ی گەورە لەگەڵ ڕوومەتداری تیژ\",Ecirc:\"پیتی لاتینی E-ی گەورە لەگەڵ نیشانە لەسەری\",Euml:\"پیتی لاتینی E-ی گەورە لەگەڵ نیشانە لەسەری\",\nIgrave:\"پیتی لاتینی I-ی گەورە لەگەڵ ڕوومەتداری لار\",Iacute:\"پیتی لاتینی I-ی گەورە لەگەڵ ڕوومەتداری تیژ\",Icirc:\"پیتی لاتینی I-ی گەورە لەگەڵ نیشانە لەسەری\",Iuml:\"پیتی لاتینی I-ی گەورە لەگەڵ نیشانە لەسەری\",ETH:\"پیتی لاتینی E-ی گەورەی\",Ntilde:\"پیتی لاتینی N-ی گەورە لەگەڵ زەڕە\",Ograve:\"پیتی لاتینی O-ی گەورە لەگەڵ ڕوومەتداری لار\",Oacute:\"پیتی لاتینی O-ی گەورە لەگەڵ ڕوومەتداری تیژ\",Ocirc:\"پیتی لاتینی O-ی گەورە لەگەڵ نیشانە لەسەری\",Otilde:\"پیتی لاتینی O-ی گەورە لەگەڵ زەڕە\",Ouml:\"پیتی لاتینی O-ی گەورە لەگەڵ نیشانە لەسەری\",\ntimes:\"نیشانەی لێکدان\",Oslash:\"پیتی لاتینی گەورەی Ø لەگەڵ هێمای دڵ وەستان\",Ugrave:\"پیتی لاتینی U-ی گەورە لەگەڵ ڕوومەتداری لار\",Uacute:\"پیتی لاتینی U-ی گەورە لەگەڵ ڕوومەتداری تیژ\",Ucirc:\"پیتی لاتینی U-ی گەورە لەگەڵ نیشانە لەسەری\",Uuml:\"پیتی لاتینی U-ی گەورە لەگەڵ نیشانە لەسەری\",Yacute:\"پیتی لاتینی Y-ی گەورە لەگەڵ ڕوومەتداری تیژ\",THORN:\"پیتی لاتینی دڕکی گەورە\",szlig:\"پیتی لاتنی نووک تیژی s\",agrave:\"پیتی لاتینی a-ی بچووک لەگەڵ ڕوومەتداری لار\",aacute:\"پیتی لاتینی a-ی بچووك لەگەڵ ڕوومەتداری تیژ\",acirc:\"پیتی لاتینی a-ی بچووك لەگەڵ نیشانە لەسەری\",\natilde:\"پیتی لاتینی a-ی بچووك لەگەڵ زەڕە\",auml:\"پیتی لاتینی a-ی بچووك لەگەڵ نیشانە لەسەری\",aring:\"پیتی لاتینی å-ی بچووك\",aelig:\"پیتی لاتینی æ-ی بچووك\",ccedil:\"پیتی لاتینی c-ی بچووك لەگەڵ ژێر چووکرە\",egrave:\"پیتی لاتینی e-ی بچووك لەگەڵ ڕوومەتداری لار\",eacute:\"پیتی لاتینی e-ی بچووك لەگەڵ ڕوومەتداری تیژ\",ecirc:\"پیتی لاتینی e-ی بچووك لەگەڵ نیشانە لەسەری\",euml:\"پیتی لاتینی e-ی بچووك لەگەڵ نیشانە لەسەری\",igrave:\"پیتی لاتینی i-ی بچووك لەگەڵ ڕوومەتداری لار\",iacute:\"پیتی لاتینی i-ی بچووك لەگەڵ ڕوومەتداری تیژ\",\nicirc:\"پیتی لاتینی i-ی بچووك لەگەڵ نیشانە لەسەری\",iuml:\"پیتی لاتینی i-ی بچووك لەگەڵ نیشانە لەسەری\",eth:\"پیتی لاتینی e-ی بچووك\",ntilde:\"پیتی لاتینی n-ی بچووك لەگەڵ زەڕە\",ograve:\"پیتی لاتینی o-ی بچووك لەگەڵ ڕوومەتداری لار\",oacute:\"پیتی لاتینی o-ی بچووك له‌گەڵ ڕوومەتداری تیژ\",ocirc:\"پیتی لاتینی o-ی بچووك لەگەڵ نیشانە لەسەری\",otilde:\"پیتی لاتینی o-ی بچووك لەگەڵ زەڕە\",ouml:\"پیتی لاتینی o-ی بچووك لەگەڵ نیشانە لەسەری\",divide:\"نیشانەی دابەش\",oslash:\"پیتی لاتینی گەورەی ø لەگەڵ هێمای دڵ وەستان\",ugrave:\"پیتی لاتینی u-ی بچووك لەگەڵ ڕوومەتداری لار\",\nuacute:\"پیتی لاتینی u-ی بچووك لەگەڵ ڕوومەتداری تیژ\",ucirc:\"پیتی لاتینی u-ی بچووك لەگەڵ نیشانە لەسەری\",uuml:\"پیتی لاتینی u-ی بچووك لەگەڵ نیشانە لەسەری\",yacute:\"پیتی لاتینی y-ی بچووك لەگەڵ ڕوومەتداری تیژ\",thorn:\"پیتی لاتینی دڕکی بچووك\",yuml:\"پیتی لاتینی y-ی بچووك لەگەڵ نیشانە لەسەری\",OElig:\"پیتی لاتینی گەورەی پێکەوەنووسراوی OE\",oelig:\"پیتی لاتینی بچووکی پێکەوەنووسراوی oe\",372:\"پیتی لاتینی W-ی گەورە لەگەڵ نیشانە لەسەری\",374:\"پیتی لاتینی Y-ی گەورە لەگەڵ نیشانە لەسەری\",373:\"پیتی لاتینی w-ی بچووکی لەگەڵ نیشانە لەسەری\",\n375:\"پیتی لاتینی y-ی بچووکی لەگەڵ نیشانە لەسەری\",sbquo:\"نیشانەی فاریزەی نزم\",8219:\"نیشانەی فاریزەی بەرزی پێچەوانە\",bdquo:\"دوو فاریزەی تەنیش یەك\",hellip:\"ئاسۆیی بازنە\",trade:\"نیشانەی بازرگانی\",9658:\"ئاراستەی ڕەشی دەستی ڕاست\",bull:\"فیشەك\",rarr:\"تیری دەستی ڕاست\",rArr:\"دووتیری دەستی ڕاست\",hArr:\"دوو تیری ڕاست و چەپ\",diams:\"ڕەشی پاقڵاوەیی\",asymp:\"نیشانەی یەکسانە\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/lv.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"lv\",{euro:\"Euro zīme\",lsquo:\"Kreisā  vienkārtīga pēdiņa\",rsquo:\"Labā  vienkārtīga pēdiņa\",ldquo:\"Kreisā  dubult pēdiņa\",rdquo:\"Labā dubult pēdiņa\",ndash:\"En svītra\",mdash:\"Em svītra\",iexcl:\"Apgriezta izsaukuma zīme\",cent:\"Centu naudas zīme\",pound:\"Sterliņu mārciņu naudas zīme\",curren:\"Valūtas zīme\",yen:\"Jenu naudas zīme\",brvbar:\"Vertikāla pārrauta līnija\",sect:\"Paragrāfa zīme\",uml:\"Diakritiska zīme\",copy:\"Autortiesību zīme\",ordf:\"Sievišķas kārtas rādītājs\",\nlaquo:\"Kreisā dubult stūra pēdiņu zīme\",not:\"Neparakstīts\",reg:\"Reģistrēta zīme\",macr:\"Garumzīme\",deg:\"Grādu zīme\",sup2:\"Augšraksts divi\",sup3:\"Augšraksts trīs\",acute:\"Akūta uzsvara zīme\",micro:\"Mikro zīme\",para:\"Rindkopas zīme \",middot:\"Vidējs punkts\",cedil:\"Āķītis zem burta\",sup1:\"Augšraksts viens\",ordm:\"Vīrišķīgas kārtas rādītājs\",raquo:\"Labā dubult stūra pēdiņu zīme\",frac14:\"Vulgāra frakcija 1/4\",frac12:\"Vulgāra frakcija 1/2\",frac34:\"Vulgāra frakcija 3/4\",iquest:\"Apgriezta jautājuma zīme\",Agrave:\"Lielais latīņu burts A ar uzsvara zīmi\",\nAacute:\"Lielais  latīņu burts A ar akūtu uzsvara zīmi\",Acirc:\"Lielais latīņu burts A ar diakritisku zīmi\",Atilde:\"Lielais latīņu burts A ar tildi \",Auml:\"Lielais latīņu burts A ar diakritisko zīmi\",Aring:\"Lielais latīņu burts A ar aplīti augšā\",AElig:\"Lielais latīņu burts Æ\",Ccedil:\"Lielais latīņu burts C ar āķīti zem burta\",Egrave:\"Lielais latīņu burts E ar apostrofu\",Eacute:\"Lielais latīņu burts E ar akūtu uzsvara zīmi\",Ecirc:\"Lielais latīņu burts E ar diakritisko zīmi\",Euml:\"Lielais latīņu burts E ar diakritisko zīmi\",\nIgrave:\"Lielais latīņu burts I ar uzsvaras  zīmi\",Iacute:\"Lielais latīņu burts I ar akūtu uzsvara zīmi\",Icirc:\"Lielais latīņu burts I ar diakritisko zīmi\",Iuml:\"Lielais latīņu burts I ar diakritisko zīmi\",ETH:\"Lielais latīņu burts Eth\",Ntilde:\"Lielais latīņu burts N ar tildi\",Ograve:\"Lielais latīņu burts O ar uzsvara zīmi\",Oacute:\"Lielais latīņu burts O ar akūto uzsvara zīmi\",Ocirc:\"Lielais latīņu burts O ar diakritisko zīmi\",Otilde:\"Lielais latīņu burts O ar tildi\",Ouml:\"Lielais latīņu burts O ar diakritisko zīmi\",\ntimes:\"Reizināšanas zīme \",Oslash:\"Lielais latīņu burts O ar iesvītrojumu\",Ugrave:\"Lielais latīņu burts U ar uzsvaras zīmi\",Uacute:\"Lielais latīņu burts U ar akūto uzsvars zīmi\",Ucirc:\"Lielais latīņu burts U ar diakritisko zīmi\",Uuml:\"Lielais latīņu burts U ar diakritisko zīmi\",Yacute:\"Lielais latīņu burts Y ar akūto uzsvaras zīmi\",THORN:\"Lielais latīņu burts torn\",szlig:\"Mazs latīņu burts ar ligatūru\",agrave:\"Mazs latīņu burts a ar uzsvara zīmi\",aacute:\"Mazs latīņu burts a ar akūto uzsvara zīmi\",\nacirc:\"Mazs latīņu burts a ar diakritisko zīmi\",atilde:\"Mazs latīņu burts a ar tildi\",auml:\"Mazs latīņu burts a ar diakritisko zīmi\",aring:\"Mazs latīņu burts a ar aplīti augšā\",aelig:\"Mazs latīņu burts æ\",ccedil:\"Mazs latīņu burts c ar āķīti zem burta\",egrave:\"Mazs latīņu burts e ar uzsvara zīmi \",eacute:\"Mazs latīņu burts e ar akūtu uzsvara zīmi\",ecirc:\"Mazs latīņu burts e ar diakritisko zīmi\",euml:\"Mazs latīņu burts e ar diakritisko zīmi\",igrave:\"Mazs latīņu burts i ar uzsvara zīmi \",iacute:\"Mazs latīņu burts i ar akūtu uzsvara zīmi\",\nicirc:\"Mazs latīņu burts i ar diakritisko zīmi\",iuml:\"Mazs latīņu burts i ar diakritisko zīmi\",eth:\"Mazs latīņu burts eth\",ntilde:\"Mazs latīņu burts n ar tildi\",ograve:\"Mazs latīņu burts o ar uzsvara zīmi \",oacute:\"Mazs latīņu burts o ar akūtu uzsvara zīmi\",ocirc:\"Mazs latīņu burts o ar diakritisko zīmi\",otilde:\"Mazs latīņu burts o ar tildi\",ouml:\"Mazs latīņu burts o ar diakritisko zīmi\",divide:\"Dalīšanas zīme\",oslash:\"Mazs latīņu burts o ar iesvītrojumu\",ugrave:\"Mazs latīņu burts u ar uzsvara zīmi \",\nuacute:\"Mazs latīņu burts u ar  akūtu uzsvara zīmi\",ucirc:\"Mazs latīņu burts u ar diakritisko zīmi\",uuml:\"Mazs latīņu burts u ar diakritisko zīmi\",yacute:\"Mazs latīņu burts y ar  akūtu uzsvaras zīmi\",thorn:\"Mazs latīņu burts torns\",yuml:\"Mazs latīņu burts y ar diakritisko zīmi\",OElig:\"Liela latīņu ligatūra OE\",oelig:\"Maza latīņu ligatūra oe\",372:\"Liels latīņu burts W ar diakritisko zīmi \",374:\"Liels latīņu burts Y ar diakritisko zīmi \",373:\"Mazs latīņu burts w ar diakritisko zīmi \",375:\"Mazs latīņu burts y ar diakritisko zīmi \",\nsbquo:\"Mazas-9 vienkārtīgas pēdiņas\",8219:\"Lielas-9 vienkārtīgas apgrieztas pēdiņas\",bdquo:\"Mazas-9 dubultas pēdiņas\",hellip:\"Horizontāli daudzpunkti\",trade:\"Preču zīmes zīme\",9658:\"Melns pa labi pagriezts radītājs\",bull:\"Lode\",rarr:\"Bulta pa labi\",rArr:\"Dubulta Bulta pa labi\",hArr:\"Bulta pa kreisi\",diams:\"Dubulta Bulta pa kreisi\",asymp:\"Gandrīz vienāds ar\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/nb.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"nb\",{euro:\"Eurosymbol\",lsquo:\"Venstre enkelt anførselstegn\",rsquo:\"Høyre enkelt anførselstegn\",ldquo:\"Venstre dobbelt anførselstegn\",rdquo:\"Høyre anførsesltegn\",ndash:\"Kort tankestrek\",mdash:\"Lang tankestrek\",iexcl:\"Omvendt utropstegn\",cent:\"Centsymbol\",pound:\"Pundsymbol\",curren:\"Valutategn\",yen:\"Yensymbol\",brvbar:\"Brutt loddrett strek\",sect:\"Paragraftegn\",uml:\"Tøddel\",copy:\"Copyrighttegn\",ordf:\"Feminin ordensindikator\",laquo:\"Venstre anførselstegn\",not:\"Negasjonstegn\",\nreg:\"Registrert varemerke-tegn\",macr:\"Makron\",deg:\"Gradsymbol\",sup2:\"Hevet totall\",sup3:\"Hevet tretall\",acute:\"Akutt aksent\",micro:\"Mikrosymbol\",para:\"Avsnittstegn\",middot:\"Midtstilt prikk\",cedil:\"Cedille\",sup1:\"Hevet ettall\",ordm:\"Maskulin ordensindikator\",raquo:\"Høyre anførselstegn\",frac14:\"Fjerdedelsbrøk\",frac12:\"Halvbrøk\",frac34:\"Tre fjerdedelers brøk\",iquest:\"Omvendt spørsmålstegn\",Agrave:\"Stor A med grav aksent\",Aacute:\"Stor A med akutt aksent\",Acirc:\"Stor A med cirkumfleks\",Atilde:\"Stor A med tilde\",\nAuml:\"Stor A med tøddel\",Aring:\"Stor Å\",AElig:\"Stor Æ\",Ccedil:\"Stor C med cedille\",Egrave:\"Stor E med grav aksent\",Eacute:\"Stor E med akutt aksent\",Ecirc:\"Stor E med cirkumfleks\",Euml:\"Stor E med tøddel\",Igrave:\"Stor I med grav aksent\",Iacute:\"Stor I med akutt aksent\",Icirc:\"Stor I med cirkumfleks\",Iuml:\"Stor I med tøddel\",ETH:\"Stor Edd/stungen D\",Ntilde:\"Stor N med tilde\",Ograve:\"Stor O med grav aksent\",Oacute:\"Stor O med akutt aksent\",Ocirc:\"Stor O med cirkumfleks\",Otilde:\"Stor O med tilde\",Ouml:\"Stor O med tøddel\",\ntimes:\"Multiplikasjonstegn\",Oslash:\"Stor Ø\",Ugrave:\"Stor U med grav aksent\",Uacute:\"Stor U med akutt aksent\",Ucirc:\"Stor U med cirkumfleks\",Uuml:\"Stor U med tøddel\",Yacute:\"Stor Y med akutt aksent\",THORN:\"Stor Thorn\",szlig:\"Liten dobbelt-s/Eszett\",agrave:\"Liten a med grav aksent\",aacute:\"Liten a med akutt aksent\",acirc:\"Liten a med cirkumfleks\",atilde:\"Liten a med tilde\",auml:\"Liten a med tøddel\",aring:\"Liten å\",aelig:\"Liten æ\",ccedil:\"Liten c med cedille\",egrave:\"Liten e med grav aksent\",eacute:\"Liten e med akutt aksent\",\necirc:\"Liten e med cirkumfleks\",euml:\"Liten e med tøddel\",igrave:\"Liten i med grav aksent\",iacute:\"Liten i med akutt aksent\",icirc:\"Liten i med cirkumfleks\",iuml:\"Liten i med tøddel\",eth:\"Liten edd/stungen d\",ntilde:\"Liten n med tilde\",ograve:\"Liten o med grav aksent\",oacute:\"Liten o med akutt aksent\",ocirc:\"Liten o med cirkumfleks\",otilde:\"Liten o med tilde\",ouml:\"Liten o med tøddel\",divide:\"Divisjonstegn\",oslash:\"Liten ø\",ugrave:\"Liten u med grav aksent\",uacute:\"Liten u med akutt aksent\",ucirc:\"Liten u med cirkumfleks\",\nuuml:\"Liten u med tøddel\",yacute:\"Liten y med akutt aksent\",thorn:\"Liten thorn\",yuml:\"Liten y med tøddel\",OElig:\"Stor ligatur av O og E\",oelig:\"Liten ligatur av o og e\",372:\"Stor W med cirkumfleks\",374:\"Stor Y med cirkumfleks\",373:\"Liten w med cirkumfleks\",375:\"Liten y med cirkumfleks\",sbquo:\"Enkelt lavt 9-anførselstegn\",8219:\"Enkelt høyt reversert 9-anførselstegn\",bdquo:\"Dobbelt lavt 9-anførselstegn\",hellip:\"Ellipse\",trade:\"Varemerkesymbol\",9658:\"Svart høyrevendt peker\",bull:\"Tykk interpunkt\",rarr:\"Høyrevendt pil\",\nrArr:\"Dobbel høyrevendt pil\",hArr:\"Dobbel venstrevendt pil\",diams:\"Svart ruter\",asymp:\"Omtrent likhetstegn\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/nl.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"nl\",{euro:\"Euro-teken\",lsquo:\"Linker enkel aanhalingsteken\",rsquo:\"Rechter enkel aanhalingsteken\",ldquo:\"Linker dubbel aanhalingsteken\",rdquo:\"Rechter dubbel aanhalingsteken\",ndash:\"En dash\",mdash:\"Em dash\",iexcl:\"Omgekeerd uitroepteken\",cent:\"Cent-teken\",pound:\"Pond-teken\",curren:\"Valuta-teken\",yen:\"Yen-teken\",brvbar:\"Gebroken streep\",sect:\"Paragraaf-teken\",uml:\"Trema\",copy:\"Copyright-teken\",ordf:\"Vrouwelijk ordinaal\",laquo:\"Linker guillemet\",not:\"Ongelijk-teken\",\nreg:\"Geregistreerd handelsmerk-teken\",macr:\"Macron\",deg:\"Graden-teken\",sup2:\"Superscript twee\",sup3:\"Superscript drie\",acute:\"Accent aigu\",micro:\"Micro-teken\",para:\"Alinea-teken\",middot:\"Halfhoge punt\",cedil:\"Cedille\",sup1:\"Superscript een\",ordm:\"Mannelijk ordinaal\",raquo:\"Rechter guillemet\",frac14:\"Breuk kwart\",frac12:\"Breuk half\",frac34:\"Breuk driekwart\",iquest:\"Omgekeerd vraagteken\",Agrave:\"Latijnse hoofdletter A met een accent grave\",Aacute:\"Latijnse hoofdletter A met een accent aigu\",Acirc:\"Latijnse hoofdletter A met een circonflexe\",\nAtilde:\"Latijnse hoofdletter A met een tilde\",Auml:\"Latijnse hoofdletter A met een trema\",Aring:\"Latijnse hoofdletter A met een corona\",AElig:\"Latijnse hoofdletter Æ\",Ccedil:\"Latijnse hoofdletter C met een cedille\",Egrave:\"Latijnse hoofdletter E met een accent grave\",Eacute:\"Latijnse hoofdletter E met een accent aigu\",Ecirc:\"Latijnse hoofdletter E met een circonflexe\",Euml:\"Latijnse hoofdletter E met een trema\",Igrave:\"Latijnse hoofdletter I met een accent grave\",Iacute:\"Latijnse hoofdletter I met een accent aigu\",\nIcirc:\"Latijnse hoofdletter I met een circonflexe\",Iuml:\"Latijnse hoofdletter I met een trema\",ETH:\"Latijnse hoofdletter Eth\",Ntilde:\"Latijnse hoofdletter N met een tilde\",Ograve:\"Latijnse hoofdletter O met een accent grave\",Oacute:\"Latijnse hoofdletter O met een accent aigu\",Ocirc:\"Latijnse hoofdletter O met een circonflexe\",Otilde:\"Latijnse hoofdletter O met een tilde\",Ouml:\"Latijnse hoofdletter O met een trema\",times:\"Maal-teken\",Oslash:\"Latijnse hoofdletter O met een schuine streep\",Ugrave:\"Latijnse hoofdletter U met een accent grave\",\nUacute:\"Latijnse hoofdletter U met een accent aigu\",Ucirc:\"Latijnse hoofdletter U met een circonflexe\",Uuml:\"Latijnse hoofdletter U met een trema\",Yacute:\"Latijnse hoofdletter Y met een accent aigu\",THORN:\"Latijnse hoofdletter Thorn\",szlig:\"Latijnse kleine ringel-s\",agrave:\"Latijnse kleine letter a met een accent grave\",aacute:\"Latijnse kleine letter a met een accent aigu\",acirc:\"Latijnse kleine letter a met een circonflexe\",atilde:\"Latijnse kleine letter a met een tilde\",auml:\"Latijnse kleine letter a met een trema\",\naring:\"Latijnse kleine letter a met een corona\",aelig:\"Latijnse kleine letter æ\",ccedil:\"Latijnse kleine letter c met een cedille\",egrave:\"Latijnse kleine letter e met een accent grave\",eacute:\"Latijnse kleine letter e met een accent aigu\",ecirc:\"Latijnse kleine letter e met een circonflexe\",euml:\"Latijnse kleine letter e met een trema\",igrave:\"Latijnse kleine letter i met een accent grave\",iacute:\"Latijnse kleine letter i met een accent aigu\",icirc:\"Latijnse kleine letter i met een circonflexe\",\niuml:\"Latijnse kleine letter i met een trema\",eth:\"Latijnse kleine letter eth\",ntilde:\"Latijnse kleine letter n met een tilde\",ograve:\"Latijnse kleine letter o met een accent grave\",oacute:\"Latijnse kleine letter o met een accent aigu\",ocirc:\"Latijnse kleine letter o met een circonflexe\",otilde:\"Latijnse kleine letter o met een tilde\",ouml:\"Latijnse kleine letter o met een trema\",divide:\"Deel-teken\",oslash:\"Latijnse kleine letter o met een schuine streep\",ugrave:\"Latijnse kleine letter u met een accent grave\",\nuacute:\"Latijnse kleine letter u met een accent aigu\",ucirc:\"Latijnse kleine letter u met een circonflexe\",uuml:\"Latijnse kleine letter u met een trema\",yacute:\"Latijnse kleine letter y met een accent aigu\",thorn:\"Latijnse kleine letter thorn\",yuml:\"Latijnse kleine letter y met een trema\",OElig:\"Latijnse hoofdletter Œ\",oelig:\"Latijnse kleine letter œ\",372:\"Latijnse hoofdletter W met een circonflexe\",374:\"Latijnse hoofdletter Y met een circonflexe\",373:\"Latijnse kleine letter w met een circonflexe\",\n375:\"Latijnse kleine letter y met een circonflexe\",sbquo:\"Lage enkele aanhalingsteken\",8219:\"Hoge omgekeerde enkele aanhalingsteken\",bdquo:\"Lage dubbele aanhalingsteken\",hellip:\"Beletselteken\",trade:\"Trademark-teken\",9658:\"Zwarte driehoek naar rechts\",bull:\"Bullet\",rarr:\"Pijl naar rechts\",rArr:\"Dubbele pijl naar rechts\",hArr:\"Dubbele pijl naar links\",diams:\"Zwart ruitje\",asymp:\"Benaderingsteken\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/no.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"no\",{euro:\"Eurosymbol\",lsquo:\"Venstre enkelt anførselstegn\",rsquo:\"Høyre enkelt anførselstegn\",ldquo:\"Venstre dobbelt anførselstegn\",rdquo:\"Høyre anførsesltegn\",ndash:\"Kort tankestrek\",mdash:\"Lang tankestrek\",iexcl:\"Omvendt utropstegn\",cent:\"Centsymbol\",pound:\"Pundsymbol\",curren:\"Valutategn\",yen:\"Yensymbol\",brvbar:\"Brutt loddrett strek\",sect:\"Paragraftegn\",uml:\"Tøddel\",copy:\"Copyrighttegn\",ordf:\"Feminin ordensindikator\",laquo:\"Venstre anførselstegn\",not:\"Negasjonstegn\",\nreg:\"Registrert varemerke-tegn\",macr:\"Makron\",deg:\"Gradsymbol\",sup2:\"Hevet totall\",sup3:\"Hevet tretall\",acute:\"Akutt aksent\",micro:\"Mikrosymbol\",para:\"Avsnittstegn\",middot:\"Midtstilt prikk\",cedil:\"Cedille\",sup1:\"Hevet ettall\",ordm:\"Maskulin ordensindikator\",raquo:\"Høyre anførselstegn\",frac14:\"Fjerdedelsbrøk\",frac12:\"Halvbrøk\",frac34:\"Tre fjerdedelers brøk\",iquest:\"Omvendt spørsmålstegn\",Agrave:\"Stor A med grav aksent\",Aacute:\"Stor A med akutt aksent\",Acirc:\"Stor A med cirkumfleks\",Atilde:\"Stor A med tilde\",\nAuml:\"Stor A med tøddel\",Aring:\"Stor Å\",AElig:\"Stor Æ\",Ccedil:\"Stor C med cedille\",Egrave:\"Stor E med grav aksent\",Eacute:\"Stor E med akutt aksent\",Ecirc:\"Stor E med cirkumfleks\",Euml:\"Stor E med tøddel\",Igrave:\"Stor I med grav aksent\",Iacute:\"Stor I med akutt aksent\",Icirc:\"Stor I med cirkumfleks\",Iuml:\"Stor I med tøddel\",ETH:\"Stor Edd/stungen D\",Ntilde:\"Stor N med tilde\",Ograve:\"Stor O med grav aksent\",Oacute:\"Stor O med akutt aksent\",Ocirc:\"Stor O med cirkumfleks\",Otilde:\"Stor O med tilde\",Ouml:\"Stor O med tøddel\",\ntimes:\"Multiplikasjonstegn\",Oslash:\"Stor Ø\",Ugrave:\"Stor U med grav aksent\",Uacute:\"Stor U med akutt aksent\",Ucirc:\"Stor U med cirkumfleks\",Uuml:\"Stor U med tøddel\",Yacute:\"Stor Y med akutt aksent\",THORN:\"Stor Thorn\",szlig:\"Liten dobbelt-s/Eszett\",agrave:\"Liten a med grav aksent\",aacute:\"Liten a med akutt aksent\",acirc:\"Liten a med cirkumfleks\",atilde:\"Liten a med tilde\",auml:\"Liten a med tøddel\",aring:\"Liten å\",aelig:\"Liten æ\",ccedil:\"Liten c med cedille\",egrave:\"Liten e med grav aksent\",eacute:\"Liten e med akutt aksent\",\necirc:\"Liten e med cirkumfleks\",euml:\"Liten e med tøddel\",igrave:\"Liten i med grav aksent\",iacute:\"Liten i med akutt aksent\",icirc:\"Liten i med cirkumfleks\",iuml:\"Liten i med tøddel\",eth:\"Liten edd/stungen d\",ntilde:\"Liten n med tilde\",ograve:\"Liten o med grav aksent\",oacute:\"Liten o med akutt aksent\",ocirc:\"Liten o med cirkumfleks\",otilde:\"Liten o med tilde\",ouml:\"Liten o med tøddel\",divide:\"Divisjonstegn\",oslash:\"Liten ø\",ugrave:\"Liten u med grav aksent\",uacute:\"Liten u med akutt aksent\",ucirc:\"Liten u med cirkumfleks\",\nuuml:\"Liten u med tøddel\",yacute:\"Liten y med akutt aksent\",thorn:\"Liten thorn\",yuml:\"Liten y med tøddel\",OElig:\"Stor ligatur av O og E\",oelig:\"Liten ligatur av o og e\",372:\"Stor W med cirkumfleks\",374:\"Stor Y med cirkumfleks\",373:\"Liten w med cirkumfleks\",375:\"Liten y med cirkumfleks\",sbquo:\"Enkelt lavt 9-anførselstegn\",8219:\"Enkelt høyt reversert 9-anførselstegn\",bdquo:\"Dobbelt lavt 9-anførselstegn\",hellip:\"Ellipse\",trade:\"Varemerkesymbol\",9658:\"Svart høyrevendt peker\",bull:\"Tykk interpunkt\",rarr:\"Høyrevendt pil\",\nrArr:\"Dobbel høyrevendt pil\",hArr:\"Dobbel venstrevendt pil\",diams:\"Svart ruter\",asymp:\"Omtrent likhetstegn\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/pl.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"pl\",{euro:\"Znak euro\",lsquo:\"Cudzysłów pojedynczy otwierający\",rsquo:\"Cudzysłów pojedynczy zamykający\",ldquo:\"Cudzysłów apostrofowy otwierający\",rdquo:\"Cudzysłów apostrofowy zamykający\",ndash:\"Półpauza\",mdash:\"Pauza\",iexcl:\"Odwrócony wykrzyknik\",cent:\"Znak centa\",pound:\"Znak funta\",curren:\"Znak waluty\",yen:\"Znak jena\",brvbar:\"Przerwana pionowa kreska\",sect:\"Paragraf\",uml:\"Diereza\",copy:\"Znak praw autorskich\",ordf:\"Wskaźnik rodzaju żeńskiego liczebnika porządkowego\",\nlaquo:\"Lewy cudzysłów ostrokątny\",not:\"Znak negacji\",reg:\"Zastrzeżony znak towarowy\",macr:\"Makron\",deg:\"Znak stopnia\",sup2:\"Druga potęga\",sup3:\"Trzecia potęga\",acute:\"Akcent ostry\",micro:\"Znak mikro\",para:\"Znak akapitu\",middot:\"Kropka środkowa\",cedil:\"Cedylla\",sup1:\"Pierwsza potęga\",ordm:\"Wskaźnik rodzaju męskiego liczebnika porządkowego\",raquo:\"Prawy cudzysłów ostrokątny\",frac14:\"Ułamek zwykły jedna czwarta\",frac12:\"Ułamek zwykły jedna druga\",frac34:\"Ułamek zwykły trzy czwarte\",iquest:\"Odwrócony znak zapytania\",\nAgrave:\"Wielka litera A z akcentem ciężkim\",Aacute:\"Wielka litera A z akcentem ostrym\",Acirc:\"Wielka litera A z akcentem przeciągłym\",Atilde:\"Wielka litera A z tyldą\",Auml:\"Wielka litera A z dierezą\",Aring:\"Wielka litera A z kółkiem\",AElig:\"Wielka ligatura Æ\",Ccedil:\"Wielka litera C z cedyllą\",Egrave:\"Wielka litera E z akcentem ciężkim\",Eacute:\"Wielka litera E z akcentem ostrym\",Ecirc:\"Wielka litera E z akcentem przeciągłym\",Euml:\"Wielka litera E z dierezą\",Igrave:\"Wielka litera I z akcentem ciężkim\",\nIacute:\"Wielka litera I z akcentem ostrym\",Icirc:\"Wielka litera I z akcentem przeciągłym\",Iuml:\"Wielka litera I z dierezą\",ETH:\"Wielka litera Eth\",Ntilde:\"Wielka litera N z tyldą\",Ograve:\"Wielka litera O z akcentem ciężkim\",Oacute:\"Wielka litera O z akcentem ostrym\",Ocirc:\"Wielka litera O z akcentem przeciągłym\",Otilde:\"Wielka litera O z tyldą\",Ouml:\"Wielka litera O z dierezą\",times:\"Znak mnożenia wektorowego\",Oslash:\"Wielka litera O z przekreśleniem\",Ugrave:\"Wielka litera U z akcentem ciężkim\",Uacute:\"Wielka litera U z akcentem ostrym\",\nUcirc:\"Wielka litera U z akcentem przeciągłym\",Uuml:\"Wielka litera U z dierezą\",Yacute:\"Wielka litera Y z akcentem ostrym\",THORN:\"Wielka litera Thorn\",szlig:\"Mała litera ostre s (eszet)\",agrave:\"Mała litera a z akcentem ciężkim\",aacute:\"Mała litera a z akcentem ostrym\",acirc:\"Mała litera a z akcentem przeciągłym\",atilde:\"Mała litera a z tyldą\",auml:\"Mała litera a z dierezą\",aring:\"Mała litera a z kółkiem\",aelig:\"Mała ligatura æ\",ccedil:\"Mała litera c z cedyllą\",egrave:\"Mała litera e z akcentem ciężkim\",\neacute:\"Mała litera e z akcentem ostrym\",ecirc:\"Mała litera e z akcentem przeciągłym\",euml:\"Mała litera e z dierezą\",igrave:\"Mała litera i z akcentem ciężkim\",iacute:\"Mała litera i z akcentem ostrym\",icirc:\"Mała litera i z akcentem przeciągłym\",iuml:\"Mała litera i z dierezą\",eth:\"Mała litera eth\",ntilde:\"Mała litera n z tyldą\",ograve:\"Mała litera o z akcentem ciężkim\",oacute:\"Mała litera o z akcentem ostrym\",ocirc:\"Mała litera o z akcentem przeciągłym\",otilde:\"Mała litera o z tyldą\",ouml:\"Mała litera o z dierezą\",\ndivide:\"Anglosaski znak dzielenia\",oslash:\"Mała litera o z przekreśleniem\",ugrave:\"Mała litera u z akcentem ciężkim\",uacute:\"Mała litera u z akcentem ostrym\",ucirc:\"Mała litera u z akcentem przeciągłym\",uuml:\"Mała litera u z dierezą\",yacute:\"Mała litera y z akcentem ostrym\",thorn:\"Mała litera thorn\",yuml:\"Mała litera y z dierezą\",OElig:\"Wielka ligatura OE\",oelig:\"Mała ligatura oe\",372:\"Wielka litera W z akcentem przeciągłym\",374:\"Wielka litera Y z akcentem przeciągłym\",373:\"Mała litera w z akcentem przeciągłym\",\n375:\"Mała litera y z akcentem przeciągłym\",sbquo:\"Pojedynczy apostrof dolny\",8219:\"Pojedynczy apostrof górny\",bdquo:\"Podwójny apostrof dolny\",hellip:\"Wielokropek\",trade:\"Znak towarowy\",9658:\"Czarny wskaźnik wskazujący w prawo\",bull:\"Punktor\",rarr:\"Strzałka w prawo\",rArr:\"Podwójna strzałka w prawo\",hArr:\"Podwójna strzałka w lewo\",diams:\"Czarny znak karo\",asymp:\"Znak prawie równe\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/pt-br.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"pt-br\",{euro:\"Euro\",lsquo:\"Aspas simples esquerda\",rsquo:\"Aspas simples direita\",ldquo:\"Aspas duplas esquerda\",rdquo:\"Aspas duplas direita\",ndash:\"Traço\",mdash:\"Travessão\",iexcl:\"Ponto de exclamação invertido\",cent:\"Cent\",pound:\"Cerquilha\",curren:\"Dinheiro\",yen:\"Yen\",brvbar:\"Bara interrompida\",sect:\"Símbolo de Parágrafo\",uml:\"Trema\",copy:\"Direito de Cópia\",ordf:\"Indicador ordinal feminino\",laquo:\"Aspas duplas angulares esquerda\",not:\"Negação\",reg:\"Marca Registrada\",\nmacr:\"Mácron\",deg:\"Grau\",sup2:\"2 Superscrito\",sup3:\"3 Superscrito\",acute:\"Acento agudo\",micro:\"Micro\",para:\"Pé de mosca\",middot:\"Ponto mediano\",cedil:\"Cedilha\",sup1:\"1 Superscrito\",ordm:\"Indicador ordinal masculino\",raquo:\"Aspas duplas angulares direita\",frac14:\"Um quarto\",frac12:\"Um meio\",frac34:\"Três quartos\",iquest:\"Interrogação invertida\",Agrave:\"A maiúsculo com acento grave\",Aacute:\"A maiúsculo com acento agudo\",Acirc:\"A maiúsculo com acento circunflexo\",Atilde:\"A maiúsculo com til\",Auml:\"A maiúsculo com trema\",\nAring:\"A maiúsculo com anel acima\",AElig:\"Æ maiúsculo\",Ccedil:\"Ç maiúlculo\",Egrave:\"E maiúsculo com acento grave\",Eacute:\"E maiúsculo com acento agudo\",Ecirc:\"E maiúsculo com acento circumflexo\",Euml:\"E maiúsculo com trema\",Igrave:\"I maiúsculo com acento grave\",Iacute:\"I maiúsculo com acento agudo\",Icirc:\"I maiúsculo com acento circunflexo\",Iuml:\"I maiúsculo com crase\",ETH:\"Eth maiúsculo\",Ntilde:\"N maiúsculo com til\",Ograve:\"O maiúsculo com acento grave\",Oacute:\"O maiúsculo com acento agudo\",Ocirc:\"O maiúsculo com acento circunflexo\",\nOtilde:\"O maiúsculo com til\",Ouml:\"O maiúsculo com trema\",times:\"Multiplicação\",Oslash:\"Diâmetro\",Ugrave:\"U maiúsculo com acento grave\",Uacute:\"U maiúsculo com acento agudo\",Ucirc:\"U maiúsculo com acento circunflexo\",Uuml:\"U maiúsculo com trema\",Yacute:\"Y maiúsculo com acento agudo\",THORN:\"Thorn maiúsculo\",szlig:\"Eszett minúsculo\",agrave:\"a minúsculo com acento grave\",aacute:\"a minúsculo com acento agudo\",acirc:\"a minúsculo com acento circunflexo\",atilde:\"a minúsculo com til\",auml:\"a minúsculo com trema\",\naring:\"a minúsculo com anel acima\",aelig:\"æ minúsculo\",ccedil:\"ç minúsculo\",egrave:\"e minúsculo com acento grave\",eacute:\"e minúsculo com acento agudo\",ecirc:\"e minúsculo com acento circunflexo\",euml:\"e minúsculo com trema\",igrave:\"i minúsculo com acento grave\",iacute:\"i minúsculo com acento agudo\",icirc:\"i minúsculo com acento circunflexo\",iuml:\"i minúsculo com trema\",eth:\"eth minúsculo\",ntilde:\"n minúsculo com til\",ograve:\"o minúsculo com acento grave\",oacute:\"o minúsculo com acento agudo\",ocirc:\"o minúsculo com acento circunflexo\",\notilde:\"o minúsculo com til\",ouml:\"o minúsculo com trema\",divide:\"Divisão\",oslash:\"o minúsculo com cortado ou diâmetro\",ugrave:\"u minúsculo com acento grave\",uacute:\"u minúsculo com acento agudo\",ucirc:\"u minúsculo com acento circunflexo\",uuml:\"u minúsculo com trema\",yacute:\"y minúsculo com acento agudo\",thorn:\"thorn minúsculo\",yuml:\"y minúsculo com trema\",OElig:\"Ligação tipográfica OE maiúscula\",oelig:\"Ligação tipográfica oe minúscula\",372:\"W maiúsculo com acento circunflexo\",374:\"Y maiúsculo com acento circunflexo\",\n373:\"w minúsculo com acento circunflexo\",375:\"y minúsculo com acento circunflexo\",sbquo:\"Aspas simples inferior direita\",8219:\"Aspas simples superior esquerda\",bdquo:\"Aspas duplas inferior direita\",hellip:\"Reticências\",trade:\"Trade mark\",9658:\"Ponta de seta preta para direita\",bull:\"Ponto lista\",rarr:\"Seta para direita\",rArr:\"Seta dupla para direita\",hArr:\"Seta dupla direita e esquerda\",diams:\"Ouros\",asymp:\"Aproximadamente\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/pt.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"pt\",{euro:\"Símbolo do Euro\",lsquo:\"Aspa esquerda simples\",rsquo:\"Aspa direita simples\",ldquo:\"Aspa esquerda dupla\",rdquo:\"Aspa direita dupla\",ndash:\"Travessão Simples\",mdash:\"Travessão Longo\",iexcl:\"Ponto de exclamação invertido\",cent:\"Símbolo do Cêntimo\",pound:\"Símbolo da Libra\",curren:\"Símbolo de Moeda\",yen:\"Símbolo do Iene\",brvbar:\"Barra quebrada\",sect:\"Símbolo de Secção\",uml:\"Trema\",copy:\"Símbolo dos Direitos de Autor\",ordf:\"Indicador ordinal feminino\",\nlaquo:\"Aspa esquerda ângulo duplo\",not:\"Não Símbolo\",reg:\"Símbolo de Registado\",macr:\"Mácron\",deg:\"Símbolo de Grau\",sup2:\"Expoente 2\",sup3:\"Expoente 3\",acute:\"Acento agudo\",micro:\"Símbolo de Micro\",para:\"Símbolo de Parágrafo\",middot:\"Ponto do Meio\",cedil:\"Cedilha\",sup1:\"Expoente 1\",ordm:\"Indicador ordinal masculino\",raquo:\"Aspas ângulo duplo pra Direita\",frac14:\"Fração vulgar 1/4\",frac12:\"Fração vulgar 1/2\",frac34:\"Fração vulgar 3/4\",iquest:\"Ponto de interrugação invertido\",Agrave:\"Letra maiúscula latina A com acento grave\",\nAacute:\"Letra maiúscula latina A com acento agudo\",Acirc:\"Letra maiúscula latina A com circunflexo\",Atilde:\"Letra maiúscula latina A com til\",Auml:\"Letra maiúscula latina A com trema\",Aring:\"Letra maiúscula latina A com sinal diacrítico\",AElig:\"Letra Maiúscula Latina Æ\",Ccedil:\"Letra maiúscula latina C com cedilha\",Egrave:\"Letra maiúscula latina E com acento grave\",Eacute:\"Letra maiúscula latina E com acento agudo\",Ecirc:\"Letra maiúscula latina E com circunflexo\",Euml:\"Letra maiúscula latina E com trema\",\nIgrave:\"Letra maiúscula latina I com acento grave\",Iacute:\"Letra maiúscula latina I com acento agudo\",Icirc:\"Letra maiúscula latina I com cincunflexo\",Iuml:\"Letra maiúscula latina I com trema\",ETH:\"Letra maiúscula latina Eth (Ðð)\",Ntilde:\"Letra maiúscula latina N com til\",Ograve:\"Letra maiúscula latina O com acento grave\",Oacute:\"Letra maiúscula latina O com acento agudo\",Ocirc:\"Letra maiúscula latina I com circunflexo\",Otilde:\"Letra maiúscula latina O com til\",Ouml:\"Letra maiúscula latina O com trema\",\ntimes:\"Símbolo de Multiplicação\",Oslash:\"Letra maiúscula O com barra\",Ugrave:\"Letra maiúscula latina U com acento grave\",Uacute:\"Letra maiúscula latina U com acento agudo\",Ucirc:\"Letra maiúscula latina U com circunflexo\",Uuml:\"Letra maiúscula latina E com trema\",Yacute:\"Letra maiúscula latina Y com acento agudo\",THORN:\"Letra maiúscula latina Rúnico\",szlig:\"Letra minúscula latina s forte\",agrave:\"Letra minúscula latina a com acento grave\",aacute:\"Letra minúscula latina a com acento agudo\",acirc:\"Letra minúscula latina a com circunflexo\",\natilde:\"Letra minúscula latina a com til\",auml:\"Letra minúscula latina a com trema\",aring:\"Letra minúscula latina a com sinal diacrítico\",aelig:\"Letra minúscula latina æ\",ccedil:\"Letra minúscula latina c com cedilha\",egrave:\"Letra minúscula latina e com acento grave\",eacute:\"Letra minúscula latina e com acento agudo\",ecirc:\"Letra minúscula latina e com circunflexo\",euml:\"Letra minúscula latina e com trema\",igrave:\"Letra minúscula latina i com acento grave\",iacute:\"Letra minúscula latina i com acento agudo\",\nicirc:\"Letra minúscula latina i com circunflexo\",iuml:\"Letra pequena latina i com trema\",eth:\"Letra minúscula latina eth\",ntilde:\"Letra minúscula latina n com til\",ograve:\"Letra minúscula latina o com acento grave\",oacute:\"Letra minúscula latina o com acento agudo\",ocirc:\"Letra minúscula latina o com circunflexo\",otilde:\"Letra minúscula latina o com til\",ouml:\"Letra minúscula latina o com trema\",divide:\"Símbolo de Divisão\",oslash:\"Letra minúscula latina o com barra\",ugrave:\"Letra minúscula latina u com acento grave\",\nuacute:\"Letra minúscula latina u com acento agudo\",ucirc:\"Letra minúscula latina u com circunflexo\",uuml:\"Letra minúscula latina u com trema\",yacute:\"Letra minúscula latina y com acento agudo\",thorn:\"Letra minúscula latina Rúnico\",yuml:\"Letra minúscula latina y com trema\",OElig:\"Ligadura maiúscula latina OE\",oelig:\"Ligadura minúscula latina oe\",372:\"Letra maiúscula latina W com circunflexo\",374:\"Letra maiúscula latina Y com circunflexo\",373:\"Letra minúscula latina w com circunflexo\",375:\"Letra minúscula latina y com circunflexo\",\nsbquo:\"Aspa Simples inferior-9\",8219:\"Aspa Simples superior invertida-9\",bdquo:\"Aspa Duplas inferior-9\",hellip:\"Elipse Horizontal \",trade:\"Símbolo de Marca Registada\",9658:\"Ponteiro preto direito\",bull:\"Marca\",rarr:\"Seta para a direita\",rArr:\"Seta dupla para a direita\",hArr:\"Seta dupla direita esquerda\",diams:\"Naipe diamante preto\",asymp:\"Quase igual a \"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/ru.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"ru\",{euro:\"Знак евро\",lsquo:\"Левая одинарная кавычка\",rsquo:\"Правая одинарная кавычка\",ldquo:\"Левая двойная кавычка\",rdquo:\"Левая двойная кавычка\",ndash:\"Среднее тире\",mdash:\"Длинное тире\",iexcl:\"перевёрнутый восклицательный знак\",cent:\"Цент\",pound:\"Фунт\",curren:\"Знак валюты\",yen:\"Йена\",brvbar:\"Вертикальная черта с разрывом\",sect:\"Знак параграфа\",uml:\"Умлаут\",copy:\"Знак охраны авторского права\",ordf:\"Указатель окончания женского рода ...ая\",laquo:\"Левая кавычка-«ёлочка»\",\nnot:\"Отрицание\",reg:\"Знак охраны смежных прав\\\\t\",macr:\"Макрон\",deg:\"Градус\",sup2:\"Надстрочное два\",sup3:\"Надстрочное три\",acute:\"Акут\",micro:\"Микро\",para:\"Абзац\",middot:\"Интерпункт\",cedil:\"Седиль\",sup1:\"Надстрочная единица\",ordm:\"Порядковое числительное\",raquo:\"Правая кавычка-«ёлочка»\",frac14:\"Одна четвертая\",frac12:\"Одна вторая\",frac34:\"Три четвёртых\",iquest:\"Перевёрнутый вопросительный знак\",Agrave:\"Латинская заглавная буква А с апострофом\",Aacute:\"Латинская заглавная буква A с ударением\",Acirc:\"Латинская заглавная буква А с циркумфлексом\",\nAtilde:\"Латинская заглавная буква А с тильдой\",Auml:\"Латинская заглавная буква А с тремой\",Aring:\"Латинская заглавная буква А с кольцом над ней\",AElig:\"Латинская большая буква Æ\",Ccedil:\"Латинская заглавная буква C с седилью\",Egrave:\"Латинская заглавная буква Е с апострофом\",Eacute:\"Латинская заглавная буква Е с ударением\",Ecirc:\"Латинская заглавная буква Е с циркумфлексом\",Euml:\"Латинская заглавная буква Е с тремой\",Igrave:\"Латинская заглавная буква I с апострофом\",Iacute:\"Латинская заглавная буква I с ударением\",\nIcirc:\"Латинская заглавная буква I с циркумфлексом\",Iuml:\"Латинская заглавная буква I с тремой\",ETH:\"Латинская большая буква Eth\",Ntilde:\"Латинская заглавная буква N с тильдой\",Ograve:\"Латинская заглавная буква O с апострофом\",Oacute:\"Латинская заглавная буква O с ударением\",Ocirc:\"Латинская заглавная буква O с циркумфлексом\",Otilde:\"Латинская заглавная буква O с тильдой\",Ouml:\"Латинская заглавная буква O с тремой\",times:\"Знак умножения\",Oslash:\"Латинская большая перечеркнутая O\",Ugrave:\"Латинская заглавная буква U с апострофом\",\nUacute:\"Латинская заглавная буква U с ударением\",Ucirc:\"Латинская заглавная буква U с циркумфлексом\",Uuml:\"Латинская заглавная буква U с тремой\",Yacute:\"Латинская заглавная буква Y с ударением\",THORN:\"Латинская заглавная буква Thorn\",szlig:\"Знак диеза\",agrave:\"Латинская маленькая буква a с апострофом\",aacute:\"Латинская маленькая буква a с ударением\",acirc:\"Латинская маленькая буква a с циркумфлексом\",atilde:\"Латинская маленькая буква a с тильдой\",auml:\"Латинская маленькая буква a с тремой\",aring:\"Латинская маленькая буква a с кольцом\",\naelig:\"Латинская маленькая буква æ\",ccedil:\"Латинская маленькая буква с с седилью\",egrave:\"Латинская маленькая буква е с апострофом\",eacute:\"Латинская маленькая буква е с ударением\",ecirc:\"Латинская маленькая буква е с циркумфлексом\",euml:\"Латинская маленькая буква е с тремой\",igrave:\"Латинская маленькая буква i с апострофом\",iacute:\"Латинская маленькая буква i с ударением\",icirc:\"Латинская маленькая буква i с циркумфлексом\",iuml:\"Латинская маленькая буква i с тремой\",eth:\"Латинская маленькая буква eth\",\nntilde:\"Латинская маленькая буква n с тильдой\",ograve:\"Латинская маленькая буква o с апострофом\",oacute:\"Латинская маленькая буква o с ударением\",ocirc:\"Латинская маленькая буква o с циркумфлексом\",otilde:\"Латинская маленькая буква o с тильдой\",ouml:\"Латинская маленькая буква o с тремой\",divide:\"Знак деления\",oslash:\"Латинская строчная перечеркнутая o\",ugrave:\"Латинская маленькая буква u с апострофом\",uacute:\"Латинская маленькая буква u с ударением\",ucirc:\"Латинская маленькая буква u с циркумфлексом\",\nuuml:\"Латинская маленькая буква u с тремой\",yacute:\"Латинская маленькая буква y с ударением\",thorn:\"Латинская маленькая буква thorn\",yuml:\"Латинская маленькая буква y с тремой\",OElig:\"Латинская прописная лигатура OE\",oelig:\"Латинская строчная лигатура oe\",372:\"Латинская заглавная буква W с циркумфлексом\",374:\"Латинская заглавная буква Y с циркумфлексом\",373:\"Латинская маленькая буква w с циркумфлексом\",375:\"Латинская маленькая буква y с циркумфлексом\",sbquo:\"Нижняя одинарная кавычка\",8219:\"Правая одинарная кавычка\",\nbdquo:\"Левая двойная кавычка\",hellip:\"Горизонтальное многоточие\",trade:\"Товарный знак\",9658:\"Черный указатель вправо\",bull:\"Маркер списка\",rarr:\"Стрелка вправо\",rArr:\"Двойная стрелка вправо\",hArr:\"Двойная стрелка влево-вправо\",diams:\"Черный ромб\",asymp:\"Примерно равно\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/si.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"si\",{euro:\"යුරෝ සලකුණ\",lsquo:\"වමේ තනි උපුටා දක්වීම \",rsquo:\"දකුණේ තනි උපුටා දක්වීම \",ldquo:\"වමේ දිත්ව  උපුටා දක්වීම \",rdquo:\"දකුණේ දිත්ව  උපුටා දක්වීම \",ndash:\"En dash\",mdash:\"Em dash\",iexcl:\"යටිකුරු හර්ෂදී \",cent:\"Cent sign\",pound:\"Pound sign\",curren:\"මුල්‍යමය \",yen:\"යෙන් \",brvbar:\"Broken bar\",sect:\"තෙරේම් \",uml:\"Diaeresis\",copy:\"පිටපත් අයිතිය \",ordf:\"දර්ශකය\",laquo:\"Left-pointing double angle quotation mark\",not:\"සලකුණක් නොවේ\",reg:\"සලකුණක් ලියාපදිංචි කිරීම\",\nmacr:\"මුද්‍රිත \",deg:\"සලකුණේ \",sup2:\"උඩු ලකුණු දෙක\",sup3:\"Superscript three\",acute:\"Acute accent\",micro:\"Micro sign\",para:\"Pilcrow sign\",middot:\"Middle dot\",cedil:\"Cedilla\",sup1:\"Superscript one\",ordm:\"Masculine ordinal indicator\",raquo:\"Right-pointing double angle quotation mark\",frac14:\"Vulgar fraction one quarter\",frac12:\"Vulgar fraction one half\",frac34:\"Vulgar fraction three quarters\",iquest:\"Inverted question mark\",Agrave:\"Latin capital letter A with grave accent\",Aacute:\"Latin capital letter A with acute accent\",\nAcirc:\"Latin capital letter A with circumflex\",Atilde:\"Latin capital letter A with tilde\",Auml:\"Latin capital letter A with diaeresis\",Aring:\"Latin capital letter A with ring above\",AElig:\"Latin Capital letter Æ\",Ccedil:\"Latin capital letter C with cedilla\",Egrave:\"Latin capital letter E with grave accent\",Eacute:\"Latin capital letter E with acute accent\",Ecirc:\"Latin capital letter E with circumflex\",Euml:\"Latin capital letter E with diaeresis\",Igrave:\"Latin capital letter I with grave accent\",Iacute:\"Latin capital letter I with acute accent\",\nIcirc:\"Latin capital letter I with circumflex\",Iuml:\"Latin capital letter I with diaeresis\",ETH:\"Latin capital letter Eth\",Ntilde:\"Latin capital letter N with tilde\",Ograve:\"Latin capital letter O with grave accent\",Oacute:\"Latin capital letter O with acute accent\",Ocirc:\"Latin capital letter O with circumflex\",Otilde:\"Latin capital letter O with tilde\",Ouml:\"Latin capital letter O with diaeresis\",times:\"Multiplication sign\",Oslash:\"Latin capital letter O with stroke\",Ugrave:\"Latin capital letter U with grave accent\",\nUacute:\"Latin capital letter U with acute accent\",Ucirc:\"Latin capital letter U with circumflex\",Uuml:\"Latin capital letter U with diaeresis\",Yacute:\"Latin capital letter Y with acute accent\",THORN:\"Latin capital letter Thorn\",szlig:\"Latin small letter sharp s\",agrave:\"Latin small letter a with grave accent\",aacute:\"Latin small letter a with acute accent\",acirc:\"Latin small letter a with circumflex\",atilde:\"Latin small letter a with tilde\",auml:\"Latin small letter a with diaeresis\",aring:\"Latin small letter a with ring above\",\naelig:\"Latin small letter æ\",ccedil:\"Latin small letter c with cedilla\",egrave:\"Latin small letter e with grave accent\",eacute:\"Latin small letter e with acute accent\",ecirc:\"Latin small letter e with circumflex\",euml:\"Latin small letter e with diaeresis\",igrave:\"Latin small letter i with grave accent\",iacute:\"Latin small letter i with acute accent\",icirc:\"Latin small letter i with circumflex\",iuml:\"Latin small letter i with diaeresis\",eth:\"Latin small letter eth\",ntilde:\"Latin small letter n with tilde\",\nograve:\"Latin small letter o with grave accent\",oacute:\"Latin small letter o with acute accent\",ocirc:\"Latin small letter o with circumflex\",otilde:\"Latin small letter o with tilde\",ouml:\"Latin small letter o with diaeresis\",divide:\"Division sign\",oslash:\"Latin small letter o with stroke\",ugrave:\"Latin small letter u with grave accent\",uacute:\"Latin small letter u with acute accent\",ucirc:\"Latin small letter u with circumflex\",uuml:\"Latin small letter u with diaeresis\",yacute:\"Latin small letter y with acute accent\",\nthorn:\"Latin small letter thorn\",yuml:\"Latin small letter y with diaeresis\",OElig:\"Latin capital ligature OE\",oelig:\"Latin small ligature oe\",372:\"Latin capital letter W with circumflex\",374:\"Latin capital letter Y with circumflex\",373:\"Latin small letter w with circumflex\",375:\"Latin small letter y with circumflex\",sbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",hellip:\"Horizontal ellipsis\",trade:\"Trade mark sign\",9658:\"Black right-pointing pointer\",\nbull:\"Bullet\",rarr:\"Rightwards arrow\",rArr:\"Rightwards double arrow\",hArr:\"Left right double arrow\",diams:\"Black diamond suit\",asymp:\"Almost equal to\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/sk.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"sk\",{euro:\"Znak eura\",lsquo:\"Ľavá jednoduchá úvodzovka\",rsquo:\"Pravá jednoduchá úvodzovka\",ldquo:\"Pravá dvojitá úvodzovka\",rdquo:\"Pravá dvojitá úvodzovka\",ndash:\"En pomlčka\",mdash:\"Em pomlčka\",iexcl:\"Obrátený výkričník\",cent:\"Znak centu\",pound:\"Znak libry\",curren:\"Znak meny\",yen:\"Znak jenu\",brvbar:\"Prerušená zvislá čiara\",sect:\"Znak odseku\",uml:\"Prehláska\",copy:\"Znak copyrightu\",ordf:\"Ženský indikátor rodu\",laquo:\"Znak dvojitých lomených úvodzoviek vľavo\",not:\"Logistický zápor\",\nreg:\"Znak registrácie\",macr:\"Pomlčka nad\",deg:\"Znak stupňa\",sup2:\"Dvojka ako horný index\",sup3:\"Trojka ako horný index\",acute:\"Dĺžeň\",micro:\"Znak mikro\",para:\"Znak odstavca\",middot:\"Bodka uprostred\",cedil:\"Chvost vľavo\",sup1:\"Jednotka ako horný index\",ordm:\"Mužský indikátor rodu\",raquo:\"Znak dvojitých lomených úvodzoviek vpravo\",frac14:\"Obyčajný zlomok jedna štvrtina\",frac12:\"Obyčajný zlomok jedna polovica\",frac34:\"Obyčajný zlomok tri štvrtiny\",iquest:\"Otočený otáznik\",Agrave:\"Veľké písmeno latinky A s accentom\",\nAacute:\"Veľké písmeno latinky A s dĺžňom\",Acirc:\"Veľké písmeno latinky A s mäkčeňom\",Atilde:\"Veľké písmeno latinky A s tildou\",Auml:\"Veľké písmeno latinky A s dvoma bodkami\",Aring:\"Veľké písmeno latinky A s krúžkom nad\",AElig:\"Veľké písmeno latinky Æ\",Ccedil:\"Veľké písmeno latinky C s chvostom vľavo\",Egrave:\"Veľké písmeno latinky E s accentom\",Eacute:\"Veľké písmeno latinky E s dĺžňom\",Ecirc:\"Veľké písmeno latinky E s mäkčeňom\",Euml:\"Veľké písmeno latinky E s dvoma bodkami\",Igrave:\"Veľké písmeno latinky I s accentom\",\nIacute:\"Veľké písmeno latinky I s dĺžňom\",Icirc:\"Veľké písmeno latinky I s mäkčeňom\",Iuml:\"Veľké písmeno latinky I s dvoma bodkami\",ETH:\"Veľké písmeno latinky Eth\",Ntilde:\"Veľké písmeno latinky N s tildou\",Ograve:\"Veľké písmeno latinky O s accentom\",Oacute:\"Veľké písmeno latinky O s dĺžňom\",Ocirc:\"Veľké písmeno latinky O s mäkčeňom\",Otilde:\"Veľké písmeno latinky O s tildou\",Ouml:\"Veľké písmeno latinky O s dvoma bodkami\",times:\"Znak násobenia\",Oslash:\"Veľké písmeno latinky O preškrtnuté\",Ugrave:\"Veľké písmeno latinky U s accentom\",\nUacute:\"Veľké písmeno latinky U s dĺžňom\",Ucirc:\"Veľké písmeno latinky U s mäkčeňom\",Uuml:\"Veľké písmeno latinky U s dvoma bodkami\",Yacute:\"Veľké písmeno latinky Y s dĺžňom\",THORN:\"Veľké písmeno latinky Thorn\",szlig:\"Malé písmeno latinky ostré s\",agrave:\"Malé písmeno latinky a s accentom\",aacute:\"Malé písmeno latinky a s dĺžňom\",acirc:\"Malé písmeno latinky a s mäkčeňom\",atilde:\"Malé písmeno latinky a s tildou\",auml:\"Malé písmeno latinky a s dvoma bodkami\",aring:\"Malé písmeno latinky a s krúžkom nad\",\naelig:\"Malé písmeno latinky æ\",ccedil:\"Malé písmeno latinky c s chvostom vľavo\",egrave:\"Malé písmeno latinky e s accentom\",eacute:\"Malé písmeno latinky e s dĺžňom\",ecirc:\"Malé písmeno latinky e s mäkčeňom\",euml:\"Malé písmeno latinky e s dvoma bodkami\",igrave:\"Malé písmeno latinky i s accentom\",iacute:\"Malé písmeno latinky i s dĺžňom\",icirc:\"Malé písmeno latinky i s mäkčeňom\",iuml:\"Malé písmeno latinky i s dvoma bodkami\",eth:\"Malé písmeno latinky eth\",ntilde:\"Malé písmeno latinky n s tildou\",ograve:\"Malé písmeno latinky o s accentom\",\noacute:\"Malé písmeno latinky o s dĺžňom\",ocirc:\"Malé písmeno latinky o s mäkčeňom\",otilde:\"Malé písmeno latinky o s tildou\",ouml:\"Malé písmeno latinky o s dvoma bodkami\",divide:\"Znak delenia\",oslash:\"Malé písmeno latinky o preškrtnuté\",ugrave:\"Malé písmeno latinky u s accentom\",uacute:\"Malé písmeno latinky u s dĺžňom\",ucirc:\"Malé písmeno latinky u s mäkčeňom\",uuml:\"Malé písmeno latinky u s dvoma bodkami\",yacute:\"Malé písmeno latinky y s dĺžňom\",thorn:\"Malé písmeno latinky thorn\",yuml:\"Malé písmeno latinky y s dvoma bodkami\",\nOElig:\"Veľká ligatúra latinky OE\",oelig:\"Malá ligatúra latinky OE\",372:\"Veľké písmeno latinky W s mäkčeňom\",374:\"Veľké písmeno latinky Y s mäkčeňom\",373:\"Malé písmeno latinky w s mäkčeňom\",375:\"Malé písmeno latinky y s mäkčeňom\",sbquo:\"Dolná jednoduchá 9-úvodzovka\",8219:\"Horná jednoduchá otočená 9-úvodzovka\",bdquo:\"Dolná dvojitá 9-úvodzovka\",hellip:\"Trojbodkový úvod\",trade:\"Znak ibchodnej značky\",9658:\"Čierny ukazovateľ smerujúci vpravo\",bull:\"Kruh\",rarr:\"Šípka vpravo\",rArr:\"Dvojitá šipka vpravo\",\nhArr:\"Dvojitá šipka vľavo a vpravo\",diams:\"Čierne piky\",asymp:\"Skoro sa rovná\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/sl.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"sl\",{euro:\"Evro znak\",lsquo:\"Levi enojni narekovaj\",rsquo:\"Desni enojni narekovaj\",ldquo:\"Levi dvojni narekovaj\",rdquo:\"Desni dvojni narekovaj\",ndash:\"En pomišljaj\",mdash:\"Em pomišljaj\",iexcl:\"Obrnjen klicaj\",cent:\"Cent znak\",pound:\"Funt znak\",curren:\"Znak valute\",yen:\"Jen znak\",brvbar:\"Zlomljena črta\",sect:\"Znak oddelka\",uml:\"Diaeresis\",copy:\"Znak avtorskih pravic\",ordf:\"Ženski zaporedni kazalnik\",laquo:\"Levi obrnjen dvojni kotni narekovaj\",not:\"Ne znak\",reg:\"Registrirani znak\",\nmacr:\"Macron\",deg:\"Znak stopinj\",sup2:\"Nadpisano dva\",sup3:\"Nadpisano tri\",acute:\"Ostrivec\",micro:\"Mikro znak\",para:\"Pilcrow znak\",middot:\"Sredinska pika\",cedil:\"Cedilla\",sup1:\"Nadpisano ena\",ordm:\"Moški zaporedni kazalnik\",raquo:\"Desno obrnjen dvojni kotni narekovaj\",frac14:\"Ena četrtina\",frac12:\"Ena polovica\",frac34:\"Tri četrtine\",iquest:\"Obrnjen vprašaj\",Agrave:\"Velika latinska črka A s krativcem\",Aacute:\"Velika latinska črka A z ostrivcem\",Acirc:\"Velika latinska črka A s strešico\",Atilde:\"Velika latinska črka A z tildo\",\nAuml:\"Velika latinska črka A z diaeresis-om\",Aring:\"Velika latinska črka A z obročem\",AElig:\"Velika latinska črka Æ\",Ccedil:\"Velika latinska črka C s cedillo\",Egrave:\"Velika latinska črka E s krativcem\",Eacute:\"Velika latinska črka E z ostrivcem\",Ecirc:\"Velika latinska črka E s strešico\",Euml:\"Velika latinska črka E z diaeresis-om\",Igrave:\"Velika latinska črka I s krativcem\",Iacute:\"Velika latinska črka I z ostrivcem\",Icirc:\"Velika latinska črka I s strešico\",Iuml:\"Velika latinska črka I z diaeresis-om\",\nETH:\"Velika latinska črka Eth\",Ntilde:\"Velika latinska črka N s tildo\",Ograve:\"Velika latinska črka O s krativcem\",Oacute:\"Velika latinska črka O z ostrivcem\",Ocirc:\"Velika latinska črka O s strešico\",Otilde:\"Velika latinska črka O s tildo\",Ouml:\"Velika latinska črka O z diaeresis-om\",times:\"Znak za množenje\",Oslash:\"Velika prečrtana latinska črka O\",Ugrave:\"Velika latinska črka U s krativcem\",Uacute:\"Velika latinska črka U z ostrivcem\",Ucirc:\"Velika latinska črka U s strešico\",Uuml:\"Velika latinska črka U z diaeresis-om\",\nYacute:\"Velika latinska črka Y z ostrivcem\",THORN:\"Velika latinska črka Thorn\",szlig:\"Mala ostra latinska črka s\",agrave:\"Mala latinska črka a s krativcem\",aacute:\"Mala latinska črka a z ostrivcem\",acirc:\"Mala latinska črka a s strešico\",atilde:\"Mala latinska črka a s tildo\",auml:\"Mala latinska črka a z diaeresis-om\",aring:\"Mala latinska črka a z obročem\",aelig:\"Mala latinska črka æ\",ccedil:\"Mala latinska črka c s cedillo\",egrave:\"Mala latinska črka e s krativcem\",eacute:\"Mala latinska črka e z ostrivcem\",\necirc:\"Mala latinska črka e s strešico\",euml:\"Mala latinska črka e z diaeresis-om\",igrave:\"Mala latinska črka i s krativcem\",iacute:\"Mala latinska črka i z ostrivcem\",icirc:\"Mala latinska črka i s strešico\",iuml:\"Mala latinska črka i z diaeresis-om\",eth:\"Mala latinska črka eth\",ntilde:\"Mala latinska črka n s tildo\",ograve:\"Mala latinska črka o s krativcem\",oacute:\"Mala latinska črka o z ostrivcem\",ocirc:\"Mala latinska črka o s strešico\",otilde:\"Mala latinska črka o s tildo\",ouml:\"Mala latinska črka o z diaeresis-om\",\ndivide:\"Znak za deljenje\",oslash:\"Mala prečrtana latinska črka o\",ugrave:\"Mala latinska črka u s krativcem\",uacute:\"Mala latinska črka u z ostrivcem\",ucirc:\"Mala latinska črka u s strešico\",uuml:\"Mala latinska črka u z diaeresis-om\",yacute:\"Mala latinska črka y z ostrivcem\",thorn:\"Mala latinska črka thorn\",yuml:\"Mala latinska črka y z diaeresis-om\",OElig:\"Velika latinska ligatura OE\",oelig:\"Mala latinska ligatura oe\",372:\"Velika latinska črka W s strešico\",374:\"Velika latinska črka Y s strešico\",\n373:\"Mala latinska črka w s strešico\",375:\"Mala latinska črka y s strešico\",sbquo:\"Enojni nizki-9 narekovaj\",8219:\"Enojni visoki-obrnjen-9 narekovaj\",bdquo:\"Dvojni nizki-9 narekovaj\",hellip:\"Horizontalni izpust\",trade:\"Znak blagovne znamke\",9658:\"Črni desno-usmerjen kazalec\",bull:\"Krogla\",rarr:\"Desno-usmerjena puščica\",rArr:\"Desno-usmerjena dvojna puščica\",hArr:\"Leva in desna dvojna puščica\",diams:\"Črna kara\",asymp:\"Skoraj enako\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/sq.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"sq\",{euro:\"Shenja e Euros\",lsquo:\"Thonjëza majtas me një vi\",rsquo:\"Thonjëza djathtas me një vi\",ldquo:\"Thonjëza majtas\",rdquo:\"Thonjëza djathtas\",ndash:\"En viza lidhëse\",mdash:\"Em viza lidhëse\",iexcl:\"Pikëçuditëse e përmbysur\",cent:\"Shenja e Centit\",pound:\"Shejna e Funtit\",curren:\"Shenja e valutës\",yen:\"Shenja e Jenit\",brvbar:\"Viza e këputur\",sect:\"Shenja e pjesës\",uml:\"Diaeresis\",copy:\"Shenja e të drejtave të kopjimit\",ordf:\"Feminine ordinal indicator\",laquo:\"Left-pointing double angle quotation mark\",\nnot:\"Nuk ka shenjë\",reg:\"Shenja e të regjistruarit\",macr:\"Macron\",deg:\"Shenja e shkallës\",sup2:\"Super-skripta dy\",sup3:\"Super-skripta tre\",acute:\"Theks i mprehtë\",micro:\"Shjenja e Mikros\",para:\"Pilcrow sign\",middot:\"Pika e Mesme\",cedil:\"Hark nën shkronja\",sup1:\"Super-skripta një\",ordm:\"Masculine ordinal indicator\",raquo:\"Right-pointing double angle quotation mark\",frac14:\"Thyesa një të katrat\",frac12:\"Thyesa një të dytat\",frac34:\"Thyesa tre të katrat\",iquest:\"Pikëpyetje e përmbysur\",Agrave:\"Shkronja e madhe latine A me theks të rëndë\",\nAacute:\"Shkronja e madhe latine A me theks akute\",Acirc:\"Shkronja e madhe latine A me theks lakor\",Atilde:\"Shkronja e madhe latine A me tildë\",Auml:\"Shkronja e madhe latine A me dy pika\",Aring:\"Shkronja e madhe latine A me unazë mbi\",AElig:\"Shkronja e madhe latine Æ\",Ccedil:\"Shkronja e madhe latine C me hark poshtë\",Egrave:\"Shkronja e madhe latine E me theks të rëndë\",Eacute:\"Shkronja e madhe latine E me theks akute\",Ecirc:\"Shkronja e madhe latine E me theks lakor\",Euml:\"Shkronja e madhe latine E me dy pika\",\nIgrave:\"Shkronja e madhe latine I me theks të rëndë\",Iacute:\"Shkronja e madhe latine I me theks akute\",Icirc:\"Shkronja e madhe latine I me theks lakor\",Iuml:\"Shkronja e madhe latine I me dy pika\",ETH:\"Shkronja e madhe latine Eth\",Ntilde:\"Shkronja e madhe latine N me tildë\",Ograve:\"Shkronja e madhe latine O me theks të rëndë\",Oacute:\"Shkronja e madhe latine O me theks akute\",Ocirc:\"Shkronja e madhe latine O me theks lakor\",Otilde:\"Shkronja e madhe latine O me tildë\",Ouml:\"Shkronja e madhe latine O me dy pika\",\ntimes:\"Shenja e shumëzimit\",Oslash:\"Shkronja e madhe latine O me vizë në mes\",Ugrave:\"Shkronja e madhe latine U me theks të rëndë\",Uacute:\"Shkronja e madhe latine U me theks akute\",Ucirc:\"Shkronja e madhe latine U me theks lakor\",Uuml:\"Shkronja e madhe latine U me dy pika\",Yacute:\"Shkronja e madhe latine Y me theks akute\",THORN:\"Shkronja e madhe latine Thorn\",szlig:\"Shkronja e vogë latine s e mprehtë\",agrave:\"Shkronja e vogë latine a me theks të rëndë\",aacute:\"Shkronja e vogë latine a me theks të mprehtë\",\nacirc:\"Shkronja e vogël latine a me theks lakor\",atilde:\"Shkronja e vogël latine a me tildë\",auml:\"Shkronja e vogël latine a me dy pika\",aring:\"Shkronja e vogë latine a me unazë mbi\",aelig:\"Shkronja e vogë latine æ\",ccedil:\"Shkronja e vogël latine c me hark poshtë\",egrave:\"Shkronja e vogë latine e me theks të rëndë\",eacute:\"Shkronja e vogë latine e me theks të mprehtë\",ecirc:\"Shkronja e vogël latine e me theks lakor\",euml:\"Shkronja e vogël latine e me dy pika\",igrave:\"Shkronja e vogë latine i me theks të rëndë\",\niacute:\"Shkronja e vogë latine i me theks të mprehtë\",icirc:\"Shkronja e vogël latine i me theks lakor\",iuml:\"Shkronja e vogël latine i me dy pika\",eth:\"Shkronja e vogë latine eth\",ntilde:\"Shkronja e vogël latine n me tildë\",ograve:\"Shkronja e vogë latine o me theks të rëndë\",oacute:\"Shkronja e vogë latine o me theks të mprehtë\",ocirc:\"Shkronja e vogël latine o me theks lakor\",otilde:\"Shkronja e vogël latine o me tildë\",ouml:\"Shkronja e vogël latine o me dy pika\",divide:\"Shenja ndarëse\",oslash:\"Shkronja e vogël latine o me vizë në mes\",\nugrave:\"Shkronja e vogë latine u me theks të rëndë\",uacute:\"Shkronja e vogë latine u me theks të mprehtë\",ucirc:\"Shkronja e vogël latine u me theks lakor\",uuml:\"Shkronja e vogël latine u me dy pika\",yacute:\"Shkronja e vogë latine y me theks të mprehtë\",thorn:\"Shkronja e vogël latine thorn\",yuml:\"Shkronja e vogël latine y me dy pika\",OElig:\"Shkronja e madhe e bashkuar latine OE\",oelig:\"Shkronja e vogël e bashkuar latine oe\",372:\"Shkronja e madhe latine W me theks lakor\",374:\"Shkronja e madhe latine Y me theks lakor\",\n373:\"Shkronja e vogël latine w me theks lakor\",375:\"Shkronja e vogël latine y me theks lakor\",sbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",hellip:\"Horizontal ellipsis\",trade:\"Shenja e Simbolit Tregtarë\",9658:\"Black right-pointing pointer\",bull:\"Pulla\",rarr:\"Shigjeta djathtas\",rArr:\"Shenja të dyfishta djathtas\",hArr:\"Shigjeta e dyfishë majtas-djathtas\",diams:\"Black diamond suit\",asymp:\"Gati e barabar me\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/sv.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"sv\",{euro:\"Eurotecken\",lsquo:\"Enkelt vänster citattecken\",rsquo:\"Enkelt höger citattecken\",ldquo:\"Dubbelt vänster citattecken\",rdquo:\"Dubbelt höger citattecken\",ndash:\"Snedstreck\",mdash:\"Långt tankstreck\",iexcl:\"Inverterad utropstecken\",cent:\"Centtecken\",pound:\"Pundtecken\",curren:\"Valutatecken\",yen:\"Yentecken\",brvbar:\"Brutet lodrätt streck\",sect:\"Paragraftecken\",uml:\"Diaeresis\",copy:\"Upphovsrättstecken\",ordf:\"Feminit ordningstalsindikator\",laquo:\"Vänsterställt dubbelt vinkelcitationstecken\",\nnot:\"Icke-tecken\",reg:\"Registrerad\",macr:\"Macron\",deg:\"Grader\",sup2:\"Upphöjt två\",sup3:\"Upphöjt tre\",acute:\"Akut accent\",micro:\"Mikrotecken\",para:\"Alinea\",middot:\"Centrerad prick\",cedil:\"Cedilj\",sup1:\"Upphöjt en\",ordm:\"Maskulina ordningsändelsen\",raquo:\"Högerställt dubbelt vinkelcitationstecken\",frac14:\"Bråktal - en kvart\",frac12:\"Bråktal - en halv\",frac34:\"Bråktal - tre fjärdedelar\",iquest:\"Inverterat frågetecken\",Agrave:\"Stort A med grav accent\",Aacute:\"Stort A med akutaccent\",Acirc:\"Stort A med circumflex\",\nAtilde:\"Stort A med tilde\",Auml:\"Stort A med diaresis\",Aring:\"Stort A med ring ovan\",AElig:\"Stort Æ\",Ccedil:\"Stort C med cedilj\",Egrave:\"Stort E med grav accent\",Eacute:\"Stort E med aktuaccent\",Ecirc:\"Stort E med circumflex\",Euml:\"Stort E med diaeresis\",Igrave:\"Stort I med grav accent\",Iacute:\"Stort I med akutaccent\",Icirc:\"Stort I med circumflex\",Iuml:\"Stort I med diaeresis\",ETH:\"Stort Eth\",Ntilde:\"Stort N med tilde\",Ograve:\"Stort O med grav accent\",Oacute:\"Stort O med aktuaccent\",Ocirc:\"Stort O med circumflex\",\nOtilde:\"Stort O med tilde\",Ouml:\"Stort O med diaeresis\",times:\"Multiplicera\",Oslash:\"Stor Ø\",Ugrave:\"Stort U med grav accent\",Uacute:\"Stort U med akutaccent\",Ucirc:\"Stort U med circumflex\",Uuml:\"Stort U med diaeresis\",Yacute:\"Stort Y med akutaccent\",THORN:\"Stort Thorn\",szlig:\"Litet dubbel-s/Eszett\",agrave:\"Litet a med grav accent\",aacute:\"Litet a med akutaccent\",acirc:\"Litet a med circumflex\",atilde:\"Litet a med tilde\",auml:\"Litet a med diaeresis\",aring:\"Litet a med ring ovan\",aelig:\"Bokstaven æ\",\nccedil:\"Litet c med cedilj\",egrave:\"Litet e med grav accent\",eacute:\"Litet e med akutaccent\",ecirc:\"Litet e med circumflex\",euml:\"Litet e med diaeresis\",igrave:\"Litet i med grav accent\",iacute:\"Litet i med akutaccent\",icirc:\"LItet i med circumflex\",iuml:\"Litet i med didaeresis\",eth:\"Litet eth\",ntilde:\"Litet n med tilde\",ograve:\"LItet o med grav accent\",oacute:\"LItet o med akutaccent\",ocirc:\"Litet o med circumflex\",otilde:\"LItet o med tilde\",ouml:\"Litet o med diaeresis\",divide:\"Division\",oslash:\"ø\",\nugrave:\"Litet u med grav accent\",uacute:\"Litet u med akutaccent\",ucirc:\"LItet u med circumflex\",uuml:\"Litet u med diaeresis\",yacute:\"Litet y med akutaccent\",thorn:\"Litet thorn\",yuml:\"Litet y med diaeresis\",OElig:\"Stor ligatur av OE\",oelig:\"Liten ligatur av oe\",372:\"Stort W med circumflex\",374:\"Stort Y med circumflex\",373:\"Litet w med circumflex\",375:\"Litet y med circumflex\",sbquo:\"Enkelt lågt 9-citationstecken\",8219:\"Enkelt högt bakvänt 9-citationstecken\",bdquo:\"Dubbelt lågt 9-citationstecken\",hellip:\"Horisontellt uteslutningstecken\",\ntrade:\"Varumärke\",9658:\"Svart högervänd pekare\",bull:\"Listpunkt\",rarr:\"Högerpil\",rArr:\"Dubbel högerpil\",hArr:\"Dubbel vänsterpil\",diams:\"Svart ruter\",asymp:\"Ungefär lika med\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/th.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"th\",{euro:\"Euro sign\",lsquo:\"Left single quotation mark\",rsquo:\"Right single quotation mark\",ldquo:\"Left double quotation mark\",rdquo:\"Right double quotation mark\",ndash:\"En dash\",mdash:\"Em dash\",iexcl:\"Inverted exclamation mark\",cent:\"Cent sign\",pound:\"Pound sign\",curren:\"สัญลักษณ์สกุลเงิน\",yen:\"สัญลักษณ์เงินเยน\",brvbar:\"Broken bar\",sect:\"Section sign\",uml:\"Diaeresis\",copy:\"Copyright sign\",ordf:\"Feminine ordinal indicator\",laquo:\"Left-pointing double angle quotation mark\",\nnot:\"Not sign\",reg:\"Registered sign\",macr:\"Macron\",deg:\"Degree sign\",sup2:\"Superscript two\",sup3:\"Superscript three\",acute:\"Acute accent\",micro:\"Micro sign\",para:\"Pilcrow sign\",middot:\"Middle dot\",cedil:\"Cedilla\",sup1:\"Superscript one\",ordm:\"Masculine ordinal indicator\",raquo:\"Right-pointing double angle quotation mark\",frac14:\"Vulgar fraction one quarter\",frac12:\"Vulgar fraction one half\",frac34:\"Vulgar fraction three quarters\",iquest:\"Inverted question mark\",Agrave:\"Latin capital letter A with grave accent\",\nAacute:\"Latin capital letter A with acute accent\",Acirc:\"Latin capital letter A with circumflex\",Atilde:\"Latin capital letter A with tilde\",Auml:\"Latin capital letter A with diaeresis\",Aring:\"Latin capital letter A with ring above\",AElig:\"Latin Capital letter Æ\",Ccedil:\"Latin capital letter C with cedilla\",Egrave:\"Latin capital letter E with grave accent\",Eacute:\"Latin capital letter E with acute accent\",Ecirc:\"Latin capital letter E with circumflex\",Euml:\"Latin capital letter E with diaeresis\",Igrave:\"Latin capital letter I with grave accent\",\nIacute:\"Latin capital letter I with acute accent\",Icirc:\"Latin capital letter I with circumflex\",Iuml:\"Latin capital letter I with diaeresis\",ETH:\"Latin capital letter Eth\",Ntilde:\"Latin capital letter N with tilde\",Ograve:\"Latin capital letter O with grave accent\",Oacute:\"Latin capital letter O with acute accent\",Ocirc:\"Latin capital letter O with circumflex\",Otilde:\"Latin capital letter O with tilde\",Ouml:\"Latin capital letter O with diaeresis\",times:\"Multiplication sign\",Oslash:\"Latin capital letter O with stroke\",\nUgrave:\"Latin capital letter U with grave accent\",Uacute:\"Latin capital letter U with acute accent\",Ucirc:\"Latin capital letter U with circumflex\",Uuml:\"Latin capital letter U with diaeresis\",Yacute:\"Latin capital letter Y with acute accent\",THORN:\"Latin capital letter Thorn\",szlig:\"Latin small letter sharp s\",agrave:\"Latin small letter a with grave accent\",aacute:\"Latin small letter a with acute accent\",acirc:\"Latin small letter a with circumflex\",atilde:\"Latin small letter a with tilde\",auml:\"Latin small letter a with diaeresis\",\naring:\"Latin small letter a with ring above\",aelig:\"Latin small letter æ\",ccedil:\"Latin small letter c with cedilla\",egrave:\"Latin small letter e with grave accent\",eacute:\"Latin small letter e with acute accent\",ecirc:\"Latin small letter e with circumflex\",euml:\"Latin small letter e with diaeresis\",igrave:\"Latin small letter i with grave accent\",iacute:\"Latin small letter i with acute accent\",icirc:\"Latin small letter i with circumflex\",iuml:\"Latin small letter i with diaeresis\",eth:\"Latin small letter eth\",\nntilde:\"Latin small letter n with tilde\",ograve:\"Latin small letter o with grave accent\",oacute:\"Latin small letter o with acute accent\",ocirc:\"Latin small letter o with circumflex\",otilde:\"Latin small letter o with tilde\",ouml:\"Latin small letter o with diaeresis\",divide:\"Division sign\",oslash:\"Latin small letter o with stroke\",ugrave:\"Latin small letter u with grave accent\",uacute:\"Latin small letter u with acute accent\",ucirc:\"Latin small letter u with circumflex\",uuml:\"Latin small letter u with diaeresis\",\nyacute:\"Latin small letter y with acute accent\",thorn:\"Latin small letter thorn\",yuml:\"Latin small letter y with diaeresis\",OElig:\"Latin capital ligature OE\",oelig:\"Latin small ligature oe\",372:\"Latin capital letter W with circumflex\",374:\"Latin capital letter Y with circumflex\",373:\"Latin small letter w with circumflex\",375:\"Latin small letter y with circumflex\",sbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",hellip:\"Horizontal ellipsis\",\ntrade:\"Trade mark sign\",9658:\"Black right-pointing pointer\",bull:\"สัญลักษณ์หัวข้อย่อย\",rarr:\"Rightwards arrow\",rArr:\"Rightwards double arrow\",hArr:\"Left right double arrow\",diams:\"Black diamond suit\",asymp:\"Almost equal to\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/tr.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"tr\",{euro:\"Euro işareti\",lsquo:\"Sol tek tırnak işareti\",rsquo:\"Sağ tek tırnak işareti\",ldquo:\"Sol çift tırnak işareti\",rdquo:\"Sağ çift tırnak işareti\",ndash:\"En tire\",mdash:\"Em tire\",iexcl:\"Ters ünlem işareti\",cent:\"Cent işareti\",pound:\"Pound işareti\",curren:\"Para birimi işareti\",yen:\"Yen işareti\",brvbar:\"Kırık bar\",sect:\"Bölüm işareti\",uml:\"İki sesli harfin ayrılması\",copy:\"Telif hakkı işareti\",ordf:\"Dişil sıralı gösterge\",laquo:\"Sol-işaret çift açı tırnak işareti\",\nnot:\"Not işareti\",reg:\"Kayıtlı işareti\",macr:\"Makron\",deg:\"Derece işareti\",sup2:\"İkili üstsimge\",sup3:\"Üçlü üstsimge\",acute:\"Aksan işareti\",micro:\"Mikro işareti\",para:\"Pilcrow işareti\",middot:\"Orta nokta\",cedil:\"Kedilla\",sup1:\"Üstsimge\",ordm:\"Eril sıralı gösterge\",raquo:\"Sağ işaret çift açı tırnak işareti\",frac14:\"Bayağı kesrin dörtte biri\",frac12:\"Bayağı kesrin bir yarım\",frac34:\"Bayağı kesrin dörtte üç\",iquest:\"Ters soru işareti\",Agrave:\"Aksanlı latin harfi\",Aacute:\"Aşırı aksanıyla Latin harfi\",\nAcirc:\"Çarpık Latin harfi\",Atilde:\"Tilde latin harfi\",Auml:\"Sesli harf ayrılımlıı latin harfi\",Aring:\"Halkalı latin büyük A harfi\",AElig:\"Latin büyük Æ harfi\",Ccedil:\"Latin büyük C harfi ile kedilla\",Egrave:\"Aksanlı latin büyük E harfi\",Eacute:\"Aşırı vurgulu latin büyük E harfi\",Ecirc:\"Çarpık latin büyük E harfi\",Euml:\"Sesli harf ayrılımlıı latin büyük E harfi\",Igrave:\"Aksanlı latin büyük I harfi\",Iacute:\"Aşırı aksanlı latin büyük I harfi\",Icirc:\"Çarpık latin büyük I harfi\",Iuml:\"Sesli harf ayrılımlıı latin büyük I harfi\",\nETH:\"Latin büyük Eth harfi\",Ntilde:\"Tildeli latin büyük N harfi\",Ograve:\"Aksanlı latin büyük O harfi\",Oacute:\"Aşırı aksanlı latin büyük O harfi\",Ocirc:\"Çarpık latin büyük O harfi\",Otilde:\"Tildeli latin büyük O harfi\",Ouml:\"Sesli harf ayrılımlı latin büyük O harfi\",times:\"Çarpma işareti\",Oslash:\"Vurgulu latin büyük O harfi\",Ugrave:\"Aksanlı latin büyük U harfi\",Uacute:\"Aşırı aksanlı latin büyük U harfi\",Ucirc:\"Çarpık latin büyük U harfi\",Uuml:\"Sesli harf ayrılımlı latin büyük U harfi\",Yacute:\"Aşırı aksanlı latin büyük Y harfi\",\nTHORN:\"Latin büyük Thorn harfi\",szlig:\"Latin küçük keskin s harfi\",agrave:\"Aksanlı latin küçük a harfi\",aacute:\"Aşırı aksanlı latin küçük a harfi\",acirc:\"Çarpık latin küçük a harfi\",atilde:\"Tildeli latin küçük a harfi\",auml:\"Sesli harf ayrılımlı latin küçük a harfi\",aring:\"Halkalı latin küçük a harfi\",aelig:\"Latin büyük æ harfi\",ccedil:\"Kedillalı latin küçük c harfi\",egrave:\"Aksanlı latin küçük e harfi\",eacute:\"Aşırı aksanlı latin küçük e harfi\",ecirc:\"Çarpık latin küçük e harfi\",euml:\"Sesli harf ayrılımlı latin küçük e harfi\",\nigrave:\"Aksanlı latin küçük i harfi\",iacute:\"Aşırı aksanlı latin küçük i harfi\",icirc:\"Çarpık latin küçük i harfi\",iuml:\"Sesli harf ayrılımlı latin küçük i harfi\",eth:\"Latin küçük eth harfi\",ntilde:\"Tildeli latin küçük n harfi\",ograve:\"Aksanlı latin küçük o harfi\",oacute:\"Aşırı aksanlı latin küçük o harfi\",ocirc:\"Çarpık latin küçük o harfi\",otilde:\"Tildeli latin küçük o harfi\",ouml:\"Sesli harf ayrılımlı latin küçük o harfi\",divide:\"Bölme işareti\",oslash:\"Vurgulu latin küçük o harfi\",ugrave:\"Aksanlı latin küçük u harfi\",\nuacute:\"Aşırı aksanlı latin küçük u harfi\",ucirc:\"Çarpık latin küçük u harfi\",uuml:\"Sesli harf ayrılımlı latin küçük u harfi\",yacute:\"Aşırı aksanlı latin küçük y harfi\",thorn:\"Latin küçük thorn harfi\",yuml:\"Sesli harf ayrılımlı latin küçük y harfi\",OElig:\"Latin büyük bağlı OE harfi\",oelig:\"Latin küçük bağlı oe harfi\",372:\"Çarpık latin büyük W harfi\",374:\"Çarpık latin büyük Y harfi\",373:\"Çarpık latin küçük w harfi\",375:\"Çarpık latin küçük y harfi\",sbquo:\"Tek düşük-9 tırnak işareti\",8219:\"Tek yüksek-ters-9 tırnak işareti\",\nbdquo:\"Çift düşük-9 tırnak işareti\",hellip:\"Yatay elips\",trade:\"Marka tescili işareti\",9658:\"Siyah sağ işaret işaretçisi\",bull:\"Koyu nokta\",rarr:\"Sağa doğru ok\",rArr:\"Sağa doğru çift ok\",hArr:\"Sol, sağ çift ok\",diams:\"Siyah elmas takımı\",asymp:\"Hemen hemen eşit\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/ug.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"ug\",{euro:\"ياۋرو بەلگىسى\",lsquo:\"يالاڭ پەش سول\",rsquo:\"يالاڭ پەش ئوڭ\",ldquo:\"قوش پەش سول\",rdquo:\"قوش پەش ئوڭ\",ndash:\"سىزىقچە\",mdash:\"سىزىق\",iexcl:\"ئۈندەش\",cent:\"تىيىن بەلگىسى\",pound:\"فوند ستېرلىڭ\",curren:\"پۇل بەلگىسى\",yen:\"ياپونىيە يىنى\",brvbar:\"ئۈزۈك بالداق\",sect:\"پاراگراف بەلگىسى\",uml:\"تاۋۇش ئايرىش بەلگىسى\",copy:\"نەشر ھوقۇقى بەلگىسى\",ordf:\"Feminine ordinal indicator\",laquo:\"قوش تىرناق سول\",not:\"غەيرى بەلگە\",reg:\"خەتلەتكەن تاۋار ماركىسى\",macr:\"سوزۇش بەلگىسى\",\ndeg:\"گىرادۇس بەلگىسى\",sup2:\"يۇقىرى ئىندېكىس 2\",sup3:\"يۇقىرى ئىندېكىس 3\",acute:\"ئۇرغۇ بەلگىسى\",micro:\"Micro sign\",para:\"ئابزاس بەلگىسى\",middot:\"ئوتتۇرا چېكىت\",cedil:\"ئاستىغا قوشۇلىدىغان بەلگە\",sup1:\"يۇقىرى ئىندېكىس 1\",ordm:\"Masculine ordinal indicator\",raquo:\"قوش تىرناق ئوڭ\",frac14:\"ئاددىي كەسىر تۆتتىن بىر\",frac12:\"ئاددىي كەسىر ئىككىدىن بىر\",frac34:\"ئاددىي كەسىر ئۈچتىن تۆرت\",iquest:\"Inverted question mark\",Agrave:\"Latin capital letter A with grave accent\",Aacute:\"Latin capital letter A with acute accent\",\nAcirc:\"Latin capital letter A with circumflex\",Atilde:\"Latin capital letter A with tilde\",Auml:\"Latin capital letter A with diaeresis\",Aring:\"Latin capital letter A with ring above\",AElig:\"Latin Capital letter Æ\",Ccedil:\"Latin capital letter C with cedilla\",Egrave:\"Latin capital letter E with grave accent\",Eacute:\"Latin capital letter E with acute accent\",Ecirc:\"Latin capital letter E with circumflex\",Euml:\"Latin capital letter E with diaeresis\",Igrave:\"Latin capital letter I with grave accent\",Iacute:\"Latin capital letter I with acute accent\",\nIcirc:\"Latin capital letter I with circumflex\",Iuml:\"Latin capital letter I with diaeresis\",ETH:\"Latin capital letter Eth\",Ntilde:\"Latin capital letter N with tilde\",Ograve:\"قوش پەش ئوڭ\",Oacute:\"Latin capital letter O with acute accent\",Ocirc:\"Latin capital letter O with circumflex\",Otilde:\"Latin capital letter O with tilde\",Ouml:\"Latin capital letter O with diaeresis\",times:\"Multiplication sign\",Oslash:\"Latin capital letter O with stroke\",Ugrave:\"Latin capital letter U with grave accent\",Uacute:\"Latin capital letter U with acute accent\",\nUcirc:\"Latin capital letter U with circumflex\",Uuml:\"Latin capital letter U with diaeresis\",Yacute:\"Latin capital letter Y with acute accent\",THORN:\"Latin capital letter Thorn\",szlig:\"Latin small letter sharp s\",agrave:\"Latin small letter a with grave accent\",aacute:\"Latin small letter a with acute accent\",acirc:\"Latin small letter a with circumflex\",atilde:\"Latin small letter a with tilde\",auml:\"Latin small letter a with diaeresis\",aring:\"Latin small letter a with ring above\",aelig:\"Latin small letter æ\",\nccedil:\"Latin small letter c with cedilla\",egrave:\"Latin small letter e with grave accent\",eacute:\"Latin small letter e with acute accent\",ecirc:\"Latin small letter e with circumflex\",euml:\"Latin small letter e with diaeresis\",igrave:\"Latin small letter i with grave accent\",iacute:\"Latin small letter i with acute accent\",icirc:\"Latin small letter i with circumflex\",iuml:\"Latin small letter i with diaeresis\",eth:\"Latin small letter eth\",ntilde:\"تىك موللاق سوئال بەلگىسى\",ograve:\"Latin small letter o with grave accent\",\noacute:\"Latin small letter o with acute accent\",ocirc:\"Latin small letter o with circumflex\",otilde:\"Latin small letter o with tilde\",ouml:\"Latin small letter o with diaeresis\",divide:\"بۆلۈش بەلگىسى\",oslash:\"Latin small letter o with stroke\",ugrave:\"Latin small letter u with grave accent\",uacute:\"Latin small letter u with acute accent\",ucirc:\"Latin small letter u with circumflex\",uuml:\"Latin small letter u with diaeresis\",yacute:\"Latin small letter y with acute accent\",thorn:\"Latin small letter thorn\",\nyuml:\"Latin small letter y with diaeresis\",OElig:\"Latin capital ligature OE\",oelig:\"Latin small ligature oe\",372:\"Latin capital letter W with circumflex\",374:\"Latin capital letter Y with circumflex\",373:\"Latin small letter w with circumflex\",375:\"Latin small letter y with circumflex\",sbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",hellip:\"Horizontal ellipsis\",trade:\"خەتلەتكەن تاۋار ماركىسى بەلگىسى\",9658:\"Black right-pointing pointer\",\nbull:\"Bullet\",rarr:\"ئوڭ يا ئوق\",rArr:\"ئوڭ قوش سىزىق يا ئوق\",hArr:\"ئوڭ سول قوش سىزىق يا ئوق\",diams:\"ئۇيۇل غىچ\",asymp:\"تەخمىنەن تەڭ\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/uk.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"uk\",{euro:\"Знак євро\",lsquo:\"Ліві одинарні лапки\",rsquo:\"Праві одинарні лапки\",ldquo:\"Ліві подвійні лапки\",rdquo:\"Праві подвійні лапки\",ndash:\"Середнє тире\",mdash:\"Довге тире\",iexcl:\"Перевернутий знак оклику\",cent:\"Знак цента\",pound:\"Знак фунта\",curren:\"Знак валюти\",yen:\"Знак єни\",brvbar:\"Переривчаста вертикальна лінія\",sect:\"Знак параграфу\",uml:\"Умлаут\",copy:\"Знак авторських прав\",ordf:\"Жіночий порядковий вказівник\",laquo:\"ліві вказівні подвійні кутові дужки\",\nnot:\"Заперечення\",reg:\"Знак охорони суміжних прав\",macr:\"Макрон\",deg:\"Знак градуса\",sup2:\"два у верхньому індексі\",sup3:\"три у верхньому індексі\",acute:\"Знак акута\",micro:\"Знак мікро\",para:\"Знак абзацу\",middot:\"Інтерпункт\",cedil:\"Седиль\",sup1:\"Один у верхньому індексі\",ordm:\"Чоловічий порядковий вказівник\",raquo:\"праві вказівні подвійні кутові дужки\",frac14:\"Одна четвертина\",frac12:\"Одна друга\",frac34:\"три четвертих\",iquest:\"Перевернутий знак питання\",Agrave:\"Велика латинська A з гравісом\",Aacute:\"Велика латинська А з акутом\",\nAcirc:\"Велика латинська А з циркумфлексом\",Atilde:\"Велика латинська А з тильдою\",Auml:\"Велике латинське А з умлаутом\",Aring:\"Велика латинська A з кільцем згори\",AElig:\"Велика латинська Æ\",Ccedil:\"Велика латинська C з седиллю\",Egrave:\"Велика латинська E з гравісом\",Eacute:\"Велика латинська E з акутом\",Ecirc:\"Велика латинська E з циркумфлексом\",Euml:\"Велика латинська А з умлаутом\",Igrave:\"Велика латинська I з гравісом\",Iacute:\"Велика латинська I з акутом\",Icirc:\"Велика латинська I з циркумфлексом\",\nIuml:\"Велика латинська І з умлаутом\",ETH:\"Велика латинська Eth\",Ntilde:\"Велика латинська N з тильдою\",Ograve:\"Велика латинська O з гравісом\",Oacute:\"Велика латинська O з акутом\",Ocirc:\"Велика латинська O з циркумфлексом\",Otilde:\"Велика латинська O з тильдою\",Ouml:\"Велика латинська О з умлаутом\",times:\"Знак множення\",Oslash:\"Велика латинська перекреслена O \",Ugrave:\"Велика латинська U з гравісом\",Uacute:\"Велика латинська U з акутом\",Ucirc:\"Велика латинська U з циркумфлексом\",Uuml:\"Велика латинська U з умлаутом\",\nYacute:\"Велика латинська Y з акутом\",THORN:\"Велика латинська Торн\",szlig:\"Мала латинська есцет\",agrave:\"Мала латинська a з гравісом\",aacute:\"Мала латинська a з акутом\",acirc:\"Мала латинська a з циркумфлексом\",atilde:\"Мала латинська a з тильдою\",auml:\"Мала латинська a з умлаутом\",aring:\"Мала латинська a з кільцем згори\",aelig:\"Мала латинська æ\",ccedil:\"Мала латинська C з седиллю\",egrave:\"Мала латинська e з гравісом\",eacute:\"Мала латинська e з акутом\",ecirc:\"Мала латинська e з циркумфлексом\",euml:\"Мала латинська e з умлаутом\",\nigrave:\"Мала латинська i з гравісом\",iacute:\"Мала латинська i з акутом\",icirc:\"Мала латинська i з циркумфлексом\",iuml:\"Мала латинська i з умлаутом\",eth:\"Мала латинська Eth\",ntilde:\"Мала латинська n з тильдою\",ograve:\"Мала латинська o з гравісом\",oacute:\"Мала латинська o з акутом\",ocirc:\"Мала латинська o з циркумфлексом\",otilde:\"Мала латинська o з тильдою\",ouml:\"Мала латинська o з умлаутом\",divide:\"Знак ділення\",oslash:\"Мала латинська перекреслена o\",ugrave:\"Мала латинська u з гравісом\",uacute:\"Мала латинська u з акутом\",\nucirc:\"Мала латинська u з циркумфлексом\",uuml:\"Мала латинська u з умлаутом\",yacute:\"Мала латинська y з акутом\",thorn:\"Мала латинська торн\",yuml:\"Мала латинська y з умлаутом\",OElig:\"Велика латинська лігатура OE\",oelig:\"Мала латинська лігатура oe\",372:\"Велика латинська W з циркумфлексом\",374:\"Велика латинська Y з циркумфлексом\",373:\"Мала латинська w з циркумфлексом\",375:\"Мала латинська y з циркумфлексом\",sbquo:\"Одиничні нижні лабки\",8219:\"Верхні одиничні обернені лабки\",bdquo:\"Подвійні нижні лабки\",\nhellip:\"Три крапки\",trade:\"Знак торгової марки\",9658:\"Чорний правий вказівник\",bull:\"Маркер списку\",rarr:\"Стрілка вправо\",rArr:\"Подвійна стрілка вправо\",hArr:\"Подвійна стрілка вліво-вправо\",diams:\"Чорний діамонт\",asymp:\"Наближено дорівнює\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/vi.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"vi\",{euro:\"Ký hiệu Euro\",lsquo:\"Dấu ngoặc đơn trái\",rsquo:\"Dấu ngoặc đơn phải\",ldquo:\"Dấu ngoặc đôi trái\",rdquo:\"Dấu ngoặc đôi phải\",ndash:\"Gạch ngang tiếng anh\",mdash:\"Gạch ngang Em\",iexcl:\"Chuyển đổi dấu chấm than\",cent:\"Ký tự tiền Mỹ\",pound:\"Ký tự tiền Anh\",curren:\"Ký tự tiền tệ\",yen:\"Ký tự tiền Yên Nhật\",brvbar:\"Thanh hỏng\",sect:\"Ký tự khu vực\",uml:\"Dấu tách đôi\",copy:\"Ký tự bản quyền\",ordf:\"Phần chỉ thị giống cái\",laquo:\"Chọn dấu ngoặc đôi trái\",not:\"Không có ký tự\",\nreg:\"Ký tự đăng ký\",macr:\"Dấu nguyên âm dài\",deg:\"Ký tự độ\",sup2:\"Chữ trồi lên trên dạng 2\",sup3:\"Chữ trồi lên trên dạng 3\",acute:\"Dấu trọng âm\",micro:\"Ký tự micro\",para:\"Ký tự đoạn văn\",middot:\"Dấu chấm tròn\",cedil:\"Dấu móc lưới\",sup1:\"Ký tự trồi lên cấp 1\",ordm:\"Ký tự biểu hiện giống đực\",raquo:\"Chọn dấu ngoặc đôi phải\",frac14:\"Tỉ lệ một phần tư\",frac12:\"Tỉ lệ một nửa\",frac34:\"Tỉ lệ ba phần tư\",iquest:\"Chuyển đổi dấu chấm hỏi\",Agrave:\"Ký tự la-tinh viết hoa A với dấu huyền\",Aacute:\"Ký tự la-tinh viết hoa A với dấu sắc\",\nAcirc:\"Ký tự la-tinh viết hoa A với dấu mũ\",Atilde:\"Ký tự la-tinh viết hoa A với dấu ngã\",Auml:\"Ký tự la-tinh viết hoa A với dấu hai chấm trên đầu\",Aring:\"Ký tự la-tinh viết hoa A với biểu tượng vòng tròn trên đầu\",AElig:\"Ký tự la-tinh viết hoa của Æ\",Ccedil:\"Ký tự la-tinh viết hoa C với dấu móc bên dưới\",Egrave:\"Ký tự la-tinh viết hoa E với dấu huyền\",Eacute:\"Ký tự la-tinh viết hoa E với dấu sắc\",Ecirc:\"Ký tự la-tinh viết hoa E với dấu mũ\",Euml:\"Ký tự la-tinh viết hoa E với dấu hai chấm trên đầu\",\nIgrave:\"Ký tự la-tinh viết hoa I với dấu huyền\",Iacute:\"Ký tự la-tinh viết hoa I với dấu sắc\",Icirc:\"Ký tự la-tinh viết hoa I với dấu mũ\",Iuml:\"Ký tự la-tinh viết hoa I với dấu hai chấm trên đầu\",ETH:\"Viết hoa của ký tự Eth\",Ntilde:\"Ký tự la-tinh viết hoa N với dấu ngã\",Ograve:\"Ký tự la-tinh viết hoa O với dấu huyền\",Oacute:\"Ký tự la-tinh viết hoa O với dấu sắc\",Ocirc:\"Ký tự la-tinh viết hoa O với dấu mũ\",Otilde:\"Ký tự la-tinh viết hoa O với dấu ngã\",Ouml:\"Ký tự la-tinh viết hoa O với dấu hai chấm trên đầu\",\ntimes:\"Ký tự phép toán nhân\",Oslash:\"Ký tự la-tinh viết hoa A với dấu ngã xuống\",Ugrave:\"Ký tự la-tinh viết hoa U với dấu huyền\",Uacute:\"Ký tự la-tinh viết hoa U với dấu sắc\",Ucirc:\"Ký tự la-tinh viết hoa U với dấu mũ\",Uuml:\"Ký tự la-tinh viết hoa U với dấu hai chấm trên đầu\",Yacute:\"Ký tự la-tinh viết hoa Y với dấu sắc\",THORN:\"Phần viết hoa của ký tự Thorn\",szlig:\"Ký tự viết nhỏ la-tinh của chữ s\",agrave:\"Ký tự la-tinh thường với dấu huyền\",aacute:\"Ký tự la-tinh thường với dấu sắc\",acirc:\"Ký tự la-tinh thường với dấu mũ\",\natilde:\"Ký tự la-tinh thường với dấu ngã\",auml:\"Ký tự la-tinh thường với dấu hai chấm trên đầu\",aring:\"Ký tự la-tinh viết thường với biểu tượng vòng tròn trên đầu\",aelig:\"Ký tự la-tinh viết thường của æ\",ccedil:\"Ký tự la-tinh viết thường của c với dấu móc bên dưới\",egrave:\"Ký tự la-tinh viết thường e với dấu huyền\",eacute:\"Ký tự la-tinh viết thường e với dấu sắc\",ecirc:\"Ký tự la-tinh viết thường e với dấu mũ\",euml:\"Ký tự la-tinh viết thường e với dấu hai chấm trên đầu\",igrave:\"Ký tự la-tinh viết thường i với dấu huyền\",\niacute:\"Ký tự la-tinh viết thường i với dấu sắc\",icirc:\"Ký tự la-tinh viết thường i với dấu mũ\",iuml:\"Ký tự la-tinh viết thường i với dấu hai chấm trên đầu\",eth:\"Ký tự la-tinh viết thường của eth\",ntilde:\"Ký tự la-tinh viết thường n với dấu ngã\",ograve:\"Ký tự la-tinh viết thường o với dấu huyền\",oacute:\"Ký tự la-tinh viết thường o với dấu sắc\",ocirc:\"Ký tự la-tinh viết thường o với dấu mũ\",otilde:\"Ký tự la-tinh viết thường o với dấu ngã\",ouml:\"Ký tự la-tinh viết thường o với dấu hai chấm trên đầu\",\ndivide:\"Ký hiệu phép tính chia\",oslash:\"Ký tự la-tinh viết thường o với dấu ngã\",ugrave:\"Ký tự la-tinh viết thường u với dấu huyền\",uacute:\"Ký tự la-tinh viết thường u với dấu sắc\",ucirc:\"Ký tự la-tinh viết thường u với dấu mũ\",uuml:\"Ký tự la-tinh viết thường u với dấu hai chấm trên đầu\",yacute:\"Ký tự la-tinh viết thường y với dấu sắc\",thorn:\"Ký tự la-tinh viết thường của chữ thorn\",yuml:\"Ký tự la-tinh viết thường y với dấu hai chấm trên đầu\",OElig:\"Ký tự la-tinh viết hoa gạch nối OE\",oelig:\"Ký tự la-tinh viết thường gạch nối OE\",\n372:\"Ký tự la-tinh viết hoa W với dấu mũ\",374:\"Ký tự la-tinh viết hoa Y với dấu mũ\",373:\"Ký tự la-tinh viết thường w với dấu mũ\",375:\"Ký tự la-tinh viết thường y với dấu mũ\",sbquo:\"Dấu ngoặc đơn thấp số-9\",8219:\"Dấu ngoặc đơn đảo ngược số-9\",bdquo:\"Gấp đôi dấu ngoặc đơn số-9\",hellip:\"Tĩnh dược chiều ngang\",trade:\"Ký tự thương hiệu\",9658:\"Ký tự trỏ về hướng bên phải màu đen\",bull:\"Ký hiệu\",rarr:\"Mũi tên hướng bên phải\",rArr:\"Mũi tên hướng bên phải dạng đôi\",hArr:\"Mũi tên hướng bên trái dạng đôi\",diams:\"Ký hiệu hình thoi\",\nasymp:\"Gần bằng với\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/zh-cn.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"zh-cn\",{euro:\"欧元符号\",lsquo:\"左单引号\",rsquo:\"右单引号\",ldquo:\"左双引号\",rdquo:\"右双引号\",ndash:\"短划线\",mdash:\"长划线\",iexcl:\"竖翻叹号\",cent:\"分币符号\",pound:\"英镑符号\",curren:\"货币符号\",yen:\"日元符号\",brvbar:\"间断条\",sect:\"节标记\",uml:\"分音符\",copy:\"版权所有标记\",ordf:\"阴性顺序指示符\",laquo:\"左指双尖引号\",not:\"非标记\",reg:\"注册标记\",macr:\"长音符\",deg:\"度标记\",sup2:\"上标二\",sup3:\"上标三\",acute:\"锐音符\",micro:\"微符\",para:\"段落标记\",middot:\"中间点\",cedil:\"下加符\",sup1:\"上标一\",ordm:\"阳性顺序指示符\",raquo:\"右指双尖引号\",frac14:\"普通分数四分之一\",frac12:\"普通分数二分之一\",frac34:\"普通分数四分之三\",iquest:\"竖翻问号\",\nAgrave:\"带抑音符的拉丁文大写字母 A\",Aacute:\"带锐音符的拉丁文大写字母 A\",Acirc:\"带扬抑符的拉丁文大写字母 A\",Atilde:\"带颚化符的拉丁文大写字母 A\",Auml:\"带分音符的拉丁文大写字母 A\",Aring:\"带上圆圈的拉丁文大写字母 A\",AElig:\"拉丁文大写字母 Ae\",Ccedil:\"带下加符的拉丁文大写字母 C\",Egrave:\"带抑音符的拉丁文大写字母 E\",Eacute:\"带锐音符的拉丁文大写字母 E\",Ecirc:\"带扬抑符的拉丁文大写字母 E\",Euml:\"带分音符的拉丁文大写字母 E\",Igrave:\"带抑音符的拉丁文大写字母 I\",Iacute:\"带锐音符的拉丁文大写字母 I\",Icirc:\"带扬抑符的拉丁文大写字母 I\",Iuml:\"带分音符的拉丁文大写字母 I\",ETH:\"拉丁文大写字母 Eth\",Ntilde:\"带颚化符的拉丁文大写字母 N\",Ograve:\"带抑音符的拉丁文大写字母 O\",Oacute:\"带锐音符的拉丁文大写字母 O\",Ocirc:\"带扬抑符的拉丁文大写字母 O\",Otilde:\"带颚化符的拉丁文大写字母 O\",\nOuml:\"带分音符的拉丁文大写字母 O\",times:\"乘号\",Oslash:\"带粗线的拉丁文大写字母 O\",Ugrave:\"带抑音符的拉丁文大写字母 U\",Uacute:\"带锐音符的拉丁文大写字母 U\",Ucirc:\"带扬抑符的拉丁文大写字母 U\",Uuml:\"带分音符的拉丁文大写字母 U\",Yacute:\"带抑音符的拉丁文大写字母 Y\",THORN:\"拉丁文大写字母 Thorn\",szlig:\"拉丁文小写字母清音 S\",agrave:\"带抑音符的拉丁文小写字母 A\",aacute:\"带锐音符的拉丁文小写字母 A\",acirc:\"带扬抑符的拉丁文小写字母 A\",atilde:\"带颚化符的拉丁文小写字母 A\",auml:\"带分音符的拉丁文小写字母 A\",aring:\"带上圆圈的拉丁文小写字母 A\",aelig:\"拉丁文小写字母 Ae\",ccedil:\"带下加符的拉丁文小写字母 C\",egrave:\"带抑音符的拉丁文小写字母 E\",eacute:\"带锐音符的拉丁文小写字母 E\",ecirc:\"带扬抑符的拉丁文小写字母 E\",euml:\"带分音符的拉丁文小写字母 E\",igrave:\"带抑音符的拉丁文小写字母 I\",\niacute:\"带锐音符的拉丁文小写字母 I\",icirc:\"带扬抑符的拉丁文小写字母 I\",iuml:\"带分音符的拉丁文小写字母 I\",eth:\"拉丁文小写字母 Eth\",ntilde:\"带颚化符的拉丁文小写字母 N\",ograve:\"带抑音符的拉丁文小写字母 O\",oacute:\"带锐音符的拉丁文小写字母 O\",ocirc:\"带扬抑符的拉丁文小写字母 O\",otilde:\"带颚化符的拉丁文小写字母 O\",ouml:\"带分音符的拉丁文小写字母 O\",divide:\"除号\",oslash:\"带粗线的拉丁文小写字母 O\",ugrave:\"带抑音符的拉丁文小写字母 U\",uacute:\"带锐音符的拉丁文小写字母 U\",ucirc:\"带扬抑符的拉丁文小写字母 U\",uuml:\"带分音符的拉丁文小写字母 U\",yacute:\"带抑音符的拉丁文小写字母 Y\",thorn:\"拉丁文小写字母 Thorn\",yuml:\"带分音符的拉丁文小写字母 Y\",OElig:\"拉丁文大写连字 Oe\",oelig:\"拉丁文小写连字 Oe\",372:\"带扬抑符的拉丁文大写字母 W\",374:\"带扬抑符的拉丁文大写字母 Y\",\n373:\"带扬抑符的拉丁文小写字母 W\",375:\"带扬抑符的拉丁文小写字母 Y\",sbquo:\"单下 9 形引号\",8219:\"单高横翻 9 形引号\",bdquo:\"双下 9 形引号\",hellip:\"水平省略号\",trade:\"商标标志\",9658:\"实心右指指针\",bull:\"加重号\",rarr:\"向右箭头\",rArr:\"向右双线箭头\",hArr:\"左右双线箭头\",diams:\"实心方块纸牌\",asymp:\"约等于\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/lang/zh.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.plugins.setLang(\"specialchar\",\"zh\",{euro:\"歐元符號\",lsquo:\"左單引號\",rsquo:\"右單引號\",ldquo:\"左雙引號\",rdquo:\"右雙引號\",ndash:\"短破折號\",mdash:\"長破折號\",iexcl:\"倒置的驚嘆號\",cent:\"美分符號\",pound:\"英鎊符號\",curren:\"貨幣符號\",yen:\"日圓符號\",brvbar:\"Broken bar\",sect:\"章節符號\",uml:\"分音符號\",copy:\"版權符號\",ordf:\"雌性符號\",laquo:\"左雙角括號\",not:\"Not 符號\",reg:\"註冊商標符號\",macr:\"長音符號\",deg:\"度數符號\",sup2:\"上標字 2\",sup3:\"上標字 3\",acute:\"尖音符號\",micro:\"Micro sign\",para:\"段落符號\",middot:\"中間點\",cedil:\"字母 C 下面的尾型符號 \",sup1:\"上標\",ordm:\"雄性符號\",raquo:\"右雙角括號\",frac14:\"四分之一符號\",frac12:\"Vulgar fraction one half\",\nfrac34:\"Vulgar fraction three quarters\",iquest:\"Inverted question mark\",Agrave:\"Latin capital letter A with grave accent\",Aacute:\"Latin capital letter A with acute accent\",Acirc:\"Latin capital letter A with circumflex\",Atilde:\"Latin capital letter A with tilde\",Auml:\"拉丁大寫字母 E 帶分音符號\",Aring:\"拉丁大寫字母 A 帶上圓圈\",AElig:\"拉丁大寫字母 Æ\",Ccedil:\"拉丁大寫字母 C 帶下尾符號\",Egrave:\"Latin capital letter E with grave accent\",Eacute:\"Latin capital letter E with acute accent\",Ecirc:\"Latin capital letter E with circumflex\",Euml:\"Latin capital letter E with diaeresis\",\nIgrave:\"Latin capital letter I with grave accent\",Iacute:\"Latin capital letter I with acute accent\",Icirc:\"Latin capital letter I with circumflex\",Iuml:\"Latin capital letter I with diaeresis\",ETH:\"Latin capital letter Eth\",Ntilde:\"Latin capital letter N with tilde\",Ograve:\"Latin capital letter O with grave accent\",Oacute:\"Latin capital letter O with acute accent\",Ocirc:\"Latin capital letter O with circumflex\",Otilde:\"Latin capital letter O with tilde\",Ouml:\"Latin capital letter O with diaeresis\",\ntimes:\"乘號\",Oslash:\"拉丁大寫字母 O 帶粗線符號\",Ugrave:\"Latin capital letter U with grave accent\",Uacute:\"Latin capital letter U with acute accent\",Ucirc:\"Latin capital letter U with circumflex\",Uuml:\"Latin capital letter U with diaeresis\",Yacute:\"Latin capital letter Y with acute accent\",THORN:\"Latin capital letter Thorn\",szlig:\"Latin small letter sharp s\",agrave:\"Latin small letter a with grave accent\",aacute:\"Latin small letter a with acute accent\",acirc:\"Latin small letter a with circumflex\",atilde:\"Latin small letter a with tilde\",\nauml:\"Latin small letter a with diaeresis\",aring:\"Latin small letter a with ring above\",aelig:\"Latin small letter æ\",ccedil:\"Latin small letter c with cedilla\",egrave:\"Latin small letter e with grave accent\",eacute:\"Latin small letter e with acute accent\",ecirc:\"Latin small letter e with circumflex\",euml:\"Latin small letter e with diaeresis\",igrave:\"Latin small letter i with grave accent\",iacute:\"Latin small letter i with acute accent\",icirc:\"Latin small letter i with circumflex\",iuml:\"Latin small letter i with diaeresis\",\neth:\"Latin small letter eth\",ntilde:\"Latin small letter n with tilde\",ograve:\"Latin small letter o with grave accent\",oacute:\"Latin small letter o with acute accent\",ocirc:\"Latin small letter o with circumflex\",otilde:\"Latin small letter o with tilde\",ouml:\"Latin small letter o with diaeresis\",divide:\"Division sign\",oslash:\"Latin small letter o with stroke\",ugrave:\"Latin small letter u with grave accent\",uacute:\"Latin small letter u with acute accent\",ucirc:\"Latin small letter u with circumflex\",\nuuml:\"Latin small letter u with diaeresis\",yacute:\"Latin small letter y with acute accent\",thorn:\"Latin small letter thorn\",yuml:\"Latin small letter y with diaeresis\",OElig:\"Latin capital ligature OE\",oelig:\"Latin small ligature oe\",372:\"Latin capital letter W with circumflex\",374:\"Latin capital letter Y with circumflex\",373:\"Latin small letter w with circumflex\",375:\"Latin small letter y with circumflex\",sbquo:\"Single low-9 quotation mark\",8219:\"Single high-reversed-9 quotation mark\",bdquo:\"Double low-9 quotation mark\",\nhellip:\"Horizontal ellipsis\",trade:\"Trade mark sign\",9658:\"Black right-pointing pointer\",bull:\"Bullet\",rarr:\"Rightwards arrow\",rArr:\"Rightwards double arrow\",hArr:\"Left right double arrow\",diams:\"Black diamond suit\",asymp:\"Almost equal to\"});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/specialchar/dialogs/specialchar.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.dialog.add(\"specialchar\",function(i){var e,l=i.lang.specialchar,k=function(c){var b,c=c.data?c.data.getTarget():new CKEDITOR.dom.element(c);if(\"a\"==c.getName()&&(b=c.getChild(0).getHtml()))c.removeClass(\"cke_light_background\"),e.hide(),c=i.document.createElement(\"span\"),c.setHtml(b),i.insertText(c.getText())},m=CKEDITOR.tools.addFunction(k),j,g=function(c,b){var a,b=b||c.data.getTarget();\"span\"==b.getName()&&(b=b.getParent());if(\"a\"==b.getName()&&(a=b.getChild(0).getHtml())){j&&d(null,j);\nvar f=e.getContentElement(\"info\",\"htmlPreview\").getElement();e.getContentElement(\"info\",\"charPreview\").getElement().setHtml(a);f.setHtml(CKEDITOR.tools.htmlEncode(a));b.getParent().addClass(\"cke_light_background\");j=b}},d=function(c,b){b=b||c.data.getTarget();\"span\"==b.getName()&&(b=b.getParent());\"a\"==b.getName()&&(e.getContentElement(\"info\",\"charPreview\").getElement().setHtml(\"&nbsp;\"),e.getContentElement(\"info\",\"htmlPreview\").getElement().setHtml(\"&nbsp;\"),b.getParent().removeClass(\"cke_light_background\"),\nj=void 0)},n=CKEDITOR.tools.addFunction(function(c){var c=new CKEDITOR.dom.event(c),b=c.getTarget(),a;a=c.getKeystroke();var f=\"rtl\"==i.lang.dir;switch(a){case 38:if(a=b.getParent().getParent().getPrevious())a=a.getChild([b.getParent().getIndex(),0]),a.focus(),d(null,b),g(null,a);c.preventDefault();break;case 40:if(a=b.getParent().getParent().getNext())if((a=a.getChild([b.getParent().getIndex(),0]))&&1==a.type)a.focus(),d(null,b),g(null,a);c.preventDefault();break;case 32:k({data:c});c.preventDefault();\nbreak;case f?37:39:if(a=b.getParent().getNext())a=a.getChild(0),1==a.type?(a.focus(),d(null,b),g(null,a),c.preventDefault(!0)):d(null,b);else if(a=b.getParent().getParent().getNext())(a=a.getChild([0,0]))&&1==a.type?(a.focus(),d(null,b),g(null,a),c.preventDefault(!0)):d(null,b);break;case f?39:37:(a=b.getParent().getPrevious())?(a=a.getChild(0),a.focus(),d(null,b),g(null,a),c.preventDefault(!0)):(a=b.getParent().getParent().getPrevious())?(a=a.getLast().getChild(0),a.focus(),d(null,b),g(null,a),c.preventDefault(!0)):\nd(null,b)}});return{title:l.title,minWidth:430,minHeight:280,buttons:[CKEDITOR.dialog.cancelButton],charColumns:17,onLoad:function(){for(var c=this.definition.charColumns,b=i.config.specialChars,a=CKEDITOR.tools.getNextId()+\"_specialchar_table_label\",f=['<table role=\"listbox\" aria-labelledby=\"'+a+'\" style=\"width: 320px; height: 100%; border-collapse: separate;\" align=\"center\" cellspacing=\"2\" cellpadding=\"2\" border=\"0\">'],d=0,g=b.length,h,e;d<g;){f.push('<tr role=\"presentation\">');for(var j=0;j<c;j++,\nd++){if(h=b[d]){h instanceof Array?(e=h[1],h=h[0]):(e=h.replace(\"&\",\"\").replace(\";\",\"\").replace(\"#\",\"\"),e=l[e]||h);var k=\"cke_specialchar_label_\"+d+\"_\"+CKEDITOR.tools.getNextNumber();f.push('<td class=\"cke_dark_background\" style=\"cursor: default\" role=\"presentation\"><a href=\"javascript: void(0);\" role=\"option\" aria-posinset=\"'+(d+1)+'\"',' aria-setsize=\"'+g+'\"',' aria-labelledby=\"'+k+'\"',' class=\"cke_specialchar\" title=\"',CKEDITOR.tools.htmlEncode(e),'\" onkeydown=\"CKEDITOR.tools.callFunction( '+n+\n', event, this )\" onclick=\"CKEDITOR.tools.callFunction('+m+', this); return false;\" tabindex=\"-1\"><span style=\"margin: 0 auto;cursor: inherit\">'+h+'</span><span class=\"cke_voice_label\" id=\"'+k+'\">'+e+\"</span></a>\")}else f.push('<td class=\"cke_dark_background\">&nbsp;');f.push(\"</td>\")}f.push(\"</tr>\")}f.push(\"</tbody></table>\",'<span id=\"'+a+'\" class=\"cke_voice_label\">'+l.options+\"</span>\");this.getContentElement(\"info\",\"charContainer\").getElement().setHtml(f.join(\"\"))},contents:[{id:\"info\",label:i.lang.common.generalTab,\ntitle:i.lang.common.generalTab,padding:0,align:\"top\",elements:[{type:\"hbox\",align:\"top\",widths:[\"320px\",\"90px\"],children:[{type:\"html\",id:\"charContainer\",html:\"\",onMouseover:g,onMouseout:d,focus:function(){var c=this.getElement().getElementsByTag(\"a\").getItem(0);setTimeout(function(){c.focus();g(null,c)},0)},onShow:function(){var c=this.getElement().getChild([0,0,0,0,0]);setTimeout(function(){c.focus();g(null,c)},0)},onLoad:function(c){e=c.sender}},{type:\"hbox\",align:\"top\",widths:[\"100%\"],children:[{type:\"vbox\",\nalign:\"top\",children:[{type:\"html\",html:\"<div></div>\"},{type:\"html\",id:\"charPreview\",className:\"cke_dark_background\",style:\"border:1px solid #eeeeee;font-size:28px;height:40px;width:70px;padding-top:9px;font-family:'Microsoft Sans Serif',Arial,Helvetica,Verdana;text-align:center;\",html:\"<div>&nbsp;</div>\"},{type:\"html\",id:\"htmlPreview\",className:\"cke_dark_background\",style:\"border:1px solid #eeeeee;font-size:14px;height:20px;width:70px;padding-top:2px;font-family:'Microsoft Sans Serif',Arial,Helvetica,Verdana;text-align:center;\",\nhtml:\"<div>&nbsp;</div>\"}]}]}]}]}]}});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/table/dialogs/table.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n(function(){function r(a){for(var e=0,l=0,k=0,m,g=a.$.rows.length;k<g;k++){m=a.$.rows[k];for(var d=e=0,c,b=m.cells.length;d<b;d++)c=m.cells[d],e+=c.colSpan;e>l&&(l=e)}return l}function o(a){return function(){var e=this.getValue(),e=!!(CKEDITOR.dialog.validate.integer()(e)&&0<e);e||(alert(a),this.select());return e}}function n(a,e){var l=function(g){return new CKEDITOR.dom.element(g,a.document)},n=a.editable(),m=a.plugins.dialogadvtab;return{title:a.lang.table.title,minWidth:310,minHeight:CKEDITOR.env.ie?\n310:280,onLoad:function(){var g=this,a=g.getContentElement(\"advanced\",\"advStyles\");if(a)a.on(\"change\",function(){var a=this.getStyle(\"width\",\"\"),b=g.getContentElement(\"info\",\"txtWidth\");b&&b.setValue(a,!0);a=this.getStyle(\"height\",\"\");(b=g.getContentElement(\"info\",\"txtHeight\"))&&b.setValue(a,!0)})},onShow:function(){var g=a.getSelection(),d=g.getRanges(),c,b=this.getContentElement(\"info\",\"txtRows\"),h=this.getContentElement(\"info\",\"txtCols\"),p=this.getContentElement(\"info\",\"txtWidth\"),f=this.getContentElement(\"info\",\n\"txtHeight\");\"tableProperties\"==e&&((g=g.getSelectedElement())&&g.is(\"table\")?c=g:0<d.length&&(CKEDITOR.env.webkit&&d[0].shrink(CKEDITOR.NODE_ELEMENT),c=a.elementPath(d[0].getCommonAncestor(!0)).contains(\"table\",1)),this._.selectedElement=c);c?(this.setupContent(c),b&&b.disable(),h&&h.disable()):(b&&b.enable(),h&&h.enable());p&&p.onChange();f&&f.onChange()},onOk:function(){var g=a.getSelection(),d=this._.selectedElement&&g.createBookmarks(),c=this._.selectedElement||l(\"table\"),b={};this.commitContent(b,\nc);if(b.info){b=b.info;if(!this._.selectedElement)for(var h=c.append(l(\"tbody\")),e=parseInt(b.txtRows,10)||0,f=parseInt(b.txtCols,10)||0,i=0;i<e;i++)for(var j=h.append(l(\"tr\")),k=0;k<f;k++)j.append(l(\"td\")).appendBogus();e=b.selHeaders;if(!c.$.tHead&&(\"row\"==e||\"both\"==e)){j=new CKEDITOR.dom.element(c.$.createTHead());h=c.getElementsByTag(\"tbody\").getItem(0);h=h.getElementsByTag(\"tr\").getItem(0);for(i=0;i<h.getChildCount();i++)f=h.getChild(i),f.type==CKEDITOR.NODE_ELEMENT&&!f.data(\"cke-bookmark\")&&\n(f.renameNode(\"th\"),f.setAttribute(\"scope\",\"col\"));j.append(h.remove())}if(null!==c.$.tHead&&!(\"row\"==e||\"both\"==e)){j=new CKEDITOR.dom.element(c.$.tHead);h=c.getElementsByTag(\"tbody\").getItem(0);for(k=h.getFirst();0<j.getChildCount();){h=j.getFirst();for(i=0;i<h.getChildCount();i++)f=h.getChild(i),f.type==CKEDITOR.NODE_ELEMENT&&(f.renameNode(\"td\"),f.removeAttribute(\"scope\"));h.insertBefore(k)}j.remove()}if(!this.hasColumnHeaders&&(\"col\"==e||\"both\"==e))for(j=0;j<c.$.rows.length;j++)f=new CKEDITOR.dom.element(c.$.rows[j].cells[0]),\nf.renameNode(\"th\"),f.setAttribute(\"scope\",\"row\");if(this.hasColumnHeaders&&!(\"col\"==e||\"both\"==e))for(i=0;i<c.$.rows.length;i++)j=new CKEDITOR.dom.element(c.$.rows[i]),\"tbody\"==j.getParent().getName()&&(f=new CKEDITOR.dom.element(j.$.cells[0]),f.renameNode(\"td\"),f.removeAttribute(\"scope\"));b.txtHeight?c.setStyle(\"height\",b.txtHeight):c.removeStyle(\"height\");b.txtWidth?c.setStyle(\"width\",b.txtWidth):c.removeStyle(\"width\");c.getAttribute(\"style\")||c.removeAttribute(\"style\")}if(this._.selectedElement)try{g.selectBookmarks(d)}catch(m){}else a.insertElement(c),\nsetTimeout(function(){var g=new CKEDITOR.dom.element(c.$.rows[0].cells[0]),b=a.createRange();b.moveToPosition(g,CKEDITOR.POSITION_AFTER_START);b.select()},0)},contents:[{id:\"info\",label:a.lang.table.title,elements:[{type:\"hbox\",widths:[null,null],styles:[\"vertical-align:top\"],children:[{type:\"vbox\",padding:0,children:[{type:\"text\",id:\"txtRows\",\"default\":3,label:a.lang.table.rows,required:!0,controlStyle:\"width:5em\",validate:o(a.lang.table.invalidRows),setup:function(a){this.setValue(a.$.rows.length)},\ncommit:k},{type:\"text\",id:\"txtCols\",\"default\":2,label:a.lang.table.columns,required:!0,controlStyle:\"width:5em\",validate:o(a.lang.table.invalidCols),setup:function(a){this.setValue(r(a))},commit:k},{type:\"html\",html:\"&nbsp;\"},{type:\"select\",id:\"selHeaders\",requiredContent:\"th\",\"default\":\"\",label:a.lang.table.headers,items:[[a.lang.table.headersNone,\"\"],[a.lang.table.headersRow,\"row\"],[a.lang.table.headersColumn,\"col\"],[a.lang.table.headersBoth,\"both\"]],setup:function(a){var d=this.getDialog();d.hasColumnHeaders=\n!0;for(var c=0;c<a.$.rows.length;c++){var b=a.$.rows[c].cells[0];if(b&&\"th\"!=b.nodeName.toLowerCase()){d.hasColumnHeaders=!1;break}}null!==a.$.tHead?this.setValue(d.hasColumnHeaders?\"both\":\"row\"):this.setValue(d.hasColumnHeaders?\"col\":\"\")},commit:k},{type:\"text\",id:\"txtBorder\",requiredContent:\"table[border]\",\"default\":a.filter.check(\"table[border]\")?1:0,label:a.lang.table.border,controlStyle:\"width:3em\",validate:CKEDITOR.dialog.validate.number(a.lang.table.invalidBorder),setup:function(a){this.setValue(a.getAttribute(\"border\")||\n\"\")},commit:function(a,d){this.getValue()?d.setAttribute(\"border\",this.getValue()):d.removeAttribute(\"border\")}},{id:\"cmbAlign\",type:\"select\",requiredContent:\"table[align]\",\"default\":\"\",label:a.lang.common.align,items:[[a.lang.common.notSet,\"\"],[a.lang.common.alignLeft,\"left\"],[a.lang.common.alignCenter,\"center\"],[a.lang.common.alignRight,\"right\"]],setup:function(a){this.setValue(a.getAttribute(\"align\")||\"\")},commit:function(a,d){this.getValue()?d.setAttribute(\"align\",this.getValue()):d.removeAttribute(\"align\")}}]},\n{type:\"vbox\",padding:0,children:[{type:\"hbox\",widths:[\"5em\"],children:[{type:\"text\",id:\"txtWidth\",requiredContent:\"table{width}\",controlStyle:\"width:5em\",label:a.lang.common.width,title:a.lang.common.cssLengthTooltip,\"default\":a.filter.check(\"table{width}\")?500>n.getSize(\"width\")?\"100%\":500:0,getValue:q,validate:CKEDITOR.dialog.validate.cssLength(a.lang.common.invalidCssLength.replace(\"%1\",a.lang.common.width)),onChange:function(){var a=this.getDialog().getContentElement(\"advanced\",\"advStyles\");a&&\na.updateStyle(\"width\",this.getValue())},setup:function(a){this.setValue(a.getStyle(\"width\"))},commit:k}]},{type:\"hbox\",widths:[\"5em\"],children:[{type:\"text\",id:\"txtHeight\",requiredContent:\"table{height}\",controlStyle:\"width:5em\",label:a.lang.common.height,title:a.lang.common.cssLengthTooltip,\"default\":\"\",getValue:q,validate:CKEDITOR.dialog.validate.cssLength(a.lang.common.invalidCssLength.replace(\"%1\",a.lang.common.height)),onChange:function(){var a=this.getDialog().getContentElement(\"advanced\",\"advStyles\");\na&&a.updateStyle(\"height\",this.getValue())},setup:function(a){(a=a.getStyle(\"height\"))&&this.setValue(a)},commit:k}]},{type:\"html\",html:\"&nbsp;\"},{type:\"text\",id:\"txtCellSpace\",requiredContent:\"table[cellspacing]\",controlStyle:\"width:3em\",label:a.lang.table.cellSpace,\"default\":a.filter.check(\"table[cellspacing]\")?1:0,validate:CKEDITOR.dialog.validate.number(a.lang.table.invalidCellSpacing),setup:function(a){this.setValue(a.getAttribute(\"cellSpacing\")||\"\")},commit:function(a,d){this.getValue()?d.setAttribute(\"cellSpacing\",\nthis.getValue()):d.removeAttribute(\"cellSpacing\")}},{type:\"text\",id:\"txtCellPad\",requiredContent:\"table[cellpadding]\",controlStyle:\"width:3em\",label:a.lang.table.cellPad,\"default\":a.filter.check(\"table[cellpadding]\")?1:0,validate:CKEDITOR.dialog.validate.number(a.lang.table.invalidCellPadding),setup:function(a){this.setValue(a.getAttribute(\"cellPadding\")||\"\")},commit:function(a,d){this.getValue()?d.setAttribute(\"cellPadding\",this.getValue()):d.removeAttribute(\"cellPadding\")}}]}]},{type:\"html\",align:\"right\",\nhtml:\"\"},{type:\"vbox\",padding:0,children:[{type:\"text\",id:\"txtCaption\",requiredContent:\"caption\",label:a.lang.table.caption,setup:function(a){this.enable();a=a.getElementsByTag(\"caption\");if(0<a.count()){var a=a.getItem(0),d=a.getFirst(CKEDITOR.dom.walker.nodeType(CKEDITOR.NODE_ELEMENT));d&&!d.equals(a.getBogus())?(this.disable(),this.setValue(a.getText())):(a=CKEDITOR.tools.trim(a.getText()),this.setValue(a))}},commit:function(e,d){if(this.isEnabled()){var c=this.getValue(),b=d.getElementsByTag(\"caption\");\nif(c)0<b.count()?(b=b.getItem(0),b.setHtml(\"\")):(b=new CKEDITOR.dom.element(\"caption\",a.document),d.getChildCount()?b.insertBefore(d.getFirst()):b.appendTo(d)),b.append(new CKEDITOR.dom.text(c,a.document));else if(0<b.count())for(c=b.count()-1;0<=c;c--)b.getItem(c).remove()}}},{type:\"text\",id:\"txtSummary\",requiredContent:\"table[summary]\",label:a.lang.table.summary,setup:function(a){this.setValue(a.getAttribute(\"summary\")||\"\")},commit:function(a,d){this.getValue()?d.setAttribute(\"summary\",this.getValue()):\nd.removeAttribute(\"summary\")}}]}]},m&&m.createAdvancedTab(a,null,\"table\")]}}var q=CKEDITOR.tools.cssLength,k=function(a){var e=this.id;a.info||(a.info={});a.info[e]=this.getValue()};CKEDITOR.dialog.add(\"table\",function(a){return n(a,\"table\")});CKEDITOR.dialog.add(\"tableProperties\",function(a){return n(a,\"tableProperties\")})})();"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/tabletools/dialogs/tableCell.js",
    "content": "﻿/*\n Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.md or http://ckeditor.com/license\n*/\nCKEDITOR.dialog.add(\"cellProperties\",function(f){var g=f.lang.table,c=g.cell,d=f.lang.common,h=CKEDITOR.dialog.validate,j=/^(\\d+(?:\\.\\d+)?)(px|%)$/,e={type:\"html\",html:\"&nbsp;\"},k=\"rtl\"==f.lang.dir,i=f.plugins.colordialog;return{title:c.title,minWidth:CKEDITOR.env.ie&&CKEDITOR.env.quirks?450:410,minHeight:CKEDITOR.env.ie&&(CKEDITOR.env.ie7Compat||CKEDITOR.env.quirks)?230:220,contents:[{id:\"info\",label:c.title,accessKey:\"I\",elements:[{type:\"hbox\",widths:[\"40%\",\"5%\",\"40%\"],children:[{type:\"vbox\",padding:0,\nchildren:[{type:\"hbox\",widths:[\"70%\",\"30%\"],children:[{type:\"text\",id:\"width\",width:\"100px\",label:d.width,validate:h.number(c.invalidWidth),onLoad:function(){var a=this.getDialog().getContentElement(\"info\",\"widthType\").getElement(),b=this.getInputElement(),c=b.getAttribute(\"aria-labelledby\");b.setAttribute(\"aria-labelledby\",[c,a.$.id].join(\" \"))},setup:function(a){var b=parseInt(a.getAttribute(\"width\"),10),a=parseInt(a.getStyle(\"width\"),10);!isNaN(b)&&this.setValue(b);!isNaN(a)&&this.setValue(a)},\ncommit:function(a){var b=parseInt(this.getValue(),10),c=this.getDialog().getValueOf(\"info\",\"widthType\");isNaN(b)?a.removeStyle(\"width\"):a.setStyle(\"width\",b+c);a.removeAttribute(\"width\")},\"default\":\"\"},{type:\"select\",id:\"widthType\",label:f.lang.table.widthUnit,labelStyle:\"visibility:hidden\",\"default\":\"px\",items:[[g.widthPx,\"px\"],[g.widthPc,\"%\"]],setup:function(a){(a=j.exec(a.getStyle(\"width\")||a.getAttribute(\"width\")))&&this.setValue(a[2])}}]},{type:\"hbox\",widths:[\"70%\",\"30%\"],children:[{type:\"text\",\nid:\"height\",label:d.height,width:\"100px\",\"default\":\"\",validate:h.number(c.invalidHeight),onLoad:function(){var a=this.getDialog().getContentElement(\"info\",\"htmlHeightType\").getElement(),b=this.getInputElement(),c=b.getAttribute(\"aria-labelledby\");b.setAttribute(\"aria-labelledby\",[c,a.$.id].join(\" \"))},setup:function(a){var b=parseInt(a.getAttribute(\"height\"),10),a=parseInt(a.getStyle(\"height\"),10);!isNaN(b)&&this.setValue(b);!isNaN(a)&&this.setValue(a)},commit:function(a){var b=parseInt(this.getValue(),\n10);isNaN(b)?a.removeStyle(\"height\"):a.setStyle(\"height\",CKEDITOR.tools.cssLength(b));a.removeAttribute(\"height\")}},{id:\"htmlHeightType\",type:\"html\",html:\"<br />\"+g.widthPx}]},e,{type:\"select\",id:\"wordWrap\",label:c.wordWrap,\"default\":\"yes\",items:[[c.yes,\"yes\"],[c.no,\"no\"]],setup:function(a){var b=a.getAttribute(\"noWrap\");(\"nowrap\"==a.getStyle(\"white-space\")||b)&&this.setValue(\"no\")},commit:function(a){\"no\"==this.getValue()?a.setStyle(\"white-space\",\"nowrap\"):a.removeStyle(\"white-space\");a.removeAttribute(\"noWrap\")}},\ne,{type:\"select\",id:\"hAlign\",label:c.hAlign,\"default\":\"\",items:[[d.notSet,\"\"],[d.alignLeft,\"left\"],[d.alignCenter,\"center\"],[d.alignRight,\"right\"]],setup:function(a){var b=a.getAttribute(\"align\");this.setValue(a.getStyle(\"text-align\")||b||\"\")},commit:function(a){var b=this.getValue();b?a.setStyle(\"text-align\",b):a.removeStyle(\"text-align\");a.removeAttribute(\"align\")}},{type:\"select\",id:\"vAlign\",label:c.vAlign,\"default\":\"\",items:[[d.notSet,\"\"],[d.alignTop,\"top\"],[d.alignMiddle,\"middle\"],[d.alignBottom,\n\"bottom\"],[c.alignBaseline,\"baseline\"]],setup:function(a){var b=a.getAttribute(\"vAlign\"),a=a.getStyle(\"vertical-align\");switch(a){case \"top\":case \"middle\":case \"bottom\":case \"baseline\":break;default:a=\"\"}this.setValue(a||b||\"\")},commit:function(a){var b=this.getValue();b?a.setStyle(\"vertical-align\",b):a.removeStyle(\"vertical-align\");a.removeAttribute(\"vAlign\")}}]},e,{type:\"vbox\",padding:0,children:[{type:\"select\",id:\"cellType\",label:c.cellType,\"default\":\"td\",items:[[c.data,\"td\"],[c.header,\"th\"]],\nsetup:function(a){this.setValue(a.getName())},commit:function(a){a.renameNode(this.getValue())}},e,{type:\"text\",id:\"rowSpan\",label:c.rowSpan,\"default\":\"\",validate:h.integer(c.invalidRowSpan),setup:function(a){(a=parseInt(a.getAttribute(\"rowSpan\"),10))&&1!=a&&this.setValue(a)},commit:function(a){var b=parseInt(this.getValue(),10);b&&1!=b?a.setAttribute(\"rowSpan\",this.getValue()):a.removeAttribute(\"rowSpan\")}},{type:\"text\",id:\"colSpan\",label:c.colSpan,\"default\":\"\",validate:h.integer(c.invalidColSpan),\nsetup:function(a){(a=parseInt(a.getAttribute(\"colSpan\"),10))&&1!=a&&this.setValue(a)},commit:function(a){var b=parseInt(this.getValue(),10);b&&1!=b?a.setAttribute(\"colSpan\",this.getValue()):a.removeAttribute(\"colSpan\")}},e,{type:\"hbox\",padding:0,widths:[\"60%\",\"40%\"],children:[{type:\"text\",id:\"bgColor\",label:c.bgColor,\"default\":\"\",setup:function(a){var b=a.getAttribute(\"bgColor\");this.setValue(a.getStyle(\"background-color\")||b)},commit:function(a){this.getValue()?a.setStyle(\"background-color\",this.getValue()):\na.removeStyle(\"background-color\");a.removeAttribute(\"bgColor\")}},i?{type:\"button\",id:\"bgColorChoose\",\"class\":\"colorChooser\",label:c.chooseColor,onLoad:function(){this.getElement().getParent().setStyle(\"vertical-align\",\"bottom\")},onClick:function(){f.getColorFromDialog(function(a){a&&this.getDialog().getContentElement(\"info\",\"bgColor\").setValue(a);this.focus()},this)}}:e]},e,{type:\"hbox\",padding:0,widths:[\"60%\",\"40%\"],children:[{type:\"text\",id:\"borderColor\",label:c.borderColor,\"default\":\"\",setup:function(a){var b=\na.getAttribute(\"borderColor\");this.setValue(a.getStyle(\"border-color\")||b)},commit:function(a){this.getValue()?a.setStyle(\"border-color\",this.getValue()):a.removeStyle(\"border-color\");a.removeAttribute(\"borderColor\")}},i?{type:\"button\",id:\"borderColorChoose\",\"class\":\"colorChooser\",label:c.chooseColor,style:(k?\"margin-right\":\"margin-left\")+\": 10px\",onLoad:function(){this.getElement().getParent().setStyle(\"vertical-align\",\"bottom\")},onClick:function(){f.getColorFromDialog(function(a){a&&this.getDialog().getContentElement(\"info\",\n\"borderColor\").setValue(a);this.focus()},this)}}:e]}]}]}]}],onShow:function(){this.cells=CKEDITOR.plugins.tabletools.getSelectedCells(this._.editor.getSelection());this.setupContent(this.cells[0])},onOk:function(){for(var a=this._.editor.getSelection(),b=a.createBookmarks(),c=this.cells,d=0;d<c.length;d++)this.commitContent(c[d]);this._.editor.forceNextSelectionCheck();a.selectBookmarks(b);this._.editor.selectionChange()}}});"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/wsc/LICENSE.md",
    "content": "Software License Agreement\r\n==========================\r\n\r\n**CKEditor WSC Plugin**\r\nCopyright &copy; 2012, [CKSource](http://cksource.com) - Frederico Knabben. All rights reserved.\r\n\r\nLicensed under the terms of any of the following licenses at your choice:\r\n\r\n*   GNU General Public License Version 2 or later (the \"GPL\"):\r\n    http://www.gnu.org/licenses/gpl.html\r\n\r\n*   GNU Lesser General Public License Version 2.1 or later (the \"LGPL\"):\r\n    http://www.gnu.org/licenses/lgpl.html\r\n\r\n*   Mozilla Public License Version 1.1 or later (the \"MPL\"):\r\n    http://www.mozilla.org/MPL/MPL-1.1.html\r\n\r\nYou are not required to, but if you want to explicitly declare the license you have chosen to be bound to when using, reproducing, modifying and distributing this software, just include a text file titled \"legal.txt\" in your version of this software, indicating your license choice.\r\n\r\nSources of Intellectual Property Included in this plugin\r\n--------------------------------------------------------\r\n\r\nWhere not otherwise indicated, all plugin content is authored by CKSource engineers and consists of CKSource-owned intellectual property. In some specific instances, the plugin will incorporate work done by developers outside of CKSource with their express permission.\r\n\r\nTrademarks\r\n----------\r\n\r\nCKEditor is a trademark of CKSource - Frederico Knabben. All other brand and product names are trademarks, registered trademarks or service marks of their respective holders.\r\n"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/wsc/README.md",
    "content": "CKEditor WebSpellChecker Plugin\r\n===============================\r\n\r\nThis plugin brings Web Spell Checker (WSC) into CKEditor.\r\n\r\nWSC is \"installation-less\", using the web-services of [WebSpellChecker.net](http://www.webspellchecker.net/). It's an out of the box solution.\r\n\r\nInstallation\r\n------------\r\n\r\n1. Clone/copy this repository contents in a new \"plugins/wsc\" folder in your CKEditor installation.\r\n2. Enable the \"wsc\" plugin in the CKEditor configuration file (config.js):\r\n\r\n        config.extraPlugins = 'wsc';\r\n\r\nThat's all. WSC will appear on the editor toolbar and will be ready to use.\r\n\r\nLicense\r\n-------\r\n\r\nLicensed under the terms of any of the following licenses at your choice: [GPL](http://www.gnu.org/licenses/gpl.html), [LGPL](http://www.gnu.org/licenses/lgpl.html) and [MPL](http://www.mozilla.org/MPL/MPL-1.1.html).\r\n\r\nSee LICENSE.md for more information.\r\n\r\nDeveloped in cooperation with [WebSpellChecker.net](http://www.webspellchecker.net/).\r\n"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/wsc/dialogs/ciframe.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n<!--\nCopyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n-->\n<html>\n<head>\n\t<title></title>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n\t<script type=\"text/javascript\">\n\nfunction gup( name )\n{\n\tname = name.replace( /[\\[]/, '\\\\\\[' ).replace( /[\\]]/, '\\\\\\]' ) ;\n\tvar regexS = '[\\\\?&]' + name + '=([^&#]*)' ;\n\tvar regex = new RegExp( regexS ) ;\n\tvar results = regex.exec( window.location.href ) ;\n\n\tif ( results )\n\t\treturn results[ 1 ] ;\n\telse\n\t\treturn '' ;\n}\n\nvar interval;\n\nfunction sendData2Master()\n{\n\tvar destination = window.parent.parent ;\n\ttry\n\t{\n\t\tif ( destination.XDTMaster )\n\t\t{\n\t\t\tvar t = destination.XDTMaster.read( [ gup( 'cmd' ), gup( 'data' ) ] ) ;\n\t\t\twindow.clearInterval( interval ) ;\n\t\t}\n\t}\n\tcatch (e) {}\n}\n\nfunction OnMessage (event) {\n\t        var message = event.data;\n\t        var destination = window.parent.parent;\n\t        destination.XDTMaster.read( [ 'end', message, 'fpm' ] ) ;\n}\n\nfunction listenPostMessage() {\n    if (window.addEventListener) { // all browsers except IE before version 9\n            window.addEventListener (\"message\", OnMessage, false);\n    }else {\n            if (window.attachEvent) { // IE before version 9\n                        window.attachEvent(\"onmessage\", OnMessage);\n                }\n        }\n}\n\nfunction onLoad()\n{\n\tinterval = window.setInterval( sendData2Master, 100 );\n\tlistenPostMessage();\n}\n\n</script>\n</head>\n<body onload=\"onLoad()\"><p></p></body>\n</html>\n"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/wsc/dialogs/tmp.html",
    "content": "<!DOCTYPE html>\n<html>\n\t<head>\n\t\t<meta charset=\"UTF-8\">\n\t\t<title>iframe</title>\n\n\t\t<style>\n\t\t\thtml,body{\n\t\t\t\tmargin: 0;\n\t\t\t\theight: 100%;\n\t\t\t\tfont: 13px/1.555 \"Trebuchet MS\", sans-serif;\n\t\t\t}\n\t\t\ta{\n\t\t\t    color: #888;\n\t\t\t    font-weight: bold;\n\t\t\t    text-decoration: none;\n\t\t\t    border-bottom: 1px solid #888;\n\t\t\t}\n\t\t\t.main-box {\n\t\t\t\tcolor:#252525;\n\t\t\t\tpadding: 3px 5px;\n\t\t\t\ttext-align: justify;\n\t\t\t}\n\t\t\t.main-box p{margin: 0 0 14px;}\n\t\t\t.main-box .cerr{\n\t\t\t    color: #f00000;\n\t\t\t    border-bottom-color: #f00000;\n\t\t\t}\n\t\t</style>\n\t</head>\n\t<body>\n\t\t<div id=\"content\" class=\"main-box\"></div>\n\t\t<iframe src=\"\" frameborder=\"0\" id=\"spelltext\" name=\"spelltext\" style=\"display:none; width: 100%\" ></iframe>\n\t\t<iframe src=\"\" frameborder=\"0\" id=\"loadsuggestfirst\" name=\"loadsuggestfirst\" style=\"display:none; width: 100%\" ></iframe>\n\t\t<iframe src=\"\" frameborder=\"0\" id=\"loadspellsuggestall\" name=\"loadspellsuggestall\" style=\"display:none; width: 100%\" ></iframe>\n\t\t<iframe src=\"\" frameborder=\"0\" id=\"loadOptionsForm\" name=\"loadOptionsForm\" style=\"display:none; width: 100%\" ></iframe>\n\t\t<script>\n\t\t(function(window) {\n\t\t\t// Constructor Manager PostMessage\n\n\t\t\tvar ManagerPostMessage = function() {\n\t\t\t\tvar _init = function(handler) {\n\t\t\t\t\tif (document.addEventListener) {\n\t\t\t\t\t\twindow.addEventListener('message', handler, false);\n\t\t\t\t\t} else {\n\t\t\t\t\t\twindow.attachEvent(\"onmessage\", handler);\n                    }\n                };\n\t\t\t\tvar _sendCmd = function(o) {\n\t\t\t\t\tvar str,\n\t\t\t\t\t\ttype = Object.prototype.toString,\n\t\t\t\t\t\tfn = o.fn || null,\n\t\t\t\t\t\tid = o.id || '',\n\t\t\t\t\t\ttarget = o.target || window,\n\t\t\t\t\t\tmessage = o.message || { 'id': id };\n\n\t\t\t\t\tif (type.call(o.message) == \"[object Object]\") {\n\t\t\t\t\t\t(o.message['id']) ? o.message['id'] : o.message['id'] = id;\n\t\t\t\t\t\tmessage = o.message;\n                    }\n                    str = JSON.stringify(message, fn);\n\t\t\t\t\ttarget.postMessage(str, '*');\n\t\t\t\t};\n\n\t\t\t\treturn {\n\t\t\t\t\tinit: _init,\n\t\t\t\t\tsend: _sendCmd\n\t\t\t\t};\n\t\t\t};\n\n\t\t\tvar manageMessageTmp = new ManagerPostMessage;\n\n\n\t\t\t\tvar appString = (function(){\n\t\t\t\t\tvar spell = parent.CKEDITOR.config.wsc.DefaultParams.scriptPath;\n\t\t\t\t\tvar serverUrl = parent.CKEDITOR.config.wsc.DefaultParams.serviceHost;\n\t\t\t\t\treturn serverUrl + spell;\n\t\t\t\t})();\n\n\t\t\t\tfunction loadScript(src, callback) {\n\t\t\t\t    var scriptTag = document.createElement(\"script\");\n\t\t\t\t   \t\tscriptTag.type = \"text/javascript\";\n\t\t\t\t   \tcallback ? callback : callback = function() {};\n\t\t\t\t    if(scriptTag.readyState) {\n\t\t\t\t        //IE\n\t\t\t\t        scriptTag.onreadystatechange = function() {\n\t\t\t\t            if (scriptTag.readyState == \"loaded\" ||\n\t\t\t\t            scriptTag.readyState == \"complete\") {\n\t\t\t\t                scriptTag.onreadystatechange = null;\n\t\t\t\t                setTimeout(function(){scriptTag.parentNode.removeChild(scriptTag)},1);\n\t\t\t\t                callback();\n\t\t\t\t            }\n\t\t\t\t        };\n\t\t\t\t    }else{\n\t\t\t\t        //Others\n\t\t\t\t        scriptTag.onload = function() {\n\t\t\t\t           setTimeout(function(){scriptTag.parentNode.removeChild(scriptTag)},1);\n\t\t\t\t           callback();\n\t\t\t\t        };\n                    }\n                    scriptTag.src = src;\n\t\t\t\t    document.getElementsByTagName(\"head\")[0].appendChild(scriptTag);\n                }\n            window.onload = function(){\n\t\t\t\t\t loadScript(appString, function(){\n\t\t\t\t\t\tmanageMessageTmp.send({\n\t\t\t\t\t\t\t'id': 'iframeOnload',\n\t\t\t\t\t\t\t'target': window.parent\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t})(this);\n\t\t</script>\n\t</body>\n</html>\n"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/wsc/dialogs/tmpFrameset.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\">\n<!--\nCopyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n-->\n<html>\n<head>\n\t<title></title>\n\t<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n\t<script type=\"text/javascript\">\n\nfunction doLoadScript( url )\n{\n\tif ( !url )\n\t\treturn false ;\n\n\tvar s = document.createElement( \"script\" ) ;\n\ts.type = \"text/javascript\" ;\n\ts.src = url ;\n\tdocument.getElementsByTagName( \"head\" )[ 0 ].appendChild( s ) ;\n\n\treturn true ;\n}\n\nvar opener;\nfunction tryLoad()\n{\n\topener = window.parent;\n\n\t// get access to global parameters\n\tvar oParams = window.opener.oldFramesetPageParams;\n\n\t// make frameset rows string prepare\n\tvar sFramesetRows = ( parseInt( oParams.firstframeh, 10 ) || '30') + \",*,\" + ( parseInt( oParams.thirdframeh, 10 ) || '150' ) + ',0' ;\n\tdocument.getElementById( 'itFrameset' ).rows = sFramesetRows ;\n\n\t// dynamic including init frames and crossdomain transport code\n\t// from config sproxy_js_frameset url\n\tvar addScriptUrl = oParams.sproxy_js_frameset ;\n\tdoLoadScript( addScriptUrl ) ;\n}\n\n\t</script>\n</head>\n\n<frameset id=\"itFrameset\" onload=\"tryLoad();\" border=\"0\" rows=\"30,*,*,0\">\n    <frame scrolling=\"no\" framespacing=\"0\" frameborder=\"0\" noresize=\"noresize\" marginheight=\"0\" marginwidth=\"2\" src=\"\" name=\"navbar\"></frame>\n    <frame scrolling=\"auto\" framespacing=\"0\" frameborder=\"0\" noresize=\"noresize\" marginheight=\"0\" marginwidth=\"0\" src=\"\" name=\"mid\"></frame>\n    <frame scrolling=\"no\" framespacing=\"0\" frameborder=\"0\" noresize=\"noresize\" marginheight=\"1\" marginwidth=\"1\" src=\"\" name=\"bot\"></frame>\n    <frame scrolling=\"no\" framespacing=\"0\" frameborder=\"0\" noresize=\"noresize\" marginheight=\"1\" marginwidth=\"1\" src=\"\" name=\"spellsuggestall\"></frame>\n</frameset>\n</html>\n"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/wsc/dialogs/wsc.css",
    "content": "/*\nCopyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.html or http://ckeditor.com/license\n*/\n\nhtml, body\n{\n\tbackground-color: transparent;\n\tmargin: 0px;\n\tpadding: 0px;\n}\n\nbody\n{\n\tpadding: 10px;\n}\n\nbody, td, input, select, textarea\n{\n\tfont-size: 11px;\n\tfont-family: 'Microsoft Sans Serif' , Arial, Helvetica, Verdana;\n}\n\n.midtext\n{\n\tpadding:0px;\n\tmargin:10px;\n}\n\n.midtext p\n{\n\tpadding:0px;\n\tmargin:10px;\n}\n\n.Button\n{\n\tborder: #737357 1px solid;\n\tcolor: #3b3b1f;\n\tbackground-color: #c7c78f;\n}\n\n.PopupTabArea\n{\n\tcolor: #737357;\n\tbackground-color: #e3e3c7;\n}\n\n.PopupTitleBorder\n{\n\tborder-bottom: #d5d59d 1px solid;\n}\n.PopupTabEmptyArea\n{\n\tpadding-left: 10px;\n\tborder-bottom: #d5d59d 1px solid;\n}\n\n.PopupTab, .PopupTabSelected\n{\n\tborder-right: #d5d59d 1px solid;\n\tborder-top: #d5d59d 1px solid;\n\tborder-left: #d5d59d 1px solid;\n\tpadding: 3px 5px 3px 5px;\n\tcolor: #737357;\n}\n\n.PopupTab\n{\n\tmargin-top: 1px;\n\tborder-bottom: #d5d59d 1px solid;\n\tcursor: pointer;\n}\n\n.PopupTabSelected\n{\n\tfont-weight: bold;\n\tcursor: default;\n\tpadding-top: 4px;\n\tborder-bottom: #f1f1e3 1px solid;\n\tbackground-color: #f1f1e3;\n}\n"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/wsc/dialogs/wsc.js",
    "content": "﻿/*\n Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.html or http://ckeditor.com/license\n*/\n(function(){function w(a){if(!a)throw\"Languages-by-groups list are required for construct selectbox\";var c=[],d=\"\",f;for(f in a)for(var g in a[f]){var h=a[f][g];\"en_US\"==h?d=h:c.push(h)}c.sort();d&&c.unshift(d);return{getCurrentLangGroup:function(c){a:{for(var d in a)for(var f in a[d])if(f.toUpperCase()===c.toUpperCase()){c=d;break a}c=\"\"}return c},setLangList:function(){var c={},d;for(d in a)for(var f in a[d])c[a[d][f]]=f;return c}()}}var e=function(){var a=function(a,b,f){var f=f||{},g=f.expires;\nif(\"number\"==typeof g&&g){var h=new Date;h.setTime(h.getTime()+1E3*g);g=f.expires=h}g&&g.toUTCString&&(f.expires=g.toUTCString());var b=encodeURIComponent(b),a=a+\"=\"+b,e;for(e in f)b=f[e],a+=\"; \"+e,!0!==b&&(a+=\"=\"+b);document.cookie=a};return{postMessage:{init:function(a){document.addEventListener?window.addEventListener(\"message\",a,!1):window.attachEvent(\"onmessage\",a)},send:function(a){var b=a.fn||null,f=a.id||\"\",g=a.target||window,h=a.message||{id:f};\"[object Object]\"==Object.prototype.toString.call(a.message)&&\n(a.message.id||(a.message.id=f),h=a.message);a=window.JSON.stringify(h,b);g.postMessage(a,\"*\")}},hash:{create:function(){},parse:function(){}},cookie:{set:a,get:function(a){return(a=document.cookie.match(RegExp(\"(?:^|; )\"+a.replace(/([\\.$?*|{}\\(\\)\\[\\]\\\\\\/\\+^])/g,\"\\\\$1\")+\"=([^;]*)\")))?decodeURIComponent(a[1]):void 0},remove:function(c){a(c,\"\",{expires:-1})}}}}(),a=a||{};a.TextAreaNumber=null;a.load=!0;a.cmd={SpellTab:\"spell\",Thesaurus:\"thes\",GrammTab:\"grammar\"};a.dialog=null;a.optionNode=null;a.selectNode=\nnull;a.grammerSuggest=null;a.textNode={};a.iframeMain=null;a.dataTemp=\"\";a.div_overlay=null;a.textNodeInfo={};a.selectNode={};a.selectNodeResponce={};a.langList=null;a.langSelectbox=null;a.banner=\"\";a.show_grammar=null;a.div_overlay_no_check=null;a.targetFromFrame={};a.onLoadOverlay=null;a.LocalizationComing={};a.OverlayPlace=null;a.LocalizationButton={ChangeTo:{instance:null,text:\"Change to\"},ChangeAll:{instance:null,text:\"Change All\"},IgnoreWord:{instance:null,text:\"Ignore word\"},IgnoreAllWords:{instance:null,\ntext:\"Ignore all words\"},Options:{instance:null,text:\"Options\",optionsDialog:{instance:null}},AddWord:{instance:null,text:\"Add word\"},FinishChecking:{instance:null,text:\"Finish Checking\"}};a.LocalizationLabel={ChangeTo:{instance:null,text:\"Change to\"},Suggestions:{instance:null,text:\"Suggestions\"}};var x=function(b){for(var c in b)b[c].instance.getElement().setText(a.LocalizationComing[c])},y=function(b){for(var c in b){if(!b[c].instance.setLabel)break;b[c].instance.setLabel(a.LocalizationComing[c])}},\nj,p;a.framesetHtml=function(b){return'<iframe src=\"'+a.templatePath+'\" id='+a.iframeNumber+\"_\"+b+' frameborder=\"0\" allowtransparency=\"1\" style=\"width:100%;border: 1px solid #AEB3B9;overflow: auto;background:#fff; border-radius: 3px;\"></iframe>'};a.setIframe=function(b,c){var d=a.framesetHtml(c);return b.getElement().setHtml(d)};a.setCurrentIframe=function(b){a.setIframe(a.dialog._.contents[b].Content,b)};a.setHeightBannerFrame=function(){var b=a.dialog.getContentElement(\"SpellTab\",\"banner\").getElement(),\nc=a.dialog.getContentElement(\"GrammTab\",\"banner\").getElement(),d=a.dialog.getContentElement(\"Thesaurus\",\"banner\").getElement();b.setStyle(\"height\",\"90px\");c.setStyle(\"height\",\"90px\");d.setStyle(\"height\",\"90px\")};a.setHeightFrame=function(){document.getElementById(a.iframeNumber+\"_\"+a.dialog._.currentTabId).style.height=\"240px\"};a.sendData=function(b){var c=b._.currentTabId,d=b._.contents[c].Content,f,g;a.setIframe(d,c);b.parts.tabs.removeAllListeners();b.parts.tabs.on(\"click\",function(h){h=h||window.event;\nh.data.getTarget().is(\"a\")&&c!=b._.currentTabId&&(c=b._.currentTabId,d=b._.contents[c].Content,f=a.iframeNumber+\"_\"+c,a.div_overlay.setEnable(),d.getElement().getChildCount()?t(a.targetFromFrame[f],a.cmd[c]):(a.setIframe(d,c),g=document.getElementById(f),a.targetFromFrame[f]=g.contentWindow))})};a.buildSelectLang=function(a){var c=new CKEDITOR.dom.element(\"div\"),d=new CKEDITOR.dom.element(\"select\"),a=\"wscLang\"+a;c.addClass(\"cke_dialog_ui_input_select\");c.setAttribute(\"role\",\"presentation\");c.setStyles({height:\"auto\",\nposition:\"absolute\",right:\"0\",top:\"-1px\",width:\"160px\",\"white-space\":\"normal\"});d.setAttribute(\"id\",a);d.addClass(\"cke_dialog_ui_input_select\");d.setStyles({width:\"160px\"});c.append(d);return c};a.buildOptionLang=function(b,c){var d=document.getElementById(\"wscLang\"+c),f=document.createDocumentFragment(),g,h,e=[];if(0===d.options.length){for(g in b)e.push([g,b[g]]);e.sort();for(var k=0;k<e.length;k++)g=document.createElement(\"option\"),g.setAttribute(\"value\",e[k][1]),h=document.createTextNode(e[k][0]),\ng.appendChild(h),e[k][1]==a.selectingLang&&g.setAttribute(\"selected\",\"selected\"),f.appendChild(g);d.appendChild(f)}};a.buildOptionSynonyms=function(b){b=a.selectNodeResponce[b];a.selectNode.synonyms.clear();for(var c=0;c<b.length;c++)a.selectNode.synonyms.add(b[c],b[c]);a.selectNode.synonyms.getInputElement().$.firstChild.selected=!0;a.textNode.Thesaurus.setValue(a.selectNode.synonyms.getInputElement().getValue())};var q=function(a){var c=document,d=a.target||c.body,f=a.id||\"overlayBlock\",g=a.opacity||\n\"0.9\",a=a.background||\"#f1f1f1\",e=c.getElementById(f),i=e||c.createElement(\"div\");i.style.cssText=\"position: absolute;top:30px;bottom:41px;left:1px;right:1px;z-index: 10020;padding:0;margin:0;background:\"+a+\";opacity: \"+g+\";filter: alpha(opacity=\"+100*g+\");display: none;\";i.id=f;e||d.appendChild(i);return{setDisable:function(){i.style.display=\"none\"},setEnable:function(){i.style.display=\"block\"}}},z=function(b,c,d){var f=new CKEDITOR.dom.element(\"div\"),g=new CKEDITOR.dom.element(\"input\"),e=new CKEDITOR.dom.element(\"label\"),\ni=\"wscGrammerSuggest\"+b+\"_\"+c;f.addClass(\"cke_dialog_ui_input_radio\");f.setAttribute(\"role\",\"presentation\");f.setStyles({width:\"97%\",padding:\"5px\",\"white-space\":\"normal\"});g.setAttributes({type:\"radio\",value:c,name:\"wscGrammerSuggest\",id:i});g.setStyles({\"float\":\"left\"});g.on(\"click\",function(b){a.textNode.GrammTab.setValue(b.sender.getValue())});d&&g.setAttribute(\"checked\",!0);g.addClass(\"cke_dialog_ui_radio_input\");e.appendText(b);e.setAttribute(\"for\",i);e.setStyles({display:\"block\",\"line-height\":\"16px\",\n\"margin-left\":\"18px\",\"white-space\":\"normal\"});f.append(g);f.append(e);return f},u=function(a){a=a||\"true\";null!==a&&\"false\"==a&&m()},n=function(b){var c=new w(b),b=\"wscLang\"+a.dialog.getParentEditor().name,b=document.getElementById(b),d=a.iframeNumber+\"_\"+a.dialog._.currentTabId;a.buildOptionLang(c.setLangList,a.dialog.getParentEditor().name);v[c.getCurrentLangGroup(a.selectingLang)]();u(a.show_grammar);b.onchange=function(){v[c.getCurrentLangGroup(this.value)]();u(a.show_grammar);a.div_overlay.setEnable();\na.selectingLang=this.value;e.postMessage.send({message:{changeLang:a.selectingLang,text:a.dataTemp},target:a.targetFromFrame[d],id:\"selectionLang_outer__page\"})}},A=function(b){if(\"no_any_suggestions\"==b){b=\"No suggestions\";a.LocalizationButton.ChangeTo.instance.disable();a.LocalizationButton.ChangeAll.instance.disable();var c=function(b){b=a.LocalizationButton[b].instance;b.getElement().hasClass(\"cke_disabled\")?b.getElement().setStyle(\"color\",\"#a0a0a0\"):b.disable()};c(\"ChangeTo\");c(\"ChangeAll\")}else a.LocalizationButton.ChangeTo.instance.enable(),\na.LocalizationButton.ChangeAll.instance.enable(),a.LocalizationButton.ChangeTo.instance.getElement().setStyle(\"color\",\"#333\"),a.LocalizationButton.ChangeAll.instance.getElement().setStyle(\"color\",\"#333\");return b},B={iframeOnload:function(){a.div_overlay.setEnable();var b=a.dialog._.currentTabId;t(a.targetFromFrame[a.iframeNumber+\"_\"+b],a.cmd[b])},suggestlist:function(b){delete b.id;a.div_overlay_no_check.setDisable();r();n(a.langList);var c=A(b.word),d=\"\";c instanceof Array&&(c=b.word[0]);d=c=c.split(\",\");\np.clear();a.textNode.SpellTab.setValue(d[0]);for(b=0;b<d.length;b++)p.add(d[b],d[b]);l();a.div_overlay.setDisable()},grammerSuggest:function(b){delete b.id;delete b.mocklangs;r();n(a.langList);var c=b.grammSuggest[0];a.grammerSuggest.getElement().setHtml(\"\");a.textNode.GrammTab.reset();a.textNode.GrammTab.setValue(c);a.textNodeInfo.GrammTab.getElement().setHtml(\"\");a.textNodeInfo.GrammTab.getElement().setText(b.info);for(var b=b.grammSuggest,c=b.length,d=!0,f=0;f<c;f++)a.grammerSuggest.getElement().append(z(b[f],\nb[f],d)),d=!1;l();a.div_overlay.setDisable()},thesaurusSuggest:function(b){delete b.id;delete b.mocklangs;r();n(a.langList);a.selectNodeResponce=b;a.textNode.Thesaurus.reset();a.selectNode.categories.clear();for(var c in b)a.selectNode.categories.add(c,c);b=a.selectNode.categories.getInputElement().getChildren().$[0].value;a.selectNode.categories.getInputElement().getChildren().$[0].selected=!0;a.buildOptionSynonyms(b);l();a.div_overlay.setDisable()},finish:function(b){delete b.id;a.dialog.getContentElement(a.dialog._.currentTabId,\n\"bottomGroup\").getElement().hide();a.dialog.getContentElement(a.dialog._.currentTabId,\"BlockFinishChecking\").getElement().show();a.div_overlay.setDisable()},settext:function(b){delete b.id;a.dialog.getParentEditor().getCommand(\"checkspell\");var c=a.dialog.getParentEditor();c.focus();c.setData(b.text,function(){a.dataTemp=\"\";c.unlockSelection();c.fire(\"saveSnapshot\");a.dialog.hide()})},ReplaceText:function(b){delete b.id;a.div_overlay.setEnable();a.dataTemp=b.text;a.selectingLang=b.currentLang;window.setTimeout(function(){a.div_overlay.setDisable()},\n500);x(a.LocalizationButton);y(a.LocalizationLabel)},options_checkbox_send:function(b){delete b.id;b={osp:e.cookie.get(\"osp\"),udn:e.cookie.get(\"udn\"),cust_dic_ids:a.cust_dic_ids};e.postMessage.send({message:b,target:a.targetFromFrame[a.iframeNumber+\"_\"+a.dialog._.currentTabId],id:\"options_outer__page\"})},getOptions:function(b){var c=b.DefOptions.udn;a.LocalizationComing=b.DefOptions.localizationButtonsAndText;a.show_grammar=b.show_grammar;a.langList=b.lang;if(a.bnr=b.bannerId){a.setHeightBannerFrame();\nvar d=b.banner;a.dialog.getContentElement(a.dialog._.currentTabId,\"banner\").getElement().setHtml(d)}else a.setHeightFrame();\"undefined\"==c&&(a.userDictionaryName?(c=a.userDictionaryName,d={osp:e.cookie.get(\"osp\"),udn:a.userDictionaryName,cust_dic_ids:a.cust_dic_ids,id:\"options_dic_send\",udnCmd:\"create\"},e.postMessage.send({message:d,target:a.targetFromFrame[void 0]})):c=\"\");e.cookie.set(\"osp\",b.DefOptions.osp);e.cookie.set(\"udn\",c);e.cookie.set(\"cust_dic_ids\",b.DefOptions.cust_dic_ids);e.postMessage.send({id:\"giveOptions\"})},\noptions_dic_send:function(){var b={osp:e.cookie.get(\"osp\"),udn:e.cookie.get(\"udn\"),cust_dic_ids:a.cust_dic_ids,id:\"options_dic_send\",udnCmd:e.cookie.get(\"udnCmd\")};e.postMessage.send({message:b,target:a.targetFromFrame[a.iframeNumber+\"_\"+a.dialog._.currentTabId]})},data:function(a){delete a.id},giveOptions:function(){},setOptionsConfirmF:function(){},setOptionsConfirmT:function(){j.setValue(\"\")},clickBusy:function(){a.div_overlay.setEnable()},suggestAllCame:function(){a.div_overlay.setDisable();a.div_overlay_no_check.setDisable()},\nTextCorrect:function(){n(a.langList)}},C=function(a){a=a||window.event;if((a=window.JSON.parse(a.data))&&a.id)B[a.id](a)},t=function(b,c,d,f){c=c||CKEDITOR.config.wsc_cmd;d=d||a.dataTemp;e.postMessage.send({message:{customerId:a.wsc_customerId,text:d,txt_ctrl:a.TextAreaNumber,cmd:c,cust_dic_ids:a.cust_dic_ids,udn:a.userDictionaryName,slang:a.selectingLang,reset_suggest:f||!1},target:b,id:\"data_outer__page\"});a.div_overlay.setEnable()},v={superset:function(){a.dialog.showPage(\"Thesaurus\");a.dialog.showPage(\"GrammTab\");\no()},usual:function(){s();m();o()},rtl:function(){s();m();o()}},D=function(b){var c=new function(a){var b={};return{getCmdByTab:function(c){for(var e in a)b[a[e]]=e;return b[c]}}}(a.cmd);b.selectPage(c.getCmdByTab(CKEDITOR.config.wsc_cmd));a.sendData(b)},s=function(){a.dialog.hidePage(\"Thesaurus\")},m=function(){a.dialog.hidePage(\"GrammTab\")},o=function(){a.dialog.showPage(\"SpellTab\")},l=function(){a.dialog.getContentElement(a.dialog._.currentTabId,\"bottomGroup\").getElement().show()},r=function(){a.dialog.getContentElement(a.dialog._.currentTabId,\n\"BlockFinishChecking\").getElement().hide()};CKEDITOR.dialog.add(\"checkspell\",function(b){var c=function(){a.div_overlay.setEnable();var c=a.dialog._.currentTabId,f=a.iframeNumber+\"_\"+c,g=a.textNode[c].getValue(),h=this.getElement().getAttribute(\"title-cmd\");e.postMessage.send({message:{cmd:h,tabId:c,new_word:g},target:a.targetFromFrame[f],id:\"cmd_outer__page\"});(\"ChangeTo\"==h||\"ChangeAll\"==h)&&b.fire(\"saveSnapshot\");\"FinishChecking\"==h&&b.config.wsc_onFinish.call(CKEDITOR.document.getWindow().getFrame())};\nreturn{title:b.config.wsc_dialogTitle||b.lang.wsc.title,minWidth:560,minHeight:444,buttons:[CKEDITOR.dialog.cancelButton],onLoad:function(){a.dialog=this;s();m();o()},onShow:function(){b.lockSelection(b.getSelection());a.TextAreaNumber=\"cke_textarea_\"+CKEDITOR.currentInstance.name;e.postMessage.init(C);a.dataTemp=CKEDITOR.currentInstance.getData();a.OverlayPlace=a.dialog.parts.tabs.getParent().$;if(CKEDITOR&&CKEDITOR.config){a.wsc_customerId=b.config.wsc_customerId;a.cust_dic_ids=b.config.wsc_customDictionaryIds;\na.userDictionaryName=b.config.wsc_userDictionaryName;a.defaultLanguage=CKEDITOR.config.defaultLanguage;var c=\"file:\"==document.location.protocol?\"http:\":document.location.protocol;CKEDITOR.scriptLoader.load(b.config.wsc_customLoaderScript||c+\"//loader.webspellchecker.net/sproxy_fck/sproxy.php?plugin=fck2&customerid=\"+a.wsc_customerId+\"&cmd=script&doc=wsc&schema=22\",function(c){CKEDITOR.config&&CKEDITOR.config.wsc&&CKEDITOR.config.wsc.DefaultParams?(a.serverLocationHash=CKEDITOR.config.wsc.DefaultParams.serviceHost,\na.logotype=CKEDITOR.config.wsc.DefaultParams.logoPath,a.loadIcon=CKEDITOR.config.wsc.DefaultParams.iconPath,a.loadIconEmptyEditor=CKEDITOR.config.wsc.DefaultParams.iconPathEmptyEditor,a.LangComparer=new CKEDITOR.config.wsc.DefaultParams._SP_FCK_LangCompare):(a.serverLocationHash=DefaultParams.serviceHost,a.logotype=DefaultParams.logoPath,a.loadIcon=DefaultParams.iconPath,a.loadIconEmptyEditor=DefaultParams.iconPathEmptyEditor,a.LangComparer=new _SP_FCK_LangCompare);a.pluginPath=CKEDITOR.getUrl(b.plugins.wsc.path);\na.iframeNumber=a.TextAreaNumber;a.templatePath=a.pluginPath+\"dialogs/tmp.html\";a.LangComparer.setDefaulLangCode(a.defaultLanguage);a.currentLang=b.config.wsc_lang||a.LangComparer.getSPLangCode(b.langCode);a.selectingLang=a.currentLang;a.div_overlay=new q({opacity:\"1\",background:\"#fff url(\"+a.loadIcon+\") no-repeat 50% 50%\",target:a.OverlayPlace});var d=a.dialog.parts.tabs.getId(),d=CKEDITOR.document.getById(d);d.setStyle(\"width\",\"97%\");d.getElementsByTag(\"DIV\").count()||d.append(a.buildSelectLang(a.dialog.getParentEditor().name));\na.div_overlay_no_check=new q({opacity:\"1\",id:\"no_check_over\",background:\"#fff url(\"+a.loadIconEmptyEditor+\") no-repeat 50% 50%\",target:a.OverlayPlace});c&&(D(a.dialog),a.dialog.setupContent(a.dialog))})}else a.dialog.hide()},onHide:function(){a.dataTemp=\"\"},contents:[{id:\"SpellTab\",label:\"SpellChecker\",accessKey:\"S\",elements:[{type:\"html\",id:\"banner\",label:\"banner\",style:\"\",html:\"<div></div>\"},{type:\"html\",id:\"Content\",label:\"spellContent\",html:\"\",setup:function(b){var b=a.iframeNumber+\"_\"+b._.currentTabId,\nc=document.getElementById(b);a.targetFromFrame[b]=c.contentWindow}},{type:\"hbox\",id:\"bottomGroup\",style:\"width:560px; margin: 0 auto;\",widths:[\"50%\",\"50%\"],children:[{type:\"hbox\",id:\"leftCol\",align:\"left\",width:\"50%\",children:[{type:\"vbox\",id:\"rightCol1\",widths:[\"50%\",\"50%\"],children:[{type:\"text\",id:\"text\",label:a.LocalizationLabel.ChangeTo.text+\":\",labelLayout:\"horizontal\",labelStyle:\"font: 12px/25px arial, sans-serif;\",width:\"140px\",\"default\":\"\",onShow:function(){a.textNode.SpellTab=this;a.LocalizationLabel.ChangeTo.instance=\nthis},onHide:function(){this.reset()}},{type:\"hbox\",id:\"rightCol\",align:\"right\",width:\"30%\",children:[{type:\"vbox\",id:\"rightCol_col__left\",children:[{type:\"text\",id:\"labelSuggestions\",label:a.LocalizationLabel.Suggestions.text+\":\",onShow:function(){a.LocalizationLabel.Suggestions.instance=this;this.getInputElement().hide()}},{type:\"html\",id:\"logo\",html:'<img width=\"99\" height=\"68\" border=\"0\" src=\"\" title=\"WebSpellChecker.net\" alt=\"WebSpellChecker.net\" style=\"display: inline-block;\">',setup:function(){this.getElement().$.src=\na.logotype;this.getElement().getParent().setStyles({\"text-align\":\"left\"})}}]},{type:\"select\",id:\"list_of_suggestions\",labelStyle:\"font: 12px/25px arial, sans-serif;\",size:\"6\",inputStyle:\"width: 140px; height: auto;\",items:[[\"loading...\"]],onShow:function(){p=this},onHide:function(){this.clear()},onChange:function(){a.textNode.SpellTab.setValue(this.getValue())}}]}]}]},{type:\"hbox\",id:\"rightCol\",align:\"right\",width:\"50%\",children:[{type:\"vbox\",id:\"rightCol_col__left\",widths:[\"50%\",\"50%\",\"50%\",\"50%\"],\nchildren:[{type:\"button\",id:\"ChangeTo\",label:a.LocalizationButton.ChangeTo.text,title:\"Change to\",style:\"width: 100%;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id);a.LocalizationButton.ChangeTo.instance=this},onClick:c},{type:\"button\",id:\"ChangeAll\",label:a.LocalizationButton.ChangeAll.text,title:\"Change All\",style:\"width: 100%;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id);a.LocalizationButton.ChangeAll.instance=this},onClick:c},{type:\"button\",id:\"AddWord\",\nlabel:a.LocalizationButton.AddWord.text,title:\"Add word\",style:\"width: 100%;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id);a.LocalizationButton.AddWord.instance=this},onClick:c},{type:\"button\",id:\"FinishChecking\",label:a.LocalizationButton.FinishChecking.text,title:\"Finish Checking\",style:\"width: 100%;margin-top: 9px;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id);a.LocalizationButton.FinishChecking.instance=this},onClick:c}]},{type:\"vbox\",id:\"rightCol_col__right\",\nwidths:[\"50%\",\"50%\",\"50%\"],children:[{type:\"button\",id:\"IgnoreWord\",label:a.LocalizationButton.IgnoreWord.text,title:\"Ignore word\",style:\"width: 100%;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id);a.LocalizationButton.IgnoreWord.instance=this},onClick:c},{type:\"button\",id:\"IgnoreAllWords\",label:a.LocalizationButton.IgnoreAllWords.text,title:\"Ignore all words\",style:\"width: 100%;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id);a.LocalizationButton.IgnoreAllWords.instance=\nthis},onClick:c},{type:\"button\",id:\"option\",label:a.LocalizationButton.Options.text,title:\"Option\",style:\"width: 100%;\",onLoad:function(){a.LocalizationButton.Options.instance=this;\"file:\"==document.location.protocol&&this.disable()},onClick:function(){\"file:\"==document.location.protocol?alert(\"WSC: Options functionality is disabled when runing from file system\"):b.openDialog(\"options\")}}]}]}]},{type:\"hbox\",id:\"BlockFinishChecking\",style:\"width:560px; margin: 0 auto;\",widths:[\"70%\",\"30%\"],onShow:function(){this.getElement().hide()},\nonHide:l,children:[{type:\"hbox\",id:\"leftCol\",align:\"left\",width:\"70%\",children:[{type:\"vbox\",id:\"rightCol1\",setup:function(){this.getChild()[0].getElement().$.src=a.logotype;this.getChild()[0].getElement().getParent().setStyles({\"text-align\":\"center\"})},children:[{type:\"html\",id:\"logo\",html:'<img width=\"99\" height=\"68\" border=\"0\" src=\"\" title=\"WebSpellChecker.net\" alt=\"WebSpellChecker.net\" style=\"display: inline-block;\">'}]}]},{type:\"hbox\",id:\"rightCol\",align:\"right\",width:\"30%\",children:[{type:\"vbox\",\nid:\"rightCol_col__left\",children:[{type:\"button\",id:\"Option_button\",label:a.LocalizationButton.Options.text,title:\"Option\",style:\"width: 100%;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id);\"file:\"==document.location.protocol&&this.disable()},onClick:function(){\"file:\"==document.location.protocol?alert(\"WSC: Options functionality is disabled when runing from file system\"):b.openDialog(\"options\")}},{type:\"button\",id:\"FinishChecking\",label:a.LocalizationButton.FinishChecking.text,\ntitle:\"Finish Checking\",style:\"width: 100%;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id)},onClick:c}]}]}]}]},{id:\"GrammTab\",label:\"Grammar\",accessKey:\"G\",elements:[{type:\"html\",id:\"banner\",label:\"banner\",style:\"\",html:\"<div></div>\"},{type:\"html\",id:\"Content\",label:\"GrammarContent\",html:\"\",setup:function(){var b=a.iframeNumber+\"_\"+a.dialog._.currentTabId,c=document.getElementById(b);a.targetFromFrame[b]=c.contentWindow}},{type:\"vbox\",id:\"bottomGroup\",style:\"width:560px; margin: 0 auto;\",\nchildren:[{type:\"hbox\",id:\"leftCol\",widths:[\"66%\",\"34%\"],children:[{type:\"vbox\",children:[{type:\"text\",id:\"text\",label:\"Change to:\",labelLayout:\"horizontal\",labelStyle:\"font: 12px/25px arial, sans-serif;\",inputStyle:\"float: right; width: 200px;\",\"default\":\"\",onShow:function(){a.textNode.GrammTab=this},onHide:function(){this.reset()}},{type:\"html\",id:\"html_text\",html:\"<div style='min-height: 17px; line-height: 17px; padding: 5px; text-align: left;background: #F1F1F1;color: #595959; white-space: normal!important;'></div>\",\nonShow:function(){a.textNodeInfo.GrammTab=this}},{type:\"html\",id:\"radio\",html:\"\",onShow:function(){a.grammerSuggest=this}}]},{type:\"vbox\",children:[{type:\"button\",id:\"ChangeTo\",label:\"Change to\",title:\"Change to\",style:\"width: 133px; float: right;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id)},onClick:c},{type:\"button\",id:\"IgnoreWord\",label:\"Ignore word\",title:\"Ignore word\",style:\"width: 133px; float: right;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id)},\nonClick:c},{type:\"button\",id:\"IgnoreAllWords\",label:\"Ignore Problem\",title:\"Ignore Problem\",style:\"width: 133px; float: right;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id)},onClick:c},{type:\"button\",id:\"FinishChecking\",label:\"Finish Checking\",title:\"Finish Checking\",style:\"width: 133px; float: right; margin-top: 9px;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id)},onClick:c}]}]}]},{type:\"hbox\",id:\"BlockFinishChecking\",style:\"width:560px; margin: 0 auto;\",\nwidths:[\"70%\",\"30%\"],onShow:function(){this.getElement().hide()},onHide:l,children:[{type:\"hbox\",id:\"leftCol\",align:\"left\",width:\"70%\",children:[{type:\"vbox\",id:\"rightCol1\",children:[{type:\"html\",id:\"logo\",html:'<img width=\"99\" height=\"68\" border=\"0\" src=\"\" title=\"WebSpellChecker.net\" alt=\"WebSpellChecker.net\" style=\"display: inline-block;\">',setup:function(){this.getElement().$.src=a.logotype;this.getElement().getParent().setStyles({\"text-align\":\"center\"})}}]}]},{type:\"hbox\",id:\"rightCol\",align:\"right\",\nwidth:\"30%\",children:[{type:\"vbox\",id:\"rightCol_col__left\",children:[{type:\"button\",id:\"FinishChecking\",label:\"Finish Checking\",title:\"Finish Checking\",style:\"width: 100%;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id)},onClick:c}]}]}]}]},{id:\"Thesaurus\",label:\"Thesaurus\",accessKey:\"T\",elements:[{type:\"html\",id:\"banner\",label:\"banner\",style:\"\",html:\"<div></div>\"},{type:\"html\",id:\"Content\",label:\"spellContent\",html:\"\",setup:function(){var b=a.iframeNumber+\"_\"+a.dialog._.currentTabId,\nc=document.getElementById(b);a.targetFromFrame[b]=c.contentWindow}},{type:\"vbox\",id:\"bottomGroup\",style:\"width:560px; margin: -10px auto; overflow: hidden;\",children:[{type:\"hbox\",widths:[\"75%\",\"25%\"],children:[{type:\"vbox\",children:[{type:\"hbox\",widths:[\"65%\",\"35%\"],children:[{type:\"text\",id:\"ChangeTo\",label:\"Change to:\",labelLayout:\"horizontal\",inputStyle:\"width: 160px;\",labelStyle:\"font: 12px/25px arial, sans-serif;\",\"default\":\"\",onShow:function(){a.textNode.Thesaurus=this},onHide:function(){this.reset()}},\n{type:\"button\",id:\"ChangeTo\",label:\"Change to\",title:\"Change to\",style:\"width: 121px; margin-top: 1px;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id)},onClick:c}]},{type:\"hbox\",children:[{type:\"select\",id:\"categories\",label:\"Categories:\",labelStyle:\"font: 12px/25px arial, sans-serif;\",size:\"5\",inputStyle:\"width: 180px; height: auto;\",items:[],onShow:function(){a.selectNode.categories=this},onHide:function(){this.clear()},onChange:function(){a.buildOptionSynonyms(this.getValue())}},\n{type:\"select\",id:\"synonyms\",label:\"Synonyms:\",labelStyle:\"font: 12px/25px arial, sans-serif;\",size:\"5\",inputStyle:\"width: 180px; height: auto;\",items:[],onShow:function(){a.selectNode.synonyms=this;a.textNode.Thesaurus.setValue(this.getValue())},onHide:function(){this.clear()},onChange:function(){a.textNode.Thesaurus.setValue(this.getValue())}}]}]},{type:\"vbox\",width:\"120px\",style:\"margin-top:46px;\",children:[{type:\"html\",id:\"logotype\",label:\"WebSpellChecker.net\",html:'<img width=\"99\" height=\"68\" border=\"0\" src=\"\" title=\"WebSpellChecker.net\" alt=\"WebSpellChecker.net\" style=\"display: inline-block;\">',\nsetup:function(){this.getElement().$.src=a.logotype;this.getElement().getParent().setStyles({\"text-align\":\"center\"})}},{type:\"button\",id:\"FinishChecking\",label:\"Finish Checking\",title:\"Finish Checking\",style:\"width: 121px; float: right; margin-top: 9px;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id)},onClick:c}]}]}]},{type:\"hbox\",id:\"BlockFinishChecking\",style:\"width:560px; margin: 0 auto;\",widths:[\"70%\",\"30%\"],onShow:function(){this.getElement().hide()},children:[{type:\"hbox\",\nid:\"leftCol\",align:\"left\",width:\"70%\",children:[{type:\"vbox\",id:\"rightCol1\",children:[{type:\"html\",id:\"logo\",html:'<img width=\"99\" height=\"68\" border=\"0\" src=\"\" title=\"WebSpellChecker.net\" alt=\"WebSpellChecker.net\" style=\"display: inline-block;\">',setup:function(){this.getElement().$.src=a.logotype;this.getElement().getParent().setStyles({\"text-align\":\"center\"})}}]}]},{type:\"hbox\",id:\"rightCol\",align:\"right\",width:\"30%\",children:[{type:\"vbox\",id:\"rightCol_col__left\",children:[{type:\"button\",id:\"FinishChecking\",\nlabel:\"Finish Checking\",title:\"Finish Checking\",style:\"width: 100%;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id)},onClick:c}]}]}]}]}]}});CKEDITOR.dialog.add(\"options\",function(){var b=null,c={},d={},f=null,g=null;e.cookie.get(\"udn\");e.cookie.get(\"osp\");var h=function(){g=this.getElement().getAttribute(\"title-cmd\");var a=[];a[0]=d.IgnoreAllCapsWords;a[1]=d.IgnoreWordsNumbers;a[2]=d.IgnoreMixedCaseWords;a[3]=d.IgnoreDomainNames;a=a.toString().replace(/,/g,\"\");e.cookie.set(\"osp\",\na);e.cookie.set(\"udnCmd\",g?g:\"ignore\");\"delete\"!=g&&(a=\"\",\"\"!==j.getValue()&&(a=j.getValue()),e.cookie.set(\"udn\",a));e.postMessage.send({id:\"options_dic_send\"})},i=function(){f.getElement().setHtml(a.LocalizationComing.error);f.getElement().show()};return{title:a.LocalizationComing.Options,minWidth:430,minHeight:130,resizable:CKEDITOR.DIALOG_RESIZE_NONE,contents:[{id:\"OptionsTab\",label:\"Options\",accessKey:\"O\",elements:[{type:\"hbox\",id:\"options_error\",children:[{type:\"html\",style:\"display: block;text-align: center;white-space: normal!important; font-size: 12px;color:red\",\nhtml:\"<div></div>\",onShow:function(){f=this}}]},{type:\"vbox\",id:\"Options_content\",children:[{type:\"hbox\",id:\"Options_manager\",widths:[\"52%\",\"48%\"],children:[{type:\"fieldset\",label:\"Spell Checking Options\",style:\"border: none;margin-top: 13px;padding: 10px 0 10px 10px\",onShow:function(){this.getInputElement().$.children[0].innerHTML=a.LocalizationComing.SpellCheckingOptions},children:[{type:\"vbox\",id:\"Options_checkbox\",children:[{type:\"checkbox\",id:\"IgnoreAllCapsWords\",label:\"Ignore All-Caps Words\",\nlabelStyle:\"margin-left: 5px; font: 12px/16px arial, sans-serif;display: inline-block;white-space: normal;\",style:\"float:left; min-height: 16px;\",\"default\":\"\",onClick:function(){d[this.id]=!this.getValue()?0:1}},{type:\"checkbox\",id:\"IgnoreWordsNumbers\",label:\"Ignore Words with Numbers\",labelStyle:\"margin-left: 5px; font: 12px/16px arial, sans-serif;display: inline-block;white-space: normal;\",style:\"float:left; min-height: 16px;\",\"default\":\"\",onClick:function(){d[this.id]=!this.getValue()?0:1}},{type:\"checkbox\",\nid:\"IgnoreMixedCaseWords\",label:\"Ignore Mixed-Case Words\",labelStyle:\"margin-left: 5px; font: 12px/16px arial, sans-serif;display: inline-block;white-space: normal;\",style:\"float:left; min-height: 16px;\",\"default\":\"\",onClick:function(){d[this.id]=!this.getValue()?0:1}},{type:\"checkbox\",id:\"IgnoreDomainNames\",label:\"Ignore Domain Names\",labelStyle:\"margin-left: 5px; font: 12px/16px arial, sans-serif;display: inline-block;white-space: normal;\",style:\"float:left; min-height: 16px;\",\"default\":\"\",onClick:function(){d[this.id]=\n!this.getValue()?0:1}}]}]},{type:\"vbox\",id:\"Options_DictionaryName\",children:[{type:\"text\",id:\"DictionaryName\",style:\"margin-bottom: 10px\",label:\"Dictionary Name:\",labelLayout:\"vertical\",labelStyle:\"font: 12px/25px arial, sans-serif;\",\"default\":\"\",onLoad:function(){j=this;this.setValue(a.userDictionaryName?a.userDictionaryName:(e.cookie.get(\"udn\"),this.getValue()))},onShow:function(){j=this;this.setValue(!e.cookie.get(\"udn\")?this.getValue():e.cookie.get(\"udn\"));this.setLabel(a.LocalizationComing.DictionaryName)},\nonHide:function(){this.reset()}},{type:\"hbox\",id:\"Options_buttons\",children:[{type:\"vbox\",id:\"Options_leftCol_col\",widths:[\"50%\",\"50%\"],children:[{type:\"button\",id:\"create\",label:\"Create\",title:\"Create\",style:\"width: 100%;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id)},onShow:function(){this.getElement().setText(a.LocalizationComing.Create)},onClick:h},{type:\"button\",id:\"restore\",label:\"Restore\",title:\"Restore\",style:\"width: 100%;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",\nthis.id)},onShow:function(){this.getElement().setText(a.LocalizationComing.Restore)},onClick:h}]},{type:\"vbox\",id:\"Options_rightCol_col\",widths:[\"50%\",\"50%\"],children:[{type:\"button\",id:\"rename\",label:\"Rename\",title:\"Rename\",style:\"width: 100%;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",this.id)},onShow:function(){this.getElement().setText(a.LocalizationComing.Rename)},onClick:h},{type:\"button\",id:\"delete\",label:\"Remove\",title:\"Remove\",style:\"width: 100%;\",onLoad:function(){this.getElement().setAttribute(\"title-cmd\",\nthis.id)},onShow:function(){this.getElement().setText(a.LocalizationComing.Remove)},onClick:h}]}]}]}]},{type:\"hbox\",id:\"Options_text\",children:[{type:\"html\",style:\"text-align: justify;margin-top: 15px;white-space: normal!important; font-size: 12px;color:#777;\",html:\"<div>\"+a.LocalizationComing.OptionsTextIntro+\"</div>\",onShow:function(){this.getElement().setText(a.LocalizationComing.OptionsTextIntro)}}]}]}]}],buttons:[CKEDITOR.dialog.okButton,CKEDITOR.dialog.cancelButton],onOk:function(){var a=[];\na[0]=d.IgnoreAllCapsWords;a[1]=d.IgnoreWordsNumbers;a[2]=d.IgnoreMixedCaseWords;a[3]=d.IgnoreDomainNames;a=a.toString().replace(/,/g,\"\");e.cookie.set(\"osp\",a);e.cookie.set(\"udn\",j.getValue());e.postMessage.send({id:\"options_checkbox_send\"});f.getElement().hide();f.getElement().setHtml(\" \")},onLoad:function(){b=this;e.postMessage.init(i);c.IgnoreAllCapsWords=b.getContentElement(\"OptionsTab\",\"IgnoreAllCapsWords\");c.IgnoreWordsNumbers=b.getContentElement(\"OptionsTab\",\"IgnoreWordsNumbers\");c.IgnoreMixedCaseWords=\nb.getContentElement(\"OptionsTab\",\"IgnoreMixedCaseWords\");c.IgnoreDomainNames=b.getContentElement(\"OptionsTab\",\"IgnoreDomainNames\")},onShow:function(){var b=e.cookie.get(\"osp\").split(\"\");d.IgnoreAllCapsWords=b[0];d.IgnoreWordsNumbers=b[1];d.IgnoreMixedCaseWords=b[2];d.IgnoreDomainNames=b[3];!parseInt(d.IgnoreAllCapsWords,10)?c.IgnoreAllCapsWords.setValue(\"\",!1):c.IgnoreAllCapsWords.setValue(\"checked\",!1);!parseInt(d.IgnoreWordsNumbers,10)?c.IgnoreWordsNumbers.setValue(\"\",!1):c.IgnoreWordsNumbers.setValue(\"checked\",\n!1);!parseInt(d.IgnoreMixedCaseWords,10)?c.IgnoreMixedCaseWords.setValue(\"\",!1):c.IgnoreMixedCaseWords.setValue(\"checked\",!1);!parseInt(d.IgnoreDomainNames,10)?c.IgnoreDomainNames.setValue(\"\",!1):c.IgnoreDomainNames.setValue(\"checked\",!1);d.IgnoreAllCapsWords=!c.IgnoreAllCapsWords.getValue()?0:1;d.IgnoreWordsNumbers=!c.IgnoreWordsNumbers.getValue()?0:1;d.IgnoreMixedCaseWords=!c.IgnoreMixedCaseWords.getValue()?0:1;d.IgnoreDomainNames=!c.IgnoreDomainNames.getValue()?0:1;c.IgnoreAllCapsWords.getElement().$.lastChild.innerHTML=\na.LocalizationComing.IgnoreAllCapsWords;c.IgnoreWordsNumbers.getElement().$.lastChild.innerHTML=a.LocalizationComing.IgnoreWordsWithNumbers;c.IgnoreMixedCaseWords.getElement().$.lastChild.innerHTML=a.LocalizationComing.IgnoreMixedCaseWords;c.IgnoreDomainNames.getElement().$.lastChild.innerHTML=a.LocalizationComing.IgnoreDomainNames}}});CKEDITOR.dialog.on(\"resize\",function(b){var b=b.data,c=b.dialog,d=CKEDITOR.document.getById(a.iframeNumber+\"_\"+c._.currentTabId);\"checkspell\"==c._.name&&(a.bnr?d&&\nd.setSize(\"height\",b.height-310):d&&d.setSize(\"height\",b.height-220))});CKEDITOR.on(\"dialogDefinition\",function(b){var c=b.data.definition;a.onLoadOverlay=new q({opacity:\"1\",background:\"#fff\",target:c.dialog.parts.tabs.getParent().$});a.onLoadOverlay.setEnable();c.dialog.on(\"show\",function(){});c.dialog.on(\"cancel\",function(){c.dialog.getParentEditor().config.wsc_onClose.call(this.document.getWindow().getFrame());a.div_overlay.setDisable();return!1},this,null,-1)})})();"
  },
  {
    "path": "public/static/plugins/ckeditor/plugins/wsc/dialogs/wsc_ie.js",
    "content": "﻿/*\n Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved.\n For licensing, see LICENSE.html or http://ckeditor.com/license\n*/\nCKEDITOR.dialog.add(\"checkspell\",function(a){function c(a,c){var d=0;return function(){\"function\"==typeof window.doSpell?(\"undefined\"!=typeof e&&window.clearInterval(e),j(a)):180==d++&&window._cancelOnError(c)}}function j(c){var f=new window._SP_FCK_LangCompare,b=CKEDITOR.getUrl(a.plugins.wsc.path+\"dialogs/\"),e=b+\"tmpFrameset.html\";window.gFCKPluginName=\"wsc\";f.setDefaulLangCode(a.config.defaultLanguage);window.doSpell({ctrl:g,lang:a.config.wsc_lang||f.getSPLangCode(a.langCode),intLang:a.config.wsc_uiLang||\nf.getSPLangCode(a.langCode),winType:d,onCancel:function(){c.hide()},onFinish:function(b){a.focus();c.getParentEditor().setData(b.value);c.hide()},staticFrame:e,framesetPath:e,iframePath:b+\"ciframe.html\",schemaURI:b+\"wsc.css\",userDictionaryName:a.config.wsc_userDictionaryName,customDictionaryName:a.config.wsc_customDictionaryIds&&a.config.wsc_customDictionaryIds.split(\",\"),domainName:a.config.wsc_domainName});CKEDITOR.document.getById(h).setStyle(\"display\",\"none\");CKEDITOR.document.getById(d).setStyle(\"display\",\n\"block\")}var b=CKEDITOR.tools.getNextNumber(),d=\"cke_frame_\"+b,g=\"cke_data_\"+b,h=\"cke_error_\"+b,e,b=document.location.protocol||\"http:\",i=a.lang.wsc.notAvailable,k='<textarea style=\"display: none\" id=\"'+g+'\" rows=\"10\" cols=\"40\"> </textarea><div id=\"'+h+'\" style=\"display:none;color:red;font-size:16px;font-weight:bold;padding-top:160px;text-align:center;z-index:11;\"></div><iframe src=\"\" style=\"width:100%;background-color:#f1f1e3;\" frameborder=\"0\" name=\"'+d+'\" id=\"'+d+'\" allowtransparency=\"1\"></iframe>',\nl=a.config.wsc_customLoaderScript||b+\"//loader.webspellchecker.net/sproxy_fck/sproxy.php?plugin=fck2&customerid=\"+a.config.wsc_customerId+\"&cmd=script&doc=wsc&schema=22\";a.config.wsc_customLoaderScript&&(i+='<p style=\"color:#000;font-size:11px;font-weight: normal;text-align:center;padding-top:10px\">'+a.lang.wsc.errorLoading.replace(/%s/g,a.config.wsc_customLoaderScript)+\"</p>\");window._cancelOnError=function(c){if(\"undefined\"==typeof window.WSC_Error){CKEDITOR.document.getById(d).setStyle(\"display\",\n\"none\");var b=CKEDITOR.document.getById(h);b.setStyle(\"display\",\"block\");b.setHtml(c||a.lang.wsc.notAvailable)}};return{title:a.config.wsc_dialogTitle||a.lang.wsc.title,minWidth:485,minHeight:380,buttons:[CKEDITOR.dialog.cancelButton],onShow:function(){var b=this.getContentElement(\"general\",\"content\").getElement();b.setHtml(k);b.getChild(2).setStyle(\"height\",this._.contentSize.height+\"px\");\"function\"!=typeof window.doSpell&&CKEDITOR.document.getHead().append(CKEDITOR.document.createElement(\"script\",\n{attributes:{type:\"text/javascript\",src:l}}));b=a.getData();CKEDITOR.document.getById(g).setValue(b);e=window.setInterval(c(this,i),250)},onHide:function(){window.ooo=void 0;window.int_framsetLoaded=void 0;window.framesetLoaded=void 0;window.is_window_opened=!1},contents:[{id:\"general\",label:a.config.wsc_dialogTitle||a.lang.wsc.title,padding:0,elements:[{type:\"html\",id:\"content\",html:\"\"}]}]}});\nCKEDITOR.dialog.on(\"resize\",function(a){var a=a.data,c=a.dialog;\"checkspell\"==c._.name&&((c=(c=c.getContentElement(\"general\",\"content\").getElement())&&c.getChild(2))&&c.setSize(\"height\",a.height),c&&c.setSize(\"width\",a.width))});"
  },
  {
    "path": "public/static/plugins/ckeditor/skins/moono/dialog.css",
    "content": "/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_browser_gecko19 .cke_dialog_body{position:relative}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;-moz-border-radius:0 0 2px 2px;-webkit-border-radius:0 0 2px 2px;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#ededed));background-image:-moz-linear-gradient(top,#fafafa,#ededed);background-image:-webkit-linear-gradient(top,#fafafa,#ededed);background-image:-o-linear-gradient(top,#fafafa,#ededed);background-image:-ms-linear-gradient(top,#fafafa,#ededed);background-image:linear-gradient(top,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover{background:#ebebeb;background:-moz-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ebebeb),color-stop(100%,#dfdfdf));background:-webkit-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-o-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-ms-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover{background:#ededed;background:-moz-linear-gradient(top,#ededed 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ededed),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ededed 0,#fff 100%);background:-o-linear-gradient(top,#ededed 0,#fff 100%);background:-ms-linear-gradient(top,#ededed 0,#fff 100%);background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:0 0;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:5px;z-index:5}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:3px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 12px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;-moz-box-shadow:0 0 6px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 6px rgba(0,0,0,.4) inset;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:20px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:-webkit-gradient(linear,0 0,0 100%,from(#9ad717),to(#69b10b));background-image:-webkit-linear-gradient(top,#9ad717,#69b10b);background-image:-o-linear-gradient(top,#9ad717,#69b10b);background-image:linear-gradient(to bottom,#9ad717,#69b10b);background-image:-moz-linear-gradient(top,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#88be14),color-stop(100%,#5d9c0a));background:-webkit-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:-o-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);background:-moz-linear-gradient(top,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:2px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:24px;line-height:24px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:2px 6px;outline:0;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}"
  },
  {
    "path": "public/static/plugins/ckeditor/skins/moono/dialog_ie.css",
    "content": "/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_browser_gecko19 .cke_dialog_body{position:relative}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;-moz-border-radius:0 0 2px 2px;-webkit-border-radius:0 0 2px 2px;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#ededed));background-image:-moz-linear-gradient(top,#fafafa,#ededed);background-image:-webkit-linear-gradient(top,#fafafa,#ededed);background-image:-o-linear-gradient(top,#fafafa,#ededed);background-image:-ms-linear-gradient(top,#fafafa,#ededed);background-image:linear-gradient(top,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover{background:#ebebeb;background:-moz-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ebebeb),color-stop(100%,#dfdfdf));background:-webkit-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-o-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-ms-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover{background:#ededed;background:-moz-linear-gradient(top,#ededed 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ededed),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ededed 0,#fff 100%);background:-o-linear-gradient(top,#ededed 0,#fff 100%);background:-ms-linear-gradient(top,#ededed 0,#fff 100%);background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:0 0;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:5px;z-index:5}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:3px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 12px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;-moz-box-shadow:0 0 6px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 6px rgba(0,0,0,.4) inset;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:20px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:-webkit-gradient(linear,0 0,0 100%,from(#9ad717),to(#69b10b));background-image:-webkit-linear-gradient(top,#9ad717,#69b10b);background-image:-o-linear-gradient(top,#9ad717,#69b10b);background-image:linear-gradient(to bottom,#9ad717,#69b10b);background-image:-moz-linear-gradient(top,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#88be14),color-stop(100%,#5d9c0a));background:-webkit-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:-o-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);background:-moz-linear-gradient(top,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:2px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:24px;line-height:24px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:2px 6px;outline:0;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{padding-right:2px}.cke_rtl div.cke_dialog_ui_input_text,.cke_rtl div.cke_dialog_ui_input_password{padding-left:2px}.cke_rtl div.cke_dialog_ui_input_text{padding-right:1px}.cke_rtl .cke_dialog_ui_vbox_child,.cke_rtl .cke_dialog_ui_hbox_child,.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_last{padding-right:2px!important}.cke_hc .cke_dialog_title,.cke_hc .cke_dialog_footer,.cke_hc a.cke_dialog_tab,.cke_hc a.cke_dialog_ui_button,.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button_ok,.cke_hc a.cke_dialog_ui_button_ok:hover{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:0}"
  },
  {
    "path": "public/static/plugins/ckeditor/skins/moono/dialog_ie7.css",
    "content": "/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_browser_gecko19 .cke_dialog_body{position:relative}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;-moz-border-radius:0 0 2px 2px;-webkit-border-radius:0 0 2px 2px;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#ededed));background-image:-moz-linear-gradient(top,#fafafa,#ededed);background-image:-webkit-linear-gradient(top,#fafafa,#ededed);background-image:-o-linear-gradient(top,#fafafa,#ededed);background-image:-ms-linear-gradient(top,#fafafa,#ededed);background-image:linear-gradient(top,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover{background:#ebebeb;background:-moz-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ebebeb),color-stop(100%,#dfdfdf));background:-webkit-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-o-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-ms-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover{background:#ededed;background:-moz-linear-gradient(top,#ededed 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ededed),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ededed 0,#fff 100%);background:-o-linear-gradient(top,#ededed 0,#fff 100%);background:-ms-linear-gradient(top,#ededed 0,#fff 100%);background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:0 0;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:5px;z-index:5}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:3px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 12px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;-moz-box-shadow:0 0 6px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 6px rgba(0,0,0,.4) inset;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:20px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:-webkit-gradient(linear,0 0,0 100%,from(#9ad717),to(#69b10b));background-image:-webkit-linear-gradient(top,#9ad717,#69b10b);background-image:-o-linear-gradient(top,#9ad717,#69b10b);background-image:linear-gradient(to bottom,#9ad717,#69b10b);background-image:-moz-linear-gradient(top,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#88be14),color-stop(100%,#5d9c0a));background:-webkit-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:-o-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);background:-moz-linear-gradient(top,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:2px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:24px;line-height:24px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:2px 6px;outline:0;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{padding-right:2px}.cke_rtl div.cke_dialog_ui_input_text,.cke_rtl div.cke_dialog_ui_input_password{padding-left:2px}.cke_rtl div.cke_dialog_ui_input_text{padding-right:1px}.cke_rtl .cke_dialog_ui_vbox_child,.cke_rtl .cke_dialog_ui_hbox_child,.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_last{padding-right:2px!important}.cke_hc .cke_dialog_title,.cke_hc .cke_dialog_footer,.cke_hc a.cke_dialog_tab,.cke_hc a.cke_dialog_ui_button,.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button_ok,.cke_hc a.cke_dialog_ui_button_ok:hover{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:0}.cke_dialog_title{zoom:1}.cke_dialog_footer{border-top:1px solid #bfbfbf}.cke_dialog_footer_buttons{position:static}.cke_dialog_footer_buttons a.cke_dialog_ui_button{vertical-align:top}.cke_dialog .cke_resizer_ltr{padding-left:4px}.cke_dialog .cke_resizer_rtl{padding-right:4px}.cke_dialog_ui_input_text,.cke_dialog_ui_input_password,.cke_dialog_ui_input_textarea,.cke_dialog_ui_input_select{padding:0!important}.cke_dialog_ui_checkbox_input,.cke_dialog_ui_ratio_input,.cke_btn_reset,.cke_btn_locked,.cke_btn_unlocked{border:1px solid transparent!important}"
  },
  {
    "path": "public/static/plugins/ckeditor/skins/moono/dialog_ie8.css",
    "content": "/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_browser_gecko19 .cke_dialog_body{position:relative}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;-moz-border-radius:0 0 2px 2px;-webkit-border-radius:0 0 2px 2px;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#ededed));background-image:-moz-linear-gradient(top,#fafafa,#ededed);background-image:-webkit-linear-gradient(top,#fafafa,#ededed);background-image:-o-linear-gradient(top,#fafafa,#ededed);background-image:-ms-linear-gradient(top,#fafafa,#ededed);background-image:linear-gradient(top,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover{background:#ebebeb;background:-moz-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ebebeb),color-stop(100%,#dfdfdf));background:-webkit-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-o-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-ms-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover{background:#ededed;background:-moz-linear-gradient(top,#ededed 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ededed),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ededed 0,#fff 100%);background:-o-linear-gradient(top,#ededed 0,#fff 100%);background:-ms-linear-gradient(top,#ededed 0,#fff 100%);background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:0 0;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:5px;z-index:5}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:3px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 12px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;-moz-box-shadow:0 0 6px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 6px rgba(0,0,0,.4) inset;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:20px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:-webkit-gradient(linear,0 0,0 100%,from(#9ad717),to(#69b10b));background-image:-webkit-linear-gradient(top,#9ad717,#69b10b);background-image:-o-linear-gradient(top,#9ad717,#69b10b);background-image:linear-gradient(to bottom,#9ad717,#69b10b);background-image:-moz-linear-gradient(top,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#88be14),color-stop(100%,#5d9c0a));background:-webkit-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:-o-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);background:-moz-linear-gradient(top,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:2px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:24px;line-height:24px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:2px 6px;outline:0;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{padding-right:2px}.cke_rtl div.cke_dialog_ui_input_text,.cke_rtl div.cke_dialog_ui_input_password{padding-left:2px}.cke_rtl div.cke_dialog_ui_input_text{padding-right:1px}.cke_rtl .cke_dialog_ui_vbox_child,.cke_rtl .cke_dialog_ui_hbox_child,.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_last{padding-right:2px!important}.cke_hc .cke_dialog_title,.cke_hc .cke_dialog_footer,.cke_hc a.cke_dialog_tab,.cke_hc a.cke_dialog_ui_button,.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button_ok,.cke_hc a.cke_dialog_ui_button_ok:hover{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:0}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{display:block}"
  },
  {
    "path": "public/static/plugins/ckeditor/skins/moono/dialog_iequirks.css",
    "content": "/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_browser_gecko19 .cke_dialog_body{position:relative}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;-moz-border-radius:0 0 2px 2px;-webkit-border-radius:0 0 2px 2px;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#ededed));background-image:-moz-linear-gradient(top,#fafafa,#ededed);background-image:-webkit-linear-gradient(top,#fafafa,#ededed);background-image:-o-linear-gradient(top,#fafafa,#ededed);background-image:-ms-linear-gradient(top,#fafafa,#ededed);background-image:linear-gradient(top,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover{background:#ebebeb;background:-moz-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ebebeb),color-stop(100%,#dfdfdf));background:-webkit-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-o-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-ms-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover{background:#ededed;background:-moz-linear-gradient(top,#ededed 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ededed),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ededed 0,#fff 100%);background:-o-linear-gradient(top,#ededed 0,#fff 100%);background:-ms-linear-gradient(top,#ededed 0,#fff 100%);background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:0 0;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:5px;z-index:5}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:3px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 12px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;-moz-box-shadow:0 0 6px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 6px rgba(0,0,0,.4) inset;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:20px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:-webkit-gradient(linear,0 0,0 100%,from(#9ad717),to(#69b10b));background-image:-webkit-linear-gradient(top,#9ad717,#69b10b);background-image:-o-linear-gradient(top,#9ad717,#69b10b);background-image:linear-gradient(to bottom,#9ad717,#69b10b);background-image:-moz-linear-gradient(top,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#88be14),color-stop(100%,#5d9c0a));background:-webkit-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:-o-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);background:-moz-linear-gradient(top,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:2px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:24px;line-height:24px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:2px 6px;outline:0;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{padding-right:2px}.cke_rtl div.cke_dialog_ui_input_text,.cke_rtl div.cke_dialog_ui_input_password{padding-left:2px}.cke_rtl div.cke_dialog_ui_input_text{padding-right:1px}.cke_rtl .cke_dialog_ui_vbox_child,.cke_rtl .cke_dialog_ui_hbox_child,.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_last{padding-right:2px!important}.cke_hc .cke_dialog_title,.cke_hc .cke_dialog_footer,.cke_hc a.cke_dialog_tab,.cke_hc a.cke_dialog_ui_button,.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button_ok,.cke_hc a.cke_dialog_ui_button_ok:hover{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:0}.cke_dialog_footer{filter:\"\"}"
  },
  {
    "path": "public/static/plugins/ckeditor/skins/moono/dialog_opera.css",
    "content": "/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_browser_gecko19 .cke_dialog_body{position:relative}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;-moz-border-radius:0 0 3px 3px;-webkit-border-radius:0 0 3px 3px;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;-moz-border-radius:0 0 2px 2px;-webkit-border-radius:0 0 2px 2px;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;-moz-border-radius:3px 3px 0 0;-webkit-border-radius:3px 3px 0 0;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fafafa),to(#ededed));background-image:-moz-linear-gradient(top,#fafafa,#ededed);background-image:-webkit-linear-gradient(top,#fafafa,#ededed);background-image:-o-linear-gradient(top,#fafafa,#ededed);background-image:-ms-linear-gradient(top,#fafafa,#ededed);background-image:linear-gradient(top,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover{background:#ebebeb;background:-moz-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ebebeb),color-stop(100%,#dfdfdf));background:-webkit-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-o-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:-ms-linear-gradient(top,#ebebeb 0,#dfdfdf 100%);background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover{background:#ededed;background:-moz-linear-gradient(top,#ededed 0,#fff 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#ededed),color-stop(100%,#fff));background:-webkit-linear-gradient(top,#ededed 0,#fff 100%);background:-o-linear-gradient(top,#ededed 0,#fff 100%);background:-ms-linear-gradient(top,#ededed 0,#fff 100%);background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:0 0;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:5px;z-index:5}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:3px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 12px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;-moz-box-shadow:0 0 6px rgba(0,0,0,.4) inset;-webkit-box-shadow:0 0 6px rgba(0,0,0,.4) inset;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:20px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:-webkit-gradient(linear,0 0,0 100%,from(#9ad717),to(#69b10b));background-image:-webkit-linear-gradient(top,#9ad717,#69b10b);background-image:-o-linear-gradient(top,#9ad717,#69b10b);background-image:linear-gradient(to bottom,#9ad717,#69b10b);background-image:-moz-linear-gradient(top,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#88be14),color-stop(100%,#5d9c0a));background:-webkit-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:-o-linear-gradient(top,#88be14 0,#5d9c0a 100%);background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);background:-moz-linear-gradient(top,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:2px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:24px;line-height:24px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:2px 6px;outline:0;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;-webkit-box-shadow:0 1px 2px rgba(0,0,0,.15) inset;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_dialog_footer{display:block;height:38px}.cke_ltr .cke_dialog_footer>*{float:right}.cke_rtl .cke_dialog_footer>*{float:left}"
  },
  {
    "path": "public/static/plugins/ckeditor/skins/moono/editor.css",
    "content": "/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none}.cke_reset_all,.cke_reset_all *{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre}.cke_reset_all textarea,.cke_reset_all input[type=\"text\"],.cke_reset_all input[type=\"password\"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type=\"text\"][disabled],.cke_reset_all input[type=\"password\"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup *:first-child{-moz-border-radius:0 2px 2px 0;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.cke_rtl .cke_toolgroup *:last-child{-moz-border-radius:2px 0 0 2px;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}.cke_button_on{-moz-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{-moz-box-shadow:0 0 1px rgba(0,0,0,.3) inset;-webkit-box-shadow:0 0 1px rgba(0,0,0,.3) inset;box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;-webkit-box-shadow:1px 0 1px rgba(255,255,255,.5);-moz-box-shadow:1px 0 1px rgba(255,255,255,.5);box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;-webkit-box-shadow:-1px 0 1px rgba(255,255,255,.1);-moz-box-shadow:-1px 0 1px rgba(255,255,255,.1);box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}.cke_combo_button{display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}.cke_path_item,.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);-webkit-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}.cke_button__about_icon {background: url(icons.png) no-repeat 0 -0px !important;}.cke_button__bold_icon {background: url(icons.png) no-repeat 0 -24px !important;}.cke_button__italic_icon {background: url(icons.png) no-repeat 0 -48px !important;}.cke_button__strike_icon {background: url(icons.png) no-repeat 0 -72px !important;}.cke_button__subscript_icon {background: url(icons.png) no-repeat 0 -96px !important;}.cke_button__superscript_icon {background: url(icons.png) no-repeat 0 -120px !important;}.cke_button__underline_icon {background: url(icons.png) no-repeat 0 -144px !important;}.cke_button__blockquote_icon {background: url(icons.png) no-repeat 0 -168px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -192px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -216px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -240px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -264px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -288px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -312px !important;}.cke_button__horizontalrule_icon {background: url(icons.png) no-repeat 0 -336px !important;}.cke_button__image_icon {background: url(icons.png) no-repeat 0 -360px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -384px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -408px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -432px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -456px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -480px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -504px !important;}.cke_button__link_icon {background: url(icons.png) no-repeat 0 -528px !important;}.cke_button__unlink_icon {background: url(icons.png) no-repeat 0 -552px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -576px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -600px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -624px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -648px !important;}.cke_button__maximize_icon {background: url(icons.png) no-repeat 0 -672px !important;}.cke_rtl .cke_button__pastetext_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -696px !important;}.cke_ltr .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -720px !important;}.cke_rtl .cke_button__pastefromword_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -744px !important;}.cke_ltr .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -768px !important;}.cke_button__removeformat_icon {background: url(icons.png) no-repeat 0 -792px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png) no-repeat 0 -816px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png) no-repeat 0 -840px !important;}.cke_button__specialchar_icon {background: url(icons.png) no-repeat 0 -864px !important;}.cke_button__scayt_icon {background: url(icons.png) no-repeat 0 -888px !important;}.cke_button__table_icon {background: url(icons.png) no-repeat 0 -912px !important;}.cke_rtl .cke_button__redo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -936px !important;}.cke_ltr .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -960px !important;}.cke_rtl .cke_button__undo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -984px !important;}.cke_ltr .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -1008px !important;}.cke_button__spellchecker_icon {background: url(icons.png) no-repeat 0 -1032px !important;}.cke_hidpi .cke_button__about_icon {background: url(icons_hidpi.png) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__blockquote_icon {background: url(icons_hidpi.png) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastetext_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastetext_icon,.cke_ltr.cke_hidpi .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastefromword_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastefromword_icon,.cke_ltr.cke_hidpi .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -840px !important;background-size: 16px !important;}.cke_hidpi .cke_button__specialchar_icon {background: url(icons_hidpi.png) no-repeat 0 -864px !important;background-size: 16px !important;}.cke_hidpi .cke_button__scayt_icon {background: url(icons_hidpi.png) no-repeat 0 -888px !important;background-size: 16px !important;}.cke_hidpi .cke_button__table_icon {background: url(icons_hidpi.png) no-repeat 0 -912px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__redo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -936px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__redo_icon,.cke_ltr.cke_hidpi .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -960px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__undo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -984px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__undo_icon,.cke_ltr.cke_hidpi .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -1008px !important;background-size: 16px !important;}.cke_hidpi .cke_button__spellchecker_icon {background: url(icons_hidpi.png) no-repeat 0 -1032px !important;background-size: 16px !important;}"
  },
  {
    "path": "public/static/plugins/ckeditor/skins/moono/editor_gecko.css",
    "content": "/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none}.cke_reset_all,.cke_reset_all *{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre}.cke_reset_all textarea,.cke_reset_all input[type=\"text\"],.cke_reset_all input[type=\"password\"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type=\"text\"][disabled],.cke_reset_all input[type=\"password\"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup *:first-child{-moz-border-radius:0 2px 2px 0;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.cke_rtl .cke_toolgroup *:last-child{-moz-border-radius:2px 0 0 2px;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}.cke_button_on{-moz-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{-moz-box-shadow:0 0 1px rgba(0,0,0,.3) inset;-webkit-box-shadow:0 0 1px rgba(0,0,0,.3) inset;box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;-webkit-box-shadow:1px 0 1px rgba(255,255,255,.5);-moz-box-shadow:1px 0 1px rgba(255,255,255,.5);box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;-webkit-box-shadow:-1px 0 1px rgba(255,255,255,.1);-moz-box-shadow:-1px 0 1px rgba(255,255,255,.1);box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}.cke_combo_button{display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}.cke_path_item,.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);-webkit-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}.cke_bottom{padding-bottom:3px}.cke_combo_text{margin-bottom:-1px;margin-top:1px}.cke_button__about_icon {background: url(icons.png) no-repeat 0 -0px !important;}.cke_button__bold_icon {background: url(icons.png) no-repeat 0 -24px !important;}.cke_button__italic_icon {background: url(icons.png) no-repeat 0 -48px !important;}.cke_button__strike_icon {background: url(icons.png) no-repeat 0 -72px !important;}.cke_button__subscript_icon {background: url(icons.png) no-repeat 0 -96px !important;}.cke_button__superscript_icon {background: url(icons.png) no-repeat 0 -120px !important;}.cke_button__underline_icon {background: url(icons.png) no-repeat 0 -144px !important;}.cke_button__blockquote_icon {background: url(icons.png) no-repeat 0 -168px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -192px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -216px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -240px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -264px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -288px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -312px !important;}.cke_button__horizontalrule_icon {background: url(icons.png) no-repeat 0 -336px !important;}.cke_button__image_icon {background: url(icons.png) no-repeat 0 -360px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -384px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -408px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -432px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -456px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -480px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -504px !important;}.cke_button__link_icon {background: url(icons.png) no-repeat 0 -528px !important;}.cke_button__unlink_icon {background: url(icons.png) no-repeat 0 -552px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -576px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -600px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -624px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -648px !important;}.cke_button__maximize_icon {background: url(icons.png) no-repeat 0 -672px !important;}.cke_rtl .cke_button__pastetext_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -696px !important;}.cke_ltr .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -720px !important;}.cke_rtl .cke_button__pastefromword_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -744px !important;}.cke_ltr .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -768px !important;}.cke_button__removeformat_icon {background: url(icons.png) no-repeat 0 -792px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png) no-repeat 0 -816px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png) no-repeat 0 -840px !important;}.cke_button__specialchar_icon {background: url(icons.png) no-repeat 0 -864px !important;}.cke_button__scayt_icon {background: url(icons.png) no-repeat 0 -888px !important;}.cke_button__table_icon {background: url(icons.png) no-repeat 0 -912px !important;}.cke_rtl .cke_button__redo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -936px !important;}.cke_ltr .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -960px !important;}.cke_rtl .cke_button__undo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -984px !important;}.cke_ltr .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -1008px !important;}.cke_button__spellchecker_icon {background: url(icons.png) no-repeat 0 -1032px !important;}.cke_hidpi .cke_button__about_icon {background: url(icons_hidpi.png) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__blockquote_icon {background: url(icons_hidpi.png) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastetext_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastetext_icon,.cke_ltr.cke_hidpi .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastefromword_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastefromword_icon,.cke_ltr.cke_hidpi .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -840px !important;background-size: 16px !important;}.cke_hidpi .cke_button__specialchar_icon {background: url(icons_hidpi.png) no-repeat 0 -864px !important;background-size: 16px !important;}.cke_hidpi .cke_button__scayt_icon {background: url(icons_hidpi.png) no-repeat 0 -888px !important;background-size: 16px !important;}.cke_hidpi .cke_button__table_icon {background: url(icons_hidpi.png) no-repeat 0 -912px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__redo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -936px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__redo_icon,.cke_ltr.cke_hidpi .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -960px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__undo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -984px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__undo_icon,.cke_ltr.cke_hidpi .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -1008px !important;background-size: 16px !important;}.cke_hidpi .cke_button__spellchecker_icon {background: url(icons_hidpi.png) no-repeat 0 -1032px !important;background-size: 16px !important;}"
  },
  {
    "path": "public/static/plugins/ckeditor/skins/moono/editor_ie.css",
    "content": "/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none}.cke_reset_all,.cke_reset_all *{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre}.cke_reset_all textarea,.cke_reset_all input[type=\"text\"],.cke_reset_all input[type=\"password\"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type=\"text\"][disabled],.cke_reset_all input[type=\"password\"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup *:first-child{-moz-border-radius:0 2px 2px 0;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.cke_rtl .cke_toolgroup *:last-child{-moz-border-radius:2px 0 0 2px;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}.cke_button_on{-moz-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{-moz-box-shadow:0 0 1px rgba(0,0,0,.3) inset;-webkit-box-shadow:0 0 1px rgba(0,0,0,.3) inset;box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;-webkit-box-shadow:1px 0 1px rgba(255,255,255,.5);-moz-box-shadow:1px 0 1px rgba(255,255,255,.5);box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;-webkit-box-shadow:-1px 0 1px rgba(255,255,255,.1);-moz-box-shadow:-1px 0 1px rgba(255,255,255,.1);box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}.cke_combo_button{display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}.cke_path_item,.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);-webkit-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}a.cke_button_disabled,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{filter:alpha(opacity = 30)}.cke_button_disabled .cke_button_icon{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00ffffff,endColorstr=#00ffffff)}.cke_button_off:hover,.cke_button_off:focus,.cke_button_off:active{filter:alpha(opacity = 100)}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{filter:alpha(opacity = 30)}.cke_toolbox_collapser{border:1px solid #a6a6a6}.cke_toolbox_collapser .cke_arrow{margin-top:1px}.cke_hc .cke_top,.cke_hc .cke_bottom,.cke_hc .cke_combo_button,.cke_hc a.cke_combo_button:hover,.cke_hc a.cke_combo_button:focus,.cke_hc .cke_toolgroup,.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc .cke_toolbox_collapser,.cke_hc .cke_toolbox_collapser:hover,.cke_hc .cke_panel_grouptitle{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_button__about_icon {background: url(icons.png) no-repeat 0 -0px !important;}.cke_button__bold_icon {background: url(icons.png) no-repeat 0 -24px !important;}.cke_button__italic_icon {background: url(icons.png) no-repeat 0 -48px !important;}.cke_button__strike_icon {background: url(icons.png) no-repeat 0 -72px !important;}.cke_button__subscript_icon {background: url(icons.png) no-repeat 0 -96px !important;}.cke_button__superscript_icon {background: url(icons.png) no-repeat 0 -120px !important;}.cke_button__underline_icon {background: url(icons.png) no-repeat 0 -144px !important;}.cke_button__blockquote_icon {background: url(icons.png) no-repeat 0 -168px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -192px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -216px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -240px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -264px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -288px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -312px !important;}.cke_button__horizontalrule_icon {background: url(icons.png) no-repeat 0 -336px !important;}.cke_button__image_icon {background: url(icons.png) no-repeat 0 -360px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -384px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -408px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -432px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -456px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -480px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -504px !important;}.cke_button__link_icon {background: url(icons.png) no-repeat 0 -528px !important;}.cke_button__unlink_icon {background: url(icons.png) no-repeat 0 -552px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -576px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -600px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -624px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -648px !important;}.cke_button__maximize_icon {background: url(icons.png) no-repeat 0 -672px !important;}.cke_rtl .cke_button__pastetext_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -696px !important;}.cke_ltr .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -720px !important;}.cke_rtl .cke_button__pastefromword_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -744px !important;}.cke_ltr .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -768px !important;}.cke_button__removeformat_icon {background: url(icons.png) no-repeat 0 -792px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png) no-repeat 0 -816px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png) no-repeat 0 -840px !important;}.cke_button__specialchar_icon {background: url(icons.png) no-repeat 0 -864px !important;}.cke_button__scayt_icon {background: url(icons.png) no-repeat 0 -888px !important;}.cke_button__table_icon {background: url(icons.png) no-repeat 0 -912px !important;}.cke_rtl .cke_button__redo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -936px !important;}.cke_ltr .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -960px !important;}.cke_rtl .cke_button__undo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -984px !important;}.cke_ltr .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -1008px !important;}.cke_button__spellchecker_icon {background: url(icons.png) no-repeat 0 -1032px !important;}.cke_hidpi .cke_button__about_icon {background: url(icons_hidpi.png) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__blockquote_icon {background: url(icons_hidpi.png) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastetext_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastetext_icon,.cke_ltr.cke_hidpi .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastefromword_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastefromword_icon,.cke_ltr.cke_hidpi .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -840px !important;background-size: 16px !important;}.cke_hidpi .cke_button__specialchar_icon {background: url(icons_hidpi.png) no-repeat 0 -864px !important;background-size: 16px !important;}.cke_hidpi .cke_button__scayt_icon {background: url(icons_hidpi.png) no-repeat 0 -888px !important;background-size: 16px !important;}.cke_hidpi .cke_button__table_icon {background: url(icons_hidpi.png) no-repeat 0 -912px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__redo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -936px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__redo_icon,.cke_ltr.cke_hidpi .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -960px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__undo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -984px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__undo_icon,.cke_ltr.cke_hidpi .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -1008px !important;background-size: 16px !important;}.cke_hidpi .cke_button__spellchecker_icon {background: url(icons_hidpi.png) no-repeat 0 -1032px !important;background-size: 16px !important;}"
  },
  {
    "path": "public/static/plugins/ckeditor/skins/moono/editor_ie7.css",
    "content": "/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none}.cke_reset_all,.cke_reset_all *{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre}.cke_reset_all textarea,.cke_reset_all input[type=\"text\"],.cke_reset_all input[type=\"password\"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type=\"text\"][disabled],.cke_reset_all input[type=\"password\"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup *:first-child{-moz-border-radius:0 2px 2px 0;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.cke_rtl .cke_toolgroup *:last-child{-moz-border-radius:2px 0 0 2px;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}.cke_button_on{-moz-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{-moz-box-shadow:0 0 1px rgba(0,0,0,.3) inset;-webkit-box-shadow:0 0 1px rgba(0,0,0,.3) inset;box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;-webkit-box-shadow:1px 0 1px rgba(255,255,255,.5);-moz-box-shadow:1px 0 1px rgba(255,255,255,.5);box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;-webkit-box-shadow:-1px 0 1px rgba(255,255,255,.1);-moz-box-shadow:-1px 0 1px rgba(255,255,255,.1);box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}.cke_combo_button{display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}.cke_path_item,.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);-webkit-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}a.cke_button_disabled,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{filter:alpha(opacity = 30)}.cke_button_disabled .cke_button_icon{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00ffffff,endColorstr=#00ffffff)}.cke_button_off:hover,.cke_button_off:focus,.cke_button_off:active{filter:alpha(opacity = 100)}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{filter:alpha(opacity = 30)}.cke_toolbox_collapser{border:1px solid #a6a6a6}.cke_toolbox_collapser .cke_arrow{margin-top:1px}.cke_hc .cke_top,.cke_hc .cke_bottom,.cke_hc .cke_combo_button,.cke_hc a.cke_combo_button:hover,.cke_hc a.cke_combo_button:focus,.cke_hc .cke_toolgroup,.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc .cke_toolbox_collapser,.cke_hc .cke_toolbox_collapser:hover,.cke_hc .cke_panel_grouptitle{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_rtl .cke_toolgroup,.cke_rtl .cke_toolbar_separator,.cke_rtl .cke_button,.cke_rtl .cke_button *,.cke_rtl .cke_combo,.cke_rtl .cke_combo *,.cke_rtl .cke_path_item,.cke_rtl .cke_path_item *,.cke_rtl .cke_path_empty{float:none}.cke_rtl .cke_toolgroup,.cke_rtl .cke_toolbar_separator,.cke_rtl .cke_combo_button,.cke_rtl .cke_combo_button *,.cke_rtl .cke_button,.cke_rtl .cke_button_icon,{display:inline-block;vertical-align:top}.cke_toolbox{display:inline-block;padding-bottom:5px;height:100%}.cke_rtl .cke_toolbox{padding-bottom:0}.cke_toolbar{margin-bottom:5px}.cke_rtl .cke_toolbar{margin-bottom:0}.cke_toolgroup{height:26px}.cke_toolgroup,.cke_combo{position:relative}a.cke_button{float:none;vertical-align:top}.cke_toolbar_separator{display:inline-block;float:none;vertical-align:top;background-color:#c0c0c0}.cke_toolbox_collapser .cke_arrow{margin-top:0}.cke_toolbox_collapser .cke_arrow{border-width:4px}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{border-width:3px}.cke_rtl .cke_button_arrow{padding-top:8px;margin-right:2px}.cke_rtl .cke_combo_inlinelabel{display:table-cell;vertical-align:middle}.cke_menubutton{display:block;height:24px}.cke_menubutton_inner{display:block;position:relative}.cke_menubutton_icon{height:16px;width:16px}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:inline-block}.cke_menubutton_label{width:auto;vertical-align:top;line-height:24px;height:24px;margin:0 10px 0 0}.cke_menuarrow{width:5px;height:6px;padding:0;position:absolute;right:8px;top:10px;background-position:0 0}.cke_rtl .cke_menubutton_icon{position:absolute;right:0;top:0}.cke_rtl .cke_menubutton_label{float:right;clear:both;margin:0 24px 0 10px}.cke_hc .cke_rtl .cke_menubutton_label{margin-right:0}.cke_rtl .cke_menuarrow{left:8px;right:auto;background-position:0 -24px}.cke_hc .cke_menuarrow{top:5px;padding:0 5px}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{position:relative}.cke_wysiwyg_div{padding-top:0!important;padding-bottom:0!important}.cke_button__about_icon {background: url(icons.png) no-repeat 0 -0px !important;}.cke_button__bold_icon {background: url(icons.png) no-repeat 0 -24px !important;}.cke_button__italic_icon {background: url(icons.png) no-repeat 0 -48px !important;}.cke_button__strike_icon {background: url(icons.png) no-repeat 0 -72px !important;}.cke_button__subscript_icon {background: url(icons.png) no-repeat 0 -96px !important;}.cke_button__superscript_icon {background: url(icons.png) no-repeat 0 -120px !important;}.cke_button__underline_icon {background: url(icons.png) no-repeat 0 -144px !important;}.cke_button__blockquote_icon {background: url(icons.png) no-repeat 0 -168px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -192px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -216px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -240px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -264px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -288px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -312px !important;}.cke_button__horizontalrule_icon {background: url(icons.png) no-repeat 0 -336px !important;}.cke_button__image_icon {background: url(icons.png) no-repeat 0 -360px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -384px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -408px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -432px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -456px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -480px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -504px !important;}.cke_button__link_icon {background: url(icons.png) no-repeat 0 -528px !important;}.cke_button__unlink_icon {background: url(icons.png) no-repeat 0 -552px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -576px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -600px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -624px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -648px !important;}.cke_button__maximize_icon {background: url(icons.png) no-repeat 0 -672px !important;}.cke_rtl .cke_button__pastetext_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -696px !important;}.cke_ltr .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -720px !important;}.cke_rtl .cke_button__pastefromword_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -744px !important;}.cke_ltr .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -768px !important;}.cke_button__removeformat_icon {background: url(icons.png) no-repeat 0 -792px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png) no-repeat 0 -816px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png) no-repeat 0 -840px !important;}.cke_button__specialchar_icon {background: url(icons.png) no-repeat 0 -864px !important;}.cke_button__scayt_icon {background: url(icons.png) no-repeat 0 -888px !important;}.cke_button__table_icon {background: url(icons.png) no-repeat 0 -912px !important;}.cke_rtl .cke_button__redo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -936px !important;}.cke_ltr .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -960px !important;}.cke_rtl .cke_button__undo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -984px !important;}.cke_ltr .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -1008px !important;}.cke_button__spellchecker_icon {background: url(icons.png) no-repeat 0 -1032px !important;}.cke_hidpi .cke_button__about_icon {background: url(icons_hidpi.png) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__blockquote_icon {background: url(icons_hidpi.png) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastetext_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastetext_icon,.cke_ltr.cke_hidpi .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastefromword_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastefromword_icon,.cke_ltr.cke_hidpi .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -840px !important;background-size: 16px !important;}.cke_hidpi .cke_button__specialchar_icon {background: url(icons_hidpi.png) no-repeat 0 -864px !important;background-size: 16px !important;}.cke_hidpi .cke_button__scayt_icon {background: url(icons_hidpi.png) no-repeat 0 -888px !important;background-size: 16px !important;}.cke_hidpi .cke_button__table_icon {background: url(icons_hidpi.png) no-repeat 0 -912px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__redo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -936px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__redo_icon,.cke_ltr.cke_hidpi .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -960px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__undo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -984px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__undo_icon,.cke_ltr.cke_hidpi .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -1008px !important;background-size: 16px !important;}.cke_hidpi .cke_button__spellchecker_icon {background: url(icons_hidpi.png) no-repeat 0 -1032px !important;background-size: 16px !important;}"
  },
  {
    "path": "public/static/plugins/ckeditor/skins/moono/editor_ie8.css",
    "content": "/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none}.cke_reset_all,.cke_reset_all *{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre}.cke_reset_all textarea,.cke_reset_all input[type=\"text\"],.cke_reset_all input[type=\"password\"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type=\"text\"][disabled],.cke_reset_all input[type=\"password\"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup *:first-child{-moz-border-radius:0 2px 2px 0;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.cke_rtl .cke_toolgroup *:last-child{-moz-border-radius:2px 0 0 2px;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}.cke_button_on{-moz-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{-moz-box-shadow:0 0 1px rgba(0,0,0,.3) inset;-webkit-box-shadow:0 0 1px rgba(0,0,0,.3) inset;box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;-webkit-box-shadow:1px 0 1px rgba(255,255,255,.5);-moz-box-shadow:1px 0 1px rgba(255,255,255,.5);box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;-webkit-box-shadow:-1px 0 1px rgba(255,255,255,.1);-moz-box-shadow:-1px 0 1px rgba(255,255,255,.1);box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}.cke_combo_button{display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}.cke_path_item,.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);-webkit-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}a.cke_button_disabled,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{filter:alpha(opacity = 30)}.cke_button_disabled .cke_button_icon{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00ffffff,endColorstr=#00ffffff)}.cke_button_off:hover,.cke_button_off:focus,.cke_button_off:active{filter:alpha(opacity = 100)}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{filter:alpha(opacity = 30)}.cke_toolbox_collapser{border:1px solid #a6a6a6}.cke_toolbox_collapser .cke_arrow{margin-top:1px}.cke_hc .cke_top,.cke_hc .cke_bottom,.cke_hc .cke_combo_button,.cke_hc a.cke_combo_button:hover,.cke_hc a.cke_combo_button:focus,.cke_hc .cke_toolgroup,.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc .cke_toolbox_collapser,.cke_hc .cke_toolbox_collapser:hover,.cke_hc .cke_panel_grouptitle{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_toolbox_collapser .cke_arrow{border-width:4px}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{border-width:3px}.cke_toolbox_collapser .cke_arrow{margin-top:0}.cke_button__about_icon {background: url(icons.png) no-repeat 0 -0px !important;}.cke_button__bold_icon {background: url(icons.png) no-repeat 0 -24px !important;}.cke_button__italic_icon {background: url(icons.png) no-repeat 0 -48px !important;}.cke_button__strike_icon {background: url(icons.png) no-repeat 0 -72px !important;}.cke_button__subscript_icon {background: url(icons.png) no-repeat 0 -96px !important;}.cke_button__superscript_icon {background: url(icons.png) no-repeat 0 -120px !important;}.cke_button__underline_icon {background: url(icons.png) no-repeat 0 -144px !important;}.cke_button__blockquote_icon {background: url(icons.png) no-repeat 0 -168px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -192px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -216px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -240px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -264px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -288px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -312px !important;}.cke_button__horizontalrule_icon {background: url(icons.png) no-repeat 0 -336px !important;}.cke_button__image_icon {background: url(icons.png) no-repeat 0 -360px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -384px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -408px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -432px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -456px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -480px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -504px !important;}.cke_button__link_icon {background: url(icons.png) no-repeat 0 -528px !important;}.cke_button__unlink_icon {background: url(icons.png) no-repeat 0 -552px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -576px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -600px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -624px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -648px !important;}.cke_button__maximize_icon {background: url(icons.png) no-repeat 0 -672px !important;}.cke_rtl .cke_button__pastetext_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -696px !important;}.cke_ltr .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -720px !important;}.cke_rtl .cke_button__pastefromword_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -744px !important;}.cke_ltr .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -768px !important;}.cke_button__removeformat_icon {background: url(icons.png) no-repeat 0 -792px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png) no-repeat 0 -816px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png) no-repeat 0 -840px !important;}.cke_button__specialchar_icon {background: url(icons.png) no-repeat 0 -864px !important;}.cke_button__scayt_icon {background: url(icons.png) no-repeat 0 -888px !important;}.cke_button__table_icon {background: url(icons.png) no-repeat 0 -912px !important;}.cke_rtl .cke_button__redo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -936px !important;}.cke_ltr .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -960px !important;}.cke_rtl .cke_button__undo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -984px !important;}.cke_ltr .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -1008px !important;}.cke_button__spellchecker_icon {background: url(icons.png) no-repeat 0 -1032px !important;}.cke_hidpi .cke_button__about_icon {background: url(icons_hidpi.png) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__blockquote_icon {background: url(icons_hidpi.png) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastetext_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastetext_icon,.cke_ltr.cke_hidpi .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastefromword_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastefromword_icon,.cke_ltr.cke_hidpi .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -840px !important;background-size: 16px !important;}.cke_hidpi .cke_button__specialchar_icon {background: url(icons_hidpi.png) no-repeat 0 -864px !important;background-size: 16px !important;}.cke_hidpi .cke_button__scayt_icon {background: url(icons_hidpi.png) no-repeat 0 -888px !important;background-size: 16px !important;}.cke_hidpi .cke_button__table_icon {background: url(icons_hidpi.png) no-repeat 0 -912px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__redo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -936px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__redo_icon,.cke_ltr.cke_hidpi .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -960px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__undo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -984px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__undo_icon,.cke_ltr.cke_hidpi .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -1008px !important;background-size: 16px !important;}.cke_hidpi .cke_button__spellchecker_icon {background: url(icons_hidpi.png) no-repeat 0 -1032px !important;background-size: 16px !important;}"
  },
  {
    "path": "public/static/plugins/ckeditor/skins/moono/editor_iequirks.css",
    "content": "/*\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\nFor licensing, see LICENSE.md or http://ckeditor.com/license\n*/\n.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none}.cke_reset_all,.cke_reset_all *{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;position:static;-webkit-transition:none;-moz-transition:none;-ms-transition:none;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre}.cke_reset_all textarea,.cke_reset_all input[type=\"text\"],.cke_reset_all input[type=\"password\"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type=\"text\"][disabled],.cke_reset_all input[type=\"password\"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#ebebeb),to(#cfd1cf));background-image:-moz-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-webkit-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-o-linear-gradient(top,#ebebeb,#cfd1cf);background-image:-ms-linear-gradient(top,#ebebeb,#cfd1cf);background-image:linear-gradient(top,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.3);-webkit-box-shadow:0 1px 0 rgba(255,255,255,.3);box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 0 3px rgba(0,0,0,.15);-webkit-box-shadow:0 0 3px rgba(0,0,0,.15);box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;-moz-border-radius:2px 2px 0 0;-webkit-border-radius:2px 2px 0 0;border-radius:2px 2px 0 0;-moz-box-shadow:0 1px 0 #fff inset;-webkit-box-shadow:0 1px 0 #fff inset;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:-webkit-gradient(linear,left top,left bottom,from(#f5f5f5),to(#cfd1cf));background-image:-moz-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-webkit-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-o-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:-ms-linear-gradient(top,#f5f5f5,#cfd1cf);background-image:linear-gradient(top,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup *:first-child{-moz-border-radius:0 2px 2px 0;-webkit-border-radius:0 2px 2px 0;border-radius:0 2px 2px 0}.cke_rtl .cke_toolgroup *:last-child{-moz-border-radius:2px 0 0 2px;-webkit-border-radius:2px 0 0 2px;border-radius:2px 0 0 2px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}.cke_button_on{-moz-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{-moz-box-shadow:0 0 1px rgba(0,0,0,.3) inset;-webkit-box-shadow:0 0 1px rgba(0,0,0,.3) inset;box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;-webkit-box-shadow:1px 0 1px rgba(255,255,255,.5);-moz-box-shadow:1px 0 1px rgba(255,255,255,.5);box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;-webkit-box-shadow:-1px 0 1px rgba(255,255,255,.1);-moz-box-shadow:-1px 0 1px rgba(255,255,255,.1);box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;-moz-box-shadow:0 0 2px rgba(0,0,0,.1) inset;-webkit-box-shadow:0 0 2px rgba(0,0,0,.1) inset;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}.cke_combo_button{display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:-webkit-gradient(linear,left top,left bottom,from(#fff),to(#e4e4e4));background-image:-moz-linear-gradient(top,#fff,#e4e4e4);background-image:-webkit-linear-gradient(top,#fff,#e4e4e4);background-image:-o-linear-gradient(top,#fff,#e4e4e4);background-image:-ms-linear-gradient(top,#fff,#e4e4e4);background-image:linear-gradient(top,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:-webkit-gradient(linear,left top,left bottom,from(#f2f2f2),to(#ccc));background-image:-moz-linear-gradient(top,#f2f2f2,#ccc);background-image:-webkit-linear-gradient(top,#f2f2f2,#ccc);background-image:-o-linear-gradient(top,#f2f2f2,#ccc);background-image:-ms-linear-gradient(top,#f2f2f2,#ccc);background-image:linear-gradient(top,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;-moz-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;-webkit-box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:-webkit-gradient(linear,left top,left bottom,from(#aaa),to(#cacaca));background-image:-moz-linear-gradient(top,#aaa,#cacaca);background-image:-webkit-linear-gradient(top,#aaa,#cacaca);background-image:-o-linear-gradient(top,#aaa,#cacaca);background-image:-ms-linear-gradient(top,#aaa,#cacaca);background-image:linear-gradient(top,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{-moz-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);-webkit-box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2);box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}.cke_path_item,.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);-moz-border-radius:2px;-webkit-border-radius:2px;border-radius:2px;-moz-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);-webkit-box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5);box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}a.cke_button_disabled,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{filter:alpha(opacity = 30)}.cke_button_disabled .cke_button_icon{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00ffffff,endColorstr=#00ffffff)}.cke_button_off:hover,.cke_button_off:focus,.cke_button_off:active{filter:alpha(opacity = 100)}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{filter:alpha(opacity = 30)}.cke_toolbox_collapser{border:1px solid #a6a6a6}.cke_toolbox_collapser .cke_arrow{margin-top:1px}.cke_hc .cke_top,.cke_hc .cke_bottom,.cke_hc .cke_combo_button,.cke_hc a.cke_combo_button:hover,.cke_hc a.cke_combo_button:focus,.cke_hc .cke_toolgroup,.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc .cke_toolbox_collapser,.cke_hc .cke_toolbox_collapser:hover,.cke_hc .cke_panel_grouptitle{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_top,.cke_contents,.cke_bottom{width:100%}.cke_button_arrow{font-size:0}.cke_rtl .cke_toolgroup,.cke_rtl .cke_toolbar_separator,.cke_rtl .cke_button,.cke_rtl .cke_button *,.cke_rtl .cke_combo,.cke_rtl .cke_combo *,.cke_rtl .cke_path_item,.cke_rtl .cke_path_item *,.cke_rtl .cke_path_empty{float:none}.cke_rtl .cke_toolgroup,.cke_rtl .cke_toolbar_separator,.cke_rtl .cke_combo_button,.cke_rtl .cke_combo_button *,.cke_rtl .cke_button,.cke_rtl .cke_button_icon,{display:inline-block;vertical-align:top}.cke_rtl .cke_button_icon{float:none}.cke_resizer{width:10px}.cke_source{white-space:normal}.cke_bottom{position:static}.cke_colorbox{font-size:0}.cke_button__about_icon {background: url(icons.png) no-repeat 0 -0px !important;}.cke_button__bold_icon {background: url(icons.png) no-repeat 0 -24px !important;}.cke_button__italic_icon {background: url(icons.png) no-repeat 0 -48px !important;}.cke_button__strike_icon {background: url(icons.png) no-repeat 0 -72px !important;}.cke_button__subscript_icon {background: url(icons.png) no-repeat 0 -96px !important;}.cke_button__superscript_icon {background: url(icons.png) no-repeat 0 -120px !important;}.cke_button__underline_icon {background: url(icons.png) no-repeat 0 -144px !important;}.cke_button__blockquote_icon {background: url(icons.png) no-repeat 0 -168px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -192px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png) no-repeat 0 -216px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -240px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png) no-repeat 0 -264px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -288px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png) no-repeat 0 -312px !important;}.cke_button__horizontalrule_icon {background: url(icons.png) no-repeat 0 -336px !important;}.cke_button__image_icon {background: url(icons.png) no-repeat 0 -360px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -384px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png) no-repeat 0 -408px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -432px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png) no-repeat 0 -456px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -480px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png) no-repeat 0 -504px !important;}.cke_button__link_icon {background: url(icons.png) no-repeat 0 -528px !important;}.cke_button__unlink_icon {background: url(icons.png) no-repeat 0 -552px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -576px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png) no-repeat 0 -600px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -624px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png) no-repeat 0 -648px !important;}.cke_button__maximize_icon {background: url(icons.png) no-repeat 0 -672px !important;}.cke_rtl .cke_button__pastetext_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -696px !important;}.cke_ltr .cke_button__pastetext_icon {background: url(icons.png) no-repeat 0 -720px !important;}.cke_rtl .cke_button__pastefromword_icon, .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -744px !important;}.cke_ltr .cke_button__pastefromword_icon {background: url(icons.png) no-repeat 0 -768px !important;}.cke_button__removeformat_icon {background: url(icons.png) no-repeat 0 -792px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png) no-repeat 0 -816px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png) no-repeat 0 -840px !important;}.cke_button__specialchar_icon {background: url(icons.png) no-repeat 0 -864px !important;}.cke_button__scayt_icon {background: url(icons.png) no-repeat 0 -888px !important;}.cke_button__table_icon {background: url(icons.png) no-repeat 0 -912px !important;}.cke_rtl .cke_button__redo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -936px !important;}.cke_ltr .cke_button__redo_icon {background: url(icons.png) no-repeat 0 -960px !important;}.cke_rtl .cke_button__undo_icon, .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -984px !important;}.cke_ltr .cke_button__undo_icon {background: url(icons.png) no-repeat 0 -1008px !important;}.cke_button__spellchecker_icon {background: url(icons.png) no-repeat 0 -1032px !important;}.cke_hidpi .cke_button__about_icon {background: url(icons_hidpi.png) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__blockquote_icon {background: url(icons_hidpi.png) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastetext_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastetext_icon,.cke_ltr.cke_hidpi .cke_button__pastetext_icon {background: url(icons_hidpi.png) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__pastefromword_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__pastefromword_icon,.cke_ltr.cke_hidpi .cke_button__pastefromword_icon {background: url(icons_hidpi.png) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png) no-repeat 0 -840px !important;background-size: 16px !important;}.cke_hidpi .cke_button__specialchar_icon {background: url(icons_hidpi.png) no-repeat 0 -864px !important;background-size: 16px !important;}.cke_hidpi .cke_button__scayt_icon {background: url(icons_hidpi.png) no-repeat 0 -888px !important;background-size: 16px !important;}.cke_hidpi .cke_button__table_icon {background: url(icons_hidpi.png) no-repeat 0 -912px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__redo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -936px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__redo_icon,.cke_ltr.cke_hidpi .cke_button__redo_icon {background: url(icons_hidpi.png) no-repeat 0 -960px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__undo_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -984px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__undo_icon,.cke_ltr.cke_hidpi .cke_button__undo_icon {background: url(icons_hidpi.png) no-repeat 0 -1008px !important;background-size: 16px !important;}.cke_hidpi .cke_button__spellchecker_icon {background: url(icons_hidpi.png) no-repeat 0 -1032px !important;background-size: 16px !important;}"
  },
  {
    "path": "public/static/plugins/ckeditor/skins/moono/readme.md",
    "content": "\"Moono\" Skin\r\n====================\r\n\r\nThis skin has been chosen for the **default skin** of CKEditor 4.x, elected from the CKEditor\r\n[skin contest](http://ckeditor.com/blog/new_ckeditor_4_skin) and further shaped by\r\nthe CKEditor team. \"Moono\" is maintained by the core developers.\r\n\r\nFor more information about skins, please check the [CKEditor Skin SDK](http://docs.cksource.com/CKEditor_4.x/Skin_SDK)\r\ndocumentation.\r\n\r\nFeatures\r\n-------------------\r\n\"Moono\" is a monochromatic skin, which offers a modern look coupled with gradients and transparency.\r\nIt comes with the following features:\r\n\r\n- Chameleon feature with brightness,\r\n- high-contrast compatibility,\r\n- graphics source provided in SVG.\r\n\r\nDirectory Structure\r\n-------------------\r\n\r\nCSS parts:\r\n- **editor.css**: the main CSS file. It's simply loading several other files, for easier maintenance,\r\n- **mainui.css**: the file contains styles of entire editor outline structures,\r\n- **toolbar.css**: the file contains styles of the editor toolbar space (top),\r\n- **richcombo.css**: the file contains styles of the rich combo ui elements on toolbar,\r\n- **panel.css**: the file contains styles of the rich combo drop-down, it's not loaded\r\nuntil the first panel open up,\r\n- **elementspath.css**: the file contains styles of the editor elements path bar (bottom),\r\n- **menu.css**: the file contains styles of all editor menus including context menu and button drop-down,\r\nit's not loaded until the first menu open up,\r\n- **dialog.css**: the CSS files for the dialog UI, it's not loaded until the first dialog open,\r\n- **reset.css**: the file defines the basis of style resets among all editor UI spaces,\r\n- **preset.css**: the file defines the default styles of some UI elements reflecting the skin preference,\r\n- **editor_XYZ.css** and **dialog_XYZ.css**: browser specific CSS hacks.\r\n\r\nOther parts:\r\n- **skin.js**: the only JavaScript part of the skin that registers the skin, its browser specific files and its icons and defines the Chameleon feature,\r\n- **icons/**: contains all skin defined icons,\r\n- **images/**: contains a fill general used images,\r\n- **dev/**: contains SVG source of the skin icons.\r\n\r\nLicense\r\n-------\r\n\r\nCopyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\r\n\r\nLicensed under the terms of any of the following licenses at your choice: [GPL](http://www.gnu.org/licenses/gpl.html), [LGPL](http://www.gnu.org/licenses/lgpl.html) and [MPL](http://www.mozilla.org/MPL/MPL-1.1.html).\r\n\r\nSee LICENSE.md for more information.\r\n"
  },
  {
    "path": "public/static/plugins/ckeditor/styles.js",
    "content": "﻿/**\n * Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\n * For licensing, see LICENSE.md or http://ckeditor.com/license\n */\n\n// This file contains style definitions that can be used by CKEditor plugins.\n//\n// The most common use for it is the \"stylescombo\" plugin, which shows a combo\n// in the editor toolbar, containing all styles. Other plugins instead, like\n// the div plugin, use a subset of the styles on their feature.\n//\n// If you don't have plugins that depend on this file, you can simply ignore it.\n// Otherwise it is strongly recommended to customize this file to match your\n// website requirements and design properly.\n\nCKEDITOR.stylesSet.add( 'default', [\n\t/* Block Styles */\n\n\t// These styles are already available in the \"Format\" combo (\"format\" plugin),\n\t// so they are not needed here by default. You may enable them to avoid\n\t// placing the \"Format\" combo in the toolbar, maintaining the same features.\n\t/*\n\t{ name: 'Paragraph',\t\telement: 'p' },\n\t{ name: 'Heading 1',\t\telement: 'h1' },\n\t{ name: 'Heading 2',\t\telement: 'h2' },\n\t{ name: 'Heading 3',\t\telement: 'h3' },\n\t{ name: 'Heading 4',\t\telement: 'h4' },\n\t{ name: 'Heading 5',\t\telement: 'h5' },\n\t{ name: 'Heading 6',\t\telement: 'h6' },\n\t{ name: 'Preformatted Text',element: 'pre' },\n\t{ name: 'Address',\t\t\telement: 'address' },\n\t*/\n\n\t{ name: 'Italic Title',\t\telement: 'h2', styles: { 'font-style': 'italic' } },\n\t{ name: 'Subtitle',\t\t\telement: 'h3', styles: { 'color': '#aaa', 'font-style': 'italic' } },\n\t{\n\t\tname: 'Special Container',\n\t\telement: 'div',\n\t\tstyles: {\n\t\t\tpadding: '5px 10px',\n\t\t\tbackground: '#eee',\n\t\t\tborder: '1px solid #ccc'\n\t\t}\n\t},\n\n\t/* Inline Styles */\n\n\t// These are core styles available as toolbar buttons. You may opt enabling\n\t// some of them in the Styles combo, removing them from the toolbar.\n\t// (This requires the \"stylescombo\" plugin)\n\t/*\n\t{ name: 'Strong',\t\t\telement: 'strong', overrides: 'b' },\n\t{ name: 'Emphasis',\t\t\telement: 'em'\t, overrides: 'i' },\n\t{ name: 'Underline',\t\telement: 'u' },\n\t{ name: 'Strikethrough',\telement: 'strike' },\n\t{ name: 'Subscript',\t\telement: 'sub' },\n\t{ name: 'Superscript',\t\telement: 'sup' },\n\t*/\n\n\t{ name: 'Marker',\t\t\telement: 'span', attributes: { 'class': 'marker' } },\n\n\t{ name: 'Big',\t\t\t\telement: 'big' },\n\t{ name: 'Small',\t\t\telement: 'small' },\n\t{ name: 'Typewriter',\t\telement: 'tt' },\n\n\t{ name: 'Computer Code',\telement: 'code' },\n\t{ name: 'Keyboard Phrase',\telement: 'kbd' },\n\t{ name: 'Sample Text',\t\telement: 'samp' },\n\t{ name: 'Variable',\t\t\telement: 'var' },\n\n\t{ name: 'Deleted Text',\t\telement: 'del' },\n\t{ name: 'Inserted Text',\telement: 'ins' },\n\n\t{ name: 'Cited Work',\t\telement: 'cite' },\n\t{ name: 'Inline Quotation',\telement: 'q' },\n\n\t{ name: 'Language: RTL',\telement: 'span', attributes: { 'dir': 'rtl' } },\n\t{ name: 'Language: LTR',\telement: 'span', attributes: { 'dir': 'ltr' } },\n\n\t/* Object Styles */\n\n\t{\n\t\tname: 'Styled image (left)',\n\t\telement: 'img',\n\t\tattributes: { 'class': 'left' }\n\t},\n\n\t{\n\t\tname: 'Styled image (right)',\n\t\telement: 'img',\n\t\tattributes: { 'class': 'right' }\n\t},\n\n\t{\n\t\tname: 'Compact table',\n\t\telement: 'table',\n\t\tattributes: {\n\t\t\tcellpadding: '5',\n\t\t\tcellspacing: '0',\n\t\t\tborder: '1',\n\t\t\tbordercolor: '#ccc'\n\t\t},\n\t\tstyles: {\n\t\t\t'border-collapse': 'collapse'\n\t\t}\n\t},\n\n\t{ name: 'Borderless Table',\t\telement: 'table',\tstyles: { 'border-style': 'hidden', 'background-color': '#E6E6FA' } },\n\t{ name: 'Square Bulleted List',\telement: 'ul',\t\tstyles: { 'list-style-type': 'square' } }\n]);\n\n"
  },
  {
    "path": "public/static/plugins/colorpicker/bootstrap-colorpicker.css",
    "content": "/*!\n * Bootstrap Colorpicker\n * http://mjolnic.github.io/bootstrap-colorpicker/\n *\n * Originally written by (c) 2012 Stefan Petre\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0.txt\n *\n */\n\n.colorpicker-saturation {\n  float: left;\n  width: 100px;\n  height: 100px;\n  cursor: crosshair;\n  background-image: url(\"img/saturation.png\");\n}\n\n.colorpicker-saturation i {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: block;\n  width: 5px;\n  height: 5px;\n  margin: -4px 0 0 -4px;\n  border: 1px solid #000;\n  -webkit-border-radius: 5px;\n     -moz-border-radius: 5px;\n          border-radius: 5px;\n}\n\n.colorpicker-saturation i b {\n  display: block;\n  width: 5px;\n  height: 5px;\n  border: 1px solid #fff;\n  -webkit-border-radius: 5px;\n     -moz-border-radius: 5px;\n          border-radius: 5px;\n}\n\n.colorpicker-hue,\n.colorpicker-alpha {\n  float: left;\n  width: 15px;\n  height: 100px;\n  margin-bottom: 4px;\n  margin-left: 4px;\n  cursor: row-resize;\n}\n\n.colorpicker-hue i,\n.colorpicker-alpha i {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: block;\n  width: 100%;\n  height: 1px;\n  margin-top: -1px;\n  background: #000;\n  border-top: 1px solid #fff;\n}\n\n.colorpicker-hue {\n  background-image: url(\"img/hue.png\");\n}\n\n.colorpicker-alpha {\n  display: none;\n  background-image: url(\"img/alpha.png\");\n}\n\n.colorpicker-saturation,\n.colorpicker-hue,\n.colorpicker-alpha {\n  background-size: contain;\n}\n\n.colorpicker {\n  top: 0;\n  left: 0;\n  z-index: 2500;\n  min-width: 130px;\n  padding: 4px;\n  margin-top: 1px;\n  -webkit-border-radius: 4px;\n     -moz-border-radius: 4px;\n          border-radius: 4px;\n  *zoom: 1;\n}\n\n.colorpicker:before,\n.colorpicker:after {\n  display: table;\n  line-height: 0;\n  content: \"\";\n}\n\n.colorpicker:after {\n  clear: both;\n}\n\n.colorpicker:before {\n  position: absolute;\n  top: -7px;\n  left: 6px;\n  display: inline-block;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid #ccc;\n  border-left: 7px solid transparent;\n  border-bottom-color: rgba(0, 0, 0, 0.2);\n  content: '';\n}\n\n.colorpicker:after {\n  position: absolute;\n  top: -6px;\n  left: 7px;\n  display: inline-block;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid #ffffff;\n  border-left: 6px solid transparent;\n  content: '';\n}\n\n.colorpicker div {\n  position: relative;\n}\n\n.colorpicker.colorpicker-with-alpha {\n  min-width: 140px;\n}\n\n.colorpicker.colorpicker-with-alpha .colorpicker-alpha {\n  display: block;\n}\n\n.colorpicker-color {\n  height: 10px;\n  margin-top: 5px;\n  clear: both;\n  background-image: url(\"img/alpha.png\");\n  background-position: 0 100%;\n}\n\n.colorpicker-color div {\n  height: 10px;\n}\n\n.colorpicker-selectors {\n  display: none;\n  height: 10px;\n  margin-top: 5px;\n  clear: both;\n}\n\n.colorpicker-selectors i {\n  float: left;\n  width: 10px;\n  height: 10px;\n  cursor: pointer;\n}\n\n.colorpicker-selectors i + i {\n  margin-left: 3px;\n}\n\n.colorpicker-element .input-group-addon i,\n.colorpicker-element .add-on i {\n  display: inline-block;\n  width: 16px;\n  height: 16px;\n  vertical-align: text-top;\n  cursor: pointer;\n}\n\n.colorpicker.colorpicker-inline {\n  position: relative;\n  z-index: auto;\n  display: inline-block;\n  float: none;\n}\n\n.colorpicker.colorpicker-horizontal {\n  width: 110px;\n  height: auto;\n  min-width: 110px;\n}\n\n.colorpicker.colorpicker-horizontal .colorpicker-saturation {\n  margin-bottom: 4px;\n}\n\n.colorpicker.colorpicker-horizontal .colorpicker-color {\n  width: 100px;\n}\n\n.colorpicker.colorpicker-horizontal .colorpicker-hue,\n.colorpicker.colorpicker-horizontal .colorpicker-alpha {\n  float: left;\n  width: 100px;\n  height: 15px;\n  margin-bottom: 4px;\n  margin-left: 0;\n  cursor: col-resize;\n}\n\n.colorpicker.colorpicker-horizontal .colorpicker-hue i,\n.colorpicker.colorpicker-horizontal .colorpicker-alpha i {\n  position: absolute;\n  top: 0;\n  left: 0;\n  display: block;\n  width: 1px;\n  height: 15px;\n  margin-top: 0;\n  background: #ffffff;\n  border: none;\n}\n\n.colorpicker.colorpicker-horizontal .colorpicker-hue {\n  background-image: url(\"img/hue-horizontal.png\");\n}\n\n.colorpicker.colorpicker-horizontal .colorpicker-alpha {\n  background-image: url(\"img/alpha-horizontal.png\");\n}\n\n.colorpicker.colorpicker-hidden {\n  display: none;\n}\n\n.colorpicker.colorpicker-visible {\n  display: block;\n}\n\n.colorpicker-inline.colorpicker-visible {\n  display: inline-block;\n}\n\n.colorpicker-right:before {\n  right: 6px;\n  left: auto;\n}\n\n.colorpicker-right:after {\n  right: 7px;\n  left: auto;\n}"
  },
  {
    "path": "public/static/plugins/colorpicker/bootstrap-colorpicker.js",
    "content": "/*!\n * Bootstrap Colorpicker\n * http://mjolnic.github.io/bootstrap-colorpicker/\n *\n * Originally written by (c) 2012 Stefan Petre\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0.txt\n *\n * @todo Update DOCS\n */\n\n(function(factory) {\n    \"use strict\";\n    if (typeof exports === 'object') {\n      module.exports = factory(window.jQuery);\n    } else if (typeof define === 'function' && define.amd) {\n      define(['jquery'], factory);\n    } else if (window.jQuery && !window.jQuery.fn.colorpicker) {\n      factory(window.jQuery);\n    }\n  }\n  (function($) {\n    'use strict';\n\n    // Color object\n    var Color = function(val, customColors) {\n      this.value = {\n        h: 0,\n        s: 0,\n        b: 0,\n        a: 1\n      };\n      this.origFormat = null; // original string format\n      if (customColors) {\n        $.extend(this.colors, customColors);\n      }\n      if (val) {\n        if (val.toLowerCase !== undefined) {\n          // cast to string\n          val = val + '';\n          this.setColor(val);\n        } else if (val.h !== undefined) {\n          this.value = val;\n        }\n      }\n    };\n\n    Color.prototype = {\n      constructor: Color,\n      // 140 predefined colors from the HTML Colors spec\n      colors: {\n        \"aliceblue\": \"#f0f8ff\",\n        \"antiquewhite\": \"#faebd7\",\n        \"aqua\": \"#00ffff\",\n        \"aquamarine\": \"#7fffd4\",\n        \"azure\": \"#f0ffff\",\n        \"beige\": \"#f5f5dc\",\n        \"bisque\": \"#ffe4c4\",\n        \"black\": \"#000000\",\n        \"blanchedalmond\": \"#ffebcd\",\n        \"blue\": \"#0000ff\",\n        \"blueviolet\": \"#8a2be2\",\n        \"brown\": \"#a52a2a\",\n        \"burlywood\": \"#deb887\",\n        \"cadetblue\": \"#5f9ea0\",\n        \"chartreuse\": \"#7fff00\",\n        \"chocolate\": \"#d2691e\",\n        \"coral\": \"#ff7f50\",\n        \"cornflowerblue\": \"#6495ed\",\n        \"cornsilk\": \"#fff8dc\",\n        \"crimson\": \"#dc143c\",\n        \"cyan\": \"#00ffff\",\n        \"darkblue\": \"#00008b\",\n        \"darkcyan\": \"#008b8b\",\n        \"darkgoldenrod\": \"#b8860b\",\n        \"darkgray\": \"#a9a9a9\",\n        \"darkgreen\": \"#006400\",\n        \"darkkhaki\": \"#bdb76b\",\n        \"darkmagenta\": \"#8b008b\",\n        \"darkolivegreen\": \"#556b2f\",\n        \"darkorange\": \"#ff8c00\",\n        \"darkorchid\": \"#9932cc\",\n        \"darkred\": \"#8b0000\",\n        \"darksalmon\": \"#e9967a\",\n        \"darkseagreen\": \"#8fbc8f\",\n        \"darkslateblue\": \"#483d8b\",\n        \"darkslategray\": \"#2f4f4f\",\n        \"darkturquoise\": \"#00ced1\",\n        \"darkviolet\": \"#9400d3\",\n        \"deeppink\": \"#ff1493\",\n        \"deepskyblue\": \"#00bfff\",\n        \"dimgray\": \"#696969\",\n        \"dodgerblue\": \"#1e90ff\",\n        \"firebrick\": \"#b22222\",\n        \"floralwhite\": \"#fffaf0\",\n        \"forestgreen\": \"#228b22\",\n        \"fuchsia\": \"#ff00ff\",\n        \"gainsboro\": \"#dcdcdc\",\n        \"ghostwhite\": \"#f8f8ff\",\n        \"gold\": \"#ffd700\",\n        \"goldenrod\": \"#daa520\",\n        \"gray\": \"#808080\",\n        \"green\": \"#008000\",\n        \"greenyellow\": \"#adff2f\",\n        \"honeydew\": \"#f0fff0\",\n        \"hotpink\": \"#ff69b4\",\n        \"indianred\": \"#cd5c5c\",\n        \"indigo\": \"#4b0082\",\n        \"ivory\": \"#fffff0\",\n        \"khaki\": \"#f0e68c\",\n        \"lavender\": \"#e6e6fa\",\n        \"lavenderblush\": \"#fff0f5\",\n        \"lawngreen\": \"#7cfc00\",\n        \"lemonchiffon\": \"#fffacd\",\n        \"lightblue\": \"#add8e6\",\n        \"lightcoral\": \"#f08080\",\n        \"lightcyan\": \"#e0ffff\",\n        \"lightgoldenrodyellow\": \"#fafad2\",\n        \"lightgrey\": \"#d3d3d3\",\n        \"lightgreen\": \"#90ee90\",\n        \"lightpink\": \"#ffb6c1\",\n        \"lightsalmon\": \"#ffa07a\",\n        \"lightseagreen\": \"#20b2aa\",\n        \"lightskyblue\": \"#87cefa\",\n        \"lightslategray\": \"#778899\",\n        \"lightsteelblue\": \"#b0c4de\",\n        \"lightyellow\": \"#ffffe0\",\n        \"lime\": \"#00ff00\",\n        \"limegreen\": \"#32cd32\",\n        \"linen\": \"#faf0e6\",\n        \"magenta\": \"#ff00ff\",\n        \"maroon\": \"#800000\",\n        \"mediumaquamarine\": \"#66cdaa\",\n        \"mediumblue\": \"#0000cd\",\n        \"mediumorchid\": \"#ba55d3\",\n        \"mediumpurple\": \"#9370d8\",\n        \"mediumseagreen\": \"#3cb371\",\n        \"mediumslateblue\": \"#7b68ee\",\n        \"mediumspringgreen\": \"#00fa9a\",\n        \"mediumturquoise\": \"#48d1cc\",\n        \"mediumvioletred\": \"#c71585\",\n        \"midnightblue\": \"#191970\",\n        \"mintcream\": \"#f5fffa\",\n        \"mistyrose\": \"#ffe4e1\",\n        \"moccasin\": \"#ffe4b5\",\n        \"navajowhite\": \"#ffdead\",\n        \"navy\": \"#000080\",\n        \"oldlace\": \"#fdf5e6\",\n        \"olive\": \"#808000\",\n        \"olivedrab\": \"#6b8e23\",\n        \"orange\": \"#ffa500\",\n        \"orangered\": \"#ff4500\",\n        \"orchid\": \"#da70d6\",\n        \"palegoldenrod\": \"#eee8aa\",\n        \"palegreen\": \"#98fb98\",\n        \"paleturquoise\": \"#afeeee\",\n        \"palevioletred\": \"#d87093\",\n        \"papayawhip\": \"#ffefd5\",\n        \"peachpuff\": \"#ffdab9\",\n        \"peru\": \"#cd853f\",\n        \"pink\": \"#ffc0cb\",\n        \"plum\": \"#dda0dd\",\n        \"powderblue\": \"#b0e0e6\",\n        \"purple\": \"#800080\",\n        \"red\": \"#ff0000\",\n        \"rosybrown\": \"#bc8f8f\",\n        \"royalblue\": \"#4169e1\",\n        \"saddlebrown\": \"#8b4513\",\n        \"salmon\": \"#fa8072\",\n        \"sandybrown\": \"#f4a460\",\n        \"seagreen\": \"#2e8b57\",\n        \"seashell\": \"#fff5ee\",\n        \"sienna\": \"#a0522d\",\n        \"silver\": \"#c0c0c0\",\n        \"skyblue\": \"#87ceeb\",\n        \"slateblue\": \"#6a5acd\",\n        \"slategray\": \"#708090\",\n        \"snow\": \"#fffafa\",\n        \"springgreen\": \"#00ff7f\",\n        \"steelblue\": \"#4682b4\",\n        \"tan\": \"#d2b48c\",\n        \"teal\": \"#008080\",\n        \"thistle\": \"#d8bfd8\",\n        \"tomato\": \"#ff6347\",\n        \"turquoise\": \"#40e0d0\",\n        \"violet\": \"#ee82ee\",\n        \"wheat\": \"#f5deb3\",\n        \"white\": \"#ffffff\",\n        \"whitesmoke\": \"#f5f5f5\",\n        \"yellow\": \"#ffff00\",\n        \"yellowgreen\": \"#9acd32\",\n        \"transparent\": \"transparent\"\n      },\n      _sanitizeNumber: function(val) {\n        if (typeof val === 'number') {\n          return val;\n        }\n        if (isNaN(val) || (val === null) || (val === '') || (val === undefined)) {\n          return 1;\n        }\n        if (val.toLowerCase !== undefined) {\n          return parseFloat(val);\n        }\n        return 1;\n      },\n      isTransparent: function(strVal) {\n        if (!strVal) {\n          return false;\n        }\n        strVal = strVal.toLowerCase().trim();\n        return (strVal === 'transparent') || (strVal.match(/#?00000000/)) || (strVal.match(/(rgba|hsla)\\(0,0,0,0?\\.?0\\)/));\n      },\n      rgbaIsTransparent: function(rgba) {\n        return ((rgba.r === 0) && (rgba.g === 0) && (rgba.b === 0) && (rgba.a === 0));\n      },\n      //parse a string to HSB\n      setColor: function(strVal) {\n        strVal = strVal.toLowerCase().trim();\n        if (strVal) {\n          if (this.isTransparent(strVal)) {\n            this.value = {\n              h: 0,\n              s: 0,\n              b: 0,\n              a: 0\n            };\n          } else {\n            this.value = this.stringToHSB(strVal) || {\n              h: 0,\n              s: 0,\n              b: 0,\n              a: 1\n            }; // if parser fails, defaults to black\n          }\n        }\n      },\n      stringToHSB: function(strVal) {\n        strVal = strVal.toLowerCase();\n        var alias;\n        if (typeof this.colors[strVal] !== 'undefined') {\n          strVal = this.colors[strVal];\n          alias = 'alias';\n        }\n        var that = this,\n          result = false;\n        $.each(this.stringParsers, function(i, parser) {\n          var match = parser.re.exec(strVal),\n            values = match && parser.parse.apply(that, [match]),\n            format = alias || parser.format || 'rgba';\n          if (values) {\n            if (format.match(/hsla?/)) {\n              result = that.RGBtoHSB.apply(that, that.HSLtoRGB.apply(that, values));\n            } else {\n              result = that.RGBtoHSB.apply(that, values);\n            }\n            that.origFormat = format;\n            return false;\n          }\n          return true;\n        });\n        return result;\n      },\n      setHue: function(h) {\n        this.value.h = 1 - h;\n      },\n      setSaturation: function(s) {\n        this.value.s = s;\n      },\n      setBrightness: function(b) {\n        this.value.b = 1 - b;\n      },\n      setAlpha: function(a) {\n        this.value.a = parseInt((1 - a) * 100, 10) / 100;\n      },\n      toRGB: function(h, s, b, a) {\n        if (!h) {\n          h = this.value.h;\n          s = this.value.s;\n          b = this.value.b;\n        }\n        h *= 360;\n        var R, G, B, X, C;\n        h = (h % 360) / 60;\n        C = b * s;\n        X = C * (1 - Math.abs(h % 2 - 1));\n        R = G = B = b - C;\n\n        h = ~~h;\n        R += [C, X, 0, 0, X, C][h];\n        G += [X, C, C, X, 0, 0][h];\n        B += [0, 0, X, C, C, X][h];\n        return {\n          r: Math.round(R * 255),\n          g: Math.round(G * 255),\n          b: Math.round(B * 255),\n          a: a || this.value.a\n        };\n      },\n      toHex: function(h, s, b, a) {\n        var rgb = this.toRGB(h, s, b, a);\n        if (this.rgbaIsTransparent(rgb)) {\n          return 'transparent';\n        }\n        return '#' + ((1 << 24) | (parseInt(rgb.r) << 16) | (parseInt(rgb.g) << 8) | parseInt(rgb.b)).toString(16).substr(1);\n      },\n      toHSL: function(h, s, b, a) {\n        h = h || this.value.h;\n        s = s || this.value.s;\n        b = b || this.value.b;\n        a = a || this.value.a;\n\n        var H = h,\n          L = (2 - s) * b,\n          S = s * b;\n        if (L > 0 && L <= 1) {\n          S /= L;\n        } else {\n          S /= 2 - L;\n        }\n        L /= 2;\n        if (S > 1) {\n          S = 1;\n        }\n        return {\n          h: isNaN(H) ? 0 : H,\n          s: isNaN(S) ? 0 : S,\n          l: isNaN(L) ? 0 : L,\n          a: isNaN(a) ? 0 : a\n        };\n      },\n      toAlias: function(r, g, b, a) {\n        var rgb = this.toHex(r, g, b, a);\n        for (var alias in this.colors) {\n          if (this.colors[alias] === rgb) {\n            return alias;\n          }\n        }\n        return false;\n      },\n      RGBtoHSB: function(r, g, b, a) {\n        r /= 255;\n        g /= 255;\n        b /= 255;\n\n        var H, S, V, C;\n        V = Math.max(r, g, b);\n        C = V - Math.min(r, g, b);\n        H = (C === 0 ? null :\n          V === r ? (g - b) / C :\n          V === g ? (b - r) / C + 2 :\n          (r - g) / C + 4\n        );\n        H = ((H + 360) % 6) * 60 / 360;\n        S = C === 0 ? 0 : C / V;\n        return {\n          h: this._sanitizeNumber(H),\n          s: S,\n          b: V,\n          a: this._sanitizeNumber(a)\n        };\n      },\n      HueToRGB: function(p, q, h) {\n        if (h < 0) {\n          h += 1;\n        } else if (h > 1) {\n          h -= 1;\n        }\n        if ((h * 6) < 1) {\n          return p + (q - p) * h * 6;\n        } else if ((h * 2) < 1) {\n          return q;\n        } else if ((h * 3) < 2) {\n          return p + (q - p) * ((2 / 3) - h) * 6;\n        } else {\n          return p;\n        }\n      },\n      HSLtoRGB: function(h, s, l, a) {\n        if (s < 0) {\n          s = 0;\n        }\n        var q;\n        if (l <= 0.5) {\n          q = l * (1 + s);\n        } else {\n          q = l + s - (l * s);\n        }\n\n        var p = 2 * l - q;\n\n        var tr = h + (1 / 3);\n        var tg = h;\n        var tb = h - (1 / 3);\n\n        var r = Math.round(this.HueToRGB(p, q, tr) * 255);\n        var g = Math.round(this.HueToRGB(p, q, tg) * 255);\n        var b = Math.round(this.HueToRGB(p, q, tb) * 255);\n        return [r, g, b, this._sanitizeNumber(a)];\n      },\n      toString: function(format) {\n        format = format || 'rgba';\n        var c = false;\n        switch (format) {\n          case 'rgb':\n            {\n              c = this.toRGB();\n              if (this.rgbaIsTransparent(c)) {\n                return 'transparent';\n              }\n              return 'rgb(' + c.r + ',' + c.g + ',' + c.b + ')';\n            }\n            break;\n          case 'rgba':\n            {\n              c = this.toRGB();\n              return 'rgba(' + c.r + ',' + c.g + ',' + c.b + ',' + c.a + ')';\n            }\n            break;\n          case 'hsl':\n            {\n              c = this.toHSL();\n              return 'hsl(' + Math.round(c.h * 360) + ',' + Math.round(c.s * 100) + '%,' + Math.round(c.l * 100) + '%)';\n            }\n            break;\n          case 'hsla':\n            {\n              c = this.toHSL();\n              return 'hsla(' + Math.round(c.h * 360) + ',' + Math.round(c.s * 100) + '%,' + Math.round(c.l * 100) + '%,' + c.a + ')';\n            }\n            break;\n          case 'hex':\n            {\n              return this.toHex();\n            }\n            break;\n          case 'alias':\n            return this.toAlias() || this.toHex();\n          default:\n            {\n              return c;\n            }\n            break;\n        }\n      },\n      // a set of RE's that can match strings and generate color tuples.\n      // from John Resig color plugin\n      // https://github.com/jquery/jquery-color/\n      stringParsers: [{\n        re: /rgb\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*?\\)/,\n        format: 'rgb',\n        parse: function(execResult) {\n          return [\n            execResult[1],\n            execResult[2],\n            execResult[3],\n            1\n          ];\n        }\n      }, {\n        re: /rgb\\(\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*?\\)/,\n        format: 'rgb',\n        parse: function(execResult) {\n          return [\n            2.55 * execResult[1],\n            2.55 * execResult[2],\n            2.55 * execResult[3],\n            1\n          ];\n        }\n      }, {\n        re: /rgba\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(?:,\\s*(\\d+(?:\\.\\d+)?)\\s*)?\\)/,\n        format: 'rgba',\n        parse: function(execResult) {\n          return [\n            execResult[1],\n            execResult[2],\n            execResult[3],\n            execResult[4]\n          ];\n        }\n      }, {\n        re: /rgba\\(\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*(?:,\\s*(\\d+(?:\\.\\d+)?)\\s*)?\\)/,\n        format: 'rgba',\n        parse: function(execResult) {\n          return [\n            2.55 * execResult[1],\n            2.55 * execResult[2],\n            2.55 * execResult[3],\n            execResult[4]\n          ];\n        }\n      }, {\n        re: /hsl\\(\\s*(\\d+(?:\\.\\d+)?)\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*?\\)/,\n        format: 'hsl',\n        parse: function(execResult) {\n          return [\n            execResult[1] / 360,\n            execResult[2] / 100,\n            execResult[3] / 100,\n            execResult[4]\n          ];\n        }\n      }, {\n        re: /hsla\\(\\s*(\\d+(?:\\.\\d+)?)\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*(?:,\\s*(\\d+(?:\\.\\d+)?)\\s*)?\\)/,\n        format: 'hsla',\n        parse: function(execResult) {\n          return [\n            execResult[1] / 360,\n            execResult[2] / 100,\n            execResult[3] / 100,\n            execResult[4]\n          ];\n        }\n      }, {\n        re: /#?([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/,\n        format: 'hex',\n        parse: function(execResult) {\n          return [\n            parseInt(execResult[1], 16),\n            parseInt(execResult[2], 16),\n            parseInt(execResult[3], 16),\n            1\n          ];\n        }\n      }, {\n        re: /#?([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/,\n        format: 'hex',\n        parse: function(execResult) {\n          return [\n            parseInt(execResult[1] + execResult[1], 16),\n            parseInt(execResult[2] + execResult[2], 16),\n            parseInt(execResult[3] + execResult[3], 16),\n            1\n          ];\n        }\n      }],\n      colorNameToHex: function(name) {\n        if (typeof this.colors[name.toLowerCase()] !== 'undefined') {\n          return this.colors[name.toLowerCase()];\n        }\n        return false;\n      }\n    };\n\n\n    var defaults = {\n      horizontal: false, // horizontal mode layout ?\n      inline: false, //forces to show the colorpicker as an inline element\n      color: false, //forces a color\n      format: false, //forces a format\n      input: 'input', // children input selector\n      container: false, // container selector\n      component: '.add-on, .input-group-addon', // children component selector\n      sliders: {\n        saturation: {\n          maxLeft: 100,\n          maxTop: 100,\n          callLeft: 'setSaturation',\n          callTop: 'setBrightness'\n        },\n        hue: {\n          maxLeft: 0,\n          maxTop: 100,\n          callLeft: false,\n          callTop: 'setHue'\n        },\n        alpha: {\n          maxLeft: 0,\n          maxTop: 100,\n          callLeft: false,\n          callTop: 'setAlpha'\n        }\n      },\n      slidersHorz: {\n        saturation: {\n          maxLeft: 100,\n          maxTop: 100,\n          callLeft: 'setSaturation',\n          callTop: 'setBrightness'\n        },\n        hue: {\n          maxLeft: 100,\n          maxTop: 0,\n          callLeft: 'setHue',\n          callTop: false\n        },\n        alpha: {\n          maxLeft: 100,\n          maxTop: 0,\n          callLeft: 'setAlpha',\n          callTop: false\n        }\n      },\n      template: '<div class=\"colorpicker dropdown-menu\">' +\n        '<div class=\"colorpicker-saturation\"><i><b></b></i></div>' +\n        '<div class=\"colorpicker-hue\"><i></i></div>' +\n        '<div class=\"colorpicker-alpha\"><i></i></div>' +\n        '<div class=\"colorpicker-color\"><div /></div>' +\n        '<div class=\"colorpicker-selectors\"></div>' +\n        '</div>',\n      align: 'right',\n      customClass: null,\n      colorSelectors: null\n    };\n\n    var Colorpicker = function(element, options) {\n      this.element = $(element).addClass('colorpicker-element');\n      this.options = $.extend(true, {}, defaults, this.element.data(), options);\n      this.component = this.options.component;\n      this.component = (this.component !== false) ? this.element.find(this.component) : false;\n      if (this.component && (this.component.length === 0)) {\n        this.component = false;\n      }\n      this.container = (this.options.container === true) ? this.element : this.options.container;\n      this.container = (this.container !== false) ? $(this.container) : false;\n\n      // Is the element an input? Should we search inside for any input?\n      this.input = this.element.is('input') ? this.element : (this.options.input ?\n        this.element.find(this.options.input) : false);\n      if (this.input && (this.input.length === 0)) {\n        this.input = false;\n      }\n      // Set HSB color\n      this.color = new Color(this.options.color !== false ? this.options.color : this.getValue(), this.options.colorSelectors);\n      this.format = this.options.format !== false ? this.options.format : this.color.origFormat;\n\n      // Setup picker\n      this.picker = $(this.options.template);\n      if (this.options.customClass) {\n        this.picker.addClass(this.options.customClass);\n      }\n      if (this.options.inline) {\n        this.picker.addClass('colorpicker-inline colorpicker-visible');\n      } else {\n        this.picker.addClass('colorpicker-hidden');\n      }\n      if (this.options.horizontal) {\n        this.picker.addClass('colorpicker-horizontal');\n      }\n      if (this.format === 'rgba' || this.format === 'hsla' || this.options.format === false) {\n        this.picker.addClass('colorpicker-with-alpha');\n      }\n      if (this.options.align === 'right') {\n        this.picker.addClass('colorpicker-right');\n      }\n      if (this.options.colorSelectors) {\n        var colorpicker = this;\n        $.each(this.options.colorSelectors, function(name, color) {\n          var $btn = $('<i />').css('background-color', color).data('class', name);\n          $btn.click(function() {\n            colorpicker.setValue($(this).css('background-color'));\n          });\n          colorpicker.picker.find('.colorpicker-selectors').append($btn);\n        });\n        this.picker.find('.colorpicker-selectors').show();\n      }\n      this.picker.on('mousedown.colorpicker touchstart.colorpicker', $.proxy(this.mousedown, this));\n      this.picker.appendTo(this.container ? this.container : $('body'));\n\n      // Bind events\n      if (this.input !== false) {\n        this.input.on({\n          'keyup.colorpicker': $.proxy(this.keyup, this)\n        });\n        this.input.on({\n          'change.colorpicker': $.proxy(this.change, this)\n        });\n        if (this.component === false) {\n          this.element.on({\n            'focus.colorpicker': $.proxy(this.show, this)\n          });\n        }\n        if (this.options.inline === false) {\n          this.element.on({\n            'focusout.colorpicker': $.proxy(this.hide, this)\n          });\n        }\n      }\n\n      if (this.component !== false) {\n        this.component.on({\n          'click.colorpicker': $.proxy(this.show, this)\n        });\n      }\n\n      if ((this.input === false) && (this.component === false)) {\n        this.element.on({\n          'click.colorpicker': $.proxy(this.show, this)\n        });\n      }\n\n      // for HTML5 input[type='color']\n      if ((this.input !== false) && (this.component !== false) && (this.input.attr('type') === 'color')) {\n\n        this.input.on({\n          'click.colorpicker': $.proxy(this.show, this),\n          'focus.colorpicker': $.proxy(this.show, this)\n        });\n      }\n      this.update();\n\n      $($.proxy(function() {\n        this.element.trigger('create');\n      }, this));\n    };\n\n    Colorpicker.Color = Color;\n\n    Colorpicker.prototype = {\n      constructor: Colorpicker,\n      destroy: function() {\n        this.picker.remove();\n        this.element.removeData('colorpicker').off('.colorpicker');\n        if (this.input !== false) {\n          this.input.off('.colorpicker');\n        }\n        if (this.component !== false) {\n          this.component.off('.colorpicker');\n        }\n        this.element.removeClass('colorpicker-element');\n        this.element.trigger({\n          type: 'destroy'\n        });\n      },\n      reposition: function() {\n        if (this.options.inline !== false || this.options.container) {\n          return false;\n        }\n        var type = this.container && this.container[0] !== document.body ? 'position' : 'offset';\n        var element = this.component || this.element;\n        var offset = element[type]();\n        if (this.options.align === 'right') {\n          offset.left -= this.picker.outerWidth() - element.outerWidth();\n        }\n        this.picker.css({\n          top: offset.top + element.outerHeight(),\n          left: offset.left\n        });\n      },\n      show: function(e) {\n        if (this.isDisabled()) {\n          return false;\n        }\n        this.picker.addClass('colorpicker-visible').removeClass('colorpicker-hidden');\n        this.reposition();\n        $(window).on('resize.colorpicker', $.proxy(this.reposition, this));\n        if (e && (!this.hasInput() || this.input.attr('type') === 'color')) {\n          if (e.stopPropagation && e.preventDefault) {\n            e.stopPropagation();\n            e.preventDefault();\n          }\n        }\n        if (this.options.inline === false) {\n          $(window.document).on({\n            'mousedown.colorpicker': $.proxy(this.hide, this)\n          });\n        }\n        this.element.trigger({\n          type: 'showPicker',\n          color: this.color\n        });\n      },\n      hide: function() {\n        this.picker.addClass('colorpicker-hidden').removeClass('colorpicker-visible');\n        $(window).off('resize.colorpicker', this.reposition);\n        $(document).off({\n          'mousedown.colorpicker': this.hide\n        });\n        this.update();\n        this.element.trigger({\n          type: 'hidePicker',\n          color: this.color\n        });\n      },\n      updateData: function(val) {\n        val = val || this.color.toString(this.format);\n        this.element.data('color', val);\n        return val;\n      },\n      updateInput: function(val) {\n        val = val || this.color.toString(this.format);\n        if (this.input !== false) {\n          if (this.options.colorSelectors) {\n            var color = new Color(val, this.options.colorSelectors);\n            var alias = color.toAlias();\n            if (typeof this.options.colorSelectors[alias] !== 'undefined') {\n              val = alias;\n            }\n          }\n          this.input.prop('value', val);\n        }\n        return val;\n      },\n      updatePicker: function(val) {\n        if (val !== undefined) {\n          this.color = new Color(val, this.options.colorSelectors);\n        }\n        var sl = (this.options.horizontal === false) ? this.options.sliders : this.options.slidersHorz;\n        var icns = this.picker.find('i');\n        if (icns.length === 0) {\n          return;\n        }\n        if (this.options.horizontal === false) {\n          sl = this.options.sliders;\n          icns.eq(1).css('top', sl.hue.maxTop * (1 - this.color.value.h)).end()\n            .eq(2).css('top', sl.alpha.maxTop * (1 - this.color.value.a));\n        } else {\n          sl = this.options.slidersHorz;\n          icns.eq(1).css('left', sl.hue.maxLeft * (1 - this.color.value.h)).end()\n            .eq(2).css('left', sl.alpha.maxLeft * (1 - this.color.value.a));\n        }\n        icns.eq(0).css({\n          'top': sl.saturation.maxTop - this.color.value.b * sl.saturation.maxTop,\n          'left': this.color.value.s * sl.saturation.maxLeft\n        });\n        this.picker.find('.colorpicker-saturation').css('backgroundColor', this.color.toHex(this.color.value.h, 1, 1, 1));\n        this.picker.find('.colorpicker-alpha').css('backgroundColor', this.color.toHex());\n        this.picker.find('.colorpicker-color, .colorpicker-color div').css('backgroundColor', this.color.toString(this.format));\n        return val;\n      },\n      updateComponent: function(val) {\n        val = val || this.color.toString(this.format);\n        if (this.component !== false) {\n          var icn = this.component.find('i').eq(0);\n          if (icn.length > 0) {\n            icn.css({\n              'backgroundColor': val\n            });\n          } else {\n            this.component.css({\n              'backgroundColor': val\n            });\n          }\n        }\n        return val;\n      },\n      update: function(force) {\n        var val;\n        if ((this.getValue(false) !== false) || (force === true)) {\n          // Update input/data only if the current value is not empty\n          val = this.updateComponent();\n          this.updateInput(val);\n          this.updateData(val);\n          this.updatePicker(); // only update picker if value is not empty\n        }\n        return val;\n\n      },\n      setValue: function(val) { // set color manually\n        this.color = new Color(val, this.options.colorSelectors);\n        this.update(true);\n        this.element.trigger({\n          type: 'changeColor',\n          color: this.color,\n          value: val\n        });\n      },\n      getValue: function(defaultValue) {\n        defaultValue = (defaultValue === undefined) ? '#000000' : defaultValue;\n        var val;\n        if (this.hasInput()) {\n          val = this.input.val();\n        } else {\n          val = this.element.data('color');\n        }\n        if ((val === undefined) || (val === '') || (val === null)) {\n          // if not defined or empty, return default\n          val = defaultValue;\n        }\n        return val;\n      },\n      hasInput: function() {\n        return (this.input !== false);\n      },\n      isDisabled: function() {\n        if (this.hasInput()) {\n          return (this.input.prop('disabled') === true);\n        }\n        return false;\n      },\n      disable: function() {\n        if (this.hasInput()) {\n          this.input.prop('disabled', true);\n          this.element.trigger({\n            type: 'disable',\n            color: this.color,\n            value: this.getValue()\n          });\n          return true;\n        }\n        return false;\n      },\n      enable: function() {\n        if (this.hasInput()) {\n          this.input.prop('disabled', false);\n          this.element.trigger({\n            type: 'enable',\n            color: this.color,\n            value: this.getValue()\n          });\n          return true;\n        }\n        return false;\n      },\n      currentSlider: null,\n      mousePointer: {\n        left: 0,\n        top: 0\n      },\n      mousedown: function(e) {\n        if (!e.pageX && !e.pageY && e.originalEvent) {\n          e.pageX = e.originalEvent.touches[0].pageX;\n          e.pageY = e.originalEvent.touches[0].pageY;\n        }\n        e.stopPropagation();\n        e.preventDefault();\n\n        var target = $(e.target);\n\n        //detect the slider and set the limits and callbacks\n        var zone = target.closest('div');\n        var sl = this.options.horizontal ? this.options.slidersHorz : this.options.sliders;\n        if (!zone.is('.colorpicker')) {\n          if (zone.is('.colorpicker-saturation')) {\n            this.currentSlider = $.extend({}, sl.saturation);\n          } else if (zone.is('.colorpicker-hue')) {\n            this.currentSlider = $.extend({}, sl.hue);\n          } else if (zone.is('.colorpicker-alpha')) {\n            this.currentSlider = $.extend({}, sl.alpha);\n          } else {\n            return false;\n          }\n          var offset = zone.offset();\n          //reference to guide's style\n          this.currentSlider.guide = zone.find('i')[0].style;\n          this.currentSlider.left = e.pageX - offset.left;\n          this.currentSlider.top = e.pageY - offset.top;\n          this.mousePointer = {\n            left: e.pageX,\n            top: e.pageY\n          };\n          //trigger mousemove to move the guide to the current position\n          $(document).on({\n            'mousemove.colorpicker': $.proxy(this.mousemove, this),\n            'touchmove.colorpicker': $.proxy(this.mousemove, this),\n            'mouseup.colorpicker': $.proxy(this.mouseup, this),\n            'touchend.colorpicker': $.proxy(this.mouseup, this)\n          }).trigger('mousemove');\n        }\n        return false;\n      },\n      mousemove: function(e) {\n        if (!e.pageX && !e.pageY && e.originalEvent) {\n          e.pageX = e.originalEvent.touches[0].pageX;\n          e.pageY = e.originalEvent.touches[0].pageY;\n        }\n        e.stopPropagation();\n        e.preventDefault();\n        var left = Math.max(\n          0,\n          Math.min(\n            this.currentSlider.maxLeft,\n            this.currentSlider.left + ((e.pageX || this.mousePointer.left) - this.mousePointer.left)\n          )\n        );\n        var top = Math.max(\n          0,\n          Math.min(\n            this.currentSlider.maxTop,\n            this.currentSlider.top + ((e.pageY || this.mousePointer.top) - this.mousePointer.top)\n          )\n        );\n        this.currentSlider.guide.left = left + 'px';\n        this.currentSlider.guide.top = top + 'px';\n        if (this.currentSlider.callLeft) {\n          this.color[this.currentSlider.callLeft].call(this.color, left / this.currentSlider.maxLeft);\n        }\n        if (this.currentSlider.callTop) {\n          this.color[this.currentSlider.callTop].call(this.color, top / this.currentSlider.maxTop);\n        }\n        // Change format dynamically\n        // Only occurs if user choose the dynamic format by\n        // setting option format to false\n        if (this.currentSlider.callTop === 'setAlpha' && this.options.format === false) {\n\n          // Converting from hex / rgb to rgba\n          if (this.color.value.a !== 1) {\n            this.format = 'rgba';\n            this.color.origFormat = 'rgba';\n          }\n\n          // Converting from rgba to hex\n          else {\n            this.format = 'hex';\n            this.color.origFormat = 'hex';\n          }\n        }\n        this.update(true);\n\n        this.element.trigger({\n          type: 'changeColor',\n          color: this.color\n        });\n        return false;\n      },\n      mouseup: function(e) {\n        e.stopPropagation();\n        e.preventDefault();\n        $(document).off({\n          'mousemove.colorpicker': this.mousemove,\n          'touchmove.colorpicker': this.mousemove,\n          'mouseup.colorpicker': this.mouseup,\n          'touchend.colorpicker': this.mouseup\n        });\n        return false;\n      },\n      change: function(e) {\n        this.keyup(e);\n      },\n      keyup: function(e) {\n        if ((e.keyCode === 38)) {\n          if (this.color.value.a < 1) {\n            this.color.value.a = Math.round((this.color.value.a + 0.01) * 100) / 100;\n          }\n          this.update(true);\n        } else if ((e.keyCode === 40)) {\n          if (this.color.value.a > 0) {\n            this.color.value.a = Math.round((this.color.value.a - 0.01) * 100) / 100;\n          }\n          this.update(true);\n        } else {\n          this.color = new Color(this.input.val(), this.options.colorSelectors);\n          // Change format dynamically\n          // Only occurs if user choose the dynamic format by\n          // setting option format to false\n          if (this.color.origFormat && this.options.format === false) {\n            this.format = this.color.origFormat;\n          }\n          if (this.getValue(false) !== false) {\n            this.updateData();\n            this.updateComponent();\n            this.updatePicker();\n          }\n        }\n        this.element.trigger({\n          type: 'changeColor',\n          color: this.color,\n          value: this.input.val()\n        });\n      }\n    };\n\n    $.colorpicker = Colorpicker;\n\n    $.fn.colorpicker = function(option) {\n      var pickerArgs = arguments,\n        rv;\n\n      var $returnValue = this.each(function() {\n        var $this = $(this),\n          inst = $this.data('colorpicker'),\n          options = ((typeof option === 'object') ? option : {});\n        if ((!inst) && (typeof option !== 'string')) {\n          $this.data('colorpicker', new Colorpicker(this, options));\n        } else {\n          if (typeof option === 'string') {\n            rv = inst[option].apply(inst, Array.prototype.slice.call(pickerArgs, 1));\n          }\n        }\n      });\n      if (option === 'getValue') {\n        return rv;\n      }\n      return $returnValue;\n    };\n\n    $.fn.colorpicker.constructor = Colorpicker;\n\n  }));\n"
  },
  {
    "path": "public/static/plugins/datatables/dataTables.bootstrap.css",
    "content": "div.dataTables_length label {\n\tfont-weight: normal;\n\ttext-align: left;\n\twhite-space: nowrap;\n}\n\ndiv.dataTables_length select {\n\twidth: 75px;\n\tdisplay: inline-block;\n}\n\ndiv.dataTables_filter {\n\ttext-align: right;\n}\n\ndiv.dataTables_filter label {\n\tfont-weight: normal;\n\twhite-space: nowrap;\n\ttext-align: left;\n}\n\ndiv.dataTables_filter input {\n\tmargin-left: 0.5em;\n\tdisplay: inline-block;\n\twidth: auto;\n}\n\ndiv.dataTables_info {\n\tpadding-top: 8px;\n\twhite-space: nowrap;\n}\n\ndiv.dataTables_paginate {\n\tmargin: 0;\n\twhite-space: nowrap;\n\ttext-align: right;\n}\n\ndiv.dataTables_paginate ul.pagination {\n\tmargin: 2px 0;\n\twhite-space: nowrap;\n}\n\n@media screen and (max-width: 767px) {\n\tdiv.dataTables_wrapper > div.row > div,\n\tdiv.dataTables_length,\n\tdiv.dataTables_filter,\n\tdiv.dataTables_info,\n\tdiv.dataTables_paginate {\n\t\ttext-align: center;\n\t}\n\n\tdiv.DTTT {\n\t\tmargin-bottom: 0.5em;\n\t}\n}\n\n\ntable.dataTable td,\ntable.dataTable th {\n\t-webkit-box-sizing: content-box;\n\t-moz-box-sizing: content-box;\n\tbox-sizing: content-box;\n}\n\n\ntable.dataTable {\n\tclear: both;\n\tmargin-top: 6px !important;\n\tmargin-bottom: 6px !important;\n\tmax-width: none !important;\n}\n\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc,\ntable.dataTable thead .sorting_asc_disabled,\ntable.dataTable thead .sorting_desc_disabled {\n\tcursor: pointer;\n\tposition: relative;\n}\n\ntable.dataTable thead .sorting:after,\ntable.dataTable thead .sorting_asc:after,\ntable.dataTable thead .sorting_desc:after {\n\tposition: absolute;\n\ttop: 8px;\n\tright: 8px;\n\tdisplay: block;\n\tfont-family: 'Glyphicons Halflings';\n\topacity: 0.5;\n}\ntable.dataTable thead .sorting:after {\n\topacity: 0.2;\n\tcontent: \"\\e150\"; /* sort */\n}\ntable.dataTable thead .sorting_asc:after {\n\tcontent: \"\\e155\"; /* sort-by-attributes */\n}\ntable.dataTable thead .sorting_desc:after {\n\tcontent: \"\\e156\"; /* sort-by-attributes-alt */\n}\ndiv.dataTables_scrollBody table.dataTable thead .sorting:after,\ndiv.dataTables_scrollBody table.dataTable thead .sorting_asc:after,\ndiv.dataTables_scrollBody table.dataTable thead .sorting_desc:after {\n\tdisplay: none;\n}\n\ntable.dataTable thead .sorting_asc_disabled:after,\ntable.dataTable thead .sorting_desc_disabled:after {\n\tcolor: #eee;\n}\n\ntable.dataTable thead > tr > th {\n\tpadding-right: 30px;\n}\n\ntable.dataTable th:active {\n\toutline: none;\n}\n\n\n/* Condensed */\ntable.dataTable.table-condensed thead > tr > th {\n\tpadding-right: 20px;\n}\n\ntable.dataTable.table-condensed thead .sorting:after,\ntable.dataTable.table-condensed thead .sorting_asc:after,\ntable.dataTable.table-condensed thead .sorting_desc:after {\n\ttop: 6px;\n\tright: 6px;\n}\n\n/* Scrolling */\ndiv.dataTables_scrollHead table {\n\tmargin-bottom: 0 !important;\n\tborder-bottom-left-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\ndiv.dataTables_scrollHead table thead tr:last-child th:first-child,\ndiv.dataTables_scrollHead table thead tr:last-child td:first-child {\n\tborder-bottom-left-radius: 0 !important;\n\tborder-bottom-right-radius: 0 !important;\n}\n\ndiv.dataTables_scrollBody table {\n\tborder-top: none;\n\tmargin-top: 0 !important;\n\tmargin-bottom: 0 !important;\n}\n\ndiv.dataTables_scrollBody tbody tr:first-child th,\ndiv.dataTables_scrollBody tbody tr:first-child td {\n\tborder-top: none;\n}\n\ndiv.dataTables_scrollFoot table {\n\tmargin-top: 0 !important;\n\tborder-top: none;\n}\n\n/* Frustratingly the border-collapse:collapse used by Bootstrap makes the column\n   width calculations when using scrolling impossible to align columns. We have\n   to use separate\n */\ntable.table-bordered.dataTable {\n\tborder-collapse: separate !important;\n}\ntable.table-bordered thead th,\ntable.table-bordered thead td {\n\tborder-left-width: 0;\n\tborder-top-width: 0;\n}\ntable.table-bordered tbody th,\ntable.table-bordered tbody td {\n\tborder-left-width: 0;\n\tborder-bottom-width: 0;\n}\ntable.table-bordered tfoot th,\ntable.table-bordered tfoot td {\n    border-left-width: 0;\n    border-bottom-width: 0;\n}\ntable.table-bordered th:last-child,\ntable.table-bordered td:last-child {\n\tborder-right-width: 0;\n}\ndiv.dataTables_scrollHead table.table-bordered {\n\tborder-bottom-width: 0;\n}\n\n\n\n\n/*\n * TableTools styles\n */\n.table.dataTable tbody tr.active td,\n.table.dataTable tbody tr.active th {\n\tbackground-color: #08C;\n\tcolor: white;\n}\n\n.table.dataTable tbody tr.active:hover td,\n.table.dataTable tbody tr.active:hover th {\n\tbackground-color: #0075b0 !important;\n}\n\n.table.dataTable tbody tr.active th > a,\n.table.dataTable tbody tr.active td > a {\n\tcolor: white;\n}\n\n.table-striped.dataTable tbody tr.active:nth-child(odd) td,\n.table-striped.dataTable tbody tr.active:nth-child(odd) th {\n\tbackground-color: #017ebc;\n}\n\ntable.DTTT_selectable tbody tr {\n\tcursor: pointer;\n}\n\ndiv.DTTT .btn:hover {\n\ttext-decoration: none !important;\n}\n\nul.DTTT_dropdown.dropdown-menu {\n  z-index: 2003;\n}\n\nul.DTTT_dropdown.dropdown-menu a {\n\tcolor: #333 !important; /* needed only when demo_page.css is included */\n}\n\nul.DTTT_dropdown.dropdown-menu li {\n\tposition: relative;\n}\n\nul.DTTT_dropdown.dropdown-menu li:hover a {\n\tbackground-color: #0088cc;\n\tcolor: white !important;\n}\n\ndiv.DTTT_collection_background {\n\tz-index: 2002;\t\n}\n\n/* TableTools information display */\ndiv.DTTT_print_info {\n\tposition: fixed;\n\ttop: 50%;\n\tleft: 50%;\n\twidth: 400px;\n\theight: 150px;\n\tmargin-left: -200px;\n\tmargin-top: -75px;\n\ttext-align: center;\n\tcolor: #333;\n\tpadding: 10px 30px;\n\topacity: 0.95;\n\n\tbackground-color: white;\n\tborder: 1px solid rgba(0, 0, 0, 0.2);\n\tborder-radius: 6px;\n\t\n\t-webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);\n\t        box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);\n}\n\ndiv.DTTT_print_info h6 {\n\tfont-weight: normal;\n\tfont-size: 28px;\n\tline-height: 28px;\n\tmargin: 1em;\n}\n\ndiv.DTTT_print_info p {\n\tfont-size: 14px;\n\tline-height: 20px;\n}\n\ndiv.dataTables_processing {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    width: 100%;\n    height: 60px;\n    margin-left: -50%;\n    margin-top: -25px;\n    padding-top: 20px;\n    padding-bottom: 20px;\n    text-align: center;\n    font-size: 1.2em;\n    background-color: white;\n    background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255,255,255,0)), color-stop(25%, rgba(255,255,255,0.9)), color-stop(75%, rgba(255,255,255,0.9)), color-stop(100%, rgba(255,255,255,0)));\n    background: -webkit-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);\n    background: -moz-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);\n    background: -ms-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);\n    background: -o-linear-gradient(left, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);\n    background: linear-gradient(to right, rgba(255,255,255,0) 0%, rgba(255,255,255,0.9) 25%, rgba(255,255,255,0.9) 75%, rgba(255,255,255,0) 100%);\n}\n\n\n\n/*\n * FixedColumns styles\n */\ndiv.DTFC_LeftHeadWrapper table,\ndiv.DTFC_LeftFootWrapper table,\ndiv.DTFC_RightHeadWrapper table,\ndiv.DTFC_RightFootWrapper table,\ntable.DTFC_Cloned tr.even {\n    background-color: white;\n    margin-bottom: 0;\n}\n \ndiv.DTFC_RightHeadWrapper table ,\ndiv.DTFC_LeftHeadWrapper table {\n\tborder-bottom: none !important;\n    margin-bottom: 0 !important;\n    border-top-right-radius: 0 !important;\n    border-bottom-left-radius: 0 !important;\n    border-bottom-right-radius: 0 !important;\n}\n \ndiv.DTFC_RightHeadWrapper table thead tr:last-child th:first-child,\ndiv.DTFC_RightHeadWrapper table thead tr:last-child td:first-child,\ndiv.DTFC_LeftHeadWrapper table thead tr:last-child th:first-child,\ndiv.DTFC_LeftHeadWrapper table thead tr:last-child td:first-child {\n    border-bottom-left-radius: 0 !important;\n    border-bottom-right-radius: 0 !important;\n}\n \ndiv.DTFC_RightBodyWrapper table,\ndiv.DTFC_LeftBodyWrapper table {\n    border-top: none;\n    margin: 0 !important;\n}\n \ndiv.DTFC_RightBodyWrapper tbody tr:first-child th,\ndiv.DTFC_RightBodyWrapper tbody tr:first-child td,\ndiv.DTFC_LeftBodyWrapper tbody tr:first-child th,\ndiv.DTFC_LeftBodyWrapper tbody tr:first-child td {\n    border-top: none;\n}\n \ndiv.DTFC_RightFootWrapper table,\ndiv.DTFC_LeftFootWrapper table {\n    border-top: none;\n    margin-top: 0 !important;\n}\n\n\ndiv.DTFC_LeftBodyWrapper table.dataTable thead .sorting:after,\ndiv.DTFC_LeftBodyWrapper table.dataTable thead .sorting_asc:after,\ndiv.DTFC_LeftBodyWrapper table.dataTable thead .sorting_desc:after,\ndiv.DTFC_RightBodyWrapper table.dataTable thead .sorting:after,\ndiv.DTFC_RightBodyWrapper table.dataTable thead .sorting_asc:after,\ndiv.DTFC_RightBodyWrapper table.dataTable thead .sorting_desc:after {\n\tdisplay: none;\n}\n\n\n/*\n * FixedHeader styles\n */\ndiv.FixedHeader_Cloned table {\n\tmargin: 0 !important\n}\n\n"
  },
  {
    "path": "public/static/plugins/datatables/dataTables.bootstrap.js",
    "content": "/*! DataTables Bootstrap 3 integration\n * ©2011-2014 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * DataTables integration for Bootstrap 3. This requires Bootstrap 3 and\n * DataTables 1.10 or newer.\n *\n * This file sets the defaults and adds options to DataTables to style its\n * controls using Bootstrap. See http://datatables.net/manual/styling/bootstrap\n * for further information.\n */\n(function(window, document, undefined){\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\n\n/* Set the defaults for DataTables initialisation */\n$.extend( true, DataTable.defaults, {\n\tdom:\n\t\t\"<'row'<'col-sm-6'l><'col-sm-6'f>>\" +\n\t\t\"<'row'<'col-sm-12'tr>>\" +\n\t\t\"<'row'<'col-sm-5'i><'col-sm-7'p>>\",\n\trenderer: 'bootstrap'\n} );\n\n\n/* Default class modification */\n$.extend( DataTable.ext.classes, {\n\tsWrapper:      \"dataTables_wrapper form-inline dt-bootstrap\",\n\tsFilterInput:  \"form-control input-sm\",\n\tsLengthSelect: \"form-control input-sm\"\n} );\n\n\n/* Bootstrap paging button renderer */\nDataTable.ext.renderer.pageButton.bootstrap = function ( settings, host, idx, buttons, page, pages ) {\n\tvar api     = new DataTable.Api( settings );\n\tvar classes = settings.oClasses;\n\tvar lang    = settings.oLanguage.oPaginate;\n\tvar btnDisplay, btnClass, counter=0;\n\n\tvar attach = function( container, buttons ) {\n\t\tvar i, ien, node, button;\n\t\tvar clickHandler = function ( e ) {\n\t\t\te.preventDefault();\n\t\t\tif ( !$(e.currentTarget).hasClass('disabled') ) {\n\t\t\t\tapi.page( e.data.action ).draw( false );\n\t\t\t}\n\t\t};\n\n\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\tbutton = buttons[i];\n\n\t\t\tif ( $.isArray( button ) ) {\n\t\t\t\tattach( container, button );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbtnDisplay = '';\n\t\t\t\tbtnClass = '';\n\n\t\t\t\tswitch ( button ) {\n\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\tbtnDisplay = '&hellip;';\n\t\t\t\t\t\tbtnClass = 'disabled';\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'first':\n\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'next':\n\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 'last':\n\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t'' : ' disabled');\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t'active' : '';\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tif ( btnDisplay ) {\n\t\t\t\t\tnode = $('<li>', {\n\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t} )\n\t\t\t\t\t\t.append( $('<a>', {\n\t\t\t\t\t\t\t\t'href': '#',\n\t\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t\t'data-dt-idx': counter,\n\t\t\t\t\t\t\t\t'tabindex': settings.iTabIndex\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.html( btnDisplay )\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.appendTo( container );\n\n\t\t\t\t\tsettings.oApi._fnBindAction(\n\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t);\n\n\t\t\t\t\tcounter++;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t// inside an iframe or frame. \n\tvar activeEl;\n\n\ttry {\n\t\t// Because this approach is destroying and recreating the paging\n\t\t// elements, focus is lost on the select button which is bad for\n\t\t// accessibility. So we want to restore focus once the draw has\n\t\t// completed\n\t\tactiveEl = $(document.activeElement).data('dt-idx');\n\t}\n\tcatch (e) {}\n\n\tattach(\n\t\t$(host).empty().html('<ul class=\"pagination\"/>').children('ul'),\n\t\tbuttons\n\t);\n\n\tif ( activeEl ) {\n\t\t$(host).find( '[data-dt-idx='+activeEl+']' ).focus();\n\t}\n};\n\n\n/*\n * TableTools Bootstrap compatibility\n * Required TableTools 2.1+\n */\nif ( DataTable.TableTools ) {\n\t// Set the classes that TableTools uses to something suitable for Bootstrap\n\t$.extend( true, DataTable.TableTools.classes, {\n\t\t\"container\": \"DTTT btn-group\",\n\t\t\"buttons\": {\n\t\t\t\"normal\": \"btn btn-default\",\n\t\t\t\"disabled\": \"disabled\"\n\t\t},\n\t\t\"collection\": {\n\t\t\t\"container\": \"DTTT_dropdown dropdown-menu\",\n\t\t\t\"buttons\": {\n\t\t\t\t\"normal\": \"\",\n\t\t\t\t\"disabled\": \"disabled\"\n\t\t\t}\n\t\t},\n\t\t\"print\": {\n\t\t\t\"info\": \"DTTT_print_info\"\n\t\t},\n\t\t\"select\": {\n\t\t\t\"row\": \"active\"\n\t\t}\n\t} );\n\n\t// Have the collection use a bootstrap compatible drop down\n\t$.extend( true, DataTable.TableTools.DEFAULTS.oTags, {\n\t\t\"collection\": {\n\t\t\t\"container\": \"ul\",\n\t\t\t\"button\": \"li\",\n\t\t\t\"liner\": \"a\"\n\t\t}\n\t} );\n}\n\n}; // /factory\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n})(window, document);\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/AutoFill/Readme.txt",
    "content": "# AutoFill\n\nAutoFill gives an Excel like option to a DataTable to click and drag over multiple cells, filling in information over the selected cells and incrementing numbers as needed. Key features include:\n\n* Click and drag cell content insertion\n* Automatic incrementing of numeric information\n* Enable and disable on any column\n* Detailed callback functions for customisation\n* Support for both DataTables and browser window scrolling\n\n\n# Installation\n\nTo use AutoFill, first download DataTables ( http://datatables.net/download ) and place the unzipped AutoFill package into a `extensions` directory in the DataTables package. This will allow the pages in the examples to operate correctly. To see the examples running, open the `examples` directory in your web-browser.\n\n\n# Basic usage\n\nAutoFill is initialised using the `$.fn.dataTable.AutoFill` constructor. For example:\n\n```js\n$(document).ready( function () {\n    var table = $('#example').dataTable();\n    new $.fn.dataTable.AutoFill( table );\n} );\n```\n\n\n# Documentation / support\n\n* Documentation: http://datatables.net/extensions/autofill/\n* DataTables support forums: http://datatables.net/forums\n\n\n# GitHub\n\nIf you fancy getting involved with the development of AutoFill and help make it better, please refer to its GitHub repo: https://github.com/DataTables/AutoFill\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/AutoFill/css/dataTables.autoFill.css",
    "content": "/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * AutoFill styles\n */\n\ndiv.AutoFill_filler {\n\tdisplay: none;\n\tposition: absolute;\n\theight: 14px;\n\twidth: 14px;\n\tbackground: url(../images/filler.png) no-repeat center center;\n\tz-index: 1002;\n}\n\ndiv.AutoFill_border {\n\tdisplay: none;\n\tposition: absolute;\n\tbackground-color: #0063dc;\n\tz-index: 1001;\n\t\n\tbox-shadow: 0px 0px 5px #76b4ff;\n\t-moz-box-shadow: 0px 0px 5px #76b4ff;\n\t-webkit-box-shadow: 0px 0px 5px #76b4ff;\n}\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/AutoFill/examples/columns.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>AutoFill example - Column options</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.autoFill.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.autoFill.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').dataTable();\n\n\tnew $.fn.dataTable.AutoFill( table, {\n\t\t\"columnDefs\": [\n\t\t\t{ enable:    false, targets: [-1, -2] },\n\t\t\t{ increment: false, targets: 3 }\n\t\t]\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>AutoFill example <span>Column options</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Columns can be enabled (which they are by default) and disabled from providing the end user with\n\t\t\t\tAutoFill abilities by using either <code>columns</code> or <code>columnDefs</code> and the\n\t\t\t\t<code>enable</code> option. These two arrays work in exactly the same way <a href=\n\t\t\t\t\"http://datatables.net/ref/columns\">as in DataTables</a>.</p>\n\n\t\t\t\t<p>This example shows how disabling columns counting from the right hand side of the table can be\n\t\t\t\tachieved. In this case, the last three columns.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar table = $('#example').dataTable();\n\n\tnew $.fn.dataTable.AutoFill( table, {\n\t\t&quot;columnDefs&quot;: [\n\t\t\t{ enable:    false, targets: [-1, -2] },\n\t\t\t{ increment: false, targets: 3 }\n\t\t]\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.autoFill.js\">../js/dataTables.autoFill.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.autoFill.css\">../css/dataTables.autoFill.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./columns.html\">Column options</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling DataTable</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-both.html\">Horizontal and vertical fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-horizontal.html\">Horizontal fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./complete-callback.html\">Complete callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./step-callback.html\">Step callback</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/AutoFill/examples/complete-callback.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>AutoFill example - Complete callback</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.autoFill.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.autoFill.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').dataTable();\n\n\tnew $.fn.dataTable.AutoFill( table, {\n\t\tcomplete: function ( altered ) {\n\t\t\tvar last = altered[ altered.length-1 ];\n\t\t\talert( \n\t\t\t\taltered.length+' cells were altered in this auto-fill. The '+\n\t\t\t\t'value of the last cell altered was: '+last.oldValue+' and is '+\n\t\t\t\t'now '+last.newValue\n\t\t\t);\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>AutoFill example <span>Complete callback</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>AutoFill provides a number of customisable callback functions so you can tailor it's actions to\n\t\t\t\texactly what you need. This example shows the use of the <code>complete</code> callback function which\n\t\t\t\tis executed at the end of an auto-fill drag, providing information about the cells that were\n\t\t\t\taltered.</p>\n\n\t\t\t\t<p>For a complete description of the <code>complete</code> callback, please refer to the <a href=\n\t\t\t\t\"//datatables.net/extras/autofill/options\">AutoFill documentation</a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar table = $('#example').dataTable();\n\n\tnew $.fn.dataTable.AutoFill( table, {\n\t\tcomplete: function ( altered ) {\n\t\t\tvar last = altered[ altered.length-1 ];\n\t\t\talert( \n\t\t\t\taltered.length+' cells were altered in this auto-fill. The '+\n\t\t\t\t'value of the last cell altered was: '+last.oldValue+' and is '+\n\t\t\t\t'now '+last.newValue\n\t\t\t);\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.autoFill.js\">../js/dataTables.autoFill.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.autoFill.css\">../css/dataTables.autoFill.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./columns.html\">Column options</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling DataTable</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-both.html\">Horizontal and vertical fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-horizontal.html\">Horizontal fill</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./complete-callback.html\">Complete callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./step-callback.html\">Step callback</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/AutoFill/examples/fill-both.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>AutoFill example - Horizontal and vertical fill</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.autoFill.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.autoFill.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.AutoFill( table, {\n\t\tmode: 'both'\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>AutoFill example <span>Horizontal and vertical fill</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>By default AutoFill will allow the fill to operate only on a single column at a time (i.e.\n\t\t\t\tvertically). However, it has the ability to provide the fill either horizontally, over both axis or\n\t\t\t\tlimited to just one axis depending on the direction of the drag. This option is provided by the\n\t\t\t\t<code>mode</code> sanitisation option.</p>\n\n\t\t\t\t<p>In this case it is set to <code>both</code> (i.e. both horizontal and vertical axis) to provide the\n\t\t\t\tfiller along a row, rather than a column.</p>\n\n\t\t\t\t<p>For the full range of options and syntax for <code>mode</code> please refer to the <a href=\n\t\t\t\t\"//datatables.net/extras/autofill/options\">AutoFill documentation</a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.AutoFill( table, {\n\t\tmode: 'both'\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.autoFill.js\">../js/dataTables.autoFill.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.autoFill.css\">../css/dataTables.autoFill.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./columns.html\">Column options</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling DataTable</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./fill-both.html\">Horizontal and vertical fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-horizontal.html\">Horizontal fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./complete-callback.html\">Complete callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./step-callback.html\">Step callback</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/AutoFill/examples/fill-horizontal.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>AutoFill example - Horizontal fill</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.autoFill.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.autoFill.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.AutoFill( table, {\n\t\tmode: 'x'\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>AutoFill example <span>Horizontal fill</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>By default AutoFill will allow the fill to operate only on a single column at a time (i.e.\n\t\t\t\tvertically). However, it has the ability to provide the fill either horizontally, over both axis or\n\t\t\t\tlimited to just one axis depending on the direction of the drag. This option is provided by the\n\t\t\t\t<code>mode</code> sanitisation option.</p>\n\n\t\t\t\t<p>In this case it is set to <code>x</code> (i.e. horizontal axis) to provide the filler along a row,\n\t\t\t\trather than a column.</p>\n\n\t\t\t\t<p>For the full range of options and syntax for <code>mode</code> please refer to the <a href=\n\t\t\t\t\"//datatables.net/extras/autofill/options\">AutoFill documentation</a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.AutoFill( table, {\n\t\tmode: 'x'\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.autoFill.js\">../js/dataTables.autoFill.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.autoFill.css\">../css/dataTables.autoFill.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./columns.html\">Column options</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling DataTable</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-both.html\">Horizontal and vertical fill</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./fill-horizontal.html\">Horizontal fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./complete-callback.html\">Complete callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./step-callback.html\">Step callback</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/AutoFill/examples/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\n\t<title>AutoFill examples - AutoFill examples</title>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>AutoFill example <span>AutoFill examples</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>AutoFill gives an Excel like option to a DataTable to click and drag over multiple cells, filling in\n\t\t\t\tinformation over the selected cells and incrementing numbers as needed.</p>\n\n\t\t\t\t<p>Thanks to <a href=\"http://www.phoniax.no/\">Phoniax AS</a> for their sponsorship of this plug-in for\n\t\t\t\tDataTables.</p>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./columns.html\">Column options</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling DataTable</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-both.html\">Horizontal and vertical fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-horizontal.html\">Horizontal fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./complete-callback.html\">Complete callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./step-callback.html\">Step callback</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/AutoFill/examples/scrolling.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>AutoFill example - Scrolling DataTable</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.autoFill.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.autoFill.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').dataTable( {\n\t\tscrollY: 200,\n\t\tscrollCollapse: false,\n\t\tpaginate: false\n\t} );\n\n\tnew $.fn.dataTable.AutoFill( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>AutoFill example <span>Scrolling DataTable</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>When dragging an AutoFill handle, the table (if DataTables scrolling is enabled) or the window will\n\t\t\t\tbe automatically scrolled, as you approach the edge of the scrolling component. The example below shows\n\t\t\t\tthe effect with DataTables scrolling (and also window if needed).</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar table = $('#example').dataTable( {\n\t\tscrollY: 200,\n\t\tscrollCollapse: false,\n\t\tpaginate: false\n\t} );\n\n\tnew $.fn.dataTable.AutoFill( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.autoFill.js\">../js/dataTables.autoFill.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.autoFill.css\">../css/dataTables.autoFill.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./columns.html\">Column options</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./scrolling.html\">Scrolling DataTable</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-both.html\">Horizontal and vertical fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-horizontal.html\">Horizontal fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./complete-callback.html\">Complete callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./step-callback.html\">Step callback</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/AutoFill/examples/simple.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>AutoFill example - Basic initialisation</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.autoFill.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.autoFill.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\tnew $.fn.dataTable.AutoFill( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>AutoFill example <span>Basic initialisation</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>AutoFill gives an Excel like option to a DataTable to click and drag over multiple cells, filling in\n\t\t\t\tinformation over the selected cells and incrementing numbers as needed.</p>\n\n\t\t\t\t<p>AutoFill is initialised using the <code>$.fn.dataTable.AutoFill</code> function as shown in the\n\t\t\t\texample below. It requires one parameter, the DataTable instance that AutoFill is to operate on, and\n\t\t\t\toptionally a second configuration parameter, which is shown in the other AutoFill examples.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\tnew $.fn.dataTable.AutoFill( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.autoFill.js\">../js/dataTables.autoFill.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.autoFill.css\">../css/dataTables.autoFill.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./columns.html\">Column options</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling DataTable</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-both.html\">Horizontal and vertical fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-horizontal.html\">Horizontal fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./complete-callback.html\">Complete callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./step-callback.html\">Step callback</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/AutoFill/examples/step-callback.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>AutoFill example - Step callback</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.autoFill.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.autoFill.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').dataTable();\n\n\tnew $.fn.dataTable.AutoFill( table, {\n\t\tcolumnDefs: [ {\n\t\t\ttargets: -1,\n\t\t\tstep: function ( cell, read, last, i, x, y ) {\n\t\t\t\tvar val = parseInt( (last || read).replace(/[$,]/g, ''), 10 );\n\t\t\t\tval += (x<0 || y<0 ? -100 : 100); // - if going back up, + if going down\n\n\t\t\t\t// Format for the currency column\n\t\t\t\treturn '$'+val.toString().replace( /\\B(?=(\\d{3})+(?!\\d))/g, ',' );\n\t\t\t}\n\t\t} ]\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>AutoFill example <span>Step callback</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>By default, AutoFill will increment cells that contain numbers by a single digit for each cell that\n\t\t\t\tis iterated over (try the <em>Age</em> column below for example). This behaviour can be disabled\n\t\t\t\tcompletely using the <code>increment</code> column option, but it can also be modified to suit your\n\t\t\t\trequirements through use of the <code>step</code> column callback function.</p>\n\n\t\t\t\t<p>The <code>step</code> callback is executed for each cell in the auto-fill set and gives complete\n\t\t\t\tcontrol over how data is incremented. The example below shows the step function being used on the\n\t\t\t\t<em>Salary</em> column to increment by 100, rather than 1 for each cell.</p>\n\n\t\t\t\t<p>For a complete description of the <code>step</code> callback, please refer to the <a href=\n\t\t\t\t\"//datatables.net/extras/autofill/options\">AutoFill documentation</a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar table = $('#example').dataTable();\n\n\tnew $.fn.dataTable.AutoFill( table, {\n\t\tcolumnDefs: [ {\n\t\t\ttargets: -1,\n\t\t\tstep: function ( cell, read, last, i, x, y ) {\n\t\t\t\tvar val = parseInt( (last || read).replace(/[$,]/g, ''), 10 );\n\t\t\t\tval += (x&lt;0 || y&lt;0 ? -100 : 100); // - if going back up, + if going down\n\n\t\t\t\t// Format for the currency column\n\t\t\t\treturn '$'+val.toString().replace( /\\B(?=(\\d{3})+(?!\\d))/g, ',' );\n\t\t\t}\n\t\t} ]\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.autoFill.js\">../js/dataTables.autoFill.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.autoFill.css\">../css/dataTables.autoFill.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./columns.html\">Column options</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling DataTable</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-both.html\">Horizontal and vertical fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fill-horizontal.html\">Horizontal fill</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./complete-callback.html\">Complete callback</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./step-callback.html\">Step callback</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/AutoFill/js/dataTables.autoFill.js",
    "content": "/*! AutoFill 1.2.1\n * ©2008-2014 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary     AutoFill\n * @description Add Excel like click and drag auto-fill options to DataTables\n * @version     1.2.1\n * @file        dataTables.autoFill.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2010-2014 SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n *   MIT license - http://datatables.net/license/mit\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n(function( window, document, undefined ) {\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\n/** \n * AutoFill provides Excel like auto-fill features for a DataTable\n *\n * @class AutoFill\n * @constructor\n * @param {object} oTD DataTables settings object\n * @param {object} oConfig Configuration object for AutoFill\n */\nvar AutoFill = function( oDT, oConfig )\n{\n\t/* Sanity check that we are a new instance */\n\tif ( ! (this instanceof AutoFill) ) {\n\t\tthrow( \"Warning: AutoFill must be initialised with the keyword 'new'\" );\n\t}\n\n\tif ( ! $.fn.dataTableExt.fnVersionCheck('1.7.0') ) {\n\t\tthrow( \"Warning: AutoFill requires DataTables 1.7 or greater\");\n\t}\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Public class variables\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\tthis.c = {};\n\n\t/**\n\t * @namespace Settings object which contains customisable information for AutoFill instance\n\t */\n\tthis.s = {\n\t\t/**\n\t\t * @namespace Cached information about the little dragging icon (the filler)\n\t\t */\n\t\t\"filler\": {\n\t\t\t\"height\": 0,\n\t\t\t\"width\": 0\n\t\t},\n\n\t\t/**\n\t\t * @namespace Cached information about the border display\n\t\t */\n\t\t\"border\": {\n\t\t\t\"width\": 2\n\t\t},\n\n\t\t/**\n\t\t * @namespace Store for live information for the current drag\n\t\t */\n\t\t\"drag\": {\n\t\t\t\"startX\": -1,\n\t\t\t\"startY\": -1,\n\t\t\t\"startTd\": null,\n\t\t\t\"endTd\": null,\n\t\t\t\"dragging\": false\n\t\t},\n\n\t\t/**\n\t\t * @namespace Data cache for information that we need for scrolling the screen when we near\n\t\t *   the edges\n\t\t */\n\t\t\"screen\": {\n\t\t\t\"interval\": null,\n\t\t\t\"y\": 0,\n\t\t\t\"height\": 0,\n\t\t\t\"scrollTop\": 0\n\t\t},\n\n\t\t/**\n\t\t * @namespace Data cache for the position of the DataTables scrolling element (when scrolling\n\t\t *   is enabled)\n\t\t */\n\t\t\"scroller\": {\n\t\t\t\"top\": 0,\n\t\t\t\"bottom\": 0\n\t\t},\n\n\t\t/**\n\t\t * @namespace Information stored for each column. An array of objects\n\t\t */\n\t\t\"columns\": []\n\t};\n\n\n\t/**\n\t * @namespace Common and useful DOM elements for the class instance\n\t */\n\tthis.dom = {\n\t\t\"table\": null,\n\t\t\"filler\": null,\n\t\t\"borderTop\": null,\n\t\t\"borderRight\": null,\n\t\t\"borderBottom\": null,\n\t\t\"borderLeft\": null,\n\t\t\"currentTarget\": null\n\t};\n\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Public class methods\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * Retreieve the settings object from an instance\n\t *  @method fnSettings\n\t *  @returns {object} AutoFill settings object\n\t */\n\tthis.fnSettings = function () {\n\t\treturn this.s;\n\t};\n\n\n\t/* Constructor logic */\n\tthis._fnInit( oDT, oConfig );\n\treturn this;\n};\n\n\n\nAutoFill.prototype = {\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Private methods (they are of course public in JS, but recommended as private)\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * Initialisation\n\t *  @method _fnInit\n\t *  @param {object} dt DataTables settings object\n\t *  @param {object} config Configuration object for AutoFill\n\t *  @returns void\n\t */\n\t\"_fnInit\": function ( dt, config )\n\t{\n\t\tvar\n\t\t\tthat = this,\n\t\t\ti, iLen;\n\n\t\t// Use DataTables API to get the settings allowing selectors, instances\n\t\t// etc to be used, or for backwards compatibility get from the old\n\t\t// fnSettings method\n\t\tthis.s.dt = DataTable.Api ?\n\t\t\tnew DataTable.Api( dt ).settings()[0] :\n\t\t\tdt.fnSettings();\n\t\tthis.s.init = config || {};\n\t\tthis.dom.table = this.s.dt.nTable;\n\n\t\t$.extend( true, this.c, AutoFill.defaults, config );\n\n\t\t/* Add and configure the columns */\n\t\tthis._initColumns();\n\n\t\t/* Auto Fill click and drag icon */\n\t\tvar filler = $('<div/>', {\n\t\t\t\t'class': 'AutoFill_filler'\n\t\t\t} )\n\t\t\t.appendTo( 'body' );\n\t\tthis.dom.filler = filler[0];\n\n\t\t// Get the height / width of the click element\n\t\tthis.s.filler.height = filler.height();\n\t\tthis.s.filler.width = filler.width();\n\t\tfiller[0].style.display = \"none\";\n\n\t\t/* Border display - one div for each side. We can't just use a single\n\t\t * one with a border, as we want the events to effectively pass through\n\t\t * the transparent bit of the box\n\t\t */\n\t\tvar border;\n\t\tvar appender = document.body;\n\t\tif ( that.s.dt.oScroll.sY !== \"\" ) {\n\t\t\tthat.s.dt.nTable.parentNode.style.position = \"relative\";\n\t\t\tappender = that.s.dt.nTable.parentNode;\n\t\t}\n\n\t\tborder = $('<div/>', {\n\t\t\t\"class\": \"AutoFill_border\"\n\t\t} );\n\t\tthis.dom.borderTop    = border.clone().appendTo( appender )[0];\n\t\tthis.dom.borderRight  = border.clone().appendTo( appender )[0];\n\t\tthis.dom.borderBottom = border.clone().appendTo( appender )[0];\n\t\tthis.dom.borderLeft   = border.clone().appendTo( appender )[0];\n\n\t\t/* Events */\n\t\tfiller.on( 'mousedown.DTAF', function (e) {\n\t\t\tthis.onselectstart = function() { return false; };\n\t\t\tthat._fnFillerDragStart.call( that, e );\n\t\t\treturn false;\n\t\t} );\n\n\t\t$('tbody', this.dom.table).on(\n\t\t\t'mouseover.DTAF mouseout.DTAF',\n\t\t\t'>tr>td, >tr>th',\n\t\t\tfunction (e) {\n\t\t\t\tthat._fnFillerDisplay.call( that, e );\n\t\t\t}\n\t\t);\n\n\t\t$(this.dom.table).on( 'destroy.dt.DTAF', function () {\n\t\t\tfiller.off( 'mousedown.DTAF' ).remove();\n\t\t\t$('tbody', this.dom.table).off( 'mouseover.DTAF mouseout.DTAF' );\n\t\t} );\n\t},\n\n\n\t_initColumns: function ( )\n\t{\n\t\tvar that = this;\n\t\tvar i, ien;\n\t\tvar dt = this.s.dt;\n\t\tvar config = this.s.init;\n\n\t\tfor ( i=0, ien=dt.aoColumns.length ; i<ien ; i++ ) {\n\t\t\tthis.s.columns[i] = $.extend( true, {}, AutoFill.defaults.column );\n\t\t}\n\n\t\tdt.oApi._fnApplyColumnDefs(\n\t\t\tdt,\n\t\t\tconfig.aoColumnDefs || config.columnDefs,\n\t\t\tconfig.aoColumns || config.columns,\n\t\t\tfunction (colIdx, def) {\n\t\t\t\tthat._fnColumnOptions( colIdx, def );\n\t\t\t}\n\t\t);\n\n\t\t// For columns which don't have read, write, step functions defined,\n\t\t// use the default ones\n\t\tfor ( i=0, ien=dt.aoColumns.length ; i<ien ; i++ ) {\n\t\t\tvar column = this.s.columns[i];\n\n\t\t\tif ( ! column.read ) {\n\t\t\t\tcolumn.read = this._fnReadCell;\n\t\t\t}\n\t\t\tif ( ! column.write ) {\n\t\t\t\tcolumn.read = this._fnWriteCell;\n\t\t\t}\n\t\t\tif ( ! column.step ) {\n\t\t\t\tcolumn.read = this._fnStep;\n\t\t\t}\n\t\t}\n\t},\n\n\n\t\"_fnColumnOptions\": function ( i, opts )\n\t{\n\t\tvar column = this.s.columns[ i ];\n\t\tvar set = function ( outProp, inProp ) {\n\t\t\tif ( opts[ inProp[0] ] !== undefined ) {\n\t\t\t\tcolumn[ outProp ] = opts[ inProp[0] ];\n\t\t\t}\n\t\t\tif ( opts[ inProp[1] ] !== undefined ) {\n\t\t\t\tcolumn[ outProp ] = opts[ inProp[1] ];\n\t\t\t}\n\t\t};\n\n\t\t// Compatibility with the old Hungarian style of notation\n\t\tset( 'enable',    ['bEnable',     'enable'] );\n\t\tset( 'read',      ['fnRead',      'read'] );\n\t\tset( 'write',     ['fnWrite',     'write'] );\n\t\tset( 'step',      ['fnStep',      'step'] );\n\t\tset( 'increment', ['bIncrement',  'increment'] );\n\t},\n\n\n\t/**\n\t * Find out the coordinates of a given TD cell in a table\n\t *  @method  _fnTargetCoords\n\t *  @param   {Node} nTd\n\t *  @returns {Object} x and y properties, for the position of the cell in the tables DOM\n\t */\n\t\"_fnTargetCoords\": function ( nTd )\n\t{\n\t\tvar nTr = $(nTd).parents('tr')[0];\n\t\tvar position = this.s.dt.oInstance.fnGetPosition( nTd );\n\n\t\treturn {\n\t\t\t\"x\":      $('td', nTr).index(nTd),\n\t\t\t\"y\":      $('tr', nTr.parentNode).index(nTr),\n\t\t\t\"row\":    position[0],\n\t\t\t\"column\": position[2]\n\t\t};\n\t},\n\n\n\t/**\n\t * Display the border around one or more cells (from start to end)\n\t *  @method  _fnUpdateBorder\n\t *  @param   {Node} nStart Starting cell\n\t *  @param   {Node} nEnd Ending cell\n\t *  @returns void\n\t */\n\t\"_fnUpdateBorder\": function ( nStart, nEnd )\n\t{\n\t\tvar\n\t\t\tborder = this.s.border.width,\n\t\t\toffsetStart = $(nStart).offset(),\n\t\t\toffsetEnd = $(nEnd).offset(),\n\t\t\tx1 = offsetStart.left - border,\n\t\t\tx2 = offsetEnd.left + $(nEnd).outerWidth(),\n\t\t\ty1 = offsetStart.top - border,\n\t\t\ty2 = offsetEnd.top + $(nEnd).outerHeight(),\n\t\t\twidth = offsetEnd.left + $(nEnd).outerWidth() - offsetStart.left + (2*border),\n\t\t\theight = offsetEnd.top + $(nEnd).outerHeight() - offsetStart.top + (2*border),\n\t\t\toStyle;\n\n\t\t// Recalculate start and end (when dragging \"backwards\")  \n\t\tif( offsetStart.left > offsetEnd.left) {\n\t\t\tx1 = offsetEnd.left - border;\n\t\t\tx2 = offsetStart.left + $(nStart).outerWidth();\n\t\t\twidth = offsetStart.left + $(nStart).outerWidth() - offsetEnd.left + (2*border);\n\t\t}\n\n\t\tif ( this.s.dt.oScroll.sY !== \"\" )\n\t\t{\n\t\t\t/* The border elements are inside the DT scroller - so position relative to that */\n\t\t\tvar\n\t\t\t\toffsetScroll = $(this.s.dt.nTable.parentNode).offset(),\n\t\t\t\tscrollTop = $(this.s.dt.nTable.parentNode).scrollTop(),\n\t\t\t\tscrollLeft = $(this.s.dt.nTable.parentNode).scrollLeft();\n\n\t\t\tx1 -= offsetScroll.left - scrollLeft;\n\t\t\tx2 -= offsetScroll.left - scrollLeft;\n\t\t\ty1 -= offsetScroll.top - scrollTop;\n\t\t\ty2 -= offsetScroll.top - scrollTop;\n\t\t}\n\n\t\t/* Top */\n\t\toStyle = this.dom.borderTop.style;\n\t\toStyle.top = y1+\"px\";\n\t\toStyle.left = x1+\"px\";\n\t\toStyle.height = this.s.border.width+\"px\";\n\t\toStyle.width = width+\"px\";\n\n\t\t/* Bottom */\n\t\toStyle = this.dom.borderBottom.style;\n\t\toStyle.top = y2+\"px\";\n\t\toStyle.left = x1+\"px\";\n\t\toStyle.height = this.s.border.width+\"px\";\n\t\toStyle.width = width+\"px\";\n\n\t\t/* Left */\n\t\toStyle = this.dom.borderLeft.style;\n\t\toStyle.top = y1+\"px\";\n\t\toStyle.left = x1+\"px\";\n\t\toStyle.height = height+\"px\";\n\t\toStyle.width = this.s.border.width+\"px\";\n\n\t\t/* Right */\n\t\toStyle = this.dom.borderRight.style;\n\t\toStyle.top = y1+\"px\";\n\t\toStyle.left = x2+\"px\";\n\t\toStyle.height = height+\"px\";\n\t\toStyle.width = this.s.border.width+\"px\";\n\t},\n\n\n\t/**\n\t * Mouse down event handler for starting a drag\n\t *  @method  _fnFillerDragStart\n\t *  @param   {Object} e Event object\n\t *  @returns void\n\t */\n\t\"_fnFillerDragStart\": function (e)\n\t{\n\t\tvar that = this;\n\t\tvar startingTd = this.dom.currentTarget;\n\n\t\tthis.s.drag.dragging = true;\n\n\t\tthat.dom.borderTop.style.display = \"block\";\n\t\tthat.dom.borderRight.style.display = \"block\";\n\t\tthat.dom.borderBottom.style.display = \"block\";\n\t\tthat.dom.borderLeft.style.display = \"block\";\n\n\t\tvar coords = this._fnTargetCoords( startingTd );\n\t\tthis.s.drag.startX = coords.x;\n\t\tthis.s.drag.startY = coords.y;\n\n\t\tthis.s.drag.startTd = startingTd;\n\t\tthis.s.drag.endTd = startingTd;\n\n\t\tthis._fnUpdateBorder( startingTd, startingTd );\n\n\t\t$(document).bind('mousemove.AutoFill', function (e) {\n\t\t\tthat._fnFillerDragMove.call( that, e );\n\t\t} );\n\n\t\t$(document).bind('mouseup.AutoFill', function (e) {\n\t\t\tthat._fnFillerFinish.call( that, e );\n\t\t} );\n\n\t\t/* Scrolling information cache */\n\t\tthis.s.screen.y = e.pageY;\n\t\tthis.s.screen.height = $(window).height();\n\t\tthis.s.screen.scrollTop = $(document).scrollTop();\n\n\t\tif ( this.s.dt.oScroll.sY !== \"\" )\n\t\t{\n\t\t\tthis.s.scroller.top = $(this.s.dt.nTable.parentNode).offset().top;\n\t\t\tthis.s.scroller.bottom = this.s.scroller.top + $(this.s.dt.nTable.parentNode).height();\n\t\t}\n\n\t\t/* Scrolling handler - we set an interval (which is cancelled on mouse up) which will fire\n\t\t * regularly and see if we need to do any scrolling\n\t\t */\n\t\tthis.s.screen.interval = setInterval( function () {\n\t\t\tvar iScrollTop = $(document).scrollTop();\n\t\t\tvar iScrollDelta = iScrollTop - that.s.screen.scrollTop;\n\t\t\tthat.s.screen.y += iScrollDelta;\n\n\t\t\tif ( that.s.screen.height - that.s.screen.y + iScrollTop < 50 )\n\t\t\t{\n\t\t\t\t$('html, body').animate( {\n\t\t\t\t\t\"scrollTop\": iScrollTop + 50\n\t\t\t\t}, 240, 'linear' );\n\t\t\t}\n\t\t\telse if ( that.s.screen.y - iScrollTop < 50 )\n\t\t\t{\n\t\t\t\t$('html, body').animate( {\n\t\t\t\t\t\"scrollTop\": iScrollTop - 50\n\t\t\t\t}, 240, 'linear' );\n\t\t\t}\n\n\t\t\tif ( that.s.dt.oScroll.sY !== \"\" )\n\t\t\t{\n\t\t\t\tif ( that.s.screen.y > that.s.scroller.bottom - 50 )\n\t\t\t\t{\n\t\t\t\t\t$(that.s.dt.nTable.parentNode).animate( {\n\t\t\t\t\t\t\"scrollTop\": $(that.s.dt.nTable.parentNode).scrollTop() + 50\n\t\t\t\t\t}, 240, 'linear' );\n\t\t\t\t}\n\t\t\t\telse if ( that.s.screen.y < that.s.scroller.top + 50 )\n\t\t\t\t{\n\t\t\t\t\t$(that.s.dt.nTable.parentNode).animate( {\n\t\t\t\t\t\t\"scrollTop\": $(that.s.dt.nTable.parentNode).scrollTop() - 50\n\t\t\t\t\t}, 240, 'linear' );\n\t\t\t\t}\n\t\t\t}\n\t\t}, 250 );\n\t},\n\n\n\t/**\n\t * Mouse move event handler for during a move. See if we want to update the display based on the\n\t * new cursor position\n\t *  @method  _fnFillerDragMove\n\t *  @param   {Object} e Event object\n\t *  @returns void\n\t */\n\t\"_fnFillerDragMove\": function (e)\n\t{\n\t\tif ( e.target && e.target.nodeName.toUpperCase() == \"TD\" &&\n\t\t\t e.target != this.s.drag.endTd )\n\t\t{\n\t\t\tvar coords = this._fnTargetCoords( e.target );\n\n\t\t\tif ( this.c.mode == \"y\" && coords.x != this.s.drag.startX )\n\t\t\t{\n\t\t\t\te.target = $('tbody>tr:eq('+coords.y+')>td:eq('+this.s.drag.startX+')', this.dom.table)[0];\n\t\t\t}\n\t\t\tif ( this.c.mode == \"x\" && coords.y != this.s.drag.startY )\n\t\t\t{\n\t\t\t\te.target = $('tbody>tr:eq('+this.s.drag.startY+')>td:eq('+coords.x+')', this.dom.table)[0];\n\t\t\t}\n\n\t\t\tif ( this.c.mode == \"either\")\n\t\t\t{\n\t\t\t\tif(coords.x != this.s.drag.startX )\n\t\t\t\t{\n\t\t\t\t\te.target = $('tbody>tr:eq('+this.s.drag.startY+')>td:eq('+coords.x+')', this.dom.table)[0];\n\t\t\t\t}\n\t\t\t\telse if ( coords.y != this.s.drag.startY ) {\n\t\t\t\t\te.target = $('tbody>tr:eq('+coords.y+')>td:eq('+this.s.drag.startX+')', this.dom.table)[0];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// update coords\n\t\t\tif ( this.c.mode !== \"both\" ) {\n\t\t\t\tcoords = this._fnTargetCoords( e.target );\n\t\t\t}\n\n\t\t\tvar drag = this.s.drag;\n\t\t\tdrag.endTd = e.target;\n\n\t\t\tif ( coords.y >= this.s.drag.startY ) {\n\t\t\t\tthis._fnUpdateBorder( drag.startTd, drag.endTd );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis._fnUpdateBorder( drag.endTd, drag.startTd );\n\t\t\t}\n\t\t\tthis._fnFillerPosition( e.target );\n\t\t}\n\n\t\t/* Update the screen information so we can perform scrolling */\n\t\tthis.s.screen.y = e.pageY;\n\t\tthis.s.screen.scrollTop = $(document).scrollTop();\n\n\t\tif ( this.s.dt.oScroll.sY !== \"\" )\n\t\t{\n\t\t\tthis.s.scroller.scrollTop = $(this.s.dt.nTable.parentNode).scrollTop();\n\t\t\tthis.s.scroller.top = $(this.s.dt.nTable.parentNode).offset().top;\n\t\t\tthis.s.scroller.bottom = this.s.scroller.top + $(this.s.dt.nTable.parentNode).height();\n\t\t}\n\t},\n\n\n\t/**\n\t * Mouse release handler - end the drag and take action to update the cells with the needed values\n\t *  @method  _fnFillerFinish\n\t *  @param   {Object} e Event object\n\t *  @returns void\n\t */\n\t\"_fnFillerFinish\": function (e)\n\t{\n\t\tvar that = this, i, iLen, j;\n\n\t\t$(document).unbind('mousemove.AutoFill mouseup.AutoFill');\n\n\t\tthis.dom.borderTop.style.display = \"none\";\n\t\tthis.dom.borderRight.style.display = \"none\";\n\t\tthis.dom.borderBottom.style.display = \"none\";\n\t\tthis.dom.borderLeft.style.display = \"none\";\n\n\t\tthis.s.drag.dragging = false;\n\n\t\tclearInterval( this.s.screen.interval );\n\n\t\tvar cells = [];\n\t\tvar table = this.dom.table;\n\t\tvar coordsStart = this._fnTargetCoords( this.s.drag.startTd );\n\t\tvar coordsEnd = this._fnTargetCoords( this.s.drag.endTd );\n\t\tvar columnIndex = function ( visIdx ) {\n\t\t\treturn that.s.dt.oApi._fnVisibleToColumnIndex( that.s.dt, visIdx );\n\t\t};\n\n\t\t// xxx - urgh - there must be a way of reducing this...\n\t\tif ( coordsStart.y <= coordsEnd.y ) {\n\t\t\tfor ( i=coordsStart.y ; i<=coordsEnd.y ; i++ ) {\n\t\t\t\tif ( coordsStart.x <= coordsEnd.x ) {\n\t\t\t\t\tfor ( j=coordsStart.x ; j<=coordsEnd.x ; j++ ) {\n\t\t\t\t\t\tcells.push( {\n\t\t\t\t\t\t\tnode:   $('tbody>tr:eq('+i+')>td:eq('+j+')', table)[0],\n\t\t\t\t\t\t\tx:      j - coordsStart.x,\n\t\t\t\t\t\t\ty:      i - coordsStart.y,\n\t\t\t\t\t\t\tcolIdx: columnIndex( j )\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tfor ( j=coordsStart.x ; j>=coordsEnd.x ; j-- ) {\n\t\t\t\t\t\tcells.push( {\n\t\t\t\t\t\t\tnode:   $('tbody>tr:eq('+i+')>td:eq('+j+')', table)[0],\n\t\t\t\t\t\t\tx:      j - coordsStart.x,\n\t\t\t\t\t\t\ty:      i - coordsStart.y,\n\t\t\t\t\t\t\tcolIdx: columnIndex( j )\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tfor ( i=coordsStart.y ; i>=coordsEnd.y ; i-- ) {\n\t\t\t\tif ( coordsStart.x <= coordsEnd.x ) {\n\t\t\t\t\tfor ( j=coordsStart.x ; j<=coordsEnd.x ; j++ ) {\n\t\t\t\t\t\tcells.push( {\n\t\t\t\t\t\t\tnode:   $('tbody>tr:eq('+i+')>td:eq('+j+')', table)[0],\n\t\t\t\t\t\t\tx:      j - coordsStart.x,\n\t\t\t\t\t\t\ty:      i - coordsStart.y,\n\t\t\t\t\t\t\tcolIdx: columnIndex( j )\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tfor ( j=coordsStart.x ; j>=coordsEnd.x ; j-- ) {\n\t\t\t\t\t\tcells.push( {\n\t\t\t\t\t\t\tnode:   $('tbody>tr:eq('+i+')>td:eq('+j+')', table)[0],\n\t\t\t\t\t\t\tx:      coordsStart.x - j,\n\t\t\t\t\t\t\ty:      coordsStart.y - i,\n\t\t\t\t\t\t\tcolIdx: columnIndex( j )\n\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// An auto-fill requires 2 or more cells\n\t\tif ( cells.length <= 1 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar edited = [];\n\t\tvar previous;\n\n\t\tfor ( i=0, iLen=cells.length ; i<iLen ; i++ ) {\n\t\t\tvar cell      = cells[i];\n\t\t\tvar column    = this.s.columns[ cell.colIdx ];\n\t\t\tvar read      = column.read.call( column, cell.node );\n\t\t\tvar stepValue = column.step.call( column, cell.node, read, previous, i, cell.x, cell.y );\n\n\t\t\tcolumn.write.call( column, cell.node, stepValue );\n\n\t\t\tprevious = stepValue;\n\t\t\tedited.push( {\n\t\t\t\tcell:     cell,\n\t\t\t\tcolIdx:   cell.colIdx,\n\t\t\t\tnewValue: stepValue,\n\t\t\t\toldValue: read\n\t\t\t} );\n\t\t}\n\n\t\tif ( this.c.complete !== null ) {\n\t\t\tthis.c.complete.call( this, edited );\n\t\t}\n\n\t\t// In 1.10 we can do a static draw\n\t\tif ( DataTable.Api ) {\n\t\t\tnew DataTable.Api( this.s.dt ).draw( false );\n\t\t}\n\t\telse {\n\t\t\tthis.s.dt.oInstance.fnDraw();\n\t\t}\n\t},\n\n\n\t/**\n\t * Display the drag handle on mouse over cell\n\t *  @method  _fnFillerDisplay\n\t *  @param   {Object} e Event object\n\t *  @returns void\n\t */\n\t\"_fnFillerDisplay\": function (e)\n\t{\n\t\tvar filler = this.dom.filler;\n\n\t\t/* Don't display automatically when dragging */\n\t\tif ( this.s.drag.dragging)\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\t/* Check that we are allowed to AutoFill this column or not */\n\t\tvar nTd = (e.target.nodeName.toLowerCase() == 'td') ? e.target : $(e.target).parents('td')[0];\n\t\tvar iX = this._fnTargetCoords(nTd).column;\n\t\tif ( !this.s.columns[iX].enable )\n\t\t{\n\t\t\tfiller.style.display = \"none\";\n\t\t\treturn;\n\t\t}\n\n\t\tif (e.type == 'mouseover')\n\t\t{\n\t\t\tthis.dom.currentTarget = nTd;\n\t\t\tthis._fnFillerPosition( nTd );\n\n\t\t\tfiller.style.display = \"block\";\n\t\t}\n\t\telse if ( !e.relatedTarget || !e.relatedTarget.className.match(/AutoFill/) )\n\t\t{\n\t\t\tfiller.style.display = \"none\";\n\t\t}\n\t},\n\n\n\t/**\n\t * Position the filler icon over a cell\n\t *  @method  _fnFillerPosition\n\t *  @param   {Node} nTd Cell to position filler icon over\n\t *  @returns void\n\t */\n\t\"_fnFillerPosition\": function ( nTd )\n\t{\n\t\tvar offset = $(nTd).offset();\n\t\tvar filler = this.dom.filler;\n\t\tfiller.style.top = (offset.top - (this.s.filler.height / 2)-1 + $(nTd).outerHeight())+\"px\";\n\t\tfiller.style.left = (offset.left - (this.s.filler.width / 2)-1 + $(nTd).outerWidth())+\"px\";\n\t}\n};\n\n\n// Alias for access\nDataTable.AutoFill = AutoFill;\nDataTable.AutoFill = AutoFill;\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Constants\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/**\n * AutoFill version\n *  @constant  version\n *  @type      String\n *  @default   See code\n */\nAutoFill.version = \"1.2.1\";\n\n\n/**\n * AutoFill defaults\n *  @namespace\n */\nAutoFill.defaults = {\n\t/**\n\t * Mode for dragging (restrict to y-axis only, x-axis only, either one or none):\n\t *\n\t *  * `y`      - y-axis only (default)\n\t *  * `x`      - x-axis only\n\t *  * `either` - either one, but not both axis at the same time\n\t *  * `both`   - multiple cells allowed\n\t *\n\t * @type {string}\n\t * @default `y`\n\t */\n\tmode: 'y',\n\n\tcomplete: null,\n\n\t/**\n\t * Column definition defaults\n\t *  @namespace\n\t */\n\tcolumn: {\n\t\t/**\n\t\t * If AutoFill should be enabled on this column\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tenable: true,\n\n\t\t/**\n\t\t * Allow automatic increment / decrement on this column if a number\n\t\t * is found.\n\t\t *\n\t\t * @type {boolean}\n\t\t * @default true\n\t\t */\n\t\tincrement: true,\n\n\t\t/**\n\t\t * Cell read function\n\t\t *\n\t\t * Default function will simply read the value from the HTML of the\n\t\t * cell.\n\t\t *\n\t\t * @type   {function}\n\t\t * @param  {node} cell `th` / `td` element to read the value from\n\t\t * @return {string}    Data that has been read\n\t\t */\n\t\tread: function ( cell ) {\n\t\t\treturn $(cell).html();\n\t\t},\n\n\t\t/**\n\t\t * Cell write function\n\t\t *\n\t\t * Default function will simply write to the HTML and tell the DataTable\n\t\t * to update.\n\t\t *\n\t\t * @type   {function}\n\t\t * @param  {node} cell `th` / `td` element to write the value to\n\t\t * @return {string}    Data two write\n\t\t */\n\t\twrite: function ( cell, val ) {\n\t\t\tvar table = $(cell).parents('table');\n\t\t\tif ( DataTable.Api ) {\n\t\t\t\t// 1.10\n\t\t\t\ttable.DataTable().cell( cell ).data( val );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// 1.9\n\t\t\t\tvar dt = table.dataTable();\n\t\t\t\tvar pos = dt.fnGetPosition( cell );\n\t\t\t\tdt.fnUpdate( val, pos[0], pos[2], false );\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Step function. This provides the ability to customise how the values\n\t\t * are incremented.\n\t\t *\n\t\t * @param  {node} cell `th` / `td` element that is being operated upon\n\t\t * @param  {string} read Cell value from `read` function\n\t\t * @param  {string} last Value of the previous cell\n\t\t * @param  {integer} i Loop counter\n\t\t * @param  {integer} x Cell x-position in the current auto-fill. The\n\t\t *   starting cell is coordinate 0 regardless of its physical position\n\t\t *   in the DataTable.\n\t\t * @param  {integer} y Cell y-position in the current auto-fill. The\n\t\t *   starting cell is coordinate 0 regardless of its physical position\n\t\t *   in the DataTable.\n\t\t * @return {string} Value to write\n\t\t */\n\t\tstep: function ( cell, read, last, i, x, y ) {\n\t\t\t// Increment a number if it is found\n\t\t\tvar re = /(\\-?\\d+)/;\n\t\t\tvar match = this.increment && last ? last.match(re) : null;\n\t\t\tif ( match ) {\n\t\t\t\treturn last.replace( re, parseInt(match[1],10) + (x<0 || y<0 ? -1 : 1) );\n\t\t\t}\n\t\t\treturn last === undefined ?\n\t\t\t\tread :\n\t\t\t\tlast;\n\t\t}\n\t}\n};\n\nreturn AutoFill;\n};\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery && !jQuery.fn.dataTable.AutoFill ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n}(window, document));\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/License.txt",
    "content": "Copyright (c) 2010-2015 SpryMedia Limited\nhttp://datatables.net\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/Readme.md",
    "content": "# ColReorder\n\nColReorder adds the ability for the end user to click and drag column headers to reorder a table as they see fit, to DataTables. Key features include:\n\n* Very easy integration with DataTables\n* Tight integration with all other DataTables plug-ins\n* The ability to exclude the first (or more) column from being movable\n* Predefine a column order\n* Save staving integration with DataTables\n\n\n# Installation\n\nTo use ColReorder, first download DataTables ( http://datatables.net/download ) and place the unzipped ColReorder package into a `extensions` directory in the DataTables package. This will allow the pages in the examples to operate correctly. To see the examples running, open the `examples` directory in your web-browser.\n\n\n# Basic usage\n\nColReorder is initialised using the `$.fn.dataTable.ColReorder` constructor. For example:\n\n```js\n$(document).ready( function () {\n    $('#example').DataTable();\n\n    new $.fn.dataTable.ColReorder( table );\n} );\n```\n\n\n# Documentation / support\n\n* Documentation: http://datatables.net/extensions/colreorder/\n* DataTables support forums: http://datatables.net/forums\n\n\n# GitHub\n\nIf you fancy getting involved with the development of ColReorder and help make it better, please refer to its GitHub repo: https://github.com/DataTables/ColReorder\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/css/dataTables.colReorder.css",
    "content": "/*\n * Namespace DTCR - \"DataTables ColReorder\" plug-in\n */\n\ntable.DTCR_clonedTable {\n\tbackground-color: rgba(255, 255, 255, 0.7);\n\tz-index: 202;\n}\n\ndiv.DTCR_pointer {\n\twidth: 1px;\n\tbackground-color: #0259C4;\n\tz-index: 201;\n}"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/alt_insert.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - Alternative insert styling</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\ndiv.DTCR_pointer {\n\tmargin-top: -15px;\n\tmargin-left: -9px;\n\twidth: 18px;\n\tbackground: url('../images/insert.png') no-repeat top left;\n}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'Rlfrtip'\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>Alternative insert styling</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Using CSS it is easy to modify the insert bar to suit your web-site. This example shows how an arrow can be used to show the insert point rather than the\n\t\t\t\tstraight bar used in the other examples by simply adding an extra CSS rule to include the image.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'Rlfrtip'\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">div.DTCR_pointer {\n\tmargin-top: -15px;\n\tmargin-left: -9px;\n\twidth: 18px;\n\tbackground: url('../images/insert.png') no-repeat top left;\n}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/col_filter.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - Individual column filtering</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n    // Setup - add a text input to each footer cell\n    $('#example tfoot th').each( function () {\n        var title = $('#example thead th').eq( $(this).index() ).text();\n        $(this).html( '<input type=\"text\" placeholder=\"Search '+title+'\" />' );\n    } );\n \n    // DataTable\n    var table = $('#example').DataTable( {\n\t\tdom: 'Rlfrtip'\n\t} );\n     \n    // Apply the filter\n    $(\"#example tfoot input\").on( 'keyup change', function () {\n        table\n            .column( $(this).parent().index()+':visible' )\n            .search( this.value )\n            .draw();\n    } );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>Individual column filtering</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example of how to use ColReorder shows how it can with with DataTables' ability to do individual column filtering. The basic example is exactly the same as\n\t\t\t\tthe DataTables column filtering example, but with ColReorder also added to the table (through the <code>R</code> option for <a href=\n\t\t\t\t\"//datatables.net/reference/option/dom\"><code class=\"option\" title=\"DataTables initialisation option\">dom<span>DT</span></code></a>).</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n    // Setup - add a text input to each footer cell\n    $('#example tfoot th').each( function () {\n        var title = $('#example thead th').eq( $(this).index() ).text();\n        $(this).html( '&lt;input type=&quot;text&quot; placeholder=&quot;Search '+title+'&quot; /&gt;' );\n    } );\n \n    // DataTable\n    var table = $('#example').DataTable( {\n\t\tdom: 'Rlfrtip'\n\t} );\n     \n    // Apply the filter\n    $(&quot;#example tfoot input&quot;).on( 'keyup change', function () {\n        table\n            .column( $(this).parent().index()+':visible' )\n            .search( this.value )\n            .draw();\n    } );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/colvis.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - ColVis integration</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../ColVis/css/dataTables.colVis.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../ColVis/js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n    var table = $('#example').DataTable( {\n        dom: 'RC<\"clear\">lfrtip',\n        columnDefs: [\n            { visible: false, targets: 1 }\n        ]\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>ColVis integration</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>ColReorder interfaces with the <a href=\"//datatables.net/extensions/colvis\">ColVis extension</a> for DataTables by updating the order of the list of columns\n\t\t\t\twhenever a reorder is done. This is shown in the example below, where one column has been initially hidden to add extra emphasis to ColVis.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n    var table = $('#example').DataTable( {\n        dom: 'RC&lt;&quot;clear&quot;&gt;lfrtip',\n        columnDefs: [\n            { visible: false, targets: 1 }\n        ]\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../ColVis/js/dataTables.colVis.js\">../../ColVis/js/dataTables.colVis.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../ColVis/css/dataTables.colVis.css\">../../ColVis/css/dataTables.colVis.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/fixedcolumns.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - FixedColumns integration</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../FixedColumns/css/dataTables.fixedColumns.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../FixedColumns/js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\twindow.table = $('#example').DataTable( {\n\t\tdom: 'Rlfrtip',\n\t\tscrollX: true,\n\t\tscrollCollapse: true,\n\t\tcolumnDefs: [\n\t\t\t{ orderable: false, targets: 0 },\n\t\t\t{ orderable: false, targets: -1 }\n\t\t],\n\t\tordering: [[ 1, 'asc' ]],\n\t\tcolReorder: {\n\t\t\tfixedColumnsLeft: 1,\n\t\t\tfixedColumnsRight: 1\n\t\t}\n\t} );\n\n\twindow.fc = new $.fn.dataTable.FixedColumns( table, {\n\t\tleftColumns: 1,\n\t\trightColumns: 1\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>FixedColumns integration</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>While ColReorder works with the built-in scrolling options in DataTables (<a href=\"//datatables.net/reference/option/scrollY\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">scrollY<span>DT</span></code></a> and <a href=\"//datatables.net/reference/option/scrollX\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">scrollX<span>DT</span></code></a>) and also the <a href=\"//datatables.net/extensions/fixedcolumns\">FixedColumns\n\t\t\t\textension</a>.</p>\n\n\t\t\t\t<p>ColReorder provides the <code>fixedColumnsLeft</code> and <code>fixedColumnsRight</code> options which allows you disallow reordering of the fixed columns\n\t\t\t\t(which is required).</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\twindow.table = $('#example').DataTable( {\n\t\tdom: 'Rlfrtip',\n\t\tscrollX: true,\n\t\tscrollCollapse: true,\n\t\tcolumnDefs: [\n\t\t\t{ orderable: false, targets: 0 },\n\t\t\t{ orderable: false, targets: -1 }\n\t\t],\n\t\tordering: [[ 1, 'asc' ]],\n\t\tcolReorder: {\n\t\t\tfixedColumnsLeft: 1,\n\t\t\tfixedColumnsRight: 1\n\t\t}\n\t} );\n\n\twindow.fc = new $.fn.dataTable.FixedColumns( table, {\n\t\tleftColumns: 1,\n\t\trightColumns: 1\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../FixedColumns/js/dataTables.fixedColumns.js\">../../FixedColumns/js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../FixedColumns/css/dataTables.fixedColumns.css\">../../FixedColumns/css/dataTables.fixedColumns.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/fixedheader.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - FixedHeader integration</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../FixedHeader/css/dataTables.fixedHeader.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../FixedHeader/js/dataTables.fixedHeader.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\tvar table = $('#example').dataTable( {\n\t\tdom: 'Rlfrtip'\n\t} );\n\n\tnew $.fn.dataTable.fixedHeader( table );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>FixedHeader integration</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>FixedHeader is a particularly useful plug-in for DataTables, allowing a table header to float at the top of a scrolling window. ColReorder works well with\n\t\t\t\tFixedHeader, allowing you to reorder columns even using the floating header, as shown in the example below.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').dataTable( {\n\t\tdom: 'Rlfrtip'\n\t} );\n\n\tnew $.fn.dataTable.fixedHeader( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../FixedHeader/js/dataTables.fixedHeader.js\">../../FixedHeader/js/dataTables.fixedHeader.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../FixedHeader/css/dataTables.fixedHeader.css\">../../FixedHeader/css/dataTables.fixedHeader.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\n\t<title>ColReorder examples - ColReorder examples</title>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>ColReorder examples</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>ColReorder adds the ability for the end user to click and drag column headers to reorder a table as they see fit, to DataTables. Key features include:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li>Very easy integration with DataTables</li>\n\t\t\t\t\t<li>Tight integration with all other DataTables plug-ins</li>\n\t\t\t\t\t<li>The ability to exclude the first (or more) column from being movable</li>\n\t\t\t\t\t<li>Predefine a column order</li>\n\t\t\t\t\t<li>Save staving integration with DataTables</li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/jqueryui.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - jQuery UI styling</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../Plugins/integration/jqueryui/dataTables.jqueryui.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../Plugins/integration/jqueryui/dataTables.jqueryui.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\tvar table = $('#example').dataTable();\n\n\tnew $.fn.dataTable.ColReorder( table );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>jQuery UI styling</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows how the jQuery UI ThemeRoller option in DataTables can be used with ColReorder.</p>\n\n\t\t\t\t<p>The important thing to note here is that it is easier to use <code>new $.fn.dataTable.ColReorder()</code> to add ColReorder to the table rather than <a href=\n\t\t\t\t\"//datatables.net/reference/option/dom\"><code class=\"option\" title=\"DataTables initialisation option\">dom<span>DT</span></code></a> as the jQuery UI integration\n\t\t\t\tuses a complex expression for <a href=\"//datatables.net/reference/option/dom\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">dom<span>DT</span></code></a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').dataTable();\n\n\tnew $.fn.dataTable.ColReorder( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../Plugins/integration/jqueryui/dataTables.jqueryui.js\">../../Plugins/integration/jqueryui/dataTables.jqueryui.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css\">//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../Plugins/integration/jqueryui/dataTables.jqueryui.css\">../../Plugins/integration/jqueryui/dataTables.jqueryui.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/new_init.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - Initialisation using `new`</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.ColReorder( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>Initialisation using `new`</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>As well as providing the option to be initialised through the <code>R</code> option of <a href=\"//datatables.net/reference/option/dom\"><code class=\"option\"\n\t\t\t\ttitle=\"DataTables initialisation option\">dom<span>DT</span></code></a>, ColReorder can also be added to a DataTable using direct initialisation - <code>new\n\t\t\t\t$.fn.dataTable.ColReorder();</code> as shown in this example.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.ColReorder( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/predefined.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - Predefined column ordering</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').dataTable( {\n\t\tdom: 'Rlfrtip',\n\t\tcolReorder: {\n\t\t\torder: [ 4, 3, 2, 1, 0, 5 ]\n\t\t}\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>Predefined column ordering</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>ColReorder provides the ability to specify a column ordering which is not that of the HTML (which typically you will want) through the parameter\n\t\t\t\t<code>colReorder.order</code>. This is an array of integers with the column ordering you want.</p>\n\n\t\t\t\t<p>For full information about the ColReorder options, please refer to the <a href=\"//datatables.net/extensions/colreorder/options\">ColReorder options\n\t\t\t\tdocumentation</a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').dataTable( {\n\t\tdom: 'Rlfrtip',\n\t\tcolReorder: {\n\t\t\torder: [ 4, 3, 2, 1, 0, 5 ]\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/realtime.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - Realtime updating</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').dataTable( {\n\t\tdom: 'Rlfrtip',\n\t\tcolReorder: {\n\t\t\trealtime: true\n\t\t}\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>Realtime updating</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>While the ColReorder insertion point indicator can be styled, another option to show the end user what the column will look like when the table has been\n\t\t\t\treordered is to actually do the reordering while the mouse is still dragging the column header. This is shown in this example and is controlled by the\n\t\t\t\t<code>realtime</code> parameter.</p>\n\n\t\t\t\t<p>For full information about the ColReorder options, please refer to the <a href=\"//datatables.net/extensions/colreorder/options\">ColReorder options\n\t\t\t\tdocumentation</a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').dataTable( {\n\t\tdom: 'Rlfrtip',\n\t\tcolReorder: {\n\t\t\trealtime: true\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/reset.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - Reset ordering API</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tdom: 'Rlfrtip',\n\t\tcolReorder: {\n\t\t\torder: [ 4, 3, 2, 1, 0 ]\n\t\t}\n\t} );\n\t\n\t$('#reset').click( function (e) {\n\t\te.preventDefault();\n\t\t\n\t\ttable.colReorder.reset();\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>Reset ordering API</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>One useful control option to present the end user when using ColReorder is the ability to reset the column ordering to that which was found in the HTML. This\n\t\t\t\tcan be done by calling the <code>reset</code> API function. While ColReorder does not provide a visual element for this itself (in order to provide maximum\n\t\t\t\tflexibility) it is easy to hook to an event handler, as shown in this example.</p>\n\n\t\t\t\t<p>For full information about the ColReorder API, please refer to the <a href=\"//datatables.net/extensions/colreorder/api\">ColReorder API documentation</a>.</p>\n\t\t\t</div><button id=\"reset\">Reset to original HTML order</button><br>\n\t\t\t<br>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tdom: 'Rlfrtip',\n\t\tcolReorder: {\n\t\t\torder: [ 4, 3, 2, 1, 0 ]\n\t\t}\n\t} );\n\t\n\t$('#reset').click( function (e) {\n\t\te.preventDefault();\n\t\t\n\t\ttable.colReorder.reset();\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/scrolling.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - Scrolling table</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').dataTable( {\n\t\tdom:     'Rlfrtip',\n\t\tscrollY: '200px',\n\t\tpaging:  false\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>Scrolling table</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This is a simple example to show ColReorder working with DataTables scrolling (<a href=\"//datatables.net/reference/option/scrollY\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">scrollY<span>DT</span></code></a> and <a href=\"//datatables.net/reference/option/scrollX\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">scrollX<span>DT</span></code></a>).</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').dataTable( {\n\t\tdom:     'Rlfrtip',\n\t\tscrollY: '200px',\n\t\tpaging:  false\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/server_side.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - Server-side processing</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').dataTable( {\n\t\tdom: 'Rlfrtip',\n\t\tprocessing: true,\n\t\tserverSide: true,\n\t\tajax: \"../../../examples/server_side/scripts/objects.php\",\n\t\tcolumns: [\n\t\t\t{ data: \"first_name\" },\n\t\t\t{ data: \"last_name\" },\n\t\t\t{ data: \"position\" },\n\t\t\t{ data: \"office\" },\n\t\t\t{ data: \"start_date\" },\n\t\t\t{ data: \"salary\" }\n\t\t]\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>Server-side processing</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Server-side processing can be exceptionally useful in DataTables when dealing with massive data sets, and ColReorder works with this as would be expected.</p>\n\n\t\t\t\t<p>It is recommend that you use object based data with server-side processing and ColReorder, as this provides easily understandable mapping between the the\n\t\t\t\tcolumns and the data relation on the server, otherwise you need to work out array indexes on each call!</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').dataTable( {\n\t\tdom: 'Rlfrtip',\n\t\tprocessing: true,\n\t\tserverSide: true,\n\t\tajax: &quot;../../../examples/server_side/scripts/objects.php&quot;,\n\t\tcolumns: [\n\t\t\t{ data: &quot;first_name&quot; },\n\t\t\t{ data: &quot;last_name&quot; },\n\t\t\t{ data: &quot;position&quot; },\n\t\t\t{ data: &quot;office&quot; },\n\t\t\t{ data: &quot;start_date&quot; },\n\t\t\t{ data: &quot;salary&quot; }\n\t\t]\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/simple.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - Basic initialisation</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'Rlfrtip'\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>Basic initialisation</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows the basic use case of the ColReorder plug-in. With ColReorder enabled for a table, the user has the ability to click and drag any table\n\t\t\t\theader cell, and drop it where they wish the column to be inserted. The insert point is shown visually, and the column reordering is done as soon as the mouse\n\t\t\t\tbutton is released.</p>\n\n\t\t\t\t<p>ColReorder is added to a DataTable through the <code>R</code> character that it adds to DataTables feature plug-ins. This means that you simply add the\n\t\t\t\tcharacter <code>R</code> to the <a href=\"//datatables.net/reference/option/dom\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">dom<span>DT</span></code></a> parameter for your table to add ColReorder - as shown in the example below.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'Rlfrtip'\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/examples/state_save.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColReorder example - State saving</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colReorder.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colReorder.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').dataTable( {\n\t\tdom: 'Rlfrtip',\n\t\tstateSave: true\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColReorder example <span>State saving</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>A useful interaction pattern to use in DataTables is state saving, so when the end user reloads or revisits a page its previous state is retained. ColReorder\n\t\t\t\tworks seamlessly with state saving in DataTables (<a href=\"//datatables.net/reference/option/stateSave\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">stateSave<span>DT</span></code></a>), remembering and restoring the column positions, as well as everything else such as sorting\n\t\t\t\tand filtering.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').dataTable( {\n\t\tdom: 'Rlfrtip',\n\t\tstateSave: true\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colReorder.js\">../js/dataTables.colReorder.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colReorder.css\">../css/dataTables.colReorder.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation using `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alt_insert.html\">Alternative insert styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./realtime.html\">Realtime updating</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./state_save.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./predefined.html\">Predefined column ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./reset.html\">Reset ordering API</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedcolumns.html\">FixedColumns integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedheader.html\">FixedHeader integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server_side.html\">Server-side processing</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColReorder/js/dataTables.colReorder.js",
    "content": "/*! ColReorder 1.1.3\n * ©2010-2014 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary     ColReorder\n * @description Provide the ability to reorder columns in a DataTable\n * @version     1.1.3\n * @file        dataTables.colReorder.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2010-2014 SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n *   MIT license - http://datatables.net/license/mit\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n(function(window, document, undefined) {\n\n\n/**\n * Switch the key value pairing of an index array to be value key (i.e. the old value is now the\n * key). For example consider [ 2, 0, 1 ] this would be returned as [ 1, 2, 0 ].\n *  @method  fnInvertKeyValues\n *  @param   array aIn Array to switch around\n *  @returns array\n */\nfunction fnInvertKeyValues( aIn )\n{\n\tvar aRet=[];\n\tfor ( var i=0, iLen=aIn.length ; i<iLen ; i++ )\n\t{\n\t\taRet[ aIn[i] ] = i;\n\t}\n\treturn aRet;\n}\n\n\n/**\n * Modify an array by switching the position of two elements\n *  @method  fnArraySwitch\n *  @param   array aArray Array to consider, will be modified by reference (i.e. no return)\n *  @param   int iFrom From point\n *  @param   int iTo Insert point\n *  @returns void\n */\nfunction fnArraySwitch( aArray, iFrom, iTo )\n{\n\tvar mStore = aArray.splice( iFrom, 1 )[0];\n\taArray.splice( iTo, 0, mStore );\n}\n\n\n/**\n * Switch the positions of nodes in a parent node (note this is specifically designed for\n * table rows). Note this function considers all element nodes under the parent!\n *  @method  fnDomSwitch\n *  @param   string sTag Tag to consider\n *  @param   int iFrom Element to move\n *  @param   int Point to element the element to (before this point), can be null for append\n *  @returns void\n */\nfunction fnDomSwitch( nParent, iFrom, iTo )\n{\n\tvar anTags = [];\n\tfor ( var i=0, iLen=nParent.childNodes.length ; i<iLen ; i++ )\n\t{\n\t\tif ( nParent.childNodes[i].nodeType == 1 )\n\t\t{\n\t\t\tanTags.push( nParent.childNodes[i] );\n\t\t}\n\t}\n\tvar nStore = anTags[ iFrom ];\n\n\tif ( iTo !== null )\n\t{\n\t\tnParent.insertBefore( nStore, anTags[iTo] );\n\t}\n\telse\n\t{\n\t\tnParent.appendChild( nStore );\n\t}\n}\n\n\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\n/**\n * Plug-in for DataTables which will reorder the internal column structure by taking the column\n * from one position (iFrom) and insert it into a given point (iTo).\n *  @method  $.fn.dataTableExt.oApi.fnColReorder\n *  @param   object oSettings DataTables settings object - automatically added by DataTables!\n *  @param   int iFrom Take the column to be repositioned from this point\n *  @param   int iTo and insert it into this point\n *  @returns void\n */\n$.fn.dataTableExt.oApi.fnColReorder = function ( oSettings, iFrom, iTo )\n{\n\tvar v110 = $.fn.dataTable.Api ? true : false;\n\tvar i, iLen, j, jLen, iCols=oSettings.aoColumns.length, nTrs, oCol;\n\tvar attrMap = function ( obj, prop, mapping ) {\n\t\tif ( ! obj[ prop ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar a = obj[ prop ].split('.');\n\t\tvar num = a.shift();\n\n\t\tif ( isNaN( num*1 ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tobj[ prop ] = mapping[ num*1 ]+'.'+a.join('.');\n\t};\n\n\t/* Sanity check in the input */\n\tif ( iFrom == iTo )\n\t{\n\t\t/* Pointless reorder */\n\t\treturn;\n\t}\n\n\tif ( iFrom < 0 || iFrom >= iCols )\n\t{\n\t\tthis.oApi._fnLog( oSettings, 1, \"ColReorder 'from' index is out of bounds: \"+iFrom );\n\t\treturn;\n\t}\n\n\tif ( iTo < 0 || iTo >= iCols )\n\t{\n\t\tthis.oApi._fnLog( oSettings, 1, \"ColReorder 'to' index is out of bounds: \"+iTo );\n\t\treturn;\n\t}\n\n\t/*\n\t * Calculate the new column array index, so we have a mapping between the old and new\n\t */\n\tvar aiMapping = [];\n\tfor ( i=0, iLen=iCols ; i<iLen ; i++ )\n\t{\n\t\taiMapping[i] = i;\n\t}\n\tfnArraySwitch( aiMapping, iFrom, iTo );\n\tvar aiInvertMapping = fnInvertKeyValues( aiMapping );\n\n\n\t/*\n\t * Convert all internal indexing to the new column order indexes\n\t */\n\t/* Sorting */\n\tfor ( i=0, iLen=oSettings.aaSorting.length ; i<iLen ; i++ )\n\t{\n\t\toSettings.aaSorting[i][0] = aiInvertMapping[ oSettings.aaSorting[i][0] ];\n\t}\n\n\t/* Fixed sorting */\n\tif ( oSettings.aaSortingFixed !== null )\n\t{\n\t\tfor ( i=0, iLen=oSettings.aaSortingFixed.length ; i<iLen ; i++ )\n\t\t{\n\t\t\toSettings.aaSortingFixed[i][0] = aiInvertMapping[ oSettings.aaSortingFixed[i][0] ];\n\t\t}\n\t}\n\n\t/* Data column sorting (the column which the sort for a given column should take place on) */\n\tfor ( i=0, iLen=iCols ; i<iLen ; i++ )\n\t{\n\t\toCol = oSettings.aoColumns[i];\n\t\tfor ( j=0, jLen=oCol.aDataSort.length ; j<jLen ; j++ )\n\t\t{\n\t\t\toCol.aDataSort[j] = aiInvertMapping[ oCol.aDataSort[j] ];\n\t\t}\n\n\t\t// Update the column indexes\n\t\tif ( v110 ) {\n\t\t\toCol.idx = aiInvertMapping[ oCol.idx ];\n\t\t}\n\t}\n\n\tif ( v110 ) {\n\t\t// Update 1.10 optimised sort class removal variable\n\t\t$.each( oSettings.aLastSort, function (i, val) {\n\t\t\toSettings.aLastSort[i].src = aiInvertMapping[ val.src ];\n\t\t} );\n\t}\n\n\t/* Update the Get and Set functions for each column */\n\tfor ( i=0, iLen=iCols ; i<iLen ; i++ )\n\t{\n\t\toCol = oSettings.aoColumns[i];\n\n\t\tif ( typeof oCol.mData == 'number' ) {\n\t\t\toCol.mData = aiInvertMapping[ oCol.mData ];\n\n\t\t\t// regenerate the get / set functions\n\t\t\toSettings.oApi._fnColumnOptions( oSettings, i, {} );\n\t\t}\n\t\telse if ( $.isPlainObject( oCol.mData ) ) {\n\t\t\t// HTML5 data sourced\n\t\t\tattrMap( oCol.mData, '_',      aiInvertMapping );\n\t\t\tattrMap( oCol.mData, 'filter', aiInvertMapping );\n\t\t\tattrMap( oCol.mData, 'sort',   aiInvertMapping );\n\t\t\tattrMap( oCol.mData, 'type',   aiInvertMapping );\n\n\t\t\t// regenerate the get / set functions\n\t\t\toSettings.oApi._fnColumnOptions( oSettings, i, {} );\n\t\t}\n\t}\n\n\n\t/*\n\t * Move the DOM elements\n\t */\n\tif ( oSettings.aoColumns[iFrom].bVisible )\n\t{\n\t\t/* Calculate the current visible index and the point to insert the node before. The insert\n\t\t * before needs to take into account that there might not be an element to insert before,\n\t\t * in which case it will be null, and an appendChild should be used\n\t\t */\n\t\tvar iVisibleIndex = this.oApi._fnColumnIndexToVisible( oSettings, iFrom );\n\t\tvar iInsertBeforeIndex = null;\n\n\t\ti = iTo < iFrom ? iTo : iTo + 1;\n\t\twhile ( iInsertBeforeIndex === null && i < iCols )\n\t\t{\n\t\t\tiInsertBeforeIndex = this.oApi._fnColumnIndexToVisible( oSettings, i );\n\t\t\ti++;\n\t\t}\n\n\t\t/* Header */\n\t\tnTrs = oSettings.nTHead.getElementsByTagName('tr');\n\t\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tfnDomSwitch( nTrs[i], iVisibleIndex, iInsertBeforeIndex );\n\t\t}\n\n\t\t/* Footer */\n\t\tif ( oSettings.nTFoot !== null )\n\t\t{\n\t\t\tnTrs = oSettings.nTFoot.getElementsByTagName('tr');\n\t\t\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tfnDomSwitch( nTrs[i], iVisibleIndex, iInsertBeforeIndex );\n\t\t\t}\n\t\t}\n\n\t\t/* Body */\n\t\tfor ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tif ( oSettings.aoData[i].nTr !== null )\n\t\t\t{\n\t\t\t\tfnDomSwitch( oSettings.aoData[i].nTr, iVisibleIndex, iInsertBeforeIndex );\n\t\t\t}\n\t\t}\n\t}\n\n\t/*\n\t * Move the internal array elements\n\t */\n\t/* Columns */\n\tfnArraySwitch( oSettings.aoColumns, iFrom, iTo );\n\n\t/* Search columns */\n\tfnArraySwitch( oSettings.aoPreSearchCols, iFrom, iTo );\n\n\t/* Array array - internal data anodes cache */\n\tfor ( i=0, iLen=oSettings.aoData.length ; i<iLen ; i++ )\n\t{\n\t\tvar data = oSettings.aoData[i];\n\n\t\tif ( v110 ) {\n\t\t\t// DataTables 1.10+\n\t\t\tif ( data.anCells ) {\n\t\t\t\tfnArraySwitch( data.anCells, iFrom, iTo );\n\t\t\t}\n\n\t\t\t// For DOM sourced data, the invalidate will reread the cell into\n\t\t\t// the data array, but for data sources as an array, they need to\n\t\t\t// be flipped\n\t\t\tif ( data.src !== 'dom' && $.isArray( data._aData ) ) {\n\t\t\t\tfnArraySwitch( data._aData, iFrom, iTo );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// DataTables 1.9-\n\t\t\tif ( $.isArray( data._aData ) ) {\n\t\t\t\tfnArraySwitch( data._aData, iFrom, iTo );\n\t\t\t}\n\t\t\tfnArraySwitch( data._anHidden, iFrom, iTo );\n\t\t}\n\t}\n\n\t/* Reposition the header elements in the header layout array */\n\tfor ( i=0, iLen=oSettings.aoHeader.length ; i<iLen ; i++ )\n\t{\n\t\tfnArraySwitch( oSettings.aoHeader[i], iFrom, iTo );\n\t}\n\n\tif ( oSettings.aoFooter !== null )\n\t{\n\t\tfor ( i=0, iLen=oSettings.aoFooter.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tfnArraySwitch( oSettings.aoFooter[i], iFrom, iTo );\n\t\t}\n\t}\n\n\t// In 1.10 we need to invalidate row cached data for sorting, filtering etc\n\tif ( v110 ) {\n\t\tvar api = new $.fn.dataTable.Api( oSettings );\n\t\tapi.rows().invalidate();\n\t}\n\n\t/*\n\t * Update DataTables' event handlers\n\t */\n\n\t/* Sort listener */\n\tfor ( i=0, iLen=iCols ; i<iLen ; i++ )\n\t{\n\t\t$(oSettings.aoColumns[i].nTh).off('click.DT');\n\t\tthis.oApi._fnSortAttachListener( oSettings, oSettings.aoColumns[i].nTh, i );\n\t}\n\n\n\t/* Fire an event so other plug-ins can update */\n\t$(oSettings.oInstance).trigger( 'column-reorder', [ oSettings, {\n\t\t\"iFrom\": iFrom,\n\t\t\"iTo\": iTo,\n\t\t\"aiInvertMapping\": aiInvertMapping\n\t} ] );\n};\n\n\n/**\n * ColReorder provides column visibility control for DataTables\n * @class ColReorder\n * @constructor\n * @param {object} dt DataTables settings object\n * @param {object} opts ColReorder options\n */\nvar ColReorder = function( dt, opts )\n{\n\tvar oDTSettings;\n\n\tif ( $.fn.dataTable.Api ) {\n\t\toDTSettings = new $.fn.dataTable.Api( dt ).settings()[0];\n\t}\n\t// 1.9 compatibility\n\telse if ( dt.fnSettings ) {\n\t\t// DataTables object, convert to the settings object\n\t\toDTSettings = dt.fnSettings();\n\t}\n\telse if ( typeof dt === 'string' ) {\n\t\t// jQuery selector\n\t\tif ( $.fn.dataTable.fnIsDataTable( $(dt)[0] ) ) {\n\t\t\toDTSettings = $(dt).eq(0).dataTable().fnSettings();\n\t\t}\n\t}\n\telse if ( dt.nodeName && dt.nodeName.toLowerCase() === 'table' ) {\n\t\t// Table node\n\t\tif ( $.fn.dataTable.fnIsDataTable( dt.nodeName ) ) {\n\t\t\toDTSettings = $(dt.nodeName).dataTable().fnSettings();\n\t\t}\n\t}\n\telse if ( dt instanceof jQuery ) {\n\t\t// jQuery object\n\t\tif ( $.fn.dataTable.fnIsDataTable( dt[0] ) ) {\n\t\t\toDTSettings = dt.eq(0).dataTable().fnSettings();\n\t\t}\n\t}\n\telse {\n\t\t// DataTables settings object\n\t\toDTSettings = dt;\n\t}\n\n\t// Ensure that we can't initialise on the same table twice\n\tif ( oDTSettings._colReorder ) {\n\t\tthrow \"ColReorder already initialised on table #\"+oDTSettings.nTable.id;\n\t}\n\n\t// Convert from camelCase to Hungarian, just as DataTables does\n\tvar camelToHungarian = $.fn.dataTable.camelToHungarian;\n\tif ( camelToHungarian ) {\n\t\tcamelToHungarian( ColReorder.defaults, ColReorder.defaults, true );\n\t\tcamelToHungarian( ColReorder.defaults, opts || {} );\n\t}\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Public class variables\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * @namespace Settings object which contains customisable information for ColReorder instance\n\t */\n\tthis.s = {\n\t\t/**\n\t\t * DataTables settings object\n\t\t *  @property dt\n\t\t *  @type     Object\n\t\t *  @default  null\n\t\t */\n\t\t\"dt\": null,\n\n\t\t/**\n\t\t * Initialisation object used for this instance\n\t\t *  @property init\n\t\t *  @type     object\n\t\t *  @default  {}\n\t\t */\n\t\t\"init\": $.extend( true, {}, ColReorder.defaults, opts ),\n\n\t\t/**\n\t\t * Number of columns to fix (not allow to be reordered)\n\t\t *  @property fixed\n\t\t *  @type     int\n\t\t *  @default  0\n\t\t */\n\t\t\"fixed\": 0,\n\n\t\t/**\n\t\t * Number of columns to fix counting from right (not allow to be reordered)\n\t\t *  @property fixedRight\n\t\t *  @type     int\n\t\t *  @default  0\n\t\t */\n\t\t\"fixedRight\": 0,\n\n\t\t/**\n\t\t * Callback function for once the reorder has been done\n\t\t *  @property reorderCallback\n\t\t *  @type     function\n\t\t *  @default  null\n\t\t */\n\t\t\"reorderCallback\": null,\n\n\t\t/**\n\t\t * @namespace Information used for the mouse drag\n\t\t */\n\t\t\"mouse\": {\n\t\t\t\"startX\": -1,\n\t\t\t\"startY\": -1,\n\t\t\t\"offsetX\": -1,\n\t\t\t\"offsetY\": -1,\n\t\t\t\"target\": -1,\n\t\t\t\"targetIndex\": -1,\n\t\t\t\"fromIndex\": -1\n\t\t},\n\n\t\t/**\n\t\t * Information which is used for positioning the insert cusor and knowing where to do the\n\t\t * insert. Array of objects with the properties:\n\t\t *   x: x-axis position\n\t\t *   to: insert point\n\t\t *  @property aoTargets\n\t\t *  @type     array\n\t\t *  @default  []\n\t\t */\n\t\t\"aoTargets\": []\n\t};\n\n\n\t/**\n\t * @namespace Common and useful DOM elements for the class instance\n\t */\n\tthis.dom = {\n\t\t/**\n\t\t * Dragging element (the one the mouse is moving)\n\t\t *  @property drag\n\t\t *  @type     element\n\t\t *  @default  null\n\t\t */\n\t\t\"drag\": null,\n\n\t\t/**\n\t\t * The insert cursor\n\t\t *  @property pointer\n\t\t *  @type     element\n\t\t *  @default  null\n\t\t */\n\t\t\"pointer\": null\n\t};\n\n\n\t/* Constructor logic */\n\tthis.s.dt = oDTSettings;\n\tthis.s.dt._colReorder = this;\n\tthis._fnConstruct();\n\n\t/* Add destroy callback */\n\toDTSettings.oApi._fnCallbackReg(oDTSettings, 'aoDestroyCallback', $.proxy(this._fnDestroy, this), 'ColReorder');\n\n\treturn this;\n};\n\n\n\nColReorder.prototype = {\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Public methods\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * Reset the column ordering to the original ordering that was detected on\n\t * start up.\n\t *  @return {this} Returns `this` for chaining.\n\t *\n\t *  @example\n\t *    // DataTables initialisation with ColReorder\n\t *    var table = $('#example').dataTable( {\n\t *        \"sDom\": 'Rlfrtip'\n\t *    } );\n\t *\n\t *    // Add click event to a button to reset the ordering\n\t *    $('#resetOrdering').click( function (e) {\n\t *        e.preventDefault();\n\t *        $.fn.dataTable.ColReorder( table ).fnReset();\n\t *    } );\n\t */\n\t\"fnReset\": function ()\n\t{\n\t\tvar a = [];\n\t\tfor ( var i=0, iLen=this.s.dt.aoColumns.length ; i<iLen ; i++ )\n\t\t{\n\t\t\ta.push( this.s.dt.aoColumns[i]._ColReorder_iOrigCol );\n\t\t}\n\n\t\tthis._fnOrderColumns( a );\n\n\t\treturn this;\n\t},\n\n\t/**\n\t * `Deprecated` - Get the current order of the columns, as an array.\n\t *  @return {array} Array of column identifiers\n\t *  @deprecated `fnOrder` should be used in preference to this method.\n\t *      `fnOrder` acts as a getter/setter.\n\t */\n\t\"fnGetCurrentOrder\": function ()\n\t{\n\t\treturn this.fnOrder();\n\t},\n\n\t/**\n\t * Get the current order of the columns, as an array. Note that the values\n\t * given in the array are unique identifiers for each column. Currently\n\t * these are the original ordering of the columns that was detected on\n\t * start up, but this could potentially change in future.\n\t *  @return {array} Array of column identifiers\n\t *\n\t *  @example\n\t *    // Get column ordering for the table\n\t *    var order = $.fn.dataTable.ColReorder( dataTable ).fnOrder();\n\t *//**\n\t * Set the order of the columns, from the positions identified in the\n\t * ordering array given. Note that ColReorder takes a brute force approach\n\t * to reordering, so it is possible multiple reordering events will occur\n\t * before the final order is settled upon.\n\t *  @param {array} [set] Array of column identifiers in the new order. Note\n\t *    that every column must be included, uniquely, in this array.\n\t *  @return {this} Returns `this` for chaining.\n\t *\n\t *  @example\n\t *    // Swap the first and second columns\n\t *    $.fn.dataTable.ColReorder( dataTable ).fnOrder( [1, 0, 2, 3, 4] );\n\t *\n\t *  @example\n\t *    // Move the first column to the end for the table `#example`\n\t *    var curr = $.fn.dataTable.ColReorder( '#example' ).fnOrder();\n\t *    var first = curr.shift();\n\t *    curr.push( first );\n\t *    $.fn.dataTable.ColReorder( '#example' ).fnOrder( curr );\n\t *\n\t *  @example\n\t *    // Reverse the table's order\n\t *    $.fn.dataTable.ColReorder( '#example' ).fnOrder(\n\t *      $.fn.dataTable.ColReorder( '#example' ).fnOrder().reverse()\n\t *    );\n\t */\n\t\"fnOrder\": function ( set )\n\t{\n\t\tif ( set === undefined )\n\t\t{\n\t\t\tvar a = [];\n\t\t\tfor ( var i=0, iLen=this.s.dt.aoColumns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\ta.push( this.s.dt.aoColumns[i]._ColReorder_iOrigCol );\n\t\t\t}\n\t\t\treturn a;\n\t\t}\n\n\t\tthis._fnOrderColumns( fnInvertKeyValues( set ) );\n\n\t\treturn this;\n\t},\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Private methods (they are of course public in JS, but recommended as private)\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * Constructor logic\n\t *  @method  _fnConstruct\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnConstruct\": function ()\n\t{\n\t\tvar that = this;\n\t\tvar iLen = this.s.dt.aoColumns.length;\n\t\tvar i;\n\n\t\t/* Columns discounted from reordering - counting left to right */\n\t\tif ( this.s.init.iFixedColumns )\n\t\t{\n\t\t\tthis.s.fixed = this.s.init.iFixedColumns;\n\t\t}\n\n\t\t/* Columns discounted from reordering - counting right to left */\n\t\tthis.s.fixedRight = this.s.init.iFixedColumnsRight ?\n\t\t\tthis.s.init.iFixedColumnsRight :\n\t\t\t0;\n\n\t\t/* Drop callback initialisation option */\n\t\tif ( this.s.init.fnReorderCallback )\n\t\t{\n\t\t\tthis.s.reorderCallback = this.s.init.fnReorderCallback;\n\t\t}\n\n\t\t/* Add event handlers for the drag and drop, and also mark the original column order */\n\t\tfor ( i = 0; i < iLen; i++ )\n\t\t{\n\t\t\tif ( i > this.s.fixed-1 && i < iLen - this.s.fixedRight )\n\t\t\t{\n\t\t\t\tthis._fnMouseListener( i, this.s.dt.aoColumns[i].nTh );\n\t\t\t}\n\n\t\t\t/* Mark the original column order for later reference */\n\t\t\tthis.s.dt.aoColumns[i]._ColReorder_iOrigCol = i;\n\t\t}\n\n\t\t/* State saving */\n\t\tthis.s.dt.oApi._fnCallbackReg( this.s.dt, 'aoStateSaveParams', function (oS, oData) {\n\t\t\tthat._fnStateSave.call( that, oData );\n\t\t}, \"ColReorder_State\" );\n\n\t\t/* An initial column order has been specified */\n\t\tvar aiOrder = null;\n\t\tif ( this.s.init.aiOrder )\n\t\t{\n\t\t\taiOrder = this.s.init.aiOrder.slice();\n\t\t}\n\n\t\t/* State loading, overrides the column order given */\n\t\tif ( this.s.dt.oLoadedState && typeof this.s.dt.oLoadedState.ColReorder != 'undefined' &&\n\t\t  this.s.dt.oLoadedState.ColReorder.length == this.s.dt.aoColumns.length )\n\t\t{\n\t\t\taiOrder = this.s.dt.oLoadedState.ColReorder;\n\t\t}\n\n\t\t/* If we have an order to apply - do so */\n\t\tif ( aiOrder )\n\t\t{\n\t\t\t/* We might be called during or after the DataTables initialisation. If before, then we need\n\t\t\t * to wait until the draw is done, if after, then do what we need to do right away\n\t\t\t */\n\t\t\tif ( !that.s.dt._bInitComplete )\n\t\t\t{\n\t\t\t\tvar bDone = false;\n\t\t\t\tthis.s.dt.aoDrawCallback.push( {\n\t\t\t\t\t\"fn\": function () {\n\t\t\t\t\t\tif ( !that.s.dt._bInitComplete && !bDone )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tbDone = true;\n\t\t\t\t\t\t\tvar resort = fnInvertKeyValues( aiOrder );\n\t\t\t\t\t\t\tthat._fnOrderColumns.call( that, resort );\n\t\t\t\t\t\t}\n\t\t\t\t\t},\n\t\t\t\t\t\"sName\": \"ColReorder_Pre\"\n\t\t\t\t} );\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar resort = fnInvertKeyValues( aiOrder );\n\t\t\t\tthat._fnOrderColumns.call( that, resort );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tthis._fnSetColumnIndexes();\n\t\t}\n\t},\n\n\n\t/**\n\t * Set the column order from an array\n\t *  @method  _fnOrderColumns\n\t *  @param   array a An array of integers which dictate the column order that should be applied\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnOrderColumns\": function ( a )\n\t{\n\t\tif ( a.length != this.s.dt.aoColumns.length )\n\t\t{\n\t\t\tthis.s.dt.oInstance.oApi._fnLog( this.s.dt, 1, \"ColReorder - array reorder does not \"+\n\t\t\t\t\"match known number of columns. Skipping.\" );\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( var i=0, iLen=a.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tvar currIndex = $.inArray( i, a );\n\t\t\tif ( i != currIndex )\n\t\t\t{\n\t\t\t\t/* Reorder our switching array */\n\t\t\t\tfnArraySwitch( a, currIndex, i );\n\n\t\t\t\t/* Do the column reorder in the table */\n\t\t\t\tthis.s.dt.oInstance.fnColReorder( currIndex, i );\n\t\t\t}\n\t\t}\n\n\t\t/* When scrolling we need to recalculate the column sizes to allow for the shift */\n\t\tif ( this.s.dt.oScroll.sX !== \"\" || this.s.dt.oScroll.sY !== \"\" )\n\t\t{\n\t\t\tthis.s.dt.oInstance.fnAdjustColumnSizing( false );\n\t\t}\n\n\t\t/* Save the state */\n\t\tthis.s.dt.oInstance.oApi._fnSaveState( this.s.dt );\n\n\t\tthis._fnSetColumnIndexes();\n\t\t\n\t\tif ( this.s.reorderCallback !== null )\n\t\t{\n\t\t\tthis.s.reorderCallback.call( this );\n\t\t}\n\t},\n\n\n\t/**\n\t * Because we change the indexes of columns in the table, relative to their starting point\n\t * we need to reorder the state columns to what they are at the starting point so we can\n\t * then rearrange them again on state load!\n\t *  @method  _fnStateSave\n\t *  @param   object oState DataTables state\n\t *  @returns string JSON encoded cookie string for DataTables\n\t *  @private\n\t */\n\t\"_fnStateSave\": function ( oState )\n\t{\n\t\tvar i, iLen, aCopy, iOrigColumn;\n\t\tvar oSettings = this.s.dt;\n\t\tvar columns = oSettings.aoColumns;\n\n\t\toState.ColReorder = [];\n\n\t\t/* Sorting */\n\t\tif ( oState.aaSorting ) {\n\t\t\t// 1.10.0-\n\t\t\tfor ( i=0 ; i<oState.aaSorting.length ; i++ ) {\n\t\t\t\toState.aaSorting[i][0] = columns[ oState.aaSorting[i][0] ]._ColReorder_iOrigCol;\n\t\t\t}\n\n\t\t\tvar aSearchCopy = $.extend( true, [], oState.aoSearchCols );\n\n\t\t\tfor ( i=0, iLen=columns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tiOrigColumn = columns[i]._ColReorder_iOrigCol;\n\n\t\t\t\t/* Column filter */\n\t\t\t\toState.aoSearchCols[ iOrigColumn ] = aSearchCopy[i];\n\n\t\t\t\t/* Visibility */\n\t\t\t\toState.abVisCols[ iOrigColumn ] = columns[i].bVisible;\n\n\t\t\t\t/* Column reordering */\n\t\t\t\toState.ColReorder.push( iOrigColumn );\n\t\t\t}\n\t\t}\n\t\telse if ( oState.order ) {\n\t\t\t// 1.10.1+\n\t\t\tfor ( i=0 ; i<oState.order.length ; i++ ) {\n\t\t\t\toState.order[i][0] = columns[ oState.order[i][0] ]._ColReorder_iOrigCol;\n\t\t\t}\n\n\t\t\tvar stateColumnsCopy = $.extend( true, [], oState.columns );\n\n\t\t\tfor ( i=0, iLen=columns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tiOrigColumn = columns[i]._ColReorder_iOrigCol;\n\n\t\t\t\t/* Columns */\n\t\t\t\toState.columns[ iOrigColumn ] = stateColumnsCopy[i];\n\n\t\t\t\t/* Column reordering */\n\t\t\t\toState.ColReorder.push( iOrigColumn );\n\t\t\t}\n\t\t}\n\t},\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Mouse drop and drag\n\t */\n\n\t/**\n\t * Add a mouse down listener to a particluar TH element\n\t *  @method  _fnMouseListener\n\t *  @param   int i Column index\n\t *  @param   element nTh TH element clicked on\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnMouseListener\": function ( i, nTh )\n\t{\n\t\tvar that = this;\n\t\t$(nTh).on( 'mousedown.ColReorder', function (e) {\n\t\t\te.preventDefault();\n\t\t\tthat._fnMouseDown.call( that, e, nTh );\n\t\t} );\n\t},\n\n\n\t/**\n\t * Mouse down on a TH element in the table header\n\t *  @method  _fnMouseDown\n\t *  @param   event e Mouse event\n\t *  @param   element nTh TH element to be dragged\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnMouseDown\": function ( e, nTh )\n\t{\n\t\tvar that = this;\n\n\t\t/* Store information about the mouse position */\n\t\tvar target = $(e.target).closest('th, td');\n\t\tvar offset = target.offset();\n\t\tvar idx = parseInt( $(nTh).attr('data-column-index'), 10 );\n\n\t\tif ( idx === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.s.mouse.startX = e.pageX;\n\t\tthis.s.mouse.startY = e.pageY;\n\t\tthis.s.mouse.offsetX = e.pageX - offset.left;\n\t\tthis.s.mouse.offsetY = e.pageY - offset.top;\n\t\tthis.s.mouse.target = this.s.dt.aoColumns[ idx ].nTh;//target[0];\n\t\tthis.s.mouse.targetIndex = idx;\n\t\tthis.s.mouse.fromIndex = idx;\n\n\t\tthis._fnRegions();\n\n\t\t/* Add event handlers to the document */\n\t\t$(document)\n\t\t\t.on( 'mousemove.ColReorder', function (e) {\n\t\t\t\tthat._fnMouseMove.call( that, e );\n\t\t\t} )\n\t\t\t.on( 'mouseup.ColReorder', function (e) {\n\t\t\t\tthat._fnMouseUp.call( that, e );\n\t\t\t} );\n\t},\n\n\n\t/**\n\t * Deal with a mouse move event while dragging a node\n\t *  @method  _fnMouseMove\n\t *  @param   event e Mouse event\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnMouseMove\": function ( e )\n\t{\n\t\tvar that = this;\n\n\t\tif ( this.dom.drag === null )\n\t\t{\n\t\t\t/* Only create the drag element if the mouse has moved a specific distance from the start\n\t\t\t * point - this allows the user to make small mouse movements when sorting and not have a\n\t\t\t * possibly confusing drag element showing up\n\t\t\t */\n\t\t\tif ( Math.pow(\n\t\t\t\tMath.pow(e.pageX - this.s.mouse.startX, 2) +\n\t\t\t\tMath.pow(e.pageY - this.s.mouse.startY, 2), 0.5 ) < 5 )\n\t\t\t{\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis._fnCreateDragNode();\n\t\t}\n\n\t\t/* Position the element - we respect where in the element the click occured */\n\t\tthis.dom.drag.css( {\n\t\t\tleft: e.pageX - this.s.mouse.offsetX,\n\t\t\ttop: e.pageY - this.s.mouse.offsetY\n\t\t} );\n\n\t\t/* Based on the current mouse position, calculate where the insert should go */\n\t\tvar bSet = false;\n\t\tvar lastToIndex = this.s.mouse.toIndex;\n\n\t\tfor ( var i=1, iLen=this.s.aoTargets.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tif ( e.pageX < this.s.aoTargets[i-1].x + ((this.s.aoTargets[i].x-this.s.aoTargets[i-1].x)/2) )\n\t\t\t{\n\t\t\t\tthis.dom.pointer.css( 'left', this.s.aoTargets[i-1].x );\n\t\t\t\tthis.s.mouse.toIndex = this.s.aoTargets[i-1].to;\n\t\t\t\tbSet = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// The insert element wasn't positioned in the array (less than\n\t\t// operator), so we put it at the end\n\t\tif ( !bSet )\n\t\t{\n\t\t\tthis.dom.pointer.css( 'left', this.s.aoTargets[this.s.aoTargets.length-1].x );\n\t\t\tthis.s.mouse.toIndex = this.s.aoTargets[this.s.aoTargets.length-1].to;\n\t\t}\n\n\t\t// Perform reordering if realtime updating is on and the column has moved\n\t\tif ( this.s.init.bRealtime && lastToIndex !== this.s.mouse.toIndex ) {\n\t\t\tthis.s.dt.oInstance.fnColReorder( this.s.mouse.fromIndex, this.s.mouse.toIndex );\n\t\t\tthis.s.mouse.fromIndex = this.s.mouse.toIndex;\n\t\t\tthis._fnRegions();\n\t\t}\n\t},\n\n\n\t/**\n\t * Finish off the mouse drag and insert the column where needed\n\t *  @method  _fnMouseUp\n\t *  @param   event e Mouse event\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnMouseUp\": function ( e )\n\t{\n\t\tvar that = this;\n\n\t\t$(document).off( 'mousemove.ColReorder mouseup.ColReorder' );\n\n\t\tif ( this.dom.drag !== null )\n\t\t{\n\t\t\t/* Remove the guide elements */\n\t\t\tthis.dom.drag.remove();\n\t\t\tthis.dom.pointer.remove();\n\t\t\tthis.dom.drag = null;\n\t\t\tthis.dom.pointer = null;\n\n\t\t\t/* Actually do the reorder */\n\t\t\tthis.s.dt.oInstance.fnColReorder( this.s.mouse.fromIndex, this.s.mouse.toIndex );\n\t\t\tthis._fnSetColumnIndexes();\n\n\t\t\t/* When scrolling we need to recalculate the column sizes to allow for the shift */\n\t\t\tif ( this.s.dt.oScroll.sX !== \"\" || this.s.dt.oScroll.sY !== \"\" )\n\t\t\t{\n\t\t\t\tthis.s.dt.oInstance.fnAdjustColumnSizing( false );\n\t\t\t}\n\n\t\t\t/* Save the state */\n\t\t\tthis.s.dt.oInstance.oApi._fnSaveState( this.s.dt );\n\n\t\t\tif ( this.s.reorderCallback !== null )\n\t\t\t{\n\t\t\t\tthis.s.reorderCallback.call( this );\n\t\t\t}\n\t\t}\n\t},\n\n\n\t/**\n\t * Calculate a cached array with the points of the column inserts, and the\n\t * 'to' points\n\t *  @method  _fnRegions\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnRegions\": function ()\n\t{\n\t\tvar aoColumns = this.s.dt.aoColumns;\n\n\t\tthis.s.aoTargets.splice( 0, this.s.aoTargets.length );\n\n\t\tthis.s.aoTargets.push( {\n\t\t\t\"x\":  $(this.s.dt.nTable).offset().left,\n\t\t\t\"to\": 0\n\t\t} );\n\n\t\tvar iToPoint = 0;\n\t\tfor ( var i=0, iLen=aoColumns.length ; i<iLen ; i++ )\n\t\t{\n\t\t\t/* For the column / header in question, we want it's position to remain the same if the\n\t\t\t * position is just to it's immediate left or right, so we only incremement the counter for\n\t\t\t * other columns\n\t\t\t */\n\t\t\tif ( i != this.s.mouse.fromIndex )\n\t\t\t{\n\t\t\t\tiToPoint++;\n\t\t\t}\n\n\t\t\tif ( aoColumns[i].bVisible )\n\t\t\t{\n\t\t\t\tthis.s.aoTargets.push( {\n\t\t\t\t\t\"x\":  $(aoColumns[i].nTh).offset().left + $(aoColumns[i].nTh).outerWidth(),\n\t\t\t\t\t\"to\": iToPoint\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\n\t\t/* Disallow columns for being reordered by drag and drop, counting right to left */\n\t\tif ( this.s.fixedRight !== 0 )\n\t\t{\n\t\t\tthis.s.aoTargets.splice( this.s.aoTargets.length - this.s.fixedRight );\n\t\t}\n\n\t\t/* Disallow columns for being reordered by drag and drop, counting left to right */\n\t\tif ( this.s.fixed !== 0 )\n\t\t{\n\t\t\tthis.s.aoTargets.splice( 0, this.s.fixed );\n\t\t}\n\t},\n\n\n\t/**\n\t * Copy the TH element that is being drags so the user has the idea that they are actually\n\t * moving it around the page.\n\t *  @method  _fnCreateDragNode\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnCreateDragNode\": function ()\n\t{\n\t\tvar scrolling = this.s.dt.oScroll.sX !== \"\" || this.s.dt.oScroll.sY !== \"\";\n\n\t\tvar origCell = this.s.dt.aoColumns[ this.s.mouse.targetIndex ].nTh;\n\t\tvar origTr = origCell.parentNode;\n\t\tvar origThead = origTr.parentNode;\n\t\tvar origTable = origThead.parentNode;\n\t\tvar cloneCell = $(origCell).clone();\n\n\t\t// This is a slightly odd combination of jQuery and DOM, but it is the\n\t\t// fastest and least resource intensive way I could think of cloning\n\t\t// the table with just a single header cell in it.\n\t\tthis.dom.drag = $(origTable.cloneNode(false))\n\t\t\t.addClass( 'DTCR_clonedTable' )\n\t\t\t.append(\n\t\t\t\t$(origThead.cloneNode(false)).append(\n\t\t\t\t\t$(origTr.cloneNode(false)).append(\n\t\t\t\t\t\tcloneCell[0]\n\t\t\t\t\t)\n\t\t\t\t)\n\t\t\t)\n\t\t\t.css( {\n\t\t\t\tposition: 'absolute',\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\twidth: $(origCell).outerWidth(),\n\t\t\t\theight: $(origCell).outerHeight()\n\t\t\t} )\n\t\t\t.appendTo( 'body' );\n\n\t\tthis.dom.pointer = $('<div></div>')\n\t\t\t.addClass( 'DTCR_pointer' )\n\t\t\t.css( {\n\t\t\t\tposition: 'absolute',\n\t\t\t\ttop: scrolling ?\n\t\t\t\t\t$('div.dataTables_scroll', this.s.dt.nTableWrapper).offset().top :\n\t\t\t\t\t$(this.s.dt.nTable).offset().top,\n\t\t\t\theight : scrolling ?\n\t\t\t\t\t$('div.dataTables_scroll', this.s.dt.nTableWrapper).height() :\n\t\t\t\t\t$(this.s.dt.nTable).height()\n\t\t\t} )\n\t\t\t.appendTo( 'body' );\n\t},\n\n\t/**\n\t * Clean up ColReorder memory references and event handlers\n\t *  @method  _fnDestroy\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnDestroy\": function ()\n\t{\n\t\tvar i, iLen;\n\n\t\tfor ( i=0, iLen=this.s.dt.aoDrawCallback.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tif ( this.s.dt.aoDrawCallback[i].sName === 'ColReorder_Pre' )\n\t\t\t{\n\t\t\t\tthis.s.dt.aoDrawCallback.splice( i, 1 );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t$(this.s.dt.nTHead).find( '*' ).off( '.ColReorder' );\n\n\t\t$.each( this.s.dt.aoColumns, function (i, column) {\n\t\t\t$(column.nTh).removeAttr('data-column-index');\n\t\t} );\n\n\t\tthis.s.dt._colReorder = null;\n\t\tthis.s = null;\n\t},\n\n\n\t/**\n\t * Add a data attribute to the column headers, so we know the index of\n\t * the row to be reordered. This allows fast detection of the index, and\n\t * for this plug-in to work with FixedHeader which clones the nodes.\n\t *  @private\n\t */\n\t\"_fnSetColumnIndexes\": function ()\n\t{\n\t\t$.each( this.s.dt.aoColumns, function (i, column) {\n\t\t\t$(column.nTh).attr('data-column-index', i);\n\t\t} );\n\t}\n};\n\n\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Static parameters\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\n/**\n * ColReorder default settings for initialisation\n *  @namespace\n *  @static\n */\nColReorder.defaults = {\n\t/**\n\t * Predefined ordering for the columns that will be applied automatically\n\t * on initialisation. If not specified then the order that the columns are\n\t * found to be in the HTML is the order used.\n\t *  @type array\n\t *  @default null\n\t *  @static\n\t *  @example\n\t *      // Using the `oColReorder` option in the DataTables options object\n\t *      $('#example').dataTable( {\n\t *          \"sDom\": 'Rlfrtip',\n\t *          \"oColReorder\": {\n\t *              \"aiOrder\": [ 4, 3, 2, 1, 0 ]\n\t *          }\n\t *      } );\n\t *\n\t *  @example\n\t *      // Using `new` constructor\n\t *      $('#example').dataTable()\n\t *\n\t *      new $.fn.dataTable.ColReorder( '#example', {\n\t *          \"aiOrder\": [ 4, 3, 2, 1, 0 ]\n\t *      } );\n\t */\n\taiOrder: null,\n\n\t/**\n\t * Redraw the table's column ordering as the end user draws the column\n\t * (`true`) or wait until the mouse is released (`false` - default). Note\n\t * that this will perform a redraw on each reordering, which involves an\n\t * Ajax request each time if you are using server-side processing in\n\t * DataTables.\n\t *  @type boolean\n\t *  @default false\n\t *  @static\n\t *  @example\n\t *      // Using the `oColReorder` option in the DataTables options object\n\t *      $('#example').dataTable( {\n\t *          \"sDom\": 'Rlfrtip',\n\t *          \"oColReorder\": {\n\t *              \"bRealtime\": true\n\t *          }\n\t *      } );\n\t *\n\t *  @example\n\t *      // Using `new` constructor\n\t *      $('#example').dataTable()\n\t *\n\t *      new $.fn.dataTable.ColReorder( '#example', {\n\t *          \"bRealtime\": true\n\t *      } );\n\t */\n\tbRealtime: false,\n\n\t/**\n\t * Indicate how many columns should be fixed in position (counting from the\n\t * left). This will typically be 1 if used, but can be as high as you like.\n\t *  @type int\n\t *  @default 0\n\t *  @static\n\t *  @example\n\t *      // Using the `oColReorder` option in the DataTables options object\n\t *      $('#example').dataTable( {\n\t *          \"sDom\": 'Rlfrtip',\n\t *          \"oColReorder\": {\n\t *              \"iFixedColumns\": 1\n\t *          }\n\t *      } );\n\t *\n\t *  @example\n\t *      // Using `new` constructor\n\t *      $('#example').dataTable()\n\t *\n\t *      new $.fn.dataTable.ColReorder( '#example', {\n\t *          \"iFixedColumns\": 1\n\t *      } );\n\t */\n\tiFixedColumns: 0,\n\n\t/**\n\t * As `iFixedColumnsRight` but counting from the right.\n\t *  @type int\n\t *  @default 0\n\t *  @static\n\t *  @example\n\t *      // Using the `oColReorder` option in the DataTables options object\n\t *      $('#example').dataTable( {\n\t *          \"sDom\": 'Rlfrtip',\n\t *          \"oColReorder\": {\n\t *              \"iFixedColumnsRight\": 1\n\t *          }\n\t *      } );\n\t *\n\t *  @example\n\t *      // Using `new` constructor\n\t *      $('#example').dataTable()\n\t *\n\t *      new $.fn.dataTable.ColReorder( '#example', {\n\t *          \"iFixedColumnsRight\": 1\n\t *      } );\n\t */\n\tiFixedColumnsRight: 0,\n\n\t/**\n\t * Callback function that is fired when columns are reordered\n\t *  @type function():void\n\t *  @default null\n\t *  @static\n\t *  @example\n\t *      // Using the `oColReorder` option in the DataTables options object\n\t *      $('#example').dataTable( {\n\t *          \"sDom\": 'Rlfrtip',\n\t *          \"oColReorder\": {\n\t *              \"fnReorderCallback\": function () {\n\t *                  alert( 'Columns reordered' );\n\t *              }\n\t *          }\n\t *      } );\n\t *\n\t *  @example\n\t *      // Using `new` constructor\n\t *      $('#example').dataTable()\n\t *\n\t *      new $.fn.dataTable.ColReorder( '#example', {\n\t *          \"fnReorderCallback\": function () {\n\t *              alert( 'Columns reordered' );\n\t *          }\n\t *      } );\n\t */\n\tfnReorderCallback: null\n};\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Constants\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/**\n * ColReorder version\n *  @constant  version\n *  @type      String\n *  @default   As code\n */\nColReorder.version = \"1.1.3\";\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * DataTables interfaces\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n// Expose\n$.fn.dataTable.ColReorder = ColReorder;\n$.fn.DataTable.ColReorder = ColReorder;\n\n\n// Register a new feature with DataTables\nif ( typeof $.fn.dataTable == \"function\" &&\n     typeof $.fn.dataTableExt.fnVersionCheck == \"function\" &&\n     $.fn.dataTableExt.fnVersionCheck('1.9.3') )\n{\n\t$.fn.dataTableExt.aoFeatures.push( {\n\t\t\"fnInit\": function( settings ) {\n\t\t\tvar table = settings.oInstance;\n\n\t\t\tif ( ! settings._colReorder ) {\n\t\t\t\tvar dtInit = settings.oInit;\n\t\t\t\tvar opts = dtInit.colReorder || dtInit.oColReorder || {};\n\n\t\t\t\tnew ColReorder( settings, opts );\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttable.oApi._fnLog( settings, 1, \"ColReorder attempted to initialise twice. Ignoring second\" );\n\t\t\t}\n\n\t\t\treturn null; /* No node for DataTables to insert */\n\t\t},\n\t\t\"cFeature\": \"R\",\n\t\t\"sFeature\": \"ColReorder\"\n\t} );\n}\nelse {\n\talert( \"Warning: ColReorder requires DataTables 1.9.3 or greater - www.datatables.net/download\");\n}\n\n\n// API augmentation\nif ( $.fn.dataTable.Api ) {\n\t$.fn.dataTable.Api.register( 'colReorder.reset()', function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\tctx._colReorder.fnReset();\n\t\t} );\n\t} );\n\n\t$.fn.dataTable.Api.register( 'colReorder.order()', function ( set ) {\n\t\tif ( set ) {\n\t\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\t\tctx._colReorder.fnOrder( set );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.context.length ?\n\t\t\tthis.context[0]._colReorder.fnOrder() :\n\t\t\tnull;\n\t} );\n}\n\nreturn ColReorder;\n}; // /factory\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery && !jQuery.fn.dataTable.ColReorder ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n})(window, document);\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/License.txt",
    "content": "Copyright (c) 2010-2015 SpryMedia Limited\nhttp://datatables.net\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/Readme.md",
    "content": "# ColVis\n\nColVis adds a button to the toolbars around DataTables which gives the end user of the table the ability to dynamically change the visibility of the columns in the table:\n\n* Dynamically show and hide columns in a table\n* Very easy integration with DataTables\n* Ability to exclude columns from being either hidden or shown\n* Save saving integration with DataTables\n\n\n# Installation\n\nTo use ColVis, first download DataTables ( http://datatables.net/download ) and place the unzipped ColVis package into a `extensions` directory in the DataTables package. This will allow the pages in the examples to operate correctly. To see the examples running, open the `examples` directory in your web-browser.\n\n\n# Basic usage\n\nColVis is initialised using the `C` option that it adds to DataTables' `dom` option. For example:\n\n```js\n$(document).ready( function () {\n    $('#example').dataTable( {\n        \"dom\": 'C<\"clear\">lfrtip'\n    } );\n} );\n```\n\n\n# Documentation / support\n\n* Documentation: http://datatables.net/extensions/colvis/\n* DataTables support forums: http://datatables.net/forums\n\n\n# GitHub\n\nIf you fancy getting involved with the development of ColVis and help make it better, please refer to its GitHub repo: https://github.com/DataTables/ColVis\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/css/dataTables.colVis.css",
    "content": "\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * ColVis styles\n */\ndiv.ColVis {\n\tfloat: right;\n\tmargin-bottom: 1em;\n}\n\nbutton.ColVis_Button,\nul.ColVis_collection li {\n\tposition: relative;\n\tfloat: left;\n\tmargin-right: 3px;\n\tpadding: 5px 8px;\n\tborder: 1px solid #999;\n\tcursor: pointer;\n\t*cursor: hand;\n\tfont-size: 0.88em;\n\tcolor: black !important;\n\twhite-space: nowrap;\n\n\t-webkit-border-radius: 2px;\n\t   -moz-border-radius: 2px;\n\t    -ms-border-radius: 2px;\n\t     -o-border-radius: 2px;\n\t        border-radius: 2px;\n\n\t-webkit-box-shadow: 1px 1px 3px #ccc;\n\t   -moz-box-shadow: 1px 1px 3px #ccc;\n\t    -ms-box-shadow: 1px 1px 3px #ccc;\n\t     -o-box-shadow: 1px 1px 3px #ccc;\n\t        box-shadow: 1px 1px 3px #ccc;\n\n\t/* Generated by http://www.colorzilla.com/gradient-editor/ */\n\tbackground: #ffffff; /* Old browsers */\n\tbackground: -webkit-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* Chrome10+,Safari5.1+ */\n\tbackground:    -moz-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* FF3.6+ */\n\tbackground:     -ms-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* IE10+ */\n\tbackground:      -o-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* Opera 11.10+ */\n\tbackground:         linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* W3C */\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#f9f9f9',GradientType=0 ); /* IE6-9 */\n}\n\n.ColVis_Button:hover,\nul.ColVis_collection li:hover {\n\tborder: 1px solid #666;\n\ttext-decoration: none !important;\n\n\t-webkit-box-shadow: 1px 1px 3px #999;\n\t   -moz-box-shadow: 1px 1px 3px #999;\n\t    -ms-box-shadow: 1px 1px 3px #999;\n\t     -o-box-shadow: 1px 1px 3px #999;\n\t        box-shadow: 1px 1px 3px #999;\n\n\tbackground: #f3f3f3; /* Old browsers */\n\tbackground: -webkit-linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* Chrome10+,Safari5.1+ */\n\tbackground:    -moz-linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* FF3.6+ */\n\tbackground:     -ms-linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* IE10+ */\n\tbackground:      -o-linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* Opera 11.10+ */\n\tbackground:         linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* W3C */\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f3f3f3', endColorstr='#f4f4f4',GradientType=0 ); /* IE6-9 */\n}\n\nbutton.ColVis_Button {\n\theight: 30px;\n\tpadding: 3px 8px;\n}\n\nbutton.ColVis_Button::-moz-focus-inner { \n\tborder: none !important;\n\tpadding: 0;\n}\n\nbutton.ColVis_Button:active { \n\toutline: none;\n}\n\n\ndiv.ColVis_collectionBackground {\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\theight: 100%;\n\twidth: 100%;\n\tbackground-color: black;\n\tz-index: 1100;\n}\n\nul.ColVis_collection {\n\tlist-style: none;\n\twidth: 150px;\n\tpadding: 8px 8px 4px 8px;\n\tmargin: 0;\n\tborder: 1px solid #ccc;\n\tborder: 1px solid rgba( 0, 0, 0, 0.4 );\n\tbackground-color: #f3f3f3;\n\tbackground-color: rgba( 255, 255, 255, 0.3 );\n\toverflow: hidden;\n\tz-index: 2002;\n\n\t-webkit-border-radius: 5px;\n\t   -moz-border-radius: 5px;\n\t    -ms-border-radius: 5px;\n\t     -o-border-radius: 5px;\n\t        border-radius: 5px;\n\t\n\t-webkit-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);\n\t   -moz-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);\n\t    -ms-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);\n\t     -o-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);\n\t        box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);\n}\n\nul.ColVis_collection li {\n\tposition: relative;\n\theight: auto;\n\tleft: 0;\n\tright: 0;\n\tpadding: 0.5em;\n\n\tdisplay: block;\n\tfloat: none;\n\tmargin-bottom: 4px;\n\t\n\t-webkit-box-shadow: 1px 1px 3px #999;\n\t   -moz-box-shadow: 1px 1px 3px #999;\n\t    -ms-box-shadow: 1px 1px 3px #999;\n\t     -o-box-shadow: 1px 1px 3px #999;\n\t        box-shadow: 1px 1px 3px #999;\n}\n\nul.ColVis_collection li {\n\ttext-align: left;\n}\n\nul.ColVis_collection li.ColVis_Button:hover {\n\tborder: 1px solid #999;\n\tbackground-color: #f0f0f0;\n}\n\nul.ColVis_collection li span {\n\tdisplay: inline-block;\n\tpadding-left: 0.5em;\n\tcursor: pointer;\n}\n\n\nul.ColVis_collection li.ColVis_Special {\n\tborder-color: #555;\n\tbackground: rgb(237,237,237); /* Old browsers */\n\tbackground: -webkit-linear-gradient(top, rgba(237,237,237,1) 0%,rgba(214,214,214,1) 77%,rgba(232,232,232,1) 100%); /* Chrome10+,Safari5.1+ */\n\tbackground:    -moz-linear-gradient(top, rgba(237,237,237,1) 0%, rgba(214,214,214,1) 77%, rgba(232,232,232,1) 100%); /* FF3.6+ */\n\tbackground:     -ms-linear-gradient(top, rgba(237,237,237,1) 0%,rgba(214,214,214,1) 77%,rgba(232,232,232,1) 100%); /* IE10+ */\n\tbackground:      -o-linear-gradient(top, rgba(237,237,237,1) 0%,rgba(214,214,214,1) 77%,rgba(232,232,232,1) 100%); /* Opera 11.10+ */\n\tbackground:         linear-gradient(to bottom, rgba(237,237,237,1) 0%,rgba(214,214,214,1) 77%,rgba(232,232,232,1) 100%); /* W3C */\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ededed', endColorstr='#e8e8e8',GradientType=0 ); /* IE6-9 */\n}\n\nul.ColVis_collection li.ColVis_Special:hover {\n\tbackground: #e2e2e2; /* Old browsers */\n\tbackground: -webkit-linear-gradient(top, #d0d0d0 0%,#d5d5d5 89%,#e2e2e2 100%); /* Chrome10+,Safari5.1+ */\n\tbackground:    -moz-linear-gradient(top, #d0d0d0 0%,#d5d5d5 89%,#e2e2e2 100%); /* FF3.6+ */\n\tbackground:     -ms-linear-gradient(top, #d0d0d0 0%,#d5d5d5 89%,#e2e2e2 100%); /* IE10+ */\n\tbackground:      -o-linear-gradient(top, #d0d0d0 0%,#d5d5d5 89%,#e2e2e2 100%); /* Opera 11.10+ */\n\tbackground:         linear-gradient(top, #d0d0d0 0%,#d5d5d5 89%,#e2e2e2 100%); /* W3C */\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f3f3f3', endColorstr='#e2e2e2',GradientType=0 ); /* IE6-9 */\n}\n\n\nspan.ColVis_radio {\n\tdisplay: inline-block;\n\twidth: 20px;\n}\n\ndiv.ColVis_catcher {\n\tposition: absolute;\n\tz-index: 1101;\n}\n\n.disabled {\n\tcolor: #999;\n}\n\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/css/dataTables.colvis.jqueryui.css",
    "content": "\nbutton.ColVis_Button,\nul.ColVis_collection li {\n\tpadding: 0.5em;\n}\n\nul.ColVis_collection {\n\tmargin: 0;\n\tpadding: 0;\n\toverflow: hidden;\n\tz-index: 2002;\n}\n\nul.ColVis_collection li {\n\tclear: both;\n\tdisplay: block;\n\ttext-align: left;\n\tmargin: -1px 0 0 0;\n}\n\nul.ColVis_collection li span {\n\tdisplay: inline-block;\n\tpadding-left: 0.5em;\n\tcursor: pointer;\n}\n\ndiv.ColVis_collectionBackground {\n\tposition: fixed;\n\ttop: 0;\n\tleft: 0;\n\theight: 100%;\n\twidth: 100%;\n\tbackground-color: black;\n\tz-index: 1100;\n}\n\n\ndiv.ColVis_catcher {\n\tposition: absolute;\n\tz-index: 1101;\n}"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/examples/button_order.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColVis example - Button ordering</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colVis.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'C<\"clear\">lfrtip',\n\t\tcolVis: {\n\t\t\torder: 'alpha'\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColVis example <span>Button ordering</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>The list of columns that ColVis displays has two options for the order in which they are displayed. The default mode of operation is to show the buttons in the\n\t\t\t\tsame order as they appear in the HTML table, but the second mode of operation is to show the buttons in alphabetical order. This is done by specifying the\n\t\t\t\t<code>order</code> option, set to <code>alpha</code>. Alphabetical button ordering is shown in this example.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'C&lt;&quot;clear&quot;&gt;lfrtip',\n\t\tcolVis: {\n\t\t\torder: 'alpha'\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colVis.js\">../js/dataTables.colVis.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colVis.css\">../css/dataTables.colVis.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">`new` initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./exclude_columns.html\">Exclude columns from list</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./title_callback.html\">Column button callback</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./button_order.html\">Button ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./mouseover.html\">Mouseover activation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./group_columns.html\">Group columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Two tables with individual controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables_identical.html\">Two tables with shared controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./restore.html\">Restore / show all</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/examples/exclude_columns.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColVis example - Exclude columns from list</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colVis.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'C<\"clear\">lfrtip',\n\t\tcolVis: {\n\t\t\texclude: [ 0 ]\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColVis example <span>Exclude columns from list</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>It can at times be useful to exclude columns from being in the 'show / hide' list (for example if you have hidden information that the end user shouldn't be\n\t\t\t\table to make visible. This can be done by the <code>exclude</code> ColVis configuration parameter when creating the DataTable. This is simply an array of integers,\n\t\t\t\tindicating which columns should be excluded. This example shows the first column being excluded.</p>\n\n\t\t\t\t<p>For full information about the ColVis options, please refer to the <a href=\"//datatables.net/extensions/colvis/options\">ColVis options documentation</a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'C&lt;&quot;clear&quot;&gt;lfrtip',\n\t\tcolVis: {\n\t\t\texclude: [ 0 ]\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colVis.js\">../js/dataTables.colVis.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colVis.css\">../css/dataTables.colVis.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">`new` initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./exclude_columns.html\">Exclude columns from list</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./title_callback.html\">Column button callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_order.html\">Button ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./mouseover.html\">Mouseover activation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./group_columns.html\">Group columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Two tables with individual controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables_identical.html\">Two tables with shared controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./restore.html\">Restore / show all</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/examples/group_columns.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColVis example - Group columns</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colVis.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'C<\"clear\">lfrtip',\n\t\tcolVis: {\n\t\t\texclude: [],\n\t\t\tgroups: [\n\t\t\t\t{\n\t\t\t\t\ttitle: \"Engine\",\n\t\t\t\t\tcolumns: [ 0, 3 ]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttitle: \"Client\",\n\t\t\t\t\tcolumns: [ 1, 2 ]\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColVis example <span>Group columns</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>It can be useful at times to show and hide multiple columns together - i.e. grouping them together. Groupings are defined by the <code>groups</code> array.\n\t\t\t\tCreate a group button by naming it (using the <code>title</code> option) and specifying by index which columns belong to it (using the <code>columns</code>\n\t\t\t\toption).</p>\n\n\t\t\t\t<p>Note also that this ability to create groups can be used in combination <code>exclude</code> to remove individual columns from the list (should you wish them to\n\t\t\t\tonly be used in the groups), or set <code>exclude = [ 'all' ]</code> to show only the grouping buttons (i.e. individual column control buttons will not be\n\t\t\t\tshown).</p>\n\n\t\t\t\t<p>For full information about the ColVis options, please refer to the <a href=\"//datatables.net/extensions/colvis/options\">ColVis options documentation</a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'C&lt;&quot;clear&quot;&gt;lfrtip',\n\t\tcolVis: {\n\t\t\texclude: [],\n\t\t\tgroups: [\n\t\t\t\t{\n\t\t\t\t\ttitle: &quot;Engine&quot;,\n\t\t\t\t\tcolumns: [ 0, 3 ]\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\ttitle: &quot;Client&quot;,\n\t\t\t\t\tcolumns: [ 1, 2 ]\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colVis.js\">../js/dataTables.colVis.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colVis.css\">../css/dataTables.colVis.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">`new` initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./exclude_columns.html\">Exclude columns from list</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./title_callback.html\">Column button callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_order.html\">Button ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./mouseover.html\">Mouseover activation</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./group_columns.html\">Group columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Two tables with individual controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables_identical.html\">Two tables with shared controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./restore.html\">Restore / show all</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/examples/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\n\t<title>ColVis examples - ColVis examples</title>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColVis example <span>ColVis examples</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>ColVis adds a button to the toolbars around DataTables which gives the end user of the table the ability to dynamically change the visibility of the columns in\n\t\t\t\tthe table:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li>Dynamically show and hide columns in a table</li>\n\t\t\t\t\t<li>Very easy integration with DataTables</li>\n\t\t\t\t\t<li>Ability to exclude columns from being either hidden or shown</li>\n\t\t\t\t\t<li>Save saving integration with DataTables</li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">`new` initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./exclude_columns.html\">Exclude columns from list</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./title_callback.html\">Column button callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_order.html\">Button ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./mouseover.html\">Mouseover activation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./group_columns.html\">Group columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Two tables with individual controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables_identical.html\">Two tables with shared controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./restore.html\">Restore / show all</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/examples/jqueryui.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColVis example - jQuery UI styling</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../Plugins/integration/jqueryui/dataTables.jqueryui.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colvis.jqueryui.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../Plugins/integration/jqueryui/dataTables.jqueryui.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tjQueryUI: true\n\t} );\n\tvar colvis = new $.fn.dataTable.ColVis( table );\n\n\t$( colvis.button() ).insertBefore('div.dataTables_length');\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColVis example <span>jQuery UI styling</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows how the jQuery UI ThemeRoller option in DataTables can be used with ColVis.</p>\n\n\t\t\t\t<p>The important thing to note here is that it is easier to use <code>new $.fn.dataTable.ColVis()</code> to add ColVis to the table rather than <a href=\n\t\t\t\t\"//datatables.net/reference/option/dom\"><code class=\"option\" title=\"DataTables initialisation option\">dom<span>DT</span></code></a> as the jQuery UI integration\n\t\t\t\tuses a complex expression for <a href=\"//datatables.net/reference/option/dom\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">dom<span>DT</span></code></a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tjQueryUI: true\n\t} );\n\tvar colvis = new $.fn.dataTable.ColVis( table );\n\n\t$( colvis.button() ).insertBefore('div.dataTables_length');\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../Plugins/integration/jqueryui/dataTables.jqueryui.js\">../../Plugins/integration/jqueryui/dataTables.jqueryui.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colVis.js\">../js/dataTables.colVis.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css\">//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../Plugins/integration/jqueryui/dataTables.jqueryui.css\">../../Plugins/integration/jqueryui/dataTables.jqueryui.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colvis.jqueryui.css\">../css/dataTables.colvis.jqueryui.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">`new` initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./exclude_columns.html\">Exclude columns from list</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./title_callback.html\">Column button callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_order.html\">Button ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./mouseover.html\">Mouseover activation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./group_columns.html\">Group columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Two tables with individual controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables_identical.html\">Two tables with shared controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./restore.html\">Restore / show all</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/examples/mouseover.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColVis example - Mouseover activation</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colVis.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'C<\"clear\">lfrtip',\n\t\tcolVis: {\n\t\t\tactivate: \"mouseover\"\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColVis example <span>Mouseover activation</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>The default activation (showing the columns list) for ColVis is for the user to click the button. This can be altered to a <code>mouseover</code> activation by\n\t\t\t\tmaking use of the <code>activate</code> initialisation option and setting it to <code class=\"string\" title=\"String\">mouseover</code>. This is shown in the example\n\t\t\t\tbelow.</p>\n\n\t\t\t\t<p>For full information about the ColVis options, please refer to the <a href=\"//datatables.net/extensions/colvis/options\">ColVis options documentation</a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'C&lt;&quot;clear&quot;&gt;lfrtip',\n\t\tcolVis: {\n\t\t\tactivate: &quot;mouseover&quot;\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colVis.js\">../js/dataTables.colVis.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colVis.css\">../css/dataTables.colVis.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">`new` initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./exclude_columns.html\">Exclude columns from list</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./title_callback.html\">Column button callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_order.html\">Button ordering</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./mouseover.html\">Mouseover activation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./group_columns.html\">Group columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Two tables with individual controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables_identical.html\">Two tables with shared controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./restore.html\">Restore / show all</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/examples/new_init.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColVis example - `new` initialisation</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colVis.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\tvar colvis = new $.fn.dataTable.ColVis( table );\n\n\t$( colvis.button() ).insertAfter('div.info');\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColVis example <span>`new` initialisation</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>As well as providing the option to be initialised through the <code>C</code> option of <a href=\"//datatables.net/reference/option/dom\"><code class=\"option\"\n\t\t\t\ttitle=\"DataTables initialisation option\">dom<span>DT</span></code></a>, ColVis can also be added to a DataTable using direct initialisation - <code>new\n\t\t\t\t$.fn.dataTable.ColVis();</code> as shown in this example. The ColVis control button it available through its <code>button()</code> method, which can then be used\n\t\t\t\tto attach to the document where you need.</p>\n\n\t\t\t\t<p>For full information about the ColVis API, please refer to the <a href=\"//datatables.net/extensions/colvis/api\">ColVis API documentation</a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\tvar colvis = new $.fn.dataTable.ColVis( table );\n\n\t$( colvis.button() ).insertAfter('div.info');\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colVis.js\">../js/dataTables.colVis.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colVis.css\">../css/dataTables.colVis.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./new_init.html\">`new` initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./exclude_columns.html\">Exclude columns from list</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./title_callback.html\">Column button callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_order.html\">Button ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./mouseover.html\">Mouseover activation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./group_columns.html\">Group columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Two tables with individual controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables_identical.html\">Two tables with shared controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./restore.html\">Restore / show all</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/examples/restore.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColVis example - Restore / show all</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colVis.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'C<\"clear\">lfrtip',\n\t\tcolumnDefs: [\n\t\t\t{ visible: false, targets: 2 }\n\t\t],\n\t\tcolVis: {\n\t\t\trestore: \"Restore\",\n\t\t\tshowAll: \"Show all\",\n\t\t\tshowNone: \"Show none\"\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColVis example <span>Restore / show all</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This demo of ColVis shows its ability to add \"Restore\", \"Show all\" and \"Show none\" buttons to the list of column visibility options. This is done with the\n\t\t\t\t<code>restore</code>, <code>showAll</code> and <code>showNone</code> options which can be enabled individually if needed.</p>\n\n\t\t\t\t<p>For full information about the ColVis options, please refer to the <a href=\"//datatables.net/extensions/colvis/options\">ColVis options documentation</a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'C&lt;&quot;clear&quot;&gt;lfrtip',\n\t\tcolumnDefs: [\n\t\t\t{ visible: false, targets: 2 }\n\t\t],\n\t\tcolVis: {\n\t\t\trestore: &quot;Restore&quot;,\n\t\t\tshowAll: &quot;Show all&quot;,\n\t\t\tshowNone: &quot;Show none&quot;\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colVis.js\">../js/dataTables.colVis.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colVis.css\">../css/dataTables.colVis.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">`new` initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./exclude_columns.html\">Exclude columns from list</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./title_callback.html\">Column button callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_order.html\">Button ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./mouseover.html\">Mouseover activation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./group_columns.html\">Group columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Two tables with individual controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables_identical.html\">Two tables with shared controls</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./restore.html\">Restore / show all</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/examples/simple.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColVis example - Basic initialisation</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colVis.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'C<\"clear\">lfrtip'\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColVis example <span>Basic initialisation</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>ColVis is a plug-in for DataTables which presents a list of all columns to a user and allows them to select which ones they wish to be visible. Click the 'Show\n\t\t\t\t/ hide columns' button to be presented with a list of columns in the table, and click the buttons to show and hide them as you wish.</p>\n\n\t\t\t\t<p>ColVis is added to a DataTable by specifying the <code>C</code> option for <a href=\"//datatables.net/reference/option/dom\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">dom<span>DT</span></code></a>. The example below shows the ColVis button added to the table with a clearing element after\n\t\t\t\tit.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'C&lt;&quot;clear&quot;&gt;lfrtip'\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colVis.js\">../js/dataTables.colVis.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colVis.css\">../css/dataTables.colVis.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">`new` initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./exclude_columns.html\">Exclude columns from list</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./title_callback.html\">Column button callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_order.html\">Button ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./mouseover.html\">Mouseover activation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./group_columns.html\">Group columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Two tables with individual controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables_identical.html\">Two tables with shared controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./restore.html\">Restore / show all</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/examples/text.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColVis example - Custom button text</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colVis.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t\"dom\": 'C<\"clear\">lfrtip',\n\t\t\"colVis\": {\n\t\t\t\"buttonText\": \"Change columns\"\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColVis example <span>Custom button text</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>You may wish to use your own text in the ColVis button - this is done by making use of the <code>buttonText</code> initialisation option, as shown in this\n\t\t\t\texample.</p>\n\n\t\t\t\t<p>For full information about the ColVis options, please refer to the <a href=\"//datatables.net/extensions/colvis/options\">ColVis options documentation</a>.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t&quot;dom&quot;: 'C&lt;&quot;clear&quot;&gt;lfrtip',\n\t\t&quot;colVis&quot;: {\n\t\t\t&quot;buttonText&quot;: &quot;Change columns&quot;\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colVis.js\">../js/dataTables.colVis.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colVis.css\">../css/dataTables.colVis.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">`new` initialisation</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./exclude_columns.html\">Exclude columns from list</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./title_callback.html\">Column button callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_order.html\">Button ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./mouseover.html\">Mouseover activation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./group_columns.html\">Group columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Two tables with individual controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables_identical.html\">Two tables with shared controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./restore.html\">Restore / show all</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/examples/title_callback.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColVis example - Column button callback</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colVis.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t\"dom\": 'C<\"clear\">lfrtip',\n\t\t\"colVis\": {\n\t\t\t\"label\": function ( index, title, th ) {\n\t\t\t\treturn (index+1) +'. '+ title;\n\t\t\t}\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColVis example <span>Column button callback</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>By default ColVis will use the information in the <code class=\"tag\" title=\"HTML tag\">th</code> cell for each column as the button name to use in ColVis, which\n\t\t\t\tmight not always be what you want (for example you might has HTML in the cell that you don't want in the button). The <code>label</code> callback provides the\n\t\t\t\tability to customise the label used for the button.</p>\n\n\t\t\t\t<p>In this example the column index is prefixed to the column title.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t&quot;dom&quot;: 'C&lt;&quot;clear&quot;&gt;lfrtip',\n\t\t&quot;colVis&quot;: {\n\t\t\t&quot;label&quot;: function ( index, title, th ) {\n\t\t\t\treturn (index+1) +'. '+ title;\n\t\t\t}\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colVis.js\">../js/dataTables.colVis.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colVis.css\">../css/dataTables.colVis.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">`new` initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./exclude_columns.html\">Exclude columns from list</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./title_callback.html\">Column button callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_order.html\">Button ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./mouseover.html\">Mouseover activation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./group_columns.html\">Group columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Two tables with individual controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables_identical.html\">Two tables with shared controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./restore.html\">Restore / show all</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/examples/two_tables.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColVis example - Two tables with individual controls</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colVis.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('table.display').DataTable( {\n\t\tdom: 'C<\"clear\">lfrtip',\n\t\tdisplayLength: 5\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColVis example <span>Two tables with individual controls</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>It can be useful to have DataTables initialise more than one table with a single call can for them to each have individual ColVis controllers. All this requires\n\t\t\t\tis a suitable jQuery selector to be used, and DataTables and ColVis will take care of the rest - as shown in this example.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<table id=\"\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('table.display').DataTable( {\n\t\tdom: 'C&lt;&quot;clear&quot;&gt;lfrtip',\n\t\tdisplayLength: 5\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colVis.js\">../js/dataTables.colVis.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colVis.css\">../css/dataTables.colVis.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">`new` initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./exclude_columns.html\">Exclude columns from list</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./title_callback.html\">Column button callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_order.html\">Button ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./mouseover.html\">Mouseover activation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./group_columns.html\">Group columns</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./two_tables.html\">Two tables with individual controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables_identical.html\">Two tables with shared controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./restore.html\">Restore / show all</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/examples/two_tables_identical.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>ColVis example - Two tables with shared controls</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.colVis.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar tables = $('table.display').DataTable( {\n\t\tdisplayLength: 5\n\t} );\n\n\t// When the column visibility changes on the firs table, also change it on\n\t// the others\n\ttables.table(0).on('column-visibility', function ( e, settings, colIdx, visibility ) {\n\t\ttables.tables(':gt(0)').column( colIdx ).visible( visibility );\n\t} );\n\n\t// Create ColVis on the first table only\n\tvar colvis = new $.fn.dataTable.ColVis( tables.table(0) );\n\t$( colvis.button() ).insertAfter('div.info');\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>ColVis example <span>Two tables with shared controls</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows how the DataTables API can be used with ColVis to use a single ColVis control to effect other tables. This is done by applying ColVis to the\n\t\t\t\tfirst table and then listening for the <a href=\"//datatables.net/reference/event/column-visibility\"><code class=\"event\" title=\n\t\t\t\t\"DataTables event\">column-visibility<span>DT</span></code></a> event and updating all other tables when triggered.</p>\n\n\t\t\t\t<p>This example makes use of the <a href=\"//datatables.net/reference/api/tables()\"><code class=\"api\" title=\n\t\t\t\t\"DataTables API method\">tables()<span>DT</span></code></a> and <a href=\"//datatables.net/reference/api/table()\"><code class=\"api\" title=\n\t\t\t\t\"DataTables API method\">table()<span>DT</span></code></a> methods for working with multiple tables, and also initialised ColVis using the <code>new\n\t\t\t\t$.fn.dataTable.ColVis();</code> operator.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<table id=\"\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar tables = $('table.display').DataTable( {\n\t\tdisplayLength: 5\n\t} );\n\n\t// When the column visibility changes on the firs table, also change it on\n\t// the others\n\ttables.table(0).on('column-visibility', function ( e, settings, colIdx, visibility ) {\n\t\ttables.tables(':gt(0)').column( colIdx ).visible( visibility );\n\t} );\n\n\t// Create ColVis on the first table only\n\tvar colvis = new $.fn.dataTable.ColVis( tables.table(0) );\n\t$( colvis.button() ).insertAfter('div.info');\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.colVis.js\">../js/dataTables.colVis.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.colVis.css\">../css/dataTables.colVis.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">`new` initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./exclude_columns.html\">Exclude columns from list</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./title_callback.html\">Column button callback</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_order.html\">Button ordering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./mouseover.html\">Mouseover activation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./group_columns.html\">Group columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Two tables with individual controls</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./two_tables_identical.html\">Two tables with shared controls</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./restore.html\">Restore / show all</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/ColVis/js/dataTables.colVis.js",
    "content": "/*! ColVis 1.1.2\n * ©2010-2015 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary     ColVis\n * @description Controls for column visibility in DataTables\n * @version     1.1.2\n * @file        dataTables.colReorder.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2010-2015 SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n *   MIT license - http://datatables.net/license/mit\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n(function(window, document, undefined) {\n\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\n/**\n * ColVis provides column visibility control for DataTables\n *\n * @class ColVis\n * @constructor\n * @param {object} DataTables settings object. With DataTables 1.10 this can\n *   also be and API instance, table node, jQuery collection or jQuery selector.\n * @param {object} ColVis configuration options\n */\nvar ColVis = function( oDTSettings, oInit )\n{\n\t/* Santiy check that we are a new instance */\n\tif ( !this.CLASS || this.CLASS != \"ColVis\" )\n\t{\n\t\talert( \"Warning: ColVis must be initialised with the keyword 'new'\" );\n\t}\n\n\tif ( typeof oInit == 'undefined' )\n\t{\n\t\toInit = {};\n\t}\n\n\tvar camelToHungarian = $.fn.dataTable.camelToHungarian;\n\tif ( camelToHungarian ) {\n\t\tcamelToHungarian( ColVis.defaults, ColVis.defaults, true );\n\t\tcamelToHungarian( ColVis.defaults, oInit );\n\t}\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Public class variables\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * @namespace Settings object which contains customisable information for\n\t *     ColVis instance. Augmented by ColVis.defaults\n\t */\n\tthis.s = {\n\t\t/**\n\t\t * DataTables settings object\n\t\t *  @property dt\n\t\t *  @type     Object\n\t\t *  @default  null\n\t\t */\n\t\t\"dt\": null,\n\n\t\t/**\n\t\t * Customisation object\n\t\t *  @property oInit\n\t\t *  @type     Object\n\t\t *  @default  passed in\n\t\t */\n\t\t\"oInit\": oInit,\n\n\t\t/**\n\t\t * Flag to say if the collection is hidden\n\t\t *  @property hidden\n\t\t *  @type     boolean\n\t\t *  @default  true\n\t\t */\n\t\t\"hidden\": true,\n\n\t\t/**\n\t\t * Store the original visibility settings so they could be restored\n\t\t *  @property abOriginal\n\t\t *  @type     Array\n\t\t *  @default  []\n\t\t */\n\t\t\"abOriginal\": []\n\t};\n\n\n\t/**\n\t * @namespace Common and useful DOM elements for the class instance\n\t */\n\tthis.dom = {\n\t\t/**\n\t\t * Wrapper for the button - given back to DataTables as the node to insert\n\t\t *  @property wrapper\n\t\t *  @type     Node\n\t\t *  @default  null\n\t\t */\n\t\t\"wrapper\": null,\n\n\t\t/**\n\t\t * Activation button\n\t\t *  @property button\n\t\t *  @type     Node\n\t\t *  @default  null\n\t\t */\n\t\t\"button\": null,\n\n\t\t/**\n\t\t * Collection list node\n\t\t *  @property collection\n\t\t *  @type     Node\n\t\t *  @default  null\n\t\t */\n\t\t\"collection\": null,\n\n\t\t/**\n\t\t * Background node used for shading the display and event capturing\n\t\t *  @property background\n\t\t *  @type     Node\n\t\t *  @default  null\n\t\t */\n\t\t\"background\": null,\n\n\t\t/**\n\t\t * Element to position over the activation button to catch mouse events when using mouseover\n\t\t *  @property catcher\n\t\t *  @type     Node\n\t\t *  @default  null\n\t\t */\n\t\t\"catcher\": null,\n\n\t\t/**\n\t\t * List of button elements\n\t\t *  @property buttons\n\t\t *  @type     Array\n\t\t *  @default  []\n\t\t */\n\t\t\"buttons\": [],\n\n\t\t/**\n\t\t * List of group button elements\n\t\t *  @property groupButtons\n\t\t *  @type     Array\n\t\t *  @default  []\n\t\t */\n\t\t\"groupButtons\": [],\n\n\t\t/**\n\t\t * Restore button\n\t\t *  @property restore\n\t\t *  @type     Node\n\t\t *  @default  null\n\t\t */\n\t\t\"restore\": null\n\t};\n\n\t/* Store global reference */\n\tColVis.aInstances.push( this );\n\n\t/* Constructor logic */\n\tthis.s.dt = $.fn.dataTable.Api ?\n\t\tnew $.fn.dataTable.Api( oDTSettings ).settings()[0] :\n\t\toDTSettings;\n\n\tthis._fnConstruct( oInit );\n\treturn this;\n};\n\n\n\nColVis.prototype = {\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Public methods\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * Get the ColVis instance's control button so it can be injected into the\n\t * DOM\n\t *  @method  button\n\t *  @returns {node} ColVis button\n\t */\n\tbutton: function ()\n\t{\n\t\treturn this.dom.wrapper;\n\t},\n\n\t/**\n\t * Alias of `rebuild` for backwards compatibility\n\t *  @method  fnRebuild\n\t */\n\t\"fnRebuild\": function ()\n\t{\n\t\tthis.rebuild();\n\t},\n\n\t/**\n\t * Rebuild the list of buttons for this instance (i.e. if there is a column\n\t * header update)\n\t *  @method  fnRebuild\n\t */\n\trebuild: function ()\n\t{\n\t\t/* Remove the old buttons */\n\t\tfor ( var i=this.dom.buttons.length-1 ; i>=0 ; i-- ) {\n\t\t\tthis.dom.collection.removeChild( this.dom.buttons[i] );\n\t\t}\n\t\tthis.dom.buttons.splice( 0, this.dom.buttons.length );\n\t\tthis.dom.groupButtons.splice(0, this.dom.groupButtons.length);\n\n\t\tif ( this.dom.restore ) {\n\t\t\tthis.dom.restore.parentNode( this.dom.restore );\n\t\t}\n\n\t\t/* Re-add them (this is not the optimal way of doing this, it is fast and effective) */\n\t\tthis._fnAddGroups();\n\t\tthis._fnAddButtons();\n\n\t\t/* Update the checkboxes */\n\t\tthis._fnDrawCallback();\n\t},\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Private methods (they are of course public in JS, but recommended as private)\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * Constructor logic\n\t *  @method  _fnConstruct\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnConstruct\": function ( init )\n\t{\n\t\tthis._fnApplyCustomisation( init );\n\n\t\tvar that = this;\n\t\tvar i, iLen;\n\t\tthis.dom.wrapper = document.createElement('div');\n\t\tthis.dom.wrapper.className = \"ColVis\";\n\n\t\tthis.dom.button = $( '<button />', {\n\t\t\t\t'class': !this.s.dt.bJUI ?\n\t\t\t\t\t\"ColVis_Button ColVis_MasterButton\" :\n\t\t\t\t\t\"ColVis_Button ColVis_MasterButton ui-button ui-state-default\"\n\t\t\t} )\n\t\t\t.append( '<span>'+this.s.buttonText+'</span>' )\n\t\t\t.bind( this.s.activate==\"mouseover\" ? \"mouseover\" : \"click\", function (e) {\n\t\t\t\te.preventDefault();\n\t\t\t\tthat._fnCollectionShow();\n\t\t\t} )\n\t\t\t.appendTo( this.dom.wrapper )[0];\n\n\t\tthis.dom.catcher = this._fnDomCatcher();\n\t\tthis.dom.collection = this._fnDomCollection();\n\t\tthis.dom.background = this._fnDomBackground();\n\n\t\tthis._fnAddGroups();\n\t\tthis._fnAddButtons();\n\n\t\t/* Store the original visibility information */\n\t\tfor ( i=0, iLen=this.s.dt.aoColumns.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tthis.s.abOriginal.push( this.s.dt.aoColumns[i].bVisible );\n\t\t}\n\n\t\t/* Update on each draw */\n\t\tthis.s.dt.aoDrawCallback.push( {\n\t\t\t\"fn\": function () {\n\t\t\t\tthat._fnDrawCallback.call( that );\n\t\t\t},\n\t\t\t\"sName\": \"ColVis\"\n\t\t} );\n\n\t\t/* If columns are reordered, then we need to update our exclude list and\n\t\t * rebuild the displayed list\n\t\t */\n\t\t$(this.s.dt.oInstance).bind( 'column-reorder.dt', function ( e, oSettings, oReorder ) {\n\t\t\tfor ( i=0, iLen=that.s.aiExclude.length ; i<iLen ; i++ ) {\n\t\t\t\tthat.s.aiExclude[i] = oReorder.aiInvertMapping[ that.s.aiExclude[i] ];\n\t\t\t}\n\n\t\t\tvar mStore = that.s.abOriginal.splice( oReorder.iFrom, 1 )[0];\n\t\t\tthat.s.abOriginal.splice( oReorder.iTo, 0, mStore );\n\n\t\t\tthat.fnRebuild();\n\t\t} );\n\n\t\t$(this.s.dt.oInstance).bind( 'destroy.dt', function () {\n\t\t\t$(that.dom.wrapper).remove();\n\t\t} );\n\n\t\t// Set the initial state\n\t\tthis._fnDrawCallback();\n\t},\n\n\n\t/**\n\t * Apply any customisation to the settings from the DataTables initialisation\n\t *  @method  _fnApplyCustomisation\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnApplyCustomisation\": function ( init )\n\t{\n\t\t$.extend( true, this.s, ColVis.defaults, init );\n\n\t\t// Slightly messy overlap for the camelCase notation\n\t\tif ( ! this.s.showAll && this.s.bShowAll ) {\n\t\t\tthis.s.showAll = this.s.sShowAll;\n\t\t}\n\n\t\tif ( ! this.s.restore && this.s.bRestore ) {\n\t\t\tthis.s.restore = this.s.sRestore;\n\t\t}\n\n\t\t// CamelCase to Hungarian for the column groups \n\t\tvar groups = this.s.groups;\n\t\tvar hungarianGroups = this.s.aoGroups;\n\t\tif ( groups ) {\n\t\t\tfor ( var i=0, ien=groups.length ; i<ien ; i++ ) {\n\t\t\t\tif ( groups[i].title ) {\n\t\t\t\t\thungarianGroups[i].sTitle = groups[i].title;\n\t\t\t\t}\n\t\t\t\tif ( groups[i].columns ) {\n\t\t\t\t\thungarianGroups[i].aiColumns = groups[i].columns;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\n\t/**\n\t * On each table draw, check the visibility checkboxes as needed. This allows any process to\n\t * update the table's column visibility and ColVis will still be accurate.\n\t *  @method  _fnDrawCallback\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnDrawCallback\": function ()\n\t{\n\t\tvar columns = this.s.dt.aoColumns;\n\t\tvar buttons = this.dom.buttons;\n\t\tvar groups = this.s.aoGroups;\n\t\tvar button;\n\n\t\tfor ( var i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\tbutton = buttons[i];\n\n\t\t\tif ( button.__columnIdx !== undefined ) {\n\t\t\t\t$('input', button).prop( 'checked', columns[ button.__columnIdx ].bVisible );\n\t\t\t}\n\t\t}\n\n\t\tvar allVisible = function ( columnIndeces ) {\n\t\t\tfor ( var k=0, kLen=columnIndeces.length ; k<kLen ; k++ )\n\t\t\t{\n\t\t\t\tif (  columns[columnIndeces[k]].bVisible === false ) { return false; }\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\t\tvar allHidden = function ( columnIndeces ) {\n\t\t\tfor ( var m=0 , mLen=columnIndeces.length ; m<mLen ; m++ )\n\t\t\t{\n\t\t\t\tif ( columns[columnIndeces[m]].bVisible === true ) { return false; }\n\t\t\t}\n\t\t\treturn true;\n\t\t};\n\n\t\tfor ( var j=0, jLen=groups.length ; j<jLen ; j++ )\n\t\t{\n\t\t\tif ( allVisible(groups[j].aiColumns) )\n\t\t\t{\n\t\t\t\t$('input', this.dom.groupButtons[j]).prop('checked', true);\n\t\t\t\t$('input', this.dom.groupButtons[j]).prop('indeterminate', false);\n\t\t\t}\n\t\t\telse if ( allHidden(groups[j].aiColumns) )\n\t\t\t{\n\t\t\t\t$('input', this.dom.groupButtons[j]).prop('checked', false);\n\t\t\t\t$('input', this.dom.groupButtons[j]).prop('indeterminate', false);\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$('input', this.dom.groupButtons[j]).prop('indeterminate', true);\n\t\t\t}\n\t\t}\n\t},\n\n\n\t/**\n\t * Loop through the groups (provided in the settings) and create a button for each.\n\t *  @method  _fnAddgroups\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnAddGroups\": function ()\n\t{\n\t\tvar nButton;\n\n\t\tif ( typeof this.s.aoGroups != 'undefined' )\n\t\t{\n\t\t\tfor ( var i=0, iLen=this.s.aoGroups.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tnButton = this._fnDomGroupButton( i );\n\t\t\t\tthis.dom.groupButtons.push( nButton );\n\t\t\t\tthis.dom.buttons.push( nButton );\n\t\t\t\tthis.dom.collection.appendChild( nButton );\n\t\t\t}\n\t\t}\n\t},\n\n\n\t/**\n\t * Loop through the columns in the table and as a new button for each one.\n\t *  @method  _fnAddButtons\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnAddButtons\": function ()\n\t{\n\t\tvar\n\t\t\tnButton,\n\t\t\tcolumns = this.s.dt.aoColumns;\n\n\t\tif ( $.inArray( 'all', this.s.aiExclude ) === -1 ) {\n\t\t\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tif ( $.inArray( i, this.s.aiExclude ) === -1 )\n\t\t\t\t{\n\t\t\t\t\tnButton = this._fnDomColumnButton( i );\n\t\t\t\t\tnButton.__columnIdx = i;\n\t\t\t\t\tthis.dom.buttons.push( nButton );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( this.s.order === 'alpha' ) {\n\t\t\tthis.dom.buttons.sort( function ( a, b ) {\n\t\t\t\tvar titleA = columns[ a.__columnIdx ].sTitle;\n\t\t\t\tvar titleB = columns[ b.__columnIdx ].sTitle;\n\n\t\t\t\treturn titleA === titleB ?\n\t\t\t\t\t0 :\n\t\t\t\t\ttitleA < titleB ?\n\t\t\t\t\t\t-1 :\n\t\t\t\t\t\t1;\n\t\t\t} );\n\t\t}\n\n\t\tif ( this.s.restore )\n\t\t{\n\t\t\tnButton = this._fnDomRestoreButton();\n\t\t\tnButton.className += \" ColVis_Restore\";\n\t\t\tthis.dom.buttons.push( nButton );\n\t\t}\n\n\t\tif ( this.s.showAll )\n\t\t{\n\t\t\tnButton = this._fnDomShowXButton( this.s.showAll, true );\n\t\t\tnButton.className += \" ColVis_ShowAll\";\n\t\t\tthis.dom.buttons.push( nButton );\n\t\t}\n\n\t\tif ( this.s.showNone )\n\t\t{\n\t\t\tnButton = this._fnDomShowXButton( this.s.showNone, false );\n\t\t\tnButton.className += \" ColVis_ShowNone\";\n\t\t\tthis.dom.buttons.push( nButton );\n\t\t}\n\n\t\t$(this.dom.collection).append( this.dom.buttons );\n\t},\n\n\n\t/**\n\t * Create a button which allows a \"restore\" action\n\t *  @method  _fnDomRestoreButton\n\t *  @returns {Node} Created button\n\t *  @private\n\t */\n\t\"_fnDomRestoreButton\": function ()\n\t{\n\t\tvar\n\t\t\tthat = this,\n\t\t\tdt = this.s.dt;\n\n\t\treturn $(\n\t\t\t\t'<li class=\"ColVis_Special '+(dt.bJUI ? 'ui-button ui-state-default' : '')+'\">'+\n\t\t\t\t\tthis.s.restore+\n\t\t\t\t'</li>'\n\t\t\t)\n\t\t\t.click( function (e) {\n\t\t\t\tfor ( var i=0, iLen=that.s.abOriginal.length ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\tthat.s.dt.oInstance.fnSetColumnVis( i, that.s.abOriginal[i], false );\n\t\t\t\t}\n\t\t\t\tthat._fnAdjustOpenRows();\n\t\t\t\tthat.s.dt.oInstance.fnAdjustColumnSizing( false );\n\t\t\t\tthat.s.dt.oInstance.fnDraw( false );\n\t\t\t} )[0];\n\t},\n\n\n\t/**\n\t * Create a button which allows show all and show node actions\n\t *  @method  _fnDomShowXButton\n\t *  @returns {Node} Created button\n\t *  @private\n\t */\n\t\"_fnDomShowXButton\": function ( str, action )\n\t{\n\t\tvar\n\t\t\tthat = this,\n\t\t\tdt = this.s.dt;\n\n\t\treturn $(\n\t\t\t\t'<li class=\"ColVis_Special '+(dt.bJUI ? 'ui-button ui-state-default' : '')+'\">'+\n\t\t\t\t\tstr+\n\t\t\t\t'</li>'\n\t\t\t)\n\t\t\t.click( function (e) {\n\t\t\t\tfor ( var i=0, iLen=that.s.abOriginal.length ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\tif (that.s.aiExclude.indexOf(i) === -1)\n\t\t\t\t\t{\n\t\t\t\t\t\tthat.s.dt.oInstance.fnSetColumnVis( i, action, false );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tthat._fnAdjustOpenRows();\n\t\t\t\tthat.s.dt.oInstance.fnAdjustColumnSizing( false );\n\t\t\t\tthat.s.dt.oInstance.fnDraw( false );\n\t\t\t} )[0];\n\t},\n\n\n\t/**\n\t * Create the DOM for a show / hide group button\n\t *  @method  _fnDomGroupButton\n\t *  @param {int} i Group in question, order based on that provided in settings\n\t *  @returns {Node} Created button\n\t *  @private\n\t */\n\t\"_fnDomGroupButton\": function ( i )\n\t{\n\t\tvar\n\t\t\tthat = this,\n\t\t\tdt = this.s.dt,\n\t\t\toGroup = this.s.aoGroups[i];\n\n\t\treturn $(\n\t\t\t\t'<li class=\"ColVis_Special '+(dt.bJUI ? 'ui-button ui-state-default' : '')+'\">'+\n\t\t\t\t\t'<label>'+\n\t\t\t\t\t\t'<input type=\"checkbox\" />'+\n\t\t\t\t\t\t'<span>'+oGroup.sTitle+'</span>'+\n\t\t\t\t\t'</label>'+\n\t\t\t\t'</li>'\n\t\t\t)\n\t\t\t.click( function (e) {\n\t\t\t\tvar showHide = !$('input', this).is(\":checked\");\n\t\t\t\tif (  e.target.nodeName.toLowerCase() !== \"li\" )\n\t\t\t\t{\n\t\t\t\t\tshowHide = ! showHide;\n\t\t\t\t}\n\n\t\t\t\tfor ( var j=0 ; j < oGroup.aiColumns.length ; j++ )\n\t\t\t\t{\n\t\t\t\t\tthat.s.dt.oInstance.fnSetColumnVis( oGroup.aiColumns[j], showHide );\n\t\t\t\t}\n\t\t\t} )[0];\n\t},\n\n\n\t/**\n\t * Create the DOM for a show / hide button\n\t *  @method  _fnDomColumnButton\n\t *  @param {int} i Column in question\n\t *  @returns {Node} Created button\n\t *  @private\n\t */\n\t\"_fnDomColumnButton\": function ( i )\n\t{\n\t\tvar\n\t\t\tthat = this,\n\t\t\tcolumn = this.s.dt.aoColumns[i],\n\t\t\tdt = this.s.dt;\n\n\t\tvar title = this.s.fnLabel===null ?\n\t\t\tcolumn.sTitle :\n\t\t\tthis.s.fnLabel( i, column.sTitle, column.nTh );\n\n\t\treturn $(\n\t\t\t\t'<li '+(dt.bJUI ? 'class=\"ui-button ui-state-default\"' : '')+'>'+\n\t\t\t\t\t'<label>'+\n\t\t\t\t\t\t'<input type=\"checkbox\" />'+\n\t\t\t\t\t\t'<span>'+title+'</span>'+\n\t\t\t\t\t'</label>'+\n\t\t\t\t'</li>'\n\t\t\t)\n\t\t\t.click( function (e) {\n\t\t\t\tvar showHide = !$('input', this).is(\":checked\");\n\t\t\t\tif (  e.target.nodeName.toLowerCase() !== \"li\" )\n\t\t\t\t{\n\t\t\t\t\tif ( e.target.nodeName.toLowerCase() == \"input\" || that.s.fnStateChange === null )\n\t\t\t\t\t{\n\t\t\t\t\t\tshowHide = ! showHide;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t/* Need to consider the case where the initialiser created more than one table - change the\n\t\t\t\t * API index that DataTables is using\n\t\t\t\t */\n\t\t\t\tvar oldIndex = $.fn.dataTableExt.iApiIndex;\n\t\t\t\t$.fn.dataTableExt.iApiIndex = that._fnDataTablesApiIndex.call(that);\n\n\t\t\t\t// Optimisation for server-side processing when scrolling - don't do a full redraw\n\t\t\t\tif ( dt.oFeatures.bServerSide )\n\t\t\t\t{\n\t\t\t\t\tthat.s.dt.oInstance.fnSetColumnVis( i, showHide, false );\n\t\t\t\t\tthat.s.dt.oInstance.fnAdjustColumnSizing( false );\n\t\t\t\t\tif (dt.oScroll.sX !== \"\" || dt.oScroll.sY !== \"\" )\n\t\t\t\t\t{\n\t\t\t\t\t\tthat.s.dt.oInstance.oApi._fnScrollDraw( that.s.dt );\n\t\t\t\t\t}\n\t\t\t\t\tthat._fnDrawCallback();\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tthat.s.dt.oInstance.fnSetColumnVis( i, showHide );\n\t\t\t\t}\n\n\t\t\t\t$.fn.dataTableExt.iApiIndex = oldIndex; /* Restore */\n\n\t\t\t\tif ( that.s.fnStateChange !== null )\n\t\t\t\t{\n\t\t\t\t\tif ( e.target.nodeName.toLowerCase() == \"span\" )\n\t\t\t\t\t{\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tthat.s.fnStateChange.call( that, i, showHide );\n\t\t\t\t}\n\t\t\t} )[0];\n\t},\n\n\n\t/**\n\t * Get the position in the DataTables instance array of the table for this\n\t * instance of ColVis\n\t *  @method  _fnDataTablesApiIndex\n\t *  @returns {int} Index\n\t *  @private\n\t */\n\t\"_fnDataTablesApiIndex\": function ()\n\t{\n\t\tfor ( var i=0, iLen=this.s.dt.oInstance.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tif ( this.s.dt.oInstance[i] == this.s.dt.nTable )\n\t\t\t{\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn 0;\n\t},\n\n\n\t/**\n\t * Create the element used to contain list the columns (it is shown and\n\t * hidden as needed)\n\t *  @method  _fnDomCollection\n\t *  @returns {Node} div container for the collection\n\t *  @private\n\t */\n\t\"_fnDomCollection\": function ()\n\t{\n\t\treturn $('<ul />', {\n\t\t\t\t'class': !this.s.dt.bJUI ?\n\t\t\t\t\t\"ColVis_collection\" :\n\t\t\t\t\t\"ColVis_collection ui-buttonset ui-buttonset-multi\"\n\t\t\t} )\n\t\t.css( {\n\t\t\t'display': 'none',\n\t\t\t'opacity': 0,\n\t\t\t'position': ! this.s.bCssPosition ?\n\t\t\t\t'absolute' :\n\t\t\t\t''\n\t\t} )[0];\n\t},\n\n\n\t/**\n\t * An element to be placed on top of the activate button to catch events\n\t *  @method  _fnDomCatcher\n\t *  @returns {Node} div container for the collection\n\t *  @private\n\t */\n\t\"_fnDomCatcher\": function ()\n\t{\n\t\tvar\n\t\t\tthat = this,\n\t\t\tnCatcher = document.createElement('div');\n\t\tnCatcher.className = \"ColVis_catcher\";\n\n\t\t$(nCatcher).click( function () {\n\t\t\tthat._fnCollectionHide.call( that, null, null );\n\t\t} );\n\n\t\treturn nCatcher;\n\t},\n\n\n\t/**\n\t * Create the element used to shade the background, and capture hide events (it is shown and\n\t * hidden as needed)\n\t *  @method  _fnDomBackground\n\t *  @returns {Node} div container for the background\n\t *  @private\n\t */\n\t\"_fnDomBackground\": function ()\n\t{\n\t\tvar that = this;\n\n\t\tvar background = $('<div></div>')\n\t\t\t.addClass( 'ColVis_collectionBackground' )\n\t\t\t.css( 'opacity', 0 )\n\t\t\t.click( function () {\n\t\t\t\tthat._fnCollectionHide.call( that, null, null );\n\t\t\t} );\n\n\t\t/* When considering a mouse over action for the activation, we also consider a mouse out\n\t\t * which is the same as a mouse over the background - without all the messing around of\n\t\t * bubbling events. Use the catcher element to avoid messing around with bubbling\n\t\t */\n\t\tif ( this.s.activate == \"mouseover\" )\n\t\t{\n\t\t\tbackground.mouseover( function () {\n\t\t\t\tthat.s.overcollection = false;\n\t\t\t\tthat._fnCollectionHide.call( that, null, null );\n\t\t\t} );\n\t\t}\n\n\t\treturn background[0];\n\t},\n\n\n\t/**\n\t * Show the show / hide list and the background\n\t *  @method  _fnCollectionShow\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnCollectionShow\": function ()\n\t{\n\t\tvar that = this, i, iLen, iLeft;\n\t\tvar oPos = $(this.dom.button).offset();\n\t\tvar nHidden = this.dom.collection;\n\t\tvar nBackground = this.dom.background;\n\t\tvar iDivX = parseInt(oPos.left, 10);\n\t\tvar iDivY = parseInt(oPos.top + $(this.dom.button).outerHeight(), 10);\n\n\t\tif ( ! this.s.bCssPosition )\n\t\t{\n\t\t\tnHidden.style.top = iDivY+\"px\";\n\t\t\tnHidden.style.left = iDivX+\"px\";\n\t\t}\n\n\t\t$(nHidden).css( {\n\t\t\t'display': 'block',\n\t\t\t'opacity': 0\n\t\t} );\n\n\t\tnBackground.style.bottom ='0px';\n\t\tnBackground.style.right = '0px';\n\n\t\tvar oStyle = this.dom.catcher.style;\n\t\toStyle.height = $(this.dom.button).outerHeight()+\"px\";\n\t\toStyle.width = $(this.dom.button).outerWidth()+\"px\";\n\t\toStyle.top = oPos.top+\"px\";\n\t\toStyle.left = iDivX+\"px\";\n\n\t\tdocument.body.appendChild( nBackground );\n\t\tdocument.body.appendChild( nHidden );\n\t\tdocument.body.appendChild( this.dom.catcher );\n\n\t\t/* This results in a very small delay for the end user but it allows the animation to be\n\t\t * much smoother. If you don't want the animation, then the setTimeout can be removed\n\t\t */\n\t\t$(nHidden).animate({\"opacity\": 1}, that.s.iOverlayFade);\n\t\t$(nBackground).animate({\"opacity\": 0.1}, that.s.iOverlayFade, 'linear', function () {\n\t\t\t/* In IE6 if you set the checked attribute of a hidden checkbox, then this is not visually\n\t\t\t * reflected. As such, we need to do it here, once it is visible. Unbelievable.\n\t\t\t */\n\t\t\tif ( $.browser && $.browser.msie && $.browser.version == \"6.0\" )\n\t\t\t{\n\t\t\t\tthat._fnDrawCallback();\n\t\t\t}\n\t\t});\n\n\t\t/* Visual corrections to try and keep the collection visible */\n\t\tif ( !this.s.bCssPosition )\n\t\t{\n\t\t\tiLeft = ( this.s.sAlign==\"left\" ) ?\n\t\t\t\tiDivX :\n\t\t\t\tiDivX - $(nHidden).outerWidth() + $(this.dom.button).outerWidth();\n\n\t\t\tnHidden.style.left = iLeft+\"px\";\n\n\t\t\tvar iDivWidth = $(nHidden).outerWidth();\n\t\t\tvar iDivHeight = $(nHidden).outerHeight();\n\t\t\tvar iDocWidth = $(document).width();\n\n\t\t\tif ( iLeft + iDivWidth > iDocWidth )\n\t\t\t{\n\t\t\t\tnHidden.style.left = (iDocWidth-iDivWidth)+\"px\";\n\t\t\t}\n\t\t}\n\n\t\tthis.s.hidden = false;\n\t},\n\n\n\t/**\n\t * Hide the show / hide list and the background\n\t *  @method  _fnCollectionHide\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnCollectionHide\": function (  )\n\t{\n\t\tvar that = this;\n\n\t\tif ( !this.s.hidden && this.dom.collection !== null )\n\t\t{\n\t\t\tthis.s.hidden = true;\n\n\t\t\t$(this.dom.collection).animate({\"opacity\": 0}, that.s.iOverlayFade, function (e) {\n\t\t\t\tthis.style.display = \"none\";\n\t\t\t} );\n\n\t\t\t$(this.dom.background).animate({\"opacity\": 0}, that.s.iOverlayFade, function (e) {\n\t\t\t\tdocument.body.removeChild( that.dom.background );\n\t\t\t\tdocument.body.removeChild( that.dom.catcher );\n\t\t\t} );\n\t\t}\n\t},\n\n\n\t/**\n\t * Alter the colspan on any fnOpen rows\n\t */\n\t\"_fnAdjustOpenRows\": function ()\n\t{\n\t\tvar aoOpen = this.s.dt.aoOpenRows;\n\t\tvar iVisible = this.s.dt.oApi._fnVisbleColumns( this.s.dt );\n\n\t\tfor ( var i=0, iLen=aoOpen.length ; i<iLen ; i++ ) {\n\t\t\taoOpen[i].nTr.getElementsByTagName('td')[0].colSpan = iVisible;\n\t\t}\n\t}\n};\n\n\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Static object methods\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/**\n * Rebuild the collection for a given table, or all tables if no parameter given\n *  @method  ColVis.fnRebuild\n *  @static\n *  @param   object oTable DataTable instance to consider - optional\n *  @returns void\n */\nColVis.fnRebuild = function ( oTable )\n{\n\tvar nTable = null;\n\tif ( typeof oTable != 'undefined' )\n\t{\n\t\tnTable = $.fn.dataTable.Api ?\n\t\t\tnew $.fn.dataTable.Api( oTable ).table().node() :\n\t\t\toTable.fnSettings().nTable;\n\t}\n\n\tfor ( var i=0, iLen=ColVis.aInstances.length ; i<iLen ; i++ )\n\t{\n\t\tif ( typeof oTable == 'undefined' || nTable == ColVis.aInstances[i].s.dt.nTable )\n\t\t{\n\t\t\tColVis.aInstances[i].fnRebuild();\n\t\t}\n\t}\n};\n\n\nColVis.defaults = {\n\t/**\n\t * Mode of activation. Can be 'click' or 'mouseover'\n\t *  @property activate\n\t *  @type     string\n\t *  @default  click\n\t */\n\tactive: 'click',\n\n\t/**\n\t * Text used for the button\n\t *  @property buttonText\n\t *  @type     string\n\t *  @default  Show / hide columns\n\t */\n\tbuttonText: 'Show / hide columns',\n\n\t/**\n\t * List of columns (integers) which should be excluded from the list\n\t *  @property aiExclude\n\t *  @type     array\n\t *  @default  []\n\t */\n\taiExclude: [],\n\n\t/**\n\t * Show restore button\n\t *  @property bRestore\n\t *  @type     boolean\n\t *  @default  false\n\t */\n\tbRestore: false,\n\n\t/**\n\t * Restore button text\n\t *  @property sRestore\n\t *  @type     string\n\t *  @default  Restore original\n\t */\n\tsRestore: 'Restore original',\n\n\t/**\n\t * Show Show-All button\n\t *  @property bShowAll\n\t *  @type     boolean\n\t *  @default  false\n\t */\n\tbShowAll: false,\n\n\t/**\n\t * Show All button text\n\t *  @property sShowAll\n\t *  @type     string\n\t *  @default  Restore original\n\t */\n\tsShowAll: 'Show All',\n\n\t/**\n\t * Position of the collection menu when shown - align \"left\" or \"right\"\n\t *  @property sAlign\n\t *  @type     string\n\t *  @default  left\n\t */\n\tsAlign: 'left',\n\n\t/**\n\t * Callback function to tell the user when the state has changed\n\t *  @property fnStateChange\n\t *  @type     function\n\t *  @default  null\n\t */\n\tfnStateChange: null,\n\n\t/**\n\t * Overlay animation duration in mS\n\t *  @property iOverlayFade\n\t *  @type     integer|false\n\t *  @default  500\n\t */\n\tiOverlayFade: 500,\n\n\t/**\n\t * Label callback for column names. Takes three parameters: 1. the\n\t * column index, 2. the column title detected by DataTables and 3. the\n\t * TH node for the column\n\t *  @property fnLabel\n\t *  @type     function\n\t *  @default  null\n\t */\n\tfnLabel: null,\n\n\t/**\n\t * Indicate if the column list should be positioned by Javascript,\n\t * visually below the button or allow CSS to do the positioning\n\t *  @property bCssPosition\n\t *  @type     boolean\n\t *  @default  false\n\t */\n\tbCssPosition: false,\n\n\t/**\n\t * Group buttons\n\t *  @property aoGroups\n\t *  @type     array\n\t *  @default  []\n\t */\n\taoGroups: [],\n\n\t/**\n\t * Button ordering - 'alpha' (alphabetical) or 'column' (table column\n\t * order)\n\t *  @property order\n\t *  @type     string\n\t *  @default  column\n\t */\n\torder: 'column'\n};\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Static object properties\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/**\n * Collection of all ColVis instances\n *  @property ColVis.aInstances\n *  @static\n *  @type     Array\n *  @default  []\n */\nColVis.aInstances = [];\n\n\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Constants\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/**\n * Name of this class\n *  @constant CLASS\n *  @type     String\n *  @default  ColVis\n */\nColVis.prototype.CLASS = \"ColVis\";\n\n\n/**\n * ColVis version\n *  @constant  VERSION\n *  @type      String\n *  @default   See code\n */\nColVis.VERSION = \"1.1.2\";\nColVis.prototype.VERSION = ColVis.VERSION;\n\n\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Initialisation\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/*\n * Register a new feature with DataTables\n */\nif ( typeof $.fn.dataTable == \"function\" &&\n     typeof $.fn.dataTableExt.fnVersionCheck == \"function\" &&\n     $.fn.dataTableExt.fnVersionCheck('1.7.0') )\n{\n\t$.fn.dataTableExt.aoFeatures.push( {\n\t\t\"fnInit\": function( oDTSettings ) {\n\t\t\tvar init = oDTSettings.oInit;\n\t\t\tvar colvis = new ColVis( oDTSettings, init.colVis || init.oColVis || {} );\n\t\t\treturn colvis.button();\n\t\t},\n\t\t\"cFeature\": \"C\",\n\t\t\"sFeature\": \"ColVis\"\n\t} );\n}\nelse\n{\n\talert( \"Warning: ColVis requires DataTables 1.7 or greater - www.datatables.net/download\");\n}\n\n\n// Make ColVis accessible from the DataTables instance\n$.fn.dataTable.ColVis = ColVis;\n$.fn.DataTable.ColVis = ColVis;\n\n\nreturn ColVis;\n}; // /factory\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery && !jQuery.fn.dataTable.ColVis ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n})(window, document);\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/License.txt",
    "content": "Copyright (c) 2010-2015 SpryMedia Limited\nhttp://datatables.net\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/Readme.md",
    "content": "# FixedColumns\n\nWhen making use of DataTables' x-axis scrolling feature (`scrollX`), you may wish to fix the left or right most columns in place. This plug-in for DataTables provides exactly this option (for non-scrolling tables, please use the FixedHeader plug-in, which can fix headers, footers and columns). Key features include:\n\n* Freezes the left most column to the side of the table\n* Option to freeze two or more columns\n* Full integration with DataTables' scrolling options\n\n\n# Installation\n\nTo use FixedColumns, first download DataTables ( http://datatables.net/download ) and place the unzipped FixedColumns package into a `extensions` directory in the DataTables package. This will allow the pages in the examples to operate correctly. To see the examples running, open the `examples` directory in your web-browser.\n\n\n# Basic usage\n\nFixedColumns is initialised using the `$.fn.dataTable.FixedColumns()` constructor. For example:\n\n```js\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\n\tnew $.fn.dataTable.FixedColumns( table );\n} );\n```\n\n\n# Documentation / support\n\n* Documentation: http://datatables.net/extensions/FixedColumns/\n* DataTables support forums: http://datatables.net/forums\n\n\n# GitHub\n\nIf you fancy getting involved with the development of FixedColumns and help make it better, please refer to its GitHub repo: https://github.com/DataTables/FixedColumns\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/css/dataTables.fixedColumns.css",
    "content": "\n\n/* Block out what is behind the fixed column's header and footer */\ntable.DTFC_Cloned thead,\ntable.DTFC_Cloned tfoot {\n\tbackground-color: white;\n}\n\n/* Block out the gap above the scrollbar on the right, when there is a fixed\n * right column\n */\ndiv.DTFC_Blocker {\n\tbackground-color: white;\n}\n\ndiv.DTFC_LeftWrapper table.dataTable,\ndiv.DTFC_RightWrapper table.dataTable {\n\tmargin-bottom: 0;\n\tz-index: 2;\n}\n\ndiv.DTFC_LeftWrapper table.dataTable.no-footer,\ndiv.DTFC_RightWrapper table.dataTable.no-footer {\n\tborder-bottom: none;\n}\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/bootstrap.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedColumns example - Bootstrap</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../Plugins/integration/bootstrap/3/dataTables.bootstrap.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\tbody { font-size: 140%; }\n\n\t/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../Plugins/integration/bootstrap/3/dataTables.bootstrap.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>Bootstrap</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>When displaying a table which scrolls along the x-axis, it can sometimes be useful to the end user for the left most column to be fixed in place, if it shows\n\t\t\t\tgrouping, index or similar information. This is basically the same idea as 'freeze columns' in Excel. This can be achieved with the FixedColumns plug-in for\n\t\t\t\tDataTables, as shown below.</p>\n\n\t\t\t\t<p>Note that FixedColumns is suitable only for use with the scrolling features in <a href=\"http://datatables.net\">DataTables</a>. If you want to achieve a similar\n\t\t\t\teffect without scrolling enabled, please checkout <a href=\"http://datatables.net/plug-ins\">FixedHeader</a>, also for DataTables.</p>\n\n\t\t\t\t<p>FixedColumns is initialised using the constructor <code>new $.fn.dataTable.FixedColumns();</code> - shown below.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"table table-striped table-bordered\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        &quot;300px&quot;,\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedColumns.js\">../js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../Plugins/integration/bootstrap/3/dataTables.bootstrap.js\">../../Plugins/integration/bootstrap/3/dataTables.bootstrap.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">body { font-size: 140%; }\n\n\t/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css\">//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../Plugins/integration/bootstrap/3/dataTables.bootstrap.css\">../../Plugins/integration/bootstrap/3/dataTables.bootstrap.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/col_filter.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedColumns example - Individual column filtering</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedColumns.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t// Setup - add a text input to each footer cell\n\t$('#example tfoot th').each( function () {\n\t\tvar title = $('#example thead th').eq( $(this).index() ).text();\n\t\t$(this).html( '<input type=\"text\" placeholder=\"Search '+title+'\" />' );\n\t} );\n \n\t// DataTable\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\t \n\t// Apply the filter\n\ttable.columns().indexes().each( function (idx) {\n\t\t$( 'input', table.column( idx ).footer() ).on( 'keyup change', function () {\n\t\t\ttable\n\t\t\t\t.column( idx )\n\t\t\t\t.search( this.value )\n\t\t\t\t.draw();\n\t\t} );\n\t} );\n\n\tnew $.fn.dataTable.FixedColumns( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>Individual column filtering</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows FixedColumns being configured with individual column filtering abilities. Note that the event handler for the filtering is applied to the\n\t\t\t\t<code class=\"tag\" title=\"HTML tag\">input</code> elements before FixedColumns is initialised, so when FixedColumns clones nodes it also copies the event.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"stripe row-border order-column\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t// Setup - add a text input to each footer cell\n\t$('#example tfoot th').each( function () {\n\t\tvar title = $('#example thead th').eq( $(this).index() ).text();\n\t\t$(this).html( '&lt;input type=&quot;text&quot; placeholder=&quot;Search '+title+'&quot; /&gt;' );\n\t} );\n \n\t// DataTable\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        &quot;300px&quot;,\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\t \n\t// Apply the filter\n\ttable.columns().indexes().each( function (idx) {\n\t\t$( 'input', table.column( idx ).footer() ).on( 'keyup change', function () {\n\t\t\ttable\n\t\t\t\t.column( idx )\n\t\t\t\t.search( this.value )\n\t\t\t\t.draw();\n\t\t} );\n\t} );\n\n\tnew $.fn.dataTable.FixedColumns( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedColumns.js\">../js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedColumns.css\">../css/dataTables.fixedColumns.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/colvis.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedColumns example - ColVis integration</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../ColVis/css/dataTables.colVis.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedColumns.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}\n\n\tdiv.ColVis {\n\t\tfloat: left;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../ColVis/js/dataTables.colVis.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tdom:            \"Cfrtip\",\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\n\tnew $.fn.dataTable.FixedColumns( table, {\n\t\tleftColumns: 2\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>ColVis integration</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>FixedColumns operates with DataTables' built-in column visibility options (<a href=\"//datatables.net/reference/option/columns.visible\"><code class=\"option\"\n\t\t\t\ttitle=\"DataTables initialisation option\">columns.visible<span>DT</span></code></a> and <a href=\"//datatables.net/reference/api/column().visible()\"><code class=\n\t\t\t\t\"api\" title=\"DataTables API method\">column().visible()<span>DT</span></code></a>), which columns that are hidden not being shown in the fixed columns. This\n\t\t\t\tintegration also means that FixedColumns works well with <a href=\"http://datatables.net/extensions/colvis\">ColVis</a>, with columns that are dynamically shown and\n\t\t\t\thidden updated immediately in the fixed columns.</p>\n\n\t\t\t\t<p>The example below shows ColVis and FixedColumns working together. Two columns have been fixed on the left hand side of the table to show FixedColumns ability to\n\t\t\t\twork effortlessly with column visibility.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"stripe row-border order-column\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tdom:            &quot;Cfrtip&quot;,\n\t\tscrollY:        &quot;300px&quot;,\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\n\tnew $.fn.dataTable.FixedColumns( table, {\n\t\tleftColumns: 2\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../ColVis/js/dataTables.colVis.js\">../../ColVis/js/dataTables.colVis.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedColumns.js\">../js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}\n\n\tdiv.ColVis {\n\t\tfloat: left;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../ColVis/css/dataTables.colVis.css\">../../ColVis/css/dataTables.colVis.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedColumns.css\">../css/dataTables.fixedColumns.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/css_size.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedColumns example - CSS row sizing</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedColumns.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}\n\n\ttr { height: 50px; }\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\n\tnew $.fn.dataTable.FixedColumns( table, {\n\t\theightMatch: 'none'\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>CSS row sizing</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Because of the method FixedColumns uses to display the fixed columns, an important consideration is the alignment of the rows due to different heights in the\n\t\t\t\tindividual rows of the table. There are two different algorithms in FixedColumns which can be used, or you can switch off automatic row sizing all together. This\n\t\t\t\tis controlled through the <code>heightMatch</code> parameter. If can take the following values:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li><code class=\"string\" title=\"String\">none</code> - no automatic row height matching is performed. CSS can be used in this case and is useful when speed is\n\t\t\t\t\tof primary importance.</li>\n\t\t\t\t\t<li><code class=\"string\" title=\"String\">semiauto</code> (default) - the height calculation will be performed once, and the result cached to be used again\n\t\t\t\t\t(<code>fnRecalculateHeight</code> can be used to force recalculation)</li>\n\t\t\t\t\t<li><code class=\"string\" title=\"String\">auto</code> - height matching is performed on every draw (slowest but must accurate)</li>\n\t\t\t\t</ul>\n\n\t\t\t\t<p>This example shows row height matching switched off but there is a CSS statement of <code>tr { height: 50px }</code> to force all rows to the same height.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"stripe row-border order-column\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        &quot;300px&quot;,\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\n\tnew $.fn.dataTable.FixedColumns( table, {\n\t\theightMatch: 'none'\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedColumns.js\">../js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}\n\n\ttr { height: 50px; }</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedColumns.css\">../css/dataTables.fixedColumns.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\n\t<title>FixedColumns examples - FixedColumns examples</title>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>FixedColumns examples</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>When making use of DataTables' x-axis scrolling feature (<a href=\"//datatables.net/reference/option/scrollX\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">scrollX<span>DT</span></code></a>), you may wish to fix the left or right most columns in place. This extension for DataTables\n\t\t\t\tprovides exactly this option (for non-scrolling tables, please use the <a href=\"//datatables.net/extensions/fixedheader\">FixedHeader extension</a>, which can fix\n\t\t\t\theaders, footers and columns). Key features include:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li>Freezes the left most column to the side of the table</li>\n\t\t\t\t\t<li>Option to freeze two or more columns</li>\n\t\t\t\t\t<li>Full integration with DataTables' scrolling options</li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/index_column.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedColumns example - Index column</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedColumns.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}\n\n\t/* Styling for the index columns */\n\tth.index,\n\ttd.index {\n\t\tbackground-color: white !important;\n\t\tborder-top: 1px solid white !important;\n\t\tborder-bottom: none !important;\n\t}\n\tdiv.DTFC_LeftHeadWrapper table {\n\t\tborder-bottom: 1px solid white !important;\n\t}\n\tdiv.DTFC_LeftHeadWrapper th {\n\t\tborder-bottom: 1px solid white !important;\n\t}\n\tdiv.DTFC_LeftBodyWrapper {\n\t\tborder-right: 1px solid black;\n\t}\n\tdiv.DTFC_LeftFootWrapper th {\n\t\tborder-top: 1px solid white !important;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false,\n\t\tcolumnDefs: [ {\n\t\t\tsortable: false,\n\t\t\t\"class\": \"index\",\n\t\t\ttargets: 0\n\t\t} ],\n\t\torder: [[ 1, 'asc' ]]\n\t} );\n\n\ttable.on( 'order.dt search.dt', function () {\n\t\ttable.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {\n\t\t\tcell.innerHTML = i+1;\n\t\t} );\n\t} ).draw();\n\n\tnew $.fn.dataTable.FixedColumns( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>Index column</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>A typical interaction to want to perform with a fixed column, is an index column. A method for how this can be achieved with FixedColumns is shown in this\n\t\t\t\texample, building on the <a href=\"http://datatables.net/examples/api/counter_column\">index column</a> example for DataTables. Also shown in this example is how the\n\t\t\t\tfixed column can be styled with CSS to show it more prominently.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"stripe row-border order-column\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th></th>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        &quot;300px&quot;,\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false,\n\t\tcolumnDefs: [ {\n\t\t\tsortable: false,\n\t\t\t&quot;class&quot;: &quot;index&quot;,\n\t\t\ttargets: 0\n\t\t} ],\n\t\torder: [[ 1, 'asc' ]]\n\t} );\n\n\ttable.on( 'order.dt search.dt', function () {\n\t\ttable.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {\n\t\t\tcell.innerHTML = i+1;\n\t\t} );\n\t} ).draw();\n\n\tnew $.fn.dataTable.FixedColumns( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedColumns.js\">../js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}\n\n\t/* Styling for the index columns */\n\tth.index,\n\ttd.index {\n\t\tbackground-color: white !important;\n\t\tborder-top: 1px solid white !important;\n\t\tborder-bottom: none !important;\n\t}\n\tdiv.DTFC_LeftHeadWrapper table {\n\t\tborder-bottom: 1px solid white !important;\n\t}\n\tdiv.DTFC_LeftHeadWrapper th {\n\t\tborder-bottom: 1px solid white !important;\n\t}\n\tdiv.DTFC_LeftBodyWrapper {\n\t\tborder-right: 1px solid black;\n\t}\n\tdiv.DTFC_LeftFootWrapper th {\n\t\tborder-top: 1px solid white !important;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedColumns.css\">../css/dataTables.fixedColumns.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/left_right_columns.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedColumns example - Left and right fixed columns</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedColumns.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\n\tnew $.fn.dataTable.FixedColumns( table, {\n\t\tleftColumns: 1,\n\t\trightColumns: 1\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>Left and right fixed columns</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>FixedColumns allows columns to be fixed from both the left and right hand sides of the table. Fixing right hand-side columns is done by using the\n\t\t\t\t<code>rightColumns</code> initialisation parameter, which works just the same as <code>leftColumns</code> does for the left side of the table. This example shows\n\t\t\t\tboth the left and right columns being fixed in place.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"stripe row-border order-column\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        &quot;300px&quot;,\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\n\tnew $.fn.dataTable.FixedColumns( table, {\n\t\tleftColumns: 1,\n\t\trightColumns: 1\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedColumns.js\">../js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedColumns.css\">../css/dataTables.fixedColumns.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/right_column.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedColumns example - Right column only</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedColumns.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\n\tnew $.fn.dataTable.FixedColumns( table, {\n\t\tleftColumns: 0,\n\t\trightColumns: 1\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>Right column only</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>FixedColumns has the ability to freeze columns on both the left and right hand sides of the table. By default it will fix the first column on the left, but\n\t\t\t\tusing the initialisation parameters <code>leftColumns</code> and <code>rightColumns</code> you can alter this to fix the columns on the right as well. This example\n\t\t\t\tshows a single column fixed in place, in this case the right most column.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"stripe row-border order-column\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        &quot;300px&quot;,\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\n\tnew $.fn.dataTable.FixedColumns( table, {\n\t\tleftColumns: 0,\n\t\trightColumns: 1\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedColumns.js\">../js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedColumns.css\">../css/dataTables.fixedColumns.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/rowspan.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedColumns example - Complex headers</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedColumns.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t/* Ensure that the demo table scrolls */\n\tth, td {\n\t\twhite-space: nowrap;\n\t\tpadding-left: 40px !important;\n\t\tpadding-right: 40px !important;\n\t}\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>Complex headers</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>If you are using multiple rows in the table header, it can be useful to have a rowspanning cell on the column(s) you have fixed in place - equally at other\n\t\t\t\ttimes it can be useful to not and make use of the two or more cells per column. FixedColumns builds on the complex header support in DataTables to make this\n\t\t\t\ttrivial to use in FixedColumns. Just initialise your FixedColumns instance as you normally would!</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"stripe row-border order-column\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th rowspan=\"2\">Name</th>\n\t\t\t\t\t\t<th colspan=\"2\">HR Information</th>\n\t\t\t\t\t\t<th colspan=\"3\">Contact</th>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        &quot;300px&quot;,\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedColumns.js\">../js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">/* Ensure that the demo table scrolls */\n\tth, td {\n\t\twhite-space: nowrap;\n\t\tpadding-left: 40px !important;\n\t\tpadding-right: 40px !important;\n\t}\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedColumns.css\">../css/dataTables.fixedColumns.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/server-side-processing.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedColumns example - Server-side processing</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedColumns.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 600px;\n\t\tmargin: 0 auto;\n\t}\n\n\t/* Lots of padding for the cells as SSP has limited data in the demo */\n\tth,\n\ttd {\n\t\tpadding-left: 40px !important;\n\t\tpadding-right: 40px !important;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tajax: \"../../../examples/server_side/scripts/server_processing.php\",\n\t\tserverSide: true\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>Server-side processing</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows how FixedColumns can be used with server-side processing in DataTables to cope with very large tables. No special considerations are\n\t\t\t\trequired, just initialise FixedColumns as you normally would!</p>\n\n\t\t\t\t<p>Note that the table width is constrained in this example to allow scrolling to occur as the server-side processing data set has a limited number of columns in\n\t\t\t\tthis demo!</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"stripe row-border order-column\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        &quot;300px&quot;,\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tajax: &quot;../../../examples/server_side/scripts/server_processing.php&quot;,\n\t\tserverSide: true\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedColumns.js\">../js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 600px;\n\t\tmargin: 0 auto;\n\t}\n\n\t/* Lots of padding for the cells as SSP has limited data in the demo */\n\tth,\n\ttd {\n\t\tpadding-left: 40px !important;\n\t\tpadding-right: 40px !important;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedColumns.css\">../css/dataTables.fixedColumns.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/simple.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedColumns example - Basic initialisation</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedColumns.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>Basic initialisation</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>When displaying a table which scrolls along the x-axis, it can sometimes be useful to the end user for the left most column to be fixed in place, if it shows\n\t\t\t\tgrouping, index or similar information. This is basically the same idea as 'freeze columns' in Excel. This can be achieved with the FixedColumns plug-in for\n\t\t\t\tDataTables, as shown below.</p>\n\n\t\t\t\t<p>Note that FixedColumns is suitable only for use with the scrolling features in <a href=\"http://datatables.net\">DataTables</a>. If you want to achieve a similar\n\t\t\t\teffect without scrolling enabled, please checkout <a href=\"http://datatables.net/plug-ins\">FixedHeader</a>, also for DataTables.</p>\n\n\t\t\t\t<p>FixedColumns is initialised using the constructor <code>new $.fn.dataTable.FixedColumns();</code> - shown below.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"stripe row-border order-column\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        &quot;300px&quot;,\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedColumns.js\">../js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedColumns.css\">../css/dataTables.fixedColumns.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/size_fixed.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedColumns example - Assigned column width</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedColumns.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\tmargin: 0 auto;\n\t}\n\n\tdiv.container {\n\t\twidth: 80%;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').removeAttr('width').DataTable( {\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false,\n\t\tcolumnDefs: [\n\t\t\t{ width: 200, targets: 0 }\n\t\t]\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>Assigned column width</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>The columns that are fixed in place by FixedColumns take their width from the parent DataTable. As such, the width of the column can be controlled using the\n\t\t\t\t<a href=\"//datatables.net/reference/option/columns.width\"><code class=\"option\" title=\"DataTables initialisation option\">columns.width<span>DT</span></code></a>\n\t\t\t\toption.</p>\n\n\t\t\t\t<p>This example shows the first column being set to <code>width: 200px</code> (note that this is not pixel perfect in a table, the browser will make some\n\t\t\t\tadjustments!), a width that is reflected in the fixed column. Resize the browser window horizontally and you will be able to see that the fixed column retains its\n\t\t\t\twidth while the scrolling viewport and the table resize.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"stripe row-border order-column\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').removeAttr('width').DataTable( {\n\t\tscrollY:        &quot;300px&quot;,\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false,\n\t\tcolumnDefs: [\n\t\t\t{ width: 200, targets: 0 }\n\t\t]\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedColumns.js\">../js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\tmargin: 0 auto;\n\t}\n\n\tdiv.container {\n\t\twidth: 80%;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedColumns.css\">../css/dataTables.fixedColumns.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/size_fluid.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedColumns example - Fluid column width</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedColumns.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\tmargin: 0 auto;\n\t}\n\n\tdiv.container {\n\t\twidth: 80%;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false,\n\t\tcolumnDefs: [\n\t\t\t{ width: '20%', targets: 0 }\n\t\t]\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>Fluid column width</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>The columns that are fixed in place by FixedColumns take their width from the parent DataTable. As such, the width of the column can be controlled using the\n\t\t\t\t<a href=\"//datatables.net/reference/option/columns.width\"><code class=\"option\" title=\"DataTables initialisation option\">columns.width<span>DT</span></code></a>\n\t\t\t\toption.</p>\n\n\t\t\t\t<p>This example shows the first column being set to <code>width: 20%</code> (note that this is not pixel perfect in a table, the browser will make some\n\t\t\t\tadjustments!), a width that is reflected in the fixed column. Resize the browser window horizontally and you will be able to see that the fixed column retains its\n\t\t\t\tproportional width (again with a small margin dictated by the browser) in the resizing table.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"stripe row-border order-column\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        &quot;300px&quot;,\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false,\n\t\tcolumnDefs: [\n\t\t\t{ width: '20%', targets: 0 }\n\t\t]\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedColumns.js\">../js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\tmargin: 0 auto;\n\t}\n\n\tdiv.container {\n\t\twidth: 80%;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedColumns.css\">../css/dataTables.fixedColumns.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/examples/two_columns.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedColumns example - Multiple fixed columns</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedColumns.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedColumns.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        \"300px\",\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table, {\n\t\tleftColumns: 2\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedColumns example <span>Multiple fixed columns</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>FixedColumns allows more than one column to be frozen into place using the <code>leftColumns</code> parameter. The example below shows two columns fixed.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"stripe row-border order-column\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY:        &quot;300px&quot;,\n\t\tscrollX:        true,\n\t\tscrollCollapse: true,\n\t\tpaging:         false\n\t} );\n\tnew $.fn.dataTable.FixedColumns( table, {\n\t\tleftColumns: 2\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedColumns.js\">../js/dataTables.fixedColumns.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">/* Ensure that the demo table scrolls */\n\tth, td { white-space: nowrap; }\n\tdiv.dataTables_wrapper {\n\t\twidth: 800px;\n\t\tmargin: 0 auto;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedColumns.css\">../css/dataTables.fixedColumns.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./left_right_columns.html\">Left and right fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./two_columns.html\">Multiple fixed columns</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right_column.html\">Right column only</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./rowspan.html\">Complex headers</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./colvis.html\">ColVis integration</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side-processing.html\">Server-side processing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./css_size.html\">CSS row sizing</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fixed.html\">Assigned column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./size_fluid.html\">Fluid column width</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./col_filter.html\">Individual column filtering</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./index_column.html\">Index column</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedColumns/js/dataTables.fixedColumns.js",
    "content": "/*! FixedColumns 3.0.4\n * ©2010-2014 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary     FixedColumns\n * @description Freeze columns in place on a scrolling DataTable\n * @version     3.0.4\n * @file        dataTables.fixedColumns.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2010-2014 SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n *   MIT license - http://datatables.net/license/mit\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n\n(function(window, document, undefined) {\n\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\n/**\n * When making use of DataTables' x-axis scrolling feature, you may wish to\n * fix the left most column in place. This plug-in for DataTables provides\n * exactly this option (note for non-scrolling tables, please use the\n * FixedHeader plug-in, which can fix headers, footers and columns). Key\n * features include:\n *\n * * Freezes the left or right most columns to the side of the table\n * * Option to freeze two or more columns\n * * Full integration with DataTables' scrolling options\n * * Speed - FixedColumns is fast in its operation\n *\n *  @class\n *  @constructor\n *  @global\n *  @param {object} dt DataTables instance. With DataTables 1.10 this can also\n *    be a jQuery collection, a jQuery selector, DataTables API instance or\n *    settings object.\n *  @param {object} [init={}] Configuration object for FixedColumns. Options are\n *    defined by {@link FixedColumns.defaults}\n *\n *  @requires jQuery 1.7+\n *  @requires DataTables 1.8.0+\n *\n *  @example\n *      var table = $('#example').dataTable( {\n *        \"scrollX\": \"100%\"\n *      } );\n *      new $.fn.dataTable.fixedColumns( table );\n */\nvar FixedColumns = function ( dt, init ) {\n\tvar that = this;\n\n\t/* Sanity check - you just know it will happen */\n\tif ( ! ( this instanceof FixedColumns ) )\n\t{\n\t\talert( \"FixedColumns warning: FixedColumns must be initialised with the 'new' keyword.\" );\n\t\treturn;\n\t}\n\n\tif ( typeof init == 'undefined' )\n\t{\n\t\tinit = {};\n\t}\n\n\t// Use the DataTables Hungarian notation mapping method, if it exists to\n\t// provide forwards compatibility for camel case variables\n\tvar camelToHungarian = $.fn.dataTable.camelToHungarian;\n\tif ( camelToHungarian ) {\n\t\tcamelToHungarian( FixedColumns.defaults, FixedColumns.defaults, true );\n\t\tcamelToHungarian( FixedColumns.defaults, init );\n\t}\n\n\t// v1.10 allows the settings object to be got form a number of sources\n\tvar dtSettings = $.fn.dataTable.Api ?\n\t\tnew $.fn.dataTable.Api( dt ).settings()[0] :\n\t\tdt.fnSettings();\n\n\t/**\n\t * Settings object which contains customisable information for FixedColumns instance\n\t * @namespace\n\t * @extends FixedColumns.defaults\n\t * @private\n\t */\n\tthis.s = {\n\t\t/**\n\t\t * DataTables settings objects\n\t\t *  @type     object\n\t\t *  @default  Obtained from DataTables instance\n\t\t */\n\t\t\"dt\": dtSettings,\n\n\t\t/**\n\t\t * Number of columns in the DataTable - stored for quick access\n\t\t *  @type     int\n\t\t *  @default  Obtained from DataTables instance\n\t\t */\n\t\t\"iTableColumns\": dtSettings.aoColumns.length,\n\n\t\t/**\n\t\t * Original outer widths of the columns as rendered by DataTables - used to calculate\n\t\t * the FixedColumns grid bounding box\n\t\t *  @type     array.<int>\n\t\t *  @default  []\n\t\t */\n\t\t\"aiOuterWidths\": [],\n\n\t\t/**\n\t\t * Original inner widths of the columns as rendered by DataTables - used to apply widths\n\t\t * to the columns\n\t\t *  @type     array.<int>\n\t\t *  @default  []\n\t\t */\n\t\t\"aiInnerWidths\": []\n\t};\n\n\n\t/**\n\t * DOM elements used by the class instance\n\t * @namespace\n\t * @private\n\t *\n\t */\n\tthis.dom = {\n\t\t/**\n\t\t * DataTables scrolling element\n\t\t *  @type     node\n\t\t *  @default  null\n\t\t */\n\t\t\"scroller\": null,\n\n\t\t/**\n\t\t * DataTables header table\n\t\t *  @type     node\n\t\t *  @default  null\n\t\t */\n\t\t\"header\": null,\n\n\t\t/**\n\t\t * DataTables body table\n\t\t *  @type     node\n\t\t *  @default  null\n\t\t */\n\t\t\"body\": null,\n\n\t\t/**\n\t\t * DataTables footer table\n\t\t *  @type     node\n\t\t *  @default  null\n\t\t */\n\t\t\"footer\": null,\n\n\t\t/**\n\t\t * Display grid elements\n\t\t * @namespace\n\t\t */\n\t\t\"grid\": {\n\t\t\t/**\n\t\t\t * Grid wrapper. This is the container element for the 3x3 grid\n\t\t\t *  @type     node\n\t\t\t *  @default  null\n\t\t\t */\n\t\t\t\"wrapper\": null,\n\n\t\t\t/**\n\t\t\t * DataTables scrolling element. This element is the DataTables\n\t\t\t * component in the display grid (making up the main table - i.e.\n\t\t\t * not the fixed columns).\n\t\t\t *  @type     node\n\t\t\t *  @default  null\n\t\t\t */\n\t\t\t\"dt\": null,\n\n\t\t\t/**\n\t\t\t * Left fixed column grid components\n\t\t\t * @namespace\n\t\t\t */\n\t\t\t\"left\": {\n\t\t\t\t\"wrapper\": null,\n\t\t\t\t\"head\": null,\n\t\t\t\t\"body\": null,\n\t\t\t\t\"foot\": null\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Right fixed column grid components\n\t\t\t * @namespace\n\t\t\t */\n\t\t\t\"right\": {\n\t\t\t\t\"wrapper\": null,\n\t\t\t\t\"head\": null,\n\t\t\t\t\"body\": null,\n\t\t\t\t\"foot\": null\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Cloned table nodes\n\t\t * @namespace\n\t\t */\n\t\t\"clone\": {\n\t\t\t/**\n\t\t\t * Left column cloned table nodes\n\t\t\t * @namespace\n\t\t\t */\n\t\t\t\"left\": {\n\t\t\t\t/**\n\t\t\t\t * Cloned header table\n\t\t\t\t *  @type     node\n\t\t\t\t *  @default  null\n\t\t\t\t */\n\t\t\t\t\"header\": null,\n\n\t\t\t\t/**\n\t\t\t\t * Cloned body table\n\t\t\t\t *  @type     node\n\t\t\t\t *  @default  null\n\t\t\t\t */\n\t\t\t\t\"body\": null,\n\n\t\t\t\t/**\n\t\t\t\t * Cloned footer table\n\t\t\t\t *  @type     node\n\t\t\t\t *  @default  null\n\t\t\t\t */\n\t\t\t\t\"footer\": null\n\t\t\t},\n\n\t\t\t/**\n\t\t\t * Right column cloned table nodes\n\t\t\t * @namespace\n\t\t\t */\n\t\t\t\"right\": {\n\t\t\t\t/**\n\t\t\t\t * Cloned header table\n\t\t\t\t *  @type     node\n\t\t\t\t *  @default  null\n\t\t\t\t */\n\t\t\t\t\"header\": null,\n\n\t\t\t\t/**\n\t\t\t\t * Cloned body table\n\t\t\t\t *  @type     node\n\t\t\t\t *  @default  null\n\t\t\t\t */\n\t\t\t\t\"body\": null,\n\n\t\t\t\t/**\n\t\t\t\t * Cloned footer table\n\t\t\t\t *  @type     node\n\t\t\t\t *  @default  null\n\t\t\t\t */\n\t\t\t\t\"footer\": null\n\t\t\t}\n\t\t}\n\t};\n\n\t/* Attach the instance to the DataTables instance so it can be accessed easily */\n\tdtSettings._oFixedColumns = this;\n\n\t/* Let's do it */\n\tif ( ! dtSettings._bInitComplete )\n\t{\n\t\tdtSettings.oApi._fnCallbackReg( dtSettings, 'aoInitComplete', function () {\n\t\t\tthat._fnConstruct( init );\n\t\t}, 'FixedColumns' );\n\t}\n\telse\n\t{\n\t\tthis._fnConstruct( init );\n\t}\n};\n\n\n\nFixedColumns.prototype = /** @lends FixedColumns.prototype */{\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Public methods\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * Update the fixed columns - including headers and footers. Note that FixedColumns will\n\t * automatically update the display whenever the host DataTable redraws.\n\t *  @returns {void}\n\t *  @example\n\t *      var table = $('#example').dataTable( {\n\t *          \"scrollX\": \"100%\"\n\t *      } );\n\t *      var fc = new $.fn.dataTable.fixedColumns( table );\n\t *\n\t *      // at some later point when the table has been manipulated....\n\t *      fc.fnUpdate();\n\t */\n\t\"fnUpdate\": function ()\n\t{\n\t\tthis._fnDraw( true );\n\t},\n\n\n\t/**\n\t * Recalculate the resizes of the 3x3 grid that FixedColumns uses for display of the table.\n\t * This is useful if you update the width of the table container. Note that FixedColumns will\n\t * perform this function automatically when the window.resize event is fired.\n\t *  @returns {void}\n\t *  @example\n\t *      var table = $('#example').dataTable( {\n\t *          \"scrollX\": \"100%\"\n\t *      } );\n\t *      var fc = new $.fn.dataTable.fixedColumns( table );\n\t *\n\t *      // Resize the table container and then have FixedColumns adjust its layout....\n\t *      $('#content').width( 1200 );\n\t *      fc.fnRedrawLayout();\n\t */\n\t\"fnRedrawLayout\": function ()\n\t{\n\t\tthis._fnColCalc();\n\t\tthis._fnGridLayout();\n\t\tthis.fnUpdate();\n\t},\n\n\n\t/**\n\t * Mark a row such that it's height should be recalculated when using 'semiauto' row\n\t * height matching. This function will have no effect when 'none' or 'auto' row height\n\t * matching is used.\n\t *  @param   {Node} nTr TR element that should have it's height recalculated\n\t *  @returns {void}\n\t *  @example\n\t *      var table = $('#example').dataTable( {\n\t *          \"scrollX\": \"100%\"\n\t *      } );\n\t *      var fc = new $.fn.dataTable.fixedColumns( table );\n\t *\n\t *      // manipulate the table - mark the row as needing an update then update the table\n\t *      // this allows the redraw performed by DataTables fnUpdate to recalculate the row\n\t *      // height\n\t *      fc.fnRecalculateHeight();\n\t *      table.fnUpdate( $('#example tbody tr:eq(0)')[0], [\"insert date\", 1, 2, 3 ... ]);\n\t */\n\t\"fnRecalculateHeight\": function ( nTr )\n\t{\n\t\tdelete nTr._DTTC_iHeight;\n\t\tnTr.style.height = 'auto';\n\t},\n\n\n\t/**\n\t * Set the height of a given row - provides cross browser compatibility\n\t *  @param   {Node} nTarget TR element that should have it's height recalculated\n\t *  @param   {int} iHeight Height in pixels to set\n\t *  @returns {void}\n\t *  @example\n\t *      var table = $('#example').dataTable( {\n\t *          \"scrollX\": \"100%\"\n\t *      } );\n\t *      var fc = new $.fn.dataTable.fixedColumns( table );\n\t *\n\t *      // You may want to do this after manipulating a row in the fixed column\n\t *      fc.fnSetRowHeight( $('#example tbody tr:eq(0)')[0], 50 );\n\t */\n\t\"fnSetRowHeight\": function ( nTarget, iHeight )\n\t{\n\t\tnTarget.style.height = iHeight+\"px\";\n\t},\n\n\n\t/**\n\t * Get data index information about a row or cell in the table body.\n\t * This function is functionally identical to fnGetPosition in DataTables,\n\t * taking the same parameter (TH, TD or TR node) and returning exactly the\n\t * the same information (data index information). THe difference between\n\t * the two is that this method takes into account the fixed columns in the\n\t * table, so you can pass in nodes from the master table, or the cloned\n\t * tables and get the index position for the data in the main table.\n\t *  @param {node} node TR, TH or TD element to get the information about\n\t *  @returns {int} If nNode is given as a TR, then a single index is \n\t *    returned, or if given as a cell, an array of [row index, column index\n\t *    (visible), column index (all)] is given.\n\t */\n\t\"fnGetPosition\": function ( node )\n\t{\n\t\tvar idx;\n\t\tvar inst = this.s.dt.oInstance;\n\n\t\tif ( ! $(node).parents('.DTFC_Cloned').length )\n\t\t{\n\t\t\t// Not in a cloned table\n\t\t\treturn inst.fnGetPosition( node );\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Its in the cloned table, so need to look up position\n\t\t\tif ( node.nodeName.toLowerCase() === 'tr' ) {\n\t\t\t\tidx = $(node).index();\n\t\t\t\treturn inst.fnGetPosition( $('tr', this.s.dt.nTBody)[ idx ] );\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tvar colIdx = $(node).index();\n\t\t\t\tidx = $(node.parentNode).index();\n\t\t\t\tvar row = inst.fnGetPosition( $('tr', this.s.dt.nTBody)[ idx ] );\n\n\t\t\t\treturn [\n\t\t\t\t\trow,\n\t\t\t\t\tcolIdx,\n\t\t\t\t\tinst.oApi._fnVisibleToColumnIndex( this.s.dt, colIdx )\n\t\t\t\t];\n\t\t\t}\n\t\t}\n\t},\n\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Private methods (they are of course public in JS, but recommended as private)\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * Initialisation for FixedColumns\n\t *  @param   {Object} oInit User settings for initialisation\n\t *  @returns {void}\n\t *  @private\n\t */\n\t\"_fnConstruct\": function ( oInit )\n\t{\n\t\tvar i, iLen, iWidth,\n\t\t\tthat = this;\n\n\t\t/* Sanity checking */\n\t\tif ( typeof this.s.dt.oInstance.fnVersionCheck != 'function' ||\n\t\t     this.s.dt.oInstance.fnVersionCheck( '1.8.0' ) !== true )\n\t\t{\n\t\t\talert( \"FixedColumns \"+FixedColumns.VERSION+\" required DataTables 1.8.0 or later. \"+\n\t\t\t\t\"Please upgrade your DataTables installation\" );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.s.dt.oScroll.sX === \"\" )\n\t\t{\n\t\t\tthis.s.dt.oInstance.oApi._fnLog( this.s.dt, 1, \"FixedColumns is not needed (no \"+\n\t\t\t\t\"x-scrolling in DataTables enabled), so no action will be taken. Use 'FixedHeader' for \"+\n\t\t\t\t\"column fixing when scrolling is not enabled\" );\n\t\t\treturn;\n\t\t}\n\n\t\t/* Apply the settings from the user / defaults */\n\t\tthis.s = $.extend( true, this.s, FixedColumns.defaults, oInit );\n\n\t\t/* Set up the DOM as we need it and cache nodes */\n\t\tvar classes = this.s.dt.oClasses;\n\t\tthis.dom.grid.dt = $(this.s.dt.nTable).parents('div.'+classes.sScrollWrapper)[0];\n\t\tthis.dom.scroller = $('div.'+classes.sScrollBody, this.dom.grid.dt )[0];\n\n\t\t/* Set up the DOM that we want for the fixed column layout grid */\n\t\tthis._fnColCalc();\n\t\tthis._fnGridSetup();\n\n\t\t/* Event handlers */\n\t\tvar mouseController;\n\n\t\t// When the body is scrolled - scroll the left and right columns\n\t\t$(this.dom.scroller)\n\t\t\t.on( 'mouseover.DTFC touchstart.DTFC', function () {\n\t\t\t\tmouseController = 'main';\n\t\t\t} )\n\t\t\t.on( 'scroll.DTFC', function () {\n\t\t\t\tif ( mouseController === 'main' ) {\n\t\t\t\t\tif ( that.s.iLeftColumns > 0 ) {\n\t\t\t\t\t\tthat.dom.grid.left.liner.scrollTop = that.dom.scroller.scrollTop;\n\t\t\t\t\t}\n\t\t\t\t\tif ( that.s.iRightColumns > 0 ) {\n\t\t\t\t\t\tthat.dom.grid.right.liner.scrollTop = that.dom.scroller.scrollTop;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\n\t\tvar wheelType = 'onwheel' in document.createElement('div') ?\n\t\t\t'wheel.DTFC' :\n\t\t\t'mousewheel.DTFC';\n\n\t\tif ( that.s.iLeftColumns > 0 ) {\n\t\t\t// When scrolling the left column, scroll the body and right column\n\t\t\t$(that.dom.grid.left.liner)\n\t\t\t\t.on( 'mouseover.DTFC touchstart.DTFC', function () {\n\t\t\t\t\tmouseController = 'left';\n\t\t\t\t} )\n\t\t\t\t.on( 'scroll.DTFC', function () {\n\t\t\t\t\tif ( mouseController === 'left' ) {\n\t\t\t\t\t\tthat.dom.scroller.scrollTop = that.dom.grid.left.liner.scrollTop;\n\t\t\t\t\t\tif ( that.s.iRightColumns > 0 ) {\n\t\t\t\t\t\t\tthat.dom.grid.right.liner.scrollTop = that.dom.grid.left.liner.scrollTop;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t\t.on( wheelType, function(e) { // xxx update the destroy as well\n\t\t\t\t\t// Pass horizontal scrolling through\n\t\t\t\t\tvar xDelta = e.type === 'wheel' ?\n\t\t\t\t\t\t-e.originalEvent.deltaX :\n\t\t\t\t\t\te.originalEvent.wheelDeltaX;\n\t\t\t\t\tthat.dom.scroller.scrollLeft -= xDelta;\n\t\t\t\t} );\n\t\t}\n\n\t\tif ( that.s.iRightColumns > 0 ) {\n\t\t\t// When scrolling the right column, scroll the body and the left column\n\t\t\t$(that.dom.grid.right.liner)\n\t\t\t\t.on( 'mouseover.DTFC touchstart.DTFC', function () {\n\t\t\t\t\tmouseController = 'right';\n\t\t\t\t} )\n\t\t\t\t.on( 'scroll.DTFC', function () {\n\t\t\t\t\tif ( mouseController === 'right' ) {\n\t\t\t\t\t\tthat.dom.scroller.scrollTop = that.dom.grid.right.liner.scrollTop;\n\t\t\t\t\t\tif ( that.s.iLeftColumns > 0 ) {\n\t\t\t\t\t\t\tthat.dom.grid.left.liner.scrollTop = that.dom.grid.right.liner.scrollTop;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t\t.on( wheelType, function(e) {\n\t\t\t\t\t// Pass horizontal scrolling through\n\t\t\t\t\tvar xDelta = e.type === 'wheel' ?\n\t\t\t\t\t\t-e.originalEvent.deltaX :\n\t\t\t\t\t\te.originalEvent.wheelDeltaX;\n\t\t\t\t\tthat.dom.scroller.scrollLeft -= xDelta;\n\t\t\t\t} );\n\t\t}\n\n\t\t$(window).on( 'resize.DTFC', function () {\n\t\t\tthat._fnGridLayout.call( that );\n\t\t} );\n\n\t\tvar bFirstDraw = true;\n\t\tvar jqTable = $(this.s.dt.nTable);\n\n\t\tjqTable\n\t\t\t.on( 'draw.dt.DTFC', function () {\n\t\t\t\tthat._fnDraw.call( that, bFirstDraw );\n\t\t\t\tbFirstDraw = false;\n\t\t\t} )\n\t\t\t.on( 'column-sizing.dt.DTFC', function () {\n\t\t\t\tthat._fnColCalc();\n\t\t\t\tthat._fnGridLayout( that );\n\t\t\t} )\n\t\t\t.on( 'column-visibility.dt.DTFC', function () {\n\t\t\t\tthat._fnColCalc();\n\t\t\t\tthat._fnGridLayout( that );\n\t\t\t\tthat._fnDraw( true );\n\t\t\t} )\n\t\t\t.on( 'destroy.dt.DTFC', function () {\n\t\t\t\tjqTable.off( 'column-sizing.dt.DTFC destroy.dt.DTFC draw.dt.DTFC' );\n\n\t\t\t\t$(that.dom.scroller).off( 'scroll.DTFC mouseover.DTFC' );\n\t\t\t\t$(window).off( 'resize.DTFC' );\n\n\t\t\t\t$(that.dom.grid.left.liner).off( 'scroll.DTFC mouseover.DTFC '+wheelType );\n\t\t\t\t$(that.dom.grid.left.wrapper).remove();\n\n\t\t\t\t$(that.dom.grid.right.liner).off( 'scroll.DTFC mouseover.DTFC '+wheelType );\n\t\t\t\t$(that.dom.grid.right.wrapper).remove();\n\t\t\t} );\n\n\t\t/* Get things right to start with - note that due to adjusting the columns, there must be\n\t\t * another redraw of the main table. It doesn't need to be a full redraw however.\n\t\t */\n\t\tthis._fnGridLayout();\n\t\tthis.s.dt.oInstance.fnDraw(false);\n\t},\n\n\n\t/**\n\t * Calculate the column widths for the grid layout\n\t *  @returns {void}\n\t *  @private\n\t */\n\t\"_fnColCalc\": function ()\n\t{\n\t\tvar that = this;\n\t\tvar iLeftWidth = 0;\n\t\tvar iRightWidth = 0;\n\n\t\tthis.s.aiInnerWidths = [];\n\t\tthis.s.aiOuterWidths = [];\n\n\t\t$.each( this.s.dt.aoColumns, function (i, col) {\n\t\t\tvar th = $(col.nTh);\n\t\t\tvar border;\n\n\t\t\tif ( ! th.filter(':visible').length ) {\n\t\t\t\tthat.s.aiInnerWidths.push( 0 );\n\t\t\t\tthat.s.aiOuterWidths.push( 0 );\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t// Inner width is used to assign widths to cells\n\t\t\t\t// Outer width is used to calculate the container\n\t\t\t\tvar iWidth = th.outerWidth();\n\n\t\t\t\t// When working with the left most-cell, need to add on the\n\t\t\t\t// table's border to the outerWidth, since we need to take\n\t\t\t\t// account of it, but it isn't in any cell\n\t\t\t\tif ( that.s.aiOuterWidths.length === 0 ) {\n\t\t\t\t\tborder = $(that.s.dt.nTable).css('border-left-width');\n\t\t\t\t\tiWidth += typeof border === 'string' ? 1 : parseInt( border, 10 );\n\t\t\t\t}\n\n\t\t\t\t// Likewise with the final column on the right\n\t\t\t\tif ( that.s.aiOuterWidths.length === that.s.dt.aoColumns.length-1 ) {\n\t\t\t\t\tborder = $(that.s.dt.nTable).css('border-right-width');\n\t\t\t\t\tiWidth += typeof border === 'string' ? 1 : parseInt( border, 10 );\n\t\t\t\t}\n\n\t\t\t\tthat.s.aiOuterWidths.push( iWidth );\n\t\t\t\tthat.s.aiInnerWidths.push( th.width() );\n\n\t\t\t\tif ( i < that.s.iLeftColumns )\n\t\t\t\t{\n\t\t\t\t\tiLeftWidth += iWidth;\n\t\t\t\t}\n\n\t\t\t\tif ( that.s.iTableColumns-that.s.iRightColumns <= i )\n\t\t\t\t{\n\t\t\t\t\tiRightWidth += iWidth;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\n\t\tthis.s.iLeftWidth = iLeftWidth;\n\t\tthis.s.iRightWidth = iRightWidth;\n\t},\n\n\n\t/**\n\t * Set up the DOM for the fixed column. The way the layout works is to create a 1x3 grid\n\t * for the left column, the DataTable (for which we just reuse the scrolling element DataTable\n\t * puts into the DOM) and the right column. In each of he two fixed column elements there is a\n\t * grouping wrapper element and then a head, body and footer wrapper. In each of these we then\n\t * place the cloned header, body or footer tables. This effectively gives as 3x3 grid structure.\n\t *  @returns {void}\n\t *  @private\n\t */\n\t\"_fnGridSetup\": function ()\n\t{\n\t\tvar that = this;\n\t\tvar oOverflow = this._fnDTOverflow();\n\t\tvar block;\n\n\t\tthis.dom.body = this.s.dt.nTable;\n\t\tthis.dom.header = this.s.dt.nTHead.parentNode;\n\t\tthis.dom.header.parentNode.parentNode.style.position = \"relative\";\n\n\t\tvar nSWrapper =\n\t\t\t$('<div class=\"DTFC_ScrollWrapper\" style=\"position:relative; clear:both;\">'+\n\t\t\t\t'<div class=\"DTFC_LeftWrapper\" style=\"position:absolute; top:0; left:0;\">'+\n\t\t\t\t\t'<div class=\"DTFC_LeftHeadWrapper\" style=\"position:relative; top:0; left:0; overflow:hidden;\"></div>'+\n\t\t\t\t\t'<div class=\"DTFC_LeftBodyWrapper\" style=\"position:relative; top:0; left:0; overflow:hidden;\">'+\n\t\t\t\t\t\t'<div class=\"DTFC_LeftBodyLiner\" style=\"position:relative; top:0; left:0; overflow-y:scroll;\"></div>'+\n\t\t\t\t\t'</div>'+\n\t\t\t\t\t'<div class=\"DTFC_LeftFootWrapper\" style=\"position:relative; top:0; left:0; overflow:hidden;\"></div>'+\n\t\t\t\t'</div>'+\n\t\t\t\t'<div class=\"DTFC_RightWrapper\" style=\"position:absolute; top:0; left:0;\">'+\n\t\t\t\t\t'<div class=\"DTFC_RightHeadWrapper\" style=\"position:relative; top:0; left:0;\">'+\n\t\t\t\t\t\t'<div class=\"DTFC_RightHeadBlocker DTFC_Blocker\" style=\"position:absolute; top:0; bottom:0;\"></div>'+\n\t\t\t\t\t'</div>'+\n\t\t\t\t\t'<div class=\"DTFC_RightBodyWrapper\" style=\"position:relative; top:0; left:0; overflow:hidden;\">'+\n\t\t\t\t\t\t'<div class=\"DTFC_RightBodyLiner\" style=\"position:relative; top:0; left:0; overflow-y:scroll;\"></div>'+\n\t\t\t\t\t'</div>'+\n\t\t\t\t\t'<div class=\"DTFC_RightFootWrapper\" style=\"position:relative; top:0; left:0;\">'+\n\t\t\t\t\t\t'<div class=\"DTFC_RightFootBlocker DTFC_Blocker\" style=\"position:absolute; top:0; bottom:0;\"></div>'+\n\t\t\t\t\t'</div>'+\n\t\t\t\t'</div>'+\n\t\t\t'</div>')[0];\n\t\tvar nLeft = nSWrapper.childNodes[0];\n\t\tvar nRight = nSWrapper.childNodes[1];\n\n\t\tthis.dom.grid.dt.parentNode.insertBefore( nSWrapper, this.dom.grid.dt );\n\t\tnSWrapper.appendChild( this.dom.grid.dt );\n\n\t\tthis.dom.grid.wrapper = nSWrapper;\n\n\t\tif ( this.s.iLeftColumns > 0 )\n\t\t{\n\t\t\tthis.dom.grid.left.wrapper = nLeft;\n\t\t\tthis.dom.grid.left.head = nLeft.childNodes[0];\n\t\t\tthis.dom.grid.left.body = nLeft.childNodes[1];\n\t\t\tthis.dom.grid.left.liner = $('div.DTFC_LeftBodyLiner', nSWrapper)[0];\n\n\t\t\tnSWrapper.appendChild( nLeft );\n\t\t}\n\n\t\tif ( this.s.iRightColumns > 0 )\n\t\t{\n\t\t\tthis.dom.grid.right.wrapper = nRight;\n\t\t\tthis.dom.grid.right.head = nRight.childNodes[0];\n\t\t\tthis.dom.grid.right.body = nRight.childNodes[1];\n\t\t\tthis.dom.grid.right.liner = $('div.DTFC_RightBodyLiner', nSWrapper)[0];\n\n\t\t\tblock = $('div.DTFC_RightHeadBlocker', nSWrapper)[0];\n\t\t\tblock.style.width = oOverflow.bar+\"px\";\n\t\t\tblock.style.right = -oOverflow.bar+\"px\";\n\t\t\tthis.dom.grid.right.headBlock = block;\n\n\t\t\tblock = $('div.DTFC_RightFootBlocker', nSWrapper)[0];\n\t\t\tblock.style.width = oOverflow.bar+\"px\";\n\t\t\tblock.style.right = -oOverflow.bar+\"px\";\n\t\t\tthis.dom.grid.right.footBlock = block;\n\n\t\t\tnSWrapper.appendChild( nRight );\n\t\t}\n\n\t\tif ( this.s.dt.nTFoot )\n\t\t{\n\t\t\tthis.dom.footer = this.s.dt.nTFoot.parentNode;\n\t\t\tif ( this.s.iLeftColumns > 0 )\n\t\t\t{\n\t\t\t\tthis.dom.grid.left.foot = nLeft.childNodes[2];\n\t\t\t}\n\t\t\tif ( this.s.iRightColumns > 0 )\n\t\t\t{\n\t\t\t\tthis.dom.grid.right.foot = nRight.childNodes[2];\n\t\t\t}\n\t\t}\n\t},\n\n\n\t/**\n\t * Style and position the grid used for the FixedColumns layout\n\t *  @returns {void}\n\t *  @private\n\t */\n\t\"_fnGridLayout\": function ()\n\t{\n\t\tvar oGrid = this.dom.grid;\n\t\tvar iWidth = $(oGrid.wrapper).width();\n\t\tvar iBodyHeight = $(this.s.dt.nTable.parentNode).outerHeight();\n\t\tvar iFullHeight = $(this.s.dt.nTable.parentNode.parentNode).outerHeight();\n\t\tvar oOverflow = this._fnDTOverflow();\n\t\tvar\n\t\t\tiLeftWidth = this.s.iLeftWidth,\n\t\t\tiRightWidth = this.s.iRightWidth,\n\t\t\tiRight;\n\t\tvar scrollbarAdjust = function ( node, width ) {\n\t\t\tif ( ! oOverflow.bar ) {\n\t\t\t\t// If there is no scrollbar (Macs) we need to hide the auto scrollbar\n\t\t\t\tnode.style.width = (width+20)+\"px\";\n\t\t\t\tnode.style.paddingRight = \"20px\";\n\t\t\t\tnode.style.boxSizing = \"border-box\";\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Otherwise just overflow by the scrollbar\n\t\t\t\tnode.style.width = (width+oOverflow.bar)+\"px\";\n\t\t\t}\n\t\t};\n\n\t\t// When x scrolling - don't paint the fixed columns over the x scrollbar\n\t\tif ( oOverflow.x )\n\t\t{\n\t\t\tiBodyHeight -= oOverflow.bar;\n\t\t}\n\n\t\toGrid.wrapper.style.height = iFullHeight+\"px\";\n\n\t\tif ( this.s.iLeftColumns > 0 )\n\t\t{\n\t\t\toGrid.left.wrapper.style.width = iLeftWidth+\"px\";\n\t\t\toGrid.left.wrapper.style.height = \"1px\";\n\t\t\toGrid.left.body.style.height = iBodyHeight+\"px\";\n\t\t\tif ( oGrid.left.foot ) {\n\t\t\t\toGrid.left.foot.style.top = (oOverflow.x ? oOverflow.bar : 0)+\"px\"; // shift footer for scrollbar\n\t\t\t}\n\n\t\t\tscrollbarAdjust( oGrid.left.liner, iLeftWidth );\n\t\t\toGrid.left.liner.style.height = iBodyHeight+\"px\";\n\t\t}\n\n\t\tif ( this.s.iRightColumns > 0 )\n\t\t{\n\t\t\tiRight = iWidth - iRightWidth;\n\t\t\tif ( oOverflow.y )\n\t\t\t{\n\t\t\t\tiRight -= oOverflow.bar;\n\t\t\t}\n\n\t\t\toGrid.right.wrapper.style.width = iRightWidth+\"px\";\n\t\t\toGrid.right.wrapper.style.left = iRight+\"px\";\n\t\t\toGrid.right.wrapper.style.height = \"1px\";\n\t\t\toGrid.right.body.style.height = iBodyHeight+\"px\";\n\t\t\tif ( oGrid.right.foot ) {\n\t\t\t\toGrid.right.foot.style.top = (oOverflow.x ? oOverflow.bar : 0)+\"px\";\n\t\t\t}\n\n\t\t\tscrollbarAdjust( oGrid.right.liner, iRightWidth );\n\t\t\toGrid.right.liner.style.height = iBodyHeight+\"px\";\n\n\t\t\toGrid.right.headBlock.style.display = oOverflow.y ? 'block' : 'none';\n\t\t\toGrid.right.footBlock.style.display = oOverflow.y ? 'block' : 'none';\n\t\t}\n\t},\n\n\n\t/**\n\t * Get information about the DataTable's scrolling state - specifically if the table is scrolling\n\t * on either the x or y axis, and also the scrollbar width.\n\t *  @returns {object} Information about the DataTables scrolling state with the properties:\n\t *    'x', 'y' and 'bar'\n\t *  @private\n\t */\n\t\"_fnDTOverflow\": function ()\n\t{\n\t\tvar nTable = this.s.dt.nTable;\n\t\tvar nTableScrollBody = nTable.parentNode;\n\t\tvar out = {\n\t\t\t\"x\": false,\n\t\t\t\"y\": false,\n\t\t\t\"bar\": this.s.dt.oScroll.iBarWidth\n\t\t};\n\n\t\tif ( nTable.offsetWidth > nTableScrollBody.clientWidth )\n\t\t{\n\t\t\tout.x = true;\n\t\t}\n\n\t\tif ( nTable.offsetHeight > nTableScrollBody.clientHeight )\n\t\t{\n\t\t\tout.y = true;\n\t\t}\n\n\t\treturn out;\n\t},\n\n\n\t/**\n\t * Clone and position the fixed columns\n\t *  @returns {void}\n\t *  @param   {Boolean} bAll Indicate if the header and footer should be updated as well (true)\n\t *  @private\n\t */\n\t\"_fnDraw\": function ( bAll )\n\t{\n\t\tthis._fnGridLayout();\n\t\tthis._fnCloneLeft( bAll );\n\t\tthis._fnCloneRight( bAll );\n\n\t\t/* Draw callback function */\n\t\tif ( this.s.fnDrawCallback !== null )\n\t\t{\n\t\t\tthis.s.fnDrawCallback.call( this, this.dom.clone.left, this.dom.clone.right );\n\t\t}\n\n\t\t/* Event triggering */\n\t\t$(this).trigger( 'draw.dtfc', {\n\t\t\t\"leftClone\": this.dom.clone.left,\n\t\t\t\"rightClone\": this.dom.clone.right\n\t\t} );\n\t},\n\n\n\t/**\n\t * Clone the right columns\n\t *  @returns {void}\n\t *  @param   {Boolean} bAll Indicate if the header and footer should be updated as well (true)\n\t *  @private\n\t */\n\t\"_fnCloneRight\": function ( bAll )\n\t{\n\t\tif ( this.s.iRightColumns <= 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar that = this,\n\t\t\ti, jq,\n\t\t\taiColumns = [];\n\n\t\tfor ( i=this.s.iTableColumns-this.s.iRightColumns ; i<this.s.iTableColumns ; i++ ) {\n\t\t\tif ( this.s.dt.aoColumns[i].bVisible ) {\n\t\t\t\taiColumns.push( i );\n\t\t\t}\n\t\t}\n\n\t\tthis._fnClone( this.dom.clone.right, this.dom.grid.right, aiColumns, bAll );\n\t},\n\n\n\t/**\n\t * Clone the left columns\n\t *  @returns {void}\n\t *  @param   {Boolean} bAll Indicate if the header and footer should be updated as well (true)\n\t *  @private\n\t */\n\t\"_fnCloneLeft\": function ( bAll )\n\t{\n\t\tif ( this.s.iLeftColumns <= 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar that = this,\n\t\t\ti, jq,\n\t\t\taiColumns = [];\n\n\t\tfor ( i=0 ; i<this.s.iLeftColumns ; i++ ) {\n\t\t\tif ( this.s.dt.aoColumns[i].bVisible ) {\n\t\t\t\taiColumns.push( i );\n\t\t\t}\n\t\t}\n\n\t\tthis._fnClone( this.dom.clone.left, this.dom.grid.left, aiColumns, bAll );\n\t},\n\n\n\t/**\n\t * Make a copy of the layout object for a header or footer element from DataTables. Note that\n\t * this method will clone the nodes in the layout object.\n\t *  @returns {Array} Copy of the layout array\n\t *  @param   {Object} aoOriginal Layout array from DataTables (aoHeader or aoFooter)\n\t *  @param   {Object} aiColumns Columns to copy\n\t *  @private\n\t */\n\t\"_fnCopyLayout\": function ( aoOriginal, aiColumns )\n\t{\n\t\tvar aReturn = [];\n\t\tvar aClones = [];\n\t\tvar aCloned = [];\n\n\t\tfor ( var i=0, iLen=aoOriginal.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tvar aRow = [];\n\t\t\taRow.nTr = $(aoOriginal[i].nTr).clone(true, true)[0];\n\n\t\t\tfor ( var j=0, jLen=this.s.iTableColumns ; j<jLen ; j++ )\n\t\t\t{\n\t\t\t\tif ( $.inArray( j, aiColumns ) === -1 )\n\t\t\t\t{\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tvar iCloned = $.inArray( aoOriginal[i][j].cell, aCloned );\n\t\t\t\tif ( iCloned === -1 )\n\t\t\t\t{\n\t\t\t\t\tvar nClone = $(aoOriginal[i][j].cell).clone(true, true)[0];\n\t\t\t\t\taClones.push( nClone );\n\t\t\t\t\taCloned.push( aoOriginal[i][j].cell );\n\n\t\t\t\t\taRow.push( {\n\t\t\t\t\t\t\"cell\": nClone,\n\t\t\t\t\t\t\"unique\": aoOriginal[i][j].unique\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\taRow.push( {\n\t\t\t\t\t\t\"cell\": aClones[ iCloned ],\n\t\t\t\t\t\t\"unique\": aoOriginal[i][j].unique\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\taReturn.push( aRow );\n\t\t}\n\n\t\treturn aReturn;\n\t},\n\n\n\t/**\n\t * Clone the DataTable nodes and place them in the DOM (sized correctly)\n\t *  @returns {void}\n\t *  @param   {Object} oClone Object containing the header, footer and body cloned DOM elements\n\t *  @param   {Object} oGrid Grid object containing the display grid elements for the cloned\n\t *                    column (left or right)\n\t *  @param   {Array} aiColumns Column indexes which should be operated on from the DataTable\n\t *  @param   {Boolean} bAll Indicate if the header and footer should be updated as well (true)\n\t *  @private\n\t */\n\t\"_fnClone\": function ( oClone, oGrid, aiColumns, bAll )\n\t{\n\t\tvar that = this,\n\t\t\ti, iLen, j, jLen, jq, nTarget, iColumn, nClone, iIndex, aoCloneLayout,\n\t\t\tjqCloneThead, aoFixedHeader,\n\t\t\tdt = this.s.dt;\n\n\t\t/*\n\t\t * Header\n\t\t */\n\t\tif ( bAll )\n\t\t{\n\t\t\tif ( oClone.header !== null )\n\t\t\t{\n\t\t\t\toClone.header.parentNode.removeChild( oClone.header );\n\t\t\t}\n\t\t\toClone.header = $(this.dom.header).clone(true, true)[0];\n\t\t\toClone.header.className += \" DTFC_Cloned\";\n\t\t\toClone.header.style.width = \"100%\";\n\t\t\toGrid.head.appendChild( oClone.header );\n\n\t\t\t/* Copy the DataTables layout cache for the header for our floating column */\n\t\t\taoCloneLayout = this._fnCopyLayout( dt.aoHeader, aiColumns );\n\t\t\tjqCloneThead = $('>thead', oClone.header);\n\t\t\tjqCloneThead.empty();\n\n\t\t\t/* Add the created cloned TR elements to the table */\n\t\t\tfor ( i=0, iLen=aoCloneLayout.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tjqCloneThead[0].appendChild( aoCloneLayout[i].nTr );\n\t\t\t}\n\n\t\t\t/* Use the handy _fnDrawHead function in DataTables to do the rowspan/colspan\n\t\t\t * calculations for us\n\t\t\t */\n\t\t\tdt.oApi._fnDrawHead( dt, aoCloneLayout, true );\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* To ensure that we copy cell classes exactly, regardless of colspan, multiple rows\n\t\t\t * etc, we make a copy of the header from the DataTable again, but don't insert the\n\t\t\t * cloned cells, just copy the classes across. To get the matching layout for the\n\t\t\t * fixed component, we use the DataTables _fnDetectHeader method, allowing 1:1 mapping\n\t\t\t */\n\t\t\taoCloneLayout = this._fnCopyLayout( dt.aoHeader, aiColumns );\n\t\t\taoFixedHeader=[];\n\n\t\t\tdt.oApi._fnDetectHeader( aoFixedHeader, $('>thead', oClone.header)[0] );\n\n\t\t\tfor ( i=0, iLen=aoCloneLayout.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tfor ( j=0, jLen=aoCloneLayout[i].length ; j<jLen ; j++ )\n\t\t\t\t{\n\t\t\t\t\taoFixedHeader[i][j].cell.className = aoCloneLayout[i][j].cell.className;\n\n\t\t\t\t\t// If jQuery UI theming is used we need to copy those elements as well\n\t\t\t\t\t$('span.DataTables_sort_icon', aoFixedHeader[i][j].cell).each( function () {\n\t\t\t\t\t\tthis.className = $('span.DataTables_sort_icon', aoCloneLayout[i][j].cell)[0].className;\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis._fnEqualiseHeights( 'thead', this.dom.header, oClone.header );\n\n\t\t/*\n\t\t * Body\n\t\t */\n\t\tif ( this.s.sHeightMatch == 'auto' )\n\t\t{\n\t\t\t/* Remove any heights which have been applied already and let the browser figure it out */\n\t\t\t$('>tbody>tr', that.dom.body).css('height', 'auto');\n\t\t}\n\n\t\tif ( oClone.body !== null )\n\t\t{\n\t\t\toClone.body.parentNode.removeChild( oClone.body );\n\t\t\toClone.body = null;\n\t\t}\n\n\t\toClone.body = $(this.dom.body).clone(true)[0];\n\t\toClone.body.className += \" DTFC_Cloned\";\n\t\toClone.body.style.paddingBottom = dt.oScroll.iBarWidth+\"px\";\n\t\toClone.body.style.marginBottom = (dt.oScroll.iBarWidth*2)+\"px\"; /* For IE */\n\t\tif ( oClone.body.getAttribute('id') !== null )\n\t\t{\n\t\t\toClone.body.removeAttribute('id');\n\t\t}\n\n\t\t$('>thead>tr', oClone.body).empty();\n\t\t$('>tfoot', oClone.body).remove();\n\n\t\tvar nBody = $('tbody', oClone.body)[0];\n\t\t$(nBody).empty();\n\t\tif ( dt.aiDisplay.length > 0 )\n\t\t{\n\t\t\t/* Copy the DataTables' header elements to force the column width in exactly the\n\t\t\t * same way that DataTables does it - have the header element, apply the width and\n\t\t\t * colapse it down\n\t\t\t */\n\t\t\tvar nInnerThead = $('>thead>tr', oClone.body)[0];\n\t\t\tfor ( iIndex=0 ; iIndex<aiColumns.length ; iIndex++ )\n\t\t\t{\n\t\t\t\tiColumn = aiColumns[iIndex];\n\n\t\t\t\tnClone = $(dt.aoColumns[iColumn].nTh).clone(true)[0];\n\t\t\t\tnClone.innerHTML = \"\";\n\n\t\t\t\tvar oStyle = nClone.style;\n\t\t\t\toStyle.paddingTop = \"0\";\n\t\t\t\toStyle.paddingBottom = \"0\";\n\t\t\t\toStyle.borderTopWidth = \"0\";\n\t\t\t\toStyle.borderBottomWidth = \"0\";\n\t\t\t\toStyle.height = 0;\n\t\t\t\toStyle.width = that.s.aiInnerWidths[iColumn]+\"px\";\n\n\t\t\t\tnInnerThead.appendChild( nClone );\n\t\t\t}\n\n\t\t\t/* Add in the tbody elements, cloning form the master table */\n\t\t\t$('>tbody>tr', that.dom.body).each( function (z) {\n\t\t\t\tvar n = this.cloneNode(false);\n\t\t\t\tn.removeAttribute('id');\n\t\t\t\tvar i = that.s.dt.oFeatures.bServerSide===false ?\n\t\t\t\t\tthat.s.dt.aiDisplay[ that.s.dt._iDisplayStart+z ] : z;\n\t\t\t\tvar aTds = that.s.dt.aoData[ i ].anCells || $(this).children('td, th');\n\n\t\t\t\tfor ( iIndex=0 ; iIndex<aiColumns.length ; iIndex++ )\n\t\t\t\t{\n\t\t\t\t\tiColumn = aiColumns[iIndex];\n\n\t\t\t\t\tif ( aTds.length > 0 )\n\t\t\t\t\t{\n\t\t\t\t\t\tnClone = $( aTds[iColumn] ).clone(true, true)[0];\n\t\t\t\t\t\tn.appendChild( nClone );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnBody.appendChild( n );\n\t\t\t} );\n\t\t}\n\t\telse\n\t\t{\n\t\t\t$('>tbody>tr', that.dom.body).each( function (z) {\n\t\t\t\tnClone = this.cloneNode(true);\n\t\t\t\tnClone.className += ' DTFC_NoData';\n\t\t\t\t$('td', nClone).html('');\n\t\t\t\tnBody.appendChild( nClone );\n\t\t\t} );\n\t\t}\n\n\t\toClone.body.style.width = \"100%\";\n\t\toClone.body.style.margin = \"0\";\n\t\toClone.body.style.padding = \"0\";\n\n\t\t// Interop with Scroller - need to use a height forcing element in the\n\t\t// scrolling area in the same way that Scroller does in the body scroll.\n\t\tif ( dt.oScroller !== undefined )\n\t\t{\n\t\t\tvar scrollerForcer = dt.oScroller.dom.force;\n\n\t\t\tif ( ! oGrid.forcer ) {\n\t\t\t\toGrid.forcer = scrollerForcer.cloneNode( true );\n\t\t\t\toGrid.liner.appendChild( oGrid.forcer );\n\t\t\t}\n\t\t\telse {\n\t\t\t\toGrid.forcer.style.height = scrollerForcer.style.height;\n\t\t\t}\n\t\t}\n\n\t\toGrid.liner.appendChild( oClone.body );\n\n\t\tthis._fnEqualiseHeights( 'tbody', that.dom.body, oClone.body );\n\n\t\t/*\n\t\t * Footer\n\t\t */\n\t\tif ( dt.nTFoot !== null )\n\t\t{\n\t\t\tif ( bAll )\n\t\t\t{\n\t\t\t\tif ( oClone.footer !== null )\n\t\t\t\t{\n\t\t\t\t\toClone.footer.parentNode.removeChild( oClone.footer );\n\t\t\t\t}\n\t\t\t\toClone.footer = $(this.dom.footer).clone(true, true)[0];\n\t\t\t\toClone.footer.className += \" DTFC_Cloned\";\n\t\t\t\toClone.footer.style.width = \"100%\";\n\t\t\t\toGrid.foot.appendChild( oClone.footer );\n\n\t\t\t\t/* Copy the footer just like we do for the header */\n\t\t\t\taoCloneLayout = this._fnCopyLayout( dt.aoFooter, aiColumns );\n\t\t\t\tvar jqCloneTfoot = $('>tfoot', oClone.footer);\n\t\t\t\tjqCloneTfoot.empty();\n\n\t\t\t\tfor ( i=0, iLen=aoCloneLayout.length ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\tjqCloneTfoot[0].appendChild( aoCloneLayout[i].nTr );\n\t\t\t\t}\n\t\t\t\tdt.oApi._fnDrawHead( dt, aoCloneLayout, true );\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\taoCloneLayout = this._fnCopyLayout( dt.aoFooter, aiColumns );\n\t\t\t\tvar aoCurrFooter=[];\n\n\t\t\t\tdt.oApi._fnDetectHeader( aoCurrFooter, $('>tfoot', oClone.footer)[0] );\n\n\t\t\t\tfor ( i=0, iLen=aoCloneLayout.length ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\tfor ( j=0, jLen=aoCloneLayout[i].length ; j<jLen ; j++ )\n\t\t\t\t\t{\n\t\t\t\t\t\taoCurrFooter[i][j].cell.className = aoCloneLayout[i][j].cell.className;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._fnEqualiseHeights( 'tfoot', this.dom.footer, oClone.footer );\n\t\t}\n\n\t\t/* Equalise the column widths between the header footer and body - body get's priority */\n\t\tvar anUnique = dt.oApi._fnGetUniqueThs( dt, $('>thead', oClone.header)[0] );\n\t\t$(anUnique).each( function (i) {\n\t\t\tiColumn = aiColumns[i];\n\t\t\tthis.style.width = that.s.aiInnerWidths[iColumn]+\"px\";\n\t\t} );\n\n\t\tif ( that.s.dt.nTFoot !== null )\n\t\t{\n\t\t\tanUnique = dt.oApi._fnGetUniqueThs( dt, $('>tfoot', oClone.footer)[0] );\n\t\t\t$(anUnique).each( function (i) {\n\t\t\t\tiColumn = aiColumns[i];\n\t\t\t\tthis.style.width = that.s.aiInnerWidths[iColumn]+\"px\";\n\t\t\t} );\n\t\t}\n\t},\n\n\n\t/**\n\t * From a given table node (THEAD etc), get a list of TR direct child elements\n\t *  @param   {Node} nIn Table element to search for TR elements (THEAD, TBODY or TFOOT element)\n\t *  @returns {Array} List of TR elements found\n\t *  @private\n\t */\n\t\"_fnGetTrNodes\": function ( nIn )\n\t{\n\t\tvar aOut = [];\n\t\tfor ( var i=0, iLen=nIn.childNodes.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tif ( nIn.childNodes[i].nodeName.toUpperCase() == \"TR\" )\n\t\t\t{\n\t\t\t\taOut.push( nIn.childNodes[i] );\n\t\t\t}\n\t\t}\n\t\treturn aOut;\n\t},\n\n\n\t/**\n\t * Equalise the heights of the rows in a given table node in a cross browser way\n\t *  @returns {void}\n\t *  @param   {String} nodeName Node type - thead, tbody or tfoot\n\t *  @param   {Node} original Original node to take the heights from\n\t *  @param   {Node} clone Copy the heights to\n\t *  @private\n\t */\n\t\"_fnEqualiseHeights\": function ( nodeName, original, clone )\n\t{\n\t\tif ( this.s.sHeightMatch == 'none' && nodeName !== 'thead' && nodeName !== 'tfoot' )\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\tvar that = this,\n\t\t\ti, iLen, iHeight, iHeight2, iHeightOriginal, iHeightClone,\n\t\t\trootOriginal = original.getElementsByTagName(nodeName)[0],\n\t\t\trootClone    = clone.getElementsByTagName(nodeName)[0],\n\t\t\tjqBoxHack    = $('>'+nodeName+'>tr:eq(0)', original).children(':first'),\n\t\t\tiBoxHack     = jqBoxHack.outerHeight() - jqBoxHack.height(),\n\t\t\tanOriginal   = this._fnGetTrNodes( rootOriginal ),\n\t\t\tanClone      = this._fnGetTrNodes( rootClone ),\n\t\t\theights      = [];\n\n\t\tfor ( i=0, iLen=anClone.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tiHeightOriginal = anOriginal[i].offsetHeight;\n\t\t\tiHeightClone = anClone[i].offsetHeight;\n\t\t\tiHeight = iHeightClone > iHeightOriginal ? iHeightClone : iHeightOriginal;\n\n\t\t\tif ( this.s.sHeightMatch == 'semiauto' )\n\t\t\t{\n\t\t\t\tanOriginal[i]._DTTC_iHeight = iHeight;\n\t\t\t}\n\n\t\t\theights.push( iHeight );\n\t\t}\n\n\t\tfor ( i=0, iLen=anClone.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tanClone[i].style.height = heights[i]+\"px\";\n\t\t\tanOriginal[i].style.height = heights[i]+\"px\";\n\t\t}\n\t}\n};\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Statics\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/**\n * FixedColumns default settings for initialisation\n *  @name FixedColumns.defaults\n *  @namespace\n *  @static\n */\nFixedColumns.defaults = /** @lends FixedColumns.defaults */{\n\t/**\n\t * Number of left hand columns to fix in position\n\t *  @type     int\n\t *  @default  1\n\t *  @static\n\t *  @example\n\t *      var  = $('#example').dataTable( {\n\t *          \"scrollX\": \"100%\"\n\t *      } );\n\t *      new $.fn.dataTable.fixedColumns( table, {\n\t *          \"leftColumns\": 2\n\t *      } );\n\t */\n\t\"iLeftColumns\": 1,\n\n\t/**\n\t * Number of right hand columns to fix in position\n\t *  @type     int\n\t *  @default  0\n\t *  @static\n\t *  @example\n\t *      var table = $('#example').dataTable( {\n\t *          \"scrollX\": \"100%\"\n\t *      } );\n\t *      new $.fn.dataTable.fixedColumns( table, {\n\t *          \"rightColumns\": 1\n\t *      } );\n\t */\n\t\"iRightColumns\": 0,\n\n\t/**\n\t * Draw callback function which is called when FixedColumns has redrawn the fixed assets\n\t *  @type     function(object, object):void\n\t *  @default  null\n\t *  @static\n\t *  @example\n\t *      var table = $('#example').dataTable( {\n\t *          \"scrollX\": \"100%\"\n\t *      } );\n\t *      new $.fn.dataTable.fixedColumns( table, {\n\t *          \"drawCallback\": function () {\n\t *\t            alert( \"FixedColumns redraw\" );\n\t *\t        }\n\t *      } );\n\t */\n\t\"fnDrawCallback\": null,\n\n\t/**\n\t * Height matching algorthim to use. This can be \"none\" which will result in no height\n\t * matching being applied by FixedColumns (height matching could be forced by CSS in this\n\t * case), \"semiauto\" whereby the height calculation will be performed once, and the result\n\t * cached to be used again (fnRecalculateHeight can be used to force recalculation), or\n\t * \"auto\" when height matching is performed on every draw (slowest but must accurate)\n\t *  @type     string\n\t *  @default  semiauto\n\t *  @static\n\t *  @example\n\t *      var table = $('#example').dataTable( {\n\t *          \"scrollX\": \"100%\"\n\t *      } );\n\t *      new $.fn.dataTable.fixedColumns( table, {\n\t *          \"heightMatch\": \"auto\"\n\t *      } );\n\t */\n\t\"sHeightMatch\": \"semiauto\"\n};\n\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Constants\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/**\n * FixedColumns version\n *  @name      FixedColumns.version\n *  @type      String\n *  @default   See code\n *  @static\n */\nFixedColumns.version = \"3.0.4\";\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Fired events (for documentation)\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\n/**\n * Event fired whenever FixedColumns redraws the fixed columns (i.e. clones the table elements from the main DataTable). This will occur whenever the DataTable that the FixedColumns instance is attached does its own draw.\n * @name FixedColumns#draw.dtfc\n * @event\n * @param {event} e jQuery event object\n * @param {object} o Event parameters from FixedColumns\n * @param {object} o.leftClone Instance's object dom.clone.left for easy reference. This object contains references to the left fixed clumn column's nodes\n * @param {object} o.rightClone Instance's object dom.clone.right for easy reference. This object contains references to the right fixed clumn column's nodes\n */\n\n\n// Make FixedColumns accessible from the DataTables instance\n$.fn.dataTable.FixedColumns = FixedColumns;\n$.fn.DataTable.FixedColumns = FixedColumns;\n\n\nreturn FixedColumns;\n}; // /factory\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery && !jQuery.fn.dataTable.FixedColumns ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n})(window, document);\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedHeader/Readme.txt",
    "content": "# FixedHeader\n\nAt times it can be useful to ensure that column titles will remain always visible on a table, even when a user scrolls down a table. The FixedHeader plug-in for DataTables will float the 'thead' element above the table at all times to help address this issue. The column titles also remain click-able to perform sorting. Key features include:\n\n* Fix the header to the top of the window\n* Ability to fix the footer and left / right columns as well\n* z-Index ordering options\n\n\n# Installation\n\nTo use FixedHeader, first download DataTables ( http://datatables.net/download ) and place the unzipped FixedHeader package into a `extensions` directory in the DataTables package. This will allow the pages in the examples to operate correctly. To see the examples running, open the `examples` directory in your web-browser.\n\n\n# Basic usage\n\nFixedHeader is initialised using the `$.fn.dataTable.FixedHeader()` object. For example:\n\n```js\n$(document).ready( function () {\n    var table = $('#example').dataTable();\n    new $.fn.dataTable.FixedHeader( table );\n} );\n```\n\n\n# Documentation / support\n\n* Documentation: http://datatables.net/extensions/FixedHeader/\n* DataTables support forums: http://datatables.net/forums\n\n\n# GitHub\n\nIf you fancy getting involved with the development of FixedHeader and help make it better, please refer to its GitHub repo: https://github.com/DataTables/FixedHeader\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedHeader/css/dataTables.fixedHeader.css",
    "content": "\n\ndiv.FixedHeader_Cloned th,\ndiv.FixedHeader_Cloned td {\n\tbackground-color: white !important;\n}\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedHeader/examples/header_footer.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedHeader example - Header and footer fixed</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedHeader.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedHeader.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.FixedHeader( table, {\n\t\tbottom: true\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedHeader example <span>Header and footer fixed</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>FixedHeader provides the ability to fix in place the header, footer, left and right columns of the\n\t\t\t\ttable. These are controlled by the options:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li><code>top</code> - default true</li>\n\t\t\t\t\t<li><code>bottom</code> - default false</li>\n\t\t\t\t\t<li><code>left</code> - default false</li>\n\t\t\t\t\t<li><code>right</code> - default false</li>\n\t\t\t\t</ul>\n\n\t\t\t\t<p>This example shows the header and footer of the table fixed by enabling the <code>bottom</code>\n\t\t\t\toption.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.FixedHeader( table, {\n\t\tbottom: true\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedHeader.js\">../js/dataTables.fixedHeader.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedHeader.css\">../css/dataTables.fixedHeader.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./header_footer.html\">Header and footer fixed</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./top_left_right.html\">Header, left and right all fixed</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./zIndexes.html\">z-index order control</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedHeader/examples/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\n\t<title>FixedHeader examples - FixedHeader examples</title>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedHeader example <span>FixedHeader examples</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>At times it can be useful to ensure that column titles will remain always visible on a table, even\n\t\t\t\twhen a user scrolls down a table. The FixedHeader plug-in for DataTables will float the <code class=\n\t\t\t\t\"tag\" title=\"HTML tag\">thead</code> element above the table at all times to help address this issue.\n\t\t\t\tThe column titles also remain click-able to perform sorting. Key features include:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li>Fix the header to the top of the window</li>\n\t\t\t\t\t<li>Ability to fix the footer and left / right columns as well</li>\n\t\t\t\t\t<li>z-Index ordering options</li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./header_footer.html\">Header and footer fixed</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./top_left_right.html\">Header, left and right all fixed</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./zIndexes.html\">z-index order control</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedHeader/examples/simple.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedHeader example - Basic initialisation</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedHeader.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedHeader.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.FixedHeader( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedHeader example <span>Basic initialisation</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>When displaying large amounts of data in a table, it can often be useful for the end user to have\n\t\t\t\tthe column titles (the <code class=\"tag\" title=\"HTML tag\">thead</code> element as a whole in fact)\n\t\t\t\talways visible. This is particularly true if using DataTables with pagination disabled, or the display\n\t\t\t\tlength is set to a high value.</p>\n\n\t\t\t\t<p>The FixedHeader extension for DataTables will ensure that your column titles will scroll with the\n\t\t\t\tpage, showing at the top of the table at all times. Try the demo shown below - you might want to try\n\t\t\t\tresizing the window for full effect! Note also that the column titles remain clickable to perform\n\t\t\t\tsorting on the table.</p>\n\n\t\t\t\t<p>FixedHeader is initialised using the constructor <code>new $.fn.dataTable.FixedHeader();</code> -\n\t\t\t\tshown below.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.FixedHeader( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedHeader.js\">../js/dataTables.fixedHeader.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedHeader.css\">../css/dataTables.fixedHeader.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./header_footer.html\">Header and footer fixed</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./top_left_right.html\">Header, left and right all fixed</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./zIndexes.html\">z-index order control</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedHeader/examples/top_left_right.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedHeader example - Header, left and right all fixed</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedHeader.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\tdiv.dataTables_wrapper {\n\t\twidth: 150%;\n\t}\n\n\tdiv.FixedHeader_Cloned.fixedLeft tbody td {\n\t\tborder-right: 1px solid black;\n\t}\n\n\tdiv.FixedHeader_Cloned.fixedRight tbody td {\n\t\tborder-left: 1px solid black;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedHeader.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\t\"order\": [ 1, 'asc' ],\n\t\t\"ajax\": \"../../../examples/ajax/data/objects.txt\",\n\t\t\"columns\": [\n\t\t\t{ title: '',           data: null, defaultContent: \"\" },\n\t\t\t{ title: 'Name',       data: \"name\" },\n\t\t\t{ title: 'Position',   data: \"position\" },\n\t\t\t{ title: 'Office',     data: \"office\" },\n\t\t\t{ title: 'Extn.',      data: \"extn\" },\n\t\t\t{ title: 'Start date', data: \"start_date\" },\n\t\t\t{ title: 'Salary',     data: \"salary\" },\n\t\t\t{ title: '',           data: null, defaultContent: \"\" }\n\t\t],\n\t\tinitComplete: function () {\n\t\t\tnew $.fn.dataTable.FixedHeader( table, {\n\t\t\t\tleft:   true,\n\t\t\t\tright:  true\n\t\t\t} );\n\t\t}\n\t} );\n\n\ttable.on( 'order.dt search.dt', function () {\n\t\ttable.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {\n\t\t\tcell.innerHTML = i+1;\n\t\t} );\n\n\t\ttable.column(-1, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {\n\t\t\tcell.innerHTML = i+1;\n\t\t} );\n\t} ).draw();\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedHeader example <span>Header, left and right all fixed</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>FixedHeader provides the ability to fix in place the header, footer, left and right columns of the\n\t\t\t\ttable. These are controlled by the options:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li><code>top</code> - default true</li>\n\t\t\t\t\t<li><code>bottom</code> - default false</li>\n\t\t\t\t\t<li><code>left</code> - default false</li>\n\t\t\t\t\t<li><code>right</code> - default false</li>\n\t\t\t\t</ul>\n\n\t\t\t\t<p>This example shows top, left and right enabled with index columns on the left and right.</p>\n\n\t\t\t\t<p>Note that in such a situation as this, the <a href=\n\t\t\t\t\"//datatables.net/extensions/fixedcolumns\">FixedColumns extension</a> might be more useful,\n\t\t\t\tparticularly if you want to use the scrolling options built into DataTables.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\"></table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\t&quot;order&quot;: [ 1, 'asc' ],\n\t\t&quot;ajax&quot;: &quot;../../../examples/ajax/data/objects.txt&quot;,\n\t\t&quot;columns&quot;: [\n\t\t\t{ title: '',           data: null, defaultContent: &quot;&quot; },\n\t\t\t{ title: 'Name',       data: &quot;name&quot; },\n\t\t\t{ title: 'Position',   data: &quot;position&quot; },\n\t\t\t{ title: 'Office',     data: &quot;office&quot; },\n\t\t\t{ title: 'Extn.',      data: &quot;extn&quot; },\n\t\t\t{ title: 'Start date', data: &quot;start_date&quot; },\n\t\t\t{ title: 'Salary',     data: &quot;salary&quot; },\n\t\t\t{ title: '',           data: null, defaultContent: &quot;&quot; }\n\t\t],\n\t\tinitComplete: function () {\n\t\t\tnew $.fn.dataTable.FixedHeader( table, {\n\t\t\t\tleft:   true,\n\t\t\t\tright:  true\n\t\t\t} );\n\t\t}\n\t} );\n\n\ttable.on( 'order.dt search.dt', function () {\n\t\ttable.column(0, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {\n\t\t\tcell.innerHTML = i+1;\n\t\t} );\n\n\t\ttable.column(-1, {search:'applied', order:'applied'}).nodes().each( function (cell, i) {\n\t\t\tcell.innerHTML = i+1;\n\t\t} );\n\t} ).draw();\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedHeader.js\">../js/dataTables.fixedHeader.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\">div.dataTables_wrapper {\n\t\twidth: 150%;\n\t}\n\n\tdiv.FixedHeader_Cloned.fixedLeft tbody td {\n\t\tborder-right: 1px solid black;\n\t}\n\n\tdiv.FixedHeader_Cloned.fixedRight tbody td {\n\t\tborder-left: 1px solid black;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedHeader.css\">../css/dataTables.fixedHeader.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./header_footer.html\">Header and footer fixed</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./top_left_right.html\">Header, left and right all\n\t\t\t\t\t\t\tfixed</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./zIndexes.html\">z-index order control</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedHeader/examples/two_tables.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedHeader example - Multiple tables</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedHeader.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedHeader.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar t1 = $('table.display').eq(0).DataTable();\n\tnew $.fn.dataTable.FixedHeader( t1, {\n\t\tbottom: true\n\t} );\n\n\tvar t2 = $('table.display').eq(1).DataTable();\n\tnew $.fn.dataTable.FixedHeader( t2, {\n\t\tbottom: true\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedHeader example <span>Multiple tables</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>The following example shows two DataTables enhanced tables both with FixedHeader enabled on them.\n\t\t\t\tThis is done simply by initialising FixedHeader on each table. This example also shows the footer being\n\t\t\t\tfixed in place for the two tables.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<table id=\"\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar t1 = $('table.display').eq(0).DataTable();\n\tnew $.fn.dataTable.FixedHeader( t1, {\n\t\tbottom: true\n\t} );\n\n\tvar t2 = $('table.display').eq(1).DataTable();\n\tnew $.fn.dataTable.FixedHeader( t2, {\n\t\tbottom: true\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedHeader.js\">../js/dataTables.fixedHeader.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedHeader.css\">../css/dataTables.fixedHeader.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./header_footer.html\">Header and footer fixed</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./top_left_right.html\">Header, left and right all fixed</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./two_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./zIndexes.html\">z-index order control</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedHeader/examples/zIndexes.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>FixedHeader example - z-index order control</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.fixedHeader.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\tdiv.dataTables_wrapper {\n\t\twidth: 1500px;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.fixedHeader.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.FixedHeader( table, {\n\t\tleft: true,\n\t\tzLeft: 105\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>FixedHeader example <span>z-index order control</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>When you have two or more columns fixed on a table, there might be occasions when you which to have\n\t\t\t\tone column floating on top of another. This example shows how you can do that with the initialisation\n\t\t\t\tparameters <code>zTop</code>, <code>zBottom</code>, <code>zLeft</code> and <code>zRight</code>. In this\n\t\t\t\texample the left column is set to float on top of the header. The difference is subtle, but can be\n\t\t\t\teffective.</p>\n\n\t\t\t\t<p>The default zIndexes are:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li><code>zTop</code>: 104</li>\n\t\t\t\t\t<li><code>zBottom</code>: 103</li>\n\t\t\t\t\t<li><code>zLeft</code>: 102</li>\n\t\t\t\t\t<li><code>zRight</code>: 101</li>\n\t\t\t\t</ul>\n\n\t\t\t\t<p>This example shows the left column being floated on top of the header.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"stripe row-border order-column\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.FixedHeader( table, {\n\t\tleft: true,\n\t\tzLeft: 105\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.fixedHeader.js\">../js/dataTables.fixedHeader.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\">div.dataTables_wrapper {\n\t\twidth: 1500px;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.fixedHeader.css\">../css/dataTables.fixedHeader.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./header_footer.html\">Header and footer fixed</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./top_left_right.html\">Header, left and right all fixed</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./two_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./zIndexes.html\">z-index order control</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/FixedHeader/js/dataTables.fixedHeader.js",
    "content": "/*! FixedHeader 2.1.2\n * ©2010-2014 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary     FixedHeader\n * @description Fix a table's header or footer, so it is always visible while\n *              Scrolling\n * @version     2.1.2\n * @file        dataTables.fixedHeader.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2009-2014 SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n *   MIT license - http://datatables.net/license/mit\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n/* Global scope for FixedColumns for backwards compatibility - will be removed\n * in future. Not documented in 1.1.x.\n */\n\n/* Global scope for FixedColumns */\nvar FixedHeader;\n\n(function(window, document, undefined) {\n\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\n/*\n * Function: FixedHeader\n * Purpose:  Provide 'fixed' header, footer and columns for a DataTable\n * Returns:  object:FixedHeader - must be called with 'new'\n * Inputs:   mixed:mTable - target table\n *  @param {object} dt DataTables instance or HTML table node. With DataTables\n *    1.10 this can also be a jQuery collection (with just a single table in its\n *    result set), a jQuery selector, DataTables API instance or settings\n *    object.\n *  @param {object} [oInit] initialisation settings, with the following\n *    properties (each optional)\n *    * bool:top -    fix the header (default true)\n *    * bool:bottom - fix the footer (default false)\n *    * int:left -    fix the left column(s) (default 0)\n *    * int:right -   fix the right column(s) (default 0)\n *    * int:zTop -    fixed header zIndex\n *    * int:zBottom - fixed footer zIndex\n *    * int:zLeft -   fixed left zIndex\n *    * int:zRight -  fixed right zIndex\n */\nFixedHeader = function ( mTable, oInit ) {\n\t/* Sanity check - you just know it will happen */\n\tif ( ! this instanceof FixedHeader )\n\t{\n\t\talert( \"FixedHeader warning: FixedHeader must be initialised with the 'new' keyword.\" );\n\t\treturn;\n\t}\n\n\tvar that = this;\n\tvar oSettings = {\n\t\t\"aoCache\": [],\n\t\t\"oSides\": {\n\t\t\t\"top\": true,\n\t\t\t\"bottom\": false,\n\t\t\t\"left\": 0,\n\t\t\t\"right\": 0\n\t\t},\n\t\t\"oZIndexes\": {\n\t\t\t\"top\": 104,\n\t\t\t\"bottom\": 103,\n\t\t\t\"left\": 102,\n\t\t\t\"right\": 101\n\t\t},\n\t\t\"oCloneOnDraw\": {\n\t\t\t\"top\": false,\n\t\t\t\"bottom\": false,\n\t\t\t\"left\": true,\n\t\t\t\"right\": true\n\t\t},\n\t\t\"oMes\": {\n\t\t\t\"iTableWidth\": 0,\n\t\t\t\"iTableHeight\": 0,\n\t\t\t\"iTableLeft\": 0,\n\t\t\t\"iTableRight\": 0, /* note this is left+width, not actually \"right\" */\n\t\t\t\"iTableTop\": 0,\n\t\t\t\"iTableBottom\": 0 /* note this is top+height, not actually \"bottom\" */\n\t\t},\n\t\t\"oOffset\": {\n\t\t\t\"top\": 0\n\t\t},\n\t\t\"nTable\": null,\n\t\t\"bFooter\": false,\n\t\t\"bInitComplete\": false\n\t};\n\n\t/*\n\t * Function: fnGetSettings\n\t * Purpose:  Get the settings for this object\n\t * Returns:  object: - settings object\n\t * Inputs:   -\n\t */\n\tthis.fnGetSettings = function () {\n\t\treturn oSettings;\n\t};\n\n\t/*\n\t * Function: fnUpdate\n\t * Purpose:  Update the positioning and copies of the fixed elements\n\t * Returns:  -\n\t * Inputs:   -\n\t */\n\tthis.fnUpdate = function () {\n\t\tthis._fnUpdateClones();\n\t\tthis._fnUpdatePositions();\n\t};\n\n\t/*\n\t * Function: fnPosition\n\t * Purpose:  Update the positioning of the fixed elements\n\t * Returns:  -\n\t * Inputs:   -\n\t */\n\tthis.fnPosition = function () {\n\t\tthis._fnUpdatePositions();\n\t};\n\n\n\tvar dt = $.fn.dataTable.Api ?\n\t\tnew $.fn.dataTable.Api( mTable ).settings()[0] :\n\t\tmTable.fnSettings();\n\n\tdt._oPluginFixedHeader = this;\n\n\t/* Let's do it */\n\tthis.fnInit( dt, oInit );\n\n};\n\n\n/*\n * Variable: FixedHeader\n * Purpose:  Prototype for FixedHeader\n * Scope:    global\n */\nFixedHeader.prototype = {\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Initialisation\n\t */\n\n\t/*\n\t * Function: fnInit\n\t * Purpose:  The \"constructor\"\n\t * Returns:  -\n\t * Inputs:   {as FixedHeader function}\n\t */\n\tfnInit: function ( oDtSettings, oInit )\n\t{\n\t\tvar s = this.fnGetSettings();\n\t\tvar that = this;\n\n\t\t/* Record the user definable settings */\n\t\tthis.fnInitSettings( s, oInit );\n\n\t\tif ( oDtSettings.oScroll.sX !== \"\" || oDtSettings.oScroll.sY !== \"\" )\n\t\t{\n\t\t\talert( \"FixedHeader 2 is not supported with DataTables' scrolling mode at this time\" );\n\t\t\treturn;\n\t\t}\n\n\t\ts.nTable = oDtSettings.nTable;\n\t\toDtSettings.aoDrawCallback.unshift( {\n\t\t\t\"fn\": function () {\n\t\t\t\tFixedHeader.fnMeasure();\n\t\t\t\tthat._fnUpdateClones.call(that);\n\t\t\t\tthat._fnUpdatePositions.call(that);\n\t\t\t},\n\t\t\t\"sName\": \"FixedHeader\"\n\t\t} );\n\n\t\ts.bFooter = ($('>tfoot', s.nTable).length > 0) ? true : false;\n\n\t\t/* Add the 'sides' that are fixed */\n\t\tif ( s.oSides.top )\n\t\t{\n\t\t\ts.aoCache.push( that._fnCloneTable( \"fixedHeader\", \"FixedHeader_Header\", that._fnCloneThead ) );\n\t\t}\n\t\tif ( s.oSides.bottom )\n\t\t{\n\t\t\ts.aoCache.push( that._fnCloneTable( \"fixedFooter\", \"FixedHeader_Footer\", that._fnCloneTfoot ) );\n\t\t}\n\t\tif ( s.oSides.left )\n\t\t{\n\t\t\ts.aoCache.push( that._fnCloneTable( \"fixedLeft\", \"FixedHeader_Left\", that._fnCloneTLeft, s.oSides.left ) );\n\t\t}\n\t\tif ( s.oSides.right )\n\t\t{\n\t\t\ts.aoCache.push( that._fnCloneTable( \"fixedRight\", \"FixedHeader_Right\", that._fnCloneTRight, s.oSides.right ) );\n\t\t}\n\n\t\t/* Event listeners for window movement */\n\t\tFixedHeader.afnScroll.push( function () {\n\t\t\tthat._fnUpdatePositions.call(that);\n\t\t} );\n\n\t\t$(window).resize( function () {\n\t\t\tFixedHeader.fnMeasure();\n\t\t\tthat._fnUpdateClones.call(that);\n\t\t\tthat._fnUpdatePositions.call(that);\n\t\t} );\n\n\t\t$(s.nTable)\n\t\t\t.on('column-reorder.dt', function () {\n\t\t\t\tFixedHeader.fnMeasure();\n\t\t\t\tthat._fnUpdateClones( true );\n\t\t\t\tthat._fnUpdatePositions();\n\t\t\t} )\n\t\t\t.on('column-visibility.dt', function () {\n\t\t\t\tFixedHeader.fnMeasure();\n\t\t\t\tthat._fnUpdateClones( true );\n\t\t\t\tthat._fnUpdatePositions();\n\t\t\t} );\n\n\t\t/* Get things right to start with */\n\t\tFixedHeader.fnMeasure();\n\t\tthat._fnUpdateClones();\n\t\tthat._fnUpdatePositions();\n\n\t\ts.bInitComplete = true;\n\t},\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Support functions\n\t */\n\n\t/*\n\t * Function: fnInitSettings\n\t * Purpose:  Take the user's settings and copy them to our local store\n\t * Returns:  -\n\t * Inputs:   object:s - the local settings object\n\t *           object:oInit - the user's settings object\n\t */\n\tfnInitSettings: function ( s, oInit )\n\t{\n\t\tif ( oInit !== undefined )\n\t\t{\n\t\t\tif ( oInit.top !== undefined ) {\n\t\t\t\ts.oSides.top = oInit.top;\n\t\t\t}\n\t\t\tif ( oInit.bottom !== undefined ) {\n\t\t\t\ts.oSides.bottom = oInit.bottom;\n\t\t\t}\n\t\t\tif ( typeof oInit.left == 'boolean' ) {\n\t\t\t\ts.oSides.left = oInit.left ? 1 : 0;\n\t\t\t}\n\t\t\telse if ( oInit.left !== undefined ) {\n\t\t\t\ts.oSides.left = oInit.left;\n\t\t\t}\n\t\t\tif ( typeof oInit.right == 'boolean' ) {\n\t\t\t\ts.oSides.right = oInit.right ? 1 : 0;\n\t\t\t}\n\t\t\telse if ( oInit.right !== undefined ) {\n\t\t\t\ts.oSides.right = oInit.right;\n\t\t\t}\n\n\t\t\tif ( oInit.zTop !== undefined ) {\n\t\t\t\ts.oZIndexes.top = oInit.zTop;\n\t\t\t}\n\t\t\tif ( oInit.zBottom !== undefined ) {\n\t\t\t\ts.oZIndexes.bottom = oInit.zBottom;\n\t\t\t}\n\t\t\tif ( oInit.zLeft !== undefined ) {\n\t\t\t\ts.oZIndexes.left = oInit.zLeft;\n\t\t\t}\n\t\t\tif ( oInit.zRight !== undefined ) {\n\t\t\t\ts.oZIndexes.right = oInit.zRight;\n\t\t\t}\n\n\t\t\tif ( oInit.offsetTop !== undefined ) {\n\t\t\t\ts.oOffset.top = oInit.offsetTop;\n\t\t\t}\n\t\t\tif ( oInit.alwaysCloneTop !== undefined ) {\n\t\t\t\ts.oCloneOnDraw.top = oInit.alwaysCloneTop;\n\t\t\t}\n\t\t\tif ( oInit.alwaysCloneBottom !== undefined ) {\n\t\t\t\ts.oCloneOnDraw.bottom = oInit.alwaysCloneBottom;\n\t\t\t}\n\t\t\tif ( oInit.alwaysCloneLeft !== undefined ) {\n\t\t\t\ts.oCloneOnDraw.left = oInit.alwaysCloneLeft;\n\t\t\t}\n\t\t\tif ( oInit.alwaysCloneRight !== undefined ) {\n\t\t\t\ts.oCloneOnDraw.right = oInit.alwaysCloneRight;\n\t\t\t}\n\t\t}\n\t},\n\n\t/*\n\t * Function: _fnCloneTable\n\t * Purpose:  Clone the table node and do basic initialisation\n\t * Returns:  -\n\t * Inputs:   -\n\t */\n\t_fnCloneTable: function ( sType, sClass, fnClone, iCells )\n\t{\n\t\tvar s = this.fnGetSettings();\n\t\tvar nCTable;\n\n\t\t/* We know that the table _MUST_ has a DIV wrapped around it, because this is simply how\n\t\t * DataTables works. Therefore, we can set this to be relatively position (if it is not\n\t\t * alreadu absolute, and use this as the base point for the cloned header\n\t\t */\n\t\tif ( $(s.nTable.parentNode).css('position') != \"absolute\" )\n\t\t{\n\t\t\ts.nTable.parentNode.style.position = \"relative\";\n\t\t}\n\n\t\t/* Just a shallow clone will do - we only want the table node */\n\t\tnCTable = s.nTable.cloneNode( false );\n\t\tnCTable.removeAttribute( 'id' );\n\n\t\tvar nDiv = document.createElement( 'div' );\n\t\tnDiv.style.position = \"absolute\";\n\t\tnDiv.style.top = \"0px\";\n\t\tnDiv.style.left = \"0px\";\n\t\tnDiv.className += \" FixedHeader_Cloned \"+sType+\" \"+sClass;\n\n\t\t/* Set the zIndexes */\n\t\tif ( sType == \"fixedHeader\" )\n\t\t{\n\t\t\tnDiv.style.zIndex = s.oZIndexes.top;\n\t\t}\n\t\tif ( sType == \"fixedFooter\" )\n\t\t{\n\t\t\tnDiv.style.zIndex = s.oZIndexes.bottom;\n\t\t}\n\t\tif ( sType == \"fixedLeft\" )\n\t\t{\n\t\t\tnDiv.style.zIndex = s.oZIndexes.left;\n\t\t}\n\t\telse if ( sType == \"fixedRight\" )\n\t\t{\n\t\t\tnDiv.style.zIndex = s.oZIndexes.right;\n\t\t}\n\n\t\t/* remove margins since we are going to position it absolutely */\n\t\tnCTable.style.margin = \"0\";\n\n\t\t/* Insert the newly cloned table into the DOM, on top of the \"real\" header */\n\t\tnDiv.appendChild( nCTable );\n\t\tdocument.body.appendChild( nDiv );\n\n\t\treturn {\n\t\t\t\"nNode\": nCTable,\n\t\t\t\"nWrapper\": nDiv,\n\t\t\t\"sType\": sType,\n\t\t\t\"sPosition\": \"\",\n\t\t\t\"sTop\": \"\",\n\t\t\t\"sLeft\": \"\",\n\t\t\t\"fnClone\": fnClone,\n\t\t\t\"iCells\": iCells\n\t\t};\n\t},\n\n\t/*\n\t * Function: _fnMeasure\n\t * Purpose:  Get the current positioning of the table in the DOM\n\t * Returns:  -\n\t * Inputs:   -\n\t */\n\t_fnMeasure: function ()\n\t{\n\t\tvar\n\t\t\ts = this.fnGetSettings(),\n\t\t\tm = s.oMes,\n\t\t\tjqTable = $(s.nTable),\n\t\t\toOffset = jqTable.offset(),\n\t\t\tiParentScrollTop = this._fnSumScroll( s.nTable.parentNode, 'scrollTop' ),\n\t\t\tiParentScrollLeft = this._fnSumScroll( s.nTable.parentNode, 'scrollLeft' );\n\n\t\tm.iTableWidth = jqTable.outerWidth();\n\t\tm.iTableHeight = jqTable.outerHeight();\n\t\tm.iTableLeft = oOffset.left + s.nTable.parentNode.scrollLeft;\n\t\tm.iTableTop = oOffset.top + iParentScrollTop;\n\t\tm.iTableRight = m.iTableLeft + m.iTableWidth;\n\t\tm.iTableRight = FixedHeader.oDoc.iWidth - m.iTableLeft - m.iTableWidth;\n\t\tm.iTableBottom = FixedHeader.oDoc.iHeight - m.iTableTop - m.iTableHeight;\n\t},\n\n\t/*\n\t * Function: _fnSumScroll\n\t * Purpose:  Sum node parameters all the way to the top\n\t * Returns:  int: sum\n\t * Inputs:   node:n - node to consider\n\t *           string:side - scrollTop or scrollLeft\n\t */\n\t_fnSumScroll: function ( n, side )\n\t{\n\t\tvar i = n[side];\n\t\twhile ( n = n.parentNode )\n\t\t{\n\t\t\tif ( n.nodeName == 'HTML' || n.nodeName == 'BODY' )\n\t\t\t{\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\ti = n[side];\n\t\t}\n\t\treturn i;\n\t},\n\n\t/*\n\t * Function: _fnUpdatePositions\n\t * Purpose:  Loop over the fixed elements for this table and update their positions\n\t * Returns:  -\n\t * Inputs:   -\n\t */\n\t_fnUpdatePositions: function ()\n\t{\n\t\tvar s = this.fnGetSettings();\n\t\tthis._fnMeasure();\n\n\t\tfor ( var i=0, iLen=s.aoCache.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tif ( s.aoCache[i].sType == \"fixedHeader\" )\n\t\t\t{\n\t\t\t\tthis._fnScrollFixedHeader( s.aoCache[i] );\n\t\t\t}\n\t\t\telse if ( s.aoCache[i].sType == \"fixedFooter\" )\n\t\t\t{\n\t\t\t\tthis._fnScrollFixedFooter( s.aoCache[i] );\n\t\t\t}\n\t\t\telse if ( s.aoCache[i].sType == \"fixedLeft\" )\n\t\t\t{\n\t\t\t\tthis._fnScrollHorizontalLeft( s.aoCache[i] );\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tthis._fnScrollHorizontalRight( s.aoCache[i] );\n\t\t\t}\n\t\t}\n\t},\n\n\t/*\n\t * Function: _fnUpdateClones\n\t * Purpose:  Loop over the fixed elements for this table and call their cloning functions\n\t * Returns:  -\n\t * Inputs:   -\n\t */\n\t_fnUpdateClones: function ( full )\n\t{\n\t\tvar s = this.fnGetSettings();\n\n\t\tif ( full ) {\n\t\t\t// This is a little bit of a hack to force a full clone draw. When\n\t\t\t// `full` is set to true, we want to reclone the source elements,\n\t\t\t// regardless of the clone-on-draw settings\n\t\t\ts.bInitComplete = false;\n\t\t}\n\n\t\tfor ( var i=0, iLen=s.aoCache.length ; i<iLen ; i++ )\n\t\t{\n\t\t\ts.aoCache[i].fnClone.call( this, s.aoCache[i] );\n\t\t}\n\n\t\tif ( full ) {\n\t\t\ts.bInitComplete = true;\n\t\t}\n\t},\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Scrolling functions\n\t */\n\n\t/*\n\t * Function: _fnScrollHorizontalLeft\n\t * Purpose:  Update the positioning of the scrolling elements\n\t * Returns:  -\n\t * Inputs:   object:oCache - the cached values for this fixed element\n\t */\n\t_fnScrollHorizontalRight: function ( oCache )\n\t{\n\t\tvar\n\t\t\ts = this.fnGetSettings(),\n\t\t\toMes = s.oMes,\n\t\t\toWin = FixedHeader.oWin,\n\t\t\toDoc = FixedHeader.oDoc,\n\t\t\tnTable = oCache.nWrapper,\n\t\t\tiFixedWidth = $(nTable).outerWidth();\n\n\t\tif ( oWin.iScrollRight < oMes.iTableRight )\n\t\t{\n\t\t\t/* Fully right aligned */\n\t\t\tthis._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+\"px\", 'top', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft+oMes.iTableWidth-iFixedWidth)+\"px\", 'left', nTable.style );\n\t\t}\n\t\telse if ( oMes.iTableLeft < oDoc.iWidth-oWin.iScrollRight-iFixedWidth )\n\t\t{\n\t\t\t/* Middle */\n\t\t\tthis._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop-oWin.iScrollTop)+\"px\", 'top', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sLeft', (oWin.iWidth-iFixedWidth)+\"px\", 'left', nTable.style );\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Fully left aligned */\n\t\t\tthis._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+\"px\", 'top', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+\"px\", 'left', nTable.style );\n\t\t}\n\t},\n\n\t/*\n\t * Function: _fnScrollHorizontalLeft\n\t * Purpose:  Update the positioning of the scrolling elements\n\t * Returns:  -\n\t * Inputs:   object:oCache - the cached values for this fixed element\n\t */\n\t_fnScrollHorizontalLeft: function ( oCache )\n\t{\n\t\tvar\n\t\t\ts = this.fnGetSettings(),\n\t\t\toMes = s.oMes,\n\t\t\toWin = FixedHeader.oWin,\n\t\t\toDoc = FixedHeader.oDoc,\n\t\t\tnTable = oCache.nWrapper,\n\t\t\tiCellWidth = $(nTable).outerWidth();\n\n\t\tif ( oWin.iScrollLeft < oMes.iTableLeft )\n\t\t{\n\t\t\t/* Fully left align */\n\t\t\tthis._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+\"px\", 'top', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+\"px\", 'left', nTable.style );\n\t\t}\n\t\telse if ( oWin.iScrollLeft < oMes.iTableLeft+oMes.iTableWidth-iCellWidth )\n\t\t{\n\t\t\tthis._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop-oWin.iScrollTop)+\"px\", 'top', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sLeft', \"0px\", 'left', nTable.style );\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Fully right align */\n\t\t\tthis._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+\"px\", 'top', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft+oMes.iTableWidth-iCellWidth)+\"px\", 'left', nTable.style );\n\t\t}\n\t},\n\n\t/*\n\t * Function: _fnScrollFixedFooter\n\t * Purpose:  Update the positioning of the scrolling elements\n\t * Returns:  -\n\t * Inputs:   object:oCache - the cached values for this fixed element\n\t */\n\t_fnScrollFixedFooter: function ( oCache )\n\t{\n\t\tvar\n\t\t\ts = this.fnGetSettings(),\n\t\t\toMes = s.oMes,\n\t\t\toWin = FixedHeader.oWin,\n\t\t\toDoc = FixedHeader.oDoc,\n\t\t\tnTable = oCache.nWrapper,\n\t\t\tiTheadHeight = $(\"thead\", s.nTable).outerHeight(),\n\t\t\tiCellHeight = $(nTable).outerHeight();\n\n\t\tif ( oWin.iScrollBottom < oMes.iTableBottom )\n\t\t{\n\t\t\t/* Below */\n\t\t\tthis._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop+oMes.iTableHeight-iCellHeight)+\"px\", 'top', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+\"px\", 'left', nTable.style );\n\t\t}\n\t\telse if ( oWin.iScrollBottom < oMes.iTableBottom+oMes.iTableHeight-iCellHeight-iTheadHeight )\n\t\t{\n\t\t\tthis._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sTop', (oWin.iHeight-iCellHeight)+\"px\", 'top', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft-oWin.iScrollLeft)+\"px\", 'left', nTable.style );\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Above */\n\t\t\tthis._fnUpdateCache( oCache, 'sPosition', 'absolute', 'position', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop+iCellHeight)+\"px\", 'top', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+\"px\", 'left', nTable.style );\n\t\t}\n\t},\n\n\t/*\n\t * Function: _fnScrollFixedHeader\n\t * Purpose:  Update the positioning of the scrolling elements\n\t * Returns:  -\n\t * Inputs:   object:oCache - the cached values for this fixed element\n\t */\n\t_fnScrollFixedHeader: function ( oCache )\n\t{\n\t\tvar\n\t\t\ts = this.fnGetSettings(),\n\t\t\toMes = s.oMes,\n\t\t\toWin = FixedHeader.oWin,\n\t\t\toDoc = FixedHeader.oDoc,\n\t\t\tnTable = oCache.nWrapper,\n\t\t\tiTbodyHeight = 0,\n\t\t\tanTbodies = s.nTable.getElementsByTagName('tbody');\n\n\t\tfor (var i = 0; i < anTbodies.length; ++i) {\n\t\t\tiTbodyHeight += anTbodies[i].offsetHeight;\n\t\t}\n\n\t\tif ( oMes.iTableTop > oWin.iScrollTop + s.oOffset.top )\n\t\t{\n\t\t\t/* Above the table */\n\t\t\tthis._fnUpdateCache( oCache, 'sPosition', \"absolute\", 'position', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sTop', oMes.iTableTop+\"px\", 'top', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+\"px\", 'left', nTable.style );\n\t\t}\n\t\telse if ( oWin.iScrollTop + s.oOffset.top > oMes.iTableTop+iTbodyHeight )\n\t\t{\n\t\t\t/* At the bottom of the table */\n\t\t\tthis._fnUpdateCache( oCache, 'sPosition', \"absolute\", 'position', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sTop', (oMes.iTableTop+iTbodyHeight)+\"px\", 'top', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sLeft', oMes.iTableLeft+\"px\", 'left', nTable.style );\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* In the middle of the table */\n\t\t\tthis._fnUpdateCache( oCache, 'sPosition', 'fixed', 'position', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sTop', s.oOffset.top+\"px\", 'top', nTable.style );\n\t\t\tthis._fnUpdateCache( oCache, 'sLeft', (oMes.iTableLeft-oWin.iScrollLeft)+\"px\", 'left', nTable.style );\n\t\t}\n\t},\n\n\t/*\n\t * Function: _fnUpdateCache\n\t * Purpose:  Check the cache and update cache and value if needed\n\t * Returns:  -\n\t * Inputs:   object:oCache - local cache object\n\t *           string:sCache - cache property\n\t *           string:sSet - value to set\n\t *           string:sProperty - object property to set\n\t *           object:oObj - object to update\n\t */\n\t_fnUpdateCache: function ( oCache, sCache, sSet, sProperty, oObj )\n\t{\n\t\tif ( oCache[sCache] != sSet )\n\t\t{\n\t\t\toObj[sProperty] = sSet;\n\t\t\toCache[sCache] = sSet;\n\t\t}\n\t},\n\n\n\n\t/**\n\t * Copy the classes of all child nodes from one element to another. This implies\n\t * that the two have identical structure - no error checking is performed to that\n\t * fact.\n\t *  @param {element} source Node to copy classes from\n\t *  @param {element} dest Node to copy classes too\n\t */\n\t_fnClassUpdate: function ( source, dest )\n\t{\n\t\tvar that = this;\n\n\t\tif ( source.nodeName.toUpperCase() === \"TR\" || source.nodeName.toUpperCase() === \"TH\" ||\n\t\t\t source.nodeName.toUpperCase() === \"TD\" || source.nodeName.toUpperCase() === \"SPAN\" )\n\t\t{\n\t\t\tdest.className = source.className;\n\t\t}\n\n\t\t$(source).children().each( function (i) {\n\t\t\tthat._fnClassUpdate( $(source).children()[i], $(dest).children()[i] );\n\t\t} );\n\t},\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Cloning functions\n\t */\n\n\t/*\n\t * Function: _fnCloneThead\n\t * Purpose:  Clone the thead element\n\t * Returns:  -\n\t * Inputs:   object:oCache - the cached values for this fixed element\n\t */\n\t_fnCloneThead: function ( oCache )\n\t{\n\t\tvar s = this.fnGetSettings();\n\t\tvar nTable = oCache.nNode;\n\n\t\tif ( s.bInitComplete && !s.oCloneOnDraw.top )\n\t\t{\n\t\t\tthis._fnClassUpdate( $('thead', s.nTable)[0], $('thead', nTable)[0] );\n\t\t\treturn;\n\t\t}\n\n\t\t/* Set the wrapper width to match that of the cloned table */\n\t\tvar iDtWidth = $(s.nTable).outerWidth();\n\t\toCache.nWrapper.style.width = iDtWidth+\"px\";\n\t\tnTable.style.width = iDtWidth+\"px\";\n\n\t\t/* Remove any children the cloned table has */\n\t\twhile ( nTable.childNodes.length > 0 )\n\t\t{\n\t\t\t$('thead th', nTable).unbind( 'click' );\n\t\t\tnTable.removeChild( nTable.childNodes[0] );\n\t\t}\n\n\t\t/* Clone the DataTables header */\n\t\tvar nThead = $('thead', s.nTable).clone(true)[0];\n\t\tnTable.appendChild( nThead );\n\n\t\t/* Copy the widths across - apparently a clone isn't good enough for this */\n\t\tvar a = [];\n\t\tvar b = [];\n\n\t\t$(\"thead>tr th\", s.nTable).each( function (i) {\n\t\t\ta.push( $(this).width() );\n\t\t} );\n\n\t\t$(\"thead>tr td\", s.nTable).each( function (i) {\n\t\t\tb.push( $(this).width() );\n\t\t} );\n\n\t\t$(\"thead>tr th\", s.nTable).each( function (i) {\n\t\t\t$(\"thead>tr th:eq(\"+i+\")\", nTable).width( a[i] );\n\t\t\t$(this).width( a[i] );\n\t\t} );\n\n\t\t$(\"thead>tr td\", s.nTable).each( function (i) {\n\t\t\t$(\"thead>tr td:eq(\"+i+\")\", nTable).width( b[i] );\n\t\t\t$(this).width( b[i] );\n\t\t} );\n\n\t\t// Stop DataTables 1.9 from putting a focus ring on the headers when\n\t\t// clicked to sort\n\t\t$('th.sorting, th.sorting_desc, th.sorting_asc', nTable).bind( 'click', function () {\n\t\t\tthis.blur();\n\t\t} );\n\t},\n\n\t/*\n\t * Function: _fnCloneTfoot\n\t * Purpose:  Clone the tfoot element\n\t * Returns:  -\n\t * Inputs:   object:oCache - the cached values for this fixed element\n\t */\n\t_fnCloneTfoot: function ( oCache )\n\t{\n\t\tvar s = this.fnGetSettings();\n\t\tvar nTable = oCache.nNode;\n\n\t\t/* Set the wrapper width to match that of the cloned table */\n\t\toCache.nWrapper.style.width = $(s.nTable).outerWidth()+\"px\";\n\n\t\t/* Remove any children the cloned table has */\n\t\twhile ( nTable.childNodes.length > 0 )\n\t\t{\n\t\t\tnTable.removeChild( nTable.childNodes[0] );\n\t\t}\n\n\t\t/* Clone the DataTables footer */\n\t\tvar nTfoot = $('tfoot', s.nTable).clone(true)[0];\n\t\tnTable.appendChild( nTfoot );\n\n\t\t/* Copy the widths across - apparently a clone isn't good enough for this */\n\t\t$(\"tfoot:eq(0)>tr th\", s.nTable).each( function (i) {\n\t\t\t$(\"tfoot:eq(0)>tr th:eq(\"+i+\")\", nTable).width( $(this).width() );\n\t\t} );\n\n\t\t$(\"tfoot:eq(0)>tr td\", s.nTable).each( function (i) {\n\t\t\t$(\"tfoot:eq(0)>tr td:eq(\"+i+\")\", nTable).width( $(this).width() );\n\t\t} );\n\t},\n\n\t/*\n\t * Function: _fnCloneTLeft\n\t * Purpose:  Clone the left column(s)\n\t * Returns:  -\n\t * Inputs:   object:oCache - the cached values for this fixed element\n\t */\n\t_fnCloneTLeft: function ( oCache )\n\t{\n\t\tvar s = this.fnGetSettings();\n\t\tvar nTable = oCache.nNode;\n\t\tvar nBody = $('tbody', s.nTable)[0];\n\n\t\t/* Remove any children the cloned table has */\n\t\twhile ( nTable.childNodes.length > 0 )\n\t\t{\n\t\t\tnTable.removeChild( nTable.childNodes[0] );\n\t\t}\n\n\t\t/* Is this the most efficient way to do this - it looks horrible... */\n\t\tnTable.appendChild( $(\"thead\", s.nTable).clone(true)[0] );\n\t\tnTable.appendChild( $(\"tbody\", s.nTable).clone(true)[0] );\n\t\tif ( s.bFooter )\n\t\t{\n\t\t\tnTable.appendChild( $(\"tfoot\", s.nTable).clone(true)[0] );\n\t\t}\n\n\t\t/* Remove unneeded cells */\n\t\tvar sSelector = 'gt(' + (oCache.iCells - 1) + ')';\n\t\t$('thead tr', nTable).each( function (k) {\n\t\t\t$('th:' + sSelector, this).remove();\n\t\t} );\n\n\t\t$('tfoot tr', nTable).each( function (k) {\n\t\t\t$('th:' + sSelector, this).remove();\n\t\t} );\n\n\t\t$('tbody tr', nTable).each( function (k) {\n\t\t\t$('td:' + sSelector, this).remove();\n\t\t} );\n\n\t\tthis.fnEqualiseHeights( 'thead', nBody.parentNode, nTable );\n\t\tthis.fnEqualiseHeights( 'tbody', nBody.parentNode, nTable );\n\t\tthis.fnEqualiseHeights( 'tfoot', nBody.parentNode, nTable );\n\n\t\tvar iWidth = 0;\n\t\tfor (var i = 0; i < oCache.iCells; i++) {\n\t\t\tiWidth += $('thead tr th:eq(' + i + ')', s.nTable).outerWidth();\n\t\t}\n\t\tnTable.style.width = iWidth+\"px\";\n\t\toCache.nWrapper.style.width = iWidth+\"px\";\n\t},\n\n\t/*\n\t * Function: _fnCloneTRight\n\t * Purpose:  Clone the right most column(s)\n\t * Returns:  -\n\t * Inputs:   object:oCache - the cached values for this fixed element\n\t */\n\t_fnCloneTRight: function ( oCache )\n\t{\n\t\tvar s = this.fnGetSettings();\n\t\tvar nBody = $('tbody', s.nTable)[0];\n\t\tvar nTable = oCache.nNode;\n\t\tvar iCols = $('tbody tr:eq(0) td', s.nTable).length;\n\n\t\t/* Remove any children the cloned table has */\n\t\twhile ( nTable.childNodes.length > 0 )\n\t\t{\n\t\t\tnTable.removeChild( nTable.childNodes[0] );\n\t\t}\n\n\t\t/* Is this the most efficient way to do this - it looks horrible... */\n\t\tnTable.appendChild( $(\"thead\", s.nTable).clone(true)[0] );\n\t\tnTable.appendChild( $(\"tbody\", s.nTable).clone(true)[0] );\n\t\tif ( s.bFooter )\n\t\t{\n\t\t\tnTable.appendChild( $(\"tfoot\", s.nTable).clone(true)[0] );\n\t\t}\n\t\t$('thead tr th:lt('+(iCols-oCache.iCells)+')', nTable).remove();\n\t\t$('tfoot tr th:lt('+(iCols-oCache.iCells)+')', nTable).remove();\n\n\t\t/* Remove unneeded cells */\n\t\t$('tbody tr', nTable).each( function (k) {\n\t\t\t$('td:lt('+(iCols-oCache.iCells)+')', this).remove();\n\t\t} );\n\n\t\tthis.fnEqualiseHeights( 'thead', nBody.parentNode, nTable );\n\t\tthis.fnEqualiseHeights( 'tbody', nBody.parentNode, nTable );\n\t\tthis.fnEqualiseHeights( 'tfoot', nBody.parentNode, nTable );\n\n\t\tvar iWidth = 0;\n\t\tfor (var i = 0; i < oCache.iCells; i++) {\n\t\t\tiWidth += $('thead tr th:eq('+(iCols-1-i)+')', s.nTable).outerWidth();\n\t\t}\n\t\tnTable.style.width = iWidth+\"px\";\n\t\toCache.nWrapper.style.width = iWidth+\"px\";\n\t},\n\n\n\t/**\n\t * Equalise the heights of the rows in a given table node in a cross browser way. Note that this\n\t * is more or less lifted as is from FixedColumns\n\t *  @method  fnEqualiseHeights\n\t *  @returns void\n\t *  @param   {string} parent Node type - thead, tbody or tfoot\n\t *  @param   {element} original Original node to take the heights from\n\t *  @param   {element} clone Copy the heights to\n\t *  @private\n\t */\n\t\"fnEqualiseHeights\": function ( parent, original, clone )\n\t{\n\t\tvar that = this;\n\t\tvar originals = $(parent +' tr', original);\n\t\tvar height;\n\n\t\t$(parent+' tr', clone).each( function (k) {\n\t\t\theight = originals.eq( k ).css('height');\n\n\t\t\t// This is nasty :-(. IE has a sub-pixel error even when setting\n\t\t\t// the height below (the Firefox fix) which causes the fixed column\n\t\t\t// to go out of alignment. Need to add a pixel before the assignment\n\t\t\t// Can this be feature detected? Not sure how...\n\t\t\tif ( navigator.appName == 'Microsoft Internet Explorer' ) {\n\t\t\t\theight = parseInt( height, 10 ) + 1;\n\t\t\t}\n\n\t\t\t$(this).css( 'height', height );\n\n\t\t\t// For Firefox to work, we need to also set the height of the\n\t\t\t// original row, to the value that we read from it! Otherwise there\n\t\t\t// is a sub-pixel rounding error\n\t\t\toriginals.eq( k ).css( 'height', height );\n\t\t} );\n\t}\n};\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Static properties and methods\n *   We use these for speed! This information is common to all instances of FixedHeader, so no\n * point if having them calculated and stored for each different instance.\n */\n\n/*\n * Variable: oWin\n * Purpose:  Store information about the window positioning\n * Scope:    FixedHeader\n */\nFixedHeader.oWin = {\n\t\"iScrollTop\": 0,\n\t\"iScrollRight\": 0,\n\t\"iScrollBottom\": 0,\n\t\"iScrollLeft\": 0,\n\t\"iHeight\": 0,\n\t\"iWidth\": 0\n};\n\n/*\n * Variable: oDoc\n * Purpose:  Store information about the document size\n * Scope:    FixedHeader\n */\nFixedHeader.oDoc = {\n\t\"iHeight\": 0,\n\t\"iWidth\": 0\n};\n\n/*\n * Variable: afnScroll\n * Purpose:  Array of functions that are to be used for the scrolling components\n * Scope:    FixedHeader\n */\nFixedHeader.afnScroll = [];\n\n/*\n * Function: fnMeasure\n * Purpose:  Update the measurements for the window and document\n * Returns:  -\n * Inputs:   -\n */\nFixedHeader.fnMeasure = function ()\n{\n\tvar\n\t\tjqWin = $(window),\n\t\tjqDoc = $(document),\n\t\toWin = FixedHeader.oWin,\n\t\toDoc = FixedHeader.oDoc;\n\n\toDoc.iHeight = jqDoc.height();\n\toDoc.iWidth = jqDoc.width();\n\n\toWin.iHeight = jqWin.height();\n\toWin.iWidth = jqWin.width();\n\toWin.iScrollTop = jqWin.scrollTop();\n\toWin.iScrollLeft = jqWin.scrollLeft();\n\toWin.iScrollRight = oDoc.iWidth - oWin.iScrollLeft - oWin.iWidth;\n\toWin.iScrollBottom = oDoc.iHeight - oWin.iScrollTop - oWin.iHeight;\n};\n\n\nFixedHeader.version = \"2.1.2\";\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Global processing\n */\n\n/*\n * Just one 'scroll' event handler in FixedHeader, which calls the required components. This is\n * done as an optimisation, to reduce calculation and proagation time\n */\n$(window).scroll( function () {\n\tFixedHeader.fnMeasure();\n\n\tfor ( var i=0, iLen=FixedHeader.afnScroll.length ; i<iLen ; i++ ) {\n\t\tFixedHeader.afnScroll[i]();\n\t}\n} );\n\n\n$.fn.dataTable.FixedHeader = FixedHeader;\n$.fn.DataTable.FixedHeader = FixedHeader;\n\n\nreturn FixedHeader;\n}; // /factory\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery && !jQuery.fn.dataTable.FixedHeader ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n})(window, document);\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/KeyTable/Readme.txt",
    "content": "# KeyTable\n\nKeyTable provides enhanced accessibility and navigation options for DataTables enhanced tables, by allowing Excel like cell navigation on any table. Events (focus, blur, action etc) can be assigned to individual cells, columns, rows or all cells to allow advanced interaction options.. Key features include:\n\n* Easy to use spreadsheet like interaction\n* Fully integrated with DataTables\n* Wide range of supported events\n\n\n# Installation\n\nTo use KeyTable, first download DataTables ( http://datatables.net/download ) and place the unzipped KeyTable package into a `extensions` directory in the DataTables package. This will allow the pages in the examples to operate correctly. To see the examples running, open the `examples` directory in your web-browser.\n\n\n# Basic usage\n\nKeyTable is initialised using the `C` option that it adds to DataTables' `dom` option. For example:\n\n```js\n$(document).ready( function () {\n\tvar table = $('#example').DataTable();\n\tnew $.fn.dataTable.KeyTable( table );\n} );\n```\n\n\n# Documentation / support\n\n* Documentation: http://datatables.net/extensions/keytable/\n* DataTables support forums: http://datatables.net/forums\n\n\n# GitHub\n\nIf you fancy getting involved with the development of KeyTable and help make it better, please refer to its GitHub repo: https://github.com/DataTables/KeyTable\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/KeyTable/css/dataTables.keyTable.css",
    "content": "\n\ntable.KeyTable th.focus,\ntable.KeyTable td.focus {\n\toutline: 3px solid #3366FF;\n\toutline-offset: -3px;\n}\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/KeyTable/examples/events.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>KeyTable example - Events</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.keyTable.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.keyTable.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\nfunction eventMsg ( msg ) {\n\tvar n = document.getElementById('info');\n\tn.innerHTML += msg+\"<br>\";\n\tn.scrollTop = n.scrollHeight;\n}\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\tvar keys = new $.fn.dataTable.KeyTable( table );\n\n\t/* Focus handler for all cells in last column */\n\tkeys.event.focus( 4, null, function( node, x, y ) {\n\t\teventMsg( \"Cell \"+x+\",\"+y+\" focused ('live' event - column)\" );\n\t} );\n\t\n\t/* Focus handler for all cells in 8th row */\n\tkeys.event.focus( null, 7, function( node, x, y ) {\n\t\teventMsg( \"Cell \"+x+\",\"+y+\" focused ('live' event - row)\" );\n\t} );\n\t\n\t/* Focus using coords. */\n\tkeys.event.focus( 1, 0, function( node ) {\n\t\tkeys.event.remove.focus( node );\n\t\teventMsg( \"Cell 1,0 focus - this event has now been removed\" );\n\t} );\n\t\n\tkeys.event.focus( 1, 3, function() {\n\t\teventMsg( \"Cell 1,3 focus\" );\n\t} );\n\t\n\t/* focus with a node */\n\tkeys.event.focus( $('#example tbody tr:eq(2) td:eq(0)')[0], function() {\n\t\teventMsg( \"Cell 0,2 focus\" );\n\t} );\n\t\n\t/* Blur using a node */\n\tkeys.event.blur( $('#example tbody tr:eq(1) td:eq(2)')[0], function() {\n\t\teventMsg( \"Cell 1,2 blur\" );\n\t} );\n\t\n\t/* Blur using coords */\n\tkeys.event.blur( 2, 4, function() {\n\t\teventMsg( \"Cell 2,4 blur\" );\n\t} );\n\t\n\t/* Action */\n\tkeys.event.action( 2, 2, function( node ) {\n\t\teventMsg( \"Cell 2,2 action\" );\n\t\tif ( node.style.fontWeight == \"\" || node.style.fontWeight == \"normal\" ) {\n\t\t\tnode.style.fontWeight = \"bold\";\n\t\t}\n\t\telse {\n\t\t\tnode.style.fontWeight = \"normal\";\n\t\t}\n\t} );\n\t\n\tkeys.event.action( 2, 5, function( node ) {\n\t\teventMsg( \"Cell 2,5 action\" );\n\t\tif ( node.style.fontStyle == \"\" ) {\n\t\t\tnode.style.fontStyle = \"italic\";\n\t\t}\n\t\telse {\n\t\t\tnode.style.fontStyle = \"\";\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>KeyTable example <span>Events</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>KeyTable provides the ability to listen for events such as <code>focus</code>, <code>blur</code>,\n\t\t\t\t<code>esc</code> (the escape key) and 'return' (the return key) can be assigned event handling\n\t\t\t\tfunctions through KeyTable's the API. This gives you the ability to take an action on a cell.</p>\n\n\t\t\t\t<p>The example shown below has a few cells (selected at random, but near the top) with blur and focus\n\t\t\t\tevents assigned to them. You can also see the navigation around the table using arrow keys.</p>\n\t\t\t</div>\n\n\t\t\t<div id=\"info\" class=\"box\">\n\t\t\t\tEvent information:<br>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">function eventMsg ( msg ) {\n\tvar n = document.getElementById('info');\n\tn.innerHTML += msg+&quot;&lt;br&gt;&quot;;\n\tn.scrollTop = n.scrollHeight;\n}\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\tvar keys = new $.fn.dataTable.KeyTable( table );\n\n\t/* Focus handler for all cells in last column */\n\tkeys.event.focus( 4, null, function( node, x, y ) {\n\t\teventMsg( &quot;Cell &quot;+x+&quot;,&quot;+y+&quot; focused ('live' event - column)&quot; );\n\t} );\n\t\n\t/* Focus handler for all cells in 8th row */\n\tkeys.event.focus( null, 7, function( node, x, y ) {\n\t\teventMsg( &quot;Cell &quot;+x+&quot;,&quot;+y+&quot; focused ('live' event - row)&quot; );\n\t} );\n\t\n\t/* Focus using coords. */\n\tkeys.event.focus( 1, 0, function( node ) {\n\t\tkeys.event.remove.focus( node );\n\t\teventMsg( &quot;Cell 1,0 focus - this event has now been removed&quot; );\n\t} );\n\t\n\tkeys.event.focus( 1, 3, function() {\n\t\teventMsg( &quot;Cell 1,3 focus&quot; );\n\t} );\n\t\n\t/* focus with a node */\n\tkeys.event.focus( $('#example tbody tr:eq(2) td:eq(0)')[0], function() {\n\t\teventMsg( &quot;Cell 0,2 focus&quot; );\n\t} );\n\t\n\t/* Blur using a node */\n\tkeys.event.blur( $('#example tbody tr:eq(1) td:eq(2)')[0], function() {\n\t\teventMsg( &quot;Cell 1,2 blur&quot; );\n\t} );\n\t\n\t/* Blur using coords */\n\tkeys.event.blur( 2, 4, function() {\n\t\teventMsg( &quot;Cell 2,4 blur&quot; );\n\t} );\n\t\n\t/* Action */\n\tkeys.event.action( 2, 2, function( node ) {\n\t\teventMsg( &quot;Cell 2,2 action&quot; );\n\t\tif ( node.style.fontWeight == &quot;&quot; || node.style.fontWeight == &quot;normal&quot; ) {\n\t\t\tnode.style.fontWeight = &quot;bold&quot;;\n\t\t}\n\t\telse {\n\t\t\tnode.style.fontWeight = &quot;normal&quot;;\n\t\t}\n\t} );\n\t\n\tkeys.event.action( 2, 5, function( node ) {\n\t\teventMsg( &quot;Cell 2,5 action&quot; );\n\t\tif ( node.style.fontStyle == &quot;&quot; ) {\n\t\t\tnode.style.fontStyle = &quot;italic&quot;;\n\t\t}\n\t\telse {\n\t\t\tnode.style.fontStyle = &quot;&quot;;\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.keyTable.js\">../js/dataTables.keyTable.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.keyTable.css\">../css/dataTables.keyTable.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./events.html\">Events</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./html.html\">Plain HTML table</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/KeyTable/examples/html.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>KeyTable example - Plain HTML table</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.keyTable.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.keyTable.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').addClass('KeyTable');\n\tnew $.fn.dataTable.KeyTable();\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>KeyTable example <span>Plain HTML table</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>As well as being usable with DataTables, KeyTable can also be used with a plain HTML table. Please\n\t\t\t\tnote that this ability is deprecated and will be removed in KeyTable 1.3.</p>\n\n\t\t\t\t<p>This example shows KeyTable being initialised without any parameter, which instructs it to search\n\t\t\t\tfor any table with the class <code>KeyTable</code> which will be used.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\t$('#example').addClass('KeyTable');\n\tnew $.fn.dataTable.KeyTable();\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.keyTable.js\">../js/dataTables.keyTable.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.keyTable.css\">../css/dataTables.keyTable.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./events.html\">Events</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./html.html\">Plain HTML table</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/KeyTable/examples/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\n\t<title>KeyTable examples - KeyTable examples</title>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>KeyTable example <span>KeyTable examples</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>KeyTable provides enhanced accessibility and navigation options for DataTables enhanced tables, by\n\t\t\t\tallowing Excel like cell navigation on any table. Events (focus, blur, action etc) can be assigned to\n\t\t\t\tindividual cells, columns, rows or all cells to allow advanced interaction options.. Key features\n\t\t\t\tinclude:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li>Easy to use spreadsheet like interaction</li>\n\t\t\t\t\t<li>Fully integrated with DataTables</li>\n\t\t\t\t\t<li>Wide range of supported events</li>\n\t\t\t\t\t<li>Works without DataTables if you just want a plain table</li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./events.html\">Events</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./html.html\">Plain HTML table</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/KeyTable/examples/scrolling.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>KeyTable example - Scrolling table</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.keyTable.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.keyTable.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY: 300,\n\t\tpaging: false\n\t} );\n\n\tnew $.fn.dataTable.KeyTable( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>KeyTable example <span>Scrolling table</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>KeyTable supports DataTables' scrolling options (<a href=\n\t\t\t\t\"//datatables.net/reference/option/scrollX\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">scrollX<span>DT</span></code></a> and <a href=\n\t\t\t\t\"//datatables.net/reference/option/scrollY\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">scrollY<span>DT</span></code></a>) without required any additional\n\t\t\t\tconfiguration. As the navigation keys are used to alter the focus of the KeyTable, the DataTables\n\t\t\t\tscrolling position is altered to show the focused cell.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY: 300,\n\t\tpaging: false\n\t} );\n\n\tnew $.fn.dataTable.KeyTable( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.keyTable.js\">../js/dataTables.keyTable.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.keyTable.css\">../css/dataTables.keyTable.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./events.html\">Events</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./html.html\">Plain HTML table</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/KeyTable/examples/simple.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>KeyTable example - Basic initialisation</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.keyTable.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.keyTable.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.KeyTable( table );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>KeyTable example <span>Basic initialisation</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>KeyTable allows you to use keyboard navigation on a DataTables enhanced table, like an Excel\n\t\t\t\tspreadsheet. The focused cell is shown through the CSS class ('focus') which in the case below is\n\t\t\t\tsimply a blue border. Use your keyboard's arrow keys and click the cells in the table to navigate.</p>\n\n\t\t\t\t<p>This example simply shows key table being initialised on a DataTable, but <a href=\n\t\t\t\t\"events.html\">events</a> can be listened for through the KeyTable API which provide interaction\n\t\t\t\toptions.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.KeyTable( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.keyTable.js\">../js/dataTables.keyTable.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.keyTable.css\">../css/dataTables.keyTable.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./events.html\">Events</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Scrolling table</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./html.html\">Plain HTML table</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/KeyTable/js/dataTables.keyTable.js",
    "content": "/*! KeyTable 1.2.1\n * ©2010-2014 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary     KeyTable\n * @description Spreadsheet like keyboard navigation for DataTables\n * @version     1.2.1\n * @file        dataTables.keyTable.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2009-2014 SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n *   MIT license - http://datatables.net/license/mit\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n// Global scope for KeyTable for backwards compatibility. Will be removed in 1.3\nvar KeyTable;\n\n\n(function(window, document, undefined) {\n\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\nKeyTable = function ( oInit )\n{\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * API parameters\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/*\n\t * Variable: block\n\t * Purpose:  Flag whether or not KeyTable events should be processed\n\t * Scope:    KeyTable - public\n\t */\n\tthis.block = false;\n\n\t/*\n\t * Variable: event\n\t * Purpose:  Container for all event application methods\n\t * Scope:    KeyTable - public\n\t * Notes:    This object contains all the public methods for adding and removing events - these\n\t *           are dynamically added later on\n\t */\n\tthis.event = {\n\t\t\"remove\": {}\n\t};\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * API methods\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/*\n\t * Function: fnGetCurrentPosition\n\t * Purpose:  Get the currently focused cell's position\n\t * Returns:  array int: [ x, y ]\n\t * Inputs:   void\n\t */\n\tthis.fnGetCurrentPosition = function ()\n\t{\n\t\treturn [ _iOldX, _iOldY ];\n\t};\n\n\n\t/*\n\t * Function: fnGetCurrentData\n\t * Purpose:  Get the currently focused cell's data (innerHTML)\n\t * Returns:  string: - data requested\n\t * Inputs:   void\n\t */\n\tthis.fnGetCurrentData = function ()\n\t{\n\t\treturn _nOldFocus.innerHTML;\n\t};\n\n\n\t/*\n\t * Function: fnGetCurrentTD\n\t * Purpose:  Get the currently focused cell\n\t * Returns:  node: - focused element\n\t * Inputs:   void\n\t */\n\tthis.fnGetCurrentTD = function ()\n\t{\n\t\treturn _nOldFocus;\n\t};\n\n\n\t/*\n\t * Function: fnSetPosition\n\t * Purpose:  Set the position of the focused cell\n\t * Returns:  -\n\t * Inputs:   int:x - x coordinate\n\t *           int:y - y coordinate\n\t * Notes:    Thanks to Rohan Daxini for the basis of this function\n\t */\n\tthis.fnSetPosition = function( x, y )\n\t{\n\t\tif ( typeof x == 'object' && x.nodeName )\n\t\t{\n\t\t\t_fnSetFocus( x );\n\t\t}\n\t\telse\n\t\t{\n\t\t\t_fnSetFocus( _fnCellFromCoords(x, y) );\n\t\t}\n\t};\n\n\n\t/*\n\t * Function: fnBlur\n\t * Purpose:  Blur the current focus\n\t * Returns:  -\n\t * Inputs:   -\n\t */\n\tthis.fnBlur = function()\n\t{\n\t\t_fnBlur();\n\t};\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Private parameters\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/*\n\t * Variable: _nBody\n\t * Purpose:  Body node of the table - cached for renference\n\t * Scope:    KeyTable - private\n\t */\n\tvar _nBody = null;\n\n\t/*\n\t * Variable: \n\t * Purpose:  \n\t * Scope:    KeyTable - private\n\t */\n\tvar _nOldFocus = null;\n\n\t/*\n\t * Variable: _iOldX and _iOldY\n\t * Purpose:  X and Y coords of the old elemet that was focused on\n\t * Scope:    KeyTable - private\n\t */\n\tvar _iOldX = null;\n\tvar _iOldY = null;\n\n\t/*\n\t * Variable: _that\n\t * Purpose:  Scope saving for 'this' after a jQuery event\n\t * Scope:    KeyTable - private\n\t */\n\tvar _that = null;\n\n\t/*\n\t * Variable: sFocusClass\n\t * Purpose:  Class that should be used for focusing on a cell\n\t * Scope:    KeyTable - private\n\t */\n\tvar _sFocusClass = \"focus\";\n\n\t/*\n\t * Variable: _bKeyCapture\n\t * Purpose:  Flag for should KeyTable capture key events or not\n\t * Scope:    KeyTable - private\n\t */\n\tvar _bKeyCapture = false;\n\n\t/*\n\t * Variable: _oaoEvents\n\t * Purpose:  Event cache object, one array for each supported event for speed of searching\n\t * Scope:    KeyTable - private\n\t */\n\tvar _oaoEvents = {\n\t\t\"action\": [],\n\t\t\"esc\": [],\n\t\t\"focus\": [],\n\t\t\"blur\": []\n\t};\n\n\t/*\n\t * Variable: _oDatatable\n\t * Purpose:  DataTables settings object for if we are actually using a \n\t *           DataTables table\n\t * Scope:    KeyTable - private\n\t */\n\tvar _oDatatable = null;\n\n\tvar _bForm;\n\tvar _nInput;\n\tvar _bInputFocused = false;\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Private methods\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Key table events\n\t */\n\n\t/*\n\t * Function: _fnEventAddTemplate\n\t * Purpose:  Create a function (with closure for sKey) event addition API\n\t * Returns:  function: - template function\n\t * Inputs:   string:sKey - type of event to detect\n\t */\n\tfunction _fnEventAddTemplate( sKey )\n\t{\n\t\t/*\n\t\t * Function: -\n\t\t * Purpose:  API function for adding event to cache\n\t\t * Returns:  -\n\t\t * Inputs:   1. node:x - target node to add event for\n\t\t *           2. function:y - callback function to apply\n\t\t *         or\n\t\t *           1. int:x - x coord. of target cell (can be null for live events)\n\t\t *           2. int:y - y coord. of target cell (can be null for live events)\n\t\t *           3. function:z - callback function to apply\n\t\t * Notes:    This function is (interally) overloaded (in as much as javascript allows for\n\t\t *           that) - the target cell can be given by either node or coords.\n\t\t */\n\t\treturn function ( x, y, z ) {\n\t\t\tif ( (x===null || typeof x == \"number\") &&\n\t\t\t\t (y===null || typeof y == \"number\") &&\n\t\t\t\t typeof z == \"function\" )\n\t\t\t{\n\t\t\t\t_fnEventAdd( sKey, x, y, z );\n\t\t\t}\n\t\t\telse if ( typeof x == \"object\" && typeof y == \"function\" )\n\t\t\t{\n\t\t\t\tvar aCoords = _fnCoordsFromCell( x );\n\t\t\t\t_fnEventAdd( sKey, aCoords[0], aCoords[1], y );\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\talert( \"Unhandable event type was added: x\" +x+ \"  y:\" +y+ \"  z:\" +z );\n\t\t\t}\n\t\t};\n\t}\n\n\n\t/*\n\t * Function: _fnEventRemoveTemplate\n\t * Purpose:  Create a function (with closure for sKey) event removal API\n\t * Returns:  function: - template function\n\t * Inputs:   string:sKey - type of event to detect\n\t */\n\tfunction _fnEventRemoveTemplate( sKey )\n\t{\n\t\t/*\n\t\t * Function: -\n\t\t * Purpose:  API function for removing event from cache\n\t\t * Returns:  int: - number of events removed\n\t\t * Inputs:   1. node:x - target node to remove event from\n\t\t *           2. function:y - callback function to apply\n\t\t *         or\n\t\t *           1. int:x - x coord. of target cell (can be null for live events)\n\t\t *           2. int:y - y coord. of target cell (can be null for live events)\n\t\t *           3. function:z - callback function to remove - optional\n\t\t * Notes:    This function is (interally) overloaded (in as much as javascript allows for\n\t\t *           that) - the target cell can be given by either node or coords and the function\n\t\t *           to remove is optional\n\t\t */\n\t\treturn function ( x, y, z ) {\n\t\t\tif ( (x===null || typeof arguments[0] == \"number\") &&\n\t\t\t\t (y===null || typeof arguments[1] == \"number\" ) )\n\t\t\t{\n\t\t\t\tif ( typeof arguments[2] == \"function\" )\n\t\t\t\t{\n\t\t\t\t\t_fnEventRemove( sKey, x, y, z );\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t_fnEventRemove( sKey, x, y );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( typeof arguments[0] == \"object\" )\n\t\t\t{\n\t\t\t\tvar aCoords = _fnCoordsFromCell( x );\n\t\t\t\tif ( typeof arguments[1] == \"function\" )\n\t\t\t\t{\n\t\t\t\t\t_fnEventRemove( sKey, aCoords[0], aCoords[1], y );\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t_fnEventRemove( sKey, aCoords[0], aCoords[1] );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\talert( \"Unhandable event type was removed: x\" +x+ \"  y:\" +y+ \"  z:\" +z );\n\t\t\t}\n\t\t};\n\t}\n\n\t/* Use the template functions to add the event API functions */\n\tfor ( var sKey in _oaoEvents )\n\t{\n\t\tif ( sKey )\n\t\t{\n\t\t\tthis.event[sKey] = _fnEventAddTemplate( sKey );\n\t\t\tthis.event.remove[sKey] = _fnEventRemoveTemplate( sKey );\n\t\t}\n\t}\n\n\n\t/*\n\t * Function: _fnEventAdd\n\t * Purpose:  Add an event to the internal cache\n\t * Returns:  -\n\t * Inputs:   string:sType - type of event to add, given by the available elements in _oaoEvents\n\t *           int:x - x-coords to add event to - can be null for \"blanket\" event\n\t *           int:y - y-coords to add event to - can be null for \"blanket\" event\n\t *           function:fn - callback function for when triggered\n\t */\n\tfunction _fnEventAdd( sType, x, y, fn )\n\t{\n\t\t_oaoEvents[sType].push( {\n\t\t\t\"x\": x,\n\t\t\t\"y\": y,\n\t\t\t\"fn\": fn\n\t\t} );\n\t}\n\n\n\t/*\n\t * Function: _fnEventRemove\n\t * Purpose:  Remove an event from the event cache\n\t * Returns:  int: - number of matching events removed\n\t * Inputs:   string:sType - type of event to look for\n\t *           node:nTarget - target table cell\n\t *           function:fn - optional - remove this function. If not given all handlers of this\n\t *             type will be removed\n\t */\n\tfunction _fnEventRemove( sType, x, y, fn )\n\t{\n\t\tvar iCorrector = 0;\n\n\t\tfor ( var i=0, iLen=_oaoEvents[sType].length ; i<iLen-iCorrector ; i++ )\n\t\t{\n\t\t\tif ( typeof fn != 'undefined' )\n\t\t\t{\n\t\t\t\tif ( _oaoEvents[sType][i-iCorrector].x == x &&\n\t\t\t\t\t _oaoEvents[sType][i-iCorrector].y == y &&\n\t\t\t\t\t   _oaoEvents[sType][i-iCorrector].fn == fn )\n\t\t\t\t{\n\t\t\t\t\t_oaoEvents[sType].splice( i-iCorrector, 1 );\n\t\t\t\t\tiCorrector++;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif ( _oaoEvents[sType][i-iCorrector].x == x &&\n\t\t\t\t\t _oaoEvents[sType][i-iCorrector].y == y )\n\t\t\t\t{\n\t\t\t\t\t_oaoEvents[sType].splice( i, 1 );\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn iCorrector;\n\t}\n\n\n\t/*\n\t * Function: _fnEventFire\n\t * Purpose:  Look thought the events cache and fire off the event of interest\n\t * Returns:  int:iFired - number of events fired\n\t * Inputs:   string:sType - type of event to look for\n\t *           int:x - x coord of cell\n\t *           int:y - y coord of  ell\n\t * Notes:    It might be more efficient to return after the first event has been tirggered,\n\t *           but that would mean that only one function of a particular type can be\n\t *           subscribed to a particular node.\n\t */\n\tfunction _fnEventFire ( sType, x, y )\n\t{\n\t\tvar iFired = 0;\n\t\tvar aEvents = _oaoEvents[sType];\n\t\tfor ( var i=0 ; i<aEvents.length ; i++ )\n\t\t{\n\t\t\tif ( (aEvents[i].x == x     && aEvents[i].y == y    ) ||\n\t\t\t\t (aEvents[i].x === null && aEvents[i].y == y    ) ||\n\t\t\t\t (aEvents[i].x == x     && aEvents[i].y === null ) ||\n\t\t\t\t (aEvents[i].x === null && aEvents[i].y === null )\n\t\t\t)\n\t\t\t{\n\t\t\t\taEvents[i].fn( _fnCellFromCoords(x,y), x, y );\n\t\t\t\tiFired++;\n\t\t\t}\n\t\t}\n\t\treturn iFired;\n\t}\n\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Focus functions\n\t */\n\n\t/*\n\t * Function: _fnSetFocus\n\t * Purpose:  Set focus on a node, and remove from an old node if needed\n\t * Returns:  -\n\t * Inputs:   node:nTarget - node we want to focus on\n\t *           bool:bAutoScroll - optional - should we scroll the view port to the display\n\t */\n\tfunction _fnSetFocus( nTarget, bAutoScroll )\n\t{\n\t\t/* If node already has focus, just ignore this call */\n\t\tif ( _nOldFocus == nTarget )\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\tif ( typeof bAutoScroll == 'undefined' )\n\t\t{\n\t\t\tbAutoScroll = true;\n\t\t}\n\n\t\t/* Remove old focus (with blur event if needed) */\n\t\tif ( _nOldFocus !== null )\n\t\t{\n\t\t\t_fnRemoveFocus( _nOldFocus );\n\t\t}\n\n\t\t/* Add the new class to highlight the focused cell */\n\t\t$(nTarget).addClass( _sFocusClass );\n\t\t$(nTarget).parent().addClass( _sFocusClass );\n\n\t\t/* If it's a DataTable then we need to jump the paging to the relevant page */\n\t\tvar oSettings;\n\t\tif ( _oDatatable )\n\t\t{\n\t\t\toSettings = _oDatatable;\n\t\t\tvar iRow = _fnFindDtCell( nTarget )[1];\n\t\t\tvar bKeyCaptureCache = _bKeyCapture;\n\n\t\t\t/* Page forwards */\n\t\t\twhile ( iRow >= oSettings.fnDisplayEnd() )\n\t\t\t{\n\t\t\t\tif ( oSettings._iDisplayLength >= 0 )\n\t\t\t\t{\n\t\t\t\t\t/* Make sure we are not over running the display array */\n\t\t\t\t\tif ( oSettings._iDisplayStart + oSettings._iDisplayLength < oSettings.fnRecordsDisplay() )\n\t\t\t\t\t{\n\t\t\t\t\t\toSettings._iDisplayStart += oSettings._iDisplayLength;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\toSettings._iDisplayStart = 0;\n\t\t\t\t}\n\t\t\t\t_oDatatable.oApi._fnCalculateEnd( oSettings );\n\t\t\t}\n\n\t\t\t/* Page backwards */\n\t\t\twhile ( iRow < oSettings._iDisplayStart )\n\t\t\t{\n\t\t\t\toSettings._iDisplayStart = oSettings._iDisplayLength>=0 ?\n\t\t\t\t\toSettings._iDisplayStart - oSettings._iDisplayLength :\n\t\t\t\t\t0;\n\n\t\t\t\tif ( oSettings._iDisplayStart < 0 )\n\t\t\t\t{\n\t\t\t\t  oSettings._iDisplayStart = 0;\n\t\t\t\t}\n\t\t\t\t_oDatatable.oApi._fnCalculateEnd( oSettings );\n\t\t\t}\n\n\t\t\t/* Re-draw the table */\n\t\t\t_oDatatable.oApi._fnDraw( oSettings );\n\n\t\t\t/* Restore the key capture */\n\t\t\t_bKeyCapture = bKeyCaptureCache;\n\t\t}\n\n\t\t/* Cache the information that we are interested in */\n\t\tvar aNewPos = _fnCoordsFromCell( nTarget );\n\t\t_nOldFocus = nTarget;\n\t\t_iOldX = aNewPos[0];\n\t\t_iOldY = aNewPos[1];\n\n\t\tvar iViewportHeight, iViewportWidth, iScrollTop, iScrollLeft, iHeight, iWidth, aiPos;\n\t\tif ( bAutoScroll )\n\t\t{\n\t\t\t/* Scroll the viewport such that the new cell is fully visible in the rendered window */\n\t\t\tiViewportHeight = $(window).height();\n\t\t\tiViewportWidth = $(window).width();\n\t\t\tiScrollTop = $(document).scrollTop();\n\t\t\tiScrollLeft = $(document).scrollLeft();\n\t\t\tiHeight = nTarget.offsetHeight;\n\t\t\tiWidth = nTarget.offsetWidth;\n\t\t\taiPos = _fnGetPos( nTarget );\n\n\t\t\t/* Take account of scrolling in DataTables 1.7 - remove scrolling since that would add to\n\t\t\t * the positioning calculation\n\t\t\t */\n\t\t\tif ( _oDatatable && typeof oSettings.oScroll != 'undefined' &&\n\t\t\t  (oSettings.oScroll.sX !== \"\" || oSettings.oScroll.sY !== \"\") )\n\t\t\t{\n\t\t\t\taiPos[1] -= $(oSettings.nTable.parentNode).scrollTop();\n\t\t\t\taiPos[0] -= $(oSettings.nTable.parentNode).scrollLeft();\n\t\t\t}\n\n\t\t\t/* Correct viewport positioning for vertical scrolling */\n\t\t\tif ( aiPos[1]+iHeight > iScrollTop+iViewportHeight )\n\t\t\t{\n\t\t\t\t/* Displayed element if off the bottom of the viewport */\n\t\t\t\t_fnSetScrollTop( aiPos[1]+iHeight - iViewportHeight );\n\t\t\t}\n\t\t\telse if ( aiPos[1] < iScrollTop )\n\t\t\t{\n\t\t\t\t/* Displayed element if off the top of the viewport */\n\t\t\t\t_fnSetScrollTop( aiPos[1] );\n\t\t\t}\n\n\t\t\t/* Correct viewport positioning for horizontal scrolling */\n\t\t\tif ( aiPos[0]+iWidth > iScrollLeft+iViewportWidth )\n\t\t\t{\n\t\t\t\t/* Displayed element is off the bottom of the viewport */\n\t\t\t\t_fnSetScrollLeft( aiPos[0]+iWidth - iViewportWidth );\n\t\t\t}\n\t\t\telse if ( aiPos[0] < iScrollLeft )\n\t\t\t{\n\t\t\t\t/* Displayed element if off the Left of the viewport */\n\t\t\t\t_fnSetScrollLeft( aiPos[0] );\n\t\t\t}\n\t\t}\n\n\t\t/* Take account of scrolling in DataTables 1.7 */\n\t\tif ( _oDatatable && typeof oSettings.oScroll != 'undefined' &&\n\t\t  (oSettings.oScroll.sX !== \"\" || oSettings.oScroll.sY !== \"\") )\n\t\t{\n\t\t\tvar dtScrollBody = oSettings.nTable.parentNode;\n\t\t\tiViewportHeight = dtScrollBody.clientHeight;\n\t\t\tiViewportWidth = dtScrollBody.clientWidth;\n\t\t\tiScrollTop = dtScrollBody.scrollTop;\n\t\t\tiScrollLeft = dtScrollBody.scrollLeft;\n\t\t\tiHeight = nTarget.offsetHeight;\n\t\t\tiWidth = nTarget.offsetWidth;\n\n\t\t\t/* Correct for vertical scrolling */\n\t\t\tif ( nTarget.offsetTop + iHeight > iViewportHeight+iScrollTop )\n\t\t\t{\n\t\t\t\tdtScrollBody.scrollTop = (nTarget.offsetTop + iHeight) - iViewportHeight;\n\t\t\t}\n\t\t\telse if ( nTarget.offsetTop < iScrollTop )\n\t\t\t{\n\t\t\t\tdtScrollBody.scrollTop = nTarget.offsetTop;\n\t\t\t}\n\n\t\t\t/* Correct for horizontal scrolling */\n\t\t\tif ( nTarget.offsetLeft + iWidth > iViewportWidth+iScrollLeft )\n\t\t\t{\n\t\t\t\tdtScrollBody.scrollLeft = (nTarget.offsetLeft + iWidth) - iViewportWidth;\n\t\t\t}\n\t\t\telse if ( nTarget.offsetLeft < iScrollLeft )\n\t\t\t{\n\t\t\t\tdtScrollBody.scrollLeft = nTarget.offsetLeft;\n\t\t\t}\n\t\t}\n\n\t\t/* Focused - so we want to capture the keys */\n\t\t_fnCaptureKeys();\n\n\t\t/* Fire of the focus event if there is one */\n\t\t_fnEventFire( \"focus\", _iOldX, _iOldY );\n\t}\n\n\n\t/*\n\t * Function: _fnBlur\n\t * Purpose:  Blur focus from the whole table\n\t * Returns:  -\n\t * Inputs:   -\n\t */\n\tfunction _fnBlur()\n\t{\n\t\t_fnRemoveFocus( _nOldFocus );\n\t\t_iOldX = null;\n\t\t_iOldY = null;\n\t\t_nOldFocus = null;\n\t\t_fnReleaseKeys();\n\t}\n\n\n\t/*\n\t * Function: _fnRemoveFocus\n\t * Purpose:  Remove focus from a cell and fire any blur events which are attached\n\t * Returns:  -\n\t * Inputs:   node:nTarget - cell of interest\n\t */\n\tfunction _fnRemoveFocus( nTarget )\n\t{\n\t\t$(nTarget).removeClass( _sFocusClass );\n\t\t$(nTarget).parent().removeClass( _sFocusClass );\n\t\t_fnEventFire( \"blur\", _iOldX, _iOldY );\n\t}\n\n\n\t/*\n\t * Function: _fnClick\n\t * Purpose:  Focus on the element that has been clicked on by the user\n\t * Returns:  -\n\t * Inputs:   event:e - click event\n\t */\n\tfunction _fnClick ( e )\n\t{\n\t\tvar nTarget = this;\n\t\twhile ( nTarget.nodeName != \"TD\" )\n\t\t{\n\t\t\tnTarget = nTarget.parentNode;\n\t\t}\n\n\t\t_fnSetFocus( nTarget );\n\t\t_fnCaptureKeys();\n\t}\n\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Key events\n\t */\n\n\t/*\n\t * Function: _fnKey\n\t * Purpose:  Deal with a key events, be it moving the focus or return etc.\n\t * Returns:  bool: - allow browser default action\n\t * Inputs:   event:e - key event\n\t */\n\tfunction _fnKey ( e )\n\t{\n\t\t/* If user or system has blocked KeyTable from doing anything, just ignore this event */\n\t\tif ( _that.block || !_bKeyCapture )\n\t\t{\n\t\t\treturn true;\n\t\t}\n\n\t\t/* If a modifier key is pressed (exapct shift), ignore the event */\n\t\tif ( e.metaKey || e.altKey || e.ctrlKey )\n\t\t{\n\t\t\treturn true;\n\t\t}\n\t\tvar\n\t\t\tx, y,\n\t\t\tiTableWidth = _nBody.getElementsByTagName('tr')[0].getElementsByTagName('td').length,\n\t\t\tiTableHeight;\n\n\t\t/* Get table height and width - done here so as to be dynamic (if table is updated) */\n\t\tif ( _oDatatable )\n\t\t{\n\t\t\t/* \n\t\t\t * Locate the current node in the DataTable overriding the old positions - the reason for\n\t\t\t * is is that there might have been some DataTables interaction between the last focus and\n\t\t\t * now\n\t\t\t */\n\t\t\tiTableHeight = _oDatatable.aiDisplay.length;\n\n\t\t\tvar aDtPos = _fnFindDtCell( _nOldFocus );\n\t\t\tif ( aDtPos === null )\n\t\t\t{\n\t\t\t\t/* If the table has been updated such that the focused cell can't be seen - do nothing */\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t_iOldX = aDtPos[ 0 ];\n\t\t\t_iOldY = aDtPos[ 1 ];\n\t\t}\n\t\telse\n\t\t{\n\t\t\tiTableHeight = _nBody.getElementsByTagName('tr').length;\n\t\t}\n\n\t\t/* Capture shift+tab to match the left arrow key */\n\t\tvar iKey = (e.keyCode == 9 && e.shiftKey) ? -1 : e.keyCode;\n\n\t\tswitch( iKey )\n\t\t{\n\t\t\tcase 13: /* return */\n\t\t\t\te.preventDefault();\n\t\t\t\te.stopPropagation();\n\t\t\t\t_fnEventFire( \"action\", _iOldX, _iOldY );\n\t\t\t\treturn true;\n\n\t\t\tcase 27: /* esc */\n\t\t\t\tif ( !_fnEventFire( \"esc\", _iOldX, _iOldY ) )\n\t\t\t\t{\n\t\t\t\t\t/* Only lose focus if there isn't an escape handler on the cell */\n\t\t\t\t\t_fnBlur();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tx = _iOldX;\n\t\t\t\ty = _iOldY;\n\t\t\t\tbreak;\n\n\t\t\tcase -1:\n\t\t\tcase 37: /* left arrow */\n\t\t\t\tif ( _iOldX > 0 ) {\n\t\t\t\t\tx = _iOldX - 1;\n\t\t\t\t\ty = _iOldY;\n\t\t\t\t} else if ( _iOldY > 0 ) {\n\t\t\t\t\tx = iTableWidth-1;\n\t\t\t\t\ty = _iOldY - 1;\n\t\t\t\t} else {\n\t\t\t\t\t/* at start of table */\n\t\t\t\t\tif ( iKey == -1 && _bForm )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* If we are in a form, return focus to the 'input' element such that tabbing will\n\t\t\t\t\t\t * follow correctly in the browser\n\t\t\t\t\t\t */\n\t\t\t\t\t\t_bInputFocused = true;\n\t\t\t\t\t\t_nInput.focus();\n\n\t\t\t\t\t\t/* This timeout is a little nasty - but IE appears to have some asyhnc behaviour for \n\t\t\t\t\t\t * focus\n\t\t\t\t\t\t */\n\t\t\t\t\t\tsetTimeout( function(){ _bInputFocused = false; }, 0 );\n\t\t\t\t\t\t_bKeyCapture = false;\n\t\t\t\t\t\t_fnBlur();\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 38: /* up arrow */\n\t\t\t\tif ( _iOldY > 0 ) {\n\t\t\t\t\tx = _iOldX;\n\t\t\t\t\ty = _iOldY - 1;\n\t\t\t\t} else {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 36: /* home */\n\t\t\t\tx = _iOldX;\n\t\t\t\ty = 0;\n\t\t\t\tbreak;\n\n\t\t\tcase 33: /* page up */\n\t\t\t\tx = _iOldX;\n\t\t\t\ty = _iOldY - 10;\n\t\t\t\tif (y < 0) {\n\t\t\t\t\ty = 0;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 9: /* tab */\n\t\t\tcase 39: /* right arrow */\n\t\t\t\tif ( _iOldX < iTableWidth-1 ) {\n\t\t\t\t\tx = _iOldX + 1;\n\t\t\t\t\ty = _iOldY;\n\t\t\t\t} else if ( _iOldY < iTableHeight-1 ) {\n\t\t\t\t\tx = 0;\n\t\t\t\t\ty = _iOldY + 1;\n\t\t\t\t} else {\n\t\t\t\t\t/* at end of table */\n\t\t\t\t\tif ( iKey == 9 && _bForm )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* If we are in a form, return focus to the 'input' element such that tabbing will\n\t\t\t\t\t\t * follow correctly in the browser\n\t\t\t\t\t\t */\n\t\t\t\t\t\t_bInputFocused = true;\n\t\t\t\t\t\t_nInput.focus();\n\n\t\t\t\t\t\t/* This timeout is a little nasty - but IE appears to have some asyhnc behaviour for \n\t\t\t\t\t\t * focus\n\t\t\t\t\t\t */\n\t\t\t\t\t\tsetTimeout( function(){ _bInputFocused = false; }, 0 );\n\t\t\t\t\t\t_bKeyCapture = false;\n\t\t\t\t\t\t_fnBlur();\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 40: /* down arrow */\n\t\t\t\tif ( _iOldY < iTableHeight-1 ) {\n\t\t\t\t\tx = _iOldX;\n\t\t\t\t\ty = _iOldY + 1;\n\t\t\t\t} else {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 35: /* end */\n\t\t\t\tx = _iOldX;\n\t\t\t\ty = iTableHeight-1;\n\t\t\t\tbreak;\n\n\t\t\tcase 34: /* page down */\n\t\t\t\tx = _iOldX;\n\t\t\t\ty = _iOldY+10;\n\t\t\t\tif (y > iTableHeight-1) {\n\t\t\t\t\ty = iTableHeight-1;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault: /* Nothing we are interested in */\n\t\t\t\treturn true;\n\t\t}\n\n\t\t_fnSetFocus( _fnCellFromCoords(x, y) );\n\t\treturn false;\n\t}\n\n\n\t/*\n\t * Function: _fnCaptureKeys\n\t * Purpose:  Start capturing key events for this table\n\t * Returns:  -\n\t * Inputs:   -\n\t */\n\tfunction _fnCaptureKeys( )\n\t{\n\t\tif ( !_bKeyCapture )\n\t\t{\n\t\t\t_bKeyCapture = true;\n\t\t}\n\t}\n\n\n\t/*\n\t * Function: _fnReleaseKeys\n\t * Purpose:  Stop capturing key events for this table\n\t * Returns:  -\n\t * Inputs:   -\n\t */\n\tfunction _fnReleaseKeys( )\n\t{\n\t\t_bKeyCapture = false;\n\t}\n\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Support functions\n\t */\n\n\t/*\n\t * Function: _fnCellFromCoords\n\t * Purpose:  Calulate the target TD cell from x and y coordinates\n\t * Returns:  node: - TD target\n\t * Inputs:   int:x - x coordinate\n\t *           int:y - y coordinate\n\t */\n\tfunction _fnCellFromCoords( x, y )\n\t{\n\t\tif ( _oDatatable )\n\t\t{\n\t\t\tif ( typeof _oDatatable.aoData[ _oDatatable.aiDisplay[ y ] ] != 'undefined' )\n\t\t\t{\n\t\t\t\treturn _oDatatable.aoData[ _oDatatable.aiDisplay[ y ] ].nTr.getElementsByTagName('td')[x];\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn $('tr:eq('+y+')>td:eq('+x+')', _nBody )[0];\n\t\t}\n\t}\n\n\n\t/*\n\t * Function: _fnCoordsFromCell\n\t * Purpose:  Calculate the x and y position in a table from a TD cell\n\t * Returns:  array[2] int: [x, y]\n\t * Inputs:   node:n - TD cell of interest\n\t * Notes:    Not actually interested in this for DataTables since it might go out of date\n\t */\n\tfunction _fnCoordsFromCell( n )\n\t{\n\t\tif ( _oDatatable )\n\t\t{\n\t\t\treturn [\n\t\t\t\t$('td', n.parentNode).index(n),\n\t\t\t\t$('tr', n.parentNode.parentNode).index(n.parentNode) + _oDatatable._iDisplayStart\n\t\t\t];\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn [\n\t\t\t\t$('td', n.parentNode).index(n),\n\t\t\t\t$('tr', n.parentNode.parentNode).index(n.parentNode)\n\t\t\t];\n\t\t}\n\t}\n\n\n\t/*\n\t * Function: _fnSetScrollTop\n\t * Purpose:  Set the vertical scrolling position\n\t * Returns:  -\n\t * Inputs:   int:iPos - scrolltop\n\t * Notes:    This is so nasty, but without browser detection you can't tell which you should set\n\t *           So on browsers that support both, the scroll top will be set twice. I can live with\n\t *           that :-)\n\t */\n\tfunction _fnSetScrollTop( iPos )\n\t{\n\t\tdocument.documentElement.scrollTop = iPos;\n\t\tdocument.body.scrollTop = iPos;\n\t}\n\n\n\t/*\n\t * Function: _fnSetScrollLeft\n\t * Purpose:  Set the horizontal scrolling position\n\t * Returns:  -\n\t * Inputs:   int:iPos - scrollleft\n\t */\n\tfunction _fnSetScrollLeft( iPos )\n\t{\n\t\tdocument.documentElement.scrollLeft = iPos;\n\t\tdocument.body.scrollLeft = iPos;\n\t}\n\n\n\t/*\n\t * Function: _fnGetPos\n\t * Purpose:  Get the position of an object on the rendered page\n\t * Returns:  array[2] int: [left, right]\n\t * Inputs:   node:obj - element of interest\n\t */\n\tfunction _fnGetPos ( obj )\n\t{\n\t\tvar iLeft = 0;\n\t\tvar iTop = 0;\n\n\t\tif (obj.offsetParent)\n\t\t{\n\t\t\tiLeft = obj.offsetLeft;\n\t\t\tiTop = obj.offsetTop;\n\t\t\tobj = obj.offsetParent;\n\t\t\twhile (obj)\n\t\t\t{\n\t\t\t\tiLeft += obj.offsetLeft;\n\t\t\t\tiTop += obj.offsetTop;\n\t\t\t\tobj = obj.offsetParent;\n\t\t\t}\n\t\t}\n\t\treturn [iLeft,iTop];\n\t}\n\n\n\t/*\n\t * Function: _fnFindDtCell\n\t * Purpose:  Get the coords. of a cell from the DataTables internal information\n\t * Returns:  array[2] int: [x, y] coords. or null if not found\n\t * Inputs:   node:nTarget - the node of interest\n\t */\n\tfunction _fnFindDtCell( nTarget )\n\t{\n\t\tfor ( var i=0, iLen=_oDatatable.aiDisplay.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tvar nTr = _oDatatable.aoData[ _oDatatable.aiDisplay[i] ].nTr;\n\t\t\tvar nTds = nTr.getElementsByTagName('td');\n\t\t\tfor ( var j=0, jLen=nTds.length ; j<jLen ; j++ )\n\t\t\t{\n\t\t\t\tif ( nTds[j] == nTarget )\n\t\t\t\t{\n\t\t\t\t\treturn [ j, i ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\n\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Initialisation\n\t */\n\n\t/*\n\t * Function: _fnInit\n\t * Purpose:  Initialise the KeyTable\n\t * Returns:  -\n\t * Inputs:   object:oInit - optional - Initalisation object with the following parameters:\n\t *   array[2] int:focus - x and y coordinates of the initial target\n\t *     or\n\t *     node:focus - the node to set initial focus on\n\t *   node:table - the table to use, if not given, first table with class 'KeyTable' will be used\n\t *   string:focusClass - focusing class to give to table elements\n\t *           object:that - focus\n\t *   bool:initScroll - scroll the view port on load, default true\n\t *   int:tabIndex - the tab index to give the hidden input element\n\t */\n\tfunction _fnInit( table, datatable, oInit, that )\n\t{\n\t\t/* Save scope */\n\t\t_that = that;\n\n\t\t/* Capture undefined initialisation and apply the defaults */\n\t\tif ( typeof oInit == 'undefined' ) {\n\t\t\toInit = {};\n\t\t}\n\n\t\tif ( typeof oInit.focus == 'undefined' ) {\n\t\t\toInit.focus = [0,0];\n\t\t}\n\n\t\toInit.table = table;\n\t\t$(oInit.table).addClass('KeyTable');\n\n\t\tif ( typeof oInit.focusClass != 'undefined' ) {\n\t\t\t_sFocusClass = oInit.focusClass;\n\t\t}\n\n\t\tif ( typeof datatable != 'undefined' ) {\n\t\t\t_oDatatable = datatable;\n\t\t}\n\n\t\tif ( typeof oInit.initScroll == 'undefined' ) {\n\t\t\toInit.initScroll = true;\n\t\t}\n\n\t\tif ( typeof oInit.form == 'undefined' ) {\n\t\t\toInit.form = false;\n\t\t}\n\t\t_bForm = oInit.form;\n\n\t\t/* Cache the tbody node of interest */\n\t\t_nBody = oInit.table.getElementsByTagName('tbody')[0];\n\n\t\t/* If the table is inside a form, then we need a hidden input box which can be used by the\n\t\t * browser to catch the browser tabbing for our table\n\t\t */\n\t\tif ( _bForm )\n\t\t{\n\t\t\tvar nDiv = document.createElement('div');\n\t\t\t_nInput = document.createElement('input');\n\t\t\tnDiv.style.height = \"1px\"; /* Opera requires a little something */\n\t\t\tnDiv.style.width = \"0px\";\n\t\t\tnDiv.style.overflow = \"hidden\";\n\t\t\tif ( typeof oInit.tabIndex != 'undefined' )\n\t\t\t{\n\t\t\t\t_nInput.tabIndex = oInit.tabIndex;\n\t\t\t}\n\t\t\tnDiv.appendChild(_nInput);\n\t\t\toInit.table.parentNode.insertBefore( nDiv, oInit.table.nextSibling );\n\n\t\t\t$(_nInput).focus( function () {\n\t\t\t\t/* See if we want to 'tab into' the table or out */\n\t\t\t\tif ( !_bInputFocused )\n\t\t\t\t{\n\t\t\t\t\t_bKeyCapture = true;\n\t\t\t\t\t_bInputFocused = false;\n\t\t\t\t\tif ( typeof oInit.focus.nodeName != \"undefined\" )\n\t\t\t\t\t{\n\t\t\t\t\t\t_fnSetFocus( oInit.focus, oInit.initScroll );\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t_fnSetFocus( _fnCellFromCoords( oInit.focus[0], oInit.focus[1]), oInit.initScroll );\n\t\t\t\t\t}\n\n\t\t\t\t\t/* Need to interup the thread for this to work */\n\t\t\t\t\tsetTimeout( function() { _nInput.blur(); }, 0 );\n\t\t\t\t}\n\t\t\t} );\n\t\t\t_bKeyCapture = false;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Set the initial focus on the table */\n\t\t\tif ( typeof oInit.focus.nodeName != \"undefined\" )\n\t\t\t{\n\t\t\t\t_fnSetFocus( oInit.focus, oInit.initScroll );\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t_fnSetFocus( _fnCellFromCoords( oInit.focus[0], oInit.focus[1]), oInit.initScroll );\n\t\t\t}\n\t\t\t_fnCaptureKeys();\n\t\t}\n\n\t\t/* Add event listeners */\n\t\t$(document).bind( \"keydown\", _fnKey );\n\n\t\tif ( _oDatatable )\n\t\t{\n\t\t\t$(_oDatatable.nTable).on( 'click', 'td', _fnClick );\n\t\t}\n\t\telse\n\t\t{\n\t\t\t$(_nBody).on( 'click', 'td', _fnClick );\n\t\t}\n\n\t\t/* Loose table focus when click outside the table */\n\t\t$(document).click( function(e) {\n\t\t\tvar nTarget = e.target;\n\t\t\tvar bTableClick = false;\n\t\t\twhile ( nTarget )\n\t\t\t{\n\t\t\t\tif ( nTarget == oInit.table )\n\t\t\t\t{\n\t\t\t\t\tbTableClick = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tnTarget = nTarget.parentNode;\n\t\t\t}\n\t\t\tif ( !bTableClick )\n\t\t\t{\n\t\t\t\t_fnBlur();\n\t\t\t}\n\t\t} );\n\t}\n\n\tvar table, datatable;\n\n\tif ( oInit === undefined ) {\n\t\ttable = $('table.KeyTable')[0];\n\t\tdatatable = null;\n\t}\n\telse if ( $.isPlainObject( oInit ) ) {\n\t\ttable = oInit.table;\n\t\tdatatable = oInit.datatable;\n\t}\n\telse {\n\t\tdatatable = new $.fn.dataTable.Api( oInit ).settings()[0];\n\t\ttable = datatable.nTable;\n\t}\n\t/* Initialise our new object */\n\t_fnInit( table, datatable, oInit, this );\n};\n\n\nKeyTable.version = \"1.2.1\";\n\n\n$.fn.dataTable.KeyTable = KeyTable;\n$.fn.DataTable.KeyTable = KeyTable;\n\n\nreturn KeyTable;\n}; // /factory\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery && !jQuery.fn.dataTable.KeyTable ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n})(window, document);\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/License.txt",
    "content": "Copyright (c) 2014-2015 SpryMedia Limited\nhttp://datatables.net\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/Readme.md",
    "content": ""
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/css/dataTables.responsive.css",
    "content": "table.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child,\ntable.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child {\n  position: relative;\n  padding-left: 30px;\n  cursor: pointer;\n}\ntable.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child:before,\ntable.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child:before {\n  top: 8px;\n  left: 4px;\n  height: 16px;\n  width: 16px;\n  display: block;\n  position: absolute;\n  color: white;\n  border: 2px solid white;\n  border-radius: 16px;\n  text-align: center;\n  line-height: 14px;\n  box-shadow: 0 0 3px #444;\n  box-sizing: content-box;\n  content: '+';\n  background-color: #31b131;\n}\ntable.dataTable.dtr-inline.collapsed > tbody > tr > td:first-child.dataTables_empty:before,\ntable.dataTable.dtr-inline.collapsed > tbody > tr > th:first-child.dataTables_empty:before {\n  display: none;\n}\ntable.dataTable.dtr-inline.collapsed > tbody > tr.parent > td:first-child:before,\ntable.dataTable.dtr-inline.collapsed > tbody > tr.parent > th:first-child:before {\n  content: '-';\n  background-color: #d33333;\n}\ntable.dataTable.dtr-inline.collapsed > tbody > tr.child td:before {\n  display: none;\n}\ntable.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child,\ntable.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child {\n  padding-left: 27px;\n}\ntable.dataTable.dtr-inline.collapsed.compact > tbody > tr > td:first-child:before,\ntable.dataTable.dtr-inline.collapsed.compact > tbody > tr > th:first-child:before {\n  top: 5px;\n  left: 4px;\n  height: 14px;\n  width: 14px;\n  border-radius: 14px;\n  line-height: 12px;\n}\ntable.dataTable.dtr-column > tbody > tr > td.control,\ntable.dataTable.dtr-column > tbody > tr > th.control {\n  position: relative;\n  cursor: pointer;\n}\ntable.dataTable.dtr-column > tbody > tr > td.control:before,\ntable.dataTable.dtr-column > tbody > tr > th.control:before {\n  top: 50%;\n  left: 50%;\n  height: 16px;\n  width: 16px;\n  margin-top: -10px;\n  margin-left: -10px;\n  display: block;\n  position: absolute;\n  color: white;\n  border: 2px solid white;\n  border-radius: 16px;\n  text-align: center;\n  line-height: 14px;\n  box-shadow: 0 0 3px #444;\n  box-sizing: content-box;\n  content: '+';\n  background-color: #31b131;\n}\ntable.dataTable.dtr-column > tbody > tr.parent td.control:before,\ntable.dataTable.dtr-column > tbody > tr.parent th.control:before {\n  content: '-';\n  background-color: #d33333;\n}\ntable.dataTable > tbody > tr.child {\n  padding: 0.5em 1em;\n}\ntable.dataTable > tbody > tr.child:hover {\n  background: transparent !important;\n}\ntable.dataTable > tbody > tr.child ul {\n  display: inline-block;\n  list-style-type: none;\n  margin: 0;\n  padding: 0;\n}\ntable.dataTable > tbody > tr.child ul li {\n  border-bottom: 1px solid #efefef;\n  padding: 0.5em 0;\n}\ntable.dataTable > tbody > tr.child ul li:first-child {\n  padding-top: 0;\n}\ntable.dataTable > tbody > tr.child ul li:last-child {\n  border-bottom: none;\n}\ntable.dataTable > tbody > tr.child span.dtr-title {\n  display: inline-block;\n  min-width: 75px;\n  font-weight: bold;\n}\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/css/dataTables.responsive.scss",
    "content": "\n//\n// Mixins\n//\n@mixin control() {\n\tdisplay: block;\n\tposition: absolute;\n\tcolor: white;\n\tborder: 2px solid white;\n\tborder-radius: 16px;\n\ttext-align: center;\n\tline-height: 14px;\n\tbox-shadow: 0 0 3px #444;\n\tbox-sizing: content-box;\n}\n\n@mixin control-open() {\n\tcontent: '+';\n\tbackground-color: #31b131;\n}\n\n@mixin control-close() {\n\tcontent: '-';\n\tbackground-color: #d33333;\n}\n\n\n//\n// Table styles\n//\ntable.dataTable {\n\t// Styling for the `inline` type\n\t&.dtr-inline.collapsed > tbody {\n\t\t> tr > td:first-child,\n\t\t> tr > th:first-child {\n\t\t\tposition: relative;\n\t\t\tpadding-left: 30px;\n\t\t\tcursor: pointer;\n\n\t\t\t&:before {\n\t\t\t\ttop: 8px;\n\t\t\t\tleft: 4px;\n\t\t\t\theight: 16px;\n\t\t\t\twidth: 16px;\n\t\t\t\t@include control;\n\t\t\t\t@include control-open;\n\t\t\t}\n\n\t\t\t&.dataTables_empty:before {\n\t\t\t\tdisplay: none;\n\t\t\t}\n\t\t}\n\n\t\t> tr.parent {\n\t\t\t> td:first-child:before,\n\t\t\t> th:first-child:before {\n\t\t\t\t@include control-close;\n\t\t\t}\n\t\t}\n\n\t\t> tr.child td:before {\n\t\t\tdisplay: none;\n\t\t}\n\t}\n\n\t// DataTables' `compact` styling\n\t&.dtr-inline.collapsed.compact > tbody {\n\t\t> tr > td:first-child,\n\t\t> tr > th:first-child {\n\t\t\tpadding-left: 27px;\n\n\t\t\t&:before {\n\t\t\t\ttop: 5px;\n\t\t\t\tleft: 4px;\n\t\t\t\theight: 14px;\n\t\t\t\twidth: 14px;\n\t\t\t\tborder-radius: 14px;\n\t\t\t\tline-height: 12px;\n\t\t\t}\n\t\t}\n\t}\n\n\n\t// Styling for the `column` type\n\t&.dtr-column > tbody {\n\t\t> tr > td.control,\n\t\t> tr > th.control {\n\t\t\tposition: relative;\n\t\t\tcursor: pointer;\n\n\t\t\t&:before {\n\t\t\t\ttop: 50%;\n\t\t\t\tleft: 50%;\n\t\t\t\theight: 16px;\n\t\t\t\twidth: 16px;\n\t\t\t\tmargin-top: -10px;\n\t\t\t\tmargin-left: -10px;\n\t\t\t\t@include control;\n\t\t\t\t@include control-open;\n\t\t\t}\n\t\t}\n\n\t\t> tr.parent {\n\t\t\ttd.control:before,\n\t\t\tth.control:before {\n\t\t\t\t@include control-close;\n\t\t\t}\n\t\t}\n\t}\n\n\n\t// Child row styling\n\t> tbody > tr.child {\n\t\tpadding: 0.5em 1em;\n\n\t\t&:hover {\n\t\t\tbackground: transparent !important;\n\t\t}\n\n\t\tul {\n\t\t\tdisplay: inline-block;\n\t\t\tlist-style-type: none;\n\t\t\tmargin: 0;\n\t\t\tpadding: 0;\n\n\t\t\tli {\n\t\t\t\tborder-bottom: 1px solid #efefef;\n\t\t\t\tpadding: 0.5em 0;\n\n\t\t\t\t&:first-child {\n\t\t\t\t\tpadding-top: 0;\n\t\t\t\t}\n\n\t\t\t\t&:last-child {\n\t\t\t\t\tborder-bottom: none;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tspan.dtr-title {\n\t\t\tdisplay: inline-block;\n\t\t\tmin-width: 75px;\n\t\t\tfont-weight: bold;\n\t\t}\n\n\t\tspan.dtr-data {}\n\t}\n}\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/child-rows/column-control.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Column controlled child rows</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tresponsive: {\n\t\t\tdetails: {\n\t\t\t\ttype: 'column'\n\t\t\t}\n\t\t},\n\t\tcolumnDefs: [ {\n\t\t\tclassName: 'control',\n\t\t\torderable: false,\n\t\t\ttargets:   0\n\t\t} ],\n\t\torder: [ 1, 'asc' ]\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Column controlled child rows</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Responsive has two built in methods for displaying the controlling element of the child rows; <code>inline</code> which is the default option and shows the\n\t\t\t\tcontrol in the first column, and <code>column</code> which set a <em>control column</em> as the control. The control column is shown only when there is some other\n\t\t\t\tcolumn hidden, and is dedicated only to the show / hide control for the rows.</p>\n\n\t\t\t\t<p>This example shows the <a href=\"//datatables.net/extensions/responsive/reference/option/responsive.details.type\"><code class=\"option\" title=\n\t\t\t\t\"Responsive initialisation option\">responsive.details.type<span>R</span></code></a> option set to <code>column</code> to activate the control column. Note that by\n\t\t\t\tdefault the first column is used as the control, so additionally in the initialisation the <a href=\"//datatables.net/reference/option/order\"><code class=\"option\"\n\t\t\t\ttitle=\"DataTables initialisation option\">order<span>DT</span></code></a> and <a href=\"//datatables.net/reference/option/columns.orderable\"><code class=\"option\"\n\t\t\t\ttitle=\"DataTables initialisation option\">columns.orderable<span>DT</span></code></a> options are used to disable sorting on this column.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th></th>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th></th>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tresponsive: {\n\t\t\tdetails: {\n\t\t\t\ttype: 'column'\n\t\t\t}\n\t\t},\n\t\tcolumnDefs: [ {\n\t\t\tclassName: 'control',\n\t\t\torderable: false,\n\t\t\ttargets:   0\n\t\t} ],\n\t\torder: [ 1, 'asc' ]\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/child-rows/custom-renderer.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Custom child row renderer</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tresponsive: {\n\t\t\tdetails: {\n\t\t\t\trenderer: function ( api, rowIdx ) {\n\t\t\t\t\t// Select hidden columns for the given row\n\t\t\t\t\tvar data = api.cells( rowIdx, ':hidden' ).eq(0).map( function ( cell ) {\n\t\t\t\t\t\tvar header = $( api.column( cell.column ).header() );\n\n\t\t\t\t\t\treturn '<tr>'+\n\t\t\t\t\t\t\t\t'<td>'+\n\t\t\t\t\t\t\t\t\theader.text()+':'+\n\t\t\t\t\t\t\t\t'</td> '+\n\t\t\t\t\t\t\t\t'<td>'+\n\t\t\t\t\t\t\t\t\tapi.cell( cell ).data()+\n\t\t\t\t\t\t\t\t'</td>'+\n\t\t\t\t\t\t\t'</tr>';\n\t\t\t\t\t} ).toArray().join('');\n\n\t\t\t\t\treturn data ?\n\t\t\t\t\t\t$('<table/>').append( data ) :\n\t\t\t\t\t\tfalse;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Custom child row renderer</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>The child row's for a collapsed table in Responsive, by default, show a <code class=\"tag\" title=\"HTML tag\">ul/li</code> list of the data from the hidden\n\t\t\t\tcolumns. The <a href=\"//datatables.net/extensions/responsive/reference/option/responsive.details.renderer\"><code class=\"option\" title=\n\t\t\t\t\"Responsive initialisation option\">responsive.details.renderer<span>R</span></code></a> option provide the ability to create your own custom renderer. It is given\n\t\t\t\ttwo parameters: the DataTables API instance for the table and the row index to use.</p>\n\n\t\t\t\t<p>This example shows the <a href=\"//datatables.net/reference/api/cells()\"><code class=\"api\" title=\"DataTables API method\">cells()<span>DT</span></code></a> method\n\t\t\t\tbeing used to select the hidden columns and constructing a table of the data. You could refine the selector to select only certain columns, or show all columns,\n\t\t\t\tetc.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tresponsive: {\n\t\t\tdetails: {\n\t\t\t\trenderer: function ( api, rowIdx ) {\n\t\t\t\t\t// Select hidden columns for the given row\n\t\t\t\t\tvar data = api.cells( rowIdx, ':hidden' ).eq(0).map( function ( cell ) {\n\t\t\t\t\t\tvar header = $( api.column( cell.column ).header() );\n\n\t\t\t\t\t\treturn '&lt;tr&gt;'+\n\t\t\t\t\t\t\t\t'&lt;td&gt;'+\n\t\t\t\t\t\t\t\t\theader.text()+':'+\n\t\t\t\t\t\t\t\t'&lt;/td&gt; '+\n\t\t\t\t\t\t\t\t'&lt;td&gt;'+\n\t\t\t\t\t\t\t\t\tapi.cell( cell ).data()+\n\t\t\t\t\t\t\t\t'&lt;/td&gt;'+\n\t\t\t\t\t\t\t'&lt;/tr&gt;';\n\t\t\t\t\t} ).toArray().join('');\n\n\t\t\t\t\treturn data ?\n\t\t\t\t\t\t$('&lt;table/&gt;').append( data ) :\n\t\t\t\t\t\tfalse;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/child-rows/disable-child-rows.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Disable child rows</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tresponsive: {\n\t\t\tdetails: false\n\t\t}\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Disable child rows</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>By default, when Responsive collapses a table, it will show an option for the end user to expand the row, showing the details of the hidden columns in a child\n\t\t\t\trow. This can be disabled using the <a href=\"//datatables.net/extensions/responsive/reference/option/responsive.details\"><code class=\"option\" title=\n\t\t\t\t\"Responsive initialisation option\">responsive.details<span>R</span></code></a> option and setting it to <code>false</code>, as shown in the example below. In this\n\t\t\t\tcase the hidden data is not directly accessible to the end user.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tresponsive: {\n\t\t\tdetails: false\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/child-rows/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\n\t<title>Responsive examples - Child row control</title>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Child row control</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>When a column is removed from display by Responsive, the data is still available in the table and can be displayed in a DataTables <em>child row</em> (see\n\t\t\t\t<a href=\"//datatables.net/reference/api/row().child()\"><code class=\"api\" title=\"DataTables API method\">row().child()<span>DT</span></code></a>). By default\n\t\t\t\tResponsive will show child row controls in the first column when the table has been collapsed, allowing the end user to show / hide the information from the hidden\n\t\t\t\tcolumns.</p>\n\n\t\t\t\t<p>Responsive has a number of options for display of the child rows:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li>If child row display is enabled: <a href=\"//datatables.net/extensions/responsive/reference/option/responsive.details\"><code class=\"option\" title=\n\t\t\t\t\t\"Responsive initialisation option\">responsive.details<span>R</span></code></a></li>\n\t\t\t\t\t<li>How the show / hide control is displayed: <a href=\"//datatables.net/extensions/responsive/reference/option/responsive.details.type\"><code class=\"option\"\n\t\t\t\t\ttitle=\"Responsive initialisation option\">responsive.details.type<span>R</span></code></a></li>\n\t\t\t\t\t<li>How the child row is rendered: <a href=\"//datatables.net/extensions/responsive/reference/option/responsive.details.renderer\"><code class=\"option\" title=\n\t\t\t\t\t\"Responsive initialisation option\">responsive.details.renderer<span>R</span></code></a></li>\n\t\t\t\t</ul>\n\n\t\t\t\t<p>This section shows examples of these options being used.</p>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/child-rows/right-column.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Column control - right</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tresponsive: {\n\t\t\tdetails: {\n\t\t\t\ttype: 'column',\n\t\t\t\ttarget: -1\n\t\t\t}\n\t\t},\n\t\tcolumnDefs: [ {\n\t\t\tclassName: 'control',\n\t\t\torderable: false,\n\t\t\ttargets:   -1\n\t\t} ]\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Column control - right</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>When using the <code>column</code> child row control type, Responsive has the ability to use any column or element as the show / hide control for the row\n\t\t\t\tdetails. This is provided through the <a href=\"//datatables.net/extensions/responsive/reference/option/responsive.details.target\"><code class=\"option\" title=\n\t\t\t\t\"Responsive initialisation option\">responsive.details.target<span>R</span></code></a> option, which can be either a column index, or a jQuery selector.</p>\n\n\t\t\t\t<p>This example shows the last column in the table being used as the control column.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th></th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th></th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tresponsive: {\n\t\t\tdetails: {\n\t\t\t\ttype: 'column',\n\t\t\t\ttarget: -1\n\t\t\t}\n\t\t},\n\t\tcolumnDefs: [ {\n\t\t\tclassName: 'control',\n\t\t\torderable: false,\n\t\t\ttargets:   -1\n\t\t} ]\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/child-rows/whole-row-control.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Whole row child row control</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tresponsive: {\n\t\t\tdetails: {\n\t\t\t\ttype: 'column',\n\t\t\t\ttarget: 'tr'\n\t\t\t}\n\t\t},\n\t\tcolumnDefs: [ {\n\t\t\tclassName: 'control',\n\t\t\torderable: false,\n\t\t\ttargets:   0\n\t\t} ],\n\t\torder: [ 1, 'asc' ]\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Whole row child row control</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>When using the <code>column</code> details type in Responsive the <a href=\n\t\t\t\t\"//datatables.net/extensions/responsive/reference/option/responsive.details.target\"><code class=\"option\" title=\n\t\t\t\t\"Responsive initialisation option\">responsive.details.target<span>R</span></code></a> option provides the ability to control what element is used to show / hide\n\t\t\t\tthe child rows when the table is collapsed.</p>\n\n\t\t\t\t<p>This example uses the <code>tr</code> selector to have the whole row act as the control.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th></th>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th></th>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td></td>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tresponsive: {\n\t\t\tdetails: {\n\t\t\t\ttype: 'column',\n\t\t\t\ttarget: 'tr'\n\t\t\t}\n\t\t},\n\t\tcolumnDefs: [ {\n\t\t\tclassName: 'control',\n\t\t\torderable: false,\n\t\t\ttargets:   0\n\t\t} ],\n\t\torder: [ 1, 'asc' ]\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/display-control/auto.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Automatic column hiding</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable();\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Automatic column hiding</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Responsive will automatically detect which columns have breakpoint class names assigned to them for visibility control. If no breakpoint class is found for a\n\t\t\t\tcolumn, Responsive will determine automatically if the column should be shown or not at any particular viewport width. This is done by removing columns which cause\n\t\t\t\tthe table to overflow the viewport, with the columns being removed from the right.</p>\n\n\t\t\t\t<p>This example shows that simple case. On a desktop browser resize the window horizontally to see columns added and removed on-the-fly. On a tablet or mobile\n\t\t\t\tbrowser, change the screen's orientation.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display responsive nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable();\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/display-control/classes.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Class control</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t\"ajax\": \"../../../../examples/ajax/data/objects.txt\",\n\t\t\"columns\": [\n\t\t\t{ \"data\": \"name\" },\n\t\t\t{ \"data\": \"position\" },\n\t\t\t{ \"data\": \"office\" },\n\t\t\t{ \"data\": \"age\" },\n\t\t\t{ \"data\": \"start_date\" },\n\t\t\t{ \"data\": \"salary\" },\n\t\t\t{ \"data\": \"extn\" }\n\t\t]\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Class control</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>You can tell Responsive what columns to want to be visible on different devices through the use of class names on the columns. The breakpoints are horizontal\n\t\t\t\tscreen resolutions and the defaults are set for common devices:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li><code>desktop</code> x &gt;= 1024px</li>\n\t\t\t\t\t<li><code>tablet-l</code> (landscape) 768 &lt;= x &lt; 1024</li>\n\t\t\t\t\t<li><code>tablet-p</code> (portrait) 480 &lt;= x &lt; 768</li>\n\t\t\t\t\t<li><code>mobile-l</code> (landscape) 320 &lt;= x &lt; 480</li>\n\t\t\t\t\t<li><code>mobile-p</code> (portrait) x &lt; 320</li>\n\t\t\t\t</ul>\n\n\t\t\t\t<p>You may leave the <code>-[lp]</code> option from the end if you wish to just target all tablet or mobile devices. Additionally to may add <code>min-</code>,\n\t\t\t\t<code>max-</code> or <code>not-</code> as a prefix to the class name to perform logic operations. For example <code>not-mobile</code> would cause a column to\n\t\t\t\tappear as visible on desktop and tablet devices, while <code>min-tablet-l</code> would require at least a horizontal width of 768 for the browser window to be\n\t\t\t\tshown, and be shown at all sizes larger.</p>\n\n\t\t\t\t<p>Additionally, there are three special class names:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li><code>all</code> - Always display</li>\n\t\t\t\t\t<li><code>none</code> - Don't display as a column, but show in the child row</li>\n\t\t\t\t\t<li><code>never</code> - Never display</li>\n\t\t\t\t\t<li><code>control</code> - Used for the <code>column</code> <a href=\n\t\t\t\t\t\"//datatables.net/extensions/responsive/reference/option/responsive.details.type\"><code class=\"option\" title=\n\t\t\t\t\t\"Responsive initialisation option\">responsive.details.type<span>R</span></code></a> option.</li>\n\t\t\t\t</ul>\n\n\t\t\t\t<p>Please <a href=\"//datatables.net/extensions/responsive/\">refer to the Responsive manual</a> for further details of these options.</p>\n\n\t\t\t\t<p>This example shows the <code>salary</code> column visible on a desktop only - <code>office</code> and <code>age</code> require a tablet, while the\n\t\t\t\t<code>position</code> column requires a phone in landscape or larger. The <code>name</code> column is always visible and the <code>start date</code> is never\n\t\t\t\tvisible.</p>\n\n\t\t\t\t<p>This can be useful if you wish to change the format of the data shown on different devices, for example using a combination of <code>mobile</code> and\n\t\t\t\t<code>not-mobile</code> on two different columns would allow information to be formatted suitable for each device type.</p>\n\t\t\t</div>\n\n\t\t\t<div id=\"breakpoint\"></div>\n\n\t\t\t<table id=\"example\" class=\"display responsive\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th class=\"all\">Name</th>\n\t\t\t\t\t\t<th class=\"min-phone-l\">Position</th>\n\t\t\t\t\t\t<th class=\"min-tablet\">Office</th>\n\t\t\t\t\t\t<th class=\"min-tablet\">Age</th>\n\t\t\t\t\t\t<th class=\"never\">Start date</th>\n\t\t\t\t\t\t<th class=\"desktop\">Salary</th>\n\t\t\t\t\t\t<th class=\"none\">Extn.</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t&quot;ajax&quot;: &quot;../../../../examples/ajax/data/objects.txt&quot;,\n\t\t&quot;columns&quot;: [\n\t\t\t{ &quot;data&quot;: &quot;name&quot; },\n\t\t\t{ &quot;data&quot;: &quot;position&quot; },\n\t\t\t{ &quot;data&quot;: &quot;office&quot; },\n\t\t\t{ &quot;data&quot;: &quot;age&quot; },\n\t\t\t{ &quot;data&quot;: &quot;start_date&quot; },\n\t\t\t{ &quot;data&quot;: &quot;salary&quot; },\n\t\t\t{ &quot;data&quot;: &quot;extn&quot; }\n\t\t]\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/display-control/complexHeader.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Complex headers (rowspan / colspan)</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\tth {\n\t\tposition: relative;\n\t\tmin-height: 41px;\n\t} \n\tspan {\n\t\tdisplay: block;\n\t\tposition: absolute;\n\t\tleft: 0;\n\t\tright: 0;\n\t\twhite-space: nowrap;\n\t\ttext-overflow: ellipsis;\n\t\toverflow: hidden;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t// jQuery update a column title from the demo table to contain a long description\n\t// You would not need to do this in your own code.\n\t$('#example thead tr:eq(0) th:eq(2)').html(\"This is a really long column title!\");\n\t\n\t// Wrap the colspan'ing header cells with a span so they can be positioned\n\t// absolutely - filling the available space, and no more.\n\t$('#example thead th[colspan]').wrapInner( '<span/>' ).append( '&nbsp;' );\n\n\t// Standard initialisation\n\t$('#example').DataTable( {\n\t\tresponsive: true,\n\t\tpaging: false\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Complex headers (rowspan / colspan)</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows how Responsive can be used with <em>complex headers</em> (i.e. headers that contain <code>colspan</code> attributes for one or more cells).\n\t\t\t\tAs Responsive will removed columns one at a time the cell with the <code>colspan</code> attribute can end up forcing the width of a column, disrupting the flow.\n\t\t\t\tRather than removing all columns under the <code>colspan</code> cell, we want to reduce the amount of text that is visible in that cell. This example shows how\n\t\t\t\tthat can be achieved thought a little bit of jQuery and CSS.</p>\n\n\t\t\t\t<p>We use jQuery to find the header cells which have a <code>colspan</code> attribute and wrap their contents in a <code class=\"tag\" title=\"HTML tag\">span</code>\n\t\t\t\ttag. That <code class=\"tag\" title=\"HTML tag\">span</code> is then set to <code>position: absolute;</code> using <code>text-overflow: ellipsis</code>. The result is\n\t\t\t\tthat the text of the <code>colspan</code> cell will reduce automatically to fit the available area based on the contents of the column cells below it.</p>\n\n\t\t\t\t<p>This functionality is not currently built into Responsive. It likely will be for v1.1.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th rowspan=\"2\">Name</th>\n\t\t\t\t\t\t<th colspan=\"2\">HR Information</th>\n\t\t\t\t\t\t<th colspan=\"3\">Contact</th>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t// jQuery update a column title from the demo table to contain a long description\n\t// You would not need to do this in your own code.\n\t$('#example thead tr:eq(0) th:eq(2)').html(&quot;This is a really long column title!&quot;);\n\t\n\t// Wrap the colspan'ing header cells with a span so they can be positioned\n\t// absolutely - filling the available space, and no more.\n\t$('#example thead th[colspan]').wrapInner( '&lt;span/&gt;' ).append( '&amp;nbsp;' );\n\n\t// Standard initialisation\n\t$('#example').DataTable( {\n\t\tresponsive: true,\n\t\tpaging: false\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">th {\n\t\tposition: relative;\n\t\tmin-height: 41px;\n\t} \n\tspan {\n\t\tdisplay: block;\n\t\tposition: absolute;\n\t\tleft: 0;\n\t\tright: 0;\n\t\twhite-space: nowrap;\n\t\ttext-overflow: ellipsis;\n\t\toverflow: hidden;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/display-control/fixedHeader.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - With FixedHeader</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../FixedHeader/css/dataTables.fixedHeader.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\tdiv.container { max-width: 1200px }\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../FixedHeader/js/dataTables.fixedHeader.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tresponsive: true,\n\t\tpaging: false\n\t} );\n\n\tnew $.fn.dataTable.FixedHeader( table );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>With FixedHeader</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows Responsive being used with the DataTables <a href=\"http://datatables.net/extensions/fixedheader\">FixedHeader</a> extension. FixedHeader will\n\t\t\t\tlock a table's header to the top of the table, ensuring that the user always knows what each column relates to.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tresponsive: true,\n\t\tpaging: false\n\t} );\n\n\tnew $.fn.dataTable.FixedHeader( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../FixedHeader/js/dataTables.fixedHeader.js\">../../../FixedHeader/js/dataTables.fixedHeader.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">div.container { max-width: 1200px }</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../FixedHeader/css/dataTables.fixedHeader.css\">../../../FixedHeader/css/dataTables.fixedHeader.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/display-control/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\n\t<title>Responsive examples - Display control</title>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Display control</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Responsive has two basic modes of operation for controlling the visibility of columns at different display sizes. These two modes can be using either separately\n\t\t\t\tor together:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li>Manually assigned class names for breakpoints - Assign a column a class name to tell Responsive which breakpoint(s) to show it in.</li>\n\t\t\t\t\t<li>Automatically - for columns without a breakpoint class name, it will be automatically removed if there is no room available on screen to show it. Columns\n\t\t\t\t\tare removed from the right, moving left.</li>\n\t\t\t\t</ul>\n\n\t\t\t\t<p>This section explores these two options.</p>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/display-control/init-classes.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Assigned class control</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t\"ajax\": \"../../../../examples/ajax/data/objects.txt\",\n\t\t\"columns\": [\n\t\t\t{ \"data\": \"name\",       className: \"all\" },\n\t\t\t{ \"data\": \"position\",   className: \"min-phone-l\" },\n\t\t\t{ \"data\": \"office\",     className: \"min-tablet\" },\n\t\t\t{ \"data\": \"age\",        className: \"min-tablet\" },\n\t\t\t{ \"data\": \"start_date\", className: \"never\" },\n\t\t\t{ \"data\": \"salary\",     className: \"desktop\" },\n\t\t\t{ \"data\": \"extn\",       className: \"none\" }\n\t\t]\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Assigned class control</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example exactly matches the functionality of the <a href=\"classes.xml\">class control example</a> but in this case the classes are assigned using the\n\t\t\t\t<a href=\"//datatables.net/reference/option/columns.className\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">columns.className<span>DT</span></code></a> option.</p>\n\t\t\t</div>\n\n\t\t\t<div id=\"breakpoint\"></div>\n\n\t\t\t<table id=\"example\" class=\"display responsive\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t&quot;ajax&quot;: &quot;../../../../examples/ajax/data/objects.txt&quot;,\n\t\t&quot;columns&quot;: [\n\t\t\t{ &quot;data&quot;: &quot;name&quot;,       className: &quot;all&quot; },\n\t\t\t{ &quot;data&quot;: &quot;position&quot;,   className: &quot;min-phone-l&quot; },\n\t\t\t{ &quot;data&quot;: &quot;office&quot;,     className: &quot;min-tablet&quot; },\n\t\t\t{ &quot;data&quot;: &quot;age&quot;,        className: &quot;min-tablet&quot; },\n\t\t\t{ &quot;data&quot;: &quot;start_date&quot;, className: &quot;never&quot; },\n\t\t\t{ &quot;data&quot;: &quot;salary&quot;,     className: &quot;desktop&quot; },\n\t\t\t{ &quot;data&quot;: &quot;extn&quot;,       className: &quot;none&quot; }\n\t\t]\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\n\t<title>Responsive examples - Responsive DataTables</title>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Responsive DataTables</span></h1>\n\n\t\t\t<div class=\"info\"></div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/initialisation/ajax.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Ajax data</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\tdiv.container { max-width: 1200px }\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t\"ajax\": \"../../../../examples/ajax/data/objects.txt\",\n\t\t\"columns\": [\n\t\t\t{ \"data\": \"name\" },\n\t\t\t{ \"data\": \"position\" },\n\t\t\t{ \"data\": \"office\" },\n\t\t\t{ \"data\": \"extn\" },\n\t\t\t{ \"data\": \"start_date\" },\n\t\t\t{ \"data\": \"salary\" }\n\t\t]\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Ajax data</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows the Responsive extension working with <a href=\"//datatables.net/manual/data\">Ajax sourced data</a> in the DataTable. Note that no special\n\t\t\t\tinitialisation is required. Responsive is enabled by adding the <code class=\"string\" title=\"String\">responsive</code> class to the <code class=\"tag\" title=\n\t\t\t\t\"HTML tag\">table</code> element.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display responsive nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t&quot;ajax&quot;: &quot;../../../../examples/ajax/data/objects.txt&quot;,\n\t\t&quot;columns&quot;: [\n\t\t\t{ &quot;data&quot;: &quot;name&quot; },\n\t\t\t{ &quot;data&quot;: &quot;position&quot; },\n\t\t\t{ &quot;data&quot;: &quot;office&quot; },\n\t\t\t{ &quot;data&quot;: &quot;extn&quot; },\n\t\t\t{ &quot;data&quot;: &quot;start_date&quot; },\n\t\t\t{ &quot;data&quot;: &quot;salary&quot; }\n\t\t]\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">div.container { max-width: 1200px }</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/initialisation/className.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Class name</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable();\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Class name</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>The easiest way to initialise the Responsive extension for DataTables is simply to add the class <code class=\"string\" title=\"String\">responsive</code> to the\n\t\t\t\ttable's class name. When the DataTable is initialised the Responsive extension will automatically enable itself on these tables.</p>\n\n\t\t\t\t<p>The may also use the class <code>dt-responsive</code> to perform the same action, since <code>responsive</code> may be used in your stylesheet, or may have some\n\t\t\t\tother meaning in a CSS framework being used (for example Bootstrap).</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display responsive nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable();\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/initialisation/default.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Default initialisation</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$.extend( $.fn.dataTable.defaults, {\n    responsive: true\n} );\n\n$(document).ready(function() {\n\t$('#example').DataTable();\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Default initialisation</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>It can often be useful to be able to set a default value for DataTables' initialisation options, providing a common starting point for initialisation when\n\t\t\t\tworking with multiple tables over many pages or even just on a single page. DataTables provides that ability through the <code>$.fn.dataTable.defaults</code>\n\t\t\t\tobject which can have any of the <a href=\"//datatables.net/reference/option\">initialisation options</a> set.</p>\n\n\t\t\t\t<p>Extending that ability, Responsive can also be set to initialise by default, as shown in this example thorugh the\n\t\t\t\t<code>$.fn.dataTable.defaults.responsive</code> property. Extending that, <a href=\"//datatables.net/extensions/responsive/reference/option/\">all of the Responsive\n\t\t\t\toptions</a> can also be set using this configuration option (i.e. use <code>responsive</code> as an object).</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$.extend( $.fn.dataTable.defaults, {\n    responsive: true\n} );\n\n$(document).ready(function() {\n\t$('#example').DataTable();\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/initialisation/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\n\t<title>Responsive examples - Initialisation</title>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Initialisation</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Responsive can be run on a DataTable in a number of different ways:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li>By adding the class <code>responsive</code> or <code>dt-responsive</code> to the <code class=\"tag\" title=\"HTML tag\">table</code></li>\n\t\t\t\t\t<li>Using the <a href=\"//datatables.net/extensions/responsive/reference/option/responsive\"><code class=\"option\" title=\n\t\t\t\t\t\"Responsive initialisation option\">responsive<span>R</span></code></a> option in the DataTables initialisation</li>\n\t\t\t\t\t<li>Use the <code>$.fn.dataTable.Responsive</code> constructor.</li>\n\t\t\t\t</ul>\n\n\t\t\t\t<p>This set of examples demonstrates these initialisation options.</p>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/initialisation/new.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - `new` constructor</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\tdiv.container { max-width: 1200px }\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.Responsive( table );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>`new` constructor</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Responsive will automatically detect new DataTable instances being created on a page and initialise itself if it find the <a href=\n\t\t\t\t\"//datatables.net/extensions/responsive/reference/option/responsive\"><code class=\"option\" title=\n\t\t\t\t\"Responsive initialisation option\">responsive<span>R</span></code></a> option or <code>responsive</code> class name on the table, as shown in the other\n\t\t\t\texamples.</p>\n\n\t\t\t\t<p>The third way of initialising Responsive is manually creating a new instance using the <code>$.fn.dataTable.Responsive</code> class, as shown in this example\n\t\t\t\t(the other two methods are provided using this constructor in a <a href=\"//datatables.net/reference/event/init\"><code class=\"event\" title=\n\t\t\t\t\"DataTables event\">init<span>DT</span></code></a> event handler!).</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.Responsive( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">div.container { max-width: 1200px }</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/initialisation/option.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Configuration option</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\tdiv.container { max-width: 1200px }\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tresponsive: true\n\t} );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Configuration option</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>The Responsive extension for DataTables can be applied to a DataTable in one of two ways; with a specific class name on the table, or using the DataTables\n\t\t\t\tinitialisation options. This method shows the latter, with the <a href=\"//datatables.net/extensions/responsive/reference/option/responsive\"><code class=\"option\"\n\t\t\t\ttitle=\"Responsive initialisation option\">responsive<span>R</span></code></a> option being set to the boolean value <code>true</code>.</p>\n\n\t\t\t\t<p>The <a href=\"//datatables.net/extensions/responsive/reference/option/responsive\"><code class=\"option\" title=\n\t\t\t\t\"Responsive initialisation option\">responsive<span>R</span></code></a> option can be given as a boolean value, or as an object with configuration options. If as a\n\t\t\t\tboolean, as in this case, the default options are used.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tresponsive: true\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">div.container { max-width: 1200px }</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../styling/index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../styling/bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../styling/compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/styling/bootstrap.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Bootstrap styling</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../Plugins/integration/bootstrap/3/dataTables.bootstrap.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\tbody { font-size: 140% }\n\n\ttable.dataTable th,\n\ttable.dataTable td {\n\t\twhite-space: nowrap;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../Plugins/integration/bootstrap/3/dataTables.bootstrap.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable();\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Bootstrap styling</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows DataTables and the Responsive extension being used with the <a href=\"http://getbootstrap.com\">Bootstrap</a> framework providing the styling.\n\t\t\t\tThe <a href=\"//datatables.net/manual/styling/bootstrap\">DataTables / Bootstrap integration files</a> prove seamless integration for DataTables to be used in a\n\t\t\t\tBootstrap page.</p>\n\n\t\t\t\t<p>Note that the <code>dt-responsive</code> class is used to indicate to the extension that it should be enabled on this page, as <code>responsive</code> <a href=\n\t\t\t\t\"http://getbootstrap.com/css/#tables-responsive\">has special meaning in Bootstrap</a>. The <a href=\n\t\t\t\t\"//datatables.net/extensions/responsive/reference/option/responsive\"><code class=\"option\" title=\n\t\t\t\t\"Responsive initialisation option\">responsive<span>R</span></code></a> option could also be used if required.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"table table-striped table-hover dt-responsive\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable();\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../Plugins/integration/bootstrap/3/dataTables.bootstrap.js\">../../../Plugins/integration/bootstrap/3/dataTables.bootstrap.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">body { font-size: 140% }\n\n\ttable.dataTable th,\n\ttable.dataTable td {\n\t\twhite-space: nowrap;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css\">//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../Plugins/integration/bootstrap/3/dataTables.bootstrap.css\">../../../Plugins/integration/bootstrap/3/dataTables.bootstrap.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/styling/compact.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Compact styling</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\tdiv.container { max-width: 1200px }\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.Responsive( table );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Compact styling</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>DataTables' <a href=\"http://datatables.net/manual/styling/classes\">default stylesheet</a> has a number number of features available that can be enabled by\n\t\t\t\tincluding a class name on the DataTable. One of those options is <code>compact</code> which displays the DataTable with less whitespace padding that might other be\n\t\t\t\tused to increase the information density of the table. Responsive's own style has support for this <code>compact</code> styling as showing in this example.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display compact nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\n\tnew $.fn.dataTable.Responsive( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">div.container { max-width: 1200px }</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/styling/foundation.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Foundation styling</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"//cdn.jsdelivr.net/foundation/5.5.1/css/foundation.min.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../Plugins/integration/foundation/dataTables.foundation.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\ttable.dataTable th,\n\ttable.dataTable td {\n\t\twhite-space: nowrap;\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../Plugins/integration/foundation/dataTables.foundation.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable();\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Foundation styling</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows DataTables and the Responsive extension being used with the <a href=\"http://foundation.zurb.com\">Foundation</a> framework providing the\n\t\t\t\tstyling. The <a href=\"//datatables.net/manual/styling/foundation\">DataTables / Foundation integration files</a> prove seamless integration for DataTables to be\n\t\t\t\tused in a Foundation page.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"tdisplay responsive\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable();\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../Plugins/integration/foundation/dataTables.foundation.js\">../../../Plugins/integration/foundation/dataTables.foundation.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">table.dataTable th,\n\ttable.dataTable td {\n\t\twhite-space: nowrap;\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"//cdn.jsdelivr.net/foundation/5.5.1/css/foundation.min.css\">//cdn.jsdelivr.net/foundation/5.5.1/css/foundation.min.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../Plugins/integration/foundation/dataTables.foundation.css\">../../../Plugins/integration/foundation/dataTables.foundation.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/styling/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\n\t<title>Responsive examples - Styling</title>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Styling</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Responsive requires very little styling information of its own, with styling needed only for the child row display when the table has been collapsed. As such,\n\t\t\t\tintegrating Responsive with your application should be as simple as including the Javascript and base stylesheet! This section shows Responsive being styling using\n\t\t\t\texternal CSS frameworks.</p>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/examples/styling/scrolling.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Responsive example - Vertical scrolling</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../css/dataTables.responsive.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\tdiv.container { max-width: 1200px }\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../js/dataTables.responsive.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY: 300,\n\t\tpaging: false\n\t} );\n\n\tnew $.fn.dataTable.Responsive( table );\n} );\n\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Responsive example <span>Vertical scrolling</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows Responsive in use with the <a href=\"//datatables.net/reference/option/scrollY\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">scrollY<span>DT</span></code></a> option to present a scrolling table (instead of using paging as the other Responsive examples\n\t\t\t\tdo). Responsive will automatically work with the table in such a configuration.</p>\n\n\t\t\t\t<p>Responsive can be used with <a href=\"//datatables.net/reference/option/scrollX\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">scrollX<span>DT</span></code></a>, however it is relatively pointless as Responsive will remove columns to ensure that there is\n\t\t\t\tno horizontal scrolling!</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display nowrap\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>E-mail</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger</td>\n\t\t\t\t\t\t<td>Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t\t<td>5421</td>\n\t\t\t\t\t\t<td>t.nixon@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett</td>\n\t\t\t\t\t\t<td>Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t\t<td>8422</td>\n\t\t\t\t\t\t<td>g.winters@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton</td>\n\t\t\t\t\t\t<td>Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t\t<td>1562</td>\n\t\t\t\t\t\t<td>a.cox@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric</td>\n\t\t\t\t\t\t<td>Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t\t<td>6224</td>\n\t\t\t\t\t\t<td>c.kelly@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi</td>\n\t\t\t\t\t\t<td>Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t\t<td>5407</td>\n\t\t\t\t\t\t<td>a.satou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle</td>\n\t\t\t\t\t\t<td>Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t\t<td>4804</td>\n\t\t\t\t\t\t<td>b.williamson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod</td>\n\t\t\t\t\t\t<td>Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t\t<td>9608</td>\n\t\t\t\t\t\t<td>h.chandler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona</td>\n\t\t\t\t\t\t<td>Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t\t<td>6200</td>\n\t\t\t\t\t\t<td>r.davidson@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen</td>\n\t\t\t\t\t\t<td>Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t\t<td>2360</td>\n\t\t\t\t\t\t<td>c.hurst@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya</td>\n\t\t\t\t\t\t<td>Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t\t<td>1667</td>\n\t\t\t\t\t\t<td>s.frost@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena</td>\n\t\t\t\t\t\t<td>Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t\t<td>3814</td>\n\t\t\t\t\t\t<td>j.gaines@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn</td>\n\t\t\t\t\t\t<td>Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t\t<td>9497</td>\n\t\t\t\t\t\t<td>q.flynn@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde</td>\n\t\t\t\t\t\t<td>Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t\t<td>6741</td>\n\t\t\t\t\t\t<td>c.marshall@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley</td>\n\t\t\t\t\t\t<td>Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t\t<td>3597</td>\n\t\t\t\t\t\t<td>h.kennedy@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana</td>\n\t\t\t\t\t\t<td>Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t\t<td>1965</td>\n\t\t\t\t\t\t<td>t.fitzpatrick@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t\t<td>1581</td>\n\t\t\t\t\t\t<td>m.silva@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul</td>\n\t\t\t\t\t\t<td>Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t\t<td>3059</td>\n\t\t\t\t\t\t<td>p.byrd@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria</td>\n\t\t\t\t\t\t<td>Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t\t<td>1721</td>\n\t\t\t\t\t\t<td>g.little@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t\t<td>2558</td>\n\t\t\t\t\t\t<td>b.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai</td>\n\t\t\t\t\t\t<td>Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t\t<td>2290</td>\n\t\t\t\t\t\t<td>d.rios@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette</td>\n\t\t\t\t\t\t<td>Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t\t<td>1937</td>\n\t\t\t\t\t\t<td>j.caldwell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri</td>\n\t\t\t\t\t\t<td>Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t\t<td>6154</td>\n\t\t\t\t\t\t<td>y.berry@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar</td>\n\t\t\t\t\t\t<td>Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t\t<td>8330</td>\n\t\t\t\t\t\t<td>c.vance@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris</td>\n\t\t\t\t\t\t<td>Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t\t<td>3023</td>\n\t\t\t\t\t\t<td>d.wilder@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica</td>\n\t\t\t\t\t\t<td>Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t\t<td>5797</td>\n\t\t\t\t\t\t<td>a.ramos@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t\t<td>8822</td>\n\t\t\t\t\t\t<td>g.joyce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t\t<td>9239</td>\n\t\t\t\t\t\t<td>j.chang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden</td>\n\t\t\t\t\t\t<td>Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t\t<td>1314</td>\n\t\t\t\t\t\t<td>b.wagner@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona</td>\n\t\t\t\t\t\t<td>Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t\t<td>2947</td>\n\t\t\t\t\t\t<td>f.green@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou</td>\n\t\t\t\t\t\t<td>Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t\t<td>8899</td>\n\t\t\t\t\t\t<td>s.itou@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle</td>\n\t\t\t\t\t\t<td>House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t\t<td>2769</td>\n\t\t\t\t\t\t<td>m.house@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki</td>\n\t\t\t\t\t\t<td>Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t\t<td>6832</td>\n\t\t\t\t\t\t<td>s.burks@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott</td>\n\t\t\t\t\t\t<td>Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t\t<td>3606</td>\n\t\t\t\t\t\t<td>p.bartlett@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin</td>\n\t\t\t\t\t\t<td>Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t\t<td>2860</td>\n\t\t\t\t\t\t<td>g.cortez@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena</td>\n\t\t\t\t\t\t<td>Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t\t<td>8240</td>\n\t\t\t\t\t\t<td>m.mccray@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>u.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard</td>\n\t\t\t\t\t\t<td>Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t\t<td>7031</td>\n\t\t\t\t\t\t<td>h.hatfield@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope</td>\n\t\t\t\t\t\t<td>Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t\t<td>6318</td>\n\t\t\t\t\t\t<td>h.fuentes@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian</td>\n\t\t\t\t\t\t<td>Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t\t<td>9422</td>\n\t\t\t\t\t\t<td>v.harrell@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy</td>\n\t\t\t\t\t\t<td>Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t\t<td>7580</td>\n\t\t\t\t\t\t<td>t.mooney@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson</td>\n\t\t\t\t\t\t<td>Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t\t<td>1042</td>\n\t\t\t\t\t\t<td>j.bradshaw@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia</td>\n\t\t\t\t\t\t<td>Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t\t<td>2120</td>\n\t\t\t\t\t\t<td>o.liang@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno</td>\n\t\t\t\t\t\t<td>Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t\t<td>6222</td>\n\t\t\t\t\t\t<td>b.nash@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura</td>\n\t\t\t\t\t\t<td>Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t\t<td>9383</td>\n\t\t\t\t\t\t<td>s.yamamoto@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor</td>\n\t\t\t\t\t\t<td>Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t\t<td>8327</td>\n\t\t\t\t\t\t<td>t.walton@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn</td>\n\t\t\t\t\t\t<td>Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t\t<td>2927</td>\n\t\t\t\t\t\t<td>f.camacho@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge</td>\n\t\t\t\t\t\t<td>Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t\t<td>8352</td>\n\t\t\t\t\t\t<td>s.baldwin@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida</td>\n\t\t\t\t\t\t<td>Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t\t<td>7439</td>\n\t\t\t\t\t\t<td>z.frank@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita</td>\n\t\t\t\t\t\t<td>Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t\t<td>4389</td>\n\t\t\t\t\t\t<td>z.serrano@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer</td>\n\t\t\t\t\t\t<td>Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t\t<td>3431</td>\n\t\t\t\t\t\t<td>j.acosta@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara</td>\n\t\t\t\t\t\t<td>Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t\t<td>3990</td>\n\t\t\t\t\t\t<td>c.stevens@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione</td>\n\t\t\t\t\t\t<td>Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t\t<td>1016</td>\n\t\t\t\t\t\t<td>h.butler@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael</td>\n\t\t\t\t\t\t<td>Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t\t<td>6733</td>\n\t\t\t\t\t\t<td>l.greer@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas</td>\n\t\t\t\t\t\t<td>Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t\t<td>8196</td>\n\t\t\t\t\t\t<td>j.alexander@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad</td>\n\t\t\t\t\t\t<td>Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>6373</td>\n\t\t\t\t\t\t<td>s.decker@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael</td>\n\t\t\t\t\t\t<td>Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t\t<td>5384</td>\n\t\t\t\t\t\t<td>m.bruce@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna</td>\n\t\t\t\t\t\t<td>Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t\t<td>4226</td>\n\t\t\t\t\t\t<td>d.snider@datatables.net</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tscrollY: 300,\n\t\tpaging: false\n\t} );\n\n\tnew $.fn.dataTable.Responsive( table );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.js\">../../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../../media/js/jquery.dataTables.js\">../../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../js/dataTables.responsive.js\">../../js/dataTables.responsive.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">div.container { max-width: 1200px }</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../../media/css/jquery.dataTables.css\">../../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../css/dataTables.responsive.css\">../../css/dataTables.responsive.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../initialisation/index.html\">Basic initialisation</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/className.html\">Class name</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/option.html\">Configuration option</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/new.html\">`new` constructor</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/ajax.html\">Ajax data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../initialisation/default.html\">Default initialisation</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Styling</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./foundation.html\">Foundation styling</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./scrolling.html\">Vertical scrolling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./compact.html\">Compact styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../display-control/index.html\">Display control</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../display-control/auto.html\">Automatic column hiding</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/classes.html\">Class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/init-classes.html\">Assigned class control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/fixedHeader.html\">With FixedHeader</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../display-control/complexHeader.html\">Complex headers (rowspan / colspan)</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"../child-rows/index.html\">Child rows</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/disable-child-rows.html\">Disable child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/column-control.html\">Column controlled child rows</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/right-column.html\">Column control - right</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/whole-row-control.html\">Whole row child row control</a></li>\n\t\t\t\t\t\t\t<li><a href=\"../child-rows/custom-renderer.html\">Custom child row renderer</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Responsive/js/dataTables.responsive.js",
    "content": "/*! Responsive 1.0.6\n * 2014-2015 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary     Responsive\n * @description Responsive tables plug-in for DataTables\n * @version     1.0.6\n * @file        dataTables.responsive.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2014-2015 SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n *   MIT license - http://datatables.net/license/mit\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n(function(window, document, undefined) {\n\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\n/**\n * Responsive is a plug-in for the DataTables library that makes use of\n * DataTables' ability to change the visibility of columns, changing the\n * visibility of columns so the displayed columns fit into the table container.\n * The end result is that complex tables will be dynamically adjusted to fit\n * into the viewport, be it on a desktop, tablet or mobile browser.\n *\n * Responsive for DataTables has two modes of operation, which can used\n * individually or combined:\n *\n * * Class name based control - columns assigned class names that match the\n *   breakpoint logic can be shown / hidden as required for each breakpoint.\n * * Automatic control - columns are automatically hidden when there is no\n *   room left to display them. Columns removed from the right.\n *\n * In additional to column visibility control, Responsive also has built into\n * options to use DataTables' child row display to show / hide the information\n * from the table that has been hidden. There are also two modes of operation\n * for this child row display:\n *\n * * Inline - when the control element that the user can use to show / hide\n *   child rows is displayed inside the first column of the table.\n * * Column - where a whole column is dedicated to be the show / hide control.\n *\n * Initialisation of Responsive is performed by:\n *\n * * Adding the class `responsive` or `dt-responsive` to the table. In this case\n *   Responsive will automatically be initialised with the default configuration\n *   options when the DataTable is created.\n * * Using the `responsive` option in the DataTables configuration options. This\n *   can also be used to specify the configuration options, or simply set to\n *   `true` to use the defaults.\n *\n *  @class\n *  @param {object} settings DataTables settings object for the host table\n *  @param {object} [opts] Configuration options\n *  @requires jQuery 1.7+\n *  @requires DataTables 1.10.1+\n *\n *  @example\n *      $('#example').DataTable( {\n *        responsive: true\n *      } );\n *    } );\n */\nvar Responsive = function ( settings, opts ) {\n\t// Sanity check that we are using DataTables 1.10 or newer\n\tif ( ! DataTable.versionCheck || ! DataTable.versionCheck( '1.10.1' ) ) {\n\t\tthrow 'DataTables Responsive requires DataTables 1.10.1 or newer';\n\t}\n\n\tthis.s = {\n\t\tdt: new DataTable.Api( settings ),\n\t\tcolumns: []\n\t};\n\n\t// Check if responsive has already been initialised on this table\n\tif ( this.s.dt.settings()[0].responsive ) {\n\t\treturn;\n\t}\n\n\t// details is an object, but for simplicity the user can give it as a string\n\tif ( opts && typeof opts.details === 'string' ) {\n\t\topts.details = { type: opts.details };\n\t}\n\n\tthis.c = $.extend( true, {}, Responsive.defaults, DataTable.defaults.responsive, opts );\n\tsettings.responsive = this;\n\tthis._constructor();\n};\n\nResponsive.prototype = {\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Constructor\n\t */\n\n\t/**\n\t * Initialise the Responsive instance\n\t *\n\t * @private\n\t */\n\t_constructor: function ()\n\t{\n\t\tvar that = this;\n\t\tvar dt = this.s.dt;\n\n\t\tdt.settings()[0]._responsive = this;\n\n\t\t// Use DataTables' private throttle function to avoid processor thrashing\n\t\t$(window).on( 'resize.dtr orientationchange.dtr', dt.settings()[0].oApi._fnThrottle( function () {\n\t\t\tthat._resize();\n\t\t} ) );\n\n\t\t// Destroy event handler\n\t\tdt.on( 'destroy.dtr', function () {\n\t\t\t$(window).off( 'resize.dtr orientationchange.dtr draw.dtr' );\n\t\t} );\n\n\t\t// Reorder the breakpoints array here in case they have been added out\n\t\t// of order\n\t\tthis.c.breakpoints.sort( function (a, b) {\n\t\t\treturn a.width < b.width ? 1 :\n\t\t\t\ta.width > b.width ? -1 : 0;\n\t\t} );\n\n\t\t// Determine which columns are already hidden, and should therefore\n\t\t// remain hidden. todo - should this be done? See thread 22677\n\t\t//\n\t\t// this.s.alwaysHidden = dt.columns(':hidden').indexes();\n\n\t\tthis._classLogic();\n\t\tthis._resizeAuto();\n\n\t\t// Details handler\n\t\tvar details = this.c.details;\n\t\tif ( details.type ) {\n\t\t\tthat._detailsInit();\n\t\t\tthis._detailsVis();\n\n\t\t\tdt.on( 'column-visibility.dtr', function () {\n\t\t\t\tthat._detailsVis();\n\t\t\t} );\n\n\t\t\t// Redraw the details box on each draw. This is used until\n\t\t\t// DataTables implements a native `updated` event for rows\n\t\t\tdt.on( 'draw.dtr', function () {\n\t\t\t\tdt.rows( {page: 'current'} ).iterator( 'row', function ( settings, idx ) {\n\t\t\t\t\tvar row = dt.row( idx );\n\n\t\t\t\t\tif ( row.child.isShown() ) {\n\t\t\t\t\t\tvar info = that.c.details.renderer( dt, idx );\n\t\t\t\t\t\trow.child( info, 'child' ).show();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t} );\n\n\t\t\t$(dt.table().node()).addClass( 'dtr-'+details.type );\n\t\t}\n\n\t\t// First pass - draw the table for the current viewport size\n\t\tthis._resize();\n\t},\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Private methods\n\t */\n\n\t/**\n\t * Calculate the visibility for the columns in a table for a given\n\t * breakpoint. The result is pre-determined based on the class logic if\n\t * class names are used to control all columns, but the width of the table\n\t * is also used if there are columns which are to be automatically shown\n\t * and hidden.\n\t *\n\t * @param  {string} breakpoint Breakpoint name to use for the calculation\n\t * @return {array} Array of boolean values initiating the visibility of each\n\t *   column.\n\t *  @private\n\t */\n\t_columnsVisiblity: function ( breakpoint )\n\t{\n\t\tvar dt = this.s.dt;\n\t\tvar columns = this.s.columns;\n\t\tvar i, ien;\n\n\t\t// Class logic - determine which columns are in this breakpoint based\n\t\t// on the classes. If no class control (i.e. `auto`) then `-` is used\n\t\t// to indicate this to the rest of the function\n\t\tvar display = $.map( columns, function ( col ) {\n\t\t\treturn col.auto && col.minWidth === null ?\n\t\t\t\tfalse :\n\t\t\t\tcol.auto === true ?\n\t\t\t\t\t'-' :\n\t\t\t\t\t$.inArray( breakpoint, col.includeIn ) !== -1;\n\t\t} );\n\n\t\t// Auto column control - first pass: how much width is taken by the\n\t\t// ones that must be included from the non-auto columns\n\t\tvar requiredWidth = 0;\n\t\tfor ( i=0, ien=display.length ; i<ien ; i++ ) {\n\t\t\tif ( display[i] === true ) {\n\t\t\t\trequiredWidth += columns[i].minWidth;\n\t\t\t}\n\t\t}\n\n\t\t// Second pass, use up any remaining width for other columns. For\n\t\t// scrolling tables we need to subtract the width of the scrollbar. It\n\t\t// may not be requires which makes this sub-optimal, but it would\n\t\t// require another full redraw to make complete use of those extra few\n\t\t// pixels\n\t\tvar scrolling = dt.settings()[0].oScroll;\n\t\tvar bar = scrolling.sY || scrolling.sX ? scrolling.iBarWidth : 0;\n\t\tvar widthAvailable = dt.table().container().offsetWidth - bar;\n\t\tvar usedWidth = widthAvailable - requiredWidth;\n\n\t\t// Control column needs to always be included. This makes it sub-\n\t\t// optimal in terms of using the available with, but to stop layout\n\t\t// thrashing or overflow. Also we need to account for the control column\n\t\t// width first so we know how much width is available for the other\n\t\t// columns, since the control column might not be the first one shown\n\t\tfor ( i=0, ien=display.length ; i<ien ; i++ ) {\n\t\t\tif ( columns[i].control ) {\n\t\t\t\tusedWidth -= columns[i].minWidth;\n\t\t\t}\n\t\t}\n\n\t\t// Allow columns to be shown (counting from the left) until we run out\n\t\t// of room\n\t\tvar empty = false;\n\t\tfor ( i=0, ien=display.length ; i<ien ; i++ ) {\n\t\t\tif ( display[i] === '-' && ! columns[i].control ) {\n\t\t\t\t// Once we've found a column that won't fit we don't let any\n\t\t\t\t// others display either, or columns might disappear in the\n\t\t\t\t// middle of the table\n\t\t\t\tif ( empty || usedWidth - columns[i].minWidth < 0 ) {\n\t\t\t\t\tempty = true;\n\t\t\t\t\tdisplay[i] = false;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tdisplay[i] = true;\n\t\t\t\t}\n\n\t\t\t\tusedWidth -= columns[i].minWidth;\n\t\t\t}\n\t\t}\n\n\t\t// Determine if the 'control' column should be shown (if there is one).\n\t\t// This is the case when there is a hidden column (that is not the\n\t\t// control column). The two loops look inefficient here, but they are\n\t\t// trivial and will fly through. We need to know the outcome from the\n\t\t// first , before the action in the second can be taken\n\t\tvar showControl = false;\n\n\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n\t\t\tif ( ! columns[i].control && ! columns[i].never && ! display[i] ) {\n\t\t\t\tshowControl = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n\t\t\tif ( columns[i].control ) {\n\t\t\t\tdisplay[i] = showControl;\n\t\t\t}\n\t\t}\n\n\t\t// Finally we need to make sure that there is at least one column that\n\t\t// is visible\n\t\tif ( $.inArray( true, display ) === -1 ) {\n\t\t\tdisplay[0] = true;\n\t\t}\n\n\t\treturn display;\n\t},\n\n\n\t/**\n\t * Create the internal `columns` array with information about the columns\n\t * for the table. This includes determining which breakpoints the column\n\t * will appear in, based upon class names in the column, which makes up the\n\t * vast majority of this method.\n\t *\n\t * @private\n\t */\n\t_classLogic: function ()\n\t{\n\t\tvar that = this;\n\t\tvar calc = {};\n\t\tvar breakpoints = this.c.breakpoints;\n\t\tvar columns = this.s.dt.columns().eq(0).map( function (i) {\n\t\t\tvar className = this.column(i).header().className;\n\n\t\t\treturn {\n\t\t\t\tclassName: className,\n\t\t\t\tincludeIn: [],\n\t\t\t\tauto:      false,\n\t\t\t\tcontrol:   false,\n\t\t\t\tnever:     className.match(/\\bnever\\b/) ? true : false\n\t\t\t};\n\t\t} );\n\n\t\t// Simply add a breakpoint to `includeIn` array, ensuring that there are\n\t\t// no duplicates\n\t\tvar add = function ( colIdx, name ) {\n\t\t\tvar includeIn = columns[ colIdx ].includeIn;\n\n\t\t\tif ( $.inArray( name, includeIn ) === -1 ) {\n\t\t\t\tincludeIn.push( name );\n\t\t\t}\n\t\t};\n\n\t\tvar column = function ( colIdx, name, operator, matched ) {\n\t\t\tvar size, i, ien;\n\n\t\t\tif ( ! operator ) {\n\t\t\t\tcolumns[ colIdx ].includeIn.push( name );\n\t\t\t}\n\t\t\telse if ( operator === 'max-' ) {\n\t\t\t\t// Add this breakpoint and all smaller\n\t\t\t\tsize = that._find( name ).width;\n\n\t\t\t\tfor ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {\n\t\t\t\t\tif ( breakpoints[i].width <= size ) {\n\t\t\t\t\t\tadd( colIdx, breakpoints[i].name );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( operator === 'min-' ) {\n\t\t\t\t// Add this breakpoint and all larger\n\t\t\t\tsize = that._find( name ).width;\n\n\t\t\t\tfor ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {\n\t\t\t\t\tif ( breakpoints[i].width >= size ) {\n\t\t\t\t\t\tadd( colIdx, breakpoints[i].name );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( operator === 'not-' ) {\n\t\t\t\t// Add all but this breakpoint (xxx need extra information)\n\n\t\t\t\tfor ( i=0, ien=breakpoints.length ; i<ien ; i++ ) {\n\t\t\t\t\tif ( breakpoints[i].name.indexOf( matched ) === -1 ) {\n\t\t\t\t\t\tadd( colIdx, breakpoints[i].name );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t// Loop over each column and determine if it has a responsive control\n\t\t// class\n\t\tcolumns.each( function ( col, i ) {\n\t\t\tvar classNames = col.className.split(' ');\n\t\t\tvar hasClass = false;\n\n\t\t\t// Split the class name up so multiple rules can be applied if needed\n\t\t\tfor ( var k=0, ken=classNames.length ; k<ken ; k++ ) {\n\t\t\t\tvar className = $.trim( classNames[k] );\n\n\t\t\t\tif ( className === 'all' ) {\n\t\t\t\t\t// Include in all\n\t\t\t\t\thasClass = true;\n\t\t\t\t\tcol.includeIn = $.map( breakpoints, function (a) {\n\t\t\t\t\t\treturn a.name;\n\t\t\t\t\t} );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if ( className === 'none' || className === 'never' ) {\n\t\t\t\t\t// Include in none (default) and no auto\n\t\t\t\t\thasClass = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\telse if ( className === 'control' ) {\n\t\t\t\t\t// Special column that is only visible, when one of the other\n\t\t\t\t\t// columns is hidden. This is used for the details control\n\t\t\t\t\thasClass = true;\n\t\t\t\t\tcol.control = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t$.each( breakpoints, function ( j, breakpoint ) {\n\t\t\t\t\t// Does this column have a class that matches this breakpoint?\n\t\t\t\t\tvar brokenPoint = breakpoint.name.split('-');\n\t\t\t\t\tvar re = new RegExp( '(min\\\\-|max\\\\-|not\\\\-)?('+brokenPoint[0]+')(\\\\-[_a-zA-Z0-9])?' );\n\t\t\t\t\tvar match = className.match( re );\n\n\t\t\t\t\tif ( match ) {\n\t\t\t\t\t\thasClass = true;\n\n\t\t\t\t\t\tif ( match[2] === brokenPoint[0] && match[3] === '-'+brokenPoint[1] ) {\n\t\t\t\t\t\t\t// Class name matches breakpoint name fully\n\t\t\t\t\t\t\tcolumn( i, breakpoint.name, match[1], match[2]+match[3] );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if ( match[2] === brokenPoint[0] && ! match[3] ) {\n\t\t\t\t\t\t\t// Class name matched primary breakpoint name with no qualifier\n\t\t\t\t\t\t\tcolumn( i, breakpoint.name, match[1], match[2] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// If there was no control class, then automatic sizing is used\n\t\t\tif ( ! hasClass ) {\n\t\t\t\tcol.auto = true;\n\t\t\t}\n\t\t} );\n\n\t\tthis.s.columns = columns;\n\t},\n\n\n\t/**\n\t * Initialisation for the details handler\n\t *\n\t * @private\n\t */\n\t_detailsInit: function ()\n\t{\n\t\tvar that    = this;\n\t\tvar dt      = this.s.dt;\n\t\tvar details = this.c.details;\n\n\t\t// The inline type always uses the first child as the target\n\t\tif ( details.type === 'inline' ) {\n\t\t\tdetails.target = 'td:first-child';\n\t\t}\n\n\t\t// type.target can be a string jQuery selector or a column index\n\t\tvar target   = details.target;\n\t\tvar selector = typeof target === 'string' ? target : 'td';\n\n\t\t// Click handler to show / hide the details rows when they are available\n\t\t$( dt.table().body() ).on( 'click', selector, function (e) {\n\t\t\t// If the table is not collapsed (i.e. there is no hidden columns)\n\t\t\t// then take no action\n\t\t\tif ( ! $(dt.table().node()).hasClass('collapsed' ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Check that the row is actually a DataTable's controlled node\n\t\t\tif ( ! dt.row( $(this).closest('tr') ).length ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// For column index, we determine if we should act or not in the\n\t\t\t// handler - otherwise it is already okay\n\t\t\tif ( typeof target === 'number' ) {\n\t\t\t\tvar targetIdx = target < 0 ?\n\t\t\t\t\tdt.columns().eq(0).length + target :\n\t\t\t\t\ttarget;\n\n\t\t\t\tif ( dt.cell( this ).index().column !== targetIdx ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// $().closest() includes itself in its check\n\t\t\tvar row = dt.row( $(this).closest('tr') );\n\n\t\t\tif ( row.child.isShown() ) {\n\t\t\t\trow.child( false );\n\t\t\t\t$( row.node() ).removeClass( 'parent' );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tvar info = that.c.details.renderer( dt, row[0] );\n\t\t\t\trow.child( info, 'child' ).show();\n\t\t\t\t$( row.node() ).addClass( 'parent' );\n\t\t\t}\n\t\t} );\n\t},\n\n\n\t/**\n\t * Update the child rows in the table whenever the column visibility changes\n\t *\n\t * @private\n\t */\n\t_detailsVis: function ()\n\t{\n\t\tvar that = this;\n\t\tvar dt = this.s.dt;\n\n\t\t// Find how many columns are hidden\n\t\tvar hiddenColumns = dt.columns().indexes().filter( function ( idx ) {\n\t\t\tvar col = dt.column( idx );\n\n\t\t\tif ( col.visible() ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Only counts as hidden if it doesn't have the `never` class\n\t\t\treturn $( col.header() ).hasClass( 'never' ) ? null : idx;\n\t\t} );\n\t\tvar haveHidden = true;\n\n\t\tif ( hiddenColumns.length === 0 || ( hiddenColumns.length === 1 && this.s.columns[ hiddenColumns[0] ].control ) ) {\n\t\t\thaveHidden = false;\n\t\t}\n\n\t\tif ( haveHidden ) {\n\t\t\t// Show all existing child rows\n\t\t\tdt.rows( { page: 'current' } ).eq(0).each( function (idx) {\n\t\t\t\tvar row = dt.row( idx );\n\n\t\t\t\tif ( row.child() ) {\n\t\t\t\t\tvar info = that.c.details.renderer( dt, row[0] );\n\n\t\t\t\t\t// The renderer can return false to have no child row\n\t\t\t\t\tif ( info === false ) {\n\t\t\t\t\t\trow.child.hide();\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\trow.child( info, 'child' ).show();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t\telse {\n\t\t\t// Hide all existing child rows\n\t\t\tdt.rows( { page: 'current' } ).eq(0).each( function (idx) {\n\t\t\t\tdt.row( idx ).child.hide();\n\t\t\t} );\n\t\t}\n\t},\n\n\n\t/**\n\t * Find a breakpoint object from a name\n\t * @param  {string} name Breakpoint name to find\n\t * @return {object}      Breakpoint description object\n\t */\n\t_find: function ( name )\n\t{\n\t\tvar breakpoints = this.c.breakpoints;\n\n\t\tfor ( var i=0, ien=breakpoints.length ; i<ien ; i++ ) {\n\t\t\tif ( breakpoints[i].name === name ) {\n\t\t\t\treturn breakpoints[i];\n\t\t\t}\n\t\t}\n\t},\n\n\n\t/**\n\t * Alter the table display for a resized viewport. This involves first\n\t * determining what breakpoint the window currently is in, getting the\n\t * column visibilities to apply and then setting them.\n\t *\n\t * @private\n\t */\n\t_resize: function ()\n\t{\n\t\tvar dt = this.s.dt;\n\t\tvar width = $(window).width();\n\t\tvar breakpoints = this.c.breakpoints;\n\t\tvar breakpoint = breakpoints[0].name;\n\t\tvar columns = this.s.columns;\n\t\tvar i, ien;\n\n\t\t// Determine what breakpoint we are currently at\n\t\tfor ( i=breakpoints.length-1 ; i>=0 ; i-- ) {\n\t\t\tif ( width <= breakpoints[i].width ) {\n\t\t\t\tbreakpoint = breakpoints[i].name;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Show the columns for that break point\n\t\tvar columnsVis = this._columnsVisiblity( breakpoint );\n\n\t\t// Set the class before the column visibility is changed so event\n\t\t// listeners know what the state is. Need to determine if there are\n\t\t// any columns that are not visible but can be shown\n\t\tvar collapsedClass = false;\n\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n\t\t\tif ( columnsVis[i] === false && ! columns[i].never ) {\n\t\t\t\tcollapsedClass = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t$( dt.table().node() ).toggleClass('collapsed', collapsedClass );\n\n\t\tdt.columns().eq(0).each( function ( colIdx, i ) {\n\t\t\tdt.column( colIdx ).visible( columnsVis[i] );\n\t\t} );\n\t},\n\n\n\t/**\n\t * Determine the width of each column in the table so the auto column hiding\n\t * has that information to work with. This method is never going to be 100%\n\t * perfect since column widths can change slightly per page, but without\n\t * seriously compromising performance this is quite effective.\n\t *\n\t * @private\n\t */\n\t_resizeAuto: function ()\n\t{\n\t\tvar dt = this.s.dt;\n\t\tvar columns = this.s.columns;\n\n\t\t// Are we allowed to do auto sizing?\n\t\tif ( ! this.c.auto ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Are there any columns that actually need auto-sizing, or do they all\n\t\t// have classes defined\n\t\tif ( $.inArray( true, $.map( columns, function (c) { return c.auto; } ) ) === -1 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clone the table with the current data in it\n\t\tvar tableWidth   = dt.table().node().offsetWidth;\n\t\tvar columnWidths = dt.columns;\n\t\tvar clonedTable  = dt.table().node().cloneNode( false );\n\t\tvar clonedHeader = $( dt.table().header().cloneNode( false ) ).appendTo( clonedTable );\n\t\tvar clonedBody   = $( dt.table().body().cloneNode( false ) ).appendTo( clonedTable );\n\n\t\t$( dt.table().footer() ).clone( false ).appendTo( clonedTable );\n\n\t\t// This is a bit slow, but we need to get a clone of each row that\n\t\t// includes all columns. As such, try to do this as little as possible.\n\t\tdt.rows( { page: 'current' } ).indexes().flatten().each( function ( idx ) {\n\t\t\tvar clone = dt.row( idx ).node().cloneNode( true );\n\t\t\t\n\t\t\tif ( dt.columns( ':hidden' ).flatten().length ) {\n\t\t\t\t$(clone).append( dt.cells( idx, ':hidden' ).nodes().to$().clone() );\n\t\t\t}\n\n\t\t\t$(clone).appendTo( clonedBody );\n\t\t} );\n\n\t\tvar cells = dt.columns().header().to$().clone( false );\n\t\t$('<tr/>')\n\t\t\t.append( cells )\n\t\t\t.appendTo( clonedHeader );\n\n\t\t// In the inline case extra padding is applied to the first column to\n\t\t// give space for the show / hide icon. We need to use this in the\n\t\t// calculation\n\t\tif ( this.c.details.type === 'inline' ) {\n\t\t\t$(clonedTable).addClass( 'dtr-inline collapsed' );\n\t\t}\n\n\t\tvar inserted = $('<div/>')\n\t\t\t.css( {\n\t\t\t\twidth: 1,\n\t\t\t\theight: 1,\n\t\t\t\toverflow: 'hidden'\n\t\t\t} )\n\t\t\t.append( clonedTable );\n\n\t\t// Remove columns which are not to be included\n\t\tinserted.find('th.never, td.never').remove();\n\n\t\tinserted.insertBefore( dt.table().node() );\n\n\t\t// The cloned header now contains the smallest that each column can be\n\t\tdt.columns().eq(0).each( function ( idx ) {\n\t\t\tcolumns[idx].minWidth = cells[ idx ].offsetWidth || 0;\n\t\t} );\n\n\t\tinserted.remove();\n\t}\n};\n\n\n/**\n * List of default breakpoints. Each item in the array is an object with two\n * properties:\n *\n * * `name` - the breakpoint name.\n * * `width` - the breakpoint width\n *\n * @name Responsive.breakpoints\n * @static\n */\nResponsive.breakpoints = [\n\t{ name: 'desktop',  width: Infinity },\n\t{ name: 'tablet-l', width: 1024 },\n\t{ name: 'tablet-p', width: 768 },\n\t{ name: 'mobile-l', width: 480 },\n\t{ name: 'mobile-p', width: 320 }\n];\n\n\n/**\n * Responsive default settings for initialisation\n *\n * @namespace\n * @name Responsive.defaults\n * @static\n */\nResponsive.defaults = {\n\t/**\n\t * List of breakpoints for the instance. Note that this means that each\n\t * instance can have its own breakpoints. Additionally, the breakpoints\n\t * cannot be changed once an instance has been creased.\n\t *\n\t * @type {Array}\n\t * @default Takes the value of `Responsive.breakpoints`\n\t */\n\tbreakpoints: Responsive.breakpoints,\n\n\t/**\n\t * Enable / disable auto hiding calculations. It can help to increase\n\t * performance slightly if you disable this option, but all columns would\n\t * need to have breakpoint classes assigned to them\n\t *\n\t * @type {Boolean}\n\t * @default  `true`\n\t */\n\tauto: true,\n\n\t/**\n\t * Details control. If given as a string value, the `type` property of the\n\t * default object is set to that value, and the defaults used for the rest\n\t * of the object - this is for ease of implementation.\n\t *\n\t * The object consists of the following properties:\n\t *\n\t * * `renderer` - function that is called for display of the child row data.\n\t *   The default function will show the data from the hidden columns\n\t * * `target` - Used as the selector for what objects to attach the child\n\t *   open / close to\n\t * * `type` - `false` to disable the details display, `inline` or `column`\n\t *   for the two control types\n\t *\n\t * @type {Object|string}\n\t */\n\tdetails: {\n\t\trenderer: function ( api, rowIdx ) {\n\t\t\tvar data = api.cells( rowIdx, ':hidden' ).eq(0).map( function ( cell ) {\n\t\t\t\tvar header = $( api.column( cell.column ).header() );\n\t\t\t\tvar idx = api.cell( cell ).index();\n\n\t\t\t\tif ( header.hasClass( 'control' ) || header.hasClass( 'never' ) ) {\n\t\t\t\t\treturn '';\n\t\t\t\t}\n\n\t\t\t\t// Use a non-public DT API method to render the data for display\n\t\t\t\t// This needs to be updated when DT adds a suitable method for\n\t\t\t\t// this type of data retrieval\n\t\t\t\tvar dtPrivate = api.settings()[0];\n\t\t\t\tvar cellData = dtPrivate.oApi._fnGetCellData(\n\t\t\t\t\tdtPrivate, idx.row, idx.column, 'display'\n\t\t\t\t);\n\t\t\t\tvar title = header.text();\n\t\t\t\tif ( title ) {\n\t\t\t\t\ttitle = title + ':';\n\t\t\t\t}\n\n\t\t\t\treturn '<li data-dtr-index=\"'+idx.column+'\">'+\n\t\t\t\t\t\t'<span class=\"dtr-title\">'+\n\t\t\t\t\t\t\ttitle+\n\t\t\t\t\t\t'</span> '+\n\t\t\t\t\t\t'<span class=\"dtr-data\">'+\n\t\t\t\t\t\t\tcellData+\n\t\t\t\t\t\t'</span>'+\n\t\t\t\t\t'</li>';\n\t\t\t} ).toArray().join('');\n\n\t\t\treturn data ?\n\t\t\t\t$('<ul data-dtr-index=\"'+rowIdx+'\"/>').append( data ) :\n\t\t\t\tfalse;\n\t\t},\n\n\t\ttarget: 0,\n\n\t\ttype: 'inline'\n\t}\n};\n\n\n/*\n * API\n */\nvar Api = $.fn.dataTable.Api;\n\n// Doesn't do anything - work around for a bug in DT... Not documented\nApi.register( 'responsive()', function () {\n\treturn this;\n} );\n\nApi.register( 'responsive.index()', function ( li ) {\n\tli = $(li);\n\n\treturn {\n\t\tcolumn: li.data('dtr-index'),\n\t\trow:    li.parent().data('dtr-index')\n\t};\n} );\n\nApi.register( 'responsive.rebuild()', function () {\n\treturn this.iterator( 'table', function ( ctx ) {\n\t\tif ( ctx._responsive ) {\n\t\t\tctx._responsive._classLogic();\n\t\t}\n\t} );\n} );\n\nApi.register( 'responsive.recalc()', function () {\n\treturn this.iterator( 'table', function ( ctx ) {\n\t\tif ( ctx._responsive ) {\n\t\t\tctx._responsive._resizeAuto();\n\t\t\tctx._responsive._resize();\n\t\t}\n\t} );\n} );\n\n\n/**\n * Version information\n *\n * @name Responsive.version\n * @static\n */\nResponsive.version = '1.0.6';\n\n\n$.fn.dataTable.Responsive = Responsive;\n$.fn.DataTable.Responsive = Responsive;\n\n// Attach a listener to the document which listens for DataTables initialisation\n// events so we can automatically initialise\n$(document).on( 'init.dt.dtr', function (e, settings, json) {\n\tif ( e.namespace !== 'dt' ) {\n\t\treturn;\n\t}\n\n\tif ( $(settings.nTable).hasClass( 'responsive' ) ||\n\t\t $(settings.nTable).hasClass( 'dt-responsive' ) ||\n\t\t settings.oInit.responsive ||\n\t\t DataTable.defaults.responsive\n\t) {\n\t\tvar init = settings.oInit.responsive;\n\n\t\tif ( init !== false ) {\n\t\t\tnew Responsive( settings, $.isPlainObject( init ) ? init : {}  );\n\t\t}\n\t}\n} );\n\nreturn Responsive;\n}; // /factory\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery && !jQuery.fn.dataTable.Responsive ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n})(window, document);\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Scroller/Readme.txt",
    "content": "# Scroller\n\nScroller is a virtual rendering plug-in for DataTables which allows large datasets to be drawn on screen every quickly. What the virtual rendering means is that only the visible portion of the table (and a bit to either side to make the scrolling smooth) is drawn, while the scrolling container gives the visual impression that the whole table is visible. This is done by making use of the pagination abilities of DataTables and moving the table around in the scrolling container DataTables adds to the page. The scrolling container is forced to the height it would be for the full table display using an extra element.\n\nKey features include:\n\n* Speed! The aim of Scroller for DataTables is to make rendering large data sets fast\n* Full compatibility with DataTables' deferred rendering for maximum speed\n* Integration with state saving in DataTables (scrolling position is saved)\n* Support for scrolling with millions of rows\n* Easy to use\n\n\n# Installation\n\nTo use Scroller, first download DataTables ( http://datatables.net/download ) and place the unzipped Scroller package into a `extensions` directory in the DataTables package. This will allow the pages in the examples to operate correctly. To see the examples running, open the `examples` directory in your web-browser.\n\n\n# Basic usage\n\nScroller is initialised by simply including the letter `dt-string S` in the `dt-init dom` for the table you want to have this feature enabled on. Note that the `dt-string S` must come after the `dt-string t` parameter in `dom`. For example:\n\n```js\n$(document).ready( function () {\n\t$('#example').DataTable( {\n\t\tdom: 'lfrtipS'\n\t} );\n} );\n```\n\nNote that rows in the table must all be the same height. Information in a cell which expands on to multiple lines will cause some odd behaviour in the scrolling. Additionally, the table's `cellspacing` parameter must be set to 0, again to ensure the information display is correct.\n\n\n# Documentation / support\n\n* Documentation: http://datatables.net/extensions/scroller/\n* DataTables support forums: http://datatables.net/forums\n\n\n# GitHub\n\nIf you fancy getting involved with the development of Scroller and help make it better, please refer to its GitHub repo: https://github.com/DataTables/Scroller\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Scroller/css/dataTables.scroller.css",
    "content": "\n/*\n * Namespace: DTS (DataTables Scroller)\n */\n\ndiv.DTS tbody th,\ndiv.DTS tbody td {\n\twhite-space: nowrap;\n}\n\ndiv.DTS tbody tr.even {\n\tbackground-color: white;\n}\n\ndiv.DTS div.DTS_Loading {\n\tposition: absolute;\n\ttop: 50%;\n\tleft: 50%;\n\twidth: 200px;\n\theight: 20px;\n\tmargin-top: -20px;\n\tmargin-left: -100px;\n\tz-index: 1;\n\n\tborder: 1px solid #999;\n\tpadding: 20px 0;\n\ttext-align: center;\n\tbackground-color: white;\n\tbackground-color: rgba(255, 255, 255, 0.5);\n}\n\ndiv.DTS div.dataTables_scrollHead,\ndiv.DTS div.dataTables_scrollFoot {\n\tbackground-color: white;\n}\n\ndiv.DTS div.dataTables_scrollBody {\n\tz-index: 2;\n}\n\ndiv.DTS div.dataTables_scroll {\n\tbackground: url('../images/loading-background.png') repeat 0 0;\n}\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Scroller/examples/api_scrolling.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Scroller example - API</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.scroller.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.scroller.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tajax:        \"data/2500.txt\",\n\t\tdeferRender: true,\n\t\tdom:         \"frtiS\",\n\t\tscrollY:     200,\n\t\tscrollCollapse: true,\n\t\tinitComplete: function () {\n\t\t\tvar api = this.api();\n\t\t\tapi.scroller().scrollToRow( 1000 );\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Scroller example <span>API</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows a trivial use of the API methods that Scroller adds to the DataTables API to\n\t\t\t\tscroll to a row once the table's data has been loaded. In this case\n\t\t\t\t<code>scroller().scrollToRow()</code> is used to jump to row 1000.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>ID</th>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>ZIP / Post code</th>\n\t\t\t\t\t\t<th>Country</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tajax:        &quot;data/2500.txt&quot;,\n\t\tdeferRender: true,\n\t\tdom:         &quot;frtiS&quot;,\n\t\tscrollY:     200,\n\t\tscrollCollapse: true,\n\t\tinitComplete: function () {\n\t\t\tvar api = this.api();\n\t\t\tapi.scroller().scrollToRow( 1000 );\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.scroller.js\">../js/dataTables.scroller.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.scroller.css\">../css/dataTables.scroller.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_saving.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./large_js_source.html\">Client-side data source (50,000 rows)</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side_processing.html\">Server-side processing (5,000,000\n\t\t\t\t\t\t\trows)</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./api_scrolling.html\">API</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Scroller/examples/data/2500.txt",
    "content": "{ \"aaData\": [\n\t[ \"1\", \"Armand\", \"Warren\", \"56045\", \"Taiwan, Province of China\" ],\n\t[ \"2\", \"Xenos\", \"Salas\", \"71090\", \"Liberia\" ],\n\t[ \"3\", \"Virginia\", \"Whitaker\", \"62723\", \"Nicaragua\" ],\n\t[ \"4\", \"Kato\", \"Patrick\", \"97662\", \"Palau\" ],\n\t[ \"5\", \"Penelope\", \"Hensley\", \"76634\", \"Greenland\" ],\n\t[ \"6\", \"Georgia\", \"Erickson\", \"81358\", \"Bolivia\" ],\n\t[ \"7\", \"Shad\", \"Pena\", \"20600\", \"Palestinian Territory, Occupied\" ],\n\t[ \"8\", \"Tanisha\", \"Humphrey\", \"93371\", \"Kenya\" ],\n\t[ \"9\", \"Claire\", \"Espinoza\", \"I8S 2S8\", \"Panama\" ],\n\t[ \"10\", \"Raya\", \"Tucker\", \"O8D 8W7\", \"Botswana\" ],\n\t[ \"11\", \"Otto\", \"Briggs\", \"57590\", \"Anguilla\" ],\n\t[ \"12\", \"Logan\", \"Burt\", \"53041\", \"Venezuela\" ],\n\t[ \"13\", \"Cooper\", \"Pennington\", \"36994\", \"France\" ],\n\t[ \"14\", \"Kristen\", \"Peterson\", \"52917\", \"Sao Tome and Principe\" ],\n\t[ \"15\", \"Jordan\", \"Velasquez\", \"08884\", \"Switzerland\" ],\n\t[ \"16\", \"Zelda\", \"Freeman\", \"F9H 1J9\", \"Holy See (Vatican City State)\" ],\n\t[ \"17\", \"Mary\", \"Pacheco\", \"A7Y 6X9\", \"Niger\" ],\n\t[ \"18\", \"Tiger\", \"Robles\", \"44533\", \"Malaysia\" ],\n\t[ \"19\", \"Zelenia\", \"Buckner\", \"Q8N 6E5\", \"Malawi\" ],\n\t[ \"20\", \"Coby\", \"Johnston\", \"N6I 2O9\", \"Rwanda\" ],\n\t[ \"21\", \"Gillian\", \"Strickland\", \"12258\", \"Cook Islands\" ],\n\t[ \"22\", \"Alfreda\", \"Mcbride\", \"K5A 3B6\", \"Nigeria\" ],\n\t[ \"23\", \"Laith\", \"Ford\", \"19072\", \"Czech Republic\" ],\n\t[ \"24\", \"Autumn\", \"Barton\", \"U9D 9F4\", \"Angola\" ],\n\t[ \"25\", \"Nadine\", \"Britt\", \"G4U 8L0\", \"Liechtenstein\" ],\n\t[ \"26\", \"Xaviera\", \"Hart\", \"T1N 7D2\", \"Mali\" ],\n\t[ \"27\", \"Neil\", \"Page\", \"T3E 9F4\", \"Korea\" ],\n\t[ \"28\", \"Rose\", \"French\", \"B7T 8M2\", \"French Polynesia\" ],\n\t[ \"29\", \"Alyssa\", \"Poole\", \"S1L 2T5\", \"Yemen\" ],\n\t[ \"30\", \"Chantale\", \"Lynch\", \"97316\", \"United States\" ],\n\t[ \"31\", \"Jermaine\", \"Dawson\", \"A3H 7A1\", \"American Samoa\" ],\n\t[ \"32\", \"Ann\", \"Giles\", \"54258\", \"Korea\" ],\n\t[ \"33\", \"Jerry\", \"Carr\", \"04901\", \"South Georgia and The South Sandwich Islands\" ],\n\t[ \"34\", \"Lionel\", \"Hooper\", \"67970\", \"Bahrain\" ],\n\t[ \"35\", \"Alyssa\", \"Hewitt\", \"R3K 2V8\", \"Paraguay\" ],\n\t[ \"36\", \"Lisandra\", \"Sheppard\", \"71886\", \"Seychelles\" ],\n\t[ \"37\", \"Kylan\", \"Harrison\", \"96763\", \"Italy\" ],\n\t[ \"38\", \"Kaitlin\", \"Montgomery\", \"V5K 5U8\", \"Niger\" ],\n\t[ \"39\", \"Heidi\", \"Boyd\", \"B3C 8M9\", \"Papua New Guinea\" ],\n\t[ \"40\", \"Rinah\", \"Case\", \"W7M 5K1\", \"Mali\" ],\n\t[ \"41\", \"Thaddeus\", \"Maynard\", \"E4V 6W6\", \"Egypt\" ],\n\t[ \"42\", \"Lacota\", \"Ray\", \"T3J 8D8\", \"United Kingdom\" ],\n\t[ \"43\", \"Olympia\", \"Cortez\", \"F8C 7I5\", \"Palau\" ],\n\t[ \"44\", \"Wendy\", \"Rojas\", \"N8T 4K6\", \"Cook Islands\" ],\n\t[ \"45\", \"Arden\", \"Kelley\", \"V9N 2T6\", \"India\" ],\n\t[ \"46\", \"Colorado\", \"Lindsey\", \"96703\", \"Chad\" ],\n\t[ \"47\", \"Alika\", \"Weaver\", \"F6V 1I1\", \"Bulgaria\" ],\n\t[ \"48\", \"Phoebe\", \"Mack\", \"E4B 1X2\", \"El Salvador\" ],\n\t[ \"49\", \"Sybill\", \"Bridges\", \"Z2G 6A2\", \"Somalia\" ],\n\t[ \"50\", \"Trevor\", \"Larsen\", \"K1R 3B9\", \"United Arab Emirates\" ],\n\t[ \"51\", \"Maya\", \"Battle\", \"70881\", \"Australia\" ],\n\t[ \"52\", \"Charity\", \"Walton\", \"I4I 5R9\", \"Swaziland\" ],\n\t[ \"53\", \"Lane\", \"Sloan\", \"79076\", \"Nauru\" ],\n\t[ \"54\", \"Christopher\", \"Watson\", \"35116\", \"Suriname\" ],\n\t[ \"55\", \"Clementine\", \"Shelton\", \"98232\", \"Venezuela\" ],\n\t[ \"56\", \"Basil\", \"Hood\", \"J9I 1R2\", \"Tonga\" ],\n\t[ \"57\", \"Meghan\", \"Pacheco\", \"H5Z 6B1\", \"Dominican Republic\" ],\n\t[ \"58\", \"Brennan\", \"Potts\", \"51743\", \"Turkey\" ],\n\t[ \"59\", \"Lawrence\", \"Duran\", \"63266\", \"Uruguay\" ],\n\t[ \"60\", \"Ina\", \"Head\", \"S8P 9J5\", \"Romania\" ],\n\t[ \"61\", \"Castor\", \"Jacobson\", \"C9F 6C9\", \"Albania\" ],\n\t[ \"62\", \"Daquan\", \"Holden\", \"38571\", \"Ireland\" ],\n\t[ \"63\", \"Donna\", \"Valencia\", \"J7B 3I0\", \"Portugal\" ],\n\t[ \"64\", \"Kessie\", \"Phelps\", \"61063\", \"Georgia\" ],\n\t[ \"65\", \"Dillon\", \"Garcia\", \"13652\", \"Holy See (Vatican City State)\" ],\n\t[ \"66\", \"Russell\", \"Sweeney\", \"T8P 2O6\", \"Saint Kitts and Nevis\" ],\n\t[ \"67\", \"Zelda\", \"Berg\", \"84946\", \"Afghanistan\" ],\n\t[ \"68\", \"Dexter\", \"Mann\", \"73596\", \"Thailand\" ],\n\t[ \"69\", \"Maisie\", \"Miller\", \"X3M 6C1\", \"Seychelles\" ],\n\t[ \"70\", \"Lynn\", \"Mitchell\", \"N5B 3Z9\", \"Wallis and Futuna\" ],\n\t[ \"71\", \"Gay\", \"Medina\", \"66692\", \"Germany\" ],\n\t[ \"72\", \"Olga\", \"Clark\", \"M6B 7B6\", \"Kuwait\" ],\n\t[ \"73\", \"Brianna\", \"Obrien\", \"Z6Z 5R3\", \"Bahrain\" ],\n\t[ \"74\", \"Daria\", \"Byers\", \"R9T 4N7\", \"Ghana\" ],\n\t[ \"75\", \"Chiquita\", \"Barker\", \"28435\", \"Ireland\" ],\n\t[ \"76\", \"Gray\", \"Salazar\", \"58618\", \"Chile\" ],\n\t[ \"77\", \"Delilah\", \"Kirby\", \"42811\", \"Oman\" ],\n\t[ \"78\", \"Xanthus\", \"Holland\", \"B8Q 9C4\", \"Antigua and Barbuda\" ],\n\t[ \"79\", \"Reuben\", \"Brennan\", \"44693\", \"Czech Republic\" ],\n\t[ \"80\", \"Alden\", \"Long\", \"94236\", \"Slovakia\" ],\n\t[ \"81\", \"Blythe\", \"Bender\", \"04812\", \"Guam\" ],\n\t[ \"82\", \"Aileen\", \"Burgess\", \"47942\", \"Djibouti\" ],\n\t[ \"83\", \"Zeus\", \"Craig\", \"43002\", \"Nicaragua\" ],\n\t[ \"84\", \"Jade\", \"Garza\", \"F2X 8F3\", \"New Zealand\" ],\n\t[ \"85\", \"Noah\", \"Barrera\", \"K9C 8U0\", \"Malawi\" ],\n\t[ \"86\", \"Quyn\", \"Robertson\", \"H3X 6J9\", \"Bosnia and Herzegovina\" ],\n\t[ \"87\", \"Serena\", \"Cabrera\", \"83671\", \"Slovenia\" ],\n\t[ \"88\", \"Charity\", \"Chase\", \"T9Q 7C4\", \"Solomon Islands\" ],\n\t[ \"89\", \"Athena\", \"Grimes\", \"62801\", \"Aruba\" ],\n\t[ \"90\", \"Mallory\", \"Middleton\", \"D2V 1M5\", \"Italy\" ],\n\t[ \"91\", \"Xenos\", \"Jones\", \"46642\", \"Singapore\" ],\n\t[ \"92\", \"Tate\", \"Gregory\", \"66538\", \"Zimbabwe\" ],\n\t[ \"93\", \"Blaze\", \"Taylor\", \"70282\", \"Paraguay\" ],\n\t[ \"94\", \"Jena\", \"Duncan\", \"63057\", \"Cambodia\" ],\n\t[ \"95\", \"Thaddeus\", \"Chase\", \"66762\", \"Netherlands Antilles\" ],\n\t[ \"96\", \"Guinevere\", \"Mcgee\", \"O9G 4S2\", \"Lebanon\" ],\n\t[ \"97\", \"Kermit\", \"Ramsey\", \"41214\", \"Dominican Republic\" ],\n\t[ \"98\", \"Josephine\", \"Gallagher\", \"04960\", \"French Southern Territories\" ],\n\t[ \"99\", \"Amela\", \"Morales\", \"M9I 1X5\", \"Sudan\" ],\n\t[ \"100\", \"Rina\", \"Yates\", \"G3T 7M9\", \"Dominica\" ],\n\t[ \"101\", \"Orson\", \"Norris\", \"21660\", \"Sierra Leone\" ],\n\t[ \"102\", \"Graiden\", \"Silva\", \"98191\", \"Saint Lucia\" ],\n\t[ \"103\", \"Amaya\", \"Hood\", \"45779\", \"India\" ],\n\t[ \"104\", \"Fatima\", \"Fitzpatrick\", \"I4R 9Q8\", \"Viet Nam\" ],\n\t[ \"105\", \"Judith\", \"Stokes\", \"97596\", \"Sudan\" ],\n\t[ \"106\", \"Jared\", \"Vaughn\", \"75521\", \"Benin\" ],\n\t[ \"107\", \"Mira\", \"Morgan\", \"35169\", \"Martinique\" ],\n\t[ \"108\", \"Walter\", \"Perkins\", \"28618\", \"San Marino\" ],\n\t[ \"109\", \"Megan\", \"Maxwell\", \"K6X 3J4\", \"Oman\" ],\n\t[ \"110\", \"Christine\", \"Christensen\", \"M7S 8G8\", \"Netherlands Antilles\" ],\n\t[ \"111\", \"Tanner\", \"Guerra\", \"S3K 6Y5\", \"Finland\" ],\n\t[ \"112\", \"Meghan\", \"Rowland\", \"K7U 3A1\", \"Rwanda\" ],\n\t[ \"113\", \"Patrick\", \"Mitchell\", \"V3F 5C4\", \"Oman\" ],\n\t[ \"114\", \"Jackson\", \"Sanders\", \"83229\", \"Greenland\" ],\n\t[ \"115\", \"Omar\", \"Savage\", \"14082\", \"Korea\" ],\n\t[ \"116\", \"Ulla\", \"Larsen\", \"Q2P 4L8\", \"French Southern Territories\" ],\n\t[ \"117\", \"Hop\", \"Gates\", \"D9G 9J4\", \"Poland\" ],\n\t[ \"118\", \"Astra\", \"Mendoza\", \"R3D 2H9\", \"Saint Vincent and The Grenadines\" ],\n\t[ \"119\", \"Denise\", \"Cardenas\", \"73138\", \"Sao Tome and Principe\" ],\n\t[ \"120\", \"Melodie\", \"Roberts\", \"L1G 4H2\", \"India\" ],\n\t[ \"121\", \"Cedric\", \"Joseph\", \"M4V 8O9\", \"Korea, Republic of\" ],\n\t[ \"122\", \"Linda\", \"Horn\", \"24465\", \"Bosnia and Herzegovina\" ],\n\t[ \"123\", \"Mary\", \"Lyons\", \"22324\", \"Norfolk Island\" ],\n\t[ \"124\", \"Ciara\", \"Mcknight\", \"30784\", \"Anguilla\" ],\n\t[ \"125\", \"Vaughan\", \"Santiago\", \"65037\", \"Guyana\" ],\n\t[ \"126\", \"Lamar\", \"Shepherd\", \"58040\", \"France\" ],\n\t[ \"127\", \"Xavier\", \"Webster\", \"68321\", \"Afghanistan\" ],\n\t[ \"128\", \"Ainsley\", \"Banks\", \"46902\", \"Pakistan\" ],\n\t[ \"129\", \"Alika\", \"Love\", \"L5O 4B3\", \"Iran, Islamic Republic of\" ],\n\t[ \"130\", \"Maite\", \"Dickson\", \"37405\", \"Saint Kitts and Nevis\" ],\n\t[ \"131\", \"Kimberley\", \"Morrow\", \"F7C 7J0\", \"Lebanon\" ],\n\t[ \"132\", \"Eugenia\", \"Stafford\", \"36282\", \"Nicaragua\" ],\n\t[ \"133\", \"Mira\", \"Gill\", \"K1T 8U1\", \"Uruguay\" ],\n\t[ \"134\", \"Herman\", \"Francis\", \"C2G 8G9\", \"Northern Mariana Islands\" ],\n\t[ \"135\", \"Veronica\", \"Peters\", \"74146\", \"Cook Islands\" ],\n\t[ \"136\", \"Axel\", \"Cochran\", \"32240\", \"Central African Republic\" ],\n\t[ \"137\", \"Edan\", \"Howe\", \"51862\", \"Mali\" ],\n\t[ \"138\", \"Ignacia\", \"Bruce\", \"Q8T 5Q1\", \"Sao Tome and Principe\" ],\n\t[ \"139\", \"Jana\", \"Mcguire\", \"89412\", \"Czech Republic\" ],\n\t[ \"140\", \"Alice\", \"Underwood\", \"74535\", \"Slovakia\" ],\n\t[ \"141\", \"Tobias\", \"Kent\", \"33601\", \"South Georgia and The South Sandwich Islands\" ],\n\t[ \"142\", \"Nasim\", \"Coleman\", \"19377\", \"United States Minor Outlying Islands\" ],\n\t[ \"143\", \"Geoffrey\", \"Byers\", \"85753\", \"Netherlands Antilles\" ],\n\t[ \"144\", \"Odette\", \"Sawyer\", \"55418\", \"Tunisia\" ],\n\t[ \"145\", \"Chaney\", \"Flowers\", \"F4W 7O7\", \"Maldives\" ],\n\t[ \"146\", \"Shelly\", \"Glover\", \"M5Y 4A6\", \"Taiwan, Province of China\" ],\n\t[ \"147\", \"Uriel\", \"Thornton\", \"Z6Q 5B7\", \"Myanmar\" ],\n\t[ \"148\", \"Clio\", \"Nicholson\", \"Y8S 7P2\", \"Martinique\" ],\n\t[ \"149\", \"Jana\", \"Foley\", \"B1O 9J5\", \"United Arab Emirates\" ],\n\t[ \"150\", \"Fulton\", \"Rasmussen\", \"39194\", \"Solomon Islands\" ],\n\t[ \"151\", \"Lisandra\", \"Boyd\", \"J2Z 2V7\", \"French Guiana\" ],\n\t[ \"152\", \"Brennan\", \"Lopez\", \"Q4M 7Y4\", \"Burkina Faso\" ],\n\t[ \"153\", \"Martha\", \"Washington\", \"M7S 4U6\", \"Iran, Islamic Republic of\" ],\n\t[ \"154\", \"Dara\", \"Ramos\", \"07799\", \"Portugal\" ],\n\t[ \"155\", \"Virginia\", \"Harris\", \"01246\", \"Bermuda\" ],\n\t[ \"156\", \"Maryam\", \"Patrick\", \"Y3J 4Y0\", \"Rwanda\" ],\n\t[ \"157\", \"Shana\", \"Mullen\", \"61169\", \"Togo\" ],\n\t[ \"158\", \"Rowan\", \"Hahn\", \"K6D 5T4\", \"Guinea-bissau\" ],\n\t[ \"159\", \"Hermione\", \"Shepherd\", \"M4F 7T6\", \"Ireland\" ],\n\t[ \"160\", \"Jada\", \"Bright\", \"P1Z 7E6\", \"French Southern Territories\" ],\n\t[ \"161\", \"Scarlet\", \"Bray\", \"57161\", \"Austria\" ],\n\t[ \"162\", \"Haviva\", \"Conner\", \"M4T 8O4\", \"Bermuda\" ],\n\t[ \"163\", \"Myra\", \"Briggs\", \"Q4B 6L7\", \"Kenya\" ],\n\t[ \"164\", \"Hall\", \"Floyd\", \"40411\", \"Bangladesh\" ],\n\t[ \"165\", \"Kyle\", \"Marquez\", \"J4T 7C6\", \"Djibouti\" ],\n\t[ \"166\", \"Claudia\", \"Long\", \"R7B 1T6\", \"Macedonia\" ],\n\t[ \"167\", \"Hasad\", \"Clemons\", \"94009\", \"Bosnia and Herzegovina\" ],\n\t[ \"168\", \"Kameko\", \"Reeves\", \"G4V 6D5\", \"Singapore\" ],\n\t[ \"169\", \"Angelica\", \"Bailey\", \"Z3Y 7I0\", \"Micronesia\" ],\n\t[ \"170\", \"Shelley\", \"Jennings\", \"O3A 9H0\", \"Christmas Island\" ],\n\t[ \"171\", \"Rafael\", \"Randolph\", \"Y4L 8B5\", \"Germany\" ],\n\t[ \"172\", \"Winter\", \"Kinney\", \"A3K 9A7\", \"Saint Lucia\" ],\n\t[ \"173\", \"Brian\", \"Larsen\", \"53752\", \"Comoros\" ],\n\t[ \"174\", \"Melvin\", \"Cooper\", \"72416\", \"Czech Republic\" ],\n\t[ \"175\", \"Gil\", \"Valencia\", \"95798\", \"Uganda\" ],\n\t[ \"176\", \"Uma\", \"Cummings\", \"84649\", \"Jordan\" ],\n\t[ \"177\", \"Micah\", \"Shannon\", \"H9L 8R6\", \"Ghana\" ],\n\t[ \"178\", \"Ahmed\", \"Weiss\", \"05291\", \"American Samoa\" ],\n\t[ \"179\", \"Hop\", \"Foster\", \"W9C 7J7\", \"Panama\" ],\n\t[ \"180\", \"Todd\", \"Barnett\", \"T9R 7J4\", \"Seychelles\" ],\n\t[ \"181\", \"Byron\", \"Meyers\", \"J4G 9P2\", \"Congo\" ],\n\t[ \"182\", \"Hadassah\", \"Barnett\", \"U1A 8V3\", \"Paraguay\" ],\n\t[ \"183\", \"Hermione\", \"Luna\", \"L4G 2E5\", \"New Zealand\" ],\n\t[ \"184\", \"Marsden\", \"Alvarado\", \"U1V 1Y4\", \"Aruba\" ],\n\t[ \"185\", \"Britanni\", \"Gregory\", \"C8O 2T4\", \"Kazakhstan\" ],\n\t[ \"186\", \"Brenda\", \"Oneil\", \"R9Q 9B7\", \"Gibraltar\" ],\n\t[ \"187\", \"Reuben\", \"Hopkins\", \"C2D 9D0\", \"Bhutan\" ],\n\t[ \"188\", \"Sonia\", \"Sandoval\", \"Y2G 5I0\", \"Guatemala\" ],\n\t[ \"189\", \"Yasir\", \"Holcomb\", \"A1H 6Y3\", \"Angola\" ],\n\t[ \"190\", \"Aristotle\", \"Rosa\", \"51870\", \"Indonesia\" ],\n\t[ \"191\", \"Uriah\", \"Blair\", \"X8K 1B9\", \"Suriname\" ],\n\t[ \"192\", \"Vaughan\", \"Sharp\", \"L2F 5N8\", \"Faroe Islands\" ],\n\t[ \"193\", \"Cooper\", \"Beard\", \"80399\", \"United States Minor Outlying Islands\" ],\n\t[ \"194\", \"Riley\", \"Greene\", \"44728\", \"Russian Federation\" ],\n\t[ \"195\", \"Rashad\", \"Flowers\", \"L6N 8U7\", \"Mongolia\" ],\n\t[ \"196\", \"Yvonne\", \"Wilson\", \"18599\", \"Svalbard and Jan Mayen\" ],\n\t[ \"197\", \"Martena\", \"Ayers\", \"A8Z 5F7\", \"Oman\" ],\n\t[ \"198\", \"Eagan\", \"Cline\", \"T9P 4L4\", \"Solomon Islands\" ],\n\t[ \"199\", \"Dawn\", \"Carrillo\", \"T6O 6E5\", \"Malawi\" ],\n\t[ \"200\", \"Ali\", \"Singleton\", \"G6F 3B4\", \"Italy\" ],\n\t[ \"201\", \"Christopher\", \"Beach\", \"01655\", \"Palau\" ],\n\t[ \"202\", \"Emma\", \"Cummings\", \"W1B 4R6\", \"Dominica\" ],\n\t[ \"203\", \"Ishmael\", \"Gray\", \"76928\", \"Egypt\" ],\n\t[ \"204\", \"Megan\", \"Hines\", \"F7X 2X5\", \"New Zealand\" ],\n\t[ \"205\", \"Emmanuel\", \"Steele\", \"09729\", \"Netherlands\" ],\n\t[ \"206\", \"Alea\", \"Burris\", \"08485\", \"Guatemala\" ],\n\t[ \"207\", \"Martina\", \"Todd\", \"46863\", \"Christmas Island\" ],\n\t[ \"208\", \"Len\", \"Valentine\", \"S6Z 5S8\", \"Slovenia\" ],\n\t[ \"209\", \"Jorden\", \"Salazar\", \"U4D 8H6\", \"Austria\" ],\n\t[ \"210\", \"Yvette\", \"Bradford\", \"17275\", \"Heard Island and Mcdonald Islands\" ],\n\t[ \"211\", \"Elvis\", \"Mcmahon\", \"27586\", \"Marshall Islands\" ],\n\t[ \"212\", \"Gray\", \"Bonner\", \"N4V 3U9\", \"Moldova\" ],\n\t[ \"213\", \"Yoshi\", \"Singleton\", \"86603\", \"United Kingdom\" ],\n\t[ \"214\", \"Amena\", \"Burks\", \"93820\", \"Reunion\" ],\n\t[ \"215\", \"Ocean\", \"Maldonado\", \"72026\", \"Ireland\" ],\n\t[ \"216\", \"Allen\", \"Foley\", \"75363\", \"Kiribati\" ],\n\t[ \"217\", \"Duncan\", \"Jimenez\", \"H3H 3G6\", \"Oman\" ],\n\t[ \"218\", \"Ira\", \"Maxwell\", \"53136\", \"French Polynesia\" ],\n\t[ \"219\", \"Astra\", \"Moon\", \"D7W 8G2\", \"Dominican Republic\" ],\n\t[ \"220\", \"Orson\", \"Myers\", \"06049\", \"Mali\" ],\n\t[ \"221\", \"Brandon\", \"Estes\", \"D2B 7P2\", \"Kenya\" ],\n\t[ \"222\", \"Halee\", \"Luna\", \"54733\", \"Moldova\" ],\n\t[ \"223\", \"Jillian\", \"Gonzalez\", \"E8W 3L9\", \"Ecuador\" ],\n\t[ \"224\", \"Julie\", \"Acosta\", \"X7M 1T2\", \"Equatorial Guinea\" ],\n\t[ \"225\", \"Quemby\", \"Foster\", \"48596\", \"Eritrea\" ],\n\t[ \"226\", \"Erich\", \"Chavez\", \"W4P 7G8\", \"Mayotte\" ],\n\t[ \"227\", \"Roary\", \"Mcknight\", \"K9K 2K4\", \"Chile\" ],\n\t[ \"228\", \"Mufutau\", \"Henderson\", \"81377\", \"Mayotte\" ],\n\t[ \"229\", \"Herman\", \"Ferguson\", \"69405\", \"Japan\" ],\n\t[ \"230\", \"Abdul\", \"Franks\", \"L1V 8X2\", \"Portugal\" ],\n\t[ \"231\", \"Dominic\", \"Logan\", \"98770\", \"Saint Lucia\" ],\n\t[ \"232\", \"Isadora\", \"Solis\", \"Y3A 6H5\", \"Portugal\" ],\n\t[ \"233\", \"Lester\", \"Davis\", \"30339\", \"British Indian Ocean Territory\" ],\n\t[ \"234\", \"Joel\", \"Rojas\", \"N8E 5T9\", \"Bahrain\" ],\n\t[ \"235\", \"Quinlan\", \"Carroll\", \"55785\", \"Australia\" ],\n\t[ \"236\", \"Guinevere\", \"Pickett\", \"A7Y 3V3\", \"Netherlands Antilles\" ],\n\t[ \"237\", \"Nita\", \"Hopkins\", \"88370\", \"Albania\" ],\n\t[ \"238\", \"Hayley\", \"Buckley\", \"F1V 7P5\", \"Togo\" ],\n\t[ \"239\", \"Colorado\", \"Reyes\", \"18798\", \"Congo\" ],\n\t[ \"240\", \"Tashya\", \"Bartlett\", \"48537\", \"Sierra Leone\" ],\n\t[ \"241\", \"Isabella\", \"Keith\", \"48878\", \"Kiribati\" ],\n\t[ \"242\", \"Jessica\", \"Noble\", \"D6C 9T9\", \"Svalbard and Jan Mayen\" ],\n\t[ \"243\", \"Cairo\", \"Edwards\", \"40598\", \"Nepal\" ],\n\t[ \"244\", \"Camille\", \"Bradley\", \"I4U 8F6\", \"Fiji\" ],\n\t[ \"245\", \"Quin\", \"Mcgee\", \"O5D 2P0\", \"Poland\" ],\n\t[ \"246\", \"Rina\", \"Guzman\", \"44940\", \"Bahrain\" ],\n\t[ \"247\", \"Glenna\", \"Kirkland\", \"Z1L 4W2\", \"San Marino\" ],\n\t[ \"248\", \"Tarik\", \"Todd\", \"77228\", \"Turks and Caicos Islands\" ],\n\t[ \"249\", \"Yardley\", \"Burris\", \"M6U 9D7\", \"New Caledonia\" ],\n\t[ \"250\", \"Hashim\", \"Casey\", \"17722\", \"Lesotho\" ],\n\t[ \"251\", \"Maggie\", \"Raymond\", \"62540\", \"Uganda\" ],\n\t[ \"252\", \"Christian\", \"Mcdonald\", \"R8K 2M1\", \"United Arab Emirates\" ],\n\t[ \"253\", \"Colt\", \"Cobb\", \"75393\", \"Moldova\" ],\n\t[ \"254\", \"Aline\", \"Graves\", \"I1C 9I6\", \"Holy See (Vatican City State)\" ],\n\t[ \"255\", \"Farrah\", \"Cannon\", \"H5W 2Y0\", \"Bhutan\" ],\n\t[ \"256\", \"Wynne\", \"Ayers\", \"B6X 6Y8\", \"Western Sahara\" ],\n\t[ \"257\", \"Teegan\", \"Avery\", \"33643\", \"San Marino\" ],\n\t[ \"258\", \"Shana\", \"Sloan\", \"K9P 9V7\", \"Gabon\" ],\n\t[ \"259\", \"Britanney\", \"Cook\", \"Y5D 6K7\", \"Romania\" ],\n\t[ \"260\", \"Kuame\", \"Schroeder\", \"12859\", \"Syrian Arab Republic\" ],\n\t[ \"261\", \"Valentine\", \"Joseph\", \"P2S 6T6\", \"Mayotte\" ],\n\t[ \"262\", \"Joelle\", \"Keller\", \"U6F 3T7\", \"Fiji\" ],\n\t[ \"263\", \"Elaine\", \"Hickman\", \"28056\", \"Tuvalu\" ],\n\t[ \"264\", \"Ivor\", \"Malone\", \"H2Z 5X5\", \"Virgin Islands, British\" ],\n\t[ \"265\", \"Maris\", \"Jefferson\", \"12474\", \"Czech Republic\" ],\n\t[ \"266\", \"Josephine\", \"Zimmerman\", \"Z5J 2I4\", \"Angola\" ],\n\t[ \"267\", \"Baker\", \"Wooten\", \"X4K 2L8\", \"Austria\" ],\n\t[ \"268\", \"Alyssa\", \"Mitchell\", \"97712\", \"Antarctica\" ],\n\t[ \"269\", \"Carlos\", \"Pearson\", \"85838\", \"Gambia\" ],\n\t[ \"270\", \"Luke\", \"Richardson\", \"73867\", \"Christmas Island\" ],\n\t[ \"271\", \"Davis\", \"Gardner\", \"U2E 4D9\", \"Chile\" ],\n\t[ \"272\", \"Thomas\", \"Conner\", \"92487\", \"Mozambique\" ],\n\t[ \"273\", \"Kieran\", \"Baird\", \"X9G 6G1\", \"Iceland\" ],\n\t[ \"274\", \"Cheyenne\", \"Morris\", \"F5V 4S2\", \"Greece\" ],\n\t[ \"275\", \"Hillary\", \"Reeves\", \"89804\", \"Slovakia\" ],\n\t[ \"276\", \"Ryder\", \"Long\", \"32725\", \"New Caledonia\" ],\n\t[ \"277\", \"Ariel\", \"Colon\", \"50675\", \"Estonia\" ],\n\t[ \"278\", \"Vanna\", \"Hess\", \"79057\", \"Saudi Arabia\" ],\n\t[ \"279\", \"Hayley\", \"Cherry\", \"B5E 9X4\", \"United States Minor Outlying Islands\" ],\n\t[ \"280\", \"Knox\", \"Blair\", \"75626\", \"Central African Republic\" ],\n\t[ \"281\", \"Astra\", \"Mcdaniel\", \"24493\", \"Bermuda\" ],\n\t[ \"282\", \"Teegan\", \"Ford\", \"A8U 1K9\", \"Iran, Islamic Republic of\" ],\n\t[ \"283\", \"Harrison\", \"Jackson\", \"43519\", \"Marshall Islands\" ],\n\t[ \"284\", \"Melyssa\", \"Lawson\", \"O7E 8E6\", \"Belize\" ],\n\t[ \"285\", \"Shaine\", \"Francis\", \"Q5K 5I4\", \"India\" ],\n\t[ \"286\", \"August\", \"Reed\", \"S9R 1O8\", \"Ghana\" ],\n\t[ \"287\", \"Aphrodite\", \"Zimmerman\", \"28336\", \"Lesotho\" ],\n\t[ \"288\", \"Declan\", \"Walters\", \"08662\", \"Rwanda\" ],\n\t[ \"289\", \"Brody\", \"Pate\", \"G2G 9D9\", \"Serbia and Montenegro\" ],\n\t[ \"290\", \"Bradley\", \"Odom\", \"L2R 6Z9\", \"Jordan\" ],\n\t[ \"291\", \"Phillip\", \"Cleveland\", \"E4D 1B7\", \"Paraguay\" ],\n\t[ \"292\", \"Silas\", \"Wiggins\", \"F9F 5X3\", \"Bahrain\" ],\n\t[ \"293\", \"Keely\", \"Donaldson\", \"B5H 7F2\", \"Vanuatu\" ],\n\t[ \"294\", \"Hammett\", \"Lancaster\", \"H2P 4E6\", \"Svalbard and Jan Mayen\" ],\n\t[ \"295\", \"Kiara\", \"Clarke\", \"50885\", \"Thailand\" ],\n\t[ \"296\", \"Ayanna\", \"Wiley\", \"20773\", \"Morocco\" ],\n\t[ \"297\", \"Tashya\", \"Stanley\", \"F5J 5R9\", \"New Caledonia\" ],\n\t[ \"298\", \"Margaret\", \"Barker\", \"J5A 9N8\", \"Marshall Islands\" ],\n\t[ \"299\", \"Xandra\", \"English\", \"92299\", \"Korea, Republic of\" ],\n\t[ \"300\", \"Jane\", \"Brock\", \"86140\", \"Yemen\" ],\n\t[ \"301\", \"Lunea\", \"Garrett\", \"96730\", \"New Caledonia\" ],\n\t[ \"302\", \"Slade\", \"Everett\", \"16105\", \"Malawi\" ],\n\t[ \"303\", \"Scott\", \"Booker\", \"G8V 2R4\", \"Macedonia\" ],\n\t[ \"304\", \"Candice\", \"Decker\", \"E5R 2D4\", \"China\" ],\n\t[ \"305\", \"Armando\", \"Bridges\", \"87959\", \"Falkland Islands (Malvinas)\" ],\n\t[ \"306\", \"Clayton\", \"Whitley\", \"Q6O 4M7\", \"British Indian Ocean Territory\" ],\n\t[ \"307\", \"Driscoll\", \"Duncan\", \"M2J 9V5\", \"Argentina\" ],\n\t[ \"308\", \"Devin\", \"Stafford\", \"L8F 2V7\", \"Svalbard and Jan Mayen\" ],\n\t[ \"309\", \"Bell\", \"York\", \"E5B 7X5\", \"Lebanon\" ],\n\t[ \"310\", \"Haley\", \"Becker\", \"19759\", \"Bhutan\" ],\n\t[ \"311\", \"Chava\", \"Santiago\", \"04396\", \"Israel\" ],\n\t[ \"312\", \"David\", \"Mccall\", \"62087\", \"Norfolk Island\" ],\n\t[ \"313\", \"Clinton\", \"Jacobson\", \"06168\", \"Guam\" ],\n\t[ \"314\", \"Melvin\", \"Kaufman\", \"C4E 9N6\", \"Gambia\" ],\n\t[ \"315\", \"Dai\", \"Shepherd\", \"37490\", \"Saudi Arabia\" ],\n\t[ \"316\", \"Zahir\", \"Chase\", \"44340\", \"Turkey\" ],\n\t[ \"317\", \"Leilani\", \"Parrish\", \"62576\", \"Cocos (Keeling) Islands\" ],\n\t[ \"318\", \"Oleg\", \"Wilkins\", \"Z7S 8Z4\", \"Latvia\" ],\n\t[ \"319\", \"Pearl\", \"Pena\", \"82526\", \"Saudi Arabia\" ],\n\t[ \"320\", \"Kelly\", \"Moody\", \"W7U 5Y3\", \"Burundi\" ],\n\t[ \"321\", \"Marcia\", \"Kennedy\", \"85952\", \"Panama\" ],\n\t[ \"322\", \"Cailin\", \"Burnett\", \"M2Z 3L5\", \"Guyana\" ],\n\t[ \"323\", \"Ciara\", \"Small\", \"X6C 6M6\", \"Tanzania, United Republic of\" ],\n\t[ \"324\", \"Lillian\", \"Massey\", \"Z8A 5U5\", \"Algeria\" ],\n\t[ \"325\", \"Garrett\", \"Elliott\", \"R5P 6T0\", \"Canada\" ],\n\t[ \"326\", \"Inga\", \"Daniels\", \"40156\", \"Cocos (Keeling) Islands\" ],\n\t[ \"327\", \"Barry\", \"Pena\", \"03593\", \"Tonga\" ],\n\t[ \"328\", \"Penelope\", \"Mcintyre\", \"29293\", \"Burkina Faso\" ],\n\t[ \"329\", \"Dante\", \"Kirk\", \"74038\", \"Lesotho\" ],\n\t[ \"330\", \"Owen\", \"Cole\", \"17968\", \"Rwanda\" ],\n\t[ \"331\", \"Brittany\", \"Edwards\", \"24507\", \"Paraguay\" ],\n\t[ \"332\", \"Zeph\", \"Bentley\", \"12000\", \"Guam\" ],\n\t[ \"333\", \"Ruth\", \"Palmer\", \"E8V 9A5\", \"Ghana\" ],\n\t[ \"334\", \"Driscoll\", \"Ellis\", \"X1X 2N5\", \"Angola\" ],\n\t[ \"335\", \"Mohammad\", \"Guerra\", \"Y9N 3Y5\", \"Mongolia\" ],\n\t[ \"336\", \"Clio\", \"Baldwin\", \"67557\", \"Morocco\" ],\n\t[ \"337\", \"Virginia\", \"Duncan\", \"J8D 4T2\", \"Haiti\" ],\n\t[ \"338\", \"Dieter\", \"Sanchez\", \"H7E 2H4\", \"Romania\" ],\n\t[ \"339\", \"Quinn\", \"Hurst\", \"K4E 2X6\", \"Reunion\" ],\n\t[ \"340\", \"Coby\", \"Kelly\", \"S1H 8N0\", \"Equatorial Guinea\" ],\n\t[ \"341\", \"Raja\", \"Solis\", \"S5G 9T5\", \"Grenada\" ],\n\t[ \"342\", \"Jordan\", \"Riddle\", \"J7M 5X3\", \"Svalbard and Jan Mayen\" ],\n\t[ \"343\", \"Dora\", \"Knox\", \"25054\", \"Libyan Arab Jamahiriya\" ],\n\t[ \"344\", \"Brendan\", \"Reilly\", \"U9U 3F7\", \"Armenia\" ],\n\t[ \"345\", \"Melyssa\", \"Reyes\", \"11285\", \"Viet Nam\" ],\n\t[ \"346\", \"Knox\", \"Rivera\", \"N8Z 7J0\", \"Nepal\" ],\n\t[ \"347\", \"Quynn\", \"Irwin\", \"26524\", \"Chile\" ],\n\t[ \"348\", \"Colin\", \"Coleman\", \"22833\", \"United Arab Emirates\" ],\n\t[ \"349\", \"Sybil\", \"Delgado\", \"99947\", \"Belize\" ],\n\t[ \"350\", \"Macaulay\", \"Salinas\", \"48521\", \"Heard Island and Mcdonald Islands\" ],\n\t[ \"351\", \"Garrison\", \"Hogan\", \"68950\", \"India\" ],\n\t[ \"352\", \"Ronan\", \"Guerra\", \"55445\", \"Angola\" ],\n\t[ \"353\", \"Regina\", \"Andrews\", \"H3E 3T0\", \"Central African Republic\" ],\n\t[ \"354\", \"Colorado\", \"Joyce\", \"V6X 5K8\", \"Anguilla\" ],\n\t[ \"355\", \"Basia\", \"Banks\", \"85049\", \"Grenada\" ],\n\t[ \"356\", \"Adena\", \"Berg\", \"04135\", \"New Caledonia\" ],\n\t[ \"357\", \"Wade\", \"Richardson\", \"C8M 9J3\", \"Dominican Republic\" ],\n\t[ \"358\", \"Cody\", \"Montoya\", \"22018\", \"Solomon Islands\" ],\n\t[ \"359\", \"Faith\", \"Barnett\", \"61475\", \"China\" ],\n\t[ \"360\", \"Cody\", \"Witt\", \"C8I 2Q8\", \"Congo\" ],\n\t[ \"361\", \"Brenden\", \"Carlson\", \"74007\", \"Marshall Islands\" ],\n\t[ \"362\", \"Gil\", \"Brooks\", \"U4S 5N1\", \"Saint Vincent and The Grenadines\" ],\n\t[ \"363\", \"Kirestin\", \"Watts\", \"H8I 1D5\", \"Myanmar\" ],\n\t[ \"364\", \"Amelia\", \"Gilliam\", \"11461\", \"Chile\" ],\n\t[ \"365\", \"Noelani\", \"Rhodes\", \"83320\", \"Cuba\" ],\n\t[ \"366\", \"Len\", \"Trevino\", \"W9F 2U5\", \"Armenia\" ],\n\t[ \"367\", \"Galvin\", \"Middleton\", \"86707\", \"Thailand\" ],\n\t[ \"368\", \"Germaine\", \"Bridges\", \"90283\", \"Japan\" ],\n\t[ \"369\", \"Rose\", \"Hines\", \"W7L 7Q6\", \"Congo\" ],\n\t[ \"370\", \"Hop\", \"Mueller\", \"I3E 2X8\", \"Angola\" ],\n\t[ \"371\", \"Iliana\", \"Williamson\", \"56758\", \"Lebanon\" ],\n\t[ \"372\", \"Raja\", \"Price\", \"49603\", \"Armenia\" ],\n\t[ \"373\", \"Jeanette\", \"Hatfield\", \"E3K 5N5\", \"India\" ],\n\t[ \"374\", \"Brittany\", \"Christensen\", \"04750\", \"Uruguay\" ],\n\t[ \"375\", \"Inga\", \"Prince\", \"D4X 6J5\", \"Switzerland\" ],\n\t[ \"376\", \"Cherokee\", \"Ballard\", \"U1O 1M0\", \"Rwanda\" ],\n\t[ \"377\", \"Deirdre\", \"Watson\", \"46983\", \"Sri Lanka\" ],\n\t[ \"378\", \"Amanda\", \"Parrish\", \"99838\", \"Hong Kong\" ],\n\t[ \"379\", \"Leo\", \"Shannon\", \"L3N 3J0\", \"Brunei Darussalam\" ],\n\t[ \"380\", \"Kimberly\", \"Clemons\", \"88734\", \"South Africa\" ],\n\t[ \"381\", \"Seth\", \"Langley\", \"D6A 1Q9\", \"Guyana\" ],\n\t[ \"382\", \"Carol\", \"Blankenship\", \"X5N 2A7\", \"Angola\" ],\n\t[ \"383\", \"Dora\", \"Flores\", \"F8F 1O5\", \"Poland\" ],\n\t[ \"384\", \"Chava\", \"Dickson\", \"P8B 6W6\", \"Comoros\" ],\n\t[ \"385\", \"Trevor\", \"Mcdowell\", \"31382\", \"Solomon Islands\" ],\n\t[ \"386\", \"Alec\", \"Valentine\", \"P2R 4K7\", \"Greenland\" ],\n\t[ \"387\", \"Philip\", \"Jenkins\", \"Q7X 5U5\", \"Aruba\" ],\n\t[ \"388\", \"Kim\", \"Bowen\", \"69873\", \"Saint Kitts and Nevis\" ],\n\t[ \"389\", \"Allegra\", \"Oconnor\", \"X3Y 1X3\", \"Holy See (Vatican City State)\" ],\n\t[ \"390\", \"Daria\", \"Briggs\", \"A7Z 7P4\", \"Serbia and Montenegro\" ],\n\t[ \"391\", \"Amelia\", \"Wiley\", \"D4S 1G5\", \"Montserrat\" ],\n\t[ \"392\", \"Erica\", \"Aguirre\", \"H5L 2O3\", \"Andorra\" ],\n\t[ \"393\", \"Kibo\", \"Sawyer\", \"30638\", \"Guyana\" ],\n\t[ \"394\", \"Jackson\", \"Meyers\", \"P4N 9D6\", \"Bangladesh\" ],\n\t[ \"395\", \"Kirk\", \"Baxter\", \"F3M 7S6\", \"Estonia\" ],\n\t[ \"396\", \"Sybil\", \"Christian\", \"B3Q 2X0\", \"South Georgia and The South Sandwich Islands\" ],\n\t[ \"397\", \"Ina\", \"Mercer\", \"N4S 1K8\", \"Korea\" ],\n\t[ \"398\", \"Kiara\", \"Whitehead\", \"86023\", \"Nicaragua\" ],\n\t[ \"399\", \"Vielka\", \"Hays\", \"29845\", \"Malta\" ],\n\t[ \"400\", \"Stacey\", \"Carlson\", \"53218\", \"Cook Islands\" ],\n\t[ \"401\", \"Selma\", \"Lloyd\", \"78256\", \"Turkey\" ],\n\t[ \"402\", \"Rhoda\", \"Mcintosh\", \"G8X 1C8\", \"Guatemala\" ],\n\t[ \"403\", \"Teagan\", \"Ochoa\", \"99752\", \"Barbados\" ],\n\t[ \"404\", \"Rebecca\", \"Carver\", \"82661\", \"Saint Kitts and Nevis\" ],\n\t[ \"405\", \"Yael\", \"Woodward\", \"66095\", \"Niger\" ],\n\t[ \"406\", \"Calvin\", \"Huffman\", \"82172\", \"Somalia\" ],\n\t[ \"407\", \"Sopoline\", \"Walters\", \"K5L 3I7\", \"Spain\" ],\n\t[ \"408\", \"Hollee\", \"Powell\", \"05572\", \"Samoa\" ],\n\t[ \"409\", \"Fiona\", \"Frank\", \"74456\", \"Timor-leste\" ],\n\t[ \"410\", \"Alana\", \"Hubbard\", \"76011\", \"Lithuania\" ],\n\t[ \"411\", \"Lillian\", \"Garcia\", \"J5Z 2O5\", \"Sierra Leone\" ],\n\t[ \"412\", \"Tad\", \"Mcleod\", \"B6A 8Z4\", \"Australia\" ],\n\t[ \"413\", \"Hadassah\", \"Hall\", \"47417\", \"China\" ],\n\t[ \"414\", \"Regan\", \"Summers\", \"X4L 4I6\", \"Honduras\" ],\n\t[ \"415\", \"Herrod\", \"Erickson\", \"R8G 3V0\", \"Israel\" ],\n\t[ \"416\", \"Autumn\", \"Rojas\", \"31205\", \"Cocos (Keeling) Islands\" ],\n\t[ \"417\", \"Castor\", \"Mooney\", \"92737\", \"Grenada\" ],\n\t[ \"418\", \"Wesley\", \"Holman\", \"57125\", \"Greenland\" ],\n\t[ \"419\", \"Kitra\", \"Wooten\", \"Q6X 4Y0\", \"Mongolia\" ],\n\t[ \"420\", \"Buckminster\", \"Rice\", \"U8B 7B8\", \"Tokelau\" ],\n\t[ \"421\", \"Xavier\", \"Hardin\", \"18280\", \"Iran, Islamic Republic of\" ],\n\t[ \"422\", \"Sopoline\", \"Fleming\", \"78437\", \"Singapore\" ],\n\t[ \"423\", \"Sydney\", \"Salinas\", \"23801\", \"Cook Islands\" ],\n\t[ \"424\", \"Bethany\", \"Rosales\", \"89650\", \"United States\" ],\n\t[ \"425\", \"Deirdre\", \"Hensley\", \"F3X 1B7\", \"Micronesia\" ],\n\t[ \"426\", \"Bernard\", \"Vargas\", \"S4D 9T0\", \"Uzbekistan\" ],\n\t[ \"427\", \"Merrill\", \"Compton\", \"17713\", \"Suriname\" ],\n\t[ \"428\", \"Carly\", \"Baird\", \"D3H 5G3\", \"United States Minor Outlying Islands\" ],\n\t[ \"429\", \"Grace\", \"Phelps\", \"64695\", \"Nauru\" ],\n\t[ \"430\", \"Kareem\", \"Stone\", \"65572\", \"Netherlands\" ],\n\t[ \"431\", \"Susan\", \"Newton\", \"04627\", \"Anguilla\" ],\n\t[ \"432\", \"Laura\", \"Miranda\", \"E1G 2R7\", \"Finland\" ],\n\t[ \"433\", \"Madaline\", \"Pugh\", \"J9A 9M5\", \"Senegal\" ],\n\t[ \"434\", \"Sophia\", \"Mendez\", \"33789\", \"Timor-leste\" ],\n\t[ \"435\", \"Roary\", \"Greene\", \"61774\", \"Canada\" ],\n\t[ \"436\", \"Amos\", \"Gilliam\", \"94933\", \"Sri Lanka\" ],\n\t[ \"437\", \"Ivory\", \"Joyner\", \"15379\", \"San Marino\" ],\n\t[ \"438\", \"Jorden\", \"Robbins\", \"43400\", \"Russian Federation\" ],\n\t[ \"439\", \"Merritt\", \"Holcomb\", \"R1I 3C7\", \"Brazil\" ],\n\t[ \"440\", \"Iliana\", \"Johnston\", \"U9W 8N2\", \"Trinidad and Tobago\" ],\n\t[ \"441\", \"Ivana\", \"Patterson\", \"G5O 6A5\", \"Georgia\" ],\n\t[ \"442\", \"Sydney\", \"Mccullough\", \"W9M 2H5\", \"American Samoa\" ],\n\t[ \"443\", \"Alvin\", \"Fulton\", \"X8A 8R5\", \"Antigua and Barbuda\" ],\n\t[ \"444\", \"Alfreda\", \"Lopez\", \"42499\", \"Montserrat\" ],\n\t[ \"445\", \"Ethan\", \"Bird\", \"W9A 8M1\", \"British Indian Ocean Territory\" ],\n\t[ \"446\", \"Zeus\", \"Logan\", \"01682\", \"San Marino\" ],\n\t[ \"447\", \"Nehru\", \"Andrews\", \"W8J 3C8\", \"Dominican Republic\" ],\n\t[ \"448\", \"Donna\", \"Booth\", \"64754\", \"Nepal\" ],\n\t[ \"449\", \"Cruz\", \"Bruce\", \"17429\", \"Burundi\" ],\n\t[ \"450\", \"Ronan\", \"Saunders\", \"69957\", \"South Africa\" ],\n\t[ \"451\", \"Jordan\", \"Barnes\", \"D8K 9L8\", \"Dominica\" ],\n\t[ \"452\", \"Carly\", \"Love\", \"D8Z 3P4\", \"Mauritania\" ],\n\t[ \"453\", \"Mari\", \"George\", \"60260\", \"Japan\" ],\n\t[ \"454\", \"Karly\", \"Hodges\", \"15790\", \"South Georgia and The South Sandwich Islands\" ],\n\t[ \"455\", \"Rana\", \"Logan\", \"M1R 6Y6\", \"Bosnia and Herzegovina\" ],\n\t[ \"456\", \"Theodore\", \"Sims\", \"C7A 8T2\", \"Barbados\" ],\n\t[ \"457\", \"Quin\", \"Thompson\", \"26884\", \"Bouvet Island\" ],\n\t[ \"458\", \"Kimberley\", \"Sloan\", \"S5T 8E3\", \"Costa Rica\" ],\n\t[ \"459\", \"Upton\", \"Valenzuela\", \"Z6J 6Q1\", \"Macao\" ],\n\t[ \"460\", \"Clinton\", \"Williams\", \"Z3O 7C4\", \"Germany\" ],\n\t[ \"461\", \"Samson\", \"Mathis\", \"G1T 1V9\", \"Senegal\" ],\n\t[ \"462\", \"Michelle\", \"Frost\", \"87113\", \"Serbia and Montenegro\" ],\n\t[ \"463\", \"Tyrone\", \"Coffey\", \"80705\", \"Albania\" ],\n\t[ \"464\", \"Alea\", \"Delaney\", \"E4S 4K4\", \"Guyana\" ],\n\t[ \"465\", \"Dominique\", \"Schwartz\", \"81368\", \"Falkland Islands (Malvinas)\" ],\n\t[ \"466\", \"Benedict\", \"Norton\", \"D1C 9C8\", \"Cyprus\" ],\n\t[ \"467\", \"Vaughan\", \"Stein\", \"R7K 1L8\", \"Egypt\" ],\n\t[ \"468\", \"Charles\", \"Foley\", \"20434\", \"Anguilla\" ],\n\t[ \"469\", \"Arden\", \"Ramos\", \"54065\", \"Gibraltar\" ],\n\t[ \"470\", \"Dillon\", \"Patel\", \"L6H 1H6\", \"Liberia\" ],\n\t[ \"471\", \"Gretchen\", \"Davenport\", \"57188\", \"Equatorial Guinea\" ],\n\t[ \"472\", \"Ivy\", \"Randall\", \"52617\", \"Costa Rica\" ],\n\t[ \"473\", \"Brett\", \"Baird\", \"45791\", \"Hungary\" ],\n\t[ \"474\", \"Wyoming\", \"Sparks\", \"11266\", \"Luxembourg\" ],\n\t[ \"475\", \"Rashad\", \"Roy\", \"47012\", \"Guam\" ],\n\t[ \"476\", \"Sopoline\", \"Le\", \"M1G 2P8\", \"United Arab Emirates\" ],\n\t[ \"477\", \"Ursa\", \"Haynes\", \"53774\", \"British Indian Ocean Territory\" ],\n\t[ \"478\", \"Maia\", \"Vincent\", \"26773\", \"New Caledonia\" ],\n\t[ \"479\", \"Salvador\", \"Pace\", \"S9E 2C4\", \"Egypt\" ],\n\t[ \"480\", \"Bethany\", \"Wilcox\", \"F2H 7N0\", \"Uzbekistan\" ],\n\t[ \"481\", \"Sara\", \"Brooks\", \"08176\", \"Holy See (Vatican City State)\" ],\n\t[ \"482\", \"Lillith\", \"Sampson\", \"75576\", \"British Indian Ocean Territory\" ],\n\t[ \"483\", \"Brynne\", \"Browning\", \"N4K 7P6\", \"Peru\" ],\n\t[ \"484\", \"Beck\", \"Tran\", \"06815\", \"Cambodia\" ],\n\t[ \"485\", \"Peter\", \"Hurley\", \"05770\", \"Rwanda\" ],\n\t[ \"486\", \"Buffy\", \"Sharpe\", \"H8F 8G6\", \"Georgia\" ],\n\t[ \"487\", \"Harrison\", \"Cross\", \"Y1A 1R8\", \"United Kingdom\" ],\n\t[ \"488\", \"Ursa\", \"Wolf\", \"J8C 9Q8\", \"French Polynesia\" ],\n\t[ \"489\", \"Nayda\", \"Vasquez\", \"05523\", \"Taiwan, Province of China\" ],\n\t[ \"490\", \"Gretchen\", \"Walters\", \"28628\", \"Seychelles\" ],\n\t[ \"491\", \"Adrian\", \"Hickman\", \"17956\", \"El Salvador\" ],\n\t[ \"492\", \"Laura\", \"Moon\", \"32103\", \"Myanmar\" ],\n\t[ \"493\", \"Kellie\", \"Barnett\", \"L5Z 2U8\", \"Saint Helena\" ],\n\t[ \"494\", \"Illana\", \"Stanton\", \"Z5D 2G0\", \"Australia\" ],\n\t[ \"495\", \"Jescie\", \"Santiago\", \"D9L 4B5\", \"Cambodia\" ],\n\t[ \"496\", \"Laura\", \"Hopkins\", \"X6V 9S5\", \"Netherlands Antilles\" ],\n\t[ \"497\", \"Vielka\", \"Harding\", \"U6A 9T2\", \"Cambodia\" ],\n\t[ \"498\", \"Walter\", \"Gentry\", \"L3X 9Q9\", \"Slovenia\" ],\n\t[ \"499\", \"Sara\", \"Atkinson\", \"67146\", \"Guinea\" ],\n\t[ \"500\", \"Yolanda\", \"Chambers\", \"Q8D 3W0\", \"Zimbabwe\" ],\n\t[ \"501\", \"Josiah\", \"Villarreal\", \"I1V 6Y7\", \"Burkina Faso\" ],\n\t[ \"502\", \"Hayfa\", \"Bowman\", \"77148\", \"Saudi Arabia\" ],\n\t[ \"503\", \"Colette\", \"Conley\", \"41232\", \"Estonia\" ],\n\t[ \"504\", \"Lana\", \"Doyle\", \"32962\", \"Cuba\" ],\n\t[ \"505\", \"Keegan\", \"Goodwin\", \"M2P 1X3\", \"Cocos (Keeling) Islands\" ],\n\t[ \"506\", \"Nina\", \"Cross\", \"49580\", \"Germany\" ],\n\t[ \"507\", \"Xenos\", \"Cervantes\", \"K6X 7W8\", \"Mauritius\" ],\n\t[ \"508\", \"Jared\", \"Hester\", \"30156\", \"Uzbekistan\" ],\n\t[ \"509\", \"Damon\", \"Curry\", \"U2J 2D8\", \"Pitcairn\" ],\n\t[ \"510\", \"Amery\", \"Savage\", \"O1S 2Z4\", \"Turkmenistan\" ],\n\t[ \"511\", \"Brian\", \"Wilkinson\", \"J6O 4T0\", \"Luxembourg\" ],\n\t[ \"512\", \"Ivory\", \"Mckinney\", \"L3E 8M2\", \"Lithuania\" ],\n\t[ \"513\", \"Eric\", \"Dalton\", \"Y1L 6F4\", \"Ethiopia\" ],\n\t[ \"514\", \"Brandon\", \"Callahan\", \"K6Q 9B4\", \"Haiti\" ],\n\t[ \"515\", \"Phillip\", \"Mclean\", \"18836\", \"Ethiopia\" ],\n\t[ \"516\", \"Carly\", \"Greer\", \"16811\", \"Mayotte\" ],\n\t[ \"517\", \"Stone\", \"Ware\", \"58795\", \"Moldova\" ],\n\t[ \"518\", \"Xena\", \"Hayden\", \"97158\", \"Chad\" ],\n\t[ \"519\", \"Catherine\", \"Leonard\", \"77868\", \"Azerbaijan\" ],\n\t[ \"520\", \"Bernard\", \"Horton\", \"04270\", \"Yemen\" ],\n\t[ \"521\", \"Olga\", \"Richmond\", \"89169\", \"Lebanon\" ],\n\t[ \"522\", \"Iris\", \"Cummings\", \"78836\", \"Falkland Islands (Malvinas)\" ],\n\t[ \"523\", \"Beau\", \"Mccall\", \"78638\", \"Monaco\" ],\n\t[ \"524\", \"Michael\", \"Humphrey\", \"Q1A 2W9\", \"Tokelau\" ],\n\t[ \"525\", \"Oren\", \"Stevens\", \"F4V 9G7\", \"Heard Island and Mcdonald Islands\" ],\n\t[ \"526\", \"Ima\", \"Shelton\", \"19295\", \"Mozambique\" ],\n\t[ \"527\", \"Merritt\", \"Morrison\", \"K6W 5R0\", \"Georgia\" ],\n\t[ \"528\", \"Vera\", \"Cherry\", \"54993\", \"Angola\" ],\n\t[ \"529\", \"Grant\", \"Turner\", \"B4V 2J0\", \"Saint Helena\" ],\n\t[ \"530\", \"Odette\", \"Snyder\", \"N9L 2V8\", \"Chad\" ],\n\t[ \"531\", \"Uma\", \"Stewart\", \"E9A 6X9\", \"Bhutan\" ],\n\t[ \"532\", \"Kylee\", \"Best\", \"11393\", \"Malaysia\" ],\n\t[ \"533\", \"Nicholas\", \"Mercado\", \"85179\", \"Switzerland\" ],\n\t[ \"534\", \"Nathaniel\", \"Stuart\", \"M1Q 6Z6\", \"Mongolia\" ],\n\t[ \"535\", \"Ruth\", \"Conrad\", \"T7G 9V6\", \"Guadeloupe\" ],\n\t[ \"536\", \"Deanna\", \"Dudley\", \"79721\", \"Kiribati\" ],\n\t[ \"537\", \"David\", \"Thornton\", \"C6R 2G3\", \"Netherlands Antilles\" ],\n\t[ \"538\", \"Jane\", \"Ashley\", \"48711\", \"Rwanda\" ],\n\t[ \"539\", \"Nero\", \"Curry\", \"20590\", \"Denmark\" ],\n\t[ \"540\", \"Kellie\", \"Poole\", \"46053\", \"Martinique\" ],\n\t[ \"541\", \"Freya\", \"Burch\", \"W5R 8Y5\", \"Northern Mariana Islands\" ],\n\t[ \"542\", \"Maxwell\", \"Mcbride\", \"D4W 4M3\", \"Paraguay\" ],\n\t[ \"543\", \"Dawn\", \"Sargent\", \"85956\", \"Gibraltar\" ],\n\t[ \"544\", \"Lilah\", \"Matthews\", \"J4D 8A9\", \"Montserrat\" ],\n\t[ \"545\", \"Salvador\", \"Burns\", \"28067\", \"Bhutan\" ],\n\t[ \"546\", \"Ezekiel\", \"Ayala\", \"67153\", \"Wallis and Futuna\" ],\n\t[ \"547\", \"Evan\", \"Barker\", \"83026\", \"Puerto Rico\" ],\n\t[ \"548\", \"Jemima\", \"Case\", \"U3S 7N6\", \"Georgia\" ],\n\t[ \"549\", \"Belle\", \"Mcconnell\", \"H4S 9F8\", \"Angola\" ],\n\t[ \"550\", \"Doris\", \"Mays\", \"57387\", \"Tonga\" ],\n\t[ \"551\", \"Carson\", \"Buchanan\", \"20457\", \"Guatemala\" ],\n\t[ \"552\", \"Calista\", \"Lamb\", \"26851\", \"Gibraltar\" ],\n\t[ \"553\", \"Remedios\", \"Haley\", \"A9K 5M1\", \"Tokelau\" ],\n\t[ \"554\", \"Odette\", \"Mccarty\", \"Y8B 3V4\", \"Marshall Islands\" ],\n\t[ \"555\", \"Libby\", \"Pugh\", \"93261\", \"Netherlands\" ],\n\t[ \"556\", \"Bo\", \"Maldonado\", \"C1H 1K7\", \"Oman\" ],\n\t[ \"557\", \"Cameron\", \"Beasley\", \"41821\", \"Northern Mariana Islands\" ],\n\t[ \"558\", \"Chadwick\", \"Crosby\", \"62855\", \"New Caledonia\" ],\n\t[ \"559\", \"Steven\", \"Barrett\", \"92102\", \"Pakistan\" ],\n\t[ \"560\", \"Jonas\", \"Valdez\", \"N3V 4R9\", \"Bulgaria\" ],\n\t[ \"561\", \"Harlan\", \"Larsen\", \"Z8F 6A0\", \"Cayman Islands\" ],\n\t[ \"562\", \"Iola\", \"Joyner\", \"D1J 4C3\", \"Italy\" ],\n\t[ \"563\", \"Abra\", \"Medina\", \"Q9O 5J2\", \"Cambodia\" ],\n\t[ \"564\", \"Solomon\", \"Davidson\", \"91317\", \"Turkmenistan\" ],\n\t[ \"565\", \"Alisa\", \"Kim\", \"33036\", \"Austria\" ],\n\t[ \"566\", \"Deacon\", \"Silva\", \"Z5L 6M0\", \"Djibouti\" ],\n\t[ \"567\", \"Bree\", \"Landry\", \"43135\", \"Czech Republic\" ],\n\t[ \"568\", \"Molly\", \"Leach\", \"71714\", \"Botswana\" ],\n\t[ \"569\", \"Idona\", \"Cain\", \"A2J 1R8\", \"South Georgia and The South Sandwich Islands\" ],\n\t[ \"570\", \"Aileen\", \"Salinas\", \"90344\", \"Uzbekistan\" ],\n\t[ \"571\", \"Dominique\", \"Cooper\", \"31803\", \"Sao Tome and Principe\" ],\n\t[ \"572\", \"Lunea\", \"Pollard\", \"S9R 7B0\", \"Sweden\" ],\n\t[ \"573\", \"Leo\", \"Combs\", \"W7E 8T4\", \"Ukraine\" ],\n\t[ \"574\", \"Illiana\", \"Donovan\", \"D8K 3R4\", \"Palau\" ],\n\t[ \"575\", \"Orlando\", \"Vaughan\", \"Q4I 3E3\", \"Bosnia and Herzegovina\" ],\n\t[ \"576\", \"Yuri\", \"Blake\", \"I9W 5U5\", \"Seychelles\" ],\n\t[ \"577\", \"Amanda\", \"Baldwin\", \"19752\", \"Turkmenistan\" ],\n\t[ \"578\", \"Hanna\", \"Emerson\", \"73316\", \"Antigua and Barbuda\" ],\n\t[ \"579\", \"Xyla\", \"Atkins\", \"11151\", \"Uganda\" ],\n\t[ \"580\", \"Nathaniel\", \"Patterson\", \"00391\", \"Portugal\" ],\n\t[ \"581\", \"Naida\", \"Cote\", \"17484\", \"Mauritius\" ],\n\t[ \"582\", \"Scarlett\", \"Little\", \"V8N 8A6\", \"Sao Tome and Principe\" ],\n\t[ \"583\", \"Odessa\", \"Kerr\", \"56456\", \"Sweden\" ],\n\t[ \"584\", \"Kamal\", \"Richardson\", \"F6S 4I1\", \"Algeria\" ],\n\t[ \"585\", \"Griffith\", \"Morton\", \"I5H 2Z0\", \"Vanuatu\" ],\n\t[ \"586\", \"Orli\", \"Santana\", \"48213\", \"Burundi\" ],\n\t[ \"587\", \"Courtney\", \"Cook\", \"R3O 3A9\", \"Cape Verde\" ],\n\t[ \"588\", \"Jolene\", \"Wallace\", \"F6Q 7W8\", \"Zambia\" ],\n\t[ \"589\", \"Bert\", \"Sharp\", \"X7T 7Z8\", \"Paraguay\" ],\n\t[ \"590\", \"Ila\", \"Carver\", \"E4M 7P4\", \"Paraguay\" ],\n\t[ \"591\", \"Merrill\", \"Wall\", \"49416\", \"Fiji\" ],\n\t[ \"592\", \"Hanae\", \"Espinoza\", \"Y6D 6K8\", \"Turkey\" ],\n\t[ \"593\", \"Stephanie\", \"Bond\", \"Z1Q 3P3\", \"Algeria\" ],\n\t[ \"594\", \"Lionel\", \"Leonard\", \"U8O 7G6\", \"Nauru\" ],\n\t[ \"595\", \"Faith\", \"Ramirez\", \"75181\", \"Slovakia\" ],\n\t[ \"596\", \"Fritz\", \"Glass\", \"62878\", \"El Salvador\" ],\n\t[ \"597\", \"Raya\", \"Gardner\", \"L3E 2C7\", \"India\" ],\n\t[ \"598\", \"Brynne\", \"Price\", \"W1S 6O9\", \"Lithuania\" ],\n\t[ \"599\", \"Karen\", \"Gray\", \"O4X 8F6\", \"Albania\" ],\n\t[ \"600\", \"Perry\", \"Goodwin\", \"44266\", \"Libyan Arab Jamahiriya\" ],\n\t[ \"601\", \"Dylan\", \"Glover\", \"76573\", \"Estonia\" ],\n\t[ \"602\", \"Melinda\", \"Holloway\", \"07861\", \"Grenada\" ],\n\t[ \"603\", \"Rahim\", \"Robinson\", \"D7M 1E8\", \"Madagascar\" ],\n\t[ \"604\", \"Ori\", \"Oconnor\", \"10386\", \"Antarctica\" ],\n\t[ \"605\", \"Candace\", \"Preston\", \"03610\", \"Denmark\" ],\n\t[ \"606\", \"Wing\", \"Howe\", \"E6U 3H2\", \"Burundi\" ],\n\t[ \"607\", \"Lucy\", \"Eaton\", \"26436\", \"Guinea\" ],\n\t[ \"608\", \"Ignatius\", \"Blevins\", \"93597\", \"Serbia and Montenegro\" ],\n\t[ \"609\", \"Nadine\", \"Franco\", \"80096\", \"Tonga\" ],\n\t[ \"610\", \"Shoshana\", \"Walters\", \"S4F 5O8\", \"Micronesia\" ],\n\t[ \"611\", \"Remedios\", \"Buckner\", \"29213\", \"Antigua and Barbuda\" ],\n\t[ \"612\", \"Adam\", \"Horne\", \"F8V 1V8\", \"Oman\" ],\n\t[ \"613\", \"Kieran\", \"Saunders\", \"I7A 7Y5\", \"Japan\" ],\n\t[ \"614\", \"Isabelle\", \"Fletcher\", \"K2K 3K5\", \"Norway\" ],\n\t[ \"615\", \"Ryder\", \"Ballard\", \"38518\", \"Tanzania, United Republic of\" ],\n\t[ \"616\", \"Nina\", \"Guerrero\", \"61142\", \"Saint Kitts and Nevis\" ],\n\t[ \"617\", \"Sheila\", \"Poole\", \"E2H 6I6\", \"Denmark\" ],\n\t[ \"618\", \"Melyssa\", \"Mcdaniel\", \"08247\", \"Netherlands Antilles\" ],\n\t[ \"619\", \"Leila\", \"Vang\", \"Q5Z 3S1\", \"United States Minor Outlying Islands\" ],\n\t[ \"620\", \"Grady\", \"Aguilar\", \"R1I 8I8\", \"Slovenia\" ],\n\t[ \"621\", \"Plato\", \"Terrell\", \"23916\", \"Kuwait\" ],\n\t[ \"622\", \"Rama\", \"Perkins\", \"56506\", \"Russian Federation\" ],\n\t[ \"623\", \"Boris\", \"Chaney\", \"66737\", \"Antigua and Barbuda\" ],\n\t[ \"624\", \"Edward\", \"Clarke\", \"30722\", \"Iraq\" ],\n\t[ \"625\", \"Skyler\", \"Wise\", \"53248\", \"Taiwan, Province of China\" ],\n\t[ \"626\", \"Uta\", \"Cox\", \"85242\", \"Malawi\" ],\n\t[ \"627\", \"Lesley\", \"Watkins\", \"26710\", \"Estonia\" ],\n\t[ \"628\", \"Gray\", \"Harrison\", \"C5L 9Y7\", \"Nepal\" ],\n\t[ \"629\", \"Joan\", \"Flores\", \"J5Q 2B9\", \"Tajikistan\" ],\n\t[ \"630\", \"Reece\", \"Lott\", \"85152\", \"Algeria\" ],\n\t[ \"631\", \"Jerome\", \"Faulkner\", \"V1K 3N2\", \"Kiribati\" ],\n\t[ \"632\", \"Jackson\", \"Hudson\", \"85932\", \"Botswana\" ],\n\t[ \"633\", \"Uma\", \"Booker\", \"79755\", \"Senegal\" ],\n\t[ \"634\", \"Katelyn\", \"Gillespie\", \"Q8P 4V9\", \"Eritrea\" ],\n\t[ \"635\", \"Clio\", \"Tillman\", \"67552\", \"Liberia\" ],\n\t[ \"636\", \"Anjolie\", \"Nixon\", \"36615\", \"Botswana\" ],\n\t[ \"637\", \"Nell\", \"Lee\", \"T9S 4R3\", \"French Southern Territories\" ],\n\t[ \"638\", \"Anthony\", \"Aguirre\", \"85443\", \"Morocco\" ],\n\t[ \"639\", \"Aaron\", \"Green\", \"90326\", \"Faroe Islands\" ],\n\t[ \"640\", \"Galvin\", \"Yang\", \"A4X 8H6\", \"Ukraine\" ],\n\t[ \"641\", \"Yoshi\", \"Strickland\", \"52538\", \"Brazil\" ],\n\t[ \"642\", \"Brenden\", \"Kirkland\", \"X7P 8V9\", \"Turks and Caicos Islands\" ],\n\t[ \"643\", \"Bree\", \"Stone\", \"U4L 2H2\", \"Hong Kong\" ],\n\t[ \"644\", \"Quin\", \"Tanner\", \"U4A 1X4\", \"Faroe Islands\" ],\n\t[ \"645\", \"Camilla\", \"Heath\", \"91749\", \"Andorra\" ],\n\t[ \"646\", \"Xaviera\", \"Bullock\", \"I4U 7W0\", \"Libyan Arab Jamahiriya\" ],\n\t[ \"647\", \"Kay\", \"Rowe\", \"59689\", \"Iceland\" ],\n\t[ \"648\", \"Lance\", \"Bond\", \"66558\", \"Spain\" ],\n\t[ \"649\", \"Fredericka\", \"Langley\", \"48782\", \"Cayman Islands\" ],\n\t[ \"650\", \"Charles\", \"Avila\", \"42037\", \"Papua New Guinea\" ],\n\t[ \"651\", \"Ramona\", \"Rios\", \"T5M 3E1\", \"Argentina\" ],\n\t[ \"652\", \"Ezekiel\", \"Young\", \"W8X 4S7\", \"French Polynesia\" ],\n\t[ \"653\", \"Celeste\", \"Dodson\", \"19140\", \"Benin\" ],\n\t[ \"654\", \"Frances\", \"Mcintosh\", \"91246\", \"Swaziland\" ],\n\t[ \"655\", \"Deanna\", \"Hyde\", \"J8P 3T5\", \"Croatia\" ],\n\t[ \"656\", \"Dahlia\", \"Blair\", \"45364\", \"Kazakhstan\" ],\n\t[ \"657\", \"Jade\", \"Hayes\", \"I5Q 3S9\", \"Malawi\" ],\n\t[ \"658\", \"Robin\", \"Bullock\", \"G9Q 2P8\", \"Ireland\" ],\n\t[ \"659\", \"Nasim\", \"Bond\", \"I2V 8N4\", \"Macedonia\" ],\n\t[ \"660\", \"Axel\", \"Pickett\", \"18370\", \"Saint Vincent and The Grenadines\" ],\n\t[ \"661\", \"Pearl\", \"Lee\", \"G1R 3R8\", \"Poland\" ],\n\t[ \"662\", \"Garth\", \"Meyers\", \"90308\", \"Georgia\" ],\n\t[ \"663\", \"Ivory\", \"Rios\", \"S8F 8R5\", \"Mexico\" ],\n\t[ \"664\", \"Jerome\", \"Lambert\", \"N1Q 6R8\", \"Saint Lucia\" ],\n\t[ \"665\", \"Meredith\", \"Clark\", \"27720\", \"Cocos (Keeling) Islands\" ],\n\t[ \"666\", \"Armando\", \"Holcomb\", \"M6D 4X0\", \"Oman\" ],\n\t[ \"667\", \"Rowan\", \"Page\", \"00307\", \"Nauru\" ],\n\t[ \"668\", \"Kyla\", \"Brown\", \"F4W 4C5\", \"Holy See (Vatican City State)\" ],\n\t[ \"669\", \"Leigh\", \"Sosa\", \"28499\", \"Uruguay\" ],\n\t[ \"670\", \"Shafira\", \"Forbes\", \"26526\", \"Honduras\" ],\n\t[ \"671\", \"Maxine\", \"Mueller\", \"90923\", \"Kazakhstan\" ],\n\t[ \"672\", \"Joy\", \"Sargent\", \"K6T 3W5\", \"Malawi\" ],\n\t[ \"673\", \"Lamar\", \"Roberts\", \"R5F 9C8\", \"Poland\" ],\n\t[ \"674\", \"Madonna\", \"Love\", \"15514\", \"Cyprus\" ],\n\t[ \"675\", \"Uriel\", \"Ware\", \"Z6V 5J1\", \"Singapore\" ],\n\t[ \"676\", \"Bevis\", \"Erickson\", \"M3X 9M8\", \"Brunei Darussalam\" ],\n\t[ \"677\", \"Grant\", \"Velasquez\", \"96942\", \"Antarctica\" ],\n\t[ \"678\", \"Lars\", \"Bullock\", \"14772\", \"Guyana\" ],\n\t[ \"679\", \"Maryam\", \"Jones\", \"01854\", \"Togo\" ],\n\t[ \"680\", \"Blythe\", \"Goodwin\", \"51731\", \"New Caledonia\" ],\n\t[ \"681\", \"Kane\", \"Wiggins\", \"55727\", \"Kiribati\" ],\n\t[ \"682\", \"Brian\", \"Rosales\", \"25896\", \"Cape Verde\" ],\n\t[ \"683\", \"Blaze\", \"Leach\", \"P6J 3E5\", \"Northern Mariana Islands\" ],\n\t[ \"684\", \"Cameron\", \"Neal\", \"82248\", \"Marshall Islands\" ],\n\t[ \"685\", \"Lydia\", \"Cunningham\", \"Q1V 8P7\", \"San Marino\" ],\n\t[ \"686\", \"Troy\", \"Cook\", \"32106\", \"British Indian Ocean Territory\" ],\n\t[ \"687\", \"Alexander\", \"Valenzuela\", \"S8Z 6B2\", \"Guadeloupe\" ],\n\t[ \"688\", \"Garth\", \"Beck\", \"46344\", \"Cook Islands\" ],\n\t[ \"689\", \"Hillary\", \"Nunez\", \"29462\", \"Sri Lanka\" ],\n\t[ \"690\", \"Hunter\", \"Sawyer\", \"W9M 6T4\", \"Saint Lucia\" ],\n\t[ \"691\", \"Jaquelyn\", \"Everett\", \"T1X 2U2\", \"Guinea-bissau\" ],\n\t[ \"692\", \"Indira\", \"Ortega\", \"43047\", \"Italy\" ],\n\t[ \"693\", \"Josiah\", \"Hinton\", \"N5F 5Y8\", \"Andorra\" ],\n\t[ \"694\", \"Bruno\", \"Gay\", \"E3U 3D9\", \"Palau\" ],\n\t[ \"695\", \"Melissa\", \"Blackburn\", \"S4V 1K2\", \"Virgin Islands, U.S.\" ],\n\t[ \"696\", \"Zeus\", \"Dawson\", \"K5S 6Z6\", \"Belgium\" ],\n\t[ \"697\", \"Castor\", \"Mcmahon\", \"H3R 1O8\", \"Cambodia\" ],\n\t[ \"698\", \"Elizabeth\", \"Beasley\", \"98178\", \"Northern Mariana Islands\" ],\n\t[ \"699\", \"Jescie\", \"Lee\", \"08056\", \"Eritrea\" ],\n\t[ \"700\", \"Dennis\", \"Chapman\", \"T4O 1Q2\", \"Bangladesh\" ],\n\t[ \"701\", \"Basia\", \"Wallace\", \"U3Y 7C1\", \"Pitcairn\" ],\n\t[ \"702\", \"Dante\", \"Brewer\", \"53544\", \"Bosnia and Herzegovina\" ],\n\t[ \"703\", \"Adrienne\", \"Glenn\", \"32378\", \"Austria\" ],\n\t[ \"704\", \"Kellie\", \"Acevedo\", \"51723\", \"Italy\" ],\n\t[ \"705\", \"Scarlet\", \"Mclaughlin\", \"43509\", \"Kiribati\" ],\n\t[ \"706\", \"Lillith\", \"Mullins\", \"S6L 4Y6\", \"Kyrgyzstan\" ],\n\t[ \"707\", \"Maxine\", \"Atkins\", \"Z5T 5R5\", \"Denmark\" ],\n\t[ \"708\", \"Nicholas\", \"Rose\", \"40286\", \"Macedonia\" ],\n\t[ \"709\", \"Zenia\", \"Pugh\", \"28682\", \"Venezuela\" ],\n\t[ \"710\", \"Keely\", \"Turner\", \"34939\", \"New Zealand\" ],\n\t[ \"711\", \"Maisie\", \"Walton\", \"S6M 5C5\", \"Cameroon\" ],\n\t[ \"712\", \"Michelle\", \"Salinas\", \"T7A 9N6\", \"Nicaragua\" ],\n\t[ \"713\", \"Reece\", \"Clements\", \"73923\", \"Austria\" ],\n\t[ \"714\", \"Eliana\", \"Fox\", \"V3Y 5T4\", \"Denmark\" ],\n\t[ \"715\", \"Kennedy\", \"Mullins\", \"43213\", \"Virgin Islands, British\" ],\n\t[ \"716\", \"Alea\", \"Glover\", \"M6P 3Z5\", \"Turkmenistan\" ],\n\t[ \"717\", \"Scarlett\", \"Hunt\", \"41461\", \"Montserrat\" ],\n\t[ \"718\", \"Rooney\", \"Kane\", \"T8A 3E2\", \"Madagascar\" ],\n\t[ \"719\", \"Cairo\", \"Ray\", \"L6M 1E7\", \"Canada\" ],\n\t[ \"720\", \"Wendy\", \"Burks\", \"R8V 8F5\", \"Virgin Islands, U.S.\" ],\n\t[ \"721\", \"Christine\", \"Suarez\", \"67369\", \"Georgia\" ],\n\t[ \"722\", \"Graiden\", \"Le\", \"K4M 9V5\", \"New Caledonia\" ],\n\t[ \"723\", \"Zane\", \"Nunez\", \"60548\", \"Haiti\" ],\n\t[ \"724\", \"Ali\", \"Bell\", \"U4Y 4C3\", \"Togo\" ],\n\t[ \"725\", \"Marsden\", \"Leon\", \"39374\", \"Venezuela\" ],\n\t[ \"726\", \"Holmes\", \"Kidd\", \"B6K 7Q9\", \"Iraq\" ],\n\t[ \"727\", \"Cameron\", \"Gardner\", \"88627\", \"Brazil\" ],\n\t[ \"728\", \"Ava\", \"George\", \"K1Z 7Y2\", \"Monaco\" ],\n\t[ \"729\", \"Chantale\", \"Holland\", \"H1B 9L8\", \"Afghanistan\" ],\n\t[ \"730\", \"Alika\", \"Middleton\", \"W8X 7O1\", \"Korea\" ],\n\t[ \"731\", \"Cameran\", \"Zimmerman\", \"78576\", \"Benin\" ],\n\t[ \"732\", \"Barrett\", \"Blair\", \"51161\", \"Virgin Islands, U.S.\" ],\n\t[ \"733\", \"Brielle\", \"Ballard\", \"59538\", \"Iceland\" ],\n\t[ \"734\", \"Teagan\", \"Morales\", \"40107\", \"Kenya\" ],\n\t[ \"735\", \"Lunea\", \"Cantu\", \"14690\", \"Oman\" ],\n\t[ \"736\", \"Robin\", \"Gilmore\", \"17972\", \"Nauru\" ],\n\t[ \"737\", \"Hall\", \"Mccarty\", \"86141\", \"China\" ],\n\t[ \"738\", \"Olga\", \"Rasmussen\", \"58309\", \"Virgin Islands, British\" ],\n\t[ \"739\", \"Mark\", \"Griffin\", \"51542\", \"Argentina\" ],\n\t[ \"740\", \"Medge\", \"Carrillo\", \"23192\", \"Pitcairn\" ],\n\t[ \"741\", \"Susan\", \"Mosley\", \"32128\", \"Turkmenistan\" ],\n\t[ \"742\", \"Zelda\", \"Valdez\", \"46831\", \"New Caledonia\" ],\n\t[ \"743\", \"Ruth\", \"Donaldson\", \"F9I 7G7\", \"Ukraine\" ],\n\t[ \"744\", \"Kirby\", \"Workman\", \"36679\", \"Rwanda\" ],\n\t[ \"745\", \"Alexa\", \"King\", \"66513\", \"Liberia\" ],\n\t[ \"746\", \"Ronan\", \"Gross\", \"K2S 6D0\", \"Saint Lucia\" ],\n\t[ \"747\", \"Kylee\", \"Dillon\", \"P7Y 1I5\", \"Faroe Islands\" ],\n\t[ \"748\", \"Brenda\", \"Weaver\", \"99365\", \"Uzbekistan\" ],\n\t[ \"749\", \"Aristotle\", \"Orr\", \"43451\", \"Canada\" ],\n\t[ \"750\", \"Jaquelyn\", \"Tyler\", \"B9Q 7P5\", \"Brunei Darussalam\" ],\n\t[ \"751\", \"Madeline\", \"Stewart\", \"D4D 2J4\", \"Zimbabwe\" ],\n\t[ \"752\", \"Lacota\", \"Glass\", \"89124\", \"Israel\" ],\n\t[ \"753\", \"Adrian\", \"Ashley\", \"N8M 4L1\", \"Sri Lanka\" ],\n\t[ \"754\", \"Ignatius\", \"Waller\", \"12053\", \"Thailand\" ],\n\t[ \"755\", \"Raven\", \"Stevens\", \"88768\", \"Estonia\" ],\n\t[ \"756\", \"Carly\", \"Camacho\", \"27075\", \"Vanuatu\" ],\n\t[ \"757\", \"Lee\", \"Calderon\", \"19501\", \"Pitcairn\" ],\n\t[ \"758\", \"Amos\", \"Briggs\", \"I6A 3L8\", \"Saint Kitts and Nevis\" ],\n\t[ \"759\", \"Cheryl\", \"Valencia\", \"90517\", \"Denmark\" ],\n\t[ \"760\", \"Kenyon\", \"Franco\", \"B2S 2E2\", \"Western Sahara\" ],\n\t[ \"761\", \"Damian\", \"Acosta\", \"A2S 6D0\", \"Bahamas\" ],\n\t[ \"762\", \"Brenda\", \"Zamora\", \"T9E 7L3\", \"Finland\" ],\n\t[ \"763\", \"Connor\", \"Atkinson\", \"03975\", \"Sierra Leone\" ],\n\t[ \"764\", \"Kaseem\", \"Waters\", \"A2K 2X0\", \"China\" ],\n\t[ \"765\", \"Zephania\", \"Whitfield\", \"A4Z 9P7\", \"Eritrea\" ],\n\t[ \"766\", \"Emmanuel\", \"Ballard\", \"G1M 6Y2\", \"Finland\" ],\n\t[ \"767\", \"Amos\", \"Walters\", \"43184\", \"Oman\" ],\n\t[ \"768\", \"Urielle\", \"Browning\", \"19959\", \"Panama\" ],\n\t[ \"769\", \"TaShya\", \"Summers\", \"B9V 3Y3\", \"Micronesia\" ],\n\t[ \"770\", \"Jermaine\", \"Mcgee\", \"X8A 4E1\", \"Cape Verde\" ],\n\t[ \"771\", \"Chaney\", \"Berry\", \"G2H 2C8\", \"Uganda\" ],\n\t[ \"772\", \"Jaime\", \"May\", \"49723\", \"Eritrea\" ],\n\t[ \"773\", \"Olga\", \"Cohen\", \"13403\", \"Macao\" ],\n\t[ \"774\", \"Jacob\", \"Vaughn\", \"U7G 1V5\", \"Greece\" ],\n\t[ \"775\", \"Kelly\", \"Mcdonald\", \"Z3B 5G7\", \"Kiribati\" ],\n\t[ \"776\", \"Emi\", \"Gilbert\", \"W1L 2M4\", \"Nicaragua\" ],\n\t[ \"777\", \"Francis\", \"Nunez\", \"K4U 6M5\", \"Lithuania\" ],\n\t[ \"778\", \"Noel\", \"Nelson\", \"Z5T 1Y0\", \"Nauru\" ],\n\t[ \"779\", \"Ora\", \"Ellison\", \"Y5I 4R8\", \"Burundi\" ],\n\t[ \"780\", \"Kirby\", \"Glass\", \"J5X 2E3\", \"Argentina\" ],\n\t[ \"781\", \"Hayley\", \"Tate\", \"V1T 6B6\", \"Greece\" ],\n\t[ \"782\", \"Mohammad\", \"Leblanc\", \"E3S 5R3\", \"Oman\" ],\n\t[ \"783\", \"Lionel\", \"Todd\", \"A1Z 9E1\", \"Macedonia\" ],\n\t[ \"784\", \"Courtney\", \"Mckay\", \"D4I 8Z3\", \"Fiji\" ],\n\t[ \"785\", \"Reagan\", \"West\", \"84159\", \"Equatorial Guinea\" ],\n\t[ \"786\", \"Noel\", \"Strickland\", \"Q7K 6S3\", \"Mozambique\" ],\n\t[ \"787\", \"Lara\", \"Porter\", \"49872\", \"Nigeria\" ],\n\t[ \"788\", \"Kyra\", \"Haley\", \"I9E 2K3\", \"Dominican Republic\" ],\n\t[ \"789\", \"Wynter\", \"Beasley\", \"66330\", \"Heard Island and Mcdonald Islands\" ],\n\t[ \"790\", \"Vladimir\", \"Briggs\", \"99538\", \"Burkina Faso\" ],\n\t[ \"791\", \"Rafael\", \"Campbell\", \"V8L 2S6\", \"Algeria\" ],\n\t[ \"792\", \"Buffy\", \"Wilder\", \"N3U 2X0\", \"Bahrain\" ],\n\t[ \"793\", \"Nyssa\", \"Dawson\", \"38434\", \"Spain\" ],\n\t[ \"794\", \"Sylvia\", \"Swanson\", \"39714\", \"Azerbaijan\" ],\n\t[ \"795\", \"Jolie\", \"Diaz\", \"A1J 5I1\", \"Cuba\" ],\n\t[ \"796\", \"Rosalyn\", \"Mcdaniel\", \"F3T 6E2\", \"Benin\" ],\n\t[ \"797\", \"Nelle\", \"Prince\", \"K1M 4U6\", \"Maldives\" ],\n\t[ \"798\", \"Luke\", \"Knight\", \"05930\", \"Seychelles\" ],\n\t[ \"799\", \"Macaulay\", \"Conway\", \"79707\", \"American Samoa\" ],\n\t[ \"800\", \"Freya\", \"Webb\", \"U2H 2D7\", \"Ireland\" ],\n\t[ \"801\", \"Clinton\", \"Meyers\", \"S9I 7N2\", \"Malta\" ],\n\t[ \"802\", \"Rudyard\", \"Chandler\", \"40347\", \"Bahrain\" ],\n\t[ \"803\", \"Courtney\", \"Hoover\", \"12325\", \"French Polynesia\" ],\n\t[ \"804\", \"Melissa\", \"Davenport\", \"K7P 1S8\", \"Canada\" ],\n\t[ \"805\", \"Noelle\", \"Nieves\", \"87427\", \"Martinique\" ],\n\t[ \"806\", \"Myles\", \"Hart\", \"V6T 1W0\", \"Niue\" ],\n\t[ \"807\", \"Jasper\", \"Campos\", \"78143\", \"Faroe Islands\" ],\n\t[ \"808\", \"Ariana\", \"Valentine\", \"J4X 2D4\", \"Ecuador\" ],\n\t[ \"809\", \"Vanna\", \"Fletcher\", \"M4Z 1F9\", \"Faroe Islands\" ],\n\t[ \"810\", \"Elijah\", \"Harper\", \"Y1B 7E4\", \"New Zealand\" ],\n\t[ \"811\", \"Leilani\", \"Nunez\", \"K9W 4F0\", \"United Arab Emirates\" ],\n\t[ \"812\", \"Maia\", \"Huber\", \"V4L 8M6\", \"United Kingdom\" ],\n\t[ \"813\", \"Richard\", \"Riddle\", \"U8C 8Q2\", \"Niue\" ],\n\t[ \"814\", \"Harper\", \"Blanchard\", \"10904\", \"Cameroon\" ],\n\t[ \"815\", \"Aurelia\", \"Trujillo\", \"01646\", \"Dominican Republic\" ],\n\t[ \"816\", \"Anthony\", \"Owen\", \"J2I 2B4\", \"Palestinian Territory, Occupied\" ],\n\t[ \"817\", \"Kelsie\", \"Roy\", \"M3J 6K3\", \"Maldives\" ],\n\t[ \"818\", \"James\", \"Pearson\", \"94810\", \"Mexico\" ],\n\t[ \"819\", \"Igor\", \"Marshall\", \"Y8M 2D6\", \"Palau\" ],\n\t[ \"820\", \"Aquila\", \"Willis\", \"20354\", \"Samoa\" ],\n\t[ \"821\", \"Randall\", \"Sheppard\", \"73577\", \"Sierra Leone\" ],\n\t[ \"822\", \"Gray\", \"Myers\", \"53651\", \"Gibraltar\" ],\n\t[ \"823\", \"Dana\", \"Camacho\", \"89571\", \"Reunion\" ],\n\t[ \"824\", \"Berk\", \"Hopper\", \"17794\", \"Cook Islands\" ],\n\t[ \"825\", \"Shannon\", \"Barry\", \"70536\", \"Bouvet Island\" ],\n\t[ \"826\", \"Dahlia\", \"Herman\", \"F8L 1Q3\", \"Lesotho\" ],\n\t[ \"827\", \"Gillian\", \"Hayes\", \"O2C 7X8\", \"Tajikistan\" ],\n\t[ \"828\", \"Leo\", \"Bolton\", \"P6V 6E1\", \"Dominica\" ],\n\t[ \"829\", \"Vivien\", \"Best\", \"E5E 6N8\", \"Cuba\" ],\n\t[ \"830\", \"Clayton\", \"Bradley\", \"E7R 3M5\", \"Zimbabwe\" ],\n\t[ \"831\", \"Lesley\", \"Collins\", \"16592\", \"Mali\" ],\n\t[ \"832\", \"Holly\", \"Hensley\", \"49080\", \"Tunisia\" ],\n\t[ \"833\", \"Larissa\", \"Velazquez\", \"41068\", \"Haiti\" ],\n\t[ \"834\", \"Delilah\", \"Mejia\", \"A5I 9Q9\", \"Croatia\" ],\n\t[ \"835\", \"Drew\", \"Roberson\", \"U7E 3R1\", \"Somalia\" ],\n\t[ \"836\", \"Jenette\", \"Patel\", \"64084\", \"Denmark\" ],\n\t[ \"837\", \"Gillian\", \"Cleveland\", \"05659\", \"Syrian Arab Republic\" ],\n\t[ \"838\", \"Noelle\", \"Lara\", \"U1N 6V6\", \"Sri Lanka\" ],\n\t[ \"839\", \"Celeste\", \"Rollins\", \"26590\", \"Mayotte\" ],\n\t[ \"840\", \"Elvis\", \"Fletcher\", \"M8V 6J4\", \"Bahamas\" ],\n\t[ \"841\", \"Caesar\", \"Hays\", \"E3D 3T7\", \"Malta\" ],\n\t[ \"842\", \"Rama\", \"Weber\", \"25880\", \"Malta\" ],\n\t[ \"843\", \"Lael\", \"Page\", \"57135\", \"Anguilla\" ],\n\t[ \"844\", \"Omar\", \"Hammond\", \"90213\", \"Belarus\" ],\n\t[ \"845\", \"Simone\", \"Mcintosh\", \"L5P 1S0\", \"Bhutan\" ],\n\t[ \"846\", \"Gay\", \"Harper\", \"56404\", \"Virgin Islands, U.S.\" ],\n\t[ \"847\", \"Joel\", \"Holman\", \"C1F 1C4\", \"Saint Lucia\" ],\n\t[ \"848\", \"Clayton\", \"Pennington\", \"57003\", \"Kazakhstan\" ],\n\t[ \"849\", \"Susan\", \"Mckee\", \"I5U 8F2\", \"Taiwan, Province of China\" ],\n\t[ \"850\", \"Jenna\", \"Stein\", \"P2K 6L4\", \"Reunion\" ],\n\t[ \"851\", \"Madonna\", \"Joyner\", \"Q4Q 4K6\", \"Guadeloupe\" ],\n\t[ \"852\", \"Deirdre\", \"Ingram\", \"N7U 3N9\", \"Monaco\" ],\n\t[ \"853\", \"Juliet\", \"Hodges\", \"U2Q 2T0\", \"Uzbekistan\" ],\n\t[ \"854\", \"Naomi\", \"Rice\", \"O6T 2Z1\", \"Nicaragua\" ],\n\t[ \"855\", \"Leila\", \"Alvarado\", \"Z2V 7L3\", \"Suriname\" ],\n\t[ \"856\", \"George\", \"Leon\", \"L6M 1V2\", \"Norway\" ],\n\t[ \"857\", \"Rama\", \"Cruz\", \"Y2S 7K6\", \"Kenya\" ],\n\t[ \"858\", \"Clarke\", \"Mckinney\", \"34622\", \"Viet Nam\" ],\n\t[ \"859\", \"Savannah\", \"Bailey\", \"L3O 1U6\", \"Solomon Islands\" ],\n\t[ \"860\", \"Maxwell\", \"Gibson\", \"R9K 9Q1\", \"Virgin Islands, British\" ],\n\t[ \"861\", \"Devin\", \"Humphrey\", \"74821\", \"Costa Rica\" ],\n\t[ \"862\", \"Kadeem\", \"Larsen\", \"43178\", \"Luxembourg\" ],\n\t[ \"863\", \"Elvis\", \"Todd\", \"O3O 3G9\", \"Azerbaijan\" ],\n\t[ \"864\", \"Levi\", \"Montoya\", \"G1Y 1N8\", \"Venezuela\" ],\n\t[ \"865\", \"Risa\", \"Barnes\", \"86118\", \"Benin\" ],\n\t[ \"866\", \"Dillon\", \"Riggs\", \"O3Y 8V2\", \"Greenland\" ],\n\t[ \"867\", \"Stewart\", \"Marshall\", \"V8G 8S2\", \"Mexico\" ],\n\t[ \"868\", \"Camden\", \"Goff\", \"N3W 2L0\", \"Bahrain\" ],\n\t[ \"869\", \"Sheila\", \"Meadows\", \"T6K 7M2\", \"Yemen\" ],\n\t[ \"870\", \"Hop\", \"Berger\", \"Q8B 9R7\", \"Germany\" ],\n\t[ \"871\", \"Charissa\", \"Wilkerson\", \"08090\", \"Burundi\" ],\n\t[ \"872\", \"Raphael\", \"Carey\", \"03667\", \"United Kingdom\" ],\n\t[ \"873\", \"Micah\", \"Hood\", \"T9N 4T5\", \"Georgia\" ],\n\t[ \"874\", \"Cathleen\", \"Mccall\", \"N6H 6N3\", \"Tanzania, United Republic of\" ],\n\t[ \"875\", \"Lisandra\", \"Poole\", \"S7O 1J1\", \"Greece\" ],\n\t[ \"876\", \"Stone\", \"Blackwell\", \"90654\", \"Serbia and Montenegro\" ],\n\t[ \"877\", \"Serena\", \"Mann\", \"32305\", \"Trinidad and Tobago\" ],\n\t[ \"878\", \"Scarlet\", \"Turner\", \"D7Y 8N4\", \"Oman\" ],\n\t[ \"879\", \"Zenaida\", \"Carrillo\", \"60361\", \"Montserrat\" ],\n\t[ \"880\", \"Jaime\", \"Dalton\", \"F4E 6R5\", \"Iraq\" ],\n\t[ \"881\", \"Wesley\", \"Drake\", \"D8J 9U2\", \"Bulgaria\" ],\n\t[ \"882\", \"Armand\", \"Chandler\", \"X8Z 9E6\", \"Saint Kitts and Nevis\" ],\n\t[ \"883\", \"Inez\", \"Dillard\", \"59975\", \"Eritrea\" ],\n\t[ \"884\", \"Roanna\", \"Floyd\", \"65958\", \"Bolivia\" ],\n\t[ \"885\", \"Timon\", \"Dalton\", \"O3Q 5B5\", \"Colombia\" ],\n\t[ \"886\", \"Ifeoma\", \"Lamb\", \"J9A 9X0\", \"Papua New Guinea\" ],\n\t[ \"887\", \"Brody\", \"Cash\", \"75525\", \"Kazakhstan\" ],\n\t[ \"888\", \"Dawn\", \"Wise\", \"G7X 5J3\", \"Samoa\" ],\n\t[ \"889\", \"Chaney\", \"Bartlett\", \"11112\", \"Ecuador\" ],\n\t[ \"890\", \"Galvin\", \"Merritt\", \"59635\", \"Bahrain\" ],\n\t[ \"891\", \"Cynthia\", \"Nash\", \"U5P 1H4\", \"Switzerland\" ],\n\t[ \"892\", \"Tara\", \"Austin\", \"Q6X 8U0\", \"Burundi\" ],\n\t[ \"893\", \"Roanna\", \"Petty\", \"28524\", \"Northern Mariana Islands\" ],\n\t[ \"894\", \"Palmer\", \"Mcdowell\", \"78234\", \"United States Minor Outlying Islands\" ],\n\t[ \"895\", \"Sade\", \"Patton\", \"28984\", \"Czech Republic\" ],\n\t[ \"896\", \"Yoko\", \"Compton\", \"62165\", \"Saint Kitts and Nevis\" ],\n\t[ \"897\", \"Regan\", \"Mccarthy\", \"C5D 6G0\", \"Lebanon\" ],\n\t[ \"898\", \"Norman\", \"Nixon\", \"E4C 4G0\", \"Virgin Islands, U.S.\" ],\n\t[ \"899\", \"Jocelyn\", \"Baldwin\", \"X9R 2B3\", \"Macedonia\" ],\n\t[ \"900\", \"Jaquelyn\", \"Berg\", \"N6X 6E1\", \"Saint Lucia\" ],\n\t[ \"901\", \"Zane\", \"Nelson\", \"G9P 4J8\", \"Macao\" ],\n\t[ \"902\", \"Judith\", \"Elliott\", \"R4I 4O3\", \"Iraq\" ],\n\t[ \"903\", \"Maia\", \"Ellis\", \"S9V 6P0\", \"Bahrain\" ],\n\t[ \"904\", \"Mechelle\", \"Stevens\", \"43406\", \"Bouvet Island\" ],\n\t[ \"905\", \"Sylvester\", \"Duran\", \"K5D 8W5\", \"Costa Rica\" ],\n\t[ \"906\", \"Unity\", \"Cooke\", \"64362\", \"Ecuador\" ],\n\t[ \"907\", \"Karly\", \"Velazquez\", \"43286\", \"Guam\" ],\n\t[ \"908\", \"Damian\", \"Yates\", \"84910\", \"Thailand\" ],\n\t[ \"909\", \"Linus\", \"Gross\", \"31808\", \"Israel\" ],\n\t[ \"910\", \"Cooper\", \"Franco\", \"36700\", \"Yemen\" ],\n\t[ \"911\", \"Gail\", \"Jones\", \"09157\", \"Turkey\" ],\n\t[ \"912\", \"Hayfa\", \"Bennett\", \"59422\", \"France\" ],\n\t[ \"913\", \"Hermione\", \"Barber\", \"I6W 8Z5\", \"Mozambique\" ],\n\t[ \"914\", \"Hedy\", \"Stevens\", \"35535\", \"Cuba\" ],\n\t[ \"915\", \"Galvin\", \"Frederick\", \"J2W 9A3\", \"Virgin Islands, British\" ],\n\t[ \"916\", \"Lamar\", \"Rush\", \"P4O 3H4\", \"Austria\" ],\n\t[ \"917\", \"Brenda\", \"Walter\", \"K8Q 9H9\", \"Tajikistan\" ],\n\t[ \"918\", \"Ria\", \"Guy\", \"12801\", \"Gibraltar\" ],\n\t[ \"919\", \"Bruno\", \"Lynch\", \"I6U 7D0\", \"Greenland\" ],\n\t[ \"920\", \"Kirk\", \"Pearson\", \"66242\", \"Falkland Islands (Malvinas)\" ],\n\t[ \"921\", \"Owen\", \"Sosa\", \"61483\", \"Martinique\" ],\n\t[ \"922\", \"Rajah\", \"Mccarty\", \"G9K 6L2\", \"Faroe Islands\" ],\n\t[ \"923\", \"Erasmus\", \"Malone\", \"D6H 7H5\", \"Sierra Leone\" ],\n\t[ \"924\", \"Raja\", \"Hale\", \"85590\", \"Guadeloupe\" ],\n\t[ \"925\", \"Logan\", \"Christensen\", \"Y6L 8Z0\", \"Guatemala\" ],\n\t[ \"926\", \"Kirestin\", \"Griffith\", \"47900\", \"Micronesia\" ],\n\t[ \"927\", \"Kato\", \"Reeves\", \"93779\", \"Uruguay\" ],\n\t[ \"928\", \"Jonah\", \"Suarez\", \"13708\", \"Spain\" ],\n\t[ \"929\", \"Adam\", \"Lynn\", \"E1P 1L3\", \"Indonesia\" ],\n\t[ \"930\", \"Quinn\", \"Mckinney\", \"99683\", \"Faroe Islands\" ],\n\t[ \"931\", \"Whilemina\", \"Macias\", \"32145\", \"Iceland\" ],\n\t[ \"932\", \"Gillian\", \"Osborne\", \"L3L 6G0\", \"Italy\" ],\n\t[ \"933\", \"Venus\", \"Zamora\", \"28318\", \"Comoros\" ],\n\t[ \"934\", \"Allegra\", \"Eaton\", \"P5X 9S0\", \"Antarctica\" ],\n\t[ \"935\", \"Driscoll\", \"Preston\", \"R3L 9R0\", \"Niue\" ],\n\t[ \"936\", \"Joel\", \"Spencer\", \"12006\", \"Monaco\" ],\n\t[ \"937\", \"Lucius\", \"Sharp\", \"B8V 6U7\", \"Dominica\" ],\n\t[ \"938\", \"Curran\", \"Robinson\", \"82216\", \"Romania\" ],\n\t[ \"939\", \"Kerry\", \"Espinoza\", \"N4B 7Q1\", \"Guatemala\" ],\n\t[ \"940\", \"Isaac\", \"Kline\", \"85674\", \"Costa Rica\" ],\n\t[ \"941\", \"Neil\", \"Harrison\", \"I5A 2S2\", \"Greenland\" ],\n\t[ \"942\", \"Ezra\", \"Rodriguez\", \"D6P 5Q3\", \"Angola\" ],\n\t[ \"943\", \"Galvin\", \"Jefferson\", \"D6H 7G0\", \"Macedonia\" ],\n\t[ \"944\", \"Joseph\", \"Hahn\", \"Z8V 9B5\", \"Uganda\" ],\n\t[ \"945\", \"Naida\", \"Hammond\", \"40105\", \"Philippines\" ],\n\t[ \"946\", \"Brenna\", \"Everett\", \"41704\", \"Indonesia\" ],\n\t[ \"947\", \"Rae\", \"Parks\", \"79077\", \"Sweden\" ],\n\t[ \"948\", \"Jessica\", \"Richard\", \"Y3I 5R3\", \"Uganda\" ],\n\t[ \"949\", \"Rachel\", \"Marks\", \"16157\", \"Cameroon\" ],\n\t[ \"950\", \"Maxwell\", \"Ferguson\", \"V6A 6M0\", \"Ukraine\" ],\n\t[ \"951\", \"Alyssa\", \"Beard\", \"13936\", \"Antarctica\" ],\n\t[ \"952\", \"Camille\", \"Gill\", \"V9Q 9P7\", \"New Caledonia\" ],\n\t[ \"953\", \"Cora\", \"Bond\", \"M9X 1A4\", \"Seychelles\" ],\n\t[ \"954\", \"Peter\", \"Acosta\", \"07937\", \"Chile\" ],\n\t[ \"955\", \"Ella\", \"Poole\", \"A3F 9Z1\", \"Panama\" ],\n\t[ \"956\", \"Ashely\", \"Guerrero\", \"37436\", \"Central African Republic\" ],\n\t[ \"957\", \"Mikayla\", \"Johnston\", \"L9W 5T8\", \"Cameroon\" ],\n\t[ \"958\", \"Ora\", \"Weaver\", \"65897\", \"Turks and Caicos Islands\" ],\n\t[ \"959\", \"Timon\", \"Barnes\", \"R6J 1J7\", \"Djibouti\" ],\n\t[ \"960\", \"Jamalia\", \"Wade\", \"22211\", \"United States\" ],\n\t[ \"961\", \"Bradley\", \"Haney\", \"K1H 1Q1\", \"Western Sahara\" ],\n\t[ \"962\", \"Lance\", \"Le\", \"H4R 9T7\", \"Botswana\" ],\n\t[ \"963\", \"Ethan\", \"Rich\", \"T8N 1C6\", \"Netherlands\" ],\n\t[ \"964\", \"Jeanette\", \"Carver\", \"G1E 5C8\", \"Cook Islands\" ],\n\t[ \"965\", \"Ocean\", \"Marquez\", \"15084\", \"Pakistan\" ],\n\t[ \"966\", \"Ifeoma\", \"Cleveland\", \"R9D 6M1\", \"French Guiana\" ],\n\t[ \"967\", \"Sylvia\", \"Herring\", \"U4R 8P1\", \"Thailand\" ],\n\t[ \"968\", \"Clare\", \"Huffman\", \"Q5G 2Q0\", \"Niger\" ],\n\t[ \"969\", \"Colton\", \"Leach\", \"V3F 9W6\", \"Syrian Arab Republic\" ],\n\t[ \"970\", \"Maryam\", \"Hoover\", \"Y7U 6N3\", \"Slovakia\" ],\n\t[ \"971\", \"Nola\", \"Snider\", \"54275\", \"Bosnia and Herzegovina\" ],\n\t[ \"972\", \"Kameko\", \"Cote\", \"M3C 8N0\", \"Cambodia\" ],\n\t[ \"973\", \"Julian\", \"Pugh\", \"B6E 7J7\", \"Mauritania\" ],\n\t[ \"974\", \"Xena\", \"Lott\", \"52294\", \"Estonia\" ],\n\t[ \"975\", \"Fuller\", \"Kirk\", \"65396\", \"Qatar\" ],\n\t[ \"976\", \"Lance\", \"Knox\", \"78074\", \"Serbia and Montenegro\" ],\n\t[ \"977\", \"Hedwig\", \"Beck\", \"T5P 4C8\", \"Dominican Republic\" ],\n\t[ \"978\", \"Martena\", \"Diaz\", \"65420\", \"Saint Pierre and Miquelon\" ],\n\t[ \"979\", \"Shafira\", \"David\", \"74843\", \"Senegal\" ],\n\t[ \"980\", \"Shafira\", \"Clark\", \"T6F 5C7\", \"Mongolia\" ],\n\t[ \"981\", \"Georgia\", \"Booth\", \"28183\", \"Japan\" ],\n\t[ \"982\", \"Cameron\", \"Austin\", \"I2J 1R1\", \"Bahrain\" ],\n\t[ \"983\", \"Vanna\", \"Hyde\", \"82434\", \"Croatia\" ],\n\t[ \"984\", \"Deanna\", \"Park\", \"68486\", \"Zimbabwe\" ],\n\t[ \"985\", \"Grady\", \"Freeman\", \"U4O 1Q9\", \"Belarus\" ],\n\t[ \"986\", \"Sandra\", \"Knapp\", \"31413\", \"Sudan\" ],\n\t[ \"987\", \"Dorian\", \"Joseph\", \"90768\", \"Lithuania\" ],\n\t[ \"988\", \"Adria\", \"Bonner\", \"15899\", \"Mongolia\" ],\n\t[ \"989\", \"Sebastian\", \"Guzman\", \"G9L 9G5\", \"Yemen\" ],\n\t[ \"990\", \"Angelica\", \"Puckett\", \"W8D 8W8\", \"Virgin Islands, U.S.\" ],\n\t[ \"991\", \"Connor\", \"Parks\", \"26175\", \"Virgin Islands, U.S.\" ],\n\t[ \"992\", \"Yardley\", \"Griffith\", \"H3L 2U3\", \"Saint Pierre and Miquelon\" ],\n\t[ \"993\", \"Charissa\", \"Beck\", \"30611\", \"Zambia\" ],\n\t[ \"994\", \"Calvin\", \"Russo\", \"79906\", \"Chile\" ],\n\t[ \"995\", \"Yoshi\", \"Durham\", \"N2J 8M8\", \"China\" ],\n\t[ \"996\", \"Finn\", \"Buck\", \"Q9F 9Z8\", \"Iraq\" ],\n\t[ \"997\", \"Kessie\", \"Holden\", \"C4A 1J0\", \"Syrian Arab Republic\" ],\n\t[ \"998\", \"Chloe\", \"Richards\", \"63091\", \"Canada\" ],\n\t[ \"999\", \"Uriel\", \"Snyder\", \"95487\", \"Pakistan\" ],\n\t[ \"1000\", \"Maite\", \"Cash\", \"90705\", \"Syrian Arab Republic\" ],\n\t[ \"1001\", \"Cameron\", \"Schwartz\", \"82778\", \"Taiwan, Province of China\" ],\n\t[ \"1002\", \"Faith\", \"Jimenez\", \"J6K 2P9\", \"Saint Pierre and Miquelon\" ],\n\t[ \"1003\", \"Otto\", \"Hancock\", \"34535\", \"Andorra\" ],\n\t[ \"1004\", \"Harlan\", \"Blackwell\", \"N8Y 4E6\", \"Qatar\" ],\n\t[ \"1005\", \"Fitzgerald\", \"Gilliam\", \"Y9J 6J5\", \"Burkina Faso\" ],\n\t[ \"1006\", \"Lev\", \"Ballard\", \"01956\", \"American Samoa\" ],\n\t[ \"1007\", \"Freya\", \"Brown\", \"01190\", \"Portugal\" ],\n\t[ \"1008\", \"Harding\", \"Osborn\", \"14814\", \"San Marino\" ],\n\t[ \"1009\", \"Alexander\", \"Howard\", \"81842\", \"Reunion\" ],\n\t[ \"1010\", \"Ori\", \"Marsh\", \"77738\", \"Saint Helena\" ],\n\t[ \"1011\", \"Brennan\", \"Rich\", \"18690\", \"Cambodia\" ],\n\t[ \"1012\", \"Dawn\", \"Christensen\", \"Y8F 7R3\", \"Mali\" ],\n\t[ \"1013\", \"Ahmed\", \"Pearson\", \"62230\", \"Sudan\" ],\n\t[ \"1014\", \"Tanek\", \"Head\", \"25744\", \"Kiribati\" ],\n\t[ \"1015\", \"Meredith\", \"Cantu\", \"E6X 2L1\", \"Kenya\" ],\n\t[ \"1016\", \"Levi\", \"Fisher\", \"I9Y 9G2\", \"Djibouti\" ],\n\t[ \"1017\", \"Katell\", \"Cameron\", \"10278\", \"Denmark\" ],\n\t[ \"1018\", \"Ina\", \"Orr\", \"P7H 2O3\", \"Congo\" ],\n\t[ \"1019\", \"Beck\", \"Hayden\", \"15115\", \"Saint Lucia\" ],\n\t[ \"1020\", \"Cassady\", \"Wagner\", \"R9H 8C5\", \"Estonia\" ],\n\t[ \"1021\", \"Amena\", \"Herrera\", \"13286\", \"Bahrain\" ],\n\t[ \"1022\", \"Tarik\", \"Gross\", \"C3X 3W0\", \"Azerbaijan\" ],\n\t[ \"1023\", \"Marshall\", \"Collier\", \"13416\", \"Dominica\" ],\n\t[ \"1024\", \"Kirestin\", \"Callahan\", \"15429\", \"Micronesia\" ],\n\t[ \"1025\", \"Sasha\", \"Rice\", \"O6H 6X2\", \"Denmark\" ],\n\t[ \"1026\", \"Ross\", \"Gonzalez\", \"D3B 3R5\", \"Sudan\" ],\n\t[ \"1027\", \"Veda\", \"Arnold\", \"56611\", \"Swaziland\" ],\n\t[ \"1028\", \"Ferdinand\", \"Macias\", \"P1Q 3I2\", \"Colombia\" ],\n\t[ \"1029\", \"Mohammad\", \"Reed\", \"74005\", \"Bhutan\" ],\n\t[ \"1030\", \"Reagan\", \"Sandoval\", \"19275\", \"Pitcairn\" ],\n\t[ \"1031\", \"Debra\", \"Nelson\", \"85945\", \"Ukraine\" ],\n\t[ \"1032\", \"Cleo\", \"Robertson\", \"84072\", \"Guadeloupe\" ],\n\t[ \"1033\", \"Tanya\", \"Vance\", \"C1F 7F1\", \"Romania\" ],\n\t[ \"1034\", \"Desirae\", \"Wooten\", \"74659\", \"Mongolia\" ],\n\t[ \"1035\", \"Hiram\", \"Estes\", \"Q5Z 5A0\", \"Namibia\" ],\n\t[ \"1036\", \"Medge\", \"Weiss\", \"67079\", \"Azerbaijan\" ],\n\t[ \"1037\", \"Hu\", \"Chase\", \"87562\", \"Cuba\" ],\n\t[ \"1038\", \"Shafira\", \"Everett\", \"18983\", \"Georgia\" ],\n\t[ \"1039\", \"Mannix\", \"Lamb\", \"45542\", \"Venezuela\" ],\n\t[ \"1040\", \"Germaine\", \"Harvey\", \"I9G 1U0\", \"Falkland Islands (Malvinas)\" ],\n\t[ \"1041\", \"Brenna\", \"Leonard\", \"55573\", \"New Zealand\" ],\n\t[ \"1042\", \"Kylie\", \"Rivas\", \"U9J 3O9\", \"Djibouti\" ],\n\t[ \"1043\", \"Alexandra\", \"Rich\", \"T4O 6S6\", \"Cuba\" ],\n\t[ \"1044\", \"Dorian\", \"Spears\", \"00456\", \"Brazil\" ],\n\t[ \"1045\", \"Laurel\", \"Abbott\", \"45449\", \"Switzerland\" ],\n\t[ \"1046\", \"Gabriel\", \"Drake\", \"U1S 5O2\", \"Trinidad and Tobago\" ],\n\t[ \"1047\", \"Priscilla\", \"Mercer\", \"01401\", \"Serbia and Montenegro\" ],\n\t[ \"1048\", \"Darius\", \"Hoffman\", \"49694\", \"Greece\" ],\n\t[ \"1049\", \"Caesar\", \"Patton\", \"42322\", \"Suriname\" ],\n\t[ \"1050\", \"Susan\", \"Clayton\", \"W1G 5C3\", \"Maldives\" ],\n\t[ \"1051\", \"Zane\", \"Dunlap\", \"73722\", \"Oman\" ],\n\t[ \"1052\", \"Leah\", \"Fuentes\", \"60412\", \"Luxembourg\" ],\n\t[ \"1053\", \"Yardley\", \"Hansen\", \"03194\", \"Mauritius\" ],\n\t[ \"1054\", \"Ingrid\", \"Talley\", \"37315\", \"Solomon Islands\" ],\n\t[ \"1055\", \"Demetria\", \"Evans\", \"30587\", \"Tajikistan\" ],\n\t[ \"1056\", \"Ignacia\", \"Alford\", \"01282\", \"Bouvet Island\" ],\n\t[ \"1057\", \"Destiny\", \"Wade\", \"L5R 3V3\", \"Uganda\" ],\n\t[ \"1058\", \"Alden\", \"Mason\", \"V7D 2V6\", \"Dominican Republic\" ],\n\t[ \"1059\", \"Pamela\", \"Wilcox\", \"L1I 6I1\", \"Canada\" ],\n\t[ \"1060\", \"Melvin\", \"Buckley\", \"05478\", \"Hungary\" ],\n\t[ \"1061\", \"Eve\", \"Holcomb\", \"B6B 8T1\", \"Cook Islands\" ],\n\t[ \"1062\", \"Arthur\", \"Weeks\", \"R5P 7U2\", \"Bangladesh\" ],\n\t[ \"1063\", \"Marah\", \"Levine\", \"10075\", \"Somalia\" ],\n\t[ \"1064\", \"Keiko\", \"Freeman\", \"90950\", \"Faroe Islands\" ],\n\t[ \"1065\", \"Dorian\", \"Rose\", \"T5M 4Z0\", \"Fiji\" ],\n\t[ \"1066\", \"Desirae\", \"Velez\", \"T4E 8K2\", \"Afghanistan\" ],\n\t[ \"1067\", \"Rebekah\", \"Lucas\", \"T9A 8V5\", \"Tunisia\" ],\n\t[ \"1068\", \"Sylvester\", \"Copeland\", \"W6R 3B6\", \"Jamaica\" ],\n\t[ \"1069\", \"Alea\", \"Preston\", \"31050\", \"Netherlands Antilles\" ],\n\t[ \"1070\", \"Aphrodite\", \"Gordon\", \"T7C 6T8\", \"Sao Tome and Principe\" ],\n\t[ \"1071\", \"Yael\", \"Delaney\", \"G9W 9P1\", \"Mexico\" ],\n\t[ \"1072\", \"Sierra\", \"Perez\", \"R3O 8H0\", \"Slovenia\" ],\n\t[ \"1073\", \"Avram\", \"Briggs\", \"05221\", \"Norfolk Island\" ],\n\t[ \"1074\", \"Troy\", \"Poole\", \"W7Q 8O5\", \"Malta\" ],\n\t[ \"1075\", \"Gavin\", \"Sandoval\", \"37352\", \"Greece\" ],\n\t[ \"1076\", \"Nerea\", \"Stokes\", \"N2Q 6S9\", \"United States\" ],\n\t[ \"1077\", \"Genevieve\", \"Ramirez\", \"53829\", \"Mali\" ],\n\t[ \"1078\", \"Oliver\", \"Boone\", \"M1Q 8V9\", \"Bolivia\" ],\n\t[ \"1079\", \"Lars\", \"Ramirez\", \"L2R 6V2\", \"Bosnia and Herzegovina\" ],\n\t[ \"1080\", \"Abbot\", \"Horton\", \"R1R 1V8\", \"Netherlands Antilles\" ],\n\t[ \"1081\", \"Abra\", \"Avila\", \"41608\", \"Congo\" ],\n\t[ \"1082\", \"Candice\", \"Christian\", \"13930\", \"Faroe Islands\" ],\n\t[ \"1083\", \"Flavia\", \"Miranda\", \"93964\", \"Estonia\" ],\n\t[ \"1084\", \"Medge\", \"Drake\", \"Q7C 2E2\", \"Belize\" ],\n\t[ \"1085\", \"Lee\", \"Montgomery\", \"H3T 4Q6\", \"Costa Rica\" ],\n\t[ \"1086\", \"Aline\", \"Ratliff\", \"99839\", \"Macao\" ],\n\t[ \"1087\", \"Shafira\", \"Fox\", \"A9S 7C8\", \"Palestinian Territory, Occupied\" ],\n\t[ \"1088\", \"Orson\", \"Greene\", \"K9L 7R8\", \"Myanmar\" ],\n\t[ \"1089\", \"Henry\", \"Joyner\", \"55853\", \"South Africa\" ],\n\t[ \"1090\", \"Keely\", \"Boyer\", \"08996\", \"Liberia\" ],\n\t[ \"1091\", \"Jerome\", \"Jones\", \"31770\", \"Saint Lucia\" ],\n\t[ \"1092\", \"Hermione\", \"Dunlap\", \"U2R 7R2\", \"Moldova\" ],\n\t[ \"1093\", \"Lenore\", \"Powers\", \"73772\", \"Tunisia\" ],\n\t[ \"1094\", \"Alden\", \"Newman\", \"V4C 3O8\", \"Bhutan\" ],\n\t[ \"1095\", \"Jasper\", \"Blevins\", \"K2H 5W0\", \"Paraguay\" ],\n\t[ \"1096\", \"Robert\", \"Bender\", \"R5F 1H9\", \"Philippines\" ],\n\t[ \"1097\", \"Bo\", \"Richard\", \"N5R 6T2\", \"Trinidad and Tobago\" ],\n\t[ \"1098\", \"Iliana\", \"Mcpherson\", \"23758\", \"Bangladesh\" ],\n\t[ \"1099\", \"Alfreda\", \"Camacho\", \"35387\", \"Saint Helena\" ],\n\t[ \"1100\", \"Kirsten\", \"Giles\", \"14079\", \"Romania\" ],\n\t[ \"1101\", \"Harlan\", \"Crawford\", \"84847\", \"French Polynesia\" ],\n\t[ \"1102\", \"Wynne\", \"Bauer\", \"W9D 6F6\", \"Kazakhstan\" ],\n\t[ \"1103\", \"Connor\", \"Melton\", \"E2F 4Q2\", \"Angola\" ],\n\t[ \"1104\", \"Evelyn\", \"Barry\", \"I9H 8W7\", \"Turkmenistan\" ],\n\t[ \"1105\", \"Barry\", \"Stephens\", \"07823\", \"Gibraltar\" ],\n\t[ \"1106\", \"Ferris\", \"Farrell\", \"I7H 5Z6\", \"Saint Vincent and The Grenadines\" ],\n\t[ \"1107\", \"Ursa\", \"Carr\", \"31124\", \"Chad\" ],\n\t[ \"1108\", \"Laith\", \"Johnson\", \"10428\", \"Cyprus\" ],\n\t[ \"1109\", \"Harlan\", \"Frank\", \"J6K 7I6\", \"Gambia\" ],\n\t[ \"1110\", \"Gregory\", \"Ratliff\", \"P1C 8H2\", \"Chile\" ],\n\t[ \"1111\", \"Rina\", \"Holloway\", \"Y7N 1E7\", \"Estonia\" ],\n\t[ \"1112\", \"Maris\", \"Joyner\", \"T6R 2H9\", \"France\" ],\n\t[ \"1113\", \"Galvin\", \"Webster\", \"V8E 9U4\", \"Croatia\" ],\n\t[ \"1114\", \"Farrah\", \"Bean\", \"H2B 8E2\", \"Palestinian Territory, Occupied\" ],\n\t[ \"1115\", \"Martha\", \"Schroeder\", \"14485\", \"Georgia\" ],\n\t[ \"1116\", \"Mari\", \"Boone\", \"D4C 1Q0\", \"Comoros\" ],\n\t[ \"1117\", \"Nadine\", \"Mercado\", \"35046\", \"Syrian Arab Republic\" ],\n\t[ \"1118\", \"Isadora\", \"Keith\", \"R5H 8Y7\", \"Mayotte\" ],\n\t[ \"1119\", \"Quinn\", \"William\", \"V8Q 3Y6\", \"India\" ],\n\t[ \"1120\", \"Justina\", \"Gilbert\", \"11271\", \"Yemen\" ],\n\t[ \"1121\", \"Jordan\", \"Hull\", \"F4Z 7R8\", \"Lesotho\" ],\n\t[ \"1122\", \"Mechelle\", \"Davenport\", \"A9Z 8P2\", \"Bermuda\" ],\n\t[ \"1123\", \"Isabelle\", \"Webster\", \"60972\", \"Zimbabwe\" ],\n\t[ \"1124\", \"Armand\", \"Butler\", \"Y3F 4H9\", \"Nicaragua\" ],\n\t[ \"1125\", \"Herman\", \"Beach\", \"Q8N 6V3\", \"Cape Verde\" ],\n\t[ \"1126\", \"Brianna\", \"Love\", \"D9B 2W8\", \"Sierra Leone\" ],\n\t[ \"1127\", \"Joy\", \"Brown\", \"O7V 7C1\", \"Djibouti\" ],\n\t[ \"1128\", \"Amena\", \"Moss\", \"P8D 1L9\", \"Andorra\" ],\n\t[ \"1129\", \"Zeph\", \"Whitehead\", \"01513\", \"Tanzania, United Republic of\" ],\n\t[ \"1130\", \"Logan\", \"Matthews\", \"73541\", \"Finland\" ],\n\t[ \"1131\", \"Amela\", \"Gregory\", \"65323\", \"Swaziland\" ],\n\t[ \"1132\", \"Zoe\", \"Owen\", \"V5L 5O6\", \"Zambia\" ],\n\t[ \"1133\", \"September\", \"Hewitt\", \"R8K 4G9\", \"Congo\" ],\n\t[ \"1134\", \"Holly\", \"Walter\", \"S2E 3M4\", \"Serbia and Montenegro\" ],\n\t[ \"1135\", \"Zeph\", \"Beach\", \"J6Z 8B5\", \"Ecuador\" ],\n\t[ \"1136\", \"Morgan\", \"Decker\", \"M9H 8I5\", \"Uruguay\" ],\n\t[ \"1137\", \"Malcolm\", \"Maldonado\", \"S6F 8X6\", \"Netherlands\" ],\n\t[ \"1138\", \"Fay\", \"Day\", \"B9R 1U7\", \"Seychelles\" ],\n\t[ \"1139\", \"Charles\", \"Juarez\", \"62791\", \"Virgin Islands, U.S.\" ],\n\t[ \"1140\", \"Amery\", \"Stout\", \"L9A 1F8\", \"Central African Republic\" ],\n\t[ \"1141\", \"Irene\", \"Ferrell\", \"52649\", \"Norway\" ],\n\t[ \"1142\", \"Dean\", \"Stout\", \"N5C 2S8\", \"Uruguay\" ],\n\t[ \"1143\", \"Eric\", \"Baxter\", \"82082\", \"Chile\" ],\n\t[ \"1144\", \"Shelley\", \"Larsen\", \"Y4T 4P3\", \"Antarctica\" ],\n\t[ \"1145\", \"Rigel\", \"Ellis\", \"E3S 6K8\", \"Zimbabwe\" ],\n\t[ \"1146\", \"Maite\", \"Rosa\", \"F6C 5Q9\", \"Zambia\" ],\n\t[ \"1147\", \"Serena\", \"Blanchard\", \"99373\", \"Estonia\" ],\n\t[ \"1148\", \"Melanie\", \"Berger\", \"C5P 4E2\", \"Mozambique\" ],\n\t[ \"1149\", \"Noah\", \"Spence\", \"B8H 7X7\", \"Martinique\" ],\n\t[ \"1150\", \"Elliott\", \"Pierce\", \"W5B 8V7\", \"Swaziland\" ],\n\t[ \"1151\", \"Ahmed\", \"Chang\", \"E9X 7J0\", \"Bulgaria\" ],\n\t[ \"1152\", \"Ross\", \"Figueroa\", \"22458\", \"China\" ],\n\t[ \"1153\", \"Gary\", \"Calderon\", \"V3C 4J8\", \"Algeria\" ],\n\t[ \"1154\", \"Montana\", \"Franklin\", \"94093\", \"Haiti\" ],\n\t[ \"1155\", \"Rae\", \"Curry\", \"45477\", \"Morocco\" ],\n\t[ \"1156\", \"Jillian\", \"Hogan\", \"N8L 4B5\", \"Iceland\" ],\n\t[ \"1157\", \"Mia\", \"Kaufman\", \"54758\", \"Burkina Faso\" ],\n\t[ \"1158\", \"Remedios\", \"Wilkerson\", \"75420\", \"Saint Vincent and The Grenadines\" ],\n\t[ \"1159\", \"Xanthus\", \"Baldwin\", \"13961\", \"Congo\" ],\n\t[ \"1160\", \"Madeline\", \"Gates\", \"76351\", \"Saint Helena\" ],\n\t[ \"1161\", \"Leroy\", \"Craig\", \"12770\", \"Finland\" ],\n\t[ \"1162\", \"Melanie\", \"Carpenter\", \"C3B 8L4\", \"Mayotte\" ],\n\t[ \"1163\", \"Ashely\", \"Mcneil\", \"E7E 9K5\", \"French Southern Territories\" ],\n\t[ \"1164\", \"Karina\", \"Mcneil\", \"39956\", \"United Arab Emirates\" ],\n\t[ \"1165\", \"Nina\", \"Mills\", \"92913\", \"Saint Kitts and Nevis\" ],\n\t[ \"1166\", \"Ashton\", \"Singleton\", \"73890\", \"Libyan Arab Jamahiriya\" ],\n\t[ \"1167\", \"Meghan\", \"Black\", \"31814\", \"Armenia\" ],\n\t[ \"1168\", \"Jolene\", \"Pope\", \"U6K 7O6\", \"Venezuela\" ],\n\t[ \"1169\", \"Abel\", \"Boyd\", \"37110\", \"Botswana\" ],\n\t[ \"1170\", \"Tiger\", \"Coffey\", \"Y6P 3S4\", \"Faroe Islands\" ],\n\t[ \"1171\", \"Aileen\", \"Rowe\", \"F7G 8D9\", \"Netherlands Antilles\" ],\n\t[ \"1172\", \"Bryar\", \"Forbes\", \"T2N 5H6\", \"Saint Vincent and The Grenadines\" ],\n\t[ \"1173\", \"Vera\", \"Hoffman\", \"36299\", \"Guadeloupe\" ],\n\t[ \"1174\", \"Hadassah\", \"Wright\", \"S8J 5B2\", \"Peru\" ],\n\t[ \"1175\", \"Bruce\", \"Blair\", \"Q8E 7K6\", \"Cape Verde\" ],\n\t[ \"1176\", \"Brianna\", \"Wolf\", \"V8S 5A6\", \"Bahamas\" ],\n\t[ \"1177\", \"Kimberley\", \"Reed\", \"17652\", \"Tajikistan\" ],\n\t[ \"1178\", \"Colin\", \"Phelps\", \"42334\", \"Brunei Darussalam\" ],\n\t[ \"1179\", \"Gil\", \"Britt\", \"U3N 6C2\", \"Swaziland\" ],\n\t[ \"1180\", \"Hasad\", \"Pena\", \"09526\", \"United States\" ],\n\t[ \"1181\", \"Violet\", \"Dixon\", \"48691\", \"Micronesia\" ],\n\t[ \"1182\", \"Uriel\", \"Bowen\", \"Z7F 7A7\", \"Uzbekistan\" ],\n\t[ \"1183\", \"Madeline\", \"Keller\", \"18227\", \"Iran, Islamic Republic of\" ],\n\t[ \"1184\", \"Buffy\", \"Mckee\", \"23861\", \"Ethiopia\" ],\n\t[ \"1185\", \"Doris\", \"Martin\", \"V8N 8O7\", \"Liberia\" ],\n\t[ \"1186\", \"Mia\", \"Burke\", \"64582\", \"Virgin Islands, British\" ],\n\t[ \"1187\", \"William\", \"Kemp\", \"63587\", \"Tuvalu\" ],\n\t[ \"1188\", \"Stacy\", \"Quinn\", \"01390\", \"Nauru\" ],\n\t[ \"1189\", \"Halla\", \"Solomon\", \"31138\", \"Pakistan\" ],\n\t[ \"1190\", \"Kasimir\", \"Rodriguez\", \"67823\", \"Costa Rica\" ],\n\t[ \"1191\", \"Davis\", \"Lawrence\", \"27918\", \"Rwanda\" ],\n\t[ \"1192\", \"Nigel\", \"Bryan\", \"L5U 2U9\", \"Seychelles\" ],\n\t[ \"1193\", \"Ivana\", \"Stone\", \"94862\", \"Niue\" ],\n\t[ \"1194\", \"Naomi\", \"Yang\", \"68985\", \"Haiti\" ],\n\t[ \"1195\", \"Roanna\", \"Brown\", \"51196\", \"India\" ],\n\t[ \"1196\", \"Colorado\", \"Chavez\", \"45634\", \"Brazil\" ],\n\t[ \"1197\", \"Illana\", \"Levy\", \"V1A 7R8\", \"Jordan\" ],\n\t[ \"1198\", \"Ali\", \"Lowe\", \"N8K 1Y5\", \"Hungary\" ],\n\t[ \"1199\", \"Virginia\", \"Witt\", \"Y3O 5W8\", \"Azerbaijan\" ],\n\t[ \"1200\", \"Howard\", \"Flores\", \"I9C 3Q7\", \"Fiji\" ],\n\t[ \"1201\", \"Walter\", \"Odom\", \"78418\", \"Thailand\" ],\n\t[ \"1202\", \"Thor\", \"Craig\", \"00935\", \"Jamaica\" ],\n\t[ \"1203\", \"Petra\", \"Barry\", \"E5L 5K5\", \"Finland\" ],\n\t[ \"1204\", \"Lev\", \"Ellison\", \"I6S 1K1\", \"Mongolia\" ],\n\t[ \"1205\", \"Roth\", \"Osborne\", \"15014\", \"Swaziland\" ],\n\t[ \"1206\", \"Lucius\", \"Baldwin\", \"12766\", \"China\" ],\n\t[ \"1207\", \"Candice\", \"Hyde\", \"B5E 4B8\", \"Bahamas\" ],\n\t[ \"1208\", \"Maggy\", \"Bailey\", \"76781\", \"Northern Mariana Islands\" ],\n\t[ \"1209\", \"Beatrice\", \"Gregory\", \"S5S 8S4\", \"Rwanda\" ],\n\t[ \"1210\", \"Adrian\", \"Bowman\", \"58500\", \"Vanuatu\" ],\n\t[ \"1211\", \"Brenden\", \"Chandler\", \"50326\", \"Thailand\" ],\n\t[ \"1212\", \"Jada\", \"Richmond\", \"15990\", \"Saint Vincent and The Grenadines\" ],\n\t[ \"1213\", \"Sawyer\", \"Page\", \"G2W 7R7\", \"Somalia\" ],\n\t[ \"1214\", \"Haley\", \"Jordan\", \"U7X 4U2\", \"Equatorial Guinea\" ],\n\t[ \"1215\", \"Ruby\", \"Watson\", \"30990\", \"Romania\" ],\n\t[ \"1216\", \"Jocelyn\", \"Knowles\", \"78987\", \"Lebanon\" ],\n\t[ \"1217\", \"Preston\", \"Stevenson\", \"F3L 9B3\", \"Mali\" ],\n\t[ \"1218\", \"Kimberly\", \"Merritt\", \"38779\", \"Venezuela\" ],\n\t[ \"1219\", \"Herrod\", \"Burke\", \"56225\", \"French Guiana\" ],\n\t[ \"1220\", \"Solomon\", \"Shannon\", \"67980\", \"Cape Verde\" ],\n\t[ \"1221\", \"Bradley\", \"Stokes\", \"10213\", \"Botswana\" ],\n\t[ \"1222\", \"Grace\", \"Kinney\", \"67923\", \"Montserrat\" ],\n\t[ \"1223\", \"Celeste\", \"Clark\", \"S7M 6I2\", \"Guatemala\" ],\n\t[ \"1224\", \"Patricia\", \"Frank\", \"05615\", \"Venezuela\" ],\n\t[ \"1225\", \"Madonna\", \"Alford\", \"10878\", \"Brunei Darussalam\" ],\n\t[ \"1226\", \"May\", \"Rios\", \"N7O 2L0\", \"Georgia\" ],\n\t[ \"1227\", \"Driscoll\", \"Roach\", \"Y7F 9F8\", \"Palestinian Territory, Occupied\" ],\n\t[ \"1228\", \"Idona\", \"Cruz\", \"T6Q 8L4\", \"Iraq\" ],\n\t[ \"1229\", \"Sydney\", \"Delacruz\", \"69511\", \"United Arab Emirates\" ],\n\t[ \"1230\", \"Gillian\", \"Huff\", \"52624\", \"French Southern Territories\" ],\n\t[ \"1231\", \"Minerva\", \"Rosario\", \"29195\", \"Andorra\" ],\n\t[ \"1232\", \"Kerry\", \"Alvarado\", \"L3Q 2V5\", \"Portugal\" ],\n\t[ \"1233\", \"Amos\", \"Bass\", \"26389\", \"Holy See (Vatican City State)\" ],\n\t[ \"1234\", \"Deanna\", \"Parks\", \"57376\", \"Estonia\" ],\n\t[ \"1235\", \"Fitzgerald\", \"Green\", \"M3P 9N2\", \"Slovenia\" ],\n\t[ \"1236\", \"Sade\", \"Hinton\", \"35561\", \"Barbados\" ],\n\t[ \"1237\", \"Suki\", \"Parsons\", \"44591\", \"Syrian Arab Republic\" ],\n\t[ \"1238\", \"Orli\", \"Weeks\", \"K2W 9L4\", \"Peru\" ],\n\t[ \"1239\", \"Nicholas\", \"Copeland\", \"I5W 7A4\", \"French Guiana\" ],\n\t[ \"1240\", \"Guy\", \"Vang\", \"22277\", \"Pitcairn\" ],\n\t[ \"1241\", \"Hunter\", \"Goodman\", \"72290\", \"Malaysia\" ],\n\t[ \"1242\", \"Noble\", \"Rich\", \"I3B 6T9\", \"Gibraltar\" ],\n\t[ \"1243\", \"Delilah\", \"Zamora\", \"96328\", \"New Zealand\" ],\n\t[ \"1244\", \"Sybil\", \"Mercer\", \"93665\", \"Namibia\" ],\n\t[ \"1245\", \"Scarlett\", \"Brock\", \"Z2E 3J2\", \"Central African Republic\" ],\n\t[ \"1246\", \"Channing\", \"Alexander\", \"W5V 8D2\", \"San Marino\" ],\n\t[ \"1247\", \"Carolyn\", \"Boyle\", \"Q5Z 9E6\", \"Gabon\" ],\n\t[ \"1248\", \"Irene\", \"Jennings\", \"F3H 4O6\", \"Saint Helena\" ],\n\t[ \"1249\", \"Bianca\", \"Pratt\", \"66354\", \"Malaysia\" ],\n\t[ \"1250\", \"Dexter\", \"Cole\", \"56106\", \"French Southern Territories\" ],\n\t[ \"1251\", \"Berk\", \"Velez\", \"26759\", \"Lesotho\" ],\n\t[ \"1252\", \"Barrett\", \"Richardson\", \"59446\", \"Cocos (Keeling) Islands\" ],\n\t[ \"1253\", \"Scarlet\", \"Jacobs\", \"G9A 7L6\", \"Dominica\" ],\n\t[ \"1254\", \"Aiko\", \"Brooks\", \"R6R 9E4\", \"Liberia\" ],\n\t[ \"1255\", \"Jacob\", \"Moore\", \"P2Y 6P3\", \"Cambodia\" ],\n\t[ \"1256\", \"Madeline\", \"Bishop\", \"D4I 2E7\", \"Dominican Republic\" ],\n\t[ \"1257\", \"Jarrod\", \"Evans\", \"C9O 7V7\", \"Taiwan, Province of China\" ],\n\t[ \"1258\", \"Beverly\", \"Witt\", \"64850\", \"Denmark\" ],\n\t[ \"1259\", \"Karyn\", \"Rhodes\", \"D6G 5Z3\", \"Cape Verde\" ],\n\t[ \"1260\", \"Imani\", \"Quinn\", \"01897\", \"Macao\" ],\n\t[ \"1261\", \"Athena\", \"Eaton\", \"03568\", \"Syrian Arab Republic\" ],\n\t[ \"1262\", \"Raymond\", \"Valdez\", \"21037\", \"Romania\" ],\n\t[ \"1263\", \"Christopher\", \"Ferguson\", \"64945\", \"Indonesia\" ],\n\t[ \"1264\", \"Latifah\", \"Harris\", \"91381\", \"Suriname\" ],\n\t[ \"1265\", \"Dacey\", \"Wagner\", \"81483\", \"Qatar\" ],\n\t[ \"1266\", \"Summer\", \"Myers\", \"H6A 1G5\", \"Angola\" ],\n\t[ \"1267\", \"Jasmine\", \"Rivera\", \"Y4W 8P2\", \"Virgin Islands, British\" ],\n\t[ \"1268\", \"Cairo\", \"Massey\", \"Q6Y 7A7\", \"Poland\" ],\n\t[ \"1269\", \"Jena\", \"Hill\", \"89480\", \"United States Minor Outlying Islands\" ],\n\t[ \"1270\", \"Ava\", \"Benson\", \"L9H 8V1\", \"Sri Lanka\" ],\n\t[ \"1271\", \"Gillian\", \"Mercado\", \"A9W 6V5\", \"Norway\" ],\n\t[ \"1272\", \"Peter\", \"Marquez\", \"I5B 3W9\", \"Guyana\" ],\n\t[ \"1273\", \"Price\", \"Coleman\", \"X8G 2S0\", \"Burkina Faso\" ],\n\t[ \"1274\", \"Shana\", \"Harper\", \"L2B 3U9\", \"Malaysia\" ],\n\t[ \"1275\", \"Serina\", \"Matthews\", \"58061\", \"Lithuania\" ],\n\t[ \"1276\", \"Aretha\", \"Bryant\", \"Y8J 7A5\", \"Tonga\" ],\n\t[ \"1277\", \"Wesley\", \"Craig\", \"20141\", \"Australia\" ],\n\t[ \"1278\", \"Martena\", \"Mercer\", \"P6X 2L9\", \"Sudan\" ],\n\t[ \"1279\", \"Tamara\", \"Dennis\", \"D3H 9R0\", \"Mali\" ],\n\t[ \"1280\", \"Phelan\", \"Pena\", \"D2H 2H7\", \"United States Minor Outlying Islands\" ],\n\t[ \"1281\", \"Rebecca\", \"Kinney\", \"B5Z 9S4\", \"Antarctica\" ],\n\t[ \"1282\", \"Josephine\", \"Delgado\", \"81010\", \"Algeria\" ],\n\t[ \"1283\", \"Kieran\", \"Estes\", \"70093\", \"Bermuda\" ],\n\t[ \"1284\", \"Tamara\", \"Williamson\", \"90905\", \"French Guiana\" ],\n\t[ \"1285\", \"Dora\", \"Serrano\", \"W8K 6R5\", \"Nauru\" ],\n\t[ \"1286\", \"Morgan\", \"Bass\", \"B6F 8R2\", \"Madagascar\" ],\n\t[ \"1287\", \"Margaret\", \"Austin\", \"D2C 2C1\", \"Belgium\" ],\n\t[ \"1288\", \"Nasim\", \"Berry\", \"J9X 7M5\", \"Heard Island and Mcdonald Islands\" ],\n\t[ \"1289\", \"Jelani\", \"Rutledge\", \"34552\", \"Bolivia\" ],\n\t[ \"1290\", \"Cassady\", \"Hardin\", \"I2K 4H6\", \"Hong Kong\" ],\n\t[ \"1291\", \"Jenette\", \"Thornton\", \"44943\", \"Uganda\" ],\n\t[ \"1292\", \"Alexandra\", \"Sims\", \"93937\", \"Australia\" ],\n\t[ \"1293\", \"Ross\", \"Higgins\", \"61993\", \"Nicaragua\" ],\n\t[ \"1294\", \"Penelope\", \"Henson\", \"90344\", \"Trinidad and Tobago\" ],\n\t[ \"1295\", \"Yoshi\", \"Blackwell\", \"C8D 1T4\", \"Costa Rica\" ],\n\t[ \"1296\", \"Daria\", \"Rodriquez\", \"X3C 6L0\", \"Iceland\" ],\n\t[ \"1297\", \"Wesley\", \"Waller\", \"43947\", \"Myanmar\" ],\n\t[ \"1298\", \"Adam\", \"Hayden\", \"88969\", \"Italy\" ],\n\t[ \"1299\", \"Charity\", \"William\", \"46439\", \"Greece\" ],\n\t[ \"1300\", \"Ronan\", \"Hopper\", \"51955\", \"Zambia\" ],\n\t[ \"1301\", \"Geraldine\", \"Hatfield\", \"W9S 7T5\", \"Luxembourg\" ],\n\t[ \"1302\", \"Barry\", \"Nicholson\", \"79625\", \"Liechtenstein\" ],\n\t[ \"1303\", \"Donovan\", \"Ortiz\", \"68119\", \"Macao\" ],\n\t[ \"1304\", \"Jeanette\", \"Cooper\", \"D5P 9L2\", \"Sri Lanka\" ],\n\t[ \"1305\", \"Isadora\", \"Stephenson\", \"P4X 4H5\", \"Mauritania\" ],\n\t[ \"1306\", \"Hall\", \"Hays\", \"J2Z 2H1\", \"Svalbard and Jan Mayen\" ],\n\t[ \"1307\", \"Idola\", \"Roberson\", \"89249\", \"Niue\" ],\n\t[ \"1308\", \"Olympia\", \"Dennis\", \"69498\", \"Guinea\" ],\n\t[ \"1309\", \"Naida\", \"Palmer\", \"19840\", \"Gambia\" ],\n\t[ \"1310\", \"Maxine\", \"Rollins\", \"87856\", \"Belize\" ],\n\t[ \"1311\", \"Rooney\", \"Phelps\", \"48424\", \"Italy\" ],\n\t[ \"1312\", \"Shelly\", \"Edwards\", \"O7O 1U4\", \"Mali\" ],\n\t[ \"1313\", \"Cassidy\", \"Holcomb\", \"98785\", \"Colombia\" ],\n\t[ \"1314\", \"Sybil\", \"Moran\", \"F3C 6E4\", \"Switzerland\" ],\n\t[ \"1315\", \"Mufutau\", \"Larson\", \"00276\", \"British Indian Ocean Territory\" ],\n\t[ \"1316\", \"Fiona\", \"Bryant\", \"U7Y 7N6\", \"Cocos (Keeling) Islands\" ],\n\t[ \"1317\", \"Lenore\", \"Boyle\", \"H5G 6P9\", \"Sudan\" ],\n\t[ \"1318\", \"Ignacia\", \"Avila\", \"Y5M 1S2\", \"Romania\" ],\n\t[ \"1319\", \"Wendy\", \"Stein\", \"25422\", \"Taiwan, Province of China\" ],\n\t[ \"1320\", \"Garrison\", \"Bass\", \"B9J 6D9\", \"Romania\" ],\n\t[ \"1321\", \"Curran\", \"Roy\", \"X2F 4P2\", \"Taiwan, Province of China\" ],\n\t[ \"1322\", \"Oliver\", \"Beach\", \"N6J 1C5\", \"Kazakhstan\" ],\n\t[ \"1323\", \"Bo\", \"Duran\", \"D5C 5C2\", \"Eritrea\" ],\n\t[ \"1324\", \"Tashya\", \"Morrow\", \"N2J 7O9\", \"Rwanda\" ],\n\t[ \"1325\", \"Cheryl\", \"Powell\", \"72413\", \"Niger\" ],\n\t[ \"1326\", \"Justin\", \"Roth\", \"18779\", \"Brunei Darussalam\" ],\n\t[ \"1327\", \"Nathaniel\", \"Foster\", \"04955\", \"Bermuda\" ],\n\t[ \"1328\", \"Candace\", \"Nunez\", \"G7Z 1N2\", \"Moldova\" ],\n\t[ \"1329\", \"Nero\", \"West\", \"K3Q 6B3\", \"Myanmar\" ],\n\t[ \"1330\", \"Brendan\", \"Mcintyre\", \"C4E 5H7\", \"Argentina\" ],\n\t[ \"1331\", \"Chaney\", \"Stafford\", \"V3X 8J4\", \"Benin\" ],\n\t[ \"1332\", \"Sylvia\", \"Velez\", \"95851\", \"Iraq\" ],\n\t[ \"1333\", \"Azalia\", \"Castro\", \"55986\", \"Israel\" ],\n\t[ \"1334\", \"Emily\", \"Hogan\", \"74667\", \"Botswana\" ],\n\t[ \"1335\", \"Buckminster\", \"Hurst\", \"N9C 2X6\", \"Reunion\" ],\n\t[ \"1336\", \"Rinah\", \"Rodriquez\", \"31896\", \"Guinea-bissau\" ],\n\t[ \"1337\", \"Nash\", \"Barnett\", \"Y8X 7H5\", \"China\" ],\n\t[ \"1338\", \"Xanthus\", \"Barker\", \"11212\", \"Trinidad and Tobago\" ],\n\t[ \"1339\", \"Minerva\", \"Huber\", \"M6M 9U3\", \"Equatorial Guinea\" ],\n\t[ \"1340\", \"Kaseem\", \"Tillman\", \"86565\", \"Bulgaria\" ],\n\t[ \"1341\", \"Cassidy\", \"Dejesus\", \"93205\", \"Sierra Leone\" ],\n\t[ \"1342\", \"Sheila\", \"Munoz\", \"26473\", \"Benin\" ],\n\t[ \"1343\", \"Florence\", \"Yates\", \"M5O 1J1\", \"Russian Federation\" ],\n\t[ \"1344\", \"Isadora\", \"Wagner\", \"88381\", \"Philippines\" ],\n\t[ \"1345\", \"Hilel\", \"Kramer\", \"E5D 4F5\", \"Lebanon\" ],\n\t[ \"1346\", \"Stewart\", \"Lawson\", \"67313\", \"Malaysia\" ],\n\t[ \"1347\", \"Ira\", \"Duffy\", \"52841\", \"Greece\" ],\n\t[ \"1348\", \"Ignatius\", \"Robinson\", \"10035\", \"Russian Federation\" ],\n\t[ \"1349\", \"Baxter\", \"Carroll\", \"92288\", \"Albania\" ],\n\t[ \"1350\", \"Palmer\", \"James\", \"N5X 5B1\", \"Germany\" ],\n\t[ \"1351\", \"Ava\", \"Eaton\", \"76497\", \"Egypt\" ],\n\t[ \"1352\", \"Kiona\", \"Smith\", \"09402\", \"Belize\" ],\n\t[ \"1353\", \"Brian\", \"Barlow\", \"00156\", \"Panama\" ],\n\t[ \"1354\", \"Nolan\", \"Rosa\", \"J2O 9W2\", \"Uruguay\" ],\n\t[ \"1355\", \"Teegan\", \"Burnett\", \"02401\", \"Italy\" ],\n\t[ \"1356\", \"Erin\", \"Knox\", \"95496\", \"Egypt\" ],\n\t[ \"1357\", \"Amela\", \"Sanford\", \"59890\", \"Virgin Islands, U.S.\" ],\n\t[ \"1358\", \"Quemby\", \"Hensley\", \"17698\", \"Tuvalu\" ],\n\t[ \"1359\", \"Ava\", \"York\", \"J1M 1A0\", \"Nigeria\" ],\n\t[ \"1360\", \"Vivien\", \"Ware\", \"N9S 1W6\", \"Bahamas\" ],\n\t[ \"1361\", \"Nyssa\", \"Lamb\", \"97964\", \"Estonia\" ],\n\t[ \"1362\", \"Brenna\", \"Slater\", \"L4P 5V6\", \"British Indian Ocean Territory\" ],\n\t[ \"1363\", \"Kennan\", \"Larsen\", \"M2A 4X0\", \"Angola\" ],\n\t[ \"1364\", \"Linda\", \"Luna\", \"P8C 4S8\", \"Gambia\" ],\n\t[ \"1365\", \"Boris\", \"Poole\", \"U7J 4G1\", \"Aruba\" ],\n\t[ \"1366\", \"Lyle\", \"Cote\", \"F5J 3Y2\", \"Somalia\" ],\n\t[ \"1367\", \"Oleg\", \"Knapp\", \"K4C 5T8\", \"Guinea\" ],\n\t[ \"1368\", \"Hanae\", \"Brown\", \"51395\", \"Nepal\" ],\n\t[ \"1369\", \"India\", \"Hyde\", \"E8P 7E8\", \"Belize\" ],\n\t[ \"1370\", \"Madeson\", \"Hodge\", \"23265\", \"Gambia\" ],\n\t[ \"1371\", \"Thaddeus\", \"Hester\", \"Y7S 5W1\", \"Saint Helena\" ],\n\t[ \"1372\", \"Aaron\", \"Kemp\", \"A1Q 8R3\", \"Albania\" ],\n\t[ \"1373\", \"Aurelia\", \"Thornton\", \"P8T 9D4\", \"Swaziland\" ],\n\t[ \"1374\", \"Preston\", \"Sharpe\", \"97472\", \"Niue\" ],\n\t[ \"1375\", \"Grace\", \"Gregory\", \"51767\", \"Burkina Faso\" ],\n\t[ \"1376\", \"Nicole\", \"Hicks\", \"81040\", \"Burkina Faso\" ],\n\t[ \"1377\", \"Hall\", \"Randall\", \"X1C 7A8\", \"Cambodia\" ],\n\t[ \"1378\", \"Burke\", \"Silva\", \"57219\", \"Romania\" ],\n\t[ \"1379\", \"Talon\", \"Kline\", \"28200\", \"Argentina\" ],\n\t[ \"1380\", \"Cassady\", \"Duncan\", \"Y2M 8F5\", \"Kenya\" ],\n\t[ \"1381\", \"Brielle\", \"Reed\", \"06254\", \"Greece\" ],\n\t[ \"1382\", \"Claire\", \"Stein\", \"50289\", \"Viet Nam\" ],\n\t[ \"1383\", \"Fleur\", \"Cabrera\", \"30131\", \"Indonesia\" ],\n\t[ \"1384\", \"Ella\", \"Ellison\", \"Q7Q 4R2\", \"Netherlands Antilles\" ],\n\t[ \"1385\", \"Zachery\", \"Wolf\", \"A9Q 6A8\", \"Jamaica\" ],\n\t[ \"1386\", \"Emerson\", \"Brewer\", \"Y4R 9M9\", \"Bosnia and Herzegovina\" ],\n\t[ \"1387\", \"Sarah\", \"Brooks\", \"27281\", \"Pitcairn\" ],\n\t[ \"1388\", \"Kylan\", \"Garrison\", \"S8E 7L8\", \"Djibouti\" ],\n\t[ \"1389\", \"Guinevere\", \"Mills\", \"75612\", \"Comoros\" ],\n\t[ \"1390\", \"Claudia\", \"Stevenson\", \"73390\", \"Colombia\" ],\n\t[ \"1391\", \"Valentine\", \"Burton\", \"Z9P 7R8\", \"Nauru\" ],\n\t[ \"1392\", \"Raymond\", \"Mclean\", \"L8W 2K5\", \"Brunei Darussalam\" ],\n\t[ \"1393\", \"Juliet\", \"Combs\", \"88712\", \"Samoa\" ],\n\t[ \"1394\", \"Lawrence\", \"Williamson\", \"32528\", \"Netherlands Antilles\" ],\n\t[ \"1395\", \"Inga\", \"Rivers\", \"12850\", \"Kuwait\" ],\n\t[ \"1396\", \"Mira\", \"Zimmerman\", \"D1I 1W2\", \"Ireland\" ],\n\t[ \"1397\", \"Hilda\", \"Stafford\", \"11054\", \"Cuba\" ],\n\t[ \"1398\", \"Tanek\", \"Kim\", \"88590\", \"Cayman Islands\" ],\n\t[ \"1399\", \"Bryar\", \"Mcintyre\", \"H6F 4S5\", \"Russian Federation\" ],\n\t[ \"1400\", \"Sean\", \"Reed\", \"P2V 8J9\", \"Malta\" ],\n\t[ \"1401\", \"Serena\", \"Henderson\", \"Z5C 8A0\", \"Madagascar\" ],\n\t[ \"1402\", \"Hedley\", \"Parks\", \"L8S 6F4\", \"Angola\" ],\n\t[ \"1403\", \"Alice\", \"Quinn\", \"06084\", \"Senegal\" ],\n\t[ \"1404\", \"Linda\", \"Burgess\", \"H1E 7C0\", \"Turkmenistan\" ],\n\t[ \"1405\", \"Hilda\", \"Burns\", \"Q9Q 4S2\", \"Kyrgyzstan\" ],\n\t[ \"1406\", \"Griffith\", \"Watts\", \"D4J 7N2\", \"United States Minor Outlying Islands\" ],\n\t[ \"1407\", \"Camden\", \"Glenn\", \"12939\", \"Russian Federation\" ],\n\t[ \"1408\", \"Tallulah\", \"Rush\", \"G9V 3N2\", \"Turkey\" ],\n\t[ \"1409\", \"Hasad\", \"Salinas\", \"H3F 7P9\", \"Cameroon\" ],\n\t[ \"1410\", \"Violet\", \"Chavez\", \"T2H 9C6\", \"Virgin Islands, U.S.\" ],\n\t[ \"1411\", \"Declan\", \"Hurley\", \"32614\", \"Iran, Islamic Republic of\" ],\n\t[ \"1412\", \"Robin\", \"Dean\", \"34266\", \"Northern Mariana Islands\" ],\n\t[ \"1413\", \"Mariko\", \"Avila\", \"B8F 8Y5\", \"Burundi\" ],\n\t[ \"1414\", \"Bradley\", \"Pugh\", \"11453\", \"Sri Lanka\" ],\n\t[ \"1415\", \"Herman\", \"Hernandez\", \"F3C 6S2\", \"Chile\" ],\n\t[ \"1416\", \"Montana\", \"Wynn\", \"B3M 8M2\", \"Aruba\" ],\n\t[ \"1417\", \"Erin\", \"Melton\", \"17022\", \"France\" ],\n\t[ \"1418\", \"Zachery\", \"Small\", \"L5O 7O1\", \"French Southern Territories\" ],\n\t[ \"1419\", \"Melanie\", \"Rivera\", \"07922\", \"Korea\" ],\n\t[ \"1420\", \"Blossom\", \"Chase\", \"75493\", \"Mauritius\" ],\n\t[ \"1421\", \"Stephanie\", \"Taylor\", \"U8K 3I9\", \"Bahamas\" ],\n\t[ \"1422\", \"Carter\", \"Fulton\", \"T4F 8D1\", \"Turks and Caicos Islands\" ],\n\t[ \"1423\", \"Celeste\", \"Medina\", \"75629\", \"Lebanon\" ],\n\t[ \"1424\", \"Katell\", \"Guzman\", \"15409\", \"United Arab Emirates\" ],\n\t[ \"1425\", \"Howard\", \"Rowland\", \"29003\", \"Liberia\" ],\n\t[ \"1426\", \"Reece\", \"Taylor\", \"W8G 7P7\", \"Samoa\" ],\n\t[ \"1427\", \"Bradley\", \"Peterson\", \"52568\", \"Singapore\" ],\n\t[ \"1428\", \"Ulric\", \"Hancock\", \"07437\", \"Bolivia\" ],\n\t[ \"1429\", \"Francis\", \"Rogers\", \"15904\", \"Albania\" ],\n\t[ \"1430\", \"Tatiana\", \"Mccray\", \"19604\", \"Belize\" ],\n\t[ \"1431\", \"Merrill\", \"Rowe\", \"68539\", \"Ethiopia\" ],\n\t[ \"1432\", \"Kiara\", \"Taylor\", \"F6D 8V7\", \"Burkina Faso\" ],\n\t[ \"1433\", \"Buffy\", \"Shannon\", \"61880\", \"Kiribati\" ],\n\t[ \"1434\", \"Amber\", \"Farmer\", \"K5F 1J7\", \"Barbados\" ],\n\t[ \"1435\", \"Blake\", \"Wilkins\", \"O1L 2G2\", \"Virgin Islands, U.S.\" ],\n\t[ \"1436\", \"Aimee\", \"Fulton\", \"18626\", \"Chad\" ],\n\t[ \"1437\", \"Kai\", \"Montgomery\", \"U6S 4W7\", \"Costa Rica\" ],\n\t[ \"1438\", \"Latifah\", \"Bell\", \"74589\", \"Chad\" ],\n\t[ \"1439\", \"Ronan\", \"Herring\", \"01710\", \"Palestinian Territory, Occupied\" ],\n\t[ \"1440\", \"Macy\", \"Skinner\", \"78054\", \"Gibraltar\" ],\n\t[ \"1441\", \"Ignatius\", \"Berg\", \"59756\", \"Liechtenstein\" ],\n\t[ \"1442\", \"Prescott\", \"Pratt\", \"V6H 6P4\", \"Kuwait\" ],\n\t[ \"1443\", \"Deborah\", \"Hebert\", \"11480\", \"Liberia\" ],\n\t[ \"1444\", \"Quentin\", \"Jones\", \"G8W 8U6\", \"Slovenia\" ],\n\t[ \"1445\", \"Duncan\", \"Parsons\", \"Z9F 5G8\", \"Cambodia\" ],\n\t[ \"1446\", \"Sheila\", \"George\", \"18033\", \"Trinidad and Tobago\" ],\n\t[ \"1447\", \"Alyssa\", \"Padilla\", \"V3O 6C3\", \"Qatar\" ],\n\t[ \"1448\", \"Amelia\", \"Orr\", \"51943\", \"Canada\" ],\n\t[ \"1449\", \"Bethany\", \"Thomas\", \"33451\", \"Liberia\" ],\n\t[ \"1450\", \"Kellie\", \"Pitts\", \"G4S 1Q3\", \"Panama\" ],\n\t[ \"1451\", \"Stone\", \"Stout\", \"L4C 9N0\", \"Latvia\" ],\n\t[ \"1452\", \"Brynne\", \"Bailey\", \"B1M 4O0\", \"Ukraine\" ],\n\t[ \"1453\", \"Aquila\", \"Hurley\", \"41312\", \"United Kingdom\" ],\n\t[ \"1454\", \"David\", \"Bradshaw\", \"11152\", \"Denmark\" ],\n\t[ \"1455\", \"Ryan\", \"Gates\", \"Z7O 1U0\", \"Austria\" ],\n\t[ \"1456\", \"Kyle\", \"Weber\", \"39871\", \"Guyana\" ],\n\t[ \"1457\", \"Declan\", \"Moore\", \"K3B 6L2\", \"Gibraltar\" ],\n\t[ \"1458\", \"Theodore\", \"Hickman\", \"W8E 6K1\", \"Mauritius\" ],\n\t[ \"1459\", \"Rebekah\", \"Merritt\", \"44042\", \"Mauritania\" ],\n\t[ \"1460\", \"Meredith\", \"Powell\", \"98238\", \"Bhutan\" ],\n\t[ \"1461\", \"Paki\", \"Simmons\", \"34122\", \"Norway\" ],\n\t[ \"1462\", \"Carissa\", \"Ballard\", \"20095\", \"Antarctica\" ],\n\t[ \"1463\", \"James\", \"Wilson\", \"96376\", \"Venezuela\" ],\n\t[ \"1464\", \"Pamela\", \"Gamble\", \"U7F 7B6\", \"Turkmenistan\" ],\n\t[ \"1465\", \"Rogan\", \"Davenport\", \"E6S 4R7\", \"French Polynesia\" ],\n\t[ \"1466\", \"Daphne\", \"Pearson\", \"G2H 9M0\", \"American Samoa\" ],\n\t[ \"1467\", \"Maxwell\", \"Nash\", \"87205\", \"Guadeloupe\" ],\n\t[ \"1468\", \"Hayes\", \"Salazar\", \"55712\", \"American Samoa\" ],\n\t[ \"1469\", \"Justin\", \"Conner\", \"03924\", \"United Kingdom\" ],\n\t[ \"1470\", \"Blythe\", \"Joyner\", \"T6H 3M0\", \"Montserrat\" ],\n\t[ \"1471\", \"Herrod\", \"Spears\", \"19474\", \"Philippines\" ],\n\t[ \"1472\", \"Yvette\", \"Joyce\", \"R7Y 7B8\", \"Botswana\" ],\n\t[ \"1473\", \"Chloe\", \"Reid\", \"K4Y 1R2\", \"Philippines\" ],\n\t[ \"1474\", \"MacKensie\", \"Branch\", \"J5E 3X8\", \"Saint Kitts and Nevis\" ],\n\t[ \"1475\", \"Nasim\", \"Buchanan\", \"M4E 4D2\", \"Portugal\" ],\n\t[ \"1476\", \"Aileen\", \"Rasmussen\", \"H2V 3F4\", \"Dominica\" ],\n\t[ \"1477\", \"Nicole\", \"Mullins\", \"U6Q 9X5\", \"New Caledonia\" ],\n\t[ \"1478\", \"David\", \"Luna\", \"11935\", \"Svalbard and Jan Mayen\" ],\n\t[ \"1479\", \"Germaine\", \"Massey\", \"G3N 4C7\", \"Colombia\" ],\n\t[ \"1480\", \"Matthew\", \"Knowles\", \"V4D 4Z0\", \"Turkey\" ],\n\t[ \"1481\", \"Timon\", \"Rowe\", \"14024\", \"Morocco\" ],\n\t[ \"1482\", \"Gail\", \"Young\", \"68293\", \"Bhutan\" ],\n\t[ \"1483\", \"Mariam\", \"Mejia\", \"O3P 4Q7\", \"Singapore\" ],\n\t[ \"1484\", \"Carla\", \"Norris\", \"D7A 3F1\", \"Liberia\" ],\n\t[ \"1485\", \"Ainsley\", \"Donaldson\", \"H4Z 1Q8\", \"Tanzania, United Republic of\" ],\n\t[ \"1486\", \"Avye\", \"Raymond\", \"44808\", \"Namibia\" ],\n\t[ \"1487\", \"Amanda\", \"Sargent\", \"O7F 3S4\", \"Afghanistan\" ],\n\t[ \"1488\", \"Tiger\", \"Chambers\", \"I3K 7H4\", \"United States\" ],\n\t[ \"1489\", \"Dylan\", \"Ford\", \"04043\", \"Solomon Islands\" ],\n\t[ \"1490\", \"Kaitlin\", \"Franklin\", \"99451\", \"Namibia\" ],\n\t[ \"1491\", \"Hayes\", \"Craft\", \"D6H 4Y6\", \"Christmas Island\" ],\n\t[ \"1492\", \"Nolan\", \"Sullivan\", \"31246\", \"United States Minor Outlying Islands\" ],\n\t[ \"1493\", \"Jennifer\", \"Romero\", \"E7I 1R7\", \"Latvia\" ],\n\t[ \"1494\", \"Deanna\", \"Wall\", \"36109\", \"Nepal\" ],\n\t[ \"1495\", \"Dara\", \"Valenzuela\", \"18359\", \"Martinique\" ],\n\t[ \"1496\", \"Iris\", \"Blanchard\", \"84392\", \"Turks and Caicos Islands\" ],\n\t[ \"1497\", \"Rhea\", \"Burgess\", \"T7Y 7C5\", \"Liberia\" ],\n\t[ \"1498\", \"Karina\", \"Small\", \"B2F 2X5\", \"Bermuda\" ],\n\t[ \"1499\", \"Victor\", \"Case\", \"49492\", \"Vanuatu\" ],\n\t[ \"1500\", \"Rose\", \"Terry\", \"B4G 8I0\", \"Timor-leste\" ],\n\t[ \"1501\", \"Wyatt\", \"Berg\", \"K3B 5N2\", \"Vanuatu\" ],\n\t[ \"1502\", \"Zephania\", \"Herrera\", \"E6R 2A5\", \"Romania\" ],\n\t[ \"1503\", \"Felix\", \"Johns\", \"X8U 2P1\", \"Angola\" ],\n\t[ \"1504\", \"Melyssa\", \"George\", \"M4J 5X8\", \"Uzbekistan\" ],\n\t[ \"1505\", \"Robert\", \"Spears\", \"61322\", \"Papua New Guinea\" ],\n\t[ \"1506\", \"Myra\", \"Wood\", \"50638\", \"Afghanistan\" ],\n\t[ \"1507\", \"Sean\", \"Kerr\", \"40094\", \"Guadeloupe\" ],\n\t[ \"1508\", \"Wesley\", \"Mcclain\", \"H7F 1H3\", \"Mongolia\" ],\n\t[ \"1509\", \"Ishmael\", \"Hoover\", \"42503\", \"Czech Republic\" ],\n\t[ \"1510\", \"Ocean\", \"Parker\", \"L3Z 8G0\", \"Guyana\" ],\n\t[ \"1511\", \"Berk\", \"Clay\", \"B6Q 7V7\", \"Botswana\" ],\n\t[ \"1512\", \"Daquan\", \"Harrison\", \"78004\", \"Niger\" ],\n\t[ \"1513\", \"Ramona\", \"Burris\", \"66986\", \"Palau\" ],\n\t[ \"1514\", \"Jaden\", \"Miranda\", \"80086\", \"Madagascar\" ],\n\t[ \"1515\", \"Solomon\", \"Kirk\", \"R7M 3M3\", \"Slovenia\" ],\n\t[ \"1516\", \"Tanek\", \"Rosales\", \"X5B 5D0\", \"Tonga\" ],\n\t[ \"1517\", \"Jack\", \"Cooke\", \"46356\", \"French Southern Territories\" ],\n\t[ \"1518\", \"Naomi\", \"Sykes\", \"76541\", \"Marshall Islands\" ],\n\t[ \"1519\", \"Moana\", \"Vinson\", \"K4R 3U7\", \"Saint Pierre and Miquelon\" ],\n\t[ \"1520\", \"Kaye\", \"Sweet\", \"S6S 2G0\", \"Dominican Republic\" ],\n\t[ \"1521\", \"Bruno\", \"Beard\", \"20686\", \"Israel\" ],\n\t[ \"1522\", \"Helen\", \"Richards\", \"66393\", \"Argentina\" ],\n\t[ \"1523\", \"Gisela\", \"Owens\", \"S8Q 4L3\", \"Haiti\" ],\n\t[ \"1524\", \"Ivy\", \"Garrett\", \"P6G 8S8\", \"United Arab Emirates\" ],\n\t[ \"1525\", \"Malik\", \"Osborne\", \"78332\", \"Tajikistan\" ],\n\t[ \"1526\", \"Whoopi\", \"Franco\", \"T3T 5Y1\", \"Serbia and Montenegro\" ],\n\t[ \"1527\", \"Basil\", \"Baker\", \"61233\", \"Cuba\" ],\n\t[ \"1528\", \"Linda\", \"King\", \"31410\", \"Falkland Islands (Malvinas)\" ],\n\t[ \"1529\", \"Allegra\", \"Hobbs\", \"F2C 9M8\", \"Andorra\" ],\n\t[ \"1530\", \"Kirsten\", \"Elliott\", \"T8C 4X3\", \"Haiti\" ],\n\t[ \"1531\", \"Joseph\", \"Ortiz\", \"40165\", \"Falkland Islands (Malvinas)\" ],\n\t[ \"1532\", \"Pearl\", \"Mccormick\", \"93914\", \"Falkland Islands (Malvinas)\" ],\n\t[ \"1533\", \"Fritz\", \"Austin\", \"A3S 7C8\", \"Canada\" ],\n\t[ \"1534\", \"Lunea\", \"Hickman\", \"25676\", \"Cameroon\" ],\n\t[ \"1535\", \"Inga\", \"Cortez\", \"14707\", \"Comoros\" ],\n\t[ \"1536\", \"Claudia\", \"Long\", \"74877\", \"Tokelau\" ],\n\t[ \"1537\", \"Judah\", \"Williamson\", \"S9N 6F0\", \"Paraguay\" ],\n\t[ \"1538\", \"Eve\", \"Beasley\", \"K8Z 5H7\", \"Honduras\" ],\n\t[ \"1539\", \"Tad\", \"Lang\", \"29577\", \"Equatorial Guinea\" ],\n\t[ \"1540\", \"Jack\", \"Lawson\", \"46631\", \"Costa Rica\" ],\n\t[ \"1541\", \"Vaughan\", \"Barron\", \"N9L 9T4\", \"Chile\" ],\n\t[ \"1542\", \"Solomon\", \"Bowman\", \"05734\", \"Cocos (Keeling) Islands\" ],\n\t[ \"1543\", \"Nash\", \"Giles\", \"64600\", \"Denmark\" ],\n\t[ \"1544\", \"Xander\", \"Eaton\", \"84933\", \"Bosnia and Herzegovina\" ],\n\t[ \"1545\", \"Hanna\", \"Hull\", \"61062\", \"Namibia\" ],\n\t[ \"1546\", \"Lee\", \"Gaines\", \"V7H 6H7\", \"Suriname\" ],\n\t[ \"1547\", \"Brian\", \"Sutton\", \"60055\", \"Timor-leste\" ],\n\t[ \"1548\", \"Azalia\", \"Henson\", \"D9J 8E4\", \"Antarctica\" ],\n\t[ \"1549\", \"Russell\", \"Avila\", \"01774\", \"China\" ],\n\t[ \"1550\", \"Marsden\", \"Leblanc\", \"30201\", \"New Caledonia\" ],\n\t[ \"1551\", \"Tad\", \"Nichols\", \"K5V 6N1\", \"Monaco\" ],\n\t[ \"1552\", \"Eliana\", \"Savage\", \"06807\", \"Central African Republic\" ],\n\t[ \"1553\", \"Madeline\", \"Conway\", \"83513\", \"Latvia\" ],\n\t[ \"1554\", \"Kai\", \"Caldwell\", \"S1K 2Q2\", \"Indonesia\" ],\n\t[ \"1555\", \"Wynne\", \"Goodman\", \"U9Y 8P7\", \"Gibraltar\" ],\n\t[ \"1556\", \"Nora\", \"Dudley\", \"52688\", \"Netherlands Antilles\" ],\n\t[ \"1557\", \"Anastasia\", \"Gates\", \"T7T 8C8\", \"Morocco\" ],\n\t[ \"1558\", \"Lester\", \"Good\", \"76376\", \"Heard Island and Mcdonald Islands\" ],\n\t[ \"1559\", \"Craig\", \"Skinner\", \"S7B 3Z6\", \"Madagascar\" ],\n\t[ \"1560\", \"Kibo\", \"Craft\", \"M5C 2I9\", \"Hong Kong\" ],\n\t[ \"1561\", \"Carlos\", \"Buck\", \"89343\", \"Northern Mariana Islands\" ],\n\t[ \"1562\", \"Ivor\", \"Mooney\", \"M9D 2Y3\", \"Korea\" ],\n\t[ \"1563\", \"Armand\", \"Shields\", \"E8O 7X6\", \"Uzbekistan\" ],\n\t[ \"1564\", \"Grace\", \"Weeks\", \"G5B 3W5\", \"Nicaragua\" ],\n\t[ \"1565\", \"Reagan\", \"Mann\", \"J2E 5I1\", \"San Marino\" ],\n\t[ \"1566\", \"Quin\", \"Nolan\", \"Q9E 2Q0\", \"Turkey\" ],\n\t[ \"1567\", \"Kareem\", \"Jefferson\", \"91393\", \"Zambia\" ],\n\t[ \"1568\", \"Erica\", \"Mccoy\", \"C3P 3L0\", \"Viet Nam\" ],\n\t[ \"1569\", \"Sybill\", \"Larsen\", \"J3U 3L9\", \"Sierra Leone\" ],\n\t[ \"1570\", \"Angela\", \"Weber\", \"46559\", \"Croatia\" ],\n\t[ \"1571\", \"Mannix\", \"Noel\", \"94029\", \"Belgium\" ],\n\t[ \"1572\", \"Martina\", \"Travis\", \"20063\", \"Solomon Islands\" ],\n\t[ \"1573\", \"Dominic\", \"Whitehead\", \"83547\", \"Gibraltar\" ],\n\t[ \"1574\", \"Vladimir\", \"Hunter\", \"L3I 4G7\", \"Reunion\" ],\n\t[ \"1575\", \"Farrah\", \"Alexander\", \"18538\", \"Croatia\" ],\n\t[ \"1576\", \"Hop\", \"Burns\", \"X1C 7J6\", \"Saint Lucia\" ],\n\t[ \"1577\", \"Zelda\", \"Trevino\", \"L8P 7E9\", \"Guinea\" ],\n\t[ \"1578\", \"Nehru\", \"Decker\", \"Q1P 4Q9\", \"Western Sahara\" ],\n\t[ \"1579\", \"Shay\", \"Goff\", \"68576\", \"Sweden\" ],\n\t[ \"1580\", \"Dominic\", \"Martin\", \"C1M 9P2\", \"Denmark\" ],\n\t[ \"1581\", \"Heather\", \"Doyle\", \"Y7R 9H1\", \"Iran, Islamic Republic of\" ],\n\t[ \"1582\", \"Honorato\", \"Rojas\", \"29414\", \"India\" ],\n\t[ \"1583\", \"Florence\", \"England\", \"64669\", \"China\" ],\n\t[ \"1584\", \"Zane\", \"Reyes\", \"84771\", \"Heard Island and Mcdonald Islands\" ],\n\t[ \"1585\", \"Scarlett\", \"Poole\", \"36928\", \"Algeria\" ],\n\t[ \"1586\", \"Dieter\", \"Brennan\", \"Y8V 5L2\", \"Colombia\" ],\n\t[ \"1587\", \"Jamal\", \"Whitney\", \"33428\", \"Turkey\" ],\n\t[ \"1588\", \"Evan\", \"Guy\", \"72119\", \"Slovakia\" ],\n\t[ \"1589\", \"Candace\", \"Bauer\", \"C8L 1P2\", \"Macedonia\" ],\n\t[ \"1590\", \"Naomi\", \"Pennington\", \"17350\", \"Tonga\" ],\n\t[ \"1591\", \"Celeste\", \"Banks\", \"R8R 4C8\", \"Anguilla\" ],\n\t[ \"1592\", \"Basil\", \"Elliott\", \"80065\", \"Singapore\" ],\n\t[ \"1593\", \"Darryl\", \"Wise\", \"33140\", \"Brunei Darussalam\" ],\n\t[ \"1594\", \"Marny\", \"Walls\", \"S1K 4V1\", \"Western Sahara\" ],\n\t[ \"1595\", \"Anastasia\", \"Meyer\", \"Z1F 8C2\", \"El Salvador\" ],\n\t[ \"1596\", \"Brynne\", \"Rivera\", \"48070\", \"Mexico\" ],\n\t[ \"1597\", \"Macey\", \"Johnston\", \"X9E 9J5\", \"Guadeloupe\" ],\n\t[ \"1598\", \"Bethany\", \"Marks\", \"46648\", \"Bhutan\" ],\n\t[ \"1599\", \"Kiayada\", \"Glass\", \"13661\", \"Christmas Island\" ],\n\t[ \"1600\", \"Veda\", \"Bowers\", \"D7S 1S9\", \"Korea\" ],\n\t[ \"1601\", \"Dante\", \"Kirk\", \"58404\", \"Guinea\" ],\n\t[ \"1602\", \"Judah\", \"Sloan\", \"04528\", \"Andorra\" ],\n\t[ \"1603\", \"Serena\", \"Giles\", \"12139\", \"Papua New Guinea\" ],\n\t[ \"1604\", \"Chase\", \"Hull\", \"27203\", \"Guinea-bissau\" ],\n\t[ \"1605\", \"Wallace\", \"Poole\", \"58919\", \"Christmas Island\" ],\n\t[ \"1606\", \"Deacon\", \"Lynn\", \"Z1H 9G4\", \"Kenya\" ],\n\t[ \"1607\", \"Igor\", \"Duncan\", \"X2V 2X1\", \"Christmas Island\" ],\n\t[ \"1608\", \"Walker\", \"Hopkins\", \"67256\", \"Bosnia and Herzegovina\" ],\n\t[ \"1609\", \"Serena\", \"Burnett\", \"Q4C 7Q0\", \"Canada\" ],\n\t[ \"1610\", \"Hedwig\", \"Burgess\", \"O2J 7A5\", \"Rwanda\" ],\n\t[ \"1611\", \"Amal\", \"Richmond\", \"34506\", \"Australia\" ],\n\t[ \"1612\", \"Rhona\", \"Gomez\", \"W2C 3I7\", \"Oman\" ],\n\t[ \"1613\", \"Kai\", \"Acosta\", \"N2O 7M2\", \"Uganda\" ],\n\t[ \"1614\", \"Henry\", \"Roman\", \"78113\", \"Guadeloupe\" ],\n\t[ \"1615\", \"Chester\", \"Good\", \"88809\", \"Norway\" ],\n\t[ \"1616\", \"Cleo\", \"Tanner\", \"73924\", \"Uganda\" ],\n\t[ \"1617\", \"Emi\", \"Lloyd\", \"59746\", \"South Africa\" ],\n\t[ \"1618\", \"Christopher\", \"Lopez\", \"76264\", \"Libyan Arab Jamahiriya\" ],\n\t[ \"1619\", \"Yvonne\", \"Mathews\", \"68655\", \"Saint Lucia\" ],\n\t[ \"1620\", \"Kimberly\", \"Mullen\", \"D6J 9G3\", \"Virgin Islands, British\" ],\n\t[ \"1621\", \"Hanna\", \"Slater\", \"F8F 9K5\", \"Montserrat\" ],\n\t[ \"1622\", \"Laura\", \"Dennis\", \"J6U 2G3\", \"Viet Nam\" ],\n\t[ \"1623\", \"Rogan\", \"Richards\", \"R1D 1B3\", \"Argentina\" ],\n\t[ \"1624\", \"Mira\", \"Rodriquez\", \"C3D 3E5\", \"Guinea\" ],\n\t[ \"1625\", \"Ezra\", \"Myers\", \"Y7Z 7X2\", \"Kuwait\" ],\n\t[ \"1626\", \"Jocelyn\", \"Martin\", \"E2F 3F2\", \"Algeria\" ],\n\t[ \"1627\", \"Denton\", \"Lee\", \"80903\", \"Congo\" ],\n\t[ \"1628\", \"Grace\", \"Leach\", \"86865\", \"Spain\" ],\n\t[ \"1629\", \"Clark\", \"Morrow\", \"12834\", \"Northern Mariana Islands\" ],\n\t[ \"1630\", \"Armando\", \"Calhoun\", \"I3I 1D4\", \"Spain\" ],\n\t[ \"1631\", \"George\", \"Decker\", \"R1B 6Q9\", \"Mali\" ],\n\t[ \"1632\", \"Jerome\", \"Salazar\", \"03831\", \"Faroe Islands\" ],\n\t[ \"1633\", \"Logan\", \"Santiago\", \"46269\", \"Hungary\" ],\n\t[ \"1634\", \"Gavin\", \"Tate\", \"Y3L 6G5\", \"Italy\" ],\n\t[ \"1635\", \"Chloe\", \"Jennings\", \"D9B 2H9\", \"Cambodia\" ],\n\t[ \"1636\", \"Rashad\", \"Knox\", \"T1V 4G5\", \"Germany\" ],\n\t[ \"1637\", \"Jin\", \"Roberts\", \"82928\", \"Azerbaijan\" ],\n\t[ \"1638\", \"Amity\", \"Guerrero\", \"F4G 2L4\", \"Viet Nam\" ],\n\t[ \"1639\", \"Carter\", \"Roberson\", \"53651\", \"Niue\" ],\n\t[ \"1640\", \"Slade\", \"Carson\", \"H9E 1G1\", \"Guyana\" ],\n\t[ \"1641\", \"Buckminster\", \"Christensen\", \"F5J 6T5\", \"Algeria\" ],\n\t[ \"1642\", \"Fallon\", \"Peters\", \"D9Y 5Q4\", \"Ethiopia\" ],\n\t[ \"1643\", \"Amy\", \"Barry\", \"D6F 3R4\", \"New Caledonia\" ],\n\t[ \"1644\", \"Calvin\", \"Buck\", \"18354\", \"Macedonia\" ],\n\t[ \"1645\", \"Kaye\", \"Haynes\", \"D9K 1X8\", \"Italy\" ],\n\t[ \"1646\", \"Shea\", \"Hammond\", \"R7P 3X8\", \"Guam\" ],\n\t[ \"1647\", \"Kiara\", \"Franks\", \"01185\", \"Mozambique\" ],\n\t[ \"1648\", \"Armando\", \"Oneil\", \"88972\", \"Bahrain\" ],\n\t[ \"1649\", \"Lesley\", \"Allen\", \"05171\", \"Belgium\" ],\n\t[ \"1650\", \"Ignatius\", \"Barrett\", \"94084\", \"Georgia\" ],\n\t[ \"1651\", \"Graham\", \"Maldonado\", \"76354\", \"Dominican Republic\" ],\n\t[ \"1652\", \"Briar\", \"Roman\", \"P9M 3A9\", \"Cayman Islands\" ],\n\t[ \"1653\", \"Germane\", \"Colon\", \"U3X 7S9\", \"Brazil\" ],\n\t[ \"1654\", \"Alvin\", \"Mcpherson\", \"58411\", \"Guinea\" ],\n\t[ \"1655\", \"Belle\", \"Sandoval\", \"87172\", \"Cyprus\" ],\n\t[ \"1656\", \"Eric\", \"Caldwell\", \"63246\", \"Guinea\" ],\n\t[ \"1657\", \"Nadine\", \"Dale\", \"T6E 4B0\", \"Denmark\" ],\n\t[ \"1658\", \"Dora\", \"Jimenez\", \"85463\", \"Nauru\" ],\n\t[ \"1659\", \"Mohammad\", \"Strickland\", \"H8B 9G2\", \"Japan\" ],\n\t[ \"1660\", \"Reagan\", \"Preston\", \"G5E 8S5\", \"Honduras\" ],\n\t[ \"1661\", \"Tamekah\", \"Daniel\", \"Z3X 6Q6\", \"Belarus\" ],\n\t[ \"1662\", \"Halee\", \"Mills\", \"23332\", \"Mayotte\" ],\n\t[ \"1663\", \"Courtney\", \"England\", \"09751\", \"Saint Kitts and Nevis\" ],\n\t[ \"1664\", \"Dai\", \"Arnold\", \"A2N 9J4\", \"Argentina\" ],\n\t[ \"1665\", \"Priscilla\", \"Reyes\", \"G2B 5M4\", \"Azerbaijan\" ],\n\t[ \"1666\", \"Brenda\", \"Stanley\", \"I6O 3I1\", \"Hungary\" ],\n\t[ \"1667\", \"Kasper\", \"Washington\", \"H4K 8K7\", \"Serbia and Montenegro\" ],\n\t[ \"1668\", \"Suki\", \"Hendricks\", \"L1K 5O9\", \"Norway\" ],\n\t[ \"1669\", \"Rebekah\", \"Mccormick\", \"89543\", \"Slovenia\" ],\n\t[ \"1670\", \"Oprah\", \"Rodriquez\", \"90034\", \"Costa Rica\" ],\n\t[ \"1671\", \"Ivory\", \"Matthews\", \"T9J 2A7\", \"Panama\" ],\n\t[ \"1672\", \"Ferris\", \"Garner\", \"93583\", \"Niue\" ],\n\t[ \"1673\", \"Melvin\", \"White\", \"X5U 9N8\", \"Nigeria\" ],\n\t[ \"1674\", \"Henry\", \"Swanson\", \"E7V 2C9\", \"Northern Mariana Islands\" ],\n\t[ \"1675\", \"Hadassah\", \"Eaton\", \"52798\", \"Albania\" ],\n\t[ \"1676\", \"Lisandra\", \"Sykes\", \"90838\", \"Namibia\" ],\n\t[ \"1677\", \"Honorato\", \"Bradshaw\", \"W3D 1Z9\", \"United States\" ],\n\t[ \"1678\", \"Aurelia\", \"Paul\", \"Z6E 6W9\", \"Malaysia\" ],\n\t[ \"1679\", \"Arthur\", \"Mann\", \"74673\", \"Bhutan\" ],\n\t[ \"1680\", \"Melissa\", \"Hernandez\", \"11742\", \"Dominican Republic\" ],\n\t[ \"1681\", \"Bert\", \"Mosley\", \"N2K 5U5\", \"Kuwait\" ],\n\t[ \"1682\", \"Sigourney\", \"Sharpe\", \"30204\", \"South Africa\" ],\n\t[ \"1683\", \"Ifeoma\", \"Woods\", \"39850\", \"Haiti\" ],\n\t[ \"1684\", \"Tyler\", \"Medina\", \"K6L 9V8\", \"Indonesia\" ],\n\t[ \"1685\", \"Karleigh\", \"Griffin\", \"G8Z 6W2\", \"Canada\" ],\n\t[ \"1686\", \"Brianna\", \"Collins\", \"11919\", \"New Caledonia\" ],\n\t[ \"1687\", \"Allistair\", \"Hampton\", \"O1X 2N7\", \"Cocos (Keeling) Islands\" ],\n\t[ \"1688\", \"Carla\", \"Manning\", \"76866\", \"Svalbard and Jan Mayen\" ],\n\t[ \"1689\", \"Jakeem\", \"Brewer\", \"Y1T 1D7\", \"Comoros\" ],\n\t[ \"1690\", \"Price\", \"Guerrero\", \"S7Z 8O1\", \"Christmas Island\" ],\n\t[ \"1691\", \"Harlan\", \"Sandoval\", \"58527\", \"Czech Republic\" ],\n\t[ \"1692\", \"Marcia\", \"Robinson\", \"64662\", \"Uganda\" ],\n\t[ \"1693\", \"Sylvester\", \"Hewitt\", \"81468\", \"Honduras\" ],\n\t[ \"1694\", \"Dawn\", \"Wood\", \"77743\", \"Malawi\" ],\n\t[ \"1695\", \"Farrah\", \"Nielsen\", \"E4N 9A9\", \"Christmas Island\" ],\n\t[ \"1696\", \"Tanisha\", \"Benjamin\", \"L2J 3G7\", \"Cape Verde\" ],\n\t[ \"1697\", \"Cherokee\", \"Atkins\", \"L7D 2L5\", \"Moldova\" ],\n\t[ \"1698\", \"Madaline\", \"Elliott\", \"H7K 8R4\", \"Barbados\" ],\n\t[ \"1699\", \"Odysseus\", \"Roy\", \"65008\", \"Slovakia\" ],\n\t[ \"1700\", \"Eaton\", \"Stein\", \"Z2V 7H0\", \"Moldova\" ],\n\t[ \"1701\", \"Rachel\", \"Hurley\", \"L6L 2B2\", \"Antigua and Barbuda\" ],\n\t[ \"1702\", \"Stacey\", \"Hardin\", \"O9U 1B7\", \"Montserrat\" ],\n\t[ \"1703\", \"Grady\", \"Montgomery\", \"75852\", \"Guinea-bissau\" ],\n\t[ \"1704\", \"Serena\", \"Douglas\", \"F5M 8Z6\", \"Mauritius\" ],\n\t[ \"1705\", \"Ralph\", \"Duke\", \"H7X 3M9\", \"Tunisia\" ],\n\t[ \"1706\", \"Charles\", \"Moody\", \"86445\", \"Pitcairn\" ],\n\t[ \"1707\", \"Mariam\", \"Lara\", \"07952\", \"United Kingdom\" ],\n\t[ \"1708\", \"Whitney\", \"Garza\", \"74001\", \"Norfolk Island\" ],\n\t[ \"1709\", \"Beverly\", \"Thornton\", \"69847\", \"Canada\" ],\n\t[ \"1710\", \"Helen\", \"Gentry\", \"Z8S 7U4\", \"Reunion\" ],\n\t[ \"1711\", \"Janna\", \"Gould\", \"W6C 6E1\", \"Burundi\" ],\n\t[ \"1712\", \"Jana\", \"Hooper\", \"A1R 9Y0\", \"Yemen\" ],\n\t[ \"1713\", \"Zachary\", \"Nicholson\", \"49616\", \"Gabon\" ],\n\t[ \"1714\", \"Julian\", \"Davis\", \"37608\", \"Anguilla\" ],\n\t[ \"1715\", \"Gay\", \"Knox\", \"51952\", \"Croatia\" ],\n\t[ \"1716\", \"Iola\", \"Moses\", \"16601\", \"French Polynesia\" ],\n\t[ \"1717\", \"Allegra\", \"Holder\", \"C9R 8J3\", \"Dominican Republic\" ],\n\t[ \"1718\", \"Cecilia\", \"Shannon\", \"62624\", \"Reunion\" ],\n\t[ \"1719\", \"Cora\", \"Peterson\", \"I9V 5P5\", \"Chad\" ],\n\t[ \"1720\", \"Stewart\", \"Mathews\", \"A5H 1E1\", \"Mexico\" ],\n\t[ \"1721\", \"Kathleen\", \"Lynn\", \"82408\", \"Honduras\" ],\n\t[ \"1722\", \"William\", \"Schneider\", \"25823\", \"Tajikistan\" ],\n\t[ \"1723\", \"Alice\", \"Mcconnell\", \"50155\", \"Russian Federation\" ],\n\t[ \"1724\", \"Timon\", \"Dillon\", \"93171\", \"Croatia\" ],\n\t[ \"1725\", \"Tanek\", \"Ellison\", \"Y7Q 5B1\", \"Malawi\" ],\n\t[ \"1726\", \"Tamekah\", \"Cummings\", \"03764\", \"Afghanistan\" ],\n\t[ \"1727\", \"Charlotte\", \"Chaney\", \"U7Y 7B0\", \"Kyrgyzstan\" ],\n\t[ \"1728\", \"Jason\", \"Conway\", \"37713\", \"Martinique\" ],\n\t[ \"1729\", \"Graiden\", \"Combs\", \"40454\", \"Turkmenistan\" ],\n\t[ \"1730\", \"Virginia\", \"Ortiz\", \"K9N 2Q4\", \"Malta\" ],\n\t[ \"1731\", \"Thomas\", \"Cannon\", \"W1H 3T9\", \"Cuba\" ],\n\t[ \"1732\", \"Galena\", \"Dominguez\", \"68072\", \"India\" ],\n\t[ \"1733\", \"Vaughan\", \"Petty\", \"15200\", \"Lesotho\" ],\n\t[ \"1734\", \"Buffy\", \"Saunders\", \"K1W 3B1\", \"Burkina Faso\" ],\n\t[ \"1735\", \"Chava\", \"Hill\", \"93461\", \"Iran, Islamic Republic of\" ],\n\t[ \"1736\", \"Sage\", \"Hampton\", \"R8Y 8J1\", \"Malta\" ],\n\t[ \"1737\", \"Nathaniel\", \"Whitney\", \"89097\", \"Ukraine\" ],\n\t[ \"1738\", \"Hector\", \"Hayden\", \"70774\", \"Netherlands\" ],\n\t[ \"1739\", \"Mercedes\", \"Freeman\", \"80848\", \"Croatia\" ],\n\t[ \"1740\", \"Vance\", \"Spencer\", \"25484\", \"Guyana\" ],\n\t[ \"1741\", \"Josephine\", \"Stevens\", \"E4D 9D1\", \"Netherlands Antilles\" ],\n\t[ \"1742\", \"Barbara\", \"Mcclure\", \"22602\", \"Cambodia\" ],\n\t[ \"1743\", \"Sydney\", \"Holder\", \"X4G 1Z7\", \"British Indian Ocean Territory\" ],\n\t[ \"1744\", \"Velma\", \"Evans\", \"83914\", \"New Zealand\" ],\n\t[ \"1745\", \"Francis\", \"Lane\", \"12545\", \"Serbia and Montenegro\" ],\n\t[ \"1746\", \"Garrison\", \"Brock\", \"19993\", \"Eritrea\" ],\n\t[ \"1747\", \"Quentin\", \"Santiago\", \"07085\", \"Norfolk Island\" ],\n\t[ \"1748\", \"Ivory\", \"Wilkerson\", \"79440\", \"Libyan Arab Jamahiriya\" ],\n\t[ \"1749\", \"Karyn\", \"Buckner\", \"D1Y 7D8\", \"Cocos (Keeling) Islands\" ],\n\t[ \"1750\", \"Mari\", \"Bright\", \"24721\", \"Pakistan\" ],\n\t[ \"1751\", \"Dexter\", \"Garrison\", \"X3X 7G3\", \"Western Sahara\" ],\n\t[ \"1752\", \"Venus\", \"Acevedo\", \"V2F 8C0\", \"Poland\" ],\n\t[ \"1753\", \"Nayda\", \"Camacho\", \"F6H 6J5\", \"Northern Mariana Islands\" ],\n\t[ \"1754\", \"Avye\", \"Hartman\", \"G6V 2H0\", \"Hong Kong\" ],\n\t[ \"1755\", \"Kerry\", \"Baird\", \"M3Q 7B7\", \"Russian Federation\" ],\n\t[ \"1756\", \"Uma\", \"Herman\", \"C9A 4P3\", \"Libyan Arab Jamahiriya\" ],\n\t[ \"1757\", \"Amaya\", \"Roman\", \"97179\", \"Iceland\" ],\n\t[ \"1758\", \"Bruce\", \"Joyce\", \"18344\", \"Denmark\" ],\n\t[ \"1759\", \"Jarrod\", \"Alvarez\", \"59269\", \"Liberia\" ],\n\t[ \"1760\", \"Olivia\", \"Reilly\", \"99058\", \"Malaysia\" ],\n\t[ \"1761\", \"Benedict\", \"Hensley\", \"23105\", \"Uganda\" ],\n\t[ \"1762\", \"Lavinia\", \"Hunter\", \"44729\", \"Maldives\" ],\n\t[ \"1763\", \"Bradley\", \"Gomez\", \"65125\", \"Belize\" ],\n\t[ \"1764\", \"Keely\", \"Burris\", \"18390\", \"Brunei Darussalam\" ],\n\t[ \"1765\", \"Autumn\", \"England\", \"E5D 7A5\", \"Kyrgyzstan\" ],\n\t[ \"1766\", \"Jane\", \"Blair\", \"S1W 4O0\", \"Bangladesh\" ],\n\t[ \"1767\", \"Chancellor\", \"Barrett\", \"E9F 1I1\", \"Fiji\" ],\n\t[ \"1768\", \"Whitney\", \"Morin\", \"G5T 4E7\", \"Aruba\" ],\n\t[ \"1769\", \"Madeline\", \"Sparks\", \"W7L 7E0\", \"Belize\" ],\n\t[ \"1770\", \"Dale\", \"Estes\", \"82712\", \"Guam\" ],\n\t[ \"1771\", \"Hakeem\", \"Buck\", \"O6K 1I8\", \"Singapore\" ],\n\t[ \"1772\", \"Alexandra\", \"Burns\", \"12697\", \"Portugal\" ],\n\t[ \"1773\", \"Winifred\", \"Gill\", \"Z8B 8B8\", \"Uruguay\" ],\n\t[ \"1774\", \"Gail\", \"Gomez\", \"S1V 3N8\", \"American Samoa\" ],\n\t[ \"1775\", \"Moana\", \"Brady\", \"18835\", \"Wallis and Futuna\" ],\n\t[ \"1776\", \"Martha\", \"Oliver\", \"81962\", \"Bolivia\" ],\n\t[ \"1777\", \"Nayda\", \"Wooten\", \"00071\", \"Palau\" ],\n\t[ \"1778\", \"Bryar\", \"Collier\", \"50631\", \"Mexico\" ],\n\t[ \"1779\", \"Penelope\", \"Bradshaw\", \"A6A 9M2\", \"Lebanon\" ],\n\t[ \"1780\", \"Wyatt\", \"Lara\", \"75486\", \"Slovenia\" ],\n\t[ \"1781\", \"Wang\", \"Odonnell\", \"N5X 1N5\", \"Bahamas\" ],\n\t[ \"1782\", \"Chiquita\", \"Harrell\", \"21691\", \"Guadeloupe\" ],\n\t[ \"1783\", \"Byron\", \"Blankenship\", \"M8A 3L4\", \"Syrian Arab Republic\" ],\n\t[ \"1784\", \"Holmes\", \"Stokes\", \"81039\", \"Mauritania\" ],\n\t[ \"1785\", \"Naomi\", \"Phillips\", \"56287\", \"Switzerland\" ],\n\t[ \"1786\", \"Quyn\", \"Johnson\", \"D2T 6B7\", \"Czech Republic\" ],\n\t[ \"1787\", \"Gillian\", \"Sanders\", \"50542\", \"Colombia\" ],\n\t[ \"1788\", \"Hope\", \"Benjamin\", \"67423\", \"Bolivia\" ],\n\t[ \"1789\", \"Bryar\", \"Dean\", \"U9V 9E5\", \"Guatemala\" ],\n\t[ \"1790\", \"Karyn\", \"Swanson\", \"S6H 3R8\", \"Israel\" ],\n\t[ \"1791\", \"Amena\", \"David\", \"02286\", \"French Polynesia\" ],\n\t[ \"1792\", \"Ira\", \"Joyner\", \"37335\", \"Cayman Islands\" ],\n\t[ \"1793\", \"Tanek\", \"Oneil\", \"75041\", \"Slovenia\" ],\n\t[ \"1794\", \"Dolan\", \"Miles\", \"K7Q 9U8\", \"Maldives\" ],\n\t[ \"1795\", \"Wang\", \"Keith\", \"88116\", \"Congo\" ],\n\t[ \"1796\", \"Wylie\", \"Bryant\", \"93369\", \"Andorra\" ],\n\t[ \"1797\", \"Heather\", \"Bryant\", \"78015\", \"French Polynesia\" ],\n\t[ \"1798\", \"Regina\", \"Wagner\", \"29087\", \"Virgin Islands, British\" ],\n\t[ \"1799\", \"Nathan\", \"Bush\", \"J5S 9L0\", \"Viet Nam\" ],\n\t[ \"1800\", \"Charity\", \"Dawson\", \"29508\", \"Greece\" ],\n\t[ \"1801\", \"Ulric\", \"Guzman\", \"I6R 6P6\", \"Micronesia\" ],\n\t[ \"1802\", \"Keefe\", \"Scott\", \"J1R 8T6\", \"Uzbekistan\" ],\n\t[ \"1803\", \"Florence\", \"Price\", \"U7P 8F6\", \"Taiwan, Province of China\" ],\n\t[ \"1804\", \"Griffith\", \"England\", \"92557\", \"China\" ],\n\t[ \"1805\", \"Kay\", \"Nielsen\", \"85991\", \"Suriname\" ],\n\t[ \"1806\", \"Tamekah\", \"Blackburn\", \"47324\", \"Panama\" ],\n\t[ \"1807\", \"Indira\", \"Crosby\", \"64463\", \"Trinidad and Tobago\" ],\n\t[ \"1808\", \"Pamela\", \"Vasquez\", \"K2Q 9A1\", \"Ghana\" ],\n\t[ \"1809\", \"Patricia\", \"Haley\", \"51509\", \"Jordan\" ],\n\t[ \"1810\", \"Nevada\", \"Prince\", \"41315\", \"Tokelau\" ],\n\t[ \"1811\", \"Martin\", \"Wilkerson\", \"Y8X 4Y5\", \"Palestinian Territory, Occupied\" ],\n\t[ \"1812\", \"Deirdre\", \"Castaneda\", \"X1S 5E2\", \"Bahrain\" ],\n\t[ \"1813\", \"Cara\", \"Flynn\", \"68372\", \"Azerbaijan\" ],\n\t[ \"1814\", \"Sylvia\", \"Alexander\", \"E5F 9M5\", \"Svalbard and Jan Mayen\" ],\n\t[ \"1815\", \"Macon\", \"Suarez\", \"69866\", \"Tunisia\" ],\n\t[ \"1816\", \"Hammett\", \"Haney\", \"09768\", \"Bangladesh\" ],\n\t[ \"1817\", \"Geoffrey\", \"Simmons\", \"61986\", \"Burundi\" ],\n\t[ \"1818\", \"Danielle\", \"Kelly\", \"71568\", \"Mali\" ],\n\t[ \"1819\", \"Wing\", \"Brown\", \"U4D 6L1\", \"Uzbekistan\" ],\n\t[ \"1820\", \"Len\", \"Barber\", \"40311\", \"Suriname\" ],\n\t[ \"1821\", \"Richard\", \"Wilson\", \"W9E 6D7\", \"Finland\" ],\n\t[ \"1822\", \"Keaton\", \"Hayes\", \"55696\", \"Slovakia\" ],\n\t[ \"1823\", \"Dora\", \"Chaney\", \"57297\", \"United States Minor Outlying Islands\" ],\n\t[ \"1824\", \"Alexandra\", \"Pruitt\", \"17207\", \"Turkmenistan\" ],\n\t[ \"1825\", \"Deanna\", \"Gomez\", \"C9M 9K0\", \"Paraguay\" ],\n\t[ \"1826\", \"Laura\", \"Downs\", \"74422\", \"Antigua and Barbuda\" ],\n\t[ \"1827\", \"Jolene\", \"Lucas\", \"K9E 6U4\", \"Tokelau\" ],\n\t[ \"1828\", \"Lucy\", \"Marquez\", \"L1N 4O4\", \"Argentina\" ],\n\t[ \"1829\", \"Abbot\", \"Bishop\", \"G8W 7I1\", \"Guinea-bissau\" ],\n\t[ \"1830\", \"Aaron\", \"Bowman\", \"K8A 5K7\", \"Greece\" ],\n\t[ \"1831\", \"Candace\", \"Lee\", \"58901\", \"Turks and Caicos Islands\" ],\n\t[ \"1832\", \"Larissa\", \"Allen\", \"O1I 4X0\", \"Belgium\" ],\n\t[ \"1833\", \"Linda\", \"Malone\", \"31211\", \"United Arab Emirates\" ],\n\t[ \"1834\", \"Grace\", \"Daugherty\", \"62610\", \"Cyprus\" ],\n\t[ \"1835\", \"Kyra\", \"Berry\", \"T2F 3E5\", \"Netherlands Antilles\" ],\n\t[ \"1836\", \"Hadassah\", \"Willis\", \"C7H 5V4\", \"El Salvador\" ],\n\t[ \"1837\", \"Kyle\", \"Fitzgerald\", \"X1V 2R9\", \"Croatia\" ],\n\t[ \"1838\", \"Graiden\", \"Atkinson\", \"L9Q 6H8\", \"Thailand\" ],\n\t[ \"1839\", \"Raymond\", \"Fletcher\", \"59574\", \"Argentina\" ],\n\t[ \"1840\", \"Keaton\", \"Barnett\", \"O2G 6B4\", \"Papua New Guinea\" ],\n\t[ \"1841\", \"Farrah\", \"Kramer\", \"21928\", \"Netherlands Antilles\" ],\n\t[ \"1842\", \"Christian\", \"Sellers\", \"55504\", \"Timor-leste\" ],\n\t[ \"1843\", \"Keith\", \"Cohen\", \"D9T 7D0\", \"Italy\" ],\n\t[ \"1844\", \"Karleigh\", \"Bruce\", \"F2A 5H9\", \"Montserrat\" ],\n\t[ \"1845\", \"Julie\", \"Avery\", \"T4T 3Y7\", \"Nepal\" ],\n\t[ \"1846\", \"Hollee\", \"Deleon\", \"47524\", \"Oman\" ],\n\t[ \"1847\", \"Charity\", \"Booker\", \"61071\", \"Cocos (Keeling) Islands\" ],\n\t[ \"1848\", \"Flynn\", \"Bond\", \"E8L 9D2\", \"Afghanistan\" ],\n\t[ \"1849\", \"Sybill\", \"Roth\", \"16453\", \"Saudi Arabia\" ],\n\t[ \"1850\", \"Alyssa\", \"Juarez\", \"04466\", \"Singapore\" ],\n\t[ \"1851\", \"Jennifer\", \"Odonnell\", \"59277\", \"Tuvalu\" ],\n\t[ \"1852\", \"Carissa\", \"Byrd\", \"80861\", \"Palau\" ],\n\t[ \"1853\", \"Coby\", \"Barrett\", \"04665\", \"Congo\" ],\n\t[ \"1854\", \"Bertha\", \"Paul\", \"46442\", \"Andorra\" ],\n\t[ \"1855\", \"Hayden\", \"Dennis\", \"K7E 3O1\", \"France\" ],\n\t[ \"1856\", \"Kadeem\", \"Berry\", \"39544\", \"Vanuatu\" ],\n\t[ \"1857\", \"Clayton\", \"Burns\", \"C2A 6W5\", \"Andorra\" ],\n\t[ \"1858\", \"Breanna\", \"Hardy\", \"12284\", \"Norway\" ],\n\t[ \"1859\", \"Yael\", \"Hester\", \"69399\", \"Hong Kong\" ],\n\t[ \"1860\", \"Hunter\", \"Harding\", \"M4O 6N5\", \"Bosnia and Herzegovina\" ],\n\t[ \"1861\", \"Breanna\", \"Sutton\", \"N2C 6K3\", \"Singapore\" ],\n\t[ \"1862\", \"Bo\", \"Huffman\", \"54558\", \"Taiwan, Province of China\" ],\n\t[ \"1863\", \"Zena\", \"Potts\", \"80326\", \"Czech Republic\" ],\n\t[ \"1864\", \"Lucian\", \"Sykes\", \"D4M 6M5\", \"Trinidad and Tobago\" ],\n\t[ \"1865\", \"Gabriel\", \"Shepherd\", \"77631\", \"Bahrain\" ],\n\t[ \"1866\", \"Vivian\", \"Gould\", \"29510\", \"Norway\" ],\n\t[ \"1867\", \"Ina\", \"Sherman\", \"08122\", \"Portugal\" ],\n\t[ \"1868\", \"Constance\", \"Parsons\", \"D6E 9J8\", \"Armenia\" ],\n\t[ \"1869\", \"Tallulah\", \"Woodard\", \"51380\", \"Bahamas\" ],\n\t[ \"1870\", \"Amos\", \"Morris\", \"37846\", \"Switzerland\" ],\n\t[ \"1871\", \"Charles\", \"Kinney\", \"45961\", \"Marshall Islands\" ],\n\t[ \"1872\", \"Colby\", \"Camacho\", \"02978\", \"Niger\" ],\n\t[ \"1873\", \"Ora\", \"Hays\", \"B6F 9Z9\", \"Martinique\" ],\n\t[ \"1874\", \"Ariel\", \"Cannon\", \"04559\", \"Burundi\" ],\n\t[ \"1875\", \"Beatrice\", \"Hull\", \"66569\", \"Saint Pierre and Miquelon\" ],\n\t[ \"1876\", \"Stacey\", \"Morrow\", \"53760\", \"Zimbabwe\" ],\n\t[ \"1877\", \"Naida\", \"Thomas\", \"43434\", \"Virgin Islands, U.S.\" ],\n\t[ \"1878\", \"Holly\", \"Holcomb\", \"31997\", \"Kazakhstan\" ],\n\t[ \"1879\", \"Lee\", \"Davenport\", \"99355\", \"Central African Republic\" ],\n\t[ \"1880\", \"Gary\", \"Higgins\", \"18703\", \"Norway\" ],\n\t[ \"1881\", \"Kay\", \"Wolf\", \"25509\", \"Switzerland\" ],\n\t[ \"1882\", \"Destiny\", \"Patel\", \"Q3X 2F8\", \"Ghana\" ],\n\t[ \"1883\", \"Clayton\", \"Middleton\", \"Y5C 1I8\", \"Antigua and Barbuda\" ],\n\t[ \"1884\", \"May\", \"Rivers\", \"26782\", \"Uzbekistan\" ],\n\t[ \"1885\", \"Hadassah\", \"Caldwell\", \"64493\", \"Chile\" ],\n\t[ \"1886\", \"Penelope\", \"Gentry\", \"V5N 7A6\", \"Kyrgyzstan\" ],\n\t[ \"1887\", \"James\", \"Boyle\", \"95421\", \"Indonesia\" ],\n\t[ \"1888\", \"Yuli\", \"Cardenas\", \"W4U 5U1\", \"Solomon Islands\" ],\n\t[ \"1889\", \"George\", \"Simpson\", \"30385\", \"Brazil\" ],\n\t[ \"1890\", \"Thaddeus\", \"Ferrell\", \"E6Z 2D4\", \"Norfolk Island\" ],\n\t[ \"1891\", \"Piper\", \"Morrow\", \"S6I 1L8\", \"Estonia\" ],\n\t[ \"1892\", \"Xaviera\", \"Heath\", \"L8I 5G1\", \"Afghanistan\" ],\n\t[ \"1893\", \"Odette\", \"Patton\", \"L2S 4I8\", \"Bosnia and Herzegovina\" ],\n\t[ \"1894\", \"Stewart\", \"Phillips\", \"E8E 5W6\", \"El Salvador\" ],\n\t[ \"1895\", \"Kellie\", \"Cooper\", \"77401\", \"Cape Verde\" ],\n\t[ \"1896\", \"Kathleen\", \"Salinas\", \"F3O 4Z9\", \"Sierra Leone\" ],\n\t[ \"1897\", \"Fallon\", \"Bennett\", \"X3P 7L1\", \"Macedonia\" ],\n\t[ \"1898\", \"Jesse\", \"Guerrero\", \"I2B 1Q0\", \"Finland\" ],\n\t[ \"1899\", \"Zenaida\", \"Mcguire\", \"M5R 1X6\", \"Kenya\" ],\n\t[ \"1900\", \"Carolyn\", \"Richards\", \"03060\", \"Paraguay\" ],\n\t[ \"1901\", \"Ulla\", \"Bruce\", \"20940\", \"Cambodia\" ],\n\t[ \"1902\", \"Adrian\", \"Shaffer\", \"M5O 9Y2\", \"Thailand\" ],\n\t[ \"1903\", \"Callum\", \"Russo\", \"L3U 5S8\", \"Holy See (Vatican City State)\" ],\n\t[ \"1904\", \"Echo\", \"Mathews\", \"49158\", \"Spain\" ],\n\t[ \"1905\", \"Driscoll\", \"Buckner\", \"70115\", \"Solomon Islands\" ],\n\t[ \"1906\", \"Nayda\", \"Phillips\", \"Y7D 4A9\", \"Singapore\" ],\n\t[ \"1907\", \"Piper\", \"Livingston\", \"51701\", \"Anguilla\" ],\n\t[ \"1908\", \"Zoe\", \"Hoover\", \"C8D 8W2\", \"Iraq\" ],\n\t[ \"1909\", \"Veronica\", \"Montoya\", \"G6B 9S4\", \"Egypt\" ],\n\t[ \"1910\", \"Kato\", \"Richmond\", \"41268\", \"Saint Helena\" ],\n\t[ \"1911\", \"Kevyn\", \"Lancaster\", \"71863\", \"Montserrat\" ],\n\t[ \"1912\", \"Rowan\", \"Carr\", \"90825\", \"Ethiopia\" ],\n\t[ \"1913\", \"Alec\", \"Wells\", \"C9P 8I7\", \"Netherlands\" ],\n\t[ \"1914\", \"Graham\", \"Shields\", \"S4B 5O9\", \"Norfolk Island\" ],\n\t[ \"1915\", \"Pearl\", \"Austin\", \"43642\", \"Bermuda\" ],\n\t[ \"1916\", \"Dana\", \"Pugh\", \"H4C 2A9\", \"Tuvalu\" ],\n\t[ \"1917\", \"Lucy\", \"Ellis\", \"31272\", \"Cameroon\" ],\n\t[ \"1918\", \"Logan\", \"Wright\", \"18651\", \"Honduras\" ],\n\t[ \"1919\", \"Chantale\", \"Velasquez\", \"A5D 3X2\", \"Burundi\" ],\n\t[ \"1920\", \"Linda\", \"Ingram\", \"R1P 1G8\", \"Myanmar\" ],\n\t[ \"1921\", \"Ginger\", \"Howell\", \"Q5D 4E6\", \"Pakistan\" ],\n\t[ \"1922\", \"Unity\", \"Lester\", \"P7M 7A4\", \"Gibraltar\" ],\n\t[ \"1923\", \"Brett\", \"Rutledge\", \"Q1E 2B4\", \"Thailand\" ],\n\t[ \"1924\", \"Stewart\", \"Morrow\", \"84299\", \"Mali\" ],\n\t[ \"1925\", \"Declan\", \"Aguilar\", \"35400\", \"Kenya\" ],\n\t[ \"1926\", \"Shad\", \"Simpson\", \"N8E 2U3\", \"Saint Pierre and Miquelon\" ],\n\t[ \"1927\", \"Alma\", \"Benton\", \"Q6C 5D2\", \"Pakistan\" ],\n\t[ \"1928\", \"Herman\", \"Bailey\", \"P5K 2X4\", \"Ireland\" ],\n\t[ \"1929\", \"Keegan\", \"Mendez\", \"19421\", \"Lesotho\" ],\n\t[ \"1930\", \"Erasmus\", \"Foreman\", \"J9T 1A2\", \"Panama\" ],\n\t[ \"1931\", \"Tarik\", \"Meyers\", \"Z8V 5F9\", \"Cape Verde\" ],\n\t[ \"1932\", \"Donovan\", \"Knox\", \"B8N 1G7\", \"Iceland\" ],\n\t[ \"1933\", \"Chloe\", \"Mccray\", \"67537\", \"United Arab Emirates\" ],\n\t[ \"1934\", \"Marvin\", \"Edwards\", \"21809\", \"Ukraine\" ],\n\t[ \"1935\", \"Freya\", \"Watkins\", \"80099\", \"Central African Republic\" ],\n\t[ \"1936\", \"Jerry\", \"Morgan\", \"C7U 7H5\", \"Guinea\" ],\n\t[ \"1937\", \"Yardley\", \"Marsh\", \"23654\", \"India\" ],\n\t[ \"1938\", \"Ava\", \"Mueller\", \"83374\", \"Greece\" ],\n\t[ \"1939\", \"Silas\", \"Joseph\", \"P5M 7F2\", \"Sweden\" ],\n\t[ \"1940\", \"Winifred\", \"Solis\", \"12335\", \"Viet Nam\" ],\n\t[ \"1941\", \"Virginia\", \"Cantu\", \"K4C 3S5\", \"Yemen\" ],\n\t[ \"1942\", \"Sade\", \"Cole\", \"40295\", \"Spain\" ],\n\t[ \"1943\", \"Ethan\", \"Hodges\", \"R7W 8X2\", \"Congo\" ],\n\t[ \"1944\", \"Barbara\", \"Day\", \"K6L 7S6\", \"Nigeria\" ],\n\t[ \"1945\", \"Conan\", \"Simon\", \"22124\", \"Guyana\" ],\n\t[ \"1946\", \"Lars\", \"Puckett\", \"R6Y 4N7\", \"Trinidad and Tobago\" ],\n\t[ \"1947\", \"Quin\", \"Ewing\", \"99053\", \"American Samoa\" ],\n\t[ \"1948\", \"Ali\", \"Haynes\", \"N6Z 7X0\", \"China\" ],\n\t[ \"1949\", \"Sara\", \"Wagner\", \"74544\", \"Chad\" ],\n\t[ \"1950\", \"Griffith\", \"Fuentes\", \"R1W 6Z9\", \"Slovenia\" ],\n\t[ \"1951\", \"Sharon\", \"Crane\", \"I2Z 9D6\", \"Philippines\" ],\n\t[ \"1952\", \"Marsden\", \"Acosta\", \"K6C 8C5\", \"Jordan\" ],\n\t[ \"1953\", \"Whoopi\", \"Villarreal\", \"E2O 1T5\", \"Svalbard and Jan Mayen\" ],\n\t[ \"1954\", \"Bruno\", \"Ball\", \"31931\", \"Barbados\" ],\n\t[ \"1955\", \"Ulric\", \"Young\", \"T4R 3M5\", \"Solomon Islands\" ],\n\t[ \"1956\", \"Noah\", \"Gonzalez\", \"L3O 6V5\", \"Mayotte\" ],\n\t[ \"1957\", \"Cheryl\", \"Gilliam\", \"F4Q 4H9\", \"Albania\" ],\n\t[ \"1958\", \"Bo\", \"Rowe\", \"67020\", \"Jamaica\" ],\n\t[ \"1959\", \"Kelly\", \"Alexander\", \"P8Y 9K5\", \"Somalia\" ],\n\t[ \"1960\", \"Hop\", \"Navarro\", \"O1G 9R6\", \"Cayman Islands\" ],\n\t[ \"1961\", \"Zachery\", \"Howard\", \"67147\", \"Fiji\" ],\n\t[ \"1962\", \"Elvis\", \"Daugherty\", \"X8V 7S7\", \"Jordan\" ],\n\t[ \"1963\", \"Mallory\", \"Hensley\", \"A5S 1U6\", \"Swaziland\" ],\n\t[ \"1964\", \"Fulton\", \"Williams\", \"P4C 4O5\", \"Viet Nam\" ],\n\t[ \"1965\", \"Madison\", \"Pittman\", \"F8G 1P9\", \"Chile\" ],\n\t[ \"1966\", \"Kermit\", \"Bradford\", \"W2T 6I5\", \"Uganda\" ],\n\t[ \"1967\", \"Gabriel\", \"Ballard\", \"N5M 6W0\", \"Andorra\" ],\n\t[ \"1968\", \"Jasmine\", \"Barber\", \"M2Z 7G5\", \"French Guiana\" ],\n\t[ \"1969\", \"Thane\", \"Koch\", \"21097\", \"Armenia\" ],\n\t[ \"1970\", \"Montana\", \"Oneal\", \"L2A 9Q6\", \"South Africa\" ],\n\t[ \"1971\", \"Brett\", \"Coleman\", \"79399\", \"Luxembourg\" ],\n\t[ \"1972\", \"Ivy\", \"Jimenez\", \"28549\", \"Senegal\" ],\n\t[ \"1973\", \"Shad\", \"Melton\", \"Z8N 4Z5\", \"Cook Islands\" ],\n\t[ \"1974\", \"Suki\", \"Vance\", \"H1A 1Z3\", \"Ireland\" ],\n\t[ \"1975\", \"Jin\", \"Hodges\", \"L2I 3T8\", \"France\" ],\n\t[ \"1976\", \"Diana\", \"Booth\", \"M3V 1S8\", \"Iran, Islamic Republic of\" ],\n\t[ \"1977\", \"Martha\", \"Nunez\", \"27837\", \"Northern Mariana Islands\" ],\n\t[ \"1978\", \"Silas\", \"Ayers\", \"17121\", \"United States\" ],\n\t[ \"1979\", \"Ainsley\", \"Whitaker\", \"42695\", \"Dominica\" ],\n\t[ \"1980\", \"Dillon\", \"Tucker\", \"N3R 3P3\", \"Botswana\" ],\n\t[ \"1981\", \"Lillian\", \"West\", \"57665\", \"Palau\" ],\n\t[ \"1982\", \"Talon\", \"Hart\", \"Z6T 4W3\", \"Serbia and Montenegro\" ],\n\t[ \"1983\", \"Desiree\", \"Booth\", \"Q1W 9S1\", \"Gambia\" ],\n\t[ \"1984\", \"Chastity\", \"Merrill\", \"F3B 9W7\", \"Puerto Rico\" ],\n\t[ \"1985\", \"Nichole\", \"Leon\", \"T7V 5D6\", \"Belize\" ],\n\t[ \"1986\", \"Rafael\", \"Washington\", \"87676\", \"Eritrea\" ],\n\t[ \"1987\", \"Samson\", \"Mathews\", \"G7Q 5V6\", \"Burkina Faso\" ],\n\t[ \"1988\", \"Jasper\", \"Campbell\", \"23791\", \"Thailand\" ],\n\t[ \"1989\", \"Mason\", \"Harrington\", \"R9R 5S3\", \"Nigeria\" ],\n\t[ \"1990\", \"Jameson\", \"Frederick\", \"R1N 4S0\", \"Guyana\" ],\n\t[ \"1991\", \"Cadman\", \"Woodard\", \"43080\", \"Gambia\" ],\n\t[ \"1992\", \"Catherine\", \"Gill\", \"W4W 8A4\", \"Philippines\" ],\n\t[ \"1993\", \"Yael\", \"Richards\", \"99504\", \"Kenya\" ],\n\t[ \"1994\", \"Porter\", \"Finley\", \"C8Z 5E0\", \"Brunei Darussalam\" ],\n\t[ \"1995\", \"Alden\", \"Merritt\", \"P4E 9F0\", \"Mali\" ],\n\t[ \"1996\", \"Kaye\", \"Andrews\", \"I5I 3A4\", \"Cayman Islands\" ],\n\t[ \"1997\", \"Luke\", \"Bryant\", \"F3Z 2U1\", \"Kuwait\" ],\n\t[ \"1998\", \"Heather\", \"Blackburn\", \"L1T 6B9\", \"Mongolia\" ],\n\t[ \"1999\", \"Gage\", \"Sykes\", \"L9Q 7E6\", \"Palestinian Territory, Occupied\" ],\n\t[ \"2000\", \"Kaseem\", \"Harris\", \"B9O 1C3\", \"Korea\" ],\n\t[ \"2001\", \"Quail\", \"Leonard\", \"88755\", \"Burkina Faso\" ],\n\t[ \"2002\", \"Dennis\", \"Craft\", \"13309\", \"Namibia\" ],\n\t[ \"2003\", \"Ivor\", \"Forbes\", \"C3P 2E1\", \"Malta\" ],\n\t[ \"2004\", \"Cade\", \"Herman\", \"R1E 5X9\", \"Sri Lanka\" ],\n\t[ \"2005\", \"Larissa\", \"Santiago\", \"57781\", \"Dominica\" ],\n\t[ \"2006\", \"Hyatt\", \"Tillman\", \"45071\", \"Ghana\" ],\n\t[ \"2007\", \"Timothy\", \"Rodgers\", \"F8W 9W0\", \"Andorra\" ],\n\t[ \"2008\", \"Hanae\", \"Powell\", \"F8B 7P7\", \"Luxembourg\" ],\n\t[ \"2009\", \"Ima\", \"Pennington\", \"Z5W 5N5\", \"Latvia\" ],\n\t[ \"2010\", \"Laurel\", \"Bell\", \"16805\", \"Venezuela\" ],\n\t[ \"2011\", \"Avye\", \"Long\", \"04794\", \"Dominica\" ],\n\t[ \"2012\", \"Lysandra\", \"Pierce\", \"H7O 3F4\", \"Zimbabwe\" ],\n\t[ \"2013\", \"Eve\", \"Pollard\", \"L5K 6E2\", \"Algeria\" ],\n\t[ \"2014\", \"Ina\", \"Mcdowell\", \"65712\", \"Saint Lucia\" ],\n\t[ \"2015\", \"Meredith\", \"Serrano\", \"V8M 6K7\", \"Libyan Arab Jamahiriya\" ],\n\t[ \"2016\", \"Daphne\", \"Irwin\", \"89933\", \"Mongolia\" ],\n\t[ \"2017\", \"Adam\", \"Henson\", \"F6U 9D5\", \"Chile\" ],\n\t[ \"2018\", \"Amery\", \"Hoover\", \"13408\", \"Mongolia\" ],\n\t[ \"2019\", \"Quamar\", \"Hendricks\", \"20310\", \"Gambia\" ],\n\t[ \"2020\", \"Ori\", \"Wheeler\", \"89005\", \"Nigeria\" ],\n\t[ \"2021\", \"Zena\", \"Douglas\", \"Z1O 6F9\", \"Serbia and Montenegro\" ],\n\t[ \"2022\", \"Buckminster\", \"Huffman\", \"R4V 9L2\", \"Mali\" ],\n\t[ \"2023\", \"Harlan\", \"Gamble\", \"U4I 7M4\", \"Guyana\" ],\n\t[ \"2024\", \"Dalton\", \"Cline\", \"63829\", \"Tonga\" ],\n\t[ \"2025\", \"Martha\", \"Weber\", \"Z9B 4T0\", \"Bangladesh\" ],\n\t[ \"2026\", \"Vernon\", \"Francis\", \"M5A 9X7\", \"Tokelau\" ],\n\t[ \"2027\", \"Janna\", \"Velazquez\", \"67406\", \"Qatar\" ],\n\t[ \"2028\", \"Fuller\", \"Keller\", \"80871\", \"Burkina Faso\" ],\n\t[ \"2029\", \"Jamal\", \"Spears\", \"42197\", \"Norfolk Island\" ],\n\t[ \"2030\", \"Christen\", \"Holcomb\", \"29806\", \"Norway\" ],\n\t[ \"2031\", \"Mary\", \"Carter\", \"C6W 9K9\", \"Belgium\" ],\n\t[ \"2032\", \"Colorado\", \"Austin\", \"62904\", \"Cook Islands\" ],\n\t[ \"2033\", \"Fritz\", \"Hunt\", \"X8G 2V0\", \"Morocco\" ],\n\t[ \"2034\", \"Isabella\", \"Bush\", \"17676\", \"Monaco\" ],\n\t[ \"2035\", \"Adam\", \"Gilliam\", \"H7K 9X3\", \"Indonesia\" ],\n\t[ \"2036\", \"John\", \"Austin\", \"O7X 4Z0\", \"Czech Republic\" ],\n\t[ \"2037\", \"Cassady\", \"Yates\", \"68835\", \"Christmas Island\" ],\n\t[ \"2038\", \"Ori\", \"Cantrell\", \"56920\", \"Guinea\" ],\n\t[ \"2039\", \"May\", \"Horn\", \"47805\", \"Kuwait\" ],\n\t[ \"2040\", \"Skyler\", \"Clarke\", \"64131\", \"Lebanon\" ],\n\t[ \"2041\", \"Levi\", \"Foster\", \"S5Q 4B2\", \"Germany\" ],\n\t[ \"2042\", \"Veda\", \"Wilkinson\", \"L7Z 9M8\", \"Niger\" ],\n\t[ \"2043\", \"Brendan\", \"Levine\", \"L5B 9P4\", \"Nepal\" ],\n\t[ \"2044\", \"Carson\", \"Sullivan\", \"93066\", \"United Arab Emirates\" ],\n\t[ \"2045\", \"Steven\", \"Spencer\", \"F1V 9A7\", \"Pitcairn\" ],\n\t[ \"2046\", \"Halla\", \"Michael\", \"N1U 1E7\", \"Seychelles\" ],\n\t[ \"2047\", \"Jamal\", \"Hobbs\", \"G3D 6J7\", \"New Caledonia\" ],\n\t[ \"2048\", \"Steel\", \"Bush\", \"U8F 6T2\", \"Belize\" ],\n\t[ \"2049\", \"Ahmed\", \"Dennis\", \"M6E 3P3\", \"Afghanistan\" ],\n\t[ \"2050\", \"Aspen\", \"Estes\", \"32157\", \"American Samoa\" ],\n\t[ \"2051\", \"Peter\", \"Kelly\", \"91773\", \"Morocco\" ],\n\t[ \"2052\", \"Xandra\", \"Grimes\", \"66702\", \"Tokelau\" ],\n\t[ \"2053\", \"Michael\", \"Battle\", \"J2J 2N5\", \"Honduras\" ],\n\t[ \"2054\", \"Steel\", \"Wiggins\", \"34625\", \"United States Minor Outlying Islands\" ],\n\t[ \"2055\", \"Holmes\", \"Christian\", \"45402\", \"Liechtenstein\" ],\n\t[ \"2056\", \"Charles\", \"Barrett\", \"O4N 9N8\", \"Lebanon\" ],\n\t[ \"2057\", \"Hermione\", \"Soto\", \"C8E 4H8\", \"Congo\" ],\n\t[ \"2058\", \"Elton\", \"Maxwell\", \"89033\", \"Madagascar\" ],\n\t[ \"2059\", \"Zelda\", \"Burks\", \"B7W 5G7\", \"Sweden\" ],\n\t[ \"2060\", \"Lynn\", \"David\", \"P3D 5K5\", \"Chad\" ],\n\t[ \"2061\", \"Margaret\", \"Neal\", \"47438\", \"Western Sahara\" ],\n\t[ \"2062\", \"David\", \"Vaughan\", \"E3L 8D9\", \"Tokelau\" ],\n\t[ \"2063\", \"Vladimir\", \"Mcfarland\", \"U9V 1B3\", \"Belgium\" ],\n\t[ \"2064\", \"Uriah\", \"Harrington\", \"77051\", \"United Arab Emirates\" ],\n\t[ \"2065\", \"Noel\", \"Merritt\", \"J3G 7S1\", \"Dominican Republic\" ],\n\t[ \"2066\", \"Christine\", \"Key\", \"54543\", \"Niger\" ],\n\t[ \"2067\", \"Illana\", \"Hendricks\", \"07584\", \"Montserrat\" ],\n\t[ \"2068\", \"Pearl\", \"Lewis\", \"U5D 2V3\", \"Libyan Arab Jamahiriya\" ],\n\t[ \"2069\", \"Victoria\", \"Bullock\", \"17462\", \"Mauritania\" ],\n\t[ \"2070\", \"Benedict\", \"Marsh\", \"61479\", \"Guyana\" ],\n\t[ \"2071\", \"Quemby\", \"Washington\", \"99774\", \"French Polynesia\" ],\n\t[ \"2072\", \"Shelley\", \"Noble\", \"U8S 5Z4\", \"Philippines\" ],\n\t[ \"2073\", \"Olivia\", \"Britt\", \"72344\", \"Holy See (Vatican City State)\" ],\n\t[ \"2074\", \"Oleg\", \"Hendrix\", \"67567\", \"Cuba\" ],\n\t[ \"2075\", \"Hermione\", \"Gutierrez\", \"J5K 2J1\", \"Mozambique\" ],\n\t[ \"2076\", \"Myra\", \"Dean\", \"03485\", \"Andorra\" ],\n\t[ \"2077\", \"Deacon\", \"Moore\", \"34501\", \"Tunisia\" ],\n\t[ \"2078\", \"Dai\", \"Baird\", \"B2P 4R0\", \"Cambodia\" ],\n\t[ \"2079\", \"Levi\", \"Melton\", \"K7T 4B1\", \"Zimbabwe\" ],\n\t[ \"2080\", \"Ocean\", \"Dalton\", \"66801\", \"Gabon\" ],\n\t[ \"2081\", \"Selma\", \"Harding\", \"D7N 3J9\", \"Kyrgyzstan\" ],\n\t[ \"2082\", \"Maisie\", \"Gill\", \"56324\", \"Morocco\" ],\n\t[ \"2083\", \"Hillary\", \"Horne\", \"Y6O 6G3\", \"Cyprus\" ],\n\t[ \"2084\", \"Joel\", \"Stokes\", \"77952\", \"Burundi\" ],\n\t[ \"2085\", \"Channing\", \"Patterson\", \"G6B 8H4\", \"China\" ],\n\t[ \"2086\", \"Elliott\", \"Cleveland\", \"H3J 9U9\", \"Namibia\" ],\n\t[ \"2087\", \"Petra\", \"Gay\", \"44314\", \"Palestinian Territory, Occupied\" ],\n\t[ \"2088\", \"May\", \"Hatfield\", \"48918\", \"Faroe Islands\" ],\n\t[ \"2089\", \"Jemima\", \"Francis\", \"14347\", \"Libyan Arab Jamahiriya\" ],\n\t[ \"2090\", \"Kyla\", \"Hale\", \"46200\", \"Cocos (Keeling) Islands\" ],\n\t[ \"2091\", \"Veda\", \"Bruce\", \"F5W 9A6\", \"Mauritania\" ],\n\t[ \"2092\", \"Sybill\", \"Avila\", \"58663\", \"Angola\" ],\n\t[ \"2093\", \"Charissa\", \"Salazar\", \"35271\", \"Faroe Islands\" ],\n\t[ \"2094\", \"Steven\", \"Allison\", \"E5L 4A3\", \"Wallis and Futuna\" ],\n\t[ \"2095\", \"Kane\", \"Parks\", \"D5C 6K7\", \"Norfolk Island\" ],\n\t[ \"2096\", \"Alika\", \"Bishop\", \"S3P 3O3\", \"China\" ],\n\t[ \"2097\", \"James\", \"Bonner\", \"33277\", \"Canada\" ],\n\t[ \"2098\", \"Yoko\", \"Foster\", \"B5J 6P9\", \"Croatia\" ],\n\t[ \"2099\", \"Ivy\", \"Riggs\", \"94420\", \"Kiribati\" ],\n\t[ \"2100\", \"Urielle\", \"Rosa\", \"V6W 2A0\", \"Falkland Islands (Malvinas)\" ],\n\t[ \"2101\", \"Armando\", \"Shepherd\", \"Y5C 5W6\", \"Panama\" ],\n\t[ \"2102\", \"Haley\", \"Ingram\", \"B4H 5U5\", \"Fiji\" ],\n\t[ \"2103\", \"Brielle\", \"Dyer\", \"P2S 4H7\", \"Malawi\" ],\n\t[ \"2104\", \"Francis\", \"Brady\", \"24239\", \"Uruguay\" ],\n\t[ \"2105\", \"Fiona\", \"Webster\", \"72015\", \"Belize\" ],\n\t[ \"2106\", \"Aiko\", \"Santos\", \"K4H 1N0\", \"Saint Vincent and The Grenadines\" ],\n\t[ \"2107\", \"Amir\", \"Rivas\", \"02737\", \"Papua New Guinea\" ],\n\t[ \"2108\", \"Mira\", \"Kerr\", \"W6E 6Y2\", \"Sri Lanka\" ],\n\t[ \"2109\", \"Harrison\", \"Jensen\", \"50193\", \"Heard Island and Mcdonald Islands\" ],\n\t[ \"2110\", \"Merrill\", \"Randall\", \"21534\", \"Colombia\" ],\n\t[ \"2111\", \"Benjamin\", \"Howe\", \"N8M 4N6\", \"Turkmenistan\" ],\n\t[ \"2112\", \"Melyssa\", \"Kidd\", \"97657\", \"Cameroon\" ],\n\t[ \"2113\", \"Henry\", \"Moore\", \"95626\", \"Botswana\" ],\n\t[ \"2114\", \"Nash\", \"Peters\", \"K3V 9F3\", \"Wallis and Futuna\" ],\n\t[ \"2115\", \"Iliana\", \"Holt\", \"E9F 2Q8\", \"Netherlands Antilles\" ],\n\t[ \"2116\", \"Naomi\", \"Hood\", \"P6D 2G3\", \"Anguilla\" ],\n\t[ \"2117\", \"Ainsley\", \"Barron\", \"94273\", \"New Caledonia\" ],\n\t[ \"2118\", \"Daphne\", \"Acevedo\", \"A9I 9E4\", \"Bermuda\" ],\n\t[ \"2119\", \"Kiona\", \"Keith\", \"62523\", \"Saint Lucia\" ],\n\t[ \"2120\", \"Kirsten\", \"Mcgee\", \"97481\", \"Macedonia\" ],\n\t[ \"2121\", \"Emerald\", \"Franklin\", \"Q2I 6D6\", \"Botswana\" ],\n\t[ \"2122\", \"Hall\", \"Schroeder\", \"I2D 9L7\", \"Kenya\" ],\n\t[ \"2123\", \"Amaya\", \"Lynch\", \"50534\", \"Costa Rica\" ],\n\t[ \"2124\", \"Randall\", \"Hanson\", \"B4R 2S3\", \"United Arab Emirates\" ],\n\t[ \"2125\", \"Sasha\", \"Clarke\", \"50972\", \"United States Minor Outlying Islands\" ],\n\t[ \"2126\", \"Susan\", \"Sutton\", \"Z4T 6K3\", \"Solomon Islands\" ],\n\t[ \"2127\", \"Hiram\", \"Torres\", \"C8O 5O7\", \"Botswana\" ],\n\t[ \"2128\", \"Melanie\", \"Calhoun\", \"87097\", \"New Zealand\" ],\n\t[ \"2129\", \"Courtney\", \"Sutton\", \"07944\", \"Spain\" ],\n\t[ \"2130\", \"Reuben\", \"Beard\", \"U6Z 8N5\", \"Faroe Islands\" ],\n\t[ \"2131\", \"Jarrod\", \"Payne\", \"94171\", \"Turkey\" ],\n\t[ \"2132\", \"Vincent\", \"Potts\", \"V5Z 9G9\", \"Madagascar\" ],\n\t[ \"2133\", \"Kaye\", \"Kent\", \"O1B 2Z9\", \"Fiji\" ],\n\t[ \"2134\", \"Carol\", \"Green\", \"78719\", \"Comoros\" ],\n\t[ \"2135\", \"Cairo\", \"Combs\", \"G3C 8F0\", \"Indonesia\" ],\n\t[ \"2136\", \"Ebony\", \"Parker\", \"77377\", \"Portugal\" ],\n\t[ \"2137\", \"Gary\", \"Shaffer\", \"F1B 9W7\", \"French Guiana\" ],\n\t[ \"2138\", \"Gay\", \"Jimenez\", \"05726\", \"Nepal\" ],\n\t[ \"2139\", \"Patience\", \"Bryan\", \"60437\", \"Macao\" ],\n\t[ \"2140\", \"Zenaida\", \"Bowen\", \"V3S 1G7\", \"Mauritania\" ],\n\t[ \"2141\", \"Isaac\", \"Aguirre\", \"X8S 9K4\", \"Bermuda\" ],\n\t[ \"2142\", \"Lacy\", \"Harrell\", \"67362\", \"Bhutan\" ],\n\t[ \"2143\", \"Jael\", \"Grimes\", \"95612\", \"Anguilla\" ],\n\t[ \"2144\", \"Catherine\", \"Galloway\", \"45834\", \"Suriname\" ],\n\t[ \"2145\", \"Donna\", \"Burt\", \"N8C 2M8\", \"Burkina Faso\" ],\n\t[ \"2146\", \"Colleen\", \"Ball\", \"N3E 4U8\", \"Libyan Arab Jamahiriya\" ],\n\t[ \"2147\", \"Lael\", \"Brady\", \"01369\", \"Macedonia\" ],\n\t[ \"2148\", \"Kermit\", \"Logan\", \"Y5P 8Q8\", \"Honduras\" ],\n\t[ \"2149\", \"Katelyn\", \"Orr\", \"R7X 9W3\", \"Switzerland\" ],\n\t[ \"2150\", \"Alisa\", \"Glenn\", \"17831\", \"Timor-leste\" ],\n\t[ \"2151\", \"Lee\", \"Bean\", \"89445\", \"Guam\" ],\n\t[ \"2152\", \"Maryam\", \"Cotton\", \"57924\", \"Gambia\" ],\n\t[ \"2153\", \"Amena\", \"Love\", \"X1Z 6F7\", \"Thailand\" ],\n\t[ \"2154\", \"Tallulah\", \"Case\", \"87477\", \"Ecuador\" ],\n\t[ \"2155\", \"Carlos\", \"Sanford\", \"F6S 8J6\", \"Iraq\" ],\n\t[ \"2156\", \"Quamar\", \"David\", \"D5F 2M8\", \"Gabon\" ],\n\t[ \"2157\", \"Cassady\", \"Mays\", \"12786\", \"Netherlands\" ],\n\t[ \"2158\", \"Jenna\", \"Rowland\", \"88845\", \"China\" ],\n\t[ \"2159\", \"Justin\", \"Tanner\", \"66071\", \"Nepal\" ],\n\t[ \"2160\", \"Riley\", \"Santiago\", \"F8K 2Y6\", \"Gabon\" ],\n\t[ \"2161\", \"Iris\", \"Gallegos\", \"K9C 3T9\", \"Niue\" ],\n\t[ \"2162\", \"Kato\", \"Osborn\", \"N4C 2L8\", \"Puerto Rico\" ],\n\t[ \"2163\", \"Imogene\", \"Schroeder\", \"79710\", \"United States Minor Outlying Islands\" ],\n\t[ \"2164\", \"Olympia\", \"Hebert\", \"D4W 1L0\", \"Saint Lucia\" ],\n\t[ \"2165\", \"Skyler\", \"Burnett\", \"B2R 5H7\", \"Antarctica\" ],\n\t[ \"2166\", \"Faith\", \"Sims\", \"88476\", \"Egypt\" ],\n\t[ \"2167\", \"Emily\", \"Odom\", \"U7O 2P6\", \"Kuwait\" ],\n\t[ \"2168\", \"Carly\", \"Washington\", \"46063\", \"Benin\" ],\n\t[ \"2169\", \"Jolene\", \"Meyer\", \"B2B 9A4\", \"Australia\" ],\n\t[ \"2170\", \"Ayanna\", \"Conrad\", \"84360\", \"Northern Mariana Islands\" ],\n\t[ \"2171\", \"Violet\", \"Blankenship\", \"W2B 3U1\", \"New Caledonia\" ],\n\t[ \"2172\", \"Rhona\", \"Gallegos\", \"10931\", \"Montserrat\" ],\n\t[ \"2173\", \"Alice\", \"Hodges\", \"96181\", \"Burkina Faso\" ],\n\t[ \"2174\", \"Brody\", \"Sandoval\", \"68959\", \"Pitcairn\" ],\n\t[ \"2175\", \"Isabella\", \"Dunlap\", \"U8U 7Y8\", \"Afghanistan\" ],\n\t[ \"2176\", \"Jordan\", \"Golden\", \"55152\", \"Guam\" ],\n\t[ \"2177\", \"Gillian\", \"Thomas\", \"75633\", \"Djibouti\" ],\n\t[ \"2178\", \"Hollee\", \"Clay\", \"79847\", \"Panama\" ],\n\t[ \"2179\", \"Dane\", \"Knapp\", \"89535\", \"Armenia\" ],\n\t[ \"2180\", \"Avram\", \"Martin\", \"T4S 4E2\", \"Madagascar\" ],\n\t[ \"2181\", \"Fuller\", \"Newman\", \"47317\", \"Jamaica\" ],\n\t[ \"2182\", \"Nina\", \"Berry\", \"81360\", \"Mongolia\" ],\n\t[ \"2183\", \"Akeem\", \"Pratt\", \"56230\", \"Colombia\" ],\n\t[ \"2184\", \"Lacy\", \"Hayes\", \"U7T 4F5\", \"Cyprus\" ],\n\t[ \"2185\", \"Alfonso\", \"Mcclure\", \"06797\", \"Swaziland\" ],\n\t[ \"2186\", \"Cedric\", \"Love\", \"64720\", \"Bermuda\" ],\n\t[ \"2187\", \"Astra\", \"Fernandez\", \"H3I 1B0\", \"Mongolia\" ],\n\t[ \"2188\", \"Iliana\", \"Durham\", \"R8C 7M8\", \"Spain\" ],\n\t[ \"2189\", \"Gwendolyn\", \"Livingston\", \"C7X 5L1\", \"Northern Mariana Islands\" ],\n\t[ \"2190\", \"Caldwell\", \"Anderson\", \"69099\", \"Kuwait\" ],\n\t[ \"2191\", \"Risa\", \"Mejia\", \"P7A 4U7\", \"Israel\" ],\n\t[ \"2192\", \"Dora\", \"Navarro\", \"L6G 2O8\", \"Ireland\" ],\n\t[ \"2193\", \"Kirk\", \"Dean\", \"I2T 3E6\", \"Pitcairn\" ],\n\t[ \"2194\", \"Jackson\", \"Harvey\", \"53467\", \"Myanmar\" ],\n\t[ \"2195\", \"Thane\", \"Ballard\", \"87240\", \"Solomon Islands\" ],\n\t[ \"2196\", \"Nadine\", \"Estes\", \"62003\", \"Malta\" ],\n\t[ \"2197\", \"Candace\", \"Nunez\", \"57223\", \"Virgin Islands, British\" ],\n\t[ \"2198\", \"Zelda\", \"Odom\", \"X4V 7F5\", \"Mongolia\" ],\n\t[ \"2199\", \"Wylie\", \"Ayala\", \"S4I 4Q4\", \"Djibouti\" ],\n\t[ \"2200\", \"Azalia\", \"Page\", \"57239\", \"Korea, Republic of\" ],\n\t[ \"2201\", \"Joshua\", \"Burch\", \"R7B 1N7\", \"Samoa\" ],\n\t[ \"2202\", \"Basil\", \"Ramos\", \"71614\", \"Tunisia\" ],\n\t[ \"2203\", \"Jessica\", \"Shields\", \"U2D 4X3\", \"Syrian Arab Republic\" ],\n\t[ \"2204\", \"Clio\", \"Singleton\", \"I1B 1B0\", \"Ghana\" ],\n\t[ \"2205\", \"Astra\", \"Dotson\", \"62378\", \"Turks and Caicos Islands\" ],\n\t[ \"2206\", \"Hamish\", \"Tucker\", \"E4Z 3N3\", \"Anguilla\" ],\n\t[ \"2207\", \"Rachel\", \"Matthews\", \"U4I 8M3\", \"Trinidad and Tobago\" ],\n\t[ \"2208\", \"Clayton\", \"Ball\", \"95319\", \"India\" ],\n\t[ \"2209\", \"Quinn\", \"Wilkinson\", \"Y6M 3Q7\", \"Virgin Islands, U.S.\" ],\n\t[ \"2210\", \"Phelan\", \"Talley\", \"00543\", \"Philippines\" ],\n\t[ \"2211\", \"Carol\", \"Brock\", \"M6X 4E2\", \"Gibraltar\" ],\n\t[ \"2212\", \"Nomlanga\", \"Robles\", \"56511\", \"Viet Nam\" ],\n\t[ \"2213\", \"Adrian\", \"Clay\", \"79479\", \"France\" ],\n\t[ \"2214\", \"Sara\", \"Riley\", \"B9N 5P4\", \"Peru\" ],\n\t[ \"2215\", \"Christine\", \"Sweeney\", \"W1Z 4S4\", \"French Polynesia\" ],\n\t[ \"2216\", \"Leilani\", \"Johnston\", \"W1C 8M8\", \"American Samoa\" ],\n\t[ \"2217\", \"Melyssa\", \"Lambert\", \"V1B 4P6\", \"Iraq\" ],\n\t[ \"2218\", \"Talon\", \"Delacruz\", \"Y3N 9R2\", \"Bulgaria\" ],\n\t[ \"2219\", \"Garth\", \"Jennings\", \"59667\", \"Malta\" ],\n\t[ \"2220\", \"Naida\", \"Coleman\", \"45456\", \"Finland\" ],\n\t[ \"2221\", \"Indigo\", \"Lopez\", \"77160\", \"Pitcairn\" ],\n\t[ \"2222\", \"Asher\", \"French\", \"99064\", \"British Indian Ocean Territory\" ],\n\t[ \"2223\", \"Vivian\", \"Mcgowan\", \"46310\", \"Oman\" ],\n\t[ \"2224\", \"Gwendolyn\", \"Cervantes\", \"48905\", \"Cocos (Keeling) Islands\" ],\n\t[ \"2225\", \"Logan\", \"Reid\", \"87376\", \"Ethiopia\" ],\n\t[ \"2226\", \"Bryar\", \"Wolfe\", \"75860\", \"Comoros\" ],\n\t[ \"2227\", \"Demetrius\", \"Hutchinson\", \"97252\", \"Dominican Republic\" ],\n\t[ \"2228\", \"Freya\", \"Becker\", \"04872\", \"United States\" ],\n\t[ \"2229\", \"Abel\", \"Brooks\", \"I7O 1M1\", \"Comoros\" ],\n\t[ \"2230\", \"Silas\", \"Mcguire\", \"04101\", \"Indonesia\" ],\n\t[ \"2231\", \"Quinn\", \"Fletcher\", \"B6E 2B0\", \"Niger\" ],\n\t[ \"2232\", \"Rooney\", \"Holden\", \"29294\", \"Micronesia\" ],\n\t[ \"2233\", \"Iris\", \"Hale\", \"N7W 6E9\", \"Greenland\" ],\n\t[ \"2234\", \"Candace\", \"Barry\", \"U8I 5A4\", \"Germany\" ],\n\t[ \"2235\", \"Yetta\", \"Ball\", \"62055\", \"Switzerland\" ],\n\t[ \"2236\", \"Dai\", \"Bentley\", \"P2Y 4C5\", \"Dominica\" ],\n\t[ \"2237\", \"Gannon\", \"Dunlap\", \"45728\", \"Fiji\" ],\n\t[ \"2238\", \"Chelsea\", \"Mays\", \"36498\", \"Guinea\" ],\n\t[ \"2239\", \"Ruth\", \"Mcguire\", \"62924\", \"Maldives\" ],\n\t[ \"2240\", \"Melissa\", \"Durham\", \"D6S 1A2\", \"Armenia\" ],\n\t[ \"2241\", \"Eaton\", \"Salinas\", \"53689\", \"Somalia\" ],\n\t[ \"2242\", \"Driscoll\", \"Cunningham\", \"31194\", \"Sweden\" ],\n\t[ \"2243\", \"Bevis\", \"Acosta\", \"V4M 9Z2\", \"Jamaica\" ],\n\t[ \"2244\", \"Anastasia\", \"Mcknight\", \"24878\", \"Sao Tome and Principe\" ],\n\t[ \"2245\", \"Anika\", \"Rowland\", \"45287\", \"Chile\" ],\n\t[ \"2246\", \"Dexter\", \"Rollins\", \"00684\", \"Iran, Islamic Republic of\" ],\n\t[ \"2247\", \"Brielle\", \"Irwin\", \"V4U 7R2\", \"Belgium\" ],\n\t[ \"2248\", \"Ocean\", \"Fields\", \"08544\", \"Croatia\" ],\n\t[ \"2249\", \"Sonia\", \"Solis\", \"C4X 1L5\", \"Niue\" ],\n\t[ \"2250\", \"Joseph\", \"Haney\", \"29567\", \"Argentina\" ],\n\t[ \"2251\", \"Lamar\", \"Heath\", \"81699\", \"Italy\" ],\n\t[ \"2252\", \"Raya\", \"Jordan\", \"R6K 7B3\", \"Spain\" ],\n\t[ \"2253\", \"Brody\", \"Frost\", \"34564\", \"Dominican Republic\" ],\n\t[ \"2254\", \"Ann\", \"Hawkins\", \"S3A 5K7\", \"Yemen\" ],\n\t[ \"2255\", \"Phillip\", \"Lindsay\", \"80544\", \"Sierra Leone\" ],\n\t[ \"2256\", \"Willa\", \"Maynard\", \"A6A 4C5\", \"Mexico\" ],\n\t[ \"2257\", \"Carolyn\", \"Mercer\", \"V8Z 1X5\", \"Zimbabwe\" ],\n\t[ \"2258\", \"Justin\", \"Cole\", \"68764\", \"Saint Vincent and The Grenadines\" ],\n\t[ \"2259\", \"Emmanuel\", \"Parks\", \"99769\", \"Latvia\" ],\n\t[ \"2260\", \"Isaiah\", \"Salazar\", \"H1K 1X3\", \"Turks and Caicos Islands\" ],\n\t[ \"2261\", \"Vance\", \"Porter\", \"49607\", \"Costa Rica\" ],\n\t[ \"2262\", \"Igor\", \"Kim\", \"99489\", \"Turkmenistan\" ],\n\t[ \"2263\", \"Emi\", \"Graves\", \"F4M 5L8\", \"El Salvador\" ],\n\t[ \"2264\", \"Griffith\", \"Monroe\", \"11550\", \"Tanzania, United Republic of\" ],\n\t[ \"2265\", \"Iliana\", \"Coffey\", \"30220\", \"Albania\" ],\n\t[ \"2266\", \"Jemima\", \"Guthrie\", \"69283\", \"Saint Pierre and Miquelon\" ],\n\t[ \"2267\", \"Zenia\", \"Farrell\", \"91872\", \"Tanzania, United Republic of\" ],\n\t[ \"2268\", \"Lucas\", \"Chambers\", \"L5Z 1W0\", \"Bouvet Island\" ],\n\t[ \"2269\", \"Zenaida\", \"Valenzuela\", \"31700\", \"Guam\" ],\n\t[ \"2270\", \"Bradley\", \"Wynn\", \"21222\", \"Lithuania\" ],\n\t[ \"2271\", \"Maite\", \"Richard\", \"H4D 7X0\", \"Cameroon\" ],\n\t[ \"2272\", \"Moses\", \"House\", \"Y3Z 3K7\", \"Saint Vincent and The Grenadines\" ],\n\t[ \"2273\", \"Erich\", \"Petersen\", \"U4N 9R7\", \"Rwanda\" ],\n\t[ \"2274\", \"Stephanie\", \"Zimmerman\", \"70097\", \"Malawi\" ],\n\t[ \"2275\", \"Rylee\", \"Schneider\", \"15645\", \"Gibraltar\" ],\n\t[ \"2276\", \"Zia\", \"Craig\", \"H1K 1N9\", \"Norway\" ],\n\t[ \"2277\", \"Fiona\", \"Chaney\", \"Y4U 7K8\", \"San Marino\" ],\n\t[ \"2278\", \"Gil\", \"Sherman\", \"64720\", \"Wallis and Futuna\" ],\n\t[ \"2279\", \"Raja\", \"Sandoval\", \"11225\", \"Lithuania\" ],\n\t[ \"2280\", \"Illana\", \"Wyatt\", \"A2M 9O2\", \"Brazil\" ],\n\t[ \"2281\", \"Declan\", \"Howell\", \"E9V 8J5\", \"San Marino\" ],\n\t[ \"2282\", \"Warren\", \"Cooper\", \"47160\", \"Guyana\" ],\n\t[ \"2283\", \"Alyssa\", \"Juarez\", \"S7G 8F2\", \"Sweden\" ],\n\t[ \"2284\", \"Quynn\", \"Long\", \"P1P 5Y4\", \"Mexico\" ],\n\t[ \"2285\", \"Dalton\", \"Booker\", \"I5T 1R3\", \"Mauritius\" ],\n\t[ \"2286\", \"Lunea\", \"Mclaughlin\", \"I3F 6D4\", \"Togo\" ],\n\t[ \"2287\", \"Irene\", \"Brock\", \"04760\", \"Tajikistan\" ],\n\t[ \"2288\", \"Raven\", \"Floyd\", \"R2N 2Y5\", \"Philippines\" ],\n\t[ \"2289\", \"Nichole\", \"Farmer\", \"81213\", \"Seychelles\" ],\n\t[ \"2290\", \"Sophia\", \"Mcdonald\", \"86291\", \"Chile\" ],\n\t[ \"2291\", \"Nehru\", \"Matthews\", \"60732\", \"Central African Republic\" ],\n\t[ \"2292\", \"Marah\", \"Nelson\", \"44533\", \"Kenya\" ],\n\t[ \"2293\", \"Marvin\", \"Lyons\", \"M7Y 1Q6\", \"Somalia\" ],\n\t[ \"2294\", \"Ian\", \"Fernandez\", \"D9U 8B6\", \"Turkey\" ],\n\t[ \"2295\", \"Gretchen\", \"Dotson\", \"48294\", \"China\" ],\n\t[ \"2296\", \"Brady\", \"Weaver\", \"S4U 4I8\", \"Burundi\" ],\n\t[ \"2297\", \"Ella\", \"Salas\", \"73771\", \"Sao Tome and Principe\" ],\n\t[ \"2298\", \"Martha\", \"Irwin\", \"06554\", \"Timor-leste\" ],\n\t[ \"2299\", \"Penelope\", \"Pratt\", \"S1R 4L4\", \"Gabon\" ],\n\t[ \"2300\", \"Kenyon\", \"Dale\", \"64548\", \"Zimbabwe\" ],\n\t[ \"2301\", \"Henry\", \"Myers\", \"07614\", \"United Arab Emirates\" ],\n\t[ \"2302\", \"Chaney\", \"Dunlap\", \"18388\", \"French Southern Territories\" ],\n\t[ \"2303\", \"Palmer\", \"Le\", \"10807\", \"Colombia\" ],\n\t[ \"2304\", \"Kaseem\", \"Madden\", \"U4E 6L9\", \"Guyana\" ],\n\t[ \"2305\", \"Grant\", \"Anthony\", \"F3K 4D8\", \"Trinidad and Tobago\" ],\n\t[ \"2306\", \"Denton\", \"Moore\", \"I5O 4I5\", \"Belize\" ],\n\t[ \"2307\", \"Regan\", \"Pittman\", \"U8T 9M1\", \"Romania\" ],\n\t[ \"2308\", \"Valentine\", \"Hunt\", \"E9O 6H6\", \"Poland\" ],\n\t[ \"2309\", \"Abraham\", \"Love\", \"X1T 4K0\", \"Philippines\" ],\n\t[ \"2310\", \"Maggie\", \"Gaines\", \"W5Z 6L4\", \"Chad\" ],\n\t[ \"2311\", \"Kylynn\", \"Sears\", \"53419\", \"Ghana\" ],\n\t[ \"2312\", \"Abel\", \"Hudson\", \"O6C 6K5\", \"Malaysia\" ],\n\t[ \"2313\", \"Aladdin\", \"Brady\", \"16465\", \"Antarctica\" ],\n\t[ \"2314\", \"Laurel\", \"Bush\", \"42295\", \"Kyrgyzstan\" ],\n\t[ \"2315\", \"Cameron\", \"Shepherd\", \"Y8R 5L7\", \"Finland\" ],\n\t[ \"2316\", \"Colin\", \"Barker\", \"H8Q 5L0\", \"Aruba\" ],\n\t[ \"2317\", \"Nichole\", \"Stephens\", \"B8P 3D5\", \"Qatar\" ],\n\t[ \"2318\", \"Mary\", \"Dorsey\", \"J7D 1E5\", \"Iceland\" ],\n\t[ \"2319\", \"Yetta\", \"Dillon\", \"I7X 9D3\", \"Hong Kong\" ],\n\t[ \"2320\", \"Hope\", \"May\", \"L5W 1T9\", \"Taiwan, Province of China\" ],\n\t[ \"2321\", \"Daphne\", \"Barr\", \"W2B 9G2\", \"Korea, Republic of\" ],\n\t[ \"2322\", \"Melissa\", \"Hartman\", \"17607\", \"Reunion\" ],\n\t[ \"2323\", \"Acton\", \"Merritt\", \"U7M 3Q5\", \"Cape Verde\" ],\n\t[ \"2324\", \"Alika\", \"Weeks\", \"45475\", \"Singapore\" ],\n\t[ \"2325\", \"Fitzgerald\", \"Rowe\", \"Z3Z 2B6\", \"Israel\" ],\n\t[ \"2326\", \"Frances\", \"Valentine\", \"54329\", \"Kyrgyzstan\" ],\n\t[ \"2327\", \"Hollee\", \"Poole\", \"56101\", \"Saint Kitts and Nevis\" ],\n\t[ \"2328\", \"Melissa\", \"Stafford\", \"R5C 7V0\", \"Philippines\" ],\n\t[ \"2329\", \"Patience\", \"Jones\", \"61516\", \"Mauritius\" ],\n\t[ \"2330\", \"Uta\", \"Sloan\", \"K1B 9R2\", \"Timor-leste\" ],\n\t[ \"2331\", \"Brent\", \"West\", \"69310\", \"Burundi\" ],\n\t[ \"2332\", \"Otto\", \"Olsen\", \"88849\", \"Monaco\" ],\n\t[ \"2333\", \"Blossom\", \"Soto\", \"E2Q 6E6\", \"Ukraine\" ],\n\t[ \"2334\", \"Anastasia\", \"Stanton\", \"S8D 3U5\", \"Mexico\" ],\n\t[ \"2335\", \"Nyssa\", \"Massey\", \"A4G 8G7\", \"Ireland\" ],\n\t[ \"2336\", \"Brian\", \"Moreno\", \"T6O 4D7\", \"Myanmar\" ],\n\t[ \"2337\", \"Fiona\", \"Price\", \"03826\", \"Benin\" ],\n\t[ \"2338\", \"Wyoming\", \"Knowles\", \"I5M 7T3\", \"Chad\" ],\n\t[ \"2339\", \"Iola\", \"Noble\", \"95251\", \"Tunisia\" ],\n\t[ \"2340\", \"Cameran\", \"Montgomery\", \"35748\", \"Korea\" ],\n\t[ \"2341\", \"Wesley\", \"Sims\", \"J6O 7C0\", \"Hungary\" ],\n\t[ \"2342\", \"Mona\", \"Gates\", \"J6Y 3E2\", \"Tokelau\" ],\n\t[ \"2343\", \"Dominique\", \"Sellers\", \"G6U 7I2\", \"Sudan\" ],\n\t[ \"2344\", \"Destiny\", \"Frazier\", \"Y2P 5X6\", \"Madagascar\" ],\n\t[ \"2345\", \"Kelsie\", \"Stokes\", \"78561\", \"Yemen\" ],\n\t[ \"2346\", \"Julie\", \"Jordan\", \"U5H 4H0\", \"Myanmar\" ],\n\t[ \"2347\", \"Xaviera\", \"Hodge\", \"36452\", \"Turkey\" ],\n\t[ \"2348\", \"Cain\", \"Boyd\", \"74543\", \"Lebanon\" ],\n\t[ \"2349\", \"Devin\", \"Burch\", \"94879\", \"Cyprus\" ],\n\t[ \"2350\", \"Michelle\", \"Manning\", \"V7T 4A3\", \"New Zealand\" ],\n\t[ \"2351\", \"Quintessa\", \"Chapman\", \"95379\", \"Faroe Islands\" ],\n\t[ \"2352\", \"Danielle\", \"Wells\", \"27722\", \"Colombia\" ],\n\t[ \"2353\", \"Faith\", \"Decker\", \"04881\", \"Canada\" ],\n\t[ \"2354\", \"Gannon\", \"Chapman\", \"07687\", \"Israel\" ],\n\t[ \"2355\", \"Jayme\", \"Black\", \"A6L 9W1\", \"Jordan\" ],\n\t[ \"2356\", \"Zenia\", \"Cooley\", \"A6X 1B7\", \"Greenland\" ],\n\t[ \"2357\", \"Maris\", \"Burton\", \"J4G 1Y0\", \"Ecuador\" ],\n\t[ \"2358\", \"Rina\", \"Vazquez\", \"G3V 7G6\", \"Russian Federation\" ],\n\t[ \"2359\", \"Nina\", \"Stanton\", \"E7Z 1W0\", \"Dominica\" ],\n\t[ \"2360\", \"Alexandra\", \"Jenkins\", \"C6N 4R4\", \"Morocco\" ],\n\t[ \"2361\", \"Jerome\", \"Chen\", \"68955\", \"Israel\" ],\n\t[ \"2362\", \"Clementine\", \"Robbins\", \"X7I 7T3\", \"Croatia\" ],\n\t[ \"2363\", \"Nigel\", \"Guthrie\", \"A4N 6X8\", \"French Southern Territories\" ],\n\t[ \"2364\", \"Xaviera\", \"Griffith\", \"90489\", \"Cuba\" ],\n\t[ \"2365\", \"Marsden\", \"Best\", \"U4B 5R7\", \"Estonia\" ],\n\t[ \"2366\", \"Ebony\", \"Benson\", \"H7C 7F7\", \"Anguilla\" ],\n\t[ \"2367\", \"Kylie\", \"Hansen\", \"38932\", \"Eritrea\" ],\n\t[ \"2368\", \"Iola\", \"Copeland\", \"P4X 9M4\", \"Rwanda\" ],\n\t[ \"2369\", \"Jorden\", \"Green\", \"48018\", \"Namibia\" ],\n\t[ \"2370\", \"Hamish\", \"Porter\", \"L6F 8L1\", \"Taiwan, Province of China\" ],\n\t[ \"2371\", \"Ezra\", \"Taylor\", \"09148\", \"French Southern Territories\" ],\n\t[ \"2372\", \"Dara\", \"Pratt\", \"00558\", \"Saint Kitts and Nevis\" ],\n\t[ \"2373\", \"Oliver\", \"Holt\", \"C4N 5Z7\", \"Thailand\" ],\n\t[ \"2374\", \"Kato\", \"Mcgee\", \"17017\", \"Micronesia\" ],\n\t[ \"2375\", \"Fuller\", \"Rogers\", \"M8F 6Y7\", \"French Polynesia\" ],\n\t[ \"2376\", \"Carol\", \"Stuart\", \"55980\", \"Sudan\" ],\n\t[ \"2377\", \"Wayne\", \"Nichols\", \"37344\", \"Chile\" ],\n\t[ \"2378\", \"Lars\", \"Gilbert\", \"27076\", \"Micronesia\" ],\n\t[ \"2379\", \"Todd\", \"Rollins\", \"M4I 4X8\", \"Virgin Islands, U.S.\" ],\n\t[ \"2380\", \"Colorado\", \"Justice\", \"68795\", \"Yemen\" ],\n\t[ \"2381\", \"Jordan\", \"Chang\", \"11149\", \"Mayotte\" ],\n\t[ \"2382\", \"Troy\", \"Haynes\", \"N2N 1N8\", \"Reunion\" ],\n\t[ \"2383\", \"Amity\", \"Snyder\", \"17785\", \"Argentina\" ],\n\t[ \"2384\", \"Kennan\", \"Turner\", \"30041\", \"Brazil\" ],\n\t[ \"2385\", \"Dorothy\", \"Gates\", \"B7Z 6V4\", \"Ghana\" ],\n\t[ \"2386\", \"Ariana\", \"Rojas\", \"70797\", \"Eritrea\" ],\n\t[ \"2387\", \"Desirae\", \"Joyner\", \"63493\", \"Maldives\" ],\n\t[ \"2388\", \"Marsden\", \"Barton\", \"36343\", \"Chile\" ],\n\t[ \"2389\", \"Graham\", \"Greer\", \"65152\", \"Cayman Islands\" ],\n\t[ \"2390\", \"Cameron\", \"Edwards\", \"89276\", \"Montserrat\" ],\n\t[ \"2391\", \"Bradley\", \"White\", \"80364\", \"United Kingdom\" ],\n\t[ \"2392\", \"Finn\", \"Cote\", \"G9P 1P0\", \"Ghana\" ],\n\t[ \"2393\", \"Geoffrey\", \"Becker\", \"O5G 4L4\", \"Wallis and Futuna\" ],\n\t[ \"2394\", \"Hayden\", \"Estes\", \"Q8G 7F9\", \"Togo\" ],\n\t[ \"2395\", \"Quinlan\", \"Garrett\", \"R2C 3E7\", \"Uganda\" ],\n\t[ \"2396\", \"Haviva\", \"Harrington\", \"64198\", \"Bahamas\" ],\n\t[ \"2397\", \"Brennan\", \"Hodge\", \"35327\", \"Paraguay\" ],\n\t[ \"2398\", \"Halee\", \"Sykes\", \"S6J 4S4\", \"Costa Rica\" ],\n\t[ \"2399\", \"Mikayla\", \"Ruiz\", \"21686\", \"Malaysia\" ],\n\t[ \"2400\", \"Macy\", \"Stanley\", \"F6D 6C4\", \"Luxembourg\" ],\n\t[ \"2401\", \"Petra\", \"Miles\", \"O7X 2D2\", \"Tokelau\" ],\n\t[ \"2402\", \"Oprah\", \"Mendez\", \"88994\", \"France\" ],\n\t[ \"2403\", \"Upton\", \"Silva\", \"17878\", \"French Southern Territories\" ],\n\t[ \"2404\", \"Wade\", \"Pennington\", \"S8J 3P2\", \"Malaysia\" ],\n\t[ \"2405\", \"Gannon\", \"Riddle\", \"I4A 2H9\", \"Somalia\" ],\n\t[ \"2406\", \"Jana\", \"Myers\", \"04982\", \"Philippines\" ],\n\t[ \"2407\", \"Brooke\", \"Hale\", \"98272\", \"Lithuania\" ],\n\t[ \"2408\", \"Hashim\", \"Mendez\", \"00144\", \"Saint Helena\" ],\n\t[ \"2409\", \"Blythe\", \"Hanson\", \"U5Z 6P4\", \"Saint Helena\" ],\n\t[ \"2410\", \"Michelle\", \"Madden\", \"B4R 1I9\", \"Ireland\" ],\n\t[ \"2411\", \"Deirdre\", \"Patton\", \"B4H 1N7\", \"Georgia\" ],\n\t[ \"2412\", \"Nathaniel\", \"Chandler\", \"W1V 8R4\", \"Sierra Leone\" ],\n\t[ \"2413\", \"Tamekah\", \"Murray\", \"I8M 1W8\", \"Guatemala\" ],\n\t[ \"2414\", \"Naida\", \"Boyle\", \"V4S 2N2\", \"United Arab Emirates\" ],\n\t[ \"2415\", \"Hiroko\", \"Winters\", \"K8G 3R9\", \"Barbados\" ],\n\t[ \"2416\", \"Palmer\", \"Guy\", \"A4H 5L1\", \"Saudi Arabia\" ],\n\t[ \"2417\", \"Hermione\", \"Nicholson\", \"76147\", \"Marshall Islands\" ],\n\t[ \"2418\", \"Russell\", \"Boyd\", \"66149\", \"Switzerland\" ],\n\t[ \"2419\", \"Gretchen\", \"Robles\", \"B9L 1J7\", \"Spain\" ],\n\t[ \"2420\", \"Leah\", \"Gibbs\", \"16682\", \"Vanuatu\" ],\n\t[ \"2421\", \"Amir\", \"Carlson\", \"A5C 6F2\", \"Myanmar\" ],\n\t[ \"2422\", \"Merrill\", \"Ratliff\", \"A6E 9B2\", \"Tonga\" ],\n\t[ \"2423\", \"Wyatt\", \"David\", \"P8G 2M1\", \"Kiribati\" ],\n\t[ \"2424\", \"Violet\", \"Boyle\", \"P5X 7B0\", \"Denmark\" ],\n\t[ \"2425\", \"Jared\", \"Myers\", \"22131\", \"Kyrgyzstan\" ],\n\t[ \"2426\", \"Lavinia\", \"Stephenson\", \"55537\", \"Turks and Caicos Islands\" ],\n\t[ \"2427\", \"Zachary\", \"Tyson\", \"C4O 7V4\", \"Macedonia\" ],\n\t[ \"2428\", \"Emma\", \"Clark\", \"A7Z 2Z1\", \"Guam\" ],\n\t[ \"2429\", \"Aaron\", \"Montoya\", \"Q3U 2X1\", \"Bahrain\" ],\n\t[ \"2430\", \"Dylan\", \"Roach\", \"81238\", \"French Guiana\" ],\n\t[ \"2431\", \"Baxter\", \"Rosario\", \"H7B 1R2\", \"Suriname\" ],\n\t[ \"2432\", \"Shad\", \"Bolton\", \"D1W 5X0\", \"Barbados\" ],\n\t[ \"2433\", \"Hasad\", \"Hines\", \"D9U 3H1\", \"Ukraine\" ],\n\t[ \"2434\", \"Maggy\", \"French\", \"M3E 5H8\", \"Nicaragua\" ],\n\t[ \"2435\", \"Evangeline\", \"Jenkins\", \"57732\", \"Nigeria\" ],\n\t[ \"2436\", \"Eaton\", \"Shannon\", \"56854\", \"Namibia\" ],\n\t[ \"2437\", \"Keaton\", \"Barber\", \"G5V 7T0\", \"Svalbard and Jan Mayen\" ],\n\t[ \"2438\", \"Lester\", \"Love\", \"J5Q 8H3\", \"United Kingdom\" ],\n\t[ \"2439\", \"Olivia\", \"Foley\", \"16284\", \"Mayotte\" ],\n\t[ \"2440\", \"Inez\", \"Craig\", \"98947\", \"Poland\" ],\n\t[ \"2441\", \"Desirae\", \"Jacobson\", \"25950\", \"French Polynesia\" ],\n\t[ \"2442\", \"Amethyst\", \"Robertson\", \"78840\", \"Timor-leste\" ],\n\t[ \"2443\", \"Rahim\", \"Day\", \"61420\", \"Maldives\" ],\n\t[ \"2444\", \"Kevyn\", \"Mccarty\", \"X7T 8Z3\", \"Guam\" ],\n\t[ \"2445\", \"Logan\", \"Malone\", \"B6F 8N0\", \"Madagascar\" ],\n\t[ \"2446\", \"Kathleen\", \"Cote\", \"L4R 6W9\", \"Congo\" ],\n\t[ \"2447\", \"Porter\", \"Mclean\", \"G1Z 1W9\", \"Mauritius\" ],\n\t[ \"2448\", \"Reagan\", \"Chapman\", \"86314\", \"Palestinian Territory, Occupied\" ],\n\t[ \"2449\", \"Veda\", \"Harrington\", \"R7W 1K4\", \"Congo\" ],\n\t[ \"2450\", \"Dominique\", \"Hewitt\", \"P5K 7L4\", \"San Marino\" ],\n\t[ \"2451\", \"Zelda\", \"Orr\", \"Z5B 6V1\", \"Greenland\" ],\n\t[ \"2452\", \"Natalie\", \"Kane\", \"10491\", \"Belgium\" ],\n\t[ \"2453\", \"Elizabeth\", \"Bright\", \"R3V 2R4\", \"Bangladesh\" ],\n\t[ \"2454\", \"Evan\", \"Knapp\", \"W3Z 3I5\", \"Mauritius\" ],\n\t[ \"2455\", \"Unity\", \"Armstrong\", \"82986\", \"Kiribati\" ],\n\t[ \"2456\", \"Arden\", \"Winters\", \"C7D 4M2\", \"Sweden\" ],\n\t[ \"2457\", \"Hayfa\", \"Henderson\", \"B8Z 3V3\", \"Latvia\" ],\n\t[ \"2458\", \"Ocean\", \"Delacruz\", \"Z3Z 2H8\", \"Tonga\" ],\n\t[ \"2459\", \"Carter\", \"Harding\", \"R1Z 8J4\", \"Ireland\" ],\n\t[ \"2460\", \"Harriet\", \"Simmons\", \"54757\", \"Indonesia\" ],\n\t[ \"2461\", \"Sopoline\", \"Hicks\", \"I5A 6O2\", \"Argentina\" ],\n\t[ \"2462\", \"Jenette\", \"Ramos\", \"I4V 3H6\", \"Portugal\" ],\n\t[ \"2463\", \"Abigail\", \"Berg\", \"E6P 6L0\", \"United States\" ],\n\t[ \"2464\", \"Sybill\", \"Fox\", \"02319\", \"Svalbard and Jan Mayen\" ],\n\t[ \"2465\", \"Wyoming\", \"Jarvis\", \"I1R 7V9\", \"Palestinian Territory, Occupied\" ],\n\t[ \"2466\", \"Cynthia\", \"English\", \"17983\", \"Israel\" ],\n\t[ \"2467\", \"Jerry\", \"Little\", \"33846\", \"Mauritius\" ],\n\t[ \"2468\", \"Quintessa\", \"Donaldson\", \"V4N 2K1\", \"China\" ],\n\t[ \"2469\", \"Anne\", \"Potter\", \"78596\", \"United States Minor Outlying Islands\" ],\n\t[ \"2470\", \"Madonna\", \"Hart\", \"A4A 4T8\", \"Bahrain\" ],\n\t[ \"2471\", \"Madeline\", \"Walls\", \"Y3D 4T3\", \"Comoros\" ],\n\t[ \"2472\", \"Fleur\", \"Blevins\", \"D1T 9P6\", \"Guinea-bissau\" ],\n\t[ \"2473\", \"Jaden\", \"Webb\", \"13917\", \"Lesotho\" ],\n\t[ \"2474\", \"Abdul\", \"Fleming\", \"A8A 3Y3\", \"Canada\" ],\n\t[ \"2475\", \"Blaze\", \"Carroll\", \"41059\", \"Marshall Islands\" ],\n\t[ \"2476\", \"David\", \"Hoover\", \"29132\", \"Algeria\" ],\n\t[ \"2477\", \"Renee\", \"Nieves\", \"35843\", \"Egypt\" ],\n\t[ \"2478\", \"Jaime\", \"Mcclure\", \"R5K 6B5\", \"Liechtenstein\" ],\n\t[ \"2479\", \"Deborah\", \"Fletcher\", \"70399\", \"Equatorial Guinea\" ],\n\t[ \"2480\", \"Otto\", \"Lopez\", \"72417\", \"Belarus\" ],\n\t[ \"2481\", \"Bo\", \"Walls\", \"F4M 8X8\", \"Latvia\" ],\n\t[ \"2482\", \"Jamal\", \"Adams\", \"N9X 3A2\", \"Spain\" ],\n\t[ \"2483\", \"Silas\", \"Gardner\", \"25259\", \"French Guiana\" ],\n\t[ \"2484\", \"Aladdin\", \"Morin\", \"45179\", \"Sweden\" ],\n\t[ \"2485\", \"Dawn\", \"Grant\", \"53613\", \"Grenada\" ],\n\t[ \"2486\", \"Forrest\", \"Gay\", \"53606\", \"Cayman Islands\" ],\n\t[ \"2487\", \"Lavinia\", \"Murphy\", \"S5L 6X9\", \"Turkey\" ],\n\t[ \"2488\", \"Sylvia\", \"Wolfe\", \"37280\", \"Indonesia\" ],\n\t[ \"2489\", \"Wynter\", \"Adkins\", \"37391\", \"Russian Federation\" ],\n\t[ \"2490\", \"Iola\", \"Frank\", \"I9H 1K7\", \"Nigeria\" ],\n\t[ \"2491\", \"Emmanuel\", \"Hester\", \"Z6E 3I4\", \"Guinea\" ],\n\t[ \"2492\", \"Karina\", \"Christian\", \"V8M 6F3\", \"Honduras\" ],\n\t[ \"2493\", \"Malcolm\", \"Holden\", \"I7J 6U7\", \"Austria\" ],\n\t[ \"2494\", \"Moana\", \"Holmes\", \"80402\", \"Israel\" ],\n\t[ \"2495\", \"Ramona\", \"Hewitt\", \"U6B 7A6\", \"Guadeloupe\" ],\n\t[ \"2496\", \"Nicholas\", \"Terry\", \"V8J 5D9\", \"Costa Rica\" ],\n\t[ \"2497\", \"Erica\", \"Dunlap\", \"91596\", \"Kazakhstan\" ],\n\t[ \"2498\", \"Logan\", \"Harper\", \"R7V 3T5\", \"Guinea-bissau\" ],\n\t[ \"2499\", \"Bert\", \"Ortega\", \"74557\", \"Paraguay\" ],\n\t[ \"2500\", \"Cameron\", \"Ortiz\", \"P9C 5B6\", \"Eritrea\" ]\n] }"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Scroller/examples/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\n\t<title>Scroller examples - Scroller examples</title>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Scroller example <span>Scroller examples</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Scroller is a virtual rendering plug-in for DataTables which allows large datasets to be drawn on\n\t\t\t\tscreen every quickly. What the virtual rendering means is that only the visible portion of the table\n\t\t\t\t(and a bit to either side to make the scrolling smooth) is drawn, while the scrolling container gives\n\t\t\t\tthe visual impression that the whole table is visible. This is done by making use of the pagination\n\t\t\t\tabilities of DataTables and moving the table around in the scrolling container DataTables adds to the\n\t\t\t\tpage. The scrolling container is forced to the height it would be for the full table display using an\n\t\t\t\textra element.</p>\n\n\t\t\t\t<p>Scroller is initialised by simply including the letter <code>S</code> in the <a href=\n\t\t\t\t\"//datatables.net/reference/option/dom\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">dom<span>DT</span></code></a> for the table you want to have this\n\t\t\t\tfeature enabled on. Note that the <code>S</code> must come after the <code>t</code> parameter in\n\t\t\t\t<a href=\"//datatables.net/reference/option/dom\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">dom<span>DT</span></code></a>.</p>\n\n\t\t\t\t<p>Key features include:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li>Speed! The aim of Scroller for DataTables is to make rendering large data sets fast</li>\n\t\t\t\t\t<li>Full compatibility with DataTables' deferred rendering for maximum speed</li>\n\t\t\t\t\t<li>Integration with state saving in DataTables (scrolling position is saved)</li>\n\t\t\t\t\t<li>Easy to use</li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_saving.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./large_js_source.html\">Client-side data source (50,000 rows)</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side_processing.html\">Server-side processing (5,000,000\n\t\t\t\t\t\t\trows)</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./api_scrolling.html\">API</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Scroller/examples/large_js_source.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Scroller example - Client-side data source (50,000 rows)</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.scroller.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.scroller.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\t$(document).ready(function() {\n\t\tvar data = [];\n\t\tfor ( var i=0 ; i<50000 ; i++ ) {\n\t\t\tdata.push( [ i, i, i, i, i ] );\n\t\t}\n\t\t\n\t\tvar oTable = $('#example').dataTable( {\n\t\t\tdata:           data,\n\t\t\tdeferRender:    true,\n\t\t\tdom:            \"frtiS\",\n\t\t\tscrollY:        200,\n\t\t\tscrollCollapse: true\n\t\t} );\n\t} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Scroller example <span>Client-side data source (50,000 rows)</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example is completely artificial in that the data generated is created on the client-side by\n\t\t\t\tjust looping around a Javascript array and then passing that to DataTables. However, it does show quite\n\t\t\t\tnicely that DataTables and Scroller can cope with large amounts of data on the client-side quite\n\t\t\t\tnicely. Typically data such as this would be Ajax sourced and server-side processing should be\n\t\t\t\tconsidered.</p>\n\n\t\t\t\t<p>Please be aware that the performance of this page will depend on your browser as the array of data\n\t\t\t\tis generated - for example IE6 will crawl!</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>ID</th>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>ZIP / Post code</th>\n\t\t\t\t\t\t<th>Country</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\t\tvar data = [];\n\t\tfor ( var i=0 ; i&lt;50000 ; i++ ) {\n\t\t\tdata.push( [ i, i, i, i, i ] );\n\t\t}\n\t\t\n\t\tvar oTable = $('#example').dataTable( {\n\t\t\tdata:           data,\n\t\t\tdeferRender:    true,\n\t\t\tdom:            &quot;frtiS&quot;,\n\t\t\tscrollY:        200,\n\t\t\tscrollCollapse: true\n\t\t} );\n\t} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.scroller.js\">../js/dataTables.scroller.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.scroller.css\">../css/dataTables.scroller.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_saving.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./large_js_source.html\">Client-side data source (50,000\n\t\t\t\t\t\t\trows)</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side_processing.html\">Server-side processing (5,000,000\n\t\t\t\t\t\t\trows)</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./api_scrolling.html\">API</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Scroller/examples/server-side_processing.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Scroller example - Server-side processing (5,000,000 rows)</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.scroller.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.scroller.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tserverSide: true,\n\t\tordering: false,\n\t\tsearching: false,\n\t\tajax: function ( data, callback, settings ) {\n\t\t\tvar out = [];\n\n\t\t\tfor ( var i=data.start, ien=data.start+data.length ; i<ien ; i++ ) {\n\t\t\t\tout.push( [ i+'-1', i+'-2', i+'-3', i+'-4', i+'-5' ] );\n\t\t\t}\n\n\t\t\tsetTimeout( function () {\n\t\t\t\tcallback( {\n\t\t\t\t\tdraw: data.draw,\n\t\t\t\t\tdata: out,\n\t\t\t\t\trecordsTotal: 5000000,\n\t\t\t\t\trecordsFiltered: 5000000\n\t\t\t\t} );\n\t\t\t}, 50 );\n\t\t},\n\t\tdom: \"rtiS\",\n\t\tscrollY: 200,\n\t\tscroller: {\n\t\t\tloadingIndicator: true\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Scroller example <span>Server-side processing (5,000,000 rows)</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>DataTables' server-side processing mode is a feature that naturally fits in with Scroller perfectly.\n\t\t\t\tServer-side processing can be used to show large data sets, with the server being used to do the data\n\t\t\t\tprocessing, and Scroller optimising the display of the data in a scrolling viewport.</p>\n\n\t\t\t\t<p>When using server-side processing, Scroller will wait a small amount of time to allow the scrolling\n\t\t\t\tto finish before requesting more data from the server (200mS by default). This prevents you from DoSing\n\t\t\t\tyour own server!</p>\n\n\t\t\t\t<p>This example shows Scroller using server-side processing mode and 5 million rows.\n\t\t\t\t<strong>Important</strong> This particular example uses <a href=\n\t\t\t\t\"//datatables.net/reference/option/ajax\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">ajax<span>DT</span></code></a> as a function to 'fake' the data to\n\t\t\t\tshow Scroller's ability to show large data sets. It does not have a real database behind it! You would\n\t\t\t\tnormally not use <a href=\"//datatables.net/reference/option/ajax\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">ajax<span>DT</span></code></a> as a function to generate data, but\n\t\t\t\trather as a url for where to fetch the real data!</p>\n\n\t\t\t\t<p>In this example we also enable the <code>loadingIndicator</code> option of Scroller to show the end\n\t\t\t\tuser what is happening when they scroll passed the currently loaded data.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>ID</th>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>ZIP / Post code</th>\n\t\t\t\t\t\t<th>Country</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tserverSide: true,\n\t\tordering: false,\n\t\tsearching: false,\n\t\tajax: function ( data, callback, settings ) {\n\t\t\tvar out = [];\n\n\t\t\tfor ( var i=data.start, ien=data.start+data.length ; i&lt;ien ; i++ ) {\n\t\t\t\tout.push( [ i+'-1', i+'-2', i+'-3', i+'-4', i+'-5' ] );\n\t\t\t}\n\n\t\t\tsetTimeout( function () {\n\t\t\t\tcallback( {\n\t\t\t\t\tdraw: data.draw,\n\t\t\t\t\tdata: out,\n\t\t\t\t\trecordsTotal: 5000000,\n\t\t\t\t\trecordsFiltered: 5000000\n\t\t\t\t} );\n\t\t\t}, 50 );\n\t\t},\n\t\tdom: &quot;rtiS&quot;,\n\t\tscrollY: 200,\n\t\tscroller: {\n\t\t\tloadingIndicator: true\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.scroller.js\">../js/dataTables.scroller.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.scroller.css\">../css/dataTables.scroller.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_saving.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./large_js_source.html\">Client-side data source (50,000 rows)</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./server-side_processing.html\">Server-side processing\n\t\t\t\t\t\t\t(5,000,000 rows)</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./api_scrolling.html\">API</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Scroller/examples/simple.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Scroller example - Basic initialisation</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.scroller.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.scroller.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tajax:           \"data/2500.txt\",\n\t\tdeferRender:    true,\n\t\tdom:            \"frtiS\",\n\t\tscrollY:        200,\n\t\tscrollCollapse: true\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Scroller example <span>Basic initialisation</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Scroller is a plug-in for DataTables which enhances DataTables' built-in scrolling features to allow\n\t\t\t\tlarge amounts of data to be rendered on page very quickly. This is done by Scroller through the use of\n\t\t\t\ta virtual rendering technique that will render only the part of the table that is actually required for\n\t\t\t\tthe current view.</p>\n\n\t\t\t\t<p>Note that Scroller assumes that all rows are of the same height (in order to preform the required\n\t\t\t\tcalculations. You can use <code>td { white-space: nowrap; }</code> in your CSS to ensure that text in\n\t\t\t\trows does not wrap.</p>\n\n\t\t\t\t<p>This example shows how Scroller for DataTables can be initialised by simply including the character\n\t\t\t\t<code>S</code> in sDom (note that the <code>S</code> must come after the <code>t</code> in sDom).\n\t\t\t\tDeferred rendering an and Ajax data source are also used in this example.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>ID</th>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>ZIP / Post code</th>\n\t\t\t\t\t\t<th>Country</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tajax:           &quot;data/2500.txt&quot;,\n\t\tdeferRender:    true,\n\t\tdom:            &quot;frtiS&quot;,\n\t\tscrollY:        200,\n\t\tscrollCollapse: true\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.scroller.js\">../js/dataTables.scroller.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.scroller.css\">../css/dataTables.scroller.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./state_saving.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./large_js_source.html\">Client-side data source (50,000 rows)</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side_processing.html\">Server-side processing (5,000,000\n\t\t\t\t\t\t\trows)</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./api_scrolling.html\">API</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Scroller/examples/state_saving.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>Scroller example - State saving</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.scroller.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.scroller.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tajax:           \"data/2500.txt\",\n\t\tdeferRender:    true,\n\t\tdom:            \"frtiS\",\n\t\tscrollY:        200,\n\t\tscrollCollapse: true,\n\t\tstateSave:      true\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>Scroller example <span>State saving</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Scroller will automatically integrate with DataTables in order to save the scrolling position of the\n\t\t\t\ttable, if state saving is enabled in the DataTable (<a href=\n\t\t\t\t\"//datatables.net/reference/option/stateSave\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">stateSave<span>DT</span></code></a>). This example shows that in\n\t\t\t\tpractice - to demonstrate, scroll the table and then reload the page.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>ID</th>\n\t\t\t\t\t\t<th>First name</th>\n\t\t\t\t\t\t<th>Last name</th>\n\t\t\t\t\t\t<th>ZIP / Post code</th>\n\t\t\t\t\t\t<th>Country</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this\n\t\t\t\t\texample:</p><code class=\"multiline brush: js;\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tajax:           &quot;data/2500.txt&quot;,\n\t\tdeferRender:    true,\n\t\tdom:            &quot;frtiS&quot;,\n\t\tscrollY:        200,\n\t\tscrollCollapse: true,\n\t\tstateSave:      true\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this\n\t\t\t\t\texample:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.scroller.js\">../js/dataTables.scroller.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by\n\t\t\t\t\tDataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library\n\t\t\t\t\t\tfiles (below), in order to correctly display the table. The additional CSS used is shown\n\t\t\t\t\t\tbelow:</p><code class=\"multiline brush: js;\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the\n\t\t\t\t\ttable:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.scroller.css\">../css/dataTables.scroller.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data\n\t\t\t\t\twill update automatically as any additional data is loaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note\n\t\t\t\t\tthat this is just an example script using PHP. Server-side processing scripts can be written in any\n\t\t\t\t\tlanguage, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the\n\t\t\t\t\tDataTables documentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./state_saving.html\">State saving</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./large_js_source.html\">Client-side data source (50,000 rows)</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./server-side_processing.html\">Server-side processing (5,000,000\n\t\t\t\t\t\t\trows)</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./api_scrolling.html\">API</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full\n\t\t\t\t\tinformation about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and\n\t\t\t\t\t<a href=\"http://www.datatables.net/plug-ins\">plug-ins</a> which extend the capabilities of\n\t\t\t\t\tDataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\n\t\t\t\t\t\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2014<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/Scroller/js/dataTables.scroller.js",
    "content": "/*! Scroller 1.2.2\n * ©2011-2014 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary     Scroller\n * @description Virtual rendering for DataTables\n * @version     1.2.2\n * @file        dataTables.scroller.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2011-2014 SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n *   MIT license - http://datatables.net/license/mit\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n(function(window, document, undefined){\n\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\n/**\n * Scroller is a virtual rendering plug-in for DataTables which allows large\n * datasets to be drawn on screen every quickly. What the virtual rendering means\n * is that only the visible portion of the table (and a bit to either side to make\n * the scrolling smooth) is drawn, while the scrolling container gives the\n * visual impression that the whole table is visible. This is done by making use\n * of the pagination abilities of DataTables and moving the table around in the\n * scrolling container DataTables adds to the page. The scrolling container is\n * forced to the height it would be for the full table display using an extra\n * element.\n *\n * Note that rows in the table MUST all be the same height. Information in a cell\n * which expands on to multiple lines will cause some odd behaviour in the scrolling.\n *\n * Scroller is initialised by simply including the letter 'S' in the sDom for the\n * table you want to have this feature enabled on. Note that the 'S' must come\n * AFTER the 't' parameter in `dom`.\n *\n * Key features include:\n *   <ul class=\"limit_length\">\n *     <li>Speed! The aim of Scroller for DataTables is to make rendering large data sets fast</li>\n *     <li>Full compatibility with deferred rendering in DataTables 1.9 for maximum speed</li>\n *     <li>Display millions of rows</li>\n *     <li>Integration with state saving in DataTables (scrolling position is saved)</li>\n *     <li>Easy to use</li>\n *   </ul>\n *\n *  @class\n *  @constructor\n *  @global\n *  @param {object} oDT DataTables settings object\n *  @param {object} [oOpts={}] Configuration object for FixedColumns. Options \n *    are defined by {@link Scroller.defaults}\n *\n *  @requires jQuery 1.7+\n *  @requires DataTables 1.9.0+\n *\n *  @example\n *    $(document).ready(function() {\n *        $('#example').dataTable( {\n *            \"sScrollY\": \"200px\",\n *            \"sAjaxSource\": \"media/dataset/large.txt\",\n *            \"sDom\": \"frtiS\",\n *            \"bDeferRender\": true\n *        } );\n *    } );\n */\nvar Scroller = function ( oDTSettings, oOpts ) {\n\t/* Sanity check - you just know it will happen */\n\tif ( ! this instanceof Scroller )\n\t{\n\t\talert( \"Scroller warning: Scroller must be initialised with the 'new' keyword.\" );\n\t\treturn;\n\t}\n\n\tif ( typeof oOpts == 'undefined' )\n\t{\n\t\toOpts = {};\n\t}\n\n\t/**\n\t * Settings object which contains customisable information for the Scroller instance\n\t * @namespace\n\t * @private\n\t * @extends Scroller.defaults\n\t */\n\tthis.s = {\n\t\t/**\n\t\t * DataTables settings object\n\t\t *  @type     object\n\t\t *  @default  Passed in as first parameter to constructor\n\t\t */\n\t\t\"dt\": oDTSettings,\n\n\t\t/**\n\t\t * Pixel location of the top of the drawn table in the viewport\n\t\t *  @type     int\n\t\t *  @default  0\n\t\t */\n\t\t\"tableTop\": 0,\n\n\t\t/**\n\t\t * Pixel location of the bottom of the drawn table in the viewport\n\t\t *  @type     int\n\t\t *  @default  0\n\t\t */\n\t\t\"tableBottom\": 0,\n\n\t\t/**\n\t\t * Pixel location of the boundary for when the next data set should be loaded and drawn\n\t\t * when scrolling up the way.\n\t\t *  @type     int\n\t\t *  @default  0\n\t\t *  @private\n\t\t */\n\t\t\"redrawTop\": 0,\n\n\t\t/**\n\t\t * Pixel location of the boundary for when the next data set should be loaded and drawn\n\t\t * when scrolling down the way. Note that this is actually calculated as the offset from\n\t\t * the top.\n\t\t *  @type     int\n\t\t *  @default  0\n\t\t *  @private\n\t\t */\n\t\t\"redrawBottom\": 0,\n\n\t\t/**\n\t\t * Auto row height or not indicator\n\t\t *  @type     bool\n\t\t *  @default  0\n\t\t */\n\t\t\"autoHeight\": true,\n\n\t\t/**\n\t\t * Number of rows calculated as visible in the visible viewport\n\t\t *  @type     int\n\t\t *  @default  0\n\t\t */\n\t\t\"viewportRows\": 0,\n\n\t\t/**\n\t\t * setTimeout reference for state saving, used when state saving is enabled in the DataTable\n\t\t * and when the user scrolls the viewport in order to stop the cookie set taking too much\n\t\t * CPU!\n\t\t *  @type     int\n\t\t *  @default  0\n\t\t */\n\t\t\"stateTO\": null,\n\n\t\t/**\n\t\t * setTimeout reference for the redraw, used when server-side processing is enabled in the\n\t\t * DataTables in order to prevent DoSing the server\n\t\t *  @type     int\n\t\t *  @default  null\n\t\t */\n\t\t\"drawTO\": null,\n\n\t\theights: {\n\t\t\tjump: null,\n\t\t\tpage: null,\n\t\t\tvirtual: null,\n\t\t\tscroll: null,\n\n\t\t\t/**\n\t\t\t * Height of rows in the table\n\t\t\t *  @type     int\n\t\t\t *  @default  0\n\t\t\t */\n\t\t\trow: null,\n\n\t\t\t/**\n\t\t\t * Pixel height of the viewport\n\t\t\t *  @type     int\n\t\t\t *  @default  0\n\t\t\t */\n\t\t\tviewport: null\n\t\t},\n\n\t\ttopRowFloat: 0,\n\t\tscrollDrawDiff: null,\n\t\tloaderVisible: false\n\t};\n\n\t// @todo The defaults should extend a `c` property and the internal settings\n\t// only held in the `s` property. At the moment they are mixed\n\tthis.s = $.extend( this.s, Scroller.oDefaults, oOpts );\n\n\t// Workaround for row height being read from height object (see above comment)\n\tthis.s.heights.row = this.s.rowHeight;\n\n\t/**\n\t * DOM elements used by the class instance\n\t * @private\n\t * @namespace\n\t *\n\t */\n\tthis.dom = {\n\t\t\"force\":    document.createElement('div'),\n\t\t\"scroller\": null,\n\t\t\"table\":    null,\n\t\t\"loader\":   null\n\t};\n\n\t/* Attach the instance to the DataTables instance so it can be accessed */\n\tthis.s.dt.oScroller = this;\n\n\t/* Let's do it */\n\tthis._fnConstruct();\n};\n\n\n\nScroller.prototype = /** @lends Scroller.prototype */{\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Public methods\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * Calculate the pixel position from the top of the scrolling container for\n\t * a given row\n\t *  @param {int} iRow Row number to calculate the position of\n\t *  @returns {int} Pixels\n\t *  @example\n\t *    $(document).ready(function() {\n\t *      $('#example').dataTable( {\n\t *        \"sScrollY\": \"200px\",\n\t *        \"sAjaxSource\": \"media/dataset/large.txt\",\n\t *        \"sDom\": \"frtiS\",\n\t *        \"bDeferRender\": true,\n\t *        \"fnInitComplete\": function (o) {\n\t *          // Find where row 25 is\n\t *          alert( o.oScroller.fnRowToPixels( 25 ) );\n\t *        }\n\t *      } );\n\t *    } );\n\t */\n\t\"fnRowToPixels\": function ( rowIdx, intParse, virtual )\n\t{\n\t\tvar pixels;\n\n\t\tif ( virtual ) {\n\t\t\tpixels = this._domain( 'virtualToPhysical', rowIdx * this.s.heights.row );\n\t\t}\n\t\telse {\n\t\t\tvar diff = rowIdx - this.s.baseRowTop;\n\t\t\tpixels = this.s.baseScrollTop + (diff * this.s.heights.row);\n\t\t}\n\n\t\treturn intParse || intParse === undefined ?\n\t\t\tparseInt( pixels, 10 ) :\n\t\t\tpixels;\n\t},\n\n\n\t/**\n\t * Calculate the row number that will be found at the given pixel position\n\t * (y-scroll).\n\t *\n\t * Please note that when the height of the full table exceeds 1 million\n\t * pixels, Scroller switches into a non-linear mode for the scrollbar to fit\n\t * all of the records into a finite area, but this function returns a linear\n\t * value (relative to the last non-linear positioning).\n\t *  @param {int} iPixels Offset from top to calculate the row number of\n\t *  @param {int} [intParse=true] If an integer value should be returned\n\t *  @param {int} [virtual=false] Perform the calculations in the virtual domain\n\t *  @returns {int} Row index\n\t *  @example\n\t *    $(document).ready(function() {\n\t *      $('#example').dataTable( {\n\t *        \"sScrollY\": \"200px\",\n\t *        \"sAjaxSource\": \"media/dataset/large.txt\",\n\t *        \"sDom\": \"frtiS\",\n\t *        \"bDeferRender\": true,\n\t *        \"fnInitComplete\": function (o) {\n\t *          // Find what row number is at 500px\n\t *          alert( o.oScroller.fnPixelsToRow( 500 ) );\n\t *        }\n\t *      } );\n\t *    } );\n\t */\n\t\"fnPixelsToRow\": function ( pixels, intParse, virtual )\n\t{\n\t\tvar diff = pixels - this.s.baseScrollTop;\n\t\tvar row = virtual ?\n\t\t\tthis._domain( 'physicalToVirtual', pixels ) / this.s.heights.row :\n\t\t\t( diff / this.s.heights.row ) + this.s.baseRowTop;\n\n\t\treturn intParse || intParse === undefined ?\n\t\t\tparseInt( row, 10 ) :\n\t\t\trow;\n\t},\n\n\n\t/**\n\t * Calculate the row number that will be found at the given pixel position (y-scroll)\n\t *  @param {int} iRow Row index to scroll to\n\t *  @param {bool} [bAnimate=true] Animate the transition or not\n\t *  @returns {void}\n\t *  @example\n\t *    $(document).ready(function() {\n\t *      $('#example').dataTable( {\n\t *        \"sScrollY\": \"200px\",\n\t *        \"sAjaxSource\": \"media/dataset/large.txt\",\n\t *        \"sDom\": \"frtiS\",\n\t *        \"bDeferRender\": true,\n\t *        \"fnInitComplete\": function (o) {\n\t *          // Immediately scroll to row 1000\n\t *          o.oScroller.fnScrollToRow( 1000 );\n\t *        }\n\t *      } );\n\t *     \n\t *      // Sometime later on use the following to scroll to row 500...\n\t *          var oSettings = $('#example').dataTable().fnSettings();\n\t *      oSettings.oScroller.fnScrollToRow( 500 );\n\t *    } );\n\t */\n\t\"fnScrollToRow\": function ( iRow, bAnimate )\n\t{\n\t\tvar that = this;\n\t\tvar ani = false;\n\t\tvar px = this.fnRowToPixels( iRow );\n\n\t\t// We need to know if the table will redraw or not before doing the\n\t\t// scroll. If it will not redraw, then we need to use the currently\n\t\t// displayed table, and scroll with the physical pixels. Otherwise, we\n\t\t// need to calculate the table's new position from the virtual\n\t\t// transform.\n\t\tvar preRows = ((this.s.displayBuffer-1)/2) * this.s.viewportRows;\n\t\tvar drawRow = iRow - preRows;\n\t\tif ( drawRow < 0 ) {\n\t\t\tdrawRow = 0;\n\t\t}\n\n\t\tif ( (px > this.s.redrawBottom || px < this.s.redrawTop) && this.s.dt._iDisplayStart !== drawRow ) {\n\t\t\tani = true;\n\t\t\tpx = this.fnRowToPixels( iRow, false, true );\n\t\t}\n\n\t\tif ( typeof bAnimate == 'undefined' || bAnimate )\n\t\t{\n\t\t\tthis.s.ani = ani;\n\t\t\t$(this.dom.scroller).animate( {\n\t\t\t\t\"scrollTop\": px\n\t\t\t}, function () {\n\t\t\t\t// This needs to happen after the animation has completed and\n\t\t\t\t// the final scroll event fired\n\t\t\t\tsetTimeout( function () {\n\t\t\t\t\tthat.s.ani = false;\n\t\t\t\t}, 25 );\n\t\t\t} );\n\t\t}\n\t\telse\n\t\t{\n\t\t\t$(this.dom.scroller).scrollTop( px );\n\t\t}\n\t},\n\n\n\t/**\n\t * Calculate and store information about how many rows are to be displayed\n\t * in the scrolling viewport, based on current dimensions in the browser's\n\t * rendering. This can be particularly useful if the table is initially\n\t * drawn in a hidden element - for example in a tab.\n\t *  @param {bool} [bRedraw=true] Redraw the table automatically after the recalculation, with\n\t *    the new dimensions forming the basis for the draw.\n\t *  @returns {void}\n\t *  @example\n\t *    $(document).ready(function() {\n\t *      // Make the example container hidden to throw off the browser's sizing\n\t *      document.getElementById('container').style.display = \"none\";\n\t *      var oTable = $('#example').dataTable( {\n\t *        \"sScrollY\": \"200px\",\n\t *        \"sAjaxSource\": \"media/dataset/large.txt\",\n\t *        \"sDom\": \"frtiS\",\n\t *        \"bDeferRender\": true,\n\t *        \"fnInitComplete\": function (o) {\n\t *          // Immediately scroll to row 1000\n\t *          o.oScroller.fnScrollToRow( 1000 );\n\t *        }\n\t *      } );\n\t *     \n\t *      setTimeout( function () {\n\t *        // Make the example container visible and recalculate the scroller sizes\n\t *        document.getElementById('container').style.display = \"block\";\n\t *        oTable.fnSettings().oScroller.fnMeasure();\n\t *      }, 3000 );\n\t */\n\t\"fnMeasure\": function ( bRedraw )\n\t{\n\t\tif ( this.s.autoHeight )\n\t\t{\n\t\t\tthis._fnCalcRowHeight();\n\t\t}\n\n\t\tvar heights = this.s.heights;\n\n\t\theights.viewport = $(this.dom.scroller).height();\n\t\tthis.s.viewportRows = parseInt( heights.viewport / heights.row, 10 )+1;\n\t\tthis.s.dt._iDisplayLength = this.s.viewportRows * this.s.displayBuffer;\n\n\t\tif ( bRedraw === undefined || bRedraw )\n\t\t{\n\t\t\tthis.s.dt.oInstance.fnDraw();\n\t\t}\n\t},\n\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Private methods (they are of course public in JS, but recommended as private)\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * Initialisation for Scroller\n\t *  @returns {void}\n\t *  @private\n\t */\n\t\"_fnConstruct\": function ()\n\t{\n\t\tvar that = this;\n\n\t\t/* Sanity check */\n\t\tif ( !this.s.dt.oFeatures.bPaginate ) {\n\t\t\tthis.s.dt.oApi._fnLog( this.s.dt, 0, 'Pagination must be enabled for Scroller' );\n\t\t\treturn;\n\t\t}\n\n\t\t/* Insert a div element that we can use to force the DT scrolling container to\n\t\t * the height that would be required if the whole table was being displayed\n\t\t */\n\t\tthis.dom.force.style.position = \"absolute\";\n\t\tthis.dom.force.style.top = \"0px\";\n\t\tthis.dom.force.style.left = \"0px\";\n\t\tthis.dom.force.style.width = \"1px\";\n\n\t\tthis.dom.scroller = $('div.'+this.s.dt.oClasses.sScrollBody, this.s.dt.nTableWrapper)[0];\n\t\tthis.dom.scroller.appendChild( this.dom.force );\n\t\tthis.dom.scroller.style.position = \"relative\";\n\n\t\tthis.dom.table = $('>table', this.dom.scroller)[0];\n\t\tthis.dom.table.style.position = \"absolute\";\n\t\tthis.dom.table.style.top = \"0px\";\n\t\tthis.dom.table.style.left = \"0px\";\n\n\t\t// Add class to 'announce' that we are a Scroller table\n\t\t$(this.s.dt.nTableWrapper).addClass('DTS');\n\n\t\t// Add a 'loading' indicator\n\t\tif ( this.s.loadingIndicator )\n\t\t{\n\t\t\tthis.dom.loader = $('<div class=\"DTS_Loading\">'+this.s.dt.oLanguage.sLoadingRecords+'</div>')\n\t\t\t\t.css('display', 'none');\n\n\t\t\t$(this.dom.scroller.parentNode)\n\t\t\t\t.css('position', 'relative')\n\t\t\t\t.append( this.dom.loader );\n\t\t}\n\n\t\t/* Initial size calculations */\n\t\tif ( this.s.heights.row && this.s.heights.row != 'auto' )\n\t\t{\n\t\t\tthis.s.autoHeight = false;\n\t\t}\n\t\tthis.fnMeasure( false );\n\n\t\t/* Scrolling callback to see if a page change is needed - use a throttled\n\t\t * function for the save save callback so we aren't hitting it on every\n\t\t * scroll\n\t\t */\n\t\tthis.s.ingnoreScroll = true;\n\t\tthis.s.stateSaveThrottle = this.s.dt.oApi._fnThrottle( function () {\n\t\t\tthat.s.dt.oApi._fnSaveState( that.s.dt );\n\t\t}, 500 );\n\t\t$(this.dom.scroller).on( 'scroll.DTS', function (e) {\n\t\t\tthat._fnScroll.call( that );\n\t\t} );\n\n\t\t/* In iOS we catch the touchstart event in case the user tries to scroll\n\t\t * while the display is already scrolling\n\t\t */\n\t\t$(this.dom.scroller).on('touchstart.DTS', function () {\n\t\t\tthat._fnScroll.call( that );\n\t\t} );\n\n\t\t/* Update the scroller when the DataTable is redrawn */\n\t\tthis.s.dt.aoDrawCallback.push( {\n\t\t\t\"fn\": function () {\n\t\t\t\tif ( that.s.dt.bInitialised ) {\n\t\t\t\t\tthat._fnDrawCallback.call( that );\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"sName\": \"Scroller\"\n\t\t} );\n\n\t\t/* On resize, update the information element, since the number of rows shown might change */\n\t\t$(window).on( 'resize.DTS', function () {\n\t\t\tthat.fnMeasure( false );\n\t\t\tthat._fnInfo();\n\t\t} );\n\n\t\t/* Add a state saving parameter to the DT state saving so we can restore the exact\n\t\t * position of the scrolling\n\t\t */\n\t\tvar initialStateSave = true;\n\t\tthis.s.dt.oApi._fnCallbackReg( this.s.dt, 'aoStateSaveParams', function (oS, oData) {\n\t\t\t/* Set iScroller to saved scroll position on initialization.\n\t\t\t */\n\t\t\tif(initialStateSave && that.s.dt.oLoadedState){\n\t\t\t\toData.iScroller = that.s.dt.oLoadedState.iScroller;\n\t\t\t\toData.iScrollerTopRow = that.s.dt.oLoadedState.iScrollerTopRow;\n\t\t\t\tinitialStateSave = false;\n\t\t\t} else {\n\t\t\t\toData.iScroller = that.dom.scroller.scrollTop;\n\t\t\t\toData.iScrollerTopRow = that.s.topRowFloat;\n\t\t\t}\n\t\t}, \"Scroller_State\" );\n\n\t\tif ( this.s.dt.oLoadedState ) {\n\t\t\tthis.s.topRowFloat = this.s.dt.oLoadedState.iScrollerTopRow || 0;\n\t\t}\n\n\t\t/* Destructor */\n\t\tthis.s.dt.aoDestroyCallback.push( {\n\t\t\t\"sName\": \"Scroller\",\n\t\t\t\"fn\": function () {\n\t\t\t\t$(window).off( 'resize.DTS' );\n\t\t\t\t$(that.dom.scroller).off('touchstart.DTS scroll.DTS');\n\t\t\t\t$(that.s.dt.nTableWrapper).removeClass('DTS');\n\t\t\t\t$('div.DTS_Loading', that.dom.scroller.parentNode).remove();\n\n\t\t\t\tthat.dom.table.style.position = \"\";\n\t\t\t\tthat.dom.table.style.top = \"\";\n\t\t\t\tthat.dom.table.style.left = \"\";\n\t\t\t}\n\t\t} );\n\t},\n\n\n\t/**\n\t * Scrolling function - fired whenever the scrolling position is changed.\n\t * This method needs to use the stored values to see if the table should be\n\t * redrawn as we are moving towards the end of the information that is\n\t * currently drawn or not. If needed, then it will redraw the table based on\n\t * the new position.\n\t *  @returns {void}\n\t *  @private\n\t */\n\t\"_fnScroll\": function ()\n\t{\n\t\tvar\n\t\t\tthat = this,\n\t\t\theights = this.s.heights,\n\t\t\tiScrollTop = this.dom.scroller.scrollTop,\n\t\t\tiTopRow;\n\n\t\tif ( this.s.skip ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.s.ingnoreScroll ) {\n\t\t\treturn;\n\t\t}\n\n\t\t/* If the table has been sorted or filtered, then we use the redraw that\n\t\t * DataTables as done, rather than performing our own\n\t\t */\n\t\tif ( this.s.dt.bFiltered || this.s.dt.bSorted ) {\n\t\t\tthis.s.lastScrollTop = 0;\n\t\t\treturn;\n\t\t}\n\n\t\t/* Update the table's information display for what is now in the viewport */\n\t\tthis._fnInfo();\n\n\t\t/* We don't want to state save on every scroll event - that's heavy\n\t\t * handed, so use a timeout to update the state saving only when the\n\t\t * scrolling has finished\n\t\t */\n\t\tclearTimeout( this.s.stateTO );\n\t\tthis.s.stateTO = setTimeout( function () {\n\t\t\tthat.s.dt.oApi._fnSaveState( that.s.dt );\n\t\t}, 250 );\n\n\t\t/* Check if the scroll point is outside the trigger boundary which would required\n\t\t * a DataTables redraw\n\t\t */\n\t\tif ( iScrollTop < this.s.redrawTop || iScrollTop > this.s.redrawBottom ) {\n\t\t\tvar preRows = Math.ceil( ((this.s.displayBuffer-1)/2) * this.s.viewportRows );\n\n\t\t\tif ( Math.abs( iScrollTop - this.s.lastScrollTop ) > heights.viewport || this.s.ani ) {\n\t\t\t\tiTopRow = parseInt(this._domain( 'physicalToVirtual', iScrollTop ) / heights.row, 10) - preRows;\n\t\t\t\tthis.s.topRowFloat = (this._domain( 'physicalToVirtual', iScrollTop ) / heights.row);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tiTopRow = this.fnPixelsToRow( iScrollTop ) - preRows;\n\t\t\t\tthis.s.topRowFloat = this.fnPixelsToRow( iScrollTop, false );\n\t\t\t}\n\n\t\t\tif ( iTopRow <= 0 ) {\n\t\t\t\t/* At the start of the table */\n\t\t\t\tiTopRow = 0;\n\t\t\t}\n\t\t\telse if ( iTopRow + this.s.dt._iDisplayLength > this.s.dt.fnRecordsDisplay() ) {\n\t\t\t\t/* At the end of the table */\n\t\t\t\tiTopRow = this.s.dt.fnRecordsDisplay() - this.s.dt._iDisplayLength;\n\t\t\t\tif ( iTopRow < 0 ) {\n\t\t\t\t\tiTopRow = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( iTopRow % 2 !== 0 ) {\n\t\t\t\t// For the row-striping classes (odd/even) we want only to start\n\t\t\t\t// on evens otherwise the stripes will change between draws and\n\t\t\t\t// look rubbish\n\t\t\t\tiTopRow++;\n\t\t\t}\n\n\t\t\tif ( iTopRow != this.s.dt._iDisplayStart ) {\n\t\t\t\t/* Cache the new table position for quick lookups */\n\t\t\t\tthis.s.tableTop = $(this.s.dt.nTable).offset().top;\n\t\t\t\tthis.s.tableBottom = $(this.s.dt.nTable).height() + this.s.tableTop;\n\n\t\t\t\tvar draw =  function () {\n\t\t\t\t\tif ( that.s.scrollDrawReq === null ) {\n\t\t\t\t\t\tthat.s.scrollDrawReq = iScrollTop;\n\t\t\t\t\t}\n\n\t\t\t\t\tthat.s.dt._iDisplayStart = iTopRow;\n\t\t\t\t\tif ( that.s.dt.oApi._fnCalculateEnd ) { // Removed in 1.10\n\t\t\t\t\t\tthat.s.dt.oApi._fnCalculateEnd( that.s.dt );\n\t\t\t\t\t}\n\t\t\t\t\tthat.s.dt.oApi._fnDraw( that.s.dt );\n\t\t\t\t};\n\n\t\t\t\t/* Do the DataTables redraw based on the calculated start point - note that when\n\t\t\t\t * using server-side processing we introduce a small delay to not DoS the server...\n\t\t\t\t */\n\t\t\t\tif ( this.s.dt.oFeatures.bServerSide ) {\n\t\t\t\t\tclearTimeout( this.s.drawTO );\n\t\t\t\t\tthis.s.drawTO = setTimeout( draw, this.s.serverWait );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tdraw();\n\t\t\t\t}\n\n\t\t\t\tif ( this.dom.loader && ! this.s.loaderVisible ) {\n\t\t\t\t\tthis.dom.loader.css( 'display', 'block' );\n\t\t\t\t\tthis.s.loaderVisible = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.s.lastScrollTop = iScrollTop;\n\t\tthis.s.stateSaveThrottle();\n\t},\n\n\n\t/**\n\t * Convert from one domain to another. The physical domain is the actual\n\t * pixel count on the screen, while the virtual is if we had browsers which\n\t * had scrolling containers of infinite height (i.e. the absolute value)\n\t *\n\t *  @param {string} dir Domain transform direction, `virtualToPhysical` or\n\t *    `physicalToVirtual` \n\t *  @returns {number} Calculated transform\n\t *  @private\n\t */\n\t_domain: function ( dir, val )\n\t{\n\t\tvar heights = this.s.heights;\n\t\tvar coeff;\n\n\t\t// If the virtual and physical height match, then we use a linear\n\t\t// transform between the two, allowing the scrollbar to be linear\n\t\tif ( heights.virtual === heights.scroll ) {\n\t\t\tcoeff = (heights.virtual-heights.viewport) / (heights.scroll-heights.viewport);\n\n\t\t\tif ( dir === 'virtualToPhysical' ) {\n\t\t\t\treturn val / coeff;\n\t\t\t}\n\t\t\telse if ( dir === 'physicalToVirtual' ) {\n\t\t\t\treturn val * coeff;\n\t\t\t}\n\t\t}\n\n\t\t// Otherwise, we want a non-linear scrollbar to take account of the\n\t\t// redrawing regions at the start and end of the table, otherwise these\n\t\t// can stutter badly - on large tables 30px (for example) scroll might\n\t\t// be hundreds of rows, so the table would be redrawing every few px at\n\t\t// the start and end. Use a simple quadratic to stop this. It does mean\n\t\t// the scrollbar is non-linear, but with such massive data sets, the\n\t\t// scrollbar is going to be a best guess anyway\n\t\tvar xMax = (heights.scroll - heights.viewport) / 2;\n\t\tvar yMax = (heights.virtual - heights.viewport) / 2;\n\n\t\tcoeff = yMax / ( xMax * xMax );\n\n\t\tif ( dir === 'virtualToPhysical' ) {\n\t\t\tif ( val < yMax ) {\n\t\t\t\treturn Math.pow(val / coeff, 0.5);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tval = (yMax*2) - val;\n\t\t\t\treturn val < 0 ?\n\t\t\t\t\theights.scroll :\n\t\t\t\t\t(xMax*2) - Math.pow(val / coeff, 0.5);\n\t\t\t}\n\t\t}\n\t\telse if ( dir === 'physicalToVirtual' ) {\n\t\t\tif ( val < xMax ) {\n\t\t\t\treturn val * val * coeff;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tval = (xMax*2) - val;\n\t\t\t\treturn val < 0 ?\n\t\t\t\t\theights.virtual :\n\t\t\t\t\t(yMax*2) - (val * val * coeff);\n\t\t\t}\n\t\t}\n\t},\n\n\n\t/**\n\t * Draw callback function which is fired when the DataTable is redrawn. The main function of\n\t * this method is to position the drawn table correctly the scrolling container for the rows\n\t * that is displays as a result of the scrolling position.\n\t *  @returns {void}\n\t *  @private\n\t */\n\t\"_fnDrawCallback\": function ()\n\t{\n\t\tvar\n\t\t\tthat = this,\n\t\t\theights = this.s.heights,\n\t\t\tiScrollTop = this.dom.scroller.scrollTop,\n\t\t\tiActualScrollTop = iScrollTop,\n\t\t\tiScrollBottom = iScrollTop + heights.viewport,\n\t\t\tiTableHeight = $(this.s.dt.nTable).height(),\n\t\t\tdisplayStart = this.s.dt._iDisplayStart,\n\t\t\tdisplayLen = this.s.dt._iDisplayLength,\n\t\t\tdisplayEnd = this.s.dt.fnRecordsDisplay();\n\n\t\t// Disable the scroll event listener while we are updating the DOM\n\t\tthis.s.skip = true;\n\n\t\t// Resize the scroll forcing element\n\t\tthis._fnScrollForce();\n\n\t\t// Reposition the scrolling for the updated virtual position if needed\n\t\tif ( displayStart === 0 ) {\n\t\t\t// Linear calculation at the top of the table\n\t\t\tiScrollTop = this.s.topRowFloat * heights.row;\n\t\t}\n\t\telse if ( displayStart + displayLen >= displayEnd ) {\n\t\t\t// Linear calculation that the bottom as well\n\t\t\tiScrollTop = heights.scroll - ((displayEnd - this.s.topRowFloat) * heights.row);\n\t\t}\n\t\telse {\n\t\t\t// Domain scaled in the middle\n\t\t\tiScrollTop = this._domain( 'virtualToPhysical', this.s.topRowFloat * heights.row );\n\t\t}\n\n\t\tthis.dom.scroller.scrollTop = iScrollTop;\n\n\t\t// Store positional information so positional calculations can be based\n\t\t// upon the current table draw position\n\t\tthis.s.baseScrollTop = iScrollTop;\n\t\tthis.s.baseRowTop = this.s.topRowFloat;\n\n\t\t// Position the table in the virtual scroller\n\t\tvar tableTop = iScrollTop - ((this.s.topRowFloat - displayStart) * heights.row);\n\t\tif ( displayStart === 0 ) {\n\t\t\ttableTop = 0;\n\t\t}\n\t\telse if ( displayStart + displayLen >= displayEnd ) {\n\t\t\ttableTop = heights.scroll - iTableHeight;\n\t\t}\n\n\t\tthis.dom.table.style.top = tableTop+'px';\n\n\t\t/* Cache some information for the scroller */\n\t\tthis.s.tableTop = tableTop;\n\t\tthis.s.tableBottom = iTableHeight + this.s.tableTop;\n\n\t\t// Calculate the boundaries for where a redraw will be triggered by the\n\t\t// scroll event listener\n\t\tvar boundaryPx = (iScrollTop - this.s.tableTop) * this.s.boundaryScale;\n\t\tthis.s.redrawTop = iScrollTop - boundaryPx;\n\t\tthis.s.redrawBottom = iScrollTop + boundaryPx;\n\n\t\tthis.s.skip = false;\n\n\t\t// Restore the scrolling position that was saved by DataTable's state\n\t\t// saving Note that this is done on the second draw when data is Ajax\n\t\t// sourced, and the first draw when DOM soured\n\t\tif ( this.s.dt.oFeatures.bStateSave && this.s.dt.oLoadedState !== null &&\n\t\t\t typeof this.s.dt.oLoadedState.iScroller != 'undefined' )\n\t\t{\n\t\t\t// A quirk of DataTables is that the draw callback will occur on an\n\t\t\t// empty set if Ajax sourced, but not if server-side processing.\n\t\t\tvar ajaxSourced = (this.s.dt.sAjaxSource || that.s.dt.ajax) && ! this.s.dt.oFeatures.bServerSide ?\n\t\t\t\ttrue :\n\t\t\t\tfalse;\n\n\t\t\tif ( ( ajaxSourced && this.s.dt.iDraw == 2) ||\n\t\t\t     (!ajaxSourced && this.s.dt.iDraw == 1) )\n\t\t\t{\n\t\t\t\tsetTimeout( function () {\n\t\t\t\t\t$(that.dom.scroller).scrollTop( that.s.dt.oLoadedState.iScroller );\n\t\t\t\t\tthat.s.redrawTop = that.s.dt.oLoadedState.iScroller - (heights.viewport/2);\n\n\t\t\t\t\t// In order to prevent layout thrashing we need another\n\t\t\t\t\t// small delay\n\t\t\t\t\tsetTimeout( function () {\n\t\t\t\t\t\tthat.s.ingnoreScroll = false;\n\t\t\t\t\t}, 0 );\n\t\t\t\t}, 0 );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tthat.s.ingnoreScroll = false;\n\t\t}\n\n\t\t// Because of the order of the DT callbacks, the info update will\n\t\t// take precedence over the one we want here. So a 'thread' break is\n\t\t// needed\n\t\tsetTimeout( function () {\n\t\t\tthat._fnInfo.call( that );\n\t\t}, 0 );\n\n\t\t// Hide the loading indicator\n\t\tif ( this.dom.loader && this.s.loaderVisible ) {\n\t\t\tthis.dom.loader.css( 'display', 'none' );\n\t\t\tthis.s.loaderVisible = false;\n\t\t}\n\t},\n\n\n\t/**\n\t * Force the scrolling container to have height beyond that of just the\n\t * table that has been drawn so the user can scroll the whole data set.\n\t *\n\t * Note that if the calculated required scrolling height exceeds a maximum\n\t * value (1 million pixels - hard-coded) the forcing element will be set\n\t * only to that maximum value and virtual / physical domain transforms will\n\t * be used to allow Scroller to display tables of any number of records.\n\t *  @returns {void}\n\t *  @private\n\t */\n\t_fnScrollForce: function ()\n\t{\n\t\tvar heights = this.s.heights;\n\t\tvar max = 1000000;\n\n\t\theights.virtual = heights.row * this.s.dt.fnRecordsDisplay();\n\t\theights.scroll = heights.virtual;\n\n\t\tif ( heights.scroll > max ) {\n\t\t\theights.scroll = max;\n\t\t}\n\n\t\tthis.dom.force.style.height = heights.scroll+\"px\";\n\t},\n\n\n\t/**\n\t * Automatic calculation of table row height. This is just a little tricky here as using\n\t * initialisation DataTables has tale the table out of the document, so we need to create\n\t * a new table and insert it into the document, calculate the row height and then whip the\n\t * table out.\n\t *  @returns {void}\n\t *  @private\n\t */\n\t\"_fnCalcRowHeight\": function ()\n\t{\n\t\tvar dt = this.s.dt;\n\t\tvar origTable = dt.nTable;\n\t\tvar nTable = origTable.cloneNode( false );\n\t\tvar tbody = $('<tbody/>').appendTo( nTable );\n\t\tvar container = $(\n\t\t\t'<div class=\"'+dt.oClasses.sWrapper+' DTS\">'+\n\t\t\t\t'<div class=\"'+dt.oClasses.sScrollWrapper+'\">'+\n\t\t\t\t\t'<div class=\"'+dt.oClasses.sScrollBody+'\"></div>'+\n\t\t\t\t'</div>'+\n\t\t\t'</div>'\n\t\t);\n\n\t\t// Want 3 rows in the sizing table so :first-child and :last-child\n\t\t// CSS styles don't come into play - take the size of the middle row\n\t\t$('tbody tr:lt(4)', origTable).clone().appendTo( tbody );\n\t\twhile( $('tr', tbody).length < 3 ) {\n\t\t\ttbody.append( '<tr><td>&nbsp;</td></tr>' );\n\t\t}\n\n\t\t$('div.'+dt.oClasses.sScrollBody, container).append( nTable );\n\n\t\tvar appendTo;\n\t\tif (dt._bInitComplete) {\n\t\t\tappendTo = origTable.parentNode;\n\t\t} else {\n\t\t\tif (!this.s.dt.nHolding) {\n\t\t\t\tthis.s.dt.nHolding = $( '<div></div>' ).insertBefore( this.s.dt.nTable );\n\t\t\t}\n\t\t\tappendTo = this.s.dt.nHolding;\n\t\t}\n\n\t\tcontainer.appendTo( appendTo );\n\t\tthis.s.heights.row = $('tr', tbody).eq(1).outerHeight();\n\t\tcontainer.remove();\n\t},\n\n\n\t/**\n\t * Update any information elements that are controlled by the DataTable based on the scrolling\n\t * viewport and what rows are visible in it. This function basically acts in the same way as\n\t * _fnUpdateInfo in DataTables, and effectively replaces that function.\n\t *  @returns {void}\n\t *  @private\n\t */\n\t\"_fnInfo\": function ()\n\t{\n\t\tif ( !this.s.dt.oFeatures.bInfo )\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\tvar\n\t\t\tdt = this.s.dt,\n\t\t\tlanguage = dt.oLanguage,\n\t\t\tiScrollTop = this.dom.scroller.scrollTop,\n\t\t\tiStart = Math.floor( this.fnPixelsToRow(iScrollTop, false, this.s.ani)+1 ),\n\t\t\tiMax = dt.fnRecordsTotal(),\n\t\t\tiTotal = dt.fnRecordsDisplay(),\n\t\t\tiPossibleEnd = Math.ceil( this.fnPixelsToRow(iScrollTop+this.s.heights.viewport, false, this.s.ani) ),\n\t\t\tiEnd = iTotal < iPossibleEnd ? iTotal : iPossibleEnd,\n\t\t\tsStart = dt.fnFormatNumber( iStart ),\n\t\t\tsEnd = dt.fnFormatNumber( iEnd ),\n\t\t\tsMax = dt.fnFormatNumber( iMax ),\n\t\t\tsTotal = dt.fnFormatNumber( iTotal ),\n\t\t\tsOut;\n\n\t\tif ( dt.fnRecordsDisplay() === 0 &&\n\t\t\t   dt.fnRecordsDisplay() == dt.fnRecordsTotal() )\n\t\t{\n\t\t\t/* Empty record set */\n\t\t\tsOut = language.sInfoEmpty+ language.sInfoPostFix;\n\t\t}\n\t\telse if ( dt.fnRecordsDisplay() === 0 )\n\t\t{\n\t\t\t/* Empty record set after filtering */\n\t\t\tsOut = language.sInfoEmpty +' '+\n\t\t\t\tlanguage.sInfoFiltered.replace('_MAX_', sMax)+\n\t\t\t\t\tlanguage.sInfoPostFix;\n\t\t}\n\t\telse if ( dt.fnRecordsDisplay() == dt.fnRecordsTotal() )\n\t\t{\n\t\t\t/* Normal record set */\n\t\t\tsOut = language.sInfo.\n\t\t\t\t\treplace('_START_', sStart).\n\t\t\t\t\treplace('_END_',   sEnd).\n\t\t\t\t\treplace('_MAX_',   sMax).\n\t\t\t\t\treplace('_TOTAL_', sTotal)+\n\t\t\t\tlanguage.sInfoPostFix;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Record set after filtering */\n\t\t\tsOut = language.sInfo.\n\t\t\t\t\treplace('_START_', sStart).\n\t\t\t\t\treplace('_END_',   sEnd).\n\t\t\t\t\treplace('_MAX_',   sMax).\n\t\t\t\t\treplace('_TOTAL_', sTotal) +' '+\n\t\t\t\tlanguage.sInfoFiltered.replace(\n\t\t\t\t\t'_MAX_',\n\t\t\t\t\tdt.fnFormatNumber(dt.fnRecordsTotal())\n\t\t\t\t)+\n\t\t\t\tlanguage.sInfoPostFix;\n\t\t}\n\n\t\tvar callback = language.fnInfoCallback;\n\t\tif ( callback ) {\n\t\t\tsOut = callback.call( dt.oInstance,\n\t\t\t\tdt, iStart, iEnd, iMax, iTotal, sOut\n\t\t\t);\n\t\t}\n\n\t\tvar n = dt.aanFeatures.i;\n\t\tif ( typeof n != 'undefined' )\n\t\t{\n\t\t\tfor ( var i=0, iLen=n.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\t$(n[i]).html( sOut );\n\t\t\t}\n\t\t}\n\t}\n};\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Statics\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\n/**\n * Scroller default settings for initialisation\n *  @namespace\n *  @name Scroller.defaults\n *  @static\n */\nScroller.defaults = /** @lends Scroller.defaults */{\n\t/**\n\t * Indicate if Scroller show show trace information on the console or not. This can be\n\t * useful when debugging Scroller or if just curious as to what it is doing, but should\n\t * be turned off for production.\n\t *  @type     bool\n\t *  @default  false\n\t *  @static\n\t *  @example\n\t *    var oTable = $('#example').dataTable( {\n\t *        \"sScrollY\": \"200px\",\n\t *        \"sDom\": \"frtiS\",\n\t *        \"bDeferRender\": true,\n\t *        \"oScroller\": {\n\t *          \"trace\": true\n\t *        }\n\t *    } );\n\t */\n\t\"trace\": false,\n\n\t/**\n\t * Scroller will attempt to automatically calculate the height of rows for it's internal\n\t * calculations. However the height that is used can be overridden using this parameter.\n\t *  @type     int|string\n\t *  @default  auto\n\t *  @static\n\t *  @example\n\t *    var oTable = $('#example').dataTable( {\n\t *        \"sScrollY\": \"200px\",\n\t *        \"sDom\": \"frtiS\",\n\t *        \"bDeferRender\": true,\n\t *        \"oScroller\": {\n\t *          \"rowHeight\": 30\n\t *        }\n\t *    } );\n\t */\n\t\"rowHeight\": \"auto\",\n\n\t/**\n\t * When using server-side processing, Scroller will wait a small amount of time to allow\n\t * the scrolling to finish before requesting more data from the server. This prevents\n\t * you from DoSing your own server! The wait time can be configured by this parameter.\n\t *  @type     int\n\t *  @default  200\n\t *  @static\n\t *  @example\n\t *    var oTable = $('#example').dataTable( {\n\t *        \"sScrollY\": \"200px\",\n\t *        \"sDom\": \"frtiS\",\n\t *        \"bDeferRender\": true,\n\t *        \"oScroller\": {\n\t *          \"serverWait\": 100\n\t *        }\n\t *    } );\n\t */\n\t\"serverWait\": 200,\n\n\t/**\n\t * The display buffer is what Scroller uses to calculate how many rows it should pre-fetch\n\t * for scrolling. Scroller automatically adjusts DataTables' display length to pre-fetch\n\t * rows that will be shown in \"near scrolling\" (i.e. just beyond the current display area).\n\t * The value is based upon the number of rows that can be displayed in the viewport (i.e.\n\t * a value of 1), and will apply the display range to records before before and after the\n\t * current viewport - i.e. a factor of 3 will allow Scroller to pre-fetch 1 viewport's worth\n\t * of rows before the current viewport, the current viewport's rows and 1 viewport's worth\n\t * of rows after the current viewport. Adjusting this value can be useful for ensuring\n\t * smooth scrolling based on your data set.\n\t *  @type     int\n\t *  @default  7\n\t *  @static\n\t *  @example\n\t *    var oTable = $('#example').dataTable( {\n\t *        \"sScrollY\": \"200px\",\n\t *        \"sDom\": \"frtiS\",\n\t *        \"bDeferRender\": true,\n\t *        \"oScroller\": {\n\t *          \"displayBuffer\": 10\n\t *        }\n\t *    } );\n\t */\n\t\"displayBuffer\": 9,\n\n\t/**\n\t * Scroller uses the boundary scaling factor to decide when to redraw the table - which it\n\t * typically does before you reach the end of the currently loaded data set (in order to\n\t * allow the data to look continuous to a user scrolling through the data). If given as 0\n\t * then the table will be redrawn whenever the viewport is scrolled, while 1 would not\n\t * redraw the table until the currently loaded data has all been shown. You will want\n\t * something in the middle - the default factor of 0.5 is usually suitable.\n\t *  @type     float\n\t *  @default  0.5\n\t *  @static\n\t *  @example\n\t *    var oTable = $('#example').dataTable( {\n\t *        \"sScrollY\": \"200px\",\n\t *        \"sDom\": \"frtiS\",\n\t *        \"bDeferRender\": true,\n\t *        \"oScroller\": {\n\t *          \"boundaryScale\": 0.75\n\t *        }\n\t *    } );\n\t */\n\t\"boundaryScale\": 0.5,\n\n\t/**\n\t * Show (or not) the loading element in the background of the table. Note that you should\n\t * include the dataTables.scroller.css file for this to be displayed correctly.\n\t *  @type     boolean\n\t *  @default  false\n\t *  @static\n\t *  @example\n\t *    var oTable = $('#example').dataTable( {\n\t *        \"sScrollY\": \"200px\",\n\t *        \"sDom\": \"frtiS\",\n\t *        \"bDeferRender\": true,\n\t *        \"oScroller\": {\n\t *          \"loadingIndicator\": true\n\t *        }\n\t *    } );\n\t */\n\t\"loadingIndicator\": false\n};\n\nScroller.oDefaults = Scroller.defaults;\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Constants\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/**\n * Scroller version\n *  @type      String\n *  @default   See code\n *  @name      Scroller.version\n *  @static\n */\nScroller.version = \"1.2.2\";\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Initialisation\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/*\n * Register a new feature with DataTables\n */\nif ( typeof $.fn.dataTable == \"function\" &&\n     typeof $.fn.dataTableExt.fnVersionCheck == \"function\" &&\n     $.fn.dataTableExt.fnVersionCheck('1.9.0') )\n{\n\t$.fn.dataTableExt.aoFeatures.push( {\n\t\t\"fnInit\": function( oDTSettings ) {\n\t\t\tvar init = oDTSettings.oInit;\n\t\t\tvar opts = init.scroller || init.oScroller || {};\n\t\t\tvar oScroller = new Scroller( oDTSettings, opts );\n\t\t\treturn oScroller.dom.wrapper;\n\t\t},\n\t\t\"cFeature\": \"S\",\n\t\t\"sFeature\": \"Scroller\"\n\t} );\n}\nelse\n{\n\talert( \"Warning: Scroller requires DataTables 1.9.0 or greater - www.datatables.net/download\");\n}\n\n\n// Attach Scroller to DataTables so it can be accessed as an 'extra'\n$.fn.dataTable.Scroller = Scroller;\n$.fn.DataTable.Scroller = Scroller;\n\n\n// DataTables 1.10 API method aliases\nif ( $.fn.dataTable.Api ) {\n\tvar Api = $.fn.dataTable.Api;\n\n\tApi.register( 'scroller()', function () {\n\t\treturn this;\n\t} );\n\n\tApi.register( 'scroller().rowToPixels()', function ( rowIdx, intParse, virtual ) {\n\t\tvar ctx = this.context;\n\n\t\tif ( ctx.length && ctx[0].oScroller ) {\n\t\t\treturn ctx[0].oScroller.fnRowToPixels( rowIdx, intParse, virtual );\n\t\t}\n\t\t// undefined\n\t} );\n\n\tApi.register( 'scroller().pixelsToRow()', function ( pixels, intParse, virtual ) {\n\t\tvar ctx = this.context;\n\n\t\tif ( ctx.length && ctx[0].oScroller ) {\n\t\t\treturn ctx[0].oScroller.fnPixelsToRow( pixels, intParse, virtual );\n\t\t}\n\t\t// undefined\n\t} );\n\n\tApi.register( 'scroller().scrollToRow()', function ( row, ani ) {\n\t\tthis.iterator( 'table', function ( ctx ) {\n\t\t\tif ( ctx.oScroller ) {\n\t\t\t\tctx.oScroller.fnScrollToRow( row, ani );\n\t\t\t}\n\t\t} );\n\n\t\treturn this;\n\t} );\n\n\tApi.register( 'scroller().measure()', function ( redraw ) {\n\t\tthis.iterator( 'table', function ( ctx ) {\n\t\t\tif ( ctx.oScroller ) {\n\t\t\t\tctx.oScroller.fnMeasure( redraw );\n\t\t\t}\n\t\t} );\n\n\t\treturn this;\n\t} );\n}\n\n\nreturn Scroller;\n}; // /factory\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery && !jQuery.fn.dataTable.Scroller ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n})(window, document);\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/Readme.md",
    "content": "# TableTools\n\nTableTools is a plug-in for the DataTables HTML table enhancer, which adds a highly customisable button toolbar to a DataTable. Key features include:\n\n* Copy to clipboard\n* Save table data as CSV, XLS or PDF files\n* Print view for clean printing\n* Row selection options\n* Easy use predefined buttons\n* Simple customisation of buttons\n* Well defined API for advanced control\n\n\n# Installation\n\nTo use TableTools, first download DataTables ( http://datatables.net/download ) and place the unzipped TableTools package into a `extensions` directory in the DataTables package (in DataTables 1.9- use the `extras` directory). This will allow the pages in the examples to operate correctly. To see the examples running, open the `examples` directory in your web-browser.\n\n\n# Basic usage\n\nTableTools is initialised using the `T` option that it adds to DataTables' `dom` option. For example:\n\n```js\n$(document).ready( function () {\n\t$('#example').DataTable( {\n\t\tdom: 'T<\"clear\">lfrtip'\n\t} );\n} );\n```\n\n\n# Documentation / support\n\n* Documentation: http://datatables.net/extensions/tabletools/\n* DataTables support forums: http://datatables.net/forums\n\n\n# GitHub\n\nIf you fancy getting involved with the development of TableTools and help make it better, please refer to its GitHub repo: https://github.com/DataTables/TableTools\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/css/dataTables.tableTools.css",
    "content": "/*\n * File:        TableTools.css\n * Description: Styles for TableTools 2\n * Author:      Allan Jardine (www.sprymedia.co.uk)\n * Language:    Javascript\n * License:     GPL v2 / 3 point BSD\n * Project:     DataTables\n * \n * Copyright 2009-2012 Allan Jardine, all rights reserved.\n *\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n *\n * CSS name space:\n *   DTTT                  DataTables TableTools\n *\n * Style sheet provides:\n *   CONTAINER             TableTools container element and styles applying to all components\n *   BUTTON_STYLES         Action specific button styles\n *   SELECTING             Row selection styles\n *   COLLECTIONS           Drop down list (collection) styles\n *   PRINTING              Print display styles\n */\n\n\n/*\n * CONTAINER\n * TableTools container element and styles applying to all components\n */\ndiv.DTTT_container {\n\tposition: relative;\n\tfloat: right;\n\tmargin-bottom: 1em;\n}\n\n@media screen and (max-width: 640px) {\n\tdiv.DTTT_container {\n\t\tfloat: none !important;\n\t\ttext-align: center;\n\t}\n\n\tdiv.DTTT_container:after {\n\t\tvisibility: hidden;\n\t\tdisplay: block;\n\t\tcontent: \"\";\n\t\tclear: both;\n\t\theight: 0;\n\t}\n}\n\n\nbutton.DTTT_button,\ndiv.DTTT_button,\na.DTTT_button {\n\tposition: relative;\n\tdisplay: inline-block;\n\tmargin-right: 3px;\n\tpadding: 5px 8px;\n\tborder: 1px solid #999;\n\tcursor: pointer;\n\t*cursor: hand;\n\tfont-size: 0.88em;\n\tcolor: black !important;\n\n\t-webkit-border-radius: 2px;\n\t   -moz-border-radius: 2px;\n\t    -ms-border-radius: 2px;\n\t     -o-border-radius: 2px;\n\t        border-radius: 2px;\n\n\t-webkit-box-shadow: 1px 1px 3px #ccc;\n\t   -moz-box-shadow: 1px 1px 3px #ccc;\n\t    -ms-box-shadow: 1px 1px 3px #ccc;\n\t     -o-box-shadow: 1px 1px 3px #ccc;\n\t        box-shadow: 1px 1px 3px #ccc;\n\n\t/* Generated by http://www.colorzilla.com/gradient-editor/ */\n\tbackground: #ffffff; /* Old browsers */\n\tbackground: -webkit-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* Chrome10+,Safari5.1+ */\n\tbackground:    -moz-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* FF3.6+ */\n\tbackground:     -ms-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* IE10+ */\n\tbackground:      -o-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* Opera 11.10+ */\n\tbackground:         linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* W3C */\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#f9f9f9',GradientType=0 ); /* IE6-9 */\n}\n\n\n/* Buttons are cunning border-box sizing - we can't just use that for A and DIV due to IE6/7 */\nbutton.DTTT_button {\n\theight: 30px;\n\tpadding: 3px 8px;\n}\n\n.DTTT_button embed { \n\toutline: none;\n}\n\nbutton.DTTT_button:hover:not(.DTTT_disabled),\ndiv.DTTT_button:hover:not(.DTTT_disabled),\na.DTTT_button:hover:not(.DTTT_disabled) {\n\tborder: 1px solid #666;\n\ttext-decoration: none !important;\n\n\t-webkit-box-shadow: 1px 1px 3px #999;\n\t   -moz-box-shadow: 1px 1px 3px #999;\n\t    -ms-box-shadow: 1px 1px 3px #999;\n\t     -o-box-shadow: 1px 1px 3px #999;\n\t        box-shadow: 1px 1px 3px #999;\n\n\tbackground: #f3f3f3; /* Old browsers */\n\tbackground: -webkit-linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* Chrome10+,Safari5.1+ */\n\tbackground:    -moz-linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* FF3.6+ */\n\tbackground:     -ms-linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* IE10+ */\n\tbackground:      -o-linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* Opera 11.10+ */\n\tbackground:         linear-gradient(top, #f3f3f3 0%,#e2e2e2 89%,#f4f4f4 100%); /* W3C */\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f3f3f3', endColorstr='#f4f4f4',GradientType=0 ); /* IE6-9 */\n}\n\nbutton.DTTT_button:focus,\ndiv.DTTT_button:focus,\na.DTTT_button:focus {\n\tborder: 1px solid #426c9e;\n\ttext-shadow: 0 1px 0 #c4def1;\n\toutline: none;\n\n\tbackground-color: #a3d0ef 100%;\n\tbackground-image: -webkit-linear-gradient(top, #a3d0ef 0%, #79ace9 65%, #a3d0ef 100%);\n\tbackground-image:    -moz-linear-gradient(top, #a3d0ef 0%, #79ace9 65%, #a3d0ef 100%);\n\tbackground-image:     -ms-linear-gradient(top, #a3d0ef 0%, #79ace9 65%, #a3d0ef 100%);\n\tbackground-image:      -o-linear-gradient(top, #a3d0ef 0%, #79ace9 65%, #a3d0ef 100%);\n\tbackground-image:         linear-gradient(top, #a3d0ef 0%, #79ace9 65%, #a3d0ef 100%);\n\tfilter: progid:DXImageTransform.Microsoft.gradient(GradientType=0,StartColorStr='#a3d0ef', EndColorStr='#a3d0ef');\n}\n\nbutton.DTTT_button:active:not(.DTTT_disabled),\ndiv.DTTT_button:active:not(.DTTT_disabled),\na.DTTT_button:active:not(.DTTT_disabled) {\n\t-webkit-box-shadow: inset 1px 1px 3px #999999;\n\t-moz-box-shadow: inset 1px 1px 3px #999999;\n\tbox-shadow: inset 1px 1px 3px #999999;\n}\n\nbutton.DTTT_disabled,\ndiv.DTTT_disabled,\na.DTTT_disabled {\n\tcolor: #999 !important;\n\tborder: 1px solid #d0d0d0;\n\tcursor: default;\n\tbackground: #ffffff; /* Old browsers */\n\tbackground: -webkit-linear-gradient(top, #ffffff 0%,#f9f9f9 89%,#fafafa 100%); /* Chrome10+,Safari5.1+ */\n\tbackground:    -moz-linear-gradient(top, #ffffff 0%,#f9f9f9 89%,#fafafa 100%); /* FF3.6+ */\n\tbackground:     -ms-linear-gradient(top, #ffffff 0%,#f9f9f9 89%,#fafafa 100%); /* IE10+ */\n\tbackground:      -o-linear-gradient(top, #ffffff 0%,#f9f9f9 89%,#fafafa 100%); /* Opera 11.10+ */\n\tbackground:         linear-gradient(top, #ffffff 0%,#f9f9f9 89%,#fafafa 100%); /* W3C */\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#fafafa',GradientType=0 ); /* IE6-9 */\n}\n\n\n\n/*\n * BUTTON_STYLES\n * Action specific button styles\n * If you want images - comment this back in\n\na.DTTT_button_csv,\na.DTTT_button_xls,\na.DTTT_button_copy,\na.DTTT_button_pdf,\na.DTTT_button_print {\n\tpadding-right: 0px;\n}\n\na.DTTT_button_csv span,\na.DTTT_button_xls span,\na.DTTT_button_copy span,\na.DTTT_button_pdf span,\na.DTTT_button_print span {\n\tdisplay: inline-block;\n\theight: 24px;\n\tline-height: 24px;\n\tpadding-right: 30px;\n}\n\n\na.DTTT_button_csv span { background: url(../images/csv.png) no-repeat bottom right; }\na.DTTT_button_csv:hover span { background: url(../images/csv_hover.png) no-repeat center right; }\n\na.DTTT_button_xls span { background: url(../images/xls.png) no-repeat center right; }\na.DTTT_button_xls:hover span { background: #f0f0f0 url(../images/xls_hover.png) no-repeat center right; }\n\na.DTTT_button_copy span { background: url(../images/copy.png) no-repeat center right; }\na.DTTT_button_copy:hover span { background: #f0f0f0 url(../images/copy_hover.png) no-repeat center right; }\n\na.DTTT_button_pdf span { background: url(../images/pdf.png) no-repeat center right; }\na.DTTT_button_pdf:hover span { background: #f0f0f0 url(../images/pdf_hover.png) no-repeat center right; }\n\na.DTTT_button_print span { background: url(../images/print.png) no-repeat center right; }\na.DTTT_button_print:hover span { background: #f0f0f0 url(../images/print_hover.png) no-repeat center right; }\n\n */\n\nbutton.DTTT_button_collection span {\n\tpadding-right: 17px;\n\tbackground: url(../images/collection.png) no-repeat center right;\n}\n\nbutton.DTTT_button_collection:hover span {\n\tpadding-right: 17px;\n\tbackground: #f0f0f0 url(../images/collection_hover.png) no-repeat center right;\n}\n\n\n/*\n * SELECTING\n * Row selection styles\n */\ntable.DTTT_selectable tbody tr {\n\tcursor: pointer;\n\t*cursor: hand;\n}\n\ntable.dataTable tr.DTTT_selected.odd {\n\tbackground-color: #9FAFD1;\n}\n\ntable.dataTable tr.DTTT_selected.odd td.sorting_1 {\n\tbackground-color: #9FAFD1;\n}\n\ntable.dataTable tr.DTTT_selected.odd td.sorting_2 {\n\tbackground-color: #9FAFD1;\n}\n\ntable.dataTable tr.DTTT_selected.odd td.sorting_3 {\n\tbackground-color: #9FAFD1;\n}\n\n\ntable.dataTable tr.DTTT_selected.even {\n\tbackground-color: #B0BED9;\n}\n\ntable.dataTable tr.DTTT_selected.even td.sorting_1 {\n\tbackground-color: #B0BED9;\n}\n\ntable.dataTable tr.DTTT_selected.even td.sorting_2 {\n\tbackground-color: #B0BED9;\n}\n\ntable.dataTable tr.DTTT_selected.even td.sorting_3 {\n\tbackground-color: #B0BED9;\n}\n\n\n/*\n * COLLECTIONS\n * Drop down list (collection) styles\n */\n\ndiv.DTTT_collection {\n\twidth: 150px;\n\tpadding: 8px 8px 4px 8px;\n\tborder: 1px solid #ccc;\n\tborder: 1px solid rgba( 0, 0, 0, 0.4 );\n\tbackground-color: #f3f3f3;\n\tbackground-color: rgba( 255, 255, 255, 0.3 );\n\toverflow: hidden;\n\tz-index: 2002;\n\n\t-webkit-border-radius: 5px;\n\t   -moz-border-radius: 5px;\n\t    -ms-border-radius: 5px;\n\t     -o-border-radius: 5px;\n\t        border-radius: 5px;\n\t\n\t-webkit-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);\n\t   -moz-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);\n\t    -ms-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);\n\t     -o-box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);\n\t        box-shadow: 3px 3px 5px rgba(0, 0, 0, 0.3);\n}\n\ndiv.DTTT_collection_background {\n\tbackground: black;\n\tz-index: 2001;\n}\n\ndiv.DTTT_collection button.DTTT_button,\ndiv.DTTT_collection div.DTTT_button,\ndiv.DTTT_collection a.DTTT_button {\n\tposition: relative;\n\tleft: 0;\n\tright: 0;\n\n\tdisplay: block;\n\tfloat: none;\n\tmargin-bottom: 4px;\n\t\n\t-webkit-box-shadow: 1px 1px 3px #999;\n\t   -moz-box-shadow: 1px 1px 3px #999;\n\t    -ms-box-shadow: 1px 1px 3px #999;\n\t     -o-box-shadow: 1px 1px 3px #999;\n\t        box-shadow: 1px 1px 3px #999;\n}\n\n\n/*\n * PRINTING\n * Print display styles\n */\n\n.DTTT_print_info {\n\tposition: fixed;\n\ttop: 50%;\n\tleft: 50%;\n\twidth: 400px;\n\theight: 150px;\n\tmargin-left: -200px;\n\tmargin-top: -75px;\n\ttext-align: center;\n\tcolor: #333;\n\tpadding: 10px 30px;\n\n\tbackground: #ffffff; /* Old browsers */\n\tbackground: -webkit-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* Chrome10+,Safari5.1+ */\n\tbackground:    -moz-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* FF3.6+ */\n\tbackground:     -ms-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* IE10+ */\n\tbackground:      -o-linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* Opera 11.10+ */\n\tbackground:         linear-gradient(top, #ffffff 0%,#f3f3f3 89%,#f9f9f9 100%); /* W3C */\n\tfilter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#f9f9f9',GradientType=0 ); /* IE6-9 */\n\t\n\topacity: 0.95;\n\n\tborder: 1px solid black;\n\tborder: 1px solid rgba(0, 0, 0, 0.5);\n\t\n\t-webkit-border-radius: 6px;\n\t   -moz-border-radius: 6px;\n\t    -ms-border-radius: 6px;\n\t     -o-border-radius: 6px;\n\t        border-radius: 6px;\n\t\n\t-webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);\n\t   -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);\n\t    -ms-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);\n\t     -o-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);\n\t        box-shadow: 0 3px 7px rgba(0, 0, 0, 0.5);\n}\n\n.DTTT_print_info h6 {\n\tfont-weight: normal;\n\tfont-size: 28px;\n\tline-height: 28px;\n\tmargin: 1em;\n}\n\n.DTTT_print_info p {\n\tfont-size: 14px;\n\tline-height: 20px;\n}\n\n"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/ajax.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Ajax loaded data</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T<\"clear\">lfrtip',\n\t\t\"ajax\": \"../../../../examples/ajax/data/objects.txt\",\n\t\t\"columns\": [\n\t\t\t{ \"data\": \"name\" },\n\t\t\t{ \"data\": \"position\" },\n\t\t\t{ \"data\": \"office\" },\n\t\t\t{ \"data\": \"extn\" },\n\t\t\t{ \"data\": \"start_date\" },\n\t\t\t{ \"data\": \"salary\" }\n\t\t],\n\t\tdeferRender: true\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Ajax loaded data</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This TableTools example shows DataTables using its ability to <a href=\"//datatables.net/manual/data#Objects\">Ajax load object based data</a> and operate in\n\t\t\t\texactly the same manner as when the data is read directly from the document.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Extn.</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T&lt;&quot;clear&quot;&gt;lfrtip',\n\t\t&quot;ajax&quot;: &quot;../../../../examples/ajax/data/objects.txt&quot;,\n\t\t&quot;columns&quot;: [\n\t\t\t{ &quot;data&quot;: &quot;name&quot; },\n\t\t\t{ &quot;data&quot;: &quot;position&quot; },\n\t\t\t{ &quot;data&quot;: &quot;office&quot; },\n\t\t\t{ &quot;data&quot;: &quot;extn&quot; },\n\t\t\t{ &quot;data&quot;: &quot;start_date&quot; },\n\t\t\t{ &quot;data&quot;: &quot;salary&quot; }\n\t\t],\n\t\tdeferRender: true\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/alter_buttons.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Button arrangement</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T<\"clear\">lfrtip',\n\t\ttableTools: {\n\t\t\t\"aButtons\": [ \"copy\", \"print\" ]\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Button arrangement</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>TableTools makes it very simple to arrange the buttons in the toolbar as you see fit. Using the <code>aButtons</code> parameter you can use any of the <a href=\n\t\t\t\t\"http://datatables.net/extensions/tabletools/buttons\">predefined buttons</a> or <a href=\"http://datatables.net/extensions/tabletools/button_options\">customised\n\t\t\t\tbuttons</a>. The example below shows how TableTools can be initialised to provide only the 'copy-to-clipboard' and 'print view' options (i.e. no save to local file\n\t\t\t\toption is available).</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T&lt;&quot;clear&quot;&gt;lfrtip',\n\t\ttableTools: {\n\t\t\t&quot;aButtons&quot;: [ &quot;copy&quot;, &quot;print&quot; ]\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/bootstrap.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Bootstrap styling</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../Plugins/integration/bootstrap/3/dataTables.bootstrap.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\tbody { font-size: 140%; }\n\tdiv.DTTT { margin-bottom: 0.5em; float: right; }\n\tdiv.dataTables_wrapper { clear: both; }\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../Plugins/integration/bootstrap/3/dataTables.bootstrap.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\tvar tt = new $.fn.dataTable.TableTools( table );\n\n\t$( tt.fnContainer() ).insertBefore('div.dataTables_wrapper');\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Bootstrap styling</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p><a href=\"http://twitter.github.com/bootstrap/\">Twitter Bootstrap</a> is a very powerful design framework for allowing you to very quickly create applications\n\t\t\t\twith a unified look and feel. <a href=\"http://datatables.net/manual/styling/bootstrap\">DataTables integrates well</a> with Bootstrap, and so does TableTools.</p>\n\n\t\t\t\t<p>This example shows the default Bootstrap theme being used with a Bootstrap styled DataTable. The <a href=\"new_init.html\"><code>new</code></a> form of\n\t\t\t\tinitialising TableTools is used here, as the Bootstrap integration uses a complex <a href=\"//datatables.net/reference/option/dom\"><code class=\"option\" title=\n\t\t\t\t\"DataTables initialisation option\">dom<span>DT</span></code></a> option (it is possible to provide a custom <a href=\n\t\t\t\t\"//datatables.net/reference/option/dom\"><code class=\"option\" title=\"DataTables initialisation option\">dom<span>DT</span></code></a> option if you want to, this is\n\t\t\t\tjust for simplicity!).</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"table table-striped table-bordered\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\tvar tt = new $.fn.dataTable.TableTools( table );\n\n\t$( tt.fnContainer() ).insertBefore('div.dataTables_wrapper');\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../Plugins/integration/bootstrap/3/dataTables.bootstrap.js\">../../Plugins/integration/bootstrap/3/dataTables.bootstrap.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">body { font-size: 140%; }\n\tdiv.DTTT { margin-bottom: 0.5em; float: right; }\n\tdiv.dataTables_wrapper { clear: both; }</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css\">//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../Plugins/integration/bootstrap/3/dataTables.bootstrap.css\">../../Plugins/integration/bootstrap/3/dataTables.bootstrap.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/button_text.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Custom button text</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t\"dom\": 'T<\"clear\">lfrtip',\n\t\t\"tableTools\": {\n\t\t\t\"aButtons\": [\n\t\t\t\t{\n\t\t\t\t\t\"sExtends\": \"copy\",\n\t\t\t\t\t\"sButtonText\": \"Copy to clipboard\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"sExtends\": \"csv\",\n\t\t\t\t\t\"sButtonText\": \"Save to CSV\"\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t\"sExtends\": \"xls\",\n\t\t\t\t\t\"oSelectorOpts\": {\n\t\t\t\t\t\tpage: 'current'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Custom button text</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>You may wish to set your own text for the buttons in the TableTools toolbar, rather than relying on the default built-in text. This is done by overriding the\n\t\t\t\t<code>sButtonText</code> parameter of whatever button you wish to alter. The way TableTools allows you to alter a predefined button is by 'extending' it (using the\n\t\t\t\t<code>sExtends</code> parameter) and then setting the overriding parameter.</p>\n\n\t\t\t\t<p>A full list of the parameters which can be used is <a href=\"http://datatables.net/extensions/tabletools/button_options\">available on the DataTables.net\n\t\t\t\tweb-site</a>. This example shows how to set the button text as required.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t&quot;dom&quot;: 'T&lt;&quot;clear&quot;&gt;lfrtip',\n\t\t&quot;tableTools&quot;: {\n\t\t\t&quot;aButtons&quot;: [\n\t\t\t\t{\n\t\t\t\t\t&quot;sExtends&quot;: &quot;copy&quot;,\n\t\t\t\t\t&quot;sButtonText&quot;: &quot;Copy to clipboard&quot;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t&quot;sExtends&quot;: &quot;csv&quot;,\n\t\t\t\t\t&quot;sButtonText&quot;: &quot;Save to CSV&quot;\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t&quot;sExtends&quot;: &quot;xls&quot;,\n\t\t\t\t\t&quot;oSelectorOpts&quot;: {\n\t\t\t\t\t\tpage: 'current'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/collection.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Button collections</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t\"dom\": 'T<\"clear\">lfrtip',\n\t\t\"tableTools\": {\n\t\t\t\"aButtons\": [\n\t\t\t\t\"copy\",\n\t\t\t\t\"print\",\n\t\t\t\t{\n\t\t\t\t\t\"sExtends\":    \"collection\",\n\t\t\t\t\t\"sButtonText\": \"Save\",\n\t\t\t\t\t\"aButtons\":    [ \"csv\", \"xls\", \"pdf\" ]\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Button collections</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>TableTools provides the ability to group buttons into a hidden drop down list, which is activated by clicking on a top-level button. This is achieved by\n\t\t\t\textending the 'collection' predefined button type and setting it's <code>aButtons</code> parameter with the same options as the top level buttons (note that you\n\t\t\t\tcannot currently use a collection within a collection).</p>\n\n\t\t\t\t<p>The example below shows the file save buttons grouped into a collection, while the copy and print buttons are left on the top level.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\t&quot;dom&quot;: 'T&lt;&quot;clear&quot;&gt;lfrtip',\n\t\t&quot;tableTools&quot;: {\n\t\t\t&quot;aButtons&quot;: [\n\t\t\t\t&quot;copy&quot;,\n\t\t\t\t&quot;print&quot;,\n\t\t\t\t{\n\t\t\t\t\t&quot;sExtends&quot;:    &quot;collection&quot;,\n\t\t\t\t\t&quot;sButtonText&quot;: &quot;Save&quot;,\n\t\t\t\t\t&quot;aButtons&quot;:    [ &quot;csv&quot;, &quot;xls&quot;, &quot;pdf&quot; ]\n\t\t\t\t}\n\t\t\t]\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/defaults.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Defaults</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$.fn.dataTable.TableTools.defaults.aButtons = [ \"copy\", \"csv\", \"xls\" ];\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T<\"clear\">lfrtip'\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Defaults</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>TableTools provides the ability to override the default initialisation parameters that are used when creating a new instance. This this particularly useful if\n\t\t\t\tyou have multiple tables which you want to have the same TableTools behaviour - rather than declaring the structure multiple times, you can just set the defaults\n\t\t\t\tonce. This example shows how to alter the default buttons.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$.fn.dataTable.TableTools.defaults.aButtons = [ &quot;copy&quot;, &quot;csv&quot;, &quot;xls&quot; ];\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T&lt;&quot;clear&quot;&gt;lfrtip'\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\n\t<title>TableTools examples - TableTools examples</title>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>TableTools examples</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>TableTools is a plug-in for the DataTables HTML table enhancer, which adds a highly customisable button toolbar to a DataTable. Key features include:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li>Copy to clipboard</li>\n\t\t\t\t\t<li>Save table data as CSV, XLS or PDF files</li>\n\t\t\t\t\t<li>Print view for clean printing</li>\n\t\t\t\t\t<li>Row selection options</li>\n\t\t\t\t\t<li>Easy use predefined buttons</li>\n\t\t\t\t\t<li>Simple customisation of buttons</li>\n\t\t\t\t\t<li>Well defined API for advanced control</li>\n\t\t\t\t</ul>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/jqueryui.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - jQuery UI styling</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../Plugins/integration/jqueryui/dataTables.jqueryui.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../Plugins/integration/jqueryui/dataTables.jqueryui.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tlengthChange: false\n\t} );\n\n\tvar tt = new $.fn.dataTable.TableTools( table );\n\t$( tt.fnContainer() ).insertBefore('div.dataTables_filter');\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>jQuery UI styling</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows the TableTools buttons being styled by jQuery UI ThemeRoller. This allows the TableTools buttons to have the same look-and-feel as other\n\t\t\t\tbuttons on your site if you are already using jQuery UI.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable( {\n\t\tlengthChange: false\n\t} );\n\n\tvar tt = new $.fn.dataTable.TableTools( table );\n\t$( tt.fnContainer() ).insertBefore('div.dataTables_filter');\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../Plugins/integration/jqueryui/dataTables.jqueryui.js\">../../Plugins/integration/jqueryui/dataTables.jqueryui.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css\">//code.jquery.com/ui/1.11.2/themes/smoothness/jquery-ui.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../../Plugins/integration/jqueryui/dataTables.jqueryui.css\">../../Plugins/integration/jqueryui/dataTables.jqueryui.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/multi_instance.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Multiple toolbars</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T<\"clear\">lfrtip<\"clear spacer\">T',\n\t\ttableTools: {\n\t\t\t\"aButtons\": [ \"copy\", \"print\" ]\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Multiple toolbars</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Like all DataTables control elements, TableTools can have multiple instances specified in the <a href=\"//datatables.net/reference/option/dom\"><code class=\n\t\t\t\t\"option\" title=\"DataTables initialisation option\">dom<span>DT</span></code></a> parameter of DataTables. This will create two TableTools toolbars next to the\n\t\t\t\ttable, providing the same functions.</p>\n\n\t\t\t\t<p>An example of when this might be useful is to show the toolbar both above and below the table - as is done in this example.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T&lt;&quot;clear&quot;&gt;lfrtip&lt;&quot;clear spacer&quot;&gt;T',\n\t\ttableTools: {\n\t\t\t&quot;aButtons&quot;: [ &quot;copy&quot;, &quot;print&quot; ]\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/multiple_tables.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Multiple tables</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T<\"clear\">lfrtip'\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Multiple tables</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows how multiple tables can be initialised with DataTables and TableTools in a single call to the <code>$().DataTable()</code> function.\n\t\t\t\tBasically it works as you would expect - no special considerations need be made!</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<table id=\"\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T&lt;&quot;clear&quot;&gt;lfrtip'\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/new_init.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Initialisation with `new`</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\tvar tt = new $.fn.dataTable.TableTools( table, {\n\t\tsRowSelect: 'single'\n\t} );\n\n\t$( tt.fnContainer() ).insertAfter('div.info');\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Initialisation with `new`</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>Typically when working with TableTools, the initialisation and insertion into the DOM will be done automatically by DataTables, through the use of the <a href=\n\t\t\t\t\"//datatables.net/reference/option/dom\"><code class=\"option\" title=\"DataTables initialisation option\">dom<span>DT</span></code></a> parameter. However, it is also\n\t\t\t\tpossible to initialise TableTools manually as shown in the example below using <code>new $.fn.dataTable.TableTools();</code>. The constructor for TableTools takes\n\t\t\t\ttwo parameters:</p>\n\n\t\t\t\t<ol class=\"markdown\">\n\t\t\t\t\t<li>The DataTable that the newly created TableTools instance should attach to</li>\n\t\t\t\t\t<li>Optionally - A list of options</li>\n\t\t\t\t</ol>\n\n\t\t\t\t<p>Once initialised you can insert the TableTools tool bar node anywhere you wish into the DOM using the <code>fnContainer()</code> API method to get the node.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\tvar table = $('#example').DataTable();\n\tvar tt = new $.fn.dataTable.TableTools( table, {\n\t\tsRowSelect: 'single'\n\t} );\n\n\t$( tt.fnContainer() ).insertAfter('div.info');\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/pdf_message.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - PDF message</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T<\"clear\">lfrtip',\n\t\ttableTools: {\n\t\t\t\"aButtons\": [\n\t\t\t\t\"copy\",\n\t\t\t\t\"csv\",\n\t\t\t\t\"xls\",\n\t\t\t\t{\n\t\t\t\t\t\"sExtends\": \"pdf\",\n\t\t\t\t\t\"sPdfOrientation\": \"landscape\",\n\t\t\t\t\t\"sPdfMessage\": \"Your custom message would go here.\"\n\t\t\t\t},\n\t\t\t\t\"print\"\n\t\t\t]\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>PDF message</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows how you can add a message to the saved PDF using the <code>sPdfMessage</code> parameter. It also shows that the orientation of the output PDF\n\t\t\t\tcan be changed to landscape which is useful if you have a lot of columns.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T&lt;&quot;clear&quot;&gt;lfrtip',\n\t\ttableTools: {\n\t\t\t&quot;aButtons&quot;: [\n\t\t\t\t&quot;copy&quot;,\n\t\t\t\t&quot;csv&quot;,\n\t\t\t\t&quot;xls&quot;,\n\t\t\t\t{\n\t\t\t\t\t&quot;sExtends&quot;: &quot;pdf&quot;,\n\t\t\t\t\t&quot;sPdfOrientation&quot;: &quot;landscape&quot;,\n\t\t\t\t\t&quot;sPdfMessage&quot;: &quot;Your custom message would go here.&quot;\n\t\t\t\t},\n\t\t\t\t&quot;print&quot;\n\t\t\t]\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/plug-in.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Plug-in button types</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$.fn.dataTable.TableTools.buttons.copy_to_div = $.extend(\n\ttrue,\n\t{},\n\t$.fn.dataTable.TableTools.buttonBase,\n\t{\n\t\t\"sNewLine\":    \"<br>\",\n\t\t\"sButtonText\": \"Copy to element\",\n\t\t\"target\":      \"\",\n\t\t\"fnClick\": function( button, conf ) {\n\t\t\t$(conf.target).html( this.fnGetTableData(conf) );\n\t\t}\n\t}\n);\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T<\"clear\">lfrtip',\n\t\ttableTools: {\n\t\t\t\"aButtons\": [ {\n\t\t\t\t\"sExtends\":    \"copy_to_div\",\n\t\t\t\t\"sButtonText\": \"Copy to HTML\",\n\t\t\t\t\"target\":      \"#copy\"\n\t\t\t} ]\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Plug-in button types</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows now a plug-in button type can be created for TableTools. Button types are attached to the <code>$.fn.dataTable.TableTools.buttons</code>\n\t\t\t\tobject and extend <code>$.fn.dataTable.TableTools.buttonBase</code>. All of the <a href=\"//datatables.net/extensions/tabletools/button_options\">button options\n\t\t\t\tdefined in the documentation</a> are available and can be overridden as required. Finally to use the button simply include its name in the <code>aButtons</code>\n\t\t\t\tarray or use it as a button extender (<code>sExtends</code>).</p>\n\n\t\t\t\t<p>This example shows a button which will simply get the data contents of a table and set that as the contents of another element.</p>\n\t\t\t</div>\n\n\t\t\t<div id=\"copy\" class=\"box\" style=\"height: 100px; overflow: auto\">\n\t\t\t\tCopy output will go here\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$.fn.dataTable.TableTools.buttons.copy_to_div = $.extend(\n\ttrue,\n\t{},\n\t$.fn.dataTable.TableTools.buttonBase,\n\t{\n\t\t&quot;sNewLine&quot;:    &quot;&lt;br&gt;&quot;,\n\t\t&quot;sButtonText&quot;: &quot;Copy to element&quot;,\n\t\t&quot;target&quot;:      &quot;&quot;,\n\t\t&quot;fnClick&quot;: function( button, conf ) {\n\t\t\t$(conf.target).html( this.fnGetTableData(conf) );\n\t\t}\n\t}\n);\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T&lt;&quot;clear&quot;&gt;lfrtip',\n\t\ttableTools: {\n\t\t\t&quot;aButtons&quot;: [ {\n\t\t\t\t&quot;sExtends&quot;:    &quot;copy_to_div&quot;,\n\t\t\t\t&quot;sButtonText&quot;: &quot;Copy to HTML&quot;,\n\t\t\t\t&quot;target&quot;:      &quot;#copy&quot;\n\t\t\t} ]\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/select_column.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Row selection - row selector on specific cells</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\ttr td:first-child {\n\t\ttext-align: center;\n\t}\n\n\ttr td:first-child:before {\n\t\tcontent: \"\\f096\"; /* fa-square-o */\n\t\tfont-family: FontAwesome;\n\t}\n\n\ttr.selected td:first-child:before {\n\t\tcontent: \"\\f046\"; /* fa-check-square-o */\n\t}\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tajax: \"../../../examples/ajax/data/objects.txt\",\n\t\tcolumns: [\n\t\t\t{ data: null, defaultContent: '', orderable: false },\n\t\t\t{ data: 'name' },\n\t\t\t{ data: 'position' },\n\t\t\t{ data: 'office' },\n\t\t\t{ data: 'extn' },\n\t\t\t{ data: 'start_date' },\n\t\t\t{ data: 'salary' }\n\t\t],\n\t\torder: [ 1, 'asc' ],\n\t\tdom: 'T<\"clear\">lfrtip',\n\t\ttableTools: {\n\t\t\tsRowSelect:   'os',\n\t\t\tsRowSelector: 'td:first-child',\n\t\t\taButtons:     [ 'select_all', 'select_none' ]\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Row selection - row selector on specific cells</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>By default, TableTools' row selector option will register a row selection click on any part of the row. Although this is often desirable, you might wish at\n\t\t\t\ttimes to limit the row selection to just a single column, or other elements in the row. This might be useful, for example, with <a href=\n\t\t\t\t\"//editor.datatables.net\">Editor's</a> inline editing, so you don't select the row on click of a cell that is to be edited.</p>\n\n\t\t\t\t<p>The <code>sRowSelector</code> method provides this ability, allowing a custom jQuery selector to be passed in. TableTools will use the parent row of any element\n\t\t\t\tthat is selected by the end user.</p>\n\n\t\t\t\t<p>In this case, the row selector is attached to the cells in the first column of the table, and <a href=\"http://fortawesome.github.io/Font-Awesome\">Font\n\t\t\t\tAwesome</a> is used to display a checkbox indicating the selection state of the row, in addition to the row background colouring.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>\n\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tajax: &quot;../../../examples/ajax/data/objects.txt&quot;,\n\t\tcolumns: [\n\t\t\t{ data: null, defaultContent: '', orderable: false },\n\t\t\t{ data: 'name' },\n\t\t\t{ data: 'position' },\n\t\t\t{ data: 'office' },\n\t\t\t{ data: 'extn' },\n\t\t\t{ data: 'start_date' },\n\t\t\t{ data: 'salary' }\n\t\t],\n\t\torder: [ 1, 'asc' ],\n\t\tdom: 'T&lt;&quot;clear&quot;&gt;lfrtip',\n\t\ttableTools: {\n\t\t\tsRowSelect:   'os',\n\t\t\tsRowSelector: 'td:first-child',\n\t\t\taButtons:     [ 'select_all', 'select_none' ]\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\">tr td:first-child {\n\t\ttext-align: center;\n\t}\n\n\ttr td:first-child:before {\n\t\tcontent: &quot;\\f096&quot;; /* fa-square-o */\n\t\tfont-family: FontAwesome;\n\t}\n\n\ttr.selected td:first-child:before {\n\t\tcontent: &quot;\\f046&quot;; /* fa-check-square-o */\n\t}</code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t\t<li><a href=\n\t\t\t\t\t\t\"//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.css\">//cdnjs.cloudflare.com/ajax/libs/font-awesome/4.0.3/css/font-awesome.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/select_multi.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Row selection - multi-row select</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T<\"clear\">lfrtip',\n\t\ttableTools: {\n\t\t\t\"sRowSelect\": \"multi\",\n\t\t\t\"aButtons\": [ \"select_all\", \"select_none\" ]\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Row selection - multi-row select</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>As well as providing a button toolbar, TableTools provides everything needed to have selectable rows in the table. TableTools has four row selection modes of\n\t\t\t\toperation:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li><code>none</code> - Default, where no user row selection options are available</li>\n\t\t\t\t\t<li><code>single</code> - A single row can be selected</li>\n\t\t\t\t\t<li><code>multi</code> - Multiple rows can be selected simply by clicking on the rows</li>\n\t\t\t\t\t<li><code>os</code> - Operating System like selection where you can use the shift and ctrl / cmd keys on your keyboard to add / remove rows from the\n\t\t\t\t\tselection.</li>\n\t\t\t\t</ul>\n\n\t\t\t\t<p>This example shows the <code>multi</code> select option. There are also a number of <a href=\"http://datatables.net/extras/tabletools/buttons\">pre-defined\n\t\t\t\tbuttons</a> to provide functions such as select-all and select-none, as shown in this example.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T&lt;&quot;clear&quot;&gt;lfrtip',\n\t\ttableTools: {\n\t\t\t&quot;sRowSelect&quot;: &quot;multi&quot;,\n\t\t\t&quot;aButtons&quot;: [ &quot;select_all&quot;, &quot;select_none&quot; ]\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/select_os.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Row selection - operating system style</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T<\"clear\">lfrtip',\n\t\ttableTools: {\n\t\t\t\"sRowSelect\": \"os\",\n\t\t\t\"aButtons\": [ \"select_all\", \"select_none\" ]\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Row selection - operating system style</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>As well as providing a button toolbar, TableTools provides everything needed to have selectable rows in the table. TableTools has four row selection modes of\n\t\t\t\toperation:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li><code>none</code> - Default, where no user row selection options are available</li>\n\t\t\t\t\t<li><code>single</code> - A single row can be selected</li>\n\t\t\t\t\t<li><code>multi</code> - Multiple rows can be selected simply by clicking on the rows</li>\n\t\t\t\t\t<li><code>os</code> - Operating System like selection where you can use the shift and ctrl / cmd keys on your keyboard to add / remove rows from the\n\t\t\t\t\tselection.</li>\n\t\t\t\t</ul>\n\n\t\t\t\t<p>This example shows the <code>os</code> select option. Without keyboard interaction a single row can be selected at a time, but multiple rows can be selected in\n\t\t\t\ta range using the shift key, while rows can be added and removed from the selection using the ctrl / cmd key.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T&lt;&quot;clear&quot;&gt;lfrtip',\n\t\ttableTools: {\n\t\t\t&quot;sRowSelect&quot;: &quot;os&quot;,\n\t\t\t&quot;aButtons&quot;: [ &quot;select_all&quot;, &quot;select_none&quot; ]\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/select_single.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Row selection - single row select</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T<\"clear\">lfrtip',\n\t\ttableTools: {\n\t\t\t\"sRowSelect\": \"single\"\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Row selection - single row select</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>As well as providing a button toolbar, TableTools provides everything needed to have selectable rows in the table. TableTools has four row selection modes of\n\t\t\t\toperation:</p>\n\n\t\t\t\t<ul class=\"markdown\">\n\t\t\t\t\t<li><code>none</code> - Default, where no user row selection options are available</li>\n\t\t\t\t\t<li><code>single</code> - A single row can be selected</li>\n\t\t\t\t\t<li><code>multi</code> - Multiple rows can be selected simply by clicking on the rows</li>\n\t\t\t\t\t<li><code>os</code> - Operating System like selection where you can use the shift and ctrl / cmd keys on your keyboard to add / remove rows from the\n\t\t\t\t\tselection.</li>\n\t\t\t\t</ul>\n\n\t\t\t\t<p>This example shows the <code>single</code> select option.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T&lt;&quot;clear&quot;&gt;lfrtip',\n\t\ttableTools: {\n\t\t\t&quot;sRowSelect&quot;: &quot;single&quot;\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/simple.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Basic initialisation</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T<\"clear\">lfrtip'\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Basic initialisation</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>This example shows the basic initialisation of TableTools by simply including the <code class=\"string\" title=\"String\">T</code> option in DataTables' <a href=\n\t\t\t\t\"//datatables.net/reference/option/dom\"><code class=\"option\" title=\"DataTables initialisation option\">dom<span>DT</span></code></a> parameter. This tell DataTables\n\t\t\t\tto insert the TableTools toolbar in that location. Remember to include the Javascript and CSS source files as well!</p>\n\n\t\t\t\t<p>It is worth noting that you might need to <a href=\"swf_path.html\">set the <code>sSwfPath</code> parameter</a> to tell TableTools where to find the SWF file for\n\t\t\t\tcopy and file save.</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T&lt;&quot;clear&quot;&gt;lfrtip'\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/examples/swf_path.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"utf-8\">\n\t<link rel=\"shortcut icon\" type=\"image/ico\" href=\"http://www.datatables.net/favicon.ico\">\n\t<meta name=\"viewport\" content=\"initial-scale=1.0, maximum-scale=2.0\">\n\n\t<title>TableTools example - Setting the SWF path</title>\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../media/css/jquery.dataTables.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../css/dataTables.tableTools.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/syntax/shCore.css\">\n\t<link rel=\"stylesheet\" type=\"text/css\" href=\"../../../examples/resources/demo.css\">\n\t<style type=\"text/css\" class=\"init\">\n\n\t</style>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../media/js/jquery.dataTables.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../js/dataTables.tableTools.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/syntax/shCore.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" src=\"../../../examples/resources/demo.js\"></script>\n\t<script type=\"text/javascript\" language=\"javascript\" class=\"init\">\n\n\n$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T<\"clear\">lfrtip',\n\t\ttableTools: {\n\t\t\t\"sSwfPath\": \"../swf/copy_csv_xls_pdf.swf\"\n\t\t}\n\t} );\n} );\n\n\n\t</script>\n</head>\n\n<body class=\"dt-example\">\n\t<div class=\"container\">\n\t\t<section>\n\t\t\t<h1>TableTools example <span>Setting the SWF path</span></h1>\n\n\t\t\t<div class=\"info\">\n\t\t\t\t<p>TableTools uses a Flash SWF file to provide the ability to copy text to the system clipboard and save files locally. TableTools must be able to load the SWF\n\t\t\t\tfile in order to provide these facilities. If you aren't using the same directory structure as the TableTools package, you will need to set the\n\t\t\t\t<code>sSwfPath</code> TableTools parameter, as shown in this example.</p>\n\n\t\t\t\t<p>Note that TableTools ships with two different SWF files - the only difference between them is that one of them provides the ability to save PDF files while the\n\t\t\t\tother doesn't. The trade off is that the PDF capable file is significantly larger in size (56K v 2K).</p>\n\t\t\t</div>\n\n\t\t\t<table id=\"example\" class=\"display\" cellspacing=\"0\" width=\"100%\">\n\t\t\t\t<thead>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</thead>\n\n\t\t\t\t<tfoot>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<th>Name</th>\n\t\t\t\t\t\t<th>Position</th>\n\t\t\t\t\t\t<th>Office</th>\n\t\t\t\t\t\t<th>Age</th>\n\t\t\t\t\t\t<th>Start date</th>\n\t\t\t\t\t\t<th>Salary</th>\n\t\t\t\t\t</tr>\n\t\t\t\t</tfoot>\n\n\t\t\t\t<tbody>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tiger Nixon</td>\n\t\t\t\t\t\t<td>System Architect</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2011/04/25</td>\n\t\t\t\t\t\t<td>$320,800</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Garrett Winters</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2011/07/25</td>\n\t\t\t\t\t\t<td>$170,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Ashton Cox</td>\n\t\t\t\t\t\t<td>Junior Technical Author</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2009/01/12</td>\n\t\t\t\t\t\t<td>$86,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cedric Kelly</td>\n\t\t\t\t\t\t<td>Senior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2012/03/29</td>\n\t\t\t\t\t\t<td>$433,060</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Airi Satou</td>\n\t\t\t\t\t\t<td>Accountant</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>33</td>\n\t\t\t\t\t\t<td>2008/11/28</td>\n\t\t\t\t\t\t<td>$162,700</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brielle Williamson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2012/12/02</td>\n\t\t\t\t\t\t<td>$372,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Herrod Chandler</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2012/08/06</td>\n\t\t\t\t\t\t<td>$137,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Rhona Davidson</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>55</td>\n\t\t\t\t\t\t<td>2010/10/14</td>\n\t\t\t\t\t\t<td>$327,900</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Colleen Hurst</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>39</td>\n\t\t\t\t\t\t<td>2009/09/15</td>\n\t\t\t\t\t\t<td>$205,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sonya Frost</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2008/12/13</td>\n\t\t\t\t\t\t<td>$103,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jena Gaines</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2008/12/19</td>\n\t\t\t\t\t\t<td>$90,560</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Quinn Flynn</td>\n\t\t\t\t\t\t<td>Support Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2013/03/03</td>\n\t\t\t\t\t\t<td>$342,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Charde Marshall</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>36</td>\n\t\t\t\t\t\t<td>2008/10/16</td>\n\t\t\t\t\t\t<td>$470,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Haley Kennedy</td>\n\t\t\t\t\t\t<td>Senior Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2012/12/18</td>\n\t\t\t\t\t\t<td>$313,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Tatyana Fitzpatrick</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>19</td>\n\t\t\t\t\t\t<td>2010/03/17</td>\n\t\t\t\t\t\t<td>$385,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Silva</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>66</td>\n\t\t\t\t\t\t<td>2012/11/27</td>\n\t\t\t\t\t\t<td>$198,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Paul Byrd</td>\n\t\t\t\t\t\t<td>Chief Financial Officer (CFO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2010/06/09</td>\n\t\t\t\t\t\t<td>$725,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gloria Little</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>59</td>\n\t\t\t\t\t\t<td>2009/04/10</td>\n\t\t\t\t\t\t<td>$237,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bradley Greer</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2012/10/13</td>\n\t\t\t\t\t\t<td>$132,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Dai Rios</td>\n\t\t\t\t\t\t<td>Personnel Lead</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>35</td>\n\t\t\t\t\t\t<td>2012/09/26</td>\n\t\t\t\t\t\t<td>$217,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jenette Caldwell</td>\n\t\t\t\t\t\t<td>Development Lead</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2011/09/03</td>\n\t\t\t\t\t\t<td>$345,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Yuri Berry</td>\n\t\t\t\t\t\t<td>Chief Marketing Officer (CMO)</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>40</td>\n\t\t\t\t\t\t<td>2009/06/25</td>\n\t\t\t\t\t\t<td>$675,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Caesar Vance</td>\n\t\t\t\t\t\t<td>Pre-Sales Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2011/12/12</td>\n\t\t\t\t\t\t<td>$106,450</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Doris Wilder</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>23</td>\n\t\t\t\t\t\t<td>2010/09/20</td>\n\t\t\t\t\t\t<td>$85,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Angelica Ramos</td>\n\t\t\t\t\t\t<td>Chief Executive Officer (CEO)</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/10/09</td>\n\t\t\t\t\t\t<td>$1,200,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Joyce</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>42</td>\n\t\t\t\t\t\t<td>2010/12/22</td>\n\t\t\t\t\t\t<td>$92,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Chang</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2010/11/14</td>\n\t\t\t\t\t\t<td>$357,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Brenden Wagner</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>28</td>\n\t\t\t\t\t\t<td>2011/06/07</td>\n\t\t\t\t\t\t<td>$206,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Fiona Green</td>\n\t\t\t\t\t\t<td>Chief Operating Officer (COO)</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>48</td>\n\t\t\t\t\t\t<td>2010/03/11</td>\n\t\t\t\t\t\t<td>$850,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shou Itou</td>\n\t\t\t\t\t\t<td>Regional Marketing</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>20</td>\n\t\t\t\t\t\t<td>2011/08/14</td>\n\t\t\t\t\t\t<td>$163,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michelle House</td>\n\t\t\t\t\t\t<td>Integration Specialist</td>\n\t\t\t\t\t\t<td>Sidney</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2011/06/02</td>\n\t\t\t\t\t\t<td>$95,400</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Suki Burks</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>53</td>\n\t\t\t\t\t\t<td>2009/10/22</td>\n\t\t\t\t\t\t<td>$114,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Prescott Bartlett</td>\n\t\t\t\t\t\t<td>Technical Author</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/05/07</td>\n\t\t\t\t\t\t<td>$145,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Gavin Cortez</td>\n\t\t\t\t\t\t<td>Team Leader</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>22</td>\n\t\t\t\t\t\t<td>2008/10/26</td>\n\t\t\t\t\t\t<td>$235,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Martena Mccray</td>\n\t\t\t\t\t\t<td>Post-Sales support</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/03/09</td>\n\t\t\t\t\t\t<td>$324,050</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Unity Butler</td>\n\t\t\t\t\t\t<td>Marketing Designer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/12/09</td>\n\t\t\t\t\t\t<td>$85,675</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Howard Hatfield</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/12/16</td>\n\t\t\t\t\t\t<td>$164,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hope Fuentes</td>\n\t\t\t\t\t\t<td>Secretary</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>41</td>\n\t\t\t\t\t\t<td>2010/02/12</td>\n\t\t\t\t\t\t<td>$109,850</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Vivian Harrell</td>\n\t\t\t\t\t\t<td>Financial Controller</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>62</td>\n\t\t\t\t\t\t<td>2009/02/14</td>\n\t\t\t\t\t\t<td>$452,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Timothy Mooney</td>\n\t\t\t\t\t\t<td>Office Manager</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2008/12/11</td>\n\t\t\t\t\t\t<td>$136,200</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jackson Bradshaw</td>\n\t\t\t\t\t\t<td>Director</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>65</td>\n\t\t\t\t\t\t<td>2008/09/26</td>\n\t\t\t\t\t\t<td>$645,750</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Olivia Liang</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2011/02/03</td>\n\t\t\t\t\t\t<td>$234,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Bruno Nash</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>38</td>\n\t\t\t\t\t\t<td>2011/05/03</td>\n\t\t\t\t\t\t<td>$163,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Sakura Yamamoto</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>Tokyo</td>\n\t\t\t\t\t\t<td>37</td>\n\t\t\t\t\t\t<td>2009/08/19</td>\n\t\t\t\t\t\t<td>$139,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Thor Walton</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>61</td>\n\t\t\t\t\t\t<td>2013/08/11</td>\n\t\t\t\t\t\t<td>$98,540</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Finn Camacho</td>\n\t\t\t\t\t\t<td>Support Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2009/07/07</td>\n\t\t\t\t\t\t<td>$87,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Serge Baldwin</td>\n\t\t\t\t\t\t<td>Data Coordinator</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>64</td>\n\t\t\t\t\t\t<td>2012/04/09</td>\n\t\t\t\t\t\t<td>$138,575</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zenaida Frank</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>63</td>\n\t\t\t\t\t\t<td>2010/01/04</td>\n\t\t\t\t\t\t<td>$125,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Zorita Serrano</td>\n\t\t\t\t\t\t<td>Software Engineer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>56</td>\n\t\t\t\t\t\t<td>2012/06/01</td>\n\t\t\t\t\t\t<td>$115,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jennifer Acosta</td>\n\t\t\t\t\t\t<td>Junior Javascript Developer</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>43</td>\n\t\t\t\t\t\t<td>2013/02/01</td>\n\t\t\t\t\t\t<td>$75,650</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Cara Stevens</td>\n\t\t\t\t\t\t<td>Sales Assistant</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>46</td>\n\t\t\t\t\t\t<td>2011/12/06</td>\n\t\t\t\t\t\t<td>$145,600</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Hermione Butler</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>47</td>\n\t\t\t\t\t\t<td>2011/03/21</td>\n\t\t\t\t\t\t<td>$356,250</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Lael Greer</td>\n\t\t\t\t\t\t<td>Systems Administrator</td>\n\t\t\t\t\t\t<td>London</td>\n\t\t\t\t\t\t<td>21</td>\n\t\t\t\t\t\t<td>2009/02/27</td>\n\t\t\t\t\t\t<td>$103,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Jonas Alexander</td>\n\t\t\t\t\t\t<td>Developer</td>\n\t\t\t\t\t\t<td>San Francisco</td>\n\t\t\t\t\t\t<td>30</td>\n\t\t\t\t\t\t<td>2010/07/14</td>\n\t\t\t\t\t\t<td>$86,500</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Shad Decker</td>\n\t\t\t\t\t\t<td>Regional Director</td>\n\t\t\t\t\t\t<td>Edinburgh</td>\n\t\t\t\t\t\t<td>51</td>\n\t\t\t\t\t\t<td>2008/11/13</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Michael Bruce</td>\n\t\t\t\t\t\t<td>Javascript Developer</td>\n\t\t\t\t\t\t<td>Singapore</td>\n\t\t\t\t\t\t<td>29</td>\n\t\t\t\t\t\t<td>2011/06/27</td>\n\t\t\t\t\t\t<td>$183,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t\t<tr>\n\t\t\t\t\t\t<td>Donna Snider</td>\n\t\t\t\t\t\t<td>Customer Support</td>\n\t\t\t\t\t\t<td>New York</td>\n\t\t\t\t\t\t<td>27</td>\n\t\t\t\t\t\t<td>2011/01/25</td>\n\t\t\t\t\t\t<td>$112,000</td>\n\t\t\t\t\t</tr>\n\t\t\t\t</tbody>\n\t\t\t</table>\n\n\t\t\t<ul class=\"tabs\">\n\t\t\t\t<li class=\"active\">Javascript</li>\n\t\t\t\t<li>HTML</li>\n\t\t\t\t<li>CSS</li>\n\t\t\t\t<li>Ajax</li>\n\t\t\t\t<li>Server-side script</li>\n\t\t\t</ul>\n\n\t\t\t<div class=\"tabs\">\n\t\t\t\t<div class=\"js\">\n\t\t\t\t\t<p>The Javascript shown below is used to initialise the table shown in this example:</p><code class=\"multiline language-js\">$(document).ready(function() {\n\t$('#example').DataTable( {\n\t\tdom: 'T&lt;&quot;clear&quot;&gt;lfrtip',\n\t\ttableTools: {\n\t\t\t&quot;sSwfPath&quot;: &quot;../swf/copy_csv_xls_pdf.swf&quot;\n\t\t}\n\t} );\n} );</code>\n\n\t\t\t\t\t<p>In addition to the above code, the following Javascript library files are loaded for use in this example:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.js\">../../../media/js/jquery.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../../../media/js/jquery.dataTables.js\">../../../media/js/jquery.dataTables.js</a></li>\n\t\t\t\t\t\t<li><a href=\"../js/dataTables.tableTools.js\">../js/dataTables.tableTools.js</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"table\">\n\t\t\t\t\t<p>The HTML shown below is the raw HTML table element, before it has been enhanced by DataTables:</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"css\">\n\t\t\t\t\t<div>\n\t\t\t\t\t\t<p>This example uses a little bit of additional CSS beyond what is loaded from the library files (below), in order to correctly display the table. The\n\t\t\t\t\t\tadditional CSS used is shown below:</p><code class=\"multiline language-css\"></code>\n\t\t\t\t\t</div>\n\n\t\t\t\t\t<p>The following CSS library files are loaded for use in this example to provide the styling of the table:</p>\n\n\t\t\t\t\t<ul>\n\t\t\t\t\t\t<li><a href=\"../../../media/css/jquery.dataTables.css\">../../../media/css/jquery.dataTables.css</a></li>\n\t\t\t\t\t\t<li><a href=\"../css/dataTables.tableTools.css\">../css/dataTables.tableTools.css</a></li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"ajax\">\n\t\t\t\t\t<p>This table loads data by Ajax. The latest data that has been loaded is shown below. This data will update automatically as any additional data is\n\t\t\t\t\tloaded.</p>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"php\">\n\t\t\t\t\t<p>The script used to perform the server-side processing for this table is shown below. Please note that this is just an example script using PHP. Server-side\n\t\t\t\t\tprocessing scripts can be written in any language, using <a href=\"//datatables.net/manual/server-side\">the protocol described in the DataTables\n\t\t\t\t\tdocumentation</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</section>\n\t</div>\n\n\t<section>\n\t\t<div class=\"footer\">\n\t\t\t<div class=\"gradient\"></div>\n\n\t\t\t<div class=\"liner\">\n\t\t\t\t<h2>Other examples</h2>\n\n\t\t\t\t<div class=\"toc\">\n\t\t\t\t\t<div class=\"toc-group\">\n\t\t\t\t\t\t<h3><a href=\"./index.html\">Examples</a></h3>\n\t\t\t\t\t\t<ul class=\"toc active\">\n\t\t\t\t\t\t\t<li><a href=\"./simple.html\">Basic initialisation</a></li>\n\t\t\t\t\t\t\t<li class=\"active\"><a href=\"./swf_path.html\">Setting the SWF path</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./new_init.html\">Initialisation with `new`</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./defaults.html\">Defaults</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_single.html\">Row selection - single row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_multi.html\">Row selection - multi-row select</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_os.html\">Row selection - operating system style</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./select_column.html\">Row selection - row selector on specific cells</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multiple_tables.html\">Multiple tables</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./multi_instance.html\">Multiple toolbars</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./collection.html\">Button collections</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./plug-in.html\">Plug-in button types</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./button_text.html\">Custom button text</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./alter_buttons.html\">Button arrangement</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./ajax.html\">Ajax loaded data</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./pdf_message.html\">PDF message</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./bootstrap.html\">Bootstrap styling</a></li>\n\t\t\t\t\t\t\t<li><a href=\"./jqueryui.html\">jQuery UI styling</a></li>\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<div class=\"epilogue\">\n\t\t\t\t\t<p>Please refer to the <a href=\"http://www.datatables.net\">DataTables documentation</a> for full information about its API properties and methods.<br>\n\t\t\t\t\tAdditionally, there are a wide range of <a href=\"http://www.datatables.net/extras\">extras</a> and <a href=\"http://www.datatables.net/plug-ins\">plug-ins</a>\n\t\t\t\t\twhich extend the capabilities of DataTables.</p>\n\n\t\t\t\t\t<p class=\"copyright\">DataTables designed and created by <a href=\"http://www.sprymedia.co.uk\">SpryMedia Ltd</a> &#169; 2007-2015<br>\n\t\t\t\t\tDataTables is licensed under the <a href=\"http://www.datatables.net/mit\">MIT license</a>.</p>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t</section>\n</body>\n</html>"
  },
  {
    "path": "public/static/plugins/datatables/extensions/TableTools/js/dataTables.tableTools.js",
    "content": "/*! TableTools 2.2.4\n * 2009-2015 SpryMedia Ltd - datatables.net/license\n *\n * ZeroClipboard 1.0.4\n * Author: Joseph Huckaby - MIT licensed\n */\n\n/**\n * @summary     TableTools\n * @description Tools and buttons for DataTables\n * @version     2.2.4\n * @file        dataTables.tableTools.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2009-2015 SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n *   MIT license - http://datatables.net/license/mit\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n\n/* Global scope for TableTools for backwards compatibility.\n * Will be removed in 2.3\n */\nvar TableTools;\n\n(function(window, document, undefined) {\n\n\nvar factory = function( $, DataTable ) {\n\"use strict\";\n\n\n//include ZeroClipboard.js\n/* ZeroClipboard 1.0.4\n * Author: Joseph Huckaby\n */\n\nvar ZeroClipboard_TableTools = {\n\n\tversion: \"1.0.4-TableTools2\",\n\tclients: {}, // registered upload clients on page, indexed by id\n\tmoviePath: '', // URL to movie\n\tnextId: 1, // ID of next movie\n\n\t$: function(thingy) {\n\t\t// simple DOM lookup utility function\n\t\tif (typeof(thingy) == 'string') {\n\t\t\tthingy = document.getElementById(thingy);\n\t\t}\n\t\tif (!thingy.addClass) {\n\t\t\t// extend element with a few useful methods\n\t\t\tthingy.hide = function() { this.style.display = 'none'; };\n\t\t\tthingy.show = function() { this.style.display = ''; };\n\t\t\tthingy.addClass = function(name) { this.removeClass(name); this.className += ' ' + name; };\n\t\t\tthingy.removeClass = function(name) {\n\t\t\t\tthis.className = this.className.replace( new RegExp(\"\\\\s*\" + name + \"\\\\s*\"), \" \").replace(/^\\s+/, '').replace(/\\s+$/, '');\n\t\t\t};\n\t\t\tthingy.hasClass = function(name) {\n\t\t\t\treturn !!this.className.match( new RegExp(\"\\\\s*\" + name + \"\\\\s*\") );\n\t\t\t};\n\t\t}\n\t\treturn thingy;\n\t},\n\n\tsetMoviePath: function(path) {\n\t\t// set path to ZeroClipboard.swf\n\t\tthis.moviePath = path;\n\t},\n\n\tdispatch: function(id, eventName, args) {\n\t\t// receive event from flash movie, send to client\n\t\tvar client = this.clients[id];\n\t\tif (client) {\n\t\t\tclient.receiveEvent(eventName, args);\n\t\t}\n\t},\n\n\tregister: function(id, client) {\n\t\t// register new client to receive events\n\t\tthis.clients[id] = client;\n\t},\n\n\tgetDOMObjectPosition: function(obj) {\n\t\t// get absolute coordinates for dom element\n\t\tvar info = {\n\t\t\tleft: 0,\n\t\t\ttop: 0,\n\t\t\twidth: obj.width ? obj.width : obj.offsetWidth,\n\t\t\theight: obj.height ? obj.height : obj.offsetHeight\n\t\t};\n\n\t\tif ( obj.style.width !== \"\" ) {\n\t\t\tinfo.width = obj.style.width.replace(\"px\",\"\");\n\t\t}\n\n\t\tif ( obj.style.height !== \"\" ) {\n\t\t\tinfo.height = obj.style.height.replace(\"px\",\"\");\n\t\t}\n\n\t\twhile (obj) {\n\t\t\tinfo.left += obj.offsetLeft;\n\t\t\tinfo.top += obj.offsetTop;\n\t\t\tobj = obj.offsetParent;\n\t\t}\n\n\t\treturn info;\n\t},\n\n\tClient: function(elem) {\n\t\t// constructor for new simple upload client\n\t\tthis.handlers = {};\n\n\t\t// unique ID\n\t\tthis.id = ZeroClipboard_TableTools.nextId++;\n\t\tthis.movieId = 'ZeroClipboard_TableToolsMovie_' + this.id;\n\n\t\t// register client with singleton to receive flash events\n\t\tZeroClipboard_TableTools.register(this.id, this);\n\n\t\t// create movie\n\t\tif (elem) {\n\t\t\tthis.glue(elem);\n\t\t}\n\t}\n};\n\nZeroClipboard_TableTools.Client.prototype = {\n\n\tid: 0, // unique ID for us\n\tready: false, // whether movie is ready to receive events or not\n\tmovie: null, // reference to movie object\n\tclipText: '', // text to copy to clipboard\n\tfileName: '', // default file save name\n\taction: 'copy', // action to perform\n\thandCursorEnabled: true, // whether to show hand cursor, or default pointer cursor\n\tcssEffects: true, // enable CSS mouse effects on dom container\n\thandlers: null, // user event handlers\n\tsized: false,\n\n\tglue: function(elem, title) {\n\t\t// glue to DOM element\n\t\t// elem can be ID or actual DOM element object\n\t\tthis.domElement = ZeroClipboard_TableTools.$(elem);\n\n\t\t// float just above object, or zIndex 99 if dom element isn't set\n\t\tvar zIndex = 99;\n\t\tif (this.domElement.style.zIndex) {\n\t\t\tzIndex = parseInt(this.domElement.style.zIndex, 10) + 1;\n\t\t}\n\n\t\t// find X/Y position of domElement\n\t\tvar box = ZeroClipboard_TableTools.getDOMObjectPosition(this.domElement);\n\n\t\t// create floating DIV above element\n\t\tthis.div = document.createElement('div');\n\t\tvar style = this.div.style;\n\t\tstyle.position = 'absolute';\n\t\tstyle.left = '0px';\n\t\tstyle.top = '0px';\n\t\tstyle.width = (box.width) + 'px';\n\t\tstyle.height = box.height + 'px';\n\t\tstyle.zIndex = zIndex;\n\n\t\tif ( typeof title != \"undefined\" && title !== \"\" ) {\n\t\t\tthis.div.title = title;\n\t\t}\n\t\tif ( box.width !== 0 && box.height !== 0 ) {\n\t\t\tthis.sized = true;\n\t\t}\n\n\t\t// style.backgroundColor = '#f00'; // debug\n\t\tif ( this.domElement ) {\n\t\t\tthis.domElement.appendChild(this.div);\n\t\t\tthis.div.innerHTML = this.getHTML( box.width, box.height ).replace(/&/g, '&amp;');\n\t\t}\n\t},\n\n\tpositionElement: function() {\n\t\tvar box = ZeroClipboard_TableTools.getDOMObjectPosition(this.domElement);\n\t\tvar style = this.div.style;\n\n\t\tstyle.position = 'absolute';\n\t\t//style.left = (this.domElement.offsetLeft)+'px';\n\t\t//style.top = this.domElement.offsetTop+'px';\n\t\tstyle.width = box.width + 'px';\n\t\tstyle.height = box.height + 'px';\n\n\t\tif ( box.width !== 0 && box.height !== 0 ) {\n\t\t\tthis.sized = true;\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\n\t\tvar flash = this.div.childNodes[0];\n\t\tflash.width = box.width;\n\t\tflash.height = box.height;\n\t},\n\n\tgetHTML: function(width, height) {\n\t\t// return HTML for movie\n\t\tvar html = '';\n\t\tvar flashvars = 'id=' + this.id +\n\t\t\t'&width=' + width +\n\t\t\t'&height=' + height;\n\n\t\tif (navigator.userAgent.match(/MSIE/)) {\n\t\t\t// IE gets an OBJECT tag\n\t\t\tvar protocol = location.href.match(/^https/i) ? 'https://' : 'http://';\n\t\t\thtml += '<object classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" codebase=\"'+protocol+'download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=10,0,0,0\" width=\"'+width+'\" height=\"'+height+'\" id=\"'+this.movieId+'\" align=\"middle\"><param name=\"allowScriptAccess\" value=\"always\" /><param name=\"allowFullScreen\" value=\"false\" /><param name=\"movie\" value=\"'+ZeroClipboard_TableTools.moviePath+'\" /><param name=\"loop\" value=\"false\" /><param name=\"menu\" value=\"false\" /><param name=\"quality\" value=\"best\" /><param name=\"bgcolor\" value=\"#ffffff\" /><param name=\"flashvars\" value=\"'+flashvars+'\"/><param name=\"wmode\" value=\"transparent\"/></object>';\n\t\t}\n\t\telse {\n\t\t\t// all other browsers get an EMBED tag\n\t\t\thtml += '<embed id=\"'+this.movieId+'\" src=\"'+ZeroClipboard_TableTools.moviePath+'\" loop=\"false\" menu=\"false\" quality=\"best\" bgcolor=\"#ffffff\" width=\"'+width+'\" height=\"'+height+'\" name=\"'+this.movieId+'\" align=\"middle\" allowScriptAccess=\"always\" allowFullScreen=\"false\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\" flashvars=\"'+flashvars+'\" wmode=\"transparent\" />';\n\t\t}\n\t\treturn html;\n\t},\n\n\thide: function() {\n\t\t// temporarily hide floater offscreen\n\t\tif (this.div) {\n\t\t\tthis.div.style.left = '-2000px';\n\t\t}\n\t},\n\n\tshow: function() {\n\t\t// show ourselves after a call to hide()\n\t\tthis.reposition();\n\t},\n\n\tdestroy: function() {\n\t\t// destroy control and floater\n\t\tif (this.domElement && this.div) {\n\t\t\tthis.hide();\n\t\t\tthis.div.innerHTML = '';\n\n\t\t\tvar body = document.getElementsByTagName('body')[0];\n\t\t\ttry { body.removeChild( this.div ); } catch(e) {}\n\n\t\t\tthis.domElement = null;\n\t\t\tthis.div = null;\n\t\t}\n\t},\n\n\treposition: function(elem) {\n\t\t// reposition our floating div, optionally to new container\n\t\t// warning: container CANNOT change size, only position\n\t\tif (elem) {\n\t\t\tthis.domElement = ZeroClipboard_TableTools.$(elem);\n\t\t\tif (!this.domElement) {\n\t\t\t\tthis.hide();\n\t\t\t}\n\t\t}\n\n\t\tif (this.domElement && this.div) {\n\t\t\tvar box = ZeroClipboard_TableTools.getDOMObjectPosition(this.domElement);\n\t\t\tvar style = this.div.style;\n\t\t\tstyle.left = '' + box.left + 'px';\n\t\t\tstyle.top = '' + box.top + 'px';\n\t\t}\n\t},\n\n\tclearText: function() {\n\t\t// clear the text to be copy / saved\n\t\tthis.clipText = '';\n\t\tif (this.ready) {\n\t\t\tthis.movie.clearText();\n\t\t}\n\t},\n\n\tappendText: function(newText) {\n\t\t// append text to that which is to be copied / saved\n\t\tthis.clipText += newText;\n\t\tif (this.ready) { this.movie.appendText(newText) ;}\n\t},\n\n\tsetText: function(newText) {\n\t\t// set text to be copied to be copied / saved\n\t\tthis.clipText = newText;\n\t\tif (this.ready) { this.movie.setText(newText) ;}\n\t},\n\n\tsetCharSet: function(charSet) {\n\t\t// set the character set (UTF16LE or UTF8)\n\t\tthis.charSet = charSet;\n\t\tif (this.ready) { this.movie.setCharSet(charSet) ;}\n\t},\n\n\tsetBomInc: function(bomInc) {\n\t\t// set if the BOM should be included or not\n\t\tthis.incBom = bomInc;\n\t\tif (this.ready) { this.movie.setBomInc(bomInc) ;}\n\t},\n\n\tsetFileName: function(newText) {\n\t\t// set the file name\n\t\tthis.fileName = newText;\n\t\tif (this.ready) {\n\t\t\tthis.movie.setFileName(newText);\n\t\t}\n\t},\n\n\tsetAction: function(newText) {\n\t\t// set action (save or copy)\n\t\tthis.action = newText;\n\t\tif (this.ready) {\n\t\t\tthis.movie.setAction(newText);\n\t\t}\n\t},\n\n\taddEventListener: function(eventName, func) {\n\t\t// add user event listener for event\n\t\t// event types: load, queueStart, fileStart, fileComplete, queueComplete, progress, error, cancel\n\t\teventName = eventName.toString().toLowerCase().replace(/^on/, '');\n\t\tif (!this.handlers[eventName]) {\n\t\t\tthis.handlers[eventName] = [];\n\t\t}\n\t\tthis.handlers[eventName].push(func);\n\t},\n\n\tsetHandCursor: function(enabled) {\n\t\t// enable hand cursor (true), or default arrow cursor (false)\n\t\tthis.handCursorEnabled = enabled;\n\t\tif (this.ready) {\n\t\t\tthis.movie.setHandCursor(enabled);\n\t\t}\n\t},\n\n\tsetCSSEffects: function(enabled) {\n\t\t// enable or disable CSS effects on DOM container\n\t\tthis.cssEffects = !!enabled;\n\t},\n\n\treceiveEvent: function(eventName, args) {\n\t\tvar self;\n\n\t\t// receive event from flash\n\t\teventName = eventName.toString().toLowerCase().replace(/^on/, '');\n\n\t\t// special behavior for certain events\n\t\tswitch (eventName) {\n\t\t\tcase 'load':\n\t\t\t\t// movie claims it is ready, but in IE this isn't always the case...\n\t\t\t\t// bug fix: Cannot extend EMBED DOM elements in Firefox, must use traditional function\n\t\t\t\tthis.movie = document.getElementById(this.movieId);\n\t\t\t\tif (!this.movie) {\n\t\t\t\t\tself = this;\n\t\t\t\t\tsetTimeout( function() { self.receiveEvent('load', null); }, 1 );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// firefox on pc needs a \"kick\" in order to set these in certain cases\n\t\t\t\tif (!this.ready && navigator.userAgent.match(/Firefox/) && navigator.userAgent.match(/Windows/)) {\n\t\t\t\t\tself = this;\n\t\t\t\t\tsetTimeout( function() { self.receiveEvent('load', null); }, 100 );\n\t\t\t\t\tthis.ready = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tthis.ready = true;\n\t\t\t\tthis.movie.clearText();\n\t\t\t\tthis.movie.appendText( this.clipText );\n\t\t\t\tthis.movie.setFileName( this.fileName );\n\t\t\t\tthis.movie.setAction( this.action );\n\t\t\t\tthis.movie.setCharSet( this.charSet );\n\t\t\t\tthis.movie.setBomInc( this.incBom );\n\t\t\t\tthis.movie.setHandCursor( this.handCursorEnabled );\n\t\t\t\tbreak;\n\n\t\t\tcase 'mouseover':\n\t\t\t\tif (this.domElement && this.cssEffects) {\n\t\t\t\t\t//this.domElement.addClass('hover');\n\t\t\t\t\tif (this.recoverActive) {\n\t\t\t\t\t\tthis.domElement.addClass('active');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'mouseout':\n\t\t\t\tif (this.domElement && this.cssEffects) {\n\t\t\t\t\tthis.recoverActive = false;\n\t\t\t\t\tif (this.domElement.hasClass('active')) {\n\t\t\t\t\t\tthis.domElement.removeClass('active');\n\t\t\t\t\t\tthis.recoverActive = true;\n\t\t\t\t\t}\n\t\t\t\t\t//this.domElement.removeClass('hover');\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'mousedown':\n\t\t\t\tif (this.domElement && this.cssEffects) {\n\t\t\t\t\tthis.domElement.addClass('active');\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'mouseup':\n\t\t\t\tif (this.domElement && this.cssEffects) {\n\t\t\t\t\tthis.domElement.removeClass('active');\n\t\t\t\t\tthis.recoverActive = false;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t} // switch eventName\n\n\t\tif (this.handlers[eventName]) {\n\t\t\tfor (var idx = 0, len = this.handlers[eventName].length; idx < len; idx++) {\n\t\t\t\tvar func = this.handlers[eventName][idx];\n\n\t\t\t\tif (typeof(func) == 'function') {\n\t\t\t\t\t// actual function reference\n\t\t\t\t\tfunc(this, args);\n\t\t\t\t}\n\t\t\t\telse if ((typeof(func) == 'object') && (func.length == 2)) {\n\t\t\t\t\t// PHP style object + method, i.e. [myObject, 'myMethod']\n\t\t\t\t\tfunc[0][ func[1] ](this, args);\n\t\t\t\t}\n\t\t\t\telse if (typeof(func) == 'string') {\n\t\t\t\t\t// name of function\n\t\t\t\t\twindow[func](this, args);\n\t\t\t\t}\n\t\t\t} // foreach event handler defined\n\t\t} // user defined handler for event\n\t}\n\n};\n\n// For the Flash binding to work, ZeroClipboard_TableTools must be on the global\n// object list\nwindow.ZeroClipboard_TableTools = ZeroClipboard_TableTools;\n//include TableTools.js\n/* TableTools\n * 2009-2015 SpryMedia Ltd - datatables.net/license\n */\n\n/*globals TableTools,ZeroClipboard_TableTools*/\n\n\n(function($, window, document) {\n\n/** \n * TableTools provides flexible buttons and other tools for a DataTables enhanced table\n * @class TableTools\n * @constructor\n * @param {Object} oDT DataTables instance. When using DataTables 1.10 this can\n *   also be a jQuery collection, jQuery selector, table node, DataTables API\n *   instance or DataTables settings object.\n * @param {Object} oOpts TableTools options\n * @param {String} oOpts.sSwfPath ZeroClipboard SWF path\n * @param {String} oOpts.sRowSelect Row selection options - 'none', 'single', 'multi' or 'os'\n * @param {Function} oOpts.fnPreRowSelect Callback function just prior to row selection\n * @param {Function} oOpts.fnRowSelected Callback function just after row selection\n * @param {Function} oOpts.fnRowDeselected Callback function when row is deselected\n * @param {Array} oOpts.aButtons List of buttons to be used\n */\nTableTools = function( oDT, oOpts )\n{\n\t/* Santiy check that we are a new instance */\n\tif ( ! this instanceof TableTools )\n\t{\n\t\talert( \"Warning: TableTools must be initialised with the keyword 'new'\" );\n\t}\n\n\t// In 1.10 we can use the API to get the settings object from a number of\n\t// sources\n\tvar dtSettings = $.fn.dataTable.Api ?\n\t\tnew $.fn.dataTable.Api( oDT ).settings()[0] :\n\t\toDT.fnSettings();\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Public class variables\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * @namespace Settings object which contains customisable information for TableTools instance\n\t */\n\tthis.s = {\n\t\t/**\n\t\t * Store 'this' so the instance can be retrieved from the settings object\n\t\t * @property that\n\t\t * @type\t object\n\t\t * @default  this\n\t\t */\n\t\t\"that\": this,\n\n\t\t/** \n\t\t * DataTables settings objects\n\t\t * @property dt\n\t\t * @type\t object\n\t\t * @default  <i>From the oDT init option</i>\n\t\t */\n\t\t\"dt\": dtSettings,\n\n\t\t/**\n\t\t * @namespace Print specific information\n\t\t */\n\t\t\"print\": {\n\t\t\t/** \n\t\t\t * DataTables draw 'start' point before the printing display was shown\n\t\t\t *  @property saveStart\n\t\t\t *  @type\t int\n\t\t\t *  @default  -1\n\t\t\t */\n\t\t\t\"saveStart\": -1,\n\n\t\t\t/** \n\t\t\t * DataTables draw 'length' point before the printing display was shown\n\t\t\t *  @property saveLength\n\t\t\t *  @type\t int\n\t\t\t *  @default  -1\n\t\t\t */\n\t\t\t\"saveLength\": -1,\n\n\t\t\t/** \n\t\t\t * Page scrolling point before the printing display was shown so it can be restored\n\t\t\t *  @property saveScroll\n\t\t\t *  @type\t int\n\t\t\t *  @default  -1\n\t\t\t */\n\t\t\t\"saveScroll\": -1,\n\n\t\t\t/** \n\t\t\t * Wrapped function to end the print display (to maintain scope)\n\t\t\t *  @property funcEnd\n\t\t\t *  @type\t Function\n\t\t\t *  @default  function () {}\n\t\t\t */\n\t\t\t\"funcEnd\": function () {}\n\t\t},\n\n\t\t/**\n\t\t * A unique ID is assigned to each button in each instance\n\t\t * @property buttonCounter\n\t\t *  @type\t int\n\t\t * @default  0\n\t\t */\n\t\t\"buttonCounter\": 0,\n\n\t\t/**\n\t\t * @namespace Select rows specific information\n\t\t */\n\t\t\"select\": {\n\t\t\t/**\n\t\t\t * Select type - can be 'none', 'single' or 'multi'\n\t\t\t * @property type\n\t\t\t *  @type\t string\n\t\t\t * @default  \"\"\n\t\t\t */\n\t\t\t\"type\": \"\",\n\n\t\t\t/**\n\t\t\t * Array of nodes which are currently selected\n\t\t\t *  @property selected\n\t\t\t *  @type\t array\n\t\t\t *  @default  []\n\t\t\t */\n\t\t\t\"selected\": [],\n\n\t\t\t/**\n\t\t\t * Function to run before the selection can take place. Will cancel the select if the\n\t\t\t * function returns false\n\t\t\t *  @property preRowSelect\n\t\t\t *  @type\t Function\n\t\t\t *  @default  null\n\t\t\t */\n\t\t\t\"preRowSelect\": null,\n\n\t\t\t/**\n\t\t\t * Function to run when a row is selected\n\t\t\t *  @property postSelected\n\t\t\t *  @type\t Function\n\t\t\t *  @default  null\n\t\t\t */\n\t\t\t\"postSelected\": null,\n\n\t\t\t/**\n\t\t\t * Function to run when a row is deselected\n\t\t\t *  @property postDeselected\n\t\t\t *  @type\t Function\n\t\t\t *  @default  null\n\t\t\t */\n\t\t\t\"postDeselected\": null,\n\n\t\t\t/**\n\t\t\t * Indicate if all rows are selected (needed for server-side processing)\n\t\t\t *  @property all\n\t\t\t *  @type\t boolean\n\t\t\t *  @default  false\n\t\t\t */\n\t\t\t\"all\": false,\n\n\t\t\t/**\n\t\t\t * Class name to add to selected TR nodes\n\t\t\t *  @property selectedClass\n\t\t\t *  @type\t String\n\t\t\t *  @default  \"\"\n\t\t\t */\n\t\t\t\"selectedClass\": \"\"\n\t\t},\n\n\t\t/**\n\t\t * Store of the user input customisation object\n\t\t *  @property custom\n\t\t *  @type\t object\n\t\t *  @default  {}\n\t\t */\n\t\t\"custom\": {},\n\n\t\t/**\n\t\t * SWF movie path\n\t\t *  @property swfPath\n\t\t *  @type\t string\n\t\t *  @default  \"\"\n\t\t */\n\t\t\"swfPath\": \"\",\n\n\t\t/**\n\t\t * Default button set\n\t\t *  @property buttonSet\n\t\t *  @type\t array\n\t\t *  @default  []\n\t\t */\n\t\t\"buttonSet\": [],\n\n\t\t/**\n\t\t * When there is more than one TableTools instance for a DataTable, there must be a \n\t\t * master which controls events (row selection etc)\n\t\t *  @property master\n\t\t *  @type\t boolean\n\t\t *  @default  false\n\t\t */\n\t\t\"master\": false,\n\n\t\t/**\n\t\t * Tag names that are used for creating collections and buttons\n\t\t *  @namesapce\n\t\t */\n\t\t\"tags\": {}\n\t};\n\n\n\t/**\n\t * @namespace Common and useful DOM elements for the class instance\n\t */\n\tthis.dom = {\n\t\t/**\n\t\t * DIV element that is create and all TableTools buttons (and their children) put into\n\t\t *  @property container\n\t\t *  @type\t node\n\t\t *  @default  null\n\t\t */\n\t\t\"container\": null,\n\n\t\t/**\n\t\t * The table node to which TableTools will be applied\n\t\t *  @property table\n\t\t *  @type\t node\n\t\t *  @default  null\n\t\t */\n\t\t\"table\": null,\n\n\t\t/**\n\t\t * @namespace Nodes used for the print display\n\t\t */\n\t\t\"print\": {\n\t\t\t/**\n\t\t\t * Nodes which have been removed from the display by setting them to display none\n\t\t\t *  @property hidden\n\t\t\t *  @type\t array\n\t\t\t *  @default  []\n\t\t\t */\n\t\t\t\"hidden\": [],\n\n\t\t\t/**\n\t\t\t * The information display saying telling the user about the print display\n\t\t\t *  @property message\n\t\t\t *  @type\t node\n\t\t\t *  @default  null\n\t\t\t */\n\t\t\t\"message\": null\n\t  },\n\n\t\t/**\n\t\t * @namespace Nodes used for a collection display. This contains the currently used collection\n\t\t */\n\t\t\"collection\": {\n\t\t\t/**\n\t\t\t * The div wrapper containing the buttons in the collection (i.e. the menu)\n\t\t\t *  @property collection\n\t\t\t *  @type\t node\n\t\t\t *  @default  null\n\t\t\t */\n\t\t\t\"collection\": null,\n\n\t\t\t/**\n\t\t\t * Background display to provide focus and capture events\n\t\t\t *  @property background\n\t\t\t *  @type\t node\n\t\t\t *  @default  null\n\t\t\t */\n\t\t\t\"background\": null\n\t\t}\n\t};\n\n\t/**\n\t * @namespace Name space for the classes that this TableTools instance will use\n\t * @extends TableTools.classes\n\t */\n\tthis.classes = $.extend( true, {}, TableTools.classes );\n\tif ( this.s.dt.bJUI )\n\t{\n\t\t$.extend( true, this.classes, TableTools.classes_themeroller );\n\t}\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Public class methods\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * Retreieve the settings object from an instance\n\t *  @method fnSettings\n\t *  @returns {object} TableTools settings object\n\t */\n\tthis.fnSettings = function () {\n\t\treturn this.s;\n\t};\n\n\n\t/* Constructor logic */\n\tif ( typeof oOpts == 'undefined' )\n\t{\n\t\toOpts = {};\n\t}\n\n\n\tTableTools._aInstances.push( this );\n\tthis._fnConstruct( oOpts );\n\n\treturn this;\n};\n\n\n\nTableTools.prototype = {\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Public methods\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * Retreieve the settings object from an instance\n\t *  @returns {array} List of TR nodes which are currently selected\n\t *  @param {boolean} [filtered=false] Get only selected rows which are  \n\t *    available given the filtering applied to the table. By default\n\t *    this is false -  i.e. all rows, regardless of filtering are \n\t      selected.\n\t */\n\t\"fnGetSelected\": function ( filtered )\n\t{\n\t\tvar\n\t\t\tout = [],\n\t\t\tdata = this.s.dt.aoData,\n\t\t\tdisplayed = this.s.dt.aiDisplay,\n\t\t\ti, iLen;\n\n\t\tif ( filtered )\n\t\t{\n\t\t\t// Only consider filtered rows\n\t\t\tfor ( i=0, iLen=displayed.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tif ( data[ displayed[i] ]._DTTT_selected )\n\t\t\t\t{\n\t\t\t\t\tout.push( data[ displayed[i] ].nTr );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Use all rows\n\t\t\tfor ( i=0, iLen=data.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tif ( data[i]._DTTT_selected )\n\t\t\t\t{\n\t\t\t\t\tout.push( data[i].nTr );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn out;\n\t},\n\n\n\t/**\n\t * Get the data source objects/arrays from DataTables for the selected rows (same as\n\t * fnGetSelected followed by fnGetData on each row from the table)\n\t *  @returns {array} Data from the TR nodes which are currently selected\n\t */\n\t\"fnGetSelectedData\": function ()\n\t{\n\t\tvar out = [];\n\t\tvar data=this.s.dt.aoData;\n\t\tvar i, iLen;\n\n\t\tfor ( i=0, iLen=data.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tif ( data[i]._DTTT_selected )\n\t\t\t{\n\t\t\t\tout.push( this.s.dt.oInstance.fnGetData(i) );\n\t\t\t}\n\t\t}\n\n\t\treturn out;\n\t},\n\n\n\t/**\n\t * Get the indexes of the selected rows\n\t *  @returns {array} List of row indexes\n\t *  @param {boolean} [filtered=false] Get only selected rows which are  \n\t *    available given the filtering applied to the table. By default\n\t *    this is false -  i.e. all rows, regardless of filtering are \n\t      selected.\n\t */\n\t\"fnGetSelectedIndexes\": function ( filtered )\n\t{\n\t\tvar\n\t\t\tout = [],\n\t\t\tdata = this.s.dt.aoData,\n\t\t\tdisplayed = this.s.dt.aiDisplay,\n\t\t\ti, iLen;\n\n\t\tif ( filtered )\n\t\t{\n\t\t\t// Only consider filtered rows\n\t\t\tfor ( i=0, iLen=displayed.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tif ( data[ displayed[i] ]._DTTT_selected )\n\t\t\t\t{\n\t\t\t\t\tout.push( displayed[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Use all rows\n\t\t\tfor ( i=0, iLen=data.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tif ( data[i]._DTTT_selected )\n\t\t\t\t{\n\t\t\t\t\tout.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn out;\n\t},\n\n\n\t/**\n\t * Check to see if a current row is selected or not\n\t *  @param {Node} n TR node to check if it is currently selected or not\n\t *  @returns {Boolean} true if select, false otherwise\n\t */\n\t\"fnIsSelected\": function ( n )\n\t{\n\t\tvar pos = this.s.dt.oInstance.fnGetPosition( n );\n\t\treturn (this.s.dt.aoData[pos]._DTTT_selected===true) ? true : false;\n\t},\n\n\n\t/**\n\t * Select all rows in the table\n\t *  @param {boolean} [filtered=false] Select only rows which are available \n\t *    given the filtering applied to the table. By default this is false - \n\t *    i.e. all rows, regardless of filtering are selected.\n\t */\n\t\"fnSelectAll\": function ( filtered )\n\t{\n\t\tthis._fnRowSelect( filtered ?\n\t\t\tthis.s.dt.aiDisplay :\n\t\t\tthis.s.dt.aoData\n\t\t);\n\t},\n\n\n\t/**\n\t * Deselect all rows in the table\n\t *  @param {boolean} [filtered=false] Deselect only rows which are available \n\t *    given the filtering applied to the table. By default this is false - \n\t *    i.e. all rows, regardless of filtering are deselected.\n\t */\n\t\"fnSelectNone\": function ( filtered )\n\t{\n\t\tthis._fnRowDeselect( this.fnGetSelectedIndexes(filtered) );\n\t},\n\n\n\t/**\n\t * Select row(s)\n\t *  @param {node|object|array} n The row(s) to select. Can be a single DOM\n\t *    TR node, an array of TR nodes or a jQuery object.\n\t */\n\t\"fnSelect\": function ( n )\n\t{\n\t\tif ( this.s.select.type == \"single\" )\n\t\t{\n\t\t\tthis.fnSelectNone();\n\t\t\tthis._fnRowSelect( n );\n\t\t}\n\t\telse\n\t\t{\n\t\t\tthis._fnRowSelect( n );\n\t\t}\n\t},\n\n\n\t/**\n\t * Deselect row(s)\n\t *  @param {node|object|array} n The row(s) to deselect. Can be a single DOM\n\t *    TR node, an array of TR nodes or a jQuery object.\n\t */\n\t\"fnDeselect\": function ( n )\n\t{\n\t\tthis._fnRowDeselect( n );\n\t},\n\n\n\t/**\n\t * Get the title of the document - useful for file names. The title is retrieved from either\n\t * the configuration object's 'title' parameter, or the HTML document title\n\t *  @param   {Object} oConfig Button configuration object\n\t *  @returns {String} Button title\n\t */\n\t\"fnGetTitle\": function( oConfig )\n\t{\n\t\tvar sTitle = \"\";\n\t\tif ( typeof oConfig.sTitle != 'undefined' && oConfig.sTitle !== \"\" ) {\n\t\t\tsTitle = oConfig.sTitle;\n\t\t} else {\n\t\t\tvar anTitle = document.getElementsByTagName('title');\n\t\t\tif ( anTitle.length > 0 )\n\t\t\t{\n\t\t\t\tsTitle = anTitle[0].innerHTML;\n\t\t\t}\n\t\t}\n\n\t\t/* Strip characters which the OS will object to - checking for UTF8 support in the scripting\n\t\t * engine\n\t\t */\n\t\tif ( \"\\u00A1\".toString().length < 4 ) {\n\t\t\treturn sTitle.replace(/[^a-zA-Z0-9_\\u00A1-\\uFFFF\\.,\\-_ !\\(\\)]/g, \"\");\n\t\t} else {\n\t\t\treturn sTitle.replace(/[^a-zA-Z0-9_\\.,\\-_ !\\(\\)]/g, \"\");\n\t\t}\n\t},\n\n\n\t/**\n\t * Calculate a unity array with the column width by proportion for a set of columns to be\n\t * included for a button. This is particularly useful for PDF creation, where we can use the\n\t * column widths calculated by the browser to size the columns in the PDF.\n\t *  @param   {Object} oConfig Button configuration object\n\t *  @returns {Array} Unity array of column ratios\n\t */\n\t\"fnCalcColRatios\": function ( oConfig )\n\t{\n\t\tvar\n\t\t\taoCols = this.s.dt.aoColumns,\n\t\t\taColumnsInc = this._fnColumnTargets( oConfig.mColumns ),\n\t\t\taColWidths = [],\n\t\t\tiWidth = 0, iTotal = 0, i, iLen;\n\n\t\tfor ( i=0, iLen=aColumnsInc.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tif ( aColumnsInc[i] )\n\t\t\t{\n\t\t\t\tiWidth = aoCols[i].nTh.offsetWidth;\n\t\t\t\tiTotal += iWidth;\n\t\t\t\taColWidths.push( iWidth );\n\t\t\t}\n\t\t}\n\n\t\tfor ( i=0, iLen=aColWidths.length ; i<iLen ; i++ )\n\t\t{\n\t\t\taColWidths[i] = aColWidths[i] / iTotal;\n\t\t}\n\n\t\treturn aColWidths.join('\\t');\n\t},\n\n\n\t/**\n\t * Get the information contained in a table as a string\n\t *  @param   {Object} oConfig Button configuration object\n\t *  @returns {String} Table data as a string\n\t */\n\t\"fnGetTableData\": function ( oConfig )\n\t{\n\t\t/* In future this could be used to get data from a plain HTML source as well as DataTables */\n\t\tif ( this.s.dt )\n\t\t{\n\t\t\treturn this._fnGetDataTablesData( oConfig );\n\t\t}\n\t},\n\n\n\t/**\n\t * Pass text to a flash button instance, which will be used on the button's click handler\n\t *  @param   {Object} clip Flash button object\n\t *  @param   {String} text Text to set\n\t */\n\t\"fnSetText\": function ( clip, text )\n\t{\n\t\tthis._fnFlashSetText( clip, text );\n\t},\n\n\n\t/**\n\t * Resize the flash elements of the buttons attached to this TableTools instance - this is\n\t * useful for when initialising TableTools when it is hidden (display:none) since sizes can't\n\t * be calculated at that time.\n\t */\n\t\"fnResizeButtons\": function ()\n\t{\n\t\tfor ( var cli in ZeroClipboard_TableTools.clients )\n\t\t{\n\t\t\tif ( cli )\n\t\t\t{\n\t\t\t\tvar client = ZeroClipboard_TableTools.clients[cli];\n\t\t\t\tif ( typeof client.domElement != 'undefined' &&\n\t\t\t\t\t client.domElement.parentNode )\n\t\t\t\t{\n\t\t\t\t\tclient.positionElement();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\n\t/**\n\t * Check to see if any of the ZeroClipboard client's attached need to be resized\n\t */\n\t\"fnResizeRequired\": function ()\n\t{\n\t\tfor ( var cli in ZeroClipboard_TableTools.clients )\n\t\t{\n\t\t\tif ( cli )\n\t\t\t{\n\t\t\t\tvar client = ZeroClipboard_TableTools.clients[cli];\n\t\t\t\tif ( typeof client.domElement != 'undefined' &&\n\t\t\t\t\t client.domElement.parentNode == this.dom.container &&\n\t\t\t\t\t client.sized === false )\n\t\t\t\t{\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t},\n\n\n\t/**\n\t * Programmatically enable or disable the print view\n\t *  @param {boolean} [bView=true] Show the print view if true or not given. If false, then\n\t *    terminate the print view and return to normal.\n\t *  @param {object} [oConfig={}] Configuration for the print view\n\t *  @param {boolean} [oConfig.bShowAll=false] Show all rows in the table if true\n\t *  @param {string} [oConfig.sInfo] Information message, displayed as an overlay to the\n\t *    user to let them know what the print view is.\n\t *  @param {string} [oConfig.sMessage] HTML string to show at the top of the document - will\n\t *    be included in the printed document.\n\t */\n\t\"fnPrint\": function ( bView, oConfig )\n\t{\n\t\tif ( oConfig === undefined )\n\t\t{\n\t\t\toConfig = {};\n\t\t}\n\n\t\tif ( bView === undefined || bView )\n\t\t{\n\t\t\tthis._fnPrintStart( oConfig );\n\t\t}\n\t\telse\n\t\t{\n\t\t\tthis._fnPrintEnd();\n\t\t}\n\t},\n\n\n\t/**\n\t * Show a message to the end user which is nicely styled\n\t *  @param {string} message The HTML string to show to the user\n\t *  @param {int} time The duration the message is to be shown on screen for (mS)\n\t */\n\t\"fnInfo\": function ( message, time ) {\n\t\tvar info = $('<div/>')\n\t\t\t.addClass( this.classes.print.info )\n\t\t\t.html( message )\n\t\t\t.appendTo( 'body' );\n\n\t\tsetTimeout( function() {\n\t\t\tinfo.fadeOut( \"normal\", function() {\n\t\t\t\tinfo.remove();\n\t\t\t} );\n\t\t}, time );\n\t},\n\n\n\n\t/**\n\t * Get the container element of the instance for attaching to the DOM\n\t *   @returns {node} DOM node\n\t */\n\t\"fnContainer\": function () {\n\t\treturn this.dom.container;\n\t},\n\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Private methods (they are of course public in JS, but recommended as private)\n\t * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\t/**\n\t * Constructor logic\n\t *  @method  _fnConstruct\n\t *  @param   {Object} oOpts Same as TableTools constructor\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnConstruct\": function ( oOpts )\n\t{\n\t\tvar that = this;\n\n\t\tthis._fnCustomiseSettings( oOpts );\n\n\t\t/* Container element */\n\t\tthis.dom.container = document.createElement( this.s.tags.container );\n\t\tthis.dom.container.className = this.classes.container;\n\n\t\t/* Row selection config */\n\t\tif ( this.s.select.type != 'none' )\n\t\t{\n\t\t\tthis._fnRowSelectConfig();\n\t\t}\n\n\t\t/* Buttons */\n\t\tthis._fnButtonDefinations( this.s.buttonSet, this.dom.container );\n\n\t\t/* Destructor */\n\t\tthis.s.dt.aoDestroyCallback.push( {\n\t\t\t\"sName\": \"TableTools\",\n\t\t\t\"fn\": function () {\n\t\t\t\t$(that.s.dt.nTBody)\n\t\t\t\t\t.off( 'click.DTTT_Select', that.s.custom.sRowSelector )\n\t\t\t\t\t.off( 'mousedown.DTTT_Select', 'tr' )\n\t\t\t\t\t.off( 'mouseup.DTTT_Select', 'tr' );\n\n\t\t\t\t$(that.dom.container).empty();\n\n\t\t\t\t// Remove the instance\n\t\t\t\tvar idx = $.inArray( that, TableTools._aInstances );\n\t\t\t\tif ( idx !== -1 ) {\n\t\t\t\t\tTableTools._aInstances.splice( idx, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\n\t/**\n\t * Take the user defined settings and the default settings and combine them.\n\t *  @method  _fnCustomiseSettings\n\t *  @param   {Object} oOpts Same as TableTools constructor\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnCustomiseSettings\": function ( oOpts )\n\t{\n\t\t/* Is this the master control instance or not? */\n\t\tif ( typeof this.s.dt._TableToolsInit == 'undefined' )\n\t\t{\n\t\t\tthis.s.master = true;\n\t\t\tthis.s.dt._TableToolsInit = true;\n\t\t}\n\n\t\t/* We can use the table node from comparisons to group controls */\n\t\tthis.dom.table = this.s.dt.nTable;\n\n\t\t/* Clone the defaults and then the user options */\n\t\tthis.s.custom = $.extend( {}, TableTools.DEFAULTS, oOpts );\n\n\t\t/* Flash file location */\n\t\tthis.s.swfPath = this.s.custom.sSwfPath;\n\t\tif ( typeof ZeroClipboard_TableTools != 'undefined' )\n\t\t{\n\t\t\tZeroClipboard_TableTools.moviePath = this.s.swfPath;\n\t\t}\n\n\t\t/* Table row selecting */\n\t\tthis.s.select.type = this.s.custom.sRowSelect;\n\t\tthis.s.select.preRowSelect = this.s.custom.fnPreRowSelect;\n\t\tthis.s.select.postSelected = this.s.custom.fnRowSelected;\n\t\tthis.s.select.postDeselected = this.s.custom.fnRowDeselected;\n\n\t\t// Backwards compatibility - allow the user to specify a custom class in the initialiser\n\t\tif ( this.s.custom.sSelectedClass )\n\t\t{\n\t\t\tthis.classes.select.row = this.s.custom.sSelectedClass;\n\t\t}\n\n\t\tthis.s.tags = this.s.custom.oTags;\n\n\t\t/* Button set */\n\t\tthis.s.buttonSet = this.s.custom.aButtons;\n\t},\n\n\n\t/**\n\t * Take the user input arrays and expand them to be fully defined, and then add them to a given\n\t * DOM element\n\t *  @method  _fnButtonDefinations\n\t *  @param {array} buttonSet Set of user defined buttons\n\t *  @param {node} wrapper Node to add the created buttons to\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnButtonDefinations\": function ( buttonSet, wrapper )\n\t{\n\t\tvar buttonDef;\n\n\t\tfor ( var i=0, iLen=buttonSet.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tif ( typeof buttonSet[i] == \"string\" )\n\t\t\t{\n\t\t\t\tif ( typeof TableTools.BUTTONS[ buttonSet[i] ] == 'undefined' )\n\t\t\t\t{\n\t\t\t\t\talert( \"TableTools: Warning - unknown button type: \"+buttonSet[i] );\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tbuttonDef = $.extend( {}, TableTools.BUTTONS[ buttonSet[i] ], true );\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tif ( typeof TableTools.BUTTONS[ buttonSet[i].sExtends ] == 'undefined' )\n\t\t\t\t{\n\t\t\t\t\talert( \"TableTools: Warning - unknown button type: \"+buttonSet[i].sExtends );\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tvar o = $.extend( {}, TableTools.BUTTONS[ buttonSet[i].sExtends ], true );\n\t\t\t\tbuttonDef = $.extend( o, buttonSet[i], true );\n\t\t\t}\n\n\t\t\tvar button = this._fnCreateButton(\n\t\t\t\tbuttonDef,\n\t\t\t\t$(wrapper).hasClass(this.classes.collection.container)\n\t\t\t);\n\n\t\t\tif ( button ) {\n\t\t\t\twrapper.appendChild( button );\n\t\t\t}\n\t\t}\n\t},\n\n\n\t/**\n\t * Create and configure a TableTools button\n\t *  @method  _fnCreateButton\n\t *  @param   {Object} oConfig Button configuration object\n\t *  @returns {Node} Button element\n\t *  @private \n\t */\n\t\"_fnCreateButton\": function ( oConfig, bCollectionButton )\n\t{\n\t  var nButton = this._fnButtonBase( oConfig, bCollectionButton );\n\n\t\tif ( oConfig.sAction.match(/flash/) )\n\t\t{\n\t\t\tif ( ! this._fnHasFlash() ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis._fnFlashConfig( nButton, oConfig );\n\t\t}\n\t\telse if ( oConfig.sAction == \"text\" )\n\t\t{\n\t\t\tthis._fnTextConfig( nButton, oConfig );\n\t\t}\n\t\telse if ( oConfig.sAction == \"div\" )\n\t\t{\n\t\t\tthis._fnTextConfig( nButton, oConfig );\n\t\t}\n\t\telse if ( oConfig.sAction == \"collection\" )\n\t\t{\n\t\t\tthis._fnTextConfig( nButton, oConfig );\n\t\t\tthis._fnCollectionConfig( nButton, oConfig );\n\t\t}\n\n\t\tif ( this.s.dt.iTabIndex !== -1 ) {\n\t\t\t$(nButton)\n\t\t\t\t.attr( 'tabindex', this.s.dt.iTabIndex )\n\t\t\t\t.attr( 'aria-controls', this.s.dt.sTableId )\n\t\t\t\t.on( 'keyup.DTTT', function (e) {\n\t\t\t\t\t// Trigger the click event on return key when focused.\n\t\t\t\t\t// Note that for Flash buttons this has no effect since we\n\t\t\t\t\t// can't programmatically trigger the Flash export\n\t\t\t\t\tif ( e.keyCode === 13 ) {\n\t\t\t\t\t\te.stopPropagation();\n\n\t\t\t\t\t\t$(this).trigger( 'click' );\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t\t.on( 'mousedown.DTTT', function (e) {\n\t\t\t\t\t// On mousedown we want to stop the focus occurring on the\n\t\t\t\t\t// button, focus is used only for the keyboard navigation.\n\t\t\t\t\t// But using preventDefault for the flash buttons stops the\n\t\t\t\t\t// flash action. However, it is not the button that gets\n\t\t\t\t\t// focused but the flash element for flash buttons, so this\n\t\t\t\t\t// works\n\t\t\t\t\tif ( ! oConfig.sAction.match(/flash/) ) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}\n\n\t\treturn nButton;\n\t},\n\n\n\t/**\n\t * Create the DOM needed for the button and apply some base properties. All buttons start here\n\t *  @method  _fnButtonBase\n\t *  @param   {o} oConfig Button configuration object\n\t *  @returns {Node} DIV element for the button\n\t *  @private\n\t */\n\t\"_fnButtonBase\": function ( o, bCollectionButton )\n\t{\n\t\tvar sTag, sLiner, sClass;\n\n\t\tif ( bCollectionButton )\n\t\t{\n\t\t\tsTag = o.sTag && o.sTag !== \"default\" ? o.sTag : this.s.tags.collection.button;\n\t\t\tsLiner = o.sLinerTag && o.sLinerTag !== \"default\" ? o.sLiner : this.s.tags.collection.liner;\n\t\t\tsClass = this.classes.collection.buttons.normal;\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsTag = o.sTag && o.sTag !== \"default\" ? o.sTag : this.s.tags.button;\n\t\t\tsLiner = o.sLinerTag && o.sLinerTag !== \"default\" ? o.sLiner : this.s.tags.liner;\n\t\t\tsClass = this.classes.buttons.normal;\n\t\t}\n\n\t\tvar\n\t\t  nButton = document.createElement( sTag ),\n\t\t  nSpan = document.createElement( sLiner ),\n\t\t  masterS = this._fnGetMasterSettings();\n\n\t\tnButton.className = sClass+\" \"+o.sButtonClass;\n\t\tnButton.setAttribute('id', \"ToolTables_\"+this.s.dt.sInstance+\"_\"+masterS.buttonCounter );\n\t\tnButton.appendChild( nSpan );\n\t\tnSpan.innerHTML = o.sButtonText;\n\n\t\tmasterS.buttonCounter++;\n\n\t\treturn nButton;\n\t},\n\n\n\t/**\n\t * Get the settings object for the master instance. When more than one TableTools instance is\n\t * assigned to a DataTable, only one of them can be the 'master' (for the select rows). As such,\n\t * we will typically want to interact with that master for global properties.\n\t *  @method  _fnGetMasterSettings\n\t *  @returns {Object} TableTools settings object\n\t *  @private \n\t */\n\t\"_fnGetMasterSettings\": function ()\n\t{\n\t\tif ( this.s.master )\n\t\t{\n\t\t\treturn this.s;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Look for the master which has the same DT as this one */\n\t\t\tvar instances = TableTools._aInstances;\n\t\t\tfor ( var i=0, iLen=instances.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tif ( this.dom.table == instances[i].s.dt.nTable )\n\t\t\t\t{\n\t\t\t\t\treturn instances[i].s;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Button collection functions\n\t */\n\n\t/**\n\t * Create a collection button, when activated will present a drop down list of other buttons\n\t *  @param   {Node} nButton Button to use for the collection activation\n\t *  @param   {Object} oConfig Button configuration object\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnCollectionConfig\": function ( nButton, oConfig )\n\t{\n\t\tvar nHidden = document.createElement( this.s.tags.collection.container );\n\t\tnHidden.style.display = \"none\";\n\t\tnHidden.className = this.classes.collection.container;\n\t\toConfig._collection = nHidden;\n\t\tdocument.body.appendChild( nHidden );\n\n\t\tthis._fnButtonDefinations( oConfig.aButtons, nHidden );\n\t},\n\n\n\t/**\n\t * Show a button collection\n\t *  @param   {Node} nButton Button to use for the collection\n\t *  @param   {Object} oConfig Button configuration object\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnCollectionShow\": function ( nButton, oConfig )\n\t{\n\t\tvar\n\t\t\tthat = this,\n\t\t\toPos = $(nButton).offset(),\n\t\t\tnHidden = oConfig._collection,\n\t\t\tiDivX = oPos.left,\n\t\t\tiDivY = oPos.top + $(nButton).outerHeight(),\n\t\t\tiWinHeight = $(window).height(), iDocHeight = $(document).height(),\n\t\t\tiWinWidth = $(window).width(), iDocWidth = $(document).width();\n\n\t\tnHidden.style.position = \"absolute\";\n\t\tnHidden.style.left = iDivX+\"px\";\n\t\tnHidden.style.top = iDivY+\"px\";\n\t\tnHidden.style.display = \"block\";\n\t\t$(nHidden).css('opacity',0);\n\n\t\tvar nBackground = document.createElement('div');\n\t\tnBackground.style.position = \"absolute\";\n\t\tnBackground.style.left = \"0px\";\n\t\tnBackground.style.top = \"0px\";\n\t\tnBackground.style.height = ((iWinHeight>iDocHeight)? iWinHeight : iDocHeight) +\"px\";\n\t\tnBackground.style.width = ((iWinWidth>iDocWidth)? iWinWidth : iDocWidth) +\"px\";\n\t\tnBackground.className = this.classes.collection.background;\n\t\t$(nBackground).css('opacity',0);\n\n\t\tdocument.body.appendChild( nBackground );\n\t\tdocument.body.appendChild( nHidden );\n\n\t\t/* Visual corrections to try and keep the collection visible */\n\t\tvar iDivWidth = $(nHidden).outerWidth();\n\t\tvar iDivHeight = $(nHidden).outerHeight();\n\n\t\tif ( iDivX + iDivWidth > iDocWidth )\n\t\t{\n\t\t\tnHidden.style.left = (iDocWidth-iDivWidth)+\"px\";\n\t\t}\n\n\t\tif ( iDivY + iDivHeight > iDocHeight )\n\t\t{\n\t\t\tnHidden.style.top = (iDivY-iDivHeight-$(nButton).outerHeight())+\"px\";\n\t\t}\n\n\t\tthis.dom.collection.collection = nHidden;\n\t\tthis.dom.collection.background = nBackground;\n\n\t\t/* This results in a very small delay for the end user but it allows the animation to be\n\t\t * much smoother. If you don't want the animation, then the setTimeout can be removed\n\t\t */\n\t\tsetTimeout( function () {\n\t\t\t$(nHidden).animate({\"opacity\": 1}, 500);\n\t\t\t$(nBackground).animate({\"opacity\": 0.25}, 500);\n\t\t}, 10 );\n\n\t\t/* Resize the buttons to the Flash contents fit */\n\t\tthis.fnResizeButtons();\n\n\t\t/* Event handler to remove the collection display */\n\t\t$(nBackground).click( function () {\n\t\t\tthat._fnCollectionHide.call( that, null, null );\n\t\t} );\n\t},\n\n\n\t/**\n\t * Hide a button collection\n\t *  @param   {Node} nButton Button to use for the collection\n\t *  @param   {Object} oConfig Button configuration object\n\t *  @returns void\n\t *  @private\n\t */\n\t\"_fnCollectionHide\": function ( nButton, oConfig )\n\t{\n\t\tif ( oConfig !== null && oConfig.sExtends == 'collection' )\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.dom.collection.collection !== null )\n\t\t{\n\t\t\t$(this.dom.collection.collection).animate({\"opacity\": 0}, 500, function (e) {\n\t\t\t\tthis.style.display = \"none\";\n\t\t\t} );\n\n\t\t\t$(this.dom.collection.background).animate({\"opacity\": 0}, 500, function (e) {\n\t\t\t\tthis.parentNode.removeChild( this );\n\t\t\t} );\n\n\t\t\tthis.dom.collection.collection = null;\n\t\t\tthis.dom.collection.background = null;\n\t\t}\n\t},\n\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Row selection functions\n\t */\n\n\t/**\n\t * Add event handlers to a table to allow for row selection\n\t *  @method  _fnRowSelectConfig\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnRowSelectConfig\": function ()\n\t{\n\t\tif ( this.s.master )\n\t\t{\n\t\t\tvar\n\t\t\t\tthat = this,\n\t\t\t\ti, iLen,\n\t\t\t\tdt = this.s.dt,\n\t\t\t\taoOpenRows = this.s.dt.aoOpenRows;\n\n\t\t\t$(dt.nTable).addClass( this.classes.select.table );\n\n\t\t\t// When using OS style selection, we want to cancel the shift text\n\t\t\t// selection, but only when the shift key is used (so you can\n\t\t\t// actually still select text in the table)\n\t\t\tif ( this.s.select.type === 'os' ) {\n\t\t\t\t$(dt.nTBody).on( 'mousedown.DTTT_Select', 'tr', function(e) {\n\t\t\t\t\tif ( e.shiftKey ) {\n\n\t\t\t\t\t\t$(dt.nTBody)\n\t\t\t\t\t\t\t.css( '-moz-user-select', 'none' )\n\t\t\t\t\t\t\t.one('selectstart.DTTT_Select', 'tr', function () {\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t}\n\t\t\t\t} );\n\n\t\t\t\t$(dt.nTBody).on( 'mouseup.DTTT_Select', 'tr', function(e) {\n\t\t\t\t\t$(dt.nTBody).css( '-moz-user-select', '' );\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\t// Row selection\n\t\t\t$(dt.nTBody).on( 'click.DTTT_Select', this.s.custom.sRowSelector, function(e) {\n\t\t\t\tvar row = this.nodeName.toLowerCase() === 'tr' ?\n\t\t\t\t\tthis :\n\t\t\t\t\t$(this).parents('tr')[0];\n\n\t\t\t\tvar select = that.s.select;\n\t\t\t\tvar pos = that.s.dt.oInstance.fnGetPosition( row );\n\n\t\t\t\t/* Sub-table must be ignored (odd that the selector won't do this with >) */\n\t\t\t\tif ( row.parentNode != dt.nTBody ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t/* Check that we are actually working with a DataTables controlled row */\n\t\t\t\tif ( dt.oInstance.fnGetData(row) === null ) {\n\t\t\t\t    return;\n\t\t\t\t}\n\n\t\t\t\t// Shift click, ctrl click and simple click handling to make\n\t\t\t\t// row selection a lot like a file system in desktop OSs\n\t\t\t\tif ( select.type == 'os' ) {\n\t\t\t\t\tif ( e.ctrlKey || e.metaKey ) {\n\t\t\t\t\t\t// Add or remove from the selection\n\t\t\t\t\t\tif ( that.fnIsSelected( row ) ) {\n\t\t\t\t\t\t\tthat._fnRowDeselect( row, e );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tthat._fnRowSelect( row, e );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse if ( e.shiftKey ) {\n\t\t\t\t\t\t// Add a range of rows, from the last selected row to\n\t\t\t\t\t\t// this one\n\t\t\t\t\t\tvar rowIdxs = that.s.dt.aiDisplay.slice(); // visible rows\n\t\t\t\t\t\tvar idx1 = $.inArray( select.lastRow, rowIdxs );\n\t\t\t\t\t\tvar idx2 = $.inArray( pos, rowIdxs );\n\n\t\t\t\t\t\tif ( that.fnGetSelected().length === 0 || idx1 === -1 ) {\n\t\t\t\t\t\t\t// select from top to here - slightly odd, but both\n\t\t\t\t\t\t\t// Windows and Mac OS do this\n\t\t\t\t\t\t\trowIdxs.splice( $.inArray( pos, rowIdxs )+1, rowIdxs.length );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t// reverse so we can shift click 'up' as well as down\n\t\t\t\t\t\t\tif ( idx1 > idx2 ) {\n\t\t\t\t\t\t\t\tvar tmp = idx2;\n\t\t\t\t\t\t\t\tidx2 = idx1;\n\t\t\t\t\t\t\t\tidx1 = tmp;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\trowIdxs.splice( idx2+1, rowIdxs.length );\n\t\t\t\t\t\t\trowIdxs.splice( 0, idx1 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ( ! that.fnIsSelected( row ) ) {\n\t\t\t\t\t\t\t// Select range\n\t\t\t\t\t\t\tthat._fnRowSelect( rowIdxs, e );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t// Deselect range - need to keep the clicked on row selected\n\t\t\t\t\t\t\trowIdxs.splice( $.inArray( pos, rowIdxs ), 1 );\n\t\t\t\t\t\t\tthat._fnRowDeselect( rowIdxs, e );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\t// No cmd or shift click. Deselect current if selected,\n\t\t\t\t\t\t// or select this row only\n\t\t\t\t\t\tif ( that.fnIsSelected( row ) && that.fnGetSelected().length === 1 ) {\n\t\t\t\t\t\t\tthat._fnRowDeselect( row, e );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tthat.fnSelectNone();\n\t\t\t\t\t\t\tthat._fnRowSelect( row, e );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if ( that.fnIsSelected( row ) ) {\n\t\t\t\t\tthat._fnRowDeselect( row, e );\n\t\t\t\t}\n\t\t\t\telse if ( select.type == \"single\" ) {\n\t\t\t\t\tthat.fnSelectNone();\n\t\t\t\t\tthat._fnRowSelect( row, e );\n\t\t\t\t}\n\t\t\t\telse if ( select.type == \"multi\" ) {\n\t\t\t\t\tthat._fnRowSelect( row, e );\n\t\t\t\t}\n\n\t\t\t\tselect.lastRow = pos;\n\t\t\t} );//.on('selectstart', function () { return false; } );\n\n\t\t\t// Bind a listener to the DataTable for when new rows are created.\n\t\t\t// This allows rows to be visually selected when they should be and\n\t\t\t// deferred rendering is used.\n\t\t\tdt.oApi._fnCallbackReg( dt, 'aoRowCreatedCallback', function (tr, data, index) {\n\t\t\t\tif ( dt.aoData[index]._DTTT_selected ) {\n\t\t\t\t\t$(tr).addClass( that.classes.select.row );\n\t\t\t\t}\n\t\t\t}, 'TableTools-SelectAll' );\n\t\t}\n\t},\n\n\t/**\n\t * Select rows\n\t *  @param   {*} src Rows to select - see _fnSelectData for a description of valid inputs\n\t *  @private \n\t */\n\t\"_fnRowSelect\": function ( src, e )\n\t{\n\t\tvar\n\t\t\tthat = this,\n\t\t\tdata = this._fnSelectData( src ),\n\t\t\tfirstTr = data.length===0 ? null : data[0].nTr,\n\t\t\tanSelected = [],\n\t\t\ti, len;\n\n\t\t// Get all the rows that will be selected\n\t\tfor ( i=0, len=data.length ; i<len ; i++ )\n\t\t{\n\t\t\tif ( data[i].nTr )\n\t\t\t{\n\t\t\t\tanSelected.push( data[i].nTr );\n\t\t\t}\n\t\t}\n\n\t\t// User defined pre-selection function\n\t\tif ( this.s.select.preRowSelect !== null && !this.s.select.preRowSelect.call(this, e, anSelected, true) )\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\t// Mark them as selected\n\t\tfor ( i=0, len=data.length ; i<len ; i++ )\n\t\t{\n\t\t\tdata[i]._DTTT_selected = true;\n\n\t\t\tif ( data[i].nTr )\n\t\t\t{\n\t\t\t\t$(data[i].nTr).addClass( that.classes.select.row );\n\t\t\t}\n\t\t}\n\n\t\t// Post-selection function\n\t\tif ( this.s.select.postSelected !== null )\n\t\t{\n\t\t\tthis.s.select.postSelected.call( this, anSelected );\n\t\t}\n\n\t\tTableTools._fnEventDispatch( this, 'select', anSelected, true );\n\t},\n\n\t/**\n\t * Deselect rows\n\t *  @param   {*} src Rows to deselect - see _fnSelectData for a description of valid inputs\n\t *  @private \n\t */\n\t\"_fnRowDeselect\": function ( src, e )\n\t{\n\t\tvar\n\t\t\tthat = this,\n\t\t\tdata = this._fnSelectData( src ),\n\t\t\tfirstTr = data.length===0 ? null : data[0].nTr,\n\t\t\tanDeselectedTrs = [],\n\t\t\ti, len;\n\n\t\t// Get all the rows that will be deselected\n\t\tfor ( i=0, len=data.length ; i<len ; i++ )\n\t\t{\n\t\t\tif ( data[i].nTr )\n\t\t\t{\n\t\t\t\tanDeselectedTrs.push( data[i].nTr );\n\t\t\t}\n\t\t}\n\n\t\t// User defined pre-selection function\n\t\tif ( this.s.select.preRowSelect !== null && !this.s.select.preRowSelect.call(this, e, anDeselectedTrs, false) )\n\t\t{\n\t\t\treturn;\n\t\t}\n\n\t\t// Mark them as deselected\n\t\tfor ( i=0, len=data.length ; i<len ; i++ )\n\t\t{\n\t\t\tdata[i]._DTTT_selected = false;\n\n\t\t\tif ( data[i].nTr )\n\t\t\t{\n\t\t\t\t$(data[i].nTr).removeClass( that.classes.select.row );\n\t\t\t}\n\t\t}\n\n\t\t// Post-deselection function\n\t\tif ( this.s.select.postDeselected !== null )\n\t\t{\n\t\t\tthis.s.select.postDeselected.call( this, anDeselectedTrs );\n\t\t}\n\n\t\tTableTools._fnEventDispatch( this, 'select', anDeselectedTrs, false );\n\t},\n\n\t/**\n\t * Take a data source for row selection and convert it into aoData points for the DT\n\t *   @param {*} src Can be a single DOM TR node, an array of TR nodes (including a\n\t *     a jQuery object), a single aoData point from DataTables, an array of aoData\n\t *     points or an array of aoData indexes\n\t *   @returns {array} An array of aoData points\n\t */\n\t\"_fnSelectData\": function ( src )\n\t{\n\t\tvar out = [], pos, i, iLen;\n\n\t\tif ( src.nodeName )\n\t\t{\n\t\t\t// Single node\n\t\t\tpos = this.s.dt.oInstance.fnGetPosition( src );\n\t\t\tout.push( this.s.dt.aoData[pos] );\n\t\t}\n\t\telse if ( typeof src.length !== 'undefined' )\n\t\t{\n\t\t\t// jQuery object or an array of nodes, or aoData points\n\t\t\tfor ( i=0, iLen=src.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tif ( src[i].nodeName )\n\t\t\t\t{\n\t\t\t\t\tpos = this.s.dt.oInstance.fnGetPosition( src[i] );\n\t\t\t\t\tout.push( this.s.dt.aoData[pos] );\n\t\t\t\t}\n\t\t\t\telse if ( typeof src[i] === 'number' )\n\t\t\t\t{\n\t\t\t\t\tout.push( this.s.dt.aoData[ src[i] ] );\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\tout.push( src[i] );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn out;\n\t\t}\n\t\telse if ( typeof src === 'number' )\n\t\t{\n\t\t\tout.push(this.s.dt.aoData[src]);\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// A single aoData point\n\t\t\tout.push( src );\n\t\t}\n\n\t\treturn out;\n\t},\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Text button functions\n\t */\n\n\t/**\n\t * Configure a text based button for interaction events\n\t *  @method  _fnTextConfig\n\t *  @param   {Node} nButton Button element which is being considered\n\t *  @param   {Object} oConfig Button configuration object\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnTextConfig\": function ( nButton, oConfig )\n\t{\n\t\tvar that = this;\n\n\t\tif ( oConfig.fnInit !== null )\n\t\t{\n\t\t\toConfig.fnInit.call( this, nButton, oConfig );\n\t\t}\n\n\t\tif ( oConfig.sToolTip !== \"\" )\n\t\t{\n\t\t\tnButton.title = oConfig.sToolTip;\n\t\t}\n\n\t\t$(nButton).hover( function () {\n\t\t\tif ( oConfig.fnMouseover !== null )\n\t\t\t{\n\t\t\t\toConfig.fnMouseover.call( this, nButton, oConfig, null );\n\t\t\t}\n\t\t}, function () {\n\t\t\tif ( oConfig.fnMouseout !== null )\n\t\t\t{\n\t\t\t\toConfig.fnMouseout.call( this, nButton, oConfig, null );\n\t\t\t}\n\t\t} );\n\n\t\tif ( oConfig.fnSelect !== null )\n\t\t{\n\t\t\tTableTools._fnEventListen( this, 'select', function (n) {\n\t\t\t\toConfig.fnSelect.call( that, nButton, oConfig, n );\n\t\t\t} );\n\t\t}\n\n\t\t$(nButton).click( function (e) {\n\t\t\t//e.preventDefault();\n\n\t\t\tif ( oConfig.fnClick !== null )\n\t\t\t{\n\t\t\t\toConfig.fnClick.call( that, nButton, oConfig, null, e );\n\t\t\t}\n\n\t\t\t/* Provide a complete function to match the behaviour of the flash elements */\n\t\t\tif ( oConfig.fnComplete !== null )\n\t\t\t{\n\t\t\t\toConfig.fnComplete.call( that, nButton, oConfig, null, null );\n\t\t\t}\n\n\t\t\tthat._fnCollectionHide( nButton, oConfig );\n\t\t} );\n\t},\n\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Flash button functions\n\t */\n\t\n\t/**\n\t * Check if the Flash plug-in is available\n\t *  @method  _fnHasFlash\n\t *  @returns {boolean} `true` if Flash available, `false` otherwise\n\t *  @private \n\t */\n\t\"_fnHasFlash\": function ()\n\t{\n\t\ttry {\n\t\t\tvar fo = new ActiveXObject('ShockwaveFlash.ShockwaveFlash');\n\t\t\tif (fo) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\tcatch (e) {\n\t\t\tif (\n\t\t\t\tnavigator.mimeTypes &&\n\t\t\t\tnavigator.mimeTypes['application/x-shockwave-flash'] !== undefined &&\n\t\t\t\tnavigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t},\n\n\n\t/**\n\t * Configure a flash based button for interaction events\n\t *  @method  _fnFlashConfig\n\t *  @param   {Node} nButton Button element which is being considered\n\t *  @param   {o} oConfig Button configuration object\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnFlashConfig\": function ( nButton, oConfig )\n\t{\n\t\tvar that = this;\n\t\tvar flash = new ZeroClipboard_TableTools.Client();\n\n\t\tif ( oConfig.fnInit !== null )\n\t\t{\n\t\t\toConfig.fnInit.call( this, nButton, oConfig );\n\t\t}\n\n\t\tflash.setHandCursor( true );\n\n\t\tif ( oConfig.sAction == \"flash_save\" )\n\t\t{\n\t\t\tflash.setAction( 'save' );\n\t\t\tflash.setCharSet( (oConfig.sCharSet==\"utf16le\") ? 'UTF16LE' : 'UTF8' );\n\t\t\tflash.setBomInc( oConfig.bBomInc );\n\t\t\tflash.setFileName( oConfig.sFileName.replace('*', this.fnGetTitle(oConfig)) );\n\t\t}\n\t\telse if ( oConfig.sAction == \"flash_pdf\" )\n\t\t{\n\t\t\tflash.setAction( 'pdf' );\n\t\t\tflash.setFileName( oConfig.sFileName.replace('*', this.fnGetTitle(oConfig)) );\n\t\t}\n\t\telse\n\t\t{\n\t\t\tflash.setAction( 'copy' );\n\t\t}\n\n\t\tflash.addEventListener('mouseOver', function(client) {\n\t\t\tif ( oConfig.fnMouseover !== null )\n\t\t\t{\n\t\t\t\toConfig.fnMouseover.call( that, nButton, oConfig, flash );\n\t\t\t}\n\t\t} );\n\n\t\tflash.addEventListener('mouseOut', function(client) {\n\t\t\tif ( oConfig.fnMouseout !== null )\n\t\t\t{\n\t\t\t\toConfig.fnMouseout.call( that, nButton, oConfig, flash );\n\t\t\t}\n\t\t} );\n\n\t\tflash.addEventListener('mouseDown', function(client) {\n\t\t\tif ( oConfig.fnClick !== null )\n\t\t\t{\n\t\t\t\toConfig.fnClick.call( that, nButton, oConfig, flash );\n\t\t\t}\n\t\t} );\n\n\t\tflash.addEventListener('complete', function (client, text) {\n\t\t\tif ( oConfig.fnComplete !== null )\n\t\t\t{\n\t\t\t\toConfig.fnComplete.call( that, nButton, oConfig, flash, text );\n\t\t\t}\n\t\t\tthat._fnCollectionHide( nButton, oConfig );\n\t\t} );\n\n\t\tif ( oConfig.fnSelect !== null )\n\t\t{\n\t\t\tTableTools._fnEventListen( this, 'select', function (n) {\n\t\t\t\toConfig.fnSelect.call( that, nButton, oConfig, n );\n\t\t\t} );\n\t\t}\n\n\t\tthis._fnFlashGlue( flash, nButton, oConfig.sToolTip );\n\t},\n\n\n\t/**\n\t * Wait until the id is in the DOM before we \"glue\" the swf. Note that this function will call\n\t * itself (using setTimeout) until it completes successfully\n\t *  @method  _fnFlashGlue\n\t *  @param   {Object} clip Zero clipboard object\n\t *  @param   {Node} node node to glue swf to\n\t *  @param   {String} text title of the flash movie\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnFlashGlue\": function ( flash, node, text )\n\t{\n\t\tvar that = this;\n\t\tvar id = node.getAttribute('id');\n\n\t\tif ( document.getElementById(id) )\n\t\t{\n\t\t\tflash.glue( node, text );\n\t\t}\n\t\telse\n\t\t{\n\t\t\tsetTimeout( function () {\n\t\t\t\tthat._fnFlashGlue( flash, node, text );\n\t\t\t}, 100 );\n\t\t}\n\t},\n\n\n\t/**\n\t * Set the text for the flash clip to deal with\n\t * \n\t * This function is required for large information sets. There is a limit on the \n\t * amount of data that can be transferred between Javascript and Flash in a single call, so\n\t * we use this method to build up the text in Flash by sending over chunks. It is estimated\n\t * that the data limit is around 64k, although it is undocumented, and appears to be different\n\t * between different flash versions. We chunk at 8KiB.\n\t *  @method  _fnFlashSetText\n\t *  @param   {Object} clip the ZeroClipboard object\n\t *  @param   {String} sData the data to be set\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnFlashSetText\": function ( clip, sData )\n\t{\n\t\tvar asData = this._fnChunkData( sData, 8192 );\n\n\t\tclip.clearText();\n\t\tfor ( var i=0, iLen=asData.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tclip.appendText( asData[i] );\n\t\t}\n\t},\n\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Data retrieval functions\n\t */\n\n\t/**\n\t * Convert the mixed columns variable into a boolean array the same size as the columns, which\n\t * indicates which columns we want to include\n\t *  @method  _fnColumnTargets\n\t *  @param   {String|Array} mColumns The columns to be included in data retrieval. If a string\n\t *\t\t\t then it can take the value of \"visible\" or \"hidden\" (to include all visible or\n\t *\t\t\t hidden columns respectively). Or an array of column indexes\n\t *  @returns {Array} A boolean array the length of the columns of the table, which each value\n\t *\t\t\t indicating if the column is to be included or not\n\t *  @private \n\t */\n\t\"_fnColumnTargets\": function ( mColumns )\n\t{\n\t\tvar aColumns = [];\n\t\tvar dt = this.s.dt;\n\t\tvar i, iLen;\n\t\tvar columns = dt.aoColumns;\n\t\tvar columnCount = columns.length;\n\n\t\tif ( typeof mColumns == \"function\" )\n\t\t{\n\t\t\tvar a = mColumns.call( this, dt );\n\n\t\t\tfor ( i=0, iLen=columnCount ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\taColumns.push( $.inArray( i, a ) !== -1 ? true : false );\n\t\t\t}\n\t\t}\n\t\telse if ( typeof mColumns == \"object\" )\n\t\t{\n\t\t\tfor ( i=0, iLen=columnCount ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\taColumns.push( false );\n\t\t\t}\n\n\t\t\tfor ( i=0, iLen=mColumns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\taColumns[ mColumns[i] ] = true;\n\t\t\t}\n\t\t}\n\t\telse if ( mColumns == \"visible\" )\n\t\t{\n\t\t\tfor ( i=0, iLen=columnCount ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\taColumns.push( columns[i].bVisible ? true : false );\n\t\t\t}\n\t\t}\n\t\telse if ( mColumns == \"hidden\" )\n\t\t{\n\t\t\tfor ( i=0, iLen=columnCount ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\taColumns.push( columns[i].bVisible ? false : true );\n\t\t\t}\n\t\t}\n\t\telse if ( mColumns == \"sortable\" )\n\t\t{\n\t\t\tfor ( i=0, iLen=columnCount ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\taColumns.push( columns[i].bSortable ? true : false );\n\t\t\t}\n\t\t}\n\t\telse /* all */\n\t\t{\n\t\t\tfor ( i=0, iLen=columnCount ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\taColumns.push( true );\n\t\t\t}\n\t\t}\n\n\t\treturn aColumns;\n\t},\n\n\n\t/**\n\t * New line character(s) depend on the platforms\n\t *  @method  method\n\t *  @param   {Object} oConfig Button configuration object - only interested in oConfig.sNewLine\n\t *  @returns {String} Newline character\n\t */\n\t\"_fnNewline\": function ( oConfig )\n\t{\n\t\tif ( oConfig.sNewLine == \"auto\" )\n\t\t{\n\t\t\treturn navigator.userAgent.match(/Windows/) ? \"\\r\\n\" : \"\\n\";\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn oConfig.sNewLine;\n\t\t}\n\t},\n\n\n\t/**\n\t * Get data from DataTables' internals and format it for output\n\t *  @method  _fnGetDataTablesData\n\t *  @param   {Object} oConfig Button configuration object\n\t *  @param   {String} oConfig.sFieldBoundary Field boundary for the data cells in the string\n\t *  @param   {String} oConfig.sFieldSeperator Field separator for the data cells\n\t *  @param   {String} oConfig.sNewline New line options\n\t *  @param   {Mixed} oConfig.mColumns Which columns should be included in the output\n\t *  @param   {Boolean} oConfig.bHeader Include the header\n\t *  @param   {Boolean} oConfig.bFooter Include the footer\n\t *  @param   {Boolean} oConfig.bSelectedOnly Include only the selected rows in the output\n\t *  @returns {String} Concatenated string of data\n\t *  @private \n\t */\n\t\"_fnGetDataTablesData\": function ( oConfig )\n\t{\n\t\tvar i, iLen, j, jLen;\n\t\tvar aRow, aData=[], sLoopData='', arr;\n\t\tvar dt = this.s.dt, tr, child;\n\t\tvar regex = new RegExp(oConfig.sFieldBoundary, \"g\"); /* Do it here for speed */\n\t\tvar aColumnsInc = this._fnColumnTargets( oConfig.mColumns );\n\t\tvar bSelectedOnly = (typeof oConfig.bSelectedOnly != 'undefined') ? oConfig.bSelectedOnly : false;\n\n\t\t/*\n\t\t * Header\n\t\t */\n\t\tif ( oConfig.bHeader )\n\t\t{\n\t\t\taRow = [];\n\n\t\t\tfor ( i=0, iLen=dt.aoColumns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tif ( aColumnsInc[i] )\n\t\t\t\t{\n\t\t\t\t\tsLoopData = dt.aoColumns[i].sTitle.replace(/\\n/g,\" \").replace( /<.*?>/g, \"\" ).replace(/^\\s+|\\s+$/g,\"\");\n\t\t\t\t\tsLoopData = this._fnHtmlDecode( sLoopData );\n\n\t\t\t\t\taRow.push( this._fnBoundData( sLoopData, oConfig.sFieldBoundary, regex ) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\taData.push( aRow.join(oConfig.sFieldSeperator) );\n\t\t}\n\n\t\tbSelectedOnly = true;\n\n\t\t/*\n\t\t * Body\n\t\t */\n\t\tvar aDataIndex;\n\t\tvar aSelected = this.fnGetSelectedIndexes();\n\t\tbSelectedOnly = this.s.select.type !== \"none\" && bSelectedOnly && aSelected.length !== 0;\n\n\t\tif ( bSelectedOnly ) {\n\t\t\t// Use the selected indexes\n\t\t\taDataIndex = aSelected;\n\t\t}\n\t\telse if ( DataTable.Api ) {\n\t\t\t// 1.10+ style\n\t\t\taDataIndex = new DataTable.Api( dt )\n\t\t\t\t.rows( oConfig.oSelectorOpts )\n\t\t\t\t.indexes()\n\t\t\t\t.flatten()\n\t\t\t\t.toArray();\n\t\t}\n\t\telse {\n\t\t\t// 1.9- style\n\t\t\taDataIndex = dt.oInstance\n\t\t\t\t.$('tr', oConfig.oSelectorOpts)\n\t\t\t\t.map( function (id, row) {\n\t\t\t\t\treturn dt.oInstance.fnGetPosition( row );\n\t\t\t\t} )\n\t\t\t\t.get();\n\t\t}\n\n\t\tfor ( j=0, jLen=aDataIndex.length ; j<jLen ; j++ )\n\t\t{\n\t\t\ttr = dt.aoData[ aDataIndex[j] ].nTr;\n\t\t\taRow = [];\n\n\t\t\t/* Columns */\n\t\t\tfor ( i=0, iLen=dt.aoColumns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tif ( aColumnsInc[i] )\n\t\t\t\t{\n\t\t\t\t\t/* Convert to strings (with small optimisation) */\n\t\t\t\t\tvar mTypeData = dt.oApi._fnGetCellData( dt, aDataIndex[j], i, 'display' );\n\t\t\t\t\tif ( oConfig.fnCellRender )\n\t\t\t\t\t{\n\t\t\t\t\t\tsLoopData = oConfig.fnCellRender( mTypeData, i, tr, aDataIndex[j] )+\"\";\n\t\t\t\t\t}\n\t\t\t\t\telse if ( typeof mTypeData == \"string\" )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Strip newlines, replace img tags with alt attr. and finally strip html... */\n\t\t\t\t\t\tsLoopData = mTypeData.replace(/\\n/g,\" \");\n\t\t\t\t\t\tsLoopData =\n\t\t\t\t\t\t    sLoopData.replace(/<img.*?\\s+alt\\s*=\\s*(?:\"([^\"]+)\"|'([^']+)'|([^\\s>]+)).*?>/gi,\n\t\t\t\t\t\t        '$1$2$3');\n\t\t\t\t\t\tsLoopData = sLoopData.replace( /<.*?>/g, \"\" );\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tsLoopData = mTypeData+\"\";\n\t\t\t\t\t}\n\n\t\t\t\t\t/* Trim and clean the data */\n\t\t\t\t\tsLoopData = sLoopData.replace(/^\\s+/, '').replace(/\\s+$/, '');\n\t\t\t\t\tsLoopData = this._fnHtmlDecode( sLoopData );\n\n\t\t\t\t\t/* Bound it and add it to the total data */\n\t\t\t\t\taRow.push( this._fnBoundData( sLoopData, oConfig.sFieldBoundary, regex ) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\taData.push( aRow.join(oConfig.sFieldSeperator) );\n\n\t\t\t/* Details rows from fnOpen */\n\t\t\tif ( oConfig.bOpenRows )\n\t\t\t{\n\t\t\t\tarr = $.grep(dt.aoOpenRows, function(o) { return o.nParent === tr; });\n\n\t\t\t\tif ( arr.length === 1 )\n\t\t\t\t{\n\t\t\t\t\tsLoopData = this._fnBoundData( $('td', arr[0].nTr).html(), oConfig.sFieldBoundary, regex );\n\t\t\t\t\taData.push( sLoopData );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/*\n\t\t * Footer\n\t\t */\n\t\tif ( oConfig.bFooter && dt.nTFoot !== null )\n\t\t{\n\t\t\taRow = [];\n\n\t\t\tfor ( i=0, iLen=dt.aoColumns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tif ( aColumnsInc[i] && dt.aoColumns[i].nTf !== null )\n\t\t\t\t{\n\t\t\t\t\tsLoopData = dt.aoColumns[i].nTf.innerHTML.replace(/\\n/g,\" \").replace( /<.*?>/g, \"\" );\n\t\t\t\t\tsLoopData = this._fnHtmlDecode( sLoopData );\n\n\t\t\t\t\taRow.push( this._fnBoundData( sLoopData, oConfig.sFieldBoundary, regex ) );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\taData.push( aRow.join(oConfig.sFieldSeperator) );\n\t\t}\n\n\t\tvar _sLastData = aData.join( this._fnNewline(oConfig) );\n\t\treturn _sLastData;\n\t},\n\n\n\t/**\n\t * Wrap data up with a boundary string\n\t *  @method  _fnBoundData\n\t *  @param   {String} sData data to bound\n\t *  @param   {String} sBoundary bounding char(s)\n\t *  @param   {RegExp} regex search for the bounding chars - constructed outside for efficiency\n\t *\t\t\t in the loop\n\t *  @returns {String} bound data\n\t *  @private \n\t */\n\t\"_fnBoundData\": function ( sData, sBoundary, regex )\n\t{\n\t\tif ( sBoundary === \"\" )\n\t\t{\n\t\t\treturn sData;\n\t\t}\n\t\telse\n\t\t{\n\t\t\treturn sBoundary + sData.replace(regex, sBoundary+sBoundary) + sBoundary;\n\t\t}\n\t},\n\n\n\t/**\n\t * Break a string up into an array of smaller strings\n\t *  @method  _fnChunkData\n\t *  @param   {String} sData data to be broken up\n\t *  @param   {Int} iSize chunk size\n\t *  @returns {Array} String array of broken up text\n\t *  @private \n\t */\n\t\"_fnChunkData\": function ( sData, iSize )\n\t{\n\t\tvar asReturn = [];\n\t\tvar iStrlen = sData.length;\n\n\t\tfor ( var i=0 ; i<iStrlen ; i+=iSize )\n\t\t{\n\t\t\tif ( i+iSize < iStrlen )\n\t\t\t{\n\t\t\t\tasReturn.push( sData.substring( i, i+iSize ) );\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tasReturn.push( sData.substring( i, iStrlen ) );\n\t\t\t}\n\t\t}\n\n\t\treturn asReturn;\n\t},\n\n\n\t/**\n\t * Decode HTML entities\n\t *  @method  _fnHtmlDecode\n\t *  @param   {String} sData encoded string\n\t *  @returns {String} decoded string\n\t *  @private \n\t */\n\t\"_fnHtmlDecode\": function ( sData )\n\t{\n\t\tif ( sData.indexOf('&') === -1 )\n\t\t{\n\t\t\treturn sData;\n\t\t}\n\n\t\tvar n = document.createElement('div');\n\n\t\treturn sData.replace( /&([^\\s]*?);/g, function( match, match2 ) {\n\t\t\tif ( match.substr(1, 1) === '#' )\n\t\t\t{\n\t\t\t\treturn String.fromCharCode( Number(match2.substr(1)) );\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tn.innerHTML = match;\n\t\t\t\treturn n.childNodes[0].nodeValue;\n\t\t\t}\n\t\t} );\n\t},\n\n\n\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Printing functions\n\t */\n\n\t/**\n\t * Show print display\n\t *  @method  _fnPrintStart\n\t *  @param   {Event} e Event object\n\t *  @param   {Object} oConfig Button configuration object\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnPrintStart\": function ( oConfig )\n\t{\n\t  var that = this;\n\t  var oSetDT = this.s.dt;\n\n\t\t/* Parse through the DOM hiding everything that isn't needed for the table */\n\t\tthis._fnPrintHideNodes( oSetDT.nTable );\n\n\t\t/* Show the whole table */\n\t\tthis.s.print.saveStart = oSetDT._iDisplayStart;\n\t\tthis.s.print.saveLength = oSetDT._iDisplayLength;\n\n\t\tif ( oConfig.bShowAll )\n\t\t{\n\t\t\toSetDT._iDisplayStart = 0;\n\t\t\toSetDT._iDisplayLength = -1;\n\t\t\tif ( oSetDT.oApi._fnCalculateEnd ) {\n\t\t\t\toSetDT.oApi._fnCalculateEnd( oSetDT );\n\t\t\t}\n\t\t\toSetDT.oApi._fnDraw( oSetDT );\n\t\t}\n\n\t\t/* Adjust the display for scrolling which might be done by DataTables */\n\t\tif ( oSetDT.oScroll.sX !== \"\" || oSetDT.oScroll.sY !== \"\" )\n\t\t{\n\t\t\tthis._fnPrintScrollStart( oSetDT );\n\n\t\t\t// If the table redraws while in print view, the DataTables scrolling\n\t\t\t// setup would hide the header, so we need to readd it on draw\n\t\t\t$(this.s.dt.nTable).bind('draw.DTTT_Print', function () {\n\t\t\t\tthat._fnPrintScrollStart( oSetDT );\n\t\t\t} );\n\t\t}\n\n\t\t/* Remove the other DataTables feature nodes - but leave the table! and info div */\n\t\tvar anFeature = oSetDT.aanFeatures;\n\t\tfor ( var cFeature in anFeature )\n\t\t{\n\t\t\tif ( cFeature != 'i' && cFeature != 't' && cFeature.length == 1 )\n\t\t\t{\n\t\t\t\tfor ( var i=0, iLen=anFeature[cFeature].length ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\tthis.dom.print.hidden.push( {\n\t\t\t\t\t\t\"node\": anFeature[cFeature][i],\n\t\t\t\t\t\t\"display\": \"block\"\n\t\t\t\t\t} );\n\t\t\t\t\tanFeature[cFeature][i].style.display = \"none\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t/* Print class can be used for styling */\n\t\t$(document.body).addClass( this.classes.print.body );\n\n\t\t/* Show information message to let the user know what is happening */\n\t\tif ( oConfig.sInfo !== \"\" )\n\t\t{\n\t\t\tthis.fnInfo( oConfig.sInfo, 3000 );\n\t\t}\n\n\t\t/* Add a message at the top of the page */\n\t\tif ( oConfig.sMessage )\n\t\t{\n\t\t\t$('<div/>')\n\t\t\t\t.addClass( this.classes.print.message )\n\t\t\t\t.html( oConfig.sMessage )\n\t\t\t\t.prependTo( 'body' );\n\t\t}\n\n\t\t/* Cache the scrolling and the jump to the top of the page */\n\t\tthis.s.print.saveScroll = $(window).scrollTop();\n\t\twindow.scrollTo( 0, 0 );\n\n\t\t/* Bind a key event listener to the document for the escape key -\n\t\t * it is removed in the callback\n\t\t */\n\t\t$(document).bind( \"keydown.DTTT\", function(e) {\n\t\t\t/* Only interested in the escape key */\n\t\t\tif ( e.keyCode == 27 )\n\t\t\t{\n\t\t\t\te.preventDefault();\n\t\t\t\tthat._fnPrintEnd.call( that, e );\n\t\t\t}\n\t\t} );\n\t},\n\n\n\t/**\n\t * Printing is finished, resume normal display\n\t *  @method  _fnPrintEnd\n\t *  @param   {Event} e Event object\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnPrintEnd\": function ( e )\n\t{\n\t\tvar that = this;\n\t\tvar oSetDT = this.s.dt;\n\t\tvar oSetPrint = this.s.print;\n\t\tvar oDomPrint = this.dom.print;\n\n\t\t/* Show all hidden nodes */\n\t\tthis._fnPrintShowNodes();\n\n\t\t/* Restore DataTables' scrolling */\n\t\tif ( oSetDT.oScroll.sX !== \"\" || oSetDT.oScroll.sY !== \"\" )\n\t\t{\n\t\t\t$(this.s.dt.nTable).unbind('draw.DTTT_Print');\n\n\t\t\tthis._fnPrintScrollEnd();\n\t\t}\n\n\t\t/* Restore the scroll */\n\t\twindow.scrollTo( 0, oSetPrint.saveScroll );\n\n\t\t/* Drop the print message */\n\t\t$('div.'+this.classes.print.message).remove();\n\n\t\t/* Styling class */\n\t\t$(document.body).removeClass( 'DTTT_Print' );\n\n\t\t/* Restore the table length */\n\t\toSetDT._iDisplayStart = oSetPrint.saveStart;\n\t\toSetDT._iDisplayLength = oSetPrint.saveLength;\n\t\tif ( oSetDT.oApi._fnCalculateEnd ) {\n\t\t\toSetDT.oApi._fnCalculateEnd( oSetDT );\n\t\t}\n\t\toSetDT.oApi._fnDraw( oSetDT );\n\n\t\t$(document).unbind( \"keydown.DTTT\" );\n\t},\n\n\n\t/**\n\t * Take account of scrolling in DataTables by showing the full table\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnPrintScrollStart\": function ()\n\t{\n\t\tvar\n\t\t\toSetDT = this.s.dt,\n\t\t\tnScrollHeadInner = oSetDT.nScrollHead.getElementsByTagName('div')[0],\n\t\t\tnScrollHeadTable = nScrollHeadInner.getElementsByTagName('table')[0],\n\t\t\tnScrollBody = oSetDT.nTable.parentNode,\n\t\t\tnTheadSize, nTfootSize;\n\n\t\t/* Copy the header in the thead in the body table, this way we show one single table when\n\t\t * in print view. Note that this section of code is more or less verbatim from DT 1.7.0\n\t\t */\n\t\tnTheadSize = oSetDT.nTable.getElementsByTagName('thead');\n\t\tif ( nTheadSize.length > 0 )\n\t\t{\n\t\t\toSetDT.nTable.removeChild( nTheadSize[0] );\n\t\t}\n\n\t\tif ( oSetDT.nTFoot !== null )\n\t\t{\n\t\t\tnTfootSize = oSetDT.nTable.getElementsByTagName('tfoot');\n\t\t\tif ( nTfootSize.length > 0 )\n\t\t\t{\n\t\t\t\toSetDT.nTable.removeChild( nTfootSize[0] );\n\t\t\t}\n\t\t}\n\n\t\tnTheadSize = oSetDT.nTHead.cloneNode(true);\n\t\toSetDT.nTable.insertBefore( nTheadSize, oSetDT.nTable.childNodes[0] );\n\n\t\tif ( oSetDT.nTFoot !== null )\n\t\t{\n\t\t\tnTfootSize = oSetDT.nTFoot.cloneNode(true);\n\t\t\toSetDT.nTable.insertBefore( nTfootSize, oSetDT.nTable.childNodes[1] );\n\t\t}\n\n\t\t/* Now adjust the table's viewport so we can actually see it */\n\t\tif ( oSetDT.oScroll.sX !== \"\" )\n\t\t{\n\t\t\toSetDT.nTable.style.width = $(oSetDT.nTable).outerWidth()+\"px\";\n\t\t\tnScrollBody.style.width = $(oSetDT.nTable).outerWidth()+\"px\";\n\t\t\tnScrollBody.style.overflow = \"visible\";\n\t\t}\n\n\t\tif ( oSetDT.oScroll.sY !== \"\" )\n\t\t{\n\t\t\tnScrollBody.style.height = $(oSetDT.nTable).outerHeight()+\"px\";\n\t\t\tnScrollBody.style.overflow = \"visible\";\n\t\t}\n\t},\n\n\n\t/**\n\t * Take account of scrolling in DataTables by showing the full table. Note that the redraw of\n\t * the DataTable that we do will actually deal with the majority of the hard work here\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnPrintScrollEnd\": function ()\n\t{\n\t\tvar\n\t\t\toSetDT = this.s.dt,\n\t\t\tnScrollBody = oSetDT.nTable.parentNode;\n\n\t\tif ( oSetDT.oScroll.sX !== \"\" )\n\t\t{\n\t\t\tnScrollBody.style.width = oSetDT.oApi._fnStringToCss( oSetDT.oScroll.sX );\n\t\t\tnScrollBody.style.overflow = \"auto\";\n\t\t}\n\n\t\tif ( oSetDT.oScroll.sY !== \"\" )\n\t\t{\n\t\t\tnScrollBody.style.height = oSetDT.oApi._fnStringToCss( oSetDT.oScroll.sY );\n\t\t\tnScrollBody.style.overflow = \"auto\";\n\t\t}\n\t},\n\n\n\t/**\n\t * Resume the display of all TableTools hidden nodes\n\t *  @method  _fnPrintShowNodes\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnPrintShowNodes\": function ( )\n\t{\n\t  var anHidden = this.dom.print.hidden;\n\n\t\tfor ( var i=0, iLen=anHidden.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tanHidden[i].node.style.display = anHidden[i].display;\n\t\t}\n\t\tanHidden.splice( 0, anHidden.length );\n\t},\n\n\n\t/**\n\t * Hide nodes which are not needed in order to display the table. Note that this function is\n\t * recursive\n\t *  @method  _fnPrintHideNodes\n\t *  @param   {Node} nNode Element which should be showing in a 'print' display\n\t *  @returns void\n\t *  @private \n\t */\n\t\"_fnPrintHideNodes\": function ( nNode )\n\t{\n\t\tvar anHidden = this.dom.print.hidden;\n\n\t\tvar nParent = nNode.parentNode;\n\t\tvar nChildren = nParent.childNodes;\n\t\tfor ( var i=0, iLen=nChildren.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tif ( nChildren[i] != nNode && nChildren[i].nodeType == 1 )\n\t\t\t{\n\t\t\t\t/* If our node is shown (don't want to show nodes which were previously hidden) */\n\t\t\t\tvar sDisplay = $(nChildren[i]).css(\"display\");\n\t\t\t\tif ( sDisplay != \"none\" )\n\t\t\t\t{\n\t\t\t\t\t/* Cache the node and it's previous state so we can restore it */\n\t\t\t\t\tanHidden.push( {\n\t\t\t\t\t\t\"node\": nChildren[i],\n\t\t\t\t\t\t\"display\": sDisplay\n\t\t\t\t\t} );\n\t\t\t\t\tnChildren[i].style.display = \"none\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( nParent.nodeName.toUpperCase() != \"BODY\" )\n\t\t{\n\t\t\tthis._fnPrintHideNodes( nParent );\n\t\t}\n\t}\n};\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Static variables\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/**\n * Store of all instances that have been created of TableTools, so one can look up other (when\n * there is need of a master)\n *  @property _aInstances\n *  @type\t Array\n *  @default  []\n *  @private\n */\nTableTools._aInstances = [];\n\n\n/**\n * Store of all listeners and their callback functions\n *  @property _aListeners\n *  @type\t Array\n *  @default  []\n */\nTableTools._aListeners = [];\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Static methods\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/**\n * Get an array of all the master instances\n *  @method  fnGetMasters\n *  @returns {Array} List of master TableTools instances\n *  @static\n */\nTableTools.fnGetMasters = function ()\n{\n\tvar a = [];\n\tfor ( var i=0, iLen=TableTools._aInstances.length ; i<iLen ; i++ )\n\t{\n\t\tif ( TableTools._aInstances[i].s.master )\n\t\t{\n\t\t\ta.push( TableTools._aInstances[i] );\n\t\t}\n\t}\n\treturn a;\n};\n\n/**\n * Get the master instance for a table node (or id if a string is given)\n *  @method  fnGetInstance\n *  @returns {Object} ID of table OR table node, for which we want the TableTools instance\n *  @static\n */\nTableTools.fnGetInstance = function ( node )\n{\n\tif ( typeof node != 'object' )\n\t{\n\t\tnode = document.getElementById(node);\n\t}\n\n\tfor ( var i=0, iLen=TableTools._aInstances.length ; i<iLen ; i++ )\n\t{\n\t\tif ( TableTools._aInstances[i].s.master && TableTools._aInstances[i].dom.table == node )\n\t\t{\n\t\t\treturn TableTools._aInstances[i];\n\t\t}\n\t}\n\treturn null;\n};\n\n\n/**\n * Add a listener for a specific event\n *  @method  _fnEventListen\n *  @param   {Object} that Scope of the listening function (i.e. 'this' in the caller)\n *  @param   {String} type Event type\n *  @param   {Function} fn Function\n *  @returns void\n *  @private\n *  @static\n */\nTableTools._fnEventListen = function ( that, type, fn )\n{\n\tTableTools._aListeners.push( {\n\t\t\"that\": that,\n\t\t\"type\": type,\n\t\t\"fn\": fn\n\t} );\n};\n\n\n/**\n * An event has occurred - look up every listener and fire it off. We check that the event we are\n * going to fire is attached to the same table (using the table node as reference) before firing\n *  @method  _fnEventDispatch\n *  @param   {Object} that Scope of the listening function (i.e. 'this' in the caller)\n *  @param   {String} type Event type\n *  @param   {Node} node Element that the event occurred on (may be null)\n *  @param   {boolean} [selected] Indicate if the node was selected (true) or deselected (false)\n *  @returns void\n *  @private\n *  @static\n */\nTableTools._fnEventDispatch = function ( that, type, node, selected )\n{\n\tvar listeners = TableTools._aListeners;\n\tfor ( var i=0, iLen=listeners.length ; i<iLen ; i++ )\n\t{\n\t\tif ( that.dom.table == listeners[i].that.dom.table && listeners[i].type == type )\n\t\t{\n\t\t\tlisteners[i].fn( node, selected );\n\t\t}\n\t}\n};\n\n\n\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Constants\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n\n\nTableTools.buttonBase = {\n\t// Button base\n\t\"sAction\": \"text\",\n\t\"sTag\": \"default\",\n\t\"sLinerTag\": \"default\",\n\t\"sButtonClass\": \"DTTT_button_text\",\n\t\"sButtonText\": \"Button text\",\n\t\"sTitle\": \"\",\n\t\"sToolTip\": \"\",\n\n\t// Common button specific options\n\t\"sCharSet\": \"utf8\",\n\t\"bBomInc\": false,\n\t\"sFileName\": \"*.csv\",\n\t\"sFieldBoundary\": \"\",\n\t\"sFieldSeperator\": \"\\t\",\n\t\"sNewLine\": \"auto\",\n\t\"mColumns\": \"all\", /* \"all\", \"visible\", \"hidden\" or array of column integers */\n\t\"bHeader\": true,\n\t\"bFooter\": true,\n\t\"bOpenRows\": false,\n\t\"bSelectedOnly\": false,\n\t\"oSelectorOpts\": undefined, // See http://datatables.net/docs/DataTables/1.9.4/#$ for full options\n\n\t// Callbacks\n\t\"fnMouseover\": null,\n\t\"fnMouseout\": null,\n\t\"fnClick\": null,\n\t\"fnSelect\": null,\n\t\"fnComplete\": null,\n\t\"fnInit\": null,\n\t\"fnCellRender\": null\n};\n\n\n/**\n * @namespace Default button configurations\n */\nTableTools.BUTTONS = {\n\t\"csv\": $.extend( {}, TableTools.buttonBase, {\n\t\t\"sAction\": \"flash_save\",\n\t\t\"sButtonClass\": \"DTTT_button_csv\",\n\t\t\"sButtonText\": \"CSV\",\n\t\t\"sFieldBoundary\": '\"',\n\t\t\"sFieldSeperator\": \",\",\n\t\t\"fnClick\": function( nButton, oConfig, flash ) {\n\t\t\tthis.fnSetText( flash, this.fnGetTableData(oConfig) );\n\t\t}\n\t} ),\n\n\t\"xls\": $.extend( {}, TableTools.buttonBase, {\n\t\t\"sAction\": \"flash_save\",\n\t\t\"sCharSet\": \"utf16le\",\n\t\t\"bBomInc\": true,\n\t\t\"sButtonClass\": \"DTTT_button_xls\",\n\t\t\"sButtonText\": \"Excel\",\n\t\t\"fnClick\": function( nButton, oConfig, flash ) {\n\t\t\tthis.fnSetText( flash, this.fnGetTableData(oConfig) );\n\t\t}\n\t} ),\n\n\t\"copy\": $.extend( {}, TableTools.buttonBase, {\n\t\t\"sAction\": \"flash_copy\",\n\t\t\"sButtonClass\": \"DTTT_button_copy\",\n\t\t\"sButtonText\": \"Copy\",\n\t\t\"fnClick\": function( nButton, oConfig, flash ) {\n\t\t\tthis.fnSetText( flash, this.fnGetTableData(oConfig) );\n\t\t},\n\t\t\"fnComplete\": function(nButton, oConfig, flash, text) {\n\t\t\tvar lines = text.split('\\n').length;\n            if (oConfig.bHeader) lines--;\n            if (this.s.dt.nTFoot !== null && oConfig.bFooter) lines--;\n\t\t\tvar plural = (lines==1) ? \"\" : \"s\";\n\t\t\tthis.fnInfo( '<h6>Table copied</h6>'+\n\t\t\t\t'<p>Copied '+lines+' row'+plural+' to the clipboard.</p>',\n\t\t\t\t1500\n\t\t\t);\n\t\t}\n\t} ),\n\n\t\"pdf\": $.extend( {}, TableTools.buttonBase, {\n\t\t\"sAction\": \"flash_pdf\",\n\t\t\"sNewLine\": \"\\n\",\n\t\t\"sFileName\": \"*.pdf\",\n\t\t\"sButtonClass\": \"DTTT_button_pdf\",\n\t\t\"sButtonText\": \"PDF\",\n\t\t\"sPdfOrientation\": \"portrait\",\n\t\t\"sPdfSize\": \"A4\",\n\t\t\"sPdfMessage\": \"\",\n\t\t\"fnClick\": function( nButton, oConfig, flash ) {\n\t\t\tthis.fnSetText( flash,\n\t\t\t\t\"title:\"+ this.fnGetTitle(oConfig) +\"\\n\"+\n\t\t\t\t\"message:\"+ oConfig.sPdfMessage +\"\\n\"+\n\t\t\t\t\"colWidth:\"+ this.fnCalcColRatios(oConfig) +\"\\n\"+\n\t\t\t\t\"orientation:\"+ oConfig.sPdfOrientation +\"\\n\"+\n\t\t\t\t\"size:\"+ oConfig.sPdfSize +\"\\n\"+\n\t\t\t\t\"--/TableToolsOpts--\\n\" +\n\t\t\t\tthis.fnGetTableData(oConfig)\n\t\t\t);\n\t\t}\n\t} ),\n\n\t\"print\": $.extend( {}, TableTools.buttonBase, {\n\t\t\"sInfo\": \"<h6>Print view</h6><p>Please use your browser's print function to \"+\n\t\t  \"print this table. Press escape when finished.</p>\",\n\t\t\"sMessage\": null,\n\t\t\"bShowAll\": true,\n\t\t\"sToolTip\": \"View print view\",\n\t\t\"sButtonClass\": \"DTTT_button_print\",\n\t\t\"sButtonText\": \"Print\",\n\t\t\"fnClick\": function ( nButton, oConfig ) {\n\t\t\tthis.fnPrint( true, oConfig );\n\t\t}\n\t} ),\n\n\t\"text\": $.extend( {}, TableTools.buttonBase ),\n\n\t\"select\": $.extend( {}, TableTools.buttonBase, {\n\t\t\"sButtonText\": \"Select button\",\n\t\t\"fnSelect\": function( nButton, oConfig ) {\n\t\t\tif ( this.fnGetSelected().length !== 0 ) {\n\t\t\t\t$(nButton).removeClass( this.classes.buttons.disabled );\n\t\t\t} else {\n\t\t\t\t$(nButton).addClass( this.classes.buttons.disabled );\n\t\t\t}\n\t\t},\n\t\t\"fnInit\": function( nButton, oConfig ) {\n\t\t\t$(nButton).addClass( this.classes.buttons.disabled );\n\t\t}\n\t} ),\n\n\t\"select_single\": $.extend( {}, TableTools.buttonBase, {\n\t\t\"sButtonText\": \"Select button\",\n\t\t\"fnSelect\": function( nButton, oConfig ) {\n\t\t\tvar iSelected = this.fnGetSelected().length;\n\t\t\tif ( iSelected == 1 ) {\n\t\t\t\t$(nButton).removeClass( this.classes.buttons.disabled );\n\t\t\t} else {\n\t\t\t\t$(nButton).addClass( this.classes.buttons.disabled );\n\t\t\t}\n\t\t},\n\t\t\"fnInit\": function( nButton, oConfig ) {\n\t\t\t$(nButton).addClass( this.classes.buttons.disabled );\n\t\t}\n\t} ),\n\n\t\"select_all\": $.extend( {}, TableTools.buttonBase, {\n\t\t\"sButtonText\": \"Select all\",\n\t\t\"fnClick\": function( nButton, oConfig ) {\n\t\t\tthis.fnSelectAll();\n\t\t},\n\t\t\"fnSelect\": function( nButton, oConfig ) {\n\t\t\tif ( this.fnGetSelected().length == this.s.dt.fnRecordsDisplay() ) {\n\t\t\t\t$(nButton).addClass( this.classes.buttons.disabled );\n\t\t\t} else {\n\t\t\t\t$(nButton).removeClass( this.classes.buttons.disabled );\n\t\t\t}\n\t\t}\n\t} ),\n\n\t\"select_none\": $.extend( {}, TableTools.buttonBase, {\n\t\t\"sButtonText\": \"Deselect all\",\n\t\t\"fnClick\": function( nButton, oConfig ) {\n\t\t\tthis.fnSelectNone();\n\t\t},\n\t\t\"fnSelect\": function( nButton, oConfig ) {\n\t\t\tif ( this.fnGetSelected().length !== 0 ) {\n\t\t\t\t$(nButton).removeClass( this.classes.buttons.disabled );\n\t\t\t} else {\n\t\t\t\t$(nButton).addClass( this.classes.buttons.disabled );\n\t\t\t}\n\t\t},\n\t\t\"fnInit\": function( nButton, oConfig ) {\n\t\t\t$(nButton).addClass( this.classes.buttons.disabled );\n\t\t}\n\t} ),\n\n\t\"ajax\": $.extend( {}, TableTools.buttonBase, {\n\t\t\"sAjaxUrl\": \"/xhr.php\",\n\t\t\"sButtonText\": \"Ajax button\",\n\t\t\"fnClick\": function( nButton, oConfig ) {\n\t\t\tvar sData = this.fnGetTableData(oConfig);\n\t\t\t$.ajax( {\n\t\t\t\t\"url\": oConfig.sAjaxUrl,\n\t\t\t\t\"data\": [\n\t\t\t\t\t{ \"name\": \"tableData\", \"value\": sData }\n\t\t\t\t],\n\t\t\t\t\"success\": oConfig.fnAjaxComplete,\n\t\t\t\t\"dataType\": \"json\",\n\t\t\t\t\"type\": \"POST\",\n\t\t\t\t\"cache\": false,\n\t\t\t\t\"error\": function () {\n\t\t\t\t\talert( \"Error detected when sending table data to server\" );\n\t\t\t\t}\n\t\t\t} );\n\t\t},\n\t\t\"fnAjaxComplete\": function( json ) {\n\t\t\talert( 'Ajax complete' );\n\t\t}\n\t} ),\n\n\t\"div\": $.extend( {}, TableTools.buttonBase, {\n\t\t\"sAction\": \"div\",\n\t\t\"sTag\": \"div\",\n\t\t\"sButtonClass\": \"DTTT_nonbutton\",\n\t\t\"sButtonText\": \"Text button\"\n\t} ),\n\n\t\"collection\": $.extend( {}, TableTools.buttonBase, {\n\t\t\"sAction\": \"collection\",\n\t\t\"sButtonClass\": \"DTTT_button_collection\",\n\t\t\"sButtonText\": \"Collection\",\n\t\t\"fnClick\": function( nButton, oConfig ) {\n\t\t\tthis._fnCollectionShow(nButton, oConfig);\n\t\t}\n\t} )\n};\n/*\n *  on* callback parameters:\n *     1. node - button element\n *     2. object - configuration object for this button\n *     3. object - ZeroClipboard reference (flash button only)\n *     4. string - Returned string from Flash (flash button only - and only on 'complete')\n */\n\n// Alias to match the other plug-ins styling\nTableTools.buttons = TableTools.BUTTONS;\n\n\n/**\n * @namespace Classes used by TableTools - allows the styles to be override easily.\n *   Note that when TableTools initialises it will take a copy of the classes object\n *   and will use its internal copy for the remainder of its run time.\n */\nTableTools.classes = {\n\t\"container\": \"DTTT_container\",\n\t\"buttons\": {\n\t\t\"normal\": \"DTTT_button\",\n\t\t\"disabled\": \"DTTT_disabled\"\n\t},\n\t\"collection\": {\n\t\t\"container\": \"DTTT_collection\",\n\t\t\"background\": \"DTTT_collection_background\",\n\t\t\"buttons\": {\n\t\t\t\"normal\": \"DTTT_button\",\n\t\t\t\"disabled\": \"DTTT_disabled\"\n\t\t}\n\t},\n\t\"select\": {\n\t\t\"table\": \"DTTT_selectable\",\n\t\t\"row\": \"DTTT_selected selected\"\n\t},\n\t\"print\": {\n\t\t\"body\": \"DTTT_Print\",\n\t\t\"info\": \"DTTT_print_info\",\n\t\t\"message\": \"DTTT_PrintMessage\"\n\t}\n};\n\n\n/**\n * @namespace ThemeRoller classes - built in for compatibility with DataTables' \n *   bJQueryUI option.\n */\nTableTools.classes_themeroller = {\n\t\"container\": \"DTTT_container ui-buttonset ui-buttonset-multi\",\n\t\"buttons\": {\n\t\t\"normal\": \"DTTT_button ui-button ui-state-default\"\n\t},\n\t\"collection\": {\n\t\t\"container\": \"DTTT_collection ui-buttonset ui-buttonset-multi\"\n\t}\n};\n\n\n/**\n * @namespace TableTools default settings for initialisation\n */\nTableTools.DEFAULTS = {\n\t\"sSwfPath\":        \"../swf/copy_csv_xls_pdf.swf\",\n\t\"sRowSelect\":      \"none\",\n\t\"sRowSelector\":    \"tr\",\n\t\"sSelectedClass\":  null,\n\t\"fnPreRowSelect\":  null,\n\t\"fnRowSelected\":   null,\n\t\"fnRowDeselected\": null,\n\t\"aButtons\":        [ \"copy\", \"csv\", \"xls\", \"pdf\", \"print\" ],\n\t\"oTags\": {\n\t\t\"container\": \"div\",\n\t\t\"button\": \"a\", // We really want to use buttons here, but Firefox and IE ignore the\n\t\t                 // click on the Flash element in the button (but not mouse[in|out]).\n\t\t\"liner\": \"span\",\n\t\t\"collection\": {\n\t\t\t\"container\": \"div\",\n\t\t\t\"button\": \"a\",\n\t\t\t\"liner\": \"span\"\n\t\t}\n\t}\n};\n\n// Alias to match the other plug-ins\nTableTools.defaults = TableTools.DEFAULTS;\n\n\n/**\n * Name of this class\n *  @constant CLASS\n *  @type\t String\n *  @default  TableTools\n */\nTableTools.prototype.CLASS = \"TableTools\";\n\n\n/**\n * TableTools version\n *  @constant  VERSION\n *  @type\t  String\n *  @default   See code\n */\nTableTools.version = \"2.2.4\";\n\n\n\n// DataTables 1.10 API\n// \n// This will be extended in a big way in in TableTools 3 to provide API methods\n// such as rows().select() and rows.selected() etc, but for the moment the\n// tabletools() method simply returns the instance.\n\nif ( $.fn.dataTable.Api ) {\n\t$.fn.dataTable.Api.register( 'tabletools()', function () {\n\t\tvar tt = null;\n\n\t\tif ( this.context.length > 0 ) {\n\t\t\ttt = TableTools.fnGetInstance( this.context[0].nTable );\n\t\t}\n\n\t\treturn tt;\n\t} );\n}\n\n\n\n\n/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n * Initialisation\n * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */\n\n/*\n * Register a new feature with DataTables\n */\nif ( typeof $.fn.dataTable == \"function\" &&\n\t typeof $.fn.dataTableExt.fnVersionCheck == \"function\" &&\n\t $.fn.dataTableExt.fnVersionCheck('1.9.0') )\n{\n\t$.fn.dataTableExt.aoFeatures.push( {\n\t\t\"fnInit\": function( oDTSettings ) {\n\t\t\tvar init = oDTSettings.oInit;\n\t\t\tvar opts = init ?\n\t\t\t\tinit.tableTools || init.oTableTools || {} :\n\t\t\t\t{};\n\n\t\t\treturn new TableTools( oDTSettings.oInstance, opts ).dom.container;\n\t\t},\n\t\t\"cFeature\": \"T\",\n\t\t\"sFeature\": \"TableTools\"\n\t} );\n}\nelse\n{\n\talert( \"Warning: TableTools requires DataTables 1.9.0 or newer - www.datatables.net/download\");\n}\n\n$.fn.DataTable.TableTools = TableTools;\n\n})(jQuery, window, document);\n\n/*\n * Register a new feature with DataTables\n */\nif ( typeof $.fn.dataTable == \"function\" &&\n\t typeof $.fn.dataTableExt.fnVersionCheck == \"function\" &&\n\t $.fn.dataTableExt.fnVersionCheck('1.9.0') )\n{\n\t$.fn.dataTableExt.aoFeatures.push( {\n\t\t\"fnInit\": function( oDTSettings ) {\n\t\t\tvar oOpts = typeof oDTSettings.oInit.oTableTools != 'undefined' ?\n\t\t\t\toDTSettings.oInit.oTableTools : {};\n\n\t\t\tvar oTT = new TableTools( oDTSettings.oInstance, oOpts );\n\t\t\tTableTools._aInstances.push( oTT );\n\n\t\t\treturn oTT.dom.container;\n\t\t},\n\t\t\"cFeature\": \"T\",\n\t\t\"sFeature\": \"TableTools\"\n\t} );\n}\nelse\n{\n\talert( \"Warning: TableTools 2 requires DataTables 1.9.0 or newer - www.datatables.net/download\");\n}\n\n\n$.fn.dataTable.TableTools = TableTools;\n$.fn.DataTable.TableTools = TableTools;\n\n\nreturn TableTools;\n}; // /factory\n\n\n// Define as an AMD module if possible\nif ( typeof define === 'function' && define.amd ) {\n\tdefine( ['jquery', 'datatables'], factory );\n}\nelse if ( typeof exports === 'object' ) {\n    // Node/CommonJS\n    factory( require('jquery'), require('datatables') );\n}\nelse if ( jQuery && !jQuery.fn.dataTable.TableTools ) {\n\t// Otherwise simply initialise as normal, stopping multiple evaluation\n\tfactory( jQuery, jQuery.fn.dataTable );\n}\n\n\n})(window, document);\n\n"
  },
  {
    "path": "public/static/plugins/datatables/jquery.dataTables.css",
    "content": "/*\n * Table styles\n */\ntable.dataTable {\n  width: 100%;\n  margin: 0 auto;\n  clear: both;\n  border-collapse: separate;\n  border-spacing: 0;\n  /*\n   * Header and footer styles\n   */\n  /*\n   * Body styles\n   */\n}\ntable.dataTable thead th,\ntable.dataTable tfoot th {\n  font-weight: bold;\n}\ntable.dataTable thead th,\ntable.dataTable thead td {\n  padding: 10px 18px;\n  border-bottom: 1px solid #111;\n}\ntable.dataTable thead th:active,\ntable.dataTable thead td:active {\n  outline: none;\n}\ntable.dataTable tfoot th,\ntable.dataTable tfoot td {\n  padding: 10px 18px 6px 18px;\n  border-top: 1px solid #111;\n}\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc {\n  cursor: pointer;\n  *cursor: hand;\n}\ntable.dataTable thead .sorting,\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc,\ntable.dataTable thead .sorting_asc_disabled,\ntable.dataTable thead .sorting_desc_disabled {\n  background-repeat: no-repeat;\n  background-position: center right;\n}\ntable.dataTable thead .sorting {\n  background-image: url(\"images/sort_both.png\");\n}\ntable.dataTable thead .sorting_asc {\n  background-image: url(\"images/sort_asc.png\");\n}\ntable.dataTable thead .sorting_desc {\n  background-image: url(\"images/sort_desc.png\");\n}\ntable.dataTable thead .sorting_asc_disabled {\n  background-image: url(\"images/sort_asc_disabled.png\");\n}\ntable.dataTable thead .sorting_desc_disabled {\n  background-image: url(\"images/sort_desc_disabled.png\");\n}\ntable.dataTable tbody tr {\n  background-color: #ffffff;\n}\ntable.dataTable tbody tr.selected {\n  background-color: #B0BED9;\n}\ntable.dataTable tbody th,\ntable.dataTable tbody td {\n  padding: 8px 10px;\n}\ntable.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {\n  border-top: 1px solid #ddd;\n}\ntable.dataTable.row-border tbody tr:first-child th,\ntable.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,\ntable.dataTable.display tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {\n  border-top: 1px solid #ddd;\n  border-right: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr th:first-child,\ntable.dataTable.cell-border tbody tr td:first-child {\n  border-left: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr:first-child th,\ntable.dataTable.cell-border tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {\n  background-color: #f9f9f9;\n}\ntable.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {\n  background-color: #abb9d3;\n}\ntable.dataTable.hover tbody tr:hover, table.dataTable.display tbody tr:hover {\n  background-color: whitesmoke;\n}\ntable.dataTable.hover tbody tr:hover.selected, table.dataTable.display tbody tr:hover.selected {\n  background-color: #a9b7d1;\n}\ntable.dataTable.order-column tbody tr > .sorting_1,\ntable.dataTable.order-column tbody tr > .sorting_2,\ntable.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,\ntable.dataTable.display tbody tr > .sorting_2,\ntable.dataTable.display tbody tr > .sorting_3 {\n  background-color: #f9f9f9;\n}\ntable.dataTable.order-column tbody tr.selected > .sorting_1,\ntable.dataTable.order-column tbody tr.selected > .sorting_2,\ntable.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,\ntable.dataTable.display tbody tr.selected > .sorting_2,\ntable.dataTable.display tbody tr.selected > .sorting_3 {\n  background-color: #acbad4;\n}\ntable.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {\n  background-color: #f1f1f1;\n}\ntable.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {\n  background-color: #f3f3f3;\n}\ntable.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {\n  background-color: whitesmoke;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {\n  background-color: #a6b3cd;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {\n  background-color: #a7b5ce;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {\n  background-color: #a9b6d0;\n}\ntable.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {\n  background-color: #f9f9f9;\n}\ntable.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {\n  background-color: #fbfbfb;\n}\ntable.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {\n  background-color: #fdfdfd;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {\n  background-color: #acbad4;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {\n  background-color: #adbbd6;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {\n  background-color: #afbdd8;\n}\ntable.dataTable.display tbody tr:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1 {\n  background-color: #eaeaea;\n}\ntable.dataTable.display tbody tr:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2 {\n  background-color: #ebebeb;\n}\ntable.dataTable.display tbody tr:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3 {\n  background-color: #eeeeee;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1 {\n  background-color: #a1aec7;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2 {\n  background-color: #a2afc8;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3 {\n  background-color: #a4b2cb;\n}\ntable.dataTable.no-footer {\n  border-bottom: 1px solid #111;\n}\ntable.dataTable.nowrap th, table.dataTable.nowrap td {\n  white-space: nowrap;\n}\ntable.dataTable.compact thead th,\ntable.dataTable.compact thead td {\n  padding: 4px 17px 4px 4px;\n}\ntable.dataTable.compact tfoot th,\ntable.dataTable.compact tfoot td {\n  padding: 4px;\n}\ntable.dataTable.compact tbody th,\ntable.dataTable.compact tbody td {\n  padding: 4px;\n}\ntable.dataTable th.dt-left,\ntable.dataTable td.dt-left {\n  text-align: left;\n}\ntable.dataTable th.dt-center,\ntable.dataTable td.dt-center,\ntable.dataTable td.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable th.dt-right,\ntable.dataTable td.dt-right {\n  text-align: right;\n}\ntable.dataTable th.dt-justify,\ntable.dataTable td.dt-justify {\n  text-align: justify;\n}\ntable.dataTable th.dt-nowrap,\ntable.dataTable td.dt-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable thead th.dt-head-left,\ntable.dataTable thead td.dt-head-left,\ntable.dataTable tfoot th.dt-head-left,\ntable.dataTable tfoot td.dt-head-left {\n  text-align: left;\n}\ntable.dataTable thead th.dt-head-center,\ntable.dataTable thead td.dt-head-center,\ntable.dataTable tfoot th.dt-head-center,\ntable.dataTable tfoot td.dt-head-center {\n  text-align: center;\n}\ntable.dataTable thead th.dt-head-right,\ntable.dataTable thead td.dt-head-right,\ntable.dataTable tfoot th.dt-head-right,\ntable.dataTable tfoot td.dt-head-right {\n  text-align: right;\n}\ntable.dataTable thead th.dt-head-justify,\ntable.dataTable thead td.dt-head-justify,\ntable.dataTable tfoot th.dt-head-justify,\ntable.dataTable tfoot td.dt-head-justify {\n  text-align: justify;\n}\ntable.dataTable thead th.dt-head-nowrap,\ntable.dataTable thead td.dt-head-nowrap,\ntable.dataTable tfoot th.dt-head-nowrap,\ntable.dataTable tfoot td.dt-head-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable tbody th.dt-body-left,\ntable.dataTable tbody td.dt-body-left {\n  text-align: left;\n}\ntable.dataTable tbody th.dt-body-center,\ntable.dataTable tbody td.dt-body-center {\n  text-align: center;\n}\ntable.dataTable tbody th.dt-body-right,\ntable.dataTable tbody td.dt-body-right {\n  text-align: right;\n}\ntable.dataTable tbody th.dt-body-justify,\ntable.dataTable tbody td.dt-body-justify {\n  text-align: justify;\n}\ntable.dataTable tbody th.dt-body-nowrap,\ntable.dataTable tbody td.dt-body-nowrap {\n  white-space: nowrap;\n}\n\ntable.dataTable,\ntable.dataTable th,\ntable.dataTable td {\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n}\n\n/*\n * Control feature layout\n */\n.dataTables_wrapper {\n  position: relative;\n  clear: both;\n  *zoom: 1;\n  zoom: 1;\n}\n.dataTables_wrapper .dataTables_length {\n  float: left;\n}\n.dataTables_wrapper .dataTables_filter {\n  float: right;\n  text-align: right;\n}\n.dataTables_wrapper .dataTables_filter input {\n  margin-left: 0.5em;\n}\n.dataTables_wrapper .dataTables_info {\n  clear: both;\n  float: left;\n  padding-top: 0.755em;\n}\n.dataTables_wrapper .dataTables_paginate {\n  float: right;\n  text-align: right;\n  padding-top: 0.25em;\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button {\n  box-sizing: border-box;\n  display: inline-block;\n  min-width: 1.5em;\n  padding: 0.5em 1em;\n  margin-left: 2px;\n  text-align: center;\n  text-decoration: none !important;\n  cursor: pointer;\n  *cursor: hand;\n  color: #333 !important;\n  border: 1px solid transparent;\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button.current, .dataTables_wrapper .dataTables_paginate .paginate_button.current:hover {\n  color: #333 !important;\n  border: 1px solid #cacaca;\n  background-color: white;\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, white), color-stop(100%, #dcdcdc));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(top, white 0%, #dcdcdc 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to bottom, white 0%, #dcdcdc 100%);\n  /* W3C */\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button.disabled, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:hover, .dataTables_wrapper .dataTables_paginate .paginate_button.disabled:active {\n  cursor: default;\n  color: #666 !important;\n  border: 1px solid transparent;\n  background: transparent;\n  box-shadow: none;\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button:hover {\n  color: white !important;\n  border: 1px solid #111;\n  background-color: #585858;\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #585858), color-stop(100%, #111));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(top, #585858 0%, #111 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(top, #585858 0%, #111 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(top, #585858 0%, #111 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(top, #585858 0%, #111 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to bottom, #585858 0%, #111 100%);\n  /* W3C */\n}\n.dataTables_wrapper .dataTables_paginate .paginate_button:active {\n  outline: none;\n  background-color: #2b2b2b;\n  background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #2b2b2b), color-stop(100%, #0c0c0c));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(top, #2b2b2b 0%, #0c0c0c 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to bottom, #2b2b2b 0%, #0c0c0c 100%);\n  /* W3C */\n  box-shadow: inset 0 0 3px #111;\n}\n.dataTables_wrapper .dataTables_paginate .ellipsis {\n  padding: 0 1em;\n}\n.dataTables_wrapper .dataTables_processing {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 100%;\n  height: 40px;\n  margin-left: -50%;\n  margin-top: -25px;\n  padding-top: 20px;\n  text-align: center;\n  font-size: 1.2em;\n  background-color: white;\n  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* W3C */\n}\n.dataTables_wrapper .dataTables_length,\n.dataTables_wrapper .dataTables_filter,\n.dataTables_wrapper .dataTables_info,\n.dataTables_wrapper .dataTables_processing,\n.dataTables_wrapper .dataTables_paginate {\n  color: #333;\n}\n.dataTables_wrapper .dataTables_scroll {\n  clear: both;\n}\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody {\n  *margin-top: -1px;\n  -webkit-overflow-scrolling: touch;\n}\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody th > div.dataTables_sizing,\n.dataTables_wrapper .dataTables_scroll div.dataTables_scrollBody td > div.dataTables_sizing {\n  height: 0;\n  overflow: hidden;\n  margin: 0 !important;\n  padding: 0 !important;\n}\n.dataTables_wrapper.no-footer .dataTables_scrollBody {\n  border-bottom: 1px solid #111;\n}\n.dataTables_wrapper.no-footer div.dataTables_scrollHead table,\n.dataTables_wrapper.no-footer div.dataTables_scrollBody table {\n  border-bottom: none;\n}\n.dataTables_wrapper:after {\n  visibility: hidden;\n  display: block;\n  content: \"\";\n  clear: both;\n  height: 0;\n}\n\n@media screen and (max-width: 767px) {\n  .dataTables_wrapper .dataTables_info,\n  .dataTables_wrapper .dataTables_paginate {\n    float: none;\n    text-align: center;\n  }\n  .dataTables_wrapper .dataTables_paginate {\n    margin-top: 0.5em;\n  }\n}\n@media screen and (max-width: 640px) {\n  .dataTables_wrapper .dataTables_length,\n  .dataTables_wrapper .dataTables_filter {\n    float: none;\n    text-align: center;\n  }\n  .dataTables_wrapper .dataTables_filter {\n    margin-top: 0.5em;\n  }\n}\n"
  },
  {
    "path": "public/static/plugins/datatables/jquery.dataTables.js",
    "content": "/*! DataTables 1.10.7\n * ©2008-2014 SpryMedia Ltd - datatables.net/license\n */\n\n/**\n * @summary     DataTables\n * @description Paginate, search and order HTML tables\n * @version     1.10.7\n * @file        jquery.dataTables.js\n * @author      SpryMedia Ltd (www.sprymedia.co.uk)\n * @contact     www.sprymedia.co.uk/contact\n * @copyright   Copyright 2008-2014 SpryMedia Ltd.\n *\n * This source file is free software, available under the following license:\n *   MIT license - http://datatables.net/license\n *\n * This source file is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n * or FITNESS FOR A PARTICULAR PURPOSE. See the license files for details.\n *\n * For details please refer to: http://www.datatables.net\n */\n\n/*jslint evil: true, undef: true, browser: true */\n/*globals $,require,jQuery,define,_selector_run,_selector_opts,_selector_first,_selector_row_indexes,_ext,_Api,_api_register,_api_registerPlural,_re_new_lines,_re_html,_re_formatted_numeric,_re_escape_regex,_empty,_intVal,_numToDecimal,_isNumber,_isHtml,_htmlNumeric,_pluck,_pluck_order,_range,_stripHtml,_unique,_fnBuildAjax,_fnAjaxUpdate,_fnAjaxParameters,_fnAjaxUpdateDraw,_fnAjaxDataSrc,_fnAddColumn,_fnColumnOptions,_fnAdjustColumnSizing,_fnVisibleToColumnIndex,_fnColumnIndexToVisible,_fnVisbleColumns,_fnGetColumns,_fnColumnTypes,_fnApplyColumnDefs,_fnHungarianMap,_fnCamelToHungarian,_fnLanguageCompat,_fnBrowserDetect,_fnAddData,_fnAddTr,_fnNodeToDataIndex,_fnNodeToColumnIndex,_fnGetCellData,_fnSetCellData,_fnSplitObjNotation,_fnGetObjectDataFn,_fnSetObjectDataFn,_fnGetDataMaster,_fnClearTable,_fnDeleteIndex,_fnInvalidate,_fnGetRowElements,_fnCreateTr,_fnBuildHead,_fnDrawHead,_fnDraw,_fnReDraw,_fnAddOptionsHtml,_fnDetectHeader,_fnGetUniqueThs,_fnFeatureHtmlFilter,_fnFilterComplete,_fnFilterCustom,_fnFilterColumn,_fnFilter,_fnFilterCreateSearch,_fnEscapeRegex,_fnFilterData,_fnFeatureHtmlInfo,_fnUpdateInfo,_fnInfoMacros,_fnInitialise,_fnInitComplete,_fnLengthChange,_fnFeatureHtmlLength,_fnFeatureHtmlPaginate,_fnPageChange,_fnFeatureHtmlProcessing,_fnProcessingDisplay,_fnFeatureHtmlTable,_fnScrollDraw,_fnApplyToChildren,_fnCalculateColumnWidths,_fnThrottle,_fnConvertToWidth,_fnScrollingWidthAdjust,_fnGetWidestNode,_fnGetMaxLenString,_fnStringToCss,_fnScrollBarWidth,_fnSortFlatten,_fnSort,_fnSortAria,_fnSortListener,_fnSortAttachListener,_fnSortingClasses,_fnSortData,_fnSaveState,_fnLoadState,_fnSettingsFromNode,_fnLog,_fnMap,_fnBindAction,_fnCallbackReg,_fnCallbackFire,_fnLengthOverflow,_fnRenderer,_fnDataSource,_fnRowAttributes*/\n\n(/** @lends <global> */function( window, document, undefined ) {\n\n(function( factory ) {\n\t\"use strict\";\n\n\tif ( typeof define === 'function' && define.amd ) {\n\t\t// Define as an AMD module if possible\n\t\tdefine( 'datatables', ['jquery'], factory );\n\t}\n    else if ( typeof exports === 'object' ) {\n        // Node/CommonJS\n        module.exports = factory( require( 'jquery' ) );\n    }\n\telse if ( jQuery && !jQuery.fn.dataTable ) {\n\t\t// Define using browser globals otherwise\n\t\t// Prevent multiple instantiations if the script is loaded twice\n\t\tfactory( jQuery );\n\t}\n}\n(/** @lends <global> */function( $ ) {\n\t\"use strict\";\n\n\t/**\n\t * DataTables is a plug-in for the jQuery Javascript library. It is a highly\n\t * flexible tool, based upon the foundations of progressive enhancement,\n\t * which will add advanced interaction controls to any HTML table. For a\n\t * full list of features please refer to\n\t * [DataTables.net](href=\"http://datatables.net).\n\t *\n\t * Note that the `DataTable` object is not a global variable but is aliased\n\t * to `jQuery.fn.DataTable` and `jQuery.fn.dataTable` through which it may\n\t * be  accessed.\n\t *\n\t *  @class\n\t *  @param {object} [init={}] Configuration object for DataTables. Options\n\t *    are defined by {@link DataTable.defaults}\n\t *  @requires jQuery 1.7+\n\t *\n\t *  @example\n\t *    // Basic initialisation\n\t *    $(document).ready( function {\n\t *      $('#example').dataTable();\n\t *    } );\n\t *\n\t *  @example\n\t *    // Initialisation with configuration options - in this case, disable\n\t *    // pagination and sorting.\n\t *    $(document).ready( function {\n\t *      $('#example').dataTable( {\n\t *        \"paginate\": false,\n\t *        \"sort\": false\n\t *      } );\n\t *    } );\n\t */\n\tvar DataTable;\n\n\t\n\t/*\n\t * It is useful to have variables which are scoped locally so only the\n\t * DataTables functions can access them and they don't leak into global space.\n\t * At the same time these functions are often useful over multiple files in the\n\t * core and API, so we list, or at least document, all variables which are used\n\t * by DataTables as private variables here. This also ensures that there is no\n\t * clashing of variable names and that they can easily referenced for reuse.\n\t */\n\t\n\t\n\t// Defined else where\n\t//  _selector_run\n\t//  _selector_opts\n\t//  _selector_first\n\t//  _selector_row_indexes\n\t\n\tvar _ext; // DataTable.ext\n\tvar _Api; // DataTable.Api\n\tvar _api_register; // DataTable.Api.register\n\tvar _api_registerPlural; // DataTable.Api.registerPlural\n\t\n\tvar _re_dic = {};\n\tvar _re_new_lines = /[\\r\\n]/g;\n\tvar _re_html = /<.*?>/g;\n\tvar _re_date_start = /^[\\w\\+\\-]/;\n\tvar _re_date_end = /[\\w\\+\\-]$/;\n\t\n\t// Escape regular expression special characters\n\tvar _re_escape_regex = new RegExp( '(\\\\' + [ '/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\\\', '$', '^', '-' ].join('|\\\\') + ')', 'g' );\n\t\n\t// http://en.wikipedia.org/wiki/Foreign_exchange_market\n\t// - \\u20BD - Russian ruble.\n\t// - \\u20a9 - South Korean Won\n\t// - \\u20BA - Turkish Lira\n\t// - \\u20B9 - Indian Rupee\n\t// - R - Brazil (R$) and South Africa\n\t// - fr - Swiss Franc\n\t// - kr - Swedish krona, Norwegian krone and Danish krone\n\t// - \\u2009 is thin space and \\u202F is narrow no-break space, both used in many\n\t//   standards as thousands separators.\n\tvar _re_formatted_numeric = /[',$£€¥%\\u2009\\u202F\\u20BD\\u20a9\\u20BArfk]/gi;\n\t\n\t\n\tvar _empty = function ( d ) {\n\t\treturn !d || d === true || d === '-' ? true : false;\n\t};\n\t\n\t\n\tvar _intVal = function ( s ) {\n\t\tvar integer = parseInt( s, 10 );\n\t\treturn !isNaN(integer) && isFinite(s) ? integer : null;\n\t};\n\t\n\t// Convert from a formatted number with characters other than `.` as the\n\t// decimal place, to a Javascript number\n\tvar _numToDecimal = function ( num, decimalPoint ) {\n\t\t// Cache created regular expressions for speed as this function is called often\n\t\tif ( ! _re_dic[ decimalPoint ] ) {\n\t\t\t_re_dic[ decimalPoint ] = new RegExp( _fnEscapeRegex( decimalPoint ), 'g' );\n\t\t}\n\t\treturn typeof num === 'string' && decimalPoint !== '.' ?\n\t\t\tnum.replace( /\\./g, '' ).replace( _re_dic[ decimalPoint ], '.' ) :\n\t\t\tnum;\n\t};\n\t\n\t\n\tvar _isNumber = function ( d, decimalPoint, formatted ) {\n\t\tvar strType = typeof d === 'string';\n\t\n\t\t// If empty return immediately so there must be a number if it is a\n\t\t// formatted string (this stops the string \"k\", or \"kr\", etc being detected\n\t\t// as a formatted number for currency\n\t\tif ( _empty( d ) ) {\n\t\t\treturn true;\n\t\t}\n\t\n\t\tif ( decimalPoint && strType ) {\n\t\t\td = _numToDecimal( d, decimalPoint );\n\t\t}\n\t\n\t\tif ( formatted && strType ) {\n\t\t\td = d.replace( _re_formatted_numeric, '' );\n\t\t}\n\t\n\t\treturn !isNaN( parseFloat(d) ) && isFinite( d );\n\t};\n\t\n\t\n\t// A string without HTML in it can be considered to be HTML still\n\tvar _isHtml = function ( d ) {\n\t\treturn _empty( d ) || typeof d === 'string';\n\t};\n\t\n\t\n\tvar _htmlNumeric = function ( d, decimalPoint, formatted ) {\n\t\tif ( _empty( d ) ) {\n\t\t\treturn true;\n\t\t}\n\t\n\t\tvar html = _isHtml( d );\n\t\treturn ! html ?\n\t\t\tnull :\n\t\t\t_isNumber( _stripHtml( d ), decimalPoint, formatted ) ?\n\t\t\t\ttrue :\n\t\t\t\tnull;\n\t};\n\t\n\t\n\tvar _pluck = function ( a, prop, prop2 ) {\n\t\tvar out = [];\n\t\tvar i=0, ien=a.length;\n\t\n\t\t// Could have the test in the loop for slightly smaller code, but speed\n\t\t// is essential here\n\t\tif ( prop2 !== undefined ) {\n\t\t\tfor ( ; i<ien ; i++ ) {\n\t\t\t\tif ( a[i] && a[i][ prop ] ) {\n\t\t\t\t\tout.push( a[i][ prop ][ prop2 ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tfor ( ; i<ien ; i++ ) {\n\t\t\t\tif ( a[i] ) {\n\t\t\t\t\tout.push( a[i][ prop ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\t// Basically the same as _pluck, but rather than looping over `a` we use `order`\n\t// as the indexes to pick from `a`\n\tvar _pluck_order = function ( a, order, prop, prop2 )\n\t{\n\t\tvar out = [];\n\t\tvar i=0, ien=order.length;\n\t\n\t\t// Could have the test in the loop for slightly smaller code, but speed\n\t\t// is essential here\n\t\tif ( prop2 !== undefined ) {\n\t\t\tfor ( ; i<ien ; i++ ) {\n\t\t\t\tif ( a[ order[i] ][ prop ] ) {\n\t\t\t\t\tout.push( a[ order[i] ][ prop ][ prop2 ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tfor ( ; i<ien ; i++ ) {\n\t\t\t\tout.push( a[ order[i] ][ prop ] );\n\t\t\t}\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\tvar _range = function ( len, start )\n\t{\n\t\tvar out = [];\n\t\tvar end;\n\t\n\t\tif ( start === undefined ) {\n\t\t\tstart = 0;\n\t\t\tend = len;\n\t\t}\n\t\telse {\n\t\t\tend = start;\n\t\t\tstart = len;\n\t\t}\n\t\n\t\tfor ( var i=start ; i<end ; i++ ) {\n\t\t\tout.push( i );\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\tvar _removeEmpty = function ( a )\n\t{\n\t\tvar out = [];\n\t\n\t\tfor ( var i=0, ien=a.length ; i<ien ; i++ ) {\n\t\t\tif ( a[i] ) { // careful - will remove all falsy values!\n\t\t\t\tout.push( a[i] );\n\t\t\t}\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\tvar _stripHtml = function ( d ) {\n\t\treturn d.replace( _re_html, '' );\n\t};\n\t\n\t\n\t/**\n\t * Find the unique elements in a source array.\n\t *\n\t * @param  {array} src Source array\n\t * @return {array} Array of unique items\n\t * @ignore\n\t */\n\tvar _unique = function ( src )\n\t{\n\t\t// A faster unique method is to use object keys to identify used values,\n\t\t// but this doesn't work with arrays or objects, which we must also\n\t\t// consider. See jsperf.com/compare-array-unique-versions/4 for more\n\t\t// information.\n\t\tvar\n\t\t\tout = [],\n\t\t\tval,\n\t\t\ti, ien=src.length,\n\t\t\tj, k=0;\n\t\n\t\tagain: for ( i=0 ; i<ien ; i++ ) {\n\t\t\tval = src[i];\n\t\n\t\t\tfor ( j=0 ; j<k ; j++ ) {\n\t\t\t\tif ( out[j] === val ) {\n\t\t\t\t\tcontinue again;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tout.push( val );\n\t\t\tk++;\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\t\n\t/**\n\t * Create a mapping object that allows camel case parameters to be looked up\n\t * for their Hungarian counterparts. The mapping is stored in a private\n\t * parameter called `_hungarianMap` which can be accessed on the source object.\n\t *  @param {object} o\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnHungarianMap ( o )\n\t{\n\t\tvar\n\t\t\thungarian = 'a aa ai ao as b fn i m o s ',\n\t\t\tmatch,\n\t\t\tnewKey,\n\t\t\tmap = {};\n\t\n\t\t$.each( o, function (key, val) {\n\t\t\tmatch = key.match(/^([^A-Z]+?)([A-Z])/);\n\t\n\t\t\tif ( match && hungarian.indexOf(match[1]+' ') !== -1 )\n\t\t\t{\n\t\t\t\tnewKey = key.replace( match[0], match[2].toLowerCase() );\n\t\t\t\tmap[ newKey ] = key;\n\t\n\t\t\t\tif ( match[1] === 'o' )\n\t\t\t\t{\n\t\t\t\t\t_fnHungarianMap( o[key] );\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t\n\t\to._hungarianMap = map;\n\t}\n\t\n\t\n\t/**\n\t * Convert from camel case parameters to Hungarian, based on a Hungarian map\n\t * created by _fnHungarianMap.\n\t *  @param {object} src The model object which holds all parameters that can be\n\t *    mapped.\n\t *  @param {object} user The object to convert from camel case to Hungarian.\n\t *  @param {boolean} force When set to `true`, properties which already have a\n\t *    Hungarian value in the `user` object will be overwritten. Otherwise they\n\t *    won't be.\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCamelToHungarian ( src, user, force )\n\t{\n\t\tif ( ! src._hungarianMap ) {\n\t\t\t_fnHungarianMap( src );\n\t\t}\n\t\n\t\tvar hungarianKey;\n\t\n\t\t$.each( user, function (key, val) {\n\t\t\thungarianKey = src._hungarianMap[ key ];\n\t\n\t\t\tif ( hungarianKey !== undefined && (force || user[hungarianKey] === undefined) )\n\t\t\t{\n\t\t\t\t// For objects, we need to buzz down into the object to copy parameters\n\t\t\t\tif ( hungarianKey.charAt(0) === 'o' )\n\t\t\t\t{\n\t\t\t\t\t// Copy the camelCase options over to the hungarian\n\t\t\t\t\tif ( ! user[ hungarianKey ] ) {\n\t\t\t\t\t\tuser[ hungarianKey ] = {};\n\t\t\t\t\t}\n\t\t\t\t\t$.extend( true, user[hungarianKey], user[key] );\n\t\n\t\t\t\t\t_fnCamelToHungarian( src[hungarianKey], user[hungarianKey], force );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tuser[hungarianKey] = user[ key ];\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Language compatibility - when certain options are given, and others aren't, we\n\t * need to duplicate the values over, in order to provide backwards compatibility\n\t * with older language files.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnLanguageCompat( lang )\n\t{\n\t\tvar defaults = DataTable.defaults.oLanguage;\n\t\tvar zeroRecords = lang.sZeroRecords;\n\t\n\t\t/* Backwards compatibility - if there is no sEmptyTable given, then use the same as\n\t\t * sZeroRecords - assuming that is given.\n\t\t */\n\t\tif ( ! lang.sEmptyTable && zeroRecords &&\n\t\t\tdefaults.sEmptyTable === \"No data available in table\" )\n\t\t{\n\t\t\t_fnMap( lang, lang, 'sZeroRecords', 'sEmptyTable' );\n\t\t}\n\t\n\t\t/* Likewise with loading records */\n\t\tif ( ! lang.sLoadingRecords && zeroRecords &&\n\t\t\tdefaults.sLoadingRecords === \"Loading...\" )\n\t\t{\n\t\t\t_fnMap( lang, lang, 'sZeroRecords', 'sLoadingRecords' );\n\t\t}\n\t\n\t\t// Old parameter name of the thousands separator mapped onto the new\n\t\tif ( lang.sInfoThousands ) {\n\t\t\tlang.sThousands = lang.sInfoThousands;\n\t\t}\n\t\n\t\tvar decimal = lang.sDecimal;\n\t\tif ( decimal ) {\n\t\t\t_addNumericSort( decimal );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Map one parameter onto another\n\t *  @param {object} o Object to map\n\t *  @param {*} knew The new parameter name\n\t *  @param {*} old The old parameter name\n\t */\n\tvar _fnCompatMap = function ( o, knew, old ) {\n\t\tif ( o[ knew ] !== undefined ) {\n\t\t\to[ old ] = o[ knew ];\n\t\t}\n\t};\n\t\n\t\n\t/**\n\t * Provide backwards compatibility for the main DT options. Note that the new\n\t * options are mapped onto the old parameters, so this is an external interface\n\t * change only.\n\t *  @param {object} init Object to map\n\t */\n\tfunction _fnCompatOpts ( init )\n\t{\n\t\t_fnCompatMap( init, 'ordering',      'bSort' );\n\t\t_fnCompatMap( init, 'orderMulti',    'bSortMulti' );\n\t\t_fnCompatMap( init, 'orderClasses',  'bSortClasses' );\n\t\t_fnCompatMap( init, 'orderCellsTop', 'bSortCellsTop' );\n\t\t_fnCompatMap( init, 'order',         'aaSorting' );\n\t\t_fnCompatMap( init, 'orderFixed',    'aaSortingFixed' );\n\t\t_fnCompatMap( init, 'paging',        'bPaginate' );\n\t\t_fnCompatMap( init, 'pagingType',    'sPaginationType' );\n\t\t_fnCompatMap( init, 'pageLength',    'iDisplayLength' );\n\t\t_fnCompatMap( init, 'searching',     'bFilter' );\n\t\n\t\t// Column search objects are in an array, so it needs to be converted\n\t\t// element by element\n\t\tvar searchCols = init.aoSearchCols;\n\t\n\t\tif ( searchCols ) {\n\t\t\tfor ( var i=0, ien=searchCols.length ; i<ien ; i++ ) {\n\t\t\t\tif ( searchCols[i] ) {\n\t\t\t\t\t_fnCamelToHungarian( DataTable.models.oSearch, searchCols[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Provide backwards compatibility for column options. Note that the new options\n\t * are mapped onto the old parameters, so this is an external interface change\n\t * only.\n\t *  @param {object} init Object to map\n\t */\n\tfunction _fnCompatCols ( init )\n\t{\n\t\t_fnCompatMap( init, 'orderable',     'bSortable' );\n\t\t_fnCompatMap( init, 'orderData',     'aDataSort' );\n\t\t_fnCompatMap( init, 'orderSequence', 'asSorting' );\n\t\t_fnCompatMap( init, 'orderDataType', 'sortDataType' );\n\t\n\t\t// orderData can be given as an integer\n\t\tvar dataSort = init.aDataSort;\n\t\tif ( dataSort && ! $.isArray( dataSort ) ) {\n\t\t\tinit.aDataSort = [ dataSort ];\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Browser feature detection for capabilities, quirks\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnBrowserDetect( settings )\n\t{\n\t\tvar browser = settings.oBrowser;\n\t\n\t\t// Scrolling feature / quirks detection\n\t\tvar n = $('<div/>')\n\t\t\t.css( {\n\t\t\t\tposition: 'absolute',\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\theight: 1,\n\t\t\t\twidth: 1,\n\t\t\t\toverflow: 'hidden'\n\t\t\t} )\n\t\t\t.append(\n\t\t\t\t$('<div/>')\n\t\t\t\t\t.css( {\n\t\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\t\ttop: 1,\n\t\t\t\t\t\tleft: 1,\n\t\t\t\t\t\twidth: 100,\n\t\t\t\t\t\toverflow: 'scroll'\n\t\t\t\t\t} )\n\t\t\t\t\t.append(\n\t\t\t\t\t\t$('<div class=\"test\"/>')\n\t\t\t\t\t\t\t.css( {\n\t\t\t\t\t\t\t\twidth: '100%',\n\t\t\t\t\t\t\t\theight: 10\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t)\n\t\t\t)\n\t\t\t.appendTo( 'body' );\n\t\n\t\tvar test = n.find('.test');\n\t\n\t\t// IE6/7 will oversize a width 100% element inside a scrolling element, to\n\t\t// include the width of the scrollbar, while other browsers ensure the inner\n\t\t// element is contained without forcing scrolling\n\t\tbrowser.bScrollOversize = test[0].offsetWidth === 100;\n\t\n\t\t// In rtl text layout, some browsers (most, but not all) will place the\n\t\t// scrollbar on the left, rather than the right.\n\t\tbrowser.bScrollbarLeft = Math.round( test.offset().left ) !== 1;\n\t\n\t\tn.remove();\n\t}\n\t\n\t\n\t/**\n\t * Array.prototype reduce[Right] method, used for browsers which don't support\n\t * JS 1.6. Done this way to reduce code size, since we iterate either way\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnReduce ( that, fn, init, start, end, inc )\n\t{\n\t\tvar\n\t\t\ti = start,\n\t\t\tvalue,\n\t\t\tisSet = false;\n\t\n\t\tif ( init !== undefined ) {\n\t\t\tvalue = init;\n\t\t\tisSet = true;\n\t\t}\n\t\n\t\twhile ( i !== end ) {\n\t\t\tif ( ! that.hasOwnProperty(i) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\n\t\t\tvalue = isSet ?\n\t\t\t\tfn( value, that[i], i, that ) :\n\t\t\t\tthat[i];\n\t\n\t\t\tisSet = true;\n\t\t\ti += inc;\n\t\t}\n\t\n\t\treturn value;\n\t}\n\t\n\t/**\n\t * Add a column to the list used for the table with default values\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {node} nTh The th element for this column\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAddColumn( oSettings, nTh )\n\t{\n\t\t// Add column to aoColumns array\n\t\tvar oDefaults = DataTable.defaults.column;\n\t\tvar iCol = oSettings.aoColumns.length;\n\t\tvar oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, {\n\t\t\t\"nTh\": nTh ? nTh : document.createElement('th'),\n\t\t\t\"sTitle\":    oDefaults.sTitle    ? oDefaults.sTitle    : nTh ? nTh.innerHTML : '',\n\t\t\t\"aDataSort\": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol],\n\t\t\t\"mData\": oDefaults.mData ? oDefaults.mData : iCol,\n\t\t\tidx: iCol\n\t\t} );\n\t\toSettings.aoColumns.push( oCol );\n\t\n\t\t// Add search object for column specific search. Note that the `searchCols[ iCol ]`\n\t\t// passed into extend can be undefined. This allows the user to give a default\n\t\t// with only some of the parameters defined, and also not give a default\n\t\tvar searchCols = oSettings.aoPreSearchCols;\n\t\tsearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch, searchCols[ iCol ] );\n\t\n\t\t// Use the default column options function to initialise classes etc\n\t\t_fnColumnOptions( oSettings, iCol, $(nTh).data() );\n\t}\n\t\n\t\n\t/**\n\t * Apply options for a column\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {int} iCol column index to consider\n\t *  @param {object} oOptions object with sType, bVisible and bSearchable etc\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnColumnOptions( oSettings, iCol, oOptions )\n\t{\n\t\tvar oCol = oSettings.aoColumns[ iCol ];\n\t\tvar oClasses = oSettings.oClasses;\n\t\tvar th = $(oCol.nTh);\n\t\n\t\t// Try to get width information from the DOM. We can't get it from CSS\n\t\t// as we'd need to parse the CSS stylesheet. `width` option can override\n\t\tif ( ! oCol.sWidthOrig ) {\n\t\t\t// Width attribute\n\t\t\toCol.sWidthOrig = th.attr('width') || null;\n\t\n\t\t\t// Style attribute\n\t\t\tvar t = (th.attr('style') || '').match(/width:\\s*(\\d+[pxem%]+)/);\n\t\t\tif ( t ) {\n\t\t\t\toCol.sWidthOrig = t[1];\n\t\t\t}\n\t\t}\n\t\n\t\t/* User specified column options */\n\t\tif ( oOptions !== undefined && oOptions !== null )\n\t\t{\n\t\t\t// Backwards compatibility\n\t\t\t_fnCompatCols( oOptions );\n\t\n\t\t\t// Map camel case parameters to their Hungarian counterparts\n\t\t\t_fnCamelToHungarian( DataTable.defaults.column, oOptions );\n\t\n\t\t\t/* Backwards compatibility for mDataProp */\n\t\t\tif ( oOptions.mDataProp !== undefined && !oOptions.mData )\n\t\t\t{\n\t\t\t\toOptions.mData = oOptions.mDataProp;\n\t\t\t}\n\t\n\t\t\tif ( oOptions.sType )\n\t\t\t{\n\t\t\t\toCol._sManualType = oOptions.sType;\n\t\t\t}\n\t\n\t\t\t// `class` is a reserved word in Javascript, so we need to provide\n\t\t\t// the ability to use a valid name for the camel case input\n\t\t\tif ( oOptions.className && ! oOptions.sClass )\n\t\t\t{\n\t\t\t\toOptions.sClass = oOptions.className;\n\t\t\t}\n\t\n\t\t\t$.extend( oCol, oOptions );\n\t\t\t_fnMap( oCol, oOptions, \"sWidth\", \"sWidthOrig\" );\n\t\n\t\t\t/* iDataSort to be applied (backwards compatibility), but aDataSort will take\n\t\t\t * priority if defined\n\t\t\t */\n\t\t\tif ( oOptions.iDataSort !== undefined )\n\t\t\t{\n\t\t\t\toCol.aDataSort = [ oOptions.iDataSort ];\n\t\t\t}\n\t\t\t_fnMap( oCol, oOptions, \"aDataSort\" );\n\t\t}\n\t\n\t\t/* Cache the data get and set functions for speed */\n\t\tvar mDataSrc = oCol.mData;\n\t\tvar mData = _fnGetObjectDataFn( mDataSrc );\n\t\tvar mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null;\n\t\n\t\tvar attrTest = function( src ) {\n\t\t\treturn typeof src === 'string' && src.indexOf('@') !== -1;\n\t\t};\n\t\toCol._bAttrSrc = $.isPlainObject( mDataSrc ) && (\n\t\t\tattrTest(mDataSrc.sort) || attrTest(mDataSrc.type) || attrTest(mDataSrc.filter)\n\t\t);\n\t\n\t\toCol.fnGetData = function (rowData, type, meta) {\n\t\t\tvar innerData = mData( rowData, type, undefined, meta );\n\t\n\t\t\treturn mRender && type ?\n\t\t\t\tmRender( innerData, type, rowData, meta ) :\n\t\t\t\tinnerData;\n\t\t};\n\t\toCol.fnSetData = function ( rowData, val, meta ) {\n\t\t\treturn _fnSetObjectDataFn( mDataSrc )( rowData, val, meta );\n\t\t};\n\t\n\t\t// Indicate if DataTables should read DOM data as an object or array\n\t\t// Used in _fnGetRowElements\n\t\tif ( typeof mDataSrc !== 'number' ) {\n\t\t\toSettings._rowReadObject = true;\n\t\t}\n\t\n\t\t/* Feature sorting overrides column specific when off */\n\t\tif ( !oSettings.oFeatures.bSort )\n\t\t{\n\t\t\toCol.bSortable = false;\n\t\t\tth.addClass( oClasses.sSortableNone ); // Have to add class here as order event isn't called\n\t\t}\n\t\n\t\t/* Check that the class assignment is correct for sorting */\n\t\tvar bAsc = $.inArray('asc', oCol.asSorting) !== -1;\n\t\tvar bDesc = $.inArray('desc', oCol.asSorting) !== -1;\n\t\tif ( !oCol.bSortable || (!bAsc && !bDesc) )\n\t\t{\n\t\t\toCol.sSortingClass = oClasses.sSortableNone;\n\t\t\toCol.sSortingClassJUI = \"\";\n\t\t}\n\t\telse if ( bAsc && !bDesc )\n\t\t{\n\t\t\toCol.sSortingClass = oClasses.sSortableAsc;\n\t\t\toCol.sSortingClassJUI = oClasses.sSortJUIAscAllowed;\n\t\t}\n\t\telse if ( !bAsc && bDesc )\n\t\t{\n\t\t\toCol.sSortingClass = oClasses.sSortableDesc;\n\t\t\toCol.sSortingClassJUI = oClasses.sSortJUIDescAllowed;\n\t\t}\n\t\telse\n\t\t{\n\t\t\toCol.sSortingClass = oClasses.sSortable;\n\t\t\toCol.sSortingClassJUI = oClasses.sSortJUI;\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Adjust the table column widths for new data. Note: you would probably want to\n\t * do a redraw after calling this function!\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAdjustColumnSizing ( settings )\n\t{\n\t\t/* Not interested in doing column width calculation if auto-width is disabled */\n\t\tif ( settings.oFeatures.bAutoWidth !== false )\n\t\t{\n\t\t\tvar columns = settings.aoColumns;\n\t\n\t\t\t_fnCalculateColumnWidths( settings );\n\t\t\tfor ( var i=0 , iLen=columns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tcolumns[i].nTh.style.width = columns[i].sWidth;\n\t\t\t}\n\t\t}\n\t\n\t\tvar scroll = settings.oScroll;\n\t\tif ( scroll.sY !== '' || scroll.sX !== '')\n\t\t{\n\t\t\t_fnScrollDraw( settings );\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, null, 'column-sizing', [settings] );\n\t}\n\t\n\t\n\t/**\n\t * Covert the index of a visible column to the index in the data array (take account\n\t * of hidden columns)\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {int} iMatch Visible column index to lookup\n\t *  @returns {int} i the data index\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnVisibleToColumnIndex( oSettings, iMatch )\n\t{\n\t\tvar aiVis = _fnGetColumns( oSettings, 'bVisible' );\n\t\n\t\treturn typeof aiVis[iMatch] === 'number' ?\n\t\t\taiVis[iMatch] :\n\t\t\tnull;\n\t}\n\t\n\t\n\t/**\n\t * Covert the index of an index in the data array and convert it to the visible\n\t *   column index (take account of hidden columns)\n\t *  @param {int} iMatch Column index to lookup\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {int} i the data index\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnColumnIndexToVisible( oSettings, iMatch )\n\t{\n\t\tvar aiVis = _fnGetColumns( oSettings, 'bVisible' );\n\t\tvar iPos = $.inArray( iMatch, aiVis );\n\t\n\t\treturn iPos !== -1 ? iPos : null;\n\t}\n\t\n\t\n\t/**\n\t * Get the number of visible columns\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {int} i the number of visible columns\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnVisbleColumns( oSettings )\n\t{\n\t\treturn _fnGetColumns( oSettings, 'bVisible' ).length;\n\t}\n\t\n\t\n\t/**\n\t * Get an array of column indexes that match a given property\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {string} sParam Parameter in aoColumns to look for - typically\n\t *    bVisible or bSearchable\n\t *  @returns {array} Array of indexes with matched properties\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetColumns( oSettings, sParam )\n\t{\n\t\tvar a = [];\n\t\n\t\t$.map( oSettings.aoColumns, function(val, i) {\n\t\t\tif ( val[sParam] ) {\n\t\t\t\ta.push( i );\n\t\t\t}\n\t\t} );\n\t\n\t\treturn a;\n\t}\n\t\n\t\n\t/**\n\t * Calculate the 'type' of a column\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnColumnTypes ( settings )\n\t{\n\t\tvar columns = settings.aoColumns;\n\t\tvar data = settings.aoData;\n\t\tvar types = DataTable.ext.type.detect;\n\t\tvar i, ien, j, jen, k, ken;\n\t\tvar col, cell, detectedType, cache;\n\t\n\t\t// For each column, spin over the \n\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n\t\t\tcol = columns[i];\n\t\t\tcache = [];\n\t\n\t\t\tif ( ! col.sType && col._sManualType ) {\n\t\t\t\tcol.sType = col._sManualType;\n\t\t\t}\n\t\t\telse if ( ! col.sType ) {\n\t\t\t\tfor ( j=0, jen=types.length ; j<jen ; j++ ) {\n\t\t\t\t\tfor ( k=0, ken=data.length ; k<ken ; k++ ) {\n\t\t\t\t\t\t// Use a cache array so we only need to get the type data\n\t\t\t\t\t\t// from the formatter once (when using multiple detectors)\n\t\t\t\t\t\tif ( cache[k] === undefined ) {\n\t\t\t\t\t\t\tcache[k] = _fnGetCellData( settings, k, i, 'type' );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tdetectedType = types[j]( cache[k], settings );\n\t\n\t\t\t\t\t\t// If null, then this type can't apply to this column, so\n\t\t\t\t\t\t// rather than testing all cells, break out. There is an\n\t\t\t\t\t\t// exception for the last type which is `html`. We need to\n\t\t\t\t\t\t// scan all rows since it is possible to mix string and HTML\n\t\t\t\t\t\t// types\n\t\t\t\t\t\tif ( ! detectedType && j !== types.length-1 ) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t// Only a single match is needed for html type since it is\n\t\t\t\t\t\t// bottom of the pile and very similar to string\n\t\t\t\t\t\tif ( detectedType === 'html' ) {\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// Type is valid for all data points in the column - use this\n\t\t\t\t\t// type\n\t\t\t\t\tif ( detectedType ) {\n\t\t\t\t\t\tcol.sType = detectedType;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\t// Fall back - if no type was detected, always use string\n\t\t\t\tif ( ! col.sType ) {\n\t\t\t\t\tcol.sType = 'string';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Take the column definitions and static columns arrays and calculate how\n\t * they relate to column indexes. The callback function will then apply the\n\t * definition found for a column to a suitable configuration object.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {array} aoColDefs The aoColumnDefs array that is to be applied\n\t *  @param {array} aoCols The aoColumns array that defines columns individually\n\t *  @param {function} fn Callback function - takes two parameters, the calculated\n\t *    column index and the definition for that column.\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnApplyColumnDefs( oSettings, aoColDefs, aoCols, fn )\n\t{\n\t\tvar i, iLen, j, jLen, k, kLen, def;\n\t\tvar columns = oSettings.aoColumns;\n\t\n\t\t// Column definitions with aTargets\n\t\tif ( aoColDefs )\n\t\t{\n\t\t\t/* Loop over the definitions array - loop in reverse so first instance has priority */\n\t\t\tfor ( i=aoColDefs.length-1 ; i>=0 ; i-- )\n\t\t\t{\n\t\t\t\tdef = aoColDefs[i];\n\t\n\t\t\t\t/* Each definition can target multiple columns, as it is an array */\n\t\t\t\tvar aTargets = def.targets !== undefined ?\n\t\t\t\t\tdef.targets :\n\t\t\t\t\tdef.aTargets;\n\t\n\t\t\t\tif ( ! $.isArray( aTargets ) )\n\t\t\t\t{\n\t\t\t\t\taTargets = [ aTargets ];\n\t\t\t\t}\n\t\n\t\t\t\tfor ( j=0, jLen=aTargets.length ; j<jLen ; j++ )\n\t\t\t\t{\n\t\t\t\t\tif ( typeof aTargets[j] === 'number' && aTargets[j] >= 0 )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Add columns that we don't yet know about */\n\t\t\t\t\t\twhile( columns.length <= aTargets[j] )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_fnAddColumn( oSettings );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t/* Integer, basic index */\n\t\t\t\t\t\tfn( aTargets[j], def );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( typeof aTargets[j] === 'number' && aTargets[j] < 0 )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Negative integer, right to left column counting */\n\t\t\t\t\t\tfn( columns.length+aTargets[j], def );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( typeof aTargets[j] === 'string' )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Class name matching on TH element */\n\t\t\t\t\t\tfor ( k=0, kLen=columns.length ; k<kLen ; k++ )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif ( aTargets[j] == \"_all\" ||\n\t\t\t\t\t\t\t     $(columns[k].nTh).hasClass( aTargets[j] ) )\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\tfn( k, def );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\t// Statically defined columns array\n\t\tif ( aoCols )\n\t\t{\n\t\t\tfor ( i=0, iLen=aoCols.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tfn( i, aoCols[i] );\n\t\t\t}\n\t\t}\n\t}\n\t\n\t/**\n\t * Add a data array to the table, creating DOM node etc. This is the parallel to\n\t * _fnGatherData, but for adding rows from a Javascript source, rather than a\n\t * DOM source.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {array} aData data array to be added\n\t *  @param {node} [nTr] TR element to add to the table - optional. If not given,\n\t *    DataTables will create a row automatically\n\t *  @param {array} [anTds] Array of TD|TH elements for the row - must be given\n\t *    if nTr is.\n\t *  @returns {int} >=0 if successful (index of new aoData entry), -1 if failed\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAddData ( oSettings, aDataIn, nTr, anTds )\n\t{\n\t\t/* Create the object for storing information about this new row */\n\t\tvar iRow = oSettings.aoData.length;\n\t\tvar oData = $.extend( true, {}, DataTable.models.oRow, {\n\t\t\tsrc: nTr ? 'dom' : 'data'\n\t\t} );\n\t\n\t\toData._aData = aDataIn;\n\t\toSettings.aoData.push( oData );\n\t\n\t\t/* Create the cells */\n\t\tvar nTd, sThisType;\n\t\tvar columns = oSettings.aoColumns;\n\t\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\n\t\t{\n\t\t\t// When working with a row, the data source object must be populated. In\n\t\t\t// all other cases, the data source object is already populated, so we\n\t\t\t// don't overwrite it, which might break bindings etc\n\t\t\tif ( nTr ) {\n\t\t\t\t_fnSetCellData( oSettings, iRow, i, _fnGetCellData( oSettings, iRow, i ) );\n\t\t\t}\n\t\t\tcolumns[i].sType = null;\n\t\t}\n\t\n\t\t/* Add to the display array */\n\t\toSettings.aiDisplayMaster.push( iRow );\n\t\n\t\t/* Create the DOM information, or register it if already present */\n\t\tif ( nTr || ! oSettings.oFeatures.bDeferRender )\n\t\t{\n\t\t\t_fnCreateTr( oSettings, iRow, nTr, anTds );\n\t\t}\n\t\n\t\treturn iRow;\n\t}\n\t\n\t\n\t/**\n\t * Add one or more TR elements to the table. Generally we'd expect to\n\t * use this for reading data from a DOM sourced table, but it could be\n\t * used for an TR element. Note that if a TR is given, it is used (i.e.\n\t * it is not cloned).\n\t *  @param {object} settings dataTables settings object\n\t *  @param {array|node|jQuery} trs The TR element(s) to add to the table\n\t *  @returns {array} Array of indexes for the added rows\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAddTr( settings, trs )\n\t{\n\t\tvar row;\n\t\n\t\t// Allow an individual node to be passed in\n\t\tif ( ! (trs instanceof $) ) {\n\t\t\ttrs = $(trs);\n\t\t}\n\t\n\t\treturn trs.map( function (i, el) {\n\t\t\trow = _fnGetRowElements( settings, el );\n\t\t\treturn _fnAddData( settings, row.data, el, row.cells );\n\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Take a TR element and convert it to an index in aoData\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {node} n the TR element to find\n\t *  @returns {int} index if the node is found, null if not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnNodeToDataIndex( oSettings, n )\n\t{\n\t\treturn (n._DT_RowIndex!==undefined) ? n._DT_RowIndex : null;\n\t}\n\t\n\t\n\t/**\n\t * Take a TD element and convert it into a column data index (not the visible index)\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {int} iRow The row number the TD/TH can be found in\n\t *  @param {node} n The TD/TH element to find\n\t *  @returns {int} index if the node is found, -1 if not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnNodeToColumnIndex( oSettings, iRow, n )\n\t{\n\t\treturn $.inArray( n, oSettings.aoData[ iRow ].anCells );\n\t}\n\t\n\t\n\t/**\n\t * Get the data for a given cell from the internal cache, taking into account data mapping\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} rowIdx aoData row id\n\t *  @param {int} colIdx Column index\n\t *  @param {string} type data get type ('display', 'type' 'filter' 'sort')\n\t *  @returns {*} Cell data\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetCellData( settings, rowIdx, colIdx, type )\n\t{\n\t\tvar draw           = settings.iDraw;\n\t\tvar col            = settings.aoColumns[colIdx];\n\t\tvar rowData        = settings.aoData[rowIdx]._aData;\n\t\tvar defaultContent = col.sDefaultContent;\n\t\tvar cellData       = col.fnGetData( rowData, type, {\n\t\t\tsettings: settings,\n\t\t\trow:      rowIdx,\n\t\t\tcol:      colIdx\n\t\t} );\n\t\n\t\tif ( cellData === undefined ) {\n\t\t\tif ( settings.iDrawError != draw && defaultContent === null ) {\n\t\t\t\t_fnLog( settings, 0, \"Requested unknown parameter \"+\n\t\t\t\t\t(typeof col.mData=='function' ? '{function}' : \"'\"+col.mData+\"'\")+\n\t\t\t\t\t\" for row \"+rowIdx, 4 );\n\t\t\t\tsettings.iDrawError = draw;\n\t\t\t}\n\t\t\treturn defaultContent;\n\t\t}\n\t\n\t\t/* When the data source is null, we can use default column data */\n\t\tif ( (cellData === rowData || cellData === null) && defaultContent !== null ) {\n\t\t\tcellData = defaultContent;\n\t\t}\n\t\telse if ( typeof cellData === 'function' ) {\n\t\t\t// If the data source is a function, then we run it and use the return,\n\t\t\t// executing in the scope of the data object (for instances)\n\t\t\treturn cellData.call( rowData );\n\t\t}\n\t\n\t\tif ( cellData === null && type == 'display' ) {\n\t\t\treturn '';\n\t\t}\n\t\treturn cellData;\n\t}\n\t\n\t\n\t/**\n\t * Set the value for a specific cell, into the internal data cache\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} rowIdx aoData row id\n\t *  @param {int} colIdx Column index\n\t *  @param {*} val Value to set\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSetCellData( settings, rowIdx, colIdx, val )\n\t{\n\t\tvar col     = settings.aoColumns[colIdx];\n\t\tvar rowData = settings.aoData[rowIdx]._aData;\n\t\n\t\tcol.fnSetData( rowData, val, {\n\t\t\tsettings: settings,\n\t\t\trow:      rowIdx,\n\t\t\tcol:      colIdx\n\t\t}  );\n\t}\n\t\n\t\n\t// Private variable that is used to match action syntax in the data property object\n\tvar __reArray = /\\[.*?\\]$/;\n\tvar __reFn = /\\(\\)$/;\n\t\n\t/**\n\t * Split string on periods, taking into account escaped periods\n\t * @param  {string} str String to split\n\t * @return {array} Split string\n\t */\n\tfunction _fnSplitObjNotation( str )\n\t{\n\t\treturn $.map( str.match(/(\\\\.|[^\\.])+/g), function ( s ) {\n\t\t\treturn s.replace(/\\\\./g, '.');\n\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Return a function that can be used to get data from a source object, taking\n\t * into account the ability to use nested objects as a source\n\t *  @param {string|int|function} mSource The data source for the object\n\t *  @returns {function} Data get function\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetObjectDataFn( mSource )\n\t{\n\t\tif ( $.isPlainObject( mSource ) )\n\t\t{\n\t\t\t/* Build an object of get functions, and wrap them in a single call */\n\t\t\tvar o = {};\n\t\t\t$.each( mSource, function (key, val) {\n\t\t\t\tif ( val ) {\n\t\t\t\t\to[key] = _fnGetObjectDataFn( val );\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\treturn function (data, type, row, meta) {\n\t\t\t\tvar t = o[type] || o._;\n\t\t\t\treturn t !== undefined ?\n\t\t\t\t\tt(data, type, row, meta) :\n\t\t\t\t\tdata;\n\t\t\t};\n\t\t}\n\t\telse if ( mSource === null )\n\t\t{\n\t\t\t/* Give an empty string for rendering / sorting etc */\n\t\t\treturn function (data) { // type, row and meta also passed, but not used\n\t\t\t\treturn data;\n\t\t\t};\n\t\t}\n\t\telse if ( typeof mSource === 'function' )\n\t\t{\n\t\t\treturn function (data, type, row, meta) {\n\t\t\t\treturn mSource( data, type, row, meta );\n\t\t\t};\n\t\t}\n\t\telse if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||\n\t\t\t      mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )\n\t\t{\n\t\t\t/* If there is a . in the source string then the data source is in a\n\t\t\t * nested object so we loop over the data for each level to get the next\n\t\t\t * level down. On each loop we test for undefined, and if found immediately\n\t\t\t * return. This allows entire objects to be missing and sDefaultContent to\n\t\t\t * be used if defined, rather than throwing an error\n\t\t\t */\n\t\t\tvar fetchData = function (data, type, src) {\n\t\t\t\tvar arrayNotation, funcNotation, out, innerSrc;\n\t\n\t\t\t\tif ( src !== \"\" )\n\t\t\t\t{\n\t\t\t\t\tvar a = _fnSplitObjNotation( src );\n\t\n\t\t\t\t\tfor ( var i=0, iLen=a.length ; i<iLen ; i++ )\n\t\t\t\t\t{\n\t\t\t\t\t\t// Check if we are dealing with special notation\n\t\t\t\t\t\tarrayNotation = a[i].match(__reArray);\n\t\t\t\t\t\tfuncNotation = a[i].match(__reFn);\n\t\n\t\t\t\t\t\tif ( arrayNotation )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Array notation\n\t\t\t\t\t\t\ta[i] = a[i].replace(__reArray, '');\n\t\n\t\t\t\t\t\t\t// Condition allows simply [] to be passed in\n\t\t\t\t\t\t\tif ( a[i] !== \"\" ) {\n\t\t\t\t\t\t\t\tdata = data[ a[i] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tout = [];\n\t\n\t\t\t\t\t\t\t// Get the remainder of the nested object to get\n\t\t\t\t\t\t\ta.splice( 0, i+1 );\n\t\t\t\t\t\t\tinnerSrc = a.join('.');\n\t\n\t\t\t\t\t\t\t// Traverse each entry in the array getting the properties requested\n\t\t\t\t\t\t\tfor ( var j=0, jLen=data.length ; j<jLen ; j++ ) {\n\t\t\t\t\t\t\t\tout.push( fetchData( data[j], type, innerSrc ) );\n\t\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t\t// If a string is given in between the array notation indicators, that\n\t\t\t\t\t\t\t// is used to join the strings together, otherwise an array is returned\n\t\t\t\t\t\t\tvar join = arrayNotation[0].substring(1, arrayNotation[0].length-1);\n\t\t\t\t\t\t\tdata = (join===\"\") ? out : out.join(join);\n\t\n\t\t\t\t\t\t\t// The inner call to fetchData has already traversed through the remainder\n\t\t\t\t\t\t\t// of the source requested, so we exit from the loop\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if ( funcNotation )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// Function call\n\t\t\t\t\t\t\ta[i] = a[i].replace(__reFn, '');\n\t\t\t\t\t\t\tdata = data[ a[i] ]();\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tif ( data === null || data[ a[i] ] === undefined )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\treturn undefined;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tdata = data[ a[i] ];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\treturn data;\n\t\t\t};\n\t\n\t\t\treturn function (data, type) { // row and meta also passed, but not used\n\t\t\t\treturn fetchData( data, type, mSource );\n\t\t\t};\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Array or flat object mapping */\n\t\t\treturn function (data, type) { // row and meta also passed, but not used\n\t\t\t\treturn data[mSource];\n\t\t\t};\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Return a function that can be used to set data from a source object, taking\n\t * into account the ability to use nested objects as a source\n\t *  @param {string|int|function} mSource The data source for the object\n\t *  @returns {function} Data set function\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSetObjectDataFn( mSource )\n\t{\n\t\tif ( $.isPlainObject( mSource ) )\n\t\t{\n\t\t\t/* Unlike get, only the underscore (global) option is used for for\n\t\t\t * setting data since we don't know the type here. This is why an object\n\t\t\t * option is not documented for `mData` (which is read/write), but it is\n\t\t\t * for `mRender` which is read only.\n\t\t\t */\n\t\t\treturn _fnSetObjectDataFn( mSource._ );\n\t\t}\n\t\telse if ( mSource === null )\n\t\t{\n\t\t\t/* Nothing to do when the data source is null */\n\t\t\treturn function () {};\n\t\t}\n\t\telse if ( typeof mSource === 'function' )\n\t\t{\n\t\t\treturn function (data, val, meta) {\n\t\t\t\tmSource( data, 'set', val, meta );\n\t\t\t};\n\t\t}\n\t\telse if ( typeof mSource === 'string' && (mSource.indexOf('.') !== -1 ||\n\t\t\t      mSource.indexOf('[') !== -1 || mSource.indexOf('(') !== -1) )\n\t\t{\n\t\t\t/* Like the get, we need to get data from a nested object */\n\t\t\tvar setData = function (data, val, src) {\n\t\t\t\tvar a = _fnSplitObjNotation( src ), b;\n\t\t\t\tvar aLast = a[a.length-1];\n\t\t\t\tvar arrayNotation, funcNotation, o, innerSrc;\n\t\n\t\t\t\tfor ( var i=0, iLen=a.length-1 ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\t// Check if we are dealing with an array notation request\n\t\t\t\t\tarrayNotation = a[i].match(__reArray);\n\t\t\t\t\tfuncNotation = a[i].match(__reFn);\n\t\n\t\t\t\t\tif ( arrayNotation )\n\t\t\t\t\t{\n\t\t\t\t\t\ta[i] = a[i].replace(__reArray, '');\n\t\t\t\t\t\tdata[ a[i] ] = [];\n\t\n\t\t\t\t\t\t// Get the remainder of the nested object to set so we can recurse\n\t\t\t\t\t\tb = a.slice();\n\t\t\t\t\t\tb.splice( 0, i+1 );\n\t\t\t\t\t\tinnerSrc = b.join('.');\n\t\n\t\t\t\t\t\t// Traverse each entry in the array setting the properties requested\n\t\t\t\t\t\tfor ( var j=0, jLen=val.length ; j<jLen ; j++ )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\to = {};\n\t\t\t\t\t\t\tsetData( o, val[j], innerSrc );\n\t\t\t\t\t\t\tdata[ a[i] ].push( o );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t// The inner call to setData has already traversed through the remainder\n\t\t\t\t\t\t// of the source and has set the data, thus we can exit here\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\telse if ( funcNotation )\n\t\t\t\t\t{\n\t\t\t\t\t\t// Function call\n\t\t\t\t\t\ta[i] = a[i].replace(__reFn, '');\n\t\t\t\t\t\tdata = data[ a[i] ]( val );\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// If the nested object doesn't currently exist - since we are\n\t\t\t\t\t// trying to set the value - create it\n\t\t\t\t\tif ( data[ a[i] ] === null || data[ a[i] ] === undefined )\n\t\t\t\t\t{\n\t\t\t\t\t\tdata[ a[i] ] = {};\n\t\t\t\t\t}\n\t\t\t\t\tdata = data[ a[i] ];\n\t\t\t\t}\n\t\n\t\t\t\t// Last item in the input - i.e, the actual set\n\t\t\t\tif ( aLast.match(__reFn ) )\n\t\t\t\t{\n\t\t\t\t\t// Function call\n\t\t\t\t\tdata = data[ aLast.replace(__reFn, '') ]( val );\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t// If array notation is used, we just want to strip it and use the property name\n\t\t\t\t\t// and assign the value. If it isn't used, then we get the result we want anyway\n\t\t\t\t\tdata[ aLast.replace(__reArray, '') ] = val;\n\t\t\t\t}\n\t\t\t};\n\t\n\t\t\treturn function (data, val) { // meta is also passed in, but not used\n\t\t\t\treturn setData( data, val, mSource );\n\t\t\t};\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Array or flat object mapping */\n\t\t\treturn function (data, val) { // meta is also passed in, but not used\n\t\t\t\tdata[mSource] = val;\n\t\t\t};\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Return an array with the full table data\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns array {array} aData Master data array\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetDataMaster ( settings )\n\t{\n\t\treturn _pluck( settings.aoData, '_aData' );\n\t}\n\t\n\t\n\t/**\n\t * Nuke the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnClearTable( settings )\n\t{\n\t\tsettings.aoData.length = 0;\n\t\tsettings.aiDisplayMaster.length = 0;\n\t\tsettings.aiDisplay.length = 0;\n\t}\n\t\n\t\n\t /**\n\t * Take an array of integers (index array) and remove a target integer (value - not\n\t * the key!)\n\t *  @param {array} a Index array to target\n\t *  @param {int} iTarget value to find\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDeleteIndex( a, iTarget, splice )\n\t{\n\t\tvar iTargetIndex = -1;\n\t\n\t\tfor ( var i=0, iLen=a.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tif ( a[i] == iTarget )\n\t\t\t{\n\t\t\t\tiTargetIndex = i;\n\t\t\t}\n\t\t\telse if ( a[i] > iTarget )\n\t\t\t{\n\t\t\t\ta[i]--;\n\t\t\t}\n\t\t}\n\t\n\t\tif ( iTargetIndex != -1 && splice === undefined )\n\t\t{\n\t\t\ta.splice( iTargetIndex, 1 );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Mark cached data as invalid such that a re-read of the data will occur when\n\t * the cached data is next requested. Also update from the data source object.\n\t *\n\t * @param {object} settings DataTables settings object\n\t * @param {int}    rowIdx   Row index to invalidate\n\t * @param {string} [src]    Source to invalidate from: undefined, 'auto', 'dom'\n\t *     or 'data'\n\t * @param {int}    [colIdx] Column index to invalidate. If undefined the whole\n\t *     row will be invalidated\n\t * @memberof DataTable#oApi\n\t *\n\t * @todo For the modularisation of v1.11 this will need to become a callback, so\n\t *   the sort and filter methods can subscribe to it. That will required\n\t *   initialisation options for sorting, which is why it is not already baked in\n\t */\n\tfunction _fnInvalidate( settings, rowIdx, src, colIdx )\n\t{\n\t\tvar row = settings.aoData[ rowIdx ];\n\t\tvar i, ien;\n\t\tvar cellWrite = function ( cell, col ) {\n\t\t\t// This is very frustrating, but in IE if you just write directly\n\t\t\t// to innerHTML, and elements that are overwritten are GC'ed,\n\t\t\t// even if there is a reference to them elsewhere\n\t\t\twhile ( cell.childNodes.length ) {\n\t\t\t\tcell.removeChild( cell.firstChild );\n\t\t\t}\n\t\n\t\t\tcell.innerHTML = _fnGetCellData( settings, rowIdx, col, 'display' );\n\t\t};\n\t\n\t\t// Are we reading last data from DOM or the data object?\n\t\tif ( src === 'dom' || ((! src || src === 'auto') && row.src === 'dom') ) {\n\t\t\t// Read the data from the DOM\n\t\t\trow._aData = _fnGetRowElements(\n\t\t\t\t\tsettings, row, colIdx, colIdx === undefined ? undefined : row._aData\n\t\t\t\t)\n\t\t\t\t.data;\n\t\t}\n\t\telse {\n\t\t\t// Reading from data object, update the DOM\n\t\t\tvar cells = row.anCells;\n\t\n\t\t\tif ( cells ) {\n\t\t\t\tif ( colIdx !== undefined ) {\n\t\t\t\t\tcellWrite( cells[colIdx], colIdx );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tfor ( i=0, ien=cells.length ; i<ien ; i++ ) {\n\t\t\t\t\t\tcellWrite( cells[i], i );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\t// For both row and cell invalidation, the cached data for sorting and\n\t\t// filtering is nulled out\n\t\trow._aSortData = null;\n\t\trow._aFilterData = null;\n\t\n\t\t// Invalidate the type for a specific column (if given) or all columns since\n\t\t// the data might have changed\n\t\tvar cols = settings.aoColumns;\n\t\tif ( colIdx !== undefined ) {\n\t\t\tcols[ colIdx ].sType = null;\n\t\t}\n\t\telse {\n\t\t\tfor ( i=0, ien=cols.length ; i<ien ; i++ ) {\n\t\t\t\tcols[i].sType = null;\n\t\t\t}\n\t\n\t\t\t// Update DataTables special `DT_*` attributes for the row\n\t\t\t_fnRowAttributes( row );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Build a data source object from an HTML row, reading the contents of the\n\t * cells that are in the row.\n\t *\n\t * @param {object} settings DataTables settings object\n\t * @param {node|object} TR element from which to read data or existing row\n\t *   object from which to re-read the data from the cells\n\t * @param {int} [colIdx] Optional column index\n\t * @param {array|object} [d] Data source object. If `colIdx` is given then this\n\t *   parameter should also be given and will be used to write the data into.\n\t *   Only the column in question will be written\n\t * @returns {object} Object with two parameters: `data` the data read, in\n\t *   document order, and `cells` and array of nodes (they can be useful to the\n\t *   caller, so rather than needing a second traversal to get them, just return\n\t *   them from here).\n\t * @memberof DataTable#oApi\n\t */\n\tfunction _fnGetRowElements( settings, row, colIdx, d )\n\t{\n\t\tvar\n\t\t\ttds = [],\n\t\t\ttd = row.firstChild,\n\t\t\tname, col, o, i=0, contents,\n\t\t\tcolumns = settings.aoColumns,\n\t\t\tobjectRead = settings._rowReadObject;\n\t\n\t\t// Allow the data object to be passed in, or construct\n\t\td = d || objectRead ? {} : [];\n\t\n\t\tvar attr = function ( str, td  ) {\n\t\t\tif ( typeof str === 'string' ) {\n\t\t\t\tvar idx = str.indexOf('@');\n\t\n\t\t\t\tif ( idx !== -1 ) {\n\t\t\t\t\tvar attr = str.substring( idx+1 );\n\t\t\t\t\tvar setter = _fnSetObjectDataFn( str );\n\t\t\t\t\tsetter( d, td.getAttribute( attr ) );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\n\t\t// Read data from a cell and store into the data object\n\t\tvar cellProcess = function ( cell ) {\n\t\t\tif ( colIdx === undefined || colIdx === i ) {\n\t\t\t\tcol = columns[i];\n\t\t\t\tcontents = $.trim(cell.innerHTML);\n\t\n\t\t\t\tif ( col && col._bAttrSrc ) {\n\t\t\t\t\tvar setter = _fnSetObjectDataFn( col.mData._ );\n\t\t\t\t\tsetter( d, contents );\n\t\n\t\t\t\t\tattr( col.mData.sort, cell );\n\t\t\t\t\tattr( col.mData.type, cell );\n\t\t\t\t\tattr( col.mData.filter, cell );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// Depending on the `data` option for the columns the data can\n\t\t\t\t\t// be read to either an object or an array.\n\t\t\t\t\tif ( objectRead ) {\n\t\t\t\t\t\tif ( ! col._setter ) {\n\t\t\t\t\t\t\t// Cache the setter function\n\t\t\t\t\t\t\tcol._setter = _fnSetObjectDataFn( col.mData );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcol._setter( d, contents );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\td[i] = contents;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\ti++;\n\t\t};\n\t\n\t\tif ( td ) {\n\t\t\t// `tr` element was passed in\n\t\t\twhile ( td ) {\n\t\t\t\tname = td.nodeName.toUpperCase();\n\t\n\t\t\t\tif ( name == \"TD\" || name == \"TH\" ) {\n\t\t\t\t\tcellProcess( td );\n\t\t\t\t\ttds.push( td );\n\t\t\t\t}\n\t\n\t\t\t\ttd = td.nextSibling;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// Existing row object passed in\n\t\t\ttds = row.anCells;\n\t\t\t\n\t\t\tfor ( var j=0, jen=tds.length ; j<jen ; j++ ) {\n\t\t\t\tcellProcess( tds[j] );\n\t\t\t}\n\t\t}\n\t\n\t\treturn {\n\t\t\tdata: d,\n\t\t\tcells: tds\n\t\t};\n\t}\n\t/**\n\t * Create a new TR element (and it's TD children) for a row\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {int} iRow Row to consider\n\t *  @param {node} [nTrIn] TR element to add to the table - optional. If not given,\n\t *    DataTables will create a row automatically\n\t *  @param {array} [anTds] Array of TD|TH elements for the row - must be given\n\t *    if nTr is.\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCreateTr ( oSettings, iRow, nTrIn, anTds )\n\t{\n\t\tvar\n\t\t\trow = oSettings.aoData[iRow],\n\t\t\trowData = row._aData,\n\t\t\tcells = [],\n\t\t\tnTr, nTd, oCol,\n\t\t\ti, iLen;\n\t\n\t\tif ( row.nTr === null )\n\t\t{\n\t\t\tnTr = nTrIn || document.createElement('tr');\n\t\n\t\t\trow.nTr = nTr;\n\t\t\trow.anCells = cells;\n\t\n\t\t\t/* Use a private property on the node to allow reserve mapping from the node\n\t\t\t * to the aoData array for fast look up\n\t\t\t */\n\t\t\tnTr._DT_RowIndex = iRow;\n\t\n\t\t\t/* Special parameters can be given by the data source to be used on the row */\n\t\t\t_fnRowAttributes( row );\n\t\n\t\t\t/* Process each column */\n\t\t\tfor ( i=0, iLen=oSettings.aoColumns.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\toCol = oSettings.aoColumns[i];\n\t\n\t\t\t\tnTd = nTrIn ? anTds[i] : document.createElement( oCol.sCellType );\n\t\t\t\tcells.push( nTd );\n\t\n\t\t\t\t// Need to create the HTML if new, or if a rendering function is defined\n\t\t\t\tif ( !nTrIn || oCol.mRender || oCol.mData !== i )\n\t\t\t\t{\n\t\t\t\t\tnTd.innerHTML = _fnGetCellData( oSettings, iRow, i, 'display' );\n\t\t\t\t}\n\t\n\t\t\t\t/* Add user defined class */\n\t\t\t\tif ( oCol.sClass )\n\t\t\t\t{\n\t\t\t\t\tnTd.className += ' '+oCol.sClass;\n\t\t\t\t}\n\t\n\t\t\t\t// Visibility - add or remove as required\n\t\t\t\tif ( oCol.bVisible && ! nTrIn )\n\t\t\t\t{\n\t\t\t\t\tnTr.appendChild( nTd );\n\t\t\t\t}\n\t\t\t\telse if ( ! oCol.bVisible && nTrIn )\n\t\t\t\t{\n\t\t\t\t\tnTd.parentNode.removeChild( nTd );\n\t\t\t\t}\n\t\n\t\t\t\tif ( oCol.fnCreatedCell )\n\t\t\t\t{\n\t\t\t\t\toCol.fnCreatedCell.call( oSettings.oInstance,\n\t\t\t\t\t\tnTd, _fnGetCellData( oSettings, iRow, i ), rowData, iRow, i\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t_fnCallbackFire( oSettings, 'aoRowCreatedCallback', null, [nTr, rowData, iRow] );\n\t\t}\n\t\n\t\t// Remove once webkit bug 131819 and Chromium bug 365619 have been resolved\n\t\t// and deployed\n\t\trow.nTr.setAttribute( 'role', 'row' );\n\t}\n\t\n\t\n\t/**\n\t * Add attributes to a row based on the special `DT_*` parameters in a data\n\t * source object.\n\t *  @param {object} DataTables row object for the row to be modified\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnRowAttributes( row )\n\t{\n\t\tvar tr = row.nTr;\n\t\tvar data = row._aData;\n\t\n\t\tif ( tr ) {\n\t\t\tif ( data.DT_RowId ) {\n\t\t\t\ttr.id = data.DT_RowId;\n\t\t\t}\n\t\n\t\t\tif ( data.DT_RowClass ) {\n\t\t\t\t// Remove any classes added by DT_RowClass before\n\t\t\t\tvar a = data.DT_RowClass.split(' ');\n\t\t\t\trow.__rowc = row.__rowc ?\n\t\t\t\t\t_unique( row.__rowc.concat( a ) ) :\n\t\t\t\t\ta;\n\t\n\t\t\t\t$(tr)\n\t\t\t\t\t.removeClass( row.__rowc.join(' ') )\n\t\t\t\t\t.addClass( data.DT_RowClass );\n\t\t\t}\n\t\n\t\t\tif ( data.DT_RowAttr ) {\n\t\t\t\t$(tr).attr( data.DT_RowAttr );\n\t\t\t}\n\t\n\t\t\tif ( data.DT_RowData ) {\n\t\t\t\t$(tr).data( data.DT_RowData );\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Create the HTML header for the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnBuildHead( oSettings )\n\t{\n\t\tvar i, ien, cell, row, column;\n\t\tvar thead = oSettings.nTHead;\n\t\tvar tfoot = oSettings.nTFoot;\n\t\tvar createHeader = $('th, td', thead).length === 0;\n\t\tvar classes = oSettings.oClasses;\n\t\tvar columns = oSettings.aoColumns;\n\t\n\t\tif ( createHeader ) {\n\t\t\trow = $('<tr/>').appendTo( thead );\n\t\t}\n\t\n\t\tfor ( i=0, ien=columns.length ; i<ien ; i++ ) {\n\t\t\tcolumn = columns[i];\n\t\t\tcell = $( column.nTh ).addClass( column.sClass );\n\t\n\t\t\tif ( createHeader ) {\n\t\t\t\tcell.appendTo( row );\n\t\t\t}\n\t\n\t\t\t// 1.11 move into sorting\n\t\t\tif ( oSettings.oFeatures.bSort ) {\n\t\t\t\tcell.addClass( column.sSortingClass );\n\t\n\t\t\t\tif ( column.bSortable !== false ) {\n\t\t\t\t\tcell\n\t\t\t\t\t\t.attr( 'tabindex', oSettings.iTabIndex )\n\t\t\t\t\t\t.attr( 'aria-controls', oSettings.sTableId );\n\t\n\t\t\t\t\t_fnSortAttachListener( oSettings, column.nTh, i );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif ( column.sTitle != cell.html() ) {\n\t\t\t\tcell.html( column.sTitle );\n\t\t\t}\n\t\n\t\t\t_fnRenderer( oSettings, 'header' )(\n\t\t\t\toSettings, cell, column, classes\n\t\t\t);\n\t\t}\n\t\n\t\tif ( createHeader ) {\n\t\t\t_fnDetectHeader( oSettings.aoHeader, thead );\n\t\t}\n\t\t\n\t\t/* ARIA role for the rows */\n\t \t$(thead).find('>tr').attr('role', 'row');\n\t\n\t\t/* Deal with the footer - add classes if required */\n\t\t$(thead).find('>tr>th, >tr>td').addClass( classes.sHeaderTH );\n\t\t$(tfoot).find('>tr>th, >tr>td').addClass( classes.sFooterTH );\n\t\n\t\t// Cache the footer cells. Note that we only take the cells from the first\n\t\t// row in the footer. If there is more than one row the user wants to\n\t\t// interact with, they need to use the table().foot() method. Note also this\n\t\t// allows cells to be used for multiple columns using colspan\n\t\tif ( tfoot !== null ) {\n\t\t\tvar cells = oSettings.aoFooter[0];\n\t\n\t\t\tfor ( i=0, ien=cells.length ; i<ien ; i++ ) {\n\t\t\t\tcolumn = columns[i];\n\t\t\t\tcolumn.nTf = cells[i].cell;\n\t\n\t\t\t\tif ( column.sClass ) {\n\t\t\t\t\t$(column.nTf).addClass( column.sClass );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Draw the header (or footer) element based on the column visibility states. The\n\t * methodology here is to use the layout array from _fnDetectHeader, modified for\n\t * the instantaneous column visibility, to construct the new layout. The grid is\n\t * traversed over cell at a time in a rows x columns grid fashion, although each\n\t * cell insert can cover multiple elements in the grid - which is tracks using the\n\t * aApplied array. Cell inserts in the grid will only occur where there isn't\n\t * already a cell in that position.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param array {objects} aoSource Layout array from _fnDetectHeader\n\t *  @param {boolean} [bIncludeHidden=false] If true then include the hidden columns in the calc,\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDrawHead( oSettings, aoSource, bIncludeHidden )\n\t{\n\t\tvar i, iLen, j, jLen, k, kLen, n, nLocalTr;\n\t\tvar aoLocal = [];\n\t\tvar aApplied = [];\n\t\tvar iColumns = oSettings.aoColumns.length;\n\t\tvar iRowspan, iColspan;\n\t\n\t\tif ( ! aoSource )\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\n\t\tif (  bIncludeHidden === undefined )\n\t\t{\n\t\t\tbIncludeHidden = false;\n\t\t}\n\t\n\t\t/* Make a copy of the master layout array, but without the visible columns in it */\n\t\tfor ( i=0, iLen=aoSource.length ; i<iLen ; i++ )\n\t\t{\n\t\t\taoLocal[i] = aoSource[i].slice();\n\t\t\taoLocal[i].nTr = aoSource[i].nTr;\n\t\n\t\t\t/* Remove any columns which are currently hidden */\n\t\t\tfor ( j=iColumns-1 ; j>=0 ; j-- )\n\t\t\t{\n\t\t\t\tif ( !oSettings.aoColumns[j].bVisible && !bIncludeHidden )\n\t\t\t\t{\n\t\t\t\t\taoLocal[i].splice( j, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t/* Prep the applied array - it needs an element for each row */\n\t\t\taApplied.push( [] );\n\t\t}\n\t\n\t\tfor ( i=0, iLen=aoLocal.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tnLocalTr = aoLocal[i].nTr;\n\t\n\t\t\t/* All cells are going to be replaced, so empty out the row */\n\t\t\tif ( nLocalTr )\n\t\t\t{\n\t\t\t\twhile( (n = nLocalTr.firstChild) )\n\t\t\t\t{\n\t\t\t\t\tnLocalTr.removeChild( n );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tfor ( j=0, jLen=aoLocal[i].length ; j<jLen ; j++ )\n\t\t\t{\n\t\t\t\tiRowspan = 1;\n\t\t\t\tiColspan = 1;\n\t\n\t\t\t\t/* Check to see if there is already a cell (row/colspan) covering our target\n\t\t\t\t * insert point. If there is, then there is nothing to do.\n\t\t\t\t */\n\t\t\t\tif ( aApplied[i][j] === undefined )\n\t\t\t\t{\n\t\t\t\t\tnLocalTr.appendChild( aoLocal[i][j].cell );\n\t\t\t\t\taApplied[i][j] = 1;\n\t\n\t\t\t\t\t/* Expand the cell to cover as many rows as needed */\n\t\t\t\t\twhile ( aoLocal[i+iRowspan] !== undefined &&\n\t\t\t\t\t        aoLocal[i][j].cell == aoLocal[i+iRowspan][j].cell )\n\t\t\t\t\t{\n\t\t\t\t\t\taApplied[i+iRowspan][j] = 1;\n\t\t\t\t\t\tiRowspan++;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t/* Expand the cell to cover as many columns as needed */\n\t\t\t\t\twhile ( aoLocal[i][j+iColspan] !== undefined &&\n\t\t\t\t\t        aoLocal[i][j].cell == aoLocal[i][j+iColspan].cell )\n\t\t\t\t\t{\n\t\t\t\t\t\t/* Must update the applied array over the rows for the columns */\n\t\t\t\t\t\tfor ( k=0 ; k<iRowspan ; k++ )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taApplied[i+k][j+iColspan] = 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tiColspan++;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t/* Do the actual expansion in the DOM */\n\t\t\t\t\t$(aoLocal[i][j].cell)\n\t\t\t\t\t\t.attr('rowspan', iRowspan)\n\t\t\t\t\t\t.attr('colspan', iColspan);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Insert the required TR nodes into the table for display\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDraw( oSettings )\n\t{\n\t\t/* Provide a pre-callback function which can be used to cancel the draw is false is returned */\n\t\tvar aPreDraw = _fnCallbackFire( oSettings, 'aoPreDrawCallback', 'preDraw', [oSettings] );\n\t\tif ( $.inArray( false, aPreDraw ) !== -1 )\n\t\t{\n\t\t\t_fnProcessingDisplay( oSettings, false );\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar i, iLen, n;\n\t\tvar anRows = [];\n\t\tvar iRowCount = 0;\n\t\tvar asStripeClasses = oSettings.asStripeClasses;\n\t\tvar iStripes = asStripeClasses.length;\n\t\tvar iOpenRows = oSettings.aoOpenRows.length;\n\t\tvar oLang = oSettings.oLanguage;\n\t\tvar iInitDisplayStart = oSettings.iInitDisplayStart;\n\t\tvar bServerSide = _fnDataSource( oSettings ) == 'ssp';\n\t\tvar aiDisplay = oSettings.aiDisplay;\n\t\n\t\toSettings.bDrawing = true;\n\t\n\t\t/* Check and see if we have an initial draw position from state saving */\n\t\tif ( iInitDisplayStart !== undefined && iInitDisplayStart !== -1 )\n\t\t{\n\t\t\toSettings._iDisplayStart = bServerSide ?\n\t\t\t\tiInitDisplayStart :\n\t\t\t\tiInitDisplayStart >= oSettings.fnRecordsDisplay() ?\n\t\t\t\t\t0 :\n\t\t\t\t\tiInitDisplayStart;\n\t\n\t\t\toSettings.iInitDisplayStart = -1;\n\t\t}\n\t\n\t\tvar iDisplayStart = oSettings._iDisplayStart;\n\t\tvar iDisplayEnd = oSettings.fnDisplayEnd();\n\t\n\t\t/* Server-side processing draw intercept */\n\t\tif ( oSettings.bDeferLoading )\n\t\t{\n\t\t\toSettings.bDeferLoading = false;\n\t\t\toSettings.iDraw++;\n\t\t\t_fnProcessingDisplay( oSettings, false );\n\t\t}\n\t\telse if ( !bServerSide )\n\t\t{\n\t\t\toSettings.iDraw++;\n\t\t}\n\t\telse if ( !oSettings.bDestroying && !_fnAjaxUpdate( oSettings ) )\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\n\t\tif ( aiDisplay.length !== 0 )\n\t\t{\n\t\t\tvar iStart = bServerSide ? 0 : iDisplayStart;\n\t\t\tvar iEnd = bServerSide ? oSettings.aoData.length : iDisplayEnd;\n\t\n\t\t\tfor ( var j=iStart ; j<iEnd ; j++ )\n\t\t\t{\n\t\t\t\tvar iDataIndex = aiDisplay[j];\n\t\t\t\tvar aoData = oSettings.aoData[ iDataIndex ];\n\t\t\t\tif ( aoData.nTr === null )\n\t\t\t\t{\n\t\t\t\t\t_fnCreateTr( oSettings, iDataIndex );\n\t\t\t\t}\n\t\n\t\t\t\tvar nRow = aoData.nTr;\n\t\n\t\t\t\t/* Remove the old striping classes and then add the new one */\n\t\t\t\tif ( iStripes !== 0 )\n\t\t\t\t{\n\t\t\t\t\tvar sStripe = asStripeClasses[ iRowCount % iStripes ];\n\t\t\t\t\tif ( aoData._sRowStripe != sStripe )\n\t\t\t\t\t{\n\t\t\t\t\t\t$(nRow).removeClass( aoData._sRowStripe ).addClass( sStripe );\n\t\t\t\t\t\taoData._sRowStripe = sStripe;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\t// Row callback functions - might want to manipulate the row\n\t\t\t\t// iRowCount and j are not currently documented. Are they at all\n\t\t\t\t// useful?\n\t\t\t\t_fnCallbackFire( oSettings, 'aoRowCallback', null,\n\t\t\t\t\t[nRow, aoData._aData, iRowCount, j] );\n\t\n\t\t\t\tanRows.push( nRow );\n\t\t\t\tiRowCount++;\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t/* Table is empty - create a row with an empty message in it */\n\t\t\tvar sZero = oLang.sZeroRecords;\n\t\t\tif ( oSettings.iDraw == 1 &&  _fnDataSource( oSettings ) == 'ajax' )\n\t\t\t{\n\t\t\t\tsZero = oLang.sLoadingRecords;\n\t\t\t}\n\t\t\telse if ( oLang.sEmptyTable && oSettings.fnRecordsTotal() === 0 )\n\t\t\t{\n\t\t\t\tsZero = oLang.sEmptyTable;\n\t\t\t}\n\t\n\t\t\tanRows[ 0 ] = $( '<tr/>', { 'class': iStripes ? asStripeClasses[0] : '' } )\n\t\t\t\t.append( $('<td />', {\n\t\t\t\t\t'valign':  'top',\n\t\t\t\t\t'colSpan': _fnVisbleColumns( oSettings ),\n\t\t\t\t\t'class':   oSettings.oClasses.sRowEmpty\n\t\t\t\t} ).html( sZero ) )[0];\n\t\t}\n\t\n\t\t/* Header and footer callbacks */\n\t\t_fnCallbackFire( oSettings, 'aoHeaderCallback', 'header', [ $(oSettings.nTHead).children('tr')[0],\n\t\t\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\n\t\n\t\t_fnCallbackFire( oSettings, 'aoFooterCallback', 'footer', [ $(oSettings.nTFoot).children('tr')[0],\n\t\t\t_fnGetDataMaster( oSettings ), iDisplayStart, iDisplayEnd, aiDisplay ] );\n\t\n\t\tvar body = $(oSettings.nTBody);\n\t\n\t\tbody.children().detach();\n\t\tbody.append( $(anRows) );\n\t\n\t\t/* Call all required callback functions for the end of a draw */\n\t\t_fnCallbackFire( oSettings, 'aoDrawCallback', 'draw', [oSettings] );\n\t\n\t\t/* Draw is complete, sorting and filtering must be as well */\n\t\toSettings.bSorted = false;\n\t\toSettings.bFiltered = false;\n\t\toSettings.bDrawing = false;\n\t}\n\t\n\t\n\t/**\n\t * Redraw the table - taking account of the various features which are enabled\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {boolean} [holdPosition] Keep the current paging position. By default\n\t *    the paging is reset to the first page\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnReDraw( settings, holdPosition )\n\t{\n\t\tvar\n\t\t\tfeatures = settings.oFeatures,\n\t\t\tsort     = features.bSort,\n\t\t\tfilter   = features.bFilter;\n\t\n\t\tif ( sort ) {\n\t\t\t_fnSort( settings );\n\t\t}\n\t\n\t\tif ( filter ) {\n\t\t\t_fnFilterComplete( settings, settings.oPreviousSearch );\n\t\t}\n\t\telse {\n\t\t\t// No filtering, so we want to just use the display master\n\t\t\tsettings.aiDisplay = settings.aiDisplayMaster.slice();\n\t\t}\n\t\n\t\tif ( holdPosition !== true ) {\n\t\t\tsettings._iDisplayStart = 0;\n\t\t}\n\t\n\t\t// Let any modules know about the draw hold position state (used by\n\t\t// scrolling internally)\n\t\tsettings._drawHold = holdPosition;\n\t\n\t\t_fnDraw( settings );\n\t\n\t\tsettings._drawHold = false;\n\t}\n\t\n\t\n\t/**\n\t * Add the options to the page HTML for the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAddOptionsHtml ( oSettings )\n\t{\n\t\tvar classes = oSettings.oClasses;\n\t\tvar table = $(oSettings.nTable);\n\t\tvar holding = $('<div/>').insertBefore( table ); // Holding element for speed\n\t\tvar features = oSettings.oFeatures;\n\t\n\t\t// All DataTables are wrapped in a div\n\t\tvar insert = $('<div/>', {\n\t\t\tid:      oSettings.sTableId+'_wrapper',\n\t\t\t'class': classes.sWrapper + (oSettings.nTFoot ? '' : ' '+classes.sNoFooter)\n\t\t} );\n\t\n\t\toSettings.nHolding = holding[0];\n\t\toSettings.nTableWrapper = insert[0];\n\t\toSettings.nTableReinsertBefore = oSettings.nTable.nextSibling;\n\t\n\t\t/* Loop over the user set positioning and place the elements as needed */\n\t\tvar aDom = oSettings.sDom.split('');\n\t\tvar featureNode, cOption, nNewNode, cNext, sAttr, j;\n\t\tfor ( var i=0 ; i<aDom.length ; i++ )\n\t\t{\n\t\t\tfeatureNode = null;\n\t\t\tcOption = aDom[i];\n\t\n\t\t\tif ( cOption == '<' )\n\t\t\t{\n\t\t\t\t/* New container div */\n\t\t\t\tnNewNode = $('<div/>')[0];\n\t\n\t\t\t\t/* Check to see if we should append an id and/or a class name to the container */\n\t\t\t\tcNext = aDom[i+1];\n\t\t\t\tif ( cNext == \"'\" || cNext == '\"' )\n\t\t\t\t{\n\t\t\t\t\tsAttr = \"\";\n\t\t\t\t\tj = 2;\n\t\t\t\t\twhile ( aDom[i+j] != cNext )\n\t\t\t\t\t{\n\t\t\t\t\t\tsAttr += aDom[i+j];\n\t\t\t\t\t\tj++;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t/* Replace jQuery UI constants @todo depreciated */\n\t\t\t\t\tif ( sAttr == \"H\" )\n\t\t\t\t\t{\n\t\t\t\t\t\tsAttr = classes.sJUIHeader;\n\t\t\t\t\t}\n\t\t\t\t\telse if ( sAttr == \"F\" )\n\t\t\t\t\t{\n\t\t\t\t\t\tsAttr = classes.sJUIFooter;\n\t\t\t\t\t}\n\t\n\t\t\t\t\t/* The attribute can be in the format of \"#id.class\", \"#id\" or \"class\" This logic\n\t\t\t\t\t * breaks the string into parts and applies them as needed\n\t\t\t\t\t */\n\t\t\t\t\tif ( sAttr.indexOf('.') != -1 )\n\t\t\t\t\t{\n\t\t\t\t\t\tvar aSplit = sAttr.split('.');\n\t\t\t\t\t\tnNewNode.id = aSplit[0].substr(1, aSplit[0].length-1);\n\t\t\t\t\t\tnNewNode.className = aSplit[1];\n\t\t\t\t\t}\n\t\t\t\t\telse if ( sAttr.charAt(0) == \"#\" )\n\t\t\t\t\t{\n\t\t\t\t\t\tnNewNode.id = sAttr.substr(1, sAttr.length-1);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\tnNewNode.className = sAttr;\n\t\t\t\t\t}\n\t\n\t\t\t\t\ti += j; /* Move along the position array */\n\t\t\t\t}\n\t\n\t\t\t\tinsert.append( nNewNode );\n\t\t\t\tinsert = $(nNewNode);\n\t\t\t}\n\t\t\telse if ( cOption == '>' )\n\t\t\t{\n\t\t\t\t/* End container div */\n\t\t\t\tinsert = insert.parent();\n\t\t\t}\n\t\t\t// @todo Move options into their own plugins?\n\t\t\telse if ( cOption == 'l' && features.bPaginate && features.bLengthChange )\n\t\t\t{\n\t\t\t\t/* Length */\n\t\t\t\tfeatureNode = _fnFeatureHtmlLength( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption == 'f' && features.bFilter )\n\t\t\t{\n\t\t\t\t/* Filter */\n\t\t\t\tfeatureNode = _fnFeatureHtmlFilter( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption == 'r' && features.bProcessing )\n\t\t\t{\n\t\t\t\t/* pRocessing */\n\t\t\t\tfeatureNode = _fnFeatureHtmlProcessing( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption == 't' )\n\t\t\t{\n\t\t\t\t/* Table */\n\t\t\t\tfeatureNode = _fnFeatureHtmlTable( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption ==  'i' && features.bInfo )\n\t\t\t{\n\t\t\t\t/* Info */\n\t\t\t\tfeatureNode = _fnFeatureHtmlInfo( oSettings );\n\t\t\t}\n\t\t\telse if ( cOption == 'p' && features.bPaginate )\n\t\t\t{\n\t\t\t\t/* Pagination */\n\t\t\t\tfeatureNode = _fnFeatureHtmlPaginate( oSettings );\n\t\t\t}\n\t\t\telse if ( DataTable.ext.feature.length !== 0 )\n\t\t\t{\n\t\t\t\t/* Plug-in features */\n\t\t\t\tvar aoFeatures = DataTable.ext.feature;\n\t\t\t\tfor ( var k=0, kLen=aoFeatures.length ; k<kLen ; k++ )\n\t\t\t\t{\n\t\t\t\t\tif ( cOption == aoFeatures[k].cFeature )\n\t\t\t\t\t{\n\t\t\t\t\t\tfeatureNode = aoFeatures[k].fnInit( oSettings );\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t/* Add to the 2D features array */\n\t\t\tif ( featureNode )\n\t\t\t{\n\t\t\t\tvar aanFeatures = oSettings.aanFeatures;\n\t\n\t\t\t\tif ( ! aanFeatures[cOption] )\n\t\t\t\t{\n\t\t\t\t\taanFeatures[cOption] = [];\n\t\t\t\t}\n\t\n\t\t\t\taanFeatures[cOption].push( featureNode );\n\t\t\t\tinsert.append( featureNode );\n\t\t\t}\n\t\t}\n\t\n\t\t/* Built our DOM structure - replace the holding div with what we want */\n\t\tholding.replaceWith( insert );\n\t}\n\t\n\t\n\t/**\n\t * Use the DOM source to create up an array of header cells. The idea here is to\n\t * create a layout grid (array) of rows x columns, which contains a reference\n\t * to the cell that that point in the grid (regardless of col/rowspan), such that\n\t * any column / row could be removed and the new grid constructed\n\t *  @param array {object} aLayout Array to store the calculated layout in\n\t *  @param {node} nThead The header/footer element for the table\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDetectHeader ( aLayout, nThead )\n\t{\n\t\tvar nTrs = $(nThead).children('tr');\n\t\tvar nTr, nCell;\n\t\tvar i, k, l, iLen, jLen, iColShifted, iColumn, iColspan, iRowspan;\n\t\tvar bUnique;\n\t\tvar fnShiftCol = function ( a, i, j ) {\n\t\t\tvar k = a[i];\n\t                while ( k[j] ) {\n\t\t\t\tj++;\n\t\t\t}\n\t\t\treturn j;\n\t\t};\n\t\n\t\taLayout.splice( 0, aLayout.length );\n\t\n\t\t/* We know how many rows there are in the layout - so prep it */\n\t\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\n\t\t{\n\t\t\taLayout.push( [] );\n\t\t}\n\t\n\t\t/* Calculate a layout array */\n\t\tfor ( i=0, iLen=nTrs.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tnTr = nTrs[i];\n\t\t\tiColumn = 0;\n\t\n\t\t\t/* For every cell in the row... */\n\t\t\tnCell = nTr.firstChild;\n\t\t\twhile ( nCell ) {\n\t\t\t\tif ( nCell.nodeName.toUpperCase() == \"TD\" ||\n\t\t\t\t     nCell.nodeName.toUpperCase() == \"TH\" )\n\t\t\t\t{\n\t\t\t\t\t/* Get the col and rowspan attributes from the DOM and sanitise them */\n\t\t\t\t\tiColspan = nCell.getAttribute('colspan') * 1;\n\t\t\t\t\tiRowspan = nCell.getAttribute('rowspan') * 1;\n\t\t\t\t\tiColspan = (!iColspan || iColspan===0 || iColspan===1) ? 1 : iColspan;\n\t\t\t\t\tiRowspan = (!iRowspan || iRowspan===0 || iRowspan===1) ? 1 : iRowspan;\n\t\n\t\t\t\t\t/* There might be colspan cells already in this row, so shift our target\n\t\t\t\t\t * accordingly\n\t\t\t\t\t */\n\t\t\t\t\tiColShifted = fnShiftCol( aLayout, i, iColumn );\n\t\n\t\t\t\t\t/* Cache calculation for unique columns */\n\t\t\t\t\tbUnique = iColspan === 1 ? true : false;\n\t\n\t\t\t\t\t/* If there is col / rowspan, copy the information into the layout grid */\n\t\t\t\t\tfor ( l=0 ; l<iColspan ; l++ )\n\t\t\t\t\t{\n\t\t\t\t\t\tfor ( k=0 ; k<iRowspan ; k++ )\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\taLayout[i+k][iColShifted+l] = {\n\t\t\t\t\t\t\t\t\"cell\": nCell,\n\t\t\t\t\t\t\t\t\"unique\": bUnique\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\taLayout[i+k].nTr = nTr;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tnCell = nCell.nextSibling;\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Get an array of unique th elements, one for each column\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {node} nHeader automatically detect the layout from this node - optional\n\t *  @param {array} aLayout thead/tfoot layout from _fnDetectHeader - optional\n\t *  @returns array {node} aReturn list of unique th's\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetUniqueThs ( oSettings, nHeader, aLayout )\n\t{\n\t\tvar aReturn = [];\n\t\tif ( !aLayout )\n\t\t{\n\t\t\taLayout = oSettings.aoHeader;\n\t\t\tif ( nHeader )\n\t\t\t{\n\t\t\t\taLayout = [];\n\t\t\t\t_fnDetectHeader( aLayout, nHeader );\n\t\t\t}\n\t\t}\n\t\n\t\tfor ( var i=0, iLen=aLayout.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tfor ( var j=0, jLen=aLayout[i].length ; j<jLen ; j++ )\n\t\t\t{\n\t\t\t\tif ( aLayout[i][j].unique &&\n\t\t\t\t\t (!aReturn[j] || !oSettings.bSortCellsTop) )\n\t\t\t\t{\n\t\t\t\t\taReturn[j] = aLayout[i][j].cell;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn aReturn;\n\t}\n\t\n\t/**\n\t * Create an Ajax call based on the table's settings, taking into account that\n\t * parameters can have multiple forms, and backwards compatibility.\n\t *\n\t * @param {object} oSettings dataTables settings object\n\t * @param {array} data Data to send to the server, required by\n\t *     DataTables - may be augmented by developer callbacks\n\t * @param {function} fn Callback function to run when data is obtained\n\t */\n\tfunction _fnBuildAjax( oSettings, data, fn )\n\t{\n\t\t// Compatibility with 1.9-, allow fnServerData and event to manipulate\n\t\t_fnCallbackFire( oSettings, 'aoServerParams', 'serverParams', [data] );\n\t\n\t\t// Convert to object based for 1.10+ if using the old array scheme which can\n\t\t// come from server-side processing or serverParams\n\t\tif ( data && $.isArray(data) ) {\n\t\t\tvar tmp = {};\n\t\t\tvar rbracket = /(.*?)\\[\\]$/;\n\t\n\t\t\t$.each( data, function (key, val) {\n\t\t\t\tvar match = val.name.match(rbracket);\n\t\n\t\t\t\tif ( match ) {\n\t\t\t\t\t// Support for arrays\n\t\t\t\t\tvar name = match[0];\n\t\n\t\t\t\t\tif ( ! tmp[ name ] ) {\n\t\t\t\t\t\ttmp[ name ] = [];\n\t\t\t\t\t}\n\t\t\t\t\ttmp[ name ].push( val.value );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttmp[val.name] = val.value;\n\t\t\t\t}\n\t\t\t} );\n\t\t\tdata = tmp;\n\t\t}\n\t\n\t\tvar ajaxData;\n\t\tvar ajax = oSettings.ajax;\n\t\tvar instance = oSettings.oInstance;\n\t\tvar callback = function ( json ) {\n\t\t\t_fnCallbackFire( oSettings, null, 'xhr', [oSettings, json, oSettings.jqXHR] );\n\t\t\tfn( json );\n\t\t};\n\t\n\t\tif ( $.isPlainObject( ajax ) && ajax.data )\n\t\t{\n\t\t\tajaxData = ajax.data;\n\t\n\t\t\tvar newData = $.isFunction( ajaxData ) ?\n\t\t\t\tajaxData( data, oSettings ) :  // fn can manipulate data or return\n\t\t\t\tajaxData;                      // an object object or array to merge\n\t\n\t\t\t// If the function returned something, use that alone\n\t\t\tdata = $.isFunction( ajaxData ) && newData ?\n\t\t\t\tnewData :\n\t\t\t\t$.extend( true, data, newData );\n\t\n\t\t\t// Remove the data property as we've resolved it already and don't want\n\t\t\t// jQuery to do it again (it is restored at the end of the function)\n\t\t\tdelete ajax.data;\n\t\t}\n\t\n\t\tvar baseAjax = {\n\t\t\t\"data\": data,\n\t\t\t\"success\": function (json) {\n\t\t\t\tvar error = json.error || json.sError;\n\t\t\t\tif ( error ) {\n\t\t\t\t\t_fnLog( oSettings, 0, error );\n\t\t\t\t}\n\t\n\t\t\t\toSettings.json = json;\n\t\t\t\tcallback( json );\n\t\t\t},\n\t\t\t\"dataType\": \"json\",\n\t\t\t\"cache\": false,\n\t\t\t\"type\": oSettings.sServerMethod,\n\t\t\t\"error\": function (xhr, error, thrown) {\n\t\t\t\tvar ret = _fnCallbackFire( oSettings, null, 'xhr', [oSettings, null, oSettings.jqXHR] );\n\t\n\t\t\t\tif ( $.inArray( true, ret ) === -1 ) {\n\t\t\t\t\tif ( error == \"parsererror\" ) {\n\t\t\t\t\t\t_fnLog( oSettings, 0, 'Invalid JSON response', 1 );\n\t\t\t\t\t}\n\t\t\t\t\telse if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\t_fnLog( oSettings, 0, 'Ajax error', 7 );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\t_fnProcessingDisplay( oSettings, false );\n\t\t\t}\n\t\t};\n\t\n\t\t// Store the data submitted for the API\n\t\toSettings.oAjaxData = data;\n\t\n\t\t// Allow plug-ins and external processes to modify the data\n\t\t_fnCallbackFire( oSettings, null, 'preXhr', [oSettings, data] );\n\t\n\t\tif ( oSettings.fnServerData )\n\t\t{\n\t\t\t// DataTables 1.9- compatibility\n\t\t\toSettings.fnServerData.call( instance,\n\t\t\t\toSettings.sAjaxSource,\n\t\t\t\t$.map( data, function (val, key) { // Need to convert back to 1.9 trad format\n\t\t\t\t\treturn { name: key, value: val };\n\t\t\t\t} ),\n\t\t\t\tcallback,\n\t\t\t\toSettings\n\t\t\t);\n\t\t}\n\t\telse if ( oSettings.sAjaxSource || typeof ajax === 'string' )\n\t\t{\n\t\t\t// DataTables 1.9- compatibility\n\t\t\toSettings.jqXHR = $.ajax( $.extend( baseAjax, {\n\t\t\t\turl: ajax || oSettings.sAjaxSource\n\t\t\t} ) );\n\t\t}\n\t\telse if ( $.isFunction( ajax ) )\n\t\t{\n\t\t\t// Is a function - let the caller define what needs to be done\n\t\t\toSettings.jqXHR = ajax.call( instance, data, callback, oSettings );\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Object to extend the base settings\n\t\t\toSettings.jqXHR = $.ajax( $.extend( baseAjax, ajax ) );\n\t\n\t\t\t// Restore for next time around\n\t\t\tajax.data = ajaxData;\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Update the table using an Ajax call\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {boolean} Block the table drawing or not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAjaxUpdate( settings )\n\t{\n\t\tif ( settings.bAjaxDataGet ) {\n\t\t\tsettings.iDraw++;\n\t\t\t_fnProcessingDisplay( settings, true );\n\t\n\t\t\t_fnBuildAjax(\n\t\t\t\tsettings,\n\t\t\t\t_fnAjaxParameters( settings ),\n\t\t\t\tfunction(json) {\n\t\t\t\t\t_fnAjaxUpdateDraw( settings, json );\n\t\t\t\t}\n\t\t\t);\n\t\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\t\n\t\n\t/**\n\t * Build up the parameters in an object needed for a server-side processing\n\t * request. Note that this is basically done twice, is different ways - a modern\n\t * method which is used by default in DataTables 1.10 which uses objects and\n\t * arrays, or the 1.9- method with is name / value pairs. 1.9 method is used if\n\t * the sAjaxSource option is used in the initialisation, or the legacyAjax\n\t * option is set.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {bool} block the table drawing or not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAjaxParameters( settings )\n\t{\n\t\tvar\n\t\t\tcolumns = settings.aoColumns,\n\t\t\tcolumnCount = columns.length,\n\t\t\tfeatures = settings.oFeatures,\n\t\t\tpreSearch = settings.oPreviousSearch,\n\t\t\tpreColSearch = settings.aoPreSearchCols,\n\t\t\ti, data = [], dataProp, column, columnSearch,\n\t\t\tsort = _fnSortFlatten( settings ),\n\t\t\tdisplayStart = settings._iDisplayStart,\n\t\t\tdisplayLength = features.bPaginate !== false ?\n\t\t\t\tsettings._iDisplayLength :\n\t\t\t\t-1;\n\t\n\t\tvar param = function ( name, value ) {\n\t\t\tdata.push( { 'name': name, 'value': value } );\n\t\t};\n\t\n\t\t// DataTables 1.9- compatible method\n\t\tparam( 'sEcho',          settings.iDraw );\n\t\tparam( 'iColumns',       columnCount );\n\t\tparam( 'sColumns',       _pluck( columns, 'sName' ).join(',') );\n\t\tparam( 'iDisplayStart',  displayStart );\n\t\tparam( 'iDisplayLength', displayLength );\n\t\n\t\t// DataTables 1.10+ method\n\t\tvar d = {\n\t\t\tdraw:    settings.iDraw,\n\t\t\tcolumns: [],\n\t\t\torder:   [],\n\t\t\tstart:   displayStart,\n\t\t\tlength:  displayLength,\n\t\t\tsearch:  {\n\t\t\t\tvalue: preSearch.sSearch,\n\t\t\t\tregex: preSearch.bRegex\n\t\t\t}\n\t\t};\n\t\n\t\tfor ( i=0 ; i<columnCount ; i++ ) {\n\t\t\tcolumn = columns[i];\n\t\t\tcolumnSearch = preColSearch[i];\n\t\t\tdataProp = typeof column.mData==\"function\" ? 'function' : column.mData ;\n\t\n\t\t\td.columns.push( {\n\t\t\t\tdata:       dataProp,\n\t\t\t\tname:       column.sName,\n\t\t\t\tsearchable: column.bSearchable,\n\t\t\t\torderable:  column.bSortable,\n\t\t\t\tsearch:     {\n\t\t\t\t\tvalue: columnSearch.sSearch,\n\t\t\t\t\tregex: columnSearch.bRegex\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\tparam( \"mDataProp_\"+i, dataProp );\n\t\n\t\t\tif ( features.bFilter ) {\n\t\t\t\tparam( 'sSearch_'+i,     columnSearch.sSearch );\n\t\t\t\tparam( 'bRegex_'+i,      columnSearch.bRegex );\n\t\t\t\tparam( 'bSearchable_'+i, column.bSearchable );\n\t\t\t}\n\t\n\t\t\tif ( features.bSort ) {\n\t\t\t\tparam( 'bSortable_'+i, column.bSortable );\n\t\t\t}\n\t\t}\n\t\n\t\tif ( features.bFilter ) {\n\t\t\tparam( 'sSearch', preSearch.sSearch );\n\t\t\tparam( 'bRegex', preSearch.bRegex );\n\t\t}\n\t\n\t\tif ( features.bSort ) {\n\t\t\t$.each( sort, function ( i, val ) {\n\t\t\t\td.order.push( { column: val.col, dir: val.dir } );\n\t\n\t\t\t\tparam( 'iSortCol_'+i, val.col );\n\t\t\t\tparam( 'sSortDir_'+i, val.dir );\n\t\t\t} );\n\t\n\t\t\tparam( 'iSortingCols', sort.length );\n\t\t}\n\t\n\t\t// If the legacy.ajax parameter is null, then we automatically decide which\n\t\t// form to use, based on sAjaxSource\n\t\tvar legacy = DataTable.ext.legacy.ajax;\n\t\tif ( legacy === null ) {\n\t\t\treturn settings.sAjaxSource ? data : d;\n\t\t}\n\t\n\t\t// Otherwise, if legacy has been specified then we use that to decide on the\n\t\t// form\n\t\treturn legacy ? data : d;\n\t}\n\t\n\t\n\t/**\n\t * Data the data from the server (nuking the old) and redraw the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {object} json json data return from the server.\n\t *  @param {string} json.sEcho Tracking flag for DataTables to match requests\n\t *  @param {int} json.iTotalRecords Number of records in the data set, not accounting for filtering\n\t *  @param {int} json.iTotalDisplayRecords Number of records in the data set, accounting for filtering\n\t *  @param {array} json.aaData The data to display on this page\n\t *  @param {string} [json.sColumns] Column ordering (sName, comma separated)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnAjaxUpdateDraw ( settings, json )\n\t{\n\t\t// v1.10 uses camelCase variables, while 1.9 uses Hungarian notation.\n\t\t// Support both\n\t\tvar compat = function ( old, modern ) {\n\t\t\treturn json[old] !== undefined ? json[old] : json[modern];\n\t\t};\n\t\n\t\tvar data = _fnAjaxDataSrc( settings, json );\n\t\tvar draw            = compat( 'sEcho',                'draw' );\n\t\tvar recordsTotal    = compat( 'iTotalRecords',        'recordsTotal' );\n\t\tvar recordsFiltered = compat( 'iTotalDisplayRecords', 'recordsFiltered' );\n\t\n\t\tif ( draw ) {\n\t\t\t// Protect against out of sequence returns\n\t\t\tif ( draw*1 < settings.iDraw ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tsettings.iDraw = draw * 1;\n\t\t}\n\t\n\t\t_fnClearTable( settings );\n\t\tsettings._iRecordsTotal   = parseInt(recordsTotal, 10);\n\t\tsettings._iRecordsDisplay = parseInt(recordsFiltered, 10);\n\t\n\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t_fnAddData( settings, data[i] );\n\t\t}\n\t\tsettings.aiDisplay = settings.aiDisplayMaster.slice();\n\t\n\t\tsettings.bAjaxDataGet = false;\n\t\t_fnDraw( settings );\n\t\n\t\tif ( ! settings._bInitComplete ) {\n\t\t\t_fnInitComplete( settings, json );\n\t\t}\n\t\n\t\tsettings.bAjaxDataGet = true;\n\t\t_fnProcessingDisplay( settings, false );\n\t}\n\t\n\t\n\t/**\n\t * Get the data from the JSON data source to use for drawing a table. Using\n\t * `_fnGetObjectDataFn` allows the data to be sourced from a property of the\n\t * source object, or from a processing function.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param  {object} json Data source object / array from the server\n\t *  @return {array} Array of data to use\n\t */\n\tfunction _fnAjaxDataSrc ( oSettings, json )\n\t{\n\t\tvar dataSrc = $.isPlainObject( oSettings.ajax ) && oSettings.ajax.dataSrc !== undefined ?\n\t\t\toSettings.ajax.dataSrc :\n\t\t\toSettings.sAjaxDataProp; // Compatibility with 1.9-.\n\t\n\t\t// Compatibility with 1.9-. In order to read from aaData, check if the\n\t\t// default has been changed, if not, check for aaData\n\t\tif ( dataSrc === 'data' ) {\n\t\t\treturn json.aaData || json[dataSrc];\n\t\t}\n\t\n\t\treturn dataSrc !== \"\" ?\n\t\t\t_fnGetObjectDataFn( dataSrc )( json ) :\n\t\t\tjson;\n\t}\n\t\n\t/**\n\t * Generate the node required for filtering text\n\t *  @returns {node} Filter control element\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlFilter ( settings )\n\t{\n\t\tvar classes = settings.oClasses;\n\t\tvar tableId = settings.sTableId;\n\t\tvar language = settings.oLanguage;\n\t\tvar previousSearch = settings.oPreviousSearch;\n\t\tvar features = settings.aanFeatures;\n\t\tvar input = '<input type=\"search\" class=\"'+classes.sFilterInput+'\"/>';\n\t\n\t\tvar str = language.sSearch;\n\t\tstr = str.match(/_INPUT_/) ?\n\t\t\tstr.replace('_INPUT_', input) :\n\t\t\tstr+input;\n\t\n\t\tvar filter = $('<div/>', {\n\t\t\t\t'id': ! features.f ? tableId+'_filter' : null,\n\t\t\t\t'class': classes.sFilter\n\t\t\t} )\n\t\t\t.append( $('<label/>' ).append( str ) );\n\t\n\t\tvar searchFn = function() {\n\t\t\t/* Update all other filter input elements for the new display */\n\t\t\tvar n = features.f;\n\t\t\tvar val = !this.value ? \"\" : this.value; // mental IE8 fix :-(\n\t\n\t\t\t/* Now do the filter */\n\t\t\tif ( val != previousSearch.sSearch ) {\n\t\t\t\t_fnFilterComplete( settings, {\n\t\t\t\t\t\"sSearch\": val,\n\t\t\t\t\t\"bRegex\": previousSearch.bRegex,\n\t\t\t\t\t\"bSmart\": previousSearch.bSmart ,\n\t\t\t\t\t\"bCaseInsensitive\": previousSearch.bCaseInsensitive\n\t\t\t\t} );\n\t\n\t\t\t\t// Need to redraw, without resorting\n\t\t\t\tsettings._iDisplayStart = 0;\n\t\t\t\t_fnDraw( settings );\n\t\t\t}\n\t\t};\n\t\n\t\tvar searchDelay = settings.searchDelay !== null ?\n\t\t\tsettings.searchDelay :\n\t\t\t_fnDataSource( settings ) === 'ssp' ?\n\t\t\t\t400 :\n\t\t\t\t0;\n\t\n\t\tvar jqFilter = $('input', filter)\n\t\t\t.val( previousSearch.sSearch )\n\t\t\t.attr( 'placeholder', language.sSearchPlaceholder )\n\t\t\t.bind(\n\t\t\t\t'keyup.DT search.DT input.DT paste.DT cut.DT',\n\t\t\t\tsearchDelay ?\n\t\t\t\t\t_fnThrottle( searchFn, searchDelay ) :\n\t\t\t\t\tsearchFn\n\t\t\t)\n\t\t\t.bind( 'keypress.DT', function(e) {\n\t\t\t\t/* Prevent form submission */\n\t\t\t\tif ( e.keyCode == 13 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t} )\n\t\t\t.attr('aria-controls', tableId);\n\t\n\t\t// Update the input elements whenever the table is filtered\n\t\t$(settings.nTable).on( 'search.dt.DT', function ( ev, s ) {\n\t\t\tif ( settings === s ) {\n\t\t\t\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t\t\t\t// inside an iframe or frame...\n\t\t\t\ttry {\n\t\t\t\t\tif ( jqFilter[0] !== document.activeElement ) {\n\t\t\t\t\t\tjqFilter.val( previousSearch.sSearch );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tcatch ( e ) {}\n\t\t\t}\n\t\t} );\n\t\n\t\treturn filter[0];\n\t}\n\t\n\t\n\t/**\n\t * Filter the table using both the global filter and column based filtering\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {object} oSearch search information\n\t *  @param {int} [iForce] force a research of the master array (1) or not (undefined or 0)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilterComplete ( oSettings, oInput, iForce )\n\t{\n\t\tvar oPrevSearch = oSettings.oPreviousSearch;\n\t\tvar aoPrevSearch = oSettings.aoPreSearchCols;\n\t\tvar fnSaveFilter = function ( oFilter ) {\n\t\t\t/* Save the filtering values */\n\t\t\toPrevSearch.sSearch = oFilter.sSearch;\n\t\t\toPrevSearch.bRegex = oFilter.bRegex;\n\t\t\toPrevSearch.bSmart = oFilter.bSmart;\n\t\t\toPrevSearch.bCaseInsensitive = oFilter.bCaseInsensitive;\n\t\t};\n\t\tvar fnRegex = function ( o ) {\n\t\t\t// Backwards compatibility with the bEscapeRegex option\n\t\t\treturn o.bEscapeRegex !== undefined ? !o.bEscapeRegex : o.bRegex;\n\t\t};\n\t\n\t\t// Resolve any column types that are unknown due to addition or invalidation\n\t\t// @todo As per sort - can this be moved into an event handler?\n\t\t_fnColumnTypes( oSettings );\n\t\n\t\t/* In server-side processing all filtering is done by the server, so no point hanging around here */\n\t\tif ( _fnDataSource( oSettings ) != 'ssp' )\n\t\t{\n\t\t\t/* Global filter */\n\t\t\t_fnFilter( oSettings, oInput.sSearch, iForce, fnRegex(oInput), oInput.bSmart, oInput.bCaseInsensitive );\n\t\t\tfnSaveFilter( oInput );\n\t\n\t\t\t/* Now do the individual column filter */\n\t\t\tfor ( var i=0 ; i<aoPrevSearch.length ; i++ )\n\t\t\t{\n\t\t\t\t_fnFilterColumn( oSettings, aoPrevSearch[i].sSearch, i, fnRegex(aoPrevSearch[i]),\n\t\t\t\t\taoPrevSearch[i].bSmart, aoPrevSearch[i].bCaseInsensitive );\n\t\t\t}\n\t\n\t\t\t/* Custom filtering */\n\t\t\t_fnFilterCustom( oSettings );\n\t\t}\n\t\telse\n\t\t{\n\t\t\tfnSaveFilter( oInput );\n\t\t}\n\t\n\t\t/* Tell the draw function we have been filtering */\n\t\toSettings.bFiltered = true;\n\t\t_fnCallbackFire( oSettings, null, 'search', [oSettings] );\n\t}\n\t\n\t\n\t/**\n\t * Apply custom filtering functions\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilterCustom( settings )\n\t{\n\t\tvar filters = DataTable.ext.search;\n\t\tvar displayRows = settings.aiDisplay;\n\t\tvar row, rowIdx;\n\t\n\t\tfor ( var i=0, ien=filters.length ; i<ien ; i++ ) {\n\t\t\tvar rows = [];\n\t\n\t\t\t// Loop over each row and see if it should be included\n\t\t\tfor ( var j=0, jen=displayRows.length ; j<jen ; j++ ) {\n\t\t\t\trowIdx = displayRows[ j ];\n\t\t\t\trow = settings.aoData[ rowIdx ];\n\t\n\t\t\t\tif ( filters[i]( settings, row._aFilterData, rowIdx, row._aData, j ) ) {\n\t\t\t\t\trows.push( rowIdx );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// So the array reference doesn't break set the results into the\n\t\t\t// existing array\n\t\t\tdisplayRows.length = 0;\n\t\t\tdisplayRows.push.apply( displayRows, rows );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Filter the table on a per-column basis\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {string} sInput string to filter on\n\t *  @param {int} iColumn column to filter\n\t *  @param {bool} bRegex treat search string as a regular expression or not\n\t *  @param {bool} bSmart use smart filtering or not\n\t *  @param {bool} bCaseInsensitive Do case insenstive matching or not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilterColumn ( settings, searchStr, colIdx, regex, smart, caseInsensitive )\n\t{\n\t\tif ( searchStr === '' ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar data;\n\t\tvar display = settings.aiDisplay;\n\t\tvar rpSearch = _fnFilterCreateSearch( searchStr, regex, smart, caseInsensitive );\n\t\n\t\tfor ( var i=display.length-1 ; i>=0 ; i-- ) {\n\t\t\tdata = settings.aoData[ display[i] ]._aFilterData[ colIdx ];\n\t\n\t\t\tif ( ! rpSearch.test( data ) ) {\n\t\t\t\tdisplay.splice( i, 1 );\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Filter the data table based on user input and draw the table\n\t *  @param {object} settings dataTables settings object\n\t *  @param {string} input string to filter on\n\t *  @param {int} force optional - force a research of the master array (1) or not (undefined or 0)\n\t *  @param {bool} regex treat as a regular expression or not\n\t *  @param {bool} smart perform smart filtering or not\n\t *  @param {bool} caseInsensitive Do case insenstive matching or not\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilter( settings, input, force, regex, smart, caseInsensitive )\n\t{\n\t\tvar rpSearch = _fnFilterCreateSearch( input, regex, smart, caseInsensitive );\n\t\tvar prevSearch = settings.oPreviousSearch.sSearch;\n\t\tvar displayMaster = settings.aiDisplayMaster;\n\t\tvar display, invalidated, i;\n\t\n\t\t// Need to take account of custom filtering functions - always filter\n\t\tif ( DataTable.ext.search.length !== 0 ) {\n\t\t\tforce = true;\n\t\t}\n\t\n\t\t// Check if any of the rows were invalidated\n\t\tinvalidated = _fnFilterData( settings );\n\t\n\t\t// If the input is blank - we just want the full data set\n\t\tif ( input.length <= 0 ) {\n\t\t\tsettings.aiDisplay = displayMaster.slice();\n\t\t}\n\t\telse {\n\t\t\t// New search - start from the master array\n\t\t\tif ( invalidated ||\n\t\t\t\t force ||\n\t\t\t\t prevSearch.length > input.length ||\n\t\t\t\t input.indexOf(prevSearch) !== 0 ||\n\t\t\t\t settings.bSorted // On resort, the display master needs to be\n\t\t\t\t                  // re-filtered since indexes will have changed\n\t\t\t) {\n\t\t\t\tsettings.aiDisplay = displayMaster.slice();\n\t\t\t}\n\t\n\t\t\t// Search the display array\n\t\t\tdisplay = settings.aiDisplay;\n\t\n\t\t\tfor ( i=display.length-1 ; i>=0 ; i-- ) {\n\t\t\t\tif ( ! rpSearch.test( settings.aoData[ display[i] ]._sFilterRow ) ) {\n\t\t\t\t\tdisplay.splice( i, 1 );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Build a regular expression object suitable for searching a table\n\t *  @param {string} sSearch string to search for\n\t *  @param {bool} bRegex treat as a regular expression or not\n\t *  @param {bool} bSmart perform smart filtering or not\n\t *  @param {bool} bCaseInsensitive Do case insensitive matching or not\n\t *  @returns {RegExp} constructed object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFilterCreateSearch( search, regex, smart, caseInsensitive )\n\t{\n\t\tsearch = regex ?\n\t\t\tsearch :\n\t\t\t_fnEscapeRegex( search );\n\t\t\n\t\tif ( smart ) {\n\t\t\t/* For smart filtering we want to allow the search to work regardless of\n\t\t\t * word order. We also want double quoted text to be preserved, so word\n\t\t\t * order is important - a la google. So this is what we want to\n\t\t\t * generate:\n\t\t\t * \n\t\t\t * ^(?=.*?\\bone\\b)(?=.*?\\btwo three\\b)(?=.*?\\bfour\\b).*$\n\t\t\t */\n\t\t\tvar a = $.map( search.match( /\"[^\"]+\"|[^ ]+/g ) || [''], function ( word ) {\n\t\t\t\tif ( word.charAt(0) === '\"' ) {\n\t\t\t\t\tvar m = word.match( /^\"(.*)\"$/ );\n\t\t\t\t\tword = m ? m[1] : word;\n\t\t\t\t}\n\t\n\t\t\t\treturn word.replace('\"', '');\n\t\t\t} );\n\t\n\t\t\tsearch = '^(?=.*?'+a.join( ')(?=.*?' )+').*$';\n\t\t}\n\t\n\t\treturn new RegExp( search, caseInsensitive ? 'i' : '' );\n\t}\n\t\n\t\n\t/**\n\t * Escape a string such that it can be used in a regular expression\n\t *  @param {string} sVal string to escape\n\t *  @returns {string} escaped string\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnEscapeRegex ( sVal )\n\t{\n\t\treturn sVal.replace( _re_escape_regex, '\\\\$1' );\n\t}\n\t\n\t\n\t\n\tvar __filter_div = $('<div>')[0];\n\tvar __filter_div_textContent = __filter_div.textContent !== undefined;\n\t\n\t// Update the filtering data for each row if needed (by invalidation or first run)\n\tfunction _fnFilterData ( settings )\n\t{\n\t\tvar columns = settings.aoColumns;\n\t\tvar column;\n\t\tvar i, j, ien, jen, filterData, cellData, row;\n\t\tvar fomatters = DataTable.ext.type.search;\n\t\tvar wasInvalidated = false;\n\t\n\t\tfor ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\trow = settings.aoData[i];\n\t\n\t\t\tif ( ! row._aFilterData ) {\n\t\t\t\tfilterData = [];\n\t\n\t\t\t\tfor ( j=0, jen=columns.length ; j<jen ; j++ ) {\n\t\t\t\t\tcolumn = columns[j];\n\t\n\t\t\t\t\tif ( column.bSearchable ) {\n\t\t\t\t\t\tcellData = _fnGetCellData( settings, i, j, 'filter' );\n\t\n\t\t\t\t\t\tif ( fomatters[ column.sType ] ) {\n\t\t\t\t\t\t\tcellData = fomatters[ column.sType ]( cellData );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t// Search in DataTables 1.10 is string based. In 1.11 this\n\t\t\t\t\t\t// should be altered to also allow strict type checking.\n\t\t\t\t\t\tif ( cellData === null ) {\n\t\t\t\t\t\t\tcellData = '';\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tif ( typeof cellData !== 'string' && cellData.toString ) {\n\t\t\t\t\t\t\tcellData = cellData.toString();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tcellData = '';\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// If it looks like there is an HTML entity in the string,\n\t\t\t\t\t// attempt to decode it so sorting works as expected. Note that\n\t\t\t\t\t// we could use a single line of jQuery to do this, but the DOM\n\t\t\t\t\t// method used here is much faster http://jsperf.com/html-decode\n\t\t\t\t\tif ( cellData.indexOf && cellData.indexOf('&') !== -1 ) {\n\t\t\t\t\t\t__filter_div.innerHTML = cellData;\n\t\t\t\t\t\tcellData = __filter_div_textContent ?\n\t\t\t\t\t\t\t__filter_div.textContent :\n\t\t\t\t\t\t\t__filter_div.innerText;\n\t\t\t\t\t}\n\t\n\t\t\t\t\tif ( cellData.replace ) {\n\t\t\t\t\t\tcellData = cellData.replace(/[\\r\\n]/g, '');\n\t\t\t\t\t}\n\t\n\t\t\t\t\tfilterData.push( cellData );\n\t\t\t\t}\n\t\n\t\t\t\trow._aFilterData = filterData;\n\t\t\t\trow._sFilterRow = filterData.join('  ');\n\t\t\t\twasInvalidated = true;\n\t\t\t}\n\t\t}\n\t\n\t\treturn wasInvalidated;\n\t}\n\t\n\t\n\t/**\n\t * Convert from the internal Hungarian notation to camelCase for external\n\t * interaction\n\t *  @param {object} obj Object to convert\n\t *  @returns {object} Inverted object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSearchToCamel ( obj )\n\t{\n\t\treturn {\n\t\t\tsearch:          obj.sSearch,\n\t\t\tsmart:           obj.bSmart,\n\t\t\tregex:           obj.bRegex,\n\t\t\tcaseInsensitive: obj.bCaseInsensitive\n\t\t};\n\t}\n\t\n\t\n\t\n\t/**\n\t * Convert from camelCase notation to the internal Hungarian. We could use the\n\t * Hungarian convert function here, but this is cleaner\n\t *  @param {object} obj Object to convert\n\t *  @returns {object} Inverted object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSearchToHung ( obj )\n\t{\n\t\treturn {\n\t\t\tsSearch:          obj.search,\n\t\t\tbSmart:           obj.smart,\n\t\t\tbRegex:           obj.regex,\n\t\t\tbCaseInsensitive: obj.caseInsensitive\n\t\t};\n\t}\n\t\n\t/**\n\t * Generate the node required for the info display\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {node} Information element\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlInfo ( settings )\n\t{\n\t\tvar\n\t\t\ttid = settings.sTableId,\n\t\t\tnodes = settings.aanFeatures.i,\n\t\t\tn = $('<div/>', {\n\t\t\t\t'class': settings.oClasses.sInfo,\n\t\t\t\t'id': ! nodes ? tid+'_info' : null\n\t\t\t} );\n\t\n\t\tif ( ! nodes ) {\n\t\t\t// Update display on each draw\n\t\t\tsettings.aoDrawCallback.push( {\n\t\t\t\t\"fn\": _fnUpdateInfo,\n\t\t\t\t\"sName\": \"information\"\n\t\t\t} );\n\t\n\t\t\tn\n\t\t\t\t.attr( 'role', 'status' )\n\t\t\t\t.attr( 'aria-live', 'polite' );\n\t\n\t\t\t// Table is described by our info div\n\t\t\t$(settings.nTable).attr( 'aria-describedby', tid+'_info' );\n\t\t}\n\t\n\t\treturn n[0];\n\t}\n\t\n\t\n\t/**\n\t * Update the information elements in the display\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnUpdateInfo ( settings )\n\t{\n\t\t/* Show information about the table */\n\t\tvar nodes = settings.aanFeatures.i;\n\t\tif ( nodes.length === 0 ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar\n\t\t\tlang  = settings.oLanguage,\n\t\t\tstart = settings._iDisplayStart+1,\n\t\t\tend   = settings.fnDisplayEnd(),\n\t\t\tmax   = settings.fnRecordsTotal(),\n\t\t\ttotal = settings.fnRecordsDisplay(),\n\t\t\tout   = total ?\n\t\t\t\tlang.sInfo :\n\t\t\t\tlang.sInfoEmpty;\n\t\n\t\tif ( total !== max ) {\n\t\t\t/* Record set after filtering */\n\t\t\tout += ' ' + lang.sInfoFiltered;\n\t\t}\n\t\n\t\t// Convert the macros\n\t\tout += lang.sInfoPostFix;\n\t\tout = _fnInfoMacros( settings, out );\n\t\n\t\tvar callback = lang.fnInfoCallback;\n\t\tif ( callback !== null ) {\n\t\t\tout = callback.call( settings.oInstance,\n\t\t\t\tsettings, start, end, max, total, out\n\t\t\t);\n\t\t}\n\t\n\t\t$(nodes).html( out );\n\t}\n\t\n\t\n\tfunction _fnInfoMacros ( settings, str )\n\t{\n\t\t// When infinite scrolling, we are always starting at 1. _iDisplayStart is used only\n\t\t// internally\n\t\tvar\n\t\t\tformatter  = settings.fnFormatNumber,\n\t\t\tstart      = settings._iDisplayStart+1,\n\t\t\tlen        = settings._iDisplayLength,\n\t\t\tvis        = settings.fnRecordsDisplay(),\n\t\t\tall        = len === -1;\n\t\n\t\treturn str.\n\t\t\treplace(/_START_/g, formatter.call( settings, start ) ).\n\t\t\treplace(/_END_/g,   formatter.call( settings, settings.fnDisplayEnd() ) ).\n\t\t\treplace(/_MAX_/g,   formatter.call( settings, settings.fnRecordsTotal() ) ).\n\t\t\treplace(/_TOTAL_/g, formatter.call( settings, vis ) ).\n\t\t\treplace(/_PAGE_/g,  formatter.call( settings, all ? 1 : Math.ceil( start / len ) ) ).\n\t\t\treplace(/_PAGES_/g, formatter.call( settings, all ? 1 : Math.ceil( vis / len ) ) );\n\t}\n\t\n\t\n\t\n\t/**\n\t * Draw the table for the first time, adding all required features\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnInitialise ( settings )\n\t{\n\t\tvar i, iLen, iAjaxStart=settings.iInitDisplayStart;\n\t\tvar columns = settings.aoColumns, column;\n\t\tvar features = settings.oFeatures;\n\t\n\t\t/* Ensure that the table data is fully initialised */\n\t\tif ( ! settings.bInitialised ) {\n\t\t\tsetTimeout( function(){ _fnInitialise( settings ); }, 200 );\n\t\t\treturn;\n\t\t}\n\t\n\t\t/* Show the display HTML options */\n\t\t_fnAddOptionsHtml( settings );\n\t\n\t\t/* Build and draw the header / footer for the table */\n\t\t_fnBuildHead( settings );\n\t\t_fnDrawHead( settings, settings.aoHeader );\n\t\t_fnDrawHead( settings, settings.aoFooter );\n\t\n\t\t/* Okay to show that something is going on now */\n\t\t_fnProcessingDisplay( settings, true );\n\t\n\t\t/* Calculate sizes for columns */\n\t\tif ( features.bAutoWidth ) {\n\t\t\t_fnCalculateColumnWidths( settings );\n\t\t}\n\t\n\t\tfor ( i=0, iLen=columns.length ; i<iLen ; i++ ) {\n\t\t\tcolumn = columns[i];\n\t\n\t\t\tif ( column.sWidth ) {\n\t\t\t\tcolumn.nTh.style.width = _fnStringToCss( column.sWidth );\n\t\t\t}\n\t\t}\n\t\n\t\t// If there is default sorting required - let's do it. The sort function\n\t\t// will do the drawing for us. Otherwise we draw the table regardless of the\n\t\t// Ajax source - this allows the table to look initialised for Ajax sourcing\n\t\t// data (show 'loading' message possibly)\n\t\t_fnReDraw( settings );\n\t\n\t\t// Server-side processing init complete is done by _fnAjaxUpdateDraw\n\t\tvar dataSrc = _fnDataSource( settings );\n\t\tif ( dataSrc != 'ssp' ) {\n\t\t\t// if there is an ajax source load the data\n\t\t\tif ( dataSrc == 'ajax' ) {\n\t\t\t\t_fnBuildAjax( settings, [], function(json) {\n\t\t\t\t\tvar aData = _fnAjaxDataSrc( settings, json );\n\t\n\t\t\t\t\t// Got the data - add it to the table\n\t\t\t\t\tfor ( i=0 ; i<aData.length ; i++ ) {\n\t\t\t\t\t\t_fnAddData( settings, aData[i] );\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// Reset the init display for cookie saving. We've already done\n\t\t\t\t\t// a filter, and therefore cleared it before. So we need to make\n\t\t\t\t\t// it appear 'fresh'\n\t\t\t\t\tsettings.iInitDisplayStart = iAjaxStart;\n\t\n\t\t\t\t\t_fnReDraw( settings );\n\t\n\t\t\t\t\t_fnProcessingDisplay( settings, false );\n\t\t\t\t\t_fnInitComplete( settings, json );\n\t\t\t\t}, settings );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t_fnProcessingDisplay( settings, false );\n\t\t\t\t_fnInitComplete( settings );\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Draw the table for the first time, adding all required features\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {object} [json] JSON from the server that completed the table, if using Ajax source\n\t *    with client-side processing (optional)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnInitComplete ( settings, json )\n\t{\n\t\tsettings._bInitComplete = true;\n\t\n\t\t// On an Ajax load we now have data and therefore want to apply the column\n\t\t// sizing\n\t\tif ( json ) {\n\t\t\t_fnAdjustColumnSizing( settings );\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, 'aoInitComplete', 'init', [settings, json] );\n\t}\n\t\n\t\n\tfunction _fnLengthChange ( settings, val )\n\t{\n\t\tvar len = parseInt( val, 10 );\n\t\tsettings._iDisplayLength = len;\n\t\n\t\t_fnLengthOverflow( settings );\n\t\n\t\t// Fire length change event\n\t\t_fnCallbackFire( settings, null, 'length', [settings, len] );\n\t}\n\t\n\t\n\t/**\n\t * Generate the node required for user display length changing\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {node} Display length feature node\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlLength ( settings )\n\t{\n\t\tvar\n\t\t\tclasses  = settings.oClasses,\n\t\t\ttableId  = settings.sTableId,\n\t\t\tmenu     = settings.aLengthMenu,\n\t\t\td2       = $.isArray( menu[0] ),\n\t\t\tlengths  = d2 ? menu[0] : menu,\n\t\t\tlanguage = d2 ? menu[1] : menu;\n\t\n\t\tvar select = $('<select/>', {\n\t\t\t'name':          tableId+'_length',\n\t\t\t'aria-controls': tableId,\n\t\t\t'class':         classes.sLengthSelect\n\t\t} );\n\t\n\t\tfor ( var i=0, ien=lengths.length ; i<ien ; i++ ) {\n\t\t\tselect[0][ i ] = new Option( language[i], lengths[i] );\n\t\t}\n\t\n\t\tvar div = $('<div><label/></div>').addClass( classes.sLength );\n\t\tif ( ! settings.aanFeatures.l ) {\n\t\t\tdiv[0].id = tableId+'_length';\n\t\t}\n\t\n\t\tdiv.children().append(\n\t\t\tsettings.oLanguage.sLengthMenu.replace( '_MENU_', select[0].outerHTML )\n\t\t);\n\t\n\t\t// Can't use `select` variable as user might provide their own and the\n\t\t// reference is broken by the use of outerHTML\n\t\t$('select', div)\n\t\t\t.val( settings._iDisplayLength )\n\t\t\t.bind( 'change.DT', function(e) {\n\t\t\t\t_fnLengthChange( settings, $(this).val() );\n\t\t\t\t_fnDraw( settings );\n\t\t\t} );\n\t\n\t\t// Update node value whenever anything changes the table's length\n\t\t$(settings.nTable).bind( 'length.dt.DT', function (e, s, len) {\n\t\t\tif ( settings === s ) {\n\t\t\t\t$('select', div).val( len );\n\t\t\t}\n\t\t} );\n\t\n\t\treturn div[0];\n\t}\n\t\n\t\n\t\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Note that most of the paging logic is done in\n\t * DataTable.ext.pager\n\t */\n\t\n\t/**\n\t * Generate the node required for default pagination\n\t *  @param {object} oSettings dataTables settings object\n\t *  @returns {node} Pagination feature node\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlPaginate ( settings )\n\t{\n\t\tvar\n\t\t\ttype   = settings.sPaginationType,\n\t\t\tplugin = DataTable.ext.pager[ type ],\n\t\t\tmodern = typeof plugin === 'function',\n\t\t\tredraw = function( settings ) {\n\t\t\t\t_fnDraw( settings );\n\t\t\t},\n\t\t\tnode = $('<div/>').addClass( settings.oClasses.sPaging + type )[0],\n\t\t\tfeatures = settings.aanFeatures;\n\t\n\t\tif ( ! modern ) {\n\t\t\tplugin.fnInit( settings, node, redraw );\n\t\t}\n\t\n\t\t/* Add a draw callback for the pagination on first instance, to update the paging display */\n\t\tif ( ! features.p )\n\t\t{\n\t\t\tnode.id = settings.sTableId+'_paginate';\n\t\n\t\t\tsettings.aoDrawCallback.push( {\n\t\t\t\t\"fn\": function( settings ) {\n\t\t\t\t\tif ( modern ) {\n\t\t\t\t\t\tvar\n\t\t\t\t\t\t\tstart      = settings._iDisplayStart,\n\t\t\t\t\t\t\tlen        = settings._iDisplayLength,\n\t\t\t\t\t\t\tvisRecords = settings.fnRecordsDisplay(),\n\t\t\t\t\t\t\tall        = len === -1,\n\t\t\t\t\t\t\tpage = all ? 0 : Math.ceil( start / len ),\n\t\t\t\t\t\t\tpages = all ? 1 : Math.ceil( visRecords / len ),\n\t\t\t\t\t\t\tbuttons = plugin(page, pages),\n\t\t\t\t\t\t\ti, ien;\n\t\n\t\t\t\t\t\tfor ( i=0, ien=features.p.length ; i<ien ; i++ ) {\n\t\t\t\t\t\t\t_fnRenderer( settings, 'pageButton' )(\n\t\t\t\t\t\t\t\tsettings, features.p[i], i, buttons, page, pages\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tplugin.fnUpdate( settings, redraw );\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t\"sName\": \"pagination\"\n\t\t\t} );\n\t\t}\n\t\n\t\treturn node;\n\t}\n\t\n\t\n\t/**\n\t * Alter the display settings to change the page\n\t *  @param {object} settings DataTables settings object\n\t *  @param {string|int} action Paging action to take: \"first\", \"previous\",\n\t *    \"next\" or \"last\" or page number to jump to (integer)\n\t *  @param [bool] redraw Automatically draw the update or not\n\t *  @returns {bool} true page has changed, false - no change\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnPageChange ( settings, action, redraw )\n\t{\n\t\tvar\n\t\t\tstart     = settings._iDisplayStart,\n\t\t\tlen       = settings._iDisplayLength,\n\t\t\trecords   = settings.fnRecordsDisplay();\n\t\n\t\tif ( records === 0 || len === -1 )\n\t\t{\n\t\t\tstart = 0;\n\t\t}\n\t\telse if ( typeof action === \"number\" )\n\t\t{\n\t\t\tstart = action * len;\n\t\n\t\t\tif ( start > records )\n\t\t\t{\n\t\t\t\tstart = 0;\n\t\t\t}\n\t\t}\n\t\telse if ( action == \"first\" )\n\t\t{\n\t\t\tstart = 0;\n\t\t}\n\t\telse if ( action == \"previous\" )\n\t\t{\n\t\t\tstart = len >= 0 ?\n\t\t\t\tstart - len :\n\t\t\t\t0;\n\t\n\t\t\tif ( start < 0 )\n\t\t\t{\n\t\t\t  start = 0;\n\t\t\t}\n\t\t}\n\t\telse if ( action == \"next\" )\n\t\t{\n\t\t\tif ( start + len < records )\n\t\t\t{\n\t\t\t\tstart += len;\n\t\t\t}\n\t\t}\n\t\telse if ( action == \"last\" )\n\t\t{\n\t\t\tstart = Math.floor( (records-1) / len) * len;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t_fnLog( settings, 0, \"Unknown paging action: \"+action, 5 );\n\t\t}\n\t\n\t\tvar changed = settings._iDisplayStart !== start;\n\t\tsettings._iDisplayStart = start;\n\t\n\t\tif ( changed ) {\n\t\t\t_fnCallbackFire( settings, null, 'page', [settings] );\n\t\n\t\t\tif ( redraw ) {\n\t\t\t\t_fnDraw( settings );\n\t\t\t}\n\t\t}\n\t\n\t\treturn changed;\n\t}\n\t\n\t\n\t\n\t/**\n\t * Generate the node required for the processing node\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {node} Processing element\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlProcessing ( settings )\n\t{\n\t\treturn $('<div/>', {\n\t\t\t\t'id': ! settings.aanFeatures.r ? settings.sTableId+'_processing' : null,\n\t\t\t\t'class': settings.oClasses.sProcessing\n\t\t\t} )\n\t\t\t.html( settings.oLanguage.sProcessing )\n\t\t\t.insertBefore( settings.nTable )[0];\n\t}\n\t\n\t\n\t/**\n\t * Display or hide the processing indicator\n\t *  @param {object} settings dataTables settings object\n\t *  @param {bool} show Show the processing indicator (true) or not (false)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnProcessingDisplay ( settings, show )\n\t{\n\t\tif ( settings.oFeatures.bProcessing ) {\n\t\t\t$(settings.aanFeatures.r).css( 'display', show ? 'block' : 'none' );\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, null, 'processing', [settings, show] );\n\t}\n\t\n\t/**\n\t * Add any control elements for the table - specifically scrolling\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {node} Node to add to the DOM\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnFeatureHtmlTable ( settings )\n\t{\n\t\tvar table = $(settings.nTable);\n\t\n\t\t// Add the ARIA grid role to the table\n\t\ttable.attr( 'role', 'grid' );\n\t\n\t\t// Scrolling from here on in\n\t\tvar scroll = settings.oScroll;\n\t\n\t\tif ( scroll.sX === '' && scroll.sY === '' ) {\n\t\t\treturn settings.nTable;\n\t\t}\n\t\n\t\tvar scrollX = scroll.sX;\n\t\tvar scrollY = scroll.sY;\n\t\tvar classes = settings.oClasses;\n\t\tvar caption = table.children('caption');\n\t\tvar captionSide = caption.length ? caption[0]._captionSide : null;\n\t\tvar headerClone = $( table[0].cloneNode(false) );\n\t\tvar footerClone = $( table[0].cloneNode(false) );\n\t\tvar footer = table.children('tfoot');\n\t\tvar _div = '<div/>';\n\t\tvar size = function ( s ) {\n\t\t\treturn !s ? null : _fnStringToCss( s );\n\t\t};\n\t\n\t\t// This is fairly messy, but with x scrolling enabled, if the table has a\n\t\t// width attribute, regardless of any width applied using the column width\n\t\t// options, the browser will shrink or grow the table as needed to fit into\n\t\t// that 100%. That would make the width options useless. So we remove it.\n\t\t// This is okay, under the assumption that width:100% is applied to the\n\t\t// table in CSS (it is in the default stylesheet) which will set the table\n\t\t// width as appropriate (the attribute and css behave differently...)\n\t\tif ( scroll.sX && table.attr('width') === '100%' ) {\n\t\t\ttable.removeAttr('width');\n\t\t}\n\t\n\t\tif ( ! footer.length ) {\n\t\t\tfooter = null;\n\t\t}\n\t\n\t\t/*\n\t\t * The HTML structure that we want to generate in this function is:\n\t\t *  div - scroller\n\t\t *    div - scroll head\n\t\t *      div - scroll head inner\n\t\t *        table - scroll head table\n\t\t *          thead - thead\n\t\t *    div - scroll body\n\t\t *      table - table (master table)\n\t\t *        thead - thead clone for sizing\n\t\t *        tbody - tbody\n\t\t *    div - scroll foot\n\t\t *      div - scroll foot inner\n\t\t *        table - scroll foot table\n\t\t *          tfoot - tfoot\n\t\t */\n\t\tvar scroller = $( _div, { 'class': classes.sScrollWrapper } )\n\t\t\t.append(\n\t\t\t\t$(_div, { 'class': classes.sScrollHead } )\n\t\t\t\t\t.css( {\n\t\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t\tposition: 'relative',\n\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\twidth: scrollX ? size(scrollX) : '100%'\n\t\t\t\t\t} )\n\t\t\t\t\t.append(\n\t\t\t\t\t\t$(_div, { 'class': classes.sScrollHeadInner } )\n\t\t\t\t\t\t\t.css( {\n\t\t\t\t\t\t\t\t'box-sizing': 'content-box',\n\t\t\t\t\t\t\t\twidth: scroll.sXInner || '100%'\n\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\theaderClone\n\t\t\t\t\t\t\t\t\t.removeAttr('id')\n\t\t\t\t\t\t\t\t\t.css( 'margin-left', 0 )\n\t\t\t\t\t\t\t\t\t.append( captionSide === 'top' ? caption : null )\n\t\t\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\t\t\ttable.children('thead')\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t)\n\t\t\t.append(\n\t\t\t\t$(_div, { 'class': classes.sScrollBody } )\n\t\t\t\t\t.css( {\n\t\t\t\t\t\toverflow: 'auto',\n\t\t\t\t\t\theight: size( scrollY ),\n\t\t\t\t\t\twidth: size( scrollX )\n\t\t\t\t\t} )\n\t\t\t\t\t.append( table )\n\t\t\t);\n\t\n\t\tif ( footer ) {\n\t\t\tscroller.append(\n\t\t\t\t$(_div, { 'class': classes.sScrollFoot } )\n\t\t\t\t\t.css( {\n\t\t\t\t\t\toverflow: 'hidden',\n\t\t\t\t\t\tborder: 0,\n\t\t\t\t\t\twidth: scrollX ? size(scrollX) : '100%'\n\t\t\t\t\t} )\n\t\t\t\t\t.append(\n\t\t\t\t\t\t$(_div, { 'class': classes.sScrollFootInner } )\n\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\tfooterClone\n\t\t\t\t\t\t\t\t\t.removeAttr('id')\n\t\t\t\t\t\t\t\t\t.css( 'margin-left', 0 )\n\t\t\t\t\t\t\t\t\t.append( captionSide === 'bottom' ? caption : null )\n\t\t\t\t\t\t\t\t\t.append(\n\t\t\t\t\t\t\t\t\t\ttable.children('tfoot')\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t)\n\t\t\t\t\t)\n\t\t\t);\n\t\t}\n\t\n\t\tvar children = scroller.children();\n\t\tvar scrollHead = children[0];\n\t\tvar scrollBody = children[1];\n\t\tvar scrollFoot = footer ? children[2] : null;\n\t\n\t\t// When the body is scrolled, then we also want to scroll the headers\n\t\tif ( scrollX ) {\n\t\t\t$(scrollBody).on( 'scroll.DT', function (e) {\n\t\t\t\tvar scrollLeft = this.scrollLeft;\n\t\n\t\t\t\tscrollHead.scrollLeft = scrollLeft;\n\t\n\t\t\t\tif ( footer ) {\n\t\t\t\t\tscrollFoot.scrollLeft = scrollLeft;\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t\n\t\tsettings.nScrollHead = scrollHead;\n\t\tsettings.nScrollBody = scrollBody;\n\t\tsettings.nScrollFoot = scrollFoot;\n\t\n\t\t// On redraw - align columns\n\t\tsettings.aoDrawCallback.push( {\n\t\t\t\"fn\": _fnScrollDraw,\n\t\t\t\"sName\": \"scrolling\"\n\t\t} );\n\t\n\t\treturn scroller[0];\n\t}\n\t\n\t\n\t\n\t/**\n\t * Update the header, footer and body tables for resizing - i.e. column\n\t * alignment.\n\t *\n\t * Welcome to the most horrible function DataTables. The process that this\n\t * function follows is basically:\n\t *   1. Re-create the table inside the scrolling div\n\t *   2. Take live measurements from the DOM\n\t *   3. Apply the measurements to align the columns\n\t *   4. Clean up\n\t *\n\t *  @param {object} settings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnScrollDraw ( settings )\n\t{\n\t\t// Given that this is such a monster function, a lot of variables are use\n\t\t// to try and keep the minimised size as small as possible\n\t\tvar\n\t\t\tscroll         = settings.oScroll,\n\t\t\tscrollX        = scroll.sX,\n\t\t\tscrollXInner   = scroll.sXInner,\n\t\t\tscrollY        = scroll.sY,\n\t\t\tbarWidth       = scroll.iBarWidth,\n\t\t\tdivHeader      = $(settings.nScrollHead),\n\t\t\tdivHeaderStyle = divHeader[0].style,\n\t\t\tdivHeaderInner = divHeader.children('div'),\n\t\t\tdivHeaderInnerStyle = divHeaderInner[0].style,\n\t\t\tdivHeaderTable = divHeaderInner.children('table'),\n\t\t\tdivBodyEl      = settings.nScrollBody,\n\t\t\tdivBody        = $(divBodyEl),\n\t\t\tdivBodyStyle   = divBodyEl.style,\n\t\t\tdivFooter      = $(settings.nScrollFoot),\n\t\t\tdivFooterInner = divFooter.children('div'),\n\t\t\tdivFooterTable = divFooterInner.children('table'),\n\t\t\theader         = $(settings.nTHead),\n\t\t\ttable          = $(settings.nTable),\n\t\t\ttableEl        = table[0],\n\t\t\ttableStyle     = tableEl.style,\n\t\t\tfooter         = settings.nTFoot ? $(settings.nTFoot) : null,\n\t\t\tbrowser        = settings.oBrowser,\n\t\t\tie67           = browser.bScrollOversize,\n\t\t\theaderTrgEls, footerTrgEls,\n\t\t\theaderSrcEls, footerSrcEls,\n\t\t\theaderCopy, footerCopy,\n\t\t\theaderWidths=[], footerWidths=[],\n\t\t\theaderContent=[],\n\t\t\tidx, correction, sanityWidth,\n\t\t\tzeroOut = function(nSizer) {\n\t\t\t\tvar style = nSizer.style;\n\t\t\t\tstyle.paddingTop = \"0\";\n\t\t\t\tstyle.paddingBottom = \"0\";\n\t\t\t\tstyle.borderTopWidth = \"0\";\n\t\t\t\tstyle.borderBottomWidth = \"0\";\n\t\t\t\tstyle.height = 0;\n\t\t\t};\n\t\n\t\t/*\n\t\t * 1. Re-create the table inside the scrolling div\n\t\t */\n\t\n\t\t// Remove the old minimised thead and tfoot elements in the inner table\n\t\ttable.children('thead, tfoot').remove();\n\t\n\t\t// Clone the current header and footer elements and then place it into the inner table\n\t\theaderCopy = header.clone().prependTo( table );\n\t\theaderTrgEls = header.find('tr'); // original header is in its own table\n\t\theaderSrcEls = headerCopy.find('tr');\n\t\theaderCopy.find('th, td').removeAttr('tabindex');\n\t\n\t\tif ( footer ) {\n\t\t\tfooterCopy = footer.clone().prependTo( table );\n\t\t\tfooterTrgEls = footer.find('tr'); // the original tfoot is in its own table and must be sized\n\t\t\tfooterSrcEls = footerCopy.find('tr');\n\t\t}\n\t\n\t\n\t\t/*\n\t\t * 2. Take live measurements from the DOM - do not alter the DOM itself!\n\t\t */\n\t\n\t\t// Remove old sizing and apply the calculated column widths\n\t\t// Get the unique column headers in the newly created (cloned) header. We want to apply the\n\t\t// calculated sizes to this header\n\t\tif ( ! scrollX )\n\t\t{\n\t\t\tdivBodyStyle.width = '100%';\n\t\t\tdivHeader[0].style.width = '100%';\n\t\t}\n\t\n\t\t$.each( _fnGetUniqueThs( settings, headerCopy ), function ( i, el ) {\n\t\t\tidx = _fnVisibleToColumnIndex( settings, i );\n\t\t\tel.style.width = settings.aoColumns[idx].sWidth;\n\t\t} );\n\t\n\t\tif ( footer ) {\n\t\t\t_fnApplyToChildren( function(n) {\n\t\t\t\tn.style.width = \"\";\n\t\t\t}, footerSrcEls );\n\t\t}\n\t\n\t\t// If scroll collapse is enabled, when we put the headers back into the body for sizing, we\n\t\t// will end up forcing the scrollbar to appear, making our measurements wrong for when we\n\t\t// then hide it (end of this function), so add the header height to the body scroller.\n\t\tif ( scroll.bCollapse && scrollY !== \"\" ) {\n\t\t\tdivBodyStyle.height = (divBody[0].offsetHeight + header[0].offsetHeight)+\"px\";\n\t\t}\n\t\n\t\t// Size the table as a whole\n\t\tsanityWidth = table.outerWidth();\n\t\tif ( scrollX === \"\" ) {\n\t\t\t// No x scrolling\n\t\t\ttableStyle.width = \"100%\";\n\t\n\t\t\t// IE7 will make the width of the table when 100% include the scrollbar\n\t\t\t// - which is shouldn't. When there is a scrollbar we need to take this\n\t\t\t// into account.\n\t\t\tif ( ie67 && (table.find('tbody').height() > divBodyEl.offsetHeight ||\n\t\t\t\tdivBody.css('overflow-y') == \"scroll\")\n\t\t\t) {\n\t\t\t\ttableStyle.width = _fnStringToCss( table.outerWidth() - barWidth);\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// x scrolling\n\t\t\tif ( scrollXInner !== \"\" ) {\n\t\t\t\t// x scroll inner has been given - use it\n\t\t\t\ttableStyle.width = _fnStringToCss(scrollXInner);\n\t\t\t}\n\t\t\telse if ( sanityWidth == divBody.width() && divBody.height() < table.height() ) {\n\t\t\t\t// There is y-scrolling - try to take account of the y scroll bar\n\t\t\t\ttableStyle.width = _fnStringToCss( sanityWidth-barWidth );\n\t\t\t\tif ( table.outerWidth() > sanityWidth-barWidth ) {\n\t\t\t\t\t// Not possible to take account of it\n\t\t\t\t\ttableStyle.width = _fnStringToCss( sanityWidth );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// When all else fails\n\t\t\t\ttableStyle.width = _fnStringToCss( sanityWidth );\n\t\t\t}\n\t\t}\n\t\n\t\t// Recalculate the sanity width - now that we've applied the required width,\n\t\t// before it was a temporary variable. This is required because the column\n\t\t// width calculation is done before this table DOM is created.\n\t\tsanityWidth = table.outerWidth();\n\t\n\t\t// Hidden header should have zero height, so remove padding and borders. Then\n\t\t// set the width based on the real headers\n\t\n\t\t// Apply all styles in one pass\n\t\t_fnApplyToChildren( zeroOut, headerSrcEls );\n\t\n\t\t// Read all widths in next pass\n\t\t_fnApplyToChildren( function(nSizer) {\n\t\t\theaderContent.push( nSizer.innerHTML );\n\t\t\theaderWidths.push( _fnStringToCss( $(nSizer).css('width') ) );\n\t\t}, headerSrcEls );\n\t\n\t\t// Apply all widths in final pass\n\t\t_fnApplyToChildren( function(nToSize, i) {\n\t\t\tnToSize.style.width = headerWidths[i];\n\t\t}, headerTrgEls );\n\t\n\t\t$(headerSrcEls).height(0);\n\t\n\t\t/* Same again with the footer if we have one */\n\t\tif ( footer )\n\t\t{\n\t\t\t_fnApplyToChildren( zeroOut, footerSrcEls );\n\t\n\t\t\t_fnApplyToChildren( function(nSizer) {\n\t\t\t\tfooterWidths.push( _fnStringToCss( $(nSizer).css('width') ) );\n\t\t\t}, footerSrcEls );\n\t\n\t\t\t_fnApplyToChildren( function(nToSize, i) {\n\t\t\t\tnToSize.style.width = footerWidths[i];\n\t\t\t}, footerTrgEls );\n\t\n\t\t\t$(footerSrcEls).height(0);\n\t\t}\n\t\n\t\n\t\t/*\n\t\t * 3. Apply the measurements\n\t\t */\n\t\n\t\t// \"Hide\" the header and footer that we used for the sizing. We need to keep\n\t\t// the content of the cell so that the width applied to the header and body\n\t\t// both match, but we want to hide it completely. We want to also fix their\n\t\t// width to what they currently are\n\t\t_fnApplyToChildren( function(nSizer, i) {\n\t\t\tnSizer.innerHTML = '<div class=\"dataTables_sizing\" style=\"height:0;overflow:hidden;\">'+headerContent[i]+'</div>';\n\t\t\tnSizer.style.width = headerWidths[i];\n\t\t}, headerSrcEls );\n\t\n\t\tif ( footer )\n\t\t{\n\t\t\t_fnApplyToChildren( function(nSizer, i) {\n\t\t\t\tnSizer.innerHTML = \"\";\n\t\t\t\tnSizer.style.width = footerWidths[i];\n\t\t\t}, footerSrcEls );\n\t\t}\n\t\n\t\t// Sanity check that the table is of a sensible width. If not then we are going to get\n\t\t// misalignment - try to prevent this by not allowing the table to shrink below its min width\n\t\tif ( table.outerWidth() < sanityWidth )\n\t\t{\n\t\t\t// The min width depends upon if we have a vertical scrollbar visible or not */\n\t\t\tcorrection = ((divBodyEl.scrollHeight > divBodyEl.offsetHeight ||\n\t\t\t\tdivBody.css('overflow-y') == \"scroll\")) ?\n\t\t\t\t\tsanityWidth+barWidth :\n\t\t\t\t\tsanityWidth;\n\t\n\t\t\t// IE6/7 are a law unto themselves...\n\t\t\tif ( ie67 && (divBodyEl.scrollHeight >\n\t\t\t\tdivBodyEl.offsetHeight || divBody.css('overflow-y') == \"scroll\")\n\t\t\t) {\n\t\t\t\ttableStyle.width = _fnStringToCss( correction-barWidth );\n\t\t\t}\n\t\n\t\t\t// And give the user a warning that we've stopped the table getting too small\n\t\t\tif ( scrollX === \"\" || scrollXInner !== \"\" ) {\n\t\t\t\t_fnLog( settings, 1, 'Possible column misalignment', 6 );\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\tcorrection = '100%';\n\t\t}\n\t\n\t\t// Apply to the container elements\n\t\tdivBodyStyle.width = _fnStringToCss( correction );\n\t\tdivHeaderStyle.width = _fnStringToCss( correction );\n\t\n\t\tif ( footer ) {\n\t\t\tsettings.nScrollFoot.style.width = _fnStringToCss( correction );\n\t\t}\n\t\n\t\n\t\t/*\n\t\t * 4. Clean up\n\t\t */\n\t\tif ( ! scrollY ) {\n\t\t\t/* IE7< puts a vertical scrollbar in place (when it shouldn't be) due to subtracting\n\t\t\t * the scrollbar height from the visible display, rather than adding it on. We need to\n\t\t\t * set the height in order to sort this. Don't want to do it in any other browsers.\n\t\t\t */\n\t\t\tif ( ie67 ) {\n\t\t\t\tdivBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+barWidth );\n\t\t\t}\n\t\t}\n\t\n\t\tif ( scrollY && scroll.bCollapse ) {\n\t\t\tdivBodyStyle.height = _fnStringToCss( scrollY );\n\t\n\t\t\tvar iExtra = (scrollX && tableEl.offsetWidth > divBodyEl.offsetWidth) ?\n\t\t\t\tbarWidth :\n\t\t\t\t0;\n\t\n\t\t\tif ( tableEl.offsetHeight < divBodyEl.offsetHeight ) {\n\t\t\t\tdivBodyStyle.height = _fnStringToCss( tableEl.offsetHeight+iExtra );\n\t\t\t}\n\t\t}\n\t\n\t\t/* Finally set the width's of the header and footer tables */\n\t\tvar iOuterWidth = table.outerWidth();\n\t\tdivHeaderTable[0].style.width = _fnStringToCss( iOuterWidth );\n\t\tdivHeaderInnerStyle.width = _fnStringToCss( iOuterWidth );\n\t\n\t\t// Figure out if there are scrollbar present - if so then we need a the header and footer to\n\t\t// provide a bit more space to allow \"overflow\" scrolling (i.e. past the scrollbar)\n\t\tvar bScrolling = table.height() > divBodyEl.clientHeight || divBody.css('overflow-y') == \"scroll\";\n\t\tvar padding = 'padding' + (browser.bScrollbarLeft ? 'Left' : 'Right' );\n\t\tdivHeaderInnerStyle[ padding ] = bScrolling ? barWidth+\"px\" : \"0px\";\n\t\n\t\tif ( footer ) {\n\t\t\tdivFooterTable[0].style.width = _fnStringToCss( iOuterWidth );\n\t\t\tdivFooterInner[0].style.width = _fnStringToCss( iOuterWidth );\n\t\t\tdivFooterInner[0].style[padding] = bScrolling ? barWidth+\"px\" : \"0px\";\n\t\t}\n\t\n\t\t/* Adjust the position of the header in case we loose the y-scrollbar */\n\t\tdivBody.scroll();\n\t\n\t\t// If sorting or filtering has occurred, jump the scrolling back to the top\n\t\t// only if we aren't holding the position\n\t\tif ( (settings.bSorted || settings.bFiltered) && ! settings._drawHold ) {\n\t\t\tdivBodyEl.scrollTop = 0;\n\t\t}\n\t}\n\t\n\t\n\t\n\t/**\n\t * Apply a given function to the display child nodes of an element array (typically\n\t * TD children of TR rows\n\t *  @param {function} fn Method to apply to the objects\n\t *  @param array {nodes} an1 List of elements to look through for display children\n\t *  @param array {nodes} an2 Another list (identical structure to the first) - optional\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnApplyToChildren( fn, an1, an2 )\n\t{\n\t\tvar index=0, i=0, iLen=an1.length;\n\t\tvar nNode1, nNode2;\n\t\n\t\twhile ( i < iLen ) {\n\t\t\tnNode1 = an1[i].firstChild;\n\t\t\tnNode2 = an2 ? an2[i].firstChild : null;\n\t\n\t\t\twhile ( nNode1 ) {\n\t\t\t\tif ( nNode1.nodeType === 1 ) {\n\t\t\t\t\tif ( an2 ) {\n\t\t\t\t\t\tfn( nNode1, nNode2, index );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tfn( nNode1, index );\n\t\t\t\t\t}\n\t\n\t\t\t\t\tindex++;\n\t\t\t\t}\n\t\n\t\t\t\tnNode1 = nNode1.nextSibling;\n\t\t\t\tnNode2 = an2 ? nNode2.nextSibling : null;\n\t\t\t}\n\t\n\t\t\ti++;\n\t\t}\n\t}\n\t\n\t\n\t\n\tvar __re_html_remove = /<.*?>/g;\n\t\n\t\n\t/**\n\t * Calculate the width of columns for the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCalculateColumnWidths ( oSettings )\n\t{\n\t\tvar\n\t\t\ttable = oSettings.nTable,\n\t\t\tcolumns = oSettings.aoColumns,\n\t\t\tscroll = oSettings.oScroll,\n\t\t\tscrollY = scroll.sY,\n\t\t\tscrollX = scroll.sX,\n\t\t\tscrollXInner = scroll.sXInner,\n\t\t\tcolumnCount = columns.length,\n\t\t\tvisibleColumns = _fnGetColumns( oSettings, 'bVisible' ),\n\t\t\theaderCells = $('th', oSettings.nTHead),\n\t\t\ttableWidthAttr = table.getAttribute('width'), // from DOM element\n\t\t\ttableContainer = table.parentNode,\n\t\t\tuserInputs = false,\n\t\t\ti, column, columnIdx, width, outerWidth;\n\t\n\t\tvar styleWidth = table.style.width;\n\t\tif ( styleWidth && styleWidth.indexOf('%') !== -1 ) {\n\t\t\ttableWidthAttr = styleWidth;\n\t\t}\n\t\n\t\t/* Convert any user input sizes into pixel sizes */\n\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\tcolumn = columns[ visibleColumns[i] ];\n\t\n\t\t\tif ( column.sWidth !== null ) {\n\t\t\t\tcolumn.sWidth = _fnConvertToWidth( column.sWidthOrig, tableContainer );\n\t\n\t\t\t\tuserInputs = true;\n\t\t\t}\n\t\t}\n\t\n\t\t/* If the number of columns in the DOM equals the number that we have to\n\t\t * process in DataTables, then we can use the offsets that are created by\n\t\t * the web- browser. No custom sizes can be set in order for this to happen,\n\t\t * nor scrolling used\n\t\t */\n\t\tif ( ! userInputs && ! scrollX && ! scrollY &&\n\t\t    columnCount == _fnVisbleColumns( oSettings ) &&\n\t\t\tcolumnCount == headerCells.length\n\t\t) {\n\t\t\tfor ( i=0 ; i<columnCount ; i++ ) {\n\t\t\t\tcolumns[i].sWidth = _fnStringToCss( headerCells.eq(i).width() );\n\t\t\t}\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// Otherwise construct a single row, worst case, table with the widest\n\t\t\t// node in the data, assign any user defined widths, then insert it into\n\t\t\t// the DOM and allow the browser to do all the hard work of calculating\n\t\t\t// table widths\n\t\t\tvar tmpTable = $(table).clone() // don't use cloneNode - IE8 will remove events on the main table\n\t\t\t\t.css( 'visibility', 'hidden' )\n\t\t\t\t.removeAttr( 'id' );\n\t\n\t\t\t// Clean up the table body\n\t\t\ttmpTable.find('tbody tr').remove();\n\t\t\tvar tr = $('<tr/>').appendTo( tmpTable.find('tbody') );\n\t\n\t\t\t// Remove any assigned widths from the footer (from scrolling)\n\t\t\ttmpTable.find('tfoot th, tfoot td').css('width', '');\n\t\n\t\t\t// Apply custom sizing to the cloned header\n\t\t\theaderCells = _fnGetUniqueThs( oSettings, tmpTable.find('thead')[0] );\n\t\n\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\t\tcolumn = columns[ visibleColumns[i] ];\n\t\n\t\t\t\theaderCells[i].style.width = column.sWidthOrig !== null && column.sWidthOrig !== '' ?\n\t\t\t\t\t_fnStringToCss( column.sWidthOrig ) :\n\t\t\t\t\t'';\n\t\t\t}\n\t\n\t\t\t// Find the widest cell for each column and put it into the table\n\t\t\tif ( oSettings.aoData.length ) {\n\t\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\t\t\tcolumnIdx = visibleColumns[i];\n\t\t\t\t\tcolumn = columns[ columnIdx ];\n\t\n\t\t\t\t\t$( _fnGetWidestNode( oSettings, columnIdx ) )\n\t\t\t\t\t\t.clone( false )\n\t\t\t\t\t\t.append( column.sContentPadding )\n\t\t\t\t\t\t.appendTo( tr );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// Table has been built, attach to the document so we can work with it\n\t\t\ttmpTable.appendTo( tableContainer );\n\t\n\t\t\t// When scrolling (X or Y) we want to set the width of the table as \n\t\t\t// appropriate. However, when not scrolling leave the table width as it\n\t\t\t// is. This results in slightly different, but I think correct behaviour\n\t\t\tif ( scrollX && scrollXInner ) {\n\t\t\t\ttmpTable.width( scrollXInner );\n\t\t\t}\n\t\t\telse if ( scrollX ) {\n\t\t\t\ttmpTable.css( 'width', 'auto' );\n\t\n\t\t\t\tif ( tmpTable.width() < tableContainer.offsetWidth ) {\n\t\t\t\t\ttmpTable.width( tableContainer.offsetWidth );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( scrollY ) {\n\t\t\t\ttmpTable.width( tableContainer.offsetWidth );\n\t\t\t}\n\t\t\telse if ( tableWidthAttr ) {\n\t\t\t\ttmpTable.width( tableWidthAttr );\n\t\t\t}\n\t\n\t\t\t// Take into account the y scrollbar\n\t\t\t_fnScrollingWidthAdjust( oSettings, tmpTable[0] );\n\t\n\t\t\t// Browsers need a bit of a hand when a width is assigned to any columns\n\t\t\t// when x-scrolling as they tend to collapse the table to the min-width,\n\t\t\t// even if we sent the column widths. So we need to keep track of what\n\t\t\t// the table width should be by summing the user given values, and the\n\t\t\t// automatic values\n\t\t\tif ( scrollX )\n\t\t\t{\n\t\t\t\tvar total = 0;\n\t\n\t\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\t\t\tcolumn = columns[ visibleColumns[i] ];\n\t\t\t\t\touterWidth = $(headerCells[i]).outerWidth();\n\t\n\t\t\t\t\ttotal += column.sWidthOrig === null ?\n\t\t\t\t\t\touterWidth :\n\t\t\t\t\t\tparseInt( column.sWidth, 10 ) + outerWidth - $(headerCells[i]).width();\n\t\t\t\t}\n\t\n\t\t\t\ttmpTable.width( _fnStringToCss( total ) );\n\t\t\t\ttable.style.width = _fnStringToCss( total );\n\t\t\t}\n\t\n\t\t\t// Get the width of each column in the constructed table\n\t\t\tfor ( i=0 ; i<visibleColumns.length ; i++ ) {\n\t\t\t\tcolumn = columns[ visibleColumns[i] ];\n\t\t\t\twidth = $(headerCells[i]).width();\n\t\n\t\t\t\tif ( width ) {\n\t\t\t\t\tcolumn.sWidth = _fnStringToCss( width );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\ttable.style.width = _fnStringToCss( tmpTable.css('width') );\n\t\n\t\t\t// Finished with the table - ditch it\n\t\t\ttmpTable.remove();\n\t\t}\n\t\n\t\t// If there is a width attr, we want to attach an event listener which\n\t\t// allows the table sizing to automatically adjust when the window is\n\t\t// resized. Use the width attr rather than CSS, since we can't know if the\n\t\t// CSS is a relative value or absolute - DOM read is always px.\n\t\tif ( tableWidthAttr ) {\n\t\t\ttable.style.width = _fnStringToCss( tableWidthAttr );\n\t\t}\n\t\n\t\tif ( (tableWidthAttr || scrollX) && ! oSettings._reszEvt ) {\n\t\t\tvar bindResize = function () {\n\t\t\t\t$(window).bind('resize.DT-'+oSettings.sInstance, _fnThrottle( function () {\n\t\t\t\t\t_fnAdjustColumnSizing( oSettings );\n\t\t\t\t} ) );\n\t\t\t};\n\t\n\t\t\t// IE6/7 will crash if we bind a resize event handler on page load.\n\t\t\t// To be removed in 1.11 which drops IE6/7 support\n\t\t\tif ( oSettings.oBrowser.bScrollOversize ) {\n\t\t\t\tsetTimeout( bindResize, 1000 );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tbindResize();\n\t\t\t}\n\t\n\t\t\toSettings._reszEvt = true;\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Throttle the calls to a function. Arguments and context are maintained for\n\t * the throttled function\n\t *  @param {function} fn Function to be called\n\t *  @param {int} [freq=200] call frequency in mS\n\t *  @returns {function} wrapped function\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnThrottle( fn, freq ) {\n\t\tvar\n\t\t\tfrequency = freq !== undefined ? freq : 200,\n\t\t\tlast,\n\t\t\ttimer;\n\t\n\t\treturn function () {\n\t\t\tvar\n\t\t\t\tthat = this,\n\t\t\t\tnow  = +new Date(),\n\t\t\t\targs = arguments;\n\t\n\t\t\tif ( last && now < last + frequency ) {\n\t\t\t\tclearTimeout( timer );\n\t\n\t\t\t\ttimer = setTimeout( function () {\n\t\t\t\t\tlast = undefined;\n\t\t\t\t\tfn.apply( that, args );\n\t\t\t\t}, frequency );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tlast = now;\n\t\t\t\tfn.apply( that, args );\n\t\t\t}\n\t\t};\n\t}\n\t\n\t\n\t/**\n\t * Convert a CSS unit width to pixels (e.g. 2em)\n\t *  @param {string} width width to be converted\n\t *  @param {node} parent parent to get the with for (required for relative widths) - optional\n\t *  @returns {int} width in pixels\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnConvertToWidth ( width, parent )\n\t{\n\t\tif ( ! width ) {\n\t\t\treturn 0;\n\t\t}\n\t\n\t\tvar n = $('<div/>')\n\t\t\t.css( 'width', _fnStringToCss( width ) )\n\t\t\t.appendTo( parent || document.body );\n\t\n\t\tvar val = n[0].offsetWidth;\n\t\tn.remove();\n\t\n\t\treturn val;\n\t}\n\t\n\t\n\t/**\n\t * Adjust a table's width to take account of vertical scroll bar\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {node} n table node\n\t *  @memberof DataTable#oApi\n\t */\n\t\n\tfunction _fnScrollingWidthAdjust ( settings, n )\n\t{\n\t\tvar scroll = settings.oScroll;\n\t\n\t\tif ( scroll.sX || scroll.sY ) {\n\t\t\t// When y-scrolling only, we want to remove the width of the scroll bar\n\t\t\t// so the table + scroll bar will fit into the area available, otherwise\n\t\t\t// we fix the table at its current size with no adjustment\n\t\t\tvar correction = ! scroll.sX ? scroll.iBarWidth : 0;\n\t\t\tn.style.width = _fnStringToCss( $(n).outerWidth() - correction );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Get the widest node\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} colIdx column of interest\n\t *  @returns {node} widest table node\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetWidestNode( settings, colIdx )\n\t{\n\t\tvar idx = _fnGetMaxLenString( settings, colIdx );\n\t\tif ( idx < 0 ) {\n\t\t\treturn null;\n\t\t}\n\t\n\t\tvar data = settings.aoData[ idx ];\n\t\treturn ! data.nTr ? // Might not have been created when deferred rendering\n\t\t\t$('<td/>').html( _fnGetCellData( settings, idx, colIdx, 'display' ) )[0] :\n\t\t\tdata.anCells[ colIdx ];\n\t}\n\t\n\t\n\t/**\n\t * Get the maximum strlen for each data column\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} colIdx column of interest\n\t *  @returns {string} max string length for each column\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnGetMaxLenString( settings, colIdx )\n\t{\n\t\tvar s, max=-1, maxIdx = -1;\n\t\n\t\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\ts = _fnGetCellData( settings, i, colIdx, 'display' )+'';\n\t\t\ts = s.replace( __re_html_remove, '' );\n\t\n\t\t\tif ( s.length > max ) {\n\t\t\t\tmax = s.length;\n\t\t\t\tmaxIdx = i;\n\t\t\t}\n\t\t}\n\t\n\t\treturn maxIdx;\n\t}\n\t\n\t\n\t/**\n\t * Append a CSS unit (only if required) to a string\n\t *  @param {string} value to css-ify\n\t *  @returns {string} value with css unit\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnStringToCss( s )\n\t{\n\t\tif ( s === null ) {\n\t\t\treturn '0px';\n\t\t}\n\t\n\t\tif ( typeof s == 'number' ) {\n\t\t\treturn s < 0 ?\n\t\t\t\t'0px' :\n\t\t\t\ts+'px';\n\t\t}\n\t\n\t\t// Check it has a unit character already\n\t\treturn s.match(/\\d$/) ?\n\t\t\ts+'px' :\n\t\t\ts;\n\t}\n\t\n\t\n\t/**\n\t * Get the width of a scroll bar in this browser being used\n\t *  @returns {int} width in pixels\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnScrollBarWidth ()\n\t{\n\t\t// On first run a static variable is set, since this is only needed once.\n\t\t// Subsequent runs will just use the previously calculated value\n\t\tvar width = DataTable.__scrollbarWidth;\n\t\n\t\tif ( width === undefined ) {\n\t\t\tvar sizer = $('<p/>').css( {\n\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0,\n\t\t\t\t\twidth: '100%',\n\t\t\t\t\theight: 150,\n\t\t\t\t\tpadding: 0,\n\t\t\t\t\toverflow: 'scroll',\n\t\t\t\t\tvisibility: 'hidden'\n\t\t\t\t} )\n\t\t\t\t.appendTo('body');\n\t\n\t\t\twidth = sizer[0].offsetWidth - sizer[0].clientWidth;\n\t\t\tDataTable.__scrollbarWidth = width;\n\t\n\t\t\tsizer.remove();\n\t\t}\n\t\n\t\treturn width;\n\t}\n\t\n\t\n\t\n\tfunction _fnSortFlatten ( settings )\n\t{\n\t\tvar\n\t\t\ti, iLen, k, kLen,\n\t\t\taSort = [],\n\t\t\taiOrig = [],\n\t\t\taoColumns = settings.aoColumns,\n\t\t\taDataSort, iCol, sType, srcCol,\n\t\t\tfixed = settings.aaSortingFixed,\n\t\t\tfixedObj = $.isPlainObject( fixed ),\n\t\t\tnestedSort = [],\n\t\t\tadd = function ( a ) {\n\t\t\t\tif ( a.length && ! $.isArray( a[0] ) ) {\n\t\t\t\t\t// 1D array\n\t\t\t\t\tnestedSort.push( a );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// 2D array\n\t\t\t\t\tnestedSort.push.apply( nestedSort, a );\n\t\t\t\t}\n\t\t\t};\n\t\n\t\t// Build the sort array, with pre-fix and post-fix options if they have been\n\t\t// specified\n\t\tif ( $.isArray( fixed ) ) {\n\t\t\tadd( fixed );\n\t\t}\n\t\n\t\tif ( fixedObj && fixed.pre ) {\n\t\t\tadd( fixed.pre );\n\t\t}\n\t\n\t\tadd( settings.aaSorting );\n\t\n\t\tif (fixedObj && fixed.post ) {\n\t\t\tadd( fixed.post );\n\t\t}\n\t\n\t\tfor ( i=0 ; i<nestedSort.length ; i++ )\n\t\t{\n\t\t\tsrcCol = nestedSort[i][0];\n\t\t\taDataSort = aoColumns[ srcCol ].aDataSort;\n\t\n\t\t\tfor ( k=0, kLen=aDataSort.length ; k<kLen ; k++ )\n\t\t\t{\n\t\t\t\tiCol = aDataSort[k];\n\t\t\t\tsType = aoColumns[ iCol ].sType || 'string';\n\t\n\t\t\t\tif ( nestedSort[i]._idx === undefined ) {\n\t\t\t\t\tnestedSort[i]._idx = $.inArray( nestedSort[i][1], aoColumns[iCol].asSorting );\n\t\t\t\t}\n\t\n\t\t\t\taSort.push( {\n\t\t\t\t\tsrc:       srcCol,\n\t\t\t\t\tcol:       iCol,\n\t\t\t\t\tdir:       nestedSort[i][1],\n\t\t\t\t\tindex:     nestedSort[i]._idx,\n\t\t\t\t\ttype:      sType,\n\t\t\t\t\tformatter: DataTable.ext.type.order[ sType+\"-pre\" ]\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t\n\t\treturn aSort;\n\t}\n\t\n\t/**\n\t * Change the order of the table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t *  @todo This really needs split up!\n\t */\n\tfunction _fnSort ( oSettings )\n\t{\n\t\tvar\n\t\t\ti, ien, iLen, j, jLen, k, kLen,\n\t\t\tsDataType, nTh,\n\t\t\taiOrig = [],\n\t\t\toExtSort = DataTable.ext.type.order,\n\t\t\taoData = oSettings.aoData,\n\t\t\taoColumns = oSettings.aoColumns,\n\t\t\taDataSort, data, iCol, sType, oSort,\n\t\t\tformatters = 0,\n\t\t\tsortCol,\n\t\t\tdisplayMaster = oSettings.aiDisplayMaster,\n\t\t\taSort;\n\t\n\t\t// Resolve any column types that are unknown due to addition or invalidation\n\t\t// @todo Can this be moved into a 'data-ready' handler which is called when\n\t\t//   data is going to be used in the table?\n\t\t_fnColumnTypes( oSettings );\n\t\n\t\taSort = _fnSortFlatten( oSettings );\n\t\n\t\tfor ( i=0, ien=aSort.length ; i<ien ; i++ ) {\n\t\t\tsortCol = aSort[i];\n\t\n\t\t\t// Track if we can use the fast sort algorithm\n\t\t\tif ( sortCol.formatter ) {\n\t\t\t\tformatters++;\n\t\t\t}\n\t\n\t\t\t// Load the data needed for the sort, for each cell\n\t\t\t_fnSortData( oSettings, sortCol.col );\n\t\t}\n\t\n\t\t/* No sorting required if server-side or no sorting array */\n\t\tif ( _fnDataSource( oSettings ) != 'ssp' && aSort.length !== 0 )\n\t\t{\n\t\t\t// Create a value - key array of the current row positions such that we can use their\n\t\t\t// current position during the sort, if values match, in order to perform stable sorting\n\t\t\tfor ( i=0, iLen=displayMaster.length ; i<iLen ; i++ ) {\n\t\t\t\taiOrig[ displayMaster[i] ] = i;\n\t\t\t}\n\t\n\t\t\t/* Do the sort - here we want multi-column sorting based on a given data source (column)\n\t\t\t * and sorting function (from oSort) in a certain direction. It's reasonably complex to\n\t\t\t * follow on it's own, but this is what we want (example two column sorting):\n\t\t\t *  fnLocalSorting = function(a,b){\n\t\t\t *    var iTest;\n\t\t\t *    iTest = oSort['string-asc']('data11', 'data12');\n\t\t\t *      if (iTest !== 0)\n\t\t\t *        return iTest;\n\t\t\t *    iTest = oSort['numeric-desc']('data21', 'data22');\n\t\t\t *    if (iTest !== 0)\n\t\t\t *      return iTest;\n\t\t\t *    return oSort['numeric-asc']( aiOrig[a], aiOrig[b] );\n\t\t\t *  }\n\t\t\t * Basically we have a test for each sorting column, if the data in that column is equal,\n\t\t\t * test the next column. If all columns match, then we use a numeric sort on the row\n\t\t\t * positions in the original data array to provide a stable sort.\n\t\t\t *\n\t\t\t * Note - I know it seems excessive to have two sorting methods, but the first is around\n\t\t\t * 15% faster, so the second is only maintained for backwards compatibility with sorting\n\t\t\t * methods which do not have a pre-sort formatting function.\n\t\t\t */\n\t\t\tif ( formatters === aSort.length ) {\n\t\t\t\t// All sort types have formatting functions\n\t\t\t\tdisplayMaster.sort( function ( a, b ) {\n\t\t\t\t\tvar\n\t\t\t\t\t\tx, y, k, test, sort,\n\t\t\t\t\t\tlen=aSort.length,\n\t\t\t\t\t\tdataA = aoData[a]._aSortData,\n\t\t\t\t\t\tdataB = aoData[b]._aSortData;\n\t\n\t\t\t\t\tfor ( k=0 ; k<len ; k++ ) {\n\t\t\t\t\t\tsort = aSort[k];\n\t\n\t\t\t\t\t\tx = dataA[ sort.col ];\n\t\t\t\t\t\ty = dataB[ sort.col ];\n\t\n\t\t\t\t\t\ttest = x<y ? -1 : x>y ? 1 : 0;\n\t\t\t\t\t\tif ( test !== 0 ) {\n\t\t\t\t\t\t\treturn sort.dir === 'asc' ? test : -test;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\n\t\t\t\t\tx = aiOrig[a];\n\t\t\t\t\ty = aiOrig[b];\n\t\t\t\t\treturn x<y ? -1 : x>y ? 1 : 0;\n\t\t\t\t} );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Depreciated - remove in 1.11 (providing a plug-in option)\n\t\t\t\t// Not all sort types have formatting methods, so we have to call their sorting\n\t\t\t\t// methods.\n\t\t\t\tdisplayMaster.sort( function ( a, b ) {\n\t\t\t\t\tvar\n\t\t\t\t\t\tx, y, k, l, test, sort, fn,\n\t\t\t\t\t\tlen=aSort.length,\n\t\t\t\t\t\tdataA = aoData[a]._aSortData,\n\t\t\t\t\t\tdataB = aoData[b]._aSortData;\n\t\n\t\t\t\t\tfor ( k=0 ; k<len ; k++ ) {\n\t\t\t\t\t\tsort = aSort[k];\n\t\n\t\t\t\t\t\tx = dataA[ sort.col ];\n\t\t\t\t\t\ty = dataB[ sort.col ];\n\t\n\t\t\t\t\t\tfn = oExtSort[ sort.type+\"-\"+sort.dir ] || oExtSort[ \"string-\"+sort.dir ];\n\t\t\t\t\t\ttest = fn( x, y );\n\t\t\t\t\t\tif ( test !== 0 ) {\n\t\t\t\t\t\t\treturn test;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\n\t\t\t\t\tx = aiOrig[a];\n\t\t\t\t\ty = aiOrig[b];\n\t\t\t\t\treturn x<y ? -1 : x>y ? 1 : 0;\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t\n\t\t/* Tell the draw function that we have sorted the data */\n\t\toSettings.bSorted = true;\n\t}\n\t\n\t\n\tfunction _fnSortAria ( settings )\n\t{\n\t\tvar label;\n\t\tvar nextSort;\n\t\tvar columns = settings.aoColumns;\n\t\tvar aSort = _fnSortFlatten( settings );\n\t\tvar oAria = settings.oLanguage.oAria;\n\t\n\t\t// ARIA attributes - need to loop all columns, to update all (removing old\n\t\t// attributes as needed)\n\t\tfor ( var i=0, iLen=columns.length ; i<iLen ; i++ )\n\t\t{\n\t\t\tvar col = columns[i];\n\t\t\tvar asSorting = col.asSorting;\n\t\t\tvar sTitle = col.sTitle.replace( /<.*?>/g, \"\" );\n\t\t\tvar th = col.nTh;\n\t\n\t\t\t// IE7 is throwing an error when setting these properties with jQuery's\n\t\t\t// attr() and removeAttr() methods...\n\t\t\tth.removeAttribute('aria-sort');\n\t\n\t\t\t/* In ARIA only the first sorting column can be marked as sorting - no multi-sort option */\n\t\t\tif ( col.bSortable ) {\n\t\t\t\tif ( aSort.length > 0 && aSort[0].col == i ) {\n\t\t\t\t\tth.setAttribute('aria-sort', aSort[0].dir==\"asc\" ? \"ascending\" : \"descending\" );\n\t\t\t\t\tnextSort = asSorting[ aSort[0].index+1 ] || asSorting[0];\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tnextSort = asSorting[0];\n\t\t\t\t}\n\t\n\t\t\t\tlabel = sTitle + ( nextSort === \"asc\" ?\n\t\t\t\t\toAria.sSortAscending :\n\t\t\t\t\toAria.sSortDescending\n\t\t\t\t);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tlabel = sTitle;\n\t\t\t}\n\t\n\t\t\tth.setAttribute('aria-label', label);\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Function to run on user sort request\n\t *  @param {object} settings dataTables settings object\n\t *  @param {node} attachTo node to attach the handler to\n\t *  @param {int} colIdx column sorting index\n\t *  @param {boolean} [append=false] Append the requested sort to the existing\n\t *    sort if true (i.e. multi-column sort)\n\t *  @param {function} [callback] callback function\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSortListener ( settings, colIdx, append, callback )\n\t{\n\t\tvar col = settings.aoColumns[ colIdx ];\n\t\tvar sorting = settings.aaSorting;\n\t\tvar asSorting = col.asSorting;\n\t\tvar nextSortIdx;\n\t\tvar next = function ( a, overflow ) {\n\t\t\tvar idx = a._idx;\n\t\t\tif ( idx === undefined ) {\n\t\t\t\tidx = $.inArray( a[1], asSorting );\n\t\t\t}\n\t\n\t\t\treturn idx+1 < asSorting.length ?\n\t\t\t\tidx+1 :\n\t\t\t\toverflow ?\n\t\t\t\t\tnull :\n\t\t\t\t\t0;\n\t\t};\n\t\n\t\t// Convert to 2D array if needed\n\t\tif ( typeof sorting[0] === 'number' ) {\n\t\t\tsorting = settings.aaSorting = [ sorting ];\n\t\t}\n\t\n\t\t// If appending the sort then we are multi-column sorting\n\t\tif ( append && settings.oFeatures.bSortMulti ) {\n\t\t\t// Are we already doing some kind of sort on this column?\n\t\t\tvar sortIdx = $.inArray( colIdx, _pluck(sorting, '0') );\n\t\n\t\t\tif ( sortIdx !== -1 ) {\n\t\t\t\t// Yes, modify the sort\n\t\t\t\tnextSortIdx = next( sorting[sortIdx], true );\n\t\n\t\t\t\tif ( nextSortIdx === null && sorting.length === 1 ) {\n\t\t\t\t\tnextSortIdx = 0; // can't remove sorting completely\n\t\t\t\t}\n\t\n\t\t\t\tif ( nextSortIdx === null ) {\n\t\t\t\t\tsorting.splice( sortIdx, 1 );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tsorting[sortIdx][1] = asSorting[ nextSortIdx ];\n\t\t\t\t\tsorting[sortIdx]._idx = nextSortIdx;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// No sort on this column yet\n\t\t\t\tsorting.push( [ colIdx, asSorting[0], 0 ] );\n\t\t\t\tsorting[sorting.length-1]._idx = 0;\n\t\t\t}\n\t\t}\n\t\telse if ( sorting.length && sorting[0][0] == colIdx ) {\n\t\t\t// Single column - already sorting on this column, modify the sort\n\t\t\tnextSortIdx = next( sorting[0] );\n\t\n\t\t\tsorting.length = 1;\n\t\t\tsorting[0][1] = asSorting[ nextSortIdx ];\n\t\t\tsorting[0]._idx = nextSortIdx;\n\t\t}\n\t\telse {\n\t\t\t// Single column - sort only on this column\n\t\t\tsorting.length = 0;\n\t\t\tsorting.push( [ colIdx, asSorting[0] ] );\n\t\t\tsorting[0]._idx = 0;\n\t\t}\n\t\n\t\t// Run the sort by calling a full redraw\n\t\t_fnReDraw( settings );\n\t\n\t\t// callback used for async user interaction\n\t\tif ( typeof callback == 'function' ) {\n\t\t\tcallback( settings );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Attach a sort handler (click) to a node\n\t *  @param {object} settings dataTables settings object\n\t *  @param {node} attachTo node to attach the handler to\n\t *  @param {int} colIdx column sorting index\n\t *  @param {function} [callback] callback function\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSortAttachListener ( settings, attachTo, colIdx, callback )\n\t{\n\t\tvar col = settings.aoColumns[ colIdx ];\n\t\n\t\t_fnBindAction( attachTo, {}, function (e) {\n\t\t\t/* If the column is not sortable - don't to anything */\n\t\t\tif ( col.bSortable === false ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// If processing is enabled use a timeout to allow the processing\n\t\t\t// display to be shown - otherwise to it synchronously\n\t\t\tif ( settings.oFeatures.bProcessing ) {\n\t\t\t\t_fnProcessingDisplay( settings, true );\n\t\n\t\t\t\tsetTimeout( function() {\n\t\t\t\t\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\n\t\n\t\t\t\t\t// In server-side processing, the draw callback will remove the\n\t\t\t\t\t// processing display\n\t\t\t\t\tif ( _fnDataSource( settings ) !== 'ssp' ) {\n\t\t\t\t\t\t_fnProcessingDisplay( settings, false );\n\t\t\t\t\t}\n\t\t\t\t}, 0 );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t_fnSortListener( settings, colIdx, e.shiftKey, callback );\n\t\t\t}\n\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Set the sorting classes on table's body, Note: it is safe to call this function\n\t * when bSort and bSortClasses are false\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSortingClasses( settings )\n\t{\n\t\tvar oldSort = settings.aLastSort;\n\t\tvar sortClass = settings.oClasses.sSortColumn;\n\t\tvar sort = _fnSortFlatten( settings );\n\t\tvar features = settings.oFeatures;\n\t\tvar i, ien, colIdx;\n\t\n\t\tif ( features.bSort && features.bSortClasses ) {\n\t\t\t// Remove old sorting classes\n\t\t\tfor ( i=0, ien=oldSort.length ; i<ien ; i++ ) {\n\t\t\t\tcolIdx = oldSort[i].src;\n\t\n\t\t\t\t// Remove column sorting\n\t\t\t\t$( _pluck( settings.aoData, 'anCells', colIdx ) )\n\t\t\t\t\t.removeClass( sortClass + (i<2 ? i+1 : 3) );\n\t\t\t}\n\t\n\t\t\t// Add new column sorting\n\t\t\tfor ( i=0, ien=sort.length ; i<ien ; i++ ) {\n\t\t\t\tcolIdx = sort[i].src;\n\t\n\t\t\t\t$( _pluck( settings.aoData, 'anCells', colIdx ) )\n\t\t\t\t\t.addClass( sortClass + (i<2 ? i+1 : 3) );\n\t\t\t}\n\t\t}\n\t\n\t\tsettings.aLastSort = sort;\n\t}\n\t\n\t\n\t// Get the data to sort a column, be it from cache, fresh (populating the\n\t// cache), or from a sort formatter\n\tfunction _fnSortData( settings, idx )\n\t{\n\t\t// Custom sorting function - provided by the sort data type\n\t\tvar column = settings.aoColumns[ idx ];\n\t\tvar customSort = DataTable.ext.order[ column.sSortDataType ];\n\t\tvar customData;\n\t\n\t\tif ( customSort ) {\n\t\t\tcustomData = customSort.call( settings.oInstance, settings, idx,\n\t\t\t\t_fnColumnIndexToVisible( settings, idx )\n\t\t\t);\n\t\t}\n\t\n\t\t// Use / populate cache\n\t\tvar row, cellData;\n\t\tvar formatter = DataTable.ext.type.order[ column.sType+\"-pre\" ];\n\t\n\t\tfor ( var i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\trow = settings.aoData[i];\n\t\n\t\t\tif ( ! row._aSortData ) {\n\t\t\t\trow._aSortData = [];\n\t\t\t}\n\t\n\t\t\tif ( ! row._aSortData[idx] || customSort ) {\n\t\t\t\tcellData = customSort ?\n\t\t\t\t\tcustomData[i] : // If there was a custom sort function, use data from there\n\t\t\t\t\t_fnGetCellData( settings, i, idx, 'sort' );\n\t\n\t\t\t\trow._aSortData[ idx ] = formatter ?\n\t\t\t\t\tformatter( cellData ) :\n\t\t\t\t\tcellData;\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t\n\t/**\n\t * Save the state of a table\n\t *  @param {object} oSettings dataTables settings object\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSaveState ( settings )\n\t{\n\t\tif ( !settings.oFeatures.bStateSave || settings.bDestroying )\n\t\t{\n\t\t\treturn;\n\t\t}\n\t\n\t\t/* Store the interesting variables */\n\t\tvar state = {\n\t\t\ttime:    +new Date(),\n\t\t\tstart:   settings._iDisplayStart,\n\t\t\tlength:  settings._iDisplayLength,\n\t\t\torder:   $.extend( true, [], settings.aaSorting ),\n\t\t\tsearch:  _fnSearchToCamel( settings.oPreviousSearch ),\n\t\t\tcolumns: $.map( settings.aoColumns, function ( col, i ) {\n\t\t\t\treturn {\n\t\t\t\t\tvisible: col.bVisible,\n\t\t\t\t\tsearch: _fnSearchToCamel( settings.aoPreSearchCols[i] )\n\t\t\t\t};\n\t\t\t} )\n\t\t};\n\t\n\t\t_fnCallbackFire( settings, \"aoStateSaveParams\", 'stateSaveParams', [settings, state] );\n\t\n\t\tsettings.oSavedState = state;\n\t\tsettings.fnStateSaveCallback.call( settings.oInstance, settings, state );\n\t}\n\t\n\t\n\t/**\n\t * Attempt to load a saved table state\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {object} oInit DataTables init object so we can override settings\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnLoadState ( settings, oInit )\n\t{\n\t\tvar i, ien;\n\t\tvar columns = settings.aoColumns;\n\t\n\t\tif ( ! settings.oFeatures.bStateSave ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar state = settings.fnStateLoadCallback.call( settings.oInstance, settings );\n\t\tif ( ! state || ! state.time ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\t/* Allow custom and plug-in manipulation functions to alter the saved data set and\n\t\t * cancelling of loading by returning false\n\t\t */\n\t\tvar abStateLoad = _fnCallbackFire( settings, 'aoStateLoadParams', 'stateLoadParams', [settings, state] );\n\t\tif ( $.inArray( false, abStateLoad ) !== -1 ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\t/* Reject old data */\n\t\tvar duration = settings.iStateDuration;\n\t\tif ( duration > 0 && state.time < +new Date() - (duration*1000) ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\t// Number of columns have changed - all bets are off, no restore of settings\n\t\tif ( columns.length !== state.columns.length ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\t// Store the saved state so it might be accessed at any time\n\t\tsettings.oLoadedState = $.extend( true, {}, state );\n\t\n\t\t// Restore key features - todo - for 1.11 this needs to be done by\n\t\t// subscribed events\n\t\tif ( state.start !== undefined ) {\n\t\t\tsettings._iDisplayStart    = state.start;\n\t\t\tsettings.iInitDisplayStart = state.start;\n\t\t}\n\t\tif ( state.length !== undefined ) {\n\t\t\tsettings._iDisplayLength   = state.length;\n\t\t}\n\t\n\t\t// Order\n\t\tif ( state.order !== undefined ) {\n\t\t\tsettings.aaSorting = [];\n\t\t\t$.each( state.order, function ( i, col ) {\n\t\t\t\tsettings.aaSorting.push( col[0] >= columns.length ?\n\t\t\t\t\t[ 0, col[1] ] :\n\t\t\t\t\tcol\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\t\n\t\t// Search\n\t\tif ( state.search !== undefined ) {\n\t\t\t$.extend( settings.oPreviousSearch, _fnSearchToHung( state.search ) );\n\t\t}\n\t\n\t\t// Columns\n\t\tfor ( i=0, ien=state.columns.length ; i<ien ; i++ ) {\n\t\t\tvar col = state.columns[i];\n\t\n\t\t\t// Visibility\n\t\t\tif ( col.visible !== undefined ) {\n\t\t\t\tcolumns[i].bVisible = col.visible;\n\t\t\t}\n\t\n\t\t\t// Search\n\t\t\tif ( col.search !== undefined ) {\n\t\t\t\t$.extend( settings.aoPreSearchCols[i], _fnSearchToHung( col.search ) );\n\t\t\t}\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, 'aoStateLoaded', 'stateLoaded', [settings, state] );\n\t}\n\t\n\t\n\t/**\n\t * Return the settings object for a particular table\n\t *  @param {node} table table we are using as a dataTable\n\t *  @returns {object} Settings object - or null if not found\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnSettingsFromNode ( table )\n\t{\n\t\tvar settings = DataTable.settings;\n\t\tvar idx = $.inArray( table, _pluck( settings, 'nTable' ) );\n\t\n\t\treturn idx !== -1 ?\n\t\t\tsettings[ idx ] :\n\t\t\tnull;\n\t}\n\t\n\t\n\t/**\n\t * Log an error message\n\t *  @param {object} settings dataTables settings object\n\t *  @param {int} level log error messages, or display them to the user\n\t *  @param {string} msg error message\n\t *  @param {int} tn Technical note id to get more information about the error.\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnLog( settings, level, msg, tn )\n\t{\n\t\tmsg = 'DataTables warning: '+\n\t\t\t(settings!==null ? 'table id='+settings.sTableId+' - ' : '')+msg;\n\t\n\t\tif ( tn ) {\n\t\t\tmsg += '. For more information about this error, please see '+\n\t\t\t'http://datatables.net/tn/'+tn;\n\t\t}\n\t\n\t\tif ( ! level  ) {\n\t\t\t// Backwards compatibility pre 1.10\n\t\t\tvar ext = DataTable.ext;\n\t\t\tvar type = ext.sErrMode || ext.errMode;\n\t\n\t\t\t_fnCallbackFire( settings, null, 'error', [ settings, tn, msg ] );\n\t\n\t\t\tif ( type == 'alert' ) {\n\t\t\t\talert( msg );\n\t\t\t}\n\t\t\telse if ( type == 'throw' ) {\n\t\t\t\tthrow new Error(msg);\n\t\t\t}\n\t\t\telse if ( typeof type == 'function' ) {\n\t\t\t\ttype( settings, tn, msg );\n\t\t\t}\n\t\t}\n\t\telse if ( window.console && console.log ) {\n\t\t\tconsole.log( msg );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * See if a property is defined on one object, if so assign it to the other object\n\t *  @param {object} ret target object\n\t *  @param {object} src source object\n\t *  @param {string} name property\n\t *  @param {string} [mappedName] name to map too - optional, name used if not given\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnMap( ret, src, name, mappedName )\n\t{\n\t\tif ( $.isArray( name ) ) {\n\t\t\t$.each( name, function (i, val) {\n\t\t\t\tif ( $.isArray( val ) ) {\n\t\t\t\t\t_fnMap( ret, src, val[0], val[1] );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t_fnMap( ret, src, val );\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\treturn;\n\t\t}\n\t\n\t\tif ( mappedName === undefined ) {\n\t\t\tmappedName = name;\n\t\t}\n\t\n\t\tif ( src[name] !== undefined ) {\n\t\t\tret[mappedName] = src[name];\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Extend objects - very similar to jQuery.extend, but deep copy objects, and\n\t * shallow copy arrays. The reason we need to do this, is that we don't want to\n\t * deep copy array init values (such as aaSorting) since the dev wouldn't be\n\t * able to override them, but we do want to deep copy arrays.\n\t *  @param {object} out Object to extend\n\t *  @param {object} extender Object from which the properties will be applied to\n\t *      out\n\t *  @param {boolean} breakRefs If true, then arrays will be sliced to take an\n\t *      independent copy with the exception of the `data` or `aaData` parameters\n\t *      if they are present. This is so you can pass in a collection to\n\t *      DataTables and have that used as your data source without breaking the\n\t *      references\n\t *  @returns {object} out Reference, just for convenience - out === the return.\n\t *  @memberof DataTable#oApi\n\t *  @todo This doesn't take account of arrays inside the deep copied objects.\n\t */\n\tfunction _fnExtend( out, extender, breakRefs )\n\t{\n\t\tvar val;\n\t\n\t\tfor ( var prop in extender ) {\n\t\t\tif ( extender.hasOwnProperty(prop) ) {\n\t\t\t\tval = extender[prop];\n\t\n\t\t\t\tif ( $.isPlainObject( val ) ) {\n\t\t\t\t\tif ( ! $.isPlainObject( out[prop] ) ) {\n\t\t\t\t\t\tout[prop] = {};\n\t\t\t\t\t}\n\t\t\t\t\t$.extend( true, out[prop], val );\n\t\t\t\t}\n\t\t\t\telse if ( breakRefs && prop !== 'data' && prop !== 'aaData' && $.isArray(val) ) {\n\t\t\t\t\tout[prop] = val.slice();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tout[prop] = val;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn out;\n\t}\n\t\n\t\n\t/**\n\t * Bind an event handers to allow a click or return key to activate the callback.\n\t * This is good for accessibility since a return on the keyboard will have the\n\t * same effect as a click, if the element has focus.\n\t *  @param {element} n Element to bind the action to\n\t *  @param {object} oData Data object to pass to the triggered function\n\t *  @param {function} fn Callback function for when the event is triggered\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnBindAction( n, oData, fn )\n\t{\n\t\t$(n)\n\t\t\t.bind( 'click.DT', oData, function (e) {\n\t\t\t\t\tn.blur(); // Remove focus outline for mouse users\n\t\t\t\t\tfn(e);\n\t\t\t\t} )\n\t\t\t.bind( 'keypress.DT', oData, function (e){\n\t\t\t\t\tif ( e.which === 13 ) {\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tfn(e);\n\t\t\t\t\t}\n\t\t\t\t} )\n\t\t\t.bind( 'selectstart.DT', function () {\n\t\t\t\t\t/* Take the brutal approach to cancelling text selection */\n\t\t\t\t\treturn false;\n\t\t\t\t} );\n\t}\n\t\n\t\n\t/**\n\t * Register a callback function. Easily allows a callback function to be added to\n\t * an array store of callback functions that can then all be called together.\n\t *  @param {object} oSettings dataTables settings object\n\t *  @param {string} sStore Name of the array storage for the callbacks in oSettings\n\t *  @param {function} fn Function to be called back\n\t *  @param {string} sName Identifying name for the callback (i.e. a label)\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCallbackReg( oSettings, sStore, fn, sName )\n\t{\n\t\tif ( fn )\n\t\t{\n\t\t\toSettings[sStore].push( {\n\t\t\t\t\"fn\": fn,\n\t\t\t\t\"sName\": sName\n\t\t\t} );\n\t\t}\n\t}\n\t\n\t\n\t/**\n\t * Fire callback functions and trigger events. Note that the loop over the\n\t * callback array store is done backwards! Further note that you do not want to\n\t * fire off triggers in time sensitive applications (for example cell creation)\n\t * as its slow.\n\t *  @param {object} settings dataTables settings object\n\t *  @param {string} callbackArr Name of the array storage for the callbacks in\n\t *      oSettings\n\t *  @param {string} eventName Name of the jQuery custom event to trigger. If\n\t *      null no trigger is fired\n\t *  @param {array} args Array of arguments to pass to the callback function /\n\t *      trigger\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnCallbackFire( settings, callbackArr, eventName, args )\n\t{\n\t\tvar ret = [];\n\t\n\t\tif ( callbackArr ) {\n\t\t\tret = $.map( settings[callbackArr].slice().reverse(), function (val, i) {\n\t\t\t\treturn val.fn.apply( settings.oInstance, args );\n\t\t\t} );\n\t\t}\n\t\n\t\tif ( eventName !== null ) {\n\t\t\tvar e = $.Event( eventName+'.dt' );\n\t\n\t\t\t$(settings.nTable).trigger( e, args );\n\t\n\t\t\tret.push( e.result );\n\t\t}\n\t\n\t\treturn ret;\n\t}\n\t\n\t\n\tfunction _fnLengthOverflow ( settings )\n\t{\n\t\tvar\n\t\t\tstart = settings._iDisplayStart,\n\t\t\tend = settings.fnDisplayEnd(),\n\t\t\tlen = settings._iDisplayLength;\n\t\n\t\t/* If we have space to show extra rows (backing up from the end point - then do so */\n\t\tif ( start >= end )\n\t\t{\n\t\t\tstart = end - len;\n\t\t}\n\t\n\t\t// Keep the start record on the current page\n\t\tstart -= (start % len);\n\t\n\t\tif ( len === -1 || start < 0 )\n\t\t{\n\t\t\tstart = 0;\n\t\t}\n\t\n\t\tsettings._iDisplayStart = start;\n\t}\n\t\n\t\n\tfunction _fnRenderer( settings, type )\n\t{\n\t\tvar renderer = settings.renderer;\n\t\tvar host = DataTable.ext.renderer[type];\n\t\n\t\tif ( $.isPlainObject( renderer ) && renderer[type] ) {\n\t\t\t// Specific renderer for this type. If available use it, otherwise use\n\t\t\t// the default.\n\t\t\treturn host[renderer[type]] || host._;\n\t\t}\n\t\telse if ( typeof renderer === 'string' ) {\n\t\t\t// Common renderer - if there is one available for this type use it,\n\t\t\t// otherwise use the default\n\t\t\treturn host[renderer] || host._;\n\t\t}\n\t\n\t\t// Use the default\n\t\treturn host._;\n\t}\n\t\n\t\n\t/**\n\t * Detect the data source being used for the table. Used to simplify the code\n\t * a little (ajax) and to make it compress a little smaller.\n\t *\n\t *  @param {object} settings dataTables settings object\n\t *  @returns {string} Data source\n\t *  @memberof DataTable#oApi\n\t */\n\tfunction _fnDataSource ( settings )\n\t{\n\t\tif ( settings.oFeatures.bServerSide ) {\n\t\t\treturn 'ssp';\n\t\t}\n\t\telse if ( settings.ajax || settings.sAjaxSource ) {\n\t\t\treturn 'ajax';\n\t\t}\n\t\treturn 'dom';\n\t}\n\t\n\n\tDataTable = function( options )\n\t{\n\t\t/**\n\t\t * Perform a jQuery selector action on the table's TR elements (from the tbody) and\n\t\t * return the resulting jQuery object.\n\t\t *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on\n\t\t *  @param {object} [oOpts] Optional parameters for modifying the rows to be included\n\t\t *  @param {string} [oOpts.filter=none] Select TR elements that meet the current filter\n\t\t *    criterion (\"applied\") or all TR elements (i.e. no filter).\n\t\t *  @param {string} [oOpts.order=current] Order of the TR elements in the processed array.\n\t\t *    Can be either 'current', whereby the current sorting of the table is used, or\n\t\t *    'original' whereby the original order the data was read into the table is used.\n\t\t *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page\n\t\t *    (\"current\") or not (\"all\"). If 'current' is given, then order is assumed to be\n\t\t *    'current' and filter is 'applied', regardless of what they might be given as.\n\t\t *  @returns {object} jQuery object, filtered by the given selector.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Highlight every second row\n\t\t *      oTable.$('tr:odd').css('backgroundColor', 'blue');\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Filter to rows with 'Webkit' in them, add a background colour and then\n\t\t *      // remove the filter, thus highlighting the 'Webkit' rows only.\n\t\t *      oTable.fnFilter('Webkit');\n\t\t *      oTable.$('tr', {\"search\": \"applied\"}).css('backgroundColor', 'blue');\n\t\t *      oTable.fnFilter('');\n\t\t *    } );\n\t\t */\n\t\tthis.$ = function ( sSelector, oOpts )\n\t\t{\n\t\t\treturn this.api(true).$( sSelector, oOpts );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Almost identical to $ in operation, but in this case returns the data for the matched\n\t\t * rows - as such, the jQuery selector used should match TR row nodes or TD/TH cell nodes\n\t\t * rather than any descendants, so the data can be obtained for the row/cell. If matching\n\t\t * rows are found, the data returned is the original data array/object that was used to\n\t\t * create the row (or a generated array if from a DOM source).\n\t\t *\n\t\t * This method is often useful in-combination with $ where both functions are given the\n\t\t * same parameters and the array indexes will match identically.\n\t\t *  @param {string|node|jQuery} sSelector jQuery selector or node collection to act on\n\t\t *  @param {object} [oOpts] Optional parameters for modifying the rows to be included\n\t\t *  @param {string} [oOpts.filter=none] Select elements that meet the current filter\n\t\t *    criterion (\"applied\") or all elements (i.e. no filter).\n\t\t *  @param {string} [oOpts.order=current] Order of the data in the processed array.\n\t\t *    Can be either 'current', whereby the current sorting of the table is used, or\n\t\t *    'original' whereby the original order the data was read into the table is used.\n\t\t *  @param {string} [oOpts.page=all] Limit the selection to the currently displayed page\n\t\t *    (\"current\") or not (\"all\"). If 'current' is given, then order is assumed to be\n\t\t *    'current' and filter is 'applied', regardless of what they might be given as.\n\t\t *  @returns {array} Data for the matched elements. If any elements, as a result of the\n\t\t *    selector, were not TR, TD or TH elements in the DataTable, they will have a null\n\t\t *    entry in the array.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Get the data from the first row in the table\n\t\t *      var data = oTable._('tr:first');\n\t\t *\n\t\t *      // Do something useful with the data\n\t\t *      alert( \"First cell is: \"+data[0] );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Filter to 'Webkit' and get all data for\n\t\t *      oTable.fnFilter('Webkit');\n\t\t *      var data = oTable._('tr', {\"search\": \"applied\"});\n\t\t *\n\t\t *      // Do something with the data\n\t\t *      alert( data.length+\" rows matched the search\" );\n\t\t *    } );\n\t\t */\n\t\tthis._ = function ( sSelector, oOpts )\n\t\t{\n\t\t\treturn this.api(true).rows( sSelector, oOpts ).data();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Create a DataTables Api instance, with the currently selected tables for\n\t\t * the Api's context.\n\t\t * @param {boolean} [traditional=false] Set the API instance's context to be\n\t\t *   only the table referred to by the `DataTable.ext.iApiIndex` option, as was\n\t\t *   used in the API presented by DataTables 1.9- (i.e. the traditional mode),\n\t\t *   or if all tables captured in the jQuery object should be used.\n\t\t * @return {DataTables.Api}\n\t\t */\n\t\tthis.api = function ( traditional )\n\t\t{\n\t\t\treturn traditional ?\n\t\t\t\tnew _Api(\n\t\t\t\t\t_fnSettingsFromNode( this[ _ext.iApiIndex ] )\n\t\t\t\t) :\n\t\t\t\tnew _Api( this );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Add a single new row or multiple rows of data to the table. Please note\n\t\t * that this is suitable for client-side processing only - if you are using\n\t\t * server-side processing (i.e. \"bServerSide\": true), then to add data, you\n\t\t * must add it to the data source, i.e. the server-side, through an Ajax call.\n\t\t *  @param {array|object} data The data to be added to the table. This can be:\n\t\t *    <ul>\n\t\t *      <li>1D array of data - add a single row with the data provided</li>\n\t\t *      <li>2D array of arrays - add multiple rows in a single call</li>\n\t\t *      <li>object - data object when using <i>mData</i></li>\n\t\t *      <li>array of objects - multiple data objects when using <i>mData</i></li>\n\t\t *    </ul>\n\t\t *  @param {bool} [redraw=true] redraw the table or not\n\t\t *  @returns {array} An array of integers, representing the list of indexes in\n\t\t *    <i>aoData</i> ({@link DataTable.models.oSettings}) that have been added to\n\t\t *    the table.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    // Global var for counter\n\t\t *    var giCount = 2;\n\t\t *\n\t\t *    $(document).ready(function() {\n\t\t *      $('#example').dataTable();\n\t\t *    } );\n\t\t *\n\t\t *    function fnClickAddRow() {\n\t\t *      $('#example').dataTable().fnAddData( [\n\t\t *        giCount+\".1\",\n\t\t *        giCount+\".2\",\n\t\t *        giCount+\".3\",\n\t\t *        giCount+\".4\" ]\n\t\t *      );\n\t\t *\n\t\t *      giCount++;\n\t\t *    }\n\t\t */\n\t\tthis.fnAddData = function( data, redraw )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\t/* Check if we want to add multiple rows or not */\n\t\t\tvar rows = $.isArray(data) && ( $.isArray(data[0]) || $.isPlainObject(data[0]) ) ?\n\t\t\t\tapi.rows.add( data ) :\n\t\t\t\tapi.row.add( data );\n\t\t\n\t\t\tif ( redraw === undefined || redraw ) {\n\t\t\t\tapi.draw();\n\t\t\t}\n\t\t\n\t\t\treturn rows.flatten().toArray();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * This function will make DataTables recalculate the column sizes, based on the data\n\t\t * contained in the table and the sizes applied to the columns (in the DOM, CSS or\n\t\t * through the sWidth parameter). This can be useful when the width of the table's\n\t\t * parent element changes (for example a window resize).\n\t\t *  @param {boolean} [bRedraw=true] Redraw the table or not, you will typically want to\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable( {\n\t\t *        \"sScrollY\": \"200px\",\n\t\t *        \"bPaginate\": false\n\t\t *      } );\n\t\t *\n\t\t *      $(window).bind('resize', function () {\n\t\t *        oTable.fnAdjustColumnSizing();\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\tthis.fnAdjustColumnSizing = function ( bRedraw )\n\t\t{\n\t\t\tvar api = this.api( true ).columns.adjust();\n\t\t\tvar settings = api.settings()[0];\n\t\t\tvar scroll = settings.oScroll;\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.draw( false );\n\t\t\t}\n\t\t\telse if ( scroll.sX !== \"\" || scroll.sY !== \"\" ) {\n\t\t\t\t/* If not redrawing, but scrolling, we want to apply the new column sizes anyway */\n\t\t\t\t_fnScrollDraw( settings );\n\t\t\t}\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Quickly and simply clear a table\n\t\t *  @param {bool} [bRedraw=true] redraw the table or not\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Immediately 'nuke' the current rows (perhaps waiting for an Ajax callback...)\n\t\t *      oTable.fnClearTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnClearTable = function( bRedraw )\n\t\t{\n\t\t\tvar api = this.api( true ).clear();\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.draw();\n\t\t\t}\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * The exact opposite of 'opening' a row, this function will close any rows which\n\t\t * are currently 'open'.\n\t\t *  @param {node} nTr the table row to 'close'\n\t\t *  @returns {int} 0 on success, or 1 if failed (can't find the row)\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable;\n\t\t *\n\t\t *      // 'open' an information row when a row is clicked on\n\t\t *      $('#example tbody tr').click( function () {\n\t\t *        if ( oTable.fnIsOpen(this) ) {\n\t\t *          oTable.fnClose( this );\n\t\t *        } else {\n\t\t *          oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n\t\t *        }\n\t\t *      } );\n\t\t *\n\t\t *      oTable = $('#example').dataTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnClose = function( nTr )\n\t\t{\n\t\t\tthis.api( true ).row( nTr ).child.hide();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Remove a row for the table\n\t\t *  @param {mixed} target The index of the row from aoData to be deleted, or\n\t\t *    the TR element you want to delete\n\t\t *  @param {function|null} [callBack] Callback function\n\t\t *  @param {bool} [redraw=true] Redraw the table or not\n\t\t *  @returns {array} The row that was deleted\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Immediately remove the first row\n\t\t *      oTable.fnDeleteRow( 0 );\n\t\t *    } );\n\t\t */\n\t\tthis.fnDeleteRow = function( target, callback, redraw )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\tvar rows = api.rows( target );\n\t\t\tvar settings = rows.settings()[0];\n\t\t\tvar data = settings.aoData[ rows[0][0] ];\n\t\t\n\t\t\trows.remove();\n\t\t\n\t\t\tif ( callback ) {\n\t\t\t\tcallback.call( this, settings, data );\n\t\t\t}\n\t\t\n\t\t\tif ( redraw === undefined || redraw ) {\n\t\t\t\tapi.draw();\n\t\t\t}\n\t\t\n\t\t\treturn data;\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Restore the table to it's original state in the DOM by removing all of DataTables\n\t\t * enhancements, alterations to the DOM structure of the table and event listeners.\n\t\t *  @param {boolean} [remove=false] Completely remove the table from the DOM\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      // This example is fairly pointless in reality, but shows how fnDestroy can be used\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      oTable.fnDestroy();\n\t\t *    } );\n\t\t */\n\t\tthis.fnDestroy = function ( remove )\n\t\t{\n\t\t\tthis.api( true ).destroy( remove );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Redraw the table\n\t\t *  @param {bool} [complete=true] Re-filter and resort (if enabled) the table before the draw.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Re-draw the table - you wouldn't want to do it here, but it's an example :-)\n\t\t *      oTable.fnDraw();\n\t\t *    } );\n\t\t */\n\t\tthis.fnDraw = function( complete )\n\t\t{\n\t\t\t// Note that this isn't an exact match to the old call to _fnDraw - it takes\n\t\t\t// into account the new data, but can hold position.\n\t\t\tthis.api( true ).draw( complete );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Filter the input based on data\n\t\t *  @param {string} sInput String to filter the table on\n\t\t *  @param {int|null} [iColumn] Column to limit filtering to\n\t\t *  @param {bool} [bRegex=false] Treat as regular expression or not\n\t\t *  @param {bool} [bSmart=true] Perform smart filtering or not\n\t\t *  @param {bool} [bShowGlobal=true] Show the input global filter in it's input box(es)\n\t\t *  @param {bool} [bCaseInsensitive=true] Do case-insensitive matching (true) or not (false)\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Sometime later - filter...\n\t\t *      oTable.fnFilter( 'test string' );\n\t\t *    } );\n\t\t */\n\t\tthis.fnFilter = function( sInput, iColumn, bRegex, bSmart, bShowGlobal, bCaseInsensitive )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\tif ( iColumn === null || iColumn === undefined ) {\n\t\t\t\tapi.search( sInput, bRegex, bSmart, bCaseInsensitive );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tapi.column( iColumn ).search( sInput, bRegex, bSmart, bCaseInsensitive );\n\t\t\t}\n\t\t\n\t\t\tapi.draw();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Get the data for the whole table, an individual row or an individual cell based on the\n\t\t * provided parameters.\n\t\t *  @param {int|node} [src] A TR row node, TD/TH cell node or an integer. If given as\n\t\t *    a TR node then the data source for the whole row will be returned. If given as a\n\t\t *    TD/TH cell node then iCol will be automatically calculated and the data for the\n\t\t *    cell returned. If given as an integer, then this is treated as the aoData internal\n\t\t *    data index for the row (see fnGetPosition) and the data for that row used.\n\t\t *  @param {int} [col] Optional column index that you want the data of.\n\t\t *  @returns {array|object|string} If mRow is undefined, then the data for all rows is\n\t\t *    returned. If mRow is defined, just data for that row, and is iCol is\n\t\t *    defined, only data for the designated cell is returned.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    // Row data\n\t\t *    $(document).ready(function() {\n\t\t *      oTable = $('#example').dataTable();\n\t\t *\n\t\t *      oTable.$('tr').click( function () {\n\t\t *        var data = oTable.fnGetData( this );\n\t\t *        // ... do something with the array / object of data for the row\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Individual cell data\n\t\t *    $(document).ready(function() {\n\t\t *      oTable = $('#example').dataTable();\n\t\t *\n\t\t *      oTable.$('td').click( function () {\n\t\t *        var sData = oTable.fnGetData( this );\n\t\t *        alert( 'The cell clicked on had the value of '+sData );\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\tthis.fnGetData = function( src, col )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\tif ( src !== undefined ) {\n\t\t\t\tvar type = src.nodeName ? src.nodeName.toLowerCase() : '';\n\t\t\n\t\t\t\treturn col !== undefined || type == 'td' || type == 'th' ?\n\t\t\t\t\tapi.cell( src, col ).data() :\n\t\t\t\t\tapi.row( src ).data() || null;\n\t\t\t}\n\t\t\n\t\t\treturn api.data().toArray();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Get an array of the TR nodes that are used in the table's body. Note that you will\n\t\t * typically want to use the '$' API method in preference to this as it is more\n\t\t * flexible.\n\t\t *  @param {int} [iRow] Optional row index for the TR element you want\n\t\t *  @returns {array|node} If iRow is undefined, returns an array of all TR elements\n\t\t *    in the table's body, or iRow is defined, just the TR element requested.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Get the nodes from the table\n\t\t *      var nNodes = oTable.fnGetNodes( );\n\t\t *    } );\n\t\t */\n\t\tthis.fnGetNodes = function( iRow )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\treturn iRow !== undefined ?\n\t\t\t\tapi.row( iRow ).node() :\n\t\t\t\tapi.rows().nodes().flatten().toArray();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Get the array indexes of a particular cell from it's DOM element\n\t\t * and column index including hidden columns\n\t\t *  @param {node} node this can either be a TR, TD or TH in the table's body\n\t\t *  @returns {int} If nNode is given as a TR, then a single index is returned, or\n\t\t *    if given as a cell, an array of [row index, column index (visible),\n\t\t *    column index (all)] is given.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      $('#example tbody td').click( function () {\n\t\t *        // Get the position of the current data from the node\n\t\t *        var aPos = oTable.fnGetPosition( this );\n\t\t *\n\t\t *        // Get the data array for this row\n\t\t *        var aData = oTable.fnGetData( aPos[0] );\n\t\t *\n\t\t *        // Update the data array and return the value\n\t\t *        aData[ aPos[1] ] = 'clicked';\n\t\t *        this.innerHTML = 'clicked';\n\t\t *      } );\n\t\t *\n\t\t *      // Init DataTables\n\t\t *      oTable = $('#example').dataTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnGetPosition = function( node )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\tvar nodeName = node.nodeName.toUpperCase();\n\t\t\n\t\t\tif ( nodeName == 'TR' ) {\n\t\t\t\treturn api.row( node ).index();\n\t\t\t}\n\t\t\telse if ( nodeName == 'TD' || nodeName == 'TH' ) {\n\t\t\t\tvar cell = api.cell( node ).index();\n\t\t\n\t\t\t\treturn [\n\t\t\t\t\tcell.row,\n\t\t\t\t\tcell.columnVisible,\n\t\t\t\t\tcell.column\n\t\t\t\t];\n\t\t\t}\n\t\t\treturn null;\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Check to see if a row is 'open' or not.\n\t\t *  @param {node} nTr the table row to check\n\t\t *  @returns {boolean} true if the row is currently open, false otherwise\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable;\n\t\t *\n\t\t *      // 'open' an information row when a row is clicked on\n\t\t *      $('#example tbody tr').click( function () {\n\t\t *        if ( oTable.fnIsOpen(this) ) {\n\t\t *          oTable.fnClose( this );\n\t\t *        } else {\n\t\t *          oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n\t\t *        }\n\t\t *      } );\n\t\t *\n\t\t *      oTable = $('#example').dataTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnIsOpen = function( nTr )\n\t\t{\n\t\t\treturn this.api( true ).row( nTr ).child.isShown();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * This function will place a new row directly after a row which is currently\n\t\t * on display on the page, with the HTML contents that is passed into the\n\t\t * function. This can be used, for example, to ask for confirmation that a\n\t\t * particular record should be deleted.\n\t\t *  @param {node} nTr The table row to 'open'\n\t\t *  @param {string|node|jQuery} mHtml The HTML to put into the row\n\t\t *  @param {string} sClass Class to give the new TD cell\n\t\t *  @returns {node} The row opened. Note that if the table row passed in as the\n\t\t *    first parameter, is not found in the table, this method will silently\n\t\t *    return.\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable;\n\t\t *\n\t\t *      // 'open' an information row when a row is clicked on\n\t\t *      $('#example tbody tr').click( function () {\n\t\t *        if ( oTable.fnIsOpen(this) ) {\n\t\t *          oTable.fnClose( this );\n\t\t *        } else {\n\t\t *          oTable.fnOpen( this, \"Temporary row opened\", \"info_row\" );\n\t\t *        }\n\t\t *      } );\n\t\t *\n\t\t *      oTable = $('#example').dataTable();\n\t\t *    } );\n\t\t */\n\t\tthis.fnOpen = function( nTr, mHtml, sClass )\n\t\t{\n\t\t\treturn this.api( true )\n\t\t\t\t.row( nTr )\n\t\t\t\t.child( mHtml, sClass )\n\t\t\t\t.show()\n\t\t\t\t.child()[0];\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Change the pagination - provides the internal logic for pagination in a simple API\n\t\t * function. With this function you can have a DataTables table go to the next,\n\t\t * previous, first or last pages.\n\t\t *  @param {string|int} mAction Paging action to take: \"first\", \"previous\", \"next\" or \"last\"\n\t\t *    or page number to jump to (integer), note that page 0 is the first page.\n\t\t *  @param {bool} [bRedraw=true] Redraw the table or not\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      oTable.fnPageChange( 'next' );\n\t\t *    } );\n\t\t */\n\t\tthis.fnPageChange = function ( mAction, bRedraw )\n\t\t{\n\t\t\tvar api = this.api( true ).page( mAction );\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.draw(false);\n\t\t\t}\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Show a particular column\n\t\t *  @param {int} iCol The column whose display should be changed\n\t\t *  @param {bool} bShow Show (true) or hide (false) the column\n\t\t *  @param {bool} [bRedraw=true] Redraw the table or not\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Hide the second column after initialisation\n\t\t *      oTable.fnSetColumnVis( 1, false );\n\t\t *    } );\n\t\t */\n\t\tthis.fnSetColumnVis = function ( iCol, bShow, bRedraw )\n\t\t{\n\t\t\tvar api = this.api( true ).column( iCol ).visible( bShow );\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.columns.adjust().draw();\n\t\t\t}\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Get the settings for a particular table for external manipulation\n\t\t *  @returns {object} DataTables settings object. See\n\t\t *    {@link DataTable.models.oSettings}\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      var oSettings = oTable.fnSettings();\n\t\t *\n\t\t *      // Show an example parameter from the settings\n\t\t *      alert( oSettings._iDisplayStart );\n\t\t *    } );\n\t\t */\n\t\tthis.fnSettings = function()\n\t\t{\n\t\t\treturn _fnSettingsFromNode( this[_ext.iApiIndex] );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Sort the table by a particular column\n\t\t *  @param {int} iCol the data index to sort on. Note that this will not match the\n\t\t *    'display index' if you have hidden data entries\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Sort immediately with columns 0 and 1\n\t\t *      oTable.fnSort( [ [0,'asc'], [1,'asc'] ] );\n\t\t *    } );\n\t\t */\n\t\tthis.fnSort = function( aaSort )\n\t\t{\n\t\t\tthis.api( true ).order( aaSort ).draw();\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Attach a sort listener to an element for a given column\n\t\t *  @param {node} nNode the element to attach the sort listener to\n\t\t *  @param {int} iColumn the column that a click on this node will sort on\n\t\t *  @param {function} [fnCallback] callback function when sort is run\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *\n\t\t *      // Sort on column 1, when 'sorter' is clicked on\n\t\t *      oTable.fnSortListener( document.getElementById('sorter'), 1 );\n\t\t *    } );\n\t\t */\n\t\tthis.fnSortListener = function( nNode, iColumn, fnCallback )\n\t\t{\n\t\t\tthis.api( true ).order.listener( nNode, iColumn, fnCallback );\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Update a table cell or row - this method will accept either a single value to\n\t\t * update the cell with, an array of values with one element for each column or\n\t\t * an object in the same format as the original data source. The function is\n\t\t * self-referencing in order to make the multi column updates easier.\n\t\t *  @param {object|array|string} mData Data to update the cell/row with\n\t\t *  @param {node|int} mRow TR element you want to update or the aoData index\n\t\t *  @param {int} [iColumn] The column to update, give as null or undefined to\n\t\t *    update a whole row.\n\t\t *  @param {bool} [bRedraw=true] Redraw the table or not\n\t\t *  @param {bool} [bAction=true] Perform pre-draw actions or not\n\t\t *  @returns {int} 0 on success, 1 on error\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      oTable.fnUpdate( 'Example update', 0, 0 ); // Single cell\n\t\t *      oTable.fnUpdate( ['a', 'b', 'c', 'd', 'e'], $('tbody tr')[0] ); // Row\n\t\t *    } );\n\t\t */\n\t\tthis.fnUpdate = function( mData, mRow, iColumn, bRedraw, bAction )\n\t\t{\n\t\t\tvar api = this.api( true );\n\t\t\n\t\t\tif ( iColumn === undefined || iColumn === null ) {\n\t\t\t\tapi.row( mRow ).data( mData );\n\t\t\t}\n\t\t\telse {\n\t\t\t\tapi.cell( mRow, iColumn ).data( mData );\n\t\t\t}\n\t\t\n\t\t\tif ( bAction === undefined || bAction ) {\n\t\t\t\tapi.columns.adjust();\n\t\t\t}\n\t\t\n\t\t\tif ( bRedraw === undefined || bRedraw ) {\n\t\t\t\tapi.draw();\n\t\t\t}\n\t\t\treturn 0;\n\t\t};\n\t\t\n\t\t\n\t\t/**\n\t\t * Provide a common method for plug-ins to check the version of DataTables being used, in order\n\t\t * to ensure compatibility.\n\t\t *  @param {string} sVersion Version string to check for, in the format \"X.Y.Z\". Note that the\n\t\t *    formats \"X\" and \"X.Y\" are also acceptable.\n\t\t *  @returns {boolean} true if this version of DataTables is greater or equal to the required\n\t\t *    version, or false if this version of DataTales is not suitable\n\t\t *  @method\n\t\t *  @dtopt API\n\t\t *  @deprecated Since v1.10\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready(function() {\n\t\t *      var oTable = $('#example').dataTable();\n\t\t *      alert( oTable.fnVersionCheck( '1.9.0' ) );\n\t\t *    } );\n\t\t */\n\t\tthis.fnVersionCheck = _ext.fnVersionCheck;\n\t\t\n\n\t\tvar _that = this;\n\t\tvar emptyInit = options === undefined;\n\t\tvar len = this.length;\n\n\t\tif ( emptyInit ) {\n\t\t\toptions = {};\n\t\t}\n\n\t\tthis.oApi = this.internal = _ext.internal;\n\n\t\t// Extend with old style plug-in API methods\n\t\tfor ( var fn in DataTable.ext.internal ) {\n\t\t\tif ( fn ) {\n\t\t\t\tthis[fn] = _fnExternApiFunc(fn);\n\t\t\t}\n\t\t}\n\n\t\tthis.each(function() {\n\t\t\t// For each initialisation we want to give it a clean initialisation\n\t\t\t// object that can be bashed around\n\t\t\tvar o = {};\n\t\t\tvar oInit = len > 1 ? // optimisation for single table case\n\t\t\t\t_fnExtend( o, options, true ) :\n\t\t\t\toptions;\n\n\t\t\t/*global oInit,_that,emptyInit*/\n\t\t\tvar i=0, iLen, j, jLen, k, kLen;\n\t\t\tvar sId = this.getAttribute( 'id' );\n\t\t\tvar bInitHandedOff = false;\n\t\t\tvar defaults = DataTable.defaults;\n\t\t\tvar $this = $(this);\n\t\t\t\n\t\t\t\n\t\t\t/* Sanity check */\n\t\t\tif ( this.nodeName.toLowerCase() != 'table' )\n\t\t\t{\n\t\t\t\t_fnLog( null, 0, 'Non-table node initialisation ('+this.nodeName+')', 2 );\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t\n\t\t\t/* Backwards compatibility for the defaults */\n\t\t\t_fnCompatOpts( defaults );\n\t\t\t_fnCompatCols( defaults.column );\n\t\t\t\n\t\t\t/* Convert the camel-case defaults to Hungarian */\n\t\t\t_fnCamelToHungarian( defaults, defaults, true );\n\t\t\t_fnCamelToHungarian( defaults.column, defaults.column, true );\n\t\t\t\n\t\t\t/* Setting up the initialisation object */\n\t\t\t_fnCamelToHungarian( defaults, $.extend( oInit, $this.data() ) );\n\t\t\t\n\t\t\t\n\t\t\t\n\t\t\t/* Check to see if we are re-initialising a table */\n\t\t\tvar allSettings = DataTable.settings;\n\t\t\tfor ( i=0, iLen=allSettings.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\tvar s = allSettings[i];\n\t\t\t\n\t\t\t\t/* Base check on table node */\n\t\t\t\tif ( s.nTable == this || s.nTHead.parentNode == this || (s.nTFoot && s.nTFoot.parentNode == this) )\n\t\t\t\t{\n\t\t\t\t\tvar bRetrieve = oInit.bRetrieve !== undefined ? oInit.bRetrieve : defaults.bRetrieve;\n\t\t\t\t\tvar bDestroy = oInit.bDestroy !== undefined ? oInit.bDestroy : defaults.bDestroy;\n\t\t\t\n\t\t\t\t\tif ( emptyInit || bRetrieve )\n\t\t\t\t\t{\n\t\t\t\t\t\treturn s.oInstance;\n\t\t\t\t\t}\n\t\t\t\t\telse if ( bDestroy )\n\t\t\t\t\t{\n\t\t\t\t\t\ts.oInstance.fnDestroy();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t_fnLog( s, 0, 'Cannot reinitialise DataTable', 3 );\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\n\t\t\t\t/* If the element we are initialising has the same ID as a table which was previously\n\t\t\t\t * initialised, but the table nodes don't match (from before) then we destroy the old\n\t\t\t\t * instance by simply deleting it. This is under the assumption that the table has been\n\t\t\t\t * destroyed by other methods. Anyone using non-id selectors will need to do this manually\n\t\t\t\t */\n\t\t\t\tif ( s.sTableId == this.id )\n\t\t\t\t{\n\t\t\t\t\tallSettings.splice( i, 1 );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t/* Ensure the table has an ID - required for accessibility */\n\t\t\tif ( sId === null || sId === \"\" )\n\t\t\t{\n\t\t\t\tsId = \"DataTables_Table_\"+(DataTable.ext._unique++);\n\t\t\t\tthis.id = sId;\n\t\t\t}\n\t\t\t\n\t\t\t/* Create the settings object for this table and set some of the default parameters */\n\t\t\tvar oSettings = $.extend( true, {}, DataTable.models.oSettings, {\n\t\t\t\t\"sDestroyWidth\": $this[0].style.width,\n\t\t\t\t\"sInstance\":     sId,\n\t\t\t\t\"sTableId\":      sId\n\t\t\t} );\n\t\t\toSettings.nTable = this;\n\t\t\toSettings.oApi   = _that.internal;\n\t\t\toSettings.oInit  = oInit;\n\t\t\t\n\t\t\tallSettings.push( oSettings );\n\t\t\t\n\t\t\t// Need to add the instance after the instance after the settings object has been added\n\t\t\t// to the settings array, so we can self reference the table instance if more than one\n\t\t\toSettings.oInstance = (_that.length===1) ? _that : $this.dataTable();\n\t\t\t\n\t\t\t// Backwards compatibility, before we apply all the defaults\n\t\t\t_fnCompatOpts( oInit );\n\t\t\t\n\t\t\tif ( oInit.oLanguage )\n\t\t\t{\n\t\t\t\t_fnLanguageCompat( oInit.oLanguage );\n\t\t\t}\n\t\t\t\n\t\t\t// If the length menu is given, but the init display length is not, use the length menu\n\t\t\tif ( oInit.aLengthMenu && ! oInit.iDisplayLength )\n\t\t\t{\n\t\t\t\toInit.iDisplayLength = $.isArray( oInit.aLengthMenu[0] ) ?\n\t\t\t\t\toInit.aLengthMenu[0][0] : oInit.aLengthMenu[0];\n\t\t\t}\n\t\t\t\n\t\t\t// Apply the defaults and init options to make a single init object will all\n\t\t\t// options defined from defaults and instance options.\n\t\t\toInit = _fnExtend( $.extend( true, {}, defaults ), oInit );\n\t\t\t\n\t\t\t\n\t\t\t// Map the initialisation options onto the settings object\n\t\t\t_fnMap( oSettings.oFeatures, oInit, [\n\t\t\t\t\"bPaginate\",\n\t\t\t\t\"bLengthChange\",\n\t\t\t\t\"bFilter\",\n\t\t\t\t\"bSort\",\n\t\t\t\t\"bSortMulti\",\n\t\t\t\t\"bInfo\",\n\t\t\t\t\"bProcessing\",\n\t\t\t\t\"bAutoWidth\",\n\t\t\t\t\"bSortClasses\",\n\t\t\t\t\"bServerSide\",\n\t\t\t\t\"bDeferRender\"\n\t\t\t] );\n\t\t\t_fnMap( oSettings, oInit, [\n\t\t\t\t\"asStripeClasses\",\n\t\t\t\t\"ajax\",\n\t\t\t\t\"fnServerData\",\n\t\t\t\t\"fnFormatNumber\",\n\t\t\t\t\"sServerMethod\",\n\t\t\t\t\"aaSorting\",\n\t\t\t\t\"aaSortingFixed\",\n\t\t\t\t\"aLengthMenu\",\n\t\t\t\t\"sPaginationType\",\n\t\t\t\t\"sAjaxSource\",\n\t\t\t\t\"sAjaxDataProp\",\n\t\t\t\t\"iStateDuration\",\n\t\t\t\t\"sDom\",\n\t\t\t\t\"bSortCellsTop\",\n\t\t\t\t\"iTabIndex\",\n\t\t\t\t\"fnStateLoadCallback\",\n\t\t\t\t\"fnStateSaveCallback\",\n\t\t\t\t\"renderer\",\n\t\t\t\t\"searchDelay\",\n\t\t\t\t[ \"iCookieDuration\", \"iStateDuration\" ], // backwards compat\n\t\t\t\t[ \"oSearch\", \"oPreviousSearch\" ],\n\t\t\t\t[ \"aoSearchCols\", \"aoPreSearchCols\" ],\n\t\t\t\t[ \"iDisplayLength\", \"_iDisplayLength\" ],\n\t\t\t\t[ \"bJQueryUI\", \"bJUI\" ]\n\t\t\t] );\n\t\t\t_fnMap( oSettings.oScroll, oInit, [\n\t\t\t\t[ \"sScrollX\", \"sX\" ],\n\t\t\t\t[ \"sScrollXInner\", \"sXInner\" ],\n\t\t\t\t[ \"sScrollY\", \"sY\" ],\n\t\t\t\t[ \"bScrollCollapse\", \"bCollapse\" ]\n\t\t\t] );\n\t\t\t_fnMap( oSettings.oLanguage, oInit, \"fnInfoCallback\" );\n\t\t\t\n\t\t\t/* Callback functions which are array driven */\n\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback',       oInit.fnDrawCallback,      'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoServerParams',       oInit.fnServerParams,      'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoStateSaveParams',    oInit.fnStateSaveParams,   'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoStateLoadParams',    oInit.fnStateLoadParams,   'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoStateLoaded',        oInit.fnStateLoaded,       'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoRowCallback',        oInit.fnRowCallback,       'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoRowCreatedCallback', oInit.fnCreatedRow,        'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoHeaderCallback',     oInit.fnHeaderCallback,    'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoFooterCallback',     oInit.fnFooterCallback,    'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoInitComplete',       oInit.fnInitComplete,      'user' );\n\t\t\t_fnCallbackReg( oSettings, 'aoPreDrawCallback',    oInit.fnPreDrawCallback,   'user' );\n\t\t\t\n\t\t\tvar oClasses = oSettings.oClasses;\n\t\t\t\n\t\t\t// @todo Remove in 1.11\n\t\t\tif ( oInit.bJQueryUI )\n\t\t\t{\n\t\t\t\t/* Use the JUI classes object for display. You could clone the oStdClasses object if\n\t\t\t\t * you want to have multiple tables with multiple independent classes\n\t\t\t\t */\n\t\t\t\t$.extend( oClasses, DataTable.ext.oJUIClasses, oInit.oClasses );\n\t\t\t\n\t\t\t\tif ( oInit.sDom === defaults.sDom && defaults.sDom === \"lfrtip\" )\n\t\t\t\t{\n\t\t\t\t\t/* Set the DOM to use a layout suitable for jQuery UI's theming */\n\t\t\t\t\toSettings.sDom = '<\"H\"lfr>t<\"F\"ip>';\n\t\t\t\t}\n\t\t\t\n\t\t\t\tif ( ! oSettings.renderer ) {\n\t\t\t\t\toSettings.renderer = 'jqueryui';\n\t\t\t\t}\n\t\t\t\telse if ( $.isPlainObject( oSettings.renderer ) && ! oSettings.renderer.header ) {\n\t\t\t\t\toSettings.renderer.header = 'jqueryui';\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$.extend( oClasses, DataTable.ext.classes, oInit.oClasses );\n\t\t\t}\n\t\t\t$this.addClass( oClasses.sTable );\n\t\t\t\n\t\t\t/* Calculate the scroll bar width and cache it for use later on */\n\t\t\tif ( oSettings.oScroll.sX !== \"\" || oSettings.oScroll.sY !== \"\" )\n\t\t\t{\n\t\t\t\toSettings.oScroll.iBarWidth = _fnScrollBarWidth();\n\t\t\t}\n\t\t\tif ( oSettings.oScroll.sX === true ) { // Easy initialisation of x-scrolling\n\t\t\t\toSettings.oScroll.sX = '100%';\n\t\t\t}\n\t\t\t\n\t\t\tif ( oSettings.iInitDisplayStart === undefined )\n\t\t\t{\n\t\t\t\t/* Display start point, taking into account the save saving */\n\t\t\t\toSettings.iInitDisplayStart = oInit.iDisplayStart;\n\t\t\t\toSettings._iDisplayStart = oInit.iDisplayStart;\n\t\t\t}\n\t\t\t\n\t\t\tif ( oInit.iDeferLoading !== null )\n\t\t\t{\n\t\t\t\toSettings.bDeferLoading = true;\n\t\t\t\tvar tmp = $.isArray( oInit.iDeferLoading );\n\t\t\t\toSettings._iRecordsDisplay = tmp ? oInit.iDeferLoading[0] : oInit.iDeferLoading;\n\t\t\t\toSettings._iRecordsTotal = tmp ? oInit.iDeferLoading[1] : oInit.iDeferLoading;\n\t\t\t}\n\t\t\t\n\t\t\t/* Language definitions */\n\t\t\tvar oLanguage = oSettings.oLanguage;\n\t\t\t$.extend( true, oLanguage, oInit.oLanguage );\n\t\t\t\n\t\t\tif ( oLanguage.sUrl !== \"\" )\n\t\t\t{\n\t\t\t\t/* Get the language definitions from a file - because this Ajax call makes the language\n\t\t\t\t * get async to the remainder of this function we use bInitHandedOff to indicate that\n\t\t\t\t * _fnInitialise will be fired by the returned Ajax handler, rather than the constructor\n\t\t\t\t */\n\t\t\t\t$.ajax( {\n\t\t\t\t\tdataType: 'json',\n\t\t\t\t\turl: oLanguage.sUrl,\n\t\t\t\t\tsuccess: function ( json ) {\n\t\t\t\t\t\t_fnLanguageCompat( json );\n\t\t\t\t\t\t_fnCamelToHungarian( defaults.oLanguage, json );\n\t\t\t\t\t\t$.extend( true, oLanguage, json );\n\t\t\t\t\t\t_fnInitialise( oSettings );\n\t\t\t\t\t},\n\t\t\t\t\terror: function () {\n\t\t\t\t\t\t// Error occurred loading language file, continue on as best we can\n\t\t\t\t\t\t_fnInitialise( oSettings );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\tbInitHandedOff = true;\n\t\t\t}\n\t\t\t\n\t\t\t/*\n\t\t\t * Stripes\n\t\t\t */\n\t\t\tif ( oInit.asStripeClasses === null )\n\t\t\t{\n\t\t\t\toSettings.asStripeClasses =[\n\t\t\t\t\toClasses.sStripeOdd,\n\t\t\t\t\toClasses.sStripeEven\n\t\t\t\t];\n\t\t\t}\n\t\t\t\n\t\t\t/* Remove row stripe classes if they are already on the table row */\n\t\t\tvar stripeClasses = oSettings.asStripeClasses;\n\t\t\tvar rowOne = $this.children('tbody').find('tr').eq(0);\n\t\t\tif ( $.inArray( true, $.map( stripeClasses, function(el, i) {\n\t\t\t\treturn rowOne.hasClass(el);\n\t\t\t} ) ) !== -1 ) {\n\t\t\t\t$('tbody tr', this).removeClass( stripeClasses.join(' ') );\n\t\t\t\toSettings.asDestroyStripes = stripeClasses.slice();\n\t\t\t}\n\t\t\t\n\t\t\t/*\n\t\t\t * Columns\n\t\t\t * See if we should load columns automatically or use defined ones\n\t\t\t */\n\t\t\tvar anThs = [];\n\t\t\tvar aoColumnsInit;\n\t\t\tvar nThead = this.getElementsByTagName('thead');\n\t\t\tif ( nThead.length !== 0 )\n\t\t\t{\n\t\t\t\t_fnDetectHeader( oSettings.aoHeader, nThead[0] );\n\t\t\t\tanThs = _fnGetUniqueThs( oSettings );\n\t\t\t}\n\t\t\t\n\t\t\t/* If not given a column array, generate one with nulls */\n\t\t\tif ( oInit.aoColumns === null )\n\t\t\t{\n\t\t\t\taoColumnsInit = [];\n\t\t\t\tfor ( i=0, iLen=anThs.length ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\taoColumnsInit.push( null );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\taoColumnsInit = oInit.aoColumns;\n\t\t\t}\n\t\t\t\n\t\t\t/* Add the columns */\n\t\t\tfor ( i=0, iLen=aoColumnsInit.length ; i<iLen ; i++ )\n\t\t\t{\n\t\t\t\t_fnAddColumn( oSettings, anThs ? anThs[i] : null );\n\t\t\t}\n\t\t\t\n\t\t\t/* Apply the column definitions */\n\t\t\t_fnApplyColumnDefs( oSettings, oInit.aoColumnDefs, aoColumnsInit, function (iCol, oDef) {\n\t\t\t\t_fnColumnOptions( oSettings, iCol, oDef );\n\t\t\t} );\n\t\t\t\n\t\t\t/* HTML5 attribute detection - build an mData object automatically if the\n\t\t\t * attributes are found\n\t\t\t */\n\t\t\tif ( rowOne.length ) {\n\t\t\t\tvar a = function ( cell, name ) {\n\t\t\t\t\treturn cell.getAttribute( 'data-'+name ) !== null ? name : null;\n\t\t\t\t};\n\t\t\t\n\t\t\t\t$.each( _fnGetRowElements( oSettings, rowOne[0] ).cells, function (i, cell) {\n\t\t\t\t\tvar col = oSettings.aoColumns[i];\n\t\t\t\n\t\t\t\t\tif ( col.mData === i ) {\n\t\t\t\t\t\tvar sort = a( cell, 'sort' ) || a( cell, 'order' );\n\t\t\t\t\t\tvar filter = a( cell, 'filter' ) || a( cell, 'search' );\n\t\t\t\n\t\t\t\t\t\tif ( sort !== null || filter !== null ) {\n\t\t\t\t\t\t\tcol.mData = {\n\t\t\t\t\t\t\t\t_:      i+'.display',\n\t\t\t\t\t\t\t\tsort:   sort !== null   ? i+'.@data-'+sort   : undefined,\n\t\t\t\t\t\t\t\ttype:   sort !== null   ? i+'.@data-'+sort   : undefined,\n\t\t\t\t\t\t\t\tfilter: filter !== null ? i+'.@data-'+filter : undefined\n\t\t\t\t\t\t\t};\n\t\t\t\n\t\t\t\t\t\t\t_fnColumnOptions( oSettings, i );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t\t\n\t\t\tvar features = oSettings.oFeatures;\n\t\t\t\n\t\t\t/* Must be done after everything which can be overridden by the state saving! */\n\t\t\tif ( oInit.bStateSave )\n\t\t\t{\n\t\t\t\tfeatures.bStateSave = true;\n\t\t\t\t_fnLoadState( oSettings, oInit );\n\t\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback', _fnSaveState, 'state_save' );\n\t\t\t}\n\t\t\t\n\t\t\t\n\t\t\t/*\n\t\t\t * Sorting\n\t\t\t * @todo For modularisation (1.11) this needs to do into a sort start up handler\n\t\t\t */\n\t\t\t\n\t\t\t// If aaSorting is not defined, then we use the first indicator in asSorting\n\t\t\t// in case that has been altered, so the default sort reflects that option\n\t\t\tif ( oInit.aaSorting === undefined )\n\t\t\t{\n\t\t\t\tvar sorting = oSettings.aaSorting;\n\t\t\t\tfor ( i=0, iLen=sorting.length ; i<iLen ; i++ )\n\t\t\t\t{\n\t\t\t\t\tsorting[i][1] = oSettings.aoColumns[ i ].asSorting[0];\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t/* Do a first pass on the sorting classes (allows any size changes to be taken into\n\t\t\t * account, and also will apply sorting disabled classes if disabled\n\t\t\t */\n\t\t\t_fnSortingClasses( oSettings );\n\t\t\t\n\t\t\tif ( features.bSort )\n\t\t\t{\n\t\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback', function () {\n\t\t\t\t\tif ( oSettings.bSorted ) {\n\t\t\t\t\t\tvar aSort = _fnSortFlatten( oSettings );\n\t\t\t\t\t\tvar sortedColumns = {};\n\t\t\t\n\t\t\t\t\t\t$.each( aSort, function (i, val) {\n\t\t\t\t\t\t\tsortedColumns[ val.src ] = val.dir;\n\t\t\t\t\t\t} );\n\t\t\t\n\t\t\t\t\t\t_fnCallbackFire( oSettings, null, 'order', [oSettings, aSort, sortedColumns] );\n\t\t\t\t\t\t_fnSortAria( oSettings );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t}\n\t\t\t\n\t\t\t_fnCallbackReg( oSettings, 'aoDrawCallback', function () {\n\t\t\t\tif ( oSettings.bSorted || _fnDataSource( oSettings ) === 'ssp' || features.bDeferRender ) {\n\t\t\t\t\t_fnSortingClasses( oSettings );\n\t\t\t\t}\n\t\t\t}, 'sc' );\n\t\t\t\n\t\t\t\n\t\t\t/*\n\t\t\t * Final init\n\t\t\t * Cache the header, body and footer as required, creating them if needed\n\t\t\t */\n\t\t\t\n\t\t\t/* Browser support detection */\n\t\t\t_fnBrowserDetect( oSettings );\n\t\t\t\n\t\t\t// Work around for Webkit bug 83867 - store the caption-side before removing from doc\n\t\t\tvar captions = $this.children('caption').each( function () {\n\t\t\t\tthis._captionSide = $this.css('caption-side');\n\t\t\t} );\n\t\t\t\n\t\t\tvar thead = $this.children('thead');\n\t\t\tif ( thead.length === 0 )\n\t\t\t{\n\t\t\t\tthead = $('<thead/>').appendTo(this);\n\t\t\t}\n\t\t\toSettings.nTHead = thead[0];\n\t\t\t\n\t\t\tvar tbody = $this.children('tbody');\n\t\t\tif ( tbody.length === 0 )\n\t\t\t{\n\t\t\t\ttbody = $('<tbody/>').appendTo(this);\n\t\t\t}\n\t\t\toSettings.nTBody = tbody[0];\n\t\t\t\n\t\t\tvar tfoot = $this.children('tfoot');\n\t\t\tif ( tfoot.length === 0 && captions.length > 0 && (oSettings.oScroll.sX !== \"\" || oSettings.oScroll.sY !== \"\") )\n\t\t\t{\n\t\t\t\t// If we are a scrolling table, and no footer has been given, then we need to create\n\t\t\t\t// a tfoot element for the caption element to be appended to\n\t\t\t\ttfoot = $('<tfoot/>').appendTo(this);\n\t\t\t}\n\t\t\t\n\t\t\tif ( tfoot.length === 0 || tfoot.children().length === 0 ) {\n\t\t\t\t$this.addClass( oClasses.sNoFooter );\n\t\t\t}\n\t\t\telse if ( tfoot.length > 0 ) {\n\t\t\t\toSettings.nTFoot = tfoot[0];\n\t\t\t\t_fnDetectHeader( oSettings.aoFooter, oSettings.nTFoot );\n\t\t\t}\n\t\t\t\n\t\t\t/* Check if there is data passing into the constructor */\n\t\t\tif ( oInit.aaData )\n\t\t\t{\n\t\t\t\tfor ( i=0 ; i<oInit.aaData.length ; i++ )\n\t\t\t\t{\n\t\t\t\t\t_fnAddData( oSettings, oInit.aaData[ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if ( oSettings.bDeferLoading || _fnDataSource( oSettings ) == 'dom' )\n\t\t\t{\n\t\t\t\t/* Grab the data from the page - only do this when deferred loading or no Ajax\n\t\t\t\t * source since there is no point in reading the DOM data if we are then going\n\t\t\t\t * to replace it with Ajax data\n\t\t\t\t */\n\t\t\t\t_fnAddTr( oSettings, $(oSettings.nTBody).children('tr') );\n\t\t\t}\n\t\t\t\n\t\t\t/* Copy the data index array */\n\t\t\toSettings.aiDisplay = oSettings.aiDisplayMaster.slice();\n\t\t\t\n\t\t\t/* Initialisation complete - table can be drawn */\n\t\t\toSettings.bInitialised = true;\n\t\t\t\n\t\t\t/* Check if we need to initialise the table (it might not have been handed off to the\n\t\t\t * language processor)\n\t\t\t */\n\t\t\tif ( bInitHandedOff === false )\n\t\t\t{\n\t\t\t\t_fnInitialise( oSettings );\n\t\t\t}\n\t\t} );\n\t\t_that = null;\n\t\treturn this;\n\t};\n\n\t\n\t\n\t/**\n\t * Computed structure of the DataTables API, defined by the options passed to\n\t * `DataTable.Api.register()` when building the API.\n\t *\n\t * The structure is built in order to speed creation and extension of the Api\n\t * objects since the extensions are effectively pre-parsed.\n\t *\n\t * The array is an array of objects with the following structure, where this\n\t * base array represents the Api prototype base:\n\t *\n\t *     [\n\t *       {\n\t *         name:      'data'                -- string   - Property name\n\t *         val:       function () {},       -- function - Api method (or undefined if just an object\n\t *         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result\n\t *         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property\n\t *       },\n\t *       {\n\t *         name:     'row'\n\t *         val:       {},\n\t *         methodExt: [ ... ],\n\t *         propExt:   [\n\t *           {\n\t *             name:      'data'\n\t *             val:       function () {},\n\t *             methodExt: [ ... ],\n\t *             propExt:   [ ... ]\n\t *           },\n\t *           ...\n\t *         ]\n\t *       }\n\t *     ]\n\t *\n\t * @type {Array}\n\t * @ignore\n\t */\n\tvar __apiStruct = [];\n\t\n\t\n\t/**\n\t * `Array.prototype` reference.\n\t *\n\t * @type object\n\t * @ignore\n\t */\n\tvar __arrayProto = Array.prototype;\n\t\n\t\n\t/**\n\t * Abstraction for `context` parameter of the `Api` constructor to allow it to\n\t * take several different forms for ease of use.\n\t *\n\t * Each of the input parameter types will be converted to a DataTables settings\n\t * object where possible.\n\t *\n\t * @param  {string|node|jQuery|object} mixed DataTable identifier. Can be one\n\t *   of:\n\t *\n\t *   * `string` - jQuery selector. Any DataTables' matching the given selector\n\t *     with be found and used.\n\t *   * `node` - `TABLE` node which has already been formed into a DataTable.\n\t *   * `jQuery` - A jQuery object of `TABLE` nodes.\n\t *   * `object` - DataTables settings object\n\t *   * `DataTables.Api` - API instance\n\t * @return {array|null} Matching DataTables settings objects. `null` or\n\t *   `undefined` is returned if no matching DataTable is found.\n\t * @ignore\n\t */\n\tvar _toSettings = function ( mixed )\n\t{\n\t\tvar idx, jq;\n\t\tvar settings = DataTable.settings;\n\t\tvar tables = $.map( settings, function (el, i) {\n\t\t\treturn el.nTable;\n\t\t} );\n\t\n\t\tif ( ! mixed ) {\n\t\t\treturn [];\n\t\t}\n\t\telse if ( mixed.nTable && mixed.oApi ) {\n\t\t\t// DataTables settings object\n\t\t\treturn [ mixed ];\n\t\t}\n\t\telse if ( mixed.nodeName && mixed.nodeName.toLowerCase() === 'table' ) {\n\t\t\t// Table node\n\t\t\tidx = $.inArray( mixed, tables );\n\t\t\treturn idx !== -1 ? [ settings[idx] ] : null;\n\t\t}\n\t\telse if ( mixed && typeof mixed.settings === 'function' ) {\n\t\t\treturn mixed.settings().toArray();\n\t\t}\n\t\telse if ( typeof mixed === 'string' ) {\n\t\t\t// jQuery selector\n\t\t\tjq = $(mixed);\n\t\t}\n\t\telse if ( mixed instanceof $ ) {\n\t\t\t// jQuery object (also DataTables instance)\n\t\t\tjq = mixed;\n\t\t}\n\t\n\t\tif ( jq ) {\n\t\t\treturn jq.map( function(i) {\n\t\t\t\tidx = $.inArray( this, tables );\n\t\t\t\treturn idx !== -1 ? settings[idx] : null;\n\t\t\t} ).toArray();\n\t\t}\n\t};\n\t\n\t\n\t/**\n\t * DataTables API class - used to control and interface with  one or more\n\t * DataTables enhanced tables.\n\t *\n\t * The API class is heavily based on jQuery, presenting a chainable interface\n\t * that you can use to interact with tables. Each instance of the API class has\n\t * a \"context\" - i.e. the tables that it will operate on. This could be a single\n\t * table, all tables on a page or a sub-set thereof.\n\t *\n\t * Additionally the API is designed to allow you to easily work with the data in\n\t * the tables, retrieving and manipulating it as required. This is done by\n\t * presenting the API class as an array like interface. The contents of the\n\t * array depend upon the actions requested by each method (for example\n\t * `rows().nodes()` will return an array of nodes, while `rows().data()` will\n\t * return an array of objects or arrays depending upon your table's\n\t * configuration). The API object has a number of array like methods (`push`,\n\t * `pop`, `reverse` etc) as well as additional helper methods (`each`, `pluck`,\n\t * `unique` etc) to assist your working with the data held in a table.\n\t *\n\t * Most methods (those which return an Api instance) are chainable, which means\n\t * the return from a method call also has all of the methods available that the\n\t * top level object had. For example, these two calls are equivalent:\n\t *\n\t *     // Not chained\n\t *     api.row.add( {...} );\n\t *     api.draw();\n\t *\n\t *     // Chained\n\t *     api.row.add( {...} ).draw();\n\t *\n\t * @class DataTable.Api\n\t * @param {array|object|string|jQuery} context DataTable identifier. This is\n\t *   used to define which DataTables enhanced tables this API will operate on.\n\t *   Can be one of:\n\t *\n\t *   * `string` - jQuery selector. Any DataTables' matching the given selector\n\t *     with be found and used.\n\t *   * `node` - `TABLE` node which has already been formed into a DataTable.\n\t *   * `jQuery` - A jQuery object of `TABLE` nodes.\n\t *   * `object` - DataTables settings object\n\t * @param {array} [data] Data to initialise the Api instance with.\n\t *\n\t * @example\n\t *   // Direct initialisation during DataTables construction\n\t *   var api = $('#example').DataTable();\n\t *\n\t * @example\n\t *   // Initialisation using a DataTables jQuery object\n\t *   var api = $('#example').dataTable().api();\n\t *\n\t * @example\n\t *   // Initialisation as a constructor\n\t *   var api = new $.fn.DataTable.Api( 'table.dataTable' );\n\t */\n\t_Api = function ( context, data )\n\t{\n\t\tif ( ! (this instanceof _Api) ) {\n\t\t\treturn new _Api( context, data );\n\t\t}\n\t\n\t\tvar settings = [];\n\t\tvar ctxSettings = function ( o ) {\n\t\t\tvar a = _toSettings( o );\n\t\t\tif ( a ) {\n\t\t\t\tsettings.push.apply( settings, a );\n\t\t\t}\n\t\t};\n\t\n\t\tif ( $.isArray( context ) ) {\n\t\t\tfor ( var i=0, ien=context.length ; i<ien ; i++ ) {\n\t\t\t\tctxSettings( context[i] );\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tctxSettings( context );\n\t\t}\n\t\n\t\t// Remove duplicates\n\t\tthis.context = _unique( settings );\n\t\n\t\t// Initial data\n\t\tif ( data ) {\n\t\t\tthis.push.apply( this, data.toArray ? data.toArray() : data );\n\t\t}\n\t\n\t\t// selector\n\t\tthis.selector = {\n\t\t\trows: null,\n\t\t\tcols: null,\n\t\t\topts: null\n\t\t};\n\t\n\t\t_Api.extend( this, this, __apiStruct );\n\t};\n\t\n\tDataTable.Api = _Api;\n\t\n\t_Api.prototype = /** @lends DataTables.Api */{\n\t\tany: function ()\n\t\t{\n\t\t\treturn this.flatten().length !== 0;\n\t\t},\n\t\n\t\n\t\tconcat:  __arrayProto.concat,\n\t\n\t\n\t\tcontext: [], // array of table settings objects\n\t\n\t\n\t\teach: function ( fn )\n\t\t{\n\t\t\tfor ( var i=0, ien=this.length ; i<ien; i++ ) {\n\t\t\t\tfn.call( this, this[i], i, this );\n\t\t\t}\n\t\n\t\t\treturn this;\n\t\t},\n\t\n\t\n\t\teq: function ( idx )\n\t\t{\n\t\t\tvar ctx = this.context;\n\t\n\t\t\treturn ctx.length > idx ?\n\t\t\t\tnew _Api( ctx[idx], this[idx] ) :\n\t\t\t\tnull;\n\t\t},\n\t\n\t\n\t\tfilter: function ( fn )\n\t\t{\n\t\t\tvar a = [];\n\t\n\t\t\tif ( __arrayProto.filter ) {\n\t\t\t\ta = __arrayProto.filter.call( this, fn, this );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Compatibility for browsers without EMCA-252-5 (JS 1.6)\n\t\t\t\tfor ( var i=0, ien=this.length ; i<ien ; i++ ) {\n\t\t\t\t\tif ( fn.call( this, this[i], i, this ) ) {\n\t\t\t\t\t\ta.push( this[i] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn new _Api( this.context, a );\n\t\t},\n\t\n\t\n\t\tflatten: function ()\n\t\t{\n\t\t\tvar a = [];\n\t\t\treturn new _Api( this.context, a.concat.apply( a, this.toArray() ) );\n\t\t},\n\t\n\t\n\t\tjoin:    __arrayProto.join,\n\t\n\t\n\t\tindexOf: __arrayProto.indexOf || function (obj, start)\n\t\t{\n\t\t\tfor ( var i=(start || 0), ien=this.length ; i<ien ; i++ ) {\n\t\t\t\tif ( this[i] === obj ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn -1;\n\t\t},\n\t\n\t\titerator: function ( flatten, type, fn, alwaysNew ) {\n\t\t\tvar\n\t\t\t\ta = [], ret,\n\t\t\t\ti, ien, j, jen,\n\t\t\t\tcontext = this.context,\n\t\t\t\trows, items, item,\n\t\t\t\tselector = this.selector;\n\t\n\t\t\t// Argument shifting\n\t\t\tif ( typeof flatten === 'string' ) {\n\t\t\t\talwaysNew = fn;\n\t\t\t\tfn = type;\n\t\t\t\ttype = flatten;\n\t\t\t\tflatten = false;\n\t\t\t}\n\t\n\t\t\tfor ( i=0, ien=context.length ; i<ien ; i++ ) {\n\t\t\t\tvar apiInst = new _Api( context[i] );\n\t\n\t\t\t\tif ( type === 'table' ) {\n\t\t\t\t\tret = fn.call( apiInst, context[i], i );\n\t\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\ta.push( ret );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if ( type === 'columns' || type === 'rows' ) {\n\t\t\t\t\t// this has same length as context - one entry for each table\n\t\t\t\t\tret = fn.call( apiInst, context[i], this[i], i );\n\t\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\ta.push( ret );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if ( type === 'column' || type === 'column-rows' || type === 'row' || type === 'cell' ) {\n\t\t\t\t\t// columns and rows share the same structure.\n\t\t\t\t\t// 'this' is an array of column indexes for each context\n\t\t\t\t\titems = this[i];\n\t\n\t\t\t\t\tif ( type === 'column-rows' ) {\n\t\t\t\t\t\trows = _selector_row_indexes( context[i], selector.opts );\n\t\t\t\t\t}\n\t\n\t\t\t\t\tfor ( j=0, jen=items.length ; j<jen ; j++ ) {\n\t\t\t\t\t\titem = items[j];\n\t\n\t\t\t\t\t\tif ( type === 'cell' ) {\n\t\t\t\t\t\t\tret = fn.call( apiInst, context[i], item.row, item.column, i, j );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tret = fn.call( apiInst, context[i], item, i, j, rows );\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\t\ta.push( ret );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tif ( a.length || alwaysNew ) {\n\t\t\t\tvar api = new _Api( context, flatten ? a.concat.apply( [], a ) : a );\n\t\t\t\tvar apiSelector = api.selector;\n\t\t\t\tapiSelector.rows = selector.rows;\n\t\t\t\tapiSelector.cols = selector.cols;\n\t\t\t\tapiSelector.opts = selector.opts;\n\t\t\t\treturn api;\n\t\t\t}\n\t\t\treturn this;\n\t\t},\n\t\n\t\n\t\tlastIndexOf: __arrayProto.lastIndexOf || function (obj, start)\n\t\t{\n\t\t\t// Bit cheeky...\n\t\t\treturn this.indexOf.apply( this.toArray.reverse(), arguments );\n\t\t},\n\t\n\t\n\t\tlength:  0,\n\t\n\t\n\t\tmap: function ( fn )\n\t\t{\n\t\t\tvar a = [];\n\t\n\t\t\tif ( __arrayProto.map ) {\n\t\t\t\ta = __arrayProto.map.call( this, fn, this );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Compatibility for browsers without EMCA-252-5 (JS 1.6)\n\t\t\t\tfor ( var i=0, ien=this.length ; i<ien ; i++ ) {\n\t\t\t\t\ta.push( fn.call( this, this[i], i ) );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn new _Api( this.context, a );\n\t\t},\n\t\n\t\n\t\tpluck: function ( prop )\n\t\t{\n\t\t\treturn this.map( function ( el ) {\n\t\t\t\treturn el[ prop ];\n\t\t\t} );\n\t\t},\n\t\n\t\tpop:     __arrayProto.pop,\n\t\n\t\n\t\tpush:    __arrayProto.push,\n\t\n\t\n\t\t// Does not return an API instance\n\t\treduce: __arrayProto.reduce || function ( fn, init )\n\t\t{\n\t\t\treturn _fnReduce( this, fn, init, 0, this.length, 1 );\n\t\t},\n\t\n\t\n\t\treduceRight: __arrayProto.reduceRight || function ( fn, init )\n\t\t{\n\t\t\treturn _fnReduce( this, fn, init, this.length-1, -1, -1 );\n\t\t},\n\t\n\t\n\t\treverse: __arrayProto.reverse,\n\t\n\t\n\t\t// Object with rows, columns and opts\n\t\tselector: null,\n\t\n\t\n\t\tshift:   __arrayProto.shift,\n\t\n\t\n\t\tsort:    __arrayProto.sort, // ? name - order?\n\t\n\t\n\t\tsplice:  __arrayProto.splice,\n\t\n\t\n\t\ttoArray: function ()\n\t\t{\n\t\t\treturn __arrayProto.slice.call( this );\n\t\t},\n\t\n\t\n\t\tto$: function ()\n\t\t{\n\t\t\treturn $( this );\n\t\t},\n\t\n\t\n\t\ttoJQuery: function ()\n\t\t{\n\t\t\treturn $( this );\n\t\t},\n\t\n\t\n\t\tunique: function ()\n\t\t{\n\t\t\treturn new _Api( this.context, _unique(this) );\n\t\t},\n\t\n\t\n\t\tunshift: __arrayProto.unshift\n\t};\n\t\n\t\n\t_Api.extend = function ( scope, obj, ext )\n\t{\n\t\t// Only extend API instances and static properties of the API\n\t\tif ( ! ext.length || ! obj || ( ! (obj instanceof _Api) && ! obj.__dt_wrapper ) ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar\n\t\t\ti, ien,\n\t\t\tj, jen,\n\t\t\tstruct, inner,\n\t\t\tmethodScoping = function ( scope, fn, struc ) {\n\t\t\t\treturn function () {\n\t\t\t\t\tvar ret = fn.apply( scope, arguments );\n\t\n\t\t\t\t\t// Method extension\n\t\t\t\t\t_Api.extend( ret, ret, struc.methodExt );\n\t\t\t\t\treturn ret;\n\t\t\t\t};\n\t\t\t};\n\t\n\t\tfor ( i=0, ien=ext.length ; i<ien ; i++ ) {\n\t\t\tstruct = ext[i];\n\t\n\t\t\t// Value\n\t\t\tobj[ struct.name ] = typeof struct.val === 'function' ?\n\t\t\t\tmethodScoping( scope, struct.val, struct ) :\n\t\t\t\t$.isPlainObject( struct.val ) ?\n\t\t\t\t\t{} :\n\t\t\t\t\tstruct.val;\n\t\n\t\t\tobj[ struct.name ].__dt_wrapper = true;\n\t\n\t\t\t// Property extension\n\t\t\t_Api.extend( scope, obj[ struct.name ], struct.propExt );\n\t\t}\n\t};\n\t\n\t\n\t// @todo - Is there need for an augment function?\n\t// _Api.augment = function ( inst, name )\n\t// {\n\t// \t// Find src object in the structure from the name\n\t// \tvar parts = name.split('.');\n\t\n\t// \t_Api.extend( inst, obj );\n\t// };\n\t\n\t\n\t//     [\n\t//       {\n\t//         name:      'data'                -- string   - Property name\n\t//         val:       function () {},       -- function - Api method (or undefined if just an object\n\t//         methodExt: [ ... ],              -- array    - Array of Api object definitions to extend the method result\n\t//         propExt:   [ ... ]               -- array    - Array of Api object definitions to extend the property\n\t//       },\n\t//       {\n\t//         name:     'row'\n\t//         val:       {},\n\t//         methodExt: [ ... ],\n\t//         propExt:   [\n\t//           {\n\t//             name:      'data'\n\t//             val:       function () {},\n\t//             methodExt: [ ... ],\n\t//             propExt:   [ ... ]\n\t//           },\n\t//           ...\n\t//         ]\n\t//       }\n\t//     ]\n\t\n\t_Api.register = _api_register = function ( name, val )\n\t{\n\t\tif ( $.isArray( name ) ) {\n\t\t\tfor ( var j=0, jen=name.length ; j<jen ; j++ ) {\n\t\t\t\t_Api.register( name[j], val );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\n\t\tvar\n\t\t\ti, ien,\n\t\t\their = name.split('.'),\n\t\t\tstruct = __apiStruct,\n\t\t\tkey, method;\n\t\n\t\tvar find = function ( src, name ) {\n\t\t\tfor ( var i=0, ien=src.length ; i<ien ; i++ ) {\n\t\t\t\tif ( src[i].name === name ) {\n\t\t\t\t\treturn src[i];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t};\n\t\n\t\tfor ( i=0, ien=heir.length ; i<ien ; i++ ) {\n\t\t\tmethod = heir[i].indexOf('()') !== -1;\n\t\t\tkey = method ?\n\t\t\t\their[i].replace('()', '') :\n\t\t\t\their[i];\n\t\n\t\t\tvar src = find( struct, key );\n\t\t\tif ( ! src ) {\n\t\t\t\tsrc = {\n\t\t\t\t\tname:      key,\n\t\t\t\t\tval:       {},\n\t\t\t\t\tmethodExt: [],\n\t\t\t\t\tpropExt:   []\n\t\t\t\t};\n\t\t\t\tstruct.push( src );\n\t\t\t}\n\t\n\t\t\tif ( i === ien-1 ) {\n\t\t\t\tsrc.val = val;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tstruct = method ?\n\t\t\t\t\tsrc.methodExt :\n\t\t\t\t\tsrc.propExt;\n\t\t\t}\n\t\t}\n\t};\n\t\n\t\n\t_Api.registerPlural = _api_registerPlural = function ( pluralName, singularName, val ) {\n\t\t_Api.register( pluralName, val );\n\t\n\t\t_Api.register( singularName, function () {\n\t\t\tvar ret = val.apply( this, arguments );\n\t\n\t\t\tif ( ret === this ) {\n\t\t\t\t// Returned item is the API instance that was passed in, return it\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\telse if ( ret instanceof _Api ) {\n\t\t\t\t// New API instance returned, want the value from the first item\n\t\t\t\t// in the returned array for the singular result.\n\t\t\t\treturn ret.length ?\n\t\t\t\t\t$.isArray( ret[0] ) ?\n\t\t\t\t\t\tnew _Api( ret.context, ret[0] ) : // Array results are 'enhanced'\n\t\t\t\t\t\tret[0] :\n\t\t\t\t\tundefined;\n\t\t\t}\n\t\n\t\t\t// Non-API return - just fire it back\n\t\t\treturn ret;\n\t\t} );\n\t};\n\t\n\t\n\t/**\n\t * Selector for HTML tables. Apply the given selector to the give array of\n\t * DataTables settings objects.\n\t *\n\t * @param {string|integer} [selector] jQuery selector string or integer\n\t * @param  {array} Array of DataTables settings objects to be filtered\n\t * @return {array}\n\t * @ignore\n\t */\n\tvar __table_selector = function ( selector, a )\n\t{\n\t\t// Integer is used to pick out a table by index\n\t\tif ( typeof selector === 'number' ) {\n\t\t\treturn [ a[ selector ] ];\n\t\t}\n\t\n\t\t// Perform a jQuery selector on the table nodes\n\t\tvar nodes = $.map( a, function (el, i) {\n\t\t\treturn el.nTable;\n\t\t} );\n\t\n\t\treturn $(nodes)\n\t\t\t.filter( selector )\n\t\t\t.map( function (i) {\n\t\t\t\t// Need to translate back from the table node to the settings\n\t\t\t\tvar idx = $.inArray( this, nodes );\n\t\t\t\treturn a[ idx ];\n\t\t\t} )\n\t\t\t.toArray();\n\t};\n\t\n\t\n\t\n\t/**\n\t * Context selector for the API's context (i.e. the tables the API instance\n\t * refers to.\n\t *\n\t * @name    DataTable.Api#tables\n\t * @param {string|integer} [selector] Selector to pick which tables the iterator\n\t *   should operate on. If not given, all tables in the current context are\n\t *   used. This can be given as a jQuery selector (for example `':gt(0)'`) to\n\t *   select multiple tables or as an integer to select a single table.\n\t * @returns {DataTable.Api} Returns a new API instance if a selector is given.\n\t */\n\t_api_register( 'tables()', function ( selector ) {\n\t\t// A new instance is created if there was a selector specified\n\t\treturn selector ?\n\t\t\tnew _Api( __table_selector( selector, this.context ) ) :\n\t\t\tthis;\n\t} );\n\t\n\t\n\t_api_register( 'table()', function ( selector ) {\n\t\tvar tables = this.tables( selector );\n\t\tvar ctx = tables.context;\n\t\n\t\t// Truncate to the first matched table\n\t\treturn ctx.length ?\n\t\t\tnew _Api( ctx[0] ) :\n\t\t\ttables;\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().nodes()', 'table().node()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTable;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().body()', 'table().body()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTBody;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().header()', 'table().header()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTHead;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().footer()', 'table().footer()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTFoot;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'tables().containers()', 'table().container()' , function () {\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\treturn ctx.nTableWrapper;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t\n\t/**\n\t * Redraw the tables in the current context.\n\t *\n\t * @param {boolean} [reset=true] Reset (default) or hold the current paging\n\t *   position. A full re-sort and re-filter is performed when this method is\n\t *   called, which is why the pagination reset is the default action.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'draw()', function ( resetPaging ) {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnReDraw( settings, resetPaging===false );\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t/**\n\t * Get the current page index.\n\t *\n\t * @return {integer} Current page index (zero based)\n\t *//**\n\t * Set the current page.\n\t *\n\t * Note that if you attempt to show a page which does not exist, DataTables will\n\t * not throw an error, but rather reset the paging.\n\t *\n\t * @param {integer|string} action The paging action to take. This can be one of:\n\t *  * `integer` - The page index to jump to\n\t *  * `string` - An action to take:\n\t *    * `first` - Jump to first page.\n\t *    * `next` - Jump to the next page\n\t *    * `previous` - Jump to previous page\n\t *    * `last` - Jump to the last page.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'page()', function ( action ) {\n\t\tif ( action === undefined ) {\n\t\t\treturn this.page.info().page; // not an expensive call\n\t\t}\n\t\n\t\t// else, have an action to take on all tables\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnPageChange( settings, action );\n\t\t} );\n\t} );\n\t\n\t\n\t/**\n\t * Paging information for the first table in the current context.\n\t *\n\t * If you require paging information for another table, use the `table()` method\n\t * with a suitable selector.\n\t *\n\t * @return {object} Object with the following properties set:\n\t *  * `page` - Current page index (zero based - i.e. the first page is `0`)\n\t *  * `pages` - Total number of pages\n\t *  * `start` - Display index for the first record shown on the current page\n\t *  * `end` - Display index for the last record shown on the current page\n\t *  * `length` - Display length (number of records). Note that generally `start\n\t *    + length = end`, but this is not always true, for example if there are\n\t *    only 2 records to show on the final page, with a length of 10.\n\t *  * `recordsTotal` - Full data set length\n\t *  * `recordsDisplay` - Data set length once the current filtering criterion\n\t *    are applied.\n\t */\n\t_api_register( 'page.info()', function ( action ) {\n\t\tif ( this.context.length === 0 ) {\n\t\t\treturn undefined;\n\t\t}\n\t\n\t\tvar\n\t\t\tsettings   = this.context[0],\n\t\t\tstart      = settings._iDisplayStart,\n\t\t\tlen        = settings._iDisplayLength,\n\t\t\tvisRecords = settings.fnRecordsDisplay(),\n\t\t\tall        = len === -1;\n\t\n\t\treturn {\n\t\t\t\"page\":           all ? 0 : Math.floor( start / len ),\n\t\t\t\"pages\":          all ? 1 : Math.ceil( visRecords / len ),\n\t\t\t\"start\":          start,\n\t\t\t\"end\":            settings.fnDisplayEnd(),\n\t\t\t\"length\":         len,\n\t\t\t\"recordsTotal\":   settings.fnRecordsTotal(),\n\t\t\t\"recordsDisplay\": visRecords\n\t\t};\n\t} );\n\t\n\t\n\t/**\n\t * Get the current page length.\n\t *\n\t * @return {integer} Current page length. Note `-1` indicates that all records\n\t *   are to be shown.\n\t *//**\n\t * Set the current page length.\n\t *\n\t * @param {integer} Page length to set. Use `-1` to show all records.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'page.len()', function ( len ) {\n\t\t// Note that we can't call this function 'length()' because `length`\n\t\t// is a Javascript property of functions which defines how many arguments\n\t\t// the function expects.\n\t\tif ( len === undefined ) {\n\t\t\treturn this.context.length !== 0 ?\n\t\t\t\tthis.context[0]._iDisplayLength :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// else, set the page length\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnLengthChange( settings, len );\n\t\t} );\n\t} );\n\t\n\t\n\t\n\tvar __reload = function ( settings, holdPosition, callback ) {\n\t\t// Use the draw event to trigger a callback\n\t\tif ( callback ) {\n\t\t\tvar api = new _Api( settings );\n\t\n\t\t\tapi.one( 'draw', function () {\n\t\t\t\tcallback( api.ajax.json() );\n\t\t\t} );\n\t\t}\n\t\n\t\tif ( _fnDataSource( settings ) == 'ssp' ) {\n\t\t\t_fnReDraw( settings, holdPosition );\n\t\t}\n\t\telse {\n\t\t\t// Trigger xhr\n\t\t\t_fnProcessingDisplay( settings, true );\n\t\n\t\t\t_fnBuildAjax( settings, [], function( json ) {\n\t\t\t\t_fnClearTable( settings );\n\t\n\t\t\t\tvar data = _fnAjaxDataSrc( settings, json );\n\t\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\t\t_fnAddData( settings, data[i] );\n\t\t\t\t}\n\t\n\t\t\t\t_fnReDraw( settings, holdPosition );\n\t\t\t\t_fnProcessingDisplay( settings, false );\n\t\t\t} );\n\t\t}\n\t};\n\t\n\t\n\t/**\n\t * Get the JSON response from the last Ajax request that DataTables made to the\n\t * server. Note that this returns the JSON from the first table in the current\n\t * context.\n\t *\n\t * @return {object} JSON received from the server.\n\t */\n\t_api_register( 'ajax.json()', function () {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( ctx.length > 0 ) {\n\t\t\treturn ctx[0].json;\n\t\t}\n\t\n\t\t// else return undefined;\n\t} );\n\t\n\t\n\t/**\n\t * Get the data submitted in the last Ajax request\n\t */\n\t_api_register( 'ajax.params()', function () {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( ctx.length > 0 ) {\n\t\t\treturn ctx[0].oAjaxData;\n\t\t}\n\t\n\t\t// else return undefined;\n\t} );\n\t\n\t\n\t/**\n\t * Reload tables from the Ajax data source. Note that this function will\n\t * automatically re-draw the table when the remote data has been loaded.\n\t *\n\t * @param {boolean} [reset=true] Reset (default) or hold the current paging\n\t *   position. A full re-sort and re-filter is performed when this method is\n\t *   called, which is why the pagination reset is the default action.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'ajax.reload()', function ( callback, resetPaging ) {\n\t\treturn this.iterator( 'table', function (settings) {\n\t\t\t__reload( settings, resetPaging===false, callback );\n\t\t} );\n\t} );\n\t\n\t\n\t/**\n\t * Get the current Ajax URL. Note that this returns the URL from the first\n\t * table in the current context.\n\t *\n\t * @return {string} Current Ajax source URL\n\t *//**\n\t * Set the Ajax URL. Note that this will set the URL for all tables in the\n\t * current context.\n\t *\n\t * @param {string} url URL to set.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'ajax.url()', function ( url ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( url === undefined ) {\n\t\t\t// get\n\t\t\tif ( ctx.length === 0 ) {\n\t\t\t\treturn undefined;\n\t\t\t}\n\t\t\tctx = ctx[0];\n\t\n\t\t\treturn ctx.ajax ?\n\t\t\t\t$.isPlainObject( ctx.ajax ) ?\n\t\t\t\t\tctx.ajax.url :\n\t\t\t\t\tctx.ajax :\n\t\t\t\tctx.sAjaxSource;\n\t\t}\n\t\n\t\t// set\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tif ( $.isPlainObject( settings.ajax ) ) {\n\t\t\t\tsettings.ajax.url = url;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsettings.ajax = url;\n\t\t\t}\n\t\t\t// No need to consider sAjaxSource here since DataTables gives priority\n\t\t\t// to `ajax` over `sAjaxSource`. So setting `ajax` here, renders any\n\t\t\t// value of `sAjaxSource` redundant.\n\t\t} );\n\t} );\n\t\n\t\n\t/**\n\t * Load data from the newly set Ajax URL. Note that this method is only\n\t * available when `ajax.url()` is used to set a URL. Additionally, this method\n\t * has the same effect as calling `ajax.reload()` but is provided for\n\t * convenience when setting a new URL. Like `ajax.reload()` it will\n\t * automatically redraw the table once the remote data has been loaded.\n\t *\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'ajax.url().load()', function ( callback, resetPaging ) {\n\t\t// Same as a reload, but makes sense to present it for easy access after a\n\t\t// url change\n\t\treturn this.iterator( 'table', function ( ctx ) {\n\t\t\t__reload( ctx, resetPaging===false, callback );\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t\n\tvar _selector_run = function ( type, selector, selectFn, settings, opts )\n\t{\n\t\tvar\n\t\t\tout = [], res,\n\t\t\ta, i, ien, j, jen,\n\t\t\tselectorType = typeof selector;\n\t\n\t\t// Can't just check for isArray here, as an API or jQuery instance might be\n\t\t// given with their array like look\n\t\tif ( ! selector || selectorType === 'string' || selectorType === 'function' || selector.length === undefined ) {\n\t\t\tselector = [ selector ];\n\t\t}\n\t\n\t\tfor ( i=0, ien=selector.length ; i<ien ; i++ ) {\n\t\t\ta = selector[i] && selector[i].split ?\n\t\t\t\tselector[i].split(',') :\n\t\t\t\t[ selector[i] ];\n\t\n\t\t\tfor ( j=0, jen=a.length ; j<jen ; j++ ) {\n\t\t\t\tres = selectFn( typeof a[j] === 'string' ? $.trim(a[j]) : a[j] );\n\t\n\t\t\t\tif ( res && res.length ) {\n\t\t\t\t\tout.push.apply( out, res );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\t// selector extensions\n\t\tvar ext = _ext.selector[ type ];\n\t\tif ( ext.length ) {\n\t\t\tfor ( i=0, ien=ext.length ; i<ien ; i++ ) {\n\t\t\t\tout = ext[i]( settings, opts, out );\n\t\t\t}\n\t\t}\n\t\n\t\treturn out;\n\t};\n\t\n\t\n\tvar _selector_opts = function ( opts )\n\t{\n\t\tif ( ! opts ) {\n\t\t\topts = {};\n\t\t}\n\t\n\t\t// Backwards compatibility for 1.9- which used the terminology filter rather\n\t\t// than search\n\t\tif ( opts.filter && opts.search === undefined ) {\n\t\t\topts.search = opts.filter;\n\t\t}\n\t\n\t\treturn $.extend( {\n\t\t\tsearch: 'none',\n\t\t\torder: 'current',\n\t\t\tpage: 'all'\n\t\t}, opts );\n\t};\n\t\n\t\n\tvar _selector_first = function ( inst )\n\t{\n\t\t// Reduce the API instance to the first item found\n\t\tfor ( var i=0, ien=inst.length ; i<ien ; i++ ) {\n\t\t\tif ( inst[i].length > 0 ) {\n\t\t\t\t// Assign the first element to the first item in the instance\n\t\t\t\t// and truncate the instance and context\n\t\t\t\tinst[0] = inst[i];\n\t\t\t\tinst[0].length = 1;\n\t\t\t\tinst.length = 1;\n\t\t\t\tinst.context = [ inst.context[i] ];\n\t\n\t\t\t\treturn inst;\n\t\t\t}\n\t\t}\n\t\n\t\t// Not found - return an empty instance\n\t\tinst.length = 0;\n\t\treturn inst;\n\t};\n\t\n\t\n\tvar _selector_row_indexes = function ( settings, opts )\n\t{\n\t\tvar\n\t\t\ti, ien, tmp, a=[],\n\t\t\tdisplayFiltered = settings.aiDisplay,\n\t\t\tdisplayMaster = settings.aiDisplayMaster;\n\t\n\t\tvar\n\t\t\tsearch = opts.search,  // none, applied, removed\n\t\t\torder  = opts.order,   // applied, current, index (original - compatibility with 1.9)\n\t\t\tpage   = opts.page;    // all, current\n\t\n\t\tif ( _fnDataSource( settings ) == 'ssp' ) {\n\t\t\t// In server-side processing mode, most options are irrelevant since\n\t\t\t// rows not shown don't exist and the index order is the applied order\n\t\t\t// Removed is a special case - for consistency just return an empty\n\t\t\t// array\n\t\t\treturn search === 'removed' ?\n\t\t\t\t[] :\n\t\t\t\t_range( 0, displayMaster.length );\n\t\t}\n\t\telse if ( page == 'current' ) {\n\t\t\t// Current page implies that order=current and fitler=applied, since it is\n\t\t\t// fairly senseless otherwise, regardless of what order and search actually\n\t\t\t// are\n\t\t\tfor ( i=settings._iDisplayStart, ien=settings.fnDisplayEnd() ; i<ien ; i++ ) {\n\t\t\t\ta.push( displayFiltered[i] );\n\t\t\t}\n\t\t}\n\t\telse if ( order == 'current' || order == 'applied' ) {\n\t\t\ta = search == 'none' ?\n\t\t\t\tdisplayMaster.slice() :                      // no search\n\t\t\t\tsearch == 'applied' ?\n\t\t\t\t\tdisplayFiltered.slice() :                // applied search\n\t\t\t\t\t$.map( displayMaster, function (el, i) { // removed search\n\t\t\t\t\t\treturn $.inArray( el, displayFiltered ) === -1 ? el : null;\n\t\t\t\t\t} );\n\t\t}\n\t\telse if ( order == 'index' || order == 'original' ) {\n\t\t\tfor ( i=0, ien=settings.aoData.length ; i<ien ; i++ ) {\n\t\t\t\tif ( search == 'none' ) {\n\t\t\t\t\ta.push( i );\n\t\t\t\t}\n\t\t\t\telse { // applied | removed\n\t\t\t\t\ttmp = $.inArray( i, displayFiltered );\n\t\n\t\t\t\t\tif ((tmp === -1 && search == 'removed') ||\n\t\t\t\t\t\t(tmp >= 0   && search == 'applied') )\n\t\t\t\t\t{\n\t\t\t\t\t\ta.push( i );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\n\t\treturn a;\n\t};\n\t\n\t\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Rows\n\t *\n\t * {}          - no selector - use all available rows\n\t * {integer}   - row aoData index\n\t * {node}      - TR node\n\t * {string}    - jQuery selector to apply to the TR elements\n\t * {array}     - jQuery array of nodes, or simply an array of TR nodes\n\t *\n\t */\n\t\n\t\n\tvar __row_selector = function ( settings, selector, opts )\n\t{\n\t\tvar run = function ( sel ) {\n\t\t\tvar selInt = _intVal( sel );\n\t\t\tvar i, ien;\n\t\n\t\t\t// Short cut - selector is a number and no options provided (default is\n\t\t\t// all records, so no need to check if the index is in there, since it\n\t\t\t// must be - dev error if the index doesn't exist).\n\t\t\tif ( selInt !== null && ! opts ) {\n\t\t\t\treturn [ selInt ];\n\t\t\t}\n\t\n\t\t\tvar rows = _selector_row_indexes( settings, opts );\n\t\n\t\t\tif ( selInt !== null && $.inArray( selInt, rows ) !== -1 ) {\n\t\t\t\t// Selector - integer\n\t\t\t\treturn [ selInt ];\n\t\t\t}\n\t\t\telse if ( ! sel ) {\n\t\t\t\t// Selector - none\n\t\t\t\treturn rows;\n\t\t\t}\n\t\n\t\t\t// Selector - function\n\t\t\tif ( typeof sel === 'function' ) {\n\t\t\t\treturn $.map( rows, function (idx) {\n\t\t\t\t\tvar row = settings.aoData[ idx ];\n\t\t\t\t\treturn sel( idx, row._aData, row.nTr ) ? idx : null;\n\t\t\t\t} );\n\t\t\t}\n\t\n\t\t\t// Get nodes in the order from the `rows` array with null values removed\n\t\t\tvar nodes = _removeEmpty(\n\t\t\t\t_pluck_order( settings.aoData, rows, 'nTr' )\n\t\t\t);\n\t\n\t\t\t// Selector - node\n\t\t\tif ( sel.nodeName ) {\n\t\t\t\tif ( $.inArray( sel, nodes ) !== -1 ) {\n\t\t\t\t\treturn [ sel._DT_RowIndex ]; // sel is a TR node that is in the table\n\t\t\t\t\t                             // and DataTables adds a prop for fast lookup\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// Selector - jQuery selector string, array of nodes or jQuery object/\n\t\t\t// As jQuery's .filter() allows jQuery objects to be passed in filter,\n\t\t\t// it also allows arrays, so this will cope with all three options\n\t\t\treturn $(nodes)\n\t\t\t\t.filter( sel )\n\t\t\t\t.map( function () {\n\t\t\t\t\treturn this._DT_RowIndex;\n\t\t\t\t} )\n\t\t\t\t.toArray();\n\t\t};\n\t\n\t\treturn _selector_run( 'row', selector, run, settings, opts );\n\t};\n\t\n\t\n\t_api_register( 'rows()', function ( selector, opts ) {\n\t\t// argument shifting\n\t\tif ( selector === undefined ) {\n\t\t\tselector = '';\n\t\t}\n\t\telse if ( $.isPlainObject( selector ) ) {\n\t\t\topts = selector;\n\t\t\tselector = '';\n\t\t}\n\t\n\t\topts = _selector_opts( opts );\n\t\n\t\tvar inst = this.iterator( 'table', function ( settings ) {\n\t\t\treturn __row_selector( settings, selector, opts );\n\t\t}, 1 );\n\t\n\t\t// Want argument shifting here and in __row_selector?\n\t\tinst.selector.rows = selector;\n\t\tinst.selector.opts = opts;\n\t\n\t\treturn inst;\n\t} );\n\t\n\t_api_register( 'rows().nodes()', function () {\n\t\treturn this.iterator( 'row', function ( settings, row ) {\n\t\t\treturn settings.aoData[ row ].nTr || undefined;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_register( 'rows().data()', function () {\n\t\treturn this.iterator( true, 'rows', function ( settings, rows ) {\n\t\t\treturn _pluck_order( settings.aoData, rows, '_aData' );\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'rows().cache()', 'row().cache()', function ( type ) {\n\t\treturn this.iterator( 'row', function ( settings, row ) {\n\t\t\tvar r = settings.aoData[ row ];\n\t\t\treturn type === 'search' ? r._aFilterData : r._aSortData;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'rows().invalidate()', 'row().invalidate()', function ( src ) {\n\t\treturn this.iterator( 'row', function ( settings, row ) {\n\t\t\t_fnInvalidate( settings, row, src );\n\t\t} );\n\t} );\n\t\n\t_api_registerPlural( 'rows().indexes()', 'row().index()', function () {\n\t\treturn this.iterator( 'row', function ( settings, row ) {\n\t\t\treturn row;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'rows().remove()', 'row().remove()', function () {\n\t\tvar that = this;\n\t\n\t\treturn this.iterator( 'row', function ( settings, row, thatIdx ) {\n\t\t\tvar data = settings.aoData;\n\t\n\t\t\tdata.splice( row, 1 );\n\t\n\t\t\t// Update the _DT_RowIndex parameter on all rows in the table\n\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\tif ( data[i].nTr !== null ) {\n\t\t\t\t\tdata[i].nTr._DT_RowIndex = i;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// Remove the target row from the search array\n\t\t\tvar displayIndex = $.inArray( row, settings.aiDisplay );\n\t\n\t\t\t// Delete from the display arrays\n\t\t\t_fnDeleteIndex( settings.aiDisplayMaster, row );\n\t\t\t_fnDeleteIndex( settings.aiDisplay, row );\n\t\t\t_fnDeleteIndex( that[ thatIdx ], row, false ); // maintain local indexes\n\t\n\t\t\t// Check for an 'overflow' they case for displaying the table\n\t\t\t_fnLengthOverflow( settings );\n\t\t} );\n\t} );\n\t\n\t\n\t_api_register( 'rows.add()', function ( rows ) {\n\t\tvar newRows = this.iterator( 'table', function ( settings ) {\n\t\t\t\tvar row, i, ien;\n\t\t\t\tvar out = [];\n\t\n\t\t\t\tfor ( i=0, ien=rows.length ; i<ien ; i++ ) {\n\t\t\t\t\trow = rows[i];\n\t\n\t\t\t\t\tif ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {\n\t\t\t\t\t\tout.push( _fnAddTr( settings, row )[0] );\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tout.push( _fnAddData( settings, row ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\treturn out;\n\t\t\t}, 1 );\n\t\n\t\t// Return an Api.rows() extended instance, so rows().nodes() etc can be used\n\t\tvar modRows = this.rows( -1 );\n\t\tmodRows.pop();\n\t\tmodRows.push.apply( modRows, newRows.toArray() );\n\t\n\t\treturn modRows;\n\t} );\n\t\n\t\n\t\n\t\n\t\n\t/**\n\t *\n\t */\n\t_api_register( 'row()', function ( selector, opts ) {\n\t\treturn _selector_first( this.rows( selector, opts ) );\n\t} );\n\t\n\t\n\t_api_register( 'row().data()', function ( data ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( data === undefined ) {\n\t\t\t// Get\n\t\t\treturn ctx.length && this.length ?\n\t\t\t\tctx[0].aoData[ this[0] ]._aData :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// Set\n\t\tctx[0].aoData[ this[0] ]._aData = data;\n\t\n\t\t// Automatically invalidate\n\t\t_fnInvalidate( ctx[0], this[0], 'data' );\n\t\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( 'row().node()', function () {\n\t\tvar ctx = this.context;\n\t\n\t\treturn ctx.length && this.length ?\n\t\t\tctx[0].aoData[ this[0] ].nTr || null :\n\t\t\tnull;\n\t} );\n\t\n\t\n\t_api_register( 'row.add()', function ( row ) {\n\t\t// Allow a jQuery object to be passed in - only a single row is added from\n\t\t// it though - the first element in the set\n\t\tif ( row instanceof $ && row.length ) {\n\t\t\trow = row[0];\n\t\t}\n\t\n\t\tvar rows = this.iterator( 'table', function ( settings ) {\n\t\t\tif ( row.nodeName && row.nodeName.toUpperCase() === 'TR' ) {\n\t\t\t\treturn _fnAddTr( settings, row )[0];\n\t\t\t}\n\t\t\treturn _fnAddData( settings, row );\n\t\t} );\n\t\n\t\t// Return an Api.rows() extended instance, with the newly added row selected\n\t\treturn this.row( rows[0] );\n\t} );\n\t\n\t\n\t\n\tvar __details_add = function ( ctx, row, data, klass )\n\t{\n\t\t// Convert to array of TR elements\n\t\tvar rows = [];\n\t\tvar addRow = function ( r, k ) {\n\t\t\t// Recursion to allow for arrays of jQuery objects\n\t\t\tif ( $.isArray( r ) || r instanceof $ ) {\n\t\t\t\tfor ( var i=0, ien=r.length ; i<ien ; i++ ) {\n\t\t\t\t\taddRow( r[i], k );\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// If we get a TR element, then just add it directly - up to the dev\n\t\t\t// to add the correct number of columns etc\n\t\t\tif ( r.nodeName && r.nodeName.toLowerCase() === 'tr' ) {\n\t\t\t\trows.push( r );\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Otherwise create a row with a wrapper\n\t\t\t\tvar created = $('<tr><td/></tr>').addClass( k );\n\t\t\t\t$('td', created)\n\t\t\t\t\t.addClass( k )\n\t\t\t\t\t.html( r )\n\t\t\t\t\t[0].colSpan = _fnVisbleColumns( ctx );\n\t\n\t\t\t\trows.push( created[0] );\n\t\t\t}\n\t\t};\n\t\n\t\taddRow( data, klass );\n\t\n\t\tif ( row._details ) {\n\t\t\trow._details.remove();\n\t\t}\n\t\n\t\trow._details = $(rows);\n\t\n\t\t// If the children were already shown, that state should be retained\n\t\tif ( row._detailsShow ) {\n\t\t\trow._details.insertAfter( row.nTr );\n\t\t}\n\t};\n\t\n\t\n\tvar __details_remove = function ( api, idx )\n\t{\n\t\tvar ctx = api.context;\n\t\n\t\tif ( ctx.length ) {\n\t\t\tvar row = ctx[0].aoData[ idx !== undefined ? idx : api[0] ];\n\t\n\t\t\tif ( row._details ) {\n\t\t\t\trow._details.remove();\n\t\n\t\t\t\trow._detailsShow = undefined;\n\t\t\t\trow._details = undefined;\n\t\t\t}\n\t\t}\n\t};\n\t\n\t\n\tvar __details_display = function ( api, show ) {\n\t\tvar ctx = api.context;\n\t\n\t\tif ( ctx.length && api.length ) {\n\t\t\tvar row = ctx[0].aoData[ api[0] ];\n\t\n\t\t\tif ( row._details ) {\n\t\t\t\trow._detailsShow = show;\n\t\n\t\t\t\tif ( show ) {\n\t\t\t\t\trow._details.insertAfter( row.nTr );\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\trow._details.detach();\n\t\t\t\t}\n\t\n\t\t\t\t__details_events( ctx[0] );\n\t\t\t}\n\t\t}\n\t};\n\t\n\t\n\tvar __details_events = function ( settings )\n\t{\n\t\tvar api = new _Api( settings );\n\t\tvar namespace = '.dt.DT_details';\n\t\tvar drawEvent = 'draw'+namespace;\n\t\tvar colvisEvent = 'column-visibility'+namespace;\n\t\tvar destroyEvent = 'destroy'+namespace;\n\t\tvar data = settings.aoData;\n\t\n\t\tapi.off( drawEvent +' '+ colvisEvent +' '+ destroyEvent );\n\t\n\t\tif ( _pluck( data, '_details' ).length > 0 ) {\n\t\t\t// On each draw, insert the required elements into the document\n\t\t\tapi.on( drawEvent, function ( e, ctx ) {\n\t\t\t\tif ( settings !== ctx ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tapi.rows( {page:'current'} ).eq(0).each( function (idx) {\n\t\t\t\t\t// Internal data grab\n\t\t\t\t\tvar row = data[ idx ];\n\t\n\t\t\t\t\tif ( row._detailsShow ) {\n\t\t\t\t\t\trow._details.insertAfter( row.nTr );\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t} );\n\t\n\t\t\t// Column visibility change - update the colspan\n\t\t\tapi.on( colvisEvent, function ( e, ctx, idx, vis ) {\n\t\t\t\tif ( settings !== ctx ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\t// Update the colspan for the details rows (note, only if it already has\n\t\t\t\t// a colspan)\n\t\t\t\tvar row, visible = _fnVisbleColumns( ctx );\n\t\n\t\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\t\trow = data[i];\n\t\n\t\t\t\t\tif ( row._details ) {\n\t\t\t\t\t\trow._details.children('td[colspan]').attr('colspan', visible );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\n\t\t\t// Table destroyed - nuke any child rows\n\t\t\tapi.on( destroyEvent, function ( e, ctx ) {\n\t\t\t\tif ( settings !== ctx ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\tfor ( var i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\t\tif ( data[i]._details ) {\n\t\t\t\t\t\t__details_remove( api, i );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} );\n\t\t}\n\t};\n\t\n\t// Strings for the method names to help minification\n\tvar _emp = '';\n\tvar _child_obj = _emp+'row().child';\n\tvar _child_mth = _child_obj+'()';\n\t\n\t// data can be:\n\t//  tr\n\t//  string\n\t//  jQuery or array of any of the above\n\t_api_register( _child_mth, function ( data, klass ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( data === undefined ) {\n\t\t\t// get\n\t\t\treturn ctx.length && this.length ?\n\t\t\t\tctx[0].aoData[ this[0] ]._details :\n\t\t\t\tundefined;\n\t\t}\n\t\telse if ( data === true ) {\n\t\t\t// show\n\t\t\tthis.child.show();\n\t\t}\n\t\telse if ( data === false ) {\n\t\t\t// remove\n\t\t\t__details_remove( this );\n\t\t}\n\t\telse if ( ctx.length && this.length ) {\n\t\t\t// set\n\t\t\t__details_add( ctx[0], ctx[0].aoData[ this[0] ], data, klass );\n\t\t}\n\t\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( [\n\t\t_child_obj+'.show()',\n\t\t_child_mth+'.show()' // only when `child()` was called with parameters (without\n\t], function ( show ) {   // it returns an object and this method is not executed)\n\t\t__details_display( this, true );\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( [\n\t\t_child_obj+'.hide()',\n\t\t_child_mth+'.hide()' // only when `child()` was called with parameters (without\n\t], function () {         // it returns an object and this method is not executed)\n\t\t__details_display( this, false );\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( [\n\t\t_child_obj+'.remove()',\n\t\t_child_mth+'.remove()' // only when `child()` was called with parameters (without\n\t], function () {           // it returns an object and this method is not executed)\n\t\t__details_remove( this );\n\t\treturn this;\n\t} );\n\t\n\t\n\t_api_register( _child_obj+'.isShown()', function () {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( ctx.length && this.length ) {\n\t\t\t// _detailsShown as false or undefined will fall through to return false\n\t\t\treturn ctx[0].aoData[ this[0] ]._detailsShow || false;\n\t\t}\n\t\treturn false;\n\t} );\n\t\n\t\n\t\n\t/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *\n\t * Columns\n\t *\n\t * {integer}           - column index (>=0 count from left, <0 count from right)\n\t * \"{integer}:visIdx\"  - visible column index (i.e. translate to column index)  (>=0 count from left, <0 count from right)\n\t * \"{integer}:visible\" - alias for {integer}:visIdx  (>=0 count from left, <0 count from right)\n\t * \"{string}:name\"     - column name\n\t * \"{string}\"          - jQuery selector on column header nodes\n\t *\n\t */\n\t\n\t// can be an array of these items, comma separated list, or an array of comma\n\t// separated lists\n\t\n\tvar __re_column_selector = /^(.+):(name|visIdx|visible)$/;\n\t\n\t\n\t// r1 and r2 are redundant - but it means that the parameters match for the\n\t// iterator callback in columns().data()\n\tvar __columnData = function ( settings, column, r1, r2, rows ) {\n\t\tvar a = [];\n\t\tfor ( var row=0, ien=rows.length ; row<ien ; row++ ) {\n\t\t\ta.push( _fnGetCellData( settings, rows[row], column ) );\n\t\t}\n\t\treturn a;\n\t};\n\t\n\t\n\tvar __column_selector = function ( settings, selector, opts )\n\t{\n\t\tvar\n\t\t\tcolumns = settings.aoColumns,\n\t\t\tnames = _pluck( columns, 'sName' ),\n\t\t\tnodes = _pluck( columns, 'nTh' );\n\t\n\t\tvar run = function ( s ) {\n\t\t\tvar selInt = _intVal( s );\n\t\n\t\t\t// Selector - all\n\t\t\tif ( s === '' ) {\n\t\t\t\treturn _range( columns.length );\n\t\t\t}\n\t\t\t\n\t\t\t// Selector - index\n\t\t\tif ( selInt !== null ) {\n\t\t\t\treturn [ selInt >= 0 ?\n\t\t\t\t\tselInt : // Count from left\n\t\t\t\t\tcolumns.length + selInt // Count from right (+ because its a negative value)\n\t\t\t\t];\n\t\t\t}\n\t\t\t\n\t\t\t// Selector = function\n\t\t\tif ( typeof s === 'function' ) {\n\t\t\t\tvar rows = _selector_row_indexes( settings, opts );\n\t\n\t\t\t\treturn $.map( columns, function (col, idx) {\n\t\t\t\t\treturn s(\n\t\t\t\t\t\t\tidx,\n\t\t\t\t\t\t\t__columnData( settings, idx, 0, 0, rows ),\n\t\t\t\t\t\t\tnodes[ idx ]\n\t\t\t\t\t\t) ? idx : null;\n\t\t\t\t} );\n\t\t\t}\n\t\n\t\t\t// jQuery or string selector\n\t\t\tvar match = typeof s === 'string' ?\n\t\t\t\ts.match( __re_column_selector ) :\n\t\t\t\t'';\n\t\n\t\t\tif ( match ) {\n\t\t\t\tswitch( match[2] ) {\n\t\t\t\t\tcase 'visIdx':\n\t\t\t\t\tcase 'visible':\n\t\t\t\t\t\tvar idx = parseInt( match[1], 10 );\n\t\t\t\t\t\t// Visible index given, convert to column index\n\t\t\t\t\t\tif ( idx < 0 ) {\n\t\t\t\t\t\t\t// Counting from the right\n\t\t\t\t\t\t\tvar visColumns = $.map( columns, function (col,i) {\n\t\t\t\t\t\t\t\treturn col.bVisible ? i : null;\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t\treturn [ visColumns[ visColumns.length + idx ] ];\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Counting from the left\n\t\t\t\t\t\treturn [ _fnVisibleToColumnIndex( settings, idx ) ];\n\t\n\t\t\t\t\tcase 'name':\n\t\t\t\t\t\t// match by name. `names` is column index complete and in order\n\t\t\t\t\t\treturn $.map( names, function (name, i) {\n\t\t\t\t\t\t\treturn name === match[1] ? i : null;\n\t\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// jQuery selector on the TH elements for the columns\n\t\t\t\treturn $( nodes )\n\t\t\t\t\t.filter( s )\n\t\t\t\t\t.map( function () {\n\t\t\t\t\t\treturn $.inArray( this, nodes ); // `nodes` is column index complete and in order\n\t\t\t\t\t} )\n\t\t\t\t\t.toArray();\n\t\t\t}\n\t\t};\n\t\n\t\treturn _selector_run( 'column', selector, run, settings, opts );\n\t};\n\t\n\t\n\tvar __setColumnVis = function ( settings, column, vis, recalc ) {\n\t\tvar\n\t\t\tcols = settings.aoColumns,\n\t\t\tcol  = cols[ column ],\n\t\t\tdata = settings.aoData,\n\t\t\trow, cells, i, ien, tr;\n\t\n\t\t// Get\n\t\tif ( vis === undefined ) {\n\t\t\treturn col.bVisible;\n\t\t}\n\t\n\t\t// Set\n\t\t// No change\n\t\tif ( col.bVisible === vis ) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tif ( vis ) {\n\t\t\t// Insert column\n\t\t\t// Need to decide if we should use appendChild or insertBefore\n\t\t\tvar insertBefore = $.inArray( true, _pluck(cols, 'bVisible'), column+1 );\n\t\n\t\t\tfor ( i=0, ien=data.length ; i<ien ; i++ ) {\n\t\t\t\ttr = data[i].nTr;\n\t\t\t\tcells = data[i].anCells;\n\t\n\t\t\t\tif ( tr ) {\n\t\t\t\t\t// insertBefore can act like appendChild if 2nd arg is null\n\t\t\t\t\ttr.insertBefore( cells[ column ], cells[ insertBefore ] || null );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\t// Remove column\n\t\t\t$( _pluck( settings.aoData, 'anCells', column ) ).detach();\n\t\t}\n\t\n\t\t// Common actions\n\t\tcol.bVisible = vis;\n\t\t_fnDrawHead( settings, settings.aoHeader );\n\t\t_fnDrawHead( settings, settings.aoFooter );\n\t\n\t\tif ( recalc === undefined || recalc ) {\n\t\t\t// Automatically adjust column sizing\n\t\t\t_fnAdjustColumnSizing( settings );\n\t\n\t\t\t// Realign columns for scrolling\n\t\t\tif ( settings.oScroll.sX || settings.oScroll.sY ) {\n\t\t\t\t_fnScrollDraw( settings );\n\t\t\t}\n\t\t}\n\t\n\t\t_fnCallbackFire( settings, null, 'column-visibility', [settings, column, vis] );\n\t\n\t\t_fnSaveState( settings );\n\t};\n\t\n\t\n\t_api_register( 'columns()', function ( selector, opts ) {\n\t\t// argument shifting\n\t\tif ( selector === undefined ) {\n\t\t\tselector = '';\n\t\t}\n\t\telse if ( $.isPlainObject( selector ) ) {\n\t\t\topts = selector;\n\t\t\tselector = '';\n\t\t}\n\t\n\t\topts = _selector_opts( opts );\n\t\n\t\tvar inst = this.iterator( 'table', function ( settings ) {\n\t\t\treturn __column_selector( settings, selector, opts );\n\t\t}, 1 );\n\t\n\t\t// Want argument shifting here and in _row_selector?\n\t\tinst.selector.cols = selector;\n\t\tinst.selector.opts = opts;\n\t\n\t\treturn inst;\n\t} );\n\t\n\t_api_registerPlural( 'columns().header()', 'column().header()', function ( selector, opts ) {\n\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\treturn settings.aoColumns[column].nTh;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().footer()', 'column().footer()', function ( selector, opts ) {\n\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\treturn settings.aoColumns[column].nTf;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().data()', 'column().data()', function () {\n\t\treturn this.iterator( 'column-rows', __columnData, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().dataSrc()', 'column().dataSrc()', function () {\n\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\treturn settings.aoColumns[column].mData;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().cache()', 'column().cache()', function ( type ) {\n\t\treturn this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {\n\t\t\treturn _pluck_order( settings.aoData, rows,\n\t\t\t\ttype === 'search' ? '_aFilterData' : '_aSortData', column\n\t\t\t);\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().nodes()', 'column().nodes()', function () {\n\t\treturn this.iterator( 'column-rows', function ( settings, column, i, j, rows ) {\n\t\t\treturn _pluck_order( settings.aoData, rows, 'anCells', column ) ;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_registerPlural( 'columns().visible()', 'column().visible()', function ( vis, calc ) {\n\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\tif ( vis === undefined ) {\n\t\t\t\treturn settings.aoColumns[ column ].bVisible;\n\t\t\t} // else\n\t\t\t__setColumnVis( settings, column, vis, calc );\n\t\t} );\n\t} );\n\t\n\t_api_registerPlural( 'columns().indexes()', 'column().index()', function ( type ) {\n\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\treturn type === 'visible' ?\n\t\t\t\t_fnColumnIndexToVisible( settings, column ) :\n\t\t\t\tcolumn;\n\t\t}, 1 );\n\t} );\n\t\n\t_api_register( 'columns.adjust()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnAdjustColumnSizing( settings );\n\t\t}, 1 );\n\t} );\n\t\n\t_api_register( 'column.index()', function ( type, idx ) {\n\t\tif ( this.context.length !== 0 ) {\n\t\t\tvar ctx = this.context[0];\n\t\n\t\t\tif ( type === 'fromVisible' || type === 'toData' ) {\n\t\t\t\treturn _fnVisibleToColumnIndex( ctx, idx );\n\t\t\t}\n\t\t\telse if ( type === 'fromData' || type === 'toVisible' ) {\n\t\t\t\treturn _fnColumnIndexToVisible( ctx, idx );\n\t\t\t}\n\t\t}\n\t} );\n\t\n\t_api_register( 'column()', function ( selector, opts ) {\n\t\treturn _selector_first( this.columns( selector, opts ) );\n\t} );\n\t\n\t\n\t\n\t\n\tvar __cell_selector = function ( settings, selector, opts )\n\t{\n\t\tvar data = settings.aoData;\n\t\tvar rows = _selector_row_indexes( settings, opts );\n\t\tvar cells = _removeEmpty( _pluck_order( data, rows, 'anCells' ) );\n\t\tvar allCells = $( [].concat.apply([], cells) );\n\t\tvar row;\n\t\tvar columns = settings.aoColumns.length;\n\t\tvar a, i, ien, j, o, host;\n\t\n\t\tvar run = function ( s ) {\n\t\t\tvar fnSelector = typeof s === 'function';\n\t\n\t\t\tif ( s === null || s === undefined || fnSelector ) {\n\t\t\t\t// All cells and function selectors\n\t\t\t\ta = [];\n\t\n\t\t\t\tfor ( i=0, ien=rows.length ; i<ien ; i++ ) {\n\t\t\t\t\trow = rows[i];\n\t\n\t\t\t\t\tfor ( j=0 ; j<columns ; j++ ) {\n\t\t\t\t\t\to = {\n\t\t\t\t\t\t\trow: row,\n\t\t\t\t\t\t\tcolumn: j\n\t\t\t\t\t\t};\n\t\n\t\t\t\t\t\tif ( fnSelector ) {\n\t\t\t\t\t\t\t// Selector - function\n\t\t\t\t\t\t\thost = settings.aoData[ row ];\n\t\n\t\t\t\t\t\t\tif ( s( o, _fnGetCellData(settings, row, j), host.anCells ? host.anCells[j] : null ) ) {\n\t\t\t\t\t\t\t\ta.push( o );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t// Selector - all\n\t\t\t\t\t\t\ta.push( o );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\treturn a;\n\t\t\t}\n\t\t\t\n\t\t\t// Selector - index\n\t\t\tif ( $.isPlainObject( s ) ) {\n\t\t\t\treturn [s];\n\t\t\t}\n\t\n\t\t\t// Selector - jQuery filtered cells\n\t\t\treturn allCells\n\t\t\t\t.filter( s )\n\t\t\t\t.map( function (i, el) {\n\t\t\t\t\trow = el.parentNode._DT_RowIndex;\n\t\n\t\t\t\t\treturn {\n\t\t\t\t\t\trow: row,\n\t\t\t\t\t\tcolumn: $.inArray( el, data[ row ].anCells )\n\t\t\t\t\t};\n\t\t\t\t} )\n\t\t\t\t.toArray();\n\t\t};\n\t\n\t\treturn _selector_run( 'cell', selector, run, settings, opts );\n\t};\n\t\n\t\n\t\n\t\n\t_api_register( 'cells()', function ( rowSelector, columnSelector, opts ) {\n\t\t// Argument shifting\n\t\tif ( $.isPlainObject( rowSelector ) ) {\n\t\t\t// Indexes\n\t\t\tif ( rowSelector.row === undefined ) {\n\t\t\t\t// Selector options in first parameter\n\t\t\t\topts = rowSelector;\n\t\t\t\trowSelector = null;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Cell index objects in first parameter\n\t\t\t\topts = columnSelector;\n\t\t\t\tcolumnSelector = null;\n\t\t\t}\n\t\t}\n\t\tif ( $.isPlainObject( columnSelector ) ) {\n\t\t\topts = columnSelector;\n\t\t\tcolumnSelector = null;\n\t\t}\n\t\n\t\t// Cell selector\n\t\tif ( columnSelector === null || columnSelector === undefined ) {\n\t\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t\treturn __cell_selector( settings, rowSelector, _selector_opts( opts ) );\n\t\t\t} );\n\t\t}\n\t\n\t\t// Row + column selector\n\t\tvar columns = this.columns( columnSelector, opts );\n\t\tvar rows = this.rows( rowSelector, opts );\n\t\tvar a, i, ien, j, jen;\n\t\n\t\tvar cells = this.iterator( 'table', function ( settings, idx ) {\n\t\t\ta = [];\n\t\n\t\t\tfor ( i=0, ien=rows[idx].length ; i<ien ; i++ ) {\n\t\t\t\tfor ( j=0, jen=columns[idx].length ; j<jen ; j++ ) {\n\t\t\t\t\ta.push( {\n\t\t\t\t\t\trow:    rows[idx][i],\n\t\t\t\t\t\tcolumn: columns[idx][j]\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\treturn a;\n\t\t}, 1 );\n\t\n\t\t$.extend( cells.selector, {\n\t\t\tcols: columnSelector,\n\t\t\trows: rowSelector,\n\t\t\topts: opts\n\t\t} );\n\t\n\t\treturn cells;\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().nodes()', 'cell().node()', function () {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\tvar cells = settings.aoData[ row ].anCells;\n\t\t\treturn cells ?\n\t\t\t\tcells[ column ] :\n\t\t\t\tundefined;\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_register( 'cells().data()', function () {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\treturn _fnGetCellData( settings, row, column );\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().cache()', 'cell().cache()', function ( type ) {\n\t\ttype = type === 'search' ? '_aFilterData' : '_aSortData';\n\t\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\treturn settings.aoData[ row ][ type ][ column ];\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().render()', 'cell().render()', function ( type ) {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\treturn _fnGetCellData( settings, row, column, type );\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().indexes()', 'cell().index()', function () {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\treturn {\n\t\t\t\trow: row,\n\t\t\t\tcolumn: column,\n\t\t\t\tcolumnVisible: _fnColumnIndexToVisible( settings, column )\n\t\t\t};\n\t\t}, 1 );\n\t} );\n\t\n\t\n\t_api_registerPlural( 'cells().invalidate()', 'cell().invalidate()', function ( src ) {\n\t\treturn this.iterator( 'cell', function ( settings, row, column ) {\n\t\t\t_fnInvalidate( settings, row, src, column );\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t_api_register( 'cell()', function ( rowSelector, columnSelector, opts ) {\n\t\treturn _selector_first( this.cells( rowSelector, columnSelector, opts ) );\n\t} );\n\t\n\t\n\t_api_register( 'cell().data()', function ( data ) {\n\t\tvar ctx = this.context;\n\t\tvar cell = this[0];\n\t\n\t\tif ( data === undefined ) {\n\t\t\t// Get\n\t\t\treturn ctx.length && cell.length ?\n\t\t\t\t_fnGetCellData( ctx[0], cell[0].row, cell[0].column ) :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// Set\n\t\t_fnSetCellData( ctx[0], cell[0].row, cell[0].column, data );\n\t\t_fnInvalidate( ctx[0], cell[0].row, 'data', cell[0].column );\n\t\n\t\treturn this;\n\t} );\n\t\n\t\n\t\n\t/**\n\t * Get current ordering (sorting) that has been applied to the table.\n\t *\n\t * @returns {array} 2D array containing the sorting information for the first\n\t *   table in the current context. Each element in the parent array represents\n\t *   a column being sorted upon (i.e. multi-sorting with two columns would have\n\t *   2 inner arrays). The inner arrays may have 2 or 3 elements. The first is\n\t *   the column index that the sorting condition applies to, the second is the\n\t *   direction of the sort (`desc` or `asc`) and, optionally, the third is the\n\t *   index of the sorting order from the `column.sorting` initialisation array.\n\t *//**\n\t * Set the ordering for the table.\n\t *\n\t * @param {integer} order Column index to sort upon.\n\t * @param {string} direction Direction of the sort to be applied (`asc` or `desc`)\n\t * @returns {DataTables.Api} this\n\t *//**\n\t * Set the ordering for the table.\n\t *\n\t * @param {array} order 1D array of sorting information to be applied.\n\t * @param {array} [...] Optional additional sorting conditions\n\t * @returns {DataTables.Api} this\n\t *//**\n\t * Set the ordering for the table.\n\t *\n\t * @param {array} order 2D array of sorting information to be applied.\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'order()', function ( order, dir ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( order === undefined ) {\n\t\t\t// get\n\t\t\treturn ctx.length !== 0 ?\n\t\t\t\tctx[0].aaSorting :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// set\n\t\tif ( typeof order === 'number' ) {\n\t\t\t// Simple column / direction passed in\n\t\t\torder = [ [ order, dir ] ];\n\t\t}\n\t\telse if ( ! $.isArray( order[0] ) ) {\n\t\t\t// Arguments passed in (list of 1D arrays)\n\t\t\torder = Array.prototype.slice.call( arguments );\n\t\t}\n\t\t// otherwise a 2D array was passed in\n\t\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tsettings.aaSorting = order.slice();\n\t\t} );\n\t} );\n\t\n\t\n\t/**\n\t * Attach a sort listener to an element for a given column\n\t *\n\t * @param {node|jQuery|string} node Identifier for the element(s) to attach the\n\t *   listener to. This can take the form of a single DOM node, a jQuery\n\t *   collection of nodes or a jQuery selector which will identify the node(s).\n\t * @param {integer} column the column that a click on this node will sort on\n\t * @param {function} [callback] callback function when sort is run\n\t * @returns {DataTables.Api} this\n\t */\n\t_api_register( 'order.listener()', function ( node, column, callback ) {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnSortAttachListener( settings, node, column, callback );\n\t\t} );\n\t} );\n\t\n\t\n\t// Order by the selected column(s)\n\t_api_register( [\n\t\t'columns().order()',\n\t\t'column().order()'\n\t], function ( dir ) {\n\t\tvar that = this;\n\t\n\t\treturn this.iterator( 'table', function ( settings, i ) {\n\t\t\tvar sort = [];\n\t\n\t\t\t$.each( that[i], function (j, col) {\n\t\t\t\tsort.push( [ col, dir ] );\n\t\t\t} );\n\t\n\t\t\tsettings.aaSorting = sort;\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t_api_register( 'search()', function ( input, regex, smart, caseInsen ) {\n\t\tvar ctx = this.context;\n\t\n\t\tif ( input === undefined ) {\n\t\t\t// get\n\t\t\treturn ctx.length !== 0 ?\n\t\t\t\tctx[0].oPreviousSearch.sSearch :\n\t\t\t\tundefined;\n\t\t}\n\t\n\t\t// set\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tif ( ! settings.oFeatures.bFilter ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t_fnFilterComplete( settings, $.extend( {}, settings.oPreviousSearch, {\n\t\t\t\t\"sSearch\": input+\"\",\n\t\t\t\t\"bRegex\":  regex === null ? false : regex,\n\t\t\t\t\"bSmart\":  smart === null ? true  : smart,\n\t\t\t\t\"bCaseInsensitive\": caseInsen === null ? true : caseInsen\n\t\t\t} ), 1 );\n\t\t} );\n\t} );\n\t\n\t\n\t_api_registerPlural(\n\t\t'columns().search()',\n\t\t'column().search()',\n\t\tfunction ( input, regex, smart, caseInsen ) {\n\t\t\treturn this.iterator( 'column', function ( settings, column ) {\n\t\t\t\tvar preSearch = settings.aoPreSearchCols;\n\t\n\t\t\t\tif ( input === undefined ) {\n\t\t\t\t\t// get\n\t\t\t\t\treturn preSearch[ column ].sSearch;\n\t\t\t\t}\n\t\n\t\t\t\t// set\n\t\t\t\tif ( ! settings.oFeatures.bFilter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\t$.extend( preSearch[ column ], {\n\t\t\t\t\t\"sSearch\": input+\"\",\n\t\t\t\t\t\"bRegex\":  regex === null ? false : regex,\n\t\t\t\t\t\"bSmart\":  smart === null ? true  : smart,\n\t\t\t\t\t\"bCaseInsensitive\": caseInsen === null ? true : caseInsen\n\t\t\t\t} );\n\t\n\t\t\t\t_fnFilterComplete( settings, settings.oPreviousSearch, 1 );\n\t\t\t} );\n\t\t}\n\t);\n\t\n\t/*\n\t * State API methods\n\t */\n\t\n\t_api_register( 'state()', function () {\n\t\treturn this.context.length ?\n\t\t\tthis.context[0].oSavedState :\n\t\t\tnull;\n\t} );\n\t\n\t\n\t_api_register( 'state.clear()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t// Save an empty object\n\t\t\tsettings.fnStateSaveCallback.call( settings.oInstance, settings, {} );\n\t\t} );\n\t} );\n\t\n\t\n\t_api_register( 'state.loaded()', function () {\n\t\treturn this.context.length ?\n\t\t\tthis.context[0].oLoadedState :\n\t\t\tnull;\n\t} );\n\t\n\t\n\t_api_register( 'state.save()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnSaveState( settings );\n\t\t} );\n\t} );\n\t\n\t\n\t\n\t/**\n\t * Provide a common method for plug-ins to check the version of DataTables being\n\t * used, in order to ensure compatibility.\n\t *\n\t *  @param {string} version Version string to check for, in the format \"X.Y.Z\".\n\t *    Note that the formats \"X\" and \"X.Y\" are also acceptable.\n\t *  @returns {boolean} true if this version of DataTables is greater or equal to\n\t *    the required version, or false if this version of DataTales is not\n\t *    suitable\n\t *  @static\n\t *  @dtopt API-Static\n\t *\n\t *  @example\n\t *    alert( $.fn.dataTable.versionCheck( '1.9.0' ) );\n\t */\n\tDataTable.versionCheck = DataTable.fnVersionCheck = function( version )\n\t{\n\t\tvar aThis = DataTable.version.split('.');\n\t\tvar aThat = version.split('.');\n\t\tvar iThis, iThat;\n\t\n\t\tfor ( var i=0, iLen=aThat.length ; i<iLen ; i++ ) {\n\t\t\tiThis = parseInt( aThis[i], 10 ) || 0;\n\t\t\tiThat = parseInt( aThat[i], 10 ) || 0;\n\t\n\t\t\t// Parts are the same, keep comparing\n\t\t\tif (iThis === iThat) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\n\t\t\t// Parts are different, return immediately\n\t\t\treturn iThis > iThat;\n\t\t}\n\t\n\t\treturn true;\n\t};\n\t\n\t\n\t/**\n\t * Check if a `<table>` node is a DataTable table already or not.\n\t *\n\t *  @param {node|jquery|string} table Table node, jQuery object or jQuery\n\t *      selector for the table to test. Note that if more than more than one\n\t *      table is passed on, only the first will be checked\n\t *  @returns {boolean} true the table given is a DataTable, or false otherwise\n\t *  @static\n\t *  @dtopt API-Static\n\t *\n\t *  @example\n\t *    if ( ! $.fn.DataTable.isDataTable( '#example' ) ) {\n\t *      $('#example').dataTable();\n\t *    }\n\t */\n\tDataTable.isDataTable = DataTable.fnIsDataTable = function ( table )\n\t{\n\t\tvar t = $(table).get(0);\n\t\tvar is = false;\n\t\n\t\t$.each( DataTable.settings, function (i, o) {\n\t\t\tvar head = o.nScrollHead ? $('table', o.nScrollHead)[0] : null;\n\t\t\tvar foot = o.nScrollFoot ? $('table', o.nScrollFoot)[0] : null;\n\t\n\t\t\tif ( o.nTable === t || head === t || foot === t ) {\n\t\t\t\tis = true;\n\t\t\t}\n\t\t} );\n\t\n\t\treturn is;\n\t};\n\t\n\t\n\t/**\n\t * Get all DataTable tables that have been initialised - optionally you can\n\t * select to get only currently visible tables.\n\t *\n\t *  @param {boolean} [visible=false] Flag to indicate if you want all (default)\n\t *    or visible tables only.\n\t *  @returns {array} Array of `table` nodes (not DataTable instances) which are\n\t *    DataTables\n\t *  @static\n\t *  @dtopt API-Static\n\t *\n\t *  @example\n\t *    $.each( $.fn.dataTable.tables(true), function () {\n\t *      $(table).DataTable().columns.adjust();\n\t *    } );\n\t */\n\tDataTable.tables = DataTable.fnTables = function ( visible )\n\t{\n\t\treturn $.map( DataTable.settings, function (o) {\n\t\t\tif ( !visible || (visible && $(o.nTable).is(':visible')) ) {\n\t\t\t\treturn o.nTable;\n\t\t\t}\n\t\t} );\n\t};\n\t\n\t\n\t/**\n\t * DataTables utility methods\n\t * \n\t * This namespace provides helper methods that DataTables uses internally to\n\t * create a DataTable, but which are not exclusively used only for DataTables.\n\t * These methods can be used by extension authors to save the duplication of\n\t * code.\n\t *\n\t *  @namespace\n\t */\n\tDataTable.util = {\n\t\t/**\n\t\t * Throttle the calls to a function. Arguments and context are maintained\n\t\t * for the throttled function.\n\t\t *\n\t\t * @param {function} fn Function to be called\n\t\t * @param {integer} freq Call frequency in mS\n\t\t * @return {function} Wrapped function\n\t\t */\n\t\tthrottle: _fnThrottle,\n\t\n\t\n\t\t/**\n\t\t * Escape a string such that it can be used in a regular expression\n\t\t *\n\t\t *  @param {string} sVal string to escape\n\t\t *  @returns {string} escaped string\n\t\t */\n\t\tescapeRegex: _fnEscapeRegex\n\t};\n\t\n\t\n\t/**\n\t * Convert from camel case parameters to Hungarian notation. This is made public\n\t * for the extensions to provide the same ability as DataTables core to accept\n\t * either the 1.9 style Hungarian notation, or the 1.10+ style camelCase\n\t * parameters.\n\t *\n\t *  @param {object} src The model object which holds all parameters that can be\n\t *    mapped.\n\t *  @param {object} user The object to convert from camel case to Hungarian.\n\t *  @param {boolean} force When set to `true`, properties which already have a\n\t *    Hungarian value in the `user` object will be overwritten. Otherwise they\n\t *    won't be.\n\t */\n\tDataTable.camelToHungarian = _fnCamelToHungarian;\n\t\n\t\n\t\n\t/**\n\t *\n\t */\n\t_api_register( '$()', function ( selector, opts ) {\n\t\tvar\n\t\t\trows   = this.rows( opts ).nodes(), // Get all rows\n\t\t\tjqRows = $(rows);\n\t\n\t\treturn $( [].concat(\n\t\t\tjqRows.filter( selector ).toArray(),\n\t\t\tjqRows.find( selector ).toArray()\n\t\t) );\n\t} );\n\t\n\t\n\t// jQuery functions to operate on the tables\n\t$.each( [ 'on', 'one', 'off' ], function (i, key) {\n\t\t_api_register( key+'()', function ( /* event, handler */ ) {\n\t\t\tvar args = Array.prototype.slice.call(arguments);\n\t\n\t\t\t// Add the `dt` namespace automatically if it isn't already present\n\t\t\tif ( ! args[0].match(/\\.dt\\b/) ) {\n\t\t\t\targs[0] += '.dt';\n\t\t\t}\n\t\n\t\t\tvar inst = $( this.tables().nodes() );\n\t\t\tinst[key].apply( inst, args );\n\t\t\treturn this;\n\t\t} );\n\t} );\n\t\n\t\n\t_api_register( 'clear()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\t_fnClearTable( settings );\n\t\t} );\n\t} );\n\t\n\t\n\t_api_register( 'settings()', function () {\n\t\treturn new _Api( this.context, this.context );\n\t} );\n\t\n\t\n\t_api_register( 'init()', function () {\n\t\tvar ctx = this.context;\n\t\treturn ctx.length ? ctx[0].oInit : null;\n\t} );\n\t\n\t\n\t_api_register( 'data()', function () {\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\treturn _pluck( settings.aoData, '_aData' );\n\t\t} ).flatten();\n\t} );\n\t\n\t\n\t_api_register( 'destroy()', function ( remove ) {\n\t\tremove = remove || false;\n\t\n\t\treturn this.iterator( 'table', function ( settings ) {\n\t\t\tvar orig      = settings.nTableWrapper.parentNode;\n\t\t\tvar classes   = settings.oClasses;\n\t\t\tvar table     = settings.nTable;\n\t\t\tvar tbody     = settings.nTBody;\n\t\t\tvar thead     = settings.nTHead;\n\t\t\tvar tfoot     = settings.nTFoot;\n\t\t\tvar jqTable   = $(table);\n\t\t\tvar jqTbody   = $(tbody);\n\t\t\tvar jqWrapper = $(settings.nTableWrapper);\n\t\t\tvar rows      = $.map( settings.aoData, function (r) { return r.nTr; } );\n\t\t\tvar i, ien;\n\t\n\t\t\t// Flag to note that the table is currently being destroyed - no action\n\t\t\t// should be taken\n\t\t\tsettings.bDestroying = true;\n\t\n\t\t\t// Fire off the destroy callbacks for plug-ins etc\n\t\t\t_fnCallbackFire( settings, \"aoDestroyCallback\", \"destroy\", [settings] );\n\t\n\t\t\t// If not being removed from the document, make all columns visible\n\t\t\tif ( ! remove ) {\n\t\t\t\tnew _Api( settings ).columns().visible( true );\n\t\t\t}\n\t\n\t\t\t// Blitz all `DT` namespaced events (these are internal events, the\n\t\t\t// lowercase, `dt` events are user subscribed and they are responsible\n\t\t\t// for removing them\n\t\t\tjqWrapper.unbind('.DT').find(':not(tbody *)').unbind('.DT');\n\t\t\t$(window).unbind('.DT-'+settings.sInstance);\n\t\n\t\t\t// When scrolling we had to break the table up - restore it\n\t\t\tif ( table != thead.parentNode ) {\n\t\t\t\tjqTable.children('thead').detach();\n\t\t\t\tjqTable.append( thead );\n\t\t\t}\n\t\n\t\t\tif ( tfoot && table != tfoot.parentNode ) {\n\t\t\t\tjqTable.children('tfoot').detach();\n\t\t\t\tjqTable.append( tfoot );\n\t\t\t}\n\t\n\t\t\t// Remove the DataTables generated nodes, events and classes\n\t\t\tjqTable.detach();\n\t\t\tjqWrapper.detach();\n\t\n\t\t\tsettings.aaSorting = [];\n\t\t\tsettings.aaSortingFixed = [];\n\t\t\t_fnSortingClasses( settings );\n\t\n\t\t\t$( rows ).removeClass( settings.asStripeClasses.join(' ') );\n\t\n\t\t\t$('th, td', thead).removeClass( classes.sSortable+' '+\n\t\t\t\tclasses.sSortableAsc+' '+classes.sSortableDesc+' '+classes.sSortableNone\n\t\t\t);\n\t\n\t\t\tif ( settings.bJUI ) {\n\t\t\t\t$('th span.'+classes.sSortIcon+ ', td span.'+classes.sSortIcon, thead).detach();\n\t\t\t\t$('th, td', thead).each( function () {\n\t\t\t\t\tvar wrapper = $('div.'+classes.sSortJUIWrapper, this);\n\t\t\t\t\t$(this).append( wrapper.contents() );\n\t\t\t\t\twrapper.detach();\n\t\t\t\t} );\n\t\t\t}\n\t\n\t\t\tif ( ! remove && orig ) {\n\t\t\t\t// insertBefore acts like appendChild if !arg[1]\n\t\t\t\torig.insertBefore( table, settings.nTableReinsertBefore );\n\t\t\t}\n\t\n\t\t\t// Add the TR elements back into the table in their original order\n\t\t\tjqTbody.children().detach();\n\t\t\tjqTbody.append( rows );\n\t\n\t\t\t// Restore the width of the original table - was read from the style property,\n\t\t\t// so we can restore directly to that\n\t\t\tjqTable\n\t\t\t\t.css( 'width', settings.sDestroyWidth )\n\t\t\t\t.removeClass( classes.sTable );\n\t\n\t\t\t// If the were originally stripe classes - then we add them back here.\n\t\t\t// Note this is not fool proof (for example if not all rows had stripe\n\t\t\t// classes - but it's a good effort without getting carried away\n\t\t\tien = settings.asDestroyStripes.length;\n\t\n\t\t\tif ( ien ) {\n\t\t\t\tjqTbody.children().each( function (i) {\n\t\t\t\t\t$(this).addClass( settings.asDestroyStripes[i % ien] );\n\t\t\t\t} );\n\t\t\t}\n\t\n\t\t\t/* Remove the settings object from the settings array */\n\t\t\tvar idx = $.inArray( settings, DataTable.settings );\n\t\t\tif ( idx !== -1 ) {\n\t\t\t\tDataTable.settings.splice( idx, 1 );\n\t\t\t}\n\t\t} );\n\t} );\n\t\n\t\n\t// Add the `every()` method for rows, columns and cells in a compact form\n\t$.each( [ 'column', 'row', 'cell' ], function ( i, type ) {\n\t\t_api_register( type+'s().every()', function ( fn ) {\n\t\t\treturn this.iterator( type, function ( settings, idx, idx2 ) {\n\t\t\t\t// idx2 is undefined for rows and columns.\n\t\t\t\tfn.call( new _Api( settings )[ type ]( idx, idx2 ) );\n\t\t\t} );\n\t\t} );\n\t} );\n\t\n\t\n\t// i18n method for extensions to be able to use the language object from the\n\t// DataTable\n\t_api_register( 'i18n()', function ( token, def, plural ) {\n\t\tvar ctx = this.context[0];\n\t\tvar resolved = _fnGetObjectDataFn( token )( ctx.oLanguage );\n\t\n\t\tif ( resolved === undefined ) {\n\t\t\tresolved = def;\n\t\t}\n\t\n\t\tif ( plural !== undefined && $.isPlainObject( resolved ) ) {\n\t\t\tresolved = resolved[ plural ] !== undefined ?\n\t\t\t\tresolved[ plural ] :\n\t\t\t\tresolved._;\n\t\t}\n\t\n\t\treturn resolved.replace( '%d', plural ); // nb: plural might be undefined,\n\t} );\n\n\t/**\n\t * Version string for plug-ins to check compatibility. Allowed format is\n\t * `a.b.c-d` where: a:int, b:int, c:int, d:string(dev|beta|alpha). `d` is used\n\t * only for non-release builds. See http://semver.org/ for more information.\n\t *  @member\n\t *  @type string\n\t *  @default Version number\n\t */\n\tDataTable.version = \"1.10.7\";\n\n\t/**\n\t * Private data store, containing all of the settings objects that are\n\t * created for the tables on a given page.\n\t *\n\t * Note that the `DataTable.settings` object is aliased to\n\t * `jQuery.fn.dataTableExt` through which it may be accessed and\n\t * manipulated, or `jQuery.fn.dataTable.settings`.\n\t *  @member\n\t *  @type array\n\t *  @default []\n\t *  @private\n\t */\n\tDataTable.settings = [];\n\n\t/**\n\t * Object models container, for the various models that DataTables has\n\t * available to it. These models define the objects that are used to hold\n\t * the active state and configuration of the table.\n\t *  @namespace\n\t */\n\tDataTable.models = {};\n\t\n\t\n\t\n\t/**\n\t * Template object for the way in which DataTables holds information about\n\t * search information for the global filter and individual column filters.\n\t *  @namespace\n\t */\n\tDataTable.models.oSearch = {\n\t\t/**\n\t\t * Flag to indicate if the filtering should be case insensitive or not\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t */\n\t\t\"bCaseInsensitive\": true,\n\t\n\t\t/**\n\t\t * Applied search term\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t */\n\t\t\"sSearch\": \"\",\n\t\n\t\t/**\n\t\t * Flag to indicate if the search term should be interpreted as a\n\t\t * regular expression (true) or not (false) and therefore and special\n\t\t * regex characters escaped.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t */\n\t\t\"bRegex\": false,\n\t\n\t\t/**\n\t\t * Flag to indicate if DataTables is to use its smart filtering or not.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t */\n\t\t\"bSmart\": true\n\t};\n\t\n\t\n\t\n\t\n\t/**\n\t * Template object for the way in which DataTables holds information about\n\t * each individual row. This is the object format used for the settings\n\t * aoData array.\n\t *  @namespace\n\t */\n\tDataTable.models.oRow = {\n\t\t/**\n\t\t * TR element for the row\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTr\": null,\n\t\n\t\t/**\n\t\t * Array of TD elements for each row. This is null until the row has been\n\t\t * created.\n\t\t *  @type array nodes\n\t\t *  @default []\n\t\t */\n\t\t\"anCells\": null,\n\t\n\t\t/**\n\t\t * Data object from the original data source for the row. This is either\n\t\t * an array if using the traditional form of DataTables, or an object if\n\t\t * using mData options. The exact type will depend on the passed in\n\t\t * data from the data source, or will be an array if using DOM a data\n\t\t * source.\n\t\t *  @type array|object\n\t\t *  @default []\n\t\t */\n\t\t\"_aData\": [],\n\t\n\t\t/**\n\t\t * Sorting data cache - this array is ostensibly the same length as the\n\t\t * number of columns (although each index is generated only as it is\n\t\t * needed), and holds the data that is used for sorting each column in the\n\t\t * row. We do this cache generation at the start of the sort in order that\n\t\t * the formatting of the sort data need be done only once for each cell\n\t\t * per sort. This array should not be read from or written to by anything\n\t\t * other than the master sorting methods.\n\t\t *  @type array\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"_aSortData\": null,\n\t\n\t\t/**\n\t\t * Per cell filtering data cache. As per the sort data cache, used to\n\t\t * increase the performance of the filtering in DataTables\n\t\t *  @type array\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"_aFilterData\": null,\n\t\n\t\t/**\n\t\t * Filtering data cache. This is the same as the cell filtering cache, but\n\t\t * in this case a string rather than an array. This is easily computed with\n\t\t * a join on `_aFilterData`, but is provided as a cache so the join isn't\n\t\t * needed on every search (memory traded for performance)\n\t\t *  @type array\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"_sFilterRow\": null,\n\t\n\t\t/**\n\t\t * Cache of the class name that DataTables has applied to the row, so we\n\t\t * can quickly look at this variable rather than needing to do a DOM check\n\t\t * on className for the nTr property.\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t *  @private\n\t\t */\n\t\t\"_sRowStripe\": \"\",\n\t\n\t\t/**\n\t\t * Denote if the original data source was from the DOM, or the data source\n\t\t * object. This is used for invalidating data, so DataTables can\n\t\t * automatically read data from the original source, unless uninstructed\n\t\t * otherwise.\n\t\t *  @type string\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"src\": null\n\t};\n\t\n\t\n\t/**\n\t * Template object for the column information object in DataTables. This object\n\t * is held in the settings aoColumns array and contains all the information that\n\t * DataTables needs about each individual column.\n\t *\n\t * Note that this object is related to {@link DataTable.defaults.column}\n\t * but this one is the internal data store for DataTables's cache of columns.\n\t * It should NOT be manipulated outside of DataTables. Any configuration should\n\t * be done through the initialisation options.\n\t *  @namespace\n\t */\n\tDataTable.models.oColumn = {\n\t\t/**\n\t\t * Column index. This could be worked out on-the-fly with $.inArray, but it\n\t\t * is faster to just hold it as a variable\n\t\t *  @type integer\n\t\t *  @default null\n\t\t */\n\t\t\"idx\": null,\n\t\n\t\t/**\n\t\t * A list of the columns that sorting should occur on when this column\n\t\t * is sorted. That this property is an array allows multi-column sorting\n\t\t * to be defined for a column (for example first name / last name columns\n\t\t * would benefit from this). The values are integers pointing to the\n\t\t * columns to be sorted on (typically it will be a single integer pointing\n\t\t * at itself, but that doesn't need to be the case).\n\t\t *  @type array\n\t\t */\n\t\t\"aDataSort\": null,\n\t\n\t\t/**\n\t\t * Define the sorting directions that are applied to the column, in sequence\n\t\t * as the column is repeatedly sorted upon - i.e. the first value is used\n\t\t * as the sorting direction when the column if first sorted (clicked on).\n\t\t * Sort it again (click again) and it will move on to the next index.\n\t\t * Repeat until loop.\n\t\t *  @type array\n\t\t */\n\t\t\"asSorting\": null,\n\t\n\t\t/**\n\t\t * Flag to indicate if the column is searchable, and thus should be included\n\t\t * in the filtering or not.\n\t\t *  @type boolean\n\t\t */\n\t\t\"bSearchable\": null,\n\t\n\t\t/**\n\t\t * Flag to indicate if the column is sortable or not.\n\t\t *  @type boolean\n\t\t */\n\t\t\"bSortable\": null,\n\t\n\t\t/**\n\t\t * Flag to indicate if the column is currently visible in the table or not\n\t\t *  @type boolean\n\t\t */\n\t\t\"bVisible\": null,\n\t\n\t\t/**\n\t\t * Store for manual type assignment using the `column.type` option. This\n\t\t * is held in store so we can manipulate the column's `sType` property.\n\t\t *  @type string\n\t\t *  @default null\n\t\t *  @private\n\t\t */\n\t\t\"_sManualType\": null,\n\t\n\t\t/**\n\t\t * Flag to indicate if HTML5 data attributes should be used as the data\n\t\t * source for filtering or sorting. True is either are.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *  @private\n\t\t */\n\t\t\"_bAttrSrc\": false,\n\t\n\t\t/**\n\t\t * Developer definable function that is called whenever a cell is created (Ajax source,\n\t\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\n\t\t * allowing you to modify the DOM element (add background colour for example) when the\n\t\t * element is available.\n\t\t *  @type function\n\t\t *  @param {element} nTd The TD node that has been created\n\t\t *  @param {*} sData The Data for the cell\n\t\t *  @param {array|object} oData The data for the whole row\n\t\t *  @param {int} iRow The row index for the aoData data store\n\t\t *  @default null\n\t\t */\n\t\t\"fnCreatedCell\": null,\n\t\n\t\t/**\n\t\t * Function to get data from a cell in a column. You should <b>never</b>\n\t\t * access data directly through _aData internally in DataTables - always use\n\t\t * the method attached to this property. It allows mData to function as\n\t\t * required. This function is automatically assigned by the column\n\t\t * initialisation method\n\t\t *  @type function\n\t\t *  @param {array|object} oData The data array/object for the array\n\t\t *    (i.e. aoData[]._aData)\n\t\t *  @param {string} sSpecific The specific data type you want to get -\n\t\t *    'display', 'type' 'filter' 'sort'\n\t\t *  @returns {*} The data for the cell from the given row's data\n\t\t *  @default null\n\t\t */\n\t\t\"fnGetData\": null,\n\t\n\t\t/**\n\t\t * Function to set data for a cell in the column. You should <b>never</b>\n\t\t * set the data directly to _aData internally in DataTables - always use\n\t\t * this method. It allows mData to function as required. This function\n\t\t * is automatically assigned by the column initialisation method\n\t\t *  @type function\n\t\t *  @param {array|object} oData The data array/object for the array\n\t\t *    (i.e. aoData[]._aData)\n\t\t *  @param {*} sValue Value to set\n\t\t *  @default null\n\t\t */\n\t\t\"fnSetData\": null,\n\t\n\t\t/**\n\t\t * Property to read the value for the cells in the column from the data\n\t\t * source array / object. If null, then the default content is used, if a\n\t\t * function is given then the return from the function is used.\n\t\t *  @type function|int|string|null\n\t\t *  @default null\n\t\t */\n\t\t\"mData\": null,\n\t\n\t\t/**\n\t\t * Partner property to mData which is used (only when defined) to get\n\t\t * the data - i.e. it is basically the same as mData, but without the\n\t\t * 'set' option, and also the data fed to it is the result from mData.\n\t\t * This is the rendering method to match the data method of mData.\n\t\t *  @type function|int|string|null\n\t\t *  @default null\n\t\t */\n\t\t\"mRender\": null,\n\t\n\t\t/**\n\t\t * Unique header TH/TD element for this column - this is what the sorting\n\t\t * listener is attached to (if sorting is enabled.)\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTh\": null,\n\t\n\t\t/**\n\t\t * Unique footer TH/TD element for this column (if there is one). Not used\n\t\t * in DataTables as such, but can be used for plug-ins to reference the\n\t\t * footer for each column.\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTf\": null,\n\t\n\t\t/**\n\t\t * The class to apply to all TD elements in the table's TBODY for the column\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sClass\": null,\n\t\n\t\t/**\n\t\t * When DataTables calculates the column widths to assign to each column,\n\t\t * it finds the longest string in each column and then constructs a\n\t\t * temporary table and reads the widths from that. The problem with this\n\t\t * is that \"mmm\" is much wider then \"iiii\", but the latter is a longer\n\t\t * string - thus the calculation can go wrong (doing it properly and putting\n\t\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\n\t\t * a \"work around\" we provide this option. It will append its value to the\n\t\t * text that is found to be the longest string for the column - i.e. padding.\n\t\t *  @type string\n\t\t */\n\t\t\"sContentPadding\": null,\n\t\n\t\t/**\n\t\t * Allows a default value to be given for a column's data, and will be used\n\t\t * whenever a null data source is encountered (this can be because mData\n\t\t * is set to null, or because the data source itself is null).\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sDefaultContent\": null,\n\t\n\t\t/**\n\t\t * Name for the column, allowing reference to the column by name as well as\n\t\t * by index (needs a lookup to work by name).\n\t\t *  @type string\n\t\t */\n\t\t\"sName\": null,\n\t\n\t\t/**\n\t\t * Custom sorting data type - defines which of the available plug-ins in\n\t\t * afnSortData the custom sorting will use - if any is defined.\n\t\t *  @type string\n\t\t *  @default std\n\t\t */\n\t\t\"sSortDataType\": 'std',\n\t\n\t\t/**\n\t\t * Class to be applied to the header element when sorting on this column\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sSortingClass\": null,\n\t\n\t\t/**\n\t\t * Class to be applied to the header element when sorting on this column -\n\t\t * when jQuery UI theming is used.\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sSortingClassJUI\": null,\n\t\n\t\t/**\n\t\t * Title of the column - what is seen in the TH element (nTh).\n\t\t *  @type string\n\t\t */\n\t\t\"sTitle\": null,\n\t\n\t\t/**\n\t\t * Column sorting and filtering type\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sType\": null,\n\t\n\t\t/**\n\t\t * Width of the column\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sWidth\": null,\n\t\n\t\t/**\n\t\t * Width of the column when it was first \"encountered\"\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sWidthOrig\": null\n\t};\n\t\n\t\n\t/*\n\t * Developer note: The properties of the object below are given in Hungarian\n\t * notation, that was used as the interface for DataTables prior to v1.10, however\n\t * from v1.10 onwards the primary interface is camel case. In order to avoid\n\t * breaking backwards compatibility utterly with this change, the Hungarian\n\t * version is still, internally the primary interface, but is is not documented\n\t * - hence the @name tags in each doc comment. This allows a Javascript function\n\t * to create a map from Hungarian notation to camel case (going the other direction\n\t * would require each property to be listed, which would at around 3K to the size\n\t * of DataTables, while this method is about a 0.5K hit.\n\t *\n\t * Ultimately this does pave the way for Hungarian notation to be dropped\n\t * completely, but that is a massive amount of work and will break current\n\t * installs (therefore is on-hold until v2).\n\t */\n\t\n\t/**\n\t * Initialisation options that can be given to DataTables at initialisation\n\t * time.\n\t *  @namespace\n\t */\n\tDataTable.defaults = {\n\t\t/**\n\t\t * An array of data to use for the table, passed in at initialisation which\n\t\t * will be used in preference to any data which is already in the DOM. This is\n\t\t * particularly useful for constructing tables purely in Javascript, for\n\t\t * example with a custom Ajax call.\n\t\t *  @type array\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.data\n\t\t *\n\t\t *  @example\n\t\t *    // Using a 2D array data source\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"data\": [\n\t\t *          ['Trident', 'Internet Explorer 4.0', 'Win 95+', 4, 'X'],\n\t\t *          ['Trident', 'Internet Explorer 5.0', 'Win 95+', 5, 'C'],\n\t\t *        ],\n\t\t *        \"columns\": [\n\t\t *          { \"title\": \"Engine\" },\n\t\t *          { \"title\": \"Browser\" },\n\t\t *          { \"title\": \"Platform\" },\n\t\t *          { \"title\": \"Version\" },\n\t\t *          { \"title\": \"Grade\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using an array of objects as a data source (`data`)\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"data\": [\n\t\t *          {\n\t\t *            \"engine\":   \"Trident\",\n\t\t *            \"browser\":  \"Internet Explorer 4.0\",\n\t\t *            \"platform\": \"Win 95+\",\n\t\t *            \"version\":  4,\n\t\t *            \"grade\":    \"X\"\n\t\t *          },\n\t\t *          {\n\t\t *            \"engine\":   \"Trident\",\n\t\t *            \"browser\":  \"Internet Explorer 5.0\",\n\t\t *            \"platform\": \"Win 95+\",\n\t\t *            \"version\":  5,\n\t\t *            \"grade\":    \"C\"\n\t\t *          }\n\t\t *        ],\n\t\t *        \"columns\": [\n\t\t *          { \"title\": \"Engine\",   \"data\": \"engine\" },\n\t\t *          { \"title\": \"Browser\",  \"data\": \"browser\" },\n\t\t *          { \"title\": \"Platform\", \"data\": \"platform\" },\n\t\t *          { \"title\": \"Version\",  \"data\": \"version\" },\n\t\t *          { \"title\": \"Grade\",    \"data\": \"grade\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"aaData\": null,\n\t\n\t\n\t\t/**\n\t\t * If ordering is enabled, then DataTables will perform a first pass sort on\n\t\t * initialisation. You can define which column(s) the sort is performed\n\t\t * upon, and the sorting direction, with this variable. The `sorting` array\n\t\t * should contain an array for each column to be sorted initially containing\n\t\t * the column's index and a direction string ('asc' or 'desc').\n\t\t *  @type array\n\t\t *  @default [[0,'asc']]\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.order\n\t\t *\n\t\t *  @example\n\t\t *    // Sort by 3rd column first, and then 4th column\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"order\": [[2,'asc'], [3,'desc']]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *    // No initial sorting\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"order\": []\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"aaSorting\": [[0,'asc']],\n\t\n\t\n\t\t/**\n\t\t * This parameter is basically identical to the `sorting` parameter, but\n\t\t * cannot be overridden by user interaction with the table. What this means\n\t\t * is that you could have a column (visible or hidden) which the sorting\n\t\t * will always be forced on first - any sorting after that (from the user)\n\t\t * will then be performed as required. This can be useful for grouping rows\n\t\t * together.\n\t\t *  @type array\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.orderFixed\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"orderFixed\": [[0,'asc']]\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"aaSortingFixed\": [],\n\t\n\t\n\t\t/**\n\t\t * DataTables can be instructed to load data to display in the table from a\n\t\t * Ajax source. This option defines how that Ajax call is made and where to.\n\t\t *\n\t\t * The `ajax` property has three different modes of operation, depending on\n\t\t * how it is defined. These are:\n\t\t *\n\t\t * * `string` - Set the URL from where the data should be loaded from.\n\t\t * * `object` - Define properties for `jQuery.ajax`.\n\t\t * * `function` - Custom data get function\n\t\t *\n\t\t * `string`\n\t\t * --------\n\t\t *\n\t\t * As a string, the `ajax` property simply defines the URL from which\n\t\t * DataTables will load data.\n\t\t *\n\t\t * `object`\n\t\t * --------\n\t\t *\n\t\t * As an object, the parameters in the object are passed to\n\t\t * [jQuery.ajax](http://api.jquery.com/jQuery.ajax/) allowing fine control\n\t\t * of the Ajax request. DataTables has a number of default parameters which\n\t\t * you can override using this option. Please refer to the jQuery\n\t\t * documentation for a full description of the options available, although\n\t\t * the following parameters provide additional options in DataTables or\n\t\t * require special consideration:\n\t\t *\n\t\t * * `data` - As with jQuery, `data` can be provided as an object, but it\n\t\t *   can also be used as a function to manipulate the data DataTables sends\n\t\t *   to the server. The function takes a single parameter, an object of\n\t\t *   parameters with the values that DataTables has readied for sending. An\n\t\t *   object may be returned which will be merged into the DataTables\n\t\t *   defaults, or you can add the items to the object that was passed in and\n\t\t *   not return anything from the function. This supersedes `fnServerParams`\n\t\t *   from DataTables 1.9-.\n\t\t *\n\t\t * * `dataSrc` - By default DataTables will look for the property `data` (or\n\t\t *   `aaData` for compatibility with DataTables 1.9-) when obtaining data\n\t\t *   from an Ajax source or for server-side processing - this parameter\n\t\t *   allows that property to be changed. You can use Javascript dotted\n\t\t *   object notation to get a data source for multiple levels of nesting, or\n\t\t *   it my be used as a function. As a function it takes a single parameter,\n\t\t *   the JSON returned from the server, which can be manipulated as\n\t\t *   required, with the returned value being that used by DataTables as the\n\t\t *   data source for the table. This supersedes `sAjaxDataProp` from\n\t\t *   DataTables 1.9-.\n\t\t *\n\t\t * * `success` - Should not be overridden it is used internally in\n\t\t *   DataTables. To manipulate / transform the data returned by the server\n\t\t *   use `ajax.dataSrc`, or use `ajax` as a function (see below).\n\t\t *\n\t\t * `function`\n\t\t * ----------\n\t\t *\n\t\t * As a function, making the Ajax call is left up to yourself allowing\n\t\t * complete control of the Ajax request. Indeed, if desired, a method other\n\t\t * than Ajax could be used to obtain the required data, such as Web storage\n\t\t * or an AIR database.\n\t\t *\n\t\t * The function is given four parameters and no return is required. The\n\t\t * parameters are:\n\t\t *\n\t\t * 1. _object_ - Data to send to the server\n\t\t * 2. _function_ - Callback function that must be executed when the required\n\t\t *    data has been obtained. That data should be passed into the callback\n\t\t *    as the only parameter\n\t\t * 3. _object_ - DataTables settings object for the table\n\t\t *\n\t\t * Note that this supersedes `fnServerData` from DataTables 1.9-.\n\t\t *\n\t\t *  @type string|object|function\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.ajax\n\t\t *  @since 1.10.0\n\t\t *\n\t\t * @example\n\t\t *   // Get JSON data from a file via Ajax.\n\t\t *   // Note DataTables expects data in the form `{ data: [ ...data... ] }` by default).\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": \"data.json\"\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Get JSON data from a file via Ajax, using `dataSrc` to change\n\t\t *   // `data` to `tableData` (i.e. `{ tableData: [ ...data... ] }`)\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"dataSrc\": \"tableData\"\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Get JSON data from a file via Ajax, using `dataSrc` to read data\n\t\t *   // from a plain array rather than an array in an object\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"dataSrc\": \"\"\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Manipulate the data returned from the server - add a link to data\n\t\t *   // (note this can, should, be done using `render` for the column - this\n\t\t *   // is just a simple example of how the data can be manipulated).\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"dataSrc\": function ( json ) {\n\t\t *         for ( var i=0, ien=json.length ; i<ien ; i++ ) {\n\t\t *           json[i][0] = '<a href=\"/message/'+json[i][0]+'>View message</a>';\n\t\t *         }\n\t\t *         return json;\n\t\t *       }\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Add data to the request\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"data\": function ( d ) {\n\t\t *         return {\n\t\t *           \"extra_search\": $('#extra').val()\n\t\t *         };\n\t\t *       }\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Send request as POST\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": {\n\t\t *       \"url\": \"data.json\",\n\t\t *       \"type\": \"POST\"\n\t\t *     }\n\t\t *   } );\n\t\t *\n\t\t * @example\n\t\t *   // Get the data from localStorage (could interface with a form for\n\t\t *   // adding, editing and removing rows).\n\t\t *   $('#example').dataTable( {\n\t\t *     \"ajax\": function (data, callback, settings) {\n\t\t *       callback(\n\t\t *         JSON.parse( localStorage.getItem('dataTablesData') )\n\t\t *       );\n\t\t *     }\n\t\t *   } );\n\t\t */\n\t\t\"ajax\": null,\n\t\n\t\n\t\t/**\n\t\t * This parameter allows you to readily specify the entries in the length drop\n\t\t * down menu that DataTables shows when pagination is enabled. It can be\n\t\t * either a 1D array of options which will be used for both the displayed\n\t\t * option and the value, or a 2D array which will use the array in the first\n\t\t * position as the value, and the array in the second position as the\n\t\t * displayed options (useful for language strings such as 'All').\n\t\t *\n\t\t * Note that the `pageLength` property will be automatically set to the\n\t\t * first value given in this array, unless `pageLength` is also provided.\n\t\t *  @type array\n\t\t *  @default [ 10, 25, 50, 100 ]\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.lengthMenu\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"lengthMenu\": [[10, 25, 50, -1], [10, 25, 50, \"All\"]]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"aLengthMenu\": [ 10, 25, 50, 100 ],\n\t\n\t\n\t\t/**\n\t\t * The `columns` option in the initialisation parameter allows you to define\n\t\t * details about the way individual columns behave. For a full list of\n\t\t * column options that can be set, please see\n\t\t * {@link DataTable.defaults.column}. Note that if you use `columns` to\n\t\t * define your columns, you must have an entry in the array for every single\n\t\t * column that you have in your table (these can be null if you don't which\n\t\t * to specify any options).\n\t\t *  @member\n\t\t *\n\t\t *  @name DataTable.defaults.column\n\t\t */\n\t\t\"aoColumns\": null,\n\t\n\t\t/**\n\t\t * Very similar to `columns`, `columnDefs` allows you to target a specific\n\t\t * column, multiple columns, or all columns, using the `targets` property of\n\t\t * each object in the array. This allows great flexibility when creating\n\t\t * tables, as the `columnDefs` arrays can be of any length, targeting the\n\t\t * columns you specifically want. `columnDefs` may use any of the column\n\t\t * options available: {@link DataTable.defaults.column}, but it _must_\n\t\t * have `targets` defined in each object in the array. Values in the `targets`\n\t\t * array may be:\n\t\t *   <ul>\n\t\t *     <li>a string - class name will be matched on the TH for the column</li>\n\t\t *     <li>0 or a positive integer - column index counting from the left</li>\n\t\t *     <li>a negative integer - column index counting from the right</li>\n\t\t *     <li>the string \"_all\" - all columns (i.e. assign a default)</li>\n\t\t *   </ul>\n\t\t *  @member\n\t\t *\n\t\t *  @name DataTable.defaults.columnDefs\n\t\t */\n\t\t\"aoColumnDefs\": null,\n\t\n\t\n\t\t/**\n\t\t * Basically the same as `search`, this parameter defines the individual column\n\t\t * filtering state at initialisation time. The array must be of the same size\n\t\t * as the number of columns, and each element be an object with the parameters\n\t\t * `search` and `escapeRegex` (the latter is optional). 'null' is also\n\t\t * accepted and the default will be used.\n\t\t *  @type array\n\t\t *  @default []\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.searchCols\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"searchCols\": [\n\t\t *          null,\n\t\t *          { \"search\": \"My filter\" },\n\t\t *          null,\n\t\t *          { \"search\": \"^[0-9]\", \"escapeRegex\": false }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"aoSearchCols\": [],\n\t\n\t\n\t\t/**\n\t\t * An array of CSS classes that should be applied to displayed rows. This\n\t\t * array may be of any length, and DataTables will apply each class\n\t\t * sequentially, looping when required.\n\t\t *  @type array\n\t\t *  @default null <i>Will take the values determined by the `oClasses.stripe*`\n\t\t *    options</i>\n\t\t *\n\t\t *  @dtopt Option\n\t\t *  @name DataTable.defaults.stripeClasses\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stripeClasses\": [ 'strip1', 'strip2', 'strip3' ]\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"asStripeClasses\": null,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable automatic column width calculation. This can be disabled\n\t\t * as an optimisation (it takes some time to calculate the widths) if the\n\t\t * tables widths are passed in using `columns`.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.autoWidth\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"autoWidth\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bAutoWidth\": true,\n\t\n\t\n\t\t/**\n\t\t * Deferred rendering can provide DataTables with a huge speed boost when you\n\t\t * are using an Ajax or JS data source for the table. This option, when set to\n\t\t * true, will cause DataTables to defer the creation of the table elements for\n\t\t * each row until they are needed for a draw - saving a significant amount of\n\t\t * time.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.deferRender\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ajax\": \"sources/arrays.txt\",\n\t\t *        \"deferRender\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bDeferRender\": false,\n\t\n\t\n\t\t/**\n\t\t * Replace a DataTable which matches the given selector and replace it with\n\t\t * one which has the properties of the new initialisation object passed. If no\n\t\t * table matches the selector, then the new DataTable will be constructed as\n\t\t * per normal.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.destroy\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"srollY\": \"200px\",\n\t\t *        \"paginate\": false\n\t\t *      } );\n\t\t *\n\t\t *      // Some time later....\n\t\t *      $('#example').dataTable( {\n\t\t *        \"filter\": false,\n\t\t *        \"destroy\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bDestroy\": false,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable filtering of data. Filtering in DataTables is \"smart\" in\n\t\t * that it allows the end user to input multiple words (space separated) and\n\t\t * will match a row containing those words, even if not in the order that was\n\t\t * specified (this allow matching across multiple columns). Note that if you\n\t\t * wish to use filtering in DataTables this must remain 'true' - to remove the\n\t\t * default filtering input box and retain filtering abilities, please use\n\t\t * {@link DataTable.defaults.dom}.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.searching\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"searching\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bFilter\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable the table information display. This shows information\n\t\t * about the data that is currently visible on the page, including information\n\t\t * about filtered data if that action is being performed.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.info\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"info\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bInfo\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable jQuery UI ThemeRoller support (required as ThemeRoller requires some\n\t\t * slightly different and additional mark-up from what DataTables has\n\t\t * traditionally used).\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.jQueryUI\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"jQueryUI\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bJQueryUI\": false,\n\t\n\t\n\t\t/**\n\t\t * Allows the end user to select the size of a formatted page from a select\n\t\t * menu (sizes are 10, 25, 50 and 100). Requires pagination (`paginate`).\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.lengthChange\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"lengthChange\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bLengthChange\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable pagination.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.paging\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"paging\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bPaginate\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable the display of a 'processing' indicator when the table is\n\t\t * being processed (e.g. a sort). This is particularly useful for tables with\n\t\t * large amounts of data where it can take a noticeable amount of time to sort\n\t\t * the entries.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.processing\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"processing\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bProcessing\": false,\n\t\n\t\n\t\t/**\n\t\t * Retrieve the DataTables object for the given selector. Note that if the\n\t\t * table has already been initialised, this parameter will cause DataTables\n\t\t * to simply return the object that has already been set up - it will not take\n\t\t * account of any changes you might have made to the initialisation object\n\t\t * passed to DataTables (setting this parameter to true is an acknowledgement\n\t\t * that you understand this). `destroy` can be used to reinitialise a table if\n\t\t * you need.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.retrieve\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      initTable();\n\t\t *      tableActions();\n\t\t *    } );\n\t\t *\n\t\t *    function initTable ()\n\t\t *    {\n\t\t *      return $('#example').dataTable( {\n\t\t *        \"scrollY\": \"200px\",\n\t\t *        \"paginate\": false,\n\t\t *        \"retrieve\": true\n\t\t *      } );\n\t\t *    }\n\t\t *\n\t\t *    function tableActions ()\n\t\t *    {\n\t\t *      var table = initTable();\n\t\t *      // perform API operations with oTable\n\t\t *    }\n\t\t */\n\t\t\"bRetrieve\": false,\n\t\n\t\n\t\t/**\n\t\t * When vertical (y) scrolling is enabled, DataTables will force the height of\n\t\t * the table's viewport to the given height at all times (useful for layout).\n\t\t * However, this can look odd when filtering data down to a small data set,\n\t\t * and the footer is left \"floating\" further down. This parameter (when\n\t\t * enabled) will cause DataTables to collapse the table's viewport down when\n\t\t * the result set will fit within the given Y height.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.scrollCollapse\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"scrollY\": \"200\",\n\t\t *        \"scrollCollapse\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bScrollCollapse\": false,\n\t\n\t\n\t\t/**\n\t\t * Configure DataTables to use server-side processing. Note that the\n\t\t * `ajax` parameter must also be given in order to give DataTables a\n\t\t * source to obtain the required data for each draw.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.serverSide\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"serverSide\": true,\n\t\t *        \"ajax\": \"xhr.php\"\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bServerSide\": false,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable sorting of columns. Sorting of individual columns can be\n\t\t * disabled by the `sortable` option for each column.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.ordering\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ordering\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bSort\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or display DataTables' ability to sort multiple columns at the\n\t\t * same time (activated by shift-click by the user).\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.orderMulti\n\t\t *\n\t\t *  @example\n\t\t *    // Disable multiple column sorting ability\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"orderMulti\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bSortMulti\": true,\n\t\n\t\n\t\t/**\n\t\t * Allows control over whether DataTables should use the top (true) unique\n\t\t * cell that is found for a single column, or the bottom (false - default).\n\t\t * This is useful when using complex headers.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.orderCellsTop\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"orderCellsTop\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bSortCellsTop\": false,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable the addition of the classes `sorting\\_1`, `sorting\\_2` and\n\t\t * `sorting\\_3` to the columns which are currently being sorted on. This is\n\t\t * presented as a feature switch as it can increase processing time (while\n\t\t * classes are removed and added) so for large data sets you might want to\n\t\t * turn this off.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.orderClasses\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"orderClasses\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bSortClasses\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable state saving. When enabled HTML5 `localStorage` will be\n\t\t * used to save table display information such as pagination information,\n\t\t * display length, filtering and sorting. As such when the end user reloads\n\t\t * the page the display display will match what thy had previously set up.\n\t\t *\n\t\t * Due to the use of `localStorage` the default state saving is not supported\n\t\t * in IE6 or 7. If state saving is required in those browsers, use\n\t\t * `stateSaveCallback` to provide a storage solution such as cookies.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.stateSave\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function () {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"bStateSave\": false,\n\t\n\t\n\t\t/**\n\t\t * This function is called when a TR element is created (and all TD child\n\t\t * elements have been inserted), or registered if using a DOM source, allowing\n\t\t * manipulation of the TR element (adding classes etc).\n\t\t *  @type function\n\t\t *  @param {node} row \"TR\" element for the current row\n\t\t *  @param {array} data Raw data array for this row\n\t\t *  @param {int} dataIndex The index of this row in the internal aoData array\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.createdRow\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"createdRow\": function( row, data, dataIndex ) {\n\t\t *          // Bold the grade for all 'A' grade browsers\n\t\t *          if ( data[4] == \"A\" )\n\t\t *          {\n\t\t *            $('td:eq(4)', row).html( '<b>A</b>' );\n\t\t *          }\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnCreatedRow\": null,\n\t\n\t\n\t\t/**\n\t\t * This function is called on every 'draw' event, and allows you to\n\t\t * dynamically modify any aspect you want about the created DOM.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.drawCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"drawCallback\": function( settings ) {\n\t\t *          alert( 'DataTables has redrawn the table' );\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnDrawCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * Identical to fnHeaderCallback() but for the table footer this function\n\t\t * allows you to modify the table footer on every 'draw' event.\n\t\t *  @type function\n\t\t *  @param {node} foot \"TR\" element for the footer\n\t\t *  @param {array} data Full table data (as derived from the original HTML)\n\t\t *  @param {int} start Index for the current display starting point in the\n\t\t *    display array\n\t\t *  @param {int} end Index for the current display ending point in the\n\t\t *    display array\n\t\t *  @param {array int} display Index array to translate the visual position\n\t\t *    to the full data array\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.footerCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"footerCallback\": function( tfoot, data, start, end, display ) {\n\t\t *          tfoot.getElementsByTagName('th')[0].innerHTML = \"Starting index is \"+start;\n\t\t *        }\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"fnFooterCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * When rendering large numbers in the information element for the table\n\t\t * (i.e. \"Showing 1 to 10 of 57 entries\") DataTables will render large numbers\n\t\t * to have a comma separator for the 'thousands' units (e.g. 1 million is\n\t\t * rendered as \"1,000,000\") to help readability for the end user. This\n\t\t * function will override the default method DataTables uses.\n\t\t *  @type function\n\t\t *  @member\n\t\t *  @param {int} toFormat number to be formatted\n\t\t *  @returns {string} formatted string for DataTables to show the number\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.formatNumber\n\t\t *\n\t\t *  @example\n\t\t *    // Format a number using a single quote for the separator (note that\n\t\t *    // this can also be done with the language.thousands option)\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"formatNumber\": function ( toFormat ) {\n\t\t *          return toFormat.toString().replace(\n\t\t *            /\\B(?=(\\d{3})+(?!\\d))/g, \"'\"\n\t\t *          );\n\t\t *        };\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnFormatNumber\": function ( toFormat ) {\n\t\t\treturn toFormat.toString().replace(\n\t\t\t\t/\\B(?=(\\d{3})+(?!\\d))/g,\n\t\t\t\tthis.oLanguage.sThousands\n\t\t\t);\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * This function is called on every 'draw' event, and allows you to\n\t\t * dynamically modify the header row. This can be used to calculate and\n\t\t * display useful information about the table.\n\t\t *  @type function\n\t\t *  @param {node} head \"TR\" element for the header\n\t\t *  @param {array} data Full table data (as derived from the original HTML)\n\t\t *  @param {int} start Index for the current display starting point in the\n\t\t *    display array\n\t\t *  @param {int} end Index for the current display ending point in the\n\t\t *    display array\n\t\t *  @param {array int} display Index array to translate the visual position\n\t\t *    to the full data array\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.headerCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"fheaderCallback\": function( head, data, start, end, display ) {\n\t\t *          head.getElementsByTagName('th')[0].innerHTML = \"Displaying \"+(end-start)+\" records\";\n\t\t *        }\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"fnHeaderCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * The information element can be used to convey information about the current\n\t\t * state of the table. Although the internationalisation options presented by\n\t\t * DataTables are quite capable of dealing with most customisations, there may\n\t\t * be times where you wish to customise the string further. This callback\n\t\t * allows you to do exactly that.\n\t\t *  @type function\n\t\t *  @param {object} oSettings DataTables settings object\n\t\t *  @param {int} start Starting position in data for the draw\n\t\t *  @param {int} end End position in data for the draw\n\t\t *  @param {int} max Total number of rows in the table (regardless of\n\t\t *    filtering)\n\t\t *  @param {int} total Total number of rows in the data set, after filtering\n\t\t *  @param {string} pre The string that DataTables has formatted using it's\n\t\t *    own rules\n\t\t *  @returns {string} The string to be displayed in the information element.\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.infoCallback\n\t\t *\n\t\t *  @example\n\t\t *    $('#example').dataTable( {\n\t\t *      \"infoCallback\": function( settings, start, end, max, total, pre ) {\n\t\t *        return start +\" to \"+ end;\n\t\t *      }\n\t\t *    } );\n\t\t */\n\t\t\"fnInfoCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * Called when the table has been initialised. Normally DataTables will\n\t\t * initialise sequentially and there will be no need for this function,\n\t\t * however, this does not hold true when using external language information\n\t\t * since that is obtained using an async XHR call.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} json The JSON object request from the server - only\n\t\t *    present if client-side Ajax sourced data is used\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.initComplete\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"initComplete\": function(settings, json) {\n\t\t *          alert( 'DataTables has finished its initialisation.' );\n\t\t *        }\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"fnInitComplete\": null,\n\t\n\t\n\t\t/**\n\t\t * Called at the very start of each table draw and can be used to cancel the\n\t\t * draw by returning false, any other return (including undefined) results in\n\t\t * the full draw occurring).\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @returns {boolean} False will cancel the draw, anything else (including no\n\t\t *    return) will allow it to complete.\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.preDrawCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"preDrawCallback\": function( settings ) {\n\t\t *          if ( $('#test').val() == 1 ) {\n\t\t *            return false;\n\t\t *          }\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnPreDrawCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * This function allows you to 'post process' each row after it have been\n\t\t * generated for each table draw, but before it is rendered on screen. This\n\t\t * function might be used for setting the row class name etc.\n\t\t *  @type function\n\t\t *  @param {node} row \"TR\" element for the current row\n\t\t *  @param {array} data Raw data array for this row\n\t\t *  @param {int} displayIndex The display index for the current table draw\n\t\t *  @param {int} displayIndexFull The index of the data in the full list of\n\t\t *    rows (after filtering)\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.rowCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"rowCallback\": function( row, data, displayIndex, displayIndexFull ) {\n\t\t *          // Bold the grade for all 'A' grade browsers\n\t\t *          if ( data[4] == \"A\" ) {\n\t\t *            $('td:eq(4)', row).html( '<b>A</b>' );\n\t\t *          }\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnRowCallback\": null,\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t * This parameter allows you to override the default function which obtains\n\t\t * the data from the server so something more suitable for your application.\n\t\t * For example you could use POST data, or pull information from a Gears or\n\t\t * AIR database.\n\t\t *  @type function\n\t\t *  @member\n\t\t *  @param {string} source HTTP source to obtain the data from (`ajax`)\n\t\t *  @param {array} data A key/value pair object containing the data to send\n\t\t *    to the server\n\t\t *  @param {function} callback to be called on completion of the data get\n\t\t *    process that will draw the data on the page.\n\t\t *  @param {object} settings DataTables settings object\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.serverData\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"fnServerData\": null,\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t *  It is often useful to send extra data to the server when making an Ajax\n\t\t * request - for example custom filtering information, and this callback\n\t\t * function makes it trivial to send extra information to the server. The\n\t\t * passed in parameter is the data set that has been constructed by\n\t\t * DataTables, and you can add to this or modify it as you require.\n\t\t *  @type function\n\t\t *  @param {array} data Data array (array of objects which are name/value\n\t\t *    pairs) that has been constructed by DataTables and will be sent to the\n\t\t *    server. In the case of Ajax sourced data with server-side processing\n\t\t *    this will be an empty array, for server-side processing there will be a\n\t\t *    significant number of parameters!\n\t\t *  @returns {undefined} Ensure that you modify the data array passed in,\n\t\t *    as this is passed by reference.\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.serverParams\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"fnServerParams\": null,\n\t\n\t\n\t\t/**\n\t\t * Load the table state. With this function you can define from where, and how, the\n\t\t * state of a table is loaded. By default DataTables will load from `localStorage`\n\t\t * but you might wish to use a server-side database or cookies.\n\t\t *  @type function\n\t\t *  @member\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @return {object} The DataTables state object to be loaded\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateLoadCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateLoadCallback\": function (settings) {\n\t\t *          var o;\n\t\t *\n\t\t *          // Send an Ajax request to the server to get the data. Note that\n\t\t *          // this is a synchronous request.\n\t\t *          $.ajax( {\n\t\t *            \"url\": \"/state_load\",\n\t\t *            \"async\": false,\n\t\t *            \"dataType\": \"json\",\n\t\t *            \"success\": function (json) {\n\t\t *              o = json;\n\t\t *            }\n\t\t *          } );\n\t\t *\n\t\t *          return o;\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateLoadCallback\": function ( settings ) {\n\t\t\ttry {\n\t\t\t\treturn JSON.parse(\n\t\t\t\t\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).getItem(\n\t\t\t\t\t\t'DataTables_'+settings.sInstance+'_'+location.pathname\n\t\t\t\t\t)\n\t\t\t\t);\n\t\t\t} catch (e) {}\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Callback which allows modification of the saved state prior to loading that state.\n\t\t * This callback is called when the table is loading state from the stored data, but\n\t\t * prior to the settings object being modified by the saved state. Note that for\n\t\t * plug-in authors, you should use the `stateLoadParams` event to load parameters for\n\t\t * a plug-in.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} data The state object that is to be loaded\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateLoadParams\n\t\t *\n\t\t *  @example\n\t\t *    // Remove a saved filter, so filtering is never loaded\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateLoadParams\": function (settings, data) {\n\t\t *          data.oSearch.sSearch = \"\";\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Disallow state loading by returning false\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateLoadParams\": function (settings, data) {\n\t\t *          return false;\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateLoadParams\": null,\n\t\n\t\n\t\t/**\n\t\t * Callback that is called when the state has been loaded from the state saving method\n\t\t * and the DataTables settings object has been modified as a result of the loaded state.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} data The state object that was loaded\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateLoaded\n\t\t *\n\t\t *  @example\n\t\t *    // Show an alert with the filtering value that was saved\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateLoaded\": function (settings, data) {\n\t\t *          alert( 'Saved filter was: '+data.oSearch.sSearch );\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateLoaded\": null,\n\t\n\t\n\t\t/**\n\t\t * Save the table state. This function allows you to define where and how the state\n\t\t * information for the table is stored By default DataTables will use `localStorage`\n\t\t * but you might wish to use a server-side database or cookies.\n\t\t *  @type function\n\t\t *  @member\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} data The state object to be saved\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateSaveCallback\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateSaveCallback\": function (settings, data) {\n\t\t *          // Send an Ajax request to the server with the state object\n\t\t *          $.ajax( {\n\t\t *            \"url\": \"/state_save\",\n\t\t *            \"data\": data,\n\t\t *            \"dataType\": \"json\",\n\t\t *            \"method\": \"POST\"\n\t\t *            \"success\": function () {}\n\t\t *          } );\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateSaveCallback\": function ( settings, data ) {\n\t\t\ttry {\n\t\t\t\t(settings.iStateDuration === -1 ? sessionStorage : localStorage).setItem(\n\t\t\t\t\t'DataTables_'+settings.sInstance+'_'+location.pathname,\n\t\t\t\t\tJSON.stringify( data )\n\t\t\t\t);\n\t\t\t} catch (e) {}\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Callback which allows modification of the state to be saved. Called when the table\n\t\t * has changed state a new state save is required. This method allows modification of\n\t\t * the state saving object prior to actually doing the save, including addition or\n\t\t * other state properties or modification. Note that for plug-in authors, you should\n\t\t * use the `stateSaveParams` event to save parameters for a plug-in.\n\t\t *  @type function\n\t\t *  @param {object} settings DataTables settings object\n\t\t *  @param {object} data The state object to be saved\n\t\t *\n\t\t *  @dtopt Callbacks\n\t\t *  @name DataTable.defaults.stateSaveParams\n\t\t *\n\t\t *  @example\n\t\t *    // Remove a saved filter, so filtering is never saved\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateSave\": true,\n\t\t *        \"stateSaveParams\": function (settings, data) {\n\t\t *          data.oSearch.sSearch = \"\";\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"fnStateSaveParams\": null,\n\t\n\t\n\t\t/**\n\t\t * Duration for which the saved state information is considered valid. After this period\n\t\t * has elapsed the state will be returned to the default.\n\t\t * Value is given in seconds.\n\t\t *  @type int\n\t\t *  @default 7200 <i>(2 hours)</i>\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.stateDuration\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"stateDuration\": 60*60*24; // 1 day\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"iStateDuration\": 7200,\n\t\n\t\n\t\t/**\n\t\t * When enabled DataTables will not make a request to the server for the first\n\t\t * page draw - rather it will use the data already on the page (no sorting etc\n\t\t * will be applied to it), thus saving on an XHR at load time. `deferLoading`\n\t\t * is used to indicate that deferred loading is required, but it is also used\n\t\t * to tell DataTables how many records there are in the full table (allowing\n\t\t * the information element and pagination to be displayed correctly). In the case\n\t\t * where a filtering is applied to the table on initial load, this can be\n\t\t * indicated by giving the parameter as an array, where the first element is\n\t\t * the number of records available after filtering and the second element is the\n\t\t * number of records without filtering (allowing the table information element\n\t\t * to be shown correctly).\n\t\t *  @type int | array\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.deferLoading\n\t\t *\n\t\t *  @example\n\t\t *    // 57 records available in the table, no filtering applied\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"serverSide\": true,\n\t\t *        \"ajax\": \"scripts/server_processing.php\",\n\t\t *        \"deferLoading\": 57\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // 57 records after filtering, 100 without filtering (an initial filter applied)\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"serverSide\": true,\n\t\t *        \"ajax\": \"scripts/server_processing.php\",\n\t\t *        \"deferLoading\": [ 57, 100 ],\n\t\t *        \"search\": {\n\t\t *          \"search\": \"my_filter\"\n\t\t *        }\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"iDeferLoading\": null,\n\t\n\t\n\t\t/**\n\t\t * Number of rows to display on a single page when using pagination. If\n\t\t * feature enabled (`lengthChange`) then the end user will be able to override\n\t\t * this to a custom setting using a pop-up menu.\n\t\t *  @type int\n\t\t *  @default 10\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.pageLength\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"pageLength\": 50\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"iDisplayLength\": 10,\n\t\n\t\n\t\t/**\n\t\t * Define the starting point for data display when using DataTables with\n\t\t * pagination. Note that this parameter is the number of records, rather than\n\t\t * the page number, so if you have 10 records per page and want to start on\n\t\t * the third page, it should be \"20\".\n\t\t *  @type int\n\t\t *  @default 0\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.displayStart\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"displayStart\": 20\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"iDisplayStart\": 0,\n\t\n\t\n\t\t/**\n\t\t * By default DataTables allows keyboard navigation of the table (sorting, paging,\n\t\t * and filtering) by adding a `tabindex` attribute to the required elements. This\n\t\t * allows you to tab through the controls and press the enter key to activate them.\n\t\t * The tabindex is default 0, meaning that the tab follows the flow of the document.\n\t\t * You can overrule this using this parameter if you wish. Use a value of -1 to\n\t\t * disable built-in keyboard navigation.\n\t\t *  @type int\n\t\t *  @default 0\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.tabIndex\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"tabIndex\": 1\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"iTabIndex\": 0,\n\t\n\t\n\t\t/**\n\t\t * Classes that DataTables assigns to the various components and features\n\t\t * that it adds to the HTML table. This allows classes to be configured\n\t\t * during initialisation in addition to through the static\n\t\t * {@link DataTable.ext.oStdClasses} object).\n\t\t *  @namespace\n\t\t *  @name DataTable.defaults.classes\n\t\t */\n\t\t\"oClasses\": {},\n\t\n\t\n\t\t/**\n\t\t * All strings that DataTables uses in the user interface that it creates\n\t\t * are defined in this object, allowing you to modified them individually or\n\t\t * completely replace them all as required.\n\t\t *  @namespace\n\t\t *  @name DataTable.defaults.language\n\t\t */\n\t\t\"oLanguage\": {\n\t\t\t/**\n\t\t\t * Strings that are used for WAI-ARIA labels and controls only (these are not\n\t\t\t * actually visible on the page, but will be read by screenreaders, and thus\n\t\t\t * must be internationalised as well).\n\t\t\t *  @namespace\n\t\t\t *  @name DataTable.defaults.language.aria\n\t\t\t */\n\t\t\t\"oAria\": {\n\t\t\t\t/**\n\t\t\t\t * ARIA label that is added to the table headers when the column may be\n\t\t\t\t * sorted ascending by activing the column (click or return when focused).\n\t\t\t\t * Note that the column header is prefixed to this string.\n\t\t\t\t *  @type string\n\t\t\t\t *  @default : activate to sort column ascending\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.aria.sortAscending\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"aria\": {\n\t\t\t\t *            \"sortAscending\": \" - click/return to sort ascending\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sSortAscending\": \": activate to sort column ascending\",\n\t\n\t\t\t\t/**\n\t\t\t\t * ARIA label that is added to the table headers when the column may be\n\t\t\t\t * sorted descending by activing the column (click or return when focused).\n\t\t\t\t * Note that the column header is prefixed to this string.\n\t\t\t\t *  @type string\n\t\t\t\t *  @default : activate to sort column ascending\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.aria.sortDescending\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"aria\": {\n\t\t\t\t *            \"sortDescending\": \" - click/return to sort descending\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sSortDescending\": \": activate to sort column descending\"\n\t\t\t},\n\t\n\t\t\t/**\n\t\t\t * Pagination string used by DataTables for the built-in pagination\n\t\t\t * control types.\n\t\t\t *  @namespace\n\t\t\t *  @name DataTable.defaults.language.paginate\n\t\t\t */\n\t\t\t\"oPaginate\": {\n\t\t\t\t/**\n\t\t\t\t * Text to use when using the 'full_numbers' type of pagination for the\n\t\t\t\t * button to take the user to the first page.\n\t\t\t\t *  @type string\n\t\t\t\t *  @default First\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.paginate.first\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"paginate\": {\n\t\t\t\t *            \"first\": \"First page\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sFirst\": \"First\",\n\t\n\t\n\t\t\t\t/**\n\t\t\t\t * Text to use when using the 'full_numbers' type of pagination for the\n\t\t\t\t * button to take the user to the last page.\n\t\t\t\t *  @type string\n\t\t\t\t *  @default Last\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.paginate.last\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"paginate\": {\n\t\t\t\t *            \"last\": \"Last page\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sLast\": \"Last\",\n\t\n\t\n\t\t\t\t/**\n\t\t\t\t * Text to use for the 'next' pagination button (to take the user to the\n\t\t\t\t * next page).\n\t\t\t\t *  @type string\n\t\t\t\t *  @default Next\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.paginate.next\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"paginate\": {\n\t\t\t\t *            \"next\": \"Next page\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sNext\": \"Next\",\n\t\n\t\n\t\t\t\t/**\n\t\t\t\t * Text to use for the 'previous' pagination button (to take the user to\n\t\t\t\t * the previous page).\n\t\t\t\t *  @type string\n\t\t\t\t *  @default Previous\n\t\t\t\t *\n\t\t\t\t *  @dtopt Language\n\t\t\t\t *  @name DataTable.defaults.language.paginate.previous\n\t\t\t\t *\n\t\t\t\t *  @example\n\t\t\t\t *    $(document).ready( function() {\n\t\t\t\t *      $('#example').dataTable( {\n\t\t\t\t *        \"language\": {\n\t\t\t\t *          \"paginate\": {\n\t\t\t\t *            \"previous\": \"Previous page\"\n\t\t\t\t *          }\n\t\t\t\t *        }\n\t\t\t\t *      } );\n\t\t\t\t *    } );\n\t\t\t\t */\n\t\t\t\t\"sPrevious\": \"Previous\"\n\t\t\t},\n\t\n\t\t\t/**\n\t\t\t * This string is shown in preference to `zeroRecords` when the table is\n\t\t\t * empty of data (regardless of filtering). Note that this is an optional\n\t\t\t * parameter - if it is not given, the value of `zeroRecords` will be used\n\t\t\t * instead (either the default or given value).\n\t\t\t *  @type string\n\t\t\t *  @default No data available in table\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.emptyTable\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"emptyTable\": \"No data available in table\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sEmptyTable\": \"No data available in table\",\n\t\n\t\n\t\t\t/**\n\t\t\t * This string gives information to the end user about the information\n\t\t\t * that is current on display on the page. The following tokens can be\n\t\t\t * used in the string and will be dynamically replaced as the table\n\t\t\t * display updates. This tokens can be placed anywhere in the string, or\n\t\t\t * removed as needed by the language requires:\n\t\t\t *\n\t\t\t * * `\\_START\\_` - Display index of the first record on the current page\n\t\t\t * * `\\_END\\_` - Display index of the last record on the current page\n\t\t\t * * `\\_TOTAL\\_` - Number of records in the table after filtering\n\t\t\t * * `\\_MAX\\_` - Number of records in the table without filtering\n\t\t\t * * `\\_PAGE\\_` - Current page number\n\t\t\t * * `\\_PAGES\\_` - Total number of pages of data in the table\n\t\t\t *\n\t\t\t *  @type string\n\t\t\t *  @default Showing _START_ to _END_ of _TOTAL_ entries\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.info\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"info\": \"Showing page _PAGE_ of _PAGES_\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sInfo\": \"Showing _START_ to _END_ of _TOTAL_ entries\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Display information string for when the table is empty. Typically the\n\t\t\t * format of this string should match `info`.\n\t\t\t *  @type string\n\t\t\t *  @default Showing 0 to 0 of 0 entries\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.infoEmpty\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"infoEmpty\": \"No entries to show\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sInfoEmpty\": \"Showing 0 to 0 of 0 entries\",\n\t\n\t\n\t\t\t/**\n\t\t\t * When a user filters the information in a table, this string is appended\n\t\t\t * to the information (`info`) to give an idea of how strong the filtering\n\t\t\t * is. The variable _MAX_ is dynamically updated.\n\t\t\t *  @type string\n\t\t\t *  @default (filtered from _MAX_ total entries)\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.infoFiltered\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"infoFiltered\": \" - filtering from _MAX_ records\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sInfoFiltered\": \"(filtered from _MAX_ total entries)\",\n\t\n\t\n\t\t\t/**\n\t\t\t * If can be useful to append extra information to the info string at times,\n\t\t\t * and this variable does exactly that. This information will be appended to\n\t\t\t * the `info` (`infoEmpty` and `infoFiltered` in whatever combination they are\n\t\t\t * being used) at all times.\n\t\t\t *  @type string\n\t\t\t *  @default <i>Empty string</i>\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.infoPostFix\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"infoPostFix\": \"All records shown are derived from real information.\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sInfoPostFix\": \"\",\n\t\n\t\n\t\t\t/**\n\t\t\t * This decimal place operator is a little different from the other\n\t\t\t * language options since DataTables doesn't output floating point\n\t\t\t * numbers, so it won't ever use this for display of a number. Rather,\n\t\t\t * what this parameter does is modify the sort methods of the table so\n\t\t\t * that numbers which are in a format which has a character other than\n\t\t\t * a period (`.`) as a decimal place will be sorted numerically.\n\t\t\t *\n\t\t\t * Note that numbers with different decimal places cannot be shown in\n\t\t\t * the same table and still be sortable, the table must be consistent.\n\t\t\t * However, multiple different tables on the page can use different\n\t\t\t * decimal place characters.\n\t\t\t *  @type string\n\t\t\t *  @default \n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.decimal\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"decimal\": \",\"\n\t\t\t *          \"thousands\": \".\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sDecimal\": \"\",\n\t\n\t\n\t\t\t/**\n\t\t\t * DataTables has a build in number formatter (`formatNumber`) which is\n\t\t\t * used to format large numbers that are used in the table information.\n\t\t\t * By default a comma is used, but this can be trivially changed to any\n\t\t\t * character you wish with this parameter.\n\t\t\t *  @type string\n\t\t\t *  @default ,\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.thousands\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"thousands\": \"'\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sThousands\": \",\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Detail the action that will be taken when the drop down menu for the\n\t\t\t * pagination length option is changed. The '_MENU_' variable is replaced\n\t\t\t * with a default select list of 10, 25, 50 and 100, and can be replaced\n\t\t\t * with a custom select box if required.\n\t\t\t *  @type string\n\t\t\t *  @default Show _MENU_ entries\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.lengthMenu\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Language change only\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"lengthMenu\": \"Display _MENU_ records\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Language and options change\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"lengthMenu\": 'Display <select>'+\n\t\t\t *            '<option value=\"10\">10</option>'+\n\t\t\t *            '<option value=\"20\">20</option>'+\n\t\t\t *            '<option value=\"30\">30</option>'+\n\t\t\t *            '<option value=\"40\">40</option>'+\n\t\t\t *            '<option value=\"50\">50</option>'+\n\t\t\t *            '<option value=\"-1\">All</option>'+\n\t\t\t *            '</select> records'\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sLengthMenu\": \"Show _MENU_ entries\",\n\t\n\t\n\t\t\t/**\n\t\t\t * When using Ajax sourced data and during the first draw when DataTables is\n\t\t\t * gathering the data, this message is shown in an empty row in the table to\n\t\t\t * indicate to the end user the the data is being loaded. Note that this\n\t\t\t * parameter is not used when loading data by server-side processing, just\n\t\t\t * Ajax sourced data with client-side processing.\n\t\t\t *  @type string\n\t\t\t *  @default Loading...\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.loadingRecords\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"loadingRecords\": \"Please wait - loading...\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sLoadingRecords\": \"Loading...\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Text which is displayed when the table is processing a user action\n\t\t\t * (usually a sort command or similar).\n\t\t\t *  @type string\n\t\t\t *  @default Processing...\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.processing\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"processing\": \"DataTables is currently busy\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sProcessing\": \"Processing...\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Details the actions that will be taken when the user types into the\n\t\t\t * filtering input text box. The variable \"_INPUT_\", if used in the string,\n\t\t\t * is replaced with the HTML text box for the filtering input allowing\n\t\t\t * control over where it appears in the string. If \"_INPUT_\" is not given\n\t\t\t * then the input box is appended to the string automatically.\n\t\t\t *  @type string\n\t\t\t *  @default Search:\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.search\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Input text box will be appended at the end automatically\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"search\": \"Filter records:\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Specify where the filter should appear\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"search\": \"Apply filter _INPUT_ to table\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sSearch\": \"Search:\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Assign a `placeholder` attribute to the search `input` element\n\t\t\t *  @type string\n\t\t\t *  @default \n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.searchPlaceholder\n\t\t\t */\n\t\t\t\"sSearchPlaceholder\": \"\",\n\t\n\t\n\t\t\t/**\n\t\t\t * All of the language information can be stored in a file on the\n\t\t\t * server-side, which DataTables will look up if this parameter is passed.\n\t\t\t * It must store the URL of the language file, which is in a JSON format,\n\t\t\t * and the object has the same properties as the oLanguage object in the\n\t\t\t * initialiser object (i.e. the above parameters). Please refer to one of\n\t\t\t * the example language files to see how this works in action.\n\t\t\t *  @type string\n\t\t\t *  @default <i>Empty string - i.e. disabled</i>\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.url\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"url\": \"http://www.sprymedia.co.uk/dataTables/lang.txt\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sUrl\": \"\",\n\t\n\t\n\t\t\t/**\n\t\t\t * Text shown inside the table records when the is no information to be\n\t\t\t * displayed after filtering. `emptyTable` is shown when there is simply no\n\t\t\t * information in the table at all (regardless of filtering).\n\t\t\t *  @type string\n\t\t\t *  @default No matching records found\n\t\t\t *\n\t\t\t *  @dtopt Language\n\t\t\t *  @name DataTable.defaults.language.zeroRecords\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $(document).ready( function() {\n\t\t\t *      $('#example').dataTable( {\n\t\t\t *        \"language\": {\n\t\t\t *          \"zeroRecords\": \"No records to display\"\n\t\t\t *        }\n\t\t\t *      } );\n\t\t\t *    } );\n\t\t\t */\n\t\t\t\"sZeroRecords\": \"No matching records found\"\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * This parameter allows you to have define the global filtering state at\n\t\t * initialisation time. As an object the `search` parameter must be\n\t\t * defined, but all other parameters are optional. When `regex` is true,\n\t\t * the search string will be treated as a regular expression, when false\n\t\t * (default) it will be treated as a straight string. When `smart`\n\t\t * DataTables will use it's smart filtering methods (to word match at\n\t\t * any point in the data), when false this will not be done.\n\t\t *  @namespace\n\t\t *  @extends DataTable.models.oSearch\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.search\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"search\": {\"search\": \"Initial search\"}\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"oSearch\": $.extend( {}, DataTable.models.oSearch ),\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t * By default DataTables will look for the property `data` (or `aaData` for\n\t\t * compatibility with DataTables 1.9-) when obtaining data from an Ajax\n\t\t * source or for server-side processing - this parameter allows that\n\t\t * property to be changed. You can use Javascript dotted object notation to\n\t\t * get a data source for multiple levels of nesting.\n\t\t *  @type string\n\t\t *  @default data\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.ajaxDataProp\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"sAjaxDataProp\": \"data\",\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t * You can instruct DataTables to load data from an external\n\t\t * source using this parameter (use aData if you want to pass data in you\n\t\t * already have). Simply provide a url a JSON object can be obtained from.\n\t\t *  @type string\n\t\t *  @default null\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.ajaxSource\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"sAjaxSource\": null,\n\t\n\t\n\t\t/**\n\t\t * This initialisation variable allows you to specify exactly where in the\n\t\t * DOM you want DataTables to inject the various controls it adds to the page\n\t\t * (for example you might want the pagination controls at the top of the\n\t\t * table). DIV elements (with or without a custom class) can also be added to\n\t\t * aid styling. The follow syntax is used:\n\t\t *   <ul>\n\t\t *     <li>The following options are allowed:\n\t\t *       <ul>\n\t\t *         <li>'l' - Length changing</li>\n\t\t *         <li>'f' - Filtering input</li>\n\t\t *         <li>'t' - The table!</li>\n\t\t *         <li>'i' - Information</li>\n\t\t *         <li>'p' - Pagination</li>\n\t\t *         <li>'r' - pRocessing</li>\n\t\t *       </ul>\n\t\t *     </li>\n\t\t *     <li>The following constants are allowed:\n\t\t *       <ul>\n\t\t *         <li>'H' - jQueryUI theme \"header\" classes ('fg-toolbar ui-widget-header ui-corner-tl ui-corner-tr ui-helper-clearfix')</li>\n\t\t *         <li>'F' - jQueryUI theme \"footer\" classes ('fg-toolbar ui-widget-header ui-corner-bl ui-corner-br ui-helper-clearfix')</li>\n\t\t *       </ul>\n\t\t *     </li>\n\t\t *     <li>The following syntax is expected:\n\t\t *       <ul>\n\t\t *         <li>'&lt;' and '&gt;' - div elements</li>\n\t\t *         <li>'&lt;\"class\" and '&gt;' - div with a class</li>\n\t\t *         <li>'&lt;\"#id\" and '&gt;' - div with an ID</li>\n\t\t *       </ul>\n\t\t *     </li>\n\t\t *     <li>Examples:\n\t\t *       <ul>\n\t\t *         <li>'&lt;\"wrapper\"flipt&gt;'</li>\n\t\t *         <li>'&lt;lf&lt;t&gt;ip&gt;'</li>\n\t\t *       </ul>\n\t\t *     </li>\n\t\t *   </ul>\n\t\t *  @type string\n\t\t *  @default lfrtip <i>(when `jQueryUI` is false)</i> <b>or</b>\n\t\t *    <\"H\"lfr>t<\"F\"ip> <i>(when `jQueryUI` is true)</i>\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.dom\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"dom\": '&lt;\"top\"i&gt;rt&lt;\"bottom\"flp&gt;&lt;\"clear\"&gt;'\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sDom\": \"lfrtip\",\n\t\n\t\n\t\t/**\n\t\t * Search delay option. This will throttle full table searches that use the\n\t\t * DataTables provided search input element (it does not effect calls to\n\t\t * `dt-api search()`, providing a delay before the search is made.\n\t\t *  @type integer\n\t\t *  @default 0\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.searchDelay\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"searchDelay\": 200\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"searchDelay\": null,\n\t\n\t\n\t\t/**\n\t\t * DataTables features four different built-in options for the buttons to\n\t\t * display for pagination control:\n\t\t *\n\t\t * * `simple` - 'Previous' and 'Next' buttons only\n\t\t * * 'simple_numbers` - 'Previous' and 'Next' buttons, plus page numbers\n\t\t * * `full` - 'First', 'Previous', 'Next' and 'Last' buttons\n\t\t * * `full_numbers` - 'First', 'Previous', 'Next' and 'Last' buttons, plus\n\t\t *   page numbers\n\t\t *  \n\t\t * Further methods can be added using {@link DataTable.ext.oPagination}.\n\t\t *  @type string\n\t\t *  @default simple_numbers\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.pagingType\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"pagingType\": \"full_numbers\"\n\t\t *      } );\n\t\t *    } )\n\t\t */\n\t\t\"sPaginationType\": \"simple_numbers\",\n\t\n\t\n\t\t/**\n\t\t * Enable horizontal scrolling. When a table is too wide to fit into a\n\t\t * certain layout, or you have a large number of columns in the table, you\n\t\t * can enable x-scrolling to show the table in a viewport, which can be\n\t\t * scrolled. This property can be `true` which will allow the table to\n\t\t * scroll horizontally when needed, or any CSS unit, or a number (in which\n\t\t * case it will be treated as a pixel measurement). Setting as simply `true`\n\t\t * is recommended.\n\t\t *  @type boolean|string\n\t\t *  @default <i>blank string - i.e. disabled</i>\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.scrollX\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"scrollX\": true,\n\t\t *        \"scrollCollapse\": true\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sScrollX\": \"\",\n\t\n\t\n\t\t/**\n\t\t * This property can be used to force a DataTable to use more width than it\n\t\t * might otherwise do when x-scrolling is enabled. For example if you have a\n\t\t * table which requires to be well spaced, this parameter is useful for\n\t\t * \"over-sizing\" the table, and thus forcing scrolling. This property can by\n\t\t * any CSS unit, or a number (in which case it will be treated as a pixel\n\t\t * measurement).\n\t\t *  @type string\n\t\t *  @default <i>blank string - i.e. disabled</i>\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @name DataTable.defaults.scrollXInner\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"scrollX\": \"100%\",\n\t\t *        \"scrollXInner\": \"110%\"\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sScrollXInner\": \"\",\n\t\n\t\n\t\t/**\n\t\t * Enable vertical scrolling. Vertical scrolling will constrain the DataTable\n\t\t * to the given height, and enable scrolling for any data which overflows the\n\t\t * current viewport. This can be used as an alternative to paging to display\n\t\t * a lot of data in a small area (although paging and scrolling can both be\n\t\t * enabled at the same time). This property can be any CSS unit, or a number\n\t\t * (in which case it will be treated as a pixel measurement).\n\t\t *  @type string\n\t\t *  @default <i>blank string - i.e. disabled</i>\n\t\t *\n\t\t *  @dtopt Features\n\t\t *  @name DataTable.defaults.scrollY\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"scrollY\": \"200px\",\n\t\t *        \"paginate\": false\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sScrollY\": \"\",\n\t\n\t\n\t\t/**\n\t\t * __Deprecated__ The functionality provided by this parameter has now been\n\t\t * superseded by that provided through `ajax`, which should be used instead.\n\t\t *\n\t\t * Set the HTTP method that is used to make the Ajax call for server-side\n\t\t * processing or Ajax sourced data.\n\t\t *  @type string\n\t\t *  @default GET\n\t\t *\n\t\t *  @dtopt Options\n\t\t *  @dtopt Server-side\n\t\t *  @name DataTable.defaults.serverMethod\n\t\t *\n\t\t *  @deprecated 1.10. Please use `ajax` for this functionality now.\n\t\t */\n\t\t\"sServerMethod\": \"GET\",\n\t\n\t\n\t\t/**\n\t\t * DataTables makes use of renderers when displaying HTML elements for\n\t\t * a table. These renderers can be added or modified by plug-ins to\n\t\t * generate suitable mark-up for a site. For example the Bootstrap\n\t\t * integration plug-in for DataTables uses a paging button renderer to\n\t\t * display pagination buttons in the mark-up required by Bootstrap.\n\t\t *\n\t\t * For further information about the renderers available see\n\t\t * DataTable.ext.renderer\n\t\t *  @type string|object\n\t\t *  @default null\n\t\t *\n\t\t *  @name DataTable.defaults.renderer\n\t\t *\n\t\t */\n\t\t\"renderer\": null\n\t};\n\t\n\t_fnHungarianMap( DataTable.defaults );\n\t\n\t\n\t\n\t/*\n\t * Developer note - See note in model.defaults.js about the use of Hungarian\n\t * notation and camel case.\n\t */\n\t\n\t/**\n\t * Column options that can be given to DataTables at initialisation time.\n\t *  @namespace\n\t */\n\tDataTable.defaults.column = {\n\t\t/**\n\t\t * Define which column(s) an order will occur on for this column. This\n\t\t * allows a column's ordering to take multiple columns into account when\n\t\t * doing a sort or use the data from a different column. For example first\n\t\t * name / last name columns make sense to do a multi-column sort over the\n\t\t * two columns.\n\t\t *  @type array|int\n\t\t *  @default null <i>Takes the value of the column index automatically</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.orderData\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"orderData\": [ 0, 1 ], \"targets\": [ 0 ] },\n\t\t *          { \"orderData\": [ 1, 0 ], \"targets\": [ 1 ] },\n\t\t *          { \"orderData\": 2, \"targets\": [ 2 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"orderData\": [ 0, 1 ] },\n\t\t *          { \"orderData\": [ 1, 0 ] },\n\t\t *          { \"orderData\": 2 },\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"aDataSort\": null,\n\t\t\"iDataSort\": -1,\n\t\n\t\n\t\t/**\n\t\t * You can control the default ordering direction, and even alter the\n\t\t * behaviour of the sort handler (i.e. only allow ascending ordering etc)\n\t\t * using this parameter.\n\t\t *  @type array\n\t\t *  @default [ 'asc', 'desc' ]\n\t\t *\n\t\t *  @name DataTable.defaults.column.orderSequence\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"orderSequence\": [ \"asc\" ], \"targets\": [ 1 ] },\n\t\t *          { \"orderSequence\": [ \"desc\", \"asc\", \"asc\" ], \"targets\": [ 2 ] },\n\t\t *          { \"orderSequence\": [ \"desc\" ], \"targets\": [ 3 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          null,\n\t\t *          { \"orderSequence\": [ \"asc\" ] },\n\t\t *          { \"orderSequence\": [ \"desc\", \"asc\", \"asc\" ] },\n\t\t *          { \"orderSequence\": [ \"desc\" ] },\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"asSorting\": [ 'asc', 'desc' ],\n\t\n\t\n\t\t/**\n\t\t * Enable or disable filtering on the data in this column.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @name DataTable.defaults.column.searchable\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"searchable\": false, \"targets\": [ 0 ] }\n\t\t *        ] } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"searchable\": false },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ] } );\n\t\t *    } );\n\t\t */\n\t\t\"bSearchable\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable ordering on this column.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @name DataTable.defaults.column.orderable\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"orderable\": false, \"targets\": [ 0 ] }\n\t\t *        ] } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"orderable\": false },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ] } );\n\t\t *    } );\n\t\t */\n\t\t\"bSortable\": true,\n\t\n\t\n\t\t/**\n\t\t * Enable or disable the display of this column.\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t *\n\t\t *  @name DataTable.defaults.column.visible\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"visible\": false, \"targets\": [ 0 ] }\n\t\t *        ] } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"visible\": false },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ] } );\n\t\t *    } );\n\t\t */\n\t\t\"bVisible\": true,\n\t\n\t\n\t\t/**\n\t\t * Developer definable function that is called whenever a cell is created (Ajax source,\n\t\t * etc) or processed for input (DOM source). This can be used as a compliment to mRender\n\t\t * allowing you to modify the DOM element (add background colour for example) when the\n\t\t * element is available.\n\t\t *  @type function\n\t\t *  @param {element} td The TD node that has been created\n\t\t *  @param {*} cellData The Data for the cell\n\t\t *  @param {array|object} rowData The data for the whole row\n\t\t *  @param {int} row The row index for the aoData data store\n\t\t *  @param {int} col The column index for aoColumns\n\t\t *\n\t\t *  @name DataTable.defaults.column.createdCell\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [3],\n\t\t *          \"createdCell\": function (td, cellData, rowData, row, col) {\n\t\t *            if ( cellData == \"1.7\" ) {\n\t\t *              $(td).css('color', 'blue')\n\t\t *            }\n\t\t *          }\n\t\t *        } ]\n\t\t *      });\n\t\t *    } );\n\t\t */\n\t\t\"fnCreatedCell\": null,\n\t\n\t\n\t\t/**\n\t\t * This parameter has been replaced by `data` in DataTables to ensure naming\n\t\t * consistency. `dataProp` can still be used, as there is backwards\n\t\t * compatibility in DataTables for this option, but it is strongly\n\t\t * recommended that you use `data` in preference to `dataProp`.\n\t\t *  @name DataTable.defaults.column.dataProp\n\t\t */\n\t\n\t\n\t\t/**\n\t\t * This property can be used to read data from any data source property,\n\t\t * including deeply nested objects / properties. `data` can be given in a\n\t\t * number of different ways which effect its behaviour:\n\t\t *\n\t\t * * `integer` - treated as an array index for the data source. This is the\n\t\t *   default that DataTables uses (incrementally increased for each column).\n\t\t * * `string` - read an object property from the data source. There are\n\t\t *   three 'special' options that can be used in the string to alter how\n\t\t *   DataTables reads the data from the source object:\n\t\t *    * `.` - Dotted Javascript notation. Just as you use a `.` in\n\t\t *      Javascript to read from nested objects, so to can the options\n\t\t *      specified in `data`. For example: `browser.version` or\n\t\t *      `browser.name`. If your object parameter name contains a period, use\n\t\t *      `\\\\` to escape it - i.e. `first\\\\.name`.\n\t\t *    * `[]` - Array notation. DataTables can automatically combine data\n\t\t *      from and array source, joining the data with the characters provided\n\t\t *      between the two brackets. For example: `name[, ]` would provide a\n\t\t *      comma-space separated list from the source array. If no characters\n\t\t *      are provided between the brackets, the original array source is\n\t\t *      returned.\n\t\t *    * `()` - Function notation. Adding `()` to the end of a parameter will\n\t\t *      execute a function of the name given. For example: `browser()` for a\n\t\t *      simple function on the data source, `browser.version()` for a\n\t\t *      function in a nested property or even `browser().version` to get an\n\t\t *      object property if the function called returns an object. Note that\n\t\t *      function notation is recommended for use in `render` rather than\n\t\t *      `data` as it is much simpler to use as a renderer.\n\t\t * * `null` - use the original data source for the row rather than plucking\n\t\t *   data directly from it. This action has effects on two other\n\t\t *   initialisation options:\n\t\t *    * `defaultContent` - When null is given as the `data` option and\n\t\t *      `defaultContent` is specified for the column, the value defined by\n\t\t *      `defaultContent` will be used for the cell.\n\t\t *    * `render` - When null is used for the `data` option and the `render`\n\t\t *      option is specified for the column, the whole data source for the\n\t\t *      row is used for the renderer.\n\t\t * * `function` - the function given will be executed whenever DataTables\n\t\t *   needs to set or get the data for a cell in the column. The function\n\t\t *   takes three parameters:\n\t\t *    * Parameters:\n\t\t *      * `{array|object}` The data source for the row\n\t\t *      * `{string}` The type call data requested - this will be 'set' when\n\t\t *        setting data or 'filter', 'display', 'type', 'sort' or undefined\n\t\t *        when gathering data. Note that when `undefined` is given for the\n\t\t *        type DataTables expects to get the raw data for the object back<\n\t\t *      * `{*}` Data to set when the second parameter is 'set'.\n\t\t *    * Return:\n\t\t *      * The return value from the function is not required when 'set' is\n\t\t *        the type of call, but otherwise the return is what will be used\n\t\t *        for the data requested.\n\t\t *\n\t\t * Note that `data` is a getter and setter option. If you just require\n\t\t * formatting of data for output, you will likely want to use `render` which\n\t\t * is simply a getter and thus simpler to use.\n\t\t *\n\t\t * Note that prior to DataTables 1.9.2 `data` was called `mDataProp`. The\n\t\t * name change reflects the flexibility of this property and is consistent\n\t\t * with the naming of mRender. If 'mDataProp' is given, then it will still\n\t\t * be used by DataTables, as it automatically maps the old name to the new\n\t\t * if required.\n\t\t *\n\t\t *  @type string|int|function|null\n\t\t *  @default null <i>Use automatically calculated column index</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.data\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Read table data from objects\n\t\t *    // JSON structure for each row:\n\t\t *    //   {\n\t\t *    //      \"engine\": {value},\n\t\t *    //      \"browser\": {value},\n\t\t *    //      \"platform\": {value},\n\t\t *    //      \"version\": {value},\n\t\t *    //      \"grade\": {value}\n\t\t *    //   }\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ajaxSource\": \"sources/objects.txt\",\n\t\t *        \"columns\": [\n\t\t *          { \"data\": \"engine\" },\n\t\t *          { \"data\": \"browser\" },\n\t\t *          { \"data\": \"platform\" },\n\t\t *          { \"data\": \"version\" },\n\t\t *          { \"data\": \"grade\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Read information from deeply nested objects\n\t\t *    // JSON structure for each row:\n\t\t *    //   {\n\t\t *    //      \"engine\": {value},\n\t\t *    //      \"browser\": {value},\n\t\t *    //      \"platform\": {\n\t\t *    //         \"inner\": {value}\n\t\t *    //      },\n\t\t *    //      \"details\": [\n\t\t *    //         {value}, {value}\n\t\t *    //      ]\n\t\t *    //   }\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ajaxSource\": \"sources/deep.txt\",\n\t\t *        \"columns\": [\n\t\t *          { \"data\": \"engine\" },\n\t\t *          { \"data\": \"browser\" },\n\t\t *          { \"data\": \"platform.inner\" },\n\t\t *          { \"data\": \"platform.details.0\" },\n\t\t *          { \"data\": \"platform.details.1\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `data` as a function to provide different information for\n\t\t *    // sorting, filtering and display. In this case, currency (price)\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": function ( source, type, val ) {\n\t\t *            if (type === 'set') {\n\t\t *              source.price = val;\n\t\t *              // Store the computed dislay and filter values for efficiency\n\t\t *              source.price_display = val==\"\" ? \"\" : \"$\"+numberFormat(val);\n\t\t *              source.price_filter  = val==\"\" ? \"\" : \"$\"+numberFormat(val)+\" \"+val;\n\t\t *              return;\n\t\t *            }\n\t\t *            else if (type === 'display') {\n\t\t *              return source.price_display;\n\t\t *            }\n\t\t *            else if (type === 'filter') {\n\t\t *              return source.price_filter;\n\t\t *            }\n\t\t *            // 'sort', 'type' and undefined all just use the integer\n\t\t *            return source.price;\n\t\t *          }\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using default content\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": null,\n\t\t *          \"defaultContent\": \"Click to edit\"\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using array notation - outputting a list from an array\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": \"name[, ]\"\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t */\n\t\t\"mData\": null,\n\t\n\t\n\t\t/**\n\t\t * This property is the rendering partner to `data` and it is suggested that\n\t\t * when you want to manipulate data for display (including filtering,\n\t\t * sorting etc) without altering the underlying data for the table, use this\n\t\t * property. `render` can be considered to be the the read only companion to\n\t\t * `data` which is read / write (then as such more complex). Like `data`\n\t\t * this option can be given in a number of different ways to effect its\n\t\t * behaviour:\n\t\t *\n\t\t * * `integer` - treated as an array index for the data source. This is the\n\t\t *   default that DataTables uses (incrementally increased for each column).\n\t\t * * `string` - read an object property from the data source. There are\n\t\t *   three 'special' options that can be used in the string to alter how\n\t\t *   DataTables reads the data from the source object:\n\t\t *    * `.` - Dotted Javascript notation. Just as you use a `.` in\n\t\t *      Javascript to read from nested objects, so to can the options\n\t\t *      specified in `data`. For example: `browser.version` or\n\t\t *      `browser.name`. If your object parameter name contains a period, use\n\t\t *      `\\\\` to escape it - i.e. `first\\\\.name`.\n\t\t *    * `[]` - Array notation. DataTables can automatically combine data\n\t\t *      from and array source, joining the data with the characters provided\n\t\t *      between the two brackets. For example: `name[, ]` would provide a\n\t\t *      comma-space separated list from the source array. If no characters\n\t\t *      are provided between the brackets, the original array source is\n\t\t *      returned.\n\t\t *    * `()` - Function notation. Adding `()` to the end of a parameter will\n\t\t *      execute a function of the name given. For example: `browser()` for a\n\t\t *      simple function on the data source, `browser.version()` for a\n\t\t *      function in a nested property or even `browser().version` to get an\n\t\t *      object property if the function called returns an object.\n\t\t * * `object` - use different data for the different data types requested by\n\t\t *   DataTables ('filter', 'display', 'type' or 'sort'). The property names\n\t\t *   of the object is the data type the property refers to and the value can\n\t\t *   defined using an integer, string or function using the same rules as\n\t\t *   `render` normally does. Note that an `_` option _must_ be specified.\n\t\t *   This is the default value to use if you haven't specified a value for\n\t\t *   the data type requested by DataTables.\n\t\t * * `function` - the function given will be executed whenever DataTables\n\t\t *   needs to set or get the data for a cell in the column. The function\n\t\t *   takes three parameters:\n\t\t *    * Parameters:\n\t\t *      * {array|object} The data source for the row (based on `data`)\n\t\t *      * {string} The type call data requested - this will be 'filter',\n\t\t *        'display', 'type' or 'sort'.\n\t\t *      * {array|object} The full data source for the row (not based on\n\t\t *        `data`)\n\t\t *    * Return:\n\t\t *      * The return value from the function is what will be used for the\n\t\t *        data requested.\n\t\t *\n\t\t *  @type string|int|function|object|null\n\t\t *  @default null Use the data source value.\n\t\t *\n\t\t *  @name DataTable.defaults.column.render\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Create a comma separated list from an array of objects\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"ajaxSource\": \"sources/deep.txt\",\n\t\t *        \"columns\": [\n\t\t *          { \"data\": \"engine\" },\n\t\t *          { \"data\": \"browser\" },\n\t\t *          {\n\t\t *            \"data\": \"platform\",\n\t\t *            \"render\": \"[, ].name\"\n\t\t *          }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Execute a function to obtain data\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": null, // Use the full data source object for the renderer's source\n\t\t *          \"render\": \"browserName()\"\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // As an object, extracting different data for the different types\n\t\t *    // This would be used with a data source such as:\n\t\t *    //   { \"phone\": 5552368, \"phone_filter\": \"5552368 555-2368\", \"phone_display\": \"555-2368\" }\n\t\t *    // Here the `phone` integer is used for sorting and type detection, while `phone_filter`\n\t\t *    // (which has both forms) is used for filtering for if a user inputs either format, while\n\t\t *    // the formatted phone number is the one that is shown in the table.\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": null, // Use the full data source object for the renderer's source\n\t\t *          \"render\": {\n\t\t *            \"_\": \"phone\",\n\t\t *            \"filter\": \"phone_filter\",\n\t\t *            \"display\": \"phone_display\"\n\t\t *          }\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Use as a function to create a link from the data source\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"data\": \"download_link\",\n\t\t *          \"render\": function ( data, type, full ) {\n\t\t *            return '<a href=\"'+data+'\">Download</a>';\n\t\t *          }\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"mRender\": null,\n\t\n\t\n\t\t/**\n\t\t * Change the cell type created for the column - either TD cells or TH cells. This\n\t\t * can be useful as TH cells have semantic meaning in the table body, allowing them\n\t\t * to act as a header for a row (you may wish to add scope='row' to the TH elements).\n\t\t *  @type string\n\t\t *  @default td\n\t\t *\n\t\t *  @name DataTable.defaults.column.cellType\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Make the first column use TH cells\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [ {\n\t\t *          \"targets\": [ 0 ],\n\t\t *          \"cellType\": \"th\"\n\t\t *        } ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sCellType\": \"td\",\n\t\n\t\n\t\t/**\n\t\t * Class to give to each cell in this column.\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.class\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"class\": \"my_class\", \"targets\": [ 0 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"class\": \"my_class\" },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sClass\": \"\",\n\t\n\t\t/**\n\t\t * When DataTables calculates the column widths to assign to each column,\n\t\t * it finds the longest string in each column and then constructs a\n\t\t * temporary table and reads the widths from that. The problem with this\n\t\t * is that \"mmm\" is much wider then \"iiii\", but the latter is a longer\n\t\t * string - thus the calculation can go wrong (doing it properly and putting\n\t\t * it into an DOM object and measuring that is horribly(!) slow). Thus as\n\t\t * a \"work around\" we provide this option. It will append its value to the\n\t\t * text that is found to be the longest string for the column - i.e. padding.\n\t\t * Generally you shouldn't need this!\n\t\t *  @type string\n\t\t *  @default <i>Empty string<i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.contentPadding\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          {\n\t\t *            \"contentPadding\": \"mmm\"\n\t\t *          }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sContentPadding\": \"\",\n\t\n\t\n\t\t/**\n\t\t * Allows a default value to be given for a column's data, and will be used\n\t\t * whenever a null data source is encountered (this can be because `data`\n\t\t * is set to null, or because the data source itself is null).\n\t\t *  @type string\n\t\t *  @default null\n\t\t *\n\t\t *  @name DataTable.defaults.column.defaultContent\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          {\n\t\t *            \"data\": null,\n\t\t *            \"defaultContent\": \"Edit\",\n\t\t *            \"targets\": [ -1 ]\n\t\t *          }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          {\n\t\t *            \"data\": null,\n\t\t *            \"defaultContent\": \"Edit\"\n\t\t *          }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sDefaultContent\": null,\n\t\n\t\n\t\t/**\n\t\t * This parameter is only used in DataTables' server-side processing. It can\n\t\t * be exceptionally useful to know what columns are being displayed on the\n\t\t * client side, and to map these to database fields. When defined, the names\n\t\t * also allow DataTables to reorder information from the server if it comes\n\t\t * back in an unexpected order (i.e. if you switch your columns around on the\n\t\t * client-side, your server-side code does not also need updating).\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.name\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"name\": \"engine\", \"targets\": [ 0 ] },\n\t\t *          { \"name\": \"browser\", \"targets\": [ 1 ] },\n\t\t *          { \"name\": \"platform\", \"targets\": [ 2 ] },\n\t\t *          { \"name\": \"version\", \"targets\": [ 3 ] },\n\t\t *          { \"name\": \"grade\", \"targets\": [ 4 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"name\": \"engine\" },\n\t\t *          { \"name\": \"browser\" },\n\t\t *          { \"name\": \"platform\" },\n\t\t *          { \"name\": \"version\" },\n\t\t *          { \"name\": \"grade\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sName\": \"\",\n\t\n\t\n\t\t/**\n\t\t * Defines a data source type for the ordering which can be used to read\n\t\t * real-time information from the table (updating the internally cached\n\t\t * version) prior to ordering. This allows ordering to occur on user\n\t\t * editable elements such as form inputs.\n\t\t *  @type string\n\t\t *  @default std\n\t\t *\n\t\t *  @name DataTable.defaults.column.orderDataType\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"orderDataType\": \"dom-text\", \"targets\": [ 2, 3 ] },\n\t\t *          { \"type\": \"numeric\", \"targets\": [ 3 ] },\n\t\t *          { \"orderDataType\": \"dom-select\", \"targets\": [ 4 ] },\n\t\t *          { \"orderDataType\": \"dom-checkbox\", \"targets\": [ 5 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          null,\n\t\t *          null,\n\t\t *          { \"orderDataType\": \"dom-text\" },\n\t\t *          { \"orderDataType\": \"dom-text\", \"type\": \"numeric\" },\n\t\t *          { \"orderDataType\": \"dom-select\" },\n\t\t *          { \"orderDataType\": \"dom-checkbox\" }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sSortDataType\": \"std\",\n\t\n\t\n\t\t/**\n\t\t * The title of this column.\n\t\t *  @type string\n\t\t *  @default null <i>Derived from the 'TH' value for this column in the\n\t\t *    original HTML table.</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.title\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"title\": \"My column title\", \"targets\": [ 0 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"title\": \"My column title\" },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sTitle\": null,\n\t\n\t\n\t\t/**\n\t\t * The type allows you to specify how the data for this column will be\n\t\t * ordered. Four types (string, numeric, date and html (which will strip\n\t\t * HTML tags before ordering)) are currently available. Note that only date\n\t\t * formats understood by Javascript's Date() object will be accepted as type\n\t\t * date. For example: \"Mar 26, 2008 5:03 PM\". May take the values: 'string',\n\t\t * 'numeric', 'date' or 'html' (by default). Further types can be adding\n\t\t * through plug-ins.\n\t\t *  @type string\n\t\t *  @default null <i>Auto-detected from raw data</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.type\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"type\": \"html\", \"targets\": [ 0 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"type\": \"html\" },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sType\": null,\n\t\n\t\n\t\t/**\n\t\t * Defining the width of the column, this parameter may take any CSS value\n\t\t * (3em, 20px etc). DataTables applies 'smart' widths to columns which have not\n\t\t * been given a specific width through this interface ensuring that the table\n\t\t * remains readable.\n\t\t *  @type string\n\t\t *  @default null <i>Automatic</i>\n\t\t *\n\t\t *  @name DataTable.defaults.column.width\n\t\t *  @dtopt Columns\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columnDefs`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columnDefs\": [\n\t\t *          { \"width\": \"20%\", \"targets\": [ 0 ] }\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t *\n\t\t *  @example\n\t\t *    // Using `columns`\n\t\t *    $(document).ready( function() {\n\t\t *      $('#example').dataTable( {\n\t\t *        \"columns\": [\n\t\t *          { \"width\": \"20%\" },\n\t\t *          null,\n\t\t *          null,\n\t\t *          null,\n\t\t *          null\n\t\t *        ]\n\t\t *      } );\n\t\t *    } );\n\t\t */\n\t\t\"sWidth\": null\n\t};\n\t\n\t_fnHungarianMap( DataTable.defaults.column );\n\t\n\t\n\t\n\t/**\n\t * DataTables settings object - this holds all the information needed for a\n\t * given table, including configuration, data and current application of the\n\t * table options. DataTables does not have a single instance for each DataTable\n\t * with the settings attached to that instance, but rather instances of the\n\t * DataTable \"class\" are created on-the-fly as needed (typically by a\n\t * $().dataTable() call) and the settings object is then applied to that\n\t * instance.\n\t *\n\t * Note that this object is related to {@link DataTable.defaults} but this\n\t * one is the internal data store for DataTables's cache of columns. It should\n\t * NOT be manipulated outside of DataTables. Any configuration should be done\n\t * through the initialisation options.\n\t *  @namespace\n\t *  @todo Really should attach the settings object to individual instances so we\n\t *    don't need to create new instances on each $().dataTable() call (if the\n\t *    table already exists). It would also save passing oSettings around and\n\t *    into every single function. However, this is a very significant\n\t *    architecture change for DataTables and will almost certainly break\n\t *    backwards compatibility with older installations. This is something that\n\t *    will be done in 2.0.\n\t */\n\tDataTable.models.oSettings = {\n\t\t/**\n\t\t * Primary features of DataTables and their enablement state.\n\t\t *  @namespace\n\t\t */\n\t\t\"oFeatures\": {\n\t\n\t\t\t/**\n\t\t\t * Flag to say if DataTables should automatically try to calculate the\n\t\t\t * optimum table and columns widths (true) or not (false).\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bAutoWidth\": null,\n\t\n\t\t\t/**\n\t\t\t * Delay the creation of TR and TD elements until they are actually\n\t\t\t * needed by a driven page draw. This can give a significant speed\n\t\t\t * increase for Ajax source and Javascript source data, but makes no\n\t\t\t * difference at all fro DOM and server-side processing tables.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bDeferRender\": null,\n\t\n\t\t\t/**\n\t\t\t * Enable filtering on the table or not. Note that if this is disabled\n\t\t\t * then there is no filtering at all on the table, including fnFilter.\n\t\t\t * To just remove the filtering input use sDom and remove the 'f' option.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bFilter\": null,\n\t\n\t\t\t/**\n\t\t\t * Table information element (the 'Showing x of y records' div) enable\n\t\t\t * flag.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bInfo\": null,\n\t\n\t\t\t/**\n\t\t\t * Present a user control allowing the end user to change the page size\n\t\t\t * when pagination is enabled.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bLengthChange\": null,\n\t\n\t\t\t/**\n\t\t\t * Pagination enabled or not. Note that if this is disabled then length\n\t\t\t * changing must also be disabled.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bPaginate\": null,\n\t\n\t\t\t/**\n\t\t\t * Processing indicator enable flag whenever DataTables is enacting a\n\t\t\t * user request - typically an Ajax request for server-side processing.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bProcessing\": null,\n\t\n\t\t\t/**\n\t\t\t * Server-side processing enabled flag - when enabled DataTables will\n\t\t\t * get all data from the server for every draw - there is no filtering,\n\t\t\t * sorting or paging done on the client-side.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bServerSide\": null,\n\t\n\t\t\t/**\n\t\t\t * Sorting enablement flag.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bSort\": null,\n\t\n\t\t\t/**\n\t\t\t * Multi-column sorting\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bSortMulti\": null,\n\t\n\t\t\t/**\n\t\t\t * Apply a class to the columns which are being sorted to provide a\n\t\t\t * visual highlight or not. This can slow things down when enabled since\n\t\t\t * there is a lot of DOM interaction.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bSortClasses\": null,\n\t\n\t\t\t/**\n\t\t\t * State saving enablement flag.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bStateSave\": null\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Scrolling settings for a table.\n\t\t *  @namespace\n\t\t */\n\t\t\"oScroll\": {\n\t\t\t/**\n\t\t\t * When the table is shorter in height than sScrollY, collapse the\n\t\t\t * table container down to the height of the table (when true).\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type boolean\n\t\t\t */\n\t\t\t\"bCollapse\": null,\n\t\n\t\t\t/**\n\t\t\t * Width of the scrollbar for the web-browser's platform. Calculated\n\t\t\t * during table initialisation.\n\t\t\t *  @type int\n\t\t\t *  @default 0\n\t\t\t */\n\t\t\t\"iBarWidth\": 0,\n\t\n\t\t\t/**\n\t\t\t * Viewport width for horizontal scrolling. Horizontal scrolling is\n\t\t\t * disabled if an empty string.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type string\n\t\t\t */\n\t\t\t\"sX\": null,\n\t\n\t\t\t/**\n\t\t\t * Width to expand the table to when using x-scrolling. Typically you\n\t\t\t * should not need to use this.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type string\n\t\t\t *  @deprecated\n\t\t\t */\n\t\t\t\"sXInner\": null,\n\t\n\t\t\t/**\n\t\t\t * Viewport height for vertical scrolling. Vertical scrolling is disabled\n\t\t\t * if an empty string.\n\t\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t\t * set a default use {@link DataTable.defaults}.\n\t\t\t *  @type string\n\t\t\t */\n\t\t\t\"sY\": null\n\t\t},\n\t\n\t\t/**\n\t\t * Language information for the table.\n\t\t *  @namespace\n\t\t *  @extends DataTable.defaults.oLanguage\n\t\t */\n\t\t\"oLanguage\": {\n\t\t\t/**\n\t\t\t * Information callback function. See\n\t\t\t * {@link DataTable.defaults.fnInfoCallback}\n\t\t\t *  @type function\n\t\t\t *  @default null\n\t\t\t */\n\t\t\t\"fnInfoCallback\": null\n\t\t},\n\t\n\t\t/**\n\t\t * Browser support parameters\n\t\t *  @namespace\n\t\t */\n\t\t\"oBrowser\": {\n\t\t\t/**\n\t\t\t * Indicate if the browser incorrectly calculates width:100% inside a\n\t\t\t * scrolling element (IE6/7)\n\t\t\t *  @type boolean\n\t\t\t *  @default false\n\t\t\t */\n\t\t\t\"bScrollOversize\": false,\n\t\n\t\t\t/**\n\t\t\t * Determine if the vertical scrollbar is on the right or left of the\n\t\t\t * scrolling container - needed for rtl language layout, although not\n\t\t\t * all browsers move the scrollbar (Safari).\n\t\t\t *  @type boolean\n\t\t\t *  @default false\n\t\t\t */\n\t\t\t\"bScrollbarLeft\": false\n\t\t},\n\t\n\t\n\t\t\"ajax\": null,\n\t\n\t\n\t\t/**\n\t\t * Array referencing the nodes which are used for the features. The\n\t\t * parameters of this object match what is allowed by sDom - i.e.\n\t\t *   <ul>\n\t\t *     <li>'l' - Length changing</li>\n\t\t *     <li>'f' - Filtering input</li>\n\t\t *     <li>'t' - The table!</li>\n\t\t *     <li>'i' - Information</li>\n\t\t *     <li>'p' - Pagination</li>\n\t\t *     <li>'r' - pRocessing</li>\n\t\t *   </ul>\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aanFeatures\": [],\n\t\n\t\t/**\n\t\t * Store data information - see {@link DataTable.models.oRow} for detailed\n\t\t * information.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoData\": [],\n\t\n\t\t/**\n\t\t * Array of indexes which are in the current display (after filtering etc)\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aiDisplay\": [],\n\t\n\t\t/**\n\t\t * Array of indexes for display - no filtering\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aiDisplayMaster\": [],\n\t\n\t\t/**\n\t\t * Store information about each column that is in use\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoColumns\": [],\n\t\n\t\t/**\n\t\t * Store information about the table's header\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoHeader\": [],\n\t\n\t\t/**\n\t\t * Store information about the table's footer\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoFooter\": [],\n\t\n\t\t/**\n\t\t * Store the applied global search information in case we want to force a\n\t\t * research or compare the old search to a new one.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @namespace\n\t\t *  @extends DataTable.models.oSearch\n\t\t */\n\t\t\"oPreviousSearch\": {},\n\t\n\t\t/**\n\t\t * Store the applied search for each column - see\n\t\t * {@link DataTable.models.oSearch} for the format that is used for the\n\t\t * filtering information for each column.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoPreSearchCols\": [],\n\t\n\t\t/**\n\t\t * Sorting that is applied to the table. Note that the inner arrays are\n\t\t * used in the following manner:\n\t\t * <ul>\n\t\t *   <li>Index 0 - column number</li>\n\t\t *   <li>Index 1 - current sorting direction</li>\n\t\t * </ul>\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type array\n\t\t *  @todo These inner arrays should really be objects\n\t\t */\n\t\t\"aaSorting\": null,\n\t\n\t\t/**\n\t\t * Sorting that is always applied to the table (i.e. prefixed in front of\n\t\t * aaSorting).\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aaSortingFixed\": [],\n\t\n\t\t/**\n\t\t * Classes to use for the striping of a table.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"asStripeClasses\": null,\n\t\n\t\t/**\n\t\t * If restoring a table - we should restore its striping classes as well\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"asDestroyStripes\": [],\n\t\n\t\t/**\n\t\t * If restoring a table - we should restore its width\n\t\t *  @type int\n\t\t *  @default 0\n\t\t */\n\t\t\"sDestroyWidth\": 0,\n\t\n\t\t/**\n\t\t * Callback functions array for every time a row is inserted (i.e. on a draw).\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoRowCallback\": [],\n\t\n\t\t/**\n\t\t * Callback functions for the header on each draw.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoHeaderCallback\": [],\n\t\n\t\t/**\n\t\t * Callback function for the footer on each draw.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoFooterCallback\": [],\n\t\n\t\t/**\n\t\t * Array of callback functions for draw callback functions\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoDrawCallback\": [],\n\t\n\t\t/**\n\t\t * Array of callback functions for row created function\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoRowCreatedCallback\": [],\n\t\n\t\t/**\n\t\t * Callback functions for just before the table is redrawn. A return of\n\t\t * false will be used to cancel the draw.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoPreDrawCallback\": [],\n\t\n\t\t/**\n\t\t * Callback functions for when the table has been initialised.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoInitComplete\": [],\n\t\n\t\n\t\t/**\n\t\t * Callbacks for modifying the settings to be stored for state saving, prior to\n\t\t * saving state.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateSaveParams\": [],\n\t\n\t\t/**\n\t\t * Callbacks for modifying the settings that have been stored for state saving\n\t\t * prior to using the stored values to restore the state.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateLoadParams\": [],\n\t\n\t\t/**\n\t\t * Callbacks for operating on the settings object once the saved state has been\n\t\t * loaded\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateLoaded\": [],\n\t\n\t\t/**\n\t\t * Cache the table ID for quick access\n\t\t *  @type string\n\t\t *  @default <i>Empty string</i>\n\t\t */\n\t\t\"sTableId\": \"\",\n\t\n\t\t/**\n\t\t * The TABLE node for the main table\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTable\": null,\n\t\n\t\t/**\n\t\t * Permanent ref to the thead element\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTHead\": null,\n\t\n\t\t/**\n\t\t * Permanent ref to the tfoot element - if it exists\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTFoot\": null,\n\t\n\t\t/**\n\t\t * Permanent ref to the tbody element\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTBody\": null,\n\t\n\t\t/**\n\t\t * Cache the wrapper node (contains all DataTables controlled elements)\n\t\t *  @type node\n\t\t *  @default null\n\t\t */\n\t\t\"nTableWrapper\": null,\n\t\n\t\t/**\n\t\t * Indicate if when using server-side processing the loading of data\n\t\t * should be deferred until the second draw.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t */\n\t\t\"bDeferLoading\": false,\n\t\n\t\t/**\n\t\t * Indicate if all required information has been read in\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t */\n\t\t\"bInitialised\": false,\n\t\n\t\t/**\n\t\t * Information about open rows. Each object in the array has the parameters\n\t\t * 'nTr' and 'nParent'\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoOpenRows\": [],\n\t\n\t\t/**\n\t\t * Dictate the positioning of DataTables' control elements - see\n\t\t * {@link DataTable.model.oInit.sDom}.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sDom\": null,\n\t\n\t\t/**\n\t\t * Search delay (in mS)\n\t\t *  @type integer\n\t\t *  @default null\n\t\t */\n\t\t\"searchDelay\": null,\n\t\n\t\t/**\n\t\t * Which type of pagination should be used.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t *  @default two_button\n\t\t */\n\t\t\"sPaginationType\": \"two_button\",\n\t\n\t\t/**\n\t\t * The state duration (for `stateSave`) in seconds.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type int\n\t\t *  @default 0\n\t\t */\n\t\t\"iStateDuration\": 0,\n\t\n\t\t/**\n\t\t * Array of callback functions for state saving. Each array element is an\n\t\t * object with the following parameters:\n\t\t *   <ul>\n\t\t *     <li>function:fn - function to call. Takes two parameters, oSettings\n\t\t *       and the JSON string to save that has been thus far created. Returns\n\t\t *       a JSON string to be inserted into a json object\n\t\t *       (i.e. '\"param\": [ 0, 1, 2]')</li>\n\t\t *     <li>string:sName - name of callback</li>\n\t\t *   </ul>\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateSave\": [],\n\t\n\t\t/**\n\t\t * Array of callback functions for state loading. Each array element is an\n\t\t * object with the following parameters:\n\t\t *   <ul>\n\t\t *     <li>function:fn - function to call. Takes two parameters, oSettings\n\t\t *       and the object stored. May return false to cancel state loading</li>\n\t\t *     <li>string:sName - name of callback</li>\n\t\t *   </ul>\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoStateLoad\": [],\n\t\n\t\t/**\n\t\t * State that was saved. Useful for back reference\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"oSavedState\": null,\n\t\n\t\t/**\n\t\t * State that was loaded. Useful for back reference\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"oLoadedState\": null,\n\t\n\t\t/**\n\t\t * Source url for AJAX data for the table.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sAjaxSource\": null,\n\t\n\t\t/**\n\t\t * Property from a given object from which to read the table data from. This\n\t\t * can be an empty string (when not server-side processing), in which case\n\t\t * it is  assumed an an array is given directly.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t */\n\t\t\"sAjaxDataProp\": null,\n\t\n\t\t/**\n\t\t * Note if draw should be blocked while getting data\n\t\t *  @type boolean\n\t\t *  @default true\n\t\t */\n\t\t\"bAjaxDataGet\": true,\n\t\n\t\t/**\n\t\t * The last jQuery XHR object that was used for server-side data gathering.\n\t\t * This can be used for working with the XHR information in one of the\n\t\t * callbacks\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"jqXHR\": null,\n\t\n\t\t/**\n\t\t * JSON returned from the server in the last Ajax request\n\t\t *  @type object\n\t\t *  @default undefined\n\t\t */\n\t\t\"json\": undefined,\n\t\n\t\t/**\n\t\t * Data submitted as part of the last Ajax request\n\t\t *  @type object\n\t\t *  @default undefined\n\t\t */\n\t\t\"oAjaxData\": undefined,\n\t\n\t\t/**\n\t\t * Function to get the server-side data.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type function\n\t\t */\n\t\t\"fnServerData\": null,\n\t\n\t\t/**\n\t\t * Functions which are called prior to sending an Ajax request so extra\n\t\t * parameters can easily be sent to the server\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoServerParams\": [],\n\t\n\t\t/**\n\t\t * Send the XHR HTTP method - GET or POST (could be PUT or DELETE if\n\t\t * required).\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type string\n\t\t */\n\t\t\"sServerMethod\": null,\n\t\n\t\t/**\n\t\t * Format numbers for display.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type function\n\t\t */\n\t\t\"fnFormatNumber\": null,\n\t\n\t\t/**\n\t\t * List of options that can be used for the user selectable length menu.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aLengthMenu\": null,\n\t\n\t\t/**\n\t\t * Counter for the draws that the table does. Also used as a tracker for\n\t\t * server-side processing\n\t\t *  @type int\n\t\t *  @default 0\n\t\t */\n\t\t\"iDraw\": 0,\n\t\n\t\t/**\n\t\t * Indicate if a redraw is being done - useful for Ajax\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t */\n\t\t\"bDrawing\": false,\n\t\n\t\t/**\n\t\t * Draw index (iDraw) of the last error when parsing the returned data\n\t\t *  @type int\n\t\t *  @default -1\n\t\t */\n\t\t\"iDrawError\": -1,\n\t\n\t\t/**\n\t\t * Paging display length\n\t\t *  @type int\n\t\t *  @default 10\n\t\t */\n\t\t\"_iDisplayLength\": 10,\n\t\n\t\t/**\n\t\t * Paging start point - aiDisplay index\n\t\t *  @type int\n\t\t *  @default 0\n\t\t */\n\t\t\"_iDisplayStart\": 0,\n\t\n\t\t/**\n\t\t * Server-side processing - number of records in the result set\n\t\t * (i.e. before filtering), Use fnRecordsTotal rather than\n\t\t * this property to get the value of the number of records, regardless of\n\t\t * the server-side processing setting.\n\t\t *  @type int\n\t\t *  @default 0\n\t\t *  @private\n\t\t */\n\t\t\"_iRecordsTotal\": 0,\n\t\n\t\t/**\n\t\t * Server-side processing - number of records in the current display set\n\t\t * (i.e. after filtering). Use fnRecordsDisplay rather than\n\t\t * this property to get the value of the number of records, regardless of\n\t\t * the server-side processing setting.\n\t\t *  @type boolean\n\t\t *  @default 0\n\t\t *  @private\n\t\t */\n\t\t\"_iRecordsDisplay\": 0,\n\t\n\t\t/**\n\t\t * Flag to indicate if jQuery UI marking and classes should be used.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type boolean\n\t\t */\n\t\t\"bJUI\": null,\n\t\n\t\t/**\n\t\t * The classes to use for the table\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\t\"oClasses\": {},\n\t\n\t\t/**\n\t\t * Flag attached to the settings object so you can check in the draw\n\t\t * callback if filtering has been done in the draw. Deprecated in favour of\n\t\t * events.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *  @deprecated\n\t\t */\n\t\t\"bFiltered\": false,\n\t\n\t\t/**\n\t\t * Flag attached to the settings object so you can check in the draw\n\t\t * callback if sorting has been done in the draw. Deprecated in favour of\n\t\t * events.\n\t\t *  @type boolean\n\t\t *  @default false\n\t\t *  @deprecated\n\t\t */\n\t\t\"bSorted\": false,\n\t\n\t\t/**\n\t\t * Indicate that if multiple rows are in the header and there is more than\n\t\t * one unique cell per column, if the top one (true) or bottom one (false)\n\t\t * should be used for sorting / title by DataTables.\n\t\t * Note that this parameter will be set by the initialisation routine. To\n\t\t * set a default use {@link DataTable.defaults}.\n\t\t *  @type boolean\n\t\t */\n\t\t\"bSortCellsTop\": null,\n\t\n\t\t/**\n\t\t * Initialisation object that is used for the table\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"oInit\": null,\n\t\n\t\t/**\n\t\t * Destroy callback functions - for plug-ins to attach themselves to the\n\t\t * destroy so they can clean up markup and events.\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aoDestroyCallback\": [],\n\t\n\t\n\t\t/**\n\t\t * Get the number of records in the current record set, before filtering\n\t\t *  @type function\n\t\t */\n\t\t\"fnRecordsTotal\": function ()\n\t\t{\n\t\t\treturn _fnDataSource( this ) == 'ssp' ?\n\t\t\t\tthis._iRecordsTotal * 1 :\n\t\t\t\tthis.aiDisplayMaster.length;\n\t\t},\n\t\n\t\t/**\n\t\t * Get the number of records in the current record set, after filtering\n\t\t *  @type function\n\t\t */\n\t\t\"fnRecordsDisplay\": function ()\n\t\t{\n\t\t\treturn _fnDataSource( this ) == 'ssp' ?\n\t\t\t\tthis._iRecordsDisplay * 1 :\n\t\t\t\tthis.aiDisplay.length;\n\t\t},\n\t\n\t\t/**\n\t\t * Get the display end point - aiDisplay index\n\t\t *  @type function\n\t\t */\n\t\t\"fnDisplayEnd\": function ()\n\t\t{\n\t\t\tvar\n\t\t\t\tlen      = this._iDisplayLength,\n\t\t\t\tstart    = this._iDisplayStart,\n\t\t\t\tcalc     = start + len,\n\t\t\t\trecords  = this.aiDisplay.length,\n\t\t\t\tfeatures = this.oFeatures,\n\t\t\t\tpaginate = features.bPaginate;\n\t\n\t\t\tif ( features.bServerSide ) {\n\t\t\t\treturn paginate === false || len === -1 ?\n\t\t\t\t\tstart + records :\n\t\t\t\t\tMath.min( start+len, this._iRecordsDisplay );\n\t\t\t}\n\t\t\telse {\n\t\t\t\treturn ! paginate || calc>records || len===-1 ?\n\t\t\t\t\trecords :\n\t\t\t\t\tcalc;\n\t\t\t}\n\t\t},\n\t\n\t\t/**\n\t\t * The DataTables object for this table\n\t\t *  @type object\n\t\t *  @default null\n\t\t */\n\t\t\"oInstance\": null,\n\t\n\t\t/**\n\t\t * Unique identifier for each instance of the DataTables object. If there\n\t\t * is an ID on the table node, then it takes that value, otherwise an\n\t\t * incrementing internal counter is used.\n\t\t *  @type string\n\t\t *  @default null\n\t\t */\n\t\t\"sInstance\": null,\n\t\n\t\t/**\n\t\t * tabindex attribute value that is added to DataTables control elements, allowing\n\t\t * keyboard navigation of the table and its controls.\n\t\t */\n\t\t\"iTabIndex\": 0,\n\t\n\t\t/**\n\t\t * DIV container for the footer scrolling table if scrolling\n\t\t */\n\t\t\"nScrollHead\": null,\n\t\n\t\t/**\n\t\t * DIV container for the footer scrolling table if scrolling\n\t\t */\n\t\t\"nScrollFoot\": null,\n\t\n\t\t/**\n\t\t * Last applied sort\n\t\t *  @type array\n\t\t *  @default []\n\t\t */\n\t\t\"aLastSort\": [],\n\t\n\t\t/**\n\t\t * Stored plug-in instances\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\t\"oPlugins\": {}\n\t};\n\n\t/**\n\t * Extension object for DataTables that is used to provide all extension\n\t * options.\n\t *\n\t * Note that the `DataTable.ext` object is available through\n\t * `jQuery.fn.dataTable.ext` where it may be accessed and manipulated. It is\n\t * also aliased to `jQuery.fn.dataTableExt` for historic reasons.\n\t *  @namespace\n\t *  @extends DataTable.models.ext\n\t */\n\t\n\t\n\t/**\n\t * DataTables extensions\n\t * \n\t * This namespace acts as a collection area for plug-ins that can be used to\n\t * extend DataTables capabilities. Indeed many of the build in methods\n\t * use this method to provide their own capabilities (sorting methods for\n\t * example).\n\t *\n\t * Note that this namespace is aliased to `jQuery.fn.dataTableExt` for legacy\n\t * reasons\n\t *\n\t *  @namespace\n\t */\n\tDataTable.ext = _ext = {\n\t\t/**\n\t\t * Buttons. For use with the Buttons extension for DataTables. This is\n\t\t * defined here so other extensions can define buttons regardless of load\n\t\t * order. It is _not_ used by DataTables core.\n\t\t *\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\tbuttons: {},\n\t\n\t\n\t\t/**\n\t\t * Element class names\n\t\t *\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\tclasses: {},\n\t\n\t\n\t\t/**\n\t\t * Error reporting.\n\t\t * \n\t\t * How should DataTables report an error. Can take the value 'alert',\n\t\t * 'throw', 'none' or a function.\n\t\t *\n\t\t *  @type string|function\n\t\t *  @default alert\n\t\t */\n\t\terrMode: \"alert\",\n\t\n\t\n\t\t/**\n\t\t * Feature plug-ins.\n\t\t * \n\t\t * This is an array of objects which describe the feature plug-ins that are\n\t\t * available to DataTables. These feature plug-ins are then available for\n\t\t * use through the `dom` initialisation option.\n\t\t * \n\t\t * Each feature plug-in is described by an object which must have the\n\t\t * following properties:\n\t\t * \n\t\t * * `fnInit` - function that is used to initialise the plug-in,\n\t\t * * `cFeature` - a character so the feature can be enabled by the `dom`\n\t\t *   instillation option. This is case sensitive.\n\t\t *\n\t\t * The `fnInit` function has the following input parameters:\n\t\t *\n\t\t * 1. `{object}` DataTables settings object: see\n\t\t *    {@link DataTable.models.oSettings}\n\t\t *\n\t\t * And the following return is expected:\n\t\t * \n\t\t * * {node|null} The element which contains your feature. Note that the\n\t\t *   return may also be void if your plug-in does not require to inject any\n\t\t *   DOM elements into DataTables control (`dom`) - for example this might\n\t\t *   be useful when developing a plug-in which allows table control via\n\t\t *   keyboard entry\n\t\t *\n\t\t *  @type array\n\t\t *\n\t\t *  @example\n\t\t *    $.fn.dataTable.ext.features.push( {\n\t\t *      \"fnInit\": function( oSettings ) {\n\t\t *        return new TableTools( { \"oDTSettings\": oSettings } );\n\t\t *      },\n\t\t *      \"cFeature\": \"T\"\n\t\t *    } );\n\t\t */\n\t\tfeature: [],\n\t\n\t\n\t\t/**\n\t\t * Row searching.\n\t\t * \n\t\t * This method of searching is complimentary to the default type based\n\t\t * searching, and a lot more comprehensive as it allows you complete control\n\t\t * over the searching logic. Each element in this array is a function\n\t\t * (parameters described below) that is called for every row in the table,\n\t\t * and your logic decides if it should be included in the searching data set\n\t\t * or not.\n\t\t *\n\t\t * Searching functions have the following input parameters:\n\t\t *\n\t\t * 1. `{object}` DataTables settings object: see\n\t\t *    {@link DataTable.models.oSettings}\n\t\t * 2. `{array|object}` Data for the row to be processed (same as the\n\t\t *    original format that was passed in as the data source, or an array\n\t\t *    from a DOM data source\n\t\t * 3. `{int}` Row index ({@link DataTable.models.oSettings.aoData}), which\n\t\t *    can be useful to retrieve the `TR` element if you need DOM interaction.\n\t\t *\n\t\t * And the following return is expected:\n\t\t *\n\t\t * * {boolean} Include the row in the searched result set (true) or not\n\t\t *   (false)\n\t\t *\n\t\t * Note that as with the main search ability in DataTables, technically this\n\t\t * is \"filtering\", since it is subtractive. However, for consistency in\n\t\t * naming we call it searching here.\n\t\t *\n\t\t *  @type array\n\t\t *  @default []\n\t\t *\n\t\t *  @example\n\t\t *    // The following example shows custom search being applied to the\n\t\t *    // fourth column (i.e. the data[3] index) based on two input values\n\t\t *    // from the end-user, matching the data in a certain range.\n\t\t *    $.fn.dataTable.ext.search.push(\n\t\t *      function( settings, data, dataIndex ) {\n\t\t *        var min = document.getElementById('min').value * 1;\n\t\t *        var max = document.getElementById('max').value * 1;\n\t\t *        var version = data[3] == \"-\" ? 0 : data[3]*1;\n\t\t *\n\t\t *        if ( min == \"\" && max == \"\" ) {\n\t\t *          return true;\n\t\t *        }\n\t\t *        else if ( min == \"\" && version < max ) {\n\t\t *          return true;\n\t\t *        }\n\t\t *        else if ( min < version && \"\" == max ) {\n\t\t *          return true;\n\t\t *        }\n\t\t *        else if ( min < version && version < max ) {\n\t\t *          return true;\n\t\t *        }\n\t\t *        return false;\n\t\t *      }\n\t\t *    );\n\t\t */\n\t\tsearch: [],\n\t\n\t\n\t\t/**\n\t\t * Selector extensions\n\t\t *\n\t\t * The `selector` option can be used to extend the options available for the\n\t\t * selector modifier options (`selector-modifier` object data type) that\n\t\t * each of the three built in selector types offer (row, column and cell +\n\t\t * their plural counterparts). For example the Select extension uses this\n\t\t * mechanism to provide an option to select only rows, columns and cells\n\t\t * that have been marked as selected by the end user (`{selected: true}`),\n\t\t * which can be used in conjunction with the existing built in selector\n\t\t * options.\n\t\t *\n\t\t * Each property is an array to which functions can be pushed. The functions\n\t\t * take three attributes:\n\t\t *\n\t\t * * Settings object for the host table\n\t\t * * Options object (`selector-modifier` object type)\n\t\t * * Array of selected item indexes\n\t\t *\n\t\t * The return is an array of the resulting item indexes after the custom\n\t\t * selector has been applied.\n\t\t *\n\t\t *  @type object\n\t\t */\n\t\tselector: {\n\t\t\tcell: [],\n\t\t\tcolumn: [],\n\t\t\trow: []\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Internal functions, exposed for used in plug-ins.\n\t\t * \n\t\t * Please note that you should not need to use the internal methods for\n\t\t * anything other than a plug-in (and even then, try to avoid if possible).\n\t\t * The internal function may change between releases.\n\t\t *\n\t\t *  @type object\n\t\t *  @default {}\n\t\t */\n\t\tinternal: {},\n\t\n\t\n\t\t/**\n\t\t * Legacy configuration options. Enable and disable legacy options that\n\t\t * are available in DataTables.\n\t\t *\n\t\t *  @type object\n\t\t */\n\t\tlegacy: {\n\t\t\t/**\n\t\t\t * Enable / disable DataTables 1.9 compatible server-side processing\n\t\t\t * requests\n\t\t\t *\n\t\t\t *  @type boolean\n\t\t\t *  @default null\n\t\t\t */\n\t\t\tajax: null\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Pagination plug-in methods.\n\t\t * \n\t\t * Each entry in this object is a function and defines which buttons should\n\t\t * be shown by the pagination rendering method that is used for the table:\n\t\t * {@link DataTable.ext.renderer.pageButton}. The renderer addresses how the\n\t\t * buttons are displayed in the document, while the functions here tell it\n\t\t * what buttons to display. This is done by returning an array of button\n\t\t * descriptions (what each button will do).\n\t\t *\n\t\t * Pagination types (the four built in options and any additional plug-in\n\t\t * options defined here) can be used through the `paginationType`\n\t\t * initialisation parameter.\n\t\t *\n\t\t * The functions defined take two parameters:\n\t\t *\n\t\t * 1. `{int} page` The current page index\n\t\t * 2. `{int} pages` The number of pages in the table\n\t\t *\n\t\t * Each function is expected to return an array where each element of the\n\t\t * array can be one of:\n\t\t *\n\t\t * * `first` - Jump to first page when activated\n\t\t * * `last` - Jump to last page when activated\n\t\t * * `previous` - Show previous page when activated\n\t\t * * `next` - Show next page when activated\n\t\t * * `{int}` - Show page of the index given\n\t\t * * `{array}` - A nested array containing the above elements to add a\n\t\t *   containing 'DIV' element (might be useful for styling).\n\t\t *\n\t\t * Note that DataTables v1.9- used this object slightly differently whereby\n\t\t * an object with two functions would be defined for each plug-in. That\n\t\t * ability is still supported by DataTables 1.10+ to provide backwards\n\t\t * compatibility, but this option of use is now decremented and no longer\n\t\t * documented in DataTables 1.10+.\n\t\t *\n\t\t *  @type object\n\t\t *  @default {}\n\t\t *\n\t\t *  @example\n\t\t *    // Show previous, next and current page buttons only\n\t\t *    $.fn.dataTableExt.oPagination.current = function ( page, pages ) {\n\t\t *      return [ 'previous', page, 'next' ];\n\t\t *    };\n\t\t */\n\t\tpager: {},\n\t\n\t\n\t\trenderer: {\n\t\t\tpageButton: {},\n\t\t\theader: {}\n\t\t},\n\t\n\t\n\t\t/**\n\t\t * Ordering plug-ins - custom data source\n\t\t * \n\t\t * The extension options for ordering of data available here is complimentary\n\t\t * to the default type based ordering that DataTables typically uses. It\n\t\t * allows much greater control over the the data that is being used to\n\t\t * order a column, but is necessarily therefore more complex.\n\t\t * \n\t\t * This type of ordering is useful if you want to do ordering based on data\n\t\t * live from the DOM (for example the contents of an 'input' element) rather\n\t\t * than just the static string that DataTables knows of.\n\t\t * \n\t\t * The way these plug-ins work is that you create an array of the values you\n\t\t * wish to be ordering for the column in question and then return that\n\t\t * array. The data in the array much be in the index order of the rows in\n\t\t * the table (not the currently ordering order!). Which order data gathering\n\t\t * function is run here depends on the `dt-init columns.orderDataType`\n\t\t * parameter that is used for the column (if any).\n\t\t *\n\t\t * The functions defined take two parameters:\n\t\t *\n\t\t * 1. `{object}` DataTables settings object: see\n\t\t *    {@link DataTable.models.oSettings}\n\t\t * 2. `{int}` Target column index\n\t\t *\n\t\t * Each function is expected to return an array:\n\t\t *\n\t\t * * `{array}` Data for the column to be ordering upon\n\t\t *\n\t\t *  @type array\n\t\t *\n\t\t *  @example\n\t\t *    // Ordering using `input` node values\n\t\t *    $.fn.dataTable.ext.order['dom-text'] = function  ( settings, col )\n\t\t *    {\n\t\t *      return this.api().column( col, {order:'index'} ).nodes().map( function ( td, i ) {\n\t\t *        return $('input', td).val();\n\t\t *      } );\n\t\t *    }\n\t\t */\n\t\torder: {},\n\t\n\t\n\t\t/**\n\t\t * Type based plug-ins.\n\t\t *\n\t\t * Each column in DataTables has a type assigned to it, either by automatic\n\t\t * detection or by direct assignment using the `type` option for the column.\n\t\t * The type of a column will effect how it is ordering and search (plug-ins\n\t\t * can also make use of the column type if required).\n\t\t *\n\t\t * @namespace\n\t\t */\n\t\ttype: {\n\t\t\t/**\n\t\t\t * Type detection functions.\n\t\t\t *\n\t\t\t * The functions defined in this object are used to automatically detect\n\t\t\t * a column's type, making initialisation of DataTables super easy, even\n\t\t\t * when complex data is in the table.\n\t\t\t *\n\t\t\t * The functions defined take two parameters:\n\t\t\t *\n\t\t     *  1. `{*}` Data from the column cell to be analysed\n\t\t     *  2. `{settings}` DataTables settings object. This can be used to\n\t\t     *     perform context specific type detection - for example detection\n\t\t     *     based on language settings such as using a comma for a decimal\n\t\t     *     place. Generally speaking the options from the settings will not\n\t\t     *     be required\n\t\t\t *\n\t\t\t * Each function is expected to return:\n\t\t\t *\n\t\t\t * * `{string|null}` Data type detected, or null if unknown (and thus\n\t\t\t *   pass it on to the other type detection functions.\n\t\t\t *\n\t\t\t *  @type array\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Currency type detection plug-in:\n\t\t\t *    $.fn.dataTable.ext.type.detect.push(\n\t\t\t *      function ( data, settings ) {\n\t\t\t *        // Check the numeric part\n\t\t\t *        if ( ! $.isNumeric( data.substring(1) ) ) {\n\t\t\t *          return null;\n\t\t\t *        }\n\t\t\t *\n\t\t\t *        // Check prefixed by currency\n\t\t\t *        if ( data.charAt(0) == '$' || data.charAt(0) == '&pound;' ) {\n\t\t\t *          return 'currency';\n\t\t\t *        }\n\t\t\t *        return null;\n\t\t\t *      }\n\t\t\t *    );\n\t\t\t */\n\t\t\tdetect: [],\n\t\n\t\n\t\t\t/**\n\t\t\t * Type based search formatting.\n\t\t\t *\n\t\t\t * The type based searching functions can be used to pre-format the\n\t\t\t * data to be search on. For example, it can be used to strip HTML\n\t\t\t * tags or to de-format telephone numbers for numeric only searching.\n\t\t\t *\n\t\t\t * Note that is a search is not defined for a column of a given type,\n\t\t\t * no search formatting will be performed.\n\t\t\t * \n\t\t\t * Pre-processing of searching data plug-ins - When you assign the sType\n\t\t\t * for a column (or have it automatically detected for you by DataTables\n\t\t\t * or a type detection plug-in), you will typically be using this for\n\t\t\t * custom sorting, but it can also be used to provide custom searching\n\t\t\t * by allowing you to pre-processing the data and returning the data in\n\t\t\t * the format that should be searched upon. This is done by adding\n\t\t\t * functions this object with a parameter name which matches the sType\n\t\t\t * for that target column. This is the corollary of <i>afnSortData</i>\n\t\t\t * for searching data.\n\t\t\t *\n\t\t\t * The functions defined take a single parameter:\n\t\t\t *\n\t\t     *  1. `{*}` Data from the column cell to be prepared for searching\n\t\t\t *\n\t\t\t * Each function is expected to return:\n\t\t\t *\n\t\t\t * * `{string|null}` Formatted string that will be used for the searching.\n\t\t\t *\n\t\t\t *  @type object\n\t\t\t *  @default {}\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    $.fn.dataTable.ext.type.search['title-numeric'] = function ( d ) {\n\t\t\t *      return d.replace(/\\n/g,\" \").replace( /<.*?>/g, \"\" );\n\t\t\t *    }\n\t\t\t */\n\t\t\tsearch: {},\n\t\n\t\n\t\t\t/**\n\t\t\t * Type based ordering.\n\t\t\t *\n\t\t\t * The column type tells DataTables what ordering to apply to the table\n\t\t\t * when a column is sorted upon. The order for each type that is defined,\n\t\t\t * is defined by the functions available in this object.\n\t\t\t *\n\t\t\t * Each ordering option can be described by three properties added to\n\t\t\t * this object:\n\t\t\t *\n\t\t\t * * `{type}-pre` - Pre-formatting function\n\t\t\t * * `{type}-asc` - Ascending order function\n\t\t\t * * `{type}-desc` - Descending order function\n\t\t\t *\n\t\t\t * All three can be used together, only `{type}-pre` or only\n\t\t\t * `{type}-asc` and `{type}-desc` together. It is generally recommended\n\t\t\t * that only `{type}-pre` is used, as this provides the optimal\n\t\t\t * implementation in terms of speed, although the others are provided\n\t\t\t * for compatibility with existing Javascript sort functions.\n\t\t\t *\n\t\t\t * `{type}-pre`: Functions defined take a single parameter:\n\t\t\t *\n\t\t     *  1. `{*}` Data from the column cell to be prepared for ordering\n\t\t\t *\n\t\t\t * And return:\n\t\t\t *\n\t\t\t * * `{*}` Data to be sorted upon\n\t\t\t *\n\t\t\t * `{type}-asc` and `{type}-desc`: Functions are typical Javascript sort\n\t\t\t * functions, taking two parameters:\n\t\t\t *\n\t\t     *  1. `{*}` Data to compare to the second parameter\n\t\t     *  2. `{*}` Data to compare to the first parameter\n\t\t\t *\n\t\t\t * And returning:\n\t\t\t *\n\t\t\t * * `{*}` Ordering match: <0 if first parameter should be sorted lower\n\t\t\t *   than the second parameter, ===0 if the two parameters are equal and\n\t\t\t *   >0 if the first parameter should be sorted height than the second\n\t\t\t *   parameter.\n\t\t\t * \n\t\t\t *  @type object\n\t\t\t *  @default {}\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Numeric ordering of formatted numbers with a pre-formatter\n\t\t\t *    $.extend( $.fn.dataTable.ext.type.order, {\n\t\t\t *      \"string-pre\": function(x) {\n\t\t\t *        a = (a === \"-\" || a === \"\") ? 0 : a.replace( /[^\\d\\-\\.]/g, \"\" );\n\t\t\t *        return parseFloat( a );\n\t\t\t *      }\n\t\t\t *    } );\n\t\t\t *\n\t\t\t *  @example\n\t\t\t *    // Case-sensitive string ordering, with no pre-formatting method\n\t\t\t *    $.extend( $.fn.dataTable.ext.order, {\n\t\t\t *      \"string-case-asc\": function(x,y) {\n\t\t\t *        return ((x < y) ? -1 : ((x > y) ? 1 : 0));\n\t\t\t *      },\n\t\t\t *      \"string-case-desc\": function(x,y) {\n\t\t\t *        return ((x < y) ? 1 : ((x > y) ? -1 : 0));\n\t\t\t *      }\n\t\t\t *    } );\n\t\t\t */\n\t\t\torder: {}\n\t\t},\n\t\n\t\t/**\n\t\t * Unique DataTables instance counter\n\t\t *\n\t\t * @type int\n\t\t * @private\n\t\t */\n\t\t_unique: 0,\n\t\n\t\n\t\t//\n\t\t// Depreciated\n\t\t// The following properties are retained for backwards compatiblity only.\n\t\t// The should not be used in new projects and will be removed in a future\n\t\t// version\n\t\t//\n\t\n\t\t/**\n\t\t * Version check function.\n\t\t *  @type function\n\t\t *  @depreciated Since 1.10\n\t\t */\n\t\tfnVersionCheck: DataTable.fnVersionCheck,\n\t\n\t\n\t\t/**\n\t\t * Index for what 'this' index API functions should use\n\t\t *  @type int\n\t\t *  @deprecated Since v1.10\n\t\t */\n\t\tiApiIndex: 0,\n\t\n\t\n\t\t/**\n\t\t * jQuery UI class container\n\t\t *  @type object\n\t\t *  @deprecated Since v1.10\n\t\t */\n\t\toJUIClasses: {},\n\t\n\t\n\t\t/**\n\t\t * Software version\n\t\t *  @type string\n\t\t *  @deprecated Since v1.10\n\t\t */\n\t\tsVersion: DataTable.version\n\t};\n\t\n\t\n\t//\n\t// Backwards compatibility. Alias to pre 1.10 Hungarian notation counter parts\n\t//\n\t$.extend( _ext, {\n\t\tafnFiltering: _ext.search,\n\t\taTypes:       _ext.type.detect,\n\t\tofnSearch:    _ext.type.search,\n\t\toSort:        _ext.type.order,\n\t\tafnSortData:  _ext.order,\n\t\taoFeatures:   _ext.feature,\n\t\toApi:         _ext.internal,\n\t\toStdClasses:  _ext.classes,\n\t\toPagination:  _ext.pager\n\t} );\n\t\n\t\n\t$.extend( DataTable.ext.classes, {\n\t\t\"sTable\": \"dataTable\",\n\t\t\"sNoFooter\": \"no-footer\",\n\t\n\t\t/* Paging buttons */\n\t\t\"sPageButton\": \"paginate_button\",\n\t\t\"sPageButtonActive\": \"current\",\n\t\t\"sPageButtonDisabled\": \"disabled\",\n\t\n\t\t/* Striping classes */\n\t\t\"sStripeOdd\": \"odd\",\n\t\t\"sStripeEven\": \"even\",\n\t\n\t\t/* Empty row */\n\t\t\"sRowEmpty\": \"dataTables_empty\",\n\t\n\t\t/* Features */\n\t\t\"sWrapper\": \"dataTables_wrapper\",\n\t\t\"sFilter\": \"dataTables_filter\",\n\t\t\"sInfo\": \"dataTables_info\",\n\t\t\"sPaging\": \"dataTables_paginate paging_\", /* Note that the type is postfixed */\n\t\t\"sLength\": \"dataTables_length\",\n\t\t\"sProcessing\": \"dataTables_processing\",\n\t\n\t\t/* Sorting */\n\t\t\"sSortAsc\": \"sorting_asc\",\n\t\t\"sSortDesc\": \"sorting_desc\",\n\t\t\"sSortable\": \"sorting\", /* Sortable in both directions */\n\t\t\"sSortableAsc\": \"sorting_asc_disabled\",\n\t\t\"sSortableDesc\": \"sorting_desc_disabled\",\n\t\t\"sSortableNone\": \"sorting_disabled\",\n\t\t\"sSortColumn\": \"sorting_\", /* Note that an int is postfixed for the sorting order */\n\t\n\t\t/* Filtering */\n\t\t\"sFilterInput\": \"\",\n\t\n\t\t/* Page length */\n\t\t\"sLengthSelect\": \"\",\n\t\n\t\t/* Scrolling */\n\t\t\"sScrollWrapper\": \"dataTables_scroll\",\n\t\t\"sScrollHead\": \"dataTables_scrollHead\",\n\t\t\"sScrollHeadInner\": \"dataTables_scrollHeadInner\",\n\t\t\"sScrollBody\": \"dataTables_scrollBody\",\n\t\t\"sScrollFoot\": \"dataTables_scrollFoot\",\n\t\t\"sScrollFootInner\": \"dataTables_scrollFootInner\",\n\t\n\t\t/* Misc */\n\t\t\"sHeaderTH\": \"\",\n\t\t\"sFooterTH\": \"\",\n\t\n\t\t// Deprecated\n\t\t\"sSortJUIAsc\": \"\",\n\t\t\"sSortJUIDesc\": \"\",\n\t\t\"sSortJUI\": \"\",\n\t\t\"sSortJUIAscAllowed\": \"\",\n\t\t\"sSortJUIDescAllowed\": \"\",\n\t\t\"sSortJUIWrapper\": \"\",\n\t\t\"sSortIcon\": \"\",\n\t\t\"sJUIHeader\": \"\",\n\t\t\"sJUIFooter\": \"\"\n\t} );\n\t\n\t\n\t(function() {\n\t\n\t// Reused strings for better compression. Closure compiler appears to have a\n\t// weird edge case where it is trying to expand strings rather than use the\n\t// variable version. This results in about 200 bytes being added, for very\n\t// little preference benefit since it this run on script load only.\n\tvar _empty = '';\n\t_empty = '';\n\t\n\tvar _stateDefault = _empty + 'ui-state-default';\n\tvar _sortIcon     = _empty + 'css_right ui-icon ui-icon-';\n\tvar _headerFooter = _empty + 'fg-toolbar ui-toolbar ui-widget-header ui-helper-clearfix';\n\t\n\t$.extend( DataTable.ext.oJUIClasses, DataTable.ext.classes, {\n\t\t/* Full numbers paging buttons */\n\t\t\"sPageButton\":         \"fg-button ui-button \"+_stateDefault,\n\t\t\"sPageButtonActive\":   \"ui-state-disabled\",\n\t\t\"sPageButtonDisabled\": \"ui-state-disabled\",\n\t\n\t\t/* Features */\n\t\t\"sPaging\": \"dataTables_paginate fg-buttonset ui-buttonset fg-buttonset-multi \"+\n\t\t\t\"ui-buttonset-multi paging_\", /* Note that the type is postfixed */\n\t\n\t\t/* Sorting */\n\t\t\"sSortAsc\":            _stateDefault+\" sorting_asc\",\n\t\t\"sSortDesc\":           _stateDefault+\" sorting_desc\",\n\t\t\"sSortable\":           _stateDefault+\" sorting\",\n\t\t\"sSortableAsc\":        _stateDefault+\" sorting_asc_disabled\",\n\t\t\"sSortableDesc\":       _stateDefault+\" sorting_desc_disabled\",\n\t\t\"sSortableNone\":       _stateDefault+\" sorting_disabled\",\n\t\t\"sSortJUIAsc\":         _sortIcon+\"triangle-1-n\",\n\t\t\"sSortJUIDesc\":        _sortIcon+\"triangle-1-s\",\n\t\t\"sSortJUI\":            _sortIcon+\"carat-2-n-s\",\n\t\t\"sSortJUIAscAllowed\":  _sortIcon+\"carat-1-n\",\n\t\t\"sSortJUIDescAllowed\": _sortIcon+\"carat-1-s\",\n\t\t\"sSortJUIWrapper\":     \"DataTables_sort_wrapper\",\n\t\t\"sSortIcon\":           \"DataTables_sort_icon\",\n\t\n\t\t/* Scrolling */\n\t\t\"sScrollHead\": \"dataTables_scrollHead \"+_stateDefault,\n\t\t\"sScrollFoot\": \"dataTables_scrollFoot \"+_stateDefault,\n\t\n\t\t/* Misc */\n\t\t\"sHeaderTH\":  _stateDefault,\n\t\t\"sFooterTH\":  _stateDefault,\n\t\t\"sJUIHeader\": _headerFooter+\" ui-corner-tl ui-corner-tr\",\n\t\t\"sJUIFooter\": _headerFooter+\" ui-corner-bl ui-corner-br\"\n\t} );\n\t\n\t}());\n\t\n\t\n\t\n\tvar extPagination = DataTable.ext.pager;\n\t\n\tfunction _numbers ( page, pages ) {\n\t\tvar\n\t\t\tnumbers = [],\n\t\t\tbuttons = extPagination.numbers_length,\n\t\t\thalf = Math.floor( buttons / 2 ),\n\t\t\ti = 1;\n\t\n\t\tif ( pages <= buttons ) {\n\t\t\tnumbers = _range( 0, pages );\n\t\t}\n\t\telse if ( page <= half ) {\n\t\t\tnumbers = _range( 0, buttons-2 );\n\t\t\tnumbers.push( 'ellipsis' );\n\t\t\tnumbers.push( pages-1 );\n\t\t}\n\t\telse if ( page >= pages - 1 - half ) {\n\t\t\tnumbers = _range( pages-(buttons-2), pages );\n\t\t\tnumbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6\n\t\t\tnumbers.splice( 0, 0, 0 );\n\t\t}\n\t\telse {\n\t\t\tnumbers = _range( page-half+2, page+half-1 );\n\t\t\tnumbers.push( 'ellipsis' );\n\t\t\tnumbers.push( pages-1 );\n\t\t\tnumbers.splice( 0, 0, 'ellipsis' );\n\t\t\tnumbers.splice( 0, 0, 0 );\n\t\t}\n\t\n\t\tnumbers.DT_el = 'span';\n\t\treturn numbers;\n\t}\n\t\n\t\n\t$.extend( extPagination, {\n\t\tsimple: function ( page, pages ) {\n\t\t\treturn [ 'previous', 'next' ];\n\t\t},\n\t\n\t\tfull: function ( page, pages ) {\n\t\t\treturn [  'first', 'previous', 'next', 'last' ];\n\t\t},\n\t\n\t\tsimple_numbers: function ( page, pages ) {\n\t\t\treturn [ 'previous', _numbers(page, pages), 'next' ];\n\t\t},\n\t\n\t\tfull_numbers: function ( page, pages ) {\n\t\t\treturn [ 'first', 'previous', _numbers(page, pages), 'next', 'last' ];\n\t\t},\n\t\n\t\t// For testing and plug-ins to use\n\t\t_numbers: _numbers,\n\t\n\t\t// Number of number buttons (including ellipsis) to show. _Must be odd!_\n\t\tnumbers_length: 7\n\t} );\n\t\n\t\n\t$.extend( true, DataTable.ext.renderer, {\n\t\tpageButton: {\n\t\t\t_: function ( settings, host, idx, buttons, page, pages ) {\n\t\t\t\tvar classes = settings.oClasses;\n\t\t\t\tvar lang = settings.oLanguage.oPaginate;\n\t\t\t\tvar btnDisplay, btnClass, counter=0;\n\t\n\t\t\t\tvar attach = function( container, buttons ) {\n\t\t\t\t\tvar i, ien, node, button;\n\t\t\t\t\tvar clickHandler = function ( e ) {\n\t\t\t\t\t\t_fnPageChange( settings, e.data.action, true );\n\t\t\t\t\t};\n\t\n\t\t\t\t\tfor ( i=0, ien=buttons.length ; i<ien ; i++ ) {\n\t\t\t\t\t\tbutton = buttons[i];\n\t\n\t\t\t\t\t\tif ( $.isArray( button ) ) {\n\t\t\t\t\t\t\tvar inner = $( '<'+(button.DT_el || 'div')+'/>' )\n\t\t\t\t\t\t\t\t.appendTo( container );\n\t\t\t\t\t\t\tattach( inner, button );\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tbtnDisplay = '';\n\t\t\t\t\t\t\tbtnClass = '';\n\t\n\t\t\t\t\t\t\tswitch ( button ) {\n\t\t\t\t\t\t\t\tcase 'ellipsis':\n\t\t\t\t\t\t\t\t\tcontainer.append('<span class=\"ellipsis\">&#x2026;</span>');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tcase 'first':\n\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sFirst;\n\t\t\t\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tcase 'previous':\n\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sPrevious;\n\t\t\t\t\t\t\t\t\tbtnClass = button + (page > 0 ?\n\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tcase 'next':\n\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sNext;\n\t\t\t\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tcase 'last':\n\t\t\t\t\t\t\t\t\tbtnDisplay = lang.sLast;\n\t\t\t\t\t\t\t\t\tbtnClass = button + (page < pages-1 ?\n\t\t\t\t\t\t\t\t\t\t'' : ' '+classes.sPageButtonDisabled);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\n\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\tbtnDisplay = button + 1;\n\t\t\t\t\t\t\t\t\tbtnClass = page === button ?\n\t\t\t\t\t\t\t\t\t\tclasses.sPageButtonActive : '';\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t\tif ( btnDisplay ) {\n\t\t\t\t\t\t\t\tnode = $('<a>', {\n\t\t\t\t\t\t\t\t\t\t'class': classes.sPageButton+' '+btnClass,\n\t\t\t\t\t\t\t\t\t\t'aria-controls': settings.sTableId,\n\t\t\t\t\t\t\t\t\t\t'data-dt-idx': counter,\n\t\t\t\t\t\t\t\t\t\t'tabindex': settings.iTabIndex,\n\t\t\t\t\t\t\t\t\t\t'id': idx === 0 && typeof button === 'string' ?\n\t\t\t\t\t\t\t\t\t\t\tsettings.sTableId +'_'+ button :\n\t\t\t\t\t\t\t\t\t\t\tnull\n\t\t\t\t\t\t\t\t\t} )\n\t\t\t\t\t\t\t\t\t.html( btnDisplay )\n\t\t\t\t\t\t\t\t\t.appendTo( container );\n\t\n\t\t\t\t\t\t\t\t_fnBindAction(\n\t\t\t\t\t\t\t\t\tnode, {action: button}, clickHandler\n\t\t\t\t\t\t\t\t);\n\t\n\t\t\t\t\t\t\t\tcounter++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\n\t\t\t\t// IE9 throws an 'unknown error' if document.activeElement is used\n\t\t\t\t// inside an iframe or frame. Try / catch the error. Not good for\n\t\t\t\t// accessibility, but neither are frames.\n\t\t\t\tvar activeEl;\n\t\n\t\t\t\ttry {\n\t\t\t\t\t// Because this approach is destroying and recreating the paging\n\t\t\t\t\t// elements, focus is lost on the select button which is bad for\n\t\t\t\t\t// accessibility. So we want to restore focus once the draw has\n\t\t\t\t\t// completed\n\t\t\t\t\tactiveEl = $(document.activeElement).data('dt-idx');\n\t\t\t\t}\n\t\t\t\tcatch (e) {}\n\t\n\t\t\t\tattach( $(host).empty(), buttons );\n\t\n\t\t\t\tif ( activeEl ) {\n\t\t\t\t\t$(host).find( '[data-dt-idx='+activeEl+']' ).focus();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t} );\n\t\n\t\n\t\n\t// Built in type detection. See model.ext.aTypes for information about\n\t// what is required from this methods.\n\t$.extend( DataTable.ext.type.detect, [\n\t\t// Plain numbers - first since V8 detects some plain numbers as dates\n\t\t// e.g. Date.parse('55') (but not all, e.g. Date.parse('22')...).\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\t\treturn _isNumber( d, decimal ) ? 'num'+decimal : null;\n\t\t},\n\t\n\t\t// Dates (only those recognised by the browser's Date.parse)\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\t// V8 will remove any unknown characters at the start and end of the\n\t\t\t// expression, leading to false matches such as `$245.12` or `10%` being\n\t\t\t// a valid date. See forum thread 18941 for detail.\n\t\t\tif ( d && !(d instanceof Date) && ( ! _re_date_start.test(d) || ! _re_date_end.test(d) ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t\tvar parsed = Date.parse(d);\n\t\t\treturn (parsed !== null && !isNaN(parsed)) || _empty(d) ? 'date' : null;\n\t\t},\n\t\n\t\t// Formatted numbers\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\t\treturn _isNumber( d, decimal, true ) ? 'num-fmt'+decimal : null;\n\t\t},\n\t\n\t\t// HTML numeric\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\t\treturn _htmlNumeric( d, decimal ) ? 'html-num'+decimal : null;\n\t\t},\n\t\n\t\t// HTML numeric, formatted\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\tvar decimal = settings.oLanguage.sDecimal;\n\t\t\treturn _htmlNumeric( d, decimal, true ) ? 'html-num-fmt'+decimal : null;\n\t\t},\n\t\n\t\t// HTML (this is strict checking - there must be html)\n\t\tfunction ( d, settings )\n\t\t{\n\t\t\treturn _empty( d ) || (typeof d === 'string' && d.indexOf('<') !== -1) ?\n\t\t\t\t'html' : null;\n\t\t}\n\t] );\n\t\n\t\n\t\n\t// Filter formatting functions. See model.ext.ofnSearch for information about\n\t// what is required from these methods.\n\t// \n\t// Note that additional search methods are added for the html numbers and\n\t// html formatted numbers by `_addNumericSort()` when we know what the decimal\n\t// place is\n\t\n\t\n\t$.extend( DataTable.ext.type.search, {\n\t\thtml: function ( data ) {\n\t\t\treturn _empty(data) ?\n\t\t\t\tdata :\n\t\t\t\ttypeof data === 'string' ?\n\t\t\t\t\tdata\n\t\t\t\t\t\t.replace( _re_new_lines, \" \" )\n\t\t\t\t\t\t.replace( _re_html, \"\" ) :\n\t\t\t\t\t'';\n\t\t},\n\t\n\t\tstring: function ( data ) {\n\t\t\treturn _empty(data) ?\n\t\t\t\tdata :\n\t\t\t\ttypeof data === 'string' ?\n\t\t\t\t\tdata.replace( _re_new_lines, \" \" ) :\n\t\t\t\t\tdata;\n\t\t}\n\t} );\n\t\n\t\n\t\n\tvar __numericReplace = function ( d, decimalPlace, re1, re2 ) {\n\t\tif ( d !== 0 && (!d || d === '-') ) {\n\t\t\treturn -Infinity;\n\t\t}\n\t\n\t\t// If a decimal place other than `.` is used, it needs to be given to the\n\t\t// function so we can detect it and replace with a `.` which is the only\n\t\t// decimal place Javascript recognises - it is not locale aware.\n\t\tif ( decimalPlace ) {\n\t\t\td = _numToDecimal( d, decimalPlace );\n\t\t}\n\t\n\t\tif ( d.replace ) {\n\t\t\tif ( re1 ) {\n\t\t\t\td = d.replace( re1, '' );\n\t\t\t}\n\t\n\t\t\tif ( re2 ) {\n\t\t\t\td = d.replace( re2, '' );\n\t\t\t}\n\t\t}\n\t\n\t\treturn d * 1;\n\t};\n\t\n\t\n\t// Add the numeric 'deformatting' functions for sorting and search. This is done\n\t// in a function to provide an easy ability for the language options to add\n\t// additional methods if a non-period decimal place is used.\n\tfunction _addNumericSort ( decimalPlace ) {\n\t\t$.each(\n\t\t\t{\n\t\t\t\t// Plain numbers\n\t\t\t\t\"num\": function ( d ) {\n\t\t\t\t\treturn __numericReplace( d, decimalPlace );\n\t\t\t\t},\n\t\n\t\t\t\t// Formatted numbers\n\t\t\t\t\"num-fmt\": function ( d ) {\n\t\t\t\t\treturn __numericReplace( d, decimalPlace, _re_formatted_numeric );\n\t\t\t\t},\n\t\n\t\t\t\t// HTML numeric\n\t\t\t\t\"html-num\": function ( d ) {\n\t\t\t\t\treturn __numericReplace( d, decimalPlace, _re_html );\n\t\t\t\t},\n\t\n\t\t\t\t// HTML numeric, formatted\n\t\t\t\t\"html-num-fmt\": function ( d ) {\n\t\t\t\t\treturn __numericReplace( d, decimalPlace, _re_html, _re_formatted_numeric );\n\t\t\t\t}\n\t\t\t},\n\t\t\tfunction ( key, fn ) {\n\t\t\t\t// Add the ordering method\n\t\t\t\t_ext.type.order[ key+decimalPlace+'-pre' ] = fn;\n\t\n\t\t\t\t// For HTML types add a search formatter that will strip the HTML\n\t\t\t\tif ( key.match(/^html\\-/) ) {\n\t\t\t\t\t_ext.type.search[ key+decimalPlace ] = _ext.type.search.html;\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\t\n\t\n\t// Default sort methods\n\t$.extend( _ext.type.order, {\n\t\t// Dates\n\t\t\"date-pre\": function ( d ) {\n\t\t\treturn Date.parse( d ) || 0;\n\t\t},\n\t\n\t\t// html\n\t\t\"html-pre\": function ( a ) {\n\t\t\treturn _empty(a) ?\n\t\t\t\t'' :\n\t\t\t\ta.replace ?\n\t\t\t\t\ta.replace( /<.*?>/g, \"\" ).toLowerCase() :\n\t\t\t\t\ta+'';\n\t\t},\n\t\n\t\t// string\n\t\t\"string-pre\": function ( a ) {\n\t\t\t// This is a little complex, but faster than always calling toString,\n\t\t\t// http://jsperf.com/tostring-v-check\n\t\t\treturn _empty(a) ?\n\t\t\t\t'' :\n\t\t\t\ttypeof a === 'string' ?\n\t\t\t\t\ta.toLowerCase() :\n\t\t\t\t\t! a.toString ?\n\t\t\t\t\t\t'' :\n\t\t\t\t\t\ta.toString();\n\t\t},\n\t\n\t\t// string-asc and -desc are retained only for compatibility with the old\n\t\t// sort methods\n\t\t\"string-asc\": function ( x, y ) {\n\t\t\treturn ((x < y) ? -1 : ((x > y) ? 1 : 0));\n\t\t},\n\t\n\t\t\"string-desc\": function ( x, y ) {\n\t\t\treturn ((x < y) ? 1 : ((x > y) ? -1 : 0));\n\t\t}\n\t} );\n\t\n\t\n\t// Numeric sorting types - order doesn't matter here\n\t_addNumericSort( '' );\n\t\n\t\n\t$.extend( true, DataTable.ext.renderer, {\n\t\theader: {\n\t\t\t_: function ( settings, cell, column, classes ) {\n\t\t\t\t// No additional mark-up required\n\t\t\t\t// Attach a sort listener to update on sort - note that using the\n\t\t\t\t// `DT` namespace will allow the event to be removed automatically\n\t\t\t\t// on destroy, while the `dt` namespaced event is the one we are\n\t\t\t\t// listening for\n\t\t\t\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\n\t\t\t\t\tif ( settings !== ctx ) { // need to check this this is the host\n\t\t\t\t\t\treturn;               // table, not a nested one\n\t\t\t\t\t}\n\t\n\t\t\t\t\tvar colIdx = column.idx;\n\t\n\t\t\t\t\tcell\n\t\t\t\t\t\t.removeClass(\n\t\t\t\t\t\t\tcolumn.sSortingClass +' '+\n\t\t\t\t\t\t\tclasses.sSortAsc +' '+\n\t\t\t\t\t\t\tclasses.sSortDesc\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\t\t\t\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\t\t\t\tclasses.sSortDesc :\n\t\t\t\t\t\t\t\tcolumn.sSortingClass\n\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t\t},\n\t\n\t\t\tjqueryui: function ( settings, cell, column, classes ) {\n\t\t\t\t$('<div/>')\n\t\t\t\t\t.addClass( classes.sSortJUIWrapper )\n\t\t\t\t\t.append( cell.contents() )\n\t\t\t\t\t.append( $('<span/>')\n\t\t\t\t\t\t.addClass( classes.sSortIcon+' '+column.sSortingClassJUI )\n\t\t\t\t\t)\n\t\t\t\t\t.appendTo( cell );\n\t\n\t\t\t\t// Attach a sort listener to update on sort\n\t\t\t\t$(settings.nTable).on( 'order.dt.DT', function ( e, ctx, sorting, columns ) {\n\t\t\t\t\tif ( settings !== ctx ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\n\t\t\t\t\tvar colIdx = column.idx;\n\t\n\t\t\t\t\tcell\n\t\t\t\t\t\t.removeClass( classes.sSortAsc +\" \"+classes.sSortDesc )\n\t\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\t\t\t\tclasses.sSortAsc : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\t\t\t\tclasses.sSortDesc :\n\t\t\t\t\t\t\t\tcolumn.sSortingClass\n\t\t\t\t\t\t);\n\t\n\t\t\t\t\tcell\n\t\t\t\t\t\t.find( 'span.'+classes.sSortIcon )\n\t\t\t\t\t\t.removeClass(\n\t\t\t\t\t\t\tclasses.sSortJUIAsc +\" \"+\n\t\t\t\t\t\t\tclasses.sSortJUIDesc +\" \"+\n\t\t\t\t\t\t\tclasses.sSortJUI +\" \"+\n\t\t\t\t\t\t\tclasses.sSortJUIAscAllowed +\" \"+\n\t\t\t\t\t\t\tclasses.sSortJUIDescAllowed\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.addClass( columns[ colIdx ] == 'asc' ?\n\t\t\t\t\t\t\tclasses.sSortJUIAsc : columns[ colIdx ] == 'desc' ?\n\t\t\t\t\t\t\t\tclasses.sSortJUIDesc :\n\t\t\t\t\t\t\t\tcolumn.sSortingClassJUI\n\t\t\t\t\t\t);\n\t\t\t\t} );\n\t\t\t}\n\t\t}\n\t} );\n\t\n\t/*\n\t * Public helper functions. These aren't used internally by DataTables, or\n\t * called by any of the options passed into DataTables, but they can be used\n\t * externally by developers working with DataTables. They are helper functions\n\t * to make working with DataTables a little bit easier.\n\t */\n\t\n\t/**\n\t * Helpers for `columns.render`.\n\t *\n\t * The options defined here can be used with the `columns.render` initialisation\n\t * option to provide a display renderer. The following functions are defined:\n\t *\n\t * * `number` - Will format numeric data (defined by `columns.data`) for\n\t *   display, retaining the original unformatted data for sorting and filtering.\n\t *   It takes 4 parameters:\n\t *   * `string` - Thousands grouping separator\n\t *   * `string` - Decimal point indicator\n\t *   * `integer` - Number of decimal points to show\n\t *   * `string` (optional) - Prefix.\n\t *\n\t * @example\n\t *   // Column definition using the number renderer\n\t *   {\n\t *     data: \"salary\",\n\t *     render: $.fn.dataTable.render.number( '\\'', '.', 0, '$' )\n\t *   }\n\t *\n\t * @namespace\n\t */\n\tDataTable.render = {\n\t\tnumber: function ( thousands, decimal, precision, prefix ) {\n\t\t\treturn {\n\t\t\t\tdisplay: function ( d ) {\n\t\t\t\t\tif ( typeof d !== 'number' && typeof d !== 'string' ) {\n\t\t\t\t\t\treturn d;\n\t\t\t\t\t}\n\t\n\t\t\t\t\tvar negative = d < 0 ? '-' : '';\n\t\t\t\t\td = Math.abs( parseFloat( d ) );\n\t\n\t\t\t\t\tvar intPart = parseInt( d, 10 );\n\t\t\t\t\tvar floatPart = precision ?\n\t\t\t\t\t\tdecimal+(d - intPart).toFixed( precision ).substring( 2 ):\n\t\t\t\t\t\t'';\n\t\n\t\t\t\t\treturn negative + (prefix||'') +\n\t\t\t\t\t\tintPart.toString().replace(\n\t\t\t\t\t\t\t/\\B(?=(\\d{3})+(?!\\d))/g, thousands\n\t\t\t\t\t\t) +\n\t\t\t\t\t\tfloatPart;\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t};\n\t\n\t\n\t/*\n\t * This is really a good bit rubbish this method of exposing the internal methods\n\t * publicly... - To be fixed in 2.0 using methods on the prototype\n\t */\n\t\n\t\n\t/**\n\t * Create a wrapper function for exporting an internal functions to an external API.\n\t *  @param {string} fn API function name\n\t *  @returns {function} wrapped function\n\t *  @memberof DataTable#internal\n\t */\n\tfunction _fnExternApiFunc (fn)\n\t{\n\t\treturn function() {\n\t\t\tvar args = [_fnSettingsFromNode( this[DataTable.ext.iApiIndex] )].concat(\n\t\t\t\tArray.prototype.slice.call(arguments)\n\t\t\t);\n\t\t\treturn DataTable.ext.internal[fn].apply( this, args );\n\t\t};\n\t}\n\t\n\t\n\t/**\n\t * Reference to internal functions for use by plug-in developers. Note that\n\t * these methods are references to internal functions and are considered to be\n\t * private. If you use these methods, be aware that they are liable to change\n\t * between versions.\n\t *  @namespace\n\t */\n\t$.extend( DataTable.ext.internal, {\n\t\t_fnExternApiFunc: _fnExternApiFunc,\n\t\t_fnBuildAjax: _fnBuildAjax,\n\t\t_fnAjaxUpdate: _fnAjaxUpdate,\n\t\t_fnAjaxParameters: _fnAjaxParameters,\n\t\t_fnAjaxUpdateDraw: _fnAjaxUpdateDraw,\n\t\t_fnAjaxDataSrc: _fnAjaxDataSrc,\n\t\t_fnAddColumn: _fnAddColumn,\n\t\t_fnColumnOptions: _fnColumnOptions,\n\t\t_fnAdjustColumnSizing: _fnAdjustColumnSizing,\n\t\t_fnVisibleToColumnIndex: _fnVisibleToColumnIndex,\n\t\t_fnColumnIndexToVisible: _fnColumnIndexToVisible,\n\t\t_fnVisbleColumns: _fnVisbleColumns,\n\t\t_fnGetColumns: _fnGetColumns,\n\t\t_fnColumnTypes: _fnColumnTypes,\n\t\t_fnApplyColumnDefs: _fnApplyColumnDefs,\n\t\t_fnHungarianMap: _fnHungarianMap,\n\t\t_fnCamelToHungarian: _fnCamelToHungarian,\n\t\t_fnLanguageCompat: _fnLanguageCompat,\n\t\t_fnBrowserDetect: _fnBrowserDetect,\n\t\t_fnAddData: _fnAddData,\n\t\t_fnAddTr: _fnAddTr,\n\t\t_fnNodeToDataIndex: _fnNodeToDataIndex,\n\t\t_fnNodeToColumnIndex: _fnNodeToColumnIndex,\n\t\t_fnGetCellData: _fnGetCellData,\n\t\t_fnSetCellData: _fnSetCellData,\n\t\t_fnSplitObjNotation: _fnSplitObjNotation,\n\t\t_fnGetObjectDataFn: _fnGetObjectDataFn,\n\t\t_fnSetObjectDataFn: _fnSetObjectDataFn,\n\t\t_fnGetDataMaster: _fnGetDataMaster,\n\t\t_fnClearTable: _fnClearTable,\n\t\t_fnDeleteIndex: _fnDeleteIndex,\n\t\t_fnInvalidate: _fnInvalidate,\n\t\t_fnGetRowElements: _fnGetRowElements,\n\t\t_fnCreateTr: _fnCreateTr,\n\t\t_fnBuildHead: _fnBuildHead,\n\t\t_fnDrawHead: _fnDrawHead,\n\t\t_fnDraw: _fnDraw,\n\t\t_fnReDraw: _fnReDraw,\n\t\t_fnAddOptionsHtml: _fnAddOptionsHtml,\n\t\t_fnDetectHeader: _fnDetectHeader,\n\t\t_fnGetUniqueThs: _fnGetUniqueThs,\n\t\t_fnFeatureHtmlFilter: _fnFeatureHtmlFilter,\n\t\t_fnFilterComplete: _fnFilterComplete,\n\t\t_fnFilterCustom: _fnFilterCustom,\n\t\t_fnFilterColumn: _fnFilterColumn,\n\t\t_fnFilter: _fnFilter,\n\t\t_fnFilterCreateSearch: _fnFilterCreateSearch,\n\t\t_fnEscapeRegex: _fnEscapeRegex,\n\t\t_fnFilterData: _fnFilterData,\n\t\t_fnFeatureHtmlInfo: _fnFeatureHtmlInfo,\n\t\t_fnUpdateInfo: _fnUpdateInfo,\n\t\t_fnInfoMacros: _fnInfoMacros,\n\t\t_fnInitialise: _fnInitialise,\n\t\t_fnInitComplete: _fnInitComplete,\n\t\t_fnLengthChange: _fnLengthChange,\n\t\t_fnFeatureHtmlLength: _fnFeatureHtmlLength,\n\t\t_fnFeatureHtmlPaginate: _fnFeatureHtmlPaginate,\n\t\t_fnPageChange: _fnPageChange,\n\t\t_fnFeatureHtmlProcessing: _fnFeatureHtmlProcessing,\n\t\t_fnProcessingDisplay: _fnProcessingDisplay,\n\t\t_fnFeatureHtmlTable: _fnFeatureHtmlTable,\n\t\t_fnScrollDraw: _fnScrollDraw,\n\t\t_fnApplyToChildren: _fnApplyToChildren,\n\t\t_fnCalculateColumnWidths: _fnCalculateColumnWidths,\n\t\t_fnThrottle: _fnThrottle,\n\t\t_fnConvertToWidth: _fnConvertToWidth,\n\t\t_fnScrollingWidthAdjust: _fnScrollingWidthAdjust,\n\t\t_fnGetWidestNode: _fnGetWidestNode,\n\t\t_fnGetMaxLenString: _fnGetMaxLenString,\n\t\t_fnStringToCss: _fnStringToCss,\n\t\t_fnScrollBarWidth: _fnScrollBarWidth,\n\t\t_fnSortFlatten: _fnSortFlatten,\n\t\t_fnSort: _fnSort,\n\t\t_fnSortAria: _fnSortAria,\n\t\t_fnSortListener: _fnSortListener,\n\t\t_fnSortAttachListener: _fnSortAttachListener,\n\t\t_fnSortingClasses: _fnSortingClasses,\n\t\t_fnSortData: _fnSortData,\n\t\t_fnSaveState: _fnSaveState,\n\t\t_fnLoadState: _fnLoadState,\n\t\t_fnSettingsFromNode: _fnSettingsFromNode,\n\t\t_fnLog: _fnLog,\n\t\t_fnMap: _fnMap,\n\t\t_fnBindAction: _fnBindAction,\n\t\t_fnCallbackReg: _fnCallbackReg,\n\t\t_fnCallbackFire: _fnCallbackFire,\n\t\t_fnLengthOverflow: _fnLengthOverflow,\n\t\t_fnRenderer: _fnRenderer,\n\t\t_fnDataSource: _fnDataSource,\n\t\t_fnRowAttributes: _fnRowAttributes,\n\t\t_fnCalculateEnd: function () {} // Used by a lot of plug-ins, but redundant\n\t\t                                // in 1.10, so this dead-end function is\n\t\t                                // added to prevent errors\n\t} );\n\t\n\n\t// jQuery access\n\t$.fn.dataTable = DataTable;\n\n\t// Legacy aliases\n\t$.fn.dataTableSettings = DataTable.settings;\n\t$.fn.dataTableExt = DataTable.ext;\n\n\t// With a capital `D` we return a DataTables API instance rather than a\n\t// jQuery object\n\t$.fn.DataTable = function ( opts ) {\n\t\treturn $(this).dataTable( opts ).api();\n\t};\n\n\t// All properties that are available to $.fn.dataTable should also be\n\t// available on $.fn.DataTable\n\t$.each( DataTable, function ( prop, val ) {\n\t\t$.fn.DataTable[ prop ] = val;\n\t} );\n\n\n\t// Information about events fired by DataTables - for documentation.\n\t/**\n\t * Draw event, fired whenever the table is redrawn on the page, at the same\n\t * point as fnDrawCallback. This may be useful for binding events or\n\t * performing calculations when the table is altered at all.\n\t *  @name DataTable#draw.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Search event, fired when the searching applied to the table (using the\n\t * built-in global search, or column filters) is altered.\n\t *  @name DataTable#search.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Page change event, fired when the paging of the table is altered.\n\t *  @name DataTable#page.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Order event, fired when the ordering applied to the table is altered.\n\t *  @name DataTable#order.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * DataTables initialisation complete event, fired when the table is fully\n\t * drawn, including Ajax data loaded, if Ajax data is required.\n\t *  @name DataTable#init.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {object} json The JSON object request from the server - only\n\t *    present if client-side Ajax sourced data is used</li></ol>\n\t */\n\n\t/**\n\t * State save event, fired when the table has changed state a new state save\n\t * is required. This event allows modification of the state saving object\n\t * prior to actually doing the save, including addition or other state\n\t * properties (for plug-ins) or modification of a DataTables core property.\n\t *  @name DataTable#stateSaveParams.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {object} json The state information to be saved\n\t */\n\n\t/**\n\t * State load event, fired when the table is loading state from the stored\n\t * data, but prior to the settings object being modified by the saved state\n\t * - allowing modification of the saved state is required or loading of\n\t * state for a plug-in.\n\t *  @name DataTable#stateLoadParams.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {object} json The saved state information\n\t */\n\n\t/**\n\t * State loaded event, fired when state has been loaded from stored data and\n\t * the settings object has been modified by the loaded data.\n\t *  @name DataTable#stateLoaded.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {object} json The saved state information\n\t */\n\n\t/**\n\t * Processing event, fired when DataTables is doing some kind of processing\n\t * (be it, order, searcg or anything else). It can be used to indicate to\n\t * the end user that there is something happening, or that something has\n\t * finished.\n\t *  @name DataTable#processing.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} oSettings DataTables settings object\n\t *  @param {boolean} bShow Flag for if DataTables is doing processing or not\n\t */\n\n\t/**\n\t * Ajax (XHR) event, fired whenever an Ajax request is completed from a\n\t * request to made to the server for new data. This event is called before\n\t * DataTables processed the returned data, so it can also be used to pre-\n\t * process the data returned from the server, if needed.\n\t *\n\t * Note that this trigger is called in `fnServerData`, if you override\n\t * `fnServerData` and which to use this event, you need to trigger it in you\n\t * success function.\n\t *  @name DataTable#xhr.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t *  @param {object} json JSON returned from the server\n\t *\n\t *  @example\n\t *     // Use a custom property returned from the server in another DOM element\n\t *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {\n\t *       $('#status').html( json.status );\n\t *     } );\n\t *\n\t *  @example\n\t *     // Pre-process the data returned from the server\n\t *     $('#table').dataTable().on('xhr.dt', function (e, settings, json) {\n\t *       for ( var i=0, ien=json.aaData.length ; i<ien ; i++ ) {\n\t *         json.aaData[i].sum = json.aaData[i].one + json.aaData[i].two;\n\t *       }\n\t *       // Note no return - manipulate the data directly in the JSON object.\n\t *     } );\n\t */\n\n\t/**\n\t * Destroy event, fired when the DataTable is destroyed by calling fnDestroy\n\t * or passing the bDestroy:true parameter in the initialisation object. This\n\t * can be used to remove bound events, added DOM nodes, etc.\n\t *  @name DataTable#destroy.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Page length change event, fired when number of records to show on each\n\t * page (the length) is changed.\n\t *  @name DataTable#length.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t *  @param {integer} len New length\n\t */\n\n\t/**\n\t * Column sizing has changed.\n\t *  @name DataTable#column-sizing.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t */\n\n\t/**\n\t * Column visibility has changed.\n\t *  @name DataTable#column-visibility.dt\n\t *  @event\n\t *  @param {event} e jQuery event object\n\t *  @param {object} o DataTables settings object {@link DataTable.models.oSettings}\n\t *  @param {int} column Column index\n\t *  @param {bool} vis `false` if column now hidden, or `true` if visible\n\t */\n\n\treturn $.fn.dataTable;\n}));\n\n}(window, document));\n\n"
  },
  {
    "path": "public/static/plugins/datatables/jquery.dataTables_themeroller.css",
    "content": "/*\n * Table styles\n */\ntable.dataTable {\n  width: 100%;\n  margin: 0 auto;\n  clear: both;\n  border-collapse: separate;\n  border-spacing: 0;\n  /*\n   * Header and footer styles\n   */\n  /*\n   * Body styles\n   */\n}\ntable.dataTable thead th,\ntable.dataTable thead td,\ntable.dataTable tfoot th,\ntable.dataTable tfoot td {\n  padding: 4px 10px;\n}\ntable.dataTable thead th,\ntable.dataTable tfoot th {\n  font-weight: bold;\n}\ntable.dataTable thead th:active,\ntable.dataTable thead td:active {\n  outline: none;\n}\ntable.dataTable thead .sorting_asc,\ntable.dataTable thead .sorting_desc,\ntable.dataTable thead .sorting {\n  cursor: pointer;\n  *cursor: hand;\n}\ntable.dataTable thead th div.DataTables_sort_wrapper {\n  position: relative;\n  padding-right: 10px;\n}\ntable.dataTable thead th div.DataTables_sort_wrapper span {\n  position: absolute;\n  top: 50%;\n  margin-top: -8px;\n  right: -5px;\n}\ntable.dataTable thead th.ui-state-default {\n  border-right-width: 0;\n}\ntable.dataTable thead th.ui-state-default:last-child {\n  border-right-width: 1px;\n}\ntable.dataTable tbody tr {\n  background-color: #ffffff;\n}\ntable.dataTable tbody tr.selected {\n  background-color: #B0BED9;\n}\ntable.dataTable tbody th,\ntable.dataTable tbody td {\n  padding: 8px 10px;\n}\ntable.dataTable th.center,\ntable.dataTable td.center,\ntable.dataTable td.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable th.right,\ntable.dataTable td.right {\n  text-align: right;\n}\ntable.dataTable.row-border tbody th, table.dataTable.row-border tbody td, table.dataTable.display tbody th, table.dataTable.display tbody td {\n  border-top: 1px solid #ddd;\n}\ntable.dataTable.row-border tbody tr:first-child th,\ntable.dataTable.row-border tbody tr:first-child td, table.dataTable.display tbody tr:first-child th,\ntable.dataTable.display tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.cell-border tbody th, table.dataTable.cell-border tbody td {\n  border-top: 1px solid #ddd;\n  border-right: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr th:first-child,\ntable.dataTable.cell-border tbody tr td:first-child {\n  border-left: 1px solid #ddd;\n}\ntable.dataTable.cell-border tbody tr:first-child th,\ntable.dataTable.cell-border tbody tr:first-child td {\n  border-top: none;\n}\ntable.dataTable.stripe tbody tr.odd, table.dataTable.display tbody tr.odd {\n  background-color: #f9f9f9;\n}\ntable.dataTable.stripe tbody tr.odd.selected, table.dataTable.display tbody tr.odd.selected {\n  background-color: #abb9d3;\n}\ntable.dataTable.hover tbody tr:hover,\ntable.dataTable.hover tbody tr.odd:hover,\ntable.dataTable.hover tbody tr.even:hover, table.dataTable.display tbody tr:hover,\ntable.dataTable.display tbody tr.odd:hover,\ntable.dataTable.display tbody tr.even:hover {\n  background-color: whitesmoke;\n}\ntable.dataTable.hover tbody tr:hover.selected,\ntable.dataTable.hover tbody tr.odd:hover.selected,\ntable.dataTable.hover tbody tr.even:hover.selected, table.dataTable.display tbody tr:hover.selected,\ntable.dataTable.display tbody tr.odd:hover.selected,\ntable.dataTable.display tbody tr.even:hover.selected {\n  background-color: #a9b7d1;\n}\ntable.dataTable.order-column tbody tr > .sorting_1,\ntable.dataTable.order-column tbody tr > .sorting_2,\ntable.dataTable.order-column tbody tr > .sorting_3, table.dataTable.display tbody tr > .sorting_1,\ntable.dataTable.display tbody tr > .sorting_2,\ntable.dataTable.display tbody tr > .sorting_3 {\n  background-color: #f9f9f9;\n}\ntable.dataTable.order-column tbody tr.selected > .sorting_1,\ntable.dataTable.order-column tbody tr.selected > .sorting_2,\ntable.dataTable.order-column tbody tr.selected > .sorting_3, table.dataTable.display tbody tr.selected > .sorting_1,\ntable.dataTable.display tbody tr.selected > .sorting_2,\ntable.dataTable.display tbody tr.selected > .sorting_3 {\n  background-color: #acbad4;\n}\ntable.dataTable.display tbody tr.odd > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd > .sorting_1 {\n  background-color: #f1f1f1;\n}\ntable.dataTable.display tbody tr.odd > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd > .sorting_2 {\n  background-color: #f3f3f3;\n}\ntable.dataTable.display tbody tr.odd > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd > .sorting_3 {\n  background-color: whitesmoke;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_1 {\n  background-color: #a6b3cd;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_2 {\n  background-color: #a7b5ce;\n}\ntable.dataTable.display tbody tr.odd.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.odd.selected > .sorting_3 {\n  background-color: #a9b6d0;\n}\ntable.dataTable.display tbody tr.even > .sorting_1, table.dataTable.order-column.stripe tbody tr.even > .sorting_1 {\n  background-color: #f9f9f9;\n}\ntable.dataTable.display tbody tr.even > .sorting_2, table.dataTable.order-column.stripe tbody tr.even > .sorting_2 {\n  background-color: #fbfbfb;\n}\ntable.dataTable.display tbody tr.even > .sorting_3, table.dataTable.order-column.stripe tbody tr.even > .sorting_3 {\n  background-color: #fdfdfd;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_1, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_1 {\n  background-color: #acbad4;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_2, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_2 {\n  background-color: #adbbd6;\n}\ntable.dataTable.display tbody tr.even.selected > .sorting_3, table.dataTable.order-column.stripe tbody tr.even.selected > .sorting_3 {\n  background-color: #afbdd8;\n}\ntable.dataTable.display tbody tr:hover > .sorting_1,\ntable.dataTable.display tbody tr.odd:hover > .sorting_1,\ntable.dataTable.display tbody tr.even:hover > .sorting_1, table.dataTable.order-column.hover tbody tr:hover > .sorting_1,\ntable.dataTable.order-column.hover tbody tr.odd:hover > .sorting_1,\ntable.dataTable.order-column.hover tbody tr.even:hover > .sorting_1 {\n  background-color: #eaeaea;\n}\ntable.dataTable.display tbody tr:hover > .sorting_2,\ntable.dataTable.display tbody tr.odd:hover > .sorting_2,\ntable.dataTable.display tbody tr.even:hover > .sorting_2, table.dataTable.order-column.hover tbody tr:hover > .sorting_2,\ntable.dataTable.order-column.hover tbody tr.odd:hover > .sorting_2,\ntable.dataTable.order-column.hover tbody tr.even:hover > .sorting_2 {\n  background-color: #ebebeb;\n}\ntable.dataTable.display tbody tr:hover > .sorting_3,\ntable.dataTable.display tbody tr.odd:hover > .sorting_3,\ntable.dataTable.display tbody tr.even:hover > .sorting_3, table.dataTable.order-column.hover tbody tr:hover > .sorting_3,\ntable.dataTable.order-column.hover tbody tr.odd:hover > .sorting_3,\ntable.dataTable.order-column.hover tbody tr.even:hover > .sorting_3 {\n  background-color: #eeeeee;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_1,\ntable.dataTable.display tbody tr.odd:hover.selected > .sorting_1,\ntable.dataTable.display tbody tr.even:hover.selected > .sorting_1, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_1,\ntable.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_1,\ntable.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_1 {\n  background-color: #a1aec7;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_2,\ntable.dataTable.display tbody tr.odd:hover.selected > .sorting_2,\ntable.dataTable.display tbody tr.even:hover.selected > .sorting_2, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_2,\ntable.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_2,\ntable.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_2 {\n  background-color: #a2afc8;\n}\ntable.dataTable.display tbody tr:hover.selected > .sorting_3,\ntable.dataTable.display tbody tr.odd:hover.selected > .sorting_3,\ntable.dataTable.display tbody tr.even:hover.selected > .sorting_3, table.dataTable.order-column.hover tbody tr:hover.selected > .sorting_3,\ntable.dataTable.order-column.hover tbody tr.odd:hover.selected > .sorting_3,\ntable.dataTable.order-column.hover tbody tr.even:hover.selected > .sorting_3 {\n  background-color: #a4b2cb;\n}\ntable.dataTable.nowrap th, table.dataTable.nowrap td {\n  white-space: nowrap;\n}\ntable.dataTable.compact thead th,\ntable.dataTable.compact thead td {\n  padding: 5px 9px;\n}\ntable.dataTable.compact tfoot th,\ntable.dataTable.compact tfoot td {\n  padding: 5px 9px 3px 9px;\n}\ntable.dataTable.compact tbody th,\ntable.dataTable.compact tbody td {\n  padding: 4px 5px;\n}\ntable.dataTable th.dt-left,\ntable.dataTable td.dt-left {\n  text-align: left;\n}\ntable.dataTable th.dt-center,\ntable.dataTable td.dt-center,\ntable.dataTable td.dataTables_empty {\n  text-align: center;\n}\ntable.dataTable th.dt-right,\ntable.dataTable td.dt-right {\n  text-align: right;\n}\ntable.dataTable th.dt-justify,\ntable.dataTable td.dt-justify {\n  text-align: justify;\n}\ntable.dataTable th.dt-nowrap,\ntable.dataTable td.dt-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable thead th.dt-head-left,\ntable.dataTable thead td.dt-head-left,\ntable.dataTable tfoot th.dt-head-left,\ntable.dataTable tfoot td.dt-head-left {\n  text-align: left;\n}\ntable.dataTable thead th.dt-head-center,\ntable.dataTable thead td.dt-head-center,\ntable.dataTable tfoot th.dt-head-center,\ntable.dataTable tfoot td.dt-head-center {\n  text-align: center;\n}\ntable.dataTable thead th.dt-head-right,\ntable.dataTable thead td.dt-head-right,\ntable.dataTable tfoot th.dt-head-right,\ntable.dataTable tfoot td.dt-head-right {\n  text-align: right;\n}\ntable.dataTable thead th.dt-head-justify,\ntable.dataTable thead td.dt-head-justify,\ntable.dataTable tfoot th.dt-head-justify,\ntable.dataTable tfoot td.dt-head-justify {\n  text-align: justify;\n}\ntable.dataTable thead th.dt-head-nowrap,\ntable.dataTable thead td.dt-head-nowrap,\ntable.dataTable tfoot th.dt-head-nowrap,\ntable.dataTable tfoot td.dt-head-nowrap {\n  white-space: nowrap;\n}\ntable.dataTable tbody th.dt-body-left,\ntable.dataTable tbody td.dt-body-left {\n  text-align: left;\n}\ntable.dataTable tbody th.dt-body-center,\ntable.dataTable tbody td.dt-body-center {\n  text-align: center;\n}\ntable.dataTable tbody th.dt-body-right,\ntable.dataTable tbody td.dt-body-right {\n  text-align: right;\n}\ntable.dataTable tbody th.dt-body-justify,\ntable.dataTable tbody td.dt-body-justify {\n  text-align: justify;\n}\ntable.dataTable tbody th.dt-body-nowrap,\ntable.dataTable tbody td.dt-body-nowrap {\n  white-space: nowrap;\n}\n\ntable.dataTable,\ntable.dataTable th,\ntable.dataTable td {\n  -webkit-box-sizing: content-box;\n  -moz-box-sizing: content-box;\n  box-sizing: content-box;\n}\n\n/*\n * Control feature layout\n */\n.dataTables_wrapper {\n  position: relative;\n  clear: both;\n  *zoom: 1;\n  zoom: 1;\n}\n.dataTables_wrapper .dataTables_length {\n  float: left;\n}\n.dataTables_wrapper .dataTables_filter {\n  float: right;\n  text-align: right;\n}\n.dataTables_wrapper .dataTables_filter input {\n  margin-left: 0.5em;\n}\n.dataTables_wrapper .dataTables_info {\n  clear: both;\n  float: left;\n  padding-top: 0.55em;\n}\n.dataTables_wrapper .dataTables_paginate {\n  float: right;\n  text-align: right;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button {\n  box-sizing: border-box;\n  display: inline-block;\n  min-width: 1.5em;\n  padding: 0.5em;\n  margin-left: 2px;\n  text-align: center;\n  text-decoration: none !important;\n  cursor: pointer;\n  *cursor: hand;\n  color: #333 !important;\n  border: 1px solid transparent;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button:active {\n  outline: none;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button:first-child {\n  border-top-left-radius: 3px;\n  border-bottom-left-radius: 3px;\n}\n.dataTables_wrapper .dataTables_paginate .fg-button:last-child {\n  border-top-right-radius: 3px;\n  border-bottom-right-radius: 3px;\n}\n.dataTables_wrapper .dataTables_processing {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  width: 100%;\n  height: 40px;\n  margin-left: -50%;\n  margin-top: -25px;\n  padding-top: 20px;\n  text-align: center;\n  font-size: 1.2em;\n  background-color: white;\n  background: -webkit-gradient(linear, left top, right top, color-stop(0%, rgba(255, 255, 255, 0)), color-stop(25%, rgba(255, 255, 255, 0.9)), color-stop(75%, rgba(255, 255, 255, 0.9)), color-stop(100%, rgba(255, 255, 255, 0)));\n  /* Chrome,Safari4+ */\n  background: -webkit-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* Chrome10+,Safari5.1+ */\n  background: -moz-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* FF3.6+ */\n  background: -ms-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* IE10+ */\n  background: -o-linear-gradient(left, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* Opera 11.10+ */\n  background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 0.9) 25%, rgba(255, 255, 255, 0.9) 75%, rgba(255, 255, 255, 0) 100%);\n  /* W3C */\n}\n.dataTables_wrapper .dataTables_length,\n.dataTables_wrapper .dataTables_filter,\n.dataTables_wrapper .dataTables_info,\n.dataTables_wrapper .dataTables_processing,\n.dataTables_wrapper .dataTables_paginate {\n  color: #333;\n}\n.dataTables_wrapper .dataTables_scroll {\n  clear: both;\n}\n.dataTables_wrapper .dataTables_scrollBody {\n  *margin-top: -1px;\n  -webkit-overflow-scrolling: touch;\n}\n.dataTables_wrapper .ui-widget-header {\n  font-weight: normal;\n}\n.dataTables_wrapper .ui-toolbar {\n  padding: 8px;\n}\n.dataTables_wrapper:after {\n  visibility: hidden;\n  display: block;\n  content: \"\";\n  clear: both;\n  height: 0;\n}\n\n@media screen and (max-width: 767px) {\n  .dataTables_wrapper .dataTables_length,\n  .dataTables_wrapper .dataTables_filter,\n  .dataTables_wrapper .dataTables_info,\n  .dataTables_wrapper .dataTables_paginate {\n    float: none;\n    text-align: center;\n  }\n  .dataTables_wrapper .dataTables_filter,\n  .dataTables_wrapper .dataTables_paginate {\n    margin-top: 0.5em;\n  }\n}\n"
  },
  {
    "path": "public/static/plugins/datepicker/bootstrap-datepicker.js",
    "content": "/* =========================================================\n * bootstrap-datepicker.js\n * Repo: https://github.com/eternicode/bootstrap-datepicker/\n * Demo: http://eternicode.github.io/bootstrap-datepicker/\n * Docs: http://bootstrap-datepicker.readthedocs.org/\n * Forked from http://www.eyecon.ro/bootstrap-datepicker\n * =========================================================\n * Started by Stefan Petre; improvements by Andrew Rowls + contributors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n * ========================================================= */\n\n(function($, undefined){\n\n\tvar $window = $(window);\n\n\tfunction UTCDate(){\n\t\treturn new Date(Date.UTC.apply(Date, arguments));\n\t}\n\tfunction UTCToday(){\n\t\tvar today = new Date();\n\t\treturn UTCDate(today.getFullYear(), today.getMonth(), today.getDate());\n\t}\n\tfunction alias(method){\n\t\treturn function(){\n\t\t\treturn this[method].apply(this, arguments);\n\t\t};\n\t}\n\n\tvar DateArray = (function(){\n\t\tvar extras = {\n\t\t\tget: function(i){\n\t\t\t\treturn this.slice(i)[0];\n\t\t\t},\n\t\t\tcontains: function(d){\n\t\t\t\t// Array.indexOf is not cross-browser;\n\t\t\t\t// $.inArray doesn't work with Dates\n\t\t\t\tvar val = d && d.valueOf();\n\t\t\t\tfor (var i=0, l=this.length; i < l; i++)\n\t\t\t\t\tif (this[i].valueOf() === val)\n\t\t\t\t\t\treturn i;\n\t\t\t\treturn -1;\n\t\t\t},\n\t\t\tremove: function(i){\n\t\t\t\tthis.splice(i,1);\n\t\t\t},\n\t\t\treplace: function(new_array){\n\t\t\t\tif (!new_array)\n\t\t\t\t\treturn;\n\t\t\t\tif (!$.isArray(new_array))\n\t\t\t\t\tnew_array = [new_array];\n\t\t\t\tthis.clear();\n\t\t\t\tthis.push.apply(this, new_array);\n\t\t\t},\n\t\t\tclear: function(){\n\t\t\t\tthis.splice(0);\n\t\t\t},\n\t\t\tcopy: function(){\n\t\t\t\tvar a = new DateArray();\n\t\t\t\ta.replace(this);\n\t\t\t\treturn a;\n\t\t\t}\n\t\t};\n\n\t\treturn function(){\n\t\t\tvar a = [];\n\t\t\ta.push.apply(a, arguments);\n\t\t\t$.extend(a, extras);\n\t\t\treturn a;\n\t\t};\n\t})();\n\n\n\t// Picker object\n\n\tvar Datepicker = function(element, options){\n\t\tthis.dates = new DateArray();\n\t\tthis.viewDate = UTCToday();\n\t\tthis.focusDate = null;\n\n\t\tthis._process_options(options);\n\n\t\tthis.element = $(element);\n\t\tthis.isInline = false;\n\t\tthis.isInput = this.element.is('input');\n\t\tthis.component = this.element.is('.date') ? this.element.find('.add-on, .input-group-addon, .btn') : false;\n\t\tthis.hasInput = this.component && this.element.find('input').length;\n\t\tif (this.component && this.component.length === 0)\n\t\t\tthis.component = false;\n\n\t\tthis.picker = $(DPGlobal.template);\n\t\tthis._buildEvents();\n\t\tthis._attachEvents();\n\n\t\tif (this.isInline){\n\t\t\tthis.picker.addClass('datepicker-inline').appendTo(this.element);\n\t\t}\n\t\telse {\n\t\t\tthis.picker.addClass('datepicker-dropdown dropdown-menu');\n\t\t}\n\n\t\tif (this.o.rtl){\n\t\t\tthis.picker.addClass('datepicker-rtl');\n\t\t}\n\n\t\tthis.viewMode = this.o.startView;\n\n\t\tif (this.o.calendarWeeks)\n\t\t\tthis.picker.find('tfoot th.today')\n\t\t\t\t\t\t.attr('colspan', function(i, val){\n\t\t\t\t\t\t\treturn parseInt(val) + 1;\n\t\t\t\t\t\t});\n\n\t\tthis._allow_update = false;\n\n\t\tthis.setStartDate(this._o.startDate);\n\t\tthis.setEndDate(this._o.endDate);\n\t\tthis.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled);\n\n\t\tthis.fillDow();\n\t\tthis.fillMonths();\n\n\t\tthis._allow_update = true;\n\n\t\tthis.update();\n\t\tthis.showMode();\n\n\t\tif (this.isInline){\n\t\t\tthis.show();\n\t\t}\n\t};\n\n\tDatepicker.prototype = {\n\t\tconstructor: Datepicker,\n\n\t\t_process_options: function(opts){\n\t\t\t// Store raw options for reference\n\t\t\tthis._o = $.extend({}, this._o, opts);\n\t\t\t// Processed options\n\t\t\tvar o = this.o = $.extend({}, this._o);\n\n\t\t\t// Check if \"de-DE\" style date is available, if not language should\n\t\t\t// fallback to 2 letter code eg \"de\"\n\t\t\tvar lang = o.language;\n\t\t\tif (!dates[lang]){\n\t\t\t\tlang = lang.split('-')[0];\n\t\t\t\tif (!dates[lang])\n\t\t\t\t\tlang = defaults.language;\n\t\t\t}\n\t\t\to.language = lang;\n\n\t\t\tswitch (o.startView){\n\t\t\t\tcase 2:\n\t\t\t\tcase 'decade':\n\t\t\t\t\to.startView = 2;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\tcase 'year':\n\t\t\t\t\to.startView = 1;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\to.startView = 0;\n\t\t\t}\n\n\t\t\tswitch (o.minViewMode){\n\t\t\t\tcase 1:\n\t\t\t\tcase 'months':\n\t\t\t\t\to.minViewMode = 1;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2:\n\t\t\t\tcase 'years':\n\t\t\t\t\to.minViewMode = 2;\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\to.minViewMode = 0;\n\t\t\t}\n\n\t\t\to.startView = Math.max(o.startView, o.minViewMode);\n\n\t\t\t// true, false, or Number > 0\n\t\t\tif (o.multidate !== true){\n\t\t\t\to.multidate = Number(o.multidate) || false;\n\t\t\t\tif (o.multidate !== false)\n\t\t\t\t\to.multidate = Math.max(0, o.multidate);\n\t\t\t\telse\n\t\t\t\t\to.multidate = 1;\n\t\t\t}\n\t\t\to.multidateSeparator = String(o.multidateSeparator);\n\n\t\t\to.weekStart %= 7;\n\t\t\to.weekEnd = ((o.weekStart + 6) % 7);\n\n\t\t\tvar format = DPGlobal.parseFormat(o.format);\n\t\t\tif (o.startDate !== -Infinity){\n\t\t\t\tif (!!o.startDate){\n\t\t\t\t\tif (o.startDate instanceof Date)\n\t\t\t\t\t\to.startDate = this._local_to_utc(this._zero_time(o.startDate));\n\t\t\t\t\telse\n\t\t\t\t\t\to.startDate = DPGlobal.parseDate(o.startDate, format, o.language);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\to.startDate = -Infinity;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (o.endDate !== Infinity){\n\t\t\t\tif (!!o.endDate){\n\t\t\t\t\tif (o.endDate instanceof Date)\n\t\t\t\t\t\to.endDate = this._local_to_utc(this._zero_time(o.endDate));\n\t\t\t\t\telse\n\t\t\t\t\t\to.endDate = DPGlobal.parseDate(o.endDate, format, o.language);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\to.endDate = Infinity;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\to.daysOfWeekDisabled = o.daysOfWeekDisabled||[];\n\t\t\tif (!$.isArray(o.daysOfWeekDisabled))\n\t\t\t\to.daysOfWeekDisabled = o.daysOfWeekDisabled.split(/[,\\s]*/);\n\t\t\to.daysOfWeekDisabled = $.map(o.daysOfWeekDisabled, function(d){\n\t\t\t\treturn parseInt(d, 10);\n\t\t\t});\n\n\t\t\tvar plc = String(o.orientation).toLowerCase().split(/\\s+/g),\n\t\t\t\t_plc = o.orientation.toLowerCase();\n\t\t\tplc = $.grep(plc, function(word){\n\t\t\t\treturn (/^auto|left|right|top|bottom$/).test(word);\n\t\t\t});\n\t\t\to.orientation = {x: 'auto', y: 'auto'};\n\t\t\tif (!_plc || _plc === 'auto')\n\t\t\t\t; // no action\n\t\t\telse if (plc.length === 1){\n\t\t\t\tswitch (plc[0]){\n\t\t\t\t\tcase 'top':\n\t\t\t\t\tcase 'bottom':\n\t\t\t\t\t\to.orientation.y = plc[0];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'left':\n\t\t\t\t\tcase 'right':\n\t\t\t\t\t\to.orientation.x = plc[0];\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\t_plc = $.grep(plc, function(word){\n\t\t\t\t\treturn (/^left|right$/).test(word);\n\t\t\t\t});\n\t\t\t\to.orientation.x = _plc[0] || 'auto';\n\n\t\t\t\t_plc = $.grep(plc, function(word){\n\t\t\t\t\treturn (/^top|bottom$/).test(word);\n\t\t\t\t});\n\t\t\t\to.orientation.y = _plc[0] || 'auto';\n\t\t\t}\n\t\t},\n\t\t_events: [],\n\t\t_secondaryEvents: [],\n\t\t_applyEvents: function(evs){\n\t\t\tfor (var i=0, el, ch, ev; i < evs.length; i++){\n\t\t\t\tel = evs[i][0];\n\t\t\t\tif (evs[i].length === 2){\n\t\t\t\t\tch = undefined;\n\t\t\t\t\tev = evs[i][1];\n\t\t\t\t}\n\t\t\t\telse if (evs[i].length === 3){\n\t\t\t\t\tch = evs[i][1];\n\t\t\t\t\tev = evs[i][2];\n\t\t\t\t}\n\t\t\t\tel.on(ev, ch);\n\t\t\t}\n\t\t},\n\t\t_unapplyEvents: function(evs){\n\t\t\tfor (var i=0, el, ev, ch; i < evs.length; i++){\n\t\t\t\tel = evs[i][0];\n\t\t\t\tif (evs[i].length === 2){\n\t\t\t\t\tch = undefined;\n\t\t\t\t\tev = evs[i][1];\n\t\t\t\t}\n\t\t\t\telse if (evs[i].length === 3){\n\t\t\t\t\tch = evs[i][1];\n\t\t\t\t\tev = evs[i][2];\n\t\t\t\t}\n\t\t\t\tel.off(ev, ch);\n\t\t\t}\n\t\t},\n\t\t_buildEvents: function(){\n\t\t\tif (this.isInput){ // single input\n\t\t\t\tthis._events = [\n\t\t\t\t\t[this.element, {\n\t\t\t\t\t\tfocus: $.proxy(this.show, this),\n\t\t\t\t\t\tkeyup: $.proxy(function(e){\n\t\t\t\t\t\t\tif ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1)\n\t\t\t\t\t\t\t\tthis.update();\n\t\t\t\t\t\t}, this),\n\t\t\t\t\t\tkeydown: $.proxy(this.keydown, this)\n\t\t\t\t\t}]\n\t\t\t\t];\n\t\t\t}\n\t\t\telse if (this.component && this.hasInput){ // component: input + button\n\t\t\t\tthis._events = [\n\t\t\t\t\t// For components that are not readonly, allow keyboard nav\n\t\t\t\t\t[this.element.find('input'), {\n\t\t\t\t\t\tfocus: $.proxy(this.show, this),\n\t\t\t\t\t\tkeyup: $.proxy(function(e){\n\t\t\t\t\t\t\tif ($.inArray(e.keyCode, [27,37,39,38,40,32,13,9]) === -1)\n\t\t\t\t\t\t\t\tthis.update();\n\t\t\t\t\t\t}, this),\n\t\t\t\t\t\tkeydown: $.proxy(this.keydown, this)\n\t\t\t\t\t}],\n\t\t\t\t\t[this.component, {\n\t\t\t\t\t\tclick: $.proxy(this.show, this)\n\t\t\t\t\t}]\n\t\t\t\t];\n\t\t\t}\n\t\t\telse if (this.element.is('div')){  // inline datepicker\n\t\t\t\tthis.isInline = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis._events = [\n\t\t\t\t\t[this.element, {\n\t\t\t\t\t\tclick: $.proxy(this.show, this)\n\t\t\t\t\t}]\n\t\t\t\t];\n\t\t\t}\n\t\t\tthis._events.push(\n\t\t\t\t// Component: listen for blur on element descendants\n\t\t\t\t[this.element, '*', {\n\t\t\t\t\tblur: $.proxy(function(e){\n\t\t\t\t\t\tthis._focused_from = e.target;\n\t\t\t\t\t}, this)\n\t\t\t\t}],\n\t\t\t\t// Input: listen for blur on element\n\t\t\t\t[this.element, {\n\t\t\t\t\tblur: $.proxy(function(e){\n\t\t\t\t\t\tthis._focused_from = e.target;\n\t\t\t\t\t}, this)\n\t\t\t\t}]\n\t\t\t);\n\n\t\t\tthis._secondaryEvents = [\n\t\t\t\t[this.picker, {\n\t\t\t\t\tclick: $.proxy(this.click, this)\n\t\t\t\t}],\n\t\t\t\t[$(window), {\n\t\t\t\t\tresize: $.proxy(this.place, this)\n\t\t\t\t}],\n\t\t\t\t[$(document), {\n\t\t\t\t\t'mousedown touchstart': $.proxy(function(e){\n\t\t\t\t\t\t// Clicked outside the datepicker, hide it\n\t\t\t\t\t\tif (!(\n\t\t\t\t\t\t\tthis.element.is(e.target) ||\n\t\t\t\t\t\t\tthis.element.find(e.target).length ||\n\t\t\t\t\t\t\tthis.picker.is(e.target) ||\n\t\t\t\t\t\t\tthis.picker.find(e.target).length\n\t\t\t\t\t\t)){\n\t\t\t\t\t\t\tthis.hide();\n\t\t\t\t\t\t}\n\t\t\t\t\t}, this)\n\t\t\t\t}]\n\t\t\t];\n\t\t},\n\t\t_attachEvents: function(){\n\t\t\tthis._detachEvents();\n\t\t\tthis._applyEvents(this._events);\n\t\t},\n\t\t_detachEvents: function(){\n\t\t\tthis._unapplyEvents(this._events);\n\t\t},\n\t\t_attachSecondaryEvents: function(){\n\t\t\tthis._detachSecondaryEvents();\n\t\t\tthis._applyEvents(this._secondaryEvents);\n\t\t},\n\t\t_detachSecondaryEvents: function(){\n\t\t\tthis._unapplyEvents(this._secondaryEvents);\n\t\t},\n\t\t_trigger: function(event, altdate){\n\t\t\tvar date = altdate || this.dates.get(-1),\n\t\t\t\tlocal_date = this._utc_to_local(date);\n\n\t\t\tthis.element.trigger({\n\t\t\t\ttype: event,\n\t\t\t\tdate: local_date,\n\t\t\t\tdates: $.map(this.dates, this._utc_to_local),\n\t\t\t\tformat: $.proxy(function(ix, format){\n\t\t\t\t\tif (arguments.length === 0){\n\t\t\t\t\t\tix = this.dates.length - 1;\n\t\t\t\t\t\tformat = this.o.format;\n\t\t\t\t\t}\n\t\t\t\t\telse if (typeof ix === 'string'){\n\t\t\t\t\t\tformat = ix;\n\t\t\t\t\t\tix = this.dates.length - 1;\n\t\t\t\t\t}\n\t\t\t\t\tformat = format || this.o.format;\n\t\t\t\t\tvar date = this.dates.get(ix);\n\t\t\t\t\treturn DPGlobal.formatDate(date, format, this.o.language);\n\t\t\t\t}, this)\n\t\t\t});\n\t\t},\n\n\t\tshow: function(){\n\t\t\tif (!this.isInline)\n\t\t\t\tthis.picker.appendTo('body');\n\t\t\tthis.picker.show();\n\t\t\tthis.place();\n\t\t\tthis._attachSecondaryEvents();\n\t\t\tthis._trigger('show');\n\t\t},\n\n\t\thide: function(){\n\t\t\tif (this.isInline)\n\t\t\t\treturn;\n\t\t\tif (!this.picker.is(':visible'))\n\t\t\t\treturn;\n\t\t\tthis.focusDate = null;\n\t\t\tthis.picker.hide().detach();\n\t\t\tthis._detachSecondaryEvents();\n\t\t\tthis.viewMode = this.o.startView;\n\t\t\tthis.showMode();\n\n\t\t\tif (\n\t\t\t\tthis.o.forceParse &&\n\t\t\t\t(\n\t\t\t\t\tthis.isInput && this.element.val() ||\n\t\t\t\t\tthis.hasInput && this.element.find('input').val()\n\t\t\t\t)\n\t\t\t)\n\t\t\t\tthis.setValue();\n\t\t\tthis._trigger('hide');\n\t\t},\n\n\t\tremove: function(){\n\t\t\tthis.hide();\n\t\t\tthis._detachEvents();\n\t\t\tthis._detachSecondaryEvents();\n\t\t\tthis.picker.remove();\n\t\t\tdelete this.element.data().datepicker;\n\t\t\tif (!this.isInput){\n\t\t\t\tdelete this.element.data().date;\n\t\t\t}\n\t\t},\n\n\t\t_utc_to_local: function(utc){\n\t\t\treturn utc && new Date(utc.getTime() + (utc.getTimezoneOffset()*60000));\n\t\t},\n\t\t_local_to_utc: function(local){\n\t\t\treturn local && new Date(local.getTime() - (local.getTimezoneOffset()*60000));\n\t\t},\n\t\t_zero_time: function(local){\n\t\t\treturn local && new Date(local.getFullYear(), local.getMonth(), local.getDate());\n\t\t},\n\t\t_zero_utc_time: function(utc){\n\t\t\treturn utc && new Date(Date.UTC(utc.getUTCFullYear(), utc.getUTCMonth(), utc.getUTCDate()));\n\t\t},\n\n\t\tgetDates: function(){\n\t\t\treturn $.map(this.dates, this._utc_to_local);\n\t\t},\n\n\t\tgetUTCDates: function(){\n\t\t\treturn $.map(this.dates, function(d){\n\t\t\t\treturn new Date(d);\n\t\t\t});\n\t\t},\n\n\t\tgetDate: function(){\n\t\t\treturn this._utc_to_local(this.getUTCDate());\n\t\t},\n\n\t\tgetUTCDate: function(){\n\t\t\treturn new Date(this.dates.get(-1));\n\t\t},\n\n\t\tsetDates: function(){\n\t\t\tvar args = $.isArray(arguments[0]) ? arguments[0] : arguments;\n\t\t\tthis.update.apply(this, args);\n\t\t\tthis._trigger('changeDate');\n\t\t\tthis.setValue();\n\t\t},\n\n\t\tsetUTCDates: function(){\n\t\t\tvar args = $.isArray(arguments[0]) ? arguments[0] : arguments;\n\t\t\tthis.update.apply(this, $.map(args, this._utc_to_local));\n\t\t\tthis._trigger('changeDate');\n\t\t\tthis.setValue();\n\t\t},\n\n\t\tsetDate: alias('setDates'),\n\t\tsetUTCDate: alias('setUTCDates'),\n\n\t\tsetValue: function(){\n\t\t\tvar formatted = this.getFormattedDate();\n\t\t\tif (!this.isInput){\n\t\t\t\tif (this.component){\n\t\t\t\t\tthis.element.find('input').val(formatted).change();\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.element.val(formatted).change();\n\t\t\t}\n\t\t},\n\n\t\tgetFormattedDate: function(format){\n\t\t\tif (format === undefined)\n\t\t\t\tformat = this.o.format;\n\n\t\t\tvar lang = this.o.language;\n\t\t\treturn $.map(this.dates, function(d){\n\t\t\t\treturn DPGlobal.formatDate(d, format, lang);\n\t\t\t}).join(this.o.multidateSeparator);\n\t\t},\n\n\t\tsetStartDate: function(startDate){\n\t\t\tthis._process_options({startDate: startDate});\n\t\t\tthis.update();\n\t\t\tthis.updateNavArrows();\n\t\t},\n\n\t\tsetEndDate: function(endDate){\n\t\t\tthis._process_options({endDate: endDate});\n\t\t\tthis.update();\n\t\t\tthis.updateNavArrows();\n\t\t},\n\n\t\tsetDaysOfWeekDisabled: function(daysOfWeekDisabled){\n\t\t\tthis._process_options({daysOfWeekDisabled: daysOfWeekDisabled});\n\t\t\tthis.update();\n\t\t\tthis.updateNavArrows();\n\t\t},\n\n\t\tplace: function(){\n\t\t\tif (this.isInline)\n\t\t\t\treturn;\n\t\t\tvar calendarWidth = this.picker.outerWidth(),\n\t\t\t\tcalendarHeight = this.picker.outerHeight(),\n\t\t\t\tvisualPadding = 10,\n\t\t\t\twindowWidth = $window.width(),\n\t\t\t\twindowHeight = $window.height(),\n\t\t\t\tscrollTop = $window.scrollTop();\n\n\t\t\tvar zIndex = parseInt(this.element.parents().filter(function(){\n\t\t\t\t\treturn $(this).css('z-index') !== 'auto';\n\t\t\t\t}).first().css('z-index'))+10;\n\t\t\tvar offset = this.component ? this.component.parent().offset() : this.element.offset();\n\t\t\tvar height = this.component ? this.component.outerHeight(true) : this.element.outerHeight(false);\n\t\t\tvar width = this.component ? this.component.outerWidth(true) : this.element.outerWidth(false);\n\t\t\tvar left = offset.left,\n\t\t\t\ttop = offset.top;\n\n\t\t\tthis.picker.removeClass(\n\t\t\t\t'datepicker-orient-top datepicker-orient-bottom '+\n\t\t\t\t'datepicker-orient-right datepicker-orient-left'\n\t\t\t);\n\n\t\t\tif (this.o.orientation.x !== 'auto'){\n\t\t\t\tthis.picker.addClass('datepicker-orient-' + this.o.orientation.x);\n\t\t\t\tif (this.o.orientation.x === 'right')\n\t\t\t\t\tleft -= calendarWidth - width;\n\t\t\t}\n\t\t\t// auto x orientation is best-placement: if it crosses a window\n\t\t\t// edge, fudge it sideways\n\t\t\telse {\n\t\t\t\t// Default to left\n\t\t\t\tthis.picker.addClass('datepicker-orient-left');\n\t\t\t\tif (offset.left < 0)\n\t\t\t\t\tleft -= offset.left - visualPadding;\n\t\t\t\telse if (offset.left + calendarWidth > windowWidth)\n\t\t\t\t\tleft = windowWidth - calendarWidth - visualPadding;\n\t\t\t}\n\n\t\t\t// auto y orientation is best-situation: top or bottom, no fudging,\n\t\t\t// decision based on which shows more of the calendar\n\t\t\tvar yorient = this.o.orientation.y,\n\t\t\t\ttop_overflow, bottom_overflow;\n\t\t\tif (yorient === 'auto'){\n\t\t\t\ttop_overflow = -scrollTop + offset.top - calendarHeight;\n\t\t\t\tbottom_overflow = scrollTop + windowHeight - (offset.top + height + calendarHeight);\n\t\t\t\tif (Math.max(top_overflow, bottom_overflow) === bottom_overflow)\n\t\t\t\t\tyorient = 'top';\n\t\t\t\telse\n\t\t\t\t\tyorient = 'bottom';\n\t\t\t}\n\t\t\tthis.picker.addClass('datepicker-orient-' + yorient);\n\t\t\tif (yorient === 'top')\n\t\t\t\ttop += height;\n\t\t\telse\n\t\t\t\ttop -= calendarHeight + parseInt(this.picker.css('padding-top'));\n\n\t\t\tthis.picker.css({\n\t\t\t\ttop: top,\n\t\t\t\tleft: left,\n\t\t\t\tzIndex: zIndex\n\t\t\t});\n\t\t},\n\n\t\t_allow_update: true,\n\t\tupdate: function(){\n\t\t\tif (!this._allow_update)\n\t\t\t\treturn;\n\n\t\t\tvar oldDates = this.dates.copy(),\n\t\t\t\tdates = [],\n\t\t\t\tfromArgs = false;\n\t\t\tif (arguments.length){\n\t\t\t\t$.each(arguments, $.proxy(function(i, date){\n\t\t\t\t\tif (date instanceof Date)\n\t\t\t\t\t\tdate = this._local_to_utc(date);\n\t\t\t\t\tdates.push(date);\n\t\t\t\t}, this));\n\t\t\t\tfromArgs = true;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tdates = this.isInput\n\t\t\t\t\t\t? this.element.val()\n\t\t\t\t\t\t: this.element.data('date') || this.element.find('input').val();\n\t\t\t\tif (dates && this.o.multidate)\n\t\t\t\t\tdates = dates.split(this.o.multidateSeparator);\n\t\t\t\telse\n\t\t\t\t\tdates = [dates];\n\t\t\t\tdelete this.element.data().date;\n\t\t\t}\n\n\t\t\tdates = $.map(dates, $.proxy(function(date){\n\t\t\t\treturn DPGlobal.parseDate(date, this.o.format, this.o.language);\n\t\t\t}, this));\n\t\t\tdates = $.grep(dates, $.proxy(function(date){\n\t\t\t\treturn (\n\t\t\t\t\tdate < this.o.startDate ||\n\t\t\t\t\tdate > this.o.endDate ||\n\t\t\t\t\t!date\n\t\t\t\t);\n\t\t\t}, this), true);\n\t\t\tthis.dates.replace(dates);\n\n\t\t\tif (this.dates.length)\n\t\t\t\tthis.viewDate = new Date(this.dates.get(-1));\n\t\t\telse if (this.viewDate < this.o.startDate)\n\t\t\t\tthis.viewDate = new Date(this.o.startDate);\n\t\t\telse if (this.viewDate > this.o.endDate)\n\t\t\t\tthis.viewDate = new Date(this.o.endDate);\n\n\t\t\tif (fromArgs){\n\t\t\t\t// setting date by clicking\n\t\t\t\tthis.setValue();\n\t\t\t}\n\t\t\telse if (dates.length){\n\t\t\t\t// setting date by typing\n\t\t\t\tif (String(oldDates) !== String(this.dates))\n\t\t\t\t\tthis._trigger('changeDate');\n\t\t\t}\n\t\t\tif (!this.dates.length && oldDates.length)\n\t\t\t\tthis._trigger('clearDate');\n\n\t\t\tthis.fill();\n\t\t},\n\n\t\tfillDow: function(){\n\t\t\tvar dowCnt = this.o.weekStart,\n\t\t\t\thtml = '<tr>';\n\t\t\tif (this.o.calendarWeeks){\n\t\t\t\tvar cell = '<th class=\"cw\">&nbsp;</th>';\n\t\t\t\thtml += cell;\n\t\t\t\tthis.picker.find('.datepicker-days thead tr:first-child').prepend(cell);\n\t\t\t}\n\t\t\twhile (dowCnt < this.o.weekStart + 7){\n\t\t\t\thtml += '<th class=\"dow\">'+dates[this.o.language].daysMin[(dowCnt++)%7]+'</th>';\n\t\t\t}\n\t\t\thtml += '</tr>';\n\t\t\tthis.picker.find('.datepicker-days thead').append(html);\n\t\t},\n\n\t\tfillMonths: function(){\n\t\t\tvar html = '',\n\t\t\ti = 0;\n\t\t\twhile (i < 12){\n\t\t\t\thtml += '<span class=\"month\">'+dates[this.o.language].monthsShort[i++]+'</span>';\n\t\t\t}\n\t\t\tthis.picker.find('.datepicker-months td').html(html);\n\t\t},\n\n\t\tsetRange: function(range){\n\t\t\tif (!range || !range.length)\n\t\t\t\tdelete this.range;\n\t\t\telse\n\t\t\t\tthis.range = $.map(range, function(d){\n\t\t\t\t\treturn d.valueOf();\n\t\t\t\t});\n\t\t\tthis.fill();\n\t\t},\n\n\t\tgetClassNames: function(date){\n\t\t\tvar cls = [],\n\t\t\t\tyear = this.viewDate.getUTCFullYear(),\n\t\t\t\tmonth = this.viewDate.getUTCMonth(),\n\t\t\t\ttoday = new Date();\n\t\t\tif (date.getUTCFullYear() < year || (date.getUTCFullYear() === year && date.getUTCMonth() < month)){\n\t\t\t\tcls.push('old');\n\t\t\t}\n\t\t\telse if (date.getUTCFullYear() > year || (date.getUTCFullYear() === year && date.getUTCMonth() > month)){\n\t\t\t\tcls.push('new');\n\t\t\t}\n\t\t\tif (this.focusDate && date.valueOf() === this.focusDate.valueOf())\n\t\t\t\tcls.push('focused');\n\t\t\t// Compare internal UTC date with local today, not UTC today\n\t\t\tif (this.o.todayHighlight &&\n\t\t\t\tdate.getUTCFullYear() === today.getFullYear() &&\n\t\t\t\tdate.getUTCMonth() === today.getMonth() &&\n\t\t\t\tdate.getUTCDate() === today.getDate()){\n\t\t\t\tcls.push('today');\n\t\t\t}\n\t\t\tif (this.dates.contains(date) !== -1)\n\t\t\t\tcls.push('active');\n\t\t\tif (date.valueOf() < this.o.startDate || date.valueOf() > this.o.endDate ||\n\t\t\t\t$.inArray(date.getUTCDay(), this.o.daysOfWeekDisabled) !== -1){\n\t\t\t\tcls.push('disabled');\n\t\t\t}\n\t\t\tif (this.range){\n\t\t\t\tif (date > this.range[0] && date < this.range[this.range.length-1]){\n\t\t\t\t\tcls.push('range');\n\t\t\t\t}\n\t\t\t\tif ($.inArray(date.valueOf(), this.range) !== -1){\n\t\t\t\t\tcls.push('selected');\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn cls;\n\t\t},\n\n\t\tfill: function(){\n\t\t\tvar d = new Date(this.viewDate),\n\t\t\t\tyear = d.getUTCFullYear(),\n\t\t\t\tmonth = d.getUTCMonth(),\n\t\t\t\tstartYear = this.o.startDate !== -Infinity ? this.o.startDate.getUTCFullYear() : -Infinity,\n\t\t\t\tstartMonth = this.o.startDate !== -Infinity ? this.o.startDate.getUTCMonth() : -Infinity,\n\t\t\t\tendYear = this.o.endDate !== Infinity ? this.o.endDate.getUTCFullYear() : Infinity,\n\t\t\t\tendMonth = this.o.endDate !== Infinity ? this.o.endDate.getUTCMonth() : Infinity,\n\t\t\t\ttodaytxt = dates[this.o.language].today || dates['en'].today || '',\n\t\t\t\tcleartxt = dates[this.o.language].clear || dates['en'].clear || '',\n\t\t\t\ttooltip;\n\t\t\tthis.picker.find('.datepicker-days thead th.datepicker-switch')\n\t\t\t\t\t\t.text(dates[this.o.language].months[month]+' '+year);\n\t\t\tthis.picker.find('tfoot th.today')\n\t\t\t\t\t\t.text(todaytxt)\n\t\t\t\t\t\t.toggle(this.o.todayBtn !== false);\n\t\t\tthis.picker.find('tfoot th.clear')\n\t\t\t\t\t\t.text(cleartxt)\n\t\t\t\t\t\t.toggle(this.o.clearBtn !== false);\n\t\t\tthis.updateNavArrows();\n\t\t\tthis.fillMonths();\n\t\t\tvar prevMonth = UTCDate(year, month-1, 28),\n\t\t\t\tday = DPGlobal.getDaysInMonth(prevMonth.getUTCFullYear(), prevMonth.getUTCMonth());\n\t\t\tprevMonth.setUTCDate(day);\n\t\t\tprevMonth.setUTCDate(day - (prevMonth.getUTCDay() - this.o.weekStart + 7)%7);\n\t\t\tvar nextMonth = new Date(prevMonth);\n\t\t\tnextMonth.setUTCDate(nextMonth.getUTCDate() + 42);\n\t\t\tnextMonth = nextMonth.valueOf();\n\t\t\tvar html = [];\n\t\t\tvar clsName;\n\t\t\twhile (prevMonth.valueOf() < nextMonth){\n\t\t\t\tif (prevMonth.getUTCDay() === this.o.weekStart){\n\t\t\t\t\thtml.push('<tr>');\n\t\t\t\t\tif (this.o.calendarWeeks){\n\t\t\t\t\t\t// ISO 8601: First week contains first thursday.\n\t\t\t\t\t\t// ISO also states week starts on Monday, but we can be more abstract here.\n\t\t\t\t\t\tvar\n\t\t\t\t\t\t\t// Start of current week: based on weekstart/current date\n\t\t\t\t\t\t\tws = new Date(+prevMonth + (this.o.weekStart - prevMonth.getUTCDay() - 7) % 7 * 864e5),\n\t\t\t\t\t\t\t// Thursday of this week\n\t\t\t\t\t\t\tth = new Date(Number(ws) + (7 + 4 - ws.getUTCDay()) % 7 * 864e5),\n\t\t\t\t\t\t\t// First Thursday of year, year from thursday\n\t\t\t\t\t\t\tyth = new Date(Number(yth = UTCDate(th.getUTCFullYear(), 0, 1)) + (7 + 4 - yth.getUTCDay())%7*864e5),\n\t\t\t\t\t\t\t// Calendar week: ms between thursdays, div ms per day, div 7 days\n\t\t\t\t\t\t\tcalWeek =  (th - yth) / 864e5 / 7 + 1;\n\t\t\t\t\t\thtml.push('<td class=\"cw\">'+ calWeek +'</td>');\n\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tclsName = this.getClassNames(prevMonth);\n\t\t\t\tclsName.push('day');\n\n\t\t\t\tif (this.o.beforeShowDay !== $.noop){\n\t\t\t\t\tvar before = this.o.beforeShowDay(this._utc_to_local(prevMonth));\n\t\t\t\t\tif (before === undefined)\n\t\t\t\t\t\tbefore = {};\n\t\t\t\t\telse if (typeof(before) === 'boolean')\n\t\t\t\t\t\tbefore = {enabled: before};\n\t\t\t\t\telse if (typeof(before) === 'string')\n\t\t\t\t\t\tbefore = {classes: before};\n\t\t\t\t\tif (before.enabled === false)\n\t\t\t\t\t\tclsName.push('disabled');\n\t\t\t\t\tif (before.classes)\n\t\t\t\t\t\tclsName = clsName.concat(before.classes.split(/\\s+/));\n\t\t\t\t\tif (before.tooltip)\n\t\t\t\t\t\ttooltip = before.tooltip;\n\t\t\t\t}\n\n\t\t\t\tclsName = $.unique(clsName);\n\t\t\t\thtml.push('<td class=\"'+clsName.join(' ')+'\"' + (tooltip ? ' title=\"'+tooltip+'\"' : '') + '>'+prevMonth.getUTCDate() + '</td>');\n\t\t\t\tif (prevMonth.getUTCDay() === this.o.weekEnd){\n\t\t\t\t\thtml.push('</tr>');\n\t\t\t\t}\n\t\t\t\tprevMonth.setUTCDate(prevMonth.getUTCDate()+1);\n\t\t\t}\n\t\t\tthis.picker.find('.datepicker-days tbody').empty().append(html.join(''));\n\n\t\t\tvar months = this.picker.find('.datepicker-months')\n\t\t\t\t\t\t.find('th:eq(1)')\n\t\t\t\t\t\t\t.text(year)\n\t\t\t\t\t\t\t.end()\n\t\t\t\t\t\t.find('span').removeClass('active');\n\n\t\t\t$.each(this.dates, function(i, d){\n\t\t\t\tif (d.getUTCFullYear() === year)\n\t\t\t\t\tmonths.eq(d.getUTCMonth()).addClass('active');\n\t\t\t});\n\n\t\t\tif (year < startYear || year > endYear){\n\t\t\t\tmonths.addClass('disabled');\n\t\t\t}\n\t\t\tif (year === startYear){\n\t\t\t\tmonths.slice(0, startMonth).addClass('disabled');\n\t\t\t}\n\t\t\tif (year === endYear){\n\t\t\t\tmonths.slice(endMonth+1).addClass('disabled');\n\t\t\t}\n\n\t\t\thtml = '';\n\t\t\tyear = parseInt(year/10, 10) * 10;\n\t\t\tvar yearCont = this.picker.find('.datepicker-years')\n\t\t\t\t\t\t\t\t.find('th:eq(1)')\n\t\t\t\t\t\t\t\t\t.text(year + '-' + (year + 9))\n\t\t\t\t\t\t\t\t\t.end()\n\t\t\t\t\t\t\t\t.find('td');\n\t\t\tyear -= 1;\n\t\t\tvar years = $.map(this.dates, function(d){\n\t\t\t\t\treturn d.getUTCFullYear();\n\t\t\t\t}),\n\t\t\t\tclasses;\n\t\t\tfor (var i = -1; i < 11; i++){\n\t\t\t\tclasses = ['year'];\n\t\t\t\tif (i === -1)\n\t\t\t\t\tclasses.push('old');\n\t\t\t\telse if (i === 10)\n\t\t\t\t\tclasses.push('new');\n\t\t\t\tif ($.inArray(year, years) !== -1)\n\t\t\t\t\tclasses.push('active');\n\t\t\t\tif (year < startYear || year > endYear)\n\t\t\t\t\tclasses.push('disabled');\n\t\t\t\thtml += '<span class=\"' + classes.join(' ') + '\">'+year+'</span>';\n\t\t\t\tyear += 1;\n\t\t\t}\n\t\t\tyearCont.html(html);\n\t\t},\n\n\t\tupdateNavArrows: function(){\n\t\t\tif (!this._allow_update)\n\t\t\t\treturn;\n\n\t\t\tvar d = new Date(this.viewDate),\n\t\t\t\tyear = d.getUTCFullYear(),\n\t\t\t\tmonth = d.getUTCMonth();\n\t\t\tswitch (this.viewMode){\n\t\t\t\tcase 0:\n\t\t\t\t\tif (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear() && month <= this.o.startDate.getUTCMonth()){\n\t\t\t\t\t\tthis.picker.find('.prev').css({visibility: 'hidden'});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.picker.find('.prev').css({visibility: 'visible'});\n\t\t\t\t\t}\n\t\t\t\t\tif (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear() && month >= this.o.endDate.getUTCMonth()){\n\t\t\t\t\t\tthis.picker.find('.next').css({visibility: 'hidden'});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.picker.find('.next').css({visibility: 'visible'});\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 1:\n\t\t\t\tcase 2:\n\t\t\t\t\tif (this.o.startDate !== -Infinity && year <= this.o.startDate.getUTCFullYear()){\n\t\t\t\t\t\tthis.picker.find('.prev').css({visibility: 'hidden'});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.picker.find('.prev').css({visibility: 'visible'});\n\t\t\t\t\t}\n\t\t\t\t\tif (this.o.endDate !== Infinity && year >= this.o.endDate.getUTCFullYear()){\n\t\t\t\t\t\tthis.picker.find('.next').css({visibility: 'hidden'});\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.picker.find('.next').css({visibility: 'visible'});\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t},\n\n\t\tclick: function(e){\n\t\t\te.preventDefault();\n\t\t\tvar target = $(e.target).closest('span, td, th'),\n\t\t\t\tyear, month, day;\n\t\t\tif (target.length === 1){\n\t\t\t\tswitch (target[0].nodeName.toLowerCase()){\n\t\t\t\t\tcase 'th':\n\t\t\t\t\t\tswitch (target[0].className){\n\t\t\t\t\t\t\tcase 'datepicker-switch':\n\t\t\t\t\t\t\t\tthis.showMode(1);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'prev':\n\t\t\t\t\t\t\tcase 'next':\n\t\t\t\t\t\t\t\tvar dir = DPGlobal.modes[this.viewMode].navStep * (target[0].className === 'prev' ? -1 : 1);\n\t\t\t\t\t\t\t\tswitch (this.viewMode){\n\t\t\t\t\t\t\t\t\tcase 0:\n\t\t\t\t\t\t\t\t\t\tthis.viewDate = this.moveMonth(this.viewDate, dir);\n\t\t\t\t\t\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 1:\n\t\t\t\t\t\t\t\t\tcase 2:\n\t\t\t\t\t\t\t\t\t\tthis.viewDate = this.moveYear(this.viewDate, dir);\n\t\t\t\t\t\t\t\t\t\tif (this.viewMode === 1)\n\t\t\t\t\t\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tthis.fill();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'today':\n\t\t\t\t\t\t\t\tvar date = new Date();\n\t\t\t\t\t\t\t\tdate = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);\n\n\t\t\t\t\t\t\t\tthis.showMode(-2);\n\t\t\t\t\t\t\t\tvar which = this.o.todayBtn === 'linked' ? null : 'view';\n\t\t\t\t\t\t\t\tthis._setDate(date, which);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'clear':\n\t\t\t\t\t\t\t\tvar element;\n\t\t\t\t\t\t\t\tif (this.isInput)\n\t\t\t\t\t\t\t\t\telement = this.element;\n\t\t\t\t\t\t\t\telse if (this.component)\n\t\t\t\t\t\t\t\t\telement = this.element.find('input');\n\t\t\t\t\t\t\t\tif (element)\n\t\t\t\t\t\t\t\t\telement.val(\"\").change();\n\t\t\t\t\t\t\t\tthis.update();\n\t\t\t\t\t\t\t\tthis._trigger('changeDate');\n\t\t\t\t\t\t\t\tif (this.o.autoclose)\n\t\t\t\t\t\t\t\t\tthis.hide();\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'span':\n\t\t\t\t\t\tif (!target.is('.disabled')){\n\t\t\t\t\t\t\tthis.viewDate.setUTCDate(1);\n\t\t\t\t\t\t\tif (target.is('.month')){\n\t\t\t\t\t\t\t\tday = 1;\n\t\t\t\t\t\t\t\tmonth = target.parent().find('span').index(target);\n\t\t\t\t\t\t\t\tyear = this.viewDate.getUTCFullYear();\n\t\t\t\t\t\t\t\tthis.viewDate.setUTCMonth(month);\n\t\t\t\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n\t\t\t\t\t\t\t\tif (this.o.minViewMode === 1){\n\t\t\t\t\t\t\t\t\tthis._setDate(UTCDate(year, month, day));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tday = 1;\n\t\t\t\t\t\t\t\tmonth = 0;\n\t\t\t\t\t\t\t\tyear = parseInt(target.text(), 10)||0;\n\t\t\t\t\t\t\t\tthis.viewDate.setUTCFullYear(year);\n\t\t\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n\t\t\t\t\t\t\t\tif (this.o.minViewMode === 2){\n\t\t\t\t\t\t\t\t\tthis._setDate(UTCDate(year, month, day));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis.showMode(-1);\n\t\t\t\t\t\t\tthis.fill();\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'td':\n\t\t\t\t\t\tif (target.is('.day') && !target.is('.disabled')){\n\t\t\t\t\t\t\tday = parseInt(target.text(), 10)||1;\n\t\t\t\t\t\t\tyear = this.viewDate.getUTCFullYear();\n\t\t\t\t\t\t\tmonth = this.viewDate.getUTCMonth();\n\t\t\t\t\t\t\tif (target.is('.old')){\n\t\t\t\t\t\t\t\tif (month === 0){\n\t\t\t\t\t\t\t\t\tmonth = 11;\n\t\t\t\t\t\t\t\t\tyear -= 1;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tmonth -= 1;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (target.is('.new')){\n\t\t\t\t\t\t\t\tif (month === 11){\n\t\t\t\t\t\t\t\t\tmonth = 0;\n\t\t\t\t\t\t\t\t\tyear += 1;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\t\tmonth += 1;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tthis._setDate(UTCDate(year, month, day));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (this.picker.is(':visible') && this._focused_from){\n\t\t\t\t$(this._focused_from).focus();\n\t\t\t}\n\t\t\tdelete this._focused_from;\n\t\t},\n\n\t\t_toggle_multidate: function(date){\n\t\t\tvar ix = this.dates.contains(date);\n\t\t\tif (!date){\n\t\t\t\tthis.dates.clear();\n\t\t\t}\n\t\t\telse if (ix !== -1){\n\t\t\t\tthis.dates.remove(ix);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tthis.dates.push(date);\n\t\t\t}\n\t\t\tif (typeof this.o.multidate === 'number')\n\t\t\t\twhile (this.dates.length > this.o.multidate)\n\t\t\t\t\tthis.dates.remove(0);\n\t\t},\n\n\t\t_setDate: function(date, which){\n\t\t\tif (!which || which === 'date')\n\t\t\t\tthis._toggle_multidate(date && new Date(date));\n\t\t\tif (!which || which  === 'view')\n\t\t\t\tthis.viewDate = date && new Date(date);\n\n\t\t\tthis.fill();\n\t\t\tthis.setValue();\n\t\t\tthis._trigger('changeDate');\n\t\t\tvar element;\n\t\t\tif (this.isInput){\n\t\t\t\telement = this.element;\n\t\t\t}\n\t\t\telse if (this.component){\n\t\t\t\telement = this.element.find('input');\n\t\t\t}\n\t\t\tif (element){\n\t\t\t\telement.change();\n\t\t\t}\n\t\t\tif (this.o.autoclose && (!which || which === 'date')){\n\t\t\t\tthis.hide();\n\t\t\t}\n\t\t},\n\n\t\tmoveMonth: function(date, dir){\n\t\t\tif (!date)\n\t\t\t\treturn undefined;\n\t\t\tif (!dir)\n\t\t\t\treturn date;\n\t\t\tvar new_date = new Date(date.valueOf()),\n\t\t\t\tday = new_date.getUTCDate(),\n\t\t\t\tmonth = new_date.getUTCMonth(),\n\t\t\t\tmag = Math.abs(dir),\n\t\t\t\tnew_month, test;\n\t\t\tdir = dir > 0 ? 1 : -1;\n\t\t\tif (mag === 1){\n\t\t\t\ttest = dir === -1\n\t\t\t\t\t// If going back one month, make sure month is not current month\n\t\t\t\t\t// (eg, Mar 31 -> Feb 31 == Feb 28, not Mar 02)\n\t\t\t\t\t? function(){\n\t\t\t\t\t\treturn new_date.getUTCMonth() === month;\n\t\t\t\t\t}\n\t\t\t\t\t// If going forward one month, make sure month is as expected\n\t\t\t\t\t// (eg, Jan 31 -> Feb 31 == Feb 28, not Mar 02)\n\t\t\t\t\t: function(){\n\t\t\t\t\t\treturn new_date.getUTCMonth() !== new_month;\n\t\t\t\t\t};\n\t\t\t\tnew_month = month + dir;\n\t\t\t\tnew_date.setUTCMonth(new_month);\n\t\t\t\t// Dec -> Jan (12) or Jan -> Dec (-1) -- limit expected date to 0-11\n\t\t\t\tif (new_month < 0 || new_month > 11)\n\t\t\t\t\tnew_month = (new_month + 12) % 12;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// For magnitudes >1, move one month at a time...\n\t\t\t\tfor (var i=0; i < mag; i++)\n\t\t\t\t\t// ...which might decrease the day (eg, Jan 31 to Feb 28, etc)...\n\t\t\t\t\tnew_date = this.moveMonth(new_date, dir);\n\t\t\t\t// ...then reset the day, keeping it in the new month\n\t\t\t\tnew_month = new_date.getUTCMonth();\n\t\t\t\tnew_date.setUTCDate(day);\n\t\t\t\ttest = function(){\n\t\t\t\t\treturn new_month !== new_date.getUTCMonth();\n\t\t\t\t};\n\t\t\t}\n\t\t\t// Common date-resetting loop -- if date is beyond end of month, make it\n\t\t\t// end of month\n\t\t\twhile (test()){\n\t\t\t\tnew_date.setUTCDate(--day);\n\t\t\t\tnew_date.setUTCMonth(new_month);\n\t\t\t}\n\t\t\treturn new_date;\n\t\t},\n\n\t\tmoveYear: function(date, dir){\n\t\t\treturn this.moveMonth(date, dir*12);\n\t\t},\n\n\t\tdateWithinRange: function(date){\n\t\t\treturn date >= this.o.startDate && date <= this.o.endDate;\n\t\t},\n\n\t\tkeydown: function(e){\n\t\t\tif (this.picker.is(':not(:visible)')){\n\t\t\t\tif (e.keyCode === 27) // allow escape to hide and re-show picker\n\t\t\t\t\tthis.show();\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tvar dateChanged = false,\n\t\t\t\tdir, newDate, newViewDate,\n\t\t\t\tfocusDate = this.focusDate || this.viewDate;\n\t\t\tswitch (e.keyCode){\n\t\t\t\tcase 27: // escape\n\t\t\t\t\tif (this.focusDate){\n\t\t\t\t\t\tthis.focusDate = null;\n\t\t\t\t\t\tthis.viewDate = this.dates.get(-1) || this.viewDate;\n\t\t\t\t\t\tthis.fill();\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\tthis.hide();\n\t\t\t\t\te.preventDefault();\n\t\t\t\t\tbreak;\n\t\t\t\tcase 37: // left\n\t\t\t\tcase 39: // right\n\t\t\t\t\tif (!this.o.keyboardNavigation)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdir = e.keyCode === 37 ? -1 : 1;\n\t\t\t\t\tif (e.ctrlKey){\n\t\t\t\t\t\tnewDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);\n\t\t\t\t\t\tnewViewDate = this.moveYear(focusDate, dir);\n\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n\t\t\t\t\t}\n\t\t\t\t\telse if (e.shiftKey){\n\t\t\t\t\t\tnewDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);\n\t\t\t\t\t\tnewViewDate = this.moveMonth(focusDate, dir);\n\t\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tnewDate = new Date(this.dates.get(-1) || UTCToday());\n\t\t\t\t\t\tnewDate.setUTCDate(newDate.getUTCDate() + dir);\n\t\t\t\t\t\tnewViewDate = new Date(focusDate);\n\t\t\t\t\t\tnewViewDate.setUTCDate(focusDate.getUTCDate() + dir);\n\t\t\t\t\t}\n\t\t\t\t\tif (this.dateWithinRange(newDate)){\n\t\t\t\t\t\tthis.focusDate = this.viewDate = newViewDate;\n\t\t\t\t\t\tthis.setValue();\n\t\t\t\t\t\tthis.fill();\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 38: // up\n\t\t\t\tcase 40: // down\n\t\t\t\t\tif (!this.o.keyboardNavigation)\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdir = e.keyCode === 38 ? -1 : 1;\n\t\t\t\t\tif (e.ctrlKey){\n\t\t\t\t\t\tnewDate = this.moveYear(this.dates.get(-1) || UTCToday(), dir);\n\t\t\t\t\t\tnewViewDate = this.moveYear(focusDate, dir);\n\t\t\t\t\t\tthis._trigger('changeYear', this.viewDate);\n\t\t\t\t\t}\n\t\t\t\t\telse if (e.shiftKey){\n\t\t\t\t\t\tnewDate = this.moveMonth(this.dates.get(-1) || UTCToday(), dir);\n\t\t\t\t\t\tnewViewDate = this.moveMonth(focusDate, dir);\n\t\t\t\t\t\tthis._trigger('changeMonth', this.viewDate);\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tnewDate = new Date(this.dates.get(-1) || UTCToday());\n\t\t\t\t\t\tnewDate.setUTCDate(newDate.getUTCDate() + dir * 7);\n\t\t\t\t\t\tnewViewDate = new Date(focusDate);\n\t\t\t\t\t\tnewViewDate.setUTCDate(focusDate.getUTCDate() + dir * 7);\n\t\t\t\t\t}\n\t\t\t\t\tif (this.dateWithinRange(newDate)){\n\t\t\t\t\t\tthis.focusDate = this.viewDate = newViewDate;\n\t\t\t\t\t\tthis.setValue();\n\t\t\t\t\t\tthis.fill();\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 32: // spacebar\n\t\t\t\t\t// Spacebar is used in manually typing dates in some formats.\n\t\t\t\t\t// As such, its behavior should not be hijacked.\n\t\t\t\t\tbreak;\n\t\t\t\tcase 13: // enter\n\t\t\t\t\tfocusDate = this.focusDate || this.dates.get(-1) || this.viewDate;\n\t\t\t\t\tthis._toggle_multidate(focusDate);\n\t\t\t\t\tdateChanged = true;\n\t\t\t\t\tthis.focusDate = null;\n\t\t\t\t\tthis.viewDate = this.dates.get(-1) || this.viewDate;\n\t\t\t\t\tthis.setValue();\n\t\t\t\t\tthis.fill();\n\t\t\t\t\tif (this.picker.is(':visible')){\n\t\t\t\t\t\te.preventDefault();\n\t\t\t\t\t\tif (this.o.autoclose)\n\t\t\t\t\t\t\tthis.hide();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase 9: // tab\n\t\t\t\t\tthis.focusDate = null;\n\t\t\t\t\tthis.viewDate = this.dates.get(-1) || this.viewDate;\n\t\t\t\t\tthis.fill();\n\t\t\t\t\tthis.hide();\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (dateChanged){\n\t\t\t\tif (this.dates.length)\n\t\t\t\t\tthis._trigger('changeDate');\n\t\t\t\telse\n\t\t\t\t\tthis._trigger('clearDate');\n\t\t\t\tvar element;\n\t\t\t\tif (this.isInput){\n\t\t\t\t\telement = this.element;\n\t\t\t\t}\n\t\t\t\telse if (this.component){\n\t\t\t\t\telement = this.element.find('input');\n\t\t\t\t}\n\t\t\t\tif (element){\n\t\t\t\t\telement.change();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tshowMode: function(dir){\n\t\t\tif (dir){\n\t\t\t\tthis.viewMode = Math.max(this.o.minViewMode, Math.min(2, this.viewMode + dir));\n\t\t\t}\n\t\t\tthis.picker\n\t\t\t\t.find('>div')\n\t\t\t\t.hide()\n\t\t\t\t.filter('.datepicker-'+DPGlobal.modes[this.viewMode].clsName)\n\t\t\t\t\t.css('display', 'block');\n\t\t\tthis.updateNavArrows();\n\t\t}\n\t};\n\n\tvar DateRangePicker = function(element, options){\n\t\tthis.element = $(element);\n\t\tthis.inputs = $.map(options.inputs, function(i){\n\t\t\treturn i.jquery ? i[0] : i;\n\t\t});\n\t\tdelete options.inputs;\n\n\t\t$(this.inputs)\n\t\t\t.datepicker(options)\n\t\t\t.bind('changeDate', $.proxy(this.dateUpdated, this));\n\n\t\tthis.pickers = $.map(this.inputs, function(i){\n\t\t\treturn $(i).data('datepicker');\n\t\t});\n\t\tthis.updateDates();\n\t};\n\tDateRangePicker.prototype = {\n\t\tupdateDates: function(){\n\t\t\tthis.dates = $.map(this.pickers, function(i){\n\t\t\t\treturn i.getUTCDate();\n\t\t\t});\n\t\t\tthis.updateRanges();\n\t\t},\n\t\tupdateRanges: function(){\n\t\t\tvar range = $.map(this.dates, function(d){\n\t\t\t\treturn d.valueOf();\n\t\t\t});\n\t\t\t$.each(this.pickers, function(i, p){\n\t\t\t\tp.setRange(range);\n\t\t\t});\n\t\t},\n\t\tdateUpdated: function(e){\n\t\t\t// `this.updating` is a workaround for preventing infinite recursion\n\t\t\t// between `changeDate` triggering and `setUTCDate` calling.  Until\n\t\t\t// there is a better mechanism.\n\t\t\tif (this.updating)\n\t\t\t\treturn;\n\t\t\tthis.updating = true;\n\n\t\t\tvar dp = $(e.target).data('datepicker'),\n\t\t\t\tnew_date = dp.getUTCDate(),\n\t\t\t\ti = $.inArray(e.target, this.inputs),\n\t\t\t\tl = this.inputs.length;\n\t\t\tif (i === -1)\n\t\t\t\treturn;\n\n\t\t\t$.each(this.pickers, function(i, p){\n\t\t\t\tif (!p.getUTCDate())\n\t\t\t\t\tp.setUTCDate(new_date);\n\t\t\t});\n\n\t\t\tif (new_date < this.dates[i]){\n\t\t\t\t// Date being moved earlier/left\n\t\t\t\twhile (i >= 0 && new_date < this.dates[i]){\n\t\t\t\t\tthis.pickers[i--].setUTCDate(new_date);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse if (new_date > this.dates[i]){\n\t\t\t\t// Date being moved later/right\n\t\t\t\twhile (i < l && new_date > this.dates[i]){\n\t\t\t\t\tthis.pickers[i++].setUTCDate(new_date);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.updateDates();\n\n\t\t\tdelete this.updating;\n\t\t},\n\t\tremove: function(){\n\t\t\t$.map(this.pickers, function(p){ p.remove(); });\n\t\t\tdelete this.element.data().datepicker;\n\t\t}\n\t};\n\n\tfunction opts_from_el(el, prefix){\n\t\t// Derive options from element data-attrs\n\t\tvar data = $(el).data(),\n\t\t\tout = {}, inkey,\n\t\t\treplace = new RegExp('^' + prefix.toLowerCase() + '([A-Z])');\n\t\tprefix = new RegExp('^' + prefix.toLowerCase());\n\t\tfunction re_lower(_,a){\n\t\t\treturn a.toLowerCase();\n\t\t}\n\t\tfor (var key in data)\n\t\t\tif (prefix.test(key)){\n\t\t\t\tinkey = key.replace(replace, re_lower);\n\t\t\t\tout[inkey] = data[key];\n\t\t\t}\n\t\treturn out;\n\t}\n\n\tfunction opts_from_locale(lang){\n\t\t// Derive options from locale plugins\n\t\tvar out = {};\n\t\t// Check if \"de-DE\" style date is available, if not language should\n\t\t// fallback to 2 letter code eg \"de\"\n\t\tif (!dates[lang]){\n\t\t\tlang = lang.split('-')[0];\n\t\t\tif (!dates[lang])\n\t\t\t\treturn;\n\t\t}\n\t\tvar d = dates[lang];\n\t\t$.each(locale_opts, function(i,k){\n\t\t\tif (k in d)\n\t\t\t\tout[k] = d[k];\n\t\t});\n\t\treturn out;\n\t}\n\n\tvar old = $.fn.datepicker;\n\t$.fn.datepicker = function(option){\n\t\tvar args = Array.apply(null, arguments);\n\t\targs.shift();\n\t\tvar internal_return;\n\t\tthis.each(function(){\n\t\t\tvar $this = $(this),\n\t\t\t\tdata = $this.data('datepicker'),\n\t\t\t\toptions = typeof option === 'object' && option;\n\t\t\tif (!data){\n\t\t\t\tvar elopts = opts_from_el(this, 'date'),\n\t\t\t\t\t// Preliminary otions\n\t\t\t\t\txopts = $.extend({}, defaults, elopts, options),\n\t\t\t\t\tlocopts = opts_from_locale(xopts.language),\n\t\t\t\t\t// Options priority: js args, data-attrs, locales, defaults\n\t\t\t\t\topts = $.extend({}, defaults, locopts, elopts, options);\n\t\t\t\tif ($this.is('.input-daterange') || opts.inputs){\n\t\t\t\t\tvar ropts = {\n\t\t\t\t\t\tinputs: opts.inputs || $this.find('input').toArray()\n\t\t\t\t\t};\n\t\t\t\t\t$this.data('datepicker', (data = new DateRangePicker(this, $.extend(opts, ropts))));\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t$this.data('datepicker', (data = new Datepicker(this, opts)));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (typeof option === 'string' && typeof data[option] === 'function'){\n\t\t\t\tinternal_return = data[option].apply(data, args);\n\t\t\t\tif (internal_return !== undefined)\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\tif (internal_return !== undefined)\n\t\t\treturn internal_return;\n\t\telse\n\t\t\treturn this;\n\t};\n\n\tvar defaults = $.fn.datepicker.defaults = {\n\t\tautoclose: false,\n\t\tbeforeShowDay: $.noop,\n\t\tcalendarWeeks: false,\n\t\tclearBtn: false,\n\t\tdaysOfWeekDisabled: [],\n\t\tendDate: Infinity,\n\t\tforceParse: true,\n\t\tformat: 'mm/dd/yyyy',\n\t\tkeyboardNavigation: true,\n\t\tlanguage: 'en',\n\t\tminViewMode: 0,\n\t\tmultidate: false,\n\t\tmultidateSeparator: ',',\n\t\torientation: \"auto\",\n\t\trtl: false,\n\t\tstartDate: -Infinity,\n\t\tstartView: 0,\n\t\ttodayBtn: false,\n\t\ttodayHighlight: false,\n\t\tweekStart: 0\n\t};\n\tvar locale_opts = $.fn.datepicker.locale_opts = [\n\t\t'format',\n\t\t'rtl',\n\t\t'weekStart'\n\t];\n\t$.fn.datepicker.Constructor = Datepicker;\n\tvar dates = $.fn.datepicker.dates = {\n\t\ten: {\n\t\t\tdays: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\", \"Sunday\"],\n\t\t\tdaysShort: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\", \"Sun\"],\n\t\t\tdaysMin: [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\", \"Su\"],\n\t\t\tmonths: [\"January\", \"February\", \"March\", \"April\", \"May\", \"June\", \"July\", \"August\", \"September\", \"October\", \"November\", \"December\"],\n\t\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n\t\t\ttoday: \"Today\",\n\t\t\tclear: \"Clear\"\n\t\t}\n\t};\n\n\tvar DPGlobal = {\n\t\tmodes: [\n\t\t\t{\n\t\t\t\tclsName: 'days',\n\t\t\t\tnavFnc: 'Month',\n\t\t\t\tnavStep: 1\n\t\t\t},\n\t\t\t{\n\t\t\t\tclsName: 'months',\n\t\t\t\tnavFnc: 'FullYear',\n\t\t\t\tnavStep: 1\n\t\t\t},\n\t\t\t{\n\t\t\t\tclsName: 'years',\n\t\t\t\tnavFnc: 'FullYear',\n\t\t\t\tnavStep: 10\n\t\t}],\n\t\tisLeapYear: function(year){\n\t\t\treturn (((year % 4 === 0) && (year % 100 !== 0)) || (year % 400 === 0));\n\t\t},\n\t\tgetDaysInMonth: function(year, month){\n\t\t\treturn [31, (DPGlobal.isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];\n\t\t},\n\t\tvalidParts: /dd?|DD?|mm?|MM?|yy(?:yy)?/g,\n\t\tnonpunctuation: /[^ -\\/:-@\\[\\u3400-\\u9fff-`{-~\\t\\n\\r]+/g,\n\t\tparseFormat: function(format){\n\t\t\t// IE treats \\0 as a string end in inputs (truncating the value),\n\t\t\t// so it's a bad format delimiter, anyway\n\t\t\tvar separators = format.replace(this.validParts, '\\0').split('\\0'),\n\t\t\t\tparts = format.match(this.validParts);\n\t\t\tif (!separators || !separators.length || !parts || parts.length === 0){\n\t\t\t\tthrow new Error(\"Invalid date format.\");\n\t\t\t}\n\t\t\treturn {separators: separators, parts: parts};\n\t\t},\n\t\tparseDate: function(date, format, language){\n\t\t\tif (!date)\n\t\t\t\treturn undefined;\n\t\t\tif (date instanceof Date)\n\t\t\t\treturn date;\n\t\t\tif (typeof format === 'string')\n\t\t\t\tformat = DPGlobal.parseFormat(format);\n\t\t\tvar part_re = /([\\-+]\\d+)([dmwy])/,\n\t\t\t\tparts = date.match(/([\\-+]\\d+)([dmwy])/g),\n\t\t\t\tpart, dir, i;\n\t\t\tif (/^[\\-+]\\d+[dmwy]([\\s,]+[\\-+]\\d+[dmwy])*$/.test(date)){\n\t\t\t\tdate = new Date();\n\t\t\t\tfor (i=0; i < parts.length; i++){\n\t\t\t\t\tpart = part_re.exec(parts[i]);\n\t\t\t\t\tdir = parseInt(part[1]);\n\t\t\t\t\tswitch (part[2]){\n\t\t\t\t\t\tcase 'd':\n\t\t\t\t\t\t\tdate.setUTCDate(date.getUTCDate() + dir);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'm':\n\t\t\t\t\t\t\tdate = Datepicker.prototype.moveMonth.call(Datepicker.prototype, date, dir);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'w':\n\t\t\t\t\t\t\tdate.setUTCDate(date.getUTCDate() + dir * 7);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'y':\n\t\t\t\t\t\t\tdate = Datepicker.prototype.moveYear.call(Datepicker.prototype, date, dir);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn UTCDate(date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate(), 0, 0, 0);\n\t\t\t}\n\t\t\tparts = date && date.match(this.nonpunctuation) || [];\n\t\t\tdate = new Date();\n\t\t\tvar parsed = {},\n\t\t\t\tsetters_order = ['yyyy', 'yy', 'M', 'MM', 'm', 'mm', 'd', 'dd'],\n\t\t\t\tsetters_map = {\n\t\t\t\t\tyyyy: function(d,v){\n\t\t\t\t\t\treturn d.setUTCFullYear(v);\n\t\t\t\t\t},\n\t\t\t\t\tyy: function(d,v){\n\t\t\t\t\t\treturn d.setUTCFullYear(2000+v);\n\t\t\t\t\t},\n\t\t\t\t\tm: function(d,v){\n\t\t\t\t\t\tif (isNaN(d))\n\t\t\t\t\t\t\treturn d;\n\t\t\t\t\t\tv -= 1;\n\t\t\t\t\t\twhile (v < 0) v += 12;\n\t\t\t\t\t\tv %= 12;\n\t\t\t\t\t\td.setUTCMonth(v);\n\t\t\t\t\t\twhile (d.getUTCMonth() !== v)\n\t\t\t\t\t\t\td.setUTCDate(d.getUTCDate()-1);\n\t\t\t\t\t\treturn d;\n\t\t\t\t\t},\n\t\t\t\t\td: function(d,v){\n\t\t\t\t\t\treturn d.setUTCDate(v);\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tval, filtered;\n\t\t\tsetters_map['M'] = setters_map['MM'] = setters_map['mm'] = setters_map['m'];\n\t\t\tsetters_map['dd'] = setters_map['d'];\n\t\t\tdate = UTCDate(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0);\n\t\t\tvar fparts = format.parts.slice();\n\t\t\t// Remove noop parts\n\t\t\tif (parts.length !== fparts.length){\n\t\t\t\tfparts = $(fparts).filter(function(i,p){\n\t\t\t\t\treturn $.inArray(p, setters_order) !== -1;\n\t\t\t\t}).toArray();\n\t\t\t}\n\t\t\t// Process remainder\n\t\t\tfunction match_part(){\n\t\t\t\tvar m = this.slice(0, parts[i].length),\n\t\t\t\t\tp = parts[i].slice(0, m.length);\n\t\t\t\treturn m === p;\n\t\t\t}\n\t\t\tif (parts.length === fparts.length){\n\t\t\t\tvar cnt;\n\t\t\t\tfor (i=0, cnt = fparts.length; i < cnt; i++){\n\t\t\t\t\tval = parseInt(parts[i], 10);\n\t\t\t\t\tpart = fparts[i];\n\t\t\t\t\tif (isNaN(val)){\n\t\t\t\t\t\tswitch (part){\n\t\t\t\t\t\t\tcase 'MM':\n\t\t\t\t\t\t\t\tfiltered = $(dates[language].months).filter(match_part);\n\t\t\t\t\t\t\t\tval = $.inArray(filtered[0], dates[language].months) + 1;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'M':\n\t\t\t\t\t\t\t\tfiltered = $(dates[language].monthsShort).filter(match_part);\n\t\t\t\t\t\t\t\tval = $.inArray(filtered[0], dates[language].monthsShort) + 1;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tparsed[part] = val;\n\t\t\t\t}\n\t\t\t\tvar _date, s;\n\t\t\t\tfor (i=0; i < setters_order.length; i++){\n\t\t\t\t\ts = setters_order[i];\n\t\t\t\t\tif (s in parsed && !isNaN(parsed[s])){\n\t\t\t\t\t\t_date = new Date(date);\n\t\t\t\t\t\tsetters_map[s](_date, parsed[s]);\n\t\t\t\t\t\tif (!isNaN(_date))\n\t\t\t\t\t\t\tdate = _date;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn date;\n\t\t},\n\t\tformatDate: function(date, format, language){\n\t\t\tif (!date)\n\t\t\t\treturn '';\n\t\t\tif (typeof format === 'string')\n\t\t\t\tformat = DPGlobal.parseFormat(format);\n\t\t\tvar val = {\n\t\t\t\td: date.getUTCDate(),\n\t\t\t\tD: dates[language].daysShort[date.getUTCDay()],\n\t\t\t\tDD: dates[language].days[date.getUTCDay()],\n\t\t\t\tm: date.getUTCMonth() + 1,\n\t\t\t\tM: dates[language].monthsShort[date.getUTCMonth()],\n\t\t\t\tMM: dates[language].months[date.getUTCMonth()],\n\t\t\t\tyy: date.getUTCFullYear().toString().substring(2),\n\t\t\t\tyyyy: date.getUTCFullYear()\n\t\t\t};\n\t\t\tval.dd = (val.d < 10 ? '0' : '') + val.d;\n\t\t\tval.mm = (val.m < 10 ? '0' : '') + val.m;\n\t\t\tdate = [];\n\t\t\tvar seps = $.extend([], format.separators);\n\t\t\tfor (var i=0, cnt = format.parts.length; i <= cnt; i++){\n\t\t\t\tif (seps.length)\n\t\t\t\t\tdate.push(seps.shift());\n\t\t\t\tdate.push(val[format.parts[i]]);\n\t\t\t}\n\t\t\treturn date.join('');\n\t\t},\n\t\theadTemplate: '<thead>'+\n\t\t\t\t\t\t\t'<tr>'+\n\t\t\t\t\t\t\t\t'<th class=\"prev\">&laquo;</th>'+\n\t\t\t\t\t\t\t\t'<th colspan=\"5\" class=\"datepicker-switch\"></th>'+\n\t\t\t\t\t\t\t\t'<th class=\"next\">&raquo;</th>'+\n\t\t\t\t\t\t\t'</tr>'+\n\t\t\t\t\t\t'</thead>',\n\t\tcontTemplate: '<tbody><tr><td colspan=\"7\"></td></tr></tbody>',\n\t\tfootTemplate: '<tfoot>'+\n\t\t\t\t\t\t\t'<tr>'+\n\t\t\t\t\t\t\t\t'<th colspan=\"7\" class=\"today\"></th>'+\n\t\t\t\t\t\t\t'</tr>'+\n\t\t\t\t\t\t\t'<tr>'+\n\t\t\t\t\t\t\t\t'<th colspan=\"7\" class=\"clear\"></th>'+\n\t\t\t\t\t\t\t'</tr>'+\n\t\t\t\t\t\t'</tfoot>'\n\t};\n\tDPGlobal.template = '<div class=\"datepicker\">'+\n\t\t\t\t\t\t\t'<div class=\"datepicker-days\">'+\n\t\t\t\t\t\t\t\t'<table class=\"table table-condensed\">'+\n\t\t\t\t\t\t\t\t\tDPGlobal.headTemplate+\n\t\t\t\t\t\t\t\t\t'<tbody></tbody>'+\n\t\t\t\t\t\t\t\t\tDPGlobal.footTemplate+\n\t\t\t\t\t\t\t\t'</table>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t\t'<div class=\"datepicker-months\">'+\n\t\t\t\t\t\t\t\t'<table class=\"table table-condensed\">'+\n\t\t\t\t\t\t\t\t\tDPGlobal.headTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.contTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.footTemplate+\n\t\t\t\t\t\t\t\t'</table>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t\t'<div class=\"datepicker-years\">'+\n\t\t\t\t\t\t\t\t'<table class=\"table table-condensed\">'+\n\t\t\t\t\t\t\t\t\tDPGlobal.headTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.contTemplate+\n\t\t\t\t\t\t\t\t\tDPGlobal.footTemplate+\n\t\t\t\t\t\t\t\t'</table>'+\n\t\t\t\t\t\t\t'</div>'+\n\t\t\t\t\t\t'</div>';\n\n\t$.fn.datepicker.DPGlobal = DPGlobal;\n\n\n\t/* DATEPICKER NO CONFLICT\n\t* =================== */\n\n\t$.fn.datepicker.noConflict = function(){\n\t\t$.fn.datepicker = old;\n\t\treturn this;\n\t};\n\n\n\t/* DATEPICKER DATA-API\n\t* ================== */\n\n\t$(document).on(\n\t\t'focus.datepicker.data-api click.datepicker.data-api',\n\t\t'[data-provide=\"datepicker\"]',\n\t\tfunction(e){\n\t\t\tvar $this = $(this);\n\t\t\tif ($this.data('datepicker'))\n\t\t\t\treturn;\n\t\t\te.preventDefault();\n\t\t\t// component click requires us to explicitly show it\n\t\t\t$this.datepicker('show');\n\t\t}\n\t);\n\t$(function(){\n\t\t$('[data-provide=\"datepicker-inline\"]').datepicker();\n\t});\n\n}(window.jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/datepicker3.css",
    "content": "/*!\n * Datepicker for Bootstrap\n *\n * Copyright 2012 Stefan Petre\n * Improvements by Andrew Rowls\n * Licensed under the Apache License v2.0\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n */\n.datepicker {\n  padding: 4px;\n  border-radius: 4px;\n  direction: ltr;\n  /*.dow {\n\t\tborder-top: 1px solid #ddd !important;\n\t}*/\n}\n.datepicker-inline {\n  width: 100%;\n}\n.datepicker.datepicker-rtl {\n  direction: rtl;\n}\n.datepicker.datepicker-rtl table tr td span {\n  float: right;\n}\n.datepicker-dropdown {\n  top: 0;\n  left: 0;\n}\n.datepicker-dropdown:before {\n  content: '';\n  display: inline-block;\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid #ccc;\n  border-top: 0;\n  border-bottom-color: rgba(0, 0, 0, 0.2);\n  position: absolute;\n}\n.datepicker-dropdown:after {\n  content: '';\n  display: inline-block;\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid #fff;\n  border-top: 0;\n  position: absolute;\n}\n.datepicker-dropdown.datepicker-orient-left:before {\n  left: 6px;\n}\n.datepicker-dropdown.datepicker-orient-left:after {\n  left: 7px;\n}\n.datepicker-dropdown.datepicker-orient-right:before {\n  right: 6px;\n}\n.datepicker-dropdown.datepicker-orient-right:after {\n  right: 7px;\n}\n.datepicker-dropdown.datepicker-orient-top:before {\n  top: -7px;\n}\n.datepicker-dropdown.datepicker-orient-top:after {\n  top: -6px;\n}\n.datepicker-dropdown.datepicker-orient-bottom:before {\n  bottom: -7px;\n  border-bottom: 0;\n  border-top: 7px solid #999;\n}\n.datepicker-dropdown.datepicker-orient-bottom:after {\n  bottom: -6px;\n  border-bottom: 0;\n  border-top: 6px solid #fff;\n}\n.datepicker > div {\n  display: none;\n}\n.datepicker.days div.datepicker-days {\n  display: block;\n}\n.datepicker.months div.datepicker-months {\n  display: block;\n}\n.datepicker.years div.datepicker-years {\n  display: block;\n}\n.datepicker table {\n  margin: 0;\n  -webkit-touch-callout: none;\n  -webkit-user-select: none;\n  -khtml-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n.datepicker table tr td,\n.datepicker table tr th {\n  text-align: center;\n  width: 30px;\n  height: 30px;\n  border-radius: 4px;\n  border: none;\n}\n.table-striped .datepicker table tr td,\n.table-striped .datepicker table tr th {\n  background-color: transparent;\n}\n.datepicker table tr td.day:hover,\n.datepicker table tr td.day.focused {\n  background: rgba(0,0,0,0.2);\n  cursor: pointer;\n}\n.datepicker table tr td.old,\n.datepicker table tr td.new {\n  color: #777;\n}\n.datepicker table tr td.disabled,\n.datepicker table tr td.disabled:hover {\n  background: none;\n  color: #444;\n  cursor: default;\n}\n.datepicker table tr td.today,\n.datepicker table tr td.today:hover,\n.datepicker table tr td.today.disabled,\n.datepicker table tr td.today.disabled:hover {\n  color: #000000;\n  background: rgba(0,0,0,0.2);\n  border-color: #ffb733;\n}\n.datepicker table tr td.today:hover,\n.datepicker table tr td.today:hover:hover,\n.datepicker table tr td.today.disabled:hover,\n.datepicker table tr td.today.disabled:hover:hover,\n.datepicker table tr td.today:focus,\n.datepicker table tr td.today:hover:focus,\n.datepicker table tr td.today.disabled:focus,\n.datepicker table tr td.today.disabled:hover:focus,\n.datepicker table tr td.today:active,\n.datepicker table tr td.today:hover:active,\n.datepicker table tr td.today.disabled:active,\n.datepicker table tr td.today.disabled:hover:active,\n.datepicker table tr td.today.active,\n.datepicker table tr td.today:hover.active,\n.datepicker table tr td.today.disabled.active,\n.datepicker table tr td.today.disabled:hover.active,\n.open .dropdown-toggle.datepicker table tr td.today,\n.open .dropdown-toggle.datepicker table tr td.today:hover,\n.open .dropdown-toggle.datepicker table tr td.today.disabled,\n.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {\n  color: #000000;\n  background: rgba(0,0,0,0.2);\n  border-color: #f59e00;\n}\n.datepicker table tr td.today:active,\n.datepicker table tr td.today:hover:active,\n.datepicker table tr td.today.disabled:active,\n.datepicker table tr td.today.disabled:hover:active,\n.datepicker table tr td.today.active,\n.datepicker table tr td.today:hover.active,\n.datepicker table tr td.today.disabled.active,\n.datepicker table tr td.today.disabled:hover.active,\n.open .dropdown-toggle.datepicker table tr td.today,\n.open .dropdown-toggle.datepicker table tr td.today:hover,\n.open .dropdown-toggle.datepicker table tr td.today.disabled,\n.open .dropdown-toggle.datepicker table tr td.today.disabled:hover {\n  background-image: none;\n}\n.datepicker table tr td.today.disabled,\n.datepicker table tr td.today:hover.disabled,\n.datepicker table tr td.today.disabled.disabled,\n.datepicker table tr td.today.disabled:hover.disabled,\n.datepicker table tr td.today[disabled],\n.datepicker table tr td.today:hover[disabled],\n.datepicker table tr td.today.disabled[disabled],\n.datepicker table tr td.today.disabled:hover[disabled],\nfieldset[disabled] .datepicker table tr td.today,\nfieldset[disabled] .datepicker table tr td.today:hover,\nfieldset[disabled] .datepicker table tr td.today.disabled,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover,\n.datepicker table tr td.today.disabled:hover,\n.datepicker table tr td.today:hover.disabled:hover,\n.datepicker table tr td.today.disabled.disabled:hover,\n.datepicker table tr td.today.disabled:hover.disabled:hover,\n.datepicker table tr td.today[disabled]:hover,\n.datepicker table tr td.today:hover[disabled]:hover,\n.datepicker table tr td.today.disabled[disabled]:hover,\n.datepicker table tr td.today.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.today:hover,\nfieldset[disabled] .datepicker table tr td.today:hover:hover,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover:hover,\n.datepicker table tr td.today.disabled:focus,\n.datepicker table tr td.today:hover.disabled:focus,\n.datepicker table tr td.today.disabled.disabled:focus,\n.datepicker table tr td.today.disabled:hover.disabled:focus,\n.datepicker table tr td.today[disabled]:focus,\n.datepicker table tr td.today:hover[disabled]:focus,\n.datepicker table tr td.today.disabled[disabled]:focus,\n.datepicker table tr td.today.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.today:focus,\nfieldset[disabled] .datepicker table tr td.today:hover:focus,\nfieldset[disabled] .datepicker table tr td.today.disabled:focus,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover:focus,\n.datepicker table tr td.today.disabled:active,\n.datepicker table tr td.today:hover.disabled:active,\n.datepicker table tr td.today.disabled.disabled:active,\n.datepicker table tr td.today.disabled:hover.disabled:active,\n.datepicker table tr td.today[disabled]:active,\n.datepicker table tr td.today:hover[disabled]:active,\n.datepicker table tr td.today.disabled[disabled]:active,\n.datepicker table tr td.today.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td.today:active,\nfieldset[disabled] .datepicker table tr td.today:hover:active,\nfieldset[disabled] .datepicker table tr td.today.disabled:active,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover:active,\n.datepicker table tr td.today.disabled.active,\n.datepicker table tr td.today:hover.disabled.active,\n.datepicker table tr td.today.disabled.disabled.active,\n.datepicker table tr td.today.disabled:hover.disabled.active,\n.datepicker table tr td.today[disabled].active,\n.datepicker table tr td.today:hover[disabled].active,\n.datepicker table tr td.today.disabled[disabled].active,\n.datepicker table tr td.today.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td.today.active,\nfieldset[disabled] .datepicker table tr td.today:hover.active,\nfieldset[disabled] .datepicker table tr td.today.disabled.active,\nfieldset[disabled] .datepicker table tr td.today.disabled:hover.active {\n  background: rgba(0,0,0,0.2);\n  border-color: #ffb733;\n}\n.datepicker table tr td.today:hover:hover {\n  color: #000;\n}\n.datepicker table tr td.today.active:hover {\n  color: #fff;\n}\n.datepicker table tr td.range,\n.datepicker table tr td.range:hover,\n.datepicker table tr td.range.disabled,\n.datepicker table tr td.range.disabled:hover {\n  background: rgba(0,0,0,0.2);\n  border-radius: 0;\n}\n.datepicker table tr td.range.today,\n.datepicker table tr td.range.today:hover,\n.datepicker table tr td.range.today.disabled,\n.datepicker table tr td.range.today.disabled:hover {\n  color: #000000;\n  background: rgba(0,0,0,0.2);\n  border-color: #f1a417;\n  border-radius: 0;\n}\n.datepicker table tr td.range.today:hover,\n.datepicker table tr td.range.today:hover:hover,\n.datepicker table tr td.range.today.disabled:hover,\n.datepicker table tr td.range.today.disabled:hover:hover,\n.datepicker table tr td.range.today:focus,\n.datepicker table tr td.range.today:hover:focus,\n.datepicker table tr td.range.today.disabled:focus,\n.datepicker table tr td.range.today.disabled:hover:focus,\n.datepicker table tr td.range.today:active,\n.datepicker table tr td.range.today:hover:active,\n.datepicker table tr td.range.today.disabled:active,\n.datepicker table tr td.range.today.disabled:hover:active,\n.datepicker table tr td.range.today.active,\n.datepicker table tr td.range.today:hover.active,\n.datepicker table tr td.range.today.disabled.active,\n.datepicker table tr td.range.today.disabled:hover.active,\n.open .dropdown-toggle.datepicker table tr td.range.today,\n.open .dropdown-toggle.datepicker table tr td.range.today:hover,\n.open .dropdown-toggle.datepicker table tr td.range.today.disabled,\n.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {\n  color: #000000;\n  background: rgba(0,0,0,0.2);\n  border-color: #bf800c;\n}\n.datepicker table tr td.range.today:active,\n.datepicker table tr td.range.today:hover:active,\n.datepicker table tr td.range.today.disabled:active,\n.datepicker table tr td.range.today.disabled:hover:active,\n.datepicker table tr td.range.today.active,\n.datepicker table tr td.range.today:hover.active,\n.datepicker table tr td.range.today.disabled.active,\n.datepicker table tr td.range.today.disabled:hover.active,\n.open .dropdown-toggle.datepicker table tr td.range.today,\n.open .dropdown-toggle.datepicker table tr td.range.today:hover,\n.open .dropdown-toggle.datepicker table tr td.range.today.disabled,\n.open .dropdown-toggle.datepicker table tr td.range.today.disabled:hover {\n  background-image: none;\n}\n.datepicker table tr td.range.today.disabled,\n.datepicker table tr td.range.today:hover.disabled,\n.datepicker table tr td.range.today.disabled.disabled,\n.datepicker table tr td.range.today.disabled:hover.disabled,\n.datepicker table tr td.range.today[disabled],\n.datepicker table tr td.range.today:hover[disabled],\n.datepicker table tr td.range.today.disabled[disabled],\n.datepicker table tr td.range.today.disabled:hover[disabled],\nfieldset[disabled] .datepicker table tr td.range.today,\nfieldset[disabled] .datepicker table tr td.range.today:hover,\nfieldset[disabled] .datepicker table tr td.range.today.disabled,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover,\n.datepicker table tr td.range.today.disabled:hover,\n.datepicker table tr td.range.today:hover.disabled:hover,\n.datepicker table tr td.range.today.disabled.disabled:hover,\n.datepicker table tr td.range.today.disabled:hover.disabled:hover,\n.datepicker table tr td.range.today[disabled]:hover,\n.datepicker table tr td.range.today:hover[disabled]:hover,\n.datepicker table tr td.range.today.disabled[disabled]:hover,\n.datepicker table tr td.range.today.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.range.today:hover,\nfieldset[disabled] .datepicker table tr td.range.today:hover:hover,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover:hover,\n.datepicker table tr td.range.today.disabled:focus,\n.datepicker table tr td.range.today:hover.disabled:focus,\n.datepicker table tr td.range.today.disabled.disabled:focus,\n.datepicker table tr td.range.today.disabled:hover.disabled:focus,\n.datepicker table tr td.range.today[disabled]:focus,\n.datepicker table tr td.range.today:hover[disabled]:focus,\n.datepicker table tr td.range.today.disabled[disabled]:focus,\n.datepicker table tr td.range.today.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.range.today:focus,\nfieldset[disabled] .datepicker table tr td.range.today:hover:focus,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:focus,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover:focus,\n.datepicker table tr td.range.today.disabled:active,\n.datepicker table tr td.range.today:hover.disabled:active,\n.datepicker table tr td.range.today.disabled.disabled:active,\n.datepicker table tr td.range.today.disabled:hover.disabled:active,\n.datepicker table tr td.range.today[disabled]:active,\n.datepicker table tr td.range.today:hover[disabled]:active,\n.datepicker table tr td.range.today.disabled[disabled]:active,\n.datepicker table tr td.range.today.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td.range.today:active,\nfieldset[disabled] .datepicker table tr td.range.today:hover:active,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:active,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover:active,\n.datepicker table tr td.range.today.disabled.active,\n.datepicker table tr td.range.today:hover.disabled.active,\n.datepicker table tr td.range.today.disabled.disabled.active,\n.datepicker table tr td.range.today.disabled:hover.disabled.active,\n.datepicker table tr td.range.today[disabled].active,\n.datepicker table tr td.range.today:hover[disabled].active,\n.datepicker table tr td.range.today.disabled[disabled].active,\n.datepicker table tr td.range.today.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td.range.today.active,\nfieldset[disabled] .datepicker table tr td.range.today:hover.active,\nfieldset[disabled] .datepicker table tr td.range.today.disabled.active,\nfieldset[disabled] .datepicker table tr td.range.today.disabled:hover.active {\n  background: rgba(0,0,0,0.2);\n  border-color: #f1a417;\n}\n.datepicker table tr td.selected,\n.datepicker table tr td.selected:hover,\n.datepicker table tr td.selected.disabled,\n.datepicker table tr td.selected.disabled:hover {\n  color: #ffffff;\n  background: rgba(0,0,0,0.2);\n  border-color: #555555;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td.selected:hover,\n.datepicker table tr td.selected:hover:hover,\n.datepicker table tr td.selected.disabled:hover,\n.datepicker table tr td.selected.disabled:hover:hover,\n.datepicker table tr td.selected:focus,\n.datepicker table tr td.selected:hover:focus,\n.datepicker table tr td.selected.disabled:focus,\n.datepicker table tr td.selected.disabled:hover:focus,\n.datepicker table tr td.selected:active,\n.datepicker table tr td.selected:hover:active,\n.datepicker table tr td.selected.disabled:active,\n.datepicker table tr td.selected.disabled:hover:active,\n.datepicker table tr td.selected.active,\n.datepicker table tr td.selected:hover.active,\n.datepicker table tr td.selected.disabled.active,\n.datepicker table tr td.selected.disabled:hover.active,\n.open .dropdown-toggle.datepicker table tr td.selected,\n.open .dropdown-toggle.datepicker table tr td.selected:hover,\n.open .dropdown-toggle.datepicker table tr td.selected.disabled,\n.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {\n  color: #ffffff;\n  background: rgba(0,0,0,0.2);\n  border-color: #373737;\n}\n.datepicker table tr td.selected:active,\n.datepicker table tr td.selected:hover:active,\n.datepicker table tr td.selected.disabled:active,\n.datepicker table tr td.selected.disabled:hover:active,\n.datepicker table tr td.selected.active,\n.datepicker table tr td.selected:hover.active,\n.datepicker table tr td.selected.disabled.active,\n.datepicker table tr td.selected.disabled:hover.active,\n.open .dropdown-toggle.datepicker table tr td.selected,\n.open .dropdown-toggle.datepicker table tr td.selected:hover,\n.open .dropdown-toggle.datepicker table tr td.selected.disabled,\n.open .dropdown-toggle.datepicker table tr td.selected.disabled:hover {\n  background-image: none;\n}\n.datepicker table tr td.selected.disabled,\n.datepicker table tr td.selected:hover.disabled,\n.datepicker table tr td.selected.disabled.disabled,\n.datepicker table tr td.selected.disabled:hover.disabled,\n.datepicker table tr td.selected[disabled],\n.datepicker table tr td.selected:hover[disabled],\n.datepicker table tr td.selected.disabled[disabled],\n.datepicker table tr td.selected.disabled:hover[disabled],\nfieldset[disabled] .datepicker table tr td.selected,\nfieldset[disabled] .datepicker table tr td.selected:hover,\nfieldset[disabled] .datepicker table tr td.selected.disabled,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover,\n.datepicker table tr td.selected.disabled:hover,\n.datepicker table tr td.selected:hover.disabled:hover,\n.datepicker table tr td.selected.disabled.disabled:hover,\n.datepicker table tr td.selected.disabled:hover.disabled:hover,\n.datepicker table tr td.selected[disabled]:hover,\n.datepicker table tr td.selected:hover[disabled]:hover,\n.datepicker table tr td.selected.disabled[disabled]:hover,\n.datepicker table tr td.selected.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.selected:hover,\nfieldset[disabled] .datepicker table tr td.selected:hover:hover,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover:hover,\n.datepicker table tr td.selected.disabled:focus,\n.datepicker table tr td.selected:hover.disabled:focus,\n.datepicker table tr td.selected.disabled.disabled:focus,\n.datepicker table tr td.selected.disabled:hover.disabled:focus,\n.datepicker table tr td.selected[disabled]:focus,\n.datepicker table tr td.selected:hover[disabled]:focus,\n.datepicker table tr td.selected.disabled[disabled]:focus,\n.datepicker table tr td.selected.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.selected:focus,\nfieldset[disabled] .datepicker table tr td.selected:hover:focus,\nfieldset[disabled] .datepicker table tr td.selected.disabled:focus,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover:focus,\n.datepicker table tr td.selected.disabled:active,\n.datepicker table tr td.selected:hover.disabled:active,\n.datepicker table tr td.selected.disabled.disabled:active,\n.datepicker table tr td.selected.disabled:hover.disabled:active,\n.datepicker table tr td.selected[disabled]:active,\n.datepicker table tr td.selected:hover[disabled]:active,\n.datepicker table tr td.selected.disabled[disabled]:active,\n.datepicker table tr td.selected.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td.selected:active,\nfieldset[disabled] .datepicker table tr td.selected:hover:active,\nfieldset[disabled] .datepicker table tr td.selected.disabled:active,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover:active,\n.datepicker table tr td.selected.disabled.active,\n.datepicker table tr td.selected:hover.disabled.active,\n.datepicker table tr td.selected.disabled.disabled.active,\n.datepicker table tr td.selected.disabled:hover.disabled.active,\n.datepicker table tr td.selected[disabled].active,\n.datepicker table tr td.selected:hover[disabled].active,\n.datepicker table tr td.selected.disabled[disabled].active,\n.datepicker table tr td.selected.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td.selected.active,\nfieldset[disabled] .datepicker table tr td.selected:hover.active,\nfieldset[disabled] .datepicker table tr td.selected.disabled.active,\nfieldset[disabled] .datepicker table tr td.selected.disabled:hover.active {\n  background: rgba(0,0,0,0.2);\n  border-color: #555555;\n}\n.datepicker table tr td.active,\n.datepicker table tr td.active:hover,\n.datepicker table tr td.active.disabled,\n.datepicker table tr td.active.disabled:hover {\n  color: #ffffff;\n  background: rgba(0,0,0,0.2);\n  border-color: #357ebd;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td.active:hover,\n.datepicker table tr td.active:hover:hover,\n.datepicker table tr td.active.disabled:hover,\n.datepicker table tr td.active.disabled:hover:hover,\n.datepicker table tr td.active:focus,\n.datepicker table tr td.active:hover:focus,\n.datepicker table tr td.active.disabled:focus,\n.datepicker table tr td.active.disabled:hover:focus,\n.datepicker table tr td.active:active,\n.datepicker table tr td.active:hover:active,\n.datepicker table tr td.active.disabled:active,\n.datepicker table tr td.active.disabled:hover:active,\n.datepicker table tr td.active.active,\n.datepicker table tr td.active:hover.active,\n.datepicker table tr td.active.disabled.active,\n.datepicker table tr td.active.disabled:hover.active,\n.open .dropdown-toggle.datepicker table tr td.active,\n.open .dropdown-toggle.datepicker table tr td.active:hover,\n.open .dropdown-toggle.datepicker table tr td.active.disabled,\n.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {\n  color: #ffffff;\n  background: rgba(0,0,0,0.5);\n  border-color: #285e8e;\n}\n.datepicker table tr td.active:active,\n.datepicker table tr td.active:hover:active,\n.datepicker table tr td.active.disabled:active,\n.datepicker table tr td.active.disabled:hover:active,\n.datepicker table tr td.active.active,\n.datepicker table tr td.active:hover.active,\n.datepicker table tr td.active.disabled.active,\n.datepicker table tr td.active.disabled:hover.active,\n.open .dropdown-toggle.datepicker table tr td.active,\n.open .dropdown-toggle.datepicker table tr td.active:hover,\n.open .dropdown-toggle.datepicker table tr td.active.disabled,\n.open .dropdown-toggle.datepicker table tr td.active.disabled:hover {\n  background-image: none;\n}\n.datepicker table tr td.active.disabled,\n.datepicker table tr td.active:hover.disabled,\n.datepicker table tr td.active.disabled.disabled,\n.datepicker table tr td.active.disabled:hover.disabled,\n.datepicker table tr td.active[disabled],\n.datepicker table tr td.active:hover[disabled],\n.datepicker table tr td.active.disabled[disabled],\n.datepicker table tr td.active.disabled:hover[disabled],\nfieldset[disabled] .datepicker table tr td.active,\nfieldset[disabled] .datepicker table tr td.active:hover,\nfieldset[disabled] .datepicker table tr td.active.disabled,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover,\n.datepicker table tr td.active.disabled:hover,\n.datepicker table tr td.active:hover.disabled:hover,\n.datepicker table tr td.active.disabled.disabled:hover,\n.datepicker table tr td.active.disabled:hover.disabled:hover,\n.datepicker table tr td.active[disabled]:hover,\n.datepicker table tr td.active:hover[disabled]:hover,\n.datepicker table tr td.active.disabled[disabled]:hover,\n.datepicker table tr td.active.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td.active:hover,\nfieldset[disabled] .datepicker table tr td.active:hover:hover,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover:hover,\n.datepicker table tr td.active.disabled:focus,\n.datepicker table tr td.active:hover.disabled:focus,\n.datepicker table tr td.active.disabled.disabled:focus,\n.datepicker table tr td.active.disabled:hover.disabled:focus,\n.datepicker table tr td.active[disabled]:focus,\n.datepicker table tr td.active:hover[disabled]:focus,\n.datepicker table tr td.active.disabled[disabled]:focus,\n.datepicker table tr td.active.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td.active:focus,\nfieldset[disabled] .datepicker table tr td.active:hover:focus,\nfieldset[disabled] .datepicker table tr td.active.disabled:focus,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover:focus,\n.datepicker table tr td.active.disabled:active,\n.datepicker table tr td.active:hover.disabled:active,\n.datepicker table tr td.active.disabled.disabled:active,\n.datepicker table tr td.active.disabled:hover.disabled:active,\n.datepicker table tr td.active[disabled]:active,\n.datepicker table tr td.active:hover[disabled]:active,\n.datepicker table tr td.active.disabled[disabled]:active,\n.datepicker table tr td.active.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td.active:active,\nfieldset[disabled] .datepicker table tr td.active:hover:active,\nfieldset[disabled] .datepicker table tr td.active.disabled:active,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover:active,\n.datepicker table tr td.active.disabled.active,\n.datepicker table tr td.active:hover.disabled.active,\n.datepicker table tr td.active.disabled.disabled.active,\n.datepicker table tr td.active.disabled:hover.disabled.active,\n.datepicker table tr td.active[disabled].active,\n.datepicker table tr td.active:hover[disabled].active,\n.datepicker table tr td.active.disabled[disabled].active,\n.datepicker table tr td.active.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td.active.active,\nfieldset[disabled] .datepicker table tr td.active:hover.active,\nfieldset[disabled] .datepicker table tr td.active.disabled.active,\nfieldset[disabled] .datepicker table tr td.active.disabled:hover.active {\n  background-color: #428bca;\n  border-color: #357ebd;\n}\n.datepicker table tr td span {\n  display: block;\n  width: 23%;\n  height: 54px;\n  line-height: 54px;\n  float: left;\n  margin: 1%;\n  cursor: pointer;\n  border-radius: 4px;\n}\n.datepicker table tr td span:hover {\n  background: rgba(0,0,0,0.2);\n}\n.datepicker table tr td span.disabled,\n.datepicker table tr td span.disabled:hover {\n  background: none;\n  color: #444;\n  cursor: default;\n}\n.datepicker table tr td span.active,\n.datepicker table tr td span.active:hover,\n.datepicker table tr td span.active.disabled,\n.datepicker table tr td span.active.disabled:hover {\n  color: #ffffff;\n  background-color: #428bca;\n  border-color: #357ebd;\n  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);\n}\n.datepicker table tr td span.active:hover,\n.datepicker table tr td span.active:hover:hover,\n.datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active.disabled:hover:hover,\n.datepicker table tr td span.active:focus,\n.datepicker table tr td span.active:hover:focus,\n.datepicker table tr td span.active.disabled:focus,\n.datepicker table tr td span.active.disabled:hover:focus,\n.datepicker table tr td span.active:active,\n.datepicker table tr td span.active:hover:active,\n.datepicker table tr td span.active.disabled:active,\n.datepicker table tr td span.active.disabled:hover:active,\n.datepicker table tr td span.active.active,\n.datepicker table tr td span.active:hover.active,\n.datepicker table tr td span.active.disabled.active,\n.datepicker table tr td span.active.disabled:hover.active,\n.open .dropdown-toggle.datepicker table tr td span.active,\n.open .dropdown-toggle.datepicker table tr td span.active:hover,\n.open .dropdown-toggle.datepicker table tr td span.active.disabled,\n.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {\n  color: #ffffff;\n  background-color: #3276b1;\n  border-color: #285e8e;\n}\n.datepicker table tr td span.active:active,\n.datepicker table tr td span.active:hover:active,\n.datepicker table tr td span.active.disabled:active,\n.datepicker table tr td span.active.disabled:hover:active,\n.datepicker table tr td span.active.active,\n.datepicker table tr td span.active:hover.active,\n.datepicker table tr td span.active.disabled.active,\n.datepicker table tr td span.active.disabled:hover.active,\n.open .dropdown-toggle.datepicker table tr td span.active,\n.open .dropdown-toggle.datepicker table tr td span.active:hover,\n.open .dropdown-toggle.datepicker table tr td span.active.disabled,\n.open .dropdown-toggle.datepicker table tr td span.active.disabled:hover {\n  background-image: none;\n}\n.datepicker table tr td span.active.disabled,\n.datepicker table tr td span.active:hover.disabled,\n.datepicker table tr td span.active.disabled.disabled,\n.datepicker table tr td span.active.disabled:hover.disabled,\n.datepicker table tr td span.active[disabled],\n.datepicker table tr td span.active:hover[disabled],\n.datepicker table tr td span.active.disabled[disabled],\n.datepicker table tr td span.active.disabled:hover[disabled],\nfieldset[disabled] .datepicker table tr td span.active,\nfieldset[disabled] .datepicker table tr td span.active:hover,\nfieldset[disabled] .datepicker table tr td span.active.disabled,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active.disabled:hover,\n.datepicker table tr td span.active:hover.disabled:hover,\n.datepicker table tr td span.active.disabled.disabled:hover,\n.datepicker table tr td span.active.disabled:hover.disabled:hover,\n.datepicker table tr td span.active[disabled]:hover,\n.datepicker table tr td span.active:hover[disabled]:hover,\n.datepicker table tr td span.active.disabled[disabled]:hover,\n.datepicker table tr td span.active.disabled:hover[disabled]:hover,\nfieldset[disabled] .datepicker table tr td span.active:hover,\nfieldset[disabled] .datepicker table tr td span.active:hover:hover,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover:hover,\n.datepicker table tr td span.active.disabled:focus,\n.datepicker table tr td span.active:hover.disabled:focus,\n.datepicker table tr td span.active.disabled.disabled:focus,\n.datepicker table tr td span.active.disabled:hover.disabled:focus,\n.datepicker table tr td span.active[disabled]:focus,\n.datepicker table tr td span.active:hover[disabled]:focus,\n.datepicker table tr td span.active.disabled[disabled]:focus,\n.datepicker table tr td span.active.disabled:hover[disabled]:focus,\nfieldset[disabled] .datepicker table tr td span.active:focus,\nfieldset[disabled] .datepicker table tr td span.active:hover:focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled:focus,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover:focus,\n.datepicker table tr td span.active.disabled:active,\n.datepicker table tr td span.active:hover.disabled:active,\n.datepicker table tr td span.active.disabled.disabled:active,\n.datepicker table tr td span.active.disabled:hover.disabled:active,\n.datepicker table tr td span.active[disabled]:active,\n.datepicker table tr td span.active:hover[disabled]:active,\n.datepicker table tr td span.active.disabled[disabled]:active,\n.datepicker table tr td span.active.disabled:hover[disabled]:active,\nfieldset[disabled] .datepicker table tr td span.active:active,\nfieldset[disabled] .datepicker table tr td span.active:hover:active,\nfieldset[disabled] .datepicker table tr td span.active.disabled:active,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover:active,\n.datepicker table tr td span.active.disabled.active,\n.datepicker table tr td span.active:hover.disabled.active,\n.datepicker table tr td span.active.disabled.disabled.active,\n.datepicker table tr td span.active.disabled:hover.disabled.active,\n.datepicker table tr td span.active[disabled].active,\n.datepicker table tr td span.active:hover[disabled].active,\n.datepicker table tr td span.active.disabled[disabled].active,\n.datepicker table tr td span.active.disabled:hover[disabled].active,\nfieldset[disabled] .datepicker table tr td span.active.active,\nfieldset[disabled] .datepicker table tr td span.active:hover.active,\nfieldset[disabled] .datepicker table tr td span.active.disabled.active,\nfieldset[disabled] .datepicker table tr td span.active.disabled:hover.active {\n  background-color: #428bca;\n  border-color: #357ebd;\n}\n.datepicker table tr td span.old,\n.datepicker table tr td span.new {\n  color: #444;\n}\n.datepicker th.datepicker-switch {\n  width: 145px;\n}\n.datepicker thead tr:first-child th,\n.datepicker tfoot tr th {\n  cursor: pointer;\n}\n.datepicker thead tr:first-child th:hover,\n.datepicker tfoot tr th:hover {\n  background: rgba(0,0,0,0.2);\n}\n.datepicker .cw {\n  font-size: 10px;\n  width: 12px;\n  padding: 0 2px 0 5px;\n  vertical-align: middle;\n}\n.datepicker thead tr:first-child th.cw {\n  cursor: default;\n  background-color: transparent;\n}\n.input-group.date .input-group-addon i {\n  cursor: pointer;\n  width: 16px;\n  height: 16px;\n}\n.input-daterange input {\n  text-align: center;\n}\n.input-daterange input:first-child {\n  border-radius: 3px 0 0 3px;\n}\n.input-daterange input:last-child {\n  border-radius: 0 3px 3px 0;\n}\n.input-daterange .input-group-addon {\n  width: auto;\n  min-width: 16px;\n  padding: 4px 5px;\n  font-weight: normal;\n  line-height: 1.428571429;\n  text-align: center;\n  text-shadow: 0 1px 0 #fff;\n  vertical-align: middle;\n  background-color: #eeeeee;\n  border: solid #cccccc;\n  border-width: 1px 0;\n  margin-left: -5px;\n  margin-right: -5px;\n}\n.datepicker.dropdown-menu {\n  position: absolute;\n  top: 100%;\n  left: 0;\n  z-index: 1000;\n  float: left;\n  display: none;\n  min-width: 160px;\n  list-style: none;\n  background-color: #ffffff;\n  border: 1px solid #ccc;\n  border: 1px solid rgba(0, 0, 0, 0.2);\n  border-radius: 5px;\n  -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\n  -webkit-background-clip: padding-box;\n  -moz-background-clip: padding;\n  background-clip: padding-box;\n  *border-right-width: 2px;\n  *border-bottom-width: 2px;\n  color: #333333;\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\n  font-size: 13px;\n  line-height: 1.428571429;\n}\n.datepicker.dropdown-menu th,\n.datepicker.dropdown-menu td {\n  padding: 4px 5px;\n}\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.ar.js",
    "content": "/**\n * Arabic translation for bootstrap-datepicker\n * Mohammed Alshehri <alshehri866@gmail.com>\n */\n;(function($){\n    $.fn.datepicker.dates['ar'] = {\n        days: [\"الأحد\", \"الاثنين\", \"الثلاثاء\", \"الأربعاء\", \"الخميس\", \"الجمعة\", \"السبت\", \"الأحد\"],\n        daysShort: [\"أحد\", \"اثنين\", \"ثلاثاء\", \"أربعاء\", \"خميس\", \"جمعة\", \"سبت\", \"أحد\"],\n        daysMin: [\"ح\", \"ن\", \"ث\", \"ع\", \"خ\", \"ج\", \"س\", \"ح\"],\n        months: [\"يناير\", \"فبراير\", \"مارس\", \"أبريل\", \"مايو\", \"يونيو\", \"يوليو\", \"أغسطس\", \"سبتمبر\", \"أكتوبر\", \"نوفمبر\", \"ديسمبر\"],\n        monthsShort: [\"يناير\", \"فبراير\", \"مارس\", \"أبريل\", \"مايو\", \"يونيو\", \"يوليو\", \"أغسطس\", \"سبتمبر\", \"أكتوبر\", \"نوفمبر\", \"ديسمبر\"],\n        today: \"هذا اليوم\",\n        rtl: true\n    };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.az.js",
    "content": "// Azerbaijani\n;(function($){\n    $.fn.datepicker.dates['az'] = {\n        days: [\"Bazar\", \"Bazar ertəsi\", \"Çərşənbə axşamı\", \"Çərşənbə\", \"Cümə axşamı\", \"Cümə\", \"Şənbə\", \"Bazar\"],\n        daysShort: [\"B.\", \"B.e\", \"Ç.a\", \"Ç.\", \"C.a\", \"C.\", \"Ş.\", \"B.\"],\n        daysMin: [\"B.\", \"B.e\", \"Ç.a\", \"Ç.\", \"C.a\", \"C.\", \"Ş.\", \"B.\"],\n        months: [\"Yanvar\", \"Fevral\", \"Mart\", \"Aprel\", \"May\", \"İyun\", \"İyul\", \"Avqust\", \"Sentyabr\", \"Oktyabr\", \"Noyabr\", \"Dekabr\"],\n        monthsShort: [\"Yan\", \"Fev\", \"Mar\", \"Apr\", \"May\", \"İyun\", \"İyul\", \"Avq\", \"Sen\", \"Okt\", \"Noy\", \"Dek\"],\n        today: \"Bu gün\",\n        weekStart: 1\n    };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.bg.js",
    "content": "/**\n * Bulgarian translation for bootstrap-datepicker\n * Apostol Apostolov <apostol.s.apostolov@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['bg'] = {\n\t\tdays: [\"Неделя\", \"Понеделник\", \"Вторник\", \"Сряда\", \"Четвъртък\", \"Петък\", \"Събота\", \"Неделя\"],\n\t\tdaysShort: [\"Нед\", \"Пон\", \"Вто\", \"Сря\", \"Чет\", \"Пет\", \"Съб\", \"Нед\"],\n\t\tdaysMin: [\"Н\", \"П\", \"В\", \"С\", \"Ч\", \"П\", \"С\", \"Н\"],\n\t\tmonths: [\"Януари\", \"Февруари\", \"Март\", \"Април\", \"Май\", \"Юни\", \"Юли\", \"Август\", \"Септември\", \"Октомври\", \"Ноември\", \"Декември\"],\n\t\tmonthsShort: [\"Ян\", \"Фев\", \"Мар\", \"Апр\", \"Май\", \"Юни\", \"Юли\", \"Авг\", \"Сеп\", \"Окт\", \"Ное\", \"Дек\"],\n\t\ttoday: \"днес\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.ca.js",
    "content": "/**\n * Catalan translation for bootstrap-datepicker\n * J. Garcia <jogaco.en@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['ca'] = {\n\t\tdays: [\"Diumenge\", \"Dilluns\", \"Dimarts\", \"Dimecres\", \"Dijous\", \"Divendres\", \"Dissabte\", \"Diumenge\"],\n\t\tdaysShort: [\"Diu\",  \"Dil\", \"Dmt\", \"Dmc\", \"Dij\", \"Div\", \"Dis\", \"Diu\"],\n\t\tdaysMin: [\"dg\", \"dl\", \"dt\", \"dc\", \"dj\", \"dv\", \"ds\", \"dg\"],\n\t\tmonths: [\"Gener\", \"Febrer\", \"Març\", \"Abril\", \"Maig\", \"Juny\", \"Juliol\", \"Agost\", \"Setembre\", \"Octubre\", \"Novembre\", \"Desembre\"],\n\t\tmonthsShort: [\"Gen\", \"Feb\", \"Mar\", \"Abr\", \"Mai\", \"Jun\", \"Jul\", \"Ago\", \"Set\", \"Oct\", \"Nov\", \"Des\"],\n\t\ttoday: \"Avui\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.cs.js",
    "content": "/**\n * Czech translation for bootstrap-datepicker\n * Matěj Koubík <matej@koubik.name>\n * Fixes by Michal Remiš <michal.remis@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['cs'] = {\n\t\tdays: [\"Neděle\", \"Pondělí\", \"Úterý\", \"Středa\", \"Čtvrtek\", \"Pátek\", \"Sobota\", \"Neděle\"],\n\t\tdaysShort: [\"Ned\", \"Pon\", \"Úte\", \"Stř\", \"Čtv\", \"Pát\", \"Sob\", \"Ned\"],\n\t\tdaysMin: [\"Ne\", \"Po\", \"Út\", \"St\", \"Čt\", \"Pá\", \"So\", \"Ne\"],\n\t\tmonths: [\"Leden\", \"Únor\", \"Březen\", \"Duben\", \"Květen\", \"Červen\", \"Červenec\", \"Srpen\", \"Září\", \"Říjen\", \"Listopad\", \"Prosinec\"],\n\t\tmonthsShort: [\"Led\", \"Úno\", \"Bře\", \"Dub\", \"Kvě\", \"Čer\", \"Čnc\", \"Srp\", \"Zář\", \"Říj\", \"Lis\", \"Pro\"],\n\t\ttoday: \"Dnes\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.cy.js",
    "content": "/**\n * Welsh translation for bootstrap-datepicker\n * S. Morris <s.morris@bangor.ac.uk>\n */\n;(function($){\n\t$.fn.datepicker.dates['cy'] = {\n\t\tdays: [\"Sul\", \"Llun\", \"Mawrth\", \"Mercher\", \"Iau\", \"Gwener\", \"Sadwrn\", \"Sul\"],\n\t\tdaysShort: [\"Sul\", \"Llu\", \"Maw\", \"Mer\", \"Iau\", \"Gwe\", \"Sad\", \"Sul\"],\n\t\tdaysMin: [\"Su\", \"Ll\", \"Ma\", \"Me\", \"Ia\", \"Gwe\", \"Sa\", \"Su\"],\n\t\tmonths: [\"Ionawr\", \"Chewfror\", \"Mawrth\", \"Ebrill\", \"Mai\", \"Mehefin\", \"Gorfennaf\", \"Awst\", \"Medi\", \"Hydref\", \"Tachwedd\", \"Rhagfyr\"],\n\t\tmonthsShort: [\"Ion\", \"Chw\", \"Maw\", \"Ebr\", \"Mai\", \"Meh\", \"Gor\", \"Aws\", \"Med\", \"Hyd\", \"Tach\", \"Rha\"],\n\t\ttoday: \"Heddiw\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.da.js",
    "content": "/**\n * Danish translation for bootstrap-datepicker\n * Christian Pedersen <http://github.com/chripede>\n */\n;(function($){\n\t$.fn.datepicker.dates['da'] = {\n\t\tdays: [\"Søndag\", \"Mandag\", \"Tirsdag\", \"Onsdag\", \"Torsdag\", \"Fredag\", \"Lørdag\", \"Søndag\"],\n\t\tdaysShort: [\"Søn\", \"Man\", \"Tir\", \"Ons\", \"Tor\", \"Fre\", \"Lør\", \"Søn\"],\n\t\tdaysMin: [\"Sø\", \"Ma\", \"Ti\", \"On\", \"To\", \"Fr\", \"Lø\", \"Sø\"],\n\t\tmonths: [\"Januar\", \"Februar\", \"Marts\", \"April\", \"Maj\", \"Juni\", \"Juli\", \"August\", \"September\", \"Oktober\", \"November\", \"December\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Maj\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"I Dag\",\n\t\tclear: \"Nulstil\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.de.js",
    "content": "/**\n * German translation for bootstrap-datepicker\n * Sam Zurcher <sam@orelias.ch>\n */\n;(function($){\n\t$.fn.datepicker.dates['de'] = {\n\t\tdays: [\"Sonntag\", \"Montag\", \"Dienstag\", \"Mittwoch\", \"Donnerstag\", \"Freitag\", \"Samstag\", \"Sonntag\"],\n\t\tdaysShort: [\"Son\", \"Mon\", \"Die\", \"Mit\", \"Don\", \"Fre\", \"Sam\", \"Son\"],\n\t\tdaysMin: [\"So\", \"Mo\", \"Di\", \"Mi\", \"Do\", \"Fr\", \"Sa\", \"So\"],\n\t\tmonths: [\"Januar\", \"Februar\", \"März\", \"April\", \"Mai\", \"Juni\", \"Juli\", \"August\", \"September\", \"Oktober\", \"November\", \"Dezember\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mär\", \"Apr\", \"Mai\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dez\"],\n\t\ttoday: \"Heute\",\n\t\tclear: \"Löschen\",\n\t\tweekStart: 1,\n\t\tformat: \"dd.mm.yyyy\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.el.js",
    "content": "/**\n * Greek translation for bootstrap-datepicker\n */\n;(function($){\n  $.fn.datepicker.dates['el'] = {\n    days: [\"Κυριακή\", \"Δευτέρα\", \"Τρίτη\", \"Τετάρτη\", \"Πέμπτη\", \"Παρασκευή\", \"Σάββατο\", \"Κυριακή\"],\n    daysShort: [\"Κυρ\", \"Δευ\", \"Τρι\", \"Τετ\", \"Πεμ\", \"Παρ\", \"Σαβ\", \"Κυρ\"],\n    daysMin: [\"Κυ\", \"Δε\", \"Τρ\", \"Τε\", \"Πε\", \"Πα\", \"Σα\", \"Κυ\"],\n    months: [\"Ιανουάριος\", \"Φεβρουάριος\", \"Μάρτιος\", \"Απρίλιος\", \"Μάιος\", \"Ιούνιος\", \"Ιούλιος\", \"Αύγουστος\", \"Σεπτέμβριος\", \"Οκτώβριος\", \"Νοέμβριος\", \"Δεκέμβριος\"],\n    monthsShort: [\"Ιαν\", \"Φεβ\", \"Μαρ\", \"Απρ\", \"Μάι\", \"Ιουν\", \"Ιουλ\", \"Αυγ\", \"Σεπ\", \"Οκτ\", \"Νοε\", \"Δεκ\"],\n    today: \"Σήμερα\"\n  };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.es.js",
    "content": "/**\n * Spanish translation for bootstrap-datepicker\n * Bruno Bonamin <bruno.bonamin@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['es'] = {\n\t\tdays: [\"Domingo\", \"Lunes\", \"Martes\", \"Miércoles\", \"Jueves\", \"Viernes\", \"Sábado\", \"Domingo\"],\n\t\tdaysShort: [\"Dom\", \"Lun\", \"Mar\", \"Mié\", \"Jue\", \"Vie\", \"Sáb\", \"Dom\"],\n\t\tdaysMin: [\"Do\", \"Lu\", \"Ma\", \"Mi\", \"Ju\", \"Vi\", \"Sa\", \"Do\"],\n\t\tmonths: [\"Enero\", \"Febrero\", \"Marzo\", \"Abril\", \"Mayo\", \"Junio\", \"Julio\", \"Agosto\", \"Septiembre\", \"Octubre\", \"Noviembre\", \"Diciembre\"],\n\t\tmonthsShort: [\"Ene\", \"Feb\", \"Mar\", \"Abr\", \"May\", \"Jun\", \"Jul\", \"Ago\", \"Sep\", \"Oct\", \"Nov\", \"Dic\"],\n\t\ttoday: \"Hoy\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.et.js",
    "content": "/**\n * Estonian translation for bootstrap-datepicker\n * Ando Roots <https://github.com/anroots>\n * Fixes by Illimar Tambek <<https://github.com/ragulka>\n */\n;(function($){\n\t$.fn.datepicker.dates['et'] = {\n\t\tdays: [\"Pühapäev\", \"Esmaspäev\", \"Teisipäev\", \"Kolmapäev\", \"Neljapäev\", \"Reede\", \"Laupäev\", \"Pühapäev\"],\n\t\tdaysShort: [\"Pühap\", \"Esmasp\", \"Teisip\", \"Kolmap\", \"Neljap\", \"Reede\", \"Laup\", \"Pühap\"],\n\t\tdaysMin: [\"P\", \"E\", \"T\", \"K\", \"N\", \"R\", \"L\", \"P\"],\n\t\tmonths: [\"Jaanuar\", \"Veebruar\", \"Märts\", \"Aprill\", \"Mai\", \"Juuni\", \"Juuli\", \"August\", \"September\", \"Oktoober\", \"November\", \"Detsember\"],\n\t\tmonthsShort: [\"Jaan\", \"Veebr\", \"Märts\", \"Apr\", \"Mai\", \"Juuni\", \"Juuli\", \"Aug\", \"Sept\", \"Okt\", \"Nov\", \"Dets\"],\n\t\ttoday: \"Täna\",\n\t\tclear: \"Tühjenda\",\n\t\tweekStart: 1,\n\t\tformat: \"dd.mm.yyyy\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.fa.js",
    "content": "/**\n * Persian translation for bootstrap-datepicker\n * Mostafa Rokooie <mostafa.rokooie@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['fa'] = {\n\t\tdays: [\"یک‌شنبه\", \"دوشنبه\", \"سه‌شنبه\", \"چهارشنبه\", \"پنج‌شنبه\", \"جمعه\", \"شنبه\", \"یک‌شنبه\"],\n\t\tdaysShort: [\"یک\", \"دو\", \"سه\", \"چهار\", \"پنج\", \"جمعه\", \"شنبه\", \"یک\"],\n\t\tdaysMin: [\"ی\", \"د\", \"س\", \"چ\", \"پ\", \"ج\", \"ش\", \"ی\"],\n\t\tmonths: [\"ژانویه\", \"فوریه\", \"مارس\", \"آوریل\", \"مه\", \"ژوئن\", \"ژوئیه\", \"اوت\", \"سپتامبر\", \"اکتبر\", \"نوامبر\", \"دسامبر\"],\n\t\tmonthsShort: [\"ژان\", \"فور\", \"مار\", \"آور\", \"مه\", \"ژون\", \"ژوی\", \"اوت\", \"سپت\", \"اکت\", \"نوا\", \"دسا\"],\n\t\ttoday: \"امروز\",\n\t\tclear: \"پاک کن\",\n\t\tweekStart: 1,\n\t\tformat: \"yyyy/mm/dd\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.fi.js",
    "content": "/**\n * Finnish translation for bootstrap-datepicker\n * Jaakko Salonen <https://github.com/jsalonen>\n */\n;(function($){\n\t$.fn.datepicker.dates['fi'] = {\n\t\tdays: [\"sunnuntai\", \"maanantai\", \"tiistai\", \"keskiviikko\", \"torstai\", \"perjantai\", \"lauantai\", \"sunnuntai\"],\n\t\tdaysShort: [\"sun\", \"maa\", \"tii\", \"kes\", \"tor\", \"per\", \"lau\", \"sun\"],\n\t\tdaysMin: [\"su\", \"ma\", \"ti\", \"ke\", \"to\", \"pe\", \"la\", \"su\"],\n\t\tmonths: [\"tammikuu\", \"helmikuu\", \"maaliskuu\", \"huhtikuu\", \"toukokuu\", \"kesäkuu\", \"heinäkuu\", \"elokuu\", \"syyskuu\", \"lokakuu\", \"marraskuu\", \"joulukuu\"],\n\t\tmonthsShort: [\"tam\", \"hel\", \"maa\", \"huh\", \"tou\", \"kes\", \"hei\", \"elo\", \"syy\", \"lok\", \"mar\", \"jou\"],\n\t\ttoday: \"tänään\",\n\t\tweekStart: 1,\n\t\tformat: \"d.m.yyyy\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.fr.js",
    "content": "/**\n * French translation for bootstrap-datepicker\n * Nico Mollet <nico.mollet@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['fr'] = {\n\t\tdays: [\"Dimanche\", \"Lundi\", \"Mardi\", \"Mercredi\", \"Jeudi\", \"Vendredi\", \"Samedi\", \"Dimanche\"],\n\t\tdaysShort: [\"Dim\", \"Lun\", \"Mar\", \"Mer\", \"Jeu\", \"Ven\", \"Sam\", \"Dim\"],\n\t\tdaysMin: [\"D\", \"L\", \"Ma\", \"Me\", \"J\", \"V\", \"S\", \"D\"],\n\t\tmonths: [\"Janvier\", \"Février\", \"Mars\", \"Avril\", \"Mai\", \"Juin\", \"Juillet\", \"Août\", \"Septembre\", \"Octobre\", \"Novembre\", \"Décembre\"],\n\t\tmonthsShort: [\"Jan\", \"Fév\", \"Mar\", \"Avr\", \"Mai\", \"Jui\", \"Jul\", \"Aou\", \"Sep\", \"Oct\", \"Nov\", \"Déc\"],\n\t\ttoday: \"Aujourd'hui\",\n\t\tclear: \"Effacer\",\n\t\tweekStart: 1,\n\t\tformat: \"dd/mm/yyyy\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.gl.js",
    "content": ";(function($){\n\t$.fn.datepicker.dates['gl'] = {\n\t\tdays: [\"Domingo\", \"Luns\", \"Martes\", \"Mércores\", \"Xoves\", \"Venres\", \"Sábado\", \"Domingo\"],\n\t\tdaysShort: [\"Dom\", \"Lun\", \"Mar\", \"Mér\", \"Xov\", \"Ven\", \"Sáb\", \"Dom\"],\n\t\tdaysMin: [\"Do\", \"Lu\", \"Ma\", \"Me\", \"Xo\", \"Ve\", \"Sa\", \"Do\"],\n\t\tmonths: [\"Xaneiro\", \"Febreiro\", \"Marzo\", \"Abril\", \"Maio\", \"Xuño\", \"Xullo\", \"Agosto\", \"Setembro\", \"Outubro\", \"Novembro\", \"Decembro\"],\n\t\tmonthsShort: [\"Xan\", \"Feb\", \"Mar\", \"Abr\", \"Mai\", \"Xun\", \"Xul\", \"Ago\", \"Sep\", \"Out\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Hoxe\",\n\t\tclear: \"Limpar\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.he.js",
    "content": "/**\n * Hebrew translation for bootstrap-datepicker\n * Sagie Maoz <sagie@maoz.info>\n */\n;(function($){\n  $.fn.datepicker.dates['he'] = {\n      days: [\"ראשון\", \"שני\", \"שלישי\", \"רביעי\", \"חמישי\", \"שישי\", \"שבת\", \"ראשון\"],\n      daysShort: [\"א\", \"ב\", \"ג\", \"ד\", \"ה\", \"ו\", \"ש\", \"א\"],\n      daysMin: [\"א\", \"ב\", \"ג\", \"ד\", \"ה\", \"ו\", \"ש\", \"א\"],\n      months: [\"ינואר\", \"פברואר\", \"מרץ\", \"אפריל\", \"מאי\", \"יוני\", \"יולי\", \"אוגוסט\", \"ספטמבר\", \"אוקטובר\", \"נובמבר\", \"דצמבר\"],\n      monthsShort: [\"ינו\", \"פבר\", \"מרץ\", \"אפר\", \"מאי\", \"יונ\", \"יול\", \"אוג\", \"ספט\", \"אוק\", \"נוב\", \"דצמ\"],\n      today: \"היום\",\n      rtl: true\n  };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.hr.js",
    "content": "/**\n * Croatian localisation\n */\n;(function($){\n\t$.fn.datepicker.dates['hr'] = {\n\t\tdays: [\"Nedjelja\", \"Ponedjeljak\", \"Utorak\", \"Srijeda\", \"Četvrtak\", \"Petak\", \"Subota\", \"Nedjelja\"],\n\t\tdaysShort: [\"Ned\", \"Pon\", \"Uto\", \"Sri\", \"Čet\", \"Pet\", \"Sub\", \"Ned\"],\n\t\tdaysMin: [\"Ne\", \"Po\", \"Ut\", \"Sr\", \"Če\", \"Pe\", \"Su\", \"Ne\"],\n\t\tmonths: [\"Siječanj\", \"Veljača\", \"Ožujak\", \"Travanj\", \"Svibanj\", \"Lipanj\", \"Srpanj\", \"Kolovoz\", \"Rujan\", \"Listopad\", \"Studeni\", \"Prosinac\"],\n\t\tmonthsShort: [\"Sij\", \"Velj\", \"Ožu\", \"Tra\", \"Svi\", \"Lip\", \"Srp\", \"Kol\", \"Ruj\", \"Lis\", \"Stu\", \"Pro\"],\n\t\ttoday: \"Danas\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.hu.js",
    "content": "/**\n * Hungarian translation for bootstrap-datepicker\n * Sotus László <lacisan@gmail.com>\n */\n;(function($){\n  $.fn.datepicker.dates['hu'] = {\n\t\tdays: [\"Vasárnap\", \"Hétfő\", \"Kedd\", \"Szerda\", \"Csütörtök\", \"Péntek\", \"Szombat\", \"Vasárnap\"],\n\t\tdaysShort: [\"Vas\", \"Hét\", \"Ked\", \"Sze\", \"Csü\", \"Pén\", \"Szo\", \"Vas\"],\n\t\tdaysMin: [\"Va\", \"Hé\", \"Ke\", \"Sz\", \"Cs\", \"Pé\", \"Sz\", \"Va\"],\n\t\tmonths: [\"Január\", \"Február\", \"Március\", \"Április\", \"Május\", \"Június\", \"Július\", \"Augusztus\", \"Szeptember\", \"Október\", \"November\", \"December\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Már\", \"Ápr\", \"Máj\", \"Jún\", \"Júl\", \"Aug\", \"Sze\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Ma\",\n\t\tweekStart: 1,\n\t\tformat: \"yyyy.mm.dd\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.id.js",
    "content": "/**\n * Bahasa translation for bootstrap-datepicker\n * Azwar Akbar <azwar.akbar@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['id'] = {\n\t\tdays: [\"Minggu\", \"Senin\", \"Selasa\", \"Rabu\", \"Kamis\", \"Jumat\", \"Sabtu\", \"Minggu\"],\n\t\tdaysShort: [\"Mgu\", \"Sen\", \"Sel\", \"Rab\", \"Kam\", \"Jum\", \"Sab\", \"Mgu\"],\n\t\tdaysMin: [\"Mg\", \"Sn\", \"Sl\", \"Ra\", \"Ka\", \"Ju\", \"Sa\", \"Mg\"],\n\t\tmonths: [\"Januari\", \"Februari\", \"Maret\", \"April\", \"Mei\", \"Juni\", \"Juli\", \"Agustus\", \"September\", \"Oktober\", \"November\", \"Desember\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Mei\", \"Jun\", \"Jul\", \"Ags\", \"Sep\", \"Okt\", \"Nov\", \"Des\"],\n\t\ttoday: \"Hari Ini\",\n\t\tclear: \"Kosongkan\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.is.js",
    "content": "/**\n * Icelandic translation for bootstrap-datepicker\n * Hinrik Örn Sigurðsson <hinrik.sig@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['is'] = {\n\t\tdays: [\"Sunnudagur\", \"Mánudagur\", \"Þriðjudagur\", \"Miðvikudagur\", \"Fimmtudagur\", \"Föstudagur\", \"Laugardagur\", \"Sunnudagur\"],\n\t\tdaysShort: [\"Sun\", \"Mán\", \"Þri\", \"Mið\", \"Fim\", \"Fös\", \"Lau\", \"Sun\"],\n\t\tdaysMin: [\"Su\", \"Má\", \"Þr\", \"Mi\", \"Fi\", \"Fö\", \"La\", \"Su\"],\n\t\tmonths: [\"Janúar\", \"Febrúar\", \"Mars\", \"Apríl\", \"Maí\", \"Júní\", \"Júlí\", \"Ágúst\", \"September\", \"Október\", \"Nóvember\", \"Desember\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Maí\", \"Jún\", \"Júl\", \"Ágú\", \"Sep\", \"Okt\", \"Nóv\", \"Des\"],\n\t\ttoday: \"Í Dag\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.it.js",
    "content": "/**\n * Italian translation for bootstrap-datepicker\n * Enrico Rubboli <rubboli@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['it'] = {\n\t\tdays: [\"Domenica\", \"Lunedì\", \"Martedì\", \"Mercoledì\", \"Giovedì\", \"Venerdì\", \"Sabato\", \"Domenica\"],\n\t\tdaysShort: [\"Dom\", \"Lun\", \"Mar\", \"Mer\", \"Gio\", \"Ven\", \"Sab\", \"Dom\"],\n\t\tdaysMin: [\"Do\", \"Lu\", \"Ma\", \"Me\", \"Gi\", \"Ve\", \"Sa\", \"Do\"],\n\t\tmonths: [\"Gennaio\", \"Febbraio\", \"Marzo\", \"Aprile\", \"Maggio\", \"Giugno\", \"Luglio\", \"Agosto\", \"Settembre\", \"Ottobre\", \"Novembre\", \"Dicembre\"],\n\t\tmonthsShort: [\"Gen\", \"Feb\", \"Mar\", \"Apr\", \"Mag\", \"Giu\", \"Lug\", \"Ago\", \"Set\", \"Ott\", \"Nov\", \"Dic\"],\n\t\ttoday: \"Oggi\",\n\t\tclear: \"Cancella\",\n\t\tweekStart: 1,\n\t\tformat: \"dd/mm/yyyy\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.ja.js",
    "content": "/**\n * Japanese translation for bootstrap-datepicker\n * Norio Suzuki <https://github.com/suzuki/>\n */\n;(function($){\n\t$.fn.datepicker.dates['ja'] = {\n\t\tdays: [\"日曜\", \"月曜\", \"火曜\", \"水曜\", \"木曜\", \"金曜\", \"土曜\", \"日曜\"],\n\t\tdaysShort: [\"日\", \"月\", \"火\", \"水\", \"木\", \"金\", \"土\", \"日\"],\n\t\tdaysMin: [\"日\", \"月\", \"火\", \"水\", \"木\", \"金\", \"土\", \"日\"],\n\t\tmonths: [\"1月\", \"2月\", \"3月\", \"4月\", \"5月\", \"6月\", \"7月\", \"8月\", \"9月\", \"10月\", \"11月\", \"12月\"],\n\t\tmonthsShort: [\"1月\", \"2月\", \"3月\", \"4月\", \"5月\", \"6月\", \"7月\", \"8月\", \"9月\", \"10月\", \"11月\", \"12月\"],\n\t\ttoday: \"今日\",\n\t\tformat: \"yyyy/mm/dd\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.ka.js",
    "content": "/**\n * Georgian translation for bootstrap-datepicker\n * Levan Melikishvili <levani0101@yahoo.com>\n */\n;(function($){\n    $.fn.datepicker.dates['ka'] = {\n        days: [\"კვირა\", \"ორშაბათი\", \"სამშაბათი\", \"ოთხშაბათი\", \"ხუთშაბათი\", \"პარასკევი\", \"შაბათი\", \"კვირა\"],\n        daysShort: [\"კვი\", \"ორშ\", \"სამ\", \"ოთხ\", \"ხუთ\", \"პარ\", \"შაბ\", \"კვი\"],\n        daysMin: [\"კვ\", \"ორ\", \"სა\", \"ოთ\", \"ხუ\", \"პა\", \"შა\", \"კვ\"],\n        months: [\"იანვარი\", \"თებერვალი\", \"მარტი\", \"აპრილი\", \"მაისი\", \"ივნისი\", \"ივლისი\", \"აგვისტო\", \"სექტემბერი\", \"ოქტომები\", \"ნოემბერი\", \"დეკემბერი\"],\n        monthsShort: [\"იან\", \"თებ\", \"მარ\", \"აპრ\", \"მაი\", \"ივნ\", \"ივლ\", \"აგვ\", \"სექ\", \"ოქტ\", \"ნოე\", \"დეკ\"],\n        today: \"დღეს\",\n        clear: \"გასუფთავება\",\n        weekStart: 1,\n        format: \"dd.mm.yyyy\"\n    };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.kk.js",
    "content": "/**\n * Kazakh translation for bootstrap-datepicker\n * Yerzhan Tolekov <era.tolekov@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['kk'] = {\n\t\tdays: [\"Жексенбі\", \"Дүйсенбі\", \"Сейсенбі\", \"Сәрсенбі\", \"Бейсенбі\", \"Жұма\", \"Сенбі\", \"Жексенбі\"],\n\t\tdaysShort: [\"Жек\", \"Дүй\", \"Сей\", \"Сәр\", \"Бей\", \"Жұм\", \"Сен\", \"Жек\"],\n\t\tdaysMin: [\"Жк\", \"Дс\", \"Сс\", \"Ср\", \"Бс\", \"Жм\", \"Сн\", \"Жк\"],\n\t\tmonths: [\"Қаңтар\", \"Ақпан\", \"Наурыз\", \"Сәуір\", \"Мамыр\", \"Маусым\", \"Шілде\", \"Тамыз\", \"Қыркүйек\", \"Қазан\", \"Қараша\", \"Желтоқсан\"],\n\t\tmonthsShort: [\"Қаң\", \"Ақп\", \"Нау\", \"Сәу\", \"Мамыр\", \"Мау\", \"Шлд\", \"Тмз\", \"Қыр\", \"Қзн\", \"Қар\", \"Жел\"],\n\t\ttoday: \"Бүгін\",\n\t\tweekStart: 1\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.kr.js",
    "content": "/**\n * Korean translation for bootstrap-datepicker\n * Gu Youn <http://github.com/guyoun>\n */\n;(function($){\n\t$.fn.datepicker.dates['kr'] = {\n\t\tdays: [\"일요일\", \"월요일\", \"화요일\", \"수요일\", \"목요일\", \"금요일\", \"토요일\", \"일요일\"],\n\t\tdaysShort: [\"일\", \"월\", \"화\", \"수\", \"목\", \"금\", \"토\", \"일\"],\n\t\tdaysMin: [\"일\", \"월\", \"화\", \"수\", \"목\", \"금\", \"토\", \"일\"],\n\t\tmonths: [\"1월\", \"2월\", \"3월\", \"4월\", \"5월\", \"6월\", \"7월\", \"8월\", \"9월\", \"10월\", \"11월\", \"12월\"],\n\t\tmonthsShort: [\"1월\", \"2월\", \"3월\", \"4월\", \"5월\", \"6월\", \"7월\", \"8월\", \"9월\", \"10월\", \"11월\", \"12월\"]\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.lt.js",
    "content": "/**\n * Lithuanian translation for bootstrap-datepicker\n * Šarūnas Gliebus <ssharunas@yahoo.co.uk>\n */\n\n;(function($){\n    $.fn.datepicker.dates['lt'] = {\n        days: [\"Sekmadienis\", \"Pirmadienis\", \"Antradienis\", \"Trečiadienis\", \"Ketvirtadienis\", \"Penktadienis\", \"Šeštadienis\", \"Sekmadienis\"],\n        daysShort: [\"S\", \"Pr\", \"A\", \"T\", \"K\", \"Pn\", \"Š\", \"S\"],\n        daysMin: [\"Sk\", \"Pr\", \"An\", \"Tr\", \"Ke\", \"Pn\", \"Št\", \"Sk\"],\n        months: [\"Sausis\", \"Vasaris\", \"Kovas\", \"Balandis\", \"Gegužė\", \"Birželis\", \"Liepa\", \"Rugpjūtis\", \"Rugsėjis\", \"Spalis\", \"Lapkritis\", \"Gruodis\"],\n        monthsShort: [\"Sau\", \"Vas\", \"Kov\", \"Bal\", \"Geg\", \"Bir\", \"Lie\", \"Rugp\", \"Rugs\", \"Spa\", \"Lap\", \"Gru\"],\n        today: \"Šiandien\",\n        weekStart: 1\n    };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.lv.js",
    "content": "/**\n * Latvian translation for bootstrap-datepicker\n * Artis Avotins <artis@apit.lv>\n */\n\n;(function($){\n    $.fn.datepicker.dates['lv'] = {\n        days: [\"Svētdiena\", \"Pirmdiena\", \"Otrdiena\", \"Trešdiena\", \"Ceturtdiena\", \"Piektdiena\", \"Sestdiena\", \"Svētdiena\"],\n        daysShort: [\"Sv\", \"P\", \"O\", \"T\", \"C\", \"Pk\", \"S\", \"Sv\"],\n        daysMin: [\"Sv\", \"Pr\", \"Ot\", \"Tr\", \"Ce\", \"Pk\", \"Se\", \"Sv\"],\n        months: [\"Janvāris\", \"Februāris\", \"Marts\", \"Aprīlis\", \"Maijs\", \"Jūnijs\", \"Jūlijs\", \"Augusts\", \"Septembris\", \"Oktobris\", \"Novembris\", \"Decembris\"],\n        monthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Mai\", \"Jūn\", \"Jūl\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n        today: \"Šodien\",\n        weekStart: 1\n    };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.mk.js",
    "content": "/**\n * Macedonian translation for bootstrap-datepicker\n * Marko Aleksic <psybaron@gmail.com>\n */\n;(function($){\n    $.fn.datepicker.dates['mk'] = {\n        days: [\"Недела\", \"Понеделник\", \"Вторник\", \"Среда\", \"Четврток\", \"Петок\", \"Сабота\", \"Недела\"],\n        daysShort: [\"Нед\", \"Пон\", \"Вто\", \"Сре\", \"Чет\", \"Пет\", \"Саб\", \"Нед\"],\n        daysMin: [\"Не\", \"По\", \"Вт\", \"Ср\", \"Че\", \"Пе\", \"Са\", \"Не\"],\n        months: [\"Јануари\", \"Февруари\", \"Март\", \"Април\", \"Мај\", \"Јуни\", \"Јули\", \"Август\", \"Септември\", \"Октомври\", \"Ноември\", \"Декември\"],\n        monthsShort: [\"Јан\", \"Фев\", \"Мар\", \"Апр\", \"Мај\", \"Јун\", \"Јул\", \"Авг\", \"Сеп\", \"Окт\", \"Ное\", \"Дек\"],\n        today: \"Денес\",\n        format: \"dd.mm.yyyy\"\n    };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.ms.js",
    "content": "/**\n * Malay translation for bootstrap-datepicker\n * Ateman Faiz <noorulfaiz@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['ms'] = {\n\t\tdays: [\"Ahad\", \"Isnin\", \"Selasa\", \"Rabu\", \"Khamis\", \"Jumaat\", \"Sabtu\", \"Ahad\"],\n\t\tdaysShort: [\"Aha\", \"Isn\", \"Sel\", \"Rab\", \"Kha\", \"Jum\", \"Sab\", \"Aha\"],\n\t\tdaysMin: [\"Ah\", \"Is\", \"Se\", \"Ra\", \"Kh\", \"Ju\", \"Sa\", \"Ah\"],\n\t\tmonths: [\"Januari\", \"Februari\", \"Mac\", \"April\", \"Mei\", \"Jun\", \"Julai\", \"Ogos\", \"September\", \"Oktober\", \"November\", \"Disember\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Mei\", \"Jun\", \"Jul\", \"Ogo\", \"Sep\", \"Okt\", \"Nov\", \"Dis\"],\n\t\ttoday: \"Hari Ini\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.nb.js",
    "content": "/**\n * Norwegian (bokmål) translation for bootstrap-datepicker\n * Fredrik Sundmyhr <http://github.com/fsundmyhr>\n */\n;(function($){\n\t$.fn.datepicker.dates['nb'] = {\n\t\tdays: [\"Søndag\", \"Mandag\", \"Tirsdag\", \"Onsdag\", \"Torsdag\", \"Fredag\", \"Lørdag\", \"Søndag\"],\n\t\tdaysShort: [\"Søn\", \"Man\", \"Tir\", \"Ons\", \"Tor\", \"Fre\", \"Lør\", \"Søn\"],\n\t\tdaysMin: [\"Sø\", \"Ma\", \"Ti\", \"On\", \"To\", \"Fr\", \"Lø\", \"Sø\"],\n\t\tmonths: [\"Januar\", \"Februar\", \"Mars\", \"April\", \"Mai\", \"Juni\", \"Juli\", \"August\", \"September\", \"Oktober\", \"November\", \"Desember\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Mai\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Des\"],\n\t\ttoday: \"I Dag\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.nl-BE.js",
    "content": "/**\n * Belgium-Dutch translation for bootstrap-datepicker\n * Julien Poulin <poulin_julien@hotmail.com>\n */\n;(function($){\n  $.fn.datepicker.dates['nl-BE'] = {\n    days: [\"Zondag\", \"Maandag\", \"Dinsdag\", \"Woensdag\", \"Donderdag\", \"Vrijdag\", \"Zaterdag\", \"Zondag\"],\n    daysShort: [\"Zo\", \"Ma\", \"Di\", \"Wo\", \"Do\", \"Vr\", \"Za\", \"Zo\"],\n    daysMin: [\"Zo\", \"Ma\", \"Di\", \"Wo\", \"Do\", \"Vr\", \"Za\", \"Zo\"],\n    months: [\"Januari\", \"Februari\", \"Maart\", \"April\", \"Mei\", \"Juni\", \"Juli\", \"Augustus\", \"September\", \"Oktober\", \"November\", \"December\"],\n    monthsShort: [\"Jan\", \"Feb\", \"Mrt\", \"Apr\", \"Mei\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n    today: \"Vandaag\",\n    clear: \"Leegmaken\",\n    weekStart: 1,\n    format: \"dd/mm/yyyy\"\n  };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.nl.js",
    "content": "/**\n * Dutch translation for bootstrap-datepicker\n * Reinier Goltstein <mrgoltstein@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['nl'] = {\n\t\tdays: [\"Zondag\", \"Maandag\", \"Dinsdag\", \"Woensdag\", \"Donderdag\", \"Vrijdag\", \"Zaterdag\", \"Zondag\"],\n\t\tdaysShort: [\"Zo\", \"Ma\", \"Di\", \"Wo\", \"Do\", \"Vr\", \"Za\", \"Zo\"],\n\t\tdaysMin: [\"Zo\", \"Ma\", \"Di\", \"Wo\", \"Do\", \"Vr\", \"Za\", \"Zo\"],\n\t\tmonths: [\"Januari\", \"Februari\", \"Maart\", \"April\", \"Mei\", \"Juni\", \"Juli\", \"Augustus\", \"September\", \"Oktober\", \"November\", \"December\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mrt\", \"Apr\", \"Mei\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Vandaag\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.no.js",
    "content": "/**\n *  Norwegian translation for bootstrap-datepicker\n **/\n;(function($){\n  $.fn.datepicker.dates['no'] = {\n    days: ['Søndag','Mandag','Tirsdag','Onsdag','Torsdag','Fredag','Lørdag'],\n    daysShort: ['Søn','Man','Tir','Ons','Tor','Fre','Lør'],\n    daysMin: ['Sø','Ma','Ti','On','To','Fr','Lø'],\n    months: ['Januar','Februar','Mars','April','Mai','Juni','Juli','August','September','Oktober','November','Desember'],\n    monthsShort: ['Jan','Feb','Mar','Apr','Mai','Jun','Jul','Aug','Sep','Okt','Nov','Des'],\n    today: 'I dag',\n    clear: 'Nullstill',\n    weekStart: 1,\n    format: 'dd.mm.yyyy'\n  };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.pl.js",
    "content": "/**\n * Polish translation for bootstrap-datepicker\n * Robert <rtpm@gazeta.pl>\n */\n;(function($){\n        $.fn.datepicker.dates['pl'] = {\n                days: [\"Niedziela\", \"Poniedziałek\", \"Wtorek\", \"Środa\", \"Czwartek\", \"Piątek\", \"Sobota\", \"Niedziela\"],\n                daysShort: [\"Nie\", \"Pn\", \"Wt\", \"Śr\", \"Czw\", \"Pt\", \"So\", \"Nie\"],\n                daysMin: [\"N\", \"Pn\", \"Wt\", \"Śr\", \"Cz\", \"Pt\", \"So\", \"N\"],\n                months: [\"Styczeń\", \"Luty\", \"Marzec\", \"Kwiecień\", \"Maj\", \"Czerwiec\", \"Lipiec\", \"Sierpień\", \"Wrzesień\", \"Październik\", \"Listopad\", \"Grudzień\"],\n                monthsShort: [\"Sty\", \"Lu\", \"Mar\", \"Kw\", \"Maj\", \"Cze\", \"Lip\", \"Sie\", \"Wrz\", \"Pa\", \"Lis\", \"Gru\"],\n                today: \"Dzisiaj\",\n                weekStart: 1\n        };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.pt-BR.js",
    "content": "/**\n * Brazilian translation for bootstrap-datepicker\n * Cauan Cabral <cauan@radig.com.br>\n */\n;(function($){\n\t$.fn.datepicker.dates['pt-BR'] = {\n\t\tdays: [\"Domingo\", \"Segunda\", \"Terça\", \"Quarta\", \"Quinta\", \"Sexta\", \"Sábado\", \"Domingo\"],\n\t\tdaysShort: [\"Dom\", \"Seg\", \"Ter\", \"Qua\", \"Qui\", \"Sex\", \"Sáb\", \"Dom\"],\n\t\tdaysMin: [\"Do\", \"Se\", \"Te\", \"Qu\", \"Qu\", \"Se\", \"Sa\", \"Do\"],\n\t\tmonths: [\"Janeiro\", \"Fevereiro\", \"Março\", \"Abril\", \"Maio\", \"Junho\", \"Julho\", \"Agosto\", \"Setembro\", \"Outubro\", \"Novembro\", \"Dezembro\"],\n\t\tmonthsShort: [\"Jan\", \"Fev\", \"Mar\", \"Abr\", \"Mai\", \"Jun\", \"Jul\", \"Ago\", \"Set\", \"Out\", \"Nov\", \"Dez\"],\n\t\ttoday: \"Hoje\",\n\t\tclear: \"Limpar\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.pt.js",
    "content": "/**\n * Portuguese translation for bootstrap-datepicker\n * Original code: Cauan Cabral <cauan@radig.com.br>\n * Tiago Melo <tiago.blackcode@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['pt'] = {\n\t\tdays: [\"Domingo\", \"Segunda\", \"Terça\", \"Quarta\", \"Quinta\", \"Sexta\", \"Sábado\", \"Domingo\"],\n\t\tdaysShort: [\"Dom\", \"Seg\", \"Ter\", \"Qua\", \"Qui\", \"Sex\", \"Sáb\", \"Dom\"],\n\t\tdaysMin: [\"Do\", \"Se\", \"Te\", \"Qu\", \"Qu\", \"Se\", \"Sa\", \"Do\"],\n\t\tmonths: [\"Janeiro\", \"Fevereiro\", \"Março\", \"Abril\", \"Maio\", \"Junho\", \"Julho\", \"Agosto\", \"Setembro\", \"Outubro\", \"Novembro\", \"Dezembro\"],\n\t\tmonthsShort: [\"Jan\", \"Fev\", \"Mar\", \"Abr\", \"Mai\", \"Jun\", \"Jul\", \"Ago\", \"Set\", \"Out\", \"Nov\", \"Dez\"],\n\t\ttoday: \"Hoje\",\n\t\tclear: \"Limpar\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.ro.js",
    "content": "/**\n * Romanian translation for bootstrap-datepicker\n * Cristian Vasile <cristi.mie@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['ro'] = {\n\t\tdays: [\"Duminică\", \"Luni\", \"Marţi\", \"Miercuri\", \"Joi\", \"Vineri\", \"Sâmbătă\", \"Duminică\"],\n\t\tdaysShort: [\"Dum\", \"Lun\", \"Mar\", \"Mie\", \"Joi\", \"Vin\", \"Sâm\", \"Dum\"],\n\t\tdaysMin: [\"Du\", \"Lu\", \"Ma\", \"Mi\", \"Jo\", \"Vi\", \"Sâ\", \"Du\"],\n\t\tmonths: [\"Ianuarie\", \"Februarie\", \"Martie\", \"Aprilie\", \"Mai\", \"Iunie\", \"Iulie\", \"August\", \"Septembrie\", \"Octombrie\", \"Noiembrie\", \"Decembrie\"],\n\t\tmonthsShort: [\"Ian\", \"Feb\", \"Mar\", \"Apr\", \"Mai\", \"Iun\", \"Iul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Astăzi\",\n\t\tclear: \"Șterge\",\n\t\tweekStart: 1\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.rs-latin.js",
    "content": "/**\n * Serbian latin translation for bootstrap-datepicker\n * Bojan Milosavlević <milboj@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['rs-latin'] = {\n\t\tdays: [\"Nedelja\",\"Ponedeljak\", \"Utorak\", \"Sreda\", \"Četvrtak\", \"Petak\", \"Subota\", \"Nedelja\"],\n\t\tdaysShort: [\"Ned\", \"Pon\", \"Uto\", \"Sre\", \"Čet\", \"Pet\", \"Sub\", \"Ned\"],\n\t\tdaysMin: [\"N\", \"Po\", \"U\", \"Sr\", \"Č\", \"Pe\", \"Su\", \"N\"],\n\t\tmonths: [\"Januar\", \"Februar\", \"Mart\", \"April\", \"Maj\", \"Jun\", \"Jul\", \"Avgust\", \"Septembar\", \"Oktobar\", \"Novembar\", \"Decembar\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Maj\", \"Jun\", \"Jul\", \"Avg\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Danas\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.rs.js",
    "content": "/**\n * Serbian cyrillic translation for bootstrap-datepicker\n * Bojan Milosavlević <milboj@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['rs'] = {\n\t\tdays: [\"Недеља\",\"Понедељак\", \"Уторак\", \"Среда\", \"Четвртак\", \"Петак\", \"Субота\", \"Недеља\"],\n\t\tdaysShort: [\"Нед\", \"Пон\", \"Уто\", \"Сре\", \"Чет\", \"Пет\", \"Суб\", \"Нед\"],\n\t\tdaysMin: [\"Н\", \"По\", \"У\", \"Ср\", \"Ч\", \"Пе\", \"Су\", \"Н\"],\n\t\tmonths: [\"Јануар\", \"Фебруар\", \"Март\", \"Април\", \"Мај\", \"Јун\", \"Јул\", \"Август\", \"Септембар\", \"Октобар\", \"Новембар\", \"Децембар\"],\n\t\tmonthsShort: [\"Јан\", \"Феб\", \"Мар\", \"Апр\", \"Мај\", \"Јун\", \"Јул\", \"Авг\", \"Сеп\", \"Окт\", \"Нов\", \"Дец\"],\n\t\ttoday: \"Данас\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.ru.js",
    "content": "/**\n * Russian translation for bootstrap-datepicker\n * Victor Taranenko <darwin@snowdale.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['ru'] = {\n\t\tdays: [\"Воскресенье\", \"Понедельник\", \"Вторник\", \"Среда\", \"Четверг\", \"Пятница\", \"Суббота\", \"Воскресенье\"],\n\t\tdaysShort: [\"Вск\", \"Пнд\", \"Втр\", \"Срд\", \"Чтв\", \"Птн\", \"Суб\", \"Вск\"],\n\t\tdaysMin: [\"Вс\", \"Пн\", \"Вт\", \"Ср\", \"Чт\", \"Пт\", \"Сб\", \"Вс\"],\n\t\tmonths: [\"Январь\", \"Февраль\", \"Март\", \"Апрель\", \"Май\", \"Июнь\", \"Июль\", \"Август\", \"Сентябрь\", \"Октябрь\", \"Ноябрь\", \"Декабрь\"],\n\t\tmonthsShort: [\"Янв\", \"Фев\", \"Мар\", \"Апр\", \"Май\", \"Июн\", \"Июл\", \"Авг\", \"Сен\", \"Окт\", \"Ноя\", \"Дек\"],\n\t\ttoday: \"Сегодня\",\n\t\tweekStart: 1\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.sk.js",
    "content": "/**\n * Slovak translation for bootstrap-datepicker\n * Marek Lichtner <marek@licht.sk>\n * Fixes by Michal Remiš <michal.remis@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates[\"sk\"] = {\n\t\tdays: [\"Nedeľa\", \"Pondelok\", \"Utorok\", \"Streda\", \"Štvrtok\", \"Piatok\", \"Sobota\", \"Nedeľa\"],\n\t\tdaysShort: [\"Ned\", \"Pon\", \"Uto\", \"Str\", \"Štv\", \"Pia\", \"Sob\", \"Ned\"],\n\t\tdaysMin: [\"Ne\", \"Po\", \"Ut\", \"St\", \"Št\", \"Pia\", \"So\", \"Ne\"],\n\t\tmonths: [\"Január\", \"Február\", \"Marec\", \"Apríl\", \"Máj\", \"Jún\", \"Júl\", \"August\", \"September\", \"Október\", \"November\", \"December\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Máj\", \"Jún\", \"Júl\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Dnes\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.sl.js",
    "content": "/**\n * Slovene translation for bootstrap-datepicker\n * Gregor Rudolf <gregor.rudolf@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['sl'] = {\n\t\tdays: [\"Nedelja\", \"Ponedeljek\", \"Torek\", \"Sreda\", \"Četrtek\", \"Petek\", \"Sobota\", \"Nedelja\"],\n\t\tdaysShort: [\"Ned\", \"Pon\", \"Tor\", \"Sre\", \"Čet\", \"Pet\", \"Sob\", \"Ned\"],\n\t\tdaysMin: [\"Ne\", \"Po\", \"To\", \"Sr\", \"Če\", \"Pe\", \"So\", \"Ne\"],\n\t\tmonths: [\"Januar\", \"Februar\", \"Marec\", \"April\", \"Maj\", \"Junij\", \"Julij\", \"Avgust\", \"September\", \"Oktober\", \"November\", \"December\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Maj\", \"Jun\", \"Jul\", \"Avg\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Danes\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.sq.js",
    "content": "/**\n * Albanian translation for bootstrap-datepicker\n * Tomor Pupovci <http://www.github.com/ttomor>\n */\n;(function($){\n\t$.fn.datepicker.dates['sq'] = {\n\t\tdays: [\"E Diel\", \"E Hënë\", \"E martē\", \"E mërkurë\", \"E Enjte\", \"E Premte\", \"E Shtunë\", \"E Diel\"],\n\t\tdaysShort: [\"Die\", \"Hën\", \"Mar\", \"Mër\", \"Enj\", \"Pre\", \"Shtu\", \"Die\"],\n\t\tdaysMin: [\"Di\", \"Hë\", \"Ma\", \"Më\", \"En\", \"Pr\", \"Sht\", \"Di\"],\n\t\tmonths: [\"Janar\", \"Shkurt\", \"Mars\", \"Prill\", \"Maj\", \"Qershor\", \"Korrik\", \"Gusht\", \"Shtator\", \"Tetor\", \"Nëntor\", \"Dhjetor\"],\n\t\tmonthsShort: [\"Jan\", \"Shk\", \"Mar\", \"Pri\", \"Maj\", \"Qer\", \"Korr\", \"Gu\", \"Sht\", \"Tet\", \"Nën\", \"Dhjet\"],\n\t\ttoday: \"Sot\"\n\t};\n}(jQuery));\n\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.sv.js",
    "content": "/**\n * Swedish translation for bootstrap-datepicker\n * Patrik Ragnarsson <patrik@starkast.net>\n */\n;(function($){\n\t$.fn.datepicker.dates['sv'] = {\n\t\tdays: [\"Söndag\", \"Måndag\", \"Tisdag\", \"Onsdag\", \"Torsdag\", \"Fredag\", \"Lördag\", \"Söndag\"],\n\t\tdaysShort: [\"Sön\", \"Mån\", \"Tis\", \"Ons\", \"Tor\", \"Fre\", \"Lör\", \"Sön\"],\n\t\tdaysMin: [\"Sö\", \"Må\", \"Ti\", \"On\", \"To\", \"Fr\", \"Lö\", \"Sö\"],\n\t\tmonths: [\"Januari\", \"Februari\", \"Mars\", \"April\", \"Maj\", \"Juni\", \"Juli\", \"Augusti\", \"September\", \"Oktober\", \"November\", \"December\"],\n\t\tmonthsShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"Maj\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Okt\", \"Nov\", \"Dec\"],\n\t\ttoday: \"Idag\",\n\t\tformat: \"yyyy-mm-dd\",\n\t\tweekStart: 1\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.sw.js",
    "content": "/**\n * Swahili translation for bootstrap-datepicker\n * Edwin Mugendi <https://github.com/edwinmugendi>\n * Source: http://scriptsource.org/cms/scripts/page.php?item_id=entry_detail&uid=xnfaqyzcku\n */\n;(function($){\n    $.fn.datepicker.dates['sw'] = {\n        days: [\"Jumapili\", \"Jumatatu\", \"Jumanne\", \"Jumatano\", \"Alhamisi\", \"Ijumaa\", \"Jumamosi\", \"Jumapili\"],\n        daysShort: [\"J2\", \"J3\", \"J4\", \"J5\", \"Alh\", \"Ij\", \"J1\", \"J2\"],\n        daysMin: [\"2\", \"3\", \"4\", \"5\", \"A\", \"I\", \"1\", \"2\"],\n        months: [\"Januari\", \"Februari\", \"Machi\", \"Aprili\", \"Mei\", \"Juni\", \"Julai\", \"Agosti\", \"Septemba\", \"Oktoba\", \"Novemba\", \"Desemba\"],\n        monthsShort: [\"Jan\", \"Feb\", \"Mac\", \"Apr\", \"Mei\", \"Jun\", \"Jul\", \"Ago\", \"Sep\", \"Okt\", \"Nov\", \"Des\"],\n        today: \"Leo\"\n    };\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.th.js",
    "content": "/**\n * Thai translation for bootstrap-datepicker\n * Suchau Jiraprapot <seroz24@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['th'] = {\n\t\tdays: [\"อาทิตย์\", \"จันทร์\", \"อังคาร\", \"พุธ\", \"พฤหัส\", \"ศุกร์\", \"เสาร์\", \"อาทิตย์\"],\n\t\tdaysShort: [\"อา\", \"จ\", \"อ\", \"พ\", \"พฤ\", \"ศ\", \"ส\", \"อา\"],\n\t\tdaysMin: [\"อา\", \"จ\", \"อ\", \"พ\", \"พฤ\", \"ศ\", \"ส\", \"อา\"],\n\t\tmonths: [\"มกราคม\", \"กุมภาพันธ์\", \"มีนาคม\", \"เมษายน\", \"พฤษภาคม\", \"มิถุนายน\", \"กรกฎาคม\", \"สิงหาคม\", \"กันยายน\", \"ตุลาคม\", \"พฤศจิกายน\", \"ธันวาคม\"],\n\t\tmonthsShort: [\"ม.ค.\", \"ก.พ.\", \"มี.ค.\", \"เม.ย.\", \"พ.ค.\", \"มิ.ย.\", \"ก.ค.\", \"ส.ค.\", \"ก.ย.\", \"ต.ค.\", \"พ.ย.\", \"ธ.ค.\"],\n\t\ttoday: \"วันนี้\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.tr.js",
    "content": "/**\n * Turkish translation for bootstrap-datepicker\n * Serkan Algur <kaisercrazy_2@hotmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['tr'] = {\n\t\tdays: [\"Pazar\", \"Pazartesi\", \"Salı\", \"Çarşamba\", \"Perşembe\", \"Cuma\", \"Cumartesi\", \"Pazar\"],\n\t\tdaysShort: [\"Pz\", \"Pzt\", \"Sal\", \"Çrş\", \"Prş\", \"Cu\", \"Cts\", \"Pz\"],\n\t\tdaysMin: [\"Pz\", \"Pzt\", \"Sa\", \"Çr\", \"Pr\", \"Cu\", \"Ct\", \"Pz\"],\n\t\tmonths: [\"Ocak\", \"Şubat\", \"Mart\", \"Nisan\", \"Mayıs\", \"Haziran\", \"Temmuz\", \"Ağustos\", \"Eylül\", \"Ekim\", \"Kasım\", \"Aralık\"],\n\t\tmonthsShort: [\"Oca\", \"Şub\", \"Mar\", \"Nis\", \"May\", \"Haz\", \"Tem\", \"Ağu\", \"Eyl\", \"Eki\", \"Kas\", \"Ara\"],\n\t\ttoday: \"Bugün\",\n\t\tformat: \"dd.mm.yyyy\"\n\t};\n}(jQuery));\n\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.ua.js",
    "content": "/**\n * Ukrainian translation for bootstrap-datepicker\n * Igor Polynets\n */\n;(function($){\n\t$.fn.datepicker.dates['ua'] = {\n\t\tdays: [\"Неділя\", \"Понеділок\", \"Вівторок\", \"Середа\", \"Четвер\", \"П'ятница\", \"Субота\", \"Неділя\"],\n\t\tdaysShort: [\"Нед\", \"Пнд\", \"Втр\", \"Срд\", \"Чтв\", \"Птн\", \"Суб\", \"Нед\"],\n\t\tdaysMin: [\"Нд\", \"Пн\", \"Вт\", \"Ср\", \"Чт\", \"Пт\", \"Сб\", \"Нд\"],\n\t\tmonths: [\"Cічень\", \"Лютий\", \"Березень\", \"Квітень\", \"Травень\", \"Червень\", \"Липень\", \"Серпень\", \"Вересень\", \"Жовтень\", \"Листопад\", \"Грудень\"],\n\t\tmonthsShort: [\"Січ\", \"Лют\", \"Бер\", \"Кві\", \"Тра\", \"Чер\", \"Лип\", \"Сер\", \"Вер\", \"Жов\", \"Лис\", \"Гру\"],\n\t\ttoday: \"Сьогодні\",\n\t\tweekStart: 1\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.vi.js",
    "content": "/**\n * Vietnamese translation for bootstrap-datepicker\n * An Vo <https://github.com/anvoz/>\n */\n;(function($){\n\t$.fn.datepicker.dates['vi'] = {\n\t\tdays: [\"Chủ nhật\", \"Thứ hai\", \"Thứ ba\", \"Thứ tư\", \"Thứ năm\", \"Thứ sáu\", \"Thứ bảy\", \"Chủ nhật\"],\n\t\tdaysShort: [\"CN\", \"Thứ 2\", \"Thứ 3\", \"Thứ 4\", \"Thứ 5\", \"Thứ 6\", \"Thứ 7\", \"CN\"],\n\t\tdaysMin: [\"CN\", \"T2\", \"T3\", \"T4\", \"T5\", \"T6\", \"T7\", \"CN\"],\n\t\tmonths: [\"Tháng 1\", \"Tháng 2\", \"Tháng 3\", \"Tháng 4\", \"Tháng 5\", \"Tháng 6\", \"Tháng 7\", \"Tháng 8\", \"Tháng 9\", \"Tháng 10\", \"Tháng 11\", \"Tháng 12\"],\n\t\tmonthsShort: [\"Th1\", \"Th2\", \"Th3\", \"Th4\", \"Th5\", \"Th6\", \"Th7\", \"Th8\", \"Th9\", \"Th10\", \"Th11\", \"Th12\"],\n\t\ttoday: \"Hôm nay\",\n\t\tclear: \"Xóa\",\n\t\tformat: \"dd/mm/yyyy\"\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.zh-CN.js",
    "content": "/**\n * Simplified Chinese translation for bootstrap-datepicker\n * Yuan Cheung <advanimal@gmail.com>\n */\n;(function($){\n\t$.fn.datepicker.dates['zh-CN'] = {\n\t\tdays: [\"星期日\", \"星期一\", \"星期二\", \"星期三\", \"星期四\", \"星期五\", \"星期六\", \"星期日\"],\n\t\tdaysShort: [\"周日\", \"周一\", \"周二\", \"周三\", \"周四\", \"周五\", \"周六\", \"周日\"],\n\t\tdaysMin:  [\"日\", \"一\", \"二\", \"三\", \"四\", \"五\", \"六\", \"日\"],\n\t\tmonths: [\"一月\", \"二月\", \"三月\", \"四月\", \"五月\", \"六月\", \"七月\", \"八月\", \"九月\", \"十月\", \"十一月\", \"十二月\"],\n\t\tmonthsShort: [\"一月\", \"二月\", \"三月\", \"四月\", \"五月\", \"六月\", \"七月\", \"八月\", \"九月\", \"十月\", \"十一月\", \"十二月\"],\n\t\ttoday: \"今日\",\n\t\tformat: \"yyyy年mm月dd日\",\n\t\tweekStart: 1\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/datepicker/locales/bootstrap-datepicker.zh-TW.js",
    "content": "/**\n * Traditional Chinese translation for bootstrap-datepicker\n * Rung-Sheng Jang <daniel@i-trend.co.cc>\n * FrankWu  <frankwu100@gmail.com> Fix more appropriate use of Traditional Chinese habit\n */\n;(function($){\n\t$.fn.datepicker.dates['zh-TW'] = {\n\t\tdays: [\"星期日\", \"星期一\", \"星期二\", \"星期三\", \"星期四\", \"星期五\", \"星期六\", \"星期日\"],\n\t\tdaysShort: [\"週日\", \"週一\", \"週二\", \"週三\", \"週四\", \"週五\", \"週六\", \"週日\"],\n\t\tdaysMin:  [\"日\", \"一\", \"二\", \"三\", \"四\", \"五\", \"六\", \"日\"],\n\t\tmonths: [\"一月\", \"二月\", \"三月\", \"四月\", \"五月\", \"六月\", \"七月\", \"八月\", \"九月\", \"十月\", \"十一月\", \"十二月\"],\n\t\tmonthsShort: [\"一月\", \"二月\", \"三月\", \"四月\", \"五月\", \"六月\", \"七月\", \"八月\", \"九月\", \"十月\", \"十一月\", \"十二月\"],\n\t\ttoday: \"今天\",\n\t\tformat: \"yyyy年mm月dd日\",\n\t\tweekStart: 1\n\t};\n}(jQuery));\n"
  },
  {
    "path": "public/static/plugins/daterangepicker/daterangepicker-bs3.css",
    "content": "/*!\n * Stylesheet for the Date Range Picker, for use with Bootstrap 3.x\n *\n * Copyright 2013-2015 Dan Grossman ( http://www.dangrossman.info )\n * Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\n *\n * Built for http://www.improvely.com\n */\n\n .daterangepicker.dropdown-menu {\n  max-width: none;\n  z-index: 3000;\n}\n\n.daterangepicker.opensleft .ranges, .daterangepicker.opensleft .calendar {\n  float: left;\n  margin: 4px;\n}\n\n.daterangepicker.opensright .ranges, .daterangepicker.opensright .calendar,\n.daterangepicker.openscenter .ranges, .daterangepicker.openscenter .calendar {\n  float: right;\n  margin: 4px;\n}\n\n.daterangepicker.single .ranges, .daterangepicker.single .calendar {\n  float: none;\n}\n\n.daterangepicker .ranges {\n  width: 160px;\n  text-align: left;\n}\n\n.daterangepicker .ranges .range_inputs>div {\n  float: left;\n}\n\n.daterangepicker .ranges .range_inputs>div:nth-child(2) {\n  padding-left: 11px;\n}\n\n.daterangepicker .calendar {\n  display: none;\n  max-width: 270px;\n}\n\n.daterangepicker.show-calendar .calendar {\n    display: block;\n}\n\n.daterangepicker .calendar.single .calendar-date {\n  border: none;\n}\n\n.daterangepicker .calendar th, .daterangepicker .calendar td {\n  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;\n  white-space: nowrap;\n  text-align: center;\n  min-width: 32px;\n}\n\n.daterangepicker .daterangepicker_start_input label,\n.daterangepicker .daterangepicker_end_input label {\n  color: #333;\n  display: block;\n  font-size: 11px;\n  font-weight: normal;\n  height: 20px;\n  line-height: 20px;\n  margin-bottom: 2px;\n  text-shadow: #fff 1px 1px 0px;\n  text-transform: uppercase;\n  width: 74px;\n}\n\n.daterangepicker .ranges input {\n  font-size: 11px;\n}\n\n.daterangepicker .ranges .input-mini {\n  border: 1px solid #ccc;\n  border-radius: 4px;\n  color: #555;\n  display: block;\n  font-size: 11px;\n  height: 30px;\n  line-height: 30px;\n  vertical-align: middle;\n  margin: 0 0 10px 0;\n  padding: 0 6px;\n  width: 74px;\n}\n\n.daterangepicker .ranges ul {\n  list-style: none;\n  margin: 0;\n  padding: 0;\n}\n\n.daterangepicker .ranges li {\n  font-size: 13px;\n  background: #f5f5f5;\n  border: 1px solid #f5f5f5;\n  color: #08c;\n  padding: 3px 12px;\n  margin-bottom: 8px;\n  -webkit-border-radius: 5px;\n  -moz-border-radius: 5px;\n  border-radius: 5px;\n  cursor: pointer;\n}\n\n.daterangepicker .ranges li.active, .daterangepicker .ranges li:hover {\n  background: #08c;\n  border: 1px solid #08c;\n  color: #fff;\n}\n\n.daterangepicker .calendar-date {\n  border: 1px solid #ddd;\n  padding: 4px;\n  border-radius: 4px;\n  background: #fff;\n}\n\n.daterangepicker .calendar-time {\n  text-align: center;\n  margin: 8px auto 0 auto;\n  line-height: 30px;\n}\n\n.daterangepicker {\n  position: absolute;\n  background: #fff;\n  top: 100px;\n  left: 20px;\n  padding: 4px;\n  margin-top: 1px;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n}\n\n.daterangepicker.opensleft:before {\n  position: absolute;\n  top: -7px;\n  right: 9px;\n  display: inline-block;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid #ccc;\n  border-left: 7px solid transparent;\n  border-bottom-color: rgba(0, 0, 0, 0.2);\n  content: '';\n}\n\n.daterangepicker.opensleft:after {\n  position: absolute;\n  top: -6px;\n  right: 10px;\n  display: inline-block;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid #fff;\n  border-left: 6px solid transparent;\n  content: '';\n}\n\n.daterangepicker.openscenter:before {\n  position: absolute;\n  top: -7px;\n  left: 0;  \n  right: 0;\n  width: 0;\n  margin-left: auto;\n  margin-right: auto;\n  display: inline-block;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid #ccc;\n  border-left: 7px solid transparent;\n  border-bottom-color: rgba(0, 0, 0, 0.2);\n  content: '';\n}\n\n.daterangepicker.openscenter:after {\n  position: absolute;\n  top: -6px;\n  left: 0;  \n  right: 0;  \n  width: 0;\n  margin-left: auto;\n  margin-right: auto;\n  display: inline-block;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid #fff;\n  border-left: 6px solid transparent;\n  content: '';\n}\n\n.daterangepicker.opensright:before {\n  position: absolute;\n  top: -7px;\n  left: 9px;\n  display: inline-block;\n  border-right: 7px solid transparent;\n  border-bottom: 7px solid #ccc;\n  border-left: 7px solid transparent;\n  border-bottom-color: rgba(0, 0, 0, 0.2);\n  content: '';\n}\n\n.daterangepicker.opensright:after {\n  position: absolute;\n  top: -6px;\n  left: 10px;\n  display: inline-block;\n  border-right: 6px solid transparent;\n  border-bottom: 6px solid #fff;\n  border-left: 6px solid transparent;\n  content: '';\n}\n\n.daterangepicker.dropup{\n  margin-top: -5px;\n}\n.daterangepicker.dropup:before{\n  top: initial;\n  bottom:-7px;\n  border-bottom: initial;\n  border-top: 7px solid #ccc;\n}\n.daterangepicker.dropup:after{\n  top: initial;\n  bottom:-6px;\n  border-bottom: initial;\n  border-top: 6px solid #fff;\n}\n\n.daterangepicker table {\n  width: 100%;\n  margin: 0;\n}\n\n.daterangepicker td, .daterangepicker th {\n  text-align: center;\n  width: 20px;\n  height: 20px;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n  cursor: pointer;\n  white-space: nowrap;\n}\n\n.daterangepicker td.off {\n  color: #999;\n}\n\n.daterangepicker td.disabled, .daterangepicker option.disabled {\n  color: #999;\n}\n\n.daterangepicker td.available:hover, .daterangepicker th.available:hover {\n  background: #eee;\n}\n\n.daterangepicker td.in-range {\n  background: #ebf4f8;\n  -webkit-border-radius: 0;\n  -moz-border-radius: 0;\n  border-radius: 0;\n}\n\n.daterangepicker td.start-date {\n  -webkit-border-radius: 4px 0 0 4px;\n  -moz-border-radius: 4px 0 0 4px;\n  border-radius: 4px 0 0 4px;\n}\n\n.daterangepicker td.end-date {\n  -webkit-border-radius: 0 4px 4px 0;\n  -moz-border-radius: 0 4px 4px 0;\n  border-radius: 0 4px 4px 0;\n}\n\n.daterangepicker td.start-date.end-date {\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n}\n\n.daterangepicker td.active, .daterangepicker td.active:hover {\n  background-color: #357ebd;\n  border-color: #3071a9;\n  color: #fff;\n}\n\n.daterangepicker td.week, .daterangepicker th.week {\n  font-size: 80%;\n  color: #ccc;\n}\n\n.daterangepicker select.monthselect, .daterangepicker select.yearselect {\n  font-size: 12px;\n  padding: 1px;\n  height: auto;\n  margin: 0;\n  cursor: default;\n}\n\n.daterangepicker select.monthselect {\n  margin-right: 2%;\n  width: 56%;\n}\n\n.daterangepicker select.yearselect {\n  width: 40%;\n}\n\n.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect {\n  width: 50px;\n  margin-bottom: 0;\n}\n\n.daterangepicker_start_input {\n  float: left;\n}\n\n.daterangepicker_end_input {\n  float: left; \n  padding-left: 11px\n}\n\n.daterangepicker th.month {\n  width: auto;\n}\n"
  },
  {
    "path": "public/static/plugins/daterangepicker/daterangepicker.js",
    "content": "/**\n* @version: 1.3.21\n* @author: Dan Grossman http://www.dangrossman.info/\n* @copyright: Copyright (c) 2012-2015 Dan Grossman. All rights reserved.\n* @license: Licensed under the MIT license. See http://www.opensource.org/licenses/mit-license.php\n* @website: https://www.improvely.com/\n*/\n\n(function(root, factory) {\n\n  if (typeof define === 'function' && define.amd) {\n    define(['moment', 'jquery', 'exports'], function(momentjs, $, exports) {\n      root.daterangepicker = factory(root, exports, momentjs, $);\n    });\n\n  } else if (typeof exports !== 'undefined') {\n    var momentjs = require('moment');\n    var jQuery;\n    try {\n      jQuery = require('jquery');\n    } catch (err) {\n      jQuery = window.jQuery;\n      if (!jQuery) throw new Error('jQuery dependency not found');\n    }\n\n    factory(root, exports, momentjs, jQuery);\n\n  // Finally, as a browser global.\n  } else {\n    root.daterangepicker = factory(root, {}, root.moment, (root.jQuery || root.Zepto || root.ender || root.$));\n  }\n\n}(this, function(root, daterangepicker, moment, $) {\n\n    var DateRangePicker = function (element, options, cb) {\n\n        // by default, the daterangepicker element is placed at the bottom of HTML body\n        this.parentEl = 'body';\n\n        //element that triggered the date range picker\n        this.element = $(element);\n\n        //tracks visible state\n        this.isShowing = false;\n\n        //create the picker HTML object\n        var DRPTemplate = '<div class=\"daterangepicker dropdown-menu\">' +\n                '<div class=\"calendar first left\"></div>' +\n                '<div class=\"calendar second right\"></div>' +\n                '<div class=\"ranges\">' +\n                  '<div class=\"range_inputs\">' +\n                    '<div class=\"daterangepicker_start_input\">' +\n                      '<label for=\"daterangepicker_start\"></label>' +\n                      '<input class=\"input-mini\" type=\"text\" name=\"daterangepicker_start\" value=\"\" />' +\n                    '</div>' +\n                    '<div class=\"daterangepicker_end_input\">' +\n                      '<label for=\"daterangepicker_end\"></label>' +\n                      '<input class=\"input-mini\" type=\"text\" name=\"daterangepicker_end\" value=\"\" />' +\n                    '</div>' +\n                    '<button class=\"applyBtn\" disabled=\"disabled\"></button>&nbsp;' +\n                    '<button class=\"cancelBtn\"></button>' +\n                  '</div>' +\n                '</div>' +\n              '</div>';\n\n        //custom options\n        if (typeof options !== 'object' || options === null)\n            options = {};\n\n        this.parentEl = (typeof options === 'object' && options.parentEl && $(options.parentEl).length) ? $(options.parentEl) : $(this.parentEl);\n        this.container = $(DRPTemplate).appendTo(this.parentEl);\n\n        this.setOptions(options, cb);\n\n        //event listeners\n        this.container.find('.calendar')\n            .on('click.daterangepicker', '.prev', $.proxy(this.clickPrev, this))\n            .on('click.daterangepicker', '.next', $.proxy(this.clickNext, this))\n            .on('click.daterangepicker', 'td.available', $.proxy(this.clickDate, this))\n            .on('mouseenter.daterangepicker', 'td.available', $.proxy(this.hoverDate, this))\n            .on('mouseleave.daterangepicker', 'td.available', $.proxy(this.updateFormInputs, this))\n            .on('change.daterangepicker', 'select.yearselect', $.proxy(this.updateMonthYear, this))\n            .on('change.daterangepicker', 'select.monthselect', $.proxy(this.updateMonthYear, this))\n            .on('change.daterangepicker', 'select.hourselect,select.minuteselect,select.secondselect,select.ampmselect', $.proxy(this.updateTime, this));\n\n        this.container.find('.ranges')\n            .on('click.daterangepicker', 'button.applyBtn', $.proxy(this.clickApply, this))\n            .on('click.daterangepicker', 'button.cancelBtn', $.proxy(this.clickCancel, this))\n            .on('click.daterangepicker', '.daterangepicker_start_input,.daterangepicker_end_input', $.proxy(this.showCalendars, this))\n            .on('change.daterangepicker', '.daterangepicker_start_input,.daterangepicker_end_input', $.proxy(this.inputsChanged, this))\n            .on('keydown.daterangepicker', '.daterangepicker_start_input,.daterangepicker_end_input', $.proxy(this.inputsKeydown, this))\n            .on('click.daterangepicker', 'li', $.proxy(this.clickRange, this))\n            .on('mouseenter.daterangepicker', 'li', $.proxy(this.enterRange, this))\n            .on('mouseleave.daterangepicker', 'li', $.proxy(this.updateFormInputs, this));\n\n        if (this.element.is('input')) {\n            this.element.on({\n                'click.daterangepicker': $.proxy(this.show, this),\n                'focus.daterangepicker': $.proxy(this.show, this),\n                'keyup.daterangepicker': $.proxy(this.updateFromControl, this),\n                'keydown.daterangepicker': $.proxy(this.keydown, this)\n            });\n        } else {\n            this.element.on('click.daterangepicker', $.proxy(this.toggle, this));\n        }\n\n    };\n\n    DateRangePicker.prototype = {\n\n        constructor: DateRangePicker,\n\n        setOptions: function(options, callback) {\n\n            this.startDate = moment().startOf('day');\n            this.endDate = moment().endOf('day');\n            this.timeZone = moment().utcOffset();\n            this.minDate = false;\n            this.maxDate = false;\n            this.dateLimit = false;\n\n            this.showDropdowns = false;\n            this.showWeekNumbers = false;\n            this.timePicker = false;\n            this.timePickerSeconds = false;\n            this.timePickerIncrement = 30;\n            this.timePicker12Hour = true;\n            this.singleDatePicker = false;\n            this.ranges = {};\n\n            this.opens = 'right';\n            if (this.element.hasClass('pull-right'))\n                this.opens = 'left';\n\n            this.drops = 'down';\n            if (this.element.hasClass('dropup'))\n                this.drops = 'up';\n\n            this.buttonClasses = ['btn', 'btn-small btn-sm'];\n            this.applyClass = 'btn-success';\n            this.cancelClass = 'btn-default';\n\n            this.format = 'MM/DD/YYYY';\n            this.separator = ' - ';\n\n            this.locale = {\n                applyLabel: 'Apply',\n                cancelLabel: 'Cancel',\n                fromLabel: 'From',\n                toLabel: 'To',\n                weekLabel: 'W',\n                customRangeLabel: 'Custom Range',\n                daysOfWeek: moment.weekdaysMin(),\n                monthNames: moment.monthsShort(),\n                firstDay: moment.localeData()._week.dow\n            };\n\n            this.cb = function () { };\n\n            if (typeof options.format === 'string')\n                this.format = options.format;\n\n            if (typeof options.separator === 'string')\n                this.separator = options.separator;\n\n            if (typeof options.startDate === 'string')\n                this.startDate = moment(options.startDate, this.format);\n\n            if (typeof options.endDate === 'string')\n                this.endDate = moment(options.endDate, this.format);\n\n            if (typeof options.minDate === 'string')\n                this.minDate = moment(options.minDate, this.format);\n\n            if (typeof options.maxDate === 'string')\n                this.maxDate = moment(options.maxDate, this.format);\n\n            if (typeof options.startDate === 'object')\n                this.startDate = moment(options.startDate);\n\n            if (typeof options.endDate === 'object')\n                this.endDate = moment(options.endDate);\n\n            if (typeof options.minDate === 'object')\n                this.minDate = moment(options.minDate);\n\n            if (typeof options.maxDate === 'object')\n                this.maxDate = moment(options.maxDate);\n\n            if (typeof options.applyClass === 'string')\n                this.applyClass = options.applyClass;\n\n            if (typeof options.cancelClass === 'string')\n                this.cancelClass = options.cancelClass;\n\n            if (typeof options.dateLimit === 'object')\n                this.dateLimit = options.dateLimit;\n\n            if (typeof options.locale === 'object') {\n\n                if (typeof options.locale.daysOfWeek === 'object') {\n                    // Create a copy of daysOfWeek to avoid modification of original\n                    // options object for reusability in multiple daterangepicker instances\n                    this.locale.daysOfWeek = options.locale.daysOfWeek.slice();\n                }\n\n                if (typeof options.locale.monthNames === 'object') {\n                  this.locale.monthNames = options.locale.monthNames.slice();\n                }\n\n                if (typeof options.locale.firstDay === 'number') {\n                  this.locale.firstDay = options.locale.firstDay;\n                }\n\n                if (typeof options.locale.applyLabel === 'string') {\n                  this.locale.applyLabel = options.locale.applyLabel;\n                }\n\n                if (typeof options.locale.cancelLabel === 'string') {\n                  this.locale.cancelLabel = options.locale.cancelLabel;\n                }\n\n                if (typeof options.locale.fromLabel === 'string') {\n                  this.locale.fromLabel = options.locale.fromLabel;\n                }\n\n                if (typeof options.locale.toLabel === 'string') {\n                  this.locale.toLabel = options.locale.toLabel;\n                }\n\n                if (typeof options.locale.weekLabel === 'string') {\n                  this.locale.weekLabel = options.locale.weekLabel;\n                }\n\n                if (typeof options.locale.customRangeLabel === 'string') {\n                  this.locale.customRangeLabel = options.locale.customRangeLabel;\n                }\n            }\n\n            if (typeof options.opens === 'string')\n                this.opens = options.opens;\n\n            if (typeof options.drops === 'string')\n                this.drops = options.drops;\n\n            if (typeof options.showWeekNumbers === 'boolean') {\n                this.showWeekNumbers = options.showWeekNumbers;\n            }\n\n            if (typeof options.buttonClasses === 'string') {\n                this.buttonClasses = [options.buttonClasses];\n            }\n\n            if (typeof options.buttonClasses === 'object') {\n                this.buttonClasses = options.buttonClasses;\n            }\n\n            if (typeof options.showDropdowns === 'boolean') {\n                this.showDropdowns = options.showDropdowns;\n            }\n\n            if (typeof options.singleDatePicker === 'boolean') {\n                this.singleDatePicker = options.singleDatePicker;\n                if (this.singleDatePicker) {\n                    this.endDate = this.startDate.clone();\n                }\n            }\n\n            if (typeof options.timePicker === 'boolean') {\n                this.timePicker = options.timePicker;\n            }\n\n            if (typeof options.timePickerSeconds === 'boolean') {\n                this.timePickerSeconds = options.timePickerSeconds;\n            }\n\n            if (typeof options.timePickerIncrement === 'number') {\n                this.timePickerIncrement = options.timePickerIncrement;\n            }\n\n            if (typeof options.timePicker12Hour === 'boolean') {\n                this.timePicker12Hour = options.timePicker12Hour;\n            }\n\n            // update day names order to firstDay\n            if (this.locale.firstDay != 0) {\n                var iterator = this.locale.firstDay;\n                while (iterator > 0) {\n                    this.locale.daysOfWeek.push(this.locale.daysOfWeek.shift());\n                    iterator--;\n                }\n            }\n\n            var start, end, range;\n\n            //if no start/end dates set, check if an input element contains initial values\n            if (typeof options.startDate === 'undefined' && typeof options.endDate === 'undefined') {\n                if ($(this.element).is('input[type=text]')) {\n                    var val = $(this.element).val(),\n                        split = val.split(this.separator);\n\n                    start = end = null;\n\n                    if (split.length == 2) {\n                        start = moment(split[0], this.format);\n                        end = moment(split[1], this.format);\n                    } else if (this.singleDatePicker && val !== \"\") {\n                        start = moment(val, this.format);\n                        end = moment(val, this.format);\n                    }\n                    if (start !== null && end !== null) {\n                        this.startDate = start;\n                        this.endDate = end;\n                    }\n                }\n            }\n\n            // bind the time zone used to build the calendar to either the timeZone passed in through the options or the zone of the startDate (which will be the local time zone by default)\n            if (typeof options.timeZone === 'string' || typeof options.timeZone === 'number') {\n            \tif (typeof options.timeZone === 'string' && typeof moment.tz !== 'undefined') {\n            \t\tthis.timeZone = moment.tz.zone(options.timeZone).parse(new Date) * -1;\t// Offset is positive if the timezone is behind UTC and negative if it is ahead.\n            \t} else {\n            \t\tthis.timeZone = options.timeZone;\n            \t}\n              this.startDate.utcOffset(this.timeZone);\n              this.endDate.utcOffset(this.timeZone);\n            } else {\n                this.timeZone = moment(this.startDate).utcOffset();\n            }\n\n            if (typeof options.ranges === 'object') {\n                for (range in options.ranges) {\n\n                    if (typeof options.ranges[range][0] === 'string')\n                        start = moment(options.ranges[range][0], this.format);\n                    else\n                        start = moment(options.ranges[range][0]);\n\n                    if (typeof options.ranges[range][1] === 'string')\n                        end = moment(options.ranges[range][1], this.format);\n                    else\n                        end = moment(options.ranges[range][1]);\n\n                    // If we have a min/max date set, bound this range\n                    // to it, but only if it would otherwise fall\n                    // outside of the min/max.\n                    if (this.minDate && start.isBefore(this.minDate))\n                        start = moment(this.minDate);\n\n                    if (this.maxDate && end.isAfter(this.maxDate))\n                        end = moment(this.maxDate);\n\n                    // If the end of the range is before the minimum (if min is set) OR\n                    // the start of the range is after the max (also if set) don't display this\n                    // range option.\n                    if ((this.minDate && end.isBefore(this.minDate)) || (this.maxDate && start.isAfter(this.maxDate))) {\n                        continue;\n                    }\n\n                    this.ranges[range] = [start, end];\n                }\n\n                var list = '<ul>';\n                for (range in this.ranges) {\n                    list += '<li>' + range + '</li>';\n                }\n                list += '<li>' + this.locale.customRangeLabel + '</li>';\n                list += '</ul>';\n                this.container.find('.ranges ul').remove();\n                this.container.find('.ranges').prepend(list);\n            }\n\n            if (typeof callback === 'function') {\n                this.cb = callback;\n            }\n\n            if (!this.timePicker) {\n                this.startDate = this.startDate.startOf('day');\n                this.endDate = this.endDate.endOf('day');\n            }\n\n            if (this.singleDatePicker) {\n                this.opens = 'right';\n                this.container.addClass('single');\n                this.container.find('.calendar.right').show();\n                this.container.find('.calendar.left').hide();\n                if (!this.timePicker) {\n                    this.container.find('.ranges').hide();\n                } else {\n                    this.container.find('.ranges .daterangepicker_start_input, .ranges .daterangepicker_end_input').hide();\n                }\n                if (!this.container.find('.calendar.right').hasClass('single'))\n                    this.container.find('.calendar.right').addClass('single');\n            } else {\n                this.container.removeClass('single');\n                this.container.find('.calendar.right').removeClass('single');\n                this.container.find('.ranges').show();\n            }\n\n            this.oldStartDate = this.startDate.clone();\n            this.oldEndDate = this.endDate.clone();\n            this.oldChosenLabel = this.chosenLabel;\n\n            this.leftCalendar = {\n                month: moment([this.startDate.year(), this.startDate.month(), 1, this.startDate.hour(), this.startDate.minute(), this.startDate.second()]),\n                calendar: []\n            };\n\n            this.rightCalendar = {\n                month: moment([this.endDate.year(), this.endDate.month(), 1, this.endDate.hour(), this.endDate.minute(), this.endDate.second()]),\n                calendar: []\n            };\n\n            if (this.opens == 'right' || this.opens == 'center') {\n                //swap calendar positions\n                var first = this.container.find('.calendar.first');\n                var second = this.container.find('.calendar.second');\n\n                if (second.hasClass('single')) {\n                    second.removeClass('single');\n                    first.addClass('single');\n                }\n\n                first.removeClass('left').addClass('right');\n                second.removeClass('right').addClass('left');\n\n                if (this.singleDatePicker) {\n                    first.show();\n                    second.hide();\n                }\n            }\n\n            if (typeof options.ranges === 'undefined' && !this.singleDatePicker) {\n                this.container.addClass('show-calendar');\n            }\n\n            this.container.removeClass('opensleft opensright').addClass('opens' + this.opens);\n\n            this.updateView();\n            this.updateCalendars();\n\n            //apply CSS classes and labels to buttons\n            var c = this.container;\n            $.each(this.buttonClasses, function (idx, val) {\n                c.find('button').addClass(val);\n            });\n            this.container.find('.daterangepicker_start_input label').html(this.locale.fromLabel);\n            this.container.find('.daterangepicker_end_input label').html(this.locale.toLabel);\n            if (this.applyClass.length)\n                this.container.find('.applyBtn').addClass(this.applyClass);\n            if (this.cancelClass.length)\n                this.container.find('.cancelBtn').addClass(this.cancelClass);\n            this.container.find('.applyBtn').html(this.locale.applyLabel);\n            this.container.find('.cancelBtn').html(this.locale.cancelLabel);\n        },\n\n        setStartDate: function(startDate) {\n            if (typeof startDate === 'string')\n                this.startDate = moment(startDate, this.format).utcOffset(this.timeZone);\n\n            if (typeof startDate === 'object')\n                this.startDate = moment(startDate);\n\n            if (!this.timePicker)\n                this.startDate = this.startDate.startOf('day');\n\n            this.oldStartDate = this.startDate.clone();\n\n            this.updateView();\n            this.updateCalendars();\n            this.updateInputText();\n        },\n\n        setEndDate: function(endDate) {\n            if (typeof endDate === 'string')\n                this.endDate = moment(endDate, this.format).utcOffset(this.timeZone);\n\n            if (typeof endDate === 'object')\n                this.endDate = moment(endDate);\n\n            if (!this.timePicker)\n                this.endDate = this.endDate.endOf('day');\n\n            this.oldEndDate = this.endDate.clone();\n\n            this.updateView();\n            this.updateCalendars();\n            this.updateInputText();\n        },\n\n        updateView: function () {\n            this.leftCalendar.month.month(this.startDate.month()).year(this.startDate.year()).hour(this.startDate.hour()).minute(this.startDate.minute());\n            this.rightCalendar.month.month(this.endDate.month()).year(this.endDate.year()).hour(this.endDate.hour()).minute(this.endDate.minute());\n            this.updateFormInputs();\n        },\n\n        updateFormInputs: function () {\n            this.container.find('input[name=daterangepicker_start]').val(this.startDate.format(this.format));\n            this.container.find('input[name=daterangepicker_end]').val(this.endDate.format(this.format));\n\n            if (this.startDate.isSame(this.endDate) || this.startDate.isBefore(this.endDate)) {\n                this.container.find('button.applyBtn').removeAttr('disabled');\n            } else {\n                this.container.find('button.applyBtn').attr('disabled', 'disabled');\n            }\n        },\n\n        updateFromControl: function () {\n            if (!this.element.is('input')) return;\n            if (!this.element.val().length) return;\n\n            var dateString = this.element.val().split(this.separator),\n                start = null,\n                end = null;\n\n            if(dateString.length === 2) {\n                start = moment(dateString[0], this.format).utcOffset(this.timeZone);\n                end = moment(dateString[1], this.format).utcOffset(this.timeZone);\n            }\n\n            if (this.singleDatePicker || start === null || end === null) {\n                start = moment(this.element.val(), this.format).utcOffset(this.timeZone);\n                end = start;\n            }\n\n            if (end.isBefore(start)) return;\n\n            this.oldStartDate = this.startDate.clone();\n            this.oldEndDate = this.endDate.clone();\n\n            this.startDate = start;\n            this.endDate = end;\n\n            if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate))\n                this.notify();\n\n            this.updateCalendars();\n        },\n        \n        keydown: function (e) {\n            //hide on tab or enter\n        \tif ((e.keyCode === 9) || (e.keyCode === 13)) {\n        \t\tthis.hide();\n        \t}\n        },\n\n        notify: function () {\n            this.updateView();\n            this.cb(this.startDate, this.endDate, this.chosenLabel);\n        },\n\n        move: function () {\n            var parentOffset = { top: 0, left: 0 },\n            \tcontainerTop;\n            var parentRightEdge = $(window).width();\n            if (!this.parentEl.is('body')) {\n                parentOffset = {\n                    top: this.parentEl.offset().top - this.parentEl.scrollTop(),\n                    left: this.parentEl.offset().left - this.parentEl.scrollLeft()\n                };\n                parentRightEdge = this.parentEl[0].clientWidth + this.parentEl.offset().left;\n            }\n            \n            if (this.drops == 'up')\n            \tcontainerTop = this.element.offset().top - this.container.outerHeight() - parentOffset.top;\n            else\n            \tcontainerTop = this.element.offset().top + this.element.outerHeight() - parentOffset.top;\n            this.container[this.drops == 'up' ? 'addClass' : 'removeClass']('dropup');\n\n            if (this.opens == 'left') {\n                this.container.css({\n                    top: containerTop,\n                    right: parentRightEdge - this.element.offset().left - this.element.outerWidth(),\n                    left: 'auto'\n                });\n                if (this.container.offset().left < 0) {\n                    this.container.css({\n                        right: 'auto',\n                        left: 9\n                    });\n                }\n            } else if (this.opens == 'center') {\n                this.container.css({\n                    top: containerTop,\n                    left: this.element.offset().left - parentOffset.left + this.element.outerWidth() / 2\n                            - this.container.outerWidth() / 2,\n                    right: 'auto'\n                });\n                if (this.container.offset().left < 0) {\n                    this.container.css({\n                        right: 'auto',\n                        left: 9\n                    });\n                }\n            } else {\n                this.container.css({\n                    top: containerTop,\n                    left: this.element.offset().left - parentOffset.left,\n                    right: 'auto'\n                });\n                if (this.container.offset().left + this.container.outerWidth() > $(window).width()) {\n                    this.container.css({\n                        left: 'auto',\n                        right: 0\n                    });\n                }\n            }\n        },\n\n        toggle: function (e) {\n            if (this.element.hasClass('active')) {\n                this.hide();\n            } else {\n                this.show();\n            }\n        },\n\n        show: function (e) {\n            if (this.isShowing) return;\n\n            this.element.addClass('active');\n            this.container.show();\n            this.move();\n\n            // Create a click proxy that is private to this instance of datepicker, for unbinding\n            this._outsideClickProxy = $.proxy(function (e) { this.outsideClick(e); }, this);\n            // Bind global datepicker mousedown for hiding and\n            $(document)\n              .on('mousedown.daterangepicker', this._outsideClickProxy)\n              // also support mobile devices\n              .on('touchend.daterangepicker', this._outsideClickProxy)\n              // also explicitly play nice with Bootstrap dropdowns, which stopPropagation when clicking them\n              .on('click.daterangepicker', '[data-toggle=dropdown]', this._outsideClickProxy)\n              // and also close when focus changes to outside the picker (eg. tabbing between controls)\n              .on('focusin.daterangepicker', this._outsideClickProxy);\n\n            this.isShowing = true;\n            this.element.trigger('show.daterangepicker', this);\n        },\n\n        outsideClick: function (e) {\n            var target = $(e.target);\n            // if the page is clicked anywhere except within the daterangerpicker/button\n            // itself then call this.hide()\n            if (\n                // ie modal dialog fix\n                e.type == \"focusin\" ||\n                target.closest(this.element).length ||\n                target.closest(this.container).length ||\n                target.closest('.calendar-date').length\n                ) return;\n            this.hide();\n        },\n\n        hide: function (e) {\n            if (!this.isShowing) return;\n\n            $(document)\n              .off('.daterangepicker');\n\n            this.element.removeClass('active');\n            this.container.hide();\n\n            if (!this.startDate.isSame(this.oldStartDate) || !this.endDate.isSame(this.oldEndDate))\n                this.notify();\n\n            this.oldStartDate = this.startDate.clone();\n            this.oldEndDate = this.endDate.clone();\n\n            this.isShowing = false;\n            this.element.trigger('hide.daterangepicker', this);\n        },\n\n        enterRange: function (e) {\n            // mouse pointer has entered a range label\n            var label = e.target.innerHTML;\n            if (label == this.locale.customRangeLabel) {\n                this.updateView();\n            } else {\n                var dates = this.ranges[label];\n                this.container.find('input[name=daterangepicker_start]').val(dates[0].format(this.format));\n                this.container.find('input[name=daterangepicker_end]').val(dates[1].format(this.format));\n            }\n        },\n\n        showCalendars: function() {\n            this.container.addClass('show-calendar');\n            this.move();\n            this.element.trigger('showCalendar.daterangepicker', this);\n        },\n\n        hideCalendars: function() {\n            this.container.removeClass('show-calendar');\n            this.element.trigger('hideCalendar.daterangepicker', this);\n        },\n\n        // when a date is typed into the start to end date textboxes\n        inputsChanged: function (e) {\n            var el = $(e.target);\n            var date = moment(el.val(), this.format);\n            if (!date.isValid()) return;\n\n            var startDate, endDate;\n            if (el.attr('name') === 'daterangepicker_start') {\n                startDate = (false !== this.minDate && date.isBefore(this.minDate)) ? this.minDate : date;\n                endDate = this.endDate;\n            } else {\n                startDate = this.startDate;\n                endDate = (false !== this.maxDate && date.isAfter(this.maxDate)) ? this.maxDate : date;\n            }\n            this.setCustomDates(startDate, endDate);\n        },\n\n        inputsKeydown: function(e) {\n            if (e.keyCode === 13) {\n                this.inputsChanged(e);\n                this.notify();\n            }\n        },\n\n        updateInputText: function() {\n            if (this.element.is('input') && !this.singleDatePicker) {\n                this.element.val(this.startDate.format(this.format) + this.separator + this.endDate.format(this.format));\n                this.element.trigger('change');\n            } else if (this.element.is('input')) {\n                this.element.val(this.endDate.format(this.format));\n                this.element.trigger('change');\n            }\n        },\n\n        clickRange: function (e) {\n            var label = e.target.innerHTML;\n            this.chosenLabel = label;\n            if (label == this.locale.customRangeLabel) {\n                this.showCalendars();\n            } else {\n                var dates = this.ranges[label];\n\n                this.startDate = dates[0];\n                this.endDate = dates[1];\n\n                if (!this.timePicker) {\n                    this.startDate.startOf('day');\n                    this.endDate.endOf('day');\n                }\n\n                this.leftCalendar.month.month(this.startDate.month()).year(this.startDate.year()).hour(this.startDate.hour()).minute(this.startDate.minute());\n                this.rightCalendar.month.month(this.endDate.month()).year(this.endDate.year()).hour(this.endDate.hour()).minute(this.endDate.minute());\n                this.updateCalendars();\n\n                this.updateInputText();\n\n                this.hideCalendars();\n                this.hide();\n                this.element.trigger('apply.daterangepicker', this);\n            }\n        },\n\n        clickPrev: function (e) {\n            var cal = $(e.target).parents('.calendar');\n            if (cal.hasClass('left')) {\n                this.leftCalendar.month.subtract(1, 'month');\n            } else {\n                this.rightCalendar.month.subtract(1, 'month');\n            }\n            this.updateCalendars();\n        },\n\n        clickNext: function (e) {\n            var cal = $(e.target).parents('.calendar');\n            if (cal.hasClass('left')) {\n                this.leftCalendar.month.add(1, 'month');\n            } else {\n                this.rightCalendar.month.add(1, 'month');\n            }\n            this.updateCalendars();\n        },\n\n        hoverDate: function (e) {\n            var title = $(e.target).attr('data-title');\n            var row = title.substr(1, 1);\n            var col = title.substr(3, 1);\n            var cal = $(e.target).parents('.calendar');\n\n            if (cal.hasClass('left')) {\n                this.container.find('input[name=daterangepicker_start]').val(this.leftCalendar.calendar[row][col].format(this.format));\n            } else {\n                this.container.find('input[name=daterangepicker_end]').val(this.rightCalendar.calendar[row][col].format(this.format));\n            }\n        },\n\n        setCustomDates: function(startDate, endDate) {\n            this.chosenLabel = this.locale.customRangeLabel;\n            if (startDate.isAfter(endDate)) {\n                var difference = this.endDate.diff(this.startDate);\n                endDate = moment(startDate).add(difference, 'ms');\n                if (this.maxDate && endDate.isAfter(this.maxDate)) {\n                  endDate = this.maxDate.clone();\n                }\n            }\n            this.startDate = startDate;\n            this.endDate = endDate;\n\n            this.updateView();\n            this.updateCalendars();\n        },\n\n        clickDate: function (e) {\n            var title = $(e.target).attr('data-title');\n            var row = title.substr(1, 1);\n            var col = title.substr(3, 1);\n            var cal = $(e.target).parents('.calendar');\n\n            var startDate, endDate;\n            if (cal.hasClass('left')) {\n                startDate = this.leftCalendar.calendar[row][col];\n                endDate = this.endDate;\n                if (typeof this.dateLimit === 'object') {\n                    var maxDate = moment(startDate).add(this.dateLimit).startOf('day');\n                    if (endDate.isAfter(maxDate)) {\n                        endDate = maxDate;\n                    }\n                }\n            } else {\n                startDate = this.startDate;\n                endDate = this.rightCalendar.calendar[row][col];\n                if (typeof this.dateLimit === 'object') {\n                    var minDate = moment(endDate).subtract(this.dateLimit).startOf('day');\n                    if (startDate.isBefore(minDate)) {\n                        startDate = minDate;\n                    }\n                }\n            }\n\n            if (this.singleDatePicker && cal.hasClass('left')) {\n                endDate = startDate.clone();\n            } else if (this.singleDatePicker && cal.hasClass('right')) {\n                startDate = endDate.clone();\n            }\n\n            cal.find('td').removeClass('active');\n\n            $(e.target).addClass('active');\n\n            this.setCustomDates(startDate, endDate);\n\n            if (!this.timePicker)\n                endDate.endOf('day');\n\n            if (this.singleDatePicker && !this.timePicker)\n                this.clickApply();\n        },\n\n        clickApply: function (e) {\n            this.updateInputText();\n            this.hide();\n            this.element.trigger('apply.daterangepicker', this);\n        },\n\n        clickCancel: function (e) {\n            this.startDate = this.oldStartDate;\n            this.endDate = this.oldEndDate;\n            this.chosenLabel = this.oldChosenLabel;\n            this.updateView();\n            this.updateCalendars();\n            this.hide();\n            this.element.trigger('cancel.daterangepicker', this);\n        },\n\n        updateMonthYear: function (e) {\n            var isLeft = $(e.target).closest('.calendar').hasClass('left'),\n                leftOrRight = isLeft ? 'left' : 'right',\n                cal = this.container.find('.calendar.'+leftOrRight);\n\n            // Month must be Number for new moment versions\n            var month = parseInt(cal.find('.monthselect').val(), 10);\n            var year = cal.find('.yearselect').val();\n\n            if (!isLeft && !this.singleDatePicker) {\n                if (year < this.startDate.year() || (year == this.startDate.year() && month < this.startDate.month())) {\n                    month = this.startDate.month();\n                    year = this.startDate.year();\n                }\n            }\n\n            if (this.minDate) {\n                if (year < this.minDate.year() || (year == this.minDate.year() && month < this.minDate.month())) {\n                    month = this.minDate.month();\n                    year = this.minDate.year();\n                }\n            }\n\n            if (this.maxDate) {\n                if (year > this.maxDate.year() || (year == this.maxDate.year() && month > this.maxDate.month())) {\n                    month = this.maxDate.month();\n                    year = this.maxDate.year();\n                }\n            }\n\n\n            this[leftOrRight+'Calendar'].month.month(month).year(year);\n            this.updateCalendars();\n        },\n\n        updateTime: function(e) {\n\n            var cal = $(e.target).closest('.calendar'),\n                isLeft = cal.hasClass('left');\n\n            var hour = parseInt(cal.find('.hourselect').val(), 10);\n            var minute = parseInt(cal.find('.minuteselect').val(), 10);\n            var second = 0;\n\n            if (this.timePickerSeconds) {\n                second = parseInt(cal.find('.secondselect').val(), 10);\n            }\n\n            if (this.timePicker12Hour) {\n                var ampm = cal.find('.ampmselect').val();\n                if (ampm === 'PM' && hour < 12)\n                    hour += 12;\n                if (ampm === 'AM' && hour === 12)\n                    hour = 0;\n            }\n\n            if (isLeft) {\n                var start = this.startDate.clone();\n                start.hour(hour);\n                start.minute(minute);\n                start.second(second);\n                this.startDate = start;\n                this.leftCalendar.month.hour(hour).minute(minute).second(second);\n                if (this.singleDatePicker)\n                    this.endDate = start.clone();\n            } else {\n                var end = this.endDate.clone();\n                end.hour(hour);\n                end.minute(minute);\n                end.second(second);\n                this.endDate = end;\n                if (this.singleDatePicker)\n                    this.startDate = end.clone();\n                this.rightCalendar.month.hour(hour).minute(minute).second(second);\n            }\n\n            this.updateView();\n            this.updateCalendars();\n        },\n\n        updateCalendars: function () {\n            this.leftCalendar.calendar = this.buildCalendar(this.leftCalendar.month.month(), this.leftCalendar.month.year(), this.leftCalendar.month.hour(), this.leftCalendar.month.minute(), this.leftCalendar.month.second(), 'left');\n            this.rightCalendar.calendar = this.buildCalendar(this.rightCalendar.month.month(), this.rightCalendar.month.year(), this.rightCalendar.month.hour(), this.rightCalendar.month.minute(), this.rightCalendar.month.second(), 'right');\n            this.container.find('.calendar.left').empty().html(this.renderCalendar(this.leftCalendar.calendar, this.startDate, this.minDate, this.maxDate, 'left'));\n            this.container.find('.calendar.right').empty().html(this.renderCalendar(this.rightCalendar.calendar, this.endDate, this.singleDatePicker ? this.minDate : this.startDate, this.maxDate, 'right'));\n\n            this.container.find('.ranges li').removeClass('active');\n            var customRange = true;\n            var i = 0;\n            for (var range in this.ranges) {\n                if (this.timePicker) {\n                    if (this.startDate.isSame(this.ranges[range][0]) && this.endDate.isSame(this.ranges[range][1])) {\n                        customRange = false;\n                        this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')')\n                            .addClass('active').html();\n                    }\n                } else {\n                    //ignore times when comparing dates if time picker is not enabled\n                    if (this.startDate.format('YYYY-MM-DD') == this.ranges[range][0].format('YYYY-MM-DD') && this.endDate.format('YYYY-MM-DD') == this.ranges[range][1].format('YYYY-MM-DD')) {\n                        customRange = false;\n                        this.chosenLabel = this.container.find('.ranges li:eq(' + i + ')')\n                            .addClass('active').html();\n                    }\n                }\n                i++;\n            }\n            if (customRange) {\n                this.chosenLabel = this.container.find('.ranges li:last').addClass('active').html();\n                this.showCalendars();\n            }\n        },\n\n        buildCalendar: function (month, year, hour, minute, second, side) {\n            var daysInMonth = moment([year, month]).daysInMonth();\n            var firstDay = moment([year, month, 1]);\n            var lastDay = moment([year, month, daysInMonth]);\n            var lastMonth = moment(firstDay).subtract(1, 'month').month();\n            var lastYear = moment(firstDay).subtract(1, 'month').year();\n\n            var daysInLastMonth = moment([lastYear, lastMonth]).daysInMonth();\n\n            var dayOfWeek = firstDay.day();\n\n            var i;\n\n            //initialize a 6 rows x 7 columns array for the calendar\n            var calendar = [];\n            calendar.firstDay = firstDay;\n            calendar.lastDay = lastDay;\n\n            for (i = 0; i < 6; i++) {\n                calendar[i] = [];\n            }\n\n            //populate the calendar with date objects\n            var startDay = daysInLastMonth - dayOfWeek + this.locale.firstDay + 1;\n            if (startDay > daysInLastMonth)\n                startDay -= 7;\n\n            if (dayOfWeek == this.locale.firstDay)\n                startDay = daysInLastMonth - 6;\n\n            var curDate = moment([lastYear, lastMonth, startDay, 12, minute, second]).utcOffset(this.timeZone);\n\n            var col, row;\n            for (i = 0, col = 0, row = 0; i < 42; i++, col++, curDate = moment(curDate).add(24, 'hour')) {\n                if (i > 0 && col % 7 === 0) {\n                    col = 0;\n                    row++;\n                }\n                calendar[row][col] = curDate.clone().hour(hour);\n                curDate.hour(12);\n\n                if (this.minDate && calendar[row][col].format('YYYY-MM-DD') == this.minDate.format('YYYY-MM-DD') && calendar[row][col].isBefore(this.minDate) && side == 'left') {\n                    calendar[row][col] = this.minDate.clone();\n                }\n\n                if (this.maxDate && calendar[row][col].format('YYYY-MM-DD') == this.maxDate.format('YYYY-MM-DD') && calendar[row][col].isAfter(this.maxDate) && side == 'right') {\n                    calendar[row][col] = this.maxDate.clone();\n                }\n\n            }\n\n            return calendar;\n        },\n\n        renderDropdowns: function (selected, minDate, maxDate) {\n            var currentMonth = selected.month();\n            var currentYear = selected.year();\n            var maxYear = (maxDate && maxDate.year()) || (currentYear + 5);\n            var minYear = (minDate && minDate.year()) || (currentYear - 50);\n\n            var monthHtml = '<select class=\"monthselect\">';\n            var inMinYear = currentYear == minYear;\n            var inMaxYear = currentYear == maxYear;\n\n            for (var m = 0; m < 12; m++) {\n                if ((!inMinYear || m >= minDate.month()) && (!inMaxYear || m <= maxDate.month())) {\n                    monthHtml += \"<option value='\" + m + \"'\" +\n                        (m === currentMonth ? \" selected='selected'\" : \"\") +\n                        \">\" + this.locale.monthNames[m] + \"</option>\";\n                }\n            }\n            monthHtml += \"</select>\";\n\n            var yearHtml = '<select class=\"yearselect\">';\n\n            for (var y = minYear; y <= maxYear; y++) {\n                yearHtml += '<option value=\"' + y + '\"' +\n                    (y === currentYear ? ' selected=\"selected\"' : '') +\n                    '>' + y + '</option>';\n            }\n\n            yearHtml += '</select>';\n\n            return monthHtml + yearHtml;\n        },\n\n        renderCalendar: function (calendar, selected, minDate, maxDate, side) {\n\n            var html = '<div class=\"calendar-date\">';\n            html += '<table class=\"table-condensed\">';\n            html += '<thead>';\n            html += '<tr>';\n\n            // add empty cell for week number\n            if (this.showWeekNumbers)\n                html += '<th></th>';\n\n            if (!minDate || minDate.isBefore(calendar.firstDay)) {\n                html += '<th class=\"prev available\"><i class=\"fa fa-arrow-left icon icon-arrow-left glyphicon glyphicon-arrow-left\"></i></th>';\n            } else {\n                html += '<th></th>';\n            }\n\n            var dateHtml = this.locale.monthNames[calendar[1][1].month()] + calendar[1][1].format(\" YYYY\");\n\n            if (this.showDropdowns) {\n                dateHtml = this.renderDropdowns(calendar[1][1], minDate, maxDate);\n            }\n\n            html += '<th colspan=\"5\" class=\"month\">' + dateHtml + '</th>';\n            if (!maxDate || maxDate.isAfter(calendar.lastDay)) {\n                html += '<th class=\"next available\"><i class=\"fa fa-arrow-right icon icon-arrow-right glyphicon glyphicon-arrow-right\"></i></th>';\n            } else {\n                html += '<th></th>';\n            }\n\n            html += '</tr>';\n            html += '<tr>';\n\n            // add week number label\n            if (this.showWeekNumbers)\n                html += '<th class=\"week\">' + this.locale.weekLabel + '</th>';\n\n            $.each(this.locale.daysOfWeek, function (index, dayOfWeek) {\n                html += '<th>' + dayOfWeek + '</th>';\n            });\n\n            html += '</tr>';\n            html += '</thead>';\n            html += '<tbody>';\n\n            for (var row = 0; row < 6; row++) {\n                html += '<tr>';\n\n                // add week number\n                if (this.showWeekNumbers)\n                    html += '<td class=\"week\">' + calendar[row][0].week() + '</td>';\n\n                for (var col = 0; col < 7; col++) {\n                    var cname = 'available ';\n                    cname += (calendar[row][col].month() == calendar[1][1].month()) ? '' : 'off';\n\n                    if ((minDate && calendar[row][col].isBefore(minDate, 'day')) || (maxDate && calendar[row][col].isAfter(maxDate, 'day'))) {\n                        cname = ' off disabled ';\n                    } else if (calendar[row][col].format('YYYY-MM-DD') == selected.format('YYYY-MM-DD')) {\n                        cname += ' active ';\n                        if (calendar[row][col].format('YYYY-MM-DD') == this.startDate.format('YYYY-MM-DD')) {\n                            cname += ' start-date ';\n                        }\n                        if (calendar[row][col].format('YYYY-MM-DD') == this.endDate.format('YYYY-MM-DD')) {\n                            cname += ' end-date ';\n                        }\n                    } else if (calendar[row][col] >= this.startDate && calendar[row][col] <= this.endDate) {\n                        cname += ' in-range ';\n                        if (calendar[row][col].isSame(this.startDate)) { cname += ' start-date '; }\n                        if (calendar[row][col].isSame(this.endDate)) { cname += ' end-date '; }\n                    }\n\n                    var title = 'r' + row + 'c' + col;\n                    html += '<td class=\"' + cname.replace(/\\s+/g, ' ').replace(/^\\s?(.*?)\\s?$/, '$1') + '\" data-title=\"' + title + '\">' + calendar[row][col].date() + '</td>';\n                }\n                html += '</tr>';\n            }\n\n            html += '</tbody>';\n            html += '</table>';\n            html += '</div>';\n\n            var i;\n            if (this.timePicker) {\n\n                html += '<div class=\"calendar-time\">';\n                html += '<select class=\"hourselect\">';\n\n                // Disallow selections before the minDate or after the maxDate\n                var min_hour = 0;\n                var max_hour = 23;\n\n                if (minDate && (side == 'left' || this.singleDatePicker) && selected.format('YYYY-MM-DD') == minDate.format('YYYY-MM-DD')) {\n                    min_hour = minDate.hour();\n                    if (selected.hour() < min_hour)\n                        selected.hour(min_hour);\n                    if (this.timePicker12Hour && min_hour >= 12 && selected.hour() >= 12)\n                        min_hour -= 12;\n                    if (this.timePicker12Hour && min_hour == 12)\n                        min_hour = 1;\n                }\n\n                if (maxDate && (side == 'right' || this.singleDatePicker) && selected.format('YYYY-MM-DD') == maxDate.format('YYYY-MM-DD')) {\n                    max_hour = maxDate.hour();\n                    if (selected.hour() > max_hour)\n                        selected.hour(max_hour);\n                    if (this.timePicker12Hour && max_hour >= 12 && selected.hour() >= 12)\n                        max_hour -= 12;\n                }\n\n                var start = 0;\n                var end = 23;\n                var selected_hour = selected.hour();\n                if (this.timePicker12Hour) {\n                    start = 1;\n                    end = 12;\n                    if (selected_hour >= 12)\n                        selected_hour -= 12;\n                    if (selected_hour === 0)\n                        selected_hour = 12;\n                }\n\n                for (i = start; i <= end; i++) {\n\n                    if (i == selected_hour) {\n                        html += '<option value=\"' + i + '\" selected=\"selected\">' + i + '</option>';\n                    } else if (i < min_hour || i > max_hour) {\n                        html += '<option value=\"' + i + '\" disabled=\"disabled\" class=\"disabled\">' + i + '</option>';\n                    } else {\n                        html += '<option value=\"' + i + '\">' + i + '</option>';\n                    }\n                }\n\n                html += '</select> : ';\n\n                html += '<select class=\"minuteselect\">';\n\n                // Disallow selections before the minDate or after the maxDate\n                var min_minute = 0;\n                var max_minute = 59;\n\n                if (minDate && (side == 'left' || this.singleDatePicker) && selected.format('YYYY-MM-DD h A') == minDate.format('YYYY-MM-DD h A')) {\n                    min_minute = minDate.minute();\n                    if (selected.minute() < min_minute)\n                        selected.minute(min_minute);\n                }\n\n                if (maxDate && (side == 'right' || this.singleDatePicker) && selected.format('YYYY-MM-DD h A') == maxDate.format('YYYY-MM-DD h A')) {\n                    max_minute = maxDate.minute();\n                    if (selected.minute() > max_minute)\n                        selected.minute(max_minute);\n                }\n\n                for (i = 0; i < 60; i += this.timePickerIncrement) {\n                    var num = i;\n                    if (num < 10)\n                        num = '0' + num;\n                    if (i == selected.minute()) {\n                        html += '<option value=\"' + i + '\" selected=\"selected\">' + num + '</option>';\n                    } else if (i < min_minute || i > max_minute) {\n                        html += '<option value=\"' + i + '\" disabled=\"disabled\" class=\"disabled\">' + num + '</option>';\n                    } else {\n                        html += '<option value=\"' + i + '\">' + num + '</option>';\n                    }\n                }\n\n                html += '</select> ';\n\n                if (this.timePickerSeconds) {\n                    html += ': <select class=\"secondselect\">';\n\n                    for (i = 0; i < 60; i += this.timePickerIncrement) {\n                        var num = i;\n                        if (num < 10)\n                            num = '0' + num;\n                        if (i == selected.second()) {\n                            html += '<option value=\"' + i + '\" selected=\"selected\">' + num + '</option>';\n                        } else {\n                            html += '<option value=\"' + i + '\">' + num + '</option>';\n                        }\n                    }\n\n                    html += '</select>';\n                }\n\n                if (this.timePicker12Hour) {\n                    html += '<select class=\"ampmselect\">';\n\n                    // Disallow selection before the minDate or after the maxDate\n                    var am_html = '';\n                    var pm_html = '';\n\n                    if (minDate && (side == 'left' || this.singleDatePicker) && selected.format('YYYY-MM-DD') == minDate.format('YYYY-MM-DD') && minDate.hour() >= 12) {\n                        am_html = ' disabled=\"disabled\" class=\"disabled\"';\n                    }\n\n                    if (maxDate && (side == 'right' || this.singleDatePicker) && selected.format('YYYY-MM-DD') == maxDate.format('YYYY-MM-DD') && maxDate.hour() < 12) {\n                        pm_html = ' disabled=\"disabled\" class=\"disabled\"';\n                    }\n\n                    if (selected.hour() >= 12) {\n                        html += '<option value=\"AM\"' + am_html + '>AM</option><option value=\"PM\" selected=\"selected\"' + pm_html + '>PM</option>';\n                    } else {\n                        html += '<option value=\"AM\" selected=\"selected\"' + am_html + '>AM</option><option value=\"PM\"' + pm_html + '>PM</option>';\n                    }\n                    html += '</select>';\n                }\n\n                html += '</div>';\n\n            }\n\n            return html;\n\n        },\n\n        remove: function() {\n\n            this.container.remove();\n            this.element.off('.daterangepicker');\n            this.element.removeData('daterangepicker');\n\n        }\n\n    };\n\n    $.fn.daterangepicker = function (options, cb) {\n        this.each(function () {\n            var el = $(this);\n            if (el.data('daterangepicker'))\n                el.data('daterangepicker').remove();\n            el.data('daterangepicker', new DateRangePicker(el, options, cb));\n        });\n        return this;\n    };\n\n}));\n"
  },
  {
    "path": "public/static/plugins/daterangepicker/moment.js",
    "content": "//! moment.js\n//! version : 2.9.0\n//! authors : Tim Wood, Iskren Chernev, Moment.js contributors\n//! license : MIT\n//! momentjs.com\n\n(function (undefined) {\n    /************************************\n        Constants\n    ************************************/\n\n    var moment,\n        VERSION = '2.9.0',\n        // the global-scope this is NOT the global object in Node.js\n        globalScope = (typeof global !== 'undefined' && (typeof window === 'undefined' || window === global.window)) ? global : this,\n        oldGlobalMoment,\n        round = Math.round,\n        hasOwnProperty = Object.prototype.hasOwnProperty,\n        i,\n\n        YEAR = 0,\n        MONTH = 1,\n        DATE = 2,\n        HOUR = 3,\n        MINUTE = 4,\n        SECOND = 5,\n        MILLISECOND = 6,\n\n        // internal storage for locale config files\n        locales = {},\n\n        // extra moment internal properties (plugins register props here)\n        momentProperties = [],\n\n        // check for nodeJS\n        hasModule = (typeof module !== 'undefined' && module && module.exports),\n\n        // ASP.NET json date format regex\n        aspNetJsonRegex = /^\\/?Date\\((\\-?\\d+)/i,\n        aspNetTimeSpanJsonRegex = /(\\-)?(?:(\\d*)\\.)?(\\d+)\\:(\\d+)(?:\\:(\\d+)\\.?(\\d{3})?)?/,\n\n        // from http://docs.closure-library.googlecode.com/git/closure_goog_date_date.js.source.html\n        // somewhat more in line with 4.4.3.2 2004 spec, but allows decimal anywhere\n        isoDurationRegex = /^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/,\n\n        // format tokens\n        formattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Q|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,4}|x|X|zz?|ZZ?|.)/g,\n        localFormattingTokens = /(\\[[^\\[]*\\])|(\\\\)?(LTS|LT|LL?L?L?|l{1,4})/g,\n\n        // parsing token regexes\n        parseTokenOneOrTwoDigits = /\\d\\d?/, // 0 - 99\n        parseTokenOneToThreeDigits = /\\d{1,3}/, // 0 - 999\n        parseTokenOneToFourDigits = /\\d{1,4}/, // 0 - 9999\n        parseTokenOneToSixDigits = /[+\\-]?\\d{1,6}/, // -999,999 - 999,999\n        parseTokenDigits = /\\d+/, // nonzero number of digits\n        parseTokenWord = /[0-9]*['a-z\\u00A0-\\u05FF\\u0700-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFEF]+|[\\u0600-\\u06FF\\/]+(\\s*?[\\u0600-\\u06FF]+){1,2}/i, // any word (or two) characters or numbers including two/three word month in arabic.\n        parseTokenTimezone = /Z|[\\+\\-]\\d\\d:?\\d\\d/gi, // +00:00 -00:00 +0000 -0000 or Z\n        parseTokenT = /T/i, // T (ISO separator)\n        parseTokenOffsetMs = /[\\+\\-]?\\d+/, // 1234567890123\n        parseTokenTimestampMs = /[\\+\\-]?\\d+(\\.\\d{1,3})?/, // 123456789 123456789.123\n\n        //strict parsing regexes\n        parseTokenOneDigit = /\\d/, // 0 - 9\n        parseTokenTwoDigits = /\\d\\d/, // 00 - 99\n        parseTokenThreeDigits = /\\d{3}/, // 000 - 999\n        parseTokenFourDigits = /\\d{4}/, // 0000 - 9999\n        parseTokenSixDigits = /[+-]?\\d{6}/, // -999,999 - 999,999\n        parseTokenSignedNumber = /[+-]?\\d+/, // -inf - inf\n\n        // iso 8601 regex\n        // 0000-00-00 0000-W00 or 0000-W00-0 + T + 00 or 00:00 or 00:00:00 or 00:00:00.000 + +00:00 or +0000 or +00)\n        isoRegex = /^\\s*(?:[+-]\\d{6}|\\d{4})-(?:(\\d\\d-\\d\\d)|(W\\d\\d$)|(W\\d\\d-\\d)|(\\d\\d\\d))((T| )(\\d\\d(:\\d\\d(:\\d\\d(\\.\\d+)?)?)?)?([\\+\\-]\\d\\d(?::?\\d\\d)?|\\s*Z)?)?$/,\n\n        isoFormat = 'YYYY-MM-DDTHH:mm:ssZ',\n\n        isoDates = [\n            ['YYYYYY-MM-DD', /[+-]\\d{6}-\\d{2}-\\d{2}/],\n            ['YYYY-MM-DD', /\\d{4}-\\d{2}-\\d{2}/],\n            ['GGGG-[W]WW-E', /\\d{4}-W\\d{2}-\\d/],\n            ['GGGG-[W]WW', /\\d{4}-W\\d{2}/],\n            ['YYYY-DDD', /\\d{4}-\\d{3}/]\n        ],\n\n        // iso time formats and regexes\n        isoTimes = [\n            ['HH:mm:ss.SSSS', /(T| )\\d\\d:\\d\\d:\\d\\d\\.\\d+/],\n            ['HH:mm:ss', /(T| )\\d\\d:\\d\\d:\\d\\d/],\n            ['HH:mm', /(T| )\\d\\d:\\d\\d/],\n            ['HH', /(T| )\\d\\d/]\n        ],\n\n        // timezone chunker '+10:00' > ['10', '00'] or '-1530' > ['-', '15', '30']\n        parseTimezoneChunker = /([\\+\\-]|\\d\\d)/gi,\n\n        // getter and setter names\n        proxyGettersAndSetters = 'Date|Hours|Minutes|Seconds|Milliseconds'.split('|'),\n        unitMillisecondFactors = {\n            'Milliseconds' : 1,\n            'Seconds' : 1e3,\n            'Minutes' : 6e4,\n            'Hours' : 36e5,\n            'Days' : 864e5,\n            'Months' : 2592e6,\n            'Years' : 31536e6\n        },\n\n        unitAliases = {\n            ms : 'millisecond',\n            s : 'second',\n            m : 'minute',\n            h : 'hour',\n            d : 'day',\n            D : 'date',\n            w : 'week',\n            W : 'isoWeek',\n            M : 'month',\n            Q : 'quarter',\n            y : 'year',\n            DDD : 'dayOfYear',\n            e : 'weekday',\n            E : 'isoWeekday',\n            gg: 'weekYear',\n            GG: 'isoWeekYear'\n        },\n\n        camelFunctions = {\n            dayofyear : 'dayOfYear',\n            isoweekday : 'isoWeekday',\n            isoweek : 'isoWeek',\n            weekyear : 'weekYear',\n            isoweekyear : 'isoWeekYear'\n        },\n\n        // format function strings\n        formatFunctions = {},\n\n        // default relative time thresholds\n        relativeTimeThresholds = {\n            s: 45,  // seconds to minute\n            m: 45,  // minutes to hour\n            h: 22,  // hours to day\n            d: 26,  // days to month\n            M: 11   // months to year\n        },\n\n        // tokens to ordinalize and pad\n        ordinalizeTokens = 'DDD w W M D d'.split(' '),\n        paddedTokens = 'M D H h m s w W'.split(' '),\n\n        formatTokenFunctions = {\n            M    : function () {\n                return this.month() + 1;\n            },\n            MMM  : function (format) {\n                return this.localeData().monthsShort(this, format);\n            },\n            MMMM : function (format) {\n                return this.localeData().months(this, format);\n            },\n            D    : function () {\n                return this.date();\n            },\n            DDD  : function () {\n                return this.dayOfYear();\n            },\n            d    : function () {\n                return this.day();\n            },\n            dd   : function (format) {\n                return this.localeData().weekdaysMin(this, format);\n            },\n            ddd  : function (format) {\n                return this.localeData().weekdaysShort(this, format);\n            },\n            dddd : function (format) {\n                return this.localeData().weekdays(this, format);\n            },\n            w    : function () {\n                return this.week();\n            },\n            W    : function () {\n                return this.isoWeek();\n            },\n            YY   : function () {\n                return leftZeroFill(this.year() % 100, 2);\n            },\n            YYYY : function () {\n                return leftZeroFill(this.year(), 4);\n            },\n            YYYYY : function () {\n                return leftZeroFill(this.year(), 5);\n            },\n            YYYYYY : function () {\n                var y = this.year(), sign = y >= 0 ? '+' : '-';\n                return sign + leftZeroFill(Math.abs(y), 6);\n            },\n            gg   : function () {\n                return leftZeroFill(this.weekYear() % 100, 2);\n            },\n            gggg : function () {\n                return leftZeroFill(this.weekYear(), 4);\n            },\n            ggggg : function () {\n                return leftZeroFill(this.weekYear(), 5);\n            },\n            GG   : function () {\n                return leftZeroFill(this.isoWeekYear() % 100, 2);\n            },\n            GGGG : function () {\n                return leftZeroFill(this.isoWeekYear(), 4);\n            },\n            GGGGG : function () {\n                return leftZeroFill(this.isoWeekYear(), 5);\n            },\n            e : function () {\n                return this.weekday();\n            },\n            E : function () {\n                return this.isoWeekday();\n            },\n            a    : function () {\n                return this.localeData().meridiem(this.hours(), this.minutes(), true);\n            },\n            A    : function () {\n                return this.localeData().meridiem(this.hours(), this.minutes(), false);\n            },\n            H    : function () {\n                return this.hours();\n            },\n            h    : function () {\n                return this.hours() % 12 || 12;\n            },\n            m    : function () {\n                return this.minutes();\n            },\n            s    : function () {\n                return this.seconds();\n            },\n            S    : function () {\n                return toInt(this.milliseconds() / 100);\n            },\n            SS   : function () {\n                return leftZeroFill(toInt(this.milliseconds() / 10), 2);\n            },\n            SSS  : function () {\n                return leftZeroFill(this.milliseconds(), 3);\n            },\n            SSSS : function () {\n                return leftZeroFill(this.milliseconds(), 3);\n            },\n            Z    : function () {\n                var a = this.utcOffset(),\n                    b = '+';\n                if (a < 0) {\n                    a = -a;\n                    b = '-';\n                }\n                return b + leftZeroFill(toInt(a / 60), 2) + ':' + leftZeroFill(toInt(a) % 60, 2);\n            },\n            ZZ   : function () {\n                var a = this.utcOffset(),\n                    b = '+';\n                if (a < 0) {\n                    a = -a;\n                    b = '-';\n                }\n                return b + leftZeroFill(toInt(a / 60), 2) + leftZeroFill(toInt(a) % 60, 2);\n            },\n            z : function () {\n                return this.zoneAbbr();\n            },\n            zz : function () {\n                return this.zoneName();\n            },\n            x    : function () {\n                return this.valueOf();\n            },\n            X    : function () {\n                return this.unix();\n            },\n            Q : function () {\n                return this.quarter();\n            }\n        },\n\n        deprecations = {},\n\n        lists = ['months', 'monthsShort', 'weekdays', 'weekdaysShort', 'weekdaysMin'],\n\n        updateInProgress = false;\n\n    // Pick the first defined of two or three arguments. dfl comes from\n    // default.\n    function dfl(a, b, c) {\n        switch (arguments.length) {\n            case 2: return a != null ? a : b;\n            case 3: return a != null ? a : b != null ? b : c;\n            default: throw new Error('Implement me');\n        }\n    }\n\n    function hasOwnProp(a, b) {\n        return hasOwnProperty.call(a, b);\n    }\n\n    function defaultParsingFlags() {\n        // We need to deep clone this object, and es5 standard is not very\n        // helpful.\n        return {\n            empty : false,\n            unusedTokens : [],\n            unusedInput : [],\n            overflow : -2,\n            charsLeftOver : 0,\n            nullInput : false,\n            invalidMonth : null,\n            invalidFormat : false,\n            userInvalidated : false,\n            iso: false\n        };\n    }\n\n    function printMsg(msg) {\n        if (moment.suppressDeprecationWarnings === false &&\n                typeof console !== 'undefined' && console.warn) {\n            console.warn('Deprecation warning: ' + msg);\n        }\n    }\n\n    function deprecate(msg, fn) {\n        var firstTime = true;\n        return extend(function () {\n            if (firstTime) {\n                printMsg(msg);\n                firstTime = false;\n            }\n            return fn.apply(this, arguments);\n        }, fn);\n    }\n\n    function deprecateSimple(name, msg) {\n        if (!deprecations[name]) {\n            printMsg(msg);\n            deprecations[name] = true;\n        }\n    }\n\n    function padToken(func, count) {\n        return function (a) {\n            return leftZeroFill(func.call(this, a), count);\n        };\n    }\n    function ordinalizeToken(func, period) {\n        return function (a) {\n            return this.localeData().ordinal(func.call(this, a), period);\n        };\n    }\n\n    function monthDiff(a, b) {\n        // difference in months\n        var wholeMonthDiff = ((b.year() - a.year()) * 12) + (b.month() - a.month()),\n            // b is in (anchor - 1 month, anchor + 1 month)\n            anchor = a.clone().add(wholeMonthDiff, 'months'),\n            anchor2, adjust;\n\n        if (b - anchor < 0) {\n            anchor2 = a.clone().add(wholeMonthDiff - 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor - anchor2);\n        } else {\n            anchor2 = a.clone().add(wholeMonthDiff + 1, 'months');\n            // linear across the month\n            adjust = (b - anchor) / (anchor2 - anchor);\n        }\n\n        return -(wholeMonthDiff + adjust);\n    }\n\n    while (ordinalizeTokens.length) {\n        i = ordinalizeTokens.pop();\n        formatTokenFunctions[i + 'o'] = ordinalizeToken(formatTokenFunctions[i], i);\n    }\n    while (paddedTokens.length) {\n        i = paddedTokens.pop();\n        formatTokenFunctions[i + i] = padToken(formatTokenFunctions[i], 2);\n    }\n    formatTokenFunctions.DDDD = padToken(formatTokenFunctions.DDD, 3);\n\n\n    function meridiemFixWrap(locale, hour, meridiem) {\n        var isPm;\n\n        if (meridiem == null) {\n            // nothing to do\n            return hour;\n        }\n        if (locale.meridiemHour != null) {\n            return locale.meridiemHour(hour, meridiem);\n        } else if (locale.isPM != null) {\n            // Fallback\n            isPm = locale.isPM(meridiem);\n            if (isPm && hour < 12) {\n                hour += 12;\n            }\n            if (!isPm && hour === 12) {\n                hour = 0;\n            }\n            return hour;\n        } else {\n            // thie is not supposed to happen\n            return hour;\n        }\n    }\n\n    /************************************\n        Constructors\n    ************************************/\n\n    function Locale() {\n    }\n\n    // Moment prototype object\n    function Moment(config, skipOverflow) {\n        if (skipOverflow !== false) {\n            checkOverflow(config);\n        }\n        copyConfig(this, config);\n        this._d = new Date(+config._d);\n        // Prevent infinite loop in case updateOffset creates new moment\n        // objects.\n        if (updateInProgress === false) {\n            updateInProgress = true;\n            moment.updateOffset(this);\n            updateInProgress = false;\n        }\n    }\n\n    // Duration Constructor\n    function Duration(duration) {\n        var normalizedInput = normalizeObjectUnits(duration),\n            years = normalizedInput.year || 0,\n            quarters = normalizedInput.quarter || 0,\n            months = normalizedInput.month || 0,\n            weeks = normalizedInput.week || 0,\n            days = normalizedInput.day || 0,\n            hours = normalizedInput.hour || 0,\n            minutes = normalizedInput.minute || 0,\n            seconds = normalizedInput.second || 0,\n            milliseconds = normalizedInput.millisecond || 0;\n\n        // representation for dateAddRemove\n        this._milliseconds = +milliseconds +\n            seconds * 1e3 + // 1000\n            minutes * 6e4 + // 1000 * 60\n            hours * 36e5; // 1000 * 60 * 60\n        // Because of dateAddRemove treats 24 hours as different from a\n        // day when working around DST, we need to store them separately\n        this._days = +days +\n            weeks * 7;\n        // It is impossible translate months into days without knowing\n        // which months you are are talking about, so we have to store\n        // it separately.\n        this._months = +months +\n            quarters * 3 +\n            years * 12;\n\n        this._data = {};\n\n        this._locale = moment.localeData();\n\n        this._bubble();\n    }\n\n    /************************************\n        Helpers\n    ************************************/\n\n\n    function extend(a, b) {\n        for (var i in b) {\n            if (hasOwnProp(b, i)) {\n                a[i] = b[i];\n            }\n        }\n\n        if (hasOwnProp(b, 'toString')) {\n            a.toString = b.toString;\n        }\n\n        if (hasOwnProp(b, 'valueOf')) {\n            a.valueOf = b.valueOf;\n        }\n\n        return a;\n    }\n\n    function copyConfig(to, from) {\n        var i, prop, val;\n\n        if (typeof from._isAMomentObject !== 'undefined') {\n            to._isAMomentObject = from._isAMomentObject;\n        }\n        if (typeof from._i !== 'undefined') {\n            to._i = from._i;\n        }\n        if (typeof from._f !== 'undefined') {\n            to._f = from._f;\n        }\n        if (typeof from._l !== 'undefined') {\n            to._l = from._l;\n        }\n        if (typeof from._strict !== 'undefined') {\n            to._strict = from._strict;\n        }\n        if (typeof from._tzm !== 'undefined') {\n            to._tzm = from._tzm;\n        }\n        if (typeof from._isUTC !== 'undefined') {\n            to._isUTC = from._isUTC;\n        }\n        if (typeof from._offset !== 'undefined') {\n            to._offset = from._offset;\n        }\n        if (typeof from._pf !== 'undefined') {\n            to._pf = from._pf;\n        }\n        if (typeof from._locale !== 'undefined') {\n            to._locale = from._locale;\n        }\n\n        if (momentProperties.length > 0) {\n            for (i in momentProperties) {\n                prop = momentProperties[i];\n                val = from[prop];\n                if (typeof val !== 'undefined') {\n                    to[prop] = val;\n                }\n            }\n        }\n\n        return to;\n    }\n\n    function absRound(number) {\n        if (number < 0) {\n            return Math.ceil(number);\n        } else {\n            return Math.floor(number);\n        }\n    }\n\n    // left zero fill a number\n    // see http://jsperf.com/left-zero-filling for performance comparison\n    function leftZeroFill(number, targetLength, forceSign) {\n        var output = '' + Math.abs(number),\n            sign = number >= 0;\n\n        while (output.length < targetLength) {\n            output = '0' + output;\n        }\n        return (sign ? (forceSign ? '+' : '') : '-') + output;\n    }\n\n    function positiveMomentsDifference(base, other) {\n        var res = {milliseconds: 0, months: 0};\n\n        res.months = other.month() - base.month() +\n            (other.year() - base.year()) * 12;\n        if (base.clone().add(res.months, 'M').isAfter(other)) {\n            --res.months;\n        }\n\n        res.milliseconds = +other - +(base.clone().add(res.months, 'M'));\n\n        return res;\n    }\n\n    function momentsDifference(base, other) {\n        var res;\n        other = makeAs(other, base);\n        if (base.isBefore(other)) {\n            res = positiveMomentsDifference(base, other);\n        } else {\n            res = positiveMomentsDifference(other, base);\n            res.milliseconds = -res.milliseconds;\n            res.months = -res.months;\n        }\n\n        return res;\n    }\n\n    // TODO: remove 'name' arg after deprecation is removed\n    function createAdder(direction, name) {\n        return function (val, period) {\n            var dur, tmp;\n            //invert the arguments, but complain about it\n            if (period !== null && !isNaN(+period)) {\n                deprecateSimple(name, 'moment().' + name  + '(period, number) is deprecated. Please use moment().' + name + '(number, period).');\n                tmp = val; val = period; period = tmp;\n            }\n\n            val = typeof val === 'string' ? +val : val;\n            dur = moment.duration(val, period);\n            addOrSubtractDurationFromMoment(this, dur, direction);\n            return this;\n        };\n    }\n\n    function addOrSubtractDurationFromMoment(mom, duration, isAdding, updateOffset) {\n        var milliseconds = duration._milliseconds,\n            days = duration._days,\n            months = duration._months;\n        updateOffset = updateOffset == null ? true : updateOffset;\n\n        if (milliseconds) {\n            mom._d.setTime(+mom._d + milliseconds * isAdding);\n        }\n        if (days) {\n            rawSetter(mom, 'Date', rawGetter(mom, 'Date') + days * isAdding);\n        }\n        if (months) {\n            rawMonthSetter(mom, rawGetter(mom, 'Month') + months * isAdding);\n        }\n        if (updateOffset) {\n            moment.updateOffset(mom, days || months);\n        }\n    }\n\n    // check if is an array\n    function isArray(input) {\n        return Object.prototype.toString.call(input) === '[object Array]';\n    }\n\n    function isDate(input) {\n        return Object.prototype.toString.call(input) === '[object Date]' ||\n            input instanceof Date;\n    }\n\n    // compare two arrays, return the number of differences\n    function compareArrays(array1, array2, dontConvert) {\n        var len = Math.min(array1.length, array2.length),\n            lengthDiff = Math.abs(array1.length - array2.length),\n            diffs = 0,\n            i;\n        for (i = 0; i < len; i++) {\n            if ((dontConvert && array1[i] !== array2[i]) ||\n                (!dontConvert && toInt(array1[i]) !== toInt(array2[i]))) {\n                diffs++;\n            }\n        }\n        return diffs + lengthDiff;\n    }\n\n    function normalizeUnits(units) {\n        if (units) {\n            var lowered = units.toLowerCase().replace(/(.)s$/, '$1');\n            units = unitAliases[units] || camelFunctions[lowered] || lowered;\n        }\n        return units;\n    }\n\n    function normalizeObjectUnits(inputObject) {\n        var normalizedInput = {},\n            normalizedProp,\n            prop;\n\n        for (prop in inputObject) {\n            if (hasOwnProp(inputObject, prop)) {\n                normalizedProp = normalizeUnits(prop);\n                if (normalizedProp) {\n                    normalizedInput[normalizedProp] = inputObject[prop];\n                }\n            }\n        }\n\n        return normalizedInput;\n    }\n\n    function makeList(field) {\n        var count, setter;\n\n        if (field.indexOf('week') === 0) {\n            count = 7;\n            setter = 'day';\n        }\n        else if (field.indexOf('month') === 0) {\n            count = 12;\n            setter = 'month';\n        }\n        else {\n            return;\n        }\n\n        moment[field] = function (format, index) {\n            var i, getter,\n                method = moment._locale[field],\n                results = [];\n\n            if (typeof format === 'number') {\n                index = format;\n                format = undefined;\n            }\n\n            getter = function (i) {\n                var m = moment().utc().set(setter, i);\n                return method.call(moment._locale, m, format || '');\n            };\n\n            if (index != null) {\n                return getter(index);\n            }\n            else {\n                for (i = 0; i < count; i++) {\n                    results.push(getter(i));\n                }\n                return results;\n            }\n        };\n    }\n\n    function toInt(argumentForCoercion) {\n        var coercedNumber = +argumentForCoercion,\n            value = 0;\n\n        if (coercedNumber !== 0 && isFinite(coercedNumber)) {\n            if (coercedNumber >= 0) {\n                value = Math.floor(coercedNumber);\n            } else {\n                value = Math.ceil(coercedNumber);\n            }\n        }\n\n        return value;\n    }\n\n    function daysInMonth(year, month) {\n        return new Date(Date.UTC(year, month + 1, 0)).getUTCDate();\n    }\n\n    function weeksInYear(year, dow, doy) {\n        return weekOfYear(moment([year, 11, 31 + dow - doy]), dow, doy).week;\n    }\n\n    function daysInYear(year) {\n        return isLeapYear(year) ? 366 : 365;\n    }\n\n    function isLeapYear(year) {\n        return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n    }\n\n    function checkOverflow(m) {\n        var overflow;\n        if (m._a && m._pf.overflow === -2) {\n            overflow =\n                m._a[MONTH] < 0 || m._a[MONTH] > 11 ? MONTH :\n                m._a[DATE] < 1 || m._a[DATE] > daysInMonth(m._a[YEAR], m._a[MONTH]) ? DATE :\n                m._a[HOUR] < 0 || m._a[HOUR] > 24 ||\n                    (m._a[HOUR] === 24 && (m._a[MINUTE] !== 0 ||\n                                           m._a[SECOND] !== 0 ||\n                                           m._a[MILLISECOND] !== 0)) ? HOUR :\n                m._a[MINUTE] < 0 || m._a[MINUTE] > 59 ? MINUTE :\n                m._a[SECOND] < 0 || m._a[SECOND] > 59 ? SECOND :\n                m._a[MILLISECOND] < 0 || m._a[MILLISECOND] > 999 ? MILLISECOND :\n                -1;\n\n            if (m._pf._overflowDayOfYear && (overflow < YEAR || overflow > DATE)) {\n                overflow = DATE;\n            }\n\n            m._pf.overflow = overflow;\n        }\n    }\n\n    function isValid(m) {\n        if (m._isValid == null) {\n            m._isValid = !isNaN(m._d.getTime()) &&\n                m._pf.overflow < 0 &&\n                !m._pf.empty &&\n                !m._pf.invalidMonth &&\n                !m._pf.nullInput &&\n                !m._pf.invalidFormat &&\n                !m._pf.userInvalidated;\n\n            if (m._strict) {\n                m._isValid = m._isValid &&\n                    m._pf.charsLeftOver === 0 &&\n                    m._pf.unusedTokens.length === 0 &&\n                    m._pf.bigHour === undefined;\n            }\n        }\n        return m._isValid;\n    }\n\n    function normalizeLocale(key) {\n        return key ? key.toLowerCase().replace('_', '-') : key;\n    }\n\n    // pick the locale from the array\n    // try ['en-au', 'en-gb'] as 'en-au', 'en-gb', 'en', as in move through the list trying each\n    // substring from most specific to least, but move to the next array item if it's a more specific variant than the current root\n    function chooseLocale(names) {\n        var i = 0, j, next, locale, split;\n\n        while (i < names.length) {\n            split = normalizeLocale(names[i]).split('-');\n            j = split.length;\n            next = normalizeLocale(names[i + 1]);\n            next = next ? next.split('-') : null;\n            while (j > 0) {\n                locale = loadLocale(split.slice(0, j).join('-'));\n                if (locale) {\n                    return locale;\n                }\n                if (next && next.length >= j && compareArrays(split, next, true) >= j - 1) {\n                    //the next array item is better than a shallower substring of this one\n                    break;\n                }\n                j--;\n            }\n            i++;\n        }\n        return null;\n    }\n\n    function loadLocale(name) {\n        var oldLocale = null;\n        if (!locales[name] && hasModule) {\n            try {\n                oldLocale = moment.locale();\n                require('./locale/' + name);\n                // because defineLocale currently also sets the global locale, we want to undo that for lazy loaded locales\n                moment.locale(oldLocale);\n            } catch (e) { }\n        }\n        return locales[name];\n    }\n\n    // Return a moment from input, that is local/utc/utcOffset equivalent to\n    // model.\n    function makeAs(input, model) {\n        var res, diff;\n        if (model._isUTC) {\n            res = model.clone();\n            diff = (moment.isMoment(input) || isDate(input) ?\n                    +input : +moment(input)) - (+res);\n            // Use low-level api, because this fn is low-level api.\n            res._d.setTime(+res._d + diff);\n            moment.updateOffset(res, false);\n            return res;\n        } else {\n            return moment(input).local();\n        }\n    }\n\n    /************************************\n        Locale\n    ************************************/\n\n\n    extend(Locale.prototype, {\n\n        set : function (config) {\n            var prop, i;\n            for (i in config) {\n                prop = config[i];\n                if (typeof prop === 'function') {\n                    this[i] = prop;\n                } else {\n                    this['_' + i] = prop;\n                }\n            }\n            // Lenient ordinal parsing accepts just a number in addition to\n            // number + (possibly) stuff coming from _ordinalParseLenient.\n            this._ordinalParseLenient = new RegExp(this._ordinalParse.source + '|' + /\\d{1,2}/.source);\n        },\n\n        _months : 'January_February_March_April_May_June_July_August_September_October_November_December'.split('_'),\n        months : function (m) {\n            return this._months[m.month()];\n        },\n\n        _monthsShort : 'Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec'.split('_'),\n        monthsShort : function (m) {\n            return this._monthsShort[m.month()];\n        },\n\n        monthsParse : function (monthName, format, strict) {\n            var i, mom, regex;\n\n            if (!this._monthsParse) {\n                this._monthsParse = [];\n                this._longMonthsParse = [];\n                this._shortMonthsParse = [];\n            }\n\n            for (i = 0; i < 12; i++) {\n                // make the regex if we don't have it already\n                mom = moment.utc([2000, i]);\n                if (strict && !this._longMonthsParse[i]) {\n                    this._longMonthsParse[i] = new RegExp('^' + this.months(mom, '').replace('.', '') + '$', 'i');\n                    this._shortMonthsParse[i] = new RegExp('^' + this.monthsShort(mom, '').replace('.', '') + '$', 'i');\n                }\n                if (!strict && !this._monthsParse[i]) {\n                    regex = '^' + this.months(mom, '') + '|^' + this.monthsShort(mom, '');\n                    this._monthsParse[i] = new RegExp(regex.replace('.', ''), 'i');\n                }\n                // test the regex\n                if (strict && format === 'MMMM' && this._longMonthsParse[i].test(monthName)) {\n                    return i;\n                } else if (strict && format === 'MMM' && this._shortMonthsParse[i].test(monthName)) {\n                    return i;\n                } else if (!strict && this._monthsParse[i].test(monthName)) {\n                    return i;\n                }\n            }\n        },\n\n        _weekdays : 'Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday'.split('_'),\n        weekdays : function (m) {\n            return this._weekdays[m.day()];\n        },\n\n        _weekdaysShort : 'Sun_Mon_Tue_Wed_Thu_Fri_Sat'.split('_'),\n        weekdaysShort : function (m) {\n            return this._weekdaysShort[m.day()];\n        },\n\n        _weekdaysMin : 'Su_Mo_Tu_We_Th_Fr_Sa'.split('_'),\n        weekdaysMin : function (m) {\n            return this._weekdaysMin[m.day()];\n        },\n\n        weekdaysParse : function (weekdayName) {\n            var i, mom, regex;\n\n            if (!this._weekdaysParse) {\n                this._weekdaysParse = [];\n            }\n\n            for (i = 0; i < 7; i++) {\n                // make the regex if we don't have it already\n                if (!this._weekdaysParse[i]) {\n                    mom = moment([2000, 1]).day(i);\n                    regex = '^' + this.weekdays(mom, '') + '|^' + this.weekdaysShort(mom, '') + '|^' + this.weekdaysMin(mom, '');\n                    this._weekdaysParse[i] = new RegExp(regex.replace('.', ''), 'i');\n                }\n                // test the regex\n                if (this._weekdaysParse[i].test(weekdayName)) {\n                    return i;\n                }\n            }\n        },\n\n        _longDateFormat : {\n            LTS : 'h:mm:ss A',\n            LT : 'h:mm A',\n            L : 'MM/DD/YYYY',\n            LL : 'MMMM D, YYYY',\n            LLL : 'MMMM D, YYYY LT',\n            LLLL : 'dddd, MMMM D, YYYY LT'\n        },\n        longDateFormat : function (key) {\n            var output = this._longDateFormat[key];\n            if (!output && this._longDateFormat[key.toUpperCase()]) {\n                output = this._longDateFormat[key.toUpperCase()].replace(/MMMM|MM|DD|dddd/g, function (val) {\n                    return val.slice(1);\n                });\n                this._longDateFormat[key] = output;\n            }\n            return output;\n        },\n\n        isPM : function (input) {\n            // IE8 Quirks Mode & IE7 Standards Mode do not allow accessing strings like arrays\n            // Using charAt should be more compatible.\n            return ((input + '').toLowerCase().charAt(0) === 'p');\n        },\n\n        _meridiemParse : /[ap]\\.?m?\\.?/i,\n        meridiem : function (hours, minutes, isLower) {\n            if (hours > 11) {\n                return isLower ? 'pm' : 'PM';\n            } else {\n                return isLower ? 'am' : 'AM';\n            }\n        },\n\n\n        _calendar : {\n            sameDay : '[Today at] LT',\n            nextDay : '[Tomorrow at] LT',\n            nextWeek : 'dddd [at] LT',\n            lastDay : '[Yesterday at] LT',\n            lastWeek : '[Last] dddd [at] LT',\n            sameElse : 'L'\n        },\n        calendar : function (key, mom, now) {\n            var output = this._calendar[key];\n            return typeof output === 'function' ? output.apply(mom, [now]) : output;\n        },\n\n        _relativeTime : {\n            future : 'in %s',\n            past : '%s ago',\n            s : 'a few seconds',\n            m : 'a minute',\n            mm : '%d minutes',\n            h : 'an hour',\n            hh : '%d hours',\n            d : 'a day',\n            dd : '%d days',\n            M : 'a month',\n            MM : '%d months',\n            y : 'a year',\n            yy : '%d years'\n        },\n\n        relativeTime : function (number, withoutSuffix, string, isFuture) {\n            var output = this._relativeTime[string];\n            return (typeof output === 'function') ?\n                output(number, withoutSuffix, string, isFuture) :\n                output.replace(/%d/i, number);\n        },\n\n        pastFuture : function (diff, output) {\n            var format = this._relativeTime[diff > 0 ? 'future' : 'past'];\n            return typeof format === 'function' ? format(output) : format.replace(/%s/i, output);\n        },\n\n        ordinal : function (number) {\n            return this._ordinal.replace('%d', number);\n        },\n        _ordinal : '%d',\n        _ordinalParse : /\\d{1,2}/,\n\n        preparse : function (string) {\n            return string;\n        },\n\n        postformat : function (string) {\n            return string;\n        },\n\n        week : function (mom) {\n            return weekOfYear(mom, this._week.dow, this._week.doy).week;\n        },\n\n        _week : {\n            dow : 0, // Sunday is the first day of the week.\n            doy : 6  // The week that contains Jan 1st is the first week of the year.\n        },\n\n        firstDayOfWeek : function () {\n            return this._week.dow;\n        },\n\n        firstDayOfYear : function () {\n            return this._week.doy;\n        },\n\n        _invalidDate: 'Invalid date',\n        invalidDate: function () {\n            return this._invalidDate;\n        }\n    });\n\n    /************************************\n        Formatting\n    ************************************/\n\n\n    function removeFormattingTokens(input) {\n        if (input.match(/\\[[\\s\\S]/)) {\n            return input.replace(/^\\[|\\]$/g, '');\n        }\n        return input.replace(/\\\\/g, '');\n    }\n\n    function makeFormatFunction(format) {\n        var array = format.match(formattingTokens), i, length;\n\n        for (i = 0, length = array.length; i < length; i++) {\n            if (formatTokenFunctions[array[i]]) {\n                array[i] = formatTokenFunctions[array[i]];\n            } else {\n                array[i] = removeFormattingTokens(array[i]);\n            }\n        }\n\n        return function (mom) {\n            var output = '';\n            for (i = 0; i < length; i++) {\n                output += array[i] instanceof Function ? array[i].call(mom, format) : array[i];\n            }\n            return output;\n        };\n    }\n\n    // format date using native date object\n    function formatMoment(m, format) {\n        if (!m.isValid()) {\n            return m.localeData().invalidDate();\n        }\n\n        format = expandFormat(format, m.localeData());\n\n        if (!formatFunctions[format]) {\n            formatFunctions[format] = makeFormatFunction(format);\n        }\n\n        return formatFunctions[format](m);\n    }\n\n    function expandFormat(format, locale) {\n        var i = 5;\n\n        function replaceLongDateFormatTokens(input) {\n            return locale.longDateFormat(input) || input;\n        }\n\n        localFormattingTokens.lastIndex = 0;\n        while (i >= 0 && localFormattingTokens.test(format)) {\n            format = format.replace(localFormattingTokens, replaceLongDateFormatTokens);\n            localFormattingTokens.lastIndex = 0;\n            i -= 1;\n        }\n\n        return format;\n    }\n\n\n    /************************************\n        Parsing\n    ************************************/\n\n\n    // get the regex to find the next token\n    function getParseRegexForToken(token, config) {\n        var a, strict = config._strict;\n        switch (token) {\n        case 'Q':\n            return parseTokenOneDigit;\n        case 'DDDD':\n            return parseTokenThreeDigits;\n        case 'YYYY':\n        case 'GGGG':\n        case 'gggg':\n            return strict ? parseTokenFourDigits : parseTokenOneToFourDigits;\n        case 'Y':\n        case 'G':\n        case 'g':\n            return parseTokenSignedNumber;\n        case 'YYYYYY':\n        case 'YYYYY':\n        case 'GGGGG':\n        case 'ggggg':\n            return strict ? parseTokenSixDigits : parseTokenOneToSixDigits;\n        case 'S':\n            if (strict) {\n                return parseTokenOneDigit;\n            }\n            /* falls through */\n        case 'SS':\n            if (strict) {\n                return parseTokenTwoDigits;\n            }\n            /* falls through */\n        case 'SSS':\n            if (strict) {\n                return parseTokenThreeDigits;\n            }\n            /* falls through */\n        case 'DDD':\n            return parseTokenOneToThreeDigits;\n        case 'MMM':\n        case 'MMMM':\n        case 'dd':\n        case 'ddd':\n        case 'dddd':\n            return parseTokenWord;\n        case 'a':\n        case 'A':\n            return config._locale._meridiemParse;\n        case 'x':\n            return parseTokenOffsetMs;\n        case 'X':\n            return parseTokenTimestampMs;\n        case 'Z':\n        case 'ZZ':\n            return parseTokenTimezone;\n        case 'T':\n            return parseTokenT;\n        case 'SSSS':\n            return parseTokenDigits;\n        case 'MM':\n        case 'DD':\n        case 'YY':\n        case 'GG':\n        case 'gg':\n        case 'HH':\n        case 'hh':\n        case 'mm':\n        case 'ss':\n        case 'ww':\n        case 'WW':\n            return strict ? parseTokenTwoDigits : parseTokenOneOrTwoDigits;\n        case 'M':\n        case 'D':\n        case 'd':\n        case 'H':\n        case 'h':\n        case 'm':\n        case 's':\n        case 'w':\n        case 'W':\n        case 'e':\n        case 'E':\n            return parseTokenOneOrTwoDigits;\n        case 'Do':\n            return strict ? config._locale._ordinalParse : config._locale._ordinalParseLenient;\n        default :\n            a = new RegExp(regexpEscape(unescapeFormat(token.replace('\\\\', '')), 'i'));\n            return a;\n        }\n    }\n\n    function utcOffsetFromString(string) {\n        string = string || '';\n        var possibleTzMatches = (string.match(parseTokenTimezone) || []),\n            tzChunk = possibleTzMatches[possibleTzMatches.length - 1] || [],\n            parts = (tzChunk + '').match(parseTimezoneChunker) || ['-', 0, 0],\n            minutes = +(parts[1] * 60) + toInt(parts[2]);\n\n        return parts[0] === '+' ? minutes : -minutes;\n    }\n\n    // function to convert string input to date\n    function addTimeToArrayFromToken(token, input, config) {\n        var a, datePartArray = config._a;\n\n        switch (token) {\n        // QUARTER\n        case 'Q':\n            if (input != null) {\n                datePartArray[MONTH] = (toInt(input) - 1) * 3;\n            }\n            break;\n        // MONTH\n        case 'M' : // fall through to MM\n        case 'MM' :\n            if (input != null) {\n                datePartArray[MONTH] = toInt(input) - 1;\n            }\n            break;\n        case 'MMM' : // fall through to MMMM\n        case 'MMMM' :\n            a = config._locale.monthsParse(input, token, config._strict);\n            // if we didn't find a month name, mark the date as invalid.\n            if (a != null) {\n                datePartArray[MONTH] = a;\n            } else {\n                config._pf.invalidMonth = input;\n            }\n            break;\n        // DAY OF MONTH\n        case 'D' : // fall through to DD\n        case 'DD' :\n            if (input != null) {\n                datePartArray[DATE] = toInt(input);\n            }\n            break;\n        case 'Do' :\n            if (input != null) {\n                datePartArray[DATE] = toInt(parseInt(\n                            input.match(/\\d{1,2}/)[0], 10));\n            }\n            break;\n        // DAY OF YEAR\n        case 'DDD' : // fall through to DDDD\n        case 'DDDD' :\n            if (input != null) {\n                config._dayOfYear = toInt(input);\n            }\n\n            break;\n        // YEAR\n        case 'YY' :\n            datePartArray[YEAR] = moment.parseTwoDigitYear(input);\n            break;\n        case 'YYYY' :\n        case 'YYYYY' :\n        case 'YYYYYY' :\n            datePartArray[YEAR] = toInt(input);\n            break;\n        // AM / PM\n        case 'a' : // fall through to A\n        case 'A' :\n            config._meridiem = input;\n            // config._isPm = config._locale.isPM(input);\n            break;\n        // HOUR\n        case 'h' : // fall through to hh\n        case 'hh' :\n            config._pf.bigHour = true;\n            /* falls through */\n        case 'H' : // fall through to HH\n        case 'HH' :\n            datePartArray[HOUR] = toInt(input);\n            break;\n        // MINUTE\n        case 'm' : // fall through to mm\n        case 'mm' :\n            datePartArray[MINUTE] = toInt(input);\n            break;\n        // SECOND\n        case 's' : // fall through to ss\n        case 'ss' :\n            datePartArray[SECOND] = toInt(input);\n            break;\n        // MILLISECOND\n        case 'S' :\n        case 'SS' :\n        case 'SSS' :\n        case 'SSSS' :\n            datePartArray[MILLISECOND] = toInt(('0.' + input) * 1000);\n            break;\n        // UNIX OFFSET (MILLISECONDS)\n        case 'x':\n            config._d = new Date(toInt(input));\n            break;\n        // UNIX TIMESTAMP WITH MS\n        case 'X':\n            config._d = new Date(parseFloat(input) * 1000);\n            break;\n        // TIMEZONE\n        case 'Z' : // fall through to ZZ\n        case 'ZZ' :\n            config._useUTC = true;\n            config._tzm = utcOffsetFromString(input);\n            break;\n        // WEEKDAY - human\n        case 'dd':\n        case 'ddd':\n        case 'dddd':\n            a = config._locale.weekdaysParse(input);\n            // if we didn't get a weekday name, mark the date as invalid\n            if (a != null) {\n                config._w = config._w || {};\n                config._w['d'] = a;\n            } else {\n                config._pf.invalidWeekday = input;\n            }\n            break;\n        // WEEK, WEEK DAY - numeric\n        case 'w':\n        case 'ww':\n        case 'W':\n        case 'WW':\n        case 'd':\n        case 'e':\n        case 'E':\n            token = token.substr(0, 1);\n            /* falls through */\n        case 'gggg':\n        case 'GGGG':\n        case 'GGGGG':\n            token = token.substr(0, 2);\n            if (input) {\n                config._w = config._w || {};\n                config._w[token] = toInt(input);\n            }\n            break;\n        case 'gg':\n        case 'GG':\n            config._w = config._w || {};\n            config._w[token] = moment.parseTwoDigitYear(input);\n        }\n    }\n\n    function dayOfYearFromWeekInfo(config) {\n        var w, weekYear, week, weekday, dow, doy, temp;\n\n        w = config._w;\n        if (w.GG != null || w.W != null || w.E != null) {\n            dow = 1;\n            doy = 4;\n\n            // TODO: We need to take the current isoWeekYear, but that depends on\n            // how we interpret now (local, utc, fixed offset). So create\n            // a now version of current config (take local/utc/offset flags, and\n            // create now).\n            weekYear = dfl(w.GG, config._a[YEAR], weekOfYear(moment(), 1, 4).year);\n            week = dfl(w.W, 1);\n            weekday = dfl(w.E, 1);\n        } else {\n            dow = config._locale._week.dow;\n            doy = config._locale._week.doy;\n\n            weekYear = dfl(w.gg, config._a[YEAR], weekOfYear(moment(), dow, doy).year);\n            week = dfl(w.w, 1);\n\n            if (w.d != null) {\n                // weekday -- low day numbers are considered next week\n                weekday = w.d;\n                if (weekday < dow) {\n                    ++week;\n                }\n            } else if (w.e != null) {\n                // local weekday -- counting starts from begining of week\n                weekday = w.e + dow;\n            } else {\n                // default to begining of week\n                weekday = dow;\n            }\n        }\n        temp = dayOfYearFromWeeks(weekYear, week, weekday, doy, dow);\n\n        config._a[YEAR] = temp.year;\n        config._dayOfYear = temp.dayOfYear;\n    }\n\n    // convert an array to a date.\n    // the array should mirror the parameters below\n    // note: all values past the year are optional and will default to the lowest possible value.\n    // [year, month, day , hour, minute, second, millisecond]\n    function dateFromConfig(config) {\n        var i, date, input = [], currentDate, yearToUse;\n\n        if (config._d) {\n            return;\n        }\n\n        currentDate = currentDateArray(config);\n\n        //compute day of the year from weeks and weekdays\n        if (config._w && config._a[DATE] == null && config._a[MONTH] == null) {\n            dayOfYearFromWeekInfo(config);\n        }\n\n        //if the day of the year is set, figure out what it is\n        if (config._dayOfYear) {\n            yearToUse = dfl(config._a[YEAR], currentDate[YEAR]);\n\n            if (config._dayOfYear > daysInYear(yearToUse)) {\n                config._pf._overflowDayOfYear = true;\n            }\n\n            date = makeUTCDate(yearToUse, 0, config._dayOfYear);\n            config._a[MONTH] = date.getUTCMonth();\n            config._a[DATE] = date.getUTCDate();\n        }\n\n        // Default to current date.\n        // * if no year, month, day of month are given, default to today\n        // * if day of month is given, default month and year\n        // * if month is given, default only year\n        // * if year is given, don't default anything\n        for (i = 0; i < 3 && config._a[i] == null; ++i) {\n            config._a[i] = input[i] = currentDate[i];\n        }\n\n        // Zero out whatever was not defaulted, including time\n        for (; i < 7; i++) {\n            config._a[i] = input[i] = (config._a[i] == null) ? (i === 2 ? 1 : 0) : config._a[i];\n        }\n\n        // Check for 24:00:00.000\n        if (config._a[HOUR] === 24 &&\n                config._a[MINUTE] === 0 &&\n                config._a[SECOND] === 0 &&\n                config._a[MILLISECOND] === 0) {\n            config._nextDay = true;\n            config._a[HOUR] = 0;\n        }\n\n        config._d = (config._useUTC ? makeUTCDate : makeDate).apply(null, input);\n        // Apply timezone offset from input. The actual utcOffset can be changed\n        // with parseZone.\n        if (config._tzm != null) {\n            config._d.setUTCMinutes(config._d.getUTCMinutes() - config._tzm);\n        }\n\n        if (config._nextDay) {\n            config._a[HOUR] = 24;\n        }\n    }\n\n    function dateFromObject(config) {\n        var normalizedInput;\n\n        if (config._d) {\n            return;\n        }\n\n        normalizedInput = normalizeObjectUnits(config._i);\n        config._a = [\n            normalizedInput.year,\n            normalizedInput.month,\n            normalizedInput.day || normalizedInput.date,\n            normalizedInput.hour,\n            normalizedInput.minute,\n            normalizedInput.second,\n            normalizedInput.millisecond\n        ];\n\n        dateFromConfig(config);\n    }\n\n    function currentDateArray(config) {\n        var now = new Date();\n        if (config._useUTC) {\n            return [\n                now.getUTCFullYear(),\n                now.getUTCMonth(),\n                now.getUTCDate()\n            ];\n        } else {\n            return [now.getFullYear(), now.getMonth(), now.getDate()];\n        }\n    }\n\n    // date from string and format string\n    function makeDateFromStringAndFormat(config) {\n        if (config._f === moment.ISO_8601) {\n            parseISO(config);\n            return;\n        }\n\n        config._a = [];\n        config._pf.empty = true;\n\n        // This array is used to make a Date, either with `new Date` or `Date.UTC`\n        var string = '' + config._i,\n            i, parsedInput, tokens, token, skipped,\n            stringLength = string.length,\n            totalParsedInputLength = 0;\n\n        tokens = expandFormat(config._f, config._locale).match(formattingTokens) || [];\n\n        for (i = 0; i < tokens.length; i++) {\n            token = tokens[i];\n            parsedInput = (string.match(getParseRegexForToken(token, config)) || [])[0];\n            if (parsedInput) {\n                skipped = string.substr(0, string.indexOf(parsedInput));\n                if (skipped.length > 0) {\n                    config._pf.unusedInput.push(skipped);\n                }\n                string = string.slice(string.indexOf(parsedInput) + parsedInput.length);\n                totalParsedInputLength += parsedInput.length;\n            }\n            // don't parse if it's not a known token\n            if (formatTokenFunctions[token]) {\n                if (parsedInput) {\n                    config._pf.empty = false;\n                }\n                else {\n                    config._pf.unusedTokens.push(token);\n                }\n                addTimeToArrayFromToken(token, parsedInput, config);\n            }\n            else if (config._strict && !parsedInput) {\n                config._pf.unusedTokens.push(token);\n            }\n        }\n\n        // add remaining unparsed input length to the string\n        config._pf.charsLeftOver = stringLength - totalParsedInputLength;\n        if (string.length > 0) {\n            config._pf.unusedInput.push(string);\n        }\n\n        // clear _12h flag if hour is <= 12\n        if (config._pf.bigHour === true && config._a[HOUR] <= 12) {\n            config._pf.bigHour = undefined;\n        }\n        // handle meridiem\n        config._a[HOUR] = meridiemFixWrap(config._locale, config._a[HOUR],\n                config._meridiem);\n        dateFromConfig(config);\n        checkOverflow(config);\n    }\n\n    function unescapeFormat(s) {\n        return s.replace(/\\\\(\\[)|\\\\(\\])|\\[([^\\]\\[]*)\\]|\\\\(.)/g, function (matched, p1, p2, p3, p4) {\n            return p1 || p2 || p3 || p4;\n        });\n    }\n\n    // Code from http://stackoverflow.com/questions/3561493/is-there-a-regexp-escape-function-in-javascript\n    function regexpEscape(s) {\n        return s.replace(/[-\\/\\\\^$*+?.()|[\\]{}]/g, '\\\\$&');\n    }\n\n    // date from string and array of format strings\n    function makeDateFromStringAndArray(config) {\n        var tempConfig,\n            bestMoment,\n\n            scoreToBeat,\n            i,\n            currentScore;\n\n        if (config._f.length === 0) {\n            config._pf.invalidFormat = true;\n            config._d = new Date(NaN);\n            return;\n        }\n\n        for (i = 0; i < config._f.length; i++) {\n            currentScore = 0;\n            tempConfig = copyConfig({}, config);\n            if (config._useUTC != null) {\n                tempConfig._useUTC = config._useUTC;\n            }\n            tempConfig._pf = defaultParsingFlags();\n            tempConfig._f = config._f[i];\n            makeDateFromStringAndFormat(tempConfig);\n\n            if (!isValid(tempConfig)) {\n                continue;\n            }\n\n            // if there is any input that was not parsed add a penalty for that format\n            currentScore += tempConfig._pf.charsLeftOver;\n\n            //or tokens\n            currentScore += tempConfig._pf.unusedTokens.length * 10;\n\n            tempConfig._pf.score = currentScore;\n\n            if (scoreToBeat == null || currentScore < scoreToBeat) {\n                scoreToBeat = currentScore;\n                bestMoment = tempConfig;\n            }\n        }\n\n        extend(config, bestMoment || tempConfig);\n    }\n\n    // date from iso format\n    function parseISO(config) {\n        var i, l,\n            string = config._i,\n            match = isoRegex.exec(string);\n\n        if (match) {\n            config._pf.iso = true;\n            for (i = 0, l = isoDates.length; i < l; i++) {\n                if (isoDates[i][1].exec(string)) {\n                    // match[5] should be 'T' or undefined\n                    config._f = isoDates[i][0] + (match[6] || ' ');\n                    break;\n                }\n            }\n            for (i = 0, l = isoTimes.length; i < l; i++) {\n                if (isoTimes[i][1].exec(string)) {\n                    config._f += isoTimes[i][0];\n                    break;\n                }\n            }\n            if (string.match(parseTokenTimezone)) {\n                config._f += 'Z';\n            }\n            makeDateFromStringAndFormat(config);\n        } else {\n            config._isValid = false;\n        }\n    }\n\n    // date from iso format or fallback\n    function makeDateFromString(config) {\n        parseISO(config);\n        if (config._isValid === false) {\n            delete config._isValid;\n            moment.createFromInputFallback(config);\n        }\n    }\n\n    function map(arr, fn) {\n        var res = [], i;\n        for (i = 0; i < arr.length; ++i) {\n            res.push(fn(arr[i], i));\n        }\n        return res;\n    }\n\n    function makeDateFromInput(config) {\n        var input = config._i, matched;\n        if (input === undefined) {\n            config._d = new Date();\n        } else if (isDate(input)) {\n            config._d = new Date(+input);\n        } else if ((matched = aspNetJsonRegex.exec(input)) !== null) {\n            config._d = new Date(+matched[1]);\n        } else if (typeof input === 'string') {\n            makeDateFromString(config);\n        } else if (isArray(input)) {\n            config._a = map(input.slice(0), function (obj) {\n                return parseInt(obj, 10);\n            });\n            dateFromConfig(config);\n        } else if (typeof(input) === 'object') {\n            dateFromObject(config);\n        } else if (typeof(input) === 'number') {\n            // from milliseconds\n            config._d = new Date(input);\n        } else {\n            moment.createFromInputFallback(config);\n        }\n    }\n\n    function makeDate(y, m, d, h, M, s, ms) {\n        //can't just apply() to create a date:\n        //http://stackoverflow.com/questions/181348/instantiating-a-javascript-object-by-calling-prototype-constructor-apply\n        var date = new Date(y, m, d, h, M, s, ms);\n\n        //the date constructor doesn't accept years < 1970\n        if (y < 1970) {\n            date.setFullYear(y);\n        }\n        return date;\n    }\n\n    function makeUTCDate(y) {\n        var date = new Date(Date.UTC.apply(null, arguments));\n        if (y < 1970) {\n            date.setUTCFullYear(y);\n        }\n        return date;\n    }\n\n    function parseWeekday(input, locale) {\n        if (typeof input === 'string') {\n            if (!isNaN(input)) {\n                input = parseInt(input, 10);\n            }\n            else {\n                input = locale.weekdaysParse(input);\n                if (typeof input !== 'number') {\n                    return null;\n                }\n            }\n        }\n        return input;\n    }\n\n    /************************************\n        Relative Time\n    ************************************/\n\n\n    // helper function for moment.fn.from, moment.fn.fromNow, and moment.duration.fn.humanize\n    function substituteTimeAgo(string, number, withoutSuffix, isFuture, locale) {\n        return locale.relativeTime(number || 1, !!withoutSuffix, string, isFuture);\n    }\n\n    function relativeTime(posNegDuration, withoutSuffix, locale) {\n        var duration = moment.duration(posNegDuration).abs(),\n            seconds = round(duration.as('s')),\n            minutes = round(duration.as('m')),\n            hours = round(duration.as('h')),\n            days = round(duration.as('d')),\n            months = round(duration.as('M')),\n            years = round(duration.as('y')),\n\n            args = seconds < relativeTimeThresholds.s && ['s', seconds] ||\n                minutes === 1 && ['m'] ||\n                minutes < relativeTimeThresholds.m && ['mm', minutes] ||\n                hours === 1 && ['h'] ||\n                hours < relativeTimeThresholds.h && ['hh', hours] ||\n                days === 1 && ['d'] ||\n                days < relativeTimeThresholds.d && ['dd', days] ||\n                months === 1 && ['M'] ||\n                months < relativeTimeThresholds.M && ['MM', months] ||\n                years === 1 && ['y'] || ['yy', years];\n\n        args[2] = withoutSuffix;\n        args[3] = +posNegDuration > 0;\n        args[4] = locale;\n        return substituteTimeAgo.apply({}, args);\n    }\n\n\n    /************************************\n        Week of Year\n    ************************************/\n\n\n    // firstDayOfWeek       0 = sun, 6 = sat\n    //                      the day of the week that starts the week\n    //                      (usually sunday or monday)\n    // firstDayOfWeekOfYear 0 = sun, 6 = sat\n    //                      the first week is the week that contains the first\n    //                      of this day of the week\n    //                      (eg. ISO weeks use thursday (4))\n    function weekOfYear(mom, firstDayOfWeek, firstDayOfWeekOfYear) {\n        var end = firstDayOfWeekOfYear - firstDayOfWeek,\n            daysToDayOfWeek = firstDayOfWeekOfYear - mom.day(),\n            adjustedMoment;\n\n\n        if (daysToDayOfWeek > end) {\n            daysToDayOfWeek -= 7;\n        }\n\n        if (daysToDayOfWeek < end - 7) {\n            daysToDayOfWeek += 7;\n        }\n\n        adjustedMoment = moment(mom).add(daysToDayOfWeek, 'd');\n        return {\n            week: Math.ceil(adjustedMoment.dayOfYear() / 7),\n            year: adjustedMoment.year()\n        };\n    }\n\n    //http://en.wikipedia.org/wiki/ISO_week_date#Calculating_a_date_given_the_year.2C_week_number_and_weekday\n    function dayOfYearFromWeeks(year, week, weekday, firstDayOfWeekOfYear, firstDayOfWeek) {\n        var d = makeUTCDate(year, 0, 1).getUTCDay(), daysToAdd, dayOfYear;\n\n        d = d === 0 ? 7 : d;\n        weekday = weekday != null ? weekday : firstDayOfWeek;\n        daysToAdd = firstDayOfWeek - d + (d > firstDayOfWeekOfYear ? 7 : 0) - (d < firstDayOfWeek ? 7 : 0);\n        dayOfYear = 7 * (week - 1) + (weekday - firstDayOfWeek) + daysToAdd + 1;\n\n        return {\n            year: dayOfYear > 0 ? year : year - 1,\n            dayOfYear: dayOfYear > 0 ?  dayOfYear : daysInYear(year - 1) + dayOfYear\n        };\n    }\n\n    /************************************\n        Top Level Functions\n    ************************************/\n\n    function makeMoment(config) {\n        var input = config._i,\n            format = config._f,\n            res;\n\n        config._locale = config._locale || moment.localeData(config._l);\n\n        if (input === null || (format === undefined && input === '')) {\n            return moment.invalid({nullInput: true});\n        }\n\n        if (typeof input === 'string') {\n            config._i = input = config._locale.preparse(input);\n        }\n\n        if (moment.isMoment(input)) {\n            return new Moment(input, true);\n        } else if (format) {\n            if (isArray(format)) {\n                makeDateFromStringAndArray(config);\n            } else {\n                makeDateFromStringAndFormat(config);\n            }\n        } else {\n            makeDateFromInput(config);\n        }\n\n        res = new Moment(config);\n        if (res._nextDay) {\n            // Adding is smart enough around DST\n            res.add(1, 'd');\n            res._nextDay = undefined;\n        }\n\n        return res;\n    }\n\n    moment = function (input, format, locale, strict) {\n        var c;\n\n        if (typeof(locale) === 'boolean') {\n            strict = locale;\n            locale = undefined;\n        }\n        // object construction must be done this way.\n        // https://github.com/moment/moment/issues/1423\n        c = {};\n        c._isAMomentObject = true;\n        c._i = input;\n        c._f = format;\n        c._l = locale;\n        c._strict = strict;\n        c._isUTC = false;\n        c._pf = defaultParsingFlags();\n\n        return makeMoment(c);\n    };\n\n    moment.suppressDeprecationWarnings = false;\n\n    moment.createFromInputFallback = deprecate(\n        'moment construction falls back to js Date. This is ' +\n        'discouraged and will be removed in upcoming major ' +\n        'release. Please refer to ' +\n        'https://github.com/moment/moment/issues/1407 for more info.',\n        function (config) {\n            config._d = new Date(config._i + (config._useUTC ? ' UTC' : ''));\n        }\n    );\n\n    // Pick a moment m from moments so that m[fn](other) is true for all\n    // other. This relies on the function fn to be transitive.\n    //\n    // moments should either be an array of moment objects or an array, whose\n    // first element is an array of moment objects.\n    function pickBy(fn, moments) {\n        var res, i;\n        if (moments.length === 1 && isArray(moments[0])) {\n            moments = moments[0];\n        }\n        if (!moments.length) {\n            return moment();\n        }\n        res = moments[0];\n        for (i = 1; i < moments.length; ++i) {\n            if (moments[i][fn](res)) {\n                res = moments[i];\n            }\n        }\n        return res;\n    }\n\n    moment.min = function () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isBefore', args);\n    };\n\n    moment.max = function () {\n        var args = [].slice.call(arguments, 0);\n\n        return pickBy('isAfter', args);\n    };\n\n    // creating with utc\n    moment.utc = function (input, format, locale, strict) {\n        var c;\n\n        if (typeof(locale) === 'boolean') {\n            strict = locale;\n            locale = undefined;\n        }\n        // object construction must be done this way.\n        // https://github.com/moment/moment/issues/1423\n        c = {};\n        c._isAMomentObject = true;\n        c._useUTC = true;\n        c._isUTC = true;\n        c._l = locale;\n        c._i = input;\n        c._f = format;\n        c._strict = strict;\n        c._pf = defaultParsingFlags();\n\n        return makeMoment(c).utc();\n    };\n\n    // creating with unix timestamp (in seconds)\n    moment.unix = function (input) {\n        return moment(input * 1000);\n    };\n\n    // duration\n    moment.duration = function (input, key) {\n        var duration = input,\n            // matching against regexp is expensive, do it on demand\n            match = null,\n            sign,\n            ret,\n            parseIso,\n            diffRes;\n\n        if (moment.isDuration(input)) {\n            duration = {\n                ms: input._milliseconds,\n                d: input._days,\n                M: input._months\n            };\n        } else if (typeof input === 'number') {\n            duration = {};\n            if (key) {\n                duration[key] = input;\n            } else {\n                duration.milliseconds = input;\n            }\n        } else if (!!(match = aspNetTimeSpanJsonRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            duration = {\n                y: 0,\n                d: toInt(match[DATE]) * sign,\n                h: toInt(match[HOUR]) * sign,\n                m: toInt(match[MINUTE]) * sign,\n                s: toInt(match[SECOND]) * sign,\n                ms: toInt(match[MILLISECOND]) * sign\n            };\n        } else if (!!(match = isoDurationRegex.exec(input))) {\n            sign = (match[1] === '-') ? -1 : 1;\n            parseIso = function (inp) {\n                // We'd normally use ~~inp for this, but unfortunately it also\n                // converts floats to ints.\n                // inp may be undefined, so careful calling replace on it.\n                var res = inp && parseFloat(inp.replace(',', '.'));\n                // apply sign while we're at it\n                return (isNaN(res) ? 0 : res) * sign;\n            };\n            duration = {\n                y: parseIso(match[2]),\n                M: parseIso(match[3]),\n                d: parseIso(match[4]),\n                h: parseIso(match[5]),\n                m: parseIso(match[6]),\n                s: parseIso(match[7]),\n                w: parseIso(match[8])\n            };\n        } else if (duration == null) {// checks for null or undefined\n            duration = {};\n        } else if (typeof duration === 'object' &&\n                ('from' in duration || 'to' in duration)) {\n            diffRes = momentsDifference(moment(duration.from), moment(duration.to));\n\n            duration = {};\n            duration.ms = diffRes.milliseconds;\n            duration.M = diffRes.months;\n        }\n\n        ret = new Duration(duration);\n\n        if (moment.isDuration(input) && hasOwnProp(input, '_locale')) {\n            ret._locale = input._locale;\n        }\n\n        return ret;\n    };\n\n    // version number\n    moment.version = VERSION;\n\n    // default format\n    moment.defaultFormat = isoFormat;\n\n    // constant that refers to the ISO standard\n    moment.ISO_8601 = function () {};\n\n    // Plugins that add properties should also add the key here (null value),\n    // so we can properly clone ourselves.\n    moment.momentProperties = momentProperties;\n\n    // This function will be called whenever a moment is mutated.\n    // It is intended to keep the offset in sync with the timezone.\n    moment.updateOffset = function () {};\n\n    // This function allows you to set a threshold for relative time strings\n    moment.relativeTimeThreshold = function (threshold, limit) {\n        if (relativeTimeThresholds[threshold] === undefined) {\n            return false;\n        }\n        if (limit === undefined) {\n            return relativeTimeThresholds[threshold];\n        }\n        relativeTimeThresholds[threshold] = limit;\n        return true;\n    };\n\n    moment.lang = deprecate(\n        'moment.lang is deprecated. Use moment.locale instead.',\n        function (key, value) {\n            return moment.locale(key, value);\n        }\n    );\n\n    // This function will load locale and then set the global locale.  If\n    // no arguments are passed in, it will simply return the current global\n    // locale key.\n    moment.locale = function (key, values) {\n        var data;\n        if (key) {\n            if (typeof(values) !== 'undefined') {\n                data = moment.defineLocale(key, values);\n            }\n            else {\n                data = moment.localeData(key);\n            }\n\n            if (data) {\n                moment.duration._locale = moment._locale = data;\n            }\n        }\n\n        return moment._locale._abbr;\n    };\n\n    moment.defineLocale = function (name, values) {\n        if (values !== null) {\n            values.abbr = name;\n            if (!locales[name]) {\n                locales[name] = new Locale();\n            }\n            locales[name].set(values);\n\n            // backwards compat for now: also set the locale\n            moment.locale(name);\n\n            return locales[name];\n        } else {\n            // useful for testing\n            delete locales[name];\n            return null;\n        }\n    };\n\n    moment.langData = deprecate(\n        'moment.langData is deprecated. Use moment.localeData instead.',\n        function (key) {\n            return moment.localeData(key);\n        }\n    );\n\n    // returns locale data\n    moment.localeData = function (key) {\n        var locale;\n\n        if (key && key._locale && key._locale._abbr) {\n            key = key._locale._abbr;\n        }\n\n        if (!key) {\n            return moment._locale;\n        }\n\n        if (!isArray(key)) {\n            //short-circuit everything else\n            locale = loadLocale(key);\n            if (locale) {\n                return locale;\n            }\n            key = [key];\n        }\n\n        return chooseLocale(key);\n    };\n\n    // compare moment object\n    moment.isMoment = function (obj) {\n        return obj instanceof Moment ||\n            (obj != null && hasOwnProp(obj, '_isAMomentObject'));\n    };\n\n    // for typechecking Duration objects\n    moment.isDuration = function (obj) {\n        return obj instanceof Duration;\n    };\n\n    for (i = lists.length - 1; i >= 0; --i) {\n        makeList(lists[i]);\n    }\n\n    moment.normalizeUnits = function (units) {\n        return normalizeUnits(units);\n    };\n\n    moment.invalid = function (flags) {\n        var m = moment.utc(NaN);\n        if (flags != null) {\n            extend(m._pf, flags);\n        }\n        else {\n            m._pf.userInvalidated = true;\n        }\n\n        return m;\n    };\n\n    moment.parseZone = function () {\n        return moment.apply(null, arguments).parseZone();\n    };\n\n    moment.parseTwoDigitYear = function (input) {\n        return toInt(input) + (toInt(input) > 68 ? 1900 : 2000);\n    };\n\n    moment.isDate = isDate;\n\n    /************************************\n        Moment Prototype\n    ************************************/\n\n\n    extend(moment.fn = Moment.prototype, {\n\n        clone : function () {\n            return moment(this);\n        },\n\n        valueOf : function () {\n            return +this._d - ((this._offset || 0) * 60000);\n        },\n\n        unix : function () {\n            return Math.floor(+this / 1000);\n        },\n\n        toString : function () {\n            return this.clone().locale('en').format('ddd MMM DD YYYY HH:mm:ss [GMT]ZZ');\n        },\n\n        toDate : function () {\n            return this._offset ? new Date(+this) : this._d;\n        },\n\n        toISOString : function () {\n            var m = moment(this).utc();\n            if (0 < m.year() && m.year() <= 9999) {\n                if ('function' === typeof Date.prototype.toISOString) {\n                    // native implementation is ~50x faster, use it when we can\n                    return this.toDate().toISOString();\n                } else {\n                    return formatMoment(m, 'YYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n                }\n            } else {\n                return formatMoment(m, 'YYYYYY-MM-DD[T]HH:mm:ss.SSS[Z]');\n            }\n        },\n\n        toArray : function () {\n            var m = this;\n            return [\n                m.year(),\n                m.month(),\n                m.date(),\n                m.hours(),\n                m.minutes(),\n                m.seconds(),\n                m.milliseconds()\n            ];\n        },\n\n        isValid : function () {\n            return isValid(this);\n        },\n\n        isDSTShifted : function () {\n            if (this._a) {\n                return this.isValid() && compareArrays(this._a, (this._isUTC ? moment.utc(this._a) : moment(this._a)).toArray()) > 0;\n            }\n\n            return false;\n        },\n\n        parsingFlags : function () {\n            return extend({}, this._pf);\n        },\n\n        invalidAt: function () {\n            return this._pf.overflow;\n        },\n\n        utc : function (keepLocalTime) {\n            return this.utcOffset(0, keepLocalTime);\n        },\n\n        local : function (keepLocalTime) {\n            if (this._isUTC) {\n                this.utcOffset(0, keepLocalTime);\n                this._isUTC = false;\n\n                if (keepLocalTime) {\n                    this.subtract(this._dateUtcOffset(), 'm');\n                }\n            }\n            return this;\n        },\n\n        format : function (inputString) {\n            var output = formatMoment(this, inputString || moment.defaultFormat);\n            return this.localeData().postformat(output);\n        },\n\n        add : createAdder(1, 'add'),\n\n        subtract : createAdder(-1, 'subtract'),\n\n        diff : function (input, units, asFloat) {\n            var that = makeAs(input, this),\n                zoneDiff = (that.utcOffset() - this.utcOffset()) * 6e4,\n                anchor, diff, output, daysAdjust;\n\n            units = normalizeUnits(units);\n\n            if (units === 'year' || units === 'month' || units === 'quarter') {\n                output = monthDiff(this, that);\n                if (units === 'quarter') {\n                    output = output / 3;\n                } else if (units === 'year') {\n                    output = output / 12;\n                }\n            } else {\n                diff = this - that;\n                output = units === 'second' ? diff / 1e3 : // 1000\n                    units === 'minute' ? diff / 6e4 : // 1000 * 60\n                    units === 'hour' ? diff / 36e5 : // 1000 * 60 * 60\n                    units === 'day' ? (diff - zoneDiff) / 864e5 : // 1000 * 60 * 60 * 24, negate dst\n                    units === 'week' ? (diff - zoneDiff) / 6048e5 : // 1000 * 60 * 60 * 24 * 7, negate dst\n                    diff;\n            }\n            return asFloat ? output : absRound(output);\n        },\n\n        from : function (time, withoutSuffix) {\n            return moment.duration({to: this, from: time}).locale(this.locale()).humanize(!withoutSuffix);\n        },\n\n        fromNow : function (withoutSuffix) {\n            return this.from(moment(), withoutSuffix);\n        },\n\n        calendar : function (time) {\n            // We want to compare the start of today, vs this.\n            // Getting start-of-today depends on whether we're locat/utc/offset\n            // or not.\n            var now = time || moment(),\n                sod = makeAs(now, this).startOf('day'),\n                diff = this.diff(sod, 'days', true),\n                format = diff < -6 ? 'sameElse' :\n                    diff < -1 ? 'lastWeek' :\n                    diff < 0 ? 'lastDay' :\n                    diff < 1 ? 'sameDay' :\n                    diff < 2 ? 'nextDay' :\n                    diff < 7 ? 'nextWeek' : 'sameElse';\n            return this.format(this.localeData().calendar(format, this, moment(now)));\n        },\n\n        isLeapYear : function () {\n            return isLeapYear(this.year());\n        },\n\n        isDST : function () {\n            return (this.utcOffset() > this.clone().month(0).utcOffset() ||\n                this.utcOffset() > this.clone().month(5).utcOffset());\n        },\n\n        day : function (input) {\n            var day = this._isUTC ? this._d.getUTCDay() : this._d.getDay();\n            if (input != null) {\n                input = parseWeekday(input, this.localeData());\n                return this.add(input - day, 'd');\n            } else {\n                return day;\n            }\n        },\n\n        month : makeAccessor('Month', true),\n\n        startOf : function (units) {\n            units = normalizeUnits(units);\n            // the following switch intentionally omits break keywords\n            // to utilize falling through the cases.\n            switch (units) {\n            case 'year':\n                this.month(0);\n                /* falls through */\n            case 'quarter':\n            case 'month':\n                this.date(1);\n                /* falls through */\n            case 'week':\n            case 'isoWeek':\n            case 'day':\n                this.hours(0);\n                /* falls through */\n            case 'hour':\n                this.minutes(0);\n                /* falls through */\n            case 'minute':\n                this.seconds(0);\n                /* falls through */\n            case 'second':\n                this.milliseconds(0);\n                /* falls through */\n            }\n\n            // weeks are a special case\n            if (units === 'week') {\n                this.weekday(0);\n            } else if (units === 'isoWeek') {\n                this.isoWeekday(1);\n            }\n\n            // quarters are also special\n            if (units === 'quarter') {\n                this.month(Math.floor(this.month() / 3) * 3);\n            }\n\n            return this;\n        },\n\n        endOf: function (units) {\n            units = normalizeUnits(units);\n            if (units === undefined || units === 'millisecond') {\n                return this;\n            }\n            return this.startOf(units).add(1, (units === 'isoWeek' ? 'week' : units)).subtract(1, 'ms');\n        },\n\n        isAfter: function (input, units) {\n            var inputMs;\n            units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n            if (units === 'millisecond') {\n                input = moment.isMoment(input) ? input : moment(input);\n                return +this > +input;\n            } else {\n                inputMs = moment.isMoment(input) ? +input : +moment(input);\n                return inputMs < +this.clone().startOf(units);\n            }\n        },\n\n        isBefore: function (input, units) {\n            var inputMs;\n            units = normalizeUnits(typeof units !== 'undefined' ? units : 'millisecond');\n            if (units === 'millisecond') {\n                input = moment.isMoment(input) ? input : moment(input);\n                return +this < +input;\n            } else {\n                inputMs = moment.isMoment(input) ? +input : +moment(input);\n                return +this.clone().endOf(units) < inputMs;\n            }\n        },\n\n        isBetween: function (from, to, units) {\n            return this.isAfter(from, units) && this.isBefore(to, units);\n        },\n\n        isSame: function (input, units) {\n            var inputMs;\n            units = normalizeUnits(units || 'millisecond');\n            if (units === 'millisecond') {\n                input = moment.isMoment(input) ? input : moment(input);\n                return +this === +input;\n            } else {\n                inputMs = +moment(input);\n                return +(this.clone().startOf(units)) <= inputMs && inputMs <= +(this.clone().endOf(units));\n            }\n        },\n\n        min: deprecate(\n                 'moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548',\n                 function (other) {\n                     other = moment.apply(null, arguments);\n                     return other < this ? this : other;\n                 }\n         ),\n\n        max: deprecate(\n                'moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548',\n                function (other) {\n                    other = moment.apply(null, arguments);\n                    return other > this ? this : other;\n                }\n        ),\n\n        zone : deprecate(\n                'moment().zone is deprecated, use moment().utcOffset instead. ' +\n                'https://github.com/moment/moment/issues/1779',\n                function (input, keepLocalTime) {\n                    if (input != null) {\n                        if (typeof input !== 'string') {\n                            input = -input;\n                        }\n\n                        this.utcOffset(input, keepLocalTime);\n\n                        return this;\n                    } else {\n                        return -this.utcOffset();\n                    }\n                }\n        ),\n\n        // keepLocalTime = true means only change the timezone, without\n        // affecting the local hour. So 5:31:26 +0300 --[utcOffset(2, true)]-->\n        // 5:31:26 +0200 It is possible that 5:31:26 doesn't exist with offset\n        // +0200, so we adjust the time as needed, to be valid.\n        //\n        // Keeping the time actually adds/subtracts (one hour)\n        // from the actual represented time. That is why we call updateOffset\n        // a second time. In case it wants us to change the offset again\n        // _changeInProgress == true case, then we have to adjust, because\n        // there is no such time in the given timezone.\n        utcOffset : function (input, keepLocalTime) {\n            var offset = this._offset || 0,\n                localAdjust;\n            if (input != null) {\n                if (typeof input === 'string') {\n                    input = utcOffsetFromString(input);\n                }\n                if (Math.abs(input) < 16) {\n                    input = input * 60;\n                }\n                if (!this._isUTC && keepLocalTime) {\n                    localAdjust = this._dateUtcOffset();\n                }\n                this._offset = input;\n                this._isUTC = true;\n                if (localAdjust != null) {\n                    this.add(localAdjust, 'm');\n                }\n                if (offset !== input) {\n                    if (!keepLocalTime || this._changeInProgress) {\n                        addOrSubtractDurationFromMoment(this,\n                                moment.duration(input - offset, 'm'), 1, false);\n                    } else if (!this._changeInProgress) {\n                        this._changeInProgress = true;\n                        moment.updateOffset(this, true);\n                        this._changeInProgress = null;\n                    }\n                }\n\n                return this;\n            } else {\n                return this._isUTC ? offset : this._dateUtcOffset();\n            }\n        },\n\n        isLocal : function () {\n            return !this._isUTC;\n        },\n\n        isUtcOffset : function () {\n            return this._isUTC;\n        },\n\n        isUtc : function () {\n            return this._isUTC && this._offset === 0;\n        },\n\n        zoneAbbr : function () {\n            return this._isUTC ? 'UTC' : '';\n        },\n\n        zoneName : function () {\n            return this._isUTC ? 'Coordinated Universal Time' : '';\n        },\n\n        parseZone : function () {\n            if (this._tzm) {\n                this.utcOffset(this._tzm);\n            } else if (typeof this._i === 'string') {\n                this.utcOffset(utcOffsetFromString(this._i));\n            }\n            return this;\n        },\n\n        hasAlignedHourOffset : function (input) {\n            if (!input) {\n                input = 0;\n            }\n            else {\n                input = moment(input).utcOffset();\n            }\n\n            return (this.utcOffset() - input) % 60 === 0;\n        },\n\n        daysInMonth : function () {\n            return daysInMonth(this.year(), this.month());\n        },\n\n        dayOfYear : function (input) {\n            var dayOfYear = round((moment(this).startOf('day') - moment(this).startOf('year')) / 864e5) + 1;\n            return input == null ? dayOfYear : this.add((input - dayOfYear), 'd');\n        },\n\n        quarter : function (input) {\n            return input == null ? Math.ceil((this.month() + 1) / 3) : this.month((input - 1) * 3 + this.month() % 3);\n        },\n\n        weekYear : function (input) {\n            var year = weekOfYear(this, this.localeData()._week.dow, this.localeData()._week.doy).year;\n            return input == null ? year : this.add((input - year), 'y');\n        },\n\n        isoWeekYear : function (input) {\n            var year = weekOfYear(this, 1, 4).year;\n            return input == null ? year : this.add((input - year), 'y');\n        },\n\n        week : function (input) {\n            var week = this.localeData().week(this);\n            return input == null ? week : this.add((input - week) * 7, 'd');\n        },\n\n        isoWeek : function (input) {\n            var week = weekOfYear(this, 1, 4).week;\n            return input == null ? week : this.add((input - week) * 7, 'd');\n        },\n\n        weekday : function (input) {\n            var weekday = (this.day() + 7 - this.localeData()._week.dow) % 7;\n            return input == null ? weekday : this.add(input - weekday, 'd');\n        },\n\n        isoWeekday : function (input) {\n            // behaves the same as moment#day except\n            // as a getter, returns 7 instead of 0 (1-7 range instead of 0-6)\n            // as a setter, sunday should belong to the previous week.\n            return input == null ? this.day() || 7 : this.day(this.day() % 7 ? input : input - 7);\n        },\n\n        isoWeeksInYear : function () {\n            return weeksInYear(this.year(), 1, 4);\n        },\n\n        weeksInYear : function () {\n            var weekInfo = this.localeData()._week;\n            return weeksInYear(this.year(), weekInfo.dow, weekInfo.doy);\n        },\n\n        get : function (units) {\n            units = normalizeUnits(units);\n            return this[units]();\n        },\n\n        set : function (units, value) {\n            var unit;\n            if (typeof units === 'object') {\n                for (unit in units) {\n                    this.set(unit, units[unit]);\n                }\n            }\n            else {\n                units = normalizeUnits(units);\n                if (typeof this[units] === 'function') {\n                    this[units](value);\n                }\n            }\n            return this;\n        },\n\n        // If passed a locale key, it will set the locale for this\n        // instance.  Otherwise, it will return the locale configuration\n        // variables for this instance.\n        locale : function (key) {\n            var newLocaleData;\n\n            if (key === undefined) {\n                return this._locale._abbr;\n            } else {\n                newLocaleData = moment.localeData(key);\n                if (newLocaleData != null) {\n                    this._locale = newLocaleData;\n                }\n                return this;\n            }\n        },\n\n        lang : deprecate(\n            'moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.',\n            function (key) {\n                if (key === undefined) {\n                    return this.localeData();\n                } else {\n                    return this.locale(key);\n                }\n            }\n        ),\n\n        localeData : function () {\n            return this._locale;\n        },\n\n        _dateUtcOffset : function () {\n            // On Firefox.24 Date#getTimezoneOffset returns a floating point.\n            // https://github.com/moment/moment/pull/1871\n            return -Math.round(this._d.getTimezoneOffset() / 15) * 15;\n        }\n\n    });\n\n    function rawMonthSetter(mom, value) {\n        var dayOfMonth;\n\n        // TODO: Move this out of here!\n        if (typeof value === 'string') {\n            value = mom.localeData().monthsParse(value);\n            // TODO: Another silent failure?\n            if (typeof value !== 'number') {\n                return mom;\n            }\n        }\n\n        dayOfMonth = Math.min(mom.date(),\n                daysInMonth(mom.year(), value));\n        mom._d['set' + (mom._isUTC ? 'UTC' : '') + 'Month'](value, dayOfMonth);\n        return mom;\n    }\n\n    function rawGetter(mom, unit) {\n        return mom._d['get' + (mom._isUTC ? 'UTC' : '') + unit]();\n    }\n\n    function rawSetter(mom, unit, value) {\n        if (unit === 'Month') {\n            return rawMonthSetter(mom, value);\n        } else {\n            return mom._d['set' + (mom._isUTC ? 'UTC' : '') + unit](value);\n        }\n    }\n\n    function makeAccessor(unit, keepTime) {\n        return function (value) {\n            if (value != null) {\n                rawSetter(this, unit, value);\n                moment.updateOffset(this, keepTime);\n                return this;\n            } else {\n                return rawGetter(this, unit);\n            }\n        };\n    }\n\n    moment.fn.millisecond = moment.fn.milliseconds = makeAccessor('Milliseconds', false);\n    moment.fn.second = moment.fn.seconds = makeAccessor('Seconds', false);\n    moment.fn.minute = moment.fn.minutes = makeAccessor('Minutes', false);\n    // Setting the hour should keep the time, because the user explicitly\n    // specified which hour he wants. So trying to maintain the same hour (in\n    // a new timezone) makes sense. Adding/subtracting hours does not follow\n    // this rule.\n    moment.fn.hour = moment.fn.hours = makeAccessor('Hours', true);\n    // moment.fn.month is defined separately\n    moment.fn.date = makeAccessor('Date', true);\n    moment.fn.dates = deprecate('dates accessor is deprecated. Use date instead.', makeAccessor('Date', true));\n    moment.fn.year = makeAccessor('FullYear', true);\n    moment.fn.years = deprecate('years accessor is deprecated. Use year instead.', makeAccessor('FullYear', true));\n\n    // add plural methods\n    moment.fn.days = moment.fn.day;\n    moment.fn.months = moment.fn.month;\n    moment.fn.weeks = moment.fn.week;\n    moment.fn.isoWeeks = moment.fn.isoWeek;\n    moment.fn.quarters = moment.fn.quarter;\n\n    // add aliased format methods\n    moment.fn.toJSON = moment.fn.toISOString;\n\n    // alias isUtc for dev-friendliness\n    moment.fn.isUTC = moment.fn.isUtc;\n\n    /************************************\n        Duration Prototype\n    ************************************/\n\n\n    function daysToYears (days) {\n        // 400 years have 146097 days (taking into account leap year rules)\n        return days * 400 / 146097;\n    }\n\n    function yearsToDays (years) {\n        // years * 365 + absRound(years / 4) -\n        //     absRound(years / 100) + absRound(years / 400);\n        return years * 146097 / 400;\n    }\n\n    extend(moment.duration.fn = Duration.prototype, {\n\n        _bubble : function () {\n            var milliseconds = this._milliseconds,\n                days = this._days,\n                months = this._months,\n                data = this._data,\n                seconds, minutes, hours, years = 0;\n\n            // The following code bubbles up values, see the tests for\n            // examples of what that means.\n            data.milliseconds = milliseconds % 1000;\n\n            seconds = absRound(milliseconds / 1000);\n            data.seconds = seconds % 60;\n\n            minutes = absRound(seconds / 60);\n            data.minutes = minutes % 60;\n\n            hours = absRound(minutes / 60);\n            data.hours = hours % 24;\n\n            days += absRound(hours / 24);\n\n            // Accurately convert days to years, assume start from year 0.\n            years = absRound(daysToYears(days));\n            days -= absRound(yearsToDays(years));\n\n            // 30 days to a month\n            // TODO (iskren): Use anchor date (like 1st Jan) to compute this.\n            months += absRound(days / 30);\n            days %= 30;\n\n            // 12 months -> 1 year\n            years += absRound(months / 12);\n            months %= 12;\n\n            data.days = days;\n            data.months = months;\n            data.years = years;\n        },\n\n        abs : function () {\n            this._milliseconds = Math.abs(this._milliseconds);\n            this._days = Math.abs(this._days);\n            this._months = Math.abs(this._months);\n\n            this._data.milliseconds = Math.abs(this._data.milliseconds);\n            this._data.seconds = Math.abs(this._data.seconds);\n            this._data.minutes = Math.abs(this._data.minutes);\n            this._data.hours = Math.abs(this._data.hours);\n            this._data.months = Math.abs(this._data.months);\n            this._data.years = Math.abs(this._data.years);\n\n            return this;\n        },\n\n        weeks : function () {\n            return absRound(this.days() / 7);\n        },\n\n        valueOf : function () {\n            return this._milliseconds +\n              this._days * 864e5 +\n              (this._months % 12) * 2592e6 +\n              toInt(this._months / 12) * 31536e6;\n        },\n\n        humanize : function (withSuffix) {\n            var output = relativeTime(this, !withSuffix, this.localeData());\n\n            if (withSuffix) {\n                output = this.localeData().pastFuture(+this, output);\n            }\n\n            return this.localeData().postformat(output);\n        },\n\n        add : function (input, val) {\n            // supports only 2.0-style add(1, 's') or add(moment)\n            var dur = moment.duration(input, val);\n\n            this._milliseconds += dur._milliseconds;\n            this._days += dur._days;\n            this._months += dur._months;\n\n            this._bubble();\n\n            return this;\n        },\n\n        subtract : function (input, val) {\n            var dur = moment.duration(input, val);\n\n            this._milliseconds -= dur._milliseconds;\n            this._days -= dur._days;\n            this._months -= dur._months;\n\n            this._bubble();\n\n            return this;\n        },\n\n        get : function (units) {\n            units = normalizeUnits(units);\n            return this[units.toLowerCase() + 's']();\n        },\n\n        as : function (units) {\n            var days, months;\n            units = normalizeUnits(units);\n\n            if (units === 'month' || units === 'year') {\n                days = this._days + this._milliseconds / 864e5;\n                months = this._months + daysToYears(days) * 12;\n                return units === 'month' ? months : months / 12;\n            } else {\n                // handle milliseconds separately because of floating point math errors (issue #1867)\n                days = this._days + Math.round(yearsToDays(this._months / 12));\n                switch (units) {\n                    case 'week': return days / 7 + this._milliseconds / 6048e5;\n                    case 'day': return days + this._milliseconds / 864e5;\n                    case 'hour': return days * 24 + this._milliseconds / 36e5;\n                    case 'minute': return days * 24 * 60 + this._milliseconds / 6e4;\n                    case 'second': return days * 24 * 60 * 60 + this._milliseconds / 1000;\n                    // Math.floor prevents floating point math errors here\n                    case 'millisecond': return Math.floor(days * 24 * 60 * 60 * 1000) + this._milliseconds;\n                    default: throw new Error('Unknown unit ' + units);\n                }\n            }\n        },\n\n        lang : moment.fn.lang,\n        locale : moment.fn.locale,\n\n        toIsoString : deprecate(\n            'toIsoString() is deprecated. Please use toISOString() instead ' +\n            '(notice the capitals)',\n            function () {\n                return this.toISOString();\n            }\n        ),\n\n        toISOString : function () {\n            // inspired by https://github.com/dordille/moment-isoduration/blob/master/moment.isoduration.js\n            var years = Math.abs(this.years()),\n                months = Math.abs(this.months()),\n                days = Math.abs(this.days()),\n                hours = Math.abs(this.hours()),\n                minutes = Math.abs(this.minutes()),\n                seconds = Math.abs(this.seconds() + this.milliseconds() / 1000);\n\n            if (!this.asSeconds()) {\n                // this is the same as C#'s (Noda) and python (isodate)...\n                // but not other JS (goog.date)\n                return 'P0D';\n            }\n\n            return (this.asSeconds() < 0 ? '-' : '') +\n                'P' +\n                (years ? years + 'Y' : '') +\n                (months ? months + 'M' : '') +\n                (days ? days + 'D' : '') +\n                ((hours || minutes || seconds) ? 'T' : '') +\n                (hours ? hours + 'H' : '') +\n                (minutes ? minutes + 'M' : '') +\n                (seconds ? seconds + 'S' : '');\n        },\n\n        localeData : function () {\n            return this._locale;\n        },\n\n        toJSON : function () {\n            return this.toISOString();\n        }\n    });\n\n    moment.duration.fn.toString = moment.duration.fn.toISOString;\n\n    function makeDurationGetter(name) {\n        moment.duration.fn[name] = function () {\n            return this._data[name];\n        };\n    }\n\n    for (i in unitMillisecondFactors) {\n        if (hasOwnProp(unitMillisecondFactors, i)) {\n            makeDurationGetter(i.toLowerCase());\n        }\n    }\n\n    moment.duration.fn.asMilliseconds = function () {\n        return this.as('ms');\n    };\n    moment.duration.fn.asSeconds = function () {\n        return this.as('s');\n    };\n    moment.duration.fn.asMinutes = function () {\n        return this.as('m');\n    };\n    moment.duration.fn.asHours = function () {\n        return this.as('h');\n    };\n    moment.duration.fn.asDays = function () {\n        return this.as('d');\n    };\n    moment.duration.fn.asWeeks = function () {\n        return this.as('weeks');\n    };\n    moment.duration.fn.asMonths = function () {\n        return this.as('M');\n    };\n    moment.duration.fn.asYears = function () {\n        return this.as('y');\n    };\n\n    /************************************\n        Default Locale\n    ************************************/\n\n\n    // Set default locale, other locale will inherit from English.\n    moment.locale('en', {\n        ordinalParse: /\\d{1,2}(th|st|nd|rd)/,\n        ordinal : function (number) {\n            var b = number % 10,\n                output = (toInt(number % 100 / 10) === 1) ? 'th' :\n                (b === 1) ? 'st' :\n                (b === 2) ? 'nd' :\n                (b === 3) ? 'rd' : 'th';\n            return number + output;\n        }\n    });\n\n    /* EMBED_LOCALES */\n\n    /************************************\n        Exposing Moment\n    ************************************/\n\n    function makeGlobal(shouldDeprecate) {\n        /*global ender:false */\n        if (typeof ender !== 'undefined') {\n            return;\n        }\n        oldGlobalMoment = globalScope.moment;\n        if (shouldDeprecate) {\n            globalScope.moment = deprecate(\n                    'Accessing Moment through the global scope is ' +\n                    'deprecated, and will be removed in an upcoming ' +\n                    'release.',\n                    moment);\n        } else {\n            globalScope.moment = moment;\n        }\n    }\n\n    // CommonJS module is defined\n    if (hasModule) {\n        module.exports = moment;\n    } else if (typeof define === 'function' && define.amd) {\n        define(function (require, exports, module) {\n            if (module.config && module.config() && module.config().noGlobal === true) {\n                // release the global variable\n                globalScope.moment = oldGlobalMoment;\n            }\n\n            return moment;\n        });\n        makeGlobal(true);\n    } else {\n        makeGlobal();\n    }\n}).call(this);\n"
  },
  {
    "path": "public/static/plugins/fastclick/fastclick.js",
    "content": ";(function () {\n\t'use strict';\n\n\t/**\n\t * @preserve FastClick: polyfill to remove click delays on browsers with touch UIs.\n\t *\n\t * @codingstandard ftlabs-jsv2\n\t * @copyright The Financial Times Limited [All Rights Reserved]\n\t * @license MIT License (see LICENSE.txt)\n\t */\n\n\t/*jslint browser:true, node:true*/\n\t/*global define, Event, Node*/\n\n\n\t/**\n\t * Instantiate fast-clicking listeners on the specified layer.\n\t *\n\t * @constructor\n\t * @param {Element} layer The layer to listen on\n\t * @param {Object} [options={}] The options to override the defaults\n\t */\n\tfunction FastClick(layer, options) {\n\t\tvar oldOnClick;\n\n\t\toptions = options || {};\n\n\t\t/**\n\t\t * Whether a click is currently being tracked.\n\t\t *\n\t\t * @type boolean\n\t\t */\n\t\tthis.trackingClick = false;\n\n\n\t\t/**\n\t\t * Timestamp for when click tracking started.\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.trackingClickStart = 0;\n\n\n\t\t/**\n\t\t * The element being tracked for a click.\n\t\t *\n\t\t * @type EventTarget\n\t\t */\n\t\tthis.targetElement = null;\n\n\n\t\t/**\n\t\t * X-coordinate of touch start event.\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.touchStartX = 0;\n\n\n\t\t/**\n\t\t * Y-coordinate of touch start event.\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.touchStartY = 0;\n\n\n\t\t/**\n\t\t * ID of the last touch, retrieved from Touch.identifier.\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.lastTouchIdentifier = 0;\n\n\n\t\t/**\n\t\t * Touchmove boundary, beyond which a click will be cancelled.\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.touchBoundary = options.touchBoundary || 10;\n\n\n\t\t/**\n\t\t * The FastClick layer.\n\t\t *\n\t\t * @type Element\n\t\t */\n\t\tthis.layer = layer;\n\n\t\t/**\n\t\t * The minimum time between tap(touchstart and touchend) events\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.tapDelay = options.tapDelay || 200;\n\n\t\t/**\n\t\t * The maximum time for a tap\n\t\t *\n\t\t * @type number\n\t\t */\n\t\tthis.tapTimeout = options.tapTimeout || 700;\n\n\t\tif (FastClick.notNeeded(layer)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Some old versions of Android don't have Function.prototype.bind\n\t\tfunction bind(method, context) {\n\t\t\treturn function() { return method.apply(context, arguments); };\n\t\t}\n\n\n\t\tvar methods = ['onMouse', 'onClick', 'onTouchStart', 'onTouchMove', 'onTouchEnd', 'onTouchCancel'];\n\t\tvar context = this;\n\t\tfor (var i = 0, l = methods.length; i < l; i++) {\n\t\t\tcontext[methods[i]] = bind(context[methods[i]], context);\n\t\t}\n\n\t\t// Set up event handlers as required\n\t\tif (deviceIsAndroid) {\n\t\t\tlayer.addEventListener('mouseover', this.onMouse, true);\n\t\t\tlayer.addEventListener('mousedown', this.onMouse, true);\n\t\t\tlayer.addEventListener('mouseup', this.onMouse, true);\n\t\t}\n\n\t\tlayer.addEventListener('click', this.onClick, true);\n\t\tlayer.addEventListener('touchstart', this.onTouchStart, false);\n\t\tlayer.addEventListener('touchmove', this.onTouchMove, false);\n\t\tlayer.addEventListener('touchend', this.onTouchEnd, false);\n\t\tlayer.addEventListener('touchcancel', this.onTouchCancel, false);\n\n\t\t// Hack is required for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)\n\t\t// which is how FastClick normally stops click events bubbling to callbacks registered on the FastClick\n\t\t// layer when they are cancelled.\n\t\tif (!Event.prototype.stopImmediatePropagation) {\n\t\t\tlayer.removeEventListener = function(type, callback, capture) {\n\t\t\t\tvar rmv = Node.prototype.removeEventListener;\n\t\t\t\tif (type === 'click') {\n\t\t\t\t\trmv.call(layer, type, callback.hijacked || callback, capture);\n\t\t\t\t} else {\n\t\t\t\t\trmv.call(layer, type, callback, capture);\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tlayer.addEventListener = function(type, callback, capture) {\n\t\t\t\tvar adv = Node.prototype.addEventListener;\n\t\t\t\tif (type === 'click') {\n\t\t\t\t\tadv.call(layer, type, callback.hijacked || (callback.hijacked = function(event) {\n\t\t\t\t\t\tif (!event.propagationStopped) {\n\t\t\t\t\t\t\tcallback(event);\n\t\t\t\t\t\t}\n\t\t\t\t\t}), capture);\n\t\t\t\t} else {\n\t\t\t\t\tadv.call(layer, type, callback, capture);\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\t// If a handler is already declared in the element's onclick attribute, it will be fired before\n\t\t// FastClick's onClick handler. Fix this by pulling out the user-defined handler function and\n\t\t// adding it as listener.\n\t\tif (typeof layer.onclick === 'function') {\n\n\t\t\t// Android browser on at least 3.2 requires a new reference to the function in layer.onclick\n\t\t\t// - the old one won't work if passed to addEventListener directly.\n\t\t\toldOnClick = layer.onclick;\n\t\t\tlayer.addEventListener('click', function(event) {\n\t\t\t\toldOnClick(event);\n\t\t\t}, false);\n\t\t\tlayer.onclick = null;\n\t\t}\n\t}\n\n\t/**\n\t* Windows Phone 8.1 fakes user agent string to look like Android and iPhone.\n\t*\n\t* @type boolean\n\t*/\n\tvar deviceIsWindowsPhone = navigator.userAgent.indexOf(\"Windows Phone\") >= 0;\n\n\t/**\n\t * Android requires exceptions.\n\t *\n\t * @type boolean\n\t */\n\tvar deviceIsAndroid = navigator.userAgent.indexOf('Android') > 0 && !deviceIsWindowsPhone;\n\n\n\t/**\n\t * iOS requires exceptions.\n\t *\n\t * @type boolean\n\t */\n\tvar deviceIsIOS = /iP(ad|hone|od)/.test(navigator.userAgent) && !deviceIsWindowsPhone;\n\n\n\t/**\n\t * iOS 4 requires an exception for select elements.\n\t *\n\t * @type boolean\n\t */\n\tvar deviceIsIOS4 = deviceIsIOS && (/OS 4_\\d(_\\d)?/).test(navigator.userAgent);\n\n\n\t/**\n\t * iOS 6.0-7.* requires the target element to be manually derived\n\t *\n\t * @type boolean\n\t */\n\tvar deviceIsIOSWithBadTarget = deviceIsIOS && (/OS [6-7]_\\d/).test(navigator.userAgent);\n\n\t/**\n\t * BlackBerry requires exceptions.\n\t *\n\t * @type boolean\n\t */\n\tvar deviceIsBlackBerry10 = navigator.userAgent.indexOf('BB10') > 0;\n\n\t/**\n\t * Determine whether a given element requires a native click.\n\t *\n\t * @param {EventTarget|Element} target Target DOM element\n\t * @returns {boolean} Returns true if the element needs a native click\n\t */\n\tFastClick.prototype.needsClick = function(target) {\n\t\tswitch (target.nodeName.toLowerCase()) {\n\n\t\t// Don't send a synthetic click to disabled inputs (issue #62)\n\t\tcase 'button':\n\t\tcase 'select':\n\t\tcase 'textarea':\n\t\t\tif (target.disabled) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tbreak;\n\t\tcase 'input':\n\n\t\t\t// File inputs need real clicks on iOS 6 due to a browser bug (issue #68)\n\t\t\tif ((deviceIsIOS && target.type === 'file') || target.disabled) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tbreak;\n\t\tcase 'label':\n\t\tcase 'iframe': // iOS8 homescreen apps can prevent events bubbling into frames\n\t\tcase 'video':\n\t\t\treturn true;\n\t\t}\n\n\t\treturn (/\\bneedsclick\\b/).test(target.className);\n\t};\n\n\n\t/**\n\t * Determine whether a given element requires a call to focus to simulate click into element.\n\t *\n\t * @param {EventTarget|Element} target Target DOM element\n\t * @returns {boolean} Returns true if the element requires a call to focus to simulate native click.\n\t */\n\tFastClick.prototype.needsFocus = function(target) {\n\t\tswitch (target.nodeName.toLowerCase()) {\n\t\tcase 'textarea':\n\t\t\treturn true;\n\t\tcase 'select':\n\t\t\treturn !deviceIsAndroid;\n\t\tcase 'input':\n\t\t\tswitch (target.type) {\n\t\t\tcase 'button':\n\t\t\tcase 'checkbox':\n\t\t\tcase 'file':\n\t\t\tcase 'image':\n\t\t\tcase 'radio':\n\t\t\tcase 'submit':\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// No point in attempting to focus disabled inputs\n\t\t\treturn !target.disabled && !target.readOnly;\n\t\tdefault:\n\t\t\treturn (/\\bneedsfocus\\b/).test(target.className);\n\t\t}\n\t};\n\n\n\t/**\n\t * Send a click event to the specified element.\n\t *\n\t * @param {EventTarget|Element} targetElement\n\t * @param {Event} event\n\t */\n\tFastClick.prototype.sendClick = function(targetElement, event) {\n\t\tvar clickEvent, touch;\n\n\t\t// On some Android devices activeElement needs to be blurred otherwise the synthetic click will have no effect (#24)\n\t\tif (document.activeElement && document.activeElement !== targetElement) {\n\t\t\tdocument.activeElement.blur();\n\t\t}\n\n\t\ttouch = event.changedTouches[0];\n\n\t\t// Synthesise a click event, with an extra attribute so it can be tracked\n\t\tclickEvent = document.createEvent('MouseEvents');\n\t\tclickEvent.initMouseEvent(this.determineEventType(targetElement), true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY, false, false, false, false, 0, null);\n\t\tclickEvent.forwardedTouchEvent = true;\n\t\ttargetElement.dispatchEvent(clickEvent);\n\t};\n\n\tFastClick.prototype.determineEventType = function(targetElement) {\n\n\t\t//Issue #159: Android Chrome Select Box does not open with a synthetic click event\n\t\tif (deviceIsAndroid && targetElement.tagName.toLowerCase() === 'select') {\n\t\t\treturn 'mousedown';\n\t\t}\n\n\t\treturn 'click';\n\t};\n\n\n\t/**\n\t * @param {EventTarget|Element} targetElement\n\t */\n\tFastClick.prototype.focus = function(targetElement) {\n\t\tvar length;\n\n\t\t// Issue #160: on iOS 7, some input elements (e.g. date datetime month) throw a vague TypeError on setSelectionRange. These elements don't have an integer value for the selectionStart and selectionEnd properties, but unfortunately that can't be used for detection because accessing the properties also throws a TypeError. Just check the type instead. Filed as Apple bug #15122724.\n\t\tif (deviceIsIOS && targetElement.setSelectionRange && targetElement.type.indexOf('date') !== 0 && targetElement.type !== 'time' && targetElement.type !== 'month') {\n\t\t\tlength = targetElement.value.length;\n\t\t\ttargetElement.setSelectionRange(length, length);\n\t\t} else {\n\t\t\ttargetElement.focus();\n\t\t}\n\t};\n\n\n\t/**\n\t * Check whether the given target element is a child of a scrollable layer and if so, set a flag on it.\n\t *\n\t * @param {EventTarget|Element} targetElement\n\t */\n\tFastClick.prototype.updateScrollParent = function(targetElement) {\n\t\tvar scrollParent, parentElement;\n\n\t\tscrollParent = targetElement.fastClickScrollParent;\n\n\t\t// Attempt to discover whether the target element is contained within a scrollable layer. Re-check if the\n\t\t// target element was moved to another parent.\n\t\tif (!scrollParent || !scrollParent.contains(targetElement)) {\n\t\t\tparentElement = targetElement;\n\t\t\tdo {\n\t\t\t\tif (parentElement.scrollHeight > parentElement.offsetHeight) {\n\t\t\t\t\tscrollParent = parentElement;\n\t\t\t\t\ttargetElement.fastClickScrollParent = parentElement;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tparentElement = parentElement.parentElement;\n\t\t\t} while (parentElement);\n\t\t}\n\n\t\t// Always update the scroll top tracker if possible.\n\t\tif (scrollParent) {\n\t\t\tscrollParent.fastClickLastScrollTop = scrollParent.scrollTop;\n\t\t}\n\t};\n\n\n\t/**\n\t * @param {EventTarget} targetElement\n\t * @returns {Element|EventTarget}\n\t */\n\tFastClick.prototype.getTargetElementFromEventTarget = function(eventTarget) {\n\n\t\t// On some older browsers (notably Safari on iOS 4.1 - see issue #56) the event target may be a text node.\n\t\tif (eventTarget.nodeType === Node.TEXT_NODE) {\n\t\t\treturn eventTarget.parentNode;\n\t\t}\n\n\t\treturn eventTarget;\n\t};\n\n\n\t/**\n\t * On touch start, record the position and scroll offset.\n\t *\n\t * @param {Event} event\n\t * @returns {boolean}\n\t */\n\tFastClick.prototype.onTouchStart = function(event) {\n\t\tvar targetElement, touch, selection;\n\n\t\t// Ignore multiple touches, otherwise pinch-to-zoom is prevented if both fingers are on the FastClick element (issue #111).\n\t\tif (event.targetTouches.length > 1) {\n\t\t\treturn true;\n\t\t}\n\n\t\ttargetElement = this.getTargetElementFromEventTarget(event.target);\n\t\ttouch = event.targetTouches[0];\n\n\t\tif (deviceIsIOS) {\n\n\t\t\t// Only trusted events will deselect text on iOS (issue #49)\n\t\t\tselection = window.getSelection();\n\t\t\tif (selection.rangeCount && !selection.isCollapsed) {\n\t\t\t\treturn true;\n\t\t\t}\n\n\t\t\tif (!deviceIsIOS4) {\n\n\t\t\t\t// Weird things happen on iOS when an alert or confirm dialog is opened from a click event callback (issue #23):\n\t\t\t\t// when the user next taps anywhere else on the page, new touchstart and touchend events are dispatched\n\t\t\t\t// with the same identifier as the touch event that previously triggered the click that triggered the alert.\n\t\t\t\t// Sadly, there is an issue on iOS 4 that causes some normal touch events to have the same identifier as an\n\t\t\t\t// immediately preceeding touch event (issue #52), so this fix is unavailable on that platform.\n\t\t\t\t// Issue 120: touch.identifier is 0 when Chrome dev tools 'Emulate touch events' is set with an iOS device UA string,\n\t\t\t\t// which causes all touch events to be ignored. As this block only applies to iOS, and iOS identifiers are always long,\n\t\t\t\t// random integers, it's safe to to continue if the identifier is 0 here.\n\t\t\t\tif (touch.identifier && touch.identifier === this.lastTouchIdentifier) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\tthis.lastTouchIdentifier = touch.identifier;\n\n\t\t\t\t// If the target element is a child of a scrollable layer (using -webkit-overflow-scrolling: touch) and:\n\t\t\t\t// 1) the user does a fling scroll on the scrollable layer\n\t\t\t\t// 2) the user stops the fling scroll with another tap\n\t\t\t\t// then the event.target of the last 'touchend' event will be the element that was under the user's finger\n\t\t\t\t// when the fling scroll was started, causing FastClick to send a click event to that layer - unless a check\n\t\t\t\t// is made to ensure that a parent layer was not scrolled before sending a synthetic click (issue #42).\n\t\t\t\tthis.updateScrollParent(targetElement);\n\t\t\t}\n\t\t}\n\n\t\tthis.trackingClick = true;\n\t\tthis.trackingClickStart = event.timeStamp;\n\t\tthis.targetElement = targetElement;\n\n\t\tthis.touchStartX = touch.pageX;\n\t\tthis.touchStartY = touch.pageY;\n\n\t\t// Prevent phantom clicks on fast double-tap (issue #36)\n\t\tif ((event.timeStamp - this.lastClickTime) < this.tapDelay) {\n\t\t\tevent.preventDefault();\n\t\t}\n\n\t\treturn true;\n\t};\n\n\n\t/**\n\t * Based on a touchmove event object, check whether the touch has moved past a boundary since it started.\n\t *\n\t * @param {Event} event\n\t * @returns {boolean}\n\t */\n\tFastClick.prototype.touchHasMoved = function(event) {\n\t\tvar touch = event.changedTouches[0], boundary = this.touchBoundary;\n\n\t\tif (Math.abs(touch.pageX - this.touchStartX) > boundary || Math.abs(touch.pageY - this.touchStartY) > boundary) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\n\t/**\n\t * Update the last position.\n\t *\n\t * @param {Event} event\n\t * @returns {boolean}\n\t */\n\tFastClick.prototype.onTouchMove = function(event) {\n\t\tif (!this.trackingClick) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// If the touch has moved, cancel the click tracking\n\t\tif (this.targetElement !== this.getTargetElementFromEventTarget(event.target) || this.touchHasMoved(event)) {\n\t\t\tthis.trackingClick = false;\n\t\t\tthis.targetElement = null;\n\t\t}\n\n\t\treturn true;\n\t};\n\n\n\t/**\n\t * Attempt to find the labelled control for the given label element.\n\t *\n\t * @param {EventTarget|HTMLLabelElement} labelElement\n\t * @returns {Element|null}\n\t */\n\tFastClick.prototype.findControl = function(labelElement) {\n\n\t\t// Fast path for newer browsers supporting the HTML5 control attribute\n\t\tif (labelElement.control !== undefined) {\n\t\t\treturn labelElement.control;\n\t\t}\n\n\t\t// All browsers under test that support touch events also support the HTML5 htmlFor attribute\n\t\tif (labelElement.htmlFor) {\n\t\t\treturn document.getElementById(labelElement.htmlFor);\n\t\t}\n\n\t\t// If no for attribute exists, attempt to retrieve the first labellable descendant element\n\t\t// the list of which is defined here: http://www.w3.org/TR/html5/forms.html#category-label\n\t\treturn labelElement.querySelector('button, input:not([type=hidden]), keygen, meter, output, progress, select, textarea');\n\t};\n\n\n\t/**\n\t * On touch end, determine whether to send a click event at once.\n\t *\n\t * @param {Event} event\n\t * @returns {boolean}\n\t */\n\tFastClick.prototype.onTouchEnd = function(event) {\n\t\tvar forElement, trackingClickStart, targetTagName, scrollParent, touch, targetElement = this.targetElement;\n\n\t\tif (!this.trackingClick) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Prevent phantom clicks on fast double-tap (issue #36)\n\t\tif ((event.timeStamp - this.lastClickTime) < this.tapDelay) {\n\t\t\tthis.cancelNextClick = true;\n\t\t\treturn true;\n\t\t}\n\n\t\tif ((event.timeStamp - this.trackingClickStart) > this.tapTimeout) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Reset to prevent wrong click cancel on input (issue #156).\n\t\tthis.cancelNextClick = false;\n\n\t\tthis.lastClickTime = event.timeStamp;\n\n\t\ttrackingClickStart = this.trackingClickStart;\n\t\tthis.trackingClick = false;\n\t\tthis.trackingClickStart = 0;\n\n\t\t// On some iOS devices, the targetElement supplied with the event is invalid if the layer\n\t\t// is performing a transition or scroll, and has to be re-detected manually. Note that\n\t\t// for this to function correctly, it must be called *after* the event target is checked!\n\t\t// See issue #57; also filed as rdar://13048589 .\n\t\tif (deviceIsIOSWithBadTarget) {\n\t\t\ttouch = event.changedTouches[0];\n\n\t\t\t// In certain cases arguments of elementFromPoint can be negative, so prevent setting targetElement to null\n\t\t\ttargetElement = document.elementFromPoint(touch.pageX - window.pageXOffset, touch.pageY - window.pageYOffset) || targetElement;\n\t\t\ttargetElement.fastClickScrollParent = this.targetElement.fastClickScrollParent;\n\t\t}\n\n\t\ttargetTagName = targetElement.tagName.toLowerCase();\n\t\tif (targetTagName === 'label') {\n\t\t\tforElement = this.findControl(targetElement);\n\t\t\tif (forElement) {\n\t\t\t\tthis.focus(targetElement);\n\t\t\t\tif (deviceIsAndroid) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\ttargetElement = forElement;\n\t\t\t}\n\t\t} else if (this.needsFocus(targetElement)) {\n\n\t\t\t// Case 1: If the touch started a while ago (best guess is 100ms based on tests for issue #36) then focus will be triggered anyway. Return early and unset the target element reference so that the subsequent click will be allowed through.\n\t\t\t// Case 2: Without this exception for input elements tapped when the document is contained in an iframe, then any inputted text won't be visible even though the value attribute is updated as the user types (issue #37).\n\t\t\tif ((event.timeStamp - trackingClickStart) > 100 || (deviceIsIOS && window.top !== window && targetTagName === 'input')) {\n\t\t\t\tthis.targetElement = null;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis.focus(targetElement);\n\t\t\tthis.sendClick(targetElement, event);\n\n\t\t\t// Select elements need the event to go through on iOS 4, otherwise the selector menu won't open.\n\t\t\t// Also this breaks opening selects when VoiceOver is active on iOS6, iOS7 (and possibly others)\n\t\t\tif (!deviceIsIOS || targetTagName !== 'select') {\n\t\t\t\tthis.targetElement = null;\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\n\t\t\treturn false;\n\t\t}\n\n\t\tif (deviceIsIOS && !deviceIsIOS4) {\n\n\t\t\t// Don't send a synthetic click event if the target element is contained within a parent layer that was scrolled\n\t\t\t// and this tap is being used to stop the scrolling (usually initiated by a fling - issue #42).\n\t\t\tscrollParent = targetElement.fastClickScrollParent;\n\t\t\tif (scrollParent && scrollParent.fastClickLastScrollTop !== scrollParent.scrollTop) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t// Prevent the actual click from going though - unless the target node is marked as requiring\n\t\t// real clicks or if it is in the whitelist in which case only non-programmatic clicks are permitted.\n\t\tif (!this.needsClick(targetElement)) {\n\t\t\tevent.preventDefault();\n\t\t\tthis.sendClick(targetElement, event);\n\t\t}\n\n\t\treturn false;\n\t};\n\n\n\t/**\n\t * On touch cancel, stop tracking the click.\n\t *\n\t * @returns {void}\n\t */\n\tFastClick.prototype.onTouchCancel = function() {\n\t\tthis.trackingClick = false;\n\t\tthis.targetElement = null;\n\t};\n\n\n\t/**\n\t * Determine mouse events which should be permitted.\n\t *\n\t * @param {Event} event\n\t * @returns {boolean}\n\t */\n\tFastClick.prototype.onMouse = function(event) {\n\n\t\t// If a target element was never set (because a touch event was never fired) allow the event\n\t\tif (!this.targetElement) {\n\t\t\treturn true;\n\t\t}\n\n\t\tif (event.forwardedTouchEvent) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Programmatically generated events targeting a specific element should be permitted\n\t\tif (!event.cancelable) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Derive and check the target element to see whether the mouse event needs to be permitted;\n\t\t// unless explicitly enabled, prevent non-touch click events from triggering actions,\n\t\t// to prevent ghost/doubleclicks.\n\t\tif (!this.needsClick(this.targetElement) || this.cancelNextClick) {\n\n\t\t\t// Prevent any user-added listeners declared on FastClick element from being fired.\n\t\t\tif (event.stopImmediatePropagation) {\n\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t} else {\n\n\t\t\t\t// Part of the hack for browsers that don't support Event#stopImmediatePropagation (e.g. Android 2)\n\t\t\t\tevent.propagationStopped = true;\n\t\t\t}\n\n\t\t\t// Cancel the event\n\t\t\tevent.stopPropagation();\n\t\t\tevent.preventDefault();\n\n\t\t\treturn false;\n\t\t}\n\n\t\t// If the mouse event is permitted, return true for the action to go through.\n\t\treturn true;\n\t};\n\n\n\t/**\n\t * On actual clicks, determine whether this is a touch-generated click, a click action occurring\n\t * naturally after a delay after a touch (which needs to be cancelled to avoid duplication), or\n\t * an actual click which should be permitted.\n\t *\n\t * @param {Event} event\n\t * @returns {boolean}\n\t */\n\tFastClick.prototype.onClick = function(event) {\n\t\tvar permitted;\n\n\t\t// It's possible for another FastClick-like library delivered with third-party code to fire a click event before FastClick does (issue #44). In that case, set the click-tracking flag back to false and return early. This will cause onTouchEnd to return early.\n\t\tif (this.trackingClick) {\n\t\t\tthis.targetElement = null;\n\t\t\tthis.trackingClick = false;\n\t\t\treturn true;\n\t\t}\n\n\t\t// Very odd behaviour on iOS (issue #18): if a submit element is present inside a form and the user hits enter in the iOS simulator or clicks the Go button on the pop-up OS keyboard the a kind of 'fake' click event will be triggered with the submit-type input element as the target.\n\t\tif (event.target.type === 'submit' && event.detail === 0) {\n\t\t\treturn true;\n\t\t}\n\n\t\tpermitted = this.onMouse(event);\n\n\t\t// Only unset targetElement if the click is not permitted. This will ensure that the check for !targetElement in onMouse fails and the browser's click doesn't go through.\n\t\tif (!permitted) {\n\t\t\tthis.targetElement = null;\n\t\t}\n\n\t\t// If clicks are permitted, return true for the action to go through.\n\t\treturn permitted;\n\t};\n\n\n\t/**\n\t * Remove all FastClick's event listeners.\n\t *\n\t * @returns {void}\n\t */\n\tFastClick.prototype.destroy = function() {\n\t\tvar layer = this.layer;\n\n\t\tif (deviceIsAndroid) {\n\t\t\tlayer.removeEventListener('mouseover', this.onMouse, true);\n\t\t\tlayer.removeEventListener('mousedown', this.onMouse, true);\n\t\t\tlayer.removeEventListener('mouseup', this.onMouse, true);\n\t\t}\n\n\t\tlayer.removeEventListener('click', this.onClick, true);\n\t\tlayer.removeEventListener('touchstart', this.onTouchStart, false);\n\t\tlayer.removeEventListener('touchmove', this.onTouchMove, false);\n\t\tlayer.removeEventListener('touchend', this.onTouchEnd, false);\n\t\tlayer.removeEventListener('touchcancel', this.onTouchCancel, false);\n\t};\n\n\n\t/**\n\t * Check whether FastClick is needed.\n\t *\n\t * @param {Element} layer The layer to listen on\n\t */\n\tFastClick.notNeeded = function(layer) {\n\t\tvar metaViewport;\n\t\tvar chromeVersion;\n\t\tvar blackberryVersion;\n\t\tvar firefoxVersion;\n\n\t\t// Devices that don't support touch don't need FastClick\n\t\tif (typeof window.ontouchstart === 'undefined') {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Chrome version - zero for other browsers\n\t\tchromeVersion = +(/Chrome\\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];\n\n\t\tif (chromeVersion) {\n\n\t\t\tif (deviceIsAndroid) {\n\t\t\t\tmetaViewport = document.querySelector('meta[name=viewport]');\n\n\t\t\t\tif (metaViewport) {\n\t\t\t\t\t// Chrome on Android with user-scalable=\"no\" doesn't need FastClick (issue #89)\n\t\t\t\t\tif (metaViewport.content.indexOf('user-scalable=no') !== -1) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\t// Chrome 32 and above with width=device-width or less don't need FastClick\n\t\t\t\t\tif (chromeVersion > 31 && document.documentElement.scrollWidth <= window.outerWidth) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Chrome desktop doesn't need FastClick (issue #15)\n\t\t\t} else {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\tif (deviceIsBlackBerry10) {\n\t\t\tblackberryVersion = navigator.userAgent.match(/Version\\/([0-9]*)\\.([0-9]*)/);\n\n\t\t\t// BlackBerry 10.3+ does not require Fastclick library.\n\t\t\t// https://github.com/ftlabs/fastclick/issues/251\n\t\t\tif (blackberryVersion[1] >= 10 && blackberryVersion[2] >= 3) {\n\t\t\t\tmetaViewport = document.querySelector('meta[name=viewport]');\n\n\t\t\t\tif (metaViewport) {\n\t\t\t\t\t// user-scalable=no eliminates click delay.\n\t\t\t\t\tif (metaViewport.content.indexOf('user-scalable=no') !== -1) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\t// width=device-width (or less than device-width) eliminates click delay.\n\t\t\t\t\tif (document.documentElement.scrollWidth <= window.outerWidth) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// IE10 with -ms-touch-action: none or manipulation, which disables double-tap-to-zoom (issue #97)\n\t\tif (layer.style.msTouchAction === 'none' || layer.style.touchAction === 'manipulation') {\n\t\t\treturn true;\n\t\t}\n\n\t\t// Firefox version - zero for other browsers\n\t\tfirefoxVersion = +(/Firefox\\/([0-9]+)/.exec(navigator.userAgent) || [,0])[1];\n\n\t\tif (firefoxVersion >= 27) {\n\t\t\t// Firefox 27+ does not have tap delay if the content is not zoomable - https://bugzilla.mozilla.org/show_bug.cgi?id=922896\n\n\t\t\tmetaViewport = document.querySelector('meta[name=viewport]');\n\t\t\tif (metaViewport && (metaViewport.content.indexOf('user-scalable=no') !== -1 || document.documentElement.scrollWidth <= window.outerWidth)) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t// IE11: prefixed -ms-touch-action is no longer supported and it's recomended to use non-prefixed version\n\t\t// http://msdn.microsoft.com/en-us/library/windows/apps/Hh767313.aspx\n\t\tif (layer.style.touchAction === 'none' || layer.style.touchAction === 'manipulation') {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t};\n\n\n\t/**\n\t * Factory method for creating a FastClick object\n\t *\n\t * @param {Element} layer The layer to listen on\n\t * @param {Object} [options={}] The options to override the defaults\n\t */\n\tFastClick.attach = function(layer, options) {\n\t\treturn new FastClick(layer, options);\n\t};\n\n\n\tif (typeof define === 'function' && typeof define.amd === 'object' && define.amd) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine(function() {\n\t\t\treturn FastClick;\n\t\t});\n\t} else if (typeof module !== 'undefined' && module.exports) {\n\t\tmodule.exports = FastClick.attach;\n\t\tmodule.exports.FastClick = FastClick;\n\t} else {\n\t\twindow.FastClick = FastClick;\n\t}\n}());\n"
  },
  {
    "path": "public/static/plugins/flot/excanvas.js",
    "content": "// Copyright 2006 Google Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n//   http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\n\n// Known Issues:\n//\n// * Patterns only support repeat.\n// * Radial gradient are not implemented. The VML version of these look very\n//   different from the canvas one.\n// * Clipping paths are not implemented.\n// * Coordsize. The width and height attribute have higher priority than the\n//   width and height style values which isn't correct.\n// * Painting mode isn't implemented.\n// * Canvas width/height should is using content-box by default. IE in\n//   Quirks mode will draw the canvas using border-box. Either change your\n//   doctype to HTML5\n//   (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)\n//   or use Box Sizing Behavior from WebFX\n//   (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)\n// * Non uniform scaling does not correctly scale strokes.\n// * Filling very large shapes (above 5000 points) is buggy.\n// * Optimize. There is always room for speed improvements.\n\n// Only add this code if we do not already have a canvas implementation\nif (!document.createElement('canvas').getContext) {\n\n(function() {\n\n  // alias some functions to make (compiled) code shorter\n  var m = Math;\n  var mr = m.round;\n  var ms = m.sin;\n  var mc = m.cos;\n  var abs = m.abs;\n  var sqrt = m.sqrt;\n\n  // this is used for sub pixel precision\n  var Z = 10;\n  var Z2 = Z / 2;\n\n  var IE_VERSION = +navigator.userAgent.match(/MSIE ([\\d.]+)?/)[1];\n\n  /**\n   * This funtion is assigned to the <canvas> elements as element.getContext().\n   * @this {HTMLElement}\n   * @return {CanvasRenderingContext2D_}\n   */\n  function getContext() {\n    return this.context_ ||\n        (this.context_ = new CanvasRenderingContext2D_(this));\n  }\n\n  var slice = Array.prototype.slice;\n\n  /**\n   * Binds a function to an object. The returned function will always use the\n   * passed in {@code obj} as {@code this}.\n   *\n   * Example:\n   *\n   *   g = bind(f, obj, a, b)\n   *   g(c, d) // will do f.call(obj, a, b, c, d)\n   *\n   * @param {Function} f The function to bind the object to\n   * @param {Object} obj The object that should act as this when the function\n   *     is called\n   * @param {*} var_args Rest arguments that will be used as the initial\n   *     arguments when the function is called\n   * @return {Function} A new function that has bound this\n   */\n  function bind(f, obj, var_args) {\n    var a = slice.call(arguments, 2);\n    return function() {\n      return f.apply(obj, a.concat(slice.call(arguments)));\n    };\n  }\n\n  function encodeHtmlAttribute(s) {\n    return String(s).replace(/&/g, '&amp;').replace(/\"/g, '&quot;');\n  }\n\n  function addNamespace(doc, prefix, urn) {\n    if (!doc.namespaces[prefix]) {\n      doc.namespaces.add(prefix, urn, '#default#VML');\n    }\n  }\n\n  function addNamespacesAndStylesheet(doc) {\n    addNamespace(doc, 'g_vml_', 'urn:schemas-microsoft-com:vml');\n    addNamespace(doc, 'g_o_', 'urn:schemas-microsoft-com:office:office');\n\n    // Setup default CSS.  Only add one style sheet per document\n    if (!doc.styleSheets['ex_canvas_']) {\n      var ss = doc.createStyleSheet();\n      ss.owningElement.id = 'ex_canvas_';\n      ss.cssText = 'canvas{display:inline-block;overflow:hidden;' +\n          // default size is 300x150 in Gecko and Opera\n          'text-align:left;width:300px;height:150px}';\n    }\n  }\n\n  // Add namespaces and stylesheet at startup.\n  addNamespacesAndStylesheet(document);\n\n  var G_vmlCanvasManager_ = {\n    init: function(opt_doc) {\n      var doc = opt_doc || document;\n      // Create a dummy element so that IE will allow canvas elements to be\n      // recognized.\n      doc.createElement('canvas');\n      doc.attachEvent('onreadystatechange', bind(this.init_, this, doc));\n    },\n\n    init_: function(doc) {\n      // find all canvas elements\n      var els = doc.getElementsByTagName('canvas');\n      for (var i = 0; i < els.length; i++) {\n        this.initElement(els[i]);\n      }\n    },\n\n    /**\n     * Public initializes a canvas element so that it can be used as canvas\n     * element from now on. This is called automatically before the page is\n     * loaded but if you are creating elements using createElement you need to\n     * make sure this is called on the element.\n     * @param {HTMLElement} el The canvas element to initialize.\n     * @return {HTMLElement} the element that was created.\n     */\n    initElement: function(el) {\n      if (!el.getContext) {\n        el.getContext = getContext;\n\n        // Add namespaces and stylesheet to document of the element.\n        addNamespacesAndStylesheet(el.ownerDocument);\n\n        // Remove fallback content. There is no way to hide text nodes so we\n        // just remove all childNodes. We could hide all elements and remove\n        // text nodes but who really cares about the fallback content.\n        el.innerHTML = '';\n\n        // do not use inline function because that will leak memory\n        el.attachEvent('onpropertychange', onPropertyChange);\n        el.attachEvent('onresize', onResize);\n\n        var attrs = el.attributes;\n        if (attrs.width && attrs.width.specified) {\n          // TODO: use runtimeStyle and coordsize\n          // el.getContext().setWidth_(attrs.width.nodeValue);\n          el.style.width = attrs.width.nodeValue + 'px';\n        } else {\n          el.width = el.clientWidth;\n        }\n        if (attrs.height && attrs.height.specified) {\n          // TODO: use runtimeStyle and coordsize\n          // el.getContext().setHeight_(attrs.height.nodeValue);\n          el.style.height = attrs.height.nodeValue + 'px';\n        } else {\n          el.height = el.clientHeight;\n        }\n        //el.getContext().setCoordsize_()\n      }\n      return el;\n    }\n  };\n\n  function onPropertyChange(e) {\n    var el = e.srcElement;\n\n    switch (e.propertyName) {\n      case 'width':\n        el.getContext().clearRect();\n        el.style.width = el.attributes.width.nodeValue + 'px';\n        // In IE8 this does not trigger onresize.\n        el.firstChild.style.width =  el.clientWidth + 'px';\n        break;\n      case 'height':\n        el.getContext().clearRect();\n        el.style.height = el.attributes.height.nodeValue + 'px';\n        el.firstChild.style.height = el.clientHeight + 'px';\n        break;\n    }\n  }\n\n  function onResize(e) {\n    var el = e.srcElement;\n    if (el.firstChild) {\n      el.firstChild.style.width =  el.clientWidth + 'px';\n      el.firstChild.style.height = el.clientHeight + 'px';\n    }\n  }\n\n  G_vmlCanvasManager_.init();\n\n  // precompute \"00\" to \"FF\"\n  var decToHex = [];\n  for (var i = 0; i < 16; i++) {\n    for (var j = 0; j < 16; j++) {\n      decToHex[i * 16 + j] = i.toString(16) + j.toString(16);\n    }\n  }\n\n  function createMatrixIdentity() {\n    return [\n      [1, 0, 0],\n      [0, 1, 0],\n      [0, 0, 1]\n    ];\n  }\n\n  function matrixMultiply(m1, m2) {\n    var result = createMatrixIdentity();\n\n    for (var x = 0; x < 3; x++) {\n      for (var y = 0; y < 3; y++) {\n        var sum = 0;\n\n        for (var z = 0; z < 3; z++) {\n          sum += m1[x][z] * m2[z][y];\n        }\n\n        result[x][y] = sum;\n      }\n    }\n    return result;\n  }\n\n  function copyState(o1, o2) {\n    o2.fillStyle     = o1.fillStyle;\n    o2.lineCap       = o1.lineCap;\n    o2.lineJoin      = o1.lineJoin;\n    o2.lineWidth     = o1.lineWidth;\n    o2.miterLimit    = o1.miterLimit;\n    o2.shadowBlur    = o1.shadowBlur;\n    o2.shadowColor   = o1.shadowColor;\n    o2.shadowOffsetX = o1.shadowOffsetX;\n    o2.shadowOffsetY = o1.shadowOffsetY;\n    o2.strokeStyle   = o1.strokeStyle;\n    o2.globalAlpha   = o1.globalAlpha;\n    o2.font          = o1.font;\n    o2.textAlign     = o1.textAlign;\n    o2.textBaseline  = o1.textBaseline;\n    o2.arcScaleX_    = o1.arcScaleX_;\n    o2.arcScaleY_    = o1.arcScaleY_;\n    o2.lineScale_    = o1.lineScale_;\n  }\n\n  var colorData = {\n    aliceblue: '#F0F8FF',\n    antiquewhite: '#FAEBD7',\n    aquamarine: '#7FFFD4',\n    azure: '#F0FFFF',\n    beige: '#F5F5DC',\n    bisque: '#FFE4C4',\n    black: '#000000',\n    blanchedalmond: '#FFEBCD',\n    blueviolet: '#8A2BE2',\n    brown: '#A52A2A',\n    burlywood: '#DEB887',\n    cadetblue: '#5F9EA0',\n    chartreuse: '#7FFF00',\n    chocolate: '#D2691E',\n    coral: '#FF7F50',\n    cornflowerblue: '#6495ED',\n    cornsilk: '#FFF8DC',\n    crimson: '#DC143C',\n    cyan: '#00FFFF',\n    darkblue: '#00008B',\n    darkcyan: '#008B8B',\n    darkgoldenrod: '#B8860B',\n    darkgray: '#A9A9A9',\n    darkgreen: '#006400',\n    darkgrey: '#A9A9A9',\n    darkkhaki: '#BDB76B',\n    darkmagenta: '#8B008B',\n    darkolivegreen: '#556B2F',\n    darkorange: '#FF8C00',\n    darkorchid: '#9932CC',\n    darkred: '#8B0000',\n    darksalmon: '#E9967A',\n    darkseagreen: '#8FBC8F',\n    darkslateblue: '#483D8B',\n    darkslategray: '#2F4F4F',\n    darkslategrey: '#2F4F4F',\n    darkturquoise: '#00CED1',\n    darkviolet: '#9400D3',\n    deeppink: '#FF1493',\n    deepskyblue: '#00BFFF',\n    dimgray: '#696969',\n    dimgrey: '#696969',\n    dodgerblue: '#1E90FF',\n    firebrick: '#B22222',\n    floralwhite: '#FFFAF0',\n    forestgreen: '#228B22',\n    gainsboro: '#DCDCDC',\n    ghostwhite: '#F8F8FF',\n    gold: '#FFD700',\n    goldenrod: '#DAA520',\n    grey: '#808080',\n    greenyellow: '#ADFF2F',\n    honeydew: '#F0FFF0',\n    hotpink: '#FF69B4',\n    indianred: '#CD5C5C',\n    indigo: '#4B0082',\n    ivory: '#FFFFF0',\n    khaki: '#F0E68C',\n    lavender: '#E6E6FA',\n    lavenderblush: '#FFF0F5',\n    lawngreen: '#7CFC00',\n    lemonchiffon: '#FFFACD',\n    lightblue: '#ADD8E6',\n    lightcoral: '#F08080',\n    lightcyan: '#E0FFFF',\n    lightgoldenrodyellow: '#FAFAD2',\n    lightgreen: '#90EE90',\n    lightgrey: '#D3D3D3',\n    lightpink: '#FFB6C1',\n    lightsalmon: '#FFA07A',\n    lightseagreen: '#20B2AA',\n    lightskyblue: '#87CEFA',\n    lightslategray: '#778899',\n    lightslategrey: '#778899',\n    lightsteelblue: '#B0C4DE',\n    lightyellow: '#FFFFE0',\n    limegreen: '#32CD32',\n    linen: '#FAF0E6',\n    magenta: '#FF00FF',\n    mediumaquamarine: '#66CDAA',\n    mediumblue: '#0000CD',\n    mediumorchid: '#BA55D3',\n    mediumpurple: '#9370DB',\n    mediumseagreen: '#3CB371',\n    mediumslateblue: '#7B68EE',\n    mediumspringgreen: '#00FA9A',\n    mediumturquoise: '#48D1CC',\n    mediumvioletred: '#C71585',\n    midnightblue: '#191970',\n    mintcream: '#F5FFFA',\n    mistyrose: '#FFE4E1',\n    moccasin: '#FFE4B5',\n    navajowhite: '#FFDEAD',\n    oldlace: '#FDF5E6',\n    olivedrab: '#6B8E23',\n    orange: '#FFA500',\n    orangered: '#FF4500',\n    orchid: '#DA70D6',\n    palegoldenrod: '#EEE8AA',\n    palegreen: '#98FB98',\n    paleturquoise: '#AFEEEE',\n    palevioletred: '#DB7093',\n    papayawhip: '#FFEFD5',\n    peachpuff: '#FFDAB9',\n    peru: '#CD853F',\n    pink: '#FFC0CB',\n    plum: '#DDA0DD',\n    powderblue: '#B0E0E6',\n    rosybrown: '#BC8F8F',\n    royalblue: '#4169E1',\n    saddlebrown: '#8B4513',\n    salmon: '#FA8072',\n    sandybrown: '#F4A460',\n    seagreen: '#2E8B57',\n    seashell: '#FFF5EE',\n    sienna: '#A0522D',\n    skyblue: '#87CEEB',\n    slateblue: '#6A5ACD',\n    slategray: '#708090',\n    slategrey: '#708090',\n    snow: '#FFFAFA',\n    springgreen: '#00FF7F',\n    steelblue: '#4682B4',\n    tan: '#D2B48C',\n    thistle: '#D8BFD8',\n    tomato: '#FF6347',\n    turquoise: '#40E0D0',\n    violet: '#EE82EE',\n    wheat: '#F5DEB3',\n    whitesmoke: '#F5F5F5',\n    yellowgreen: '#9ACD32'\n  };\n\n\n  function getRgbHslContent(styleString) {\n    var start = styleString.indexOf('(', 3);\n    var end = styleString.indexOf(')', start + 1);\n    var parts = styleString.substring(start + 1, end).split(',');\n    // add alpha if needed\n    if (parts.length != 4 || styleString.charAt(3) != 'a') {\n      parts[3] = 1;\n    }\n    return parts;\n  }\n\n  function percent(s) {\n    return parseFloat(s) / 100;\n  }\n\n  function clamp(v, min, max) {\n    return Math.min(max, Math.max(min, v));\n  }\n\n  function hslToRgb(parts){\n    var r, g, b, h, s, l;\n    h = parseFloat(parts[0]) / 360 % 360;\n    if (h < 0)\n      h++;\n    s = clamp(percent(parts[1]), 0, 1);\n    l = clamp(percent(parts[2]), 0, 1);\n    if (s == 0) {\n      r = g = b = l; // achromatic\n    } else {\n      var q = l < 0.5 ? l * (1 + s) : l + s - l * s;\n      var p = 2 * l - q;\n      r = hueToRgb(p, q, h + 1 / 3);\n      g = hueToRgb(p, q, h);\n      b = hueToRgb(p, q, h - 1 / 3);\n    }\n\n    return '#' + decToHex[Math.floor(r * 255)] +\n        decToHex[Math.floor(g * 255)] +\n        decToHex[Math.floor(b * 255)];\n  }\n\n  function hueToRgb(m1, m2, h) {\n    if (h < 0)\n      h++;\n    if (h > 1)\n      h--;\n\n    if (6 * h < 1)\n      return m1 + (m2 - m1) * 6 * h;\n    else if (2 * h < 1)\n      return m2;\n    else if (3 * h < 2)\n      return m1 + (m2 - m1) * (2 / 3 - h) * 6;\n    else\n      return m1;\n  }\n\n  var processStyleCache = {};\n\n  function processStyle(styleString) {\n    if (styleString in processStyleCache) {\n      return processStyleCache[styleString];\n    }\n\n    var str, alpha = 1;\n\n    styleString = String(styleString);\n    if (styleString.charAt(0) == '#') {\n      str = styleString;\n    } else if (/^rgb/.test(styleString)) {\n      var parts = getRgbHslContent(styleString);\n      var str = '#', n;\n      for (var i = 0; i < 3; i++) {\n        if (parts[i].indexOf('%') != -1) {\n          n = Math.floor(percent(parts[i]) * 255);\n        } else {\n          n = +parts[i];\n        }\n        str += decToHex[clamp(n, 0, 255)];\n      }\n      alpha = +parts[3];\n    } else if (/^hsl/.test(styleString)) {\n      var parts = getRgbHslContent(styleString);\n      str = hslToRgb(parts);\n      alpha = parts[3];\n    } else {\n      str = colorData[styleString] || styleString;\n    }\n    return processStyleCache[styleString] = {color: str, alpha: alpha};\n  }\n\n  var DEFAULT_STYLE = {\n    style: 'normal',\n    variant: 'normal',\n    weight: 'normal',\n    size: 10,\n    family: 'sans-serif'\n  };\n\n  // Internal text style cache\n  var fontStyleCache = {};\n\n  function processFontStyle(styleString) {\n    if (fontStyleCache[styleString]) {\n      return fontStyleCache[styleString];\n    }\n\n    var el = document.createElement('div');\n    var style = el.style;\n    try {\n      style.font = styleString;\n    } catch (ex) {\n      // Ignore failures to set to invalid font.\n    }\n\n    return fontStyleCache[styleString] = {\n      style: style.fontStyle || DEFAULT_STYLE.style,\n      variant: style.fontVariant || DEFAULT_STYLE.variant,\n      weight: style.fontWeight || DEFAULT_STYLE.weight,\n      size: style.fontSize || DEFAULT_STYLE.size,\n      family: style.fontFamily || DEFAULT_STYLE.family\n    };\n  }\n\n  function getComputedStyle(style, element) {\n    var computedStyle = {};\n\n    for (var p in style) {\n      computedStyle[p] = style[p];\n    }\n\n    // Compute the size\n    var canvasFontSize = parseFloat(element.currentStyle.fontSize),\n        fontSize = parseFloat(style.size);\n\n    if (typeof style.size == 'number') {\n      computedStyle.size = style.size;\n    } else if (style.size.indexOf('px') != -1) {\n      computedStyle.size = fontSize;\n    } else if (style.size.indexOf('em') != -1) {\n      computedStyle.size = canvasFontSize * fontSize;\n    } else if(style.size.indexOf('%') != -1) {\n      computedStyle.size = (canvasFontSize / 100) * fontSize;\n    } else if (style.size.indexOf('pt') != -1) {\n      computedStyle.size = fontSize / .75;\n    } else {\n      computedStyle.size = canvasFontSize;\n    }\n\n    // Different scaling between normal text and VML text. This was found using\n    // trial and error to get the same size as non VML text.\n    computedStyle.size *= 0.981;\n\n    return computedStyle;\n  }\n\n  function buildStyle(style) {\n    return style.style + ' ' + style.variant + ' ' + style.weight + ' ' +\n        style.size + 'px ' + style.family;\n  }\n\n  var lineCapMap = {\n    'butt': 'flat',\n    'round': 'round'\n  };\n\n  function processLineCap(lineCap) {\n    return lineCapMap[lineCap] || 'square';\n  }\n\n  /**\n   * This class implements CanvasRenderingContext2D interface as described by\n   * the WHATWG.\n   * @param {HTMLElement} canvasElement The element that the 2D context should\n   * be associated with\n   */\n  function CanvasRenderingContext2D_(canvasElement) {\n    this.m_ = createMatrixIdentity();\n\n    this.mStack_ = [];\n    this.aStack_ = [];\n    this.currentPath_ = [];\n\n    // Canvas context properties\n    this.strokeStyle = '#000';\n    this.fillStyle = '#000';\n\n    this.lineWidth = 1;\n    this.lineJoin = 'miter';\n    this.lineCap = 'butt';\n    this.miterLimit = Z * 1;\n    this.globalAlpha = 1;\n    this.font = '10px sans-serif';\n    this.textAlign = 'left';\n    this.textBaseline = 'alphabetic';\n    this.canvas = canvasElement;\n\n    var cssText = 'width:' + canvasElement.clientWidth + 'px;height:' +\n        canvasElement.clientHeight + 'px;overflow:hidden;position:absolute';\n    var el = canvasElement.ownerDocument.createElement('div');\n    el.style.cssText = cssText;\n    canvasElement.appendChild(el);\n\n    var overlayEl = el.cloneNode(false);\n    // Use a non transparent background.\n    overlayEl.style.backgroundColor = 'red';\n    overlayEl.style.filter = 'alpha(opacity=0)';\n    canvasElement.appendChild(overlayEl);\n\n    this.element_ = el;\n    this.arcScaleX_ = 1;\n    this.arcScaleY_ = 1;\n    this.lineScale_ = 1;\n  }\n\n  var contextPrototype = CanvasRenderingContext2D_.prototype;\n  contextPrototype.clearRect = function() {\n    if (this.textMeasureEl_) {\n      this.textMeasureEl_.removeNode(true);\n      this.textMeasureEl_ = null;\n    }\n    this.element_.innerHTML = '';\n  };\n\n  contextPrototype.beginPath = function() {\n    // TODO: Branch current matrix so that save/restore has no effect\n    //       as per safari docs.\n    this.currentPath_ = [];\n  };\n\n  contextPrototype.moveTo = function(aX, aY) {\n    var p = getCoords(this, aX, aY);\n    this.currentPath_.push({type: 'moveTo', x: p.x, y: p.y});\n    this.currentX_ = p.x;\n    this.currentY_ = p.y;\n  };\n\n  contextPrototype.lineTo = function(aX, aY) {\n    var p = getCoords(this, aX, aY);\n    this.currentPath_.push({type: 'lineTo', x: p.x, y: p.y});\n\n    this.currentX_ = p.x;\n    this.currentY_ = p.y;\n  };\n\n  contextPrototype.bezierCurveTo = function(aCP1x, aCP1y,\n                                            aCP2x, aCP2y,\n                                            aX, aY) {\n    var p = getCoords(this, aX, aY);\n    var cp1 = getCoords(this, aCP1x, aCP1y);\n    var cp2 = getCoords(this, aCP2x, aCP2y);\n    bezierCurveTo(this, cp1, cp2, p);\n  };\n\n  // Helper function that takes the already fixed cordinates.\n  function bezierCurveTo(self, cp1, cp2, p) {\n    self.currentPath_.push({\n      type: 'bezierCurveTo',\n      cp1x: cp1.x,\n      cp1y: cp1.y,\n      cp2x: cp2.x,\n      cp2y: cp2.y,\n      x: p.x,\n      y: p.y\n    });\n    self.currentX_ = p.x;\n    self.currentY_ = p.y;\n  }\n\n  contextPrototype.quadraticCurveTo = function(aCPx, aCPy, aX, aY) {\n    // the following is lifted almost directly from\n    // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes\n\n    var cp = getCoords(this, aCPx, aCPy);\n    var p = getCoords(this, aX, aY);\n\n    var cp1 = {\n      x: this.currentX_ + 2.0 / 3.0 * (cp.x - this.currentX_),\n      y: this.currentY_ + 2.0 / 3.0 * (cp.y - this.currentY_)\n    };\n    var cp2 = {\n      x: cp1.x + (p.x - this.currentX_) / 3.0,\n      y: cp1.y + (p.y - this.currentY_) / 3.0\n    };\n\n    bezierCurveTo(this, cp1, cp2, p);\n  };\n\n  contextPrototype.arc = function(aX, aY, aRadius,\n                                  aStartAngle, aEndAngle, aClockwise) {\n    aRadius *= Z;\n    var arcType = aClockwise ? 'at' : 'wa';\n\n    var xStart = aX + mc(aStartAngle) * aRadius - Z2;\n    var yStart = aY + ms(aStartAngle) * aRadius - Z2;\n\n    var xEnd = aX + mc(aEndAngle) * aRadius - Z2;\n    var yEnd = aY + ms(aEndAngle) * aRadius - Z2;\n\n    // IE won't render arches drawn counter clockwise if xStart == xEnd.\n    if (xStart == xEnd && !aClockwise) {\n      xStart += 0.125; // Offset xStart by 1/80 of a pixel. Use something\n                       // that can be represented in binary\n    }\n\n    var p = getCoords(this, aX, aY);\n    var pStart = getCoords(this, xStart, yStart);\n    var pEnd = getCoords(this, xEnd, yEnd);\n\n    this.currentPath_.push({type: arcType,\n                           x: p.x,\n                           y: p.y,\n                           radius: aRadius,\n                           xStart: pStart.x,\n                           yStart: pStart.y,\n                           xEnd: pEnd.x,\n                           yEnd: pEnd.y});\n\n  };\n\n  contextPrototype.rect = function(aX, aY, aWidth, aHeight) {\n    this.moveTo(aX, aY);\n    this.lineTo(aX + aWidth, aY);\n    this.lineTo(aX + aWidth, aY + aHeight);\n    this.lineTo(aX, aY + aHeight);\n    this.closePath();\n  };\n\n  contextPrototype.strokeRect = function(aX, aY, aWidth, aHeight) {\n    var oldPath = this.currentPath_;\n    this.beginPath();\n\n    this.moveTo(aX, aY);\n    this.lineTo(aX + aWidth, aY);\n    this.lineTo(aX + aWidth, aY + aHeight);\n    this.lineTo(aX, aY + aHeight);\n    this.closePath();\n    this.stroke();\n\n    this.currentPath_ = oldPath;\n  };\n\n  contextPrototype.fillRect = function(aX, aY, aWidth, aHeight) {\n    var oldPath = this.currentPath_;\n    this.beginPath();\n\n    this.moveTo(aX, aY);\n    this.lineTo(aX + aWidth, aY);\n    this.lineTo(aX + aWidth, aY + aHeight);\n    this.lineTo(aX, aY + aHeight);\n    this.closePath();\n    this.fill();\n\n    this.currentPath_ = oldPath;\n  };\n\n  contextPrototype.createLinearGradient = function(aX0, aY0, aX1, aY1) {\n    var gradient = new CanvasGradient_('gradient');\n    gradient.x0_ = aX0;\n    gradient.y0_ = aY0;\n    gradient.x1_ = aX1;\n    gradient.y1_ = aY1;\n    return gradient;\n  };\n\n  contextPrototype.createRadialGradient = function(aX0, aY0, aR0,\n                                                   aX1, aY1, aR1) {\n    var gradient = new CanvasGradient_('gradientradial');\n    gradient.x0_ = aX0;\n    gradient.y0_ = aY0;\n    gradient.r0_ = aR0;\n    gradient.x1_ = aX1;\n    gradient.y1_ = aY1;\n    gradient.r1_ = aR1;\n    return gradient;\n  };\n\n  contextPrototype.drawImage = function(image, var_args) {\n    var dx, dy, dw, dh, sx, sy, sw, sh;\n\n    // to find the original width we overide the width and height\n    var oldRuntimeWidth = image.runtimeStyle.width;\n    var oldRuntimeHeight = image.runtimeStyle.height;\n    image.runtimeStyle.width = 'auto';\n    image.runtimeStyle.height = 'auto';\n\n    // get the original size\n    var w = image.width;\n    var h = image.height;\n\n    // and remove overides\n    image.runtimeStyle.width = oldRuntimeWidth;\n    image.runtimeStyle.height = oldRuntimeHeight;\n\n    if (arguments.length == 3) {\n      dx = arguments[1];\n      dy = arguments[2];\n      sx = sy = 0;\n      sw = dw = w;\n      sh = dh = h;\n    } else if (arguments.length == 5) {\n      dx = arguments[1];\n      dy = arguments[2];\n      dw = arguments[3];\n      dh = arguments[4];\n      sx = sy = 0;\n      sw = w;\n      sh = h;\n    } else if (arguments.length == 9) {\n      sx = arguments[1];\n      sy = arguments[2];\n      sw = arguments[3];\n      sh = arguments[4];\n      dx = arguments[5];\n      dy = arguments[6];\n      dw = arguments[7];\n      dh = arguments[8];\n    } else {\n      throw Error('Invalid number of arguments');\n    }\n\n    var d = getCoords(this, dx, dy);\n\n    var w2 = sw / 2;\n    var h2 = sh / 2;\n\n    var vmlStr = [];\n\n    var W = 10;\n    var H = 10;\n\n    // For some reason that I've now forgotten, using divs didn't work\n    vmlStr.push(' <g_vml_:group',\n                ' coordsize=\"', Z * W, ',', Z * H, '\"',\n                ' coordorigin=\"0,0\"' ,\n                ' style=\"width:', W, 'px;height:', H, 'px;position:absolute;');\n\n    // If filters are necessary (rotation exists), create them\n    // filters are bog-slow, so only create them if abbsolutely necessary\n    // The following check doesn't account for skews (which don't exist\n    // in the canvas spec (yet) anyway.\n\n    if (this.m_[0][0] != 1 || this.m_[0][1] ||\n        this.m_[1][1] != 1 || this.m_[1][0]) {\n      var filter = [];\n\n      // Note the 12/21 reversal\n      filter.push('M11=', this.m_[0][0], ',',\n                  'M12=', this.m_[1][0], ',',\n                  'M21=', this.m_[0][1], ',',\n                  'M22=', this.m_[1][1], ',',\n                  'Dx=', mr(d.x / Z), ',',\n                  'Dy=', mr(d.y / Z), '');\n\n      // Bounding box calculation (need to minimize displayed area so that\n      // filters don't waste time on unused pixels.\n      var max = d;\n      var c2 = getCoords(this, dx + dw, dy);\n      var c3 = getCoords(this, dx, dy + dh);\n      var c4 = getCoords(this, dx + dw, dy + dh);\n\n      max.x = m.max(max.x, c2.x, c3.x, c4.x);\n      max.y = m.max(max.y, c2.y, c3.y, c4.y);\n\n      vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),\n                  'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',\n                  filter.join(''), \", sizingmethod='clip');\");\n\n    } else {\n      vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');\n    }\n\n    vmlStr.push(' \">' ,\n                '<g_vml_:image src=\"', image.src, '\"',\n                ' style=\"width:', Z * dw, 'px;',\n                ' height:', Z * dh, 'px\"',\n                ' cropleft=\"', sx / w, '\"',\n                ' croptop=\"', sy / h, '\"',\n                ' cropright=\"', (w - sx - sw) / w, '\"',\n                ' cropbottom=\"', (h - sy - sh) / h, '\"',\n                ' />',\n                '</g_vml_:group>');\n\n    this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join(''));\n  };\n\n  contextPrototype.stroke = function(aFill) {\n    var W = 10;\n    var H = 10;\n    // Divide the shape into chunks if it's too long because IE has a limit\n    // somewhere for how long a VML shape can be. This simple division does\n    // not work with fills, only strokes, unfortunately.\n    var chunkSize = 5000;\n\n    var min = {x: null, y: null};\n    var max = {x: null, y: null};\n\n    for (var j = 0; j < this.currentPath_.length; j += chunkSize) {\n      var lineStr = [];\n      var lineOpen = false;\n\n      lineStr.push('<g_vml_:shape',\n                   ' filled=\"', !!aFill, '\"',\n                   ' style=\"position:absolute;width:', W, 'px;height:', H, 'px;\"',\n                   ' coordorigin=\"0,0\"',\n                   ' coordsize=\"', Z * W, ',', Z * H, '\"',\n                   ' stroked=\"', !aFill, '\"',\n                   ' path=\"');\n\n      var newSeq = false;\n\n      for (var i = j; i < Math.min(j + chunkSize, this.currentPath_.length); i++) {\n        if (i % chunkSize == 0 && i > 0) { // move into position for next chunk\n          lineStr.push(' m ', mr(this.currentPath_[i-1].x), ',', mr(this.currentPath_[i-1].y));\n        }\n\n        var p = this.currentPath_[i];\n        var c;\n\n        switch (p.type) {\n          case 'moveTo':\n            c = p;\n            lineStr.push(' m ', mr(p.x), ',', mr(p.y));\n            break;\n          case 'lineTo':\n            lineStr.push(' l ', mr(p.x), ',', mr(p.y));\n            break;\n          case 'close':\n            lineStr.push(' x ');\n            p = null;\n            break;\n          case 'bezierCurveTo':\n            lineStr.push(' c ',\n                         mr(p.cp1x), ',', mr(p.cp1y), ',',\n                         mr(p.cp2x), ',', mr(p.cp2y), ',',\n                         mr(p.x), ',', mr(p.y));\n            break;\n          case 'at':\n          case 'wa':\n            lineStr.push(' ', p.type, ' ',\n                         mr(p.x - this.arcScaleX_ * p.radius), ',',\n                         mr(p.y - this.arcScaleY_ * p.radius), ' ',\n                         mr(p.x + this.arcScaleX_ * p.radius), ',',\n                         mr(p.y + this.arcScaleY_ * p.radius), ' ',\n                         mr(p.xStart), ',', mr(p.yStart), ' ',\n                         mr(p.xEnd), ',', mr(p.yEnd));\n            break;\n        }\n  \n  \n        // TODO: Following is broken for curves due to\n        //       move to proper paths.\n  \n        // Figure out dimensions so we can do gradient fills\n        // properly\n        if (p) {\n          if (min.x == null || p.x < min.x) {\n            min.x = p.x;\n          }\n          if (max.x == null || p.x > max.x) {\n            max.x = p.x;\n          }\n          if (min.y == null || p.y < min.y) {\n            min.y = p.y;\n          }\n          if (max.y == null || p.y > max.y) {\n            max.y = p.y;\n          }\n        }\n      }\n      lineStr.push(' \">');\n  \n      if (!aFill) {\n        appendStroke(this, lineStr);\n      } else {\n        appendFill(this, lineStr, min, max);\n      }\n  \n      lineStr.push('</g_vml_:shape>');\n  \n      this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));\n    }\n  };\n\n  function appendStroke(ctx, lineStr) {\n    var a = processStyle(ctx.strokeStyle);\n    var color = a.color;\n    var opacity = a.alpha * ctx.globalAlpha;\n    var lineWidth = ctx.lineScale_ * ctx.lineWidth;\n\n    // VML cannot correctly render a line if the width is less than 1px.\n    // In that case, we dilute the color to make the line look thinner.\n    if (lineWidth < 1) {\n      opacity *= lineWidth;\n    }\n\n    lineStr.push(\n      '<g_vml_:stroke',\n      ' opacity=\"', opacity, '\"',\n      ' joinstyle=\"', ctx.lineJoin, '\"',\n      ' miterlimit=\"', ctx.miterLimit, '\"',\n      ' endcap=\"', processLineCap(ctx.lineCap), '\"',\n      ' weight=\"', lineWidth, 'px\"',\n      ' color=\"', color, '\" />'\n    );\n  }\n\n  function appendFill(ctx, lineStr, min, max) {\n    var fillStyle = ctx.fillStyle;\n    var arcScaleX = ctx.arcScaleX_;\n    var arcScaleY = ctx.arcScaleY_;\n    var width = max.x - min.x;\n    var height = max.y - min.y;\n    if (fillStyle instanceof CanvasGradient_) {\n      // TODO: Gradients transformed with the transformation matrix.\n      var angle = 0;\n      var focus = {x: 0, y: 0};\n\n      // additional offset\n      var shift = 0;\n      // scale factor for offset\n      var expansion = 1;\n\n      if (fillStyle.type_ == 'gradient') {\n        var x0 = fillStyle.x0_ / arcScaleX;\n        var y0 = fillStyle.y0_ / arcScaleY;\n        var x1 = fillStyle.x1_ / arcScaleX;\n        var y1 = fillStyle.y1_ / arcScaleY;\n        var p0 = getCoords(ctx, x0, y0);\n        var p1 = getCoords(ctx, x1, y1);\n        var dx = p1.x - p0.x;\n        var dy = p1.y - p0.y;\n        angle = Math.atan2(dx, dy) * 180 / Math.PI;\n\n        // The angle should be a non-negative number.\n        if (angle < 0) {\n          angle += 360;\n        }\n\n        // Very small angles produce an unexpected result because they are\n        // converted to a scientific notation string.\n        if (angle < 1e-6) {\n          angle = 0;\n        }\n      } else {\n        var p0 = getCoords(ctx, fillStyle.x0_, fillStyle.y0_);\n        focus = {\n          x: (p0.x - min.x) / width,\n          y: (p0.y - min.y) / height\n        };\n\n        width  /= arcScaleX * Z;\n        height /= arcScaleY * Z;\n        var dimension = m.max(width, height);\n        shift = 2 * fillStyle.r0_ / dimension;\n        expansion = 2 * fillStyle.r1_ / dimension - shift;\n      }\n\n      // We need to sort the color stops in ascending order by offset,\n      // otherwise IE won't interpret it correctly.\n      var stops = fillStyle.colors_;\n      stops.sort(function(cs1, cs2) {\n        return cs1.offset - cs2.offset;\n      });\n\n      var length = stops.length;\n      var color1 = stops[0].color;\n      var color2 = stops[length - 1].color;\n      var opacity1 = stops[0].alpha * ctx.globalAlpha;\n      var opacity2 = stops[length - 1].alpha * ctx.globalAlpha;\n\n      var colors = [];\n      for (var i = 0; i < length; i++) {\n        var stop = stops[i];\n        colors.push(stop.offset * expansion + shift + ' ' + stop.color);\n      }\n\n      // When colors attribute is used, the meanings of opacity and o:opacity2\n      // are reversed.\n      lineStr.push('<g_vml_:fill type=\"', fillStyle.type_, '\"',\n                   ' method=\"none\" focus=\"100%\"',\n                   ' color=\"', color1, '\"',\n                   ' color2=\"', color2, '\"',\n                   ' colors=\"', colors.join(','), '\"',\n                   ' opacity=\"', opacity2, '\"',\n                   ' g_o_:opacity2=\"', opacity1, '\"',\n                   ' angle=\"', angle, '\"',\n                   ' focusposition=\"', focus.x, ',', focus.y, '\" />');\n    } else if (fillStyle instanceof CanvasPattern_) {\n      if (width && height) {\n        var deltaLeft = -min.x;\n        var deltaTop = -min.y;\n        lineStr.push('<g_vml_:fill',\n                     ' position=\"',\n                     deltaLeft / width * arcScaleX * arcScaleX, ',',\n                     deltaTop / height * arcScaleY * arcScaleY, '\"',\n                     ' type=\"tile\"',\n                     // TODO: Figure out the correct size to fit the scale.\n                     //' size=\"', w, 'px ', h, 'px\"',\n                     ' src=\"', fillStyle.src_, '\" />');\n       }\n    } else {\n      var a = processStyle(ctx.fillStyle);\n      var color = a.color;\n      var opacity = a.alpha * ctx.globalAlpha;\n      lineStr.push('<g_vml_:fill color=\"', color, '\" opacity=\"', opacity,\n                   '\" />');\n    }\n  }\n\n  contextPrototype.fill = function() {\n    this.stroke(true);\n  };\n\n  contextPrototype.closePath = function() {\n    this.currentPath_.push({type: 'close'});\n  };\n\n  function getCoords(ctx, aX, aY) {\n    var m = ctx.m_;\n    return {\n      x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,\n      y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2\n    };\n  }\n    contextPrototype.save = function() {\n    var o = {};\n    copyState(this, o);\n    this.aStack_.push(o);\n    this.mStack_.push(this.m_);\n    this.m_ = matrixMultiply(createMatrixIdentity(), this.m_);\n  };\n\n  contextPrototype.restore = function() {\n    if (this.aStack_.length) {\n      copyState(this.aStack_.pop(), this);\n      this.m_ = this.mStack_.pop();\n    }\n  };\n\n  function matrixIsFinite(m) {\n    return isFinite(m[0][0]) && isFinite(m[0][1]) &&\n        isFinite(m[1][0]) && isFinite(m[1][1]) &&\n        isFinite(m[2][0]) && isFinite(m[2][1]);\n  }\n\n  function setM(ctx, m, updateLineScale) {\n    if (!matrixIsFinite(m)) {\n      return;\n    }\n    ctx.m_ = m;\n\n    if (updateLineScale) {\n      // Get the line scale.\n      // Determinant of this.m_ means how much the area is enlarged by the\n      // transformation. So its square root can be used as a scale factor\n      // for width.\n      var det = m[0][0] * m[1][1] - m[0][1] * m[1][0];\n      ctx.lineScale_ = sqrt(abs(det));\n    }\n  }\n\n  contextPrototype.translate = function(aX, aY) {\n    var m1 = [\n      [1,  0,  0],\n      [0,  1,  0],\n      [aX, aY, 1]\n    ];\n\n    setM(this, matrixMultiply(m1, this.m_), false);\n  };\n\n  contextPrototype.rotate = function(aRot) {\n    var c = mc(aRot);\n    var s = ms(aRot);\n\n    var m1 = [\n      [c,  s, 0],\n      [-s, c, 0],\n      [0,  0, 1]\n    ];\n\n    setM(this, matrixMultiply(m1, this.m_), false);\n  };\n\n  contextPrototype.scale = function(aX, aY) {\n    this.arcScaleX_ *= aX;\n    this.arcScaleY_ *= aY;\n    var m1 = [\n      [aX, 0,  0],\n      [0,  aY, 0],\n      [0,  0,  1]\n    ];\n\n    setM(this, matrixMultiply(m1, this.m_), true);\n  };\n\n  contextPrototype.transform = function(m11, m12, m21, m22, dx, dy) {\n    var m1 = [\n      [m11, m12, 0],\n      [m21, m22, 0],\n      [dx,  dy,  1]\n    ];\n\n    setM(this, matrixMultiply(m1, this.m_), true);\n  };\n\n  contextPrototype.setTransform = function(m11, m12, m21, m22, dx, dy) {\n    var m = [\n      [m11, m12, 0],\n      [m21, m22, 0],\n      [dx,  dy,  1]\n    ];\n\n    setM(this, m, true);\n  };\n\n  /**\n   * The text drawing function.\n   * The maxWidth argument isn't taken in account, since no browser supports\n   * it yet.\n   */\n  contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) {\n    var m = this.m_,\n        delta = 1000,\n        left = 0,\n        right = delta,\n        offset = {x: 0, y: 0},\n        lineStr = [];\n\n    var fontStyle = getComputedStyle(processFontStyle(this.font),\n                                     this.element_);\n\n    var fontStyleString = buildStyle(fontStyle);\n\n    var elementStyle = this.element_.currentStyle;\n    var textAlign = this.textAlign.toLowerCase();\n    switch (textAlign) {\n      case 'left':\n      case 'center':\n      case 'right':\n        break;\n      case 'end':\n        textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left';\n        break;\n      case 'start':\n        textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left';\n        break;\n      default:\n        textAlign = 'left';\n    }\n\n    // 1.75 is an arbitrary number, as there is no info about the text baseline\n    switch (this.textBaseline) {\n      case 'hanging':\n      case 'top':\n        offset.y = fontStyle.size / 1.75;\n        break;\n      case 'middle':\n        break;\n      default:\n      case null:\n      case 'alphabetic':\n      case 'ideographic':\n      case 'bottom':\n        offset.y = -fontStyle.size / 2.25;\n        break;\n    }\n\n    switch(textAlign) {\n      case 'right':\n        left = delta;\n        right = 0.05;\n        break;\n      case 'center':\n        left = right = delta / 2;\n        break;\n    }\n\n    var d = getCoords(this, x + offset.x, y + offset.y);\n\n    lineStr.push('<g_vml_:line from=\"', -left ,' 0\" to=\"', right ,' 0.05\" ',\n                 ' coordsize=\"100 100\" coordorigin=\"0 0\"',\n                 ' filled=\"', !stroke, '\" stroked=\"', !!stroke,\n                 '\" style=\"position:absolute;width:1px;height:1px;\">');\n\n    if (stroke) {\n      appendStroke(this, lineStr);\n    } else {\n      // TODO: Fix the min and max params.\n      appendFill(this, lineStr, {x: -left, y: 0},\n                 {x: right, y: fontStyle.size});\n    }\n\n    var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' +\n                m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0';\n\n    var skewOffset = mr(d.x / Z) + ',' + mr(d.y / Z);\n\n    lineStr.push('<g_vml_:skew on=\"t\" matrix=\"', skewM ,'\" ',\n                 ' offset=\"', skewOffset, '\" origin=\"', left ,' 0\" />',\n                 '<g_vml_:path textpathok=\"true\" />',\n                 '<g_vml_:textpath on=\"true\" string=\"',\n                 encodeHtmlAttribute(text),\n                 '\" style=\"v-text-align:', textAlign,\n                 ';font:', encodeHtmlAttribute(fontStyleString),\n                 '\" /></g_vml_:line>');\n\n    this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));\n  };\n\n  contextPrototype.fillText = function(text, x, y, maxWidth) {\n    this.drawText_(text, x, y, maxWidth, false);\n  };\n\n  contextPrototype.strokeText = function(text, x, y, maxWidth) {\n    this.drawText_(text, x, y, maxWidth, true);\n  };\n\n  contextPrototype.measureText = function(text) {\n    if (!this.textMeasureEl_) {\n      var s = '<span style=\"position:absolute;' +\n          'top:-20000px;left:0;padding:0;margin:0;border:none;' +\n          'white-space:pre;\"></span>';\n      this.element_.insertAdjacentHTML('beforeEnd', s);\n      this.textMeasureEl_ = this.element_.lastChild;\n    }\n    var doc = this.element_.ownerDocument;\n    this.textMeasureEl_.innerHTML = '';\n    this.textMeasureEl_.style.font = this.font;\n    // Don't use innerHTML or innerText because they allow markup/whitespace.\n    this.textMeasureEl_.appendChild(doc.createTextNode(text));\n    return {width: this.textMeasureEl_.offsetWidth};\n  };\n\n  /******** STUBS ********/\n  contextPrototype.clip = function() {\n    // TODO: Implement\n  };\n\n  contextPrototype.arcTo = function() {\n    // TODO: Implement\n  };\n\n  contextPrototype.createPattern = function(image, repetition) {\n    return new CanvasPattern_(image, repetition);\n  };\n\n  // Gradient / Pattern Stubs\n  function CanvasGradient_(aType) {\n    this.type_ = aType;\n    this.x0_ = 0;\n    this.y0_ = 0;\n    this.r0_ = 0;\n    this.x1_ = 0;\n    this.y1_ = 0;\n    this.r1_ = 0;\n    this.colors_ = [];\n  }\n\n  CanvasGradient_.prototype.addColorStop = function(aOffset, aColor) {\n    aColor = processStyle(aColor);\n    this.colors_.push({offset: aOffset,\n                       color: aColor.color,\n                       alpha: aColor.alpha});\n  };\n\n  function CanvasPattern_(image, repetition) {\n    assertImageIsValid(image);\n    switch (repetition) {\n      case 'repeat':\n      case null:\n      case '':\n        this.repetition_ = 'repeat';\n        break;\n      case 'repeat-x':\n      case 'repeat-y':\n      case 'no-repeat':\n        this.repetition_ = repetition;\n        break;\n      default:\n        throwException('SYNTAX_ERR');\n    }\n\n    this.src_ = image.src;\n    this.width_ = image.width;\n    this.height_ = image.height;\n  }\n\n  function throwException(s) {\n    throw new DOMException_(s);\n  }\n\n  function assertImageIsValid(img) {\n    if (!img || img.nodeType != 1 || img.tagName != 'IMG') {\n      throwException('TYPE_MISMATCH_ERR');\n    }\n    if (img.readyState != 'complete') {\n      throwException('INVALID_STATE_ERR');\n    }\n  }\n\n  function DOMException_(s) {\n    this.code = this[s];\n    this.message = s +': DOM Exception ' + this.code;\n  }\n  var p = DOMException_.prototype = new Error;\n  p.INDEX_SIZE_ERR = 1;\n  p.DOMSTRING_SIZE_ERR = 2;\n  p.HIERARCHY_REQUEST_ERR = 3;\n  p.WRONG_DOCUMENT_ERR = 4;\n  p.INVALID_CHARACTER_ERR = 5;\n  p.NO_DATA_ALLOWED_ERR = 6;\n  p.NO_MODIFICATION_ALLOWED_ERR = 7;\n  p.NOT_FOUND_ERR = 8;\n  p.NOT_SUPPORTED_ERR = 9;\n  p.INUSE_ATTRIBUTE_ERR = 10;\n  p.INVALID_STATE_ERR = 11;\n  p.SYNTAX_ERR = 12;\n  p.INVALID_MODIFICATION_ERR = 13;\n  p.NAMESPACE_ERR = 14;\n  p.INVALID_ACCESS_ERR = 15;\n  p.VALIDATION_ERR = 16;\n  p.TYPE_MISMATCH_ERR = 17;\n\n  // set up externs\n  G_vmlCanvasManager = G_vmlCanvasManager_;\n  CanvasRenderingContext2D = CanvasRenderingContext2D_;\n  CanvasGradient = CanvasGradient_;\n  CanvasPattern = CanvasPattern_;\n  DOMException = DOMException_;\n})();\n\n} // if\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.colorhelpers.js",
    "content": "/* Plugin for jQuery for working with colors.\n * \n * Version 1.1.\n * \n * Inspiration from jQuery color animation plugin by John Resig.\n *\n * Released under the MIT license by Ole Laursen, October 2009.\n *\n * Examples:\n *\n *   $.color.parse(\"#fff\").scale('rgb', 0.25).add('a', -0.5).toString()\n *   var c = $.color.extract($(\"#mydiv\"), 'background-color');\n *   console.log(c.r, c.g, c.b, c.a);\n *   $.color.make(100, 50, 25, 0.4).toString() // returns \"rgba(100,50,25,0.4)\"\n *\n * Note that .scale() and .add() return the same modified object\n * instead of making a new one.\n *\n * V. 1.1: Fix error handling so e.g. parsing an empty string does\n * produce a color rather than just crashing.\n */ \n\n(function($) {\n    $.color = {};\n\n    // construct color object with some convenient chainable helpers\n    $.color.make = function (r, g, b, a) {\n        var o = {};\n        o.r = r || 0;\n        o.g = g || 0;\n        o.b = b || 0;\n        o.a = a != null ? a : 1;\n\n        o.add = function (c, d) {\n            for (var i = 0; i < c.length; ++i)\n                o[c.charAt(i)] += d;\n            return o.normalize();\n        };\n        \n        o.scale = function (c, f) {\n            for (var i = 0; i < c.length; ++i)\n                o[c.charAt(i)] *= f;\n            return o.normalize();\n        };\n        \n        o.toString = function () {\n            if (o.a >= 1.0) {\n                return \"rgb(\"+[o.r, o.g, o.b].join(\",\")+\")\";\n            } else {\n                return \"rgba(\"+[o.r, o.g, o.b, o.a].join(\",\")+\")\";\n            }\n        };\n\n        o.normalize = function () {\n            function clamp(min, value, max) {\n                return value < min ? min: (value > max ? max: value);\n            }\n            \n            o.r = clamp(0, parseInt(o.r), 255);\n            o.g = clamp(0, parseInt(o.g), 255);\n            o.b = clamp(0, parseInt(o.b), 255);\n            o.a = clamp(0, o.a, 1);\n            return o;\n        };\n\n        o.clone = function () {\n            return $.color.make(o.r, o.b, o.g, o.a);\n        };\n\n        return o.normalize();\n    };\n\n    // extract CSS color property from element, going up in the DOM\n    // if it's \"transparent\"\n    $.color.extract = function (elem, css) {\n        var c;\n\n        do {\n            c = elem.css(css).toLowerCase();\n            // keep going until we find an element that has color, or\n            // we hit the body or root (have no parent)\n            if (c != '' && c != 'transparent')\n                break;\n            elem = elem.parent();\n        } while (elem.length && !$.nodeName(elem.get(0), \"body\"));\n\n        // catch Safari's way of signalling transparent\n        if (c == \"rgba(0, 0, 0, 0)\")\n            c = \"transparent\";\n        \n        return $.color.parse(c);\n    };\n    \n    // parse CSS color string (like \"rgb(10, 32, 43)\" or \"#fff\"),\n    // returns color object, if parsing failed, you get black (0, 0,\n    // 0) out\n    $.color.parse = function (str) {\n        var res, m = $.color.make;\n\n        // Look for rgb(num,num,num)\n        if (res = /rgb\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)/.exec(str))\n            return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10));\n        \n        // Look for rgba(num,num,num,num)\n        if (res = /rgba\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\)/.exec(str))\n            return m(parseInt(res[1], 10), parseInt(res[2], 10), parseInt(res[3], 10), parseFloat(res[4]));\n            \n        // Look for rgb(num%,num%,num%)\n        if (res = /rgb\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*\\)/.exec(str))\n            return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55);\n\n        // Look for rgba(num%,num%,num%,num)\n        if (res = /rgba\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\)/.exec(str))\n            return m(parseFloat(res[1])*2.55, parseFloat(res[2])*2.55, parseFloat(res[3])*2.55, parseFloat(res[4]));\n        \n        // Look for #a0b1c2\n        if (res = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))\n            return m(parseInt(res[1], 16), parseInt(res[2], 16), parseInt(res[3], 16));\n\n        // Look for #fff\n        if (res = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))\n            return m(parseInt(res[1]+res[1], 16), parseInt(res[2]+res[2], 16), parseInt(res[3]+res[3], 16));\n\n        // Otherwise, we're most likely dealing with a named color\n        var name = $.trim(str).toLowerCase();\n        if (name == \"transparent\")\n            return m(255, 255, 255, 0);\n        else {\n            // default to black\n            res = lookupColors[name] || [0, 0, 0];\n            return m(res[0], res[1], res[2]);\n        }\n    };\n    \n    var lookupColors = {\n        aqua:[0,255,255],\n        azure:[240,255,255],\n        beige:[245,245,220],\n        black:[0,0,0],\n        blue:[0,0,255],\n        brown:[165,42,42],\n        cyan:[0,255,255],\n        darkblue:[0,0,139],\n        darkcyan:[0,139,139],\n        darkgrey:[169,169,169],\n        darkgreen:[0,100,0],\n        darkkhaki:[189,183,107],\n        darkmagenta:[139,0,139],\n        darkolivegreen:[85,107,47],\n        darkorange:[255,140,0],\n        darkorchid:[153,50,204],\n        darkred:[139,0,0],\n        darksalmon:[233,150,122],\n        darkviolet:[148,0,211],\n        fuchsia:[255,0,255],\n        gold:[255,215,0],\n        green:[0,128,0],\n        indigo:[75,0,130],\n        khaki:[240,230,140],\n        lightblue:[173,216,230],\n        lightcyan:[224,255,255],\n        lightgreen:[144,238,144],\n        lightgrey:[211,211,211],\n        lightpink:[255,182,193],\n        lightyellow:[255,255,224],\n        lime:[0,255,0],\n        magenta:[255,0,255],\n        maroon:[128,0,0],\n        navy:[0,0,128],\n        olive:[128,128,0],\n        orange:[255,165,0],\n        pink:[255,192,203],\n        purple:[128,0,128],\n        violet:[128,0,128],\n        red:[255,0,0],\n        silver:[192,192,192],\n        white:[255,255,255],\n        yellow:[255,255,0]\n    };\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.canvas.js",
    "content": "/* Flot plugin for drawing all elements of a plot on the canvas.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nFlot normally produces certain elements, like axis labels and the legend, using\nHTML elements. This permits greater interactivity and customization, and often\nlooks better, due to cross-browser canvas text inconsistencies and limitations.\n\nIt can also be desirable to render the plot entirely in canvas, particularly\nif the goal is to save it as an image, or if Flot is being used in a context\nwhere the HTML DOM does not exist, as is the case within Node.js. This plugin\nswitches out Flot's standard drawing operations for canvas-only replacements.\n\nCurrently the plugin supports only axis labels, but it will eventually allow\nevery element of the plot to be rendered directly to canvas.\n\nThe plugin supports these options:\n\n{\n    canvas: boolean\n}\n\nThe \"canvas\" option controls whether full canvas drawing is enabled, making it\npossible to toggle on and off. This is useful when a plot uses HTML text in the\nbrowser, but needs to redraw with canvas text when exporting as an image.\n\n*/\n\n(function($) {\n\n\tvar options = {\n\t\tcanvas: true\n\t};\n\n\tvar render, getTextInfo, addText;\n\n\t// Cache the prototype hasOwnProperty for faster access\n\n\tvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\n\tfunction init(plot, classes) {\n\n\t\tvar Canvas = classes.Canvas;\n\n\t\t// We only want to replace the functions once; the second time around\n\t\t// we would just get our new function back.  This whole replacing of\n\t\t// prototype functions is a disaster, and needs to be changed ASAP.\n\n\t\tif (render == null) {\n\t\t\tgetTextInfo = Canvas.prototype.getTextInfo,\n\t\t\taddText = Canvas.prototype.addText,\n\t\t\trender = Canvas.prototype.render;\n\t\t}\n\n\t\t// Finishes rendering the canvas, including overlaid text\n\n\t\tCanvas.prototype.render = function() {\n\n\t\t\tif (!plot.getOptions().canvas) {\n\t\t\t\treturn render.call(this);\n\t\t\t}\n\n\t\t\tvar context = this.context,\n\t\t\t\tcache = this._textCache;\n\n\t\t\t// For each text layer, render elements marked as active\n\n\t\t\tcontext.save();\n\t\t\tcontext.textBaseline = \"middle\";\n\n\t\t\tfor (var layerKey in cache) {\n\t\t\t\tif (hasOwnProperty.call(cache, layerKey)) {\n\t\t\t\t\tvar layerCache = cache[layerKey];\n\t\t\t\t\tfor (var styleKey in layerCache) {\n\t\t\t\t\t\tif (hasOwnProperty.call(layerCache, styleKey)) {\n\t\t\t\t\t\t\tvar styleCache = layerCache[styleKey],\n\t\t\t\t\t\t\t\tupdateStyles = true;\n\t\t\t\t\t\t\tfor (var key in styleCache) {\n\t\t\t\t\t\t\t\tif (hasOwnProperty.call(styleCache, key)) {\n\n\t\t\t\t\t\t\t\t\tvar info = styleCache[key],\n\t\t\t\t\t\t\t\t\t\tpositions = info.positions,\n\t\t\t\t\t\t\t\t\t\tlines = info.lines;\n\n\t\t\t\t\t\t\t\t\t// Since every element at this level of the cache have the\n\t\t\t\t\t\t\t\t\t// same font and fill styles, we can just change them once\n\t\t\t\t\t\t\t\t\t// using the values from the first element.\n\n\t\t\t\t\t\t\t\t\tif (updateStyles) {\n\t\t\t\t\t\t\t\t\t\tcontext.fillStyle = info.font.color;\n\t\t\t\t\t\t\t\t\t\tcontext.font = info.font.definition;\n\t\t\t\t\t\t\t\t\t\tupdateStyles = false;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\t\t\t\t\t\t\tif (position.active) {\n\t\t\t\t\t\t\t\t\t\t\tfor (var j = 0, line; line = position.lines[j]; j++) {\n\t\t\t\t\t\t\t\t\t\t\t\tcontext.fillText(lines[j].text, line[0], line[1]);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tpositions.splice(i--, 1);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif (positions.length == 0) {\n\t\t\t\t\t\t\t\t\t\tdelete styleCache[key];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tcontext.restore();\n\t\t};\n\n\t\t// Creates (if necessary) and returns a text info object.\n\t\t//\n\t\t// When the canvas option is set, the object looks like this:\n\t\t//\n\t\t// {\n\t\t//     width: Width of the text's bounding box.\n\t\t//     height: Height of the text's bounding box.\n\t\t//     positions: Array of positions at which this text is drawn.\n\t\t//     lines: [{\n\t\t//         height: Height of this line.\n\t\t//         widths: Width of this line.\n\t\t//         text: Text on this line.\n\t\t//     }],\n\t\t//     font: {\n\t\t//         definition: Canvas font property string.\n\t\t//         color: Color of the text.\n\t\t//     },\n\t\t// }\n\t\t//\n\t\t// The positions array contains objects that look like this:\n\t\t//\n\t\t// {\n\t\t//     active: Flag indicating whether the text should be visible.\n\t\t//     lines: Array of [x, y] coordinates at which to draw the line.\n\t\t//     x: X coordinate at which to draw the text.\n\t\t//     y: Y coordinate at which to draw the text.\n\t\t// }\n\n\t\tCanvas.prototype.getTextInfo = function(layer, text, font, angle, width) {\n\n\t\t\tif (!plot.getOptions().canvas) {\n\t\t\t\treturn getTextInfo.call(this, layer, text, font, angle, width);\n\t\t\t}\n\n\t\t\tvar textStyle, layerCache, styleCache, info;\n\n\t\t\t// Cast the value to a string, in case we were given a number\n\n\t\t\ttext = \"\" + text;\n\n\t\t\t// If the font is a font-spec object, generate a CSS definition\n\n\t\t\tif (typeof font === \"object\") {\n\t\t\t\ttextStyle = font.style + \" \" + font.variant + \" \" + font.weight + \" \" + font.size + \"px \" + font.family;\n\t\t\t} else {\n\t\t\t\ttextStyle = font;\n\t\t\t}\n\n\t\t\t// Retrieve (or create) the cache for the text's layer and styles\n\n\t\t\tlayerCache = this._textCache[layer];\n\n\t\t\tif (layerCache == null) {\n\t\t\t\tlayerCache = this._textCache[layer] = {};\n\t\t\t}\n\n\t\t\tstyleCache = layerCache[textStyle];\n\n\t\t\tif (styleCache == null) {\n\t\t\t\tstyleCache = layerCache[textStyle] = {};\n\t\t\t}\n\n\t\t\tinfo = styleCache[text];\n\n\t\t\tif (info == null) {\n\n\t\t\t\tvar context = this.context;\n\n\t\t\t\t// If the font was provided as CSS, create a div with those\n\t\t\t\t// classes and examine it to generate a canvas font spec.\n\n\t\t\t\tif (typeof font !== \"object\") {\n\n\t\t\t\t\tvar element = $(\"<div>&nbsp;</div>\")\n\t\t\t\t\t\t.css(\"position\", \"absolute\")\n\t\t\t\t\t\t.addClass(typeof font === \"string\" ? font : null)\n\t\t\t\t\t\t.appendTo(this.getTextLayer(layer));\n\n\t\t\t\t\tfont = {\n\t\t\t\t\t\tlineHeight: element.height(),\n\t\t\t\t\t\tstyle: element.css(\"font-style\"),\n\t\t\t\t\t\tvariant: element.css(\"font-variant\"),\n\t\t\t\t\t\tweight: element.css(\"font-weight\"),\n\t\t\t\t\t\tfamily: element.css(\"font-family\"),\n\t\t\t\t\t\tcolor: element.css(\"color\")\n\t\t\t\t\t};\n\n\t\t\t\t\t// Setting line-height to 1, without units, sets it equal\n\t\t\t\t\t// to the font-size, even if the font-size is abstract,\n\t\t\t\t\t// like 'smaller'.  This enables us to read the real size\n\t\t\t\t\t// via the element's height, working around browsers that\n\t\t\t\t\t// return the literal 'smaller' value.\n\n\t\t\t\t\tfont.size = element.css(\"line-height\", 1).height();\n\n\t\t\t\t\telement.remove();\n\t\t\t\t}\n\n\t\t\t\ttextStyle = font.style + \" \" + font.variant + \" \" + font.weight + \" \" + font.size + \"px \" + font.family;\n\n\t\t\t\t// Create a new info object, initializing the dimensions to\n\t\t\t\t// zero so we can count them up line-by-line.\n\n\t\t\t\tinfo = styleCache[text] = {\n\t\t\t\t\twidth: 0,\n\t\t\t\t\theight: 0,\n\t\t\t\t\tpositions: [],\n\t\t\t\t\tlines: [],\n\t\t\t\t\tfont: {\n\t\t\t\t\t\tdefinition: textStyle,\n\t\t\t\t\t\tcolor: font.color\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\tcontext.save();\n\t\t\t\tcontext.font = textStyle;\n\n\t\t\t\t// Canvas can't handle multi-line strings; break on various\n\t\t\t\t// newlines, including HTML brs, to build a list of lines.\n\t\t\t\t// Note that we could split directly on regexps, but IE < 9 is\n\t\t\t\t// broken; revisit when we drop IE 7/8 support.\n\n\t\t\t\tvar lines = (text + \"\").replace(/<br ?\\/?>|\\r\\n|\\r/g, \"\\n\").split(\"\\n\");\n\n\t\t\t\tfor (var i = 0; i < lines.length; ++i) {\n\n\t\t\t\t\tvar lineText = lines[i],\n\t\t\t\t\t\tmeasured = context.measureText(lineText);\n\n\t\t\t\t\tinfo.width = Math.max(measured.width, info.width);\n\t\t\t\t\tinfo.height += font.lineHeight;\n\n\t\t\t\t\tinfo.lines.push({\n\t\t\t\t\t\ttext: lineText,\n\t\t\t\t\t\twidth: measured.width,\n\t\t\t\t\t\theight: font.lineHeight\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tcontext.restore();\n\t\t\t}\n\n\t\t\treturn info;\n\t\t};\n\n\t\t// Adds a text string to the canvas text overlay.\n\n\t\tCanvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {\n\n\t\t\tif (!plot.getOptions().canvas) {\n\t\t\t\treturn addText.call(this, layer, x, y, text, font, angle, width, halign, valign);\n\t\t\t}\n\n\t\t\tvar info = this.getTextInfo(layer, text, font, angle, width),\n\t\t\t\tpositions = info.positions,\n\t\t\t\tlines = info.lines;\n\n\t\t\t// Text is drawn with baseline 'middle', which we need to account\n\t\t\t// for by adding half a line's height to the y position.\n\n\t\t\ty += info.height / lines.length / 2;\n\n\t\t\t// Tweak the initial y-position to match vertical alignment\n\n\t\t\tif (valign == \"middle\") {\n\t\t\t\ty = Math.round(y - info.height / 2);\n\t\t\t} else if (valign == \"bottom\") {\n\t\t\t\ty = Math.round(y - info.height);\n\t\t\t} else {\n\t\t\t\ty = Math.round(y);\n\t\t\t}\n\n\t\t\t// FIXME: LEGACY BROWSER FIX\n\t\t\t// AFFECTS: Opera < 12.00\n\n\t\t\t// Offset the y coordinate, since Opera is off pretty\n\t\t\t// consistently compared to the other browsers.\n\n\t\t\tif (!!(window.opera && window.opera.version().split(\".\")[0] < 12)) {\n\t\t\t\ty -= 2;\n\t\t\t}\n\n\t\t\t// Determine whether this text already exists at this position.\n\t\t\t// If so, mark it for inclusion in the next render pass.\n\n\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\tif (position.x == x && position.y == y) {\n\t\t\t\t\tposition.active = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the text doesn't exist at this position, create a new entry\n\n\t\t\tposition = {\n\t\t\t\tactive: true,\n\t\t\t\tlines: [],\n\t\t\t\tx: x,\n\t\t\t\ty: y\n\t\t\t};\n\n\t\t\tpositions.push(position);\n\n\t\t\t// Fill in the x & y positions of each line, adjusting them\n\t\t\t// individually for horizontal alignment.\n\n\t\t\tfor (var i = 0, line; line = lines[i]; i++) {\n\t\t\t\tif (halign == \"center\") {\n\t\t\t\t\tposition.lines.push([Math.round(x - line.width / 2), y]);\n\t\t\t\t} else if (halign == \"right\") {\n\t\t\t\t\tposition.lines.push([Math.round(x - line.width), y]);\n\t\t\t\t} else {\n\t\t\t\t\tposition.lines.push([Math.round(x), y]);\n\t\t\t\t}\n\t\t\t\ty += line.height;\n\t\t\t}\n\t\t};\n\t}\n\n\t$.plot.plugins.push({\n\t\tinit: init,\n\t\toptions: options,\n\t\tname: \"canvas\",\n\t\tversion: \"1.0\"\n\t});\n\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.categories.js",
    "content": "/* Flot plugin for plotting textual data or categories.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nConsider a dataset like [[\"February\", 34], [\"March\", 20], ...]. This plugin\nallows you to plot such a dataset directly.\n\nTo enable it, you must specify mode: \"categories\" on the axis with the textual\nlabels, e.g.\n\n\t$.plot(\"#placeholder\", data, { xaxis: { mode: \"categories\" } });\n\nBy default, the labels are ordered as they are met in the data series. If you\nneed a different ordering, you can specify \"categories\" on the axis options\nand list the categories there:\n\n\txaxis: {\n\t\tmode: \"categories\",\n\t\tcategories: [\"February\", \"March\", \"April\"]\n\t}\n\nIf you need to customize the distances between the categories, you can specify\n\"categories\" as an object mapping labels to values\n\n\txaxis: {\n\t\tmode: \"categories\",\n\t\tcategories: { \"February\": 1, \"March\": 3, \"April\": 4 }\n\t}\n\nIf you don't specify all categories, the remaining categories will be numbered\nfrom the max value plus 1 (with a spacing of 1 between each).\n\nInternally, the plugin works by transforming the input data through an auto-\ngenerated mapping where the first category becomes 0, the second 1, etc.\nHence, a point like [\"February\", 34] becomes [0, 34] internally in Flot (this\nis visible in hover and click events that return numbers rather than the\ncategory labels). The plugin also overrides the tick generator to spit out the\ncategories as ticks instead of the values.\n\nIf you need to map a value back to its label, the mapping is always accessible\nas \"categories\" on the axis object, e.g. plot.getAxes().xaxis.categories.\n\n*/\n\n(function ($) {\n    var options = {\n        xaxis: {\n            categories: null\n        },\n        yaxis: {\n            categories: null\n        }\n    };\n    \n    function processRawData(plot, series, data, datapoints) {\n        // if categories are enabled, we need to disable\n        // auto-transformation to numbers so the strings are intact\n        // for later processing\n\n        var xCategories = series.xaxis.options.mode == \"categories\",\n            yCategories = series.yaxis.options.mode == \"categories\";\n        \n        if (!(xCategories || yCategories))\n            return;\n\n        var format = datapoints.format;\n\n        if (!format) {\n            // FIXME: auto-detection should really not be defined here\n            var s = series;\n            format = [];\n            format.push({ x: true, number: true, required: true });\n            format.push({ y: true, number: true, required: true });\n\n            if (s.bars.show || (s.lines.show && s.lines.fill)) {\n                var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));\n                format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });\n                if (s.bars.horizontal) {\n                    delete format[format.length - 1].y;\n                    format[format.length - 1].x = true;\n                }\n            }\n            \n            datapoints.format = format;\n        }\n\n        for (var m = 0; m < format.length; ++m) {\n            if (format[m].x && xCategories)\n                format[m].number = false;\n            \n            if (format[m].y && yCategories)\n                format[m].number = false;\n        }\n    }\n\n    function getNextIndex(categories) {\n        var index = -1;\n        \n        for (var v in categories)\n            if (categories[v] > index)\n                index = categories[v];\n\n        return index + 1;\n    }\n\n    function categoriesTickGenerator(axis) {\n        var res = [];\n        for (var label in axis.categories) {\n            var v = axis.categories[label];\n            if (v >= axis.min && v <= axis.max)\n                res.push([v, label]);\n        }\n\n        res.sort(function (a, b) { return a[0] - b[0]; });\n\n        return res;\n    }\n    \n    function setupCategoriesForAxis(series, axis, datapoints) {\n        if (series[axis].options.mode != \"categories\")\n            return;\n        \n        if (!series[axis].categories) {\n            // parse options\n            var c = {}, o = series[axis].options.categories || {};\n            if ($.isArray(o)) {\n                for (var i = 0; i < o.length; ++i)\n                    c[o[i]] = i;\n            }\n            else {\n                for (var v in o)\n                    c[v] = o[v];\n            }\n            \n            series[axis].categories = c;\n        }\n\n        // fix ticks\n        if (!series[axis].options.ticks)\n            series[axis].options.ticks = categoriesTickGenerator;\n\n        transformPointsOnAxis(datapoints, axis, series[axis].categories);\n    }\n    \n    function transformPointsOnAxis(datapoints, axis, categories) {\n        // go through the points, transforming them\n        var points = datapoints.points,\n            ps = datapoints.pointsize,\n            format = datapoints.format,\n            formatColumn = axis.charAt(0),\n            index = getNextIndex(categories);\n\n        for (var i = 0; i < points.length; i += ps) {\n            if (points[i] == null)\n                continue;\n            \n            for (var m = 0; m < ps; ++m) {\n                var val = points[i + m];\n\n                if (val == null || !format[m][formatColumn])\n                    continue;\n\n                if (!(val in categories)) {\n                    categories[val] = index;\n                    ++index;\n                }\n                \n                points[i + m] = categories[val];\n            }\n        }\n    }\n\n    function processDatapoints(plot, series, datapoints) {\n        setupCategoriesForAxis(series, \"xaxis\", datapoints);\n        setupCategoriesForAxis(series, \"yaxis\", datapoints);\n    }\n\n    function init(plot) {\n        plot.hooks.processRawData.push(processRawData);\n        plot.hooks.processDatapoints.push(processDatapoints);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'categories',\n        version: '1.0'\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.crosshair.js",
    "content": "/* Flot plugin for showing crosshairs when the mouse hovers over the plot.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin supports these options:\n\n\tcrosshair: {\n\t\tmode: null or \"x\" or \"y\" or \"xy\"\n\t\tcolor: color\n\t\tlineWidth: number\n\t}\n\nSet the mode to one of \"x\", \"y\" or \"xy\". The \"x\" mode enables a vertical\ncrosshair that lets you trace the values on the x axis, \"y\" enables a\nhorizontal crosshair and \"xy\" enables them both. \"color\" is the color of the\ncrosshair (default is \"rgba(170, 0, 0, 0.80)\"), \"lineWidth\" is the width of\nthe drawn lines (default is 1).\n\nThe plugin also adds four public methods:\n\n  - setCrosshair( pos )\n\n    Set the position of the crosshair. Note that this is cleared if the user\n    moves the mouse. \"pos\" is in coordinates of the plot and should be on the\n    form { x: xpos, y: ypos } (you can use x2/x3/... if you're using multiple\n    axes), which is coincidentally the same format as what you get from a\n    \"plothover\" event. If \"pos\" is null, the crosshair is cleared.\n\n  - clearCrosshair()\n\n    Clear the crosshair.\n\n  - lockCrosshair(pos)\n\n    Cause the crosshair to lock to the current location, no longer updating if\n    the user moves the mouse. Optionally supply a position (passed on to\n    setCrosshair()) to move it to.\n\n    Example usage:\n\n\tvar myFlot = $.plot( $(\"#graph\"), ..., { crosshair: { mode: \"x\" } } };\n\t$(\"#graph\").bind( \"plothover\", function ( evt, position, item ) {\n\t\tif ( item ) {\n\t\t\t// Lock the crosshair to the data point being hovered\n\t\t\tmyFlot.lockCrosshair({\n\t\t\t\tx: item.datapoint[ 0 ],\n\t\t\t\ty: item.datapoint[ 1 ]\n\t\t\t});\n\t\t} else {\n\t\t\t// Return normal crosshair operation\n\t\t\tmyFlot.unlockCrosshair();\n\t\t}\n\t});\n\n  - unlockCrosshair()\n\n    Free the crosshair to move again after locking it.\n*/\n\n(function ($) {\n    var options = {\n        crosshair: {\n            mode: null, // one of null, \"x\", \"y\" or \"xy\",\n            color: \"rgba(170, 0, 0, 0.80)\",\n            lineWidth: 1\n        }\n    };\n    \n    function init(plot) {\n        // position of crosshair in pixels\n        var crosshair = { x: -1, y: -1, locked: false };\n\n        plot.setCrosshair = function setCrosshair(pos) {\n            if (!pos)\n                crosshair.x = -1;\n            else {\n                var o = plot.p2c(pos);\n                crosshair.x = Math.max(0, Math.min(o.left, plot.width()));\n                crosshair.y = Math.max(0, Math.min(o.top, plot.height()));\n            }\n            \n            plot.triggerRedrawOverlay();\n        };\n        \n        plot.clearCrosshair = plot.setCrosshair; // passes null for pos\n        \n        plot.lockCrosshair = function lockCrosshair(pos) {\n            if (pos)\n                plot.setCrosshair(pos);\n            crosshair.locked = true;\n        };\n\n        plot.unlockCrosshair = function unlockCrosshair() {\n            crosshair.locked = false;\n        };\n\n        function onMouseOut(e) {\n            if (crosshair.locked)\n                return;\n\n            if (crosshair.x != -1) {\n                crosshair.x = -1;\n                plot.triggerRedrawOverlay();\n            }\n        }\n\n        function onMouseMove(e) {\n            if (crosshair.locked)\n                return;\n                \n            if (plot.getSelection && plot.getSelection()) {\n                crosshair.x = -1; // hide the crosshair while selecting\n                return;\n            }\n                \n            var offset = plot.offset();\n            crosshair.x = Math.max(0, Math.min(e.pageX - offset.left, plot.width()));\n            crosshair.y = Math.max(0, Math.min(e.pageY - offset.top, plot.height()));\n            plot.triggerRedrawOverlay();\n        }\n        \n        plot.hooks.bindEvents.push(function (plot, eventHolder) {\n            if (!plot.getOptions().crosshair.mode)\n                return;\n\n            eventHolder.mouseout(onMouseOut);\n            eventHolder.mousemove(onMouseMove);\n        });\n\n        plot.hooks.drawOverlay.push(function (plot, ctx) {\n            var c = plot.getOptions().crosshair;\n            if (!c.mode)\n                return;\n\n            var plotOffset = plot.getPlotOffset();\n            \n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            if (crosshair.x != -1) {\n                var adj = plot.getOptions().crosshair.lineWidth % 2 === 0 ? 0 : 0.5;\n\n                ctx.strokeStyle = c.color;\n                ctx.lineWidth = c.lineWidth;\n                ctx.lineJoin = \"round\";\n\n                ctx.beginPath();\n                if (c.mode.indexOf(\"x\") != -1) {\n                    var drawX = Math.round(crosshair.x) + adj;\n                    ctx.moveTo(drawX, 0);\n                    ctx.lineTo(drawX, plot.height());\n                }\n                if (c.mode.indexOf(\"y\") != -1) {\n                    var drawY = Math.round(crosshair.y) + adj;\n                    ctx.moveTo(0, drawY);\n                    ctx.lineTo(plot.width(), drawY);\n                }\n                ctx.stroke();\n            }\n            ctx.restore();\n        });\n\n        plot.hooks.shutdown.push(function (plot, eventHolder) {\n            eventHolder.unbind(\"mouseout\", onMouseOut);\n            eventHolder.unbind(\"mousemove\", onMouseMove);\n        });\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'crosshair',\n        version: '1.0'\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.errorbars.js",
    "content": "/* Flot plugin for plotting error bars.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nError bars are used to show standard deviation and other statistical\nproperties in a plot.\n\n* Created by Rui Pereira  -  rui (dot) pereira (at) gmail (dot) com\n\nThis plugin allows you to plot error-bars over points. Set \"errorbars\" inside\nthe points series to the axis name over which there will be error values in\nyour data array (*even* if you do not intend to plot them later, by setting\n\"show: null\" on xerr/yerr).\n\nThe plugin supports these options:\n\n\tseries: {\n\t\tpoints: {\n\t\t\terrorbars: \"x\" or \"y\" or \"xy\",\n\t\t\txerr: {\n\t\t\t\tshow: null/false or true,\n\t\t\t\tasymmetric: null/false or true,\n\t\t\t\tupperCap: null or \"-\" or function,\n\t\t\t\tlowerCap: null or \"-\" or function,\n\t\t\t\tcolor: null or color,\n\t\t\t\tradius: null or number\n\t\t\t},\n\t\t\tyerr: { same options as xerr }\n\t\t}\n\t}\n\nEach data point array is expected to be of the type:\n\n\t\"x\"  [ x, y, xerr ]\n\t\"y\"  [ x, y, yerr ]\n\t\"xy\" [ x, y, xerr, yerr ]\n\nWhere xerr becomes xerr_lower,xerr_upper for the asymmetric error case, and\nequivalently for yerr. Eg., a datapoint for the \"xy\" case with symmetric\nerror-bars on X and asymmetric on Y would be:\n\n\t[ x, y, xerr, yerr_lower, yerr_upper ]\n\nBy default no end caps are drawn. Setting upperCap and/or lowerCap to \"-\" will\ndraw a small cap perpendicular to the error bar. They can also be set to a\nuser-defined drawing function, with (ctx, x, y, radius) as parameters, as eg.\n\n\tfunction drawSemiCircle( ctx, x, y, radius ) {\n\t\tctx.beginPath();\n\t\tctx.arc( x, y, radius, 0, Math.PI, false );\n\t\tctx.moveTo( x - radius, y );\n\t\tctx.lineTo( x + radius, y );\n\t\tctx.stroke();\n\t}\n\nColor and radius both default to the same ones of the points series if not\nset. The independent radius parameter on xerr/yerr is useful for the case when\nwe may want to add error-bars to a line, without showing the interconnecting\npoints (with radius: 0), and still showing end caps on the error-bars.\nshadowSize and lineWidth are derived as well from the points series.\n\n*/\n\n(function ($) {\n    var options = {\n        series: {\n            points: {\n                errorbars: null, //should be 'x', 'y' or 'xy'\n                xerr: { err: 'x', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null},\n                yerr: { err: 'y', show: null, asymmetric: null, upperCap: null, lowerCap: null, color: null, radius: null}\n            }\n        }\n    };\n\n    function processRawData(plot, series, data, datapoints){\n        if (!series.points.errorbars)\n            return;\n\n        // x,y values\n        var format = [\n            { x: true, number: true, required: true },\n            { y: true, number: true, required: true }\n        ];\n\n        var errors = series.points.errorbars;\n        // error bars - first X then Y\n        if (errors == 'x' || errors == 'xy') {\n            // lower / upper error\n            if (series.points.xerr.asymmetric) {\n                format.push({ x: true, number: true, required: true });\n                format.push({ x: true, number: true, required: true });\n            } else\n                format.push({ x: true, number: true, required: true });\n        }\n        if (errors == 'y' || errors == 'xy') {\n            // lower / upper error\n            if (series.points.yerr.asymmetric) {\n                format.push({ y: true, number: true, required: true });\n                format.push({ y: true, number: true, required: true });\n            } else\n                format.push({ y: true, number: true, required: true });\n        }\n        datapoints.format = format;\n    }\n\n    function parseErrors(series, i){\n\n        var points = series.datapoints.points;\n\n        // read errors from points array\n        var exl = null,\n                exu = null,\n                eyl = null,\n                eyu = null;\n        var xerr = series.points.xerr,\n                yerr = series.points.yerr;\n\n        var eb = series.points.errorbars;\n        // error bars - first X\n        if (eb == 'x' || eb == 'xy') {\n            if (xerr.asymmetric) {\n                exl = points[i + 2];\n                exu = points[i + 3];\n                if (eb == 'xy')\n                    if (yerr.asymmetric){\n                        eyl = points[i + 4];\n                        eyu = points[i + 5];\n                    } else eyl = points[i + 4];\n            } else {\n                exl = points[i + 2];\n                if (eb == 'xy')\n                    if (yerr.asymmetric) {\n                        eyl = points[i + 3];\n                        eyu = points[i + 4];\n                    } else eyl = points[i + 3];\n            }\n        // only Y\n        } else if (eb == 'y')\n            if (yerr.asymmetric) {\n                eyl = points[i + 2];\n                eyu = points[i + 3];\n            } else eyl = points[i + 2];\n\n        // symmetric errors?\n        if (exu == null) exu = exl;\n        if (eyu == null) eyu = eyl;\n\n        var errRanges = [exl, exu, eyl, eyu];\n        // nullify if not showing\n        if (!xerr.show){\n            errRanges[0] = null;\n            errRanges[1] = null;\n        }\n        if (!yerr.show){\n            errRanges[2] = null;\n            errRanges[3] = null;\n        }\n        return errRanges;\n    }\n\n    function drawSeriesErrors(plot, ctx, s){\n\n        var points = s.datapoints.points,\n                ps = s.datapoints.pointsize,\n                ax = [s.xaxis, s.yaxis],\n                radius = s.points.radius,\n                err = [s.points.xerr, s.points.yerr];\n\n        //sanity check, in case some inverted axis hack is applied to flot\n        var invertX = false;\n        if (ax[0].p2c(ax[0].max) < ax[0].p2c(ax[0].min)) {\n            invertX = true;\n            var tmp = err[0].lowerCap;\n            err[0].lowerCap = err[0].upperCap;\n            err[0].upperCap = tmp;\n        }\n\n        var invertY = false;\n        if (ax[1].p2c(ax[1].min) < ax[1].p2c(ax[1].max)) {\n            invertY = true;\n            var tmp = err[1].lowerCap;\n            err[1].lowerCap = err[1].upperCap;\n            err[1].upperCap = tmp;\n        }\n\n        for (var i = 0; i < s.datapoints.points.length; i += ps) {\n\n            //parse\n            var errRanges = parseErrors(s, i);\n\n            //cycle xerr & yerr\n            for (var e = 0; e < err.length; e++){\n\n                var minmax = [ax[e].min, ax[e].max];\n\n                //draw this error?\n                if (errRanges[e * err.length]){\n\n                    //data coordinates\n                    var x = points[i],\n                        y = points[i + 1];\n\n                    //errorbar ranges\n                    var upper = [x, y][e] + errRanges[e * err.length + 1],\n                        lower = [x, y][e] - errRanges[e * err.length];\n\n                    //points outside of the canvas\n                    if (err[e].err == 'x')\n                        if (y > ax[1].max || y < ax[1].min || upper < ax[0].min || lower > ax[0].max)\n                            continue;\n                    if (err[e].err == 'y')\n                        if (x > ax[0].max || x < ax[0].min || upper < ax[1].min || lower > ax[1].max)\n                            continue;\n\n                    // prevent errorbars getting out of the canvas\n                    var drawUpper = true,\n                        drawLower = true;\n\n                    if (upper > minmax[1]) {\n                        drawUpper = false;\n                        upper = minmax[1];\n                    }\n                    if (lower < minmax[0]) {\n                        drawLower = false;\n                        lower = minmax[0];\n                    }\n\n                    //sanity check, in case some inverted axis hack is applied to flot\n                    if ((err[e].err == 'x' && invertX) || (err[e].err == 'y' && invertY)) {\n                        //swap coordinates\n                        var tmp = lower;\n                        lower = upper;\n                        upper = tmp;\n                        tmp = drawLower;\n                        drawLower = drawUpper;\n                        drawUpper = tmp;\n                        tmp = minmax[0];\n                        minmax[0] = minmax[1];\n                        minmax[1] = tmp;\n                    }\n\n                    // convert to pixels\n                    x = ax[0].p2c(x),\n                        y = ax[1].p2c(y),\n                        upper = ax[e].p2c(upper);\n                    lower = ax[e].p2c(lower);\n                    minmax[0] = ax[e].p2c(minmax[0]);\n                    minmax[1] = ax[e].p2c(minmax[1]);\n\n                    //same style as points by default\n                    var lw = err[e].lineWidth ? err[e].lineWidth : s.points.lineWidth,\n                        sw = s.points.shadowSize != null ? s.points.shadowSize : s.shadowSize;\n\n                    //shadow as for points\n                    if (lw > 0 && sw > 0) {\n                        var w = sw / 2;\n                        ctx.lineWidth = w;\n                        ctx.strokeStyle = \"rgba(0,0,0,0.1)\";\n                        drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w + w/2, minmax);\n\n                        ctx.strokeStyle = \"rgba(0,0,0,0.2)\";\n                        drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, w/2, minmax);\n                    }\n\n                    ctx.strokeStyle = err[e].color? err[e].color: s.color;\n                    ctx.lineWidth = lw;\n                    //draw it\n                    drawError(ctx, err[e], x, y, upper, lower, drawUpper, drawLower, radius, 0, minmax);\n                }\n            }\n        }\n    }\n\n    function drawError(ctx,err,x,y,upper,lower,drawUpper,drawLower,radius,offset,minmax){\n\n        //shadow offset\n        y += offset;\n        upper += offset;\n        lower += offset;\n\n        // error bar - avoid plotting over circles\n        if (err.err == 'x'){\n            if (upper > x + radius) drawPath(ctx, [[upper,y],[Math.max(x + radius,minmax[0]),y]]);\n            else drawUpper = false;\n            if (lower < x - radius) drawPath(ctx, [[Math.min(x - radius,minmax[1]),y],[lower,y]] );\n            else drawLower = false;\n        }\n        else {\n            if (upper < y - radius) drawPath(ctx, [[x,upper],[x,Math.min(y - radius,minmax[0])]] );\n            else drawUpper = false;\n            if (lower > y + radius) drawPath(ctx, [[x,Math.max(y + radius,minmax[1])],[x,lower]] );\n            else drawLower = false;\n        }\n\n        //internal radius value in errorbar, allows to plot radius 0 points and still keep proper sized caps\n        //this is a way to get errorbars on lines without visible connecting dots\n        radius = err.radius != null? err.radius: radius;\n\n        // upper cap\n        if (drawUpper) {\n            if (err.upperCap == '-'){\n                if (err.err=='x') drawPath(ctx, [[upper,y - radius],[upper,y + radius]] );\n                else drawPath(ctx, [[x - radius,upper],[x + radius,upper]] );\n            } else if ($.isFunction(err.upperCap)){\n                if (err.err=='x') err.upperCap(ctx, upper, y, radius);\n                else err.upperCap(ctx, x, upper, radius);\n            }\n        }\n        // lower cap\n        if (drawLower) {\n            if (err.lowerCap == '-'){\n                if (err.err=='x') drawPath(ctx, [[lower,y - radius],[lower,y + radius]] );\n                else drawPath(ctx, [[x - radius,lower],[x + radius,lower]] );\n            } else if ($.isFunction(err.lowerCap)){\n                if (err.err=='x') err.lowerCap(ctx, lower, y, radius);\n                else err.lowerCap(ctx, x, lower, radius);\n            }\n        }\n    }\n\n    function drawPath(ctx, pts){\n        ctx.beginPath();\n        ctx.moveTo(pts[0][0], pts[0][1]);\n        for (var p=1; p < pts.length; p++)\n            ctx.lineTo(pts[p][0], pts[p][1]);\n        ctx.stroke();\n    }\n\n    function draw(plot, ctx){\n        var plotOffset = plot.getPlotOffset();\n\n        ctx.save();\n        ctx.translate(plotOffset.left, plotOffset.top);\n        $.each(plot.getData(), function (i, s) {\n            if (s.points.errorbars && (s.points.xerr.show || s.points.yerr.show))\n                drawSeriesErrors(plot, ctx, s);\n        });\n        ctx.restore();\n    }\n\n    function init(plot) {\n        plot.hooks.processRawData.push(processRawData);\n        plot.hooks.draw.push(draw);\n    }\n\n    $.plot.plugins.push({\n                init: init,\n                options: options,\n                name: 'errorbars',\n                version: '1.0'\n            });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.fillbetween.js",
    "content": "/* Flot plugin for computing bottoms for filled line and bar charts.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe case: you've got two series that you want to fill the area between. In Flot\nterms, you need to use one as the fill bottom of the other. You can specify the\nbottom of each data point as the third coordinate manually, or you can use this\nplugin to compute it for you.\n\nIn order to name the other series, you need to give it an id, like this:\n\n\tvar dataset = [\n\t\t{ data: [ ... ], id: \"foo\" } ,         // use default bottom\n\t\t{ data: [ ... ], fillBetween: \"foo\" }, // use first dataset as bottom\n\t];\n\n\t$.plot($(\"#placeholder\"), dataset, { lines: { show: true, fill: true }});\n\nAs a convenience, if the id given is a number that doesn't appear as an id in\nthe series, it is interpreted as the index in the array instead (so fillBetween:\n0 can also mean the first series).\n\nInternally, the plugin modifies the datapoints in each series. For line series,\nextra data points might be inserted through interpolation. Note that at points\nwhere the bottom line is not defined (due to a null point or start/end of line),\nthe current line will show a gap too. The algorithm comes from the\njquery.flot.stack.js plugin, possibly some code could be shared.\n\n*/\n\n(function ( $ ) {\n\n\tvar options = {\n\t\tseries: {\n\t\t\tfillBetween: null\t// or number\n\t\t}\n\t};\n\n\tfunction init( plot ) {\n\n\t\tfunction findBottomSeries( s, allseries ) {\n\n\t\t\tvar i;\n\n\t\t\tfor ( i = 0; i < allseries.length; ++i ) {\n\t\t\t\tif ( allseries[ i ].id === s.fillBetween ) {\n\t\t\t\t\treturn allseries[ i ];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( typeof s.fillBetween === \"number\" ) {\n\t\t\t\tif ( s.fillBetween < 0 || s.fillBetween >= allseries.length ) {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\treturn allseries[ s.fillBetween ];\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tfunction computeFillBottoms( plot, s, datapoints ) {\n\n\t\t\tif ( s.fillBetween == null ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar other = findBottomSeries( s, plot.getData() );\n\n\t\t\tif ( !other ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar ps = datapoints.pointsize,\n\t\t\t\tpoints = datapoints.points,\n\t\t\t\totherps = other.datapoints.pointsize,\n\t\t\t\totherpoints = other.datapoints.points,\n\t\t\t\tnewpoints = [],\n\t\t\t\tpx, py, intery, qx, qy, bottom,\n\t\t\t\twithlines = s.lines.show,\n\t\t\t\twithbottom = ps > 2 && datapoints.format[2].y,\n\t\t\t\twithsteps = withlines && s.lines.steps,\n\t\t\t\tfromgap = true,\n\t\t\t\ti = 0,\n\t\t\t\tj = 0,\n\t\t\t\tl, m;\n\n\t\t\twhile ( true ) {\n\n\t\t\t\tif ( i >= points.length ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tl = newpoints.length;\n\n\t\t\t\tif ( points[ i ] == null ) {\n\n\t\t\t\t\t// copy gaps\n\n\t\t\t\t\tfor ( m = 0; m < ps; ++m ) {\n\t\t\t\t\t\tnewpoints.push( points[ i + m ] );\n\t\t\t\t\t}\n\n\t\t\t\t\ti += ps;\n\n\t\t\t\t} else if ( j >= otherpoints.length ) {\n\n\t\t\t\t\t// for lines, we can't use the rest of the points\n\n\t\t\t\t\tif ( !withlines ) {\n\t\t\t\t\t\tfor ( m = 0; m < ps; ++m ) {\n\t\t\t\t\t\t\tnewpoints.push( points[ i + m ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\ti += ps;\n\n\t\t\t\t} else if ( otherpoints[ j ] == null ) {\n\n\t\t\t\t\t// oops, got a gap\n\n\t\t\t\t\tfor ( m = 0; m < ps; ++m ) {\n\t\t\t\t\t\tnewpoints.push( null );\n\t\t\t\t\t}\n\n\t\t\t\t\tfromgap = true;\n\t\t\t\t\tj += otherps;\n\n\t\t\t\t} else {\n\n\t\t\t\t\t// cases where we actually got two points\n\n\t\t\t\t\tpx = points[ i ];\n\t\t\t\t\tpy = points[ i + 1 ];\n\t\t\t\t\tqx = otherpoints[ j ];\n\t\t\t\t\tqy = otherpoints[ j + 1 ];\n\t\t\t\t\tbottom = 0;\n\n\t\t\t\t\tif ( px === qx ) {\n\n\t\t\t\t\t\tfor ( m = 0; m < ps; ++m ) {\n\t\t\t\t\t\t\tnewpoints.push( points[ i + m ] );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t//newpoints[ l + 1 ] += qy;\n\t\t\t\t\t\tbottom = qy;\n\n\t\t\t\t\t\ti += ps;\n\t\t\t\t\t\tj += otherps;\n\n\t\t\t\t\t} else if ( px > qx ) {\n\n\t\t\t\t\t\t// we got past point below, might need to\n\t\t\t\t\t\t// insert interpolated extra point\n\n\t\t\t\t\t\tif ( withlines && i > 0 && points[ i - ps ] != null ) {\n\t\t\t\t\t\t\tintery = py + ( points[ i - ps + 1 ] - py ) * ( qx - px ) / ( points[ i - ps ] - px );\n\t\t\t\t\t\t\tnewpoints.push( qx );\n\t\t\t\t\t\t\tnewpoints.push( intery );\n\t\t\t\t\t\t\tfor ( m = 2; m < ps; ++m ) {\n\t\t\t\t\t\t\t\tnewpoints.push( points[ i + m ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbottom = qy;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tj += otherps;\n\n\t\t\t\t\t} else { // px < qx\n\n\t\t\t\t\t\t// if we come from a gap, we just skip this point\n\n\t\t\t\t\t\tif ( fromgap && withlines ) {\n\t\t\t\t\t\t\ti += ps;\n\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor ( m = 0; m < ps; ++m ) {\n\t\t\t\t\t\t\tnewpoints.push( points[ i + m ] );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// we might be able to interpolate a point below,\n\t\t\t\t\t\t// this can give us a better y\n\n\t\t\t\t\t\tif ( withlines && j > 0 && otherpoints[ j - otherps ] != null ) {\n\t\t\t\t\t\t\tbottom = qy + ( otherpoints[ j - otherps + 1 ] - qy ) * ( px - qx ) / ( otherpoints[ j - otherps ] - qx );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t//newpoints[l + 1] += bottom;\n\n\t\t\t\t\t\ti += ps;\n\t\t\t\t\t}\n\n\t\t\t\t\tfromgap = false;\n\n\t\t\t\t\tif ( l !== newpoints.length && withbottom ) {\n\t\t\t\t\t\tnewpoints[ l + 2 ] = bottom;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// maintain the line steps invariant\n\n\t\t\t\tif ( withsteps && l !== newpoints.length && l > 0 &&\n\t\t\t\t\tnewpoints[ l ] !== null &&\n\t\t\t\t\tnewpoints[ l ] !== newpoints[ l - ps ] &&\n\t\t\t\t\tnewpoints[ l + 1 ] !== newpoints[ l - ps + 1 ] ) {\n\t\t\t\t\tfor (m = 0; m < ps; ++m) {\n\t\t\t\t\t\tnewpoints[ l + ps + m ] = newpoints[ l + m ];\n\t\t\t\t\t}\n\t\t\t\t\tnewpoints[ l + 1 ] = newpoints[ l - ps + 1 ];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tdatapoints.points = newpoints;\n\t\t}\n\n\t\tplot.hooks.processDatapoints.push( computeFillBottoms );\n\t}\n\n\t$.plot.plugins.push({\n\t\tinit: init,\n\t\toptions: options,\n\t\tname: \"fillbetween\",\n\t\tversion: \"1.0\"\n\t});\n\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.image.js",
    "content": "/* Flot plugin for plotting images.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe data syntax is [ [ image, x1, y1, x2, y2 ], ... ] where (x1, y1) and\n(x2, y2) are where you intend the two opposite corners of the image to end up\nin the plot. Image must be a fully loaded Javascript image (you can make one\nwith new Image()). If the image is not complete, it's skipped when plotting.\n\nThere are two helpers included for retrieving images. The easiest work the way\nthat you put in URLs instead of images in the data, like this:\n\n\t[ \"myimage.png\", 0, 0, 10, 10 ]\n\nThen call $.plot.image.loadData( data, options, callback ) where data and\noptions are the same as you pass in to $.plot. This loads the images, replaces\nthe URLs in the data with the corresponding images and calls \"callback\" when\nall images are loaded (or failed loading). In the callback, you can then call\n$.plot with the data set. See the included example.\n\nA more low-level helper, $.plot.image.load(urls, callback) is also included.\nGiven a list of URLs, it calls callback with an object mapping from URL to\nImage object when all images are loaded or have failed loading.\n\nThe plugin supports these options:\n\n\tseries: {\n\t\timages: {\n\t\t\tshow: boolean\n\t\t\tanchor: \"corner\" or \"center\"\n\t\t\talpha: [ 0, 1 ]\n\t\t}\n\t}\n\nThey can be specified for a specific series:\n\n\t$.plot( $(\"#placeholder\"), [{\n\t\tdata: [ ... ],\n\t\timages: { ... }\n\t])\n\nNote that because the data format is different from usual data points, you\ncan't use images with anything else in a specific data series.\n\nSetting \"anchor\" to \"center\" causes the pixels in the image to be anchored at\nthe corner pixel centers inside of at the pixel corners, effectively letting\nhalf a pixel stick out to each side in the plot.\n\nA possible future direction could be support for tiling for large images (like\nGoogle Maps).\n\n*/\n\n(function ($) {\n    var options = {\n        series: {\n            images: {\n                show: false,\n                alpha: 1,\n                anchor: \"corner\" // or \"center\"\n            }\n        }\n    };\n\n    $.plot.image = {};\n\n    $.plot.image.loadDataImages = function (series, options, callback) {\n        var urls = [], points = [];\n\n        var defaultShow = options.series.images.show;\n        \n        $.each(series, function (i, s) {\n            if (!(defaultShow || s.images.show))\n                return;\n            \n            if (s.data)\n                s = s.data;\n\n            $.each(s, function (i, p) {\n                if (typeof p[0] == \"string\") {\n                    urls.push(p[0]);\n                    points.push(p);\n                }\n            });\n        });\n\n        $.plot.image.load(urls, function (loadedImages) {\n            $.each(points, function (i, p) {\n                var url = p[0];\n                if (loadedImages[url])\n                    p[0] = loadedImages[url];\n            });\n\n            callback();\n        });\n    };\n    \n    $.plot.image.load = function (urls, callback) {\n        var missing = urls.length, loaded = {};\n        if (missing == 0)\n            callback({});\n\n        $.each(urls, function (i, url) {\n            var handler = function () {\n                --missing;\n                \n                loaded[url] = this;\n                \n                if (missing == 0)\n                    callback(loaded);\n            };\n\n            $('<img />').load(handler).error(handler).attr('src', url);\n        });\n    };\n    \n    function drawSeries(plot, ctx, series) {\n        var plotOffset = plot.getPlotOffset();\n        \n        if (!series.images || !series.images.show)\n            return;\n        \n        var points = series.datapoints.points,\n            ps = series.datapoints.pointsize;\n        \n        for (var i = 0; i < points.length; i += ps) {\n            var img = points[i],\n                x1 = points[i + 1], y1 = points[i + 2],\n                x2 = points[i + 3], y2 = points[i + 4],\n                xaxis = series.xaxis, yaxis = series.yaxis,\n                tmp;\n\n            // actually we should check img.complete, but it\n            // appears to be a somewhat unreliable indicator in\n            // IE6 (false even after load event)\n            if (!img || img.width <= 0 || img.height <= 0)\n                continue;\n\n            if (x1 > x2) {\n                tmp = x2;\n                x2 = x1;\n                x1 = tmp;\n            }\n            if (y1 > y2) {\n                tmp = y2;\n                y2 = y1;\n                y1 = tmp;\n            }\n            \n            // if the anchor is at the center of the pixel, expand the \n            // image by 1/2 pixel in each direction\n            if (series.images.anchor == \"center\") {\n                tmp = 0.5 * (x2-x1) / (img.width - 1);\n                x1 -= tmp;\n                x2 += tmp;\n                tmp = 0.5 * (y2-y1) / (img.height - 1);\n                y1 -= tmp;\n                y2 += tmp;\n            }\n            \n            // clip\n            if (x1 == x2 || y1 == y2 ||\n                x1 >= xaxis.max || x2 <= xaxis.min ||\n                y1 >= yaxis.max || y2 <= yaxis.min)\n                continue;\n\n            var sx1 = 0, sy1 = 0, sx2 = img.width, sy2 = img.height;\n            if (x1 < xaxis.min) {\n                sx1 += (sx2 - sx1) * (xaxis.min - x1) / (x2 - x1);\n                x1 = xaxis.min;\n            }\n\n            if (x2 > xaxis.max) {\n                sx2 += (sx2 - sx1) * (xaxis.max - x2) / (x2 - x1);\n                x2 = xaxis.max;\n            }\n\n            if (y1 < yaxis.min) {\n                sy2 += (sy1 - sy2) * (yaxis.min - y1) / (y2 - y1);\n                y1 = yaxis.min;\n            }\n\n            if (y2 > yaxis.max) {\n                sy1 += (sy1 - sy2) * (yaxis.max - y2) / (y2 - y1);\n                y2 = yaxis.max;\n            }\n            \n            x1 = xaxis.p2c(x1);\n            x2 = xaxis.p2c(x2);\n            y1 = yaxis.p2c(y1);\n            y2 = yaxis.p2c(y2);\n            \n            // the transformation may have swapped us\n            if (x1 > x2) {\n                tmp = x2;\n                x2 = x1;\n                x1 = tmp;\n            }\n            if (y1 > y2) {\n                tmp = y2;\n                y2 = y1;\n                y1 = tmp;\n            }\n\n            tmp = ctx.globalAlpha;\n            ctx.globalAlpha *= series.images.alpha;\n            ctx.drawImage(img,\n                          sx1, sy1, sx2 - sx1, sy2 - sy1,\n                          x1 + plotOffset.left, y1 + plotOffset.top,\n                          x2 - x1, y2 - y1);\n            ctx.globalAlpha = tmp;\n        }\n    }\n\n    function processRawData(plot, series, data, datapoints) {\n        if (!series.images.show)\n            return;\n\n        // format is Image, x1, y1, x2, y2 (opposite corners)\n        datapoints.format = [\n            { required: true },\n            { x: true, number: true, required: true },\n            { y: true, number: true, required: true },\n            { x: true, number: true, required: true },\n            { y: true, number: true, required: true }\n        ];\n    }\n    \n    function init(plot) {\n        plot.hooks.processRawData.push(processRawData);\n        plot.hooks.drawSeries.push(drawSeries);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'image',\n        version: '1.1'\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.js",
    "content": "/* Javascript plotting library for jQuery, version 0.8.2.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\n*/\n\n// first an inline dependency, jquery.colorhelpers.js, we inline it here\n// for convenience\n\n/* Plugin for jQuery for working with colors.\n *\n * Version 1.1.\n *\n * Inspiration from jQuery color animation plugin by John Resig.\n *\n * Released under the MIT license by Ole Laursen, October 2009.\n *\n * Examples:\n *\n *   $.color.parse(\"#fff\").scale('rgb', 0.25).add('a', -0.5).toString()\n *   var c = $.color.extract($(\"#mydiv\"), 'background-color');\n *   console.log(c.r, c.g, c.b, c.a);\n *   $.color.make(100, 50, 25, 0.4).toString() // returns \"rgba(100,50,25,0.4)\"\n *\n * Note that .scale() and .add() return the same modified object\n * instead of making a new one.\n *\n * V. 1.1: Fix error handling so e.g. parsing an empty string does\n * produce a color rather than just crashing.\n */\n(function($){$.color={};$.color.make=function(r,g,b,a){var o={};o.r=r||0;o.g=g||0;o.b=b||0;o.a=a!=null?a:1;o.add=function(c,d){for(var i=0;i<c.length;++i)o[c.charAt(i)]+=d;return o.normalize()};o.scale=function(c,f){for(var i=0;i<c.length;++i)o[c.charAt(i)]*=f;return o.normalize()};o.toString=function(){if(o.a>=1){return\"rgb(\"+[o.r,o.g,o.b].join(\",\")+\")\"}else{return\"rgba(\"+[o.r,o.g,o.b,o.a].join(\",\")+\")\"}};o.normalize=function(){function clamp(min,value,max){return value<min?min:value>max?max:value}o.r=clamp(0,parseInt(o.r),255);o.g=clamp(0,parseInt(o.g),255);o.b=clamp(0,parseInt(o.b),255);o.a=clamp(0,o.a,1);return o};o.clone=function(){return $.color.make(o.r,o.b,o.g,o.a)};return o.normalize()};$.color.extract=function(elem,css){var c;do{c=elem.css(css).toLowerCase();if(c!=\"\"&&c!=\"transparent\")break;elem=elem.parent()}while(elem.length&&!$.nodeName(elem.get(0),\"body\"));if(c==\"rgba(0, 0, 0, 0)\")c=\"transparent\";return $.color.parse(c)};$.color.parse=function(str){var res,m=$.color.make;if(res=/rgb\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10));if(res=/rgba\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\)/.exec(str))return m(parseInt(res[1],10),parseInt(res[2],10),parseInt(res[3],10),parseFloat(res[4]));if(res=/rgb\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*\\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55);if(res=/rgba\\(\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\%\\s*,\\s*([0-9]+(?:\\.[0-9]+)?)\\s*\\)/.exec(str))return m(parseFloat(res[1])*2.55,parseFloat(res[2])*2.55,parseFloat(res[3])*2.55,parseFloat(res[4]));if(res=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(str))return m(parseInt(res[1],16),parseInt(res[2],16),parseInt(res[3],16));if(res=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(str))return m(parseInt(res[1]+res[1],16),parseInt(res[2]+res[2],16),parseInt(res[3]+res[3],16));var name=$.trim(str).toLowerCase();if(name==\"transparent\")return m(255,255,255,0);else{res=lookupColors[name]||[0,0,0];return m(res[0],res[1],res[2])}};var lookupColors={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0]}})(jQuery);\n\n// the actual Flot code\n(function($) {\n\n\t// Cache the prototype hasOwnProperty for faster access\n\n\tvar hasOwnProperty = Object.prototype.hasOwnProperty;\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// The Canvas object is a wrapper around an HTML5 <canvas> tag.\n\t//\n\t// @constructor\n\t// @param {string} cls List of classes to apply to the canvas.\n\t// @param {element} container Element onto which to append the canvas.\n\t//\n\t// Requiring a container is a little iffy, but unfortunately canvas\n\t// operations don't work unless the canvas is attached to the DOM.\n\n\tfunction Canvas(cls, container) {\n\n\t\tvar element = container.children(\".\" + cls)[0];\n\n\t\tif (element == null) {\n\n\t\t\telement = document.createElement(\"canvas\");\n\t\t\telement.className = cls;\n\n\t\t\t$(element).css({ direction: \"ltr\", position: \"absolute\", left: 0, top: 0 })\n\t\t\t\t.appendTo(container);\n\n\t\t\t// If HTML5 Canvas isn't available, fall back to [Ex|Flash]canvas\n\n\t\t\tif (!element.getContext) {\n\t\t\t\tif (window.G_vmlCanvasManager) {\n\t\t\t\t\telement = window.G_vmlCanvasManager.initElement(element);\n\t\t\t\t} else {\n\t\t\t\t\tthrow new Error(\"Canvas is not available. If you're using IE with a fall-back such as Excanvas, then there's either a mistake in your conditional include, or the page has no DOCTYPE and is rendering in Quirks Mode.\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element = element;\n\n\t\tvar context = this.context = element.getContext(\"2d\");\n\n\t\t// Determine the screen's ratio of physical to device-independent\n\t\t// pixels.  This is the ratio between the canvas width that the browser\n\t\t// advertises and the number of pixels actually present in that space.\n\n\t\t// The iPhone 4, for example, has a device-independent width of 320px,\n\t\t// but its screen is actually 640px wide.  It therefore has a pixel\n\t\t// ratio of 2, while most normal devices have a ratio of 1.\n\n\t\tvar devicePixelRatio = window.devicePixelRatio || 1,\n\t\t\tbackingStoreRatio =\n\t\t\t\tcontext.webkitBackingStorePixelRatio ||\n\t\t\t\tcontext.mozBackingStorePixelRatio ||\n\t\t\t\tcontext.msBackingStorePixelRatio ||\n\t\t\t\tcontext.oBackingStorePixelRatio ||\n\t\t\t\tcontext.backingStorePixelRatio || 1;\n\n\t\tthis.pixelRatio = devicePixelRatio / backingStoreRatio;\n\n\t\t// Size the canvas to match the internal dimensions of its container\n\n\t\tthis.resize(container.width(), container.height());\n\n\t\t// Collection of HTML div layers for text overlaid onto the canvas\n\n\t\tthis.textContainer = null;\n\t\tthis.text = {};\n\n\t\t// Cache of text fragments and metrics, so we can avoid expensively\n\t\t// re-calculating them when the plot is re-rendered in a loop.\n\n\t\tthis._textCache = {};\n\t}\n\n\t// Resizes the canvas to the given dimensions.\n\t//\n\t// @param {number} width New width of the canvas, in pixels.\n\t// @param {number} width New height of the canvas, in pixels.\n\n\tCanvas.prototype.resize = function(width, height) {\n\n\t\tif (width <= 0 || height <= 0) {\n\t\t\tthrow new Error(\"Invalid dimensions for plot, width = \" + width + \", height = \" + height);\n\t\t}\n\n\t\tvar element = this.element,\n\t\t\tcontext = this.context,\n\t\t\tpixelRatio = this.pixelRatio;\n\n\t\t// Resize the canvas, increasing its density based on the display's\n\t\t// pixel ratio; basically giving it more pixels without increasing the\n\t\t// size of its element, to take advantage of the fact that retina\n\t\t// displays have that many more pixels in the same advertised space.\n\n\t\t// Resizing should reset the state (excanvas seems to be buggy though)\n\n\t\tif (this.width != width) {\n\t\t\telement.width = width * pixelRatio;\n\t\t\telement.style.width = width + \"px\";\n\t\t\tthis.width = width;\n\t\t}\n\n\t\tif (this.height != height) {\n\t\t\telement.height = height * pixelRatio;\n\t\t\telement.style.height = height + \"px\";\n\t\t\tthis.height = height;\n\t\t}\n\n\t\t// Save the context, so we can reset in case we get replotted.  The\n\t\t// restore ensure that we're really back at the initial state, and\n\t\t// should be safe even if we haven't saved the initial state yet.\n\n\t\tcontext.restore();\n\t\tcontext.save();\n\n\t\t// Scale the coordinate space to match the display density; so even though we\n\t\t// may have twice as many pixels, we still want lines and other drawing to\n\t\t// appear at the same size; the extra pixels will just make them crisper.\n\n\t\tcontext.scale(pixelRatio, pixelRatio);\n\t};\n\n\t// Clears the entire canvas area, not including any overlaid HTML text\n\n\tCanvas.prototype.clear = function() {\n\t\tthis.context.clearRect(0, 0, this.width, this.height);\n\t};\n\n\t// Finishes rendering the canvas, including managing the text overlay.\n\n\tCanvas.prototype.render = function() {\n\n\t\tvar cache = this._textCache;\n\n\t\t// For each text layer, add elements marked as active that haven't\n\t\t// already been rendered, and remove those that are no longer active.\n\n\t\tfor (var layerKey in cache) {\n\t\t\tif (hasOwnProperty.call(cache, layerKey)) {\n\n\t\t\t\tvar layer = this.getTextLayer(layerKey),\n\t\t\t\t\tlayerCache = cache[layerKey];\n\n\t\t\t\tlayer.hide();\n\n\t\t\t\tfor (var styleKey in layerCache) {\n\t\t\t\t\tif (hasOwnProperty.call(layerCache, styleKey)) {\n\t\t\t\t\t\tvar styleCache = layerCache[styleKey];\n\t\t\t\t\t\tfor (var key in styleCache) {\n\t\t\t\t\t\t\tif (hasOwnProperty.call(styleCache, key)) {\n\n\t\t\t\t\t\t\t\tvar positions = styleCache[key].positions;\n\n\t\t\t\t\t\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\t\t\t\t\t\tif (position.active) {\n\t\t\t\t\t\t\t\t\t\tif (!position.rendered) {\n\t\t\t\t\t\t\t\t\t\t\tlayer.append(position.element);\n\t\t\t\t\t\t\t\t\t\t\tposition.rendered = true;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\tpositions.splice(i--, 1);\n\t\t\t\t\t\t\t\t\t\tif (position.rendered) {\n\t\t\t\t\t\t\t\t\t\t\tposition.element.detach();\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (positions.length == 0) {\n\t\t\t\t\t\t\t\t\tdelete styleCache[key];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tlayer.show();\n\t\t\t}\n\t\t}\n\t};\n\n\t// Creates (if necessary) and returns the text overlay container.\n\t//\n\t// @param {string} classes String of space-separated CSS classes used to\n\t//     uniquely identify the text layer.\n\t// @return {object} The jQuery-wrapped text-layer div.\n\n\tCanvas.prototype.getTextLayer = function(classes) {\n\n\t\tvar layer = this.text[classes];\n\n\t\t// Create the text layer if it doesn't exist\n\n\t\tif (layer == null) {\n\n\t\t\t// Create the text layer container, if it doesn't exist\n\n\t\t\tif (this.textContainer == null) {\n\t\t\t\tthis.textContainer = $(\"<div class='flot-text'></div>\")\n\t\t\t\t\t.css({\n\t\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t\ttop: 0,\n\t\t\t\t\t\tleft: 0,\n\t\t\t\t\t\tbottom: 0,\n\t\t\t\t\t\tright: 0,\n\t\t\t\t\t\t'font-size': \"smaller\",\n\t\t\t\t\t\tcolor: \"#545454\"\n\t\t\t\t\t})\n\t\t\t\t\t.insertAfter(this.element);\n\t\t\t}\n\n\t\t\tlayer = this.text[classes] = $(\"<div></div>\")\n\t\t\t\t.addClass(classes)\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: 0,\n\t\t\t\t\tbottom: 0,\n\t\t\t\t\tright: 0\n\t\t\t\t})\n\t\t\t\t.appendTo(this.textContainer);\n\t\t}\n\n\t\treturn layer;\n\t};\n\n\t// Creates (if necessary) and returns a text info object.\n\t//\n\t// The object looks like this:\n\t//\n\t// {\n\t//     width: Width of the text's wrapper div.\n\t//     height: Height of the text's wrapper div.\n\t//     element: The jQuery-wrapped HTML div containing the text.\n\t//     positions: Array of positions at which this text is drawn.\n\t// }\n\t//\n\t// The positions array contains objects that look like this:\n\t//\n\t// {\n\t//     active: Flag indicating whether the text should be visible.\n\t//     rendered: Flag indicating whether the text is currently visible.\n\t//     element: The jQuery-wrapped HTML div containing the text.\n\t//     x: X coordinate at which to draw the text.\n\t//     y: Y coordinate at which to draw the text.\n\t// }\n\t//\n\t// Each position after the first receives a clone of the original element.\n\t//\n\t// The idea is that that the width, height, and general 'identity' of the\n\t// text is constant no matter where it is placed; the placements are a\n\t// secondary property.\n\t//\n\t// Canvas maintains a cache of recently-used text info objects; getTextInfo\n\t// either returns the cached element or creates a new entry.\n\t//\n\t// @param {string} layer A string of space-separated CSS classes uniquely\n\t//     identifying the layer containing this text.\n\t// @param {string} text Text string to retrieve info for.\n\t// @param {(string|object)=} font Either a string of space-separated CSS\n\t//     classes or a font-spec object, defining the text's font and style.\n\t// @param {number=} angle Angle at which to rotate the text, in degrees.\n\t//     Angle is currently unused, it will be implemented in the future.\n\t// @param {number=} width Maximum width of the text before it wraps.\n\t// @return {object} a text info object.\n\n\tCanvas.prototype.getTextInfo = function(layer, text, font, angle, width) {\n\n\t\tvar textStyle, layerCache, styleCache, info;\n\n\t\t// Cast the value to a string, in case we were given a number or such\n\n\t\ttext = \"\" + text;\n\n\t\t// If the font is a font-spec object, generate a CSS font definition\n\n\t\tif (typeof font === \"object\") {\n\t\t\ttextStyle = font.style + \" \" + font.variant + \" \" + font.weight + \" \" + font.size + \"px/\" + font.lineHeight + \"px \" + font.family;\n\t\t} else {\n\t\t\ttextStyle = font;\n\t\t}\n\n\t\t// Retrieve (or create) the cache for the text's layer and styles\n\n\t\tlayerCache = this._textCache[layer];\n\n\t\tif (layerCache == null) {\n\t\t\tlayerCache = this._textCache[layer] = {};\n\t\t}\n\n\t\tstyleCache = layerCache[textStyle];\n\n\t\tif (styleCache == null) {\n\t\t\tstyleCache = layerCache[textStyle] = {};\n\t\t}\n\n\t\tinfo = styleCache[text];\n\n\t\t// If we can't find a matching element in our cache, create a new one\n\n\t\tif (info == null) {\n\n\t\t\tvar element = $(\"<div></div>\").html(text)\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\t'max-width': width,\n\t\t\t\t\ttop: -9999\n\t\t\t\t})\n\t\t\t\t.appendTo(this.getTextLayer(layer));\n\n\t\t\tif (typeof font === \"object\") {\n\t\t\t\telement.css({\n\t\t\t\t\tfont: textStyle,\n\t\t\t\t\tcolor: font.color\n\t\t\t\t});\n\t\t\t} else if (typeof font === \"string\") {\n\t\t\t\telement.addClass(font);\n\t\t\t}\n\n\t\t\tinfo = styleCache[text] = {\n\t\t\t\twidth: element.outerWidth(true),\n\t\t\t\theight: element.outerHeight(true),\n\t\t\t\telement: element,\n\t\t\t\tpositions: []\n\t\t\t};\n\n\t\t\telement.detach();\n\t\t}\n\n\t\treturn info;\n\t};\n\n\t// Adds a text string to the canvas text overlay.\n\t//\n\t// The text isn't drawn immediately; it is marked as rendering, which will\n\t// result in its addition to the canvas on the next render pass.\n\t//\n\t// @param {string} layer A string of space-separated CSS classes uniquely\n\t//     identifying the layer containing this text.\n\t// @param {number} x X coordinate at which to draw the text.\n\t// @param {number} y Y coordinate at which to draw the text.\n\t// @param {string} text Text string to draw.\n\t// @param {(string|object)=} font Either a string of space-separated CSS\n\t//     classes or a font-spec object, defining the text's font and style.\n\t// @param {number=} angle Angle at which to rotate the text, in degrees.\n\t//     Angle is currently unused, it will be implemented in the future.\n\t// @param {number=} width Maximum width of the text before it wraps.\n\t// @param {string=} halign Horizontal alignment of the text; either \"left\",\n\t//     \"center\" or \"right\".\n\t// @param {string=} valign Vertical alignment of the text; either \"top\",\n\t//     \"middle\" or \"bottom\".\n\n\tCanvas.prototype.addText = function(layer, x, y, text, font, angle, width, halign, valign) {\n\n\t\tvar info = this.getTextInfo(layer, text, font, angle, width),\n\t\t\tpositions = info.positions;\n\n\t\t// Tweak the div's position to match the text's alignment\n\n\t\tif (halign == \"center\") {\n\t\t\tx -= info.width / 2;\n\t\t} else if (halign == \"right\") {\n\t\t\tx -= info.width;\n\t\t}\n\n\t\tif (valign == \"middle\") {\n\t\t\ty -= info.height / 2;\n\t\t} else if (valign == \"bottom\") {\n\t\t\ty -= info.height;\n\t\t}\n\n\t\t// Determine whether this text already exists at this position.\n\t\t// If so, mark it for inclusion in the next render pass.\n\n\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\tif (position.x == x && position.y == y) {\n\t\t\t\tposition.active = true;\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\t// If the text doesn't exist at this position, create a new entry\n\n\t\t// For the very first position we'll re-use the original element,\n\t\t// while for subsequent ones we'll clone it.\n\n\t\tposition = {\n\t\t\tactive: true,\n\t\t\trendered: false,\n\t\t\telement: positions.length ? info.element.clone() : info.element,\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\n\t\tpositions.push(position);\n\n\t\t// Move the element to its final position within the container\n\n\t\tposition.element.css({\n\t\t\ttop: Math.round(y),\n\t\t\tleft: Math.round(x),\n\t\t\t'text-align': halign\t// In case the text wraps\n\t\t});\n\t};\n\n\t// Removes one or more text strings from the canvas text overlay.\n\t//\n\t// If no parameters are given, all text within the layer is removed.\n\t//\n\t// Note that the text is not immediately removed; it is simply marked as\n\t// inactive, which will result in its removal on the next render pass.\n\t// This avoids the performance penalty for 'clear and redraw' behavior,\n\t// where we potentially get rid of all text on a layer, but will likely\n\t// add back most or all of it later, as when redrawing axes, for example.\n\t//\n\t// @param {string} layer A string of space-separated CSS classes uniquely\n\t//     identifying the layer containing this text.\n\t// @param {number=} x X coordinate of the text.\n\t// @param {number=} y Y coordinate of the text.\n\t// @param {string=} text Text string to remove.\n\t// @param {(string|object)=} font Either a string of space-separated CSS\n\t//     classes or a font-spec object, defining the text's font and style.\n\t// @param {number=} angle Angle at which the text is rotated, in degrees.\n\t//     Angle is currently unused, it will be implemented in the future.\n\n\tCanvas.prototype.removeText = function(layer, x, y, text, font, angle) {\n\t\tif (text == null) {\n\t\t\tvar layerCache = this._textCache[layer];\n\t\t\tif (layerCache != null) {\n\t\t\t\tfor (var styleKey in layerCache) {\n\t\t\t\t\tif (hasOwnProperty.call(layerCache, styleKey)) {\n\t\t\t\t\t\tvar styleCache = layerCache[styleKey];\n\t\t\t\t\t\tfor (var key in styleCache) {\n\t\t\t\t\t\t\tif (hasOwnProperty.call(styleCache, key)) {\n\t\t\t\t\t\t\t\tvar positions = styleCache[key].positions;\n\t\t\t\t\t\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\t\t\t\t\t\tposition.active = false;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tvar positions = this.getTextInfo(layer, text, font, angle).positions;\n\t\t\tfor (var i = 0, position; position = positions[i]; i++) {\n\t\t\t\tif (position.x == x && position.y == y) {\n\t\t\t\t\tposition.active = false;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t///////////////////////////////////////////////////////////////////////////\n\t// The top-level container for the entire plot.\n\n    function Plot(placeholder, data_, options_, plugins) {\n        // data is on the form:\n        //   [ series1, series2 ... ]\n        // where series is either just the data as [ [x1, y1], [x2, y2], ... ]\n        // or { data: [ [x1, y1], [x2, y2], ... ], label: \"some label\", ... }\n\n        var series = [],\n            options = {\n                // the color theme used for graphs\n                colors: [\"#edc240\", \"#afd8f8\", \"#cb4b4b\", \"#4da74d\", \"#9440ed\"],\n                legend: {\n                    show: true,\n                    noColumns: 1, // number of colums in legend table\n                    labelFormatter: null, // fn: string -> string\n                    labelBoxBorderColor: \"#ccc\", // border color for the little label boxes\n                    container: null, // container (as jQuery object) to put legend in, null means default on top of graph\n                    position: \"ne\", // position of default legend container within plot\n                    margin: 5, // distance from grid edge to default legend container within plot\n                    backgroundColor: null, // null means auto-detect\n                    backgroundOpacity: 0.85, // set to 0 to avoid background\n                    sorted: null    // default to no legend sorting\n                },\n                xaxis: {\n                    show: null, // null = auto-detect, true = always, false = never\n                    position: \"bottom\", // or \"top\"\n                    mode: null, // null or \"time\"\n                    font: null, // null (derived from CSS in placeholder) or object like { size: 11, lineHeight: 13, style: \"italic\", weight: \"bold\", family: \"sans-serif\", variant: \"small-caps\" }\n                    color: null, // base color, labels, ticks\n                    tickColor: null, // possibly different color of ticks, e.g. \"rgba(0,0,0,0.15)\"\n                    transform: null, // null or f: number -> number to transform axis\n                    inverseTransform: null, // if transform is set, this should be the inverse function\n                    min: null, // min. value to show, null means set automatically\n                    max: null, // max. value to show, null means set automatically\n                    autoscaleMargin: null, // margin in % to add if auto-setting min/max\n                    ticks: null, // either [1, 3] or [[1, \"a\"], 3] or (fn: axis info -> ticks) or app. number of ticks for auto-ticks\n                    tickFormatter: null, // fn: number -> string\n                    labelWidth: null, // size of tick labels in pixels\n                    labelHeight: null,\n                    reserveSpace: null, // whether to reserve space even if axis isn't shown\n                    tickLength: null, // size in pixels of ticks, or \"full\" for whole line\n                    alignTicksWithAxis: null, // axis number or null for no sync\n                    tickDecimals: null, // no. of decimals, null means auto\n                    tickSize: null, // number or [number, \"unit\"]\n                    minTickSize: null // number or [number, \"unit\"]\n                },\n                yaxis: {\n                    autoscaleMargin: 0.02,\n                    position: \"left\" // or \"right\"\n                },\n                xaxes: [],\n                yaxes: [],\n                series: {\n                    points: {\n                        show: false,\n                        radius: 3,\n                        lineWidth: 2, // in pixels\n                        fill: true,\n                        fillColor: \"#ffffff\",\n                        symbol: \"circle\" // or callback\n                    },\n                    lines: {\n                        // we don't put in show: false so we can see\n                        // whether lines were actively disabled\n                        lineWidth: 2, // in pixels\n                        fill: false,\n                        fillColor: null,\n                        steps: false\n                        // Omit 'zero', so we can later default its value to\n                        // match that of the 'fill' option.\n                    },\n                    bars: {\n                        show: false,\n                        lineWidth: 2, // in pixels\n                        barWidth: 1, // in units of the x axis\n                        fill: true,\n                        fillColor: null,\n                        align: \"left\", // \"left\", \"right\", or \"center\"\n                        horizontal: false,\n                        zero: true\n                    },\n                    shadowSize: 3,\n                    highlightColor: null\n                },\n                grid: {\n                    show: true,\n                    aboveData: false,\n                    color: \"#545454\", // primary color used for outline and labels\n                    backgroundColor: null, // null for transparent, else color\n                    borderColor: null, // set if different from the grid color\n                    tickColor: null, // color for the ticks, e.g. \"rgba(0,0,0,0.15)\"\n                    margin: 0, // distance from the canvas edge to the grid\n                    labelMargin: 5, // in pixels\n                    axisMargin: 8, // in pixels\n                    borderWidth: 2, // in pixels\n                    minBorderMargin: null, // in pixels, null means taken from points radius\n                    markings: null, // array of ranges or fn: axes -> array of ranges\n                    markingsColor: \"#f4f4f4\",\n                    markingsLineWidth: 2,\n                    // interactive stuff\n                    clickable: false,\n                    hoverable: false,\n                    autoHighlight: true, // highlight in case mouse is near\n                    mouseActiveRadius: 10 // how far the mouse can be away to activate an item\n                },\n                interaction: {\n                    redrawOverlayInterval: 1000/60 // time between updates, -1 means in same flow\n                },\n                hooks: {}\n            },\n        surface = null,     // the canvas for the plot itself\n        overlay = null,     // canvas for interactive stuff on top of plot\n        eventHolder = null, // jQuery object that events should be bound to\n        ctx = null, octx = null,\n        xaxes = [], yaxes = [],\n        plotOffset = { left: 0, right: 0, top: 0, bottom: 0},\n        plotWidth = 0, plotHeight = 0,\n        hooks = {\n            processOptions: [],\n            processRawData: [],\n            processDatapoints: [],\n            processOffset: [],\n            drawBackground: [],\n            drawSeries: [],\n            draw: [],\n            bindEvents: [],\n            drawOverlay: [],\n            shutdown: []\n        },\n        plot = this;\n\n        // public functions\n        plot.setData = setData;\n        plot.setupGrid = setupGrid;\n        plot.draw = draw;\n        plot.getPlaceholder = function() { return placeholder; };\n        plot.getCanvas = function() { return surface.element; };\n        plot.getPlotOffset = function() { return plotOffset; };\n        plot.width = function () { return plotWidth; };\n        plot.height = function () { return plotHeight; };\n        plot.offset = function () {\n            var o = eventHolder.offset();\n            o.left += plotOffset.left;\n            o.top += plotOffset.top;\n            return o;\n        };\n        plot.getData = function () { return series; };\n        plot.getAxes = function () {\n            var res = {}, i;\n            $.each(xaxes.concat(yaxes), function (_, axis) {\n                if (axis)\n                    res[axis.direction + (axis.n != 1 ? axis.n : \"\") + \"axis\"] = axis;\n            });\n            return res;\n        };\n        plot.getXAxes = function () { return xaxes; };\n        plot.getYAxes = function () { return yaxes; };\n        plot.c2p = canvasToAxisCoords;\n        plot.p2c = axisToCanvasCoords;\n        plot.getOptions = function () { return options; };\n        plot.highlight = highlight;\n        plot.unhighlight = unhighlight;\n        plot.triggerRedrawOverlay = triggerRedrawOverlay;\n        plot.pointOffset = function(point) {\n            return {\n                left: parseInt(xaxes[axisNumber(point, \"x\") - 1].p2c(+point.x) + plotOffset.left, 10),\n                top: parseInt(yaxes[axisNumber(point, \"y\") - 1].p2c(+point.y) + plotOffset.top, 10)\n            };\n        };\n        plot.shutdown = shutdown;\n        plot.destroy = function () {\n            shutdown();\n            placeholder.removeData(\"plot\").empty();\n\n            series = [];\n            options = null;\n            surface = null;\n            overlay = null;\n            eventHolder = null;\n            ctx = null;\n            octx = null;\n            xaxes = [];\n            yaxes = [];\n            hooks = null;\n            highlights = [];\n            plot = null;\n        };\n        plot.resize = function () {\n        \tvar width = placeholder.width(),\n        \t\theight = placeholder.height();\n            surface.resize(width, height);\n            overlay.resize(width, height);\n        };\n\n        // public attributes\n        plot.hooks = hooks;\n\n        // initialize\n        initPlugins(plot);\n        parseOptions(options_);\n        setupCanvases();\n        setData(data_);\n        setupGrid();\n        draw();\n        bindEvents();\n\n\n        function executeHooks(hook, args) {\n            args = [plot].concat(args);\n            for (var i = 0; i < hook.length; ++i)\n                hook[i].apply(this, args);\n        }\n\n        function initPlugins() {\n\n            // References to key classes, allowing plugins to modify them\n\n            var classes = {\n                Canvas: Canvas\n            };\n\n            for (var i = 0; i < plugins.length; ++i) {\n                var p = plugins[i];\n                p.init(plot, classes);\n                if (p.options)\n                    $.extend(true, options, p.options);\n            }\n        }\n\n        function parseOptions(opts) {\n\n            $.extend(true, options, opts);\n\n            // $.extend merges arrays, rather than replacing them.  When less\n            // colors are provided than the size of the default palette, we\n            // end up with those colors plus the remaining defaults, which is\n            // not expected behavior; avoid it by replacing them here.\n\n            if (opts && opts.colors) {\n            \toptions.colors = opts.colors;\n            }\n\n            if (options.xaxis.color == null)\n                options.xaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();\n            if (options.yaxis.color == null)\n                options.yaxis.color = $.color.parse(options.grid.color).scale('a', 0.22).toString();\n\n            if (options.xaxis.tickColor == null) // grid.tickColor for back-compatibility\n                options.xaxis.tickColor = options.grid.tickColor || options.xaxis.color;\n            if (options.yaxis.tickColor == null) // grid.tickColor for back-compatibility\n                options.yaxis.tickColor = options.grid.tickColor || options.yaxis.color;\n\n            if (options.grid.borderColor == null)\n                options.grid.borderColor = options.grid.color;\n            if (options.grid.tickColor == null)\n                options.grid.tickColor = $.color.parse(options.grid.color).scale('a', 0.22).toString();\n\n            // Fill in defaults for axis options, including any unspecified\n            // font-spec fields, if a font-spec was provided.\n\n            // If no x/y axis options were provided, create one of each anyway,\n            // since the rest of the code assumes that they exist.\n\n            var i, axisOptions, axisCount,\n                fontSize = placeholder.css(\"font-size\"),\n                fontSizeDefault = fontSize ? +fontSize.replace(\"px\", \"\") : 13,\n                fontDefaults = {\n                    style: placeholder.css(\"font-style\"),\n                    size: Math.round(0.8 * fontSizeDefault),\n                    variant: placeholder.css(\"font-variant\"),\n                    weight: placeholder.css(\"font-weight\"),\n                    family: placeholder.css(\"font-family\")\n                };\n\n            axisCount = options.xaxes.length || 1;\n            for (i = 0; i < axisCount; ++i) {\n\n                axisOptions = options.xaxes[i];\n                if (axisOptions && !axisOptions.tickColor) {\n                    axisOptions.tickColor = axisOptions.color;\n                }\n\n                axisOptions = $.extend(true, {}, options.xaxis, axisOptions);\n                options.xaxes[i] = axisOptions;\n\n                if (axisOptions.font) {\n                    axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);\n                    if (!axisOptions.font.color) {\n                        axisOptions.font.color = axisOptions.color;\n                    }\n                    if (!axisOptions.font.lineHeight) {\n                        axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);\n                    }\n                }\n            }\n\n            axisCount = options.yaxes.length || 1;\n            for (i = 0; i < axisCount; ++i) {\n\n                axisOptions = options.yaxes[i];\n                if (axisOptions && !axisOptions.tickColor) {\n                    axisOptions.tickColor = axisOptions.color;\n                }\n\n                axisOptions = $.extend(true, {}, options.yaxis, axisOptions);\n                options.yaxes[i] = axisOptions;\n\n                if (axisOptions.font) {\n                    axisOptions.font = $.extend({}, fontDefaults, axisOptions.font);\n                    if (!axisOptions.font.color) {\n                        axisOptions.font.color = axisOptions.color;\n                    }\n                    if (!axisOptions.font.lineHeight) {\n                        axisOptions.font.lineHeight = Math.round(axisOptions.font.size * 1.15);\n                    }\n                }\n            }\n\n            // backwards compatibility, to be removed in future\n            if (options.xaxis.noTicks && options.xaxis.ticks == null)\n                options.xaxis.ticks = options.xaxis.noTicks;\n            if (options.yaxis.noTicks && options.yaxis.ticks == null)\n                options.yaxis.ticks = options.yaxis.noTicks;\n            if (options.x2axis) {\n                options.xaxes[1] = $.extend(true, {}, options.xaxis, options.x2axis);\n                options.xaxes[1].position = \"top\";\n            }\n            if (options.y2axis) {\n                options.yaxes[1] = $.extend(true, {}, options.yaxis, options.y2axis);\n                options.yaxes[1].position = \"right\";\n            }\n            if (options.grid.coloredAreas)\n                options.grid.markings = options.grid.coloredAreas;\n            if (options.grid.coloredAreasColor)\n                options.grid.markingsColor = options.grid.coloredAreasColor;\n            if (options.lines)\n                $.extend(true, options.series.lines, options.lines);\n            if (options.points)\n                $.extend(true, options.series.points, options.points);\n            if (options.bars)\n                $.extend(true, options.series.bars, options.bars);\n            if (options.shadowSize != null)\n                options.series.shadowSize = options.shadowSize;\n            if (options.highlightColor != null)\n                options.series.highlightColor = options.highlightColor;\n\n            // save options on axes for future reference\n            for (i = 0; i < options.xaxes.length; ++i)\n                getOrCreateAxis(xaxes, i + 1).options = options.xaxes[i];\n            for (i = 0; i < options.yaxes.length; ++i)\n                getOrCreateAxis(yaxes, i + 1).options = options.yaxes[i];\n\n            // add hooks from options\n            for (var n in hooks)\n                if (options.hooks[n] && options.hooks[n].length)\n                    hooks[n] = hooks[n].concat(options.hooks[n]);\n\n            executeHooks(hooks.processOptions, [options]);\n        }\n\n        function setData(d) {\n            series = parseData(d);\n            fillInSeriesOptions();\n            processData();\n        }\n\n        function parseData(d) {\n            var res = [];\n            for (var i = 0; i < d.length; ++i) {\n                var s = $.extend(true, {}, options.series);\n\n                if (d[i].data != null) {\n                    s.data = d[i].data; // move the data instead of deep-copy\n                    delete d[i].data;\n\n                    $.extend(true, s, d[i]);\n\n                    d[i].data = s.data;\n                }\n                else\n                    s.data = d[i];\n                res.push(s);\n            }\n\n            return res;\n        }\n\n        function axisNumber(obj, coord) {\n            var a = obj[coord + \"axis\"];\n            if (typeof a == \"object\") // if we got a real axis, extract number\n                a = a.n;\n            if (typeof a != \"number\")\n                a = 1; // default to first axis\n            return a;\n        }\n\n        function allAxes() {\n            // return flat array without annoying null entries\n            return $.grep(xaxes.concat(yaxes), function (a) { return a; });\n        }\n\n        function canvasToAxisCoords(pos) {\n            // return an object with x/y corresponding to all used axes\n            var res = {}, i, axis;\n            for (i = 0; i < xaxes.length; ++i) {\n                axis = xaxes[i];\n                if (axis && axis.used)\n                    res[\"x\" + axis.n] = axis.c2p(pos.left);\n            }\n\n            for (i = 0; i < yaxes.length; ++i) {\n                axis = yaxes[i];\n                if (axis && axis.used)\n                    res[\"y\" + axis.n] = axis.c2p(pos.top);\n            }\n\n            if (res.x1 !== undefined)\n                res.x = res.x1;\n            if (res.y1 !== undefined)\n                res.y = res.y1;\n\n            return res;\n        }\n\n        function axisToCanvasCoords(pos) {\n            // get canvas coords from the first pair of x/y found in pos\n            var res = {}, i, axis, key;\n\n            for (i = 0; i < xaxes.length; ++i) {\n                axis = xaxes[i];\n                if (axis && axis.used) {\n                    key = \"x\" + axis.n;\n                    if (pos[key] == null && axis.n == 1)\n                        key = \"x\";\n\n                    if (pos[key] != null) {\n                        res.left = axis.p2c(pos[key]);\n                        break;\n                    }\n                }\n            }\n\n            for (i = 0; i < yaxes.length; ++i) {\n                axis = yaxes[i];\n                if (axis && axis.used) {\n                    key = \"y\" + axis.n;\n                    if (pos[key] == null && axis.n == 1)\n                        key = \"y\";\n\n                    if (pos[key] != null) {\n                        res.top = axis.p2c(pos[key]);\n                        break;\n                    }\n                }\n            }\n\n            return res;\n        }\n\n        function getOrCreateAxis(axes, number) {\n            if (!axes[number - 1])\n                axes[number - 1] = {\n                    n: number, // save the number for future reference\n                    direction: axes == xaxes ? \"x\" : \"y\",\n                    options: $.extend(true, {}, axes == xaxes ? options.xaxis : options.yaxis)\n                };\n\n            return axes[number - 1];\n        }\n\n        function fillInSeriesOptions() {\n\n            var neededColors = series.length, maxIndex = -1, i;\n\n            // Subtract the number of series that already have fixed colors or\n            // color indexes from the number that we still need to generate.\n\n            for (i = 0; i < series.length; ++i) {\n                var sc = series[i].color;\n                if (sc != null) {\n                    neededColors--;\n                    if (typeof sc == \"number\" && sc > maxIndex) {\n                        maxIndex = sc;\n                    }\n                }\n            }\n\n            // If any of the series have fixed color indexes, then we need to\n            // generate at least as many colors as the highest index.\n\n            if (neededColors <= maxIndex) {\n                neededColors = maxIndex + 1;\n            }\n\n            // Generate all the colors, using first the option colors and then\n            // variations on those colors once they're exhausted.\n\n            var c, colors = [], colorPool = options.colors,\n                colorPoolSize = colorPool.length, variation = 0;\n\n            for (i = 0; i < neededColors; i++) {\n\n                c = $.color.parse(colorPool[i % colorPoolSize] || \"#666\");\n\n                // Each time we exhaust the colors in the pool we adjust\n                // a scaling factor used to produce more variations on\n                // those colors. The factor alternates negative/positive\n                // to produce lighter/darker colors.\n\n                // Reset the variation after every few cycles, or else\n                // it will end up producing only white or black colors.\n\n                if (i % colorPoolSize == 0 && i) {\n                    if (variation >= 0) {\n                        if (variation < 0.5) {\n                            variation = -variation - 0.2;\n                        } else variation = 0;\n                    } else variation = -variation;\n                }\n\n                colors[i] = c.scale('rgb', 1 + variation);\n            }\n\n            // Finalize the series options, filling in their colors\n\n            var colori = 0, s;\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n\n                // assign colors\n                if (s.color == null) {\n                    s.color = colors[colori].toString();\n                    ++colori;\n                }\n                else if (typeof s.color == \"number\")\n                    s.color = colors[s.color].toString();\n\n                // turn on lines automatically in case nothing is set\n                if (s.lines.show == null) {\n                    var v, show = true;\n                    for (v in s)\n                        if (s[v] && s[v].show) {\n                            show = false;\n                            break;\n                        }\n                    if (show)\n                        s.lines.show = true;\n                }\n\n                // If nothing was provided for lines.zero, default it to match\n                // lines.fill, since areas by default should extend to zero.\n\n                if (s.lines.zero == null) {\n                    s.lines.zero = !!s.lines.fill;\n                }\n\n                // setup axes\n                s.xaxis = getOrCreateAxis(xaxes, axisNumber(s, \"x\"));\n                s.yaxis = getOrCreateAxis(yaxes, axisNumber(s, \"y\"));\n            }\n        }\n\n        function processData() {\n            var topSentry = Number.POSITIVE_INFINITY,\n                bottomSentry = Number.NEGATIVE_INFINITY,\n                fakeInfinity = Number.MAX_VALUE,\n                i, j, k, m, length,\n                s, points, ps, x, y, axis, val, f, p,\n                data, format;\n\n            function updateAxis(axis, min, max) {\n                if (min < axis.datamin && min != -fakeInfinity)\n                    axis.datamin = min;\n                if (max > axis.datamax && max != fakeInfinity)\n                    axis.datamax = max;\n            }\n\n            $.each(allAxes(), function (_, axis) {\n                // init axis\n                axis.datamin = topSentry;\n                axis.datamax = bottomSentry;\n                axis.used = false;\n            });\n\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n                s.datapoints = { points: [] };\n\n                executeHooks(hooks.processRawData, [ s, s.data, s.datapoints ]);\n            }\n\n            // first pass: clean and copy data\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n\n                data = s.data;\n                format = s.datapoints.format;\n\n                if (!format) {\n                    format = [];\n                    // find out how to copy\n                    format.push({ x: true, number: true, required: true });\n                    format.push({ y: true, number: true, required: true });\n\n                    if (s.bars.show || (s.lines.show && s.lines.fill)) {\n                        var autoscale = !!((s.bars.show && s.bars.zero) || (s.lines.show && s.lines.zero));\n                        format.push({ y: true, number: true, required: false, defaultValue: 0, autoscale: autoscale });\n                        if (s.bars.horizontal) {\n                            delete format[format.length - 1].y;\n                            format[format.length - 1].x = true;\n                        }\n                    }\n\n                    s.datapoints.format = format;\n                }\n\n                if (s.datapoints.pointsize != null)\n                    continue; // already filled in\n\n                s.datapoints.pointsize = format.length;\n\n                ps = s.datapoints.pointsize;\n                points = s.datapoints.points;\n\n                var insertSteps = s.lines.show && s.lines.steps;\n                s.xaxis.used = s.yaxis.used = true;\n\n                for (j = k = 0; j < data.length; ++j, k += ps) {\n                    p = data[j];\n\n                    var nullify = p == null;\n                    if (!nullify) {\n                        for (m = 0; m < ps; ++m) {\n                            val = p[m];\n                            f = format[m];\n\n                            if (f) {\n                                if (f.number && val != null) {\n                                    val = +val; // convert to number\n                                    if (isNaN(val))\n                                        val = null;\n                                    else if (val == Infinity)\n                                        val = fakeInfinity;\n                                    else if (val == -Infinity)\n                                        val = -fakeInfinity;\n                                }\n\n                                if (val == null) {\n                                    if (f.required)\n                                        nullify = true;\n\n                                    if (f.defaultValue != null)\n                                        val = f.defaultValue;\n                                }\n                            }\n\n                            points[k + m] = val;\n                        }\n                    }\n\n                    if (nullify) {\n                        for (m = 0; m < ps; ++m) {\n                            val = points[k + m];\n                            if (val != null) {\n                                f = format[m];\n                                // extract min/max info\n                                if (f.autoscale !== false) {\n                                    if (f.x) {\n                                        updateAxis(s.xaxis, val, val);\n                                    }\n                                    if (f.y) {\n                                        updateAxis(s.yaxis, val, val);\n                                    }\n                                }\n                            }\n                            points[k + m] = null;\n                        }\n                    }\n                    else {\n                        // a little bit of line specific stuff that\n                        // perhaps shouldn't be here, but lacking\n                        // better means...\n                        if (insertSteps && k > 0\n                            && points[k - ps] != null\n                            && points[k - ps] != points[k]\n                            && points[k - ps + 1] != points[k + 1]) {\n                            // copy the point to make room for a middle point\n                            for (m = 0; m < ps; ++m)\n                                points[k + ps + m] = points[k + m];\n\n                            // middle point has same y\n                            points[k + 1] = points[k - ps + 1];\n\n                            // we've added a point, better reflect that\n                            k += ps;\n                        }\n                    }\n                }\n            }\n\n            // give the hooks a chance to run\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n\n                executeHooks(hooks.processDatapoints, [ s, s.datapoints]);\n            }\n\n            // second pass: find datamax/datamin for auto-scaling\n            for (i = 0; i < series.length; ++i) {\n                s = series[i];\n                points = s.datapoints.points;\n                ps = s.datapoints.pointsize;\n                format = s.datapoints.format;\n\n                var xmin = topSentry, ymin = topSentry,\n                    xmax = bottomSentry, ymax = bottomSentry;\n\n                for (j = 0; j < points.length; j += ps) {\n                    if (points[j] == null)\n                        continue;\n\n                    for (m = 0; m < ps; ++m) {\n                        val = points[j + m];\n                        f = format[m];\n                        if (!f || f.autoscale === false || val == fakeInfinity || val == -fakeInfinity)\n                            continue;\n\n                        if (f.x) {\n                            if (val < xmin)\n                                xmin = val;\n                            if (val > xmax)\n                                xmax = val;\n                        }\n                        if (f.y) {\n                            if (val < ymin)\n                                ymin = val;\n                            if (val > ymax)\n                                ymax = val;\n                        }\n                    }\n                }\n\n                if (s.bars.show) {\n                    // make sure we got room for the bar on the dancing floor\n                    var delta;\n\n                    switch (s.bars.align) {\n                        case \"left\":\n                            delta = 0;\n                            break;\n                        case \"right\":\n                            delta = -s.bars.barWidth;\n                            break;\n                        default:\n                            delta = -s.bars.barWidth / 2;\n                    }\n\n                    if (s.bars.horizontal) {\n                        ymin += delta;\n                        ymax += delta + s.bars.barWidth;\n                    }\n                    else {\n                        xmin += delta;\n                        xmax += delta + s.bars.barWidth;\n                    }\n                }\n\n                updateAxis(s.xaxis, xmin, xmax);\n                updateAxis(s.yaxis, ymin, ymax);\n            }\n\n            $.each(allAxes(), function (_, axis) {\n                if (axis.datamin == topSentry)\n                    axis.datamin = null;\n                if (axis.datamax == bottomSentry)\n                    axis.datamax = null;\n            });\n        }\n\n        function setupCanvases() {\n\n            // Make sure the placeholder is clear of everything except canvases\n            // from a previous plot in this container that we'll try to re-use.\n\n            placeholder.css(\"padding\", 0) // padding messes up the positioning\n                .children().filter(function(){\n                    return !$(this).hasClass(\"flot-overlay\") && !$(this).hasClass('flot-base');\n                }).remove();\n\n            if (placeholder.css(\"position\") == 'static')\n                placeholder.css(\"position\", \"relative\"); // for positioning labels and overlay\n\n            surface = new Canvas(\"flot-base\", placeholder);\n            overlay = new Canvas(\"flot-overlay\", placeholder); // overlay canvas for interactive features\n\n            ctx = surface.context;\n            octx = overlay.context;\n\n            // define which element we're listening for events on\n            eventHolder = $(overlay.element).unbind();\n\n            // If we're re-using a plot object, shut down the old one\n\n            var existing = placeholder.data(\"plot\");\n\n            if (existing) {\n                existing.shutdown();\n                overlay.clear();\n            }\n\n            // save in case we get replotted\n            placeholder.data(\"plot\", plot);\n        }\n\n        function bindEvents() {\n            // bind events\n            if (options.grid.hoverable) {\n                eventHolder.mousemove(onMouseMove);\n\n                // Use bind, rather than .mouseleave, because we officially\n                // still support jQuery 1.2.6, which doesn't define a shortcut\n                // for mouseenter or mouseleave.  This was a bug/oversight that\n                // was fixed somewhere around 1.3.x.  We can return to using\n                // .mouseleave when we drop support for 1.2.6.\n\n                eventHolder.bind(\"mouseleave\", onMouseLeave);\n            }\n\n            if (options.grid.clickable)\n                eventHolder.click(onClick);\n\n            executeHooks(hooks.bindEvents, [eventHolder]);\n        }\n\n        function shutdown() {\n            if (redrawTimeout)\n                clearTimeout(redrawTimeout);\n\n            eventHolder.unbind(\"mousemove\", onMouseMove);\n            eventHolder.unbind(\"mouseleave\", onMouseLeave);\n            eventHolder.unbind(\"click\", onClick);\n\n            executeHooks(hooks.shutdown, [eventHolder]);\n        }\n\n        function setTransformationHelpers(axis) {\n            // set helper functions on the axis, assumes plot area\n            // has been computed already\n\n            function identity(x) { return x; }\n\n            var s, m, t = axis.options.transform || identity,\n                it = axis.options.inverseTransform;\n\n            // precompute how much the axis is scaling a point\n            // in canvas space\n            if (axis.direction == \"x\") {\n                s = axis.scale = plotWidth / Math.abs(t(axis.max) - t(axis.min));\n                m = Math.min(t(axis.max), t(axis.min));\n            }\n            else {\n                s = axis.scale = plotHeight / Math.abs(t(axis.max) - t(axis.min));\n                s = -s;\n                m = Math.max(t(axis.max), t(axis.min));\n            }\n\n            // data point to canvas coordinate\n            if (t == identity) // slight optimization\n                axis.p2c = function (p) { return (p - m) * s; };\n            else\n                axis.p2c = function (p) { return (t(p) - m) * s; };\n            // canvas coordinate to data point\n            if (!it)\n                axis.c2p = function (c) { return m + c / s; };\n            else\n                axis.c2p = function (c) { return it(m + c / s); };\n        }\n\n        function measureTickLabels(axis) {\n\n            var opts = axis.options,\n                ticks = axis.ticks || [],\n                labelWidth = opts.labelWidth || 0,\n                labelHeight = opts.labelHeight || 0,\n                maxWidth = labelWidth || (axis.direction == \"x\" ? Math.floor(surface.width / (ticks.length || 1)) : null),\n                legacyStyles = axis.direction + \"Axis \" + axis.direction + axis.n + \"Axis\",\n                layer = \"flot-\" + axis.direction + \"-axis flot-\" + axis.direction + axis.n + \"-axis \" + legacyStyles,\n                font = opts.font || \"flot-tick-label tickLabel\";\n\n            for (var i = 0; i < ticks.length; ++i) {\n\n                var t = ticks[i];\n\n                if (!t.label)\n                    continue;\n\n                var info = surface.getTextInfo(layer, t.label, font, null, maxWidth);\n\n                labelWidth = Math.max(labelWidth, info.width);\n                labelHeight = Math.max(labelHeight, info.height);\n            }\n\n            axis.labelWidth = opts.labelWidth || labelWidth;\n            axis.labelHeight = opts.labelHeight || labelHeight;\n        }\n\n        function allocateAxisBoxFirstPhase(axis) {\n            // find the bounding box of the axis by looking at label\n            // widths/heights and ticks, make room by diminishing the\n            // plotOffset; this first phase only looks at one\n            // dimension per axis, the other dimension depends on the\n            // other axes so will have to wait\n\n            var lw = axis.labelWidth,\n                lh = axis.labelHeight,\n                pos = axis.options.position,\n                isXAxis = axis.direction === \"x\",\n                tickLength = axis.options.tickLength,\n                axisMargin = options.grid.axisMargin,\n                padding = options.grid.labelMargin,\n                innermost = true,\n                outermost = true,\n                first = true,\n                found = false;\n\n            // Determine the axis's position in its direction and on its side\n\n            $.each(isXAxis ? xaxes : yaxes, function(i, a) {\n                if (a && a.reserveSpace) {\n                    if (a === axis) {\n                        found = true;\n                    } else if (a.options.position === pos) {\n                        if (found) {\n                            outermost = false;\n                        } else {\n                            innermost = false;\n                        }\n                    }\n                    if (!found) {\n                        first = false;\n                    }\n                }\n            });\n\n            // The outermost axis on each side has no margin\n\n            if (outermost) {\n                axisMargin = 0;\n            }\n\n            // The ticks for the first axis in each direction stretch across\n\n            if (tickLength == null) {\n                tickLength = first ? \"full\" : 5;\n            }\n\n            if (!isNaN(+tickLength))\n                padding += +tickLength;\n\n            if (isXAxis) {\n                lh += padding;\n\n                if (pos == \"bottom\") {\n                    plotOffset.bottom += lh + axisMargin;\n                    axis.box = { top: surface.height - plotOffset.bottom, height: lh };\n                }\n                else {\n                    axis.box = { top: plotOffset.top + axisMargin, height: lh };\n                    plotOffset.top += lh + axisMargin;\n                }\n            }\n            else {\n                lw += padding;\n\n                if (pos == \"left\") {\n                    axis.box = { left: plotOffset.left + axisMargin, width: lw };\n                    plotOffset.left += lw + axisMargin;\n                }\n                else {\n                    plotOffset.right += lw + axisMargin;\n                    axis.box = { left: surface.width - plotOffset.right, width: lw };\n                }\n            }\n\n             // save for future reference\n            axis.position = pos;\n            axis.tickLength = tickLength;\n            axis.box.padding = padding;\n            axis.innermost = innermost;\n        }\n\n        function allocateAxisBoxSecondPhase(axis) {\n            // now that all axis boxes have been placed in one\n            // dimension, we can set the remaining dimension coordinates\n            if (axis.direction == \"x\") {\n                axis.box.left = plotOffset.left - axis.labelWidth / 2;\n                axis.box.width = surface.width - plotOffset.left - plotOffset.right + axis.labelWidth;\n            }\n            else {\n                axis.box.top = plotOffset.top - axis.labelHeight / 2;\n                axis.box.height = surface.height - plotOffset.bottom - plotOffset.top + axis.labelHeight;\n            }\n        }\n\n        function adjustLayoutForThingsStickingOut() {\n            // possibly adjust plot offset to ensure everything stays\n            // inside the canvas and isn't clipped off\n\n            var minMargin = options.grid.minBorderMargin,\n                axis, i;\n\n            // check stuff from the plot (FIXME: this should just read\n            // a value from the series, otherwise it's impossible to\n            // customize)\n            if (minMargin == null) {\n                minMargin = 0;\n                for (i = 0; i < series.length; ++i)\n                    minMargin = Math.max(minMargin, 2 * (series[i].points.radius + series[i].points.lineWidth/2));\n            }\n\n            var margins = {\n                left: minMargin,\n                right: minMargin,\n                top: minMargin,\n                bottom: minMargin\n            };\n\n            // check axis labels, note we don't check the actual\n            // labels but instead use the overall width/height to not\n            // jump as much around with replots\n            $.each(allAxes(), function (_, axis) {\n                if (axis.reserveSpace && axis.ticks && axis.ticks.length) {\n                    var lastTick = axis.ticks[axis.ticks.length - 1];\n                    if (axis.direction === \"x\") {\n                        margins.left = Math.max(margins.left, axis.labelWidth / 2);\n                        if (lastTick.v <= axis.max) {\n                            margins.right = Math.max(margins.right, axis.labelWidth / 2);\n                        }\n                    } else {\n                        margins.bottom = Math.max(margins.bottom, axis.labelHeight / 2);\n                        if (lastTick.v <= axis.max) {\n                            margins.top = Math.max(margins.top, axis.labelHeight / 2);\n                        }\n                    }\n                }\n            });\n\n            plotOffset.left = Math.ceil(Math.max(margins.left, plotOffset.left));\n            plotOffset.right = Math.ceil(Math.max(margins.right, plotOffset.right));\n            plotOffset.top = Math.ceil(Math.max(margins.top, plotOffset.top));\n            plotOffset.bottom = Math.ceil(Math.max(margins.bottom, plotOffset.bottom));\n        }\n\n        function setupGrid() {\n            var i, axes = allAxes(), showGrid = options.grid.show;\n\n            // Initialize the plot's offset from the edge of the canvas\n\n            for (var a in plotOffset) {\n                var margin = options.grid.margin || 0;\n                plotOffset[a] = typeof margin == \"number\" ? margin : margin[a] || 0;\n            }\n\n            executeHooks(hooks.processOffset, [plotOffset]);\n\n            // If the grid is visible, add its border width to the offset\n\n            for (var a in plotOffset) {\n                if(typeof(options.grid.borderWidth) == \"object\") {\n                    plotOffset[a] += showGrid ? options.grid.borderWidth[a] : 0;\n                }\n                else {\n                    plotOffset[a] += showGrid ? options.grid.borderWidth : 0;\n                }\n            }\n\n            // init axes\n            $.each(axes, function (_, axis) {\n                axis.show = axis.options.show;\n                if (axis.show == null)\n                    axis.show = axis.used; // by default an axis is visible if it's got data\n\n                axis.reserveSpace = axis.show || axis.options.reserveSpace;\n\n                setRange(axis);\n            });\n\n            if (showGrid) {\n\n                var allocatedAxes = $.grep(axes, function (axis) { return axis.reserveSpace; });\n\n                $.each(allocatedAxes, function (_, axis) {\n                    // make the ticks\n                    setupTickGeneration(axis);\n                    setTicks(axis);\n                    snapRangeToTicks(axis, axis.ticks);\n                    // find labelWidth/Height for axis\n                    measureTickLabels(axis);\n                });\n\n                // with all dimensions calculated, we can compute the\n                // axis bounding boxes, start from the outside\n                // (reverse order)\n                for (i = allocatedAxes.length - 1; i >= 0; --i)\n                    allocateAxisBoxFirstPhase(allocatedAxes[i]);\n\n                // make sure we've got enough space for things that\n                // might stick out\n                adjustLayoutForThingsStickingOut();\n\n                $.each(allocatedAxes, function (_, axis) {\n                    allocateAxisBoxSecondPhase(axis);\n                });\n            }\n\n            plotWidth = surface.width - plotOffset.left - plotOffset.right;\n            plotHeight = surface.height - plotOffset.bottom - plotOffset.top;\n\n            // now we got the proper plot dimensions, we can compute the scaling\n            $.each(axes, function (_, axis) {\n                setTransformationHelpers(axis);\n            });\n\n            if (showGrid) {\n                drawAxisLabels();\n            }\n\n            insertLegend();\n        }\n\n        function setRange(axis) {\n            var opts = axis.options,\n                min = +(opts.min != null ? opts.min : axis.datamin),\n                max = +(opts.max != null ? opts.max : axis.datamax),\n                delta = max - min;\n\n            if (delta == 0.0) {\n                // degenerate case\n                var widen = max == 0 ? 1 : 0.01;\n\n                if (opts.min == null)\n                    min -= widen;\n                // always widen max if we couldn't widen min to ensure we\n                // don't fall into min == max which doesn't work\n                if (opts.max == null || opts.min != null)\n                    max += widen;\n            }\n            else {\n                // consider autoscaling\n                var margin = opts.autoscaleMargin;\n                if (margin != null) {\n                    if (opts.min == null) {\n                        min -= delta * margin;\n                        // make sure we don't go below zero if all values\n                        // are positive\n                        if (min < 0 && axis.datamin != null && axis.datamin >= 0)\n                            min = 0;\n                    }\n                    if (opts.max == null) {\n                        max += delta * margin;\n                        if (max > 0 && axis.datamax != null && axis.datamax <= 0)\n                            max = 0;\n                    }\n                }\n            }\n            axis.min = min;\n            axis.max = max;\n        }\n\n        function setupTickGeneration(axis) {\n            var opts = axis.options;\n\n            // estimate number of ticks\n            var noTicks;\n            if (typeof opts.ticks == \"number\" && opts.ticks > 0)\n                noTicks = opts.ticks;\n            else\n                // heuristic based on the model a*sqrt(x) fitted to\n                // some data points that seemed reasonable\n                noTicks = 0.3 * Math.sqrt(axis.direction == \"x\" ? surface.width : surface.height);\n\n            var delta = (axis.max - axis.min) / noTicks,\n                dec = -Math.floor(Math.log(delta) / Math.LN10),\n                maxDec = opts.tickDecimals;\n\n            if (maxDec != null && dec > maxDec) {\n                dec = maxDec;\n            }\n\n            var magn = Math.pow(10, -dec),\n                norm = delta / magn, // norm is between 1.0 and 10.0\n                size;\n\n            if (norm < 1.5) {\n                size = 1;\n            } else if (norm < 3) {\n                size = 2;\n                // special case for 2.5, requires an extra decimal\n                if (norm > 2.25 && (maxDec == null || dec + 1 <= maxDec)) {\n                    size = 2.5;\n                    ++dec;\n                }\n            } else if (norm < 7.5) {\n                size = 5;\n            } else {\n                size = 10;\n            }\n\n            size *= magn;\n\n            if (opts.minTickSize != null && size < opts.minTickSize) {\n                size = opts.minTickSize;\n            }\n\n            axis.delta = delta;\n            axis.tickDecimals = Math.max(0, maxDec != null ? maxDec : dec);\n            axis.tickSize = opts.tickSize || size;\n\n            // Time mode was moved to a plug-in in 0.8, but since so many people use this\n            // we'll add an especially friendly make sure they remembered to include it.\n\n            if (opts.mode == \"time\" && !axis.tickGenerator) {\n                throw new Error(\"Time mode requires the flot.time plugin.\");\n            }\n\n            // Flot supports base-10 axes; any other mode else is handled by a plug-in,\n            // like flot.time.js.\n\n            if (!axis.tickGenerator) {\n\n                axis.tickGenerator = function (axis) {\n\n                    var ticks = [],\n                        start = floorInBase(axis.min, axis.tickSize),\n                        i = 0,\n                        v = Number.NaN,\n                        prev;\n\n                    do {\n                        prev = v;\n                        v = start + i * axis.tickSize;\n                        ticks.push(v);\n                        ++i;\n                    } while (v < axis.max && v != prev);\n                    return ticks;\n                };\n\n\t\t\t\taxis.tickFormatter = function (value, axis) {\n\n\t\t\t\t\tvar factor = axis.tickDecimals ? Math.pow(10, axis.tickDecimals) : 1;\n\t\t\t\t\tvar formatted = \"\" + Math.round(value * factor) / factor;\n\n\t\t\t\t\t// If tickDecimals was specified, ensure that we have exactly that\n\t\t\t\t\t// much precision; otherwise default to the value's own precision.\n\n\t\t\t\t\tif (axis.tickDecimals != null) {\n\t\t\t\t\t\tvar decimal = formatted.indexOf(\".\");\n\t\t\t\t\t\tvar precision = decimal == -1 ? 0 : formatted.length - decimal - 1;\n\t\t\t\t\t\tif (precision < axis.tickDecimals) {\n\t\t\t\t\t\t\treturn (precision ? formatted : formatted + \".\") + (\"\" + factor).substr(1, axis.tickDecimals - precision);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n                    return formatted;\n                };\n            }\n\n            if ($.isFunction(opts.tickFormatter))\n                axis.tickFormatter = function (v, axis) { return \"\" + opts.tickFormatter(v, axis); };\n\n            if (opts.alignTicksWithAxis != null) {\n                var otherAxis = (axis.direction == \"x\" ? xaxes : yaxes)[opts.alignTicksWithAxis - 1];\n                if (otherAxis && otherAxis.used && otherAxis != axis) {\n                    // consider snapping min/max to outermost nice ticks\n                    var niceTicks = axis.tickGenerator(axis);\n                    if (niceTicks.length > 0) {\n                        if (opts.min == null)\n                            axis.min = Math.min(axis.min, niceTicks[0]);\n                        if (opts.max == null && niceTicks.length > 1)\n                            axis.max = Math.max(axis.max, niceTicks[niceTicks.length - 1]);\n                    }\n\n                    axis.tickGenerator = function (axis) {\n                        // copy ticks, scaled to this axis\n                        var ticks = [], v, i;\n                        for (i = 0; i < otherAxis.ticks.length; ++i) {\n                            v = (otherAxis.ticks[i].v - otherAxis.min) / (otherAxis.max - otherAxis.min);\n                            v = axis.min + v * (axis.max - axis.min);\n                            ticks.push(v);\n                        }\n                        return ticks;\n                    };\n\n                    // we might need an extra decimal since forced\n                    // ticks don't necessarily fit naturally\n                    if (!axis.mode && opts.tickDecimals == null) {\n                        var extraDec = Math.max(0, -Math.floor(Math.log(axis.delta) / Math.LN10) + 1),\n                            ts = axis.tickGenerator(axis);\n\n                        // only proceed if the tick interval rounded\n                        // with an extra decimal doesn't give us a\n                        // zero at end\n                        if (!(ts.length > 1 && /\\..*0$/.test((ts[1] - ts[0]).toFixed(extraDec))))\n                            axis.tickDecimals = extraDec;\n                    }\n                }\n            }\n        }\n\n        function setTicks(axis) {\n            var oticks = axis.options.ticks, ticks = [];\n            if (oticks == null || (typeof oticks == \"number\" && oticks > 0))\n                ticks = axis.tickGenerator(axis);\n            else if (oticks) {\n                if ($.isFunction(oticks))\n                    // generate the ticks\n                    ticks = oticks(axis);\n                else\n                    ticks = oticks;\n            }\n\n            // clean up/labelify the supplied ticks, copy them over\n            var i, v;\n            axis.ticks = [];\n            for (i = 0; i < ticks.length; ++i) {\n                var label = null;\n                var t = ticks[i];\n                if (typeof t == \"object\") {\n                    v = +t[0];\n                    if (t.length > 1)\n                        label = t[1];\n                }\n                else\n                    v = +t;\n                if (label == null)\n                    label = axis.tickFormatter(v, axis);\n                if (!isNaN(v))\n                    axis.ticks.push({ v: v, label: label });\n            }\n        }\n\n        function snapRangeToTicks(axis, ticks) {\n            if (axis.options.autoscaleMargin && ticks.length > 0) {\n                // snap to ticks\n                if (axis.options.min == null)\n                    axis.min = Math.min(axis.min, ticks[0].v);\n                if (axis.options.max == null && ticks.length > 1)\n                    axis.max = Math.max(axis.max, ticks[ticks.length - 1].v);\n            }\n        }\n\n        function draw() {\n\n            surface.clear();\n\n            executeHooks(hooks.drawBackground, [ctx]);\n\n            var grid = options.grid;\n\n            // draw background, if any\n            if (grid.show && grid.backgroundColor)\n                drawBackground();\n\n            if (grid.show && !grid.aboveData) {\n                drawGrid();\n            }\n\n            for (var i = 0; i < series.length; ++i) {\n                executeHooks(hooks.drawSeries, [ctx, series[i]]);\n                drawSeries(series[i]);\n            }\n\n            executeHooks(hooks.draw, [ctx]);\n\n            if (grid.show && grid.aboveData) {\n                drawGrid();\n            }\n\n            surface.render();\n\n            // A draw implies that either the axes or data have changed, so we\n            // should probably update the overlay highlights as well.\n\n            triggerRedrawOverlay();\n        }\n\n        function extractRange(ranges, coord) {\n            var axis, from, to, key, axes = allAxes();\n\n            for (var i = 0; i < axes.length; ++i) {\n                axis = axes[i];\n                if (axis.direction == coord) {\n                    key = coord + axis.n + \"axis\";\n                    if (!ranges[key] && axis.n == 1)\n                        key = coord + \"axis\"; // support x1axis as xaxis\n                    if (ranges[key]) {\n                        from = ranges[key].from;\n                        to = ranges[key].to;\n                        break;\n                    }\n                }\n            }\n\n            // backwards-compat stuff - to be removed in future\n            if (!ranges[key]) {\n                axis = coord == \"x\" ? xaxes[0] : yaxes[0];\n                from = ranges[coord + \"1\"];\n                to = ranges[coord + \"2\"];\n            }\n\n            // auto-reverse as an added bonus\n            if (from != null && to != null && from > to) {\n                var tmp = from;\n                from = to;\n                to = tmp;\n            }\n\n            return { from: from, to: to, axis: axis };\n        }\n\n        function drawBackground() {\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            ctx.fillStyle = getColorOrGradient(options.grid.backgroundColor, plotHeight, 0, \"rgba(255, 255, 255, 0)\");\n            ctx.fillRect(0, 0, plotWidth, plotHeight);\n            ctx.restore();\n        }\n\n        function drawGrid() {\n            var i, axes, bw, bc;\n\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            // draw markings\n            var markings = options.grid.markings;\n            if (markings) {\n                if ($.isFunction(markings)) {\n                    axes = plot.getAxes();\n                    // xmin etc. is backwards compatibility, to be\n                    // removed in the future\n                    axes.xmin = axes.xaxis.min;\n                    axes.xmax = axes.xaxis.max;\n                    axes.ymin = axes.yaxis.min;\n                    axes.ymax = axes.yaxis.max;\n\n                    markings = markings(axes);\n                }\n\n                for (i = 0; i < markings.length; ++i) {\n                    var m = markings[i],\n                        xrange = extractRange(m, \"x\"),\n                        yrange = extractRange(m, \"y\");\n\n                    // fill in missing\n                    if (xrange.from == null)\n                        xrange.from = xrange.axis.min;\n                    if (xrange.to == null)\n                        xrange.to = xrange.axis.max;\n                    if (yrange.from == null)\n                        yrange.from = yrange.axis.min;\n                    if (yrange.to == null)\n                        yrange.to = yrange.axis.max;\n\n                    // clip\n                    if (xrange.to < xrange.axis.min || xrange.from > xrange.axis.max ||\n                        yrange.to < yrange.axis.min || yrange.from > yrange.axis.max)\n                        continue;\n\n                    xrange.from = Math.max(xrange.from, xrange.axis.min);\n                    xrange.to = Math.min(xrange.to, xrange.axis.max);\n                    yrange.from = Math.max(yrange.from, yrange.axis.min);\n                    yrange.to = Math.min(yrange.to, yrange.axis.max);\n\n                    if (xrange.from == xrange.to && yrange.from == yrange.to)\n                        continue;\n\n                    // then draw\n                    xrange.from = xrange.axis.p2c(xrange.from);\n                    xrange.to = xrange.axis.p2c(xrange.to);\n                    yrange.from = yrange.axis.p2c(yrange.from);\n                    yrange.to = yrange.axis.p2c(yrange.to);\n\n                    if (xrange.from == xrange.to || yrange.from == yrange.to) {\n                        // draw line\n                        ctx.beginPath();\n                        ctx.strokeStyle = m.color || options.grid.markingsColor;\n                        ctx.lineWidth = m.lineWidth || options.grid.markingsLineWidth;\n                        ctx.moveTo(xrange.from, yrange.from);\n                        ctx.lineTo(xrange.to, yrange.to);\n                        ctx.stroke();\n                    }\n                    else {\n                        // fill area\n                        ctx.fillStyle = m.color || options.grid.markingsColor;\n                        ctx.fillRect(xrange.from, yrange.to,\n                                     xrange.to - xrange.from,\n                                     yrange.from - yrange.to);\n                    }\n                }\n            }\n\n            // draw the ticks\n            axes = allAxes();\n            bw = options.grid.borderWidth;\n\n            for (var j = 0; j < axes.length; ++j) {\n                var axis = axes[j], box = axis.box,\n                    t = axis.tickLength, x, y, xoff, yoff;\n                if (!axis.show || axis.ticks.length == 0)\n                    continue;\n\n                ctx.lineWidth = 1;\n\n                // find the edges\n                if (axis.direction == \"x\") {\n                    x = 0;\n                    if (t == \"full\")\n                        y = (axis.position == \"top\" ? 0 : plotHeight);\n                    else\n                        y = box.top - plotOffset.top + (axis.position == \"top\" ? box.height : 0);\n                }\n                else {\n                    y = 0;\n                    if (t == \"full\")\n                        x = (axis.position == \"left\" ? 0 : plotWidth);\n                    else\n                        x = box.left - plotOffset.left + (axis.position == \"left\" ? box.width : 0);\n                }\n\n                // draw tick bar\n                if (!axis.innermost) {\n                    ctx.strokeStyle = axis.options.color;\n                    ctx.beginPath();\n                    xoff = yoff = 0;\n                    if (axis.direction == \"x\")\n                        xoff = plotWidth + 1;\n                    else\n                        yoff = plotHeight + 1;\n\n                    if (ctx.lineWidth == 1) {\n                        if (axis.direction == \"x\") {\n                            y = Math.floor(y) + 0.5;\n                        } else {\n                            x = Math.floor(x) + 0.5;\n                        }\n                    }\n\n                    ctx.moveTo(x, y);\n                    ctx.lineTo(x + xoff, y + yoff);\n                    ctx.stroke();\n                }\n\n                // draw ticks\n\n                ctx.strokeStyle = axis.options.tickColor;\n\n                ctx.beginPath();\n                for (i = 0; i < axis.ticks.length; ++i) {\n                    var v = axis.ticks[i].v;\n\n                    xoff = yoff = 0;\n\n                    if (isNaN(v) || v < axis.min || v > axis.max\n                        // skip those lying on the axes if we got a border\n                        || (t == \"full\"\n                            && ((typeof bw == \"object\" && bw[axis.position] > 0) || bw > 0)\n                            && (v == axis.min || v == axis.max)))\n                        continue;\n\n                    if (axis.direction == \"x\") {\n                        x = axis.p2c(v);\n                        yoff = t == \"full\" ? -plotHeight : t;\n\n                        if (axis.position == \"top\")\n                            yoff = -yoff;\n                    }\n                    else {\n                        y = axis.p2c(v);\n                        xoff = t == \"full\" ? -plotWidth : t;\n\n                        if (axis.position == \"left\")\n                            xoff = -xoff;\n                    }\n\n                    if (ctx.lineWidth == 1) {\n                        if (axis.direction == \"x\")\n                            x = Math.floor(x) + 0.5;\n                        else\n                            y = Math.floor(y) + 0.5;\n                    }\n\n                    ctx.moveTo(x, y);\n                    ctx.lineTo(x + xoff, y + yoff);\n                }\n\n                ctx.stroke();\n            }\n\n\n            // draw border\n            if (bw) {\n                // If either borderWidth or borderColor is an object, then draw the border\n                // line by line instead of as one rectangle\n                bc = options.grid.borderColor;\n                if(typeof bw == \"object\" || typeof bc == \"object\") {\n                    if (typeof bw !== \"object\") {\n                        bw = {top: bw, right: bw, bottom: bw, left: bw};\n                    }\n                    if (typeof bc !== \"object\") {\n                        bc = {top: bc, right: bc, bottom: bc, left: bc};\n                    }\n\n                    if (bw.top > 0) {\n                        ctx.strokeStyle = bc.top;\n                        ctx.lineWidth = bw.top;\n                        ctx.beginPath();\n                        ctx.moveTo(0 - bw.left, 0 - bw.top/2);\n                        ctx.lineTo(plotWidth, 0 - bw.top/2);\n                        ctx.stroke();\n                    }\n\n                    if (bw.right > 0) {\n                        ctx.strokeStyle = bc.right;\n                        ctx.lineWidth = bw.right;\n                        ctx.beginPath();\n                        ctx.moveTo(plotWidth + bw.right / 2, 0 - bw.top);\n                        ctx.lineTo(plotWidth + bw.right / 2, plotHeight);\n                        ctx.stroke();\n                    }\n\n                    if (bw.bottom > 0) {\n                        ctx.strokeStyle = bc.bottom;\n                        ctx.lineWidth = bw.bottom;\n                        ctx.beginPath();\n                        ctx.moveTo(plotWidth + bw.right, plotHeight + bw.bottom / 2);\n                        ctx.lineTo(0, plotHeight + bw.bottom / 2);\n                        ctx.stroke();\n                    }\n\n                    if (bw.left > 0) {\n                        ctx.strokeStyle = bc.left;\n                        ctx.lineWidth = bw.left;\n                        ctx.beginPath();\n                        ctx.moveTo(0 - bw.left/2, plotHeight + bw.bottom);\n                        ctx.lineTo(0- bw.left/2, 0);\n                        ctx.stroke();\n                    }\n                }\n                else {\n                    ctx.lineWidth = bw;\n                    ctx.strokeStyle = options.grid.borderColor;\n                    ctx.strokeRect(-bw/2, -bw/2, plotWidth + bw, plotHeight + bw);\n                }\n            }\n\n            ctx.restore();\n        }\n\n        function drawAxisLabels() {\n\n            $.each(allAxes(), function (_, axis) {\n                var box = axis.box,\n                    legacyStyles = axis.direction + \"Axis \" + axis.direction + axis.n + \"Axis\",\n                    layer = \"flot-\" + axis.direction + \"-axis flot-\" + axis.direction + axis.n + \"-axis \" + legacyStyles,\n                    font = axis.options.font || \"flot-tick-label tickLabel\",\n                    tick, x, y, halign, valign;\n\n                // Remove text before checking for axis.show and ticks.length;\n                // otherwise plugins, like flot-tickrotor, that draw their own\n                // tick labels will end up with both theirs and the defaults.\n\n                surface.removeText(layer);\n\n                if (!axis.show || axis.ticks.length == 0)\n                    return;\n\n                for (var i = 0; i < axis.ticks.length; ++i) {\n\n                    tick = axis.ticks[i];\n                    if (!tick.label || tick.v < axis.min || tick.v > axis.max)\n                        continue;\n\n                    if (axis.direction == \"x\") {\n                        halign = \"center\";\n                        x = plotOffset.left + axis.p2c(tick.v);\n                        if (axis.position == \"bottom\") {\n                            y = box.top + box.padding;\n                        } else {\n                            y = box.top + box.height - box.padding;\n                            valign = \"bottom\";\n                        }\n                    } else {\n                        valign = \"middle\";\n                        y = plotOffset.top + axis.p2c(tick.v);\n                        if (axis.position == \"left\") {\n                            x = box.left + box.width - box.padding;\n                            halign = \"right\";\n                        } else {\n                            x = box.left + box.padding;\n                        }\n                    }\n\n                    surface.addText(layer, x, y, tick.label, font, null, null, halign, valign);\n                }\n            });\n        }\n\n        function drawSeries(series) {\n            if (series.lines.show)\n                drawSeriesLines(series);\n            if (series.bars.show)\n                drawSeriesBars(series);\n            if (series.points.show)\n                drawSeriesPoints(series);\n        }\n\n        function drawSeriesLines(series) {\n            function plotLine(datapoints, xoffset, yoffset, axisx, axisy) {\n                var points = datapoints.points,\n                    ps = datapoints.pointsize,\n                    prevx = null, prevy = null;\n\n                ctx.beginPath();\n                for (var i = ps; i < points.length; i += ps) {\n                    var x1 = points[i - ps], y1 = points[i - ps + 1],\n                        x2 = points[i], y2 = points[i + 1];\n\n                    if (x1 == null || x2 == null)\n                        continue;\n\n                    // clip with ymin\n                    if (y1 <= y2 && y1 < axisy.min) {\n                        if (y2 < axisy.min)\n                            continue;   // line segment is outside\n                        // compute new intersection point\n                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y1 = axisy.min;\n                    }\n                    else if (y2 <= y1 && y2 < axisy.min) {\n                        if (y1 < axisy.min)\n                            continue;\n                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y2 = axisy.min;\n                    }\n\n                    // clip with ymax\n                    if (y1 >= y2 && y1 > axisy.max) {\n                        if (y2 > axisy.max)\n                            continue;\n                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y1 = axisy.max;\n                    }\n                    else if (y2 >= y1 && y2 > axisy.max) {\n                        if (y1 > axisy.max)\n                            continue;\n                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y2 = axisy.max;\n                    }\n\n                    // clip with xmin\n                    if (x1 <= x2 && x1 < axisx.min) {\n                        if (x2 < axisx.min)\n                            continue;\n                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x1 = axisx.min;\n                    }\n                    else if (x2 <= x1 && x2 < axisx.min) {\n                        if (x1 < axisx.min)\n                            continue;\n                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x2 = axisx.min;\n                    }\n\n                    // clip with xmax\n                    if (x1 >= x2 && x1 > axisx.max) {\n                        if (x2 > axisx.max)\n                            continue;\n                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x1 = axisx.max;\n                    }\n                    else if (x2 >= x1 && x2 > axisx.max) {\n                        if (x1 > axisx.max)\n                            continue;\n                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x2 = axisx.max;\n                    }\n\n                    if (x1 != prevx || y1 != prevy)\n                        ctx.moveTo(axisx.p2c(x1) + xoffset, axisy.p2c(y1) + yoffset);\n\n                    prevx = x2;\n                    prevy = y2;\n                    ctx.lineTo(axisx.p2c(x2) + xoffset, axisy.p2c(y2) + yoffset);\n                }\n                ctx.stroke();\n            }\n\n            function plotLineArea(datapoints, axisx, axisy) {\n                var points = datapoints.points,\n                    ps = datapoints.pointsize,\n                    bottom = Math.min(Math.max(0, axisy.min), axisy.max),\n                    i = 0, top, areaOpen = false,\n                    ypos = 1, segmentStart = 0, segmentEnd = 0;\n\n                // we process each segment in two turns, first forward\n                // direction to sketch out top, then once we hit the\n                // end we go backwards to sketch the bottom\n                while (true) {\n                    if (ps > 0 && i > points.length + ps)\n                        break;\n\n                    i += ps; // ps is negative if going backwards\n\n                    var x1 = points[i - ps],\n                        y1 = points[i - ps + ypos],\n                        x2 = points[i], y2 = points[i + ypos];\n\n                    if (areaOpen) {\n                        if (ps > 0 && x1 != null && x2 == null) {\n                            // at turning point\n                            segmentEnd = i;\n                            ps = -ps;\n                            ypos = 2;\n                            continue;\n                        }\n\n                        if (ps < 0 && i == segmentStart + ps) {\n                            // done with the reverse sweep\n                            ctx.fill();\n                            areaOpen = false;\n                            ps = -ps;\n                            ypos = 1;\n                            i = segmentStart = segmentEnd + ps;\n                            continue;\n                        }\n                    }\n\n                    if (x1 == null || x2 == null)\n                        continue;\n\n                    // clip x values\n\n                    // clip with xmin\n                    if (x1 <= x2 && x1 < axisx.min) {\n                        if (x2 < axisx.min)\n                            continue;\n                        y1 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x1 = axisx.min;\n                    }\n                    else if (x2 <= x1 && x2 < axisx.min) {\n                        if (x1 < axisx.min)\n                            continue;\n                        y2 = (axisx.min - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x2 = axisx.min;\n                    }\n\n                    // clip with xmax\n                    if (x1 >= x2 && x1 > axisx.max) {\n                        if (x2 > axisx.max)\n                            continue;\n                        y1 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x1 = axisx.max;\n                    }\n                    else if (x2 >= x1 && x2 > axisx.max) {\n                        if (x1 > axisx.max)\n                            continue;\n                        y2 = (axisx.max - x1) / (x2 - x1) * (y2 - y1) + y1;\n                        x2 = axisx.max;\n                    }\n\n                    if (!areaOpen) {\n                        // open area\n                        ctx.beginPath();\n                        ctx.moveTo(axisx.p2c(x1), axisy.p2c(bottom));\n                        areaOpen = true;\n                    }\n\n                    // now first check the case where both is outside\n                    if (y1 >= axisy.max && y2 >= axisy.max) {\n                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.max));\n                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.max));\n                        continue;\n                    }\n                    else if (y1 <= axisy.min && y2 <= axisy.min) {\n                        ctx.lineTo(axisx.p2c(x1), axisy.p2c(axisy.min));\n                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(axisy.min));\n                        continue;\n                    }\n\n                    // else it's a bit more complicated, there might\n                    // be a flat maxed out rectangle first, then a\n                    // triangular cutout or reverse; to find these\n                    // keep track of the current x values\n                    var x1old = x1, x2old = x2;\n\n                    // clip the y values, without shortcutting, we\n                    // go through all cases in turn\n\n                    // clip with ymin\n                    if (y1 <= y2 && y1 < axisy.min && y2 >= axisy.min) {\n                        x1 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y1 = axisy.min;\n                    }\n                    else if (y2 <= y1 && y2 < axisy.min && y1 >= axisy.min) {\n                        x2 = (axisy.min - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y2 = axisy.min;\n                    }\n\n                    // clip with ymax\n                    if (y1 >= y2 && y1 > axisy.max && y2 <= axisy.max) {\n                        x1 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y1 = axisy.max;\n                    }\n                    else if (y2 >= y1 && y2 > axisy.max && y1 <= axisy.max) {\n                        x2 = (axisy.max - y1) / (y2 - y1) * (x2 - x1) + x1;\n                        y2 = axisy.max;\n                    }\n\n                    // if the x value was changed we got a rectangle\n                    // to fill\n                    if (x1 != x1old) {\n                        ctx.lineTo(axisx.p2c(x1old), axisy.p2c(y1));\n                        // it goes to (x1, y1), but we fill that below\n                    }\n\n                    // fill triangular section, this sometimes result\n                    // in redundant points if (x1, y1) hasn't changed\n                    // from previous line to, but we just ignore that\n                    ctx.lineTo(axisx.p2c(x1), axisy.p2c(y1));\n                    ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));\n\n                    // fill the other rectangle if it's there\n                    if (x2 != x2old) {\n                        ctx.lineTo(axisx.p2c(x2), axisy.p2c(y2));\n                        ctx.lineTo(axisx.p2c(x2old), axisy.p2c(y2));\n                    }\n                }\n            }\n\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n            ctx.lineJoin = \"round\";\n\n            var lw = series.lines.lineWidth,\n                sw = series.shadowSize;\n            // FIXME: consider another form of shadow when filling is turned on\n            if (lw > 0 && sw > 0) {\n                // draw shadow as a thick and thin line with transparency\n                ctx.lineWidth = sw;\n                ctx.strokeStyle = \"rgba(0,0,0,0.1)\";\n                // position shadow at angle from the mid of line\n                var angle = Math.PI/18;\n                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/2), Math.cos(angle) * (lw/2 + sw/2), series.xaxis, series.yaxis);\n                ctx.lineWidth = sw/2;\n                plotLine(series.datapoints, Math.sin(angle) * (lw/2 + sw/4), Math.cos(angle) * (lw/2 + sw/4), series.xaxis, series.yaxis);\n            }\n\n            ctx.lineWidth = lw;\n            ctx.strokeStyle = series.color;\n            var fillStyle = getFillStyle(series.lines, series.color, 0, plotHeight);\n            if (fillStyle) {\n                ctx.fillStyle = fillStyle;\n                plotLineArea(series.datapoints, series.xaxis, series.yaxis);\n            }\n\n            if (lw > 0)\n                plotLine(series.datapoints, 0, 0, series.xaxis, series.yaxis);\n            ctx.restore();\n        }\n\n        function drawSeriesPoints(series) {\n            function plotPoints(datapoints, radius, fillStyle, offset, shadow, axisx, axisy, symbol) {\n                var points = datapoints.points, ps = datapoints.pointsize;\n\n                for (var i = 0; i < points.length; i += ps) {\n                    var x = points[i], y = points[i + 1];\n                    if (x == null || x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)\n                        continue;\n\n                    ctx.beginPath();\n                    x = axisx.p2c(x);\n                    y = axisy.p2c(y) + offset;\n                    if (symbol == \"circle\")\n                        ctx.arc(x, y, radius, 0, shadow ? Math.PI : Math.PI * 2, false);\n                    else\n                        symbol(ctx, x, y, radius, shadow);\n                    ctx.closePath();\n\n                    if (fillStyle) {\n                        ctx.fillStyle = fillStyle;\n                        ctx.fill();\n                    }\n                    ctx.stroke();\n                }\n            }\n\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            var lw = series.points.lineWidth,\n                sw = series.shadowSize,\n                radius = series.points.radius,\n                symbol = series.points.symbol;\n\n            // If the user sets the line width to 0, we change it to a very \n            // small value. A line width of 0 seems to force the default of 1.\n            // Doing the conditional here allows the shadow setting to still be \n            // optional even with a lineWidth of 0.\n\n            if( lw == 0 )\n                lw = 0.0001;\n\n            if (lw > 0 && sw > 0) {\n                // draw shadow in two steps\n                var w = sw / 2;\n                ctx.lineWidth = w;\n                ctx.strokeStyle = \"rgba(0,0,0,0.1)\";\n                plotPoints(series.datapoints, radius, null, w + w/2, true,\n                           series.xaxis, series.yaxis, symbol);\n\n                ctx.strokeStyle = \"rgba(0,0,0,0.2)\";\n                plotPoints(series.datapoints, radius, null, w/2, true,\n                           series.xaxis, series.yaxis, symbol);\n            }\n\n            ctx.lineWidth = lw;\n            ctx.strokeStyle = series.color;\n            plotPoints(series.datapoints, radius,\n                       getFillStyle(series.points, series.color), 0, false,\n                       series.xaxis, series.yaxis, symbol);\n            ctx.restore();\n        }\n\n        function drawBar(x, y, b, barLeft, barRight, fillStyleCallback, axisx, axisy, c, horizontal, lineWidth) {\n            var left, right, bottom, top,\n                drawLeft, drawRight, drawTop, drawBottom,\n                tmp;\n\n            // in horizontal mode, we start the bar from the left\n            // instead of from the bottom so it appears to be\n            // horizontal rather than vertical\n            if (horizontal) {\n                drawBottom = drawRight = drawTop = true;\n                drawLeft = false;\n                left = b;\n                right = x;\n                top = y + barLeft;\n                bottom = y + barRight;\n\n                // account for negative bars\n                if (right < left) {\n                    tmp = right;\n                    right = left;\n                    left = tmp;\n                    drawLeft = true;\n                    drawRight = false;\n                }\n            }\n            else {\n                drawLeft = drawRight = drawTop = true;\n                drawBottom = false;\n                left = x + barLeft;\n                right = x + barRight;\n                bottom = b;\n                top = y;\n\n                // account for negative bars\n                if (top < bottom) {\n                    tmp = top;\n                    top = bottom;\n                    bottom = tmp;\n                    drawBottom = true;\n                    drawTop = false;\n                }\n            }\n\n            // clip\n            if (right < axisx.min || left > axisx.max ||\n                top < axisy.min || bottom > axisy.max)\n                return;\n\n            if (left < axisx.min) {\n                left = axisx.min;\n                drawLeft = false;\n            }\n\n            if (right > axisx.max) {\n                right = axisx.max;\n                drawRight = false;\n            }\n\n            if (bottom < axisy.min) {\n                bottom = axisy.min;\n                drawBottom = false;\n            }\n\n            if (top > axisy.max) {\n                top = axisy.max;\n                drawTop = false;\n            }\n\n            left = axisx.p2c(left);\n            bottom = axisy.p2c(bottom);\n            right = axisx.p2c(right);\n            top = axisy.p2c(top);\n\n            // fill the bar\n            if (fillStyleCallback) {\n                c.fillStyle = fillStyleCallback(bottom, top);\n                c.fillRect(left, top, right - left, bottom - top)\n            }\n\n            // draw outline\n            if (lineWidth > 0 && (drawLeft || drawRight || drawTop || drawBottom)) {\n                c.beginPath();\n\n                // FIXME: inline moveTo is buggy with excanvas\n                c.moveTo(left, bottom);\n                if (drawLeft)\n                    c.lineTo(left, top);\n                else\n                    c.moveTo(left, top);\n                if (drawTop)\n                    c.lineTo(right, top);\n                else\n                    c.moveTo(right, top);\n                if (drawRight)\n                    c.lineTo(right, bottom);\n                else\n                    c.moveTo(right, bottom);\n                if (drawBottom)\n                    c.lineTo(left, bottom);\n                else\n                    c.moveTo(left, bottom);\n                c.stroke();\n            }\n        }\n\n        function drawSeriesBars(series) {\n            function plotBars(datapoints, barLeft, barRight, fillStyleCallback, axisx, axisy) {\n                var points = datapoints.points, ps = datapoints.pointsize;\n\n                for (var i = 0; i < points.length; i += ps) {\n                    if (points[i] == null)\n                        continue;\n                    drawBar(points[i], points[i + 1], points[i + 2], barLeft, barRight, fillStyleCallback, axisx, axisy, ctx, series.bars.horizontal, series.bars.lineWidth);\n                }\n            }\n\n            ctx.save();\n            ctx.translate(plotOffset.left, plotOffset.top);\n\n            // FIXME: figure out a way to add shadows (for instance along the right edge)\n            ctx.lineWidth = series.bars.lineWidth;\n            ctx.strokeStyle = series.color;\n\n            var barLeft;\n\n            switch (series.bars.align) {\n                case \"left\":\n                    barLeft = 0;\n                    break;\n                case \"right\":\n                    barLeft = -series.bars.barWidth;\n                    break;\n                default:\n                    barLeft = -series.bars.barWidth / 2;\n            }\n\n            var fillStyleCallback = series.bars.fill ? function (bottom, top) { return getFillStyle(series.bars, series.color, bottom, top); } : null;\n            plotBars(series.datapoints, barLeft, barLeft + series.bars.barWidth, fillStyleCallback, series.xaxis, series.yaxis);\n            ctx.restore();\n        }\n\n        function getFillStyle(filloptions, seriesColor, bottom, top) {\n            var fill = filloptions.fill;\n            if (!fill)\n                return null;\n\n            if (filloptions.fillColor)\n                return getColorOrGradient(filloptions.fillColor, bottom, top, seriesColor);\n\n            var c = $.color.parse(seriesColor);\n            c.a = typeof fill == \"number\" ? fill : 0.4;\n            c.normalize();\n            return c.toString();\n        }\n\n        function insertLegend() {\n\n            if (options.legend.container != null) {\n                $(options.legend.container).html(\"\");\n            } else {\n                placeholder.find(\".legend\").remove();\n            }\n\n            if (!options.legend.show) {\n                return;\n            }\n\n            var fragments = [], entries = [], rowStarted = false,\n                lf = options.legend.labelFormatter, s, label;\n\n            // Build a list of legend entries, with each having a label and a color\n\n            for (var i = 0; i < series.length; ++i) {\n                s = series[i];\n                if (s.label) {\n                    label = lf ? lf(s.label, s) : s.label;\n                    if (label) {\n                        entries.push({\n                            label: label,\n                            color: s.color\n                        });\n                    }\n                }\n            }\n\n            // Sort the legend using either the default or a custom comparator\n\n            if (options.legend.sorted) {\n                if ($.isFunction(options.legend.sorted)) {\n                    entries.sort(options.legend.sorted);\n                } else if (options.legend.sorted == \"reverse\") {\n                \tentries.reverse();\n                } else {\n                    var ascending = options.legend.sorted != \"descending\";\n                    entries.sort(function(a, b) {\n                        return a.label == b.label ? 0 : (\n                            (a.label < b.label) != ascending ? 1 : -1   // Logical XOR\n                        );\n                    });\n                }\n            }\n\n            // Generate markup for the list of entries, in their final order\n\n            for (var i = 0; i < entries.length; ++i) {\n\n                var entry = entries[i];\n\n                if (i % options.legend.noColumns == 0) {\n                    if (rowStarted)\n                        fragments.push('</tr>');\n                    fragments.push('<tr>');\n                    rowStarted = true;\n                }\n\n                fragments.push(\n                    '<td class=\"legendColorBox\"><div style=\"border:1px solid ' + options.legend.labelBoxBorderColor + ';padding:1px\"><div style=\"width:4px;height:0;border:5px solid ' + entry.color + ';overflow:hidden\"></div></div></td>' +\n                    '<td class=\"legendLabel\">' + entry.label + '</td>'\n                );\n            }\n\n            if (rowStarted)\n                fragments.push('</tr>');\n\n            if (fragments.length == 0)\n                return;\n\n            var table = '<table style=\"font-size:smaller;color:' + options.grid.color + '\">' + fragments.join(\"\") + '</table>';\n            if (options.legend.container != null)\n                $(options.legend.container).html(table);\n            else {\n                var pos = \"\",\n                    p = options.legend.position,\n                    m = options.legend.margin;\n                if (m[0] == null)\n                    m = [m, m];\n                if (p.charAt(0) == \"n\")\n                    pos += 'top:' + (m[1] + plotOffset.top) + 'px;';\n                else if (p.charAt(0) == \"s\")\n                    pos += 'bottom:' + (m[1] + plotOffset.bottom) + 'px;';\n                if (p.charAt(1) == \"e\")\n                    pos += 'right:' + (m[0] + plotOffset.right) + 'px;';\n                else if (p.charAt(1) == \"w\")\n                    pos += 'left:' + (m[0] + plotOffset.left) + 'px;';\n                var legend = $('<div class=\"legend\">' + table.replace('style=\"', 'style=\"position:absolute;' + pos +';') + '</div>').appendTo(placeholder);\n                if (options.legend.backgroundOpacity != 0.0) {\n                    // put in the transparent background\n                    // separately to avoid blended labels and\n                    // label boxes\n                    var c = options.legend.backgroundColor;\n                    if (c == null) {\n                        c = options.grid.backgroundColor;\n                        if (c && typeof c == \"string\")\n                            c = $.color.parse(c);\n                        else\n                            c = $.color.extract(legend, 'background-color');\n                        c.a = 1;\n                        c = c.toString();\n                    }\n                    var div = legend.children();\n                    $('<div style=\"position:absolute;width:' + div.width() + 'px;height:' + div.height() + 'px;' + pos +'background-color:' + c + ';\"> </div>').prependTo(legend).css('opacity', options.legend.backgroundOpacity);\n                }\n            }\n        }\n\n\n        // interactive features\n\n        var highlights = [],\n            redrawTimeout = null;\n\n        // returns the data item the mouse is over, or null if none is found\n        function findNearbyItem(mouseX, mouseY, seriesFilter) {\n            var maxDistance = options.grid.mouseActiveRadius,\n                smallestDistance = maxDistance * maxDistance + 1,\n                item = null, foundPoint = false, i, j, ps;\n\n            for (i = series.length - 1; i >= 0; --i) {\n                if (!seriesFilter(series[i]))\n                    continue;\n\n                var s = series[i],\n                    axisx = s.xaxis,\n                    axisy = s.yaxis,\n                    points = s.datapoints.points,\n                    mx = axisx.c2p(mouseX), // precompute some stuff to make the loop faster\n                    my = axisy.c2p(mouseY),\n                    maxx = maxDistance / axisx.scale,\n                    maxy = maxDistance / axisy.scale;\n\n                ps = s.datapoints.pointsize;\n                // with inverse transforms, we can't use the maxx/maxy\n                // optimization, sadly\n                if (axisx.options.inverseTransform)\n                    maxx = Number.MAX_VALUE;\n                if (axisy.options.inverseTransform)\n                    maxy = Number.MAX_VALUE;\n\n                if (s.lines.show || s.points.show) {\n                    for (j = 0; j < points.length; j += ps) {\n                        var x = points[j], y = points[j + 1];\n                        if (x == null)\n                            continue;\n\n                        // For points and lines, the cursor must be within a\n                        // certain distance to the data point\n                        if (x - mx > maxx || x - mx < -maxx ||\n                            y - my > maxy || y - my < -maxy)\n                            continue;\n\n                        // We have to calculate distances in pixels, not in\n                        // data units, because the scales of the axes may be different\n                        var dx = Math.abs(axisx.p2c(x) - mouseX),\n                            dy = Math.abs(axisy.p2c(y) - mouseY),\n                            dist = dx * dx + dy * dy; // we save the sqrt\n\n                        // use <= to ensure last point takes precedence\n                        // (last generally means on top of)\n                        if (dist < smallestDistance) {\n                            smallestDistance = dist;\n                            item = [i, j / ps];\n                        }\n                    }\n                }\n\n                if (s.bars.show && !item) { // no other point can be nearby\n\n                    var barLeft, barRight;\n\n                    switch (s.bars.align) {\n                        case \"left\":\n                            barLeft = 0;\n                            break;\n                        case \"right\":\n                            barLeft = -s.bars.barWidth;\n                            break;\n                        default:\n                            barLeft = -s.bars.barWidth / 2;\n                    }\n\n                    barRight = barLeft + s.bars.barWidth;\n\n                    for (j = 0; j < points.length; j += ps) {\n                        var x = points[j], y = points[j + 1], b = points[j + 2];\n                        if (x == null)\n                            continue;\n\n                        // for a bar graph, the cursor must be inside the bar\n                        if (series[i].bars.horizontal ?\n                            (mx <= Math.max(b, x) && mx >= Math.min(b, x) &&\n                             my >= y + barLeft && my <= y + barRight) :\n                            (mx >= x + barLeft && mx <= x + barRight &&\n                             my >= Math.min(b, y) && my <= Math.max(b, y)))\n                                item = [i, j / ps];\n                    }\n                }\n            }\n\n            if (item) {\n                i = item[0];\n                j = item[1];\n                ps = series[i].datapoints.pointsize;\n\n                return { datapoint: series[i].datapoints.points.slice(j * ps, (j + 1) * ps),\n                         dataIndex: j,\n                         series: series[i],\n                         seriesIndex: i };\n            }\n\n            return null;\n        }\n\n        function onMouseMove(e) {\n            if (options.grid.hoverable)\n                triggerClickHoverEvent(\"plothover\", e,\n                                       function (s) { return s[\"hoverable\"] != false; });\n        }\n\n        function onMouseLeave(e) {\n            if (options.grid.hoverable)\n                triggerClickHoverEvent(\"plothover\", e,\n                                       function (s) { return false; });\n        }\n\n        function onClick(e) {\n            triggerClickHoverEvent(\"plotclick\", e,\n                                   function (s) { return s[\"clickable\"] != false; });\n        }\n\n        // trigger click or hover event (they send the same parameters\n        // so we share their code)\n        function triggerClickHoverEvent(eventname, event, seriesFilter) {\n            var offset = eventHolder.offset(),\n                canvasX = event.pageX - offset.left - plotOffset.left,\n                canvasY = event.pageY - offset.top - plotOffset.top,\n            pos = canvasToAxisCoords({ left: canvasX, top: canvasY });\n\n            pos.pageX = event.pageX;\n            pos.pageY = event.pageY;\n\n            var item = findNearbyItem(canvasX, canvasY, seriesFilter);\n\n            if (item) {\n                // fill in mouse pos for any listeners out there\n                item.pageX = parseInt(item.series.xaxis.p2c(item.datapoint[0]) + offset.left + plotOffset.left, 10);\n                item.pageY = parseInt(item.series.yaxis.p2c(item.datapoint[1]) + offset.top + plotOffset.top, 10);\n            }\n\n            if (options.grid.autoHighlight) {\n                // clear auto-highlights\n                for (var i = 0; i < highlights.length; ++i) {\n                    var h = highlights[i];\n                    if (h.auto == eventname &&\n                        !(item && h.series == item.series &&\n                          h.point[0] == item.datapoint[0] &&\n                          h.point[1] == item.datapoint[1]))\n                        unhighlight(h.series, h.point);\n                }\n\n                if (item)\n                    highlight(item.series, item.datapoint, eventname);\n            }\n\n            placeholder.trigger(eventname, [ pos, item ]);\n        }\n\n        function triggerRedrawOverlay() {\n            var t = options.interaction.redrawOverlayInterval;\n            if (t == -1) {      // skip event queue\n                drawOverlay();\n                return;\n            }\n\n            if (!redrawTimeout)\n                redrawTimeout = setTimeout(drawOverlay, t);\n        }\n\n        function drawOverlay() {\n            redrawTimeout = null;\n\n            // draw highlights\n            octx.save();\n            overlay.clear();\n            octx.translate(plotOffset.left, plotOffset.top);\n\n            var i, hi;\n            for (i = 0; i < highlights.length; ++i) {\n                hi = highlights[i];\n\n                if (hi.series.bars.show)\n                    drawBarHighlight(hi.series, hi.point);\n                else\n                    drawPointHighlight(hi.series, hi.point);\n            }\n            octx.restore();\n\n            executeHooks(hooks.drawOverlay, [octx]);\n        }\n\n        function highlight(s, point, auto) {\n            if (typeof s == \"number\")\n                s = series[s];\n\n            if (typeof point == \"number\") {\n                var ps = s.datapoints.pointsize;\n                point = s.datapoints.points.slice(ps * point, ps * (point + 1));\n            }\n\n            var i = indexOfHighlight(s, point);\n            if (i == -1) {\n                highlights.push({ series: s, point: point, auto: auto });\n\n                triggerRedrawOverlay();\n            }\n            else if (!auto)\n                highlights[i].auto = false;\n        }\n\n        function unhighlight(s, point) {\n            if (s == null && point == null) {\n                highlights = [];\n                triggerRedrawOverlay();\n                return;\n            }\n\n            if (typeof s == \"number\")\n                s = series[s];\n\n            if (typeof point == \"number\") {\n                var ps = s.datapoints.pointsize;\n                point = s.datapoints.points.slice(ps * point, ps * (point + 1));\n            }\n\n            var i = indexOfHighlight(s, point);\n            if (i != -1) {\n                highlights.splice(i, 1);\n\n                triggerRedrawOverlay();\n            }\n        }\n\n        function indexOfHighlight(s, p) {\n            for (var i = 0; i < highlights.length; ++i) {\n                var h = highlights[i];\n                if (h.series == s && h.point[0] == p[0]\n                    && h.point[1] == p[1])\n                    return i;\n            }\n            return -1;\n        }\n\n        function drawPointHighlight(series, point) {\n            var x = point[0], y = point[1],\n                axisx = series.xaxis, axisy = series.yaxis,\n                highlightColor = (typeof series.highlightColor === \"string\") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString();\n\n            if (x < axisx.min || x > axisx.max || y < axisy.min || y > axisy.max)\n                return;\n\n            var pointRadius = series.points.radius + series.points.lineWidth / 2;\n            octx.lineWidth = pointRadius;\n            octx.strokeStyle = highlightColor;\n            var radius = 1.5 * pointRadius;\n            x = axisx.p2c(x);\n            y = axisy.p2c(y);\n\n            octx.beginPath();\n            if (series.points.symbol == \"circle\")\n                octx.arc(x, y, radius, 0, 2 * Math.PI, false);\n            else\n                series.points.symbol(octx, x, y, radius, false);\n            octx.closePath();\n            octx.stroke();\n        }\n\n        function drawBarHighlight(series, point) {\n            var highlightColor = (typeof series.highlightColor === \"string\") ? series.highlightColor : $.color.parse(series.color).scale('a', 0.5).toString(),\n                fillStyle = highlightColor,\n                barLeft;\n\n            switch (series.bars.align) {\n                case \"left\":\n                    barLeft = 0;\n                    break;\n                case \"right\":\n                    barLeft = -series.bars.barWidth;\n                    break;\n                default:\n                    barLeft = -series.bars.barWidth / 2;\n            }\n\n            octx.lineWidth = series.bars.lineWidth;\n            octx.strokeStyle = highlightColor;\n\n            drawBar(point[0], point[1], point[2] || 0, barLeft, barLeft + series.bars.barWidth,\n                    function () { return fillStyle; }, series.xaxis, series.yaxis, octx, series.bars.horizontal, series.bars.lineWidth);\n        }\n\n        function getColorOrGradient(spec, bottom, top, defaultColor) {\n            if (typeof spec == \"string\")\n                return spec;\n            else {\n                // assume this is a gradient spec; IE currently only\n                // supports a simple vertical gradient properly, so that's\n                // what we support too\n                var gradient = ctx.createLinearGradient(0, top, 0, bottom);\n\n                for (var i = 0, l = spec.colors.length; i < l; ++i) {\n                    var c = spec.colors[i];\n                    if (typeof c != \"string\") {\n                        var co = $.color.parse(defaultColor);\n                        if (c.brightness != null)\n                            co = co.scale('rgb', c.brightness);\n                        if (c.opacity != null)\n                            co.a *= c.opacity;\n                        c = co.toString();\n                    }\n                    gradient.addColorStop(i / (l - 1), c);\n                }\n\n                return gradient;\n            }\n        }\n    }\n\n    // Add the plot function to the top level of the jQuery object\n\n    $.plot = function(placeholder, data, options) {\n        //var t0 = new Date();\n        var plot = new Plot($(placeholder), data, options, $.plot.plugins);\n        //(window.console ? console.log : alert)(\"time used (msecs): \" + ((new Date()).getTime() - t0.getTime()));\n        return plot;\n    };\n\n    $.plot.version = \"0.8.2\";\n\n    $.plot.plugins = [];\n\n    // Also add the plot function as a chainable property\n\n    $.fn.plot = function(data, options) {\n        return this.each(function() {\n            $.plot(this, data, options);\n        });\n    };\n\n    // round to nearby lower multiple of base\n    function floorInBase(n, base) {\n        return base * Math.floor(n / base);\n    }\n\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.navigate.js",
    "content": "/* Flot plugin for adding the ability to pan and zoom the plot.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe default behaviour is double click and scrollwheel up/down to zoom in, drag\nto pan. The plugin defines plot.zoom({ center }), plot.zoomOut() and\nplot.pan( offset ) so you easily can add custom controls. It also fires\n\"plotpan\" and \"plotzoom\" events, useful for synchronizing plots.\n\nThe plugin supports these options:\n\n\tzoom: {\n\t\tinteractive: false\n\t\ttrigger: \"dblclick\" // or \"click\" for single click\n\t\tamount: 1.5         // 2 = 200% (zoom in), 0.5 = 50% (zoom out)\n\t}\n\n\tpan: {\n\t\tinteractive: false\n\t\tcursor: \"move\"      // CSS mouse cursor value used when dragging, e.g. \"pointer\"\n\t\tframeRate: 20\n\t}\n\n\txaxis, yaxis, x2axis, y2axis: {\n\t\tzoomRange: null  // or [ number, number ] (min range, max range) or false\n\t\tpanRange: null   // or [ number, number ] (min, max) or false\n\t}\n\n\"interactive\" enables the built-in drag/click behaviour. If you enable\ninteractive for pan, then you'll have a basic plot that supports moving\naround; the same for zoom.\n\n\"amount\" specifies the default amount to zoom in (so 1.5 = 150%) relative to\nthe current viewport.\n\n\"cursor\" is a standard CSS mouse cursor string used for visual feedback to the\nuser when dragging.\n\n\"frameRate\" specifies the maximum number of times per second the plot will\nupdate itself while the user is panning around on it (set to null to disable\nintermediate pans, the plot will then not update until the mouse button is\nreleased).\n\n\"zoomRange\" is the interval in which zooming can happen, e.g. with zoomRange:\n[1, 100] the zoom will never scale the axis so that the difference between min\nand max is smaller than 1 or larger than 100. You can set either end to null\nto ignore, e.g. [1, null]. If you set zoomRange to false, zooming on that axis\nwill be disabled.\n\n\"panRange\" confines the panning to stay within a range, e.g. with panRange:\n[-10, 20] panning stops at -10 in one end and at 20 in the other. Either can\nbe null, e.g. [-10, null]. If you set panRange to false, panning on that axis\nwill be disabled.\n\nExample API usage:\n\n\tplot = $.plot(...);\n\n\t// zoom default amount in on the pixel ( 10, 20 )\n\tplot.zoom({ center: { left: 10, top: 20 } });\n\n\t// zoom out again\n\tplot.zoomOut({ center: { left: 10, top: 20 } });\n\n\t// zoom 200% in on the pixel (10, 20)\n\tplot.zoom({ amount: 2, center: { left: 10, top: 20 } });\n\n\t// pan 100 pixels to the left and 20 down\n\tplot.pan({ left: -100, top: 20 })\n\nHere, \"center\" specifies where the center of the zooming should happen. Note\nthat this is defined in pixel space, not the space of the data points (you can\nuse the p2c helpers on the axes in Flot to help you convert between these).\n\n\"amount\" is the amount to zoom the viewport relative to the current range, so\n1 is 100% (i.e. no change), 1.5 is 150% (zoom in), 0.7 is 70% (zoom out). You\ncan set the default in the options.\n\n*/\n\n// First two dependencies, jquery.event.drag.js and\n// jquery.mousewheel.js, we put them inline here to save people the\n// effort of downloading them.\n\n/*\njquery.event.drag.js ~ v1.5 ~ Copyright (c) 2008, Three Dub Media (http://threedubmedia.com)\nLicensed under the MIT License ~ http://threedubmedia.googlecode.com/files/MIT-LICENSE.txt\n*/\n(function(a){function e(h){var k,j=this,l=h.data||{};if(l.elem)j=h.dragTarget=l.elem,h.dragProxy=d.proxy||j,h.cursorOffsetX=l.pageX-l.left,h.cursorOffsetY=l.pageY-l.top,h.offsetX=h.pageX-h.cursorOffsetX,h.offsetY=h.pageY-h.cursorOffsetY;else if(d.dragging||l.which>0&&h.which!=l.which||a(h.target).is(l.not))return;switch(h.type){case\"mousedown\":return a.extend(l,a(j).offset(),{elem:j,target:h.target,pageX:h.pageX,pageY:h.pageY}),b.add(document,\"mousemove mouseup\",e,l),i(j,!1),d.dragging=null,!1;case!d.dragging&&\"mousemove\":if(g(h.pageX-l.pageX)+g(h.pageY-l.pageY)<l.distance)break;h.target=l.target,k=f(h,\"dragstart\",j),k!==!1&&(d.dragging=j,d.proxy=h.dragProxy=a(k||j)[0]);case\"mousemove\":if(d.dragging){if(k=f(h,\"drag\",j),c.drop&&(c.drop.allowed=k!==!1,c.drop.handler(h)),k!==!1)break;h.type=\"mouseup\"}case\"mouseup\":b.remove(document,\"mousemove mouseup\",e),d.dragging&&(c.drop&&c.drop.handler(h),f(h,\"dragend\",j)),i(j,!0),d.dragging=d.proxy=l.elem=!1}return!0}function f(b,c,d){b.type=c;var e=a.event.dispatch.call(d,b);return e===!1?!1:e||b.result}function g(a){return Math.pow(a,2)}function h(){return d.dragging===!1}function i(a,b){a&&(a.unselectable=b?\"off\":\"on\",a.onselectstart=function(){return b},a.style&&(a.style.MozUserSelect=b?\"\":\"none\"))}a.fn.drag=function(a,b,c){return b&&this.bind(\"dragstart\",a),c&&this.bind(\"dragend\",c),a?this.bind(\"drag\",b?b:a):this.trigger(\"drag\")};var b=a.event,c=b.special,d=c.drag={not:\":input\",distance:0,which:1,dragging:!1,setup:function(c){c=a.extend({distance:d.distance,which:d.which,not:d.not},c||{}),c.distance=g(c.distance),b.add(this,\"mousedown\",e,c),this.attachEvent&&this.attachEvent(\"ondragstart\",h)},teardown:function(){b.remove(this,\"mousedown\",e),this===d.dragging&&(d.dragging=d.proxy=!1),i(this,!0),this.detachEvent&&this.detachEvent(\"ondragstart\",h)}};c.dragstart=c.dragend={setup:function(){},teardown:function(){}}})(jQuery);\n\n/* jquery.mousewheel.min.js\n * Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)\n * Licensed under the MIT License (LICENSE.txt).\n * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.\n * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.\n * Thanks to: Seamus Leahy for adding deltaX and deltaY\n *\n * Version: 3.0.6\n *\n * Requires: 1.2.2+\n */\n(function(d){function e(a){var b=a||window.event,c=[].slice.call(arguments,1),f=0,e=0,g=0,a=d.event.fix(b);a.type=\"mousewheel\";b.wheelDelta&&(f=b.wheelDelta/120);b.detail&&(f=-b.detail/3);g=f;void 0!==b.axis&&b.axis===b.HORIZONTAL_AXIS&&(g=0,e=-1*f);void 0!==b.wheelDeltaY&&(g=b.wheelDeltaY/120);void 0!==b.wheelDeltaX&&(e=-1*b.wheelDeltaX/120);c.unshift(a,f,e,g);return(d.event.dispatch||d.event.handle).apply(this,c)}var c=[\"DOMMouseScroll\",\"mousewheel\"];if(d.event.fixHooks)for(var h=c.length;h;)d.event.fixHooks[c[--h]]=d.event.mouseHooks;d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=c.length;a;)this.addEventListener(c[--a],e,!1);else this.onmousewheel=e},teardown:function(){if(this.removeEventListener)for(var a=c.length;a;)this.removeEventListener(c[--a],e,!1);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind(\"mousewheel\",a):this.trigger(\"mousewheel\")},unmousewheel:function(a){return this.unbind(\"mousewheel\",a)}})})(jQuery);\n\n\n\n\n(function ($) {\n    var options = {\n        xaxis: {\n            zoomRange: null, // or [number, number] (min range, max range)\n            panRange: null // or [number, number] (min, max)\n        },\n        zoom: {\n            interactive: false,\n            trigger: \"dblclick\", // or \"click\" for single click\n            amount: 1.5 // how much to zoom relative to current position, 2 = 200% (zoom in), 0.5 = 50% (zoom out)\n        },\n        pan: {\n            interactive: false,\n            cursor: \"move\",\n            frameRate: 20\n        }\n    };\n\n    function init(plot) {\n        function onZoomClick(e, zoomOut) {\n            var c = plot.offset();\n            c.left = e.pageX - c.left;\n            c.top = e.pageY - c.top;\n            if (zoomOut)\n                plot.zoomOut({ center: c });\n            else\n                plot.zoom({ center: c });\n        }\n\n        function onMouseWheel(e, delta) {\n            e.preventDefault();\n            onZoomClick(e, delta < 0);\n            return false;\n        }\n        \n        var prevCursor = 'default', prevPageX = 0, prevPageY = 0,\n            panTimeout = null;\n\n        function onDragStart(e) {\n            if (e.which != 1)  // only accept left-click\n                return false;\n            var c = plot.getPlaceholder().css('cursor');\n            if (c)\n                prevCursor = c;\n            plot.getPlaceholder().css('cursor', plot.getOptions().pan.cursor);\n            prevPageX = e.pageX;\n            prevPageY = e.pageY;\n        }\n        \n        function onDrag(e) {\n            var frameRate = plot.getOptions().pan.frameRate;\n            if (panTimeout || !frameRate)\n                return;\n\n            panTimeout = setTimeout(function () {\n                plot.pan({ left: prevPageX - e.pageX,\n                           top: prevPageY - e.pageY });\n                prevPageX = e.pageX;\n                prevPageY = e.pageY;\n                                                    \n                panTimeout = null;\n            }, 1 / frameRate * 1000);\n        }\n\n        function onDragEnd(e) {\n            if (panTimeout) {\n                clearTimeout(panTimeout);\n                panTimeout = null;\n            }\n                    \n            plot.getPlaceholder().css('cursor', prevCursor);\n            plot.pan({ left: prevPageX - e.pageX,\n                       top: prevPageY - e.pageY });\n        }\n        \n        function bindEvents(plot, eventHolder) {\n            var o = plot.getOptions();\n            if (o.zoom.interactive) {\n                eventHolder[o.zoom.trigger](onZoomClick);\n                eventHolder.mousewheel(onMouseWheel);\n            }\n\n            if (o.pan.interactive) {\n                eventHolder.bind(\"dragstart\", { distance: 10 }, onDragStart);\n                eventHolder.bind(\"drag\", onDrag);\n                eventHolder.bind(\"dragend\", onDragEnd);\n            }\n        }\n\n        plot.zoomOut = function (args) {\n            if (!args)\n                args = {};\n            \n            if (!args.amount)\n                args.amount = plot.getOptions().zoom.amount;\n\n            args.amount = 1 / args.amount;\n            plot.zoom(args);\n        };\n        \n        plot.zoom = function (args) {\n            if (!args)\n                args = {};\n            \n            var c = args.center,\n                amount = args.amount || plot.getOptions().zoom.amount,\n                w = plot.width(), h = plot.height();\n\n            if (!c)\n                c = { left: w / 2, top: h / 2 };\n                \n            var xf = c.left / w,\n                yf = c.top / h,\n                minmax = {\n                    x: {\n                        min: c.left - xf * w / amount,\n                        max: c.left + (1 - xf) * w / amount\n                    },\n                    y: {\n                        min: c.top - yf * h / amount,\n                        max: c.top + (1 - yf) * h / amount\n                    }\n                };\n\n            $.each(plot.getAxes(), function(_, axis) {\n                var opts = axis.options,\n                    min = minmax[axis.direction].min,\n                    max = minmax[axis.direction].max,\n                    zr = opts.zoomRange,\n                    pr = opts.panRange;\n\n                if (zr === false) // no zooming on this axis\n                    return;\n                    \n                min = axis.c2p(min);\n                max = axis.c2p(max);\n                if (min > max) {\n                    // make sure min < max\n                    var tmp = min;\n                    min = max;\n                    max = tmp;\n                }\n\n                //Check that we are in panRange\n                if (pr) {\n                    if (pr[0] != null && min < pr[0]) {\n                        min = pr[0];\n                    }\n                    if (pr[1] != null && max > pr[1]) {\n                        max = pr[1];\n                    }\n                }\n\n                var range = max - min;\n                if (zr &&\n                    ((zr[0] != null && range < zr[0]) ||\n                     (zr[1] != null && range > zr[1])))\n                    return;\n            \n                opts.min = min;\n                opts.max = max;\n            });\n            \n            plot.setupGrid();\n            plot.draw();\n            \n            if (!args.preventEvent)\n                plot.getPlaceholder().trigger(\"plotzoom\", [ plot, args ]);\n        };\n\n        plot.pan = function (args) {\n            var delta = {\n                x: +args.left,\n                y: +args.top\n            };\n\n            if (isNaN(delta.x))\n                delta.x = 0;\n            if (isNaN(delta.y))\n                delta.y = 0;\n\n            $.each(plot.getAxes(), function (_, axis) {\n                var opts = axis.options,\n                    min, max, d = delta[axis.direction];\n\n                min = axis.c2p(axis.p2c(axis.min) + d),\n                max = axis.c2p(axis.p2c(axis.max) + d);\n\n                var pr = opts.panRange;\n                if (pr === false) // no panning on this axis\n                    return;\n                \n                if (pr) {\n                    // check whether we hit the wall\n                    if (pr[0] != null && pr[0] > min) {\n                        d = pr[0] - min;\n                        min += d;\n                        max += d;\n                    }\n                    \n                    if (pr[1] != null && pr[1] < max) {\n                        d = pr[1] - max;\n                        min += d;\n                        max += d;\n                    }\n                }\n                \n                opts.min = min;\n                opts.max = max;\n            });\n            \n            plot.setupGrid();\n            plot.draw();\n            \n            if (!args.preventEvent)\n                plot.getPlaceholder().trigger(\"plotpan\", [ plot, args ]);\n        };\n\n        function shutdown(plot, eventHolder) {\n            eventHolder.unbind(plot.getOptions().zoom.trigger, onZoomClick);\n            eventHolder.unbind(\"mousewheel\", onMouseWheel);\n            eventHolder.unbind(\"dragstart\", onDragStart);\n            eventHolder.unbind(\"drag\", onDrag);\n            eventHolder.unbind(\"dragend\", onDragEnd);\n            if (panTimeout)\n                clearTimeout(panTimeout);\n        }\n        \n        plot.hooks.bindEvents.push(bindEvents);\n        plot.hooks.shutdown.push(shutdown);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'navigate',\n        version: '1.3'\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.pie.js",
    "content": "/* Flot plugin for rendering pie charts.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin assumes that each series has a single data value, and that each\nvalue is a positive integer or zero.  Negative numbers don't make sense for a\npie chart, and have unpredictable results.  The values do NOT need to be\npassed in as percentages; the plugin will calculate the total and per-slice\npercentages internally.\n\n* Created by Brian Medendorp\n\n* Updated with contributions from btburnett3, Anthony Aragues and Xavi Ivars\n\nThe plugin supports these options:\n\n\tseries: {\n\t\tpie: {\n\t\t\tshow: true/false\n\t\t\tradius: 0-1 for percentage of fullsize, or a specified pixel length, or 'auto'\n\t\t\tinnerRadius: 0-1 for percentage of fullsize or a specified pixel length, for creating a donut effect\n\t\t\tstartAngle: 0-2 factor of PI used for starting angle (in radians) i.e 3/2 starts at the top, 0 and 2 have the same result\n\t\t\ttilt: 0-1 for percentage to tilt the pie, where 1 is no tilt, and 0 is completely flat (nothing will show)\n\t\t\toffset: {\n\t\t\t\ttop: integer value to move the pie up or down\n\t\t\t\tleft: integer value to move the pie left or right, or 'auto'\n\t\t\t},\n\t\t\tstroke: {\n\t\t\t\tcolor: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#FFF')\n\t\t\t\twidth: integer pixel width of the stroke\n\t\t\t},\n\t\t\tlabel: {\n\t\t\t\tshow: true/false, or 'auto'\n\t\t\t\tformatter:  a user-defined function that modifies the text/style of the label text\n\t\t\t\tradius: 0-1 for percentage of fullsize, or a specified pixel length\n\t\t\t\tbackground: {\n\t\t\t\t\tcolor: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#000')\n\t\t\t\t\topacity: 0-1\n\t\t\t\t},\n\t\t\t\tthreshold: 0-1 for the percentage value at which to hide labels (if they're too small)\n\t\t\t},\n\t\t\tcombine: {\n\t\t\t\tthreshold: 0-1 for the percentage value at which to combine slices (if they're too small)\n\t\t\t\tcolor: any hexidecimal color value (other formats may or may not work, so best to stick with something like '#CCC'), if null, the plugin will automatically use the color of the first slice to be combined\n\t\t\t\tlabel: any text value of what the combined slice should be labeled\n\t\t\t}\n\t\t\thighlight: {\n\t\t\t\topacity: 0-1\n\t\t\t}\n\t\t}\n\t}\n\nMore detail and specific examples can be found in the included HTML file.\n\n*/\n\n(function($) {\n\n\t// Maximum redraw attempts when fitting labels within the plot\n\n\tvar REDRAW_ATTEMPTS = 10;\n\n\t// Factor by which to shrink the pie when fitting labels within the plot\n\n\tvar REDRAW_SHRINK = 0.95;\n\n\tfunction init(plot) {\n\n\t\tvar canvas = null,\n\t\t\ttarget = null,\n\t\t\toptions = null,\n\t\t\tmaxRadius = null,\n\t\t\tcenterLeft = null,\n\t\t\tcenterTop = null,\n\t\t\tprocessed = false,\n\t\t\tctx = null;\n\n\t\t// interactive variables\n\n\t\tvar highlights = [];\n\n\t\t// add hook to determine if pie plugin in enabled, and then perform necessary operations\n\n\t\tplot.hooks.processOptions.push(function(plot, options) {\n\t\t\tif (options.series.pie.show) {\n\n\t\t\t\toptions.grid.show = false;\n\n\t\t\t\t// set labels.show\n\n\t\t\t\tif (options.series.pie.label.show == \"auto\") {\n\t\t\t\t\tif (options.legend.show) {\n\t\t\t\t\t\toptions.series.pie.label.show = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toptions.series.pie.label.show = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// set radius\n\n\t\t\t\tif (options.series.pie.radius == \"auto\") {\n\t\t\t\t\tif (options.series.pie.label.show) {\n\t\t\t\t\t\toptions.series.pie.radius = 3/4;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toptions.series.pie.radius = 1;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// ensure sane tilt\n\n\t\t\t\tif (options.series.pie.tilt > 1) {\n\t\t\t\t\toptions.series.pie.tilt = 1;\n\t\t\t\t} else if (options.series.pie.tilt < 0) {\n\t\t\t\t\toptions.series.pie.tilt = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.bindEvents.push(function(plot, eventHolder) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tif (options.grid.hoverable) {\n\t\t\t\t\teventHolder.unbind(\"mousemove\").mousemove(onMouseMove);\n\t\t\t\t}\n\t\t\t\tif (options.grid.clickable) {\n\t\t\t\t\teventHolder.unbind(\"click\").click(onClick);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.processDatapoints.push(function(plot, series, data, datapoints) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tprocessDatapoints(plot, series, data, datapoints);\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.drawOverlay.push(function(plot, octx) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tdrawOverlay(plot, octx);\n\t\t\t}\n\t\t});\n\n\t\tplot.hooks.draw.push(function(plot, newCtx) {\n\t\t\tvar options = plot.getOptions();\n\t\t\tif (options.series.pie.show) {\n\t\t\t\tdraw(plot, newCtx);\n\t\t\t}\n\t\t});\n\n\t\tfunction processDatapoints(plot, series, datapoints) {\n\t\t\tif (!processed)\t{\n\t\t\t\tprocessed = true;\n\t\t\t\tcanvas = plot.getCanvas();\n\t\t\t\ttarget = $(canvas).parent();\n\t\t\t\toptions = plot.getOptions();\n\t\t\t\tplot.setData(combine(plot.getData()));\n\t\t\t}\n\t\t}\n\n\t\tfunction combine(data) {\n\n\t\t\tvar total = 0,\n\t\t\t\tcombined = 0,\n\t\t\t\tnumCombined = 0,\n\t\t\t\tcolor = options.series.pie.combine.color,\n\t\t\t\tnewdata = [];\n\n\t\t\t// Fix up the raw data from Flot, ensuring the data is numeric\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\n\t\t\t\tvar value = data[i].data;\n\n\t\t\t\t// If the data is an array, we'll assume that it's a standard\n\t\t\t\t// Flot x-y pair, and are concerned only with the second value.\n\n\t\t\t\t// Note how we use the original array, rather than creating a\n\t\t\t\t// new one; this is more efficient and preserves any extra data\n\t\t\t\t// that the user may have stored in higher indexes.\n\n\t\t\t\tif ($.isArray(value) && value.length == 1) {\n    \t\t\t\tvalue = value[0];\n\t\t\t\t}\n\n\t\t\t\tif ($.isArray(value)) {\n\t\t\t\t\t// Equivalent to $.isNumeric() but compatible with jQuery < 1.7\n\t\t\t\t\tif (!isNaN(parseFloat(value[1])) && isFinite(value[1])) {\n\t\t\t\t\t\tvalue[1] = +value[1];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tvalue[1] = 0;\n\t\t\t\t\t}\n\t\t\t\t} else if (!isNaN(parseFloat(value)) && isFinite(value)) {\n\t\t\t\t\tvalue = [1, +value];\n\t\t\t\t} else {\n\t\t\t\t\tvalue = [1, 0];\n\t\t\t\t}\n\n\t\t\t\tdata[i].data = [value];\n\t\t\t}\n\n\t\t\t// Sum up all the slices, so we can calculate percentages for each\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\t\t\t\ttotal += data[i].data[0][1];\n\t\t\t}\n\n\t\t\t// Count the number of slices with percentages below the combine\n\t\t\t// threshold; if it turns out to be just one, we won't combine.\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\t\t\t\tvar value = data[i].data[0][1];\n\t\t\t\tif (value / total <= options.series.pie.combine.threshold) {\n\t\t\t\t\tcombined += value;\n\t\t\t\t\tnumCombined++;\n\t\t\t\t\tif (!color) {\n\t\t\t\t\t\tcolor = data[i].color;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (var i = 0; i < data.length; ++i) {\n\t\t\t\tvar value = data[i].data[0][1];\n\t\t\t\tif (numCombined < 2 || value / total > options.series.pie.combine.threshold) {\n\t\t\t\t\tnewdata.push({\n\t\t\t\t\t\tdata: [[1, value]],\n\t\t\t\t\t\tcolor: data[i].color,\n\t\t\t\t\t\tlabel: data[i].label,\n\t\t\t\t\t\tangle: value * Math.PI * 2 / total,\n\t\t\t\t\t\tpercent: value / (total / 100)\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (numCombined > 1) {\n\t\t\t\tnewdata.push({\n\t\t\t\t\tdata: [[1, combined]],\n\t\t\t\t\tcolor: color,\n\t\t\t\t\tlabel: options.series.pie.combine.label,\n\t\t\t\t\tangle: combined * Math.PI * 2 / total,\n\t\t\t\t\tpercent: combined / (total / 100)\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn newdata;\n\t\t}\n\n\t\tfunction draw(plot, newCtx) {\n\n\t\t\tif (!target) {\n\t\t\t\treturn; // if no series were passed\n\t\t\t}\n\n\t\t\tvar canvasWidth = plot.getPlaceholder().width(),\n\t\t\t\tcanvasHeight = plot.getPlaceholder().height(),\n\t\t\t\tlegendWidth = target.children().filter(\".legend\").children().width() || 0;\n\n\t\t\tctx = newCtx;\n\n\t\t\t// WARNING: HACK! REWRITE THIS CODE AS SOON AS POSSIBLE!\n\n\t\t\t// When combining smaller slices into an 'other' slice, we need to\n\t\t\t// add a new series.  Since Flot gives plugins no way to modify the\n\t\t\t// list of series, the pie plugin uses a hack where the first call\n\t\t\t// to processDatapoints results in a call to setData with the new\n\t\t\t// list of series, then subsequent processDatapoints do nothing.\n\n\t\t\t// The plugin-global 'processed' flag is used to control this hack;\n\t\t\t// it starts out false, and is set to true after the first call to\n\t\t\t// processDatapoints.\n\n\t\t\t// Unfortunately this turns future setData calls into no-ops; they\n\t\t\t// call processDatapoints, the flag is true, and nothing happens.\n\n\t\t\t// To fix this we'll set the flag back to false here in draw, when\n\t\t\t// all series have been processed, so the next sequence of calls to\n\t\t\t// processDatapoints once again starts out with a slice-combine.\n\t\t\t// This is really a hack; in 0.9 we need to give plugins a proper\n\t\t\t// way to modify series before any processing begins.\n\n\t\t\tprocessed = false;\n\n\t\t\t// calculate maximum radius and center point\n\n\t\t\tmaxRadius =  Math.min(canvasWidth, canvasHeight / options.series.pie.tilt) / 2;\n\t\t\tcenterTop = canvasHeight / 2 + options.series.pie.offset.top;\n\t\t\tcenterLeft = canvasWidth / 2;\n\n\t\t\tif (options.series.pie.offset.left == \"auto\") {\n\t\t\t\tif (options.legend.position.match(\"w\")) {\n\t\t\t\t\tcenterLeft += legendWidth / 2;\n\t\t\t\t} else {\n\t\t\t\t\tcenterLeft -= legendWidth / 2;\n\t\t\t\t}\n\t\t\t\tif (centerLeft < maxRadius) {\n\t\t\t\t\tcenterLeft = maxRadius;\n\t\t\t\t} else if (centerLeft > canvasWidth - maxRadius) {\n\t\t\t\t\tcenterLeft = canvasWidth - maxRadius;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcenterLeft += options.series.pie.offset.left;\n\t\t\t}\n\n\t\t\tvar slices = plot.getData(),\n\t\t\t\tattempts = 0;\n\n\t\t\t// Keep shrinking the pie's radius until drawPie returns true,\n\t\t\t// indicating that all the labels fit, or we try too many times.\n\n\t\t\tdo {\n\t\t\t\tif (attempts > 0) {\n\t\t\t\t\tmaxRadius *= REDRAW_SHRINK;\n\t\t\t\t}\n\t\t\t\tattempts += 1;\n\t\t\t\tclear();\n\t\t\t\tif (options.series.pie.tilt <= 0.8) {\n\t\t\t\t\tdrawShadow();\n\t\t\t\t}\n\t\t\t} while (!drawPie() && attempts < REDRAW_ATTEMPTS);\n\n\t\t\tif (attempts >= REDRAW_ATTEMPTS) {\n\t\t\t\tclear();\n\t\t\t\ttarget.prepend(\"<div class='error'>Could not draw pie with labels contained inside canvas</div>\");\n\t\t\t}\n\n\t\t\tif (plot.setSeries && plot.insertLegend) {\n\t\t\t\tplot.setSeries(slices);\n\t\t\t\tplot.insertLegend();\n\t\t\t}\n\n\t\t\t// we're actually done at this point, just defining internal functions at this point\n\n\t\t\tfunction clear() {\n\t\t\t\tctx.clearRect(0, 0, canvasWidth, canvasHeight);\n\t\t\t\ttarget.children().filter(\".pieLabel, .pieLabelBackground\").remove();\n\t\t\t}\n\n\t\t\tfunction drawShadow() {\n\n\t\t\t\tvar shadowLeft = options.series.pie.shadow.left;\n\t\t\t\tvar shadowTop = options.series.pie.shadow.top;\n\t\t\t\tvar edge = 10;\n\t\t\t\tvar alpha = options.series.pie.shadow.alpha;\n\t\t\t\tvar radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;\n\n\t\t\t\tif (radius >= canvasWidth / 2 - shadowLeft || radius * options.series.pie.tilt >= canvasHeight / 2 - shadowTop || radius <= edge) {\n\t\t\t\t\treturn;\t// shadow would be outside canvas, so don't draw it\n\t\t\t\t}\n\n\t\t\t\tctx.save();\n\t\t\t\tctx.translate(shadowLeft,shadowTop);\n\t\t\t\tctx.globalAlpha = alpha;\n\t\t\t\tctx.fillStyle = \"#000\";\n\n\t\t\t\t// center and rotate to starting position\n\n\t\t\t\tctx.translate(centerLeft,centerTop);\n\t\t\t\tctx.scale(1, options.series.pie.tilt);\n\n\t\t\t\t//radius -= edge;\n\n\t\t\t\tfor (var i = 1; i <= edge; i++) {\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.arc(0, 0, radius, 0, Math.PI * 2, false);\n\t\t\t\t\tctx.fill();\n\t\t\t\t\tradius -= i;\n\t\t\t\t}\n\n\t\t\t\tctx.restore();\n\t\t\t}\n\n\t\t\tfunction drawPie() {\n\n\t\t\t\tvar startAngle = Math.PI * options.series.pie.startAngle;\n\t\t\t\tvar radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;\n\n\t\t\t\t// center and rotate to starting position\n\n\t\t\t\tctx.save();\n\t\t\t\tctx.translate(centerLeft,centerTop);\n\t\t\t\tctx.scale(1, options.series.pie.tilt);\n\t\t\t\t//ctx.rotate(startAngle); // start at top; -- This doesn't work properly in Opera\n\n\t\t\t\t// draw slices\n\n\t\t\t\tctx.save();\n\t\t\t\tvar currentAngle = startAngle;\n\t\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\t\t\t\t\tslices[i].startAngle = currentAngle;\n\t\t\t\t\tdrawSlice(slices[i].angle, slices[i].color, true);\n\t\t\t\t}\n\t\t\t\tctx.restore();\n\n\t\t\t\t// draw slice outlines\n\n\t\t\t\tif (options.series.pie.stroke.width > 0) {\n\t\t\t\t\tctx.save();\n\t\t\t\t\tctx.lineWidth = options.series.pie.stroke.width;\n\t\t\t\t\tcurrentAngle = startAngle;\n\t\t\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\t\t\t\t\t\tdrawSlice(slices[i].angle, options.series.pie.stroke.color, false);\n\t\t\t\t\t}\n\t\t\t\t\tctx.restore();\n\t\t\t\t}\n\n\t\t\t\t// draw donut hole\n\n\t\t\t\tdrawDonutHole(ctx);\n\n\t\t\t\tctx.restore();\n\n\t\t\t\t// Draw the labels, returning true if they fit within the plot\n\n\t\t\t\tif (options.series.pie.label.show) {\n\t\t\t\t\treturn drawLabels();\n\t\t\t\t} else return true;\n\n\t\t\t\tfunction drawSlice(angle, color, fill) {\n\n\t\t\t\t\tif (angle <= 0 || isNaN(angle)) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif (fill) {\n\t\t\t\t\t\tctx.fillStyle = color;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tctx.strokeStyle = color;\n\t\t\t\t\t\tctx.lineJoin = \"round\";\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tif (Math.abs(angle - Math.PI * 2) > 0.000000001) {\n\t\t\t\t\t\tctx.moveTo(0, 0); // Center of the pie\n\t\t\t\t\t}\n\n\t\t\t\t\t//ctx.arc(0, 0, radius, 0, angle, false); // This doesn't work properly in Opera\n\t\t\t\t\tctx.arc(0, 0, radius,currentAngle, currentAngle + angle / 2, false);\n\t\t\t\t\tctx.arc(0, 0, radius,currentAngle + angle / 2, currentAngle + angle, false);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\t//ctx.rotate(angle); // This doesn't work properly in Opera\n\t\t\t\t\tcurrentAngle += angle;\n\n\t\t\t\t\tif (fill) {\n\t\t\t\t\t\tctx.fill();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tctx.stroke();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfunction drawLabels() {\n\n\t\t\t\t\tvar currentAngle = startAngle;\n\t\t\t\t\tvar radius = options.series.pie.label.radius > 1 ? options.series.pie.label.radius : maxRadius * options.series.pie.label.radius;\n\n\t\t\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\t\t\t\t\t\tif (slices[i].percent >= options.series.pie.label.threshold * 100) {\n\t\t\t\t\t\t\tif (!drawLabel(slices[i], currentAngle, i)) {\n\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcurrentAngle += slices[i].angle;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn true;\n\n\t\t\t\t\tfunction drawLabel(slice, startAngle, index) {\n\n\t\t\t\t\t\tif (slice.data[0][1] == 0) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// format label text\n\n\t\t\t\t\t\tvar lf = options.legend.labelFormatter, text, plf = options.series.pie.label.formatter;\n\n\t\t\t\t\t\tif (lf) {\n\t\t\t\t\t\t\ttext = lf(slice.label, slice);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\ttext = slice.label;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (plf) {\n\t\t\t\t\t\t\ttext = plf(text, slice);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar halfAngle = ((startAngle + slice.angle) + startAngle) / 2;\n\t\t\t\t\t\tvar x = centerLeft + Math.round(Math.cos(halfAngle) * radius);\n\t\t\t\t\t\tvar y = centerTop + Math.round(Math.sin(halfAngle) * radius) * options.series.pie.tilt;\n\n\t\t\t\t\t\tvar html = \"<span class='pieLabel' id='pieLabel\" + index + \"' style='position:absolute;top:\" + y + \"px;left:\" + x + \"px;'>\" + text + \"</span>\";\n\t\t\t\t\t\ttarget.append(html);\n\n\t\t\t\t\t\tvar label = target.children(\"#pieLabel\" + index);\n\t\t\t\t\t\tvar labelTop = (y - label.height() / 2);\n\t\t\t\t\t\tvar labelLeft = (x - label.width() / 2);\n\n\t\t\t\t\t\tlabel.css(\"top\", labelTop);\n\t\t\t\t\t\tlabel.css(\"left\", labelLeft);\n\n\t\t\t\t\t\t// check to make sure that the label is not outside the canvas\n\n\t\t\t\t\t\tif (0 - labelTop > 0 || 0 - labelLeft > 0 || canvasHeight - (labelTop + label.height()) < 0 || canvasWidth - (labelLeft + label.width()) < 0) {\n\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (options.series.pie.label.background.opacity != 0) {\n\n\t\t\t\t\t\t\t// put in the transparent background separately to avoid blended labels and label boxes\n\n\t\t\t\t\t\t\tvar c = options.series.pie.label.background.color;\n\n\t\t\t\t\t\t\tif (c == null) {\n\t\t\t\t\t\t\t\tc = slice.color;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tvar pos = \"top:\" + labelTop + \"px;left:\" + labelLeft + \"px;\";\n\t\t\t\t\t\t\t$(\"<div class='pieLabelBackground' style='position:absolute;width:\" + label.width() + \"px;height:\" + label.height() + \"px;\" + pos + \"background-color:\" + c + \";'></div>\")\n\t\t\t\t\t\t\t\t.css(\"opacity\", options.series.pie.label.background.opacity)\n\t\t\t\t\t\t\t\t.insertBefore(label);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t} // end individual label function\n\t\t\t\t} // end drawLabels function\n\t\t\t} // end drawPie function\n\t\t} // end draw function\n\n\t\t// Placed here because it needs to be accessed from multiple locations\n\n\t\tfunction drawDonutHole(layer) {\n\t\t\tif (options.series.pie.innerRadius > 0) {\n\n\t\t\t\t// subtract the center\n\n\t\t\t\tlayer.save();\n\t\t\t\tvar innerRadius = options.series.pie.innerRadius > 1 ? options.series.pie.innerRadius : maxRadius * options.series.pie.innerRadius;\n\t\t\t\tlayer.globalCompositeOperation = \"destination-out\"; // this does not work with excanvas, but it will fall back to using the stroke color\n\t\t\t\tlayer.beginPath();\n\t\t\t\tlayer.fillStyle = options.series.pie.stroke.color;\n\t\t\t\tlayer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);\n\t\t\t\tlayer.fill();\n\t\t\t\tlayer.closePath();\n\t\t\t\tlayer.restore();\n\n\t\t\t\t// add inner stroke\n\n\t\t\t\tlayer.save();\n\t\t\t\tlayer.beginPath();\n\t\t\t\tlayer.strokeStyle = options.series.pie.stroke.color;\n\t\t\t\tlayer.arc(0, 0, innerRadius, 0, Math.PI * 2, false);\n\t\t\t\tlayer.stroke();\n\t\t\t\tlayer.closePath();\n\t\t\t\tlayer.restore();\n\n\t\t\t\t// TODO: add extra shadow inside hole (with a mask) if the pie is tilted.\n\t\t\t}\n\t\t}\n\n\t\t//-- Additional Interactive related functions --\n\n\t\tfunction isPointInPoly(poly, pt) {\n\t\t\tfor(var c = false, i = -1, l = poly.length, j = l - 1; ++i < l; j = i)\n\t\t\t\t((poly[i][1] <= pt[1] && pt[1] < poly[j][1]) || (poly[j][1] <= pt[1] && pt[1]< poly[i][1]))\n\t\t\t\t&& (pt[0] < (poly[j][0] - poly[i][0]) * (pt[1] - poly[i][1]) / (poly[j][1] - poly[i][1]) + poly[i][0])\n\t\t\t\t&& (c = !c);\n\t\t\treturn c;\n\t\t}\n\n\t\tfunction findNearbySlice(mouseX, mouseY) {\n\n\t\t\tvar slices = plot.getData(),\n\t\t\t\toptions = plot.getOptions(),\n\t\t\t\tradius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius,\n\t\t\t\tx, y;\n\n\t\t\tfor (var i = 0; i < slices.length; ++i) {\n\n\t\t\t\tvar s = slices[i];\n\n\t\t\t\tif (s.pie.show) {\n\n\t\t\t\t\tctx.save();\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(0, 0); // Center of the pie\n\t\t\t\t\t//ctx.scale(1, options.series.pie.tilt);\t// this actually seems to break everything when here.\n\t\t\t\t\tctx.arc(0, 0, radius, s.startAngle, s.startAngle + s.angle / 2, false);\n\t\t\t\t\tctx.arc(0, 0, radius, s.startAngle + s.angle / 2, s.startAngle + s.angle, false);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tx = mouseX - centerLeft;\n\t\t\t\t\ty = mouseY - centerTop;\n\n\t\t\t\t\tif (ctx.isPointInPath) {\n\t\t\t\t\t\tif (ctx.isPointInPath(mouseX - centerLeft, mouseY - centerTop)) {\n\t\t\t\t\t\t\tctx.restore();\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tdatapoint: [s.percent, s.data],\n\t\t\t\t\t\t\t\tdataIndex: 0,\n\t\t\t\t\t\t\t\tseries: s,\n\t\t\t\t\t\t\t\tseriesIndex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// excanvas for IE doesn;t support isPointInPath, this is a workaround.\n\n\t\t\t\t\t\tvar p1X = radius * Math.cos(s.startAngle),\n\t\t\t\t\t\t\tp1Y = radius * Math.sin(s.startAngle),\n\t\t\t\t\t\t\tp2X = radius * Math.cos(s.startAngle + s.angle / 4),\n\t\t\t\t\t\t\tp2Y = radius * Math.sin(s.startAngle + s.angle / 4),\n\t\t\t\t\t\t\tp3X = radius * Math.cos(s.startAngle + s.angle / 2),\n\t\t\t\t\t\t\tp3Y = radius * Math.sin(s.startAngle + s.angle / 2),\n\t\t\t\t\t\t\tp4X = radius * Math.cos(s.startAngle + s.angle / 1.5),\n\t\t\t\t\t\t\tp4Y = radius * Math.sin(s.startAngle + s.angle / 1.5),\n\t\t\t\t\t\t\tp5X = radius * Math.cos(s.startAngle + s.angle),\n\t\t\t\t\t\t\tp5Y = radius * Math.sin(s.startAngle + s.angle),\n\t\t\t\t\t\t\tarrPoly = [[0, 0], [p1X, p1Y], [p2X, p2Y], [p3X, p3Y], [p4X, p4Y], [p5X, p5Y]],\n\t\t\t\t\t\t\tarrPoint = [x, y];\n\n\t\t\t\t\t\t// TODO: perhaps do some mathmatical trickery here with the Y-coordinate to compensate for pie tilt?\n\n\t\t\t\t\t\tif (isPointInPoly(arrPoly, arrPoint)) {\n\t\t\t\t\t\t\tctx.restore();\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tdatapoint: [s.percent, s.data],\n\t\t\t\t\t\t\t\tdataIndex: 0,\n\t\t\t\t\t\t\t\tseries: s,\n\t\t\t\t\t\t\t\tseriesIndex: i\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tctx.restore();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\tfunction onMouseMove(e) {\n\t\t\ttriggerClickHoverEvent(\"plothover\", e);\n\t\t}\n\n\t\tfunction onClick(e) {\n\t\t\ttriggerClickHoverEvent(\"plotclick\", e);\n\t\t}\n\n\t\t// trigger click or hover event (they send the same parameters so we share their code)\n\n\t\tfunction triggerClickHoverEvent(eventname, e) {\n\n\t\t\tvar offset = plot.offset();\n\t\t\tvar canvasX = parseInt(e.pageX - offset.left);\n\t\t\tvar canvasY =  parseInt(e.pageY - offset.top);\n\t\t\tvar item = findNearbySlice(canvasX, canvasY);\n\n\t\t\tif (options.grid.autoHighlight) {\n\n\t\t\t\t// clear auto-highlights\n\n\t\t\t\tfor (var i = 0; i < highlights.length; ++i) {\n\t\t\t\t\tvar h = highlights[i];\n\t\t\t\t\tif (h.auto == eventname && !(item && h.series == item.series)) {\n\t\t\t\t\t\tunhighlight(h.series);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// highlight the slice\n\n\t\t\tif (item) {\n\t\t\t\thighlight(item.series, eventname);\n\t\t\t}\n\n\t\t\t// trigger any hover bind events\n\n\t\t\tvar pos = { pageX: e.pageX, pageY: e.pageY };\n\t\t\ttarget.trigger(eventname, [pos, item]);\n\t\t}\n\n\t\tfunction highlight(s, auto) {\n\t\t\t//if (typeof s == \"number\") {\n\t\t\t//\ts = series[s];\n\t\t\t//}\n\n\t\t\tvar i = indexOfHighlight(s);\n\n\t\t\tif (i == -1) {\n\t\t\t\thighlights.push({ series: s, auto: auto });\n\t\t\t\tplot.triggerRedrawOverlay();\n\t\t\t} else if (!auto) {\n\t\t\t\thighlights[i].auto = false;\n\t\t\t}\n\t\t}\n\n\t\tfunction unhighlight(s) {\n\t\t\tif (s == null) {\n\t\t\t\thighlights = [];\n\t\t\t\tplot.triggerRedrawOverlay();\n\t\t\t}\n\n\t\t\t//if (typeof s == \"number\") {\n\t\t\t//\ts = series[s];\n\t\t\t//}\n\n\t\t\tvar i = indexOfHighlight(s);\n\n\t\t\tif (i != -1) {\n\t\t\t\thighlights.splice(i, 1);\n\t\t\t\tplot.triggerRedrawOverlay();\n\t\t\t}\n\t\t}\n\n\t\tfunction indexOfHighlight(s) {\n\t\t\tfor (var i = 0; i < highlights.length; ++i) {\n\t\t\t\tvar h = highlights[i];\n\t\t\t\tif (h.series == s)\n\t\t\t\t\treturn i;\n\t\t\t}\n\t\t\treturn -1;\n\t\t}\n\n\t\tfunction drawOverlay(plot, octx) {\n\n\t\t\tvar options = plot.getOptions();\n\n\t\t\tvar radius = options.series.pie.radius > 1 ? options.series.pie.radius : maxRadius * options.series.pie.radius;\n\n\t\t\toctx.save();\n\t\t\toctx.translate(centerLeft, centerTop);\n\t\t\toctx.scale(1, options.series.pie.tilt);\n\n\t\t\tfor (var i = 0; i < highlights.length; ++i) {\n\t\t\t\tdrawHighlight(highlights[i].series);\n\t\t\t}\n\n\t\t\tdrawDonutHole(octx);\n\n\t\t\toctx.restore();\n\n\t\t\tfunction drawHighlight(series) {\n\n\t\t\t\tif (series.angle <= 0 || isNaN(series.angle)) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t//octx.fillStyle = parseColor(options.series.pie.highlight.color).scale(null, null, null, options.series.pie.highlight.opacity).toString();\n\t\t\t\toctx.fillStyle = \"rgba(255, 255, 255, \" + options.series.pie.highlight.opacity + \")\"; // this is temporary until we have access to parseColor\n\t\t\t\toctx.beginPath();\n\t\t\t\tif (Math.abs(series.angle - Math.PI * 2) > 0.000000001) {\n\t\t\t\t\toctx.moveTo(0, 0); // Center of the pie\n\t\t\t\t}\n\t\t\t\toctx.arc(0, 0, radius, series.startAngle, series.startAngle + series.angle / 2, false);\n\t\t\t\toctx.arc(0, 0, radius, series.startAngle + series.angle / 2, series.startAngle + series.angle, false);\n\t\t\t\toctx.closePath();\n\t\t\t\toctx.fill();\n\t\t\t}\n\t\t}\n\t} // end init (plugin body)\n\n\t// define pie specific options and their default values\n\n\tvar options = {\n\t\tseries: {\n\t\t\tpie: {\n\t\t\t\tshow: false,\n\t\t\t\tradius: \"auto\",\t// actual radius of the visible pie (based on full calculated radius if <=1, or hard pixel value)\n\t\t\t\tinnerRadius: 0, /* for donut */\n\t\t\t\tstartAngle: 3/2,\n\t\t\t\ttilt: 1,\n\t\t\t\tshadow: {\n\t\t\t\t\tleft: 5,\t// shadow left offset\n\t\t\t\t\ttop: 15,\t// shadow top offset\n\t\t\t\t\talpha: 0.02\t// shadow alpha\n\t\t\t\t},\n\t\t\t\toffset: {\n\t\t\t\t\ttop: 0,\n\t\t\t\t\tleft: \"auto\"\n\t\t\t\t},\n\t\t\t\tstroke: {\n\t\t\t\t\tcolor: \"#fff\",\n\t\t\t\t\twidth: 1\n\t\t\t\t},\n\t\t\t\tlabel: {\n\t\t\t\t\tshow: \"auto\",\n\t\t\t\t\tformatter: function(label, slice) {\n\t\t\t\t\t\treturn \"<div style='font-size:x-small;text-align:center;padding:2px;color:\" + slice.color + \";'>\" + label + \"<br/>\" + Math.round(slice.percent) + \"%</div>\";\n\t\t\t\t\t},\t// formatter function\n\t\t\t\t\tradius: 1,\t// radius at which to place the labels (based on full calculated radius if <=1, or hard pixel value)\n\t\t\t\t\tbackground: {\n\t\t\t\t\t\tcolor: null,\n\t\t\t\t\t\topacity: 0\n\t\t\t\t\t},\n\t\t\t\t\tthreshold: 0\t// percentage at which to hide the label (i.e. the slice is too narrow)\n\t\t\t\t},\n\t\t\t\tcombine: {\n\t\t\t\t\tthreshold: -1,\t// percentage at which to combine little slices into one larger slice\n\t\t\t\t\tcolor: null,\t// color to give the new slice (auto-generated if null)\n\t\t\t\t\tlabel: \"Other\"\t// label to give the new slice\n\t\t\t\t},\n\t\t\t\thighlight: {\n\t\t\t\t\t//color: \"#fff\",\t\t// will add this functionality once parseColor is available\n\t\t\t\t\topacity: 0.5\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n\n\t$.plot.plugins.push({\n\t\tinit: init,\n\t\toptions: options,\n\t\tname: \"pie\",\n\t\tversion: \"1.1\"\n\t});\n\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.resize.js",
    "content": "/* Flot plugin for automatically redrawing plots as the placeholder resizes.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nIt works by listening for changes on the placeholder div (through the jQuery\nresize event plugin) - if the size changes, it will redraw the plot.\n\nThere are no options. If you need to disable the plugin for some plots, you\ncan just fix the size of their placeholders.\n\n*/\n\n/* Inline dependency:\n * jQuery resize event - v1.1 - 3/14/2010\n * http://benalman.com/projects/jquery-resize-plugin/\n *\n * Copyright (c) 2010 \"Cowboy\" Ben Alman\n * Dual licensed under the MIT and GPL licenses.\n * http://benalman.com/about/license/\n */\n\n(function($,t,n){function p(){for(var n=r.length-1;n>=0;n--){var o=$(r[n]);if(o[0]==t||o.is(\":visible\")){var h=o.width(),d=o.height(),v=o.data(a);!v||h===v.w&&d===v.h?i[f]=i[l]:(i[f]=i[c],o.trigger(u,[v.w=h,v.h=d]))}else v=o.data(a),v.w=0,v.h=0}s!==null&&(s=t.requestAnimationFrame(p))}var r=[],i=$.resize=$.extend($.resize,{}),s,o=\"setTimeout\",u=\"resize\",a=u+\"-special-event\",f=\"delay\",l=\"pendingDelay\",c=\"activeDelay\",h=\"throttleWindow\";i[l]=250,i[c]=20,i[f]=i[l],i[h]=!0,$.event.special[u]={setup:function(){if(!i[h]&&this[o])return!1;var t=$(this);r.push(this),t.data(a,{w:t.width(),h:t.height()}),r.length===1&&(s=n,p())},teardown:function(){if(!i[h]&&this[o])return!1;var t=$(this);for(var n=r.length-1;n>=0;n--)if(r[n]==this){r.splice(n,1);break}t.removeData(a),r.length||(cancelAnimationFrame(s),s=null)},add:function(t){function s(t,i,s){var o=$(this),u=o.data(a);u.w=i!==n?i:o.width(),u.h=s!==n?s:o.height(),r.apply(this,arguments)}if(!i[h]&&this[o])return!1;var r;if($.isFunction(t))return r=t,s;r=t.handler,t.handler=s}},t.requestAnimationFrame||(t.requestAnimationFrame=function(){return t.webkitRequestAnimationFrame||t.mozRequestAnimationFrame||t.oRequestAnimationFrame||t.msRequestAnimationFrame||function(e,n){return t.setTimeout(e,i[f])}}()),t.cancelAnimationFrame||(t.cancelAnimationFrame=function(){return t.webkitCancelRequestAnimationFrame||t.mozCancelRequestAnimationFrame||t.oCancelRequestAnimationFrame||t.msCancelRequestAnimationFrame||clearTimeout}())})(jQuery,this);\n\n(function ($) {\n    var options = { }; // no options\n\n    function init(plot) {\n        function onResize() {\n            var placeholder = plot.getPlaceholder();\n\n            // somebody might have hidden us and we can't plot\n            // when we don't have the dimensions\n            if (placeholder.width() == 0 || placeholder.height() == 0)\n                return;\n\n            plot.resize();\n            plot.setupGrid();\n            plot.draw();\n        }\n        \n        function bindEvents(plot, eventHolder) {\n            plot.getPlaceholder().resize(onResize);\n        }\n\n        function shutdown(plot, eventHolder) {\n            plot.getPlaceholder().unbind(\"resize\", onResize);\n        }\n        \n        plot.hooks.bindEvents.push(bindEvents);\n        plot.hooks.shutdown.push(shutdown);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'resize',\n        version: '1.0'\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.selection.js",
    "content": "/* Flot plugin for selecting regions of a plot.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin supports these options:\n\nselection: {\n\tmode: null or \"x\" or \"y\" or \"xy\",\n\tcolor: color,\n\tshape: \"round\" or \"miter\" or \"bevel\",\n\tminSize: number of pixels\n}\n\nSelection support is enabled by setting the mode to one of \"x\", \"y\" or \"xy\".\nIn \"x\" mode, the user will only be able to specify the x range, similarly for\n\"y\" mode. For \"xy\", the selection becomes a rectangle where both ranges can be\nspecified. \"color\" is color of the selection (if you need to change the color\nlater on, you can get to it with plot.getOptions().selection.color). \"shape\"\nis the shape of the corners of the selection.\n\n\"minSize\" is the minimum size a selection can be in pixels. This value can\nbe customized to determine the smallest size a selection can be and still\nhave the selection rectangle be displayed. When customizing this value, the\nfact that it refers to pixels, not axis units must be taken into account.\nThus, for example, if there is a bar graph in time mode with BarWidth set to 1\nminute, setting \"minSize\" to 1 will not make the minimum selection size 1\nminute, but rather 1 pixel. Note also that setting \"minSize\" to 0 will prevent\n\"plotunselected\" events from being fired when the user clicks the mouse without\ndragging.\n\nWhen selection support is enabled, a \"plotselected\" event will be emitted on\nthe DOM element you passed into the plot function. The event handler gets a\nparameter with the ranges selected on the axes, like this:\n\n\tplaceholder.bind( \"plotselected\", function( event, ranges ) {\n\t\talert(\"You selected \" + ranges.xaxis.from + \" to \" + ranges.xaxis.to)\n\t\t// similar for yaxis - with multiple axes, the extra ones are in\n\t\t// x2axis, x3axis, ...\n\t});\n\nThe \"plotselected\" event is only fired when the user has finished making the\nselection. A \"plotselecting\" event is fired during the process with the same\nparameters as the \"plotselected\" event, in case you want to know what's\nhappening while it's happening,\n\nA \"plotunselected\" event with no arguments is emitted when the user clicks the\nmouse to remove the selection. As stated above, setting \"minSize\" to 0 will\ndestroy this behavior.\n\nThe plugin allso adds the following methods to the plot object:\n\n- setSelection( ranges, preventEvent )\n\n  Set the selection rectangle. The passed in ranges is on the same form as\n  returned in the \"plotselected\" event. If the selection mode is \"x\", you\n  should put in either an xaxis range, if the mode is \"y\" you need to put in\n  an yaxis range and both xaxis and yaxis if the selection mode is \"xy\", like\n  this:\n\n\tsetSelection({ xaxis: { from: 0, to: 10 }, yaxis: { from: 40, to: 60 } });\n\n  setSelection will trigger the \"plotselected\" event when called. If you don't\n  want that to happen, e.g. if you're inside a \"plotselected\" handler, pass\n  true as the second parameter. If you are using multiple axes, you can\n  specify the ranges on any of those, e.g. as x2axis/x3axis/... instead of\n  xaxis, the plugin picks the first one it sees.\n\n- clearSelection( preventEvent )\n\n  Clear the selection rectangle. Pass in true to avoid getting a\n  \"plotunselected\" event.\n\n- getSelection()\n\n  Returns the current selection in the same format as the \"plotselected\"\n  event. If there's currently no selection, the function returns null.\n\n*/\n\n(function ($) {\n    function init(plot) {\n        var selection = {\n                first: { x: -1, y: -1}, second: { x: -1, y: -1},\n                show: false,\n                active: false\n            };\n\n        // FIXME: The drag handling implemented here should be\n        // abstracted out, there's some similar code from a library in\n        // the navigation plugin, this should be massaged a bit to fit\n        // the Flot cases here better and reused. Doing this would\n        // make this plugin much slimmer.\n        var savedhandlers = {};\n\n        var mouseUpHandler = null;\n        \n        function onMouseMove(e) {\n            if (selection.active) {\n                updateSelection(e);\n                \n                plot.getPlaceholder().trigger(\"plotselecting\", [ getSelection() ]);\n            }\n        }\n\n        function onMouseDown(e) {\n            if (e.which != 1)  // only accept left-click\n                return;\n            \n            // cancel out any text selections\n            document.body.focus();\n\n            // prevent text selection and drag in old-school browsers\n            if (document.onselectstart !== undefined && savedhandlers.onselectstart == null) {\n                savedhandlers.onselectstart = document.onselectstart;\n                document.onselectstart = function () { return false; };\n            }\n            if (document.ondrag !== undefined && savedhandlers.ondrag == null) {\n                savedhandlers.ondrag = document.ondrag;\n                document.ondrag = function () { return false; };\n            }\n\n            setSelectionPos(selection.first, e);\n\n            selection.active = true;\n\n            // this is a bit silly, but we have to use a closure to be\n            // able to whack the same handler again\n            mouseUpHandler = function (e) { onMouseUp(e); };\n            \n            $(document).one(\"mouseup\", mouseUpHandler);\n        }\n\n        function onMouseUp(e) {\n            mouseUpHandler = null;\n            \n            // revert drag stuff for old-school browsers\n            if (document.onselectstart !== undefined)\n                document.onselectstart = savedhandlers.onselectstart;\n            if (document.ondrag !== undefined)\n                document.ondrag = savedhandlers.ondrag;\n\n            // no more dragging\n            selection.active = false;\n            updateSelection(e);\n\n            if (selectionIsSane())\n                triggerSelectedEvent();\n            else {\n                // this counts as a clear\n                plot.getPlaceholder().trigger(\"plotunselected\", [ ]);\n                plot.getPlaceholder().trigger(\"plotselecting\", [ null ]);\n            }\n\n            return false;\n        }\n\n        function getSelection() {\n            if (!selectionIsSane())\n                return null;\n            \n            if (!selection.show) return null;\n\n            var r = {}, c1 = selection.first, c2 = selection.second;\n            $.each(plot.getAxes(), function (name, axis) {\n                if (axis.used) {\n                    var p1 = axis.c2p(c1[axis.direction]), p2 = axis.c2p(c2[axis.direction]); \n                    r[name] = { from: Math.min(p1, p2), to: Math.max(p1, p2) };\n                }\n            });\n            return r;\n        }\n\n        function triggerSelectedEvent() {\n            var r = getSelection();\n\n            plot.getPlaceholder().trigger(\"plotselected\", [ r ]);\n\n            // backwards-compat stuff, to be removed in future\n            if (r.xaxis && r.yaxis)\n                plot.getPlaceholder().trigger(\"selected\", [ { x1: r.xaxis.from, y1: r.yaxis.from, x2: r.xaxis.to, y2: r.yaxis.to } ]);\n        }\n\n        function clamp(min, value, max) {\n            return value < min ? min: (value > max ? max: value);\n        }\n\n        function setSelectionPos(pos, e) {\n            var o = plot.getOptions();\n            var offset = plot.getPlaceholder().offset();\n            var plotOffset = plot.getPlotOffset();\n            pos.x = clamp(0, e.pageX - offset.left - plotOffset.left, plot.width());\n            pos.y = clamp(0, e.pageY - offset.top - plotOffset.top, plot.height());\n\n            if (o.selection.mode == \"y\")\n                pos.x = pos == selection.first ? 0 : plot.width();\n\n            if (o.selection.mode == \"x\")\n                pos.y = pos == selection.first ? 0 : plot.height();\n        }\n\n        function updateSelection(pos) {\n            if (pos.pageX == null)\n                return;\n\n            setSelectionPos(selection.second, pos);\n            if (selectionIsSane()) {\n                selection.show = true;\n                plot.triggerRedrawOverlay();\n            }\n            else\n                clearSelection(true);\n        }\n\n        function clearSelection(preventEvent) {\n            if (selection.show) {\n                selection.show = false;\n                plot.triggerRedrawOverlay();\n                if (!preventEvent)\n                    plot.getPlaceholder().trigger(\"plotunselected\", [ ]);\n            }\n        }\n\n        // function taken from markings support in Flot\n        function extractRange(ranges, coord) {\n            var axis, from, to, key, axes = plot.getAxes();\n\n            for (var k in axes) {\n                axis = axes[k];\n                if (axis.direction == coord) {\n                    key = coord + axis.n + \"axis\";\n                    if (!ranges[key] && axis.n == 1)\n                        key = coord + \"axis\"; // support x1axis as xaxis\n                    if (ranges[key]) {\n                        from = ranges[key].from;\n                        to = ranges[key].to;\n                        break;\n                    }\n                }\n            }\n\n            // backwards-compat stuff - to be removed in future\n            if (!ranges[key]) {\n                axis = coord == \"x\" ? plot.getXAxes()[0] : plot.getYAxes()[0];\n                from = ranges[coord + \"1\"];\n                to = ranges[coord + \"2\"];\n            }\n\n            // auto-reverse as an added bonus\n            if (from != null && to != null && from > to) {\n                var tmp = from;\n                from = to;\n                to = tmp;\n            }\n            \n            return { from: from, to: to, axis: axis };\n        }\n        \n        function setSelection(ranges, preventEvent) {\n            var axis, range, o = plot.getOptions();\n\n            if (o.selection.mode == \"y\") {\n                selection.first.x = 0;\n                selection.second.x = plot.width();\n            }\n            else {\n                range = extractRange(ranges, \"x\");\n\n                selection.first.x = range.axis.p2c(range.from);\n                selection.second.x = range.axis.p2c(range.to);\n            }\n\n            if (o.selection.mode == \"x\") {\n                selection.first.y = 0;\n                selection.second.y = plot.height();\n            }\n            else {\n                range = extractRange(ranges, \"y\");\n\n                selection.first.y = range.axis.p2c(range.from);\n                selection.second.y = range.axis.p2c(range.to);\n            }\n\n            selection.show = true;\n            plot.triggerRedrawOverlay();\n            if (!preventEvent && selectionIsSane())\n                triggerSelectedEvent();\n        }\n\n        function selectionIsSane() {\n            var minSize = plot.getOptions().selection.minSize;\n            return Math.abs(selection.second.x - selection.first.x) >= minSize &&\n                Math.abs(selection.second.y - selection.first.y) >= minSize;\n        }\n\n        plot.clearSelection = clearSelection;\n        plot.setSelection = setSelection;\n        plot.getSelection = getSelection;\n\n        plot.hooks.bindEvents.push(function(plot, eventHolder) {\n            var o = plot.getOptions();\n            if (o.selection.mode != null) {\n                eventHolder.mousemove(onMouseMove);\n                eventHolder.mousedown(onMouseDown);\n            }\n        });\n\n\n        plot.hooks.drawOverlay.push(function (plot, ctx) {\n            // draw selection\n            if (selection.show && selectionIsSane()) {\n                var plotOffset = plot.getPlotOffset();\n                var o = plot.getOptions();\n\n                ctx.save();\n                ctx.translate(plotOffset.left, plotOffset.top);\n\n                var c = $.color.parse(o.selection.color);\n\n                ctx.strokeStyle = c.scale('a', 0.8).toString();\n                ctx.lineWidth = 1;\n                ctx.lineJoin = o.selection.shape;\n                ctx.fillStyle = c.scale('a', 0.4).toString();\n\n                var x = Math.min(selection.first.x, selection.second.x) + 0.5,\n                    y = Math.min(selection.first.y, selection.second.y) + 0.5,\n                    w = Math.abs(selection.second.x - selection.first.x) - 1,\n                    h = Math.abs(selection.second.y - selection.first.y) - 1;\n\n                ctx.fillRect(x, y, w, h);\n                ctx.strokeRect(x, y, w, h);\n\n                ctx.restore();\n            }\n        });\n        \n        plot.hooks.shutdown.push(function (plot, eventHolder) {\n            eventHolder.unbind(\"mousemove\", onMouseMove);\n            eventHolder.unbind(\"mousedown\", onMouseDown);\n            \n            if (mouseUpHandler)\n                $(document).unbind(\"mouseup\", mouseUpHandler);\n        });\n\n    }\n\n    $.plot.plugins.push({\n        init: init,\n        options: {\n            selection: {\n                mode: null, // one of null, \"x\", \"y\" or \"xy\"\n                color: \"#e8cfac\",\n                shape: \"round\", // one of \"round\", \"miter\", or \"bevel\"\n                minSize: 5 // minimum number of pixels\n            }\n        },\n        name: 'selection',\n        version: '1.1'\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.stack.js",
    "content": "/* Flot plugin for stacking data sets rather than overlyaing them.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin assumes the data is sorted on x (or y if stacking horizontally).\nFor line charts, it is assumed that if a line has an undefined gap (from a\nnull point), then the line above it should have the same gap - insert zeros\ninstead of \"null\" if you want another behaviour. This also holds for the start\nand end of the chart. Note that stacking a mix of positive and negative values\nin most instances doesn't make sense (so it looks weird).\n\nTwo or more series are stacked when their \"stack\" attribute is set to the same\nkey (which can be any number or string or just \"true\"). To specify the default\nstack, you can set the stack option like this:\n\n\tseries: {\n\t\tstack: null/false, true, or a key (number/string)\n\t}\n\nYou can also specify it for a single series, like this:\n\n\t$.plot( $(\"#placeholder\"), [{\n\t\tdata: [ ... ],\n\t\tstack: true\n\t}])\n\nThe stacking order is determined by the order of the data series in the array\n(later series end up on top of the previous).\n\nInternally, the plugin modifies the datapoints in each series, adding an\noffset to the y value. For line series, extra data points are inserted through\ninterpolation. If there's a second y value, it's also adjusted (e.g for bar\ncharts or filled areas).\n\n*/\n\n(function ($) {\n    var options = {\n        series: { stack: null } // or number/string\n    };\n    \n    function init(plot) {\n        function findMatchingSeries(s, allseries) {\n            var res = null;\n            for (var i = 0; i < allseries.length; ++i) {\n                if (s == allseries[i])\n                    break;\n                \n                if (allseries[i].stack == s.stack)\n                    res = allseries[i];\n            }\n            \n            return res;\n        }\n        \n        function stackData(plot, s, datapoints) {\n            if (s.stack == null || s.stack === false)\n                return;\n\n            var other = findMatchingSeries(s, plot.getData());\n            if (!other)\n                return;\n\n            var ps = datapoints.pointsize,\n                points = datapoints.points,\n                otherps = other.datapoints.pointsize,\n                otherpoints = other.datapoints.points,\n                newpoints = [],\n                px, py, intery, qx, qy, bottom,\n                withlines = s.lines.show,\n                horizontal = s.bars.horizontal,\n                withbottom = ps > 2 && (horizontal ? datapoints.format[2].x : datapoints.format[2].y),\n                withsteps = withlines && s.lines.steps,\n                fromgap = true,\n                keyOffset = horizontal ? 1 : 0,\n                accumulateOffset = horizontal ? 0 : 1,\n                i = 0, j = 0, l, m;\n\n            while (true) {\n                if (i >= points.length)\n                    break;\n\n                l = newpoints.length;\n\n                if (points[i] == null) {\n                    // copy gaps\n                    for (m = 0; m < ps; ++m)\n                        newpoints.push(points[i + m]);\n                    i += ps;\n                }\n                else if (j >= otherpoints.length) {\n                    // for lines, we can't use the rest of the points\n                    if (!withlines) {\n                        for (m = 0; m < ps; ++m)\n                            newpoints.push(points[i + m]);\n                    }\n                    i += ps;\n                }\n                else if (otherpoints[j] == null) {\n                    // oops, got a gap\n                    for (m = 0; m < ps; ++m)\n                        newpoints.push(null);\n                    fromgap = true;\n                    j += otherps;\n                }\n                else {\n                    // cases where we actually got two points\n                    px = points[i + keyOffset];\n                    py = points[i + accumulateOffset];\n                    qx = otherpoints[j + keyOffset];\n                    qy = otherpoints[j + accumulateOffset];\n                    bottom = 0;\n\n                    if (px == qx) {\n                        for (m = 0; m < ps; ++m)\n                            newpoints.push(points[i + m]);\n\n                        newpoints[l + accumulateOffset] += qy;\n                        bottom = qy;\n                        \n                        i += ps;\n                        j += otherps;\n                    }\n                    else if (px > qx) {\n                        // we got past point below, might need to\n                        // insert interpolated extra point\n                        if (withlines && i > 0 && points[i - ps] != null) {\n                            intery = py + (points[i - ps + accumulateOffset] - py) * (qx - px) / (points[i - ps + keyOffset] - px);\n                            newpoints.push(qx);\n                            newpoints.push(intery + qy);\n                            for (m = 2; m < ps; ++m)\n                                newpoints.push(points[i + m]);\n                            bottom = qy; \n                        }\n\n                        j += otherps;\n                    }\n                    else { // px < qx\n                        if (fromgap && withlines) {\n                            // if we come from a gap, we just skip this point\n                            i += ps;\n                            continue;\n                        }\n                            \n                        for (m = 0; m < ps; ++m)\n                            newpoints.push(points[i + m]);\n                        \n                        // we might be able to interpolate a point below,\n                        // this can give us a better y\n                        if (withlines && j > 0 && otherpoints[j - otherps] != null)\n                            bottom = qy + (otherpoints[j - otherps + accumulateOffset] - qy) * (px - qx) / (otherpoints[j - otherps + keyOffset] - qx);\n\n                        newpoints[l + accumulateOffset] += bottom;\n                        \n                        i += ps;\n                    }\n\n                    fromgap = false;\n                    \n                    if (l != newpoints.length && withbottom)\n                        newpoints[l + 2] += bottom;\n                }\n\n                // maintain the line steps invariant\n                if (withsteps && l != newpoints.length && l > 0\n                    && newpoints[l] != null\n                    && newpoints[l] != newpoints[l - ps]\n                    && newpoints[l + 1] != newpoints[l - ps + 1]) {\n                    for (m = 0; m < ps; ++m)\n                        newpoints[l + ps + m] = newpoints[l + m];\n                    newpoints[l + 1] = newpoints[l - ps + 1];\n                }\n            }\n\n            datapoints.points = newpoints;\n        }\n        \n        plot.hooks.processDatapoints.push(stackData);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'stack',\n        version: '1.2'\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.symbol.js",
    "content": "/* Flot plugin that adds some extra symbols for plotting points.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe symbols are accessed as strings through the standard symbol options:\n\n\tseries: {\n\t\tpoints: {\n\t\t\tsymbol: \"square\" // or \"diamond\", \"triangle\", \"cross\"\n\t\t}\n\t}\n\n*/\n\n(function ($) {\n    function processRawData(plot, series, datapoints) {\n        // we normalize the area of each symbol so it is approximately the\n        // same as a circle of the given radius\n\n        var handlers = {\n            square: function (ctx, x, y, radius, shadow) {\n                // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2\n                var size = radius * Math.sqrt(Math.PI) / 2;\n                ctx.rect(x - size, y - size, size + size, size + size);\n            },\n            diamond: function (ctx, x, y, radius, shadow) {\n                // pi * r^2 = 2s^2  =>  s = r * sqrt(pi/2)\n                var size = radius * Math.sqrt(Math.PI / 2);\n                ctx.moveTo(x - size, y);\n                ctx.lineTo(x, y - size);\n                ctx.lineTo(x + size, y);\n                ctx.lineTo(x, y + size);\n                ctx.lineTo(x - size, y);\n            },\n            triangle: function (ctx, x, y, radius, shadow) {\n                // pi * r^2 = 1/2 * s^2 * sin (pi / 3)  =>  s = r * sqrt(2 * pi / sin(pi / 3))\n                var size = radius * Math.sqrt(2 * Math.PI / Math.sin(Math.PI / 3));\n                var height = size * Math.sin(Math.PI / 3);\n                ctx.moveTo(x - size/2, y + height/2);\n                ctx.lineTo(x + size/2, y + height/2);\n                if (!shadow) {\n                    ctx.lineTo(x, y - height/2);\n                    ctx.lineTo(x - size/2, y + height/2);\n                }\n            },\n            cross: function (ctx, x, y, radius, shadow) {\n                // pi * r^2 = (2s)^2  =>  s = r * sqrt(pi)/2\n                var size = radius * Math.sqrt(Math.PI) / 2;\n                ctx.moveTo(x - size, y - size);\n                ctx.lineTo(x + size, y + size);\n                ctx.moveTo(x - size, y + size);\n                ctx.lineTo(x + size, y - size);\n            }\n        };\n\n        var s = series.points.symbol;\n        if (handlers[s])\n            series.points.symbol = handlers[s];\n    }\n    \n    function init(plot) {\n        plot.hooks.processDatapoints.push(processRawData);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        name: 'symbols',\n        version: '1.0'\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.threshold.js",
    "content": "/* Flot plugin for thresholding data.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nThe plugin supports these options:\n\n\tseries: {\n\t\tthreshold: {\n\t\t\tbelow: number\n\t\t\tcolor: colorspec\n\t\t}\n\t}\n\nIt can also be applied to a single series, like this:\n\n\t$.plot( $(\"#placeholder\"), [{\n\t\tdata: [ ... ],\n\t\tthreshold: { ... }\n\t}])\n\nAn array can be passed for multiple thresholding, like this:\n\n\tthreshold: [{\n\t\tbelow: number1\n\t\tcolor: color1\n\t},{\n\t\tbelow: number2\n\t\tcolor: color2\n\t}]\n\nThese multiple threshold objects can be passed in any order since they are\nsorted by the processing function.\n\nThe data points below \"below\" are drawn with the specified color. This makes\nit easy to mark points below 0, e.g. for budget data.\n\nInternally, the plugin works by splitting the data into two series, above and\nbelow the threshold. The extra series below the threshold will have its label\ncleared and the special \"originSeries\" attribute set to the original series.\nYou may need to check for this in hover events.\n\n*/\n\n(function ($) {\n    var options = {\n        series: { threshold: null } // or { below: number, color: color spec}\n    };\n    \n    function init(plot) {\n        function thresholdData(plot, s, datapoints, below, color) {\n            var ps = datapoints.pointsize, i, x, y, p, prevp,\n                thresholded = $.extend({}, s); // note: shallow copy\n\n            thresholded.datapoints = { points: [], pointsize: ps, format: datapoints.format };\n            thresholded.label = null;\n            thresholded.color = color;\n            thresholded.threshold = null;\n            thresholded.originSeries = s;\n            thresholded.data = [];\n \n            var origpoints = datapoints.points,\n                addCrossingPoints = s.lines.show;\n\n            var threspoints = [];\n            var newpoints = [];\n            var m;\n\n            for (i = 0; i < origpoints.length; i += ps) {\n                x = origpoints[i];\n                y = origpoints[i + 1];\n\n                prevp = p;\n                if (y < below)\n                    p = threspoints;\n                else\n                    p = newpoints;\n\n                if (addCrossingPoints && prevp != p && x != null\n                    && i > 0 && origpoints[i - ps] != null) {\n                    var interx = x + (below - y) * (x - origpoints[i - ps]) / (y - origpoints[i - ps + 1]);\n                    prevp.push(interx);\n                    prevp.push(below);\n                    for (m = 2; m < ps; ++m)\n                        prevp.push(origpoints[i + m]);\n                    \n                    p.push(null); // start new segment\n                    p.push(null);\n                    for (m = 2; m < ps; ++m)\n                        p.push(origpoints[i + m]);\n                    p.push(interx);\n                    p.push(below);\n                    for (m = 2; m < ps; ++m)\n                        p.push(origpoints[i + m]);\n                }\n\n                p.push(x);\n                p.push(y);\n                for (m = 2; m < ps; ++m)\n                    p.push(origpoints[i + m]);\n            }\n\n            datapoints.points = newpoints;\n            thresholded.datapoints.points = threspoints;\n            \n            if (thresholded.datapoints.points.length > 0) {\n                var origIndex = $.inArray(s, plot.getData());\n                // Insert newly-generated series right after original one (to prevent it from becoming top-most)\n                plot.getData().splice(origIndex + 1, 0, thresholded);\n            }\n                \n            // FIXME: there are probably some edge cases left in bars\n        }\n        \n        function processThresholds(plot, s, datapoints) {\n            if (!s.threshold)\n                return;\n            \n            if (s.threshold instanceof Array) {\n                s.threshold.sort(function(a, b) {\n                    return a.below - b.below;\n                });\n                \n                $(s.threshold).each(function(i, th) {\n                    thresholdData(plot, s, datapoints, th.below, th.color);\n                });\n            }\n            else {\n                thresholdData(plot, s, datapoints, s.threshold.below, s.threshold.color);\n            }\n        }\n        \n        plot.hooks.processDatapoints.push(processThresholds);\n    }\n    \n    $.plot.plugins.push({\n        init: init,\n        options: options,\n        name: 'threshold',\n        version: '1.2'\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/flot/jquery.flot.time.js",
    "content": "/* Pretty handling of time axes.\n\nCopyright (c) 2007-2013 IOLA and Ole Laursen.\nLicensed under the MIT license.\n\nSet axis.mode to \"time\" to enable. See the section \"Time series data\" in\nAPI.txt for details.\n\n*/\n\n(function($) {\n\n\tvar options = {\n\t\txaxis: {\n\t\t\ttimezone: null,\t\t// \"browser\" for local to the client or timezone for timezone-js\n\t\t\ttimeformat: null,\t// format string to use\n\t\t\ttwelveHourClock: false,\t// 12 or 24 time in time mode\n\t\t\tmonthNames: null\t// list of names of months\n\t\t}\n\t};\n\n\t// round to nearby lower multiple of base\n\n\tfunction floorInBase(n, base) {\n\t\treturn base * Math.floor(n / base);\n\t}\n\n\t// Returns a string with the date d formatted according to fmt.\n\t// A subset of the Open Group's strftime format is supported.\n\n\tfunction formatDate(d, fmt, monthNames, dayNames) {\n\n\t\tif (typeof d.strftime == \"function\") {\n\t\t\treturn d.strftime(fmt);\n\t\t}\n\n\t\tvar leftPad = function(n, pad) {\n\t\t\tn = \"\" + n;\n\t\t\tpad = \"\" + (pad == null ? \"0\" : pad);\n\t\t\treturn n.length == 1 ? pad + n : n;\n\t\t};\n\n\t\tvar r = [];\n\t\tvar escape = false;\n\t\tvar hours = d.getHours();\n\t\tvar isAM = hours < 12;\n\n\t\tif (monthNames == null) {\n\t\t\tmonthNames = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"];\n\t\t}\n\n\t\tif (dayNames == null) {\n\t\t\tdayNames = [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"];\n\t\t}\n\n\t\tvar hours12;\n\n\t\tif (hours > 12) {\n\t\t\thours12 = hours - 12;\n\t\t} else if (hours == 0) {\n\t\t\thours12 = 12;\n\t\t} else {\n\t\t\thours12 = hours;\n\t\t}\n\n\t\tfor (var i = 0; i < fmt.length; ++i) {\n\n\t\t\tvar c = fmt.charAt(i);\n\n\t\t\tif (escape) {\n\t\t\t\tswitch (c) {\n\t\t\t\t\tcase 'a': c = \"\" + dayNames[d.getDay()]; break;\n\t\t\t\t\tcase 'b': c = \"\" + monthNames[d.getMonth()]; break;\n\t\t\t\t\tcase 'd': c = leftPad(d.getDate()); break;\n\t\t\t\t\tcase 'e': c = leftPad(d.getDate(), \" \"); break;\n\t\t\t\t\tcase 'h':\t// For back-compat with 0.7; remove in 1.0\n\t\t\t\t\tcase 'H': c = leftPad(hours); break;\n\t\t\t\t\tcase 'I': c = leftPad(hours12); break;\n\t\t\t\t\tcase 'l': c = leftPad(hours12, \" \"); break;\n\t\t\t\t\tcase 'm': c = leftPad(d.getMonth() + 1); break;\n\t\t\t\t\tcase 'M': c = leftPad(d.getMinutes()); break;\n\t\t\t\t\t// quarters not in Open Group's strftime specification\n\t\t\t\t\tcase 'q':\n\t\t\t\t\t\tc = \"\" + (Math.floor(d.getMonth() / 3) + 1); break;\n\t\t\t\t\tcase 'S': c = leftPad(d.getSeconds()); break;\n\t\t\t\t\tcase 'y': c = leftPad(d.getFullYear() % 100); break;\n\t\t\t\t\tcase 'Y': c = \"\" + d.getFullYear(); break;\n\t\t\t\t\tcase 'p': c = (isAM) ? (\"\" + \"am\") : (\"\" + \"pm\"); break;\n\t\t\t\t\tcase 'P': c = (isAM) ? (\"\" + \"AM\") : (\"\" + \"PM\"); break;\n\t\t\t\t\tcase 'w': c = \"\" + d.getDay(); break;\n\t\t\t\t}\n\t\t\t\tr.push(c);\n\t\t\t\tescape = false;\n\t\t\t} else {\n\t\t\t\tif (c == \"%\") {\n\t\t\t\t\tescape = true;\n\t\t\t\t} else {\n\t\t\t\t\tr.push(c);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn r.join(\"\");\n\t}\n\n\t// To have a consistent view of time-based data independent of which time\n\t// zone the client happens to be in we need a date-like object independent\n\t// of time zones.  This is done through a wrapper that only calls the UTC\n\t// versions of the accessor methods.\n\n\tfunction makeUtcWrapper(d) {\n\n\t\tfunction addProxyMethod(sourceObj, sourceMethod, targetObj, targetMethod) {\n\t\t\tsourceObj[sourceMethod] = function() {\n\t\t\t\treturn targetObj[targetMethod].apply(targetObj, arguments);\n\t\t\t};\n        }\n        var utc = {\n\t\t\tdate: d\n\t\t};\n\n\t\t// support strftime, if found\n\n\t\tif (d.strftime != undefined) {\n\t\t\taddProxyMethod(utc, \"strftime\", d, \"strftime\");\n\t\t}\n\n\t\taddProxyMethod(utc, \"getTime\", d, \"getTime\");\n\t\taddProxyMethod(utc, \"setTime\", d, \"setTime\");\n\n\t\tvar props = [\"Date\", \"Day\", \"FullYear\", \"Hours\", \"Milliseconds\", \"Minutes\", \"Month\", \"Seconds\"];\n\n\t\tfor (var p = 0; p < props.length; p++) {\n\t\t\taddProxyMethod(utc, \"get\" + props[p], d, \"getUTC\" + props[p]);\n\t\t\taddProxyMethod(utc, \"set\" + props[p], d, \"setUTC\" + props[p]);\n\t\t}\n\n\t\treturn utc;\n    }\n    // select time zone strategy.  This returns a date-like object tied to the\n\t// desired timezone\n\n\tfunction dateGenerator(ts, opts) {\n\t\tif (opts.timezone == \"browser\") {\n\t\t\treturn new Date(ts);\n\t\t} else if (!opts.timezone || opts.timezone == \"utc\") {\n\t\t\treturn makeUtcWrapper(new Date(ts));\n\t\t} else if (typeof timezoneJS != \"undefined\" && typeof timezoneJS.Date != \"undefined\") {\n\t\t\tvar d = new timezoneJS.Date();\n\t\t\t// timezone-js is fickle, so be sure to set the time zone before\n\t\t\t// setting the time.\n\t\t\td.setTimezone(opts.timezone);\n\t\t\td.setTime(ts);\n\t\t\treturn d;\n\t\t} else {\n\t\t\treturn makeUtcWrapper(new Date(ts));\n\t\t}\n\t}\n\t\n\t// map of app. size of time units in milliseconds\n\n\tvar timeUnitSize = {\n\t\t\"second\": 1000,\n\t\t\"minute\": 60 * 1000,\n\t\t\"hour\": 60 * 60 * 1000,\n\t\t\"day\": 24 * 60 * 60 * 1000,\n\t\t\"month\": 30 * 24 * 60 * 60 * 1000,\n\t\t\"quarter\": 3 * 30 * 24 * 60 * 60 * 1000,\n\t\t\"year\": 365.2425 * 24 * 60 * 60 * 1000\n\t};\n\n\t// the allowed tick sizes, after 1 year we use\n\t// an integer algorithm\n\n\tvar baseSpec = [\n\t\t[1, \"second\"], [2, \"second\"], [5, \"second\"], [10, \"second\"],\n\t\t[30, \"second\"], \n\t\t[1, \"minute\"], [2, \"minute\"], [5, \"minute\"], [10, \"minute\"],\n\t\t[30, \"minute\"], \n\t\t[1, \"hour\"], [2, \"hour\"], [4, \"hour\"],\n\t\t[8, \"hour\"], [12, \"hour\"],\n\t\t[1, \"day\"], [2, \"day\"], [3, \"day\"],\n\t\t[0.25, \"month\"], [0.5, \"month\"], [1, \"month\"],\n\t\t[2, \"month\"]\n\t];\n\n\t// we don't know which variant(s) we'll need yet, but generating both is\n\t// cheap\n\n\tvar specMonths = baseSpec.concat([[3, \"month\"], [6, \"month\"],\n\t\t[1, \"year\"]]);\n\tvar specQuarters = baseSpec.concat([[1, \"quarter\"], [2, \"quarter\"],\n\t\t[1, \"year\"]]);\n\n\tfunction init(plot) {\n\t\tplot.hooks.processOptions.push(function (plot, options) {\n\t\t\t$.each(plot.getAxes(), function(axisName, axis) {\n\n\t\t\t\tvar opts = axis.options;\n\n\t\t\t\tif (opts.mode == \"time\") {\n\t\t\t\t\taxis.tickGenerator = function(axis) {\n\n\t\t\t\t\t\tvar ticks = [];\n\t\t\t\t\t\tvar d = dateGenerator(axis.min, opts);\n\t\t\t\t\t\tvar minSize = 0;\n\n\t\t\t\t\t\t// make quarter use a possibility if quarters are\n\t\t\t\t\t\t// mentioned in either of these options\n\n\t\t\t\t\t\tvar spec = (opts.tickSize && opts.tickSize[1] ===\n\t\t\t\t\t\t\t\"quarter\") ||\n\t\t\t\t\t\t\t(opts.minTickSize && opts.minTickSize[1] ===\n\t\t\t\t\t\t\t\"quarter\") ? specQuarters : specMonths;\n\n\t\t\t\t\t\tif (opts.minTickSize != null) {\n\t\t\t\t\t\t\tif (typeof opts.tickSize == \"number\") {\n\t\t\t\t\t\t\t\tminSize = opts.tickSize;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tminSize = opts.minTickSize[0] * timeUnitSize[opts.minTickSize[1]];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tfor (var i = 0; i < spec.length - 1; ++i) {\n\t\t\t\t\t\t\tif (axis.delta < (spec[i][0] * timeUnitSize[spec[i][1]]\n\t\t\t\t\t\t\t\t\t\t\t  + spec[i + 1][0] * timeUnitSize[spec[i + 1][1]]) / 2\n\t\t\t\t\t\t\t\t&& spec[i][0] * timeUnitSize[spec[i][1]] >= minSize) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar size = spec[i][0];\n\t\t\t\t\t\tvar unit = spec[i][1];\n\n\t\t\t\t\t\t// special-case the possibility of several years\n\n\t\t\t\t\t\tif (unit == \"year\") {\n\n\t\t\t\t\t\t\t// if given a minTickSize in years, just use it,\n\t\t\t\t\t\t\t// ensuring that it's an integer\n\n\t\t\t\t\t\t\tif (opts.minTickSize != null && opts.minTickSize[1] == \"year\") {\n\t\t\t\t\t\t\t\tsize = Math.floor(opts.minTickSize[0]);\n\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\tvar magn = Math.pow(10, Math.floor(Math.log(axis.delta / timeUnitSize.year) / Math.LN10));\n\t\t\t\t\t\t\t\tvar norm = (axis.delta / timeUnitSize.year) / magn;\n\n\t\t\t\t\t\t\t\tif (norm < 1.5) {\n\t\t\t\t\t\t\t\t\tsize = 1;\n\t\t\t\t\t\t\t\t} else if (norm < 3) {\n\t\t\t\t\t\t\t\t\tsize = 2;\n\t\t\t\t\t\t\t\t} else if (norm < 7.5) {\n\t\t\t\t\t\t\t\t\tsize = 5;\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tsize = 10;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tsize *= magn;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// minimum size for years is 1\n\n\t\t\t\t\t\t\tif (size < 1) {\n\t\t\t\t\t\t\t\tsize = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\taxis.tickSize = opts.tickSize || [size, unit];\n\t\t\t\t\t\tvar tickSize = axis.tickSize[0];\n\t\t\t\t\t\tunit = axis.tickSize[1];\n\n\t\t\t\t\t\tvar step = tickSize * timeUnitSize[unit];\n\n\t\t\t\t\t\tif (unit == \"second\") {\n\t\t\t\t\t\t\td.setSeconds(floorInBase(d.getSeconds(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"minute\") {\n\t\t\t\t\t\t\td.setMinutes(floorInBase(d.getMinutes(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"hour\") {\n\t\t\t\t\t\t\td.setHours(floorInBase(d.getHours(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"month\") {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), tickSize));\n\t\t\t\t\t\t} else if (unit == \"quarter\") {\n\t\t\t\t\t\t\td.setMonth(3 * floorInBase(d.getMonth() / 3,\n\t\t\t\t\t\t\t\ttickSize));\n\t\t\t\t\t\t} else if (unit == \"year\") {\n\t\t\t\t\t\t\td.setFullYear(floorInBase(d.getFullYear(), tickSize));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// reset smaller components\n\n\t\t\t\t\t\td.setMilliseconds(0);\n\n\t\t\t\t\t\tif (step >= timeUnitSize.minute) {\n\t\t\t\t\t\t\td.setSeconds(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.hour) {\n\t\t\t\t\t\t\td.setMinutes(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.day) {\n\t\t\t\t\t\t\td.setHours(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.day * 4) {\n\t\t\t\t\t\t\td.setDate(1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.month * 2) {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), 3));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.quarter * 2) {\n\t\t\t\t\t\t\td.setMonth(floorInBase(d.getMonth(), 6));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (step >= timeUnitSize.year) {\n\t\t\t\t\t\t\td.setMonth(0);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar carry = 0;\n\t\t\t\t\t\tvar v = Number.NaN;\n\t\t\t\t\t\tvar prev;\n\n\t\t\t\t\t\tdo {\n\n\t\t\t\t\t\t\tprev = v;\n\t\t\t\t\t\t\tv = d.getTime();\n\t\t\t\t\t\t\tticks.push(v);\n\n\t\t\t\t\t\t\tif (unit == \"month\" || unit == \"quarter\") {\n\t\t\t\t\t\t\t\tif (tickSize < 1) {\n\n\t\t\t\t\t\t\t\t\t// a bit complicated - we'll divide the\n\t\t\t\t\t\t\t\t\t// month/quarter up but we need to take\n\t\t\t\t\t\t\t\t\t// care of fractions so we don't end up in\n\t\t\t\t\t\t\t\t\t// the middle of a day\n\n\t\t\t\t\t\t\t\t\td.setDate(1);\n\t\t\t\t\t\t\t\t\tvar start = d.getTime();\n\t\t\t\t\t\t\t\t\td.setMonth(d.getMonth() +\n\t\t\t\t\t\t\t\t\t\t(unit == \"quarter\" ? 3 : 1));\n\t\t\t\t\t\t\t\t\tvar end = d.getTime();\n\t\t\t\t\t\t\t\t\td.setTime(v + carry * timeUnitSize.hour + (end - start) * tickSize);\n\t\t\t\t\t\t\t\t\tcarry = d.getHours();\n\t\t\t\t\t\t\t\t\td.setHours(0);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\td.setMonth(d.getMonth() +\n\t\t\t\t\t\t\t\t\t\ttickSize * (unit == \"quarter\" ? 3 : 1));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if (unit == \"year\") {\n\t\t\t\t\t\t\t\td.setFullYear(d.getFullYear() + tickSize);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\td.setTime(v + step);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} while (v < axis.max && v != prev);\n\n\t\t\t\t\t\treturn ticks;\n\t\t\t\t\t};\n\n\t\t\t\t\taxis.tickFormatter = function (v, axis) {\n\n\t\t\t\t\t\tvar d = dateGenerator(v, axis.options);\n\n\t\t\t\t\t\t// first check global format\n\n\t\t\t\t\t\tif (opts.timeformat != null) {\n\t\t\t\t\t\t\treturn formatDate(d, opts.timeformat, opts.monthNames, opts.dayNames);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// possibly use quarters if quarters are mentioned in\n\t\t\t\t\t\t// any of these places\n\n\t\t\t\t\t\tvar useQuarters = (axis.options.tickSize &&\n\t\t\t\t\t\t\t\taxis.options.tickSize[1] == \"quarter\") ||\n\t\t\t\t\t\t\t(axis.options.minTickSize &&\n\t\t\t\t\t\t\t\taxis.options.minTickSize[1] == \"quarter\");\n\n\t\t\t\t\t\tvar t = axis.tickSize[0] * timeUnitSize[axis.tickSize[1]];\n\t\t\t\t\t\tvar span = axis.max - axis.min;\n\t\t\t\t\t\tvar suffix = (opts.twelveHourClock) ? \" %p\" : \"\";\n\t\t\t\t\t\tvar hourCode = (opts.twelveHourClock) ? \"%I\" : \"%H\";\n\t\t\t\t\t\tvar fmt;\n\n\t\t\t\t\t\tif (t < timeUnitSize.minute) {\n\t\t\t\t\t\t\tfmt = hourCode + \":%M:%S\" + suffix;\n\t\t\t\t\t\t} else if (t < timeUnitSize.day) {\n\t\t\t\t\t\t\tif (span < 2 * timeUnitSize.day) {\n\t\t\t\t\t\t\t\tfmt = hourCode + \":%M\" + suffix;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"%b %d \" + hourCode + \":%M\" + suffix;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (t < timeUnitSize.month) {\n\t\t\t\t\t\t\tfmt = \"%b %d\";\n\t\t\t\t\t\t} else if ((useQuarters && t < timeUnitSize.quarter) ||\n\t\t\t\t\t\t\t(!useQuarters && t < timeUnitSize.year)) {\n\t\t\t\t\t\t\tif (span < timeUnitSize.year) {\n\t\t\t\t\t\t\t\tfmt = \"%b\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"%b %Y\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if (useQuarters && t < timeUnitSize.year) {\n\t\t\t\t\t\t\tif (span < timeUnitSize.year) {\n\t\t\t\t\t\t\t\tfmt = \"Q%q\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tfmt = \"Q%q %Y\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tfmt = \"%Y\";\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvar rt = formatDate(d, fmt, opts.monthNames, opts.dayNames);\n\n\t\t\t\t\t\treturn rt;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t$.plot.plugins.push({\n\t\tinit: init,\n\t\toptions: options,\n\t\tname: 'time',\n\t\tversion: '1.0'\n\t});\n\n\t// Time-axis support used to be in Flot core, which exposed the\n\t// formatDate function on the plot object.  Various plugins depend\n\t// on the function, so we need to re-expose it here.\n\n\t$.plot.formatDate = formatDate;\n\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/form/jquery.form.js",
    "content": "/*!\n * jQuery Form Plugin\n * version: 3.51.0-2014.06.20\n * Requires jQuery v1.5 or later\n * Copyright (c) 2014 M. Alsup\n * Examples and documentation at: http://malsup.com/jquery/form/\n * Project repository: https://github.com/malsup/form\n * Dual licensed under the MIT and GPL licenses.\n * https://github.com/malsup/form#copyright-and-license\n */\n/*global ActiveXObject */\n\n// AMD support\n(function (factory) {\n    \"use strict\";\n    if (typeof define === 'function' && define.amd) {\n        // using AMD; register as anon module\n        define(['jquery'], factory);\n    } else {\n        // no AMD; invoke directly\n        factory( (typeof(jQuery) != 'undefined') ? jQuery : window.Zepto );\n    }\n}\n\n(function($) {\n\"use strict\";\n\n/*\n    Usage Note:\n    -----------\n    Do not use both ajaxSubmit and ajaxForm on the same form.  These\n    functions are mutually exclusive.  Use ajaxSubmit if you want\n    to bind your own submit handler to the form.  For example,\n\n    $(document).ready(function() {\n        $('#myForm').on('submit', function(e) {\n            e.preventDefault(); // <-- important\n            $(this).ajaxSubmit({\n                target: '#output'\n            });\n        });\n    });\n\n    Use ajaxForm when you want the plugin to manage all the event binding\n    for you.  For example,\n\n    $(document).ready(function() {\n        $('#myForm').ajaxForm({\n            target: '#output'\n        });\n    });\n\n    You can also use ajaxForm with delegation (requires jQuery v1.7+), so the\n    form does not have to exist when you invoke ajaxForm:\n\n    $('#myForm').ajaxForm({\n        delegation: true,\n        target: '#output'\n    });\n\n    When using ajaxForm, the ajaxSubmit function will be invoked for you\n    at the appropriate time.\n*/\n\n/**\n * Feature detection\n */\nvar feature = {};\nfeature.fileapi = $(\"<input type='file'/>\").get(0).files !== undefined;\nfeature.formdata = window.FormData !== undefined;\n\nvar hasProp = !!$.fn.prop;\n\n// attr2 uses prop when it can but checks the return type for\n// an expected string.  this accounts for the case where a form \n// contains inputs with names like \"action\" or \"method\"; in those\n// cases \"prop\" returns the element\n$.fn.attr2 = function() {\n    if ( ! hasProp ) {\n        return this.attr.apply(this, arguments);\n    }\n    var val = this.prop.apply(this, arguments);\n    if ( ( val && val.jquery ) || typeof val === 'string' ) {\n        return val;\n    }\n    return this.attr.apply(this, arguments);\n};\n\n/**\n * ajaxSubmit() provides a mechanism for immediately submitting\n * an HTML form using AJAX.\n */\n$.fn.ajaxSubmit = function(options) {\n    /*jshint scripturl:true */\n\n    // fast fail if nothing selected (http://dev.jquery.com/ticket/2752)\n    if (!this.length) {\n        log('ajaxSubmit: skipping submit process - no element selected');\n        return this;\n    }\n\n    var method, action, url, $form = this;\n\n    if (typeof options == 'function') {\n        options = { success: options };\n    }\n    else if ( options === undefined ) {\n        options = {};\n    }\n\n    method = options.type || this.attr2('method');\n    action = options.url  || this.attr2('action');\n\n    url = (typeof action === 'string') ? $.trim(action) : '';\n    url = url || window.location.href || '';\n    if (url) {\n        // clean url (don't include hash vaue)\n        url = (url.match(/^([^#]+)/)||[])[1];\n    }\n\n    options = $.extend(true, {\n        url:  url,\n        success: $.ajaxSettings.success,\n        type: method || $.ajaxSettings.type,\n        iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank'\n    }, options);\n\n    // hook for manipulating the form data before it is extracted;\n    // convenient for use with rich editors like tinyMCE or FCKEditor\n    var veto = {};\n    this.trigger('form-pre-serialize', [this, options, veto]);\n    if (veto.veto) {\n        log('ajaxSubmit: submit vetoed via form-pre-serialize trigger');\n        return this;\n    }\n\n    // provide opportunity to alter form data before it is serialized\n    if (options.beforeSerialize && options.beforeSerialize(this, options) === false) {\n        log('ajaxSubmit: submit aborted via beforeSerialize callback');\n        return this;\n    }\n\n    var traditional = options.traditional;\n    if ( traditional === undefined ) {\n        traditional = $.ajaxSettings.traditional;\n    }\n\n    var elements = [];\n    var qx, a = this.formToArray(options.semantic, elements);\n    if (options.data) {\n        options.extraData = options.data;\n        qx = $.param(options.data, traditional);\n    }\n\n    // give pre-submit callback an opportunity to abort the submit\n    if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) {\n        log('ajaxSubmit: submit aborted via beforeSubmit callback');\n        return this;\n    }\n\n    // fire vetoable 'validate' event\n    this.trigger('form-submit-validate', [a, this, options, veto]);\n    if (veto.veto) {\n        log('ajaxSubmit: submit vetoed via form-submit-validate trigger');\n        return this;\n    }\n\n    var q = $.param(a, traditional);\n    if (qx) {\n        q = ( q ? (q + '&' + qx) : qx );\n    }\n    if (options.type.toUpperCase() == 'GET') {\n        options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q;\n        options.data = null;  // data is null for 'get'\n    }\n    else {\n        options.data = q; // data is the query string for 'post'\n    }\n\n    var callbacks = [];\n    if (options.resetForm) {\n        callbacks.push(function() { $form.resetForm(); });\n    }\n    if (options.clearForm) {\n        callbacks.push(function() { $form.clearForm(options.includeHidden); });\n    }\n\n    // perform a load on the target only if dataType is not provided\n    if (!options.dataType && options.target) {\n        var oldSuccess = options.success || function(){};\n        callbacks.push(function(data) {\n            var fn = options.replaceTarget ? 'replaceWith' : 'html';\n            $(options.target)[fn](data).each(oldSuccess, arguments);\n        });\n    }\n    else if (options.success) {\n        callbacks.push(options.success);\n    }\n\n    options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg\n        var context = options.context || this ;    // jQuery 1.4+ supports scope context\n        for (var i=0, max=callbacks.length; i < max; i++) {\n            callbacks[i].apply(context, [data, status, xhr || $form, $form]);\n        }\n    };\n\n    if (options.error) {\n        var oldError = options.error;\n        options.error = function(xhr, status, error) {\n            var context = options.context || this;\n            oldError.apply(context, [xhr, status, error, $form]);\n        };\n    }\n\n     if (options.complete) {\n        var oldComplete = options.complete;\n        options.complete = function(xhr, status) {\n            var context = options.context || this;\n            oldComplete.apply(context, [xhr, status, $form]);\n        };\n    }\n\n    // are there files to upload?\n\n    // [value] (issue #113), also see comment:\n    // https://github.com/malsup/form/commit/588306aedba1de01388032d5f42a60159eea9228#commitcomment-2180219\n    var fileInputs = $('input[type=file]:enabled', this).filter(function() { return $(this).val() !== ''; });\n\n    var hasFileInputs = fileInputs.length > 0;\n    var mp = 'multipart/form-data';\n    var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp);\n\n    var fileAPI = feature.fileapi && feature.formdata;\n    log(\"fileAPI :\" + fileAPI);\n    var shouldUseFrame = (hasFileInputs || multipart) && !fileAPI;\n\n    var jqxhr;\n\n    // options.iframe allows user to force iframe mode\n    // 06-NOV-09: now defaulting to iframe mode if file input is detected\n    if (options.iframe !== false && (options.iframe || shouldUseFrame)) {\n        // hack to fix Safari hang (thanks to Tim Molendijk for this)\n        // see:  http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d\n        if (options.closeKeepAlive) {\n            $.get(options.closeKeepAlive, function() {\n                jqxhr = fileUploadIframe(a);\n            });\n        }\n        else {\n            jqxhr = fileUploadIframe(a);\n        }\n    }\n    else if ((hasFileInputs || multipart) && fileAPI) {\n        jqxhr = fileUploadXhr(a);\n    }\n    else {\n        jqxhr = $.ajax(options);\n    }\n\n    $form.removeData('jqxhr').data('jqxhr', jqxhr);\n\n    // clear element array\n    for (var k=0; k < elements.length; k++) {\n        elements[k] = null;\n    }\n\n    // fire 'notify' event\n    this.trigger('form-submit-notify', [this, options]);\n    return this;\n\n    // utility fn for deep serialization\n    function deepSerialize(extraData){\n        var serialized = $.param(extraData, options.traditional).split('&');\n        var len = serialized.length;\n        var result = [];\n        var i, part;\n        for (i=0; i < len; i++) {\n            // #252; undo param space replacement\n            serialized[i] = serialized[i].replace(/\\+/g,' ');\n            part = serialized[i].split('=');\n            // #278; use array instead of object storage, favoring array serializations\n            result.push([decodeURIComponent(part[0]), decodeURIComponent(part[1])]);\n        }\n        return result;\n    }\n\n     // XMLHttpRequest Level 2 file uploads (big hat tip to francois2metz)\n    function fileUploadXhr(a) {\n        var formdata = new FormData();\n\n        for (var i=0; i < a.length; i++) {\n            formdata.append(a[i].name, a[i].value);\n        }\n\n        if (options.extraData) {\n            var serializedData = deepSerialize(options.extraData);\n            for (i=0; i < serializedData.length; i++) {\n                if (serializedData[i]) {\n                    formdata.append(serializedData[i][0], serializedData[i][1]);\n                }\n            }\n        }\n\n        options.data = null;\n\n        var s = $.extend(true, {}, $.ajaxSettings, options, {\n            contentType: false,\n            processData: false,\n            cache: false,\n            type: method || 'POST'\n        });\n\n        if (options.uploadProgress) {\n            // workaround because jqXHR does not expose upload property\n            s.xhr = function() {\n                var xhr = $.ajaxSettings.xhr();\n                if (xhr.upload) {\n                    xhr.upload.addEventListener('progress', function(event) {\n                        var percent = 0;\n                        var position = event.loaded || event.position; /*event.position is deprecated*/\n                        var total = event.total;\n                        if (event.lengthComputable) {\n                            percent = Math.ceil(position / total * 100);\n                        }\n                        options.uploadProgress(event, position, total, percent);\n                    }, false);\n                }\n                return xhr;\n            };\n        }\n\n        s.data = null;\n        var beforeSend = s.beforeSend;\n        s.beforeSend = function(xhr, o) {\n            //Send FormData() provided by user\n            if (options.formData) {\n                o.data = options.formData;\n            }\n            else {\n                o.data = formdata;\n            }\n            if(beforeSend) {\n                beforeSend.call(this, xhr, o);\n            }\n        };\n        return $.ajax(s);\n    }\n\n    // private function for handling file uploads (hat tip to YAHOO!)\n    function fileUploadIframe(a) {\n        var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle;\n        var deferred = $.Deferred();\n\n        // #341\n        deferred.abort = function(status) {\n            xhr.abort(status);\n        };\n\n        if (a) {\n            // ensure that every serialized input is still enabled\n            for (i=0; i < elements.length; i++) {\n                el = $(elements[i]);\n                if ( hasProp ) {\n                    el.prop('disabled', false);\n                }\n                else {\n                    el.removeAttr('disabled');\n                }\n            }\n        }\n\n        s = $.extend(true, {}, $.ajaxSettings, options);\n        s.context = s.context || s;\n        id = 'jqFormIO' + (new Date().getTime());\n        if (s.iframeTarget) {\n            $io = $(s.iframeTarget);\n            n = $io.attr2('name');\n            if (!n) {\n                $io.attr2('name', id);\n            }\n            else {\n                id = n;\n            }\n        }\n        else {\n            $io = $('<iframe name=\"' + id + '\" src=\"'+ s.iframeSrc +'\" />');\n            $io.css({ position: 'absolute', top: '-1000px', left: '-1000px' });\n        }\n        io = $io[0];\n\n\n        xhr = { // mock object\n            aborted: 0,\n            responseText: null,\n            responseXML: null,\n            status: 0,\n            statusText: 'n/a',\n            getAllResponseHeaders: function() {},\n            getResponseHeader: function() {},\n            setRequestHeader: function() {},\n            abort: function(status) {\n                var e = (status === 'timeout' ? 'timeout' : 'aborted');\n                log('aborting upload... ' + e);\n                this.aborted = 1;\n\n                try { // #214, #257\n                    if (io.contentWindow.document.execCommand) {\n                        io.contentWindow.document.execCommand('Stop');\n                    }\n                }\n                catch(ignore) {}\n\n                $io.attr('src', s.iframeSrc); // abort op in progress\n                xhr.error = e;\n                if (s.error) {\n                    s.error.call(s.context, xhr, e, status);\n                }\n                if (g) {\n                    $.event.trigger(\"ajaxError\", [xhr, s, e]);\n                }\n                if (s.complete) {\n                    s.complete.call(s.context, xhr, e);\n                }\n            }\n        };\n\n        g = s.global;\n        // trigger ajax global events so that activity/block indicators work like normal\n        if (g && 0 === $.active++) {\n            $.event.trigger(\"ajaxStart\");\n        }\n        if (g) {\n            $.event.trigger(\"ajaxSend\", [xhr, s]);\n        }\n\n        if (s.beforeSend && s.beforeSend.call(s.context, xhr, s) === false) {\n            if (s.global) {\n                $.active--;\n            }\n            deferred.reject();\n            return deferred;\n        }\n        if (xhr.aborted) {\n            deferred.reject();\n            return deferred;\n        }\n\n        // add submitting element to data if we know it\n        sub = form.clk;\n        if (sub) {\n            n = sub.name;\n            if (n && !sub.disabled) {\n                s.extraData = s.extraData || {};\n                s.extraData[n] = sub.value;\n                if (sub.type == \"image\") {\n                    s.extraData[n+'.x'] = form.clk_x;\n                    s.extraData[n+'.y'] = form.clk_y;\n                }\n            }\n        }\n\n        var CLIENT_TIMEOUT_ABORT = 1;\n        var SERVER_ABORT = 2;\n                \n        function getDoc(frame) {\n            /* it looks like contentWindow or contentDocument do not\n             * carry the protocol property in ie8, when running under ssl\n             * frame.document is the only valid response document, since\n             * the protocol is know but not on the other two objects. strange?\n             * \"Same origin policy\" http://en.wikipedia.org/wiki/Same_origin_policy\n             */\n            \n            var doc = null;\n            \n            // IE8 cascading access check\n            try {\n                if (frame.contentWindow) {\n                    doc = frame.contentWindow.document;\n                }\n            } catch(err) {\n                // IE8 access denied under ssl & missing protocol\n                log('cannot get iframe.contentWindow document: ' + err);\n            }\n\n            if (doc) { // successful getting content\n                return doc;\n            }\n\n            try { // simply checking may throw in ie8 under ssl or mismatched protocol\n                doc = frame.contentDocument ? frame.contentDocument : frame.document;\n            } catch(err) {\n                // last attempt\n                log('cannot get iframe.contentDocument: ' + err);\n                doc = frame.document;\n            }\n            return doc;\n        }\n\n        // Rails CSRF hack (thanks to Yvan Barthelemy)\n        var csrf_token = $('meta[name=csrf-token]').attr('content');\n        var csrf_param = $('meta[name=csrf-param]').attr('content');\n        if (csrf_param && csrf_token) {\n            s.extraData = s.extraData || {};\n            s.extraData[csrf_param] = csrf_token;\n        }\n\n        // take a breath so that pending repaints get some cpu time before the upload starts\n        function doSubmit() {\n            // make sure form attrs are set\n            var t = $form.attr2('target'), \n                a = $form.attr2('action'), \n                mp = 'multipart/form-data',\n                et = $form.attr('enctype') || $form.attr('encoding') || mp;\n\n            // update form attrs in IE friendly way\n            form.setAttribute('target',id);\n            if (!method || /post/i.test(method) ) {\n                form.setAttribute('method', 'POST');\n            }\n            if (a != s.url) {\n                form.setAttribute('action', s.url);\n            }\n\n            // ie borks in some cases when setting encoding\n            if (! s.skipEncodingOverride && (!method || /post/i.test(method))) {\n                $form.attr({\n                    encoding: 'multipart/form-data',\n                    enctype:  'multipart/form-data'\n                });\n            }\n\n            // support timout\n            if (s.timeout) {\n                timeoutHandle = setTimeout(function() { timedOut = true; cb(CLIENT_TIMEOUT_ABORT); }, s.timeout);\n            }\n\n            // look for server aborts\n            function checkState() {\n                try {\n                    var state = getDoc(io).readyState;\n                    log('state = ' + state);\n                    if (state && state.toLowerCase() == 'uninitialized') {\n                        setTimeout(checkState,50);\n                    }\n                }\n                catch(e) {\n                    log('Server abort: ' , e, ' (', e.name, ')');\n                    cb(SERVER_ABORT);\n                    if (timeoutHandle) {\n                        clearTimeout(timeoutHandle);\n                    }\n                    timeoutHandle = undefined;\n                }\n            }\n\n            // add \"extra\" data to form if provided in options\n            var extraInputs = [];\n            try {\n                if (s.extraData) {\n                    for (var n in s.extraData) {\n                        if (s.extraData.hasOwnProperty(n)) {\n                           // if using the $.param format that allows for multiple values with the same name\n                           if($.isPlainObject(s.extraData[n]) && s.extraData[n].hasOwnProperty('name') && s.extraData[n].hasOwnProperty('value')) {\n                               extraInputs.push(\n                               $('<input type=\"hidden\" name=\"'+s.extraData[n].name+'\">').val(s.extraData[n].value)\n                                   .appendTo(form)[0]);\n                           } else {\n                               extraInputs.push(\n                               $('<input type=\"hidden\" name=\"'+n+'\">').val(s.extraData[n])\n                                   .appendTo(form)[0]);\n                           }\n                        }\n                    }\n                }\n\n                if (!s.iframeTarget) {\n                    // add iframe to doc and submit the form\n                    $io.appendTo('body');\n                }\n                if (io.attachEvent) {\n                    io.attachEvent('onload', cb);\n                }\n                else {\n                    io.addEventListener('load', cb, false);\n                }\n                setTimeout(checkState,15);\n\n                try {\n                    form.submit();\n                } catch(err) {\n                    // just in case form has element with name/id of 'submit'\n                    var submitFn = document.createElement('form').submit;\n                    submitFn.apply(form);\n                }\n            }\n            finally {\n                // reset attrs and remove \"extra\" input elements\n                form.setAttribute('action',a);\n                form.setAttribute('enctype', et); // #380\n                if(t) {\n                    form.setAttribute('target', t);\n                } else {\n                    $form.removeAttr('target');\n                }\n                $(extraInputs).remove();\n            }\n        }\n\n        if (s.forceSync) {\n            doSubmit();\n        }\n        else {\n            setTimeout(doSubmit, 10); // this lets dom updates render\n        }\n\n        var data, doc, domCheckCount = 50, callbackProcessed;\n\n        function cb(e) {\n            if (xhr.aborted || callbackProcessed) {\n                return;\n            }\n            \n            doc = getDoc(io);\n            if(!doc) {\n                log('cannot access response document');\n                e = SERVER_ABORT;\n            }\n            if (e === CLIENT_TIMEOUT_ABORT && xhr) {\n                xhr.abort('timeout');\n                deferred.reject(xhr, 'timeout');\n                return;\n            }\n            else if (e == SERVER_ABORT && xhr) {\n                xhr.abort('server abort');\n                deferred.reject(xhr, 'error', 'server abort');\n                return;\n            }\n\n            if (!doc || doc.location.href == s.iframeSrc) {\n                // response not received yet\n                if (!timedOut) {\n                    return;\n                }\n            }\n            if (io.detachEvent) {\n                io.detachEvent('onload', cb);\n            }\n            else {\n                io.removeEventListener('load', cb, false);\n            }\n\n            var status = 'success', errMsg;\n            try {\n                if (timedOut) {\n                    throw 'timeout';\n                }\n\n                var isXml = s.dataType == 'xml' || doc.XMLDocument || $.isXMLDoc(doc);\n                log('isXml='+isXml);\n                if (!isXml && window.opera && (doc.body === null || !doc.body.innerHTML)) {\n                    if (--domCheckCount) {\n                        // in some browsers (Opera) the iframe DOM is not always traversable when\n                        // the onload callback fires, so we loop a bit to accommodate\n                        log('requeing onLoad callback, DOM not available');\n                        setTimeout(cb, 250);\n                        return;\n                    }\n                    // let this fall through because server response could be an empty document\n                    //log('Could not access iframe DOM after mutiple tries.');\n                    //throw 'DOMException: not available';\n                }\n\n                //log('response detected');\n                var docRoot = doc.body ? doc.body : doc.documentElement;\n                xhr.responseText = docRoot ? docRoot.innerHTML : null;\n                xhr.responseXML = doc.XMLDocument ? doc.XMLDocument : doc;\n                if (isXml) {\n                    s.dataType = 'xml';\n                }\n                xhr.getResponseHeader = function(header){\n                    var headers = {'content-type': s.dataType};\n                    return headers[header.toLowerCase()];\n                };\n                // support for XHR 'status' & 'statusText' emulation :\n                if (docRoot) {\n                    xhr.status = Number( docRoot.getAttribute('status') ) || xhr.status;\n                    xhr.statusText = docRoot.getAttribute('statusText') || xhr.statusText;\n                }\n\n                var dt = (s.dataType || '').toLowerCase();\n                var scr = /(json|script|text)/.test(dt);\n                if (scr || s.textarea) {\n                    // see if user embedded response in textarea\n                    var ta = doc.getElementsByTagName('textarea')[0];\n                    if (ta) {\n                        xhr.responseText = ta.value;\n                        // support for XHR 'status' & 'statusText' emulation :\n                        xhr.status = Number( ta.getAttribute('status') ) || xhr.status;\n                        xhr.statusText = ta.getAttribute('statusText') || xhr.statusText;\n                    }\n                    else if (scr) {\n                        // account for browsers injecting pre around json response\n                        var pre = doc.getElementsByTagName('pre')[0];\n                        var b = doc.getElementsByTagName('body')[0];\n                        if (pre) {\n                            xhr.responseText = pre.textContent ? pre.textContent : pre.innerText;\n                        }\n                        else if (b) {\n                            xhr.responseText = b.textContent ? b.textContent : b.innerText;\n                        }\n                    }\n                }\n                else if (dt == 'xml' && !xhr.responseXML && xhr.responseText) {\n                    xhr.responseXML = toXml(xhr.responseText);\n                }\n\n                try {\n                    data = httpData(xhr, dt, s);\n                }\n                catch (err) {\n                    status = 'parsererror';\n                    xhr.error = errMsg = (err || status);\n                }\n            }\n            catch (err) {\n                log('error caught: ',err);\n                status = 'error';\n                xhr.error = errMsg = (err || status);\n            }\n\n            if (xhr.aborted) {\n                log('upload aborted');\n                status = null;\n            }\n\n            if (xhr.status) { // we've set xhr.status\n                status = (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) ? 'success' : 'error';\n            }\n\n            // ordering of these callbacks/triggers is odd, but that's how $.ajax does it\n            if (status === 'success') {\n                if (s.success) {\n                    s.success.call(s.context, data, 'success', xhr);\n                }\n                deferred.resolve(xhr.responseText, 'success', xhr);\n                if (g) {\n                    $.event.trigger(\"ajaxSuccess\", [xhr, s]);\n                }\n            }\n            else if (status) {\n                if (errMsg === undefined) {\n                    errMsg = xhr.statusText;\n                }\n                if (s.error) {\n                    s.error.call(s.context, xhr, status, errMsg);\n                }\n                deferred.reject(xhr, 'error', errMsg);\n                if (g) {\n                    $.event.trigger(\"ajaxError\", [xhr, s, errMsg]);\n                }\n            }\n\n            if (g) {\n                $.event.trigger(\"ajaxComplete\", [xhr, s]);\n            }\n\n            if (g && ! --$.active) {\n                $.event.trigger(\"ajaxStop\");\n            }\n\n            if (s.complete) {\n                s.complete.call(s.context, xhr, status);\n            }\n\n            callbackProcessed = true;\n            if (s.timeout) {\n                clearTimeout(timeoutHandle);\n            }\n\n            // clean up\n            setTimeout(function() {\n                if (!s.iframeTarget) {\n                    $io.remove();\n                }\n                else { //adding else to clean up existing iframe response.\n                    $io.attr('src', s.iframeSrc);\n                }\n                xhr.responseXML = null;\n            }, 100);\n        }\n\n        var toXml = $.parseXML || function(s, doc) { // use parseXML if available (jQuery 1.5+)\n            if (window.ActiveXObject) {\n                doc = new ActiveXObject('Microsoft.XMLDOM');\n                doc.async = 'false';\n                doc.loadXML(s);\n            }\n            else {\n                doc = (new DOMParser()).parseFromString(s, 'text/xml');\n            }\n            return (doc && doc.documentElement && doc.documentElement.nodeName != 'parsererror') ? doc : null;\n        };\n        var parseJSON = $.parseJSON || function(s) {\n            /*jslint evil:true */\n            return window['eval']('(' + s + ')');\n        };\n\n        var httpData = function( xhr, type, s ) { // mostly lifted from jq1.4.4\n\n            var ct = xhr.getResponseHeader('content-type') || '',\n                xml = type === 'xml' || !type && ct.indexOf('xml') >= 0,\n                data = xml ? xhr.responseXML : xhr.responseText;\n\n            if (xml && data.documentElement.nodeName === 'parsererror') {\n                if ($.error) {\n                    $.error('parsererror');\n                }\n            }\n            if (s && s.dataFilter) {\n                data = s.dataFilter(data, type);\n            }\n            if (typeof data === 'string') {\n                if (type === 'json' || !type && ct.indexOf('json') >= 0) {\n                    data = parseJSON(data);\n                } else if (type === \"script\" || !type && ct.indexOf(\"javascript\") >= 0) {\n                    $.globalEval(data);\n                }\n            }\n            return data;\n        };\n\n        return deferred;\n    }\n};\n\n/**\n * ajaxForm() provides a mechanism for fully automating form submission.\n *\n * The advantages of using this method instead of ajaxSubmit() are:\n *\n * 1: This method will include coordinates for <input type=\"image\" /> elements (if the element\n *    is used to submit the form).\n * 2. This method will include the submit element's name/value data (for the element that was\n *    used to submit the form).\n * 3. This method binds the submit() method to the form for you.\n *\n * The options argument for ajaxForm works exactly as it does for ajaxSubmit.  ajaxForm merely\n * passes the options argument along after properly binding events for submit elements and\n * the form itself.\n */\n$.fn.ajaxForm = function(options) {\n    options = options || {};\n    options.delegation = options.delegation && $.isFunction($.fn.on);\n\n    // in jQuery 1.3+ we can fix mistakes with the ready state\n    if (!options.delegation && this.length === 0) {\n        var o = { s: this.selector, c: this.context };\n        if (!$.isReady && o.s) {\n            log('DOM not ready, queuing ajaxForm');\n            $(function() {\n                $(o.s,o.c).ajaxForm(options);\n            });\n            return this;\n        }\n        // is your DOM ready?  http://docs.jquery.com/Tutorials:Introducing_$(document).ready()\n        log('terminating; zero elements found by selector' + ($.isReady ? '' : ' (DOM not ready)'));\n        return this;\n    }\n\n    if ( options.delegation ) {\n        $(document)\n            .off('submit.form-plugin', this.selector, doAjaxSubmit)\n            .off('click.form-plugin', this.selector, captureSubmittingElement)\n            .on('submit.form-plugin', this.selector, options, doAjaxSubmit)\n            .on('click.form-plugin', this.selector, options, captureSubmittingElement);\n        return this;\n    }\n\n    return this.ajaxFormUnbind()\n        .bind('submit.form-plugin', options, doAjaxSubmit)\n        .bind('click.form-plugin', options, captureSubmittingElement);\n};\n\n// private event handlers\nfunction doAjaxSubmit(e) {\n    /*jshint validthis:true */\n    var options = e.data;\n    if (!e.isDefaultPrevented()) { // if event has been canceled, don't proceed\n        e.preventDefault();\n        $(e.target).ajaxSubmit(options); // #365\n    }\n}\n\nfunction captureSubmittingElement(e) {\n    /*jshint validthis:true */\n    var target = e.target;\n    var $el = $(target);\n    if (!($el.is(\"[type=submit],[type=image]\"))) {\n        // is this a child element of the submit el?  (ex: a span within a button)\n        var t = $el.closest('[type=submit]');\n        if (t.length === 0) {\n            return;\n        }\n        target = t[0];\n    }\n    var form = this;\n    form.clk = target;\n    if (target.type == 'image') {\n        if (e.offsetX !== undefined) {\n            form.clk_x = e.offsetX;\n            form.clk_y = e.offsetY;\n        } else if (typeof $.fn.offset == 'function') {\n            var offset = $el.offset();\n            form.clk_x = e.pageX - offset.left;\n            form.clk_y = e.pageY - offset.top;\n        } else {\n            form.clk_x = e.pageX - target.offsetLeft;\n            form.clk_y = e.pageY - target.offsetTop;\n        }\n    }\n    // clear form vars\n    setTimeout(function() { form.clk = form.clk_x = form.clk_y = null; }, 100);\n}\n\n\n// ajaxFormUnbind unbinds the event handlers that were bound by ajaxForm\n$.fn.ajaxFormUnbind = function() {\n    return this.unbind('submit.form-plugin click.form-plugin');\n};\n\n/**\n * formToArray() gathers form element data into an array of objects that can\n * be passed to any of the following ajax functions: $.get, $.post, or load.\n * Each object in the array has both a 'name' and 'value' property.  An example of\n * an array for a simple login form might be:\n *\n * [ { name: 'username', value: 'jresig' }, { name: 'password', value: 'secret' } ]\n *\n * It is this array that is passed to pre-submit callback functions provided to the\n * ajaxSubmit() and ajaxForm() methods.\n */\n$.fn.formToArray = function(semantic, elements) {\n    var a = [];\n    if (this.length === 0) {\n        return a;\n    }\n\n    var form = this[0];\n    var formId = this.attr('id');\n    var els = semantic ? form.getElementsByTagName('*') : form.elements;\n    var els2;\n\n    if (els && !/MSIE [678]/.test(navigator.userAgent)) { // #390\n        els = $(els).get();  // convert to standard array\n    }\n\n    // #386; account for inputs outside the form which use the 'form' attribute\n    if ( formId ) {\n        els2 = $(':input[form=\"' + formId + '\"]').get(); // hat tip @thet\n        if ( els2.length ) {\n            els = (els || []).concat(els2);\n        }\n    }\n\n    if (!els || !els.length) {\n        return a;\n    }\n\n    var i,j,n,v,el,max,jmax;\n    for(i=0, max=els.length; i < max; i++) {\n        el = els[i];\n        n = el.name;\n        if (!n || el.disabled) {\n            continue;\n        }\n\n        if (semantic && form.clk && el.type == \"image\") {\n            // handle image inputs on the fly when semantic == true\n            if(form.clk == el) {\n                a.push({name: n, value: $(el).val(), type: el.type });\n                a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});\n            }\n            continue;\n        }\n\n        v = $.fieldValue(el, true);\n        if (v && v.constructor == Array) {\n            if (elements) {\n                elements.push(el);\n            }\n            for(j=0, jmax=v.length; j < jmax; j++) {\n                a.push({name: n, value: v[j]});\n            }\n        }\n        else if (feature.fileapi && el.type == 'file') {\n            if (elements) {\n                elements.push(el);\n            }\n            var files = el.files;\n            if (files.length) {\n                for (j=0; j < files.length; j++) {\n                    a.push({name: n, value: files[j], type: el.type});\n                }\n            }\n            else {\n                // #180\n                a.push({ name: n, value: '', type: el.type });\n            }\n        }\n        else if (v !== null && typeof v != 'undefined') {\n            if (elements) {\n                elements.push(el);\n            }\n            a.push({name: n, value: v, type: el.type, required: el.required});\n        }\n    }\n\n    if (!semantic && form.clk) {\n        // input type=='image' are not found in elements array! handle it here\n        var $input = $(form.clk), input = $input[0];\n        n = input.name;\n        if (n && !input.disabled && input.type == 'image') {\n            a.push({name: n, value: $input.val()});\n            a.push({name: n+'.x', value: form.clk_x}, {name: n+'.y', value: form.clk_y});\n        }\n    }\n    return a;\n};\n\n/**\n * Serializes form data into a 'submittable' string. This method will return a string\n * in the format: name1=value1&amp;name2=value2\n */\n$.fn.formSerialize = function(semantic) {\n    //hand off to jQuery.param for proper encoding\n    return $.param(this.formToArray(semantic));\n};\n\n/**\n * Serializes all field elements in the jQuery object into a query string.\n * This method will return a string in the format: name1=value1&amp;name2=value2\n */\n$.fn.fieldSerialize = function(successful) {\n    var a = [];\n    this.each(function() {\n        var n = this.name;\n        if (!n) {\n            return;\n        }\n        var v = $.fieldValue(this, successful);\n        if (v && v.constructor == Array) {\n            for (var i=0,max=v.length; i < max; i++) {\n                a.push({name: n, value: v[i]});\n            }\n        }\n        else if (v !== null && typeof v != 'undefined') {\n            a.push({name: this.name, value: v});\n        }\n    });\n    //hand off to jQuery.param for proper encoding\n    return $.param(a);\n};\n\n/**\n * Returns the value(s) of the element in the matched set.  For example, consider the following form:\n *\n *  <form><fieldset>\n *      <input name=\"A\" type=\"text\" />\n *      <input name=\"A\" type=\"text\" />\n *      <input name=\"B\" type=\"checkbox\" value=\"B1\" />\n *      <input name=\"B\" type=\"checkbox\" value=\"B2\"/>\n *      <input name=\"C\" type=\"radio\" value=\"C1\" />\n *      <input name=\"C\" type=\"radio\" value=\"C2\" />\n *  </fieldset></form>\n *\n *  var v = $('input[type=text]').fieldValue();\n *  // if no values are entered into the text inputs\n *  v == ['','']\n *  // if values entered into the text inputs are 'foo' and 'bar'\n *  v == ['foo','bar']\n *\n *  var v = $('input[type=checkbox]').fieldValue();\n *  // if neither checkbox is checked\n *  v === undefined\n *  // if both checkboxes are checked\n *  v == ['B1', 'B2']\n *\n *  var v = $('input[type=radio]').fieldValue();\n *  // if neither radio is checked\n *  v === undefined\n *  // if first radio is checked\n *  v == ['C1']\n *\n * The successful argument controls whether or not the field element must be 'successful'\n * (per http://www.w3.org/TR/html4/interact/forms.html#successful-controls).\n * The default value of the successful argument is true.  If this value is false the value(s)\n * for each element is returned.\n *\n * Note: This method *always* returns an array.  If no valid value can be determined the\n *    array will be empty, otherwise it will contain one or more values.\n */\n$.fn.fieldValue = function(successful) {\n    for (var val=[], i=0, max=this.length; i < max; i++) {\n        var el = this[i];\n        var v = $.fieldValue(el, successful);\n        if (v === null || typeof v == 'undefined' || (v.constructor == Array && !v.length)) {\n            continue;\n        }\n        if (v.constructor == Array) {\n            $.merge(val, v);\n        }\n        else {\n            val.push(v);\n        }\n    }\n    return val;\n};\n\n/**\n * Returns the value of the field element.\n */\n$.fieldValue = function(el, successful) {\n    var n = el.name, t = el.type, tag = el.tagName.toLowerCase();\n    if (successful === undefined) {\n        successful = true;\n    }\n\n    if (successful && (!n || el.disabled || t == 'reset' || t == 'button' ||\n        (t == 'checkbox' || t == 'radio') && !el.checked ||\n        (t == 'submit' || t == 'image') && el.form && el.form.clk != el ||\n        tag == 'select' && el.selectedIndex == -1)) {\n            return null;\n    }\n\n    if (tag == 'select') {\n        var index = el.selectedIndex;\n        if (index < 0) {\n            return null;\n        }\n        var a = [], ops = el.options;\n        var one = (t == 'select-one');\n        var max = (one ? index+1 : ops.length);\n        for(var i=(one ? index : 0); i < max; i++) {\n            var op = ops[i];\n            if (op.selected) {\n                var v = op.value;\n                if (!v) { // extra pain for IE...\n                    v = (op.attributes && op.attributes.value && !(op.attributes.value.specified)) ? op.text : op.value;\n                }\n                if (one) {\n                    return v;\n                }\n                a.push(v);\n            }\n        }\n        return a;\n    }\n    return $(el).val();\n};\n\n/**\n * Clears the form data.  Takes the following actions on the form's input fields:\n *  - input text fields will have their 'value' property set to the empty string\n *  - select elements will have their 'selectedIndex' property set to -1\n *  - checkbox and radio inputs will have their 'checked' property set to false\n *  - inputs of type submit, button, reset, and hidden will *not* be effected\n *  - button elements will *not* be effected\n */\n$.fn.clearForm = function(includeHidden) {\n    return this.each(function() {\n        $('input,select,textarea', this).clearFields(includeHidden);\n    });\n};\n\n/**\n * Clears the selected form elements.\n */\n$.fn.clearFields = $.fn.clearInputs = function(includeHidden) {\n    var re = /^(?:color|date|datetime|email|month|number|password|range|search|tel|text|time|url|week)$/i; // 'hidden' is not in this list\n    return this.each(function() {\n        var t = this.type, tag = this.tagName.toLowerCase();\n        if (re.test(t) || tag == 'textarea') {\n            this.value = '';\n        }\n        else if (t == 'checkbox' || t == 'radio') {\n            this.checked = false;\n        }\n        else if (tag == 'select') {\n            this.selectedIndex = -1;\n        }\n        else if (t == \"file\") {\n            if (/MSIE/.test(navigator.userAgent)) {\n                $(this).replaceWith($(this).clone(true));\n            } else {\n                $(this).val('');\n            }\n        }\n        else if (includeHidden) {\n            // includeHidden can be the value true, or it can be a selector string\n            // indicating a special test; for example:\n            //  $('#myForm').clearForm('.special:hidden')\n            // the above would clean hidden inputs that have the class of 'special'\n            if ( (includeHidden === true && /hidden/.test(t)) ||\n                 (typeof includeHidden == 'string' && $(this).is(includeHidden)) ) {\n                this.value = '';\n            }\n        }\n    });\n};\n\n/**\n * Resets the form data.  Causes all form elements to be reset to their original value.\n */\n$.fn.resetForm = function() {\n    return this.each(function() {\n        // guard against an input with the name of 'reset'\n        // note that IE reports the reset function as an 'object'\n        if (typeof this.reset == 'function' || (typeof this.reset == 'object' && !this.reset.nodeType)) {\n            this.reset();\n        }\n    });\n};\n\n/**\n * Enables or disables any matching elements.\n */\n$.fn.enable = function(b) {\n    if (b === undefined) {\n        b = true;\n    }\n    return this.each(function() {\n        this.disabled = !b;\n    });\n};\n\n/**\n * Checks/unchecks any matching checkboxes or radio buttons and\n * selects/deselects and matching option elements.\n */\n$.fn.selected = function(select) {\n    if (select === undefined) {\n        select = true;\n    }\n    return this.each(function() {\n        var t = this.type;\n        if (t == 'checkbox' || t == 'radio') {\n            this.checked = select;\n        }\n        else if (this.tagName.toLowerCase() == 'option') {\n            var $sel = $(this).parent('select');\n            if (select && $sel[0] && $sel[0].type == 'select-one') {\n                // deselect all other options\n                $sel.find('option').selected(false);\n            }\n            this.selected = select;\n        }\n    });\n};\n\n// expose debug var\n$.fn.ajaxSubmit.debug = false;\n\n// helper fn for console logging\nfunction log() {\n    if (!$.fn.ajaxSubmit.debug) {\n        return;\n    }\n    var msg = '[jquery.form] ' + Array.prototype.join.call(arguments,'');\n    if (window.console && window.console.log) {\n        window.console.log(msg);\n    }\n    else if (window.opera && window.opera.postError) {\n        window.opera.postError(msg);\n    }\n}\n\n}));\n"
  },
  {
    "path": "public/static/plugins/fullcalendar/fullcalendar.css",
    "content": "/*!\n * FullCalendar v2.2.5 Stylesheet\n * Docs & License: http://arshaw.com/fullcalendar/\n * (c) 2013 Adam Shaw\n */\n\n\n.fc {\n\tdirection: ltr;\n\ttext-align: left;\n}\n\n.fc-rtl {\n\ttext-align: right;\n}\n\nbody .fc { /* extra precedence to overcome jqui */\n\tfont-size: 1em;\n}\n\n\n/* Colors\n--------------------------------------------------------------------------------------------------*/\n\n.fc-unthemed th,\n.fc-unthemed td,\n.fc-unthemed hr,\n.fc-unthemed thead,\n.fc-unthemed tbody,\n.fc-unthemed .fc-row,\n.fc-unthemed .fc-popover {\n\tborder-color: #ddd;\n}\n\n.fc-unthemed .fc-popover {\n\tbackground-color: #fff;\n}\n\n.fc-unthemed hr,\n.fc-unthemed .fc-popover .fc-header {\n\tbackground: #eee;\n}\n\n.fc-unthemed .fc-popover .fc-header .fc-close {\n\tcolor: #666;\n}\n\n.fc-unthemed .fc-today {\n\tbackground: #fcf8e3;\n}\n\n.fc-highlight { /* when user is selecting cells */\n\tbackground: #bce8f1;\n\topacity: .3;\n\tfilter: alpha(opacity=30); /* for IE */\n}\n\n.fc-bgevent { /* default look for background events */\n\tbackground: rgb(143, 223, 130);\n\topacity: .3;\n\tfilter: alpha(opacity=30); /* for IE */\n}\n\n.fc-nonbusiness { /* default look for non-business-hours areas */\n\t/* will inherit .fc-bgevent's styles */\n\tbackground: #ccc;\n}\n\n\n/* Icons (inline elements with styled text that mock arrow icons)\n--------------------------------------------------------------------------------------------------*/\n\n.fc-icon {\n\tdisplay: inline-block;\n\tfont-size: 2em;\n\tline-height: .5em;\n\theight: .5em; /* will make the total height 1em */\n\tfont-family: \"Courier New\", Courier, monospace;\n}\n\n.fc-icon-left-single-arrow:after {\n\tcontent: \"\\02039\";\n\tfont-weight: bold;\n}\n\n.fc-icon-right-single-arrow:after {\n\tcontent: \"\\0203A\";\n\tfont-weight: bold;\n}\n\n.fc-icon-left-double-arrow:after {\n\tcontent: \"\\000AB\";\n}\n\n.fc-icon-right-double-arrow:after {\n\tcontent: \"\\000BB\";\n}\n\n.fc-icon-x:after {\n\tcontent: \"\\000D7\";\n}\n\n\n/* Buttons (styled <button> tags, normalized to work cross-browser)\n--------------------------------------------------------------------------------------------------*/\n\n.fc button {\n\t/* force height to include the border and padding */\n\t-moz-box-sizing: border-box;\n\t-webkit-box-sizing: border-box;\n\tbox-sizing: border-box;\n\n\t/* dimensions */\n\tmargin: 0;\n\theight: 2.1em;\n\tpadding: 0 .6em;\n\n\t/* text & cursor */\n\tfont-size: 1em; /* normalize */\n\twhite-space: nowrap;\n\tcursor: pointer;\n}\n\n/* Firefox has an annoying inner border */\n.fc button::-moz-focus-inner { margin: 0; padding: 0; }\n\t\n.fc-state-default { /* non-theme */\n\tborder: 1px solid;\n}\n\n.fc-state-default.fc-corner-left { /* non-theme */\n\tborder-top-left-radius: 4px;\n\tborder-bottom-left-radius: 4px;\n}\n\n.fc-state-default.fc-corner-right { /* non-theme */\n\tborder-top-right-radius: 4px;\n\tborder-bottom-right-radius: 4px;\n}\n\n/* icons in buttons */\n\n.fc button .fc-icon { /* non-theme */\n\tposition: relative;\n\ttop: .05em; /* seems to be a good adjustment across browsers */\n\tmargin: 0 .1em;\n}\n\t\n/*\n  button states\n  borrowed from twitter bootstrap (http://twitter.github.com/bootstrap/)\n*/\n\n.fc-state-default {\n\tbackground-color: #f5f5f5;\n\tbackground-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);\n\tbackground-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));\n\tbackground-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);\n\tbackground-image: -o-linear-gradient(top, #ffffff, #e6e6e6);\n\tbackground-image: linear-gradient(to bottom, #ffffff, #e6e6e6);\n\tbackground-repeat: repeat-x;\n\tborder-color: #e6e6e6 #e6e6e6 #bfbfbf;\n\tborder-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);\n\tcolor: #333;\n\ttext-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);\n\tbox-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.fc-state-hover,\n.fc-state-down,\n.fc-state-active,\n.fc-state-disabled {\n\tcolor: #333333;\n\tbackground-color: #e6e6e6;\n}\n\n.fc-state-hover {\n\tcolor: #333333;\n\ttext-decoration: none;\n\tbackground-position: 0 -15px;\n\t-webkit-transition: background-position 0.1s linear;\n\t   -moz-transition: background-position 0.1s linear;\n\t     -o-transition: background-position 0.1s linear;\n\t        transition: background-position 0.1s linear;\n}\n\n.fc-state-down,\n.fc-state-active {\n\tbackground-color: #cccccc;\n\tbackground-image: none;\n\tbox-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);\n}\n\n.fc-state-disabled {\n\tcursor: default;\n\tbackground-image: none;\n\topacity: 0.65;\n\tfilter: alpha(opacity=65);\n\tbox-shadow: none;\n}\n\n\n/* Buttons Groups\n--------------------------------------------------------------------------------------------------*/\n\n.fc-button-group {\n\tdisplay: inline-block;\n}\n\n/*\nevery button that is not first in a button group should scootch over one pixel and cover the\nprevious button's border...\n*/\n\n.fc .fc-button-group > * { /* extra precedence b/c buttons have margin set to zero */\n\tfloat: left;\n\tmargin: 0 0 0 -1px;\n}\n\n.fc .fc-button-group > :first-child { /* same */\n\tmargin-left: 0;\n}\n\n\n/* Popover\n--------------------------------------------------------------------------------------------------*/\n\n.fc-popover {\n\tposition: absolute;\n\tbox-shadow: 0 2px 6px rgba(0,0,0,.15);\n}\n\n.fc-popover .fc-header {\n\tpadding: 2px 4px;\n}\n\n.fc-popover .fc-header .fc-title {\n\tmargin: 0 2px;\n}\n\n.fc-popover .fc-header .fc-close {\n\tcursor: pointer;\n}\n\n.fc-ltr .fc-popover .fc-header .fc-title,\n.fc-rtl .fc-popover .fc-header .fc-close {\n\tfloat: left;\n}\n\n.fc-rtl .fc-popover .fc-header .fc-title,\n.fc-ltr .fc-popover .fc-header .fc-close {\n\tfloat: right;\n}\n\n/* unthemed */\n\n.fc-unthemed .fc-popover {\n\tborder-width: 1px;\n\tborder-style: solid;\n}\n\n.fc-unthemed .fc-popover .fc-header .fc-close {\n\tfont-size: 25px;\n\tmargin-top: 4px;\n}\n\n/* jqui themed */\n\n.fc-popover > .ui-widget-header + .ui-widget-content {\n\tborder-top: 0; /* where they meet, let the header have the border */\n}\n\n\n/* Misc Reusable Components\n--------------------------------------------------------------------------------------------------*/\n\n.fc hr {\n\theight: 0;\n\tmargin: 0;\n\tpadding: 0 0 2px; /* height is unreliable across browsers, so use padding */\n\tborder-style: solid;\n\tborder-width: 1px 0;\n}\n\n.fc-clear {\n\tclear: both;\n}\n\n.fc-bg,\n.fc-bgevent-skeleton,\n.fc-highlight-skeleton,\n.fc-helper-skeleton {\n\t/* these element should always cling to top-left/right corners */\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n}\n\n.fc-bg {\n\tbottom: 0; /* strech bg to bottom edge */\n}\n\n.fc-bg table {\n\theight: 100%; /* strech bg to bottom edge */\n}\n\n\n/* Tables\n--------------------------------------------------------------------------------------------------*/\n\n.fc table {\n\twidth: 100%;\n\ttable-layout: fixed;\n\tborder-collapse: collapse;\n\tborder-spacing: 0;\n\tfont-size: 1em; /* normalize cross-browser */\n}\n\n.fc th {\n\ttext-align: center;\n}\n\n.fc th,\n.fc td {\n\tborder-style: solid;\n\tborder-width: 1px;\n\tpadding: 0;\n\tvertical-align: top;\n}\n\n.fc td.fc-today {\n\tborder-style: double; /* overcome neighboring borders */\n}\n\n\n/* Fake Table Rows\n--------------------------------------------------------------------------------------------------*/\n\n.fc .fc-row { /* extra precedence to overcome themes w/ .ui-widget-content forcing a 1px border */\n\t/* no visible border by default. but make available if need be (scrollbar width compensation) */\n\tborder-style: solid;\n\tborder-width: 0;\n}\n\n.fc-row table {\n\t/* don't put left/right border on anything within a fake row.\n\t   the outer tbody will worry about this */\n\tborder-left: 0 hidden transparent;\n\tborder-right: 0 hidden transparent;\n\n\t/* no bottom borders on rows */\n\tborder-bottom: 0 hidden transparent; \n}\n\n.fc-row:first-child table {\n\tborder-top: 0 hidden transparent; /* no top border on first row */\n}\n\n\n/* Day Row (used within the header and the DayGrid)\n--------------------------------------------------------------------------------------------------*/\n\n.fc-row {\n\tposition: relative;\n}\n\n.fc-row .fc-bg {\n\tz-index: 1;\n}\n\n/* highlighting cells & background event skeleton */\n\n.fc-row .fc-bgevent-skeleton,\n.fc-row .fc-highlight-skeleton {\n\tbottom: 0; /* stretch skeleton to bottom of row */\n}\n\n.fc-row .fc-bgevent-skeleton table,\n.fc-row .fc-highlight-skeleton table {\n\theight: 100%; /* stretch skeleton to bottom of row */\n}\n\n.fc-row .fc-highlight-skeleton td,\n.fc-row .fc-bgevent-skeleton td {\n\tborder-color: transparent;\n}\n\n.fc-row .fc-bgevent-skeleton {\n\tz-index: 2;\n\n}\n\n.fc-row .fc-highlight-skeleton {\n\tz-index: 3;\n}\n\n/*\nrow content (which contains day/week numbers and events) as well as \"helper\" (which contains\ntemporary rendered events).\n*/\n\n.fc-row .fc-content-skeleton {\n\tposition: relative;\n\tz-index: 4;\n\tpadding-bottom: 2px; /* matches the space above the events */\n}\n\n.fc-row .fc-helper-skeleton {\n\tz-index: 5;\n}\n\n.fc-row .fc-content-skeleton td,\n.fc-row .fc-helper-skeleton td {\n\t/* see-through to the background below */\n\tbackground: none; /* in case <td>s are globally styled */\n\tborder-color: transparent;\n\n\t/* don't put a border between events and/or the day number */\n\tborder-bottom: 0;\n}\n\n.fc-row .fc-content-skeleton tbody td, /* cells with events inside (so NOT the day number cell) */\n.fc-row .fc-helper-skeleton tbody td {\n\t/* don't put a border between event cells */\n\tborder-top: 0;\n}\n\n\n/* Scrolling Container\n--------------------------------------------------------------------------------------------------*/\n\n.fc-scroller { /* this class goes on elements for guaranteed vertical scrollbars */\n\toverflow-y: scroll;\n\toverflow-x: hidden;\n}\n\n.fc-scroller > * { /* we expect an immediate inner element */\n\tposition: relative; /* re-scope all positions */\n\twidth: 100%; /* hack to force re-sizing this inner element when scrollbars appear/disappear */\n\toverflow: hidden; /* don't let negative margins or absolute positioning create further scroll */\n}\n\n\n/* Global Event Styles\n--------------------------------------------------------------------------------------------------*/\n\n.fc-event {\n\tposition: relative; /* for resize handle and other inner positioning */\n\tdisplay: block; /* make the <a> tag block */\n\tfont-size: .85em;\n\tline-height: 1.3;\n\tborder-radius: 3px;\n\tborder: 1px solid #3a87ad; /* default BORDER color */\n\tbackground-color: #3a87ad; /* default BACKGROUND color */\n\tfont-weight: normal; /* undo jqui's ui-widget-header bold */\n}\n\n/* overpower some of bootstrap's and jqui's styles on <a> tags */\n.fc-event,\n.fc-event:hover,\n.ui-widget .fc-event {\n\tcolor: #fff; /* default TEXT color */\n\ttext-decoration: none; /* if <a> has an href */\n}\n\n.fc-event[href],\n.fc-event.fc-draggable {\n\tcursor: pointer; /* give events with links and draggable events a hand mouse pointer */\n}\n\n.fc-not-allowed, /* causes a \"warning\" cursor. applied on body */\n.fc-not-allowed .fc-event { /* to override an event's custom cursor */\n\tcursor: not-allowed;\n}\n\n\n/* DayGrid events\n----------------------------------------------------------------------------------------------------\nWe use the full \"fc-day-grid-event\" class instead of using descendants because the event won't\nbe a descendant of the grid when it is being dragged.\n*/\n\n.fc-day-grid-event {\n\tmargin: 1px 2px 0; /* spacing between events and edges */\n\tpadding: 0 1px;\n}\n\n/* events that are continuing to/from another week. kill rounded corners and butt up against edge */\n\n.fc-ltr .fc-day-grid-event.fc-not-start,\n.fc-rtl .fc-day-grid-event.fc-not-end {\n\tmargin-left: 0;\n\tborder-left-width: 0;\n\tpadding-left: 1px; /* replace the border with padding */\n\tborder-top-left-radius: 0;\n\tborder-bottom-left-radius: 0;\n}\n\n.fc-ltr .fc-day-grid-event.fc-not-end,\n.fc-rtl .fc-day-grid-event.fc-not-start {\n\tmargin-right: 0;\n\tborder-right-width: 0;\n\tpadding-right: 1px; /* replace the border with padding */\n\tborder-top-right-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\n.fc-day-grid-event > .fc-content { /* force events to be one-line tall */\n\twhite-space: nowrap;\n\toverflow: hidden;\n}\n\n.fc-day-grid-event .fc-time {\n\tfont-weight: bold;\n}\n\n/* resize handle (outside of fc-content, so can go outside of bounds) */\n\n.fc-day-grid-event .fc-resizer {\n\tposition: absolute;\n\ttop: 0;\n\tbottom: 0;\n\twidth: 7px;\n}\n\n.fc-ltr .fc-day-grid-event .fc-resizer {\n\tright: -3px;\n\tcursor: e-resize;\n}\n\n.fc-rtl .fc-day-grid-event .fc-resizer {\n\tleft: -3px;\n\tcursor: w-resize;\n}\n\n\n/* Event Limiting\n--------------------------------------------------------------------------------------------------*/\n\n/* \"more\" link that represents hidden events */\n\na.fc-more {\n\tmargin: 1px 3px;\n\tfont-size: .85em;\n\tcursor: pointer;\n\ttext-decoration: none;\n}\n\na.fc-more:hover {\n\ttext-decoration: underline;\n}\n\n.fc-limited { /* rows and cells that are hidden because of a \"more\" link */\n\tdisplay: none;\n}\n\n/* popover that appears when \"more\" link is clicked */\n\n.fc-day-grid .fc-row {\n\tz-index: 1; /* make the \"more\" popover one higher than this */\n}\n\n.fc-more-popover {\n\tz-index: 2;\n\twidth: 220px;\n}\n\n.fc-more-popover .fc-event-container {\n\tpadding: 10px;\n}\n\n/* Toolbar\n--------------------------------------------------------------------------------------------------*/\n\n.fc-toolbar {\n\ttext-align: center;\n\tmargin-bottom: 1em;\n}\n\n.fc-toolbar .fc-left {\n\tfloat: left;\n}\n\n.fc-toolbar .fc-right {\n\tfloat: right;\n}\n\n.fc-toolbar .fc-center {\n\tdisplay: inline-block;\n}\n\n/* the things within each left/right/center section */\n.fc .fc-toolbar > * > * { /* extra precedence to override button border margins */\n\tfloat: left;\n\tmargin-left: .75em;\n}\n\n/* the first thing within each left/center/right section */\n.fc .fc-toolbar > * > :first-child { /* extra precedence to override button border margins */\n\tmargin-left: 0;\n}\n\t\n/* title text */\n\n.fc-toolbar h2 {\n\tmargin: 0;\n}\n\n/* button layering (for border precedence) */\n\n.fc-toolbar button {\n\tposition: relative;\n}\n\n.fc-toolbar .fc-state-hover,\n.fc-toolbar .ui-state-hover {\n\tz-index: 2;\n}\n\t\n.fc-toolbar .fc-state-down {\n\tz-index: 3;\n}\n\n.fc-toolbar .fc-state-active,\n.fc-toolbar .ui-state-active {\n\tz-index: 4;\n}\n\n.fc-toolbar button:focus {\n\tz-index: 5;\n}\n\n\n/* View Structure\n--------------------------------------------------------------------------------------------------*/\n\n/* undo twitter bootstrap's box-sizing rules. normalizes positioning techniques */\n/* don't do this for the toolbar because we'll want bootstrap to style those buttons as some pt */\n.fc-view-container *,\n.fc-view-container *:before,\n.fc-view-container *:after {\n\t-webkit-box-sizing: content-box;\n\t   -moz-box-sizing: content-box;\n\t        box-sizing: content-box;\n}\n\n.fc-view, /* scope positioning and z-index's for everything within the view */\n.fc-view > table { /* so dragged elements can be above the view's main element */\n\tposition: relative;\n\tz-index: 1;\n}\n\n/* BasicView\n--------------------------------------------------------------------------------------------------*/\n\n/* day row structure */\n\n.fc-basicWeek-view .fc-content-skeleton,\n.fc-basicDay-view .fc-content-skeleton {\n\t/* we are sure there are no day numbers in these views, so... */\n\tpadding-top: 1px; /* add a pixel to make sure there are 2px padding above events */\n\tpadding-bottom: 1em; /* ensure a space at bottom of cell for user selecting/clicking */\n}\n\n.fc-basic-view tbody .fc-row {\n\tmin-height: 4em; /* ensure that all rows are at least this tall */\n}\n\n/* a \"rigid\" row will take up a constant amount of height because content-skeleton is absolute */\n\n.fc-row.fc-rigid {\n\toverflow: hidden;\n}\n\n.fc-row.fc-rigid .fc-content-skeleton {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n}\n\n/* week and day number styling */\n\n.fc-basic-view .fc-week-number,\n.fc-basic-view .fc-day-number {\n\tpadding: 0 2px;\n}\n\n.fc-basic-view td.fc-week-number span,\n.fc-basic-view td.fc-day-number {\n\tpadding-top: 2px;\n\tpadding-bottom: 2px;\n}\n\n.fc-basic-view .fc-week-number {\n\ttext-align: center;\n}\n\n.fc-basic-view .fc-week-number span {\n\t/* work around the way we do column resizing and ensure a minimum width */\n\tdisplay: inline-block;\n\tmin-width: 1.25em;\n}\n\n.fc-ltr .fc-basic-view .fc-day-number {\n\ttext-align: right;\n}\n\n.fc-rtl .fc-basic-view .fc-day-number {\n\ttext-align: left;\n}\n\n.fc-day-number.fc-other-month {\n\topacity: 0.3;\n\tfilter: alpha(opacity=30); /* for IE */\n\t/* opacity with small font can sometimes look too faded\n\t   might want to set the 'color' property instead\n\t   making day-numbers bold also fixes the problem */\n}\n\n/* AgendaView all-day area\n--------------------------------------------------------------------------------------------------*/\n\n.fc-agenda-view .fc-day-grid {\n\tposition: relative;\n\tz-index: 2; /* so the \"more..\" popover will be over the time grid */\n}\n\n.fc-agenda-view .fc-day-grid .fc-row {\n\tmin-height: 3em; /* all-day section will never get shorter than this */\n}\n\n.fc-agenda-view .fc-day-grid .fc-row .fc-content-skeleton {\n\tpadding-top: 1px; /* add a pixel to make sure there are 2px padding above events */\n\tpadding-bottom: 1em; /* give space underneath events for clicking/selecting days */\n}\n\n\n/* TimeGrid axis running down the side (for both the all-day area and the slot area)\n--------------------------------------------------------------------------------------------------*/\n\n.fc .fc-axis { /* .fc to overcome default cell styles */\n\tvertical-align: middle;\n\tpadding: 0 4px;\n\twhite-space: nowrap;\n}\n\n.fc-ltr .fc-axis {\n\ttext-align: right;\n}\n\n.fc-rtl .fc-axis {\n\ttext-align: left;\n}\n\n.ui-widget td.fc-axis {\n\tfont-weight: normal; /* overcome jqui theme making it bold */\n}\n\n\n/* TimeGrid Structure\n--------------------------------------------------------------------------------------------------*/\n\n.fc-time-grid-container, /* so scroll container's z-index is below all-day */\n.fc-time-grid { /* so slats/bg/content/etc positions get scoped within here */\n\tposition: relative;\n\tz-index: 1;\n}\n\n.fc-time-grid {\n\tmin-height: 100%; /* so if height setting is 'auto', .fc-bg stretches to fill height */\n}\n\n.fc-time-grid table { /* don't put outer borders on slats/bg/content/etc */\n\tborder: 0 hidden transparent;\n}\n\n.fc-time-grid > .fc-bg {\n\tz-index: 1;\n}\n\n.fc-time-grid .fc-slats,\n.fc-time-grid > hr { /* the <hr> AgendaView injects when grid is shorter than scroller */\n\tposition: relative;\n\tz-index: 2;\n}\n\n.fc-time-grid .fc-bgevent-skeleton,\n.fc-time-grid .fc-content-skeleton {\n\tposition: absolute;\n\ttop: 0;\n\tleft: 0;\n\tright: 0;\n}\n\n.fc-time-grid .fc-bgevent-skeleton {\n\tz-index: 3;\n}\n\n.fc-time-grid .fc-highlight-skeleton {\n\tz-index: 4;\n}\n\n.fc-time-grid .fc-content-skeleton {\n\tz-index: 5;\n}\n\n.fc-time-grid .fc-helper-skeleton {\n\tz-index: 6;\n}\n\n\n/* TimeGrid Slats (lines that run horizontally)\n--------------------------------------------------------------------------------------------------*/\n\n.fc-slats td {\n\theight: 1.5em;\n\tborder-bottom: 0; /* each cell is responsible for its top border */\n}\n\n.fc-slats .fc-minor td {\n\tborder-top-style: dotted;\n}\n\n.fc-slats .ui-widget-content { /* for jqui theme */\n\tbackground: none; /* see through to fc-bg */\n}\n\n\n/* TimeGrid Highlighting Slots\n--------------------------------------------------------------------------------------------------*/\n\n.fc-time-grid .fc-highlight-container { /* a div within a cell within the fc-highlight-skeleton */\n\tposition: relative; /* scopes the left/right of the fc-highlight to be in the column */\n}\n\n.fc-time-grid .fc-highlight {\n\tposition: absolute;\n\tleft: 0;\n\tright: 0;\n\t/* top and bottom will be in by JS */\n}\n\n\n/* TimeGrid Event Containment\n--------------------------------------------------------------------------------------------------*/\n\n.fc-time-grid .fc-event-container, /* a div within a cell within the fc-content-skeleton */\n.fc-time-grid .fc-bgevent-container { /* a div within a cell within the fc-bgevent-skeleton */\n\tposition: relative;\n}\n\n.fc-ltr .fc-time-grid .fc-event-container { /* space on the sides of events for LTR (default) */\n\tmargin: 0 2.5% 0 2px;\n}\n\n.fc-rtl .fc-time-grid .fc-event-container { /* space on the sides of events for RTL */\n\tmargin: 0 2px 0 2.5%;\n}\n\n.fc-time-grid .fc-event,\n.fc-time-grid .fc-bgevent {\n\tposition: absolute;\n\tz-index: 1; /* scope inner z-index's */\n}\n\n.fc-time-grid .fc-bgevent {\n\t/* background events always span full width */\n\tleft: 0;\n\tright: 0;\n}\n\n\n/* TimeGrid Event Styling\n----------------------------------------------------------------------------------------------------\nWe use the full \"fc-time-grid-event\" class instead of using descendants because the event won't\nbe a descendant of the grid when it is being dragged.\n*/\n\n.fc-time-grid-event.fc-not-start { /* events that are continuing from another day */\n\t/* replace space made by the top border with padding */\n\tborder-top-width: 0;\n\tpadding-top: 1px;\n\n\t/* remove top rounded corners */\n\tborder-top-left-radius: 0;\n\tborder-top-right-radius: 0;\n}\n\n.fc-time-grid-event.fc-not-end {\n\t/* replace space made by the top border with padding */\n\tborder-bottom-width: 0;\n\tpadding-bottom: 1px;\n\n\t/* remove bottom rounded corners */\n\tborder-bottom-left-radius: 0;\n\tborder-bottom-right-radius: 0;\n}\n\n.fc-time-grid-event {\n\toverflow: hidden; /* don't let the bg flow over rounded corners */\n}\n\n.fc-time-grid-event > .fc-content { /* contains the time and title, but no bg and resizer */\n\tposition: relative;\n\tz-index: 2; /* above the bg */\n}\n\n.fc-time-grid-event .fc-time,\n.fc-time-grid-event .fc-title {\n\tpadding: 0 1px;\n}\n\n.fc-time-grid-event .fc-time {\n\tfont-size: .85em;\n\twhite-space: nowrap;\n}\n\n.fc-time-grid-event .fc-bg {\n\tz-index: 1;\n\tbackground: #fff;\n\topacity: .25;\n\tfilter: alpha(opacity=25); /* for IE */\n}\n\n/* short mode, where time and title are on the same line */\n\n.fc-time-grid-event.fc-short .fc-content {\n\t/* don't wrap to second line (now that contents will be inline) */\n\twhite-space: nowrap;\n}\n\n.fc-time-grid-event.fc-short .fc-time,\n.fc-time-grid-event.fc-short .fc-title {\n\t/* put the time and title on the same line */\n\tdisplay: inline-block;\n\tvertical-align: top;\n}\n\n.fc-time-grid-event.fc-short .fc-time span {\n\tdisplay: none; /* don't display the full time text... */\n}\n\n.fc-time-grid-event.fc-short .fc-time:before {\n\tcontent: attr(data-start); /* ...instead, display only the start time */\n}\n\n.fc-time-grid-event.fc-short .fc-time:after {\n\tcontent: \"\\000A0-\\000A0\"; /* seperate with a dash, wrapped in nbsp's */\n}\n\n.fc-time-grid-event.fc-short .fc-title {\n\tfont-size: .85em; /* make the title text the same size as the time */\n\tpadding: 0; /* undo padding from above */\n}\n\n/* resizer */\n\n.fc-time-grid-event .fc-resizer {\n\tposition: absolute;\n\tz-index: 3; /* above content */\n\tleft: 0;\n\tright: 0;\n\tbottom: 0;\n\theight: 8px;\n\toverflow: hidden;\n\tline-height: 8px;\n\tfont-size: 11px;\n\tfont-family: monospace;\n\ttext-align: center;\n\tcursor: s-resize;\n}\n\n.fc-time-grid-event .fc-resizer:after {\n\tcontent: \"=\";\n}\n"
  },
  {
    "path": "public/static/plugins/fullcalendar/fullcalendar.js",
    "content": "/*!\n * FullCalendar v2.2.5\n * Docs & License: http://arshaw.com/fullcalendar/\n * (c) 2013 Adam Shaw\n */\n\n(function(factory) {\n\tif (typeof define === 'function' && define.amd) {\n\t\tdefine([ 'jquery', 'moment' ], factory);\n\t}\n\telse {\n\t\tfactory(jQuery, moment);\n\t}\n})(function($, moment) {\n\n    var defaults = {\n\n\ttitleRangeSeparator: ' \\u2014 ', // emphasized dash\n\tmonthYearFormat: 'MMMM YYYY', // required for en. other languages rely on datepicker computable option\n\n\tdefaultTimedEventDuration: '02:00:00',\n\tdefaultAllDayEventDuration: { days: 1 },\n\tforceEventDuration: false,\n\tnextDayThreshold: '09:00:00', // 9am\n\n\t// display\n\tdefaultView: 'month',\n\taspectRatio: 1.35,\n\theader: {\n\t\tleft: 'title',\n\t\tcenter: '',\n\t\tright: 'today prev,next'\n\t},\n\tweekends: true,\n\tweekNumbers: false,\n\n\tweekNumberTitle: 'W',\n\tweekNumberCalculation: 'local',\n\t\n\t//editable: false,\n\t\n\t// event ajax\n\tlazyFetching: true,\n\tstartParam: 'start',\n\tendParam: 'end',\n\ttimezoneParam: 'timezone',\n\n\ttimezone: false,\n\n\t//allDayDefault: undefined,\n\n\t// locale\n\tisRTL: false,\n\tdefaultButtonText: {\n\t\tprev: \"prev\",\n\t\tnext: \"next\",\n\t\tprevYear: \"prev year\",\n\t\tnextYear: \"next year\",\n\t\ttoday: 'today',\n\t\tmonth: 'month',\n\t\tweek: 'week',\n\t\tday: 'day'\n\t},\n\n\tbuttonIcons: {\n\t\tprev: 'left-single-arrow',\n\t\tnext: 'right-single-arrow',\n\t\tprevYear: 'left-double-arrow',\n\t\tnextYear: 'right-double-arrow'\n\t},\n\t\n\t// jquery-ui theming\n\ttheme: false,\n\tthemeButtonIcons: {\n\t\tprev: 'circle-triangle-w',\n\t\tnext: 'circle-triangle-e',\n\t\tprevYear: 'seek-prev',\n\t\tnextYear: 'seek-next'\n\t},\n\n\tdragOpacity: .75,\n\tdragRevertDuration: 500,\n\tdragScroll: true,\n\t\n\t//selectable: false,\n\tunselectAuto: true,\n\t\n\tdropAccept: '*',\n\n\teventLimit: false,\n\teventLimitText: 'more',\n\teventLimitClick: 'popover',\n\tdayPopoverFormat: 'LL',\n\t\n\thandleWindowResize: true,\n\twindowResizeDelay: 200 // milliseconds before an updateSize happens\n\t\n};\n\n\nvar englishDefaults = {\n\tdayPopoverFormat: 'dddd, MMMM D'\n};\n\n\n// right-to-left defaults\nvar rtlDefaults = {\n\theader: {\n\t\tleft: 'next,prev today',\n\t\tcenter: '',\n\t\tright: 'title'\n\t},\n\tbuttonIcons: {\n\t\tprev: 'right-single-arrow',\n\t\tnext: 'left-single-arrow',\n\t\tprevYear: 'right-double-arrow',\n\t\tnextYear: 'left-double-arrow'\n\t},\n\tthemeButtonIcons: {\n\t\tprev: 'circle-triangle-e',\n\t\tnext: 'circle-triangle-w',\n\t\tnextYear: 'seek-prev',\n\t\tprevYear: 'seek-next'\n\t}\n};\n\n    var fc = $.fullCalendar = { version: \"2.2.5\" };\nvar fcViews = fc.views = {};\n\n\n$.fn.fullCalendar = function(options) {\n\tvar args = Array.prototype.slice.call(arguments, 1); // for a possible method call\n\tvar res = this; // what this function will return (this jQuery object by default)\n\n\tthis.each(function(i, _element) { // loop each DOM element involved\n\t\tvar element = $(_element);\n\t\tvar calendar = element.data('fullCalendar'); // get the existing calendar object (if any)\n\t\tvar singleRes; // the returned value of this single method call\n\n\t\t// a method call\n\t\tif (typeof options === 'string') {\n\t\t\tif (calendar && $.isFunction(calendar[options])) {\n\t\t\t\tsingleRes = calendar[options].apply(calendar, args);\n\t\t\t\tif (!i) {\n\t\t\t\t\tres = singleRes; // record the first method call result\n\t\t\t\t}\n\t\t\t\tif (options === 'destroy') { // for the destroy method, must remove Calendar object data\n\t\t\t\t\telement.removeData('fullCalendar');\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// a new calendar initialization\n\t\telse if (!calendar) { // don't initialize twice\n\t\t\tcalendar = new Calendar(element, options);\n\t\t\telement.data('fullCalendar', calendar);\n\t\t\tcalendar.render();\n\t\t}\n\t});\n\t\n\treturn res;\n};\n\n\n// function for adding/overriding defaults\nfunction setDefaults(d) {\n\tmergeOptions(defaults, d);\n}\n\n\n// Recursively combines option hash-objects.\n// Better than `$.extend(true, ...)` because arrays are not traversed/copied.\n//\n// called like:\n//     mergeOptions(target, obj1, obj2, ...)\n//\nfunction mergeOptions(target) {\n\n\tfunction mergeIntoTarget(name, value) {\n\t\tif ($.isPlainObject(value) && $.isPlainObject(target[name]) && !isForcedAtomicOption(name)) {\n\t\t\t// merge into a new object to avoid destruction\n\t\t\ttarget[name] = mergeOptions({}, target[name], value); // combine. `value` object takes precedence\n\t\t}\n\t\telse if (value !== undefined) { // only use values that are set and not undefined\n\t\t\ttarget[name] = value;\n\t\t}\n\t}\n\n\tfor (var i=1; i<arguments.length; i++) {\n\t\t$.each(arguments[i], mergeIntoTarget);\n\t}\n\n\treturn target;\n}\n\n\n// overcome sucky view-option-hash and option-merging behavior messing with options it shouldn't\nfunction isForcedAtomicOption(name) {\n\t// Any option that ends in \"Time\" or \"Duration\" is probably a Duration,\n\t// and these will commonly be specified as plain objects, which we don't want to mess up.\n\treturn /(Time|Duration)$/.test(name);\n}\n// FIX: find a different solution for view-option-hashes and have a whitelist\n// for options that can be recursively merged.\n\n    var langOptionHash = fc.langs = {}; // initialize and expose\n\n\n// TODO: document the structure and ordering of a FullCalendar lang file\n// TODO: rename everything \"lang\" to \"locale\", like what the moment project did\n\n\n// Initialize jQuery UI datepicker translations while using some of the translations\n// Will set this as the default language for datepicker.\nfc.datepickerLang = function(langCode, dpLangCode, dpOptions) {\n\n\t// get the FullCalendar internal option hash for this language. create if necessary\n\tvar fcOptions = langOptionHash[langCode] || (langOptionHash[langCode] = {});\n\n\t// transfer some simple options from datepicker to fc\n\tfcOptions.isRTL = dpOptions.isRTL;\n\tfcOptions.weekNumberTitle = dpOptions.weekHeader;\n\n\t// compute some more complex options from datepicker\n\t$.each(dpComputableOptions, function(name, func) {\n\t\tfcOptions[name] = func(dpOptions);\n\t});\n\n\t// is jQuery UI Datepicker is on the page?\n\tif ($.datepicker) {\n\n\t\t// Register the language data.\n\t\t// FullCalendar and MomentJS use language codes like \"pt-br\" but Datepicker\n\t\t// does it like \"pt-BR\" or if it doesn't have the language, maybe just \"pt\".\n\t\t// Make an alias so the language can be referenced either way.\n\t\t$.datepicker.regional[dpLangCode] =\n\t\t\t$.datepicker.regional[langCode] = // alias\n\t\t\t\tdpOptions;\n\n\t\t// Alias 'en' to the default language data. Do this every time.\n\t\t$.datepicker.regional.en = $.datepicker.regional[''];\n\n\t\t// Set as Datepicker's global defaults.\n\t\t$.datepicker.setDefaults(dpOptions);\n\t}\n};\n\n\n// Sets FullCalendar-specific translations. Will set the language as the global default.\nfc.lang = function(langCode, newFcOptions) {\n\tvar fcOptions;\n\tvar momOptions;\n\n\t// get the FullCalendar internal option hash for this language. create if necessary\n\tfcOptions = langOptionHash[langCode] || (langOptionHash[langCode] = {});\n\n\t// provided new options for this language? merge them in\n\tif (newFcOptions) {\n\t\tmergeOptions(fcOptions, newFcOptions);\n\t}\n\n\t// compute language options that weren't defined.\n\t// always do this. newFcOptions can be undefined when initializing from i18n file,\n\t// so no way to tell if this is an initialization or a default-setting.\n\tmomOptions = getMomentLocaleData(langCode); // will fall back to en\n\t$.each(momComputableOptions, function(name, func) {\n\t\tif (fcOptions[name] === undefined) {\n\t\t\tfcOptions[name] = func(momOptions, fcOptions);\n\t\t}\n\t});\n\n\t// set it as the default language for FullCalendar\n\tdefaults.lang = langCode;\n};\n\n\n// NOTE: can't guarantee any of these computations will run because not every language has datepicker\n// configs, so make sure there are English fallbacks for these in the defaults file.\nvar dpComputableOptions = {\n\n\tdefaultButtonText: function(dpOptions) {\n\t\treturn {\n\t\t\t// the translations sometimes wrongly contain HTML entities\n\t\t\tprev: stripHtmlEntities(dpOptions.prevText),\n\t\t\tnext: stripHtmlEntities(dpOptions.nextText),\n\t\t\ttoday: stripHtmlEntities(dpOptions.currentText)\n\t\t};\n\t},\n\n\t// Produces format strings like \"MMMM YYYY\" -> \"September 2014\"\n\tmonthYearFormat: function(dpOptions) {\n\t\treturn dpOptions.showMonthAfterYear ?\n\t\t\t'YYYY[' + dpOptions.yearSuffix + '] MMMM' :\n\t\t\t'MMMM YYYY[' + dpOptions.yearSuffix + ']';\n\t}\n\n};\n\nvar momComputableOptions = {\n\n\t// Produces format strings like \"ddd MM/DD\" -> \"Fri 12/10\"\n\tdayOfMonthFormat: function(momOptions, fcOptions) {\n\t\tvar format = momOptions.longDateFormat('l'); // for the format like \"M/D/YYYY\"\n\n\t\t// strip the year off the edge, as well as other misc non-whitespace chars\n\t\tformat = format.replace(/^Y+[^\\w\\s]*|[^\\w\\s]*Y+$/g, '');\n\n\t\tif (fcOptions.isRTL) {\n\t\t\tformat += ' ddd'; // for RTL, add day-of-week to end\n\t\t}\n\t\telse {\n\t\t\tformat = 'ddd ' + format; // for LTR, add day-of-week to beginning\n\t\t}\n\t\treturn format;\n\t},\n\n\t// Produces format strings like \"H(:mm)a\" -> \"6pm\" or \"6:30pm\"\n\tsmallTimeFormat: function(momOptions) {\n\t\treturn momOptions.longDateFormat('LT')\n\t\t\t.replace(':mm', '(:mm)')\n\t\t\t.replace(/(\\Wmm)$/, '($1)') // like above, but for foreign langs\n\t\t\t.replace(/\\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand\n\t},\n\n\t// Produces format strings like \"H(:mm)t\" -> \"6p\" or \"6:30p\"\n\textraSmallTimeFormat: function(momOptions) {\n\t\treturn momOptions.longDateFormat('LT')\n\t\t\t.replace(':mm', '(:mm)')\n\t\t\t.replace(/(\\Wmm)$/, '($1)') // like above, but for foreign langs\n\t\t\t.replace(/\\s*a$/i, 't'); // convert to AM/PM/am/pm to lowercase one-letter. remove any spaces beforehand\n\t},\n\n\t// Produces format strings like \"H:mm\" -> \"6:30\" (with no AM/PM)\n\tnoMeridiemTimeFormat: function(momOptions) {\n\t\treturn momOptions.longDateFormat('LT')\n\t\t\t.replace(/\\s*a$/i, ''); // remove trailing AM/PM\n\t}\n\n};\n\n\n// Returns moment's internal locale data. If doesn't exist, returns English.\n// Works with moment-pre-2.8\nfunction getMomentLocaleData(langCode) {\n\tvar func = moment.localeData || moment.langData;\n\treturn func.call(moment, langCode) ||\n\t\tfunc.call(moment, 'en'); // the newer localData could return null, so fall back to en\n}\n\n\n// Initialize English by forcing computation of moment-derived options.\n// Also, sets it as the default.\nfc.lang('en', englishDefaults);\n\n// exports\nfc.intersectionToSeg = intersectionToSeg;\nfc.applyAll = applyAll;\nfc.debounce = debounce;\n\n\n/* FullCalendar-specific DOM Utilities\n----------------------------------------------------------------------------------------------------------------------*/\n\n\n// Given the scrollbar widths of some other container, create borders/margins on rowEls in order to match the left\n// and right space that was offset by the scrollbars. A 1-pixel border first, then margin beyond that.\nfunction compensateScroll(rowEls, scrollbarWidths) {\n\tif (scrollbarWidths.left) {\n\t\trowEls.css({\n\t\t\t'border-left-width': 1,\n\t\t\t'margin-left': scrollbarWidths.left - 1\n\t\t});\n\t}\n\tif (scrollbarWidths.right) {\n\t\trowEls.css({\n\t\t\t'border-right-width': 1,\n\t\t\t'margin-right': scrollbarWidths.right - 1\n\t\t});\n\t}\n}\n\n\n// Undoes compensateScroll and restores all borders/margins\nfunction uncompensateScroll(rowEls) {\n\trowEls.css({\n\t\t'margin-left': '',\n\t\t'margin-right': '',\n\t\t'border-left-width': '',\n\t\t'border-right-width': ''\n\t});\n}\n\n\n// Make the mouse cursor express that an event is not allowed in the current area\nfunction disableCursor() {\n\t$('body').addClass('fc-not-allowed');\n}\n\n\n// Returns the mouse cursor to its original look\nfunction enableCursor() {\n\t$('body').removeClass('fc-not-allowed');\n}\n\n\n// Given a total available height to fill, have `els` (essentially child rows) expand to accomodate.\n// By default, all elements that are shorter than the recommended height are expanded uniformly, not considering\n// any other els that are already too tall. if `shouldRedistribute` is on, it considers these tall rows and \n// reduces the available height.\nfunction distributeHeight(els, availableHeight, shouldRedistribute) {\n\n\t// *FLOORING NOTE*: we floor in certain places because zoom can give inaccurate floating-point dimensions,\n\t// and it is better to be shorter than taller, to avoid creating unnecessary scrollbars.\n\n\tvar minOffset1 = Math.floor(availableHeight / els.length); // for non-last element\n\tvar minOffset2 = Math.floor(availableHeight - minOffset1 * (els.length - 1)); // for last element *FLOORING NOTE*\n\tvar flexEls = []; // elements that are allowed to expand. array of DOM nodes\n\tvar flexOffsets = []; // amount of vertical space it takes up\n\tvar flexHeights = []; // actual css height\n\tvar usedHeight = 0;\n\n\tundistributeHeight(els); // give all elements their natural height\n\n\t// find elements that are below the recommended height (expandable).\n\t// important to query for heights in a single first pass (to avoid reflow oscillation).\n\tels.each(function(i, el) {\n\t\tvar minOffset = i === els.length - 1 ? minOffset2 : minOffset1;\n\t\tvar naturalOffset = $(el).outerHeight(true);\n\n\t\tif (naturalOffset < minOffset) {\n\t\t\tflexEls.push(el);\n\t\t\tflexOffsets.push(naturalOffset);\n\t\t\tflexHeights.push($(el).height());\n\t\t}\n\t\telse {\n\t\t\t// this element stretches past recommended height (non-expandable). mark the space as occupied.\n\t\t\tusedHeight += naturalOffset;\n\t\t}\n\t});\n\n\t// readjust the recommended height to only consider the height available to non-maxed-out rows.\n\tif (shouldRedistribute) {\n\t\tavailableHeight -= usedHeight;\n\t\tminOffset1 = Math.floor(availableHeight / flexEls.length);\n\t\tminOffset2 = Math.floor(availableHeight - minOffset1 * (flexEls.length - 1)); // *FLOORING NOTE*\n\t}\n\n\t// assign heights to all expandable elements\n\t$(flexEls).each(function(i, el) {\n\t\tvar minOffset = i === flexEls.length - 1 ? minOffset2 : minOffset1;\n\t\tvar naturalOffset = flexOffsets[i];\n\t\tvar naturalHeight = flexHeights[i];\n\t\tvar newHeight = minOffset - (naturalOffset - naturalHeight); // subtract the margin/padding\n\n\t\tif (naturalOffset < minOffset) { // we check this again because redistribution might have changed things\n\t\t\t$(el).height(newHeight);\n\t\t}\n\t});\n}\n\n\n// Undoes distrubuteHeight, restoring all els to their natural height\nfunction undistributeHeight(els) {\n\tels.height('');\n}\n\n\n// Given `els`, a jQuery set of <td> cells, find the cell with the largest natural width and set the widths of all the\n// cells to be that width.\n// PREREQUISITE: if you want a cell to take up width, it needs to have a single inner element w/ display:inline\nfunction matchCellWidths(els) {\n\tvar maxInnerWidth = 0;\n\n\tels.find('> *').each(function(i, innerEl) {\n\t\tvar innerWidth = $(innerEl).outerWidth();\n\t\tif (innerWidth > maxInnerWidth) {\n\t\t\tmaxInnerWidth = innerWidth;\n\t\t}\n\t});\n\n\tmaxInnerWidth++; // sometimes not accurate of width the text needs to stay on one line. insurance\n\n\tels.width(maxInnerWidth);\n\n\treturn maxInnerWidth;\n}\n\n\n// Turns a container element into a scroller if its contents is taller than the allotted height.\n// Returns true if the element is now a scroller, false otherwise.\n// NOTE: this method is best because it takes weird zooming dimensions into account\nfunction setPotentialScroller(containerEl, height) {\n\tcontainerEl.height(height).addClass('fc-scroller');\n\n\t// are scrollbars needed?\n\tif (containerEl[0].scrollHeight - 1 > containerEl[0].clientHeight) { // !!! -1 because IE is often off-by-one :(\n\t\treturn true;\n\t}\n\n\tunsetScroller(containerEl); // undo\n\treturn false;\n}\n\n\n// Takes an element that might have been a scroller, and turns it back into a normal element.\nfunction unsetScroller(containerEl) {\n\tcontainerEl.height('').removeClass('fc-scroller');\n}\n\n\n/* General DOM Utilities\n----------------------------------------------------------------------------------------------------------------------*/\n\n\n// borrowed from https://github.com/jquery/jquery-ui/blob/1.11.0/ui/core.js#L51\nfunction getScrollParent(el) {\n\tvar position = el.css('position'),\n\t\tscrollParent = el.parents().filter(function() {\n\t\t\tvar parent = $(this);\n\t\t\treturn (/(auto|scroll)/).test(\n\t\t\t\tparent.css('overflow') + parent.css('overflow-y') + parent.css('overflow-x')\n\t\t\t);\n\t\t}).eq(0);\n\n\treturn position === 'fixed' || !scrollParent.length ? $(el[0].ownerDocument || document) : scrollParent;\n}\n\n\n// Given a container element, return an object with the pixel values of the left/right scrollbars.\n// Left scrollbars might occur on RTL browsers (IE maybe?) but I have not tested.\n// PREREQUISITE: container element must have a single child with display:block\nfunction getScrollbarWidths(container) {\n\tvar containerLeft = container.offset().left;\n\tvar containerRight = containerLeft + container.width();\n\tvar inner = container.children();\n\tvar innerLeft = inner.offset().left;\n\tvar innerRight = innerLeft + inner.outerWidth();\n\n\treturn {\n\t\tleft: innerLeft - containerLeft,\n\t\tright: containerRight - innerRight\n\t};\n}\n\n\n// Returns a boolean whether this was a left mouse click and no ctrl key (which means right click on Mac)\nfunction isPrimaryMouseButton(ev) {\n\treturn ev.which == 1 && !ev.ctrlKey;\n}\n\n\n/* FullCalendar-specific Misc Utilities\n----------------------------------------------------------------------------------------------------------------------*/\n\n\n// Creates a basic segment with the intersection of the two ranges. Returns undefined if no intersection.\n// Expects all dates to be normalized to the same timezone beforehand.\n// TODO: move to date section?\nfunction intersectionToSeg(subjectRange, constraintRange) {\n\tvar subjectStart = subjectRange.start;\n\tvar subjectEnd = subjectRange.end;\n\tvar constraintStart = constraintRange.start;\n\tvar constraintEnd = constraintRange.end;\n\tvar segStart, segEnd;\n\tvar isStart, isEnd;\n\n\tif (subjectEnd > constraintStart && subjectStart < constraintEnd) { // in bounds at all?\n\n\t\tif (subjectStart >= constraintStart) {\n\t\t\tsegStart = subjectStart.clone();\n\t\t\tisStart = true;\n\t\t}\n\t\telse {\n\t\t\tsegStart = constraintStart.clone();\n\t\t\tisStart =  false;\n\t\t}\n\n\t\tif (subjectEnd <= constraintEnd) {\n\t\t\tsegEnd = subjectEnd.clone();\n\t\t\tisEnd = true;\n\t\t}\n\t\telse {\n\t\t\tsegEnd = constraintEnd.clone();\n\t\t\tisEnd = false;\n\t\t}\n\n\t\treturn {\n\t\t\tstart: segStart,\n\t\t\tend: segEnd,\n\t\t\tisStart: isStart,\n\t\t\tisEnd: isEnd\n\t\t};\n\t}\n}\n\n\nfunction smartProperty(obj, name) { // get a camel-cased/namespaced property of an object\n\tobj = obj || {};\n\tif (obj[name] !== undefined) {\n\t\treturn obj[name];\n\t}\n\tvar parts = name.split(/(?=[A-Z])/),\n\t\ti = parts.length - 1, res;\n\tfor (; i>=0; i--) {\n\t\tres = obj[parts[i].toLowerCase()];\n\t\tif (res !== undefined) {\n\t\t\treturn res;\n\t\t}\n\t}\n\treturn obj['default'];\n}\n\n\n/* Date Utilities\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar dayIDs = [ 'sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat' ];\nvar intervalUnits = [ 'year', 'month', 'week', 'day', 'hour', 'minute', 'second', 'millisecond' ];\n\n\n// Diffs the two moments into a Duration where full-days are recorded first, then the remaining time.\n// Moments will have their timezones normalized.\nfunction diffDayTime(a, b) {\n\treturn moment.duration({\n\t\tdays: a.clone().stripTime().diff(b.clone().stripTime(), 'days'),\n\t\tms: a.time() - b.time() // time-of-day from day start. disregards timezone\n\t});\n}\n\n\n// Diffs the two moments via their start-of-day (regardless of timezone). Produces whole-day durations.\nfunction diffDay(a, b) {\n\treturn moment.duration({\n\t\tdays: a.clone().stripTime().diff(b.clone().stripTime(), 'days')\n\t});\n}\n\n\n// Computes the larges whole-unit period of time, as a duration object.\n// For example, 48 hours will be {days:2} whereas 49 hours will be {hours:49}.\n// Accepts start/end, a range object, or an original duration object.\n/* (never used)\nfunction computeIntervalDuration(start, end) {\n\tvar durationInput = {};\n\tvar i, unit;\n\tvar val;\n\n\tfor (i = 0; i < intervalUnits.length; i++) {\n\t\tunit = intervalUnits[i];\n\t\tval = computeIntervalAs(unit, start, end);\n\t\tif (val) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\tdurationInput[unit] = val;\n\treturn moment.duration(durationInput);\n}\n*/\n\n\n// Computes the unit name of the largest whole-unit period of time.\n// For example, 48 hours will be \"days\" wherewas 49 hours will be \"hours\".\n// Accepts start/end, a range object, or an original duration object.\nfunction computeIntervalUnit(start, end) {\n\tvar i, unit;\n\n\tfor (i = 0; i < intervalUnits.length; i++) {\n\t\tunit = intervalUnits[i];\n\t\tif (computeIntervalAs(unit, start, end)) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\treturn unit; // will be \"milliseconds\" if nothing else matches\n}\n\n\n// Computes the number of units the interval is cleanly comprised of.\n// If the given unit does not cleanly divide the interval a whole number of times, `false` is returned.\n// Accepts start/end, a range object, or an original duration object.\nfunction computeIntervalAs(unit, start, end) {\n\tvar val;\n\n\tif (end != null) { // given start, end\n\t\tval = end.diff(start, unit, true);\n\t}\n\telse if (moment.isDuration(start)) { // given duration\n\t\tval = start.as(unit);\n\t}\n\telse { // given { start, end } range object\n\t\tval = start.end.diff(start.start, unit, true);\n\t}\n\n\tif (val >= 1 && isInt(val)) {\n\t\treturn val;\n\t}\n\n\treturn false;\n}\n\n\nfunction isNativeDate(input) {\n\treturn  Object.prototype.toString.call(input) === '[object Date]' || input instanceof Date;\n}\n\n\n// Returns a boolean about whether the given input is a time string, like \"06:40:00\" or \"06:00\"\nfunction isTimeString(str) {\n\treturn /^\\d+\\:\\d+(?:\\:\\d+\\.?(?:\\d{3})?)?$/.test(str);\n}\n\n\n/* General Utilities\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar hasOwnPropMethod = {}.hasOwnProperty;\n\n\n// Create an object that has the given prototype. Just like Object.create\nfunction createObject(proto) {\n\tvar f = function() {};\n\tf.prototype = proto;\n\treturn new f();\n}\n\n\nfunction copyOwnProps(src, dest) {\n\tfor (var name in src) {\n\t\tif (hasOwnProp(src, name)) {\n\t\t\tdest[name] = src[name];\n\t\t}\n\t}\n}\n\n\nfunction hasOwnProp(obj, name) {\n\treturn hasOwnPropMethod.call(obj, name);\n}\n\n\n// Is the given value a non-object non-function value?\nfunction isAtomic(val) {\n\treturn /undefined|null|boolean|number|string/.test($.type(val));\n}\n\n\nfunction applyAll(functions, thisObj, args) {\n\tif ($.isFunction(functions)) {\n\t\tfunctions = [ functions ];\n\t}\n\tif (functions) {\n\t\tvar i;\n\t\tvar ret;\n\t\tfor (i=0; i<functions.length; i++) {\n\t\t\tret = functions[i].apply(thisObj, args) || ret;\n\t\t}\n\t\treturn ret;\n\t}\n}\n\n\nfunction firstDefined() {\n\tfor (var i=0; i<arguments.length; i++) {\n\t\tif (arguments[i] !== undefined) {\n\t\t\treturn arguments[i];\n\t\t}\n\t}\n}\n\n\nfunction htmlEscape(s) {\n\treturn (s + '').replace(/&/g, '&amp;')\n\t\t.replace(/</g, '&lt;')\n\t\t.replace(/>/g, '&gt;')\n\t\t.replace(/'/g, '&#039;')\n\t\t.replace(/\"/g, '&quot;')\n\t\t.replace(/\\n/g, '<br />');\n}\n\n\nfunction stripHtmlEntities(text) {\n\treturn text.replace(/&.*?;/g, '');\n}\n\n\nfunction capitaliseFirstLetter(str) {\n\treturn str.charAt(0).toUpperCase() + str.slice(1);\n}\n\n\nfunction compareNumbers(a, b) { // for .sort()\n\treturn a - b;\n}\n\n\nfunction isInt(n) {\n\treturn n % 1 === 0;\n}\n\n\n// Returns a function, that, as long as it continues to be invoked, will not\n// be triggered. The function will be called after it stops being called for\n// N milliseconds.\n// https://github.com/jashkenas/underscore/blob/1.6.0/underscore.js#L714\nfunction debounce(func, wait) {\n\tvar timeoutId;\n\tvar args;\n\tvar context;\n\tvar timestamp; // of most recent call\n\tvar later = function() {\n\t\tvar last = +new Date() - timestamp;\n\t\tif (last < wait && last > 0) {\n\t\t\ttimeoutId = setTimeout(later, wait - last);\n\t\t}\n\t\telse {\n\t\t\ttimeoutId = null;\n\t\t\tfunc.apply(context, args);\n\t\t\tif (!timeoutId) {\n\t\t\t\tcontext = args = null;\n\t\t\t}\n\t\t}\n\t};\n\n\treturn function() {\n\t\tcontext = this;\n\t\targs = arguments;\n\t\ttimestamp = +new Date();\n\t\tif (!timeoutId) {\n\t\t\ttimeoutId = setTimeout(later, wait);\n\t\t}\n\t};\n}\n\n    var ambigDateOfMonthRegex = /^\\s*\\d{4}-\\d\\d$/;\nvar ambigTimeOrZoneRegex =\n\t/^\\s*\\d{4}-(?:(\\d\\d-\\d\\d)|(W\\d\\d$)|(W\\d\\d-\\d)|(\\d\\d\\d))((T| )(\\d\\d(:\\d\\d(:\\d\\d(\\.\\d+)?)?)?)?)?$/;\nvar newMomentProto = moment.fn; // where we will attach our new methods\nvar oldMomentProto = $.extend({}, newMomentProto); // copy of original moment methods\nvar allowValueOptimization;\nvar setUTCValues; // function defined below\nvar setLocalValues; // function defined below\n\n\n// Creating\n// -------------------------------------------------------------------------------------------------\n\n// Creates a new moment, similar to the vanilla moment(...) constructor, but with\n// extra features (ambiguous time, enhanced formatting). When given an existing moment,\n// it will function as a clone (and retain the zone of the moment). Anything else will\n// result in a moment in the local zone.\nfc.moment = function() {\n\treturn makeMoment(arguments);\n};\n\n// Sames as fc.moment, but forces the resulting moment to be in the UTC timezone.\nfc.moment.utc = function() {\n\tvar mom = makeMoment(arguments, true);\n\n\t// Force it into UTC because makeMoment doesn't guarantee it\n\t// (if given a pre-existing moment for example)\n\tif (mom.hasTime()) { // don't give ambiguously-timed moments a UTC zone\n\t\tmom.utc();\n\t}\n\n\treturn mom;\n};\n\n// Same as fc.moment, but when given an ISO8601 string, the timezone offset is preserved.\n// ISO8601 strings with no timezone offset will become ambiguously zoned.\nfc.moment.parseZone = function() {\n\treturn makeMoment(arguments, true, true);\n};\n\n// Builds an enhanced moment from args. When given an existing moment, it clones. When given a\n// native Date, or called with no arguments (the current time), the resulting moment will be local.\n// Anything else needs to be \"parsed\" (a string or an array), and will be affected by:\n//    parseAsUTC - if there is no zone information, should we parse the input in UTC?\n//    parseZone - if there is zone information, should we force the zone of the moment?\nfunction makeMoment(args, parseAsUTC, parseZone) {\n\tvar input = args[0];\n\tvar isSingleString = args.length == 1 && typeof input === 'string';\n\tvar isAmbigTime;\n\tvar isAmbigZone;\n\tvar ambigMatch;\n\tvar mom;\n\n\tif (moment.isMoment(input)) {\n\t\tmom = moment.apply(null, args); // clone it\n\t\ttransferAmbigs(input, mom); // the ambig flags weren't transfered with the clone\n\t}\n\telse if (isNativeDate(input) || input === undefined) {\n\t\tmom = moment.apply(null, args); // will be local\n\t}\n\telse { // \"parsing\" is required\n\t\tisAmbigTime = false;\n\t\tisAmbigZone = false;\n\n\t\tif (isSingleString) {\n\t\t\tif (ambigDateOfMonthRegex.test(input)) {\n\t\t\t\t// accept strings like '2014-05', but convert to the first of the month\n\t\t\t\tinput += '-01';\n\t\t\t\targs = [ input ]; // for when we pass it on to moment's constructor\n\t\t\t\tisAmbigTime = true;\n\t\t\t\tisAmbigZone = true;\n\t\t\t}\n\t\t\telse if ((ambigMatch = ambigTimeOrZoneRegex.exec(input))) {\n\t\t\t\tisAmbigTime = !ambigMatch[5]; // no time part?\n\t\t\t\tisAmbigZone = true;\n\t\t\t}\n\t\t}\n\t\telse if ($.isArray(input)) {\n\t\t\t// arrays have no timezone information, so assume ambiguous zone\n\t\t\tisAmbigZone = true;\n\t\t}\n\t\t// otherwise, probably a string with a format\n\n\t\tif (parseAsUTC || isAmbigTime) {\n\t\t\tmom = moment.utc.apply(moment, args);\n\t\t}\n\t\telse {\n\t\t\tmom = moment.apply(null, args);\n\t\t}\n\n\t\tif (isAmbigTime) {\n\t\t\tmom._ambigTime = true;\n\t\t\tmom._ambigZone = true; // ambiguous time always means ambiguous zone\n\t\t}\n\t\telse if (parseZone) { // let's record the inputted zone somehow\n\t\t\tif (isAmbigZone) {\n\t\t\t\tmom._ambigZone = true;\n\t\t\t}\n\t\t\telse if (isSingleString) {\n\t\t\t\tmom.zone(input); // if not a valid zone, will assign UTC\n\t\t\t}\n\t\t}\n\t}\n\n\tmom._fullCalendar = true; // flag for extended functionality\n\n\treturn mom;\n}\n\n\n// A clone method that works with the flags related to our enhanced functionality.\n// In the future, use moment.momentProperties\nnewMomentProto.clone = function() {\n\tvar mom = oldMomentProto.clone.apply(this, arguments);\n\n\t// these flags weren't transfered with the clone\n\ttransferAmbigs(this, mom);\n\tif (this._fullCalendar) {\n\t\tmom._fullCalendar = true;\n\t}\n\n\treturn mom;\n};\n\n\n// Time-of-day\n// -------------------------------------------------------------------------------------------------\n\n// GETTER\n// Returns a Duration with the hours/minutes/seconds/ms values of the moment.\n// If the moment has an ambiguous time, a duration of 00:00 will be returned.\n//\n// SETTER\n// You can supply a Duration, a Moment, or a Duration-like argument.\n// When setting the time, and the moment has an ambiguous time, it then becomes unambiguous.\nnewMomentProto.time = function(time) {\n\n\t// Fallback to the original method (if there is one) if this moment wasn't created via FullCalendar.\n\t// `time` is a generic enough method name where this precaution is necessary to avoid collisions w/ other plugins.\n\tif (!this._fullCalendar) {\n\t\treturn oldMomentProto.time.apply(this, arguments);\n\t}\n\n\tif (time == null) { // getter\n\t\treturn moment.duration({\n\t\t\thours: this.hours(),\n\t\t\tminutes: this.minutes(),\n\t\t\tseconds: this.seconds(),\n\t\t\tmilliseconds: this.milliseconds()\n\t\t});\n\t}\n\telse { // setter\n\n\t\tthis._ambigTime = false; // mark that the moment now has a time\n\n\t\tif (!moment.isDuration(time) && !moment.isMoment(time)) {\n\t\t\ttime = moment.duration(time);\n\t\t}\n\n\t\t// The day value should cause overflow (so 24 hours becomes 00:00:00 of next day).\n\t\t// Only for Duration times, not Moment times.\n\t\tvar dayHours = 0;\n\t\tif (moment.isDuration(time)) {\n\t\t\tdayHours = Math.floor(time.asDays()) * 24;\n\t\t}\n\n\t\t// We need to set the individual fields.\n\t\t// Can't use startOf('day') then add duration. In case of DST at start of day.\n\t\treturn this.hours(dayHours + time.hours())\n\t\t\t.minutes(time.minutes())\n\t\t\t.seconds(time.seconds())\n\t\t\t.milliseconds(time.milliseconds());\n\t}\n};\n\n// Converts the moment to UTC, stripping out its time-of-day and timezone offset,\n// but preserving its YMD. A moment with a stripped time will display no time\n// nor timezone offset when .format() is called.\nnewMomentProto.stripTime = function() {\n\tvar a;\n\n\tif (!this._ambigTime) {\n\n\t\t// get the values before any conversion happens\n\t\ta = this.toArray(); // array of y/m/d/h/m/s/ms\n\n\t\tthis.utc(); // set the internal UTC flag (will clear the ambig flags)\n\t\tsetUTCValues(this, a.slice(0, 3)); // set the year/month/date. time will be zero\n\n\t\t// Mark the time as ambiguous. This needs to happen after the .utc() call, which calls .zone(),\n\t\t// which clears all ambig flags. Same with setUTCValues with moment-timezone.\n\t\tthis._ambigTime = true;\n\t\tthis._ambigZone = true; // if ambiguous time, also ambiguous timezone offset\n\t}\n\n\treturn this; // for chaining\n};\n\n// Returns if the moment has a non-ambiguous time (boolean)\nnewMomentProto.hasTime = function() {\n\treturn !this._ambigTime;\n};\n\n\n// Timezone\n// -------------------------------------------------------------------------------------------------\n\n// Converts the moment to UTC, stripping out its timezone offset, but preserving its\n// YMD and time-of-day. A moment with a stripped timezone offset will display no\n// timezone offset when .format() is called.\nnewMomentProto.stripZone = function() {\n\tvar a, wasAmbigTime;\n\n\tif (!this._ambigZone) {\n\n\t\t// get the values before any conversion happens\n\t\ta = this.toArray(); // array of y/m/d/h/m/s/ms\n\t\twasAmbigTime = this._ambigTime;\n\n\t\tthis.utc(); // set the internal UTC flag (will clear the ambig flags)\n\t\tsetUTCValues(this, a); // will set the year/month/date/hours/minutes/seconds/ms\n\n\t\tif (wasAmbigTime) {\n\t\t\t// the above call to .utc()/.zone() unfortunately clears the ambig flags, so reassign\n\t\t\tthis._ambigTime = true;\n\t\t}\n\n\t\t// Mark the zone as ambiguous. This needs to happen after the .utc() call, which calls .zone(),\n\t\t// which clears all ambig flags. Same with setUTCValues with moment-timezone.\n\t\tthis._ambigZone = true;\n\t}\n\n\treturn this; // for chaining\n};\n\n// Returns of the moment has a non-ambiguous timezone offset (boolean)\nnewMomentProto.hasZone = function() {\n\treturn !this._ambigZone;\n};\n\n// this method implicitly marks a zone (will get called upon .utc() and .local())\nnewMomentProto.zone = function(tzo) {\n\n\tif (tzo != null) { // setter\n\t\t// these assignments needs to happen before the original zone method is called.\n\t\t// I forget why, something to do with a browser crash.\n\t\tthis._ambigTime = false;\n\t\tthis._ambigZone = false;\n\t}\n\n\treturn oldMomentProto.zone.apply(this, arguments);\n};\n\n// this method implicitly marks a zone\nnewMomentProto.local = function() {\n\tvar a = this.toArray(); // year,month,date,hours,minutes,seconds,ms as an array\n\tvar wasAmbigZone = this._ambigZone;\n\n\toldMomentProto.local.apply(this, arguments); // will clear ambig flags\n\n\tif (wasAmbigZone) {\n\t\t// If the moment was ambiguously zoned, the date fields were stored as UTC.\n\t\t// We want to preserve these, but in local time.\n\t\tsetLocalValues(this, a);\n\t}\n\n\treturn this; // for chaining\n};\n\n\n// Formatting\n// -------------------------------------------------------------------------------------------------\n\nnewMomentProto.format = function() {\n\tif (this._fullCalendar && arguments[0]) { // an enhanced moment? and a format string provided?\n\t\treturn formatDate(this, arguments[0]); // our extended formatting\n\t}\n\tif (this._ambigTime) {\n\t\treturn oldMomentFormat(this, 'YYYY-MM-DD');\n\t}\n\tif (this._ambigZone) {\n\t\treturn oldMomentFormat(this, 'YYYY-MM-DD[T]HH:mm:ss');\n\t}\n\treturn oldMomentProto.format.apply(this, arguments);\n};\n\nnewMomentProto.toISOString = function() {\n\tif (this._ambigTime) {\n\t\treturn oldMomentFormat(this, 'YYYY-MM-DD');\n\t}\n\tif (this._ambigZone) {\n\t\treturn oldMomentFormat(this, 'YYYY-MM-DD[T]HH:mm:ss');\n\t}\n\treturn oldMomentProto.toISOString.apply(this, arguments);\n};\n\n\n// Querying\n// -------------------------------------------------------------------------------------------------\n\n// Is the moment within the specified range? `end` is exclusive.\n// FYI, this method is not a standard Moment method, so always do our enhanced logic.\nnewMomentProto.isWithin = function(start, end) {\n\tvar a = commonlyAmbiguate([ this, start, end ]);\n\treturn a[0] >= a[1] && a[0] < a[2];\n};\n\n// When isSame is called with units, timezone ambiguity is normalized before the comparison happens.\n// If no units specified, the two moments must be identically the same, with matching ambig flags.\nnewMomentProto.isSame = function(input, units) {\n\tvar a;\n\n\t// only do custom logic if this is an enhanced moment\n\tif (!this._fullCalendar) {\n\t\treturn oldMomentProto.isSame.apply(this, arguments);\n\t}\n\n\tif (units) {\n\t\ta = commonlyAmbiguate([ this, input ], true); // normalize timezones but don't erase times\n\t\treturn oldMomentProto.isSame.call(a[0], a[1], units);\n\t}\n\telse {\n\t\tinput = fc.moment.parseZone(input); // normalize input\n\t\treturn oldMomentProto.isSame.call(this, input) &&\n\t\t\tBoolean(this._ambigTime) === Boolean(input._ambigTime) &&\n\t\t\tBoolean(this._ambigZone) === Boolean(input._ambigZone);\n\t}\n};\n\n// Make these query methods work with ambiguous moments\n$.each([\n\t'isBefore',\n\t'isAfter'\n], function(i, methodName) {\n\tnewMomentProto[methodName] = function(input, units) {\n\t\tvar a;\n\n\t\t// only do custom logic if this is an enhanced moment\n\t\tif (!this._fullCalendar) {\n\t\t\treturn oldMomentProto[methodName].apply(this, arguments);\n\t\t}\n\n\t\ta = commonlyAmbiguate([ this, input ]);\n\t\treturn oldMomentProto[methodName].call(a[0], a[1], units);\n\t};\n});\n\n\n// Misc Internals\n// -------------------------------------------------------------------------------------------------\n\n// given an array of moment-like inputs, return a parallel array w/ moments similarly ambiguated.\n// for example, of one moment has ambig time, but not others, all moments will have their time stripped.\n// set `preserveTime` to `true` to keep times, but only normalize zone ambiguity.\n// returns the original moments if no modifications are necessary.\nfunction commonlyAmbiguate(inputs, preserveTime) {\n\tvar anyAmbigTime = false;\n\tvar anyAmbigZone = false;\n\tvar len = inputs.length;\n\tvar moms = [];\n\tvar i, mom;\n\n\t// parse inputs into real moments and query their ambig flags\n\tfor (i = 0; i < len; i++) {\n\t\tmom = inputs[i];\n\t\tif (!moment.isMoment(mom)) {\n\t\t\tmom = fc.moment.parseZone(mom);\n\t\t}\n\t\tanyAmbigTime = anyAmbigTime || mom._ambigTime;\n\t\tanyAmbigZone = anyAmbigZone || mom._ambigZone;\n\t\tmoms.push(mom);\n\t}\n\n\t// strip each moment down to lowest common ambiguity\n\t// use clones to avoid modifying the original moments\n\tfor (i = 0; i < len; i++) {\n\t\tmom = moms[i];\n\t\tif (!preserveTime && anyAmbigTime && !mom._ambigTime) {\n\t\t\tmoms[i] = mom.clone().stripTime();\n\t\t}\n\t\telse if (anyAmbigZone && !mom._ambigZone) {\n\t\t\tmoms[i] = mom.clone().stripZone();\n\t\t}\n\t}\n\n\treturn moms;\n}\n\n// Transfers all the flags related to ambiguous time/zone from the `src` moment to the `dest` moment\nfunction transferAmbigs(src, dest) {\n\tif (src._ambigTime) {\n\t\tdest._ambigTime = true;\n\t}\n\telse if (dest._ambigTime) {\n\t\tdest._ambigTime = false;\n\t}\n\n\tif (src._ambigZone) {\n\t\tdest._ambigZone = true;\n\t}\n\telse if (dest._ambigZone) {\n\t\tdest._ambigZone = false;\n\t}\n}\n\n\n// Sets the year/month/date/etc values of the moment from the given array.\n// Inefficient because it calls each individual setter.\nfunction setMomentValues(mom, a) {\n\tmom.year(a[0] || 0)\n\t\t.month(a[1] || 0)\n\t\t.date(a[2] || 0)\n\t\t.hours(a[3] || 0)\n\t\t.minutes(a[4] || 0)\n\t\t.seconds(a[5] || 0)\n\t\t.milliseconds(a[6] || 0);\n}\n\n// Can we set the moment's internal date directly?\nallowValueOptimization = '_d' in moment() && 'updateOffset' in moment;\n\n// Utility function. Accepts a moment and an array of the UTC year/month/date/etc values to set.\n// Assumes the given moment is already in UTC mode.\nsetUTCValues = allowValueOptimization ? function(mom, a) {\n\t// simlate what moment's accessors do\n\tmom._d.setTime(Date.UTC.apply(Date, a));\n\tmoment.updateOffset(mom, false); // keepTime=false\n} : setMomentValues;\n\n// Utility function. Accepts a moment and an array of the local year/month/date/etc values to set.\n// Assumes the given moment is already in local mode.\nsetLocalValues = allowValueOptimization ? function(mom, a) {\n\t// simlate what moment's accessors do\n\tmom._d.setTime(+new Date( // FYI, there is now way to apply an array of args to a constructor\n\t\ta[0] || 0,\n\t\ta[1] || 0,\n\t\ta[2] || 0,\n\t\ta[3] || 0,\n\t\ta[4] || 0,\n\t\ta[5] || 0,\n\t\ta[6] || 0\n\t));\n\tmoment.updateOffset(mom, false); // keepTime=false\n} : setMomentValues;\n\n// Single Date Formatting\n// -------------------------------------------------------------------------------------------------\n\n\n// call this if you want Moment's original format method to be used\nfunction oldMomentFormat(mom, formatStr) {\n\treturn oldMomentProto.format.call(mom, formatStr); // oldMomentProto defined in moment-ext.js\n}\n\n\n// Formats `date` with a Moment formatting string, but allow our non-zero areas and\n// additional token.\nfunction formatDate(date, formatStr) {\n\treturn formatDateWithChunks(date, getFormatStringChunks(formatStr));\n}\n\n\nfunction formatDateWithChunks(date, chunks) {\n\tvar s = '';\n\tvar i;\n\n\tfor (i=0; i<chunks.length; i++) {\n\t\ts += formatDateWithChunk(date, chunks[i]);\n\t}\n\n\treturn s;\n}\n\n\n// addition formatting tokens we want recognized\nvar tokenOverrides = {\n\tt: function(date) { // \"a\" or \"p\"\n\t\treturn oldMomentFormat(date, 'a').charAt(0);\n\t},\n\tT: function(date) { // \"A\" or \"P\"\n\t\treturn oldMomentFormat(date, 'A').charAt(0);\n\t}\n};\n\n\nfunction formatDateWithChunk(date, chunk) {\n\tvar token;\n\tvar maybeStr;\n\n\tif (typeof chunk === 'string') { // a literal string\n\t\treturn chunk;\n\t}\n\telse if ((token = chunk.token)) { // a token, like \"YYYY\"\n\t\tif (tokenOverrides[token]) {\n\t\t\treturn tokenOverrides[token](date); // use our custom token\n\t\t}\n\t\treturn oldMomentFormat(date, token);\n\t}\n\telse if (chunk.maybe) { // a grouping of other chunks that must be non-zero\n\t\tmaybeStr = formatDateWithChunks(date, chunk.maybe);\n\t\tif (maybeStr.match(/[1-9]/)) {\n\t\t\treturn maybeStr;\n\t\t}\n\t}\n\n\treturn '';\n}\n\n\n// Date Range Formatting\n// -------------------------------------------------------------------------------------------------\n// TODO: make it work with timezone offset\n\n// Using a formatting string meant for a single date, generate a range string, like\n// \"Sep 2 - 9 2013\", that intelligently inserts a separator where the dates differ.\n// If the dates are the same as far as the format string is concerned, just return a single\n// rendering of one date, without any separator.\nfunction formatRange(date1, date2, formatStr, separator, isRTL) {\n\tvar localeData;\n\n\tdate1 = fc.moment.parseZone(date1);\n\tdate2 = fc.moment.parseZone(date2);\n\n\tlocaleData = (date1.localeData || date1.lang).call(date1); // works with moment-pre-2.8\n\n\t// Expand localized format strings, like \"LL\" -> \"MMMM D YYYY\"\n\tformatStr = localeData.longDateFormat(formatStr) || formatStr;\n\t// BTW, this is not important for `formatDate` because it is impossible to put custom tokens\n\t// or non-zero areas in Moment's localized format strings.\n\n\tseparator = separator || ' - ';\n\n\treturn formatRangeWithChunks(\n\t\tdate1,\n\t\tdate2,\n\t\tgetFormatStringChunks(formatStr),\n\t\tseparator,\n\t\tisRTL\n\t);\n}\nfc.formatRange = formatRange; // expose\n\n\nfunction formatRangeWithChunks(date1, date2, chunks, separator, isRTL) {\n\tvar chunkStr; // the rendering of the chunk\n\tvar leftI;\n\tvar leftStr = '';\n\tvar rightI;\n\tvar rightStr = '';\n\tvar middleI;\n\tvar middleStr1 = '';\n\tvar middleStr2 = '';\n\tvar middleStr = '';\n\n\t// Start at the leftmost side of the formatting string and continue until you hit a token\n\t// that is not the same between dates.\n\tfor (leftI=0; leftI<chunks.length; leftI++) {\n\t\tchunkStr = formatSimilarChunk(date1, date2, chunks[leftI]);\n\t\tif (chunkStr === false) {\n\t\t\tbreak;\n\t\t}\n\t\tleftStr += chunkStr;\n\t}\n\n\t// Similarly, start at the rightmost side of the formatting string and move left\n\tfor (rightI=chunks.length-1; rightI>leftI; rightI--) {\n\t\tchunkStr = formatSimilarChunk(date1, date2, chunks[rightI]);\n\t\tif (chunkStr === false) {\n\t\t\tbreak;\n\t\t}\n\t\trightStr = chunkStr + rightStr;\n\t}\n\n\t// The area in the middle is different for both of the dates.\n\t// Collect them distinctly so we can jam them together later.\n\tfor (middleI=leftI; middleI<=rightI; middleI++) {\n\t\tmiddleStr1 += formatDateWithChunk(date1, chunks[middleI]);\n\t\tmiddleStr2 += formatDateWithChunk(date2, chunks[middleI]);\n\t}\n\n\tif (middleStr1 || middleStr2) {\n\t\tif (isRTL) {\n\t\t\tmiddleStr = middleStr2 + separator + middleStr1;\n\t\t}\n\t\telse {\n\t\t\tmiddleStr = middleStr1 + separator + middleStr2;\n\t\t}\n\t}\n\n\treturn leftStr + middleStr + rightStr;\n}\n\n\nvar similarUnitMap = {\n\tY: 'year',\n\tM: 'month',\n\tD: 'day', // day of month\n\td: 'day', // day of week\n\t// prevents a separator between anything time-related...\n\tA: 'second', // AM/PM\n\ta: 'second', // am/pm\n\tT: 'second', // A/P\n\tt: 'second', // a/p\n\tH: 'second', // hour (24)\n\th: 'second', // hour (12)\n\tm: 'second', // minute\n\ts: 'second' // second\n};\n// TODO: week maybe?\n\n\n// Given a formatting chunk, and given that both dates are similar in the regard the\n// formatting chunk is concerned, format date1 against `chunk`. Otherwise, return `false`.\nfunction formatSimilarChunk(date1, date2, chunk) {\n\tvar token;\n\tvar unit;\n\n\tif (typeof chunk === 'string') { // a literal string\n\t\treturn chunk;\n\t}\n\telse if ((token = chunk.token)) {\n\t\tunit = similarUnitMap[token.charAt(0)];\n\t\t// are the dates the same for this unit of measurement?\n\t\tif (unit && date1.isSame(date2, unit)) {\n\t\t\treturn oldMomentFormat(date1, token); // would be the same if we used `date2`\n\t\t\t// BTW, don't support custom tokens\n\t\t}\n\t}\n\n\treturn false; // the chunk is NOT the same for the two dates\n\t// BTW, don't support splitting on non-zero areas\n}\n\n\n// Chunking Utils\n// -------------------------------------------------------------------------------------------------\n\n\nvar formatStringChunkCache = {};\n\n\nfunction getFormatStringChunks(formatStr) {\n\tif (formatStr in formatStringChunkCache) {\n\t\treturn formatStringChunkCache[formatStr];\n\t}\n\treturn (formatStringChunkCache[formatStr] = chunkFormatString(formatStr));\n}\n\n\n// Break the formatting string into an array of chunks\nfunction chunkFormatString(formatStr) {\n\tvar chunks = [];\n\tvar chunker = /\\[([^\\]]*)\\]|\\(([^\\)]*)\\)|(LT|(\\w)\\4*o?)|([^\\w\\[\\(]+)/g; // TODO: more descrimination\n\tvar match;\n\n\twhile ((match = chunker.exec(formatStr))) {\n\t\tif (match[1]) { // a literal string inside [ ... ]\n\t\t\tchunks.push(match[1]);\n\t\t}\n\t\telse if (match[2]) { // non-zero formatting inside ( ... )\n\t\t\tchunks.push({ maybe: chunkFormatString(match[2]) });\n\t\t}\n\t\telse if (match[3]) { // a formatting token\n\t\t\tchunks.push({ token: match[3] });\n\t\t}\n\t\telse if (match[5]) { // an unenclosed literal string\n\t\t\tchunks.push(match[5]);\n\t\t}\n\t}\n\n\treturn chunks;\n}\n\n    fc.Class = Class; // export\n\n// class that all other classes will inherit from\nfunction Class() { }\n\n// called upon a class to create a subclass\nClass.extend = function(members) {\n\tvar superClass = this;\n\tvar subClass;\n\n\tmembers = members || {};\n\n\t// ensure a constructor for the subclass, forwarding all arguments to the super-constructor if it doesn't exist\n\tif (hasOwnProp(members, 'constructor')) {\n\t\tsubClass = members.constructor;\n\t}\n\tif (typeof subClass !== 'function') {\n\t\tsubClass = members.constructor = function() {\n\t\t\tsuperClass.apply(this, arguments);\n\t\t};\n\t}\n\n\t// build the base prototype for the subclass, which is an new object chained to the superclass's prototype\n\tsubClass.prototype = createObject(superClass.prototype);\n\n\t// copy each member variable/method onto the the subclass's prototype\n\tcopyOwnProps(members, subClass.prototype);\n\n\t// copy over all class variables/methods to the subclass, such as `extend` and `mixin`\n\tcopyOwnProps(superClass, subClass);\n\n\treturn subClass;\n};\n\n// adds new member variables/methods to the class's prototype.\n// can be called with another class, or a plain object hash containing new members.\nClass.mixin = function(members) {\n\tcopyOwnProps(members.prototype || members, this.prototype);\n};\n    /* A rectangular panel that is absolutely positioned over other content\n------------------------------------------------------------------------------------------------------------------------\nOptions:\n\t- className (string)\n\t- content (HTML string or jQuery element set)\n\t- parentEl\n\t- top\n\t- left\n\t- right (the x coord of where the right edge should be. not a \"CSS\" right)\n\t- autoHide (boolean)\n\t- show (callback)\n\t- hide (callback)\n*/\n\nvar Popover = Class.extend({\n\n\tisHidden: true,\n\toptions: null,\n\tel: null, // the container element for the popover. generated by this object\n\tdocumentMousedownProxy: null, // document mousedown handler bound to `this`\n\tmargin: 10, // the space required between the popover and the edges of the scroll container\n\n\n\tconstructor: function(options) {\n\t\tthis.options = options || {};\n\t},\n\n\n\t// Shows the popover on the specified position. Renders it if not already\n\tshow: function() {\n\t\tif (this.isHidden) {\n\t\t\tif (!this.el) {\n\t\t\t\tthis.render();\n\t\t\t}\n\t\t\tthis.el.show();\n\t\t\tthis.position();\n\t\t\tthis.isHidden = false;\n\t\t\tthis.trigger('show');\n\t\t}\n\t},\n\n\n\t// Hides the popover, through CSS, but does not remove it from the DOM\n\thide: function() {\n\t\tif (!this.isHidden) {\n\t\t\tthis.el.hide();\n\t\t\tthis.isHidden = true;\n\t\t\tthis.trigger('hide');\n\t\t}\n\t},\n\n\n\t// Creates `this.el` and renders content inside of it\n\trender: function() {\n\t\tvar _this = this;\n\t\tvar options = this.options;\n\n\t\tthis.el = $('<div class=\"fc-popover\"/>')\n\t\t\t.addClass(options.className || '')\n\t\t\t.css({\n\t\t\t\t// position initially to the top left to avoid creating scrollbars\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0\n\t\t\t})\n\t\t\t.append(options.content)\n\t\t\t.appendTo(options.parentEl);\n\n\t\t// when a click happens on anything inside with a 'fc-close' className, hide the popover\n\t\tthis.el.on('click', '.fc-close', function() {\n\t\t\t_this.hide();\n\t\t});\n\n\t\tif (options.autoHide) {\n\t\t\t$(document).on('mousedown', this.documentMousedownProxy = $.proxy(this, 'documentMousedown'));\n\t\t}\n\t},\n\n\n\t// Triggered when the user clicks *anywhere* in the document, for the autoHide feature\n\tdocumentMousedown: function(ev) {\n\t\t// only hide the popover if the click happened outside the popover\n\t\tif (this.el && !$(ev.target).closest(this.el).length) {\n\t\t\tthis.hide();\n\t\t}\n\t},\n\n\n\t// Hides and unregisters any handlers\n\tdestroy: function() {\n\t\tthis.hide();\n\n\t\tif (this.el) {\n\t\t\tthis.el.remove();\n\t\t\tthis.el = null;\n\t\t}\n\n\t\t$(document).off('mousedown', this.documentMousedownProxy);\n\t},\n\n\n\t// Positions the popover optimally, using the top/left/right options\n\tposition: function() {\n\t\tvar options = this.options;\n\t\tvar origin = this.el.offsetParent().offset();\n\t\tvar width = this.el.outerWidth();\n\t\tvar height = this.el.outerHeight();\n\t\tvar windowEl = $(window);\n\t\tvar viewportEl = getScrollParent(this.el);\n\t\tvar viewportTop;\n\t\tvar viewportLeft;\n\t\tvar viewportOffset;\n\t\tvar top; // the \"position\" (not \"offset\") values for the popover\n\t\tvar left; //\n\n\t\t// compute top and left\n\t\ttop = options.top || 0;\n\t\tif (options.left !== undefined) {\n\t\t\tleft = options.left;\n\t\t}\n\t\telse if (options.right !== undefined) {\n\t\t\tleft = options.right - width; // derive the left value from the right value\n\t\t}\n\t\telse {\n\t\t\tleft = 0;\n\t\t}\n\n\t\tif (viewportEl.is(window) || viewportEl.is(document)) { // normalize getScrollParent's result\n\t\t\tviewportEl = windowEl;\n\t\t\tviewportTop = 0; // the window is always at the top left\n\t\t\tviewportLeft = 0; // (and .offset() won't work if called here)\n\t\t}\n\t\telse {\n\t\t\tviewportOffset = viewportEl.offset();\n\t\t\tviewportTop = viewportOffset.top;\n\t\t\tviewportLeft = viewportOffset.left;\n\t\t}\n\n\t\t// if the window is scrolled, it causes the visible area to be further down\n\t\tviewportTop += windowEl.scrollTop();\n\t\tviewportLeft += windowEl.scrollLeft();\n\n\t\t// constrain to the view port. if constrained by two edges, give precedence to top/left\n\t\tif (options.viewportConstrain !== false) {\n\t\t\ttop = Math.min(top, viewportTop + viewportEl.outerHeight() - height - this.margin);\n\t\t\ttop = Math.max(top, viewportTop + this.margin);\n\t\t\tleft = Math.min(left, viewportLeft + viewportEl.outerWidth() - width - this.margin);\n\t\t\tleft = Math.max(left, viewportLeft + this.margin);\n\t\t}\n\n\t\tthis.el.css({\n\t\t\ttop: top - origin.top,\n\t\t\tleft: left - origin.left\n\t\t});\n\t},\n\n\n\t// Triggers a callback. Calls a function in the option hash of the same name.\n\t// Arguments beyond the first `name` are forwarded on.\n\t// TODO: better code reuse for this. Repeat code\n\ttrigger: function(name) {\n\t\tif (this.options[name]) {\n\t\t\tthis.options[name].apply(this, Array.prototype.slice.call(arguments, 1));\n\t\t}\n\t}\n\n});\n\n    /* A \"coordinate map\" converts pixel coordinates into an associated cell, which has an associated date\n------------------------------------------------------------------------------------------------------------------------\nCommon interface:\n\n\tCoordMap.prototype = {\n\t\tbuild: function() {},\n\t\tgetCell: function(x, y) {}\n\t};\n\n*/\n\n/* Coordinate map for a grid component\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar GridCoordMap = Class.extend({\n\n\tgrid: null, // reference to the Grid\n\trowCoords: null, // array of {top,bottom} objects\n\tcolCoords: null, // array of {left,right} objects\n\n\tcontainerEl: null, // container element that all coordinates are constrained to. optionally assigned\n\tminX: null,\n\tmaxX: null, // exclusive\n\tminY: null,\n\tmaxY: null, // exclusive\n\n\n\tconstructor: function(grid) {\n\t\tthis.grid = grid;\n\t},\n\n\n\t// Queries the grid for the coordinates of all the cells\n\tbuild: function() {\n\t\tthis.rowCoords = this.grid.computeRowCoords();\n\t\tthis.colCoords = this.grid.computeColCoords();\n\t\tthis.computeBounds();\n\t},\n\n\n\t// Clears the coordinates data to free up memory\n\tclear: function() {\n\t\tthis.rowCoords = null;\n\t\tthis.colCoords = null;\n\t},\n\n\n\t// Given a coordinate of the document, gets the associated cell. If no cell is underneath, returns null\n\tgetCell: function(x, y) {\n\t\tvar rowCoords = this.rowCoords;\n\t\tvar colCoords = this.colCoords;\n\t\tvar hitRow = null;\n\t\tvar hitCol = null;\n\t\tvar i, coords;\n\t\tvar cell;\n\n\t\tif (this.inBounds(x, y)) {\n\n\t\t\tfor (i = 0; i < rowCoords.length; i++) {\n\t\t\t\tcoords = rowCoords[i];\n\t\t\t\tif (y >= coords.top && y < coords.bottom) {\n\t\t\t\t\thitRow = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor (i = 0; i < colCoords.length; i++) {\n\t\t\t\tcoords = colCoords[i];\n\t\t\t\tif (x >= coords.left && x < coords.right) {\n\t\t\t\t\thitCol = i;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (hitRow !== null && hitCol !== null) {\n\t\t\t\tcell = this.grid.getCell(hitRow, hitCol);\n\t\t\t\tcell.grid = this.grid; // for DragListener's isCellsEqual. dragging between grids\n\t\t\t\treturn cell;\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t},\n\n\n\t// If there is a containerEl, compute the bounds into min/max values\n\tcomputeBounds: function() {\n\t\tvar containerOffset;\n\n\t\tif (this.containerEl) {\n\t\t\tcontainerOffset = this.containerEl.offset();\n\t\t\tthis.minX = containerOffset.left;\n\t\t\tthis.maxX = containerOffset.left + this.containerEl.outerWidth();\n\t\t\tthis.minY = containerOffset.top;\n\t\t\tthis.maxY = containerOffset.top + this.containerEl.outerHeight();\n\t\t}\n\t},\n\n\n\t// Determines if the given coordinates are in bounds. If no `containerEl`, always true\n\tinBounds: function(x, y) {\n\t\tif (this.containerEl) {\n\t\t\treturn x >= this.minX && x < this.maxX && y >= this.minY && y < this.maxY;\n\t\t}\n\t\treturn true;\n\t}\n\n});\n\n\n/* Coordinate map that is a combination of multiple other coordinate maps\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar ComboCoordMap = Class.extend({\n\n\tcoordMaps: null, // an array of CoordMaps\n\n\n\tconstructor: function(coordMaps) {\n\t\tthis.coordMaps = coordMaps;\n\t},\n\n\n\t// Builds all coordMaps\n\tbuild: function() {\n\t\tvar coordMaps = this.coordMaps;\n\t\tvar i;\n\n\t\tfor (i = 0; i < coordMaps.length; i++) {\n\t\t\tcoordMaps[i].build();\n\t\t}\n\t},\n\n\n\t// Queries all coordMaps for the cell underneath the given coordinates, returning the first result\n\tgetCell: function(x, y) {\n\t\tvar coordMaps = this.coordMaps;\n\t\tvar cell = null;\n\t\tvar i;\n\n\t\tfor (i = 0; i < coordMaps.length && !cell; i++) {\n\t\t\tcell = coordMaps[i].getCell(x, y);\n\t\t}\n\n\t\treturn cell;\n\t},\n\n\n\t// Clears all coordMaps\n\tclear: function() {\n\t\tvar coordMaps = this.coordMaps;\n\t\tvar i;\n\n\t\tfor (i = 0; i < coordMaps.length; i++) {\n\t\t\tcoordMaps[i].clear();\n\t\t}\n\t}\n\n});\n\n    /* Tracks mouse movements over a CoordMap and raises events about which cell the mouse is over.\n----------------------------------------------------------------------------------------------------------------------*/\n// TODO: very useful to have a handler that gets called upon cellOut OR when dragging stops (for cleanup)\n\nvar DragListener = Class.extend({\n\n\tcoordMap: null,\n\toptions: null,\n\n\tisListening: false,\n\tisDragging: false,\n\n\t// the cell the mouse was over when listening started\n\torigCell: null,\n\n\t// the cell the mouse is over\n\tcell: null,\n\n\t// coordinates of the initial mousedown\n\tmouseX0: null,\n\tmouseY0: null,\n\n\t// handler attached to the document, bound to the DragListener's `this`\n\tmousemoveProxy: null,\n\tmouseupProxy: null,\n\n\tscrollEl: null,\n\tscrollBounds: null, // { top, bottom, left, right }\n\tscrollTopVel: null, // pixels per second\n\tscrollLeftVel: null, // pixels per second\n\tscrollIntervalId: null, // ID of setTimeout for scrolling animation loop\n\tscrollHandlerProxy: null, // this-scoped function for handling when scrollEl is scrolled\n\n\tscrollSensitivity: 30, // pixels from edge for scrolling to start\n\tscrollSpeed: 200, // pixels per second, at maximum speed\n\tscrollIntervalMs: 50, // millisecond wait between scroll increment\n\n\n\tconstructor: function(coordMap, options) {\n\t\tthis.coordMap = coordMap;\n\t\tthis.options = options || {};\n\t},\n\n\n\t// Call this when the user does a mousedown. Will probably lead to startListening\n\tmousedown: function(ev) {\n\t\tif (isPrimaryMouseButton(ev)) {\n\n\t\t\tev.preventDefault(); // prevents native selection in most browsers\n\n\t\t\tthis.startListening(ev);\n\n\t\t\t// start the drag immediately if there is no minimum distance for a drag start\n\t\t\tif (!this.options.distance) {\n\t\t\t\tthis.startDrag(ev);\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Call this to start tracking mouse movements\n\tstartListening: function(ev) {\n\t\tvar scrollParent;\n\t\tvar cell;\n\n\t\tif (!this.isListening) {\n\n\t\t\t// grab scroll container and attach handler\n\t\t\tif (ev && this.options.scroll) {\n\t\t\t\tscrollParent = getScrollParent($(ev.target));\n\t\t\t\tif (!scrollParent.is(window) && !scrollParent.is(document)) {\n\t\t\t\t\tthis.scrollEl = scrollParent;\n\n\t\t\t\t\t// scope to `this`, and use `debounce` to make sure rapid calls don't happen\n\t\t\t\t\tthis.scrollHandlerProxy = debounce($.proxy(this, 'scrollHandler'), 100);\n\t\t\t\t\tthis.scrollEl.on('scroll', this.scrollHandlerProxy);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.computeCoords(); // relies on `scrollEl`\n\n\t\t\t// get info on the initial cell and its coordinates\n\t\t\tif (ev) {\n\t\t\t\tcell = this.getCell(ev);\n\t\t\t\tthis.origCell = cell;\n\n\t\t\t\tthis.mouseX0 = ev.pageX;\n\t\t\t\tthis.mouseY0 = ev.pageY;\n\t\t\t}\n\n\t\t\t$(document)\n\t\t\t\t.on('mousemove', this.mousemoveProxy = $.proxy(this, 'mousemove'))\n\t\t\t\t.on('mouseup', this.mouseupProxy = $.proxy(this, 'mouseup'))\n\t\t\t\t.on('selectstart', this.preventDefault); // prevents native selection in IE<=8\n\n\t\t\tthis.isListening = true;\n\t\t\tthis.trigger('listenStart', ev);\n\t\t}\n\t},\n\n\n\t// Recomputes the drag-critical positions of elements\n\tcomputeCoords: function() {\n\t\tthis.coordMap.build();\n\t\tthis.computeScrollBounds();\n\t},\n\n\n\t// Called when the user moves the mouse\n\tmousemove: function(ev) {\n\t\tvar minDistance;\n\t\tvar distanceSq; // current distance from mouseX0/mouseY0, squared\n\n\t\tif (!this.isDragging) { // if not already dragging...\n\t\t\t// then start the drag if the minimum distance criteria is met\n\t\t\tminDistance = this.options.distance || 1;\n\t\t\tdistanceSq = Math.pow(ev.pageX - this.mouseX0, 2) + Math.pow(ev.pageY - this.mouseY0, 2);\n\t\t\tif (distanceSq >= minDistance * minDistance) { // use pythagorean theorem\n\t\t\t\tthis.startDrag(ev);\n\t\t\t}\n\t\t}\n\n\t\tif (this.isDragging) {\n\t\t\tthis.drag(ev); // report a drag, even if this mousemove initiated the drag\n\t\t}\n\t},\n\n\n\t// Call this to initiate a legitimate drag.\n\t// This function is called internally from this class, but can also be called explicitly from outside\n\tstartDrag: function(ev) {\n\t\tvar cell;\n\n\t\tif (!this.isListening) { // startDrag must have manually initiated\n\t\t\tthis.startListening();\n\t\t}\n\n\t\tif (!this.isDragging) {\n\t\t\tthis.isDragging = true;\n\t\t\tthis.trigger('dragStart', ev);\n\n\t\t\t// report the initial cell the mouse is over\n\t\t\t// especially important if no min-distance and drag starts immediately\n\t\t\tcell = this.getCell(ev); // this might be different from this.origCell if the min-distance is large\n\t\t\tif (cell) {\n\t\t\t\tthis.cellOver(cell);\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Called while the mouse is being moved and when we know a legitimate drag is taking place\n\tdrag: function(ev) {\n\t\tvar cell;\n\n\t\tif (this.isDragging) {\n\t\t\tcell = this.getCell(ev);\n\n\t\t\tif (!isCellsEqual(cell, this.cell)) { // a different cell than before?\n\t\t\t\tif (this.cell) {\n\t\t\t\t\tthis.cellOut();\n\t\t\t\t}\n\t\t\t\tif (cell) {\n\t\t\t\t\tthis.cellOver(cell);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.dragScroll(ev); // will possibly cause scrolling\n\t\t}\n\t},\n\n\n\t// Called when a the mouse has just moved over a new cell\n\tcellOver: function(cell) {\n\t\tthis.cell = cell;\n\t\tthis.trigger('cellOver', cell, isCellsEqual(cell, this.origCell));\n\t},\n\n\n\t// Called when the mouse has just moved out of a cell\n\tcellOut: function() {\n\t\tif (this.cell) {\n\t\t\tthis.trigger('cellOut', this.cell);\n\t\t\tthis.cell = null;\n\t\t}\n\t},\n\n\n\t// Called when the user does a mouseup\n\tmouseup: function(ev) {\n\t\tthis.stopDrag(ev);\n\t\tthis.stopListening(ev);\n\t},\n\n\n\t// Called when the drag is over. Will not cause listening to stop however.\n\t// A concluding 'cellOut' event will NOT be triggered.\n\tstopDrag: function(ev) {\n\t\tif (this.isDragging) {\n\t\t\tthis.stopScrolling();\n\t\t\tthis.trigger('dragStop', ev);\n\t\t\tthis.isDragging = false;\n\t\t}\n\t},\n\n\n\t// Call this to stop listening to the user's mouse events\n\tstopListening: function(ev) {\n\t\tif (this.isListening) {\n\n\t\t\t// remove the scroll handler if there is a scrollEl\n\t\t\tif (this.scrollEl) {\n\t\t\t\tthis.scrollEl.off('scroll', this.scrollHandlerProxy);\n\t\t\t\tthis.scrollHandlerProxy = null;\n\t\t\t}\n\n\t\t\t$(document)\n\t\t\t\t.off('mousemove', this.mousemoveProxy)\n\t\t\t\t.off('mouseup', this.mouseupProxy)\n\t\t\t\t.off('selectstart', this.preventDefault);\n\n\t\t\tthis.mousemoveProxy = null;\n\t\t\tthis.mouseupProxy = null;\n\n\t\t\tthis.isListening = false;\n\t\t\tthis.trigger('listenStop', ev);\n\n\t\t\tthis.origCell = this.cell = null;\n\t\t\tthis.coordMap.clear();\n\t\t}\n\t},\n\n\n\t// Gets the cell underneath the coordinates for the given mouse event\n\tgetCell: function(ev) {\n\t\treturn this.coordMap.getCell(ev.pageX, ev.pageY);\n\t},\n\n\n\t// Triggers a callback. Calls a function in the option hash of the same name.\n\t// Arguments beyond the first `name` are forwarded on.\n\ttrigger: function(name) {\n\t\tif (this.options[name]) {\n\t\t\tthis.options[name].apply(this, Array.prototype.slice.call(arguments, 1));\n\t\t}\n\t},\n\n\n\t// Stops a given mouse event from doing it's native browser action. In our case, text selection.\n\tpreventDefault: function(ev) {\n\t\tev.preventDefault();\n\t},\n\n\n\t/* Scrolling\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Computes and stores the bounding rectangle of scrollEl\n\tcomputeScrollBounds: function() {\n\t\tvar el = this.scrollEl;\n\t\tvar offset;\n\n\t\tif (el) {\n\t\t\toffset = el.offset();\n\t\t\tthis.scrollBounds = {\n\t\t\t\ttop: offset.top,\n\t\t\t\tleft: offset.left,\n\t\t\t\tbottom: offset.top + el.outerHeight(),\n\t\t\t\tright: offset.left + el.outerWidth()\n\t\t\t};\n\t\t}\n\t},\n\n\n\t// Called when the dragging is in progress and scrolling should be updated\n\tdragScroll: function(ev) {\n\t\tvar sensitivity = this.scrollSensitivity;\n\t\tvar bounds = this.scrollBounds;\n\t\tvar topCloseness, bottomCloseness;\n\t\tvar leftCloseness, rightCloseness;\n\t\tvar topVel = 0;\n\t\tvar leftVel = 0;\n\n\t\tif (bounds) { // only scroll if scrollEl exists\n\n\t\t\t// compute closeness to edges. valid range is from 0.0 - 1.0\n\t\t\ttopCloseness = (sensitivity - (ev.pageY - bounds.top)) / sensitivity;\n\t\t\tbottomCloseness = (sensitivity - (bounds.bottom - ev.pageY)) / sensitivity;\n\t\t\tleftCloseness = (sensitivity - (ev.pageX - bounds.left)) / sensitivity;\n\t\t\trightCloseness = (sensitivity - (bounds.right - ev.pageX)) / sensitivity;\n\n\t\t\t// translate vertical closeness into velocity.\n\t\t\t// mouse must be completely in bounds for velocity to happen.\n\t\t\tif (topCloseness >= 0 && topCloseness <= 1) {\n\t\t\t\ttopVel = topCloseness * this.scrollSpeed * -1; // negative. for scrolling up\n\t\t\t}\n\t\t\telse if (bottomCloseness >= 0 && bottomCloseness <= 1) {\n\t\t\t\ttopVel = bottomCloseness * this.scrollSpeed;\n\t\t\t}\n\n\t\t\t// translate horizontal closeness into velocity\n\t\t\tif (leftCloseness >= 0 && leftCloseness <= 1) {\n\t\t\t\tleftVel = leftCloseness * this.scrollSpeed * -1; // negative. for scrolling left\n\t\t\t}\n\t\t\telse if (rightCloseness >= 0 && rightCloseness <= 1) {\n\t\t\t\tleftVel = rightCloseness * this.scrollSpeed;\n\t\t\t}\n\t\t}\n\n\t\tthis.setScrollVel(topVel, leftVel);\n\t},\n\n\n\t// Sets the speed-of-scrolling for the scrollEl\n\tsetScrollVel: function(topVel, leftVel) {\n\n\t\tthis.scrollTopVel = topVel;\n\t\tthis.scrollLeftVel = leftVel;\n\n\t\tthis.constrainScrollVel(); // massages into realistic values\n\n\t\t// if there is non-zero velocity, and an animation loop hasn't already started, then START\n\t\tif ((this.scrollTopVel || this.scrollLeftVel) && !this.scrollIntervalId) {\n\t\t\tthis.scrollIntervalId = setInterval(\n\t\t\t\t$.proxy(this, 'scrollIntervalFunc'), // scope to `this`\n\t\t\t\tthis.scrollIntervalMs\n\t\t\t);\n\t\t}\n\t},\n\n\n\t// Forces scrollTopVel and scrollLeftVel to be zero if scrolling has already gone all the way\n\tconstrainScrollVel: function() {\n\t\tvar el = this.scrollEl;\n\n\t\tif (this.scrollTopVel < 0) { // scrolling up?\n\t\t\tif (el.scrollTop() <= 0) { // already scrolled all the way up?\n\t\t\t\tthis.scrollTopVel = 0;\n\t\t\t}\n\t\t}\n\t\telse if (this.scrollTopVel > 0) { // scrolling down?\n\t\t\tif (el.scrollTop() + el[0].clientHeight >= el[0].scrollHeight) { // already scrolled all the way down?\n\t\t\t\tthis.scrollTopVel = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (this.scrollLeftVel < 0) { // scrolling left?\n\t\t\tif (el.scrollLeft() <= 0) { // already scrolled all the left?\n\t\t\t\tthis.scrollLeftVel = 0;\n\t\t\t}\n\t\t}\n\t\telse if (this.scrollLeftVel > 0) { // scrolling right?\n\t\t\tif (el.scrollLeft() + el[0].clientWidth >= el[0].scrollWidth) { // already scrolled all the way right?\n\t\t\t\tthis.scrollLeftVel = 0;\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// This function gets called during every iteration of the scrolling animation loop\n\tscrollIntervalFunc: function() {\n\t\tvar el = this.scrollEl;\n\t\tvar frac = this.scrollIntervalMs / 1000; // considering animation frequency, what the vel should be mult'd by\n\n\t\t// change the value of scrollEl's scroll\n\t\tif (this.scrollTopVel) {\n\t\t\tel.scrollTop(el.scrollTop() + this.scrollTopVel * frac);\n\t\t}\n\t\tif (this.scrollLeftVel) {\n\t\t\tel.scrollLeft(el.scrollLeft() + this.scrollLeftVel * frac);\n\t\t}\n\n\t\tthis.constrainScrollVel(); // since the scroll values changed, recompute the velocities\n\n\t\t// if scrolled all the way, which causes the vels to be zero, stop the animation loop\n\t\tif (!this.scrollTopVel && !this.scrollLeftVel) {\n\t\t\tthis.stopScrolling();\n\t\t}\n\t},\n\n\n\t// Kills any existing scrolling animation loop\n\tstopScrolling: function() {\n\t\tif (this.scrollIntervalId) {\n\t\t\tclearInterval(this.scrollIntervalId);\n\t\t\tthis.scrollIntervalId = null;\n\n\t\t\t// when all done with scrolling, recompute positions since they probably changed\n\t\t\tthis.computeCoords();\n\t\t}\n\t},\n\n\n\t// Get called when the scrollEl is scrolled (NOTE: this is delayed via debounce)\n\tscrollHandler: function() {\n\t\t// recompute all coordinates, but *only* if this is *not* part of our scrolling animation\n\t\tif (!this.scrollIntervalId) {\n\t\t\tthis.computeCoords();\n\t\t}\n\t}\n\n});\n\n\n// Returns `true` if the cells are identically equal. `false` otherwise.\n// They must have the same row, col, and be from the same grid.\n// Two null values will be considered equal, as two \"out of the grid\" states are the same.\nfunction isCellsEqual(cell1, cell2) {\n\n\tif (!cell1 && !cell2) {\n\t\treturn true;\n\t}\n\n\tif (cell1 && cell2) {\n\t\treturn cell1.grid === cell2.grid &&\n\t\t\tcell1.row === cell2.row &&\n\t\t\tcell1.col === cell2.col;\n\t}\n\n\treturn false;\n}\n\n    /* Creates a clone of an element and lets it track the mouse as it moves\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar MouseFollower = Class.extend({\n\n\toptions: null,\n\n\tsourceEl: null, // the element that will be cloned and made to look like it is dragging\n\tel: null, // the clone of `sourceEl` that will track the mouse\n\tparentEl: null, // the element that `el` (the clone) will be attached to\n\n\t// the initial position of el, relative to the offset parent. made to match the initial offset of sourceEl\n\ttop0: null,\n\tleft0: null,\n\n\t// the initial position of the mouse\n\tmouseY0: null,\n\tmouseX0: null,\n\n\t// the number of pixels the mouse has moved from its initial position\n\ttopDelta: null,\n\tleftDelta: null,\n\n\tmousemoveProxy: null, // document mousemove handler, bound to the MouseFollower's `this`\n\n\tisFollowing: false,\n\tisHidden: false,\n\tisAnimating: false, // doing the revert animation?\n\n\tconstructor: function(sourceEl, options) {\n\t\tthis.options = options = options || {};\n\t\tthis.sourceEl = sourceEl;\n\t\tthis.parentEl = options.parentEl ? $(options.parentEl) : sourceEl.parent(); // default to sourceEl's parent\n\t},\n\n\n\t// Causes the element to start following the mouse\n\tstart: function(ev) {\n\t\tif (!this.isFollowing) {\n\t\t\tthis.isFollowing = true;\n\n\t\t\tthis.mouseY0 = ev.pageY;\n\t\t\tthis.mouseX0 = ev.pageX;\n\t\t\tthis.topDelta = 0;\n\t\t\tthis.leftDelta = 0;\n\n\t\t\tif (!this.isHidden) {\n\t\t\t\tthis.updatePosition();\n\t\t\t}\n\n\t\t\t$(document).on('mousemove', this.mousemoveProxy = $.proxy(this, 'mousemove'));\n\t\t}\n\t},\n\n\n\t// Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position.\n\t// `callback` gets invoked when the animation is complete. If no animation, it is invoked immediately.\n\tstop: function(shouldRevert, callback) {\n\t\tvar _this = this;\n\t\tvar revertDuration = this.options.revertDuration;\n\n\t\tfunction complete() {\n\t\t\tthis.isAnimating = false;\n\t\t\t_this.destroyEl();\n\n\t\t\tthis.top0 = this.left0 = null; // reset state for future updatePosition calls\n\n\t\t\tif (callback) {\n\t\t\t\tcallback();\n\t\t\t}\n\t\t}\n\n\t\tif (this.isFollowing && !this.isAnimating) { // disallow more than one stop animation at a time\n\t\t\tthis.isFollowing = false;\n\n\t\t\t$(document).off('mousemove', this.mousemoveProxy);\n\n\t\t\tif (shouldRevert && revertDuration && !this.isHidden) { // do a revert animation?\n\t\t\t\tthis.isAnimating = true;\n\t\t\t\tthis.el.animate({\n\t\t\t\t\ttop: this.top0,\n\t\t\t\t\tleft: this.left0\n\t\t\t\t}, {\n\t\t\t\t\tduration: revertDuration,\n\t\t\t\t\tcomplete: complete\n\t\t\t\t});\n\t\t\t}\n\t\t\telse {\n\t\t\t\tcomplete();\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Gets the tracking element. Create it if necessary\n\tgetEl: function() {\n\t\tvar el = this.el;\n\n\t\tif (!el) {\n\t\t\tthis.sourceEl.width(); // hack to force IE8 to compute correct bounding box\n\t\t\tel = this.el = this.sourceEl.clone()\n\t\t\t\t.css({\n\t\t\t\t\tposition: 'absolute',\n\t\t\t\t\tvisibility: '', // in case original element was hidden (commonly through hideEvents())\n\t\t\t\t\tdisplay: this.isHidden ? 'none' : '', // for when initially hidden\n\t\t\t\t\tmargin: 0,\n\t\t\t\t\tright: 'auto', // erase and set width instead\n\t\t\t\t\tbottom: 'auto', // erase and set height instead\n\t\t\t\t\twidth: this.sourceEl.width(), // explicit height in case there was a 'right' value\n\t\t\t\t\theight: this.sourceEl.height(), // explicit width in case there was a 'bottom' value\n\t\t\t\t\topacity: this.options.opacity || '',\n\t\t\t\t\tzIndex: this.options.zIndex\n\t\t\t\t})\n\t\t\t\t.appendTo(this.parentEl);\n\t\t}\n\n\t\treturn el;\n\t},\n\n\n\t// Removes the tracking element if it has already been created\n\tdestroyEl: function() {\n\t\tif (this.el) {\n\t\t\tthis.el.remove();\n\t\t\tthis.el = null;\n\t\t}\n\t},\n\n\n\t// Update the CSS position of the tracking element\n\tupdatePosition: function() {\n\t\tvar sourceOffset;\n\t\tvar origin;\n\n\t\tthis.getEl(); // ensure this.el\n\n\t\t// make sure origin info was computed\n\t\tif (this.top0 === null) {\n\t\t\tthis.sourceEl.width(); // hack to force IE8 to compute correct bounding box\n\t\t\tsourceOffset = this.sourceEl.offset();\n\t\t\torigin = this.el.offsetParent().offset();\n\t\t\tthis.top0 = sourceOffset.top - origin.top;\n\t\t\tthis.left0 = sourceOffset.left - origin.left;\n\t\t}\n\n\t\tthis.el.css({\n\t\t\ttop: this.top0 + this.topDelta,\n\t\t\tleft: this.left0 + this.leftDelta\n\t\t});\n\t},\n\n\n\t// Gets called when the user moves the mouse\n\tmousemove: function(ev) {\n\t\tthis.topDelta = ev.pageY - this.mouseY0;\n\t\tthis.leftDelta = ev.pageX - this.mouseX0;\n\n\t\tif (!this.isHidden) {\n\t\t\tthis.updatePosition();\n\t\t}\n\t},\n\n\n\t// Temporarily makes the tracking element invisible. Can be called before following starts\n\thide: function() {\n\t\tif (!this.isHidden) {\n\t\t\tthis.isHidden = true;\n\t\t\tif (this.el) {\n\t\t\t\tthis.el.hide();\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Show the tracking element after it has been temporarily hidden\n\tshow: function() {\n\t\tif (this.isHidden) {\n\t\t\tthis.isHidden = false;\n\t\t\tthis.updatePosition();\n\t\t\tthis.getEl().show();\n\t\t}\n\t}\n\n});\n\n    /* A utility class for rendering <tr> rows.\n----------------------------------------------------------------------------------------------------------------------*/\n// It leverages methods of the subclass and the View to determine custom rendering behavior for each row \"type\"\n// (such as highlight rows, day rows, helper rows, etc).\n\nvar RowRenderer = Class.extend({\n\n\tview: null, // a View object\n\tisRTL: null, // shortcut to the view's isRTL option\n\tcellHtml: '<td/>', // plain default HTML used for a cell when no other is available\n\n\n\tconstructor: function(view) {\n\t\tthis.view = view;\n\t\tthis.isRTL = view.opt('isRTL');\n\t},\n\n\n\t// Renders the HTML for a row, leveraging custom cell-HTML-renderers based on the `rowType`.\n\t// Also applies the \"intro\" and \"outro\" cells, which are specified by the subclass and views.\n\t// `row` is an optional row number.\n\trowHtml: function(rowType, row) {\n\t\tvar renderCell = this.getHtmlRenderer('cell', rowType);\n\t\tvar rowCellHtml = '';\n\t\tvar col;\n\t\tvar cell;\n\n\t\trow = row || 0;\n\n\t\tfor (col = 0; col < this.colCnt; col++) {\n\t\t\tcell = this.getCell(row, col);\n\t\t\trowCellHtml += renderCell(cell);\n\t\t}\n\n\t\trowCellHtml = this.bookendCells(rowCellHtml, rowType, row); // apply intro and outro\n\n\t\treturn '<tr>' + rowCellHtml + '</tr>';\n\t},\n\n\n\t// Applies the \"intro\" and \"outro\" HTML to the given cells.\n\t// Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro.\n\t// `cells` can be an HTML string of <td>'s or a jQuery <tr> element\n\t// `row` is an optional row number.\n\tbookendCells: function(cells, rowType, row) {\n\t\tvar intro = this.getHtmlRenderer('intro', rowType)(row || 0);\n\t\tvar outro = this.getHtmlRenderer('outro', rowType)(row || 0);\n\t\tvar prependHtml = this.isRTL ? outro : intro;\n\t\tvar appendHtml = this.isRTL ? intro : outro;\n\n\t\tif (typeof cells === 'string') {\n\t\t\treturn prependHtml + cells + appendHtml;\n\t\t}\n\t\telse { // a jQuery <tr> element\n\t\t\treturn cells.prepend(prependHtml).append(appendHtml);\n\t\t}\n\t},\n\n\n\t// Returns an HTML-rendering function given a specific `rendererName` (like cell, intro, or outro) and a specific\n\t// `rowType` (like day, eventSkeleton, helperSkeleton), which is optional.\n\t// If a renderer for the specific rowType doesn't exist, it will fall back to a generic renderer.\n\t// We will query the View object first for any custom rendering functions, then the methods of the subclass.\n\tgetHtmlRenderer: function(rendererName, rowType) {\n\t\tvar view = this.view;\n\t\tvar generalName; // like \"cellHtml\"\n\t\tvar specificName; // like \"dayCellHtml\". based on rowType\n\t\tvar provider; // either the View or the RowRenderer subclass, whichever provided the method\n\t\tvar renderer;\n\n\t\tgeneralName = rendererName + 'Html';\n\t\tif (rowType) {\n\t\t\tspecificName = rowType + capitaliseFirstLetter(rendererName) + 'Html';\n\t\t}\n\n\t\tif (specificName && (renderer = view[specificName])) {\n\t\t\tprovider = view;\n\t\t}\n\t\telse if (specificName && (renderer = this[specificName])) {\n\t\t\tprovider = this;\n\t\t}\n\t\telse if ((renderer = view[generalName])) {\n\t\t\tprovider = view;\n\t\t}\n\t\telse if ((renderer = this[generalName])) {\n\t\t\tprovider = this;\n\t\t}\n\n\t\tif (typeof renderer === 'function') {\n\t\t\treturn function() {\n\t\t\t\treturn renderer.apply(provider, arguments) || ''; // use correct `this` and always return a string\n\t\t\t};\n\t\t}\n\n\t\t// the rendered can be a plain string as well. if not specified, always an empty string.\n\t\treturn function() {\n\t\t\treturn renderer || '';\n\t\t};\n\t}\n\n});\n\n    /* An abstract class comprised of a \"grid\" of cells that each represent a specific datetime\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar Grid = fc.Grid = RowRenderer.extend({\n\n\tstart: null, // the date of the first cell\n\tend: null, // the date after the last cell\n\n\trowCnt: 0, // number of rows\n\tcolCnt: 0, // number of cols\n\trowData: null, // array of objects, holding misc data for each row\n\tcolData: null, // array of objects, holding misc data for each column\n\n\tel: null, // the containing element\n\tcoordMap: null, // a GridCoordMap that converts pixel values to datetimes\n\telsByFill: null, // a hash of jQuery element sets used for rendering each fill. Keyed by fill name.\n\n\tdocumentDragStartProxy: null, // binds the Grid's scope to documentDragStart (in DayGrid.events)\n\n\t// derived from options\n\tcolHeadFormat: null, // TODO: move to another class. not applicable to all Grids\n\teventTimeFormat: null,\n\tdisplayEventEnd: null,\n\n\n\tconstructor: function() {\n\t\tRowRenderer.apply(this, arguments); // call the super-constructor\n\n\t\tthis.coordMap = new GridCoordMap(this);\n\t\tthis.elsByFill = {};\n\t\tthis.documentDragStartProxy = $.proxy(this, 'documentDragStart');\n\t},\n\n\n\t// Renders the grid into the `el` element.\n\t// Subclasses should override and call this super-method when done.\n\trender: function() {\n\t\tthis.bindHandlers();\n\t},\n\n\n\t// Called when the grid's resources need to be cleaned up\n\tdestroy: function() {\n\t\tthis.unbindHandlers();\n\t},\n\n\n\t/* Options\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Generates the format string used for the text in column headers, if not explicitly defined by 'columnFormat'\n\t// TODO: move to another class. not applicable to all Grids\n\tcomputeColHeadFormat: function() {\n\t\t// subclasses must implement if they want to use headHtml()\n\t},\n\n\n\t// Generates the format string used for event time text, if not explicitly defined by 'timeFormat'\n\tcomputeEventTimeFormat: function() {\n\t\treturn this.view.opt('smallTimeFormat');\n\t},\n\n\n\t// Determines whether events should have their end times displayed, if not explicitly defined by 'displayEventEnd'\n\tcomputeDisplayEventEnd: function() {\n\t\treturn false;\n\t},\n\n\n\t/* Dates\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Tells the grid about what period of time to display. Grid will subsequently compute dates for cell system.\n\tsetRange: function(range) {\n\t\tvar view = this.view;\n\n\t\tthis.start = range.start.clone();\n\t\tthis.end = range.end.clone();\n\n\t\tthis.rowData = [];\n\t\tthis.colData = [];\n\t\tthis.updateCells();\n\n\t\t// Populate option-derived settings. Look for override first, then compute if necessary.\n\t\tthis.colHeadFormat = view.opt('columnFormat') || this.computeColHeadFormat();\n\t\tthis.eventTimeFormat = view.opt('timeFormat') || this.computeEventTimeFormat();\n\t\tthis.displayEventEnd = view.opt('displayEventEnd');\n\t\tif (this.displayEventEnd == null) {\n\t\t\tthis.displayEventEnd = this.computeDisplayEventEnd();\n\t\t}\n\t},\n\n\n\t// Responsible for setting rowCnt/colCnt and any other row/col data\n\tupdateCells: function() {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Converts a range with an inclusive `start` and an exclusive `end` into an array of segment objects\n\trangeToSegs: function(range) {\n\t\t// subclasses must implement\n\t},\n\n\n\t/* Cells\n\t------------------------------------------------------------------------------------------------------------------*/\n\t// NOTE: columns are ordered left-to-right\n\n\n\t// Gets an object containing row/col number, misc data, and range information about the cell.\n\t// Accepts row/col values, an object with row/col properties, or a single-number offset from the first cell.\n\tgetCell: function(row, col) {\n\t\tvar cell;\n\n\t\tif (col == null) {\n\t\t\tif (typeof row === 'number') { // a single-number offset\n\t\t\t\tcol = row % this.colCnt;\n\t\t\t\trow = Math.floor(row / this.colCnt);\n\t\t\t}\n\t\t\telse { // an object with row/col properties\n\t\t\t\tcol = row.col;\n\t\t\t\trow = row.row;\n\t\t\t}\n\t\t}\n\n\t\tcell = { row: row, col: col };\n\n\t\t$.extend(cell, this.getRowData(row), this.getColData(col));\n\t\t$.extend(cell, this.computeCellRange(cell));\n\n\t\treturn cell;\n\t},\n\n\n\t// Given a cell object with index and misc data, generates a range object\n\tcomputeCellRange: function(cell) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Retrieves misc data about the given row\n\tgetRowData: function(row) {\n\t\treturn this.rowData[row] || {};\n\t},\n\n\n\t// Retrieves misc data baout the given column\n\tgetColData: function(col) {\n\t\treturn this.colData[col] || {};\n\t},\n\n\n\t// Retrieves the element representing the given row\n\tgetRowEl: function(row) {\n\t\t// subclasses should implement if leveraging the default getCellDayEl() or computeRowCoords()\n\t},\n\n\n\t// Retrieves the element representing the given column\n\tgetColEl: function(col) {\n\t\t// subclasses should implement if leveraging the default getCellDayEl() or computeColCoords()\n\t},\n\n\n\t// Given a cell object, returns the element that represents the cell's whole-day\n\tgetCellDayEl: function(cell) {\n\t\treturn this.getColEl(cell.col) || this.getRowEl(cell.row);\n\t},\n\n\n\t/* Cell Coordinates\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Computes the top/bottom coordinates of all rows.\n\t// By default, queries the dimensions of the element provided by getRowEl().\n\tcomputeRowCoords: function() {\n\t\tvar items = [];\n\t\tvar i, el;\n\t\tvar item;\n\n\t\tfor (i = 0; i < this.rowCnt; i++) {\n\t\t\tel = this.getRowEl(i);\n\t\t\titem = {\n\t\t\t\ttop: el.offset().top\n\t\t\t};\n\t\t\tif (i > 0) {\n\t\t\t\titems[i - 1].bottom = item.top;\n\t\t\t}\n\t\t\titems.push(item);\n\t\t}\n\t\titem.bottom = item.top + el.outerHeight();\n\n\t\treturn items;\n\t},\n\n\n\t// Computes the left/right coordinates of all rows.\n\t// By default, queries the dimensions of the element provided by getColEl().\n\tcomputeColCoords: function() {\n\t\tvar items = [];\n\t\tvar i, el;\n\t\tvar item;\n\n\t\tfor (i = 0; i < this.colCnt; i++) {\n\t\t\tel = this.getColEl(i);\n\t\t\titem = {\n\t\t\t\tleft: el.offset().left\n\t\t\t};\n\t\t\tif (i > 0) {\n\t\t\t\titems[i - 1].right = item.left;\n\t\t\t}\n\t\t\titems.push(item);\n\t\t}\n\t\titem.right = item.left + el.outerWidth();\n\n\t\treturn items;\n\t},\n\n\n\t/* Handlers\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Attaches handlers to DOM\n\tbindHandlers: function() {\n\t\tvar _this = this;\n\n\t\t// attach a handler to the grid's root element.\n\t\t// we don't need to clean up in unbindHandlers or destroy, because when jQuery removes the element from the\n\t\t// DOM it automatically unregisters the handlers.\n\t\tthis.el.on('mousedown', function(ev) {\n\t\t\tif (\n\t\t\t\t!$(ev.target).is('.fc-event-container *, .fc-more') && // not an an event element, or \"more..\" link\n\t\t\t\t!$(ev.target).closest('.fc-popover').length // not on a popover (like the \"more..\" events one)\n\t\t\t) {\n\t\t\t\t_this.dayMousedown(ev);\n\t\t\t}\n\t\t});\n\n\t\t// attach event-element-related handlers. in Grid.events\n\t\t// same garbage collection note as above.\n\t\tthis.bindSegHandlers();\n\n\t\t$(document).on('dragstart', this.documentDragStartProxy); // jqui drag\n\t},\n\n\n\t// Unattaches handlers from the DOM\n\tunbindHandlers: function() {\n\t\t$(document).off('dragstart', this.documentDragStartProxy); // jqui drag\n\t},\n\n\n\t// Process a mousedown on an element that represents a day. For day clicking and selecting.\n\tdayMousedown: function(ev) {\n\t\tvar _this = this;\n\t\tvar view = this.view;\n\t\tvar isSelectable = view.opt('selectable');\n\t\tvar dayClickCell; // null if invalid dayClick\n\t\tvar selectionRange; // null if invalid selection\n\n\t\t// this listener tracks a mousedown on a day element, and a subsequent drag.\n\t\t// if the drag ends on the same day, it is a 'dayClick'.\n\t\t// if 'selectable' is enabled, this listener also detects selections.\n\t\tvar dragListener = new DragListener(this.coordMap, {\n\t\t\t//distance: 5, // needs more work if we want dayClick to fire correctly\n\t\t\tscroll: view.opt('dragScroll'),\n\t\t\tdragStart: function() {\n\t\t\t\tview.unselect(); // since we could be rendering a new selection, we want to clear any old one\n\t\t\t},\n\t\t\tcellOver: function(cell, isOrig) {\n\t\t\t\tvar origCell = dragListener.origCell;\n\t\t\t\tif (origCell) { // click needs to have started on a cell\n\t\t\t\t\tdayClickCell = isOrig ? cell : null; // single-cell selection is a day click\n\t\t\t\t\tif (isSelectable) {\n\t\t\t\t\t\tselectionRange = _this.computeSelection(origCell, cell);\n\t\t\t\t\t\tif (selectionRange) {\n\t\t\t\t\t\t\t_this.renderSelection(selectionRange);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tdisableCursor();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tcellOut: function(cell) {\n\t\t\t\tdayClickCell = null;\n\t\t\t\tselectionRange = null;\n\t\t\t\t_this.destroySelection();\n\t\t\t\tenableCursor();\n\t\t\t},\n\t\t\tlistenStop: function(ev) {\n\t\t\t\tif (dayClickCell) {\n\t\t\t\t\tview.trigger('dayClick', _this.getCellDayEl(dayClickCell), dayClickCell.start, ev);\n\t\t\t\t}\n\t\t\t\tif (selectionRange) {\n\t\t\t\t\t// the selection will already have been rendered. just report it\n\t\t\t\t\tview.reportSelection(selectionRange, ev);\n\t\t\t\t}\n\t\t\t\tenableCursor();\n\t\t\t}\n\t\t});\n\n\t\tdragListener.mousedown(ev); // start listening, which will eventually initiate a dragStart\n\t},\n\n\n\t/* Event Helper\n\t------------------------------------------------------------------------------------------------------------------*/\n\t// TODO: should probably move this to Grid.events, like we did event dragging / resizing\n\n\n\t// Renders a mock event over the given range.\n\t// The range's end can be null, in which case the mock event that is rendered will have a null end time.\n\t// `sourceSeg` is the internal segment object involved in the drag. If null, something external is dragging.\n\trenderRangeHelper: function(range, sourceSeg) {\n\t\tvar fakeEvent;\n\n\t\tfakeEvent = sourceSeg ? createObject(sourceSeg.event) : {}; // mask the original event object if possible\n\t\tfakeEvent.start = range.start.clone();\n\t\tfakeEvent.end = range.end ? range.end.clone() : null;\n\t\tfakeEvent.allDay = null; // force it to be freshly computed by normalizeEventDateProps\n\t\tthis.view.calendar.normalizeEventDateProps(fakeEvent);\n\n\t\t// this extra className will be useful for differentiating real events from mock events in CSS\n\t\tfakeEvent.className = (fakeEvent.className || []).concat('fc-helper');\n\n\t\t// if something external is being dragged in, don't render a resizer\n\t\tif (!sourceSeg) {\n\t\t\tfakeEvent.editable = false;\n\t\t}\n\n\t\tthis.renderHelper(fakeEvent, sourceSeg); // do the actual rendering\n\t},\n\n\n\t// Renders a mock event\n\trenderHelper: function(event, sourceSeg) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Unrenders a mock event\n\tdestroyHelper: function() {\n\t\t// subclasses must implement\n\t},\n\n\n\t/* Selection\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of a selection. Will highlight by default but can be overridden by subclasses.\n\trenderSelection: function(range) {\n\t\tthis.renderHighlight(range);\n\t},\n\n\n\t// Unrenders any visual indications of a selection. Will unrender a highlight by default.\n\tdestroySelection: function() {\n\t\tthis.destroyHighlight();\n\t},\n\n\n\t// Given the first and last cells of a selection, returns a range object.\n\t// Will return something falsy if the selection is invalid (when outside of selectionConstraint for example).\n\t// Subclasses can override and provide additional data in the range object. Will be passed to renderSelection().\n\tcomputeSelection: function(firstCell, lastCell) {\n\t\tvar dates = [\n\t\t\tfirstCell.start,\n\t\t\tfirstCell.end,\n\t\t\tlastCell.start,\n\t\t\tlastCell.end\n\t\t];\n\t\tvar range;\n\n\t\tdates.sort(compareNumbers); // sorts chronologically. works with Moments\n\n\t\trange = {\n\t\t\tstart: dates[0].clone(),\n\t\t\tend: dates[3].clone()\n\t\t};\n\n\t\tif (!this.view.calendar.isSelectionRangeAllowed(range)) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn range;\n\t},\n\n\n\t/* Highlight\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders an emphasis on the given date range. `start` is inclusive. `end` is exclusive.\n\trenderHighlight: function(range) {\n\t\tthis.renderFill('highlight', this.rangeToSegs(range));\n\t},\n\n\n\t// Unrenders the emphasis on a date range\n\tdestroyHighlight: function() {\n\t\tthis.destroyFill('highlight');\n\t},\n\n\n\t// Generates an array of classNames for rendering the highlight. Used by the fill system.\n\thighlightSegClasses: function() {\n\t\treturn [ 'fc-highlight' ];\n\t},\n\n\n\t/* Fill System (highlight, background events, business hours)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a set of rectangles over the given segments of time.\n\t// Returns a subset of segs, the segs that were actually rendered.\n\t// Responsible for populating this.elsByFill. TODO: better API for expressing this requirement\n\trenderFill: function(type, segs) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Unrenders a specific type of fill that is currently rendered on the grid\n\tdestroyFill: function(type) {\n\t\tvar el = this.elsByFill[type];\n\n\t\tif (el) {\n\t\t\tel.remove();\n\t\t\tdelete this.elsByFill[type];\n\t\t}\n\t},\n\n\n\t// Renders and assigns an `el` property for each fill segment. Generic enough to work with different types.\n\t// Only returns segments that successfully rendered.\n\t// To be harnessed by renderFill (implemented by subclasses).\n\t// Analagous to renderFgSegEls.\n\trenderFillSegEls: function(type, segs) {\n\t\tvar _this = this;\n\t\tvar segElMethod = this[type + 'SegEl'];\n\t\tvar html = '';\n\t\tvar renderedSegs = [];\n\t\tvar i;\n\n\t\tif (segs.length) {\n\n\t\t\t// build a large concatenation of segment HTML\n\t\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\t\thtml += this.fillSegHtml(type, segs[i]);\n\t\t\t}\n\n\t\t\t// Grab individual elements from the combined HTML string. Use each as the default rendering.\n\t\t\t// Then, compute the 'el' for each segment.\n\t\t\t$(html).each(function(i, node) {\n\t\t\t\tvar seg = segs[i];\n\t\t\t\tvar el = $(node);\n\n\t\t\t\t// allow custom filter methods per-type\n\t\t\t\tif (segElMethod) {\n\t\t\t\t\tel = segElMethod.call(_this, seg, el);\n\t\t\t\t}\n\n\t\t\t\tif (el) { // custom filters did not cancel the render\n\t\t\t\t\tel = $(el); // allow custom filter to return raw DOM node\n\n\t\t\t\t\t// correct element type? (would be bad if a non-TD were inserted into a table for example)\n\t\t\t\t\tif (el.is(_this.fillSegTag)) {\n\t\t\t\t\t\tseg.el = el;\n\t\t\t\t\t\trenderedSegs.push(seg);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn renderedSegs;\n\t},\n\n\n\tfillSegTag: 'div', // subclasses can override\n\n\n\t// Builds the HTML needed for one fill segment. Generic enought o work with different types.\n\tfillSegHtml: function(type, seg) {\n\t\tvar classesMethod = this[type + 'SegClasses']; // custom hooks per-type\n\t\tvar stylesMethod = this[type + 'SegStyles']; //\n\t\tvar classes = classesMethod ? classesMethod.call(this, seg) : [];\n\t\tvar styles = stylesMethod ? stylesMethod.call(this, seg) : ''; // a semi-colon separated CSS property string\n\n\t\treturn '<' + this.fillSegTag +\n\t\t\t(classes.length ? ' class=\"' + classes.join(' ') + '\"' : '') +\n\t\t\t(styles ? ' style=\"' + styles + '\"' : '') +\n\t\t\t' />';\n\t},\n\n\n\t/* Generic rendering utilities for subclasses\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a day-of-week header row.\n\t// TODO: move to another class. not applicable to all Grids\n\theadHtml: function() {\n\t\treturn '' +\n\t\t\t'<div class=\"fc-row ' + this.view.widgetHeaderClass + '\">' +\n\t\t\t\t'<table>' +\n\t\t\t\t\t'<thead>' +\n\t\t\t\t\t\tthis.rowHtml('head') + // leverages RowRenderer\n\t\t\t\t\t'</thead>' +\n\t\t\t\t'</table>' +\n\t\t\t'</div>';\n\t},\n\n\n\t// Used by the `headHtml` method, via RowRenderer, for rendering the HTML of a day-of-week header cell\n\t// TODO: move to another class. not applicable to all Grids\n\theadCellHtml: function(cell) {\n\t\tvar view = this.view;\n\t\tvar date = cell.start;\n\n\t\treturn '' +\n\t\t\t'<th class=\"fc-day-header ' + view.widgetHeaderClass + ' fc-' + dayIDs[date.day()] + '\">' +\n\t\t\t\thtmlEscape(date.format(this.colHeadFormat)) +\n\t\t\t'</th>';\n\t},\n\n\n\t// Renders the HTML for a single-day background cell\n\tbgCellHtml: function(cell) {\n\t\tvar view = this.view;\n\t\tvar date = cell.start;\n\t\tvar classes = this.getDayClasses(date);\n\n\t\tclasses.unshift('fc-day', view.widgetContentClass);\n\n\t\treturn '<td class=\"' + classes.join(' ') + '\"' +\n\t\t\t' data-date=\"' + date.format('YYYY-MM-DD') + '\"' + // if date has a time, won't format it\n\t\t\t'></td>';\n\t},\n\n\n\t// Computes HTML classNames for a single-day cell\n\tgetDayClasses: function(date) {\n\t\tvar view = this.view;\n\t\tvar today = view.calendar.getNow().stripTime();\n\t\tvar classes = [ 'fc-' + dayIDs[date.day()] ];\n\n\t\tif (\n\t\t\tview.name === 'month' &&\n\t\t\tdate.month() != view.intervalStart.month()\n\t\t) {\n\t\t\tclasses.push('fc-other-month');\n\t\t}\n\n\t\tif (date.isSame(today, 'day')) {\n\t\t\tclasses.push(\n\t\t\t\t'fc-today',\n\t\t\t\tview.highlightStateClass\n\t\t\t);\n\t\t}\n\t\telse if (date < today) {\n\t\t\tclasses.push('fc-past');\n\t\t}\n\t\telse {\n\t\t\tclasses.push('fc-future');\n\t\t}\n\n\t\treturn classes;\n\t}\n\n});\n\n    /* Event-rendering and event-interaction methods for the abstract Grid class\n----------------------------------------------------------------------------------------------------------------------*/\n\nGrid.mixin({\n\n\tmousedOverSeg: null, // the segment object the user's mouse is over. null if over nothing\n\tisDraggingSeg: false, // is a segment being dragged? boolean\n\tisResizingSeg: false, // is a segment being resized? boolean\n\tsegs: null, // the event segments currently rendered in the grid\n\n\n\t// Renders the given events onto the grid\n\trenderEvents: function(events) {\n\t\tvar segs = this.eventsToSegs(events);\n\t\tvar bgSegs = [];\n\t\tvar fgSegs = [];\n\t\tvar i, seg;\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tseg = segs[i];\n\n\t\t\tif (isBgEvent(seg.event)) {\n\t\t\t\tbgSegs.push(seg);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tfgSegs.push(seg);\n\t\t\t}\n\t\t}\n\n\t\t// Render each different type of segment.\n\t\t// Each function may return a subset of the segs, segs that were actually rendered.\n\t\tbgSegs = this.renderBgSegs(bgSegs) || bgSegs;\n\t\tfgSegs = this.renderFgSegs(fgSegs) || fgSegs;\n\n\t\tthis.segs = bgSegs.concat(fgSegs);\n\t},\n\n\n\t// Unrenders all events currently rendered on the grid\n\tdestroyEvents: function() {\n\t\tthis.triggerSegMouseout(); // trigger an eventMouseout if user's mouse is over an event\n\n\t\tthis.destroyFgSegs();\n\t\tthis.destroyBgSegs();\n\n\t\tthis.segs = null;\n\t},\n\n\n\t// Retrieves all rendered segment objects currently rendered on the grid\n\tgetEventSegs: function() {\n\t\treturn this.segs || [];\n\t},\n\n\n\t/* Foreground Segment Rendering\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders foreground event segments onto the grid. May return a subset of segs that were rendered.\n\trenderFgSegs: function(segs) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Unrenders all currently rendered foreground segments\n\tdestroyFgSegs: function() {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Renders and assigns an `el` property for each foreground event segment.\n\t// Only returns segments that successfully rendered.\n\t// A utility that subclasses may use.\n\trenderFgSegEls: function(segs, disableResizing) {\n\t\tvar view = this.view;\n\t\tvar html = '';\n\t\tvar renderedSegs = [];\n\t\tvar i;\n\n\t\tif (segs.length) { // don't build an empty html string\n\n\t\t\t// build a large concatenation of event segment HTML\n\t\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\t\thtml += this.fgSegHtml(segs[i], disableResizing);\n\t\t\t}\n\n\t\t\t// Grab individual elements from the combined HTML string. Use each as the default rendering.\n\t\t\t// Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false.\n\t\t\t$(html).each(function(i, node) {\n\t\t\t\tvar seg = segs[i];\n\t\t\t\tvar el = view.resolveEventEl(seg.event, $(node));\n\n\t\t\t\tif (el) {\n\t\t\t\t\tel.data('fc-seg', seg); // used by handlers\n\t\t\t\t\tseg.el = el;\n\t\t\t\t\trenderedSegs.push(seg);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn renderedSegs;\n\t},\n\n\n\t// Generates the HTML for the default rendering of a foreground event segment. Used by renderFgSegEls()\n\tfgSegHtml: function(seg, disableResizing) {\n\t\t// subclasses should implement\n\t},\n\n\n\t/* Background Segment Rendering\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders the given background event segments onto the grid.\n\t// Returns a subset of the segs that were actually rendered.\n\trenderBgSegs: function(segs) {\n\t\treturn this.renderFill('bgEvent', segs);\n\t},\n\n\n\t// Unrenders all the currently rendered background event segments\n\tdestroyBgSegs: function() {\n\t\tthis.destroyFill('bgEvent');\n\t},\n\n\n\t// Renders a background event element, given the default rendering. Called by the fill system.\n\tbgEventSegEl: function(seg, el) {\n\t\treturn this.view.resolveEventEl(seg.event, el); // will filter through eventRender\n\t},\n\n\n\t// Generates an array of classNames to be used for the default rendering of a background event.\n\t// Called by the fill system.\n\tbgEventSegClasses: function(seg) {\n\t\tvar event = seg.event;\n\t\tvar source = event.source || {};\n\n\t\treturn [ 'fc-bgevent' ].concat(\n\t\t\tevent.className,\n\t\t\tsource.className || []\n\t\t);\n\t},\n\n\n\t// Generates a semicolon-separated CSS string to be used for the default rendering of a background event.\n\t// Called by the fill system.\n\t// TODO: consolidate with getEventSkinCss?\n\tbgEventSegStyles: function(seg) {\n\t\tvar view = this.view;\n\t\tvar event = seg.event;\n\t\tvar source = event.source || {};\n\t\tvar eventColor = event.color;\n\t\tvar sourceColor = source.color;\n\t\tvar optionColor = view.opt('eventColor');\n\t\tvar backgroundColor =\n\t\t\tevent.backgroundColor ||\n\t\t\teventColor ||\n\t\t\tsource.backgroundColor ||\n\t\t\tsourceColor ||\n\t\t\tview.opt('eventBackgroundColor') ||\n\t\t\toptionColor;\n\n\t\tif (backgroundColor) {\n\t\t\treturn 'background-color:' + backgroundColor;\n\t\t}\n\n\t\treturn '';\n\t},\n\n\n\t// Generates an array of classNames to be used for the rendering business hours overlay. Called by the fill system.\n\tbusinessHoursSegClasses: function(seg) {\n\t\treturn [ 'fc-nonbusiness', 'fc-bgevent' ];\n\t},\n\n\n\t/* Handlers\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Attaches event-element-related handlers to the container element and leverage bubbling\n\tbindSegHandlers: function() {\n\t\tvar _this = this;\n\t\tvar view = this.view;\n\n\t\t$.each(\n\t\t\t{\n\t\t\t\tmouseenter: function(seg, ev) {\n\t\t\t\t\t_this.triggerSegMouseover(seg, ev);\n\t\t\t\t},\n\t\t\t\tmouseleave: function(seg, ev) {\n\t\t\t\t\t_this.triggerSegMouseout(seg, ev);\n\t\t\t\t},\n\t\t\t\tclick: function(seg, ev) {\n\t\t\t\t\treturn view.trigger('eventClick', this, seg.event, ev); // can return `false` to cancel\n\t\t\t\t},\n\t\t\t\tmousedown: function(seg, ev) {\n\t\t\t\t\tif ($(ev.target).is('.fc-resizer') && view.isEventResizable(seg.event)) {\n\t\t\t\t\t\t_this.segResizeMousedown(seg, ev);\n\t\t\t\t\t}\n\t\t\t\t\telse if (view.isEventDraggable(seg.event)) {\n\t\t\t\t\t\t_this.segDragMousedown(seg, ev);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tfunction(name, func) {\n\t\t\t\t// attach the handler to the container element and only listen for real event elements via bubbling\n\t\t\t\t_this.el.on(name, '.fc-event-container > *', function(ev) {\n\t\t\t\t\tvar seg = $(this).data('fc-seg'); // grab segment data. put there by View::renderEvents\n\n\t\t\t\t\t// only call the handlers if there is not a drag/resize in progress\n\t\t\t\t\tif (seg && !_this.isDraggingSeg && !_this.isResizingSeg) {\n\t\t\t\t\t\treturn func.call(this, seg, ev); // `this` will be the event element\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t);\n\t},\n\n\n\t// Updates internal state and triggers handlers for when an event element is moused over\n\ttriggerSegMouseover: function(seg, ev) {\n\t\tif (!this.mousedOverSeg) {\n\t\t\tthis.mousedOverSeg = seg;\n\t\t\tthis.view.trigger('eventMouseover', seg.el[0], seg.event, ev);\n\t\t}\n\t},\n\n\n\t// Updates internal state and triggers handlers for when an event element is moused out.\n\t// Can be given no arguments, in which case it will mouseout the segment that was previously moused over.\n\ttriggerSegMouseout: function(seg, ev) {\n\t\tev = ev || {}; // if given no args, make a mock mouse event\n\n\t\tif (this.mousedOverSeg) {\n\t\t\tseg = seg || this.mousedOverSeg; // if given no args, use the currently moused-over segment\n\t\t\tthis.mousedOverSeg = null;\n\t\t\tthis.view.trigger('eventMouseout', seg.el[0], seg.event, ev);\n\t\t}\n\t},\n\n\n\t/* Event Dragging\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Called when the user does a mousedown on an event, which might lead to dragging.\n\t// Generic enough to work with any type of Grid.\n\tsegDragMousedown: function(seg, ev) {\n\t\tvar _this = this;\n\t\tvar view = this.view;\n\t\tvar el = seg.el;\n\t\tvar event = seg.event;\n\t\tvar dropLocation;\n\n\t\t// A clone of the original element that will move with the mouse\n\t\tvar mouseFollower = new MouseFollower(seg.el, {\n\t\t\tparentEl: view.el,\n\t\t\topacity: view.opt('dragOpacity'),\n\t\t\trevertDuration: view.opt('dragRevertDuration'),\n\t\t\tzIndex: 2 // one above the .fc-view\n\t\t});\n\n\t\t// Tracks mouse movement over the *view's* coordinate map. Allows dragging and dropping between subcomponents\n\t\t// of the view.\n\t\tvar dragListener = new DragListener(view.coordMap, {\n\t\t\tdistance: 5,\n\t\t\tscroll: view.opt('dragScroll'),\n\t\t\tlistenStart: function(ev) {\n\t\t\t\tmouseFollower.hide(); // don't show until we know this is a real drag\n\t\t\t\tmouseFollower.start(ev);\n\t\t\t},\n\t\t\tdragStart: function(ev) {\n\t\t\t\t_this.triggerSegMouseout(seg, ev); // ensure a mouseout on the manipulated event has been reported\n\t\t\t\t_this.isDraggingSeg = true;\n\t\t\t\tview.hideEvent(event); // hide all event segments. our mouseFollower will take over\n\t\t\t\tview.trigger('eventDragStart', el[0], event, ev, {}); // last argument is jqui dummy\n\t\t\t},\n\t\t\tcellOver: function(cell, isOrig) {\n\t\t\t\tvar origCell = seg.cell || dragListener.origCell; // starting cell could be forced (DayGrid.limit)\n\n\t\t\t\tdropLocation = _this.computeEventDrop(origCell, cell, event);\n\t\t\t\tif (dropLocation) {\n\t\t\t\t\tif (view.renderDrag(dropLocation, seg)) { // have the subclass render a visual indication\n\t\t\t\t\t\tmouseFollower.hide(); // if the subclass is already using a mock event \"helper\", hide our own\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tmouseFollower.show();\n\t\t\t\t\t}\n\t\t\t\t\tif (isOrig) {\n\t\t\t\t\t\tdropLocation = null; // needs to have moved cells to be a valid drop\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// have the helper follow the mouse (no snapping) with a warning-style cursor\n\t\t\t\t\tmouseFollower.show();\n\t\t\t\t\tdisableCursor();\n\t\t\t\t}\n\t\t\t},\n\t\t\tcellOut: function() { // called before mouse moves to a different cell OR moved out of all cells\n\t\t\t\tdropLocation = null;\n\t\t\t\tview.destroyDrag(); // unrender whatever was done in renderDrag\n\t\t\t\tmouseFollower.show(); // show in case we are moving out of all cells\n\t\t\t\tenableCursor();\n\t\t\t},\n\t\t\tdragStop: function(ev) {\n\t\t\t\t// do revert animation if hasn't changed. calls a callback when finished (whether animation or not)\n\t\t\t\tmouseFollower.stop(!dropLocation, function() {\n\t\t\t\t\t_this.isDraggingSeg = false;\n\t\t\t\t\tview.destroyDrag();\n\t\t\t\t\tview.showEvent(event);\n\t\t\t\t\tview.trigger('eventDragStop', el[0], event, ev, {}); // last argument is jqui dummy\n\n\t\t\t\t\tif (dropLocation) {\n\t\t\t\t\t\tview.reportEventDrop(event, dropLocation, el, ev);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tenableCursor();\n\t\t\t},\n\t\t\tlistenStop: function() {\n\t\t\t\tmouseFollower.stop(); // put in listenStop in case there was a mousedown but the drag never started\n\t\t\t}\n\t\t});\n\n\t\tdragListener.mousedown(ev); // start listening, which will eventually lead to a dragStart\n\t},\n\n\n\t// Given the cell an event drag began, and the cell event was dropped, calculates the new start/end/allDay\n\t// values for the event. Subclasses may override and set additional properties to be used by renderDrag.\n\t// A falsy returned value indicates an invalid drop.\n\tcomputeEventDrop: function(startCell, endCell, event) {\n\t\tvar dragStart = startCell.start;\n\t\tvar dragEnd = endCell.start;\n\t\tvar delta;\n\t\tvar newStart;\n\t\tvar newEnd;\n\t\tvar newAllDay;\n\t\tvar dropLocation;\n\n\t\tif (dragStart.hasTime() === dragEnd.hasTime()) {\n\t\t\tdelta = diffDayTime(dragEnd, dragStart);\n\t\t\tnewStart = event.start.clone().add(delta);\n\t\t\tif (event.end === null) { // do we need to compute an end?\n\t\t\t\tnewEnd = null;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tnewEnd = event.end.clone().add(delta);\n\t\t\t}\n\t\t\tnewAllDay = event.allDay; // keep it the same\n\t\t}\n\t\telse {\n\t\t\t// if switching from day <-> timed, start should be reset to the dropped date, and the end cleared\n\t\t\tnewStart = dragEnd.clone();\n\t\t\tnewEnd = null; // end should be cleared\n\t\t\tnewAllDay = !dragEnd.hasTime();\n\t\t}\n\n\t\tdropLocation = {\n\t\t\tstart: newStart,\n\t\t\tend: newEnd,\n\t\t\tallDay: newAllDay\n\t\t};\n\n\t\tif (!this.view.calendar.isEventRangeAllowed(dropLocation, event)) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn dropLocation;\n\t},\n\n\n\t/* External Element Dragging\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Called when a jQuery UI drag is initiated anywhere in the DOM\n\tdocumentDragStart: function(ev, ui) {\n\t\tvar view = this.view;\n\t\tvar el;\n\t\tvar accept;\n\n\t\tif (view.opt('droppable')) { // only listen if this setting is on\n\t\t\tel = $(ev.target);\n\n\t\t\t// Test that the dragged element passes the dropAccept selector or filter function.\n\t\t\t// FYI, the default is \"*\" (matches all)\n\t\t\taccept = view.opt('dropAccept');\n\t\t\tif ($.isFunction(accept) ? accept.call(el[0], el) : el.is(accept)) {\n\n\t\t\t\tthis.startExternalDrag(el, ev, ui);\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Called when a jQuery UI drag starts and it needs to be monitored for cell dropping\n\tstartExternalDrag: function(el, ev, ui) {\n\t\tvar _this = this;\n\t\tvar meta = getDraggedElMeta(el); // extra data about event drop, including possible event to create\n\t\tvar dragListener;\n\t\tvar dropLocation; // a null value signals an unsuccessful drag\n\n\t\t// listener that tracks mouse movement over date-associated pixel regions\n\t\tdragListener = new DragListener(this.coordMap, {\n\t\t\tcellOver: function(cell) {\n\t\t\t\tdropLocation = _this.computeExternalDrop(cell, meta);\n\t\t\t\tif (dropLocation) {\n\t\t\t\t\t_this.renderDrag(dropLocation); // called without a seg parameter\n\t\t\t\t}\n\t\t\t\telse { // invalid drop cell\n\t\t\t\t\tdisableCursor();\n\t\t\t\t}\n\t\t\t},\n\t\t\tcellOut: function() {\n\t\t\t\tdropLocation = null; // signal unsuccessful\n\t\t\t\t_this.destroyDrag();\n\t\t\t\tenableCursor();\n\t\t\t}\n\t\t});\n\n\t\t// gets called, only once, when jqui drag is finished\n\t\t$(document).one('dragstop', function(ev, ui) {\n\t\t\t_this.destroyDrag();\n\t\t\tenableCursor();\n\n\t\t\tif (dropLocation) { // element was dropped on a valid date/time cell\n\t\t\t\t_this.view.reportExternalDrop(meta, dropLocation, el, ev, ui);\n\t\t\t}\n\t\t});\n\n\t\tdragListener.startDrag(ev); // start listening immediately\n\t},\n\n\n\t// Given a cell to be dropped upon, and misc data associated with the jqui drag (guaranteed to be a plain object),\n\t// returns start/end dates for the event that would result from the hypothetical drop. end might be null.\n\t// Returning a null value signals an invalid drop cell.\n\tcomputeExternalDrop: function(cell, meta) {\n\t\tvar dropLocation = {\n\t\t\tstart: cell.start.clone(),\n\t\t\tend: null\n\t\t};\n\n\t\t// if dropped on an all-day cell, and element's metadata specified a time, set it\n\t\tif (meta.startTime && !dropLocation.start.hasTime()) {\n\t\t\tdropLocation.start.time(meta.startTime);\n\t\t}\n\n\t\tif (meta.duration) {\n\t\t\tdropLocation.end = dropLocation.start.clone().add(meta.duration);\n\t\t}\n\n\t\tif (!this.view.calendar.isExternalDropRangeAllowed(dropLocation, meta.eventProps)) {\n\t\t\treturn null;\n\t\t}\n\n\t\treturn dropLocation;\n\t},\n\n\n\n\t/* Drag Rendering (for both events and an external elements)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of an event or external element being dragged.\n\t// `dropLocation` contains hypothetical start/end/allDay values the event would have if dropped. end can be null.\n\t// `seg` is the internal segment object that is being dragged. If dragging an external element, `seg` is null.\n\t// A truthy returned value indicates this method has rendered a helper element.\n\trenderDrag: function(dropLocation, seg) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Unrenders a visual indication of an event or external element being dragged\n\tdestroyDrag: function() {\n\t\t// subclasses must implement\n\t},\n\n\n\t/* Resizing\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Called when the user does a mousedown on an event's resizer, which might lead to resizing.\n\t// Generic enough to work with any type of Grid.\n\tsegResizeMousedown: function(seg, ev) {\n\t\tvar _this = this;\n\t\tvar view = this.view;\n\t\tvar calendar = view.calendar;\n\t\tvar el = seg.el;\n\t\tvar event = seg.event;\n\t\tvar start = event.start;\n\t\tvar oldEnd = calendar.getEventEnd(event);\n\t\tvar newEnd; // falsy if invalid resize\n\t\tvar dragListener;\n\n\t\tfunction destroy() { // resets the rendering to show the original event\n\t\t\t_this.destroyEventResize();\n\t\t\tview.showEvent(event);\n\t\t\tenableCursor();\n\t\t}\n\n\t\t// Tracks mouse movement over the *grid's* coordinate map\n\t\tdragListener = new DragListener(this.coordMap, {\n\t\t\tdistance: 5,\n\t\t\tscroll: view.opt('dragScroll'),\n\t\t\tdragStart: function(ev) {\n\t\t\t\t_this.triggerSegMouseout(seg, ev); // ensure a mouseout on the manipulated event has been reported\n\t\t\t\t_this.isResizingSeg = true;\n\t\t\t\tview.trigger('eventResizeStart', el[0], event, ev, {}); // last argument is jqui dummy\n\t\t\t},\n\t\t\tcellOver: function(cell) {\n\t\t\t\tnewEnd = cell.end;\n\n\t\t\t\tif (!newEnd.isAfter(start)) { // was end moved before start?\n\t\t\t\t\tnewEnd = start.clone().add( // make the event span a single slot\n\t\t\t\t\t\tdiffDayTime(cell.end, cell.start) // assumes all slot durations are the same\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tif (newEnd.isSame(oldEnd)) {\n\t\t\t\t\tnewEnd = null;\n\t\t\t\t}\n\t\t\t\telse if (!calendar.isEventRangeAllowed({ start: start, end: newEnd }, event)) {\n\t\t\t\t\tnewEnd = null;\n\t\t\t\t\tdisableCursor();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t_this.renderEventResize({ start: start, end: newEnd }, seg);\n\t\t\t\t\tview.hideEvent(event);\n\t\t\t\t}\n\t\t\t},\n\t\t\tcellOut: function() { // called before mouse moves to a different cell OR moved out of all cells\n\t\t\t\tnewEnd = null;\n\t\t\t\tdestroy();\n\t\t\t},\n\t\t\tdragStop: function(ev) {\n\t\t\t\t_this.isResizingSeg = false;\n\t\t\t\tdestroy();\n\t\t\t\tview.trigger('eventResizeStop', el[0], event, ev, {}); // last argument is jqui dummy\n\n\t\t\t\tif (newEnd) { // valid date to resize to?\n\t\t\t\t\tview.reportEventResize(event, newEnd, el, ev);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tdragListener.mousedown(ev); // start listening, which will eventually lead to a dragStart\n\t},\n\n\n\t// Renders a visual indication of an event being resized.\n\t// `range` has the updated dates of the event. `seg` is the original segment object involved in the drag.\n\trenderEventResize: function(range, seg) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Unrenders a visual indication of an event being resized.\n\tdestroyEventResize: function() {\n\t\t// subclasses must implement\n\t},\n\n\n\t/* Rendering Utils\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Compute the text that should be displayed on an event's element.\n\t// `range` can be the Event object itself, or something range-like, with at least a `start`.\n\t// The `timeFormat` options and the grid's default format is used, but `formatStr` can override.\n\tgetEventTimeText: function(range, formatStr) {\n\n\t\tformatStr = formatStr || this.eventTimeFormat;\n\n\t\tif (range.end && this.displayEventEnd) {\n\t\t\treturn this.view.formatRange(range, formatStr);\n\t\t}\n\t\telse {\n\t\t\treturn range.start.format(formatStr);\n\t\t}\n\t},\n\n\n\t// Generic utility for generating the HTML classNames for an event segment's element\n\tgetSegClasses: function(seg, isDraggable, isResizable) {\n\t\tvar event = seg.event;\n\t\tvar classes = [\n\t\t\t'fc-event',\n\t\t\tseg.isStart ? 'fc-start' : 'fc-not-start',\n\t\t\tseg.isEnd ? 'fc-end' : 'fc-not-end'\n\t\t].concat(\n\t\t\tevent.className,\n\t\t\tevent.source ? event.source.className : []\n\t\t);\n\n\t\tif (isDraggable) {\n\t\t\tclasses.push('fc-draggable');\n\t\t}\n\t\tif (isResizable) {\n\t\t\tclasses.push('fc-resizable');\n\t\t}\n\n\t\treturn classes;\n\t},\n\n\n\t// Utility for generating a CSS string with all the event skin-related properties\n\tgetEventSkinCss: function(event) {\n\t\tvar view = this.view;\n\t\tvar source = event.source || {};\n\t\tvar eventColor = event.color;\n\t\tvar sourceColor = source.color;\n\t\tvar optionColor = view.opt('eventColor');\n\t\tvar backgroundColor =\n\t\t\tevent.backgroundColor ||\n\t\t\teventColor ||\n\t\t\tsource.backgroundColor ||\n\t\t\tsourceColor ||\n\t\t\tview.opt('eventBackgroundColor') ||\n\t\t\toptionColor;\n\t\tvar borderColor =\n\t\t\tevent.borderColor ||\n\t\t\teventColor ||\n\t\t\tsource.borderColor ||\n\t\t\tsourceColor ||\n\t\t\tview.opt('eventBorderColor') ||\n\t\t\toptionColor;\n\t\tvar textColor =\n\t\t\tevent.textColor ||\n\t\t\tsource.textColor ||\n\t\t\tview.opt('eventTextColor');\n\t\tvar statements = [];\n\t\tif (backgroundColor) {\n\t\t\tstatements.push('background-color:' + backgroundColor);\n\t\t}\n\t\tif (borderColor) {\n\t\t\tstatements.push('border-color:' + borderColor);\n\t\t}\n\t\tif (textColor) {\n\t\t\tstatements.push('color:' + textColor);\n\t\t}\n\t\treturn statements.join(';');\n\t},\n\n\n\t/* Converting events -> ranges -> segs\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Converts an array of event objects into an array of event segment objects.\n\t// A custom `rangeToSegsFunc` may be given for arbitrarily slicing up events.\n\teventsToSegs: function(events, rangeToSegsFunc) {\n\t\tvar eventRanges = this.eventsToRanges(events);\n\t\tvar segs = [];\n\t\tvar i;\n\n\t\tfor (i = 0; i < eventRanges.length; i++) {\n\t\t\tsegs.push.apply(\n\t\t\t\tsegs,\n\t\t\t\tthis.eventRangeToSegs(eventRanges[i], rangeToSegsFunc)\n\t\t\t);\n\t\t}\n\n\t\treturn segs;\n\t},\n\n\n\t// Converts an array of events into an array of \"range\" objects.\n\t// A \"range\" object is a plain object with start/end properties denoting the time it covers. Also an event property.\n\t// For \"normal\" events, this will be identical to the event's start/end, but for \"inverse-background\" events,\n\t// will create an array of ranges that span the time *not* covered by the given event.\n\teventsToRanges: function(events) {\n\t\tvar _this = this;\n\t\tvar eventsById = groupEventsById(events);\n\t\tvar ranges = [];\n\n\t\t// group by ID so that related inverse-background events can be rendered together\n\t\t$.each(eventsById, function(id, eventGroup) {\n\t\t\tif (eventGroup.length) {\n\t\t\t\tranges.push.apply(\n\t\t\t\t\tranges,\n\t\t\t\t\tisInverseBgEvent(eventGroup[0]) ?\n\t\t\t\t\t\t_this.eventsToInverseRanges(eventGroup) :\n\t\t\t\t\t\t_this.eventsToNormalRanges(eventGroup)\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\n\t\treturn ranges;\n\t},\n\n\n\t// Converts an array of \"normal\" events (not inverted rendering) into a parallel array of ranges\n\teventsToNormalRanges: function(events) {\n\t\tvar calendar = this.view.calendar;\n\t\tvar ranges = [];\n\t\tvar i, event;\n\t\tvar eventStart, eventEnd;\n\n\t\tfor (i = 0; i < events.length; i++) {\n\t\t\tevent = events[i];\n\n\t\t\t// make copies and normalize by stripping timezone\n\t\t\teventStart = event.start.clone().stripZone();\n\t\t\teventEnd = calendar.getEventEnd(event).stripZone();\n\n\t\t\tranges.push({\n\t\t\t\tevent: event,\n\t\t\t\tstart: eventStart,\n\t\t\t\tend: eventEnd,\n\t\t\t\teventStartMS: +eventStart,\n\t\t\t\teventDurationMS: eventEnd - eventStart\n\t\t\t});\n\t\t}\n\n\t\treturn ranges;\n\t},\n\n\n\t// Converts an array of events, with inverse-background rendering, into an array of range objects.\n\t// The range objects will cover all the time NOT covered by the events.\n\teventsToInverseRanges: function(events) {\n\t\tvar view = this.view;\n\t\tvar viewStart = view.start.clone().stripZone(); // normalize timezone\n\t\tvar viewEnd = view.end.clone().stripZone(); // normalize timezone\n\t\tvar normalRanges = this.eventsToNormalRanges(events); // will give us normalized dates we can use w/o copies\n\t\tvar inverseRanges = [];\n\t\tvar event0 = events[0]; // assign this to each range's `.event`\n\t\tvar start = viewStart; // the end of the previous range. the start of the new range\n\t\tvar i, normalRange;\n\n\t\t// ranges need to be in order. required for our date-walking algorithm\n\t\tnormalRanges.sort(compareNormalRanges);\n\n\t\tfor (i = 0; i < normalRanges.length; i++) {\n\t\t\tnormalRange = normalRanges[i];\n\n\t\t\t// add the span of time before the event (if there is any)\n\t\t\tif (normalRange.start > start) { // compare millisecond time (skip any ambig logic)\n\t\t\t\tinverseRanges.push({\n\t\t\t\t\tevent: event0,\n\t\t\t\t\tstart: start,\n\t\t\t\t\tend: normalRange.start\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tstart = normalRange.end;\n\t\t}\n\n\t\t// add the span of time after the last event (if there is any)\n\t\tif (start < viewEnd) { // compare millisecond time (skip any ambig logic)\n\t\t\tinverseRanges.push({\n\t\t\t\tevent: event0,\n\t\t\t\tstart: start,\n\t\t\t\tend: viewEnd\n\t\t\t});\n\t\t}\n\n\t\treturn inverseRanges;\n\t},\n\n\n\t// Slices the given event range into one or more segment objects.\n\t// A `rangeToSegsFunc` custom slicing function can be given.\n\teventRangeToSegs: function(eventRange, rangeToSegsFunc) {\n\t\tvar segs;\n\t\tvar i, seg;\n\n\t\tif (rangeToSegsFunc) {\n\t\t\tsegs = rangeToSegsFunc(eventRange);\n\t\t}\n\t\telse {\n\t\t\tsegs = this.rangeToSegs(eventRange); // defined by the subclass\n\t\t}\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tseg = segs[i];\n\t\t\tseg.event = eventRange.event;\n\t\t\tseg.eventStartMS = eventRange.eventStartMS;\n\t\t\tseg.eventDurationMS = eventRange.eventDurationMS;\n\t\t}\n\n\t\treturn segs;\n\t}\n\n});\n\n\n/* Utilities\n----------------------------------------------------------------------------------------------------------------------*/\n\n\nfunction isBgEvent(event) { // returns true if background OR inverse-background\n\tvar rendering = getEventRendering(event);\n\treturn rendering === 'background' || rendering === 'inverse-background';\n}\n\n\nfunction isInverseBgEvent(event) {\n\treturn getEventRendering(event) === 'inverse-background';\n}\n\n\nfunction getEventRendering(event) {\n\treturn firstDefined((event.source || {}).rendering, event.rendering);\n}\n\n\nfunction groupEventsById(events) {\n\tvar eventsById = {};\n\tvar i, event;\n\n\tfor (i = 0; i < events.length; i++) {\n\t\tevent = events[i];\n\t\t(eventsById[event._id] || (eventsById[event._id] = [])).push(event);\n\t}\n\n\treturn eventsById;\n}\n\n\n// A cmp function for determining which non-inverted \"ranges\" (see above) happen earlier\nfunction compareNormalRanges(range1, range2) {\n\treturn range1.eventStartMS - range2.eventStartMS; // earlier ranges go first\n}\n\n\n// A cmp function for determining which segments should take visual priority\n// DOES NOT WORK ON INVERTED BACKGROUND EVENTS because they have no eventStartMS/eventDurationMS\nfunction compareSegs(seg1, seg2) {\n\treturn seg1.eventStartMS - seg2.eventStartMS || // earlier events go first\n\t\tseg2.eventDurationMS - seg1.eventDurationMS || // tie? longer events go first\n\t\tseg2.event.allDay - seg1.event.allDay || // tie? put all-day events first (booleans cast to 0/1)\n\t\t(seg1.event.title || '').localeCompare(seg2.event.title); // tie? alphabetically by title\n}\n\nfc.compareSegs = compareSegs; // export\n\n\n/* External-Dragging-Element Data\n----------------------------------------------------------------------------------------------------------------------*/\n\n// Require all HTML5 data-* attributes used by FullCalendar to have this prefix.\n// A value of '' will query attributes like data-event. A value of 'fc' will query attributes like data-fc-event.\nfc.dataAttrPrefix = '';\n\n// Given a jQuery element that might represent a dragged FullCalendar event, returns an intermediate data structure\n// to be used for Event Object creation.\n// A defined `.eventProps`, even when empty, indicates that an event should be created.\nfunction getDraggedElMeta(el) {\n\tvar prefix = fc.dataAttrPrefix;\n\tvar eventProps; // properties for creating the event, not related to date/time\n\tvar startTime; // a Duration\n\tvar duration;\n\tvar stick;\n\n\tif (prefix) { prefix += '-'; }\n\teventProps = el.data(prefix + 'event') || null;\n\n\tif (eventProps) {\n\t\tif (typeof eventProps === 'object') {\n\t\t\teventProps = $.extend({}, eventProps); // make a copy\n\t\t}\n\t\telse { // something like 1 or true. still signal event creation\n\t\t\teventProps = {};\n\t\t}\n\n\t\t// pluck special-cased date/time properties\n\t\tstartTime = eventProps.start;\n\t\tif (startTime == null) { startTime = eventProps.time; } // accept 'time' as well\n\t\tduration = eventProps.duration;\n\t\tstick = eventProps.stick;\n\t\tdelete eventProps.start;\n\t\tdelete eventProps.time;\n\t\tdelete eventProps.duration;\n\t\tdelete eventProps.stick;\n\t}\n\n\t// fallback to standalone attribute values for each of the date/time properties\n\tif (startTime == null) { startTime = el.data(prefix + 'start'); }\n\tif (startTime == null) { startTime = el.data(prefix + 'time'); } // accept 'time' as well\n\tif (duration == null) { duration = el.data(prefix + 'duration'); }\n\tif (stick == null) { stick = el.data(prefix + 'stick'); }\n\n\t// massage into correct data types\n\tstartTime = startTime != null ? moment.duration(startTime) : null;\n\tduration = duration != null ? moment.duration(duration) : null;\n\tstick = Boolean(stick);\n\n\treturn { eventProps: eventProps, startTime: startTime, duration: duration, stick: stick };\n}\n\n\n    /* A component that renders a grid of whole-days that runs horizontally. There can be multiple rows, one per week.\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar DayGrid = Grid.extend({\n\n\tnumbersVisible: false, // should render a row for day/week numbers? set by outside view. TODO: make internal\n\tbottomCoordPadding: 0, // hack for extending the hit area for the last row of the coordinate grid\n\tbreakOnWeeks: null, // should create a new row for each week? set by outside view\n\n\tcellDates: null, // flat chronological array of each cell's dates\n\tdayToCellOffsets: null, // maps days offsets from grid's start date, to cell offsets\n\n\trowEls: null, // set of fake row elements\n\tdayEls: null, // set of whole-day elements comprising the row's background\n\thelperEls: null, // set of cell skeleton elements for rendering the mock event \"helper\"\n\n\n\t// Renders the rows and columns into the component's `this.el`, which should already be assigned.\n\t// isRigid determins whether the individual rows should ignore the contents and be a constant height.\n\t// Relies on the view's colCnt and rowCnt. In the future, this component should probably be self-sufficient.\n\trender: function(isRigid) {\n\t\tvar view = this.view;\n\t\tvar rowCnt = this.rowCnt;\n\t\tvar colCnt = this.colCnt;\n\t\tvar cellCnt = rowCnt * colCnt;\n\t\tvar html = '';\n\t\tvar row;\n\t\tvar i, cell;\n\n\t\tfor (row = 0; row < rowCnt; row++) {\n\t\t\thtml += this.dayRowHtml(row, isRigid);\n\t\t}\n\t\tthis.el.html(html);\n\n\t\tthis.rowEls = this.el.find('.fc-row');\n\t\tthis.dayEls = this.el.find('.fc-day');\n\n\t\t// trigger dayRender with each cell's element\n\t\tfor (i = 0; i < cellCnt; i++) {\n\t\t\tcell = this.getCell(i);\n\t\t\tview.trigger('dayRender', null, cell.start, this.dayEls.eq(i));\n\t\t}\n\n\t\tGrid.prototype.render.call(this); // call the super-method\n\t},\n\n\n\tdestroy: function() {\n\t\tthis.destroySegPopover();\n\t\tGrid.prototype.destroy.call(this); // call the super-method\n\t},\n\n\n\t// Generates the HTML for a single row. `row` is the row number.\n\tdayRowHtml: function(row, isRigid) {\n\t\tvar view = this.view;\n\t\tvar classes = [ 'fc-row', 'fc-week', view.widgetContentClass ];\n\n\t\tif (isRigid) {\n\t\t\tclasses.push('fc-rigid');\n\t\t}\n\n\t\treturn '' +\n\t\t\t'<div class=\"' + classes.join(' ') + '\">' +\n\t\t\t\t'<div class=\"fc-bg\">' +\n\t\t\t\t\t'<table>' +\n\t\t\t\t\t\tthis.rowHtml('day', row) + // leverages RowRenderer. calls dayCellHtml()\n\t\t\t\t\t'</table>' +\n\t\t\t\t'</div>' +\n\t\t\t\t'<div class=\"fc-content-skeleton\">' +\n\t\t\t\t\t'<table>' +\n\t\t\t\t\t\t(this.numbersVisible ?\n\t\t\t\t\t\t\t'<thead>' +\n\t\t\t\t\t\t\t\tthis.rowHtml('number', row) + // leverages RowRenderer. View will define render method\n\t\t\t\t\t\t\t'</thead>' :\n\t\t\t\t\t\t\t''\n\t\t\t\t\t\t\t) +\n\t\t\t\t\t'</table>' +\n\t\t\t\t'</div>' +\n\t\t\t'</div>';\n\t},\n\n\n\t// Renders the HTML for a whole-day cell. Will eventually end up in the day-row's background.\n\t// We go through a 'day' row type instead of just doing a 'bg' row type so that the View can do custom rendering\n\t// specifically for whole-day rows, whereas a 'bg' might also be used for other purposes (TimeGrid bg for example).\n\tdayCellHtml: function(cell) {\n\t\treturn this.bgCellHtml(cell);\n\t},\n\n\n\t/* Options\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Computes a default column header formatting string if `colFormat` is not explicitly defined\n\tcomputeColHeadFormat: function() {\n\t\tif (this.rowCnt > 1) { // more than one week row. day numbers will be in each cell\n\t\t\treturn 'ddd'; // \"Sat\"\n\t\t}\n\t\telse if (this.colCnt > 1) { // multiple days, so full single date string WON'T be in title text\n\t\t\treturn this.view.opt('dayOfMonthFormat'); // \"Sat 12/10\"\n\t\t}\n\t\telse { // single day, so full single date string will probably be in title text\n\t\t\treturn 'dddd'; // \"Saturday\"\n\t\t}\n\t},\n\n\n\t// Computes a default event time formatting string if `timeFormat` is not explicitly defined\n\tcomputeEventTimeFormat: function() {\n\t\treturn this.view.opt('extraSmallTimeFormat'); // like \"6p\" or \"6:30p\"\n\t},\n\n\n\t// Computes a default `displayEventEnd` value if one is not expliclty defined\n\tcomputeDisplayEventEnd: function() {\n\t\treturn this.colCnt == 1; // we'll likely have space if there's only one day\n\t},\n\n\n\t/* Cell System\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Initializes row/col information\n\tupdateCells: function() {\n\t\tvar cellDates;\n\t\tvar firstDay;\n\t\tvar rowCnt;\n\t\tvar colCnt;\n\n\t\tthis.updateCellDates(); // populates cellDates and dayToCellOffsets\n\t\tcellDates = this.cellDates;\n\n\t\tif (this.breakOnWeeks) {\n\t\t\t// count columns until the day-of-week repeats\n\t\t\tfirstDay = cellDates[0].day();\n\t\t\tfor (colCnt = 1; colCnt < cellDates.length; colCnt++) {\n\t\t\t\tif (cellDates[colCnt].day() == firstDay) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\trowCnt = Math.ceil(cellDates.length / colCnt);\n\t\t}\n\t\telse {\n\t\t\trowCnt = 1;\n\t\t\tcolCnt = cellDates.length;\n\t\t}\n\n\t\tthis.rowCnt = rowCnt;\n\t\tthis.colCnt = colCnt;\n\t},\n\n\n\t// Populates cellDates and dayToCellOffsets\n\tupdateCellDates: function() {\n\t\tvar view = this.view;\n\t\tvar date = this.start.clone();\n\t\tvar dates = [];\n\t\tvar offset = -1;\n\t\tvar offsets = [];\n\n\t\twhile (date.isBefore(this.end)) { // loop each day from start to end\n\t\t\tif (view.isHiddenDay(date)) {\n\t\t\t\toffsets.push(offset + 0.5); // mark that it's between offsets\n\t\t\t}\n\t\t\telse {\n\t\t\t\toffset++;\n\t\t\t\toffsets.push(offset);\n\t\t\t\tdates.push(date.clone());\n\t\t\t}\n\t\t\tdate.add(1, 'days');\n\t\t}\n\n\t\tthis.cellDates = dates;\n\t\tthis.dayToCellOffsets = offsets;\n\t},\n\n\n\t// Given a cell object, generates a range object\n\tcomputeCellRange: function(cell) {\n\t\tvar colCnt = this.colCnt;\n\t\tvar index = cell.row * colCnt + (this.isRTL ? colCnt - cell.col - 1 : cell.col);\n\t\tvar start = this.cellDates[index].clone();\n\t\tvar end = start.clone().add(1, 'day');\n\n\t\treturn { start: start, end: end };\n\t},\n\n\n\t// Retrieves the element representing the given row\n\tgetRowEl: function(row) {\n\t\treturn this.rowEls.eq(row);\n\t},\n\n\n\t// Retrieves the element representing the given column\n\tgetColEl: function(col) {\n\t\treturn this.dayEls.eq(col);\n\t},\n\n\n\t// Gets the whole-day element associated with the cell\n\tgetCellDayEl: function(cell) {\n\t\treturn this.dayEls.eq(cell.row * this.colCnt + cell.col);\n\t},\n\n\n\t// Overrides Grid's method for when row coordinates are computed\n\tcomputeRowCoords: function() {\n\t\tvar rowCoords = Grid.prototype.computeRowCoords.call(this); // call the super-method\n\n\t\t// hack for extending last row (used by AgendaView)\n\t\trowCoords[rowCoords.length - 1].bottom += this.bottomCoordPadding;\n\n\t\treturn rowCoords;\n\t},\n\n\n\t/* Dates\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Slices up a date range by row into an array of segments\n\trangeToSegs: function(range) {\n\t\tvar isRTL = this.isRTL;\n\t\tvar rowCnt = this.rowCnt;\n\t\tvar colCnt = this.colCnt;\n\t\tvar segs = [];\n\t\tvar first, last; // inclusive cell-offset range for given range\n\t\tvar row;\n\t\tvar rowFirst, rowLast; // inclusive cell-offset range for current row\n\t\tvar isStart, isEnd;\n\t\tvar segFirst, segLast; // inclusive cell-offset range for segment\n\t\tvar seg;\n\n\t\trange = this.view.computeDayRange(range); // make whole-day range, considering nextDayThreshold\n\t\tfirst = this.dateToCellOffset(range.start);\n\t\tlast = this.dateToCellOffset(range.end.subtract(1, 'days')); // offset of inclusive end date\n\n\t\tfor (row = 0; row < rowCnt; row++) {\n\t\t\trowFirst = row * colCnt;\n\t\t\trowLast = rowFirst + colCnt - 1;\n\n\t\t\t// intersect segment's offset range with the row's\n\t\t\tsegFirst = Math.max(rowFirst, first);\n\t\t\tsegLast = Math.min(rowLast, last);\n\n\t\t\t// deal with in-between indices\n\t\t\tsegFirst = Math.ceil(segFirst); // in-between starts round to next cell\n\t\t\tsegLast = Math.floor(segLast); // in-between ends round to prev cell\n\n\t\t\tif (segFirst <= segLast) { // was there any intersection with the current row?\n\n\t\t\t\t// must be matching integers to be the segment's start/end\n\t\t\t\tisStart = segFirst === first;\n\t\t\t\tisEnd = segLast === last;\n\n\t\t\t\t// translate offsets to be relative to start-of-row\n\t\t\t\tsegFirst -= rowFirst;\n\t\t\t\tsegLast -= rowFirst;\n\n\t\t\t\tseg = { row: row, isStart: isStart, isEnd: isEnd };\n\t\t\t\tif (isRTL) {\n\t\t\t\t\tseg.leftCol = colCnt - segLast - 1;\n\t\t\t\t\tseg.rightCol = colCnt - segFirst - 1;\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tseg.leftCol = segFirst;\n\t\t\t\t\tseg.rightCol = segLast;\n\t\t\t\t}\n\t\t\t\tsegs.push(seg);\n\t\t\t}\n\t\t}\n\n\t\treturn segs;\n\t},\n\n\n\t// Given a date, returns its chronolocial cell-offset from the first cell of the grid.\n\t// If the date lies between cells (because of hiddenDays), returns a floating-point value between offsets.\n\t// If before the first offset, returns a negative number.\n\t// If after the last offset, returns an offset past the last cell offset.\n\t// Only works for *start* dates of cells. Will not work for exclusive end dates for cells.\n\tdateToCellOffset: function(date) {\n\t\tvar offsets = this.dayToCellOffsets;\n\t\tvar day = date.diff(this.start, 'days');\n\n\t\tif (day < 0) {\n\t\t\treturn offsets[0] - 1;\n\t\t}\n\t\telse if (day >= offsets.length) {\n\t\t\treturn offsets[offsets.length - 1] + 1;\n\t\t}\n\t\telse {\n\t\t\treturn offsets[day];\n\t\t}\n\t},\n\n\n\t/* Event Drag Visualization\n\t------------------------------------------------------------------------------------------------------------------*/\n\t// TODO: move to DayGrid.event, similar to what we did with Grid's drag methods\n\n\n\t// Renders a visual indication of an event or external element being dragged.\n\t// The dropLocation's end can be null. seg can be null. See Grid::renderDrag for more info.\n\trenderDrag: function(dropLocation, seg) {\n\t\tvar opacity;\n\n\t\t// always render a highlight underneath\n\t\tthis.renderHighlight(\n\t\t\tthis.view.calendar.ensureVisibleEventRange(dropLocation) // needs to be a proper range\n\t\t);\n\n\t\t// if a segment from the same calendar but another component is being dragged, render a helper event\n\t\tif (seg && !seg.el.closest(this.el).length) {\n\n\t\t\tthis.renderRangeHelper(dropLocation, seg);\n\n\t\t\topacity = this.view.opt('dragOpacity');\n\t\t\tif (opacity !== undefined) {\n\t\t\t\tthis.helperEls.css('opacity', opacity);\n\t\t\t}\n\n\t\t\treturn true; // a helper has been rendered\n\t\t}\n\t},\n\n\n\t// Unrenders any visual indication of a hovering event\n\tdestroyDrag: function() {\n\t\tthis.destroyHighlight();\n\t\tthis.destroyHelper();\n\t},\n\n\n\t/* Event Resize Visualization\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of an event being resized\n\trenderEventResize: function(range, seg) {\n\t\tthis.renderHighlight(range);\n\t\tthis.renderRangeHelper(range, seg);\n\t},\n\n\n\t// Unrenders a visual indication of an event being resized\n\tdestroyEventResize: function() {\n\t\tthis.destroyHighlight();\n\t\tthis.destroyHelper();\n\t},\n\n\n\t/* Event Helper\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a mock \"helper\" event. `sourceSeg` is the associated internal segment object. It can be null.\n\trenderHelper: function(event, sourceSeg) {\n\t\tvar helperNodes = [];\n\t\tvar segs = this.eventsToSegs([ event ]);\n\t\tvar rowStructs;\n\n\t\tsegs = this.renderFgSegEls(segs); // assigns each seg's el and returns a subset of segs that were rendered\n\t\trowStructs = this.renderSegRows(segs);\n\n\t\t// inject each new event skeleton into each associated row\n\t\tthis.rowEls.each(function(row, rowNode) {\n\t\t\tvar rowEl = $(rowNode); // the .fc-row\n\t\t\tvar skeletonEl = $('<div class=\"fc-helper-skeleton\"><table/></div>'); // will be absolutely positioned\n\t\t\tvar skeletonTop;\n\n\t\t\t// If there is an original segment, match the top position. Otherwise, put it at the row's top level\n\t\t\tif (sourceSeg && sourceSeg.row === row) {\n\t\t\t\tskeletonTop = sourceSeg.el.position().top;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tskeletonTop = rowEl.find('.fc-content-skeleton tbody').position().top;\n\t\t\t}\n\n\t\t\tskeletonEl.css('top', skeletonTop)\n\t\t\t\t.find('table')\n\t\t\t\t\t.append(rowStructs[row].tbodyEl);\n\n\t\t\trowEl.append(skeletonEl);\n\t\t\thelperNodes.push(skeletonEl[0]);\n\t\t});\n\n\t\tthis.helperEls = $(helperNodes); // array -> jQuery set\n\t},\n\n\n\t// Unrenders any visual indication of a mock helper event\n\tdestroyHelper: function() {\n\t\tif (this.helperEls) {\n\t\t\tthis.helperEls.remove();\n\t\t\tthis.helperEls = null;\n\t\t}\n\t},\n\n\n\t/* Fill System (highlight, background events, business hours)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\tfillSegTag: 'td', // override the default tag name\n\n\n\t// Renders a set of rectangles over the given segments of days.\n\t// Only returns segments that successfully rendered.\n\trenderFill: function(type, segs) {\n\t\tvar nodes = [];\n\t\tvar i, seg;\n\t\tvar skeletonEl;\n\n\t\tsegs = this.renderFillSegEls(type, segs); // assignes `.el` to each seg. returns successfully rendered segs\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tseg = segs[i];\n\t\t\tskeletonEl = this.renderFillRow(type, seg);\n\t\t\tthis.rowEls.eq(seg.row).append(skeletonEl);\n\t\t\tnodes.push(skeletonEl[0]);\n\t\t}\n\n\t\tthis.elsByFill[type] = $(nodes);\n\n\t\treturn segs;\n\t},\n\n\n\t// Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered.\n\trenderFillRow: function(type, seg) {\n\t\tvar colCnt = this.colCnt;\n\t\tvar startCol = seg.leftCol;\n\t\tvar endCol = seg.rightCol + 1;\n\t\tvar skeletonEl;\n\t\tvar trEl;\n\n\t\tskeletonEl = $(\n\t\t\t'<div class=\"fc-' + type.toLowerCase() + '-skeleton\">' +\n\t\t\t\t'<table><tr/></table>' +\n\t\t\t'</div>'\n\t\t);\n\t\ttrEl = skeletonEl.find('tr');\n\n\t\tif (startCol > 0) {\n\t\t\ttrEl.append('<td colspan=\"' + startCol + '\"/>');\n\t\t}\n\n\t\ttrEl.append(\n\t\t\tseg.el.attr('colspan', endCol - startCol)\n\t\t);\n\n\t\tif (endCol < colCnt) {\n\t\t\ttrEl.append('<td colspan=\"' + (colCnt - endCol) + '\"/>');\n\t\t}\n\n\t\tthis.bookendCells(trEl, type);\n\n\t\treturn skeletonEl;\n\t}\n\n});\n\n    /* Event-rendering methods for the DayGrid class\n----------------------------------------------------------------------------------------------------------------------*/\n\nDayGrid.mixin({\n\n\trowStructs: null, // an array of objects, each holding information about a row's foreground event-rendering\n\n\n\t// Unrenders all events currently rendered on the grid\n\tdestroyEvents: function() {\n\t\tthis.destroySegPopover(); // removes the \"more..\" events popover\n\t\tGrid.prototype.destroyEvents.apply(this, arguments); // calls the super-method\n\t},\n\n\n\t// Retrieves all rendered segment objects currently rendered on the grid\n\tgetEventSegs: function() {\n\t\treturn Grid.prototype.getEventSegs.call(this) // get the segments from the super-method\n\t\t\t.concat(this.popoverSegs || []); // append the segments from the \"more...\" popover\n\t},\n\n\n\t// Renders the given background event segments onto the grid\n\trenderBgSegs: function(segs) {\n\n\t\t// don't render timed background events\n\t\tvar allDaySegs = $.grep(segs, function(seg) {\n\t\t\treturn seg.event.allDay;\n\t\t});\n\n\t\treturn Grid.prototype.renderBgSegs.call(this, allDaySegs); // call the super-method\n\t},\n\n\n\t// Renders the given foreground event segments onto the grid\n\trenderFgSegs: function(segs) {\n\t\tvar rowStructs;\n\n\t\t// render an `.el` on each seg\n\t\t// returns a subset of the segs. segs that were actually rendered\n\t\tsegs = this.renderFgSegEls(segs);\n\n\t\trowStructs = this.rowStructs = this.renderSegRows(segs);\n\n\t\t// append to each row's content skeleton\n\t\tthis.rowEls.each(function(i, rowNode) {\n\t\t\t$(rowNode).find('.fc-content-skeleton > table').append(\n\t\t\t\trowStructs[i].tbodyEl\n\t\t\t);\n\t\t});\n\n\t\treturn segs; // return only the segs that were actually rendered\n\t},\n\n\n\t// Unrenders all currently rendered foreground event segments\n\tdestroyFgSegs: function() {\n\t\tvar rowStructs = this.rowStructs || [];\n\t\tvar rowStruct;\n\n\t\twhile ((rowStruct = rowStructs.pop())) {\n\t\t\trowStruct.tbodyEl.remove();\n\t\t}\n\n\t\tthis.rowStructs = null;\n\t},\n\n\n\t// Uses the given events array to generate <tbody> elements that should be appended to each row's content skeleton.\n\t// Returns an array of rowStruct objects (see the bottom of `renderSegRow`).\n\t// PRECONDITION: each segment shoud already have a rendered and assigned `.el`\n\trenderSegRows: function(segs) {\n\t\tvar rowStructs = [];\n\t\tvar segRows;\n\t\tvar row;\n\n\t\tsegRows = this.groupSegRows(segs); // group into nested arrays\n\n\t\t// iterate each row of segment groupings\n\t\tfor (row = 0; row < segRows.length; row++) {\n\t\t\trowStructs.push(\n\t\t\t\tthis.renderSegRow(row, segRows[row])\n\t\t\t);\n\t\t}\n\n\t\treturn rowStructs;\n\t},\n\n\n\t// Builds the HTML to be used for the default element for an individual segment\n\tfgSegHtml: function(seg, disableResizing) {\n\t\tvar view = this.view;\n\t\tvar event = seg.event;\n\t\tvar isDraggable = view.isEventDraggable(event);\n\t\tvar isResizable = !disableResizing && event.allDay && seg.isEnd && view.isEventResizable(event);\n\t\tvar classes = this.getSegClasses(seg, isDraggable, isResizable);\n\t\tvar skinCss = this.getEventSkinCss(event);\n\t\tvar timeHtml = '';\n\t\tvar titleHtml;\n\n\t\tclasses.unshift('fc-day-grid-event');\n\n\t\t// Only display a timed events time if it is the starting segment\n\t\tif (!event.allDay && seg.isStart) {\n\t\t\ttimeHtml = '<span class=\"fc-time\">' + htmlEscape(this.getEventTimeText(event)) + '</span>';\n\t\t}\n\n\t\ttitleHtml =\n\t\t\t'<span class=\"fc-title\">' +\n\t\t\t\t(htmlEscape(event.title || '') || '&nbsp;') + // we always want one line of height\n\t\t\t'</span>';\n\t\t\n\t\treturn '<a class=\"' + classes.join(' ') + '\"' +\n\t\t\t\t(event.url ?\n\t\t\t\t\t' href=\"' + htmlEscape(event.url) + '\"' :\n\t\t\t\t\t''\n\t\t\t\t\t) +\n\t\t\t\t(skinCss ?\n\t\t\t\t\t' style=\"' + skinCss + '\"' :\n\t\t\t\t\t''\n\t\t\t\t\t) +\n\t\t\t'>' +\n\t\t\t\t'<div class=\"fc-content\">' +\n\t\t\t\t\t(this.isRTL ?\n\t\t\t\t\t\ttitleHtml + ' ' + timeHtml : // put a natural space in between\n\t\t\t\t\t\ttimeHtml + ' ' + titleHtml   //\n\t\t\t\t\t\t) +\n\t\t\t\t'</div>' +\n\t\t\t\t(isResizable ?\n\t\t\t\t\t'<div class=\"fc-resizer\"/>' :\n\t\t\t\t\t''\n\t\t\t\t\t) +\n\t\t\t'</a>';\n\t},\n\n\n\t// Given a row # and an array of segments all in the same row, render a <tbody> element, a skeleton that contains\n\t// the segments. Returns object with a bunch of internal data about how the render was calculated.\n\trenderSegRow: function(row, rowSegs) {\n\t\tvar colCnt = this.colCnt;\n\t\tvar segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels\n\t\tvar levelCnt = Math.max(1, segLevels.length); // ensure at least one level\n\t\tvar tbody = $('<tbody/>');\n\t\tvar segMatrix = []; // lookup for which segments are rendered into which level+col cells\n\t\tvar cellMatrix = []; // lookup for all <td> elements of the level+col matrix\n\t\tvar loneCellMatrix = []; // lookup for <td> elements that only take up a single column\n\t\tvar i, levelSegs;\n\t\tvar col;\n\t\tvar tr;\n\t\tvar j, seg;\n\t\tvar td;\n\n\t\t// populates empty cells from the current column (`col`) to `endCol`\n\t\tfunction emptyCellsUntil(endCol) {\n\t\t\twhile (col < endCol) {\n\t\t\t\t// try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell\n\t\t\t\ttd = (loneCellMatrix[i - 1] || [])[col];\n\t\t\t\tif (td) {\n\t\t\t\t\ttd.attr(\n\t\t\t\t\t\t'rowspan',\n\t\t\t\t\t\tparseInt(td.attr('rowspan') || 1, 10) + 1\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\ttd = $('<td/>');\n\t\t\t\t\ttr.append(td);\n\t\t\t\t}\n\t\t\t\tcellMatrix[i][col] = td;\n\t\t\t\tloneCellMatrix[i][col] = td;\n\t\t\t\tcol++;\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < levelCnt; i++) { // iterate through all levels\n\t\t\tlevelSegs = segLevels[i];\n\t\t\tcol = 0;\n\t\t\ttr = $('<tr/>');\n\n\t\t\tsegMatrix.push([]);\n\t\t\tcellMatrix.push([]);\n\t\t\tloneCellMatrix.push([]);\n\n\t\t\t// levelCnt might be 1 even though there are no actual levels. protect against this.\n\t\t\t// this single empty row is useful for styling.\n\t\t\tif (levelSegs) {\n\t\t\t\tfor (j = 0; j < levelSegs.length; j++) { // iterate through segments in level\n\t\t\t\t\tseg = levelSegs[j];\n\n\t\t\t\t\temptyCellsUntil(seg.leftCol);\n\n\t\t\t\t\t// create a container that occupies or more columns. append the event element.\n\t\t\t\t\ttd = $('<td class=\"fc-event-container\"/>').append(seg.el);\n\t\t\t\t\tif (seg.leftCol != seg.rightCol) {\n\t\t\t\t\t\ttd.attr('colspan', seg.rightCol - seg.leftCol + 1);\n\t\t\t\t\t}\n\t\t\t\t\telse { // a single-column segment\n\t\t\t\t\t\tloneCellMatrix[i][col] = td;\n\t\t\t\t\t}\n\n\t\t\t\t\twhile (col <= seg.rightCol) {\n\t\t\t\t\t\tcellMatrix[i][col] = td;\n\t\t\t\t\t\tsegMatrix[i][col] = seg;\n\t\t\t\t\t\tcol++;\n\t\t\t\t\t}\n\n\t\t\t\t\ttr.append(td);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\temptyCellsUntil(colCnt); // finish off the row\n\t\t\tthis.bookendCells(tr, 'eventSkeleton');\n\t\t\ttbody.append(tr);\n\t\t}\n\n\t\treturn { // a \"rowStruct\"\n\t\t\trow: row, // the row number\n\t\t\ttbodyEl: tbody,\n\t\t\tcellMatrix: cellMatrix,\n\t\t\tsegMatrix: segMatrix,\n\t\t\tsegLevels: segLevels,\n\t\t\tsegs: rowSegs\n\t\t};\n\t},\n\n\n\t// Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.\n\tbuildSegLevels: function(segs) {\n\t\tvar levels = [];\n\t\tvar i, seg;\n\t\tvar j;\n\n\t\t// Give preference to elements with certain criteria, so they have\n\t\t// a chance to be closer to the top.\n\t\tsegs.sort(compareSegs);\n\t\t\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tseg = segs[i];\n\n\t\t\t// loop through levels, starting with the topmost, until the segment doesn't collide with other segments\n\t\t\tfor (j = 0; j < levels.length; j++) {\n\t\t\t\tif (!isDaySegCollision(seg, levels[j])) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t// `j` now holds the desired subrow index\n\t\t\tseg.level = j;\n\n\t\t\t// create new level array if needed and append segment\n\t\t\t(levels[j] || (levels[j] = [])).push(seg);\n\t\t}\n\n\t\t// order segments left-to-right. very important if calendar is RTL\n\t\tfor (j = 0; j < levels.length; j++) {\n\t\t\tlevels[j].sort(compareDaySegCols);\n\t\t}\n\n\t\treturn levels;\n\t},\n\n\n\t// Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row\n\tgroupSegRows: function(segs) {\n\t\tvar segRows = [];\n\t\tvar i;\n\n\t\tfor (i = 0; i < this.rowCnt; i++) {\n\t\t\tsegRows.push([]);\n\t\t}\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tsegRows[segs[i].row].push(segs[i]);\n\t\t}\n\n\t\treturn segRows;\n\t}\n\n});\n\n\n// Computes whether two segments' columns collide. They are assumed to be in the same row.\nfunction isDaySegCollision(seg, otherSegs) {\n\tvar i, otherSeg;\n\n\tfor (i = 0; i < otherSegs.length; i++) {\n\t\totherSeg = otherSegs[i];\n\n\t\tif (\n\t\t\totherSeg.leftCol <= seg.rightCol &&\n\t\t\totherSeg.rightCol >= seg.leftCol\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t}\n\n\treturn false;\n}\n\n\n// A cmp function for determining the leftmost event\nfunction compareDaySegCols(a, b) {\n\treturn a.leftCol - b.leftCol;\n}\n\n    /* Methods relate to limiting the number events for a given day on a DayGrid\n----------------------------------------------------------------------------------------------------------------------*/\n// NOTE: all the segs being passed around in here are foreground segs\n\nDayGrid.mixin({\n\n\tsegPopover: null, // the Popover that holds events that can't fit in a cell. null when not visible\n\tpopoverSegs: null, // an array of segment objects that the segPopover holds. null when not visible\n\n\n\tdestroySegPopover: function() {\n\t\tif (this.segPopover) {\n\t\t\tthis.segPopover.hide(); // will trigger destruction of `segPopover` and `popoverSegs`\n\t\t}\n\t},\n\n\n\t// Limits the number of \"levels\" (vertically stacking layers of events) for each row of the grid.\n\t// `levelLimit` can be false (don't limit), a number, or true (should be computed).\n\tlimitRows: function(levelLimit) {\n\t\tvar rowStructs = this.rowStructs || [];\n\t\tvar row; // row #\n\t\tvar rowLevelLimit;\n\n\t\tfor (row = 0; row < rowStructs.length; row++) {\n\t\t\tthis.unlimitRow(row);\n\n\t\t\tif (!levelLimit) {\n\t\t\t\trowLevelLimit = false;\n\t\t\t}\n\t\t\telse if (typeof levelLimit === 'number') {\n\t\t\t\trowLevelLimit = levelLimit;\n\t\t\t}\n\t\t\telse {\n\t\t\t\trowLevelLimit = this.computeRowLevelLimit(row);\n\t\t\t}\n\n\t\t\tif (rowLevelLimit !== false) {\n\t\t\t\tthis.limitRow(row, rowLevelLimit);\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Computes the number of levels a row will accomodate without going outside its bounds.\n\t// Assumes the row is \"rigid\" (maintains a constant height regardless of what is inside).\n\t// `row` is the row number.\n\tcomputeRowLevelLimit: function(row) {\n\t\tvar rowEl = this.rowEls.eq(row); // the containing \"fake\" row div\n\t\tvar rowHeight = rowEl.height(); // TODO: cache somehow?\n\t\tvar trEls = this.rowStructs[row].tbodyEl.children();\n\t\tvar i, trEl;\n\n\t\t// Reveal one level <tr> at a time and stop when we find one out of bounds\n\t\tfor (i = 0; i < trEls.length; i++) {\n\t\t\ttrEl = trEls.eq(i).removeClass('fc-limited'); // get and reveal\n\t\t\tif (trEl.position().top + trEl.outerHeight() > rowHeight) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\n\t\treturn false; // should not limit at all\n\t},\n\n\n\t// Limits the given grid row to the maximum number of levels and injects \"more\" links if necessary.\n\t// `row` is the row number.\n\t// `levelLimit` is a number for the maximum (inclusive) number of levels allowed.\n\tlimitRow: function(row, levelLimit) {\n\t\tvar _this = this;\n\t\tvar rowStruct = this.rowStructs[row];\n\t\tvar moreNodes = []; // array of \"more\" <a> links and <td> DOM nodes\n\t\tvar col = 0; // col #, left-to-right (not chronologically)\n\t\tvar cell;\n\t\tvar levelSegs; // array of segment objects in the last allowable level, ordered left-to-right\n\t\tvar cellMatrix; // a matrix (by level, then column) of all <td> jQuery elements in the row\n\t\tvar limitedNodes; // array of temporarily hidden level <tr> and segment <td> DOM nodes\n\t\tvar i, seg;\n\t\tvar segsBelow; // array of segment objects below `seg` in the current `col`\n\t\tvar totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies\n\t\tvar colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column)\n\t\tvar td, rowspan;\n\t\tvar segMoreNodes; // array of \"more\" <td> cells that will stand-in for the current seg's cell\n\t\tvar j;\n\t\tvar moreTd, moreWrap, moreLink;\n\n\t\t// Iterates through empty level cells and places \"more\" links inside if need be\n\t\tfunction emptyCellsUntil(endCol) { // goes from current `col` to `endCol`\n\t\t\twhile (col < endCol) {\n\t\t\t\tcell = _this.getCell(row, col);\n\t\t\t\tsegsBelow = _this.getCellSegs(cell, levelLimit);\n\t\t\t\tif (segsBelow.length) {\n\t\t\t\t\ttd = cellMatrix[levelLimit - 1][col];\n\t\t\t\t\tmoreLink = _this.renderMoreLink(cell, segsBelow);\n\t\t\t\t\tmoreWrap = $('<div/>').append(moreLink);\n\t\t\t\t\ttd.append(moreWrap);\n\t\t\t\t\tmoreNodes.push(moreWrap[0]);\n\t\t\t\t}\n\t\t\t\tcol++;\n\t\t\t}\n\t\t}\n\n\t\tif (levelLimit && levelLimit < rowStruct.segLevels.length) { // is it actually over the limit?\n\t\t\tlevelSegs = rowStruct.segLevels[levelLimit - 1];\n\t\t\tcellMatrix = rowStruct.cellMatrix;\n\n\t\t\tlimitedNodes = rowStruct.tbodyEl.children().slice(levelLimit) // get level <tr> elements past the limit\n\t\t\t\t.addClass('fc-limited').get(); // hide elements and get a simple DOM-nodes array\n\n\t\t\t// iterate though segments in the last allowable level\n\t\t\tfor (i = 0; i < levelSegs.length; i++) {\n\t\t\t\tseg = levelSegs[i];\n\t\t\t\temptyCellsUntil(seg.leftCol); // process empty cells before the segment\n\n\t\t\t\t// determine *all* segments below `seg` that occupy the same columns\n\t\t\t\tcolSegsBelow = [];\n\t\t\t\ttotalSegsBelow = 0;\n\t\t\t\twhile (col <= seg.rightCol) {\n\t\t\t\t\tcell = this.getCell(row, col);\n\t\t\t\t\tsegsBelow = this.getCellSegs(cell, levelLimit);\n\t\t\t\t\tcolSegsBelow.push(segsBelow);\n\t\t\t\t\ttotalSegsBelow += segsBelow.length;\n\t\t\t\t\tcol++;\n\t\t\t\t}\n\n\t\t\t\tif (totalSegsBelow) { // do we need to replace this segment with one or many \"more\" links?\n\t\t\t\t\ttd = cellMatrix[levelLimit - 1][seg.leftCol]; // the segment's parent cell\n\t\t\t\t\trowspan = td.attr('rowspan') || 1;\n\t\t\t\t\tsegMoreNodes = [];\n\n\t\t\t\t\t// make a replacement <td> for each column the segment occupies. will be one for each colspan\n\t\t\t\t\tfor (j = 0; j < colSegsBelow.length; j++) {\n\t\t\t\t\t\tmoreTd = $('<td class=\"fc-more-cell\"/>').attr('rowspan', rowspan);\n\t\t\t\t\t\tsegsBelow = colSegsBelow[j];\n\t\t\t\t\t\tcell = this.getCell(row, seg.leftCol + j);\n\t\t\t\t\t\tmoreLink = this.renderMoreLink(cell, [ seg ].concat(segsBelow)); // count seg as hidden too\n\t\t\t\t\t\tmoreWrap = $('<div/>').append(moreLink);\n\t\t\t\t\t\tmoreTd.append(moreWrap);\n\t\t\t\t\t\tsegMoreNodes.push(moreTd[0]);\n\t\t\t\t\t\tmoreNodes.push(moreTd[0]);\n\t\t\t\t\t}\n\n\t\t\t\t\ttd.addClass('fc-limited').after($(segMoreNodes)); // hide original <td> and inject replacements\n\t\t\t\t\tlimitedNodes.push(td[0]);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\temptyCellsUntil(this.colCnt); // finish off the level\n\t\t\trowStruct.moreEls = $(moreNodes); // for easy undoing later\n\t\t\trowStruct.limitedEls = $(limitedNodes); // for easy undoing later\n\t\t}\n\t},\n\n\n\t// Reveals all levels and removes all \"more\"-related elements for a grid's row.\n\t// `row` is a row number.\n\tunlimitRow: function(row) {\n\t\tvar rowStruct = this.rowStructs[row];\n\n\t\tif (rowStruct.moreEls) {\n\t\t\trowStruct.moreEls.remove();\n\t\t\trowStruct.moreEls = null;\n\t\t}\n\n\t\tif (rowStruct.limitedEls) {\n\t\t\trowStruct.limitedEls.removeClass('fc-limited');\n\t\t\trowStruct.limitedEls = null;\n\t\t}\n\t},\n\n\n\t// Renders an <a> element that represents hidden event element for a cell.\n\t// Responsible for attaching click handler as well.\n\trenderMoreLink: function(cell, hiddenSegs) {\n\t\tvar _this = this;\n\t\tvar view = this.view;\n\n\t\treturn $('<a class=\"fc-more\"/>')\n\t\t\t.text(\n\t\t\t\tthis.getMoreLinkText(hiddenSegs.length)\n\t\t\t)\n\t\t\t.on('click', function(ev) {\n\t\t\t\tvar clickOption = view.opt('eventLimitClick');\n\t\t\t\tvar date = cell.start;\n\t\t\t\tvar moreEl = $(this);\n\t\t\t\tvar dayEl = _this.getCellDayEl(cell);\n\t\t\t\tvar allSegs = _this.getCellSegs(cell);\n\n\t\t\t\t// rescope the segments to be within the cell's date\n\t\t\t\tvar reslicedAllSegs = _this.resliceDaySegs(allSegs, date);\n\t\t\t\tvar reslicedHiddenSegs = _this.resliceDaySegs(hiddenSegs, date);\n\n\t\t\t\tif (typeof clickOption === 'function') {\n\t\t\t\t\t// the returned value can be an atomic option\n\t\t\t\t\tclickOption = view.trigger('eventLimitClick', null, {\n\t\t\t\t\t\tdate: date,\n\t\t\t\t\t\tdayEl: dayEl,\n\t\t\t\t\t\tmoreEl: moreEl,\n\t\t\t\t\t\tsegs: reslicedAllSegs,\n\t\t\t\t\t\thiddenSegs: reslicedHiddenSegs\n\t\t\t\t\t}, ev);\n\t\t\t\t}\n\n\t\t\t\tif (clickOption === 'popover') {\n\t\t\t\t\t_this.showSegPopover(cell, moreEl, reslicedAllSegs);\n\t\t\t\t}\n\t\t\t\telse if (typeof clickOption === 'string') { // a view name\n\t\t\t\t\tview.calendar.zoomTo(date, clickOption);\n\t\t\t\t}\n\t\t\t});\n\t},\n\n\n\t// Reveals the popover that displays all events within a cell\n\tshowSegPopover: function(cell, moreLink, segs) {\n\t\tvar _this = this;\n\t\tvar view = this.view;\n\t\tvar moreWrap = moreLink.parent(); // the <div> wrapper around the <a>\n\t\tvar topEl; // the element we want to match the top coordinate of\n\t\tvar options;\n\n\t\tif (this.rowCnt == 1) {\n\t\t\ttopEl = view.el; // will cause the popover to cover any sort of header\n\t\t}\n\t\telse {\n\t\t\ttopEl = this.rowEls.eq(cell.row); // will align with top of row\n\t\t}\n\n\t\toptions = {\n\t\t\tclassName: 'fc-more-popover',\n\t\t\tcontent: this.renderSegPopoverContent(cell, segs),\n\t\t\tparentEl: this.el,\n\t\t\ttop: topEl.offset().top,\n\t\t\tautoHide: true, // when the user clicks elsewhere, hide the popover\n\t\t\tviewportConstrain: view.opt('popoverViewportConstrain'),\n\t\t\thide: function() {\n\t\t\t\t// destroy everything when the popover is hidden\n\t\t\t\t_this.segPopover.destroy();\n\t\t\t\t_this.segPopover = null;\n\t\t\t\t_this.popoverSegs = null;\n\t\t\t}\n\t\t};\n\n\t\t// Determine horizontal coordinate.\n\t\t// We use the moreWrap instead of the <td> to avoid border confusion.\n\t\tif (this.isRTL) {\n\t\t\toptions.right = moreWrap.offset().left + moreWrap.outerWidth() + 1; // +1 to be over cell border\n\t\t}\n\t\telse {\n\t\t\toptions.left = moreWrap.offset().left - 1; // -1 to be over cell border\n\t\t}\n\n\t\tthis.segPopover = new Popover(options);\n\t\tthis.segPopover.show();\n\t},\n\n\n\t// Builds the inner DOM contents of the segment popover\n\trenderSegPopoverContent: function(cell, segs) {\n\t\tvar view = this.view;\n\t\tvar isTheme = view.opt('theme');\n\t\tvar title = cell.start.format(view.opt('dayPopoverFormat'));\n\t\tvar content = $(\n\t\t\t'<div class=\"fc-header ' + view.widgetHeaderClass + '\">' +\n\t\t\t\t'<span class=\"fc-close ' +\n\t\t\t\t\t(isTheme ? 'ui-icon ui-icon-closethick' : 'fc-icon fc-icon-x') +\n\t\t\t\t'\"></span>' +\n\t\t\t\t'<span class=\"fc-title\">' +\n\t\t\t\t\thtmlEscape(title) +\n\t\t\t\t'</span>' +\n\t\t\t\t'<div class=\"fc-clear\"/>' +\n\t\t\t'</div>' +\n\t\t\t'<div class=\"fc-body ' + view.widgetContentClass + '\">' +\n\t\t\t\t'<div class=\"fc-event-container\"></div>' +\n\t\t\t'</div>'\n\t\t);\n\t\tvar segContainer = content.find('.fc-event-container');\n\t\tvar i;\n\n\t\t// render each seg's `el` and only return the visible segs\n\t\tsegs = this.renderFgSegEls(segs, true); // disableResizing=true\n\t\tthis.popoverSegs = segs;\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\n\t\t\t// because segments in the popover are not part of a grid coordinate system, provide a hint to any\n\t\t\t// grids that want to do drag-n-drop about which cell it came from\n\t\t\tsegs[i].cell = cell;\n\n\t\t\tsegContainer.append(segs[i].el);\n\t\t}\n\n\t\treturn content;\n\t},\n\n\n\t// Given the events within an array of segment objects, reslice them to be in a single day\n\tresliceDaySegs: function(segs, dayDate) {\n\n\t\t// build an array of the original events\n\t\tvar events = $.map(segs, function(seg) {\n\t\t\treturn seg.event;\n\t\t});\n\n\t\tvar dayStart = dayDate.clone().stripTime();\n\t\tvar dayEnd = dayStart.clone().add(1, 'days');\n\t\tvar dayRange = { start: dayStart, end: dayEnd };\n\n\t\t// slice the events with a custom slicing function\n\t\treturn this.eventsToSegs(\n\t\t\tevents,\n\t\t\tfunction(range) {\n\t\t\t\tvar seg = intersectionToSeg(range, dayRange); // undefind if no intersection\n\t\t\t\treturn seg ? [ seg ] : []; // must return an array of segments\n\t\t\t}\n\t\t);\n\t},\n\n\n\t// Generates the text that should be inside a \"more\" link, given the number of events it represents\n\tgetMoreLinkText: function(num) {\n\t\tvar opt = this.view.opt('eventLimitText');\n\n\t\tif (typeof opt === 'function') {\n\t\t\treturn opt(num);\n\t\t}\n\t\telse {\n\t\t\treturn '+' + num + ' ' + opt;\n\t\t}\n\t},\n\n\n\t// Returns segments within a given cell.\n\t// If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs.\n\tgetCellSegs: function(cell, startLevel) {\n\t\tvar segMatrix = this.rowStructs[cell.row].segMatrix;\n\t\tvar level = startLevel || 0;\n\t\tvar segs = [];\n\t\tvar seg;\n\n\t\twhile (level < segMatrix.length) {\n\t\t\tseg = segMatrix[level][cell.col];\n\t\t\tif (seg) {\n\t\t\t\tsegs.push(seg);\n\t\t\t}\n\t\t\tlevel++;\n\t\t}\n\n\t\treturn segs;\n\t}\n\n});\n\n    /* A component that renders one or more columns of vertical time slots\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar TimeGrid = Grid.extend({\n\n\tslotDuration: null, // duration of a \"slot\", a distinct time segment on given day, visualized by lines\n\tsnapDuration: null, // granularity of time for dragging and selecting\n\n\tminTime: null, // Duration object that denotes the first visible time of any given day\n\tmaxTime: null, // Duration object that denotes the exclusive visible end time of any given day\n\n\taxisFormat: null, // formatting string for times running along vertical axis\n\n\tdayEls: null, // cells elements in the day-row background\n\tslatEls: null, // elements running horizontally across all columns\n\n\tslatTops: null, // an array of top positions, relative to the container. last item holds bottom of last slot\n\n\thelperEl: null, // cell skeleton element for rendering the mock event \"helper\"\n\n\tbusinessHourSegs: null,\n\n\n\tconstructor: function() {\n\t\tGrid.apply(this, arguments); // call the super-constructor\n\t\tthis.processOptions();\n\t},\n\n\n\t// Renders the time grid into `this.el`, which should already be assigned.\n\t// Relies on the view's colCnt. In the future, this component should probably be self-sufficient.\n\trender: function() {\n\t\tthis.el.html(this.renderHtml());\n\t\tthis.dayEls = this.el.find('.fc-day');\n\t\tthis.slatEls = this.el.find('.fc-slats tr');\n\n\t\tthis.computeSlatTops();\n\t\tthis.renderBusinessHours();\n\t\tGrid.prototype.render.call(this); // call the super-method\n\t},\n\n\n\trenderBusinessHours: function() {\n\t\tvar events = this.view.calendar.getBusinessHoursEvents();\n\t\tthis.businessHourSegs = this.renderFill('businessHours', this.eventsToSegs(events), 'bgevent');\n\t},\n\n\n\t// Renders the basic HTML skeleton for the grid\n\trenderHtml: function() {\n\t\treturn '' +\n\t\t\t'<div class=\"fc-bg\">' +\n\t\t\t\t'<table>' +\n\t\t\t\t\tthis.rowHtml('slotBg') + // leverages RowRenderer, which will call slotBgCellHtml\n\t\t\t\t'</table>' +\n\t\t\t'</div>' +\n\t\t\t'<div class=\"fc-slats\">' +\n\t\t\t\t'<table>' +\n\t\t\t\t\tthis.slatRowHtml() +\n\t\t\t\t'</table>' +\n\t\t\t'</div>';\n\t},\n\n\n\t// Renders the HTML for a vertical background cell behind the slots.\n\t// This method is distinct from 'bg' because we wanted a new `rowType` so the View could customize the rendering.\n\tslotBgCellHtml: function(cell) {\n\t\treturn this.bgCellHtml(cell);\n\t},\n\n\n\t// Generates the HTML for the horizontal \"slats\" that run width-wise. Has a time axis on a side. Depends on RTL.\n\tslatRowHtml: function() {\n\t\tvar view = this.view;\n\t\tvar isRTL = this.isRTL;\n\t\tvar html = '';\n\t\tvar slotNormal = this.slotDuration.asMinutes() % 15 === 0;\n\t\tvar slotTime = moment.duration(+this.minTime); // wish there was .clone() for durations\n\t\tvar slotDate; // will be on the view's first day, but we only care about its time\n\t\tvar minutes;\n\t\tvar axisHtml;\n\n\t\t// Calculate the time for each slot\n\t\twhile (slotTime < this.maxTime) {\n\t\t\tslotDate = this.start.clone().time(slotTime); // will be in UTC but that's good. to avoid DST issues\n\t\t\tminutes = slotDate.minutes();\n\n\t\t\taxisHtml =\n\t\t\t\t'<td class=\"fc-axis fc-time ' + view.widgetContentClass + '\" ' + view.axisStyleAttr() + '>' +\n\t\t\t\t\t((!slotNormal || !minutes) ? // if irregular slot duration, or on the hour, then display the time\n\t\t\t\t\t\t'<span>' + // for matchCellWidths\n\t\t\t\t\t\t\thtmlEscape(slotDate.format(this.axisFormat)) +\n\t\t\t\t\t\t'</span>' :\n\t\t\t\t\t\t''\n\t\t\t\t\t\t) +\n\t\t\t\t'</td>';\n\n\t\t\thtml +=\n\t\t\t\t'<tr ' + (!minutes ? '' : 'class=\"fc-minor\"') + '>' +\n\t\t\t\t\t(!isRTL ? axisHtml : '') +\n\t\t\t\t\t'<td class=\"' + view.widgetContentClass + '\"/>' +\n\t\t\t\t\t(isRTL ? axisHtml : '') +\n\t\t\t\t\"</tr>\";\n\n\t\t\tslotTime.add(this.slotDuration);\n\t\t}\n\n\t\treturn html;\n\t},\n\n\n\t/* Options\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Parses various options into properties of this object\n\tprocessOptions: function() {\n\t\tvar view = this.view;\n\t\tvar slotDuration = view.opt('slotDuration');\n\t\tvar snapDuration = view.opt('snapDuration');\n\n\t\tslotDuration = moment.duration(slotDuration);\n\t\tsnapDuration = snapDuration ? moment.duration(snapDuration) : slotDuration;\n\n\t\tthis.slotDuration = slotDuration;\n\t\tthis.snapDuration = snapDuration;\n\n\t\tthis.minTime = moment.duration(view.opt('minTime'));\n\t\tthis.maxTime = moment.duration(view.opt('maxTime'));\n\n\t\tthis.axisFormat = view.opt('axisFormat') || view.opt('smallTimeFormat');\n\t},\n\n\n\t// Computes a default column header formatting string if `colFormat` is not explicitly defined\n\tcomputeColHeadFormat: function() {\n\t\tif (this.colCnt > 1) { // multiple days, so full single date string WON'T be in title text\n\t\t\treturn this.view.opt('dayOfMonthFormat'); // \"Sat 12/10\"\n\t\t}\n\t\telse { // single day, so full single date string will probably be in title text\n\t\t\treturn 'dddd'; // \"Saturday\"\n\t\t}\n\t},\n\n\n\t// Computes a default event time formatting string if `timeFormat` is not explicitly defined\n\tcomputeEventTimeFormat: function() {\n\t\treturn this.view.opt('noMeridiemTimeFormat'); // like \"6:30\" (no AM/PM)\n\t},\n\n\n\t// Computes a default `displayEventEnd` value if one is not expliclty defined\n\tcomputeDisplayEventEnd: function() {\n\t\treturn true;\n\t},\n\n\n\t/* Cell System\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Initializes row/col information\n\tupdateCells: function() {\n\t\tvar view = this.view;\n\t\tvar colData = [];\n\t\tvar date;\n\n\t\tdate = this.start.clone();\n\t\twhile (date.isBefore(this.end)) {\n\t\t\tcolData.push({\n\t\t\t\tday: date.clone()\n\t\t\t});\n\t\t\tdate.add(1, 'day');\n\t\t\tdate = view.skipHiddenDays(date);\n\t\t}\n\n\t\tif (this.isRTL) {\n\t\t\tcolData.reverse();\n\t\t}\n\n\t\tthis.colData = colData;\n\t\tthis.colCnt = colData.length;\n\t\tthis.rowCnt = Math.ceil((this.maxTime - this.minTime) / this.snapDuration); // # of vertical snaps\n\t},\n\n\n\t// Given a cell object, generates a range object\n\tcomputeCellRange: function(cell) {\n\t\tvar time = this.computeSnapTime(cell.row);\n\t\tvar start = this.view.calendar.rezoneDate(cell.day).time(time);\n\t\tvar end = start.clone().add(this.snapDuration);\n\n\t\treturn { start: start, end: end };\n\t},\n\n\n\t// Retrieves the element representing the given column\n\tgetColEl: function(col) {\n\t\treturn this.dayEls.eq(col);\n\t},\n\n\n\t/* Dates\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Given a row number of the grid, representing a \"snap\", returns a time (Duration) from its start-of-day\n\tcomputeSnapTime: function(row) {\n\t\treturn moment.duration(this.minTime + this.snapDuration * row);\n\t},\n\n\n\t// Slices up a date range by column into an array of segments\n\trangeToSegs: function(range) {\n\t\tvar colCnt = this.colCnt;\n\t\tvar segs = [];\n\t\tvar seg;\n\t\tvar col;\n\t\tvar colDate;\n\t\tvar colRange;\n\n\t\t// normalize :(\n\t\trange = {\n\t\t\tstart: range.start.clone().stripZone(),\n\t\t\tend: range.end.clone().stripZone()\n\t\t};\n\n\t\tfor (col = 0; col < colCnt; col++) {\n\t\t\tcolDate = this.colData[col].day; // will be ambig time/timezone\n\t\t\tcolRange = {\n\t\t\t\tstart: colDate.clone().time(this.minTime),\n\t\t\t\tend: colDate.clone().time(this.maxTime)\n\t\t\t};\n\t\t\tseg = intersectionToSeg(range, colRange); // both will be ambig timezone\n\t\t\tif (seg) {\n\t\t\t\tseg.col = col;\n\t\t\t\tsegs.push(seg);\n\t\t\t}\n\t\t}\n\n\t\treturn segs;\n\t},\n\n\n\t/* Coordinates\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Called when there is a window resize/zoom and we need to recalculate coordinates for the grid\n\tresize: function() {\n\t\tthis.computeSlatTops();\n\t\tthis.updateSegVerticals();\n\t},\n\n\n\t// Computes the top/bottom coordinates of each \"snap\" rows\n\tcomputeRowCoords: function() {\n\t\tvar originTop = this.el.offset().top;\n\t\tvar items = [];\n\t\tvar i;\n\t\tvar item;\n\n\t\tfor (i = 0; i < this.rowCnt; i++) {\n\t\t\titem = {\n\t\t\t\ttop: originTop + this.computeTimeTop(this.computeSnapTime(i))\n\t\t\t};\n\t\t\tif (i > 0) {\n\t\t\t\titems[i - 1].bottom = item.top;\n\t\t\t}\n\t\t\titems.push(item);\n\t\t}\n\t\titem.bottom = item.top + this.computeTimeTop(this.computeSnapTime(i));\n\n\t\treturn items;\n\t},\n\n\n\t// Computes the top coordinate, relative to the bounds of the grid, of the given date.\n\t// A `startOfDayDate` must be given for avoiding ambiguity over how to treat midnight.\n\tcomputeDateTop: function(date, startOfDayDate) {\n\t\treturn this.computeTimeTop(\n\t\t\tmoment.duration(\n\t\t\t\tdate.clone().stripZone() - startOfDayDate.clone().stripTime()\n\t\t\t)\n\t\t);\n\t},\n\n\n\t// Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).\n\tcomputeTimeTop: function(time) {\n\t\tvar slatCoverage = (time - this.minTime) / this.slotDuration; // floating-point value of # of slots covered\n\t\tvar slatIndex;\n\t\tvar slatRemainder;\n\t\tvar slatTop;\n\t\tvar slatBottom;\n\n\t\t// constrain. because minTime/maxTime might be customized\n\t\tslatCoverage = Math.max(0, slatCoverage);\n\t\tslatCoverage = Math.min(this.slatEls.length, slatCoverage);\n\n\t\tslatIndex = Math.floor(slatCoverage); // an integer index of the furthest whole slot\n\t\tslatRemainder = slatCoverage - slatIndex;\n\t\tslatTop = this.slatTops[slatIndex]; // the top position of the furthest whole slot\n\n\t\tif (slatRemainder) { // time spans part-way into the slot\n\t\t\tslatBottom = this.slatTops[slatIndex + 1];\n\t\t\treturn slatTop + (slatBottom - slatTop) * slatRemainder; // part-way between slots\n\t\t}\n\t\telse {\n\t\t\treturn slatTop;\n\t\t}\n\t},\n\n\n\t// Queries each `slatEl` for its position relative to the grid's container and stores it in `slatTops`.\n\t// Includes the the bottom of the last slat as the last item in the array.\n\tcomputeSlatTops: function() {\n\t\tvar tops = [];\n\t\tvar top;\n\n\t\tthis.slatEls.each(function(i, node) {\n\t\t\ttop = $(node).position().top;\n\t\t\ttops.push(top);\n\t\t});\n\n\t\ttops.push(top + this.slatEls.last().outerHeight()); // bottom of the last slat\n\n\t\tthis.slatTops = tops;\n\t},\n\n\n\t/* Event Drag Visualization\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of an event being dragged over the specified date(s).\n\t// dropLocation's end might be null, as well as `seg`. See Grid::renderDrag for more info.\n\t// A returned value of `true` signals that a mock \"helper\" event has been rendered.\n\trenderDrag: function(dropLocation, seg) {\n\t\tvar opacity;\n\n\t\tif (seg) { // if there is event information for this drag, render a helper event\n\t\t\tthis.renderRangeHelper(dropLocation, seg);\n\n\t\t\topacity = this.view.opt('dragOpacity');\n\t\t\tif (opacity !== undefined) {\n\t\t\t\tthis.helperEl.css('opacity', opacity);\n\t\t\t}\n\n\t\t\treturn true; // signal that a helper has been rendered\n\t\t}\n\t\telse {\n\t\t\t// otherwise, just render a highlight\n\t\t\tthis.renderHighlight(\n\t\t\t\tthis.view.calendar.ensureVisibleEventRange(dropLocation) // needs to be a proper range\n\t\t\t);\n\t\t}\n\t},\n\n\n\t// Unrenders any visual indication of an event being dragged\n\tdestroyDrag: function() {\n\t\tthis.destroyHelper();\n\t\tthis.destroyHighlight();\n\t},\n\n\n\t/* Event Resize Visualization\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of an event being resized\n\trenderEventResize: function(range, seg) {\n\t\tthis.renderRangeHelper(range, seg);\n\t},\n\n\n\t// Unrenders any visual indication of an event being resized\n\tdestroyEventResize: function() {\n\t\tthis.destroyHelper();\n\t},\n\n\n\t/* Event Helper\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a mock \"helper\" event. `sourceSeg` is the original segment object and might be null (an external drag)\n\trenderHelper: function(event, sourceSeg) {\n\t\tvar segs = this.eventsToSegs([ event ]);\n\t\tvar tableEl;\n\t\tvar i, seg;\n\t\tvar sourceEl;\n\n\t\tsegs = this.renderFgSegEls(segs); // assigns each seg's el and returns a subset of segs that were rendered\n\t\ttableEl = this.renderSegTable(segs);\n\n\t\t// Try to make the segment that is in the same row as sourceSeg look the same\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tseg = segs[i];\n\t\t\tif (sourceSeg && sourceSeg.col === seg.col) {\n\t\t\t\tsourceEl = sourceSeg.el;\n\t\t\t\tseg.el.css({\n\t\t\t\t\tleft: sourceEl.css('left'),\n\t\t\t\t\tright: sourceEl.css('right'),\n\t\t\t\t\t'margin-left': sourceEl.css('margin-left'),\n\t\t\t\t\t'margin-right': sourceEl.css('margin-right')\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis.helperEl = $('<div class=\"fc-helper-skeleton\"/>')\n\t\t\t.append(tableEl)\n\t\t\t\t.appendTo(this.el);\n\t},\n\n\n\t// Unrenders any mock helper event\n\tdestroyHelper: function() {\n\t\tif (this.helperEl) {\n\t\t\tthis.helperEl.remove();\n\t\t\tthis.helperEl = null;\n\t\t}\n\t},\n\n\n\t/* Selection\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.\n\trenderSelection: function(range) {\n\t\tif (this.view.opt('selectHelper')) { // this setting signals that a mock helper event should be rendered\n\t\t\tthis.renderRangeHelper(range);\n\t\t}\n\t\telse {\n\t\t\tthis.renderHighlight(range);\n\t\t}\n\t},\n\n\n\t// Unrenders any visual indication of a selection\n\tdestroySelection: function() {\n\t\tthis.destroyHelper();\n\t\tthis.destroyHighlight();\n\t},\n\n\n\t/* Fill System (highlight, background events, business hours)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a set of rectangles over the given time segments.\n\t// Only returns segments that successfully rendered.\n\trenderFill: function(type, segs, className) {\n\t\tvar segCols;\n\t\tvar skeletonEl;\n\t\tvar trEl;\n\t\tvar col, colSegs;\n\t\tvar tdEl;\n\t\tvar containerEl;\n\t\tvar dayDate;\n\t\tvar i, seg;\n\n\t\tif (segs.length) {\n\n\t\t\tsegs = this.renderFillSegEls(type, segs); // assignes `.el` to each seg. returns successfully rendered segs\n\t\t\tsegCols = this.groupSegCols(segs); // group into sub-arrays, and assigns 'col' to each seg\n\n\t\t\tclassName = className || type.toLowerCase();\n\t\t\tskeletonEl = $(\n\t\t\t\t'<div class=\"fc-' + className + '-skeleton\">' +\n\t\t\t\t\t'<table><tr/></table>' +\n\t\t\t\t'</div>'\n\t\t\t);\n\t\t\ttrEl = skeletonEl.find('tr');\n\n\t\t\tfor (col = 0; col < segCols.length; col++) {\n\t\t\t\tcolSegs = segCols[col];\n\t\t\t\ttdEl = $('<td/>').appendTo(trEl);\n\n\t\t\t\tif (colSegs.length) {\n\t\t\t\t\tcontainerEl = $('<div class=\"fc-' + className + '-container\"/>').appendTo(tdEl);\n\t\t\t\t\tdayDate = this.colData[col].day;\n\n\t\t\t\t\tfor (i = 0; i < colSegs.length; i++) {\n\t\t\t\t\t\tseg = colSegs[i];\n\t\t\t\t\t\tcontainerEl.append(\n\t\t\t\t\t\t\tseg.el.css({\n\t\t\t\t\t\t\t\ttop: this.computeDateTop(seg.start, dayDate),\n\t\t\t\t\t\t\t\tbottom: -this.computeDateTop(seg.end, dayDate) // the y position of the bottom edge\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.bookendCells(trEl, type);\n\n\t\t\tthis.el.append(skeletonEl);\n\t\t\tthis.elsByFill[type] = skeletonEl;\n\t\t}\n\n\t\treturn segs;\n\t}\n\n});\n\n    /* Event-rendering methods for the TimeGrid class\n----------------------------------------------------------------------------------------------------------------------*/\n\nTimeGrid.mixin({\n\n\teventSkeletonEl: null, // has cells with event-containers, which contain absolutely positioned event elements\n\n\n\t// Renders the given foreground event segments onto the grid\n\trenderFgSegs: function(segs) {\n\t\tsegs = this.renderFgSegEls(segs); // returns a subset of the segs. segs that were actually rendered\n\n\t\tthis.el.append(\n\t\t\tthis.eventSkeletonEl = $('<div class=\"fc-content-skeleton\"/>')\n\t\t\t\t.append(this.renderSegTable(segs))\n\t\t);\n\n\t\treturn segs; // return only the segs that were actually rendered\n\t},\n\n\n\t// Unrenders all currently rendered foreground event segments\n\tdestroyFgSegs: function(segs) {\n\t\tif (this.eventSkeletonEl) {\n\t\t\tthis.eventSkeletonEl.remove();\n\t\t\tthis.eventSkeletonEl = null;\n\t\t}\n\t},\n\n\n\t// Renders and returns the <table> portion of the event-skeleton.\n\t// Returns an object with properties 'tbodyEl' and 'segs'.\n\trenderSegTable: function(segs) {\n\t\tvar tableEl = $('<table><tr/></table>');\n\t\tvar trEl = tableEl.find('tr');\n\t\tvar segCols;\n\t\tvar i, seg;\n\t\tvar col, colSegs;\n\t\tvar containerEl;\n\n\t\tsegCols = this.groupSegCols(segs); // group into sub-arrays, and assigns 'col' to each seg\n\n\t\tthis.computeSegVerticals(segs); // compute and assign top/bottom\n\n\t\tfor (col = 0; col < segCols.length; col++) { // iterate each column grouping\n\t\t\tcolSegs = segCols[col];\n\t\t\tplaceSlotSegs(colSegs); // compute horizontal coordinates, z-index's, and reorder the array\n\n\t\t\tcontainerEl = $('<div class=\"fc-event-container\"/>');\n\n\t\t\t// assign positioning CSS and insert into container\n\t\t\tfor (i = 0; i < colSegs.length; i++) {\n\t\t\t\tseg = colSegs[i];\n\t\t\t\tseg.el.css(this.generateSegPositionCss(seg));\n\n\t\t\t\t// if the height is short, add a className for alternate styling\n\t\t\t\tif (seg.bottom - seg.top < 30) {\n\t\t\t\t\tseg.el.addClass('fc-short');\n\t\t\t\t}\n\n\t\t\t\tcontainerEl.append(seg.el);\n\t\t\t}\n\n\t\t\ttrEl.append($('<td/>').append(containerEl));\n\t\t}\n\n\t\tthis.bookendCells(trEl, 'eventSkeleton');\n\n\t\treturn tableEl;\n\t},\n\n\n\t// Refreshes the CSS top/bottom coordinates for each segment element. Probably after a window resize/zoom.\n\t// Repositions business hours segs too, so not just for events. Maybe shouldn't be here.\n\tupdateSegVerticals: function() {\n\t\tvar allSegs = (this.segs || []).concat(this.businessHourSegs || []);\n\t\tvar i;\n\n\t\tthis.computeSegVerticals(allSegs);\n\n\t\tfor (i = 0; i < allSegs.length; i++) {\n\t\t\tallSegs[i].el.css(\n\t\t\t\tthis.generateSegVerticalCss(allSegs[i])\n\t\t\t);\n\t\t}\n\t},\n\n\n\t// For each segment in an array, computes and assigns its top and bottom properties\n\tcomputeSegVerticals: function(segs) {\n\t\tvar i, seg;\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tseg = segs[i];\n\t\t\tseg.top = this.computeDateTop(seg.start, seg.start);\n\t\t\tseg.bottom = this.computeDateTop(seg.end, seg.start);\n\t\t}\n\t},\n\n\n\t// Renders the HTML for a single event segment's default rendering\n\tfgSegHtml: function(seg, disableResizing) {\n\t\tvar view = this.view;\n\t\tvar event = seg.event;\n\t\tvar isDraggable = view.isEventDraggable(event);\n\t\tvar isResizable = !disableResizing && seg.isEnd && view.isEventResizable(event);\n\t\tvar classes = this.getSegClasses(seg, isDraggable, isResizable);\n\t\tvar skinCss = this.getEventSkinCss(event);\n\t\tvar timeText;\n\t\tvar fullTimeText; // more verbose time text. for the print stylesheet\n\t\tvar startTimeText; // just the start time text\n\n\t\tclasses.unshift('fc-time-grid-event');\n\n\t\tif (view.isMultiDayEvent(event)) { // if the event appears to span more than one day...\n\t\t\t// Don't display time text on segments that run entirely through a day.\n\t\t\t// That would appear as midnight-midnight and would look dumb.\n\t\t\t// Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am)\n\t\t\tif (seg.isStart || seg.isEnd) {\n\t\t\t\ttimeText = this.getEventTimeText(seg);\n\t\t\t\tfullTimeText = this.getEventTimeText(seg, 'LT');\n\t\t\t\tstartTimeText = this.getEventTimeText({ start: seg.start });\n\t\t\t}\n\t\t} else {\n\t\t\t// Display the normal time text for the *event's* times\n\t\t\ttimeText = this.getEventTimeText(event);\n\t\t\tfullTimeText = this.getEventTimeText(event, 'LT');\n\t\t\tstartTimeText = this.getEventTimeText({ start: event.start });\n\t\t}\n\n\t\treturn '<a class=\"' + classes.join(' ') + '\"' +\n\t\t\t(event.url ?\n\t\t\t\t' href=\"' + htmlEscape(event.url) + '\"' :\n\t\t\t\t''\n\t\t\t\t) +\n\t\t\t(skinCss ?\n\t\t\t\t' style=\"' + skinCss + '\"' :\n\t\t\t\t''\n\t\t\t\t) +\n\t\t\t'>' +\n\t\t\t\t'<div class=\"fc-content\">' +\n\t\t\t\t\t(timeText ?\n\t\t\t\t\t\t'<div class=\"fc-time\"' +\n\t\t\t\t\t\t' data-start=\"' + htmlEscape(startTimeText) + '\"' +\n\t\t\t\t\t\t' data-full=\"' + htmlEscape(fullTimeText) + '\"' +\n\t\t\t\t\t\t'>' +\n\t\t\t\t\t\t\t'<span>' + htmlEscape(timeText) + '</span>' +\n\t\t\t\t\t\t'</div>' :\n\t\t\t\t\t\t''\n\t\t\t\t\t\t) +\n\t\t\t\t\t(event.title ?\n\t\t\t\t\t\t'<div class=\"fc-title\">' +\n\t\t\t\t\t\t\thtmlEscape(event.title) +\n\t\t\t\t\t\t'</div>' :\n\t\t\t\t\t\t''\n\t\t\t\t\t\t) +\n\t\t\t\t'</div>' +\n\t\t\t\t'<div class=\"fc-bg\"/>' +\n\t\t\t\t(isResizable ?\n\t\t\t\t\t'<div class=\"fc-resizer\"/>' :\n\t\t\t\t\t''\n\t\t\t\t\t) +\n\t\t\t'</a>';\n\t},\n\n\n\t// Generates an object with CSS properties/values that should be applied to an event segment element.\n\t// Contains important positioning-related properties that should be applied to any event element, customized or not.\n\tgenerateSegPositionCss: function(seg) {\n\t\tvar shouldOverlap = this.view.opt('slotEventOverlap');\n\t\tvar backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point\n\t\tvar forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point\n\t\tvar props = this.generateSegVerticalCss(seg); // get top/bottom first\n\t\tvar left; // amount of space from left edge, a fraction of the total width\n\t\tvar right; // amount of space from right edge, a fraction of the total width\n\n\t\tif (shouldOverlap) {\n\t\t\t// double the width, but don't go beyond the maximum forward coordinate (1.0)\n\t\t\tforwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);\n\t\t}\n\n\t\tif (this.isRTL) {\n\t\t\tleft = 1 - forwardCoord;\n\t\t\tright = backwardCoord;\n\t\t}\n\t\telse {\n\t\t\tleft = backwardCoord;\n\t\t\tright = 1 - forwardCoord;\n\t\t}\n\n\t\tprops.zIndex = seg.level + 1; // convert from 0-base to 1-based\n\t\tprops.left = left * 100 + '%';\n\t\tprops.right = right * 100 + '%';\n\n\t\tif (shouldOverlap && seg.forwardPressure) {\n\t\t\t// add padding to the edge so that forward stacked events don't cover the resizer's icon\n\t\t\tprops[this.isRTL ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width\n\t\t}\n\n\t\treturn props;\n\t},\n\n\n\t// Generates an object with CSS properties for the top/bottom coordinates of a segment element\n\tgenerateSegVerticalCss: function(seg) {\n\t\treturn {\n\t\t\ttop: seg.top,\n\t\t\tbottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container\n\t\t};\n\t},\n\n\n\t// Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col\n\tgroupSegCols: function(segs) {\n\t\tvar segCols = [];\n\t\tvar i;\n\n\t\tfor (i = 0; i < this.colCnt; i++) {\n\t\t\tsegCols.push([]);\n\t\t}\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tsegCols[segs[i].col].push(segs[i]);\n\t\t}\n\n\t\treturn segCols;\n\t}\n\n});\n\n\n// Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.\n// Also reorders the given array by date!\nfunction placeSlotSegs(segs) {\n\tvar levels;\n\tvar level0;\n\tvar i;\n\n\tsegs.sort(compareSegs); // order by date\n\tlevels = buildSlotSegLevels(segs);\n\tcomputeForwardSlotSegs(levels);\n\n\tif ((level0 = levels[0])) {\n\n\t\tfor (i = 0; i < level0.length; i++) {\n\t\t\tcomputeSlotSegPressures(level0[i]);\n\t\t}\n\n\t\tfor (i = 0; i < level0.length; i++) {\n\t\t\tcomputeSlotSegCoords(level0[i], 0, 0);\n\t\t}\n\t}\n}\n\n\n// Builds an array of segments \"levels\". The first level will be the leftmost tier of segments if the calendar is\n// left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.\nfunction buildSlotSegLevels(segs) {\n\tvar levels = [];\n\tvar i, seg;\n\tvar j;\n\n\tfor (i=0; i<segs.length; i++) {\n\t\tseg = segs[i];\n\n\t\t// go through all the levels and stop on the first level where there are no collisions\n\t\tfor (j=0; j<levels.length; j++) {\n\t\t\tif (!computeSlotSegCollisions(seg, levels[j]).length) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tseg.level = j;\n\n\t\t(levels[j] || (levels[j] = [])).push(seg);\n\t}\n\n\treturn levels;\n}\n\n\n// For every segment, figure out the other segments that are in subsequent\n// levels that also occupy the same vertical space. Accumulate in seg.forwardSegs\nfunction computeForwardSlotSegs(levels) {\n\tvar i, level;\n\tvar j, seg;\n\tvar k;\n\n\tfor (i=0; i<levels.length; i++) {\n\t\tlevel = levels[i];\n\n\t\tfor (j=0; j<level.length; j++) {\n\t\t\tseg = level[j];\n\n\t\t\tseg.forwardSegs = [];\n\t\t\tfor (k=i+1; k<levels.length; k++) {\n\t\t\t\tcomputeSlotSegCollisions(seg, levels[k], seg.forwardSegs);\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n// Figure out which path forward (via seg.forwardSegs) results in the longest path until\n// the furthest edge is reached. The number of segments in this path will be seg.forwardPressure\nfunction computeSlotSegPressures(seg) {\n\tvar forwardSegs = seg.forwardSegs;\n\tvar forwardPressure = 0;\n\tvar i, forwardSeg;\n\n\tif (seg.forwardPressure === undefined) { // not already computed\n\n\t\tfor (i=0; i<forwardSegs.length; i++) {\n\t\t\tforwardSeg = forwardSegs[i];\n\n\t\t\t// figure out the child's maximum forward path\n\t\t\tcomputeSlotSegPressures(forwardSeg);\n\n\t\t\t// either use the existing maximum, or use the child's forward pressure\n\t\t\t// plus one (for the forwardSeg itself)\n\t\t\tforwardPressure = Math.max(\n\t\t\t\tforwardPressure,\n\t\t\t\t1 + forwardSeg.forwardPressure\n\t\t\t);\n\t\t}\n\n\t\tseg.forwardPressure = forwardPressure;\n\t}\n}\n\n\n// Calculate seg.forwardCoord and seg.backwardCoord for the segment, where both values range\n// from 0 to 1. If the calendar is left-to-right, the seg.backwardCoord maps to \"left\" and\n// seg.forwardCoord maps to \"right\" (via percentage). Vice-versa if the calendar is right-to-left.\n//\n// The segment might be part of a \"series\", which means consecutive segments with the same pressure\n// who's width is unknown until an edge has been hit. `seriesBackwardPressure` is the number of\n// segments behind this one in the current series, and `seriesBackwardCoord` is the starting\n// coordinate of the first segment in the series.\nfunction computeSlotSegCoords(seg, seriesBackwardPressure, seriesBackwardCoord) {\n\tvar forwardSegs = seg.forwardSegs;\n\tvar i;\n\n\tif (seg.forwardCoord === undefined) { // not already computed\n\n\t\tif (!forwardSegs.length) {\n\n\t\t\t// if there are no forward segments, this segment should butt up against the edge\n\t\t\tseg.forwardCoord = 1;\n\t\t}\n\t\telse {\n\n\t\t\t// sort highest pressure first\n\t\t\tforwardSegs.sort(compareForwardSlotSegs);\n\n\t\t\t// this segment's forwardCoord will be calculated from the backwardCoord of the\n\t\t\t// highest-pressure forward segment.\n\t\t\tcomputeSlotSegCoords(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);\n\t\t\tseg.forwardCoord = forwardSegs[0].backwardCoord;\n\t\t}\n\n\t\t// calculate the backwardCoord from the forwardCoord. consider the series\n\t\tseg.backwardCoord = seg.forwardCoord -\n\t\t\t(seg.forwardCoord - seriesBackwardCoord) / // available width for series\n\t\t\t(seriesBackwardPressure + 1); // # of segments in the series\n\n\t\t// use this segment's coordinates to computed the coordinates of the less-pressurized\n\t\t// forward segments\n\t\tfor (i=0; i<forwardSegs.length; i++) {\n\t\t\tcomputeSlotSegCoords(forwardSegs[i], 0, seg.forwardCoord);\n\t\t}\n\t}\n}\n\n\n// Find all the segments in `otherSegs` that vertically collide with `seg`.\n// Append into an optionally-supplied `results` array and return.\nfunction computeSlotSegCollisions(seg, otherSegs, results) {\n\tresults = results || [];\n\n\tfor (var i=0; i<otherSegs.length; i++) {\n\t\tif (isSlotSegCollision(seg, otherSegs[i])) {\n\t\t\tresults.push(otherSegs[i]);\n\t\t}\n\t}\n\n\treturn results;\n}\n\n\n// Do these segments occupy the same vertical space?\nfunction isSlotSegCollision(seg1, seg2) {\n\treturn seg1.bottom > seg2.top && seg1.top < seg2.bottom;\n}\n\n\n// A cmp function for determining which forward segment to rely on more when computing coordinates.\nfunction compareForwardSlotSegs(seg1, seg2) {\n\t// put higher-pressure first\n\treturn seg2.forwardPressure - seg1.forwardPressure ||\n\t\t// put segments that are closer to initial edge first (and favor ones with no coords yet)\n\t\t(seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) ||\n\t\t// do normal sorting...\n\t\tcompareSegs(seg1, seg2);\n}\n\n    /* An abstract class from which other views inherit from\n----------------------------------------------------------------------------------------------------------------------*/\n\nvar View = fc.View = Class.extend({\n\n\ttype: null, // subclass' view name (string)\n\tname: null, // deprecated. use `type` instead\n\n\tcalendar: null, // owner Calendar object\n\toptions: null, // view-specific options\n\tcoordMap: null, // a CoordMap object for converting pixel regions to dates\n\tel: null, // the view's containing element. set by Calendar\n\n\t// range the view is actually displaying (moments)\n\tstart: null,\n\tend: null, // exclusive\n\n\t// range the view is formally responsible for (moments)\n\t// may be different from start/end. for example, a month view might have 1st-31st, excluding padded dates\n\tintervalStart: null,\n\tintervalEnd: null, // exclusive\n\n\tintervalDuration: null, // the whole-unit duration that is being displayed\n\tintervalUnit: null, // name of largest unit being displayed, like \"month\" or \"week\"\n\n\tisSelected: false, // boolean whether a range of time is user-selected or not\n\n\t// subclasses can optionally use a scroll container\n\tscrollerEl: null, // the element that will most likely scroll when content is too tall\n\tscrollTop: null, // cached vertical scroll value\n\n\t// classNames styled by jqui themes\n\twidgetHeaderClass: null,\n\twidgetContentClass: null,\n\thighlightStateClass: null,\n\n\t// for date utils, computed from options\n\tnextDayThreshold: null,\n\tisHiddenDayHash: null,\n\n\t// document handlers, bound to `this` object\n\tdocumentMousedownProxy: null, // TODO: doesn't work with touch\n\n\n\tconstructor: function(calendar, viewOptions, viewType) {\n\t\tthis.calendar = calendar;\n\t\tthis.options = viewOptions;\n\t\tthis.type = this.name = viewType; // .name is deprecated\n\n\t\tthis.nextDayThreshold = moment.duration(this.opt('nextDayThreshold'));\n\t\tthis.initTheming();\n\t\tthis.initHiddenDays();\n\n\t\tthis.documentMousedownProxy = $.proxy(this, 'documentMousedown');\n\n\t\tthis.initialize();\n\t},\n\n\n\t// A good place for subclasses to initialize member variables\n\tinitialize: function() {\n\t\t// subclasses can implement\n\t},\n\n\n\t// Retrieves an option with the given name\n\topt: function(name) {\n\t\tvar val;\n\n\t\tval = this.options[name]; // look at view-specific options first\n\t\tif (val !== undefined) {\n\t\t\treturn val;\n\t\t}\n\n\t\tval = this.calendar.options[name];\n\t\tif ($.isPlainObject(val) && !isForcedAtomicOption(name)) { // view-option-hashes are deprecated\n\t\t\treturn smartProperty(val, this.type);\n\t\t}\n\n\t\treturn val;\n\t},\n\n\n\t// Triggers handlers that are view-related. Modifies args before passing to calendar.\n\ttrigger: function(name, thisObj) { // arguments beyond thisObj are passed along\n\t\tvar calendar = this.calendar;\n\n\t\treturn calendar.trigger.apply(\n\t\t\tcalendar,\n\t\t\t[name, thisObj || this].concat(\n\t\t\t\tArray.prototype.slice.call(arguments, 2), // arguments beyond thisObj\n\t\t\t\t[ this ] // always make the last argument a reference to the view. TODO: deprecate\n\t\t\t)\n\t\t);\n\t},\n\n\n\t/* Dates\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Updates all internal dates to center around the given current date\n\tsetDate: function(date) {\n\t\tthis.setRange(this.computeRange(date));\n\t},\n\n\n\t// Updates all internal dates for displaying the given range.\n\t// Expects all values to be normalized (like what computeRange does).\n\tsetRange: function(range) {\n\t\t$.extend(this, range);\n\t},\n\n\n\t// Given a single current date, produce information about what range to display.\n\t// Subclasses can override. Must return all properties.\n\tcomputeRange: function(date) {\n\t\tvar intervalDuration = moment.duration(this.opt('duration') || this.constructor.duration || { days: 1 });\n\t\tvar intervalUnit = computeIntervalUnit(intervalDuration);\n\t\tvar intervalStart = date.clone().startOf(intervalUnit);\n\t\tvar intervalEnd = intervalStart.clone().add(intervalDuration);\n\t\tvar start, end;\n\n\t\t// normalize the range's time-ambiguity\n\t\tif (computeIntervalAs('days', intervalDuration)) { // whole-days?\n\t\t\tintervalStart.stripTime();\n\t\t\tintervalEnd.stripTime();\n\t\t}\n\t\telse { // needs to have a time?\n\t\t\tif (!intervalStart.hasTime()) {\n\t\t\t\tintervalStart = this.calendar.rezoneDate(intervalStart); // convert to current timezone, with 00:00\n\t\t\t}\n\t\t\tif (!intervalEnd.hasTime()) {\n\t\t\t\tintervalEnd = this.calendar.rezoneDate(intervalEnd); // convert to current timezone, with 00:00\n\t\t\t}\n\t\t}\n\n\t\tstart = intervalStart.clone();\n\t\tstart = this.skipHiddenDays(start);\n\t\tend = intervalEnd.clone();\n\t\tend = this.skipHiddenDays(end, -1, true); // exclusively move backwards\n\n\t\treturn {\n\t\t\tintervalDuration: intervalDuration,\n\t\t\tintervalUnit: intervalUnit,\n\t\t\tintervalStart: intervalStart,\n\t\t\tintervalEnd: intervalEnd,\n\t\t\tstart: start,\n\t\t\tend: end\n\t\t};\n\t},\n\n\n\t// Computes the new date when the user hits the prev button, given the current date\n\tcomputePrevDate: function(date) {\n\t\treturn this.skipHiddenDays(\n\t\t\tdate.clone().startOf(this.intervalUnit).subtract(this.intervalDuration), -1\n\t\t);\n\t},\n\n\n\t// Computes the new date when the user hits the next button, given the current date\n\tcomputeNextDate: function(date) {\n\t\treturn this.skipHiddenDays(\n\t\t\tdate.clone().startOf(this.intervalUnit).add(this.intervalDuration)\n\t\t);\n\t},\n\n\n\t/* Title and Date Formatting\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Computes what the title at the top of the calendar should be for this view\n\tcomputeTitle: function() {\n\t\treturn this.formatRange(\n\t\t\t{ start: this.intervalStart, end: this.intervalEnd },\n\t\t\tthis.opt('titleFormat') || this.computeTitleFormat(),\n\t\t\tthis.opt('titleRangeSeparator')\n\t\t);\n\t},\n\n\n\t// Generates the format string that should be used to generate the title for the current date range.\n\t// Attempts to compute the most appropriate format if not explicitly specified with `titleFormat`.\n\tcomputeTitleFormat: function() {\n\t\tif (this.intervalUnit == 'year') {\n\t\t\treturn 'YYYY';\n\t\t}\n\t\telse if (this.intervalUnit == 'month') {\n\t\t\treturn this.opt('monthYearFormat'); // like \"September 2014\"\n\t\t}\n\t\telse if (this.intervalDuration.as('days') > 1) {\n\t\t\treturn 'll'; // multi-day range. shorter, like \"Sep 9 - 10 2014\"\n\t\t}\n\t\telse {\n\t\t\treturn 'LL'; // one day. longer, like \"September 9 2014\"\n\t\t}\n\t},\n\n\n\t// Utility for formatting a range. Accepts a range object, formatting string, and optional separator.\n\t// Displays all-day ranges naturally, with an inclusive end. Takes the current isRTL into account.\n\tformatRange: function(range, formatStr, separator) {\n\t\tvar end = range.end;\n\n\t\tif (!end.hasTime()) { // all-day?\n\t\t\tend = end.clone().subtract(1); // convert to inclusive. last ms of previous day\n\t\t}\n\n\t\treturn formatRange(range.start, end, formatStr, separator, this.opt('isRTL'));\n\t},\n\n\n\t/* Rendering\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Wraps the basic render() method with more View-specific logic. Called by the owner Calendar.\n\trenderView: function() {\n\t\tthis.render();\n\t\tthis.updateSize();\n\t\tthis.initializeScroll();\n\t\tthis.trigger('viewRender', this, this, this.el);\n\n\t\t// attach handlers to document. do it here to allow for destroy/rerender\n\t\t$(document).on('mousedown', this.documentMousedownProxy);\n\t},\n\n\n\t// Renders the view inside an already-defined `this.el`\n\trender: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Wraps the basic destroy() method with more View-specific logic. Called by the owner Calendar.\n\tdestroyView: function() {\n\t\tthis.unselect();\n\t\tthis.destroyViewEvents();\n\t\tthis.destroy();\n\t\tthis.trigger('viewDestroy', this, this, this.el);\n\n\t\t$(document).off('mousedown', this.documentMousedownProxy);\n\t},\n\n\n\t// Clears the view's rendering\n\tdestroy: function() {\n\t\tthis.el.empty(); // removes inner contents but leaves the element intact\n\t},\n\n\n\t// Initializes internal variables related to theming\n\tinitTheming: function() {\n\t\tvar tm = this.opt('theme') ? 'ui' : 'fc';\n\n\t\tthis.widgetHeaderClass = tm + '-widget-header';\n\t\tthis.widgetContentClass = tm + '-widget-content';\n\t\tthis.highlightStateClass = tm + '-state-highlight';\n\t},\n\n\n\t/* Dimensions\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Refreshes anything dependant upon sizing of the container element of the grid\n\tupdateSize: function(isResize) {\n\t\tif (isResize) {\n\t\t\tthis.recordScroll();\n\t\t}\n\t\tthis.updateHeight();\n\t\tthis.updateWidth();\n\t},\n\n\n\t// Refreshes the horizontal dimensions of the calendar\n\tupdateWidth: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Refreshes the vertical dimensions of the calendar\n\tupdateHeight: function() {\n\t\tvar calendar = this.calendar; // we poll the calendar for height information\n\n\t\tthis.setHeight(\n\t\t\tcalendar.getSuggestedViewHeight(),\n\t\t\tcalendar.isHeightAuto()\n\t\t);\n\t},\n\n\n\t// Updates the vertical dimensions of the calendar to the specified height.\n\t// if `isAuto` is set to true, height becomes merely a suggestion and the view should use its \"natural\" height.\n\tsetHeight: function(height, isAuto) {\n\t\t// subclasses should implement\n\t},\n\n\n\t/* Scroller\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Given the total height of the view, return the number of pixels that should be used for the scroller.\n\t// By default, uses this.scrollerEl, but can pass this in as well.\n\t// Utility for subclasses.\n\tcomputeScrollerHeight: function(totalHeight, scrollerEl) {\n\t\tvar both;\n\t\tvar otherHeight; // cumulative height of everything that is not the scrollerEl in the view (header+borders)\n\n\t\tscrollerEl = scrollerEl || this.scrollerEl;\n\t\tboth = this.el.add(scrollerEl);\n\n\t\t// fuckin IE8/9/10/11 sometimes returns 0 for dimensions. this weird hack was the only thing that worked\n\t\tboth.css({\n\t\t\tposition: 'relative', // cause a reflow, which will force fresh dimension recalculation\n\t\t\tleft: -1 // ensure reflow in case the el was already relative. negative is less likely to cause new scroll\n\t\t});\n\t\totherHeight = this.el.outerHeight() - scrollerEl.height(); // grab the dimensions\n\t\tboth.css({ position: '', left: '' }); // undo hack\n\n\t\treturn totalHeight - otherHeight;\n\t},\n\n\n\t// Sets the scroll value of the scroller to the initial pre-configured state prior to allowing the user to change it\n\tinitializeScroll: function() {\n\t},\n\n\n\t// Called for remembering the current scroll value of the scroller.\n\t// Should be called before there is a destructive operation (like removing DOM elements) that might inadvertently\n\t// change the scroll of the container.\n\trecordScroll: function() {\n\t\tif (this.scrollerEl) {\n\t\t\tthis.scrollTop = this.scrollerEl.scrollTop();\n\t\t}\n\t},\n\n\n\t// Set the scroll value of the scroller to the previously recorded value.\n\t// Should be called after we know the view's dimensions have been restored following some type of destructive\n\t// operation (like temporarily removing DOM elements).\n\trestoreScroll: function() {\n\t\tif (this.scrollTop !== null) {\n\t\t\tthis.scrollerEl.scrollTop(this.scrollTop);\n\t\t}\n\t},\n\n\n\t/* Event Elements / Segments\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Wraps the basic renderEvents() method with more View-specific logic\n\trenderViewEvents: function(events) {\n\t\tthis.renderEvents(events);\n\n\t\tthis.eventSegEach(function(seg) {\n\t\t\tthis.trigger('eventAfterRender', seg.event, seg.event, seg.el);\n\t\t});\n\t\tthis.trigger('eventAfterAllRender');\n\t},\n\n\n\t// Renders the events onto the view.\n\trenderEvents: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Wraps the basic destroyEvents() method with more View-specific logic\n\tdestroyViewEvents: function() {\n\t\tthis.eventSegEach(function(seg) {\n\t\t\tthis.trigger('eventDestroy', seg.event, seg.event, seg.el);\n\t\t});\n\n\t\tthis.destroyEvents();\n\t},\n\n\n\t// Removes event elements from the view.\n\tdestroyEvents: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Given an event and the default element used for rendering, returns the element that should actually be used.\n\t// Basically runs events and elements through the eventRender hook.\n\tresolveEventEl: function(event, el) {\n\t\tvar custom = this.trigger('eventRender', event, event, el);\n\n\t\tif (custom === false) { // means don't render at all\n\t\t\tel = null;\n\t\t}\n\t\telse if (custom && custom !== true) {\n\t\t\tel = $(custom);\n\t\t}\n\n\t\treturn el;\n\t},\n\n\n\t// Hides all rendered event segments linked to the given event\n\tshowEvent: function(event) {\n\t\tthis.eventSegEach(function(seg) {\n\t\t\tseg.el.css('visibility', '');\n\t\t}, event);\n\t},\n\n\n\t// Shows all rendered event segments linked to the given event\n\thideEvent: function(event) {\n\t\tthis.eventSegEach(function(seg) {\n\t\t\tseg.el.css('visibility', 'hidden');\n\t\t}, event);\n\t},\n\n\n\t// Iterates through event segments. Goes through all by default.\n\t// If the optional `event` argument is specified, only iterates through segments linked to that event.\n\t// The `this` value of the callback function will be the view.\n\teventSegEach: function(func, event) {\n\t\tvar segs = this.getEventSegs();\n\t\tvar i;\n\n\t\tfor (i = 0; i < segs.length; i++) {\n\t\t\tif (!event || segs[i].event._id === event._id) {\n\t\t\t\tfunc.call(this, segs[i]);\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Retrieves all the rendered segment objects for the view\n\tgetEventSegs: function() {\n\t\t// subclasses must implement\n\t\treturn [];\n\t},\n\n\n\t/* Event Drag-n-Drop\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Computes if the given event is allowed to be dragged by the user\n\tisEventDraggable: function(event) {\n\t\tvar source = event.source || {};\n\n\t\treturn firstDefined(\n\t\t\tevent.startEditable,\n\t\t\tsource.startEditable,\n\t\t\tthis.opt('eventStartEditable'),\n\t\t\tevent.editable,\n\t\t\tsource.editable,\n\t\t\tthis.opt('editable')\n\t\t);\n\t},\n\n\n\t// Must be called when an event in the view is dropped onto new location.\n\t// `dropLocation` is an object that contains the new start/end/allDay values for the event.\n\treportEventDrop: function(event, dropLocation, el, ev) {\n\t\tvar calendar = this.calendar;\n\t\tvar mutateResult = calendar.mutateEvent(event, dropLocation);\n\t\tvar undoFunc = function() {\n\t\t\tmutateResult.undo();\n\t\t\tcalendar.reportEventChange();\n\t\t};\n\n\t\tthis.triggerEventDrop(event, mutateResult.dateDelta, undoFunc, el, ev);\n\t\tcalendar.reportEventChange(); // will rerender events\n\t},\n\n\n\t// Triggers event-drop handlers that have subscribed via the API\n\ttriggerEventDrop: function(event, dateDelta, undoFunc, el, ev) {\n\t\tthis.trigger('eventDrop', el[0], event, dateDelta, undoFunc, ev, {}); // {} = jqui dummy\n\t},\n\n\n\t/* External Element Drag-n-Drop\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Must be called when an external element, via jQuery UI, has been dropped onto the calendar.\n\t// `meta` is the parsed data that has been embedded into the dragging event.\n\t// `dropLocation` is an object that contains the new start/end/allDay values for the event.\n\treportExternalDrop: function(meta, dropLocation, el, ev, ui) {\n\t\tvar eventProps = meta.eventProps;\n\t\tvar eventInput;\n\t\tvar event;\n\n\t\t// Try to build an event object and render it. TODO: decouple the two\n\t\tif (eventProps) {\n\t\t\teventInput = $.extend({}, eventProps, dropLocation);\n\t\t\tevent = this.calendar.renderEvent(eventInput, meta.stick)[0]; // renderEvent returns an array\n\t\t}\n\n\t\tthis.triggerExternalDrop(event, dropLocation, el, ev, ui);\n\t},\n\n\n\t// Triggers external-drop handlers that have subscribed via the API\n\ttriggerExternalDrop: function(event, dropLocation, el, ev, ui) {\n\n\t\t// trigger 'drop' regardless of whether element represents an event\n\t\tthis.trigger('drop', el[0], dropLocation.start, ev, ui);\n\n\t\tif (event) {\n\t\t\tthis.trigger('eventReceive', null, event); // signal an external event landed\n\t\t}\n\t},\n\n\n\t/* Drag-n-Drop Rendering (for both events and external elements)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of a event or external-element drag over the given drop zone.\n\t// If an external-element, seg will be `null`\n\trenderDrag: function(dropLocation, seg) {\n\t\t// subclasses must implement\n\t},\n\n\n\t// Unrenders a visual indication of an event or external-element being dragged.\n\tdestroyDrag: function() {\n\t\t// subclasses must implement\n\t},\n\n\n\t/* Event Resizing\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Computes if the given event is allowed to be resize by the user\n\tisEventResizable: function(event) {\n\t\tvar source = event.source || {};\n\n\t\treturn firstDefined(\n\t\t\tevent.durationEditable,\n\t\t\tsource.durationEditable,\n\t\t\tthis.opt('eventDurationEditable'),\n\t\t\tevent.editable,\n\t\t\tsource.editable,\n\t\t\tthis.opt('editable')\n\t\t);\n\t},\n\n\n\t// Must be called when an event in the view has been resized to a new length\n\treportEventResize: function(event, newEnd, el, ev) {\n\t\tvar calendar = this.calendar;\n\t\tvar mutateResult = calendar.mutateEvent(event, { end: newEnd });\n\t\tvar undoFunc = function() {\n\t\t\tmutateResult.undo();\n\t\t\tcalendar.reportEventChange();\n\t\t};\n\n\t\tthis.triggerEventResize(event, mutateResult.durationDelta, undoFunc, el, ev);\n\t\tcalendar.reportEventChange(); // will rerender events\n\t},\n\n\n\t// Triggers event-resize handlers that have subscribed via the API\n\ttriggerEventResize: function(event, durationDelta, undoFunc, el, ev) {\n\t\tthis.trigger('eventResize', el[0], event, durationDelta, undoFunc, ev, {}); // {} = jqui dummy\n\t},\n\n\n\t/* Selection\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Selects a date range on the view. `start` and `end` are both Moments.\n\t// `ev` is the native mouse event that begin the interaction.\n\tselect: function(range, ev) {\n\t\tthis.unselect(ev);\n\t\tthis.renderSelection(range);\n\t\tthis.reportSelection(range, ev);\n\t},\n\n\n\t// Renders a visual indication of the selection\n\trenderSelection: function(range) {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Called when a new selection is made. Updates internal state and triggers handlers.\n\treportSelection: function(range, ev) {\n\t\tthis.isSelected = true;\n\t\tthis.trigger('select', null, range.start, range.end, ev);\n\t},\n\n\n\t// Undoes a selection. updates in the internal state and triggers handlers.\n\t// `ev` is the native mouse event that began the interaction.\n\tunselect: function(ev) {\n\t\tif (this.isSelected) {\n\t\t\tthis.isSelected = false;\n\t\t\tthis.destroySelection();\n\t\t\tthis.trigger('unselect', null, ev);\n\t\t}\n\t},\n\n\n\t// Unrenders a visual indication of selection\n\tdestroySelection: function() {\n\t\t// subclasses should implement\n\t},\n\n\n\t// Handler for unselecting when the user clicks something and the 'unselectAuto' setting is on\n\tdocumentMousedown: function(ev) {\n\t\tvar ignore;\n\n\t\t// is there a selection, and has the user made a proper left click?\n\t\tif (this.isSelected && this.opt('unselectAuto') && isPrimaryMouseButton(ev)) {\n\n\t\t\t// only unselect if the clicked element is not identical to or inside of an 'unselectCancel' element\n\t\t\tignore = this.opt('unselectCancel');\n\t\t\tif (!ignore || !$(ev.target).closest(ignore).length) {\n\t\t\t\tthis.unselect(ev);\n\t\t\t}\n\t\t}\n\t},\n\n\n\t/* Date Utils\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Initializes internal variables related to calculating hidden days-of-week\n\tinitHiddenDays: function() {\n\t\tvar hiddenDays = this.opt('hiddenDays') || []; // array of day-of-week indices that are hidden\n\t\tvar isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)\n\t\tvar dayCnt = 0;\n\t\tvar i;\n\n\t\tif (this.opt('weekends') === false) {\n\t\t\thiddenDays.push(0, 6); // 0=sunday, 6=saturday\n\t\t}\n\n\t\tfor (i = 0; i < 7; i++) {\n\t\t\tif (\n\t\t\t\t!(isHiddenDayHash[i] = $.inArray(i, hiddenDays) !== -1)\n\t\t\t) {\n\t\t\t\tdayCnt++;\n\t\t\t}\n\t\t}\n\n\t\tif (!dayCnt) {\n\t\t\tthrow 'invalid hiddenDays'; // all days were hidden? bad.\n\t\t}\n\n\t\tthis.isHiddenDayHash = isHiddenDayHash;\n\t},\n\n\n\t// Is the current day hidden?\n\t// `day` is a day-of-week index (0-6), or a Moment\n\tisHiddenDay: function(day) {\n\t\tif (moment.isMoment(day)) {\n\t\t\tday = day.day();\n\t\t}\n\t\treturn this.isHiddenDayHash[day];\n\t},\n\n\n\t// Incrementing the current day until it is no longer a hidden day, returning a copy.\n\t// If the initial value of `date` is not a hidden day, don't do anything.\n\t// Pass `isExclusive` as `true` if you are dealing with an end date.\n\t// `inc` defaults to `1` (increment one day forward each time)\n\tskipHiddenDays: function(date, inc, isExclusive) {\n\t\tvar out = date.clone();\n\t\tinc = inc || 1;\n\t\twhile (\n\t\t\tthis.isHiddenDayHash[(out.day() + (isExclusive ? inc : 0) + 7) % 7]\n\t\t) {\n\t\t\tout.add(inc, 'days');\n\t\t}\n\t\treturn out;\n\t},\n\n\n\t// Returns the date range of the full days the given range visually appears to occupy.\n\t// Returns a new range object.\n\tcomputeDayRange: function(range) {\n\t\tvar startDay = range.start.clone().stripTime(); // the beginning of the day the range starts\n\t\tvar end = range.end;\n\t\tvar endDay = null;\n\t\tvar endTimeMS;\n\n\t\tif (end) {\n\t\t\tendDay = end.clone().stripTime(); // the beginning of the day the range exclusively ends\n\t\t\tendTimeMS = +end.time(); // # of milliseconds into `endDay`\n\n\t\t\t// If the end time is actually inclusively part of the next day and is equal to or\n\t\t\t// beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.\n\t\t\t// Otherwise, leaving it as inclusive will cause it to exclude `endDay`.\n\t\t\tif (endTimeMS && endTimeMS >= this.nextDayThreshold) {\n\t\t\t\tendDay.add(1, 'days');\n\t\t\t}\n\t\t}\n\n\t\t// If no end was specified, or if it is within `startDay` but not past nextDayThreshold,\n\t\t// assign the default duration of one day.\n\t\tif (!end || endDay <= startDay) {\n\t\t\tendDay = startDay.clone().add(1, 'days');\n\t\t}\n\n\t\treturn { start: startDay, end: endDay };\n\t},\n\n\n\t// Does the given event visually appear to occupy more than one day?\n\tisMultiDayEvent: function(event) {\n\t\tvar range = this.computeDayRange(event); // event is range-ish\n\n\t\treturn range.end.diff(range.start, 'days') > 1;\n\t}\n\n});\n\n    function Calendar(element, instanceOptions) {\n\tvar t = this;\n\n\n\n\t// Build options object\n\t// -----------------------------------------------------------------------------------\n\t// Precedence (lowest to highest): defaults, rtlDefaults, langOptions, instanceOptions\n\n\tinstanceOptions = instanceOptions || {};\n\n\tvar options = mergeOptions({}, defaults, instanceOptions);\n\tvar langOptions;\n\n\t// determine language options\n\tif (options.lang in langOptionHash) {\n\t\tlangOptions = langOptionHash[options.lang];\n\t}\n\telse {\n\t\tlangOptions = langOptionHash[defaults.lang];\n\t}\n\n\tif (langOptions) { // if language options exist, rebuild...\n\t\toptions = mergeOptions({}, defaults, langOptions, instanceOptions);\n\t}\n\n\tif (options.isRTL) { // is isRTL, rebuild...\n\t\toptions = mergeOptions({}, defaults, rtlDefaults, langOptions || {}, instanceOptions);\n\t}\n\n\n\t\n\t// Exports\n\t// -----------------------------------------------------------------------------------\n\n\tt.options = options;\n\tt.render = render;\n\tt.destroy = destroy;\n\tt.refetchEvents = refetchEvents;\n\tt.reportEvents = reportEvents;\n\tt.reportEventChange = reportEventChange;\n\tt.rerenderEvents = renderEvents; // `renderEvents` serves as a rerender. an API method\n\tt.changeView = changeView;\n\tt.select = select;\n\tt.unselect = unselect;\n\tt.prev = prev;\n\tt.next = next;\n\tt.prevYear = prevYear;\n\tt.nextYear = nextYear;\n\tt.today = today;\n\tt.gotoDate = gotoDate;\n\tt.incrementDate = incrementDate;\n\tt.zoomTo = zoomTo;\n\tt.getDate = getDate;\n\tt.getCalendar = getCalendar;\n\tt.getView = getView;\n\tt.option = option;\n\tt.trigger = trigger;\n\tt.isValidViewType = isValidViewType;\n\tt.getViewButtonText = getViewButtonText;\n\n\n\n\t// Language-data Internals\n\t// -----------------------------------------------------------------------------------\n\t// Apply overrides to the current language's data\n\n\n\tvar localeData = createObject( // make a cheap copy\n\t\tgetMomentLocaleData(options.lang) // will fall back to en\n\t);\n\n\tif (options.monthNames) {\n\t\tlocaleData._months = options.monthNames;\n\t}\n\tif (options.monthNamesShort) {\n\t\tlocaleData._monthsShort = options.monthNamesShort;\n\t}\n\tif (options.dayNames) {\n\t\tlocaleData._weekdays = options.dayNames;\n\t}\n\tif (options.dayNamesShort) {\n\t\tlocaleData._weekdaysShort = options.dayNamesShort;\n\t}\n\tif (options.firstDay != null) {\n\t\tvar _week = createObject(localeData._week); // _week: { dow: # }\n\t\t_week.dow = options.firstDay;\n\t\tlocaleData._week = _week;\n\t}\n\n\n\n\t// Calendar-specific Date Utilities\n\t// -----------------------------------------------------------------------------------\n\n\n\tt.defaultAllDayEventDuration = moment.duration(options.defaultAllDayEventDuration);\n\tt.defaultTimedEventDuration = moment.duration(options.defaultTimedEventDuration);\n\n\n\t// Builds a moment using the settings of the current calendar: timezone and language.\n\t// Accepts anything the vanilla moment() constructor accepts.\n\tt.moment = function() {\n\t\tvar mom;\n\n\t\tif (options.timezone === 'local') {\n\t\t\tmom = fc.moment.apply(null, arguments);\n\n\t\t\t// Force the moment to be local, because fc.moment doesn't guarantee it.\n\t\t\tif (mom.hasTime()) { // don't give ambiguously-timed moments a local zone\n\t\t\t\tmom.local();\n\t\t\t}\n\t\t}\n\t\telse if (options.timezone === 'UTC') {\n\t\t\tmom = fc.moment.utc.apply(null, arguments); // process as UTC\n\t\t}\n\t\telse {\n\t\t\tmom = fc.moment.parseZone.apply(null, arguments); // let the input decide the zone\n\t\t}\n\n\t\tif ('_locale' in mom) { // moment 2.8 and above\n\t\t\tmom._locale = localeData;\n\t\t}\n\t\telse { // pre-moment-2.8\n\t\t\tmom._lang = localeData;\n\t\t}\n\n\t\treturn mom;\n\t};\n\n\n\t// Returns a boolean about whether or not the calendar knows how to calculate\n\t// the timezone offset of arbitrary dates in the current timezone.\n\tt.getIsAmbigTimezone = function() {\n\t\treturn options.timezone !== 'local' && options.timezone !== 'UTC';\n\t};\n\n\n\t// Returns a copy of the given date in the current timezone of it is ambiguously zoned.\n\t// This will also give the date an unambiguous time.\n\tt.rezoneDate = function(date) {\n\t\treturn t.moment(date.toArray());\n\t};\n\n\n\t// Returns a moment for the current date, as defined by the client's computer,\n\t// or overridden by the `now` option.\n\tt.getNow = function() {\n\t\tvar now = options.now;\n\t\tif (typeof now === 'function') {\n\t\t\tnow = now();\n\t\t}\n\t\treturn t.moment(now);\n\t};\n\n\n\t// Calculates the week number for a moment according to the calendar's\n\t// `weekNumberCalculation` setting.\n\tt.calculateWeekNumber = function(mom) {\n\t\tvar calc = options.weekNumberCalculation;\n\n\t\tif (typeof calc === 'function') {\n\t\t\treturn calc(mom);\n\t\t}\n\t\telse if (calc === 'local') {\n\t\t\treturn mom.week();\n\t\t}\n\t\telse if (calc.toUpperCase() === 'ISO') {\n\t\t\treturn mom.isoWeek();\n\t\t}\n\t};\n\n\n\t// Get an event's normalized end date. If not present, calculate it from the defaults.\n\tt.getEventEnd = function(event) {\n\t\tif (event.end) {\n\t\t\treturn event.end.clone();\n\t\t}\n\t\telse {\n\t\t\treturn t.getDefaultEventEnd(event.allDay, event.start);\n\t\t}\n\t};\n\n\n\t// Given an event's allDay status and start date, return swhat its fallback end date should be.\n\tt.getDefaultEventEnd = function(allDay, start) { // TODO: rename to computeDefaultEventEnd\n\t\tvar end = start.clone();\n\n\t\tif (allDay) {\n\t\t\tend.stripTime().add(t.defaultAllDayEventDuration);\n\t\t}\n\t\telse {\n\t\t\tend.add(t.defaultTimedEventDuration);\n\t\t}\n\n\t\tif (t.getIsAmbigTimezone()) {\n\t\t\tend.stripZone(); // we don't know what the tzo should be\n\t\t}\n\n\t\treturn end;\n\t};\n\n\n\t// Produces a human-readable string for the given duration.\n\t// Side-effect: changes the locale of the given duration.\n\tfunction humanizeDuration(duration) {\n\t\treturn (duration.locale || duration.lang).call(duration, options.lang) // works moment-pre-2.8\n\t\t\t.humanize();\n\t}\n\n\n\t\n\t// Imports\n\t// -----------------------------------------------------------------------------------\n\n\n\tEventManager.call(t, options);\n\tvar isFetchNeeded = t.isFetchNeeded;\n\tvar fetchEvents = t.fetchEvents;\n\n\n\n\t// Locals\n\t// -----------------------------------------------------------------------------------\n\n\n\tvar _element = element[0];\n\tvar header;\n\tvar headerElement;\n\tvar content;\n\tvar tm; // for making theme classes\n\tvar viewSpecCache = {};\n\tvar currentView;\n\tvar suggestedViewHeight;\n\tvar windowResizeProxy; // wraps the windowResize function\n\tvar ignoreWindowResize = 0;\n\tvar date;\n\tvar events = [];\n\t\n\t\n\t\n\t// Main Rendering\n\t// -----------------------------------------------------------------------------------\n\n\n\tif (options.defaultDate != null) {\n\t\tdate = t.moment(options.defaultDate);\n\t}\n\telse {\n\t\tdate = t.getNow();\n\t}\n\t\n\t\n\tfunction render(inc) {\n\t\tif (!content) {\n\t\t\tinitialRender();\n\t\t}\n\t\telse if (elementVisible()) {\n\t\t\t// mainly for the public API\n\t\t\tcalcSize();\n\t\t\trenderView(inc);\n\t\t}\n\t}\n\t\n\t\n\tfunction initialRender() {\n\t\ttm = options.theme ? 'ui' : 'fc';\n\t\telement.addClass('fc');\n\n\t\tif (options.isRTL) {\n\t\t\telement.addClass('fc-rtl');\n\t\t}\n\t\telse {\n\t\t\telement.addClass('fc-ltr');\n\t\t}\n\n\t\tif (options.theme) {\n\t\t\telement.addClass('ui-widget');\n\t\t}\n\t\telse {\n\t\t\telement.addClass('fc-unthemed');\n\t\t}\n\n\t\tcontent = $(\"<div class='fc-view-container'/>\").prependTo(element);\n\n\t\theader = new Header(t, options);\n\t\theaderElement = header.render();\n\t\tif (headerElement) {\n\t\t\telement.prepend(headerElement);\n\t\t}\n\n\t\tchangeView(options.defaultView);\n\n\t\tif (options.handleWindowResize) {\n\t\t\twindowResizeProxy = debounce(windowResize, options.windowResizeDelay); // prevents rapid calls\n\t\t\t$(window).resize(windowResizeProxy);\n\t\t}\n\t}\n\t\n\t\n\tfunction destroy() {\n\n\t\tif (currentView) {\n\t\t\tcurrentView.destroyView();\n\t\t}\n\n\t\theader.destroy();\n\t\tcontent.remove();\n\t\telement.removeClass('fc fc-ltr fc-rtl fc-unthemed ui-widget');\n\n\t\t$(window).unbind('resize', windowResizeProxy);\n\t}\n\t\n\t\n\tfunction elementVisible() {\n\t\treturn element.is(':visible');\n\t}\n\t\n\t\n\n\t// View Rendering\n\t// -----------------------------------------------------------------------------------\n\n\n\tfunction changeView(viewType) {\n\t\trenderView(0, viewType);\n\t}\n\n\n\t// Renders a view because of a date change, view-type change, or for the first time\n\tfunction renderView(delta, viewType) {\n\t\tignoreWindowResize++;\n\n\t\t// if viewType is changing, destroy the old view\n\t\tif (currentView && viewType && currentView.type !== viewType) {\n\t\t\theader.deactivateButton(currentView.type);\n\t\t\tfreezeContentHeight(); // prevent a scroll jump when view element is removed\n\t\t\tif (currentView.start) { // rendered before?\n\t\t\t\tcurrentView.destroyView();\n\t\t\t}\n\t\t\tcurrentView.el.remove();\n\t\t\tcurrentView = null;\n\t\t}\n\n\t\t// if viewType changed, or the view was never created, create a fresh view\n\t\tif (!currentView && viewType) {\n\t\t\tcurrentView = instantiateView(viewType);\n\t\t\tcurrentView.el =  $(\"<div class='fc-view fc-\" + viewType + \"-view' />\").appendTo(content);\n\t\t\theader.activateButton(viewType);\n\t\t}\n\n\t\tif (currentView) {\n\n\t\t\t// let the view determine what the delta means\n\t\t\tif (delta < 0) {\n\t\t\t\tdate = currentView.computePrevDate(date);\n\t\t\t}\n\t\t\telse if (delta > 0) {\n\t\t\t\tdate = currentView.computeNextDate(date);\n\t\t\t}\n\n\t\t\t// render or rerender the view\n\t\t\tif (\n\t\t\t\t!currentView.start || // never rendered before\n\t\t\t\tdelta || // explicit date window change\n\t\t\t\t!date.isWithin(currentView.intervalStart, currentView.intervalEnd) // implicit date window change\n\t\t\t) {\n\t\t\t\tif (elementVisible()) {\n\n\t\t\t\t\tfreezeContentHeight();\n\t\t\t\t\tif (currentView.start) { // rendered before?\n\t\t\t\t\t\tcurrentView.destroyView();\n\t\t\t\t\t}\n\t\t\t\t\tcurrentView.setDate(date);\n\t\t\t\t\tcurrentView.renderView();\n\t\t\t\t\tunfreezeContentHeight();\n\n\t\t\t\t\t// need to do this after View::render, so dates are calculated\n\t\t\t\t\tupdateTitle();\n\t\t\t\t\tupdateTodayButton();\n\n\t\t\t\t\tgetAndRenderEvents();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tunfreezeContentHeight(); // undo any lone freezeContentHeight calls\n\t\tignoreWindowResize--;\n\t}\n\n\n\n\t// View Instantiation\n\t// -----------------------------------------------------------------------------------\n\n\n\t// Given a view name for a custom view or a standard view, creates a ready-to-go View object\n\tfunction instantiateView(viewType) {\n\t\tvar spec = getViewSpec(viewType);\n\n\t\treturn new spec['class'](t, spec.options, viewType);\n\t}\n\n\n\t// Gets information about how to create a view\n\tfunction getViewSpec(requestedViewType) {\n\t\tvar allDefaultButtonText = options.defaultButtonText || {};\n\t\tvar allButtonText = options.buttonText || {};\n\t\tvar hash = options.views || {}; // the `views` option object\n\t\tvar viewType = requestedViewType;\n\t\tvar viewOptionsChain = [];\n\t\tvar viewOptions;\n\t\tvar viewClass;\n\t\tvar duration, unit, unitIsSingle = false;\n\t\tvar buttonText;\n\n\t\tif (viewSpecCache[requestedViewType]) {\n\t\t\treturn viewSpecCache[requestedViewType];\n\t\t}\n\n\t\tfunction processSpecInput(input) {\n\t\t\tif (typeof input === 'function') {\n\t\t\t\tviewClass = input;\n\t\t\t}\n\t\t\telse if (typeof input === 'object') {\n\t\t\t\t$.extend(viewOptions, input);\n\t\t\t}\n\t\t}\n\n\t\t// iterate up a view's spec ancestor chain util we find a class to instantiate\n\t\twhile (viewType && !viewClass) {\n\t\t\tviewOptions = {}; // only for this specific view in the ancestry\n\t\t\tprocessSpecInput(fcViews[viewType]); // $.fullCalendar.views, lower precedence\n\t\t\tprocessSpecInput(hash[viewType]); // options at initialization, higher precedence\n\t\t\tviewOptionsChain.unshift(viewOptions); // record older ancestors first\n\t\t\tviewType = viewOptions.type;\n\t\t}\n\n\t\tviewOptionsChain.unshift({}); // jQuery's extend needs at least one arg\n\t\tviewOptions = $.extend.apply($, viewOptionsChain); // combine all, newer ancestors overwritting old\n\n\t\tif (viewClass) {\n\n\t\t\tduration = viewOptions.duration || viewClass.duration;\n\t\t\tif (duration) {\n\t\t\t\tduration = moment.duration(duration);\n\t\t\t\tunit = computeIntervalUnit(duration);\n\t\t\t\tunitIsSingle = computeIntervalAs(unit, duration) === 1;\n\t\t\t}\n\n\t\t\t// options that are specified per the view's duration, like \"week\" or \"day\"\n\t\t\tif (unitIsSingle && hash[unit]) {\n\t\t\t\tviewOptions = $.extend({}, hash[unit], viewOptions); // lowest priority\n\t\t\t}\n\n\t\t\t// compute the final text for the button representing this view\n\t\t\tbuttonText =\n\t\t\t\tallButtonText[requestedViewType] || // init options, like \"agendaWeek\"\n\t\t\t\t(unitIsSingle ? allButtonText[unit] : null) || // init options, like \"week\"\n\t\t\t\tallDefaultButtonText[requestedViewType] || // lang data, like \"agendaWeek\"\n\t\t\t\t(unitIsSingle ? allDefaultButtonText[unit] : null) || // lang data, like \"week\"\n\t\t\t\tviewOptions.buttonText ||\n\t\t\t\tviewClass.buttonText ||\n\t\t\t\t(duration ? humanizeDuration(duration) : null) ||\n\t\t\t\trequestedViewType;\n\n\t\t\treturn (viewSpecCache[requestedViewType] = {\n\t\t\t\t'class': viewClass,\n\t\t\t\toptions: viewOptions,\n\t\t\t\tbuttonText: buttonText\n\t\t\t});\n\t\t}\n\t}\n\n\n\t// Returns a boolean about whether the view is okay to instantiate at some point\n\tfunction isValidViewType(viewType) {\n\t\treturn Boolean(getViewSpec(viewType));\n\t}\n\n\n\t// Gets the text that should be displayed on a view's button in the header\n\tfunction getViewButtonText(viewType) {\n\t\tvar spec = getViewSpec(viewType);\n\n\t\tif (spec) {\n\t\t\treturn spec.buttonText;\n\t\t}\n\t}\n\t\n\t\n\n\t// Resizing\n\t// -----------------------------------------------------------------------------------\n\n\n\tt.getSuggestedViewHeight = function() {\n\t\tif (suggestedViewHeight === undefined) {\n\t\t\tcalcSize();\n\t\t}\n\t\treturn suggestedViewHeight;\n\t};\n\n\n\tt.isHeightAuto = function() {\n\t\treturn options.contentHeight === 'auto' || options.height === 'auto';\n\t};\n\t\n\t\n\tfunction updateSize(shouldRecalc) {\n\t\tif (elementVisible()) {\n\n\t\t\tif (shouldRecalc) {\n\t\t\t\t_calcSize();\n\t\t\t}\n\n\t\t\tignoreWindowResize++;\n\t\t\tcurrentView.updateSize(true); // isResize=true. will poll getSuggestedViewHeight() and isHeightAuto()\n\t\t\tignoreWindowResize--;\n\n\t\t\treturn true; // signal success\n\t\t}\n\t}\n\n\n\tfunction calcSize() {\n\t\tif (elementVisible()) {\n\t\t\t_calcSize();\n\t\t}\n\t}\n\t\n\t\n\tfunction _calcSize() { // assumes elementVisible\n\t\tif (typeof options.contentHeight === 'number') { // exists and not 'auto'\n\t\t\tsuggestedViewHeight = options.contentHeight;\n\t\t}\n\t\telse if (typeof options.height === 'number') { // exists and not 'auto'\n\t\t\tsuggestedViewHeight = options.height - (headerElement ? headerElement.outerHeight(true) : 0);\n\t\t}\n\t\telse {\n\t\t\tsuggestedViewHeight = Math.round(content.width() / Math.max(options.aspectRatio, .5));\n\t\t}\n\t}\n\t\n\t\n\tfunction windowResize(ev) {\n\t\tif (\n\t\t\t!ignoreWindowResize &&\n\t\t\tev.target === window && // so we don't process jqui \"resize\" events that have bubbled up\n\t\t\tcurrentView.start // view has already been rendered\n\t\t) {\n\t\t\tif (updateSize(true)) {\n\t\t\t\tcurrentView.trigger('windowResize', _element);\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t\n\t/* Event Fetching/Rendering\n\t-----------------------------------------------------------------------------*/\n\t// TODO: going forward, most of this stuff should be directly handled by the view\n\n\n\tfunction refetchEvents() { // can be called as an API method\n\t\tdestroyEvents(); // so that events are cleared before user starts waiting for AJAX\n\t\tfetchAndRenderEvents();\n\t}\n\n\n\tfunction renderEvents() { // destroys old events if previously rendered\n\t\tif (elementVisible()) {\n\t\t\tfreezeContentHeight();\n\t\t\tcurrentView.destroyViewEvents(); // no performance cost if never rendered\n\t\t\tcurrentView.renderViewEvents(events);\n\t\t\tunfreezeContentHeight();\n\t\t}\n\t}\n\n\n\tfunction destroyEvents() {\n\t\tfreezeContentHeight();\n\t\tcurrentView.destroyViewEvents();\n\t\tunfreezeContentHeight();\n\t}\n\t\n\n\tfunction getAndRenderEvents() {\n\t\tif (!options.lazyFetching || isFetchNeeded(currentView.start, currentView.end)) {\n\t\t\tfetchAndRenderEvents();\n\t\t}\n\t\telse {\n\t\t\trenderEvents();\n\t\t}\n\t}\n\n\n\tfunction fetchAndRenderEvents() {\n\t\tfetchEvents(currentView.start, currentView.end);\n\t\t\t// ... will call reportEvents\n\t\t\t// ... which will call renderEvents\n\t}\n\n\t\n\t// called when event data arrives\n\tfunction reportEvents(_events) {\n\t\tevents = _events;\n\t\trenderEvents();\n\t}\n\n\n\t// called when a single event's data has been changed\n\tfunction reportEventChange() {\n\t\trenderEvents();\n\t}\n\n\n\n\t/* Header Updating\n\t-----------------------------------------------------------------------------*/\n\n\n\tfunction updateTitle() {\n\t\theader.updateTitle(currentView.computeTitle());\n\t}\n\n\n\tfunction updateTodayButton() {\n\t\tvar now = t.getNow();\n\t\tif (now.isWithin(currentView.intervalStart, currentView.intervalEnd)) {\n\t\t\theader.disableButton('today');\n\t\t}\n\t\telse {\n\t\t\theader.enableButton('today');\n\t\t}\n\t}\n\t\n\n\n\t/* Selection\n\t-----------------------------------------------------------------------------*/\n\t\n\n\tfunction select(start, end) {\n\n\t\tstart = t.moment(start);\n\t\tif (end) {\n\t\t\tend = t.moment(end);\n\t\t}\n\t\telse if (start.hasTime()) {\n\t\t\tend = start.clone().add(t.defaultTimedEventDuration);\n\t\t}\n\t\telse {\n\t\t\tend = start.clone().add(t.defaultAllDayEventDuration);\n\t\t}\n\n\t\tcurrentView.select({ start: start, end: end }); // accepts a range\n\t}\n\t\n\n\tfunction unselect() { // safe to be called before renderView\n\t\tif (currentView) {\n\t\t\tcurrentView.unselect();\n\t\t}\n\t}\n\t\n\t\n\t\n\t/* Date\n\t-----------------------------------------------------------------------------*/\n\t\n\t\n\tfunction prev() {\n\t\trenderView(-1);\n\t}\n\t\n\t\n\tfunction next() {\n\t\trenderView(1);\n\t}\n\t\n\t\n\tfunction prevYear() {\n\t\tdate.add(-1, 'years');\n\t\trenderView();\n\t}\n\t\n\t\n\tfunction nextYear() {\n\t\tdate.add(1, 'years');\n\t\trenderView();\n\t}\n\t\n\t\n\tfunction today() {\n\t\tdate = t.getNow();\n\t\trenderView();\n\t}\n\t\n\t\n\tfunction gotoDate(dateInput) {\n\t\tdate = t.moment(dateInput);\n\t\trenderView();\n\t}\n\t\n\t\n\tfunction incrementDate(delta) {\n\t\tdate.add(moment.duration(delta));\n\t\trenderView();\n\t}\n\n\n\t// Forces navigation to a view for the given date.\n\t// `viewType` can be a specific view name or a generic one like \"week\" or \"day\".\n\tfunction zoomTo(newDate, viewType) {\n\t\tvar viewStr;\n\t\tvar match;\n\n\t\tif (!viewType || !isValidViewType(viewType)) { // a general view name, or \"auto\"\n\t\t\tviewType = viewType || 'day';\n\t\t\tviewStr = header.getViewsWithButtons().join(' '); // space-separated string of all the views in the header\n\n\t\t\t// try to match a general view name, like \"week\", against a specific one, like \"agendaWeek\"\n\t\t\tmatch = viewStr.match(new RegExp('\\\\w+' + capitaliseFirstLetter(viewType)));\n\n\t\t\t// fall back to the day view being used in the header\n\t\t\tif (!match) {\n\t\t\t\tmatch = viewStr.match(/\\w+Day/);\n\t\t\t}\n\n\t\t\tviewType = match ? match[0] : 'agendaDay'; // fall back to agendaDay\n\t\t}\n\n\t\tdate = newDate;\n\t\tchangeView(viewType);\n\t}\n\t\n\t\n\tfunction getDate() {\n\t\treturn date.clone();\n\t}\n\n\n\n\t/* Height \"Freezing\"\n\t-----------------------------------------------------------------------------*/\n\n\n\tfunction freezeContentHeight() {\n\t\tcontent.css({\n\t\t\twidth: '100%',\n\t\t\theight: content.height(),\n\t\t\toverflow: 'hidden'\n\t\t});\n\t}\n\n\n\tfunction unfreezeContentHeight() {\n\t\tcontent.css({\n\t\t\twidth: '',\n\t\t\theight: '',\n\t\t\toverflow: ''\n\t\t});\n\t}\n\t\n\t\n\t\n\t/* Misc\n\t-----------------------------------------------------------------------------*/\n\t\n\n\tfunction getCalendar() {\n\t\treturn t;\n\t}\n\n\t\n\tfunction getView() {\n\t\treturn currentView;\n\t}\n\t\n\t\n\tfunction option(name, value) {\n\t\tif (value === undefined) {\n\t\t\treturn options[name];\n\t\t}\n\t\tif (name == 'height' || name == 'contentHeight' || name == 'aspectRatio') {\n\t\t\toptions[name] = value;\n\t\t\tupdateSize(true); // true = allow recalculation of height\n\t\t}\n\t}\n\t\n\t\n\tfunction trigger(name, thisObj) {\n\t\tif (options[name]) {\n\t\t\treturn options[name].apply(\n\t\t\t\tthisObj || _element,\n\t\t\t\tArray.prototype.slice.call(arguments, 2)\n\t\t\t);\n\t\t}\n\t}\n\n}\n\n    /* Top toolbar area with buttons and title\n----------------------------------------------------------------------------------------------------------------------*/\n// TODO: rename all header-related things to \"toolbar\"\n\nfunction Header(calendar, options) {\n\tvar t = this;\n\t\n\t// exports\n\tt.render = render;\n\tt.destroy = destroy;\n\tt.updateTitle = updateTitle;\n\tt.activateButton = activateButton;\n\tt.deactivateButton = deactivateButton;\n\tt.disableButton = disableButton;\n\tt.enableButton = enableButton;\n\tt.getViewsWithButtons = getViewsWithButtons;\n\t\n\t// locals\n\tvar el = $();\n\tvar viewsWithButtons = [];\n\tvar tm;\n\n\n\tfunction render() {\n\t\tvar sections = options.header;\n\n\t\ttm = options.theme ? 'ui' : 'fc';\n\n\t\tif (sections) {\n\t\t\tel = $(\"<div class='fc-toolbar'/>\")\n\t\t\t\t.append(renderSection('left'))\n\t\t\t\t.append(renderSection('right'))\n\t\t\t\t.append(renderSection('center'))\n\t\t\t\t.append('<div class=\"fc-clear\"/>');\n\n\t\t\treturn el;\n\t\t}\n\t}\n\t\n\t\n\tfunction destroy() {\n\t\tel.remove();\n\t}\n\t\n\t\n\tfunction renderSection(position) {\n\t\tvar sectionEl = $('<div class=\"fc-' + position + '\"/>');\n\t\tvar buttonStr = options.header[position];\n\n\t\tif (buttonStr) {\n\t\t\t$.each(buttonStr.split(' '), function(i) {\n\t\t\t\tvar groupChildren = $();\n\t\t\t\tvar isOnlyButtons = true;\n\t\t\t\tvar groupEl;\n\n\t\t\t\t$.each(this.split(','), function(j, buttonName) {\n\t\t\t\t\tvar buttonClick;\n\t\t\t\t\tvar themeIcon;\n\t\t\t\t\tvar normalIcon;\n\t\t\t\t\tvar defaultText;\n\t\t\t\t\tvar viewText; // highest priority\n\t\t\t\t\tvar customText;\n\t\t\t\t\tvar innerHtml;\n\t\t\t\t\tvar classes;\n\t\t\t\t\tvar button;\n\n\t\t\t\t\tif (buttonName == 'title') {\n\t\t\t\t\t\tgroupChildren = groupChildren.add($('<h2>&nbsp;</h2>')); // we always want it to take up height\n\t\t\t\t\t\tisOnlyButtons = false;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tif (calendar[buttonName]) { // a calendar method\n\t\t\t\t\t\t\tbuttonClick = function() {\n\t\t\t\t\t\t\t\tcalendar[buttonName]();\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (calendar.isValidViewType(buttonName)) { // a view type\n\t\t\t\t\t\t\tbuttonClick = function() {\n\t\t\t\t\t\t\t\tcalendar.changeView(buttonName);\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tviewsWithButtons.push(buttonName);\n\t\t\t\t\t\t\tviewText = calendar.getViewButtonText(buttonName);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (buttonClick) {\n\n\t\t\t\t\t\t\t// smartProperty allows different text per view button (ex: \"Agenda Week\" vs \"Basic Week\")\n\t\t\t\t\t\t\tthemeIcon = smartProperty(options.themeButtonIcons, buttonName);\n\t\t\t\t\t\t\tnormalIcon = smartProperty(options.buttonIcons, buttonName);\n\t\t\t\t\t\t\tdefaultText = smartProperty(options.defaultButtonText, buttonName); // from languages\n\t\t\t\t\t\t\tcustomText = smartProperty(options.buttonText, buttonName);\n\n\t\t\t\t\t\t\tif (viewText || customText) {\n\t\t\t\t\t\t\t\tinnerHtml = htmlEscape(viewText || customText);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (themeIcon && options.theme) {\n\t\t\t\t\t\t\t\tinnerHtml = \"<span class='ui-icon ui-icon-\" + themeIcon + \"'></span>\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse if (normalIcon && !options.theme) {\n\t\t\t\t\t\t\t\tinnerHtml = \"<span class='fc-icon fc-icon-\" + normalIcon + \"'></span>\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse {\n\t\t\t\t\t\t\t\tinnerHtml = htmlEscape(defaultText || buttonName);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tclasses = [\n\t\t\t\t\t\t\t\t'fc-' + buttonName + '-button',\n\t\t\t\t\t\t\t\ttm + '-button',\n\t\t\t\t\t\t\t\ttm + '-state-default'\n\t\t\t\t\t\t\t];\n\n\t\t\t\t\t\t\tbutton = $( // type=\"button\" so that it doesn't submit a form\n\t\t\t\t\t\t\t\t'<button type=\"button\" class=\"' + classes.join(' ') + '\">' +\n\t\t\t\t\t\t\t\t\tinnerHtml +\n\t\t\t\t\t\t\t\t'</button>'\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t.click(function() {\n\t\t\t\t\t\t\t\t\t// don't process clicks for disabled buttons\n\t\t\t\t\t\t\t\t\tif (!button.hasClass(tm + '-state-disabled')) {\n\n\t\t\t\t\t\t\t\t\t\tbuttonClick();\n\n\t\t\t\t\t\t\t\t\t\t// after the click action, if the button becomes the \"active\" tab, or disabled,\n\t\t\t\t\t\t\t\t\t\t// it should never have a hover class, so remove it now.\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\tbutton.hasClass(tm + '-state-active') ||\n\t\t\t\t\t\t\t\t\t\t\tbutton.hasClass(tm + '-state-disabled')\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\tbutton.removeClass(tm + '-state-hover');\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.mousedown(function() {\n\t\t\t\t\t\t\t\t\t// the *down* effect (mouse pressed in).\n\t\t\t\t\t\t\t\t\t// only on buttons that are not the \"active\" tab, or disabled\n\t\t\t\t\t\t\t\t\tbutton\n\t\t\t\t\t\t\t\t\t\t.not('.' + tm + '-state-active')\n\t\t\t\t\t\t\t\t\t\t.not('.' + tm + '-state-disabled')\n\t\t\t\t\t\t\t\t\t\t.addClass(tm + '-state-down');\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.mouseup(function() {\n\t\t\t\t\t\t\t\t\t// undo the *down* effect\n\t\t\t\t\t\t\t\t\tbutton.removeClass(tm + '-state-down');\n\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t.hover(\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\t// the *hover* effect.\n\t\t\t\t\t\t\t\t\t\t// only on buttons that are not the \"active\" tab, or disabled\n\t\t\t\t\t\t\t\t\t\tbutton\n\t\t\t\t\t\t\t\t\t\t\t.not('.' + tm + '-state-active')\n\t\t\t\t\t\t\t\t\t\t\t.not('.' + tm + '-state-disabled')\n\t\t\t\t\t\t\t\t\t\t\t.addClass(tm + '-state-hover');\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tfunction() {\n\t\t\t\t\t\t\t\t\t\t// undo the *hover* effect\n\t\t\t\t\t\t\t\t\t\tbutton\n\t\t\t\t\t\t\t\t\t\t\t.removeClass(tm + '-state-hover')\n\t\t\t\t\t\t\t\t\t\t\t.removeClass(tm + '-state-down'); // if mouseleave happens before mouseup\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t);\n\n\t\t\t\t\t\t\tgroupChildren = groupChildren.add(button);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif (isOnlyButtons) {\n\t\t\t\t\tgroupChildren\n\t\t\t\t\t\t.first().addClass(tm + '-corner-left').end()\n\t\t\t\t\t\t.last().addClass(tm + '-corner-right').end();\n\t\t\t\t}\n\n\t\t\t\tif (groupChildren.length > 1) {\n\t\t\t\t\tgroupEl = $('<div/>');\n\t\t\t\t\tif (isOnlyButtons) {\n\t\t\t\t\t\tgroupEl.addClass('fc-button-group');\n\t\t\t\t\t}\n\t\t\t\t\tgroupEl.append(groupChildren);\n\t\t\t\t\tsectionEl.append(groupEl);\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tsectionEl.append(groupChildren); // 1 or 0 children\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn sectionEl;\n\t}\n\t\n\t\n\tfunction updateTitle(text) {\n\t\tel.find('h2').text(text);\n\t}\n\t\n\t\n\tfunction activateButton(buttonName) {\n\t\tel.find('.fc-' + buttonName + '-button')\n\t\t\t.addClass(tm + '-state-active');\n\t}\n\t\n\t\n\tfunction deactivateButton(buttonName) {\n\t\tel.find('.fc-' + buttonName + '-button')\n\t\t\t.removeClass(tm + '-state-active');\n\t}\n\t\n\t\n\tfunction disableButton(buttonName) {\n\t\tel.find('.fc-' + buttonName + '-button')\n\t\t\t.attr('disabled', 'disabled')\n\t\t\t.addClass(tm + '-state-disabled');\n\t}\n\t\n\t\n\tfunction enableButton(buttonName) {\n\t\tel.find('.fc-' + buttonName + '-button')\n\t\t\t.removeAttr('disabled')\n\t\t\t.removeClass(tm + '-state-disabled');\n\t}\n\n\n\tfunction getViewsWithButtons() {\n\t\treturn viewsWithButtons;\n\t}\n\n}\n\n    fc.sourceNormalizers = [];\nfc.sourceFetchers = [];\n\nvar ajaxDefaults = {\n\tdataType: 'json',\n\tcache: false\n};\n\nvar eventGUID = 1;\n\n\nfunction EventManager(options) { // assumed to be a calendar\n\tvar t = this;\n\t\n\t\n\t// exports\n\tt.isFetchNeeded = isFetchNeeded;\n\tt.fetchEvents = fetchEvents;\n\tt.addEventSource = addEventSource;\n\tt.removeEventSource = removeEventSource;\n\tt.updateEvent = updateEvent;\n\tt.renderEvent = renderEvent;\n\tt.removeEvents = removeEvents;\n\tt.clientEvents = clientEvents;\n\tt.mutateEvent = mutateEvent;\n\tt.normalizeEventDateProps = normalizeEventDateProps;\n\tt.ensureVisibleEventRange = ensureVisibleEventRange;\n\t\n\t\n\t// imports\n\tvar trigger = t.trigger;\n\tvar getView = t.getView;\n\tvar reportEvents = t.reportEvents;\n\t\n\t\n\t// locals\n\tvar stickySource = { events: [] };\n\tvar sources = [ stickySource ];\n\tvar rangeStart, rangeEnd;\n\tvar currentFetchID = 0;\n\tvar pendingSourceCnt = 0;\n\tvar loadingLevel = 0;\n\tvar cache = []; // holds events that have already been expanded\n\n\n\t$.each(\n\t\t(options.events ? [ options.events ] : []).concat(options.eventSources || []),\n\t\tfunction(i, sourceInput) {\n\t\t\tvar source = buildEventSource(sourceInput);\n\t\t\tif (source) {\n\t\t\t\tsources.push(source);\n\t\t\t}\n\t\t}\n\t);\n\t\n\t\n\t\n\t/* Fetching\n\t-----------------------------------------------------------------------------*/\n\t\n\t\n\tfunction isFetchNeeded(start, end) {\n\t\treturn !rangeStart || // nothing has been fetched yet?\n\t\t\t// or, a part of the new range is outside of the old range? (after normalizing)\n\t\t\tstart.clone().stripZone() < rangeStart.clone().stripZone() ||\n\t\t\tend.clone().stripZone() > rangeEnd.clone().stripZone();\n\t}\n\t\n\t\n\tfunction fetchEvents(start, end) {\n\t\trangeStart = start;\n\t\trangeEnd = end;\n\t\tcache = [];\n\t\tvar fetchID = ++currentFetchID;\n\t\tvar len = sources.length;\n\t\tpendingSourceCnt = len;\n\t\tfor (var i=0; i<len; i++) {\n\t\t\tfetchEventSource(sources[i], fetchID);\n\t\t}\n\t}\n\t\n\t\n\tfunction fetchEventSource(source, fetchID) {\n\t\t_fetchEventSource(source, function(eventInputs) {\n\t\t\tvar isArraySource = $.isArray(source.events);\n\t\t\tvar i, eventInput;\n\t\t\tvar abstractEvent;\n\n\t\t\tif (fetchID == currentFetchID) {\n\n\t\t\t\tif (eventInputs) {\n\t\t\t\t\tfor (i = 0; i < eventInputs.length; i++) {\n\t\t\t\t\t\teventInput = eventInputs[i];\n\n\t\t\t\t\t\tif (isArraySource) { // array sources have already been convert to Event Objects\n\t\t\t\t\t\t\tabstractEvent = eventInput;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse {\n\t\t\t\t\t\t\tabstractEvent = buildEventFromInput(eventInput, source);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (abstractEvent) { // not false (an invalid event)\n\t\t\t\t\t\t\tcache.push.apply(\n\t\t\t\t\t\t\t\tcache,\n\t\t\t\t\t\t\t\texpandEvent(abstractEvent) // add individual expanded events to the cache\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tpendingSourceCnt--;\n\t\t\t\tif (!pendingSourceCnt) {\n\t\t\t\t\treportEvents(cache);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\t\n\t\n\tfunction _fetchEventSource(source, callback) {\n\t\tvar i;\n\t\tvar fetchers = fc.sourceFetchers;\n\t\tvar res;\n\n\t\tfor (i=0; i<fetchers.length; i++) {\n\t\t\tres = fetchers[i].call(\n\t\t\t\tt, // this, the Calendar object\n\t\t\t\tsource,\n\t\t\t\trangeStart.clone(),\n\t\t\t\trangeEnd.clone(),\n\t\t\t\toptions.timezone,\n\t\t\t\tcallback\n\t\t\t);\n\n\t\t\tif (res === true) {\n\t\t\t\t// the fetcher is in charge. made its own async request\n\t\t\t\treturn;\n\t\t\t}\n\t\t\telse if (typeof res == 'object') {\n\t\t\t\t// the fetcher returned a new source. process it\n\t\t\t\t_fetchEventSource(res, callback);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\n\t\tvar events = source.events;\n\t\tif (events) {\n\t\t\tif ($.isFunction(events)) {\n\t\t\t\tpushLoading();\n\t\t\t\tevents.call(\n\t\t\t\t\tt, // this, the Calendar object\n\t\t\t\t\trangeStart.clone(),\n\t\t\t\t\trangeEnd.clone(),\n\t\t\t\t\toptions.timezone,\n\t\t\t\t\tfunction(events) {\n\t\t\t\t\t\tcallback(events);\n\t\t\t\t\t\tpopLoading();\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t}\n\t\t\telse if ($.isArray(events)) {\n\t\t\t\tcallback(events);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tcallback();\n\t\t\t}\n\t\t}else{\n\t\t\tvar url = source.url;\n\t\t\tif (url) {\n\t\t\t\tvar success = source.success;\n\t\t\t\tvar error = source.error;\n\t\t\t\tvar complete = source.complete;\n\n\t\t\t\t// retrieve any outbound GET/POST $.ajax data from the options\n\t\t\t\tvar customData;\n\t\t\t\tif ($.isFunction(source.data)) {\n\t\t\t\t\t// supplied as a function that returns a key/value object\n\t\t\t\t\tcustomData = source.data();\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// supplied as a straight key/value object\n\t\t\t\t\tcustomData = source.data;\n\t\t\t\t}\n\n\t\t\t\t// use a copy of the custom data so we can modify the parameters\n\t\t\t\t// and not affect the passed-in object.\n\t\t\t\tvar data = $.extend({}, customData || {});\n\n\t\t\t\tvar startParam = firstDefined(source.startParam, options.startParam);\n\t\t\t\tvar endParam = firstDefined(source.endParam, options.endParam);\n\t\t\t\tvar timezoneParam = firstDefined(source.timezoneParam, options.timezoneParam);\n\n\t\t\t\tif (startParam) {\n\t\t\t\t\tdata[startParam] = rangeStart.format();\n\t\t\t\t}\n\t\t\t\tif (endParam) {\n\t\t\t\t\tdata[endParam] = rangeEnd.format();\n\t\t\t\t}\n\t\t\t\tif (options.timezone && options.timezone != 'local') {\n\t\t\t\t\tdata[timezoneParam] = options.timezone;\n\t\t\t\t}\n\n\t\t\t\tpushLoading();\n\t\t\t\t$.ajax($.extend({}, ajaxDefaults, source, {\n\t\t\t\t\tdata: data,\n\t\t\t\t\tsuccess: function(events) {\n\t\t\t\t\t\tevents = events || [];\n\t\t\t\t\t\tvar res = applyAll(success, this, arguments);\n\t\t\t\t\t\tif ($.isArray(res)) {\n\t\t\t\t\t\t\tevents = res;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcallback(events);\n\t\t\t\t\t},\n\t\t\t\t\terror: function() {\n\t\t\t\t\t\tapplyAll(error, this, arguments);\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t},\n\t\t\t\t\tcomplete: function() {\n\t\t\t\t\t\tapplyAll(complete, this, arguments);\n\t\t\t\t\t\tpopLoading();\n\t\t\t\t\t}\n\t\t\t\t}));\n\t\t\t}else{\n\t\t\t\tcallback();\n\t\t\t}\n\t\t}\n\t}\n\t\n\t\n\t\n\t/* Sources\n\t-----------------------------------------------------------------------------*/\n\t\n\n\tfunction addEventSource(sourceInput) {\n\t\tvar source = buildEventSource(sourceInput);\n\t\tif (source) {\n\t\t\tsources.push(source);\n\t\t\tpendingSourceCnt++;\n\t\t\tfetchEventSource(source, currentFetchID); // will eventually call reportEvents\n\t\t}\n\t}\n\n\n\tfunction buildEventSource(sourceInput) { // will return undefined if invalid source\n\t\tvar normalizers = fc.sourceNormalizers;\n\t\tvar source;\n\t\tvar i;\n\n\t\tif ($.isFunction(sourceInput) || $.isArray(sourceInput)) {\n\t\t\tsource = { events: sourceInput };\n\t\t}\n\t\telse if (typeof sourceInput === 'string') {\n\t\t\tsource = { url: sourceInput };\n\t\t}\n\t\telse if (typeof sourceInput === 'object') {\n\t\t\tsource = $.extend({}, sourceInput); // shallow copy\n\t\t}\n\n\t\tif (source) {\n\n\t\t\t// TODO: repeat code, same code for event classNames\n\t\t\tif (source.className) {\n\t\t\t\tif (typeof source.className === 'string') {\n\t\t\t\t\tsource.className = source.className.split(/\\s+/);\n\t\t\t\t}\n\t\t\t\t// otherwise, assumed to be an array\n\t\t\t}\n\t\t\telse {\n\t\t\t\tsource.className = [];\n\t\t\t}\n\n\t\t\t// for array sources, we convert to standard Event Objects up front\n\t\t\tif ($.isArray(source.events)) {\n\t\t\t\tsource.origArray = source.events; // for removeEventSource\n\t\t\t\tsource.events = $.map(source.events, function(eventInput) {\n\t\t\t\t\treturn buildEventFromInput(eventInput, source);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tfor (i=0; i<normalizers.length; i++) {\n\t\t\t\tnormalizers[i].call(t, source);\n\t\t\t}\n\n\t\t\treturn source;\n\t\t}\n\t}\n\n\n\tfunction removeEventSource(source) {\n\t\tsources = $.grep(sources, function(src) {\n\t\t\treturn !isSourcesEqual(src, source);\n\t\t});\n\t\t// remove all client events from that source\n\t\tcache = $.grep(cache, function(e) {\n\t\t\treturn !isSourcesEqual(e.source, source);\n\t\t});\n\t\treportEvents(cache);\n\t}\n\n\n\tfunction isSourcesEqual(source1, source2) {\n\t\treturn source1 && source2 && getSourcePrimitive(source1) == getSourcePrimitive(source2);\n\t}\n\n\n\tfunction getSourcePrimitive(source) {\n\t\treturn (\n\t\t\t(typeof source === 'object') ? // a normalized event source?\n\t\t\t\t(source.origArray || source.googleCalendarId || source.url || source.events) : // get the primitive\n\t\t\t\tnull\n\t\t) ||\n\t\tsource; // the given argument *is* the primitive\n\t}\n\t\n\t\n\t\n\t/* Manipulation\n\t-----------------------------------------------------------------------------*/\n\n\n\t// Only ever called from the externally-facing API\n\tfunction updateEvent(event) {\n\n\t\t// massage start/end values, even if date string values\n\t\tevent.start = t.moment(event.start);\n\t\tif (event.end) {\n\t\t\tevent.end = t.moment(event.end);\n\t\t}\n\t\telse {\n\t\t\tevent.end = null;\n\t\t}\n\n\t\tmutateEvent(event, getMiscEventProps(event)); // will handle start/end/allDay normalization\n\t\treportEvents(cache); // reports event modifications (so we can redraw)\n\t}\n\n\n\t// Returns a hash of misc event properties that should be copied over to related events.\n\tfunction getMiscEventProps(event) {\n\t\tvar props = {};\n\n\t\t$.each(event, function(name, val) {\n\t\t\tif (isMiscEventPropName(name)) {\n\t\t\t\tif (val !== undefined && isAtomic(val)) { // a defined non-object\n\t\t\t\t\tprops[name] = val;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn props;\n\t}\n\n\t// non-date-related, non-id-related, non-secret\n\tfunction isMiscEventPropName(name) {\n\t\treturn !/^_|^(id|allDay|start|end)$/.test(name);\n\t}\n\n\t\n\t// returns the expanded events that were created\n\tfunction renderEvent(eventInput, stick) {\n\t\tvar abstractEvent = buildEventFromInput(eventInput);\n\t\tvar events;\n\t\tvar i, event;\n\n\t\tif (abstractEvent) { // not false (a valid input)\n\t\t\tevents = expandEvent(abstractEvent);\n\n\t\t\tfor (i = 0; i < events.length; i++) {\n\t\t\t\tevent = events[i];\n\n\t\t\t\tif (!event.source) {\n\t\t\t\t\tif (stick) {\n\t\t\t\t\t\tstickySource.events.push(event);\n\t\t\t\t\t\tevent.source = stickySource;\n\t\t\t\t\t}\n\t\t\t\t\tcache.push(event);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treportEvents(cache);\n\n\t\t\treturn events;\n\t\t}\n\n\t\treturn [];\n\t}\n\t\n\t\n\tfunction removeEvents(filter) {\n\t\tvar eventID;\n\t\tvar i;\n\n\t\tif (filter == null) { // null or undefined. remove all events\n\t\t\tfilter = function() { return true; }; // will always match\n\t\t}\n\t\telse if (!$.isFunction(filter)) { // an event ID\n\t\t\teventID = filter + '';\n\t\t\tfilter = function(event) {\n\t\t\t\treturn event._id == eventID;\n\t\t\t};\n\t\t}\n\n\t\t// Purge event(s) from our local cache\n\t\tcache = $.grep(cache, filter, true); // inverse=true\n\n\t\t// Remove events from array sources.\n\t\t// This works because they have been converted to official Event Objects up front.\n\t\t// (and as a result, event._id has been calculated).\n\t\tfor (i=0; i<sources.length; i++) {\n\t\t\tif ($.isArray(sources[i].events)) {\n\t\t\t\tsources[i].events = $.grep(sources[i].events, filter, true);\n\t\t\t}\n\t\t}\n\n\t\treportEvents(cache);\n\t}\n\t\n\t\n\tfunction clientEvents(filter) {\n\t\tif ($.isFunction(filter)) {\n\t\t\treturn $.grep(cache, filter);\n\t\t}\n\t\telse if (filter != null) { // not null, not undefined. an event ID\n\t\t\tfilter += '';\n\t\t\treturn $.grep(cache, function(e) {\n\t\t\t\treturn e._id == filter;\n\t\t\t});\n\t\t}\n\t\treturn cache; // else, return all\n\t}\n\t\n\t\n\t\n\t/* Loading State\n\t-----------------------------------------------------------------------------*/\n\t\n\t\n\tfunction pushLoading() {\n\t\tif (!(loadingLevel++)) {\n\t\t\ttrigger('loading', null, true, getView());\n\t\t}\n\t}\n\t\n\t\n\tfunction popLoading() {\n\t\tif (!(--loadingLevel)) {\n\t\t\ttrigger('loading', null, false, getView());\n\t\t}\n\t}\n\t\n\t\n\t\n\t/* Event Normalization\n\t-----------------------------------------------------------------------------*/\n\n\n\t// Given a raw object with key/value properties, returns an \"abstract\" Event object.\n\t// An \"abstract\" event is an event that, if recurring, will not have been expanded yet.\n\t// Will return `false` when input is invalid.\n\t// `source` is optional\n\tfunction buildEventFromInput(input, source) {\n\t\tvar out = {};\n\t\tvar start, end;\n\t\tvar allDay;\n\n\t\tif (options.eventDataTransform) {\n\t\t\tinput = options.eventDataTransform(input);\n\t\t}\n\t\tif (source && source.eventDataTransform) {\n\t\t\tinput = source.eventDataTransform(input);\n\t\t}\n\n\t\t// Copy all properties over to the resulting object.\n\t\t// The special-case properties will be copied over afterwards.\n\t\t$.extend(out, input);\n\n\t\tif (source) {\n\t\t\tout.source = source;\n\t\t}\n\n\t\tout._id = input._id || (input.id === undefined ? '_fc' + eventGUID++ : input.id + '');\n\n\t\tif (input.className) {\n\t\t\tif (typeof input.className == 'string') {\n\t\t\t\tout.className = input.className.split(/\\s+/);\n\t\t\t}\n\t\t\telse { // assumed to be an array\n\t\t\t\tout.className = input.className;\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tout.className = [];\n\t\t}\n\n\t\tstart = input.start || input.date; // \"date\" is an alias for \"start\"\n\t\tend = input.end;\n\n\t\t// parse as a time (Duration) if applicable\n\t\tif (isTimeString(start)) {\n\t\t\tstart = moment.duration(start);\n\t\t}\n\t\tif (isTimeString(end)) {\n\t\t\tend = moment.duration(end);\n\t\t}\n\n\t\tif (input.dow || moment.isDuration(start) || moment.isDuration(end)) {\n\n\t\t\t// the event is \"abstract\" (recurring) so don't calculate exact start/end dates just yet\n\t\t\tout.start = start ? moment.duration(start) : null; // will be a Duration or null\n\t\t\tout.end = end ? moment.duration(end) : null; // will be a Duration or null\n\t\t\tout._recurring = true; // our internal marker\n\t\t}\n\t\telse {\n\n\t\t\tif (start) {\n\t\t\t\tstart = t.moment(start);\n\t\t\t\tif (!start.isValid()) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (end) {\n\t\t\t\tend = t.moment(end);\n\t\t\t\tif (!end.isValid()) {\n\t\t\t\t\tend = null; // let defaults take over\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tallDay = input.allDay;\n\t\t\tif (allDay === undefined) { // still undefined? fallback to default\n\t\t\t\tallDay = firstDefined(\n\t\t\t\t\tsource ? source.allDayDefault : undefined,\n\t\t\t\t\toptions.allDayDefault\n\t\t\t\t);\n\t\t\t\t// still undefined? normalizeEventDateProps will calculate it\n\t\t\t}\n\n\t\t\tassignDatesToEvent(start, end, allDay, out);\n\t\t}\n\n\t\treturn out;\n\t}\n\n\n\t// Normalizes and assigns the given dates to the given partially-formed event object.\n\t// NOTE: mutates the given start/end moments. does not make a copy.\n\tfunction assignDatesToEvent(start, end, allDay, event) {\n\t\tevent.start = start;\n\t\tevent.end = end;\n\t\tevent.allDay = allDay;\n\t\tnormalizeEventDateProps(event);\n\t\tbackupEventDates(event);\n\t}\n\n\n\t// Ensures the allDay property exists.\n\t// Ensures the start/end dates are consistent with allDay and forceEventDuration.\n\t// Accepts an Event object, or a plain object with event-ish properties.\n\t// NOTE: Will modify the given object.\n\tfunction normalizeEventDateProps(props) {\n\n\t\tif (props.allDay == null) {\n\t\t\tprops.allDay = !(props.start.hasTime() || (props.end && props.end.hasTime()));\n\t\t}\n\n\t\tif (props.allDay) {\n\t\t\tprops.start.stripTime();\n\t\t\tif (props.end) {\n\t\t\t\tprops.end.stripTime();\n\t\t\t}\n\t\t}\n\t\telse {\n\t\t\tif (!props.start.hasTime()) {\n\t\t\t\tprops.start = t.rezoneDate(props.start); // will also give it a 00:00 time\n\t\t\t}\n\t\t\tif (props.end && !props.end.hasTime()) {\n\t\t\t\tprops.end = t.rezoneDate(props.end); // will also give it a 00:00 time\n\t\t\t}\n\t\t}\n\n\t\tif (props.end && !props.end.isAfter(props.start)) {\n\t\t\tprops.end = null;\n\t\t}\n\n\t\tif (!props.end) {\n\t\t\tif (options.forceEventDuration) {\n\t\t\t\tprops.end = t.getDefaultEventEnd(props.allDay, props.start);\n\t\t\t}\n\t\t\telse {\n\t\t\t\tprops.end = null;\n\t\t\t}\n\t\t}\n\t}\n\n\n\t// If `range` is a proper range with a start and end, returns the original object.\n\t// If missing an end, computes a new range with an end, computing it as if it were an event.\n\t// TODO: make this a part of the event -> eventRange system\n\tfunction ensureVisibleEventRange(range) {\n\t\tvar allDay;\n\n\t\tif (!range.end) {\n\n\t\t\tallDay = range.allDay; // range might be more event-ish than we think\n\t\t\tif (allDay == null) {\n\t\t\t\tallDay = !range.start.hasTime();\n\t\t\t}\n\n\t\t\trange = {\n\t\t\t\tstart: range.start,\n\t\t\t\tend: t.getDefaultEventEnd(allDay, range.start)\n\t\t\t};\n\t\t}\n\t\treturn range;\n\t}\n\n\n\t// If the given event is a recurring event, break it down into an array of individual instances.\n\t// If not a recurring event, return an array with the single original event.\n\t// If given a falsy input (probably because of a failed buildEventFromInput call), returns an empty array.\n\t// HACK: can override the recurring window by providing custom rangeStart/rangeEnd (for businessHours).\n\tfunction expandEvent(abstractEvent, _rangeStart, _rangeEnd) {\n\t\tvar events = [];\n\t\tvar dowHash;\n\t\tvar dow;\n\t\tvar i;\n\t\tvar date;\n\t\tvar startTime, endTime;\n\t\tvar start, end;\n\t\tvar event;\n\n\t\t_rangeStart = _rangeStart || rangeStart;\n\t\t_rangeEnd = _rangeEnd || rangeEnd;\n\n\t\tif (abstractEvent) {\n\t\t\tif (abstractEvent._recurring) {\n\n\t\t\t\t// make a boolean hash as to whether the event occurs on each day-of-week\n\t\t\t\tif ((dow = abstractEvent.dow)) {\n\t\t\t\t\tdowHash = {};\n\t\t\t\t\tfor (i = 0; i < dow.length; i++) {\n\t\t\t\t\t\tdowHash[dow[i]] = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// iterate through every day in the current range\n\t\t\t\tdate = _rangeStart.clone().stripTime(); // holds the date of the current day\n\t\t\t\twhile (date.isBefore(_rangeEnd)) {\n\n\t\t\t\t\tif (!dowHash || dowHash[date.day()]) { // if everyday, or this particular day-of-week\n\n\t\t\t\t\t\tstartTime = abstractEvent.start; // the stored start and end properties are times (Durations)\n\t\t\t\t\t\tendTime = abstractEvent.end; // \"\n\t\t\t\t\t\tstart = date.clone();\n\t\t\t\t\t\tend = null;\n\n\t\t\t\t\t\tif (startTime) {\n\t\t\t\t\t\t\tstart = start.time(startTime);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (endTime) {\n\t\t\t\t\t\t\tend = date.clone().time(endTime);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tevent = $.extend({}, abstractEvent); // make a copy of the original\n\t\t\t\t\t\tassignDatesToEvent(\n\t\t\t\t\t\t\tstart, end,\n\t\t\t\t\t\t\t!startTime && !endTime, // allDay?\n\t\t\t\t\t\t\tevent\n\t\t\t\t\t\t);\n\t\t\t\t\t\tevents.push(event);\n\t\t\t\t\t}\n\n\t\t\t\t\tdate.add(1, 'days');\n\t\t\t\t}\n\t\t\t}\n\t\t\telse {\n\t\t\t\tevents.push(abstractEvent); // return the original event. will be a one-item array\n\t\t\t}\n\t\t}\n\n\t\treturn events;\n\t}\n\n\n\n\t/* Event Modification Math\n\t-----------------------------------------------------------------------------------------*/\n\n\n\t// Modifies an event and all related events by applying the given properties.\n\t// Special date-diffing logic is used for manipulation of dates.\n\t// If `props` does not contain start/end dates, the updated values are assumed to be the event's current start/end.\n\t// All date comparisons are done against the event's pristine _start and _end dates.\n\t// Returns an object with delta information and a function to undo all operations.\n\t//\n\tfunction mutateEvent(event, props) {\n\t\tvar miscProps = {};\n\t\tvar clearEnd;\n\t\tvar dateDelta;\n\t\tvar durationDelta;\n\t\tvar undoFunc;\n\n\t\tprops = props || {};\n\n\t\t// ensure new date-related values to compare against\n\t\tif (!props.start) {\n\t\t\tprops.start = event.start.clone();\n\t\t}\n\t\tif (props.end === undefined) {\n\t\t\tprops.end = event.end ? event.end.clone() : null;\n\t\t}\n\t\tif (props.allDay == null) { // is null or undefined?\n\t\t\tprops.allDay = event.allDay;\n\t\t}\n\n\t\tnormalizeEventDateProps(props); // massages start/end/allDay\n\n\t\t// clear the end date if explicitly changed to null\n\t\tclearEnd = event._end !== null && props.end === null;\n\n\t\t// compute the delta for moving the start and end dates together\n\t\tif (props.allDay) {\n\t\t\tdateDelta = diffDay(props.start, event._start); // whole-day diff from start-of-day\n\t\t}\n\t\telse {\n\t\t\tdateDelta = diffDayTime(props.start, event._start);\n\t\t}\n\n\t\t// compute the delta for moving the end date (after applying dateDelta)\n\t\tif (!clearEnd && props.end) {\n\t\t\tdurationDelta = diffDayTime(\n\t\t\t\t// new duration\n\t\t\t\tprops.end,\n\t\t\t\tprops.start\n\t\t\t).subtract(diffDayTime(\n\t\t\t\t// subtract old duration\n\t\t\t\tevent._end || t.getDefaultEventEnd(event._allDay, event._start),\n\t\t\t\tevent._start\n\t\t\t));\n\t\t}\n\n\t\t// gather all non-date-related properties\n\t\t$.each(props, function(name, val) {\n\t\t\tif (isMiscEventPropName(name)) {\n\t\t\t\tif (val !== undefined) {\n\t\t\t\t\tmiscProps[name] = val;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// apply the operations to the event and all related events\n\t\tundoFunc = mutateEvents(\n\t\t\tclientEvents(event._id), // get events with this ID\n\t\t\tclearEnd,\n\t\t\tprops.allDay,\n\t\t\tdateDelta,\n\t\t\tdurationDelta,\n\t\t\tmiscProps\n\t\t);\n\n\t\treturn {\n\t\t\tdateDelta: dateDelta,\n\t\t\tdurationDelta: durationDelta,\n\t\t\tundo: undoFunc\n\t\t};\n\t}\n\n\n\t// Modifies an array of events in the following ways (operations are in order):\n\t// - clear the event's `end`\n\t// - convert the event to allDay\n\t// - add `dateDelta` to the start and end\n\t// - add `durationDelta` to the event's duration\n\t// - assign `miscProps` to the event\n\t//\n\t// Returns a function that can be called to undo all the operations.\n\t//\n\t// TODO: don't use so many closures. possible memory issues when lots of events with same ID.\n\t//\n\tfunction mutateEvents(events, clearEnd, allDay, dateDelta, durationDelta, miscProps) {\n\t\tvar isAmbigTimezone = t.getIsAmbigTimezone();\n\t\tvar undoFunctions = [];\n\n\t\t// normalize zero-length deltas to be null\n\t\tif (dateDelta && !dateDelta.valueOf()) { dateDelta = null; }\n\t\tif (durationDelta && !durationDelta.valueOf()) { durationDelta = null; }\n\n\t\t$.each(events, function(i, event) {\n\t\t\tvar oldProps;\n\t\t\tvar newProps;\n\n\t\t\t// build an object holding all the old values, both date-related and misc.\n\t\t\t// for the undo function.\n\t\t\toldProps = {\n\t\t\t\tstart: event.start.clone(),\n\t\t\t\tend: event.end ? event.end.clone() : null,\n\t\t\t\tallDay: event.allDay\n\t\t\t};\n\t\t\t$.each(miscProps, function(name) {\n\t\t\t\toldProps[name] = event[name];\n\t\t\t});\n\n\t\t\t// new date-related properties. work off the original date snapshot.\n\t\t\t// ok to use references because they will be thrown away when backupEventDates is called.\n\t\t\tnewProps = {\n\t\t\t\tstart: event._start,\n\t\t\t\tend: event._end,\n\t\t\t\tallDay: event._allDay\n\t\t\t};\n\n\t\t\tif (clearEnd) {\n\t\t\t\tnewProps.end = null;\n\t\t\t}\n\n\t\t\tnewProps.allDay = allDay;\n\n\t\t\tnormalizeEventDateProps(newProps); // massages start/end/allDay\n\n\t\t\tif (dateDelta) {\n\t\t\t\tnewProps.start.add(dateDelta);\n\t\t\t\tif (newProps.end) {\n\t\t\t\t\tnewProps.end.add(dateDelta);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (durationDelta) {\n\t\t\t\tif (!newProps.end) {\n\t\t\t\t\tnewProps.end = t.getDefaultEventEnd(newProps.allDay, newProps.start);\n\t\t\t\t}\n\t\t\t\tnewProps.end.add(durationDelta);\n\t\t\t}\n\n\t\t\t// if the dates have changed, and we know it is impossible to recompute the\n\t\t\t// timezone offsets, strip the zone.\n\t\t\tif (\n\t\t\t\tisAmbigTimezone &&\n\t\t\t\t!newProps.allDay &&\n\t\t\t\t(dateDelta || durationDelta)\n\t\t\t) {\n\t\t\t\tnewProps.start.stripZone();\n\t\t\t\tif (newProps.end) {\n\t\t\t\t\tnewProps.end.stripZone();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$.extend(event, miscProps, newProps); // copy over misc props, then date-related props\n\t\t\tbackupEventDates(event); // regenerate internal _start/_end/_allDay\n\n\t\t\tundoFunctions.push(function() {\n\t\t\t\t$.extend(event, oldProps);\n\t\t\t\tbackupEventDates(event); // regenerate internal _start/_end/_allDay\n\t\t\t});\n\t\t});\n\n\t\treturn function() {\n\t\t\tfor (var i = 0; i < undoFunctions.length; i++) {\n\t\t\t\tundoFunctions[i]();\n\t\t\t}\n\t\t};\n\t}\n\n\n\t/* Business Hours\n\t-----------------------------------------------------------------------------------------*/\n\n\tt.getBusinessHoursEvents = getBusinessHoursEvents;\n\n\n\t// Returns an array of events as to when the business hours occur in the given view.\n\t// Abuse of our event system :(\n\tfunction getBusinessHoursEvents() {\n\t\tvar optionVal = options.businessHours;\n\t\tvar defaultVal = {\n\t\t\tclassName: 'fc-nonbusiness',\n\t\t\tstart: '09:00',\n\t\t\tend: '17:00',\n\t\t\tdow: [ 1, 2, 3, 4, 5 ], // monday - friday\n\t\t\trendering: 'inverse-background'\n\t\t};\n\t\tvar view = t.getView();\n\t\tvar eventInput;\n\n\t\tif (optionVal) {\n\t\t\tif (typeof optionVal === 'object') {\n\t\t\t\t// option value is an object that can override the default business hours\n\t\t\t\teventInput = $.extend({}, defaultVal, optionVal);\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// option value is `true`. use default business hours\n\t\t\t\teventInput = defaultVal;\n\t\t\t}\n\t\t}\n\n\t\tif (eventInput) {\n\t\t\treturn expandEvent(\n\t\t\t\tbuildEventFromInput(eventInput),\n\t\t\t\tview.start,\n\t\t\t\tview.end\n\t\t\t);\n\t\t}\n\n\t\treturn [];\n\t}\n\n\n\t/* Overlapping / Constraining\n\t-----------------------------------------------------------------------------------------*/\n\n\tt.isEventRangeAllowed = isEventRangeAllowed;\n\tt.isSelectionRangeAllowed = isSelectionRangeAllowed;\n\tt.isExternalDropRangeAllowed = isExternalDropRangeAllowed;\n\n\n\tfunction isEventRangeAllowed(range, event) {\n\t\tvar source = event.source || {};\n\t\tvar constraint = firstDefined(\n\t\t\tevent.constraint,\n\t\t\tsource.constraint,\n\t\t\toptions.eventConstraint\n\t\t);\n\t\tvar overlap = firstDefined(\n\t\t\tevent.overlap,\n\t\t\tsource.overlap,\n\t\t\toptions.eventOverlap\n\t\t);\n\n\t\trange = ensureVisibleEventRange(range); // ensure a proper range with an end for isRangeAllowed\n\n\t\treturn isRangeAllowed(range, constraint, overlap, event);\n\t}\n\n\n\tfunction isSelectionRangeAllowed(range) {\n\t\treturn isRangeAllowed(range, options.selectConstraint, options.selectOverlap);\n\t}\n\n\n\t// when `eventProps` is defined, consider this an event.\n\t// `eventProps` can contain misc non-date-related info about the event.\n\tfunction isExternalDropRangeAllowed(range, eventProps) {\n\t\tvar eventInput;\n\t\tvar event;\n\n\t\t// note: very similar logic is in View's reportExternalDrop\n\t\tif (eventProps) {\n\t\t\teventInput = $.extend({}, eventProps, range);\n\t\t\tevent = expandEvent(buildEventFromInput(eventInput))[0];\n\t\t}\n\n\t\tif (event) {\n\t\t\treturn isEventRangeAllowed(range, event);\n\t\t}\n\t\telse { // treat it as a selection\n\n\t\t\trange = ensureVisibleEventRange(range); // ensure a proper range with an end for isSelectionRangeAllowed\n\n\t\t\treturn isSelectionRangeAllowed(range);\n\t\t}\n\t}\n\n\n\t// Returns true if the given range (caused by an event drop/resize or a selection) is allowed to exist\n\t// according to the constraint/overlap settings.\n\t// `event` is not required if checking a selection.\n\tfunction isRangeAllowed(range, constraint, overlap, event) {\n\t\tvar constraintEvents;\n\t\tvar anyContainment;\n\t\tvar i, otherEvent;\n\t\tvar otherOverlap;\n\n\t\t// normalize. fyi, we're normalizing in too many places :(\n\t\trange = {\n\t\t\tstart: range.start.clone().stripZone(),\n\t\t\tend: range.end.clone().stripZone()\n\t\t};\n\n\t\t// the range must be fully contained by at least one of produced constraint events\n\t\tif (constraint != null) {\n\n\t\t\t// not treated as an event! intermediate data structure\n\t\t\t// TODO: use ranges in the future\n\t\t\tconstraintEvents = constraintToEvents(constraint);\n\n\t\t\tanyContainment = false;\n\t\t\tfor (i = 0; i < constraintEvents.length; i++) {\n\t\t\t\tif (eventContainsRange(constraintEvents[i], range)) {\n\t\t\t\t\tanyContainment = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!anyContainment) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tfor (i = 0; i < cache.length; i++) { // loop all events and detect overlap\n\t\t\totherEvent = cache[i];\n\n\t\t\t// don't compare the event to itself or other related [repeating] events\n\t\t\tif (event && event._id === otherEvent._id) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// there needs to be an actual intersection before disallowing anything\n\t\t\tif (eventIntersectsRange(otherEvent, range)) {\n\n\t\t\t\t// evaluate overlap for the given range and short-circuit if necessary\n\t\t\t\tif (overlap === false) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\telse if (typeof overlap === 'function' && !overlap(otherEvent, event)) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\n\t\t\t\t// if we are computing if the given range is allowable for an event, consider the other event's\n\t\t\t\t// EventObject-specific or Source-specific `overlap` property\n\t\t\t\tif (event) {\n\t\t\t\t\totherOverlap = firstDefined(\n\t\t\t\t\t\totherEvent.overlap,\n\t\t\t\t\t\t(otherEvent.source || {}).overlap\n\t\t\t\t\t\t// we already considered the global `eventOverlap`\n\t\t\t\t\t);\n\t\t\t\t\tif (otherOverlap === false) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif (typeof otherOverlap === 'function' && !otherOverlap(event, otherEvent)) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\n\t// Given an event input from the API, produces an array of event objects. Possible event inputs:\n\t// 'businessHours'\n\t// An event ID (number or string)\n\t// An object with specific start/end dates or a recurring event (like what businessHours accepts)\n\tfunction constraintToEvents(constraintInput) {\n\n\t\tif (constraintInput === 'businessHours') {\n\t\t\treturn getBusinessHoursEvents();\n\t\t}\n\n\t\tif (typeof constraintInput === 'object') {\n\t\t\treturn expandEvent(buildEventFromInput(constraintInput));\n\t\t}\n\n\t\treturn clientEvents(constraintInput); // probably an ID\n\t}\n\n\n\t// Does the event's date range fully contain the given range?\n\t// start/end already assumed to have stripped zones :(\n\tfunction eventContainsRange(event, range) {\n\t\tvar eventStart = event.start.clone().stripZone();\n\t\tvar eventEnd = t.getEventEnd(event).stripZone();\n\n\t\treturn range.start >= eventStart && range.end <= eventEnd;\n\t}\n\n\n\t// Does the event's date range intersect with the given range?\n\t// start/end already assumed to have stripped zones :(\n\tfunction eventIntersectsRange(event, range) {\n\t\tvar eventStart = event.start.clone().stripZone();\n\t\tvar eventEnd = t.getEventEnd(event).stripZone();\n\n\t\treturn range.start < eventEnd && range.end > eventStart;\n\t}\n\n}\n\n\n// updates the \"backup\" properties, which are preserved in order to compute diffs later on.\nfunction backupEventDates(event) {\n\tevent._allDay = event.allDay;\n\tevent._start = event.start.clone();\n\tevent._end = event.end ? event.end.clone() : null;\n}\n\n    /* An abstract class for the \"basic\" views, as well as month view. Renders one or more rows of day cells.\n----------------------------------------------------------------------------------------------------------------------*/\n// It is a manager for a DayGrid subcomponent, which does most of the heavy lifting.\n// It is responsible for managing width/height.\n\nvar BasicView = fcViews.basic = View.extend({\n\n\tdayGrid: null, // the main subcomponent that does most of the heavy lifting\n\n\tdayNumbersVisible: false, // display day numbers on each day cell?\n\tweekNumbersVisible: false, // display week numbers along the side?\n\n\tweekNumberWidth: null, // width of all the week-number cells running down the side\n\n\theadRowEl: null, // the fake row element of the day-of-week header\n\n\n\tinitialize: function() {\n\t\tthis.dayGrid = new DayGrid(this);\n\t\tthis.coordMap = this.dayGrid.coordMap; // the view's date-to-cell mapping is identical to the subcomponent's\n\t},\n\n\n\t// Sets the display range and computes all necessary dates\n\tsetRange: function(range) {\n\t\tView.prototype.setRange.call(this, range); // call the super-method\n\n\t\tthis.dayGrid.breakOnWeeks = /year|month|week/.test(this.intervalUnit); // do before setRange\n\t\tthis.dayGrid.setRange(range);\n\t},\n\n\n\t// Compute the value to feed into setRange. Overrides superclass.\n\tcomputeRange: function(date) {\n\t\tvar range = View.prototype.computeRange.call(this, date); // get value from the super-method\n\n\t\t// year and month views should be aligned with weeks. this is already done for week\n\t\tif (/year|month/.test(range.intervalUnit)) {\n\t\t\trange.start.startOf('week');\n\t\t\trange.start = this.skipHiddenDays(range.start);\n\n\t\t\t// make end-of-week if not already\n\t\t\tif (range.end.weekday()) {\n\t\t\t\trange.end.add(1, 'week').startOf('week');\n\t\t\t\trange.end = this.skipHiddenDays(range.end, -1, true); // exclusively move backwards\n\t\t\t}\n\t\t}\n\n\t\treturn range;\n\t},\n\n\n\t// Renders the view into `this.el`, which should already be assigned\n\trender: function() {\n\n\t\tthis.dayNumbersVisible = this.dayGrid.rowCnt > 1; // TODO: make grid responsible\n\t\tthis.weekNumbersVisible = this.opt('weekNumbers');\n\t\tthis.dayGrid.numbersVisible = this.dayNumbersVisible || this.weekNumbersVisible;\n\n\t\tthis.el.addClass('fc-basic-view').html(this.renderHtml());\n\n\t\tthis.headRowEl = this.el.find('thead .fc-row');\n\n\t\tthis.scrollerEl = this.el.find('.fc-day-grid-container');\n\t\tthis.dayGrid.coordMap.containerEl = this.scrollerEl; // constrain clicks/etc to the dimensions of the scroller\n\n\t\tthis.dayGrid.el = this.el.find('.fc-day-grid');\n\t\tthis.dayGrid.render(this.hasRigidRows());\n\t},\n\n\n\t// Make subcomponents ready for cleanup\n\tdestroy: function() {\n\t\tthis.dayGrid.destroy();\n\t\tView.prototype.destroy.call(this); // call the super-method\n\t},\n\n\n\t// Builds the HTML skeleton for the view.\n\t// The day-grid component will render inside of a container defined by this HTML.\n\trenderHtml: function() {\n\t\treturn '' +\n\t\t\t'<table>' +\n\t\t\t\t'<thead>' +\n\t\t\t\t\t'<tr>' +\n\t\t\t\t\t\t'<td class=\"' + this.widgetHeaderClass + '\">' +\n\t\t\t\t\t\t\tthis.dayGrid.headHtml() + // render the day-of-week headers\n\t\t\t\t\t\t'</td>' +\n\t\t\t\t\t'</tr>' +\n\t\t\t\t'</thead>' +\n\t\t\t\t'<tbody>' +\n\t\t\t\t\t'<tr>' +\n\t\t\t\t\t\t'<td class=\"' + this.widgetContentClass + '\">' +\n\t\t\t\t\t\t\t'<div class=\"fc-day-grid-container\">' +\n\t\t\t\t\t\t\t\t'<div class=\"fc-day-grid\"/>' +\n\t\t\t\t\t\t\t'</div>' +\n\t\t\t\t\t\t'</td>' +\n\t\t\t\t\t'</tr>' +\n\t\t\t\t'</tbody>' +\n\t\t\t'</table>';\n\t},\n\n\n\t// Generates the HTML that will go before the day-of week header cells.\n\t// Queried by the DayGrid subcomponent when generating rows. Ordering depends on isRTL.\n\theadIntroHtml: function() {\n\t\tif (this.weekNumbersVisible) {\n\t\t\treturn '' +\n\t\t\t\t'<th class=\"fc-week-number ' + this.widgetHeaderClass + '\" ' + this.weekNumberStyleAttr() + '>' +\n\t\t\t\t\t'<span>' + // needed for matchCellWidths\n\t\t\t\t\t\thtmlEscape(this.opt('weekNumberTitle')) +\n\t\t\t\t\t'</span>' +\n\t\t\t\t'</th>';\n\t\t}\n\t},\n\n\n\t// Generates the HTML that will go before content-skeleton cells that display the day/week numbers.\n\t// Queried by the DayGrid subcomponent. Ordering depends on isRTL.\n\tnumberIntroHtml: function(row) {\n\t\tif (this.weekNumbersVisible) {\n\t\t\treturn '' +\n\t\t\t\t'<td class=\"fc-week-number\" ' + this.weekNumberStyleAttr() + '>' +\n\t\t\t\t\t'<span>' + // needed for matchCellWidths\n\t\t\t\t\t\tthis.calendar.calculateWeekNumber(this.dayGrid.getCell(row, 0).start) +\n\t\t\t\t\t'</span>' +\n\t\t\t\t'</td>';\n\t\t}\n\t},\n\n\n\t// Generates the HTML that goes before the day bg cells for each day-row.\n\t// Queried by the DayGrid subcomponent. Ordering depends on isRTL.\n\tdayIntroHtml: function() {\n\t\tif (this.weekNumbersVisible) {\n\t\t\treturn '<td class=\"fc-week-number ' + this.widgetContentClass + '\" ' +\n\t\t\t\tthis.weekNumberStyleAttr() + '></td>';\n\t\t}\n\t},\n\n\n\t// Generates the HTML that goes before every other type of row generated by DayGrid. Ordering depends on isRTL.\n\t// Affects helper-skeleton and highlight-skeleton rows.\n\tintroHtml: function() {\n\t\tif (this.weekNumbersVisible) {\n\t\t\treturn '<td class=\"fc-week-number\" ' + this.weekNumberStyleAttr() + '></td>';\n\t\t}\n\t},\n\n\n\t// Generates the HTML for the <td>s of the \"number\" row in the DayGrid's content skeleton.\n\t// The number row will only exist if either day numbers or week numbers are turned on.\n\tnumberCellHtml: function(cell) {\n\t\tvar date = cell.start;\n\t\tvar classes;\n\n\t\tif (!this.dayNumbersVisible) { // if there are week numbers but not day numbers\n\t\t\treturn '<td/>'; //  will create an empty space above events :(\n\t\t}\n\n\t\tclasses = this.dayGrid.getDayClasses(date);\n\t\tclasses.unshift('fc-day-number');\n\n\t\treturn '' +\n\t\t\t'<td class=\"' + classes.join(' ') + '\" data-date=\"' + date.format() + '\">' +\n\t\t\t\tdate.date() +\n\t\t\t'</td>';\n\t},\n\n\n\t// Generates an HTML attribute string for setting the width of the week number column, if it is known\n\tweekNumberStyleAttr: function() {\n\t\tif (this.weekNumberWidth !== null) {\n\t\t\treturn 'style=\"width:' + this.weekNumberWidth + 'px\"';\n\t\t}\n\t\treturn '';\n\t},\n\n\n\t// Determines whether each row should have a constant height\n\thasRigidRows: function() {\n\t\tvar eventLimit = this.opt('eventLimit');\n\t\treturn eventLimit && typeof eventLimit !== 'number';\n\t},\n\n\n\t/* Dimensions\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Refreshes the horizontal dimensions of the view\n\tupdateWidth: function() {\n\t\tif (this.weekNumbersVisible) {\n\t\t\t// Make sure all week number cells running down the side have the same width.\n\t\t\t// Record the width for cells created later.\n\t\t\tthis.weekNumberWidth = matchCellWidths(\n\t\t\t\tthis.el.find('.fc-week-number')\n\t\t\t);\n\t\t}\n\t},\n\n\n\t// Adjusts the vertical dimensions of the view to the specified values\n\tsetHeight: function(totalHeight, isAuto) {\n\t\tvar eventLimit = this.opt('eventLimit');\n\t\tvar scrollerHeight;\n\n\t\t// reset all heights to be natural\n\t\tunsetScroller(this.scrollerEl);\n\t\tuncompensateScroll(this.headRowEl);\n\n\t\tthis.dayGrid.destroySegPopover(); // kill the \"more\" popover if displayed\n\n\t\t// is the event limit a constant level number?\n\t\tif (eventLimit && typeof eventLimit === 'number') {\n\t\t\tthis.dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after\n\t\t}\n\n\t\tscrollerHeight = this.computeScrollerHeight(totalHeight);\n\t\tthis.setGridHeight(scrollerHeight, isAuto);\n\n\t\t// is the event limit dynamically calculated?\n\t\tif (eventLimit && typeof eventLimit !== 'number') {\n\t\t\tthis.dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set\n\t\t}\n\n\t\tif (!isAuto && setPotentialScroller(this.scrollerEl, scrollerHeight)) { // using scrollbars?\n\n\t\t\tcompensateScroll(this.headRowEl, getScrollbarWidths(this.scrollerEl));\n\n\t\t\t// doing the scrollbar compensation might have created text overflow which created more height. redo\n\t\t\tscrollerHeight = this.computeScrollerHeight(totalHeight);\n\t\t\tthis.scrollerEl.height(scrollerHeight);\n\n\t\t\tthis.restoreScroll();\n\t\t}\n\t},\n\n\n\t// Sets the height of just the DayGrid component in this view\n\tsetGridHeight: function(height, isAuto) {\n\t\tif (isAuto) {\n\t\t\tundistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding\n\t\t}\n\t\telse {\n\t\t\tdistributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows\n\t\t}\n\t},\n\n\n\t/* Events\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders the given events onto the view and populates the segments array\n\trenderEvents: function(events) {\n\t\tthis.dayGrid.renderEvents(events);\n\n\t\tthis.updateHeight(); // must compensate for events that overflow the row\n\t},\n\n\n\t// Retrieves all segment objects that are rendered in the view\n\tgetEventSegs: function() {\n\t\treturn this.dayGrid.getEventSegs();\n\t},\n\n\n\t// Unrenders all event elements and clears internal segment data\n\tdestroyEvents: function() {\n\t\tthis.recordScroll(); // removing events will reduce height and mess with the scroll, so record beforehand\n\t\tthis.dayGrid.destroyEvents();\n\n\t\t// we DON'T need to call updateHeight() because:\n\t\t// A) a renderEvents() call always happens after this, which will eventually call updateHeight()\n\t\t// B) in IE8, this causes a flash whenever events are rerendered\n\t},\n\n\n\t/* Dragging (for both events and external elements)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// A returned value of `true` signals that a mock \"helper\" event has been rendered.\n\trenderDrag: function(dropLocation, seg) {\n\t\treturn this.dayGrid.renderDrag(dropLocation, seg);\n\t},\n\n\n\tdestroyDrag: function() {\n\t\tthis.dayGrid.destroyDrag();\n\t},\n\n\n\t/* Selection\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of a selection\n\trenderSelection: function(range) {\n\t\tthis.dayGrid.renderSelection(range);\n\t},\n\n\n\t// Unrenders a visual indications of a selection\n\tdestroySelection: function() {\n\t\tthis.dayGrid.destroySelection();\n\t}\n\n});\n\n    /* A month view with day cells running in rows (one-per-week) and columns\n----------------------------------------------------------------------------------------------------------------------*/\n\nsetDefaults({\n\tfixedWeekCount: true\n});\n\nvar MonthView = fcViews.month = BasicView.extend({\n\n\t// Produces information about what range to display\n\tcomputeRange: function(date) {\n\t\tvar range = BasicView.prototype.computeRange.call(this, date); // get value from super-method\n\n\t\tif (this.isFixedWeeks()) {\n\t\t\t// ensure 6 weeks\n\t\t\trange.end.add(\n\t\t\t\t6 - range.end.diff(range.start, 'weeks'),\n\t\t\t\t'weeks'\n\t\t\t);\n\t\t}\n\n\t\treturn range;\n\t},\n\n\n\t// Overrides the default BasicView behavior to have special multi-week auto-height logic\n\tsetGridHeight: function(height, isAuto) {\n\n\t\tisAuto = isAuto || this.opt('weekMode') === 'variable'; // LEGACY: weekMode is deprecated\n\n\t\t// if auto, make the height of each row the height that it would be if there were 6 weeks\n\t\tif (isAuto) {\n\t\t\theight *= this.rowCnt / 6;\n\t\t}\n\n\t\tdistributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows\n\t},\n\n\n\tisFixedWeeks: function() {\n\t\tvar weekMode = this.opt('weekMode'); // LEGACY: weekMode is deprecated\n\t\tif (weekMode) {\n\t\t\treturn weekMode === 'fixed'; // if any other type of weekMode, assume NOT fixed\n\t\t}\n\n\t\treturn this.opt('fixedWeekCount');\n\t}\n\n});\n\nMonthView.duration = { months: 1 };\n\n    /* A week view with simple day cells running horizontally\n----------------------------------------------------------------------------------------------------------------------*/\n\nfcViews.basicWeek = {\n\ttype: 'basic',\n\tduration: { weeks: 1 }\n};\n    /* A view with a single simple day cell\n----------------------------------------------------------------------------------------------------------------------*/\n\nfcViews.basicDay = {\n\ttype: 'basic',\n\tduration: { days: 1 }\n};\n    /* An abstract class for all agenda-related views. Displays one more columns with time slots running vertically.\n----------------------------------------------------------------------------------------------------------------------*/\n// Is a manager for the TimeGrid subcomponent and possibly the DayGrid subcomponent (if allDaySlot is on).\n// Responsible for managing width/height.\n\nsetDefaults({\n\tallDaySlot: true,\n\tallDayText: 'all-day',\n\tscrollTime: '06:00:00',\n\tslotDuration: '00:30:00',\n\tminTime: '00:00:00',\n\tmaxTime: '24:00:00',\n\tslotEventOverlap: true\n});\n\nvar AGENDA_ALL_DAY_EVENT_LIMIT = 5;\n\nfcViews.agenda = View.extend({ // AgendaView\n\n\ttimeGrid: null, // the main time-grid subcomponent of this view\n\tdayGrid: null, // the \"all-day\" subcomponent. if all-day is turned off, this will be null\n\n\taxisWidth: null, // the width of the time axis running down the side\n\n\tnoScrollRowEls: null, // set of fake row elements that must compensate when scrollerEl has scrollbars\n\n\t// when the time-grid isn't tall enough to occupy the given height, we render an <hr> underneath\n\tbottomRuleEl: null,\n\tbottomRuleHeight: null,\n\n\n\tinitialize: function() {\n\t\tthis.timeGrid = new TimeGrid(this);\n\n\t\tif (this.opt('allDaySlot')) { // should we display the \"all-day\" area?\n\t\t\tthis.dayGrid = new DayGrid(this); // the all-day subcomponent of this view\n\n\t\t\t// the coordinate grid will be a combination of both subcomponents' grids\n\t\t\tthis.coordMap = new ComboCoordMap([\n\t\t\t\tthis.dayGrid.coordMap,\n\t\t\t\tthis.timeGrid.coordMap\n\t\t\t]);\n\t\t}\n\t\telse {\n\t\t\tthis.coordMap = this.timeGrid.coordMap;\n\t\t}\n\t},\n\n\n\t/* Rendering\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Sets the display range and computes all necessary dates\n\tsetRange: function(range) {\n\t\tView.prototype.setRange.call(this, range); // call the super-method\n\n\t\tthis.timeGrid.setRange(range);\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.setRange(range);\n\t\t}\n\t},\n\n\n\t// Renders the view into `this.el`, which has already been assigned\n\trender: function() {\n\n\t\tthis.el.addClass('fc-agenda-view').html(this.renderHtml());\n\n\t\t// the element that wraps the time-grid that will probably scroll\n\t\tthis.scrollerEl = this.el.find('.fc-time-grid-container');\n\t\tthis.timeGrid.coordMap.containerEl = this.scrollerEl; // don't accept clicks/etc outside of this\n\n\t\tthis.timeGrid.el = this.el.find('.fc-time-grid');\n\t\tthis.timeGrid.render();\n\n\t\t// the <hr> that sometimes displays under the time-grid\n\t\tthis.bottomRuleEl = $('<hr class=\"' + this.widgetHeaderClass + '\"/>')\n\t\t\t.appendTo(this.timeGrid.el); // inject it into the time-grid\n\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.el = this.el.find('.fc-day-grid');\n\t\t\tthis.dayGrid.render();\n\n\t\t\t// have the day-grid extend it's coordinate area over the <hr> dividing the two grids\n\t\t\tthis.dayGrid.bottomCoordPadding = this.dayGrid.el.next('hr').outerHeight();\n\t\t}\n\n\t\tthis.noScrollRowEls = this.el.find('.fc-row:not(.fc-scroller *)'); // fake rows not within the scroller\n\t},\n\n\n\t// Make subcomponents ready for cleanup\n\tdestroy: function() {\n\t\tthis.timeGrid.destroy();\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.destroy();\n\t\t}\n\t\tView.prototype.destroy.call(this); // call the super-method\n\t},\n\n\n\t// Builds the HTML skeleton for the view.\n\t// The day-grid and time-grid components will render inside containers defined by this HTML.\n\trenderHtml: function() {\n\t\treturn '' +\n\t\t\t'<table>' +\n\t\t\t\t'<thead>' +\n\t\t\t\t\t'<tr>' +\n\t\t\t\t\t\t'<td class=\"' + this.widgetHeaderClass + '\">' +\n\t\t\t\t\t\t\tthis.timeGrid.headHtml() + // render the day-of-week headers\n\t\t\t\t\t\t'</td>' +\n\t\t\t\t\t'</tr>' +\n\t\t\t\t'</thead>' +\n\t\t\t\t'<tbody>' +\n\t\t\t\t\t'<tr>' +\n\t\t\t\t\t\t'<td class=\"' + this.widgetContentClass + '\">' +\n\t\t\t\t\t\t\t(this.dayGrid ?\n\t\t\t\t\t\t\t\t'<div class=\"fc-day-grid\"/>' +\n\t\t\t\t\t\t\t\t'<hr class=\"' + this.widgetHeaderClass + '\"/>' :\n\t\t\t\t\t\t\t\t''\n\t\t\t\t\t\t\t\t) +\n\t\t\t\t\t\t\t'<div class=\"fc-time-grid-container\">' +\n\t\t\t\t\t\t\t\t'<div class=\"fc-time-grid\"/>' +\n\t\t\t\t\t\t\t'</div>' +\n\t\t\t\t\t\t'</td>' +\n\t\t\t\t\t'</tr>' +\n\t\t\t\t'</tbody>' +\n\t\t\t'</table>';\n\t},\n\n\n\t// Generates the HTML that will go before the day-of week header cells.\n\t// Queried by the TimeGrid subcomponent when generating rows. Ordering depends on isRTL.\n\theadIntroHtml: function() {\n\t\tvar date;\n\t\tvar weekNumber;\n\t\tvar weekTitle;\n\t\tvar weekText;\n\n\t\tif (this.opt('weekNumbers')) {\n\t\t\tdate = this.timeGrid.getCell(0).start;\n\t\t\tweekNumber = this.calendar.calculateWeekNumber(date);\n\t\t\tweekTitle = this.opt('weekNumberTitle');\n\n\t\t\tif (this.opt('isRTL')) {\n\t\t\t\tweekText = weekNumber + weekTitle;\n\t\t\t}\n\t\t\telse {\n\t\t\t\tweekText = weekTitle + weekNumber;\n\t\t\t}\n\n\t\t\treturn '' +\n\t\t\t\t'<th class=\"fc-axis fc-week-number ' + this.widgetHeaderClass + '\" ' + this.axisStyleAttr() + '>' +\n\t\t\t\t\t'<span>' + // needed for matchCellWidths\n\t\t\t\t\t\thtmlEscape(weekText) +\n\t\t\t\t\t'</span>' +\n\t\t\t\t'</th>';\n\t\t}\n\t\telse {\n\t\t\treturn '<th class=\"fc-axis ' + this.widgetHeaderClass + '\" ' + this.axisStyleAttr() + '></th>';\n\t\t}\n\t},\n\n\n\t// Generates the HTML that goes before the all-day cells.\n\t// Queried by the DayGrid subcomponent when generating rows. Ordering depends on isRTL.\n\tdayIntroHtml: function() {\n\t\treturn '' +\n\t\t\t'<td class=\"fc-axis ' + this.widgetContentClass + '\" ' + this.axisStyleAttr() + '>' +\n\t\t\t\t'<span>' + // needed for matchCellWidths\n\t\t\t\t\t(this.opt('allDayHtml') || htmlEscape(this.opt('allDayText'))) +\n\t\t\t\t'</span>' +\n\t\t\t'</td>';\n\t},\n\n\n\t// Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column.\n\tslotBgIntroHtml: function() {\n\t\treturn '<td class=\"fc-axis ' + this.widgetContentClass + '\" ' + this.axisStyleAttr() + '></td>';\n\t},\n\n\n\t// Generates the HTML that goes before all other types of cells.\n\t// Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.\n\t// Queried by the TimeGrid and DayGrid subcomponents when generating rows. Ordering depends on isRTL.\n\tintroHtml: function() {\n\t\treturn '<td class=\"fc-axis\" ' + this.axisStyleAttr() + '></td>';\n\t},\n\n\n\t// Generates an HTML attribute string for setting the width of the axis, if it is known\n\taxisStyleAttr: function() {\n\t\tif (this.axisWidth !== null) {\n\t\t\t return 'style=\"width:' + this.axisWidth + 'px\"';\n\t\t}\n\t\treturn '';\n\t},\n\n\n\t/* Dimensions\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\tupdateSize: function(isResize) {\n\t\tif (isResize) {\n\t\t\tthis.timeGrid.resize();\n\t\t}\n\t\tView.prototype.updateSize.call(this, isResize);\n\t},\n\n\n\t// Refreshes the horizontal dimensions of the view\n\tupdateWidth: function() {\n\t\t// make all axis cells line up, and record the width so newly created axis cells will have it\n\t\tthis.axisWidth = matchCellWidths(this.el.find('.fc-axis'));\n\t},\n\n\n\t// Adjusts the vertical dimensions of the view to the specified values\n\tsetHeight: function(totalHeight, isAuto) {\n\t\tvar eventLimit;\n\t\tvar scrollerHeight;\n\n\t\tif (this.bottomRuleHeight === null) {\n\t\t\t// calculate the height of the rule the very first time\n\t\t\tthis.bottomRuleHeight = this.bottomRuleEl.outerHeight();\n\t\t}\n\t\tthis.bottomRuleEl.hide(); // .show() will be called later if this <hr> is necessary\n\n\t\t// reset all dimensions back to the original state\n\t\tthis.scrollerEl.css('overflow', '');\n\t\tunsetScroller(this.scrollerEl);\n\t\tuncompensateScroll(this.noScrollRowEls);\n\n\t\t// limit number of events in the all-day area\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.destroySegPopover(); // kill the \"more\" popover if displayed\n\n\t\t\teventLimit = this.opt('eventLimit');\n\t\t\tif (eventLimit && typeof eventLimit !== 'number') {\n\t\t\t\teventLimit = AGENDA_ALL_DAY_EVENT_LIMIT; // make sure \"auto\" goes to a real number\n\t\t\t}\n\t\t\tif (eventLimit) {\n\t\t\t\tthis.dayGrid.limitRows(eventLimit);\n\t\t\t}\n\t\t}\n\n\t\tif (!isAuto) { // should we force dimensions of the scroll container, or let the contents be natural height?\n\n\t\t\tscrollerHeight = this.computeScrollerHeight(totalHeight);\n\t\t\tif (setPotentialScroller(this.scrollerEl, scrollerHeight)) { // using scrollbars?\n\n\t\t\t\t// make the all-day and header rows lines up\n\t\t\t\tcompensateScroll(this.noScrollRowEls, getScrollbarWidths(this.scrollerEl));\n\n\t\t\t\t// the scrollbar compensation might have changed text flow, which might affect height, so recalculate\n\t\t\t\t// and reapply the desired height to the scroller.\n\t\t\t\tscrollerHeight = this.computeScrollerHeight(totalHeight);\n\t\t\t\tthis.scrollerEl.height(scrollerHeight);\n\n\t\t\t\tthis.restoreScroll();\n\t\t\t}\n\t\t\telse { // no scrollbars\n\t\t\t\t// still, force a height and display the bottom rule (marks the end of day)\n\t\t\t\tthis.scrollerEl.height(scrollerHeight).css('overflow', 'hidden'); // in case <hr> goes outside\n\t\t\t\tthis.bottomRuleEl.show();\n\t\t\t}\n\t\t}\n\t},\n\n\n\t// Sets the scroll value of the scroller to the initial pre-configured state prior to allowing the user to change it\n\tinitializeScroll: function() {\n\t\tvar _this = this;\n\t\tvar scrollTime = moment.duration(this.opt('scrollTime'));\n\t\tvar top = this.timeGrid.computeTimeTop(scrollTime);\n\n\t\t// zoom can give weird floating-point values. rather scroll a little bit further\n\t\ttop = Math.ceil(top);\n\n\t\tif (top) {\n\t\t\ttop++; // to overcome top border that slots beyond the first have. looks better\n\t\t}\n\n\t\tfunction scroll() {\n\t\t\t_this.scrollerEl.scrollTop(top);\n\t\t}\n\n\t\tscroll();\n\t\tsetTimeout(scroll, 0); // overrides any previous scroll state made by the browser\n\t},\n\n\n\t/* Events\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders events onto the view and populates the View's segment array\n\trenderEvents: function(events) {\n\t\tvar dayEvents = [];\n\t\tvar timedEvents = [];\n\t\tvar daySegs = [];\n\t\tvar timedSegs;\n\t\tvar i;\n\n\t\t// separate the events into all-day and timed\n\t\tfor (i = 0; i < events.length; i++) {\n\t\t\tif (events[i].allDay) {\n\t\t\t\tdayEvents.push(events[i]);\n\t\t\t}\n\t\t\telse {\n\t\t\t\ttimedEvents.push(events[i]);\n\t\t\t}\n\t\t}\n\n\t\t// render the events in the subcomponents\n\t\ttimedSegs = this.timeGrid.renderEvents(timedEvents);\n\t\tif (this.dayGrid) {\n\t\t\tdaySegs = this.dayGrid.renderEvents(dayEvents);\n\t\t}\n\n\t\t// the all-day area is flexible and might have a lot of events, so shift the height\n\t\tthis.updateHeight();\n\t},\n\n\n\t// Retrieves all segment objects that are rendered in the view\n\tgetEventSegs: function() {\n\t\treturn this.timeGrid.getEventSegs().concat(\n\t\t\tthis.dayGrid ? this.dayGrid.getEventSegs() : []\n\t\t);\n\t},\n\n\n\t// Unrenders all event elements and clears internal segment data\n\tdestroyEvents: function() {\n\n\t\t// if destroyEvents is being called as part of an event rerender, renderEvents will be called shortly\n\t\t// after, so remember what the scroll value was so we can restore it.\n\t\tthis.recordScroll();\n\n\t\t// destroy the events in the subcomponents\n\t\tthis.timeGrid.destroyEvents();\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.destroyEvents();\n\t\t}\n\n\t\t// we DON'T need to call updateHeight() because:\n\t\t// A) a renderEvents() call always happens after this, which will eventually call updateHeight()\n\t\t// B) in IE8, this causes a flash whenever events are rerendered\n\t},\n\n\n\t/* Dragging (for events and external elements)\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// A returned value of `true` signals that a mock \"helper\" event has been rendered.\n\trenderDrag: function(dropLocation, seg) {\n\t\tif (dropLocation.start.hasTime()) {\n\t\t\treturn this.timeGrid.renderDrag(dropLocation, seg);\n\t\t}\n\t\telse if (this.dayGrid) {\n\t\t\treturn this.dayGrid.renderDrag(dropLocation, seg);\n\t\t}\n\t},\n\n\n\tdestroyDrag: function() {\n\t\tthis.timeGrid.destroyDrag();\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.destroyDrag();\n\t\t}\n\t},\n\n\n\t/* Selection\n\t------------------------------------------------------------------------------------------------------------------*/\n\n\n\t// Renders a visual indication of a selection\n\trenderSelection: function(range) {\n\t\tif (range.start.hasTime() || range.end.hasTime()) {\n\t\t\tthis.timeGrid.renderSelection(range);\n\t\t}\n\t\telse if (this.dayGrid) {\n\t\t\tthis.dayGrid.renderSelection(range);\n\t\t}\n\t},\n\n\n\t// Unrenders a visual indications of a selection\n\tdestroySelection: function() {\n\t\tthis.timeGrid.destroySelection();\n\t\tif (this.dayGrid) {\n\t\t\tthis.dayGrid.destroySelection();\n\t\t}\n\t}\n\n});\n\n    /* A week view with an all-day cell area at the top, and a time grid below\n----------------------------------------------------------------------------------------------------------------------*/\n\nfcViews.agendaWeek = {\n\ttype: 'agenda',\n\tduration: { weeks: 1 }\n};\n    /* A day view with an all-day cell area at the top, and a time grid below\n----------------------------------------------------------------------------------------------------------------------*/\n\nfcViews.agendaDay = {\n\ttype: 'agenda',\n\tduration: { days: 1 }\n};\n});"
  },
  {
    "path": "public/static/plugins/fullcalendar/fullcalendar.print.css",
    "content": "/*!\n * FullCalendar v2.2.5 Print Stylesheet\n * Docs & License: http://arshaw.com/fullcalendar/\n * (c) 2013 Adam Shaw\n */\n\n/*\n * Include this stylesheet on your page to get a more printer-friendly calendar.\n * When including this stylesheet, use the media='print' attribute of the <link> tag.\n * Make sure to include this stylesheet IN ADDITION to the regular fullcalendar.css.\n */\n\n.fc {\n\tmax-width: 100% !important;\n}\n\n\n/* Global Event Restyling\n--------------------------------------------------------------------------------------------------*/\n\n.fc-event {\n\tbackground: #fff !important;\n\tcolor: #000 !important;\n\tpage-break-inside: avoid;\n}\n\n.fc-event .fc-resizer {\n\tdisplay: none;\n}\n\n\n/* Table & Day-Row Restyling\n--------------------------------------------------------------------------------------------------*/\n\nth,\ntd,\nhr,\nthead,\ntbody,\n.fc-row {\n\tborder-color: #ccc !important;\n\tbackground: #fff !important;\n}\n\n/* kill the overlaid, absolutely-positioned common components */\n.fc-bg,\n.fc-bgevent-skeleton,\n.fc-highlight-skeleton,\n.fc-helper-skeleton {\n\tdisplay: none;\n}\n\n/* don't force a min-height on rows (for DayGrid) */\n.fc tbody .fc-row {\n\theight: auto !important; /* undo height that JS set in distributeHeight */\n\tmin-height: 0 !important; /* undo the min-height from each view's specific stylesheet */\n}\n\n.fc tbody .fc-row .fc-content-skeleton {\n\tposition: static; /* undo .fc-rigid */\n\tpadding-bottom: 0 !important; /* use a more border-friendly method for this... */\n}\n\n.fc tbody .fc-row .fc-content-skeleton tbody tr:last-child td { /* only works in newer browsers */\n\tpadding-bottom: 1em; /* ...gives space within the skeleton. also ensures min height in a way */\n}\n\n.fc tbody .fc-row .fc-content-skeleton table {\n\t/* provides a min-height for the row, but only effective for IE, which exaggerates this value,\n\t   making it look more like 3em. for other browers, it will already be this tall */\n\theight: 1em;\n}\n\n\n/* Undo month-view event limiting. Display all events and hide the \"more\" links\n--------------------------------------------------------------------------------------------------*/\n\n.fc-more-cell,\n.fc-more {\n\tdisplay: none !important;\n}\n\n.fc tr.fc-limited {\n\tdisplay: table-row !important;\n}\n\n.fc td.fc-limited {\n\tdisplay: table-cell !important;\n}\n\n.fc-popover {\n\tdisplay: none; /* never display the \"more..\" popover in print mode */\n}\n\n\n/* TimeGrid Restyling\n--------------------------------------------------------------------------------------------------*/\n\n/* undo the min-height 100% trick used to fill the container's height */\n.fc-time-grid {\n\tmin-height: 0 !important;\n}\n\n/* don't display the side axis at all (\"all-day\" and time cells) */\n.fc-agenda-view .fc-axis {\n\tdisplay: none;\n}\n\n/* don't display the horizontal lines */\n.fc-slats,\n.fc-time-grid hr { /* this hr is used when height is underused and needs to be filled */\n\tdisplay: none !important; /* important overrides inline declaration */\n}\n\n/* let the container that holds the events be naturally positioned and create real height */\n.fc-time-grid .fc-content-skeleton {\n\tposition: static;\n}\n\n/* in case there are no events, we still want some height */\n.fc-time-grid .fc-content-skeleton table {\n\theight: 4em;\n}\n\n/* kill the horizontal spacing made by the event container. event margins will be done below */\n.fc-time-grid .fc-event-container {\n\tmargin: 0 !important;\n}\n\n\n/* TimeGrid *Event* Restyling\n--------------------------------------------------------------------------------------------------*/\n\n/* naturally position events, vertically stacking them */\n.fc-time-grid .fc-event {\n\tposition: static !important;\n\tmargin: 3px 2px !important;\n}\n\n/* for events that continue to a future day, give the bottom border back */\n.fc-time-grid .fc-event.fc-not-end {\n\tborder-bottom-width: 1px !important;\n}\n\n/* indicate the event continues via \"...\" text */\n.fc-time-grid .fc-event.fc-not-end:after {\n\tcontent: \"...\";\n}\n\n/* for events that are continuations from previous days, give the top border back */\n.fc-time-grid .fc-event.fc-not-start {\n\tborder-top-width: 1px !important;\n}\n\n/* indicate the event is a continuation via \"...\" text */\n.fc-time-grid .fc-event.fc-not-start:before {\n\tcontent: \"...\";\n}\n\n/* time */\n\n/* undo a previous declaration and let the time text span to a second line */\n.fc-time-grid .fc-event .fc-time {\n\twhite-space: normal !important;\n}\n\n/* hide the the time that is normally displayed... */\n.fc-time-grid .fc-event .fc-time span {\n\tdisplay: none;\n}\n\n/* ...replace it with a more verbose version (includes AM/PM) stored in an html attribute */\n.fc-time-grid .fc-event .fc-time:after {\n\tcontent: attr(data-full);\n}\n\n\n/* Vertical Scroller & Containers\n--------------------------------------------------------------------------------------------------*/\n\n/* kill the scrollbars and allow natural height */\n.fc-scroller,\n.fc-day-grid-container,    /* these divs might be assigned height, which we need to cleared */\n.fc-time-grid-container {  /* */\n\toverflow: visible !important;\n\theight: auto !important;\n}\n\n/* kill the horizontal border/padding used to compensate for scrollbars */\n.fc-row {\n\tborder: 0 !important;\n\tmargin: 0 !important;\n}\n\n\n/* Button Controls\n--------------------------------------------------------------------------------------------------*/\n\n.fc-button-group,\n.fc button {\n\tdisplay: none; /* don't display any button-related controls */\n}\n"
  },
  {
    "path": "public/static/plugins/iCheck/all.css",
    "content": "/* iCheck plugin skins\n----------------------------------- */\n@import url(\"minimal/_all.css\");\n/*\n@import url(\"minimal/minimal.css\");\n@import url(\"minimal/red.css\");\n@import url(\"minimal/green.css\");\n@import url(\"minimal/blue.css\");\n@import url(\"minimal/aero.css\");\n@import url(\"minimal/grey.css\");\n@import url(\"minimal/orange.css\");\n@import url(\"minimal/yellow.css\");\n@import url(\"minimal/pink.css\");\n@import url(\"minimal/purple.css\");\n*/\n\n@import url(\"square/_all.css\");\n/*\n@import url(\"square/square.css\");\n@import url(\"square/red.css\");\n@import url(\"square/green.css\");\n@import url(\"square/blue.css\");\n@import url(\"square/aero.css\");\n@import url(\"square/grey.css\");\n@import url(\"square/orange.css\");\n@import url(\"square/yellow.css\");\n@import url(\"square/pink.css\");\n@import url(\"square/purple.css\");\n*/\n\n@import url(\"flat/_all.css\");\n/*\n@import url(\"flat/flat.css\");\n@import url(\"flat/red.css\");\n@import url(\"flat/green.css\");\n@import url(\"flat/blue.css\");\n@import url(\"flat/aero.css\");\n@import url(\"flat/grey.css\");\n@import url(\"flat/orange.css\");\n@import url(\"flat/yellow.css\");\n@import url(\"flat/pink.css\");\n@import url(\"flat/purple.css\");\n*/\n\n@import url(\"line/_all.css\");\n/*\n@import url(\"line/line.css\");\n@import url(\"line/red.css\");\n@import url(\"line/green.css\");\n@import url(\"line/blue.css\");\n@import url(\"line/aero.css\");\n@import url(\"line/grey.css\");\n@import url(\"line/orange.css\");\n@import url(\"line/yellow.css\");\n@import url(\"line/pink.css\");\n@import url(\"line/purple.css\");\n*/\n\n@import url(\"polaris/polaris.css\");\n\n@import url(\"futurico/futurico.css\");"
  },
  {
    "path": "public/static/plugins/iCheck/flat/_all.css",
    "content": "/* iCheck plugin Flat skin\n----------------------------------- */\n.icheckbox_flat,\n.iradio_flat {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(flat.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat {\n    background-position: 0 0;\n}\n    .icheckbox_flat.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat {\n    background-position: -88px 0;\n}\n    .iradio_flat.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat,\n    .iradio_flat {\n        background-image: url(flat@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}\n\n/* red */\n.icheckbox_flat-red,\n.iradio_flat-red {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(red.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-red {\n    background-position: 0 0;\n}\n    .icheckbox_flat-red.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-red.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-red.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-red {\n    background-position: -88px 0;\n}\n    .iradio_flat-red.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-red.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-red.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-red,\n    .iradio_flat-red {\n        background-image: url(red@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}\n\n/* green */\n.icheckbox_flat-green,\n.iradio_flat-green {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(green.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-green {\n    background-position: 0 0;\n}\n    .icheckbox_flat-green.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-green.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-green.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-green {\n    background-position: -88px 0;\n}\n    .iradio_flat-green.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-green.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-green.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-green,\n    .iradio_flat-green {\n        background-image: url(green@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}\n\n/* blue */\n.icheckbox_flat-blue,\n.iradio_flat-blue {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(blue.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-blue {\n    background-position: 0 0;\n}\n    .icheckbox_flat-blue.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-blue.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-blue.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-blue {\n    background-position: -88px 0;\n}\n    .iradio_flat-blue.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-blue.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-blue.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-blue,\n    .iradio_flat-blue {\n        background-image: url(blue@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}\n\n/* aero */\n.icheckbox_flat-aero,\n.iradio_flat-aero {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(aero.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-aero {\n    background-position: 0 0;\n}\n    .icheckbox_flat-aero.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-aero.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-aero.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-aero {\n    background-position: -88px 0;\n}\n    .iradio_flat-aero.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-aero.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-aero.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-aero,\n    .iradio_flat-aero {\n        background-image: url(aero@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}\n\n/* grey */\n.icheckbox_flat-grey,\n.iradio_flat-grey {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(grey.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-grey {\n    background-position: 0 0;\n}\n    .icheckbox_flat-grey.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-grey.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-grey.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-grey {\n    background-position: -88px 0;\n}\n    .iradio_flat-grey.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-grey.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-grey.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-grey,\n    .iradio_flat-grey {\n        background-image: url(grey@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}\n\n/* orange */\n.icheckbox_flat-orange,\n.iradio_flat-orange {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(orange.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-orange {\n    background-position: 0 0;\n}\n    .icheckbox_flat-orange.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-orange.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-orange.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-orange {\n    background-position: -88px 0;\n}\n    .iradio_flat-orange.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-orange.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-orange.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-orange,\n    .iradio_flat-orange {\n        background-image: url(orange@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}\n\n/* yellow */\n.icheckbox_flat-yellow,\n.iradio_flat-yellow {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(yellow.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-yellow {\n    background-position: 0 0;\n}\n    .icheckbox_flat-yellow.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-yellow.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-yellow.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-yellow {\n    background-position: -88px 0;\n}\n    .iradio_flat-yellow.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-yellow.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-yellow.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-yellow,\n    .iradio_flat-yellow {\n        background-image: url(yellow@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}\n\n/* pink */\n.icheckbox_flat-pink,\n.iradio_flat-pink {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(pink.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-pink {\n    background-position: 0 0;\n}\n    .icheckbox_flat-pink.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-pink.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-pink.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-pink {\n    background-position: -88px 0;\n}\n    .iradio_flat-pink.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-pink.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-pink.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-pink,\n    .iradio_flat-pink {\n        background-image: url(pink@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}\n\n/* purple */\n.icheckbox_flat-purple,\n.iradio_flat-purple {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(purple.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-purple {\n    background-position: 0 0;\n}\n    .icheckbox_flat-purple.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-purple.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-purple.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-purple {\n    background-position: -88px 0;\n}\n    .iradio_flat-purple.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-purple.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-purple.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-purple,\n    .iradio_flat-purple {\n        background-image: url(purple@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/flat/aero.css",
    "content": "/* iCheck plugin Flat skin, aero\n----------------------------------- */\n.icheckbox_flat-aero,\n.iradio_flat-aero {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(aero.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-aero {\n    background-position: 0 0;\n}\n    .icheckbox_flat-aero.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-aero.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-aero.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-aero {\n    background-position: -88px 0;\n}\n    .iradio_flat-aero.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-aero.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-aero.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-aero,\n    .iradio_flat-aero {\n        background-image: url(aero@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/flat/blue.css",
    "content": "/* iCheck plugin Flat skin, blue\n----------------------------------- */\n.icheckbox_flat-blue,\n.iradio_flat-blue {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(blue.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-blue {\n    background-position: 0 0;\n}\n    .icheckbox_flat-blue.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-blue.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-blue.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-blue {\n    background-position: -88px 0;\n}\n    .iradio_flat-blue.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-blue.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-blue.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-blue,\n    .iradio_flat-blue {\n        background-image: url(blue@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/flat/flat.css",
    "content": "/* iCheck plugin flat skin, black\n----------------------------------- */\n.icheckbox_flat,\n.iradio_flat {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(flat.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat {\n    background-position: 0 0;\n}\n    .icheckbox_flat.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat {\n    background-position: -88px 0;\n}\n    .iradio_flat.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat,\n    .iradio_flat {\n        background-image: url(flat@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/flat/green.css",
    "content": "/* iCheck plugin Flat skin, green\n----------------------------------- */\n.icheckbox_flat-green,\n.iradio_flat-green {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(green.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-green {\n    background-position: 0 0;\n}\n    .icheckbox_flat-green.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-green.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-green.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-green {\n    background-position: -88px 0;\n}\n    .iradio_flat-green.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-green.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-green.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-green,\n    .iradio_flat-green {\n        background-image: url(green@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/flat/grey.css",
    "content": "/* iCheck plugin Flat skin, grey\n----------------------------------- */\n.icheckbox_flat-grey,\n.iradio_flat-grey {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(grey.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-grey {\n    background-position: 0 0;\n}\n    .icheckbox_flat-grey.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-grey.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-grey.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-grey {\n    background-position: -88px 0;\n}\n    .iradio_flat-grey.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-grey.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-grey.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-grey,\n    .iradio_flat-grey {\n        background-image: url(grey@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/flat/orange.css",
    "content": "/* iCheck plugin Flat skin, orange\n----------------------------------- */\n.icheckbox_flat-orange,\n.iradio_flat-orange {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(orange.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-orange {\n    background-position: 0 0;\n}\n    .icheckbox_flat-orange.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-orange.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-orange.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-orange {\n    background-position: -88px 0;\n}\n    .iradio_flat-orange.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-orange.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-orange.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-orange,\n    .iradio_flat-orange {\n        background-image: url(orange@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/flat/pink.css",
    "content": "/* iCheck plugin Flat skin, pink\n----------------------------------- */\n.icheckbox_flat-pink,\n.iradio_flat-pink {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(pink.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-pink {\n    background-position: 0 0;\n}\n    .icheckbox_flat-pink.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-pink.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-pink.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-pink {\n    background-position: -88px 0;\n}\n    .iradio_flat-pink.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-pink.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-pink.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-pink,\n    .iradio_flat-pink {\n        background-image: url(pink@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/flat/purple.css",
    "content": "/* iCheck plugin Flat skin, purple\n----------------------------------- */\n.icheckbox_flat-purple,\n.iradio_flat-purple {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(purple.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-purple {\n    background-position: 0 0;\n}\n    .icheckbox_flat-purple.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-purple.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-purple.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-purple {\n    background-position: -88px 0;\n}\n    .iradio_flat-purple.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-purple.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-purple.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-purple,\n    .iradio_flat-purple {\n        background-image: url(purple@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/flat/red.css",
    "content": "/* iCheck plugin Flat skin, red\n----------------------------------- */\n.icheckbox_flat-red,\n.iradio_flat-red {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(red.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-red {\n    background-position: 0 0;\n}\n    .icheckbox_flat-red.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-red.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-red.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-red {\n    background-position: -88px 0;\n}\n    .iradio_flat-red.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-red.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-red.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-red,\n    .iradio_flat-red {\n        background-image: url(red@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/flat/yellow.css",
    "content": "/* iCheck plugin Flat skin, yellow\n----------------------------------- */\n.icheckbox_flat-yellow,\n.iradio_flat-yellow {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 20px;\n    height: 20px;\n    background: url(yellow.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_flat-yellow {\n    background-position: 0 0;\n}\n    .icheckbox_flat-yellow.checked {\n        background-position: -22px 0;\n    }\n    .icheckbox_flat-yellow.disabled {\n        background-position: -44px 0;\n        cursor: default;\n    }\n    .icheckbox_flat-yellow.checked.disabled {\n        background-position: -66px 0;\n    }\n\n.iradio_flat-yellow {\n    background-position: -88px 0;\n}\n    .iradio_flat-yellow.checked {\n        background-position: -110px 0;\n    }\n    .iradio_flat-yellow.disabled {\n        background-position: -132px 0;\n        cursor: default;\n    }\n    .iradio_flat-yellow.checked.disabled {\n        background-position: -154px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_flat-yellow,\n    .iradio_flat-yellow {\n        background-image: url(yellow@2x.png);\n        -webkit-background-size: 176px 22px;\n        background-size: 176px 22px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/futurico/futurico.css",
    "content": "/* iCheck plugin Futurico skin\n----------------------------------- */\n.icheckbox_futurico,\n.iradio_futurico {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 16px;\n    height: 17px;\n    background: url(futurico.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_futurico {\n    background-position: 0 0;\n}\n    .icheckbox_futurico.checked {\n        background-position: -18px 0;\n    }\n    .icheckbox_futurico.disabled {\n        background-position: -36px 0;\n        cursor: default;\n    }\n    .icheckbox_futurico.checked.disabled {\n        background-position: -54px 0;\n    }\n\n.iradio_futurico {\n    background-position: -72px 0;\n}\n    .iradio_futurico.checked {\n        background-position: -90px 0;\n    }\n    .iradio_futurico.disabled {\n        background-position: -108px 0;\n        cursor: default;\n    }\n    .iradio_futurico.checked.disabled {\n        background-position: -126px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_futurico,\n    .iradio_futurico {\n        background-image: url(futurico@2x.png);\n        -webkit-background-size: 144px 19px;\n        background-size: 144px 19px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/icheck.js",
    "content": "/*!\n * iCheck v1.0.1, http://git.io/arlzeA\n * =================================\n * Powerful jQuery and Zepto plugin for checkboxes and radio buttons customization\n *\n * (c) 2013 Damir Sultanov, http://fronteed.com\n * MIT Licensed\n */\n\n(function($) {\n\n  // Cached vars\n  var _iCheck = 'iCheck',\n    _iCheckHelper = _iCheck + '-helper',\n    _checkbox = 'checkbox',\n    _radio = 'radio',\n    _checked = 'checked',\n    _unchecked = 'un' + _checked,\n    _disabled = 'disabled',\n    _determinate = 'determinate',\n    _indeterminate = 'in' + _determinate,\n    _update = 'update',\n    _type = 'type',\n    _click = 'click',\n    _touch = 'touchbegin.i touchend.i',\n    _add = 'addClass',\n    _remove = 'removeClass',\n    _callback = 'trigger',\n    _label = 'label',\n    _cursor = 'cursor',\n    _mobile = /ipad|iphone|ipod|android|blackberry|windows phone|opera mini|silk/i.test(navigator.userAgent);\n\n  // Plugin init\n  $.fn[_iCheck] = function(options, fire) {\n\n    // Walker\n    var handle = 'input[type=\"' + _checkbox + '\"], input[type=\"' + _radio + '\"]',\n      stack = $(),\n      walker = function(object) {\n        object.each(function() {\n          var self = $(this);\n\n          if (self.is(handle)) {\n            stack = stack.add(self);\n          } else {\n            stack = stack.add(self.find(handle));\n          }\n        });\n      };\n\n    // Check if we should operate with some method\n    if (/^(check|uncheck|toggle|indeterminate|determinate|disable|enable|update|destroy)$/i.test(options)) {\n\n      // Normalize method's name\n      options = options.toLowerCase();\n\n      // Find checkboxes and radio buttons\n      walker(this);\n\n      return stack.each(function() {\n        var self = $(this);\n\n        if (options == 'destroy') {\n          tidy(self, 'ifDestroyed');\n        } else {\n          operate(self, true, options);\n        }\n          // Fire method's callback\n        if ($.isFunction(fire)) {\n          fire();\n        }\n      });\n\n    // Customization\n    } else if (typeof options == 'object' || !options) {\n\n      // Check if any options were passed\n      var settings = $.extend({\n          checkedClass: _checked,\n          disabledClass: _disabled,\n          indeterminateClass: _indeterminate,\n          labelHover: true,\n          aria: false\n        }, options),\n\n        selector = settings.handle,\n        hoverClass = settings.hoverClass || 'hover',\n        focusClass = settings.focusClass || 'focus',\n        activeClass = settings.activeClass || 'active',\n        labelHover = !!settings.labelHover,\n        labelHoverClass = settings.labelHoverClass || 'hover',\n\n        // Setup clickable area\n        area = ('' + settings.increaseArea).replace('%', '') | 0;\n\n      // Selector limit\n      if (selector == _checkbox || selector == _radio) {\n        handle = 'input[type=\"' + selector + '\"]';\n      }\n        // Clickable area limit\n      if (area < -50) {\n        area = -50;\n      }\n        // Walk around the selector\n      walker(this);\n\n      return stack.each(function() {\n        var self = $(this);\n\n        // If already customized\n        tidy(self);\n\n        var node = this,\n          id = node.id,\n\n          // Layer styles\n          offset = -area + '%',\n          size = 100 + (area * 2) + '%',\n          layer = {\n            position: 'absolute',\n            top: offset,\n            left: offset,\n            display: 'block',\n            width: size,\n            height: size,\n            margin: 0,\n            padding: 0,\n            background: '#fff',\n            border: 0,\n            opacity: 0\n          },\n\n          // Choose how to hide input\n          hide = _mobile ? {\n            position: 'absolute',\n            visibility: 'hidden'\n          } : area ? layer : {\n            position: 'absolute',\n            opacity: 0\n          },\n\n          // Get proper class\n          className = node[_type] == _checkbox ? settings.checkboxClass || 'i' + _checkbox : settings.radioClass || 'i' + _radio,\n\n          // Find assigned labels\n          label = $(_label + '[for=\"' + id + '\"]').add(self.closest(_label)),\n\n          // Check ARIA option\n          aria = !!settings.aria,\n\n          // Set ARIA placeholder\n          ariaID = _iCheck + '-' + Math.random().toString(36).replace('0.', ''),\n\n          // Parent & helper\n          parent = '<div class=\"' + className + '\" ' + (aria ? 'role=\"' + node[_type] + '\" ' : ''),\n          helper;\n\n        // Set ARIA \"labelledby\"\n        if (label.length && aria) {\n          label.each(function() {\n            parent += 'aria-labelledby=\"';\n\n            if (this.id) {\n              parent += this.id;\n            } else {\n              this.id = ariaID;\n              parent += ariaID;\n            }\n\n            parent += '\"';\n          });\n        }\n          // Wrap input\n        parent = self.wrap(parent + '/>')[_callback]('ifCreated').parent().append(settings.insert);\n\n        // Layer addition\n        helper = $('<ins class=\"' + _iCheckHelper + '\"/>').css(layer).appendTo(parent);\n\n        // Finalize customization\n        self.data(_iCheck, {o: settings, s: self.attr('style')}).css(hide);\n        !!settings.inheritClass && parent[_add](node.className || '');\n        !!settings.inheritID && id && parent.attr('id', _iCheck + '-' + id);\n        parent.css('position') == 'static' && parent.css('position', 'relative');\n        operate(self, true, _update);\n\n        // Label events\n        if (label.length) {\n          label.on(_click + '.i mouseover.i mouseout.i ' + _touch, function(event) {\n            var type = event[_type],\n              item = $(this);\n\n            // Do nothing if input is disabled\n            if (!node[_disabled]) {\n\n              // Click\n              if (type == _click) {\n                if ($(event.target).is('a')) {\n                  return;\n                }\n                operate(self, false, true);\n\n              // Hover state\n              } else if (labelHover) {\n\n                // mouseout|touchend\n                if (/ut|nd/.test(type)) {\n                  parent[_remove](hoverClass);\n                  item[_remove](labelHoverClass);\n                } else {\n                  parent[_add](hoverClass);\n                  item[_add](labelHoverClass);\n                }\n              }\n                if (_mobile) {\n                event.stopPropagation();\n              } else {\n                return false;\n              }\n            }\n          });\n        }\n          // Input events\n        self.on(_click + '.i focus.i blur.i keyup.i keydown.i keypress.i', function(event) {\n          var type = event[_type],\n            key = event.keyCode;\n\n          // Click\n          if (type == _click) {\n            return false;\n\n          // Keydown\n          } else if (type == 'keydown' && key == 32) {\n            if (!(node[_type] == _radio && node[_checked])) {\n              if (node[_checked]) {\n                off(self, _checked);\n              } else {\n                on(self, _checked);\n              }\n            }\n              return false;\n\n          // Keyup\n          } else if (type == 'keyup' && node[_type] == _radio) {\n            !node[_checked] && on(self, _checked);\n\n          // Focus/blur\n          } else if (/us|ur/.test(type)) {\n            parent[type == 'blur' ? _remove : _add](focusClass);\n          }\n        });\n\n        // Helper events\n        helper.on(_click + ' mousedown mouseup mouseover mouseout ' + _touch, function(event) {\n          var type = event[_type],\n\n            // mousedown|mouseup\n            toggle = /wn|up/.test(type) ? activeClass : hoverClass;\n\n          // Do nothing if input is disabled\n          if (!node[_disabled]) {\n\n            // Click\n            if (type == _click) {\n              operate(self, false, true);\n\n            // Active and hover states\n            } else {\n\n              // State is on\n              if (/wn|er|in/.test(type)) {\n\n                // mousedown|mouseover|touchbegin\n                parent[_add](toggle);\n\n              // State is off\n              } else {\n                parent[_remove](toggle + ' ' + activeClass);\n              }\n                // Label hover\n              if (label.length && labelHover && toggle == hoverClass) {\n\n                // mouseout|touchend\n                label[/ut|nd/.test(type) ? _remove : _add](labelHoverClass);\n              }\n            }\n              if (_mobile) {\n              event.stopPropagation();\n            } else {\n              return false;\n            }\n          }\n        });\n      });\n    } else {\n      return this;\n    }\n  };\n\n  // Do something with inputs\n  function operate(input, direct, method) {\n    var node = input[0],\n      state = /er/.test(method) ? _indeterminate : /bl/.test(method) ? _disabled : _checked,\n      active = method == _update ? {\n        checked: node[_checked],\n        disabled: node[_disabled],\n        indeterminate: input.attr(_indeterminate) == 'true' || input.attr(_determinate) == 'false'\n      } : node[state];\n\n    // Check, disable or indeterminate\n    if (/^(ch|di|in)/.test(method) && !active) {\n      on(input, state);\n\n    // Uncheck, enable or determinate\n    } else if (/^(un|en|de)/.test(method) && active) {\n      off(input, state);\n\n    // Update\n    } else if (method == _update) {\n\n      // Handle states\n      for (var state in active) {\n        if (active[state]) {\n          on(input, state, true);\n        } else {\n          off(input, state, true);\n        }\n      }\n    } else if (!direct || method == 'toggle') {\n\n      // Helper or label was clicked\n      if (!direct) {\n        input[_callback]('ifClicked');\n      }\n        // Toggle checked state\n      if (active) {\n        if (node[_type] !== _radio) {\n          off(input, state);\n        }\n      } else {\n        on(input, state);\n      }\n    }\n  }\n    // Add checked, disabled or indeterminate state\n  function on(input, state, keep) {\n    var node = input[0],\n      parent = input.parent(),\n      checked = state == _checked,\n      indeterminate = state == _indeterminate,\n      disabled = state == _disabled,\n      callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',\n      regular = option(input, callback + capitalize(node[_type])),\n      specific = option(input, state + capitalize(node[_type]));\n\n    // Prevent unnecessary actions\n    if (node[state] !== true) {\n\n      // Toggle assigned radio buttons\n      if (!keep && state == _checked && node[_type] == _radio && node.name) {\n        var form = input.closest('form'),\n          inputs = 'input[name=\"' + node.name + '\"]';\n\n        inputs = form.length ? form.find(inputs) : $(inputs);\n\n        inputs.each(function() {\n          if (this !== node && $(this).data(_iCheck)) {\n            off($(this), state);\n          }\n        });\n      }\n        // Indeterminate state\n      if (indeterminate) {\n\n        // Add indeterminate state\n        node[state] = true;\n\n        // Remove checked state\n        if (node[_checked]) {\n          off(input, _checked, 'force');\n        }\n          // Checked or disabled state\n      } else {\n\n        // Add checked or disabled state\n        if (!keep) {\n          node[state] = true;\n        }\n          // Remove indeterminate state\n        if (checked && node[_indeterminate]) {\n          off(input, _indeterminate, false);\n        }\n      }\n        // Trigger callbacks\n      callbacks(input, checked, state, keep);\n    }\n      // Add proper cursor\n    if (node[_disabled] && !!option(input, _cursor, true)) {\n      parent.find('.' + _iCheckHelper).css(_cursor, 'default');\n    }\n      // Add state class\n    parent[_add](specific || option(input, state) || '');\n\n    // Set ARIA attribute\n    disabled ? parent.attr('aria-disabled', 'true') : parent.attr('aria-checked', indeterminate ? 'mixed' : 'true');\n\n    // Remove regular state class\n    parent[_remove](regular || option(input, callback) || '');\n  }\n    // Remove checked, disabled or indeterminate state\n  function off(input, state, keep) {\n    var node = input[0],\n      parent = input.parent(),\n      checked = state == _checked,\n      indeterminate = state == _indeterminate,\n      disabled = state == _disabled,\n      callback = indeterminate ? _determinate : checked ? _unchecked : 'enabled',\n      regular = option(input, callback + capitalize(node[_type])),\n      specific = option(input, state + capitalize(node[_type]));\n\n    // Prevent unnecessary actions\n    if (node[state] !== false) {\n\n      // Toggle state\n      if (indeterminate || !keep || keep == 'force') {\n        node[state] = false;\n      }\n        // Trigger callbacks\n      callbacks(input, checked, callback, keep);\n    }\n      // Add proper cursor\n    if (!node[_disabled] && !!option(input, _cursor, true)) {\n      parent.find('.' + _iCheckHelper).css(_cursor, 'pointer');\n    }\n      // Remove state class\n    parent[_remove](specific || option(input, state) || '');\n\n    // Set ARIA attribute\n    disabled ? parent.attr('aria-disabled', 'false') : parent.attr('aria-checked', 'false');\n\n    // Add regular state class\n    parent[_add](regular || option(input, callback) || '');\n  }\n    // Remove all traces\n  function tidy(input, callback) {\n    if (input.data(_iCheck)) {\n\n      // Remove everything except input\n      input.parent().html(input.attr('style', input.data(_iCheck).s || ''));\n\n      // Callback\n      if (callback) {\n        input[_callback](callback);\n      }\n        // Unbind events\n      input.off('.i').unwrap();\n      $(_label + '[for=\"' + input[0].id + '\"]').add(input.closest(_label)).off('.i');\n    }\n  }\n    // Get some option\n  function option(input, state, regular) {\n    if (input.data(_iCheck)) {\n      return input.data(_iCheck).o[state + (regular ? '' : 'Class')];\n    }\n  }\n    // Capitalize some string\n  function capitalize(string) {\n    return string.charAt(0).toUpperCase() + string.slice(1);\n  }\n    // Executable handlers\n  function callbacks(input, checked, callback, keep) {\n    if (!keep) {\n      if (checked) {\n        input[_callback]('ifToggled');\n      }\n        input[_callback]('ifChanged')[_callback]('if' + capitalize(callback));\n    }\n  }\n})(window.jQuery || window.Zepto);\n"
  },
  {
    "path": "public/static/plugins/iCheck/line/_all.css",
    "content": "/* iCheck plugin Line skin\n----------------------------------- */\n.icheckbox_line,\n.iradio_line {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #000;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line .icheck_line-icon,\n    .iradio_line .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line.hover,\n    .icheckbox_line.checked.hover,\n    .iradio_line.hover {\n        background: #444;\n    }\n    .icheckbox_line.checked,\n    .iradio_line.checked {\n        background: #000;\n    }\n        .icheckbox_line.checked .icheck_line-icon,\n        .iradio_line.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line.disabled,\n    .iradio_line.disabled {\n        background: #ccc;\n        cursor: default;\n    }\n        .icheckbox_line.disabled .icheck_line-icon,\n        .iradio_line.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line.checked.disabled,\n    .iradio_line.checked.disabled {\n        background: #ccc;\n    }\n        .icheckbox_line.checked.disabled .icheck_line-icon,\n        .iradio_line.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line .icheck_line-icon,\n    .iradio_line .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}\n\n/* red */\n.icheckbox_line-red,\n.iradio_line-red {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #e56c69;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-red .icheck_line-icon,\n    .iradio_line-red .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-red.hover,\n    .icheckbox_line-red.checked.hover,\n    .iradio_line-red.hover {\n        background: #E98582;\n    }\n    .icheckbox_line-red.checked,\n    .iradio_line-red.checked {\n        background: #e56c69;\n    }\n        .icheckbox_line-red.checked .icheck_line-icon,\n        .iradio_line-red.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-red.disabled,\n    .iradio_line-red.disabled {\n        background: #F7D3D2;\n        cursor: default;\n    }\n        .icheckbox_line-red.disabled .icheck_line-icon,\n        .iradio_line-red.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-red.checked.disabled,\n    .iradio_line-red.checked.disabled {\n        background: #F7D3D2;\n    }\n        .icheckbox_line-red.checked.disabled .icheck_line-icon,\n        .iradio_line-red.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-red .icheck_line-icon,\n    .iradio_line-red .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}\n\n/* green */\n.icheckbox_line-green,\n.iradio_line-green {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #1b7e5a;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-green .icheck_line-icon,\n    .iradio_line-green .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-green.hover,\n    .icheckbox_line-green.checked.hover,\n    .iradio_line-green.hover {\n        background: #24AA7A;\n    }\n    .icheckbox_line-green.checked,\n    .iradio_line-green.checked {\n        background: #1b7e5a;\n    }\n        .icheckbox_line-green.checked .icheck_line-icon,\n        .iradio_line-green.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-green.disabled,\n    .iradio_line-green.disabled {\n        background: #89E6C4;\n        cursor: default;\n    }\n        .icheckbox_line-green.disabled .icheck_line-icon,\n        .iradio_line-green.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-green.checked.disabled,\n    .iradio_line-green.checked.disabled {\n        background: #89E6C4;\n    }\n        .icheckbox_line-green.checked.disabled .icheck_line-icon,\n        .iradio_line-green.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-green .icheck_line-icon,\n    .iradio_line-green .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}\n\n/* blue */\n.icheckbox_line-blue,\n.iradio_line-blue {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #2489c5;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-blue .icheck_line-icon,\n    .iradio_line-blue .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-blue.hover,\n    .icheckbox_line-blue.checked.hover,\n    .iradio_line-blue.hover {\n        background: #3DA0DB;\n    }\n    .icheckbox_line-blue.checked,\n    .iradio_line-blue.checked {\n        background: #2489c5;\n    }\n        .icheckbox_line-blue.checked .icheck_line-icon,\n        .iradio_line-blue.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-blue.disabled,\n    .iradio_line-blue.disabled {\n        background: #ADD7F0;\n        cursor: default;\n    }\n        .icheckbox_line-blue.disabled .icheck_line-icon,\n        .iradio_line-blue.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-blue.checked.disabled,\n    .iradio_line-blue.checked.disabled {\n        background: #ADD7F0;\n    }\n        .icheckbox_line-blue.checked.disabled .icheck_line-icon,\n        .iradio_line-blue.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-blue .icheck_line-icon,\n    .iradio_line-blue .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}\n\n/* aero */\n.icheckbox_line-aero,\n.iradio_line-aero {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #9cc2cb;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-aero .icheck_line-icon,\n    .iradio_line-aero .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-aero.hover,\n    .icheckbox_line-aero.checked.hover,\n    .iradio_line-aero.hover {\n        background: #B5D1D8;\n    }\n    .icheckbox_line-aero.checked,\n    .iradio_line-aero.checked {\n        background: #9cc2cb;\n    }\n        .icheckbox_line-aero.checked .icheck_line-icon,\n        .iradio_line-aero.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-aero.disabled,\n    .iradio_line-aero.disabled {\n        background: #D2E4E8;\n        cursor: default;\n    }\n        .icheckbox_line-aero.disabled .icheck_line-icon,\n        .iradio_line-aero.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-aero.checked.disabled,\n    .iradio_line-aero.checked.disabled {\n        background: #D2E4E8;\n    }\n        .icheckbox_line-aero.checked.disabled .icheck_line-icon,\n        .iradio_line-aero.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-aero .icheck_line-icon,\n    .iradio_line-aero .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}\n\n/* grey */\n.icheckbox_line-grey,\n.iradio_line-grey {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #73716e;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-grey .icheck_line-icon,\n    .iradio_line-grey .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-grey.hover,\n    .icheckbox_line-grey.checked.hover,\n    .iradio_line-grey.hover {\n        background: #8B8986;\n    }\n    .icheckbox_line-grey.checked,\n    .iradio_line-grey.checked {\n        background: #73716e;\n    }\n        .icheckbox_line-grey.checked .icheck_line-icon,\n        .iradio_line-grey.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-grey.disabled,\n    .iradio_line-grey.disabled {\n        background: #D5D4D3;\n        cursor: default;\n    }\n        .icheckbox_line-grey.disabled .icheck_line-icon,\n        .iradio_line-grey.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-grey.checked.disabled,\n    .iradio_line-grey.checked.disabled {\n        background: #D5D4D3;\n    }\n        .icheckbox_line-grey.checked.disabled .icheck_line-icon,\n        .iradio_line-grey.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-grey .icheck_line-icon,\n    .iradio_line-grey .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}\n\n/* orange */\n.icheckbox_line-orange,\n.iradio_line-orange {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #f70;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-orange .icheck_line-icon,\n    .iradio_line-orange .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-orange.hover,\n    .icheckbox_line-orange.checked.hover,\n    .iradio_line-orange.hover {\n        background: #FF9233;\n    }\n    .icheckbox_line-orange.checked,\n    .iradio_line-orange.checked {\n        background: #f70;\n    }\n        .icheckbox_line-orange.checked .icheck_line-icon,\n        .iradio_line-orange.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-orange.disabled,\n    .iradio_line-orange.disabled {\n        background: #FFD6B3;\n        cursor: default;\n    }\n        .icheckbox_line-orange.disabled .icheck_line-icon,\n        .iradio_line-orange.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-orange.checked.disabled,\n    .iradio_line-orange.checked.disabled {\n        background: #FFD6B3;\n    }\n        .icheckbox_line-orange.checked.disabled .icheck_line-icon,\n        .iradio_line-orange.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-orange .icheck_line-icon,\n    .iradio_line-orange .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}\n\n/* yellow */\n.icheckbox_line-yellow,\n.iradio_line-yellow {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #FFC414;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-yellow .icheck_line-icon,\n    .iradio_line-yellow .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-yellow.hover,\n    .icheckbox_line-yellow.checked.hover,\n    .iradio_line-yellow.hover {\n        background: #FFD34F;\n    }\n    .icheckbox_line-yellow.checked,\n    .iradio_line-yellow.checked {\n        background: #FFC414;\n    }\n        .icheckbox_line-yellow.checked .icheck_line-icon,\n        .iradio_line-yellow.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-yellow.disabled,\n    .iradio_line-yellow.disabled {\n        background: #FFE495;\n        cursor: default;\n    }\n        .icheckbox_line-yellow.disabled .icheck_line-icon,\n        .iradio_line-yellow.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-yellow.checked.disabled,\n    .iradio_line-yellow.checked.disabled {\n        background: #FFE495;\n    }\n        .icheckbox_line-yellow.checked.disabled .icheck_line-icon,\n        .iradio_line-yellow.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-yellow .icheck_line-icon,\n    .iradio_line-yellow .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}\n\n/* pink */\n.icheckbox_line-pink,\n.iradio_line-pink {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #a77a94;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-pink .icheck_line-icon,\n    .iradio_line-pink .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-pink.hover,\n    .icheckbox_line-pink.checked.hover,\n    .iradio_line-pink.hover {\n        background: #B995A9;\n    }\n    .icheckbox_line-pink.checked,\n    .iradio_line-pink.checked {\n        background: #a77a94;\n    }\n        .icheckbox_line-pink.checked .icheck_line-icon,\n        .iradio_line-pink.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-pink.disabled,\n    .iradio_line-pink.disabled {\n        background: #E0D0DA;\n        cursor: default;\n    }\n        .icheckbox_line-pink.disabled .icheck_line-icon,\n        .iradio_line-pink.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-pink.checked.disabled,\n    .iradio_line-pink.checked.disabled {\n        background: #E0D0DA;\n    }\n        .icheckbox_line-pink.checked.disabled .icheck_line-icon,\n        .iradio_line-pink.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-pink .icheck_line-icon,\n    .iradio_line-pink .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}\n\n/* purple */\n.icheckbox_line-purple,\n.iradio_line-purple {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #6a5a8c;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-purple .icheck_line-icon,\n    .iradio_line-purple .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-purple.hover,\n    .icheckbox_line-purple.checked.hover,\n    .iradio_line-purple.hover {\n        background: #8677A7;\n    }\n    .icheckbox_line-purple.checked,\n    .iradio_line-purple.checked {\n        background: #6a5a8c;\n    }\n        .icheckbox_line-purple.checked .icheck_line-icon,\n        .iradio_line-purple.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-purple.disabled,\n    .iradio_line-purple.disabled {\n        background: #D2CCDE;\n        cursor: default;\n    }\n        .icheckbox_line-purple.disabled .icheck_line-icon,\n        .iradio_line-purple.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-purple.checked.disabled,\n    .iradio_line-purple.checked.disabled {\n        background: #D2CCDE;\n    }\n        .icheckbox_line-purple.checked.disabled .icheck_line-icon,\n        .iradio_line-purple.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-purple .icheck_line-icon,\n    .iradio_line-purple .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/line/aero.css",
    "content": "/* iCheck plugin Line skin, aero\n----------------------------------- */\n.icheckbox_line-aero,\n.iradio_line-aero {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #9cc2cb;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-aero .icheck_line-icon,\n    .iradio_line-aero .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-aero.hover,\n    .icheckbox_line-aero.checked.hover,\n    .iradio_line-aero.hover {\n        background: #B5D1D8;\n    }\n    .icheckbox_line-aero.checked,\n    .iradio_line-aero.checked {\n        background: #9cc2cb;\n    }\n        .icheckbox_line-aero.checked .icheck_line-icon,\n        .iradio_line-aero.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-aero.disabled,\n    .iradio_line-aero.disabled {\n        background: #D2E4E8;\n        cursor: default;\n    }\n        .icheckbox_line-aero.disabled .icheck_line-icon,\n        .iradio_line-aero.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-aero.checked.disabled,\n    .iradio_line-aero.checked.disabled {\n        background: #D2E4E8;\n    }\n        .icheckbox_line-aero.checked.disabled .icheck_line-icon,\n        .iradio_line-aero.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-aero .icheck_line-icon,\n    .iradio_line-aero .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/line/blue.css",
    "content": "/* iCheck plugin Line skin, blue\n----------------------------------- */\n.icheckbox_line-blue,\n.iradio_line-blue {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #2489c5;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-blue .icheck_line-icon,\n    .iradio_line-blue .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-blue.hover,\n    .icheckbox_line-blue.checked.hover,\n    .iradio_line-blue.hover {\n        background: #3DA0DB;\n    }\n    .icheckbox_line-blue.checked,\n    .iradio_line-blue.checked {\n        background: #2489c5;\n    }\n        .icheckbox_line-blue.checked .icheck_line-icon,\n        .iradio_line-blue.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-blue.disabled,\n    .iradio_line-blue.disabled {\n        background: #ADD7F0;\n        cursor: default;\n    }\n        .icheckbox_line-blue.disabled .icheck_line-icon,\n        .iradio_line-blue.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-blue.checked.disabled,\n    .iradio_line-blue.checked.disabled {\n        background: #ADD7F0;\n    }\n        .icheckbox_line-blue.checked.disabled .icheck_line-icon,\n        .iradio_line-blue.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-blue .icheck_line-icon,\n    .iradio_line-blue .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/line/green.css",
    "content": "/* iCheck plugin Line skin, green\n----------------------------------- */\n.icheckbox_line-green,\n.iradio_line-green {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #1b7e5a;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-green .icheck_line-icon,\n    .iradio_line-green .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-green.hover,\n    .icheckbox_line-green.checked.hover,\n    .iradio_line-green.hover {\n        background: #24AA7A;\n    }\n    .icheckbox_line-green.checked,\n    .iradio_line-green.checked {\n        background: #1b7e5a;\n    }\n        .icheckbox_line-green.checked .icheck_line-icon,\n        .iradio_line-green.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-green.disabled,\n    .iradio_line-green.disabled {\n        background: #89E6C4;\n        cursor: default;\n    }\n        .icheckbox_line-green.disabled .icheck_line-icon,\n        .iradio_line-green.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-green.checked.disabled,\n    .iradio_line-green.checked.disabled {\n        background: #89E6C4;\n    }\n        .icheckbox_line-green.checked.disabled .icheck_line-icon,\n        .iradio_line-green.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-green .icheck_line-icon,\n    .iradio_line-green .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/line/grey.css",
    "content": "/* iCheck plugin Line skin, grey\n----------------------------------- */\n.icheckbox_line-grey,\n.iradio_line-grey {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #73716e;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-grey .icheck_line-icon,\n    .iradio_line-grey .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-grey.hover,\n    .icheckbox_line-grey.checked.hover,\n    .iradio_line-grey.hover {\n        background: #8B8986;\n    }\n    .icheckbox_line-grey.checked,\n    .iradio_line-grey.checked {\n        background: #73716e;\n    }\n        .icheckbox_line-grey.checked .icheck_line-icon,\n        .iradio_line-grey.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-grey.disabled,\n    .iradio_line-grey.disabled {\n        background: #D5D4D3;\n        cursor: default;\n    }\n        .icheckbox_line-grey.disabled .icheck_line-icon,\n        .iradio_line-grey.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-grey.checked.disabled,\n    .iradio_line-grey.checked.disabled {\n        background: #D5D4D3;\n    }\n        .icheckbox_line-grey.checked.disabled .icheck_line-icon,\n        .iradio_line-grey.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-grey .icheck_line-icon,\n    .iradio_line-grey .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/line/line.css",
    "content": "/* iCheck plugin Line skin, black\n----------------------------------- */\n.icheckbox_line,\n.iradio_line {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #000;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line .icheck_line-icon,\n    .iradio_line .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line.hover,\n    .icheckbox_line.checked.hover,\n    .iradio_line.hover {\n        background: #444;\n    }\n    .icheckbox_line.checked,\n    .iradio_line.checked {\n        background: #000;\n    }\n        .icheckbox_line.checked .icheck_line-icon,\n        .iradio_line.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line.disabled,\n    .iradio_line.disabled {\n        background: #ccc;\n        cursor: default;\n    }\n        .icheckbox_line.disabled .icheck_line-icon,\n        .iradio_line.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line.checked.disabled,\n    .iradio_line.checked.disabled {\n        background: #ccc;\n    }\n        .icheckbox_line.checked.disabled .icheck_line-icon,\n        .iradio_line.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line .icheck_line-icon,\n    .iradio_line .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/line/orange.css",
    "content": "/* iCheck plugin Line skin, orange\n----------------------------------- */\n.icheckbox_line-orange,\n.iradio_line-orange {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #f70;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-orange .icheck_line-icon,\n    .iradio_line-orange .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-orange.hover,\n    .icheckbox_line-orange.checked.hover,\n    .iradio_line-orange.hover {\n        background: #FF9233;\n    }\n    .icheckbox_line-orange.checked,\n    .iradio_line-orange.checked {\n        background: #f70;\n    }\n        .icheckbox_line-orange.checked .icheck_line-icon,\n        .iradio_line-orange.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-orange.disabled,\n    .iradio_line-orange.disabled {\n        background: #FFD6B3;\n        cursor: default;\n    }\n        .icheckbox_line-orange.disabled .icheck_line-icon,\n        .iradio_line-orange.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-orange.checked.disabled,\n    .iradio_line-orange.checked.disabled {\n        background: #FFD6B3;\n    }\n        .icheckbox_line-orange.checked.disabled .icheck_line-icon,\n        .iradio_line-orange.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-orange .icheck_line-icon,\n    .iradio_line-orange .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/line/pink.css",
    "content": "/* iCheck plugin Line skin, pink\n----------------------------------- */\n.icheckbox_line-pink,\n.iradio_line-pink {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #a77a94;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-pink .icheck_line-icon,\n    .iradio_line-pink .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-pink.hover,\n    .icheckbox_line-pink.checked.hover,\n    .iradio_line-pink.hover {\n        background: #B995A9;\n    }\n    .icheckbox_line-pink.checked,\n    .iradio_line-pink.checked {\n        background: #a77a94;\n    }\n        .icheckbox_line-pink.checked .icheck_line-icon,\n        .iradio_line-pink.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-pink.disabled,\n    .iradio_line-pink.disabled {\n        background: #E0D0DA;\n        cursor: default;\n    }\n        .icheckbox_line-pink.disabled .icheck_line-icon,\n        .iradio_line-pink.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-pink.checked.disabled,\n    .iradio_line-pink.checked.disabled {\n        background: #E0D0DA;\n    }\n        .icheckbox_line-pink.checked.disabled .icheck_line-icon,\n        .iradio_line-pink.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-pink .icheck_line-icon,\n    .iradio_line-pink .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/line/purple.css",
    "content": "/* iCheck plugin Line skin, purple\n----------------------------------- */\n.icheckbox_line-purple,\n.iradio_line-purple {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #6a5a8c;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-purple .icheck_line-icon,\n    .iradio_line-purple .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-purple.hover,\n    .icheckbox_line-purple.checked.hover,\n    .iradio_line-purple.hover {\n        background: #8677A7;\n    }\n    .icheckbox_line-purple.checked,\n    .iradio_line-purple.checked {\n        background: #6a5a8c;\n    }\n        .icheckbox_line-purple.checked .icheck_line-icon,\n        .iradio_line-purple.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-purple.disabled,\n    .iradio_line-purple.disabled {\n        background: #D2CCDE;\n        cursor: default;\n    }\n        .icheckbox_line-purple.disabled .icheck_line-icon,\n        .iradio_line-purple.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-purple.checked.disabled,\n    .iradio_line-purple.checked.disabled {\n        background: #D2CCDE;\n    }\n        .icheckbox_line-purple.checked.disabled .icheck_line-icon,\n        .iradio_line-purple.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-purple .icheck_line-icon,\n    .iradio_line-purple .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/line/red.css",
    "content": "/* iCheck plugin Line skin, red\n----------------------------------- */\n.icheckbox_line-red,\n.iradio_line-red {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #e56c69;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-red .icheck_line-icon,\n    .iradio_line-red .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-red.hover,\n    .icheckbox_line-red.checked.hover,\n    .iradio_line-red.hover {\n        background: #E98582;\n    }\n    .icheckbox_line-red.checked,\n    .iradio_line-red.checked {\n        background: #e56c69;\n    }\n        .icheckbox_line-red.checked .icheck_line-icon,\n        .iradio_line-red.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-red.disabled,\n    .iradio_line-red.disabled {\n        background: #F7D3D2;\n        cursor: default;\n    }\n        .icheckbox_line-red.disabled .icheck_line-icon,\n        .iradio_line-red.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-red.checked.disabled,\n    .iradio_line-red.checked.disabled {\n        background: #F7D3D2;\n    }\n        .icheckbox_line-red.checked.disabled .icheck_line-icon,\n        .iradio_line-red.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-red .icheck_line-icon,\n    .iradio_line-red .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/line/yellow.css",
    "content": "/* iCheck plugin Line skin, yellow\n----------------------------------- */\n.icheckbox_line-yellow,\n.iradio_line-yellow {\n    position: relative;\n    display: block;\n    margin: 0;\n    padding: 5px 15px 5px 38px;\n    font-size: 13px;\n    line-height: 17px;\n    color: #fff;\n    background: #FFC414;\n    border: none;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    cursor: pointer;\n}\n    .icheckbox_line-yellow .icheck_line-icon,\n    .iradio_line-yellow .icheck_line-icon {\n        position: absolute;\n        top: 50%;\n        left: 13px;\n        width: 13px;\n        height: 11px;\n        margin: -5px 0 0 0;\n        padding: 0;\n        overflow: hidden;\n        background: url(line.png) no-repeat;\n        border: none;\n    }\n    .icheckbox_line-yellow.hover,\n    .icheckbox_line-yellow.checked.hover,\n    .iradio_line-yellow.hover {\n        background: #FFD34F;\n    }\n    .icheckbox_line-yellow.checked,\n    .iradio_line-yellow.checked {\n        background: #FFC414;\n    }\n        .icheckbox_line-yellow.checked .icheck_line-icon,\n        .iradio_line-yellow.checked .icheck_line-icon {\n            background-position: -15px 0;\n        }\n    .icheckbox_line-yellow.disabled,\n    .iradio_line-yellow.disabled {\n        background: #FFE495;\n        cursor: default;\n    }\n        .icheckbox_line-yellow.disabled .icheck_line-icon,\n        .iradio_line-yellow.disabled .icheck_line-icon {\n            background-position: -30px 0;\n        }\n    .icheckbox_line-yellow.checked.disabled,\n    .iradio_line-yellow.checked.disabled {\n        background: #FFE495;\n    }\n        .icheckbox_line-yellow.checked.disabled .icheck_line-icon,\n        .iradio_line-yellow.checked.disabled .icheck_line-icon {\n            background-position: -45px 0;\n        }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_line-yellow .icheck_line-icon,\n    .iradio_line-yellow .icheck_line-icon {\n        background-image: url(line@2x.png);\n        -webkit-background-size: 60px 13px;\n        background-size: 60px 13px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/minimal/_all.css",
    "content": "/* red */\n.icheckbox_minimal-red,\n.iradio_minimal-red {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(red.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-red {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-red.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-red.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-red.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-red.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-red {\n    background-position: -100px 0;\n}\n    .iradio_minimal-red.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-red.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-red.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-red.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-red,\n    .iradio_minimal-red {\n        background-image: url(red@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}\n\n/* green */\n.icheckbox_minimal-green,\n.iradio_minimal-green {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(green.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-green {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-green.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-green.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-green.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-green.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-green {\n    background-position: -100px 0;\n}\n    .iradio_minimal-green.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-green.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-green.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-green.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-green,\n    .iradio_minimal-green {\n        background-image: url(green@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}\n\n/* blue */\n.icheckbox_minimal-blue,\n.iradio_minimal-blue {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(blue.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-blue {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-blue.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-blue.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-blue.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-blue.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-blue {\n    background-position: -100px 0;\n}\n    .iradio_minimal-blue.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-blue.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-blue.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-blue.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-blue,\n    .iradio_minimal-blue {\n        background-image: url(blue@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}\n\n/* aero */\n.icheckbox_minimal-aero,\n.iradio_minimal-aero {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(aero.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-aero {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-aero.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-aero.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-aero.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-aero.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-aero {\n    background-position: -100px 0;\n}\n    .iradio_minimal-aero.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-aero.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-aero.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-aero.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-aero,\n    .iradio_minimal-aero {\n        background-image: url(aero@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}\n\n/* grey */\n.icheckbox_minimal-grey,\n.iradio_minimal-grey {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(grey.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-grey {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-grey.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-grey.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-grey.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-grey.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-grey {\n    background-position: -100px 0;\n}\n    .iradio_minimal-grey.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-grey.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-grey.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-grey.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-grey,\n    .iradio_minimal-grey {\n        background-image: url(grey@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}\n\n/* orange */\n.icheckbox_minimal-orange,\n.iradio_minimal-orange {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(orange.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-orange {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-orange.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-orange.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-orange.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-orange.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-orange {\n    background-position: -100px 0;\n}\n    .iradio_minimal-orange.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-orange.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-orange.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-orange.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-orange,\n    .iradio_minimal-orange {\n        background-image: url(orange@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}\n\n/* yellow */\n.icheckbox_minimal-yellow,\n.iradio_minimal-yellow {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(yellow.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-yellow {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-yellow.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-yellow.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-yellow.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-yellow.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-yellow {\n    background-position: -100px 0;\n}\n    .iradio_minimal-yellow.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-yellow.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-yellow.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-yellow.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-yellow,\n    .iradio_minimal-yellow {\n        background-image: url(yellow@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}\n\n/* pink */\n.icheckbox_minimal-pink,\n.iradio_minimal-pink {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(pink.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-pink {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-pink.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-pink.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-pink.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-pink.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-pink {\n    background-position: -100px 0;\n}\n    .iradio_minimal-pink.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-pink.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-pink.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-pink.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-pink,\n    .iradio_minimal-pink {\n        background-image: url(pink@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}\n\n/* purple */\n.icheckbox_minimal-purple,\n.iradio_minimal-purple {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(purple.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-purple {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-purple.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-purple.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-purple.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-purple.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-purple {\n    background-position: -100px 0;\n}\n    .iradio_minimal-purple.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-purple.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-purple.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-purple.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-purple,\n    .iradio_minimal-purple {\n        background-image: url(purple@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/minimal/aero.css",
    "content": "/* iCheck plugin Minimal skin, aero\n----------------------------------- */\n.icheckbox_minimal-aero,\n.iradio_minimal-aero {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(aero.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-aero {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-aero.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-aero.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-aero.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-aero.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-aero {\n    background-position: -100px 0;\n}\n    .iradio_minimal-aero.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-aero.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-aero.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-aero.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-aero,\n    .iradio_minimal-aero {\n        background-image: url(aero@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/minimal/blue.css",
    "content": "/* iCheck plugin Minimal skin, blue\n----------------------------------- */\n.icheckbox_minimal-blue,\n.iradio_minimal-blue {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(blue.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-blue {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-blue.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-blue.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-blue.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-blue.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-blue {\n    background-position: -100px 0;\n}\n    .iradio_minimal-blue.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-blue.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-blue.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-blue.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-blue,\n    .iradio_minimal-blue {\n        background-image: url(blue@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/minimal/green.css",
    "content": "/* iCheck plugin Minimal skin, green\n----------------------------------- */\n.icheckbox_minimal-green,\n.iradio_minimal-green {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(green.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-green {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-green.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-green.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-green.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-green.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-green {\n    background-position: -100px 0;\n}\n    .iradio_minimal-green.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-green.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-green.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-green.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-green,\n    .iradio_minimal-green {\n        background-image: url(green@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/minimal/grey.css",
    "content": "/* iCheck plugin Minimal skin, grey\n----------------------------------- */\n.icheckbox_minimal-grey,\n.iradio_minimal-grey {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(grey.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-grey {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-grey.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-grey.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-grey.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-grey.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-grey {\n    background-position: -100px 0;\n}\n    .iradio_minimal-grey.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-grey.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-grey.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-grey.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-grey,\n    .iradio_minimal-grey {\n        background-image: url(grey@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/minimal/minimal.css",
    "content": "/* iCheck plugin Minimal skin, black\n----------------------------------- */\n.icheckbox_minimal,\n.iradio_minimal {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(minimal.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal {\n    background-position: 0 0;\n}\n    .icheckbox_minimal.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal {\n    background-position: -100px 0;\n}\n    .iradio_minimal.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal,\n    .iradio_minimal {\n        background-image: url(minimal@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/minimal/orange.css",
    "content": "/* iCheck plugin Minimal skin, orange\n----------------------------------- */\n.icheckbox_minimal-orange,\n.iradio_minimal-orange {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(orange.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-orange {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-orange.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-orange.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-orange.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-orange.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-orange {\n    background-position: -100px 0;\n}\n    .iradio_minimal-orange.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-orange.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-orange.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-orange.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-orange,\n    .iradio_minimal-orange {\n        background-image: url(orange@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/minimal/pink.css",
    "content": "/* iCheck plugin Minimal skin, pink\n----------------------------------- */\n.icheckbox_minimal-pink,\n.iradio_minimal-pink {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(pink.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-pink {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-pink.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-pink.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-pink.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-pink.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-pink {\n    background-position: -100px 0;\n}\n    .iradio_minimal-pink.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-pink.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-pink.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-pink.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-pink,\n    .iradio_minimal-pink {\n        background-image: url(pink@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/minimal/purple.css",
    "content": "/* iCheck plugin Minimal skin, purple\n----------------------------------- */\n.icheckbox_minimal-purple,\n.iradio_minimal-purple {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(purple.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-purple {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-purple.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-purple.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-purple.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-purple.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-purple {\n    background-position: -100px 0;\n}\n    .iradio_minimal-purple.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-purple.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-purple.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-purple.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-purple,\n    .iradio_minimal-purple {\n        background-image: url(purple@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/minimal/red.css",
    "content": "/* iCheck plugin Minimal skin, red\n----------------------------------- */\n.icheckbox_minimal-red,\n.iradio_minimal-red {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(red.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-red {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-red.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-red.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-red.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-red.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-red {\n    background-position: -100px 0;\n}\n    .iradio_minimal-red.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-red.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-red.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-red.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-red,\n    .iradio_minimal-red {\n        background-image: url(red@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/minimal/yellow.css",
    "content": "/* iCheck plugin Minimal skin, yellow\n----------------------------------- */\n.icheckbox_minimal-yellow,\n.iradio_minimal-yellow {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 18px;\n    height: 18px;\n    background: url(yellow.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_minimal-yellow {\n    background-position: 0 0;\n}\n    .icheckbox_minimal-yellow.hover {\n        background-position: -20px 0;\n    }\n    .icheckbox_minimal-yellow.checked {\n        background-position: -40px 0;\n    }\n    .icheckbox_minimal-yellow.disabled {\n        background-position: -60px 0;\n        cursor: default;\n    }\n    .icheckbox_minimal-yellow.checked.disabled {\n        background-position: -80px 0;\n    }\n\n.iradio_minimal-yellow {\n    background-position: -100px 0;\n}\n    .iradio_minimal-yellow.hover {\n        background-position: -120px 0;\n    }\n    .iradio_minimal-yellow.checked {\n        background-position: -140px 0;\n    }\n    .iradio_minimal-yellow.disabled {\n        background-position: -160px 0;\n        cursor: default;\n    }\n    .iradio_minimal-yellow.checked.disabled {\n        background-position: -180px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 1.5),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_minimal-yellow,\n    .iradio_minimal-yellow {\n        background-image: url(yellow@2x.png);\n        -webkit-background-size: 200px 20px;\n        background-size: 200px 20px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/polaris/polaris.css",
    "content": "/* iCheck plugin Polaris skin\n----------------------------------- */\n.icheckbox_polaris,\n.iradio_polaris {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 29px;\n    height: 29px;\n    background: url(polaris.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_polaris {\n    background-position: 0 0;\n}\n    .icheckbox_polaris.hover {\n        background-position: -31px 0;\n    }\n    .icheckbox_polaris.checked {\n        background-position: -62px 0;\n    }\n    .icheckbox_polaris.disabled {\n        background-position: -93px 0;\n        cursor: default;\n    }\n    .icheckbox_polaris.checked.disabled {\n        background-position: -124px 0;\n    }\n\n.iradio_polaris {\n    background-position: -155px 0;\n}\n    .iradio_polaris.hover {\n        background-position: -186px 0;\n    }\n    .iradio_polaris.checked {\n        background-position: -217px 0;\n    }\n    .iradio_polaris.disabled {\n        background-position: -248px 0;\n        cursor: default;\n    }\n    .iradio_polaris.checked.disabled {\n        background-position: -279px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_polaris,\n    .iradio_polaris {\n        background-image: url(polaris@2x.png);\n        -webkit-background-size: 310px 31px;\n        background-size: 310px 31px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/square/_all.css",
    "content": "/* iCheck plugin Square skin\n----------------------------------- */\n.icheckbox_square,\n.iradio_square {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(square.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square {\n    background-position: 0 0;\n}\n    .icheckbox_square.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square {\n    background-position: -120px 0;\n}\n    .iradio_square.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square,\n    .iradio_square {\n        background-image: url(square@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}\n\n/* red */\n.icheckbox_square-red,\n.iradio_square-red {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(red.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-red {\n    background-position: 0 0;\n}\n    .icheckbox_square-red.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-red.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-red.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-red.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-red {\n    background-position: -120px 0;\n}\n    .iradio_square-red.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-red.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-red.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-red.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-red,\n    .iradio_square-red {\n        background-image: url(red@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}\n\n/* green */\n.icheckbox_square-green,\n.iradio_square-green {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(green.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-green {\n    background-position: 0 0;\n}\n    .icheckbox_square-green.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-green.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-green.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-green.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-green {\n    background-position: -120px 0;\n}\n    .iradio_square-green.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-green.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-green.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-green.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-green,\n    .iradio_square-green {\n        background-image: url(green@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}\n\n/* blue */\n.icheckbox_square-blue,\n.iradio_square-blue {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(blue.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-blue {\n    background-position: 0 0;\n}\n    .icheckbox_square-blue.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-blue.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-blue.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-blue.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-blue {\n    background-position: -120px 0;\n}\n    .iradio_square-blue.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-blue.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-blue.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-blue.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-blue,\n    .iradio_square-blue {\n        background-image: url(blue@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}\n\n/* aero */\n.icheckbox_square-aero,\n.iradio_square-aero {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(aero.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-aero {\n    background-position: 0 0;\n}\n    .icheckbox_square-aero.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-aero.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-aero.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-aero.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-aero {\n    background-position: -120px 0;\n}\n    .iradio_square-aero.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-aero.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-aero.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-aero.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-aero,\n    .iradio_square-aero {\n        background-image: url(aero@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}\n\n/* grey */\n.icheckbox_square-grey,\n.iradio_square-grey {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(grey.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-grey {\n    background-position: 0 0;\n}\n    .icheckbox_square-grey.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-grey.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-grey.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-grey.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-grey {\n    background-position: -120px 0;\n}\n    .iradio_square-grey.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-grey.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-grey.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-grey.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-grey,\n    .iradio_square-grey {\n        background-image: url(grey@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}\n\n/* orange */\n.icheckbox_square-orange,\n.iradio_square-orange {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(orange.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-orange {\n    background-position: 0 0;\n}\n    .icheckbox_square-orange.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-orange.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-orange.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-orange.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-orange {\n    background-position: -120px 0;\n}\n    .iradio_square-orange.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-orange.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-orange.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-orange.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-orange,\n    .iradio_square-orange {\n        background-image: url(orange@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}\n\n/* yellow */\n.icheckbox_square-yellow,\n.iradio_square-yellow {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(yellow.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-yellow {\n    background-position: 0 0;\n}\n    .icheckbox_square-yellow.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-yellow.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-yellow.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-yellow.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-yellow {\n    background-position: -120px 0;\n}\n    .iradio_square-yellow.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-yellow.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-yellow.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-yellow.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-yellow,\n    .iradio_square-yellow {\n        background-image: url(yellow@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}\n\n/* pink */\n.icheckbox_square-pink,\n.iradio_square-pink {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(pink.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-pink {\n    background-position: 0 0;\n}\n    .icheckbox_square-pink.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-pink.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-pink.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-pink.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-pink {\n    background-position: -120px 0;\n}\n    .iradio_square-pink.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-pink.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-pink.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-pink.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-pink,\n    .iradio_square-pink {\n        background-image: url(pink@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}\n\n/* purple */\n.icheckbox_square-purple,\n.iradio_square-purple {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(purple.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-purple {\n    background-position: 0 0;\n}\n    .icheckbox_square-purple.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-purple.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-purple.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-purple.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-purple {\n    background-position: -120px 0;\n}\n    .iradio_square-purple.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-purple.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-purple.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-purple.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-purple,\n    .iradio_square-purple {\n        background-image: url(purple@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/square/aero.css",
    "content": "/* iCheck plugin Square skin, aero\n----------------------------------- */\n.icheckbox_square-aero,\n.iradio_square-aero {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(aero.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-aero {\n    background-position: 0 0;\n}\n    .icheckbox_square-aero.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-aero.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-aero.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-aero.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-aero {\n    background-position: -120px 0;\n}\n    .iradio_square-aero.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-aero.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-aero.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-aero.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-aero,\n    .iradio_square-aero {\n        background-image: url(aero@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/square/blue.css",
    "content": "/* iCheck plugin Square skin, blue\n----------------------------------- */\n.icheckbox_square-blue,\n.iradio_square-blue {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(blue.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-blue {\n    background-position: 0 0;\n}\n    .icheckbox_square-blue.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-blue.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-blue.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-blue.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-blue {\n    background-position: -120px 0;\n}\n    .iradio_square-blue.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-blue.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-blue.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-blue.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-blue,\n    .iradio_square-blue {\n        background-image: url(blue@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/square/green.css",
    "content": "/* iCheck plugin Square skin, green\n----------------------------------- */\n.icheckbox_square-green,\n.iradio_square-green {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(green.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-green {\n    background-position: 0 0;\n}\n    .icheckbox_square-green.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-green.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-green.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-green.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-green {\n    background-position: -120px 0;\n}\n    .iradio_square-green.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-green.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-green.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-green.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-green,\n    .iradio_square-green {\n        background-image: url(green@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/square/grey.css",
    "content": "/* iCheck plugin Square skin, grey\n----------------------------------- */\n.icheckbox_square-grey,\n.iradio_square-grey {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(grey.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-grey {\n    background-position: 0 0;\n}\n    .icheckbox_square-grey.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-grey.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-grey.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-grey.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-grey {\n    background-position: -120px 0;\n}\n    .iradio_square-grey.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-grey.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-grey.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-grey.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-grey,\n    .iradio_square-grey {\n        background-image: url(grey@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/square/orange.css",
    "content": "/* iCheck plugin Square skin, orange\n----------------------------------- */\n.icheckbox_square-orange,\n.iradio_square-orange {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(orange.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-orange {\n    background-position: 0 0;\n}\n    .icheckbox_square-orange.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-orange.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-orange.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-orange.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-orange {\n    background-position: -120px 0;\n}\n    .iradio_square-orange.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-orange.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-orange.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-orange.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-orange,\n    .iradio_square-orange {\n        background-image: url(orange@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/square/pink.css",
    "content": "/* iCheck plugin Square skin, pink\n----------------------------------- */\n.icheckbox_square-pink,\n.iradio_square-pink {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(pink.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-pink {\n    background-position: 0 0;\n}\n    .icheckbox_square-pink.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-pink.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-pink.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-pink.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-pink {\n    background-position: -120px 0;\n}\n    .iradio_square-pink.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-pink.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-pink.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-pink.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-pink,\n    .iradio_square-pink {\n        background-image: url(pink@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/square/purple.css",
    "content": "/* iCheck plugin Square skin, purple\n----------------------------------- */\n.icheckbox_square-purple,\n.iradio_square-purple {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(purple.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-purple {\n    background-position: 0 0;\n}\n    .icheckbox_square-purple.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-purple.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-purple.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-purple.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-purple {\n    background-position: -120px 0;\n}\n    .iradio_square-purple.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-purple.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-purple.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-purple.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-purple,\n    .iradio_square-purple {\n        background-image: url(purple@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/square/red.css",
    "content": "/* iCheck plugin Square skin, red\n----------------------------------- */\n.icheckbox_square-red,\n.iradio_square-red {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(red.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-red {\n    background-position: 0 0;\n}\n    .icheckbox_square-red.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-red.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-red.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-red.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-red {\n    background-position: -120px 0;\n}\n    .iradio_square-red.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-red.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-red.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-red.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-red,\n    .iradio_square-red {\n        background-image: url(red@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/square/square.css",
    "content": "/* iCheck plugin Square skin, black\n----------------------------------- */\n.icheckbox_square,\n.iradio_square {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(square.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square {\n    background-position: 0 0;\n}\n    .icheckbox_square.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square {\n    background-position: -120px 0;\n}\n    .iradio_square.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square,\n    .iradio_square {\n        background-image: url(square@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/iCheck/square/yellow.css",
    "content": "/* iCheck plugin Square skin, yellow\n----------------------------------- */\n.icheckbox_square-yellow,\n.iradio_square-yellow {\n    display: inline-block;\n    *display: inline;\n    vertical-align: middle;\n    margin: 0;\n    padding: 0;\n    width: 22px;\n    height: 22px;\n    background: url(yellow.png) no-repeat;\n    border: none;\n    cursor: pointer;\n}\n\n.icheckbox_square-yellow {\n    background-position: 0 0;\n}\n    .icheckbox_square-yellow.hover {\n        background-position: -24px 0;\n    }\n    .icheckbox_square-yellow.checked {\n        background-position: -48px 0;\n    }\n    .icheckbox_square-yellow.disabled {\n        background-position: -72px 0;\n        cursor: default;\n    }\n    .icheckbox_square-yellow.checked.disabled {\n        background-position: -96px 0;\n    }\n\n.iradio_square-yellow {\n    background-position: -120px 0;\n}\n    .iradio_square-yellow.hover {\n        background-position: -144px 0;\n    }\n    .iradio_square-yellow.checked {\n        background-position: -168px 0;\n    }\n    .iradio_square-yellow.disabled {\n        background-position: -192px 0;\n        cursor: default;\n    }\n    .iradio_square-yellow.checked.disabled {\n        background-position: -216px 0;\n    }\n\n/* Retina support */\n@media only screen and (-webkit-min-device-pixel-ratio: 1.5),\n       only screen and (-moz-min-device-pixel-ratio: 1.5),\n       only screen and (-o-min-device-pixel-ratio: 3/2),\n       only screen and (min-device-pixel-ratio: 1.5) {\n    .icheckbox_square-yellow,\n    .iradio_square-yellow {\n        background-image: url(yellow@2x.png);\n        -webkit-background-size: 240px 24px;\n        background-size: 240px 24px;\n    }\n}"
  },
  {
    "path": "public/static/plugins/input-mask/jquery.inputmask.date.extensions.js",
    "content": "/*\nInput Mask plugin extensions\nhttp://github.com/RobinHerbots/jquery.inputmask\nCopyright (c) 2010 - 2014 Robin Herbots\nLicensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)\nVersion: 0.0.0\n\nOptional extensions on the jquery.inputmask base\n*/\n(function ($) {\n    //date & time aliases\n    $.extend($.inputmask.defaults.definitions, {\n        'h': { //hours\n            validator: \"[01][0-9]|2[0-3]\",\n            cardinality: 2,\n            prevalidator: [{ validator: \"[0-2]\", cardinality: 1 }]\n        },\n        's': { //seconds || minutes\n            validator: \"[0-5][0-9]\",\n            cardinality: 2,\n            prevalidator: [{ validator: \"[0-5]\", cardinality: 1 }]\n        },\n        'd': { //basic day\n            validator: \"0[1-9]|[12][0-9]|3[01]\",\n            cardinality: 2,\n            prevalidator: [{ validator: \"[0-3]\", cardinality: 1 }]\n        },\n        'm': { //basic month\n            validator: \"0[1-9]|1[012]\",\n            cardinality: 2,\n            prevalidator: [{ validator: \"[01]\", cardinality: 1 }]\n        },\n        'y': { //basic year\n            validator: \"(19|20)\\\\d{2}\",\n            cardinality: 4,\n            prevalidator: [\n                        { validator: \"[12]\", cardinality: 1 },\n                        { validator: \"(19|20)\", cardinality: 2 },\n                        { validator: \"(19|20)\\\\d\", cardinality: 3 }\n            ]\n        }\n    });\n    $.extend($.inputmask.defaults.aliases, {\n        'dd/mm/yyyy': {\n            mask: \"1/2/y\",\n            placeholder: \"dd/mm/yyyy\",\n            regex: {\n                val1pre: new RegExp(\"[0-3]\"), //daypre\n                val1: new RegExp(\"0[1-9]|[12][0-9]|3[01]\"), //day\n                val2pre: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp(\"((0[1-9]|[12][0-9]|3[01])\" + escapedSeparator + \"[01])\"); }, //monthpre\n                val2: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp(\"((0[1-9]|[12][0-9])\" + escapedSeparator + \"(0[1-9]|1[012]))|(30\" + escapedSeparator + \"(0[13-9]|1[012]))|(31\" + escapedSeparator + \"(0[13578]|1[02]))\"); }//month\n            },\n            leapday: \"29/02/\",\n            separator: '/',\n            yearrange: { minyear: 1900, maxyear: 2099 },\n            isInYearRange: function (chrs, minyear, maxyear) {\n                var enteredyear = parseInt(chrs.concat(minyear.toString().slice(chrs.length)));\n                var enteredyear2 = parseInt(chrs.concat(maxyear.toString().slice(chrs.length)));\n                return (enteredyear != NaN ? minyear <= enteredyear && enteredyear <= maxyear : false) ||\n            \t\t   (enteredyear2 != NaN ? minyear <= enteredyear2 && enteredyear2 <= maxyear : false);\n            },\n            determinebaseyear: function (minyear, maxyear, hint) {\n                var currentyear = (new Date()).getFullYear();\n                if (minyear > currentyear) return minyear;\n                if (maxyear < currentyear) {\n                    var maxYearPrefix = maxyear.toString().slice(0, 2);\n                    var maxYearPostfix = maxyear.toString().slice(2, 4);\n                    while (maxyear < maxYearPrefix + hint) {\n                        maxYearPrefix--;\n                    }\n                    var maxxYear = maxYearPrefix + maxYearPostfix;\n                    return minyear > maxxYear ? minyear : maxxYear;\n                }\n\n                return currentyear;\n            },\n            onKeyUp: function (e, buffer, opts) {\n                var $input = $(this);\n                if (e.ctrlKey && e.keyCode == opts.keyCode.RIGHT) {\n                    var today = new Date();\n                    $input.val(today.getDate().toString() + (today.getMonth() + 1).toString() + today.getFullYear().toString());\n                }\n            },\n            definitions: {\n                '1': { //val1 ~ day or month\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        var isValid = opts.regex.val1.test(chrs);\n                        if (!strict && !isValid) {\n                            if (chrs.charAt(1) == opts.separator || \"-./\".indexOf(chrs.charAt(1)) != -1) {\n                                isValid = opts.regex.val1.test(\"0\" + chrs.charAt(0));\n                                if (isValid) {\n                                    buffer[pos - 1] = \"0\";\n                                    return { \"pos\": pos, \"c\": chrs.charAt(0) };\n                                }\n                            }\n                        }\n                        return isValid;\n                    },\n                    cardinality: 2,\n                    prevalidator: [{\n                        validator: function (chrs, buffer, pos, strict, opts) {\n                            var isValid = opts.regex.val1pre.test(chrs);\n                            if (!strict && !isValid) {\n                                isValid = opts.regex.val1.test(\"0\" + chrs);\n                                if (isValid) {\n                                    buffer[pos] = \"0\";\n                                    pos++;\n                                    return { \"pos\": pos };\n                                }\n                            }\n                            return isValid;\n                        }, cardinality: 1\n                    }]\n                },\n                '2': { //val2 ~ day or month\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        var frontValue = buffer.join('').substr(0, 3);\n                        if (frontValue.indexOf(opts.placeholder[0]) != -1) frontValue = \"01\" + opts.separator;\n                        var isValid = opts.regex.val2(opts.separator).test(frontValue + chrs);\n                        if (!strict && !isValid) {\n                            if (chrs.charAt(1) == opts.separator || \"-./\".indexOf(chrs.charAt(1)) != -1) {\n                                isValid = opts.regex.val2(opts.separator).test(frontValue + \"0\" + chrs.charAt(0));\n                                if (isValid) {\n                                    buffer[pos - 1] = \"0\";\n                                    return { \"pos\": pos, \"c\": chrs.charAt(0) };\n                                }\n                            }\n                        }\n                        return isValid;\n                    },\n                    cardinality: 2,\n                    prevalidator: [{\n                        validator: function (chrs, buffer, pos, strict, opts) {\n                            var frontValue = buffer.join('').substr(0, 3);\n                            if (frontValue.indexOf(opts.placeholder[0]) != -1) frontValue = \"01\" + opts.separator;\n                            var isValid = opts.regex.val2pre(opts.separator).test(frontValue + chrs);\n                            if (!strict && !isValid) {\n                                isValid = opts.regex.val2(opts.separator).test(frontValue + \"0\" + chrs);\n                                if (isValid) {\n                                    buffer[pos] = \"0\";\n                                    pos++;\n                                    return { \"pos\": pos };\n                                }\n                            }\n                            return isValid;\n                        }, cardinality: 1\n                    }]\n                },\n                'y': { //year\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        if (opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) {\n                            var dayMonthValue = buffer.join('').substr(0, 6);\n                            if (dayMonthValue != opts.leapday)\n                                return true;\n                            else {\n                                var year = parseInt(chrs, 10);//detect leap year\n                                if (year % 4 === 0)\n                                    if (year % 100 === 0)\n                                        if (year % 400 === 0)\n                                            return true;\n                                        else return false;\n                                    else return true;\n                                else return false;\n                            }\n                        } else return false;\n                    },\n                    cardinality: 4,\n                    prevalidator: [\n                {\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        var isValid = opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear);\n                        if (!strict && !isValid) {\n                            var yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs + \"0\").toString().slice(0, 1);\n\n                            isValid = opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear);\n                            if (isValid) {\n                                buffer[pos++] = yearPrefix[0];\n                                return { \"pos\": pos };\n                            }\n                            yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs + \"0\").toString().slice(0, 2);\n\n                            isValid = opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear);\n                            if (isValid) {\n                                buffer[pos++] = yearPrefix[0];\n                                buffer[pos++] = yearPrefix[1];\n                                return { \"pos\": pos };\n                            }\n                        }\n                        return isValid;\n                    },\n                    cardinality: 1\n                },\n                {\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        var isValid = opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear);\n                        if (!strict && !isValid) {\n                            var yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs).toString().slice(0, 2);\n\n                            isValid = opts.isInYearRange(chrs[0] + yearPrefix[1] + chrs[1], opts.yearrange.minyear, opts.yearrange.maxyear);\n                            if (isValid) {\n                                buffer[pos++] = yearPrefix[1];\n                                return { \"pos\": pos };\n                            }\n\n                            yearPrefix = opts.determinebaseyear(opts.yearrange.minyear, opts.yearrange.maxyear, chrs).toString().slice(0, 2);\n                            if (opts.isInYearRange(yearPrefix + chrs, opts.yearrange.minyear, opts.yearrange.maxyear)) {\n                                var dayMonthValue = buffer.join('').substr(0, 6);\n                                if (dayMonthValue != opts.leapday)\n                                    isValid = true;\n                                else {\n                                    var year = parseInt(chrs, 10);//detect leap year\n                                    if (year % 4 === 0)\n                                        if (year % 100 === 0)\n                                            if (year % 400 === 0)\n                                                isValid = true;\n                                            else isValid = false;\n                                        else isValid = true;\n                                    else isValid = false;\n                                }\n                            } else isValid = false;\n                            if (isValid) {\n                                buffer[pos - 1] = yearPrefix[0];\n                                buffer[pos++] = yearPrefix[1];\n                                buffer[pos++] = chrs[0];\n                                return { \"pos\": pos };\n                            }\n                        }\n                        return isValid;\n                    }, cardinality: 2\n                },\n                {\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        return opts.isInYearRange(chrs, opts.yearrange.minyear, opts.yearrange.maxyear);\n                    }, cardinality: 3\n                }\n                    ]\n                }\n            },\n            insertMode: false,\n            autoUnmask: false\n        },\n        'mm/dd/yyyy': {\n            placeholder: \"mm/dd/yyyy\",\n            alias: \"dd/mm/yyyy\", //reuse functionality of dd/mm/yyyy alias\n            regex: {\n                val2pre: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp(\"((0[13-9]|1[012])\" + escapedSeparator + \"[0-3])|(02\" + escapedSeparator + \"[0-2])\"); }, //daypre\n                val2: function (separator) { var escapedSeparator = $.inputmask.escapeRegex.call(this, separator); return new RegExp(\"((0[1-9]|1[012])\" + escapedSeparator + \"(0[1-9]|[12][0-9]))|((0[13-9]|1[012])\" + escapedSeparator + \"30)|((0[13578]|1[02])\" + escapedSeparator + \"31)\"); }, //day\n                val1pre: new RegExp(\"[01]\"), //monthpre\n                val1: new RegExp(\"0[1-9]|1[012]\") //month\n            },\n            leapday: \"02/29/\",\n            onKeyUp: function (e, buffer, opts) {\n                var $input = $(this);\n                if (e.ctrlKey && e.keyCode == opts.keyCode.RIGHT) {\n                    var today = new Date();\n                    $input.val((today.getMonth() + 1).toString() + today.getDate().toString() + today.getFullYear().toString());\n                }\n            }\n        },\n        'yyyy/mm/dd': {\n            mask: \"y/1/2\",\n            placeholder: \"yyyy/mm/dd\",\n            alias: \"mm/dd/yyyy\",\n            leapday: \"/02/29\",\n            onKeyUp: function (e, buffer, opts) {\n                var $input = $(this);\n                if (e.ctrlKey && e.keyCode == opts.keyCode.RIGHT) {\n                    var today = new Date();\n                    $input.val(today.getFullYear().toString() + (today.getMonth() + 1).toString() + today.getDate().toString());\n                }\n            },\n            definitions: {\n                '2': { //val2 ~ day or month\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        var frontValue = buffer.join('').substr(5, 3);\n                        if (frontValue.indexOf(opts.placeholder[5]) != -1) frontValue = \"01\" + opts.separator;\n                        var isValid = opts.regex.val2(opts.separator).test(frontValue + chrs);\n                        if (!strict && !isValid) {\n                            if (chrs.charAt(1) == opts.separator || \"-./\".indexOf(chrs.charAt(1)) != -1) {\n                                isValid = opts.regex.val2(opts.separator).test(frontValue + \"0\" + chrs.charAt(0));\n                                if (isValid) {\n                                    buffer[pos - 1] = \"0\";\n                                    return { \"pos\": pos, \"c\": chrs.charAt(0) };\n                                }\n                            }\n                        }\n\n                        //check leap yeap\n                        if (isValid) {\n                            var dayMonthValue = buffer.join('').substr(4, 4) + chrs;\n                            if (dayMonthValue != opts.leapday)\n                                return true;\n                            else {\n                                var year = parseInt(buffer.join('').substr(0, 4), 10);  //detect leap year\n                                if (year % 4 === 0)\n                                    if (year % 100 === 0)\n                                        if (year % 400 === 0)\n                                            return true;\n                                        else return false;\n                                    else return true;\n                                else return false;\n                            }\n                        }\n\n                        return isValid;\n                    },\n                    cardinality: 2,\n                    prevalidator: [{\n                        validator: function (chrs, buffer, pos, strict, opts) {\n                            var frontValue = buffer.join('').substr(5, 3);\n                            if (frontValue.indexOf(opts.placeholder[5]) != -1) frontValue = \"01\" + opts.separator;\n                            var isValid = opts.regex.val2pre(opts.separator).test(frontValue + chrs);\n                            if (!strict && !isValid) {\n                                isValid = opts.regex.val2(opts.separator).test(frontValue + \"0\" + chrs);\n                                if (isValid) {\n                                    buffer[pos] = \"0\";\n                                    pos++;\n                                    return { \"pos\": pos };\n                                }\n                            }\n                            return isValid;\n                        }, cardinality: 1\n                    }]\n                }\n            }\n        },\n        'dd.mm.yyyy': {\n            mask: \"1.2.y\",\n            placeholder: \"dd.mm.yyyy\",\n            leapday: \"29.02.\",\n            separator: '.',\n            alias: \"dd/mm/yyyy\"\n        },\n        'dd-mm-yyyy': {\n            mask: \"1-2-y\",\n            placeholder: \"dd-mm-yyyy\",\n            leapday: \"29-02-\",\n            separator: '-',\n            alias: \"dd/mm/yyyy\"\n        },\n        'mm.dd.yyyy': {\n            mask: \"1.2.y\",\n            placeholder: \"mm.dd.yyyy\",\n            leapday: \"02.29.\",\n            separator: '.',\n            alias: \"mm/dd/yyyy\"\n        },\n        'mm-dd-yyyy': {\n            mask: \"1-2-y\",\n            placeholder: \"mm-dd-yyyy\",\n            leapday: \"02-29-\",\n            separator: '-',\n            alias: \"mm/dd/yyyy\"\n        },\n        'yyyy.mm.dd': {\n            mask: \"y.1.2\",\n            placeholder: \"yyyy.mm.dd\",\n            leapday: \".02.29\",\n            separator: '.',\n            alias: \"yyyy/mm/dd\"\n        },\n        'yyyy-mm-dd': {\n            mask: \"y-1-2\",\n            placeholder: \"yyyy-mm-dd\",\n            leapday: \"-02-29\",\n            separator: '-',\n            alias: \"yyyy/mm/dd\"\n        },\n        'datetime': {\n            mask: \"1/2/y h:s\",\n            placeholder: \"dd/mm/yyyy hh:mm\",\n            alias: \"dd/mm/yyyy\",\n            regex: {\n                hrspre: new RegExp(\"[012]\"), //hours pre\n                hrs24: new RegExp(\"2[0-9]|1[3-9]\"),\n                hrs: new RegExp(\"[01][0-9]|2[0-3]\"), //hours\n                ampm: new RegExp(\"^[a|p|A|P][m|M]\")\n            },\n            timeseparator: ':',\n            hourFormat: \"24\", // or 12\n            definitions: {\n                'h': { //hours\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        var isValid = opts.regex.hrs.test(chrs);\n                        if (!strict && !isValid) {\n                            if (chrs.charAt(1) == opts.timeseparator || \"-.:\".indexOf(chrs.charAt(1)) != -1) {\n                                isValid = opts.regex.hrs.test(\"0\" + chrs.charAt(0));\n                                if (isValid) {\n                                    buffer[pos - 1] = \"0\";\n                                    buffer[pos] = chrs.charAt(0);\n                                    pos++;\n                                    return { \"pos\": pos };\n                                }\n                            }\n                        }\n\n                        if (isValid && opts.hourFormat !== \"24\" && opts.regex.hrs24.test(chrs)) {\n\n                            var tmp = parseInt(chrs, 10);\n\n                            if (tmp == 24) {\n                                buffer[pos + 5] = \"a\";\n                                buffer[pos + 6] = \"m\";\n                            } else {\n                                buffer[pos + 5] = \"p\";\n                                buffer[pos + 6] = \"m\";\n                            }\n\n                            tmp = tmp - 12;\n\n                            if (tmp < 10) {\n                                buffer[pos] = tmp.toString();\n                                buffer[pos - 1] = \"0\";\n                            } else {\n                                buffer[pos] = tmp.toString().charAt(1);\n                                buffer[pos - 1] = tmp.toString().charAt(0);\n                            }\n\n                            return { \"pos\": pos, \"c\": buffer[pos] };\n                        }\n\n                        return isValid;\n                    },\n                    cardinality: 2,\n                    prevalidator: [{\n                        validator: function (chrs, buffer, pos, strict, opts) {\n                            var isValid = opts.regex.hrspre.test(chrs);\n                            if (!strict && !isValid) {\n                                isValid = opts.regex.hrs.test(\"0\" + chrs);\n                                if (isValid) {\n                                    buffer[pos] = \"0\";\n                                    pos++;\n                                    return { \"pos\": pos };\n                                }\n                            }\n                            return isValid;\n                        }, cardinality: 1\n                    }]\n                },\n                't': { //am/pm\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        return opts.regex.ampm.test(chrs + \"m\");\n                    },\n                    casing: \"lower\",\n                    cardinality: 1\n                }\n            },\n            insertMode: false,\n            autoUnmask: false\n        },\n        'datetime12': {\n            mask: \"1/2/y h:s t\\\\m\",\n            placeholder: \"dd/mm/yyyy hh:mm xm\",\n            alias: \"datetime\",\n            hourFormat: \"12\"\n        },\n        'hh:mm t': {\n            mask: \"h:s t\\\\m\",\n            placeholder: \"hh:mm xm\",\n            alias: \"datetime\",\n            hourFormat: \"12\"\n        },\n        'h:s t': {\n            mask: \"h:s t\\\\m\",\n            placeholder: \"hh:mm xm\",\n            alias: \"datetime\",\n            hourFormat: \"12\"\n        },\n        'hh:mm:ss': {\n            mask: \"h:s:s\",\n            autoUnmask: false\n        },\n        'hh:mm': {\n            mask: \"h:s\",\n            autoUnmask: false\n        },\n        'date': {\n            alias: \"dd/mm/yyyy\" // \"mm/dd/yyyy\"\n        },\n        'mm/yyyy': {\n            mask: \"1/y\",\n            placeholder: \"mm/yyyy\",\n            leapday: \"donotuse\",\n            separator: '/',\n            alias: \"mm/dd/yyyy\"\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/input-mask/jquery.inputmask.extensions.js",
    "content": "/*\nInput Mask plugin extensions\nhttp://github.com/RobinHerbots/jquery.inputmask\nCopyright (c) 2010 - 2014 Robin Herbots\nLicensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)\nVersion: 0.0.0\n\nOptional extensions on the jquery.inputmask base\n*/\n(function ($) {\n    //extra definitions\n    $.extend($.inputmask.defaults.definitions, {\n        'A': {\n            validator: \"[A-Za-z]\",\n            cardinality: 1,\n            casing: \"upper\" //auto uppercasing\n        },\n        '#': {\n            validator: \"[A-Za-z\\u0410-\\u044F\\u0401\\u04510-9]\",\n            cardinality: 1,\n            casing: \"upper\"\n        }\n    });\n    $.extend($.inputmask.defaults.aliases, {\n        'url': {\n            mask: \"ir\",\n            placeholder: \"\",\n            separator: \"\",\n            defaultPrefix: \"http://\",\n            regex: {\n                urlpre1: new RegExp(\"[fh]\"),\n                urlpre2: new RegExp(\"(ft|ht)\"),\n                urlpre3: new RegExp(\"(ftp|htt)\"),\n                urlpre4: new RegExp(\"(ftp:|http|ftps)\"),\n                urlpre5: new RegExp(\"(ftp:/|ftps:|http:|https)\"),\n                urlpre6: new RegExp(\"(ftp://|ftps:/|http:/|https:)\"),\n                urlpre7: new RegExp(\"(ftp://|ftps://|http://|https:/)\"),\n                urlpre8: new RegExp(\"(ftp://|ftps://|http://|https://)\")\n            },\n            definitions: {\n                'i': {\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        return true;\n                    },\n                    cardinality: 8,\n                    prevalidator: (function () {\n                        var result = [], prefixLimit = 8;\n                        for (var i = 0; i < prefixLimit; i++) {\n                            result[i] = (function () {\n                                var j = i;\n                                return {\n                                    validator: function (chrs, buffer, pos, strict, opts) {\n                                        if (opts.regex[\"urlpre\" + (j + 1)]) {\n                                            var tmp = chrs, k;\n                                            if (((j + 1) - chrs.length) > 0) {\n                                                tmp = buffer.join('').substring(0, ((j + 1) - chrs.length)) + \"\" + tmp;\n                                            }\n                                            var isValid = opts.regex[\"urlpre\" + (j + 1)].test(tmp);\n                                            if (!strict && !isValid) {\n                                                pos = pos - j;\n                                                for (k = 0; k < opts.defaultPrefix.length; k++) {\n                                                    buffer[pos] = opts.defaultPrefix[k]; pos++;\n                                                }\n                                                for (k = 0; k < tmp.length - 1; k++) {\n                                                    buffer[pos] = tmp[k]; pos++;\n                                                }\n                                                return { \"pos\": pos };\n                                            }\n                                            return isValid;\n                                        } else {\n                                            return false;\n                                        }\n                                    }, cardinality: j\n                                };\n                            })();\n                        }\n                        return result;\n                    })()\n                },\n                \"r\": {\n                    validator: \".\",\n                    cardinality: 50\n                }\n            },\n            insertMode: false,\n            autoUnmask: false\n        },\n        \"ip\": { //ip-address mask\n            mask: [\"[[x]y]z.[[x]y]z.[[x]y]z.x[yz]\", \"[[x]y]z.[[x]y]z.[[x]y]z.[[x]y][z]\"],\n            definitions: {\n                'x': {\n                    validator: \"[012]\",\n                    cardinality: 1,\n                    definitionSymbol: \"i\"\n                },\n                'y': {\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        if (pos - 1 > -1 && buffer[pos - 1] != \".\")\n                            chrs = buffer[pos - 1] + chrs;\n                        else chrs = \"0\" + chrs;\n                        return new RegExp(\"2[0-5]|[01][0-9]\").test(chrs);\n                    },\n                    cardinality: 1,\n                    definitionSymbol: \"i\"\n                },\n                'z': {\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        if (pos - 1 > -1 && buffer[pos - 1] != \".\") {\n                            chrs = buffer[pos - 1] + chrs;\n                            if (pos - 2 > -1 && buffer[pos - 2] != \".\") {\n                                chrs = buffer[pos - 2] + chrs;\n                            } else chrs = \"0\" + chrs;\n                        } else chrs = \"00\" + chrs;\n                        return new RegExp(\"25[0-5]|2[0-4][0-9]|[01][0-9][0-9]\").test(chrs);\n                    },\n                    cardinality: 1,\n                    definitionSymbol: \"i\"\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/input-mask/jquery.inputmask.js",
    "content": "/**\n* @license Input Mask plugin for jquery\n* http://github.com/RobinHerbots/jquery.inputmask\n* Copyright (c) 2010 - 2014 Robin Herbots\n* Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)\n* Version: 0.0.0\n*/\n\n(function ($) {\n    if ($.fn.inputmask === undefined) {\n        //helper functions    \n        function isInputEventSupported(eventName) {\n            var el = document.createElement('input'),\n            eventName = 'on' + eventName,\n            isSupported = (eventName in el);\n            if (!isSupported) {\n                el.setAttribute(eventName, 'return;');\n                isSupported = typeof el[eventName] == 'function';\n            }\n            el = null;\n            return isSupported;\n        }\n        function resolveAlias(aliasStr, options, opts) {\n            var aliasDefinition = opts.aliases[aliasStr];\n            if (aliasDefinition) {\n                if (aliasDefinition.alias) resolveAlias(aliasDefinition.alias, undefined, opts); //alias is another alias\n                $.extend(true, opts, aliasDefinition);  //merge alias definition in the options\n                $.extend(true, opts, options);  //reapply extra given options\n                return true;\n            }\n            return false;\n        }\n        function generateMaskSets(opts) {\n            var ms = [];\n            var genmasks = []; //used to keep track of the masks that where processed, to avoid duplicates\n            function getMaskTemplate(mask) {\n                if (opts.numericInput) {\n                    mask = mask.split('').reverse().join('');\n                }\n                var escaped = false, outCount = 0, greedy = opts.greedy, repeat = opts.repeat;\n                if (repeat == \"*\") greedy = false;\n                //if (greedy == true && opts.placeholder == \"\") opts.placeholder = \" \";\n                if (mask.length == 1 && greedy == false && repeat != 0) { opts.placeholder = \"\"; } //hide placeholder with single non-greedy mask\n                var singleMask = $.map(mask.split(\"\"), function (element, index) {\n                    var outElem = [];\n                    if (element == opts.escapeChar) {\n                        escaped = true;\n                    }\n                    else if ((element != opts.optionalmarker.start && element != opts.optionalmarker.end) || escaped) {\n                        var maskdef = opts.definitions[element];\n                        if (maskdef && !escaped) {\n                            for (var i = 0; i < maskdef.cardinality; i++) {\n                                outElem.push(opts.placeholder.charAt((outCount + i) % opts.placeholder.length));\n                            }\n                        } else {\n                            outElem.push(element);\n                            escaped = false;\n                        }\n                        outCount += outElem.length;\n                        return outElem;\n                    }\n                });\n\n                //allocate repetitions\n                var repeatedMask = singleMask.slice();\n                for (var i = 1; i < repeat && greedy; i++) {\n                    repeatedMask = repeatedMask.concat(singleMask.slice());\n                }\n\n                return { \"mask\": repeatedMask, \"repeat\": repeat, \"greedy\": greedy };\n            }\n            //test definition => {fn: RegExp/function, cardinality: int, optionality: bool, newBlockMarker: bool, offset: int, casing: null/upper/lower, def: definitionSymbol}\n            function getTestingChain(mask) {\n                if (opts.numericInput) {\n                    mask = mask.split('').reverse().join('');\n                }\n                var isOptional = false, escaped = false;\n                var newBlockMarker = false; //indicates wheter the begin/ending of a block should be indicated\n\n                return $.map(mask.split(\"\"), function (element, index) {\n                    var outElem = [];\n\n                    if (element == opts.escapeChar) {\n                        escaped = true;\n                    } else if (element == opts.optionalmarker.start && !escaped) {\n                        isOptional = true;\n                        newBlockMarker = true;\n                    }\n                    else if (element == opts.optionalmarker.end && !escaped) {\n                        isOptional = false;\n                        newBlockMarker = true;\n                    }\n                    else {\n                        var maskdef = opts.definitions[element];\n                        if (maskdef && !escaped) {\n                            var prevalidators = maskdef[\"prevalidator\"], prevalidatorsL = prevalidators ? prevalidators.length : 0;\n                            for (var i = 1; i < maskdef.cardinality; i++) {\n                                var prevalidator = prevalidatorsL >= i ? prevalidators[i - 1] : [], validator = prevalidator[\"validator\"], cardinality = prevalidator[\"cardinality\"];\n                                outElem.push({ fn: validator ? typeof validator == 'string' ? new RegExp(validator) : new function () { this.test = validator; } : new RegExp(\".\"), cardinality: cardinality ? cardinality : 1, optionality: isOptional, newBlockMarker: isOptional == true ? newBlockMarker : false, offset: 0, casing: maskdef[\"casing\"], def: maskdef[\"definitionSymbol\"] || element });\n                                if (isOptional == true) //reset newBlockMarker\n                                    newBlockMarker = false;\n                            }\n                            outElem.push({ fn: maskdef.validator ? typeof maskdef.validator == 'string' ? new RegExp(maskdef.validator) : new function () { this.test = maskdef.validator; } : new RegExp(\".\"), cardinality: maskdef.cardinality, optionality: isOptional, newBlockMarker: newBlockMarker, offset: 0, casing: maskdef[\"casing\"], def: maskdef[\"definitionSymbol\"] || element });\n                        } else {\n                            outElem.push({ fn: null, cardinality: 0, optionality: isOptional, newBlockMarker: newBlockMarker, offset: 0, casing: null, def: element });\n                            escaped = false;\n                        }\n                        //reset newBlockMarker\n                        newBlockMarker = false;\n                        return outElem;\n                    }\n                });\n            }\n            function markOptional(maskPart) { //needed for the clearOptionalTail functionality\n                return opts.optionalmarker.start + maskPart + opts.optionalmarker.end;\n            }\n            function splitFirstOptionalEndPart(maskPart) {\n                var optionalStartMarkers = 0, optionalEndMarkers = 0, mpl = maskPart.length;\n                for (var i = 0; i < mpl; i++) {\n                    if (maskPart.charAt(i) == opts.optionalmarker.start) {\n                        optionalStartMarkers++;\n                    }\n                    if (maskPart.charAt(i) == opts.optionalmarker.end) {\n                        optionalEndMarkers++;\n                    }\n                    if (optionalStartMarkers > 0 && optionalStartMarkers == optionalEndMarkers)\n                        break;\n                }\n                var maskParts = [maskPart.substring(0, i)];\n                if (i < mpl) {\n                    maskParts.push(maskPart.substring(i + 1, mpl));\n                }\n                return maskParts;\n            }\n            function splitFirstOptionalStartPart(maskPart) {\n                var mpl = maskPart.length;\n                for (var i = 0; i < mpl; i++) {\n                    if (maskPart.charAt(i) == opts.optionalmarker.start) {\n                        break;\n                    }\n                }\n                var maskParts = [maskPart.substring(0, i)];\n                if (i < mpl) {\n                    maskParts.push(maskPart.substring(i + 1, mpl));\n                }\n                return maskParts;\n            }\n            function generateMask(maskPrefix, maskPart, metadata) {\n                var maskParts = splitFirstOptionalEndPart(maskPart);\n                var newMask, maskTemplate;\n\n                var masks = splitFirstOptionalStartPart(maskParts[0]);\n                if (masks.length > 1) {\n                    newMask = maskPrefix + masks[0] + markOptional(masks[1]) + (maskParts.length > 1 ? maskParts[1] : \"\");\n                    if ($.inArray(newMask, genmasks) == -1 && newMask != \"\") {\n                        genmasks.push(newMask);\n                        maskTemplate = getMaskTemplate(newMask);\n                        ms.push({\n                            \"mask\": newMask,\n                            \"_buffer\": maskTemplate[\"mask\"],\n                            \"buffer\": maskTemplate[\"mask\"].slice(),\n                            \"tests\": getTestingChain(newMask),\n                            \"lastValidPosition\": -1,\n                            \"greedy\": maskTemplate[\"greedy\"],\n                            \"repeat\": maskTemplate[\"repeat\"],\n                            \"metadata\": metadata\n                        });\n                    }\n                    newMask = maskPrefix + masks[0] + (maskParts.length > 1 ? maskParts[1] : \"\");\n                    if ($.inArray(newMask, genmasks) == -1 && newMask != \"\") {\n                        genmasks.push(newMask);\n                        maskTemplate = getMaskTemplate(newMask);\n                        ms.push({\n                            \"mask\": newMask,\n                            \"_buffer\": maskTemplate[\"mask\"],\n                            \"buffer\": maskTemplate[\"mask\"].slice(),\n                            \"tests\": getTestingChain(newMask),\n                            \"lastValidPosition\": -1,\n                            \"greedy\": maskTemplate[\"greedy\"],\n                            \"repeat\": maskTemplate[\"repeat\"],\n                            \"metadata\": metadata\n                        });\n                    }\n                    if (splitFirstOptionalStartPart(masks[1]).length > 1) { //optional contains another optional\n                        generateMask(maskPrefix + masks[0], masks[1] + maskParts[1], metadata);\n                    }\n                    if (maskParts.length > 1 && splitFirstOptionalStartPart(maskParts[1]).length > 1) {\n                        generateMask(maskPrefix + masks[0] + markOptional(masks[1]), maskParts[1], metadata);\n                        generateMask(maskPrefix + masks[0], maskParts[1], metadata);\n                    }\n                }\n                else {\n                    newMask = maskPrefix + maskParts;\n                    if ($.inArray(newMask, genmasks) == -1 && newMask != \"\") {\n                        genmasks.push(newMask);\n                        maskTemplate = getMaskTemplate(newMask);\n                        ms.push({\n                            \"mask\": newMask,\n                            \"_buffer\": maskTemplate[\"mask\"],\n                            \"buffer\": maskTemplate[\"mask\"].slice(),\n                            \"tests\": getTestingChain(newMask),\n                            \"lastValidPosition\": -1,\n                            \"greedy\": maskTemplate[\"greedy\"],\n                            \"repeat\": maskTemplate[\"repeat\"],\n                            \"metadata\": metadata\n                        });\n                    }\n                }\n\n            }\n\n            if ($.isFunction(opts.mask)) { //allow mask to be a preprocessing fn - should return a valid mask\n                opts.mask = opts.mask.call(this, opts);\n            }\n            if ($.isArray(opts.mask)) {\n                $.each(opts.mask, function (ndx, msk) {\n                    if (msk[\"mask\"] != undefined) {\n                        generateMask(\"\", msk[\"mask\"].toString(), msk);\n                    } else\n                        generateMask(\"\", msk.toString());\n                });\n            } else generateMask(\"\", opts.mask.toString());\n\n            return opts.greedy ? ms : ms.sort(function (a, b) { return a[\"mask\"].length - b[\"mask\"].length; });\n        }\n\n        var msie10 = navigator.userAgent.match(new RegExp(\"msie 10\", \"i\")) !== null,\n            iphone = navigator.userAgent.match(new RegExp(\"iphone\", \"i\")) !== null,\n            android = navigator.userAgent.match(new RegExp(\"android.*safari.*\", \"i\")) !== null,\n            androidchrome = navigator.userAgent.match(new RegExp(\"android.*chrome.*\", \"i\")) !== null,\n            pasteEvent = isInputEventSupported('paste') ? 'paste' : isInputEventSupported('input') ? 'input' : \"propertychange\";\n\n\n        //masking scope\n        //actionObj definition see below\n        function maskScope(masksets, activeMasksetIndex, opts, actionObj) {\n            var isRTL = false,\n                valueOnFocus = getActiveBuffer().join(''),\n                $el, chromeValueOnInput,\n                skipKeyPressEvent = false, //Safari 5.1.x - modal dialog fires keypress twice workaround\n                skipInputEvent = false, //skip when triggered from within inputmask\n                ignorable = false;\n\n\n            //maskset helperfunctions\n\n            function getActiveMaskSet() {\n                return masksets[activeMasksetIndex];\n            }\n\n            function getActiveTests() {\n                return getActiveMaskSet()['tests'];\n            }\n\n            function getActiveBufferTemplate() {\n                return getActiveMaskSet()['_buffer'];\n            }\n\n            function getActiveBuffer() {\n                return getActiveMaskSet()['buffer'];\n            }\n\n            function isValid(pos, c, strict) { //strict true ~ no correction or autofill\n                strict = strict === true; //always set a value to strict to prevent possible strange behavior in the extensions \n\n                function _isValid(position, activeMaskset, c, strict) {\n                    var testPos = determineTestPosition(position), loopend = c ? 1 : 0, chrs = '', buffer = activeMaskset[\"buffer\"];\n                    for (var i = activeMaskset['tests'][testPos].cardinality; i > loopend; i--) {\n                        chrs += getBufferElement(buffer, testPos - (i - 1));\n                    }\n\n                    if (c) {\n                        chrs += c;\n                    }\n\n                    //return is false or a json object => { pos: ??, c: ??} or true\n                    return activeMaskset['tests'][testPos].fn != null ?\n                        activeMaskset['tests'][testPos].fn.test(chrs, buffer, position, strict, opts)\n                        : (c == getBufferElement(activeMaskset['_buffer'], position, true) || c == opts.skipOptionalPartCharacter) ?\n                            { \"refresh\": true, c: getBufferElement(activeMaskset['_buffer'], position, true), pos: position }\n                            : false;\n                }\n\n                function PostProcessResults(maskForwards, results) {\n                    var hasValidActual = false;\n                    $.each(results, function (ndx, rslt) {\n                        hasValidActual = $.inArray(rslt[\"activeMasksetIndex\"], maskForwards) == -1 && rslt[\"result\"] !== false;\n                        if (hasValidActual) return false;\n                    });\n                    if (hasValidActual) { //strip maskforwards\n                        results = $.map(results, function (rslt, ndx) {\n                            if ($.inArray(rslt[\"activeMasksetIndex\"], maskForwards) == -1) {\n                                return rslt;\n                            } else {\n                                masksets[rslt[\"activeMasksetIndex\"]][\"lastValidPosition\"] = actualLVP;\n                            }\n                        });\n                    } else { //keep maskforwards with the least forward\n                        var lowestPos = -1, lowestIndex = -1, rsltValid;\n                        $.each(results, function (ndx, rslt) {\n                            if ($.inArray(rslt[\"activeMasksetIndex\"], maskForwards) != -1 && rslt[\"result\"] !== false & (lowestPos == -1 || lowestPos > rslt[\"result\"][\"pos\"])) {\n                                lowestPos = rslt[\"result\"][\"pos\"];\n                                lowestIndex = rslt[\"activeMasksetIndex\"];\n                            }\n                        });\n                        results = $.map(results, function (rslt, ndx) {\n                            if ($.inArray(rslt[\"activeMasksetIndex\"], maskForwards) != -1) {\n                                if (rslt[\"result\"][\"pos\"] == lowestPos) {\n                                    return rslt;\n                                } else if (rslt[\"result\"] !== false) {\n                                    for (var i = pos; i < lowestPos; i++) {\n                                        rsltValid = _isValid(i, masksets[rslt[\"activeMasksetIndex\"]], masksets[lowestIndex][\"buffer\"][i], true);\n                                        if (rsltValid === false) {\n                                            masksets[rslt[\"activeMasksetIndex\"]][\"lastValidPosition\"] = lowestPos - 1;\n                                            break;\n                                        } else {\n                                            setBufferElement(masksets[rslt[\"activeMasksetIndex\"]][\"buffer\"], i, masksets[lowestIndex][\"buffer\"][i], true);\n                                            masksets[rslt[\"activeMasksetIndex\"]][\"lastValidPosition\"] = i;\n                                        }\n                                    }\n                                    //also check check for the lowestpos with the new input\n                                    rsltValid = _isValid(lowestPos, masksets[rslt[\"activeMasksetIndex\"]], c, true);\n                                    if (rsltValid !== false) {\n                                        setBufferElement(masksets[rslt[\"activeMasksetIndex\"]][\"buffer\"], lowestPos, c, true);\n                                        masksets[rslt[\"activeMasksetIndex\"]][\"lastValidPosition\"] = lowestPos;\n                                    }\n                                    //console.log(\"ndx \" + rslt[\"activeMasksetIndex\"] + \" validate \" + masksets[rslt[\"activeMasksetIndex\"]][\"buffer\"].join('') + \" lv \" + masksets[rslt[\"activeMasksetIndex\"]]['lastValidPosition']);\n                                    return rslt;\n                                }\n                            }\n                        });\n                    }\n                    return results;\n                }\n\n                if (strict) {\n                    var result = _isValid(pos, getActiveMaskSet(), c, strict); //only check validity in current mask when validating strict\n                    if (result === true) {\n                        result = { \"pos\": pos }; //always take a possible corrected maskposition into account\n                    }\n                    return result;\n                }\n\n                var results = [], result = false, currentActiveMasksetIndex = activeMasksetIndex,\n                    actualBuffer = getActiveBuffer().slice(), actualLVP = getActiveMaskSet()[\"lastValidPosition\"],\n                    actualPrevious = seekPrevious(pos),\n                    maskForwards = [];\n                $.each(masksets, function (index, value) {\n                    if (typeof (value) == \"object\") {\n                        activeMasksetIndex = index;\n\n                        var maskPos = pos;\n                        var lvp = getActiveMaskSet()['lastValidPosition'],\n                            rsltValid;\n                        if (lvp == actualLVP) {\n                            if ((maskPos - actualLVP) > 1) {\n                                for (var i = lvp == -1 ? 0 : lvp; i < maskPos; i++) {\n                                    rsltValid = _isValid(i, getActiveMaskSet(), actualBuffer[i], true);\n                                    if (rsltValid === false) {\n                                        break;\n                                    } else {\n                                        setBufferElement(getActiveBuffer(), i, actualBuffer[i], true);\n                                        if (rsltValid === true) {\n                                            rsltValid = { \"pos\": i }; //always take a possible corrected maskposition into account\n                                        }\n                                        var newValidPosition = rsltValid.pos || i;\n                                        if (getActiveMaskSet()['lastValidPosition'] < newValidPosition)\n                                            getActiveMaskSet()['lastValidPosition'] = newValidPosition; //set new position from isValid\n                                    }\n                                }\n                            }\n                            //does the input match on a further position?\n                            if (!isMask(maskPos) && !_isValid(maskPos, getActiveMaskSet(), c, strict)) {\n                                var maxForward = seekNext(maskPos) - maskPos;\n                                for (var fw = 0; fw < maxForward; fw++) {\n                                    if (_isValid(++maskPos, getActiveMaskSet(), c, strict) !== false)\n                                        break;\n                                }\n                                maskForwards.push(activeMasksetIndex);\n                                //console.log('maskforward ' + activeMasksetIndex + \" pos \" + pos + \" maskPos \" + maskPos);\n                            }\n                        }\n\n                        if (getActiveMaskSet()['lastValidPosition'] >= actualLVP || activeMasksetIndex == currentActiveMasksetIndex) {\n                            if (maskPos >= 0 && maskPos < getMaskLength()) {\n                                result = _isValid(maskPos, getActiveMaskSet(), c, strict);\n                                if (result !== false) {\n                                    if (result === true) {\n                                        result = { \"pos\": maskPos }; //always take a possible corrected maskposition into account\n                                    }\n                                    var newValidPosition = result.pos || maskPos;\n                                    if (getActiveMaskSet()['lastValidPosition'] < newValidPosition)\n                                        getActiveMaskSet()['lastValidPosition'] = newValidPosition; //set new position from isValid\n                                }\n                                //console.log(\"pos \" + pos + \" ndx \" + activeMasksetIndex + \" validate \" + getActiveBuffer().join('') + \" lv \" + getActiveMaskSet()['lastValidPosition']);\n                                results.push({ \"activeMasksetIndex\": index, \"result\": result });\n                            }\n                        }\n                    }\n                });\n                activeMasksetIndex = currentActiveMasksetIndex; //reset activeMasksetIndex\n\n                return PostProcessResults(maskForwards, results); //return results of the multiple mask validations\n            }\n\n            function determineActiveMasksetIndex() {\n                var currentMasksetIndex = activeMasksetIndex,\n                    highestValid = { \"activeMasksetIndex\": 0, \"lastValidPosition\": -1, \"next\": -1 };\n                $.each(masksets, function (index, value) {\n                    if (typeof (value) == \"object\") {\n                        activeMasksetIndex = index;\n                        if (getActiveMaskSet()['lastValidPosition'] > highestValid['lastValidPosition']) {\n                            highestValid[\"activeMasksetIndex\"] = index;\n                            highestValid[\"lastValidPosition\"] = getActiveMaskSet()['lastValidPosition'];\n                            highestValid[\"next\"] = seekNext(getActiveMaskSet()['lastValidPosition']);\n                        } else if (getActiveMaskSet()['lastValidPosition'] == highestValid['lastValidPosition'] &&\n                            (highestValid['next'] == -1 || highestValid['next'] > seekNext(getActiveMaskSet()['lastValidPosition']))) {\n                            highestValid[\"activeMasksetIndex\"] = index;\n                            highestValid[\"lastValidPosition\"] = getActiveMaskSet()['lastValidPosition'];\n                            highestValid[\"next\"] = seekNext(getActiveMaskSet()['lastValidPosition']);\n                        }\n                    }\n                });\n\n                activeMasksetIndex = highestValid[\"lastValidPosition\"] != -1 && masksets[currentMasksetIndex][\"lastValidPosition\"] == highestValid[\"lastValidPosition\"] ? currentMasksetIndex : highestValid[\"activeMasksetIndex\"];\n                if (currentMasksetIndex != activeMasksetIndex) {\n                    clearBuffer(getActiveBuffer(), seekNext(highestValid[\"lastValidPosition\"]), getMaskLength());\n                    getActiveMaskSet()[\"writeOutBuffer\"] = true;\n                }\n                $el.data('_inputmask')['activeMasksetIndex'] = activeMasksetIndex; //store the activeMasksetIndex\n            }\n\n            function isMask(pos) {\n                var testPos = determineTestPosition(pos);\n                var test = getActiveTests()[testPos];\n\n                return test != undefined ? test.fn : false;\n            }\n\n            function determineTestPosition(pos) {\n                return pos % getActiveTests().length;\n            }\n\n            function getMaskLength() {\n                return opts.getMaskLength(getActiveBufferTemplate(), getActiveMaskSet()['greedy'], getActiveMaskSet()['repeat'], getActiveBuffer(), opts);\n            }\n\n            //pos: from position\n\n            function seekNext(pos) {\n                var maskL = getMaskLength();\n                if (pos >= maskL) return maskL;\n                var position = pos;\n                while (++position < maskL && !isMask(position)) {\n                }\n                return position;\n            }\n\n            //pos: from position\n\n            function seekPrevious(pos) {\n                var position = pos;\n                if (position <= 0) return 0;\n\n                while (--position > 0 && !isMask(position)) {\n                }\n                return position;\n            }\n\n            function setBufferElement(buffer, position, element, autoPrepare) {\n                if (autoPrepare) position = prepareBuffer(buffer, position);\n\n                var test = getActiveTests()[determineTestPosition(position)];\n                var elem = element;\n                if (elem != undefined && test != undefined) {\n                    switch (test.casing) {\n                        case \"upper\":\n                            elem = element.toUpperCase();\n                            break;\n                        case \"lower\":\n                            elem = element.toLowerCase();\n                            break;\n                    }\n                }\n\n                buffer[position] = elem;\n            }\n\n            function getBufferElement(buffer, position, autoPrepare) {\n                if (autoPrepare) position = prepareBuffer(buffer, position);\n                return buffer[position];\n            }\n\n            //needed to handle the non-greedy mask repetitions\n\n            function prepareBuffer(buffer, position) {\n                var j;\n                while (buffer[position] == undefined && buffer.length < getMaskLength()) {\n                    j = 0;\n                    while (getActiveBufferTemplate()[j] !== undefined) { //add a new buffer\n                        buffer.push(getActiveBufferTemplate()[j++]);\n                    }\n                }\n\n                return position;\n            }\n\n            function writeBuffer(input, buffer, caretPos) {\n                input._valueSet(buffer.join(''));\n                if (caretPos != undefined) {\n                    caret(input, caretPos);\n                }\n            }\n\n            function clearBuffer(buffer, start, end, stripNomasks) {\n                for (var i = start, maskL = getMaskLength() ; i < end && i < maskL; i++) {\n                    if (stripNomasks === true) {\n                        if (!isMask(i))\n                            setBufferElement(buffer, i, \"\");\n                    } else\n                        setBufferElement(buffer, i, getBufferElement(getActiveBufferTemplate().slice(), i, true));\n                }\n            }\n\n            function setReTargetPlaceHolder(buffer, pos) {\n                var testPos = determineTestPosition(pos);\n                setBufferElement(buffer, pos, getBufferElement(getActiveBufferTemplate(), testPos));\n            }\n\n            function getPlaceHolder(pos) {\n                return opts.placeholder.charAt(pos % opts.placeholder.length);\n            }\n\n            function checkVal(input, writeOut, strict, nptvl, intelliCheck) {\n                var inputValue = nptvl != undefined ? nptvl.slice() : truncateInput(input._valueGet()).split('');\n\n                $.each(masksets, function (ndx, ms) {\n                    if (typeof (ms) == \"object\") {\n                        ms[\"buffer\"] = ms[\"_buffer\"].slice();\n                        ms[\"lastValidPosition\"] = -1;\n                        ms[\"p\"] = -1;\n                    }\n                });\n                if (strict !== true) activeMasksetIndex = 0;\n                if (writeOut) input._valueSet(\"\"); //initial clear\n                var ml = getMaskLength();\n                $.each(inputValue, function (ndx, charCode) {\n                    if (intelliCheck === true) {\n                        var p = getActiveMaskSet()[\"p\"], lvp = p == -1 ? p : seekPrevious(p),\n                            pos = lvp == -1 ? ndx : seekNext(lvp);\n                        if ($.inArray(charCode, getActiveBufferTemplate().slice(lvp + 1, pos)) == -1) {\n                            keypressEvent.call(input, undefined, true, charCode.charCodeAt(0), writeOut, strict, ndx);\n                        }\n                    } else {\n                        keypressEvent.call(input, undefined, true, charCode.charCodeAt(0), writeOut, strict, ndx);\n                    }\n                });\n\n                if (strict === true && getActiveMaskSet()[\"p\"] != -1) {\n                    getActiveMaskSet()[\"lastValidPosition\"] = seekPrevious(getActiveMaskSet()[\"p\"]);\n                }\n            }\n\n            function escapeRegex(str) {\n                return $.inputmask.escapeRegex.call(this, str);\n            }\n\n            function truncateInput(inputValue) {\n                return inputValue.replace(new RegExp(\"(\" + escapeRegex(getActiveBufferTemplate().join('')) + \")*$\"), \"\");\n            }\n\n            function clearOptionalTail(input) {\n                var buffer = getActiveBuffer(), tmpBuffer = buffer.slice(), testPos, pos;\n                for (var pos = tmpBuffer.length - 1; pos >= 0; pos--) {\n                    var testPos = determineTestPosition(pos);\n                    if (getActiveTests()[testPos].optionality) {\n                        if (!isMask(pos) || !isValid(pos, buffer[pos], true))\n                            tmpBuffer.pop();\n                        else break;\n                    } else break;\n                }\n                writeBuffer(input, tmpBuffer);\n            }\n\n            function unmaskedvalue($input, skipDatepickerCheck) {\n                if (getActiveTests() && (skipDatepickerCheck === true || !$input.hasClass('hasDatepicker'))) {\n                    //checkVal(input, false, true);\n                    var umValue = $.map(getActiveBuffer(), function (element, index) {\n                        return isMask(index) && isValid(index, element, true) ? element : null;\n                    });\n                    var unmaskedValue = (isRTL ? umValue.reverse() : umValue).join('');\n                    return opts.onUnMask != undefined ? opts.onUnMask.call(this, getActiveBuffer().join(''), unmaskedValue) : unmaskedValue;\n                } else {\n                    return $input[0]._valueGet();\n                }\n            }\n\n            function TranslatePosition(pos) {\n                if (isRTL && typeof pos == 'number' && (!opts.greedy || opts.placeholder != \"\")) {\n                    var bffrLght = getActiveBuffer().length;\n                    pos = bffrLght - pos;\n                }\n                return pos;\n            }\n\n            function caret(input, begin, end) {\n                var npt = input.jquery && input.length > 0 ? input[0] : input, range;\n                if (typeof begin == 'number') {\n                    begin = TranslatePosition(begin);\n                    end = TranslatePosition(end);\n                    if (!$(input).is(':visible')) {\n                        return;\n                    }\n                    end = (typeof end == 'number') ? end : begin;\n                    npt.scrollLeft = npt.scrollWidth;\n                    if (opts.insertMode == false && begin == end) end++; //set visualization for insert/overwrite mode\n                    if (npt.setSelectionRange) {\n                        npt.selectionStart = begin;\n                        npt.selectionEnd = android ? begin : end;\n\n                    } else if (npt.createTextRange) {\n                        range = npt.createTextRange();\n                        range.collapse(true);\n                        range.moveEnd('character', end);\n                        range.moveStart('character', begin);\n                        range.select();\n                    }\n                } else {\n                    if (!$(input).is(':visible')) {\n                        return { \"begin\": 0, \"end\": 0 };\n                    }\n                    if (npt.setSelectionRange) {\n                        begin = npt.selectionStart;\n                        end = npt.selectionEnd;\n                    } else if (document.selection && document.selection.createRange) {\n                        range = document.selection.createRange();\n                        begin = 0 - range.duplicate().moveStart('character', -100000);\n                        end = begin + range.text.length;\n                    }\n                    begin = TranslatePosition(begin);\n                    end = TranslatePosition(end);\n                    return { \"begin\": begin, \"end\": end };\n                }\n            }\n\n            function isComplete(buffer) { //return true / false / undefined (repeat *)\n                if (opts.repeat == \"*\") return undefined;\n                var complete = false, highestValidPosition = 0, currentActiveMasksetIndex = activeMasksetIndex;\n                $.each(masksets, function (ndx, ms) {\n                    if (typeof (ms) == \"object\") {\n                        activeMasksetIndex = ndx;\n                        var aml = seekPrevious(getMaskLength());\n                        if (ms[\"lastValidPosition\"] >= highestValidPosition && ms[\"lastValidPosition\"] == aml) {\n                            var msComplete = true;\n                            for (var i = 0; i <= aml; i++) {\n                                var mask = isMask(i), testPos = determineTestPosition(i);\n                                if ((mask && (buffer[i] == undefined || buffer[i] == getPlaceHolder(i))) || (!mask && buffer[i] != getActiveBufferTemplate()[testPos])) {\n                                    msComplete = false;\n                                    break;\n                                }\n                            }\n                            complete = complete || msComplete;\n                            if (complete) //break loop\n                                return false;\n                        }\n                        highestValidPosition = ms[\"lastValidPosition\"];\n                    }\n                });\n                activeMasksetIndex = currentActiveMasksetIndex; //reset activeMaskset\n                return complete;\n            }\n\n            function isSelection(begin, end) {\n                return isRTL ? (begin - end) > 1 || ((begin - end) == 1 && opts.insertMode) :\n                    (end - begin) > 1 || ((end - begin) == 1 && opts.insertMode);\n            }\n\n\n            //private functions\n            function installEventRuler(npt) {\n                var events = $._data(npt).events;\n\n                $.each(events, function (eventType, eventHandlers) {\n                    $.each(eventHandlers, function (ndx, eventHandler) {\n                        if (eventHandler.namespace == \"inputmask\") {\n                            if (eventHandler.type != \"setvalue\") {\n                                var handler = eventHandler.handler;\n                                eventHandler.handler = function (e) {\n                                    if (this.readOnly || this.disabled)\n                                        e.preventDefault;\n                                    else\n                                        return handler.apply(this, arguments);\n                                };\n                            }\n                        }\n                    });\n                });\n            }\n\n            function patchValueProperty(npt) {\n                var valueProperty;\n                if (Object.getOwnPropertyDescriptor)\n                    valueProperty = Object.getOwnPropertyDescriptor(npt, \"value\");\n                if (valueProperty && valueProperty.get) {\n                    if (!npt._valueGet) {\n                        var valueGet = valueProperty.get;\n                        var valueSet = valueProperty.set;\n                        npt._valueGet = function () {\n                            return isRTL ? valueGet.call(this).split('').reverse().join('') : valueGet.call(this);\n                        };\n                        npt._valueSet = function (value) {\n                            valueSet.call(this, isRTL ? value.split('').reverse().join('') : value);\n                        };\n\n                        Object.defineProperty(npt, \"value\", {\n                            get: function () {\n                                var $self = $(this), inputData = $(this).data('_inputmask'), masksets = inputData['masksets'],\n                                    activeMasksetIndex = inputData['activeMasksetIndex'];\n                                return inputData && inputData['opts'].autoUnmask ? $self.inputmask('unmaskedvalue') : valueGet.call(this) != masksets[activeMasksetIndex]['_buffer'].join('') ? valueGet.call(this) : '';\n                            },\n                            set: function (value) {\n                                valueSet.call(this, value);\n                                $(this).triggerHandler('setvalue.inputmask');\n                            }\n                        });\n                    }\n                } else if (document.__lookupGetter__ && npt.__lookupGetter__(\"value\")) {\n                    if (!npt._valueGet) {\n                        var valueGet = npt.__lookupGetter__(\"value\");\n                        var valueSet = npt.__lookupSetter__(\"value\");\n                        npt._valueGet = function () {\n                            return isRTL ? valueGet.call(this).split('').reverse().join('') : valueGet.call(this);\n                        };\n                        npt._valueSet = function (value) {\n                            valueSet.call(this, isRTL ? value.split('').reverse().join('') : value);\n                        };\n\n                        npt.__defineGetter__(\"value\", function () {\n                            var $self = $(this), inputData = $(this).data('_inputmask'), masksets = inputData['masksets'],\n                                activeMasksetIndex = inputData['activeMasksetIndex'];\n                            return inputData && inputData['opts'].autoUnmask ? $self.inputmask('unmaskedvalue') : valueGet.call(this) != masksets[activeMasksetIndex]['_buffer'].join('') ? valueGet.call(this) : '';\n                        });\n                        npt.__defineSetter__(\"value\", function (value) {\n                            valueSet.call(this, value);\n                            $(this).triggerHandler('setvalue.inputmask');\n                        });\n                    }\n                } else {\n                    if (!npt._valueGet) {\n                        npt._valueGet = function () { return isRTL ? this.value.split('').reverse().join('') : this.value; };\n                        npt._valueSet = function (value) { this.value = isRTL ? value.split('').reverse().join('') : value; };\n                    }\n                    if ($.valHooks.text == undefined || $.valHooks.text.inputmaskpatch != true) {\n                        var valueGet = $.valHooks.text && $.valHooks.text.get ? $.valHooks.text.get : function (elem) { return elem.value; };\n                        var valueSet = $.valHooks.text && $.valHooks.text.set ? $.valHooks.text.set : function (elem, value) {\n                            elem.value = value;\n                            return elem;\n                        };\n\n                        jQuery.extend($.valHooks, {\n                            text: {\n                                get: function (elem) {\n                                    var $elem = $(elem);\n                                    if ($elem.data('_inputmask')) {\n                                        if ($elem.data('_inputmask')['opts'].autoUnmask)\n                                            return $elem.inputmask('unmaskedvalue');\n                                        else {\n                                            var result = valueGet(elem),\n                                                inputData = $elem.data('_inputmask'), masksets = inputData['masksets'],\n                                                activeMasksetIndex = inputData['activeMasksetIndex'];\n                                            return result != masksets[activeMasksetIndex]['_buffer'].join('') ? result : '';\n                                        }\n                                    } else return valueGet(elem);\n                                },\n                                set: function (elem, value) {\n                                    var $elem = $(elem);\n                                    var result = valueSet(elem, value);\n                                    if ($elem.data('_inputmask')) $elem.triggerHandler('setvalue.inputmask');\n                                    return result;\n                                },\n                                inputmaskpatch: true\n                            }\n                        });\n                    }\n                }\n            }\n\n            //shift chars to left from start to end and put c at end position if defined\n\n            function shiftL(start, end, c, maskJumps) {\n                var buffer = getActiveBuffer();\n                if (maskJumps !== false) //jumping over nonmask position\n                    while (!isMask(start) && start - 1 >= 0) start--;\n                for (var i = start; i < end && i < getMaskLength() ; i++) {\n                    if (isMask(i)) {\n                        setReTargetPlaceHolder(buffer, i);\n                        var j = seekNext(i);\n                        var p = getBufferElement(buffer, j);\n                        if (p != getPlaceHolder(j)) {\n                            if (j < getMaskLength() && isValid(i, p, true) !== false && getActiveTests()[determineTestPosition(i)].def == getActiveTests()[determineTestPosition(j)].def) {\n                                setBufferElement(buffer, i, p, true);\n                            } else {\n                                if (isMask(i))\n                                    break;\n                            }\n                        }\n                    } else {\n                        setReTargetPlaceHolder(buffer, i);\n                    }\n                }\n                if (c != undefined)\n                    setBufferElement(buffer, seekPrevious(end), c);\n\n                if (getActiveMaskSet()[\"greedy\"] == false) {\n                    var trbuffer = truncateInput(buffer.join('')).split('');\n                    buffer.length = trbuffer.length;\n                    for (var i = 0, bl = buffer.length; i < bl; i++) {\n                        buffer[i] = trbuffer[i];\n                    }\n                    if (buffer.length == 0) getActiveMaskSet()[\"buffer\"] = getActiveBufferTemplate().slice();\n                }\n                return start; //return the used start position\n            }\n\n            function shiftR(start, end, c) {\n                var buffer = getActiveBuffer();\n                if (getBufferElement(buffer, start, true) != getPlaceHolder(start)) {\n                    for (var i = seekPrevious(end) ; i > start && i >= 0; i--) {\n                        if (isMask(i)) {\n                            var j = seekPrevious(i);\n                            var t = getBufferElement(buffer, j);\n                            if (t != getPlaceHolder(j)) {\n                                if (isValid(j, t, true) !== false && getActiveTests()[determineTestPosition(i)].def == getActiveTests()[determineTestPosition(j)].def) {\n                                    setBufferElement(buffer, i, t, true);\n                                    setReTargetPlaceHolder(buffer, j);\n                                } //else break;\n                            }\n                        } else\n                            setReTargetPlaceHolder(buffer, i);\n                    }\n                }\n                if (c != undefined && getBufferElement(buffer, start) == getPlaceHolder(start))\n                    setBufferElement(buffer, start, c);\n                var lengthBefore = buffer.length;\n                if (getActiveMaskSet()[\"greedy\"] == false) {\n                    var trbuffer = truncateInput(buffer.join('')).split('');\n                    buffer.length = trbuffer.length;\n                    for (var i = 0, bl = buffer.length; i < bl; i++) {\n                        buffer[i] = trbuffer[i];\n                    }\n                    if (buffer.length == 0) getActiveMaskSet()[\"buffer\"] = getActiveBufferTemplate().slice();\n                }\n                return end - (lengthBefore - buffer.length); //return new start position\n            }\n\n            function HandleRemove(input, k, pos) {\n                if (opts.numericInput || isRTL) {\n                    switch (k) {\n                        case opts.keyCode.BACKSPACE:\n                            k = opts.keyCode.DELETE;\n                            break;\n                        case opts.keyCode.DELETE:\n                            k = opts.keyCode.BACKSPACE;\n                            break;\n                    }\n                    if (isRTL) {\n                        var pend = pos.end;\n                        pos.end = pos.begin;\n                        pos.begin = pend;\n                    }\n                }\n\n                var isSelection = true;\n                if (pos.begin == pos.end) {\n                    var posBegin = k == opts.keyCode.BACKSPACE ? pos.begin - 1 : pos.begin;\n                    if (opts.isNumeric && opts.radixPoint != \"\" && getActiveBuffer()[posBegin] == opts.radixPoint) {\n                        pos.begin = (getActiveBuffer().length - 1 == posBegin) /* radixPoint is latest? delete it */ ? pos.begin : k == opts.keyCode.BACKSPACE ? posBegin : seekNext(posBegin);\n                        pos.end = pos.begin;\n                    }\n                    isSelection = false;\n                    if (k == opts.keyCode.BACKSPACE)\n                        pos.begin--;\n                    else if (k == opts.keyCode.DELETE)\n                        pos.end++;\n                } else if (pos.end - pos.begin == 1 && !opts.insertMode) {\n                    isSelection = false;\n                    if (k == opts.keyCode.BACKSPACE)\n                        pos.begin--;\n                }\n\n                clearBuffer(getActiveBuffer(), pos.begin, pos.end);\n\n                var ml = getMaskLength();\n                if (opts.greedy == false) {\n                    shiftL(pos.begin, ml, undefined, !isRTL && (k == opts.keyCode.BACKSPACE && !isSelection));\n                } else {\n                    var newpos = pos.begin;\n                    for (var i = pos.begin; i < pos.end; i++) { //seeknext to skip placeholders at start in selection\n                        if (isMask(i) || !isSelection)\n                            newpos = shiftL(pos.begin, ml, undefined, !isRTL && (k == opts.keyCode.BACKSPACE && !isSelection));\n                    }\n                    if (!isSelection) pos.begin = newpos;\n                }\n                var firstMaskPos = seekNext(-1);\n                clearBuffer(getActiveBuffer(), pos.begin, pos.end, true);\n                checkVal(input, false, masksets[1] == undefined || firstMaskPos >= pos.end, getActiveBuffer());\n                if (getActiveMaskSet()['lastValidPosition'] < firstMaskPos) {\n                    getActiveMaskSet()[\"lastValidPosition\"] = -1;\n                    getActiveMaskSet()[\"p\"] = firstMaskPos;\n                } else {\n                    getActiveMaskSet()[\"p\"] = pos.begin;\n                }\n            }\n\n            function keydownEvent(e) {\n                //Safari 5.1.x - modal dialog fires keypress twice workaround\n                skipKeyPressEvent = false;\n                var input = this, $input = $(input), k = e.keyCode, pos = caret(input);\n\n                //backspace, delete, and escape get special treatment\n                if (k == opts.keyCode.BACKSPACE || k == opts.keyCode.DELETE || (iphone && k == 127) || e.ctrlKey && k == 88) { //backspace/delete\n                    e.preventDefault(); //stop default action but allow propagation\n                    if (k == 88) valueOnFocus = getActiveBuffer().join('');\n                    HandleRemove(input, k, pos);\n                    determineActiveMasksetIndex();\n                    writeBuffer(input, getActiveBuffer(), getActiveMaskSet()[\"p\"]);\n                    if (input._valueGet() == getActiveBufferTemplate().join(''))\n                        $input.trigger('cleared');\n\n                    if (opts.showTooltip) { //update tooltip\n                        $input.prop(\"title\", getActiveMaskSet()[\"mask\"]);\n                    }\n                } else if (k == opts.keyCode.END || k == opts.keyCode.PAGE_DOWN) { //when END or PAGE_DOWN pressed set position at lastmatch\n                    setTimeout(function () {\n                        var caretPos = seekNext(getActiveMaskSet()[\"lastValidPosition\"]);\n                        if (!opts.insertMode && caretPos == getMaskLength() && !e.shiftKey) caretPos--;\n                        caret(input, e.shiftKey ? pos.begin : caretPos, caretPos);\n                    }, 0);\n                } else if ((k == opts.keyCode.HOME && !e.shiftKey) || k == opts.keyCode.PAGE_UP) { //Home or page_up\n                    caret(input, 0, e.shiftKey ? pos.begin : 0);\n                } else if (k == opts.keyCode.ESCAPE || (k == 90 && e.ctrlKey)) { //escape && undo\n                    checkVal(input, true, false, valueOnFocus.split(''));\n                    $input.click();\n                } else if (k == opts.keyCode.INSERT && !(e.shiftKey || e.ctrlKey)) { //insert\n                    opts.insertMode = !opts.insertMode;\n                    caret(input, !opts.insertMode && pos.begin == getMaskLength() ? pos.begin - 1 : pos.begin);\n                } else if (opts.insertMode == false && !e.shiftKey) {\n                    if (k == opts.keyCode.RIGHT) {\n                        setTimeout(function () {\n                            var caretPos = caret(input);\n                            caret(input, caretPos.begin);\n                        }, 0);\n                    } else if (k == opts.keyCode.LEFT) {\n                        setTimeout(function () {\n                            var caretPos = caret(input);\n                            caret(input, caretPos.begin - 1);\n                        }, 0);\n                    }\n                }\n\n                var currentCaretPos = caret(input);\n                if (opts.onKeyDown.call(this, e, getActiveBuffer(), opts) === true) //extra stuff to execute on keydown\n                    caret(input, currentCaretPos.begin, currentCaretPos.end);\n                ignorable = $.inArray(k, opts.ignorables) != -1;\n            }\n\n\n            function keypressEvent(e, checkval, k, writeOut, strict, ndx) {\n                //Safari 5.1.x - modal dialog fires keypress twice workaround\n                if (k == undefined && skipKeyPressEvent) return false;\n                skipKeyPressEvent = true;\n\n                var input = this, $input = $(input);\n\n                e = e || window.event;\n                var k = checkval ? k : (e.which || e.charCode || e.keyCode);\n\n                if (checkval !== true && (!(e.ctrlKey && e.altKey) && (e.ctrlKey || e.metaKey || ignorable))) {\n                    return true;\n                } else {\n                    if (k) {\n                        //special treat the decimal separator\n                        if (checkval !== true && k == 46 && e.shiftKey == false && opts.radixPoint == \",\") k = 44;\n\n                        var pos, results, result, c = String.fromCharCode(k);\n                        if (checkval) {\n                            var pcaret = strict ? ndx : getActiveMaskSet()[\"lastValidPosition\"] + 1;\n                            pos = { begin: pcaret, end: pcaret };\n                        } else {\n                            pos = caret(input);\n                        }\n\n                        //should we clear a possible selection??\n                        var isSlctn = isSelection(pos.begin, pos.end), redetermineLVP = false,\n                            initialIndex = activeMasksetIndex;\n                        if (isSlctn) {\n                            activeMasksetIndex = initialIndex;\n                            $.each(masksets, function (ndx, lmnt) { //init undobuffer for recovery when not valid\n                                if (typeof (lmnt) == \"object\") {\n                                    activeMasksetIndex = ndx;\n                                    getActiveMaskSet()[\"undoBuffer\"] = getActiveBuffer().join('');\n                                }\n                            });\n                            HandleRemove(input, opts.keyCode.DELETE, pos);\n                            if (!opts.insertMode) { //preserve some space\n                                $.each(masksets, function (ndx, lmnt) {\n                                    if (typeof (lmnt) == \"object\") {\n                                        activeMasksetIndex = ndx;\n                                        shiftR(pos.begin, getMaskLength());\n                                        getActiveMaskSet()[\"lastValidPosition\"] = seekNext(getActiveMaskSet()[\"lastValidPosition\"]);\n                                    }\n                                });\n                            }\n                            activeMasksetIndex = initialIndex; //restore index\n                        }\n\n                        var radixPosition = getActiveBuffer().join('').indexOf(opts.radixPoint);\n                        if (opts.isNumeric && checkval !== true && radixPosition != -1) {\n                            if (opts.greedy && pos.begin <= radixPosition) {\n                                pos.begin = seekPrevious(pos.begin);\n                                pos.end = pos.begin;\n                            } else if (c == opts.radixPoint) {\n                                pos.begin = radixPosition;\n                                pos.end = pos.begin;\n                            }\n                        }\n\n\n                        var p = pos.begin;\n                        results = isValid(p, c, strict);\n                        if (strict === true) results = [{ \"activeMasksetIndex\": activeMasksetIndex, \"result\": results }];\n                        var minimalForwardPosition = -1;\n                        $.each(results, function (index, result) {\n                            activeMasksetIndex = result[\"activeMasksetIndex\"];\n                            getActiveMaskSet()[\"writeOutBuffer\"] = true;\n                            var np = result[\"result\"];\n                            if (np !== false) {\n                                var refresh = false, buffer = getActiveBuffer();\n                                if (np !== true) {\n                                    refresh = np[\"refresh\"]; //only rewrite buffer from isValid\n                                    p = np.pos != undefined ? np.pos : p; //set new position from isValid\n                                    c = np.c != undefined ? np.c : c; //set new char from isValid\n                                }\n                                if (refresh !== true) {\n                                    if (opts.insertMode == true) {\n                                        var lastUnmaskedPosition = getMaskLength();\n                                        var bfrClone = buffer.slice();\n                                        while (getBufferElement(bfrClone, lastUnmaskedPosition, true) != getPlaceHolder(lastUnmaskedPosition) && lastUnmaskedPosition >= p) {\n                                            lastUnmaskedPosition = lastUnmaskedPosition == 0 ? -1 : seekPrevious(lastUnmaskedPosition);\n                                        }\n                                        if (lastUnmaskedPosition >= p) {\n                                            shiftR(p, getMaskLength(), c);\n                                            //shift the lvp if needed\n                                            var lvp = getActiveMaskSet()[\"lastValidPosition\"], nlvp = seekNext(lvp);\n                                            if (nlvp != getMaskLength() && lvp >= p && (getBufferElement(getActiveBuffer(), nlvp, true) != getPlaceHolder(nlvp))) {\n                                                getActiveMaskSet()[\"lastValidPosition\"] = nlvp;\n                                            }\n                                        } else getActiveMaskSet()[\"writeOutBuffer\"] = false;\n                                    } else setBufferElement(buffer, p, c, true);\n                                    if (minimalForwardPosition == -1 || minimalForwardPosition > seekNext(p)) {\n                                        minimalForwardPosition = seekNext(p);\n                                    }\n                                } else if (!strict) {\n                                    var nextPos = p < getMaskLength() ? p + 1 : p;\n                                    if (minimalForwardPosition == -1 || minimalForwardPosition > nextPos) {\n                                        minimalForwardPosition = nextPos;\n                                    }\n                                }\n                                if (minimalForwardPosition > getActiveMaskSet()[\"p\"])\n                                    getActiveMaskSet()[\"p\"] = minimalForwardPosition; //needed for checkval strict \n                            }\n                        });\n\n                        if (strict !== true) {\n                            activeMasksetIndex = initialIndex;\n                            determineActiveMasksetIndex();\n                        }\n                        if (writeOut !== false) {\n                            $.each(results, function (ndx, rslt) {\n                                if (rslt[\"activeMasksetIndex\"] == activeMasksetIndex) {\n                                    result = rslt;\n                                    return false;\n                                }\n                            });\n                            if (result != undefined) {\n                                var self = this;\n                                setTimeout(function () { opts.onKeyValidation.call(self, result[\"result\"], opts); }, 0);\n                                if (getActiveMaskSet()[\"writeOutBuffer\"] && result[\"result\"] !== false) {\n                                    var buffer = getActiveBuffer();\n\n                                    var newCaretPosition;\n                                    if (checkval) {\n                                        newCaretPosition = undefined;\n                                    } else if (opts.numericInput) {\n                                        if (p > radixPosition) {\n                                            newCaretPosition = seekPrevious(minimalForwardPosition);\n                                        } else if (c == opts.radixPoint) {\n                                            newCaretPosition = minimalForwardPosition - 1;\n                                        } else newCaretPosition = seekPrevious(minimalForwardPosition - 1);\n                                    } else {\n                                        newCaretPosition = minimalForwardPosition;\n                                    }\n\n                                    writeBuffer(input, buffer, newCaretPosition);\n                                    if (checkval !== true) {\n                                        setTimeout(function () { //timeout needed for IE\n                                            if (isComplete(buffer) === true)\n                                                $input.trigger(\"complete\");\n                                            skipInputEvent = true;\n                                            $input.trigger(\"input\");\n                                        }, 0);\n                                    }\n                                } else if (isSlctn) {\n                                    getActiveMaskSet()[\"buffer\"] = getActiveMaskSet()[\"undoBuffer\"].split('');\n                                }\n                            }\n                        }\n\n                        if (opts.showTooltip) { //update tooltip\n                            $input.prop(\"title\", getActiveMaskSet()[\"mask\"]);\n                        }\n\n                        //needed for IE8 and below\n                        if (e) e.preventDefault ? e.preventDefault() : e.returnValue = false;\n                    }\n                }\n            }\n\n            function keyupEvent(e) {\n                var $input = $(this), input = this, k = e.keyCode, buffer = getActiveBuffer();\n\n                if (androidchrome && k == opts.keyCode.BACKSPACE) {\n                    if (chromeValueOnInput == input._valueGet())\n                        keydownEvent.call(this, e);\n                }\n\n                opts.onKeyUp.call(this, e, buffer, opts); //extra stuff to execute on keyup\n                if (k == opts.keyCode.TAB && opts.showMaskOnFocus) {\n                    if ($input.hasClass('focus.inputmask') && input._valueGet().length == 0) {\n                        buffer = getActiveBufferTemplate().slice();\n                        writeBuffer(input, buffer);\n                        caret(input, 0);\n                        valueOnFocus = getActiveBuffer().join('');\n                    } else {\n                        writeBuffer(input, buffer);\n                        if (buffer.join('') == getActiveBufferTemplate().join('') && $.inArray(opts.radixPoint, buffer) != -1) {\n                            caret(input, TranslatePosition(0));\n                            $input.click();\n                        } else\n                            caret(input, TranslatePosition(0), TranslatePosition(getMaskLength()));\n                    }\n                }\n            }\n\n            function inputEvent(e) {\n                if (skipInputEvent === true) {\n                    skipInputEvent = false;\n                    return true;\n                }\n                var input = this, $input = $(input);\n\n                chromeValueOnInput = getActiveBuffer().join('');\n                checkVal(input, false, false);\n                writeBuffer(input, getActiveBuffer());\n                if (isComplete(getActiveBuffer()) === true)\n                    $input.trigger(\"complete\");\n                $input.click();\n            }\n\n            function mask(el) {\n                $el = $(el);\n                if ($el.is(\":input\")) {\n                    //store tests & original buffer in the input element - used to get the unmasked value\n                    $el.data('_inputmask', {\n                        'masksets': masksets,\n                        'activeMasksetIndex': activeMasksetIndex,\n                        'opts': opts,\n                        'isRTL': false\n                    });\n\n                    //show tooltip\n                    if (opts.showTooltip) {\n                        $el.prop(\"title\", getActiveMaskSet()[\"mask\"]);\n                    }\n\n                    //correct greedy setting if needed\n                    getActiveMaskSet()['greedy'] = getActiveMaskSet()['greedy'] ? getActiveMaskSet()['greedy'] : getActiveMaskSet()['repeat'] == 0;\n\n                    //handle maxlength attribute\n                    if ($el.attr(\"maxLength\") != null) //only when the attribute is set\n                    {\n                        var maxLength = $el.prop('maxLength');\n                        if (maxLength > -1) { //handle *-repeat\n                            $.each(masksets, function (ndx, ms) {\n                                if (typeof (ms) == \"object\") {\n                                    if (ms[\"repeat\"] == \"*\") {\n                                        ms[\"repeat\"] = maxLength;\n                                    }\n                                }\n                            });\n                        }\n                        if (getMaskLength() >= maxLength && maxLength > -1) { //FF sets no defined max length to -1 \n                            if (maxLength < getActiveBufferTemplate().length) getActiveBufferTemplate().length = maxLength;\n                            if (getActiveMaskSet()['greedy'] == false) {\n                                getActiveMaskSet()['repeat'] = Math.round(maxLength / getActiveBufferTemplate().length);\n                            }\n                            $el.prop('maxLength', getMaskLength() * 2);\n                        }\n                    }\n\n                    patchValueProperty(el);\n\n                    if (opts.numericInput) opts.isNumeric = opts.numericInput;\n                    if (el.dir == \"rtl\" || (opts.numericInput && opts.rightAlignNumerics) || (opts.isNumeric && opts.rightAlignNumerics))\n                        $el.css(\"text-align\", \"right\");\n\n                    if (el.dir == \"rtl\" || opts.numericInput) {\n                        el.dir = \"ltr\";\n                        $el.removeAttr(\"dir\");\n                        var inputData = $el.data('_inputmask');\n                        inputData['isRTL'] = true;\n                        $el.data('_inputmask', inputData);\n                        isRTL = true;\n                    }\n\n                    //unbind all events - to make sure that no other mask will interfere when re-masking\n                    $el.unbind(\".inputmask\");\n                    $el.removeClass('focus.inputmask');\n                    //bind events\n                    $el.closest('form').bind(\"submit\", function () { //trigger change on submit if any\n                        if (valueOnFocus != getActiveBuffer().join('')) {\n                            $el.change();\n                        }\n                    }).bind('reset', function () {\n                        setTimeout(function () {\n                            $el.trigger(\"setvalue\");\n                        }, 0);\n                    });\n                    $el.bind(\"mouseenter.inputmask\", function () {\n                        var $input = $(this), input = this;\n                        if (!$input.hasClass('focus.inputmask') && opts.showMaskOnHover) {\n                            if (input._valueGet() != getActiveBuffer().join('')) {\n                                writeBuffer(input, getActiveBuffer());\n                            }\n                        }\n                    }).bind(\"blur.inputmask\", function () {\n                        var $input = $(this), input = this, nptValue = input._valueGet(), buffer = getActiveBuffer();\n                        $input.removeClass('focus.inputmask');\n                        if (valueOnFocus != getActiveBuffer().join('')) {\n                            $input.change();\n                        }\n                        if (opts.clearMaskOnLostFocus && nptValue != '') {\n                            if (nptValue == getActiveBufferTemplate().join(''))\n                                input._valueSet('');\n                            else { //clearout optional tail of the mask\n                                clearOptionalTail(input);\n                            }\n                        }\n                        if (isComplete(buffer) === false) {\n                            $input.trigger(\"incomplete\");\n                            if (opts.clearIncomplete) {\n                                $.each(masksets, function (ndx, ms) {\n                                    if (typeof (ms) == \"object\") {\n                                        ms[\"buffer\"] = ms[\"_buffer\"].slice();\n                                        ms[\"lastValidPosition\"] = -1;\n                                    }\n                                });\n                                activeMasksetIndex = 0;\n                                if (opts.clearMaskOnLostFocus)\n                                    input._valueSet('');\n                                else {\n                                    buffer = getActiveBufferTemplate().slice();\n                                    writeBuffer(input, buffer);\n                                }\n                            }\n                        }\n                    }).bind(\"focus.inputmask\", function () {\n                        var $input = $(this), input = this, nptValue = input._valueGet();\n                        if (opts.showMaskOnFocus && !$input.hasClass('focus.inputmask') && (!opts.showMaskOnHover || (opts.showMaskOnHover && nptValue == ''))) {\n                            if (input._valueGet() != getActiveBuffer().join('')) {\n                                writeBuffer(input, getActiveBuffer(), seekNext(getActiveMaskSet()[\"lastValidPosition\"]));\n                            }\n                        }\n                        $input.addClass('focus.inputmask');\n                        valueOnFocus = getActiveBuffer().join('');\n                    }).bind(\"mouseleave.inputmask\", function () {\n                        var $input = $(this), input = this;\n                        if (opts.clearMaskOnLostFocus) {\n                            if (!$input.hasClass('focus.inputmask') && input._valueGet() != $input.attr(\"placeholder\")) {\n                                if (input._valueGet() == getActiveBufferTemplate().join('') || input._valueGet() == '')\n                                    input._valueSet('');\n                                else { //clearout optional tail of the mask\n                                    clearOptionalTail(input);\n                                }\n                            }\n                        }\n                    }).bind(\"click.inputmask\", function () {\n                        var input = this;\n                        setTimeout(function () {\n                            var selectedCaret = caret(input), buffer = getActiveBuffer();\n                            if (selectedCaret.begin == selectedCaret.end) {\n                                var clickPosition = isRTL ? TranslatePosition(selectedCaret.begin) : selectedCaret.begin,\n                                    lvp = getActiveMaskSet()[\"lastValidPosition\"],\n                                    lastPosition;\n                                if (opts.isNumeric) {\n                                    lastPosition = opts.skipRadixDance === false && opts.radixPoint != \"\" && $.inArray(opts.radixPoint, buffer) != -1 ?\n                                        (opts.numericInput ? seekNext($.inArray(opts.radixPoint, buffer)) : $.inArray(opts.radixPoint, buffer)) :\n                                        seekNext(lvp);\n                                } else {\n                                    lastPosition = seekNext(lvp);\n                                }\n                                if (clickPosition < lastPosition) {\n                                    if (isMask(clickPosition))\n                                        caret(input, clickPosition);\n                                    else caret(input, seekNext(clickPosition));\n                                } else\n                                    caret(input, lastPosition);\n                            }\n                        }, 0);\n                    }).bind('dblclick.inputmask', function () {\n                        var input = this;\n                        setTimeout(function () {\n                            caret(input, 0, seekNext(getActiveMaskSet()[\"lastValidPosition\"]));\n                        }, 0);\n                    }).bind(pasteEvent + \".inputmask dragdrop.inputmask drop.inputmask\", function (e) {\n                        if (skipInputEvent === true) {\n                            skipInputEvent = false;\n                            return true;\n                        }\n                        var input = this, $input = $(input);\n\n                        //paste event for IE8 and lower I guess ;-)\n                        if (e.type == \"propertychange\" && input._valueGet().length <= getMaskLength()) {\n                            return true;\n                        }\n                        setTimeout(function () {\n                            var pasteValue = opts.onBeforePaste != undefined ? opts.onBeforePaste.call(this, input._valueGet()) : input._valueGet();\n                            checkVal(input, true, false, pasteValue.split(''), true);\n                            if (isComplete(getActiveBuffer()) === true)\n                                $input.trigger(\"complete\");\n                            $input.click();\n                        }, 0);\n                    }).bind('setvalue.inputmask', function () {\n                        var input = this;\n                        checkVal(input, true);\n                        valueOnFocus = getActiveBuffer().join('');\n                        if (input._valueGet() == getActiveBufferTemplate().join(''))\n                            input._valueSet('');\n                    }).bind('complete.inputmask', opts.oncomplete\n                    ).bind('incomplete.inputmask', opts.onincomplete\n                    ).bind('cleared.inputmask', opts.oncleared\n                    ).bind(\"keyup.inputmask\", keyupEvent);\n\n                    if (androidchrome) {\n                        $el.bind(\"input.inputmask\", inputEvent);\n                    } else {\n                        $el.bind(\"keydown.inputmask\", keydownEvent\n                        ).bind(\"keypress.inputmask\", keypressEvent);\n                    }\n\n                    if (msie10)\n                        $el.bind(\"input.inputmask\", inputEvent);\n\n                    //apply mask\n                    checkVal(el, true, false);\n                    valueOnFocus = getActiveBuffer().join('');\n                    // Wrap document.activeElement in a try/catch block since IE9 throw \"Unspecified error\" if document.activeElement is undefined when we are in an IFrame.\n                    var activeElement;\n                    try {\n                        activeElement = document.activeElement;\n                    } catch (e) {\n                    }\n                    if (activeElement === el) { //position the caret when in focus\n                        $el.addClass('focus.inputmask');\n                        caret(el, seekNext(getActiveMaskSet()[\"lastValidPosition\"]));\n                    } else if (opts.clearMaskOnLostFocus) {\n                        if (getActiveBuffer().join('') == getActiveBufferTemplate().join('')) {\n                            el._valueSet('');\n                        } else {\n                            clearOptionalTail(el);\n                        }\n                    } else {\n                        writeBuffer(el, getActiveBuffer());\n                    }\n\n                    installEventRuler(el);\n                }\n            }\n\n            //action object\n            if (actionObj != undefined) {\n                switch (actionObj[\"action\"]) {\n                    case \"isComplete\":\n                        return isComplete(actionObj[\"buffer\"]);\n                    case \"unmaskedvalue\":\n                        isRTL = actionObj[\"$input\"].data('_inputmask')['isRTL'];\n                        return unmaskedvalue(actionObj[\"$input\"], actionObj[\"skipDatepickerCheck\"]);\n                    case \"mask\":\n                        mask(actionObj[\"el\"]);\n                        break;\n                    case \"format\":\n                        $el = $({});\n                        $el.data('_inputmask', {\n                            'masksets': masksets,\n                            'activeMasksetIndex': activeMasksetIndex,\n                            'opts': opts,\n                            'isRTL': opts.numericInput\n                        });\n                        if (opts.numericInput) {\n                            opts.isNumeric = opts.numericInput;\n                            isRTL = true;\n                        }\n\n                        checkVal($el, false, false, actionObj[\"value\"].split(''), true);\n                        return getActiveBuffer().join('');\n                }\n            }\n        }\n        $.inputmask = {\n            //options default\n            defaults: {\n                placeholder: \"_\",\n                optionalmarker: { start: \"[\", end: \"]\" },\n                quantifiermarker: { start: \"{\", end: \"}\" },\n                groupmarker: { start: \"(\", end: \")\" },\n                escapeChar: \"\\\\\",\n                mask: null,\n                oncomplete: $.noop, //executes when the mask is complete\n                onincomplete: $.noop, //executes when the mask is incomplete and focus is lost\n                oncleared: $.noop, //executes when the mask is cleared\n                repeat: 0, //repetitions of the mask: * ~ forever, otherwise specify an integer\n                greedy: true, //true: allocated buffer for the mask and repetitions - false: allocate only if needed\n                autoUnmask: false, //automatically unmask when retrieving the value with $.fn.val or value if the browser supports __lookupGetter__ or getOwnPropertyDescriptor\n                clearMaskOnLostFocus: true,\n                insertMode: true, //insert the input or overwrite the input\n                clearIncomplete: false, //clear the incomplete input on blur\n                aliases: {}, //aliases definitions => see jquery.inputmask.extensions.js\n                onKeyUp: $.noop, //override to implement autocomplete on certain keys for example\n                onKeyDown: $.noop, //override to implement autocomplete on certain keys for example\n                onBeforePaste: undefined, //executes before masking the pasted value to allow preprocessing of the pasted value.  args => pastedValue => return processedValue\n                onUnMask: undefined, //executes after unmasking to allow postprocessing of the unmaskedvalue.  args => maskedValue, unmaskedValue\n                showMaskOnFocus: true, //show the mask-placeholder when the input has focus\n                showMaskOnHover: true, //show the mask-placeholder when hovering the empty input\n                onKeyValidation: $.noop, //executes on every key-press with the result of isValid. Params: result, opts\n                skipOptionalPartCharacter: \" \", //a character which can be used to skip an optional part of a mask\n                showTooltip: false, //show the activemask as tooltip\n                numericInput: false, //numericInput input direction style (input shifts to the left while holding the caret position)\n                //numeric basic properties\n                isNumeric: false, //enable numeric features\n                radixPoint: \"\", //\".\", // | \",\"\n                skipRadixDance: false, //disable radixpoint caret positioning\n                rightAlignNumerics: true, //align numerics to the right\n                //numeric basic properties\n                definitions: {\n                    '9': {\n                        validator: \"[0-9]\",\n                        cardinality: 1\n                    },\n                    'a': {\n                        validator: \"[A-Za-z\\u0410-\\u044F\\u0401\\u0451]\",\n                        cardinality: 1\n                    },\n                    '*': {\n                        validator: \"[A-Za-z\\u0410-\\u044F\\u0401\\u04510-9]\",\n                        cardinality: 1\n                    }\n                },\n                keyCode: {\n                    ALT: 18, BACKSPACE: 8, CAPS_LOCK: 20, COMMA: 188, COMMAND: 91, COMMAND_LEFT: 91, COMMAND_RIGHT: 93, CONTROL: 17, DELETE: 46, DOWN: 40, END: 35, ENTER: 13, ESCAPE: 27, HOME: 36, INSERT: 45, LEFT: 37, MENU: 93, NUMPAD_ADD: 107, NUMPAD_DECIMAL: 110, NUMPAD_DIVIDE: 111, NUMPAD_ENTER: 108,\n                    NUMPAD_MULTIPLY: 106, NUMPAD_SUBTRACT: 109, PAGE_DOWN: 34, PAGE_UP: 33, PERIOD: 190, RIGHT: 39, SHIFT: 16, SPACE: 32, TAB: 9, UP: 38, WINDOWS: 91\n                },\n                //specify keycodes which should not be considered in the keypress event, otherwise the preventDefault will stop their default behavior especially in FF\n                ignorables: [8, 9, 13, 19, 27, 33, 34, 35, 36, 37, 38, 39, 40, 45, 46, 93, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123],\n                getMaskLength: function (buffer, greedy, repeat, currentBuffer, opts) {\n                    var calculatedLength = buffer.length;\n                    if (!greedy) {\n                        if (repeat == \"*\") {\n                            calculatedLength = currentBuffer.length + 1;\n                        } else if (repeat > 1) {\n                            calculatedLength += (buffer.length * (repeat - 1));\n                        }\n                    }\n                    return calculatedLength;\n                }\n            },\n            escapeRegex: function (str) {\n                var specials = ['/', '.', '*', '+', '?', '|', '(', ')', '[', ']', '{', '}', '\\\\'];\n                return str.replace(new RegExp('(\\\\' + specials.join('|\\\\') + ')', 'gim'), '\\\\$1');\n            },\n            format: function (value, options) {\n                var opts = $.extend(true, {}, $.inputmask.defaults, options);\n                resolveAlias(opts.alias, options, opts);\n                return maskScope(generateMaskSets(opts), 0, opts, { \"action\": \"format\", \"value\": value });\n            }\n        };\n\n        $.fn.inputmask = function (fn, options) {\n            var opts = $.extend(true, {}, $.inputmask.defaults, options),\n                masksets,\n                activeMasksetIndex = 0;\n\n            if (typeof fn === \"string\") {\n                switch (fn) {\n                    case \"mask\":\n                        //resolve possible aliases given by options\n                        resolveAlias(opts.alias, options, opts);\n                        masksets = generateMaskSets(opts);\n                        if (masksets.length == 0) { return this; }\n\n                        return this.each(function () {\n                            maskScope($.extend(true, {}, masksets), 0, opts, { \"action\": \"mask\", \"el\": this });\n                        });\n                    case \"unmaskedvalue\":\n                        var $input = $(this), input = this;\n                        if ($input.data('_inputmask')) {\n                            masksets = $input.data('_inputmask')['masksets'];\n                            activeMasksetIndex = $input.data('_inputmask')['activeMasksetIndex'];\n                            opts = $input.data('_inputmask')['opts'];\n                            return maskScope(masksets, activeMasksetIndex, opts, { \"action\": \"unmaskedvalue\", \"$input\": $input });\n                        } else return $input.val();\n                    case \"remove\":\n                        return this.each(function () {\n                            var $input = $(this), input = this;\n                            if ($input.data('_inputmask')) {\n                                masksets = $input.data('_inputmask')['masksets'];\n                                activeMasksetIndex = $input.data('_inputmask')['activeMasksetIndex'];\n                                opts = $input.data('_inputmask')['opts'];\n                                //writeout the unmaskedvalue\n                                input._valueSet(maskScope(masksets, activeMasksetIndex, opts, { \"action\": \"unmaskedvalue\", \"$input\": $input, \"skipDatepickerCheck\": true }));\n                                //clear data\n                                $input.removeData('_inputmask');\n                                //unbind all events\n                                $input.unbind(\".inputmask\");\n                                $input.removeClass('focus.inputmask');\n                                //restore the value property\n                                var valueProperty;\n                                if (Object.getOwnPropertyDescriptor)\n                                    valueProperty = Object.getOwnPropertyDescriptor(input, \"value\");\n                                if (valueProperty && valueProperty.get) {\n                                    if (input._valueGet) {\n                                        Object.defineProperty(input, \"value\", {\n                                            get: input._valueGet,\n                                            set: input._valueSet\n                                        });\n                                    }\n                                } else if (document.__lookupGetter__ && input.__lookupGetter__(\"value\")) {\n                                    if (input._valueGet) {\n                                        input.__defineGetter__(\"value\", input._valueGet);\n                                        input.__defineSetter__(\"value\", input._valueSet);\n                                    }\n                                }\n                                try { //try catch needed for IE7 as it does not supports deleting fns\n                                    delete input._valueGet;\n                                    delete input._valueSet;\n                                } catch (e) {\n                                    input._valueGet = undefined;\n                                    input._valueSet = undefined;\n\n                                }\n                            }\n                        });\n                        break;\n                    case \"getemptymask\": //return the default (empty) mask value, usefull for setting the default value in validation\n                        if (this.data('_inputmask')) {\n                            masksets = this.data('_inputmask')['masksets'];\n                            activeMasksetIndex = this.data('_inputmask')['activeMasksetIndex'];\n                            return masksets[activeMasksetIndex]['_buffer'].join('');\n                        }\n                        else return \"\";\n                    case \"hasMaskedValue\": //check wheter the returned value is masked or not; currently only works reliable when using jquery.val fn to retrieve the value \n                        return this.data('_inputmask') ? !this.data('_inputmask')['opts'].autoUnmask : false;\n                    case \"isComplete\":\n                        masksets = this.data('_inputmask')['masksets'];\n                        activeMasksetIndex = this.data('_inputmask')['activeMasksetIndex'];\n                        opts = this.data('_inputmask')['opts'];\n                        return maskScope(masksets, activeMasksetIndex, opts, { \"action\": \"isComplete\", \"buffer\": this[0]._valueGet().split('') });\n                    case \"getmetadata\": //return mask metadata if exists\n                        if (this.data('_inputmask')) {\n                            masksets = this.data('_inputmask')['masksets'];\n                            activeMasksetIndex = this.data('_inputmask')['activeMasksetIndex'];\n                            return masksets[activeMasksetIndex]['metadata'];\n                        }\n                        else return undefined;\n                    default:\n                        //check if the fn is an alias\n                        if (!resolveAlias(fn, options, opts)) {\n                            //maybe fn is a mask so we try\n                            //set mask\n                            opts.mask = fn;\n                        }\n                        masksets = generateMaskSets(opts);\n                        if (masksets.length == 0) { return this; }\n                        return this.each(function () {\n                            maskScope($.extend(true, {}, masksets), activeMasksetIndex, opts, { \"action\": \"mask\", \"el\": this });\n                        });\n\n                        break;\n                }\n            } else if (typeof fn == \"object\") {\n                opts = $.extend(true, {}, $.inputmask.defaults, fn);\n\n                resolveAlias(opts.alias, fn, opts); //resolve aliases\n                masksets = generateMaskSets(opts);\n                if (masksets.length == 0) { return this; }\n                return this.each(function () {\n                    maskScope($.extend(true, {}, masksets), activeMasksetIndex, opts, { \"action\": \"mask\", \"el\": this });\n                });\n            } else if (fn == undefined) {\n                //look for data-inputmask atribute - the attribute should only contain optipns\n                return this.each(function () {\n                    var attrOptions = $(this).attr(\"data-inputmask\");\n                    if (attrOptions && attrOptions != \"\") {\n                        try {\n                            attrOptions = attrOptions.replace(new RegExp(\"'\", \"g\"), '\"');\n                            var dataoptions = $.parseJSON(\"{\" + attrOptions + \"}\");\n                            $.extend(true, dataoptions, options);\n                            opts = $.extend(true, {}, $.inputmask.defaults, dataoptions);\n                            resolveAlias(opts.alias, dataoptions, opts);\n                            opts.alias = undefined;\n                            $(this).inputmask(opts);\n                        } catch (ex) { } //need a more relax parseJSON\n                    }\n                });\n            }\n        };\n    }\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/input-mask/jquery.inputmask.numeric.extensions.js",
    "content": "/*\nInput Mask plugin extensions\nhttp://github.com/RobinHerbots/jquery.inputmask\nCopyright (c) 2010 - 2014 Robin Herbots\nLicensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)\nVersion: 0.0.0\n\nOptional extensions on the jquery.inputmask base\n*/\n(function ($) {\n    //number aliases\n    $.extend($.inputmask.defaults.aliases, {\n        'decimal': {\n            mask: \"~\",\n            placeholder: \"\",\n            repeat: \"*\",\n            greedy: false,\n            numericInput: false,\n            isNumeric: true,\n            digits: \"*\", //number of fractionalDigits\n            groupSeparator: \"\",//\",\", // | \".\"\n            radixPoint: \".\",\n            groupSize: 3,\n            autoGroup: false,\n            allowPlus: true,\n            allowMinus: true,\n            //todo\n            integerDigits: \"*\", //number of integerDigits\n            defaultValue: \"\",\n            prefix: \"\",\n            suffix: \"\",\n\n            //todo\n            getMaskLength: function (buffer, greedy, repeat, currentBuffer, opts) { //custom getMaskLength to take the groupSeparator into account\n                var calculatedLength = buffer.length;\n\n                if (!greedy) {\n                    if (repeat == \"*\") {\n                        calculatedLength = currentBuffer.length + 1;\n                    } else if (repeat > 1) {\n                        calculatedLength += (buffer.length * (repeat - 1));\n                    }\n                }\n\n                var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, opts.groupSeparator);\n                var escapedRadixPoint = $.inputmask.escapeRegex.call(this, opts.radixPoint);\n                var currentBufferStr = currentBuffer.join(''), strippedBufferStr = currentBufferStr.replace(new RegExp(escapedGroupSeparator, \"g\"), \"\").replace(new RegExp(escapedRadixPoint), \"\"),\n                groupOffset = currentBufferStr.length - strippedBufferStr.length;\n                return calculatedLength + groupOffset;\n            },\n            postFormat: function (buffer, pos, reformatOnly, opts) {\n                if (opts.groupSeparator == \"\") return pos;\n                var cbuf = buffer.slice(),\n                    radixPos = $.inArray(opts.radixPoint, buffer);\n                if (!reformatOnly) {\n                    cbuf.splice(pos, 0, \"?\"); //set position indicator\n                }\n                var bufVal = cbuf.join('');\n                if (opts.autoGroup || (reformatOnly && bufVal.indexOf(opts.groupSeparator) != -1)) {\n                    var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, opts.groupSeparator);\n                    bufVal = bufVal.replace(new RegExp(escapedGroupSeparator, \"g\"), '');\n                    var radixSplit = bufVal.split(opts.radixPoint);\n                    bufVal = radixSplit[0];\n                    var reg = new RegExp('([-\\+]?[\\\\d\\?]+)([\\\\d\\?]{' + opts.groupSize + '})');\n                    while (reg.test(bufVal)) {\n                        bufVal = bufVal.replace(reg, '$1' + opts.groupSeparator + '$2');\n                        bufVal = bufVal.replace(opts.groupSeparator + opts.groupSeparator, opts.groupSeparator);\n                    }\n                    if (radixSplit.length > 1)\n                        bufVal += opts.radixPoint + radixSplit[1];\n                }\n                buffer.length = bufVal.length; //align the length\n                for (var i = 0, l = bufVal.length; i < l; i++) {\n                    buffer[i] = bufVal.charAt(i);\n                }\n                var newPos = $.inArray(\"?\", buffer);\n                if (!reformatOnly) buffer.splice(newPos, 1);\n\n                return reformatOnly ? pos : newPos;\n            },\n            regex: {\n                number: function (opts) {\n                    var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, opts.groupSeparator);\n                    var escapedRadixPoint = $.inputmask.escapeRegex.call(this, opts.radixPoint);\n                    var digitExpression = isNaN(opts.digits) ? opts.digits : '{0,' + opts.digits + '}';\n                    var signedExpression = opts.allowPlus || opts.allowMinus ? \"[\" + (opts.allowPlus ? \"\\+\" : \"\") + (opts.allowMinus ? \"-\" : \"\") + \"]?\" : \"\";\n                    return new RegExp(\"^\" + signedExpression + \"(\\\\d+|\\\\d{1,\" + opts.groupSize + \"}((\" + escapedGroupSeparator + \"\\\\d{\" + opts.groupSize + \"})?)+)(\" + escapedRadixPoint + \"\\\\d\" + digitExpression + \")?$\");\n                }\n            },\n            onKeyDown: function (e, buffer, opts) {\n                var $input = $(this), input = this;\n                if (e.keyCode == opts.keyCode.TAB) {\n                    var radixPosition = $.inArray(opts.radixPoint, buffer);\n                    if (radixPosition != -1) {\n                        var masksets = $input.data('_inputmask')['masksets'];\n                        var activeMasksetIndex = $input.data('_inputmask')['activeMasksetIndex'];\n                        for (var i = 1; i <= opts.digits && i < opts.getMaskLength(masksets[activeMasksetIndex][\"_buffer\"], masksets[activeMasksetIndex][\"greedy\"], masksets[activeMasksetIndex][\"repeat\"], buffer, opts) ; i++) {\n                            if (buffer[radixPosition + i] == undefined || buffer[radixPosition + i] == \"\") buffer[radixPosition + i] = \"0\";\n                        }\n                        input._valueSet(buffer.join(''));\n                    }\n                } else if (e.keyCode == opts.keyCode.DELETE || e.keyCode == opts.keyCode.BACKSPACE) {\n                    opts.postFormat(buffer, 0, true, opts);\n                    input._valueSet(buffer.join(''));\n                    return true;\n                }\n            },\n            definitions: {\n                '~': { //real number\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        if (chrs == \"\") return false;\n                        if (!strict && pos <= 1 && buffer[0] === '0' && new RegExp(\"[\\\\d-]\").test(chrs) && buffer.join('').length == 1) { //handle first char\n                            buffer[0] = \"\";\n                            return { \"pos\": 0 };\n                        }\n\n                        var cbuf = strict ? buffer.slice(0, pos) : buffer.slice();\n\n                        cbuf.splice(pos, 0, chrs);\n                        var bufferStr = cbuf.join('');\n\n                        //strip groupseparator\n                        var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, opts.groupSeparator);\n                        bufferStr = bufferStr.replace(new RegExp(escapedGroupSeparator, \"g\"), '');\n\n                        var isValid = opts.regex.number(opts).test(bufferStr);\n                        if (!isValid) {\n                            //let's help the regex a bit\n                            bufferStr += \"0\";\n                            isValid = opts.regex.number(opts).test(bufferStr);\n                            if (!isValid) {\n                                //make a valid group\n                                var lastGroupSeparator = bufferStr.lastIndexOf(opts.groupSeparator);\n                                for (var i = bufferStr.length - lastGroupSeparator; i <= 3; i++) {\n                                    bufferStr += \"0\";\n                                }\n\n                                isValid = opts.regex.number(opts).test(bufferStr);\n                                if (!isValid && !strict) {\n                                    if (chrs == opts.radixPoint) {\n                                        isValid = opts.regex.number(opts).test(\"0\" + bufferStr + \"0\");\n                                        if (isValid) {\n                                            buffer[pos] = \"0\";\n                                            pos++;\n                                            return { \"pos\": pos };\n                                        }\n                                    }\n                                }\n                            }\n                        }\n\n                        if (isValid != false && !strict && chrs != opts.radixPoint) {\n                            var newPos = opts.postFormat(buffer, pos, false, opts);\n                            return { \"pos\": newPos };\n                        }\n\n                        return isValid;\n                    },\n                    cardinality: 1,\n                    prevalidator: null\n                }\n            },\n            insertMode: true,\n            autoUnmask: false\n        },\n        'integer': {\n            regex: {\n                number: function (opts) {\n                    var escapedGroupSeparator = $.inputmask.escapeRegex.call(this, opts.groupSeparator);\n                    var signedExpression = opts.allowPlus || opts.allowMinus ? \"[\" + (opts.allowPlus ? \"\\+\" : \"\") + (opts.allowMinus ? \"-\" : \"\") + \"]?\" : \"\";\n                    return new RegExp(\"^\" + signedExpression + \"(\\\\d+|\\\\d{1,\" + opts.groupSize + \"}((\" + escapedGroupSeparator + \"\\\\d{\" + opts.groupSize + \"})?)+)$\");\n                }\n            },\n            alias: \"decimal\"\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/input-mask/jquery.inputmask.phone.extensions.js",
    "content": "/*\nInput Mask plugin extensions\nhttp://github.com/RobinHerbots/jquery.inputmask\nCopyright (c) 2010 - 2014 Robin Herbots\nLicensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)\nVersion: 0.0.0\n\nPhone extension.\nWhen using this extension make sure you specify the correct url to get the masks\n\n $(selector).inputmask(\"phone\", {\n                url: \"Scripts/jquery.inputmask/phone-codes/phone-codes.json\", \n                onKeyValidation: function () { //show some metadata in the console\n                    console.log($(this).inputmask(\"getmetadata\")[\"name_en\"]);\n                } \n  });\n\n\n*/\n(function ($) {\n    $.extend($.inputmask.defaults.aliases, {\n        'phone': {\n            url: \"phone-codes/phone-codes.json\",\n            mask: function (opts) {\n                opts.definitions = {\n                    'p': {\n                        validator: function () { return false; },\n                        cardinality: 1\n                    },\n                    '#': {\n                        validator: \"[0-9]\",\n                        cardinality: 1\n                    }\n                };\n                var maskList = [];\n                $.ajax({\n                    url: opts.url,\n                    async: false,\n                    dataType: 'json',\n                    success: function (response) {\n                        maskList = response;\n                    }\n                });\n    \n                maskList.splice(0, 0, \"+p(ppp)ppp-pppp\");\n                return maskList;\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/input-mask/jquery.inputmask.regex.extensions.js",
    "content": "/*\nInput Mask plugin extensions\nhttp://github.com/RobinHerbots/jquery.inputmask\nCopyright (c) 2010 - 2014 Robin Herbots\nLicensed under the MIT license (http://www.opensource.org/licenses/mit-license.php)\nVersion: 0.0.0\n\nRegex extensions on the jquery.inputmask base\nAllows for using regular expressions as a mask\n*/\n(function ($) {\n    $.extend($.inputmask.defaults.aliases, { // $(selector).inputmask(\"Regex\", { regex: \"[0-9]*\"}\n        'Regex': {\n            mask: \"r\",\n            greedy: false,\n            repeat: \"*\",\n            regex: null,\n            regexTokens: null,\n            //Thx to https://github.com/slevithan/regex-colorizer for the tokenizer regex\n            tokenizer: /\\[\\^?]?(?:[^\\\\\\]]+|\\\\[\\S\\s]?)*]?|\\\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9][0-9]*|x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4}|c[A-Za-z]|[\\S\\s]?)|\\((?:\\?[:=!]?)?|(?:[?*+]|\\{[0-9]+(?:,[0-9]*)?\\})\\??|[^.?*+^${[()|\\\\]+|./g,\n            quantifierFilter: /[0-9]+[^,]/,\n            definitions: {\n                'r': {\n                    validator: function (chrs, buffer, pos, strict, opts) {\n                        function regexToken() {\n                            this.matches = [];\n                            this.isGroup = false;\n                            this.isQuantifier = false;\n                            this.isLiteral = false;\n                        }\n                        function analyseRegex() {\n                            var currentToken = new regexToken(), match, m, opengroups = [];\n\n                            opts.regexTokens = [];\n\n                            // The tokenizer regex does most of the tokenization grunt work\n                            while (match = opts.tokenizer.exec(opts.regex)) {\n                                m = match[0];\n                                switch (m.charAt(0)) {\n                                    case \"[\": // Character class\n                                    case \"\\\\\":  // Escape or backreference\n                                        if (opengroups.length > 0) {\n                                            opengroups[opengroups.length - 1][\"matches\"].push(m);\n                                        } else {\n                                            currentToken.matches.push(m);\n                                        }\n                                        break;\n                                    case \"(\": // Group opening\n                                        if (!currentToken.isGroup && currentToken.matches.length > 0)\n                                            opts.regexTokens.push(currentToken);\n                                        currentToken = new regexToken();\n                                        currentToken.isGroup = true;\n                                        opengroups.push(currentToken);\n                                        break;\n                                    case \")\": // Group closing\n                                        var groupToken = opengroups.pop();\n                                        if (opengroups.length > 0) {\n                                            opengroups[opengroups.length - 1][\"matches\"].push(groupToken);\n                                        } else {\n                                            opts.regexTokens.push(groupToken);\n                                            currentToken = new regexToken();\n                                        }\n                                        break;\n                                    case \"{\": //Quantifier\n                                        var quantifier = new regexToken();\n                                        quantifier.isQuantifier = true;\n                                        quantifier.matches.push(m);\n                                        if (opengroups.length > 0) {\n                                            opengroups[opengroups.length - 1][\"matches\"].push(quantifier);\n                                        } else {\n                                            currentToken.matches.push(quantifier);\n                                        }\n                                        break;\n                                    default:\n                                        // Vertical bar (alternator) \n                                        // ^ or $ anchor\n                                        // Dot (.)\n                                        // Literal character sequence\n                                        var literal = new regexToken();\n                                        literal.isLiteral = true;\n                                        literal.matches.push(m);\n                                        if (opengroups.length > 0) {\n                                            opengroups[opengroups.length - 1][\"matches\"].push(literal);\n                                        } else {\n                                            currentToken.matches.push(literal);\n                                        }\n                                }\n                            }\n\n                            if (currentToken.matches.length > 0)\n                                opts.regexTokens.push(currentToken);\n                        }\n                        function validateRegexToken(token, fromGroup) {\n                            var isvalid = false;\n                            if (fromGroup) {\n                                regexPart += \"(\";\n                                openGroupCount++;\n                            }\n                            for (var mndx = 0; mndx < token[\"matches\"].length; mndx++) {\n                                var matchToken = token[\"matches\"][mndx];\n                                if (matchToken[\"isGroup\"] == true) {\n                                    isvalid = validateRegexToken(matchToken, true);\n                                } else if (matchToken[\"isQuantifier\"] == true) {\n                                    matchToken = matchToken[\"matches\"][0];\n                                    var quantifierMax = opts.quantifierFilter.exec(matchToken)[0].replace(\"}\", \"\");\n                                    var testExp = regexPart + \"{1,\" + quantifierMax + \"}\"; //relax quantifier validation\n                                    for (var j = 0; j < openGroupCount; j++) {\n                                        testExp += \")\";\n                                    }\n                                    var exp = new RegExp(\"^(\" + testExp + \")$\");\n                                    isvalid = exp.test(bufferStr);\n                                    regexPart += matchToken;\n                                } else if (matchToken[\"isLiteral\"] == true) {\n                                    matchToken = matchToken[\"matches\"][0];\n                                    var testExp = regexPart, openGroupCloser = \"\";\n                                    for (var j = 0; j < openGroupCount; j++) {\n                                        openGroupCloser += \")\";\n                                    }\n                                    for (var k = 0; k < matchToken.length; k++) { //relax literal validation\n                                        testExp = (testExp + matchToken[k]).replace(/\\|$/, \"\");\n                                        var exp = new RegExp(\"^(\" + testExp + openGroupCloser + \")$\");\n                                        isvalid = exp.test(bufferStr);\n                                        if (isvalid) break;\n                                    }\n                                    regexPart += matchToken;\n                                    //console.log(bufferStr + \" \" + exp + \" \" + isvalid);\n                                } else {\n                                    regexPart += matchToken;\n                                    var testExp = regexPart.replace(/\\|$/, \"\");\n                                    for (var j = 0; j < openGroupCount; j++) {\n                                        testExp += \")\";\n                                    }\n                                    var exp = new RegExp(\"^(\" + testExp + \")$\");\n                                    isvalid = exp.test(bufferStr);\n                                    //console.log(bufferStr + \" \" + exp + \" \" + isvalid);\n                                }\n                                if (isvalid) break;\n                            }\n\n                            if (fromGroup) {\n                                regexPart += \")\";\n                                openGroupCount--;\n                            }\n\n                            return isvalid;\n                        }\n\n\n                        if (opts.regexTokens == null) {\n                            analyseRegex();\n                        }\n\n                        var cbuffer = buffer.slice(), regexPart = \"\", isValid = false, openGroupCount = 0;\n                        cbuffer.splice(pos, 0, chrs);\n                        var bufferStr = cbuffer.join('');\n                        for (var i = 0; i < opts.regexTokens.length; i++) {\n                            var regexToken = opts.regexTokens[i];\n                            isValid = validateRegexToken(regexToken, regexToken[\"isGroup\"]);\n                            if (isValid) break;\n                        }\n\n                        return isValid;\n                    },\n                    cardinality: 1\n                }\n            }\n        }\n    });\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/input-mask/phone-codes/phone-be.json",
    "content": "[\n\t{ \"mask\": \"+32(53)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Aalst (Alost)\" },\n\t{ \"mask\": \"+32(3)###-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Antwerpen (Anvers)\" },\n\t{ \"mask\": \"+32(63)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Arlon\" },\n\t{ \"mask\": \"+32(67)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Ath\" },\n\t{ \"mask\": \"+32(50)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Brugge (Bruges)\" },\n\t{ \"mask\": \"+32(2)###-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Brussel/Bruxelles (Brussels)\" },\n\t{ \"mask\": \"+32(71)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Charleroi\" },\n\t{ \"mask\": \"+32(60)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Chimay\" },\n\t{ \"mask\": \"+32(83)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Ciney\" },\n\t{ \"mask\": \"+32(52)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Dendermonde\" },\n\t{ \"mask\": \"+32(13)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Diest\" },\n\t{ \"mask\": \"+32(82)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Dinant\" },\n\t{ \"mask\": \"+32(86)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Durbuy\" },\n\t{ \"mask\": \"+32(89)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Genk\" },\n\t{ \"mask\": \"+32(9)###-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Gent (Gand)\" },\n\t{ \"mask\": \"+32(11)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Hasselt\" },\n\t{ \"mask\": \"+32(14)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Herentals\" },\n\t{ \"mask\": \"+32(85)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Huy (Hoei)\" },\n\t{ \"mask\": \"+32(64)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"La Louvière\" },\n\t{ \"mask\": \"+32(16)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Leuven (Louvain)\" },\n\t{ \"mask\": \"+32(61)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Libramont\" },\n\t{ \"mask\": \"+32(4)###-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Liège (Luik)\" },\n\t{ \"mask\": \"+32(15)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Mechelen (Malines)\" },\n\t{ \"mask\": \"+32(47#)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Mobile Phones\" },    \n\t{ \"mask\": \"+32(48#)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Mobile Phones\" },    \n\t{ \"mask\": \"+32(49#)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Mobile Phones\" },    \n\t{ \"mask\": \"+32(65)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Mons (Bergen)\" },\n\t{ \"mask\": \"+32(81)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Namur (Namen)\" },\t\n\t{ \"mask\": \"+32(58)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Nieuwpoort (Nieuport)\" },\t\n\t{ \"mask\": \"+32(54)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Ninove\" },\n\t{ \"mask\": \"+32(67)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Nivelles (Nijvel)\" },\n\t{ \"mask\": \"+32(59)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Oostende (Ostende)\" },\n\t{ \"mask\": \"+32(51)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Roeselare (Roulers)\" },\n\t{ \"mask\": \"+32(55)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Ronse\" },\t\n\t{ \"mask\": \"+32(80)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Stavelot\" },\n\t{ \"mask\": \"+32(12)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Tongeren (Tongres)\" },\n\t{ \"mask\": \"+32(69)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Tounai\" },\n\t{ \"mask\": \"+32(14)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Turnhout\" },\n\t{ \"mask\": \"+32(87)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Verviers\" },\n\t{ \"mask\": \"+32(58)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Veurne\" },\n\t{ \"mask\": \"+32(19)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Wareme\" },\n\t{ \"mask\": \"+32(10)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Wavre (Waver)\" },\n\t{ \"mask\": \"+32(50)##-##-##\", \"cc\": \"BE\", \"cd\": \"Belgium\", \"city\": \"Zeebrugge\" }\n]"
  },
  {
    "path": "public/static/plugins/input-mask/phone-codes/phone-codes.json",
    "content": "[\n\t{ \"mask\": \"+247-####\", \"cc\": \"AC\", \"name_en\": \"Ascension\", \"desc_en\": \"\", \"name_ru\": \"Остров Вознесения\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+376-###-###\", \"cc\": \"AD\", \"name_en\": \"Andorra\", \"desc_en\": \"\", \"name_ru\": \"Андорра\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+971-5#-###-####\", \"cc\": \"AE\", \"name_en\": \"United Arab Emirates\", \"desc_en\": \"mobile\", \"name_ru\": \"Объединенные Арабские Эмираты\", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+971-#-###-####\", \"cc\": \"AE\", \"name_en\": \"United Arab Emirates\", \"desc_en\": \"\", \"name_ru\": \"Объединенные Арабские Эмираты\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+93-##-###-####\", \"cc\": \"AF\", \"name_en\": \"Afghanistan\", \"desc_en\": \"\", \"name_ru\": \"Афганистан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(268)###-####\", \"cc\": \"AG\", \"name_en\": \"Antigua & Barbuda\", \"desc_en\": \"\", \"name_ru\": \"Антигуа и Барбуда\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(264)###-####\", \"cc\": \"AI\", \"name_en\": \"Anguilla\", \"desc_en\": \"\", \"name_ru\": \"Ангилья\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+355(###)###-###\", \"cc\": \"AL\", \"name_en\": \"Albania\", \"desc_en\": \"\", \"name_ru\": \"Албания\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+374-##-###-###\", \"cc\": \"AM\", \"name_en\": \"Armenia\", \"desc_en\": \"\", \"name_ru\": \"Армения\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+599-###-####\", \"cc\": \"AN\", \"name_en\": \"Caribbean Netherlands\", \"desc_en\": \"\", \"name_ru\": \"Карибские Нидерланды\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+599-###-####\", \"cc\": \"AN\", \"name_en\": \"Netherlands Antilles\", \"desc_en\": \"\", \"name_ru\": \"Нидерландские Антильские острова\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+599-9###-####\", \"cc\": \"AN\", \"name_en\": \"Netherlands Antilles\", \"desc_en\": \"Curacao\", \"name_ru\": \"Нидерландские Антильские острова\", \"desc_ru\": \"Кюрасао\" },\n\t{ \"mask\": \"+244(###)###-###\", \"cc\": \"AO\", \"name_en\": \"Angola\", \"desc_en\": \"\", \"name_ru\": \"Ангола\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+672-1##-###\", \"cc\": \"AQ\", \"name_en\": \"Australian bases in Antarctica\", \"desc_en\": \"\", \"name_ru\": \"Австралийская антарктическая база\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+54(###)###-####\", \"cc\": \"AR\", \"name_en\": \"Argentina\", \"desc_en\": \"\", \"name_ru\": \"Аргентина\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(684)###-####\", \"cc\": \"AS\", \"name_en\": \"American Samoa\", \"desc_en\": \"\", \"name_ru\": \"Американское Самоа\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+43(###)###-####\", \"cc\": \"AT\", \"name_en\": \"Austria\", \"desc_en\": \"\", \"name_ru\": \"Австрия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+61-#-####-####\", \"cc\": \"AU\", \"name_en\": \"Australia\", \"desc_en\": \"\", \"name_ru\": \"Австралия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+297-###-####\", \"cc\": \"AW\", \"name_en\": \"Aruba\", \"desc_en\": \"\", \"name_ru\": \"Аруба\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+994-##-###-##-##\", \"cc\": \"AZ\", \"name_en\": \"Azerbaijan\", \"desc_en\": \"\", \"name_ru\": \"Азербайджан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+387-##-#####\", \"cc\": \"BA\", \"name_en\": \"Bosnia and Herzegovina\", \"desc_en\": \"\", \"name_ru\": \"Босния и Герцеговина\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+387-##-####\", \"cc\": \"BA\", \"name_en\": \"Bosnia and Herzegovina\", \"desc_en\": \"\", \"name_ru\": \"Босния и Герцеговина\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(246)###-####\", \"cc\": \"BB\", \"name_en\": \"Barbados\", \"desc_en\": \"\", \"name_ru\": \"Барбадос\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+880-##-###-###\", \"cc\": \"BD\", \"name_en\": \"Bangladesh\", \"desc_en\": \"\", \"name_ru\": \"Бангладеш\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+32(###)###-###\", \"cc\": \"BE\", \"name_en\": \"Belgium\", \"desc_en\": \"\", \"name_ru\": \"Бельгия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+226-##-##-####\", \"cc\": \"BF\", \"name_en\": \"Burkina Faso\", \"desc_en\": \"\", \"name_ru\": \"Буркина Фасо\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+359(###)###-###\", \"cc\": \"BG\", \"name_en\": \"Bulgaria\", \"desc_en\": \"\", \"name_ru\": \"Болгария\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+973-####-####\", \"cc\": \"BH\", \"name_en\": \"Bahrain\", \"desc_en\": \"\", \"name_ru\": \"Бахрейн\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+257-##-##-####\", \"cc\": \"BI\", \"name_en\": \"Burundi\", \"desc_en\": \"\", \"name_ru\": \"Бурунди\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+229-##-##-####\", \"cc\": \"BJ\", \"name_en\": \"Benin\", \"desc_en\": \"\", \"name_ru\": \"Бенин\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(441)###-####\", \"cc\": \"BM\", \"name_en\": \"Bermuda\", \"desc_en\": \"\", \"name_ru\": \"Бермудские острова\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+673-###-####\", \"cc\": \"BN\", \"name_en\": \"Brunei Darussalam\", \"desc_en\": \"\", \"name_ru\": \"Бруней-Даруссалам\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+591-#-###-####\", \"cc\": \"BO\", \"name_en\": \"Bolivia\", \"desc_en\": \"\", \"name_ru\": \"Боливия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+55-##-####[#]-####\", \"cc\": \"BR\", \"name_en\": \"Brazil\", \"desc_en\": \"\", \"name_ru\": \"Бразилия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(242)###-####\", \"cc\": \"BS\", \"name_en\": \"Bahamas\", \"desc_en\": \"\", \"name_ru\": \"Багамские Острова\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+975-17-###-###\", \"cc\": \"BT\", \"name_en\": \"Bhutan\", \"desc_en\": \"\", \"name_ru\": \"Бутан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+975-#-###-###\", \"cc\": \"BT\", \"name_en\": \"Bhutan\", \"desc_en\": \"\", \"name_ru\": \"Бутан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+267-##-###-###\", \"cc\": \"BW\", \"name_en\": \"Botswana\", \"desc_en\": \"\", \"name_ru\": \"Ботсвана\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+375(##)###-##-##\", \"cc\": \"BY\", \"name_en\": \"Belarus\", \"desc_en\": \"\", \"name_ru\": \"Беларусь (Белоруссия)\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+501-###-####\", \"cc\": \"BZ\", \"name_en\": \"Belize\", \"desc_en\": \"\", \"name_ru\": \"Белиз\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+243(###)###-###\", \"cc\": \"CD\", \"name_en\": \"Dem. Rep. Congo\", \"desc_en\": \"\", \"name_ru\": \"Дем. Респ. Конго (Киншаса)\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+236-##-##-####\", \"cc\": \"CF\", \"name_en\": \"Central African Republic\", \"desc_en\": \"\", \"name_ru\": \"Центральноафриканская Республика\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+242-##-###-####\", \"cc\": \"CG\", \"name_en\": \"Congo (Brazzaville)\", \"desc_en\": \"\", \"name_ru\": \"Конго (Браззавиль)\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+41-##-###-####\", \"cc\": \"CH\", \"name_en\": \"Switzerland\", \"desc_en\": \"\", \"name_ru\": \"Швейцария\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+225-##-###-###\", \"cc\": \"CI\", \"name_en\": \"Cote d’Ivoire (Ivory Coast)\", \"desc_en\": \"\", \"name_ru\": \"Кот-д’Ивуар\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+682-##-###\", \"cc\": \"CK\", \"name_en\": \"Cook Islands\", \"desc_en\": \"\", \"name_ru\": \"Острова Кука\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+56-#-####-####\", \"cc\": \"CL\", \"name_en\": \"Chile\", \"desc_en\": \"\", \"name_ru\": \"Чили\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+237-####-####\", \"cc\": \"CM\", \"name_en\": \"Cameroon\", \"desc_en\": \"\", \"name_ru\": \"Камерун\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+86(###)####-####\", \"cc\": \"CN\", \"name_en\": \"China (PRC)\", \"desc_en\": \"\", \"name_ru\": \"Китайская Н.Р.\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+86(###)####-###\", \"cc\": \"CN\", \"name_en\": \"China (PRC)\", \"desc_en\": \"\", \"name_ru\": \"Китайская Н.Р.\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+86-##-#####-#####\", \"cc\": \"CN\", \"name_en\": \"China (PRC)\", \"desc_en\": \"\", \"name_ru\": \"Китайская Н.Р.\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+57(###)###-####\", \"cc\": \"CO\", \"name_en\": \"Colombia\", \"desc_en\": \"\", \"name_ru\": \"Колумбия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+506-####-####\", \"cc\": \"CR\", \"name_en\": \"Costa Rica\", \"desc_en\": \"\", \"name_ru\": \"Коста-Рика\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+53-#-###-####\", \"cc\": \"CU\", \"name_en\": \"Cuba\", \"desc_en\": \"\", \"name_ru\": \"Куба\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+238(###)##-##\", \"cc\": \"CV\", \"name_en\": \"Cape Verde\", \"desc_en\": \"\", \"name_ru\": \"Кабо-Верде\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+599-###-####\", \"cc\": \"CW\", \"name_en\": \"Curacao\", \"desc_en\": \"\", \"name_ru\": \"Кюрасао\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+357-##-###-###\", \"cc\": \"CY\", \"name_en\": \"Cyprus\", \"desc_en\": \"\", \"name_ru\": \"Кипр\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+420(###)###-###\", \"cc\": \"CZ\", \"name_en\": \"Czech Republic\", \"desc_en\": \"\", \"name_ru\": \"Чехия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+49(####)###-####\", \"cc\": \"DE\", \"name_en\": \"Germany\", \"desc_en\": \"\", \"name_ru\": \"Германия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+49(###)###-####\", \"cc\": \"DE\", \"name_en\": \"Germany\", \"desc_en\": \"\", \"name_ru\": \"Германия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+49(###)##-####\", \"cc\": \"DE\", \"name_en\": \"Germany\", \"desc_en\": \"\", \"name_ru\": \"Германия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+49(###)##-###\", \"cc\": \"DE\", \"name_en\": \"Germany\", \"desc_en\": \"\", \"name_ru\": \"Германия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+49(###)##-##\", \"cc\": \"DE\", \"name_en\": \"Germany\", \"desc_en\": \"\", \"name_ru\": \"Германия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+49-###-###\", \"cc\": \"DE\", \"name_en\": \"Germany\", \"desc_en\": \"\", \"name_ru\": \"Германия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+253-##-##-##-##\", \"cc\": \"DJ\", \"name_en\": \"Djibouti\", \"desc_en\": \"\", \"name_ru\": \"Джибути\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+45-##-##-##-##\", \"cc\": \"DK\", \"name_en\": \"Denmark\", \"desc_en\": \"\", \"name_ru\": \"Дания\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(767)###-####\", \"cc\": \"DM\", \"name_en\": \"Dominica\", \"desc_en\": \"\", \"name_ru\": \"Доминика\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(809)###-####\", \"cc\": \"DO\", \"name_en\": \"Dominican Republic\", \"desc_en\": \"\", \"name_ru\": \"Доминиканская Республика\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(829)###-####\", \"cc\": \"DO\", \"name_en\": \"Dominican Republic\", \"desc_en\": \"\", \"name_ru\": \"Доминиканская Республика\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(849)###-####\", \"cc\": \"DO\", \"name_en\": \"Dominican Republic\", \"desc_en\": \"\", \"name_ru\": \"Доминиканская Республика\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+213-##-###-####\", \"cc\": \"DZ\", \"name_en\": \"Algeria\", \"desc_en\": \"\", \"name_ru\": \"Алжир\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+593-##-###-####\", \"cc\": \"EC\", \"name_en\": \"Ecuador \", \"desc_en\": \"mobile\", \"name_ru\": \"Эквадор \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+593-#-###-####\", \"cc\": \"EC\", \"name_en\": \"Ecuador\", \"desc_en\": \"\", \"name_ru\": \"Эквадор\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+372-####-####\", \"cc\": \"EE\", \"name_en\": \"Estonia \", \"desc_en\": \"mobile\", \"name_ru\": \"Эстония \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+372-###-####\", \"cc\": \"EE\", \"name_en\": \"Estonia\", \"desc_en\": \"\", \"name_ru\": \"Эстония\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+20(###)###-####\", \"cc\": \"EG\", \"name_en\": \"Egypt\", \"desc_en\": \"\", \"name_ru\": \"Египет\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+291-#-###-###\", \"cc\": \"ER\", \"name_en\": \"Eritrea\", \"desc_en\": \"\", \"name_ru\": \"Эритрея\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+34(###)###-###\", \"cc\": \"ES\", \"name_en\": \"Spain\", \"desc_en\": \"\", \"name_ru\": \"Испания\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+251-##-###-####\", \"cc\": \"ET\", \"name_en\": \"Ethiopia\", \"desc_en\": \"\", \"name_ru\": \"Эфиопия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+358(###)###-##-##\", \"cc\": \"FI\", \"name_en\": \"Finland\", \"desc_en\": \"\", \"name_ru\": \"Финляндия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+679-##-#####\", \"cc\": \"FJ\", \"name_en\": \"Fiji\", \"desc_en\": \"\", \"name_ru\": \"Фиджи\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+500-#####\", \"cc\": \"FK\", \"name_en\": \"Falkland Islands\", \"desc_en\": \"\", \"name_ru\": \"Фолклендские острова\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+691-###-####\", \"cc\": \"FM\", \"name_en\": \"F.S. Micronesia\", \"desc_en\": \"\", \"name_ru\": \"Ф.Ш. Микронезии\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+298-###-###\", \"cc\": \"FO\", \"name_en\": \"Faroe Islands\", \"desc_en\": \"\", \"name_ru\": \"Фарерские острова\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+262-#####-####\", \"cc\": \"FR\", \"name_en\": \"Mayotte\", \"desc_en\": \"\", \"name_ru\": \"Майотта\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+33(###)###-###\", \"cc\": \"FR\", \"name_en\": \"France\", \"desc_en\": \"\", \"name_ru\": \"Франция\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+508-##-####\", \"cc\": \"FR\", \"name_en\": \"St Pierre & Miquelon\", \"desc_en\": \"\", \"name_ru\": \"Сен-Пьер и Микелон\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+590(###)###-###\", \"cc\": \"FR\", \"name_en\": \"Guadeloupe\", \"desc_en\": \"\", \"name_ru\": \"Гваделупа\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+241-#-##-##-##\", \"cc\": \"GA\", \"name_en\": \"Gabon\", \"desc_en\": \"\", \"name_ru\": \"Габон\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(473)###-####\", \"cc\": \"GD\", \"name_en\": \"Grenada\", \"desc_en\": \"\", \"name_ru\": \"Гренада\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+995(###)###-###\", \"cc\": \"GE\", \"name_en\": \"Rep. of Georgia\", \"desc_en\": \"\", \"name_ru\": \"Грузия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+594-#####-####\", \"cc\": \"GF\", \"name_en\": \"Guiana (French)\", \"desc_en\": \"\", \"name_ru\": \"Фр. Гвиана\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+233(###)###-###\", \"cc\": \"GH\", \"name_en\": \"Ghana\", \"desc_en\": \"\", \"name_ru\": \"Гана\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+350-###-#####\", \"cc\": \"GI\", \"name_en\": \"Gibraltar\", \"desc_en\": \"\", \"name_ru\": \"Гибралтар\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+299-##-##-##\", \"cc\": \"GL\", \"name_en\": \"Greenland\", \"desc_en\": \"\", \"name_ru\": \"Гренландия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+220(###)##-##\", \"cc\": \"GM\", \"name_en\": \"Gambia\", \"desc_en\": \"\", \"name_ru\": \"Гамбия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+224-##-###-###\", \"cc\": \"GN\", \"name_en\": \"Guinea\", \"desc_en\": \"\", \"name_ru\": \"Гвинея\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+240-##-###-####\", \"cc\": \"GQ\", \"name_en\": \"Equatorial Guinea\", \"desc_en\": \"\", \"name_ru\": \"Экваториальная Гвинея\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+30(###)###-####\", \"cc\": \"GR\", \"name_en\": \"Greece\", \"desc_en\": \"\", \"name_ru\": \"Греция\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+502-#-###-####\", \"cc\": \"GT\", \"name_en\": \"Guatemala\", \"desc_en\": \"\", \"name_ru\": \"Гватемала\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(671)###-####\", \"cc\": \"GU\", \"name_en\": \"Guam\", \"desc_en\": \"\", \"name_ru\": \"Гуам\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+245-#-######\", \"cc\": \"GW\", \"name_en\": \"Guinea-Bissau\", \"desc_en\": \"\", \"name_ru\": \"Гвинея-Бисау\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+592-###-####\", \"cc\": \"GY\", \"name_en\": \"Guyana\", \"desc_en\": \"\", \"name_ru\": \"Гайана\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+852-####-####\", \"cc\": \"HK\", \"name_en\": \"Hong Kong\", \"desc_en\": \"\", \"name_ru\": \"Гонконг\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+504-####-####\", \"cc\": \"HN\", \"name_en\": \"Honduras\", \"desc_en\": \"\", \"name_ru\": \"Гондурас\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+385-##-###-###\", \"cc\": \"HR\", \"name_en\": \"Croatia\", \"desc_en\": \"\", \"name_ru\": \"Хорватия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+509-##-##-####\", \"cc\": \"HT\", \"name_en\": \"Haiti\", \"desc_en\": \"\", \"name_ru\": \"Гаити\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+36(###)###-###\", \"cc\": \"HU\", \"name_en\": \"Hungary\", \"desc_en\": \"\", \"name_ru\": \"Венгрия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+62(8##)###-####\", \"cc\": \"ID\", \"name_en\": \"Indonesia \", \"desc_en\": \"mobile\", \"name_ru\": \"Индонезия \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+62-##-###-##\", \"cc\": \"ID\", \"name_en\": \"Indonesia\", \"desc_en\": \"\", \"name_ru\": \"Индонезия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+62-##-###-###\", \"cc\": \"ID\", \"name_en\": \"Indonesia\", \"desc_en\": \"\", \"name_ru\": \"Индонезия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+62-##-###-####\", \"cc\": \"ID\", \"name_en\": \"Indonesia\", \"desc_en\": \"\", \"name_ru\": \"Индонезия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+62(8##)###-###\", \"cc\": \"ID\", \"name_en\": \"Indonesia \", \"desc_en\": \"mobile\", \"name_ru\": \"Индонезия \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+62(8##)###-##-###\", \"cc\": \"ID\", \"name_en\": \"Indonesia \", \"desc_en\": \"mobile\", \"name_ru\": \"Индонезия \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+353(###)###-###\", \"cc\": \"IE\", \"name_en\": \"Ireland\", \"desc_en\": \"\", \"name_ru\": \"Ирландия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+972-5#-###-####\", \"cc\": \"IL\", \"name_en\": \"Israel \", \"desc_en\": \"mobile\", \"name_ru\": \"Израиль \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+972-#-###-####\", \"cc\": \"IL\", \"name_en\": \"Israel\", \"desc_en\": \"\", \"name_ru\": \"Израиль\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+91(####)###-###\", \"cc\": \"IN\", \"name_en\": \"India\", \"desc_en\": \"\", \"name_ru\": \"Индия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+246-###-####\", \"cc\": \"IO\", \"name_en\": \"Diego Garcia\", \"desc_en\": \"\", \"name_ru\": \"Диего-Гарсия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+964(###)###-####\", \"cc\": \"IQ\", \"name_en\": \"Iraq\", \"desc_en\": \"\", \"name_ru\": \"Ирак\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+98(###)###-####\", \"cc\": \"IR\", \"name_en\": \"Iran\", \"desc_en\": \"\", \"name_ru\": \"Иран\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+354-###-####\", \"cc\": \"IS\", \"name_en\": \"Iceland\", \"desc_en\": \"\", \"name_ru\": \"Исландия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+39(###)####-###\", \"cc\": \"IT\", \"name_en\": \"Italy\", \"desc_en\": \"\", \"name_ru\": \"Италия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(876)###-####\", \"cc\": \"JM\", \"name_en\": \"Jamaica\", \"desc_en\": \"\", \"name_ru\": \"Ямайка\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+962-#-####-####\", \"cc\": \"JO\", \"name_en\": \"Jordan\", \"desc_en\": \"\", \"name_ru\": \"Иордания\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+81-##-####-####\", \"cc\": \"JP\", \"name_en\": \"Japan \", \"desc_en\": \"mobile\", \"name_ru\": \"Япония \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+81(###)###-###\", \"cc\": \"JP\", \"name_en\": \"Japan\", \"desc_en\": \"\", \"name_ru\": \"Япония\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+254-###-######\", \"cc\": \"KE\", \"name_en\": \"Kenya\", \"desc_en\": \"\", \"name_ru\": \"Кения\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+996(###)###-###\", \"cc\": \"KG\", \"name_en\": \"Kyrgyzstan\", \"desc_en\": \"\", \"name_ru\": \"Киргизия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+855-##-###-###\", \"cc\": \"KH\", \"name_en\": \"Cambodia\", \"desc_en\": \"\", \"name_ru\": \"Камбоджа\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+686-##-###\", \"cc\": \"KI\", \"name_en\": \"Kiribati\", \"desc_en\": \"\", \"name_ru\": \"Кирибати\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+269-##-#####\", \"cc\": \"KM\", \"name_en\": \"Comoros\", \"desc_en\": \"\", \"name_ru\": \"Коморы\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(869)###-####\", \"cc\": \"KN\", \"name_en\": \"Saint Kitts & Nevis\", \"desc_en\": \"\", \"name_ru\": \"Сент-Китс и Невис\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+850-191-###-####\", \"cc\": \"KP\", \"name_en\": \"DPR Korea (North) \", \"desc_en\": \"mobile\", \"name_ru\": \"Корейская НДР \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+850-##-###-###\", \"cc\": \"KP\", \"name_en\": \"DPR Korea (North)\", \"desc_en\": \"\", \"name_ru\": \"Корейская НДР\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+850-###-####-###\", \"cc\": \"KP\", \"name_en\": \"DPR Korea (North)\", \"desc_en\": \"\", \"name_ru\": \"Корейская НДР\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+850-###-###\", \"cc\": \"KP\", \"name_en\": \"DPR Korea (North)\", \"desc_en\": \"\", \"name_ru\": \"Корейская НДР\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+850-####-####\", \"cc\": \"KP\", \"name_en\": \"DPR Korea (North)\", \"desc_en\": \"\", \"name_ru\": \"Корейская НДР\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+850-####-#############\", \"cc\": \"KP\", \"name_en\": \"DPR Korea (North)\", \"desc_en\": \"\", \"name_ru\": \"Корейская НДР\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+82-##-###-####\", \"cc\": \"KR\", \"name_en\": \"Korea (South)\", \"desc_en\": \"\", \"name_ru\": \"Респ. Корея\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+965-####-####\", \"cc\": \"KW\", \"name_en\": \"Kuwait\", \"desc_en\": \"\", \"name_ru\": \"Кувейт\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(345)###-####\", \"cc\": \"KY\", \"name_en\": \"Cayman Islands\", \"desc_en\": \"\", \"name_ru\": \"Каймановы острова\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+7(6##)###-##-##\", \"cc\": \"KZ\", \"name_en\": \"Kazakhstan\", \"desc_en\": \"\", \"name_ru\": \"Казахстан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+7(7##)###-##-##\", \"cc\": \"KZ\", \"name_en\": \"Kazakhstan\", \"desc_en\": \"\", \"name_ru\": \"Казахстан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+856(20##)###-###\", \"cc\": \"LA\", \"name_en\": \"Laos \", \"desc_en\": \"mobile\", \"name_ru\": \"Лаос \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+856-##-###-###\", \"cc\": \"LA\", \"name_en\": \"Laos\", \"desc_en\": \"\", \"name_ru\": \"Лаос\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+961-##-###-###\", \"cc\": \"LB\", \"name_en\": \"Lebanon \", \"desc_en\": \"mobile\", \"name_ru\": \"Ливан \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+961-#-###-###\", \"cc\": \"LB\", \"name_en\": \"Lebanon\", \"desc_en\": \"\", \"name_ru\": \"Ливан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(758)###-####\", \"cc\": \"LC\", \"name_en\": \"Saint Lucia\", \"desc_en\": \"\", \"name_ru\": \"Сент-Люсия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+423(###)###-####\", \"cc\": \"LI\", \"name_en\": \"Liechtenstein\", \"desc_en\": \"\", \"name_ru\": \"Лихтенштейн\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+94-##-###-####\", \"cc\": \"LK\", \"name_en\": \"Sri Lanka\", \"desc_en\": \"\", \"name_ru\": \"Шри-Ланка\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+231-##-###-###\", \"cc\": \"LR\", \"name_en\": \"Liberia\", \"desc_en\": \"\", \"name_ru\": \"Либерия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+266-#-###-####\", \"cc\": \"LS\", \"name_en\": \"Lesotho\", \"desc_en\": \"\", \"name_ru\": \"Лесото\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+370(###)##-###\", \"cc\": \"LT\", \"name_en\": \"Lithuania\", \"desc_en\": \"\", \"name_ru\": \"Литва\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+352(###)###-###\", \"cc\": \"LU\", \"name_en\": \"Luxembourg\", \"desc_en\": \"\", \"name_ru\": \"Люксембург\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+371-##-###-###\", \"cc\": \"LV\", \"name_en\": \"Latvia\", \"desc_en\": \"\", \"name_ru\": \"Латвия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+218-##-###-###\", \"cc\": \"LY\", \"name_en\": \"Libya\", \"desc_en\": \"\", \"name_ru\": \"Ливия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+218-21-###-####\", \"cc\": \"LY\", \"name_en\": \"Libya\", \"desc_en\": \"Tripoli\", \"name_ru\": \"Ливия\", \"desc_ru\": \"Триполи\" },\n\t{ \"mask\": \"+212-##-####-###\", \"cc\": \"MA\", \"name_en\": \"Morocco\", \"desc_en\": \"\", \"name_ru\": \"Марокко\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+377(###)###-###\", \"cc\": \"MC\", \"name_en\": \"Monaco\", \"desc_en\": \"\", \"name_ru\": \"Монако\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+377-##-###-###\", \"cc\": \"MC\", \"name_en\": \"Monaco\", \"desc_en\": \"\", \"name_ru\": \"Монако\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+373-####-####\", \"cc\": \"MD\", \"name_en\": \"Moldova\", \"desc_en\": \"\", \"name_ru\": \"Молдова\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+382-##-###-###\", \"cc\": \"ME\", \"name_en\": \"Montenegro\", \"desc_en\": \"\", \"name_ru\": \"Черногория\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+261-##-##-#####\", \"cc\": \"MG\", \"name_en\": \"Madagascar\", \"desc_en\": \"\", \"name_ru\": \"Мадагаскар\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+692-###-####\", \"cc\": \"MH\", \"name_en\": \"Marshall Islands\", \"desc_en\": \"\", \"name_ru\": \"Маршалловы Острова\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+389-##-###-###\", \"cc\": \"MK\", \"name_en\": \"Republic of Macedonia\", \"desc_en\": \"\", \"name_ru\": \"Респ. Македония\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+223-##-##-####\", \"cc\": \"ML\", \"name_en\": \"Mali\", \"desc_en\": \"\", \"name_ru\": \"Мали\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+95-##-###-###\", \"cc\": \"MM\", \"name_en\": \"Burma (Myanmar)\", \"desc_en\": \"\", \"name_ru\": \"Бирма (Мьянма)\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+95-#-###-###\", \"cc\": \"MM\", \"name_en\": \"Burma (Myanmar)\", \"desc_en\": \"\", \"name_ru\": \"Бирма (Мьянма)\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+95-###-###\", \"cc\": \"MM\", \"name_en\": \"Burma (Myanmar)\", \"desc_en\": \"\", \"name_ru\": \"Бирма (Мьянма)\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+976-##-##-####\", \"cc\": \"MN\", \"name_en\": \"Mongolia\", \"desc_en\": \"\", \"name_ru\": \"Монголия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+853-####-####\", \"cc\": \"MO\", \"name_en\": \"Macau\", \"desc_en\": \"\", \"name_ru\": \"Макао\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(670)###-####\", \"cc\": \"MP\", \"name_en\": \"Northern Mariana Islands\", \"desc_en\": \"\", \"name_ru\": \"Северные Марианские острова Сайпан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+596(###)##-##-##\", \"cc\": \"MQ\", \"name_en\": \"Martinique\", \"desc_en\": \"\", \"name_ru\": \"Мартиника\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+222-##-##-####\", \"cc\": \"MR\", \"name_en\": \"Mauritania\", \"desc_en\": \"\", \"name_ru\": \"Мавритания\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(664)###-####\", \"cc\": \"MS\", \"name_en\": \"Montserrat\", \"desc_en\": \"\", \"name_ru\": \"Монтсеррат\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+356-####-####\", \"cc\": \"MT\", \"name_en\": \"Malta\", \"desc_en\": \"\", \"name_ru\": \"Мальта\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+230-###-####\", \"cc\": \"MU\", \"name_en\": \"Mauritius\", \"desc_en\": \"\", \"name_ru\": \"Маврикий\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+960-###-####\", \"cc\": \"MV\", \"name_en\": \"Maldives\", \"desc_en\": \"\", \"name_ru\": \"Мальдивские острова\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+265-1-###-###\", \"cc\": \"MW\", \"name_en\": \"Malawi\", \"desc_en\": \"Telecom Ltd\", \"name_ru\": \"Малави\", \"desc_ru\": \"Telecom Ltd\" },\n\t{ \"mask\": \"+265-#-####-####\", \"cc\": \"MW\", \"name_en\": \"Malawi\", \"desc_en\": \"\", \"name_ru\": \"Малави\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+52(###)###-####\", \"cc\": \"MX\", \"name_en\": \"Mexico\", \"desc_en\": \"\", \"name_ru\": \"Мексика\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+52-##-##-####\", \"cc\": \"MX\", \"name_en\": \"Mexico\", \"desc_en\": \"\", \"name_ru\": \"Мексика\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+60-##-###-####\", \"cc\": \"MY\", \"name_en\": \"Malaysia \", \"desc_en\": \"mobile\", \"name_ru\": \"Малайзия \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+60(###)###-###\", \"cc\": \"MY\", \"name_en\": \"Malaysia\", \"desc_en\": \"\", \"name_ru\": \"Малайзия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+60-##-###-###\", \"cc\": \"MY\", \"name_en\": \"Malaysia\", \"desc_en\": \"\", \"name_ru\": \"Малайзия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+60-#-###-###\", \"cc\": \"MY\", \"name_en\": \"Malaysia\", \"desc_en\": \"\", \"name_ru\": \"Малайзия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+258-##-###-###\", \"cc\": \"MZ\", \"name_en\": \"Mozambique\", \"desc_en\": \"\", \"name_ru\": \"Мозамбик\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+264-##-###-####\", \"cc\": \"NA\", \"name_en\": \"Namibia\", \"desc_en\": \"\", \"name_ru\": \"Намибия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+687-##-####\", \"cc\": \"NC\", \"name_en\": \"New Caledonia\", \"desc_en\": \"\", \"name_ru\": \"Новая Каледония\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+227-##-##-####\", \"cc\": \"NE\", \"name_en\": \"Niger\", \"desc_en\": \"\", \"name_ru\": \"Нигер\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+672-3##-###\", \"cc\": \"NF\", \"name_en\": \"Norfolk Island\", \"desc_en\": \"\", \"name_ru\": \"Норфолк (остров)\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+234(###)###-####\", \"cc\": \"NG\", \"name_en\": \"Nigeria\", \"desc_en\": \"\", \"name_ru\": \"Нигерия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+234-##-###-###\", \"cc\": \"NG\", \"name_en\": \"Nigeria\", \"desc_en\": \"\", \"name_ru\": \"Нигерия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+234-##-###-##\", \"cc\": \"NG\", \"name_en\": \"Nigeria\", \"desc_en\": \"\", \"name_ru\": \"Нигерия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+234(###)###-####\", \"cc\": \"NG\", \"name_en\": \"Nigeria \", \"desc_en\": \"mobile\", \"name_ru\": \"Нигерия \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+505-####-####\", \"cc\": \"NI\", \"name_en\": \"Nicaragua\", \"desc_en\": \"\", \"name_ru\": \"Никарагуа\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+31-##-###-####\", \"cc\": \"NL\", \"name_en\": \"Netherlands\", \"desc_en\": \"\", \"name_ru\": \"Нидерланды\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+47(###)##-###\", \"cc\": \"NO\", \"name_en\": \"Norway\", \"desc_en\": \"\", \"name_ru\": \"Норвегия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+977-##-###-###\", \"cc\": \"NP\", \"name_en\": \"Nepal\", \"desc_en\": \"\", \"name_ru\": \"Непал\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+674-###-####\", \"cc\": \"NR\", \"name_en\": \"Nauru\", \"desc_en\": \"\", \"name_ru\": \"Науру\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+683-####\", \"cc\": \"NU\", \"name_en\": \"Niue\", \"desc_en\": \"\", \"name_ru\": \"Ниуэ\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+64(###)###-###\", \"cc\": \"NZ\", \"name_en\": \"New Zealand\", \"desc_en\": \"\", \"name_ru\": \"Новая Зеландия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+64-##-###-###\", \"cc\": \"NZ\", \"name_en\": \"New Zealand\", \"desc_en\": \"\", \"name_ru\": \"Новая Зеландия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+64(###)###-####\", \"cc\": \"NZ\", \"name_en\": \"New Zealand\", \"desc_en\": \"\", \"name_ru\": \"Новая Зеландия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+968-##-###-###\", \"cc\": \"OM\", \"name_en\": \"Oman\", \"desc_en\": \"\", \"name_ru\": \"Оман\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+507-###-####\", \"cc\": \"PA\", \"name_en\": \"Panama\", \"desc_en\": \"\", \"name_ru\": \"Панама\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+51(###)###-###\", \"cc\": \"PE\", \"name_en\": \"Peru\", \"desc_en\": \"\", \"name_ru\": \"Перу\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+689-##-##-##\", \"cc\": \"PF\", \"name_en\": \"French Polynesia\", \"desc_en\": \"\", \"name_ru\": \"Французская Полинезия (Таити)\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+675(###)##-###\", \"cc\": \"PG\", \"name_en\": \"Papua New Guinea\", \"desc_en\": \"\", \"name_ru\": \"Папуа-Новая Гвинея\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+63(###)###-####\", \"cc\": \"PH\", \"name_en\": \"Philippines\", \"desc_en\": \"\", \"name_ru\": \"Филиппины\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+92(###)###-####\", \"cc\": \"PK\", \"name_en\": \"Pakistan\", \"desc_en\": \"\", \"name_ru\": \"Пакистан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+48(###)###-###\", \"cc\": \"PL\", \"name_en\": \"Poland\", \"desc_en\": \"\", \"name_ru\": \"Польша\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+970-##-###-####\", \"cc\": \"PS\", \"name_en\": \"Palestine\", \"desc_en\": \"\", \"name_ru\": \"Палестина\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+351-##-###-####\", \"cc\": \"PT\", \"name_en\": \"Portugal\", \"desc_en\": \"\", \"name_ru\": \"Португалия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+680-###-####\", \"cc\": \"PW\", \"name_en\": \"Palau\", \"desc_en\": \"\", \"name_ru\": \"Палау\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+595(###)###-###\", \"cc\": \"PY\", \"name_en\": \"Paraguay\", \"desc_en\": \"\", \"name_ru\": \"Парагвай\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+974-####-####\", \"cc\": \"QA\", \"name_en\": \"Qatar\", \"desc_en\": \"\", \"name_ru\": \"Катар\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+262-#####-####\", \"cc\": \"RE\", \"name_en\": \"Reunion\", \"desc_en\": \"\", \"name_ru\": \"Реюньон\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+40-##-###-####\", \"cc\": \"RO\", \"name_en\": \"Romania\", \"desc_en\": \"\", \"name_ru\": \"Румыния\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+381-##-###-####\", \"cc\": \"RS\", \"name_en\": \"Serbia\", \"desc_en\": \"\", \"name_ru\": \"Сербия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+7(###)###-##-##\", \"cc\": \"RU\", \"name_en\": \"Russia\", \"desc_en\": \"\", \"name_ru\": \"Россия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+250(###)###-###\", \"cc\": \"RW\", \"name_en\": \"Rwanda\", \"desc_en\": \"\", \"name_ru\": \"Руанда\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+966-5-####-####\", \"cc\": \"SA\", \"name_en\": \"Saudi Arabia \", \"desc_en\": \"mobile\", \"name_ru\": \"Саудовская Аравия \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+966-#-###-####\", \"cc\": \"SA\", \"name_en\": \"Saudi Arabia\", \"desc_en\": \"\", \"name_ru\": \"Саудовская Аравия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+677-###-####\", \"cc\": \"SB\", \"name_en\": \"Solomon Islands \", \"desc_en\": \"mobile\", \"name_ru\": \"Соломоновы Острова \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+677-#####\", \"cc\": \"SB\", \"name_en\": \"Solomon Islands\", \"desc_en\": \"\", \"name_ru\": \"Соломоновы Острова\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+248-#-###-###\", \"cc\": \"SC\", \"name_en\": \"Seychelles\", \"desc_en\": \"\", \"name_ru\": \"Сейшелы\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+249-##-###-####\", \"cc\": \"SD\", \"name_en\": \"Sudan\", \"desc_en\": \"\", \"name_ru\": \"Судан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+46-##-###-####\", \"cc\": \"SE\", \"name_en\": \"Sweden\", \"desc_en\": \"\", \"name_ru\": \"Швеция\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+65-####-####\", \"cc\": \"SG\", \"name_en\": \"Singapore\", \"desc_en\": \"\", \"name_ru\": \"Сингапур\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+290-####\", \"cc\": \"SH\", \"name_en\": \"Saint Helena\", \"desc_en\": \"\", \"name_ru\": \"Остров Святой Елены\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+290-####\", \"cc\": \"SH\", \"name_en\": \"Tristan da Cunha\", \"desc_en\": \"\", \"name_ru\": \"Тристан-да-Кунья\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+386-##-###-###\", \"cc\": \"SI\", \"name_en\": \"Slovenia\", \"desc_en\": \"\", \"name_ru\": \"Словения\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+421(###)###-###\", \"cc\": \"SK\", \"name_en\": \"Slovakia\", \"desc_en\": \"\", \"name_ru\": \"Словакия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+232-##-######\", \"cc\": \"SL\", \"name_en\": \"Sierra Leone\", \"desc_en\": \"\", \"name_ru\": \"Сьерра-Леоне\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+378-####-######\", \"cc\": \"SM\", \"name_en\": \"San Marino\", \"desc_en\": \"\", \"name_ru\": \"Сан-Марино\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+221-##-###-####\", \"cc\": \"SN\", \"name_en\": \"Senegal\", \"desc_en\": \"\", \"name_ru\": \"Сенегал\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+252-##-###-###\", \"cc\": \"SO\", \"name_en\": \"Somalia\", \"desc_en\": \"\", \"name_ru\": \"Сомали\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+252-#-###-###\", \"cc\": \"SO\", \"name_en\": \"Somalia\", \"desc_en\": \"\", \"name_ru\": \"Сомали\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+252-#-###-###\", \"cc\": \"SO\", \"name_en\": \"Somalia \", \"desc_en\": \"mobile\", \"name_ru\": \"Сомали \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+597-###-####\", \"cc\": \"SR\", \"name_en\": \"Suriname \", \"desc_en\": \"mobile\", \"name_ru\": \"Суринам \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+597-###-###\", \"cc\": \"SR\", \"name_en\": \"Suriname\", \"desc_en\": \"\", \"name_ru\": \"Суринам\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+211-##-###-####\", \"cc\": \"SS\", \"name_en\": \"South Sudan\", \"desc_en\": \"\", \"name_ru\": \"Южный Судан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+239-##-#####\", \"cc\": \"ST\", \"name_en\": \"Sao Tome and Principe\", \"desc_en\": \"\", \"name_ru\": \"Сан-Томе и Принсипи\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+503-##-##-####\", \"cc\": \"SV\", \"name_en\": \"El Salvador\", \"desc_en\": \"\", \"name_ru\": \"Сальвадор\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(721)###-####\", \"cc\": \"SX\", \"name_en\": \"Sint Maarten\", \"desc_en\": \"\", \"name_ru\": \"Синт-Маартен\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+963-##-####-###\", \"cc\": \"SY\", \"name_en\": \"Syrian Arab Republic\", \"desc_en\": \"\", \"name_ru\": \"Сирийская арабская республика\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+268-##-##-####\", \"cc\": \"SZ\", \"name_en\": \"Swaziland\", \"desc_en\": \"\", \"name_ru\": \"Свазиленд\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(649)###-####\", \"cc\": \"TC\", \"name_en\": \"Turks & Caicos\", \"desc_en\": \"\", \"name_ru\": \"Тёркс и Кайкос\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+235-##-##-##-##\", \"cc\": \"TD\", \"name_en\": \"Chad\", \"desc_en\": \"\", \"name_ru\": \"Чад\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+228-##-###-###\", \"cc\": \"TG\", \"name_en\": \"Togo\", \"desc_en\": \"\", \"name_ru\": \"Того\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+66-##-###-####\", \"cc\": \"TH\", \"name_en\": \"Thailand \", \"desc_en\": \"mobile\", \"name_ru\": \"Таиланд \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+66-##-###-###\", \"cc\": \"TH\", \"name_en\": \"Thailand\", \"desc_en\": \"\", \"name_ru\": \"Таиланд\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+992-##-###-####\", \"cc\": \"TJ\", \"name_en\": \"Tajikistan\", \"desc_en\": \"\", \"name_ru\": \"Таджикистан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+690-####\", \"cc\": \"TK\", \"name_en\": \"Tokelau\", \"desc_en\": \"\", \"name_ru\": \"Токелау\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+670-###-####\", \"cc\": \"TL\", \"name_en\": \"East Timor\", \"desc_en\": \"\", \"name_ru\": \"Восточный Тимор\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+670-77#-#####\", \"cc\": \"TL\", \"name_en\": \"East Timor\", \"desc_en\": \"Timor Telecom\", \"name_ru\": \"Восточный Тимор\", \"desc_ru\": \"Timor Telecom\" },\n\t{ \"mask\": \"+670-78#-#####\", \"cc\": \"TL\", \"name_en\": \"East Timor\", \"desc_en\": \"Timor Telecom\", \"name_ru\": \"Восточный Тимор\", \"desc_ru\": \"Timor Telecom\" },\n\t{ \"mask\": \"+993-#-###-####\", \"cc\": \"TM\", \"name_en\": \"Turkmenistan\", \"desc_en\": \"\", \"name_ru\": \"Туркменистан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+216-##-###-###\", \"cc\": \"TN\", \"name_en\": \"Tunisia\", \"desc_en\": \"\", \"name_ru\": \"Тунис\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+676-#####\", \"cc\": \"TO\", \"name_en\": \"Tonga\", \"desc_en\": \"\", \"name_ru\": \"Тонга\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+90(###)###-####\", \"cc\": \"TR\", \"name_en\": \"Turkey\", \"desc_en\": \"\", \"name_ru\": \"Турция\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(868)###-####\", \"cc\": \"TT\", \"name_en\": \"Trinidad & Tobago\", \"desc_en\": \"\", \"name_ru\": \"Тринидад и Тобаго\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+688-90####\", \"cc\": \"TV\", \"name_en\": \"Tuvalu \", \"desc_en\": \"mobile\", \"name_ru\": \"Тувалу \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+688-2####\", \"cc\": \"TV\", \"name_en\": \"Tuvalu\", \"desc_en\": \"\", \"name_ru\": \"Тувалу\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+886-#-####-####\", \"cc\": \"TW\", \"name_en\": \"Taiwan\", \"desc_en\": \"\", \"name_ru\": \"Тайвань\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+886-####-####\", \"cc\": \"TW\", \"name_en\": \"Taiwan\", \"desc_en\": \"\", \"name_ru\": \"Тайвань\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+255-##-###-####\", \"cc\": \"TZ\", \"name_en\": \"Tanzania\", \"desc_en\": \"\", \"name_ru\": \"Танзания\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+380(##)###-##-##\", \"cc\": \"UA\", \"name_en\": \"Ukraine\", \"desc_en\": \"\", \"name_ru\": \"Украина\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+256(###)###-###\", \"cc\": \"UG\", \"name_en\": \"Uganda\", \"desc_en\": \"\", \"name_ru\": \"Уганда\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+44-##-####-####\", \"cc\": \"UK\", \"name_en\": \"United Kingdom\", \"desc_en\": \"\", \"name_ru\": \"Великобритания\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+598-#-###-##-##\", \"cc\": \"UY\", \"name_en\": \"Uruguay\", \"desc_en\": \"\", \"name_ru\": \"Уругвай\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+998-##-###-####\", \"cc\": \"UZ\", \"name_en\": \"Uzbekistan\", \"desc_en\": \"\", \"name_ru\": \"Узбекистан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+39-6-698-#####\", \"cc\": \"VA\", \"name_en\": \"Vatican City\", \"desc_en\": \"\", \"name_ru\": \"Ватикан\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(784)###-####\", \"cc\": \"VC\", \"name_en\": \"Saint Vincent & the Grenadines\", \"desc_en\": \"\", \"name_ru\": \"Сент-Винсент и Гренадины\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+58(###)###-####\", \"cc\": \"VE\", \"name_en\": \"Venezuela\", \"desc_en\": \"\", \"name_ru\": \"Венесуэла\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(284)###-####\", \"cc\": \"VG\", \"name_en\": \"British Virgin Islands\", \"desc_en\": \"\", \"name_ru\": \"Британские Виргинские острова\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(340)###-####\", \"cc\": \"VI\", \"name_en\": \"US Virgin Islands\", \"desc_en\": \"\", \"name_ru\": \"Американские Виргинские острова\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+84-##-####-###\", \"cc\": \"VN\", \"name_en\": \"Vietnam\", \"desc_en\": \"\", \"name_ru\": \"Вьетнам\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+84(###)####-###\", \"cc\": \"VN\", \"name_en\": \"Vietnam\", \"desc_en\": \"\", \"name_ru\": \"Вьетнам\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+678-##-#####\", \"cc\": \"VU\", \"name_en\": \"Vanuatu \", \"desc_en\": \"mobile\", \"name_ru\": \"Вануату \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+678-#####\", \"cc\": \"VU\", \"name_en\": \"Vanuatu\", \"desc_en\": \"\", \"name_ru\": \"Вануату\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+681-##-####\", \"cc\": \"WF\", \"name_en\": \"Wallis and Futuna\", \"desc_en\": \"\", \"name_ru\": \"Уоллис и Футуна\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+685-##-####\", \"cc\": \"WS\", \"name_en\": \"Samoa\", \"desc_en\": \"\", \"name_ru\": \"Самоа\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+967-###-###-###\", \"cc\": \"YE\", \"name_en\": \"Yemen \", \"desc_en\": \"mobile\", \"name_ru\": \"Йемен \", \"desc_ru\": \"мобильные\" },\n\t{ \"mask\": \"+967-#-###-###\", \"cc\": \"YE\", \"name_en\": \"Yemen\", \"desc_en\": \"\", \"name_ru\": \"Йемен\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+967-##-###-###\", \"cc\": \"YE\", \"name_en\": \"Yemen\", \"desc_en\": \"\", \"name_ru\": \"Йемен\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+27-##-###-####\", \"cc\": \"ZA\", \"name_en\": \"South Africa\", \"desc_en\": \"\", \"name_ru\": \"Южно-Африканская Респ.\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+260-##-###-####\", \"cc\": \"ZM\", \"name_en\": \"Zambia\", \"desc_en\": \"\", \"name_ru\": \"Замбия\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+263-#-######\", \"cc\": \"ZW\", \"name_en\": \"Zimbabwe\", \"desc_en\": \"\", \"name_ru\": \"Зимбабве\", \"desc_ru\": \"\" },\n\t{ \"mask\": \"+1(###)###-####\", \"cc\": [\"US\", \"CA\"], \"name_en\": \"USA and Canada\", \"desc_en\": \"\", \"name_ru\": \"США и Канада\", \"desc_ru\": \"\" }\n]\n"
  },
  {
    "path": "public/static/plugins/input-mask/phone-codes/readme.txt",
    "content": "more phone masks can be found at https://github.com/andr-04/inputmask-multi "
  },
  {
    "path": "public/static/plugins/ionslider/ion.rangeSlider.css",
    "content": "/* Ion.RangeSlider\n// css version 2.0.3\n// © 2013-2014 Denis Ineshin | IonDen.com\n// ===================================================================================================================*/\n\n/* =====================================================================================================================\n// RangeSlider */\n\n.irs {\n    position: relative; display: block;\n    -webkit-touch-callout: none;\n    -webkit-user-select: none;\n     -khtml-user-select: none;\n       -moz-user-select: none;\n        -ms-user-select: none;\n            user-select: none;\n}\n    .irs-line {\n        position: relative; display: block;\n        overflow: hidden;\n        outline: none !important;\n    }\n        .irs-line-left, .irs-line-mid, .irs-line-right {\n            position: absolute; display: block;\n            top: 0;\n        }\n        .irs-line-left {\n            left: 0; width: 11%;\n        }\n        .irs-line-mid {\n            left: 9%; width: 82%;\n        }\n        .irs-line-right {\n            right: 0; width: 11%;\n        }\n\n    .irs-bar {\n        position: absolute; display: block;\n        left: 0; width: 0;\n    }\n        .irs-bar-edge {\n            position: absolute; display: block;\n            top: 0; left: 0;\n        }\n\n    .irs-shadow {\n        position: absolute; display: none;\n        left: 0; width: 0;\n    }\n\n    .irs-slider {\n        position: absolute; display: block;\n        cursor: default;\n        z-index: 1;\n    }\n        .irs-slider.single {\n\n        }\n        .irs-slider.from {\n\n        }\n        .irs-slider.to {\n\n        }\n        .irs-slider.type_last {\n            z-index: 2;\n        }\n\n    .irs-min {\n        position: absolute; display: block;\n        left: 0;\n        cursor: default;\n    }\n    .irs-max {\n        position: absolute; display: block;\n        right: 0;\n        cursor: default;\n    }\n\n    .irs-from, .irs-to, .irs-single {\n        position: absolute; display: block;\n        top: 0; left: 0;\n        cursor: default;\n        white-space: nowrap;\n    }\n\n.irs-grid {\n    position: absolute; display: none;\n    bottom: 0; left: 0;\n    width: 100%; height: 20px;\n}\n.irs-with-grid .irs-grid {\n    display: block;\n}\n    .irs-grid-pol {\n        position: absolute;\n        top: 0; left: 0;\n        width: 1px; height: 8px;\n        background: #000;\n    }\n    .irs-grid-pol.small {\n        height: 4px;\n    }\n    .irs-grid-text {\n        position: absolute;\n        bottom: 0; left: 0;\n        white-space: nowrap;\n        text-align: center;\n        font-size: 9px; line-height: 9px;\n        padding: 0 3px;\n        color: #000;\n    }\n\n.irs-disable-mask {\n    position: absolute; display: block;\n    top: 0; left: -1%;\n    width: 102%; height: 100%;\n    cursor: default;\n    background: rgba(0,0,0,0.0);\n    z-index: 2;\n}\n.lt-ie9 .irs-disable-mask {\n    background: #000;\n    filter: alpha(opacity=0);\n    cursor: not-allowed;\n}\n\n.irs-disabled {\n    opacity: 0.4;\n}\n\n\n.irs-hidden-input {\n    position: absolute !important;\n    display: block !important;\n    top: 0 !important;\n    left: 0 !important;\n    width: 0 !important;\n    height: 0 !important;\n    font-size: 0 !important;\n    line-height: 0 !important;\n    padding: 0 !important;\n    margin: 0 !important;\n    outline: none !important;\n    z-index: -9999 !important;\n    background: none !important;\n    border-style: solid !important;\n    border-color: transparent !important;\n}\n"
  },
  {
    "path": "public/static/plugins/ionslider/ion.rangeSlider.skinFlat.css",
    "content": "/* Ion.RangeSlider, Flat UI Skin\n// css version 2.0.3\n// © Denis Ineshin, 2014    https://github.com/IonDen\n// ===================================================================================================================*/\n\n/* =====================================================================================================================\n// Skin details */\n\n.irs-line-mid,\n.irs-line-left,\n.irs-line-right,\n.irs-bar,\n.irs-bar-edge,\n.irs-slider {\n    background: url(img/sprite-skin-flat.png) repeat-x;\n}\n\n.irs {\n    height: 40px;\n}\n.irs-with-grid {\n    height: 60px;\n}\n.irs-line {\n    height: 12px; top: 25px;\n}\n    .irs-line-left {\n        height: 12px;\n        background-position: 0 -30px;\n    }\n    .irs-line-mid {\n        height: 12px;\n        background-position: 0 0;\n    }\n    .irs-line-right {\n        height: 12px;\n        background-position: 100% -30px;\n    }\n\n.irs-bar {\n    height: 12px; top: 25px;\n    background-position: 0 -60px;\n}\n    .irs-bar-edge {\n        top: 25px;\n        height: 12px; width: 9px;\n        background-position: 0 -90px;\n    }\n\n.irs-shadow {\n    height: 3px; top: 34px;\n    background: #000;\n    opacity: 0.25;\n}\n.lt-ie9 .irs-shadow {\n    filter: alpha(opacity=25);\n}\n\n.irs-slider {\n    width: 16px; height: 18px;\n    top: 22px;\n    background-position: 0 -120px;\n}\n.irs-slider.state_hover, .irs-slider:hover {\n    background-position: 0 -150px;\n}\n\n.irs-min, .irs-max {\n    color: #999;\n    font-size: 10px; line-height: 1.333;\n    text-shadow: none;\n    top: 0; padding: 1px 3px;\n    background: #e1e4e9;\n    -moz-border-radius: 4px;\n    border-radius: 4px;\n}\n\n.irs-from, .irs-to, .irs-single {\n    color: #fff;\n    font-size: 10px; line-height: 1.333;\n    text-shadow: none;\n    padding: 1px 5px;\n    background: #ed5565;\n    -moz-border-radius: 4px;\n    border-radius: 4px;\n}\n.irs-from:after, .irs-to:after, .irs-single:after {\n    position: absolute; display: block; content: \"\";\n    bottom: -6px; left: 50%;\n    width: 0; height: 0;\n    margin-left: -3px;\n    overflow: hidden;\n    border: 3px solid transparent;\n    border-top-color: #ed5565;\n}\n\n\n.irs-grid-pol {\n    background: #e1e4e9;\n}\n.irs-grid-text {\n    color: #999;\n}\n\n.irs-disabled {\n}\n"
  },
  {
    "path": "public/static/plugins/ionslider/ion.rangeSlider.skinNice.css",
    "content": "/* Ion.RangeSlider, Nice Skin\n// css version 2.0.3\n// © Denis Ineshin, 2014    https://github.com/IonDen\n// ===================================================================================================================*/\n\n/* =====================================================================================================================\n// Skin details */\n\n.irs-line-mid,\n.irs-line-left,\n.irs-line-right,\n.irs-bar,\n.irs-bar-edge,\n.irs-slider {\n    background: url(img/sprite-skin-nice.png) repeat-x;\n}\n\n.irs {\n    height: 40px;\n}\n.irs-with-grid {\n    height: 60px;\n}\n.irs-line {\n    height: 8px; top: 25px;\n}\n    .irs-line-left {\n        height: 8px;\n        background-position: 0 -30px;\n    }\n    .irs-line-mid {\n        height: 8px;\n        background-position: 0 0;\n    }\n    .irs-line-right {\n        height: 8px;\n        background-position: 100% -30px;\n    }\n\n.irs-bar {\n    height: 8px; top: 25px;\n    background-position: 0 -60px;\n}\n    .irs-bar-edge {\n        top: 25px;\n        height: 8px; width: 11px;\n        background-position: 0 -90px;\n    }\n\n.irs-shadow {\n    height: 1px; top: 34px;\n    background: #000;\n    opacity: 0.15;\n}\n.lt-ie9 .irs-shadow {\n    filter: alpha(opacity=15);\n}\n\n.irs-slider {\n    width: 22px; height: 22px;\n    top: 17px;\n    background-position: 0 -120px;\n}\n.irs-slider.state_hover, .irs-slider:hover {\n    background-position: 0 -150px;\n}\n\n.irs-min, .irs-max {\n    color: #999;\n    font-size: 10px; line-height: 1.333;\n    text-shadow: none;\n    top: 0; padding: 1px 3px;\n    background: rgba(0,0,0,0.1);\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n}\n.lt-ie9 .irs-min, .lt-ie9 .irs-max {\n    background: #ccc;\n}\n\n.irs-from, .irs-to, .irs-single {\n    color: #fff;\n    font-size: 10px; line-height: 1.333;\n    text-shadow: none;\n    padding: 1px 5px;\n    background: rgba(0,0,0,0.3);\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n}\n.lt-ie9 .irs-from, .lt-ie9 .irs-to, .lt-ie9 .irs-single {\n    background: #999;\n}\n\n.irs-grid-pol {\n    background: #99a4ac;\n}\n.irs-grid-text {\n    color: #99a4ac;\n}\n\n.irs-disabled {\n}\n"
  },
  {
    "path": "public/static/plugins/jQueryUI/jquery-ui.js",
    "content": "/*! jQuery UI - v1.11.4 - 2015-03-11\n* http://jqueryui.com\n* Includes: core.js, widget.js, mouse.js, position.js, accordion.js, autocomplete.js, button.js, datepicker.js, dialog.js, draggable.js, droppable.js, effect.js, effect-blind.js, effect-bounce.js, effect-clip.js, effect-drop.js, effect-explode.js, effect-fade.js, effect-fold.js, effect-highlight.js, effect-puff.js, effect-pulsate.js, effect-scale.js, effect-shake.js, effect-size.js, effect-slide.js, effect-transfer.js, menu.js, progressbar.js, resizable.js, selectable.js, selectmenu.js, slider.js, sortable.js, spinner.js, tabs.js, tooltip.js\n* Copyright 2015 jQuery Foundation and other contributors; Licensed MIT */\n\n(function( factory ) {\n\tif ( typeof define === \"function\" && define.amd ) {\n\n\t\t// AMD. Register as an anonymous module.\n\t\tdefine([ \"jquery\" ], factory );\n\t} else {\n\n\t\t// Browser globals\n\t\tfactory( jQuery );\n\t}\n}(function( $ ) {\n/*!\n * jQuery UI Core 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/category/ui-core/\n */\n\n\n// $.ui might exist from components with no dependencies, e.g., $.ui.position\n$.ui = $.ui || {};\n\n$.extend( $.ui, {\n\tversion: \"1.11.4\",\n\n\tkeyCode: {\n\t\tBACKSPACE: 8,\n\t\tCOMMA: 188,\n\t\tDELETE: 46,\n\t\tDOWN: 40,\n\t\tEND: 35,\n\t\tENTER: 13,\n\t\tESCAPE: 27,\n\t\tHOME: 36,\n\t\tLEFT: 37,\n\t\tPAGE_DOWN: 34,\n\t\tPAGE_UP: 33,\n\t\tPERIOD: 190,\n\t\tRIGHT: 39,\n\t\tSPACE: 32,\n\t\tTAB: 9,\n\t\tUP: 38\n\t}\n});\n\n// plugins\n$.fn.extend({\n\tscrollParent: function( includeHidden ) {\n\t\tvar position = this.css( \"position\" ),\n\t\t\texcludeStaticParent = position === \"absolute\",\n\t\t\toverflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,\n\t\t\tscrollParent = this.parents().filter( function() {\n\t\t\t\tvar parent = $( this );\n\t\t\t\tif ( excludeStaticParent && parent.css( \"position\" ) === \"static\" ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn overflowRegex.test( parent.css( \"overflow\" ) + parent.css( \"overflow-y\" ) + parent.css( \"overflow-x\" ) );\n\t\t\t}).eq( 0 );\n\n\t\treturn position === \"fixed\" || !scrollParent.length ? $( this[ 0 ].ownerDocument || document ) : scrollParent;\n\t},\n\n\tuniqueId: (function() {\n\t\tvar uuid = 0;\n\n\t\treturn function() {\n\t\t\treturn this.each(function() {\n\t\t\t\tif ( !this.id ) {\n\t\t\t\t\tthis.id = \"ui-id-\" + ( ++uuid );\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\t})(),\n\n\tremoveUniqueId: function() {\n\t\treturn this.each(function() {\n\t\t\tif ( /^ui-id-\\d+$/.test( this.id ) ) {\n\t\t\t\t$( this ).removeAttr( \"id\" );\n\t\t\t}\n\t\t});\n\t}\n});\n\n// selectors\nfunction focusable( element, isTabIndexNotNaN ) {\n\tvar map, mapName, img,\n\t\tnodeName = element.nodeName.toLowerCase();\n\tif ( \"area\" === nodeName ) {\n\t\tmap = element.parentNode;\n\t\tmapName = map.name;\n\t\tif ( !element.href || !mapName || map.nodeName.toLowerCase() !== \"map\" ) {\n\t\t\treturn false;\n\t\t}\n\t\timg = $( \"img[usemap='#\" + mapName + \"']\" )[ 0 ];\n\t\treturn !!img && visible( img );\n\t}\n\treturn ( /^(input|select|textarea|button|object)$/.test( nodeName ) ?\n\t\t!element.disabled :\n\t\t\"a\" === nodeName ?\n\t\t\telement.href || isTabIndexNotNaN :\n\t\t\tisTabIndexNotNaN) &&\n\t\t// the element and all of its ancestors must be visible\n\t\tvisible( element );\n}\n\nfunction visible( element ) {\n\treturn $.expr.filters.visible( element ) &&\n\t\t!$( element ).parents().addBack().filter(function() {\n\t\t\treturn $.css( this, \"visibility\" ) === \"hidden\";\n\t\t}).length;\n}\n\n$.extend( $.expr[ \":\" ], {\n\tdata: $.expr.createPseudo ?\n\t\t$.expr.createPseudo(function( dataName ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn !!$.data( elem, dataName );\n\t\t\t};\n\t\t}) :\n\t\t// support: jQuery <1.8\n\t\tfunction( elem, i, match ) {\n\t\t\treturn !!$.data( elem, match[ 3 ] );\n\t\t},\n\n\tfocusable: function( element ) {\n\t\treturn focusable( element, !isNaN( $.attr( element, \"tabindex\" ) ) );\n\t},\n\n\ttabbable: function( element ) {\n\t\tvar tabIndex = $.attr( element, \"tabindex\" ),\n\t\t\tisTabIndexNaN = isNaN( tabIndex );\n\t\treturn ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );\n\t}\n});\n\n// support: jQuery <1.8\nif ( !$( \"<a>\" ).outerWidth( 1 ).jquery ) {\n\t$.each( [ \"Width\", \"Height\" ], function( i, name ) {\n\t\tvar side = name === \"Width\" ? [ \"Left\", \"Right\" ] : [ \"Top\", \"Bottom\" ],\n\t\t\ttype = name.toLowerCase(),\n\t\t\torig = {\n\t\t\t\tinnerWidth: $.fn.innerWidth,\n\t\t\t\tinnerHeight: $.fn.innerHeight,\n\t\t\t\touterWidth: $.fn.outerWidth,\n\t\t\t\touterHeight: $.fn.outerHeight\n\t\t\t};\n\n\t\tfunction reduce( elem, size, border, margin ) {\n\t\t\t$.each( side, function() {\n\t\t\t\tsize -= parseFloat( $.css( elem, \"padding\" + this ) ) || 0;\n\t\t\t\tif ( border ) {\n\t\t\t\t\tsize -= parseFloat( $.css( elem, \"border\" + this + \"Width\" ) ) || 0;\n\t\t\t\t}\n\t\t\t\tif ( margin ) {\n\t\t\t\t\tsize -= parseFloat( $.css( elem, \"margin\" + this ) ) || 0;\n\t\t\t\t}\n\t\t\t});\n\t\t\treturn size;\n\t\t}\n\n\t\t$.fn[ \"inner\" + name ] = function( size ) {\n\t\t\tif ( size === undefined ) {\n\t\t\t\treturn orig[ \"inner\" + name ].call( this );\n\t\t\t}\n\n\t\t\treturn this.each(function() {\n\t\t\t\t$( this ).css( type, reduce( this, size ) + \"px\" );\n\t\t\t});\n\t\t};\n\n\t\t$.fn[ \"outer\" + name] = function( size, margin ) {\n\t\t\tif ( typeof size !== \"number\" ) {\n\t\t\t\treturn orig[ \"outer\" + name ].call( this, size );\n\t\t\t}\n\n\t\t\treturn this.each(function() {\n\t\t\t\t$( this).css( type, reduce( this, size, true, margin ) + \"px\" );\n\t\t\t});\n\t\t};\n\t});\n}\n\n// support: jQuery <1.8\nif ( !$.fn.addBack ) {\n\t$.fn.addBack = function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t};\n}\n\n// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)\nif ( $( \"<a>\" ).data( \"a-b\", \"a\" ).removeData( \"a-b\" ).data( \"a-b\" ) ) {\n\t$.fn.removeData = (function( removeData ) {\n\t\treturn function( key ) {\n\t\t\tif ( arguments.length ) {\n\t\t\t\treturn removeData.call( this, $.camelCase( key ) );\n\t\t\t} else {\n\t\t\t\treturn removeData.call( this );\n\t\t\t}\n\t\t};\n\t})( $.fn.removeData );\n}\n\n// deprecated\n$.ui.ie = !!/msie [\\w.]+/.exec( navigator.userAgent.toLowerCase() );\n\n$.fn.extend({\n\tfocus: (function( orig ) {\n\t\treturn function( delay, fn ) {\n\t\t\treturn typeof delay === \"number\" ?\n\t\t\t\tthis.each(function() {\n\t\t\t\t\tvar elem = this;\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\t$( elem ).focus();\n\t\t\t\t\t\tif ( fn ) {\n\t\t\t\t\t\t\tfn.call( elem );\n\t\t\t\t\t\t}\n\t\t\t\t\t}, delay );\n\t\t\t\t}) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t})( $.fn.focus ),\n\n\tdisableSelection: (function() {\n\t\tvar eventType = \"onselectstart\" in document.createElement( \"div\" ) ?\n\t\t\t\"selectstart\" :\n\t\t\t\"mousedown\";\n\n\t\treturn function() {\n\t\t\treturn this.bind( eventType + \".ui-disableSelection\", function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t});\n\t\t};\n\t})(),\n\n\tenableSelection: function() {\n\t\treturn this.unbind( \".ui-disableSelection\" );\n\t},\n\n\tzIndex: function( zIndex ) {\n\t\tif ( zIndex !== undefined ) {\n\t\t\treturn this.css( \"zIndex\", zIndex );\n\t\t}\n\n\t\tif ( this.length ) {\n\t\t\tvar elem = $( this[ 0 ] ), position, value;\n\t\t\twhile ( elem.length && elem[ 0 ] !== document ) {\n\t\t\t\t// Ignore z-index if position is set to a value where z-index is ignored by the browser\n\t\t\t\t// This makes behavior of this function consistent across browsers\n\t\t\t\t// WebKit always returns auto if the element is positioned\n\t\t\t\tposition = elem.css( \"position\" );\n\t\t\t\tif ( position === \"absolute\" || position === \"relative\" || position === \"fixed\" ) {\n\t\t\t\t\t// IE returns 0 when zIndex is not specified\n\t\t\t\t\t// other browsers return a string\n\t\t\t\t\t// we ignore the case of nested elements with an explicit value of 0\n\t\t\t\t\t// <div style=\"z-index: -10;\"><div style=\"z-index: 0;\"></div></div>\n\t\t\t\t\tvalue = parseInt( elem.css( \"zIndex\" ), 10 );\n\t\t\t\t\tif ( !isNaN( value ) && value !== 0 ) {\n\t\t\t\t\t\treturn value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telem = elem.parent();\n\t\t\t}\n\t\t}\n\n\t\treturn 0;\n\t}\n});\n\n// $.ui.plugin is deprecated. Use $.widget() extensions instead.\n$.ui.plugin = {\n\tadd: function( module, option, set ) {\n\t\tvar i,\n\t\t\tproto = $.ui[ module ].prototype;\n\t\tfor ( i in set ) {\n\t\t\tproto.plugins[ i ] = proto.plugins[ i ] || [];\n\t\t\tproto.plugins[ i ].push( [ option, set[ i ] ] );\n\t\t}\n\t},\n\tcall: function( instance, name, args, allowDisconnected ) {\n\t\tvar i,\n\t\t\tset = instance.plugins[ name ];\n\n\t\tif ( !set ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( !allowDisconnected && ( !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ( i = 0; i < set.length; i++ ) {\n\t\t\tif ( instance.options[ set[ i ][ 0 ] ] ) {\n\t\t\t\tset[ i ][ 1 ].apply( instance.element, args );\n\t\t\t}\n\t\t}\n\t}\n};\n\n\n/*!\n * jQuery UI Widget 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/jQuery.widget/\n */\n\n\nvar widget_uuid = 0,\n\twidget_slice = Array.prototype.slice;\n\n$.cleanData = (function( orig ) {\n\treturn function( elems ) {\n\t\tvar events, elem, i;\n\t\tfor ( i = 0; (elem = elems[i]) != null; i++ ) {\n\t\t\ttry {\n\n\t\t\t\t// Only trigger remove when necessary to save time\n\t\t\t\tevents = $._data( elem, \"events\" );\n\t\t\t\tif ( events && events.remove ) {\n\t\t\t\t\t$( elem ).triggerHandler( \"remove\" );\n\t\t\t\t}\n\n\t\t\t// http://bugs.jquery.com/ticket/8235\n\t\t\t} catch ( e ) {}\n\t\t}\n\t\torig( elems );\n\t};\n})( $.cleanData );\n\n$.widget = function( name, base, prototype ) {\n\tvar fullName, existingConstructor, constructor, basePrototype,\n\t\t// proxiedPrototype allows the provided prototype to remain unmodified\n\t\t// so that it can be used as a mixin for multiple widgets (#8876)\n\t\tproxiedPrototype = {},\n\t\tnamespace = name.split( \".\" )[ 0 ];\n\n\tname = name.split( \".\" )[ 1 ];\n\tfullName = namespace + \"-\" + name;\n\n\tif ( !prototype ) {\n\t\tprototype = base;\n\t\tbase = $.Widget;\n\t}\n\n\t// create selector for plugin\n\t$.expr[ \":\" ][ fullName.toLowerCase() ] = function( elem ) {\n\t\treturn !!$.data( elem, fullName );\n\t};\n\n\t$[ namespace ] = $[ namespace ] || {};\n\texistingConstructor = $[ namespace ][ name ];\n\tconstructor = $[ namespace ][ name ] = function( options, element ) {\n\t\t// allow instantiation without \"new\" keyword\n\t\tif ( !this._createWidget ) {\n\t\t\treturn new constructor( options, element );\n\t\t}\n\n\t\t// allow instantiation without initializing for simple inheritance\n\t\t// must use \"new\" keyword (the code above always passes args)\n\t\tif ( arguments.length ) {\n\t\t\tthis._createWidget( options, element );\n\t\t}\n\t};\n\t// extend with the existing constructor to carry over any static properties\n\t$.extend( constructor, existingConstructor, {\n\t\tversion: prototype.version,\n\t\t// copy the object used to create the prototype in case we need to\n\t\t// redefine the widget later\n\t\t_proto: $.extend( {}, prototype ),\n\t\t// track widgets that inherit from this widget in case this widget is\n\t\t// redefined after a widget inherits from it\n\t\t_childConstructors: []\n\t});\n\n\tbasePrototype = new base();\n\t// we need to make the options hash a property directly on the new instance\n\t// otherwise we'll modify the options hash on the prototype that we're\n\t// inheriting from\n\tbasePrototype.options = $.widget.extend( {}, basePrototype.options );\n\t$.each( prototype, function( prop, value ) {\n\t\tif ( !$.isFunction( value ) ) {\n\t\t\tproxiedPrototype[ prop ] = value;\n\t\t\treturn;\n\t\t}\n\t\tproxiedPrototype[ prop ] = (function() {\n\t\t\tvar _super = function() {\n\t\t\t\t\treturn base.prototype[ prop ].apply( this, arguments );\n\t\t\t\t},\n\t\t\t\t_superApply = function( args ) {\n\t\t\t\t\treturn base.prototype[ prop ].apply( this, args );\n\t\t\t\t};\n\t\t\treturn function() {\n\t\t\t\tvar __super = this._super,\n\t\t\t\t\t__superApply = this._superApply,\n\t\t\t\t\treturnValue;\n\n\t\t\t\tthis._super = _super;\n\t\t\t\tthis._superApply = _superApply;\n\n\t\t\t\treturnValue = value.apply( this, arguments );\n\n\t\t\t\tthis._super = __super;\n\t\t\t\tthis._superApply = __superApply;\n\n\t\t\t\treturn returnValue;\n\t\t\t};\n\t\t})();\n\t});\n\tconstructor.prototype = $.widget.extend( basePrototype, {\n\t\t// TODO: remove support for widgetEventPrefix\n\t\t// always use the name + a colon as the prefix, e.g., draggable:start\n\t\t// don't prefix for widgets that aren't DOM-based\n\t\twidgetEventPrefix: existingConstructor ? (basePrototype.widgetEventPrefix || name) : name\n\t}, proxiedPrototype, {\n\t\tconstructor: constructor,\n\t\tnamespace: namespace,\n\t\twidgetName: name,\n\t\twidgetFullName: fullName\n\t});\n\n\t// If this widget is being redefined then we need to find all widgets that\n\t// are inheriting from it and redefine all of them so that they inherit from\n\t// the new version of this widget. We're essentially trying to replace one\n\t// level in the prototype chain.\n\tif ( existingConstructor ) {\n\t\t$.each( existingConstructor._childConstructors, function( i, child ) {\n\t\t\tvar childPrototype = child.prototype;\n\n\t\t\t// redefine the child widget using the same prototype that was\n\t\t\t// originally used, but inherit from the new version of the base\n\t\t\t$.widget( childPrototype.namespace + \".\" + childPrototype.widgetName, constructor, child._proto );\n\t\t});\n\t\t// remove the list of existing child constructors from the old constructor\n\t\t// so the old child constructors can be garbage collected\n\t\tdelete existingConstructor._childConstructors;\n\t} else {\n\t\tbase._childConstructors.push( constructor );\n\t}\n\n\t$.widget.bridge( name, constructor );\n\n\treturn constructor;\n};\n\n$.widget.extend = function( target ) {\n\tvar input = widget_slice.call( arguments, 1 ),\n\t\tinputIndex = 0,\n\t\tinputLength = input.length,\n\t\tkey,\n\t\tvalue;\n\tfor ( ; inputIndex < inputLength; inputIndex++ ) {\n\t\tfor ( key in input[ inputIndex ] ) {\n\t\t\tvalue = input[ inputIndex ][ key ];\n\t\t\tif ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {\n\t\t\t\t// Clone objects\n\t\t\t\tif ( $.isPlainObject( value ) ) {\n\t\t\t\t\ttarget[ key ] = $.isPlainObject( target[ key ] ) ?\n\t\t\t\t\t\t$.widget.extend( {}, target[ key ], value ) :\n\t\t\t\t\t\t// Don't extend strings, arrays, etc. with objects\n\t\t\t\t\t\t$.widget.extend( {}, value );\n\t\t\t\t// Copy everything else by reference\n\t\t\t\t} else {\n\t\t\t\t\ttarget[ key ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn target;\n};\n\n$.widget.bridge = function( name, object ) {\n\tvar fullName = object.prototype.widgetFullName || name;\n\t$.fn[ name ] = function( options ) {\n\t\tvar isMethodCall = typeof options === \"string\",\n\t\t\targs = widget_slice.call( arguments, 1 ),\n\t\t\treturnValue = this;\n\n\t\tif ( isMethodCall ) {\n\t\t\tthis.each(function() {\n\t\t\t\tvar methodValue,\n\t\t\t\t\tinstance = $.data( this, fullName );\n\t\t\t\tif ( options === \"instance\" ) {\n\t\t\t\t\treturnValue = instance;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tif ( !instance ) {\n\t\t\t\t\treturn $.error( \"cannot call methods on \" + name + \" prior to initialization; \" +\n\t\t\t\t\t\t\"attempted to call method '\" + options + \"'\" );\n\t\t\t\t}\n\t\t\t\tif ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === \"_\" ) {\n\t\t\t\t\treturn $.error( \"no such method '\" + options + \"' for \" + name + \" widget instance\" );\n\t\t\t\t}\n\t\t\t\tmethodValue = instance[ options ].apply( instance, args );\n\t\t\t\tif ( methodValue !== instance && methodValue !== undefined ) {\n\t\t\t\t\treturnValue = methodValue && methodValue.jquery ?\n\t\t\t\t\t\treturnValue.pushStack( methodValue.get() ) :\n\t\t\t\t\t\tmethodValue;\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\n\t\t\t// Allow multiple hashes to be passed on init\n\t\t\tif ( args.length ) {\n\t\t\t\toptions = $.widget.extend.apply( null, [ options ].concat(args) );\n\t\t\t}\n\n\t\t\tthis.each(function() {\n\t\t\t\tvar instance = $.data( this, fullName );\n\t\t\t\tif ( instance ) {\n\t\t\t\t\tinstance.option( options || {} );\n\t\t\t\t\tif ( instance._init ) {\n\t\t\t\t\t\tinstance._init();\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t$.data( this, fullName, new object( options, this ) );\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn returnValue;\n\t};\n};\n\n$.Widget = function( /* options, element */ ) {};\n$.Widget._childConstructors = [];\n\n$.Widget.prototype = {\n\twidgetName: \"widget\",\n\twidgetEventPrefix: \"\",\n\tdefaultElement: \"<div>\",\n\toptions: {\n\t\tdisabled: false,\n\n\t\t// callbacks\n\t\tcreate: null\n\t},\n\t_createWidget: function( options, element ) {\n\t\telement = $( element || this.defaultElement || this )[ 0 ];\n\t\tthis.element = $( element );\n\t\tthis.uuid = widget_uuid++;\n\t\tthis.eventNamespace = \".\" + this.widgetName + this.uuid;\n\n\t\tthis.bindings = $();\n\t\tthis.hoverable = $();\n\t\tthis.focusable = $();\n\n\t\tif ( element !== this ) {\n\t\t\t$.data( element, this.widgetFullName, this );\n\t\t\tthis._on( true, this.element, {\n\t\t\t\tremove: function( event ) {\n\t\t\t\t\tif ( event.target === element ) {\n\t\t\t\t\t\tthis.destroy();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.document = $( element.style ?\n\t\t\t\t// element within the document\n\t\t\t\telement.ownerDocument :\n\t\t\t\t// element is window or document\n\t\t\t\telement.document || element );\n\t\t\tthis.window = $( this.document[0].defaultView || this.document[0].parentWindow );\n\t\t}\n\n\t\tthis.options = $.widget.extend( {},\n\t\t\tthis.options,\n\t\t\tthis._getCreateOptions(),\n\t\t\toptions );\n\n\t\tthis._create();\n\t\tthis._trigger( \"create\", null, this._getCreateEventData() );\n\t\tthis._init();\n\t},\n\t_getCreateOptions: $.noop,\n\t_getCreateEventData: $.noop,\n\t_create: $.noop,\n\t_init: $.noop,\n\n\tdestroy: function() {\n\t\tthis._destroy();\n\t\t// we can probably remove the unbind calls in 2.0\n\t\t// all event bindings should go through this._on()\n\t\tthis.element\n\t\t\t.unbind( this.eventNamespace )\n\t\t\t.removeData( this.widgetFullName )\n\t\t\t// support: jquery <1.6.3\n\t\t\t// http://bugs.jquery.com/ticket/9413\n\t\t\t.removeData( $.camelCase( this.widgetFullName ) );\n\t\tthis.widget()\n\t\t\t.unbind( this.eventNamespace )\n\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t.removeClass(\n\t\t\t\tthis.widgetFullName + \"-disabled \" +\n\t\t\t\t\"ui-state-disabled\" );\n\n\t\t// clean up events and states\n\t\tthis.bindings.unbind( this.eventNamespace );\n\t\tthis.hoverable.removeClass( \"ui-state-hover\" );\n\t\tthis.focusable.removeClass( \"ui-state-focus\" );\n\t},\n\t_destroy: $.noop,\n\n\twidget: function() {\n\t\treturn this.element;\n\t},\n\n\toption: function( key, value ) {\n\t\tvar options = key,\n\t\t\tparts,\n\t\t\tcurOption,\n\t\t\ti;\n\n\t\tif ( arguments.length === 0 ) {\n\t\t\t// don't return a reference to the internal hash\n\t\t\treturn $.widget.extend( {}, this.options );\n\t\t}\n\n\t\tif ( typeof key === \"string\" ) {\n\t\t\t// handle nested keys, e.g., \"foo.bar\" => { foo: { bar: ___ } }\n\t\t\toptions = {};\n\t\t\tparts = key.split( \".\" );\n\t\t\tkey = parts.shift();\n\t\t\tif ( parts.length ) {\n\t\t\t\tcurOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );\n\t\t\t\tfor ( i = 0; i < parts.length - 1; i++ ) {\n\t\t\t\t\tcurOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};\n\t\t\t\t\tcurOption = curOption[ parts[ i ] ];\n\t\t\t\t}\n\t\t\t\tkey = parts.pop();\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn curOption[ key ] === undefined ? null : curOption[ key ];\n\t\t\t\t}\n\t\t\t\tcurOption[ key ] = value;\n\t\t\t} else {\n\t\t\t\tif ( arguments.length === 1 ) {\n\t\t\t\t\treturn this.options[ key ] === undefined ? null : this.options[ key ];\n\t\t\t\t}\n\t\t\t\toptions[ key ] = value;\n\t\t\t}\n\t\t}\n\n\t\tthis._setOptions( options );\n\n\t\treturn this;\n\t},\n\t_setOptions: function( options ) {\n\t\tvar key;\n\n\t\tfor ( key in options ) {\n\t\t\tthis._setOption( key, options[ key ] );\n\t\t}\n\n\t\treturn this;\n\t},\n\t_setOption: function( key, value ) {\n\t\tthis.options[ key ] = value;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.widget()\n\t\t\t\t.toggleClass( this.widgetFullName + \"-disabled\", !!value );\n\n\t\t\t// If the widget is becoming disabled, then nothing is interactive\n\t\t\tif ( value ) {\n\t\t\t\tthis.hoverable.removeClass( \"ui-state-hover\" );\n\t\t\t\tthis.focusable.removeClass( \"ui-state-focus\" );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tenable: function() {\n\t\treturn this._setOptions({ disabled: false });\n\t},\n\tdisable: function() {\n\t\treturn this._setOptions({ disabled: true });\n\t},\n\n\t_on: function( suppressDisabledCheck, element, handlers ) {\n\t\tvar delegateElement,\n\t\t\tinstance = this;\n\n\t\t// no suppressDisabledCheck flag, shuffle arguments\n\t\tif ( typeof suppressDisabledCheck !== \"boolean\" ) {\n\t\t\thandlers = element;\n\t\t\telement = suppressDisabledCheck;\n\t\t\tsuppressDisabledCheck = false;\n\t\t}\n\n\t\t// no element argument, shuffle and use this.element\n\t\tif ( !handlers ) {\n\t\t\thandlers = element;\n\t\t\telement = this.element;\n\t\t\tdelegateElement = this.widget();\n\t\t} else {\n\t\t\telement = delegateElement = $( element );\n\t\t\tthis.bindings = this.bindings.add( element );\n\t\t}\n\n\t\t$.each( handlers, function( event, handler ) {\n\t\t\tfunction handlerProxy() {\n\t\t\t\t// allow widgets to customize the disabled handling\n\t\t\t\t// - disabled as an array instead of boolean\n\t\t\t\t// - disabled class as method for disabling individual parts\n\t\t\t\tif ( !suppressDisabledCheck &&\n\t\t\t\t\t\t( instance.options.disabled === true ||\n\t\t\t\t\t\t\t$( this ).hasClass( \"ui-state-disabled\" ) ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t\t.apply( instance, arguments );\n\t\t\t}\n\n\t\t\t// copy the guid so direct unbinding works\n\t\t\tif ( typeof handler !== \"string\" ) {\n\t\t\t\thandlerProxy.guid = handler.guid =\n\t\t\t\t\thandler.guid || handlerProxy.guid || $.guid++;\n\t\t\t}\n\n\t\t\tvar match = event.match( /^([\\w:-]*)\\s*(.*)$/ ),\n\t\t\t\teventName = match[1] + instance.eventNamespace,\n\t\t\t\tselector = match[2];\n\t\t\tif ( selector ) {\n\t\t\t\tdelegateElement.delegate( selector, eventName, handlerProxy );\n\t\t\t} else {\n\t\t\t\telement.bind( eventName, handlerProxy );\n\t\t\t}\n\t\t});\n\t},\n\n\t_off: function( element, eventName ) {\n\t\teventName = (eventName || \"\").split( \" \" ).join( this.eventNamespace + \" \" ) +\n\t\t\tthis.eventNamespace;\n\t\telement.unbind( eventName ).undelegate( eventName );\n\n\t\t// Clear the stack to avoid memory leaks (#10056)\n\t\tthis.bindings = $( this.bindings.not( element ).get() );\n\t\tthis.focusable = $( this.focusable.not( element ).get() );\n\t\tthis.hoverable = $( this.hoverable.not( element ).get() );\n\t},\n\n\t_delay: function( handler, delay ) {\n\t\tfunction handlerProxy() {\n\t\t\treturn ( typeof handler === \"string\" ? instance[ handler ] : handler )\n\t\t\t\t.apply( instance, arguments );\n\t\t}\n\t\tvar instance = this;\n\t\treturn setTimeout( handlerProxy, delay || 0 );\n\t},\n\n\t_hoverable: function( element ) {\n\t\tthis.hoverable = this.hoverable.add( element );\n\t\tthis._on( element, {\n\t\t\tmouseenter: function( event ) {\n\t\t\t\t$( event.currentTarget ).addClass( \"ui-state-hover\" );\n\t\t\t},\n\t\t\tmouseleave: function( event ) {\n\t\t\t\t$( event.currentTarget ).removeClass( \"ui-state-hover\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_focusable: function( element ) {\n\t\tthis.focusable = this.focusable.add( element );\n\t\tthis._on( element, {\n\t\t\tfocusin: function( event ) {\n\t\t\t\t$( event.currentTarget ).addClass( \"ui-state-focus\" );\n\t\t\t},\n\t\t\tfocusout: function( event ) {\n\t\t\t\t$( event.currentTarget ).removeClass( \"ui-state-focus\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_trigger: function( type, event, data ) {\n\t\tvar prop, orig,\n\t\t\tcallback = this.options[ type ];\n\n\t\tdata = data || {};\n\t\tevent = $.Event( event );\n\t\tevent.type = ( type === this.widgetEventPrefix ?\n\t\t\ttype :\n\t\t\tthis.widgetEventPrefix + type ).toLowerCase();\n\t\t// the original event may come from any element\n\t\t// so we need to reset the target on the new event\n\t\tevent.target = this.element[ 0 ];\n\n\t\t// copy original event properties over to the new event\n\t\torig = event.originalEvent;\n\t\tif ( orig ) {\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tif ( !( prop in event ) ) {\n\t\t\t\t\tevent[ prop ] = orig[ prop ];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthis.element.trigger( event, data );\n\t\treturn !( $.isFunction( callback ) &&\n\t\t\tcallback.apply( this.element[0], [ event ].concat( data ) ) === false ||\n\t\t\tevent.isDefaultPrevented() );\n\t}\n};\n\n$.each( { show: \"fadeIn\", hide: \"fadeOut\" }, function( method, defaultEffect ) {\n\t$.Widget.prototype[ \"_\" + method ] = function( element, options, callback ) {\n\t\tif ( typeof options === \"string\" ) {\n\t\t\toptions = { effect: options };\n\t\t}\n\t\tvar hasOptions,\n\t\t\teffectName = !options ?\n\t\t\t\tmethod :\n\t\t\t\toptions === true || typeof options === \"number\" ?\n\t\t\t\t\tdefaultEffect :\n\t\t\t\t\toptions.effect || defaultEffect;\n\t\toptions = options || {};\n\t\tif ( typeof options === \"number\" ) {\n\t\t\toptions = { duration: options };\n\t\t}\n\t\thasOptions = !$.isEmptyObject( options );\n\t\toptions.complete = callback;\n\t\tif ( options.delay ) {\n\t\t\telement.delay( options.delay );\n\t\t}\n\t\tif ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {\n\t\t\telement[ method ]( options );\n\t\t} else if ( effectName !== method && element[ effectName ] ) {\n\t\t\telement[ effectName ]( options.duration, options.easing, callback );\n\t\t} else {\n\t\t\telement.queue(function( next ) {\n\t\t\t\t$( this )[ method ]();\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback.call( element[ 0 ] );\n\t\t\t\t}\n\t\t\t\tnext();\n\t\t\t});\n\t\t}\n\t};\n});\n\nvar widget = $.widget;\n\n\n/*!\n * jQuery UI Mouse 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/mouse/\n */\n\n\nvar mouseHandled = false;\n$( document ).mouseup( function() {\n\tmouseHandled = false;\n});\n\nvar mouse = $.widget(\"ui.mouse\", {\n\tversion: \"1.11.4\",\n\toptions: {\n\t\tcancel: \"input,textarea,button,select,option\",\n\t\tdistance: 1,\n\t\tdelay: 0\n\t},\n\t_mouseInit: function() {\n\t\tvar that = this;\n\n\t\tthis.element\n\t\t\t.bind(\"mousedown.\" + this.widgetName, function(event) {\n\t\t\t\treturn that._mouseDown(event);\n\t\t\t})\n\t\t\t.bind(\"click.\" + this.widgetName, function(event) {\n\t\t\t\tif (true === $.data(event.target, that.widgetName + \".preventClickEvent\")) {\n\t\t\t\t\t$.removeData(event.target, that.widgetName + \".preventClickEvent\");\n\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis.started = false;\n\t},\n\n\t// TODO: make sure destroying one instance of mouse doesn't mess with\n\t// other instances of mouse\n\t_mouseDestroy: function() {\n\t\tthis.element.unbind(\".\" + this.widgetName);\n\t\tif ( this._mouseMoveDelegate ) {\n\t\t\tthis.document\n\t\t\t\t.unbind(\"mousemove.\" + this.widgetName, this._mouseMoveDelegate)\n\t\t\t\t.unbind(\"mouseup.\" + this.widgetName, this._mouseUpDelegate);\n\t\t}\n\t},\n\n\t_mouseDown: function(event) {\n\t\t// don't let more than one widget handle mouseStart\n\t\tif ( mouseHandled ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._mouseMoved = false;\n\n\t\t// we may have missed mouseup (out of window)\n\t\t(this._mouseStarted && this._mouseUp(event));\n\n\t\tthis._mouseDownEvent = event;\n\n\t\tvar that = this,\n\t\t\tbtnIsLeft = (event.which === 1),\n\t\t\t// event.target.nodeName works around a bug in IE 8 with\n\t\t\t// disabled inputs (#7620)\n\t\t\telIsCancel = (typeof this.options.cancel === \"string\" && event.target.nodeName ? $(event.target).closest(this.options.cancel).length : false);\n\t\tif (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {\n\t\t\treturn true;\n\t\t}\n\n\t\tthis.mouseDelayMet = !this.options.delay;\n\t\tif (!this.mouseDelayMet) {\n\t\t\tthis._mouseDelayTimer = setTimeout(function() {\n\t\t\t\tthat.mouseDelayMet = true;\n\t\t\t}, this.options.delay);\n\t\t}\n\n\t\tif (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {\n\t\t\tthis._mouseStarted = (this._mouseStart(event) !== false);\n\t\t\tif (!this._mouseStarted) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\t// Click event may never have fired (Gecko & Opera)\n\t\tif (true === $.data(event.target, this.widgetName + \".preventClickEvent\")) {\n\t\t\t$.removeData(event.target, this.widgetName + \".preventClickEvent\");\n\t\t}\n\n\t\t// these delegates are required to keep context\n\t\tthis._mouseMoveDelegate = function(event) {\n\t\t\treturn that._mouseMove(event);\n\t\t};\n\t\tthis._mouseUpDelegate = function(event) {\n\t\t\treturn that._mouseUp(event);\n\t\t};\n\n\t\tthis.document\n\t\t\t.bind( \"mousemove.\" + this.widgetName, this._mouseMoveDelegate )\n\t\t\t.bind( \"mouseup.\" + this.widgetName, this._mouseUpDelegate );\n\n\t\tevent.preventDefault();\n\n\t\tmouseHandled = true;\n\t\treturn true;\n\t},\n\n\t_mouseMove: function(event) {\n\t\t// Only check for mouseups outside the document if you've moved inside the document\n\t\t// at least once. This prevents the firing of mouseup in the case of IE<9, which will\n\t\t// fire a mousemove event if content is placed under the cursor. See #7778\n\t\t// Support: IE <9\n\t\tif ( this._mouseMoved ) {\n\t\t\t// IE mouseup check - mouseup happened when mouse was out of window\n\t\t\tif ($.ui.ie && ( !document.documentMode || document.documentMode < 9 ) && !event.button) {\n\t\t\t\treturn this._mouseUp(event);\n\n\t\t\t// Iframe mouseup check - mouseup occurred in another document\n\t\t\t} else if ( !event.which ) {\n\t\t\t\treturn this._mouseUp( event );\n\t\t\t}\n\t\t}\n\n\t\tif ( event.which || event.button ) {\n\t\t\tthis._mouseMoved = true;\n\t\t}\n\n\t\tif (this._mouseStarted) {\n\t\t\tthis._mouseDrag(event);\n\t\t\treturn event.preventDefault();\n\t\t}\n\n\t\tif (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {\n\t\t\tthis._mouseStarted =\n\t\t\t\t(this._mouseStart(this._mouseDownEvent, event) !== false);\n\t\t\t(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));\n\t\t}\n\n\t\treturn !this._mouseStarted;\n\t},\n\n\t_mouseUp: function(event) {\n\t\tthis.document\n\t\t\t.unbind( \"mousemove.\" + this.widgetName, this._mouseMoveDelegate )\n\t\t\t.unbind( \"mouseup.\" + this.widgetName, this._mouseUpDelegate );\n\n\t\tif (this._mouseStarted) {\n\t\t\tthis._mouseStarted = false;\n\n\t\t\tif (event.target === this._mouseDownEvent.target) {\n\t\t\t\t$.data(event.target, this.widgetName + \".preventClickEvent\", true);\n\t\t\t}\n\n\t\t\tthis._mouseStop(event);\n\t\t}\n\n\t\tmouseHandled = false;\n\t\treturn false;\n\t},\n\n\t_mouseDistanceMet: function(event) {\n\t\treturn (Math.max(\n\t\t\t\tMath.abs(this._mouseDownEvent.pageX - event.pageX),\n\t\t\t\tMath.abs(this._mouseDownEvent.pageY - event.pageY)\n\t\t\t) >= this.options.distance\n\t\t);\n\t},\n\n\t_mouseDelayMet: function(/* event */) {\n\t\treturn this.mouseDelayMet;\n\t},\n\n\t// These are placeholder methods, to be overriden by extending plugin\n\t_mouseStart: function(/* event */) {},\n\t_mouseDrag: function(/* event */) {},\n\t_mouseStop: function(/* event */) {},\n\t_mouseCapture: function(/* event */) { return true; }\n});\n\n\n/*!\n * jQuery UI Position 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/position/\n */\n\n(function() {\n\n$.ui = $.ui || {};\n\nvar cachedScrollbarWidth, supportsOffsetFractions,\n\tmax = Math.max,\n\tabs = Math.abs,\n\tround = Math.round,\n\trhorizontal = /left|center|right/,\n\trvertical = /top|center|bottom/,\n\troffset = /[\\+\\-]\\d+(\\.[\\d]+)?%?/,\n\trposition = /^\\w+/,\n\trpercent = /%$/,\n\t_position = $.fn.position;\n\nfunction getOffsets( offsets, width, height ) {\n\treturn [\n\t\tparseFloat( offsets[ 0 ] ) * ( rpercent.test( offsets[ 0 ] ) ? width / 100 : 1 ),\n\t\tparseFloat( offsets[ 1 ] ) * ( rpercent.test( offsets[ 1 ] ) ? height / 100 : 1 )\n\t];\n}\n\nfunction parseCss( element, property ) {\n\treturn parseInt( $.css( element, property ), 10 ) || 0;\n}\n\nfunction getDimensions( elem ) {\n\tvar raw = elem[0];\n\tif ( raw.nodeType === 9 ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: 0, left: 0 }\n\t\t};\n\t}\n\tif ( $.isWindow( raw ) ) {\n\t\treturn {\n\t\t\twidth: elem.width(),\n\t\t\theight: elem.height(),\n\t\t\toffset: { top: elem.scrollTop(), left: elem.scrollLeft() }\n\t\t};\n\t}\n\tif ( raw.preventDefault ) {\n\t\treturn {\n\t\t\twidth: 0,\n\t\t\theight: 0,\n\t\t\toffset: { top: raw.pageY, left: raw.pageX }\n\t\t};\n\t}\n\treturn {\n\t\twidth: elem.outerWidth(),\n\t\theight: elem.outerHeight(),\n\t\toffset: elem.offset()\n\t};\n}\n\n$.position = {\n\tscrollbarWidth: function() {\n\t\tif ( cachedScrollbarWidth !== undefined ) {\n\t\t\treturn cachedScrollbarWidth;\n\t\t}\n\t\tvar w1, w2,\n\t\t\tdiv = $( \"<div style='display:block;position:absolute;width:50px;height:50px;overflow:hidden;'><div style='height:100px;width:auto;'></div></div>\" ),\n\t\t\tinnerDiv = div.children()[0];\n\n\t\t$( \"body\" ).append( div );\n\t\tw1 = innerDiv.offsetWidth;\n\t\tdiv.css( \"overflow\", \"scroll\" );\n\n\t\tw2 = innerDiv.offsetWidth;\n\n\t\tif ( w1 === w2 ) {\n\t\t\tw2 = div[0].clientWidth;\n\t\t}\n\n\t\tdiv.remove();\n\n\t\treturn (cachedScrollbarWidth = w1 - w2);\n\t},\n\tgetScrollInfo: function( within ) {\n\t\tvar overflowX = within.isWindow || within.isDocument ? \"\" :\n\t\t\t\twithin.element.css( \"overflow-x\" ),\n\t\t\toverflowY = within.isWindow || within.isDocument ? \"\" :\n\t\t\t\twithin.element.css( \"overflow-y\" ),\n\t\t\thasOverflowX = overflowX === \"scroll\" ||\n\t\t\t\t( overflowX === \"auto\" && within.width < within.element[0].scrollWidth ),\n\t\t\thasOverflowY = overflowY === \"scroll\" ||\n\t\t\t\t( overflowY === \"auto\" && within.height < within.element[0].scrollHeight );\n\t\treturn {\n\t\t\twidth: hasOverflowY ? $.position.scrollbarWidth() : 0,\n\t\t\theight: hasOverflowX ? $.position.scrollbarWidth() : 0\n\t\t};\n\t},\n\tgetWithinInfo: function( element ) {\n\t\tvar withinElement = $( element || window ),\n\t\t\tisWindow = $.isWindow( withinElement[0] ),\n\t\t\tisDocument = !!withinElement[ 0 ] && withinElement[ 0 ].nodeType === 9;\n\t\treturn {\n\t\t\telement: withinElement,\n\t\t\tisWindow: isWindow,\n\t\t\tisDocument: isDocument,\n\t\t\toffset: withinElement.offset() || { left: 0, top: 0 },\n\t\t\tscrollLeft: withinElement.scrollLeft(),\n\t\t\tscrollTop: withinElement.scrollTop(),\n\n\t\t\t// support: jQuery 1.6.x\n\t\t\t// jQuery 1.6 doesn't support .outerWidth/Height() on documents or windows\n\t\t\twidth: isWindow || isDocument ? withinElement.width() : withinElement.outerWidth(),\n\t\t\theight: isWindow || isDocument ? withinElement.height() : withinElement.outerHeight()\n\t\t};\n\t}\n};\n\n$.fn.position = function( options ) {\n\tif ( !options || !options.of ) {\n\t\treturn _position.apply( this, arguments );\n\t}\n\n\t// make a copy, we don't want to modify arguments\n\toptions = $.extend( {}, options );\n\n\tvar atOffset, targetWidth, targetHeight, targetOffset, basePosition, dimensions,\n\t\ttarget = $( options.of ),\n\t\twithin = $.position.getWithinInfo( options.within ),\n\t\tscrollInfo = $.position.getScrollInfo( within ),\n\t\tcollision = ( options.collision || \"flip\" ).split( \" \" ),\n\t\toffsets = {};\n\n\tdimensions = getDimensions( target );\n\tif ( target[0].preventDefault ) {\n\t\t// force left top to allow flipping\n\t\toptions.at = \"left top\";\n\t}\n\ttargetWidth = dimensions.width;\n\ttargetHeight = dimensions.height;\n\ttargetOffset = dimensions.offset;\n\t// clone to reuse original targetOffset later\n\tbasePosition = $.extend( {}, targetOffset );\n\n\t// force my and at to have valid horizontal and vertical positions\n\t// if a value is missing or invalid, it will be converted to center\n\t$.each( [ \"my\", \"at\" ], function() {\n\t\tvar pos = ( options[ this ] || \"\" ).split( \" \" ),\n\t\t\thorizontalOffset,\n\t\t\tverticalOffset;\n\n\t\tif ( pos.length === 1) {\n\t\t\tpos = rhorizontal.test( pos[ 0 ] ) ?\n\t\t\t\tpos.concat( [ \"center\" ] ) :\n\t\t\t\trvertical.test( pos[ 0 ] ) ?\n\t\t\t\t\t[ \"center\" ].concat( pos ) :\n\t\t\t\t\t[ \"center\", \"center\" ];\n\t\t}\n\t\tpos[ 0 ] = rhorizontal.test( pos[ 0 ] ) ? pos[ 0 ] : \"center\";\n\t\tpos[ 1 ] = rvertical.test( pos[ 1 ] ) ? pos[ 1 ] : \"center\";\n\n\t\t// calculate offsets\n\t\thorizontalOffset = roffset.exec( pos[ 0 ] );\n\t\tverticalOffset = roffset.exec( pos[ 1 ] );\n\t\toffsets[ this ] = [\n\t\t\thorizontalOffset ? horizontalOffset[ 0 ] : 0,\n\t\t\tverticalOffset ? verticalOffset[ 0 ] : 0\n\t\t];\n\n\t\t// reduce to just the positions without the offsets\n\t\toptions[ this ] = [\n\t\t\trposition.exec( pos[ 0 ] )[ 0 ],\n\t\t\trposition.exec( pos[ 1 ] )[ 0 ]\n\t\t];\n\t});\n\n\t// normalize collision option\n\tif ( collision.length === 1 ) {\n\t\tcollision[ 1 ] = collision[ 0 ];\n\t}\n\n\tif ( options.at[ 0 ] === \"right\" ) {\n\t\tbasePosition.left += targetWidth;\n\t} else if ( options.at[ 0 ] === \"center\" ) {\n\t\tbasePosition.left += targetWidth / 2;\n\t}\n\n\tif ( options.at[ 1 ] === \"bottom\" ) {\n\t\tbasePosition.top += targetHeight;\n\t} else if ( options.at[ 1 ] === \"center\" ) {\n\t\tbasePosition.top += targetHeight / 2;\n\t}\n\n\tatOffset = getOffsets( offsets.at, targetWidth, targetHeight );\n\tbasePosition.left += atOffset[ 0 ];\n\tbasePosition.top += atOffset[ 1 ];\n\n\treturn this.each(function() {\n\t\tvar collisionPosition, using,\n\t\t\telem = $( this ),\n\t\t\telemWidth = elem.outerWidth(),\n\t\t\telemHeight = elem.outerHeight(),\n\t\t\tmarginLeft = parseCss( this, \"marginLeft\" ),\n\t\t\tmarginTop = parseCss( this, \"marginTop\" ),\n\t\t\tcollisionWidth = elemWidth + marginLeft + parseCss( this, \"marginRight\" ) + scrollInfo.width,\n\t\t\tcollisionHeight = elemHeight + marginTop + parseCss( this, \"marginBottom\" ) + scrollInfo.height,\n\t\t\tposition = $.extend( {}, basePosition ),\n\t\t\tmyOffset = getOffsets( offsets.my, elem.outerWidth(), elem.outerHeight() );\n\n\t\tif ( options.my[ 0 ] === \"right\" ) {\n\t\t\tposition.left -= elemWidth;\n\t\t} else if ( options.my[ 0 ] === \"center\" ) {\n\t\t\tposition.left -= elemWidth / 2;\n\t\t}\n\n\t\tif ( options.my[ 1 ] === \"bottom\" ) {\n\t\t\tposition.top -= elemHeight;\n\t\t} else if ( options.my[ 1 ] === \"center\" ) {\n\t\t\tposition.top -= elemHeight / 2;\n\t\t}\n\n\t\tposition.left += myOffset[ 0 ];\n\t\tposition.top += myOffset[ 1 ];\n\n\t\t// if the browser doesn't support fractions, then round for consistent results\n\t\tif ( !supportsOffsetFractions ) {\n\t\t\tposition.left = round( position.left );\n\t\t\tposition.top = round( position.top );\n\t\t}\n\n\t\tcollisionPosition = {\n\t\t\tmarginLeft: marginLeft,\n\t\t\tmarginTop: marginTop\n\t\t};\n\n\t\t$.each( [ \"left\", \"top\" ], function( i, dir ) {\n\t\t\tif ( $.ui.position[ collision[ i ] ] ) {\n\t\t\t\t$.ui.position[ collision[ i ] ][ dir ]( position, {\n\t\t\t\t\ttargetWidth: targetWidth,\n\t\t\t\t\ttargetHeight: targetHeight,\n\t\t\t\t\telemWidth: elemWidth,\n\t\t\t\t\telemHeight: elemHeight,\n\t\t\t\t\tcollisionPosition: collisionPosition,\n\t\t\t\t\tcollisionWidth: collisionWidth,\n\t\t\t\t\tcollisionHeight: collisionHeight,\n\t\t\t\t\toffset: [ atOffset[ 0 ] + myOffset[ 0 ], atOffset [ 1 ] + myOffset[ 1 ] ],\n\t\t\t\t\tmy: options.my,\n\t\t\t\t\tat: options.at,\n\t\t\t\t\twithin: within,\n\t\t\t\t\telem: elem\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\tif ( options.using ) {\n\t\t\t// adds feedback as second argument to using callback, if present\n\t\t\tusing = function( props ) {\n\t\t\t\tvar left = targetOffset.left - position.left,\n\t\t\t\t\tright = left + targetWidth - elemWidth,\n\t\t\t\t\ttop = targetOffset.top - position.top,\n\t\t\t\t\tbottom = top + targetHeight - elemHeight,\n\t\t\t\t\tfeedback = {\n\t\t\t\t\t\ttarget: {\n\t\t\t\t\t\t\telement: target,\n\t\t\t\t\t\t\tleft: targetOffset.left,\n\t\t\t\t\t\t\ttop: targetOffset.top,\n\t\t\t\t\t\t\twidth: targetWidth,\n\t\t\t\t\t\t\theight: targetHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\telement: {\n\t\t\t\t\t\t\telement: elem,\n\t\t\t\t\t\t\tleft: position.left,\n\t\t\t\t\t\t\ttop: position.top,\n\t\t\t\t\t\t\twidth: elemWidth,\n\t\t\t\t\t\t\theight: elemHeight\n\t\t\t\t\t\t},\n\t\t\t\t\t\thorizontal: right < 0 ? \"left\" : left > 0 ? \"right\" : \"center\",\n\t\t\t\t\t\tvertical: bottom < 0 ? \"top\" : top > 0 ? \"bottom\" : \"middle\"\n\t\t\t\t\t};\n\t\t\t\tif ( targetWidth < elemWidth && abs( left + right ) < targetWidth ) {\n\t\t\t\t\tfeedback.horizontal = \"center\";\n\t\t\t\t}\n\t\t\t\tif ( targetHeight < elemHeight && abs( top + bottom ) < targetHeight ) {\n\t\t\t\t\tfeedback.vertical = \"middle\";\n\t\t\t\t}\n\t\t\t\tif ( max( abs( left ), abs( right ) ) > max( abs( top ), abs( bottom ) ) ) {\n\t\t\t\t\tfeedback.important = \"horizontal\";\n\t\t\t\t} else {\n\t\t\t\t\tfeedback.important = \"vertical\";\n\t\t\t\t}\n\t\t\t\toptions.using.call( this, props, feedback );\n\t\t\t};\n\t\t}\n\n\t\telem.offset( $.extend( position, { using: using } ) );\n\t});\n};\n\n$.ui.position = {\n\tfit: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\touterWidth = within.width,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = withinOffset - collisionPosLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - withinOffset,\n\t\t\t\tnewOverRight;\n\n\t\t\t// element is wider than within\n\t\t\tif ( data.collisionWidth > outerWidth ) {\n\t\t\t\t// element is initially over the left side of within\n\t\t\t\tif ( overLeft > 0 && overRight <= 0 ) {\n\t\t\t\t\tnewOverRight = position.left + overLeft + data.collisionWidth - outerWidth - withinOffset;\n\t\t\t\t\tposition.left += overLeft - newOverRight;\n\t\t\t\t// element is initially over right side of within\n\t\t\t\t} else if ( overRight > 0 && overLeft <= 0 ) {\n\t\t\t\t\tposition.left = withinOffset;\n\t\t\t\t// element is initially over both left and right sides of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overLeft > overRight ) {\n\t\t\t\t\t\tposition.left = withinOffset + outerWidth - data.collisionWidth;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.left = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t// too far left -> align with left edge\n\t\t\t} else if ( overLeft > 0 ) {\n\t\t\t\tposition.left += overLeft;\n\t\t\t// too far right -> align with right edge\n\t\t\t} else if ( overRight > 0 ) {\n\t\t\t\tposition.left -= overRight;\n\t\t\t// adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.left = max( position.left - collisionPosLeft, position.left );\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\touterHeight = data.within.height,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = withinOffset - collisionPosTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - withinOffset,\n\t\t\t\tnewOverBottom;\n\n\t\t\t// element is taller than within\n\t\t\tif ( data.collisionHeight > outerHeight ) {\n\t\t\t\t// element is initially over the top of within\n\t\t\t\tif ( overTop > 0 && overBottom <= 0 ) {\n\t\t\t\t\tnewOverBottom = position.top + overTop + data.collisionHeight - outerHeight - withinOffset;\n\t\t\t\t\tposition.top += overTop - newOverBottom;\n\t\t\t\t// element is initially over bottom of within\n\t\t\t\t} else if ( overBottom > 0 && overTop <= 0 ) {\n\t\t\t\t\tposition.top = withinOffset;\n\t\t\t\t// element is initially over both top and bottom of within\n\t\t\t\t} else {\n\t\t\t\t\tif ( overTop > overBottom ) {\n\t\t\t\t\t\tposition.top = withinOffset + outerHeight - data.collisionHeight;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tposition.top = withinOffset;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t// too far up -> align with top\n\t\t\t} else if ( overTop > 0 ) {\n\t\t\t\tposition.top += overTop;\n\t\t\t// too far down -> align with bottom edge\n\t\t\t} else if ( overBottom > 0 ) {\n\t\t\t\tposition.top -= overBottom;\n\t\t\t// adjust based on position and margin\n\t\t\t} else {\n\t\t\t\tposition.top = max( position.top - collisionPosTop, position.top );\n\t\t\t}\n\t\t}\n\t},\n\tflip: {\n\t\tleft: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.left + within.scrollLeft,\n\t\t\t\touterWidth = within.width,\n\t\t\t\toffsetLeft = within.isWindow ? within.scrollLeft : within.offset.left,\n\t\t\t\tcollisionPosLeft = position.left - data.collisionPosition.marginLeft,\n\t\t\t\toverLeft = collisionPosLeft - offsetLeft,\n\t\t\t\toverRight = collisionPosLeft + data.collisionWidth - outerWidth - offsetLeft,\n\t\t\t\tmyOffset = data.my[ 0 ] === \"left\" ?\n\t\t\t\t\t-data.elemWidth :\n\t\t\t\t\tdata.my[ 0 ] === \"right\" ?\n\t\t\t\t\t\tdata.elemWidth :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 0 ] === \"left\" ?\n\t\t\t\t\tdata.targetWidth :\n\t\t\t\t\tdata.at[ 0 ] === \"right\" ?\n\t\t\t\t\t\t-data.targetWidth :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 0 ],\n\t\t\t\tnewOverRight,\n\t\t\t\tnewOverLeft;\n\n\t\t\tif ( overLeft < 0 ) {\n\t\t\t\tnewOverRight = position.left + myOffset + atOffset + offset + data.collisionWidth - outerWidth - withinOffset;\n\t\t\t\tif ( newOverRight < 0 || newOverRight < abs( overLeft ) ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t} else if ( overRight > 0 ) {\n\t\t\t\tnewOverLeft = position.left - data.collisionPosition.marginLeft + myOffset + atOffset + offset - offsetLeft;\n\t\t\t\tif ( newOverLeft > 0 || abs( newOverLeft ) < overRight ) {\n\t\t\t\t\tposition.left += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\ttop: function( position, data ) {\n\t\t\tvar within = data.within,\n\t\t\t\twithinOffset = within.offset.top + within.scrollTop,\n\t\t\t\touterHeight = within.height,\n\t\t\t\toffsetTop = within.isWindow ? within.scrollTop : within.offset.top,\n\t\t\t\tcollisionPosTop = position.top - data.collisionPosition.marginTop,\n\t\t\t\toverTop = collisionPosTop - offsetTop,\n\t\t\t\toverBottom = collisionPosTop + data.collisionHeight - outerHeight - offsetTop,\n\t\t\t\ttop = data.my[ 1 ] === \"top\",\n\t\t\t\tmyOffset = top ?\n\t\t\t\t\t-data.elemHeight :\n\t\t\t\t\tdata.my[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\tdata.elemHeight :\n\t\t\t\t\t\t0,\n\t\t\t\tatOffset = data.at[ 1 ] === \"top\" ?\n\t\t\t\t\tdata.targetHeight :\n\t\t\t\t\tdata.at[ 1 ] === \"bottom\" ?\n\t\t\t\t\t\t-data.targetHeight :\n\t\t\t\t\t\t0,\n\t\t\t\toffset = -2 * data.offset[ 1 ],\n\t\t\t\tnewOverTop,\n\t\t\t\tnewOverBottom;\n\t\t\tif ( overTop < 0 ) {\n\t\t\t\tnewOverBottom = position.top + myOffset + atOffset + offset + data.collisionHeight - outerHeight - withinOffset;\n\t\t\t\tif ( newOverBottom < 0 || newOverBottom < abs( overTop ) ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t} else if ( overBottom > 0 ) {\n\t\t\t\tnewOverTop = position.top - data.collisionPosition.marginTop + myOffset + atOffset + offset - offsetTop;\n\t\t\t\tif ( newOverTop > 0 || abs( newOverTop ) < overBottom ) {\n\t\t\t\t\tposition.top += myOffset + atOffset + offset;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tflipfit: {\n\t\tleft: function() {\n\t\t\t$.ui.position.flip.left.apply( this, arguments );\n\t\t\t$.ui.position.fit.left.apply( this, arguments );\n\t\t},\n\t\ttop: function() {\n\t\t\t$.ui.position.flip.top.apply( this, arguments );\n\t\t\t$.ui.position.fit.top.apply( this, arguments );\n\t\t}\n\t}\n};\n\n// fraction support test\n(function() {\n\tvar testElement, testElementParent, testElementStyle, offsetLeft, i,\n\t\tbody = document.getElementsByTagName( \"body\" )[ 0 ],\n\t\tdiv = document.createElement( \"div\" );\n\n\t//Create a \"fake body\" for testing based on method used in jQuery.support\n\ttestElement = document.createElement( body ? \"div\" : \"body\" );\n\ttestElementStyle = {\n\t\tvisibility: \"hidden\",\n\t\twidth: 0,\n\t\theight: 0,\n\t\tborder: 0,\n\t\tmargin: 0,\n\t\tbackground: \"none\"\n\t};\n\tif ( body ) {\n\t\t$.extend( testElementStyle, {\n\t\t\tposition: \"absolute\",\n\t\t\tleft: \"-1000px\",\n\t\t\ttop: \"-1000px\"\n\t\t});\n\t}\n\tfor ( i in testElementStyle ) {\n\t\ttestElement.style[ i ] = testElementStyle[ i ];\n\t}\n\ttestElement.appendChild( div );\n\ttestElementParent = body || document.documentElement;\n\ttestElementParent.insertBefore( testElement, testElementParent.firstChild );\n\n\tdiv.style.cssText = \"position: absolute; left: 10.7432222px;\";\n\n\toffsetLeft = $( div ).offset().left;\n\tsupportsOffsetFractions = offsetLeft > 10 && offsetLeft < 11;\n\n\ttestElement.innerHTML = \"\";\n\ttestElementParent.removeChild( testElement );\n})();\n\n})();\n\nvar position = $.ui.position;\n\n\n/*!\n * jQuery UI Accordion 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/accordion/\n */\n\n\nvar accordion = $.widget( \"ui.accordion\", {\n\tversion: \"1.11.4\",\n\toptions: {\n\t\tactive: 0,\n\t\tanimate: {},\n\t\tcollapsible: false,\n\t\tevent: \"click\",\n\t\theader: \"> li > :first-child,> :not(li):even\",\n\t\theightStyle: \"auto\",\n\t\ticons: {\n\t\t\tactiveHeader: \"ui-icon-triangle-1-s\",\n\t\t\theader: \"ui-icon-triangle-1-e\"\n\t\t},\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tbeforeActivate: null\n\t},\n\n\thideProps: {\n\t\tborderTopWidth: \"hide\",\n\t\tborderBottomWidth: \"hide\",\n\t\tpaddingTop: \"hide\",\n\t\tpaddingBottom: \"hide\",\n\t\theight: \"hide\"\n\t},\n\n\tshowProps: {\n\t\tborderTopWidth: \"show\",\n\t\tborderBottomWidth: \"show\",\n\t\tpaddingTop: \"show\",\n\t\tpaddingBottom: \"show\",\n\t\theight: \"show\"\n\t},\n\n\t_create: function() {\n\t\tvar options = this.options;\n\t\tthis.prevShow = this.prevHide = $();\n\t\tthis.element.addClass( \"ui-accordion ui-widget ui-helper-reset\" )\n\t\t\t// ARIA\n\t\t\t.attr( \"role\", \"tablist\" );\n\n\t\t// don't allow collapsible: false and active: false / null\n\t\tif ( !options.collapsible && (options.active === false || options.active == null) ) {\n\t\t\toptions.active = 0;\n\t\t}\n\n\t\tthis._processPanels();\n\t\t// handle negative values\n\t\tif ( options.active < 0 ) {\n\t\t\toptions.active += this.headers.length;\n\t\t}\n\t\tthis._refresh();\n\t},\n\n\t_getCreateEventData: function() {\n\t\treturn {\n\t\t\theader: this.active,\n\t\t\tpanel: !this.active.length ? $() : this.active.next()\n\t\t};\n\t},\n\n\t_createIcons: function() {\n\t\tvar icons = this.options.icons;\n\t\tif ( icons ) {\n\t\t\t$( \"<span>\" )\n\t\t\t\t.addClass( \"ui-accordion-header-icon ui-icon \" + icons.header )\n\t\t\t\t.prependTo( this.headers );\n\t\t\tthis.active.children( \".ui-accordion-header-icon\" )\n\t\t\t\t.removeClass( icons.header )\n\t\t\t\t.addClass( icons.activeHeader );\n\t\t\tthis.headers.addClass( \"ui-accordion-icons\" );\n\t\t}\n\t},\n\n\t_destroyIcons: function() {\n\t\tthis.headers\n\t\t\t.removeClass( \"ui-accordion-icons\" )\n\t\t\t.children( \".ui-accordion-header-icon\" )\n\t\t\t\t.remove();\n\t},\n\n\t_destroy: function() {\n\t\tvar contents;\n\n\t\t// clean up main element\n\t\tthis.element\n\t\t\t.removeClass( \"ui-accordion ui-widget ui-helper-reset\" )\n\t\t\t.removeAttr( \"role\" );\n\n\t\t// clean up headers\n\t\tthis.headers\n\t\t\t.removeClass( \"ui-accordion-header ui-accordion-header-active ui-state-default \" +\n\t\t\t\t\"ui-corner-all ui-state-active ui-state-disabled ui-corner-top\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-expanded\" )\n\t\t\t.removeAttr( \"aria-selected\" )\n\t\t\t.removeAttr( \"aria-controls\" )\n\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t.removeUniqueId();\n\n\t\tthis._destroyIcons();\n\n\t\t// clean up content panels\n\t\tcontents = this.headers.next()\n\t\t\t.removeClass( \"ui-helper-reset ui-widget-content ui-corner-bottom \" +\n\t\t\t\t\"ui-accordion-content ui-accordion-content-active ui-state-disabled\" )\n\t\t\t.css( \"display\", \"\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t.removeAttr( \"aria-labelledby\" )\n\t\t\t.removeUniqueId();\n\n\t\tif ( this.options.heightStyle !== \"content\" ) {\n\t\t\tcontents.css( \"height\", \"\" );\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"active\" ) {\n\t\t\t// _activate() will handle invalid values and update this.options\n\t\t\tthis._activate( value );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key === \"event\" ) {\n\t\t\tif ( this.options.event ) {\n\t\t\t\tthis._off( this.headers, this.options.event );\n\t\t\t}\n\t\t\tthis._setupEvents( value );\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\t// setting collapsible: false while collapsed; open first panel\n\t\tif ( key === \"collapsible\" && !value && this.options.active === false ) {\n\t\t\tthis._activate( 0 );\n\t\t}\n\n\t\tif ( key === \"icons\" ) {\n\t\t\tthis._destroyIcons();\n\t\t\tif ( value ) {\n\t\t\t\tthis._createIcons();\n\t\t\t}\n\t\t}\n\n\t\t// #5332 - opacity doesn't cascade to positioned elements in IE\n\t\t// so we need to add the disabled class to the headers and panels\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.element\n\t\t\t\t.toggleClass( \"ui-state-disabled\", !!value )\n\t\t\t\t.attr( \"aria-disabled\", value );\n\t\t\tthis.headers.add( this.headers.next() )\n\t\t\t\t.toggleClass( \"ui-state-disabled\", !!value );\n\t\t}\n\t},\n\n\t_keydown: function( event ) {\n\t\tif ( event.altKey || event.ctrlKey ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar keyCode = $.ui.keyCode,\n\t\t\tlength = this.headers.length,\n\t\t\tcurrentIndex = this.headers.index( event.target ),\n\t\t\ttoFocus = false;\n\n\t\tswitch ( event.keyCode ) {\n\t\t\tcase keyCode.RIGHT:\n\t\t\tcase keyCode.DOWN:\n\t\t\t\ttoFocus = this.headers[ ( currentIndex + 1 ) % length ];\n\t\t\t\tbreak;\n\t\t\tcase keyCode.LEFT:\n\t\t\tcase keyCode.UP:\n\t\t\t\ttoFocus = this.headers[ ( currentIndex - 1 + length ) % length ];\n\t\t\t\tbreak;\n\t\t\tcase keyCode.SPACE:\n\t\t\tcase keyCode.ENTER:\n\t\t\t\tthis._eventHandler( event );\n\t\t\t\tbreak;\n\t\t\tcase keyCode.HOME:\n\t\t\t\ttoFocus = this.headers[ 0 ];\n\t\t\t\tbreak;\n\t\t\tcase keyCode.END:\n\t\t\t\ttoFocus = this.headers[ length - 1 ];\n\t\t\t\tbreak;\n\t\t}\n\n\t\tif ( toFocus ) {\n\t\t\t$( event.target ).attr( \"tabIndex\", -1 );\n\t\t\t$( toFocus ).attr( \"tabIndex\", 0 );\n\t\t\ttoFocus.focus();\n\t\t\tevent.preventDefault();\n\t\t}\n\t},\n\n\t_panelKeyDown: function( event ) {\n\t\tif ( event.keyCode === $.ui.keyCode.UP && event.ctrlKey ) {\n\t\t\t$( event.currentTarget ).prev().focus();\n\t\t}\n\t},\n\n\trefresh: function() {\n\t\tvar options = this.options;\n\t\tthis._processPanels();\n\n\t\t// was collapsed or no panel\n\t\tif ( ( options.active === false && options.collapsible === true ) || !this.headers.length ) {\n\t\t\toptions.active = false;\n\t\t\tthis.active = $();\n\t\t// active false only when collapsible is true\n\t\t} else if ( options.active === false ) {\n\t\t\tthis._activate( 0 );\n\t\t// was active, but active panel is gone\n\t\t} else if ( this.active.length && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {\n\t\t\t// all remaining panel are disabled\n\t\t\tif ( this.headers.length === this.headers.find(\".ui-state-disabled\").length ) {\n\t\t\t\toptions.active = false;\n\t\t\t\tthis.active = $();\n\t\t\t// activate previous panel\n\t\t\t} else {\n\t\t\t\tthis._activate( Math.max( 0, options.active - 1 ) );\n\t\t\t}\n\t\t// was active, active panel still exists\n\t\t} else {\n\t\t\t// make sure active index is correct\n\t\t\toptions.active = this.headers.index( this.active );\n\t\t}\n\n\t\tthis._destroyIcons();\n\n\t\tthis._refresh();\n\t},\n\n\t_processPanels: function() {\n\t\tvar prevHeaders = this.headers,\n\t\t\tprevPanels = this.panels;\n\n\t\tthis.headers = this.element.find( this.options.header )\n\t\t\t.addClass( \"ui-accordion-header ui-state-default ui-corner-all\" );\n\n\t\tthis.panels = this.headers.next()\n\t\t\t.addClass( \"ui-accordion-content ui-helper-reset ui-widget-content ui-corner-bottom\" )\n\t\t\t.filter( \":not(.ui-accordion-content-active)\" )\n\t\t\t.hide();\n\n\t\t// Avoid memory leaks (#10056)\n\t\tif ( prevPanels ) {\n\t\t\tthis._off( prevHeaders.not( this.headers ) );\n\t\t\tthis._off( prevPanels.not( this.panels ) );\n\t\t}\n\t},\n\n\t_refresh: function() {\n\t\tvar maxHeight,\n\t\t\toptions = this.options,\n\t\t\theightStyle = options.heightStyle,\n\t\t\tparent = this.element.parent();\n\n\t\tthis.active = this._findActive( options.active )\n\t\t\t.addClass( \"ui-accordion-header-active ui-state-active ui-corner-top\" )\n\t\t\t.removeClass( \"ui-corner-all\" );\n\t\tthis.active.next()\n\t\t\t.addClass( \"ui-accordion-content-active\" )\n\t\t\t.show();\n\n\t\tthis.headers\n\t\t\t.attr( \"role\", \"tab\" )\n\t\t\t.each(function() {\n\t\t\t\tvar header = $( this ),\n\t\t\t\t\theaderId = header.uniqueId().attr( \"id\" ),\n\t\t\t\t\tpanel = header.next(),\n\t\t\t\t\tpanelId = panel.uniqueId().attr( \"id\" );\n\t\t\t\theader.attr( \"aria-controls\", panelId );\n\t\t\t\tpanel.attr( \"aria-labelledby\", headerId );\n\t\t\t})\n\t\t\t.next()\n\t\t\t\t.attr( \"role\", \"tabpanel\" );\n\n\t\tthis.headers\n\t\t\t.not( this.active )\n\t\t\t.attr({\n\t\t\t\t\"aria-selected\": \"false\",\n\t\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\ttabIndex: -1\n\t\t\t})\n\t\t\t.next()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-hidden\": \"true\"\n\t\t\t\t})\n\t\t\t\t.hide();\n\n\t\t// make sure at least one header is in the tab order\n\t\tif ( !this.active.length ) {\n\t\t\tthis.headers.eq( 0 ).attr( \"tabIndex\", 0 );\n\t\t} else {\n\t\t\tthis.active.attr({\n\t\t\t\t\"aria-selected\": \"true\",\n\t\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\ttabIndex: 0\n\t\t\t})\n\t\t\t.next()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-hidden\": \"false\"\n\t\t\t\t});\n\t\t}\n\n\t\tthis._createIcons();\n\n\t\tthis._setupEvents( options.event );\n\n\t\tif ( heightStyle === \"fill\" ) {\n\t\t\tmaxHeight = parent.height();\n\t\t\tthis.element.siblings( \":visible\" ).each(function() {\n\t\t\t\tvar elem = $( this ),\n\t\t\t\t\tposition = elem.css( \"position\" );\n\n\t\t\t\tif ( position === \"absolute\" || position === \"fixed\" ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tmaxHeight -= elem.outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.headers.each(function() {\n\t\t\t\tmaxHeight -= $( this ).outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.headers.next()\n\t\t\t\t.each(function() {\n\t\t\t\t\t$( this ).height( Math.max( 0, maxHeight -\n\t\t\t\t\t\t$( this ).innerHeight() + $( this ).height() ) );\n\t\t\t\t})\n\t\t\t\t.css( \"overflow\", \"auto\" );\n\t\t} else if ( heightStyle === \"auto\" ) {\n\t\t\tmaxHeight = 0;\n\t\t\tthis.headers.next()\n\t\t\t\t.each(function() {\n\t\t\t\t\tmaxHeight = Math.max( maxHeight, $( this ).css( \"height\", \"\" ).height() );\n\t\t\t\t})\n\t\t\t\t.height( maxHeight );\n\t\t}\n\t},\n\n\t_activate: function( index ) {\n\t\tvar active = this._findActive( index )[ 0 ];\n\n\t\t// trying to activate the already active panel\n\t\tif ( active === this.active[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// trying to collapse, simulate a click on the currently active header\n\t\tactive = active || this.active[ 0 ];\n\n\t\tthis._eventHandler({\n\t\t\ttarget: active,\n\t\t\tcurrentTarget: active,\n\t\t\tpreventDefault: $.noop\n\t\t});\n\t},\n\n\t_findActive: function( selector ) {\n\t\treturn typeof selector === \"number\" ? this.headers.eq( selector ) : $();\n\t},\n\n\t_setupEvents: function( event ) {\n\t\tvar events = {\n\t\t\tkeydown: \"_keydown\"\n\t\t};\n\t\tif ( event ) {\n\t\t\t$.each( event.split( \" \" ), function( index, eventName ) {\n\t\t\t\tevents[ eventName ] = \"_eventHandler\";\n\t\t\t});\n\t\t}\n\n\t\tthis._off( this.headers.add( this.headers.next() ) );\n\t\tthis._on( this.headers, events );\n\t\tthis._on( this.headers.next(), { keydown: \"_panelKeyDown\" });\n\t\tthis._hoverable( this.headers );\n\t\tthis._focusable( this.headers );\n\t},\n\n\t_eventHandler: function( event ) {\n\t\tvar options = this.options,\n\t\t\tactive = this.active,\n\t\t\tclicked = $( event.currentTarget ),\n\t\t\tclickedIsActive = clicked[ 0 ] === active[ 0 ],\n\t\t\tcollapsing = clickedIsActive && options.collapsible,\n\t\t\ttoShow = collapsing ? $() : clicked.next(),\n\t\t\ttoHide = active.next(),\n\t\t\teventData = {\n\t\t\t\toldHeader: active,\n\t\t\t\toldPanel: toHide,\n\t\t\t\tnewHeader: collapsing ? $() : clicked,\n\t\t\t\tnewPanel: toShow\n\t\t\t};\n\n\t\tevent.preventDefault();\n\n\t\tif (\n\t\t\t\t// click on active header, but not collapsible\n\t\t\t\t( clickedIsActive && !options.collapsible ) ||\n\t\t\t\t// allow canceling activation\n\t\t\t\t( this._trigger( \"beforeActivate\", event, eventData ) === false ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\toptions.active = collapsing ? false : this.headers.index( clicked );\n\n\t\t// when the call to ._toggle() comes after the class changes\n\t\t// it causes a very odd bug in IE 8 (see #6720)\n\t\tthis.active = clickedIsActive ? $() : clicked;\n\t\tthis._toggle( eventData );\n\n\t\t// switch classes\n\t\t// corner classes on the previously active header stay after the animation\n\t\tactive.removeClass( \"ui-accordion-header-active ui-state-active\" );\n\t\tif ( options.icons ) {\n\t\t\tactive.children( \".ui-accordion-header-icon\" )\n\t\t\t\t.removeClass( options.icons.activeHeader )\n\t\t\t\t.addClass( options.icons.header );\n\t\t}\n\n\t\tif ( !clickedIsActive ) {\n\t\t\tclicked\n\t\t\t\t.removeClass( \"ui-corner-all\" )\n\t\t\t\t.addClass( \"ui-accordion-header-active ui-state-active ui-corner-top\" );\n\t\t\tif ( options.icons ) {\n\t\t\t\tclicked.children( \".ui-accordion-header-icon\" )\n\t\t\t\t\t.removeClass( options.icons.header )\n\t\t\t\t\t.addClass( options.icons.activeHeader );\n\t\t\t}\n\n\t\t\tclicked\n\t\t\t\t.next()\n\t\t\t\t.addClass( \"ui-accordion-content-active\" );\n\t\t}\n\t},\n\n\t_toggle: function( data ) {\n\t\tvar toShow = data.newPanel,\n\t\t\ttoHide = this.prevShow.length ? this.prevShow : data.oldPanel;\n\n\t\t// handle activating a panel during the animation for another activation\n\t\tthis.prevShow.add( this.prevHide ).stop( true, true );\n\t\tthis.prevShow = toShow;\n\t\tthis.prevHide = toHide;\n\n\t\tif ( this.options.animate ) {\n\t\t\tthis._animate( toShow, toHide, data );\n\t\t} else {\n\t\t\ttoHide.hide();\n\t\t\ttoShow.show();\n\t\t\tthis._toggleComplete( data );\n\t\t}\n\n\t\ttoHide.attr({\n\t\t\t\"aria-hidden\": \"true\"\n\t\t});\n\t\ttoHide.prev().attr({\n\t\t\t\"aria-selected\": \"false\",\n\t\t\t\"aria-expanded\": \"false\"\n\t\t});\n\t\t// if we're switching panels, remove the old header from the tab order\n\t\t// if we're opening from collapsed state, remove the previous header from the tab order\n\t\t// if we're collapsing, then keep the collapsing header in the tab order\n\t\tif ( toShow.length && toHide.length ) {\n\t\t\ttoHide.prev().attr({\n\t\t\t\t\"tabIndex\": -1,\n\t\t\t\t\"aria-expanded\": \"false\"\n\t\t\t});\n\t\t} else if ( toShow.length ) {\n\t\t\tthis.headers.filter(function() {\n\t\t\t\treturn parseInt( $( this ).attr( \"tabIndex\" ), 10 ) === 0;\n\t\t\t})\n\t\t\t.attr( \"tabIndex\", -1 );\n\t\t}\n\n\t\ttoShow\n\t\t\t.attr( \"aria-hidden\", \"false\" )\n\t\t\t.prev()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-selected\": \"true\",\n\t\t\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\t\ttabIndex: 0\n\t\t\t\t});\n\t},\n\n\t_animate: function( toShow, toHide, data ) {\n\t\tvar total, easing, duration,\n\t\t\tthat = this,\n\t\t\tadjust = 0,\n\t\t\tboxSizing = toShow.css( \"box-sizing\" ),\n\t\t\tdown = toShow.length &&\n\t\t\t\t( !toHide.length || ( toShow.index() < toHide.index() ) ),\n\t\t\tanimate = this.options.animate || {},\n\t\t\toptions = down && animate.down || animate,\n\t\t\tcomplete = function() {\n\t\t\t\tthat._toggleComplete( data );\n\t\t\t};\n\n\t\tif ( typeof options === \"number\" ) {\n\t\t\tduration = options;\n\t\t}\n\t\tif ( typeof options === \"string\" ) {\n\t\t\teasing = options;\n\t\t}\n\t\t// fall back from options to animation in case of partial down settings\n\t\teasing = easing || options.easing || animate.easing;\n\t\tduration = duration || options.duration || animate.duration;\n\n\t\tif ( !toHide.length ) {\n\t\t\treturn toShow.animate( this.showProps, duration, easing, complete );\n\t\t}\n\t\tif ( !toShow.length ) {\n\t\t\treturn toHide.animate( this.hideProps, duration, easing, complete );\n\t\t}\n\n\t\ttotal = toShow.show().outerHeight();\n\t\ttoHide.animate( this.hideProps, {\n\t\t\tduration: duration,\n\t\t\teasing: easing,\n\t\t\tstep: function( now, fx ) {\n\t\t\t\tfx.now = Math.round( now );\n\t\t\t}\n\t\t});\n\t\ttoShow\n\t\t\t.hide()\n\t\t\t.animate( this.showProps, {\n\t\t\t\tduration: duration,\n\t\t\t\teasing: easing,\n\t\t\t\tcomplete: complete,\n\t\t\t\tstep: function( now, fx ) {\n\t\t\t\t\tfx.now = Math.round( now );\n\t\t\t\t\tif ( fx.prop !== \"height\" ) {\n\t\t\t\t\t\tif ( boxSizing === \"content-box\" ) {\n\t\t\t\t\t\t\tadjust += fx.now;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if ( that.options.heightStyle !== \"content\" ) {\n\t\t\t\t\t\tfx.now = Math.round( total - toHide.outerHeight() - adjust );\n\t\t\t\t\t\tadjust = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t},\n\n\t_toggleComplete: function( data ) {\n\t\tvar toHide = data.oldPanel;\n\n\t\ttoHide\n\t\t\t.removeClass( \"ui-accordion-content-active\" )\n\t\t\t.prev()\n\t\t\t\t.removeClass( \"ui-corner-top\" )\n\t\t\t\t.addClass( \"ui-corner-all\" );\n\n\t\t// Work around for rendering bug in IE (#5421)\n\t\tif ( toHide.length ) {\n\t\t\ttoHide.parent()[ 0 ].className = toHide.parent()[ 0 ].className;\n\t\t}\n\t\tthis._trigger( \"activate\", null, data );\n\t}\n});\n\n\n/*!\n * jQuery UI Menu 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/menu/\n */\n\n\nvar menu = $.widget( \"ui.menu\", {\n\tversion: \"1.11.4\",\n\tdefaultElement: \"<ul>\",\n\tdelay: 300,\n\toptions: {\n\t\ticons: {\n\t\t\tsubmenu: \"ui-icon-carat-1-e\"\n\t\t},\n\t\titems: \"> *\",\n\t\tmenus: \"ul\",\n\t\tposition: {\n\t\t\tmy: \"left-1 top\",\n\t\t\tat: \"right top\"\n\t\t},\n\t\trole: \"menu\",\n\n\t\t// callbacks\n\t\tblur: null,\n\t\tfocus: null,\n\t\tselect: null\n\t},\n\n\t_create: function() {\n\t\tthis.activeMenu = this.element;\n\n\t\t// Flag used to prevent firing of the click handler\n\t\t// as the event bubbles up through nested menus\n\t\tthis.mouseHandled = false;\n\t\tthis.element\n\t\t\t.uniqueId()\n\t\t\t.addClass( \"ui-menu ui-widget ui-widget-content\" )\n\t\t\t.toggleClass( \"ui-menu-icons\", !!this.element.find( \".ui-icon\" ).length )\n\t\t\t.attr({\n\t\t\t\trole: this.options.role,\n\t\t\t\ttabIndex: 0\n\t\t\t});\n\n\t\tif ( this.options.disabled ) {\n\t\t\tthis.element\n\t\t\t\t.addClass( \"ui-state-disabled\" )\n\t\t\t\t.attr( \"aria-disabled\", \"true\" );\n\t\t}\n\n\t\tthis._on({\n\t\t\t// Prevent focus from sticking to links inside menu after clicking\n\t\t\t// them (focus should always stay on UL during navigation).\n\t\t\t\"mousedown .ui-menu-item\": function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t},\n\t\t\t\"click .ui-menu-item\": function( event ) {\n\t\t\t\tvar target = $( event.target );\n\t\t\t\tif ( !this.mouseHandled && target.not( \".ui-state-disabled\" ).length ) {\n\t\t\t\t\tthis.select( event );\n\n\t\t\t\t\t// Only set the mouseHandled flag if the event will bubble, see #9469.\n\t\t\t\t\tif ( !event.isPropagationStopped() ) {\n\t\t\t\t\t\tthis.mouseHandled = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Open submenu on click\n\t\t\t\t\tif ( target.has( \".ui-menu\" ).length ) {\n\t\t\t\t\t\tthis.expand( event );\n\t\t\t\t\t} else if ( !this.element.is( \":focus\" ) && $( this.document[ 0 ].activeElement ).closest( \".ui-menu\" ).length ) {\n\n\t\t\t\t\t\t// Redirect focus to the menu\n\t\t\t\t\t\tthis.element.trigger( \"focus\", [ true ] );\n\n\t\t\t\t\t\t// If the active item is on the top level, let it stay active.\n\t\t\t\t\t\t// Otherwise, blur the active item since it is no longer visible.\n\t\t\t\t\t\tif ( this.active && this.active.parents( \".ui-menu\" ).length === 1 ) {\n\t\t\t\t\t\t\tclearTimeout( this.timer );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"mouseenter .ui-menu-item\": function( event ) {\n\t\t\t\t// Ignore mouse events while typeahead is active, see #10458.\n\t\t\t\t// Prevents focusing the wrong item when typeahead causes a scroll while the mouse\n\t\t\t\t// is over an item in the menu\n\t\t\t\tif ( this.previousFilter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar target = $( event.currentTarget );\n\t\t\t\t// Remove ui-state-active class from siblings of the newly focused menu item\n\t\t\t\t// to avoid a jump caused by adjacent elements both having a class with a border\n\t\t\t\ttarget.siblings( \".ui-state-active\" ).removeClass( \"ui-state-active\" );\n\t\t\t\tthis.focus( event, target );\n\t\t\t},\n\t\t\tmouseleave: \"collapseAll\",\n\t\t\t\"mouseleave .ui-menu\": \"collapseAll\",\n\t\t\tfocus: function( event, keepActiveItem ) {\n\t\t\t\t// If there's already an active item, keep it active\n\t\t\t\t// If not, activate the first item\n\t\t\t\tvar item = this.active || this.element.find( this.options.items ).eq( 0 );\n\n\t\t\t\tif ( !keepActiveItem ) {\n\t\t\t\t\tthis.focus( event, item );\n\t\t\t\t}\n\t\t\t},\n\t\t\tblur: function( event ) {\n\t\t\t\tthis._delay(function() {\n\t\t\t\t\tif ( !$.contains( this.element[0], this.document[0].activeElement ) ) {\n\t\t\t\t\t\tthis.collapseAll( event );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t},\n\t\t\tkeydown: \"_keydown\"\n\t\t});\n\n\t\tthis.refresh();\n\n\t\t// Clicks outside of a menu collapse any open menus\n\t\tthis._on( this.document, {\n\t\t\tclick: function( event ) {\n\t\t\t\tif ( this._closeOnDocumentClick( event ) ) {\n\t\t\t\t\tthis.collapseAll( event );\n\t\t\t\t}\n\n\t\t\t\t// Reset the mouseHandled flag\n\t\t\t\tthis.mouseHandled = false;\n\t\t\t}\n\t\t});\n\t},\n\n\t_destroy: function() {\n\t\t// Destroy (sub)menus\n\t\tthis.element\n\t\t\t.removeAttr( \"aria-activedescendant\" )\n\t\t\t.find( \".ui-menu\" ).addBack()\n\t\t\t\t.removeClass( \"ui-menu ui-widget ui-widget-content ui-menu-icons ui-front\" )\n\t\t\t\t.removeAttr( \"role\" )\n\t\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t\t.removeAttr( \"aria-labelledby\" )\n\t\t\t\t.removeAttr( \"aria-expanded\" )\n\t\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t\t.removeUniqueId()\n\t\t\t\t.show();\n\n\t\t// Destroy menu items\n\t\tthis.element.find( \".ui-menu-item\" )\n\t\t\t.removeClass( \"ui-menu-item\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-disabled\" )\n\t\t\t.removeUniqueId()\n\t\t\t.removeClass( \"ui-state-hover\" )\n\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-haspopup\" )\n\t\t\t.children().each( function() {\n\t\t\t\tvar elem = $( this );\n\t\t\t\tif ( elem.data( \"ui-menu-submenu-carat\" ) ) {\n\t\t\t\t\telem.remove();\n\t\t\t\t}\n\t\t\t});\n\n\t\t// Destroy menu dividers\n\t\tthis.element.find( \".ui-menu-divider\" ).removeClass( \"ui-menu-divider ui-widget-content\" );\n\t},\n\n\t_keydown: function( event ) {\n\t\tvar match, prev, character, skip,\n\t\t\tpreventDefault = true;\n\n\t\tswitch ( event.keyCode ) {\n\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\tthis.previousPage( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\tthis.nextPage( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.HOME:\n\t\t\tthis._move( \"first\", \"first\", event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.END:\n\t\t\tthis._move( \"last\", \"last\", event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.UP:\n\t\t\tthis.previous( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.DOWN:\n\t\t\tthis.next( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.LEFT:\n\t\t\tthis.collapse( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.RIGHT:\n\t\t\tif ( this.active && !this.active.is( \".ui-state-disabled\" ) ) {\n\t\t\t\tthis.expand( event );\n\t\t\t}\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.ENTER:\n\t\tcase $.ui.keyCode.SPACE:\n\t\t\tthis._activate( event );\n\t\t\tbreak;\n\t\tcase $.ui.keyCode.ESCAPE:\n\t\t\tthis.collapse( event );\n\t\t\tbreak;\n\t\tdefault:\n\t\t\tpreventDefault = false;\n\t\t\tprev = this.previousFilter || \"\";\n\t\t\tcharacter = String.fromCharCode( event.keyCode );\n\t\t\tskip = false;\n\n\t\t\tclearTimeout( this.filterTimer );\n\n\t\t\tif ( character === prev ) {\n\t\t\t\tskip = true;\n\t\t\t} else {\n\t\t\t\tcharacter = prev + character;\n\t\t\t}\n\n\t\t\tmatch = this._filterMenuItems( character );\n\t\t\tmatch = skip && match.index( this.active.next() ) !== -1 ?\n\t\t\t\tthis.active.nextAll( \".ui-menu-item\" ) :\n\t\t\t\tmatch;\n\n\t\t\t// If no matches on the current filter, reset to the last character pressed\n\t\t\t// to move down the menu to the first item that starts with that character\n\t\t\tif ( !match.length ) {\n\t\t\t\tcharacter = String.fromCharCode( event.keyCode );\n\t\t\t\tmatch = this._filterMenuItems( character );\n\t\t\t}\n\n\t\t\tif ( match.length ) {\n\t\t\t\tthis.focus( event, match );\n\t\t\t\tthis.previousFilter = character;\n\t\t\t\tthis.filterTimer = this._delay(function() {\n\t\t\t\t\tdelete this.previousFilter;\n\t\t\t\t}, 1000 );\n\t\t\t} else {\n\t\t\t\tdelete this.previousFilter;\n\t\t\t}\n\t\t}\n\n\t\tif ( preventDefault ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t},\n\n\t_activate: function( event ) {\n\t\tif ( !this.active.is( \".ui-state-disabled\" ) ) {\n\t\t\tif ( this.active.is( \"[aria-haspopup='true']\" ) ) {\n\t\t\t\tthis.expand( event );\n\t\t\t} else {\n\t\t\t\tthis.select( event );\n\t\t\t}\n\t\t}\n\t},\n\n\trefresh: function() {\n\t\tvar menus, items,\n\t\t\tthat = this,\n\t\t\ticon = this.options.icons.submenu,\n\t\t\tsubmenus = this.element.find( this.options.menus );\n\n\t\tthis.element.toggleClass( \"ui-menu-icons\", !!this.element.find( \".ui-icon\" ).length );\n\n\t\t// Initialize nested menus\n\t\tsubmenus.filter( \":not(.ui-menu)\" )\n\t\t\t.addClass( \"ui-menu ui-widget ui-widget-content ui-front\" )\n\t\t\t.hide()\n\t\t\t.attr({\n\t\t\t\trole: this.options.role,\n\t\t\t\t\"aria-hidden\": \"true\",\n\t\t\t\t\"aria-expanded\": \"false\"\n\t\t\t})\n\t\t\t.each(function() {\n\t\t\t\tvar menu = $( this ),\n\t\t\t\t\titem = menu.parent(),\n\t\t\t\t\tsubmenuCarat = $( \"<span>\" )\n\t\t\t\t\t\t.addClass( \"ui-menu-icon ui-icon \" + icon )\n\t\t\t\t\t\t.data( \"ui-menu-submenu-carat\", true );\n\n\t\t\t\titem\n\t\t\t\t\t.attr( \"aria-haspopup\", \"true\" )\n\t\t\t\t\t.prepend( submenuCarat );\n\t\t\t\tmenu.attr( \"aria-labelledby\", item.attr( \"id\" ) );\n\t\t\t});\n\n\t\tmenus = submenus.add( this.element );\n\t\titems = menus.find( this.options.items );\n\n\t\t// Initialize menu-items containing spaces and/or dashes only as dividers\n\t\titems.not( \".ui-menu-item\" ).each(function() {\n\t\t\tvar item = $( this );\n\t\t\tif ( that._isDivider( item ) ) {\n\t\t\t\titem.addClass( \"ui-widget-content ui-menu-divider\" );\n\t\t\t}\n\t\t});\n\n\t\t// Don't refresh list items that are already adapted\n\t\titems.not( \".ui-menu-item, .ui-menu-divider\" )\n\t\t\t.addClass( \"ui-menu-item\" )\n\t\t\t.uniqueId()\n\t\t\t.attr({\n\t\t\t\ttabIndex: -1,\n\t\t\t\trole: this._itemRole()\n\t\t\t});\n\n\t\t// Add aria-disabled attribute to any disabled menu item\n\t\titems.filter( \".ui-state-disabled\" ).attr( \"aria-disabled\", \"true\" );\n\n\t\t// If the active item has been removed, blur the menu\n\t\tif ( this.active && !$.contains( this.element[ 0 ], this.active[ 0 ] ) ) {\n\t\t\tthis.blur();\n\t\t}\n\t},\n\n\t_itemRole: function() {\n\t\treturn {\n\t\t\tmenu: \"menuitem\",\n\t\t\tlistbox: \"option\"\n\t\t}[ this.options.role ];\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"icons\" ) {\n\t\t\tthis.element.find( \".ui-menu-icon\" )\n\t\t\t\t.removeClass( this.options.icons.submenu )\n\t\t\t\t.addClass( value.submenu );\n\t\t}\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.element\n\t\t\t\t.toggleClass( \"ui-state-disabled\", !!value )\n\t\t\t\t.attr( \"aria-disabled\", value );\n\t\t}\n\t\tthis._super( key, value );\n\t},\n\n\tfocus: function( event, item ) {\n\t\tvar nested, focused;\n\t\tthis.blur( event, event && event.type === \"focus\" );\n\n\t\tthis._scrollIntoView( item );\n\n\t\tthis.active = item.first();\n\t\tfocused = this.active.addClass( \"ui-state-focus\" ).removeClass( \"ui-state-active\" );\n\t\t// Only update aria-activedescendant if there's a role\n\t\t// otherwise we assume focus is managed elsewhere\n\t\tif ( this.options.role ) {\n\t\t\tthis.element.attr( \"aria-activedescendant\", focused.attr( \"id\" ) );\n\t\t}\n\n\t\t// Highlight active parent menu item, if any\n\t\tthis.active\n\t\t\t.parent()\n\t\t\t.closest( \".ui-menu-item\" )\n\t\t\t.addClass( \"ui-state-active\" );\n\n\t\tif ( event && event.type === \"keydown\" ) {\n\t\t\tthis._close();\n\t\t} else {\n\t\t\tthis.timer = this._delay(function() {\n\t\t\t\tthis._close();\n\t\t\t}, this.delay );\n\t\t}\n\n\t\tnested = item.children( \".ui-menu\" );\n\t\tif ( nested.length && event && ( /^mouse/.test( event.type ) ) ) {\n\t\t\tthis._startOpening(nested);\n\t\t}\n\t\tthis.activeMenu = item.parent();\n\n\t\tthis._trigger( \"focus\", event, { item: item } );\n\t},\n\n\t_scrollIntoView: function( item ) {\n\t\tvar borderTop, paddingTop, offset, scroll, elementHeight, itemHeight;\n\t\tif ( this._hasScroll() ) {\n\t\t\tborderTop = parseFloat( $.css( this.activeMenu[0], \"borderTopWidth\" ) ) || 0;\n\t\t\tpaddingTop = parseFloat( $.css( this.activeMenu[0], \"paddingTop\" ) ) || 0;\n\t\t\toffset = item.offset().top - this.activeMenu.offset().top - borderTop - paddingTop;\n\t\t\tscroll = this.activeMenu.scrollTop();\n\t\t\telementHeight = this.activeMenu.height();\n\t\t\titemHeight = item.outerHeight();\n\n\t\t\tif ( offset < 0 ) {\n\t\t\t\tthis.activeMenu.scrollTop( scroll + offset );\n\t\t\t} else if ( offset + itemHeight > elementHeight ) {\n\t\t\t\tthis.activeMenu.scrollTop( scroll + offset - elementHeight + itemHeight );\n\t\t\t}\n\t\t}\n\t},\n\n\tblur: function( event, fromFocus ) {\n\t\tif ( !fromFocus ) {\n\t\t\tclearTimeout( this.timer );\n\t\t}\n\n\t\tif ( !this.active ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.active.removeClass( \"ui-state-focus\" );\n\t\tthis.active = null;\n\n\t\tthis._trigger( \"blur\", event, { item: this.active } );\n\t},\n\n\t_startOpening: function( submenu ) {\n\t\tclearTimeout( this.timer );\n\n\t\t// Don't open if already open fixes a Firefox bug that caused a .5 pixel\n\t\t// shift in the submenu position when mousing over the carat icon\n\t\tif ( submenu.attr( \"aria-hidden\" ) !== \"true\" ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.timer = this._delay(function() {\n\t\t\tthis._close();\n\t\t\tthis._open( submenu );\n\t\t}, this.delay );\n\t},\n\n\t_open: function( submenu ) {\n\t\tvar position = $.extend({\n\t\t\tof: this.active\n\t\t}, this.options.position );\n\n\t\tclearTimeout( this.timer );\n\t\tthis.element.find( \".ui-menu\" ).not( submenu.parents( \".ui-menu\" ) )\n\t\t\t.hide()\n\t\t\t.attr( \"aria-hidden\", \"true\" );\n\n\t\tsubmenu\n\t\t\t.show()\n\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t.attr( \"aria-expanded\", \"true\" )\n\t\t\t.position( position );\n\t},\n\n\tcollapseAll: function( event, all ) {\n\t\tclearTimeout( this.timer );\n\t\tthis.timer = this._delay(function() {\n\t\t\t// If we were passed an event, look for the submenu that contains the event\n\t\t\tvar currentMenu = all ? this.element :\n\t\t\t\t$( event && event.target ).closest( this.element.find( \".ui-menu\" ) );\n\n\t\t\t// If we found no valid submenu ancestor, use the main menu to close all sub menus anyway\n\t\t\tif ( !currentMenu.length ) {\n\t\t\t\tcurrentMenu = this.element;\n\t\t\t}\n\n\t\t\tthis._close( currentMenu );\n\n\t\t\tthis.blur( event );\n\t\t\tthis.activeMenu = currentMenu;\n\t\t}, this.delay );\n\t},\n\n\t// With no arguments, closes the currently active menu - if nothing is active\n\t// it closes all menus.  If passed an argument, it will search for menus BELOW\n\t_close: function( startMenu ) {\n\t\tif ( !startMenu ) {\n\t\t\tstartMenu = this.active ? this.active.parent() : this.element;\n\t\t}\n\n\t\tstartMenu\n\t\t\t.find( \".ui-menu\" )\n\t\t\t\t.hide()\n\t\t\t\t.attr( \"aria-hidden\", \"true\" )\n\t\t\t\t.attr( \"aria-expanded\", \"false\" )\n\t\t\t.end()\n\t\t\t.find( \".ui-state-active\" ).not( \".ui-state-focus\" )\n\t\t\t\t.removeClass( \"ui-state-active\" );\n\t},\n\n\t_closeOnDocumentClick: function( event ) {\n\t\treturn !$( event.target ).closest( \".ui-menu\" ).length;\n\t},\n\n\t_isDivider: function( item ) {\n\n\t\t// Match hyphen, em dash, en dash\n\t\treturn !/[^\\-\\u2014\\u2013\\s]/.test( item.text() );\n\t},\n\n\tcollapse: function( event ) {\n\t\tvar newItem = this.active &&\n\t\t\tthis.active.parent().closest( \".ui-menu-item\", this.element );\n\t\tif ( newItem && newItem.length ) {\n\t\t\tthis._close();\n\t\t\tthis.focus( event, newItem );\n\t\t}\n\t},\n\n\texpand: function( event ) {\n\t\tvar newItem = this.active &&\n\t\t\tthis.active\n\t\t\t\t.children( \".ui-menu \" )\n\t\t\t\t.find( this.options.items )\n\t\t\t\t.first();\n\n\t\tif ( newItem && newItem.length ) {\n\t\t\tthis._open( newItem.parent() );\n\n\t\t\t// Delay so Firefox will not hide activedescendant change in expanding submenu from AT\n\t\t\tthis._delay(function() {\n\t\t\t\tthis.focus( event, newItem );\n\t\t\t});\n\t\t}\n\t},\n\n\tnext: function( event ) {\n\t\tthis._move( \"next\", \"first\", event );\n\t},\n\n\tprevious: function( event ) {\n\t\tthis._move( \"prev\", \"last\", event );\n\t},\n\n\tisFirstItem: function() {\n\t\treturn this.active && !this.active.prevAll( \".ui-menu-item\" ).length;\n\t},\n\n\tisLastItem: function() {\n\t\treturn this.active && !this.active.nextAll( \".ui-menu-item\" ).length;\n\t},\n\n\t_move: function( direction, filter, event ) {\n\t\tvar next;\n\t\tif ( this.active ) {\n\t\t\tif ( direction === \"first\" || direction === \"last\" ) {\n\t\t\t\tnext = this.active\n\t\t\t\t\t[ direction === \"first\" ? \"prevAll\" : \"nextAll\" ]( \".ui-menu-item\" )\n\t\t\t\t\t.eq( -1 );\n\t\t\t} else {\n\t\t\t\tnext = this.active\n\t\t\t\t\t[ direction + \"All\" ]( \".ui-menu-item\" )\n\t\t\t\t\t.eq( 0 );\n\t\t\t}\n\t\t}\n\t\tif ( !next || !next.length || !this.active ) {\n\t\t\tnext = this.activeMenu.find( this.options.items )[ filter ]();\n\t\t}\n\n\t\tthis.focus( event, next );\n\t},\n\n\tnextPage: function( event ) {\n\t\tvar item, base, height;\n\n\t\tif ( !this.active ) {\n\t\t\tthis.next( event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.isLastItem() ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( this._hasScroll() ) {\n\t\t\tbase = this.active.offset().top;\n\t\t\theight = this.element.height();\n\t\t\tthis.active.nextAll( \".ui-menu-item\" ).each(function() {\n\t\t\t\titem = $( this );\n\t\t\t\treturn item.offset().top - base - height < 0;\n\t\t\t});\n\n\t\t\tthis.focus( event, item );\n\t\t} else {\n\t\t\tthis.focus( event, this.activeMenu.find( this.options.items )\n\t\t\t\t[ !this.active ? \"first\" : \"last\" ]() );\n\t\t}\n\t},\n\n\tpreviousPage: function( event ) {\n\t\tvar item, base, height;\n\t\tif ( !this.active ) {\n\t\t\tthis.next( event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.isFirstItem() ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( this._hasScroll() ) {\n\t\t\tbase = this.active.offset().top;\n\t\t\theight = this.element.height();\n\t\t\tthis.active.prevAll( \".ui-menu-item\" ).each(function() {\n\t\t\t\titem = $( this );\n\t\t\t\treturn item.offset().top - base + height > 0;\n\t\t\t});\n\n\t\t\tthis.focus( event, item );\n\t\t} else {\n\t\t\tthis.focus( event, this.activeMenu.find( this.options.items ).first() );\n\t\t}\n\t},\n\n\t_hasScroll: function() {\n\t\treturn this.element.outerHeight() < this.element.prop( \"scrollHeight\" );\n\t},\n\n\tselect: function( event ) {\n\t\t// TODO: It should never be possible to not have an active item at this\n\t\t// point, but the tests don't trigger mouseenter before click.\n\t\tthis.active = this.active || $( event.target ).closest( \".ui-menu-item\" );\n\t\tvar ui = { item: this.active };\n\t\tif ( !this.active.has( \".ui-menu\" ).length ) {\n\t\t\tthis.collapseAll( event, true );\n\t\t}\n\t\tthis._trigger( \"select\", event, ui );\n\t},\n\n\t_filterMenuItems: function(character) {\n\t\tvar escapedCharacter = character.replace( /[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, \"\\\\$&\" ),\n\t\t\tregex = new RegExp( \"^\" + escapedCharacter, \"i\" );\n\n\t\treturn this.activeMenu\n\t\t\t.find( this.options.items )\n\n\t\t\t// Only match on items, not dividers or other content (#10571)\n\t\t\t.filter( \".ui-menu-item\" )\n\t\t\t.filter(function() {\n\t\t\t\treturn regex.test( $.trim( $( this ).text() ) );\n\t\t\t});\n\t}\n});\n\n\n/*!\n * jQuery UI Autocomplete 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/autocomplete/\n */\n\n\n$.widget( \"ui.autocomplete\", {\n\tversion: \"1.11.4\",\n\tdefaultElement: \"<input>\",\n\toptions: {\n\t\tappendTo: null,\n\t\tautoFocus: false,\n\t\tdelay: 300,\n\t\tminLength: 1,\n\t\tposition: {\n\t\t\tmy: \"left top\",\n\t\t\tat: \"left bottom\",\n\t\t\tcollision: \"none\"\n\t\t},\n\t\tsource: null,\n\n\t\t// callbacks\n\t\tchange: null,\n\t\tclose: null,\n\t\tfocus: null,\n\t\topen: null,\n\t\tresponse: null,\n\t\tsearch: null,\n\t\tselect: null\n\t},\n\n\trequestIndex: 0,\n\tpending: 0,\n\n\t_create: function() {\n\t\t// Some browsers only repeat keydown events, not keypress events,\n\t\t// so we use the suppressKeyPress flag to determine if we've already\n\t\t// handled the keydown event. #7269\n\t\t// Unfortunately the code for & in keypress is the same as the up arrow,\n\t\t// so we use the suppressKeyPressRepeat flag to avoid handling keypress\n\t\t// events when we know the keydown event was used to modify the\n\t\t// search term. #7799\n\t\tvar suppressKeyPress, suppressKeyPressRepeat, suppressInput,\n\t\t\tnodeName = this.element[ 0 ].nodeName.toLowerCase(),\n\t\t\tisTextarea = nodeName === \"textarea\",\n\t\t\tisInput = nodeName === \"input\";\n\n\t\tthis.isMultiLine =\n\t\t\t// Textareas are always multi-line\n\t\t\tisTextarea ? true :\n\t\t\t// Inputs are always single-line, even if inside a contentEditable element\n\t\t\t// IE also treats inputs as contentEditable\n\t\t\tisInput ? false :\n\t\t\t// All other element types are determined by whether or not they're contentEditable\n\t\t\tthis.element.prop( \"isContentEditable\" );\n\n\t\tthis.valueMethod = this.element[ isTextarea || isInput ? \"val\" : \"text\" ];\n\t\tthis.isNewMenu = true;\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-autocomplete-input\" )\n\t\t\t.attr( \"autocomplete\", \"off\" );\n\n\t\tthis._on( this.element, {\n\t\t\tkeydown: function( event ) {\n\t\t\t\tif ( this.element.prop( \"readOnly\" ) ) {\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tsuppressInput = true;\n\t\t\t\t\tsuppressKeyPressRepeat = true;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tsuppressKeyPress = false;\n\t\t\t\tsuppressInput = false;\n\t\t\t\tsuppressKeyPressRepeat = false;\n\t\t\t\tvar keyCode = $.ui.keyCode;\n\t\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase keyCode.PAGE_UP:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._move( \"previousPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.PAGE_DOWN:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._move( \"nextPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.UP:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._keyEvent( \"previous\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.DOWN:\n\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\tthis._keyEvent( \"next\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.ENTER:\n\t\t\t\t\t// when menu is open and has focus\n\t\t\t\t\tif ( this.menu.active ) {\n\t\t\t\t\t\t// #6055 - Opera still allows the keypress to occur\n\t\t\t\t\t\t// which causes forms to submit\n\t\t\t\t\t\tsuppressKeyPress = true;\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tthis.menu.select( event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.TAB:\n\t\t\t\t\tif ( this.menu.active ) {\n\t\t\t\t\t\tthis.menu.select( event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.ESCAPE:\n\t\t\t\t\tif ( this.menu.element.is( \":visible\" ) ) {\n\t\t\t\t\t\tif ( !this.isMultiLine ) {\n\t\t\t\t\t\t\tthis._value( this.term );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tthis.close( event );\n\t\t\t\t\t\t// Different browsers have different default behavior for escape\n\t\t\t\t\t\t// Single press can mean undo or clear\n\t\t\t\t\t\t// Double press in IE means clear the whole form\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tsuppressKeyPressRepeat = true;\n\t\t\t\t\t// search timeout should be triggered before the input value is changed\n\t\t\t\t\tthis._searchTimeout( event );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t\tkeypress: function( event ) {\n\t\t\t\tif ( suppressKeyPress ) {\n\t\t\t\t\tsuppressKeyPress = false;\n\t\t\t\t\tif ( !this.isMultiLine || this.menu.element.is( \":visible\" ) ) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( suppressKeyPressRepeat ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// replicate some key handlers to allow them to repeat in Firefox and Opera\n\t\t\t\tvar keyCode = $.ui.keyCode;\n\t\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase keyCode.PAGE_UP:\n\t\t\t\t\tthis._move( \"previousPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.PAGE_DOWN:\n\t\t\t\t\tthis._move( \"nextPage\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.UP:\n\t\t\t\t\tthis._keyEvent( \"previous\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase keyCode.DOWN:\n\t\t\t\t\tthis._keyEvent( \"next\", event );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t},\n\t\t\tinput: function( event ) {\n\t\t\t\tif ( suppressInput ) {\n\t\t\t\t\tsuppressInput = false;\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tthis._searchTimeout( event );\n\t\t\t},\n\t\t\tfocus: function() {\n\t\t\t\tthis.selectedItem = null;\n\t\t\t\tthis.previous = this._value();\n\t\t\t},\n\t\t\tblur: function( event ) {\n\t\t\t\tif ( this.cancelBlur ) {\n\t\t\t\t\tdelete this.cancelBlur;\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tclearTimeout( this.searching );\n\t\t\t\tthis.close( event );\n\t\t\t\tthis._change( event );\n\t\t\t}\n\t\t});\n\n\t\tthis._initSource();\n\t\tthis.menu = $( \"<ul>\" )\n\t\t\t.addClass( \"ui-autocomplete ui-front\" )\n\t\t\t.appendTo( this._appendTo() )\n\t\t\t.menu({\n\t\t\t\t// disable ARIA support, the live region takes care of that\n\t\t\t\trole: null\n\t\t\t})\n\t\t\t.hide()\n\t\t\t.menu( \"instance\" );\n\n\t\tthis._on( this.menu.element, {\n\t\t\tmousedown: function( event ) {\n\t\t\t\t// prevent moving focus out of the text field\n\t\t\t\tevent.preventDefault();\n\n\t\t\t\t// IE doesn't prevent moving focus even with event.preventDefault()\n\t\t\t\t// so we set a flag to know when we should ignore the blur event\n\t\t\t\tthis.cancelBlur = true;\n\t\t\t\tthis._delay(function() {\n\t\t\t\t\tdelete this.cancelBlur;\n\t\t\t\t});\n\n\t\t\t\t// clicking on the scrollbar causes focus to shift to the body\n\t\t\t\t// but we can't detect a mouseup or a click immediately afterward\n\t\t\t\t// so we have to track the next mousedown and close the menu if\n\t\t\t\t// the user clicks somewhere outside of the autocomplete\n\t\t\t\tvar menuElement = this.menu.element[ 0 ];\n\t\t\t\tif ( !$( event.target ).closest( \".ui-menu-item\" ).length ) {\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tvar that = this;\n\t\t\t\t\t\tthis.document.one( \"mousedown\", function( event ) {\n\t\t\t\t\t\t\tif ( event.target !== that.element[ 0 ] &&\n\t\t\t\t\t\t\t\t\tevent.target !== menuElement &&\n\t\t\t\t\t\t\t\t\t!$.contains( menuElement, event.target ) ) {\n\t\t\t\t\t\t\t\tthat.close();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t},\n\t\t\tmenufocus: function( event, ui ) {\n\t\t\t\tvar label, item;\n\t\t\t\t// support: Firefox\n\t\t\t\t// Prevent accidental activation of menu items in Firefox (#7024 #9118)\n\t\t\t\tif ( this.isNewMenu ) {\n\t\t\t\t\tthis.isNewMenu = false;\n\t\t\t\t\tif ( event.originalEvent && /^mouse/.test( event.originalEvent.type ) ) {\n\t\t\t\t\t\tthis.menu.blur();\n\n\t\t\t\t\t\tthis.document.one( \"mousemove\", function() {\n\t\t\t\t\t\t\t$( event.target ).trigger( event.originalEvent );\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\titem = ui.item.data( \"ui-autocomplete-item\" );\n\t\t\t\tif ( false !== this._trigger( \"focus\", event, { item: item } ) ) {\n\t\t\t\t\t// use value to match what will end up in the input, if it was a key event\n\t\t\t\t\tif ( event.originalEvent && /^key/.test( event.originalEvent.type ) ) {\n\t\t\t\t\t\tthis._value( item.value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Announce the value in the liveRegion\n\t\t\t\tlabel = ui.item.attr( \"aria-label\" ) || item.value;\n\t\t\t\tif ( label && $.trim( label ).length ) {\n\t\t\t\t\tthis.liveRegion.children().hide();\n\t\t\t\t\t$( \"<div>\" ).text( label ).appendTo( this.liveRegion );\n\t\t\t\t}\n\t\t\t},\n\t\t\tmenuselect: function( event, ui ) {\n\t\t\t\tvar item = ui.item.data( \"ui-autocomplete-item\" ),\n\t\t\t\t\tprevious = this.previous;\n\n\t\t\t\t// only trigger when focus was lost (click on menu)\n\t\t\t\tif ( this.element[ 0 ] !== this.document[ 0 ].activeElement ) {\n\t\t\t\t\tthis.element.focus();\n\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t// #6109 - IE triggers two focus events and the second\n\t\t\t\t\t// is asynchronous, so we need to reset the previous\n\t\t\t\t\t// term synchronously and asynchronously :-(\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t\tthis.selectedItem = item;\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\tif ( false !== this._trigger( \"select\", event, { item: item } ) ) {\n\t\t\t\t\tthis._value( item.value );\n\t\t\t\t}\n\t\t\t\t// reset the term after the select event\n\t\t\t\t// this allows custom select handling to work properly\n\t\t\t\tthis.term = this._value();\n\n\t\t\t\tthis.close( event );\n\t\t\t\tthis.selectedItem = item;\n\t\t\t}\n\t\t});\n\n\t\tthis.liveRegion = $( \"<span>\", {\n\t\t\t\trole: \"status\",\n\t\t\t\t\"aria-live\": \"assertive\",\n\t\t\t\t\"aria-relevant\": \"additions\"\n\t\t\t})\n\t\t\t.addClass( \"ui-helper-hidden-accessible\" )\n\t\t\t.appendTo( this.document[ 0 ].body );\n\n\t\t// turning off autocomplete prevents the browser from remembering the\n\t\t// value when navigating through history, so we re-enable autocomplete\n\t\t// if the page is unloaded before the widget is destroyed. #7790\n\t\tthis._on( this.window, {\n\t\t\tbeforeunload: function() {\n\t\t\t\tthis.element.removeAttr( \"autocomplete\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_destroy: function() {\n\t\tclearTimeout( this.searching );\n\t\tthis.element\n\t\t\t.removeClass( \"ui-autocomplete-input\" )\n\t\t\t.removeAttr( \"autocomplete\" );\n\t\tthis.menu.element.remove();\n\t\tthis.liveRegion.remove();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tthis._super( key, value );\n\t\tif ( key === \"source\" ) {\n\t\t\tthis._initSource();\n\t\t}\n\t\tif ( key === \"appendTo\" ) {\n\t\t\tthis.menu.element.appendTo( this._appendTo() );\n\t\t}\n\t\tif ( key === \"disabled\" && value && this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\t},\n\n\t_appendTo: function() {\n\t\tvar element = this.options.appendTo;\n\n\t\tif ( element ) {\n\t\t\telement = element.jquery || element.nodeType ?\n\t\t\t\t$( element ) :\n\t\t\t\tthis.document.find( element ).eq( 0 );\n\t\t}\n\n\t\tif ( !element || !element[ 0 ] ) {\n\t\t\telement = this.element.closest( \".ui-front\" );\n\t\t}\n\n\t\tif ( !element.length ) {\n\t\t\telement = this.document[ 0 ].body;\n\t\t}\n\n\t\treturn element;\n\t},\n\n\t_initSource: function() {\n\t\tvar array, url,\n\t\t\tthat = this;\n\t\tif ( $.isArray( this.options.source ) ) {\n\t\t\tarray = this.options.source;\n\t\t\tthis.source = function( request, response ) {\n\t\t\t\tresponse( $.ui.autocomplete.filter( array, request.term ) );\n\t\t\t};\n\t\t} else if ( typeof this.options.source === \"string\" ) {\n\t\t\turl = this.options.source;\n\t\t\tthis.source = function( request, response ) {\n\t\t\t\tif ( that.xhr ) {\n\t\t\t\t\tthat.xhr.abort();\n\t\t\t\t}\n\t\t\t\tthat.xhr = $.ajax({\n\t\t\t\t\turl: url,\n\t\t\t\t\tdata: request,\n\t\t\t\t\tdataType: \"json\",\n\t\t\t\t\tsuccess: function( data ) {\n\t\t\t\t\t\tresponse( data );\n\t\t\t\t\t},\n\t\t\t\t\terror: function() {\n\t\t\t\t\t\tresponse([]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t};\n\t\t} else {\n\t\t\tthis.source = this.options.source;\n\t\t}\n\t},\n\n\t_searchTimeout: function( event ) {\n\t\tclearTimeout( this.searching );\n\t\tthis.searching = this._delay(function() {\n\n\t\t\t// Search if the value has changed, or if the user retypes the same value (see #7434)\n\t\t\tvar equalValues = this.term === this._value(),\n\t\t\t\tmenuVisible = this.menu.element.is( \":visible\" ),\n\t\t\t\tmodifierKey = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey;\n\n\t\t\tif ( !equalValues || ( equalValues && !menuVisible && !modifierKey ) ) {\n\t\t\t\tthis.selectedItem = null;\n\t\t\t\tthis.search( null, event );\n\t\t\t}\n\t\t}, this.options.delay );\n\t},\n\n\tsearch: function( value, event ) {\n\t\tvalue = value != null ? value : this._value();\n\n\t\t// always save the actual value, not the one passed as an argument\n\t\tthis.term = this._value();\n\n\t\tif ( value.length < this.options.minLength ) {\n\t\t\treturn this.close( event );\n\t\t}\n\n\t\tif ( this._trigger( \"search\", event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\treturn this._search( value );\n\t},\n\n\t_search: function( value ) {\n\t\tthis.pending++;\n\t\tthis.element.addClass( \"ui-autocomplete-loading\" );\n\t\tthis.cancelSearch = false;\n\n\t\tthis.source( { term: value }, this._response() );\n\t},\n\n\t_response: function() {\n\t\tvar index = ++this.requestIndex;\n\n\t\treturn $.proxy(function( content ) {\n\t\t\tif ( index === this.requestIndex ) {\n\t\t\t\tthis.__response( content );\n\t\t\t}\n\n\t\t\tthis.pending--;\n\t\t\tif ( !this.pending ) {\n\t\t\t\tthis.element.removeClass( \"ui-autocomplete-loading\" );\n\t\t\t}\n\t\t}, this );\n\t},\n\n\t__response: function( content ) {\n\t\tif ( content ) {\n\t\t\tcontent = this._normalize( content );\n\t\t}\n\t\tthis._trigger( \"response\", null, { content: content } );\n\t\tif ( !this.options.disabled && content && content.length && !this.cancelSearch ) {\n\t\t\tthis._suggest( content );\n\t\t\tthis._trigger( \"open\" );\n\t\t} else {\n\t\t\t// use ._close() instead of .close() so we don't cancel future searches\n\t\t\tthis._close();\n\t\t}\n\t},\n\n\tclose: function( event ) {\n\t\tthis.cancelSearch = true;\n\t\tthis._close( event );\n\t},\n\n\t_close: function( event ) {\n\t\tif ( this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis.menu.element.hide();\n\t\t\tthis.menu.blur();\n\t\t\tthis.isNewMenu = true;\n\t\t\tthis._trigger( \"close\", event );\n\t\t}\n\t},\n\n\t_change: function( event ) {\n\t\tif ( this.previous !== this._value() ) {\n\t\t\tthis._trigger( \"change\", event, { item: this.selectedItem } );\n\t\t}\n\t},\n\n\t_normalize: function( items ) {\n\t\t// assume all items have the right format when the first item is complete\n\t\tif ( items.length && items[ 0 ].label && items[ 0 ].value ) {\n\t\t\treturn items;\n\t\t}\n\t\treturn $.map( items, function( item ) {\n\t\t\tif ( typeof item === \"string\" ) {\n\t\t\t\treturn {\n\t\t\t\t\tlabel: item,\n\t\t\t\t\tvalue: item\n\t\t\t\t};\n\t\t\t}\n\t\t\treturn $.extend( {}, item, {\n\t\t\t\tlabel: item.label || item.value,\n\t\t\t\tvalue: item.value || item.label\n\t\t\t});\n\t\t});\n\t},\n\n\t_suggest: function( items ) {\n\t\tvar ul = this.menu.element.empty();\n\t\tthis._renderMenu( ul, items );\n\t\tthis.isNewMenu = true;\n\t\tthis.menu.refresh();\n\n\t\t// size and position menu\n\t\tul.show();\n\t\tthis._resizeMenu();\n\t\tul.position( $.extend({\n\t\t\tof: this.element\n\t\t}, this.options.position ) );\n\n\t\tif ( this.options.autoFocus ) {\n\t\t\tthis.menu.next();\n\t\t}\n\t},\n\n\t_resizeMenu: function() {\n\t\tvar ul = this.menu.element;\n\t\tul.outerWidth( Math.max(\n\t\t\t// Firefox wraps long text (possibly a rounding bug)\n\t\t\t// so we add 1px to avoid the wrapping (#7513)\n\t\t\tul.width( \"\" ).outerWidth() + 1,\n\t\t\tthis.element.outerWidth()\n\t\t) );\n\t},\n\n\t_renderMenu: function( ul, items ) {\n\t\tvar that = this;\n\t\t$.each( items, function( index, item ) {\n\t\t\tthat._renderItemData( ul, item );\n\t\t});\n\t},\n\n\t_renderItemData: function( ul, item ) {\n\t\treturn this._renderItem( ul, item ).data( \"ui-autocomplete-item\", item );\n\t},\n\n\t_renderItem: function( ul, item ) {\n\t\treturn $( \"<li>\" ).text( item.label ).appendTo( ul );\n\t},\n\n\t_move: function( direction, event ) {\n\t\tif ( !this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis.search( null, event );\n\t\t\treturn;\n\t\t}\n\t\tif ( this.menu.isFirstItem() && /^previous/.test( direction ) ||\n\t\t\t\tthis.menu.isLastItem() && /^next/.test( direction ) ) {\n\n\t\t\tif ( !this.isMultiLine ) {\n\t\t\t\tthis._value( this.term );\n\t\t\t}\n\n\t\t\tthis.menu.blur();\n\t\t\treturn;\n\t\t}\n\t\tthis.menu[ direction ]( event );\n\t},\n\n\twidget: function() {\n\t\treturn this.menu.element;\n\t},\n\n\t_value: function() {\n\t\treturn this.valueMethod.apply( this.element, arguments );\n\t},\n\n\t_keyEvent: function( keyEvent, event ) {\n\t\tif ( !this.isMultiLine || this.menu.element.is( \":visible\" ) ) {\n\t\t\tthis._move( keyEvent, event );\n\n\t\t\t// prevents moving cursor to beginning/end of the text field in some browsers\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n});\n\n$.extend( $.ui.autocomplete, {\n\tescapeRegex: function( value ) {\n\t\treturn value.replace( /[\\-\\[\\]{}()*+?.,\\\\\\^$|#\\s]/g, \"\\\\$&\" );\n\t},\n\tfilter: function( array, term ) {\n\t\tvar matcher = new RegExp( $.ui.autocomplete.escapeRegex( term ), \"i\" );\n\t\treturn $.grep( array, function( value ) {\n\t\t\treturn matcher.test( value.label || value.value || value );\n\t\t});\n\t}\n});\n\n// live region extension, adding a `messages` option\n// NOTE: This is an experimental API. We are still investigating\n// a full solution for string manipulation and internationalization.\n$.widget( \"ui.autocomplete\", $.ui.autocomplete, {\n\toptions: {\n\t\tmessages: {\n\t\t\tnoResults: \"No search results.\",\n\t\t\tresults: function( amount ) {\n\t\t\t\treturn amount + ( amount > 1 ? \" results are\" : \" result is\" ) +\n\t\t\t\t\t\" available, use up and down arrow keys to navigate.\";\n\t\t\t}\n\t\t}\n\t},\n\n\t__response: function( content ) {\n\t\tvar message;\n\t\tthis._superApply( arguments );\n\t\tif ( this.options.disabled || this.cancelSearch ) {\n\t\t\treturn;\n\t\t}\n\t\tif ( content && content.length ) {\n\t\t\tmessage = this.options.messages.results( content.length );\n\t\t} else {\n\t\t\tmessage = this.options.messages.noResults;\n\t\t}\n\t\tthis.liveRegion.children().hide();\n\t\t$( \"<div>\" ).text( message ).appendTo( this.liveRegion );\n\t}\n});\n\nvar autocomplete = $.ui.autocomplete;\n\n\n/*!\n * jQuery UI Button 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/button/\n */\n\n\nvar lastActive,\n\tbaseClasses = \"ui-button ui-widget ui-state-default ui-corner-all\",\n\ttypeClasses = \"ui-button-icons-only ui-button-icon-only ui-button-text-icons ui-button-text-icon-primary ui-button-text-icon-secondary ui-button-text-only\",\n\tformResetHandler = function() {\n\t\tvar form = $( this );\n\t\tsetTimeout(function() {\n\t\t\tform.find( \":ui-button\" ).button( \"refresh\" );\n\t\t}, 1 );\n\t},\n\tradioGroup = function( radio ) {\n\t\tvar name = radio.name,\n\t\t\tform = radio.form,\n\t\t\tradios = $( [] );\n\t\tif ( name ) {\n\t\t\tname = name.replace( /'/g, \"\\\\'\" );\n\t\t\tif ( form ) {\n\t\t\t\tradios = $( form ).find( \"[name='\" + name + \"'][type=radio]\" );\n\t\t\t} else {\n\t\t\t\tradios = $( \"[name='\" + name + \"'][type=radio]\", radio.ownerDocument )\n\t\t\t\t\t.filter(function() {\n\t\t\t\t\t\treturn !this.form;\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\treturn radios;\n\t};\n\n$.widget( \"ui.button\", {\n\tversion: \"1.11.4\",\n\tdefaultElement: \"<button>\",\n\toptions: {\n\t\tdisabled: null,\n\t\ttext: true,\n\t\tlabel: null,\n\t\ticons: {\n\t\t\tprimary: null,\n\t\t\tsecondary: null\n\t\t}\n\t},\n\t_create: function() {\n\t\tthis.element.closest( \"form\" )\n\t\t\t.unbind( \"reset\" + this.eventNamespace )\n\t\t\t.bind( \"reset\" + this.eventNamespace, formResetHandler );\n\n\t\tif ( typeof this.options.disabled !== \"boolean\" ) {\n\t\t\tthis.options.disabled = !!this.element.prop( \"disabled\" );\n\t\t} else {\n\t\t\tthis.element.prop( \"disabled\", this.options.disabled );\n\t\t}\n\n\t\tthis._determineButtonType();\n\t\tthis.hasTitle = !!this.buttonElement.attr( \"title\" );\n\n\t\tvar that = this,\n\t\t\toptions = this.options,\n\t\t\ttoggleButton = this.type === \"checkbox\" || this.type === \"radio\",\n\t\t\tactiveClass = !toggleButton ? \"ui-state-active\" : \"\";\n\n\t\tif ( options.label === null ) {\n\t\t\toptions.label = (this.type === \"input\" ? this.buttonElement.val() : this.buttonElement.html());\n\t\t}\n\n\t\tthis._hoverable( this.buttonElement );\n\n\t\tthis.buttonElement\n\t\t\t.addClass( baseClasses )\n\t\t\t.attr( \"role\", \"button\" )\n\t\t\t.bind( \"mouseenter\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tif ( this === lastActive ) {\n\t\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\t}\n\t\t\t})\n\t\t\t.bind( \"mouseleave\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\t$( this ).removeClass( activeClass );\n\t\t\t})\n\t\t\t.bind( \"click\" + this.eventNamespace, function( event ) {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tevent.stopImmediatePropagation();\n\t\t\t\t}\n\t\t\t});\n\n\t\t// Can't use _focusable() because the element that receives focus\n\t\t// and the element that gets the ui-state-focus class are different\n\t\tthis._on({\n\t\t\tfocus: function() {\n\t\t\t\tthis.buttonElement.addClass( \"ui-state-focus\" );\n\t\t\t},\n\t\t\tblur: function() {\n\t\t\t\tthis.buttonElement.removeClass( \"ui-state-focus\" );\n\t\t\t}\n\t\t});\n\n\t\tif ( toggleButton ) {\n\t\t\tthis.element.bind( \"change\" + this.eventNamespace, function() {\n\t\t\t\tthat.refresh();\n\t\t\t});\n\t\t}\n\n\t\tif ( this.type === \"checkbox\" ) {\n\t\t\tthis.buttonElement.bind( \"click\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t});\n\t\t} else if ( this.type === \"radio\" ) {\n\t\t\tthis.buttonElement.bind( \"click\" + this.eventNamespace, function() {\n\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\tthat.buttonElement.attr( \"aria-pressed\", \"true\" );\n\n\t\t\t\tvar radio = that.element[ 0 ];\n\t\t\t\tradioGroup( radio )\n\t\t\t\t\t.not( radio )\n\t\t\t\t\t.map(function() {\n\t\t\t\t\t\treturn $( this ).button( \"widget\" )[ 0 ];\n\t\t\t\t\t})\n\t\t\t\t\t.removeClass( \"ui-state-active\" )\n\t\t\t\t\t.attr( \"aria-pressed\", \"false\" );\n\t\t\t});\n\t\t} else {\n\t\t\tthis.buttonElement\n\t\t\t\t.bind( \"mousedown\" + this.eventNamespace, function() {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\t\tlastActive = this;\n\t\t\t\t\tthat.document.one( \"mouseup\", function() {\n\t\t\t\t\t\tlastActive = null;\n\t\t\t\t\t});\n\t\t\t\t})\n\t\t\t\t.bind( \"mouseup\" + this.eventNamespace, function() {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\t$( this ).removeClass( \"ui-state-active\" );\n\t\t\t\t})\n\t\t\t\t.bind( \"keydown\" + this.eventNamespace, function(event) {\n\t\t\t\t\tif ( options.disabled ) {\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t\tif ( event.keyCode === $.ui.keyCode.SPACE || event.keyCode === $.ui.keyCode.ENTER ) {\n\t\t\t\t\t\t$( this ).addClass( \"ui-state-active\" );\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\t// see #8559, we bind to blur here in case the button element loses\n\t\t\t\t// focus between keydown and keyup, it would be left in an \"active\" state\n\t\t\t\t.bind( \"keyup\" + this.eventNamespace + \" blur\" + this.eventNamespace, function() {\n\t\t\t\t\t$( this ).removeClass( \"ui-state-active\" );\n\t\t\t\t});\n\n\t\t\tif ( this.buttonElement.is(\"a\") ) {\n\t\t\t\tthis.buttonElement.keyup(function(event) {\n\t\t\t\t\tif ( event.keyCode === $.ui.keyCode.SPACE ) {\n\t\t\t\t\t\t// TODO pass through original event correctly (just as 2nd argument doesn't work)\n\t\t\t\t\t\t$( this ).click();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tthis._setOption( \"disabled\", options.disabled );\n\t\tthis._resetButton();\n\t},\n\n\t_determineButtonType: function() {\n\t\tvar ancestor, labelSelector, checked;\n\n\t\tif ( this.element.is(\"[type=checkbox]\") ) {\n\t\t\tthis.type = \"checkbox\";\n\t\t} else if ( this.element.is(\"[type=radio]\") ) {\n\t\t\tthis.type = \"radio\";\n\t\t} else if ( this.element.is(\"input\") ) {\n\t\t\tthis.type = \"input\";\n\t\t} else {\n\t\t\tthis.type = \"button\";\n\t\t}\n\n\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t// we don't search against the document in case the element\n\t\t\t// is disconnected from the DOM\n\t\t\tancestor = this.element.parents().last();\n\t\t\tlabelSelector = \"label[for='\" + this.element.attr(\"id\") + \"']\";\n\t\t\tthis.buttonElement = ancestor.find( labelSelector );\n\t\t\tif ( !this.buttonElement.length ) {\n\t\t\t\tancestor = ancestor.length ? ancestor.siblings() : this.element.siblings();\n\t\t\t\tthis.buttonElement = ancestor.filter( labelSelector );\n\t\t\t\tif ( !this.buttonElement.length ) {\n\t\t\t\t\tthis.buttonElement = ancestor.find( labelSelector );\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.element.addClass( \"ui-helper-hidden-accessible\" );\n\n\t\t\tchecked = this.element.is( \":checked\" );\n\t\t\tif ( checked ) {\n\t\t\t\tthis.buttonElement.addClass( \"ui-state-active\" );\n\t\t\t}\n\t\t\tthis.buttonElement.prop( \"aria-pressed\", checked );\n\t\t} else {\n\t\t\tthis.buttonElement = this.element;\n\t\t}\n\t},\n\n\twidget: function() {\n\t\treturn this.buttonElement;\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass( \"ui-helper-hidden-accessible\" );\n\t\tthis.buttonElement\n\t\t\t.removeClass( baseClasses + \" ui-state-active \" + typeClasses )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-pressed\" )\n\t\t\t.html( this.buttonElement.find(\".ui-button-text\").html() );\n\n\t\tif ( !this.hasTitle ) {\n\t\t\tthis.buttonElement.removeAttr( \"title\" );\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tthis._super( key, value );\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.widget().toggleClass( \"ui-state-disabled\", !!value );\n\t\t\tthis.element.prop( \"disabled\", !!value );\n\t\t\tif ( value ) {\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tthis.buttonElement.removeClass( \"ui-state-focus\" );\n\t\t\t\t} else {\n\t\t\t\t\tthis.buttonElement.removeClass( \"ui-state-focus ui-state-active\" );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tthis._resetButton();\n\t},\n\n\trefresh: function() {\n\t\t//See #8237 & #8828\n\t\tvar isDisabled = this.element.is( \"input, button\" ) ? this.element.is( \":disabled\" ) : this.element.hasClass( \"ui-button-disabled\" );\n\n\t\tif ( isDisabled !== this.options.disabled ) {\n\t\t\tthis._setOption( \"disabled\", isDisabled );\n\t\t}\n\t\tif ( this.type === \"radio\" ) {\n\t\t\tradioGroup( this.element[0] ).each(function() {\n\t\t\t\tif ( $( this ).is( \":checked\" ) ) {\n\t\t\t\t\t$( this ).button( \"widget\" )\n\t\t\t\t\t\t.addClass( \"ui-state-active\" )\n\t\t\t\t\t\t.attr( \"aria-pressed\", \"true\" );\n\t\t\t\t} else {\n\t\t\t\t\t$( this ).button( \"widget\" )\n\t\t\t\t\t\t.removeClass( \"ui-state-active\" )\n\t\t\t\t\t\t.attr( \"aria-pressed\", \"false\" );\n\t\t\t\t}\n\t\t\t});\n\t\t} else if ( this.type === \"checkbox\" ) {\n\t\t\tif ( this.element.is( \":checked\" ) ) {\n\t\t\t\tthis.buttonElement\n\t\t\t\t\t.addClass( \"ui-state-active\" )\n\t\t\t\t\t.attr( \"aria-pressed\", \"true\" );\n\t\t\t} else {\n\t\t\t\tthis.buttonElement\n\t\t\t\t\t.removeClass( \"ui-state-active\" )\n\t\t\t\t\t.attr( \"aria-pressed\", \"false\" );\n\t\t\t}\n\t\t}\n\t},\n\n\t_resetButton: function() {\n\t\tif ( this.type === \"input\" ) {\n\t\t\tif ( this.options.label ) {\n\t\t\t\tthis.element.val( this.options.label );\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\t\tvar buttonElement = this.buttonElement.removeClass( typeClasses ),\n\t\t\tbuttonText = $( \"<span></span>\", this.document[0] )\n\t\t\t\t.addClass( \"ui-button-text\" )\n\t\t\t\t.html( this.options.label )\n\t\t\t\t.appendTo( buttonElement.empty() )\n\t\t\t\t.text(),\n\t\t\ticons = this.options.icons,\n\t\t\tmultipleIcons = icons.primary && icons.secondary,\n\t\t\tbuttonClasses = [];\n\n\t\tif ( icons.primary || icons.secondary ) {\n\t\t\tif ( this.options.text ) {\n\t\t\t\tbuttonClasses.push( \"ui-button-text-icon\" + ( multipleIcons ? \"s\" : ( icons.primary ? \"-primary\" : \"-secondary\" ) ) );\n\t\t\t}\n\n\t\t\tif ( icons.primary ) {\n\t\t\t\tbuttonElement.prepend( \"<span class='ui-button-icon-primary ui-icon \" + icons.primary + \"'></span>\" );\n\t\t\t}\n\n\t\t\tif ( icons.secondary ) {\n\t\t\t\tbuttonElement.append( \"<span class='ui-button-icon-secondary ui-icon \" + icons.secondary + \"'></span>\" );\n\t\t\t}\n\n\t\t\tif ( !this.options.text ) {\n\t\t\t\tbuttonClasses.push( multipleIcons ? \"ui-button-icons-only\" : \"ui-button-icon-only\" );\n\n\t\t\t\tif ( !this.hasTitle ) {\n\t\t\t\t\tbuttonElement.attr( \"title\", $.trim( buttonText ) );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tbuttonClasses.push( \"ui-button-text-only\" );\n\t\t}\n\t\tbuttonElement.addClass( buttonClasses.join( \" \" ) );\n\t}\n});\n\n$.widget( \"ui.buttonset\", {\n\tversion: \"1.11.4\",\n\toptions: {\n\t\titems: \"button, input[type=button], input[type=submit], input[type=reset], input[type=checkbox], input[type=radio], a, :data(ui-button)\"\n\t},\n\n\t_create: function() {\n\t\tthis.element.addClass( \"ui-buttonset\" );\n\t},\n\n\t_init: function() {\n\t\tthis.refresh();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.buttons.button( \"option\", key, value );\n\t\t}\n\n\t\tthis._super( key, value );\n\t},\n\n\trefresh: function() {\n\t\tvar rtl = this.element.css( \"direction\" ) === \"rtl\",\n\t\t\tallButtons = this.element.find( this.options.items ),\n\t\t\texistingButtons = allButtons.filter( \":ui-button\" );\n\n\t\t// Initialize new buttons\n\t\tallButtons.not( \":ui-button\" ).button();\n\n\t\t// Refresh existing buttons\n\t\texistingButtons.button( \"refresh\" );\n\n\t\tthis.buttons = allButtons\n\t\t\t.map(function() {\n\t\t\t\treturn $( this ).button( \"widget\" )[ 0 ];\n\t\t\t})\n\t\t\t\t.removeClass( \"ui-corner-all ui-corner-left ui-corner-right\" )\n\t\t\t\t.filter( \":first\" )\n\t\t\t\t\t.addClass( rtl ? \"ui-corner-right\" : \"ui-corner-left\" )\n\t\t\t\t.end()\n\t\t\t\t.filter( \":last\" )\n\t\t\t\t\t.addClass( rtl ? \"ui-corner-left\" : \"ui-corner-right\" )\n\t\t\t\t.end()\n\t\t\t.end();\n\t},\n\n\t_destroy: function() {\n\t\tthis.element.removeClass( \"ui-buttonset\" );\n\t\tthis.buttons\n\t\t\t.map(function() {\n\t\t\t\treturn $( this ).button( \"widget\" )[ 0 ];\n\t\t\t})\n\t\t\t\t.removeClass( \"ui-corner-left ui-corner-right\" )\n\t\t\t.end()\n\t\t\t.button( \"destroy\" );\n\t}\n});\n\nvar button = $.ui.button;\n\n\n/*!\n * jQuery UI Datepicker 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/datepicker/\n */\n\n\n$.extend($.ui, { datepicker: { version: \"1.11.4\" } });\n\nvar datepicker_instActive;\n\nfunction datepicker_getZindex( elem ) {\n\tvar position, value;\n\twhile ( elem.length && elem[ 0 ] !== document ) {\n\t\t// Ignore z-index if position is set to a value where z-index is ignored by the browser\n\t\t// This makes behavior of this function consistent across browsers\n\t\t// WebKit always returns auto if the element is positioned\n\t\tposition = elem.css( \"position\" );\n\t\tif ( position === \"absolute\" || position === \"relative\" || position === \"fixed\" ) {\n\t\t\t// IE returns 0 when zIndex is not specified\n\t\t\t// other browsers return a string\n\t\t\t// we ignore the case of nested elements with an explicit value of 0\n\t\t\t// <div style=\"z-index: -10;\"><div style=\"z-index: 0;\"></div></div>\n\t\t\tvalue = parseInt( elem.css( \"zIndex\" ), 10 );\n\t\t\tif ( !isNaN( value ) && value !== 0 ) {\n\t\t\t\treturn value;\n\t\t\t}\n\t\t}\n\t\telem = elem.parent();\n\t}\n\n\treturn 0;\n}\n/* Date picker manager.\n   Use the singleton instance of this class, $.datepicker, to interact with the date picker.\n   Settings for (groups of) date pickers are maintained in an instance object,\n   allowing multiple different settings on the same page. */\n\nfunction Datepicker() {\n\tthis._curInst = null; // The current instance in use\n\tthis._keyEvent = false; // If the last event was a key event\n\tthis._disabledInputs = []; // List of date picker inputs that have been disabled\n\tthis._datepickerShowing = false; // True if the popup picker is showing , false if not\n\tthis._inDialog = false; // True if showing within a \"dialog\", false if not\n\tthis._mainDivId = \"ui-datepicker-div\"; // The ID of the main datepicker division\n\tthis._inlineClass = \"ui-datepicker-inline\"; // The name of the inline marker class\n\tthis._appendClass = \"ui-datepicker-append\"; // The name of the append marker class\n\tthis._triggerClass = \"ui-datepicker-trigger\"; // The name of the trigger marker class\n\tthis._dialogClass = \"ui-datepicker-dialog\"; // The name of the dialog marker class\n\tthis._disableClass = \"ui-datepicker-disabled\"; // The name of the disabled covering marker class\n\tthis._unselectableClass = \"ui-datepicker-unselectable\"; // The name of the unselectable cell marker class\n\tthis._currentClass = \"ui-datepicker-current-day\"; // The name of the current day marker class\n\tthis._dayOverClass = \"ui-datepicker-days-cell-over\"; // The name of the day hover marker class\n\tthis.regional = []; // Available regional settings, indexed by language code\n\tthis.regional[\"\"] = { // Default regional settings\n\t\tcloseText: \"Done\", // Display text for close link\n\t\tprevText: \"Prev\", // Display text for previous month link\n\t\tnextText: \"Next\", // Display text for next month link\n\t\tcurrentText: \"Today\", // Display text for current month link\n\t\tmonthNames: [\"January\",\"February\",\"March\",\"April\",\"May\",\"June\",\n\t\t\t\"July\",\"August\",\"September\",\"October\",\"November\",\"December\"], // Names of months for drop-down and formatting\n\t\tmonthNamesShort: [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\", \"Sep\", \"Oct\", \"Nov\", \"Dec\"], // For formatting\n\t\tdayNames: [\"Sunday\", \"Monday\", \"Tuesday\", \"Wednesday\", \"Thursday\", \"Friday\", \"Saturday\"], // For formatting\n\t\tdayNamesShort: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"], // For formatting\n\t\tdayNamesMin: [\"Su\",\"Mo\",\"Tu\",\"We\",\"Th\",\"Fr\",\"Sa\"], // Column headings for days starting at Sunday\n\t\tweekHeader: \"Wk\", // Column header for week of the year\n\t\tdateFormat: \"mm/dd/yy\", // See format options on parseDate\n\t\tfirstDay: 0, // The first day of the week, Sun = 0, Mon = 1, ...\n\t\tisRTL: false, // True if right-to-left language, false if left-to-right\n\t\tshowMonthAfterYear: false, // True if the year select precedes month, false for month then year\n\t\tyearSuffix: \"\" // Additional text to append to the year in the month headers\n\t};\n\tthis._defaults = { // Global defaults for all the date picker instances\n\t\tshowOn: \"focus\", // \"focus\" for popup on focus,\n\t\t\t// \"button\" for trigger button, or \"both\" for either\n\t\tshowAnim: \"fadeIn\", // Name of jQuery animation for popup\n\t\tshowOptions: {}, // Options for enhanced animations\n\t\tdefaultDate: null, // Used when field is blank: actual date,\n\t\t\t// +/-number for offset from today, null for today\n\t\tappendText: \"\", // Display text following the input box, e.g. showing the format\n\t\tbuttonText: \"...\", // Text for trigger button\n\t\tbuttonImage: \"\", // URL for trigger button image\n\t\tbuttonImageOnly: false, // True if the image appears alone, false if it appears on a button\n\t\thideIfNoPrevNext: false, // True to hide next/previous month links\n\t\t\t// if not applicable, false to just disable them\n\t\tnavigationAsDateFormat: false, // True if date formatting applied to prev/today/next links\n\t\tgotoCurrent: false, // True if today link goes back to current selection instead\n\t\tchangeMonth: false, // True if month can be selected directly, false if only prev/next\n\t\tchangeYear: false, // True if year can be selected directly, false if only prev/next\n\t\tyearRange: \"c-10:c+10\", // Range of years to display in drop-down,\n\t\t\t// either relative to today's year (-nn:+nn), relative to currently displayed year\n\t\t\t// (c-nn:c+nn), absolute (nnnn:nnnn), or a combination of the above (nnnn:-n)\n\t\tshowOtherMonths: false, // True to show dates in other months, false to leave blank\n\t\tselectOtherMonths: false, // True to allow selection of dates in other months, false for unselectable\n\t\tshowWeek: false, // True to show week of the year, false to not show it\n\t\tcalculateWeek: this.iso8601Week, // How to calculate the week of the year,\n\t\t\t// takes a Date and returns the number of the week for it\n\t\tshortYearCutoff: \"+10\", // Short year values < this are in the current century,\n\t\t\t// > this are in the previous century,\n\t\t\t// string value starting with \"+\" for current year + value\n\t\tminDate: null, // The earliest selectable date, or null for no limit\n\t\tmaxDate: null, // The latest selectable date, or null for no limit\n\t\tduration: \"fast\", // Duration of display/closure\n\t\tbeforeShowDay: null, // Function that takes a date and returns an array with\n\t\t\t// [0] = true if selectable, false if not, [1] = custom CSS class name(s) or \"\",\n\t\t\t// [2] = cell title (optional), e.g. $.datepicker.noWeekends\n\t\tbeforeShow: null, // Function that takes an input field and\n\t\t\t// returns a set of custom settings for the date picker\n\t\tonSelect: null, // Define a callback function when a date is selected\n\t\tonChangeMonthYear: null, // Define a callback function when the month or year is changed\n\t\tonClose: null, // Define a callback function when the datepicker is closed\n\t\tnumberOfMonths: 1, // Number of months to show at a time\n\t\tshowCurrentAtPos: 0, // The position in multipe months at which to show the current month (starting at 0)\n\t\tstepMonths: 1, // Number of months to step back/forward\n\t\tstepBigMonths: 12, // Number of months to step back/forward for the big links\n\t\taltField: \"\", // Selector for an alternate field to store selected dates into\n\t\taltFormat: \"\", // The date format to use for the alternate field\n\t\tconstrainInput: true, // The input is constrained by the current date format\n\t\tshowButtonPanel: false, // True to show button panel, false to not show it\n\t\tautoSize: false, // True to size the input for the date format, false to leave as is\n\t\tdisabled: false // The initial disabled state\n\t};\n\t$.extend(this._defaults, this.regional[\"\"]);\n\tthis.regional.en = $.extend( true, {}, this.regional[ \"\" ]);\n\tthis.regional[ \"en-US\" ] = $.extend( true, {}, this.regional.en );\n\tthis.dpDiv = datepicker_bindHover($(\"<div id='\" + this._mainDivId + \"' class='ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>\"));\n}\n\n$.extend(Datepicker.prototype, {\n\t/* Class name added to elements to indicate already configured with a date picker. */\n\tmarkerClassName: \"hasDatepicker\",\n\n\t//Keep track of the maximum number of rows displayed (see #7043)\n\tmaxRows: 4,\n\n\t// TODO rename to \"widget\" when switching to widget factory\n\t_widgetDatepicker: function() {\n\t\treturn this.dpDiv;\n\t},\n\n\t/* Override the default settings for all instances of the date picker.\n\t * @param  settings  object - the new settings to use as defaults (anonymous object)\n\t * @return the manager object\n\t */\n\tsetDefaults: function(settings) {\n\t\tdatepicker_extendRemove(this._defaults, settings || {});\n\t\treturn this;\n\t},\n\n\t/* Attach the date picker to a jQuery selection.\n\t * @param  target\telement - the target input field or division or span\n\t * @param  settings  object - the new settings to use for this date picker instance (anonymous)\n\t */\n\t_attachDatepicker: function(target, settings) {\n\t\tvar nodeName, inline, inst;\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\tinline = (nodeName === \"div\" || nodeName === \"span\");\n\t\tif (!target.id) {\n\t\t\tthis.uuid += 1;\n\t\t\ttarget.id = \"dp\" + this.uuid;\n\t\t}\n\t\tinst = this._newInst($(target), inline);\n\t\tinst.settings = $.extend({}, settings || {});\n\t\tif (nodeName === \"input\") {\n\t\t\tthis._connectDatepicker(target, inst);\n\t\t} else if (inline) {\n\t\t\tthis._inlineDatepicker(target, inst);\n\t\t}\n\t},\n\n\t/* Create a new instance object. */\n\t_newInst: function(target, inline) {\n\t\tvar id = target[0].id.replace(/([^A-Za-z0-9_\\-])/g, \"\\\\\\\\$1\"); // escape jQuery meta chars\n\t\treturn {id: id, input: target, // associated target\n\t\t\tselectedDay: 0, selectedMonth: 0, selectedYear: 0, // current selection\n\t\t\tdrawMonth: 0, drawYear: 0, // month being drawn\n\t\t\tinline: inline, // is datepicker inline or not\n\t\t\tdpDiv: (!inline ? this.dpDiv : // presentation div\n\t\t\tdatepicker_bindHover($(\"<div class='\" + this._inlineClass + \" ui-datepicker ui-widget ui-widget-content ui-helper-clearfix ui-corner-all'></div>\")))};\n\t},\n\n\t/* Attach the date picker to an input field. */\n\t_connectDatepicker: function(target, inst) {\n\t\tvar input = $(target);\n\t\tinst.append = $([]);\n\t\tinst.trigger = $([]);\n\t\tif (input.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\t\tthis._attachments(input, inst);\n\t\tinput.addClass(this.markerClassName).keydown(this._doKeyDown).\n\t\t\tkeypress(this._doKeyPress).keyup(this._doKeyUp);\n\t\tthis._autoSize(inst);\n\t\t$.data(target, \"datepicker\", inst);\n\t\t//If disabled option is true, disable the datepicker once it has been attached to the input (see ticket #5665)\n\t\tif( inst.settings.disabled ) {\n\t\t\tthis._disableDatepicker( target );\n\t\t}\n\t},\n\n\t/* Make attachments based on settings. */\n\t_attachments: function(input, inst) {\n\t\tvar showOn, buttonText, buttonImage,\n\t\t\tappendText = this._get(inst, \"appendText\"),\n\t\t\tisRTL = this._get(inst, \"isRTL\");\n\n\t\tif (inst.append) {\n\t\t\tinst.append.remove();\n\t\t}\n\t\tif (appendText) {\n\t\t\tinst.append = $(\"<span class='\" + this._appendClass + \"'>\" + appendText + \"</span>\");\n\t\t\tinput[isRTL ? \"before\" : \"after\"](inst.append);\n\t\t}\n\n\t\tinput.unbind(\"focus\", this._showDatepicker);\n\n\t\tif (inst.trigger) {\n\t\t\tinst.trigger.remove();\n\t\t}\n\n\t\tshowOn = this._get(inst, \"showOn\");\n\t\tif (showOn === \"focus\" || showOn === \"both\") { // pop-up date picker when in the marked field\n\t\t\tinput.focus(this._showDatepicker);\n\t\t}\n\t\tif (showOn === \"button\" || showOn === \"both\") { // pop-up date picker when button clicked\n\t\t\tbuttonText = this._get(inst, \"buttonText\");\n\t\t\tbuttonImage = this._get(inst, \"buttonImage\");\n\t\t\tinst.trigger = $(this._get(inst, \"buttonImageOnly\") ?\n\t\t\t\t$(\"<img/>\").addClass(this._triggerClass).\n\t\t\t\t\tattr({ src: buttonImage, alt: buttonText, title: buttonText }) :\n\t\t\t\t$(\"<button type='button'></button>\").addClass(this._triggerClass).\n\t\t\t\t\thtml(!buttonImage ? buttonText : $(\"<img/>\").attr(\n\t\t\t\t\t{ src:buttonImage, alt:buttonText, title:buttonText })));\n\t\t\tinput[isRTL ? \"before\" : \"after\"](inst.trigger);\n\t\t\tinst.trigger.click(function() {\n\t\t\t\tif ($.datepicker._datepickerShowing && $.datepicker._lastInput === input[0]) {\n\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t} else if ($.datepicker._datepickerShowing && $.datepicker._lastInput !== input[0]) {\n\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t\t$.datepicker._showDatepicker(input[0]);\n\t\t\t\t} else {\n\t\t\t\t\t$.datepicker._showDatepicker(input[0]);\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t});\n\t\t}\n\t},\n\n\t/* Apply the maximum length for the date format. */\n\t_autoSize: function(inst) {\n\t\tif (this._get(inst, \"autoSize\") && !inst.inline) {\n\t\t\tvar findMax, max, maxI, i,\n\t\t\t\tdate = new Date(2009, 12 - 1, 20), // Ensure double digits\n\t\t\t\tdateFormat = this._get(inst, \"dateFormat\");\n\n\t\t\tif (dateFormat.match(/[DM]/)) {\n\t\t\t\tfindMax = function(names) {\n\t\t\t\t\tmax = 0;\n\t\t\t\t\tmaxI = 0;\n\t\t\t\t\tfor (i = 0; i < names.length; i++) {\n\t\t\t\t\t\tif (names[i].length > max) {\n\t\t\t\t\t\t\tmax = names[i].length;\n\t\t\t\t\t\t\tmaxI = i;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn maxI;\n\t\t\t\t};\n\t\t\t\tdate.setMonth(findMax(this._get(inst, (dateFormat.match(/MM/) ?\n\t\t\t\t\t\"monthNames\" : \"monthNamesShort\"))));\n\t\t\t\tdate.setDate(findMax(this._get(inst, (dateFormat.match(/DD/) ?\n\t\t\t\t\t\"dayNames\" : \"dayNamesShort\"))) + 20 - date.getDay());\n\t\t\t}\n\t\t\tinst.input.attr(\"size\", this._formatDate(inst, date).length);\n\t\t}\n\t},\n\n\t/* Attach an inline date picker to a div. */\n\t_inlineDatepicker: function(target, inst) {\n\t\tvar divSpan = $(target);\n\t\tif (divSpan.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\t\tdivSpan.addClass(this.markerClassName).append(inst.dpDiv);\n\t\t$.data(target, \"datepicker\", inst);\n\t\tthis._setDate(inst, this._getDefaultDate(inst), true);\n\t\tthis._updateDatepicker(inst);\n\t\tthis._updateAlternate(inst);\n\t\t//If disabled option is true, disable the datepicker before showing it (see ticket #5665)\n\t\tif( inst.settings.disabled ) {\n\t\t\tthis._disableDatepicker( target );\n\t\t}\n\t\t// Set display:block in place of inst.dpDiv.show() which won't work on disconnected elements\n\t\t// http://bugs.jqueryui.com/ticket/7552 - A Datepicker created on a detached div has zero height\n\t\tinst.dpDiv.css( \"display\", \"block\" );\n\t},\n\n\t/* Pop-up the date picker in a \"dialog\" box.\n\t * @param  input element - ignored\n\t * @param  date\tstring or Date - the initial date to display\n\t * @param  onSelect  function - the function to call when a date is selected\n\t * @param  settings  object - update the dialog date picker instance's settings (anonymous object)\n\t * @param  pos int[2] - coordinates for the dialog's position within the screen or\n\t *\t\t\t\t\tevent - with x/y coordinates or\n\t *\t\t\t\t\tleave empty for default (screen centre)\n\t * @return the manager object\n\t */\n\t_dialogDatepicker: function(input, date, onSelect, settings, pos) {\n\t\tvar id, browserWidth, browserHeight, scrollX, scrollY,\n\t\t\tinst = this._dialogInst; // internal instance\n\n\t\tif (!inst) {\n\t\t\tthis.uuid += 1;\n\t\t\tid = \"dp\" + this.uuid;\n\t\t\tthis._dialogInput = $(\"<input type='text' id='\" + id +\n\t\t\t\t\"' style='position: absolute; top: -100px; width: 0px;'/>\");\n\t\t\tthis._dialogInput.keydown(this._doKeyDown);\n\t\t\t$(\"body\").append(this._dialogInput);\n\t\t\tinst = this._dialogInst = this._newInst(this._dialogInput, false);\n\t\t\tinst.settings = {};\n\t\t\t$.data(this._dialogInput[0], \"datepicker\", inst);\n\t\t}\n\t\tdatepicker_extendRemove(inst.settings, settings || {});\n\t\tdate = (date && date.constructor === Date ? this._formatDate(inst, date) : date);\n\t\tthis._dialogInput.val(date);\n\n\t\tthis._pos = (pos ? (pos.length ? pos : [pos.pageX, pos.pageY]) : null);\n\t\tif (!this._pos) {\n\t\t\tbrowserWidth = document.documentElement.clientWidth;\n\t\t\tbrowserHeight = document.documentElement.clientHeight;\n\t\t\tscrollX = document.documentElement.scrollLeft || document.body.scrollLeft;\n\t\t\tscrollY = document.documentElement.scrollTop || document.body.scrollTop;\n\t\t\tthis._pos = // should use actual width/height below\n\t\t\t\t[(browserWidth / 2) - 100 + scrollX, (browserHeight / 2) - 150 + scrollY];\n\t\t}\n\n\t\t// move input on screen for focus, but hidden behind dialog\n\t\tthis._dialogInput.css(\"left\", (this._pos[0] + 20) + \"px\").css(\"top\", this._pos[1] + \"px\");\n\t\tinst.settings.onSelect = onSelect;\n\t\tthis._inDialog = true;\n\t\tthis.dpDiv.addClass(this._dialogClass);\n\t\tthis._showDatepicker(this._dialogInput[0]);\n\t\tif ($.blockUI) {\n\t\t\t$.blockUI(this.dpDiv);\n\t\t}\n\t\t$.data(this._dialogInput[0], \"datepicker\", inst);\n\t\treturn this;\n\t},\n\n\t/* Detach a datepicker from its control.\n\t * @param  target\telement - the target input field or division or span\n\t */\n\t_destroyDatepicker: function(target) {\n\t\tvar nodeName,\n\t\t\t$target = $(target),\n\t\t\tinst = $.data(target, \"datepicker\");\n\n\t\tif (!$target.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\t$.removeData(target, \"datepicker\");\n\t\tif (nodeName === \"input\") {\n\t\t\tinst.append.remove();\n\t\t\tinst.trigger.remove();\n\t\t\t$target.removeClass(this.markerClassName).\n\t\t\t\tunbind(\"focus\", this._showDatepicker).\n\t\t\t\tunbind(\"keydown\", this._doKeyDown).\n\t\t\t\tunbind(\"keypress\", this._doKeyPress).\n\t\t\t\tunbind(\"keyup\", this._doKeyUp);\n\t\t} else if (nodeName === \"div\" || nodeName === \"span\") {\n\t\t\t$target.removeClass(this.markerClassName).empty();\n\t\t}\n\n\t\tif ( datepicker_instActive === inst ) {\n\t\t\tdatepicker_instActive = null;\n\t\t}\n\t},\n\n\t/* Enable the date picker to a jQuery selection.\n\t * @param  target\telement - the target input field or division or span\n\t */\n\t_enableDatepicker: function(target) {\n\t\tvar nodeName, inline,\n\t\t\t$target = $(target),\n\t\t\tinst = $.data(target, \"datepicker\");\n\n\t\tif (!$target.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\tif (nodeName === \"input\") {\n\t\t\ttarget.disabled = false;\n\t\t\tinst.trigger.filter(\"button\").\n\t\t\t\teach(function() { this.disabled = false; }).end().\n\t\t\t\tfilter(\"img\").css({opacity: \"1.0\", cursor: \"\"});\n\t\t} else if (nodeName === \"div\" || nodeName === \"span\") {\n\t\t\tinline = $target.children(\".\" + this._inlineClass);\n\t\t\tinline.children().removeClass(\"ui-state-disabled\");\n\t\t\tinline.find(\"select.ui-datepicker-month, select.ui-datepicker-year\").\n\t\t\t\tprop(\"disabled\", false);\n\t\t}\n\t\tthis._disabledInputs = $.map(this._disabledInputs,\n\t\t\tfunction(value) { return (value === target ? null : value); }); // delete entry\n\t},\n\n\t/* Disable the date picker to a jQuery selection.\n\t * @param  target\telement - the target input field or division or span\n\t */\n\t_disableDatepicker: function(target) {\n\t\tvar nodeName, inline,\n\t\t\t$target = $(target),\n\t\t\tinst = $.data(target, \"datepicker\");\n\n\t\tif (!$target.hasClass(this.markerClassName)) {\n\t\t\treturn;\n\t\t}\n\n\t\tnodeName = target.nodeName.toLowerCase();\n\t\tif (nodeName === \"input\") {\n\t\t\ttarget.disabled = true;\n\t\t\tinst.trigger.filter(\"button\").\n\t\t\t\teach(function() { this.disabled = true; }).end().\n\t\t\t\tfilter(\"img\").css({opacity: \"0.5\", cursor: \"default\"});\n\t\t} else if (nodeName === \"div\" || nodeName === \"span\") {\n\t\t\tinline = $target.children(\".\" + this._inlineClass);\n\t\t\tinline.children().addClass(\"ui-state-disabled\");\n\t\t\tinline.find(\"select.ui-datepicker-month, select.ui-datepicker-year\").\n\t\t\t\tprop(\"disabled\", true);\n\t\t}\n\t\tthis._disabledInputs = $.map(this._disabledInputs,\n\t\t\tfunction(value) { return (value === target ? null : value); }); // delete entry\n\t\tthis._disabledInputs[this._disabledInputs.length] = target;\n\t},\n\n\t/* Is the first field in a jQuery collection disabled as a datepicker?\n\t * @param  target\telement - the target input field or division or span\n\t * @return boolean - true if disabled, false if enabled\n\t */\n\t_isDisabledDatepicker: function(target) {\n\t\tif (!target) {\n\t\t\treturn false;\n\t\t}\n\t\tfor (var i = 0; i < this._disabledInputs.length; i++) {\n\t\t\tif (this._disabledInputs[i] === target) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t},\n\n\t/* Retrieve the instance data for the target control.\n\t * @param  target  element - the target input field or division or span\n\t * @return  object - the associated instance data\n\t * @throws  error if a jQuery problem getting data\n\t */\n\t_getInst: function(target) {\n\t\ttry {\n\t\t\treturn $.data(target, \"datepicker\");\n\t\t}\n\t\tcatch (err) {\n\t\t\tthrow \"Missing instance data for this datepicker\";\n\t\t}\n\t},\n\n\t/* Update or retrieve the settings for a date picker attached to an input field or division.\n\t * @param  target  element - the target input field or division or span\n\t * @param  name\tobject - the new settings to update or\n\t *\t\t\t\tstring - the name of the setting to change or retrieve,\n\t *\t\t\t\twhen retrieving also \"all\" for all instance settings or\n\t *\t\t\t\t\"defaults\" for all global defaults\n\t * @param  value   any - the new value for the setting\n\t *\t\t\t\t(omit if above is an object or to retrieve a value)\n\t */\n\t_optionDatepicker: function(target, name, value) {\n\t\tvar settings, date, minDate, maxDate,\n\t\t\tinst = this._getInst(target);\n\n\t\tif (arguments.length === 2 && typeof name === \"string\") {\n\t\t\treturn (name === \"defaults\" ? $.extend({}, $.datepicker._defaults) :\n\t\t\t\t(inst ? (name === \"all\" ? $.extend({}, inst.settings) :\n\t\t\t\tthis._get(inst, name)) : null));\n\t\t}\n\n\t\tsettings = name || {};\n\t\tif (typeof name === \"string\") {\n\t\t\tsettings = {};\n\t\t\tsettings[name] = value;\n\t\t}\n\n\t\tif (inst) {\n\t\t\tif (this._curInst === inst) {\n\t\t\t\tthis._hideDatepicker();\n\t\t\t}\n\n\t\t\tdate = this._getDateDatepicker(target, true);\n\t\t\tminDate = this._getMinMaxDate(inst, \"min\");\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\");\n\t\t\tdatepicker_extendRemove(inst.settings, settings);\n\t\t\t// reformat the old minDate/maxDate values if dateFormat changes and a new minDate/maxDate isn't provided\n\t\t\tif (minDate !== null && settings.dateFormat !== undefined && settings.minDate === undefined) {\n\t\t\t\tinst.settings.minDate = this._formatDate(inst, minDate);\n\t\t\t}\n\t\t\tif (maxDate !== null && settings.dateFormat !== undefined && settings.maxDate === undefined) {\n\t\t\t\tinst.settings.maxDate = this._formatDate(inst, maxDate);\n\t\t\t}\n\t\t\tif ( \"disabled\" in settings ) {\n\t\t\t\tif ( settings.disabled ) {\n\t\t\t\t\tthis._disableDatepicker(target);\n\t\t\t\t} else {\n\t\t\t\t\tthis._enableDatepicker(target);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._attachments($(target), inst);\n\t\t\tthis._autoSize(inst);\n\t\t\tthis._setDate(inst, date);\n\t\t\tthis._updateAlternate(inst);\n\t\t\tthis._updateDatepicker(inst);\n\t\t}\n\t},\n\n\t// change method deprecated\n\t_changeDatepicker: function(target, name, value) {\n\t\tthis._optionDatepicker(target, name, value);\n\t},\n\n\t/* Redraw the date picker attached to an input field or division.\n\t * @param  target  element - the target input field or division or span\n\t */\n\t_refreshDatepicker: function(target) {\n\t\tvar inst = this._getInst(target);\n\t\tif (inst) {\n\t\t\tthis._updateDatepicker(inst);\n\t\t}\n\t},\n\n\t/* Set the dates for a jQuery selection.\n\t * @param  target element - the target input field or division or span\n\t * @param  date\tDate - the new date\n\t */\n\t_setDateDatepicker: function(target, date) {\n\t\tvar inst = this._getInst(target);\n\t\tif (inst) {\n\t\t\tthis._setDate(inst, date);\n\t\t\tthis._updateDatepicker(inst);\n\t\t\tthis._updateAlternate(inst);\n\t\t}\n\t},\n\n\t/* Get the date(s) for the first entry in a jQuery selection.\n\t * @param  target element - the target input field or division or span\n\t * @param  noDefault boolean - true if no default date is to be used\n\t * @return Date - the current date\n\t */\n\t_getDateDatepicker: function(target, noDefault) {\n\t\tvar inst = this._getInst(target);\n\t\tif (inst && !inst.inline) {\n\t\t\tthis._setDateFromField(inst, noDefault);\n\t\t}\n\t\treturn (inst ? this._getDate(inst) : null);\n\t},\n\n\t/* Handle keystrokes. */\n\t_doKeyDown: function(event) {\n\t\tvar onSelect, dateStr, sel,\n\t\t\tinst = $.datepicker._getInst(event.target),\n\t\t\thandled = true,\n\t\t\tisRTL = inst.dpDiv.is(\".ui-datepicker-rtl\");\n\n\t\tinst._keyEvent = true;\n\t\tif ($.datepicker._datepickerShowing) {\n\t\t\tswitch (event.keyCode) {\n\t\t\t\tcase 9: $.datepicker._hideDatepicker();\n\t\t\t\t\t\thandled = false;\n\t\t\t\t\t\tbreak; // hide on tab out\n\t\t\t\tcase 13: sel = $(\"td.\" + $.datepicker._dayOverClass + \":not(.\" +\n\t\t\t\t\t\t\t\t\t$.datepicker._currentClass + \")\", inst.dpDiv);\n\t\t\t\t\t\tif (sel[0]) {\n\t\t\t\t\t\t\t$.datepicker._selectDay(event.target, inst.selectedMonth, inst.selectedYear, sel[0]);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tonSelect = $.datepicker._get(inst, \"onSelect\");\n\t\t\t\t\t\tif (onSelect) {\n\t\t\t\t\t\t\tdateStr = $.datepicker._formatDate(inst);\n\n\t\t\t\t\t\t\t// trigger custom callback\n\t\t\t\t\t\t\tonSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn false; // don't submit the form\n\t\t\t\tcase 27: $.datepicker._hideDatepicker();\n\t\t\t\t\t\tbreak; // hide on escape\n\t\t\t\tcase 33: $.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\tbreak; // previous month/year on page up/+ ctrl\n\t\t\t\tcase 34: $.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\tbreak; // next month/year on page down/+ ctrl\n\t\t\t\tcase 35: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._clearDate(event.target);\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // clear on ctrl or command +end\n\t\t\t\tcase 36: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._gotoToday(event.target);\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // current on ctrl or command +home\n\t\t\t\tcase 37: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (isRTL ? +1 : -1), \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\t// -1 day on ctrl or command +left\n\t\t\t\t\t\tif (event.originalEvent.altKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t\t-$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// next month/year on alt +left on Mac\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 38: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, -7, \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // -1 week on ctrl or command +up\n\t\t\t\tcase 39: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (isRTL ? -1 : +1), \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\t// +1 day on ctrl or command +right\n\t\t\t\t\t\tif (event.originalEvent.altKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, (event.ctrlKey ?\n\t\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepBigMonths\") :\n\t\t\t\t\t\t\t\t+$.datepicker._get(inst, \"stepMonths\")), \"M\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// next month/year on alt +right\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 40: if (event.ctrlKey || event.metaKey) {\n\t\t\t\t\t\t\t$.datepicker._adjustDate(event.target, +7, \"D\");\n\t\t\t\t\t\t}\n\t\t\t\t\t\thandled = event.ctrlKey || event.metaKey;\n\t\t\t\t\t\tbreak; // +1 week on ctrl or command +down\n\t\t\t\tdefault: handled = false;\n\t\t\t}\n\t\t} else if (event.keyCode === 36 && event.ctrlKey) { // display the date picker on ctrl+home\n\t\t\t$.datepicker._showDatepicker(this);\n\t\t} else {\n\t\t\thandled = false;\n\t\t}\n\n\t\tif (handled) {\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\t}\n\t},\n\n\t/* Filter entered characters - based on date format. */\n\t_doKeyPress: function(event) {\n\t\tvar chars, chr,\n\t\t\tinst = $.datepicker._getInst(event.target);\n\n\t\tif ($.datepicker._get(inst, \"constrainInput\")) {\n\t\t\tchars = $.datepicker._possibleChars($.datepicker._get(inst, \"dateFormat\"));\n\t\t\tchr = String.fromCharCode(event.charCode == null ? event.keyCode : event.charCode);\n\t\t\treturn event.ctrlKey || event.metaKey || (chr < \" \" || !chars || chars.indexOf(chr) > -1);\n\t\t}\n\t},\n\n\t/* Synchronise manual entry and field/alternate field. */\n\t_doKeyUp: function(event) {\n\t\tvar date,\n\t\t\tinst = $.datepicker._getInst(event.target);\n\n\t\tif (inst.input.val() !== inst.lastVal) {\n\t\t\ttry {\n\t\t\t\tdate = $.datepicker.parseDate($.datepicker._get(inst, \"dateFormat\"),\n\t\t\t\t\t(inst.input ? inst.input.val() : null),\n\t\t\t\t\t$.datepicker._getFormatConfig(inst));\n\n\t\t\t\tif (date) { // only if valid\n\t\t\t\t\t$.datepicker._setDateFromField(inst);\n\t\t\t\t\t$.datepicker._updateAlternate(inst);\n\t\t\t\t\t$.datepicker._updateDatepicker(inst);\n\t\t\t\t}\n\t\t\t}\n\t\t\tcatch (err) {\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t},\n\n\t/* Pop-up the date picker for a given input field.\n\t * If false returned from beforeShow event handler do not show.\n\t * @param  input  element - the input field attached to the date picker or\n\t *\t\t\t\t\tevent - if triggered by focus\n\t */\n\t_showDatepicker: function(input) {\n\t\tinput = input.target || input;\n\t\tif (input.nodeName.toLowerCase() !== \"input\") { // find from button/image trigger\n\t\t\tinput = $(\"input\", input.parentNode)[0];\n\t\t}\n\n\t\tif ($.datepicker._isDisabledDatepicker(input) || $.datepicker._lastInput === input) { // already here\n\t\t\treturn;\n\t\t}\n\n\t\tvar inst, beforeShow, beforeShowSettings, isFixed,\n\t\t\toffset, showAnim, duration;\n\n\t\tinst = $.datepicker._getInst(input);\n\t\tif ($.datepicker._curInst && $.datepicker._curInst !== inst) {\n\t\t\t$.datepicker._curInst.dpDiv.stop(true, true);\n\t\t\tif ( inst && $.datepicker._datepickerShowing ) {\n\t\t\t\t$.datepicker._hideDatepicker( $.datepicker._curInst.input[0] );\n\t\t\t}\n\t\t}\n\n\t\tbeforeShow = $.datepicker._get(inst, \"beforeShow\");\n\t\tbeforeShowSettings = beforeShow ? beforeShow.apply(input, [input, inst]) : {};\n\t\tif(beforeShowSettings === false){\n\t\t\treturn;\n\t\t}\n\t\tdatepicker_extendRemove(inst.settings, beforeShowSettings);\n\n\t\tinst.lastVal = null;\n\t\t$.datepicker._lastInput = input;\n\t\t$.datepicker._setDateFromField(inst);\n\n\t\tif ($.datepicker._inDialog) { // hide cursor\n\t\t\tinput.value = \"\";\n\t\t}\n\t\tif (!$.datepicker._pos) { // position below input\n\t\t\t$.datepicker._pos = $.datepicker._findPos(input);\n\t\t\t$.datepicker._pos[1] += input.offsetHeight; // add the height\n\t\t}\n\n\t\tisFixed = false;\n\t\t$(input).parents().each(function() {\n\t\t\tisFixed |= $(this).css(\"position\") === \"fixed\";\n\t\t\treturn !isFixed;\n\t\t});\n\n\t\toffset = {left: $.datepicker._pos[0], top: $.datepicker._pos[1]};\n\t\t$.datepicker._pos = null;\n\t\t//to avoid flashes on Firefox\n\t\tinst.dpDiv.empty();\n\t\t// determine sizing offscreen\n\t\tinst.dpDiv.css({position: \"absolute\", display: \"block\", top: \"-1000px\"});\n\t\t$.datepicker._updateDatepicker(inst);\n\t\t// fix width for dynamic number of date pickers\n\t\t// and adjust position before showing\n\t\toffset = $.datepicker._checkOffset(inst, offset, isFixed);\n\t\tinst.dpDiv.css({position: ($.datepicker._inDialog && $.blockUI ?\n\t\t\t\"static\" : (isFixed ? \"fixed\" : \"absolute\")), display: \"none\",\n\t\t\tleft: offset.left + \"px\", top: offset.top + \"px\"});\n\n\t\tif (!inst.inline) {\n\t\t\tshowAnim = $.datepicker._get(inst, \"showAnim\");\n\t\t\tduration = $.datepicker._get(inst, \"duration\");\n\t\t\tinst.dpDiv.css( \"z-index\", datepicker_getZindex( $( input ) ) + 1 );\n\t\t\t$.datepicker._datepickerShowing = true;\n\n\t\t\tif ( $.effects && $.effects.effect[ showAnim ] ) {\n\t\t\t\tinst.dpDiv.show(showAnim, $.datepicker._get(inst, \"showOptions\"), duration);\n\t\t\t} else {\n\t\t\t\tinst.dpDiv[showAnim || \"show\"](showAnim ? duration : null);\n\t\t\t}\n\n\t\t\tif ( $.datepicker._shouldFocusInput( inst ) ) {\n\t\t\t\tinst.input.focus();\n\t\t\t}\n\n\t\t\t$.datepicker._curInst = inst;\n\t\t}\n\t},\n\n\t/* Generate the date picker content. */\n\t_updateDatepicker: function(inst) {\n\t\tthis.maxRows = 4; //Reset the max number of rows being displayed (see #7043)\n\t\tdatepicker_instActive = inst; // for delegate hover events\n\t\tinst.dpDiv.empty().append(this._generateHTML(inst));\n\t\tthis._attachHandlers(inst);\n\n\t\tvar origyearshtml,\n\t\t\tnumMonths = this._getNumberOfMonths(inst),\n\t\t\tcols = numMonths[1],\n\t\t\twidth = 17,\n\t\t\tactiveCell = inst.dpDiv.find( \".\" + this._dayOverClass + \" a\" );\n\n\t\tif ( activeCell.length > 0 ) {\n\t\t\tdatepicker_handleMouseover.apply( activeCell.get( 0 ) );\n\t\t}\n\n\t\tinst.dpDiv.removeClass(\"ui-datepicker-multi-2 ui-datepicker-multi-3 ui-datepicker-multi-4\").width(\"\");\n\t\tif (cols > 1) {\n\t\t\tinst.dpDiv.addClass(\"ui-datepicker-multi-\" + cols).css(\"width\", (width * cols) + \"em\");\n\t\t}\n\t\tinst.dpDiv[(numMonths[0] !== 1 || numMonths[1] !== 1 ? \"add\" : \"remove\") +\n\t\t\t\"Class\"](\"ui-datepicker-multi\");\n\t\tinst.dpDiv[(this._get(inst, \"isRTL\") ? \"add\" : \"remove\") +\n\t\t\t\"Class\"](\"ui-datepicker-rtl\");\n\n\t\tif (inst === $.datepicker._curInst && $.datepicker._datepickerShowing && $.datepicker._shouldFocusInput( inst ) ) {\n\t\t\tinst.input.focus();\n\t\t}\n\n\t\t// deffered render of the years select (to avoid flashes on Firefox)\n\t\tif( inst.yearshtml ){\n\t\t\torigyearshtml = inst.yearshtml;\n\t\t\tsetTimeout(function(){\n\t\t\t\t//assure that inst.yearshtml didn't change.\n\t\t\t\tif( origyearshtml === inst.yearshtml && inst.yearshtml ){\n\t\t\t\t\tinst.dpDiv.find(\"select.ui-datepicker-year:first\").replaceWith(inst.yearshtml);\n\t\t\t\t}\n\t\t\t\torigyearshtml = inst.yearshtml = null;\n\t\t\t}, 0);\n\t\t}\n\t},\n\n\t// #6694 - don't focus the input if it's already focused\n\t// this breaks the change event in IE\n\t// Support: IE and jQuery <1.9\n\t_shouldFocusInput: function( inst ) {\n\t\treturn inst.input && inst.input.is( \":visible\" ) && !inst.input.is( \":disabled\" ) && !inst.input.is( \":focus\" );\n\t},\n\n\t/* Check positioning to remain on screen. */\n\t_checkOffset: function(inst, offset, isFixed) {\n\t\tvar dpWidth = inst.dpDiv.outerWidth(),\n\t\t\tdpHeight = inst.dpDiv.outerHeight(),\n\t\t\tinputWidth = inst.input ? inst.input.outerWidth() : 0,\n\t\t\tinputHeight = inst.input ? inst.input.outerHeight() : 0,\n\t\t\tviewWidth = document.documentElement.clientWidth + (isFixed ? 0 : $(document).scrollLeft()),\n\t\t\tviewHeight = document.documentElement.clientHeight + (isFixed ? 0 : $(document).scrollTop());\n\n\t\toffset.left -= (this._get(inst, \"isRTL\") ? (dpWidth - inputWidth) : 0);\n\t\toffset.left -= (isFixed && offset.left === inst.input.offset().left) ? $(document).scrollLeft() : 0;\n\t\toffset.top -= (isFixed && offset.top === (inst.input.offset().top + inputHeight)) ? $(document).scrollTop() : 0;\n\n\t\t// now check if datepicker is showing outside window viewport - move to a better place if so.\n\t\toffset.left -= Math.min(offset.left, (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ?\n\t\t\tMath.abs(offset.left + dpWidth - viewWidth) : 0);\n\t\toffset.top -= Math.min(offset.top, (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ?\n\t\t\tMath.abs(dpHeight + inputHeight) : 0);\n\n\t\treturn offset;\n\t},\n\n\t/* Find an object's position on the screen. */\n\t_findPos: function(obj) {\n\t\tvar position,\n\t\t\tinst = this._getInst(obj),\n\t\t\tisRTL = this._get(inst, \"isRTL\");\n\n\t\twhile (obj && (obj.type === \"hidden\" || obj.nodeType !== 1 || $.expr.filters.hidden(obj))) {\n\t\t\tobj = obj[isRTL ? \"previousSibling\" : \"nextSibling\"];\n\t\t}\n\n\t\tposition = $(obj).offset();\n\t\treturn [position.left, position.top];\n\t},\n\n\t/* Hide the date picker from view.\n\t * @param  input  element - the input field attached to the date picker\n\t */\n\t_hideDatepicker: function(input) {\n\t\tvar showAnim, duration, postProcess, onClose,\n\t\t\tinst = this._curInst;\n\n\t\tif (!inst || (input && inst !== $.data(input, \"datepicker\"))) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (this._datepickerShowing) {\n\t\t\tshowAnim = this._get(inst, \"showAnim\");\n\t\t\tduration = this._get(inst, \"duration\");\n\t\t\tpostProcess = function() {\n\t\t\t\t$.datepicker._tidyDialog(inst);\n\t\t\t};\n\n\t\t\t// DEPRECATED: after BC for 1.8.x $.effects[ showAnim ] is not needed\n\t\t\tif ( $.effects && ( $.effects.effect[ showAnim ] || $.effects[ showAnim ] ) ) {\n\t\t\t\tinst.dpDiv.hide(showAnim, $.datepicker._get(inst, \"showOptions\"), duration, postProcess);\n\t\t\t} else {\n\t\t\t\tinst.dpDiv[(showAnim === \"slideDown\" ? \"slideUp\" :\n\t\t\t\t\t(showAnim === \"fadeIn\" ? \"fadeOut\" : \"hide\"))]((showAnim ? duration : null), postProcess);\n\t\t\t}\n\n\t\t\tif (!showAnim) {\n\t\t\t\tpostProcess();\n\t\t\t}\n\t\t\tthis._datepickerShowing = false;\n\n\t\t\tonClose = this._get(inst, \"onClose\");\n\t\t\tif (onClose) {\n\t\t\t\tonClose.apply((inst.input ? inst.input[0] : null), [(inst.input ? inst.input.val() : \"\"), inst]);\n\t\t\t}\n\n\t\t\tthis._lastInput = null;\n\t\t\tif (this._inDialog) {\n\t\t\t\tthis._dialogInput.css({ position: \"absolute\", left: \"0\", top: \"-100px\" });\n\t\t\t\tif ($.blockUI) {\n\t\t\t\t\t$.unblockUI();\n\t\t\t\t\t$(\"body\").append(this.dpDiv);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis._inDialog = false;\n\t\t}\n\t},\n\n\t/* Tidy up after a dialog display. */\n\t_tidyDialog: function(inst) {\n\t\tinst.dpDiv.removeClass(this._dialogClass).unbind(\".ui-datepicker-calendar\");\n\t},\n\n\t/* Close date picker if clicked elsewhere. */\n\t_checkExternalClick: function(event) {\n\t\tif (!$.datepicker._curInst) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar $target = $(event.target),\n\t\t\tinst = $.datepicker._getInst($target[0]);\n\n\t\tif ( ( ( $target[0].id !== $.datepicker._mainDivId &&\n\t\t\t\t$target.parents(\"#\" + $.datepicker._mainDivId).length === 0 &&\n\t\t\t\t!$target.hasClass($.datepicker.markerClassName) &&\n\t\t\t\t!$target.closest(\".\" + $.datepicker._triggerClass).length &&\n\t\t\t\t$.datepicker._datepickerShowing && !($.datepicker._inDialog && $.blockUI) ) ) ||\n\t\t\t( $target.hasClass($.datepicker.markerClassName) && $.datepicker._curInst !== inst ) ) {\n\t\t\t\t$.datepicker._hideDatepicker();\n\t\t}\n\t},\n\n\t/* Adjust one of the date sub-fields. */\n\t_adjustDate: function(id, offset, period) {\n\t\tvar target = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tif (this._isDisabledDatepicker(target[0])) {\n\t\t\treturn;\n\t\t}\n\t\tthis._adjustInstDate(inst, offset +\n\t\t\t(period === \"M\" ? this._get(inst, \"showCurrentAtPos\") : 0), // undo positioning\n\t\t\tperiod);\n\t\tthis._updateDatepicker(inst);\n\t},\n\n\t/* Action for current link. */\n\t_gotoToday: function(id) {\n\t\tvar date,\n\t\t\ttarget = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tif (this._get(inst, \"gotoCurrent\") && inst.currentDay) {\n\t\t\tinst.selectedDay = inst.currentDay;\n\t\t\tinst.drawMonth = inst.selectedMonth = inst.currentMonth;\n\t\t\tinst.drawYear = inst.selectedYear = inst.currentYear;\n\t\t} else {\n\t\t\tdate = new Date();\n\t\t\tinst.selectedDay = date.getDate();\n\t\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\n\t\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\n\t\t}\n\t\tthis._notifyChange(inst);\n\t\tthis._adjustDate(target);\n\t},\n\n\t/* Action for selecting a new month/year. */\n\t_selectMonthYear: function(id, select, period) {\n\t\tvar target = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tinst[\"selected\" + (period === \"M\" ? \"Month\" : \"Year\")] =\n\t\tinst[\"draw\" + (period === \"M\" ? \"Month\" : \"Year\")] =\n\t\t\tparseInt(select.options[select.selectedIndex].value,10);\n\n\t\tthis._notifyChange(inst);\n\t\tthis._adjustDate(target);\n\t},\n\n\t/* Action for selecting a day. */\n\t_selectDay: function(id, month, year, td) {\n\t\tvar inst,\n\t\t\ttarget = $(id);\n\n\t\tif ($(td).hasClass(this._unselectableClass) || this._isDisabledDatepicker(target[0])) {\n\t\t\treturn;\n\t\t}\n\n\t\tinst = this._getInst(target[0]);\n\t\tinst.selectedDay = inst.currentDay = $(\"a\", td).html();\n\t\tinst.selectedMonth = inst.currentMonth = month;\n\t\tinst.selectedYear = inst.currentYear = year;\n\t\tthis._selectDate(id, this._formatDate(inst,\n\t\t\tinst.currentDay, inst.currentMonth, inst.currentYear));\n\t},\n\n\t/* Erase the input field and hide the date picker. */\n\t_clearDate: function(id) {\n\t\tvar target = $(id);\n\t\tthis._selectDate(target, \"\");\n\t},\n\n\t/* Update the input field with the selected date. */\n\t_selectDate: function(id, dateStr) {\n\t\tvar onSelect,\n\t\t\ttarget = $(id),\n\t\t\tinst = this._getInst(target[0]);\n\n\t\tdateStr = (dateStr != null ? dateStr : this._formatDate(inst));\n\t\tif (inst.input) {\n\t\t\tinst.input.val(dateStr);\n\t\t}\n\t\tthis._updateAlternate(inst);\n\n\t\tonSelect = this._get(inst, \"onSelect\");\n\t\tif (onSelect) {\n\t\t\tonSelect.apply((inst.input ? inst.input[0] : null), [dateStr, inst]);  // trigger custom callback\n\t\t} else if (inst.input) {\n\t\t\tinst.input.trigger(\"change\"); // fire the change event\n\t\t}\n\n\t\tif (inst.inline){\n\t\t\tthis._updateDatepicker(inst);\n\t\t} else {\n\t\t\tthis._hideDatepicker();\n\t\t\tthis._lastInput = inst.input[0];\n\t\t\tif (typeof(inst.input[0]) !== \"object\") {\n\t\t\t\tinst.input.focus(); // restore focus\n\t\t\t}\n\t\t\tthis._lastInput = null;\n\t\t}\n\t},\n\n\t/* Update any alternate field to synchronise with the main field. */\n\t_updateAlternate: function(inst) {\n\t\tvar altFormat, date, dateStr,\n\t\t\taltField = this._get(inst, \"altField\");\n\n\t\tif (altField) { // update alternate field too\n\t\t\taltFormat = this._get(inst, \"altFormat\") || this._get(inst, \"dateFormat\");\n\t\t\tdate = this._getDate(inst);\n\t\t\tdateStr = this.formatDate(altFormat, date, this._getFormatConfig(inst));\n\t\t\t$(altField).each(function() { $(this).val(dateStr); });\n\t\t}\n\t},\n\n\t/* Set as beforeShowDay function to prevent selection of weekends.\n\t * @param  date  Date - the date to customise\n\t * @return [boolean, string] - is this date selectable?, what is its CSS class?\n\t */\n\tnoWeekends: function(date) {\n\t\tvar day = date.getDay();\n\t\treturn [(day > 0 && day < 6), \"\"];\n\t},\n\n\t/* Set as calculateWeek to determine the week of the year based on the ISO 8601 definition.\n\t * @param  date  Date - the date to get the week for\n\t * @return  number - the number of the week within the year that contains this date\n\t */\n\tiso8601Week: function(date) {\n\t\tvar time,\n\t\t\tcheckDate = new Date(date.getTime());\n\n\t\t// Find Thursday of this week starting on Monday\n\t\tcheckDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));\n\n\t\ttime = checkDate.getTime();\n\t\tcheckDate.setMonth(0); // Compare with Jan 1\n\t\tcheckDate.setDate(1);\n\t\treturn Math.floor(Math.round((time - checkDate) / 86400000) / 7) + 1;\n\t},\n\n\t/* Parse a string value into a date object.\n\t * See formatDate below for the possible formats.\n\t *\n\t * @param  format string - the expected format of the date\n\t * @param  value string - the date in the above format\n\t * @param  settings Object - attributes include:\n\t *\t\t\t\t\tshortYearCutoff  number - the cutoff year for determining the century (optional)\n\t *\t\t\t\t\tdayNamesShort\tstring[7] - abbreviated names of the days from Sunday (optional)\n\t *\t\t\t\t\tdayNames\t\tstring[7] - names of the days from Sunday (optional)\n\t *\t\t\t\t\tmonthNamesShort string[12] - abbreviated names of the months (optional)\n\t *\t\t\t\t\tmonthNames\t\tstring[12] - names of the months (optional)\n\t * @return  Date - the extracted date value or null if value is blank\n\t */\n\tparseDate: function (format, value, settings) {\n\t\tif (format == null || value == null) {\n\t\t\tthrow \"Invalid arguments\";\n\t\t}\n\n\t\tvalue = (typeof value === \"object\" ? value.toString() : value + \"\");\n\t\tif (value === \"\") {\n\t\t\treturn null;\n\t\t}\n\n\t\tvar iFormat, dim, extra,\n\t\t\tiValue = 0,\n\t\t\tshortYearCutoffTemp = (settings ? settings.shortYearCutoff : null) || this._defaults.shortYearCutoff,\n\t\t\tshortYearCutoff = (typeof shortYearCutoffTemp !== \"string\" ? shortYearCutoffTemp :\n\t\t\t\tnew Date().getFullYear() % 100 + parseInt(shortYearCutoffTemp, 10)),\n\t\t\tdayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,\n\t\t\tdayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,\n\t\t\tmonthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,\n\t\t\tmonthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,\n\t\t\tyear = -1,\n\t\t\tmonth = -1,\n\t\t\tday = -1,\n\t\t\tdoy = -1,\n\t\t\tliteral = false,\n\t\t\tdate,\n\t\t\t// Check whether a format character is doubled\n\t\t\tlookAhead = function(match) {\n\t\t\t\tvar matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);\n\t\t\t\tif (matches) {\n\t\t\t\t\tiFormat++;\n\t\t\t\t}\n\t\t\t\treturn matches;\n\t\t\t},\n\t\t\t// Extract a number from the string value\n\t\t\tgetNumber = function(match) {\n\t\t\t\tvar isDoubled = lookAhead(match),\n\t\t\t\t\tsize = (match === \"@\" ? 14 : (match === \"!\" ? 20 :\n\t\t\t\t\t(match === \"y\" && isDoubled ? 4 : (match === \"o\" ? 3 : 2)))),\n\t\t\t\t\tminSize = (match === \"y\" ? size : 1),\n\t\t\t\t\tdigits = new RegExp(\"^\\\\d{\" + minSize + \",\" + size + \"}\"),\n\t\t\t\t\tnum = value.substring(iValue).match(digits);\n\t\t\t\tif (!num) {\n\t\t\t\t\tthrow \"Missing number at position \" + iValue;\n\t\t\t\t}\n\t\t\t\tiValue += num[0].length;\n\t\t\t\treturn parseInt(num[0], 10);\n\t\t\t},\n\t\t\t// Extract a name from the string value and convert to an index\n\t\t\tgetName = function(match, shortNames, longNames) {\n\t\t\t\tvar index = -1,\n\t\t\t\t\tnames = $.map(lookAhead(match) ? longNames : shortNames, function (v, k) {\n\t\t\t\t\t\treturn [ [k, v] ];\n\t\t\t\t\t}).sort(function (a, b) {\n\t\t\t\t\t\treturn -(a[1].length - b[1].length);\n\t\t\t\t\t});\n\n\t\t\t\t$.each(names, function (i, pair) {\n\t\t\t\t\tvar name = pair[1];\n\t\t\t\t\tif (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {\n\t\t\t\t\t\tindex = pair[0];\n\t\t\t\t\t\tiValue += name.length;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (index !== -1) {\n\t\t\t\t\treturn index + 1;\n\t\t\t\t} else {\n\t\t\t\t\tthrow \"Unknown name at position \" + iValue;\n\t\t\t\t}\n\t\t\t},\n\t\t\t// Confirm that a literal character matches the string value\n\t\t\tcheckLiteral = function() {\n\t\t\t\tif (value.charAt(iValue) !== format.charAt(iFormat)) {\n\t\t\t\t\tthrow \"Unexpected literal at position \" + iValue;\n\t\t\t\t}\n\t\t\t\tiValue++;\n\t\t\t};\n\n\t\tfor (iFormat = 0; iFormat < format.length; iFormat++) {\n\t\t\tif (literal) {\n\t\t\t\tif (format.charAt(iFormat) === \"'\" && !lookAhead(\"'\")) {\n\t\t\t\t\tliteral = false;\n\t\t\t\t} else {\n\t\t\t\t\tcheckLiteral();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tswitch (format.charAt(iFormat)) {\n\t\t\t\t\tcase \"d\":\n\t\t\t\t\t\tday = getNumber(\"d\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"D\":\n\t\t\t\t\t\tgetName(\"D\", dayNamesShort, dayNames);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"o\":\n\t\t\t\t\t\tdoy = getNumber(\"o\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"m\":\n\t\t\t\t\t\tmonth = getNumber(\"m\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"M\":\n\t\t\t\t\t\tmonth = getName(\"M\", monthNamesShort, monthNames);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"y\":\n\t\t\t\t\t\tyear = getNumber(\"y\");\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"@\":\n\t\t\t\t\t\tdate = new Date(getNumber(\"@\"));\n\t\t\t\t\t\tyear = date.getFullYear();\n\t\t\t\t\t\tmonth = date.getMonth() + 1;\n\t\t\t\t\t\tday = date.getDate();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"!\":\n\t\t\t\t\t\tdate = new Date((getNumber(\"!\") - this._ticksTo1970) / 10000);\n\t\t\t\t\t\tyear = date.getFullYear();\n\t\t\t\t\t\tmonth = date.getMonth() + 1;\n\t\t\t\t\t\tday = date.getDate();\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"'\":\n\t\t\t\t\t\tif (lookAhead(\"'\")){\n\t\t\t\t\t\t\tcheckLiteral();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tliteral = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tcheckLiteral();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (iValue < value.length){\n\t\t\textra = value.substr(iValue);\n\t\t\tif (!/^\\s+/.test(extra)) {\n\t\t\t\tthrow \"Extra/unparsed characters found in date: \" + extra;\n\t\t\t}\n\t\t}\n\n\t\tif (year === -1) {\n\t\t\tyear = new Date().getFullYear();\n\t\t} else if (year < 100) {\n\t\t\tyear += new Date().getFullYear() - new Date().getFullYear() % 100 +\n\t\t\t\t(year <= shortYearCutoff ? 0 : -100);\n\t\t}\n\n\t\tif (doy > -1) {\n\t\t\tmonth = 1;\n\t\t\tday = doy;\n\t\t\tdo {\n\t\t\t\tdim = this._getDaysInMonth(year, month - 1);\n\t\t\t\tif (day <= dim) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tmonth++;\n\t\t\t\tday -= dim;\n\t\t\t} while (true);\n\t\t}\n\n\t\tdate = this._daylightSavingAdjust(new Date(year, month - 1, day));\n\t\tif (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {\n\t\t\tthrow \"Invalid date\"; // E.g. 31/02/00\n\t\t}\n\t\treturn date;\n\t},\n\n\t/* Standard date formats. */\n\tATOM: \"yy-mm-dd\", // RFC 3339 (ISO 8601)\n\tCOOKIE: \"D, dd M yy\",\n\tISO_8601: \"yy-mm-dd\",\n\tRFC_822: \"D, d M y\",\n\tRFC_850: \"DD, dd-M-y\",\n\tRFC_1036: \"D, d M y\",\n\tRFC_1123: \"D, d M yy\",\n\tRFC_2822: \"D, d M yy\",\n\tRSS: \"D, d M y\", // RFC 822\n\tTICKS: \"!\",\n\tTIMESTAMP: \"@\",\n\tW3C: \"yy-mm-dd\", // ISO 8601\n\n\t_ticksTo1970: (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) +\n\t\tMath.floor(1970 / 400)) * 24 * 60 * 60 * 10000000),\n\n\t/* Format a date object into a string value.\n\t * The format can be combinations of the following:\n\t * d  - day of month (no leading zero)\n\t * dd - day of month (two digit)\n\t * o  - day of year (no leading zeros)\n\t * oo - day of year (three digit)\n\t * D  - day name short\n\t * DD - day name long\n\t * m  - month of year (no leading zero)\n\t * mm - month of year (two digit)\n\t * M  - month name short\n\t * MM - month name long\n\t * y  - year (two digit)\n\t * yy - year (four digit)\n\t * @ - Unix timestamp (ms since 01/01/1970)\n\t * ! - Windows ticks (100ns since 01/01/0001)\n\t * \"...\" - literal text\n\t * '' - single quote\n\t *\n\t * @param  format string - the desired format of the date\n\t * @param  date Date - the date value to format\n\t * @param  settings Object - attributes include:\n\t *\t\t\t\t\tdayNamesShort\tstring[7] - abbreviated names of the days from Sunday (optional)\n\t *\t\t\t\t\tdayNames\t\tstring[7] - names of the days from Sunday (optional)\n\t *\t\t\t\t\tmonthNamesShort string[12] - abbreviated names of the months (optional)\n\t *\t\t\t\t\tmonthNames\t\tstring[12] - names of the months (optional)\n\t * @return  string - the date in the above format\n\t */\n\tformatDate: function (format, date, settings) {\n\t\tif (!date) {\n\t\t\treturn \"\";\n\t\t}\n\n\t\tvar iFormat,\n\t\t\tdayNamesShort = (settings ? settings.dayNamesShort : null) || this._defaults.dayNamesShort,\n\t\t\tdayNames = (settings ? settings.dayNames : null) || this._defaults.dayNames,\n\t\t\tmonthNamesShort = (settings ? settings.monthNamesShort : null) || this._defaults.monthNamesShort,\n\t\t\tmonthNames = (settings ? settings.monthNames : null) || this._defaults.monthNames,\n\t\t\t// Check whether a format character is doubled\n\t\t\tlookAhead = function(match) {\n\t\t\t\tvar matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);\n\t\t\t\tif (matches) {\n\t\t\t\t\tiFormat++;\n\t\t\t\t}\n\t\t\t\treturn matches;\n\t\t\t},\n\t\t\t// Format a number, with leading zero if necessary\n\t\t\tformatNumber = function(match, value, len) {\n\t\t\t\tvar num = \"\" + value;\n\t\t\t\tif (lookAhead(match)) {\n\t\t\t\t\twhile (num.length < len) {\n\t\t\t\t\t\tnum = \"0\" + num;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn num;\n\t\t\t},\n\t\t\t// Format a name, short or long as requested\n\t\t\tformatName = function(match, value, shortNames, longNames) {\n\t\t\t\treturn (lookAhead(match) ? longNames[value] : shortNames[value]);\n\t\t\t},\n\t\t\toutput = \"\",\n\t\t\tliteral = false;\n\n\t\tif (date) {\n\t\t\tfor (iFormat = 0; iFormat < format.length; iFormat++) {\n\t\t\t\tif (literal) {\n\t\t\t\t\tif (format.charAt(iFormat) === \"'\" && !lookAhead(\"'\")) {\n\t\t\t\t\t\tliteral = false;\n\t\t\t\t\t} else {\n\t\t\t\t\t\toutput += format.charAt(iFormat);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tswitch (format.charAt(iFormat)) {\n\t\t\t\t\t\tcase \"d\":\n\t\t\t\t\t\t\toutput += formatNumber(\"d\", date.getDate(), 2);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"D\":\n\t\t\t\t\t\t\toutput += formatName(\"D\", date.getDay(), dayNamesShort, dayNames);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"o\":\n\t\t\t\t\t\t\toutput += formatNumber(\"o\",\n\t\t\t\t\t\t\t\tMath.round((new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() - new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"m\":\n\t\t\t\t\t\t\toutput += formatNumber(\"m\", date.getMonth() + 1, 2);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"M\":\n\t\t\t\t\t\t\toutput += formatName(\"M\", date.getMonth(), monthNamesShort, monthNames);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"y\":\n\t\t\t\t\t\t\toutput += (lookAhead(\"y\") ? date.getFullYear() :\n\t\t\t\t\t\t\t\t(date.getYear() % 100 < 10 ? \"0\" : \"\") + date.getYear() % 100);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"@\":\n\t\t\t\t\t\t\toutput += date.getTime();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"!\":\n\t\t\t\t\t\t\toutput += date.getTime() * 10000 + this._ticksTo1970;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"'\":\n\t\t\t\t\t\t\tif (lookAhead(\"'\")) {\n\t\t\t\t\t\t\t\toutput += \"'\";\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tliteral = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\toutput += format.charAt(iFormat);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn output;\n\t},\n\n\t/* Extract all possible characters from the date format. */\n\t_possibleChars: function (format) {\n\t\tvar iFormat,\n\t\t\tchars = \"\",\n\t\t\tliteral = false,\n\t\t\t// Check whether a format character is doubled\n\t\t\tlookAhead = function(match) {\n\t\t\t\tvar matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);\n\t\t\t\tif (matches) {\n\t\t\t\t\tiFormat++;\n\t\t\t\t}\n\t\t\t\treturn matches;\n\t\t\t};\n\n\t\tfor (iFormat = 0; iFormat < format.length; iFormat++) {\n\t\t\tif (literal) {\n\t\t\t\tif (format.charAt(iFormat) === \"'\" && !lookAhead(\"'\")) {\n\t\t\t\t\tliteral = false;\n\t\t\t\t} else {\n\t\t\t\t\tchars += format.charAt(iFormat);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tswitch (format.charAt(iFormat)) {\n\t\t\t\t\tcase \"d\": case \"m\": case \"y\": case \"@\":\n\t\t\t\t\t\tchars += \"0123456789\";\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase \"D\": case \"M\":\n\t\t\t\t\t\treturn null; // Accept anything\n\t\t\t\t\tcase \"'\":\n\t\t\t\t\t\tif (lookAhead(\"'\")) {\n\t\t\t\t\t\t\tchars += \"'\";\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tliteral = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault:\n\t\t\t\t\t\tchars += format.charAt(iFormat);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn chars;\n\t},\n\n\t/* Get a setting value, defaulting if necessary. */\n\t_get: function(inst, name) {\n\t\treturn inst.settings[name] !== undefined ?\n\t\t\tinst.settings[name] : this._defaults[name];\n\t},\n\n\t/* Parse existing date and initialise date picker. */\n\t_setDateFromField: function(inst, noDefault) {\n\t\tif (inst.input.val() === inst.lastVal) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar dateFormat = this._get(inst, \"dateFormat\"),\n\t\t\tdates = inst.lastVal = inst.input ? inst.input.val() : null,\n\t\t\tdefaultDate = this._getDefaultDate(inst),\n\t\t\tdate = defaultDate,\n\t\t\tsettings = this._getFormatConfig(inst);\n\n\t\ttry {\n\t\t\tdate = this.parseDate(dateFormat, dates, settings) || defaultDate;\n\t\t} catch (event) {\n\t\t\tdates = (noDefault ? \"\" : dates);\n\t\t}\n\t\tinst.selectedDay = date.getDate();\n\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\n\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\n\t\tinst.currentDay = (dates ? date.getDate() : 0);\n\t\tinst.currentMonth = (dates ? date.getMonth() : 0);\n\t\tinst.currentYear = (dates ? date.getFullYear() : 0);\n\t\tthis._adjustInstDate(inst);\n\t},\n\n\t/* Retrieve the default date shown on opening. */\n\t_getDefaultDate: function(inst) {\n\t\treturn this._restrictMinMax(inst,\n\t\t\tthis._determineDate(inst, this._get(inst, \"defaultDate\"), new Date()));\n\t},\n\n\t/* A date may be specified as an exact value or a relative one. */\n\t_determineDate: function(inst, date, defaultDate) {\n\t\tvar offsetNumeric = function(offset) {\n\t\t\t\tvar date = new Date();\n\t\t\t\tdate.setDate(date.getDate() + offset);\n\t\t\t\treturn date;\n\t\t\t},\n\t\t\toffsetString = function(offset) {\n\t\t\t\ttry {\n\t\t\t\t\treturn $.datepicker.parseDate($.datepicker._get(inst, \"dateFormat\"),\n\t\t\t\t\t\toffset, $.datepicker._getFormatConfig(inst));\n\t\t\t\t}\n\t\t\t\tcatch (e) {\n\t\t\t\t\t// Ignore\n\t\t\t\t}\n\n\t\t\t\tvar date = (offset.toLowerCase().match(/^c/) ?\n\t\t\t\t\t$.datepicker._getDate(inst) : null) || new Date(),\n\t\t\t\t\tyear = date.getFullYear(),\n\t\t\t\t\tmonth = date.getMonth(),\n\t\t\t\t\tday = date.getDate(),\n\t\t\t\t\tpattern = /([+\\-]?[0-9]+)\\s*(d|D|w|W|m|M|y|Y)?/g,\n\t\t\t\t\tmatches = pattern.exec(offset);\n\n\t\t\t\twhile (matches) {\n\t\t\t\t\tswitch (matches[2] || \"d\") {\n\t\t\t\t\t\tcase \"d\" : case \"D\" :\n\t\t\t\t\t\t\tday += parseInt(matches[1],10); break;\n\t\t\t\t\t\tcase \"w\" : case \"W\" :\n\t\t\t\t\t\t\tday += parseInt(matches[1],10) * 7; break;\n\t\t\t\t\t\tcase \"m\" : case \"M\" :\n\t\t\t\t\t\t\tmonth += parseInt(matches[1],10);\n\t\t\t\t\t\t\tday = Math.min(day, $.datepicker._getDaysInMonth(year, month));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase \"y\": case \"Y\" :\n\t\t\t\t\t\t\tyear += parseInt(matches[1],10);\n\t\t\t\t\t\t\tday = Math.min(day, $.datepicker._getDaysInMonth(year, month));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tmatches = pattern.exec(offset);\n\t\t\t\t}\n\t\t\t\treturn new Date(year, month, day);\n\t\t\t},\n\t\t\tnewDate = (date == null || date === \"\" ? defaultDate : (typeof date === \"string\" ? offsetString(date) :\n\t\t\t\t(typeof date === \"number\" ? (isNaN(date) ? defaultDate : offsetNumeric(date)) : new Date(date.getTime()))));\n\n\t\tnewDate = (newDate && newDate.toString() === \"Invalid Date\" ? defaultDate : newDate);\n\t\tif (newDate) {\n\t\t\tnewDate.setHours(0);\n\t\t\tnewDate.setMinutes(0);\n\t\t\tnewDate.setSeconds(0);\n\t\t\tnewDate.setMilliseconds(0);\n\t\t}\n\t\treturn this._daylightSavingAdjust(newDate);\n\t},\n\n\t/* Handle switch to/from daylight saving.\n\t * Hours may be non-zero on daylight saving cut-over:\n\t * > 12 when midnight changeover, but then cannot generate\n\t * midnight datetime, so jump to 1AM, otherwise reset.\n\t * @param  date  (Date) the date to check\n\t * @return  (Date) the corrected date\n\t */\n\t_daylightSavingAdjust: function(date) {\n\t\tif (!date) {\n\t\t\treturn null;\n\t\t}\n\t\tdate.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);\n\t\treturn date;\n\t},\n\n\t/* Set the date(s) directly. */\n\t_setDate: function(inst, date, noChange) {\n\t\tvar clear = !date,\n\t\t\torigMonth = inst.selectedMonth,\n\t\t\torigYear = inst.selectedYear,\n\t\t\tnewDate = this._restrictMinMax(inst, this._determineDate(inst, date, new Date()));\n\n\t\tinst.selectedDay = inst.currentDay = newDate.getDate();\n\t\tinst.drawMonth = inst.selectedMonth = inst.currentMonth = newDate.getMonth();\n\t\tinst.drawYear = inst.selectedYear = inst.currentYear = newDate.getFullYear();\n\t\tif ((origMonth !== inst.selectedMonth || origYear !== inst.selectedYear) && !noChange) {\n\t\t\tthis._notifyChange(inst);\n\t\t}\n\t\tthis._adjustInstDate(inst);\n\t\tif (inst.input) {\n\t\t\tinst.input.val(clear ? \"\" : this._formatDate(inst));\n\t\t}\n\t},\n\n\t/* Retrieve the date(s) directly. */\n\t_getDate: function(inst) {\n\t\tvar startDate = (!inst.currentYear || (inst.input && inst.input.val() === \"\") ? null :\n\t\t\tthis._daylightSavingAdjust(new Date(\n\t\t\tinst.currentYear, inst.currentMonth, inst.currentDay)));\n\t\t\treturn startDate;\n\t},\n\n\t/* Attach the onxxx handlers.  These are declared statically so\n\t * they work with static code transformers like Caja.\n\t */\n\t_attachHandlers: function(inst) {\n\t\tvar stepMonths = this._get(inst, \"stepMonths\"),\n\t\t\tid = \"#\" + inst.id.replace( /\\\\\\\\/g, \"\\\\\" );\n\t\tinst.dpDiv.find(\"[data-handler]\").map(function () {\n\t\t\tvar handler = {\n\t\t\t\tprev: function () {\n\t\t\t\t\t$.datepicker._adjustDate(id, -stepMonths, \"M\");\n\t\t\t\t},\n\t\t\t\tnext: function () {\n\t\t\t\t\t$.datepicker._adjustDate(id, +stepMonths, \"M\");\n\t\t\t\t},\n\t\t\t\thide: function () {\n\t\t\t\t\t$.datepicker._hideDatepicker();\n\t\t\t\t},\n\t\t\t\ttoday: function () {\n\t\t\t\t\t$.datepicker._gotoToday(id);\n\t\t\t\t},\n\t\t\t\tselectDay: function () {\n\t\t\t\t\t$.datepicker._selectDay(id, +this.getAttribute(\"data-month\"), +this.getAttribute(\"data-year\"), this);\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t\tselectMonth: function () {\n\t\t\t\t\t$.datepicker._selectMonthYear(id, this, \"M\");\n\t\t\t\t\treturn false;\n\t\t\t\t},\n\t\t\t\tselectYear: function () {\n\t\t\t\t\t$.datepicker._selectMonthYear(id, this, \"Y\");\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t};\n\t\t\t$(this).bind(this.getAttribute(\"data-event\"), handler[this.getAttribute(\"data-handler\")]);\n\t\t});\n\t},\n\n\t/* Generate the HTML for the current state of the date picker. */\n\t_generateHTML: function(inst) {\n\t\tvar maxDraw, prevText, prev, nextText, next, currentText, gotoDate,\n\t\t\tcontrols, buttonPanel, firstDay, showWeek, dayNames, dayNamesMin,\n\t\t\tmonthNames, monthNamesShort, beforeShowDay, showOtherMonths,\n\t\t\tselectOtherMonths, defaultDate, html, dow, row, group, col, selectedDate,\n\t\t\tcornerClass, calender, thead, day, daysInMonth, leadDays, curRows, numRows,\n\t\t\tprintDate, dRow, tbody, daySettings, otherMonth, unselectable,\n\t\t\ttempDate = new Date(),\n\t\t\ttoday = this._daylightSavingAdjust(\n\t\t\t\tnew Date(tempDate.getFullYear(), tempDate.getMonth(), tempDate.getDate())), // clear time\n\t\t\tisRTL = this._get(inst, \"isRTL\"),\n\t\t\tshowButtonPanel = this._get(inst, \"showButtonPanel\"),\n\t\t\thideIfNoPrevNext = this._get(inst, \"hideIfNoPrevNext\"),\n\t\t\tnavigationAsDateFormat = this._get(inst, \"navigationAsDateFormat\"),\n\t\t\tnumMonths = this._getNumberOfMonths(inst),\n\t\t\tshowCurrentAtPos = this._get(inst, \"showCurrentAtPos\"),\n\t\t\tstepMonths = this._get(inst, \"stepMonths\"),\n\t\t\tisMultiMonth = (numMonths[0] !== 1 || numMonths[1] !== 1),\n\t\t\tcurrentDate = this._daylightSavingAdjust((!inst.currentDay ? new Date(9999, 9, 9) :\n\t\t\t\tnew Date(inst.currentYear, inst.currentMonth, inst.currentDay))),\n\t\t\tminDate = this._getMinMaxDate(inst, \"min\"),\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\"),\n\t\t\tdrawMonth = inst.drawMonth - showCurrentAtPos,\n\t\t\tdrawYear = inst.drawYear;\n\n\t\tif (drawMonth < 0) {\n\t\t\tdrawMonth += 12;\n\t\t\tdrawYear--;\n\t\t}\n\t\tif (maxDate) {\n\t\t\tmaxDraw = this._daylightSavingAdjust(new Date(maxDate.getFullYear(),\n\t\t\t\tmaxDate.getMonth() - (numMonths[0] * numMonths[1]) + 1, maxDate.getDate()));\n\t\t\tmaxDraw = (minDate && maxDraw < minDate ? minDate : maxDraw);\n\t\t\twhile (this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1)) > maxDraw) {\n\t\t\t\tdrawMonth--;\n\t\t\t\tif (drawMonth < 0) {\n\t\t\t\t\tdrawMonth = 11;\n\t\t\t\t\tdrawYear--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tinst.drawMonth = drawMonth;\n\t\tinst.drawYear = drawYear;\n\n\t\tprevText = this._get(inst, \"prevText\");\n\t\tprevText = (!navigationAsDateFormat ? prevText : this.formatDate(prevText,\n\t\t\tthis._daylightSavingAdjust(new Date(drawYear, drawMonth - stepMonths, 1)),\n\t\t\tthis._getFormatConfig(inst)));\n\n\t\tprev = (this._canAdjustMonth(inst, -1, drawYear, drawMonth) ?\n\t\t\t\"<a class='ui-datepicker-prev ui-corner-all' data-handler='prev' data-event='click'\" +\n\t\t\t\" title='\" + prevText + \"'><span class='ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"e\" : \"w\") + \"'>\" + prevText + \"</span></a>\" :\n\t\t\t(hideIfNoPrevNext ? \"\" : \"<a class='ui-datepicker-prev ui-corner-all ui-state-disabled' title='\"+ prevText +\"'><span class='ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"e\" : \"w\") + \"'>\" + prevText + \"</span></a>\"));\n\n\t\tnextText = this._get(inst, \"nextText\");\n\t\tnextText = (!navigationAsDateFormat ? nextText : this.formatDate(nextText,\n\t\t\tthis._daylightSavingAdjust(new Date(drawYear, drawMonth + stepMonths, 1)),\n\t\t\tthis._getFormatConfig(inst)));\n\n\t\tnext = (this._canAdjustMonth(inst, +1, drawYear, drawMonth) ?\n\t\t\t\"<a class='ui-datepicker-next ui-corner-all' data-handler='next' data-event='click'\" +\n\t\t\t\" title='\" + nextText + \"'><span class='ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"w\" : \"e\") + \"'>\" + nextText + \"</span></a>\" :\n\t\t\t(hideIfNoPrevNext ? \"\" : \"<a class='ui-datepicker-next ui-corner-all ui-state-disabled' title='\"+ nextText + \"'><span class='ui-icon ui-icon-circle-triangle-\" + ( isRTL ? \"w\" : \"e\") + \"'>\" + nextText + \"</span></a>\"));\n\n\t\tcurrentText = this._get(inst, \"currentText\");\n\t\tgotoDate = (this._get(inst, \"gotoCurrent\") && inst.currentDay ? currentDate : today);\n\t\tcurrentText = (!navigationAsDateFormat ? currentText :\n\t\t\tthis.formatDate(currentText, gotoDate, this._getFormatConfig(inst)));\n\n\t\tcontrols = (!inst.inline ? \"<button type='button' class='ui-datepicker-close ui-state-default ui-priority-primary ui-corner-all' data-handler='hide' data-event='click'>\" +\n\t\t\tthis._get(inst, \"closeText\") + \"</button>\" : \"\");\n\n\t\tbuttonPanel = (showButtonPanel) ? \"<div class='ui-datepicker-buttonpane ui-widget-content'>\" + (isRTL ? controls : \"\") +\n\t\t\t(this._isInRange(inst, gotoDate) ? \"<button type='button' class='ui-datepicker-current ui-state-default ui-priority-secondary ui-corner-all' data-handler='today' data-event='click'\" +\n\t\t\t\">\" + currentText + \"</button>\" : \"\") + (isRTL ? \"\" : controls) + \"</div>\" : \"\";\n\n\t\tfirstDay = parseInt(this._get(inst, \"firstDay\"),10);\n\t\tfirstDay = (isNaN(firstDay) ? 0 : firstDay);\n\n\t\tshowWeek = this._get(inst, \"showWeek\");\n\t\tdayNames = this._get(inst, \"dayNames\");\n\t\tdayNamesMin = this._get(inst, \"dayNamesMin\");\n\t\tmonthNames = this._get(inst, \"monthNames\");\n\t\tmonthNamesShort = this._get(inst, \"monthNamesShort\");\n\t\tbeforeShowDay = this._get(inst, \"beforeShowDay\");\n\t\tshowOtherMonths = this._get(inst, \"showOtherMonths\");\n\t\tselectOtherMonths = this._get(inst, \"selectOtherMonths\");\n\t\tdefaultDate = this._getDefaultDate(inst);\n\t\thtml = \"\";\n\t\tdow;\n\t\tfor (row = 0; row < numMonths[0]; row++) {\n\t\t\tgroup = \"\";\n\t\t\tthis.maxRows = 4;\n\t\t\tfor (col = 0; col < numMonths[1]; col++) {\n\t\t\t\tselectedDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, inst.selectedDay));\n\t\t\t\tcornerClass = \" ui-corner-all\";\n\t\t\t\tcalender = \"\";\n\t\t\t\tif (isMultiMonth) {\n\t\t\t\t\tcalender += \"<div class='ui-datepicker-group\";\n\t\t\t\t\tif (numMonths[1] > 1) {\n\t\t\t\t\t\tswitch (col) {\n\t\t\t\t\t\t\tcase 0: calender += \" ui-datepicker-group-first\";\n\t\t\t\t\t\t\t\tcornerClass = \" ui-corner-\" + (isRTL ? \"right\" : \"left\"); break;\n\t\t\t\t\t\t\tcase numMonths[1]-1: calender += \" ui-datepicker-group-last\";\n\t\t\t\t\t\t\t\tcornerClass = \" ui-corner-\" + (isRTL ? \"left\" : \"right\"); break;\n\t\t\t\t\t\t\tdefault: calender += \" ui-datepicker-group-middle\"; cornerClass = \"\"; break;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcalender += \"'>\";\n\t\t\t\t}\n\t\t\t\tcalender += \"<div class='ui-datepicker-header ui-widget-header ui-helper-clearfix\" + cornerClass + \"'>\" +\n\t\t\t\t\t(/all|left/.test(cornerClass) && row === 0 ? (isRTL ? next : prev) : \"\") +\n\t\t\t\t\t(/all|right/.test(cornerClass) && row === 0 ? (isRTL ? prev : next) : \"\") +\n\t\t\t\t\tthis._generateMonthYearHeader(inst, drawMonth, drawYear, minDate, maxDate,\n\t\t\t\t\trow > 0 || col > 0, monthNames, monthNamesShort) + // draw month headers\n\t\t\t\t\t\"</div><table class='ui-datepicker-calendar'><thead>\" +\n\t\t\t\t\t\"<tr>\";\n\t\t\t\tthead = (showWeek ? \"<th class='ui-datepicker-week-col'>\" + this._get(inst, \"weekHeader\") + \"</th>\" : \"\");\n\t\t\t\tfor (dow = 0; dow < 7; dow++) { // days of the week\n\t\t\t\t\tday = (dow + firstDay) % 7;\n\t\t\t\t\tthead += \"<th scope='col'\" + ((dow + firstDay + 6) % 7 >= 5 ? \" class='ui-datepicker-week-end'\" : \"\") + \">\" +\n\t\t\t\t\t\t\"<span title='\" + dayNames[day] + \"'>\" + dayNamesMin[day] + \"</span></th>\";\n\t\t\t\t}\n\t\t\t\tcalender += thead + \"</tr></thead><tbody>\";\n\t\t\t\tdaysInMonth = this._getDaysInMonth(drawYear, drawMonth);\n\t\t\t\tif (drawYear === inst.selectedYear && drawMonth === inst.selectedMonth) {\n\t\t\t\t\tinst.selectedDay = Math.min(inst.selectedDay, daysInMonth);\n\t\t\t\t}\n\t\t\t\tleadDays = (this._getFirstDayOfMonth(drawYear, drawMonth) - firstDay + 7) % 7;\n\t\t\t\tcurRows = Math.ceil((leadDays + daysInMonth) / 7); // calculate the number of rows to generate\n\t\t\t\tnumRows = (isMultiMonth ? this.maxRows > curRows ? this.maxRows : curRows : curRows); //If multiple months, use the higher number of rows (see #7043)\n\t\t\t\tthis.maxRows = numRows;\n\t\t\t\tprintDate = this._daylightSavingAdjust(new Date(drawYear, drawMonth, 1 - leadDays));\n\t\t\t\tfor (dRow = 0; dRow < numRows; dRow++) { // create date picker rows\n\t\t\t\t\tcalender += \"<tr>\";\n\t\t\t\t\ttbody = (!showWeek ? \"\" : \"<td class='ui-datepicker-week-col'>\" +\n\t\t\t\t\t\tthis._get(inst, \"calculateWeek\")(printDate) + \"</td>\");\n\t\t\t\t\tfor (dow = 0; dow < 7; dow++) { // create date picker days\n\t\t\t\t\t\tdaySettings = (beforeShowDay ?\n\t\t\t\t\t\t\tbeforeShowDay.apply((inst.input ? inst.input[0] : null), [printDate]) : [true, \"\"]);\n\t\t\t\t\t\totherMonth = (printDate.getMonth() !== drawMonth);\n\t\t\t\t\t\tunselectable = (otherMonth && !selectOtherMonths) || !daySettings[0] ||\n\t\t\t\t\t\t\t(minDate && printDate < minDate) || (maxDate && printDate > maxDate);\n\t\t\t\t\t\ttbody += \"<td class='\" +\n\t\t\t\t\t\t\t((dow + firstDay + 6) % 7 >= 5 ? \" ui-datepicker-week-end\" : \"\") + // highlight weekends\n\t\t\t\t\t\t\t(otherMonth ? \" ui-datepicker-other-month\" : \"\") + // highlight days from other months\n\t\t\t\t\t\t\t((printDate.getTime() === selectedDate.getTime() && drawMonth === inst.selectedMonth && inst._keyEvent) || // user pressed key\n\t\t\t\t\t\t\t(defaultDate.getTime() === printDate.getTime() && defaultDate.getTime() === selectedDate.getTime()) ?\n\t\t\t\t\t\t\t// or defaultDate is current printedDate and defaultDate is selectedDate\n\t\t\t\t\t\t\t\" \" + this._dayOverClass : \"\") + // highlight selected day\n\t\t\t\t\t\t\t(unselectable ? \" \" + this._unselectableClass + \" ui-state-disabled\": \"\") +  // highlight unselectable days\n\t\t\t\t\t\t\t(otherMonth && !showOtherMonths ? \"\" : \" \" + daySettings[1] + // highlight custom dates\n\t\t\t\t\t\t\t(printDate.getTime() === currentDate.getTime() ? \" \" + this._currentClass : \"\") + // highlight selected day\n\t\t\t\t\t\t\t(printDate.getTime() === today.getTime() ? \" ui-datepicker-today\" : \"\")) + \"'\" + // highlight today (if different)\n\t\t\t\t\t\t\t((!otherMonth || showOtherMonths) && daySettings[2] ? \" title='\" + daySettings[2].replace(/'/g, \"&#39;\") + \"'\" : \"\") + // cell title\n\t\t\t\t\t\t\t(unselectable ? \"\" : \" data-handler='selectDay' data-event='click' data-month='\" + printDate.getMonth() + \"' data-year='\" + printDate.getFullYear() + \"'\") + \">\" + // actions\n\t\t\t\t\t\t\t(otherMonth && !showOtherMonths ? \"&#xa0;\" : // display for other months\n\t\t\t\t\t\t\t(unselectable ? \"<span class='ui-state-default'>\" + printDate.getDate() + \"</span>\" : \"<a class='ui-state-default\" +\n\t\t\t\t\t\t\t(printDate.getTime() === today.getTime() ? \" ui-state-highlight\" : \"\") +\n\t\t\t\t\t\t\t(printDate.getTime() === currentDate.getTime() ? \" ui-state-active\" : \"\") + // highlight selected day\n\t\t\t\t\t\t\t(otherMonth ? \" ui-priority-secondary\" : \"\") + // distinguish dates from other months\n\t\t\t\t\t\t\t\"' href='#'>\" + printDate.getDate() + \"</a>\")) + \"</td>\"; // display selectable date\n\t\t\t\t\t\tprintDate.setDate(printDate.getDate() + 1);\n\t\t\t\t\t\tprintDate = this._daylightSavingAdjust(printDate);\n\t\t\t\t\t}\n\t\t\t\t\tcalender += tbody + \"</tr>\";\n\t\t\t\t}\n\t\t\t\tdrawMonth++;\n\t\t\t\tif (drawMonth > 11) {\n\t\t\t\t\tdrawMonth = 0;\n\t\t\t\t\tdrawYear++;\n\t\t\t\t}\n\t\t\t\tcalender += \"</tbody></table>\" + (isMultiMonth ? \"</div>\" +\n\t\t\t\t\t\t\t((numMonths[0] > 0 && col === numMonths[1]-1) ? \"<div class='ui-datepicker-row-break'></div>\" : \"\") : \"\");\n\t\t\t\tgroup += calender;\n\t\t\t}\n\t\t\thtml += group;\n\t\t}\n\t\thtml += buttonPanel;\n\t\tinst._keyEvent = false;\n\t\treturn html;\n\t},\n\n\t/* Generate the month and year header. */\n\t_generateMonthYearHeader: function(inst, drawMonth, drawYear, minDate, maxDate,\n\t\t\tsecondary, monthNames, monthNamesShort) {\n\n\t\tvar inMinYear, inMaxYear, month, years, thisYear, determineYear, year, endYear,\n\t\t\tchangeMonth = this._get(inst, \"changeMonth\"),\n\t\t\tchangeYear = this._get(inst, \"changeYear\"),\n\t\t\tshowMonthAfterYear = this._get(inst, \"showMonthAfterYear\"),\n\t\t\thtml = \"<div class='ui-datepicker-title'>\",\n\t\t\tmonthHtml = \"\";\n\n\t\t// month selection\n\t\tif (secondary || !changeMonth) {\n\t\t\tmonthHtml += \"<span class='ui-datepicker-month'>\" + monthNames[drawMonth] + \"</span>\";\n\t\t} else {\n\t\t\tinMinYear = (minDate && minDate.getFullYear() === drawYear);\n\t\t\tinMaxYear = (maxDate && maxDate.getFullYear() === drawYear);\n\t\t\tmonthHtml += \"<select class='ui-datepicker-month' data-handler='selectMonth' data-event='change'>\";\n\t\t\tfor ( month = 0; month < 12; month++) {\n\t\t\t\tif ((!inMinYear || month >= minDate.getMonth()) && (!inMaxYear || month <= maxDate.getMonth())) {\n\t\t\t\t\tmonthHtml += \"<option value='\" + month + \"'\" +\n\t\t\t\t\t\t(month === drawMonth ? \" selected='selected'\" : \"\") +\n\t\t\t\t\t\t\">\" + monthNamesShort[month] + \"</option>\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tmonthHtml += \"</select>\";\n\t\t}\n\n\t\tif (!showMonthAfterYear) {\n\t\t\thtml += monthHtml + (secondary || !(changeMonth && changeYear) ? \"&#xa0;\" : \"\");\n\t\t}\n\n\t\t// year selection\n\t\tif ( !inst.yearshtml ) {\n\t\t\tinst.yearshtml = \"\";\n\t\t\tif (secondary || !changeYear) {\n\t\t\t\thtml += \"<span class='ui-datepicker-year'>\" + drawYear + \"</span>\";\n\t\t\t} else {\n\t\t\t\t// determine range of years to display\n\t\t\t\tyears = this._get(inst, \"yearRange\").split(\":\");\n\t\t\t\tthisYear = new Date().getFullYear();\n\t\t\t\tdetermineYear = function(value) {\n\t\t\t\t\tvar year = (value.match(/c[+\\-].*/) ? drawYear + parseInt(value.substring(1), 10) :\n\t\t\t\t\t\t(value.match(/[+\\-].*/) ? thisYear + parseInt(value, 10) :\n\t\t\t\t\t\tparseInt(value, 10)));\n\t\t\t\t\treturn (isNaN(year) ? thisYear : year);\n\t\t\t\t};\n\t\t\t\tyear = determineYear(years[0]);\n\t\t\t\tendYear = Math.max(year, determineYear(years[1] || \"\"));\n\t\t\t\tyear = (minDate ? Math.max(year, minDate.getFullYear()) : year);\n\t\t\t\tendYear = (maxDate ? Math.min(endYear, maxDate.getFullYear()) : endYear);\n\t\t\t\tinst.yearshtml += \"<select class='ui-datepicker-year' data-handler='selectYear' data-event='change'>\";\n\t\t\t\tfor (; year <= endYear; year++) {\n\t\t\t\t\tinst.yearshtml += \"<option value='\" + year + \"'\" +\n\t\t\t\t\t\t(year === drawYear ? \" selected='selected'\" : \"\") +\n\t\t\t\t\t\t\">\" + year + \"</option>\";\n\t\t\t\t}\n\t\t\t\tinst.yearshtml += \"</select>\";\n\n\t\t\t\thtml += inst.yearshtml;\n\t\t\t\tinst.yearshtml = null;\n\t\t\t}\n\t\t}\n\n\t\thtml += this._get(inst, \"yearSuffix\");\n\t\tif (showMonthAfterYear) {\n\t\t\thtml += (secondary || !(changeMonth && changeYear) ? \"&#xa0;\" : \"\") + monthHtml;\n\t\t}\n\t\thtml += \"</div>\"; // Close datepicker_header\n\t\treturn html;\n\t},\n\n\t/* Adjust one of the date sub-fields. */\n\t_adjustInstDate: function(inst, offset, period) {\n\t\tvar year = inst.drawYear + (period === \"Y\" ? offset : 0),\n\t\t\tmonth = inst.drawMonth + (period === \"M\" ? offset : 0),\n\t\t\tday = Math.min(inst.selectedDay, this._getDaysInMonth(year, month)) + (period === \"D\" ? offset : 0),\n\t\t\tdate = this._restrictMinMax(inst, this._daylightSavingAdjust(new Date(year, month, day)));\n\n\t\tinst.selectedDay = date.getDate();\n\t\tinst.drawMonth = inst.selectedMonth = date.getMonth();\n\t\tinst.drawYear = inst.selectedYear = date.getFullYear();\n\t\tif (period === \"M\" || period === \"Y\") {\n\t\t\tthis._notifyChange(inst);\n\t\t}\n\t},\n\n\t/* Ensure a date is within any min/max bounds. */\n\t_restrictMinMax: function(inst, date) {\n\t\tvar minDate = this._getMinMaxDate(inst, \"min\"),\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\"),\n\t\t\tnewDate = (minDate && date < minDate ? minDate : date);\n\t\treturn (maxDate && newDate > maxDate ? maxDate : newDate);\n\t},\n\n\t/* Notify change of month/year. */\n\t_notifyChange: function(inst) {\n\t\tvar onChange = this._get(inst, \"onChangeMonthYear\");\n\t\tif (onChange) {\n\t\t\tonChange.apply((inst.input ? inst.input[0] : null),\n\t\t\t\t[inst.selectedYear, inst.selectedMonth + 1, inst]);\n\t\t}\n\t},\n\n\t/* Determine the number of months to show. */\n\t_getNumberOfMonths: function(inst) {\n\t\tvar numMonths = this._get(inst, \"numberOfMonths\");\n\t\treturn (numMonths == null ? [1, 1] : (typeof numMonths === \"number\" ? [1, numMonths] : numMonths));\n\t},\n\n\t/* Determine the current maximum date - ensure no time components are set. */\n\t_getMinMaxDate: function(inst, minMax) {\n\t\treturn this._determineDate(inst, this._get(inst, minMax + \"Date\"), null);\n\t},\n\n\t/* Find the number of days in a given month. */\n\t_getDaysInMonth: function(year, month) {\n\t\treturn 32 - this._daylightSavingAdjust(new Date(year, month, 32)).getDate();\n\t},\n\n\t/* Find the day of the week of the first of a month. */\n\t_getFirstDayOfMonth: function(year, month) {\n\t\treturn new Date(year, month, 1).getDay();\n\t},\n\n\t/* Determines if we should allow a \"next/prev\" month display change. */\n\t_canAdjustMonth: function(inst, offset, curYear, curMonth) {\n\t\tvar numMonths = this._getNumberOfMonths(inst),\n\t\t\tdate = this._daylightSavingAdjust(new Date(curYear,\n\t\t\tcurMonth + (offset < 0 ? offset : numMonths[0] * numMonths[1]), 1));\n\n\t\tif (offset < 0) {\n\t\t\tdate.setDate(this._getDaysInMonth(date.getFullYear(), date.getMonth()));\n\t\t}\n\t\treturn this._isInRange(inst, date);\n\t},\n\n\t/* Is the given date in the accepted range? */\n\t_isInRange: function(inst, date) {\n\t\tvar yearSplit, currentYear,\n\t\t\tminDate = this._getMinMaxDate(inst, \"min\"),\n\t\t\tmaxDate = this._getMinMaxDate(inst, \"max\"),\n\t\t\tminYear = null,\n\t\t\tmaxYear = null,\n\t\t\tyears = this._get(inst, \"yearRange\");\n\t\t\tif (years){\n\t\t\t\tyearSplit = years.split(\":\");\n\t\t\t\tcurrentYear = new Date().getFullYear();\n\t\t\t\tminYear = parseInt(yearSplit[0], 10);\n\t\t\t\tmaxYear = parseInt(yearSplit[1], 10);\n\t\t\t\tif ( yearSplit[0].match(/[+\\-].*/) ) {\n\t\t\t\t\tminYear += currentYear;\n\t\t\t\t}\n\t\t\t\tif ( yearSplit[1].match(/[+\\-].*/) ) {\n\t\t\t\t\tmaxYear += currentYear;\n\t\t\t\t}\n\t\t\t}\n\n\t\treturn ((!minDate || date.getTime() >= minDate.getTime()) &&\n\t\t\t(!maxDate || date.getTime() <= maxDate.getTime()) &&\n\t\t\t(!minYear || date.getFullYear() >= minYear) &&\n\t\t\t(!maxYear || date.getFullYear() <= maxYear));\n\t},\n\n\t/* Provide the configuration settings for formatting/parsing. */\n\t_getFormatConfig: function(inst) {\n\t\tvar shortYearCutoff = this._get(inst, \"shortYearCutoff\");\n\t\tshortYearCutoff = (typeof shortYearCutoff !== \"string\" ? shortYearCutoff :\n\t\t\tnew Date().getFullYear() % 100 + parseInt(shortYearCutoff, 10));\n\t\treturn {shortYearCutoff: shortYearCutoff,\n\t\t\tdayNamesShort: this._get(inst, \"dayNamesShort\"), dayNames: this._get(inst, \"dayNames\"),\n\t\t\tmonthNamesShort: this._get(inst, \"monthNamesShort\"), monthNames: this._get(inst, \"monthNames\")};\n\t},\n\n\t/* Format the given date for display. */\n\t_formatDate: function(inst, day, month, year) {\n\t\tif (!day) {\n\t\t\tinst.currentDay = inst.selectedDay;\n\t\t\tinst.currentMonth = inst.selectedMonth;\n\t\t\tinst.currentYear = inst.selectedYear;\n\t\t}\n\t\tvar date = (day ? (typeof day === \"object\" ? day :\n\t\t\tthis._daylightSavingAdjust(new Date(year, month, day))) :\n\t\t\tthis._daylightSavingAdjust(new Date(inst.currentYear, inst.currentMonth, inst.currentDay)));\n\t\treturn this.formatDate(this._get(inst, \"dateFormat\"), date, this._getFormatConfig(inst));\n\t}\n});\n\n/*\n * Bind hover events for datepicker elements.\n * Done via delegate so the binding only occurs once in the lifetime of the parent div.\n * Global datepicker_instActive, set by _updateDatepicker allows the handlers to find their way back to the active picker.\n */\nfunction datepicker_bindHover(dpDiv) {\n\tvar selector = \"button, .ui-datepicker-prev, .ui-datepicker-next, .ui-datepicker-calendar td a\";\n\treturn dpDiv.delegate(selector, \"mouseout\", function() {\n\t\t\t$(this).removeClass(\"ui-state-hover\");\n\t\t\tif (this.className.indexOf(\"ui-datepicker-prev\") !== -1) {\n\t\t\t\t$(this).removeClass(\"ui-datepicker-prev-hover\");\n\t\t\t}\n\t\t\tif (this.className.indexOf(\"ui-datepicker-next\") !== -1) {\n\t\t\t\t$(this).removeClass(\"ui-datepicker-next-hover\");\n\t\t\t}\n\t\t})\n\t\t.delegate( selector, \"mouseover\", datepicker_handleMouseover );\n}\n\nfunction datepicker_handleMouseover() {\n\tif (!$.datepicker._isDisabledDatepicker( datepicker_instActive.inline? datepicker_instActive.dpDiv.parent()[0] : datepicker_instActive.input[0])) {\n\t\t$(this).parents(\".ui-datepicker-calendar\").find(\"a\").removeClass(\"ui-state-hover\");\n\t\t$(this).addClass(\"ui-state-hover\");\n\t\tif (this.className.indexOf(\"ui-datepicker-prev\") !== -1) {\n\t\t\t$(this).addClass(\"ui-datepicker-prev-hover\");\n\t\t}\n\t\tif (this.className.indexOf(\"ui-datepicker-next\") !== -1) {\n\t\t\t$(this).addClass(\"ui-datepicker-next-hover\");\n\t\t}\n\t}\n}\n\n/* jQuery extend now ignores nulls! */\nfunction datepicker_extendRemove(target, props) {\n\t$.extend(target, props);\n\tfor (var name in props) {\n\t\tif (props[name] == null) {\n\t\t\ttarget[name] = props[name];\n\t\t}\n\t}\n\treturn target;\n}\n\n/* Invoke the datepicker functionality.\n   @param  options  string - a command, optionally followed by additional parameters or\n\t\t\t\t\tObject - settings for attaching new datepicker functionality\n   @return  jQuery object */\n$.fn.datepicker = function(options){\n\n\t/* Verify an empty collection wasn't passed - Fixes #6976 */\n\tif ( !this.length ) {\n\t\treturn this;\n\t}\n\n\t/* Initialise the date picker. */\n\tif (!$.datepicker.initialized) {\n\t\t$(document).mousedown($.datepicker._checkExternalClick);\n\t\t$.datepicker.initialized = true;\n\t}\n\n\t/* Append datepicker main container to body if not exist. */\n\tif ($(\"#\"+$.datepicker._mainDivId).length === 0) {\n\t\t$(\"body\").append($.datepicker.dpDiv);\n\t}\n\n\tvar otherArgs = Array.prototype.slice.call(arguments, 1);\n\tif (typeof options === \"string\" && (options === \"isDisabled\" || options === \"getDate\" || options === \"widget\")) {\n\t\treturn $.datepicker[\"_\" + options + \"Datepicker\"].\n\t\t\tapply($.datepicker, [this[0]].concat(otherArgs));\n\t}\n\tif (options === \"option\" && arguments.length === 2 && typeof arguments[1] === \"string\") {\n\t\treturn $.datepicker[\"_\" + options + \"Datepicker\"].\n\t\t\tapply($.datepicker, [this[0]].concat(otherArgs));\n\t}\n\treturn this.each(function() {\n\t\ttypeof options === \"string\" ?\n\t\t\t$.datepicker[\"_\" + options + \"Datepicker\"].\n\t\t\t\tapply($.datepicker, [this].concat(otherArgs)) :\n\t\t\t$.datepicker._attachDatepicker(this, options);\n\t});\n};\n\n$.datepicker = new Datepicker(); // singleton instance\n$.datepicker.initialized = false;\n$.datepicker.uuid = new Date().getTime();\n$.datepicker.version = \"1.11.4\";\n\nvar datepicker = $.datepicker;\n\n\n/*!\n * jQuery UI Draggable 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/draggable/\n */\n\n\n$.widget(\"ui.draggable\", $.ui.mouse, {\n\tversion: \"1.11.4\",\n\twidgetEventPrefix: \"drag\",\n\toptions: {\n\t\taddClasses: true,\n\t\tappendTo: \"parent\",\n\t\taxis: false,\n\t\tconnectToSortable: false,\n\t\tcontainment: false,\n\t\tcursor: \"auto\",\n\t\tcursorAt: false,\n\t\tgrid: false,\n\t\thandle: false,\n\t\thelper: \"original\",\n\t\tiframeFix: false,\n\t\topacity: false,\n\t\trefreshPositions: false,\n\t\trevert: false,\n\t\trevertDuration: 500,\n\t\tscope: \"default\",\n\t\tscroll: true,\n\t\tscrollSensitivity: 20,\n\t\tscrollSpeed: 20,\n\t\tsnap: false,\n\t\tsnapMode: \"both\",\n\t\tsnapTolerance: 20,\n\t\tstack: false,\n\t\tzIndex: false,\n\n\t\t// callbacks\n\t\tdrag: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\t_create: function() {\n\n\t\tif ( this.options.helper === \"original\" ) {\n\t\t\tthis._setPositionRelative();\n\t\t}\n\t\tif (this.options.addClasses){\n\t\t\tthis.element.addClass(\"ui-draggable\");\n\t\t}\n\t\tif (this.options.disabled){\n\t\t\tthis.element.addClass(\"ui-draggable-disabled\");\n\t\t}\n\t\tthis._setHandleClassName();\n\n\t\tthis._mouseInit();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tthis._super( key, value );\n\t\tif ( key === \"handle\" ) {\n\t\t\tthis._removeHandleClassName();\n\t\t\tthis._setHandleClassName();\n\t\t}\n\t},\n\n\t_destroy: function() {\n\t\tif ( ( this.helper || this.element ).is( \".ui-draggable-dragging\" ) ) {\n\t\t\tthis.destroyOnClear = true;\n\t\t\treturn;\n\t\t}\n\t\tthis.element.removeClass( \"ui-draggable ui-draggable-dragging ui-draggable-disabled\" );\n\t\tthis._removeHandleClassName();\n\t\tthis._mouseDestroy();\n\t},\n\n\t_mouseCapture: function(event) {\n\t\tvar o = this.options;\n\n\t\tthis._blurActiveElement( event );\n\n\t\t// among others, prevent a drag on a resizable-handle\n\t\tif (this.helper || o.disabled || $(event.target).closest(\".ui-resizable-handle\").length > 0) {\n\t\t\treturn false;\n\t\t}\n\n\t\t//Quit if we're not on a valid handle\n\t\tthis.handle = this._getHandle(event);\n\t\tif (!this.handle) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis._blockFrames( o.iframeFix === true ? \"iframe\" : o.iframeFix );\n\n\t\treturn true;\n\n\t},\n\n\t_blockFrames: function( selector ) {\n\t\tthis.iframeBlocks = this.document.find( selector ).map(function() {\n\t\t\tvar iframe = $( this );\n\n\t\t\treturn $( \"<div>\" )\n\t\t\t\t.css( \"position\", \"absolute\" )\n\t\t\t\t.appendTo( iframe.parent() )\n\t\t\t\t.outerWidth( iframe.outerWidth() )\n\t\t\t\t.outerHeight( iframe.outerHeight() )\n\t\t\t\t.offset( iframe.offset() )[ 0 ];\n\t\t});\n\t},\n\n\t_unblockFrames: function() {\n\t\tif ( this.iframeBlocks ) {\n\t\t\tthis.iframeBlocks.remove();\n\t\t\tdelete this.iframeBlocks;\n\t\t}\n\t},\n\n\t_blurActiveElement: function( event ) {\n\t\tvar document = this.document[ 0 ];\n\n\t\t// Only need to blur if the event occurred on the draggable itself, see #10527\n\t\tif ( !this.handleElement.is( event.target ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// support: IE9\n\t\t// IE9 throws an \"Unspecified error\" accessing document.activeElement from an <iframe>\n\t\ttry {\n\n\t\t\t// Support: IE9, IE10\n\t\t\t// If the <body> is blurred, IE will switch windows, see #9520\n\t\t\tif ( document.activeElement && document.activeElement.nodeName.toLowerCase() !== \"body\" ) {\n\n\t\t\t\t// Blur any element that currently has focus, see #4261\n\t\t\t\t$( document.activeElement ).blur();\n\t\t\t}\n\t\t} catch ( error ) {}\n\t},\n\n\t_mouseStart: function(event) {\n\n\t\tvar o = this.options;\n\n\t\t//Create and append the visible helper\n\t\tthis.helper = this._createHelper(event);\n\n\t\tthis.helper.addClass(\"ui-draggable-dragging\");\n\n\t\t//Cache the helper size\n\t\tthis._cacheHelperProportions();\n\n\t\t//If ddmanager is used for droppables, set the global draggable\n\t\tif ($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.current = this;\n\t\t}\n\n\t\t/*\n\t\t * - Position generation -\n\t\t * This block generates everything position related - it's the core of draggables.\n\t\t */\n\n\t\t//Cache the margins of the original element\n\t\tthis._cacheMargins();\n\n\t\t//Store the helper's css position\n\t\tthis.cssPosition = this.helper.css( \"position\" );\n\t\tthis.scrollParent = this.helper.scrollParent( true );\n\t\tthis.offsetParent = this.helper.offsetParent();\n\t\tthis.hasFixedAncestor = this.helper.parents().filter(function() {\n\t\t\t\treturn $( this ).css( \"position\" ) === \"fixed\";\n\t\t\t}).length > 0;\n\n\t\t//The element's absolute position on the page minus margins\n\t\tthis.positionAbs = this.element.offset();\n\t\tthis._refreshOffsets( event );\n\n\t\t//Generate the original position\n\t\tthis.originalPosition = this.position = this._generatePosition( event, false );\n\t\tthis.originalPageX = event.pageX;\n\t\tthis.originalPageY = event.pageY;\n\n\t\t//Adjust the mouse offset relative to the helper if \"cursorAt\" is supplied\n\t\t(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));\n\n\t\t//Set a containment if given in the options\n\t\tthis._setContainment();\n\n\t\t//Trigger event + callbacks\n\t\tif (this._trigger(\"start\", event) === false) {\n\t\t\tthis._clear();\n\t\t\treturn false;\n\t\t}\n\n\t\t//Recache the helper size\n\t\tthis._cacheHelperProportions();\n\n\t\t//Prepare the droppable offsets\n\t\tif ($.ui.ddmanager && !o.dropBehaviour) {\n\t\t\t$.ui.ddmanager.prepareOffsets(this, event);\n\t\t}\n\n\t\t// Reset helper's right/bottom css if they're set and set explicit width/height instead\n\t\t// as this prevents resizing of elements with right/bottom set (see #7772)\n\t\tthis._normalizeRightBottom();\n\n\t\tthis._mouseDrag(event, true); //Execute the drag once - this causes the helper not to be visible before getting its correct position\n\n\t\t//If the ddmanager is used for droppables, inform the manager that dragging has started (see #5003)\n\t\tif ( $.ui.ddmanager ) {\n\t\t\t$.ui.ddmanager.dragStart(this, event);\n\t\t}\n\n\t\treturn true;\n\t},\n\n\t_refreshOffsets: function( event ) {\n\t\tthis.offset = {\n\t\t\ttop: this.positionAbs.top - this.margins.top,\n\t\t\tleft: this.positionAbs.left - this.margins.left,\n\t\t\tscroll: false,\n\t\t\tparent: this._getParentOffset(),\n\t\t\trelative: this._getRelativeOffset()\n\t\t};\n\n\t\tthis.offset.click = {\n\t\t\tleft: event.pageX - this.offset.left,\n\t\t\ttop: event.pageY - this.offset.top\n\t\t};\n\t},\n\n\t_mouseDrag: function(event, noPropagation) {\n\t\t// reset any necessary cached properties (see #5009)\n\t\tif ( this.hasFixedAncestor ) {\n\t\t\tthis.offset.parent = this._getParentOffset();\n\t\t}\n\n\t\t//Compute the helpers position\n\t\tthis.position = this._generatePosition( event, true );\n\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\n\t\t//Call plugins and callbacks and use the resulting position if something is returned\n\t\tif (!noPropagation) {\n\t\t\tvar ui = this._uiHash();\n\t\t\tif (this._trigger(\"drag\", event, ui) === false) {\n\t\t\t\tthis._mouseUp({});\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis.position = ui.position;\n\t\t}\n\n\t\tthis.helper[ 0 ].style.left = this.position.left + \"px\";\n\t\tthis.helper[ 0 ].style.top = this.position.top + \"px\";\n\n\t\tif ($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.drag(this, event);\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function(event) {\n\n\t\t//If we are using droppables, inform the manager about the drop\n\t\tvar that = this,\n\t\t\tdropped = false;\n\t\tif ($.ui.ddmanager && !this.options.dropBehaviour) {\n\t\t\tdropped = $.ui.ddmanager.drop(this, event);\n\t\t}\n\n\t\t//if a drop comes from outside (a sortable)\n\t\tif (this.dropped) {\n\t\t\tdropped = this.dropped;\n\t\t\tthis.dropped = false;\n\t\t}\n\n\t\tif ((this.options.revert === \"invalid\" && !dropped) || (this.options.revert === \"valid\" && dropped) || this.options.revert === true || ($.isFunction(this.options.revert) && this.options.revert.call(this.element, dropped))) {\n\t\t\t$(this.helper).animate(this.originalPosition, parseInt(this.options.revertDuration, 10), function() {\n\t\t\t\tif (that._trigger(\"stop\", event) !== false) {\n\t\t\t\t\tthat._clear();\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tif (this._trigger(\"stop\", event) !== false) {\n\t\t\t\tthis._clear();\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseUp: function( event ) {\n\t\tthis._unblockFrames();\n\n\t\t//If the ddmanager is used for droppables, inform the manager that dragging has stopped (see #5003)\n\t\tif ( $.ui.ddmanager ) {\n\t\t\t$.ui.ddmanager.dragStop(this, event);\n\t\t}\n\n\t\t// Only need to focus if the event occurred on the draggable itself, see #10527\n\t\tif ( this.handleElement.is( event.target ) ) {\n\t\t\t// The interaction is over; whether or not the click resulted in a drag, focus the element\n\t\t\tthis.element.focus();\n\t\t}\n\n\t\treturn $.ui.mouse.prototype._mouseUp.call(this, event);\n\t},\n\n\tcancel: function() {\n\n\t\tif (this.helper.is(\".ui-draggable-dragging\")) {\n\t\t\tthis._mouseUp({});\n\t\t} else {\n\t\t\tthis._clear();\n\t\t}\n\n\t\treturn this;\n\n\t},\n\n\t_getHandle: function(event) {\n\t\treturn this.options.handle ?\n\t\t\t!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :\n\t\t\ttrue;\n\t},\n\n\t_setHandleClassName: function() {\n\t\tthis.handleElement = this.options.handle ?\n\t\t\tthis.element.find( this.options.handle ) : this.element;\n\t\tthis.handleElement.addClass( \"ui-draggable-handle\" );\n\t},\n\n\t_removeHandleClassName: function() {\n\t\tthis.handleElement.removeClass( \"ui-draggable-handle\" );\n\t},\n\n\t_createHelper: function(event) {\n\n\t\tvar o = this.options,\n\t\t\thelperIsFunction = $.isFunction( o.helper ),\n\t\t\thelper = helperIsFunction ?\n\t\t\t\t$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :\n\t\t\t\t( o.helper === \"clone\" ?\n\t\t\t\t\tthis.element.clone().removeAttr( \"id\" ) :\n\t\t\t\t\tthis.element );\n\n\t\tif (!helper.parents(\"body\").length) {\n\t\t\thelper.appendTo((o.appendTo === \"parent\" ? this.element[0].parentNode : o.appendTo));\n\t\t}\n\n\t\t// http://bugs.jqueryui.com/ticket/9446\n\t\t// a helper function can return the original element\n\t\t// which wouldn't have been set to relative in _create\n\t\tif ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {\n\t\t\tthis._setPositionRelative();\n\t\t}\n\n\t\tif (helper[0] !== this.element[0] && !(/(fixed|absolute)/).test(helper.css(\"position\"))) {\n\t\t\thelper.css(\"position\", \"absolute\");\n\t\t}\n\n\t\treturn helper;\n\n\t},\n\n\t_setPositionRelative: function() {\n\t\tif ( !( /^(?:r|a|f)/ ).test( this.element.css( \"position\" ) ) ) {\n\t\t\tthis.element[ 0 ].style.position = \"relative\";\n\t\t}\n\t},\n\n\t_adjustOffsetFromHelper: function(obj) {\n\t\tif (typeof obj === \"string\") {\n\t\t\tobj = obj.split(\" \");\n\t\t}\n\t\tif ($.isArray(obj)) {\n\t\t\tobj = { left: +obj[0], top: +obj[1] || 0 };\n\t\t}\n\t\tif (\"left\" in obj) {\n\t\t\tthis.offset.click.left = obj.left + this.margins.left;\n\t\t}\n\t\tif (\"right\" in obj) {\n\t\t\tthis.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;\n\t\t}\n\t\tif (\"top\" in obj) {\n\t\t\tthis.offset.click.top = obj.top + this.margins.top;\n\t\t}\n\t\tif (\"bottom\" in obj) {\n\t\t\tthis.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;\n\t\t}\n\t},\n\n\t_isRootNode: function( element ) {\n\t\treturn ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];\n\t},\n\n\t_getParentOffset: function() {\n\n\t\t//Get the offsetParent and cache its position\n\t\tvar po = this.offsetParent.offset(),\n\t\t\tdocument = this.document[ 0 ];\n\n\t\t// This is a special case where we need to modify a offset calculated on start, since the following happened:\n\t\t// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent\n\t\t// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that\n\t\t//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag\n\t\tif (this.cssPosition === \"absolute\" && this.scrollParent[0] !== document && $.contains(this.scrollParent[0], this.offsetParent[0])) {\n\t\t\tpo.left += this.scrollParent.scrollLeft();\n\t\t\tpo.top += this.scrollParent.scrollTop();\n\t\t}\n\n\t\tif ( this._isRootNode( this.offsetParent[ 0 ] ) ) {\n\t\t\tpo = { top: 0, left: 0 };\n\t\t}\n\n\t\treturn {\n\t\t\ttop: po.top + (parseInt(this.offsetParent.css(\"borderTopWidth\"), 10) || 0),\n\t\t\tleft: po.left + (parseInt(this.offsetParent.css(\"borderLeftWidth\"), 10) || 0)\n\t\t};\n\n\t},\n\n\t_getRelativeOffset: function() {\n\t\tif ( this.cssPosition !== \"relative\" ) {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t\tvar p = this.element.position(),\n\t\t\tscrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );\n\n\t\treturn {\n\t\t\ttop: p.top - ( parseInt(this.helper.css( \"top\" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),\n\t\t\tleft: p.left - ( parseInt(this.helper.css( \"left\" ), 10) || 0 ) + ( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )\n\t\t};\n\n\t},\n\n\t_cacheMargins: function() {\n\t\tthis.margins = {\n\t\t\tleft: (parseInt(this.element.css(\"marginLeft\"), 10) || 0),\n\t\t\ttop: (parseInt(this.element.css(\"marginTop\"), 10) || 0),\n\t\t\tright: (parseInt(this.element.css(\"marginRight\"), 10) || 0),\n\t\t\tbottom: (parseInt(this.element.css(\"marginBottom\"), 10) || 0)\n\t\t};\n\t},\n\n\t_cacheHelperProportions: function() {\n\t\tthis.helperProportions = {\n\t\t\twidth: this.helper.outerWidth(),\n\t\t\theight: this.helper.outerHeight()\n\t\t};\n\t},\n\n\t_setContainment: function() {\n\n\t\tvar isUserScrollable, c, ce,\n\t\t\to = this.options,\n\t\t\tdocument = this.document[ 0 ];\n\n\t\tthis.relativeContainer = null;\n\n\t\tif ( !o.containment ) {\n\t\t\tthis.containment = null;\n\t\t\treturn;\n\t\t}\n\n\t\tif ( o.containment === \"window\" ) {\n\t\t\tthis.containment = [\n\t\t\t\t$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,\n\t\t\t\t$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,\n\t\t\t\t$( window ).scrollLeft() + $( window ).width() - this.helperProportions.width - this.margins.left,\n\t\t\t\t$( window ).scrollTop() + ( $( window ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t\treturn;\n\t\t}\n\n\t\tif ( o.containment === \"document\") {\n\t\t\tthis.containment = [\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t\t$( document ).width() - this.helperProportions.width - this.margins.left,\n\t\t\t\t( $( document ).height() || document.body.parentNode.scrollHeight ) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t\treturn;\n\t\t}\n\n\t\tif ( o.containment.constructor === Array ) {\n\t\t\tthis.containment = o.containment;\n\t\t\treturn;\n\t\t}\n\n\t\tif ( o.containment === \"parent\" ) {\n\t\t\to.containment = this.helper[ 0 ].parentNode;\n\t\t}\n\n\t\tc = $( o.containment );\n\t\tce = c[ 0 ];\n\n\t\tif ( !ce ) {\n\t\t\treturn;\n\t\t}\n\n\t\tisUserScrollable = /(scroll|auto)/.test( c.css( \"overflow\" ) );\n\n\t\tthis.containment = [\n\t\t\t( parseInt( c.css( \"borderLeftWidth\" ), 10 ) || 0 ) + ( parseInt( c.css( \"paddingLeft\" ), 10 ) || 0 ),\n\t\t\t( parseInt( c.css( \"borderTopWidth\" ), 10 ) || 0 ) + ( parseInt( c.css( \"paddingTop\" ), 10 ) || 0 ),\n\t\t\t( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -\n\t\t\t\t( parseInt( c.css( \"borderRightWidth\" ), 10 ) || 0 ) -\n\t\t\t\t( parseInt( c.css( \"paddingRight\" ), 10 ) || 0 ) -\n\t\t\t\tthis.helperProportions.width -\n\t\t\t\tthis.margins.left -\n\t\t\t\tthis.margins.right,\n\t\t\t( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -\n\t\t\t\t( parseInt( c.css( \"borderBottomWidth\" ), 10 ) || 0 ) -\n\t\t\t\t( parseInt( c.css( \"paddingBottom\" ), 10 ) || 0 ) -\n\t\t\t\tthis.helperProportions.height -\n\t\t\t\tthis.margins.top -\n\t\t\t\tthis.margins.bottom\n\t\t];\n\t\tthis.relativeContainer = c;\n\t},\n\n\t_convertPositionTo: function(d, pos) {\n\n\t\tif (!pos) {\n\t\t\tpos = this.position;\n\t\t}\n\n\t\tvar mod = d === \"absolute\" ? 1 : -1,\n\t\t\tscrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpos.top\t+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.top * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top * mod -\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod)\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpos.left +\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.left * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left * mod\t-\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod)\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_generatePosition: function( event, constrainPosition ) {\n\n\t\tvar containment, co, top, left,\n\t\t\to = this.options,\n\t\t\tscrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),\n\t\t\tpageX = event.pageX,\n\t\t\tpageY = event.pageY;\n\n\t\t// Cache the scroll\n\t\tif ( !scrollIsRootNode || !this.offset.scroll ) {\n\t\t\tthis.offset.scroll = {\n\t\t\t\ttop: this.scrollParent.scrollTop(),\n\t\t\t\tleft: this.scrollParent.scrollLeft()\n\t\t\t};\n\t\t}\n\n\t\t/*\n\t\t * - Position constraining -\n\t\t * Constrain the position to a mix of grid, containment.\n\t\t */\n\n\t\t// If we are not dragging yet, we won't check for options\n\t\tif ( constrainPosition ) {\n\t\t\tif ( this.containment ) {\n\t\t\t\tif ( this.relativeContainer ){\n\t\t\t\t\tco = this.relativeContainer.offset();\n\t\t\t\t\tcontainment = [\n\t\t\t\t\t\tthis.containment[ 0 ] + co.left,\n\t\t\t\t\t\tthis.containment[ 1 ] + co.top,\n\t\t\t\t\t\tthis.containment[ 2 ] + co.left,\n\t\t\t\t\t\tthis.containment[ 3 ] + co.top\n\t\t\t\t\t];\n\t\t\t\t} else {\n\t\t\t\t\tcontainment = this.containment;\n\t\t\t\t}\n\n\t\t\t\tif (event.pageX - this.offset.click.left < containment[0]) {\n\t\t\t\t\tpageX = containment[0] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif (event.pageY - this.offset.click.top < containment[1]) {\n\t\t\t\t\tpageY = containment[1] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t\tif (event.pageX - this.offset.click.left > containment[2]) {\n\t\t\t\t\tpageX = containment[2] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif (event.pageY - this.offset.click.top > containment[3]) {\n\t\t\t\t\tpageY = containment[3] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (o.grid) {\n\t\t\t\t//Check for grid elements set to 0 to prevent divide by 0 error causing invalid argument errors in IE (see ticket #6950)\n\t\t\t\ttop = o.grid[1] ? this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1] : this.originalPageY;\n\t\t\t\tpageY = containment ? ((top - this.offset.click.top >= containment[1] || top - this.offset.click.top > containment[3]) ? top : ((top - this.offset.click.top >= containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;\n\n\t\t\t\tleft = o.grid[0] ? this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0] : this.originalPageX;\n\t\t\t\tpageX = containment ? ((left - this.offset.click.left >= containment[0] || left - this.offset.click.left > containment[2]) ? left : ((left - this.offset.click.left >= containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;\n\t\t\t}\n\n\t\t\tif ( o.axis === \"y\" ) {\n\t\t\t\tpageX = this.originalPageX;\n\t\t\t}\n\n\t\t\tif ( o.axis === \"x\" ) {\n\t\t\t\tpageY = this.originalPageY;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpageY -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.top\t-\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.top -\t\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( this.cssPosition === \"fixed\" ? -this.offset.scroll.top : ( scrollIsRootNode ? 0 : this.offset.scroll.top ) )\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpageX -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.left -\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.left -\t\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( this.cssPosition === \"fixed\" ? -this.offset.scroll.left : ( scrollIsRootNode ? 0 : this.offset.scroll.left ) )\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_clear: function() {\n\t\tthis.helper.removeClass(\"ui-draggable-dragging\");\n\t\tif (this.helper[0] !== this.element[0] && !this.cancelHelperRemoval) {\n\t\t\tthis.helper.remove();\n\t\t}\n\t\tthis.helper = null;\n\t\tthis.cancelHelperRemoval = false;\n\t\tif ( this.destroyOnClear ) {\n\t\t\tthis.destroy();\n\t\t}\n\t},\n\n\t_normalizeRightBottom: function() {\n\t\tif ( this.options.axis !== \"y\" && this.helper.css( \"right\" ) !== \"auto\" ) {\n\t\t\tthis.helper.width( this.helper.width() );\n\t\t\tthis.helper.css( \"right\", \"auto\" );\n\t\t}\n\t\tif ( this.options.axis !== \"x\" && this.helper.css( \"bottom\" ) !== \"auto\" ) {\n\t\t\tthis.helper.height( this.helper.height() );\n\t\t\tthis.helper.css( \"bottom\", \"auto\" );\n\t\t}\n\t},\n\n\t// From now on bulk stuff - mainly helpers\n\n\t_trigger: function( type, event, ui ) {\n\t\tui = ui || this._uiHash();\n\t\t$.ui.plugin.call( this, type, [ event, ui, this ], true );\n\n\t\t// Absolute position and offset (see #6884 ) have to be recalculated after plugins\n\t\tif ( /^(drag|start|stop)/.test( type ) ) {\n\t\t\tthis.positionAbs = this._convertPositionTo( \"absolute\" );\n\t\t\tui.offset = this.positionAbs;\n\t\t}\n\t\treturn $.Widget.prototype._trigger.call( this, type, event, ui );\n\t},\n\n\tplugins: {},\n\n\t_uiHash: function() {\n\t\treturn {\n\t\t\thelper: this.helper,\n\t\t\tposition: this.position,\n\t\t\toriginalPosition: this.originalPosition,\n\t\t\toffset: this.positionAbs\n\t\t};\n\t}\n\n});\n\n$.ui.plugin.add( \"draggable\", \"connectToSortable\", {\n\tstart: function( event, ui, draggable ) {\n\t\tvar uiSortable = $.extend( {}, ui, {\n\t\t\titem: draggable.element\n\t\t});\n\n\t\tdraggable.sortables = [];\n\t\t$( draggable.options.connectToSortable ).each(function() {\n\t\t\tvar sortable = $( this ).sortable( \"instance\" );\n\n\t\t\tif ( sortable && !sortable.options.disabled ) {\n\t\t\t\tdraggable.sortables.push( sortable );\n\n\t\t\t\t// refreshPositions is called at drag start to refresh the containerCache\n\t\t\t\t// which is used in drag. This ensures it's initialized and synchronized\n\t\t\t\t// with any changes that might have happened on the page since initialization.\n\t\t\t\tsortable.refreshPositions();\n\t\t\t\tsortable._trigger(\"activate\", event, uiSortable);\n\t\t\t}\n\t\t});\n\t},\n\tstop: function( event, ui, draggable ) {\n\t\tvar uiSortable = $.extend( {}, ui, {\n\t\t\titem: draggable.element\n\t\t});\n\n\t\tdraggable.cancelHelperRemoval = false;\n\n\t\t$.each( draggable.sortables, function() {\n\t\t\tvar sortable = this;\n\n\t\t\tif ( sortable.isOver ) {\n\t\t\t\tsortable.isOver = 0;\n\n\t\t\t\t// Allow this sortable to handle removing the helper\n\t\t\t\tdraggable.cancelHelperRemoval = true;\n\t\t\t\tsortable.cancelHelperRemoval = false;\n\n\t\t\t\t// Use _storedCSS To restore properties in the sortable,\n\t\t\t\t// as this also handles revert (#9675) since the draggable\n\t\t\t\t// may have modified them in unexpected ways (#8809)\n\t\t\t\tsortable._storedCSS = {\n\t\t\t\t\tposition: sortable.placeholder.css( \"position\" ),\n\t\t\t\t\ttop: sortable.placeholder.css( \"top\" ),\n\t\t\t\t\tleft: sortable.placeholder.css( \"left\" )\n\t\t\t\t};\n\n\t\t\t\tsortable._mouseStop(event);\n\n\t\t\t\t// Once drag has ended, the sortable should return to using\n\t\t\t\t// its original helper, not the shared helper from draggable\n\t\t\t\tsortable.options.helper = sortable.options._helper;\n\t\t\t} else {\n\t\t\t\t// Prevent this Sortable from removing the helper.\n\t\t\t\t// However, don't set the draggable to remove the helper\n\t\t\t\t// either as another connected Sortable may yet handle the removal.\n\t\t\t\tsortable.cancelHelperRemoval = true;\n\n\t\t\t\tsortable._trigger( \"deactivate\", event, uiSortable );\n\t\t\t}\n\t\t});\n\t},\n\tdrag: function( event, ui, draggable ) {\n\t\t$.each( draggable.sortables, function() {\n\t\t\tvar innermostIntersecting = false,\n\t\t\t\tsortable = this;\n\n\t\t\t// Copy over variables that sortable's _intersectsWith uses\n\t\t\tsortable.positionAbs = draggable.positionAbs;\n\t\t\tsortable.helperProportions = draggable.helperProportions;\n\t\t\tsortable.offset.click = draggable.offset.click;\n\n\t\t\tif ( sortable._intersectsWith( sortable.containerCache ) ) {\n\t\t\t\tinnermostIntersecting = true;\n\n\t\t\t\t$.each( draggable.sortables, function() {\n\t\t\t\t\t// Copy over variables that sortable's _intersectsWith uses\n\t\t\t\t\tthis.positionAbs = draggable.positionAbs;\n\t\t\t\t\tthis.helperProportions = draggable.helperProportions;\n\t\t\t\t\tthis.offset.click = draggable.offset.click;\n\n\t\t\t\t\tif ( this !== sortable &&\n\t\t\t\t\t\t\tthis._intersectsWith( this.containerCache ) &&\n\t\t\t\t\t\t\t$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {\n\t\t\t\t\t\tinnermostIntersecting = false;\n\t\t\t\t\t}\n\n\t\t\t\t\treturn innermostIntersecting;\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif ( innermostIntersecting ) {\n\t\t\t\t// If it intersects, we use a little isOver variable and set it once,\n\t\t\t\t// so that the move-in stuff gets fired only once.\n\t\t\t\tif ( !sortable.isOver ) {\n\t\t\t\t\tsortable.isOver = 1;\n\n\t\t\t\t\t// Store draggable's parent in case we need to reappend to it later.\n\t\t\t\t\tdraggable._parent = ui.helper.parent();\n\n\t\t\t\t\tsortable.currentItem = ui.helper\n\t\t\t\t\t\t.appendTo( sortable.element )\n\t\t\t\t\t\t.data( \"ui-sortable-item\", true );\n\n\t\t\t\t\t// Store helper option to later restore it\n\t\t\t\t\tsortable.options._helper = sortable.options.helper;\n\n\t\t\t\t\tsortable.options.helper = function() {\n\t\t\t\t\t\treturn ui.helper[ 0 ];\n\t\t\t\t\t};\n\n\t\t\t\t\t// Fire the start events of the sortable with our passed browser event,\n\t\t\t\t\t// and our own helper (so it doesn't create a new one)\n\t\t\t\t\tevent.target = sortable.currentItem[ 0 ];\n\t\t\t\t\tsortable._mouseCapture( event, true );\n\t\t\t\t\tsortable._mouseStart( event, true, true );\n\n\t\t\t\t\t// Because the browser event is way off the new appended portlet,\n\t\t\t\t\t// modify necessary variables to reflect the changes\n\t\t\t\t\tsortable.offset.click.top = draggable.offset.click.top;\n\t\t\t\t\tsortable.offset.click.left = draggable.offset.click.left;\n\t\t\t\t\tsortable.offset.parent.left -= draggable.offset.parent.left -\n\t\t\t\t\t\tsortable.offset.parent.left;\n\t\t\t\t\tsortable.offset.parent.top -= draggable.offset.parent.top -\n\t\t\t\t\t\tsortable.offset.parent.top;\n\n\t\t\t\t\tdraggable._trigger( \"toSortable\", event );\n\n\t\t\t\t\t// Inform draggable that the helper is in a valid drop zone,\n\t\t\t\t\t// used solely in the revert option to handle \"valid/invalid\".\n\t\t\t\t\tdraggable.dropped = sortable.element;\n\n\t\t\t\t\t// Need to refreshPositions of all sortables in the case that\n\t\t\t\t\t// adding to one sortable changes the location of the other sortables (#9675)\n\t\t\t\t\t$.each( draggable.sortables, function() {\n\t\t\t\t\t\tthis.refreshPositions();\n\t\t\t\t\t});\n\n\t\t\t\t\t// hack so receive/update callbacks work (mostly)\n\t\t\t\t\tdraggable.currentItem = draggable.element;\n\t\t\t\t\tsortable.fromOutside = draggable;\n\t\t\t\t}\n\n\t\t\t\tif ( sortable.currentItem ) {\n\t\t\t\t\tsortable._mouseDrag( event );\n\t\t\t\t\t// Copy the sortable's position because the draggable's can potentially reflect\n\t\t\t\t\t// a relative position, while sortable is always absolute, which the dragged\n\t\t\t\t\t// element has now become. (#8809)\n\t\t\t\t\tui.position = sortable.position;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If it doesn't intersect with the sortable, and it intersected before,\n\t\t\t\t// we fake the drag stop of the sortable, but make sure it doesn't remove\n\t\t\t\t// the helper by using cancelHelperRemoval.\n\t\t\t\tif ( sortable.isOver ) {\n\n\t\t\t\t\tsortable.isOver = 0;\n\t\t\t\t\tsortable.cancelHelperRemoval = true;\n\n\t\t\t\t\t// Calling sortable's mouseStop would trigger a revert,\n\t\t\t\t\t// so revert must be temporarily false until after mouseStop is called.\n\t\t\t\t\tsortable.options._revert = sortable.options.revert;\n\t\t\t\t\tsortable.options.revert = false;\n\n\t\t\t\t\tsortable._trigger( \"out\", event, sortable._uiHash( sortable ) );\n\t\t\t\t\tsortable._mouseStop( event, true );\n\n\t\t\t\t\t// restore sortable behaviors that were modfied\n\t\t\t\t\t// when the draggable entered the sortable area (#9481)\n\t\t\t\t\tsortable.options.revert = sortable.options._revert;\n\t\t\t\t\tsortable.options.helper = sortable.options._helper;\n\n\t\t\t\t\tif ( sortable.placeholder ) {\n\t\t\t\t\t\tsortable.placeholder.remove();\n\t\t\t\t\t}\n\n\t\t\t\t\t// Restore and recalculate the draggable's offset considering the sortable\n\t\t\t\t\t// may have modified them in unexpected ways. (#8809, #10669)\n\t\t\t\t\tui.helper.appendTo( draggable._parent );\n\t\t\t\t\tdraggable._refreshOffsets( event );\n\t\t\t\t\tui.position = draggable._generatePosition( event, true );\n\n\t\t\t\t\tdraggable._trigger( \"fromSortable\", event );\n\n\t\t\t\t\t// Inform draggable that the helper is no longer in a valid drop zone\n\t\t\t\t\tdraggable.dropped = false;\n\n\t\t\t\t\t// Need to refreshPositions of all sortables just in case removing\n\t\t\t\t\t// from one sortable changes the location of other sortables (#9675)\n\t\t\t\t\t$.each( draggable.sortables, function() {\n\t\t\t\t\t\tthis.refreshPositions();\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"cursor\", {\n\tstart: function( event, ui, instance ) {\n\t\tvar t = $( \"body\" ),\n\t\t\to = instance.options;\n\n\t\tif (t.css(\"cursor\")) {\n\t\t\to._cursor = t.css(\"cursor\");\n\t\t}\n\t\tt.css(\"cursor\", o.cursor);\n\t},\n\tstop: function( event, ui, instance ) {\n\t\tvar o = instance.options;\n\t\tif (o._cursor) {\n\t\t\t$(\"body\").css(\"cursor\", o._cursor);\n\t\t}\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"opacity\", {\n\tstart: function( event, ui, instance ) {\n\t\tvar t = $( ui.helper ),\n\t\t\to = instance.options;\n\t\tif (t.css(\"opacity\")) {\n\t\t\to._opacity = t.css(\"opacity\");\n\t\t}\n\t\tt.css(\"opacity\", o.opacity);\n\t},\n\tstop: function( event, ui, instance ) {\n\t\tvar o = instance.options;\n\t\tif (o._opacity) {\n\t\t\t$(ui.helper).css(\"opacity\", o._opacity);\n\t\t}\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"scroll\", {\n\tstart: function( event, ui, i ) {\n\t\tif ( !i.scrollParentNotHidden ) {\n\t\t\ti.scrollParentNotHidden = i.helper.scrollParent( false );\n\t\t}\n\n\t\tif ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] && i.scrollParentNotHidden[ 0 ].tagName !== \"HTML\" ) {\n\t\t\ti.overflowOffset = i.scrollParentNotHidden.offset();\n\t\t}\n\t},\n\tdrag: function( event, ui, i  ) {\n\n\t\tvar o = i.options,\n\t\t\tscrolled = false,\n\t\t\tscrollParent = i.scrollParentNotHidden[ 0 ],\n\t\t\tdocument = i.document[ 0 ];\n\n\t\tif ( scrollParent !== document && scrollParent.tagName !== \"HTML\" ) {\n\t\t\tif ( !o.axis || o.axis !== \"x\" ) {\n\t\t\t\tif ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY < o.scrollSensitivity ) {\n\t\t\t\t\tscrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;\n\t\t\t\t} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {\n\t\t\t\t\tscrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !o.axis || o.axis !== \"y\" ) {\n\t\t\t\tif ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX < o.scrollSensitivity ) {\n\t\t\t\t\tscrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;\n\t\t\t\t} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {\n\t\t\t\t\tscrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;\n\t\t\t\t}\n\t\t\t}\n\n\t\t} else {\n\n\t\t\tif (!o.axis || o.axis !== \"x\") {\n\t\t\t\tif (event.pageY - $(document).scrollTop() < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() - o.scrollSpeed);\n\t\t\t\t} else if ($(window).height() - (event.pageY - $(document).scrollTop()) < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollTop($(document).scrollTop() + o.scrollSpeed);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!o.axis || o.axis !== \"y\") {\n\t\t\t\tif (event.pageX - $(document).scrollLeft() < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() - o.scrollSpeed);\n\t\t\t\t} else if ($(window).width() - (event.pageX - $(document).scrollLeft()) < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = $(document).scrollLeft($(document).scrollLeft() + o.scrollSpeed);\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tif (scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {\n\t\t\t$.ui.ddmanager.prepareOffsets(i, event);\n\t\t}\n\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"snap\", {\n\tstart: function( event, ui, i ) {\n\n\t\tvar o = i.options;\n\n\t\ti.snapElements = [];\n\n\t\t$(o.snap.constructor !== String ? ( o.snap.items || \":data(ui-draggable)\" ) : o.snap).each(function() {\n\t\t\tvar $t = $(this),\n\t\t\t\t$o = $t.offset();\n\t\t\tif (this !== i.element[0]) {\n\t\t\t\ti.snapElements.push({\n\t\t\t\t\titem: this,\n\t\t\t\t\twidth: $t.outerWidth(), height: $t.outerHeight(),\n\t\t\t\t\ttop: $o.top, left: $o.left\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t},\n\tdrag: function( event, ui, inst ) {\n\n\t\tvar ts, bs, ls, rs, l, r, t, b, i, first,\n\t\t\to = inst.options,\n\t\t\td = o.snapTolerance,\n\t\t\tx1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,\n\t\t\ty1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;\n\n\t\tfor (i = inst.snapElements.length - 1; i >= 0; i--){\n\n\t\t\tl = inst.snapElements[i].left - inst.margins.left;\n\t\t\tr = l + inst.snapElements[i].width;\n\t\t\tt = inst.snapElements[i].top - inst.margins.top;\n\t\t\tb = t + inst.snapElements[i].height;\n\n\t\t\tif ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d || !$.contains( inst.snapElements[ i ].item.ownerDocument, inst.snapElements[ i ].item ) ) {\n\t\t\t\tif (inst.snapElements[i].snapping) {\n\t\t\t\t\t(inst.options.snap.release && inst.options.snap.release.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));\n\t\t\t\t}\n\t\t\t\tinst.snapElements[i].snapping = false;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (o.snapMode !== \"inner\") {\n\t\t\t\tts = Math.abs(t - y2) <= d;\n\t\t\t\tbs = Math.abs(b - y1) <= d;\n\t\t\t\tls = Math.abs(l - x2) <= d;\n\t\t\t\trs = Math.abs(r - x1) <= d;\n\t\t\t\tif (ts) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: t - inst.helperProportions.height, left: 0 }).top;\n\t\t\t\t}\n\t\t\t\tif (bs) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: b, left: 0 }).top;\n\t\t\t\t}\n\t\t\t\tif (ls) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: l - inst.helperProportions.width }).left;\n\t\t\t\t}\n\t\t\t\tif (rs) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: r }).left;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfirst = (ts || bs || ls || rs);\n\n\t\t\tif (o.snapMode !== \"outer\") {\n\t\t\t\tts = Math.abs(t - y1) <= d;\n\t\t\t\tbs = Math.abs(b - y2) <= d;\n\t\t\t\tls = Math.abs(l - x1) <= d;\n\t\t\t\trs = Math.abs(r - x2) <= d;\n\t\t\t\tif (ts) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: t, left: 0 }).top;\n\t\t\t\t}\n\t\t\t\tif (bs) {\n\t\t\t\t\tui.position.top = inst._convertPositionTo(\"relative\", { top: b - inst.helperProportions.height, left: 0 }).top;\n\t\t\t\t}\n\t\t\t\tif (ls) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: l }).left;\n\t\t\t\t}\n\t\t\t\tif (rs) {\n\t\t\t\t\tui.position.left = inst._convertPositionTo(\"relative\", { top: 0, left: r - inst.helperProportions.width }).left;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (!inst.snapElements[i].snapping && (ts || bs || ls || rs || first)) {\n\t\t\t\t(inst.options.snap.snap && inst.options.snap.snap.call(inst.element, event, $.extend(inst._uiHash(), { snapItem: inst.snapElements[i].item })));\n\t\t\t}\n\t\t\tinst.snapElements[i].snapping = (ts || bs || ls || rs || first);\n\n\t\t}\n\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"stack\", {\n\tstart: function( event, ui, instance ) {\n\t\tvar min,\n\t\t\to = instance.options,\n\t\t\tgroup = $.makeArray($(o.stack)).sort(function(a, b) {\n\t\t\t\treturn (parseInt($(a).css(\"zIndex\"), 10) || 0) - (parseInt($(b).css(\"zIndex\"), 10) || 0);\n\t\t\t});\n\n\t\tif (!group.length) { return; }\n\n\t\tmin = parseInt($(group[0]).css(\"zIndex\"), 10) || 0;\n\t\t$(group).each(function(i) {\n\t\t\t$(this).css(\"zIndex\", min + i);\n\t\t});\n\t\tthis.css(\"zIndex\", (min + group.length));\n\t}\n});\n\n$.ui.plugin.add(\"draggable\", \"zIndex\", {\n\tstart: function( event, ui, instance ) {\n\t\tvar t = $( ui.helper ),\n\t\t\to = instance.options;\n\n\t\tif (t.css(\"zIndex\")) {\n\t\t\to._zIndex = t.css(\"zIndex\");\n\t\t}\n\t\tt.css(\"zIndex\", o.zIndex);\n\t},\n\tstop: function( event, ui, instance ) {\n\t\tvar o = instance.options;\n\n\t\tif (o._zIndex) {\n\t\t\t$(ui.helper).css(\"zIndex\", o._zIndex);\n\t\t}\n\t}\n});\n\nvar draggable = $.ui.draggable;\n\n\n/*!\n * jQuery UI Resizable 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/resizable/\n */\n\n\n$.widget(\"ui.resizable\", $.ui.mouse, {\n\tversion: \"1.11.4\",\n\twidgetEventPrefix: \"resize\",\n\toptions: {\n\t\talsoResize: false,\n\t\tanimate: false,\n\t\tanimateDuration: \"slow\",\n\t\tanimateEasing: \"swing\",\n\t\taspectRatio: false,\n\t\tautoHide: false,\n\t\tcontainment: false,\n\t\tghost: false,\n\t\tgrid: false,\n\t\thandles: \"e,s,se\",\n\t\thelper: false,\n\t\tmaxHeight: null,\n\t\tmaxWidth: null,\n\t\tminHeight: 10,\n\t\tminWidth: 10,\n\t\t// See #7960\n\t\tzIndex: 90,\n\n\t\t// callbacks\n\t\tresize: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\n\t_num: function( value ) {\n\t\treturn parseInt( value, 10 ) || 0;\n\t},\n\n\t_isNumber: function( value ) {\n\t\treturn !isNaN( parseInt( value, 10 ) );\n\t},\n\n\t_hasScroll: function( el, a ) {\n\n\t\tif ( $( el ).css( \"overflow\" ) === \"hidden\") {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar scroll = ( a && a === \"left\" ) ? \"scrollLeft\" : \"scrollTop\",\n\t\t\thas = false;\n\n\t\tif ( el[ scroll ] > 0 ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// TODO: determine which cases actually cause this to happen\n\t\t// if the element doesn't have the scroll set, see if it's possible to\n\t\t// set the scroll\n\t\tel[ scroll ] = 1;\n\t\thas = ( el[ scroll ] > 0 );\n\t\tel[ scroll ] = 0;\n\t\treturn has;\n\t},\n\n\t_create: function() {\n\n\t\tvar n, i, handle, axis, hname,\n\t\t\tthat = this,\n\t\t\to = this.options;\n\t\tthis.element.addClass(\"ui-resizable\");\n\n\t\t$.extend(this, {\n\t\t\t_aspectRatio: !!(o.aspectRatio),\n\t\t\taspectRatio: o.aspectRatio,\n\t\t\toriginalElement: this.element,\n\t\t\t_proportionallyResizeElements: [],\n\t\t\t_helper: o.helper || o.ghost || o.animate ? o.helper || \"ui-resizable-helper\" : null\n\t\t});\n\n\t\t// Wrap the element if it cannot hold child nodes\n\t\tif (this.element[0].nodeName.match(/^(canvas|textarea|input|select|button|img)$/i)) {\n\n\t\t\tthis.element.wrap(\n\t\t\t\t$(\"<div class='ui-wrapper' style='overflow: hidden;'></div>\").css({\n\t\t\t\t\tposition: this.element.css(\"position\"),\n\t\t\t\t\twidth: this.element.outerWidth(),\n\t\t\t\t\theight: this.element.outerHeight(),\n\t\t\t\t\ttop: this.element.css(\"top\"),\n\t\t\t\t\tleft: this.element.css(\"left\")\n\t\t\t\t})\n\t\t\t);\n\n\t\t\tthis.element = this.element.parent().data(\n\t\t\t\t\"ui-resizable\", this.element.resizable( \"instance\" )\n\t\t\t);\n\n\t\t\tthis.elementIsWrapper = true;\n\n\t\t\tthis.element.css({\n\t\t\t\tmarginLeft: this.originalElement.css(\"marginLeft\"),\n\t\t\t\tmarginTop: this.originalElement.css(\"marginTop\"),\n\t\t\t\tmarginRight: this.originalElement.css(\"marginRight\"),\n\t\t\t\tmarginBottom: this.originalElement.css(\"marginBottom\")\n\t\t\t});\n\t\t\tthis.originalElement.css({\n\t\t\t\tmarginLeft: 0,\n\t\t\t\tmarginTop: 0,\n\t\t\t\tmarginRight: 0,\n\t\t\t\tmarginBottom: 0\n\t\t\t});\n\t\t\t// support: Safari\n\t\t\t// Prevent Safari textarea resize\n\t\t\tthis.originalResizeStyle = this.originalElement.css(\"resize\");\n\t\t\tthis.originalElement.css(\"resize\", \"none\");\n\n\t\t\tthis._proportionallyResizeElements.push( this.originalElement.css({\n\t\t\t\tposition: \"static\",\n\t\t\t\tzoom: 1,\n\t\t\t\tdisplay: \"block\"\n\t\t\t}) );\n\n\t\t\t// support: IE9\n\t\t\t// avoid IE jump (hard set the margin)\n\t\t\tthis.originalElement.css({ margin: this.originalElement.css(\"margin\") });\n\n\t\t\tthis._proportionallyResize();\n\t\t}\n\n\t\tthis.handles = o.handles ||\n\t\t\t( !$(\".ui-resizable-handle\", this.element).length ?\n\t\t\t\t\"e,s,se\" : {\n\t\t\t\t\tn: \".ui-resizable-n\",\n\t\t\t\t\te: \".ui-resizable-e\",\n\t\t\t\t\ts: \".ui-resizable-s\",\n\t\t\t\t\tw: \".ui-resizable-w\",\n\t\t\t\t\tse: \".ui-resizable-se\",\n\t\t\t\t\tsw: \".ui-resizable-sw\",\n\t\t\t\t\tne: \".ui-resizable-ne\",\n\t\t\t\t\tnw: \".ui-resizable-nw\"\n\t\t\t\t} );\n\n\t\tthis._handles = $();\n\t\tif ( this.handles.constructor === String ) {\n\n\t\t\tif ( this.handles === \"all\") {\n\t\t\t\tthis.handles = \"n,e,s,w,se,sw,ne,nw\";\n\t\t\t}\n\n\t\t\tn = this.handles.split(\",\");\n\t\t\tthis.handles = {};\n\n\t\t\tfor (i = 0; i < n.length; i++) {\n\n\t\t\t\thandle = $.trim(n[i]);\n\t\t\t\thname = \"ui-resizable-\" + handle;\n\t\t\t\taxis = $(\"<div class='ui-resizable-handle \" + hname + \"'></div>\");\n\n\t\t\t\taxis.css({ zIndex: o.zIndex });\n\n\t\t\t\t// TODO : What's going on here?\n\t\t\t\tif (\"se\" === handle) {\n\t\t\t\t\taxis.addClass(\"ui-icon ui-icon-gripsmall-diagonal-se\");\n\t\t\t\t}\n\n\t\t\t\tthis.handles[handle] = \".ui-resizable-\" + handle;\n\t\t\t\tthis.element.append(axis);\n\t\t\t}\n\n\t\t}\n\n\t\tthis._renderAxis = function(target) {\n\n\t\t\tvar i, axis, padPos, padWrapper;\n\n\t\t\ttarget = target || this.element;\n\n\t\t\tfor (i in this.handles) {\n\n\t\t\t\tif (this.handles[i].constructor === String) {\n\t\t\t\t\tthis.handles[i] = this.element.children( this.handles[ i ] ).first().show();\n\t\t\t\t} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {\n\t\t\t\t\tthis.handles[ i ] = $( this.handles[ i ] );\n\t\t\t\t\tthis._on( this.handles[ i ], { \"mousedown\": that._mouseDown });\n\t\t\t\t}\n\n\t\t\t\tif (this.elementIsWrapper && this.originalElement[0].nodeName.match(/^(textarea|input|select|button)$/i)) {\n\n\t\t\t\t\taxis = $(this.handles[i], this.element);\n\n\t\t\t\t\tpadWrapper = /sw|ne|nw|se|n|s/.test(i) ? axis.outerHeight() : axis.outerWidth();\n\n\t\t\t\t\tpadPos = [ \"padding\",\n\t\t\t\t\t\t/ne|nw|n/.test(i) ? \"Top\" :\n\t\t\t\t\t\t/se|sw|s/.test(i) ? \"Bottom\" :\n\t\t\t\t\t\t/^e$/.test(i) ? \"Right\" : \"Left\" ].join(\"\");\n\n\t\t\t\t\ttarget.css(padPos, padWrapper);\n\n\t\t\t\t\tthis._proportionallyResize();\n\t\t\t\t}\n\n\t\t\t\tthis._handles = this._handles.add( this.handles[ i ] );\n\t\t\t}\n\t\t};\n\n\t\t// TODO: make renderAxis a prototype function\n\t\tthis._renderAxis(this.element);\n\n\t\tthis._handles = this._handles.add( this.element.find( \".ui-resizable-handle\" ) );\n\t\tthis._handles.disableSelection();\n\n\t\tthis._handles.mouseover(function() {\n\t\t\tif (!that.resizing) {\n\t\t\t\tif (this.className) {\n\t\t\t\t\taxis = this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i);\n\t\t\t\t}\n\t\t\t\tthat.axis = axis && axis[1] ? axis[1] : \"se\";\n\t\t\t}\n\t\t});\n\n\t\tif (o.autoHide) {\n\t\t\tthis._handles.hide();\n\t\t\t$(this.element)\n\t\t\t\t.addClass(\"ui-resizable-autohide\")\n\t\t\t\t.mouseenter(function() {\n\t\t\t\t\tif (o.disabled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\t$(this).removeClass(\"ui-resizable-autohide\");\n\t\t\t\t\tthat._handles.show();\n\t\t\t\t})\n\t\t\t\t.mouseleave(function() {\n\t\t\t\t\tif (o.disabled) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tif (!that.resizing) {\n\t\t\t\t\t\t$(this).addClass(\"ui-resizable-autohide\");\n\t\t\t\t\t\tthat._handles.hide();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t}\n\n\t\tthis._mouseInit();\n\t},\n\n\t_destroy: function() {\n\n\t\tthis._mouseDestroy();\n\n\t\tvar wrapper,\n\t\t\t_destroy = function(exp) {\n\t\t\t\t$(exp)\n\t\t\t\t\t.removeClass(\"ui-resizable ui-resizable-disabled ui-resizable-resizing\")\n\t\t\t\t\t.removeData(\"resizable\")\n\t\t\t\t\t.removeData(\"ui-resizable\")\n\t\t\t\t\t.unbind(\".resizable\")\n\t\t\t\t\t.find(\".ui-resizable-handle\")\n\t\t\t\t\t\t.remove();\n\t\t\t};\n\n\t\t// TODO: Unwrap at same DOM position\n\t\tif (this.elementIsWrapper) {\n\t\t\t_destroy(this.element);\n\t\t\twrapper = this.element;\n\t\t\tthis.originalElement.css({\n\t\t\t\tposition: wrapper.css(\"position\"),\n\t\t\t\twidth: wrapper.outerWidth(),\n\t\t\t\theight: wrapper.outerHeight(),\n\t\t\t\ttop: wrapper.css(\"top\"),\n\t\t\t\tleft: wrapper.css(\"left\")\n\t\t\t}).insertAfter( wrapper );\n\t\t\twrapper.remove();\n\t\t}\n\n\t\tthis.originalElement.css(\"resize\", this.originalResizeStyle);\n\t\t_destroy(this.originalElement);\n\n\t\treturn this;\n\t},\n\n\t_mouseCapture: function(event) {\n\t\tvar i, handle,\n\t\t\tcapture = false;\n\n\t\tfor (i in this.handles) {\n\t\t\thandle = $(this.handles[i])[0];\n\t\t\tif (handle === event.target || $.contains(handle, event.target)) {\n\t\t\t\tcapture = true;\n\t\t\t}\n\t\t}\n\n\t\treturn !this.options.disabled && capture;\n\t},\n\n\t_mouseStart: function(event) {\n\n\t\tvar curleft, curtop, cursor,\n\t\t\to = this.options,\n\t\t\tel = this.element;\n\n\t\tthis.resizing = true;\n\n\t\tthis._renderProxy();\n\n\t\tcurleft = this._num(this.helper.css(\"left\"));\n\t\tcurtop = this._num(this.helper.css(\"top\"));\n\n\t\tif (o.containment) {\n\t\t\tcurleft += $(o.containment).scrollLeft() || 0;\n\t\t\tcurtop += $(o.containment).scrollTop() || 0;\n\t\t}\n\n\t\tthis.offset = this.helper.offset();\n\t\tthis.position = { left: curleft, top: curtop };\n\n\t\tthis.size = this._helper ? {\n\t\t\t\twidth: this.helper.width(),\n\t\t\t\theight: this.helper.height()\n\t\t\t} : {\n\t\t\t\twidth: el.width(),\n\t\t\t\theight: el.height()\n\t\t\t};\n\n\t\tthis.originalSize = this._helper ? {\n\t\t\t\twidth: el.outerWidth(),\n\t\t\t\theight: el.outerHeight()\n\t\t\t} : {\n\t\t\t\twidth: el.width(),\n\t\t\t\theight: el.height()\n\t\t\t};\n\n\t\tthis.sizeDiff = {\n\t\t\twidth: el.outerWidth() - el.width(),\n\t\t\theight: el.outerHeight() - el.height()\n\t\t};\n\n\t\tthis.originalPosition = { left: curleft, top: curtop };\n\t\tthis.originalMousePosition = { left: event.pageX, top: event.pageY };\n\n\t\tthis.aspectRatio = (typeof o.aspectRatio === \"number\") ?\n\t\t\to.aspectRatio :\n\t\t\t((this.originalSize.width / this.originalSize.height) || 1);\n\n\t\tcursor = $(\".ui-resizable-\" + this.axis).css(\"cursor\");\n\t\t$(\"body\").css(\"cursor\", cursor === \"auto\" ? this.axis + \"-resize\" : cursor);\n\n\t\tel.addClass(\"ui-resizable-resizing\");\n\t\tthis._propagate(\"start\", event);\n\t\treturn true;\n\t},\n\n\t_mouseDrag: function(event) {\n\n\t\tvar data, props,\n\t\t\tsmp = this.originalMousePosition,\n\t\t\ta = this.axis,\n\t\t\tdx = (event.pageX - smp.left) || 0,\n\t\t\tdy = (event.pageY - smp.top) || 0,\n\t\t\ttrigger = this._change[a];\n\n\t\tthis._updatePrevProperties();\n\n\t\tif (!trigger) {\n\t\t\treturn false;\n\t\t}\n\n\t\tdata = trigger.apply(this, [ event, dx, dy ]);\n\n\t\tthis._updateVirtualBoundaries(event.shiftKey);\n\t\tif (this._aspectRatio || event.shiftKey) {\n\t\t\tdata = this._updateRatio(data, event);\n\t\t}\n\n\t\tdata = this._respectSize(data, event);\n\n\t\tthis._updateCache(data);\n\n\t\tthis._propagate(\"resize\", event);\n\n\t\tprops = this._applyChanges();\n\n\t\tif ( !this._helper && this._proportionallyResizeElements.length ) {\n\t\t\tthis._proportionallyResize();\n\t\t}\n\n\t\tif ( !$.isEmptyObject( props ) ) {\n\t\t\tthis._updatePrevProperties();\n\t\t\tthis._trigger( \"resize\", event, this.ui() );\n\t\t\tthis._applyChanges();\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function(event) {\n\n\t\tthis.resizing = false;\n\t\tvar pr, ista, soffseth, soffsetw, s, left, top,\n\t\t\to = this.options, that = this;\n\n\t\tif (this._helper) {\n\n\t\t\tpr = this._proportionallyResizeElements;\n\t\t\tista = pr.length && (/textarea/i).test(pr[0].nodeName);\n\t\t\tsoffseth = ista && this._hasScroll(pr[0], \"left\") ? 0 : that.sizeDiff.height;\n\t\t\tsoffsetw = ista ? 0 : that.sizeDiff.width;\n\n\t\t\ts = {\n\t\t\t\twidth: (that.helper.width()  - soffsetw),\n\t\t\t\theight: (that.helper.height() - soffseth)\n\t\t\t};\n\t\t\tleft = (parseInt(that.element.css(\"left\"), 10) +\n\t\t\t\t(that.position.left - that.originalPosition.left)) || null;\n\t\t\ttop = (parseInt(that.element.css(\"top\"), 10) +\n\t\t\t\t(that.position.top - that.originalPosition.top)) || null;\n\n\t\t\tif (!o.animate) {\n\t\t\t\tthis.element.css($.extend(s, { top: top, left: left }));\n\t\t\t}\n\n\t\t\tthat.helper.height(that.size.height);\n\t\t\tthat.helper.width(that.size.width);\n\n\t\t\tif (this._helper && !o.animate) {\n\t\t\t\tthis._proportionallyResize();\n\t\t\t}\n\t\t}\n\n\t\t$(\"body\").css(\"cursor\", \"auto\");\n\n\t\tthis.element.removeClass(\"ui-resizable-resizing\");\n\n\t\tthis._propagate(\"stop\", event);\n\n\t\tif (this._helper) {\n\t\t\tthis.helper.remove();\n\t\t}\n\n\t\treturn false;\n\n\t},\n\n\t_updatePrevProperties: function() {\n\t\tthis.prevPosition = {\n\t\t\ttop: this.position.top,\n\t\t\tleft: this.position.left\n\t\t};\n\t\tthis.prevSize = {\n\t\t\twidth: this.size.width,\n\t\t\theight: this.size.height\n\t\t};\n\t},\n\n\t_applyChanges: function() {\n\t\tvar props = {};\n\n\t\tif ( this.position.top !== this.prevPosition.top ) {\n\t\t\tprops.top = this.position.top + \"px\";\n\t\t}\n\t\tif ( this.position.left !== this.prevPosition.left ) {\n\t\t\tprops.left = this.position.left + \"px\";\n\t\t}\n\t\tif ( this.size.width !== this.prevSize.width ) {\n\t\t\tprops.width = this.size.width + \"px\";\n\t\t}\n\t\tif ( this.size.height !== this.prevSize.height ) {\n\t\t\tprops.height = this.size.height + \"px\";\n\t\t}\n\n\t\tthis.helper.css( props );\n\n\t\treturn props;\n\t},\n\n\t_updateVirtualBoundaries: function(forceAspectRatio) {\n\t\tvar pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,\n\t\t\to = this.options;\n\n\t\tb = {\n\t\t\tminWidth: this._isNumber(o.minWidth) ? o.minWidth : 0,\n\t\t\tmaxWidth: this._isNumber(o.maxWidth) ? o.maxWidth : Infinity,\n\t\t\tminHeight: this._isNumber(o.minHeight) ? o.minHeight : 0,\n\t\t\tmaxHeight: this._isNumber(o.maxHeight) ? o.maxHeight : Infinity\n\t\t};\n\n\t\tif (this._aspectRatio || forceAspectRatio) {\n\t\t\tpMinWidth = b.minHeight * this.aspectRatio;\n\t\t\tpMinHeight = b.minWidth / this.aspectRatio;\n\t\t\tpMaxWidth = b.maxHeight * this.aspectRatio;\n\t\t\tpMaxHeight = b.maxWidth / this.aspectRatio;\n\n\t\t\tif (pMinWidth > b.minWidth) {\n\t\t\t\tb.minWidth = pMinWidth;\n\t\t\t}\n\t\t\tif (pMinHeight > b.minHeight) {\n\t\t\t\tb.minHeight = pMinHeight;\n\t\t\t}\n\t\t\tif (pMaxWidth < b.maxWidth) {\n\t\t\t\tb.maxWidth = pMaxWidth;\n\t\t\t}\n\t\t\tif (pMaxHeight < b.maxHeight) {\n\t\t\t\tb.maxHeight = pMaxHeight;\n\t\t\t}\n\t\t}\n\t\tthis._vBoundaries = b;\n\t},\n\n\t_updateCache: function(data) {\n\t\tthis.offset = this.helper.offset();\n\t\tif (this._isNumber(data.left)) {\n\t\t\tthis.position.left = data.left;\n\t\t}\n\t\tif (this._isNumber(data.top)) {\n\t\t\tthis.position.top = data.top;\n\t\t}\n\t\tif (this._isNumber(data.height)) {\n\t\t\tthis.size.height = data.height;\n\t\t}\n\t\tif (this._isNumber(data.width)) {\n\t\t\tthis.size.width = data.width;\n\t\t}\n\t},\n\n\t_updateRatio: function( data ) {\n\n\t\tvar cpos = this.position,\n\t\t\tcsize = this.size,\n\t\t\ta = this.axis;\n\n\t\tif (this._isNumber(data.height)) {\n\t\t\tdata.width = (data.height * this.aspectRatio);\n\t\t} else if (this._isNumber(data.width)) {\n\t\t\tdata.height = (data.width / this.aspectRatio);\n\t\t}\n\n\t\tif (a === \"sw\") {\n\t\t\tdata.left = cpos.left + (csize.width - data.width);\n\t\t\tdata.top = null;\n\t\t}\n\t\tif (a === \"nw\") {\n\t\t\tdata.top = cpos.top + (csize.height - data.height);\n\t\t\tdata.left = cpos.left + (csize.width - data.width);\n\t\t}\n\n\t\treturn data;\n\t},\n\n\t_respectSize: function( data ) {\n\n\t\tvar o = this._vBoundaries,\n\t\t\ta = this.axis,\n\t\t\tismaxw = this._isNumber(data.width) && o.maxWidth && (o.maxWidth < data.width),\n\t\t\tismaxh = this._isNumber(data.height) && o.maxHeight && (o.maxHeight < data.height),\n\t\t\tisminw = this._isNumber(data.width) && o.minWidth && (o.minWidth > data.width),\n\t\t\tisminh = this._isNumber(data.height) && o.minHeight && (o.minHeight > data.height),\n\t\t\tdw = this.originalPosition.left + this.originalSize.width,\n\t\t\tdh = this.position.top + this.size.height,\n\t\t\tcw = /sw|nw|w/.test(a), ch = /nw|ne|n/.test(a);\n\t\tif (isminw) {\n\t\t\tdata.width = o.minWidth;\n\t\t}\n\t\tif (isminh) {\n\t\t\tdata.height = o.minHeight;\n\t\t}\n\t\tif (ismaxw) {\n\t\t\tdata.width = o.maxWidth;\n\t\t}\n\t\tif (ismaxh) {\n\t\t\tdata.height = o.maxHeight;\n\t\t}\n\n\t\tif (isminw && cw) {\n\t\t\tdata.left = dw - o.minWidth;\n\t\t}\n\t\tif (ismaxw && cw) {\n\t\t\tdata.left = dw - o.maxWidth;\n\t\t}\n\t\tif (isminh && ch) {\n\t\t\tdata.top = dh - o.minHeight;\n\t\t}\n\t\tif (ismaxh && ch) {\n\t\t\tdata.top = dh - o.maxHeight;\n\t\t}\n\n\t\t// Fixing jump error on top/left - bug #2330\n\t\tif (!data.width && !data.height && !data.left && data.top) {\n\t\t\tdata.top = null;\n\t\t} else if (!data.width && !data.height && !data.top && data.left) {\n\t\t\tdata.left = null;\n\t\t}\n\n\t\treturn data;\n\t},\n\n\t_getPaddingPlusBorderDimensions: function( element ) {\n\t\tvar i = 0,\n\t\t\twidths = [],\n\t\t\tborders = [\n\t\t\t\telement.css( \"borderTopWidth\" ),\n\t\t\t\telement.css( \"borderRightWidth\" ),\n\t\t\t\telement.css( \"borderBottomWidth\" ),\n\t\t\t\telement.css( \"borderLeftWidth\" )\n\t\t\t],\n\t\t\tpaddings = [\n\t\t\t\telement.css( \"paddingTop\" ),\n\t\t\t\telement.css( \"paddingRight\" ),\n\t\t\t\telement.css( \"paddingBottom\" ),\n\t\t\t\telement.css( \"paddingLeft\" )\n\t\t\t];\n\n\t\tfor ( ; i < 4; i++ ) {\n\t\t\twidths[ i ] = ( parseInt( borders[ i ], 10 ) || 0 );\n\t\t\twidths[ i ] += ( parseInt( paddings[ i ], 10 ) || 0 );\n\t\t}\n\n\t\treturn {\n\t\t\theight: widths[ 0 ] + widths[ 2 ],\n\t\t\twidth: widths[ 1 ] + widths[ 3 ]\n\t\t};\n\t},\n\n\t_proportionallyResize: function() {\n\n\t\tif (!this._proportionallyResizeElements.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar prel,\n\t\t\ti = 0,\n\t\t\telement = this.helper || this.element;\n\n\t\tfor ( ; i < this._proportionallyResizeElements.length; i++) {\n\n\t\t\tprel = this._proportionallyResizeElements[i];\n\n\t\t\t// TODO: Seems like a bug to cache this.outerDimensions\n\t\t\t// considering that we are in a loop.\n\t\t\tif (!this.outerDimensions) {\n\t\t\t\tthis.outerDimensions = this._getPaddingPlusBorderDimensions( prel );\n\t\t\t}\n\n\t\t\tprel.css({\n\t\t\t\theight: (element.height() - this.outerDimensions.height) || 0,\n\t\t\t\twidth: (element.width() - this.outerDimensions.width) || 0\n\t\t\t});\n\n\t\t}\n\n\t},\n\n\t_renderProxy: function() {\n\n\t\tvar el = this.element, o = this.options;\n\t\tthis.elementOffset = el.offset();\n\n\t\tif (this._helper) {\n\n\t\t\tthis.helper = this.helper || $(\"<div style='overflow:hidden;'></div>\");\n\n\t\t\tthis.helper.addClass(this._helper).css({\n\t\t\t\twidth: this.element.outerWidth() - 1,\n\t\t\t\theight: this.element.outerHeight() - 1,\n\t\t\t\tposition: \"absolute\",\n\t\t\t\tleft: this.elementOffset.left + \"px\",\n\t\t\t\ttop: this.elementOffset.top + \"px\",\n\t\t\t\tzIndex: ++o.zIndex //TODO: Don't modify option\n\t\t\t});\n\n\t\t\tthis.helper\n\t\t\t\t.appendTo(\"body\")\n\t\t\t\t.disableSelection();\n\n\t\t} else {\n\t\t\tthis.helper = this.element;\n\t\t}\n\n\t},\n\n\t_change: {\n\t\te: function(event, dx) {\n\t\t\treturn { width: this.originalSize.width + dx };\n\t\t},\n\t\tw: function(event, dx) {\n\t\t\tvar cs = this.originalSize, sp = this.originalPosition;\n\t\t\treturn { left: sp.left + dx, width: cs.width - dx };\n\t\t},\n\t\tn: function(event, dx, dy) {\n\t\t\tvar cs = this.originalSize, sp = this.originalPosition;\n\t\t\treturn { top: sp.top + dy, height: cs.height - dy };\n\t\t},\n\t\ts: function(event, dx, dy) {\n\t\t\treturn { height: this.originalSize.height + dy };\n\t\t},\n\t\tse: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.s.apply(this, arguments),\n\t\t\t\tthis._change.e.apply(this, [ event, dx, dy ]));\n\t\t},\n\t\tsw: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.s.apply(this, arguments),\n\t\t\t\tthis._change.w.apply(this, [ event, dx, dy ]));\n\t\t},\n\t\tne: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.n.apply(this, arguments),\n\t\t\t\tthis._change.e.apply(this, [ event, dx, dy ]));\n\t\t},\n\t\tnw: function(event, dx, dy) {\n\t\t\treturn $.extend(this._change.n.apply(this, arguments),\n\t\t\t\tthis._change.w.apply(this, [ event, dx, dy ]));\n\t\t}\n\t},\n\n\t_propagate: function(n, event) {\n\t\t$.ui.plugin.call(this, n, [ event, this.ui() ]);\n\t\t(n !== \"resize\" && this._trigger(n, event, this.ui()));\n\t},\n\n\tplugins: {},\n\n\tui: function() {\n\t\treturn {\n\t\t\toriginalElement: this.originalElement,\n\t\t\telement: this.element,\n\t\t\thelper: this.helper,\n\t\t\tposition: this.position,\n\t\t\tsize: this.size,\n\t\t\toriginalSize: this.originalSize,\n\t\t\toriginalPosition: this.originalPosition\n\t\t};\n\t}\n\n});\n\n/*\n * Resizable Extensions\n */\n\n$.ui.plugin.add(\"resizable\", \"animate\", {\n\n\tstop: function( event ) {\n\t\tvar that = $(this).resizable( \"instance\" ),\n\t\t\to = that.options,\n\t\t\tpr = that._proportionallyResizeElements,\n\t\t\tista = pr.length && (/textarea/i).test(pr[0].nodeName),\n\t\t\tsoffseth = ista && that._hasScroll(pr[0], \"left\") ? 0 : that.sizeDiff.height,\n\t\t\tsoffsetw = ista ? 0 : that.sizeDiff.width,\n\t\t\tstyle = { width: (that.size.width - soffsetw), height: (that.size.height - soffseth) },\n\t\t\tleft = (parseInt(that.element.css(\"left\"), 10) +\n\t\t\t\t(that.position.left - that.originalPosition.left)) || null,\n\t\t\ttop = (parseInt(that.element.css(\"top\"), 10) +\n\t\t\t\t(that.position.top - that.originalPosition.top)) || null;\n\n\t\tthat.element.animate(\n\t\t\t$.extend(style, top && left ? { top: top, left: left } : {}), {\n\t\t\t\tduration: o.animateDuration,\n\t\t\t\teasing: o.animateEasing,\n\t\t\t\tstep: function() {\n\n\t\t\t\t\tvar data = {\n\t\t\t\t\t\twidth: parseInt(that.element.css(\"width\"), 10),\n\t\t\t\t\t\theight: parseInt(that.element.css(\"height\"), 10),\n\t\t\t\t\t\ttop: parseInt(that.element.css(\"top\"), 10),\n\t\t\t\t\t\tleft: parseInt(that.element.css(\"left\"), 10)\n\t\t\t\t\t};\n\n\t\t\t\t\tif (pr && pr.length) {\n\t\t\t\t\t\t$(pr[0]).css({ width: data.width, height: data.height });\n\t\t\t\t\t}\n\n\t\t\t\t\t// propagating resize, and updating values for each animation step\n\t\t\t\t\tthat._updateCache(data);\n\t\t\t\t\tthat._propagate(\"resize\", event);\n\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\t}\n\n});\n\n$.ui.plugin.add( \"resizable\", \"containment\", {\n\n\tstart: function() {\n\t\tvar element, p, co, ch, cw, width, height,\n\t\t\tthat = $( this ).resizable( \"instance\" ),\n\t\t\to = that.options,\n\t\t\tel = that.element,\n\t\t\toc = o.containment,\n\t\t\tce = ( oc instanceof $ ) ? oc.get( 0 ) : ( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;\n\n\t\tif ( !ce ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthat.containerElement = $( ce );\n\n\t\tif ( /document/.test( oc ) || oc === document ) {\n\t\t\tthat.containerOffset = {\n\t\t\t\tleft: 0,\n\t\t\t\ttop: 0\n\t\t\t};\n\t\t\tthat.containerPosition = {\n\t\t\t\tleft: 0,\n\t\t\t\ttop: 0\n\t\t\t};\n\n\t\t\tthat.parentData = {\n\t\t\t\telement: $( document ),\n\t\t\t\tleft: 0,\n\t\t\t\ttop: 0,\n\t\t\t\twidth: $( document ).width(),\n\t\t\t\theight: $( document ).height() || document.body.parentNode.scrollHeight\n\t\t\t};\n\t\t} else {\n\t\t\telement = $( ce );\n\t\t\tp = [];\n\t\t\t$([ \"Top\", \"Right\", \"Left\", \"Bottom\" ]).each(function( i, name ) {\n\t\t\t\tp[ i ] = that._num( element.css( \"padding\" + name ) );\n\t\t\t});\n\n\t\t\tthat.containerOffset = element.offset();\n\t\t\tthat.containerPosition = element.position();\n\t\t\tthat.containerSize = {\n\t\t\t\theight: ( element.innerHeight() - p[ 3 ] ),\n\t\t\t\twidth: ( element.innerWidth() - p[ 1 ] )\n\t\t\t};\n\n\t\t\tco = that.containerOffset;\n\t\t\tch = that.containerSize.height;\n\t\t\tcw = that.containerSize.width;\n\t\t\twidth = ( that._hasScroll ( ce, \"left\" ) ? ce.scrollWidth : cw );\n\t\t\theight = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;\n\n\t\t\tthat.parentData = {\n\t\t\t\telement: ce,\n\t\t\t\tleft: co.left,\n\t\t\t\ttop: co.top,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t};\n\t\t}\n\t},\n\n\tresize: function( event ) {\n\t\tvar woset, hoset, isParent, isOffsetRelative,\n\t\t\tthat = $( this ).resizable( \"instance\" ),\n\t\t\to = that.options,\n\t\t\tco = that.containerOffset,\n\t\t\tcp = that.position,\n\t\t\tpRatio = that._aspectRatio || event.shiftKey,\n\t\t\tcop = {\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0\n\t\t\t},\n\t\t\tce = that.containerElement,\n\t\t\tcontinueResize = true;\n\n\t\tif ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( \"position\" ) ) ) {\n\t\t\tcop = co;\n\t\t}\n\n\t\tif ( cp.left < ( that._helper ? co.left : 0 ) ) {\n\t\t\tthat.size.width = that.size.width +\n\t\t\t\t( that._helper ?\n\t\t\t\t\t( that.position.left - co.left ) :\n\t\t\t\t\t( that.position.left - cop.left ) );\n\n\t\t\tif ( pRatio ) {\n\t\t\t\tthat.size.height = that.size.width / that.aspectRatio;\n\t\t\t\tcontinueResize = false;\n\t\t\t}\n\t\t\tthat.position.left = o.helper ? co.left : 0;\n\t\t}\n\n\t\tif ( cp.top < ( that._helper ? co.top : 0 ) ) {\n\t\t\tthat.size.height = that.size.height +\n\t\t\t\t( that._helper ?\n\t\t\t\t\t( that.position.top - co.top ) :\n\t\t\t\t\tthat.position.top );\n\n\t\t\tif ( pRatio ) {\n\t\t\t\tthat.size.width = that.size.height * that.aspectRatio;\n\t\t\t\tcontinueResize = false;\n\t\t\t}\n\t\t\tthat.position.top = that._helper ? co.top : 0;\n\t\t}\n\n\t\tisParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );\n\t\tisOffsetRelative = /relative|absolute/.test( that.containerElement.css( \"position\" ) );\n\n\t\tif ( isParent && isOffsetRelative ) {\n\t\t\tthat.offset.left = that.parentData.left + that.position.left;\n\t\t\tthat.offset.top = that.parentData.top + that.position.top;\n\t\t} else {\n\t\t\tthat.offset.left = that.element.offset().left;\n\t\t\tthat.offset.top = that.element.offset().top;\n\t\t}\n\n\t\twoset = Math.abs( that.sizeDiff.width +\n\t\t\t(that._helper ?\n\t\t\t\tthat.offset.left - cop.left :\n\t\t\t\t(that.offset.left - co.left)) );\n\n\t\thoset = Math.abs( that.sizeDiff.height +\n\t\t\t(that._helper ?\n\t\t\t\tthat.offset.top - cop.top :\n\t\t\t\t(that.offset.top - co.top)) );\n\n\t\tif ( woset + that.size.width >= that.parentData.width ) {\n\t\t\tthat.size.width = that.parentData.width - woset;\n\t\t\tif ( pRatio ) {\n\t\t\t\tthat.size.height = that.size.width / that.aspectRatio;\n\t\t\t\tcontinueResize = false;\n\t\t\t}\n\t\t}\n\n\t\tif ( hoset + that.size.height >= that.parentData.height ) {\n\t\t\tthat.size.height = that.parentData.height - hoset;\n\t\t\tif ( pRatio ) {\n\t\t\t\tthat.size.width = that.size.height * that.aspectRatio;\n\t\t\t\tcontinueResize = false;\n\t\t\t}\n\t\t}\n\n\t\tif ( !continueResize ) {\n\t\t\tthat.position.left = that.prevPosition.left;\n\t\t\tthat.position.top = that.prevPosition.top;\n\t\t\tthat.size.width = that.prevSize.width;\n\t\t\tthat.size.height = that.prevSize.height;\n\t\t}\n\t},\n\n\tstop: function() {\n\t\tvar that = $( this ).resizable( \"instance\" ),\n\t\t\to = that.options,\n\t\t\tco = that.containerOffset,\n\t\t\tcop = that.containerPosition,\n\t\t\tce = that.containerElement,\n\t\t\thelper = $( that.helper ),\n\t\t\tho = helper.offset(),\n\t\t\tw = helper.outerWidth() - that.sizeDiff.width,\n\t\t\th = helper.outerHeight() - that.sizeDiff.height;\n\n\t\tif ( that._helper && !o.animate && ( /relative/ ).test( ce.css( \"position\" ) ) ) {\n\t\t\t$( this ).css({\n\t\t\t\tleft: ho.left - cop.left - co.left,\n\t\t\t\twidth: w,\n\t\t\t\theight: h\n\t\t\t});\n\t\t}\n\n\t\tif ( that._helper && !o.animate && ( /static/ ).test( ce.css( \"position\" ) ) ) {\n\t\t\t$( this ).css({\n\t\t\t\tleft: ho.left - cop.left - co.left,\n\t\t\t\twidth: w,\n\t\t\t\theight: h\n\t\t\t});\n\t\t}\n\t}\n});\n\n$.ui.plugin.add(\"resizable\", \"alsoResize\", {\n\n\tstart: function() {\n\t\tvar that = $(this).resizable( \"instance\" ),\n\t\t\to = that.options;\n\n\t\t$(o.alsoResize).each(function() {\n\t\t\tvar el = $(this);\n\t\t\tel.data(\"ui-resizable-alsoresize\", {\n\t\t\t\twidth: parseInt(el.width(), 10), height: parseInt(el.height(), 10),\n\t\t\t\tleft: parseInt(el.css(\"left\"), 10), top: parseInt(el.css(\"top\"), 10)\n\t\t\t});\n\t\t});\n\t},\n\n\tresize: function(event, ui) {\n\t\tvar that = $(this).resizable( \"instance\" ),\n\t\t\to = that.options,\n\t\t\tos = that.originalSize,\n\t\t\top = that.originalPosition,\n\t\t\tdelta = {\n\t\t\t\theight: (that.size.height - os.height) || 0,\n\t\t\t\twidth: (that.size.width - os.width) || 0,\n\t\t\t\ttop: (that.position.top - op.top) || 0,\n\t\t\t\tleft: (that.position.left - op.left) || 0\n\t\t\t};\n\n\t\t\t$(o.alsoResize).each(function() {\n\t\t\t\tvar el = $(this), start = $(this).data(\"ui-resizable-alsoresize\"), style = {},\n\t\t\t\t\tcss = el.parents(ui.originalElement[0]).length ?\n\t\t\t\t\t\t\t[ \"width\", \"height\" ] :\n\t\t\t\t\t\t\t[ \"width\", \"height\", \"top\", \"left\" ];\n\n\t\t\t\t$.each(css, function(i, prop) {\n\t\t\t\t\tvar sum = (start[prop] || 0) + (delta[prop] || 0);\n\t\t\t\t\tif (sum && sum >= 0) {\n\t\t\t\t\t\tstyle[prop] = sum || null;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tel.css(style);\n\t\t\t});\n\t},\n\n\tstop: function() {\n\t\t$(this).removeData(\"resizable-alsoresize\");\n\t}\n});\n\n$.ui.plugin.add(\"resizable\", \"ghost\", {\n\n\tstart: function() {\n\n\t\tvar that = $(this).resizable( \"instance\" ), o = that.options, cs = that.size;\n\n\t\tthat.ghost = that.originalElement.clone();\n\t\tthat.ghost\n\t\t\t.css({\n\t\t\t\topacity: 0.25,\n\t\t\t\tdisplay: \"block\",\n\t\t\t\tposition: \"relative\",\n\t\t\t\theight: cs.height,\n\t\t\t\twidth: cs.width,\n\t\t\t\tmargin: 0,\n\t\t\t\tleft: 0,\n\t\t\t\ttop: 0\n\t\t\t})\n\t\t\t.addClass(\"ui-resizable-ghost\")\n\t\t\t.addClass(typeof o.ghost === \"string\" ? o.ghost : \"\");\n\n\t\tthat.ghost.appendTo(that.helper);\n\n\t},\n\n\tresize: function() {\n\t\tvar that = $(this).resizable( \"instance\" );\n\t\tif (that.ghost) {\n\t\t\tthat.ghost.css({\n\t\t\t\tposition: \"relative\",\n\t\t\t\theight: that.size.height,\n\t\t\t\twidth: that.size.width\n\t\t\t});\n\t\t}\n\t},\n\n\tstop: function() {\n\t\tvar that = $(this).resizable( \"instance\" );\n\t\tif (that.ghost && that.helper) {\n\t\t\tthat.helper.get(0).removeChild(that.ghost.get(0));\n\t\t}\n\t}\n\n});\n\n$.ui.plugin.add(\"resizable\", \"grid\", {\n\n\tresize: function() {\n\t\tvar outerDimensions,\n\t\t\tthat = $(this).resizable( \"instance\" ),\n\t\t\to = that.options,\n\t\t\tcs = that.size,\n\t\t\tos = that.originalSize,\n\t\t\top = that.originalPosition,\n\t\t\ta = that.axis,\n\t\t\tgrid = typeof o.grid === \"number\" ? [ o.grid, o.grid ] : o.grid,\n\t\t\tgridX = (grid[0] || 1),\n\t\t\tgridY = (grid[1] || 1),\n\t\t\tox = Math.round((cs.width - os.width) / gridX) * gridX,\n\t\t\toy = Math.round((cs.height - os.height) / gridY) * gridY,\n\t\t\tnewWidth = os.width + ox,\n\t\t\tnewHeight = os.height + oy,\n\t\t\tisMaxWidth = o.maxWidth && (o.maxWidth < newWidth),\n\t\t\tisMaxHeight = o.maxHeight && (o.maxHeight < newHeight),\n\t\t\tisMinWidth = o.minWidth && (o.minWidth > newWidth),\n\t\t\tisMinHeight = o.minHeight && (o.minHeight > newHeight);\n\n\t\to.grid = grid;\n\n\t\tif (isMinWidth) {\n\t\t\tnewWidth += gridX;\n\t\t}\n\t\tif (isMinHeight) {\n\t\t\tnewHeight += gridY;\n\t\t}\n\t\tif (isMaxWidth) {\n\t\t\tnewWidth -= gridX;\n\t\t}\n\t\tif (isMaxHeight) {\n\t\t\tnewHeight -= gridY;\n\t\t}\n\n\t\tif (/^(se|s|e)$/.test(a)) {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t} else if (/^(ne)$/.test(a)) {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t\tthat.position.top = op.top - oy;\n\t\t} else if (/^(sw)$/.test(a)) {\n\t\t\tthat.size.width = newWidth;\n\t\t\tthat.size.height = newHeight;\n\t\t\tthat.position.left = op.left - ox;\n\t\t} else {\n\t\t\tif ( newHeight - gridY <= 0 || newWidth - gridX <= 0) {\n\t\t\t\touterDimensions = that._getPaddingPlusBorderDimensions( this );\n\t\t\t}\n\n\t\t\tif ( newHeight - gridY > 0 ) {\n\t\t\t\tthat.size.height = newHeight;\n\t\t\t\tthat.position.top = op.top - oy;\n\t\t\t} else {\n\t\t\t\tnewHeight = gridY - outerDimensions.height;\n\t\t\t\tthat.size.height = newHeight;\n\t\t\t\tthat.position.top = op.top + os.height - newHeight;\n\t\t\t}\n\t\t\tif ( newWidth - gridX > 0 ) {\n\t\t\t\tthat.size.width = newWidth;\n\t\t\t\tthat.position.left = op.left - ox;\n\t\t\t} else {\n\t\t\t\tnewWidth = gridX - outerDimensions.width;\n\t\t\t\tthat.size.width = newWidth;\n\t\t\t\tthat.position.left = op.left + os.width - newWidth;\n\t\t\t}\n\t\t}\n\t}\n\n});\n\nvar resizable = $.ui.resizable;\n\n\n/*!\n * jQuery UI Dialog 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/dialog/\n */\n\n\nvar dialog = $.widget( \"ui.dialog\", {\n\tversion: \"1.11.4\",\n\toptions: {\n\t\tappendTo: \"body\",\n\t\tautoOpen: true,\n\t\tbuttons: [],\n\t\tcloseOnEscape: true,\n\t\tcloseText: \"Close\",\n\t\tdialogClass: \"\",\n\t\tdraggable: true,\n\t\thide: null,\n\t\theight: \"auto\",\n\t\tmaxHeight: null,\n\t\tmaxWidth: null,\n\t\tminHeight: 150,\n\t\tminWidth: 150,\n\t\tmodal: false,\n\t\tposition: {\n\t\t\tmy: \"center\",\n\t\t\tat: \"center\",\n\t\t\tof: window,\n\t\t\tcollision: \"fit\",\n\t\t\t// Ensure the titlebar is always visible\n\t\t\tusing: function( pos ) {\n\t\t\t\tvar topOffset = $( this ).css( pos ).offset().top;\n\t\t\t\tif ( topOffset < 0 ) {\n\t\t\t\t\t$( this ).css( \"top\", pos.top - topOffset );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tresizable: true,\n\t\tshow: null,\n\t\ttitle: null,\n\t\twidth: 300,\n\n\t\t// callbacks\n\t\tbeforeClose: null,\n\t\tclose: null,\n\t\tdrag: null,\n\t\tdragStart: null,\n\t\tdragStop: null,\n\t\tfocus: null,\n\t\topen: null,\n\t\tresize: null,\n\t\tresizeStart: null,\n\t\tresizeStop: null\n\t},\n\n\tsizeRelatedOptions: {\n\t\tbuttons: true,\n\t\theight: true,\n\t\tmaxHeight: true,\n\t\tmaxWidth: true,\n\t\tminHeight: true,\n\t\tminWidth: true,\n\t\twidth: true\n\t},\n\n\tresizableRelatedOptions: {\n\t\tmaxHeight: true,\n\t\tmaxWidth: true,\n\t\tminHeight: true,\n\t\tminWidth: true\n\t},\n\n\t_create: function() {\n\t\tthis.originalCss = {\n\t\t\tdisplay: this.element[ 0 ].style.display,\n\t\t\twidth: this.element[ 0 ].style.width,\n\t\t\tminHeight: this.element[ 0 ].style.minHeight,\n\t\t\tmaxHeight: this.element[ 0 ].style.maxHeight,\n\t\t\theight: this.element[ 0 ].style.height\n\t\t};\n\t\tthis.originalPosition = {\n\t\t\tparent: this.element.parent(),\n\t\t\tindex: this.element.parent().children().index( this.element )\n\t\t};\n\t\tthis.originalTitle = this.element.attr( \"title\" );\n\t\tthis.options.title = this.options.title || this.originalTitle;\n\n\t\tthis._createWrapper();\n\n\t\tthis.element\n\t\t\t.show()\n\t\t\t.removeAttr( \"title\" )\n\t\t\t.addClass( \"ui-dialog-content ui-widget-content\" )\n\t\t\t.appendTo( this.uiDialog );\n\n\t\tthis._createTitlebar();\n\t\tthis._createButtonPane();\n\n\t\tif ( this.options.draggable && $.fn.draggable ) {\n\t\t\tthis._makeDraggable();\n\t\t}\n\t\tif ( this.options.resizable && $.fn.resizable ) {\n\t\t\tthis._makeResizable();\n\t\t}\n\n\t\tthis._isOpen = false;\n\n\t\tthis._trackFocus();\n\t},\n\n\t_init: function() {\n\t\tif ( this.options.autoOpen ) {\n\t\t\tthis.open();\n\t\t}\n\t},\n\n\t_appendTo: function() {\n\t\tvar element = this.options.appendTo;\n\t\tif ( element && (element.jquery || element.nodeType) ) {\n\t\t\treturn $( element );\n\t\t}\n\t\treturn this.document.find( element || \"body\" ).eq( 0 );\n\t},\n\n\t_destroy: function() {\n\t\tvar next,\n\t\t\toriginalPosition = this.originalPosition;\n\n\t\tthis._untrackInstance();\n\t\tthis._destroyOverlay();\n\n\t\tthis.element\n\t\t\t.removeUniqueId()\n\t\t\t.removeClass( \"ui-dialog-content ui-widget-content\" )\n\t\t\t.css( this.originalCss )\n\t\t\t// Without detaching first, the following becomes really slow\n\t\t\t.detach();\n\n\t\tthis.uiDialog.stop( true, true ).remove();\n\n\t\tif ( this.originalTitle ) {\n\t\t\tthis.element.attr( \"title\", this.originalTitle );\n\t\t}\n\n\t\tnext = originalPosition.parent.children().eq( originalPosition.index );\n\t\t// Don't try to place the dialog next to itself (#8613)\n\t\tif ( next.length && next[ 0 ] !== this.element[ 0 ] ) {\n\t\t\tnext.before( this.element );\n\t\t} else {\n\t\t\toriginalPosition.parent.append( this.element );\n\t\t}\n\t},\n\n\twidget: function() {\n\t\treturn this.uiDialog;\n\t},\n\n\tdisable: $.noop,\n\tenable: $.noop,\n\n\tclose: function( event ) {\n\t\tvar activeElement,\n\t\t\tthat = this;\n\n\t\tif ( !this._isOpen || this._trigger( \"beforeClose\", event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isOpen = false;\n\t\tthis._focusedElement = null;\n\t\tthis._destroyOverlay();\n\t\tthis._untrackInstance();\n\n\t\tif ( !this.opener.filter( \":focusable\" ).focus().length ) {\n\n\t\t\t// support: IE9\n\t\t\t// IE9 throws an \"Unspecified error\" accessing document.activeElement from an <iframe>\n\t\t\ttry {\n\t\t\t\tactiveElement = this.document[ 0 ].activeElement;\n\n\t\t\t\t// Support: IE9, IE10\n\t\t\t\t// If the <body> is blurred, IE will switch windows, see #4520\n\t\t\t\tif ( activeElement && activeElement.nodeName.toLowerCase() !== \"body\" ) {\n\n\t\t\t\t\t// Hiding a focused element doesn't trigger blur in WebKit\n\t\t\t\t\t// so in case we have nothing to focus on, explicitly blur the active element\n\t\t\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=47182\n\t\t\t\t\t$( activeElement ).blur();\n\t\t\t\t}\n\t\t\t} catch ( error ) {}\n\t\t}\n\n\t\tthis._hide( this.uiDialog, this.options.hide, function() {\n\t\t\tthat._trigger( \"close\", event );\n\t\t});\n\t},\n\n\tisOpen: function() {\n\t\treturn this._isOpen;\n\t},\n\n\tmoveToTop: function() {\n\t\tthis._moveToTop();\n\t},\n\n\t_moveToTop: function( event, silent ) {\n\t\tvar moved = false,\n\t\t\tzIndices = this.uiDialog.siblings( \".ui-front:visible\" ).map(function() {\n\t\t\t\treturn +$( this ).css( \"z-index\" );\n\t\t\t}).get(),\n\t\t\tzIndexMax = Math.max.apply( null, zIndices );\n\n\t\tif ( zIndexMax >= +this.uiDialog.css( \"z-index\" ) ) {\n\t\t\tthis.uiDialog.css( \"z-index\", zIndexMax + 1 );\n\t\t\tmoved = true;\n\t\t}\n\n\t\tif ( moved && !silent ) {\n\t\t\tthis._trigger( \"focus\", event );\n\t\t}\n\t\treturn moved;\n\t},\n\n\topen: function() {\n\t\tvar that = this;\n\t\tif ( this._isOpen ) {\n\t\t\tif ( this._moveToTop() ) {\n\t\t\t\tthis._focusTabbable();\n\t\t\t}\n\t\t\treturn;\n\t\t}\n\n\t\tthis._isOpen = true;\n\t\tthis.opener = $( this.document[ 0 ].activeElement );\n\n\t\tthis._size();\n\t\tthis._position();\n\t\tthis._createOverlay();\n\t\tthis._moveToTop( null, true );\n\n\t\t// Ensure the overlay is moved to the top with the dialog, but only when\n\t\t// opening. The overlay shouldn't move after the dialog is open so that\n\t\t// modeless dialogs opened after the modal dialog stack properly.\n\t\tif ( this.overlay ) {\n\t\t\tthis.overlay.css( \"z-index\", this.uiDialog.css( \"z-index\" ) - 1 );\n\t\t}\n\n\t\tthis._show( this.uiDialog, this.options.show, function() {\n\t\t\tthat._focusTabbable();\n\t\t\tthat._trigger( \"focus\" );\n\t\t});\n\n\t\t// Track the dialog immediately upon openening in case a focus event\n\t\t// somehow occurs outside of the dialog before an element inside the\n\t\t// dialog is focused (#10152)\n\t\tthis._makeFocusTarget();\n\n\t\tthis._trigger( \"open\" );\n\t},\n\n\t_focusTabbable: function() {\n\t\t// Set focus to the first match:\n\t\t// 1. An element that was focused previously\n\t\t// 2. First element inside the dialog matching [autofocus]\n\t\t// 3. Tabbable element inside the content element\n\t\t// 4. Tabbable element inside the buttonpane\n\t\t// 5. The close button\n\t\t// 6. The dialog itself\n\t\tvar hasFocus = this._focusedElement;\n\t\tif ( !hasFocus ) {\n\t\t\thasFocus = this.element.find( \"[autofocus]\" );\n\t\t}\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.element.find( \":tabbable\" );\n\t\t}\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.uiDialogButtonPane.find( \":tabbable\" );\n\t\t}\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.uiDialogTitlebarClose.filter( \":tabbable\" );\n\t\t}\n\t\tif ( !hasFocus.length ) {\n\t\t\thasFocus = this.uiDialog;\n\t\t}\n\t\thasFocus.eq( 0 ).focus();\n\t},\n\n\t_keepFocus: function( event ) {\n\t\tfunction checkFocus() {\n\t\t\tvar activeElement = this.document[0].activeElement,\n\t\t\t\tisActive = this.uiDialog[0] === activeElement ||\n\t\t\t\t\t$.contains( this.uiDialog[0], activeElement );\n\t\t\tif ( !isActive ) {\n\t\t\t\tthis._focusTabbable();\n\t\t\t}\n\t\t}\n\t\tevent.preventDefault();\n\t\tcheckFocus.call( this );\n\t\t// support: IE\n\t\t// IE <= 8 doesn't prevent moving focus even with event.preventDefault()\n\t\t// so we check again later\n\t\tthis._delay( checkFocus );\n\t},\n\n\t_createWrapper: function() {\n\t\tthis.uiDialog = $(\"<div>\")\n\t\t\t.addClass( \"ui-dialog ui-widget ui-widget-content ui-corner-all ui-front \" +\n\t\t\t\tthis.options.dialogClass )\n\t\t\t.hide()\n\t\t\t.attr({\n\t\t\t\t// Setting tabIndex makes the div focusable\n\t\t\t\ttabIndex: -1,\n\t\t\t\trole: \"dialog\"\n\t\t\t})\n\t\t\t.appendTo( this._appendTo() );\n\n\t\tthis._on( this.uiDialog, {\n\t\t\tkeydown: function( event ) {\n\t\t\t\tif ( this.options.closeOnEscape && !event.isDefaultPrevented() && event.keyCode &&\n\t\t\t\t\t\tevent.keyCode === $.ui.keyCode.ESCAPE ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tthis.close( event );\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// prevent tabbing out of dialogs\n\t\t\t\tif ( event.keyCode !== $.ui.keyCode.TAB || event.isDefaultPrevented() ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tvar tabbables = this.uiDialog.find( \":tabbable\" ),\n\t\t\t\t\tfirst = tabbables.filter( \":first\" ),\n\t\t\t\t\tlast = tabbables.filter( \":last\" );\n\n\t\t\t\tif ( ( event.target === last[0] || event.target === this.uiDialog[0] ) && !event.shiftKey ) {\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tfirst.focus();\n\t\t\t\t\t});\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t} else if ( ( event.target === first[0] || event.target === this.uiDialog[0] ) && event.shiftKey ) {\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tlast.focus();\n\t\t\t\t\t});\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t},\n\t\t\tmousedown: function( event ) {\n\t\t\t\tif ( this._moveToTop( event ) ) {\n\t\t\t\t\tthis._focusTabbable();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// We assume that any existing aria-describedby attribute means\n\t\t// that the dialog content is marked up properly\n\t\t// otherwise we brute force the content as the description\n\t\tif ( !this.element.find( \"[aria-describedby]\" ).length ) {\n\t\t\tthis.uiDialog.attr({\n\t\t\t\t\"aria-describedby\": this.element.uniqueId().attr( \"id\" )\n\t\t\t});\n\t\t}\n\t},\n\n\t_createTitlebar: function() {\n\t\tvar uiDialogTitle;\n\n\t\tthis.uiDialogTitlebar = $( \"<div>\" )\n\t\t\t.addClass( \"ui-dialog-titlebar ui-widget-header ui-corner-all ui-helper-clearfix\" )\n\t\t\t.prependTo( this.uiDialog );\n\t\tthis._on( this.uiDialogTitlebar, {\n\t\t\tmousedown: function( event ) {\n\t\t\t\t// Don't prevent click on close button (#8838)\n\t\t\t\t// Focusing a dialog that is partially scrolled out of view\n\t\t\t\t// causes the browser to scroll it into view, preventing the click event\n\t\t\t\tif ( !$( event.target ).closest( \".ui-dialog-titlebar-close\" ) ) {\n\t\t\t\t\t// Dialog isn't getting focus when dragging (#8063)\n\t\t\t\t\tthis.uiDialog.focus();\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// support: IE\n\t\t// Use type=\"button\" to prevent enter keypresses in textboxes from closing the\n\t\t// dialog in IE (#9312)\n\t\tthis.uiDialogTitlebarClose = $( \"<button type='button'></button>\" )\n\t\t\t.button({\n\t\t\t\tlabel: this.options.closeText,\n\t\t\t\ticons: {\n\t\t\t\t\tprimary: \"ui-icon-closethick\"\n\t\t\t\t},\n\t\t\t\ttext: false\n\t\t\t})\n\t\t\t.addClass( \"ui-dialog-titlebar-close\" )\n\t\t\t.appendTo( this.uiDialogTitlebar );\n\t\tthis._on( this.uiDialogTitlebarClose, {\n\t\t\tclick: function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t\tthis.close( event );\n\t\t\t}\n\t\t});\n\n\t\tuiDialogTitle = $( \"<span>\" )\n\t\t\t.uniqueId()\n\t\t\t.addClass( \"ui-dialog-title\" )\n\t\t\t.prependTo( this.uiDialogTitlebar );\n\t\tthis._title( uiDialogTitle );\n\n\t\tthis.uiDialog.attr({\n\t\t\t\"aria-labelledby\": uiDialogTitle.attr( \"id\" )\n\t\t});\n\t},\n\n\t_title: function( title ) {\n\t\tif ( !this.options.title ) {\n\t\t\ttitle.html( \"&#160;\" );\n\t\t}\n\t\ttitle.text( this.options.title );\n\t},\n\n\t_createButtonPane: function() {\n\t\tthis.uiDialogButtonPane = $( \"<div>\" )\n\t\t\t.addClass( \"ui-dialog-buttonpane ui-widget-content ui-helper-clearfix\" );\n\n\t\tthis.uiButtonSet = $( \"<div>\" )\n\t\t\t.addClass( \"ui-dialog-buttonset\" )\n\t\t\t.appendTo( this.uiDialogButtonPane );\n\n\t\tthis._createButtons();\n\t},\n\n\t_createButtons: function() {\n\t\tvar that = this,\n\t\t\tbuttons = this.options.buttons;\n\n\t\t// if we already have a button pane, remove it\n\t\tthis.uiDialogButtonPane.remove();\n\t\tthis.uiButtonSet.empty();\n\n\t\tif ( $.isEmptyObject( buttons ) || ($.isArray( buttons ) && !buttons.length) ) {\n\t\t\tthis.uiDialog.removeClass( \"ui-dialog-buttons\" );\n\t\t\treturn;\n\t\t}\n\n\t\t$.each( buttons, function( name, props ) {\n\t\t\tvar click, buttonOptions;\n\t\t\tprops = $.isFunction( props ) ?\n\t\t\t\t{ click: props, text: name } :\n\t\t\t\tprops;\n\t\t\t// Default to a non-submitting button\n\t\t\tprops = $.extend( { type: \"button\" }, props );\n\t\t\t// Change the context for the click callback to be the main element\n\t\t\tclick = props.click;\n\t\t\tprops.click = function() {\n\t\t\t\tclick.apply( that.element[ 0 ], arguments );\n\t\t\t};\n\t\t\tbuttonOptions = {\n\t\t\t\ticons: props.icons,\n\t\t\t\ttext: props.showText\n\t\t\t};\n\t\t\tdelete props.icons;\n\t\t\tdelete props.showText;\n\t\t\t$( \"<button></button>\", props )\n\t\t\t\t.button( buttonOptions )\n\t\t\t\t.appendTo( that.uiButtonSet );\n\t\t});\n\t\tthis.uiDialog.addClass( \"ui-dialog-buttons\" );\n\t\tthis.uiDialogButtonPane.appendTo( this.uiDialog );\n\t},\n\n\t_makeDraggable: function() {\n\t\tvar that = this,\n\t\t\toptions = this.options;\n\n\t\tfunction filteredUi( ui ) {\n\t\t\treturn {\n\t\t\t\tposition: ui.position,\n\t\t\t\toffset: ui.offset\n\t\t\t};\n\t\t}\n\n\t\tthis.uiDialog.draggable({\n\t\t\tcancel: \".ui-dialog-content, .ui-dialog-titlebar-close\",\n\t\t\thandle: \".ui-dialog-titlebar\",\n\t\t\tcontainment: \"document\",\n\t\t\tstart: function( event, ui ) {\n\t\t\t\t$( this ).addClass( \"ui-dialog-dragging\" );\n\t\t\t\tthat._blockFrames();\n\t\t\t\tthat._trigger( \"dragStart\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tdrag: function( event, ui ) {\n\t\t\t\tthat._trigger( \"drag\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tstop: function( event, ui ) {\n\t\t\t\tvar left = ui.offset.left - that.document.scrollLeft(),\n\t\t\t\t\ttop = ui.offset.top - that.document.scrollTop();\n\n\t\t\t\toptions.position = {\n\t\t\t\t\tmy: \"left top\",\n\t\t\t\t\tat: \"left\" + (left >= 0 ? \"+\" : \"\") + left + \" \" +\n\t\t\t\t\t\t\"top\" + (top >= 0 ? \"+\" : \"\") + top,\n\t\t\t\t\tof: that.window\n\t\t\t\t};\n\t\t\t\t$( this ).removeClass( \"ui-dialog-dragging\" );\n\t\t\t\tthat._unblockFrames();\n\t\t\t\tthat._trigger( \"dragStop\", event, filteredUi( ui ) );\n\t\t\t}\n\t\t});\n\t},\n\n\t_makeResizable: function() {\n\t\tvar that = this,\n\t\t\toptions = this.options,\n\t\t\thandles = options.resizable,\n\t\t\t// .ui-resizable has position: relative defined in the stylesheet\n\t\t\t// but dialogs have to use absolute or fixed positioning\n\t\t\tposition = this.uiDialog.css(\"position\"),\n\t\t\tresizeHandles = typeof handles === \"string\" ?\n\t\t\t\thandles\t:\n\t\t\t\t\"n,e,s,w,se,sw,ne,nw\";\n\n\t\tfunction filteredUi( ui ) {\n\t\t\treturn {\n\t\t\t\toriginalPosition: ui.originalPosition,\n\t\t\t\toriginalSize: ui.originalSize,\n\t\t\t\tposition: ui.position,\n\t\t\t\tsize: ui.size\n\t\t\t};\n\t\t}\n\n\t\tthis.uiDialog.resizable({\n\t\t\tcancel: \".ui-dialog-content\",\n\t\t\tcontainment: \"document\",\n\t\t\talsoResize: this.element,\n\t\t\tmaxWidth: options.maxWidth,\n\t\t\tmaxHeight: options.maxHeight,\n\t\t\tminWidth: options.minWidth,\n\t\t\tminHeight: this._minHeight(),\n\t\t\thandles: resizeHandles,\n\t\t\tstart: function( event, ui ) {\n\t\t\t\t$( this ).addClass( \"ui-dialog-resizing\" );\n\t\t\t\tthat._blockFrames();\n\t\t\t\tthat._trigger( \"resizeStart\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tresize: function( event, ui ) {\n\t\t\t\tthat._trigger( \"resize\", event, filteredUi( ui ) );\n\t\t\t},\n\t\t\tstop: function( event, ui ) {\n\t\t\t\tvar offset = that.uiDialog.offset(),\n\t\t\t\t\tleft = offset.left - that.document.scrollLeft(),\n\t\t\t\t\ttop = offset.top - that.document.scrollTop();\n\n\t\t\t\toptions.height = that.uiDialog.height();\n\t\t\t\toptions.width = that.uiDialog.width();\n\t\t\t\toptions.position = {\n\t\t\t\t\tmy: \"left top\",\n\t\t\t\t\tat: \"left\" + (left >= 0 ? \"+\" : \"\") + left + \" \" +\n\t\t\t\t\t\t\"top\" + (top >= 0 ? \"+\" : \"\") + top,\n\t\t\t\t\tof: that.window\n\t\t\t\t};\n\t\t\t\t$( this ).removeClass( \"ui-dialog-resizing\" );\n\t\t\t\tthat._unblockFrames();\n\t\t\t\tthat._trigger( \"resizeStop\", event, filteredUi( ui ) );\n\t\t\t}\n\t\t})\n\t\t.css( \"position\", position );\n\t},\n\n\t_trackFocus: function() {\n\t\tthis._on( this.widget(), {\n\t\t\tfocusin: function( event ) {\n\t\t\t\tthis._makeFocusTarget();\n\t\t\t\tthis._focusedElement = $( event.target );\n\t\t\t}\n\t\t});\n\t},\n\n\t_makeFocusTarget: function() {\n\t\tthis._untrackInstance();\n\t\tthis._trackingInstances().unshift( this );\n\t},\n\n\t_untrackInstance: function() {\n\t\tvar instances = this._trackingInstances(),\n\t\t\texists = $.inArray( this, instances );\n\t\tif ( exists !== -1 ) {\n\t\t\tinstances.splice( exists, 1 );\n\t\t}\n\t},\n\n\t_trackingInstances: function() {\n\t\tvar instances = this.document.data( \"ui-dialog-instances\" );\n\t\tif ( !instances ) {\n\t\t\tinstances = [];\n\t\t\tthis.document.data( \"ui-dialog-instances\", instances );\n\t\t}\n\t\treturn instances;\n\t},\n\n\t_minHeight: function() {\n\t\tvar options = this.options;\n\n\t\treturn options.height === \"auto\" ?\n\t\t\toptions.minHeight :\n\t\t\tMath.min( options.minHeight, options.height );\n\t},\n\n\t_position: function() {\n\t\t// Need to show the dialog to get the actual offset in the position plugin\n\t\tvar isVisible = this.uiDialog.is( \":visible\" );\n\t\tif ( !isVisible ) {\n\t\t\tthis.uiDialog.show();\n\t\t}\n\t\tthis.uiDialog.position( this.options.position );\n\t\tif ( !isVisible ) {\n\t\t\tthis.uiDialog.hide();\n\t\t}\n\t},\n\n\t_setOptions: function( options ) {\n\t\tvar that = this,\n\t\t\tresize = false,\n\t\t\tresizableOptions = {};\n\n\t\t$.each( options, function( key, value ) {\n\t\t\tthat._setOption( key, value );\n\n\t\t\tif ( key in that.sizeRelatedOptions ) {\n\t\t\t\tresize = true;\n\t\t\t}\n\t\t\tif ( key in that.resizableRelatedOptions ) {\n\t\t\t\tresizableOptions[ key ] = value;\n\t\t\t}\n\t\t});\n\n\t\tif ( resize ) {\n\t\t\tthis._size();\n\t\t\tthis._position();\n\t\t}\n\t\tif ( this.uiDialog.is( \":data(ui-resizable)\" ) ) {\n\t\t\tthis.uiDialog.resizable( \"option\", resizableOptions );\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tvar isDraggable, isResizable,\n\t\t\tuiDialog = this.uiDialog;\n\n\t\tif ( key === \"dialogClass\" ) {\n\t\t\tuiDialog\n\t\t\t\t.removeClass( this.options.dialogClass )\n\t\t\t\t.addClass( value );\n\t\t}\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"appendTo\" ) {\n\t\t\tthis.uiDialog.appendTo( this._appendTo() );\n\t\t}\n\n\t\tif ( key === \"buttons\" ) {\n\t\t\tthis._createButtons();\n\t\t}\n\n\t\tif ( key === \"closeText\" ) {\n\t\t\tthis.uiDialogTitlebarClose.button({\n\t\t\t\t// Ensure that we always pass a string\n\t\t\t\tlabel: \"\" + value\n\t\t\t});\n\t\t}\n\n\t\tif ( key === \"draggable\" ) {\n\t\t\tisDraggable = uiDialog.is( \":data(ui-draggable)\" );\n\t\t\tif ( isDraggable && !value ) {\n\t\t\t\tuiDialog.draggable( \"destroy\" );\n\t\t\t}\n\n\t\t\tif ( !isDraggable && value ) {\n\t\t\t\tthis._makeDraggable();\n\t\t\t}\n\t\t}\n\n\t\tif ( key === \"position\" ) {\n\t\t\tthis._position();\n\t\t}\n\n\t\tif ( key === \"resizable\" ) {\n\t\t\t// currently resizable, becoming non-resizable\n\t\t\tisResizable = uiDialog.is( \":data(ui-resizable)\" );\n\t\t\tif ( isResizable && !value ) {\n\t\t\t\tuiDialog.resizable( \"destroy\" );\n\t\t\t}\n\n\t\t\t// currently resizable, changing handles\n\t\t\tif ( isResizable && typeof value === \"string\" ) {\n\t\t\t\tuiDialog.resizable( \"option\", \"handles\", value );\n\t\t\t}\n\n\t\t\t// currently non-resizable, becoming resizable\n\t\t\tif ( !isResizable && value !== false ) {\n\t\t\t\tthis._makeResizable();\n\t\t\t}\n\t\t}\n\n\t\tif ( key === \"title\" ) {\n\t\t\tthis._title( this.uiDialogTitlebar.find( \".ui-dialog-title\" ) );\n\t\t}\n\t},\n\n\t_size: function() {\n\t\t// If the user has resized the dialog, the .ui-dialog and .ui-dialog-content\n\t\t// divs will both have width and height set, so we need to reset them\n\t\tvar nonContentHeight, minContentHeight, maxContentHeight,\n\t\t\toptions = this.options;\n\n\t\t// Reset content sizing\n\t\tthis.element.show().css({\n\t\t\twidth: \"auto\",\n\t\t\tminHeight: 0,\n\t\t\tmaxHeight: \"none\",\n\t\t\theight: 0\n\t\t});\n\n\t\tif ( options.minWidth > options.width ) {\n\t\t\toptions.width = options.minWidth;\n\t\t}\n\n\t\t// reset wrapper sizing\n\t\t// determine the height of all the non-content elements\n\t\tnonContentHeight = this.uiDialog.css({\n\t\t\t\theight: \"auto\",\n\t\t\t\twidth: options.width\n\t\t\t})\n\t\t\t.outerHeight();\n\t\tminContentHeight = Math.max( 0, options.minHeight - nonContentHeight );\n\t\tmaxContentHeight = typeof options.maxHeight === \"number\" ?\n\t\t\tMath.max( 0, options.maxHeight - nonContentHeight ) :\n\t\t\t\"none\";\n\n\t\tif ( options.height === \"auto\" ) {\n\t\t\tthis.element.css({\n\t\t\t\tminHeight: minContentHeight,\n\t\t\t\tmaxHeight: maxContentHeight,\n\t\t\t\theight: \"auto\"\n\t\t\t});\n\t\t} else {\n\t\t\tthis.element.height( Math.max( 0, options.height - nonContentHeight ) );\n\t\t}\n\n\t\tif ( this.uiDialog.is( \":data(ui-resizable)\" ) ) {\n\t\t\tthis.uiDialog.resizable( \"option\", \"minHeight\", this._minHeight() );\n\t\t}\n\t},\n\n\t_blockFrames: function() {\n\t\tthis.iframeBlocks = this.document.find( \"iframe\" ).map(function() {\n\t\t\tvar iframe = $( this );\n\n\t\t\treturn $( \"<div>\" )\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\twidth: iframe.outerWidth(),\n\t\t\t\t\theight: iframe.outerHeight()\n\t\t\t\t})\n\t\t\t\t.appendTo( iframe.parent() )\n\t\t\t\t.offset( iframe.offset() )[0];\n\t\t});\n\t},\n\n\t_unblockFrames: function() {\n\t\tif ( this.iframeBlocks ) {\n\t\t\tthis.iframeBlocks.remove();\n\t\t\tdelete this.iframeBlocks;\n\t\t}\n\t},\n\n\t_allowInteraction: function( event ) {\n\t\tif ( $( event.target ).closest( \".ui-dialog\" ).length ) {\n\t\t\treturn true;\n\t\t}\n\n\t\t// TODO: Remove hack when datepicker implements\n\t\t// the .ui-front logic (#8989)\n\t\treturn !!$( event.target ).closest( \".ui-datepicker\" ).length;\n\t},\n\n\t_createOverlay: function() {\n\t\tif ( !this.options.modal ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// We use a delay in case the overlay is created from an\n\t\t// event that we're going to be cancelling (#2804)\n\t\tvar isOpening = true;\n\t\tthis._delay(function() {\n\t\t\tisOpening = false;\n\t\t});\n\n\t\tif ( !this.document.data( \"ui-dialog-overlays\" ) ) {\n\n\t\t\t// Prevent use of anchors and inputs\n\t\t\t// Using _on() for an event handler shared across many instances is\n\t\t\t// safe because the dialogs stack and must be closed in reverse order\n\t\t\tthis._on( this.document, {\n\t\t\t\tfocusin: function( event ) {\n\t\t\t\t\tif ( isOpening ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !this._allowInteraction( event ) ) {\n\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\tthis._trackingInstances()[ 0 ]._focusTabbable();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis.overlay = $( \"<div>\" )\n\t\t\t.addClass( \"ui-widget-overlay ui-front\" )\n\t\t\t.appendTo( this._appendTo() );\n\t\tthis._on( this.overlay, {\n\t\t\tmousedown: \"_keepFocus\"\n\t\t});\n\t\tthis.document.data( \"ui-dialog-overlays\",\n\t\t\t(this.document.data( \"ui-dialog-overlays\" ) || 0) + 1 );\n\t},\n\n\t_destroyOverlay: function() {\n\t\tif ( !this.options.modal ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.overlay ) {\n\t\t\tvar overlays = this.document.data( \"ui-dialog-overlays\" ) - 1;\n\n\t\t\tif ( !overlays ) {\n\t\t\t\tthis.document\n\t\t\t\t\t.unbind( \"focusin\" )\n\t\t\t\t\t.removeData( \"ui-dialog-overlays\" );\n\t\t\t} else {\n\t\t\t\tthis.document.data( \"ui-dialog-overlays\", overlays );\n\t\t\t}\n\n\t\t\tthis.overlay.remove();\n\t\t\tthis.overlay = null;\n\t\t}\n\t}\n});\n\n\n/*!\n * jQuery UI Droppable 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/droppable/\n */\n\n\n$.widget( \"ui.droppable\", {\n\tversion: \"1.11.4\",\n\twidgetEventPrefix: \"drop\",\n\toptions: {\n\t\taccept: \"*\",\n\t\tactiveClass: false,\n\t\taddClasses: true,\n\t\tgreedy: false,\n\t\thoverClass: false,\n\t\tscope: \"default\",\n\t\ttolerance: \"intersect\",\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tdeactivate: null,\n\t\tdrop: null,\n\t\tout: null,\n\t\tover: null\n\t},\n\t_create: function() {\n\n\t\tvar proportions,\n\t\t\to = this.options,\n\t\t\taccept = o.accept;\n\n\t\tthis.isover = false;\n\t\tthis.isout = true;\n\n\t\tthis.accept = $.isFunction( accept ) ? accept : function( d ) {\n\t\t\treturn d.is( accept );\n\t\t};\n\n\t\tthis.proportions = function( /* valueToWrite */ ) {\n\t\t\tif ( arguments.length ) {\n\t\t\t\t// Store the droppable's proportions\n\t\t\t\tproportions = arguments[ 0 ];\n\t\t\t} else {\n\t\t\t\t// Retrieve or derive the droppable's proportions\n\t\t\t\treturn proportions ?\n\t\t\t\t\tproportions :\n\t\t\t\t\tproportions = {\n\t\t\t\t\t\twidth: this.element[ 0 ].offsetWidth,\n\t\t\t\t\t\theight: this.element[ 0 ].offsetHeight\n\t\t\t\t\t};\n\t\t\t}\n\t\t};\n\n\t\tthis._addToManager( o.scope );\n\n\t\to.addClasses && this.element.addClass( \"ui-droppable\" );\n\n\t},\n\n\t_addToManager: function( scope ) {\n\t\t// Add the reference and positions to the manager\n\t\t$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];\n\t\t$.ui.ddmanager.droppables[ scope ].push( this );\n\t},\n\n\t_splice: function( drop ) {\n\t\tvar i = 0;\n\t\tfor ( ; i < drop.length; i++ ) {\n\t\t\tif ( drop[ i ] === this ) {\n\t\t\t\tdrop.splice( i, 1 );\n\t\t\t}\n\t\t}\n\t},\n\n\t_destroy: function() {\n\t\tvar drop = $.ui.ddmanager.droppables[ this.options.scope ];\n\n\t\tthis._splice( drop );\n\n\t\tthis.element.removeClass( \"ui-droppable ui-droppable-disabled\" );\n\t},\n\n\t_setOption: function( key, value ) {\n\n\t\tif ( key === \"accept\" ) {\n\t\t\tthis.accept = $.isFunction( value ) ? value : function( d ) {\n\t\t\t\treturn d.is( value );\n\t\t\t};\n\t\t} else if ( key === \"scope\" ) {\n\t\t\tvar drop = $.ui.ddmanager.droppables[ this.options.scope ];\n\n\t\t\tthis._splice( drop );\n\t\t\tthis._addToManager( value );\n\t\t}\n\n\t\tthis._super( key, value );\n\t},\n\n\t_activate: function( event ) {\n\t\tvar draggable = $.ui.ddmanager.current;\n\t\tif ( this.options.activeClass ) {\n\t\t\tthis.element.addClass( this.options.activeClass );\n\t\t}\n\t\tif ( draggable ){\n\t\t\tthis._trigger( \"activate\", event, this.ui( draggable ) );\n\t\t}\n\t},\n\n\t_deactivate: function( event ) {\n\t\tvar draggable = $.ui.ddmanager.current;\n\t\tif ( this.options.activeClass ) {\n\t\t\tthis.element.removeClass( this.options.activeClass );\n\t\t}\n\t\tif ( draggable ){\n\t\t\tthis._trigger( \"deactivate\", event, this.ui( draggable ) );\n\t\t}\n\t},\n\n\t_over: function( event ) {\n\n\t\tvar draggable = $.ui.ddmanager.current;\n\n\t\t// Bail if draggable and droppable are same element\n\t\tif ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {\n\t\t\tif ( this.options.hoverClass ) {\n\t\t\t\tthis.element.addClass( this.options.hoverClass );\n\t\t\t}\n\t\t\tthis._trigger( \"over\", event, this.ui( draggable ) );\n\t\t}\n\n\t},\n\n\t_out: function( event ) {\n\n\t\tvar draggable = $.ui.ddmanager.current;\n\n\t\t// Bail if draggable and droppable are same element\n\t\tif ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {\n\t\t\tif ( this.options.hoverClass ) {\n\t\t\t\tthis.element.removeClass( this.options.hoverClass );\n\t\t\t}\n\t\t\tthis._trigger( \"out\", event, this.ui( draggable ) );\n\t\t}\n\n\t},\n\n\t_drop: function( event, custom ) {\n\n\t\tvar draggable = custom || $.ui.ddmanager.current,\n\t\t\tchildrenIntersection = false;\n\n\t\t// Bail if draggable and droppable are same element\n\t\tif ( !draggable || ( draggable.currentItem || draggable.element )[ 0 ] === this.element[ 0 ] ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.element.find( \":data(ui-droppable)\" ).not( \".ui-draggable-dragging\" ).each(function() {\n\t\t\tvar inst = $( this ).droppable( \"instance\" );\n\t\t\tif (\n\t\t\t\tinst.options.greedy &&\n\t\t\t\t!inst.options.disabled &&\n\t\t\t\tinst.options.scope === draggable.options.scope &&\n\t\t\t\tinst.accept.call( inst.element[ 0 ], ( draggable.currentItem || draggable.element ) ) &&\n\t\t\t\t$.ui.intersect( draggable, $.extend( inst, { offset: inst.element.offset() } ), inst.options.tolerance, event )\n\t\t\t) { childrenIntersection = true; return false; }\n\t\t});\n\t\tif ( childrenIntersection ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {\n\t\t\tif ( this.options.activeClass ) {\n\t\t\t\tthis.element.removeClass( this.options.activeClass );\n\t\t\t}\n\t\t\tif ( this.options.hoverClass ) {\n\t\t\t\tthis.element.removeClass( this.options.hoverClass );\n\t\t\t}\n\t\t\tthis._trigger( \"drop\", event, this.ui( draggable ) );\n\t\t\treturn this.element;\n\t\t}\n\n\t\treturn false;\n\n\t},\n\n\tui: function( c ) {\n\t\treturn {\n\t\t\tdraggable: ( c.currentItem || c.element ),\n\t\t\thelper: c.helper,\n\t\t\tposition: c.position,\n\t\t\toffset: c.positionAbs\n\t\t};\n\t}\n\n});\n\n$.ui.intersect = (function() {\n\tfunction isOverAxis( x, reference, size ) {\n\t\treturn ( x >= reference ) && ( x < ( reference + size ) );\n\t}\n\n\treturn function( draggable, droppable, toleranceMode, event ) {\n\n\t\tif ( !droppable.offset ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar x1 = ( draggable.positionAbs || draggable.position.absolute ).left + draggable.margins.left,\n\t\t\ty1 = ( draggable.positionAbs || draggable.position.absolute ).top + draggable.margins.top,\n\t\t\tx2 = x1 + draggable.helperProportions.width,\n\t\t\ty2 = y1 + draggable.helperProportions.height,\n\t\t\tl = droppable.offset.left,\n\t\t\tt = droppable.offset.top,\n\t\t\tr = l + droppable.proportions().width,\n\t\t\tb = t + droppable.proportions().height;\n\n\t\tswitch ( toleranceMode ) {\n\t\tcase \"fit\":\n\t\t\treturn ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );\n\t\tcase \"intersect\":\n\t\t\treturn ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half\n\t\t\t\tx2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half\n\t\t\t\tt < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half\n\t\t\t\ty2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half\n\t\tcase \"pointer\":\n\t\t\treturn isOverAxis( event.pageY, t, droppable.proportions().height ) && isOverAxis( event.pageX, l, droppable.proportions().width );\n\t\tcase \"touch\":\n\t\t\treturn (\n\t\t\t\t( y1 >= t && y1 <= b ) || // Top edge touching\n\t\t\t\t( y2 >= t && y2 <= b ) || // Bottom edge touching\n\t\t\t\t( y1 < t && y2 > b ) // Surrounded vertically\n\t\t\t) && (\n\t\t\t\t( x1 >= l && x1 <= r ) || // Left edge touching\n\t\t\t\t( x2 >= l && x2 <= r ) || // Right edge touching\n\t\t\t\t( x1 < l && x2 > r ) // Surrounded horizontally\n\t\t\t);\n\t\tdefault:\n\t\t\treturn false;\n\t\t}\n\t};\n})();\n\n/*\n\tThis manager tracks offsets of draggables and droppables\n*/\n$.ui.ddmanager = {\n\tcurrent: null,\n\tdroppables: { \"default\": [] },\n\tprepareOffsets: function( t, event ) {\n\n\t\tvar i, j,\n\t\t\tm = $.ui.ddmanager.droppables[ t.options.scope ] || [],\n\t\t\ttype = event ? event.type : null, // workaround for #2317\n\t\t\tlist = ( t.currentItem || t.element ).find( \":data(ui-droppable)\" ).addBack();\n\n\t\tdroppablesLoop: for ( i = 0; i < m.length; i++ ) {\n\n\t\t\t// No disabled and non-accepted\n\t\t\tif ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ], ( t.currentItem || t.element ) ) ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Filter out elements in the current dragged item\n\t\t\tfor ( j = 0; j < list.length; j++ ) {\n\t\t\t\tif ( list[ j ] === m[ i ].element[ 0 ] ) {\n\t\t\t\t\tm[ i ].proportions().height = 0;\n\t\t\t\t\tcontinue droppablesLoop;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tm[ i ].visible = m[ i ].element.css( \"display\" ) !== \"none\";\n\t\t\tif ( !m[ i ].visible ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Activate the droppable if used directly from draggables\n\t\t\tif ( type === \"mousedown\" ) {\n\t\t\t\tm[ i ]._activate.call( m[ i ], event );\n\t\t\t}\n\n\t\t\tm[ i ].offset = m[ i ].element.offset();\n\t\t\tm[ i ].proportions({ width: m[ i ].element[ 0 ].offsetWidth, height: m[ i ].element[ 0 ].offsetHeight });\n\n\t\t}\n\n\t},\n\tdrop: function( draggable, event ) {\n\n\t\tvar dropped = false;\n\t\t// Create a copy of the droppables in case the list changes during the drop (#9116)\n\t\t$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {\n\n\t\t\tif ( !this.options ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( !this.options.disabled && this.visible && $.ui.intersect( draggable, this, this.options.tolerance, event ) ) {\n\t\t\t\tdropped = this._drop.call( this, event ) || dropped;\n\t\t\t}\n\n\t\t\tif ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ], ( draggable.currentItem || draggable.element ) ) ) {\n\t\t\t\tthis.isout = true;\n\t\t\t\tthis.isover = false;\n\t\t\t\tthis._deactivate.call( this, event );\n\t\t\t}\n\n\t\t});\n\t\treturn dropped;\n\n\t},\n\tdragStart: function( draggable, event ) {\n\t\t// Listen for scrolling so that if the dragging causes scrolling the position of the droppables can be recalculated (see #5003)\n\t\tdraggable.element.parentsUntil( \"body\" ).bind( \"scroll.droppable\", function() {\n\t\t\tif ( !draggable.options.refreshPositions ) {\n\t\t\t\t$.ui.ddmanager.prepareOffsets( draggable, event );\n\t\t\t}\n\t\t});\n\t},\n\tdrag: function( draggable, event ) {\n\n\t\t// If you have a highly dynamic page, you might try this option. It renders positions every time you move the mouse.\n\t\tif ( draggable.options.refreshPositions ) {\n\t\t\t$.ui.ddmanager.prepareOffsets( draggable, event );\n\t\t}\n\n\t\t// Run through all droppables and check their positions based on specific tolerance options\n\t\t$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {\n\n\t\t\tif ( this.options.disabled || this.greedyChild || !this.visible ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar parentInstance, scope, parent,\n\t\t\t\tintersects = $.ui.intersect( draggable, this, this.options.tolerance, event ),\n\t\t\t\tc = !intersects && this.isover ? \"isout\" : ( intersects && !this.isover ? \"isover\" : null );\n\t\t\tif ( !c ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( this.options.greedy ) {\n\t\t\t\t// find droppable parents with same scope\n\t\t\t\tscope = this.options.scope;\n\t\t\t\tparent = this.element.parents( \":data(ui-droppable)\" ).filter(function() {\n\t\t\t\t\treturn $( this ).droppable( \"instance\" ).options.scope === scope;\n\t\t\t\t});\n\n\t\t\t\tif ( parent.length ) {\n\t\t\t\t\tparentInstance = $( parent[ 0 ] ).droppable( \"instance\" );\n\t\t\t\t\tparentInstance.greedyChild = ( c === \"isover\" );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// we just moved into a greedy child\n\t\t\tif ( parentInstance && c === \"isover\" ) {\n\t\t\t\tparentInstance.isover = false;\n\t\t\t\tparentInstance.isout = true;\n\t\t\t\tparentInstance._out.call( parentInstance, event );\n\t\t\t}\n\n\t\t\tthis[ c ] = true;\n\t\t\tthis[c === \"isout\" ? \"isover\" : \"isout\"] = false;\n\t\t\tthis[c === \"isover\" ? \"_over\" : \"_out\"].call( this, event );\n\n\t\t\t// we just moved out of a greedy child\n\t\t\tif ( parentInstance && c === \"isout\" ) {\n\t\t\t\tparentInstance.isout = false;\n\t\t\t\tparentInstance.isover = true;\n\t\t\t\tparentInstance._over.call( parentInstance, event );\n\t\t\t}\n\t\t});\n\n\t},\n\tdragStop: function( draggable, event ) {\n\t\tdraggable.element.parentsUntil( \"body\" ).unbind( \"scroll.droppable\" );\n\t\t// Call prepareOffsets one final time since IE does not fire return scroll events when overflow was caused by drag (see #5003)\n\t\tif ( !draggable.options.refreshPositions ) {\n\t\t\t$.ui.ddmanager.prepareOffsets( draggable, event );\n\t\t}\n\t}\n};\n\nvar droppable = $.ui.droppable;\n\n\n/*!\n * jQuery UI Effects 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/category/effects-core/\n */\n\n\nvar dataSpace = \"ui-effects-\",\n\n\t// Create a local jQuery because jQuery Color relies on it and the\n\t// global may not exist with AMD and a custom build (#10199)\n\tjQuery = $;\n\n$.effects = {\n\teffect: {}\n};\n\n/*!\n * jQuery Color Animations v2.1.2\n * https://github.com/jquery/jquery-color\n *\n * Copyright 2014 jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * Date: Wed Jan 16 08:47:09 2013 -0600\n */\n(function( jQuery, undefined ) {\n\n\tvar stepHooks = \"backgroundColor borderBottomColor borderLeftColor borderRightColor borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor\",\n\n\t// plusequals test for += 100 -= 100\n\trplusequals = /^([\\-+])=\\s*(\\d+\\.?\\d*)/,\n\t// a set of RE's that can match strings and generate color tuples.\n\tstringParsers = [ {\n\t\t\tre: /rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ],\n\t\t\t\t\texecResult[ 2 ],\n\t\t\t\t\texecResult[ 3 ],\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\tre: /rgba?\\(\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ] * 2.55,\n\t\t\t\t\texecResult[ 2 ] * 2.55,\n\t\t\t\t\texecResult[ 3 ] * 2.55,\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\t// this regex ignores A-F because it's compared against an already lowercased string\n\t\t\tre: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\tparseInt( execResult[ 1 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 2 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 3 ], 16 )\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\t// this regex ignores A-F because it's compared against an already lowercased string\n\t\t\tre: /#([a-f0-9])([a-f0-9])([a-f0-9])/,\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\tparseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),\n\t\t\t\t\tparseInt( execResult[ 3 ] + execResult[ 3 ], 16 )\n\t\t\t\t];\n\t\t\t}\n\t\t}, {\n\t\t\tre: /hsla?\\(\\s*(\\d+(?:\\.\\d+)?)\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*,\\s*(\\d+(?:\\.\\d+)?)\\%\\s*(?:,\\s*(\\d?(?:\\.\\d+)?)\\s*)?\\)/,\n\t\t\tspace: \"hsla\",\n\t\t\tparse: function( execResult ) {\n\t\t\t\treturn [\n\t\t\t\t\texecResult[ 1 ],\n\t\t\t\t\texecResult[ 2 ] / 100,\n\t\t\t\t\texecResult[ 3 ] / 100,\n\t\t\t\t\texecResult[ 4 ]\n\t\t\t\t];\n\t\t\t}\n\t\t} ],\n\n\t// jQuery.Color( )\n\tcolor = jQuery.Color = function( color, green, blue, alpha ) {\n\t\treturn new jQuery.Color.fn.parse( color, green, blue, alpha );\n\t},\n\tspaces = {\n\t\trgba: {\n\t\t\tprops: {\n\t\t\t\tred: {\n\t\t\t\t\tidx: 0,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t},\n\t\t\t\tgreen: {\n\t\t\t\t\tidx: 1,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t},\n\t\t\t\tblue: {\n\t\t\t\t\tidx: 2,\n\t\t\t\t\ttype: \"byte\"\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\thsla: {\n\t\t\tprops: {\n\t\t\t\thue: {\n\t\t\t\t\tidx: 0,\n\t\t\t\t\ttype: \"degrees\"\n\t\t\t\t},\n\t\t\t\tsaturation: {\n\t\t\t\t\tidx: 1,\n\t\t\t\t\ttype: \"percent\"\n\t\t\t\t},\n\t\t\t\tlightness: {\n\t\t\t\t\tidx: 2,\n\t\t\t\t\ttype: \"percent\"\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\tpropTypes = {\n\t\t\"byte\": {\n\t\t\tfloor: true,\n\t\t\tmax: 255\n\t\t},\n\t\t\"percent\": {\n\t\t\tmax: 1\n\t\t},\n\t\t\"degrees\": {\n\t\t\tmod: 360,\n\t\t\tfloor: true\n\t\t}\n\t},\n\tsupport = color.support = {},\n\n\t// element for support tests\n\tsupportElem = jQuery( \"<p>\" )[ 0 ],\n\n\t// colors = jQuery.Color.names\n\tcolors,\n\n\t// local aliases of functions called often\n\teach = jQuery.each;\n\n// determine rgba support immediately\nsupportElem.style.cssText = \"background-color:rgba(1,1,1,.5)\";\nsupport.rgba = supportElem.style.backgroundColor.indexOf( \"rgba\" ) > -1;\n\n// define cache name and alpha properties\n// for rgba and hsla spaces\neach( spaces, function( spaceName, space ) {\n\tspace.cache = \"_\" + spaceName;\n\tspace.props.alpha = {\n\t\tidx: 3,\n\t\ttype: \"percent\",\n\t\tdef: 1\n\t};\n});\n\nfunction clamp( value, prop, allowEmpty ) {\n\tvar type = propTypes[ prop.type ] || {};\n\n\tif ( value == null ) {\n\t\treturn (allowEmpty || !prop.def) ? null : prop.def;\n\t}\n\n\t// ~~ is an short way of doing floor for positive numbers\n\tvalue = type.floor ? ~~value : parseFloat( value );\n\n\t// IE will pass in empty strings as value for alpha,\n\t// which will hit this case\n\tif ( isNaN( value ) ) {\n\t\treturn prop.def;\n\t}\n\n\tif ( type.mod ) {\n\t\t// we add mod before modding to make sure that negatives values\n\t\t// get converted properly: -10 -> 350\n\t\treturn (value + type.mod) % type.mod;\n\t}\n\n\t// for now all property types without mod have min and max\n\treturn 0 > value ? 0 : type.max < value ? type.max : value;\n}\n\nfunction stringParse( string ) {\n\tvar inst = color(),\n\t\trgba = inst._rgba = [];\n\n\tstring = string.toLowerCase();\n\n\teach( stringParsers, function( i, parser ) {\n\t\tvar parsed,\n\t\t\tmatch = parser.re.exec( string ),\n\t\t\tvalues = match && parser.parse( match ),\n\t\t\tspaceName = parser.space || \"rgba\";\n\n\t\tif ( values ) {\n\t\t\tparsed = inst[ spaceName ]( values );\n\n\t\t\t// if this was an rgba parse the assignment might happen twice\n\t\t\t// oh well....\n\t\t\tinst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];\n\t\t\trgba = inst._rgba = parsed._rgba;\n\n\t\t\t// exit each( stringParsers ) here because we matched\n\t\t\treturn false;\n\t\t}\n\t});\n\n\t// Found a stringParser that handled it\n\tif ( rgba.length ) {\n\n\t\t// if this came from a parsed string, force \"transparent\" when alpha is 0\n\t\t// chrome, (and maybe others) return \"transparent\" as rgba(0,0,0,0)\n\t\tif ( rgba.join() === \"0,0,0,0\" ) {\n\t\t\tjQuery.extend( rgba, colors.transparent );\n\t\t}\n\t\treturn inst;\n\t}\n\n\t// named colors\n\treturn colors[ string ];\n}\n\ncolor.fn = jQuery.extend( color.prototype, {\n\tparse: function( red, green, blue, alpha ) {\n\t\tif ( red === undefined ) {\n\t\t\tthis._rgba = [ null, null, null, null ];\n\t\t\treturn this;\n\t\t}\n\t\tif ( red.jquery || red.nodeType ) {\n\t\t\tred = jQuery( red ).css( green );\n\t\t\tgreen = undefined;\n\t\t}\n\n\t\tvar inst = this,\n\t\t\ttype = jQuery.type( red ),\n\t\t\trgba = this._rgba = [];\n\n\t\t// more than 1 argument specified - assume ( red, green, blue, alpha )\n\t\tif ( green !== undefined ) {\n\t\t\tred = [ red, green, blue, alpha ];\n\t\t\ttype = \"array\";\n\t\t}\n\n\t\tif ( type === \"string\" ) {\n\t\t\treturn this.parse( stringParse( red ) || colors._default );\n\t\t}\n\n\t\tif ( type === \"array\" ) {\n\t\t\teach( spaces.rgba.props, function( key, prop ) {\n\t\t\t\trgba[ prop.idx ] = clamp( red[ prop.idx ], prop );\n\t\t\t});\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( type === \"object\" ) {\n\t\t\tif ( red instanceof color ) {\n\t\t\t\teach( spaces, function( spaceName, space ) {\n\t\t\t\t\tif ( red[ space.cache ] ) {\n\t\t\t\t\t\tinst[ space.cache ] = red[ space.cache ].slice();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\teach( spaces, function( spaceName, space ) {\n\t\t\t\t\tvar cache = space.cache;\n\t\t\t\t\teach( space.props, function( key, prop ) {\n\n\t\t\t\t\t\t// if the cache doesn't exist, and we know how to convert\n\t\t\t\t\t\tif ( !inst[ cache ] && space.to ) {\n\n\t\t\t\t\t\t\t// if the value was null, we don't need to copy it\n\t\t\t\t\t\t\t// if the key was alpha, we don't need to copy it either\n\t\t\t\t\t\t\tif ( key === \"alpha\" || red[ key ] == null ) {\n\t\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tinst[ cache ] = space.to( inst._rgba );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// this is the only case where we allow nulls for ALL properties.\n\t\t\t\t\t\t// call clamp with alwaysAllowEmpty\n\t\t\t\t\t\tinst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );\n\t\t\t\t\t});\n\n\t\t\t\t\t// everything defined but alpha?\n\t\t\t\t\tif ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {\n\t\t\t\t\t\t// use the default of 1\n\t\t\t\t\t\tinst[ cache ][ 3 ] = 1;\n\t\t\t\t\t\tif ( space.from ) {\n\t\t\t\t\t\t\tinst._rgba = space.from( inst[ cache ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t},\n\tis: function( compare ) {\n\t\tvar is = color( compare ),\n\t\t\tsame = true,\n\t\t\tinst = this;\n\n\t\teach( spaces, function( _, space ) {\n\t\t\tvar localCache,\n\t\t\t\tisCache = is[ space.cache ];\n\t\t\tif (isCache) {\n\t\t\t\tlocalCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];\n\t\t\t\teach( space.props, function( _, prop ) {\n\t\t\t\t\tif ( isCache[ prop.idx ] != null ) {\n\t\t\t\t\t\tsame = ( isCache[ prop.idx ] === localCache[ prop.idx ] );\n\t\t\t\t\t\treturn same;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn same;\n\t\t});\n\t\treturn same;\n\t},\n\t_space: function() {\n\t\tvar used = [],\n\t\t\tinst = this;\n\t\teach( spaces, function( spaceName, space ) {\n\t\t\tif ( inst[ space.cache ] ) {\n\t\t\t\tused.push( spaceName );\n\t\t\t}\n\t\t});\n\t\treturn used.pop();\n\t},\n\ttransition: function( other, distance ) {\n\t\tvar end = color( other ),\n\t\t\tspaceName = end._space(),\n\t\t\tspace = spaces[ spaceName ],\n\t\t\tstartColor = this.alpha() === 0 ? color( \"transparent\" ) : this,\n\t\t\tstart = startColor[ space.cache ] || space.to( startColor._rgba ),\n\t\t\tresult = start.slice();\n\n\t\tend = end[ space.cache ];\n\t\teach( space.props, function( key, prop ) {\n\t\t\tvar index = prop.idx,\n\t\t\t\tstartValue = start[ index ],\n\t\t\t\tendValue = end[ index ],\n\t\t\t\ttype = propTypes[ prop.type ] || {};\n\n\t\t\t// if null, don't override start value\n\t\t\tif ( endValue === null ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\t// if null - use end\n\t\t\tif ( startValue === null ) {\n\t\t\t\tresult[ index ] = endValue;\n\t\t\t} else {\n\t\t\t\tif ( type.mod ) {\n\t\t\t\t\tif ( endValue - startValue > type.mod / 2 ) {\n\t\t\t\t\t\tstartValue += type.mod;\n\t\t\t\t\t} else if ( startValue - endValue > type.mod / 2 ) {\n\t\t\t\t\t\tstartValue -= type.mod;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tresult[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );\n\t\t\t}\n\t\t});\n\t\treturn this[ spaceName ]( result );\n\t},\n\tblend: function( opaque ) {\n\t\t// if we are already opaque - return ourself\n\t\tif ( this._rgba[ 3 ] === 1 ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tvar rgb = this._rgba.slice(),\n\t\t\ta = rgb.pop(),\n\t\t\tblend = color( opaque )._rgba;\n\n\t\treturn color( jQuery.map( rgb, function( v, i ) {\n\t\t\treturn ( 1 - a ) * blend[ i ] + a * v;\n\t\t}));\n\t},\n\ttoRgbaString: function() {\n\t\tvar prefix = \"rgba(\",\n\t\t\trgba = jQuery.map( this._rgba, function( v, i ) {\n\t\t\t\treturn v == null ? ( i > 2 ? 1 : 0 ) : v;\n\t\t\t});\n\n\t\tif ( rgba[ 3 ] === 1 ) {\n\t\t\trgba.pop();\n\t\t\tprefix = \"rgb(\";\n\t\t}\n\n\t\treturn prefix + rgba.join() + \")\";\n\t},\n\ttoHslaString: function() {\n\t\tvar prefix = \"hsla(\",\n\t\t\thsla = jQuery.map( this.hsla(), function( v, i ) {\n\t\t\t\tif ( v == null ) {\n\t\t\t\t\tv = i > 2 ? 1 : 0;\n\t\t\t\t}\n\n\t\t\t\t// catch 1 and 2\n\t\t\t\tif ( i && i < 3 ) {\n\t\t\t\t\tv = Math.round( v * 100 ) + \"%\";\n\t\t\t\t}\n\t\t\t\treturn v;\n\t\t\t});\n\n\t\tif ( hsla[ 3 ] === 1 ) {\n\t\t\thsla.pop();\n\t\t\tprefix = \"hsl(\";\n\t\t}\n\t\treturn prefix + hsla.join() + \")\";\n\t},\n\ttoHexString: function( includeAlpha ) {\n\t\tvar rgba = this._rgba.slice(),\n\t\t\talpha = rgba.pop();\n\n\t\tif ( includeAlpha ) {\n\t\t\trgba.push( ~~( alpha * 255 ) );\n\t\t}\n\n\t\treturn \"#\" + jQuery.map( rgba, function( v ) {\n\n\t\t\t// default to 0 when nulls exist\n\t\t\tv = ( v || 0 ).toString( 16 );\n\t\t\treturn v.length === 1 ? \"0\" + v : v;\n\t\t}).join(\"\");\n\t},\n\ttoString: function() {\n\t\treturn this._rgba[ 3 ] === 0 ? \"transparent\" : this.toRgbaString();\n\t}\n});\ncolor.fn.parse.prototype = color.fn;\n\n// hsla conversions adapted from:\n// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021\n\nfunction hue2rgb( p, q, h ) {\n\th = ( h + 1 ) % 1;\n\tif ( h * 6 < 1 ) {\n\t\treturn p + ( q - p ) * h * 6;\n\t}\n\tif ( h * 2 < 1) {\n\t\treturn q;\n\t}\n\tif ( h * 3 < 2 ) {\n\t\treturn p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;\n\t}\n\treturn p;\n}\n\nspaces.hsla.to = function( rgba ) {\n\tif ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {\n\t\treturn [ null, null, null, rgba[ 3 ] ];\n\t}\n\tvar r = rgba[ 0 ] / 255,\n\t\tg = rgba[ 1 ] / 255,\n\t\tb = rgba[ 2 ] / 255,\n\t\ta = rgba[ 3 ],\n\t\tmax = Math.max( r, g, b ),\n\t\tmin = Math.min( r, g, b ),\n\t\tdiff = max - min,\n\t\tadd = max + min,\n\t\tl = add * 0.5,\n\t\th, s;\n\n\tif ( min === max ) {\n\t\th = 0;\n\t} else if ( r === max ) {\n\t\th = ( 60 * ( g - b ) / diff ) + 360;\n\t} else if ( g === max ) {\n\t\th = ( 60 * ( b - r ) / diff ) + 120;\n\t} else {\n\t\th = ( 60 * ( r - g ) / diff ) + 240;\n\t}\n\n\t// chroma (diff) == 0 means greyscale which, by definition, saturation = 0%\n\t// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)\n\tif ( diff === 0 ) {\n\t\ts = 0;\n\t} else if ( l <= 0.5 ) {\n\t\ts = diff / add;\n\t} else {\n\t\ts = diff / ( 2 - add );\n\t}\n\treturn [ Math.round(h) % 360, s, l, a == null ? 1 : a ];\n};\n\nspaces.hsla.from = function( hsla ) {\n\tif ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {\n\t\treturn [ null, null, null, hsla[ 3 ] ];\n\t}\n\tvar h = hsla[ 0 ] / 360,\n\t\ts = hsla[ 1 ],\n\t\tl = hsla[ 2 ],\n\t\ta = hsla[ 3 ],\n\t\tq = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,\n\t\tp = 2 * l - q;\n\n\treturn [\n\t\tMath.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),\n\t\tMath.round( hue2rgb( p, q, h ) * 255 ),\n\t\tMath.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),\n\t\ta\n\t];\n};\n\neach( spaces, function( spaceName, space ) {\n\tvar props = space.props,\n\t\tcache = space.cache,\n\t\tto = space.to,\n\t\tfrom = space.from;\n\n\t// makes rgba() and hsla()\n\tcolor.fn[ spaceName ] = function( value ) {\n\n\t\t// generate a cache for this space if it doesn't exist\n\t\tif ( to && !this[ cache ] ) {\n\t\t\tthis[ cache ] = to( this._rgba );\n\t\t}\n\t\tif ( value === undefined ) {\n\t\t\treturn this[ cache ].slice();\n\t\t}\n\n\t\tvar ret,\n\t\t\ttype = jQuery.type( value ),\n\t\t\tarr = ( type === \"array\" || type === \"object\" ) ? value : arguments,\n\t\t\tlocal = this[ cache ].slice();\n\n\t\teach( props, function( key, prop ) {\n\t\t\tvar val = arr[ type === \"object\" ? key : prop.idx ];\n\t\t\tif ( val == null ) {\n\t\t\t\tval = local[ prop.idx ];\n\t\t\t}\n\t\t\tlocal[ prop.idx ] = clamp( val, prop );\n\t\t});\n\n\t\tif ( from ) {\n\t\t\tret = color( from( local ) );\n\t\t\tret[ cache ] = local;\n\t\t\treturn ret;\n\t\t} else {\n\t\t\treturn color( local );\n\t\t}\n\t};\n\n\t// makes red() green() blue() alpha() hue() saturation() lightness()\n\teach( props, function( key, prop ) {\n\t\t// alpha is included in more than one space\n\t\tif ( color.fn[ key ] ) {\n\t\t\treturn;\n\t\t}\n\t\tcolor.fn[ key ] = function( value ) {\n\t\t\tvar vtype = jQuery.type( value ),\n\t\t\t\tfn = ( key === \"alpha\" ? ( this._hsla ? \"hsla\" : \"rgba\" ) : spaceName ),\n\t\t\t\tlocal = this[ fn ](),\n\t\t\t\tcur = local[ prop.idx ],\n\t\t\t\tmatch;\n\n\t\t\tif ( vtype === \"undefined\" ) {\n\t\t\t\treturn cur;\n\t\t\t}\n\n\t\t\tif ( vtype === \"function\" ) {\n\t\t\t\tvalue = value.call( this, cur );\n\t\t\t\tvtype = jQuery.type( value );\n\t\t\t}\n\t\t\tif ( value == null && prop.empty ) {\n\t\t\t\treturn this;\n\t\t\t}\n\t\t\tif ( vtype === \"string\" ) {\n\t\t\t\tmatch = rplusequals.exec( value );\n\t\t\t\tif ( match ) {\n\t\t\t\t\tvalue = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === \"+\" ? 1 : -1 );\n\t\t\t\t}\n\t\t\t}\n\t\t\tlocal[ prop.idx ] = value;\n\t\t\treturn this[ fn ]( local );\n\t\t};\n\t});\n});\n\n// add cssHook and .fx.step function for each named hook.\n// accept a space separated string of properties\ncolor.hook = function( hook ) {\n\tvar hooks = hook.split( \" \" );\n\teach( hooks, function( i, hook ) {\n\t\tjQuery.cssHooks[ hook ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar parsed, curElem,\n\t\t\t\t\tbackgroundColor = \"\";\n\n\t\t\t\tif ( value !== \"transparent\" && ( jQuery.type( value ) !== \"string\" || ( parsed = stringParse( value ) ) ) ) {\n\t\t\t\t\tvalue = color( parsed || value );\n\t\t\t\t\tif ( !support.rgba && value._rgba[ 3 ] !== 1 ) {\n\t\t\t\t\t\tcurElem = hook === \"backgroundColor\" ? elem.parentNode : elem;\n\t\t\t\t\t\twhile (\n\t\t\t\t\t\t\t(backgroundColor === \"\" || backgroundColor === \"transparent\") &&\n\t\t\t\t\t\t\tcurElem && curElem.style\n\t\t\t\t\t\t) {\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\tbackgroundColor = jQuery.css( curElem, \"backgroundColor\" );\n\t\t\t\t\t\t\t\tcurElem = curElem.parentNode;\n\t\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tvalue = value.blend( backgroundColor && backgroundColor !== \"transparent\" ?\n\t\t\t\t\t\t\tbackgroundColor :\n\t\t\t\t\t\t\t\"_default\" );\n\t\t\t\t\t}\n\n\t\t\t\t\tvalue = value.toRgbaString();\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\telem.style[ hook ] = value;\n\t\t\t\t} catch ( e ) {\n\t\t\t\t\t// wrapped to prevent IE from throwing errors on \"invalid\" values like 'auto' or 'inherit'\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t\tjQuery.fx.step[ hook ] = function( fx ) {\n\t\t\tif ( !fx.colorInit ) {\n\t\t\t\tfx.start = color( fx.elem, hook );\n\t\t\t\tfx.end = color( fx.end );\n\t\t\t\tfx.colorInit = true;\n\t\t\t}\n\t\t\tjQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );\n\t\t};\n\t});\n\n};\n\ncolor.hook( stepHooks );\n\njQuery.cssHooks.borderColor = {\n\texpand: function( value ) {\n\t\tvar expanded = {};\n\n\t\teach( [ \"Top\", \"Right\", \"Bottom\", \"Left\" ], function( i, part ) {\n\t\t\texpanded[ \"border\" + part + \"Color\" ] = value;\n\t\t});\n\t\treturn expanded;\n\t}\n};\n\n// Basic color names only.\n// Usage of any of the other color names requires adding yourself or including\n// jquery.color.svg-names.js.\ncolors = jQuery.Color.names = {\n\t// 4.1. Basic color keywords\n\taqua: \"#00ffff\",\n\tblack: \"#000000\",\n\tblue: \"#0000ff\",\n\tfuchsia: \"#ff00ff\",\n\tgray: \"#808080\",\n\tgreen: \"#008000\",\n\tlime: \"#00ff00\",\n\tmaroon: \"#800000\",\n\tnavy: \"#000080\",\n\tolive: \"#808000\",\n\tpurple: \"#800080\",\n\tred: \"#ff0000\",\n\tsilver: \"#c0c0c0\",\n\tteal: \"#008080\",\n\twhite: \"#ffffff\",\n\tyellow: \"#ffff00\",\n\n\t// 4.2.3. \"transparent\" color keyword\n\ttransparent: [ null, null, null, 0 ],\n\n\t_default: \"#ffffff\"\n};\n\n})( jQuery );\n\n/******************************************************************************/\n/****************************** CLASS ANIMATIONS ******************************/\n/******************************************************************************/\n(function() {\n\nvar classAnimationActions = [ \"add\", \"remove\", \"toggle\" ],\n\tshorthandStyles = {\n\t\tborder: 1,\n\t\tborderBottom: 1,\n\t\tborderColor: 1,\n\t\tborderLeft: 1,\n\t\tborderRight: 1,\n\t\tborderTop: 1,\n\t\tborderWidth: 1,\n\t\tmargin: 1,\n\t\tpadding: 1\n\t};\n\n$.each([ \"borderLeftStyle\", \"borderRightStyle\", \"borderBottomStyle\", \"borderTopStyle\" ], function( _, prop ) {\n\t$.fx.step[ prop ] = function( fx ) {\n\t\tif ( fx.end !== \"none\" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {\n\t\t\tjQuery.style( fx.elem, prop, fx.end );\n\t\t\tfx.setAttr = true;\n\t\t}\n\t};\n});\n\nfunction getElementStyles( elem ) {\n\tvar key, len,\n\t\tstyle = elem.ownerDocument.defaultView ?\n\t\t\telem.ownerDocument.defaultView.getComputedStyle( elem, null ) :\n\t\t\telem.currentStyle,\n\t\tstyles = {};\n\n\tif ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {\n\t\tlen = style.length;\n\t\twhile ( len-- ) {\n\t\t\tkey = style[ len ];\n\t\t\tif ( typeof style[ key ] === \"string\" ) {\n\t\t\t\tstyles[ $.camelCase( key ) ] = style[ key ];\n\t\t\t}\n\t\t}\n\t// support: Opera, IE <9\n\t} else {\n\t\tfor ( key in style ) {\n\t\t\tif ( typeof style[ key ] === \"string\" ) {\n\t\t\t\tstyles[ key ] = style[ key ];\n\t\t\t}\n\t\t}\n\t}\n\n\treturn styles;\n}\n\nfunction styleDifference( oldStyle, newStyle ) {\n\tvar diff = {},\n\t\tname, value;\n\n\tfor ( name in newStyle ) {\n\t\tvalue = newStyle[ name ];\n\t\tif ( oldStyle[ name ] !== value ) {\n\t\t\tif ( !shorthandStyles[ name ] ) {\n\t\t\t\tif ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {\n\t\t\t\t\tdiff[ name ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn diff;\n}\n\n// support: jQuery <1.8\nif ( !$.fn.addBack ) {\n\t$.fn.addBack = function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t};\n}\n\n$.effects.animateClass = function( value, duration, easing, callback ) {\n\tvar o = $.speed( duration, easing, callback );\n\n\treturn this.queue( function() {\n\t\tvar animated = $( this ),\n\t\t\tbaseClass = animated.attr( \"class\" ) || \"\",\n\t\t\tapplyClassChange,\n\t\t\tallAnimations = o.children ? animated.find( \"*\" ).addBack() : animated;\n\n\t\t// map the animated objects to store the original styles.\n\t\tallAnimations = allAnimations.map(function() {\n\t\t\tvar el = $( this );\n\t\t\treturn {\n\t\t\t\tel: el,\n\t\t\t\tstart: getElementStyles( this )\n\t\t\t};\n\t\t});\n\n\t\t// apply class change\n\t\tapplyClassChange = function() {\n\t\t\t$.each( classAnimationActions, function(i, action) {\n\t\t\t\tif ( value[ action ] ) {\n\t\t\t\t\tanimated[ action + \"Class\" ]( value[ action ] );\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\t\tapplyClassChange();\n\n\t\t// map all animated objects again - calculate new styles and diff\n\t\tallAnimations = allAnimations.map(function() {\n\t\t\tthis.end = getElementStyles( this.el[ 0 ] );\n\t\t\tthis.diff = styleDifference( this.start, this.end );\n\t\t\treturn this;\n\t\t});\n\n\t\t// apply original class\n\t\tanimated.attr( \"class\", baseClass );\n\n\t\t// map all animated objects again - this time collecting a promise\n\t\tallAnimations = allAnimations.map(function() {\n\t\t\tvar styleInfo = this,\n\t\t\t\tdfd = $.Deferred(),\n\t\t\t\topts = $.extend({}, o, {\n\t\t\t\t\tqueue: false,\n\t\t\t\t\tcomplete: function() {\n\t\t\t\t\t\tdfd.resolve( styleInfo );\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\tthis.el.animate( this.diff, opts );\n\t\t\treturn dfd.promise();\n\t\t});\n\n\t\t// once all animations have completed:\n\t\t$.when.apply( $, allAnimations.get() ).done(function() {\n\n\t\t\t// set the final class\n\t\t\tapplyClassChange();\n\n\t\t\t// for each animated element,\n\t\t\t// clear all css properties that were animated\n\t\t\t$.each( arguments, function() {\n\t\t\t\tvar el = this.el;\n\t\t\t\t$.each( this.diff, function(key) {\n\t\t\t\t\tel.css( key, \"\" );\n\t\t\t\t});\n\t\t\t});\n\n\t\t\t// this is guarnteed to be there if you use jQuery.speed()\n\t\t\t// it also handles dequeuing the next anim...\n\t\t\to.complete.call( animated[ 0 ] );\n\t\t});\n\t});\n};\n\n$.fn.extend({\n\taddClass: (function( orig ) {\n\t\treturn function( classNames, speed, easing, callback ) {\n\t\t\treturn speed ?\n\t\t\t\t$.effects.animateClass.call( this,\n\t\t\t\t\t{ add: classNames }, speed, easing, callback ) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t})( $.fn.addClass ),\n\n\tremoveClass: (function( orig ) {\n\t\treturn function( classNames, speed, easing, callback ) {\n\t\t\treturn arguments.length > 1 ?\n\t\t\t\t$.effects.animateClass.call( this,\n\t\t\t\t\t{ remove: classNames }, speed, easing, callback ) :\n\t\t\t\torig.apply( this, arguments );\n\t\t};\n\t})( $.fn.removeClass ),\n\n\ttoggleClass: (function( orig ) {\n\t\treturn function( classNames, force, speed, easing, callback ) {\n\t\t\tif ( typeof force === \"boolean\" || force === undefined ) {\n\t\t\t\tif ( !speed ) {\n\t\t\t\t\t// without speed parameter\n\t\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t\t} else {\n\t\t\t\t\treturn $.effects.animateClass.call( this,\n\t\t\t\t\t\t(force ? { add: classNames } : { remove: classNames }),\n\t\t\t\t\t\tspeed, easing, callback );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// without force parameter\n\t\t\t\treturn $.effects.animateClass.call( this,\n\t\t\t\t\t{ toggle: classNames }, force, speed, easing );\n\t\t\t}\n\t\t};\n\t})( $.fn.toggleClass ),\n\n\tswitchClass: function( remove, add, speed, easing, callback) {\n\t\treturn $.effects.animateClass.call( this, {\n\t\t\tadd: add,\n\t\t\tremove: remove\n\t\t}, speed, easing, callback );\n\t}\n});\n\n})();\n\n/******************************************************************************/\n/*********************************** EFFECTS **********************************/\n/******************************************************************************/\n\n(function() {\n\n$.extend( $.effects, {\n\tversion: \"1.11.4\",\n\n\t// Saves a set of properties in a data storage\n\tsave: function( element, set ) {\n\t\tfor ( var i = 0; i < set.length; i++ ) {\n\t\t\tif ( set[ i ] !== null ) {\n\t\t\t\telement.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );\n\t\t\t}\n\t\t}\n\t},\n\n\t// Restores a set of previously saved properties from a data storage\n\trestore: function( element, set ) {\n\t\tvar val, i;\n\t\tfor ( i = 0; i < set.length; i++ ) {\n\t\t\tif ( set[ i ] !== null ) {\n\t\t\t\tval = element.data( dataSpace + set[ i ] );\n\t\t\t\t// support: jQuery 1.6.2\n\t\t\t\t// http://bugs.jquery.com/ticket/9917\n\t\t\t\t// jQuery 1.6.2 incorrectly returns undefined for any falsy value.\n\t\t\t\t// We can't differentiate between \"\" and 0 here, so we just assume\n\t\t\t\t// empty string since it's likely to be a more common value...\n\t\t\t\tif ( val === undefined ) {\n\t\t\t\t\tval = \"\";\n\t\t\t\t}\n\t\t\t\telement.css( set[ i ], val );\n\t\t\t}\n\t\t}\n\t},\n\n\tsetMode: function( el, mode ) {\n\t\tif (mode === \"toggle\") {\n\t\t\tmode = el.is( \":hidden\" ) ? \"show\" : \"hide\";\n\t\t}\n\t\treturn mode;\n\t},\n\n\t// Translates a [top,left] array into a baseline value\n\t// this should be a little more flexible in the future to handle a string & hash\n\tgetBaseline: function( origin, original ) {\n\t\tvar y, x;\n\t\tswitch ( origin[ 0 ] ) {\n\t\t\tcase \"top\": y = 0; break;\n\t\t\tcase \"middle\": y = 0.5; break;\n\t\t\tcase \"bottom\": y = 1; break;\n\t\t\tdefault: y = origin[ 0 ] / original.height;\n\t\t}\n\t\tswitch ( origin[ 1 ] ) {\n\t\t\tcase \"left\": x = 0; break;\n\t\t\tcase \"center\": x = 0.5; break;\n\t\t\tcase \"right\": x = 1; break;\n\t\t\tdefault: x = origin[ 1 ] / original.width;\n\t\t}\n\t\treturn {\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\t},\n\n\t// Wraps the element around a wrapper that copies position properties\n\tcreateWrapper: function( element ) {\n\n\t\t// if the element is already wrapped, return it\n\t\tif ( element.parent().is( \".ui-effects-wrapper\" )) {\n\t\t\treturn element.parent();\n\t\t}\n\n\t\t// wrap the element\n\t\tvar props = {\n\t\t\t\twidth: element.outerWidth(true),\n\t\t\t\theight: element.outerHeight(true),\n\t\t\t\t\"float\": element.css( \"float\" )\n\t\t\t},\n\t\t\twrapper = $( \"<div></div>\" )\n\t\t\t\t.addClass( \"ui-effects-wrapper\" )\n\t\t\t\t.css({\n\t\t\t\t\tfontSize: \"100%\",\n\t\t\t\t\tbackground: \"transparent\",\n\t\t\t\t\tborder: \"none\",\n\t\t\t\t\tmargin: 0,\n\t\t\t\t\tpadding: 0\n\t\t\t\t}),\n\t\t\t// Store the size in case width/height are defined in % - Fixes #5245\n\t\t\tsize = {\n\t\t\t\twidth: element.width(),\n\t\t\t\theight: element.height()\n\t\t\t},\n\t\t\tactive = document.activeElement;\n\n\t\t// support: Firefox\n\t\t// Firefox incorrectly exposes anonymous content\n\t\t// https://bugzilla.mozilla.org/show_bug.cgi?id=561664\n\t\ttry {\n\t\t\tactive.id;\n\t\t} catch ( e ) {\n\t\t\tactive = document.body;\n\t\t}\n\n\t\telement.wrap( wrapper );\n\n\t\t// Fixes #7595 - Elements lose focus when wrapped.\n\t\tif ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {\n\t\t\t$( active ).focus();\n\t\t}\n\n\t\twrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually lose the reference to the wrapped element\n\n\t\t// transfer positioning properties to the wrapper\n\t\tif ( element.css( \"position\" ) === \"static\" ) {\n\t\t\twrapper.css({ position: \"relative\" });\n\t\t\telement.css({ position: \"relative\" });\n\t\t} else {\n\t\t\t$.extend( props, {\n\t\t\t\tposition: element.css( \"position\" ),\n\t\t\t\tzIndex: element.css( \"z-index\" )\n\t\t\t});\n\t\t\t$.each([ \"top\", \"left\", \"bottom\", \"right\" ], function(i, pos) {\n\t\t\t\tprops[ pos ] = element.css( pos );\n\t\t\t\tif ( isNaN( parseInt( props[ pos ], 10 ) ) ) {\n\t\t\t\t\tprops[ pos ] = \"auto\";\n\t\t\t\t}\n\t\t\t});\n\t\t\telement.css({\n\t\t\t\tposition: \"relative\",\n\t\t\t\ttop: 0,\n\t\t\t\tleft: 0,\n\t\t\t\tright: \"auto\",\n\t\t\t\tbottom: \"auto\"\n\t\t\t});\n\t\t}\n\t\telement.css(size);\n\n\t\treturn wrapper.css( props ).show();\n\t},\n\n\tremoveWrapper: function( element ) {\n\t\tvar active = document.activeElement;\n\n\t\tif ( element.parent().is( \".ui-effects-wrapper\" ) ) {\n\t\t\telement.parent().replaceWith( element );\n\n\t\t\t// Fixes #7595 - Elements lose focus when wrapped.\n\t\t\tif ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {\n\t\t\t\t$( active ).focus();\n\t\t\t}\n\t\t}\n\n\t\treturn element;\n\t},\n\n\tsetTransition: function( element, list, factor, value ) {\n\t\tvalue = value || {};\n\t\t$.each( list, function( i, x ) {\n\t\t\tvar unit = element.cssUnit( x );\n\t\t\tif ( unit[ 0 ] > 0 ) {\n\t\t\t\tvalue[ x ] = unit[ 0 ] * factor + unit[ 1 ];\n\t\t\t}\n\t\t});\n\t\treturn value;\n\t}\n});\n\n// return an effect options object for the given parameters:\nfunction _normalizeArguments( effect, options, speed, callback ) {\n\n\t// allow passing all options as the first parameter\n\tif ( $.isPlainObject( effect ) ) {\n\t\toptions = effect;\n\t\teffect = effect.effect;\n\t}\n\n\t// convert to an object\n\teffect = { effect: effect };\n\n\t// catch (effect, null, ...)\n\tif ( options == null ) {\n\t\toptions = {};\n\t}\n\n\t// catch (effect, callback)\n\tif ( $.isFunction( options ) ) {\n\t\tcallback = options;\n\t\tspeed = null;\n\t\toptions = {};\n\t}\n\n\t// catch (effect, speed, ?)\n\tif ( typeof options === \"number\" || $.fx.speeds[ options ] ) {\n\t\tcallback = speed;\n\t\tspeed = options;\n\t\toptions = {};\n\t}\n\n\t// catch (effect, options, callback)\n\tif ( $.isFunction( speed ) ) {\n\t\tcallback = speed;\n\t\tspeed = null;\n\t}\n\n\t// add options to effect\n\tif ( options ) {\n\t\t$.extend( effect, options );\n\t}\n\n\tspeed = speed || options.duration;\n\teffect.duration = $.fx.off ? 0 :\n\t\ttypeof speed === \"number\" ? speed :\n\t\tspeed in $.fx.speeds ? $.fx.speeds[ speed ] :\n\t\t$.fx.speeds._default;\n\n\teffect.complete = callback || options.complete;\n\n\treturn effect;\n}\n\nfunction standardAnimationOption( option ) {\n\t// Valid standard speeds (nothing, number, named speed)\n\tif ( !option || typeof option === \"number\" || $.fx.speeds[ option ] ) {\n\t\treturn true;\n\t}\n\n\t// Invalid strings - treat as \"normal\" speed\n\tif ( typeof option === \"string\" && !$.effects.effect[ option ] ) {\n\t\treturn true;\n\t}\n\n\t// Complete callback\n\tif ( $.isFunction( option ) ) {\n\t\treturn true;\n\t}\n\n\t// Options hash (but not naming an effect)\n\tif ( typeof option === \"object\" && !option.effect ) {\n\t\treturn true;\n\t}\n\n\t// Didn't match any standard API\n\treturn false;\n}\n\n$.fn.extend({\n\teffect: function( /* effect, options, speed, callback */ ) {\n\t\tvar args = _normalizeArguments.apply( this, arguments ),\n\t\t\tmode = args.mode,\n\t\t\tqueue = args.queue,\n\t\t\teffectMethod = $.effects.effect[ args.effect ];\n\n\t\tif ( $.fx.off || !effectMethod ) {\n\t\t\t// delegate to the original method (e.g., .show()) if possible\n\t\t\tif ( mode ) {\n\t\t\t\treturn this[ mode ]( args.duration, args.complete );\n\t\t\t} else {\n\t\t\t\treturn this.each( function() {\n\t\t\t\t\tif ( args.complete ) {\n\t\t\t\t\t\targs.complete.call( this );\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tfunction run( next ) {\n\t\t\tvar elem = $( this ),\n\t\t\t\tcomplete = args.complete,\n\t\t\t\tmode = args.mode;\n\n\t\t\tfunction done() {\n\t\t\t\tif ( $.isFunction( complete ) ) {\n\t\t\t\t\tcomplete.call( elem[0] );\n\t\t\t\t}\n\t\t\t\tif ( $.isFunction( next ) ) {\n\t\t\t\t\tnext();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the element already has the correct final state, delegate to\n\t\t\t// the core methods so the internal tracking of \"olddisplay\" works.\n\t\t\tif ( elem.is( \":hidden\" ) ? mode === \"hide\" : mode === \"show\" ) {\n\t\t\t\telem[ mode ]();\n\t\t\t\tdone();\n\t\t\t} else {\n\t\t\t\teffectMethod.call( elem[0], args, done );\n\t\t\t}\n\t\t}\n\n\t\treturn queue === false ? this.each( run ) : this.queue( queue || \"fx\", run );\n\t},\n\n\tshow: (function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"show\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t})( $.fn.show ),\n\n\thide: (function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"hide\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t})( $.fn.hide ),\n\n\ttoggle: (function( orig ) {\n\t\treturn function( option ) {\n\t\t\tif ( standardAnimationOption( option ) || typeof option === \"boolean\" ) {\n\t\t\t\treturn orig.apply( this, arguments );\n\t\t\t} else {\n\t\t\t\tvar args = _normalizeArguments.apply( this, arguments );\n\t\t\t\targs.mode = \"toggle\";\n\t\t\t\treturn this.effect.call( this, args );\n\t\t\t}\n\t\t};\n\t})( $.fn.toggle ),\n\n\t// helper functions\n\tcssUnit: function(key) {\n\t\tvar style = this.css( key ),\n\t\t\tval = [];\n\n\t\t$.each( [ \"em\", \"px\", \"%\", \"pt\" ], function( i, unit ) {\n\t\t\tif ( style.indexOf( unit ) > 0 ) {\n\t\t\t\tval = [ parseFloat( style ), unit ];\n\t\t\t}\n\t\t});\n\t\treturn val;\n\t}\n});\n\n})();\n\n/******************************************************************************/\n/*********************************** EASING ***********************************/\n/******************************************************************************/\n\n(function() {\n\n// based on easing equations from Robert Penner (http://www.robertpenner.com/easing)\n\nvar baseEasings = {};\n\n$.each( [ \"Quad\", \"Cubic\", \"Quart\", \"Quint\", \"Expo\" ], function( i, name ) {\n\tbaseEasings[ name ] = function( p ) {\n\t\treturn Math.pow( p, i + 2 );\n\t};\n});\n\n$.extend( baseEasings, {\n\tSine: function( p ) {\n\t\treturn 1 - Math.cos( p * Math.PI / 2 );\n\t},\n\tCirc: function( p ) {\n\t\treturn 1 - Math.sqrt( 1 - p * p );\n\t},\n\tElastic: function( p ) {\n\t\treturn p === 0 || p === 1 ? p :\n\t\t\t-Math.pow( 2, 8 * (p - 1) ) * Math.sin( ( (p - 1) * 80 - 7.5 ) * Math.PI / 15 );\n\t},\n\tBack: function( p ) {\n\t\treturn p * p * ( 3 * p - 2 );\n\t},\n\tBounce: function( p ) {\n\t\tvar pow2,\n\t\t\tbounce = 4;\n\n\t\twhile ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}\n\t\treturn 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );\n\t}\n});\n\n$.each( baseEasings, function( name, easeIn ) {\n\t$.easing[ \"easeIn\" + name ] = easeIn;\n\t$.easing[ \"easeOut\" + name ] = function( p ) {\n\t\treturn 1 - easeIn( 1 - p );\n\t};\n\t$.easing[ \"easeInOut\" + name ] = function( p ) {\n\t\treturn p < 0.5 ?\n\t\t\teaseIn( p * 2 ) / 2 :\n\t\t\t1 - easeIn( p * -2 + 2 ) / 2;\n\t};\n});\n\n})();\n\nvar effect = $.effects;\n\n\n/*!\n * jQuery UI Effects Blind 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/blind-effect/\n */\n\n\nvar effectBlind = $.effects.effect.blind = function( o, done ) {\n\t// Create element\n\tvar el = $( this ),\n\t\trvertical = /up|down|vertical/,\n\t\trpositivemotion = /up|left|vertical|horizontal/,\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tdirection = o.direction || \"up\",\n\t\tvertical = rvertical.test( direction ),\n\t\tref = vertical ? \"height\" : \"width\",\n\t\tref2 = vertical ? \"top\" : \"left\",\n\t\tmotion = rpositivemotion.test( direction ),\n\t\tanimation = {},\n\t\tshow = mode === \"show\",\n\t\twrapper, distance, margin;\n\n\t// if already wrapped, the wrapper's properties are my property. #6245\n\tif ( el.parent().is( \".ui-effects-wrapper\" ) ) {\n\t\t$.effects.save( el.parent(), props );\n\t} else {\n\t\t$.effects.save( el, props );\n\t}\n\tel.show();\n\twrapper = $.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\n\tdistance = wrapper[ ref ]();\n\tmargin = parseFloat( wrapper.css( ref2 ) ) || 0;\n\n\tanimation[ ref ] = show ? distance : 0;\n\tif ( !motion ) {\n\t\tel\n\t\t\t.css( vertical ? \"bottom\" : \"right\", 0 )\n\t\t\t.css( vertical ? \"top\" : \"left\", \"auto\" )\n\t\t\t.css({ position: \"absolute\" });\n\n\t\tanimation[ ref2 ] = show ? margin : distance + margin;\n\t}\n\n\t// start at 0 if we are showing\n\tif ( show ) {\n\t\twrapper.css( ref, 0 );\n\t\tif ( !motion ) {\n\t\t\twrapper.css( ref2, margin + distance );\n\t\t}\n\t}\n\n\t// Animate\n\twrapper.animate( animation, {\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tqueue: false,\n\t\tcomplete: function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n};\n\n\n/*!\n * jQuery UI Effects Bounce 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/bounce-effect/\n */\n\n\nvar effectBounce = $.effects.effect.bounce = function( o, done ) {\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\n\t\t// defaults:\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\thide = mode === \"hide\",\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"up\",\n\t\tdistance = o.distance,\n\t\ttimes = o.times || 5,\n\n\t\t// number of internal animations\n\t\tanims = times * 2 + ( show || hide ? 1 : 0 ),\n\t\tspeed = o.duration / anims,\n\t\teasing = o.easing,\n\n\t\t// utility:\n\t\tref = ( direction === \"up\" || direction === \"down\" ) ? \"top\" : \"left\",\n\t\tmotion = ( direction === \"up\" || direction === \"left\" ),\n\t\ti,\n\t\tupAnim,\n\t\tdownAnim,\n\n\t\t// we will need to re-assemble the queue to stack our animations in place\n\t\tqueue = el.queue(),\n\t\tqueuelen = queue.length;\n\n\t// Avoid touching opacity to prevent clearType and PNG issues in IE\n\tif ( show || hide ) {\n\t\tprops.push( \"opacity\" );\n\t}\n\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el ); // Create Wrapper\n\n\t// default distance for the BIGGEST bounce is the outer Distance / 3\n\tif ( !distance ) {\n\t\tdistance = el[ ref === \"top\" ? \"outerHeight\" : \"outerWidth\" ]() / 3;\n\t}\n\n\tif ( show ) {\n\t\tdownAnim = { opacity: 1 };\n\t\tdownAnim[ ref ] = 0;\n\n\t\t// if we are showing, force opacity 0 and set the initial position\n\t\t// then do the \"first\" animation\n\t\tel.css( \"opacity\", 0 )\n\t\t\t.css( ref, motion ? -distance * 2 : distance * 2 )\n\t\t\t.animate( downAnim, speed, easing );\n\t}\n\n\t// start at the smallest distance if we are hiding\n\tif ( hide ) {\n\t\tdistance = distance / Math.pow( 2, times - 1 );\n\t}\n\n\tdownAnim = {};\n\tdownAnim[ ref ] = 0;\n\t// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here\n\tfor ( i = 0; i < times; i++ ) {\n\t\tupAnim = {};\n\t\tupAnim[ ref ] = ( motion ? \"-=\" : \"+=\" ) + distance;\n\n\t\tel.animate( upAnim, speed, easing )\n\t\t\t.animate( downAnim, speed, easing );\n\n\t\tdistance = hide ? distance * 2 : distance / 2;\n\t}\n\n\t// Last Bounce when Hiding\n\tif ( hide ) {\n\t\tupAnim = { opacity: 0 };\n\t\tupAnim[ ref ] = ( motion ? \"-=\" : \"+=\" ) + distance;\n\n\t\tel.animate( upAnim, speed, easing );\n\t}\n\n\tel.queue(function() {\n\t\tif ( hide ) {\n\t\t\tel.hide();\n\t\t}\n\t\t$.effects.restore( el, props );\n\t\t$.effects.removeWrapper( el );\n\t\tdone();\n\t});\n\n\t// inject all the animations we just queued to be first in line (after \"inprogress\")\n\tif ( queuelen > 1) {\n\t\tqueue.splice.apply( queue,\n\t\t\t[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );\n\t}\n\tel.dequeue();\n\n};\n\n\n/*!\n * jQuery UI Effects Clip 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/clip-effect/\n */\n\n\nvar effectClip = $.effects.effect.clip = function( o, done ) {\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"vertical\",\n\t\tvert = direction === \"vertical\",\n\t\tsize = vert ? \"height\" : \"width\",\n\t\tposition = vert ? \"top\" : \"left\",\n\t\tanimation = {},\n\t\twrapper, animate, distance;\n\n\t// Save & Show\n\t$.effects.save( el, props );\n\tel.show();\n\n\t// Create Wrapper\n\twrapper = $.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\tanimate = ( el[0].tagName === \"IMG\" ) ? wrapper : el;\n\tdistance = animate[ size ]();\n\n\t// Shift\n\tif ( show ) {\n\t\tanimate.css( size, 0 );\n\t\tanimate.css( position, distance / 2 );\n\t}\n\n\t// Create Animation Object:\n\tanimation[ size ] = show ? distance : 0;\n\tanimation[ position ] = show ? 0 : distance / 2;\n\n\t// Animate\n\tanimate.animate( animation, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( !show ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n\n};\n\n\n/*!\n * jQuery UI Effects Drop 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/drop-effect/\n */\n\n\nvar effectDrop = $.effects.effect.drop = function( o, done ) {\n\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"opacity\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"left\",\n\t\tref = ( direction === \"up\" || direction === \"down\" ) ? \"top\" : \"left\",\n\t\tmotion = ( direction === \"up\" || direction === \"left\" ) ? \"pos\" : \"neg\",\n\t\tanimation = {\n\t\t\topacity: show ? 1 : 0\n\t\t},\n\t\tdistance;\n\n\t// Adjust\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el );\n\n\tdistance = o.distance || el[ ref === \"top\" ? \"outerHeight\" : \"outerWidth\" ]( true ) / 2;\n\n\tif ( show ) {\n\t\tel\n\t\t\t.css( \"opacity\", 0 )\n\t\t\t.css( ref, motion === \"pos\" ? -distance : distance );\n\t}\n\n\t// Animation\n\tanimation[ ref ] = ( show ?\n\t\t( motion === \"pos\" ? \"+=\" : \"-=\" ) :\n\t\t( motion === \"pos\" ? \"-=\" : \"+=\" ) ) +\n\t\tdistance;\n\n\t// Animate\n\tel.animate( animation, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n};\n\n\n/*!\n * jQuery UI Effects Explode 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/explode-effect/\n */\n\n\nvar effectExplode = $.effects.effect.explode = function( o, done ) {\n\n\tvar rows = o.pieces ? Math.round( Math.sqrt( o.pieces ) ) : 3,\n\t\tcells = rows,\n\t\tel = $( this ),\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\n\t\t// show and then visibility:hidden the element before calculating offset\n\t\toffset = el.show().css( \"visibility\", \"hidden\" ).offset(),\n\n\t\t// width and height of a piece\n\t\twidth = Math.ceil( el.outerWidth() / cells ),\n\t\theight = Math.ceil( el.outerHeight() / rows ),\n\t\tpieces = [],\n\n\t\t// loop\n\t\ti, j, left, top, mx, my;\n\n\t// children animate complete:\n\tfunction childComplete() {\n\t\tpieces.push( this );\n\t\tif ( pieces.length === rows * cells ) {\n\t\t\tanimComplete();\n\t\t}\n\t}\n\n\t// clone the element for each row and cell.\n\tfor ( i = 0; i < rows ; i++ ) { // ===>\n\t\ttop = offset.top + i * height;\n\t\tmy = i - ( rows - 1 ) / 2 ;\n\n\t\tfor ( j = 0; j < cells ; j++ ) { // |||\n\t\t\tleft = offset.left + j * width;\n\t\t\tmx = j - ( cells - 1 ) / 2 ;\n\n\t\t\t// Create a clone of the now hidden main element that will be absolute positioned\n\t\t\t// within a wrapper div off the -left and -top equal to size of our pieces\n\t\t\tel\n\t\t\t\t.clone()\n\t\t\t\t.appendTo( \"body\" )\n\t\t\t\t.wrap( \"<div></div>\" )\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\tvisibility: \"visible\",\n\t\t\t\t\tleft: -j * width,\n\t\t\t\t\ttop: -i * height\n\t\t\t\t})\n\n\t\t\t// select the wrapper - make it overflow: hidden and absolute positioned based on\n\t\t\t// where the original was located +left and +top equal to the size of pieces\n\t\t\t\t.parent()\n\t\t\t\t.addClass( \"ui-effects-explode\" )\n\t\t\t\t.css({\n\t\t\t\t\tposition: \"absolute\",\n\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\twidth: width,\n\t\t\t\t\theight: height,\n\t\t\t\t\tleft: left + ( show ? mx * width : 0 ),\n\t\t\t\t\ttop: top + ( show ? my * height : 0 ),\n\t\t\t\t\topacity: show ? 0 : 1\n\t\t\t\t}).animate({\n\t\t\t\t\tleft: left + ( show ? 0 : mx * width ),\n\t\t\t\t\ttop: top + ( show ? 0 : my * height ),\n\t\t\t\t\topacity: show ? 1 : 0\n\t\t\t\t}, o.duration || 500, o.easing, childComplete );\n\t\t}\n\t}\n\n\tfunction animComplete() {\n\t\tel.css({\n\t\t\tvisibility: \"visible\"\n\t\t});\n\t\t$( pieces ).remove();\n\t\tif ( !show ) {\n\t\t\tel.hide();\n\t\t}\n\t\tdone();\n\t}\n};\n\n\n/*!\n * jQuery UI Effects Fade 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/fade-effect/\n */\n\n\nvar effectFade = $.effects.effect.fade = function( o, done ) {\n\tvar el = $( this ),\n\t\tmode = $.effects.setMode( el, o.mode || \"toggle\" );\n\n\tel.animate({\n\t\topacity: mode\n\t}, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: done\n\t});\n};\n\n\n/*!\n * jQuery UI Effects Fold 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/fold-effect/\n */\n\n\nvar effectFold = $.effects.effect.fold = function( o, done ) {\n\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"hide\" ),\n\t\tshow = mode === \"show\",\n\t\thide = mode === \"hide\",\n\t\tsize = o.size || 15,\n\t\tpercent = /([0-9]+)%/.exec( size ),\n\t\thorizFirst = !!o.horizFirst,\n\t\twidthFirst = show !== horizFirst,\n\t\tref = widthFirst ? [ \"width\", \"height\" ] : [ \"height\", \"width\" ],\n\t\tduration = o.duration / 2,\n\t\twrapper, distance,\n\t\tanimation1 = {},\n\t\tanimation2 = {};\n\n\t$.effects.save( el, props );\n\tel.show();\n\n\t// Create Wrapper\n\twrapper = $.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\tdistance = widthFirst ?\n\t\t[ wrapper.width(), wrapper.height() ] :\n\t\t[ wrapper.height(), wrapper.width() ];\n\n\tif ( percent ) {\n\t\tsize = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];\n\t}\n\tif ( show ) {\n\t\twrapper.css( horizFirst ? {\n\t\t\theight: 0,\n\t\t\twidth: size\n\t\t} : {\n\t\t\theight: size,\n\t\t\twidth: 0\n\t\t});\n\t}\n\n\t// Animation\n\tanimation1[ ref[ 0 ] ] = show ? distance[ 0 ] : size;\n\tanimation2[ ref[ 1 ] ] = show ? distance[ 1 ] : 0;\n\n\t// Animate\n\twrapper\n\t\t.animate( animation1, duration, o.easing )\n\t\t.animate( animation2, duration, o.easing, function() {\n\t\t\tif ( hide ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t});\n\n};\n\n\n/*!\n * jQuery UI Effects Highlight 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/highlight-effect/\n */\n\n\nvar effectHighlight = $.effects.effect.highlight = function( o, done ) {\n\tvar elem = $( this ),\n\t\tprops = [ \"backgroundImage\", \"backgroundColor\", \"opacity\" ],\n\t\tmode = $.effects.setMode( elem, o.mode || \"show\" ),\n\t\tanimation = {\n\t\t\tbackgroundColor: elem.css( \"backgroundColor\" )\n\t\t};\n\n\tif (mode === \"hide\") {\n\t\tanimation.opacity = 0;\n\t}\n\n\t$.effects.save( elem, props );\n\n\telem\n\t\t.show()\n\t\t.css({\n\t\t\tbackgroundImage: \"none\",\n\t\t\tbackgroundColor: o.color || \"#ffff99\"\n\t\t})\n\t\t.animate( animation, {\n\t\t\tqueue: false,\n\t\t\tduration: o.duration,\n\t\t\teasing: o.easing,\n\t\t\tcomplete: function() {\n\t\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\t\telem.hide();\n\t\t\t\t}\n\t\t\t\t$.effects.restore( elem, props );\n\t\t\t\tdone();\n\t\t\t}\n\t\t});\n};\n\n\n/*!\n * jQuery UI Effects Size 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/size-effect/\n */\n\n\nvar effectSize = $.effects.effect.size = function( o, done ) {\n\n\t// Create element\n\tvar original, baseline, factor,\n\t\tel = $( this ),\n\t\tprops0 = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"width\", \"height\", \"overflow\", \"opacity\" ],\n\n\t\t// Always restore\n\t\tprops1 = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"overflow\", \"opacity\" ],\n\n\t\t// Copy for children\n\t\tprops2 = [ \"width\", \"height\", \"overflow\" ],\n\t\tcProps = [ \"fontSize\" ],\n\t\tvProps = [ \"borderTopWidth\", \"borderBottomWidth\", \"paddingTop\", \"paddingBottom\" ],\n\t\thProps = [ \"borderLeftWidth\", \"borderRightWidth\", \"paddingLeft\", \"paddingRight\" ],\n\n\t\t// Set options\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\trestore = o.restore || mode !== \"effect\",\n\t\tscale = o.scale || \"both\",\n\t\torigin = o.origin || [ \"middle\", \"center\" ],\n\t\tposition = el.css( \"position\" ),\n\t\tprops = restore ? props0 : props1,\n\t\tzero = {\n\t\t\theight: 0,\n\t\t\twidth: 0,\n\t\t\touterHeight: 0,\n\t\t\touterWidth: 0\n\t\t};\n\n\tif ( mode === \"show\" ) {\n\t\tel.show();\n\t}\n\toriginal = {\n\t\theight: el.height(),\n\t\twidth: el.width(),\n\t\touterHeight: el.outerHeight(),\n\t\touterWidth: el.outerWidth()\n\t};\n\n\tif ( o.mode === \"toggle\" && mode === \"show\" ) {\n\t\tel.from = o.to || zero;\n\t\tel.to = o.from || original;\n\t} else {\n\t\tel.from = o.from || ( mode === \"show\" ? zero : original );\n\t\tel.to = o.to || ( mode === \"hide\" ? zero : original );\n\t}\n\n\t// Set scaling factor\n\tfactor = {\n\t\tfrom: {\n\t\t\ty: el.from.height / original.height,\n\t\t\tx: el.from.width / original.width\n\t\t},\n\t\tto: {\n\t\t\ty: el.to.height / original.height,\n\t\t\tx: el.to.width / original.width\n\t\t}\n\t};\n\n\t// Scale the css box\n\tif ( scale === \"box\" || scale === \"both\" ) {\n\n\t\t// Vertical props scaling\n\t\tif ( factor.from.y !== factor.to.y ) {\n\t\t\tprops = props.concat( vProps );\n\t\t\tel.from = $.effects.setTransition( el, vProps, factor.from.y, el.from );\n\t\t\tel.to = $.effects.setTransition( el, vProps, factor.to.y, el.to );\n\t\t}\n\n\t\t// Horizontal props scaling\n\t\tif ( factor.from.x !== factor.to.x ) {\n\t\t\tprops = props.concat( hProps );\n\t\t\tel.from = $.effects.setTransition( el, hProps, factor.from.x, el.from );\n\t\t\tel.to = $.effects.setTransition( el, hProps, factor.to.x, el.to );\n\t\t}\n\t}\n\n\t// Scale the content\n\tif ( scale === \"content\" || scale === \"both\" ) {\n\n\t\t// Vertical props scaling\n\t\tif ( factor.from.y !== factor.to.y ) {\n\t\t\tprops = props.concat( cProps ).concat( props2 );\n\t\t\tel.from = $.effects.setTransition( el, cProps, factor.from.y, el.from );\n\t\t\tel.to = $.effects.setTransition( el, cProps, factor.to.y, el.to );\n\t\t}\n\t}\n\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el );\n\tel.css( \"overflow\", \"hidden\" ).css( el.from );\n\n\t// Adjust\n\tif (origin) { // Calculate baseline shifts\n\t\tbaseline = $.effects.getBaseline( origin, original );\n\t\tel.from.top = ( original.outerHeight - el.outerHeight() ) * baseline.y;\n\t\tel.from.left = ( original.outerWidth - el.outerWidth() ) * baseline.x;\n\t\tel.to.top = ( original.outerHeight - el.to.outerHeight ) * baseline.y;\n\t\tel.to.left = ( original.outerWidth - el.to.outerWidth ) * baseline.x;\n\t}\n\tel.css( el.from ); // set top & left\n\n\t// Animate\n\tif ( scale === \"content\" || scale === \"both\" ) { // Scale the children\n\n\t\t// Add margins/font-size\n\t\tvProps = vProps.concat([ \"marginTop\", \"marginBottom\" ]).concat(cProps);\n\t\thProps = hProps.concat([ \"marginLeft\", \"marginRight\" ]);\n\t\tprops2 = props0.concat(vProps).concat(hProps);\n\n\t\tel.find( \"*[width]\" ).each( function() {\n\t\t\tvar child = $( this ),\n\t\t\t\tc_original = {\n\t\t\t\t\theight: child.height(),\n\t\t\t\t\twidth: child.width(),\n\t\t\t\t\touterHeight: child.outerHeight(),\n\t\t\t\t\touterWidth: child.outerWidth()\n\t\t\t\t};\n\t\t\tif (restore) {\n\t\t\t\t$.effects.save(child, props2);\n\t\t\t}\n\n\t\t\tchild.from = {\n\t\t\t\theight: c_original.height * factor.from.y,\n\t\t\t\twidth: c_original.width * factor.from.x,\n\t\t\t\touterHeight: c_original.outerHeight * factor.from.y,\n\t\t\t\touterWidth: c_original.outerWidth * factor.from.x\n\t\t\t};\n\t\t\tchild.to = {\n\t\t\t\theight: c_original.height * factor.to.y,\n\t\t\t\twidth: c_original.width * factor.to.x,\n\t\t\t\touterHeight: c_original.height * factor.to.y,\n\t\t\t\touterWidth: c_original.width * factor.to.x\n\t\t\t};\n\n\t\t\t// Vertical props scaling\n\t\t\tif ( factor.from.y !== factor.to.y ) {\n\t\t\t\tchild.from = $.effects.setTransition( child, vProps, factor.from.y, child.from );\n\t\t\t\tchild.to = $.effects.setTransition( child, vProps, factor.to.y, child.to );\n\t\t\t}\n\n\t\t\t// Horizontal props scaling\n\t\t\tif ( factor.from.x !== factor.to.x ) {\n\t\t\t\tchild.from = $.effects.setTransition( child, hProps, factor.from.x, child.from );\n\t\t\t\tchild.to = $.effects.setTransition( child, hProps, factor.to.x, child.to );\n\t\t\t}\n\n\t\t\t// Animate children\n\t\t\tchild.css( child.from );\n\t\t\tchild.animate( child.to, o.duration, o.easing, function() {\n\n\t\t\t\t// Restore children\n\t\t\t\tif ( restore ) {\n\t\t\t\t\t$.effects.restore( child, props2 );\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// Animate\n\tel.animate( el.to, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( el.to.opacity === 0 ) {\n\t\t\t\tel.css( \"opacity\", el.from.opacity );\n\t\t\t}\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\tif ( !restore ) {\n\n\t\t\t\t// we need to calculate our new positioning based on the scaling\n\t\t\t\tif ( position === \"static\" ) {\n\t\t\t\t\tel.css({\n\t\t\t\t\t\tposition: \"relative\",\n\t\t\t\t\t\ttop: el.to.top,\n\t\t\t\t\t\tleft: el.to.left\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\t$.each([ \"top\", \"left\" ], function( idx, pos ) {\n\t\t\t\t\t\tel.css( pos, function( _, str ) {\n\t\t\t\t\t\t\tvar val = parseInt( str, 10 ),\n\t\t\t\t\t\t\t\ttoRef = idx ? el.to.left : el.to.top;\n\n\t\t\t\t\t\t\t// if original was \"auto\", recalculate the new value from wrapper\n\t\t\t\t\t\t\tif ( str === \"auto\" ) {\n\t\t\t\t\t\t\t\treturn toRef + \"px\";\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\treturn val + toRef + \"px\";\n\t\t\t\t\t\t});\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n\n};\n\n\n/*!\n * jQuery UI Effects Scale 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/scale-effect/\n */\n\n\nvar effectScale = $.effects.effect.scale = function( o, done ) {\n\n\t// Create element\n\tvar el = $( this ),\n\t\toptions = $.extend( true, {}, o ),\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\tpercent = parseInt( o.percent, 10 ) ||\n\t\t\t( parseInt( o.percent, 10 ) === 0 ? 0 : ( mode === \"hide\" ? 0 : 100 ) ),\n\t\tdirection = o.direction || \"both\",\n\t\torigin = o.origin,\n\t\toriginal = {\n\t\t\theight: el.height(),\n\t\t\twidth: el.width(),\n\t\t\touterHeight: el.outerHeight(),\n\t\t\touterWidth: el.outerWidth()\n\t\t},\n\t\tfactor = {\n\t\t\ty: direction !== \"horizontal\" ? (percent / 100) : 1,\n\t\t\tx: direction !== \"vertical\" ? (percent / 100) : 1\n\t\t};\n\n\t// We are going to pass this effect to the size effect:\n\toptions.effect = \"size\";\n\toptions.queue = false;\n\toptions.complete = done;\n\n\t// Set default origin and restore for show/hide\n\tif ( mode !== \"effect\" ) {\n\t\toptions.origin = origin || [ \"middle\", \"center\" ];\n\t\toptions.restore = true;\n\t}\n\n\toptions.from = o.from || ( mode === \"show\" ? {\n\t\theight: 0,\n\t\twidth: 0,\n\t\touterHeight: 0,\n\t\touterWidth: 0\n\t} : original );\n\toptions.to = {\n\t\theight: original.height * factor.y,\n\t\twidth: original.width * factor.x,\n\t\touterHeight: original.outerHeight * factor.y,\n\t\touterWidth: original.outerWidth * factor.x\n\t};\n\n\t// Fade option to support puff\n\tif ( options.fade ) {\n\t\tif ( mode === \"show\" ) {\n\t\t\toptions.from.opacity = 0;\n\t\t\toptions.to.opacity = 1;\n\t\t}\n\t\tif ( mode === \"hide\" ) {\n\t\t\toptions.from.opacity = 1;\n\t\t\toptions.to.opacity = 0;\n\t\t}\n\t}\n\n\t// Animate\n\tel.effect( options );\n\n};\n\n\n/*!\n * jQuery UI Effects Puff 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/puff-effect/\n */\n\n\nvar effectPuff = $.effects.effect.puff = function( o, done ) {\n\tvar elem = $( this ),\n\t\tmode = $.effects.setMode( elem, o.mode || \"hide\" ),\n\t\thide = mode === \"hide\",\n\t\tpercent = parseInt( o.percent, 10 ) || 150,\n\t\tfactor = percent / 100,\n\t\toriginal = {\n\t\t\theight: elem.height(),\n\t\t\twidth: elem.width(),\n\t\t\touterHeight: elem.outerHeight(),\n\t\t\touterWidth: elem.outerWidth()\n\t\t};\n\n\t$.extend( o, {\n\t\teffect: \"scale\",\n\t\tqueue: false,\n\t\tfade: true,\n\t\tmode: mode,\n\t\tcomplete: done,\n\t\tpercent: hide ? percent : 100,\n\t\tfrom: hide ?\n\t\t\toriginal :\n\t\t\t{\n\t\t\t\theight: original.height * factor,\n\t\t\t\twidth: original.width * factor,\n\t\t\t\touterHeight: original.outerHeight * factor,\n\t\t\t\touterWidth: original.outerWidth * factor\n\t\t\t}\n\t});\n\n\telem.effect( o );\n};\n\n\n/*!\n * jQuery UI Effects Pulsate 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/pulsate-effect/\n */\n\n\nvar effectPulsate = $.effects.effect.pulsate = function( o, done ) {\n\tvar elem = $( this ),\n\t\tmode = $.effects.setMode( elem, o.mode || \"show\" ),\n\t\tshow = mode === \"show\",\n\t\thide = mode === \"hide\",\n\t\tshowhide = ( show || mode === \"hide\" ),\n\n\t\t// showing or hiding leaves of the \"last\" animation\n\t\tanims = ( ( o.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),\n\t\tduration = o.duration / anims,\n\t\tanimateTo = 0,\n\t\tqueue = elem.queue(),\n\t\tqueuelen = queue.length,\n\t\ti;\n\n\tif ( show || !elem.is(\":visible\")) {\n\t\telem.css( \"opacity\", 0 ).show();\n\t\tanimateTo = 1;\n\t}\n\n\t// anims - 1 opacity \"toggles\"\n\tfor ( i = 1; i < anims; i++ ) {\n\t\telem.animate({\n\t\t\topacity: animateTo\n\t\t}, duration, o.easing );\n\t\tanimateTo = 1 - animateTo;\n\t}\n\n\telem.animate({\n\t\topacity: animateTo\n\t}, duration, o.easing);\n\n\telem.queue(function() {\n\t\tif ( hide ) {\n\t\t\telem.hide();\n\t\t}\n\t\tdone();\n\t});\n\n\t// We just queued up \"anims\" animations, we need to put them next in the queue\n\tif ( queuelen > 1 ) {\n\t\tqueue.splice.apply( queue,\n\t\t\t[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );\n\t}\n\telem.dequeue();\n};\n\n\n/*!\n * jQuery UI Effects Shake 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/shake-effect/\n */\n\n\nvar effectShake = $.effects.effect.shake = function( o, done ) {\n\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"height\", \"width\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"effect\" ),\n\t\tdirection = o.direction || \"left\",\n\t\tdistance = o.distance || 20,\n\t\ttimes = o.times || 3,\n\t\tanims = times * 2 + 1,\n\t\tspeed = Math.round( o.duration / anims ),\n\t\tref = (direction === \"up\" || direction === \"down\") ? \"top\" : \"left\",\n\t\tpositiveMotion = (direction === \"up\" || direction === \"left\"),\n\t\tanimation = {},\n\t\tanimation1 = {},\n\t\tanimation2 = {},\n\t\ti,\n\n\t\t// we will need to re-assemble the queue to stack our animations in place\n\t\tqueue = el.queue(),\n\t\tqueuelen = queue.length;\n\n\t$.effects.save( el, props );\n\tel.show();\n\t$.effects.createWrapper( el );\n\n\t// Animation\n\tanimation[ ref ] = ( positiveMotion ? \"-=\" : \"+=\" ) + distance;\n\tanimation1[ ref ] = ( positiveMotion ? \"+=\" : \"-=\" ) + distance * 2;\n\tanimation2[ ref ] = ( positiveMotion ? \"-=\" : \"+=\" ) + distance * 2;\n\n\t// Animate\n\tel.animate( animation, speed, o.easing );\n\n\t// Shakes\n\tfor ( i = 1; i < times; i++ ) {\n\t\tel.animate( animation1, speed, o.easing ).animate( animation2, speed, o.easing );\n\t}\n\tel\n\t\t.animate( animation1, speed, o.easing )\n\t\t.animate( animation, speed / 2, o.easing )\n\t\t.queue(function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t});\n\n\t// inject all the animations we just queued to be first in line (after \"inprogress\")\n\tif ( queuelen > 1) {\n\t\tqueue.splice.apply( queue,\n\t\t\t[ 1, 0 ].concat( queue.splice( queuelen, anims + 1 ) ) );\n\t}\n\tel.dequeue();\n\n};\n\n\n/*!\n * jQuery UI Effects Slide 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/slide-effect/\n */\n\n\nvar effectSlide = $.effects.effect.slide = function( o, done ) {\n\n\t// Create element\n\tvar el = $( this ),\n\t\tprops = [ \"position\", \"top\", \"bottom\", \"left\", \"right\", \"width\", \"height\" ],\n\t\tmode = $.effects.setMode( el, o.mode || \"show\" ),\n\t\tshow = mode === \"show\",\n\t\tdirection = o.direction || \"left\",\n\t\tref = (direction === \"up\" || direction === \"down\") ? \"top\" : \"left\",\n\t\tpositiveMotion = (direction === \"up\" || direction === \"left\"),\n\t\tdistance,\n\t\tanimation = {};\n\n\t// Adjust\n\t$.effects.save( el, props );\n\tel.show();\n\tdistance = o.distance || el[ ref === \"top\" ? \"outerHeight\" : \"outerWidth\" ]( true );\n\n\t$.effects.createWrapper( el ).css({\n\t\toverflow: \"hidden\"\n\t});\n\n\tif ( show ) {\n\t\tel.css( ref, positiveMotion ? (isNaN(distance) ? \"-\" + distance : -distance) : distance );\n\t}\n\n\t// Animation\n\tanimation[ ref ] = ( show ?\n\t\t( positiveMotion ? \"+=\" : \"-=\") :\n\t\t( positiveMotion ? \"-=\" : \"+=\")) +\n\t\tdistance;\n\n\t// Animate\n\tel.animate( animation, {\n\t\tqueue: false,\n\t\tduration: o.duration,\n\t\teasing: o.easing,\n\t\tcomplete: function() {\n\t\t\tif ( mode === \"hide\" ) {\n\t\t\t\tel.hide();\n\t\t\t}\n\t\t\t$.effects.restore( el, props );\n\t\t\t$.effects.removeWrapper( el );\n\t\t\tdone();\n\t\t}\n\t});\n};\n\n\n/*!\n * jQuery UI Effects Transfer 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/transfer-effect/\n */\n\n\nvar effectTransfer = $.effects.effect.transfer = function( o, done ) {\n\tvar elem = $( this ),\n\t\ttarget = $( o.to ),\n\t\ttargetFixed = target.css( \"position\" ) === \"fixed\",\n\t\tbody = $(\"body\"),\n\t\tfixTop = targetFixed ? body.scrollTop() : 0,\n\t\tfixLeft = targetFixed ? body.scrollLeft() : 0,\n\t\tendPosition = target.offset(),\n\t\tanimation = {\n\t\t\ttop: endPosition.top - fixTop,\n\t\t\tleft: endPosition.left - fixLeft,\n\t\t\theight: target.innerHeight(),\n\t\t\twidth: target.innerWidth()\n\t\t},\n\t\tstartPosition = elem.offset(),\n\t\ttransfer = $( \"<div class='ui-effects-transfer'></div>\" )\n\t\t\t.appendTo( document.body )\n\t\t\t.addClass( o.className )\n\t\t\t.css({\n\t\t\t\ttop: startPosition.top - fixTop,\n\t\t\t\tleft: startPosition.left - fixLeft,\n\t\t\t\theight: elem.innerHeight(),\n\t\t\t\twidth: elem.innerWidth(),\n\t\t\t\tposition: targetFixed ? \"fixed\" : \"absolute\"\n\t\t\t})\n\t\t\t.animate( animation, o.duration, o.easing, function() {\n\t\t\t\ttransfer.remove();\n\t\t\t\tdone();\n\t\t\t});\n};\n\n\n/*!\n * jQuery UI Progressbar 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/progressbar/\n */\n\n\nvar progressbar = $.widget( \"ui.progressbar\", {\n\tversion: \"1.11.4\",\n\toptions: {\n\t\tmax: 100,\n\t\tvalue: 0,\n\n\t\tchange: null,\n\t\tcomplete: null\n\t},\n\n\tmin: 0,\n\n\t_create: function() {\n\t\t// Constrain initial value\n\t\tthis.oldValue = this.options.value = this._constrainedValue();\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-progressbar ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.attr({\n\t\t\t\t// Only set static values, aria-valuenow and aria-valuemax are\n\t\t\t\t// set inside _refreshValue()\n\t\t\t\trole: \"progressbar\",\n\t\t\t\t\"aria-valuemin\": this.min\n\t\t\t});\n\n\t\tthis.valueDiv = $( \"<div class='ui-progressbar-value ui-widget-header ui-corner-left'></div>\" )\n\t\t\t.appendTo( this.element );\n\n\t\tthis._refreshValue();\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass( \"ui-progressbar ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-valuemin\" )\n\t\t\t.removeAttr( \"aria-valuemax\" )\n\t\t\t.removeAttr( \"aria-valuenow\" );\n\n\t\tthis.valueDiv.remove();\n\t},\n\n\tvalue: function( newValue ) {\n\t\tif ( newValue === undefined ) {\n\t\t\treturn this.options.value;\n\t\t}\n\n\t\tthis.options.value = this._constrainedValue( newValue );\n\t\tthis._refreshValue();\n\t},\n\n\t_constrainedValue: function( newValue ) {\n\t\tif ( newValue === undefined ) {\n\t\t\tnewValue = this.options.value;\n\t\t}\n\n\t\tthis.indeterminate = newValue === false;\n\n\t\t// sanitize value\n\t\tif ( typeof newValue !== \"number\" ) {\n\t\t\tnewValue = 0;\n\t\t}\n\n\t\treturn this.indeterminate ? false :\n\t\t\tMath.min( this.options.max, Math.max( this.min, newValue ) );\n\t},\n\n\t_setOptions: function( options ) {\n\t\t// Ensure \"value\" option is set after other values (like max)\n\t\tvar value = options.value;\n\t\tdelete options.value;\n\n\t\tthis._super( options );\n\n\t\tthis.options.value = this._constrainedValue( value );\n\t\tthis._refreshValue();\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"max\" ) {\n\t\t\t// Don't allow a max less than min\n\t\t\tvalue = Math.max( this.min, value );\n\t\t}\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.element\n\t\t\t\t.toggleClass( \"ui-state-disabled\", !!value )\n\t\t\t\t.attr( \"aria-disabled\", value );\n\t\t}\n\t\tthis._super( key, value );\n\t},\n\n\t_percentage: function() {\n\t\treturn this.indeterminate ? 100 : 100 * ( this.options.value - this.min ) / ( this.options.max - this.min );\n\t},\n\n\t_refreshValue: function() {\n\t\tvar value = this.options.value,\n\t\t\tpercentage = this._percentage();\n\n\t\tthis.valueDiv\n\t\t\t.toggle( this.indeterminate || value > this.min )\n\t\t\t.toggleClass( \"ui-corner-right\", value === this.options.max )\n\t\t\t.width( percentage.toFixed(0) + \"%\" );\n\n\t\tthis.element.toggleClass( \"ui-progressbar-indeterminate\", this.indeterminate );\n\n\t\tif ( this.indeterminate ) {\n\t\t\tthis.element.removeAttr( \"aria-valuenow\" );\n\t\t\tif ( !this.overlayDiv ) {\n\t\t\t\tthis.overlayDiv = $( \"<div class='ui-progressbar-overlay'></div>\" ).appendTo( this.valueDiv );\n\t\t\t}\n\t\t} else {\n\t\t\tthis.element.attr({\n\t\t\t\t\"aria-valuemax\": this.options.max,\n\t\t\t\t\"aria-valuenow\": value\n\t\t\t});\n\t\t\tif ( this.overlayDiv ) {\n\t\t\t\tthis.overlayDiv.remove();\n\t\t\t\tthis.overlayDiv = null;\n\t\t\t}\n\t\t}\n\n\t\tif ( this.oldValue !== value ) {\n\t\t\tthis.oldValue = value;\n\t\t\tthis._trigger( \"change\" );\n\t\t}\n\t\tif ( value === this.options.max ) {\n\t\t\tthis._trigger( \"complete\" );\n\t\t}\n\t}\n});\n\n\n/*!\n * jQuery UI Selectable 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/selectable/\n */\n\n\nvar selectable = $.widget(\"ui.selectable\", $.ui.mouse, {\n\tversion: \"1.11.4\",\n\toptions: {\n\t\tappendTo: \"body\",\n\t\tautoRefresh: true,\n\t\tdistance: 0,\n\t\tfilter: \"*\",\n\t\ttolerance: \"touch\",\n\n\t\t// callbacks\n\t\tselected: null,\n\t\tselecting: null,\n\t\tstart: null,\n\t\tstop: null,\n\t\tunselected: null,\n\t\tunselecting: null\n\t},\n\t_create: function() {\n\t\tvar selectees,\n\t\t\tthat = this;\n\n\t\tthis.element.addClass(\"ui-selectable\");\n\n\t\tthis.dragged = false;\n\n\t\t// cache selectee children based on filter\n\t\tthis.refresh = function() {\n\t\t\tselectees = $(that.options.filter, that.element[0]);\n\t\t\tselectees.addClass(\"ui-selectee\");\n\t\t\tselectees.each(function() {\n\t\t\t\tvar $this = $(this),\n\t\t\t\t\tpos = $this.offset();\n\t\t\t\t$.data(this, \"selectable-item\", {\n\t\t\t\t\telement: this,\n\t\t\t\t\t$element: $this,\n\t\t\t\t\tleft: pos.left,\n\t\t\t\t\ttop: pos.top,\n\t\t\t\t\tright: pos.left + $this.outerWidth(),\n\t\t\t\t\tbottom: pos.top + $this.outerHeight(),\n\t\t\t\t\tstartselected: false,\n\t\t\t\t\tselected: $this.hasClass(\"ui-selected\"),\n\t\t\t\t\tselecting: $this.hasClass(\"ui-selecting\"),\n\t\t\t\t\tunselecting: $this.hasClass(\"ui-unselecting\")\n\t\t\t\t});\n\t\t\t});\n\t\t};\n\t\tthis.refresh();\n\n\t\tthis.selectees = selectees.addClass(\"ui-selectee\");\n\n\t\tthis._mouseInit();\n\n\t\tthis.helper = $(\"<div class='ui-selectable-helper'></div>\");\n\t},\n\n\t_destroy: function() {\n\t\tthis.selectees\n\t\t\t.removeClass(\"ui-selectee\")\n\t\t\t.removeData(\"selectable-item\");\n\t\tthis.element\n\t\t\t.removeClass(\"ui-selectable ui-selectable-disabled\");\n\t\tthis._mouseDestroy();\n\t},\n\n\t_mouseStart: function(event) {\n\t\tvar that = this,\n\t\t\toptions = this.options;\n\n\t\tthis.opos = [ event.pageX, event.pageY ];\n\n\t\tif (this.options.disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.selectees = $(options.filter, this.element[0]);\n\n\t\tthis._trigger(\"start\", event);\n\n\t\t$(options.appendTo).append(this.helper);\n\t\t// position helper (lasso)\n\t\tthis.helper.css({\n\t\t\t\"left\": event.pageX,\n\t\t\t\"top\": event.pageY,\n\t\t\t\"width\": 0,\n\t\t\t\"height\": 0\n\t\t});\n\n\t\tif (options.autoRefresh) {\n\t\t\tthis.refresh();\n\t\t}\n\n\t\tthis.selectees.filter(\".ui-selected\").each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\");\n\t\t\tselectee.startselected = true;\n\t\t\tif (!event.metaKey && !event.ctrlKey) {\n\t\t\t\tselectee.$element.removeClass(\"ui-selected\");\n\t\t\t\tselectee.selected = false;\n\t\t\t\tselectee.$element.addClass(\"ui-unselecting\");\n\t\t\t\tselectee.unselecting = true;\n\t\t\t\t// selectable UNSELECTING callback\n\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t\t$(event.target).parents().addBack().each(function() {\n\t\t\tvar doSelect,\n\t\t\t\tselectee = $.data(this, \"selectable-item\");\n\t\t\tif (selectee) {\n\t\t\t\tdoSelect = (!event.metaKey && !event.ctrlKey) || !selectee.$element.hasClass(\"ui-selected\");\n\t\t\t\tselectee.$element\n\t\t\t\t\t.removeClass(doSelect ? \"ui-unselecting\" : \"ui-selected\")\n\t\t\t\t\t.addClass(doSelect ? \"ui-selecting\" : \"ui-unselecting\");\n\t\t\t\tselectee.unselecting = !doSelect;\n\t\t\t\tselectee.selecting = doSelect;\n\t\t\t\tselectee.selected = doSelect;\n\t\t\t\t// selectable (UN)SELECTING callback\n\t\t\t\tif (doSelect) {\n\t\t\t\t\tthat._trigger(\"selecting\", event, {\n\t\t\t\t\t\tselecting: selectee.element\n\t\t\t\t\t});\n\t\t\t\t} else {\n\t\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\n\t},\n\n\t_mouseDrag: function(event) {\n\n\t\tthis.dragged = true;\n\n\t\tif (this.options.disabled) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar tmp,\n\t\t\tthat = this,\n\t\t\toptions = this.options,\n\t\t\tx1 = this.opos[0],\n\t\t\ty1 = this.opos[1],\n\t\t\tx2 = event.pageX,\n\t\t\ty2 = event.pageY;\n\n\t\tif (x1 > x2) { tmp = x2; x2 = x1; x1 = tmp; }\n\t\tif (y1 > y2) { tmp = y2; y2 = y1; y1 = tmp; }\n\t\tthis.helper.css({ left: x1, top: y1, width: x2 - x1, height: y2 - y1 });\n\n\t\tthis.selectees.each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\"),\n\t\t\t\thit = false;\n\n\t\t\t//prevent helper from being selected if appendTo: selectable\n\t\t\tif (!selectee || selectee.element === that.element[0]) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (options.tolerance === \"touch\") {\n\t\t\t\thit = ( !(selectee.left > x2 || selectee.right < x1 || selectee.top > y2 || selectee.bottom < y1) );\n\t\t\t} else if (options.tolerance === \"fit\") {\n\t\t\t\thit = (selectee.left > x1 && selectee.right < x2 && selectee.top > y1 && selectee.bottom < y2);\n\t\t\t}\n\n\t\t\tif (hit) {\n\t\t\t\t// SELECT\n\t\t\t\tif (selectee.selected) {\n\t\t\t\t\tselectee.$element.removeClass(\"ui-selected\");\n\t\t\t\t\tselectee.selected = false;\n\t\t\t\t}\n\t\t\t\tif (selectee.unselecting) {\n\t\t\t\t\tselectee.$element.removeClass(\"ui-unselecting\");\n\t\t\t\t\tselectee.unselecting = false;\n\t\t\t\t}\n\t\t\t\tif (!selectee.selecting) {\n\t\t\t\t\tselectee.$element.addClass(\"ui-selecting\");\n\t\t\t\t\tselectee.selecting = true;\n\t\t\t\t\t// selectable SELECTING callback\n\t\t\t\t\tthat._trigger(\"selecting\", event, {\n\t\t\t\t\t\tselecting: selectee.element\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// UNSELECT\n\t\t\t\tif (selectee.selecting) {\n\t\t\t\t\tif ((event.metaKey || event.ctrlKey) && selectee.startselected) {\n\t\t\t\t\t\tselectee.$element.removeClass(\"ui-selecting\");\n\t\t\t\t\t\tselectee.selecting = false;\n\t\t\t\t\t\tselectee.$element.addClass(\"ui-selected\");\n\t\t\t\t\t\tselectee.selected = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tselectee.$element.removeClass(\"ui-selecting\");\n\t\t\t\t\t\tselectee.selecting = false;\n\t\t\t\t\t\tif (selectee.startselected) {\n\t\t\t\t\t\t\tselectee.$element.addClass(\"ui-unselecting\");\n\t\t\t\t\t\t\tselectee.unselecting = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// selectable UNSELECTING callback\n\t\t\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (selectee.selected) {\n\t\t\t\t\tif (!event.metaKey && !event.ctrlKey && !selectee.startselected) {\n\t\t\t\t\t\tselectee.$element.removeClass(\"ui-selected\");\n\t\t\t\t\t\tselectee.selected = false;\n\n\t\t\t\t\t\tselectee.$element.addClass(\"ui-unselecting\");\n\t\t\t\t\t\tselectee.unselecting = true;\n\t\t\t\t\t\t// selectable UNSELECTING callback\n\t\t\t\t\t\tthat._trigger(\"unselecting\", event, {\n\t\t\t\t\t\t\tunselecting: selectee.element\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function(event) {\n\t\tvar that = this;\n\n\t\tthis.dragged = false;\n\n\t\t$(\".ui-unselecting\", this.element[0]).each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\");\n\t\t\tselectee.$element.removeClass(\"ui-unselecting\");\n\t\t\tselectee.unselecting = false;\n\t\t\tselectee.startselected = false;\n\t\t\tthat._trigger(\"unselected\", event, {\n\t\t\t\tunselected: selectee.element\n\t\t\t});\n\t\t});\n\t\t$(\".ui-selecting\", this.element[0]).each(function() {\n\t\t\tvar selectee = $.data(this, \"selectable-item\");\n\t\t\tselectee.$element.removeClass(\"ui-selecting\").addClass(\"ui-selected\");\n\t\t\tselectee.selecting = false;\n\t\t\tselectee.selected = true;\n\t\t\tselectee.startselected = true;\n\t\t\tthat._trigger(\"selected\", event, {\n\t\t\t\tselected: selectee.element\n\t\t\t});\n\t\t});\n\t\tthis._trigger(\"stop\", event);\n\n\t\tthis.helper.remove();\n\n\t\treturn false;\n\t}\n\n});\n\n\n/*!\n * jQuery UI Selectmenu 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/selectmenu\n */\n\n\nvar selectmenu = $.widget( \"ui.selectmenu\", {\n\tversion: \"1.11.4\",\n\tdefaultElement: \"<select>\",\n\toptions: {\n\t\tappendTo: null,\n\t\tdisabled: null,\n\t\ticons: {\n\t\t\tbutton: \"ui-icon-triangle-1-s\"\n\t\t},\n\t\tposition: {\n\t\t\tmy: \"left top\",\n\t\t\tat: \"left bottom\",\n\t\t\tcollision: \"none\"\n\t\t},\n\t\twidth: null,\n\n\t\t// callbacks\n\t\tchange: null,\n\t\tclose: null,\n\t\tfocus: null,\n\t\topen: null,\n\t\tselect: null\n\t},\n\n\t_create: function() {\n\t\tvar selectmenuId = this.element.uniqueId().attr( \"id\" );\n\t\tthis.ids = {\n\t\t\telement: selectmenuId,\n\t\t\tbutton: selectmenuId + \"-button\",\n\t\t\tmenu: selectmenuId + \"-menu\"\n\t\t};\n\n\t\tthis._drawButton();\n\t\tthis._drawMenu();\n\n\t\tif ( this.options.disabled ) {\n\t\t\tthis.disable();\n\t\t}\n\t},\n\n\t_drawButton: function() {\n\t\tvar that = this;\n\n\t\t// Associate existing label with the new button\n\t\tthis.label = $( \"label[for='\" + this.ids.element + \"']\" ).attr( \"for\", this.ids.button );\n\t\tthis._on( this.label, {\n\t\t\tclick: function( event ) {\n\t\t\t\tthis.button.focus();\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t});\n\n\t\t// Hide original select element\n\t\tthis.element.hide();\n\n\t\t// Create button\n\t\tthis.button = $( \"<span>\", {\n\t\t\t\"class\": \"ui-selectmenu-button ui-widget ui-state-default ui-corner-all\",\n\t\t\ttabindex: this.options.disabled ? -1 : 0,\n\t\t\tid: this.ids.button,\n\t\t\trole: \"combobox\",\n\t\t\t\"aria-expanded\": \"false\",\n\t\t\t\"aria-autocomplete\": \"list\",\n\t\t\t\"aria-owns\": this.ids.menu,\n\t\t\t\"aria-haspopup\": \"true\"\n\t\t})\n\t\t\t.insertAfter( this.element );\n\n\t\t$( \"<span>\", {\n\t\t\t\"class\": \"ui-icon \" + this.options.icons.button\n\t\t})\n\t\t\t.prependTo( this.button );\n\n\t\tthis.buttonText = $( \"<span>\", {\n\t\t\t\"class\": \"ui-selectmenu-text\"\n\t\t})\n\t\t\t.appendTo( this.button );\n\n\t\tthis._setText( this.buttonText, this.element.find( \"option:selected\" ).text() );\n\t\tthis._resizeButton();\n\n\t\tthis._on( this.button, this._buttonEvents );\n\t\tthis.button.one( \"focusin\", function() {\n\n\t\t\t// Delay rendering the menu items until the button receives focus.\n\t\t\t// The menu may have already been rendered via a programmatic open.\n\t\t\tif ( !that.menuItems ) {\n\t\t\t\tthat._refreshMenu();\n\t\t\t}\n\t\t});\n\t\tthis._hoverable( this.button );\n\t\tthis._focusable( this.button );\n\t},\n\n\t_drawMenu: function() {\n\t\tvar that = this;\n\n\t\t// Create menu\n\t\tthis.menu = $( \"<ul>\", {\n\t\t\t\"aria-hidden\": \"true\",\n\t\t\t\"aria-labelledby\": this.ids.button,\n\t\t\tid: this.ids.menu\n\t\t});\n\n\t\t// Wrap menu\n\t\tthis.menuWrap = $( \"<div>\", {\n\t\t\t\"class\": \"ui-selectmenu-menu ui-front\"\n\t\t})\n\t\t\t.append( this.menu )\n\t\t\t.appendTo( this._appendTo() );\n\n\t\t// Initialize menu widget\n\t\tthis.menuInstance = this.menu\n\t\t\t.menu({\n\t\t\t\trole: \"listbox\",\n\t\t\t\tselect: function( event, ui ) {\n\t\t\t\t\tevent.preventDefault();\n\n\t\t\t\t\t// support: IE8\n\t\t\t\t\t// If the item was selected via a click, the text selection\n\t\t\t\t\t// will be destroyed in IE\n\t\t\t\t\tthat._setSelection();\n\n\t\t\t\t\tthat._select( ui.item.data( \"ui-selectmenu-item\" ), event );\n\t\t\t\t},\n\t\t\t\tfocus: function( event, ui ) {\n\t\t\t\t\tvar item = ui.item.data( \"ui-selectmenu-item\" );\n\n\t\t\t\t\t// Prevent inital focus from firing and check if its a newly focused item\n\t\t\t\t\tif ( that.focusIndex != null && item.index !== that.focusIndex ) {\n\t\t\t\t\t\tthat._trigger( \"focus\", event, { item: item } );\n\t\t\t\t\t\tif ( !that.isOpen ) {\n\t\t\t\t\t\t\tthat._select( item, event );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tthat.focusIndex = item.index;\n\n\t\t\t\t\tthat.button.attr( \"aria-activedescendant\",\n\t\t\t\t\t\tthat.menuItems.eq( item.index ).attr( \"id\" ) );\n\t\t\t\t}\n\t\t\t})\n\t\t\t.menu( \"instance\" );\n\n\t\t// Adjust menu styles to dropdown\n\t\tthis.menu\n\t\t\t.addClass( \"ui-corner-bottom\" )\n\t\t\t.removeClass( \"ui-corner-all\" );\n\n\t\t// Don't close the menu on mouseleave\n\t\tthis.menuInstance._off( this.menu, \"mouseleave\" );\n\n\t\t// Cancel the menu's collapseAll on document click\n\t\tthis.menuInstance._closeOnDocumentClick = function() {\n\t\t\treturn false;\n\t\t};\n\n\t\t// Selects often contain empty items, but never contain dividers\n\t\tthis.menuInstance._isDivider = function() {\n\t\t\treturn false;\n\t\t};\n\t},\n\n\trefresh: function() {\n\t\tthis._refreshMenu();\n\t\tthis._setText( this.buttonText, this._getSelectedItem().text() );\n\t\tif ( !this.options.width ) {\n\t\t\tthis._resizeButton();\n\t\t}\n\t},\n\n\t_refreshMenu: function() {\n\t\tthis.menu.empty();\n\n\t\tvar item,\n\t\t\toptions = this.element.find( \"option\" );\n\n\t\tif ( !options.length ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis._parseOptions( options );\n\t\tthis._renderMenu( this.menu, this.items );\n\n\t\tthis.menuInstance.refresh();\n\t\tthis.menuItems = this.menu.find( \"li\" ).not( \".ui-selectmenu-optgroup\" );\n\n\t\titem = this._getSelectedItem();\n\n\t\t// Update the menu to have the correct item focused\n\t\tthis.menuInstance.focus( null, item );\n\t\tthis._setAria( item.data( \"ui-selectmenu-item\" ) );\n\n\t\t// Set disabled state\n\t\tthis._setOption( \"disabled\", this.element.prop( \"disabled\" ) );\n\t},\n\n\topen: function( event ) {\n\t\tif ( this.options.disabled ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If this is the first time the menu is being opened, render the items\n\t\tif ( !this.menuItems ) {\n\t\t\tthis._refreshMenu();\n\t\t} else {\n\n\t\t\t// Menu clears focus on close, reset focus to selected item\n\t\t\tthis.menu.find( \".ui-state-focus\" ).removeClass( \"ui-state-focus\" );\n\t\t\tthis.menuInstance.focus( null, this._getSelectedItem() );\n\t\t}\n\n\t\tthis.isOpen = true;\n\t\tthis._toggleAttr();\n\t\tthis._resizeMenu();\n\t\tthis._position();\n\n\t\tthis._on( this.document, this._documentClick );\n\n\t\tthis._trigger( \"open\", event );\n\t},\n\n\t_position: function() {\n\t\tthis.menuWrap.position( $.extend( { of: this.button }, this.options.position ) );\n\t},\n\n\tclose: function( event ) {\n\t\tif ( !this.isOpen ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.isOpen = false;\n\t\tthis._toggleAttr();\n\n\t\tthis.range = null;\n\t\tthis._off( this.document );\n\n\t\tthis._trigger( \"close\", event );\n\t},\n\n\twidget: function() {\n\t\treturn this.button;\n\t},\n\n\tmenuWidget: function() {\n\t\treturn this.menu;\n\t},\n\n\t_renderMenu: function( ul, items ) {\n\t\tvar that = this,\n\t\t\tcurrentOptgroup = \"\";\n\n\t\t$.each( items, function( index, item ) {\n\t\t\tif ( item.optgroup !== currentOptgroup ) {\n\t\t\t\t$( \"<li>\", {\n\t\t\t\t\t\"class\": \"ui-selectmenu-optgroup ui-menu-divider\" +\n\t\t\t\t\t\t( item.element.parent( \"optgroup\" ).prop( \"disabled\" ) ?\n\t\t\t\t\t\t\t\" ui-state-disabled\" :\n\t\t\t\t\t\t\t\"\" ),\n\t\t\t\t\ttext: item.optgroup\n\t\t\t\t})\n\t\t\t\t\t.appendTo( ul );\n\n\t\t\t\tcurrentOptgroup = item.optgroup;\n\t\t\t}\n\n\t\t\tthat._renderItemData( ul, item );\n\t\t});\n\t},\n\n\t_renderItemData: function( ul, item ) {\n\t\treturn this._renderItem( ul, item ).data( \"ui-selectmenu-item\", item );\n\t},\n\n\t_renderItem: function( ul, item ) {\n\t\tvar li = $( \"<li>\" );\n\n\t\tif ( item.disabled ) {\n\t\t\tli.addClass( \"ui-state-disabled\" );\n\t\t}\n\t\tthis._setText( li, item.label );\n\n\t\treturn li.appendTo( ul );\n\t},\n\n\t_setText: function( element, value ) {\n\t\tif ( value ) {\n\t\t\telement.text( value );\n\t\t} else {\n\t\t\telement.html( \"&#160;\" );\n\t\t}\n\t},\n\n\t_move: function( direction, event ) {\n\t\tvar item, next,\n\t\t\tfilter = \".ui-menu-item\";\n\n\t\tif ( this.isOpen ) {\n\t\t\titem = this.menuItems.eq( this.focusIndex );\n\t\t} else {\n\t\t\titem = this.menuItems.eq( this.element[ 0 ].selectedIndex );\n\t\t\tfilter += \":not(.ui-state-disabled)\";\n\t\t}\n\n\t\tif ( direction === \"first\" || direction === \"last\" ) {\n\t\t\tnext = item[ direction === \"first\" ? \"prevAll\" : \"nextAll\" ]( filter ).eq( -1 );\n\t\t} else {\n\t\t\tnext = item[ direction + \"All\" ]( filter ).eq( 0 );\n\t\t}\n\n\t\tif ( next.length ) {\n\t\t\tthis.menuInstance.focus( event, next );\n\t\t}\n\t},\n\n\t_getSelectedItem: function() {\n\t\treturn this.menuItems.eq( this.element[ 0 ].selectedIndex );\n\t},\n\n\t_toggle: function( event ) {\n\t\tthis[ this.isOpen ? \"close\" : \"open\" ]( event );\n\t},\n\n\t_setSelection: function() {\n\t\tvar selection;\n\n\t\tif ( !this.range ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( window.getSelection ) {\n\t\t\tselection = window.getSelection();\n\t\t\tselection.removeAllRanges();\n\t\t\tselection.addRange( this.range );\n\n\t\t// support: IE8\n\t\t} else {\n\t\t\tthis.range.select();\n\t\t}\n\n\t\t// support: IE\n\t\t// Setting the text selection kills the button focus in IE, but\n\t\t// restoring the focus doesn't kill the selection.\n\t\tthis.button.focus();\n\t},\n\n\t_documentClick: {\n\t\tmousedown: function( event ) {\n\t\t\tif ( !this.isOpen ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( !$( event.target ).closest( \".ui-selectmenu-menu, #\" + this.ids.button ).length ) {\n\t\t\t\tthis.close( event );\n\t\t\t}\n\t\t}\n\t},\n\n\t_buttonEvents: {\n\n\t\t// Prevent text selection from being reset when interacting with the selectmenu (#10144)\n\t\tmousedown: function() {\n\t\t\tvar selection;\n\n\t\t\tif ( window.getSelection ) {\n\t\t\t\tselection = window.getSelection();\n\t\t\t\tif ( selection.rangeCount ) {\n\t\t\t\t\tthis.range = selection.getRangeAt( 0 );\n\t\t\t\t}\n\n\t\t\t// support: IE8\n\t\t\t} else {\n\t\t\t\tthis.range = document.selection.createRange();\n\t\t\t}\n\t\t},\n\n\t\tclick: function( event ) {\n\t\t\tthis._setSelection();\n\t\t\tthis._toggle( event );\n\t\t},\n\n\t\tkeydown: function( event ) {\n\t\t\tvar preventDefault = true;\n\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase $.ui.keyCode.TAB:\n\t\t\t\tcase $.ui.keyCode.ESCAPE:\n\t\t\t\t\tthis.close( event );\n\t\t\t\t\tpreventDefault = false;\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.ENTER:\n\t\t\t\t\tif ( this.isOpen ) {\n\t\t\t\t\t\tthis._selectFocusedItem( event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.UP:\n\t\t\t\t\tif ( event.altKey ) {\n\t\t\t\t\t\tthis._toggle( event );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._move( \"prev\", event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.DOWN:\n\t\t\t\t\tif ( event.altKey ) {\n\t\t\t\t\t\tthis._toggle( event );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._move( \"next\", event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.SPACE:\n\t\t\t\t\tif ( this.isOpen ) {\n\t\t\t\t\t\tthis._selectFocusedItem( event );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._toggle( event );\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.LEFT:\n\t\t\t\t\tthis._move( \"prev\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.RIGHT:\n\t\t\t\t\tthis._move( \"next\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.HOME:\n\t\t\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\t\t\tthis._move( \"first\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.END:\n\t\t\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\t\t\tthis._move( \"last\", event );\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tthis.menu.trigger( event );\n\t\t\t\t\tpreventDefault = false;\n\t\t\t}\n\n\t\t\tif ( preventDefault ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t}\n\t},\n\n\t_selectFocusedItem: function( event ) {\n\t\tvar item = this.menuItems.eq( this.focusIndex );\n\t\tif ( !item.hasClass( \"ui-state-disabled\" ) ) {\n\t\t\tthis._select( item.data( \"ui-selectmenu-item\" ), event );\n\t\t}\n\t},\n\n\t_select: function( item, event ) {\n\t\tvar oldIndex = this.element[ 0 ].selectedIndex;\n\n\t\t// Change native select element\n\t\tthis.element[ 0 ].selectedIndex = item.index;\n\t\tthis._setText( this.buttonText, item.label );\n\t\tthis._setAria( item );\n\t\tthis._trigger( \"select\", event, { item: item } );\n\n\t\tif ( item.index !== oldIndex ) {\n\t\t\tthis._trigger( \"change\", event, { item: item } );\n\t\t}\n\n\t\tthis.close( event );\n\t},\n\n\t_setAria: function( item ) {\n\t\tvar id = this.menuItems.eq( item.index ).attr( \"id\" );\n\n\t\tthis.button.attr({\n\t\t\t\"aria-labelledby\": id,\n\t\t\t\"aria-activedescendant\": id\n\t\t});\n\t\tthis.menu.attr( \"aria-activedescendant\", id );\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"icons\" ) {\n\t\t\tthis.button.find( \"span.ui-icon\" )\n\t\t\t\t.removeClass( this.options.icons.button )\n\t\t\t\t.addClass( value.button );\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"appendTo\" ) {\n\t\t\tthis.menuWrap.appendTo( this._appendTo() );\n\t\t}\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.menuInstance.option( \"disabled\", value );\n\t\t\tthis.button\n\t\t\t\t.toggleClass( \"ui-state-disabled\", value )\n\t\t\t\t.attr( \"aria-disabled\", value );\n\n\t\t\tthis.element.prop( \"disabled\", value );\n\t\t\tif ( value ) {\n\t\t\t\tthis.button.attr( \"tabindex\", -1 );\n\t\t\t\tthis.close();\n\t\t\t} else {\n\t\t\t\tthis.button.attr( \"tabindex\", 0 );\n\t\t\t}\n\t\t}\n\n\t\tif ( key === \"width\" ) {\n\t\t\tthis._resizeButton();\n\t\t}\n\t},\n\n\t_appendTo: function() {\n\t\tvar element = this.options.appendTo;\n\n\t\tif ( element ) {\n\t\t\telement = element.jquery || element.nodeType ?\n\t\t\t\t$( element ) :\n\t\t\t\tthis.document.find( element ).eq( 0 );\n\t\t}\n\n\t\tif ( !element || !element[ 0 ] ) {\n\t\t\telement = this.element.closest( \".ui-front\" );\n\t\t}\n\n\t\tif ( !element.length ) {\n\t\t\telement = this.document[ 0 ].body;\n\t\t}\n\n\t\treturn element;\n\t},\n\n\t_toggleAttr: function() {\n\t\tthis.button\n\t\t\t.toggleClass( \"ui-corner-top\", this.isOpen )\n\t\t\t.toggleClass( \"ui-corner-all\", !this.isOpen )\n\t\t\t.attr( \"aria-expanded\", this.isOpen );\n\t\tthis.menuWrap.toggleClass( \"ui-selectmenu-open\", this.isOpen );\n\t\tthis.menu.attr( \"aria-hidden\", !this.isOpen );\n\t},\n\n\t_resizeButton: function() {\n\t\tvar width = this.options.width;\n\n\t\tif ( !width ) {\n\t\t\twidth = this.element.show().outerWidth();\n\t\t\tthis.element.hide();\n\t\t}\n\n\t\tthis.button.outerWidth( width );\n\t},\n\n\t_resizeMenu: function() {\n\t\tthis.menu.outerWidth( Math.max(\n\t\t\tthis.button.outerWidth(),\n\n\t\t\t// support: IE10\n\t\t\t// IE10 wraps long text (possibly a rounding bug)\n\t\t\t// so we add 1px to avoid the wrapping\n\t\t\tthis.menu.width( \"\" ).outerWidth() + 1\n\t\t) );\n\t},\n\n\t_getCreateOptions: function() {\n\t\treturn { disabled: this.element.prop( \"disabled\" ) };\n\t},\n\n\t_parseOptions: function( options ) {\n\t\tvar data = [];\n\t\toptions.each(function( index, item ) {\n\t\t\tvar option = $( item ),\n\t\t\t\toptgroup = option.parent( \"optgroup\" );\n\t\t\tdata.push({\n\t\t\t\telement: option,\n\t\t\t\tindex: index,\n\t\t\t\tvalue: option.val(),\n\t\t\t\tlabel: option.text(),\n\t\t\t\toptgroup: optgroup.attr( \"label\" ) || \"\",\n\t\t\t\tdisabled: optgroup.prop( \"disabled\" ) || option.prop( \"disabled\" )\n\t\t\t});\n\t\t});\n\t\tthis.items = data;\n\t},\n\n\t_destroy: function() {\n\t\tthis.menuWrap.remove();\n\t\tthis.button.remove();\n\t\tthis.element.show();\n\t\tthis.element.removeUniqueId();\n\t\tthis.label.attr( \"for\", this.ids.element );\n\t}\n});\n\n\n/*!\n * jQuery UI Slider 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/slider/\n */\n\n\nvar slider = $.widget( \"ui.slider\", $.ui.mouse, {\n\tversion: \"1.11.4\",\n\twidgetEventPrefix: \"slide\",\n\n\toptions: {\n\t\tanimate: false,\n\t\tdistance: 0,\n\t\tmax: 100,\n\t\tmin: 0,\n\t\torientation: \"horizontal\",\n\t\trange: false,\n\t\tstep: 1,\n\t\tvalue: 0,\n\t\tvalues: null,\n\n\t\t// callbacks\n\t\tchange: null,\n\t\tslide: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\n\t// number of pages in a slider\n\t// (how many times can you page up/down to go through the whole range)\n\tnumPages: 5,\n\n\t_create: function() {\n\t\tthis._keySliding = false;\n\t\tthis._mouseSliding = false;\n\t\tthis._animateOff = true;\n\t\tthis._handleIndex = null;\n\t\tthis._detectOrientation();\n\t\tthis._mouseInit();\n\t\tthis._calculateNewMax();\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-slider\" +\n\t\t\t\t\" ui-slider-\" + this.orientation +\n\t\t\t\t\" ui-widget\" +\n\t\t\t\t\" ui-widget-content\" +\n\t\t\t\t\" ui-corner-all\");\n\n\t\tthis._refresh();\n\t\tthis._setOption( \"disabled\", this.options.disabled );\n\n\t\tthis._animateOff = false;\n\t},\n\n\t_refresh: function() {\n\t\tthis._createRange();\n\t\tthis._createHandles();\n\t\tthis._setupEvents();\n\t\tthis._refreshValue();\n\t},\n\n\t_createHandles: function() {\n\t\tvar i, handleCount,\n\t\t\toptions = this.options,\n\t\t\texistingHandles = this.element.find( \".ui-slider-handle\" ).addClass( \"ui-state-default ui-corner-all\" ),\n\t\t\thandle = \"<span class='ui-slider-handle ui-state-default ui-corner-all' tabindex='0'></span>\",\n\t\t\thandles = [];\n\n\t\thandleCount = ( options.values && options.values.length ) || 1;\n\n\t\tif ( existingHandles.length > handleCount ) {\n\t\t\texistingHandles.slice( handleCount ).remove();\n\t\t\texistingHandles = existingHandles.slice( 0, handleCount );\n\t\t}\n\n\t\tfor ( i = existingHandles.length; i < handleCount; i++ ) {\n\t\t\thandles.push( handle );\n\t\t}\n\n\t\tthis.handles = existingHandles.add( $( handles.join( \"\" ) ).appendTo( this.element ) );\n\n\t\tthis.handle = this.handles.eq( 0 );\n\n\t\tthis.handles.each(function( i ) {\n\t\t\t$( this ).data( \"ui-slider-handle-index\", i );\n\t\t});\n\t},\n\n\t_createRange: function() {\n\t\tvar options = this.options,\n\t\t\tclasses = \"\";\n\n\t\tif ( options.range ) {\n\t\t\tif ( options.range === true ) {\n\t\t\t\tif ( !options.values ) {\n\t\t\t\t\toptions.values = [ this._valueMin(), this._valueMin() ];\n\t\t\t\t} else if ( options.values.length && options.values.length !== 2 ) {\n\t\t\t\t\toptions.values = [ options.values[0], options.values[0] ];\n\t\t\t\t} else if ( $.isArray( options.values ) ) {\n\t\t\t\t\toptions.values = options.values.slice(0);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( !this.range || !this.range.length ) {\n\t\t\t\tthis.range = $( \"<div></div>\" )\n\t\t\t\t\t.appendTo( this.element );\n\n\t\t\t\tclasses = \"ui-slider-range\" +\n\t\t\t\t// note: this isn't the most fittingly semantic framework class for this element,\n\t\t\t\t// but worked best visually with a variety of themes\n\t\t\t\t\" ui-widget-header ui-corner-all\";\n\t\t\t} else {\n\t\t\t\tthis.range.removeClass( \"ui-slider-range-min ui-slider-range-max\" )\n\t\t\t\t\t// Handle range switching from true to min/max\n\t\t\t\t\t.css({\n\t\t\t\t\t\t\"left\": \"\",\n\t\t\t\t\t\t\"bottom\": \"\"\n\t\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.range.addClass( classes +\n\t\t\t\t( ( options.range === \"min\" || options.range === \"max\" ) ? \" ui-slider-range-\" + options.range : \"\" ) );\n\t\t} else {\n\t\t\tif ( this.range ) {\n\t\t\t\tthis.range.remove();\n\t\t\t}\n\t\t\tthis.range = null;\n\t\t}\n\t},\n\n\t_setupEvents: function() {\n\t\tthis._off( this.handles );\n\t\tthis._on( this.handles, this._handleEvents );\n\t\tthis._hoverable( this.handles );\n\t\tthis._focusable( this.handles );\n\t},\n\n\t_destroy: function() {\n\t\tthis.handles.remove();\n\t\tif ( this.range ) {\n\t\t\tthis.range.remove();\n\t\t}\n\n\t\tthis.element\n\t\t\t.removeClass( \"ui-slider\" +\n\t\t\t\t\" ui-slider-horizontal\" +\n\t\t\t\t\" ui-slider-vertical\" +\n\t\t\t\t\" ui-widget\" +\n\t\t\t\t\" ui-widget-content\" +\n\t\t\t\t\" ui-corner-all\" );\n\n\t\tthis._mouseDestroy();\n\t},\n\n\t_mouseCapture: function( event ) {\n\t\tvar position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,\n\t\t\tthat = this,\n\t\t\to = this.options;\n\n\t\tif ( o.disabled ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tthis.elementSize = {\n\t\t\twidth: this.element.outerWidth(),\n\t\t\theight: this.element.outerHeight()\n\t\t};\n\t\tthis.elementOffset = this.element.offset();\n\n\t\tposition = { x: event.pageX, y: event.pageY };\n\t\tnormValue = this._normValueFromMouse( position );\n\t\tdistance = this._valueMax() - this._valueMin() + 1;\n\t\tthis.handles.each(function( i ) {\n\t\t\tvar thisDistance = Math.abs( normValue - that.values(i) );\n\t\t\tif (( distance > thisDistance ) ||\n\t\t\t\t( distance === thisDistance &&\n\t\t\t\t\t(i === that._lastChangedValue || that.values(i) === o.min ))) {\n\t\t\t\tdistance = thisDistance;\n\t\t\t\tclosestHandle = $( this );\n\t\t\t\tindex = i;\n\t\t\t}\n\t\t});\n\n\t\tallowed = this._start( event, index );\n\t\tif ( allowed === false ) {\n\t\t\treturn false;\n\t\t}\n\t\tthis._mouseSliding = true;\n\n\t\tthis._handleIndex = index;\n\n\t\tclosestHandle\n\t\t\t.addClass( \"ui-state-active\" )\n\t\t\t.focus();\n\n\t\toffset = closestHandle.offset();\n\t\tmouseOverHandle = !$( event.target ).parents().addBack().is( \".ui-slider-handle\" );\n\t\tthis._clickOffset = mouseOverHandle ? { left: 0, top: 0 } : {\n\t\t\tleft: event.pageX - offset.left - ( closestHandle.width() / 2 ),\n\t\t\ttop: event.pageY - offset.top -\n\t\t\t\t( closestHandle.height() / 2 ) -\n\t\t\t\t( parseInt( closestHandle.css(\"borderTopWidth\"), 10 ) || 0 ) -\n\t\t\t\t( parseInt( closestHandle.css(\"borderBottomWidth\"), 10 ) || 0) +\n\t\t\t\t( parseInt( closestHandle.css(\"marginTop\"), 10 ) || 0)\n\t\t};\n\n\t\tif ( !this.handles.hasClass( \"ui-state-hover\" ) ) {\n\t\t\tthis._slide( event, index, normValue );\n\t\t}\n\t\tthis._animateOff = true;\n\t\treturn true;\n\t},\n\n\t_mouseStart: function() {\n\t\treturn true;\n\t},\n\n\t_mouseDrag: function( event ) {\n\t\tvar position = { x: event.pageX, y: event.pageY },\n\t\t\tnormValue = this._normValueFromMouse( position );\n\n\t\tthis._slide( event, this._handleIndex, normValue );\n\n\t\treturn false;\n\t},\n\n\t_mouseStop: function( event ) {\n\t\tthis.handles.removeClass( \"ui-state-active\" );\n\t\tthis._mouseSliding = false;\n\n\t\tthis._stop( event, this._handleIndex );\n\t\tthis._change( event, this._handleIndex );\n\n\t\tthis._handleIndex = null;\n\t\tthis._clickOffset = null;\n\t\tthis._animateOff = false;\n\n\t\treturn false;\n\t},\n\n\t_detectOrientation: function() {\n\t\tthis.orientation = ( this.options.orientation === \"vertical\" ) ? \"vertical\" : \"horizontal\";\n\t},\n\n\t_normValueFromMouse: function( position ) {\n\t\tvar pixelTotal,\n\t\t\tpixelMouse,\n\t\t\tpercentMouse,\n\t\t\tvalueTotal,\n\t\t\tvalueMouse;\n\n\t\tif ( this.orientation === \"horizontal\" ) {\n\t\t\tpixelTotal = this.elementSize.width;\n\t\t\tpixelMouse = position.x - this.elementOffset.left - ( this._clickOffset ? this._clickOffset.left : 0 );\n\t\t} else {\n\t\t\tpixelTotal = this.elementSize.height;\n\t\t\tpixelMouse = position.y - this.elementOffset.top - ( this._clickOffset ? this._clickOffset.top : 0 );\n\t\t}\n\n\t\tpercentMouse = ( pixelMouse / pixelTotal );\n\t\tif ( percentMouse > 1 ) {\n\t\t\tpercentMouse = 1;\n\t\t}\n\t\tif ( percentMouse < 0 ) {\n\t\t\tpercentMouse = 0;\n\t\t}\n\t\tif ( this.orientation === \"vertical\" ) {\n\t\t\tpercentMouse = 1 - percentMouse;\n\t\t}\n\n\t\tvalueTotal = this._valueMax() - this._valueMin();\n\t\tvalueMouse = this._valueMin() + percentMouse * valueTotal;\n\n\t\treturn this._trimAlignValue( valueMouse );\n\t},\n\n\t_start: function( event, index ) {\n\t\tvar uiHash = {\n\t\t\thandle: this.handles[ index ],\n\t\t\tvalue: this.value()\n\t\t};\n\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\tuiHash.value = this.values( index );\n\t\t\tuiHash.values = this.values();\n\t\t}\n\t\treturn this._trigger( \"start\", event, uiHash );\n\t},\n\n\t_slide: function( event, index, newVal ) {\n\t\tvar otherVal,\n\t\t\tnewValues,\n\t\t\tallowed;\n\n\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\totherVal = this.values( index ? 0 : 1 );\n\n\t\t\tif ( ( this.options.values.length === 2 && this.options.range === true ) &&\n\t\t\t\t\t( ( index === 0 && newVal > otherVal) || ( index === 1 && newVal < otherVal ) )\n\t\t\t\t) {\n\t\t\t\tnewVal = otherVal;\n\t\t\t}\n\n\t\t\tif ( newVal !== this.values( index ) ) {\n\t\t\t\tnewValues = this.values();\n\t\t\t\tnewValues[ index ] = newVal;\n\t\t\t\t// A slide can be canceled by returning false from the slide callback\n\t\t\t\tallowed = this._trigger( \"slide\", event, {\n\t\t\t\t\thandle: this.handles[ index ],\n\t\t\t\t\tvalue: newVal,\n\t\t\t\t\tvalues: newValues\n\t\t\t\t} );\n\t\t\t\totherVal = this.values( index ? 0 : 1 );\n\t\t\t\tif ( allowed !== false ) {\n\t\t\t\t\tthis.values( index, newVal );\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif ( newVal !== this.value() ) {\n\t\t\t\t// A slide can be canceled by returning false from the slide callback\n\t\t\t\tallowed = this._trigger( \"slide\", event, {\n\t\t\t\t\thandle: this.handles[ index ],\n\t\t\t\t\tvalue: newVal\n\t\t\t\t} );\n\t\t\t\tif ( allowed !== false ) {\n\t\t\t\t\tthis.value( newVal );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t_stop: function( event, index ) {\n\t\tvar uiHash = {\n\t\t\thandle: this.handles[ index ],\n\t\t\tvalue: this.value()\n\t\t};\n\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\tuiHash.value = this.values( index );\n\t\t\tuiHash.values = this.values();\n\t\t}\n\n\t\tthis._trigger( \"stop\", event, uiHash );\n\t},\n\n\t_change: function( event, index ) {\n\t\tif ( !this._keySliding && !this._mouseSliding ) {\n\t\t\tvar uiHash = {\n\t\t\t\thandle: this.handles[ index ],\n\t\t\t\tvalue: this.value()\n\t\t\t};\n\t\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\t\tuiHash.value = this.values( index );\n\t\t\t\tuiHash.values = this.values();\n\t\t\t}\n\n\t\t\t//store the last changed value index for reference when handles overlap\n\t\t\tthis._lastChangedValue = index;\n\n\t\t\tthis._trigger( \"change\", event, uiHash );\n\t\t}\n\t},\n\n\tvalue: function( newValue ) {\n\t\tif ( arguments.length ) {\n\t\t\tthis.options.value = this._trimAlignValue( newValue );\n\t\t\tthis._refreshValue();\n\t\t\tthis._change( null, 0 );\n\t\t\treturn;\n\t\t}\n\n\t\treturn this._value();\n\t},\n\n\tvalues: function( index, newValue ) {\n\t\tvar vals,\n\t\t\tnewValues,\n\t\t\ti;\n\n\t\tif ( arguments.length > 1 ) {\n\t\t\tthis.options.values[ index ] = this._trimAlignValue( newValue );\n\t\t\tthis._refreshValue();\n\t\t\tthis._change( null, index );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( arguments.length ) {\n\t\t\tif ( $.isArray( arguments[ 0 ] ) ) {\n\t\t\t\tvals = this.options.values;\n\t\t\t\tnewValues = arguments[ 0 ];\n\t\t\t\tfor ( i = 0; i < vals.length; i += 1 ) {\n\t\t\t\t\tvals[ i ] = this._trimAlignValue( newValues[ i ] );\n\t\t\t\t\tthis._change( null, i );\n\t\t\t\t}\n\t\t\t\tthis._refreshValue();\n\t\t\t} else {\n\t\t\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\t\t\treturn this._values( index );\n\t\t\t\t} else {\n\t\t\t\t\treturn this.value();\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\treturn this._values();\n\t\t}\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tvar i,\n\t\t\tvalsLength = 0;\n\n\t\tif ( key === \"range\" && this.options.range === true ) {\n\t\t\tif ( value === \"min\" ) {\n\t\t\t\tthis.options.value = this._values( 0 );\n\t\t\t\tthis.options.values = null;\n\t\t\t} else if ( value === \"max\" ) {\n\t\t\t\tthis.options.value = this._values( this.options.values.length - 1 );\n\t\t\t\tthis.options.values = null;\n\t\t\t}\n\t\t}\n\n\t\tif ( $.isArray( this.options.values ) ) {\n\t\t\tvalsLength = this.options.values.length;\n\t\t}\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.element.toggleClass( \"ui-state-disabled\", !!value );\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tswitch ( key ) {\n\t\t\tcase \"orientation\":\n\t\t\t\tthis._detectOrientation();\n\t\t\t\tthis.element\n\t\t\t\t\t.removeClass( \"ui-slider-horizontal ui-slider-vertical\" )\n\t\t\t\t\t.addClass( \"ui-slider-\" + this.orientation );\n\t\t\t\tthis._refreshValue();\n\n\t\t\t\t// Reset positioning from previous orientation\n\t\t\t\tthis.handles.css( value === \"horizontal\" ? \"bottom\" : \"left\", \"\" );\n\t\t\t\tbreak;\n\t\t\tcase \"value\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refreshValue();\n\t\t\t\tthis._change( null, 0 );\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t\tcase \"values\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refreshValue();\n\t\t\t\tfor ( i = 0; i < valsLength; i += 1 ) {\n\t\t\t\t\tthis._change( null, i );\n\t\t\t\t}\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t\tcase \"step\":\n\t\t\tcase \"min\":\n\t\t\tcase \"max\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._calculateNewMax();\n\t\t\t\tthis._refreshValue();\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t\tcase \"range\":\n\t\t\t\tthis._animateOff = true;\n\t\t\t\tthis._refresh();\n\t\t\t\tthis._animateOff = false;\n\t\t\t\tbreak;\n\t\t}\n\t},\n\n\t//internal value getter\n\t// _value() returns value trimmed by min and max, aligned by step\n\t_value: function() {\n\t\tvar val = this.options.value;\n\t\tval = this._trimAlignValue( val );\n\n\t\treturn val;\n\t},\n\n\t//internal values getter\n\t// _values() returns array of values trimmed by min and max, aligned by step\n\t// _values( index ) returns single value trimmed by min and max, aligned by step\n\t_values: function( index ) {\n\t\tvar val,\n\t\t\tvals,\n\t\t\ti;\n\n\t\tif ( arguments.length ) {\n\t\t\tval = this.options.values[ index ];\n\t\t\tval = this._trimAlignValue( val );\n\n\t\t\treturn val;\n\t\t} else if ( this.options.values && this.options.values.length ) {\n\t\t\t// .slice() creates a copy of the array\n\t\t\t// this copy gets trimmed by min and max and then returned\n\t\t\tvals = this.options.values.slice();\n\t\t\tfor ( i = 0; i < vals.length; i += 1) {\n\t\t\t\tvals[ i ] = this._trimAlignValue( vals[ i ] );\n\t\t\t}\n\n\t\t\treturn vals;\n\t\t} else {\n\t\t\treturn [];\n\t\t}\n\t},\n\n\t// returns the step-aligned value that val is closest to, between (inclusive) min and max\n\t_trimAlignValue: function( val ) {\n\t\tif ( val <= this._valueMin() ) {\n\t\t\treturn this._valueMin();\n\t\t}\n\t\tif ( val >= this._valueMax() ) {\n\t\t\treturn this._valueMax();\n\t\t}\n\t\tvar step = ( this.options.step > 0 ) ? this.options.step : 1,\n\t\t\tvalModStep = (val - this._valueMin()) % step,\n\t\t\talignValue = val - valModStep;\n\n\t\tif ( Math.abs(valModStep) * 2 >= step ) {\n\t\t\talignValue += ( valModStep > 0 ) ? step : ( -step );\n\t\t}\n\n\t\t// Since JavaScript has problems with large floats, round\n\t\t// the final value to 5 digits after the decimal point (see #4124)\n\t\treturn parseFloat( alignValue.toFixed(5) );\n\t},\n\n\t_calculateNewMax: function() {\n\t\tvar max = this.options.max,\n\t\t\tmin = this._valueMin(),\n\t\t\tstep = this.options.step,\n\t\t\taboveMin = Math.floor( ( +( max - min ).toFixed( this._precision() ) ) / step ) * step;\n\t\tmax = aboveMin + min;\n\t\tthis.max = parseFloat( max.toFixed( this._precision() ) );\n\t},\n\n\t_precision: function() {\n\t\tvar precision = this._precisionOf( this.options.step );\n\t\tif ( this.options.min !== null ) {\n\t\t\tprecision = Math.max( precision, this._precisionOf( this.options.min ) );\n\t\t}\n\t\treturn precision;\n\t},\n\n\t_precisionOf: function( num ) {\n\t\tvar str = num.toString(),\n\t\t\tdecimal = str.indexOf( \".\" );\n\t\treturn decimal === -1 ? 0 : str.length - decimal - 1;\n\t},\n\n\t_valueMin: function() {\n\t\treturn this.options.min;\n\t},\n\n\t_valueMax: function() {\n\t\treturn this.max;\n\t},\n\n\t_refreshValue: function() {\n\t\tvar lastValPercent, valPercent, value, valueMin, valueMax,\n\t\t\toRange = this.options.range,\n\t\t\to = this.options,\n\t\t\tthat = this,\n\t\t\tanimate = ( !this._animateOff ) ? o.animate : false,\n\t\t\t_set = {};\n\n\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\tthis.handles.each(function( i ) {\n\t\t\t\tvalPercent = ( that.values(i) - that._valueMin() ) / ( that._valueMax() - that._valueMin() ) * 100;\n\t\t\t\t_set[ that.orientation === \"horizontal\" ? \"left\" : \"bottom\" ] = valPercent + \"%\";\n\t\t\t\t$( this ).stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( _set, o.animate );\n\t\t\t\tif ( that.options.range === true ) {\n\t\t\t\t\tif ( that.orientation === \"horizontal\" ) {\n\t\t\t\t\t\tif ( i === 0 ) {\n\t\t\t\t\t\t\tthat.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { left: valPercent + \"%\" }, o.animate );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( i === 1 ) {\n\t\t\t\t\t\t\tthat.range[ animate ? \"animate\" : \"css\" ]( { width: ( valPercent - lastValPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ( i === 0 ) {\n\t\t\t\t\t\t\tthat.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { bottom: ( valPercent ) + \"%\" }, o.animate );\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( i === 1 ) {\n\t\t\t\t\t\t\tthat.range[ animate ? \"animate\" : \"css\" ]( { height: ( valPercent - lastValPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tlastValPercent = valPercent;\n\t\t\t});\n\t\t} else {\n\t\t\tvalue = this.value();\n\t\t\tvalueMin = this._valueMin();\n\t\t\tvalueMax = this._valueMax();\n\t\t\tvalPercent = ( valueMax !== valueMin ) ?\n\t\t\t\t\t( value - valueMin ) / ( valueMax - valueMin ) * 100 :\n\t\t\t\t\t0;\n\t\t\t_set[ this.orientation === \"horizontal\" ? \"left\" : \"bottom\" ] = valPercent + \"%\";\n\t\t\tthis.handle.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( _set, o.animate );\n\n\t\t\tif ( oRange === \"min\" && this.orientation === \"horizontal\" ) {\n\t\t\t\tthis.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { width: valPercent + \"%\" }, o.animate );\n\t\t\t}\n\t\t\tif ( oRange === \"max\" && this.orientation === \"horizontal\" ) {\n\t\t\t\tthis.range[ animate ? \"animate\" : \"css\" ]( { width: ( 100 - valPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t}\n\t\t\tif ( oRange === \"min\" && this.orientation === \"vertical\" ) {\n\t\t\t\tthis.range.stop( 1, 1 )[ animate ? \"animate\" : \"css\" ]( { height: valPercent + \"%\" }, o.animate );\n\t\t\t}\n\t\t\tif ( oRange === \"max\" && this.orientation === \"vertical\" ) {\n\t\t\t\tthis.range[ animate ? \"animate\" : \"css\" ]( { height: ( 100 - valPercent ) + \"%\" }, { queue: false, duration: o.animate } );\n\t\t\t}\n\t\t}\n\t},\n\n\t_handleEvents: {\n\t\tkeydown: function( event ) {\n\t\t\tvar allowed, curVal, newVal, step,\n\t\t\t\tindex = $( event.target ).data( \"ui-slider-handle-index\" );\n\n\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase $.ui.keyCode.HOME:\n\t\t\t\tcase $.ui.keyCode.END:\n\t\t\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\t\tcase $.ui.keyCode.UP:\n\t\t\t\tcase $.ui.keyCode.RIGHT:\n\t\t\t\tcase $.ui.keyCode.DOWN:\n\t\t\t\tcase $.ui.keyCode.LEFT:\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\tif ( !this._keySliding ) {\n\t\t\t\t\t\tthis._keySliding = true;\n\t\t\t\t\t\t$( event.target ).addClass( \"ui-state-active\" );\n\t\t\t\t\t\tallowed = this._start( event, index );\n\t\t\t\t\t\tif ( allowed === false ) {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tstep = this.options.step;\n\t\t\tif ( this.options.values && this.options.values.length ) {\n\t\t\t\tcurVal = newVal = this.values( index );\n\t\t\t} else {\n\t\t\t\tcurVal = newVal = this.value();\n\t\t\t}\n\n\t\t\tswitch ( event.keyCode ) {\n\t\t\t\tcase $.ui.keyCode.HOME:\n\t\t\t\t\tnewVal = this._valueMin();\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.END:\n\t\t\t\t\tnewVal = this._valueMax();\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.PAGE_UP:\n\t\t\t\t\tnewVal = this._trimAlignValue(\n\t\t\t\t\t\tcurVal + ( ( this._valueMax() - this._valueMin() ) / this.numPages )\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.PAGE_DOWN:\n\t\t\t\t\tnewVal = this._trimAlignValue(\n\t\t\t\t\t\tcurVal - ( (this._valueMax() - this._valueMin()) / this.numPages ) );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.UP:\n\t\t\t\tcase $.ui.keyCode.RIGHT:\n\t\t\t\t\tif ( curVal === this._valueMax() ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal + step );\n\t\t\t\t\tbreak;\n\t\t\t\tcase $.ui.keyCode.DOWN:\n\t\t\t\tcase $.ui.keyCode.LEFT:\n\t\t\t\t\tif ( curVal === this._valueMin() ) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\t\t\t\t\tnewVal = this._trimAlignValue( curVal - step );\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tthis._slide( event, index, newVal );\n\t\t},\n\t\tkeyup: function( event ) {\n\t\t\tvar index = $( event.target ).data( \"ui-slider-handle-index\" );\n\n\t\t\tif ( this._keySliding ) {\n\t\t\t\tthis._keySliding = false;\n\t\t\t\tthis._stop( event, index );\n\t\t\t\tthis._change( event, index );\n\t\t\t\t$( event.target ).removeClass( \"ui-state-active\" );\n\t\t\t}\n\t\t}\n\t}\n});\n\n\n/*!\n * jQuery UI Sortable 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/sortable/\n */\n\n\nvar sortable = $.widget(\"ui.sortable\", $.ui.mouse, {\n\tversion: \"1.11.4\",\n\twidgetEventPrefix: \"sort\",\n\tready: false,\n\toptions: {\n\t\tappendTo: \"parent\",\n\t\taxis: false,\n\t\tconnectWith: false,\n\t\tcontainment: false,\n\t\tcursor: \"auto\",\n\t\tcursorAt: false,\n\t\tdropOnEmpty: true,\n\t\tforcePlaceholderSize: false,\n\t\tforceHelperSize: false,\n\t\tgrid: false,\n\t\thandle: false,\n\t\thelper: \"original\",\n\t\titems: \"> *\",\n\t\topacity: false,\n\t\tplaceholder: false,\n\t\trevert: false,\n\t\tscroll: true,\n\t\tscrollSensitivity: 20,\n\t\tscrollSpeed: 20,\n\t\tscope: \"default\",\n\t\ttolerance: \"intersect\",\n\t\tzIndex: 1000,\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tbeforeStop: null,\n\t\tchange: null,\n\t\tdeactivate: null,\n\t\tout: null,\n\t\tover: null,\n\t\treceive: null,\n\t\tremove: null,\n\t\tsort: null,\n\t\tstart: null,\n\t\tstop: null,\n\t\tupdate: null\n\t},\n\n\t_isOverAxis: function( x, reference, size ) {\n\t\treturn ( x >= reference ) && ( x < ( reference + size ) );\n\t},\n\n\t_isFloating: function( item ) {\n\t\treturn (/left|right/).test(item.css(\"float\")) || (/inline|table-cell/).test(item.css(\"display\"));\n\t},\n\n\t_create: function() {\n\t\tthis.containerCache = {};\n\t\tthis.element.addClass(\"ui-sortable\");\n\n\t\t//Get the items\n\t\tthis.refresh();\n\n\t\t//Let's determine the parent's offset\n\t\tthis.offset = this.element.offset();\n\n\t\t//Initialize mouse events for interaction\n\t\tthis._mouseInit();\n\n\t\tthis._setHandleClassName();\n\n\t\t//We're ready to go\n\t\tthis.ready = true;\n\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"handle\" ) {\n\t\t\tthis._setHandleClassName();\n\t\t}\n\t},\n\n\t_setHandleClassName: function() {\n\t\tthis.element.find( \".ui-sortable-handle\" ).removeClass( \"ui-sortable-handle\" );\n\t\t$.each( this.items, function() {\n\t\t\t( this.instance.options.handle ?\n\t\t\t\tthis.item.find( this.instance.options.handle ) : this.item )\n\t\t\t\t.addClass( \"ui-sortable-handle\" );\n\t\t});\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass( \"ui-sortable ui-sortable-disabled\" )\n\t\t\t.find( \".ui-sortable-handle\" )\n\t\t\t\t.removeClass( \"ui-sortable-handle\" );\n\t\tthis._mouseDestroy();\n\n\t\tfor ( var i = this.items.length - 1; i >= 0; i-- ) {\n\t\t\tthis.items[i].item.removeData(this.widgetName + \"-item\");\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_mouseCapture: function(event, overrideHandle) {\n\t\tvar currentItem = null,\n\t\t\tvalidHandle = false,\n\t\t\tthat = this;\n\n\t\tif (this.reverting) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif(this.options.disabled || this.options.type === \"static\") {\n\t\t\treturn false;\n\t\t}\n\n\t\t//We have to refresh the items data once first\n\t\tthis._refreshItems(event);\n\n\t\t//Find out if the clicked node (or one of its parents) is a actual item in this.items\n\t\t$(event.target).parents().each(function() {\n\t\t\tif($.data(this, that.widgetName + \"-item\") === that) {\n\t\t\t\tcurrentItem = $(this);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t});\n\t\tif($.data(event.target, that.widgetName + \"-item\") === that) {\n\t\t\tcurrentItem = $(event.target);\n\t\t}\n\n\t\tif(!currentItem) {\n\t\t\treturn false;\n\t\t}\n\t\tif(this.options.handle && !overrideHandle) {\n\t\t\t$(this.options.handle, currentItem).find(\"*\").addBack().each(function() {\n\t\t\t\tif(this === event.target) {\n\t\t\t\t\tvalidHandle = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\tif(!validHandle) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\n\t\tthis.currentItem = currentItem;\n\t\tthis._removeCurrentsFromItems();\n\t\treturn true;\n\n\t},\n\n\t_mouseStart: function(event, overrideHandle, noActivation) {\n\n\t\tvar i, body,\n\t\t\to = this.options;\n\n\t\tthis.currentContainer = this;\n\n\t\t//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture\n\t\tthis.refreshPositions();\n\n\t\t//Create and append the visible helper\n\t\tthis.helper = this._createHelper(event);\n\n\t\t//Cache the helper size\n\t\tthis._cacheHelperProportions();\n\n\t\t/*\n\t\t * - Position generation -\n\t\t * This block generates everything position related - it's the core of draggables.\n\t\t */\n\n\t\t//Cache the margins of the original element\n\t\tthis._cacheMargins();\n\n\t\t//Get the next scrolling parent\n\t\tthis.scrollParent = this.helper.scrollParent();\n\n\t\t//The element's absolute position on the page minus margins\n\t\tthis.offset = this.currentItem.offset();\n\t\tthis.offset = {\n\t\t\ttop: this.offset.top - this.margins.top,\n\t\t\tleft: this.offset.left - this.margins.left\n\t\t};\n\n\t\t$.extend(this.offset, {\n\t\t\tclick: { //Where the click happened, relative to the element\n\t\t\t\tleft: event.pageX - this.offset.left,\n\t\t\t\ttop: event.pageY - this.offset.top\n\t\t\t},\n\t\t\tparent: this._getParentOffset(),\n\t\t\trelative: this._getRelativeOffset() //This is a relative to absolute position minus the actual position calculation - only used for relative positioned helper\n\t\t});\n\n\t\t// Only after we got the offset, we can change the helper's position to absolute\n\t\t// TODO: Still need to figure out a way to make relative sorting possible\n\t\tthis.helper.css(\"position\", \"absolute\");\n\t\tthis.cssPosition = this.helper.css(\"position\");\n\n\t\t//Generate the original position\n\t\tthis.originalPosition = this._generatePosition(event);\n\t\tthis.originalPageX = event.pageX;\n\t\tthis.originalPageY = event.pageY;\n\n\t\t//Adjust the mouse offset relative to the helper if \"cursorAt\" is supplied\n\t\t(o.cursorAt && this._adjustOffsetFromHelper(o.cursorAt));\n\n\t\t//Cache the former DOM position\n\t\tthis.domPosition = { prev: this.currentItem.prev()[0], parent: this.currentItem.parent()[0] };\n\n\t\t//If the helper is not the original, hide the original so it's not playing any role during the drag, won't cause anything bad this way\n\t\tif(this.helper[0] !== this.currentItem[0]) {\n\t\t\tthis.currentItem.hide();\n\t\t}\n\n\t\t//Create the placeholder\n\t\tthis._createPlaceholder();\n\n\t\t//Set a containment if given in the options\n\t\tif(o.containment) {\n\t\t\tthis._setContainment();\n\t\t}\n\n\t\tif( o.cursor && o.cursor !== \"auto\" ) { // cursor option\n\t\t\tbody = this.document.find( \"body\" );\n\n\t\t\t// support: IE\n\t\t\tthis.storedCursor = body.css( \"cursor\" );\n\t\t\tbody.css( \"cursor\", o.cursor );\n\n\t\t\tthis.storedStylesheet = $( \"<style>*{ cursor: \"+o.cursor+\" !important; }</style>\" ).appendTo( body );\n\t\t}\n\n\t\tif(o.opacity) { // opacity option\n\t\t\tif (this.helper.css(\"opacity\")) {\n\t\t\t\tthis._storedOpacity = this.helper.css(\"opacity\");\n\t\t\t}\n\t\t\tthis.helper.css(\"opacity\", o.opacity);\n\t\t}\n\n\t\tif(o.zIndex) { // zIndex option\n\t\t\tif (this.helper.css(\"zIndex\")) {\n\t\t\t\tthis._storedZIndex = this.helper.css(\"zIndex\");\n\t\t\t}\n\t\t\tthis.helper.css(\"zIndex\", o.zIndex);\n\t\t}\n\n\t\t//Prepare scrolling\n\t\tif(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== \"HTML\") {\n\t\t\tthis.overflowOffset = this.scrollParent.offset();\n\t\t}\n\n\t\t//Call callbacks\n\t\tthis._trigger(\"start\", event, this._uiHash());\n\n\t\t//Recache the helper size\n\t\tif(!this._preserveHelperProportions) {\n\t\t\tthis._cacheHelperProportions();\n\t\t}\n\n\n\t\t//Post \"activate\" events to possible containers\n\t\tif( !noActivation ) {\n\t\t\tfor ( i = this.containers.length - 1; i >= 0; i-- ) {\n\t\t\t\tthis.containers[ i ]._trigger( \"activate\", event, this._uiHash( this ) );\n\t\t\t}\n\t\t}\n\n\t\t//Prepare possible droppables\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.current = this;\n\t\t}\n\n\t\tif ($.ui.ddmanager && !o.dropBehaviour) {\n\t\t\t$.ui.ddmanager.prepareOffsets(this, event);\n\t\t}\n\n\t\tthis.dragging = true;\n\n\t\tthis.helper.addClass(\"ui-sortable-helper\");\n\t\tthis._mouseDrag(event); //Execute the drag once - this causes the helper not to be visible before getting its correct position\n\t\treturn true;\n\n\t},\n\n\t_mouseDrag: function(event) {\n\t\tvar i, item, itemElement, intersection,\n\t\t\to = this.options,\n\t\t\tscrolled = false;\n\n\t\t//Compute the helpers position\n\t\tthis.position = this._generatePosition(event);\n\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\n\t\tif (!this.lastPositionAbs) {\n\t\t\tthis.lastPositionAbs = this.positionAbs;\n\t\t}\n\n\t\t//Do scrolling\n\t\tif(this.options.scroll) {\n\t\t\tif(this.scrollParent[0] !== this.document[0] && this.scrollParent[0].tagName !== \"HTML\") {\n\n\t\t\t\tif((this.overflowOffset.top + this.scrollParent[0].offsetHeight) - event.pageY < o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop + o.scrollSpeed;\n\t\t\t\t} else if(event.pageY - this.overflowOffset.top < o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollTop = scrolled = this.scrollParent[0].scrollTop - o.scrollSpeed;\n\t\t\t\t}\n\n\t\t\t\tif((this.overflowOffset.left + this.scrollParent[0].offsetWidth) - event.pageX < o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft + o.scrollSpeed;\n\t\t\t\t} else if(event.pageX - this.overflowOffset.left < o.scrollSensitivity) {\n\t\t\t\t\tthis.scrollParent[0].scrollLeft = scrolled = this.scrollParent[0].scrollLeft - o.scrollSpeed;\n\t\t\t\t}\n\n\t\t\t} else {\n\n\t\t\t\tif(event.pageY - this.document.scrollTop() < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = this.document.scrollTop(this.document.scrollTop() - o.scrollSpeed);\n\t\t\t\t} else if(this.window.height() - (event.pageY - this.document.scrollTop()) < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = this.document.scrollTop(this.document.scrollTop() + o.scrollSpeed);\n\t\t\t\t}\n\n\t\t\t\tif(event.pageX - this.document.scrollLeft() < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = this.document.scrollLeft(this.document.scrollLeft() - o.scrollSpeed);\n\t\t\t\t} else if(this.window.width() - (event.pageX - this.document.scrollLeft()) < o.scrollSensitivity) {\n\t\t\t\t\tscrolled = this.document.scrollLeft(this.document.scrollLeft() + o.scrollSpeed);\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tif(scrolled !== false && $.ui.ddmanager && !o.dropBehaviour) {\n\t\t\t\t$.ui.ddmanager.prepareOffsets(this, event);\n\t\t\t}\n\t\t}\n\n\t\t//Regenerate the absolute position used for position checks\n\t\tthis.positionAbs = this._convertPositionTo(\"absolute\");\n\n\t\t//Set the helper position\n\t\tif(!this.options.axis || this.options.axis !== \"y\") {\n\t\t\tthis.helper[0].style.left = this.position.left+\"px\";\n\t\t}\n\t\tif(!this.options.axis || this.options.axis !== \"x\") {\n\t\t\tthis.helper[0].style.top = this.position.top+\"px\";\n\t\t}\n\n\t\t//Rearrange\n\t\tfor (i = this.items.length - 1; i >= 0; i--) {\n\n\t\t\t//Cache variables and intersection, continue if no intersection\n\t\t\titem = this.items[i];\n\t\t\titemElement = item.item[0];\n\t\t\tintersection = this._intersectsWithPointer(item);\n\t\t\tif (!intersection) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Only put the placeholder inside the current Container, skip all\n\t\t\t// items from other containers. This works because when moving\n\t\t\t// an item from one container to another the\n\t\t\t// currentContainer is switched before the placeholder is moved.\n\t\t\t//\n\t\t\t// Without this, moving items in \"sub-sortables\" can cause\n\t\t\t// the placeholder to jitter between the outer and inner container.\n\t\t\tif (item.instance !== this.currentContainer) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// cannot intersect with itself\n\t\t\t// no useless actions that have been done before\n\t\t\t// no action if the item moved is the parent of the item checked\n\t\t\tif (itemElement !== this.currentItem[0] &&\n\t\t\t\tthis.placeholder[intersection === 1 ? \"next\" : \"prev\"]()[0] !== itemElement &&\n\t\t\t\t!$.contains(this.placeholder[0], itemElement) &&\n\t\t\t\t(this.options.type === \"semi-dynamic\" ? !$.contains(this.element[0], itemElement) : true)\n\t\t\t) {\n\n\t\t\t\tthis.direction = intersection === 1 ? \"down\" : \"up\";\n\n\t\t\t\tif (this.options.tolerance === \"pointer\" || this._intersectsWithSides(item)) {\n\t\t\t\t\tthis._rearrange(event, item);\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t\tthis._trigger(\"change\", event, this._uiHash());\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t//Post events to containers\n\t\tthis._contactContainers(event);\n\n\t\t//Interconnect with droppables\n\t\tif($.ui.ddmanager) {\n\t\t\t$.ui.ddmanager.drag(this, event);\n\t\t}\n\n\t\t//Call callbacks\n\t\tthis._trigger(\"sort\", event, this._uiHash());\n\n\t\tthis.lastPositionAbs = this.positionAbs;\n\t\treturn false;\n\n\t},\n\n\t_mouseStop: function(event, noPropagation) {\n\n\t\tif(!event) {\n\t\t\treturn;\n\t\t}\n\n\t\t//If we are using droppables, inform the manager about the drop\n\t\tif ($.ui.ddmanager && !this.options.dropBehaviour) {\n\t\t\t$.ui.ddmanager.drop(this, event);\n\t\t}\n\n\t\tif(this.options.revert) {\n\t\t\tvar that = this,\n\t\t\t\tcur = this.placeholder.offset(),\n\t\t\t\taxis = this.options.axis,\n\t\t\t\tanimation = {};\n\n\t\t\tif ( !axis || axis === \"x\" ) {\n\t\t\t\tanimation.left = cur.left - this.offset.parent.left - this.margins.left + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollLeft);\n\t\t\t}\n\t\t\tif ( !axis || axis === \"y\" ) {\n\t\t\t\tanimation.top = cur.top - this.offset.parent.top - this.margins.top + (this.offsetParent[0] === this.document[0].body ? 0 : this.offsetParent[0].scrollTop);\n\t\t\t}\n\t\t\tthis.reverting = true;\n\t\t\t$(this.helper).animate( animation, parseInt(this.options.revert, 10) || 500, function() {\n\t\t\t\tthat._clear(event);\n\t\t\t});\n\t\t} else {\n\t\t\tthis._clear(event, noPropagation);\n\t\t}\n\n\t\treturn false;\n\n\t},\n\n\tcancel: function() {\n\n\t\tif(this.dragging) {\n\n\t\t\tthis._mouseUp({ target: null });\n\n\t\t\tif(this.options.helper === \"original\") {\n\t\t\t\tthis.currentItem.css(this._storedCSS).removeClass(\"ui-sortable-helper\");\n\t\t\t} else {\n\t\t\t\tthis.currentItem.show();\n\t\t\t}\n\n\t\t\t//Post deactivating events to containers\n\t\t\tfor (var i = this.containers.length - 1; i >= 0; i--){\n\t\t\t\tthis.containers[i]._trigger(\"deactivate\", null, this._uiHash(this));\n\t\t\t\tif(this.containers[i].containerCache.over) {\n\t\t\t\t\tthis.containers[i]._trigger(\"out\", null, this._uiHash(this));\n\t\t\t\t\tthis.containers[i].containerCache.over = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\tif (this.placeholder) {\n\t\t\t//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!\n\t\t\tif(this.placeholder[0].parentNode) {\n\t\t\t\tthis.placeholder[0].parentNode.removeChild(this.placeholder[0]);\n\t\t\t}\n\t\t\tif(this.options.helper !== \"original\" && this.helper && this.helper[0].parentNode) {\n\t\t\t\tthis.helper.remove();\n\t\t\t}\n\n\t\t\t$.extend(this, {\n\t\t\t\thelper: null,\n\t\t\t\tdragging: false,\n\t\t\t\treverting: false,\n\t\t\t\t_noFinalSort: null\n\t\t\t});\n\n\t\t\tif(this.domPosition.prev) {\n\t\t\t\t$(this.domPosition.prev).after(this.currentItem);\n\t\t\t} else {\n\t\t\t\t$(this.domPosition.parent).prepend(this.currentItem);\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\n\t},\n\n\tserialize: function(o) {\n\n\t\tvar items = this._getItemsAsjQuery(o && o.connected),\n\t\t\tstr = [];\n\t\to = o || {};\n\n\t\t$(items).each(function() {\n\t\t\tvar res = ($(o.item || this).attr(o.attribute || \"id\") || \"\").match(o.expression || (/(.+)[\\-=_](.+)/));\n\t\t\tif (res) {\n\t\t\t\tstr.push((o.key || res[1]+\"[]\")+\"=\"+(o.key && o.expression ? res[1] : res[2]));\n\t\t\t}\n\t\t});\n\n\t\tif(!str.length && o.key) {\n\t\t\tstr.push(o.key + \"=\");\n\t\t}\n\n\t\treturn str.join(\"&\");\n\n\t},\n\n\ttoArray: function(o) {\n\n\t\tvar items = this._getItemsAsjQuery(o && o.connected),\n\t\t\tret = [];\n\n\t\to = o || {};\n\n\t\titems.each(function() { ret.push($(o.item || this).attr(o.attribute || \"id\") || \"\"); });\n\t\treturn ret;\n\n\t},\n\n\t/* Be careful with the following core functions */\n\t_intersectsWith: function(item) {\n\n\t\tvar x1 = this.positionAbs.left,\n\t\t\tx2 = x1 + this.helperProportions.width,\n\t\t\ty1 = this.positionAbs.top,\n\t\t\ty2 = y1 + this.helperProportions.height,\n\t\t\tl = item.left,\n\t\t\tr = l + item.width,\n\t\t\tt = item.top,\n\t\t\tb = t + item.height,\n\t\t\tdyClick = this.offset.click.top,\n\t\t\tdxClick = this.offset.click.left,\n\t\t\tisOverElementHeight = ( this.options.axis === \"x\" ) || ( ( y1 + dyClick ) > t && ( y1 + dyClick ) < b ),\n\t\t\tisOverElementWidth = ( this.options.axis === \"y\" ) || ( ( x1 + dxClick ) > l && ( x1 + dxClick ) < r ),\n\t\t\tisOverElement = isOverElementHeight && isOverElementWidth;\n\n\t\tif ( this.options.tolerance === \"pointer\" ||\n\t\t\tthis.options.forcePointerForContainers ||\n\t\t\t(this.options.tolerance !== \"pointer\" && this.helperProportions[this.floating ? \"width\" : \"height\"] > item[this.floating ? \"width\" : \"height\"])\n\t\t) {\n\t\t\treturn isOverElement;\n\t\t} else {\n\n\t\t\treturn (l < x1 + (this.helperProportions.width / 2) && // Right Half\n\t\t\t\tx2 - (this.helperProportions.width / 2) < r && // Left Half\n\t\t\t\tt < y1 + (this.helperProportions.height / 2) && // Bottom Half\n\t\t\t\ty2 - (this.helperProportions.height / 2) < b ); // Top Half\n\n\t\t}\n\t},\n\n\t_intersectsWithPointer: function(item) {\n\n\t\tvar isOverElementHeight = (this.options.axis === \"x\") || this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top, item.height),\n\t\t\tisOverElementWidth = (this.options.axis === \"y\") || this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left, item.width),\n\t\t\tisOverElement = isOverElementHeight && isOverElementWidth,\n\t\t\tverticalDirection = this._getDragVerticalDirection(),\n\t\t\thorizontalDirection = this._getDragHorizontalDirection();\n\n\t\tif (!isOverElement) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn this.floating ?\n\t\t\t( ((horizontalDirection && horizontalDirection === \"right\") || verticalDirection === \"down\") ? 2 : 1 )\n\t\t\t: ( verticalDirection && (verticalDirection === \"down\" ? 2 : 1) );\n\n\t},\n\n\t_intersectsWithSides: function(item) {\n\n\t\tvar isOverBottomHalf = this._isOverAxis(this.positionAbs.top + this.offset.click.top, item.top + (item.height/2), item.height),\n\t\t\tisOverRightHalf = this._isOverAxis(this.positionAbs.left + this.offset.click.left, item.left + (item.width/2), item.width),\n\t\t\tverticalDirection = this._getDragVerticalDirection(),\n\t\t\thorizontalDirection = this._getDragHorizontalDirection();\n\n\t\tif (this.floating && horizontalDirection) {\n\t\t\treturn ((horizontalDirection === \"right\" && isOverRightHalf) || (horizontalDirection === \"left\" && !isOverRightHalf));\n\t\t} else {\n\t\t\treturn verticalDirection && ((verticalDirection === \"down\" && isOverBottomHalf) || (verticalDirection === \"up\" && !isOverBottomHalf));\n\t\t}\n\n\t},\n\n\t_getDragVerticalDirection: function() {\n\t\tvar delta = this.positionAbs.top - this.lastPositionAbs.top;\n\t\treturn delta !== 0 && (delta > 0 ? \"down\" : \"up\");\n\t},\n\n\t_getDragHorizontalDirection: function() {\n\t\tvar delta = this.positionAbs.left - this.lastPositionAbs.left;\n\t\treturn delta !== 0 && (delta > 0 ? \"right\" : \"left\");\n\t},\n\n\trefresh: function(event) {\n\t\tthis._refreshItems(event);\n\t\tthis._setHandleClassName();\n\t\tthis.refreshPositions();\n\t\treturn this;\n\t},\n\n\t_connectWith: function() {\n\t\tvar options = this.options;\n\t\treturn options.connectWith.constructor === String ? [options.connectWith] : options.connectWith;\n\t},\n\n\t_getItemsAsjQuery: function(connected) {\n\n\t\tvar i, j, cur, inst,\n\t\t\titems = [],\n\t\t\tqueries = [],\n\t\t\tconnectWith = this._connectWith();\n\n\t\tif(connectWith && connected) {\n\t\t\tfor (i = connectWith.length - 1; i >= 0; i--){\n\t\t\t\tcur = $(connectWith[i], this.document[0]);\n\t\t\t\tfor ( j = cur.length - 1; j >= 0; j--){\n\t\t\t\t\tinst = $.data(cur[j], this.widgetFullName);\n\t\t\t\t\tif(inst && inst !== this && !inst.options.disabled) {\n\t\t\t\t\t\tqueries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element) : $(inst.options.items, inst.element).not(\".ui-sortable-helper\").not(\".ui-sortable-placeholder\"), inst]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tqueries.push([$.isFunction(this.options.items) ? this.options.items.call(this.element, null, { options: this.options, item: this.currentItem }) : $(this.options.items, this.element).not(\".ui-sortable-helper\").not(\".ui-sortable-placeholder\"), this]);\n\n\t\tfunction addItems() {\n\t\t\titems.push( this );\n\t\t}\n\t\tfor (i = queries.length - 1; i >= 0; i--){\n\t\t\tqueries[i][0].each( addItems );\n\t\t}\n\n\t\treturn $(items);\n\n\t},\n\n\t_removeCurrentsFromItems: function() {\n\n\t\tvar list = this.currentItem.find(\":data(\" + this.widgetName + \"-item)\");\n\n\t\tthis.items = $.grep(this.items, function (item) {\n\t\t\tfor (var j=0; j < list.length; j++) {\n\t\t\t\tif(list[j] === item.item[0]) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t});\n\n\t},\n\n\t_refreshItems: function(event) {\n\n\t\tthis.items = [];\n\t\tthis.containers = [this];\n\n\t\tvar i, j, cur, inst, targetData, _queries, item, queriesLength,\n\t\t\titems = this.items,\n\t\t\tqueries = [[$.isFunction(this.options.items) ? this.options.items.call(this.element[0], event, { item: this.currentItem }) : $(this.options.items, this.element), this]],\n\t\t\tconnectWith = this._connectWith();\n\n\t\tif(connectWith && this.ready) { //Shouldn't be run the first time through due to massive slow-down\n\t\t\tfor (i = connectWith.length - 1; i >= 0; i--){\n\t\t\t\tcur = $(connectWith[i], this.document[0]);\n\t\t\t\tfor (j = cur.length - 1; j >= 0; j--){\n\t\t\t\t\tinst = $.data(cur[j], this.widgetFullName);\n\t\t\t\t\tif(inst && inst !== this && !inst.options.disabled) {\n\t\t\t\t\t\tqueries.push([$.isFunction(inst.options.items) ? inst.options.items.call(inst.element[0], event, { item: this.currentItem }) : $(inst.options.items, inst.element), inst]);\n\t\t\t\t\t\tthis.containers.push(inst);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tfor (i = queries.length - 1; i >= 0; i--) {\n\t\t\ttargetData = queries[i][1];\n\t\t\t_queries = queries[i][0];\n\n\t\t\tfor (j=0, queriesLength = _queries.length; j < queriesLength; j++) {\n\t\t\t\titem = $(_queries[j]);\n\n\t\t\t\titem.data(this.widgetName + \"-item\", targetData); // Data for target checking (mouse manager)\n\n\t\t\t\titems.push({\n\t\t\t\t\titem: item,\n\t\t\t\t\tinstance: targetData,\n\t\t\t\t\twidth: 0, height: 0,\n\t\t\t\t\tleft: 0, top: 0\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t},\n\n\trefreshPositions: function(fast) {\n\n\t\t// Determine whether items are being displayed horizontally\n\t\tthis.floating = this.items.length ?\n\t\t\tthis.options.axis === \"x\" || this._isFloating( this.items[ 0 ].item ) :\n\t\t\tfalse;\n\n\t\t//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change\n\t\tif(this.offsetParent && this.helper) {\n\t\t\tthis.offset.parent = this._getParentOffset();\n\t\t}\n\n\t\tvar i, item, t, p;\n\n\t\tfor (i = this.items.length - 1; i >= 0; i--){\n\t\t\titem = this.items[i];\n\n\t\t\t//We ignore calculating positions of all connected containers when we're not over them\n\t\t\tif(item.instance !== this.currentContainer && this.currentContainer && item.item[0] !== this.currentItem[0]) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tt = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;\n\n\t\t\tif (!fast) {\n\t\t\t\titem.width = t.outerWidth();\n\t\t\t\titem.height = t.outerHeight();\n\t\t\t}\n\n\t\t\tp = t.offset();\n\t\t\titem.left = p.left;\n\t\t\titem.top = p.top;\n\t\t}\n\n\t\tif(this.options.custom && this.options.custom.refreshContainers) {\n\t\t\tthis.options.custom.refreshContainers.call(this);\n\t\t} else {\n\t\t\tfor (i = this.containers.length - 1; i >= 0; i--){\n\t\t\t\tp = this.containers[i].element.offset();\n\t\t\t\tthis.containers[i].containerCache.left = p.left;\n\t\t\t\tthis.containers[i].containerCache.top = p.top;\n\t\t\t\tthis.containers[i].containerCache.width = this.containers[i].element.outerWidth();\n\t\t\t\tthis.containers[i].containerCache.height = this.containers[i].element.outerHeight();\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\t_createPlaceholder: function(that) {\n\t\tthat = that || this;\n\t\tvar className,\n\t\t\to = that.options;\n\n\t\tif(!o.placeholder || o.placeholder.constructor === String) {\n\t\t\tclassName = o.placeholder;\n\t\t\to.placeholder = {\n\t\t\t\telement: function() {\n\n\t\t\t\t\tvar nodeName = that.currentItem[0].nodeName.toLowerCase(),\n\t\t\t\t\t\telement = $( \"<\" + nodeName + \">\", that.document[0] )\n\t\t\t\t\t\t\t.addClass(className || that.currentItem[0].className+\" ui-sortable-placeholder\")\n\t\t\t\t\t\t\t.removeClass(\"ui-sortable-helper\");\n\n\t\t\t\t\tif ( nodeName === \"tbody\" ) {\n\t\t\t\t\t\tthat._createTrPlaceholder(\n\t\t\t\t\t\t\tthat.currentItem.find( \"tr\" ).eq( 0 ),\n\t\t\t\t\t\t\t$( \"<tr>\", that.document[ 0 ] ).appendTo( element )\n\t\t\t\t\t\t);\n\t\t\t\t\t} else if ( nodeName === \"tr\" ) {\n\t\t\t\t\t\tthat._createTrPlaceholder( that.currentItem, element );\n\t\t\t\t\t} else if ( nodeName === \"img\" ) {\n\t\t\t\t\t\telement.attr( \"src\", that.currentItem.attr( \"src\" ) );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ( !className ) {\n\t\t\t\t\t\telement.css( \"visibility\", \"hidden\" );\n\t\t\t\t\t}\n\n\t\t\t\t\treturn element;\n\t\t\t\t},\n\t\t\t\tupdate: function(container, p) {\n\n\t\t\t\t\t// 1. If a className is set as 'placeholder option, we don't force sizes - the class is responsible for that\n\t\t\t\t\t// 2. The option 'forcePlaceholderSize can be enabled to force it even if a class name is specified\n\t\t\t\t\tif(className && !o.forcePlaceholderSize) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t//If the element doesn't have a actual height by itself (without styles coming from a stylesheet), it receives the inline height from the dragged item\n\t\t\t\t\tif(!p.height()) { p.height(that.currentItem.innerHeight() - parseInt(that.currentItem.css(\"paddingTop\")||0, 10) - parseInt(that.currentItem.css(\"paddingBottom\")||0, 10)); }\n\t\t\t\t\tif(!p.width()) { p.width(that.currentItem.innerWidth() - parseInt(that.currentItem.css(\"paddingLeft\")||0, 10) - parseInt(that.currentItem.css(\"paddingRight\")||0, 10)); }\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\t//Create the placeholder\n\t\tthat.placeholder = $(o.placeholder.element.call(that.element, that.currentItem));\n\n\t\t//Append it after the actual current item\n\t\tthat.currentItem.after(that.placeholder);\n\n\t\t//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)\n\t\to.placeholder.update(that, that.placeholder);\n\n\t},\n\n\t_createTrPlaceholder: function( sourceTr, targetTr ) {\n\t\tvar that = this;\n\n\t\tsourceTr.children().each(function() {\n\t\t\t$( \"<td>&#160;</td>\", that.document[ 0 ] )\n\t\t\t\t.attr( \"colspan\", $( this ).attr( \"colspan\" ) || 1 )\n\t\t\t\t.appendTo( targetTr );\n\t\t});\n\t},\n\n\t_contactContainers: function(event) {\n\t\tvar i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom, floating, axis,\n\t\t\tinnermostContainer = null,\n\t\t\tinnermostIndex = null;\n\n\t\t// get innermost container that intersects with item\n\t\tfor (i = this.containers.length - 1; i >= 0; i--) {\n\n\t\t\t// never consider a container that's located within the item itself\n\t\t\tif($.contains(this.currentItem[0], this.containers[i].element[0])) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif(this._intersectsWith(this.containers[i].containerCache)) {\n\n\t\t\t\t// if we've already found a container and it's more \"inner\" than this, then continue\n\t\t\t\tif(innermostContainer && $.contains(this.containers[i].element[0], innermostContainer.element[0])) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tinnermostContainer = this.containers[i];\n\t\t\t\tinnermostIndex = i;\n\n\t\t\t} else {\n\t\t\t\t// container doesn't intersect. trigger \"out\" event if necessary\n\t\t\t\tif(this.containers[i].containerCache.over) {\n\t\t\t\t\tthis.containers[i]._trigger(\"out\", event, this._uiHash(this));\n\t\t\t\t\tthis.containers[i].containerCache.over = 0;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\n\t\t// if no intersecting containers found, return\n\t\tif(!innermostContainer) {\n\t\t\treturn;\n\t\t}\n\n\t\t// move the item into the container if it's not there already\n\t\tif(this.containers.length === 1) {\n\t\t\tif (!this.containers[innermostIndex].containerCache.over) {\n\t\t\t\tthis.containers[innermostIndex]._trigger(\"over\", event, this._uiHash(this));\n\t\t\t\tthis.containers[innermostIndex].containerCache.over = 1;\n\t\t\t}\n\t\t} else {\n\n\t\t\t//When entering a new container, we will find the item with the least distance and append our item near it\n\t\t\tdist = 10000;\n\t\t\titemWithLeastDistance = null;\n\t\t\tfloating = innermostContainer.floating || this._isFloating(this.currentItem);\n\t\t\tposProperty = floating ? \"left\" : \"top\";\n\t\t\tsizeProperty = floating ? \"width\" : \"height\";\n\t\t\taxis = floating ? \"clientX\" : \"clientY\";\n\n\t\t\tfor (j = this.items.length - 1; j >= 0; j--) {\n\t\t\t\tif(!$.contains(this.containers[innermostIndex].element[0], this.items[j].item[0])) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif(this.items[j].item[0] === this.currentItem[0]) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\tcur = this.items[j].item.offset()[posProperty];\n\t\t\t\tnearBottom = false;\n\t\t\t\tif ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {\n\t\t\t\t\tnearBottom = true;\n\t\t\t\t}\n\n\t\t\t\tif ( Math.abs( event[ axis ] - cur ) < dist ) {\n\t\t\t\t\tdist = Math.abs( event[ axis ] - cur );\n\t\t\t\t\titemWithLeastDistance = this.items[ j ];\n\t\t\t\t\tthis.direction = nearBottom ? \"up\": \"down\";\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//Check if dropOnEmpty is enabled\n\t\t\tif(!itemWithLeastDistance && !this.options.dropOnEmpty) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif(this.currentContainer === this.containers[innermostIndex]) {\n\t\t\t\tif ( !this.currentContainer.containerCache.over ) {\n\t\t\t\t\tthis.containers[ innermostIndex ]._trigger( \"over\", event, this._uiHash() );\n\t\t\t\t\tthis.currentContainer.containerCache.over = 1;\n\t\t\t\t}\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\titemWithLeastDistance ? this._rearrange(event, itemWithLeastDistance, null, true) : this._rearrange(event, null, this.containers[innermostIndex].element, true);\n\t\t\tthis._trigger(\"change\", event, this._uiHash());\n\t\t\tthis.containers[innermostIndex]._trigger(\"change\", event, this._uiHash(this));\n\t\t\tthis.currentContainer = this.containers[innermostIndex];\n\n\t\t\t//Update the placeholder\n\t\t\tthis.options.placeholder.update(this.currentContainer, this.placeholder);\n\n\t\t\tthis.containers[innermostIndex]._trigger(\"over\", event, this._uiHash(this));\n\t\t\tthis.containers[innermostIndex].containerCache.over = 1;\n\t\t}\n\n\n\t},\n\n\t_createHelper: function(event) {\n\n\t\tvar o = this.options,\n\t\t\thelper = $.isFunction(o.helper) ? $(o.helper.apply(this.element[0], [event, this.currentItem])) : (o.helper === \"clone\" ? this.currentItem.clone() : this.currentItem);\n\n\t\t//Add the helper to the DOM if that didn't happen already\n\t\tif(!helper.parents(\"body\").length) {\n\t\t\t$(o.appendTo !== \"parent\" ? o.appendTo : this.currentItem[0].parentNode)[0].appendChild(helper[0]);\n\t\t}\n\n\t\tif(helper[0] === this.currentItem[0]) {\n\t\t\tthis._storedCSS = { width: this.currentItem[0].style.width, height: this.currentItem[0].style.height, position: this.currentItem.css(\"position\"), top: this.currentItem.css(\"top\"), left: this.currentItem.css(\"left\") };\n\t\t}\n\n\t\tif(!helper[0].style.width || o.forceHelperSize) {\n\t\t\thelper.width(this.currentItem.width());\n\t\t}\n\t\tif(!helper[0].style.height || o.forceHelperSize) {\n\t\t\thelper.height(this.currentItem.height());\n\t\t}\n\n\t\treturn helper;\n\n\t},\n\n\t_adjustOffsetFromHelper: function(obj) {\n\t\tif (typeof obj === \"string\") {\n\t\t\tobj = obj.split(\" \");\n\t\t}\n\t\tif ($.isArray(obj)) {\n\t\t\tobj = {left: +obj[0], top: +obj[1] || 0};\n\t\t}\n\t\tif (\"left\" in obj) {\n\t\t\tthis.offset.click.left = obj.left + this.margins.left;\n\t\t}\n\t\tif (\"right\" in obj) {\n\t\t\tthis.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;\n\t\t}\n\t\tif (\"top\" in obj) {\n\t\t\tthis.offset.click.top = obj.top + this.margins.top;\n\t\t}\n\t\tif (\"bottom\" in obj) {\n\t\t\tthis.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;\n\t\t}\n\t},\n\n\t_getParentOffset: function() {\n\n\n\t\t//Get the offsetParent and cache its position\n\t\tthis.offsetParent = this.helper.offsetParent();\n\t\tvar po = this.offsetParent.offset();\n\n\t\t// This is a special case where we need to modify a offset calculated on start, since the following happened:\n\t\t// 1. The position of the helper is absolute, so it's position is calculated based on the next positioned parent\n\t\t// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't the document, which means that\n\t\t//    the scroll is included in the initial calculation of the offset of the parent, and never recalculated upon drag\n\t\tif(this.cssPosition === \"absolute\" && this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) {\n\t\t\tpo.left += this.scrollParent.scrollLeft();\n\t\t\tpo.top += this.scrollParent.scrollTop();\n\t\t}\n\n\t\t// This needs to be actually done for all browsers, since pageX/pageY includes this information\n\t\t// with an ugly IE fix\n\t\tif( this.offsetParent[0] === this.document[0].body || (this.offsetParent[0].tagName && this.offsetParent[0].tagName.toLowerCase() === \"html\" && $.ui.ie)) {\n\t\t\tpo = { top: 0, left: 0 };\n\t\t}\n\n\t\treturn {\n\t\t\ttop: po.top + (parseInt(this.offsetParent.css(\"borderTopWidth\"),10) || 0),\n\t\t\tleft: po.left + (parseInt(this.offsetParent.css(\"borderLeftWidth\"),10) || 0)\n\t\t};\n\n\t},\n\n\t_getRelativeOffset: function() {\n\n\t\tif(this.cssPosition === \"relative\") {\n\t\t\tvar p = this.currentItem.position();\n\t\t\treturn {\n\t\t\t\ttop: p.top - (parseInt(this.helper.css(\"top\"),10) || 0) + this.scrollParent.scrollTop(),\n\t\t\t\tleft: p.left - (parseInt(this.helper.css(\"left\"),10) || 0) + this.scrollParent.scrollLeft()\n\t\t\t};\n\t\t} else {\n\t\t\treturn { top: 0, left: 0 };\n\t\t}\n\n\t},\n\n\t_cacheMargins: function() {\n\t\tthis.margins = {\n\t\t\tleft: (parseInt(this.currentItem.css(\"marginLeft\"),10) || 0),\n\t\t\ttop: (parseInt(this.currentItem.css(\"marginTop\"),10) || 0)\n\t\t};\n\t},\n\n\t_cacheHelperProportions: function() {\n\t\tthis.helperProportions = {\n\t\t\twidth: this.helper.outerWidth(),\n\t\t\theight: this.helper.outerHeight()\n\t\t};\n\t},\n\n\t_setContainment: function() {\n\n\t\tvar ce, co, over,\n\t\t\to = this.options;\n\t\tif(o.containment === \"parent\") {\n\t\t\to.containment = this.helper[0].parentNode;\n\t\t}\n\t\tif(o.containment === \"document\" || o.containment === \"window\") {\n\t\t\tthis.containment = [\n\t\t\t\t0 - this.offset.relative.left - this.offset.parent.left,\n\t\t\t\t0 - this.offset.relative.top - this.offset.parent.top,\n\t\t\t\to.containment === \"document\" ? this.document.width() : this.window.width() - this.helperProportions.width - this.margins.left,\n\t\t\t\t(o.containment === \"document\" ? this.document.width() : this.window.height() || this.document[0].body.parentNode.scrollHeight) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t}\n\n\t\tif(!(/^(document|window|parent)$/).test(o.containment)) {\n\t\t\tce = $(o.containment)[0];\n\t\t\tco = $(o.containment).offset();\n\t\t\tover = ($(ce).css(\"overflow\") !== \"hidden\");\n\n\t\t\tthis.containment = [\n\t\t\t\tco.left + (parseInt($(ce).css(\"borderLeftWidth\"),10) || 0) + (parseInt($(ce).css(\"paddingLeft\"),10) || 0) - this.margins.left,\n\t\t\t\tco.top + (parseInt($(ce).css(\"borderTopWidth\"),10) || 0) + (parseInt($(ce).css(\"paddingTop\"),10) || 0) - this.margins.top,\n\t\t\t\tco.left+(over ? Math.max(ce.scrollWidth,ce.offsetWidth) : ce.offsetWidth) - (parseInt($(ce).css(\"borderLeftWidth\"),10) || 0) - (parseInt($(ce).css(\"paddingRight\"),10) || 0) - this.helperProportions.width - this.margins.left,\n\t\t\t\tco.top+(over ? Math.max(ce.scrollHeight,ce.offsetHeight) : ce.offsetHeight) - (parseInt($(ce).css(\"borderTopWidth\"),10) || 0) - (parseInt($(ce).css(\"paddingBottom\"),10) || 0) - this.helperProportions.height - this.margins.top\n\t\t\t];\n\t\t}\n\n\t},\n\n\t_convertPositionTo: function(d, pos) {\n\n\t\tif(!pos) {\n\t\t\tpos = this.position;\n\t\t}\n\t\tvar mod = d === \"absolute\" ? 1 : -1,\n\t\t\tscroll = this.cssPosition === \"absolute\" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent,\n\t\t\tscrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpos.top\t+\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.top * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top * mod -\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod)\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpos.left +\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.relative.left * mod +\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left * mod\t-\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ) * mod)\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_generatePosition: function(event) {\n\n\t\tvar top, left,\n\t\t\to = this.options,\n\t\t\tpageX = event.pageX,\n\t\t\tpageY = event.pageY,\n\t\t\tscroll = this.cssPosition === \"absolute\" && !(this.scrollParent[0] !== this.document[0] && $.contains(this.scrollParent[0], this.offsetParent[0])) ? this.offsetParent : this.scrollParent, scrollIsRootNode = (/(html|body)/i).test(scroll[0].tagName);\n\n\t\t// This is another very weird special case that only happens for relative elements:\n\t\t// 1. If the css position is relative\n\t\t// 2. and the scroll parent is the document or similar to the offset parent\n\t\t// we have to refresh the relative offset during the scroll so there are no jumps\n\t\tif(this.cssPosition === \"relative\" && !(this.scrollParent[0] !== this.document[0] && this.scrollParent[0] !== this.offsetParent[0])) {\n\t\t\tthis.offset.relative = this._getRelativeOffset();\n\t\t}\n\n\t\t/*\n\t\t * - Position constraining -\n\t\t * Constrain the position to a mix of grid, containment.\n\t\t */\n\n\t\tif(this.originalPosition) { //If we are not dragging yet, we won't check for options\n\n\t\t\tif(this.containment) {\n\t\t\t\tif(event.pageX - this.offset.click.left < this.containment[0]) {\n\t\t\t\t\tpageX = this.containment[0] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top < this.containment[1]) {\n\t\t\t\t\tpageY = this.containment[1] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t\tif(event.pageX - this.offset.click.left > this.containment[2]) {\n\t\t\t\t\tpageX = this.containment[2] + this.offset.click.left;\n\t\t\t\t}\n\t\t\t\tif(event.pageY - this.offset.click.top > this.containment[3]) {\n\t\t\t\t\tpageY = this.containment[3] + this.offset.click.top;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(o.grid) {\n\t\t\t\ttop = this.originalPageY + Math.round((pageY - this.originalPageY) / o.grid[1]) * o.grid[1];\n\t\t\t\tpageY = this.containment ? ( (top - this.offset.click.top >= this.containment[1] && top - this.offset.click.top <= this.containment[3]) ? top : ((top - this.offset.click.top >= this.containment[1]) ? top - o.grid[1] : top + o.grid[1])) : top;\n\n\t\t\t\tleft = this.originalPageX + Math.round((pageX - this.originalPageX) / o.grid[0]) * o.grid[0];\n\t\t\t\tpageX = this.containment ? ( (left - this.offset.click.left >= this.containment[0] && left - this.offset.click.left <= this.containment[2]) ? left : ((left - this.offset.click.left >= this.containment[0]) ? left - o.grid[0] : left + o.grid[0])) : left;\n\t\t\t}\n\n\t\t}\n\n\t\treturn {\n\t\t\ttop: (\n\t\t\t\tpageY -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.top -\t\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.top\t-\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.top +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollTop() : ( scrollIsRootNode ? 0 : scroll.scrollTop() ) ))\n\t\t\t),\n\t\t\tleft: (\n\t\t\t\tpageX -\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// The absolute mouse position\n\t\t\t\tthis.offset.click.left -\t\t\t\t\t\t\t\t\t\t\t\t// Click offset (relative to the element)\n\t\t\t\tthis.offset.relative.left\t-\t\t\t\t\t\t\t\t\t\t\t// Only for relative positioned nodes: Relative offset from element to offset parent\n\t\t\t\tthis.offset.parent.left +\t\t\t\t\t\t\t\t\t\t\t\t// The offsetParent's offset without borders (offset + border)\n\t\t\t\t( ( this.cssPosition === \"fixed\" ? -this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 : scroll.scrollLeft() ))\n\t\t\t)\n\t\t};\n\n\t},\n\n\t_rearrange: function(event, i, a, hardRefresh) {\n\n\t\ta ? a[0].appendChild(this.placeholder[0]) : i.item[0].parentNode.insertBefore(this.placeholder[0], (this.direction === \"down\" ? i.item[0] : i.item[0].nextSibling));\n\n\t\t//Various things done here to improve the performance:\n\t\t// 1. we create a setTimeout, that calls refreshPositions\n\t\t// 2. on the instance, we have a counter variable, that get's higher after every append\n\t\t// 3. on the local scope, we copy the counter variable, and check in the timeout, if it's still the same\n\t\t// 4. this lets only the last addition to the timeout stack through\n\t\tthis.counter = this.counter ? ++this.counter : 1;\n\t\tvar counter = this.counter;\n\n\t\tthis._delay(function() {\n\t\t\tif(counter === this.counter) {\n\t\t\t\tthis.refreshPositions(!hardRefresh); //Precompute after each DOM insertion, NOT on mousemove\n\t\t\t}\n\t\t});\n\n\t},\n\n\t_clear: function(event, noPropagation) {\n\n\t\tthis.reverting = false;\n\t\t// We delay all events that have to be triggered to after the point where the placeholder has been removed and\n\t\t// everything else normalized again\n\t\tvar i,\n\t\t\tdelayedTriggers = [];\n\n\t\t// We first have to update the dom position of the actual currentItem\n\t\t// Note: don't do it if the current item is already removed (by a user), or it gets reappended (see #4088)\n\t\tif(!this._noFinalSort && this.currentItem.parent().length) {\n\t\t\tthis.placeholder.before(this.currentItem);\n\t\t}\n\t\tthis._noFinalSort = null;\n\n\t\tif(this.helper[0] === this.currentItem[0]) {\n\t\t\tfor(i in this._storedCSS) {\n\t\t\t\tif(this._storedCSS[i] === \"auto\" || this._storedCSS[i] === \"static\") {\n\t\t\t\t\tthis._storedCSS[i] = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.currentItem.css(this._storedCSS).removeClass(\"ui-sortable-helper\");\n\t\t} else {\n\t\t\tthis.currentItem.show();\n\t\t}\n\n\t\tif(this.fromOutside && !noPropagation) {\n\t\t\tdelayedTriggers.push(function(event) { this._trigger(\"receive\", event, this._uiHash(this.fromOutside)); });\n\t\t}\n\t\tif((this.fromOutside || this.domPosition.prev !== this.currentItem.prev().not(\".ui-sortable-helper\")[0] || this.domPosition.parent !== this.currentItem.parent()[0]) && !noPropagation) {\n\t\t\tdelayedTriggers.push(function(event) { this._trigger(\"update\", event, this._uiHash()); }); //Trigger update callback if the DOM position has changed\n\t\t}\n\n\t\t// Check if the items Container has Changed and trigger appropriate\n\t\t// events.\n\t\tif (this !== this.currentContainer) {\n\t\t\tif(!noPropagation) {\n\t\t\t\tdelayedTriggers.push(function(event) { this._trigger(\"remove\", event, this._uiHash()); });\n\t\t\t\tdelayedTriggers.push((function(c) { return function(event) { c._trigger(\"receive\", event, this._uiHash(this)); };  }).call(this, this.currentContainer));\n\t\t\t\tdelayedTriggers.push((function(c) { return function(event) { c._trigger(\"update\", event, this._uiHash(this));  }; }).call(this, this.currentContainer));\n\t\t\t}\n\t\t}\n\n\n\t\t//Post events to containers\n\t\tfunction delayEvent( type, instance, container ) {\n\t\t\treturn function( event ) {\n\t\t\t\tcontainer._trigger( type, event, instance._uiHash( instance ) );\n\t\t\t};\n\t\t}\n\t\tfor (i = this.containers.length - 1; i >= 0; i--){\n\t\t\tif (!noPropagation) {\n\t\t\t\tdelayedTriggers.push( delayEvent( \"deactivate\", this, this.containers[ i ] ) );\n\t\t\t}\n\t\t\tif(this.containers[i].containerCache.over) {\n\t\t\t\tdelayedTriggers.push( delayEvent( \"out\", this, this.containers[ i ] ) );\n\t\t\t\tthis.containers[i].containerCache.over = 0;\n\t\t\t}\n\t\t}\n\n\t\t//Do what was originally in plugins\n\t\tif ( this.storedCursor ) {\n\t\t\tthis.document.find( \"body\" ).css( \"cursor\", this.storedCursor );\n\t\t\tthis.storedStylesheet.remove();\n\t\t}\n\t\tif(this._storedOpacity) {\n\t\t\tthis.helper.css(\"opacity\", this._storedOpacity);\n\t\t}\n\t\tif(this._storedZIndex) {\n\t\t\tthis.helper.css(\"zIndex\", this._storedZIndex === \"auto\" ? \"\" : this._storedZIndex);\n\t\t}\n\n\t\tthis.dragging = false;\n\n\t\tif(!noPropagation) {\n\t\t\tthis._trigger(\"beforeStop\", event, this._uiHash());\n\t\t}\n\n\t\t//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately, it unbinds ALL events from the original node!\n\t\tthis.placeholder[0].parentNode.removeChild(this.placeholder[0]);\n\n\t\tif ( !this.cancelHelperRemoval ) {\n\t\t\tif ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {\n\t\t\t\tthis.helper.remove();\n\t\t\t}\n\t\t\tthis.helper = null;\n\t\t}\n\n\t\tif(!noPropagation) {\n\t\t\tfor (i=0; i < delayedTriggers.length; i++) {\n\t\t\t\tdelayedTriggers[i].call(this, event);\n\t\t\t} //Trigger all delayed events\n\t\t\tthis._trigger(\"stop\", event, this._uiHash());\n\t\t}\n\n\t\tthis.fromOutside = false;\n\t\treturn !this.cancelHelperRemoval;\n\n\t},\n\n\t_trigger: function() {\n\t\tif ($.Widget.prototype._trigger.apply(this, arguments) === false) {\n\t\t\tthis.cancel();\n\t\t}\n\t},\n\n\t_uiHash: function(_inst) {\n\t\tvar inst = _inst || this;\n\t\treturn {\n\t\t\thelper: inst.helper,\n\t\t\tplaceholder: inst.placeholder || $([]),\n\t\t\tposition: inst.position,\n\t\t\toriginalPosition: inst.originalPosition,\n\t\t\toffset: inst.positionAbs,\n\t\t\titem: inst.currentItem,\n\t\t\tsender: _inst ? _inst.element : null\n\t\t};\n\t}\n\n});\n\n\n/*!\n * jQuery UI Spinner 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/spinner/\n */\n\n\nfunction spinner_modifier( fn ) {\n\treturn function() {\n\t\tvar previous = this.element.val();\n\t\tfn.apply( this, arguments );\n\t\tthis._refresh();\n\t\tif ( previous !== this.element.val() ) {\n\t\t\tthis._trigger( \"change\" );\n\t\t}\n\t};\n}\n\nvar spinner = $.widget( \"ui.spinner\", {\n\tversion: \"1.11.4\",\n\tdefaultElement: \"<input>\",\n\twidgetEventPrefix: \"spin\",\n\toptions: {\n\t\tculture: null,\n\t\ticons: {\n\t\t\tdown: \"ui-icon-triangle-1-s\",\n\t\t\tup: \"ui-icon-triangle-1-n\"\n\t\t},\n\t\tincremental: true,\n\t\tmax: null,\n\t\tmin: null,\n\t\tnumberFormat: null,\n\t\tpage: 10,\n\t\tstep: 1,\n\n\t\tchange: null,\n\t\tspin: null,\n\t\tstart: null,\n\t\tstop: null\n\t},\n\n\t_create: function() {\n\t\t// handle string values that need to be parsed\n\t\tthis._setOption( \"max\", this.options.max );\n\t\tthis._setOption( \"min\", this.options.min );\n\t\tthis._setOption( \"step\", this.options.step );\n\n\t\t// Only format if there is a value, prevents the field from being marked\n\t\t// as invalid in Firefox, see #9573.\n\t\tif ( this.value() !== \"\" ) {\n\t\t\t// Format the value, but don't constrain.\n\t\t\tthis._value( this.element.val(), true );\n\t\t}\n\n\t\tthis._draw();\n\t\tthis._on( this._events );\n\t\tthis._refresh();\n\n\t\t// turning off autocomplete prevents the browser from remembering the\n\t\t// value when navigating through history, so we re-enable autocomplete\n\t\t// if the page is unloaded before the widget is destroyed. #7790\n\t\tthis._on( this.window, {\n\t\t\tbeforeunload: function() {\n\t\t\t\tthis.element.removeAttr( \"autocomplete\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_getCreateOptions: function() {\n\t\tvar options = {},\n\t\t\telement = this.element;\n\n\t\t$.each( [ \"min\", \"max\", \"step\" ], function( i, option ) {\n\t\t\tvar value = element.attr( option );\n\t\t\tif ( value !== undefined && value.length ) {\n\t\t\t\toptions[ option ] = value;\n\t\t\t}\n\t\t});\n\n\t\treturn options;\n\t},\n\n\t_events: {\n\t\tkeydown: function( event ) {\n\t\t\tif ( this._start( event ) && this._keydown( event ) ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t},\n\t\tkeyup: \"_stop\",\n\t\tfocus: function() {\n\t\t\tthis.previous = this.element.val();\n\t\t},\n\t\tblur: function( event ) {\n\t\t\tif ( this.cancelBlur ) {\n\t\t\t\tdelete this.cancelBlur;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._stop();\n\t\t\tthis._refresh();\n\t\t\tif ( this.previous !== this.element.val() ) {\n\t\t\t\tthis._trigger( \"change\", event );\n\t\t\t}\n\t\t},\n\t\tmousewheel: function( event, delta ) {\n\t\t\tif ( !delta ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( !this.spinning && !this._start( event ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tthis._spin( (delta > 0 ? 1 : -1) * this.options.step, event );\n\t\t\tclearTimeout( this.mousewheelTimer );\n\t\t\tthis.mousewheelTimer = this._delay(function() {\n\t\t\t\tif ( this.spinning ) {\n\t\t\t\t\tthis._stop( event );\n\t\t\t\t}\n\t\t\t}, 100 );\n\t\t\tevent.preventDefault();\n\t\t},\n\t\t\"mousedown .ui-spinner-button\": function( event ) {\n\t\t\tvar previous;\n\n\t\t\t// We never want the buttons to have focus; whenever the user is\n\t\t\t// interacting with the spinner, the focus should be on the input.\n\t\t\t// If the input is focused then this.previous is properly set from\n\t\t\t// when the input first received focus. If the input is not focused\n\t\t\t// then we need to set this.previous based on the value before spinning.\n\t\t\tprevious = this.element[0] === this.document[0].activeElement ?\n\t\t\t\tthis.previous : this.element.val();\n\t\t\tfunction checkFocus() {\n\t\t\t\tvar isActive = this.element[0] === this.document[0].activeElement;\n\t\t\t\tif ( !isActive ) {\n\t\t\t\t\tthis.element.focus();\n\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t// support: IE\n\t\t\t\t\t// IE sets focus asynchronously, so we need to check if focus\n\t\t\t\t\t// moved off of the input because the user clicked on the button.\n\t\t\t\t\tthis._delay(function() {\n\t\t\t\t\t\tthis.previous = previous;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// ensure focus is on (or stays on) the text field\n\t\t\tevent.preventDefault();\n\t\t\tcheckFocus.call( this );\n\n\t\t\t// support: IE\n\t\t\t// IE doesn't prevent moving focus even with event.preventDefault()\n\t\t\t// so we set a flag to know when we should ignore the blur event\n\t\t\t// and check (again) if focus moved off of the input.\n\t\t\tthis.cancelBlur = true;\n\t\t\tthis._delay(function() {\n\t\t\t\tdelete this.cancelBlur;\n\t\t\t\tcheckFocus.call( this );\n\t\t\t});\n\n\t\t\tif ( this._start( event ) === false ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tthis._repeat( null, $( event.currentTarget ).hasClass( \"ui-spinner-up\" ) ? 1 : -1, event );\n\t\t},\n\t\t\"mouseup .ui-spinner-button\": \"_stop\",\n\t\t\"mouseenter .ui-spinner-button\": function( event ) {\n\t\t\t// button will add ui-state-active if mouse was down while mouseleave and kept down\n\t\t\tif ( !$( event.currentTarget ).hasClass( \"ui-state-active\" ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( this._start( event ) === false ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tthis._repeat( null, $( event.currentTarget ).hasClass( \"ui-spinner-up\" ) ? 1 : -1, event );\n\t\t},\n\t\t// TODO: do we really want to consider this a stop?\n\t\t// shouldn't we just stop the repeater and wait until mouseup before\n\t\t// we trigger the stop event?\n\t\t\"mouseleave .ui-spinner-button\": \"_stop\"\n\t},\n\n\t_draw: function() {\n\t\tvar uiSpinner = this.uiSpinner = this.element\n\t\t\t.addClass( \"ui-spinner-input\" )\n\t\t\t.attr( \"autocomplete\", \"off\" )\n\t\t\t.wrap( this._uiSpinnerHtml() )\n\t\t\t.parent()\n\t\t\t\t// add buttons\n\t\t\t\t.append( this._buttonHtml() );\n\n\t\tthis.element.attr( \"role\", \"spinbutton\" );\n\n\t\t// button bindings\n\t\tthis.buttons = uiSpinner.find( \".ui-spinner-button\" )\n\t\t\t.attr( \"tabIndex\", -1 )\n\t\t\t.button()\n\t\t\t.removeClass( \"ui-corner-all\" );\n\n\t\t// IE 6 doesn't understand height: 50% for the buttons\n\t\t// unless the wrapper has an explicit height\n\t\tif ( this.buttons.height() > Math.ceil( uiSpinner.height() * 0.5 ) &&\n\t\t\t\tuiSpinner.height() > 0 ) {\n\t\t\tuiSpinner.height( uiSpinner.height() );\n\t\t}\n\n\t\t// disable spinner if element was already disabled\n\t\tif ( this.options.disabled ) {\n\t\t\tthis.disable();\n\t\t}\n\t},\n\n\t_keydown: function( event ) {\n\t\tvar options = this.options,\n\t\t\tkeyCode = $.ui.keyCode;\n\n\t\tswitch ( event.keyCode ) {\n\t\tcase keyCode.UP:\n\t\t\tthis._repeat( null, 1, event );\n\t\t\treturn true;\n\t\tcase keyCode.DOWN:\n\t\t\tthis._repeat( null, -1, event );\n\t\t\treturn true;\n\t\tcase keyCode.PAGE_UP:\n\t\t\tthis._repeat( null, options.page, event );\n\t\t\treturn true;\n\t\tcase keyCode.PAGE_DOWN:\n\t\t\tthis._repeat( null, -options.page, event );\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t},\n\n\t_uiSpinnerHtml: function() {\n\t\treturn \"<span class='ui-spinner ui-widget ui-widget-content ui-corner-all'></span>\";\n\t},\n\n\t_buttonHtml: function() {\n\t\treturn \"\" +\n\t\t\t\"<a class='ui-spinner-button ui-spinner-up ui-corner-tr'>\" +\n\t\t\t\t\"<span class='ui-icon \" + this.options.icons.up + \"'>&#9650;</span>\" +\n\t\t\t\"</a>\" +\n\t\t\t\"<a class='ui-spinner-button ui-spinner-down ui-corner-br'>\" +\n\t\t\t\t\"<span class='ui-icon \" + this.options.icons.down + \"'>&#9660;</span>\" +\n\t\t\t\"</a>\";\n\t},\n\n\t_start: function( event ) {\n\t\tif ( !this.spinning && this._trigger( \"start\", event ) === false ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( !this.counter ) {\n\t\t\tthis.counter = 1;\n\t\t}\n\t\tthis.spinning = true;\n\t\treturn true;\n\t},\n\n\t_repeat: function( i, steps, event ) {\n\t\ti = i || 500;\n\n\t\tclearTimeout( this.timer );\n\t\tthis.timer = this._delay(function() {\n\t\t\tthis._repeat( 40, steps, event );\n\t\t}, i );\n\n\t\tthis._spin( steps * this.options.step, event );\n\t},\n\n\t_spin: function( step, event ) {\n\t\tvar value = this.value() || 0;\n\n\t\tif ( !this.counter ) {\n\t\t\tthis.counter = 1;\n\t\t}\n\n\t\tvalue = this._adjustValue( value + step * this._increment( this.counter ) );\n\n\t\tif ( !this.spinning || this._trigger( \"spin\", event, { value: value } ) !== false) {\n\t\t\tthis._value( value );\n\t\t\tthis.counter++;\n\t\t}\n\t},\n\n\t_increment: function( i ) {\n\t\tvar incremental = this.options.incremental;\n\n\t\tif ( incremental ) {\n\t\t\treturn $.isFunction( incremental ) ?\n\t\t\t\tincremental( i ) :\n\t\t\t\tMath.floor( i * i * i / 50000 - i * i / 500 + 17 * i / 200 + 1 );\n\t\t}\n\n\t\treturn 1;\n\t},\n\n\t_precision: function() {\n\t\tvar precision = this._precisionOf( this.options.step );\n\t\tif ( this.options.min !== null ) {\n\t\t\tprecision = Math.max( precision, this._precisionOf( this.options.min ) );\n\t\t}\n\t\treturn precision;\n\t},\n\n\t_precisionOf: function( num ) {\n\t\tvar str = num.toString(),\n\t\t\tdecimal = str.indexOf( \".\" );\n\t\treturn decimal === -1 ? 0 : str.length - decimal - 1;\n\t},\n\n\t_adjustValue: function( value ) {\n\t\tvar base, aboveMin,\n\t\t\toptions = this.options;\n\n\t\t// make sure we're at a valid step\n\t\t// - find out where we are relative to the base (min or 0)\n\t\tbase = options.min !== null ? options.min : 0;\n\t\taboveMin = value - base;\n\t\t// - round to the nearest step\n\t\taboveMin = Math.round(aboveMin / options.step) * options.step;\n\t\t// - rounding is based on 0, so adjust back to our base\n\t\tvalue = base + aboveMin;\n\n\t\t// fix precision from bad JS floating point math\n\t\tvalue = parseFloat( value.toFixed( this._precision() ) );\n\n\t\t// clamp the value\n\t\tif ( options.max !== null && value > options.max) {\n\t\t\treturn options.max;\n\t\t}\n\t\tif ( options.min !== null && value < options.min ) {\n\t\t\treturn options.min;\n\t\t}\n\n\t\treturn value;\n\t},\n\n\t_stop: function( event ) {\n\t\tif ( !this.spinning ) {\n\t\t\treturn;\n\t\t}\n\n\t\tclearTimeout( this.timer );\n\t\tclearTimeout( this.mousewheelTimer );\n\t\tthis.counter = 0;\n\t\tthis.spinning = false;\n\t\tthis._trigger( \"stop\", event );\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"culture\" || key === \"numberFormat\" ) {\n\t\t\tvar prevValue = this._parse( this.element.val() );\n\t\t\tthis.options[ key ] = value;\n\t\t\tthis.element.val( this._format( prevValue ) );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key === \"max\" || key === \"min\" || key === \"step\" ) {\n\t\t\tif ( typeof value === \"string\" ) {\n\t\t\t\tvalue = this._parse( value );\n\t\t\t}\n\t\t}\n\t\tif ( key === \"icons\" ) {\n\t\t\tthis.buttons.first().find( \".ui-icon\" )\n\t\t\t\t.removeClass( this.options.icons.up )\n\t\t\t\t.addClass( value.up );\n\t\t\tthis.buttons.last().find( \".ui-icon\" )\n\t\t\t\t.removeClass( this.options.icons.down )\n\t\t\t\t.addClass( value.down );\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis.widget().toggleClass( \"ui-state-disabled\", !!value );\n\t\t\tthis.element.prop( \"disabled\", !!value );\n\t\t\tthis.buttons.button( value ? \"disable\" : \"enable\" );\n\t\t}\n\t},\n\n\t_setOptions: spinner_modifier(function( options ) {\n\t\tthis._super( options );\n\t}),\n\n\t_parse: function( val ) {\n\t\tif ( typeof val === \"string\" && val !== \"\" ) {\n\t\t\tval = window.Globalize && this.options.numberFormat ?\n\t\t\t\tGlobalize.parseFloat( val, 10, this.options.culture ) : +val;\n\t\t}\n\t\treturn val === \"\" || isNaN( val ) ? null : val;\n\t},\n\n\t_format: function( value ) {\n\t\tif ( value === \"\" ) {\n\t\t\treturn \"\";\n\t\t}\n\t\treturn window.Globalize && this.options.numberFormat ?\n\t\t\tGlobalize.format( value, this.options.numberFormat, this.options.culture ) :\n\t\t\tvalue;\n\t},\n\n\t_refresh: function() {\n\t\tthis.element.attr({\n\t\t\t\"aria-valuemin\": this.options.min,\n\t\t\t\"aria-valuemax\": this.options.max,\n\t\t\t// TODO: what should we do with values that can't be parsed?\n\t\t\t\"aria-valuenow\": this._parse( this.element.val() )\n\t\t});\n\t},\n\n\tisValid: function() {\n\t\tvar value = this.value();\n\n\t\t// null is invalid\n\t\tif ( value === null ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// if value gets adjusted, it's invalid\n\t\treturn value === this._adjustValue( value );\n\t},\n\n\t// update the value without triggering change\n\t_value: function( value, allowAny ) {\n\t\tvar parsed;\n\t\tif ( value !== \"\" ) {\n\t\t\tparsed = this._parse( value );\n\t\t\tif ( parsed !== null ) {\n\t\t\t\tif ( !allowAny ) {\n\t\t\t\t\tparsed = this._adjustValue( parsed );\n\t\t\t\t}\n\t\t\t\tvalue = this._format( parsed );\n\t\t\t}\n\t\t}\n\t\tthis.element.val( value );\n\t\tthis._refresh();\n\t},\n\n\t_destroy: function() {\n\t\tthis.element\n\t\t\t.removeClass( \"ui-spinner-input\" )\n\t\t\t.prop( \"disabled\", false )\n\t\t\t.removeAttr( \"autocomplete\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"aria-valuemin\" )\n\t\t\t.removeAttr( \"aria-valuemax\" )\n\t\t\t.removeAttr( \"aria-valuenow\" );\n\t\tthis.uiSpinner.replaceWith( this.element );\n\t},\n\n\tstepUp: spinner_modifier(function( steps ) {\n\t\tthis._stepUp( steps );\n\t}),\n\t_stepUp: function( steps ) {\n\t\tif ( this._start() ) {\n\t\t\tthis._spin( (steps || 1) * this.options.step );\n\t\t\tthis._stop();\n\t\t}\n\t},\n\n\tstepDown: spinner_modifier(function( steps ) {\n\t\tthis._stepDown( steps );\n\t}),\n\t_stepDown: function( steps ) {\n\t\tif ( this._start() ) {\n\t\t\tthis._spin( (steps || 1) * -this.options.step );\n\t\t\tthis._stop();\n\t\t}\n\t},\n\n\tpageUp: spinner_modifier(function( pages ) {\n\t\tthis._stepUp( (pages || 1) * this.options.page );\n\t}),\n\n\tpageDown: spinner_modifier(function( pages ) {\n\t\tthis._stepDown( (pages || 1) * this.options.page );\n\t}),\n\n\tvalue: function( newVal ) {\n\t\tif ( !arguments.length ) {\n\t\t\treturn this._parse( this.element.val() );\n\t\t}\n\t\tspinner_modifier( this._value ).call( this, newVal );\n\t},\n\n\twidget: function() {\n\t\treturn this.uiSpinner;\n\t}\n});\n\n\n/*!\n * jQuery UI Tabs 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/tabs/\n */\n\n\nvar tabs = $.widget( \"ui.tabs\", {\n\tversion: \"1.11.4\",\n\tdelay: 300,\n\toptions: {\n\t\tactive: null,\n\t\tcollapsible: false,\n\t\tevent: \"click\",\n\t\theightStyle: \"content\",\n\t\thide: null,\n\t\tshow: null,\n\n\t\t// callbacks\n\t\tactivate: null,\n\t\tbeforeActivate: null,\n\t\tbeforeLoad: null,\n\t\tload: null\n\t},\n\n\t_isLocal: (function() {\n\t\tvar rhash = /#.*$/;\n\n\t\treturn function( anchor ) {\n\t\t\tvar anchorUrl, locationUrl;\n\n\t\t\t// support: IE7\n\t\t\t// IE7 doesn't normalize the href property when set via script (#9317)\n\t\t\tanchor = anchor.cloneNode( false );\n\n\t\t\tanchorUrl = anchor.href.replace( rhash, \"\" );\n\t\t\tlocationUrl = location.href.replace( rhash, \"\" );\n\n\t\t\t// decoding may throw an error if the URL isn't UTF-8 (#9518)\n\t\t\ttry {\n\t\t\t\tanchorUrl = decodeURIComponent( anchorUrl );\n\t\t\t} catch ( error ) {}\n\t\t\ttry {\n\t\t\t\tlocationUrl = decodeURIComponent( locationUrl );\n\t\t\t} catch ( error ) {}\n\n\t\t\treturn anchor.hash.length > 1 && anchorUrl === locationUrl;\n\t\t};\n\t})(),\n\n\t_create: function() {\n\t\tvar that = this,\n\t\t\toptions = this.options;\n\n\t\tthis.running = false;\n\n\t\tthis.element\n\t\t\t.addClass( \"ui-tabs ui-widget ui-widget-content ui-corner-all\" )\n\t\t\t.toggleClass( \"ui-tabs-collapsible\", options.collapsible );\n\n\t\tthis._processTabs();\n\t\toptions.active = this._initialActive();\n\n\t\t// Take disabling tabs via class attribute from HTML\n\t\t// into account and update option properly.\n\t\tif ( $.isArray( options.disabled ) ) {\n\t\t\toptions.disabled = $.unique( options.disabled.concat(\n\t\t\t\t$.map( this.tabs.filter( \".ui-state-disabled\" ), function( li ) {\n\t\t\t\t\treturn that.tabs.index( li );\n\t\t\t\t})\n\t\t\t) ).sort();\n\t\t}\n\n\t\t// check for length avoids error when initializing empty list\n\t\tif ( this.options.active !== false && this.anchors.length ) {\n\t\t\tthis.active = this._findActive( options.active );\n\t\t} else {\n\t\t\tthis.active = $();\n\t\t}\n\n\t\tthis._refresh();\n\n\t\tif ( this.active.length ) {\n\t\t\tthis.load( options.active );\n\t\t}\n\t},\n\n\t_initialActive: function() {\n\t\tvar active = this.options.active,\n\t\t\tcollapsible = this.options.collapsible,\n\t\t\tlocationHash = location.hash.substring( 1 );\n\n\t\tif ( active === null ) {\n\t\t\t// check the fragment identifier in the URL\n\t\t\tif ( locationHash ) {\n\t\t\t\tthis.tabs.each(function( i, tab ) {\n\t\t\t\t\tif ( $( tab ).attr( \"aria-controls\" ) === locationHash ) {\n\t\t\t\t\t\tactive = i;\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// check for a tab marked active via a class\n\t\t\tif ( active === null ) {\n\t\t\t\tactive = this.tabs.index( this.tabs.filter( \".ui-tabs-active\" ) );\n\t\t\t}\n\n\t\t\t// no active tab, set to false\n\t\t\tif ( active === null || active === -1 ) {\n\t\t\t\tactive = this.tabs.length ? 0 : false;\n\t\t\t}\n\t\t}\n\n\t\t// handle numbers: negative, out of range\n\t\tif ( active !== false ) {\n\t\t\tactive = this.tabs.index( this.tabs.eq( active ) );\n\t\t\tif ( active === -1 ) {\n\t\t\t\tactive = collapsible ? false : 0;\n\t\t\t}\n\t\t}\n\n\t\t// don't allow collapsible: false and active: false\n\t\tif ( !collapsible && active === false && this.anchors.length ) {\n\t\t\tactive = 0;\n\t\t}\n\n\t\treturn active;\n\t},\n\n\t_getCreateEventData: function() {\n\t\treturn {\n\t\t\ttab: this.active,\n\t\t\tpanel: !this.active.length ? $() : this._getPanelForTab( this.active )\n\t\t};\n\t},\n\n\t_tabKeydown: function( event ) {\n\t\tvar focusedTab = $( this.document[0].activeElement ).closest( \"li\" ),\n\t\t\tselectedIndex = this.tabs.index( focusedTab ),\n\t\t\tgoingForward = true;\n\n\t\tif ( this._handlePageNav( event ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tswitch ( event.keyCode ) {\n\t\t\tcase $.ui.keyCode.RIGHT:\n\t\t\tcase $.ui.keyCode.DOWN:\n\t\t\t\tselectedIndex++;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.UP:\n\t\t\tcase $.ui.keyCode.LEFT:\n\t\t\t\tgoingForward = false;\n\t\t\t\tselectedIndex--;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.END:\n\t\t\t\tselectedIndex = this.anchors.length - 1;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.HOME:\n\t\t\t\tselectedIndex = 0;\n\t\t\t\tbreak;\n\t\t\tcase $.ui.keyCode.SPACE:\n\t\t\t\t// Activate only, no collapsing\n\t\t\t\tevent.preventDefault();\n\t\t\t\tclearTimeout( this.activating );\n\t\t\t\tthis._activate( selectedIndex );\n\t\t\t\treturn;\n\t\t\tcase $.ui.keyCode.ENTER:\n\t\t\t\t// Toggle (cancel delayed activation, allow collapsing)\n\t\t\t\tevent.preventDefault();\n\t\t\t\tclearTimeout( this.activating );\n\t\t\t\t// Determine if we should collapse or activate\n\t\t\t\tthis._activate( selectedIndex === this.options.active ? false : selectedIndex );\n\t\t\t\treturn;\n\t\t\tdefault:\n\t\t\t\treturn;\n\t\t}\n\n\t\t// Focus the appropriate tab, based on which key was pressed\n\t\tevent.preventDefault();\n\t\tclearTimeout( this.activating );\n\t\tselectedIndex = this._focusNextTab( selectedIndex, goingForward );\n\n\t\t// Navigating with control/command key will prevent automatic activation\n\t\tif ( !event.ctrlKey && !event.metaKey ) {\n\n\t\t\t// Update aria-selected immediately so that AT think the tab is already selected.\n\t\t\t// Otherwise AT may confuse the user by stating that they need to activate the tab,\n\t\t\t// but the tab will already be activated by the time the announcement finishes.\n\t\t\tfocusedTab.attr( \"aria-selected\", \"false\" );\n\t\t\tthis.tabs.eq( selectedIndex ).attr( \"aria-selected\", \"true\" );\n\n\t\t\tthis.activating = this._delay(function() {\n\t\t\t\tthis.option( \"active\", selectedIndex );\n\t\t\t}, this.delay );\n\t\t}\n\t},\n\n\t_panelKeydown: function( event ) {\n\t\tif ( this._handlePageNav( event ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Ctrl+up moves focus to the current tab\n\t\tif ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {\n\t\t\tevent.preventDefault();\n\t\t\tthis.active.focus();\n\t\t}\n\t},\n\n\t// Alt+page up/down moves focus to the previous/next tab (and activates)\n\t_handlePageNav: function( event ) {\n\t\tif ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {\n\t\t\tthis._activate( this._focusNextTab( this.options.active - 1, false ) );\n\t\t\treturn true;\n\t\t}\n\t\tif ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {\n\t\t\tthis._activate( this._focusNextTab( this.options.active + 1, true ) );\n\t\t\treturn true;\n\t\t}\n\t},\n\n\t_findNextTab: function( index, goingForward ) {\n\t\tvar lastTabIndex = this.tabs.length - 1;\n\n\t\tfunction constrain() {\n\t\t\tif ( index > lastTabIndex ) {\n\t\t\t\tindex = 0;\n\t\t\t}\n\t\t\tif ( index < 0 ) {\n\t\t\t\tindex = lastTabIndex;\n\t\t\t}\n\t\t\treturn index;\n\t\t}\n\n\t\twhile ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {\n\t\t\tindex = goingForward ? index + 1 : index - 1;\n\t\t}\n\n\t\treturn index;\n\t},\n\n\t_focusNextTab: function( index, goingForward ) {\n\t\tindex = this._findNextTab( index, goingForward );\n\t\tthis.tabs.eq( index ).focus();\n\t\treturn index;\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tif ( key === \"active\" ) {\n\t\t\t// _activate() will handle invalid values and update this.options\n\t\t\tthis._activate( value );\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\t// don't use the widget factory's disabled handling\n\t\t\tthis._setupDisabled( value );\n\t\t\treturn;\n\t\t}\n\n\t\tthis._super( key, value);\n\n\t\tif ( key === \"collapsible\" ) {\n\t\t\tthis.element.toggleClass( \"ui-tabs-collapsible\", value );\n\t\t\t// Setting collapsible: false while collapsed; open first panel\n\t\t\tif ( !value && this.options.active === false ) {\n\t\t\t\tthis._activate( 0 );\n\t\t\t}\n\t\t}\n\n\t\tif ( key === \"event\" ) {\n\t\t\tthis._setupEvents( value );\n\t\t}\n\n\t\tif ( key === \"heightStyle\" ) {\n\t\t\tthis._setupHeightStyle( value );\n\t\t}\n\t},\n\n\t_sanitizeSelector: function( hash ) {\n\t\treturn hash ? hash.replace( /[!\"$%&'()*+,.\\/:;<=>?@\\[\\]\\^`{|}~]/g, \"\\\\$&\" ) : \"\";\n\t},\n\n\trefresh: function() {\n\t\tvar options = this.options,\n\t\t\tlis = this.tablist.children( \":has(a[href])\" );\n\n\t\t// get disabled tabs from class attribute from HTML\n\t\t// this will get converted to a boolean if needed in _refresh()\n\t\toptions.disabled = $.map( lis.filter( \".ui-state-disabled\" ), function( tab ) {\n\t\t\treturn lis.index( tab );\n\t\t});\n\n\t\tthis._processTabs();\n\n\t\t// was collapsed or no tabs\n\t\tif ( options.active === false || !this.anchors.length ) {\n\t\t\toptions.active = false;\n\t\t\tthis.active = $();\n\t\t// was active, but active tab is gone\n\t\t} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {\n\t\t\t// all remaining tabs are disabled\n\t\t\tif ( this.tabs.length === options.disabled.length ) {\n\t\t\t\toptions.active = false;\n\t\t\t\tthis.active = $();\n\t\t\t// activate previous tab\n\t\t\t} else {\n\t\t\t\tthis._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );\n\t\t\t}\n\t\t// was active, active tab still exists\n\t\t} else {\n\t\t\t// make sure active index is correct\n\t\t\toptions.active = this.tabs.index( this.active );\n\t\t}\n\n\t\tthis._refresh();\n\t},\n\n\t_refresh: function() {\n\t\tthis._setupDisabled( this.options.disabled );\n\t\tthis._setupEvents( this.options.event );\n\t\tthis._setupHeightStyle( this.options.heightStyle );\n\n\t\tthis.tabs.not( this.active ).attr({\n\t\t\t\"aria-selected\": \"false\",\n\t\t\t\"aria-expanded\": \"false\",\n\t\t\ttabIndex: -1\n\t\t});\n\t\tthis.panels.not( this._getPanelForTab( this.active ) )\n\t\t\t.hide()\n\t\t\t.attr({\n\t\t\t\t\"aria-hidden\": \"true\"\n\t\t\t});\n\n\t\t// Make sure one tab is in the tab order\n\t\tif ( !this.active.length ) {\n\t\t\tthis.tabs.eq( 0 ).attr( \"tabIndex\", 0 );\n\t\t} else {\n\t\t\tthis.active\n\t\t\t\t.addClass( \"ui-tabs-active ui-state-active\" )\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-selected\": \"true\",\n\t\t\t\t\t\"aria-expanded\": \"true\",\n\t\t\t\t\ttabIndex: 0\n\t\t\t\t});\n\t\t\tthis._getPanelForTab( this.active )\n\t\t\t\t.show()\n\t\t\t\t.attr({\n\t\t\t\t\t\"aria-hidden\": \"false\"\n\t\t\t\t});\n\t\t}\n\t},\n\n\t_processTabs: function() {\n\t\tvar that = this,\n\t\t\tprevTabs = this.tabs,\n\t\t\tprevAnchors = this.anchors,\n\t\t\tprevPanels = this.panels;\n\n\t\tthis.tablist = this._getList()\n\t\t\t.addClass( \"ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all\" )\n\t\t\t.attr( \"role\", \"tablist\" )\n\n\t\t\t// Prevent users from focusing disabled tabs via click\n\t\t\t.delegate( \"> li\", \"mousedown\" + this.eventNamespace, function( event ) {\n\t\t\t\tif ( $( this ).is( \".ui-state-disabled\" ) ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t})\n\n\t\t\t// support: IE <9\n\t\t\t// Preventing the default action in mousedown doesn't prevent IE\n\t\t\t// from focusing the element, so if the anchor gets focused, blur.\n\t\t\t// We don't have to worry about focusing the previously focused\n\t\t\t// element since clicking on a non-focusable element should focus\n\t\t\t// the body anyway.\n\t\t\t.delegate( \".ui-tabs-anchor\", \"focus\" + this.eventNamespace, function() {\n\t\t\t\tif ( $( this ).closest( \"li\" ).is( \".ui-state-disabled\" ) ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t}\n\t\t\t});\n\n\t\tthis.tabs = this.tablist.find( \"> li:has(a[href])\" )\n\t\t\t.addClass( \"ui-state-default ui-corner-top\" )\n\t\t\t.attr({\n\t\t\t\trole: \"tab\",\n\t\t\t\ttabIndex: -1\n\t\t\t});\n\n\t\tthis.anchors = this.tabs.map(function() {\n\t\t\t\treturn $( \"a\", this )[ 0 ];\n\t\t\t})\n\t\t\t.addClass( \"ui-tabs-anchor\" )\n\t\t\t.attr({\n\t\t\t\trole: \"presentation\",\n\t\t\t\ttabIndex: -1\n\t\t\t});\n\n\t\tthis.panels = $();\n\n\t\tthis.anchors.each(function( i, anchor ) {\n\t\t\tvar selector, panel, panelId,\n\t\t\t\tanchorId = $( anchor ).uniqueId().attr( \"id\" ),\n\t\t\t\ttab = $( anchor ).closest( \"li\" ),\n\t\t\t\toriginalAriaControls = tab.attr( \"aria-controls\" );\n\n\t\t\t// inline tab\n\t\t\tif ( that._isLocal( anchor ) ) {\n\t\t\t\tselector = anchor.hash;\n\t\t\t\tpanelId = selector.substring( 1 );\n\t\t\t\tpanel = that.element.find( that._sanitizeSelector( selector ) );\n\t\t\t// remote tab\n\t\t\t} else {\n\t\t\t\t// If the tab doesn't already have aria-controls,\n\t\t\t\t// generate an id by using a throw-away element\n\t\t\t\tpanelId = tab.attr( \"aria-controls\" ) || $( {} ).uniqueId()[ 0 ].id;\n\t\t\t\tselector = \"#\" + panelId;\n\t\t\t\tpanel = that.element.find( selector );\n\t\t\t\tif ( !panel.length ) {\n\t\t\t\t\tpanel = that._createPanel( panelId );\n\t\t\t\t\tpanel.insertAfter( that.panels[ i - 1 ] || that.tablist );\n\t\t\t\t}\n\t\t\t\tpanel.attr( \"aria-live\", \"polite\" );\n\t\t\t}\n\n\t\t\tif ( panel.length) {\n\t\t\t\tthat.panels = that.panels.add( panel );\n\t\t\t}\n\t\t\tif ( originalAriaControls ) {\n\t\t\t\ttab.data( \"ui-tabs-aria-controls\", originalAriaControls );\n\t\t\t}\n\t\t\ttab.attr({\n\t\t\t\t\"aria-controls\": panelId,\n\t\t\t\t\"aria-labelledby\": anchorId\n\t\t\t});\n\t\t\tpanel.attr( \"aria-labelledby\", anchorId );\n\t\t});\n\n\t\tthis.panels\n\t\t\t.addClass( \"ui-tabs-panel ui-widget-content ui-corner-bottom\" )\n\t\t\t.attr( \"role\", \"tabpanel\" );\n\n\t\t// Avoid memory leaks (#10056)\n\t\tif ( prevTabs ) {\n\t\t\tthis._off( prevTabs.not( this.tabs ) );\n\t\t\tthis._off( prevAnchors.not( this.anchors ) );\n\t\t\tthis._off( prevPanels.not( this.panels ) );\n\t\t}\n\t},\n\n\t// allow overriding how to find the list for rare usage scenarios (#7715)\n\t_getList: function() {\n\t\treturn this.tablist || this.element.find( \"ol,ul\" ).eq( 0 );\n\t},\n\n\t_createPanel: function( id ) {\n\t\treturn $( \"<div>\" )\n\t\t\t.attr( \"id\", id )\n\t\t\t.addClass( \"ui-tabs-panel ui-widget-content ui-corner-bottom\" )\n\t\t\t.data( \"ui-tabs-destroy\", true );\n\t},\n\n\t_setupDisabled: function( disabled ) {\n\t\tif ( $.isArray( disabled ) ) {\n\t\t\tif ( !disabled.length ) {\n\t\t\t\tdisabled = false;\n\t\t\t} else if ( disabled.length === this.anchors.length ) {\n\t\t\t\tdisabled = true;\n\t\t\t}\n\t\t}\n\n\t\t// disable tabs\n\t\tfor ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {\n\t\t\tif ( disabled === true || $.inArray( i, disabled ) !== -1 ) {\n\t\t\t\t$( li )\n\t\t\t\t\t.addClass( \"ui-state-disabled\" )\n\t\t\t\t\t.attr( \"aria-disabled\", \"true\" );\n\t\t\t} else {\n\t\t\t\t$( li )\n\t\t\t\t\t.removeClass( \"ui-state-disabled\" )\n\t\t\t\t\t.removeAttr( \"aria-disabled\" );\n\t\t\t}\n\t\t}\n\n\t\tthis.options.disabled = disabled;\n\t},\n\n\t_setupEvents: function( event ) {\n\t\tvar events = {};\n\t\tif ( event ) {\n\t\t\t$.each( event.split(\" \"), function( index, eventName ) {\n\t\t\t\tevents[ eventName ] = \"_eventHandler\";\n\t\t\t});\n\t\t}\n\n\t\tthis._off( this.anchors.add( this.tabs ).add( this.panels ) );\n\t\t// Always prevent the default action, even when disabled\n\t\tthis._on( true, this.anchors, {\n\t\t\tclick: function( event ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t});\n\t\tthis._on( this.anchors, events );\n\t\tthis._on( this.tabs, { keydown: \"_tabKeydown\" } );\n\t\tthis._on( this.panels, { keydown: \"_panelKeydown\" } );\n\n\t\tthis._focusable( this.tabs );\n\t\tthis._hoverable( this.tabs );\n\t},\n\n\t_setupHeightStyle: function( heightStyle ) {\n\t\tvar maxHeight,\n\t\t\tparent = this.element.parent();\n\n\t\tif ( heightStyle === \"fill\" ) {\n\t\t\tmaxHeight = parent.height();\n\t\t\tmaxHeight -= this.element.outerHeight() - this.element.height();\n\n\t\t\tthis.element.siblings( \":visible\" ).each(function() {\n\t\t\t\tvar elem = $( this ),\n\t\t\t\t\tposition = elem.css( \"position\" );\n\n\t\t\t\tif ( position === \"absolute\" || position === \"fixed\" ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\tmaxHeight -= elem.outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.element.children().not( this.panels ).each(function() {\n\t\t\t\tmaxHeight -= $( this ).outerHeight( true );\n\t\t\t});\n\n\t\t\tthis.panels.each(function() {\n\t\t\t\t$( this ).height( Math.max( 0, maxHeight -\n\t\t\t\t\t$( this ).innerHeight() + $( this ).height() ) );\n\t\t\t})\n\t\t\t.css( \"overflow\", \"auto\" );\n\t\t} else if ( heightStyle === \"auto\" ) {\n\t\t\tmaxHeight = 0;\n\t\t\tthis.panels.each(function() {\n\t\t\t\tmaxHeight = Math.max( maxHeight, $( this ).height( \"\" ).height() );\n\t\t\t}).height( maxHeight );\n\t\t}\n\t},\n\n\t_eventHandler: function( event ) {\n\t\tvar options = this.options,\n\t\t\tactive = this.active,\n\t\t\tanchor = $( event.currentTarget ),\n\t\t\ttab = anchor.closest( \"li\" ),\n\t\t\tclickedIsActive = tab[ 0 ] === active[ 0 ],\n\t\t\tcollapsing = clickedIsActive && options.collapsible,\n\t\t\ttoShow = collapsing ? $() : this._getPanelForTab( tab ),\n\t\t\ttoHide = !active.length ? $() : this._getPanelForTab( active ),\n\t\t\teventData = {\n\t\t\t\toldTab: active,\n\t\t\t\toldPanel: toHide,\n\t\t\t\tnewTab: collapsing ? $() : tab,\n\t\t\t\tnewPanel: toShow\n\t\t\t};\n\n\t\tevent.preventDefault();\n\n\t\tif ( tab.hasClass( \"ui-state-disabled\" ) ||\n\t\t\t\t// tab is already loading\n\t\t\t\ttab.hasClass( \"ui-tabs-loading\" ) ||\n\t\t\t\t// can't switch durning an animation\n\t\t\t\tthis.running ||\n\t\t\t\t// click on active header, but not collapsible\n\t\t\t\t( clickedIsActive && !options.collapsible ) ||\n\t\t\t\t// allow canceling activation\n\t\t\t\t( this._trigger( \"beforeActivate\", event, eventData ) === false ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\toptions.active = collapsing ? false : this.tabs.index( tab );\n\n\t\tthis.active = clickedIsActive ? $() : tab;\n\t\tif ( this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\n\t\tif ( !toHide.length && !toShow.length ) {\n\t\t\t$.error( \"jQuery UI Tabs: Mismatching fragment identifier.\" );\n\t\t}\n\n\t\tif ( toShow.length ) {\n\t\t\tthis.load( this.tabs.index( tab ), event );\n\t\t}\n\t\tthis._toggle( event, eventData );\n\t},\n\n\t// handles show/hide for selecting tabs\n\t_toggle: function( event, eventData ) {\n\t\tvar that = this,\n\t\t\ttoShow = eventData.newPanel,\n\t\t\ttoHide = eventData.oldPanel;\n\n\t\tthis.running = true;\n\n\t\tfunction complete() {\n\t\t\tthat.running = false;\n\t\t\tthat._trigger( \"activate\", event, eventData );\n\t\t}\n\n\t\tfunction show() {\n\t\t\teventData.newTab.closest( \"li\" ).addClass( \"ui-tabs-active ui-state-active\" );\n\n\t\t\tif ( toShow.length && that.options.show ) {\n\t\t\t\tthat._show( toShow, that.options.show, complete );\n\t\t\t} else {\n\t\t\t\ttoShow.show();\n\t\t\t\tcomplete();\n\t\t\t}\n\t\t}\n\n\t\t// start out by hiding, then showing, then completing\n\t\tif ( toHide.length && this.options.hide ) {\n\t\t\tthis._hide( toHide, this.options.hide, function() {\n\t\t\t\teventData.oldTab.closest( \"li\" ).removeClass( \"ui-tabs-active ui-state-active\" );\n\t\t\t\tshow();\n\t\t\t});\n\t\t} else {\n\t\t\teventData.oldTab.closest( \"li\" ).removeClass( \"ui-tabs-active ui-state-active\" );\n\t\t\ttoHide.hide();\n\t\t\tshow();\n\t\t}\n\n\t\ttoHide.attr( \"aria-hidden\", \"true\" );\n\t\teventData.oldTab.attr({\n\t\t\t\"aria-selected\": \"false\",\n\t\t\t\"aria-expanded\": \"false\"\n\t\t});\n\t\t// If we're switching tabs, remove the old tab from the tab order.\n\t\t// If we're opening from collapsed state, remove the previous tab from the tab order.\n\t\t// If we're collapsing, then keep the collapsing tab in the tab order.\n\t\tif ( toShow.length && toHide.length ) {\n\t\t\teventData.oldTab.attr( \"tabIndex\", -1 );\n\t\t} else if ( toShow.length ) {\n\t\t\tthis.tabs.filter(function() {\n\t\t\t\treturn $( this ).attr( \"tabIndex\" ) === 0;\n\t\t\t})\n\t\t\t.attr( \"tabIndex\", -1 );\n\t\t}\n\n\t\ttoShow.attr( \"aria-hidden\", \"false\" );\n\t\teventData.newTab.attr({\n\t\t\t\"aria-selected\": \"true\",\n\t\t\t\"aria-expanded\": \"true\",\n\t\t\ttabIndex: 0\n\t\t});\n\t},\n\n\t_activate: function( index ) {\n\t\tvar anchor,\n\t\t\tactive = this._findActive( index );\n\n\t\t// trying to activate the already active panel\n\t\tif ( active[ 0 ] === this.active[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// trying to collapse, simulate a click on the current active header\n\t\tif ( !active.length ) {\n\t\t\tactive = this.active;\n\t\t}\n\n\t\tanchor = active.find( \".ui-tabs-anchor\" )[ 0 ];\n\t\tthis._eventHandler({\n\t\t\ttarget: anchor,\n\t\t\tcurrentTarget: anchor,\n\t\t\tpreventDefault: $.noop\n\t\t});\n\t},\n\n\t_findActive: function( index ) {\n\t\treturn index === false ? $() : this.tabs.eq( index );\n\t},\n\n\t_getIndex: function( index ) {\n\t\t// meta-function to give users option to provide a href string instead of a numerical index.\n\t\tif ( typeof index === \"string\" ) {\n\t\t\tindex = this.anchors.index( this.anchors.filter( \"[href$='\" + index + \"']\" ) );\n\t\t}\n\n\t\treturn index;\n\t},\n\n\t_destroy: function() {\n\t\tif ( this.xhr ) {\n\t\t\tthis.xhr.abort();\n\t\t}\n\n\t\tthis.element.removeClass( \"ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible\" );\n\n\t\tthis.tablist\n\t\t\t.removeClass( \"ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all\" )\n\t\t\t.removeAttr( \"role\" );\n\n\t\tthis.anchors\n\t\t\t.removeClass( \"ui-tabs-anchor\" )\n\t\t\t.removeAttr( \"role\" )\n\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t.removeUniqueId();\n\n\t\tthis.tablist.unbind( this.eventNamespace );\n\n\t\tthis.tabs.add( this.panels ).each(function() {\n\t\t\tif ( $.data( this, \"ui-tabs-destroy\" ) ) {\n\t\t\t\t$( this ).remove();\n\t\t\t} else {\n\t\t\t\t$( this )\n\t\t\t\t\t.removeClass( \"ui-state-default ui-state-active ui-state-disabled \" +\n\t\t\t\t\t\t\"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel\" )\n\t\t\t\t\t.removeAttr( \"tabIndex\" )\n\t\t\t\t\t.removeAttr( \"aria-live\" )\n\t\t\t\t\t.removeAttr( \"aria-busy\" )\n\t\t\t\t\t.removeAttr( \"aria-selected\" )\n\t\t\t\t\t.removeAttr( \"aria-labelledby\" )\n\t\t\t\t\t.removeAttr( \"aria-hidden\" )\n\t\t\t\t\t.removeAttr( \"aria-expanded\" )\n\t\t\t\t\t.removeAttr( \"role\" );\n\t\t\t}\n\t\t});\n\n\t\tthis.tabs.each(function() {\n\t\t\tvar li = $( this ),\n\t\t\t\tprev = li.data( \"ui-tabs-aria-controls\" );\n\t\t\tif ( prev ) {\n\t\t\t\tli\n\t\t\t\t\t.attr( \"aria-controls\", prev )\n\t\t\t\t\t.removeData( \"ui-tabs-aria-controls\" );\n\t\t\t} else {\n\t\t\t\tli.removeAttr( \"aria-controls\" );\n\t\t\t}\n\t\t});\n\n\t\tthis.panels.show();\n\n\t\tif ( this.options.heightStyle !== \"content\" ) {\n\t\t\tthis.panels.css( \"height\", \"\" );\n\t\t}\n\t},\n\n\tenable: function( index ) {\n\t\tvar disabled = this.options.disabled;\n\t\tif ( disabled === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( index === undefined ) {\n\t\t\tdisabled = false;\n\t\t} else {\n\t\t\tindex = this._getIndex( index );\n\t\t\tif ( $.isArray( disabled ) ) {\n\t\t\t\tdisabled = $.map( disabled, function( num ) {\n\t\t\t\t\treturn num !== index ? num : null;\n\t\t\t\t});\n\t\t\t} else {\n\t\t\t\tdisabled = $.map( this.tabs, function( li, num ) {\n\t\t\t\t\treturn num !== index ? num : null;\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\tthis._setupDisabled( disabled );\n\t},\n\n\tdisable: function( index ) {\n\t\tvar disabled = this.options.disabled;\n\t\tif ( disabled === true ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( index === undefined ) {\n\t\t\tdisabled = true;\n\t\t} else {\n\t\t\tindex = this._getIndex( index );\n\t\t\tif ( $.inArray( index, disabled ) !== -1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif ( $.isArray( disabled ) ) {\n\t\t\t\tdisabled = $.merge( [ index ], disabled ).sort();\n\t\t\t} else {\n\t\t\t\tdisabled = [ index ];\n\t\t\t}\n\t\t}\n\t\tthis._setupDisabled( disabled );\n\t},\n\n\tload: function( index, event ) {\n\t\tindex = this._getIndex( index );\n\t\tvar that = this,\n\t\t\ttab = this.tabs.eq( index ),\n\t\t\tanchor = tab.find( \".ui-tabs-anchor\" ),\n\t\t\tpanel = this._getPanelForTab( tab ),\n\t\t\teventData = {\n\t\t\t\ttab: tab,\n\t\t\t\tpanel: panel\n\t\t\t},\n\t\t\tcomplete = function( jqXHR, status ) {\n\t\t\t\tif ( status === \"abort\" ) {\n\t\t\t\t\tthat.panels.stop( false, true );\n\t\t\t\t}\n\n\t\t\t\ttab.removeClass( \"ui-tabs-loading\" );\n\t\t\t\tpanel.removeAttr( \"aria-busy\" );\n\n\t\t\t\tif ( jqXHR === that.xhr ) {\n\t\t\t\t\tdelete that.xhr;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// not remote\n\t\tif ( this._isLocal( anchor[ 0 ] ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );\n\n\t\t// support: jQuery <1.8\n\t\t// jQuery <1.8 returns false if the request is canceled in beforeSend,\n\t\t// but as of 1.8, $.ajax() always returns a jqXHR object.\n\t\tif ( this.xhr && this.xhr.statusText !== \"canceled\" ) {\n\t\t\ttab.addClass( \"ui-tabs-loading\" );\n\t\t\tpanel.attr( \"aria-busy\", \"true\" );\n\n\t\t\tthis.xhr\n\t\t\t\t.done(function( response, status, jqXHR ) {\n\t\t\t\t\t// support: jQuery <1.8\n\t\t\t\t\t// http://bugs.jquery.com/ticket/11778\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tpanel.html( response );\n\t\t\t\t\t\tthat._trigger( \"load\", event, eventData );\n\n\t\t\t\t\t\tcomplete( jqXHR, status );\n\t\t\t\t\t}, 1 );\n\t\t\t\t})\n\t\t\t\t.fail(function( jqXHR, status ) {\n\t\t\t\t\t// support: jQuery <1.8\n\t\t\t\t\t// http://bugs.jquery.com/ticket/11778\n\t\t\t\t\tsetTimeout(function() {\n\t\t\t\t\t\tcomplete( jqXHR, status );\n\t\t\t\t\t}, 1 );\n\t\t\t\t});\n\t\t}\n\t},\n\n\t_ajaxSettings: function( anchor, event, eventData ) {\n\t\tvar that = this;\n\t\treturn {\n\t\t\turl: anchor.attr( \"href\" ),\n\t\t\tbeforeSend: function( jqXHR, settings ) {\n\t\t\t\treturn that._trigger( \"beforeLoad\", event,\n\t\t\t\t\t$.extend( { jqXHR: jqXHR, ajaxSettings: settings }, eventData ) );\n\t\t\t}\n\t\t};\n\t},\n\n\t_getPanelForTab: function( tab ) {\n\t\tvar id = $( tab ).attr( \"aria-controls\" );\n\t\treturn this.element.find( this._sanitizeSelector( \"#\" + id ) );\n\t}\n});\n\n\n/*!\n * jQuery UI Tooltip 1.11.4\n * http://jqueryui.com\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license.\n * http://jquery.org/license\n *\n * http://api.jqueryui.com/tooltip/\n */\n\n\nvar tooltip = $.widget( \"ui.tooltip\", {\n\tversion: \"1.11.4\",\n\toptions: {\n\t\tcontent: function() {\n\t\t\t// support: IE<9, Opera in jQuery <1.7\n\t\t\t// .text() can't accept undefined, so coerce to a string\n\t\t\tvar title = $( this ).attr( \"title\" ) || \"\";\n\t\t\t// Escape title, since we're going from an attribute to raw HTML\n\t\t\treturn $( \"<a>\" ).text( title ).html();\n\t\t},\n\t\thide: true,\n\t\t// Disabled elements have inconsistent behavior across browsers (#8661)\n\t\titems: \"[title]:not([disabled])\",\n\t\tposition: {\n\t\t\tmy: \"left top+15\",\n\t\t\tat: \"left bottom\",\n\t\t\tcollision: \"flipfit flip\"\n\t\t},\n\t\tshow: true,\n\t\ttooltipClass: null,\n\t\ttrack: false,\n\n\t\t// callbacks\n\t\tclose: null,\n\t\topen: null\n\t},\n\n\t_addDescribedBy: function( elem, id ) {\n\t\tvar describedby = (elem.attr( \"aria-describedby\" ) || \"\").split( /\\s+/ );\n\t\tdescribedby.push( id );\n\t\telem\n\t\t\t.data( \"ui-tooltip-id\", id )\n\t\t\t.attr( \"aria-describedby\", $.trim( describedby.join( \" \" ) ) );\n\t},\n\n\t_removeDescribedBy: function( elem ) {\n\t\tvar id = elem.data( \"ui-tooltip-id\" ),\n\t\t\tdescribedby = (elem.attr( \"aria-describedby\" ) || \"\").split( /\\s+/ ),\n\t\t\tindex = $.inArray( id, describedby );\n\n\t\tif ( index !== -1 ) {\n\t\t\tdescribedby.splice( index, 1 );\n\t\t}\n\n\t\telem.removeData( \"ui-tooltip-id\" );\n\t\tdescribedby = $.trim( describedby.join( \" \" ) );\n\t\tif ( describedby ) {\n\t\t\telem.attr( \"aria-describedby\", describedby );\n\t\t} else {\n\t\t\telem.removeAttr( \"aria-describedby\" );\n\t\t}\n\t},\n\n\t_create: function() {\n\t\tthis._on({\n\t\t\tmouseover: \"open\",\n\t\t\tfocusin: \"open\"\n\t\t});\n\n\t\t// IDs of generated tooltips, needed for destroy\n\t\tthis.tooltips = {};\n\n\t\t// IDs of parent tooltips where we removed the title attribute\n\t\tthis.parents = {};\n\n\t\tif ( this.options.disabled ) {\n\t\t\tthis._disable();\n\t\t}\n\n\t\t// Append the aria-live region so tooltips announce correctly\n\t\tthis.liveRegion = $( \"<div>\" )\n\t\t\t.attr({\n\t\t\t\trole: \"log\",\n\t\t\t\t\"aria-live\": \"assertive\",\n\t\t\t\t\"aria-relevant\": \"additions\"\n\t\t\t})\n\t\t\t.addClass( \"ui-helper-hidden-accessible\" )\n\t\t\t.appendTo( this.document[ 0 ].body );\n\t},\n\n\t_setOption: function( key, value ) {\n\t\tvar that = this;\n\n\t\tif ( key === \"disabled\" ) {\n\t\t\tthis[ value ? \"_disable\" : \"_enable\" ]();\n\t\t\tthis.options[ key ] = value;\n\t\t\t// disable element style changes\n\t\t\treturn;\n\t\t}\n\n\t\tthis._super( key, value );\n\n\t\tif ( key === \"content\" ) {\n\t\t\t$.each( this.tooltips, function( id, tooltipData ) {\n\t\t\t\tthat._updateContent( tooltipData.element );\n\t\t\t});\n\t\t}\n\t},\n\n\t_disable: function() {\n\t\tvar that = this;\n\n\t\t// close open tooltips\n\t\t$.each( this.tooltips, function( id, tooltipData ) {\n\t\t\tvar event = $.Event( \"blur\" );\n\t\t\tevent.target = event.currentTarget = tooltipData.element[ 0 ];\n\t\t\tthat.close( event, true );\n\t\t});\n\n\t\t// remove title attributes to prevent native tooltips\n\t\tthis.element.find( this.options.items ).addBack().each(function() {\n\t\t\tvar element = $( this );\n\t\t\tif ( element.is( \"[title]\" ) ) {\n\t\t\t\telement\n\t\t\t\t\t.data( \"ui-tooltip-title\", element.attr( \"title\" ) )\n\t\t\t\t\t.removeAttr( \"title\" );\n\t\t\t}\n\t\t});\n\t},\n\n\t_enable: function() {\n\t\t// restore title attributes\n\t\tthis.element.find( this.options.items ).addBack().each(function() {\n\t\t\tvar element = $( this );\n\t\t\tif ( element.data( \"ui-tooltip-title\" ) ) {\n\t\t\t\telement.attr( \"title\", element.data( \"ui-tooltip-title\" ) );\n\t\t\t}\n\t\t});\n\t},\n\n\topen: function( event ) {\n\t\tvar that = this,\n\t\t\ttarget = $( event ? event.target : this.element )\n\t\t\t\t// we need closest here due to mouseover bubbling,\n\t\t\t\t// but always pointing at the same event target\n\t\t\t\t.closest( this.options.items );\n\n\t\t// No element to show a tooltip for or the tooltip is already open\n\t\tif ( !target.length || target.data( \"ui-tooltip-id\" ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( target.attr( \"title\" ) ) {\n\t\t\ttarget.data( \"ui-tooltip-title\", target.attr( \"title\" ) );\n\t\t}\n\n\t\ttarget.data( \"ui-tooltip-open\", true );\n\n\t\t// kill parent tooltips, custom or native, for hover\n\t\tif ( event && event.type === \"mouseover\" ) {\n\t\t\ttarget.parents().each(function() {\n\t\t\t\tvar parent = $( this ),\n\t\t\t\t\tblurEvent;\n\t\t\t\tif ( parent.data( \"ui-tooltip-open\" ) ) {\n\t\t\t\t\tblurEvent = $.Event( \"blur\" );\n\t\t\t\t\tblurEvent.target = blurEvent.currentTarget = this;\n\t\t\t\t\tthat.close( blurEvent, true );\n\t\t\t\t}\n\t\t\t\tif ( parent.attr( \"title\" ) ) {\n\t\t\t\t\tparent.uniqueId();\n\t\t\t\t\tthat.parents[ this.id ] = {\n\t\t\t\t\t\telement: this,\n\t\t\t\t\t\ttitle: parent.attr( \"title\" )\n\t\t\t\t\t};\n\t\t\t\t\tparent.attr( \"title\", \"\" );\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tthis._registerCloseHandlers( event, target );\n\t\tthis._updateContent( target, event );\n\t},\n\n\t_updateContent: function( target, event ) {\n\t\tvar content,\n\t\t\tcontentOption = this.options.content,\n\t\t\tthat = this,\n\t\t\teventType = event ? event.type : null;\n\n\t\tif ( typeof contentOption === \"string\" ) {\n\t\t\treturn this._open( event, target, contentOption );\n\t\t}\n\n\t\tcontent = contentOption.call( target[0], function( response ) {\n\n\t\t\t// IE may instantly serve a cached response for ajax requests\n\t\t\t// delay this call to _open so the other call to _open runs first\n\t\t\tthat._delay(function() {\n\n\t\t\t\t// Ignore async response if tooltip was closed already\n\t\t\t\tif ( !target.data( \"ui-tooltip-open\" ) ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// jQuery creates a special event for focusin when it doesn't\n\t\t\t\t// exist natively. To improve performance, the native event\n\t\t\t\t// object is reused and the type is changed. Therefore, we can't\n\t\t\t\t// rely on the type being correct after the event finished\n\t\t\t\t// bubbling, so we set it back to the previous value. (#8740)\n\t\t\t\tif ( event ) {\n\t\t\t\t\tevent.type = eventType;\n\t\t\t\t}\n\t\t\t\tthis._open( event, target, response );\n\t\t\t});\n\t\t});\n\t\tif ( content ) {\n\t\t\tthis._open( event, target, content );\n\t\t}\n\t},\n\n\t_open: function( event, target, content ) {\n\t\tvar tooltipData, tooltip, delayedShow, a11yContent,\n\t\t\tpositionOption = $.extend( {}, this.options.position );\n\n\t\tif ( !content ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Content can be updated multiple times. If the tooltip already\n\t\t// exists, then just update the content and bail.\n\t\ttooltipData = this._find( target );\n\t\tif ( tooltipData ) {\n\t\t\ttooltipData.tooltip.find( \".ui-tooltip-content\" ).html( content );\n\t\t\treturn;\n\t\t}\n\n\t\t// if we have a title, clear it to prevent the native tooltip\n\t\t// we have to check first to avoid defining a title if none exists\n\t\t// (we don't want to cause an element to start matching [title])\n\t\t//\n\t\t// We use removeAttr only for key events, to allow IE to export the correct\n\t\t// accessible attributes. For mouse events, set to empty string to avoid\n\t\t// native tooltip showing up (happens only when removing inside mouseover).\n\t\tif ( target.is( \"[title]\" ) ) {\n\t\t\tif ( event && event.type === \"mouseover\" ) {\n\t\t\t\ttarget.attr( \"title\", \"\" );\n\t\t\t} else {\n\t\t\t\ttarget.removeAttr( \"title\" );\n\t\t\t}\n\t\t}\n\n\t\ttooltipData = this._tooltip( target );\n\t\ttooltip = tooltipData.tooltip;\n\t\tthis._addDescribedBy( target, tooltip.attr( \"id\" ) );\n\t\ttooltip.find( \".ui-tooltip-content\" ).html( content );\n\n\t\t// Support: Voiceover on OS X, JAWS on IE <= 9\n\t\t// JAWS announces deletions even when aria-relevant=\"additions\"\n\t\t// Voiceover will sometimes re-read the entire log region's contents from the beginning\n\t\tthis.liveRegion.children().hide();\n\t\tif ( content.clone ) {\n\t\t\ta11yContent = content.clone();\n\t\t\ta11yContent.removeAttr( \"id\" ).find( \"[id]\" ).removeAttr( \"id\" );\n\t\t} else {\n\t\t\ta11yContent = content;\n\t\t}\n\t\t$( \"<div>\" ).html( a11yContent ).appendTo( this.liveRegion );\n\n\t\tfunction position( event ) {\n\t\t\tpositionOption.of = event;\n\t\t\tif ( tooltip.is( \":hidden\" ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\ttooltip.position( positionOption );\n\t\t}\n\t\tif ( this.options.track && event && /^mouse/.test( event.type ) ) {\n\t\t\tthis._on( this.document, {\n\t\t\t\tmousemove: position\n\t\t\t});\n\t\t\t// trigger once to override element-relative positioning\n\t\t\tposition( event );\n\t\t} else {\n\t\t\ttooltip.position( $.extend({\n\t\t\t\tof: target\n\t\t\t}, this.options.position ) );\n\t\t}\n\n\t\ttooltip.hide();\n\n\t\tthis._show( tooltip, this.options.show );\n\t\t// Handle tracking tooltips that are shown with a delay (#8644). As soon\n\t\t// as the tooltip is visible, position the tooltip using the most recent\n\t\t// event.\n\t\tif ( this.options.show && this.options.show.delay ) {\n\t\t\tdelayedShow = this.delayedShow = setInterval(function() {\n\t\t\t\tif ( tooltip.is( \":visible\" ) ) {\n\t\t\t\t\tposition( positionOption.of );\n\t\t\t\t\tclearInterval( delayedShow );\n\t\t\t\t}\n\t\t\t}, $.fx.interval );\n\t\t}\n\n\t\tthis._trigger( \"open\", event, { tooltip: tooltip } );\n\t},\n\n\t_registerCloseHandlers: function( event, target ) {\n\t\tvar events = {\n\t\t\tkeyup: function( event ) {\n\t\t\t\tif ( event.keyCode === $.ui.keyCode.ESCAPE ) {\n\t\t\t\t\tvar fakeEvent = $.Event(event);\n\t\t\t\t\tfakeEvent.currentTarget = target[0];\n\t\t\t\t\tthis.close( fakeEvent, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\n\t\t// Only bind remove handler for delegated targets. Non-delegated\n\t\t// tooltips will handle this in destroy.\n\t\tif ( target[ 0 ] !== this.element[ 0 ] ) {\n\t\t\tevents.remove = function() {\n\t\t\t\tthis._removeTooltip( this._find( target ).tooltip );\n\t\t\t};\n\t\t}\n\n\t\tif ( !event || event.type === \"mouseover\" ) {\n\t\t\tevents.mouseleave = \"close\";\n\t\t}\n\t\tif ( !event || event.type === \"focusin\" ) {\n\t\t\tevents.focusout = \"close\";\n\t\t}\n\t\tthis._on( true, target, events );\n\t},\n\n\tclose: function( event ) {\n\t\tvar tooltip,\n\t\t\tthat = this,\n\t\t\ttarget = $( event ? event.currentTarget : this.element ),\n\t\t\ttooltipData = this._find( target );\n\n\t\t// The tooltip may already be closed\n\t\tif ( !tooltipData ) {\n\n\t\t\t// We set ui-tooltip-open immediately upon open (in open()), but only set the\n\t\t\t// additional data once there's actually content to show (in _open()). So even if the\n\t\t\t// tooltip doesn't have full data, we always remove ui-tooltip-open in case we're in\n\t\t\t// the period between open() and _open().\n\t\t\ttarget.removeData( \"ui-tooltip-open\" );\n\t\t\treturn;\n\t\t}\n\n\t\ttooltip = tooltipData.tooltip;\n\n\t\t// disabling closes the tooltip, so we need to track when we're closing\n\t\t// to avoid an infinite loop in case the tooltip becomes disabled on close\n\t\tif ( tooltipData.closing ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Clear the interval for delayed tracking tooltips\n\t\tclearInterval( this.delayedShow );\n\n\t\t// only set title if we had one before (see comment in _open())\n\t\t// If the title attribute has changed since open(), don't restore\n\t\tif ( target.data( \"ui-tooltip-title\" ) && !target.attr( \"title\" ) ) {\n\t\t\ttarget.attr( \"title\", target.data( \"ui-tooltip-title\" ) );\n\t\t}\n\n\t\tthis._removeDescribedBy( target );\n\n\t\ttooltipData.hiding = true;\n\t\ttooltip.stop( true );\n\t\tthis._hide( tooltip, this.options.hide, function() {\n\t\t\tthat._removeTooltip( $( this ) );\n\t\t});\n\n\t\ttarget.removeData( \"ui-tooltip-open\" );\n\t\tthis._off( target, \"mouseleave focusout keyup\" );\n\n\t\t// Remove 'remove' binding only on delegated targets\n\t\tif ( target[ 0 ] !== this.element[ 0 ] ) {\n\t\t\tthis._off( target, \"remove\" );\n\t\t}\n\t\tthis._off( this.document, \"mousemove\" );\n\n\t\tif ( event && event.type === \"mouseleave\" ) {\n\t\t\t$.each( this.parents, function( id, parent ) {\n\t\t\t\t$( parent.element ).attr( \"title\", parent.title );\n\t\t\t\tdelete that.parents[ id ];\n\t\t\t});\n\t\t}\n\n\t\ttooltipData.closing = true;\n\t\tthis._trigger( \"close\", event, { tooltip: tooltip } );\n\t\tif ( !tooltipData.hiding ) {\n\t\t\ttooltipData.closing = false;\n\t\t}\n\t},\n\n\t_tooltip: function( element ) {\n\t\tvar tooltip = $( \"<div>\" )\n\t\t\t\t.attr( \"role\", \"tooltip\" )\n\t\t\t\t.addClass( \"ui-tooltip ui-widget ui-corner-all ui-widget-content \" +\n\t\t\t\t\t( this.options.tooltipClass || \"\" ) ),\n\t\t\tid = tooltip.uniqueId().attr( \"id\" );\n\n\t\t$( \"<div>\" )\n\t\t\t.addClass( \"ui-tooltip-content\" )\n\t\t\t.appendTo( tooltip );\n\n\t\ttooltip.appendTo( this.document[0].body );\n\n\t\treturn this.tooltips[ id ] = {\n\t\t\telement: element,\n\t\t\ttooltip: tooltip\n\t\t};\n\t},\n\n\t_find: function( target ) {\n\t\tvar id = target.data( \"ui-tooltip-id\" );\n\t\treturn id ? this.tooltips[ id ] : null;\n\t},\n\n\t_removeTooltip: function( tooltip ) {\n\t\ttooltip.remove();\n\t\tdelete this.tooltips[ tooltip.attr( \"id\" ) ];\n\t},\n\n\t_destroy: function() {\n\t\tvar that = this;\n\n\t\t// close open tooltips\n\t\t$.each( this.tooltips, function( id, tooltipData ) {\n\t\t\t// Delegate to close method to handle common cleanup\n\t\t\tvar event = $.Event( \"blur\" ),\n\t\t\t\telement = tooltipData.element;\n\t\t\tevent.target = event.currentTarget = element[ 0 ];\n\t\t\tthat.close( event, true );\n\n\t\t\t// Remove immediately; destroying an open tooltip doesn't use the\n\t\t\t// hide animation\n\t\t\t$( \"#\" + id ).remove();\n\n\t\t\t// Restore the title\n\t\t\tif ( element.data( \"ui-tooltip-title\" ) ) {\n\t\t\t\t// If the title attribute has changed since open(), don't restore\n\t\t\t\tif ( !element.attr( \"title\" ) ) {\n\t\t\t\t\telement.attr( \"title\", element.data( \"ui-tooltip-title\" ) );\n\t\t\t\t}\n\t\t\t\telement.removeData( \"ui-tooltip-title\" );\n\t\t\t}\n\t\t});\n\t\tthis.liveRegion.remove();\n\t}\n});\n\n\n\n}));"
  },
  {
    "path": "public/static/plugins/jvectormap/jquery-jvectormap-1.2.2.css",
    "content": ".jvectormap-label {\n    position: absolute;\n    display: none;\n    border: solid 1px #CDCDCD;\n    -webkit-border-radius: 3px;\n    -moz-border-radius: 3px;\n    border-radius: 3px;\n    background: #292929;\n    color: white;\n    font-size: 10px!important;\n    padding: 3px;\n    z-index: 9999;\n}\n\n.jvectormap-zoomin, .jvectormap-zoomout {\n    position: absolute;\n    top: 100%;\n    margin-top: -25px;\n    -webkit-border-radius: 2px;\n    -moz-border-radius: 2px;\n    border-radius: 2px;\n    background: #d2d6de;//rgba(0,0,0,0.4);\n    padding: 5px;\n    color: #444;\n    cursor: pointer;\n    line-height: 10px;\n    text-align: center;\n    font-weight: bold;\n    box-shadow: 0 1px 2px rgba(0,0,0,0.2);\n}\n\n.jvectormap-zoomin {\n    left: 100%;\n    margin-left: -50px;\n}\n\n.jvectormap-zoomout {\n    left: 100%;\n    margin-left: -30px;\n}"
  },
  {
    "path": "public/static/plugins/jvectormap/jquery-jvectormap-usa-en.js",
    "content": "jQuery.fn.vectorMap('addMap', 'us_aea',{\"insets\": [{\"width\": 220, \"top\": 440, \"height\": 172.3954126857679, \"bbox\": [{\"y\": -8441276.54251503, \"x\": -4774054.664881943}, {\"y\": -6227982.667213126, \"x\": -1949590.5739843722}], \"left\": 0}, {\"width\": 80, \"top\": 460, \"height\": 151.48337407091987, \"bbox\": [{\"y\": -4196208.652471859, \"x\": -5906305.806252358}, {\"y\": -3657293.3059425415, \"x\": -5621698.812337889}], \"left\": 245}, {\"width\": 900, \"top\": 0, \"height\": 550.1122047105795, \"bbox\": [{\"y\": -5490816.561605522, \"x\": -2029882.6485830692}, {\"y\": -2690009.0242363815, \"x\": 2552322.14899711}], \"left\": 0}], \"paths\": {\"US-VA\": {\"path\": \"M682.42,289.98l1.61,-0.93l1.65,-0.48l1.12,-0.95l3.57,-1.69l0.74,-2.33l0.82,-0.19l2.32,-1.53l0.05,-1.81l2.04,-1.86l-0.13,-1.58l0.26,-0.41l5.0,-4.09l4.76,-6.0l0.09,0.63l0.96,0.54l0.33,1.37l1.32,0.74l0.71,0.81l1.46,0.09l2.09,1.13l1.41,-0.09l0.79,-0.41l0.76,-1.22l1.17,-0.57l0.53,-1.38l2.72,1.49l1.42,-1.1l2.25,-0.99l0.76,0.06l1.08,-0.97l0.33,-0.82l-0.48,-0.96l0.23,-0.42l1.9,0.58l3.26,-2.62l0.3,-0.1l0.51,0.73l0.66,-0.07l2.38,-2.34l0.17,-0.85l-0.49,-0.51l0.99,-1.12l0.1,-0.6l-0.28,-0.51l-1.0,-0.46l0.71,-3.03l2.6,-4.8l0.55,-2.15l-0.01,-1.91l1.61,-2.55l-0.22,-0.94l0.24,-0.84l0.5,-0.48l0.39,-1.7l-0.0,-3.18l1.22,0.19l1.18,1.73l3.8,0.43l0.59,-0.28l1.05,-2.52l0.2,-2.36l0.71,-1.05l-0.04,-1.61l0.76,-2.3l1.78,0.75l0.65,-0.17l1.3,-3.3l0.57,0.05l0.59,-0.39l0.52,-1.2l0.81,-0.68l0.44,-1.8l1.38,-2.43l-0.35,-2.57l0.54,-1.76l-0.3,-2.01l9.18,4.57l0.59,-0.29l0.63,-4.0l2.6,-0.07l0.63,0.57l1.05,0.23l-0.5,1.74l0.6,0.88l1.61,0.85l2.52,-0.04l1.03,1.18l1.49,0.13l2.24,1.73l-0.0,1.31l0.44,1.27l-1.67,0.96l-0.12,0.65l-0.64,0.14l-0.27,0.45l-0.47,5.03l-0.36,0.13l-0.04,0.48l1.17,0.97l-0.29,0.11l-0.04,0.76l2.03,-0.01l2.41,-1.45l0.49,-0.72l0.34,0.74l-0.52,0.63l1.21,0.88l0.69,0.13l0.42,1.11l1.62,0.52l1.94,-0.2l0.84,0.43l0.82,-0.65l0.89,0.02l0.23,0.6l1.33,0.48l0.46,1.1l1.12,-0.05l0.02,0.3l1.18,0.42l2.84,0.65l0.4,1.01l-0.85,-0.41l-0.57,0.45l0.89,1.74l-0.35,0.57l0.62,0.79l-0.43,0.89l0.24,0.59l-1.36,-0.36l-0.59,-0.72l-0.67,0.18l-0.1,0.43l-2.44,-2.29l-0.56,0.05l-0.37,-0.56l-0.52,0.32l-1.47,-1.32l-1.19,-0.38l-0.43,-0.64l-0.9,-0.39l-0.7,-1.29l-0.77,-0.64l-1.34,-0.12l-1.11,-0.81l-1.17,0.05l-0.39,0.52l0.47,0.71l1.1,-0.01l0.63,0.68l1.33,0.07l0.59,0.42l0.38,1.52l2.73,1.56l1.86,1.88l1.95,0.61l1.59,2.1l0.98,0.24l1.35,-0.45l1.28,0.47l-0.61,0.7l0.3,0.49l2.03,0.34l0.26,0.72l0.47,0.12l0.31,1.96l-0.57,-0.83l-0.52,-0.22l-0.39,0.21l-1.13,-1.0l-0.58,0.3l0.1,0.82l-0.31,0.68l0.7,0.7l-0.18,0.59l0.51,0.28l0.43,-0.14l0.28,0.35l-1.39,0.72l-6.15,-4.74l-0.58,0.11l-0.19,0.81l0.24,0.54l2.28,1.53l2.09,2.14l2.77,1.18l1.26,-0.68l0.45,1.05l1.27,0.26l-0.44,0.67l0.29,0.56l0.93,-0.19l-0.0,1.24l-0.92,0.41l-0.57,0.73l-0.64,-0.88l-3.14,-1.26l-0.42,-1.53l-0.59,-0.59l-0.87,-0.12l-1.2,0.67l-1.71,-0.44l-0.36,-1.15l-0.71,-0.05l-0.05,1.31l-0.33,0.41l-1.42,-1.32l-0.51,0.09l-0.49,0.57l-0.64,-0.4l-0.99,0.45l-2.23,-0.1l-0.37,0.94l0.34,0.46l1.9,0.22l1.4,-0.31l0.85,0.24l0.56,-0.69l0.63,0.88l1.34,0.43l1.95,-0.31l0.82,0.72l0.84,0.12l0.51,-0.55l0.77,2.44l1.35,0.13l0.23,0.43l1.68,0.71l0.45,0.68l-0.57,1.03l0.56,0.44l1.72,-1.32l0.88,-0.02l0.83,0.65l0.8,-0.26l-0.61,-0.9l0.0,-0.82l-0.46,-0.34l3.99,0.08l0.93,-0.73l2.07,3.53l-0.4,0.7l0.65,3.09l-1.19,-0.58l-0.02,0.88l-30.94,7.83l-37.18,8.41l-19.51,3.35l-11.78,1.24l-0.82,0.62l-28.2,5.01ZM781.17,223.48l0.11,0.08l-0.08,0.06l0.0,-0.03l-0.03,-0.11ZM808.02,244.55l0.53,-1.15l-0.62,-0.62l0.58,-0.97l-0.39,-0.71l-0.03,-0.49l0.44,-0.35l-0.17,-0.73l0.62,-0.3l0.23,-0.6l0.14,-2.33l1.01,-0.39l-0.12,-0.9l0.48,-0.14l-0.26,-1.53l-0.79,-0.4l0.87,-0.57l0.1,-0.96l2.64,-1.01l0.31,2.47l-0.97,2.12l-2.32,7.36l-0.58,1.0l0.17,1.12l-0.48,0.31l-0.33,1.09l0.25,4.27l-1.1,-1.81l0.23,-0.94l-0.33,-1.57l0.28,-0.97l-0.38,-0.29Z\", \"name\": \"Virginia\"}, \"US-PA\": {\"path\": \"M716.45,159.95l0.63,-0.19l4.3,-3.73l1.12,5.19l0.48,0.31l34.84,-7.93l34.27,-8.64l1.42,0.58l0.71,1.39l0.63,0.13l0.77,-0.33l1.24,0.59l0.14,0.85l0.81,0.41l-0.16,0.58l0.89,2.69l1.9,2.07l2.12,0.75l2.2,-0.2l0.72,0.79l-0.89,0.87l-0.73,1.48l-0.17,2.25l-1.41,3.35l-1.37,1.58l0.04,0.79l1.79,1.72l-0.31,1.65l-0.84,0.43l-0.22,0.66l0.14,1.48l1.04,2.87l0.52,0.25l1.2,-0.18l1.18,2.39l0.95,0.58l0.66,-0.26l0.6,0.9l4.23,2.75l0.12,0.41l-1.29,0.93l-3.71,4.22l-0.23,0.75l0.17,0.9l-1.36,1.13l-0.84,0.15l-1.33,1.08l-0.31,0.66l-1.72,-0.12l-2.03,0.84l-1.15,1.37l-0.41,1.39l-37.22,9.21l-39.1,8.66l-10.03,-48.2l1.92,-1.22l3.07,-3.04Z\", \"name\": \"Pennsylvania\"}, \"US-TN\": {\"path\": \"M571.74,341.02l0.86,-0.84l0.29,-1.37l1.0,0.04l0.65,-0.79l-0.99,-4.89l1.41,-1.93l0.06,-1.32l1.18,-0.46l0.36,-0.48l-0.63,-1.31l0.57,-1.21l-0.89,-1.33l2.55,-1.57l1.09,-1.13l-0.14,-0.84l-0.85,-0.53l0.14,-0.19l0.34,-0.16l0.85,0.37l0.46,-0.33l-0.27,-1.31l-0.85,-0.9l0.06,-0.71l0.51,-1.43l1.0,-1.11l-1.35,-2.06l1.37,-0.21l0.61,-0.55l-0.13,-0.64l-1.17,-0.82l0.82,-0.15l0.58,-0.54l0.13,-0.69l-0.58,-1.38l0.02,-0.36l0.37,0.53l0.47,0.08l1.18,-1.15l23.66,-2.81l0.35,-0.41l-0.1,-1.34l-0.84,-2.39l2.98,-0.08l0.82,0.58l22.78,-3.54l7.64,-0.46l7.5,-0.86l8.82,-1.42l24.01,-3.09l1.11,-0.6l29.29,-5.2l0.73,-0.6l3.56,-0.54l-0.4,1.44l0.43,0.85l-0.4,2.0l0.36,0.82l-1.15,-0.03l-1.71,1.79l-1.21,3.89l-0.55,0.7l-0.56,0.08l-0.63,-0.74l-1.44,-0.02l-2.66,1.73l-1.42,2.73l-0.96,0.89l-0.34,-0.34l-0.13,-1.05l-0.73,-0.54l-0.53,0.15l-2.3,1.81l-0.29,1.32l-0.93,-0.24l-0.9,0.48l-0.16,0.77l0.32,0.73l-0.85,2.18l-1.28,0.06l-1.75,1.14l-1.89,2.3l-0.78,0.27l-2.28,2.46l-4.04,0.78l-2.58,1.7l-0.49,1.09l-0.88,0.55l-0.55,0.81l-0.18,2.88l-0.35,0.6l-1.65,0.52l-0.89,-0.16l-1.06,1.14l0.21,5.24l-20.21,3.32l-21.61,3.04l-25.56,2.95l-0.34,0.31l-7.39,0.9l-28.72,3.17Z\", \"name\": \"Tennessee\"}, \"US-WV\": {\"path\": \"M693.03,248.37l3.95,-1.54l0.35,-0.71l0.12,-2.77l1.15,-0.22l0.4,-0.61l-0.57,-2.49l-0.61,-1.24l0.49,-0.64l0.36,-2.77l0.68,-1.66l0.45,-0.39l1.24,0.55l0.41,0.71l-0.14,1.13l0.71,0.46l0.78,-0.44l0.48,-1.42l0.49,0.21l0.57,-0.2l0.2,-0.44l-0.63,-2.09l-0.75,-0.55l0.81,-0.79l-0.26,-1.71l0.74,-2.0l1.65,-0.51l0.17,-1.6l1.02,-1.42l0.43,-0.08l0.65,0.79l0.67,0.19l2.28,-1.59l1.5,-1.64l0.79,-1.83l2.45,-2.67l0.37,-2.41l-0.73,-1.0l0.71,-2.33l-0.25,-0.76l0.59,-0.58l-0.27,-3.43l0.47,-3.93l0.53,-0.8l0.08,-1.11l-0.38,-1.21l-0.39,-0.33l-0.04,-2.0l-1.57,-1.9l0.44,-0.54l0.85,-0.1l0.3,-0.33l4.03,19.33l0.47,0.31l16.59,-3.55l2.17,10.68l0.5,0.37l2.06,-2.5l0.97,-0.56l0.34,-1.03l1.63,-1.99l0.25,-1.05l0.52,-0.4l1.19,0.45l0.74,-0.32l1.32,-2.6l0.6,-0.46l-0.04,-0.85l0.42,0.59l1.81,0.52l3.2,-0.57l0.78,-0.86l0.08,-1.46l2.0,-0.74l1.02,-1.69l0.67,-0.1l3.16,1.5l1.8,-0.71l-0.45,1.02l0.56,0.92l1.27,0.42l0.09,0.96l1.13,0.43l0.09,1.2l0.33,0.42l-0.58,3.64l-9.0,-4.48l-0.64,0.24l-0.31,1.14l0.38,1.61l-0.52,1.62l0.41,2.28l-1.36,2.4l-0.42,1.76l-0.72,0.53l-0.42,1.11l-0.27,0.21l-0.61,-0.23l-0.37,0.33l-1.25,3.28l-1.84,-0.78l-0.64,0.25l-0.94,2.77l0.08,1.46l-0.73,1.14l-0.19,2.33l-0.89,2.2l-3.25,-0.36l-1.44,-1.76l-1.71,-0.24l-0.5,0.41l-0.26,2.17l0.19,1.3l-0.32,1.45l-0.49,0.45l-0.31,1.04l0.23,0.92l-1.58,2.44l-0.04,2.1l-0.52,2.0l-2.58,4.73l-0.75,3.16l0.14,0.76l1.13,0.55l-1.08,1.38l0.06,0.6l0.45,0.4l-2.16,2.13l-0.55,-0.7l-0.84,0.15l-3.12,2.53l-1.03,-0.56l-1.32,0.26l-0.44,0.91l0.45,1.17l-0.91,0.91l-0.73,-0.05l-2.27,1.0l-1.21,0.96l-2.18,-1.36l-0.73,-0.01l-0.82,1.58l-1.1,0.49l-1.22,1.46l-1.08,0.08l-1.98,-1.09l-1.3,-0.01l-0.61,-0.74l-1.19,-0.6l-0.31,-1.33l-0.89,-0.55l0.36,-0.67l-0.3,-0.81l-0.85,-0.37l-0.84,0.25l-1.33,-0.17l-1.26,-1.19l-2.06,-0.79l-0.76,-1.43l-1.58,-1.24l-0.7,-1.49l-1.0,-0.6l-0.12,-1.09l-1.38,-0.95l-2.0,-2.27l0.71,-2.03l-0.25,-1.62l-0.66,-1.46Z\", \"name\": \"West Virginia\"}, \"US-NV\": {\"path\": \"M139.46,329.14l-12.69,-16.93l-36.58,-51.09l-25.34,-34.51l13.7,-64.18l46.88,9.24l46.98,7.74l-18.71,125.81l-0.9,1.16l-0.99,2.19l-0.44,0.17l-1.34,-0.22l-0.98,-2.24l-0.7,-0.63l-1.41,0.22l-1.95,-1.02l-1.6,0.23l-1.78,0.96l-0.76,2.48l0.88,2.59l-0.6,0.97l-0.24,1.3l0.38,3.12l-0.76,2.54l0.77,3.71l-0.13,3.07l-0.3,1.07l-1.04,0.31l0.2,1.31l-0.52,0.62Z\", \"name\": \"Nevada\"}, \"US-TX\": {\"path\": \"M276.24,412.51l33.07,1.98l32.79,1.35l0.41,-0.39l3.6,-98.69l25.86,0.61l26.29,0.22l0.05,42.08l0.44,0.4l1.02,-0.13l0.78,0.28l3.74,3.82l1.66,0.21l0.88,-0.58l2.49,0.64l0.6,-0.68l0.11,-1.05l0.6,0.76l0.92,0.22l0.38,0.93l0.77,0.78l-0.01,1.64l0.52,0.83l2.85,0.42l1.25,-0.2l1.38,0.89l2.78,0.69l1.82,-0.56l0.62,0.1l1.89,1.8l1.4,-0.11l1.25,-1.43l2.43,0.26l1.67,-0.46l0.1,2.28l0.91,0.67l1.62,0.4l-0.04,2.08l1.56,0.79l1.82,-0.66l1.57,-1.67l1.02,-0.65l0.41,0.19l0.45,1.64l2.01,0.2l0.24,1.05l0.72,0.48l1.47,-0.21l0.88,-0.93l0.39,0.33l0.59,-0.08l0.61,-0.99l0.26,0.41l-0.45,1.23l0.14,0.76l0.67,1.14l0.78,0.42l0.57,-0.04l0.6,-0.5l0.68,-2.36l0.91,-0.65l0.35,-1.54l0.57,-0.14l0.4,0.14l0.29,0.99l0.57,0.64l1.21,0.02l0.83,0.5l1.25,-0.2l0.68,-1.34l0.48,0.15l-0.13,0.7l0.49,0.69l1.21,0.45l0.49,0.72l1.52,-0.05l1.49,1.74l0.52,0.02l0.63,-0.62l0.08,-0.71l1.49,-0.1l0.93,-1.43l1.88,-0.41l1.66,-1.13l1.52,0.83l1.51,-0.22l0.29,-0.83l2.29,-0.73l0.52,-0.55l0.5,0.32l0.38,0.88l1.82,0.42l1.69,-0.06l1.86,-1.14l0.41,-1.05l1.06,0.31l2.24,1.56l1.16,0.17l1.79,2.08l2.14,0.41l1.04,0.92l0.76,-0.11l2.48,0.85l1.04,0.04l0.37,0.79l1.38,0.97l1.45,-0.12l0.39,-0.72l0.8,0.36l0.88,-0.4l0.92,0.35l0.76,-0.15l0.64,0.36l2.22,34.02l1.51,1.67l1.3,0.82l1.25,1.87l0.57,1.63l-0.1,2.64l1.0,1.21l0.85,0.4l-0.12,0.85l0.75,0.54l0.28,0.87l0.65,0.7l-0.19,1.17l1.0,1.02l0.59,1.63l0.5,0.34l0.55,-0.1l-0.16,1.71l0.81,1.22l-0.64,0.25l-0.35,0.68l0.77,1.27l-0.55,0.89l0.19,1.39l-0.75,2.69l-0.74,0.85l-0.36,1.54l-0.79,1.13l0.64,2.0l-0.83,2.28l0.17,1.07l0.83,1.2l-0.19,1.01l0.49,1.6l-0.24,1.41l-1.18,1.78l-1.18,0.4l-1.16,2.72l-0.03,2.1l1.39,1.67l-3.43,0.08l-7.37,3.78l-0.02,-0.43l-0.69,-0.24l-0.23,0.23l-0.78,-0.43l-3.38,1.13l0.65,-1.31l0.35,-2.04l-0.34,-1.36l-0.8,-0.78l-1.79,0.16l-1.18,2.58l-0.42,0.15l-0.36,-0.65l-2.38,-1.23l-0.4,0.31l-0.18,0.82l0.23,0.45l1.07,0.38l-0.3,0.82l0.54,0.81l-0.47,0.64l0.04,0.99l1.48,0.76l-0.44,0.47l0.5,1.12l0.91,0.23l0.28,0.37l-0.4,1.25l-0.45,-0.12l-0.97,0.81l-1.72,2.25l-1.18,-0.4l-0.49,0.12l0.32,1.0l0.08,2.54l-1.85,1.49l-1.91,2.11l-0.96,0.37l-4.1,2.9l-3.3,0.44l-2.54,1.07l-0.2,1.12l-0.75,-0.34l-2.04,0.89l-0.33,-0.34l-1.11,0.18l0.43,-0.87l-0.52,-0.6l-1.43,0.22l-1.22,1.08l-0.6,-0.62l-0.11,-1.2l-1.38,-0.81l-0.5,0.44l0.65,1.44l0.01,1.12l-0.71,0.09l-0.54,-0.44l-0.75,-0.0l-0.55,-1.34l-1.46,-0.37l-0.58,0.39l0.04,0.54l0.94,1.7l0.03,1.23l0.58,0.37l0.37,-0.16l1.13,0.78l-0.75,0.37l-0.12,0.9l0.7,0.23l1.08,-0.55l0.96,0.6l-4.27,2.42l-0.57,-0.13l-0.37,-1.44l-0.5,-0.19l-1.13,-1.47l-0.48,-0.03l-1.05,1.99l1.19,1.61l-0.31,1.04l0.33,0.85l-1.66,1.79l-0.37,0.2l0.37,-0.63l-0.18,-0.72l0.25,-0.73l-0.46,-0.67l-0.52,0.17l-0.71,1.1l0.26,0.72l-0.39,0.95l-0.07,-1.13l-0.52,-0.55l-1.95,1.29l-0.78,-0.33l-0.69,0.51l0.07,0.75l-0.81,0.99l0.02,0.49l1.25,0.63l0.03,0.56l0.78,0.29l0.7,-1.41l0.86,-0.41l0.01,0.62l-2.82,4.36l-1.23,-1.0l-1.36,0.39l-0.32,-0.34l-2.4,0.39l-0.46,-0.31l-0.65,0.16l-0.18,0.58l0.41,0.61l0.55,0.38l1.53,0.03l0.54,1.55l2.07,1.03l-2.7,7.63l-0.2,0.1l-0.39,-0.54l-0.33,0.1l0.18,-0.75l-0.57,-0.43l-2.35,1.95l-1.67,-2.31l-1.23,-0.97l-0.61,0.4l0.09,0.52l1.44,2.0l-0.24,0.46l0.36,0.47l-1.17,-0.21l-0.33,0.63l0.5,0.56l0.89,0.23l1.12,-0.16l0.66,0.62l1.37,0.18l1.0,-0.03l0.99,-0.62l-0.34,1.59l0.24,0.77l-0.98,0.7l0.37,1.59l-1.12,0.14l-0.43,0.41l0.4,2.11l-0.33,1.6l0.45,0.64l0.84,0.24l0.87,2.86l0.71,2.8l-0.91,0.82l0.62,0.49l-0.08,1.28l0.71,0.3l0.18,0.61l0.58,0.29l0.4,1.79l0.68,0.31l0.45,3.21l1.46,0.62l-0.52,1.1l0.31,1.08l-0.62,0.77l-0.84,-0.05l-0.54,0.44l0.09,1.3l-0.49,-0.33l-0.49,0.25l-0.39,-0.67l-1.49,-0.45l-2.92,-2.53l-2.2,-0.18l-0.81,-0.51l-4.2,0.09l-0.9,0.42l-0.79,-0.62l-1.64,0.24l-2.12,-0.89l-0.73,-0.97l-0.6,-0.14l-0.21,-0.72l-1.17,-0.49l-0.99,-0.02l-1.98,-0.87l-1.45,0.39l-0.83,-1.09l-0.6,-0.21l-1.43,-1.38l-1.96,0.01l-1.47,-0.64l-0.86,0.11l-1.62,-0.41l0.35,-0.9l-0.3,-0.97l-1.11,-0.7l0.3,-0.29l-0.26,-1.44l0.56,-1.21l-0.35,-0.67l0.88,-0.38l0.12,-0.54l-1.04,-0.54l-0.91,0.67l-0.32,-0.31l0.03,-1.09l-0.59,-0.83l0.31,-0.09l0.53,-1.43l-0.22,-0.71l-0.71,0.09l-1.03,0.96l-0.57,-0.89l-0.85,-0.28l-0.26,-1.34l-1.51,-0.77l0.29,-0.65l-0.24,-0.76l0.34,-2.18l-0.45,-0.96l-1.04,-1.01l0.65,-1.99l0.05,-1.19l-0.18,-0.7l-0.54,-0.33l-0.15,-1.81l-1.85,-1.44l-0.86,0.21l-0.3,-0.41l-0.81,-0.11l-0.74,-1.31l-2.22,-1.71l0.01,-0.69l-0.51,-0.58l0.12,-0.87l-0.97,-0.92l-0.08,-0.75l-1.12,-0.61l-1.3,-2.88l-2.66,-1.48l-0.38,-0.91l-1.13,-0.59l-0.06,-1.16l-0.82,-1.19l-0.59,-1.95l0.41,-0.22l-0.04,-0.72l-1.03,-0.49l-0.26,-1.29l-0.82,-0.58l-0.94,-1.73l-0.61,-2.38l-1.85,-2.36l-0.87,-4.24l-1.81,-1.34l0.05,-0.7l-0.75,-1.21l-4.07,-2.82l-0.29,-1.39l1.68,-0.02l0.79,-0.84l-0.29,-0.39l-0.65,-0.06l-0.09,-0.72l0.08,-0.89l0.64,-0.7l-0.11,-0.74l-0.48,0.05l-0.77,0.72l-0.45,0.69l0.01,0.66l-0.88,0.15l-0.39,1.07l-0.54,-0.04l-1.81,-1.75l0.06,-0.67l-0.41,-0.68l-0.77,-0.2l-0.64,0.29l-0.33,-0.53l-0.73,-0.13l-0.89,-2.16l-1.49,-0.8l-0.85,0.27l-0.44,-0.87l-0.61,0.1l-0.25,0.61l-1.05,0.16l-2.88,-0.47l-0.39,-0.38l-1.48,-0.03l-0.79,0.29l-0.77,-0.44l-2.66,0.27l-2.42,-1.08l-1.14,-0.89l-0.68,-0.07l-1.03,0.82l-0.64,1.61l-1.99,-0.17l-0.51,0.44l-0.49,-0.17l-2.52,0.78l-3.07,6.25l-0.18,1.77l-0.76,0.67l-0.38,1.8l0.35,0.59l-1.97,0.98l-0.75,1.32l-1.07,0.61l-0.62,0.83l-0.29,1.09l-2.91,-0.34l-1.04,-0.87l-0.54,0.3l-1.69,-1.21l-1.31,-1.63l-2.9,-0.85l-1.15,-0.95l-0.02,-0.67l-0.42,-0.4l-2.75,-0.51l-2.28,-1.03l-1.89,-1.75l-0.91,-1.53l-0.96,-0.91l-1.53,-0.29l-1.76,-1.26l-0.22,-0.56l-1.14,-0.97l-0.83,-2.9l-0.86,-1.01l-0.24,-1.1l-0.76,-1.27l-0.26,-2.34l0.52,-3.04l-3.0,-5.07l-0.06,-1.94l-1.26,-2.51l-0.99,-0.44l-0.43,-1.24l-1.43,-0.81l-2.15,-2.17l-1.02,-0.1l-2.01,-1.25l-3.18,-3.35l-0.59,-1.55l-3.13,-2.55l-1.59,-2.45l-1.19,-0.95l-0.61,-1.05l-4.42,-2.6l-2.4,-5.42l-1.37,-1.08l-1.12,-0.08l-1.76,-1.68l-0.79,-3.05ZM502.12,468.09l-0.33,0.17l0.18,-0.16l0.15,-0.02ZM498.72,470.76l-0.09,0.12l-0.04,0.02l0.13,-0.14ZM467.58,489.09l0.03,0.02l-0.02,0.02l-0.0,-0.03ZM453.97,547.08l0.76,-0.5l0.25,-0.68l0.11,1.08l-1.11,0.1Z\", \"name\": \"Texas\"}, \"US-NH\": {\"path\": \"M829.91,105.39l0.2,-1.33l-1.43,-5.38l0.53,-1.45l-0.28,-2.22l1.0,-1.86l-0.13,-2.3l0.64,-2.28l-0.44,-0.62l0.29,-2.3l-0.93,-3.8l0.08,-0.7l0.3,-0.45l1.83,-0.8l0.7,-1.39l1.43,-1.62l0.74,-1.8l-0.25,-1.13l0.52,-0.62l-2.34,-3.49l0.87,-3.26l-0.11,-0.78l-0.81,-1.29l0.28,-0.59l-0.23,-0.7l0.48,-3.2l-0.36,-0.82l0.91,-1.49l2.44,0.33l0.65,-0.86l12.99,34.86l0.84,3.65l2.6,2.21l0.88,0.34l0.36,1.6l1.71,1.31l0.0,0.35l0.77,0.23l-0.06,0.58l-0.46,3.09l-1.57,0.24l-1.32,1.19l-0.51,0.94l-0.96,0.37l-0.5,1.68l-1.1,1.44l-17.61,4.74l-1.7,-1.43l-0.41,-0.89l-0.1,-2.0l0.54,-0.59l0.03,-0.52l-1.02,-5.18Z\", \"name\": \"New Hampshire\"}, \"US-NY\": {\"path\": \"M821.95,168.59l-0.84,-0.72l0.83,-3.23l1.03,-0.3l0.37,-0.48l0.74,0.21l0.64,-0.32l-0.06,-0.58l0.43,-0.05l0.28,-0.66l0.72,-0.32l-0.21,-1.42l0.73,-0.47l0.35,0.56l1.04,-0.16l0.49,-0.33l0.01,-0.54l1.46,-0.18l0.24,-0.74l1.66,0.02l0.91,-0.54l0.45,-1.21l0.62,0.24l0.43,-0.5l4.32,-1.28l2.35,-1.12l2.36,-2.84l0.18,0.17l-2.53,3.41l-0.01,0.46l0.56,0.38l1.59,-0.33l0.28,0.61l-1.3,1.19l-2.05,0.53l-0.37,0.58l-1.16,0.41l0.23,0.43l-0.24,0.3l-0.68,-0.16l-0.74,0.7l-1.04,0.17l-0.37,0.55l-1.42,0.45l-0.26,0.67l-1.34,0.19l-0.44,0.7l-1.35,0.96l-2.77,1.33l-1.02,0.88l-1.04,0.09l-0.32,0.93l-0.28,0.03l-0.26,-0.68l-1.45,-0.25l-0.88,0.74l0.07,0.96l-0.94,0.56ZM844.29,155.03l0.88,-2.14l1.18,-0.48l0.6,-0.93l0.81,0.34l0.13,-0.83l0.75,0.63l-3.84,3.68l-0.51,-0.28ZM845.16,149.15l0.06,-0.06l0.18,-0.06l-0.11,0.19l-0.13,-0.07ZM722.08,155.52l3.76,-3.85l1.27,-2.19l1.75,-1.86l1.16,-0.78l1.28,-3.35l2.09,-2.13l-0.21,-1.84l-1.61,-2.42l0.42,-1.13l-0.17,-0.78l-0.83,-0.53l-2.09,-0.0l0.04,-0.99l-0.58,-2.23l4.98,-2.94l4.48,-1.79l2.38,-0.2l1.84,-0.74l5.64,-0.24l3.12,1.25l3.16,-1.68l5.49,-1.06l0.59,0.45l0.68,-0.2l0.12,-0.99l3.23,-1.85l0.69,-2.05l1.87,-1.76l0.78,-1.26l1.12,0.03l1.13,-0.52l1.07,-1.63l-0.46,-0.69l0.36,-1.2l-0.25,-0.51l-0.64,0.02l-0.17,-1.18l-0.94,-1.58l-1.01,-0.62l0.12,-0.18l0.59,0.39l0.53,-0.27l0.75,-1.43l-0.01,-0.92l0.81,-0.64l-0.01,-0.98l-0.93,-0.19l-0.6,0.7l-0.28,0.12l0.56,-1.3l-0.81,-0.63l-1.26,0.05l-0.87,0.77l-0.98,-0.7l2.05,-2.51l1.78,-1.47l1.67,-2.63l0.7,-0.56l0.89,-1.54l0.07,-0.56l-0.49,-0.94l0.78,-1.9l4.82,-7.61l4.76,-4.5l2.84,-0.51l19.65,-5.66l0.4,0.87l-0.08,2.01l1.02,1.22l0.43,3.79l2.29,3.25l-0.09,1.89l0.85,2.41l-0.59,1.07l-0.0,3.41l0.71,0.89l1.32,2.76l0.19,1.09l0.62,0.84l0.12,3.92l0.55,0.85l0.54,0.07l0.53,-0.61l0.06,-0.87l0.33,-0.07l1.05,1.12l3.87,14.48l0.11,1.59l0.62,1.09l0.33,14.92l0.6,0.62l3.57,16.23l1.26,1.34l-2.82,3.18l0.03,0.54l1.74,1.62l-1.86,3.37l0.21,1.06l-1.03,0.45l-0.24,-4.26l-0.56,-2.23l-0.74,-1.62l-1.46,-1.1l-0.17,-1.13l-0.7,-0.09l-0.42,1.33l0.8,1.45l0.94,0.69l0.95,2.79l-13.74,-4.06l-1.28,-1.47l-2.39,0.24l-0.63,-0.43l-1.06,-0.15l-1.74,-1.91l-0.75,-2.33l0.12,-0.72l-0.36,-0.63l-0.56,-0.21l0.09,-0.46l-0.35,-0.42l-1.64,-0.68l-1.08,0.32l-0.53,-1.22l-1.92,-0.93l-34.6,8.73l-34.43,7.84l-1.11,-5.15Z\", \"name\": \"New York\"}, \"US-HI\": {\"path\": \"M293.44,610.32l-0.16,-1.33l-1.79,-3.5l-1.21,-1.37l0.23,-0.95l-0.21,-0.49l0.64,-1.68l4.55,-5.05l0.88,-5.09l0.45,-0.65l0.48,-2.22l-0.34,-2.5l0.41,-1.79l1.19,-0.79l1.55,-0.08l1.27,-0.5l1.51,0.3l2.68,-1.18l1.51,-0.07l1.15,-1.13l-0.03,-3.17l0.35,-1.25l0.99,-1.6l1.21,-0.53l2.67,2.45l-0.1,1.68l1.07,1.67l0.81,2.19l1.64,1.05l2.04,2.64l3.96,7.75l0.59,3.31l-2.1,3.31l0.14,0.54l0.73,0.44l1.2,0.23l0.29,0.68l-0.01,0.53l-0.8,1.13l-0.09,1.86l0.56,2.06l1.01,1.51l0.17,1.18l-0.37,0.44l-2.35,0.67l-1.45,-0.32l-2.49,0.4l-1.2,-0.39l-2.49,-0.11l-3.15,-1.01l-0.9,-0.94l-1.39,-0.68l-2.87,0.15l-4.73,-0.64l-1.91,0.32l-1.08,1.21l-1.89,0.33l-1.22,0.8l-1.62,0.21ZM302.97,554.35l1.47,-2.4l0.62,-1.93l-0.3,-0.8l-0.55,-0.42l-1.1,0.04l-1.49,-2.22l-0.31,-2.64l0.31,-0.99l0.92,-0.89l0.88,-0.53l1.05,-0.12l0.9,0.44l0.73,1.4l0.05,3.78l1.07,0.23l1.89,1.04l1.66,0.12l1.88,1.67l0.65,3.28l0.56,0.34l0.11,1.09l2.18,2.69l-0.14,1.17l-1.45,1.15l-0.84,-0.19l-0.81,0.3l-0.68,-0.4l-1.7,-0.23l-1.91,-1.3l-3.1,-0.5l-0.96,-1.02l-1.42,-0.79l-0.16,-1.4ZM273.53,509.24l-0.16,-0.35l0.54,-1.85l-0.3,-1.63l0.39,-1.12l-0.31,-1.61l0.83,-1.4l-0.26,-1.26l3.14,2.06l2.55,-0.17l1.08,-0.64l1.25,-0.12l0.77,0.28l0.39,1.22l-0.11,1.03l-0.4,0.54l0.01,2.42l0.41,1.21l-0.78,0.43l-0.61,1.27l0.64,2.46l0.61,0.41l0.56,-0.16l-0.24,0.78l0.3,0.88l-0.35,0.37l-0.14,1.04l0.56,1.3l-1.15,0.14l-0.29,-0.77l-2.67,-0.85l-0.05,-0.86l-0.79,-1.25l0.15,-0.76l-0.26,-0.63l-1.05,0.24l-0.45,-0.78l0.16,-0.27l1.0,0.06l0.45,-0.62l-0.42,-0.96l-0.64,-0.2l-0.35,-0.61l-0.47,0.25l-0.47,-0.55l-0.38,0.32l0.14,1.95l-2.85,-1.22ZM284.15,511.85l0.1,-0.21l-0.0,-0.01l0.1,0.09l-0.19,0.14ZM246.14,461.52l2.01,-0.42l1.12,-0.67l1.33,0.51l3.66,0.37l0.71,1.4l1.04,-0.06l1.12,1.14l0.89,0.21l0.72,0.89l0.28,1.56l-0.23,1.15l-0.51,0.62l-2.05,0.87l-1.37,1.99l-0.6,-0.19l-0.46,0.49l-2.84,0.16l-3.61,-3.83l-0.24,-1.91l-1.68,-2.24l0.05,-1.26l0.66,-0.81Z\", \"name\": \"Hawaii\"}, \"US-VT\": {\"path\": \"M805.54,72.68l26.02,-7.96l0.89,1.85l-0.74,2.37l-0.03,1.54l2.22,2.75l-0.51,0.58l0.26,1.13l-0.67,1.6l-1.35,1.49l-0.64,1.32l-1.72,0.7l-0.62,0.92l-0.1,0.98l0.93,3.74l-0.29,2.44l0.4,0.54l-0.6,2.11l0.15,2.19l-1.0,1.87l0.27,2.36l-0.53,1.54l1.43,5.44l-0.22,1.22l1.05,5.3l-0.58,0.85l0.11,2.31l0.6,1.26l1.51,1.1l-11.72,3.08l-4.31,-16.79l-1.72,-1.59l-0.91,0.25l-0.3,1.19l-0.12,-0.26l-0.11,-3.91l-0.68,-1.0l-0.14,-0.98l-1.37,-2.85l-0.63,-0.68l0.01,-3.15l0.6,-1.15l-0.86,-2.57l0.08,-1.93l-0.39,-0.91l-1.55,-1.63l-0.38,-0.81l-0.41,-3.71l-1.03,-1.27l0.11,-1.87l-0.42,-1.0Z\", \"name\": \"Vermont\"}, \"US-NM\": {\"path\": \"M230.94,422.8l11.82,-123.64l25.66,2.24l26.09,1.86l26.12,1.45l25.74,1.02l-0.31,10.24l-0.74,0.39l-3.59,98.67l-32.38,-1.34l-33.52,-2.02l-0.44,0.76l0.54,2.31l0.44,1.26l1.0,0.77l-30.53,-2.46l-0.43,0.36l-0.81,9.46l-14.64,-1.33Z\", \"name\": \"New Mexico\"}, \"US-NC\": {\"path\": \"M676.72,321.71l0.92,0.17l1.52,-0.39l0.42,-0.39l0.52,-0.97l0.13,-2.7l1.34,-1.19l0.47,-1.05l2.24,-1.47l2.12,-0.52l0.76,0.18l1.32,-0.52l2.36,-2.52l0.78,-0.25l1.84,-2.29l1.48,-1.0l1.55,-0.19l1.15,-2.65l-0.28,-1.22l1.65,0.06l0.51,-1.65l0.93,-0.77l1.08,-0.77l0.51,1.52l1.07,0.33l1.34,-1.17l1.35,-2.64l2.49,-1.59l0.79,0.08l0.82,0.8l1.06,-0.21l0.84,-1.07l1.47,-4.18l1.08,-1.1l1.47,0.09l0.44,-0.31l-0.69,-1.26l0.4,-2.0l-0.42,-0.9l0.38,-1.25l7.42,-0.86l19.54,-3.36l37.21,-8.42l31.11,-7.87l0.4,1.21l3.54,3.24l1.0,1.53l-1.2,-1.0l-0.16,-0.63l-0.92,-0.41l-0.52,0.05l-0.24,0.65l0.66,0.54l0.59,1.56l-0.53,0.01l-0.91,-0.75l-2.31,-0.8l-0.4,-0.48l-0.55,0.13l-0.31,0.69l0.14,0.64l1.37,0.44l1.69,1.38l-1.1,0.66l-2.49,-1.2l-0.35,0.5l0.14,0.42l1.6,1.18l-1.84,-0.33l-2.23,-0.87l-0.46,0.14l0.01,0.48l0.6,0.7l1.7,0.83l-0.97,0.58l0.0,0.6l-0.43,0.53l-1.48,0.75l-0.89,-0.77l-0.61,0.22l-0.1,0.35l-0.2,-0.13l-1.31,-2.32l0.21,-2.63l-0.42,-0.48l-0.89,-0.22l-0.37,0.64l0.62,0.71l-0.43,0.99l-0.02,1.03l0.49,1.73l1.6,2.2l-0.31,1.28l0.48,0.29l2.97,-0.59l2.1,-1.49l0.27,0.01l0.37,0.79l0.76,-0.34l1.56,0.05l0.16,-0.72l-0.57,-0.32l1.29,-0.76l2.04,-0.46l-0.1,1.19l0.64,0.29l-0.6,0.88l0.88,1.19l-0.84,0.1l-0.19,0.66l1.38,0.46l0.26,0.94l-1.21,0.05l-0.19,0.66l0.66,0.59l1.25,-0.16l0.52,0.26l0.41,-0.38l0.18,-1.95l-0.75,-3.33l0.41,-0.48l0.56,0.43l0.94,0.06l0.28,-0.58l-0.29,-0.44l0.48,-0.57l1.71,1.84l-0.01,1.4l0.62,0.9l-0.78,0.65l0.9,1.14l-0.08,0.37l-0.42,0.55l-0.78,0.09l-0.91,-0.86l-0.32,0.34l0.13,1.26l-1.08,1.62l0.2,0.57l-0.33,0.22l-0.15,0.98l-0.74,0.55l0.1,0.91l-0.9,0.97l-1.06,0.21l-0.6,-0.37l-0.52,0.52l-0.93,-0.81l-0.86,0.1l-0.4,-0.82l-0.59,-0.21l-0.52,0.38l0.08,0.94l-0.52,0.22l-1.42,-1.24l1.31,-0.4l0.23,-0.88l-0.57,-0.42l-2.02,0.31l-1.14,1.01l0.29,0.67l0.44,0.16l-0.06,0.39l0.15,0.43l0.35,0.25l-0.03,0.12l-0.57,-0.34l-1.69,0.83l-1.12,-0.43l-1.45,0.06l-3.32,-0.7l0.42,1.08l0.97,0.45l0.36,0.64l1.51,-0.21l4.03,1.02l3.51,0.11l0.47,0.42l-0.06,0.52l-0.99,0.05l-0.25,0.72l-1.62,1.44l0.32,0.58l1.85,0.01l-2.56,3.5l-1.67,0.04l-1.6,-0.98l-0.9,-0.19l-1.21,-1.02l-1.12,0.07l0.07,0.47l1.04,1.14l2.32,2.09l2.68,0.26l1.31,0.49l1.7,-2.16l0.51,0.47l1.17,0.33l0.4,-0.57l-0.55,-0.9l0.87,0.16l0.19,0.57l0.66,0.23l1.63,-1.2l-0.18,0.61l0.29,0.57l-0.29,0.38l-0.43,-0.21l-0.41,0.37l0.03,0.9l-0.97,1.72l0.01,0.78l-0.71,-0.07l-0.06,-0.74l-1.12,-0.61l-0.42,0.47l0.27,1.45l-0.52,-1.1l-0.65,-0.15l-1.22,1.08l-0.21,0.53l0.25,0.27l-2.03,0.32l-2.75,1.84l-0.67,-1.03l-0.75,-0.3l-0.37,0.49l0.43,1.26l-0.57,-0.01l-0.09,0.82l-0.94,1.73l-0.91,0.84l-0.59,-0.26l0.49,-0.69l-0.02,-0.77l-1.06,-0.93l-0.08,-0.52l-1.69,-0.41l-0.16,0.47l0.43,1.16l0.2,0.33l0.58,0.07l0.3,0.61l-0.88,0.37l-0.08,0.71l0.65,0.64l0.77,0.18l-0.01,0.37l-2.12,1.67l-1.91,2.65l-2.0,4.31l-0.34,2.13l0.12,1.33l-0.15,-1.03l-1.0,-1.6l-0.55,-0.17l-0.3,0.48l1.17,3.95l-0.63,2.27l-3.9,0.19l-1.43,0.65l-0.35,-0.52l-0.58,-0.18l-0.54,1.07l-1.9,1.14l-0.61,-0.02l-23.25,-15.36l-1.05,-0.02l-18.68,3.49l-0.65,-2.77l-3.25,-2.84l-0.47,0.08l-1.23,1.31l-0.01,-1.29l-0.82,-0.54l-22.82,3.35l-0.64,-0.27l-0.62,0.46l-0.25,0.65l-3.98,1.92l-0.89,1.23l-1.01,0.08l-4.78,2.66l-20.95,3.93l-0.34,-4.55l0.7,-0.95ZM816.97,271.42l0.19,0.35l0.24,0.38l-0.45,-0.41l0.02,-0.32ZM807.5,290.22l0.2,0.32l-0.16,-0.09l-0.04,-0.24ZM815.28,299.09l0.16,-0.36l0.16,0.07l-0.13,0.29l-0.19,0.01ZM812.72,299.05l-0.06,-0.29l-0.03,-0.11l0.3,0.26l-0.21,0.13Z\", \"name\": \"North Carolina\"}, \"US-ND\": {\"path\": \"M438.58,42.78l2.06,6.89l-0.73,2.53l0.57,2.36l-0.27,1.17l0.47,1.99l0.01,3.26l1.42,3.95l0.45,0.54l-0.08,0.97l0.39,1.52l0.62,0.74l1.48,3.74l-0.06,3.9l0.42,0.7l0.5,8.35l0.51,1.54l0.51,0.25l-0.47,2.64l0.36,1.63l-0.14,1.75l0.69,1.1l0.2,2.16l0.49,1.13l1.8,2.56l0.15,2.2l0.51,1.08l0.17,1.39l-0.24,1.36l0.28,1.74l-27.89,0.73l-28.38,0.19l-28.38,-0.37l-28.48,-0.93l2.75,-65.45l23.09,0.78l25.56,0.42l25.56,-0.06l24.09,-0.49Z\", \"name\": \"North Dakota\"}, \"US-NE\": {\"path\": \"M422.62,173.98l3.92,2.71l3.93,1.9l1.33,-0.22l0.51,-0.47l0.36,-1.08l0.48,-0.2l2.49,0.34l1.32,-0.47l1.58,0.25l3.45,-0.65l2.37,1.98l1.4,0.14l1.55,0.77l1.45,0.08l0.88,1.1l1.49,0.17l-0.06,0.98l1.68,2.08l3.32,0.6l-0.02,2.55l1.13,1.94l0.01,2.29l1.15,1.07l0.34,1.72l1.73,1.46l0.07,1.88l1.5,2.11l-0.49,2.33l0.44,3.09l0.52,0.54l0.93,-0.2l-0.04,1.25l1.21,0.5l-0.41,2.36l0.21,0.44l1.12,0.4l-0.6,0.77l-0.09,1.01l0.13,0.59l0.82,0.5l0.16,1.45l-0.26,0.92l0.26,1.27l0.55,0.61l0.3,1.93l-0.22,1.33l0.23,0.72l-0.57,0.92l0.02,0.79l0.45,0.88l1.23,0.63l0.25,2.5l1.1,0.51l0.03,0.79l1.18,2.75l-0.23,0.96l1.16,0.21l0.8,0.99l1.1,0.24l-0.15,0.96l1.31,1.68l-0.21,1.12l0.51,0.91l-26.14,1.05l-27.83,0.63l-27.84,0.14l-27.88,-0.35l0.46,-21.65l-0.39,-0.41l-32.35,-1.04l1.85,-43.23l43.35,1.22l44.66,-0.04Z\", \"name\": \"Nebraska\"}, \"US-LA\": {\"path\": \"M509.0,412.88l-1.33,-21.76l51.43,-4.07l0.34,0.83l1.48,0.65l-0.92,1.35l-0.25,2.13l0.49,0.72l1.18,0.31l-1.21,0.47l-0.45,0.78l0.45,1.36l1.04,0.84l0.08,2.15l0.46,0.54l1.51,0.74l0.45,1.05l1.42,0.44l-0.87,1.22l-0.85,2.34l-0.75,0.04l-0.52,0.51l-0.02,0.73l0.63,0.72l-0.22,1.16l-1.34,0.96l-1.08,1.89l-1.37,0.67l-0.68,0.83l-0.79,2.42l-0.25,3.52l-1.55,1.74l0.13,1.2l0.62,0.96l-0.35,2.38l-1.61,0.29l-0.6,0.57l0.28,0.97l0.64,0.59l-0.26,1.41l0.98,1.51l-1.18,1.18l-0.08,0.45l0.4,0.23l6.18,-0.55l29.23,-2.92l-0.68,3.47l-0.52,1.02l-0.2,2.24l0.69,0.98l-0.09,0.66l0.6,1.0l1.31,0.7l1.22,1.42l0.14,0.88l0.89,1.39l0.14,1.05l1.11,1.84l-1.85,0.39l-0.38,-0.08l-0.01,-0.56l-0.53,-0.57l-1.28,0.27l-1.18,-0.59l-1.51,0.17l-0.61,-0.98l-1.24,-0.86l-2.84,-0.47l-1.24,0.63l-1.39,2.3l-1.3,1.42l-0.42,0.91l0.07,1.2l0.55,0.89l0.82,0.57l4.25,0.82l3.35,-1.0l1.32,-1.19l0.68,-1.2l0.34,0.59l1.08,0.43l0.59,-0.4l0.81,0.03l0.51,-0.46l-0.76,1.21l-1.12,-0.12l-0.57,0.32l-0.38,0.62l0.0,0.83l0.76,1.22l1.48,-0.02l0.65,0.89l1.1,0.48l1.44,-0.66l0.46,-1.11l-0.02,-1.37l0.93,-0.57l0.42,-0.99l0.23,0.05l0.1,1.16l-0.24,0.25l0.19,0.57l0.42,0.15l-0.07,0.75l1.34,1.08l0.35,-0.16l-0.48,0.59l0.18,0.63l-0.24,0.17l-0.84,-0.72l-0.71,-0.08l-1.0,1.89l-0.84,0.14l-0.46,0.53l0.16,1.19l-1.59,-0.6l-0.43,0.19l0.04,0.46l1.14,1.06l-1.17,-0.14l-0.92,0.6l0.68,0.43l1.26,2.04l2.74,0.97l-0.08,1.2l0.33,0.4l2.07,-0.31l0.77,0.17l0.17,0.53l0.73,0.32l1.35,-0.34l0.53,0.78l1.08,-0.46l1.13,0.73l0.14,0.3l-0.41,0.63l1.54,0.86l-0.39,0.65l0.39,0.58l-0.18,0.62l-0.95,1.49l-1.3,-1.56l-0.68,0.34l0.1,0.66l-0.38,0.12l0.41,-1.88l-1.32,-0.76l-0.51,0.5l0.2,1.17l-0.54,0.45l-0.27,-1.02l-0.57,-0.25l-0.89,-1.27l0.03,-0.77l-0.96,-0.14l-0.47,0.5l-1.41,-0.17l-0.74,-0.77l-2.31,-0.09l0.38,-0.86l-0.13,-0.66l-0.64,-0.69l-0.91,0.04l0.1,-0.96l-0.37,-0.36l-0.91,-0.03l-0.22,0.59l-0.85,-0.38l-0.48,0.27l-2.61,-1.26l-1.24,-0.02l-0.67,-0.64l-0.61,0.18l-0.3,0.56l-0.05,1.25l1.72,0.94l1.67,0.35l-0.16,0.92l0.28,0.4l-0.34,0.34l0.23,0.68l-0.76,0.94l-0.03,0.66l0.81,0.97l-0.95,1.43l-1.33,0.94l-0.76,-1.15l0.22,-1.5l-0.35,-0.92l-0.49,-0.18l-0.4,0.36l-1.15,-1.08l-0.6,0.42l-0.76,-1.05l-0.62,-0.2l-0.64,1.33l-0.85,0.26l-0.89,-0.53l-0.85,0.53l-0.1,0.62l0.48,0.41l-0.67,0.56l-0.13,1.44l-0.46,0.13l-0.4,0.84l-0.92,0.08l-0.11,-0.68l-1.6,-0.4l-0.76,0.97l-1.92,-0.93l-0.3,-0.54l-0.99,0.01l-0.35,0.6l-1.15,-0.51l0.42,-0.4l0.0,-1.46l-0.38,-0.57l-1.9,-1.19l-0.08,-0.54l-0.83,-0.71l-0.09,-0.91l0.73,-1.15l-0.34,-1.14l-0.88,-0.19l-0.34,0.57l0.16,0.43l-0.58,0.81l0.04,0.91l-1.8,-0.4l0.07,-0.39l-0.47,-0.54l-1.97,0.76l-0.7,-2.22l-1.32,0.23l-0.18,-2.12l-1.31,-0.35l-1.89,0.3l-1.08,0.66l-0.21,-0.71l0.84,-0.26l-0.05,-0.8l-0.6,-0.58l-1.03,-0.1l-0.85,0.42l-0.94,-0.15l-0.4,0.8l-2.0,1.11l-0.63,-0.31l-1.29,0.71l0.54,1.37l0.81,0.31l1.04,1.55l-1.27,0.36l-1.82,1.06l-7.63,-0.92l-6.7,-2.31l-3.46,-0.65l-6.85,0.69l-3.41,0.8l-1.57,0.73l-0.91,-1.41l1.2,-0.46l0.79,-0.98l0.27,-2.3l-0.59,-0.84l1.15,-1.62l0.23,-1.59l-0.5,-1.83l0.07,-1.46l-0.66,-0.7l-0.21,-1.04l0.83,-2.21l-0.64,-1.95l0.76,-0.84l0.3,-1.49l0.78,-0.94l0.79,-2.83l-0.18,-1.42l0.58,-0.97l-0.75,-1.33l0.84,-0.39l0.2,-0.44l-0.89,-1.36l0.03,-2.13l-1.07,-0.23l-0.57,-1.57l-0.92,-0.84l0.28,-1.27l-0.81,-0.76l-0.33,-0.95l-0.64,-0.34l0.22,-0.98l-1.16,-0.58l-0.81,-0.93l0.16,-2.46l-0.68,-1.93l-1.33,-1.98l-2.63,-2.21ZM548.97,462.65l0.0,-0.0l0.0,0.0l-0.0,0.0ZM607.49,467.36l-0.03,-0.03l-0.08,-0.04l0.13,-0.01l-0.03,0.08ZM607.51,465.75l-0.02,-0.01l0.03,-0.01l-0.02,0.02ZM567.05,468.89l-2.0,-0.42l-0.66,-0.5l0.73,-0.43l0.35,-0.75l0.39,0.49l0.83,0.21l-0.14,0.6l0.5,0.81Z\", \"name\": \"Louisiana\"}, \"US-SD\": {\"path\": \"M336.43,128.81l0.3,-0.53l0.75,-19.92l28.49,0.93l28.39,0.37l28.39,-0.19l27.77,-0.73l-0.18,1.71l-0.73,1.71l-2.9,2.46l-0.42,1.27l1.59,2.13l1.06,2.06l0.55,0.36l1.74,0.24l1.01,0.84l0.57,1.02l1.45,38.83l-1.84,0.09l-0.42,0.56l0.24,1.44l0.88,1.14l0.01,1.45l-0.65,0.36l0.17,1.48l0.48,0.43l1.09,0.04l0.34,1.68l-0.16,0.91l-0.62,0.83l0.02,1.73l-0.68,2.45l-0.49,0.44l-0.67,1.88l0.5,1.1l1.33,1.08l-0.16,0.62l0.64,0.66l0.35,1.15l-1.65,-0.28l-0.34,-0.94l-0.85,-0.73l0.19,-0.61l-0.28,-0.59l-1.58,-0.23l-1.03,-1.18l-1.57,-0.11l-1.51,-0.75l-1.34,-0.12l-2.38,-1.99l-3.78,0.6l-1.65,-0.25l-1.19,0.46l-2.62,-0.33l-0.98,0.48l-0.76,1.45l-0.72,0.05l-3.66,-1.82l-4.13,-2.8l-44.82,0.05l-43.33,-1.22l1.79,-43.19Z\", \"name\": \"South Dakota\"}, \"US-DC\": {\"path\": \"M783.1,218.48l-0.45,-0.64l-1.55,-0.67l0.58,-1.01l2.03,1.26l-0.61,1.06Z\", \"name\": \"District of Columbia\"}, \"US-DE\": {\"path\": \"M798.42,195.12l0.48,-1.56l0.92,-1.11l1.72,-0.71l1.12,0.06l-0.33,0.56l-0.08,1.38l-0.46,1.09l-0.6,0.54l-0.09,0.77l0.13,0.61l1.03,0.85l0.11,2.31l3.98,3.32l1.13,3.99l1.96,1.68l0.47,1.26l3.17,2.27l1.35,-0.08l0.48,1.21l-0.58,0.27l-0.31,0.67l0.03,0.76l0.36,0.19l-0.82,0.57l-0.08,1.21l0.66,0.21l0.85,-0.73l0.72,0.34l0.3,-0.21l0.59,1.55l-9.84,2.64l-8.37,-25.89Z\", \"name\": \"Delaware\"}, \"US-FL\": {\"path\": \"M630.29,423.61l47.18,-6.86l1.52,1.91l0.86,2.72l1.47,1.0l48.78,-5.11l1.03,1.38l0.03,1.09l0.55,1.05l1.04,0.48l1.64,-0.28l0.85,-0.75l-0.14,-4.57l-0.98,-1.49l-0.22,-1.77l0.28,-0.74l0.62,-0.3l0.12,-0.7l5.59,0.96l4.03,-0.16l0.14,1.24l-0.75,-0.12l-0.32,0.43l0.25,1.54l2.11,1.81l0.22,1.01l0.42,0.38l0.3,1.92l5.3,11.5l1.81,3.07l7.14,10.22l0.63,0.36l6.82,7.53l-0.48,-0.02l-0.27,0.61l-1.35,-0.02l-0.34,-0.65l0.38,-1.38l-0.16,-0.56l-2.3,-0.92l-0.46,0.53l1.0,2.8l0.78,0.97l2.14,4.77l9.92,13.71l1.37,3.11l3.66,5.34l-1.38,-0.35l-0.43,0.74l0.8,0.65l0.85,0.24l0.56,-0.22l1.46,0.94l2.05,3.05l-0.5,0.34l-0.12,0.53l1.16,0.53l0.89,1.83l-0.08,1.06l0.59,0.95l0.61,2.64l-0.27,0.75l0.93,8.98l-0.31,1.07l0.46,0.67l0.5,3.1l-0.78,1.26l0.03,2.43l-0.84,0.74l-0.22,1.8l-0.48,0.85l0.21,1.47l-0.31,1.74l0.54,1.74l0.45,0.23l-1.15,1.8l-0.39,1.28l-0.94,0.24l-0.53,-0.22l-1.37,0.45l-0.35,1.06l-0.89,0.3l-0.18,0.58l-0.85,0.67l-1.44,0.14l-0.27,-0.32l-1.23,-0.1l-0.9,1.05l-3.17,1.13l-1.06,-0.59l-0.7,-1.04l0.06,-1.8l1.0,0.84l1.64,0.47l0.26,0.63l0.52,0.07l1.35,-0.72l0.2,-0.69l-0.26,-0.64l-1.58,-1.11l-2.4,-0.26l-0.91,-0.46l-0.85,-1.67l-0.89,-0.72l0.22,-0.98l-0.48,-0.28l-0.53,0.15l-1.38,-2.51l-0.44,-0.3l-0.64,0.07l-0.44,-0.61l0.22,-0.89l-0.7,-0.65l-1.21,-0.6l-1.06,-0.08l-0.75,-0.54l-0.57,0.18l-2.8,-0.59l-0.5,0.64l0.25,-0.91l-0.46,-0.42l-0.87,0.12l-0.26,-0.72l-0.88,-0.65l-0.61,-1.41l-0.55,-0.11l-0.73,-2.95l-0.77,-0.98l-0.16,-1.52l-0.44,-0.83l-0.71,-0.89l-0.49,-0.15l-0.12,0.93l-1.29,-0.26l1.07,-1.3l0.18,-1.37l0.86,-1.46l0.65,-0.34l0.28,-0.83l-0.61,-0.38l-1.42,0.93l-1.03,1.67l-0.28,1.79l-1.37,0.35l-0.2,-1.33l-0.79,-1.33l-0.27,-4.04l-0.86,-0.6l1.63,-1.33l0.22,-0.97l-0.58,-0.42l-3.05,1.92l-0.75,-0.66l-0.4,0.26l-1.27,-0.89l-0.37,0.74l1.13,1.09l0.52,0.1l1.26,2.0l-1.04,0.24l-1.43,-0.38l-0.84,-1.6l-1.13,-0.6l-1.94,-2.54l-1.04,-2.28l-1.28,-0.87l0.1,-0.87l-0.97,-1.8l-1.77,-0.98l0.09,-0.67l0.99,-0.41l-0.35,-0.49l0.44,-0.73l-0.39,-0.35l0.4,-1.21l2.47,-4.47l-1.05,-2.41l-0.68,-0.46l-0.92,0.42l-0.28,0.93l0.29,1.19l-0.24,0.03l-0.73,-2.44l-0.99,-0.28l-1.18,-0.87l-1.52,-0.31l0.29,1.94l-0.48,0.61l0.27,0.59l2.21,0.56l0.24,0.97l-0.37,2.46l-0.31,-0.58l-0.8,-0.21l-2.13,-1.53l-0.41,0.2l-0.29,-0.62l0.59,-2.11l0.07,-2.97l-0.66,-1.97l0.42,-0.51l0.48,-1.91l-0.24,-0.54l0.66,-3.04l-0.37,-5.41l-0.69,-1.56l0.35,-0.47l-0.47,-2.18l-2.1,-1.33l-0.05,-0.53l-0.55,-0.43l-0.1,-1.01l-0.92,-0.73l-0.55,-1.51l-0.64,-0.25l-1.44,0.32l-1.02,-0.2l-1.57,0.54l-1.15,-1.74l-1.5,-0.47l-0.19,-0.6l-1.35,-1.51l-3.81,-1.88l-0.51,-2.75l-3.06,-1.14l-0.65,-0.59l-0.52,-1.23l-2.15,-1.93l-2.19,-1.09l-1.45,-0.12l-3.44,-1.68l-2.85,0.98l-1.01,-0.4l-1.04,0.42l-0.36,0.68l-1.33,0.68l-0.5,0.71l0.03,0.64l-0.73,-0.22l-0.59,0.6l0.67,0.94l1.51,0.08l0.41,0.21l-3.03,0.23l-1.58,1.51l-0.91,0.45l-1.3,1.56l-1.56,1.03l-0.32,0.13l0.2,-0.48l-0.26,-0.54l-0.67,-0.04l-2.07,2.24l-2.2,0.23l-2.11,1.06l-0.78,0.03l-0.27,-2.03l-1.71,-2.23l-2.21,-1.0l-0.18,-0.41l-2.51,-1.5l2.8,1.33l1.21,-0.74l-0.0,-0.74l-1.32,-0.34l-0.35,0.55l-0.21,-1.01l-0.34,-0.1l0.12,-0.52l-0.49,-0.33l-1.4,0.61l-2.3,-0.76l0.65,-1.08l0.83,-0.1l1.03,-1.45l-0.91,-0.96l-0.46,0.13l-0.49,1.02l-0.44,-0.04l-0.81,0.56l-0.72,-0.9l-0.7,0.09l-0.17,0.38l-1.34,0.73l-0.14,0.68l0.28,0.46l-3.95,-1.35l-5.05,-0.71l0.11,-0.24l1.27,0.29l0.61,-0.53l2.1,0.39l0.23,-0.78l-0.94,-1.02l0.09,-0.69l-0.62,-0.29l-0.5,0.32l-0.28,-0.47l-1.9,0.19l-2.25,1.1l0.3,-0.64l-0.41,-0.58l-0.96,0.35l-0.58,-0.25l-0.23,0.44l0.2,0.71l-1.45,0.79l-0.4,0.64l-5.17,0.97l0.32,-0.52l-0.4,-0.52l-1.35,-0.28l-0.72,-0.53l0.69,-0.53l0.01,-0.78l-0.68,-0.13l-0.81,-0.66l-0.46,0.11l0.14,0.76l-0.42,1.77l-1.05,-1.39l-0.69,-0.45l-0.55,0.07l-0.3,0.71l0.82,1.77l-0.25,0.79l-1.39,0.99l-0.05,1.04l-0.6,0.22l-0.17,0.57l-1.48,0.55l0.28,-0.66l-0.22,-0.45l1.14,-1.03l0.07,-0.74l-0.4,-0.58l-1.18,-0.24l-0.42,-0.84l0.3,-1.7l-0.18,-1.61l-2.17,-1.12l-2.39,-2.46l0.32,-1.44l-0.15,-1.04ZM644.36,434.04l-0.94,0.26l0.4,-0.44l0.53,0.18ZM665.13,435.61l0.98,-0.28l0.35,0.31l0.08,0.72l-1.42,-0.75ZM770.53,454.92l0.42,0.56l-0.43,0.75l0.0,-1.31Z\", \"name\": \"Florida\"}, \"US-CT\": {\"path\": \"M823.41,156.51l2.83,-3.23l-0.07,-0.54l-1.31,-1.25l-3.5,-15.89l9.81,-2.41l0.6,0.46l0.65,-0.26l0.23,-0.58l14.16,-4.0l3.2,10.18l0.47,1.96l-0.04,1.69l-1.66,0.32l-0.92,0.81l-0.69,-0.36l-0.5,0.1l-0.18,0.91l-1.14,0.07l-1.27,1.27l-0.62,-0.14l-0.56,-1.02l-0.89,-0.09l-0.21,0.67l0.75,0.64l0.08,0.54l-0.89,-0.02l-1.02,0.87l-1.65,0.07l-1.15,0.94l-1.44,0.13l-1.21,0.93l-0.65,-1.0l-0.61,0.11l-1.01,2.46l-1.06,0.61l-0.25,1.02l-0.77,-0.26l-0.96,0.56l-0.09,0.85l-1.72,0.98l-1.94,2.27l-1.19,0.46l-0.24,0.38l-1.4,-1.23Z\", \"name\": \"Connecticut\"}, \"US-WA\": {\"path\": \"M38.51,55.06l0.37,-1.08l0.93,0.65l0.55,-0.14l0.54,-0.65l0.49,0.67l0.71,-0.01l0.17,-0.77l-0.98,-1.47l0.85,-0.83l-0.09,-1.36l0.49,-0.39l-0.1,-1.03l0.81,-0.27l0.05,0.5l0.48,0.41l0.95,-0.31l-0.09,-0.68l-1.44,-1.82l-1.84,-0.1l-0.15,0.32l-0.78,-0.82l0.26,-1.62l0.66,0.53l0.52,-0.07l0.29,-0.56l-0.17,-0.68l3.33,-0.52l0.25,-0.68l-2.59,-1.29l-0.05,-0.79l-0.67,-0.57l-1.3,-0.31l0.37,-4.73l-0.5,-1.29l0.25,-0.72l-0.52,-0.48l0.55,-3.93l0.04,-4.38l-0.56,-1.02l-0.04,-0.98l-1.56,-2.34l0.33,-4.24l-0.21,-1.29l0.78,-0.79l0.04,-0.71l0.97,-1.44l-0.6,-1.43l1.04,0.8l0.44,0.0l3.35,3.31l0.99,0.35l2.18,2.41l3.73,1.49l1.21,0.07l0.79,0.71l0.67,0.31l0.6,-0.15l1.57,1.07l1.49,0.47l1.28,0.28l1.22,-0.61l0.53,0.31l0.46,0.71l-0.05,1.24l0.55,0.74l0.8,-0.24l0.07,-0.75l0.44,0.03l0.63,1.39l-0.4,0.58l0.34,0.49l0.56,-0.04l0.73,-0.84l-0.38,-1.7l1.03,-0.24l-0.44,0.23l-0.22,0.69l1.27,4.41l-0.46,0.1l-1.67,1.72l0.22,-1.29l-0.22,-0.41l-1.31,0.31l-0.38,0.81l0.09,0.95l-1.37,1.7l-1.98,1.38l-1.06,1.41l-0.96,0.69l-1.1,1.67l-0.06,0.71l0.62,0.6l0.96,0.12l2.77,-0.48l1.22,-0.58l-0.03,-0.7l-0.64,-0.23l-2.94,0.79l-0.35,-0.3l3.23,-3.42l3.06,-0.88l0.89,-1.51l1.73,-1.54l0.53,0.57l0.54,-0.19l0.22,-1.81l-0.06,2.25l0.26,0.91l-0.98,-0.21l-0.64,0.77l-0.41,-0.73l-0.53,-0.19l-0.39,0.64l0.32,2.34l-0.21,-1.07l-0.67,-0.21l-0.46,0.69l-0.07,0.75l0.46,0.66l-0.63,0.58l-0.0,0.45l0.42,0.17l1.67,-0.57l0.25,1.09l-1.08,1.79l-0.08,1.05l-0.83,0.7l0.13,1.0l-0.85,-0.68l1.12,-1.44l-0.23,-0.96l-1.96,1.08l-0.38,0.64l-0.05,-2.11l-0.52,0.02l-1.03,1.59l-1.26,0.53l-1.14,1.87l-1.51,0.3l-0.46,0.44l-0.21,1.18l1.11,-0.03l-0.25,0.36l0.27,0.37l0.93,0.02l0.06,0.68l0.53,0.47l0.52,-0.27l0.35,-1.76l0.15,0.42l0.83,-0.15l1.11,1.48l1.31,-0.61l1.64,-1.48l0.98,-1.56l0.63,0.78l0.73,0.14l0.44,-0.23l-0.06,-0.86l1.56,-0.55l0.35,-0.94l-0.33,-1.26l0.22,-1.19l-0.18,-1.35l0.83,0.2l0.3,-0.92l-0.19,-0.75l-0.72,-0.63l0.89,-1.13l0.07,-1.75l1.24,-1.24l0.61,-1.37l1.61,-0.49l0.78,-1.15l-0.45,-0.66l-0.51,-0.02l-0.86,-1.3l0.16,-2.09l-0.26,-0.87l0.49,-0.79l0.06,-0.84l-1.15,-1.73l-0.63,-0.4l-0.17,-0.64l0.18,-0.5l0.59,0.24l0.53,-0.33l0.24,-1.8l0.79,-0.24l0.3,-1.0l-0.61,-2.32l0.44,-0.53l-0.03,-0.86l-0.96,-0.88l-0.95,0.3l-1.09,-2.65l0.93,-1.82l41.31,9.4l38.95,7.65l-10.13,55.39l1.04,3.0l0.13,2.0l-1.0,1.3l0.73,1.88l-31.18,-5.92l-1.67,0.79l-7.24,-1.02l-1.68,0.92l-4.19,-0.12l-3.18,0.45l-1.64,0.75l-0.88,-0.26l-1.2,0.3l-1.51,-0.23l-2.43,-0.94l-0.91,0.46l-3.45,0.51l-2.11,-0.71l-1.65,0.3l-0.31,-1.36l-1.09,-0.88l-4.34,-1.46l-2.32,-0.11l-1.15,-0.51l-1.27,0.21l-1.89,0.86l-4.49,0.58l-2.26,-1.01l-1.61,-1.15l-1.84,-0.51l-0.63,-0.81l0.64,-6.82l-0.46,-0.95l-0.22,-1.9l-0.98,-1.35l-1.96,-1.67l-1.59,-0.23l-1.31,0.28l-1.95,-3.24l-2.07,-0.23l-0.56,-0.3l-0.1,-0.52l-0.55,-0.47l-1.22,0.28l-0.81,-0.15l-1.0,0.52l-1.03,-1.77l-0.93,-0.23ZM61.97,39.77l0.16,0.74l-0.42,0.48l0.0,-0.91l0.26,-0.31ZM71.38,20.37l-0.61,0.87l-0.15,0.52l0.18,-1.38l0.58,-0.01ZM71.25,15.62l-0.09,-0.05l0.05,-0.04l0.04,0.1ZM70.48,15.47l-0.77,0.39l0.37,-0.68l-0.07,-0.6l0.22,-0.07l0.25,0.97ZM57.68,42.43l0.04,-0.02l-0.01,0.0l-0.03,0.01Z\", \"name\": \"Washington\"}, \"US-KS\": {\"path\": \"M477.93,239.62l0.44,0.63l0.76,0.18l1.04,0.8l2.19,-1.08l-0.0,0.75l1.08,0.79l0.23,1.44l-0.95,-0.15l-0.6,0.31l-0.17,0.97l-1.14,1.37l-0.06,1.14l-0.79,0.5l0.04,0.64l1.56,2.1l2.0,1.49l0.2,1.13l0.42,0.86l0.74,0.56l0.32,1.11l1.89,0.91l1.54,0.26l2.67,46.81l-31.54,1.48l-31.97,0.88l-31.98,0.26l-32.04,-0.37l1.21,-65.46l27.89,0.35l27.85,-0.14l27.84,-0.64l27.67,-1.12l1.65,1.23Z\", \"name\": \"Kansas\"}, \"US-WI\": {\"path\": \"M510.09,124.06l0.41,-0.27l0.28,-0.9l-0.45,-1.48l0.04,-1.91l0.7,-1.16l0.53,-2.25l-1.61,-2.91l-0.83,-0.36l-1.28,-0.01l-0.21,-2.31l1.67,-2.26l-0.05,-0.77l0.77,-1.55l1.95,-1.09l0.48,-0.75l0.97,-0.25l0.45,-0.75l1.16,-0.14l1.04,-1.56l-0.97,-12.11l1.03,-0.35l0.22,-1.1l0.73,-0.97l0.78,0.7l1.68,0.64l2.61,-0.56l3.27,-1.57l2.65,-0.82l2.22,-2.12l0.31,0.29l1.39,-0.11l1.25,-1.48l0.79,-0.58l1.04,-0.1l0.4,-0.52l1.07,0.99l-0.48,1.68l-0.67,1.01l0.23,1.61l-1.21,2.21l0.64,0.66l2.5,-1.09l0.72,-0.87l2.15,1.22l2.34,0.47l0.44,0.53l0.86,-0.13l1.6,0.7l2.23,3.54l15.47,2.52l4.65,1.96l1.67,-0.16l1.63,0.42l1.33,-0.59l3.17,0.71l2.18,0.09l0.85,0.41l0.56,0.89l-0.42,1.09l0.41,0.77l3.4,0.63l1.4,1.13l-0.16,0.71l0.59,1.11l-0.36,0.81l0.43,1.25l-0.78,1.25l-0.03,1.76l0.91,0.63l1.38,-0.26l1.02,-0.72l0.2,0.26l-0.79,2.44l0.04,1.31l1.32,1.46l0.84,0.35l-0.24,2.02l-2.42,1.2l-0.51,0.78l0.04,1.26l-1.61,3.49l-0.4,3.5l1.11,0.83l0.91,-0.04l0.5,-0.37l0.49,-1.37l1.82,-1.47l0.66,-2.54l1.06,-1.7l0.59,0.18l0.58,-0.71l0.87,-0.4l1.12,1.12l0.59,0.2l-0.28,2.18l-1.19,2.85l-0.57,5.58l0.23,1.11l0.8,0.93l0.07,0.52l-0.51,0.98l-1.3,1.34l-0.86,3.88l0.15,2.57l0.72,1.2l0.06,1.24l-1.07,3.23l0.12,2.11l-0.73,2.11l-0.28,2.46l0.59,2.02l-0.04,1.32l0.49,0.53l-0.21,1.7l0.92,0.78l0.54,2.44l1.2,1.54l0.08,1.69l-0.33,1.45l0.48,2.95l-44.2,4.6l-0.19,-0.79l-1.56,-2.19l-4.94,-0.84l-1.06,-1.35l-0.36,-1.68l-0.9,-1.21l-0.86,-4.89l1.04,-2.61l-0.09,-0.99l-0.71,-0.79l-1.44,-0.48l-0.71,-1.76l-0.47,-6.02l-0.7,-1.4l-0.52,-2.56l-1.15,-0.6l-1.1,-1.56l-0.93,-0.11l-1.17,-0.75l-1.71,0.09l-2.67,-1.79l-2.3,-3.5l-2.64,-2.1l-2.94,-0.53l-0.73,-1.24l-1.12,-1.0l-3.12,-0.45l-3.53,-2.74l0.45,-1.24l-0.12,-1.61l0.25,-0.81l-0.88,-3.11Z\", \"name\": \"Wisconsin\"}, \"US-OR\": {\"path\": \"M10.81,140.09l0.63,-3.94l1.32,-2.52l0.23,-1.22l-0.01,-1.26l-0.46,-0.66l-0.14,-1.12l-0.42,-0.32l-0.11,-1.85l2.73,-3.63l2.2,-4.73l0.1,-1.09l0.42,-0.27l0.01,0.79l0.73,0.1l0.42,-1.11l0.88,-0.84l0.23,0.94l1.39,0.27l-0.51,-2.64l-0.92,0.08l2.09,-3.81l1.11,-0.76l0.8,0.4l0.55,-0.33l-0.66,-1.35l-0.6,-0.3l1.71,-4.39l0.41,-0.38l0.04,-0.96l1.74,-5.49l0.97,-1.98l0.4,0.33l0.67,-0.29l-0.12,-0.97l-0.56,-0.32l0.96,-2.74l0.81,0.17l0.23,-0.45l-0.16,-0.52l-0.52,-0.28l0.54,-2.86l1.58,-2.7l0.83,-3.02l1.14,-1.76l0.97,-3.1l-0.08,-1.04l1.21,-1.1l0.04,-0.6l-0.46,-0.65l0.14,-0.52l0.51,0.64l0.45,0.05l0.39,-0.63l0.17,-1.39l-0.74,-0.72l0.5,-1.2l1.28,-0.78l0.05,-0.46l-0.86,-0.5l-0.26,-1.11l0.86,-2.17l-0.06,-1.44l0.92,-0.59l0.4,-0.85l0.07,-3.75l0.49,0.86l0.9,0.41l-0.04,0.91l0.55,0.53l0.43,-0.82l0.39,-0.14l-0.27,-0.98l1.12,0.84l1.53,0.0l1.45,-0.68l1.44,2.36l1.99,0.78l1.39,-0.67l0.91,0.06l1.72,1.51l0.77,1.04l0.21,1.9l0.43,0.78l-0.03,2.05l-0.39,1.24l0.19,0.93l-0.43,1.74l0.26,1.45l0.79,0.85l1.94,0.56l1.44,1.05l2.4,1.1l4.98,-0.53l2.9,-1.06l1.14,0.51l2.23,0.09l4.24,1.43l0.69,0.54l0.19,1.15l0.57,0.58l1.86,-0.27l2.11,0.71l3.79,-0.55l0.69,-0.42l2.19,0.93l1.64,0.24l1.19,-0.3l0.88,0.26l1.89,-0.78l3.07,-0.43l4.16,0.13l1.61,-0.91l7.16,1.02l0.96,-0.19l0.79,-0.58l31.27,5.93l0.23,1.81l0.93,1.82l1.16,0.63l1.96,1.86l0.57,2.45l-0.16,1.0l-3.69,4.54l-0.4,1.41l-1.39,2.63l-2.21,2.42l-0.65,2.68l-1.49,1.84l-2.23,1.5l-1.92,3.35l-1.49,1.27l-0.62,2.02l-0.12,1.87l0.28,0.92l0.56,0.61l0.54,0.04l0.39,-0.35l0.63,0.76l0.89,-0.05l0.07,0.88l0.8,0.95l-0.46,1.0l-0.65,0.06l-0.33,0.4l0.21,1.8l-1.03,2.56l-1.22,1.41l-6.86,39.15l-26.21,-4.99l-28.89,-6.05l-28.8,-6.61l-28.87,-7.22l-1.54,-2.51l0.26,-2.47l-0.29,-0.87Z\", \"name\": \"Oregon\"}, \"US-KY\": {\"path\": \"M583.03,306.53l0.35,-2.18l1.13,0.96l0.72,0.2l0.75,-0.36l0.46,-0.88l0.87,-3.55l-0.54,-1.75l0.38,-0.86l-0.1,-1.87l-1.27,-2.04l1.79,-3.21l1.24,-0.51l0.73,0.06l7.03,2.56l0.81,-0.2l0.65,-0.72l0.24,-1.93l-1.48,-2.14l-0.24,-1.44l0.2,-0.87l0.4,-0.52l1.1,-0.18l1.24,-0.83l3.0,-0.95l0.64,-0.51l0.15,-1.13l-1.53,-2.05l-0.08,-0.68l1.33,-1.97l0.14,-1.16l1.25,0.42l1.12,-1.33l-0.68,-2.0l1.92,0.9l1.72,-0.84l0.03,1.18l1.0,0.46l0.99,-0.94l0.02,-1.36l0.51,0.16l1.9,-0.96l4.41,1.52l0.64,0.94l0.86,0.18l0.59,-0.59l0.73,-2.53l1.38,-0.55l1.39,-1.34l0.86,1.29l0.77,0.42l1.16,-0.13l0.11,0.75l0.95,0.19l0.67,-0.62l0.03,-1.0l0.84,-0.38l0.26,-0.48l-0.25,-2.09l0.84,-0.4l0.34,-0.56l-0.06,-0.69l1.25,-0.56l0.34,-0.72l0.38,1.47l0.61,0.6l1.46,0.64l1.25,-0.0l1.11,0.81l0.53,-0.11l0.26,-0.55l1.1,-0.46l0.53,-0.69l0.04,-3.47l0.85,-2.18l1.02,0.18l1.55,-1.19l0.75,-3.46l1.04,-0.37l1.65,-2.23l0.0,-0.81l-1.18,-2.88l2.78,-0.59l1.54,0.81l3.85,-2.82l2.23,-0.46l-0.18,-1.07l0.36,-1.47l-0.32,-0.36l-1.22,-0.04l0.58,-1.39l-1.09,-1.54l1.65,-1.83l1.81,1.18l0.92,-0.11l1.93,-1.01l0.78,0.88l1.75,0.54l0.57,1.28l0.94,0.92l0.79,1.84l2.6,0.67l1.87,-0.57l1.63,0.27l2.18,1.85l0.96,0.43l1.28,-0.18l0.61,-1.31l0.99,-0.54l1.35,0.5l1.34,0.04l1.33,1.09l1.26,-0.69l1.41,-0.15l1.81,-2.55l1.72,-1.03l0.92,2.35l0.7,0.83l2.45,0.81l1.35,0.97l0.75,1.05l0.93,3.35l-0.37,0.45l0.09,0.72l-0.44,0.61l0.02,0.53l2.24,2.62l1.35,0.92l-0.08,0.89l1.34,0.97l0.58,1.35l1.55,1.2l0.98,1.62l2.14,0.84l1.09,1.12l2.14,0.25l-4.86,6.13l-5.06,4.15l-0.42,0.86l0.22,1.25l-2.07,1.93l0.04,1.64l-3.06,1.63l-0.8,2.38l-1.71,0.6l-2.7,1.83l-1.66,0.48l-3.39,2.42l-23.95,3.09l-8.8,1.42l-7.47,0.86l-7.68,0.46l-22.71,3.52l-0.64,-0.56l-3.63,0.09l-0.41,0.6l1.03,3.57l-22.99,2.73Z\", \"name\": \"Kentucky\"}, \"US-ME\": {\"path\": \"M837.01,56.27l0.87,-1.15l1.42,1.7l0.84,0.04l0.39,-2.12l-0.46,-2.19l1.7,0.36l0.73,-0.42l0.21,-0.52l-0.32,-0.7l-1.18,-0.47l-0.44,-0.62l0.19,-1.42l0.86,-2.02l2.08,-2.25l0.01,-0.98l-0.52,-0.93l1.02,-1.64l0.39,-1.51l-0.22,-0.92l-1.02,-0.35l-0.07,-1.42l-0.4,-0.43l0.55,-0.96l-0.04,-0.63l-1.0,-1.26l0.13,-1.73l0.37,-0.63l-0.15,-0.97l1.22,-1.93l-0.96,-6.17l5.58,-18.87l2.25,-0.23l1.14,3.18l0.55,0.43l2.54,0.56l1.83,-1.73l1.68,-0.83l1.24,-1.72l1.25,-0.12l0.64,-0.47l0.25,-1.43l0.42,-0.3l1.36,0.04l3.68,1.41l1.14,0.96l2.36,1.05l8.38,22.7l0.64,0.65l-0.19,1.26l0.64,0.86l-0.1,1.52l-0.33,0.05l-0.24,0.66l1.72,1.13l1.79,0.22l0.82,0.41l1.88,-0.19l1.25,-0.64l0.34,0.86l-0.59,1.43l1.69,1.86l0.28,2.69l2.72,1.68l0.98,-0.1l0.47,-0.74l-0.06,-0.5l0.36,0.08l0.25,0.49l0.64,0.07l1.41,1.11l0.27,0.75l1.27,0.94l0.04,0.47l-0.52,-0.14l-0.39,0.41l0.18,0.77l-0.76,-0.15l-0.35,0.4l0.16,0.63l0.81,0.53l0.55,0.92l0.48,0.17l0.16,-0.88l0.39,-0.17l0.8,0.32l0.25,-0.83l0.34,0.41l-0.31,0.85l-0.53,0.19l-1.21,3.24l-0.63,-0.04l-0.31,0.44l-0.55,-1.05l-0.72,0.03l-0.3,0.5l-0.56,0.06l-0.02,0.49l0.58,0.85l-0.9,-0.45l-0.33,0.63l0.26,0.52l-1.2,-0.28l-0.36,0.3l-0.37,0.78l0.07,0.45l0.44,0.08l0.07,1.21l-0.37,-0.57l-0.55,-0.06l-0.39,0.45l-0.2,1.09l-0.48,-1.53l-1.14,0.01l-0.68,0.75l-0.36,1.48l0.59,0.63l-0.83,0.63l-0.69,-0.46l-0.73,1.04l0.1,0.64l0.99,0.63l-0.35,0.21l-0.1,0.82l-0.46,-0.21l-0.85,-1.82l-1.03,-0.46l-0.39,0.22l-0.45,-0.41l-0.57,0.63l-1.24,-0.19l-0.26,0.85l0.78,0.4l0.01,0.37l-0.51,-0.05l-0.56,0.4l-0.09,0.7l-0.49,-1.02l-1.17,-0.02l-0.16,0.64l0.52,0.88l-1.44,0.96l0.84,1.11l0.08,1.06l0.53,0.65l-0.97,-0.41l-0.96,0.22l-1.2,-0.42l-0.17,-0.91l0.74,-0.28l-0.08,-0.56l-0.42,-0.49l-0.67,-0.12l-0.3,0.33l-0.23,-2.37l-0.37,-0.22l-1.1,0.27l0.04,1.96l-1.85,1.92l0.02,0.49l1.25,1.47l-0.64,0.96l-0.19,3.87l0.77,1.41l-1.08,1.72l-0.8,-0.19l-0.45,0.93l-0.62,-0.06l-0.41,-1.15l-0.73,-0.21l-0.52,1.03l0.11,0.69l-0.45,0.59l0.12,2.41l-0.95,-1.01l0.14,-1.28l-0.24,-0.59l-0.82,0.29l-0.08,2.01l-0.44,-0.25l0.15,-1.54l-0.47,-0.4l-0.68,0.49l-0.76,3.04l-0.77,-1.97l0.17,-1.21l-0.4,-0.27l-0.46,0.21l-1.05,2.59l0.35,0.53l0.85,-0.15l0.95,2.08l-0.28,-0.59l-0.51,-0.23l-0.66,0.3l-0.07,0.64l-1.38,-0.1l-2.16,3.17l-0.53,1.86l0.29,0.6l-0.68,0.65l0.51,0.43l0.91,-0.21l0.37,0.92l-0.77,0.3l-0.2,0.39l-0.4,-0.04l-0.51,0.57l-0.14,1.03l0.67,1.37l-0.08,0.68l-0.79,1.29l-0.94,0.61l-0.54,1.29l0.44,1.56l-0.4,2.81l-0.8,-0.33l-0.42,0.59l-1.02,-0.76l-0.57,-1.85l-0.93,-0.37l-2.36,-1.99l-0.76,-3.45l-13.24,-35.53ZM863.91,81.24l0.08,0.26l-0.08,0.23l0.03,-0.29l-0.04,-0.2ZM865.32,81.46l0.47,0.7l-0.04,0.47l-0.32,-0.25l-0.1,-0.93ZM867.66,78.32l0.42,0.82l-0.16,0.14l-0.42,-0.19l0.16,-0.77ZM877.03,64.89l-0.14,0.2l-0.03,-0.24l0.17,0.04ZM873.08,75.23l0.01,0.02l-0.03,0.03l0.01,-0.06Z\", \"name\": \"Maine\"}, \"US-OH\": {\"path\": \"M665.07,178.88l1.66,0.36l0.97,-0.31l1.75,1.07l2.07,0.26l1.47,1.17l1.7,0.24l-2.17,1.18l-0.12,0.47l0.42,0.24l2.45,0.19l1.39,-1.1l1.76,-0.25l3.39,0.96l0.92,-0.08l1.48,-1.3l1.73,-0.59l1.15,-0.97l1.91,-0.97l2.61,-0.03l1.09,-0.62l1.24,-0.06l1.07,-0.8l4.24,-5.46l4.53,-3.47l6.92,-4.36l5.83,28.04l-0.51,0.54l-1.28,0.43l-0.41,0.95l1.65,2.23l0.02,2.11l0.41,0.26l0.31,0.94l-0.04,0.76l-0.54,0.83l-0.5,4.08l0.18,3.21l-0.58,0.41l0.34,1.11l-0.35,1.74l-0.39,0.54l0.76,1.23l-0.25,1.87l-2.41,2.65l-0.82,1.86l-1.37,1.5l-1.24,0.67l-0.6,0.7l-0.87,-0.92l-1.18,0.14l-1.32,1.74l-0.09,1.32l-1.78,0.85l-0.78,2.25l0.28,1.58l-0.94,0.85l0.3,0.67l0.63,0.41l0.27,1.3l-0.8,0.17l-0.5,1.6l0.06,-0.93l-0.91,-1.26l-1.53,-0.55l-1.07,0.71l-0.82,1.98l-0.34,2.69l-0.53,0.82l1.22,3.58l-1.27,0.39l-0.28,0.42l-0.25,3.12l-2.66,1.2l-1.0,0.05l-0.76,-1.06l-1.51,-1.1l-2.34,-0.73l-1.16,-1.92l-0.31,-1.14l-0.42,-0.33l-0.73,0.13l-1.84,1.17l-1.1,1.28l-0.4,1.05l-1.43,0.15l-0.87,0.61l-1.11,-1.0l-3.14,-0.59l-1.37,0.72l-0.53,1.25l-0.71,0.05l-3.04,-2.26l-1.93,-0.29l-1.77,0.56l-2.14,-0.52l-0.55,-1.54l-0.96,-0.97l-0.63,-1.38l-2.03,-0.76l-1.14,-1.01l-0.97,0.26l-1.31,0.89l-0.46,0.03l-1.79,-1.23l-0.61,0.2l-0.6,0.7l-8.67,-55.57l20.65,-4.25ZM675.61,181.3l0.53,-0.79l0.67,0.41l-0.48,0.35l-0.72,0.03Z\", \"name\": \"Ohio\"}, \"US-OK\": {\"path\": \"M399.11,359.23l-0.05,-42.02l-0.39,-0.4l-51.81,-0.82l0.31,-10.23l36.69,0.74l35.99,-0.07l35.98,-0.86l35.56,-1.62l0.6,10.68l4.55,24.34l1.41,37.87l-1.2,-0.22l-0.29,-0.36l-2.13,-0.21l-0.82,-0.79l-2.11,-0.39l-1.77,-2.05l-1.23,-0.22l-2.25,-1.56l-1.5,-0.4l-0.8,0.46l-0.23,0.88l-0.82,0.24l-0.46,0.62l-2.47,-0.14l-1.79,-1.48l-2.3,1.29l-1.16,0.2l-0.19,0.56l-0.63,0.28l-2.12,-0.77l-1.7,1.18l-2.06,0.51l-0.83,1.37l-1.48,0.06l-0.57,1.25l-1.26,-1.55l-1.7,-0.1l-0.32,-0.58l-1.21,-0.46l-0.02,-0.96l-0.44,-0.5l-1.24,-0.18l-0.73,1.38l-0.66,0.11l-0.84,-0.5l-0.97,0.07l-0.71,-1.51l-1.09,-0.35l-1.17,0.57l-0.45,1.7l-0.7,-0.08l-0.49,0.43l0.29,0.73l-0.51,1.68l-0.43,0.19l-0.86,-1.45l0.39,-1.65l-0.75,-0.86l-0.8,0.18l-0.49,0.76l-0.84,-0.18l-0.92,0.98l-1.07,0.13l-0.53,-1.36l-1.99,-0.19l-0.3,-1.48l-1.19,-0.53l-0.82,0.33l-2.12,2.15l-1.21,0.51l-0.97,-0.38l0.19,-1.25l-0.28,-1.13l-2.33,-0.67l-0.07,-2.18l-0.43,-0.55l-2.11,0.39l-2.52,-0.25l-0.64,0.26l-0.81,1.21l-0.95,0.06l-1.76,-1.77l-0.97,-0.12l-1.5,0.56l-2.68,-0.63l-1.86,-1.0l-1.05,0.25l-2.46,-0.3l-0.17,-2.12l-0.85,-0.87l-0.43,-1.02l-1.16,-0.41l-0.7,-0.83l-0.83,0.08l-0.44,1.64l-2.22,-0.68l-1.07,0.6l-0.96,-0.09l-3.79,-3.78l-1.12,-0.43l-0.8,0.08Z\", \"name\": \"Oklahoma\"}, \"US-ID\": {\"path\": \"M132.48,121.36l-0.34,-0.44l0.08,-1.99l0.53,-1.74l1.42,-1.22l2.11,-3.59l1.68,-0.92l1.39,-1.52l1.08,-2.15l0.05,-1.22l2.21,-2.41l1.43,-2.7l0.37,-1.37l2.04,-2.26l1.89,-2.81l0.03,-1.01l-0.79,-2.95l-2.13,-1.94l-0.87,-0.36l-0.85,-1.61l-0.41,-3.02l-0.59,-1.19l0.94,-1.19l-0.12,-2.35l-1.04,-2.69l10.12,-55.42l13.39,2.35l-3.54,20.71l1.29,2.89l1.0,1.27l0.27,1.55l1.17,1.76l-0.12,0.83l0.39,1.14l-0.99,0.95l0.83,1.76l-0.83,0.11l-0.28,0.71l1.93,1.68l1.03,2.04l2.24,1.22l0.54,1.58l1.09,1.33l1.49,2.79l0.08,0.68l1.64,1.81l0.01,1.88l1.79,1.71l-0.07,1.35l0.74,0.19l0.9,-0.58l0.36,0.46l-0.36,0.55l0.07,0.54l1.11,0.96l1.61,0.15l1.81,-0.36l-0.63,2.61l-0.99,0.54l0.25,1.14l-1.83,3.73l0.06,1.72l-0.81,0.07l-0.37,0.54l0.6,1.33l-0.62,0.9l-0.03,1.16l0.96,0.93l-0.37,0.81l0.28,1.01l-1.57,0.43l-1.21,1.41l0.1,1.11l0.46,0.77l-0.13,0.73l-0.83,0.77l-0.2,1.52l1.48,0.63l1.38,1.79l0.78,0.27l1.08,-0.35l0.56,-0.8l1.85,-0.41l1.21,-1.28l0.81,-0.29l0.15,-0.76l0.78,0.81l0.23,0.71l1.05,0.64l-0.42,1.23l0.73,0.95l-0.34,1.38l0.57,1.34l-0.21,1.61l1.54,2.64l0.31,1.73l0.82,0.37l0.67,2.08l-0.18,0.98l-0.76,0.64l0.51,1.89l1.24,1.16l0.3,0.79l0.81,0.08l0.86,-0.37l1.04,0.93l1.06,2.79l-0.5,0.81l0.89,1.83l-0.28,0.6l0.11,0.98l2.29,2.41l0.97,-0.14l-0.01,-1.14l1.07,-0.89l0.93,-0.22l4.53,1.62l0.69,-0.32l0.67,-1.35l1.19,-0.39l2.25,0.93l3.3,-0.1l0.96,0.88l2.29,-0.58l3.23,0.78l0.45,-0.49l-0.67,-0.76l0.26,-1.06l0.74,-0.48l-0.07,-0.96l1.23,-0.51l0.48,0.37l1.07,2.11l0.12,1.11l1.36,1.95l0.73,0.45l-6.27,53.85l-47.47,-6.31l-46.96,-7.72l6.88,-39.16l1.12,-1.18l1.07,-2.67l-0.21,-1.74l0.74,-0.15l0.77,-1.62l-0.9,-1.27l-0.18,-1.2l-1.24,-0.08l-0.64,-0.81l-0.88,0.29Z\", \"name\": \"Idaho\"}, \"US-WY\": {\"path\": \"M218.62,206.98l10.1,-86.59l25.45,2.74l26.79,2.4l26.83,1.91l27.84,1.46l-3.67,87.1l-27.31,-1.41l-28.2,-1.97l-29.69,-2.63l-28.14,-3.02Z\", \"name\": \"Wyoming\"}, \"US-UT\": {\"path\": \"M220.28,185.78l-2.51,21.5l0.35,0.45l32.23,3.42l-8.32,87.13l-42.53,-4.67l-42.4,-5.77l16.08,-108.32l47.1,6.26Z\", \"name\": \"Utah\"}, \"US-IN\": {\"path\": \"M600.87,189.59l1.42,0.87l2.1,0.15l1.52,-0.38l2.63,-1.39l2.73,-2.1l32.14,-4.8l8.96,57.41l-0.66,1.15l0.3,0.92l0.81,0.79l-0.66,1.14l0.49,0.8l1.12,0.04l-0.36,1.14l0.18,0.51l-1.81,0.29l-3.18,2.55l-0.43,0.17l-1.4,-0.81l-3.46,0.91l-0.09,0.78l1.19,3.1l-1.4,1.88l-1.18,0.49l-0.45,0.89l-0.31,2.6l-1.11,0.88l-1.06,-0.24l-0.47,0.47l-0.85,1.95l0.05,3.13l-0.39,1.0l-1.38,0.85l-0.93,-0.68l-1.24,0.01l-1.47,-0.69l-0.62,-1.84l-1.89,-0.73l-0.44,0.3l-0.04,0.5l0.83,0.68l-0.62,0.31l-0.89,-0.35l-0.36,0.29l0.5,1.42l-1.08,0.68l0.14,2.37l-1.06,0.65l-0.0,0.83l-0.16,0.37l-0.25,-1.01l-1.6,0.18l-1.4,-1.69l-0.5,-0.08l-1.67,1.5l-1.57,0.69l-1.07,2.89l-0.81,-1.07l-2.79,-0.77l-1.11,-0.61l-1.08,-0.18l-1.76,0.92l-0.64,-1.02l-0.58,-0.18l-0.53,0.56l0.64,1.86l-0.34,0.84l-0.28,0.09l-0.02,-1.18l-0.42,-0.4l-0.58,0.01l-1.46,0.79l-1.41,-0.84l-0.85,0.0l-0.48,0.95l0.71,1.55l-0.49,0.74l-1.15,-0.39l-0.07,-0.54l-0.53,-0.44l0.55,-0.63l-0.35,-3.09l0.96,-0.78l-0.07,-0.58l-0.44,-0.23l0.69,-0.46l0.25,-0.61l-1.17,-1.47l0.46,-1.16l0.32,0.19l1.39,-0.55l0.33,-1.8l0.55,-0.4l0.44,-0.92l-0.06,-0.83l1.52,-1.07l0.06,-0.69l-0.41,-0.93l0.57,-0.86l0.14,-1.29l0.87,-0.51l0.4,-1.91l-1.08,-2.54l0.06,-1.91l-0.93,-0.91l-0.61,-1.5l-1.05,-0.78l-0.04,-0.58l0.92,-1.39l-0.63,-2.25l1.27,-1.31l-6.5,-50.67Z\", \"name\": \"Indiana\"}, \"US-IL\": {\"path\": \"M540.1,225.5l0.86,-0.35l0.37,-0.67l-0.23,-2.33l-0.73,-0.93l0.15,-0.41l0.72,-0.69l2.42,-0.98l0.71,-0.65l0.63,-1.68l0.17,-2.11l1.65,-2.47l0.27,-0.94l-0.03,-1.22l-0.59,-1.95l-2.23,-1.88l-0.11,-1.77l0.67,-2.38l0.45,-0.37l4.6,-0.85l0.81,-0.41l0.82,-1.12l2.55,-1.0l1.43,-1.56l0.39,-3.28l1.42,-1.46l0.29,-0.74l0.33,-4.37l-0.76,-2.14l-4.02,-2.47l-0.28,-1.5l-0.48,-0.82l-3.64,-2.48l44.57,-4.64l-0.01,2.65l0.57,2.59l1.38,2.49l1.3,0.95l0.76,2.6l1.26,2.71l1.42,1.85l6.6,51.47l-1.22,1.13l-0.1,0.69l0.67,1.76l-0.84,1.09l-0.03,1.11l1.19,1.09l0.56,1.41l0.89,0.82l-0.1,1.8l1.06,2.31l-0.28,1.49l-0.87,0.56l-0.21,1.47l-0.59,0.93l0.34,1.2l-1.48,1.13l-0.23,0.41l0.28,0.7l-0.93,1.17l-0.31,1.19l-1.64,0.67l-0.63,1.67l0.15,0.8l0.97,0.83l-1.27,1.15l0.42,0.76l-0.49,0.23l-0.13,0.54l0.43,2.94l-1.15,0.19l0.08,0.45l0.91,0.78l-0.48,0.17l-0.03,0.64l0.83,0.29l0.04,0.42l-1.31,1.97l-0.25,1.19l0.59,1.22l0.7,0.64l0.37,1.08l-3.31,1.22l-1.19,0.82l-1.24,0.24l-0.77,1.01l-0.18,2.04l1.7,2.81l0.07,0.54l-0.53,1.19l-0.96,0.03l-6.3,-2.43l-1.08,-0.08l-1.57,0.64l-0.68,0.72l-1.44,2.95l0.06,0.66l-1.18,-1.2l-0.79,0.14l-0.35,0.47l0.59,1.13l-1.24,-0.79l-0.01,-0.68l-1.6,-2.21l-0.4,-1.12l-0.75,-0.37l-0.05,-0.49l0.94,-1.35l0.2,-1.03l-0.32,-1.01l-1.44,-2.02l-0.47,-3.18l-2.26,-0.99l-1.55,-2.14l-1.95,-0.82l-1.72,-1.34l-1.56,-0.14l-1.82,-0.96l-2.32,-1.78l-2.34,-2.44l-0.36,-1.95l2.37,-6.85l-0.25,-2.32l0.98,-2.06l-0.38,-0.84l-2.66,-1.45l-2.59,-0.67l-1.29,0.45l-0.86,1.45l-0.9,0.15l-1.3,-1.9l-0.43,-1.52l0.16,-0.87l-0.54,-0.91l-0.29,-1.65l-0.83,-1.36l-0.94,-0.9l-4.11,-2.52l-1.01,-1.64l-4.53,-3.53l-0.73,-1.9l-1.04,-1.21l-0.04,-1.6l-0.96,-1.48l-0.75,-3.54l0.1,-2.94l0.6,-1.28ZM585.53,295.46l0.05,0.05l0.04,0.04l-0.05,-0.0l-0.04,-0.09Z\", \"name\": \"Illinois\"}, \"US-AK\": {\"path\": \"M64.88,530.75l0.06,-0.04l0.04,0.06l-0.06,-0.01l-0.05,-0.0ZM66.64,530.24l1.13,0.16l0.11,0.52l-1.21,0.78l-0.23,-0.24l0.3,-0.47l-0.09,-0.76ZM69.51,530.52l0.7,-0.13l0.3,-0.66l2.1,-0.44l2.68,0.09l1.86,0.74l0.99,0.81l0.04,2.23l0.65,0.89l0.77,-0.37l-0.07,-0.76l0.56,0.36l-0.1,0.53l1.05,1.08l-1.24,-0.51l-0.68,0.56l-0.08,-0.76l-1.26,-0.01l-0.76,-0.43l-0.82,0.28l-1.12,-0.26l-0.44,-0.54l0.4,-0.34l0.95,0.84l0.47,-0.03l0.2,-0.5l-0.7,-1.62l-1.11,-0.6l-1.17,0.32l-0.66,0.82l-1.29,0.37l-0.52,-0.37l-0.59,0.38l-0.74,-0.26l-0.58,0.37l0.21,-2.07ZM81.1,534.87l0.81,-0.72l-0.68,-1.59l0.14,-0.29l1.83,-1.05l3.86,-0.11l2.68,0.81l0.57,-0.32l1.04,0.3l0.88,1.1l0.7,-0.06l0.9,-1.66l2.68,-0.78l1.06,0.33l1.28,-0.46l0.86,0.05l-0.14,0.54l0.5,0.59l1.15,0.33l0.6,-0.91l-0.56,-0.35l-0.31,0.15l0.28,-0.7l-0.2,-0.46l2.24,-2.37l1.05,0.07l0.63,0.82l0.66,-0.29l-0.11,-0.63l-1.04,-0.94l0.19,-0.63l0.96,-0.57l3.31,-0.22l-0.15,-0.63l0.81,-0.73l0.76,-0.04l1.14,-1.23l-0.94,-0.25l-0.69,0.62l-0.61,-0.12l-0.59,0.33l-5.45,-1.21l0.08,-1.16l-0.36,-0.69l0.61,-0.46l0.52,-0.18l0.49,0.51l-0.04,1.27l0.91,-0.05l0.15,-0.75l-0.06,-0.85l-0.98,-1.22l0.01,-0.82l-0.67,-0.19l-0.29,0.86l-0.73,0.37l-0.19,0.06l0.24,-0.27l-0.27,-0.52l-0.4,-0.11l-0.76,0.98l-0.97,0.24l-0.67,2.38l-0.33,0.05l-0.36,-0.33l0.03,-4.92l-0.66,-0.64l-1.23,0.46l0.07,-0.72l-0.68,-0.92l0.27,-0.42l-0.12,-1.01l-2.89,-0.21l-0.54,-0.39l-1.37,-0.13l-0.43,-0.56l-1.2,0.69l-0.99,-0.27l-0.29,-0.65l1.23,-0.02l-0.05,-0.92l0.46,-0.72l1.47,-0.11l-0.03,-0.81l-1.33,-0.74l0.14,-0.43l0.85,-0.72l1.34,-0.01l0.43,-0.43l0.58,-4.63l1.27,-1.41l-0.84,-0.73l1.97,-1.03l1.58,0.21l0.44,-0.55l-0.81,-0.46l-0.34,-0.75l-0.6,0.5l-0.57,-0.1l-1.3,0.72l-2.17,0.25l-0.12,0.5l0.5,0.82l-0.72,0.78l-0.48,-0.47l-2.21,-0.3l-2.19,-1.17l-1.56,-1.56l0.03,-0.37l0.7,-0.05l0.04,-0.67l-0.61,-1.28l-0.09,-1.54l0.39,-0.61l-0.72,-0.34l-0.58,-1.19l0.93,-0.28l0.14,-0.6l-1.09,-0.61l1.52,0.14l0.51,-0.46l0.88,0.03l0.05,0.6l1.07,1.2l-1.21,0.44l-0.39,0.39l0.31,0.47l1.11,-0.1l0.47,0.28l1.12,-0.22l0.18,0.15l-0.72,1.13l0.74,0.73l1.63,0.09l0.68,-0.64l-0.26,-0.92l0.44,-0.39l-0.14,-1.27l-0.59,-0.28l-1.31,0.1l-1.81,-1.44l0.01,-0.63l-0.97,-1.12l0.81,0.16l0.53,-0.4l-1.18,-1.08l0.63,-0.51l-0.14,-0.67l1.25,-0.21l0.53,0.32l0.83,-0.05l0.73,-0.46l-0.08,-0.52l-3.03,-0.29l-1.91,0.63l-0.4,0.68l-0.19,-0.22l0.72,-1.02l-0.63,-1.4l0.68,0.09l0.47,-0.54l-0.48,-1.21l0.96,0.46l0.42,-0.51l-0.63,-0.98l1.73,1.01l0.42,-1.53l0.59,-0.35l3.77,-0.6l0.5,0.35l0.25,0.85l-0.36,0.21l0.14,0.47l1.2,0.19l0.3,-0.42l-0.18,-1.0l1.6,-0.11l0.29,-0.63l-1.51,-0.29l0.59,-0.27l0.16,-0.74l0.9,-0.32l1.37,1.16l0.47,-0.57l-0.32,-0.84l0.37,-0.03l1.02,0.42l1.03,1.2l-0.04,0.6l-0.87,-0.06l-0.35,0.64l1.72,0.3l0.1,0.67l1.21,0.8l3.02,0.17l1.92,-0.37l0.11,0.59l2.89,1.88l2.0,0.37l1.83,-0.33l0.67,-0.63l0.41,-1.78l0.72,-1.29l-0.14,-1.81l0.74,0.39l1.24,-0.12l0.86,-0.71l-0.17,-1.62l0.3,-0.04l0.11,-0.44l-0.25,-0.34l-0.83,-0.45l-1.45,0.34l-0.98,-1.22l-1.22,0.1l-0.5,-0.38l-2.79,-0.15l-0.75,0.51l0.35,-0.85l-0.56,-1.94l-1.57,-0.24l-3.01,-2.71l-1.14,-0.28l-0.95,-0.93l-0.77,0.17l-3.27,-3.98l-0.31,-1.07l0.73,-0.34l0.39,-0.82l-0.53,-1.14l0.14,-0.32l0.52,0.26l1.05,-0.26l1.2,1.12l0.36,-0.78l-2.39,-3.21l-1.44,-1.39l-1.03,-2.33l0.73,0.11l1.02,0.72l1.24,-0.42l0.31,0.63l0.57,0.29l1.08,0.2l0.98,-0.22l1.81,0.53l1.37,1.81l1.19,0.53l0.56,-0.47l-0.6,-1.16l1.94,0.62l0.58,0.79l2.66,0.53l1.79,1.18l0.34,0.64l-0.69,0.11l-0.63,0.77l-1.35,-0.42l-0.12,0.69l0.75,0.66l0.19,1.01l2.13,1.87l1.3,0.71l-0.16,0.68l2.13,1.1l0.66,1.36l0.45,0.21l2.16,-0.88l0.7,1.0l-0.4,0.08l0.01,0.51l0.87,0.33l0.96,-0.71l-0.06,-1.11l-0.58,-0.85l0.4,0.0l1.01,2.11l1.88,1.12l0.85,-0.28l0.74,-1.61l-0.17,-0.25l-1.34,-0.47l-0.61,-1.11l-1.03,-0.61l-1.16,0.14l-0.44,-0.38l-0.48,-1.61l1.18,-0.54l0.78,0.4l0.37,-0.59l-0.87,-1.38l-1.35,-0.8l0.0,-1.23l-0.47,-0.25l-1.01,0.43l-3.2,-3.27l0.71,-1.39l0.04,-2.41l-2.35,-5.81l-1.25,-1.7l-0.54,-1.91l1.29,-0.66l1.24,-1.29l3.37,2.86l2.53,1.62l1.6,0.63l4.17,0.25l2.43,-1.65l1.96,0.17l1.51,-0.27l4.46,2.3l3.16,0.43l0.14,0.68l-0.34,0.08l-0.14,0.66l0.53,0.23l0.34,1.4l0.55,-0.29l0.38,-1.21l1.25,0.75l0.88,0.14l0.29,-0.35l-0.22,-0.39l-1.5,-1.03l0.05,-0.38l0.97,-0.06l0.34,0.13l0.34,1.14l0.55,0.33l0.18,-0.22l0.76,0.21l3.84,2.25l2.9,0.43l2.71,-0.19l0.31,0.85l0.85,0.61l0.02,0.66l1.47,0.88l-0.91,-0.04l-0.91,-0.49l-0.93,0.25l0.42,0.83l-0.26,0.43l0.18,0.59l0.73,-0.04l1.12,0.51l1.03,-0.39l1.07,0.65l0.92,-0.02l0.21,0.47l-0.71,0.01l-0.29,0.34l1.75,2.14l1.64,0.18l2.21,1.14l1.47,1.72l0.67,-0.07l0.41,0.37l-1.57,0.55l-0.18,0.63l2.16,1.28l-0.22,0.75l1.74,1.13l0.58,0.79l0.82,-0.05l1.56,0.52l0.51,0.45l0.14,0.61l2.14,0.56l1.96,1.16l1.82,1.63l0.39,0.96l1.19,0.37l1.05,0.92l-0.12,0.41l0.45,0.47l1.93,1.39l4.48,2.43l1.5,1.94l1.21,0.76l1.38,0.67l0.93,0.04l0.77,0.37l0.03,0.38l1.6,0.03l1.23,0.61l0.47,0.58l0.29,-0.26l1.69,1.44l1.68,2.36l1.24,0.84l0.65,1.11l1.25,0.49l-27.91,60.77l0.17,0.48l1.69,1.44l0.83,-0.19l1.44,1.5l2.05,-0.3l2.16,0.82l-0.98,1.08l-0.15,0.61l0.53,1.11l1.01,1.05l0.05,1.28l2.81,5.56l-0.47,2.71l0.54,0.33l1.98,-0.35l0.06,0.23l-1.19,0.71l0.29,0.54l0.84,-0.22l1.03,0.71l0.36,1.46l-0.28,0.03l-0.1,0.51l0.26,0.36l1.11,0.26l-0.24,0.59l0.49,0.49l-0.11,0.51l-0.36,-0.03l-0.12,-0.59l-0.85,-0.8l-0.47,-0.03l-1.0,0.68l-0.32,-0.86l-1.11,-0.57l-1.15,-1.83l0.58,-0.48l-0.09,-0.3l-0.99,-0.27l-0.56,-1.13l-0.02,-1.29l-1.34,-2.12l0.09,-0.76l-1.17,-0.46l-1.47,-1.72l-0.33,-0.8l-1.65,-1.66l1.58,-0.72l-0.4,0.98l0.71,0.53l0.48,-0.34l0.48,-1.49l0.98,0.8l0.73,-0.31l-0.53,-0.92l-0.81,-0.46l-0.73,-1.81l-0.41,-0.17l-2.16,1.02l-2.27,-0.06l-1.73,-1.01l-1.8,-1.85l0.52,-0.4l0.26,-0.96l-0.45,-1.04l-0.92,0.09l-0.12,0.64l-0.81,-0.05l-1.0,-1.05l-3.3,-2.31l-5.2,-1.56l-0.48,-1.29l0.16,-0.55l-1.83,-0.99l-0.64,-1.23l0.85,-0.63l0.26,-0.77l1.16,-0.21l0.15,-0.7l-0.98,-0.3l-2.56,1.0l-1.03,-0.01l-0.22,-0.7l-0.85,-0.75l1.1,-0.51l0.19,-0.4l-0.31,-0.45l-0.64,-0.02l-0.47,-0.8l0.14,-0.59l-0.49,-1.17l-0.45,-0.22l-0.62,0.19l-0.57,-0.49l0.25,-0.73l0.46,-0.09l1.22,0.53l0.42,-0.5l-0.16,-0.48l-1.49,-0.88l-1.82,0.34l-0.6,-0.61l-1.17,-0.28l-0.22,-0.32l0.32,-1.1l-0.72,-0.3l0.35,-0.97l-0.33,-0.29l-2.04,0.78l-0.28,-0.64l-1.38,-0.22l-0.75,0.57l0.31,0.89l-1.75,-0.34l-0.8,0.99l0.26,0.62l0.9,-0.03l-0.2,0.34l-1.52,0.34l-0.23,0.63l0.38,0.29l1.02,-0.16l0.49,0.83l-0.47,0.61l-0.59,-0.24l-0.7,0.58l0.05,0.63l-0.31,0.35l-0.27,-0.15l-0.68,0.39l-1.38,-1.05l0.03,-0.72l-1.08,-0.12l0.11,-0.8l-0.55,-0.46l-1.0,1.06l-1.09,-0.68l-0.44,0.5l-0.48,-0.1l-0.2,0.41l-0.8,-0.43l-0.29,0.55l-0.7,-0.52l-1.3,0.56l-0.16,-0.45l-0.91,-0.04l-0.56,0.81l-1.73,0.25l-1.02,-0.92l-0.6,0.32l-0.44,-0.36l-1.29,0.01l-0.44,-1.08l0.64,0.17l0.17,-0.48l0.68,0.04l0.89,0.91l0.56,-0.11l0.11,-0.54l0.9,0.16l1.67,-0.74l0.32,-0.52l-0.22,-0.4l-2.72,-0.16l-0.79,-1.25l1.54,-1.19l1.91,-0.52l0.81,-0.85l0.52,-0.09l0.76,-1.03l0.15,-1.27l1.37,0.34l3.53,-0.14l0.24,1.07l0.66,0.57l1.41,0.31l2.69,2.59l0.5,-0.37l-0.13,-0.93l-0.99,-0.67l-1.76,-2.54l1.94,-0.66l2.25,0.33l0.05,-0.75l-1.75,-0.86l-1.62,0.15l-0.71,0.63l-1.07,-0.92l-0.7,-0.18l0.17,-0.32l-0.28,-0.7l-1.24,0.32l-1.57,-0.23l-0.99,0.48l-1.49,-0.52l-1.37,0.05l-0.78,0.4l-0.2,0.55l-1.24,-0.08l-1.92,0.49l-0.59,0.81l-0.62,0.26l-0.75,-0.02l-0.97,-1.32l-1.1,-0.29l-0.3,0.28l0.16,0.51l0.44,0.07l0.66,2.11l-0.91,0.44l-2.4,-0.95l-0.46,0.21l0.03,0.68l0.78,0.42l-0.2,0.15l-0.56,0.01l-0.54,-1.57l-0.76,0.74l-0.24,-0.5l-0.88,0.16l-0.13,0.57l-0.85,-0.44l-0.36,0.28l0.3,0.67l-1.93,-0.49l-0.81,1.18l-0.83,0.28l-0.17,1.22l0.33,0.36l0.71,-0.05l1.13,0.82l0.76,1.64l-0.81,0.65l-1.11,0.16l-1.09,-0.54l-0.98,0.53l-0.75,-0.18l-0.37,0.73l-1.4,-0.13l-0.46,0.82l-0.5,-0.62l-0.4,0.44l-1.47,0.04l-1.12,-0.71l-1.09,0.61l-0.67,-0.22l-0.91,0.37l-0.64,-0.78l-0.94,0.73l-0.49,-0.21l-0.32,0.36l-0.62,-0.1l-0.41,-0.5l-0.83,0.37l-2.51,-0.14l-0.57,0.44l0.28,1.17l-0.59,0.14l-1.31,-0.59l-0.58,0.52l-0.3,-0.46l-2.04,0.38l-0.15,-0.68l-0.48,-0.37l-0.79,0.47l-0.83,0.0l-0.29,0.61l-0.03,-0.62l-0.42,-0.3l-1.95,-0.18l-0.77,0.39l-0.34,-0.37l-0.72,-0.1l-1.8,0.43l-0.28,0.75l-0.4,-0.03l-0.82,0.77l-2.9,-0.76l-0.87,-0.79l-0.66,0.16l-0.84,-0.82l-1.36,-0.26l-0.93,0.26ZM89.01,536.65l-0.02,0.01l-0.0,0.03l0.02,-0.04ZM89.06,536.61l0.02,-0.01l-0.01,0.01l-0.0,0.01ZM91.61,484.22l-0.0,0.01l-0.0,-0.01l0.01,0.0ZM87.17,484.0l-0.0,-0.0l0.01,-0.0l-0.0,0.01l-0.01,-0.0ZM186.66,475.29l-0.0,0.02l-0.01,-0.01l0.01,-0.0ZM156.69,531.75l-0.95,1.06l-0.87,0.02l-0.13,-0.28l0.69,-0.51l1.26,-0.28ZM151.45,532.97l-0.11,0.02l0.12,-0.04l-0.01,0.02ZM152.06,535.54l-0.09,-0.14l0.41,-0.11l-0.1,0.3l-0.22,-0.05ZM116.92,535.18l-0.13,0.11l-0.06,-0.02l0.04,-0.19l0.16,0.1ZM90.72,536.66l0.27,-0.19l0.07,0.3l-0.17,0.07l-0.17,-0.19ZM121.46,528.8l-0.0,-0.02l0.04,0.01l-0.03,0.01ZM186.96,558.95l-0.09,-1.09l0.4,-0.11l0.13,0.57l-0.44,0.62ZM196.09,568.76l2.06,0.17l0.88,-0.72l0.4,-0.93l0.62,0.05l0.66,-0.45l0.12,-0.56l3.59,0.11l1.22,2.1l-0.59,0.6l0.11,1.69l1.05,0.86l0.25,0.97l0.46,0.34l0.11,1.76l1.72,2.25l0.24,1.0l-1.26,-0.23l-0.94,0.69l-0.72,1.06l-0.71,-1.34l-1.02,-0.73l0.15,-0.58l-0.32,-1.25l0.48,-1.41l-0.8,-0.55l0.41,-2.32l-0.18,-1.24l0.62,-1.53l-0.66,-0.25l-0.62,0.87l-0.78,-0.09l0.03,0.58l-0.38,0.41l0.37,1.24l-0.41,0.99l0.15,1.56l-0.41,1.27l0.03,2.19l-0.37,0.45l-0.41,-0.46l0.02,-1.59l-0.29,-0.45l-0.66,0.28l-1.11,-0.29l0.47,-0.38l0.24,-0.99l-0.35,-1.47l1.14,0.14l0.45,-0.45l-0.11,-0.36l-0.86,-0.52l-0.27,0.12l-0.01,-1.01l-0.61,-0.4l-0.96,1.15l0.46,0.38l-0.33,0.4l-0.04,-0.54l-0.68,-0.29l0.29,-0.67l-0.28,-0.54l-0.39,-0.02l-0.2,-0.62l-0.47,-0.15l-0.26,0.42l-0.35,-0.7ZM209.19,578.54l0.61,1.19l-0.23,0.77l0.66,1.82l0.05,1.22l1.73,7.29l-0.66,0.56l0.03,0.64l1.0,0.69l-0.59,0.84l0.05,0.52l0.72,0.67l-0.2,1.56l0.37,0.44l1.07,0.31l1.71,2.17l1.4,0.95l0.39,0.88l0.67,0.5l0.09,0.91l1.53,1.02l-0.19,0.84l-1.17,1.01l-0.41,1.68l-0.0,2.19l-2.07,1.87l-1.09,0.57l-0.63,-0.13l-0.02,-1.13l-0.64,0.07l-0.3,1.04l-0.22,0.05l0.16,-1.54l1.09,0.23l2.31,-1.69l-0.23,-0.63l-0.64,0.13l-0.33,-0.61l-0.71,0.13l0.71,-2.09l0.22,-1.84l-0.43,-0.29l-0.4,-1.06l0.62,-0.2l0.58,-0.88l-0.43,-0.27l-1.78,0.52l-0.59,-0.36l-2.75,0.29l-0.13,0.71l0.35,0.37l-0.57,0.72l-0.64,-0.46l-0.2,1.01l-0.3,-0.39l0.1,-0.81l0.89,-0.27l0.51,-0.97l0.54,-0.2l0.43,-1.37l1.49,0.53l1.01,-0.36l-0.17,-0.59l-1.8,-0.6l0.03,-1.02l-0.82,-0.63l0.03,-0.53l-0.51,-0.72l0.35,-0.41l-0.16,-0.68l-0.59,-0.0l0.81,-0.68l0.22,-0.62l-0.41,-0.27l-0.79,0.23l-0.68,-1.21l0.4,-0.26l0.21,-1.19l-0.39,-0.3l-0.8,0.09l-0.48,-1.2l-0.52,-0.26l-0.49,0.27l-0.37,-0.39l0.13,-0.25l1.84,0.29l0.62,-0.37l-0.23,-0.67l-1.19,-0.13l0.23,-0.72l-0.6,-0.28l0.07,-0.27l0.81,-0.01l0.81,1.13l0.62,-0.14l0.04,-0.52l-1.77,-2.58l0.17,-0.56l1.59,1.01l0.37,-0.69l-0.4,-0.48l-1.89,-0.89l0.24,-0.34l-0.2,-0.47l0.54,-0.81l-0.81,-0.3l-0.88,0.87l-0.2,-0.58l0.08,-0.72l0.74,-0.62l0.17,-0.66l0.54,-0.5l0.92,-0.14ZM214.84,608.68l-0.72,0.37l-0.3,-0.26l-0.82,0.1l0.74,-0.58l1.09,0.36ZM207.55,585.56l-0.21,-0.06l0.0,-0.24l0.08,0.17l0.13,0.13ZM124.33,461.82l-0.72,-0.79l0.08,-0.62l0.61,0.33l0.02,1.08ZM96.68,478.86l-0.08,-0.01l0.0,-0.01l0.08,0.02ZM87.61,480.71l-0.14,-0.07l0.02,0.0l0.12,0.07ZM87.75,487.21l-0.01,0.0l-0.04,-0.04l0.05,0.04ZM210.21,605.25l0.95,-0.39l0.15,-0.88l1.01,-0.37l0.59,-1.12l0.76,0.04l0.47,2.53l-1.46,2.49l0.34,-0.93l-0.25,-0.46l0.16,-1.74l-0.39,-0.42l-0.42,0.19l-0.21,0.58l-0.85,0.26l-0.29,1.23l-0.57,-1.01ZM204.53,604.41l0.23,-0.52l-0.58,-0.47l0.16,-0.56l-0.41,-0.26l1.05,-0.38l0.21,-0.67l-2.13,-0.56l1.59,-0.9l0.16,-0.86l-0.36,-0.08l0.35,-1.05l0.21,0.49l1.38,0.95l0.65,1.87l-0.18,0.82l-0.68,0.31l-0.12,0.51l-0.79,0.23l-0.06,0.42l0.07,0.51l0.76,-0.09l-0.11,0.29l0.38,0.45l0.87,0.16l0.31,0.67l-0.54,-0.15l-0.4,0.8l0.23,0.39l0.85,0.22l-1.39,0.74l0.11,0.7l0.57,0.32l-0.22,0.31l0.26,0.63l-0.39,0.4l-0.4,-0.2l0.24,-0.39l-0.45,-1.27l0.19,-0.92l-0.49,-0.5l-0.25,-1.87l-0.67,0.18l-0.2,-0.66ZM204.7,605.12l-0.02,0.03l0.0,-0.0l0.02,-0.03ZM204.91,597.51l-0.15,-0.81l-1.16,-0.79l0.71,0.03l0.44,0.61l0.43,-0.21l0.17,0.98l-0.44,0.18ZM204.03,589.42l1.73,1.0l0.58,0.52l0.11,0.57l0.56,0.15l0.24,-0.39l0.54,0.65l-0.54,1.63l-0.36,-1.55l-0.5,-0.5l-0.56,0.05l-0.21,0.96l0.31,0.54l-0.25,0.39l0.51,0.85l-0.29,0.21l-0.99,-0.68l-0.46,0.33l-0.4,-0.11l0.95,-2.9l-0.98,-1.74ZM204.3,590.82l0.01,0.01l0.01,0.01l-0.01,-0.0l-0.01,-0.01ZM201.28,587.91l0.24,-0.68l0.52,-0.17l-0.03,-0.45l0.42,-0.22l0.35,0.32l0.6,-0.35l-0.0,-0.8l-0.62,-0.4l0.7,-0.07l0.24,-0.65l-1.03,-0.28l-0.02,-1.43l0.48,-2.46l0.45,-0.43l0.87,0.22l0.37,0.4l-0.69,2.23l0.41,0.23l0.08,1.49l0.51,0.53l-0.12,0.39l-0.62,-0.22l-0.31,0.8l-0.69,0.34l0.04,0.32l-0.11,0.42l-0.22,0.32l-1.81,0.61ZM204.42,586.23l0.02,0.16l-0.19,-0.27l0.07,0.06l0.09,0.05ZM203.16,578.77l0.02,-0.02l0.01,0.06l-0.01,0.0l-0.03,-0.05ZM202.08,593.81l-0.03,-0.32l0.05,-0.01l0.09,0.19l-0.11,0.14ZM202.25,593.0l-0.25,-0.54l0.16,-0.07l0.34,0.48l-0.24,0.13ZM201.87,592.45l-0.2,-0.02l-0.02,-0.03l0.04,-0.01l0.17,0.06ZM201.97,591.45l-0.19,-0.44l-0.52,-0.05l0.08,-0.24l1.42,-0.09l-0.01,0.81l-0.39,0.25l-0.38,-0.25ZM195.26,578.67l0.22,-0.17l0.78,1.25l0.56,-0.45l-0.67,-1.58l0.86,0.26l0.05,-1.05l0.36,0.52l1.18,-0.42l0.77,0.97l-0.44,0.2l-0.8,-0.21l-0.17,0.33l-0.79,0.06l0.06,0.48l1.78,2.24l-0.07,0.74l0.9,0.5l1.08,0.01l-0.34,1.59l-0.43,-0.2l-2.75,-3.68l-0.61,0.35l0.09,0.44l-0.28,0.18l0.52,0.86l-0.19,0.56l0.29,0.37l-0.52,0.14l-0.52,-1.4l0.33,-0.19l-0.16,-0.49l-1.1,-2.22ZM197.81,583.65l0.03,-0.01l-0.01,0.04l-0.02,-0.02l-0.0,-0.0ZM197.98,583.86l0.65,0.02l0.94,0.95l0.23,2.78l-0.4,2.69l-0.3,0.89l-0.47,0.37l-0.63,1.95l-0.37,-2.3l1.14,-0.59l-0.06,-0.73l-0.28,-0.06l0.01,-0.56l-0.47,-0.3l-0.19,-0.68l-0.71,-0.04l0.39,-0.63l0.81,-0.06l0.22,-0.32l-0.13,-0.54l-0.66,-0.34l0.68,-0.34l-0.35,-1.27l-0.73,-0.27l0.59,-0.15l0.09,-0.48ZM196.56,583.11l-0.06,-0.04l0.15,-0.08l-0.09,0.12ZM199.05,579.52l1.11,-0.49l0.92,0.47l0.59,0.75l-0.17,0.31l-0.56,-0.63l-0.63,-0.07l-0.13,0.57l0.35,0.67l-1.49,-1.58ZM121.86,538.8l-0.0,-0.01l0.02,0.02l-0.02,-0.01ZM122.16,539.2l0.38,0.41l0.59,-0.1l-0.04,-0.62l0.83,0.53l0.61,-1.11l0.62,0.04l-0.13,0.7l0.46,0.88l-0.67,0.48l-0.23,-0.84l-0.37,-0.03l-0.81,0.68l-0.2,-0.29l-0.67,0.31l-0.36,-1.02ZM125.68,539.91l0.02,-0.0l-0.01,0.0l-0.01,-0.0ZM126.24,540.18l-0.05,-0.09l0.07,0.07l-0.02,0.02ZM126.1,539.97l-0.36,-0.07l0.27,-0.16l0.09,0.23ZM111.97,541.9l0.13,-1.11l-0.41,-0.51l0.57,-0.47l0.58,-0.31l0.5,0.27l1.58,-0.22l0.55,0.47l-0.75,0.07l0.02,0.5l0.56,0.37l-0.31,0.99l0.56,1.75l0.45,0.16l0.28,-0.39l-0.23,-0.7l0.33,-1.09l0.38,0.2l0.37,-0.33l1.06,0.15l0.41,-0.28l0.62,0.17l0.21,0.41l0.91,-0.72l0.49,0.31l-0.22,0.73l0.26,0.4l0.49,-0.02l0.33,-0.47l1.39,0.19l-0.09,0.39l-0.85,0.24l-0.21,0.41l0.21,1.1l0.75,0.33l-0.77,0.3l-2.35,-2.03l-0.88,0.42l-0.02,0.69l-0.56,-0.49l-0.44,0.12l-0.27,0.58l-1.74,-0.5l-0.49,0.58l-0.32,-0.15l-0.13,-0.86l-0.79,-0.03l-1.07,-1.18l-1.1,-0.44ZM119.11,544.38l0.82,0.17l0.33,0.72l-0.52,-0.07l-0.2,-0.66l-0.42,-0.16ZM117.78,540.47l-0.76,-0.83l0.17,-0.28l0.83,0.02l-0.24,1.09ZM121.13,540.99l0.32,0.07l-0.59,0.51l0.31,-0.44l-0.03,-0.14ZM113.0,545.5l-0.71,0.24l-0.07,-0.11l0.36,-0.03l0.42,-0.1ZM111.68,543.33l0.69,-0.15l0.23,0.13l-0.51,0.43l-0.41,-0.41ZM76.93,452.59l0.44,-0.56l0.74,-0.21l0.04,0.98l0.81,0.62l0.81,1.25l1.59,0.48l1.11,0.77l0.29,0.97l-0.62,0.7l1.28,1.78l-0.03,0.76l0.83,0.73l0.06,0.6l-0.76,-0.35l-1.49,0.03l-0.08,-1.15l-0.71,-1.29l0.16,-0.62l-1.2,-2.9l-0.96,-0.77l-1.79,-0.42l-0.51,-1.4ZM84.52,461.74l0.69,0.18l0.56,0.73l-0.43,0.12l-0.82,-1.03ZM75.58,485.5l0.07,-0.44l1.7,1.61l0.78,-0.27l0.53,0.4l0.88,-0.0l-0.06,0.37l0.83,0.24l0.29,0.89l1.02,0.89l-0.67,0.62l-0.55,1.49l-2.66,-1.39l-0.92,-0.99l-0.64,-2.06l-0.55,-0.58l-0.06,-0.77ZM55.82,528.18l0.22,-0.57l1.29,0.26l2.05,-0.81l0.73,0.9l0.76,-0.1l1.99,0.58l0.55,0.5l0.05,0.8l-0.49,1.14l-1.03,0.31l-2.5,-1.87l-2.52,0.16l-1.15,-0.81l0.05,-0.5ZM37.73,525.86l0.44,0.13l0.4,0.44l-0.66,-0.33l-0.17,-0.24ZM43.99,527.71l-0.32,-0.33l-0.55,0.04l0.82,-0.2l0.41,-0.61l-1.11,-1.43l0.35,-0.53l1.55,0.81l-0.4,0.52l0.03,0.83l-0.39,0.13l-0.39,0.76ZM42.84,527.18l-0.0,-0.0l0.0,0.0l0.0,0.0ZM43.98,526.54l0.02,-0.01l0.01,0.01l-0.02,0.0l-0.0,-0.0ZM42.63,527.12l-0.35,0.44l-0.22,-0.21l0.3,-0.36l-0.18,-0.32l0.39,-0.07l0.05,0.51ZM42.72,526.39l-0.0,-0.06l0.01,0.01l-0.01,0.05ZM31.87,524.21l0.91,-0.8l0.8,0.02l0.72,0.69l-1.15,0.35l-1.28,-0.25ZM35.31,524.02l0.44,-0.89l0.8,-0.04l0.97,0.45l0.25,0.65l-0.43,0.37l-2.04,-0.54ZM4.9,508.63l0.28,0.1l-0.04,0.24l-0.12,0.03l-0.12,-0.37ZM6.12,508.53l-0.05,-0.66l0.53,0.07l0.12,0.71l-0.59,-0.13Z\", \"name\": \"Alaska\"}, \"US-NJ\": {\"path\": \"M801.65,165.2l1.31,-1.55l0.48,-1.57l0.5,-0.62l0.54,-1.45l0.11,-2.05l0.67,-1.35l0.92,-0.71l14.12,4.16l-0.4,6.03l-0.35,0.55l-0.23,-0.44l-0.7,0.11l-0.26,1.18l-0.76,0.97l0.12,1.42l-0.46,0.6l0.08,1.71l0.58,0.62l1.2,0.29l1.38,-0.43l2.3,0.24l0.9,6.92l-0.56,0.39l0.18,0.66l-0.61,0.95l0.46,0.58l-0.21,0.6l0.53,1.94l-0.47,2.0l0.11,0.61l0.62,0.64l-0.39,1.13l-0.49,0.45l-0.01,0.59l-0.93,1.13l0.02,0.52l-1.07,0.1l0.09,1.21l0.64,0.83l-0.82,0.56l-0.18,1.15l1.05,0.77l-0.31,0.29l-0.17,-0.44l-0.53,-0.18l-0.5,0.22l-0.44,1.51l-1.28,0.61l-0.2,0.45l0.46,0.55l0.8,0.06l-0.66,1.26l-0.26,1.5l-0.68,0.65l0.19,0.48l0.4,0.04l-0.89,1.57l0.07,0.95l-1.65,1.72l-0.12,-1.34l0.36,-2.44l-0.11,-0.87l-0.58,-0.82l-0.89,-0.28l-1.11,0.34l-0.81,-0.35l-1.51,0.88l-0.31,-0.7l-1.62,-0.96l-1.0,0.04l-0.65,-0.71l-0.7,0.07l-3.24,-2.03l-0.06,-1.73l-1.02,-0.94l0.48,-0.68l0.0,-0.87l0.43,-0.83l-0.12,-0.73l0.51,-1.18l1.2,-1.16l2.6,-1.49l0.54,-0.86l-0.38,-0.85l0.5,-0.37l0.47,-1.44l1.24,-1.7l2.52,-2.22l0.18,-0.67l-0.47,-0.82l-4.26,-2.78l-0.75,-1.05l-0.9,0.24l-0.48,-0.33l-1.24,-2.46l-1.62,-0.02l-1.0,-3.44l1.02,-1.03l0.36,-2.23l-1.87,-1.91Z\", \"name\": \"New Jersey\"}, \"US-CO\": {\"path\": \"M364.23,239.52l-1.22,65.86l-29.29,-0.9l-29.38,-1.43l-29.35,-1.95l-32.17,-2.75l8.32,-87.13l27.79,2.39l28.22,1.92l29.58,1.46l27.95,0.87l-0.46,21.65Z\", \"name\": \"Colorado\"}, \"US-MD\": {\"path\": \"M740.67,219.62l-2.04,-10.06l19.85,-4.49l-0.66,1.29l-0.94,0.08l-1.54,0.81l0.16,0.7l-0.42,0.49l0.23,0.78l-1.76,0.5l-1.48,0.03l-1.14,-0.39l0.21,-0.36l-0.3,-0.49l-1.11,-0.31l-0.47,1.8l-1.63,2.84l-1.37,-0.39l-1.03,0.62l-0.41,1.26l-1.6,1.93l-0.36,1.04l-0.88,0.45l-1.3,1.87ZM760.74,204.54l36.93,-9.13l8.48,26.19l0.45,0.26l1.06,-0.21l8.18,-2.08l-0.9,0.53l0.31,0.64l0.52,0.01l0.37,0.76l0.52,-0.05l-0.38,1.96l-0.12,-0.26l-0.47,0.07l-0.73,0.86l-0.17,2.7l-0.6,0.19l-0.36,0.71l-0.02,1.66l-3.62,1.37l-0.45,0.7l-2.2,0.43l-0.56,0.65l-0.3,-1.09l0.5,-0.31l0.86,-1.84l-0.4,-0.51l-0.45,0.12l0.08,-0.5l-0.44,-0.42l-2.29,0.63l0.3,-0.6l1.15,-0.83l-0.17,-0.69l-1.36,-0.18l0.38,-2.24l-0.18,-1.02l-0.91,0.16l-0.53,1.76l-0.34,-0.68l-0.62,-0.07l-0.44,0.47l-0.5,1.39l0.53,1.02l-2.87,-2.14l-0.43,-0.19l-0.61,0.36l-0.73,-0.76l0.33,-1.67l0.76,-0.6l-0.08,-1.35l2.55,0.23l0.78,-1.5l-0.32,-1.42l-0.72,0.27l-0.28,1.29l-0.98,-0.25l-0.38,-1.07l-0.52,-0.28l-0.55,0.23l-0.22,-0.68l-0.63,0.08l1.0,-0.82l0.22,-1.04l-0.54,-0.55l-0.75,0.83l-0.21,-0.61l1.06,-0.92l-0.25,-0.65l-0.54,-0.08l-0.51,-0.75l-0.42,0.22l-0.53,-0.37l0.83,-1.03l-0.24,-1.02l0.84,-1.95l-0.07,-0.86l-0.46,0.02l-0.66,0.66l-0.56,-0.16l-0.48,0.45l-0.19,0.97l-0.95,-1.2l0.75,-3.46l0.59,-0.51l0.07,-0.74l3.89,-0.78l0.49,-0.41l-0.23,-0.67l-0.45,-0.07l-2.38,0.56l0.88,-1.55l1.42,-0.05l0.35,-0.5l-0.99,-0.67l0.44,-1.9l-0.63,-0.32l-0.48,0.39l-0.87,1.96l0.21,-2.02l-0.59,-0.34l-0.88,1.43l-1.42,0.34l-0.31,1.65l0.39,0.53l0.65,0.12l-1.45,1.92l-0.2,-1.64l-0.64,-0.42l-0.61,0.73l0.07,1.45l-0.85,-0.29l-1.16,0.64l0.02,0.71l1.01,0.27l-0.37,0.54l-0.83,0.22l-0.05,0.34l-0.44,-0.04l-0.35,0.64l1.2,1.22l-0.29,0.17l-1.52,-0.76l-1.33,0.48l0.16,0.69l0.82,0.1l1.26,1.21l1.49,0.58l0.1,0.28l-0.44,0.33l-1.37,0.5l-0.12,1.19l1.83,1.04l0.47,0.63l-0.66,-0.43l-1.05,0.29l0.2,0.64l0.92,0.48l-0.34,0.47l0.4,1.15l0.6,0.09l-0.63,1.26l0.13,0.43l0.63,0.65l1.28,4.18l2.83,2.58l-0.01,0.35l-0.38,0.54l-0.67,-1.23l-1.21,-0.22l-1.69,-0.87l-1.51,-3.64l-0.74,-0.68l-0.28,0.69l1.17,3.94l0.65,0.92l1.45,0.81l1.3,0.31l1.49,1.39l0.89,-0.33l0.37,1.32l1.47,1.47l0.1,1.07l-1.08,-0.68l-0.33,-1.23l-0.63,-0.45l-0.45,0.04l-0.13,0.44l0.27,0.78l-0.74,0.13l-0.62,-0.73l-1.16,-0.38l-1.53,0.0l-0.92,0.43l-0.55,-0.2l-1.0,-2.19l-1.26,-0.71l-0.46,0.14l0.01,0.48l1.19,2.0l-0.67,-0.12l-0.28,-0.5l-0.89,-0.4l-1.61,-2.6l-0.48,-0.14l-0.43,1.47l-0.25,-0.74l-0.62,-0.04l-0.4,0.46l0.33,0.72l-0.18,0.69l-0.64,0.59l-0.57,-0.26l-0.63,-1.86l0.25,-1.14l0.71,-0.37l0.2,-0.51l-0.37,-0.52l0.83,-0.52l0.21,-1.61l1.06,-0.35l0.07,-0.66l-0.33,-0.42l0.23,-0.42l-0.38,-0.38l-0.04,-0.7l1.27,-2.2l-0.14,-0.54l-2.72,-1.68l-0.56,0.14l-0.69,1.19l-1.81,-0.37l-1.09,-1.19l-2.96,-0.09l-1.25,-0.91l0.61,-1.35l-0.4,-0.97l-1.19,-0.3l-0.89,-0.66l-2.69,0.07l-0.36,-0.23l-0.11,-1.26l-1.04,-0.6l0.09,-1.2l-0.51,-0.29l-0.49,0.19l-0.23,-0.64l-0.52,-0.13l0.26,-0.83l-0.45,-0.58l-0.69,-0.12l-1.81,0.67l-2.24,-1.27ZM790.07,212.25l0.29,-0.0l0.93,0.21l-0.44,0.4l-0.78,-0.61ZM796.79,218.15l0.0,0.16l-0.13,-0.11l0.13,-0.06ZM803.02,225.62l-0.02,0.33l-0.21,-0.15l0.23,-0.19ZM806.99,229.08l-0.16,0.3l-0.12,0.07l0.02,-0.25l0.26,-0.12ZM797.54,220.57l-0.06,0.01l-0.09,0.03l0.12,-0.06l0.03,0.02ZM797.21,220.69l-0.26,0.57l-0.18,0.12l0.15,-0.61l0.29,-0.07ZM796.09,217.04l-0.61,0.32l-0.58,-0.42l0.02,-0.53l0.16,-0.23l0.68,0.3l0.32,0.56ZM794.46,213.09l-0.25,0.5l-0.8,0.39l0.15,-1.17l0.9,0.27Z\", \"name\": \"Maryland\"}, \"US-MA\": {\"path\": \"M820.4,120.02l30.04,-8.0l1.53,-1.8l0.34,-1.48l0.95,-0.35l0.61,-1.04l1.17,-1.05l1.35,-0.1l-0.44,1.05l1.03,0.32l0.21,1.55l1.17,0.55l-0.06,0.32l0.39,0.28l1.31,0.19l-0.17,0.56l-2.29,1.79l-0.05,1.07l0.45,0.16l-1.11,1.41l0.23,1.08l-1.01,0.96l0.58,1.41l1.4,0.45l0.5,0.63l1.36,-0.57l0.33,-0.59l1.2,0.09l0.79,0.47l0.23,0.68l1.79,1.37l-0.07,1.25l-0.56,0.55l0.12,0.6l1.23,0.66l1.73,-0.23l0.68,1.2l0.21,1.14l0.89,0.68l1.33,0.41l1.48,-0.12l0.43,0.38l1.05,-0.23l2.92,-2.34l0.82,-1.11l0.54,0.02l0.56,1.86l-3.32,1.52l-0.94,0.82l-2.75,0.98l-0.49,1.64l-1.93,1.37l-0.82,-2.64l0.11,-1.34l-0.55,-0.31l-0.5,0.39l-0.93,-0.1l-0.3,0.51l0.25,0.92l-0.26,0.79l-0.4,0.06l-0.63,1.1l-0.6,-0.2l-0.5,0.48l0.22,1.86l-0.9,0.87l-0.63,-0.8l-0.47,0.01l-0.11,0.55l-0.26,0.03l-0.71,-2.03l-1.02,-0.35l0.44,-2.5l-0.21,-0.4l-0.78,0.4l-0.29,1.47l-0.69,0.2l-1.4,-0.64l-0.78,-2.12l-0.8,-0.22l-0.78,-2.15l-0.49,-0.24l-6.13,2.0l-0.3,-0.15l-14.84,4.19l-0.28,0.5l-0.46,-0.28l-0.86,0.17l-9.54,2.36l-0.25,-0.18l-0.32,-14.66ZM860.63,110.12l-0.02,-0.37l-0.14,-0.48l0.51,0.23l-0.35,0.62ZM876.24,122.86l-0.12,-0.42l0.25,0.35l-0.13,0.06ZM875.23,121.15l-0.78,0.0l-0.55,-1.2l0.56,0.44l0.77,0.76ZM871.43,119.57l-0.08,0.14l-0.09,-0.07l0.0,-0.0l0.17,-0.07Z\", \"name\": \"Massachusetts\"}, \"US-AL\": {\"path\": \"M608.67,337.4l25.17,-2.91l19.4,-2.75l14.04,43.29l1.01,2.45l1.17,1.59l0.59,1.87l2.24,2.5l0.92,1.8l-0.11,2.13l1.8,1.13l-0.17,0.74l-0.63,0.1l-0.16,0.7l-0.98,0.84l-0.22,2.29l0.25,1.48l-0.76,2.3l-0.14,1.84l1.1,2.94l1.21,1.52l0.53,1.6l-0.08,5.02l-0.25,0.81l0.48,2.03l1.35,1.16l1.14,2.07l-47.64,6.92l-0.42,0.61l-0.08,2.99l2.64,2.75l2.0,0.96l-0.34,2.7l0.56,1.61l0.43,0.39l-0.94,1.69l-1.24,1.0l-1.13,-0.75l-0.34,0.49l0.66,1.46l-2.81,1.05l0.29,-0.63l-0.45,-0.86l-0.99,-0.76l-0.1,-1.11l-0.57,-0.22l-0.52,0.61l-0.32,-0.1l-0.89,-1.53l0.41,-1.67l-0.97,-2.21l-1.32,-0.65l-0.3,-0.89l-0.56,-0.17l-0.37,0.61l0.15,0.35l-0.77,3.1l-0.01,5.08l-0.59,0.0l-0.24,-0.71l-2.22,-0.44l-1.64,0.31l-5.46,-31.98l-0.99,-66.48l-0.02,-0.37l-1.07,-0.63l-0.69,-1.02Z\", \"name\": \"Alabama\"}, \"US-MO\": {\"path\": \"M468.72,225.49l24.71,-0.73l18.94,-1.42l22.1,-2.58l0.42,0.35l0.39,0.91l2.43,1.65l0.29,0.74l1.21,0.87l-0.51,1.36l-0.1,3.21l0.78,3.65l0.95,1.44l0.03,1.59l1.11,1.37l0.46,1.55l4.96,4.1l1.06,1.69l4.93,3.31l0.7,1.15l0.27,1.62l0.5,0.82l-0.18,0.69l0.47,1.8l0.97,1.63l0.77,0.73l1.04,0.16l0.83,-0.56l0.84,-1.4l0.57,-0.19l2.41,0.61l1.68,0.76l0.84,0.77l-0.97,1.95l0.26,2.28l-2.37,6.86l0.01,1.02l0.7,1.92l4.67,4.05l1.99,1.05l1.46,0.09l1.66,1.3l1.92,0.8l1.5,2.11l2.04,0.83l0.42,2.96l1.72,2.9l-1.1,1.94l0.18,1.38l0.75,0.33l2.31,4.25l1.94,0.92l0.55,-0.32l0.0,-0.65l0.87,1.1l1.07,-0.08l0.14,1.85l-0.37,1.07l0.53,1.59l-1.07,3.86l-0.51,0.07l-1.37,-1.13l-0.65,0.13l-0.78,3.34l-0.52,0.74l0.13,-1.06l-0.56,-1.09l-0.97,-0.2l-0.74,0.63l0.02,1.05l0.53,0.66l-0.04,0.7l0.58,1.34l-0.2,0.4l-1.2,0.39l-0.17,0.41l0.15,0.55l0.86,0.84l-1.71,0.37l-0.14,0.62l1.53,1.97l-0.89,0.75l-0.63,2.13l-10.61,1.42l1.06,-2.28l0.87,-0.61l0.18,-0.87l1.43,-0.96l0.25,-0.96l0.63,-0.37l0.29,-0.59l-0.22,-2.28l-1.05,-0.75l-0.2,-0.77l-1.09,-1.18l-39.24,3.6l-37.71,2.58l-3.21,-58.18l-1.03,-0.63l-1.2,-0.02l-1.52,-0.73l-0.19,-0.93l-1.11,-1.3l-0.36,-1.55l-0.55,-0.09l-0.3,-0.56l-1.13,-0.66l-1.4,-1.84l0.73,-0.51l0.09,-1.24l1.12,-1.27l0.09,-0.79l1.01,0.16l0.56,-0.43l-0.2,-2.24l-1.02,-0.74l-0.32,-1.1l-1.17,-0.01l-1.31,0.96l-0.81,-0.7l-0.73,-0.17l-2.67,-2.35l-1.05,-0.28l0.13,-1.6l-1.32,-1.72l0.1,-1.01l-0.37,-0.36l-1.01,-0.18l-0.59,-0.85l-0.84,-0.26l0.07,-0.52l-1.24,-2.88l-0.0,-0.74l-0.4,-0.49l-0.85,-0.29l-0.05,-0.54ZM583.78,294.53l-0.1,-0.1l-0.08,-0.15l0.11,-0.01l0.07,0.26Z\", \"name\": \"Missouri\"}, \"US-MN\": {\"path\": \"M443.67,67.68l-0.4,-1.37l0.05,-1.19l-0.48,-0.53l-1.36,-3.77l0.0,-3.22l-0.47,-1.97l0.27,-1.12l-0.57,-2.32l0.73,-2.56l-2.06,-6.89l29.55,-1.22l0.47,-0.81l-0.38,-7.12l2.84,0.15l1.24,0.82l0.38,2.69l1.73,5.31l0.13,2.3l0.52,0.86l1.46,1.05l1.3,0.49l3.23,-0.36l0.39,0.85l0.54,0.38l5.25,0.04l0.38,0.24l0.54,1.58l0.72,0.61l4.27,-0.78l0.77,-0.65l0.07,-0.69l0.69,-0.35l1.74,-0.44l3.97,-0.02l1.42,0.7l3.38,0.66l-1.01,0.79l0.0,0.82l0.51,0.45l2.91,-0.06l0.52,2.08l1.58,2.29l0.71,0.05l1.03,-0.78l-0.04,-1.73l2.67,-0.46l1.43,2.16l2.01,0.79l1.54,0.18l0.54,0.57l-0.03,0.83l0.58,0.35l1.32,0.06l0.19,0.75l0.41,0.1l1.2,-0.22l1.12,0.22l2.21,-0.85l2.78,-2.55l2.49,-1.54l1.24,2.52l0.96,0.51l2.23,-0.66l0.87,0.36l5.98,-1.3l0.56,0.18l1.32,1.64l1.24,0.59l0.62,-0.01l1.61,-0.83l1.3,0.1l-0.89,1.0l-4.69,3.07l-6.35,2.82l-3.68,2.47l-2.15,2.49l-0.96,0.57l-6.62,8.67l-0.95,0.61l-1.07,1.56l-1.96,1.97l-4.18,3.55l-0.86,1.78l-0.55,0.44l-0.14,0.96l-0.78,-0.01l-0.46,0.51l0.98,12.22l-0.79,1.2l-1.04,0.08l-0.52,0.82l-0.83,0.15l-0.61,0.83l-2.06,1.19l-0.94,1.86l0.06,0.72l-1.69,2.39l-0.01,2.06l0.38,0.91l2.15,0.39l1.42,2.49l-0.52,1.92l-0.71,1.25l-0.05,2.12l0.45,1.32l-0.71,1.23l0.91,3.14l-0.51,4.08l3.95,3.03l3.02,0.4l1.89,2.25l2.87,0.5l2.45,1.93l2.39,3.59l2.63,1.8l2.09,0.09l1.07,0.71l0.88,0.1l0.82,1.36l1.26,0.84l0.28,2.03l0.68,1.3l0.39,4.82l-40.62,3.2l-40.63,2.09l-1.46,-38.98l-1.52,-2.05l-2.57,-0.79l-0.94,-1.91l-1.46,-1.79l0.21,-0.68l2.82,-2.34l0.93,-2.03l0.43,-2.53l-0.35,-1.58l0.23,-1.86l-0.18,-1.51l-0.5,-1.03l-0.18,-2.33l-1.81,-2.59l-0.47,-1.13l-0.21,-2.16l-0.66,-0.98l0.15,-1.66l-0.35,-1.52l0.53,-2.69l-1.08,-1.85l-0.49,-8.32l-0.42,-0.79l0.06,-3.92l-1.58,-3.95l-0.53,-0.65Z\", \"name\": \"Minnesota\"}, \"US-CA\": {\"path\": \"M3.07,175.36l0.87,-1.1l0.96,0.24l1.21,-2.15l0.92,0.12l0.64,-0.23l0.41,-0.57l-0.27,-0.82l-0.71,-0.36l1.52,-2.68l0.12,-0.78l-0.43,-0.48l0.1,-1.34l0.85,-0.88l1.17,-2.25l1.26,-3.01l0.39,-2.1l-0.28,-1.0l0.05,-3.89l-1.25,-1.24l0.92,-1.24l0.94,-2.81l32.73,8.13l32.57,7.34l-13.67,64.67l25.44,34.66l36.59,51.09l13.3,17.72l-0.19,2.73l0.73,0.94l0.21,1.71l0.85,0.63l0.81,2.56l-0.07,0.91l0.63,1.46l-0.16,1.36l3.8,3.82l0.01,0.5l-1.95,1.53l-3.11,1.26l-1.2,1.99l-1.72,1.14l-0.33,0.81l0.38,1.03l-0.51,0.51l-0.1,0.9l0.08,2.29l-0.6,0.72l-0.64,2.44l-2.02,2.47l-1.6,0.14l-0.42,0.51l0.33,0.89l-0.59,1.34l0.54,1.11l-0.01,1.19l-0.78,2.68l0.57,1.02l2.74,1.13l0.34,0.83l-0.19,2.4l-1.18,0.78l-0.42,1.37l-2.27,-0.62l-1.26,0.61l-43.36,-3.35l0.04,-0.76l0.39,-0.07l0.3,-0.56l-0.12,-1.38l-1.1,-1.65l-1.08,0.02l0.16,-1.13l-0.24,-1.11l0.35,-0.13l0.36,-0.93l0.05,-2.47l-0.39,-2.64l-2.46,-5.66l-3.47,-4.07l-1.29,-1.98l-2.42,-2.12l-2.07,-2.86l-2.01,-1.04l-1.23,0.18l-0.29,0.88l-1.56,-0.95l-0.11,-0.38l0.63,-0.52l0.22,-0.95l-0.46,-2.65l-1.0,-1.95l-0.7,-0.58l-2.17,-0.43l-1.45,-0.13l-1.11,0.3l-0.49,-0.59l-1.66,-0.65l-3.05,-1.95l-1.24,-1.35l-0.54,-2.64l-0.89,-0.66l-1.77,-2.24l-1.66,-1.3l-1.92,-0.51l-1.09,0.24l-1.1,-0.72l-1.51,-0.14l-2.0,-1.52l-2.34,-0.84l-5.72,-0.67l-0.4,-1.69l-1.01,-0.93l-0.92,-0.35l1.28,-2.62l-0.33,-1.38l0.84,-2.21l-0.65,-1.27l1.18,-2.39l0.32,-2.41l-0.99,-1.24l-1.32,-0.26l-1.34,-1.39l-0.08,-0.75l1.44,-1.4l-0.5,-2.3l-0.34,-0.54l-1.68,-0.76l-1.88,-4.27l-1.79,-1.16l-0.32,-2.63l-1.62,-2.61l-0.22,-2.75l-1.01,-0.76l-1.13,-3.38l-2.16,-2.3l-0.75,-1.6l0.04,-3.93l0.55,-1.46l-0.54,-0.6l0.52,-0.53l0.56,0.71l0.58,-0.1l0.8,-0.59l0.9,-1.64l0.83,0.01l0.08,-0.52l-0.51,-0.5l0.4,-0.88l-0.05,-0.93l-0.49,-2.22l-0.61,-1.2l-0.6,-0.44l-0.92,0.25l-2.02,-0.43l-1.45,-1.81l-0.86,-2.15l-0.53,-0.38l-0.32,-1.18l-0.46,-0.5l0.04,-1.12l0.85,-2.26l-0.21,-2.94l-0.89,-1.29l1.1,-2.74l0.21,-2.34l1.33,-0.2l0.23,1.52l-0.62,0.31l-0.1,2.71l1.73,1.17l0.7,1.42l1.0,0.72l0.4,1.01l0.89,0.41l0.85,-0.4l-0.19,-1.18l-0.68,-0.51l-0.37,-1.53l0.13,-1.99l-0.54,-1.26l-0.37,-0.02l-0.11,-0.14l0.62,-0.35l-0.0,-0.34l-1.62,-1.2l0.69,-0.67l-0.17,-1.88l-0.94,-0.36l-0.3,-0.61l1.07,-0.66l0.99,-0.01l0.96,-0.71l1.25,1.03l2.63,-0.1l5.01,2.23l0.53,-0.22l0.04,-0.59l0.61,-0.67l-0.3,0.75l0.39,0.76l0.81,-0.06l0.35,-0.49l1.35,1.6l0.7,-0.16l0.02,-0.38l-0.53,-1.14l-0.97,-0.74l-0.27,-0.8l-0.66,-0.38l-1.09,-0.07l0.27,-0.58l-0.25,-0.54l-2.48,1.29l-0.7,-0.34l-0.75,0.18l-0.18,-0.55l-1.09,-0.25l0.28,-0.66l-0.36,-0.69l-1.09,-0.17l-1.86,1.57l-0.34,-0.46l-1.36,-0.54l-0.36,-0.88l-1.36,-1.35l-2.59,0.52l0.1,0.92l-0.7,1.21l0.53,0.72l-0.88,0.92l-0.07,2.28l-0.37,-0.09l-1.52,-2.07l-1.18,-0.34l-1.16,-2.44l-1.41,-1.2l0.09,-0.69l-0.68,-0.18l0.73,-1.18l0.93,2.05l0.44,0.25l0.33,-0.38l-1.77,-5.65l-0.41,-0.59l-0.57,-0.2l0.2,-0.84l-0.53,-2.28l-2.72,-3.32l-1.0,-2.99l-3.45,-6.17l-0.03,-0.38l1.14,-1.43l0.12,-0.85l-0.51,-6.75l0.61,-1.87l1.33,-2.02l0.4,-3.04l-0.36,-1.21l0.19,-2.39l-0.7,-1.04l-1.24,-3.68l-0.57,-0.53l0.1,-0.93l-0.32,-0.88l-1.04,-0.88l-2.01,-3.32l0.52,-1.23l-0.26,-2.71l2.38,-3.44ZM33.36,240.61l0.01,-0.01l0.01,0.01l-0.02,-0.01ZM45.67,326.22l-0.02,0.03l0.02,-0.03l0.01,0.01ZM31.63,240.38l-0.09,0.14l-0.63,0.23l-0.2,-0.07l0.92,-0.3Z\", \"name\": \"California\"}, \"US-IA\": {\"path\": \"M452.94,162.22l42.82,-2.19l40.55,-3.19l0.96,2.52l2.0,1.0l0.08,0.59l-0.9,1.8l-0.16,1.04l0.9,5.09l0.92,1.26l0.39,1.75l1.46,1.72l4.94,0.85l1.27,2.03l-0.3,1.03l0.29,0.66l3.61,2.37l0.85,2.41l3.84,2.31l0.62,1.68l-0.31,4.21l-1.64,1.98l-0.5,1.94l0.13,1.28l-1.26,1.36l-2.51,0.97l-0.89,1.18l-0.55,0.25l-4.56,0.83l-0.89,0.73l-0.61,1.71l-0.15,2.55l0.4,1.08l2.01,1.47l0.54,2.65l-1.87,3.25l-0.22,2.24l-0.52,1.42l-2.88,1.39l-1.02,1.02l-0.2,0.99l0.72,0.87l0.2,2.15l-0.58,0.23l-1.34,-0.82l-0.31,-0.76l-1.29,-0.82l-0.29,-0.51l-0.88,-0.36l-0.3,-0.82l-0.95,-0.68l-22.3,2.61l-15.12,1.17l-7.59,0.51l-20.78,0.47l-0.22,-1.06l-1.3,-0.73l-0.33,-0.67l0.58,-1.16l-0.21,-0.95l0.22,-1.39l-0.36,-2.19l-0.6,-0.73l0.07,-3.65l-1.05,-0.5l0.05,-0.91l0.71,-1.02l-0.05,-0.44l-1.31,-0.56l0.33,-2.54l-0.41,-0.45l-0.89,-0.16l0.23,-0.8l-0.3,-0.58l-0.51,-0.25l-0.74,0.23l-0.42,-2.81l0.5,-2.36l-0.2,-0.67l-1.36,-1.71l-0.08,-1.92l-1.78,-1.54l-0.36,-1.74l-1.09,-0.94l0.03,-2.18l-1.1,-1.87l0.21,-1.7l-0.27,-1.08l-1.38,-0.67l-0.87,-2.17l0.05,-0.63l-1.81,-1.82l0.56,-1.61l0.54,-0.47l0.73,-2.68l0.0,-1.68l0.55,-0.69l0.21,-1.19l-0.51,-2.24l-1.33,-0.29l-0.05,-0.73l0.45,-0.56l-0.0,-1.71l-0.95,-1.42l-0.05,-0.87Z\", \"name\": \"Iowa\"}, \"US-MI\": {\"path\": \"M612.25,185.8l1.83,-2.17l0.7,-1.59l1.18,-4.4l1.43,-3.05l1.01,-5.05l0.09,-5.37l-0.86,-5.54l-2.4,-5.17l0.6,-0.5l0.3,-0.79l-0.57,-0.42l-1.08,0.55l-3.82,-7.03l-0.21,-1.1l1.13,-2.68l-0.01,-0.97l-0.74,-3.13l-1.29,-1.65l-0.05,-0.62l1.73,-2.73l1.22,-4.14l-0.21,-5.35l-0.77,-1.59l1.09,-1.15l0.81,-0.02l0.56,-0.47l-0.27,-3.49l1.08,-0.11l0.67,-1.43l1.18,0.47l0.66,-0.33l0.76,-2.59l0.82,-1.2l0.56,-1.68l0.55,-0.18l-0.58,0.87l0.6,1.65l-0.71,1.8l0.71,0.42l-0.48,2.61l0.88,1.43l0.73,-0.05l0.52,0.56l0.64,-0.24l0.89,-2.26l0.67,-3.51l-0.08,-2.07l-0.76,-3.42l0.58,-1.02l2.13,-1.64l2.74,-0.55l0.98,-0.63l0.28,-0.64l-0.25,-0.54l-1.76,-0.11l-0.96,-0.86l-0.52,-1.98l1.85,-2.98l-0.1,-0.73l1.72,-0.23l0.74,-0.94l4.16,2.0l0.83,0.12l1.98,-0.4l1.37,0.4l1.19,1.04l0.53,1.15l0.77,0.49l2.41,-0.29l1.7,1.01l1.92,0.09l0.8,0.64l3.27,0.45l1.1,0.77l-0.01,1.12l1.04,1.31l0.64,0.21l0.37,0.91l-0.14,0.55l-0.67,-0.25l-0.94,0.57l-0.23,1.83l0.81,1.29l1.6,0.98l0.69,1.37l0.65,2.26l-0.12,1.73l0.77,5.57l-0.14,0.59l-0.58,0.21l-0.48,0.96l-0.74,0.07l-0.8,0.81l-0.17,4.47l-1.12,0.49l-0.18,0.82l-1.86,0.43l-0.72,0.6l-0.58,2.61l0.26,0.45l-0.21,0.52l0.25,2.57l1.38,1.31l2.89,0.84l0.91,-0.08l1.08,-1.23l0.6,-1.44l0.62,0.19l0.39,-0.24l1.01,-3.59l0.6,-1.06l-0.08,-0.51l0.97,-1.45l1.39,-0.39l1.07,-0.69l0.83,-1.1l0.87,-0.44l2.06,0.59l1.13,0.7l1.0,1.09l1.21,2.16l2.01,5.91l0.82,1.6l1.03,3.71l1.49,3.63l1.29,1.74l-0.34,3.92l0.45,2.48l-0.48,2.79l-0.36,0.45l-0.57,-1.21l0.03,-0.85l-1.46,-0.52l-0.47,0.08l-1.48,1.36l-0.06,0.83l0.55,0.67l-0.82,0.57l-0.29,0.79l0.28,2.94l-0.48,0.75l-1.62,0.92l-1.06,1.85l-0.43,3.73l0.27,1.56l-0.33,0.93l-0.42,0.19l0.02,0.91l-0.64,0.3l-0.89,1.6l-0.5,1.29l-0.02,1.05l-0.52,0.91l-20.5,4.22l-0.15,-0.92l-0.45,-0.33l-31.44,4.71ZM621.47,115.84l0.0,-0.07l0.11,-0.12l-0.01,0.03l-0.11,0.16ZM621.73,114.93l-0.07,-0.16l0.07,-0.14l-0.0,0.3ZM543.5,88.02l4.87,-2.38l3.55,-3.62l5.77,-1.36l1.39,-0.84l2.36,-2.71l0.98,0.04l1.52,-0.73l1.0,-2.24l2.82,-2.85l0.23,1.72l1.85,0.59l0.05,1.44l0.67,0.14l0.51,0.6l-0.17,3.14l0.44,0.95l-0.34,0.47l0.2,0.47l0.74,-0.02l1.08,-2.21l1.08,-0.89l-0.42,1.15l0.58,0.45l0.83,-0.67l0.52,-1.22l1.0,-0.43l3.09,-0.25l1.5,0.21l1.18,0.93l1.54,0.44l0.47,1.05l2.31,2.58l1.17,0.55l0.53,1.55l0.73,0.34l1.87,0.07l0.73,-0.4l1.06,-0.06l1.4,-1.09l1.0,1.11l1.1,0.64l1.01,-0.25l0.68,-0.82l1.87,1.06l0.64,-0.34l1.65,-2.58l2.81,-1.89l1.7,-1.65l0.92,0.11l3.27,-1.21l5.17,-0.25l3.25,-2.09l2.28,-0.88l1.52,-0.11l-0.01,3.24l0.29,0.71l-0.36,1.1l0.46,0.7l0.68,0.28l0.91,-0.41l2.2,0.7l1.14,-0.43l1.03,-0.87l0.66,0.48l0.21,0.7l0.85,0.22l1.22,-0.76l0.79,-1.57l0.69,-0.28l1.06,0.23l1.35,-1.15l0.53,-0.01l0.22,0.08l-0.3,2.02l0.75,1.32l-1.11,-0.04l-0.36,0.5l0.84,1.83l-0.87,1.04l0.12,0.45l0.83,0.79l1.37,-0.42l0.6,0.47l0.62,0.04l0.18,1.19l0.98,0.87l1.53,0.51l-1.17,0.68l-4.96,-0.15l-0.53,0.3l-1.35,-0.17l-0.88,0.41l-0.66,-0.75l-1.63,-0.07l-0.59,0.47l-0.07,1.22l-0.49,0.76l0.38,2.05l-0.92,-0.22l-0.89,-0.92l-0.77,-0.13l-1.96,-1.65l-2.41,-0.6l-1.6,0.04l-1.04,-0.5l-2.89,0.47l-0.61,0.45l-1.18,2.52l-3.47,0.73l-0.57,0.77l-2.06,-0.33l-2.82,0.93l-0.68,0.83l-0.56,2.51l-0.78,0.28l-0.81,0.87l-0.65,0.28l0.16,-1.95l-0.74,-0.91l-1.02,0.34l-0.77,0.92l-0.97,-0.39l-0.68,0.17l-0.37,0.4l0.1,0.82l-0.73,2.01l-1.2,0.59l-0.1,-1.37l-0.46,-1.06l0.34,-1.69l-0.17,-0.37l-0.66,-0.17l-0.45,0.57l-0.6,2.13l-0.22,2.57l-1.12,0.91l-1.26,3.03l-0.62,2.65l-2.55,5.33l-0.69,0.73l0.12,0.91l-1.4,-1.28l0.18,-1.74l0.63,-1.69l-0.41,-0.81l-0.62,-0.31l-1.36,0.85l-1.16,0.1l0.04,-1.29l0.81,-1.45l-0.41,-1.34l0.3,-1.09l-0.58,-0.98l0.15,-0.83l-1.9,-1.55l-1.1,-0.06l-0.59,-0.44l-1.48,-0.0l0.3,-1.36l-0.94,-1.45l-1.13,-0.51l-2.23,-0.1l-3.2,-0.71l-1.55,0.59l-1.43,-0.42l-1.62,0.17l-4.56,-1.94l-15.37,-2.5l-1.99,-3.39l-1.88,-0.96l-0.76,0.26l-0.1,-0.29ZM603.39,98.63l-0.0,0.52l-0.46,0.32l-0.7,1.39l0.08,0.57l-0.65,-0.58l0.91,-2.15l0.83,-0.06ZM570.53,72.73l-0.51,-0.27l-1.16,0.06l-0.04,-1.56l1.0,-1.02l1.18,-2.09l1.83,-1.5l0.63,-0.0l0.53,-0.58l2.08,-0.89l3.34,-0.42l1.1,0.66l-0.54,0.38l-1.32,-0.12l-2.26,0.78l0.15,0.87l0.71,0.13l-1.19,0.98l-1.4,1.89l-0.69,0.28l-0.36,1.45l-1.15,1.36l-0.66,2.04l-0.67,-0.87l0.75,-0.97l0.14,-1.95l-0.84,-0.23l-0.6,0.92l-0.05,0.67Z\", \"name\": \"Michigan\"}, \"US-GA\": {\"path\": \"M654.05,331.64l22.02,-3.57l20.65,-3.86l-0.07,0.58l-2.59,3.35l-0.41,1.73l0.11,1.23l0.82,0.78l1.84,0.8l1.03,0.12l2.7,2.03l0.84,0.24l1.9,-0.37l0.6,0.25l0.8,1.64l1.51,1.6l1.04,2.5l1.33,0.82l0.84,1.16l0.56,0.26l1.0,1.77l1.07,0.3l1.17,0.99l3.81,1.85l2.41,3.16l2.25,0.58l2.53,1.67l0.5,2.34l1.25,1.01l0.47,-0.16l0.31,0.49l-0.1,0.62l0.79,0.73l0.79,0.09l0.56,1.2l4.99,1.88l0.4,1.78l1.54,1.73l1.02,2.01l-0.07,0.8l0.48,0.69l0.11,1.24l1.04,0.79l1.16,0.17l1.25,0.62l0.28,0.53l0.57,0.23l1.12,2.56l0.76,0.57l0.08,2.68l0.77,1.48l1.38,0.9l1.52,-0.27l1.44,0.76l1.45,0.12l-0.59,0.78l-0.55,-0.35l-0.47,0.28l-0.4,0.99l0.62,0.91l-0.38,0.48l-1.38,-0.16l-0.77,-0.55l-0.65,0.44l0.26,0.71l-0.49,0.52l0.36,0.6l1.44,0.25l-0.58,1.35l-1.43,0.27l-1.08,-0.44l-0.6,0.21l0.03,0.82l1.45,0.6l-1.76,3.73l0.36,1.73l-0.48,0.97l0.85,1.48l-2.29,-0.19l-0.46,0.29l0.06,0.63l0.55,0.34l2.76,0.24l1.07,0.66l-0.02,0.34l-0.56,0.22l-0.88,1.95l-0.5,-1.41l-0.45,-0.13l-0.6,0.33l-0.15,0.84l0.34,0.96l-0.6,0.12l-0.03,0.84l-0.3,0.16l0.07,0.46l1.34,1.15l-1.09,1.03l0.32,0.47l0.77,0.08l-0.39,0.92l0.06,0.88l-0.46,0.51l1.1,1.66l0.03,0.76l-0.79,0.33l-2.64,-0.17l-4.06,-0.96l-1.31,0.35l-0.18,0.74l-0.68,0.26l-0.35,1.25l0.28,2.08l0.95,1.36l0.13,4.25l-1.97,0.4l-0.54,-0.92l-0.12,-1.3l-1.33,-1.82l-49.21,5.14l-0.72,-0.56l-0.86,-2.7l-0.94,-1.51l-0.56,-0.38l0.16,-0.68l-0.73,-1.51l-1.82,-1.81l-0.43,-1.75l0.25,-0.8l0.06,-5.18l-0.6,-1.81l-1.19,-1.47l-1.03,-2.65l0.12,-1.65l0.78,-2.36l-0.25,-1.53l0.19,-2.11l1.62,-1.33l0.46,-1.47l-0.55,-0.61l-1.42,-0.69l0.09,-2.15l-0.97,-1.87l-2.18,-2.42l-1.03,-2.81l-0.75,-0.68l-0.17,-0.96l-0.77,-1.37l-13.99,-43.11Z\", \"name\": \"Georgia\"}, \"US-AZ\": {\"path\": \"M128.51,384.14l0.44,-1.81l1.29,-1.29l0.53,-1.12l0.48,-0.25l1.66,0.62l0.96,-0.03l0.52,-0.46l0.28,-1.17l1.31,-1.0l0.24,-2.73l-0.46,-1.24l-0.84,-0.66l-2.07,-0.66l-0.3,-0.61l0.8,-2.4l0.0,-1.39l-0.52,-1.19l0.57,-0.86l-0.2,-0.87l1.57,-0.27l2.29,-2.81l0.65,-2.43l0.65,-0.81l0.02,-3.17l0.55,-0.62l-0.29,-1.43l1.71,-1.14l1.03,-1.85l3.16,-1.29l2.03,-1.58l0.26,-0.53l-0.13,-1.04l-3.25,-3.49l-0.51,-0.22l0.22,-1.26l-0.66,-1.46l0.07,-0.91l-0.88,-2.76l-0.84,-0.56l-0.19,-1.65l-0.69,-0.8l0.19,-3.54l0.58,-0.87l-0.3,-0.86l1.03,-0.4l0.4,-1.42l0.14,-3.2l-0.76,-3.66l0.76,-2.55l-0.4,-3.0l0.85,-2.56l-0.8,-1.87l-0.03,-0.92l0.78,-1.88l2.54,-0.63l1.75,0.99l1.43,-0.19l0.96,2.24l0.79,0.71l1.54,0.14l1.01,-0.5l1.02,-2.27l0.94,-1.19l2.57,-16.94l42.42,5.78l42.56,4.67l-11.82,123.64l-36.87,-4.05l-36.33,-18.97l-28.43,-15.56Z\", \"name\": \"Arizona\"}, \"US-MT\": {\"path\": \"M166.39,57.3l0.69,-0.1l0.33,-0.38l-0.9,-1.99l0.83,-0.96l-0.39,-1.3l0.09,-0.96l-1.24,-1.93l-0.24,-1.49l-1.03,-1.33l-1.19,-2.44l3.53,-20.64l43.67,6.71l43.04,5.23l42.75,3.84l43.13,2.53l-3.53,86.04l-28.1,-1.47l-26.82,-1.91l-26.78,-2.4l-25.83,-2.79l-0.44,0.35l-1.22,10.41l-1.51,-2.01l-0.03,-0.91l-1.18,-2.35l-1.25,-0.74l-1.8,0.92l0.03,1.05l-0.72,0.42l-0.34,1.56l-2.42,-0.41l-1.91,0.57l-0.92,-0.85l-3.36,0.09l-2.38,-0.96l-1.68,0.58l-0.84,1.49l-4.66,-1.6l-1.3,0.37l-1.12,0.9l-0.31,0.67l-1.65,-1.4l0.22,-1.43l-0.9,-1.71l0.4,-0.36l0.07,-0.62l-1.17,-3.08l-1.45,-1.25l-1.44,0.36l-0.21,-0.64l-1.08,-0.9l-0.41,-1.37l0.68,-0.61l0.2,-1.41l-0.77,-2.38l-0.77,-0.35l-0.31,-1.58l-1.51,-2.54l0.23,-1.51l-0.56,-1.26l0.34,-1.4l-0.73,-0.86l0.48,-0.98l-0.21,-0.74l-1.14,-0.75l-0.13,-0.59l-0.85,-0.91l-0.8,-0.4l-0.51,0.37l-0.07,0.74l-0.7,0.27l-1.13,1.22l-1.75,0.37l-1.21,1.07l-1.08,-0.85l-0.64,-1.01l-1.06,-0.44l0.02,-0.86l0.74,-0.63l0.24,-1.06l-0.61,-1.6l0.9,-1.09l1.07,-0.08l0.83,-0.8l-0.26,-1.14l0.38,-1.07l-0.95,-0.81l-0.04,-0.81l0.66,-1.28l-0.59,-1.07l0.74,-0.07l0.38,-0.42l-0.04,-1.77l1.83,-3.73l-0.14,-1.05l0.89,-0.62l0.6,-3.16l-0.78,-0.5l-1.8,0.37l-1.33,-0.11l-0.64,-0.55l0.37,-0.83l-0.62,-0.97l-0.66,-0.23l-0.72,0.35l-0.07,-0.95l-1.74,-1.62l0.04,-1.84l-1.68,-1.82l-0.08,-0.69l-1.55,-2.88l-1.07,-1.29l-0.57,-1.63l-2.35,-1.34l-0.95,-1.95l-1.43,-1.19Z\", \"name\": \"Montana\"}, \"US-MS\": {\"path\": \"M555.51,431.02l0.67,-0.97l-1.05,-1.76l0.18,-1.63l-0.81,-0.87l1.69,-0.25l0.47,-0.54l0.4,-2.74l-0.77,-1.82l1.56,-1.79l0.25,-3.58l0.74,-2.26l1.89,-1.25l1.15,-1.97l1.4,-1.04l0.34,-0.78l-0.04,-0.99l-0.63,-0.96l1.14,-0.28l0.96,-2.58l0.91,-1.31l-0.16,-0.86l-1.54,-0.43l-0.35,-0.96l-1.83,-1.04l-0.07,-2.14l-0.93,-0.74l-0.45,-0.84l-0.02,-0.37l1.14,-0.29l0.46,-0.69l-0.26,-0.89l-1.41,-0.49l0.23,-1.77l0.98,-1.54l-0.77,-1.06l-1.08,-0.31l-0.15,-2.82l0.9,-0.54l0.23,-0.8l-0.62,-2.52l-1.25,-0.66l0.7,-1.33l-0.07,-2.22l-2.02,-1.52l1.13,-0.47l0.12,-1.41l-1.34,-0.89l1.58,-2.04l0.93,-0.31l0.36,-0.69l-0.52,-1.56l0.42,-1.35l-0.9,-0.89l2.84,-1.1l0.59,-0.76l-0.09,-1.07l-1.41,-0.95l1.39,-1.08l0.62,-1.77l0.94,-0.17l0.34,-0.97l-0.2,-0.77l1.48,-0.43l1.22,-1.21l0.07,-3.53l-0.46,-1.53l0.36,-1.78l0.73,0.09l0.68,-0.33l0.42,-0.87l-0.41,-1.06l2.72,-1.71l0.58,-1.06l-0.29,-1.28l36.44,-4.1l0.86,1.26l0.85,0.45l0.99,66.49l5.52,32.95l-0.73,0.69l-1.53,-0.3l-0.9,-0.94l-1.32,1.06l-1.23,0.17l-2.17,-1.26l-1.85,-0.19l-0.83,0.36l-0.34,0.44l0.32,0.41l-0.56,0.36l-3.96,1.66l-0.05,-0.5l-0.96,-0.52l-1.0,0.05l-0.58,1.0l0.76,0.61l-1.59,1.21l-0.33,1.28l-0.69,0.3l-1.33,-0.06l-1.16,-1.86l-0.08,-0.89l-0.92,-1.47l-0.21,-1.0l-1.4,-1.63l-1.16,-0.54l-0.47,-0.77l0.1,-0.62l-0.69,-0.92l0.21,-1.99l0.5,-0.93l0.66,-2.98l-0.06,-1.22l-0.43,-0.29l-34.66,3.41Z\", \"name\": \"Mississippi\"}, \"US-SC\": {\"path\": \"M697.55,324.05l4.86,-2.69l1.02,-0.05l1.11,-1.38l3.93,-1.9l0.45,-0.88l0.63,0.22l22.71,-3.36l0.07,1.22l0.42,0.57l0.71,0.01l1.21,-1.3l2.82,2.54l0.46,2.48l0.55,0.52l19.74,-3.49l22.74,15.07l0.02,0.55l-2.48,2.18l-2.44,3.67l-2.41,5.72l-0.09,2.74l-1.08,-0.21l0.85,-2.72l-0.63,-0.23l-0.76,0.87l-0.56,1.38l-0.11,1.55l0.83,0.95l1.05,0.23l0.44,0.91l-0.75,0.08l-0.41,0.56l-0.87,0.02l-0.24,0.68l0.94,0.45l-1.1,1.13l-0.07,1.02l-1.34,0.63l-0.5,-0.61l-0.5,-0.08l-1.06,0.87l-0.56,1.77l0.43,0.87l-1.19,1.23l-0.61,1.44l-1.2,1.01l-0.9,-0.4l0.27,-0.6l-0.53,-0.74l-1.37,0.31l0.25,1.2l-0.52,0.03l0.05,0.76l2.02,1.01l-0.12,0.39l-0.88,0.94l-1.22,0.23l-0.24,0.51l0.33,0.45l-2.29,1.34l-1.42,-0.84l-0.56,0.11l-0.1,0.67l1.19,0.78l-1.54,1.57l-0.72,-0.75l-0.5,0.52l-0.0,0.74l-1.54,-0.37l-1.34,-0.84l-0.44,0.5l0.16,0.53l-1.73,0.17l-0.44,0.37l-0.06,0.78l2.07,0.05l-0.26,0.55l0.42,0.25l1.91,-0.15l0.11,0.22l-0.97,0.86l-0.32,0.78l0.57,0.49l0.94,-0.53l0.03,0.21l-1.12,1.09l-0.99,0.43l-0.21,-2.04l-0.69,-0.27l-0.22,-1.54l-0.88,-0.15l-0.3,0.58l0.86,2.69l-1.12,-0.66l-0.63,-1.0l-0.39,-1.76l-0.65,-0.21l-0.52,-0.63l-0.69,0.0l-0.27,0.6l0.84,1.02l0.01,0.68l1.11,1.83l-0.02,0.86l1.22,1.17l-0.62,0.35l0.03,0.98l-1.2,3.56l-1.51,-0.78l-1.52,0.26l-0.97,-0.68l-0.54,-1.03l-0.17,-2.93l-0.86,-0.75l-1.06,-2.47l-1.04,-0.95l-3.23,-1.33l-0.49,-2.65l-1.12,-2.17l-1.43,-1.58l-0.06,-1.07l-0.76,-1.21l-4.81,-1.69l-0.58,-1.27l-1.21,-0.37l0.02,-0.7l-0.53,-0.87l-0.87,0.0l-0.73,-0.61l0.03,-1.21l-0.66,-1.26l-2.7,-1.78l-2.16,-0.52l-2.36,-3.12l-3.93,-1.93l-1.22,-1.03l-0.83,-0.12l-1.04,-1.81l-0.51,-0.22l-0.91,-1.21l-1.18,-0.68l-0.99,-2.42l-1.54,-1.65l-1.02,-1.87l-1.06,-0.37l-1.93,0.37l-0.46,-0.16l-2.75,-2.19l-1.06,0.02l-2.23,-1.27l0.36,-2.22l2.6,-3.31l0.15,-1.07ZM750.36,375.19l0.73,-0.08l0.51,0.45l-1.23,1.9l0.28,-1.22l-0.3,-1.06Z\", \"name\": \"South Carolina\"}, \"US-RI\": {\"path\": \"M851.1,141.46l0.22,-0.46l-0.53,-2.22l-3.14,-10.0l5.61,-1.84l0.76,2.06l0.8,0.25l0.19,0.73l0.08,0.42l-0.77,0.25l0.03,0.29l0.51,1.45l0.59,0.5l-0.75,0.28l-0.3,0.6l0.87,0.97l-0.14,1.23l0.89,1.9l0.03,1.67l-0.27,0.71l-0.9,0.16l-3.59,2.35l-0.18,-1.31ZM855.89,131.53l0.26,0.1l0.01,0.1l-0.17,-0.08l-0.1,-0.12ZM857.28,132.21l0.25,0.54l-0.05,0.32l-0.15,0.01l-0.05,-0.87Z\", \"name\": \"Rhode Island\"}, \"US-AR\": {\"path\": \"M498.76,376.91l-1.42,-38.01l-4.48,-23.98l37.68,-2.58l39.02,-3.58l0.8,1.6l1.01,0.7l0.11,1.77l-0.77,0.57l-0.22,0.94l-1.42,0.93l-0.29,1.04l-0.83,0.54l-1.19,2.59l0.02,0.7l0.53,0.26l10.94,-1.46l0.86,0.93l-1.18,0.37l-0.52,0.96l0.25,0.49l0.84,0.41l-3.6,2.7l0.02,0.84l0.83,1.04l-0.6,1.15l0.62,0.97l-1.42,0.74l-0.11,1.44l-1.45,2.09l0.12,1.64l0.91,3.1l-0.15,0.27l-1.08,-0.01l-0.33,0.26l-0.51,1.73l-1.52,0.95l-0.04,0.51l0.79,0.91l0.05,0.65l-1.11,1.21l-2.02,1.13l-0.21,0.62l0.43,1.0l-0.19,0.27l-1.23,0.03l-0.42,0.67l-0.32,1.89l0.47,1.57l0.02,3.08l-1.27,1.09l-1.54,0.13l0.23,1.49l-0.21,0.48l-0.93,0.25l-0.59,1.77l-1.49,1.19l-0.02,0.93l1.39,0.76l-0.03,0.7l-1.23,0.3l-2.24,1.23l0.03,0.67l0.99,0.82l-0.45,1.14l0.53,1.38l-1.09,0.62l-1.9,2.57l0.52,0.7l1.0,0.49l0.01,0.58l-0.98,0.29l-0.42,0.64l0.51,0.84l1.63,1.01l0.06,1.77l-0.59,0.98l-0.09,0.84l1.34,0.79l0.5,2.17l-1.09,1.01l0.06,2.11l-51.45,4.07l-0.83,-11.53l-1.18,-0.85l-0.9,0.16l-0.83,-0.35l-0.93,0.39l-1.22,-0.33l-0.57,0.72l-0.47,0.01l-0.49,-0.48l-0.82,-0.15l-0.63,-1.0Z\", \"name\": \"Arkansas\"}}, \"height\": 612.395412685768, \"projection\": {\"type\": \"aea\", \"centralMeridian\": -100.0}, \"width\": 900.0});"
  },
  {
    "path": "public/static/plugins/jvectormap/jquery-jvectormap-world-mill-en.js",
    "content": "$.fn.vectorMap('addMap', 'world_mill_en',{\"insets\": [{\"width\": 900.0, \"top\": 0, \"height\": 440.7063107441331, \"bbox\": [{\"y\": -12671671.123330014, \"x\": -20004297.151525836}, {\"y\": 6930392.02513512, \"x\": 20026572.394749384}], \"left\": 0}], \"paths\": {\"BD\": {\"path\": \"M652.71,228.85l-0.04,1.38l-0.46,-0.21l-0.42,0.3l0.05,0.65l-0.17,-1.37l-0.48,-1.26l-1.08,-1.6l-0.23,-0.13l-2.31,-0.11l-0.31,0.36l0.21,0.98l-0.6,1.11l-0.8,-0.4l-0.37,0.09l-0.23,0.3l-0.54,-0.21l-0.78,-0.19l-0.38,-2.04l-0.83,-1.89l0.4,-1.5l-0.16,-0.35l-1.24,-0.57l0.36,-0.62l1.5,-0.95l0.02,-0.49l-1.62,-1.26l0.64,-1.31l1.7,1.0l0.12,0.04l0.96,0.11l0.19,1.62l0.25,0.26l2.38,0.37l2.32,-0.04l1.06,0.33l-0.92,1.79l-0.97,0.13l-0.23,0.16l-0.77,1.51l0.05,0.35l1.37,1.37l0.5,-0.14l0.35,-1.46l0.24,-0.0l1.24,3.92Z\", \"name\": \"Bangladesh\"}, \"BE\": {\"path\": \"M429.28,143.95l1.76,0.25l0.13,-0.01l2.16,-0.64l1.46,1.34l1.26,0.71l-0.23,1.8l-0.44,0.08l-0.24,0.25l-0.2,1.36l-1.8,-1.22l-0.23,-0.05l-1.14,0.23l-1.62,-1.43l-1.15,-1.31l-0.21,-0.1l-0.95,-0.04l-0.21,-0.68l1.66,-0.54Z\", \"name\": \"Belgium\"}, \"BF\": {\"path\": \"M413.48,260.21l-1.22,-0.46l-0.13,-0.02l-1.17,0.1l-0.15,0.06l-0.73,0.53l-0.87,-0.41l-0.39,-0.75l-0.13,-0.13l-0.98,-0.48l-0.14,-1.2l0.63,-0.99l0.05,-0.18l-0.05,-0.73l1.9,-2.01l0.08,-0.14l0.35,-1.65l0.49,-0.44l1.05,0.3l0.21,-0.02l1.05,-0.52l0.13,-0.13l0.3,-0.58l1.87,-1.1l0.11,-0.1l0.43,-0.72l2.23,-1.01l1.21,-0.32l0.51,0.4l0.19,0.06l1.25,-0.01l-0.14,0.89l0.01,0.13l0.34,1.16l0.06,0.11l1.35,1.59l0.07,1.13l0.24,0.28l2.64,0.53l-0.05,1.39l-0.42,0.59l-1.11,0.21l-0.22,0.17l-0.46,0.99l-0.69,0.23l-2.12,-0.05l-1.14,-0.2l-0.19,0.03l-0.72,0.36l-1.07,-0.17l-4.35,0.12l-0.29,0.29l-0.06,1.44l0.25,1.45Z\", \"name\": \"Burkina Faso\"}, \"BG\": {\"path\": \"M477.63,166.84l0.51,0.9l0.33,0.14l0.9,-0.21l1.91,0.47l3.68,0.16l0.17,-0.05l1.2,-0.75l2.78,-0.67l1.72,1.05l1.02,0.24l-0.97,0.97l-0.91,2.17l0.0,0.24l0.56,1.19l-1.58,-0.3l-0.16,0.01l-2.55,0.95l-0.2,0.28l-0.02,1.23l-1.92,0.24l-1.68,-0.99l-0.27,-0.02l-1.94,0.8l-1.52,-0.07l-0.15,-1.72l-0.12,-0.21l-0.99,-0.76l0.18,-0.18l0.02,-0.39l-0.17,-0.22l0.33,-0.75l0.91,-0.91l0.01,-0.42l-1.16,-1.25l-0.18,-0.89l0.24,-0.27Z\", \"name\": \"Bulgaria\"}, \"BA\": {\"path\": \"M468.39,164.66l0.16,0.04l0.43,-0.0l-0.43,0.93l0.06,0.34l1.08,1.06l-0.28,1.09l-0.5,0.13l-0.47,0.28l-0.86,0.74l-0.1,0.16l-0.28,1.29l-1.81,-0.94l-0.9,-1.22l-1.0,-0.73l-1.1,-1.1l-0.55,-0.96l-1.11,-1.3l0.3,-0.75l0.59,0.46l0.42,-0.04l0.46,-0.54l1.0,-0.06l2.11,0.5l1.72,-0.03l1.06,0.64Z\", \"name\": \"Bosnia and Herzegovina\"}, \"BN\": {\"path\": \"M707.34,273.57l0.76,-0.72l1.59,-1.03l-0.18,1.93l-0.9,-0.06l-0.28,0.14l-0.31,0.51l-0.68,-0.78Z\", \"name\": \"Brunei\"}, \"BO\": {\"path\": \"M263.83,340.79l-0.23,-0.12l-2.86,-0.11l-0.28,0.17l-0.77,1.67l-1.17,-1.51l-0.18,-0.11l-3.28,-0.64l-0.28,0.1l-2.02,2.3l-1.43,0.29l-0.91,-3.35l-1.31,-2.88l0.75,-2.41l-0.09,-0.32l-1.23,-1.03l-0.31,-1.76l-0.05,-0.12l-1.12,-1.6l1.49,-2.62l0.01,-0.28l-1.0,-2.0l0.48,-0.72l0.02,-0.29l-0.37,-0.78l0.87,-1.13l0.06,-0.18l0.05,-2.17l0.12,-1.71l0.5,-0.8l0.01,-0.3l-1.9,-3.58l1.3,0.15l1.34,-0.05l0.23,-0.12l0.51,-0.7l2.12,-0.99l1.31,-0.93l2.81,-0.37l-0.21,1.51l0.01,0.13l0.29,0.91l-0.19,1.64l0.11,0.27l2.72,2.27l0.15,0.07l2.71,0.41l0.92,0.88l0.12,0.07l1.64,0.49l1.0,0.71l0.18,0.06l1.5,-0.02l1.24,0.64l0.1,1.31l0.05,0.14l0.44,0.68l0.02,0.73l-0.44,0.03l-0.27,0.39l0.96,2.99l0.28,0.21l4.43,0.1l-0.28,1.12l0.0,0.15l0.27,1.02l0.15,0.19l1.27,0.67l0.52,1.42l-0.42,1.91l-0.66,1.1l-0.04,0.2l0.21,1.3l-0.19,0.13l-0.01,-0.27l-0.15,-0.24l-2.33,-1.33l-0.14,-0.04l-2.38,-0.03l-4.36,0.76l-0.21,0.16l-1.2,2.29l-0.03,0.13l-0.06,1.37l-0.79,2.53l-0.05,-0.08Z\", \"name\": \"Bolivia\"}, \"JP\": {\"path\": \"M781.17,166.78l1.8,0.67l0.28,-0.04l1.38,-1.01l0.43,2.67l-3.44,0.77l-0.18,0.12l-2.04,2.79l-3.71,-1.94l-0.42,0.15l-1.29,3.11l-2.32,0.04l-0.3,-2.63l1.12,-2.1l2.51,-0.16l0.28,-0.25l0.73,-4.22l0.58,-1.9l2.59,2.84l2.0,1.1ZM773.66,187.36l-0.92,2.24l-0.01,0.2l0.4,1.3l-1.18,1.81l-3.06,1.28l-4.35,0.17l-0.19,0.08l-3.4,3.06l-1.36,-0.87l-0.1,-1.95l-0.34,-0.28l-4.35,0.62l-2.99,1.33l-2.87,0.05l-0.28,0.2l0.09,0.33l2.37,1.93l-1.57,4.44l-1.35,0.97l-0.9,-0.79l0.57,-2.32l-0.15,-0.34l-1.5,-0.77l-0.81,-1.53l2.04,-0.75l0.14,-0.1l1.28,-1.72l2.47,-1.43l1.84,-1.92l4.83,-0.82l2.62,0.57l0.33,-0.16l2.45,-4.77l1.38,1.14l0.38,0.0l5.1,-4.02l0.09,-0.11l1.57,-3.57l0.02,-0.16l-0.42,-3.22l0.94,-1.67l2.27,-0.47l1.26,3.82l-0.07,2.23l-2.26,2.86l-0.06,0.19l0.04,2.93ZM757.85,196.18l0.22,0.66l-1.11,1.33l-0.8,-0.7l-0.33,-0.04l-1.28,0.65l-0.14,0.15l-0.54,1.34l-1.17,-0.57l0.02,-1.03l1.2,-1.45l1.24,0.28l0.29,-0.1l0.9,-1.03l1.51,0.5Z\", \"name\": \"Japan\"}, \"BI\": {\"path\": \"M494.7,295.83l-0.14,-2.71l-0.04,-0.13l-0.34,-0.62l0.93,0.12l0.3,-0.16l0.67,-1.25l0.9,0.11l0.11,0.76l0.08,0.16l0.46,0.48l0.02,0.56l-0.55,0.48l-0.96,1.29l-0.82,0.82l-0.61,0.07Z\", \"name\": \"Burundi\"}, \"BJ\": {\"path\": \"M427.4,268.94l-1.58,0.22l-0.52,-1.45l0.11,-5.73l-0.08,-0.21l-0.43,-0.44l-0.09,-1.13l-0.09,-0.19l-1.52,-1.52l0.24,-1.01l0.7,-0.23l0.18,-0.16l0.45,-0.97l1.07,-0.21l0.19,-0.12l0.53,-0.73l0.73,-0.65l0.68,-0.0l1.69,1.3l-0.08,0.67l0.02,0.14l0.52,1.38l-0.44,0.9l-0.01,0.24l0.2,0.52l-1.1,1.42l-0.76,0.76l-0.08,0.13l-0.47,1.59l0.05,1.69l-0.13,3.79Z\", \"name\": \"Benin\"}, \"BT\": {\"path\": \"M650.38,213.78l0.88,0.75l-0.13,1.24l-1.77,0.07l-2.1,-0.18l-1.57,0.4l-2.02,-0.91l-0.02,-0.24l1.54,-1.87l1.18,-0.6l1.67,0.59l1.32,0.08l1.01,0.67Z\", \"name\": \"Bhutan\"}, \"JM\": {\"path\": \"M226.67,238.37l1.64,0.23l1.2,0.56l0.11,0.19l-1.25,0.03l-0.14,0.04l-0.65,0.37l-1.24,-0.37l-1.17,-0.77l0.11,-0.22l0.86,-0.15l0.52,0.08Z\", \"name\": \"Jamaica\"}, \"BW\": {\"path\": \"M484.91,331.96l0.53,0.52l0.82,1.53l2.83,2.86l0.14,0.08l0.85,0.22l0.03,0.81l0.74,1.66l0.21,0.17l1.87,0.39l1.17,0.87l-3.13,1.71l-2.3,2.01l-0.07,0.1l-0.82,1.74l-0.66,0.88l-1.24,0.19l-0.24,0.2l-0.65,1.98l-1.4,0.55l-1.9,-0.12l-1.2,-0.74l-1.06,-0.32l-0.22,0.02l-1.22,0.62l-0.14,0.14l-0.58,1.21l-1.16,0.79l-1.18,1.13l-1.5,0.23l-0.4,-0.68l0.22,-1.53l-0.04,-0.19l-1.48,-2.54l-0.11,-0.11l-0.53,-0.31l-0.0,-7.25l2.18,-0.08l0.29,-0.3l0.07,-9.0l1.63,-0.08l3.69,-0.86l0.84,0.93l0.38,0.05l1.53,-0.97l0.79,-0.03l1.3,-0.53l0.23,0.1l0.92,1.96Z\", \"name\": \"Botswana\"}, \"BR\": {\"path\": \"M259.49,274.87l1.42,0.25l1.97,0.62l0.28,-0.05l0.67,-0.55l1.76,-0.38l2.8,-0.94l0.12,-0.08l0.92,-0.96l0.05,-0.33l-0.15,-0.32l0.73,-0.06l0.36,0.35l-0.27,0.93l0.17,0.36l0.76,0.34l0.44,0.9l-0.58,0.73l-0.06,0.13l-0.4,2.13l0.03,0.19l0.62,1.22l0.17,1.11l0.11,0.19l1.54,1.18l0.15,0.06l1.23,0.12l0.29,-0.15l0.2,-0.36l0.71,-0.11l1.13,-0.44l0.79,-0.63l1.25,0.19l0.65,-0.08l1.32,0.2l0.32,-0.18l0.23,-0.51l-0.05,-0.31l-0.31,-0.37l0.11,-0.31l0.75,0.17l0.13,0.0l1.1,-0.24l1.34,0.5l1.08,0.51l0.33,-0.05l0.67,-0.58l0.27,0.05l0.28,0.57l0.31,0.17l1.2,-0.18l0.17,-0.08l1.03,-1.05l0.76,-1.82l1.39,-2.16l0.49,-0.07l0.52,1.17l1.4,4.37l0.2,0.2l1.14,0.35l0.05,1.39l-1.8,1.97l0.01,0.42l0.78,0.75l0.18,0.08l4.16,0.37l0.08,2.25l0.5,0.22l1.78,-1.54l2.98,0.85l4.07,1.5l1.07,1.28l-0.37,1.23l0.36,0.38l2.83,-0.75l4.8,1.3l3.75,-0.09l3.6,2.02l3.27,2.84l1.93,0.72l2.13,0.11l0.76,0.66l1.22,4.56l-0.96,4.03l-1.22,1.58l-3.52,3.51l-1.63,2.91l-1.75,2.09l-0.5,0.04l-0.26,0.19l-0.72,1.99l0.18,4.76l-0.95,5.56l-0.74,0.96l-0.06,0.15l-0.43,3.39l-2.49,3.34l-0.06,0.13l-0.4,2.56l-1.9,1.07l-0.13,0.16l-0.51,1.38l-2.59,0.0l-3.94,1.01l-1.82,1.19l-2.85,0.81l-3.01,2.17l-2.12,2.65l-0.06,0.13l-0.36,2.0l0.01,0.13l0.4,1.42l-0.45,2.63l-0.53,1.23l-1.76,1.53l-2.76,4.79l-2.16,2.15l-1.69,1.29l-0.09,0.12l-1.12,2.6l-1.3,1.26l-0.45,-1.02l0.99,-1.18l0.01,-0.37l-1.5,-1.95l-1.98,-1.54l-2.58,-1.77l-0.2,-0.05l-0.81,0.07l-2.42,-2.05l-0.25,-0.07l-0.77,0.14l2.75,-3.07l2.8,-2.61l1.67,-1.09l2.11,-1.49l0.13,-0.24l0.05,-2.15l-0.07,-0.2l-1.26,-1.54l-0.35,-0.09l-0.64,0.27l0.3,-0.95l0.34,-1.57l0.01,-1.52l-0.16,-0.26l-0.9,-0.48l-0.27,-0.01l-0.86,0.39l-0.65,-0.08l-0.23,-0.8l-0.23,-2.39l-0.04,-0.12l-0.47,-0.79l-0.14,-0.12l-1.69,-0.71l-0.25,0.01l-0.93,0.47l-2.29,-0.44l0.15,-3.3l-0.03,-0.15l-0.62,-1.22l0.57,-0.39l0.13,-0.3l-0.22,-1.37l0.67,-1.13l0.44,-2.04l-0.01,-0.17l-0.59,-1.61l-0.14,-0.16l-1.25,-0.66l-0.22,-0.82l0.35,-1.41l-0.28,-0.37l-4.59,-0.1l-0.78,-2.41l0.34,-0.02l0.28,-0.31l-0.03,-1.1l-0.05,-0.16l-0.45,-0.68l-0.1,-1.4l-0.16,-0.24l-1.45,-0.76l-0.14,-0.03l-1.48,0.02l-1.04,-0.73l-1.62,-0.48l-0.93,-0.9l-0.16,-0.08l-2.72,-0.41l-2.53,-2.12l0.18,-1.54l-0.01,-0.13l-0.29,-0.91l0.26,-1.83l-0.34,-0.34l-3.28,0.43l-0.14,0.05l-1.3,0.93l-2.16,1.01l-0.12,0.09l-0.47,0.65l-1.12,0.05l-1.84,-0.21l-0.12,0.01l-1.33,0.41l-0.82,-0.21l0.16,-3.6l-0.48,-0.26l-1.97,1.43l-1.96,-0.06l-0.86,-1.23l-0.22,-0.13l-1.23,-0.11l0.34,-0.69l-0.05,-0.33l-1.36,-1.5l-0.92,-2.0l0.45,-0.32l0.13,-0.25l-0.0,-0.87l1.34,-0.64l0.17,-0.32l-0.23,-1.23l0.56,-0.77l0.05,-0.13l0.16,-1.03l2.7,-1.61l2.01,-0.47l0.16,-0.09l0.24,-0.27l2.11,0.11l0.31,-0.25l1.13,-6.87l0.06,-1.12l-0.4,-1.53l-0.1,-0.15l-1.0,-0.82l0.01,-1.45l1.08,-0.32l0.39,0.2l0.44,-0.24l0.08,-0.96l-0.25,-0.32l-1.22,-0.22l-0.02,-1.01l4.57,0.05l0.22,-0.09l0.6,-0.63l0.44,0.5l0.47,1.42l0.45,0.16l0.27,-0.18l1.21,1.16l0.23,0.08l1.95,-0.16l0.23,-0.14l0.43,-0.67l1.76,-0.55l1.05,-0.42l0.18,-0.2l0.25,-0.92l1.65,-0.66l0.18,-0.35l-0.14,-0.53l-0.26,-0.22l-1.91,-0.19l-0.29,-1.33l0.1,-1.64l-0.15,-0.28l-0.44,-0.25Z\", \"name\": \"Brazil\"}, \"BS\": {\"path\": \"M227.51,216.69l0.3,0.18l-0.24,1.07l0.03,-1.04l-0.09,-0.21ZM226.5,224.03l-0.13,0.03l-0.54,-1.3l-0.09,-0.12l-0.78,-0.64l0.4,-1.26l0.33,0.05l0.79,2.0l0.01,1.24ZM225.76,216.5l-2.16,0.34l-0.07,-0.41l0.85,-0.16l1.36,0.07l0.02,0.16Z\", \"name\": \"The Bahamas\"}, \"BY\": {\"path\": \"M480.08,135.28l2.09,0.02l0.13,-0.03l2.72,-1.3l0.16,-0.19l0.55,-1.83l1.94,-1.06l0.15,-0.31l-0.2,-1.33l1.33,-0.52l2.58,-1.3l2.39,0.8l0.3,0.75l0.37,0.17l1.22,-0.39l2.18,0.75l0.2,1.36l-0.48,0.85l0.01,0.32l1.57,2.26l0.92,0.6l-0.1,0.41l0.19,0.35l1.61,0.57l0.48,0.6l-0.64,0.49l-1.91,-0.11l-0.18,0.05l-0.48,0.32l-0.1,0.39l0.57,1.1l0.51,1.78l-1.79,0.17l-0.18,0.08l-0.77,0.73l-0.09,0.19l-0.13,1.31l-0.75,-0.22l-2.11,0.15l-0.56,-0.66l-0.39,-0.06l-0.8,0.49l-0.79,-0.4l-0.13,-0.03l-1.94,-0.07l-2.76,-0.79l-2.58,-0.27l-1.98,0.07l-0.15,0.05l-1.31,0.86l-0.8,0.09l-0.04,-1.16l-0.03,-0.12l-0.63,-1.28l1.22,-0.56l0.17,-0.27l0.01,-1.35l-0.04,-0.15l-0.66,-1.24l-0.08,-1.12Z\", \"name\": \"Belarus\"}, \"BZ\": {\"path\": \"M198.03,239.7l0.28,0.19l0.43,-0.1l0.82,-1.42l0.0,0.07l0.29,0.29l0.16,0.0l-0.02,0.35l-0.39,1.08l0.02,0.25l0.16,0.29l-0.23,0.8l0.04,0.24l0.09,0.14l-0.25,1.12l-0.38,0.53l-0.33,0.06l-0.21,0.15l-0.41,0.74l-0.25,0.0l0.17,-2.58l0.01,-2.2Z\", \"name\": \"Belize\"}, \"RU\": {\"path\": \"M688.57,38.85l0.63,2.39l0.44,0.19l2.22,-1.23l7.18,0.07l5.54,2.49l1.85,1.77l-0.55,2.34l-2.64,1.42l-6.57,2.76l-1.95,1.5l0.12,0.53l3.09,0.68l3.69,1.23l0.21,-0.01l1.98,-0.81l1.16,2.84l0.5,0.08l1.03,-1.18l3.86,-0.74l7.79,0.78l0.56,2.05l0.27,0.22l10.47,0.71l0.32,-0.29l0.13,-3.34l4.98,0.8l3.96,-0.02l3.88,2.43l1.06,2.79l-1.38,1.83l0.01,0.38l3.15,3.64l0.1,0.08l3.94,1.86l0.4,-0.14l2.28,-4.56l3.75,1.94l0.22,0.02l4.18,-1.22l4.76,1.4l0.26,-0.04l1.74,-1.23l3.98,0.63l0.32,-0.41l-1.71,-4.1l3.0,-1.86l22.39,3.04l2.06,2.67l0.1,0.08l6.55,3.51l0.17,0.03l10.08,-0.86l4.86,0.73l1.91,1.72l-0.29,3.13l0.18,0.31l3.08,1.26l0.19,0.01l3.32,-0.9l4.37,-0.11l4.78,0.87l4.61,-0.48l4.26,3.82l0.32,0.05l3.1,-1.4l0.12,-0.45l-1.91,-2.67l0.92,-1.64l7.78,1.22l5.22,-0.26l7.12,2.1l9.6,5.22l6.4,4.15l-0.2,2.44l0.14,0.28l1.69,1.04l0.45,-0.31l-0.51,-2.66l6.31,0.58l4.52,3.61l-2.1,1.52l-4.02,0.42l-0.27,0.29l-0.06,3.83l-0.81,0.67l-2.14,-0.11l-1.91,-1.39l-3.19,-1.13l-0.51,-1.63l-0.21,-0.2l-2.54,-0.67l-0.13,-0.0l-2.69,0.5l-1.12,-1.19l0.48,-1.36l-0.38,-0.39l-3.0,0.98l-0.17,0.44l1.02,1.76l-1.27,1.55l-3.09,1.71l-3.15,-0.29l-0.3,0.18l0.07,0.34l2.22,2.1l1.47,3.22l1.15,1.09l0.25,1.41l-0.48,0.76l-4.47,-0.81l-0.17,0.02l-6.97,2.9l-2.2,0.44l-0.11,0.05l-3.83,2.68l-3.63,2.32l-0.1,0.11l-0.76,1.4l-3.3,-2.4l-0.3,-0.03l-6.31,2.85l-0.99,-1.21l-0.4,-0.06l-2.32,1.54l-3.23,-0.49l-0.33,0.2l-0.79,2.39l-2.97,3.51l-0.07,0.21l0.09,1.47l0.22,0.27l2.62,0.74l-0.3,4.7l-2.06,0.12l-0.26,0.2l-1.07,2.94l0.04,0.27l0.83,1.19l-4.03,1.63l-0.18,0.21l-0.83,3.72l-3.55,0.79l-0.23,0.23l-0.73,3.32l-3.22,2.76l-0.76,-1.88l-1.07,-4.88l-1.39,-7.59l1.17,-4.76l2.05,-2.08l0.09,-0.19l0.11,-1.46l3.67,-0.77l0.15,-0.08l4.47,-4.61l4.29,-3.82l4.48,-3.01l0.11,-0.14l2.01,-5.43l-0.31,-0.4l-3.04,0.33l-0.24,0.17l-1.47,3.11l-5.98,3.94l-1.91,-4.36l-0.33,-0.17l-6.46,1.3l-0.15,0.08l-6.27,6.33l-0.01,0.41l1.7,1.87l-5.04,0.87l-3.51,0.34l0.16,-2.32l-0.26,-0.32l-3.89,-0.56l-0.19,0.04l-3.02,1.77l-7.63,-0.63l-8.24,1.1l-0.16,0.07l-8.11,7.09l-9.6,8.31l0.16,0.52l3.79,0.42l1.16,2.03l0.17,0.14l2.43,0.76l0.31,-0.08l1.5,-1.61l2.49,0.2l3.46,3.6l0.08,2.67l-1.91,3.26l-0.04,0.14l-0.21,3.91l-1.11,5.09l-3.73,4.55l-0.87,2.21l-6.73,7.14l-1.59,1.77l-3.23,1.72l-1.38,0.03l-1.48,-1.39l-0.37,-0.03l-3.36,2.22l-0.11,0.14l-0.16,0.42l-0.01,-1.09l1.0,-0.06l0.28,-0.27l0.36,-3.6l-0.61,-2.51l1.85,-0.94l2.94,0.53l0.32,-0.15l1.71,-3.1l0.84,-3.38l0.97,-1.18l1.32,-2.88l-0.34,-0.42l-4.14,0.95l-2.18,1.25l-3.51,-0.0l-0.95,-2.81l-0.1,-0.14l-2.97,-2.3l-0.11,-0.05l-4.19,-1.0l-0.89,-3.08l-0.87,-2.03l-0.95,-1.46l-1.54,-3.37l-0.12,-0.14l-2.27,-1.28l-3.83,-1.02l-3.37,0.1l-3.11,0.61l-0.13,0.06l-2.07,1.69l0.04,0.49l1.23,0.72l0.03,1.53l-1.34,1.05l-2.26,3.51l-0.05,0.17l0.02,1.27l-3.25,1.9l-2.87,-1.17l-0.14,-0.02l-2.86,0.26l-1.22,-1.02l-0.12,-0.06l-1.5,-0.35l-0.23,0.04l-3.62,2.27l-3.24,0.53l-2.28,0.79l-3.08,-0.51l-2.24,0.03l-1.49,-1.61l-2.45,-1.57l-0.11,-0.04l-2.6,-0.43l-3.17,0.43l-2.31,0.59l-3.31,-1.28l-0.45,-2.31l-0.21,-0.23l-2.94,-0.85l-2.26,-0.39l-2.77,-1.36l-0.37,0.09l-2.59,3.45l-0.03,0.32l0.91,1.74l-2.15,2.01l-3.47,-0.79l-2.44,-0.12l-1.59,-1.46l-0.2,-0.08l-2.55,-0.05l-2.12,-0.98l-0.24,-0.01l-3.85,1.57l-4.74,2.79l-2.59,0.55l-0.79,0.21l-1.21,-1.81l-0.29,-0.13l-3.05,0.41l-0.96,-1.25l-0.14,-0.1l-1.65,-0.6l-1.15,-1.82l-0.13,-0.12l-1.38,-0.6l-0.19,-0.02l-3.49,0.82l-3.35,-1.85l-0.38,0.08l-1.08,1.4l-5.36,-8.17l-3.02,-2.52l0.72,-0.85l0.01,-0.38l-0.37,-0.08l-6.22,3.21l-1.98,0.16l0.17,-1.51l-0.2,-0.31l-3.22,-1.17l-0.19,-0.0l-2.3,0.74l-0.72,-3.27l-0.24,-0.23l-4.5,-0.75l-0.21,0.04l-2.2,1.42l-6.21,1.27l-0.11,0.05l-1.16,0.81l-9.3,1.19l-0.18,0.09l-1.15,1.17l-0.02,0.39l1.56,2.01l-2.02,0.74l-0.16,0.42l0.35,0.68l-2.18,1.49l0.02,0.51l3.83,2.16l-0.45,1.13l-3.31,-0.13l-0.25,0.12l-0.57,0.77l-2.97,-1.59l-0.15,-0.04l-3.97,0.07l-0.13,0.03l-2.53,1.32l-2.84,-1.28l-5.52,-2.3l-0.12,-0.02l-3.91,0.09l-0.16,0.05l-5.17,3.6l-0.13,0.21l-0.25,1.89l-2.17,-1.6l-0.44,0.1l-2.0,3.59l0.06,0.37l0.55,0.5l-1.32,2.23l0.04,0.36l2.13,2.17l0.23,0.09l1.7,-0.08l1.42,1.89l-0.23,1.5l0.19,0.32l0.94,0.38l-0.89,1.44l-2.3,0.49l-0.17,0.11l-2.49,3.2l0.0,0.37l2.2,2.81l-0.23,1.93l0.06,0.22l2.56,3.32l-1.27,1.02l-0.4,0.66l-0.8,-0.15l-1.65,-1.75l-0.18,-0.09l-0.66,-0.09l-1.45,-0.64l-0.72,-1.16l-0.18,-0.13l-2.34,-0.63l-0.17,0.0l-1.32,0.41l-0.31,-0.4l-0.12,-0.09l-3.49,-1.48l-3.67,-0.49l-2.1,-0.52l-0.3,0.1l-0.12,0.14l-2.96,-2.4l-2.89,-1.19l-1.69,-1.42l1.27,-0.35l0.16,-0.1l2.08,-2.61l-0.04,-0.41l-1.02,-0.9l3.21,-1.12l0.2,-0.31l-0.07,-0.69l-0.37,-0.26l-1.86,0.42l0.05,-0.86l1.11,-0.76l2.35,-0.23l0.25,-0.19l0.39,-1.07l0.0,-0.19l-0.51,-1.64l0.95,-1.58l0.04,-0.16l-0.03,-0.95l-0.22,-0.28l-3.69,-1.06l-1.43,0.02l-1.45,-1.44l-0.29,-0.08l-1.83,0.49l-2.88,-1.04l0.04,-0.42l-0.04,-0.18l-0.89,-1.43l-0.23,-0.14l-1.77,-0.14l-0.13,-0.66l0.52,-0.56l0.01,-0.4l-1.6,-1.9l-0.27,-0.1l-2.55,0.32l-0.71,-0.16l-0.3,0.1l-0.53,0.63l-0.58,-0.08l-0.56,-1.97l-0.48,-0.94l0.17,-0.11l1.92,0.11l0.2,-0.06l0.97,-0.74l0.05,-0.42l-0.72,-0.91l-0.13,-0.1l-1.43,-0.51l0.09,-0.36l-0.13,-0.33l-0.97,-0.59l-1.43,-2.06l0.44,-0.77l0.04,-0.19l-0.25,-1.64l-0.2,-0.24l-2.45,-0.84l-0.19,-0.0l-1.05,0.34l-0.25,-0.62l-0.18,-0.17l-2.5,-0.84l-0.74,-1.93l-0.21,-1.7l-0.13,-0.21l-0.92,-0.63l0.83,-0.89l0.07,-0.27l-0.71,-3.26l1.69,-2.01l0.03,-0.34l-0.24,-0.41l2.63,-1.9l-0.01,-0.49l-2.31,-1.57l5.08,-4.61l2.33,-2.24l1.01,-2.08l-0.09,-0.37l-3.52,-2.56l0.94,-2.38l-0.04,-0.29l-2.14,-2.86l1.61,-3.35l-0.01,-0.29l-2.81,-4.58l2.19,-3.04l-0.06,-0.42l-3.7,-2.76l0.32,-2.67l1.87,-0.38l4.26,-1.77l2.46,-1.47l3.96,2.58l0.12,0.05l6.81,1.04l9.37,4.87l1.81,1.92l0.15,2.55l-2.61,2.06l-3.95,1.07l-11.1,-3.15l-0.17,0.0l-1.84,0.53l-0.1,0.53l3.97,2.97l0.15,1.77l0.16,4.14l0.19,0.27l3.21,1.22l1.94,1.03l0.44,-0.22l0.32,-1.94l-0.07,-0.25l-1.32,-1.52l1.25,-1.2l5.87,2.45l0.24,-0.01l2.11,-0.98l0.13,-0.42l-1.55,-2.75l5.52,-3.84l2.13,0.22l2.28,1.42l0.43,-0.12l1.46,-2.87l-0.04,-0.33l-1.97,-2.37l1.14,-2.38l-0.02,-0.3l-1.42,-2.07l6.15,1.22l1.14,1.92l-2.74,0.46l-0.25,0.3l0.02,2.36l0.12,0.24l1.97,1.44l0.25,0.05l3.87,-0.91l0.22,-0.23l0.58,-2.55l5.09,-1.98l8.67,-3.69l1.22,0.14l-2.06,2.2l0.18,0.5l3.11,0.45l0.23,-0.07l1.71,-1.41l4.59,-0.12l0.12,-0.03l3.53,-1.72l2.7,2.48l0.42,-0.01l2.85,-2.88l-0.0,-0.43l-2.42,-2.35l1.0,-1.13l7.2,1.31l3.42,1.36l9.06,4.97l0.39,-0.08l1.67,-2.27l-0.04,-0.4l-2.46,-2.23l-0.06,-0.82l-0.26,-0.27l-2.64,-0.38l0.69,-1.76l0.0,-0.22l-1.32,-3.47l-0.07,-1.27l4.52,-4.09l0.08,-0.11l1.6,-4.18l1.67,-0.84l6.33,1.2l0.46,2.31l-2.31,3.67l0.05,0.38l1.49,1.41l0.77,3.04l-0.56,6.05l0.09,0.24l2.62,2.54l-0.99,2.65l-4.87,5.96l0.17,0.48l2.86,0.61l0.31,-0.13l0.94,-1.42l2.67,-1.04l0.18,-0.19l0.64,-2.01l2.11,-1.98l0.05,-0.37l-1.38,-2.32l1.11,-2.74l-0.24,-0.41l-2.53,-0.33l-0.53,-2.16l1.96,-4.42l-0.05,-0.32l-3.03,-3.48l4.21,-2.94l0.12,-0.3l-0.52,-3.04l0.72,-0.06l1.18,2.35l-0.97,4.39l0.2,0.35l2.68,0.84l0.37,-0.38l-1.05,-3.07l3.89,-1.71l5.05,-0.24l4.55,2.62l0.36,-0.05l0.05,-0.36l-2.19,-3.84l-0.23,-4.78l4.07,-0.92l5.98,0.21l5.47,-0.64l0.2,-0.48l-1.88,-2.37l2.65,-2.99l2.75,-0.13l0.12,-0.03l4.82,-2.48l6.56,-0.67l0.23,-0.14l0.76,-1.27l6.33,-0.46l1.97,1.11l0.28,0.01l5.55,-2.71l4.53,0.08l0.29,-0.21l0.67,-2.18l2.29,-2.15l5.75,-2.13l3.48,1.4l-2.7,1.03l-0.19,0.31l0.26,0.26l5.47,0.78ZM871.83,65.73l0.25,-0.15l1.99,0.01l3.3,1.2l-0.08,0.22l-2.41,1.03l-5.73,0.49l-0.31,-1.0l2.99,-1.8ZM797.64,48.44l-2.22,1.51l-3.85,-0.43l-4.35,-1.85l0.42,-1.13l4.42,0.72l5.59,1.17ZM783.82,46.06l-1.71,3.25l-9.05,-0.14l-4.11,1.15l-4.64,-3.04l1.21,-3.13l3.11,-0.91l6.53,0.22l8.66,2.59ZM780.37,145.71l2.28,5.23l-3.09,-0.89l-0.37,0.19l-1.54,4.65l0.04,0.27l2.38,3.17l-0.05,1.4l-1.41,-1.41l-0.46,0.04l-1.23,1.81l-0.33,-1.86l0.28,-3.1l-0.28,-3.41l0.58,-2.46l0.11,-4.39l-0.03,-0.13l-1.44,-3.2l0.21,-4.39l2.19,-1.49l0.09,-0.41l-0.81,-1.3l0.48,-0.21l0.56,1.94l0.86,3.23l-0.05,3.36l1.03,3.35ZM780.16,57.18l-3.4,0.03l-5.06,-0.53l1.97,-1.59l2.95,-0.42l3.35,1.75l0.18,0.77ZM683.84,31.18l-13.29,1.97l4.16,-6.56l1.88,-0.58l1.77,0.34l6.08,3.02l-0.6,1.8ZM670.94,28.02l-5.18,0.65l-6.89,-1.58l-4.03,-2.07l-1.88,-3.98l-0.18,-0.16l-2.8,-0.93l5.91,-3.62l5.25,-1.29l4.73,2.88l5.63,5.44l-0.57,4.66ZM564.37,68.98l-0.85,0.23l-7.93,-0.57l-0.6,-1.84l-0.21,-0.2l-4.34,-1.18l-0.3,-2.08l2.34,-0.92l0.19,-0.29l-0.08,-2.43l4.85,-4.0l-0.12,-0.52l-1.68,-0.43l5.47,-3.94l0.11,-0.33l-0.6,-2.02l5.36,-2.55l8.22,-3.27l8.29,-0.96l4.34,-1.94l4.67,-0.65l1.45,1.72l-1.43,1.37l-8.8,2.52l-7.65,2.42l-7.92,4.84l-3.73,4.75l-3.92,4.58l-0.07,0.23l0.51,3.88l0.11,0.2l4.32,3.39ZM548.86,18.57l-3.28,0.75l-2.25,0.44l-0.22,0.19l-0.3,0.81l-2.67,0.86l-2.27,-1.14l1.2,-1.51l-0.23,-0.49l-3.14,-0.1l2.48,-0.54l3.55,-0.07l0.44,1.36l0.49,0.12l1.4,-1.35l2.2,-0.9l3.13,1.08l-0.54,0.49ZM477.5,133.25l-4.21,0.05l-2.69,-0.34l0.39,-1.03l3.24,-1.06l2.51,0.58l0.85,0.43l-0.2,0.71l-0.0,0.15l0.12,0.52Z\", \"name\": \"Russia\"}, \"RW\": {\"path\": \"M497.03,288.12l0.78,1.11l-0.12,1.19l-0.49,0.21l-1.25,-0.15l-0.3,0.16l-0.67,1.24l-1.01,-0.13l0.16,-0.92l0.22,-0.12l0.15,-0.24l0.09,-1.37l0.49,-0.48l0.42,0.18l0.25,-0.01l1.26,-0.65Z\", \"name\": \"Rwanda\"}, \"RS\": {\"path\": \"M469.75,168.65l0.21,-0.21l0.36,-1.44l-0.08,-0.29l-1.06,-1.03l0.54,-1.16l-0.28,-0.43l-0.26,0.0l0.55,-0.67l-0.01,-0.39l-0.77,-0.86l-0.45,-0.89l1.56,-0.67l1.39,0.12l1.22,1.1l0.26,0.91l0.16,0.19l1.38,0.66l0.17,1.12l0.14,0.21l1.46,0.9l0.35,-0.03l0.62,-0.54l0.09,0.06l-0.28,0.25l-0.03,0.42l0.29,0.34l-0.44,0.5l-0.07,0.26l0.22,1.12l0.07,0.14l1.02,1.1l-0.81,0.84l-0.42,0.96l0.04,0.3l0.12,0.15l-0.15,0.16l-1.04,0.04l-0.39,0.08l0.33,-0.81l-0.29,-0.41l-0.21,0.01l-0.39,-0.45l-0.13,-0.09l-0.32,-0.11l-0.27,-0.4l-0.14,-0.11l-0.4,-0.16l-0.31,-0.37l-0.34,-0.09l-0.45,0.17l-0.18,0.18l-0.29,0.84l-0.96,-0.65l-0.81,-0.33l-0.32,-0.37l-0.22,-0.18Z\", \"name\": \"Republic of Serbia\"}, \"LT\": {\"path\": \"M478.13,133.31l-0.14,-0.63l0.25,-0.88l-0.15,-0.35l-1.17,-0.58l-2.43,-0.57l-0.45,-2.51l2.58,-0.97l4.14,0.22l2.3,-0.32l0.26,0.54l0.22,0.17l1.26,0.22l2.25,1.6l0.19,1.23l-1.87,1.01l-0.14,0.18l-0.54,1.83l-2.54,1.21l-2.18,-0.02l-0.52,-0.91l-0.18,-0.14l-1.11,-0.32Z\", \"name\": \"Lithuania\"}, \"LU\": {\"path\": \"M435.95,147.99l0.33,0.49l-0.11,1.07l-0.39,0.04l-0.29,-0.15l0.21,-1.4l0.25,-0.05Z\", \"name\": \"Luxembourg\"}, \"LR\": {\"path\": \"M401.37,273.67l-0.32,0.01l-2.48,-1.15l-2.24,-1.89l-2.14,-1.38l-1.47,-1.42l0.44,-0.59l0.05,-0.13l0.12,-0.65l1.07,-1.3l1.08,-1.09l0.52,-0.07l0.43,-0.18l0.84,1.24l-0.15,0.89l0.07,0.25l0.49,0.54l0.22,0.1l0.71,0.01l0.27,-0.16l0.42,-0.83l0.19,0.02l-0.06,0.52l0.23,1.12l-0.5,1.03l0.06,0.35l0.73,0.69l0.14,0.08l0.71,0.15l0.92,0.91l0.06,0.76l-0.17,0.22l-0.06,0.15l-0.17,1.8Z\", \"name\": \"Liberia\"}, \"RO\": {\"path\": \"M477.94,155.19l1.02,-0.64l1.49,0.33l1.52,0.01l1.09,0.73l0.32,0.01l0.81,-0.46l1.8,-0.3l0.18,-0.1l0.54,-0.64l0.86,0.0l0.64,0.26l0.71,0.87l0.8,1.35l1.39,1.81l0.07,1.25l-0.26,1.3l0.01,0.15l0.45,1.42l0.15,0.18l1.12,0.57l0.25,0.01l1.05,-0.45l0.86,0.4l0.03,0.43l-0.92,0.51l-0.63,-0.24l-0.4,0.22l-0.64,3.41l-1.12,-0.24l-1.78,-1.09l-0.23,-0.04l-2.95,0.71l-1.25,0.77l-3.55,-0.16l-1.89,-0.47l-0.14,-0.0l-0.75,0.17l-0.61,-1.07l-0.3,-0.36l0.36,-0.32l-0.04,-0.48l-0.62,-0.38l-0.36,0.03l-0.62,0.54l-1.15,-0.71l-0.18,-1.14l-0.17,-0.22l-1.4,-0.67l-0.24,-0.86l-0.09,-0.14l-0.96,-0.87l1.49,-0.44l0.16,-0.11l1.51,-2.14l1.15,-2.09l1.44,-0.63Z\", \"name\": \"Romania\"}, \"GW\": {\"path\": \"M383.03,256.73l-1.12,-0.88l-0.14,-0.06l-0.94,-0.15l-0.43,-0.54l0.01,-0.27l-0.13,-0.26l-0.68,-0.48l-0.05,-0.16l0.99,-0.31l0.77,0.08l0.15,-0.02l0.61,-0.26l4.25,0.1l-0.02,0.44l-0.19,0.18l-0.08,0.29l0.17,0.66l-0.17,0.14l-0.44,0.0l-0.16,0.05l-0.57,0.37l-0.66,-0.04l-0.24,0.1l-0.92,1.03Z\", \"name\": \"Guinea Bissau\"}, \"GT\": {\"path\": \"M195.13,249.89l-1.05,-0.35l-1.5,-0.04l-1.06,-0.47l-1.19,-0.93l0.04,-0.53l0.27,-0.55l-0.03,-0.31l-0.24,-0.32l1.02,-1.77l3.04,-0.01l0.3,-0.28l0.06,-0.88l-0.19,-0.3l-0.3,-0.11l-0.23,-0.45l-0.11,-0.12l-0.9,-0.58l-0.35,-0.33l0.37,-0.0l0.3,-0.3l0.0,-1.15l4.05,0.02l-0.02,1.74l-0.2,2.89l0.3,0.32l0.67,-0.0l0.75,0.42l0.4,-0.11l-0.62,0.53l-1.17,0.7l-0.13,0.16l-0.18,0.49l0.0,0.21l0.14,0.34l-0.35,0.44l-0.49,0.13l-0.2,0.41l0.03,0.06l-0.27,0.16l-0.86,0.64l-0.12,0.22ZM199.35,245.38l0.07,-0.13l0.05,0.02l-0.13,0.11Z\", \"name\": \"Guatemala\"}, \"GR\": {\"path\": \"M487.2,174.55l-0.64,1.54l-0.43,0.24l-1.41,-0.08l-1.28,-0.28l-0.14,0.0l-3.03,0.77l-0.13,0.51l1.39,1.34l-0.78,0.29l-1.2,0.0l-1.23,-1.42l-0.47,0.02l-0.47,0.65l-0.04,0.27l0.56,1.76l0.06,0.11l1.02,1.12l-0.66,0.45l-0.04,0.46l1.39,1.35l1.15,0.79l0.02,1.06l-1.91,-0.63l-0.36,0.42l0.56,1.12l-1.2,0.23l-0.22,0.4l0.8,2.14l-1.15,0.02l-1.89,-1.15l-0.89,-2.19l-0.43,-1.91l-0.05,-0.11l-0.98,-1.35l-1.24,-1.62l-0.13,-0.63l1.07,-1.32l0.06,-0.14l0.13,-0.81l0.68,-0.36l0.16,-0.25l0.03,-0.54l1.4,-0.23l0.12,-0.05l0.87,-0.6l1.26,0.05l0.25,-0.11l0.34,-0.43l0.33,-0.07l1.81,0.08l0.13,-0.02l1.87,-0.77l1.64,0.97l0.19,0.04l2.28,-0.28l0.26,-0.29l0.02,-0.95l0.56,0.36ZM480.44,192.0l1.05,0.74l0.01,0.0l-1.26,-0.23l0.2,-0.51ZM481.76,192.79l1.86,-0.15l1.53,0.17l-0.02,0.19l0.34,0.3l-2.28,0.15l0.01,-0.13l-0.25,-0.31l-1.19,-0.22ZM485.65,193.28l0.65,-0.16l-0.05,0.12l-0.6,0.04Z\", \"name\": \"Greece\"}, \"GQ\": {\"path\": \"M444.81,282.04l-0.21,-0.17l0.74,-2.4l3.56,0.05l0.02,2.42l-3.34,-0.02l-0.76,0.13Z\", \"name\": \"Equatorial Guinea\"}, \"GY\": {\"path\": \"M271.34,264.25l1.43,0.81l1.44,1.53l0.06,1.19l0.28,0.28l0.84,0.05l2.13,1.92l-0.34,1.93l-1.37,0.59l-0.17,0.34l0.12,0.51l-0.43,1.21l0.03,0.26l1.11,1.82l0.26,0.14l0.56,0.0l0.32,1.29l1.25,1.78l-0.08,0.01l-1.34,-0.21l-0.24,0.06l-0.78,0.64l-1.06,0.41l-0.76,0.1l-0.22,0.15l-0.18,0.32l-0.95,-0.1l-1.38,-1.05l-0.19,-1.13l-0.6,-1.18l0.37,-1.96l0.65,-0.83l0.03,-0.32l-0.57,-1.17l-0.15,-0.14l-0.62,-0.27l0.25,-0.85l-0.08,-0.3l-0.58,-0.58l-0.24,-0.09l-1.15,0.1l-1.41,-1.58l0.48,-0.49l0.09,-0.22l-0.04,-0.92l1.31,-0.34l0.73,-0.52l0.04,-0.44l-0.75,-0.82l0.16,-0.66l1.74,-1.3Z\", \"name\": \"Guyana\"}, \"GE\": {\"path\": \"M525.41,174.19l0.26,-0.88l-0.0,-0.17l-0.63,-2.06l-0.1,-0.15l-1.45,-1.12l-0.11,-0.05l-1.31,-0.33l-0.66,-0.69l1.97,0.48l3.65,0.49l3.3,1.41l0.39,0.5l0.33,0.1l1.43,-0.45l2.14,0.58l0.7,1.14l0.13,0.12l1.06,0.47l-0.18,0.11l-0.08,0.43l1.08,1.41l-0.06,0.06l-1.16,-0.15l-1.82,-0.84l-0.31,0.04l-0.55,0.44l-3.29,0.44l-2.32,-1.41l-0.17,-0.04l-2.25,0.12Z\", \"name\": \"Georgia\"}, \"GB\": {\"path\": \"M412.82,118.6l-2.31,3.4l-0.0,0.33l0.31,0.13l2.52,-0.49l2.34,0.02l-0.56,2.51l-2.22,3.13l0.22,0.47l2.43,0.21l2.35,4.35l0.17,0.14l1.58,0.51l1.49,3.78l0.73,1.37l0.2,0.15l2.76,0.59l-0.25,1.75l-1.18,0.91l-0.08,0.39l0.87,1.49l-1.96,1.51l-3.31,-0.02l-4.15,0.88l-1.07,-0.59l-0.35,0.04l-1.55,1.44l-2.17,-0.35l-0.22,0.05l-1.61,1.15l-0.78,-0.38l3.31,-3.12l2.18,-0.7l0.21,-0.31l-0.26,-0.27l-3.78,-0.54l-0.48,-0.9l2.3,-0.92l0.13,-0.46l-1.29,-1.71l0.39,-1.83l3.46,0.29l0.32,-0.24l0.37,-1.99l-0.06,-0.24l-1.71,-2.17l-0.18,-0.11l-2.91,-0.58l-0.43,-0.68l0.82,-1.4l-0.03,-0.35l-0.82,-0.97l-0.46,0.01l-0.85,1.05l-0.11,-2.6l-0.05,-0.16l-1.19,-1.7l0.86,-3.53l1.81,-2.75l1.88,0.26l2.38,-0.24ZM406.39,132.84l-1.09,1.92l-1.65,-0.62l-1.26,0.02l0.41,-1.46l0.0,-0.16l-0.42,-1.51l1.62,-0.11l2.39,1.92Z\", \"name\": \"United Kingdom\"}, \"GA\": {\"path\": \"M448.76,294.47l-2.38,-2.34l-1.63,-2.04l-1.46,-2.48l0.06,-0.66l0.54,-0.81l0.61,-1.82l0.46,-1.69l0.63,-0.11l3.62,0.03l0.3,-0.3l-0.02,-2.75l0.88,-0.12l1.47,0.32l0.13,0.0l1.39,-0.3l-0.13,0.87l0.03,0.19l0.7,1.29l0.3,0.16l1.74,-0.19l0.36,0.29l-1.01,2.7l0.05,0.29l1.13,1.42l0.25,1.82l-0.3,1.56l-0.64,0.99l-1.93,-0.09l-1.26,-1.13l-0.5,0.17l-0.16,0.91l-1.48,0.27l-0.12,0.05l-0.86,0.63l-0.08,0.39l0.81,1.42l-1.48,1.08Z\", \"name\": \"Gabon\"}, \"GN\": {\"path\": \"M399.83,265.31l-0.69,-0.06l-0.3,0.16l-0.43,0.85l-0.39,-0.01l-0.3,-0.33l0.14,-0.87l-0.05,-0.22l-1.05,-1.54l-0.37,-0.11l-0.61,0.27l-0.84,0.12l0.02,-0.54l-0.04,-0.17l-0.35,-0.57l0.07,-0.63l-0.03,-0.17l-0.57,-1.11l-0.7,-0.9l-0.24,-0.12l-2.0,-0.0l-0.19,0.07l-0.51,0.42l-0.6,0.05l-0.21,0.11l-0.43,0.55l-0.3,0.7l-1.04,0.86l-0.91,-1.24l-1.0,-1.02l-0.69,-0.37l-0.52,-0.42l-0.3,-1.11l-0.37,-0.56l-0.1,-0.1l-0.4,-0.23l0.77,-0.85l0.62,0.04l0.18,-0.05l0.58,-0.38l0.46,-0.0l0.19,-0.07l0.39,-0.34l0.1,-0.3l-0.17,-0.67l0.15,-0.14l0.09,-0.2l0.03,-0.57l0.87,0.02l1.76,0.6l0.13,0.01l0.55,-0.06l0.22,-0.13l0.08,-0.12l1.18,0.17l0.17,-0.02l0.09,0.56l0.3,0.25l0.4,-0.0l0.14,-0.03l0.56,-0.29l0.23,0.05l0.63,0.59l0.15,0.07l1.07,0.2l0.24,-0.06l0.65,-0.52l0.77,-0.32l0.55,-0.32l0.3,0.04l0.44,0.45l0.34,0.74l0.84,0.87l-0.35,0.45l-0.06,0.15l-0.1,0.82l0.42,0.31l0.35,-0.16l0.05,0.04l-0.1,0.59l0.09,0.27l0.42,0.4l-0.06,0.02l-0.18,0.21l-0.2,0.86l0.03,0.21l0.56,1.02l0.52,1.71l-0.65,0.21l-0.15,0.12l-0.24,0.35l-0.03,0.28l0.16,0.41l-0.1,0.76l-0.12,0.0Z\", \"name\": \"Guinea\"}, \"GM\": {\"path\": \"M379.18,251.48l0.15,-0.55l2.51,-0.07l0.21,-0.09l0.48,-0.52l0.58,-0.03l0.91,0.58l0.16,0.05l0.78,0.01l0.14,-0.03l0.59,-0.31l0.16,0.24l-0.71,0.38l-0.94,-0.04l-1.02,-0.51l-0.3,0.01l-0.86,0.55l-0.37,0.02l-0.14,0.04l-0.53,0.31l-1.81,-0.04Z\", \"name\": \"Gambia\"}, \"GL\": {\"path\": \"M304.13,6.6l8.19,-3.63l8.72,0.28l0.19,-0.06l3.12,-2.28l8.75,-0.61l19.94,0.8l14.93,4.75l-3.92,2.01l-9.52,0.27l-13.48,0.6l-0.27,0.2l0.09,0.33l1.26,1.09l0.22,0.07l8.81,-0.67l7.49,2.07l0.19,-0.01l4.68,-1.78l1.76,1.84l-2.59,3.26l-0.01,0.36l0.34,0.11l6.35,-2.2l12.09,-2.32l7.31,1.14l1.17,2.13l-9.9,4.05l-1.43,1.32l-7.91,0.98l-0.26,0.31l0.29,0.29l5.25,0.25l-2.63,3.72l-2.02,3.61l-0.04,0.15l0.08,6.05l0.07,0.19l2.61,3.0l-3.4,0.2l-4.12,1.66l-0.04,0.54l4.5,2.67l0.53,3.9l-2.39,0.42l-0.19,0.48l2.91,3.83l-5.0,0.32l-0.27,0.22l0.12,0.33l2.69,1.84l-0.65,1.35l-3.36,0.71l-3.46,0.01l-0.21,0.51l3.05,3.15l0.02,1.53l-4.54,-1.79l-0.32,0.06l-1.29,1.26l0.11,0.5l3.33,1.15l3.17,2.74l0.85,3.29l-4.0,0.78l-1.83,-1.66l-3.1,-2.64l-0.36,-0.02l-0.13,0.33l0.8,2.92l-2.76,2.26l-0.09,0.33l0.28,0.2l6.59,0.19l2.47,0.18l-5.86,3.38l-6.76,3.43l-7.26,1.48l-2.73,0.02l-0.16,0.05l-2.67,1.72l-3.44,4.42l-5.28,2.86l-1.73,0.18l-3.33,1.01l-3.59,0.96l-0.15,0.1l-2.15,2.52l-0.07,0.19l-0.03,2.76l-1.21,2.49l-4.03,3.1l-0.1,0.33l0.98,2.94l-2.31,6.57l-3.21,0.21l-3.6,-3.0l-0.19,-0.07l-4.9,-0.02l-2.29,-1.97l-1.69,-3.78l-4.31,-4.86l-1.23,-2.52l-0.34,-3.58l-0.08,-0.17l-3.35,-3.67l0.85,-2.92l-0.09,-0.31l-1.5,-1.34l2.33,-4.7l3.67,-1.57l0.15,-0.13l1.02,-1.93l0.52,-3.47l-0.44,-0.31l-2.85,1.57l-1.33,0.64l-2.12,0.59l-2.81,-1.32l-0.15,-2.79l0.88,-2.17l2.09,-0.06l5.07,1.2l0.34,-0.17l-0.11,-0.37l-4.3,-2.9l-2.24,-1.58l-0.25,-0.05l-2.38,0.62l-1.7,-0.93l2.62,-4.1l-0.03,-0.36l-1.51,-1.75l-1.97,-3.3l-3.01,-5.21l-0.1,-0.11l-3.04,-1.85l0.03,-1.94l-0.18,-0.28l-6.82,-3.01l-5.35,-0.38l-6.69,0.21l-6.03,0.37l-2.81,-1.59l-3.84,-2.9l5.94,-1.5l5.01,-0.28l0.28,-0.29l-0.26,-0.31l-10.68,-1.38l-5.38,-2.1l0.27,-1.68l9.3,-2.6l9.18,-2.68l0.19,-0.16l0.97,-2.05l-0.18,-0.42l-6.29,-1.91l1.81,-1.9l8.58,-4.05l3.6,-0.63l0.23,-0.4l-0.92,-2.37l5.59,-1.5l7.66,-0.95l7.58,-0.05l2.65,1.84l0.31,0.02l6.52,-3.29l5.85,2.24l3.55,0.49l5.17,1.95l0.38,-0.16l-0.13,-0.39l-5.77,-3.16l0.29,-2.26Z\", \"name\": \"Greenland\"}, \"KW\": {\"path\": \"M540.87,207.81l0.41,0.94l-0.18,0.51l0.0,0.21l0.65,1.66l-1.15,0.05l-0.54,-1.12l-0.24,-0.17l-1.73,-0.2l1.44,-2.06l1.33,0.18Z\", \"name\": \"Kuwait\"}, \"GH\": {\"path\": \"M423.16,269.88l-3.58,1.34l-1.41,0.87l-2.13,0.69l-1.91,-0.61l0.09,-0.75l-0.03,-0.17l-1.04,-2.07l0.62,-2.7l1.04,-2.08l0.03,-0.19l-1.0,-5.46l0.05,-1.12l4.04,-0.11l1.08,0.18l0.18,-0.03l0.72,-0.36l0.75,0.13l-0.11,0.48l0.06,0.26l0.98,1.22l-0.0,1.77l0.24,1.99l0.05,0.13l0.55,0.81l-0.52,2.14l0.19,1.37l0.69,1.66l0.38,0.62Z\", \"name\": \"Ghana\"}, \"OM\": {\"path\": \"M568.16,231.0l-0.08,0.1l-0.84,1.61l-0.93,-0.11l-0.27,0.11l-0.58,0.73l-0.4,1.32l-0.01,0.14l0.29,1.61l-0.07,0.09l-1.0,-0.01l-0.16,0.04l-1.56,0.97l-0.14,0.2l-0.23,1.17l-0.41,0.4l-1.44,-0.02l-0.17,0.05l-0.98,0.65l-0.13,0.25l0.01,0.87l-0.97,0.57l-1.27,-0.22l-0.19,0.03l-1.63,0.84l-0.88,0.11l-2.55,-5.57l7.2,-2.49l0.19,-0.19l1.67,-5.23l-0.03,-0.25l-1.1,-1.78l0.05,-0.89l0.68,-1.03l0.05,-0.16l0.01,-0.89l0.96,-0.44l0.07,-0.5l-0.32,-0.26l0.16,-1.31l0.85,-0.01l1.03,1.67l0.09,0.09l1.4,0.96l0.11,0.05l1.82,0.34l1.37,0.45l1.75,2.32l0.13,0.1l0.7,0.26l-0.0,0.3l-1.25,2.19l-1.01,0.8ZM561.88,218.47l-0.01,0.02l-0.15,-0.29l0.3,-0.38l-0.14,0.65Z\", \"name\": \"Oman\"}, \"_3\": {\"path\": \"M543.2,261.06l-1.07,1.46l-1.65,1.99l-1.91,0.01l-8.08,-2.95l-0.89,-0.84l-0.9,-1.19l-0.81,-1.23l0.44,-0.73l0.76,-1.12l0.49,0.28l0.52,1.05l1.13,1.06l0.2,0.08l1.24,0.01l2.42,-0.65l2.77,-0.31l2.17,-0.78l1.31,-0.19l0.84,-0.43l1.03,-0.06l-0.01,4.54Z\", \"name\": \"Somaliland\"}, \"_2\": {\"path\": \"M384.23,230.37l0.07,-0.06l0.28,-0.89l0.99,-1.13l0.07,-0.13l0.8,-3.54l3.4,-2.8l0.09,-0.13l0.76,-2.17l0.07,5.5l-2.07,0.21l-0.24,0.17l-0.61,1.36l-0.02,0.16l0.43,3.46l-4.01,-0.01ZM391.82,218.2l0.07,-0.06l0.75,-1.93l1.86,-0.25l0.94,0.34l1.14,0.0l0.18,-0.06l0.73,-0.56l1.41,-0.08l-0.0,2.72l-7.08,-0.12Z\", \"name\": \"Western Sahara\"}, \"_1\": {\"path\": \"M472.71,172.84l-0.07,-0.43l-0.16,-0.22l-0.53,-0.27l-0.38,-0.58l0.3,-0.43l0.51,-0.19l0.18,-0.18l0.3,-0.87l0.12,-0.04l0.22,0.26l0.12,0.09l0.38,0.15l0.28,0.41l0.15,0.12l0.34,0.12l0.43,0.5l0.15,0.07l-0.12,0.3l-0.27,0.32l-0.03,0.18l-0.31,0.06l-1.48,0.47l-0.15,0.17Z\", \"name\": \"Kosovo\"}, \"_0\": {\"path\": \"M503.54,192.92l0.09,-0.17l0.41,0.01l-0.08,0.01l-0.42,0.15ZM504.23,192.76l1.02,0.02l0.4,-0.13l-0.09,0.29l0.03,0.08l-0.35,0.16l-0.24,-0.04l-0.06,-0.1l-0.18,-0.17l-0.19,-0.08l-0.33,-0.02Z\", \"name\": \"Northern Cyprus\"}, \"JO\": {\"path\": \"M510.26,200.93l0.28,-0.57l2.53,1.0l0.27,-0.02l4.57,-2.77l0.84,2.84l-0.28,0.25l-4.95,1.37l-0.14,0.49l2.24,2.48l-0.5,0.28l-0.13,0.14l-0.35,0.78l-1.76,0.35l-0.2,0.14l-0.57,0.94l-0.94,0.73l-2.45,-0.38l-0.03,-0.12l1.23,-4.32l-0.04,-1.1l0.34,-0.75l0.03,-0.12l0.0,-1.63Z\", \"name\": \"Jordan\"}, \"HR\": {\"path\": \"M455.49,162.73l1.53,0.09l0.24,-0.1l0.29,-0.34l0.64,0.38l0.14,0.04l0.98,0.06l0.32,-0.3l-0.01,-0.66l0.67,-0.25l0.19,-0.22l0.21,-1.11l1.72,-0.72l0.65,0.32l1.94,1.37l2.07,0.6l0.22,-0.02l0.67,-0.33l0.47,0.94l0.67,0.76l-0.63,0.77l-0.91,-0.55l-0.16,-0.04l-1.69,0.04l-2.2,-0.51l-1.17,0.07l-0.21,0.11l-0.36,0.42l-0.67,-0.53l-0.46,0.12l-0.52,1.29l0.05,0.31l1.21,1.42l0.58,0.99l1.15,1.14l0.95,0.68l0.92,1.23l0.1,0.09l1.75,0.91l-1.87,-0.89l-1.5,-1.11l-2.23,-0.88l-1.77,-1.9l0.12,-0.06l0.1,-0.47l-1.07,-1.22l-0.04,-0.94l-0.21,-0.27l-1.61,-0.49l-0.35,0.14l-0.53,0.93l-0.41,-0.57l0.04,-0.73Z\", \"name\": \"Croatia\"}, \"HT\": {\"path\": \"M237.82,234.68l1.35,0.1l1.95,0.37l0.18,1.15l-0.16,0.83l-0.51,0.37l-0.06,0.44l0.57,0.68l-0.02,0.22l-1.31,-0.35l-1.26,0.17l-1.49,-0.18l-0.15,0.02l-1.03,0.43l-1.02,-0.61l0.09,-0.36l2.04,0.32l1.9,0.21l0.19,-0.05l0.9,-0.58l0.05,-0.47l-1.05,-1.03l0.02,-0.86l-0.23,-0.3l-1.13,-0.29l0.18,-0.23Z\", \"name\": \"Haiti\"}, \"HU\": {\"path\": \"M461.96,157.92l0.68,-1.66l-0.03,-0.29l-0.15,-0.22l0.84,-0.0l0.3,-0.26l0.12,-0.84l0.88,0.57l0.98,0.38l0.16,0.01l2.1,-0.39l0.23,-0.21l0.14,-0.45l0.88,-0.1l1.06,-0.43l0.13,0.1l0.28,0.04l1.18,-0.4l0.14,-0.1l0.52,-0.67l0.63,-0.15l2.6,0.95l0.26,-0.03l0.38,-0.23l1.12,0.7l0.1,0.49l-1.31,0.57l-0.14,0.13l-1.18,2.14l-1.44,2.04l-1.85,0.55l-1.51,-0.13l-0.14,0.02l-1.92,0.82l-0.85,0.42l-1.91,-0.55l-1.83,-1.31l-0.74,-0.37l-0.44,-0.97l-0.26,-0.18Z\", \"name\": \"Hungary\"}, \"HN\": {\"path\": \"M202.48,251.87l-0.33,-0.62l-0.18,-0.14l-0.5,-0.15l0.13,-0.76l-0.11,-0.28l-0.34,-0.28l-0.6,-0.23l-0.18,-0.01l-0.81,0.22l-0.16,-0.24l-0.72,-0.39l-0.51,-0.48l-0.12,-0.07l-0.31,-0.09l0.24,-0.3l0.04,-0.3l-0.16,-0.4l0.1,-0.28l1.14,-0.69l1.0,-0.86l0.09,0.04l0.3,-0.05l0.47,-0.39l0.49,-0.03l0.14,0.13l0.29,0.06l0.31,-0.1l1.16,0.22l1.24,-0.08l0.81,-0.28l0.29,-0.25l0.63,0.1l0.69,0.18l0.65,-0.06l0.49,-0.2l1.04,0.32l0.38,0.06l0.7,0.44l0.71,0.56l0.92,0.41l0.1,0.11l-0.11,-0.01l-0.23,0.09l-0.3,0.3l-0.76,0.29l-0.58,0.0l-0.15,0.04l-0.45,0.26l-0.31,-0.07l-0.37,-0.34l-0.28,-0.07l-0.26,0.07l-0.18,0.15l-0.23,0.43l-0.04,-0.0l-0.33,0.28l-0.03,0.4l-0.76,0.61l-0.45,0.3l-0.15,0.16l-0.51,-0.36l-0.41,0.06l-0.45,0.56l-0.41,-0.01l-0.59,0.06l-0.27,0.31l0.04,0.96l-0.07,0.0l-0.25,0.16l-0.24,0.45l-0.42,0.06Z\", \"name\": \"Honduras\"}, \"PR\": {\"path\": \"M254.95,238.31l1.15,0.21l0.2,0.23l-0.36,0.36l-1.76,-0.01l-1.2,0.07l-0.09,-0.69l0.17,-0.18l1.89,0.01Z\", \"name\": \"Puerto Rico\"}, \"PS\": {\"path\": \"M509.66,201.06l-0.0,1.44l-0.29,0.63l-0.59,0.19l0.02,-0.11l0.52,-0.31l-0.02,-0.53l-0.41,-0.2l0.36,-1.28l0.41,0.17Z\", \"name\": \"West Bank\"}, \"PT\": {\"path\": \"M398.65,173.6l0.75,-0.63l0.7,-0.3l0.51,1.2l0.28,0.18l1.48,-0.0l0.2,-0.08l0.33,-0.3l1.16,0.08l0.52,1.11l-0.95,0.66l-0.13,0.24l-0.03,2.2l-0.33,0.35l-0.08,0.18l-0.08,1.17l-0.86,0.19l-0.2,0.44l0.93,1.64l-0.64,1.79l0.07,0.31l0.72,0.72l-0.24,0.56l-0.9,1.05l-0.07,0.26l0.17,0.77l-0.73,0.54l-1.18,-0.36l-0.16,-0.0l-0.85,0.21l0.31,-1.81l-0.23,-1.87l-0.23,-0.25l-0.99,-0.24l-0.49,-0.91l0.18,-1.72l0.93,-0.99l0.08,-0.16l0.17,-1.17l0.52,-1.76l-0.04,-1.36l-0.51,-1.14l-0.09,-0.8Z\", \"name\": \"Portugal\"}, \"PY\": {\"path\": \"M264.33,341.43l0.93,-2.96l0.07,-1.42l1.1,-2.1l4.19,-0.73l2.22,0.04l2.12,1.21l0.07,0.76l0.7,1.38l-0.16,3.48l0.24,0.31l2.64,0.5l0.19,-0.03l0.9,-0.45l1.47,0.62l0.38,0.64l0.23,2.35l0.3,1.07l0.25,0.21l0.93,0.12l0.16,-0.02l0.8,-0.37l0.61,0.33l-0.0,1.25l-0.33,1.53l-0.5,1.57l-0.39,2.26l-2.14,1.94l-1.85,0.4l-2.74,-0.4l-2.13,-0.62l2.26,-3.75l0.03,-0.24l-0.36,-1.18l-0.17,-0.19l-2.55,-1.03l-3.04,-1.95l-2.07,-0.43l-4.4,-4.12Z\", \"name\": \"Paraguay\"}, \"PA\": {\"path\": \"M213.65,263.79l0.18,-0.43l0.02,-0.18l-0.06,-0.28l0.23,-0.18l-0.01,-0.48l-0.4,-0.29l-0.01,-0.62l0.57,-0.13l0.68,0.69l-0.04,0.39l0.26,0.33l1.0,0.11l0.27,-0.1l0.49,0.44l0.24,0.07l1.34,-0.22l1.04,-0.62l1.49,-0.5l0.86,-0.73l0.99,0.11l0.18,0.28l1.35,0.08l1.02,0.4l0.78,0.72l0.71,0.53l-0.1,0.12l-0.05,0.3l0.53,1.34l-0.28,0.44l-0.6,-0.13l-0.36,0.22l-0.2,0.76l-0.41,-0.36l-0.44,-1.12l0.49,-0.53l-0.14,-0.49l-0.51,-0.14l-0.41,-0.72l-0.11,-0.11l-1.25,-0.7l-0.19,-0.04l-1.1,0.16l-0.22,0.15l-0.47,0.81l-0.9,0.56l-0.49,0.08l-0.22,0.17l-0.25,0.52l0.05,0.32l0.93,1.07l-0.41,0.21l-0.29,0.3l-0.81,0.09l-0.36,-1.26l-0.53,-0.1l-0.21,0.28l-0.5,-0.09l-0.44,-0.88l-0.22,-0.16l-0.99,-0.16l-0.61,-0.28l-0.13,-0.03l-1.0,0.0Z\", \"name\": \"Panama\"}, \"PG\": {\"path\": \"M808.4,298.6l0.62,0.46l1.19,1.56l1.04,0.77l-0.18,0.37l-0.42,0.15l-0.92,-0.82l-1.05,-1.53l-0.27,-0.96ZM804.09,296.06l-0.3,0.26l-0.36,-1.11l-0.66,-1.06l-2.55,-1.89l-1.42,-0.59l0.17,-0.15l1.16,0.6l0.85,0.55l1.01,0.58l0.97,1.02l0.9,0.76l0.24,1.03ZM796.71,297.99l0.15,0.82l0.34,0.24l1.43,-0.19l0.19,-0.11l0.68,-0.82l1.36,-0.87l0.13,-0.31l-0.21,-1.13l1.04,-0.03l0.3,0.25l-0.04,1.17l-0.74,1.34l-1.17,0.18l-0.22,0.15l-0.35,0.62l-2.51,1.13l-1.21,-0.0l-1.99,-0.71l-1.19,-0.58l0.07,-0.28l1.98,0.32l1.46,-0.2l0.24,-0.21l0.25,-0.79ZM789.24,303.52l0.11,0.15l2.19,1.62l1.6,2.62l0.27,0.14l1.09,-0.06l-0.07,0.77l0.23,0.32l1.23,0.27l-0.14,0.09l0.05,0.53l2.39,0.95l-0.11,0.28l-1.33,0.14l-0.51,-0.55l-0.18,-0.09l-4.59,-0.65l-1.87,-1.55l-1.38,-1.35l-1.28,-2.17l-0.16,-0.13l-3.27,-1.1l-0.19,0.0l-2.12,0.72l-1.58,0.85l-0.15,0.31l0.28,1.63l-1.65,0.73l-1.37,-0.4l-2.3,-0.09l-0.08,-15.65l3.95,1.57l4.58,1.42l1.67,1.25l1.32,1.19l0.36,1.39l0.19,0.21l4.06,1.51l0.39,0.85l-1.9,0.22l-0.25,0.39l0.55,1.68Z\", \"name\": \"Papua New Guinea\"}, \"PE\": {\"path\": \"M246.44,329.21l-0.63,1.25l-1.05,0.54l-2.25,-1.33l-0.19,-0.93l-0.16,-0.21l-4.95,-2.58l-4.46,-2.79l-1.87,-1.52l-0.94,-1.91l0.33,-0.6l-0.01,-0.31l-2.11,-3.33l-2.46,-4.66l-2.36,-5.02l-1.04,-1.18l-0.77,-1.81l-0.08,-0.11l-1.95,-1.64l-1.54,-0.88l0.61,-0.85l0.02,-0.31l-1.15,-2.27l0.69,-1.56l1.59,-1.26l0.12,0.42l-0.56,0.47l-0.11,0.25l0.07,0.92l0.36,0.27l0.97,-0.19l0.85,0.23l0.99,1.19l0.41,0.05l1.42,-1.03l0.11,-0.16l0.46,-1.64l1.45,-2.06l2.92,-0.96l0.11,-0.07l2.73,-2.62l0.84,-1.72l0.02,-0.18l-0.3,-1.65l0.28,-0.1l1.49,1.06l0.77,1.14l0.1,0.09l1.08,0.6l1.43,2.55l0.21,0.15l1.86,0.31l0.18,-0.03l1.25,-0.6l0.77,0.37l0.17,0.03l1.4,-0.2l1.57,0.96l-1.45,2.29l0.23,0.46l0.63,0.05l0.66,0.7l-1.51,-0.08l-0.24,0.1l-0.27,0.31l-1.96,0.46l-2.95,1.74l-0.14,0.21l-0.17,1.1l-0.6,0.82l-0.05,0.23l0.21,1.13l-1.31,0.63l-0.17,0.27l0.0,0.91l-0.53,0.37l-0.1,0.37l1.04,2.27l1.31,1.46l-0.44,0.9l0.24,0.43l1.52,0.13l0.87,1.23l0.24,0.13l2.21,0.07l0.18,-0.06l1.55,-1.13l-0.14,3.22l0.23,0.3l1.14,0.29l0.16,-0.0l1.18,-0.36l1.97,3.71l-0.45,0.71l-0.04,0.14l-0.12,1.8l-0.05,2.07l-0.92,1.2l-0.03,0.31l0.38,0.8l-0.48,0.72l-0.02,0.3l1.01,2.02l-1.5,2.64Z\", \"name\": \"Peru\"}, \"PK\": {\"path\": \"M609.08,187.76l1.66,1.21l0.71,2.11l0.2,0.19l3.62,1.01l-1.98,1.95l-2.65,0.4l-3.75,-0.68l-0.26,0.08l-1.23,1.22l-0.07,0.31l0.89,2.46l0.88,1.92l0.1,0.12l1.67,1.14l-1.8,1.35l-0.12,0.25l0.04,1.85l-2.35,2.67l-1.59,2.79l-2.5,2.72l-2.76,-0.2l-0.24,0.09l-2.76,2.83l0.04,0.45l1.54,1.13l0.27,1.94l0.09,0.17l1.34,1.29l0.4,1.83l-5.14,-0.01l-0.22,0.09l-1.53,1.63l-1.52,-0.56l-0.76,-1.88l-1.93,-2.03l-0.25,-0.09l-4.6,0.5l-4.05,0.05l-3.1,0.33l0.77,-2.53l3.48,-1.33l0.19,-0.33l-0.21,-1.24l-0.19,-0.23l-1.01,-0.37l-0.06,-2.18l-0.17,-0.26l-2.32,-1.16l-0.96,-1.57l-0.56,-0.65l3.16,1.05l0.14,0.01l2.45,-0.4l1.44,0.33l0.3,-0.1l0.4,-0.47l1.58,0.22l0.14,-0.01l3.25,-1.14l0.2,-0.27l0.08,-2.23l1.23,-1.38l1.73,0.0l0.28,-0.2l0.22,-0.61l1.68,-0.32l0.86,0.24l0.27,-0.05l0.98,-0.78l0.11,-0.26l-0.13,-1.57l0.96,-1.52l1.51,-0.67l0.14,-0.41l-0.74,-1.4l1.86,0.07l0.26,-0.13l0.69,-1.01l0.05,-0.2l-0.09,-0.94l1.14,-1.09l0.09,-0.28l-0.29,-1.41l-0.51,-1.07l1.23,-1.05l2.6,-0.58l2.86,-0.33l1.33,-0.54l1.3,-0.29Z\", \"name\": \"Pakistan\"}, \"PH\": {\"path\": \"M737.11,263.82l0.25,1.66l0.14,1.34l-0.54,1.46l-0.64,-1.79l-0.5,-0.1l-1.17,1.28l-0.05,0.32l0.74,1.71l-0.49,0.81l-2.6,-1.28l-0.61,-1.57l0.68,-1.07l-0.07,-0.4l-1.59,-1.19l-0.42,0.06l-0.69,0.91l-1.01,-0.08l-0.21,0.06l-1.58,1.2l-0.17,-0.3l0.87,-1.88l1.48,-0.66l1.18,-0.81l0.71,0.92l0.34,0.1l1.9,-0.69l0.18,-0.18l0.34,-0.94l1.57,-0.06l0.29,-0.32l-0.1,-1.38l1.41,0.83l0.36,2.06ZM734.94,254.42l0.56,2.24l-1.41,-0.49l-0.4,0.3l0.07,0.94l0.51,1.3l-0.54,0.26l-0.08,-1.34l-0.25,-0.28l-0.56,-0.1l-0.23,-0.91l1.03,0.14l0.34,-0.31l-0.03,-0.96l-0.06,-0.18l-1.14,-1.44l1.62,0.04l0.57,0.78ZM724.68,238.33l1.48,0.71l0.33,-0.04l0.44,-0.38l0.05,0.13l-0.37,0.97l0.01,0.23l0.81,1.75l-0.59,1.92l-1.37,0.79l-0.14,0.2l-0.39,2.07l0.01,0.14l0.56,2.04l0.23,0.21l1.33,0.28l0.14,-0.0l1.0,-0.27l2.82,1.28l-0.2,1.16l0.12,0.29l0.66,0.5l-0.13,0.56l-1.54,-0.99l-0.89,-1.29l-0.49,0.0l-0.44,0.65l-1.34,-1.28l-0.26,-0.08l-2.18,0.36l-0.96,-0.44l0.09,-0.72l0.69,-0.57l-0.01,-0.47l-0.75,-0.59l-0.47,0.14l-0.15,0.43l-0.86,-1.02l-0.34,-1.02l-0.07,-1.74l0.49,0.41l0.49,-0.21l0.26,-3.99l0.73,-2.1l1.23,0.0ZM731.12,258.92l-0.82,0.75l-0.83,1.64l-0.52,0.5l-1.17,-1.33l0.36,-0.47l0.62,-0.7l0.07,-0.15l0.24,-1.35l0.73,-0.08l-0.31,1.29l0.16,0.34l0.37,-0.09l1.21,-1.6l-0.12,1.24ZM726.66,255.58l0.85,0.45l0.14,0.03l1.28,-0.0l-0.03,0.62l-1.04,0.96l-1.15,0.55l-0.05,-0.71l0.17,-1.26l-0.01,-0.13l-0.16,-0.51ZM724.92,252.06l-0.45,1.5l-0.7,-0.83l-0.95,-1.43l1.44,0.06l0.67,0.7ZM717.48,261.28l-1.87,1.35l0.21,-0.3l1.81,-1.57l1.5,-1.75l0.97,-1.84l0.23,1.08l-1.56,1.33l-1.29,1.7Z\", \"name\": \"Philippines\"}, \"PL\": {\"path\": \"M458.8,144.25l-0.96,-1.98l0.18,-1.06l-0.01,-0.15l-0.62,-1.8l-0.82,-1.11l0.56,-0.73l0.05,-0.28l-0.51,-1.51l1.48,-0.87l3.88,-1.58l3.06,-1.14l2.23,0.52l0.15,0.66l0.29,0.23l2.4,0.04l3.11,0.39l4.56,-0.05l1.12,0.32l0.51,0.89l0.1,1.45l0.03,0.12l0.66,1.23l-0.01,1.08l-1.33,0.61l-0.14,0.41l0.74,1.5l0.07,1.53l1.22,2.79l-0.19,0.66l-1.09,0.33l-0.14,0.09l-2.27,2.72l-0.04,0.31l0.35,0.8l-2.22,-1.16l-0.21,-0.02l-1.72,0.44l-1.1,-0.31l-0.21,0.02l-1.3,0.61l-1.11,-1.02l-0.32,-0.05l-0.81,0.35l-1.15,-1.61l-0.21,-0.12l-1.65,-0.17l-0.19,-0.82l-0.23,-0.23l-1.72,-0.37l-0.34,0.17l-0.25,0.56l-0.88,-0.44l0.12,-0.69l-0.25,-0.35l-1.78,-0.27l-1.08,-0.97Z\", \"name\": \"Poland\"}, \"ZM\": {\"path\": \"M502.81,308.32l1.09,1.04l0.58,1.94l-0.39,0.66l-0.5,2.05l-0.0,0.14l0.45,1.95l-0.69,0.77l-0.06,0.11l-0.76,2.37l0.15,0.36l0.62,0.31l-6.85,1.9l-0.22,0.33l0.2,1.54l-1.62,0.3l-0.12,0.05l-1.43,1.02l-0.11,0.15l-0.25,0.73l-0.73,0.17l-0.14,0.08l-2.18,2.12l-1.33,1.6l-0.65,0.05l-0.83,-0.29l-2.75,-0.28l-0.24,-0.1l-0.15,-0.27l-0.99,-0.58l-0.12,-0.04l-1.73,-0.14l-1.88,0.54l-1.5,-1.48l-1.61,-2.01l0.11,-7.73l4.92,0.03l0.29,-0.37l-0.19,-0.79l0.34,-0.86l0.0,-0.21l-0.41,-1.11l0.26,-1.14l-0.01,-0.16l-0.12,-0.36l0.18,0.01l0.1,0.56l0.31,0.25l1.14,-0.06l1.44,0.21l0.76,1.05l0.19,0.12l2.01,0.35l0.19,-0.03l1.24,-0.65l0.44,1.03l0.22,0.18l1.81,0.34l0.85,0.99l1.02,1.39l0.24,0.12l1.92,0.02l0.3,-0.32l-0.21,-2.74l-0.47,-0.23l-0.53,0.36l-1.58,-0.89l-0.51,-0.34l0.29,-2.36l0.44,-2.99l-0.03,-0.18l-0.5,-0.99l0.61,-1.38l0.53,-0.24l3.26,-0.41l0.89,0.23l1.01,0.62l1.04,0.44l1.6,0.43l1.35,0.72Z\", \"name\": \"Zambia\"}, \"EE\": {\"path\": \"M482.19,120.88l0.23,-1.68l-0.43,-0.31l-0.75,0.37l-1.34,-1.1l-0.18,-1.75l2.92,-0.95l3.07,-0.53l2.66,0.6l2.48,-0.1l0.18,0.31l-1.65,1.96l-0.06,0.26l0.71,3.25l-0.88,0.94l-1.85,-0.01l-2.08,-1.3l-1.14,-0.47l-0.2,-0.01l-1.69,0.51Z\", \"name\": \"Estonia\"}, \"EG\": {\"path\": \"M508.07,208.8l-0.66,1.06l-0.53,2.03l-0.64,1.32l-0.32,0.26l-1.74,-1.85l-1.77,-3.86l-0.48,-0.09l-0.26,0.25l-0.07,0.32l1.04,2.88l1.55,2.76l1.89,4.18l0.94,1.48l0.83,1.54l2.08,2.73l-0.3,0.28l-0.1,0.23l0.08,1.72l0.11,0.22l2.91,2.37l-28.78,0.0l0.0,-19.06l-0.73,-2.2l0.61,-1.59l0.0,-0.2l-0.34,-1.04l0.73,-1.08l3.13,-0.04l2.36,0.72l2.48,0.81l1.15,0.43l0.23,-0.01l1.93,-0.87l1.02,-0.78l2.08,-0.21l1.59,0.31l0.62,1.24l0.52,0.03l0.46,-0.71l1.86,0.59l1.95,0.16l0.17,-0.04l0.92,-0.52l1.48,4.24Z\", \"name\": \"Egypt\"}, \"ZA\": {\"path\": \"M467.06,373.27l-0.13,-0.29l0.01,-1.58l-0.02,-0.12l-0.71,-1.64l0.59,-0.37l0.14,-0.26l-0.07,-2.13l-0.05,-0.15l-1.63,-2.58l-1.25,-2.31l-1.71,-3.37l0.88,-0.98l0.7,0.52l0.39,1.08l0.23,0.19l1.1,0.19l1.55,0.51l0.14,0.01l1.35,-0.2l0.11,-0.04l2.24,-1.39l0.14,-0.25l0.0,-9.4l0.16,0.09l1.39,2.38l-0.22,1.53l0.04,0.19l0.56,0.94l0.3,0.14l1.79,-0.27l0.16,-0.08l1.23,-1.18l1.17,-0.79l0.1,-0.12l0.57,-1.19l1.02,-0.52l0.9,0.28l1.16,0.73l0.14,0.05l2.04,0.13l0.13,-0.02l1.6,-0.62l0.18,-0.19l0.63,-1.93l1.18,-0.19l0.19,-0.12l0.78,-1.05l0.81,-1.71l2.18,-1.91l3.44,-1.88l0.89,0.02l1.17,0.43l0.21,-0.0l0.76,-0.29l1.07,0.21l1.15,3.55l0.63,1.82l-0.44,2.9l0.1,0.52l-0.74,-0.29l-0.18,-0.01l-0.72,0.19l-0.21,0.2l-0.22,0.74l-0.66,0.97l-0.05,0.18l0.02,0.93l0.09,0.21l1.49,1.46l0.27,0.08l1.47,-0.29l0.22,-0.18l0.43,-1.01l1.29,0.02l-0.51,1.63l-0.29,2.2l-0.59,1.12l-2.2,1.78l-1.06,1.39l-0.72,1.44l-1.39,1.93l-2.81,2.84l-1.75,1.65l-1.85,1.24l-2.55,1.06l-1.23,0.14l-0.24,0.18l-0.22,0.54l-1.27,-0.35l-0.2,0.01l-1.15,0.5l-2.62,-0.52l-0.12,0.0l-1.46,0.33l-0.98,-0.14l-0.16,0.02l-2.55,1.1l-2.11,0.44l-1.59,1.07l-0.93,0.06l-0.97,-0.92l-0.19,-0.08l-0.72,-0.04l-1.0,-1.16l-0.25,0.05ZM493.72,359.24l-1.12,-0.86l-0.31,-0.03l-1.23,0.59l-1.36,1.07l-1.39,1.78l0.01,0.38l1.88,2.11l0.31,0.09l0.9,-0.27l0.18,-0.15l0.4,-0.77l1.28,-0.39l0.18,-0.16l0.42,-0.88l0.76,-1.32l-0.05,-0.37l-0.87,-0.82Z\", \"name\": \"South Africa\"}, \"EC\": {\"path\": \"M220.2,293.48l1.25,-1.76l0.02,-0.31l-0.54,-1.09l-0.5,-0.06l-0.78,0.94l-1.03,-0.75l0.33,-0.46l0.05,-0.23l-0.38,-2.04l0.66,-0.28l0.17,-0.19l0.45,-1.52l0.93,-1.58l0.04,-0.2l-0.13,-0.78l1.19,-0.47l1.57,-0.91l2.35,1.34l0.17,0.04l0.28,-0.02l0.52,0.91l0.21,0.15l2.12,0.35l0.2,-0.03l0.55,-0.31l1.08,0.73l0.97,0.54l0.31,1.67l-0.71,1.49l-2.64,2.54l-2.95,0.97l-0.15,0.11l-1.53,2.18l-0.49,1.68l-1.1,0.8l-0.87,-1.05l-0.15,-0.1l-1.01,-0.27l-0.13,-0.0l-0.7,0.14l-0.03,-0.43l0.6,-0.5l0.1,-0.31l-0.26,-0.91Z\", \"name\": \"Ecuador\"}, \"AL\": {\"path\": \"M470.27,171.7l0.38,0.19l0.45,-0.18l0.4,0.61l0.11,0.1l0.46,0.24l0.13,0.87l-0.3,0.95l-0.0,0.17l0.36,1.28l0.12,0.17l0.9,0.63l-0.03,0.44l-0.67,0.35l-0.16,0.22l-0.14,0.88l-0.96,1.18l-0.06,-0.03l-0.04,-0.48l-0.12,-0.22l-1.28,-0.92l-0.19,-1.25l0.2,-1.96l0.33,-0.89l-0.06,-0.3l-0.36,-0.41l-0.13,-0.75l0.66,-0.9Z\", \"name\": \"Albania\"}, \"AO\": {\"path\": \"M461.62,299.93l0.55,1.67l0.73,1.54l1.56,2.18l0.28,0.12l1.66,-0.2l0.81,-0.34l1.28,0.33l0.33,-0.14l0.39,-0.67l0.56,-1.3l1.37,-0.09l0.27,-0.21l0.07,-0.23l0.67,-0.01l-0.13,0.53l0.29,0.37l2.74,-0.02l0.04,1.29l0.03,0.13l0.46,0.87l-0.35,1.52l0.18,1.55l0.07,0.16l0.75,0.85l-0.13,2.89l0.41,0.29l0.56,-0.21l1.11,0.05l1.5,-0.37l0.9,0.12l0.18,0.53l-0.27,1.15l0.01,0.17l0.4,1.08l-0.33,0.85l-0.01,0.18l0.12,0.51l-4.83,-0.03l-0.3,0.3l-0.12,8.13l0.07,0.19l1.69,2.1l1.27,1.25l-4.03,0.92l-5.93,-0.36l-1.66,-1.19l-0.18,-0.06l-10.15,0.11l-0.34,0.13l-1.35,-1.05l-0.17,-0.06l-1.62,-0.08l-1.6,0.45l-0.88,0.36l-0.17,-1.2l0.34,-2.19l0.85,-2.32l0.14,-1.13l0.79,-2.24l0.57,-1.0l1.42,-1.64l0.82,-1.15l0.05,-0.13l0.26,-1.88l-0.13,-1.51l-0.07,-0.16l-0.72,-0.87l-1.23,-2.91l0.09,-0.37l0.73,-0.95l0.05,-0.27l-1.27,-4.12l-1.19,-1.54l0.1,-0.2l0.86,-0.28l0.78,0.03l0.83,-0.29l7.12,0.03ZM451.81,298.94l-0.17,0.07l-0.5,-1.42l0.85,-0.92l0.53,-0.29l0.48,0.44l-0.56,0.32l-0.1,0.1l-0.41,0.65l-0.05,0.14l-0.07,0.91Z\", \"name\": \"Angola\"}, \"KZ\": {\"path\": \"M598.42,172.08l-1.37,0.54l-3.3,2.09l-0.11,0.12l-1.01,1.97l-0.56,0.01l-0.6,-1.24l-0.26,-0.17l-2.95,-0.09l-0.46,-2.22l-0.29,-0.24l-0.91,-0.02l0.17,-2.72l-0.12,-0.26l-3.0,-2.22l-0.2,-0.06l-4.29,0.24l-2.8,0.42l-2.36,-2.7l-6.4,-3.65l-0.23,-0.03l-6.45,1.83l-0.22,0.29l0.1,10.94l-0.84,0.1l-1.65,-2.21l-0.11,-0.09l-1.69,-0.84l-0.2,-0.02l-2.84,0.63l-0.14,0.07l-0.71,0.64l-0.02,-0.11l0.57,-1.17l0.0,-0.26l-0.48,-1.05l-0.17,-0.16l-2.78,-0.99l-1.08,-2.62l-0.13,-0.15l-1.24,-0.7l-0.04,-0.48l2.07,0.25l0.34,-0.29l0.09,-2.03l1.84,-0.44l2.12,0.45l0.36,-0.25l0.45,-3.04l-0.45,-2.06l-0.31,-0.23l-2.44,0.15l-2.07,-0.75l-0.23,0.01l-2.88,1.38l-2.21,0.62l-0.96,-0.38l0.22,-1.39l-0.06,-0.23l-1.6,-2.12l-0.25,-0.12l-1.72,0.08l-1.87,-1.91l1.33,-2.24l-0.06,-0.38l-0.55,-0.5l1.72,-3.08l2.3,1.7l0.48,-0.2l0.29,-2.26l4.99,-3.48l3.76,-0.08l5.46,2.27l2.96,1.33l0.26,-0.01l2.59,-1.36l3.82,-0.06l3.13,1.67l0.38,-0.09l0.63,-0.85l3.36,0.14l0.29,-0.19l0.63,-1.57l-0.13,-0.37l-3.64,-2.05l2.0,-1.36l0.1,-0.38l-0.32,-0.62l2.09,-0.76l0.13,-0.47l-1.65,-2.13l0.89,-0.91l9.27,-1.18l0.13,-0.05l1.17,-0.82l6.2,-1.27l2.26,-1.43l4.19,0.7l0.74,3.39l0.38,0.22l2.52,-0.81l2.9,1.06l-0.18,1.63l0.32,0.33l2.52,-0.23l5.0,-2.58l0.03,0.39l3.16,2.62l5.57,8.48l0.49,0.02l1.18,-1.53l3.22,1.78l0.21,0.03l3.5,-0.83l1.21,0.52l1.16,1.82l0.15,0.12l1.67,0.61l1.01,1.32l0.28,0.11l3.04,-0.41l1.1,1.64l-1.68,1.89l-1.97,0.28l-0.26,0.29l-0.12,3.09l-1.2,1.23l-4.81,-1.01l-0.35,0.2l-1.77,5.51l-1.14,0.62l-4.92,1.23l-0.2,0.41l2.14,5.06l-1.45,0.67l-0.17,0.31l0.15,1.28l-1.05,-0.3l-1.21,-1.04l-0.17,-0.07l-3.73,-0.32l-4.15,-0.08l-0.92,0.31l-3.46,-1.24l-0.22,0.01l-1.42,0.63l-0.17,0.21l-0.32,1.49l-3.82,-0.97l-0.15,0.0l-1.65,0.43l-0.2,0.17l-0.51,1.21Z\", \"name\": \"Kazakhstan\"}, \"ET\": {\"path\": \"M516.0,247.63l1.21,0.92l0.3,0.04l1.3,-0.53l0.46,0.41l0.19,0.08l1.65,0.03l2.05,0.96l0.67,0.88l1.07,0.79l1.0,1.45l0.7,0.68l-0.72,0.92l-0.85,1.19l-0.04,0.25l0.19,0.67l0.04,0.74l0.29,0.28l1.4,0.04l0.55,-0.15l0.23,0.19l-0.41,0.67l0.01,0.32l0.92,1.39l0.93,1.23l0.99,0.94l0.1,0.06l8.19,2.99l1.51,0.01l-6.51,6.95l-3.14,0.11l-0.18,0.06l-2.15,1.71l-1.51,0.04l-0.22,0.1l-0.6,0.69l-1.46,-0.0l-0.93,-0.78l-0.32,-0.04l-2.29,1.05l-0.12,0.1l-0.64,0.9l-1.44,-0.17l-0.51,-0.26l-0.17,-0.03l-0.56,0.07l-0.68,-0.02l-3.1,-2.08l-0.17,-0.05l-1.62,0.0l-0.68,-0.65l0.0,-1.28l-0.21,-0.29l-1.19,-0.38l-1.42,-2.63l-0.13,-0.12l-1.05,-0.53l-0.46,-1.0l-1.27,-1.23l-0.17,-0.08l-1.08,-0.13l0.53,-0.9l1.17,-0.05l0.26,-0.17l0.37,-0.77l0.03,-0.14l-0.03,-2.23l0.7,-2.49l1.08,-0.65l0.14,-0.19l0.24,-1.0l1.03,-1.85l1.47,-1.22l0.09,-0.12l1.02,-2.51l0.36,-1.96l2.62,0.48l0.33,-0.18l0.63,-1.55Z\", \"name\": \"Ethiopia\"}, \"ZW\": {\"path\": \"M498.95,341.2l-1.16,-0.23l-0.16,0.01l-0.74,0.28l-1.11,-0.41l-1.02,-0.04l-1.52,-1.13l-0.12,-0.05l-1.79,-0.37l-0.65,-1.46l-0.01,-0.86l-0.22,-0.29l-0.99,-0.26l-2.74,-2.77l-0.77,-1.46l-0.52,-0.5l-0.72,-1.54l2.24,0.23l0.78,0.28l0.12,0.02l0.85,-0.06l0.21,-0.11l1.38,-1.66l2.11,-2.05l0.81,-0.18l0.22,-0.2l0.27,-0.8l1.29,-0.93l1.53,-0.28l0.11,0.66l0.3,0.25l2.02,-0.05l1.04,0.48l0.5,0.59l0.18,0.1l1.13,0.18l1.11,0.7l0.01,3.06l-0.49,1.82l-0.11,1.94l0.03,0.16l0.35,0.68l-0.24,1.3l-0.27,0.17l-0.12,0.15l-0.64,1.83l-2.49,2.8Z\", \"name\": \"Zimbabwe\"}, \"ES\": {\"path\": \"M398.67,172.8l0.09,-1.45l-0.06,-0.2l-0.82,-1.05l3.16,-1.96l3.01,0.54l3.33,-0.02l2.64,0.52l2.14,-0.15l3.9,0.1l0.91,1.08l0.14,0.09l4.61,1.38l0.26,-0.04l0.77,-0.55l2.66,1.29l0.17,0.03l2.59,-0.35l0.1,1.28l-2.2,1.85l-3.13,0.62l-0.23,0.23l-0.21,0.92l-1.54,1.68l-0.97,2.4l0.02,0.26l0.85,1.46l-1.27,1.14l-0.09,0.14l-0.5,1.73l-1.73,0.53l-0.15,0.1l-1.68,2.1l-3.03,0.04l-2.38,-0.05l-0.17,0.05l-1.57,1.01l-0.9,1.01l-0.96,-0.19l-0.82,-0.86l-0.69,-1.6l-0.22,-0.18l-2.14,-0.41l-0.13,-0.62l0.83,-0.97l0.39,-0.86l-0.06,-0.33l-0.73,-0.73l0.63,-1.74l-0.02,-0.25l-0.8,-1.41l0.69,-0.15l0.23,-0.27l0.09,-1.29l0.33,-0.36l0.08,-0.2l0.03,-2.16l1.03,-0.72l0.1,-0.37l-0.7,-1.5l-0.25,-0.17l-1.46,-0.11l-0.22,0.07l-0.34,0.3l-1.17,0.0l-0.55,-1.29l-0.39,-0.16l-1.02,0.44l-0.45,0.36Z\", \"name\": \"Spain\"}, \"ER\": {\"path\": \"M527.15,253.05l-0.77,-0.74l-1.01,-1.47l-1.14,-0.86l-0.62,-0.84l-0.11,-0.09l-2.18,-1.02l-0.12,-0.03l-1.61,-0.03l-0.52,-0.46l-0.31,-0.05l-1.31,0.54l-1.38,-1.06l-0.46,0.12l-0.69,1.68l-2.49,-0.46l-0.2,-0.76l1.06,-3.69l0.24,-1.65l0.66,-0.66l1.76,-0.4l0.16,-0.1l0.97,-1.13l1.24,2.55l0.68,2.34l0.09,0.14l1.4,1.27l3.39,2.4l1.37,1.43l2.14,2.34l0.94,0.6l-0.32,0.26l-0.85,-0.17Z\", \"name\": \"Eritrea\"}, \"ME\": {\"path\": \"M469.05,172.9l-0.57,-0.8l-0.1,-0.09l-0.82,-0.46l0.16,-0.33l0.35,-1.57l0.72,-0.62l0.27,-0.16l0.48,0.38l0.35,0.4l0.12,0.08l0.79,0.32l0.66,0.43l-0.43,0.62l-0.28,0.11l-0.07,-0.25l-0.53,-0.1l-1.09,1.49l-0.05,0.23l0.06,0.32Z\", \"name\": \"Montenegro\"}, \"MD\": {\"path\": \"M488.2,153.75l0.14,-0.11l1.49,-0.28l1.75,0.95l1.06,0.14l0.92,0.7l-0.15,0.9l0.15,0.31l0.8,0.46l0.33,1.2l0.09,0.14l0.72,0.66l-0.11,0.28l0.1,0.33l-0.06,0.02l-1.25,-0.08l-0.17,-0.29l-0.39,-0.12l-0.52,0.25l-0.16,0.36l0.13,0.42l-0.6,0.88l-0.43,1.03l-0.22,0.12l-0.32,-1.0l0.25,-1.34l-0.08,-1.38l-0.06,-0.17l-1.43,-1.87l-0.81,-1.36l-0.78,-0.95l-0.12,-0.09l-0.29,-0.12Z\", \"name\": \"Moldova\"}, \"MG\": {\"path\": \"M544.77,316.45l0.64,1.04l0.6,1.62l0.4,3.04l0.63,1.21l-0.22,1.07l-0.15,0.26l-0.59,-1.05l-0.52,-0.01l-0.47,0.76l-0.04,0.23l0.46,1.84l-0.19,0.92l-0.61,0.53l-0.1,0.21l-0.16,2.15l-0.97,2.98l-1.24,3.59l-1.55,4.97l-0.96,3.67l-1.08,2.93l-1.94,0.61l-2.05,1.06l-3.2,-1.53l-0.62,-1.26l-0.18,-2.39l-0.87,-2.07l-0.22,-1.8l0.4,-1.69l1.01,-0.4l0.19,-0.28l0.01,-0.79l1.15,-1.91l0.04,-0.11l0.23,-1.66l-0.03,-0.17l-0.57,-1.21l-0.46,-1.58l-0.19,-2.25l0.82,-1.36l0.33,-1.51l1.11,-0.1l1.4,-0.53l0.9,-0.45l1.03,-0.03l0.21,-0.09l1.41,-1.45l2.12,-1.65l0.75,-1.29l0.03,-0.24l-0.17,-0.56l0.53,0.15l0.32,-0.1l1.38,-1.77l0.06,-0.18l0.04,-1.44l0.54,-0.74l0.62,0.77Z\", \"name\": \"Madagascar\"}, \"MA\": {\"path\": \"M378.66,230.13l0.07,-0.75l0.93,-0.72l0.82,-1.37l0.04,-0.21l-0.14,-0.8l0.8,-1.74l1.33,-1.61l0.79,-0.4l0.14,-0.15l0.66,-1.55l0.08,-1.46l0.83,-1.52l1.6,-0.94l0.11,-0.11l1.56,-2.71l1.2,-0.99l2.24,-0.29l0.17,-0.08l1.95,-1.83l1.3,-0.77l2.09,-2.28l0.07,-0.26l-0.61,-3.34l0.92,-2.3l0.33,-1.44l1.52,-1.79l2.48,-1.27l1.86,-1.16l0.1,-0.11l1.67,-2.93l0.72,-1.59l1.54,0.01l1.43,1.14l0.21,0.06l2.33,-0.19l2.55,0.62l0.97,0.03l0.83,1.6l0.15,1.71l0.86,2.96l0.09,0.14l0.5,0.45l-0.31,0.73l-3.11,0.44l-0.16,0.07l-1.07,0.97l-1.36,0.23l-0.25,0.28l-0.1,1.85l-2.74,1.02l-0.14,0.11l-0.9,1.3l-1.93,0.69l-2.56,0.44l-4.04,2.01l-0.17,0.27l0.02,2.91l-0.08,0.0l-0.3,0.31l0.05,1.15l-1.25,0.07l-0.16,0.06l-0.73,0.55l-0.98,0.0l-0.85,-0.33l-0.15,-0.02l-2.11,0.29l-0.24,0.19l-0.76,1.95l-0.63,0.16l-0.21,0.19l-1.15,3.29l-3.42,2.81l-0.1,0.17l-0.81,3.57l-0.98,1.12l-0.3,0.85l-5.13,0.19Z\", \"name\": \"Morocco\"}, \"UZ\": {\"path\": \"M587.83,186.48l0.06,-1.46l-0.19,-0.29l-3.31,-1.24l-2.57,-1.4l-1.63,-1.38l-2.79,-1.98l-1.2,-2.98l-0.12,-0.14l-0.84,-0.54l-0.18,-0.05l-2.61,0.13l-0.76,-0.48l-0.25,-2.25l-0.17,-0.24l-3.37,-1.6l-0.32,0.04l-2.08,1.73l-2.11,1.02l-0.16,0.35l0.31,1.14l-2.14,0.03l-0.09,-10.68l6.1,-1.74l6.25,3.57l2.36,2.72l0.27,0.1l2.92,-0.44l4.17,-0.23l2.78,2.06l-0.18,2.87l0.29,0.32l0.98,0.02l0.46,2.22l0.28,0.24l3.0,0.09l0.61,1.25l0.28,0.17l0.93,-0.02l0.26,-0.16l1.06,-2.06l3.21,-2.03l1.3,-0.5l0.19,0.08l-1.75,1.62l0.05,0.48l1.85,1.12l0.27,0.02l1.65,-0.69l2.4,1.27l-2.69,1.79l-1.79,-0.27l-0.89,0.06l-0.22,-0.52l0.48,-1.26l-0.34,-0.4l-3.35,0.69l-0.22,0.18l-0.78,1.87l-1.07,1.47l-1.93,-0.13l-0.29,0.16l-0.65,1.29l0.16,0.42l1.69,0.64l0.48,1.91l-1.25,2.6l-1.64,-0.53l-1.18,-0.03Z\", \"name\": \"Uzbekistan\"}, \"MM\": {\"path\": \"M670.1,233.39l-1.46,1.11l-1.68,0.11l-0.26,0.19l-1.1,2.7l-0.95,0.42l-0.14,0.42l1.21,2.27l1.61,1.92l0.94,1.55l-0.82,1.99l-0.77,0.42l-0.13,0.39l0.64,1.35l1.62,1.97l0.26,1.32l-0.04,1.15l0.02,0.13l0.92,2.18l-1.3,2.23l-0.79,1.69l-0.1,-0.77l0.74,-1.87l-0.02,-0.26l-0.8,-1.42l0.2,-2.68l-0.06,-0.2l-0.98,-1.27l-0.8,-2.98l-0.45,-3.22l-1.11,-2.22l-0.45,-0.1l-1.64,1.28l-2.74,1.76l-1.26,-0.2l-1.27,-0.49l0.79,-2.93l0.0,-0.14l-0.52,-2.42l-1.93,-2.97l0.26,-0.8l-0.22,-0.39l-1.37,-0.31l-1.65,-1.98l-0.12,-1.5l0.41,0.19l0.42,-0.26l0.05,-1.7l1.08,-0.54l0.16,-0.34l-0.24,-1.0l0.5,-0.79l0.05,-0.15l0.08,-2.35l1.58,0.49l0.36,-0.15l1.12,-2.19l0.15,-1.34l1.35,-2.18l0.04,-0.17l-0.07,-1.35l2.97,-1.71l1.67,0.45l0.38,-0.33l-0.18,-1.46l0.7,-0.4l0.15,-0.32l-0.13,-0.72l0.94,-0.13l0.74,1.41l0.11,0.12l0.95,0.56l0.07,1.89l-0.09,2.08l-2.28,2.15l-0.09,0.19l-0.3,3.15l0.35,0.32l2.37,-0.39l0.53,2.17l0.2,0.21l1.3,0.42l-0.63,1.9l0.14,0.36l1.86,0.99l1.1,0.49l0.24,0.0l1.45,-0.6l0.04,0.51l-2.01,1.6l-0.56,0.96l-1.34,0.56Z\", \"name\": \"Myanmar\"}, \"ML\": {\"path\": \"M390.79,248.2l0.67,-0.37l0.14,-0.18l0.36,-1.31l0.51,-0.04l1.68,0.69l0.21,0.0l1.34,-0.48l0.89,0.16l0.3,-0.13l0.29,-0.44l9.89,-0.04l0.29,-0.21l0.56,-1.8l-0.11,-0.33l-0.33,-0.24l-2.37,-22.1l3.41,-0.04l8.37,5.73l8.38,5.68l0.56,1.15l0.14,0.14l1.56,0.75l0.99,0.36l0.03,1.45l0.33,0.29l2.45,-0.22l0.01,5.52l-1.3,1.64l-0.06,0.15l-0.18,1.37l-1.99,0.36l-3.4,0.22l-0.19,0.09l-0.85,0.83l-1.48,0.09l-1.49,0.01l-0.54,-0.43l-0.26,-0.05l-1.38,0.36l-2.39,1.08l-0.13,0.12l-0.44,0.73l-1.88,1.11l-0.11,0.12l-0.3,0.57l-0.86,0.42l-1.1,-0.31l-0.28,0.07l-0.69,0.62l-0.09,0.16l-0.35,1.66l-1.93,2.04l-0.08,0.23l0.05,0.76l-0.63,0.99l-0.04,0.19l0.14,1.23l-0.81,0.29l-0.32,0.17l-0.27,-0.75l-0.39,-0.18l-0.65,0.26l-0.36,-0.04l-0.29,0.14l-0.37,0.6l-1.69,-0.02l-0.63,-0.34l-0.32,0.02l-0.12,0.09l-0.47,-0.45l0.1,-0.6l-0.09,-0.27l-0.31,-0.3l-0.33,-0.05l-0.05,0.02l0.02,-0.21l0.46,-0.59l-0.02,-0.39l-0.99,-1.02l-0.34,-0.74l-0.56,-0.56l-0.17,-0.09l-0.5,-0.07l-0.19,0.04l-0.58,0.35l-0.79,0.33l-0.65,0.51l-0.85,-0.16l-0.63,-0.59l-0.14,-0.07l-0.41,-0.08l-0.2,0.03l-0.59,0.31l-0.07,0.0l-0.1,-0.63l0.11,-0.85l-0.21,-0.98l-0.11,-0.17l-0.86,-0.66l-0.45,-1.34l-0.1,-1.36Z\", \"name\": \"Mali\"}, \"MN\": {\"path\": \"M641.06,150.59l2.41,-0.53l4.76,-2.8l3.67,-1.49l2.06,0.96l0.12,0.03l2.5,0.05l1.59,1.45l0.19,0.08l2.47,0.12l3.59,0.81l0.27,-0.07l2.43,-2.28l0.06,-0.36l-0.93,-1.77l2.33,-3.1l2.66,1.3l2.26,0.39l2.75,0.8l0.44,2.3l0.19,0.22l3.56,1.38l0.18,0.01l2.35,-0.6l3.1,-0.42l2.4,0.41l2.37,1.52l1.49,1.63l0.23,0.1l2.29,-0.03l3.13,0.52l0.15,-0.01l2.28,-0.79l3.27,-0.53l0.11,-0.04l3.56,-2.23l1.31,0.31l1.26,1.05l0.22,0.07l2.45,-0.22l-0.98,1.96l-1.77,3.21l-0.01,0.28l0.64,1.31l0.35,0.16l1.35,-0.38l2.4,0.48l0.22,-0.04l1.78,-1.09l1.82,0.92l2.11,2.07l-0.17,0.68l-1.79,-0.31l-3.74,0.45l-1.85,0.96l-1.78,2.01l-3.74,1.18l-2.46,1.61l-2.45,-0.6l-1.42,-0.28l-0.31,0.13l-1.31,1.99l0.0,0.33l0.78,1.15l0.3,0.74l-1.58,0.93l-1.75,1.59l-2.83,1.03l-3.77,0.12l-4.05,1.05l-2.81,1.54l-0.95,-0.8l-0.19,-0.07l-2.96,0.0l-3.64,-1.8l-2.55,-0.48l-3.38,0.41l-5.13,-0.67l-2.66,0.06l-1.35,-1.65l-1.12,-2.78l-0.21,-0.18l-1.5,-0.33l-2.98,-1.89l-0.12,-0.04l-3.37,-0.43l-2.84,-0.51l-0.75,-1.13l0.93,-3.54l-0.04,-0.24l-1.73,-2.55l-0.15,-0.12l-3.52,-1.18l-1.99,-1.61l-0.54,-1.85Z\", \"name\": \"Mongolia\"}, \"MK\": {\"path\": \"M472.73,173.87l0.08,0.01l0.32,-0.25l0.08,-0.44l1.29,-0.41l1.37,-0.28l1.03,-0.04l1.06,0.82l0.14,1.59l-0.22,0.04l-0.17,0.11l-0.32,0.4l-1.2,-0.05l-0.18,0.05l-0.9,0.61l-1.45,0.23l-0.85,-0.59l-0.3,-1.09l0.22,-0.71Z\", \"name\": \"Macedonia\"}, \"MW\": {\"path\": \"M507.18,313.84l-0.67,1.85l-0.01,0.16l0.7,3.31l0.31,0.24l0.75,-0.03l0.78,0.71l0.99,1.75l0.2,3.03l-0.91,0.45l-0.14,0.15l-0.59,1.38l-1.24,-1.21l-0.17,-1.62l0.49,-1.12l0.02,-0.16l-0.15,-1.03l-0.13,-0.21l-0.99,-0.65l-0.26,-0.03l-0.53,0.18l-1.31,-1.12l-1.15,-0.59l0.66,-2.06l0.75,-0.84l0.07,-0.27l-0.47,-2.04l0.48,-1.94l0.4,-0.65l0.03,-0.24l-0.64,-2.15l-0.08,-0.13l-0.44,-0.42l1.34,0.26l1.25,1.73l0.67,3.3Z\", \"name\": \"Malawi\"}, \"MR\": {\"path\": \"M390.54,247.66l-1.48,-1.58l-1.51,-1.88l-0.12,-0.09l-1.64,-0.67l-1.17,-0.74l-0.17,-0.05l-1.4,0.03l-0.12,0.03l-1.14,0.52l-1.15,-0.21l-0.26,0.08l-0.44,0.43l-0.11,-0.72l0.68,-1.29l0.31,-2.43l-0.28,-2.63l-0.29,-1.27l0.24,-1.24l-0.03,-0.2l-0.65,-1.24l-1.19,-1.05l0.32,-0.51l9.64,0.02l0.3,-0.34l-0.46,-3.71l0.51,-1.12l2.17,-0.22l0.27,-0.3l-0.08,-6.5l7.91,0.13l0.31,-0.3l0.01,-3.5l8.17,5.63l-2.89,0.04l-0.29,0.33l2.42,22.56l0.12,0.21l0.26,0.19l-0.43,1.38l-9.83,0.04l-0.25,0.13l-0.27,0.41l-0.77,-0.14l-0.15,0.01l-1.3,0.47l-1.64,-0.67l-0.14,-0.02l-0.79,0.06l-0.27,0.22l-0.39,1.39l-0.53,0.29Z\", \"name\": \"Mauritania\"}, \"UG\": {\"path\": \"M500.74,287.17l-2.84,-0.02l-0.92,0.32l-1.37,0.71l-0.29,-0.12l0.02,-1.6l0.54,-0.89l0.04,-0.13l0.14,-1.96l0.49,-1.09l0.91,-1.24l0.97,-0.68l0.8,-0.89l-0.13,-0.49l-0.79,-0.27l0.13,-2.55l0.78,-0.52l1.45,0.51l0.18,0.01l1.97,-0.57l1.72,0.01l0.18,-0.06l1.29,-0.97l0.98,1.44l0.29,1.24l1.05,2.75l-0.84,1.68l-1.94,2.66l-0.06,0.18l0.02,2.36l-4.8,0.18Z\", \"name\": \"Uganda\"}, \"MY\": {\"path\": \"M717.6,273.52l-1.51,0.7l-2.13,-0.41l-2.88,-0.0l-0.29,0.21l-0.84,2.77l-0.9,0.82l-0.08,0.12l-1.23,3.34l-1.81,0.47l-2.29,-0.68l-0.14,-0.01l-1.2,0.22l-0.14,0.07l-1.36,1.18l-1.47,-0.17l-0.12,0.01l-1.46,0.46l-1.51,-1.25l-0.24,-0.97l1.26,0.59l0.2,0.02l1.93,-0.47l0.22,-0.22l0.47,-1.98l0.9,-0.4l2.97,-0.54l0.17,-0.09l1.8,-1.98l1.02,-1.32l0.9,1.03l0.48,-0.04l0.43,-0.7l1.02,0.07l0.32,-0.27l0.25,-2.72l1.84,-1.67l1.23,-1.89l0.73,-0.01l1.12,1.11l0.1,0.99l0.18,0.24l1.66,0.71l1.85,0.67l-0.09,0.51l-1.45,0.11l-0.26,0.4l0.35,0.97ZM673.78,269.53l0.17,1.14l0.35,0.25l1.65,-0.3l0.18,-0.11l0.68,-0.86l0.31,0.13l1.41,1.45l0.99,1.59l0.13,1.57l-0.26,1.09l0.0,0.15l0.24,0.84l0.18,1.46l0.11,0.2l0.82,0.64l0.92,2.08l-0.03,0.52l-1.4,0.13l-2.29,-1.79l-2.86,-1.92l-0.27,-1.16l-0.07,-0.13l-1.39,-1.61l-0.33,-1.99l-0.05,-0.12l-0.84,-1.27l0.26,-1.72l-0.03,-0.18l-0.45,-0.87l0.13,-0.13l1.71,0.92Z\", \"name\": \"Malaysia\"}, \"MX\": {\"path\": \"M133.41,213.83l0.61,0.09l0.27,-0.09l0.93,-1.01l0.08,-0.18l0.09,-1.22l-0.09,-0.23l-1.93,-1.94l-1.46,-0.77l-2.96,-5.62l-0.86,-2.1l2.44,-0.18l2.68,-0.25l-0.03,0.08l0.17,0.4l3.79,1.35l5.81,1.97l6.96,-0.02l0.3,-0.3l0.0,-0.84l3.91,0.0l0.87,0.93l1.27,0.87l1.44,1.17l0.79,1.37l0.62,1.49l0.12,0.14l1.35,0.85l2.08,0.82l0.35,-0.1l1.49,-2.04l1.81,-0.05l1.63,1.01l1.21,1.8l0.86,1.58l1.47,1.55l0.53,1.82l0.73,1.32l0.14,0.13l1.98,0.84l1.78,0.59l0.61,-0.03l-0.78,1.89l-0.45,1.96l-0.19,3.58l-0.24,1.27l0.01,0.14l0.43,1.43l0.78,1.31l0.49,1.98l0.06,0.12l1.63,1.9l0.61,1.51l0.98,1.28l0.16,0.11l2.58,0.67l0.98,1.02l0.31,0.08l2.17,-0.71l1.91,-0.26l1.87,-0.47l1.67,-0.49l1.59,-1.06l0.11,-0.14l0.6,-1.52l0.22,-2.21l0.35,-0.62l1.58,-0.64l2.59,-0.59l2.18,0.09l1.43,-0.2l0.39,0.36l-0.07,1.02l-1.28,1.48l-0.65,1.68l0.07,0.32l0.33,0.32l-0.79,2.49l-0.28,-0.3l-0.24,-0.09l-1.0,0.08l-0.24,0.15l-0.74,1.28l-0.19,-0.13l-0.28,-0.03l-0.3,0.12l-0.19,0.29l0.0,0.06l-4.34,-0.02l-0.3,0.3l-0.0,1.16l-0.83,0.0l-0.28,0.19l0.08,0.33l0.93,0.86l0.9,0.58l0.24,0.48l0.16,0.15l0.2,0.08l-0.03,0.38l-2.94,0.01l-0.26,0.15l-1.21,2.09l0.02,0.33l0.25,0.33l-0.21,0.44l-0.04,0.22l-2.42,-2.35l-1.36,-0.87l-2.04,-0.67l-0.13,-0.01l-1.4,0.19l-2.07,0.98l-1.14,0.23l-1.72,-0.66l-1.85,-0.48l-2.31,-1.16l-1.92,-0.38l-2.79,-1.18l-2.04,-1.2l-0.6,-0.66l-0.19,-0.1l-1.37,-0.15l-2.45,-0.78l-1.07,-1.18l-2.63,-1.44l-1.2,-1.56l-0.44,-0.93l0.5,-0.15l0.2,-0.39l-0.2,-0.58l0.46,-0.55l0.07,-0.19l0.01,-0.91l-0.06,-0.18l-0.81,-1.13l-0.25,-1.08l-0.86,-1.36l-2.21,-2.63l-2.53,-2.09l-1.2,-1.63l-0.11,-0.09l-2.08,-1.06l-0.34,-0.48l0.35,-1.53l-0.16,-0.34l-1.24,-0.61l-1.39,-1.23l-0.6,-1.81l-0.24,-0.2l-1.25,-0.2l-1.38,-1.35l-1.11,-1.25l-0.1,-0.76l-0.05,-0.13l-1.33,-2.04l-0.85,-2.02l0.04,-0.99l-0.14,-0.27l-1.81,-1.1l-0.2,-0.04l-0.74,0.11l-1.34,-0.72l-0.42,0.16l-0.4,1.12l-0.0,0.19l0.41,1.3l0.24,2.04l0.06,0.15l0.88,1.16l1.84,1.86l0.4,0.61l0.12,0.1l0.27,0.14l0.29,0.82l0.31,0.2l0.2,-0.02l0.43,1.51l0.09,0.14l0.72,0.65l0.51,0.91l1.58,1.4l0.8,2.42l0.77,1.23l0.66,1.19l0.13,1.34l0.28,0.27l1.08,0.08l0.92,1.1l0.83,1.08l-0.03,0.24l-0.88,0.81l-0.13,-0.0l-0.59,-1.42l-0.07,-0.11l-1.67,-1.53l-1.81,-1.28l-1.15,-0.61l0.07,-1.85l-0.38,-1.45l-0.12,-0.17l-2.91,-2.03l-0.39,0.04l-0.11,0.11l-0.42,-0.46l-0.11,-0.08l-1.49,-0.63l-1.09,-1.16Z\", \"name\": \"Mexico\"}, \"VU\": {\"path\": \"M839.92,325.66l0.78,0.73l-0.18,0.07l-0.6,-0.8ZM839.13,322.74l0.27,1.36l-0.13,-0.06l-0.21,-0.02l-0.29,0.08l-0.22,-0.43l-0.03,-1.32l0.61,0.4Z\", \"name\": \"Vanuatu\"}, \"FR\": {\"path\": \"M444.58,172.63l-0.68,1.92l-0.72,-0.38l-0.51,-1.79l0.43,-0.95l1.15,-0.83l0.33,2.04ZM429.71,147.03l1.77,1.57l0.26,0.07l1.16,-0.23l2.12,1.44l0.56,0.28l0.16,0.03l0.61,-0.06l1.09,0.78l0.13,0.05l3.18,0.53l-1.09,1.94l-0.3,2.16l-0.48,0.38l-1.0,-0.26l-0.37,0.32l0.07,0.66l-1.73,1.68l-0.09,0.21l-0.04,1.42l0.41,0.29l0.96,-0.4l0.67,1.07l-0.09,0.78l0.04,0.19l0.61,0.97l-0.71,0.78l-0.07,0.28l0.65,2.39l0.21,0.21l1.09,0.31l-0.2,0.95l-2.08,1.58l-4.81,-0.8l-0.13,0.01l-3.65,0.99l-0.22,0.24l-0.25,1.6l-2.59,0.35l-2.74,-1.33l-0.31,0.03l-0.79,0.57l-4.38,-1.31l-0.79,-0.94l1.16,-1.64l0.05,-0.15l0.48,-6.17l-0.06,-0.21l-2.58,-3.3l-1.89,-1.65l-0.11,-0.06l-3.64,-1.17l-0.2,-1.88l2.92,-0.63l4.14,0.82l0.35,-0.36l-0.65,-3.0l1.77,1.05l0.27,0.02l5.83,-2.54l0.17,-0.19l0.71,-2.54l1.75,-0.53l0.27,0.88l0.27,0.21l1.04,0.05l1.08,1.23ZM289.1,278.45l-0.85,0.84l-0.88,0.13l-0.25,-0.51l-0.21,-0.16l-0.56,-0.1l-0.25,0.07l-0.63,0.55l-0.62,-0.29l0.5,-0.88l0.21,-1.11l0.42,-1.05l-0.03,-0.28l-0.93,-1.42l-0.18,-1.54l1.13,-1.87l2.42,0.78l2.55,2.04l0.33,0.81l-1.4,2.16l-0.77,1.84Z\", \"name\": \"France\"}, \"FI\": {\"path\": \"M492.26,76.42l-0.38,3.12l0.12,0.28l3.6,2.69l-2.14,2.96l-0.01,0.33l2.83,4.61l-1.61,3.36l0.03,0.31l2.15,2.87l-0.96,2.44l0.1,0.35l3.51,2.55l-0.81,1.72l-2.28,2.19l-5.28,4.79l-4.51,0.31l-4.39,1.37l-3.87,0.75l-1.34,-1.89l-0.11,-0.09l-2.23,-1.14l0.53,-3.54l-0.01,-0.14l-1.17,-3.37l1.12,-2.13l2.23,-2.44l5.69,-4.33l1.65,-0.84l0.16,-0.31l-0.26,-1.73l-0.15,-0.22l-3.4,-1.91l-0.77,-1.47l-0.07,-6.45l-0.12,-0.24l-3.91,-2.94l-3.0,-1.92l0.97,-0.76l2.6,2.17l0.21,0.07l3.2,-0.21l2.63,1.03l0.3,-0.05l2.39,-1.94l0.09,-0.13l1.18,-3.12l3.63,-1.42l2.87,1.59l-0.98,2.87Z\", \"name\": \"Finland\"}, \"FJ\": {\"path\": \"M869.98,327.07l-1.31,0.44l-0.14,-0.41l0.96,-0.41l0.85,-0.17l1.43,-0.78l-0.16,0.65l-1.64,0.67ZM867.58,329.12l0.54,0.47l-0.31,1.0l-1.32,0.3l-1.13,-0.26l-0.17,-0.78l0.72,-0.66l0.98,0.27l0.25,-0.04l0.43,-0.29Z\", \"name\": \"Fiji\"}, \"FK\": {\"path\": \"M268.15,427.89l2.6,-1.73l1.98,0.77l0.31,-0.05l1.32,-1.17l1.58,1.18l-0.54,0.84l-3.1,0.92l-1.0,-1.04l-0.39,-0.04l-1.9,1.35l-0.86,-1.04Z\", \"name\": \"Falkland Islands\"}, \"NI\": {\"path\": \"M202.1,252.6l0.23,-0.0l0.12,-0.11l0.68,-0.09l0.22,-0.15l0.23,-0.43l0.2,-0.01l0.28,-0.31l-0.04,-0.97l0.29,-0.03l0.5,0.02l0.25,-0.11l0.37,-0.46l0.51,0.35l0.4,-0.06l0.23,-0.28l0.45,-0.29l0.87,-0.7l0.11,-0.21l0.02,-0.26l0.23,-0.12l0.25,-0.48l0.29,0.27l0.14,0.07l0.5,0.12l0.22,-0.03l0.48,-0.28l0.66,-0.02l0.87,-0.33l0.36,-0.32l0.21,0.01l-0.11,0.48l0.0,0.14l0.22,0.8l-0.54,0.85l-0.27,1.03l-0.09,1.18l0.14,0.72l0.05,0.95l-0.24,0.15l-0.13,0.19l-0.23,1.09l0.0,0.14l0.14,0.53l-0.42,0.53l-0.06,0.24l0.12,0.69l0.08,0.15l0.18,0.19l-0.26,0.23l-0.49,-0.11l-0.35,-0.44l-0.16,-0.1l-0.79,-0.21l-0.23,0.03l-0.45,0.26l-1.51,-0.62l-0.31,0.05l-0.17,0.15l-1.81,-1.62l-0.6,-0.9l-1.04,-0.79l-0.77,-0.71Z\", \"name\": \"Nicaragua\"}, \"NL\": {\"path\": \"M436.22,136.65l1.82,0.08l0.36,0.89l-0.6,2.96l-0.53,1.06l-1.32,0.0l-0.3,0.34l0.35,2.89l-0.83,-0.47l-1.56,-1.43l-0.29,-0.07l-2.26,0.67l-1.02,-0.15l0.68,-0.48l0.1,-0.12l2.14,-4.84l3.25,-1.35Z\", \"name\": \"Netherlands\"}, \"NO\": {\"path\": \"M491.45,67.31l7.06,3.0l-2.52,0.94l-0.11,0.49l2.43,2.49l-3.82,1.59l-1.48,0.3l0.89,-2.61l-0.14,-0.36l-3.21,-1.78l-0.25,-0.02l-3.89,1.52l-0.17,0.17l-1.2,3.17l-2.19,1.78l-2.53,-0.99l-0.13,-0.02l-3.15,0.21l-2.69,-2.25l-0.38,-0.01l-1.43,1.11l-1.47,0.17l-0.26,0.26l-0.33,2.57l-4.42,-0.65l-0.33,0.22l-0.6,2.19l-2.17,-0.01l-0.27,0.16l-4.15,7.68l-3.88,5.76l-0.0,0.33l0.81,1.23l-0.7,1.27l-2.3,-0.06l-0.28,0.18l-1.63,3.72l-0.02,0.13l0.15,5.17l0.07,0.18l1.51,1.84l-0.79,4.24l-2.04,2.5l-0.92,1.75l-1.39,-1.88l-0.44,-0.05l-4.89,4.21l-3.16,0.81l-3.24,-1.74l-0.86,-3.82l-0.78,-8.6l2.18,-2.36l6.56,-3.28l5.0,-4.16l4.63,-5.74l5.99,-8.09l4.17,-3.23l6.84,-5.49l5.39,-1.92l4.06,0.24l0.23,-0.09l3.72,-3.67l4.51,0.19l4.4,-0.89ZM484.58,19.95l4.42,1.82l-3.25,2.68l-7.14,0.65l-7.16,-0.91l-0.39,-1.37l-0.28,-0.22l-3.48,-0.1l-2.25,-2.15l7.09,-1.48l3.55,1.36l0.28,-0.03l2.42,-1.66l6.18,1.41ZM481.99,33.92l-4.73,1.85l-3.76,-1.06l1.27,-1.02l0.04,-0.43l-1.18,-1.35l4.46,-0.94l0.89,1.83l0.17,0.15l2.83,0.96ZM466.5,23.95l7.64,3.87l-5.63,1.94l-0.19,0.19l-1.35,3.88l-2.08,0.96l-0.16,0.19l-1.14,4.18l-2.71,0.18l-4.94,-2.95l1.95,-1.63l-0.08,-0.51l-3.7,-1.54l-4.79,-4.54l-1.78,-4.01l6.29,-1.88l1.25,1.81l0.25,0.13l3.57,-0.08l0.26,-0.17l0.87,-1.79l3.41,-0.18l3.08,1.94Z\", \"name\": \"Norway\"}, \"NA\": {\"path\": \"M461.88,357.98l-1.61,-1.77l-0.94,-1.9l-0.54,-2.58l-0.62,-1.95l-0.83,-4.05l-0.06,-3.13l-0.33,-1.5l-0.07,-0.14l-0.95,-1.06l-1.27,-2.12l-1.3,-3.1l-0.59,-1.71l-1.98,-2.46l-0.13,-1.67l0.99,-0.4l1.44,-0.42l1.48,0.07l1.42,1.11l0.31,0.03l0.32,-0.15l9.99,-0.11l1.66,1.18l0.16,0.06l6.06,0.37l4.69,-1.06l2.01,-0.57l1.5,0.14l0.63,0.37l-1.0,0.41l-0.7,0.01l-0.16,0.05l-1.38,0.88l-0.79,-0.88l-0.29,-0.09l-3.83,0.9l-1.84,0.08l-0.29,0.3l-0.07,8.99l-2.18,0.08l-0.29,0.3l-0.0,17.47l-2.04,1.27l-1.21,0.18l-1.51,-0.49l-0.99,-0.18l-0.36,-1.0l-0.1,-0.14l-0.99,-0.74l-0.4,0.04l-0.98,1.09Z\", \"name\": \"Namibia\"}, \"NC\": {\"path\": \"M835.87,338.68l2.06,1.63l1.01,0.94l-0.49,0.32l-1.21,-0.62l-1.76,-1.16l-1.58,-1.36l-1.61,-1.79l-0.16,-0.41l0.54,0.02l1.32,0.83l1.08,0.87l0.79,0.73Z\", \"name\": \"New Caledonia\"}, \"NE\": {\"path\": \"M426.67,254.17l0.03,-1.04l-0.24,-0.3l-2.66,-0.53l-0.06,-1.0l-0.07,-0.17l-1.37,-1.62l-0.3,-1.04l0.15,-0.94l1.37,-0.09l0.19,-0.09l0.85,-0.83l3.34,-0.22l2.22,-0.41l0.24,-0.26l0.2,-1.5l1.32,-1.65l0.07,-0.19l-0.01,-5.74l3.4,-1.13l7.24,-5.12l8.46,-4.95l3.76,1.08l1.35,1.39l0.36,0.05l1.39,-0.77l0.55,3.66l0.12,0.2l0.82,0.6l0.03,0.69l0.1,0.21l0.87,0.74l-0.47,0.99l-0.96,5.26l-0.13,3.25l-3.08,2.34l-0.1,0.15l-1.08,3.37l0.08,0.31l0.94,0.86l-0.01,1.51l0.29,0.3l1.25,0.05l-0.14,0.66l-0.51,0.11l-0.24,0.26l-0.06,0.57l-0.04,0.0l-1.59,-2.62l-0.21,-0.14l-0.59,-0.1l-0.23,0.05l-1.83,1.33l-1.79,-0.68l-1.42,-0.17l-0.17,0.03l-0.65,0.32l-1.39,-0.07l-0.19,0.06l-1.4,1.03l-1.12,0.05l-2.97,-1.29l-0.26,0.01l-1.12,0.59l-1.08,-0.04l-0.85,-0.88l-0.11,-0.07l-2.51,-0.95l-0.14,-0.02l-2.69,0.3l-0.16,0.07l-0.65,0.55l-0.1,0.16l-0.34,1.41l-0.69,0.98l-0.05,0.15l-0.13,1.72l-1.47,-1.13l-0.18,-0.06l-0.9,0.01l-0.2,0.08l-0.32,0.28Z\", \"name\": \"Niger\"}, \"NG\": {\"path\": \"M442.0,272.7l-2.4,0.83l-0.88,-0.12l-0.19,0.04l-0.89,0.52l-1.78,-0.05l-1.23,-1.44l-0.88,-1.87l-1.77,-1.66l-0.21,-0.08l-3.78,0.03l0.13,-3.75l-0.06,-1.58l0.44,-1.47l0.74,-0.75l1.21,-1.56l0.04,-0.29l-0.22,-0.56l0.44,-0.9l0.01,-0.24l-0.54,-1.44l0.26,-2.97l0.72,-1.06l0.33,-1.37l0.51,-0.43l2.53,-0.28l2.38,0.9l0.89,0.91l0.2,0.09l1.28,0.04l0.15,-0.03l1.06,-0.56l2.9,1.26l0.13,0.02l1.28,-0.06l0.16,-0.06l1.39,-1.02l1.36,0.07l0.15,-0.03l0.64,-0.32l1.22,0.13l1.9,0.73l0.28,-0.04l1.86,-1.35l0.33,0.06l1.62,2.67l0.29,0.14l0.32,-0.04l0.73,0.74l-0.19,0.37l-0.12,0.74l-2.03,1.89l-0.07,0.11l-0.66,1.62l-0.35,1.28l-0.48,0.51l-0.07,0.12l-0.48,1.67l-1.26,0.98l-0.1,0.15l-0.38,1.24l-0.58,1.07l-0.2,0.91l-1.43,0.7l-1.26,-0.93l-0.19,-0.06l-0.95,0.04l-0.2,0.09l-1.41,1.39l-0.61,0.02l-0.26,0.17l-1.19,2.42l-0.61,1.67Z\", \"name\": \"Nigeria\"}, \"NZ\": {\"path\": \"M857.9,379.62l1.85,3.1l0.33,0.14l0.22,-0.28l0.04,-1.41l0.57,0.4l0.35,2.06l0.17,0.22l2.02,0.94l1.78,0.26l0.22,-0.06l1.31,-1.01l0.84,0.22l-0.53,2.27l-0.67,1.5l-1.71,-0.05l-0.25,0.12l-0.67,0.89l-0.05,0.23l0.21,1.15l-0.31,0.46l-2.15,3.57l-1.6,0.99l-0.28,-0.51l-0.15,-0.13l-0.72,-0.3l1.27,-2.15l0.01,-0.29l-0.82,-1.63l-0.15,-0.14l-2.5,-1.09l0.05,-0.69l1.67,-0.94l0.15,-0.21l0.42,-2.24l-0.11,-1.95l-0.03,-0.12l-0.97,-1.85l0.05,-0.41l-0.09,-0.25l-1.18,-1.17l-1.94,-2.49l-0.86,-1.64l0.38,-0.09l1.24,1.43l0.12,0.08l1.81,0.68l0.67,2.39ZM853.93,393.55l0.57,1.24l0.44,0.12l1.51,-1.03l0.52,0.91l0.0,1.09l-0.88,1.31l-1.62,2.2l-1.26,1.2l-0.05,0.38l0.64,1.02l-1.4,0.03l-0.14,0.04l-2.14,1.16l-0.14,0.17l-0.67,2.0l-1.38,3.06l-3.07,2.19l-2.12,-0.06l-1.55,-0.99l-0.14,-0.05l-2.53,-0.2l-0.31,-0.84l1.25,-2.15l3.07,-2.97l1.62,-0.59l1.81,-1.17l2.18,-1.63l1.55,-1.65l1.08,-2.18l0.9,-0.72l0.11,-0.17l0.35,-1.56l1.37,-1.07l0.4,0.91Z\", \"name\": \"New Zealand\"}, \"NP\": {\"path\": \"M641.26,213.53l-0.14,0.95l0.32,1.64l-0.21,0.78l-1.83,0.04l-2.98,-0.62l-1.86,-0.25l-1.37,-1.3l-0.18,-0.08l-3.38,-0.34l-3.21,-1.49l-2.38,-1.34l-2.16,-0.92l0.84,-2.2l1.51,-1.18l0.89,-0.57l1.83,0.77l2.5,1.76l1.39,0.41l0.78,1.21l0.17,0.13l1.91,0.53l2.0,1.17l2.92,0.66l2.63,0.24Z\", \"name\": \"Nepal\"}, \"CI\": {\"path\": \"M413.53,272.08l-0.83,0.02l-1.79,-0.49l-1.64,0.03l-3.04,0.46l-1.73,0.72l-2.4,0.89l-0.12,-0.02l0.16,-1.7l0.19,-0.25l0.06,-0.2l-0.08,-0.99l-0.09,-0.19l-1.06,-1.05l-0.15,-0.08l-0.71,-0.15l-0.51,-0.48l0.45,-0.92l0.02,-0.19l-0.24,-1.16l0.07,-0.43l0.14,-0.0l0.3,-0.26l0.15,-1.1l-0.02,-0.15l-0.13,-0.34l0.09,-0.13l0.83,-0.27l0.19,-0.37l-0.62,-2.02l-0.55,-1.0l0.14,-0.59l0.35,-0.14l0.24,-0.16l0.53,0.29l0.14,0.04l1.93,0.02l0.26,-0.14l0.36,-0.58l0.39,0.01l0.43,-0.17l0.28,0.79l0.43,0.16l0.56,-0.31l0.89,-0.32l0.92,0.45l0.39,0.75l0.14,0.13l1.13,0.53l0.3,-0.03l0.81,-0.59l1.02,-0.08l1.49,0.57l0.62,3.33l-1.03,2.09l-0.65,2.84l0.02,0.2l1.05,2.08l-0.07,0.64Z\", \"name\": \"Ivory Coast\"}, \"CH\": {\"path\": \"M444.71,156.27l0.05,0.3l-0.34,0.69l0.13,0.4l1.13,0.58l1.07,0.1l-0.12,0.81l-0.87,0.42l-1.75,-0.37l-0.34,0.18l-0.47,1.1l-0.86,0.07l-0.33,-0.38l-0.41,-0.04l-1.34,1.01l-1.02,0.13l-0.93,-0.58l-0.82,-1.32l-0.37,-0.12l-0.77,0.32l0.02,-0.84l1.74,-1.69l0.09,-0.25l-0.04,-0.38l0.73,0.19l0.26,-0.06l0.6,-0.48l2.02,0.02l0.24,-0.12l0.38,-0.51l2.31,0.84Z\", \"name\": \"Switzerland\"}, \"CO\": {\"path\": \"M232.24,284.95l-0.94,-0.52l-1.22,-0.82l-0.31,-0.01l-0.62,0.35l-1.88,-0.31l-0.54,-0.95l-0.29,-0.15l-0.37,0.03l-2.34,-1.33l-0.15,-0.35l0.57,-0.11l0.24,-0.32l-0.1,-1.15l0.46,-0.71l1.11,-0.15l0.21,-0.13l1.05,-1.57l0.95,-1.31l-0.08,-0.43l-0.73,-0.47l0.4,-1.24l0.01,-0.16l-0.53,-2.15l0.44,-0.54l0.06,-0.24l-0.4,-2.13l-0.06,-0.13l-0.93,-1.22l0.21,-0.8l0.52,0.12l0.32,-0.13l0.47,-0.75l0.03,-0.27l-0.52,-1.32l0.09,-0.11l1.14,0.07l0.22,-0.08l1.82,-1.71l0.96,-0.25l0.22,-0.28l0.02,-0.81l0.43,-2.01l1.28,-1.04l1.48,-0.05l0.27,-0.19l0.12,-0.31l1.73,0.19l0.2,-0.05l1.96,-1.28l0.97,-0.56l1.16,-1.16l0.64,0.11l0.43,0.44l-0.31,0.55l-1.49,0.39l-0.19,0.16l-0.6,1.2l-0.97,0.74l-0.73,0.94l-0.06,0.13l-0.3,1.76l-0.68,1.44l0.23,0.43l1.1,0.14l0.27,0.97l0.08,0.13l0.49,0.49l0.17,0.85l-0.27,0.86l-0.01,0.14l0.09,0.53l0.2,0.23l0.52,0.18l0.54,0.79l0.27,0.13l3.18,-0.24l1.31,0.29l1.7,2.08l0.31,0.1l0.96,-0.26l1.75,0.13l1.41,-0.27l0.56,0.27l-0.36,1.07l-0.54,0.81l-0.05,0.13l-0.2,1.8l0.51,1.79l0.07,0.12l0.65,0.68l0.05,0.32l-1.16,1.14l0.05,0.47l0.86,0.52l0.6,0.79l0.31,1.01l-0.7,-0.81l-0.44,-0.01l-0.74,0.77l-4.75,-0.05l-0.3,0.31l0.03,1.57l0.25,0.29l1.2,0.21l-0.02,0.24l-0.1,-0.05l-0.22,-0.02l-1.41,0.41l-0.22,0.29l-0.01,1.82l0.11,0.23l1.04,0.85l0.35,1.3l-0.06,1.02l-1.02,6.26l-0.84,-0.89l-0.19,-0.09l-0.25,-0.02l1.35,-2.13l-0.1,-0.42l-1.92,-1.17l-0.2,-0.04l-1.41,0.2l-0.82,-0.39l-0.26,0.0l-1.29,0.62l-1.63,-0.27l-1.4,-2.5l-0.12,-0.12l-1.1,-0.61l-0.83,-1.2l-1.67,-1.19l-0.27,-0.04l-0.54,0.19Z\", \"name\": \"Colombia\"}, \"CN\": {\"path\": \"M740.32,148.94l0.22,0.21l4.3,1.03l2.84,2.2l0.99,2.92l0.28,0.2l3.8,0.0l0.15,-0.04l2.13,-1.24l3.5,-0.8l-1.05,2.29l-0.95,1.13l-0.06,0.12l-0.85,3.41l-1.56,2.81l-2.83,-0.51l-0.19,0.03l-2.15,1.09l-0.15,0.34l0.65,2.59l-0.33,3.3l-1.03,0.07l-0.28,0.3l0.01,0.75l-1.09,-1.2l-0.48,0.05l-0.94,1.6l-3.76,1.26l-0.2,0.36l0.29,1.19l-1.67,-0.08l-1.11,-0.88l-0.42,0.05l-1.69,2.08l-2.71,1.57l-2.04,1.88l-3.42,0.84l-0.11,0.05l-1.8,1.34l-1.54,0.46l0.52,-0.53l0.06,-0.33l-0.44,-0.96l1.84,-1.84l0.02,-0.41l-1.32,-1.56l-0.36,-0.08l-2.23,1.08l-2.83,2.06l-1.52,1.85l-2.32,0.13l-0.2,0.09l-1.28,1.37l-0.03,0.37l1.32,1.97l0.18,0.13l1.83,0.43l0.07,1.08l0.18,0.26l1.98,0.84l0.3,-0.03l2.66,-1.96l2.06,1.04l0.12,0.03l1.4,0.07l0.27,1.0l-3.24,0.73l-0.17,0.11l-1.13,1.5l-2.38,1.4l-0.1,0.1l-1.29,1.99l0.1,0.42l2.6,1.5l0.97,2.72l1.52,2.56l1.66,2.08l-0.03,1.76l-1.4,0.67l-0.15,0.38l0.6,1.47l0.13,0.15l1.29,0.75l-0.35,2.0l-0.58,1.96l-1.22,0.21l-0.2,0.14l-1.83,2.93l-2.02,3.51l-2.29,3.13l-3.4,2.42l-3.42,2.18l-2.75,0.3l-0.15,0.06l-1.32,1.01l-0.68,-0.67l-0.41,-0.01l-1.37,1.27l-3.42,1.28l-2.62,0.4l-0.24,0.21l-0.8,2.57l-0.95,0.11l-0.53,-1.54l0.52,-0.89l-0.19,-0.44l-3.36,-0.84l-0.17,0.01l-1.09,0.4l-2.36,-0.64l-1.0,-0.9l0.35,-1.34l-0.23,-0.37l-2.22,-0.47l-1.15,-0.94l-0.36,-0.02l-2.08,1.37l-2.35,0.29l-1.98,-0.01l-0.13,0.03l-1.32,0.63l-1.28,0.38l-0.21,0.33l0.33,2.65l-0.78,-0.04l-0.14,-0.39l-0.07,-1.04l-0.41,-0.26l-1.72,0.71l-0.96,-0.43l-1.63,-0.86l0.65,-1.95l-0.19,-0.38l-1.43,-0.46l-0.56,-2.27l-0.34,-0.22l-2.26,0.38l0.25,-2.65l2.29,-2.15l0.09,-0.2l0.1,-2.21l-0.07,-2.09l-0.15,-0.25l-1.02,-0.6l-0.8,-1.52l-0.31,-0.16l-1.42,0.2l-2.16,-0.32l0.55,-0.74l0.01,-0.35l-1.17,-1.7l-0.41,-0.08l-1.67,1.07l-1.97,-0.63l-0.25,0.03l-2.89,1.73l-2.26,1.99l-1.82,0.3l-1.0,-0.66l-0.15,-0.05l-1.28,-0.06l-1.75,-0.61l-0.24,0.02l-1.35,0.69l-0.1,0.08l-1.2,1.45l-0.14,-1.41l-0.4,-0.25l-1.46,0.55l-2.83,-0.26l-2.77,-0.61l-1.99,-1.17l-1.91,-0.54l-0.78,-1.21l-0.17,-0.13l-1.36,-0.38l-2.54,-1.79l-2.01,-0.84l-0.28,0.02l-0.89,0.56l-3.31,-1.83l-2.35,-1.67l-0.57,-2.49l1.34,0.28l0.36,-0.28l0.08,-1.42l-0.05,-0.19l-0.93,-1.34l0.24,-2.18l-0.07,-0.22l-2.69,-3.32l-0.15,-0.1l-3.97,-1.11l-0.69,-2.05l-0.11,-0.15l-1.79,-1.3l-0.39,-0.73l-0.36,-1.57l0.08,-1.09l-0.18,-0.3l-1.52,-0.66l-0.22,-0.01l-0.51,0.18l-0.52,-2.21l0.59,-0.55l0.06,-0.35l-0.22,-0.44l2.12,-1.24l1.63,-0.55l2.58,0.39l0.31,-0.16l0.87,-1.75l3.05,-0.34l0.21,-0.12l0.84,-1.12l3.87,-1.59l0.15,-0.14l0.35,-0.68l0.03,-0.17l-0.17,-1.51l1.52,-0.7l0.15,-0.39l-2.12,-5.0l4.62,-1.15l1.35,-0.72l0.14,-0.17l1.72,-5.37l4.7,0.99l0.28,-0.08l1.39,-1.43l0.08,-0.2l0.11,-2.95l1.83,-0.26l0.18,-0.1l1.85,-2.08l0.61,-0.17l0.57,1.97l0.1,0.15l2.2,1.75l3.48,1.17l1.59,2.36l-0.93,3.53l0.04,0.24l0.9,1.35l0.2,0.13l2.98,0.53l3.32,0.43l2.97,1.89l1.49,0.35l1.08,2.67l1.52,1.88l0.24,0.11l2.74,-0.07l5.15,0.67l3.36,-0.41l2.39,0.43l3.67,1.81l0.13,0.03l2.92,-0.0l1.02,0.86l0.34,0.03l2.88,-1.59l3.98,-1.03l3.81,-0.13l3.02,-1.12l1.77,-1.61l1.73,-1.01l0.13,-0.37l-0.41,-1.01l-0.72,-1.07l1.09,-1.66l1.21,0.24l2.57,0.63l0.24,-0.04l2.46,-1.62l3.78,-1.19l0.13,-0.09l1.8,-2.03l1.66,-0.84l3.54,-0.41l1.93,0.35l0.34,-0.22l0.27,-1.12l-0.08,-0.29l-2.27,-2.22l-2.08,-1.07l-0.29,0.01l-1.82,1.12l-2.36,-0.47l-0.14,0.01l-1.18,0.34l-0.46,-0.94l1.69,-3.08l1.1,-2.21l2.75,1.12l0.26,-0.02l3.53,-2.06l0.15,-0.26l-0.02,-1.35l2.18,-3.39l1.35,-1.04l0.12,-0.24l-0.03,-1.85l-0.15,-0.25l-1.0,-0.58l1.68,-1.37l3.01,-0.59l3.25,-0.09l3.67,0.99l2.08,1.18l1.51,3.3l0.95,1.45l0.85,1.99l0.92,3.19ZM697.0,237.37l-1.95,1.12l-1.74,-0.68l-0.06,-1.9l1.08,-1.03l2.62,-0.7l1.23,0.05l0.37,0.65l-1.01,1.08l-0.54,1.4Z\", \"name\": \"China\"}, \"CM\": {\"path\": \"M453.76,278.92l-0.26,-0.11l-0.18,-0.02l-1.42,0.31l-1.56,-0.33l-1.17,0.16l-3.7,-0.05l0.3,-1.63l-0.04,-0.21l-0.98,-1.66l-0.15,-0.13l-1.03,-0.38l-0.46,-1.01l-0.13,-0.14l-0.48,-0.27l0.02,-0.46l0.62,-1.72l1.1,-2.25l0.54,-0.02l0.2,-0.09l1.41,-1.39l0.73,-0.03l1.32,0.97l0.31,0.03l1.72,-0.85l0.16,-0.2l0.22,-1.0l0.57,-1.03l0.36,-1.18l1.26,-0.98l0.1,-0.15l0.49,-1.7l0.48,-0.51l0.07,-0.13l0.35,-1.3l0.63,-1.54l2.06,-1.92l0.09,-0.17l0.12,-0.79l0.24,-0.41l-0.04,-0.36l-0.89,-0.91l0.04,-0.45l0.28,-0.06l0.85,1.39l0.16,1.59l-0.09,1.66l0.04,0.17l1.09,1.84l-0.86,-0.02l-0.72,0.17l-1.07,-0.24l-0.34,0.17l-0.54,1.19l0.06,0.34l1.48,1.47l1.06,0.44l0.32,0.94l0.73,1.6l-0.32,0.57l-1.23,2.49l-0.54,0.41l-0.12,0.21l-0.19,1.95l0.24,1.08l-0.18,0.67l0.07,0.28l1.13,1.25l0.24,0.93l0.92,1.29l1.1,0.8l0.1,1.01l0.26,0.73l-0.12,0.93l-1.65,-0.49l-2.02,-0.66l-3.19,-0.11Z\", \"name\": \"Cameroon\"}, \"CL\": {\"path\": \"M246.8,429.1l-1.14,0.78l-2.25,1.21l-0.16,0.23l-0.37,2.94l-0.75,0.06l-2.72,-1.07l-2.83,-2.34l-3.06,-1.9l-0.71,-1.92l0.67,-1.84l-0.02,-0.25l-1.22,-2.13l-0.31,-5.41l1.02,-2.95l2.59,-2.4l-0.13,-0.51l-3.32,-0.8l2.06,-2.4l0.07,-0.15l0.79,-4.77l2.44,0.95l0.4,-0.22l1.31,-6.31l-0.16,-0.33l-1.68,-0.8l-0.42,0.21l-0.72,3.47l-1.01,-0.27l0.74,-4.06l0.85,-5.46l1.12,-1.96l0.03,-0.22l-0.71,-2.82l-0.19,-2.94l0.76,-0.07l0.26,-0.2l1.53,-4.62l1.73,-4.52l1.07,-4.2l-0.56,-4.2l0.73,-2.2l0.01,-0.12l-0.29,-3.3l1.46,-3.34l0.45,-5.19l0.8,-5.52l0.78,-5.89l-0.18,-4.33l-0.49,-3.47l1.1,-0.56l0.13,-0.13l0.44,-0.88l0.9,1.29l0.32,1.8l0.1,0.18l1.16,0.97l-0.73,2.33l0.01,0.21l1.33,2.91l0.97,3.6l0.35,0.22l1.57,-0.31l0.16,0.34l-0.79,2.51l-2.61,1.25l-0.17,0.28l0.08,4.36l-0.48,0.79l0.01,0.33l0.6,0.84l-1.62,1.55l-1.67,2.6l-0.89,2.47l-0.02,0.13l0.23,2.56l-1.5,2.76l-0.03,0.21l1.15,4.8l0.11,0.17l0.54,0.42l-0.01,2.37l-1.4,2.7l-0.03,0.15l0.06,2.25l-1.8,1.78l-0.09,0.21l0.02,2.73l0.71,2.63l-1.33,0.94l-0.12,0.17l-0.67,2.64l-0.59,3.03l0.4,3.55l-0.84,0.51l-0.14,0.31l0.58,3.5l0.08,0.16l0.96,0.99l-0.7,1.08l0.11,0.43l1.04,0.55l0.19,0.8l-0.89,0.48l-0.16,0.31l0.26,1.77l-0.89,4.06l-1.31,2.67l-0.03,0.19l0.28,1.53l-0.73,1.88l-1.85,1.37l-0.12,0.26l0.22,3.46l0.06,0.16l0.88,1.19l0.28,0.12l1.32,-0.17l-0.04,2.13l0.04,0.15l1.04,1.95l0.24,0.16l5.94,0.44ZM248.79,430.71l0.0,7.41l0.3,0.3l2.67,0.0l1.01,0.06l-0.54,0.91l-1.99,1.01l-1.13,-0.1l-1.42,-0.27l-1.87,-1.06l-2.57,-0.49l-3.09,-1.9l-2.52,-1.83l-2.65,-2.93l0.93,0.32l3.54,2.29l3.32,1.23l0.34,-0.09l1.29,-1.57l0.83,-2.32l2.11,-1.28l1.43,0.32Z\", \"name\": \"Chile\"}, \"CA\": {\"path\": \"M280.14,145.66l-1.66,2.88l0.06,0.37l0.37,0.03l1.5,-1.01l1.17,0.49l-0.64,0.83l0.13,0.46l2.22,0.89l0.28,-0.03l1.02,-0.7l2.09,0.83l-0.69,2.1l0.37,0.38l1.43,-0.45l0.27,1.43l0.74,1.88l-0.95,2.5l-0.88,0.09l-1.34,-0.48l0.49,-2.34l-0.14,-0.32l-0.7,-0.4l-0.36,0.04l-2.81,2.66l-0.63,-0.05l1.2,-1.01l-0.1,-0.52l-2.4,-0.77l-2.79,0.18l-4.65,-0.09l-0.22,-0.54l1.37,-0.99l0.01,-0.48l-0.82,-0.65l1.91,-1.79l2.57,-5.17l1.49,-1.81l2.04,-1.07l0.63,0.08l-0.27,0.51l-1.33,2.07ZM193.92,74.85l-0.01,4.24l0.19,0.28l0.33,-0.07l3.14,-3.22l2.65,2.5l-0.71,3.04l0.06,0.26l2.42,2.88l0.46,0.0l2.66,-3.14l1.83,-3.74l0.03,-0.12l0.13,-4.53l3.23,0.31l3.63,0.64l3.18,2.08l0.13,1.91l-1.79,2.22l-0.0,0.37l1.69,2.2l-0.28,1.8l-4.74,2.84l-3.33,0.62l-2.5,-1.21l-0.41,0.17l-0.73,2.05l-2.39,3.44l-0.74,1.78l-2.78,2.61l-3.48,0.26l-0.17,0.07l-1.98,1.68l-0.1,0.21l-0.15,2.33l-2.68,0.45l-0.17,0.09l-3.1,3.2l-2.75,4.38l-0.99,3.06l-0.14,4.31l0.25,0.31l3.5,0.58l1.07,3.24l1.18,2.76l0.34,0.18l3.43,-0.69l4.55,1.52l2.45,1.32l1.76,1.65l0.12,0.07l3.11,0.96l2.63,1.46l0.13,0.04l4.12,0.2l2.41,0.3l-0.36,2.81l0.8,3.51l1.81,3.78l0.08,0.1l3.73,3.17l0.34,0.03l1.93,-1.08l0.13,-0.15l1.35,-3.44l0.01,-0.18l-1.31,-5.38l-0.08,-0.14l-1.46,-1.5l3.68,-1.51l2.84,-2.46l1.45,-2.55l0.04,-0.17l-0.2,-2.39l-0.04,-0.12l-1.7,-3.07l-2.9,-2.64l2.79,-3.66l0.05,-0.27l-1.08,-3.38l-0.8,-5.75l1.45,-0.75l4.18,1.03l2.6,0.38l0.18,-0.03l1.93,-0.95l2.18,1.23l3.01,2.18l0.73,1.42l0.25,0.16l4.18,0.27l-0.06,2.95l0.83,4.7l0.22,0.24l2.19,0.55l1.75,2.08l0.38,0.07l3.63,-2.03l0.11,-0.11l2.38,-4.06l1.36,-1.43l1.76,3.01l3.26,4.68l2.68,4.19l-0.94,2.09l0.12,0.38l3.31,1.98l2.23,1.98l0.13,0.07l3.94,0.89l1.48,1.02l0.96,2.82l0.22,0.2l1.85,0.43l0.88,1.13l0.17,3.53l-1.68,1.16l-1.76,1.14l-4.08,1.17l-0.11,0.06l-3.08,2.65l-4.11,0.52l-5.35,-0.69l-3.76,-0.02l-2.62,0.23l-0.2,0.1l-2.05,2.29l-3.13,1.41l-0.11,0.08l-3.6,4.24l-2.87,2.92l-0.05,0.36l0.33,0.14l2.13,-0.52l0.15,-0.08l3.98,-4.15l5.16,-2.63l3.58,-0.31l1.82,1.3l-2.09,1.91l-0.09,0.29l0.8,3.46l0.82,2.37l0.15,0.17l3.25,1.56l0.16,0.03l4.14,-0.45l0.21,-0.12l2.03,-2.86l0.11,1.46l0.13,0.22l1.26,0.88l-2.7,1.78l-5.51,1.83l-2.52,1.26l-2.75,2.16l-1.52,-0.18l-0.08,-2.16l4.19,-2.47l0.14,-0.34l-0.3,-0.22l-4.01,0.1l-2.66,0.36l-1.45,-1.56l0.0,-4.16l-0.11,-0.23l-1.11,-0.91l-0.28,-0.05l-1.5,0.48l-0.7,-0.7l-0.45,0.02l-1.91,2.39l-0.8,2.5l-0.82,1.31l-0.95,0.43l-0.77,0.15l-0.23,0.2l-0.18,0.56l-8.2,0.02l-0.13,0.03l-1.19,0.61l-2.95,2.45l-0.78,1.13l-4.6,0.01l-0.12,0.02l-1.13,0.48l-0.13,0.44l0.37,0.55l0.2,0.82l-0.01,0.09l-3.1,1.42l-2.63,0.5l-2.84,1.57l-0.47,0.0l-0.72,-0.4l-0.18,-0.27l0.03,-0.15l0.52,-1.0l1.2,-1.71l0.73,-1.8l0.02,-0.17l-1.03,-5.47l-0.15,-0.21l-2.35,-1.32l0.16,-0.29l-0.05,-0.35l-0.37,-0.38l-0.22,-0.09l-0.56,0.0l-0.35,-0.34l-0.11,-0.65l-0.46,-0.2l-0.39,0.26l-0.2,-0.03l-0.11,-0.33l-0.48,-0.25l-0.21,-0.71l-0.15,-0.18l-3.97,-2.07l-4.8,-2.39l-0.25,-0.01l-2.19,0.89l-0.72,0.03l-3.04,-0.82l-0.14,-0.0l-1.94,0.4l-2.4,-0.98l-2.56,-0.51l-1.7,-0.19l-0.62,-0.44l-0.42,-1.67l-0.3,-0.23l-0.85,0.02l-0.29,0.3l-0.01,0.95l-69.26,-0.01l-4.77,-3.14l-1.78,-1.41l-4.51,-1.38l-1.3,-2.73l0.34,-1.96l-0.17,-0.33l-3.06,-1.37l-0.41,-2.58l-0.11,-0.18l-2.92,-2.4l-0.05,-1.53l1.32,-1.59l0.07,-0.2l-0.07,-2.21l-0.16,-0.26l-4.19,-2.22l-2.52,-4.02l-1.56,-2.6l-0.08,-0.09l-2.28,-1.64l-1.65,-1.48l-1.31,-1.89l-0.38,-0.1l-2.51,1.21l-2.28,1.92l-2.03,-2.22l-1.85,-1.71l-2.44,-1.04l-2.28,-0.12l0.03,-37.72l4.27,0.98l4.0,2.13l2.61,0.4l0.24,-0.07l2.17,-1.81l2.92,-1.33l3.63,0.53l0.18,-0.03l3.72,-1.94l3.89,-1.06l1.6,1.72l0.37,0.06l1.87,-1.04l0.14,-0.19l0.48,-1.83l1.37,0.38l4.18,3.96l0.41,0.0l2.89,-2.62l0.28,2.79l0.37,0.26l3.08,-0.73l0.17,-0.12l0.85,-1.16l2.81,0.24l3.83,1.86l5.86,1.61l3.46,0.75l2.44,-0.26l2.89,1.89l-3.12,1.89l-0.14,0.31l0.24,0.24l4.53,0.92l6.84,-0.5l2.04,-0.71l2.54,2.44l0.39,0.02l2.72,-2.16l-0.01,-0.48l-2.26,-1.61l1.27,-1.16l2.94,-0.19l1.94,-0.42l1.89,0.97l2.49,2.32l0.24,0.08l2.71,-0.33l4.35,1.9l0.17,0.02l3.86,-0.67l3.62,0.1l0.31,-0.33l-0.26,-2.44l1.9,-0.65l3.58,1.36l-0.01,3.84l0.23,0.29l0.34,-0.17l1.51,-3.23l1.81,0.1l0.31,-0.22l1.13,-4.37l-0.08,-0.29l-2.68,-2.73l-2.83,-1.76l0.19,-4.73l2.77,-3.15l3.06,0.69l2.44,1.97l3.24,4.88l-2.05,2.02l0.15,0.51l4.41,0.85ZM265.85,150.7l-0.84,0.04l-3.15,-0.99l-1.77,-1.17l0.19,-0.06l3.17,0.79l2.39,1.27l0.01,0.12ZM249.41,3.71l6.68,0.49l5.34,0.79l4.34,1.6l-0.08,1.24l-5.91,2.56l-6.03,1.21l-2.36,1.38l-0.14,0.34l0.29,0.22l4.37,-0.02l-4.96,3.01l-4.06,1.64l-0.11,0.08l-4.21,4.62l-5.07,0.92l-0.12,0.05l-1.53,1.1l-7.5,0.59l-0.28,0.28l0.24,0.31l2.67,0.54l-1.04,0.6l-0.09,0.44l1.89,2.49l-2.11,1.66l-3.83,1.52l-0.15,0.13l-1.14,2.01l-3.41,1.55l-0.16,0.36l0.35,1.19l0.3,0.22l3.98,-0.19l0.03,0.78l-6.42,2.99l-6.44,-1.41l-7.41,0.79l-3.72,-0.62l-4.48,-0.26l-0.25,-2.0l4.37,-1.13l0.21,-0.38l-1.14,-3.55l1.13,-0.28l6.61,2.29l0.35,-0.12l-0.04,-0.37l-3.41,-3.45l-0.14,-0.08l-3.57,-0.92l1.62,-1.7l4.36,-1.3l0.2,-0.18l0.71,-1.94l-0.12,-0.36l-3.45,-2.15l-0.88,-2.43l6.36,0.23l1.94,0.61l0.23,-0.02l3.91,-2.1l0.15,-0.32l-0.26,-0.24l-5.69,-0.67l-8.69,0.37l-4.3,-1.92l-2.12,-2.39l-2.82,-1.68l-0.44,-1.65l3.41,-1.06l2.93,-0.2l4.91,-0.99l3.69,-2.28l2.93,0.31l2.64,1.68l0.42,-0.1l1.84,-3.23l3.17,-0.96l4.45,-0.69l7.56,-0.26l1.26,0.64l0.18,0.03l7.2,-1.06l10.81,0.8ZM203.94,57.59l0.01,0.32l1.97,2.97l0.51,-0.01l2.26,-3.75l6.05,-1.89l4.08,4.72l-0.36,2.95l0.38,0.33l4.95,-1.36l0.11,-0.05l2.23,-1.77l5.37,2.31l3.32,2.14l0.3,1.89l0.36,0.25l4.48,-1.01l2.49,2.8l0.14,0.09l5.99,1.78l2.09,1.74l2.18,3.83l-4.29,1.91l-0.01,0.54l5.9,2.83l3.95,0.94l3.54,3.84l0.2,0.1l3.58,0.25l-0.67,2.51l-4.18,4.54l-2.84,-1.61l-3.91,-3.95l-0.26,-0.09l-3.24,0.52l-0.25,0.26l-0.32,2.37l0.1,0.26l2.63,2.38l3.42,1.89l0.96,1.0l1.57,3.8l-0.74,2.43l-2.85,-0.96l-6.26,-3.15l-0.38,0.09l0.04,0.39l3.54,3.4l2.55,2.31l0.23,0.78l-6.26,-1.43l-5.33,-2.25l-2.73,-1.73l0.67,-0.86l-0.09,-0.45l-7.38,-4.01l-0.44,0.27l0.03,0.89l-6.85,0.61l-1.8,-1.17l1.43,-2.6l4.56,-0.07l5.15,-0.52l0.23,-0.45l-0.76,-1.34l0.8,-1.89l3.21,-4.06l0.05,-0.29l-0.72,-1.95l-0.97,-1.47l-0.11,-0.1l-3.84,-2.1l-4.53,-1.33l1.09,-0.75l0.05,-0.45l-2.65,-2.75l-0.18,-0.09l-2.12,-0.24l-1.91,-1.47l-0.39,0.02l-1.27,1.25l-4.4,0.56l-9.06,-0.99l-5.28,-1.31l-4.01,-0.67l-1.72,-1.31l2.32,-1.85l0.1,-0.33l-0.28,-0.2l-3.3,-0.02l-0.74,-4.36l1.86,-4.09l2.46,-1.88l5.74,-1.15l-1.5,2.55ZM261.28,159.28l0.19,0.14l1.82,0.42l1.66,-0.05l-0.66,0.68l-0.75,0.16l-3.0,-1.25l-0.46,-0.77l0.51,-0.52l0.68,1.19ZM230.87,84.48l-2.48,0.19l-0.52,-1.74l0.96,-2.17l2.03,-0.53l1.71,1.04l0.02,1.6l-0.22,0.46l-1.5,1.16ZM229.52,58.19l0.14,0.82l-4.99,-0.22l-2.73,0.63l-0.59,-0.23l-2.61,-2.4l0.08,-1.38l0.94,-0.25l5.61,0.51l4.14,2.54ZM222.12,105.0l-0.79,1.63l-0.75,-0.22l-0.52,-0.91l0.04,-0.09l0.84,-1.01l0.74,0.06l0.44,0.55ZM183.77,38.22l2.72,1.65l0.16,0.04l4.83,-0.01l1.92,1.52l-0.51,1.75l0.18,0.36l2.84,1.14l1.56,1.19l0.16,0.06l3.37,0.22l3.65,0.42l4.07,-1.1l5.05,-0.43l3.96,0.35l2.53,1.8l0.48,1.79l-1.37,1.16l-3.6,1.03l-3.22,-0.59l-7.17,0.76l-5.1,0.09l-4.0,-0.6l-6.48,-1.56l-0.81,-2.57l-0.3,-2.49l-0.1,-0.19l-2.51,-2.25l-0.16,-0.07l-5.12,-0.63l-2.61,-1.45l0.75,-1.71l4.88,0.32ZM207.46,91.26l0.42,1.62l0.42,0.19l1.12,-0.55l1.35,0.99l2.74,1.39l2.73,1.2l0.2,1.74l0.35,0.26l1.72,-0.29l1.31,0.97l-1.72,0.96l-3.68,-0.9l-1.34,-1.71l-0.43,-0.04l-2.46,2.1l-3.23,1.85l-0.74,-1.98l-0.31,-0.19l-2.47,0.28l1.49,-1.34l0.1,-0.19l0.32,-3.15l0.79,-3.45l1.34,0.25ZM215.59,102.66l-2.73,2.0l-1.49,-0.08l-0.37,-0.7l1.61,-1.56l3.0,0.03l-0.02,0.3ZM202.79,24.07l0.11,0.12l2.54,1.53l-3.01,1.47l-4.55,4.07l-4.3,0.38l-5.07,-0.68l-2.51,-2.09l0.03,-1.72l1.86,-1.4l0.1,-0.34l-0.29,-0.2l-4.49,0.04l-2.63,-1.79l-1.45,-2.36l1.61,-2.38l1.65,-1.69l2.47,-0.4l0.19,-0.48l-0.72,-0.89l5.1,-0.26l3.1,3.05l0.13,0.07l4.21,1.25l3.99,1.06l1.92,3.65ZM187.5,59.3l-0.15,0.1l-2.59,3.4l-2.5,-0.15l-1.47,-3.92l0.04,-2.24l1.22,-1.92l2.34,-1.26l5.11,0.17l4.28,1.06l-3.36,3.86l-2.9,0.9ZM186.19,48.8l-1.15,1.63l-3.42,-0.35l-2.68,-1.15l1.11,-1.88l3.34,-1.27l2.01,1.63l0.79,1.38ZM185.78,35.41l-0.95,0.13l-4.48,-0.33l-0.4,-0.91l4.5,0.07l1.45,0.82l-0.1,0.21ZM180.76,32.56l-3.43,1.03l-1.85,-1.14l-1.01,-1.92l-0.16,-1.87l2.87,0.2l1.39,0.35l2.75,1.75l-0.55,1.6ZM181.03,76.32l-1.21,1.2l-3.19,-1.26l-0.18,-0.01l-1.92,0.45l-2.88,-1.67l1.84,-1.16l1.6,-1.77l2.45,1.17l1.45,0.77l2.05,2.28ZM169.72,54.76l2.83,0.97l0.14,0.01l4.25,-0.58l0.47,1.01l-2.19,2.16l0.07,0.48l3.61,1.95l-0.41,3.84l-3.87,1.68l-2.23,-0.36l-1.73,-1.75l-6.07,-3.53l0.03,-1.01l4.79,0.55l0.3,-0.16l-0.04,-0.34l-2.55,-2.89l2.59,-2.05ZM174.44,40.56l1.49,1.87l0.07,2.48l-1.07,3.52l-3.87,0.48l-2.41,-0.72l0.05,-2.72l-0.33,-0.3l-3.79,0.36l-0.13,-3.31l2.36,0.14l0.15,-0.03l3.7,-1.74l3.44,0.29l0.31,-0.22l0.03,-0.12ZM170.14,31.5l0.75,1.74l-3.52,-0.52l-4.19,-1.77l-4.65,-0.17l1.65,-1.11l-0.05,-0.52l-2.86,-1.26l-0.13,-1.58l4.52,0.7l6.66,1.99l1.84,2.5ZM134.64,58.08l-1.08,1.93l0.34,0.44l5.44,-1.41l3.37,2.32l0.37,-0.02l2.66,-2.28l2.03,1.38l2.01,4.53l0.53,0.04l1.26,-1.93l0.03,-0.27l-1.67,-4.55l1.82,-0.58l2.36,0.73l2.69,1.84l1.53,4.46l0.77,3.24l0.15,0.19l4.22,2.26l4.32,2.04l-0.21,1.51l-3.87,0.34l-0.19,0.5l1.45,1.54l-0.65,1.23l-4.3,-0.65l-4.4,-1.19l-2.97,0.28l-4.67,1.48l-6.31,0.65l-4.27,0.39l-1.26,-1.91l-0.15,-0.12l-3.42,-1.2l-0.16,-0.01l-2.05,0.45l-2.66,-3.02l1.2,-0.34l3.82,-0.76l3.58,0.19l3.27,-0.78l0.23,-0.29l-0.24,-0.29l-4.84,-1.06l-5.42,0.35l-3.4,-0.09l-0.97,-1.22l5.39,-1.7l0.21,-0.33l-0.3,-0.25l-3.82,0.06l-3.95,-1.1l1.88,-3.13l1.68,-1.81l6.54,-2.84l2.11,0.77ZM158.85,56.58l-1.82,2.62l-3.38,-2.9l0.49,-0.39l3.17,-0.18l1.54,0.86ZM149.71,42.7l1.0,1.87l0.37,0.14l2.17,-0.83l2.33,0.2l0.38,2.16l-1.38,2.17l-8.33,0.76l-6.34,2.15l-3.51,0.1l-0.22,-1.13l4.98,-2.12l0.17,-0.34l-0.31,-0.23l-11.27,0.6l-3.04,-0.78l3.14,-4.57l2.2,-1.35l6.87,1.7l4.4,3.0l0.14,0.05l4.37,0.39l0.27,-0.48l-3.41,-4.68l1.96,-1.62l2.28,0.53l0.79,2.32ZM145.44,29.83l-2.18,0.77l-3.79,-0.0l0.02,-0.31l2.34,-1.5l1.2,0.23l2.42,0.83ZM144.83,34.5l-4.44,1.46l-3.18,-1.48l1.6,-1.36l3.51,-0.53l3.1,0.75l-0.6,1.16ZM119.02,65.87l-6.17,2.07l-1.19,-1.82l-0.13,-0.11l-5.48,-2.32l0.92,-1.7l1.73,-3.44l2.16,-3.15l-0.02,-0.36l-2.09,-2.56l7.84,-0.71l3.59,1.02l6.32,0.27l2.35,1.37l2.25,1.71l-2.68,1.04l-6.21,3.41l-3.1,3.28l-0.08,0.21l0.0,1.81ZM129.66,35.4l-0.3,3.55l-1.77,1.67l-2.34,0.27l-4.62,2.2l-3.89,0.76l-2.83,-0.93l3.85,-3.52l5.04,-3.36l3.75,0.07l3.11,-0.7ZM111.24,152.74l-0.82,0.29l-3.92,-1.39l-0.7,-1.06l-0.12,-0.1l-2.15,-1.09l-0.41,-0.84l-0.2,-0.16l-2.44,-0.56l-0.84,-1.56l0.1,-0.36l2.34,0.64l1.53,0.5l2.28,0.34l0.78,1.04l1.24,1.55l0.09,0.08l2.42,1.3l0.81,1.39ZM88.54,134.82l0.14,0.02l2.0,-0.23l-0.67,3.48l0.06,0.24l1.78,2.22l-0.24,-0.0l-1.4,-1.42l-0.91,-1.53l-1.26,-1.08l-0.42,-1.35l0.09,-0.66l0.82,0.31Z\", \"name\": \"Canada\"}, \"CG\": {\"path\": \"M453.66,296.61l-0.9,-0.82l-0.35,-0.04l-0.83,0.48l-0.77,0.83l-1.65,-2.13l1.66,-1.2l0.08,-0.39l-0.81,-1.43l0.59,-0.43l1.62,-0.29l0.24,-0.24l0.1,-0.58l0.94,0.84l0.19,0.08l2.21,0.11l0.27,-0.14l0.81,-1.29l0.32,-1.76l-0.27,-1.96l-0.06,-0.15l-1.08,-1.35l1.02,-2.74l-0.09,-0.34l-0.62,-0.5l-0.22,-0.06l-1.66,0.18l-0.55,-1.03l0.12,-0.73l2.85,0.09l1.98,0.65l2.0,0.59l0.38,-0.25l0.17,-1.3l1.26,-2.24l1.34,-1.19l1.54,0.38l1.35,0.12l-0.11,1.15l-0.74,1.34l-0.5,1.61l-0.31,2.22l0.12,1.41l-0.4,0.9l-0.06,0.88l-0.24,0.67l-1.57,1.15l-1.24,1.41l-1.09,2.43l-0.03,0.13l0.08,1.95l-0.55,0.69l-1.46,1.23l-1.32,1.41l-0.61,-0.29l-0.13,-0.57l-0.29,-0.23l-1.36,-0.02l-0.23,0.1l-0.72,0.81l-0.41,-0.16Z\", \"name\": \"Republic of the Congo\"}, \"CF\": {\"path\": \"M459.41,266.56l1.9,-0.17l0.22,-0.12l0.36,-0.5l0.14,0.02l0.55,0.51l0.29,0.07l3.15,-0.96l0.12,-0.07l1.05,-0.97l1.29,-0.87l0.12,-0.33l-0.17,-0.61l0.38,-0.12l2.36,0.15l0.15,-0.03l2.36,-1.17l0.12,-0.1l1.78,-2.72l1.18,-0.96l1.23,-0.34l0.21,0.79l0.07,0.13l1.37,1.5l0.01,0.86l-0.39,1.0l-0.01,0.17l0.16,0.78l0.1,0.17l0.91,0.76l1.89,1.09l1.24,0.92l0.02,0.67l0.12,0.23l1.67,1.3l0.99,1.03l0.61,1.46l0.14,0.15l1.79,0.95l0.2,0.4l-0.44,0.14l-1.54,-0.06l-1.98,-0.26l-0.93,0.22l-0.19,0.14l-0.3,0.48l-0.57,0.05l-0.91,-0.49l-0.26,-0.01l-2.7,1.21l-1.04,-0.23l-0.21,0.03l-0.34,0.19l-0.12,0.13l-0.64,1.3l-1.67,-0.43l-1.77,-0.24l-1.58,-0.91l-2.06,-0.85l-0.27,0.02l-1.42,0.88l-0.97,1.27l-0.06,0.14l-0.19,1.46l-1.3,-0.11l-1.67,-0.42l-0.27,0.07l-1.55,1.41l-0.99,1.76l-0.14,-1.18l-0.13,-0.22l-1.1,-0.78l-0.86,-1.2l-0.2,-0.84l-0.07,-0.13l-1.07,-1.19l0.16,-0.59l0.0,-0.15l-0.24,-1.01l0.18,-1.77l0.5,-0.38l0.09,-0.11l1.18,-2.4Z\", \"name\": \"Central African Republic\"}, \"CD\": {\"path\": \"M497.85,276.25l-0.14,2.77l0.2,0.3l0.57,0.19l-0.47,0.52l-1.0,0.71l-0.96,1.31l-0.56,1.22l-0.16,2.04l-0.54,0.89l-0.04,0.15l-0.02,1.76l-0.63,0.61l-0.09,0.2l-0.08,1.33l-0.2,0.11l-0.15,0.21l-0.23,1.37l0.03,0.2l0.6,1.08l0.16,2.96l0.44,2.29l-0.24,1.25l0.01,0.15l0.5,1.46l0.07,0.12l1.41,1.37l1.09,2.56l-0.51,-0.11l-3.45,0.45l-0.67,0.3l-0.15,0.15l-0.71,1.61l0.01,0.26l0.52,1.03l-0.43,2.9l-0.31,2.55l0.13,0.29l0.7,0.46l1.75,0.99l0.31,-0.01l0.26,-0.17l0.15,1.9l-1.44,-0.02l-0.94,-1.28l-0.94,-1.1l-0.17,-0.1l-1.76,-0.33l-0.5,-1.18l-0.42,-0.15l-1.44,0.75l-1.79,-0.32l-0.77,-1.05l-0.2,-0.12l-1.59,-0.23l-0.97,0.04l-0.1,-0.53l-0.27,-0.25l-0.86,-0.06l-1.13,-0.15l-1.62,0.37l-1.04,-0.06l-0.32,0.09l0.11,-2.56l-0.08,-0.21l-0.77,-0.87l-0.17,-1.41l0.36,-1.47l-0.03,-0.21l-0.48,-0.91l-0.04,-1.52l-0.3,-0.29l-2.65,0.02l0.13,-0.53l-0.29,-0.37l-1.28,0.01l-0.28,0.21l-0.07,0.24l-1.35,0.09l-0.26,0.18l-0.62,1.45l-0.25,0.42l-1.17,-0.3l-0.19,0.01l-0.79,0.34l-1.44,0.18l-1.41,-1.96l-0.7,-1.47l-0.61,-1.86l-0.28,-0.21l-7.39,-0.03l-0.92,0.3l-0.78,-0.03l-0.78,0.25l-0.11,-0.25l0.35,-0.15l0.18,-0.26l0.07,-1.02l0.33,-0.52l0.72,-0.42l0.52,0.2l0.33,-0.08l0.76,-0.86l0.99,0.02l0.11,0.48l0.16,0.2l0.94,0.44l0.35,-0.07l1.46,-1.56l1.44,-1.21l0.68,-0.85l0.06,-0.2l-0.08,-1.99l1.04,-2.33l1.1,-1.23l1.62,-1.19l0.11,-0.14l0.29,-0.8l0.08,-0.94l0.38,-0.82l0.03,-0.16l-0.13,-1.38l0.3,-2.16l0.47,-1.51l0.73,-1.31l0.04,-0.12l0.15,-1.51l0.21,-1.66l0.89,-1.16l1.16,-0.7l1.9,0.79l1.69,0.95l1.81,0.24l1.85,0.48l0.35,-0.16l0.71,-1.43l0.16,-0.09l1.03,0.23l0.19,-0.02l2.65,-1.19l0.86,0.46l0.17,0.03l0.81,-0.08l0.23,-0.14l0.31,-0.5l0.75,-0.17l1.83,0.26l1.64,0.06l0.72,-0.21l1.39,1.9l0.16,0.11l1.12,0.3l0.24,-0.04l0.58,-0.36l1.05,0.15l0.15,-0.02l1.15,-0.44l0.47,0.84l0.08,0.09l2.08,1.57Z\", \"name\": \"Democratic Republic of the Congo\"}, \"CZ\": {\"path\": \"M463.29,152.22l-0.88,-0.47l-0.18,-0.03l-1.08,0.15l-1.86,-0.94l-0.21,-0.02l-0.88,0.24l-0.13,0.07l-1.25,1.17l-1.63,-0.91l-1.38,-1.36l-1.22,-0.75l-0.24,-1.24l-0.33,-0.75l1.53,-0.6l0.98,-0.84l1.74,-0.62l0.11,-0.07l0.47,-0.47l0.46,0.27l0.24,0.03l0.96,-0.3l1.06,0.95l0.15,0.07l1.57,0.24l-0.1,0.6l0.16,0.32l1.36,0.68l0.41,-0.15l0.28,-0.62l1.29,0.28l0.19,0.84l0.26,0.23l1.73,0.18l0.74,1.02l-0.17,0.0l-0.25,0.13l-0.32,0.49l-0.46,0.11l-0.22,0.23l-0.13,0.57l-0.32,0.1l-0.2,0.22l-0.03,0.14l-0.65,0.25l-1.05,-0.05l-0.28,0.17l-0.22,0.43Z\", \"name\": \"Czech Republic\"}, \"CY\": {\"path\": \"M505.03,193.75l-1.51,0.68l-1.0,-0.3l-0.32,-0.63l0.69,-0.06l0.41,0.13l0.19,-0.0l0.62,-0.22l0.31,0.02l0.06,0.22l0.49,0.17l0.06,-0.01Z\", \"name\": \"Cyprus\"}, \"CR\": {\"path\": \"M213.0,263.84l-0.98,-0.4l-0.3,-0.31l0.16,-0.24l0.05,-0.21l-0.09,-0.56l-0.1,-0.18l-0.76,-0.65l-0.99,-0.5l-0.74,-0.28l-0.13,-0.58l-0.12,-0.18l-0.66,-0.45l-0.34,-0.0l-0.13,0.31l0.13,0.59l-0.17,0.21l-0.34,-0.42l-0.14,-0.1l-0.7,-0.22l-0.23,-0.34l0.01,-0.62l0.31,-0.74l-0.14,-0.38l-0.3,-0.15l0.47,-0.4l1.48,0.6l0.26,-0.02l0.47,-0.27l0.58,0.15l0.35,0.44l0.17,0.11l0.74,0.17l0.27,-0.07l0.3,-0.27l0.52,1.09l0.97,1.02l0.77,0.71l-0.41,0.1l-0.23,0.3l0.01,1.02l0.12,0.24l0.2,0.14l-0.07,0.05l-0.11,0.3l0.08,0.37l-0.23,0.63Z\", \"name\": \"Costa Rica\"}, \"CU\": {\"path\": \"M215.01,226.09l2.08,0.18l1.94,0.03l2.24,0.86l0.95,0.92l0.25,0.08l2.22,-0.28l0.79,0.55l3.68,2.81l0.19,0.06l0.77,-0.03l1.18,0.42l-0.12,0.47l0.27,0.37l1.78,0.1l1.59,0.9l-0.11,0.22l-1.5,0.3l-1.64,0.13l-1.75,-0.2l-2.69,0.19l1.0,-0.86l-0.03,-0.48l-1.02,-0.68l-0.13,-0.05l-1.52,-0.16l-0.74,-0.64l-0.57,-1.42l-0.3,-0.19l-1.36,0.1l-2.23,-0.67l-0.71,-0.52l-0.14,-0.06l-3.2,-0.4l-0.42,-0.25l0.56,-0.39l0.12,-0.33l-0.27,-0.22l-2.46,-0.13l-0.2,0.06l-1.72,1.31l-0.94,0.03l-0.25,0.15l-0.29,0.53l-1.04,0.24l-0.29,-0.07l0.7,-0.43l0.1,-0.11l0.5,-0.87l1.04,-0.54l1.23,-0.49l1.86,-0.25l0.62,-0.28Z\", \"name\": \"Cuba\"}, \"SZ\": {\"path\": \"M500.95,353.41l-0.41,0.97l-1.16,0.23l-1.29,-1.26l-0.02,-0.71l0.63,-0.93l0.23,-0.7l0.47,-0.12l1.04,0.4l0.32,1.05l0.2,1.08Z\", \"name\": \"Swaziland\"}, \"SY\": {\"path\": \"M510.84,199.83l0.09,-0.11l0.07,-0.2l-0.04,-1.08l0.56,-1.4l1.3,-1.01l0.1,-0.34l-0.41,-1.11l-0.24,-0.19l-0.89,-0.11l-0.2,-1.84l0.55,-1.05l1.3,-1.22l0.09,-0.19l0.09,-1.09l0.39,0.27l0.25,0.04l2.66,-0.77l1.35,0.52l2.06,-0.01l2.93,-1.08l1.35,0.04l2.14,-0.34l-0.83,1.16l-1.31,0.68l-0.16,0.3l0.23,2.03l-0.9,3.25l-5.43,2.87l-4.79,2.91l-2.32,-0.92Z\", \"name\": \"Syria\"}, \"KG\": {\"path\": \"M599.04,172.15l0.38,-0.9l1.43,-0.37l4.04,1.02l0.37,-0.23l0.36,-1.64l1.17,-0.52l3.45,1.24l0.2,-0.0l0.86,-0.31l4.09,0.08l3.61,0.31l1.18,1.02l0.11,0.06l1.19,0.34l-0.13,0.26l-3.84,1.58l-0.13,0.1l-0.81,1.08l-3.08,0.34l-0.24,0.16l-0.85,1.7l-2.43,-0.37l-0.14,0.01l-1.79,0.61l-2.39,1.4l-0.12,0.39l0.25,0.49l-0.48,0.45l-4.57,0.43l-3.04,-0.94l-2.45,0.18l0.14,-1.02l2.42,0.44l0.27,-0.08l0.81,-0.81l1.76,0.27l0.21,-0.05l3.21,-2.14l-0.03,-0.51l-2.97,-1.57l-0.26,-0.01l-1.64,0.69l-1.38,-0.84l1.81,-1.67l-0.09,-0.5l-0.46,-0.18Z\", \"name\": \"Kyrgyzstan\"}, \"KE\": {\"path\": \"M523.3,287.04l0.06,0.17l1.29,1.8l-1.46,0.84l-0.11,0.11l-0.55,0.93l-0.81,0.16l-0.24,0.24l-0.34,1.69l-0.81,1.06l-0.46,1.58l-0.76,0.63l-3.3,-2.3l-0.16,-1.32l-0.15,-0.23l-9.35,-5.28l-0.02,-2.4l1.92,-2.63l0.91,-1.83l0.01,-0.24l-1.09,-2.86l-0.29,-1.24l-1.09,-1.63l2.93,-2.85l0.92,0.3l0.0,1.19l0.09,0.22l0.86,0.83l0.21,0.08l1.65,0.0l3.09,2.08l0.16,0.05l0.79,0.03l0.54,-0.06l0.58,0.28l1.67,0.2l0.28,-0.12l0.69,-0.98l2.04,-0.94l0.86,0.73l0.19,0.07l1.1,0.0l-1.82,2.36l-0.06,0.18l0.03,9.12Z\", \"name\": \"Kenya\"}, \"SS\": {\"path\": \"M505.7,261.39l0.02,1.64l-0.27,0.55l-1.15,0.05l-0.24,0.15l-0.85,1.44l0.22,0.45l1.44,0.17l1.15,1.12l0.42,0.95l0.14,0.15l1.06,0.54l1.33,2.45l-3.06,2.98l-1.44,1.08l-1.75,0.01l-1.92,0.56l-1.5,-0.53l-0.27,0.03l-0.85,0.57l-1.98,-1.5l-0.56,-1.02l-0.37,-0.13l-1.32,0.5l-1.08,-0.15l-0.2,0.04l-0.56,0.35l-0.9,-0.24l-1.44,-1.97l-0.39,-0.77l-0.13,-0.13l-1.78,-0.94l-0.65,-1.5l-1.08,-1.12l-1.57,-1.22l-0.02,-0.68l-0.12,-0.23l-1.37,-1.02l-1.17,-0.68l0.2,-0.08l0.86,-0.48l0.14,-0.18l0.63,-2.22l0.6,-1.02l1.47,-0.28l0.35,0.56l1.29,1.48l0.14,0.09l0.69,0.22l0.22,-0.02l0.83,-0.4l1.58,0.08l0.26,0.39l0.25,0.13l2.49,0.0l0.3,-0.25l0.06,-0.35l1.13,-0.42l0.18,-0.18l0.22,-0.63l0.68,-0.38l1.95,1.37l0.23,0.05l1.29,-0.26l0.19,-0.12l1.23,-1.8l1.36,-1.37l0.08,-0.25l-0.21,-1.52l-0.06,-0.15l-0.25,-0.3l0.94,-0.08l0.26,-0.21l0.1,-0.32l0.6,0.09l-0.25,1.67l0.3,1.83l0.11,0.19l1.22,0.94l0.25,0.73l-0.04,1.2l0.26,0.31l0.09,0.01Z\", \"name\": \"South Sudan\"}, \"SR\": {\"path\": \"M278.1,270.26l2.71,0.45l0.31,-0.14l0.19,-0.32l1.82,-0.16l2.25,0.56l-1.09,1.81l-0.04,0.19l0.2,1.72l0.05,0.13l0.9,1.35l-0.39,0.99l-0.21,1.09l-0.48,0.8l-1.2,-0.44l-0.17,-0.01l-1.12,0.24l-0.95,-0.21l-0.35,0.2l-0.25,0.73l0.05,0.29l0.3,0.35l-0.06,0.13l-1.01,-0.15l-1.42,-2.03l-0.32,-1.36l-0.29,-0.23l-0.63,-0.0l-0.95,-1.56l0.41,-1.16l0.01,-0.17l-0.08,-0.35l1.29,-0.56l0.18,-0.22l0.35,-1.97Z\", \"name\": \"Suriname\"}, \"KH\": {\"path\": \"M680.28,257.89l-0.93,-1.2l-1.24,-2.56l-0.56,-2.9l1.45,-1.92l3.07,-0.46l2.26,0.35l2.03,0.98l0.38,-0.11l1.0,-1.55l1.86,0.79l0.52,1.51l-0.28,2.82l-4.05,1.88l-0.12,0.45l0.79,1.1l-2.2,0.17l-2.08,0.98l-1.89,-0.33Z\", \"name\": \"Cambodia\"}, \"SV\": {\"path\": \"M197.02,248.89l0.18,-0.05l0.59,0.17l0.55,0.51l0.64,0.35l0.06,0.22l0.37,0.21l1.01,-0.28l0.38,0.13l0.16,0.13l-0.14,0.81l-0.18,0.38l-1.22,-0.03l-0.84,-0.23l-1.11,-0.52l-1.31,-0.15l-0.49,-0.38l0.02,-0.08l0.76,-0.57l0.46,-0.27l0.11,-0.35Z\", \"name\": \"El Salvador\"}, \"SK\": {\"path\": \"M468.01,150.02l0.05,0.07l0.36,0.1l0.85,-0.37l1.12,1.02l0.33,0.05l1.38,-0.65l1.07,0.3l0.16,0.0l1.69,-0.43l1.95,1.02l-0.51,0.64l-0.45,1.2l-0.32,0.2l-2.55,-0.93l-0.17,-0.01l-0.82,0.2l-0.17,0.11l-0.53,0.68l-0.94,0.32l-0.14,-0.11l-0.29,-0.04l-1.18,0.48l-0.95,0.09l-0.26,0.21l-0.15,0.47l-1.84,0.34l-0.82,-0.31l-1.14,-0.73l-0.2,-0.89l0.42,-0.84l0.91,0.05l0.12,-0.02l0.86,-0.33l0.18,-0.21l0.03,-0.13l0.32,-0.1l0.2,-0.22l0.12,-0.55l0.39,-0.1l0.18,-0.13l0.3,-0.45l0.43,-0.0Z\", \"name\": \"Slovakia\"}, \"KR\": {\"path\": \"M737.31,185.72l0.84,0.08l0.27,-0.12l0.89,-1.2l1.63,-0.13l1.1,-0.2l0.21,-0.16l0.12,-0.24l1.86,2.95l0.59,1.79l0.02,3.17l-0.84,1.38l-2.23,0.55l-1.95,1.14l-1.91,0.21l-0.22,-1.21l0.45,-2.07l-0.01,-0.17l-0.99,-2.67l1.54,-0.4l0.17,-0.46l-1.55,-2.24Z\", \"name\": \"South Korea\"}, \"SI\": {\"path\": \"M455.77,159.59l1.79,0.21l0.18,-0.04l1.2,-0.68l2.12,-0.08l0.21,-0.1l0.38,-0.42l0.1,0.01l0.28,0.62l-1.71,0.71l-0.18,0.22l-0.21,1.1l-0.71,0.26l-0.2,0.28l0.01,0.55l-0.59,-0.04l-0.79,-0.47l-0.38,0.06l-0.36,0.41l-0.84,-0.05l0.05,-0.15l-0.56,-1.24l0.21,-1.17Z\", \"name\": \"Slovenia\"}, \"KP\": {\"path\": \"M747.76,172.02l-0.23,-0.04l-0.26,0.08l-1.09,1.02l-0.78,1.06l-0.06,0.19l0.09,1.95l-1.12,0.57l-0.53,0.58l-0.88,0.82l-1.69,0.51l-1.09,0.79l-0.12,0.22l-0.07,1.17l-0.22,0.25l0.09,0.47l0.96,0.46l1.22,1.1l-0.19,0.37l-0.91,0.16l-1.75,0.14l-0.22,0.12l-0.87,1.18l-0.95,-0.09l-0.3,0.18l-0.97,-0.44l-0.39,0.13l-0.25,0.44l-0.29,0.09l-0.03,-0.2l-0.18,-0.23l-0.62,-0.25l-0.43,-0.29l0.52,-0.97l0.52,-0.3l0.13,-0.38l-0.18,-0.42l0.59,-1.47l0.01,-0.21l-0.16,-0.48l-0.22,-0.2l-1.41,-0.31l-0.82,-0.55l1.74,-1.62l2.73,-1.58l1.62,-1.96l0.96,0.76l0.17,0.06l2.17,0.11l0.31,-0.37l-0.32,-1.31l3.61,-1.21l0.16,-0.13l0.79,-1.34l1.25,1.38Z\", \"name\": \"North Korea\"}, \"SO\": {\"path\": \"M543.8,256.48l0.61,-0.05l1.14,-0.37l1.31,-0.25l0.12,-0.05l1.11,-0.81l0.57,-0.0l0.03,0.39l-0.23,1.49l0.01,1.25l-0.52,0.92l-0.7,2.71l-1.19,2.79l-1.54,3.2l-2.13,3.66l-2.12,2.79l-2.92,3.39l-2.47,2.0l-3.76,2.5l-2.33,1.9l-2.77,3.06l-0.61,1.35l-0.28,0.29l-1.22,-1.69l-0.03,-8.92l2.12,-2.76l0.59,-0.68l1.47,-0.04l0.18,-0.06l2.15,-1.71l3.16,-0.11l0.21,-0.09l7.08,-7.55l1.76,-2.12l1.14,-1.57l0.06,-0.18l0.01,-4.67Z\", \"name\": \"Somalia\"}, \"SN\": {\"path\": \"M379.28,250.34l-0.95,-1.82l-0.09,-0.1l-0.83,-0.6l0.62,-0.28l0.13,-0.11l1.21,-1.8l0.6,-1.31l0.71,-0.68l1.09,0.2l0.18,-0.02l1.17,-0.53l1.25,-0.03l1.17,0.73l1.59,0.65l1.47,1.83l1.59,1.7l0.12,1.56l0.49,1.46l0.1,0.14l0.85,0.65l0.18,0.82l-0.08,0.57l-0.13,0.05l-1.29,-0.19l-0.29,0.13l-0.11,0.16l-0.35,0.04l-1.83,-0.61l-5.84,-0.13l-0.12,0.02l-0.6,0.26l-0.87,-0.06l-1.01,0.32l-0.26,-1.26l1.9,0.04l0.16,-0.04l0.54,-0.32l0.37,-0.02l0.15,-0.05l0.78,-0.5l0.92,0.46l0.12,0.03l1.09,0.04l0.15,-0.03l1.08,-0.57l0.11,-0.44l-0.51,-0.74l-0.39,-0.1l-0.76,0.39l-0.62,-0.01l-0.92,-0.58l-0.18,-0.05l-0.79,0.04l-0.2,0.09l-0.48,0.51l-2.41,0.06Z\", \"name\": \"Senegal\"}, \"SL\": {\"path\": \"M392.19,267.53l-0.44,-0.12l-1.73,-0.97l-1.24,-1.28l-0.4,-0.84l-0.27,-1.65l1.21,-1.0l0.09,-0.12l0.27,-0.66l0.32,-0.41l0.56,-0.05l0.16,-0.07l0.5,-0.41l1.75,0.0l0.59,0.77l0.49,0.96l-0.07,0.64l0.04,0.19l0.36,0.58l-0.03,0.84l0.24,0.2l-0.64,0.65l-1.13,1.37l-0.06,0.14l-0.12,0.66l-0.43,0.58Z\", \"name\": \"Sierra Leone\"}, \"SB\": {\"path\": \"M826.74,311.51l0.23,0.29l-0.95,-0.01l-0.39,-0.63l0.65,0.27l0.45,0.09ZM825.01,308.52l-1.18,-1.39l-0.37,-1.06l0.24,0.0l0.82,1.84l0.49,0.6ZM823.21,309.42l-0.44,0.03l-1.43,-0.24l-0.32,-0.24l0.08,-0.5l1.29,0.31l0.72,0.47l0.11,0.18ZM817.9,303.81l2.59,1.44l0.3,0.41l-1.21,-0.66l-1.34,-0.89l-0.34,-0.3ZM813.77,302.4l0.48,0.34l0.1,0.08l-0.33,-0.17l-0.25,-0.25Z\", \"name\": \"Solomon Islands\"}, \"SA\": {\"path\": \"M528.24,243.1l-0.2,-0.69l-0.07,-0.12l-0.69,-0.71l-0.18,-0.94l-0.12,-0.19l-1.24,-0.89l-1.28,-2.09l-0.7,-2.08l-0.07,-0.11l-1.73,-1.79l-0.11,-0.07l-1.03,-0.39l-1.57,-2.36l-0.27,-1.72l0.1,-1.53l-0.03,-0.15l-1.44,-2.93l-1.25,-1.13l-1.34,-0.56l-0.72,-1.33l0.11,-0.49l-0.02,-0.2l-0.7,-1.38l-0.08,-0.1l-0.68,-0.56l-0.97,-1.98l-2.8,-4.03l-0.25,-0.13l-0.85,0.01l0.29,-1.11l0.12,-0.97l0.23,-0.81l2.52,0.39l0.23,-0.06l1.08,-0.84l0.6,-0.95l1.78,-0.35l0.22,-0.17l0.37,-0.83l0.74,-0.42l0.08,-0.46l-2.17,-2.4l4.55,-1.26l0.12,-0.06l0.36,-0.32l2.83,0.71l3.67,1.91l7.04,5.5l0.17,0.06l4.64,0.22l2.06,0.24l0.55,1.15l0.28,0.17l1.56,-0.06l0.9,2.15l0.14,0.15l1.14,0.57l0.39,0.85l0.11,0.13l1.59,1.06l0.12,0.91l-0.23,0.83l0.01,0.18l0.32,0.9l0.07,0.11l0.68,0.7l0.33,0.86l0.37,0.65l0.09,0.1l0.76,0.53l0.25,0.04l0.45,-0.12l0.35,0.75l0.1,0.63l0.96,2.68l0.23,0.19l7.53,1.33l0.27,-0.09l0.24,-0.26l0.87,1.41l-1.58,4.96l-7.34,2.54l-7.28,1.02l-2.34,1.17l-0.12,0.1l-1.74,2.63l-0.86,0.32l-0.49,-0.68l-0.28,-0.12l-0.92,0.12l-2.32,-0.25l-0.41,-0.23l-0.15,-0.04l-2.89,0.06l-0.63,0.2l-0.91,-0.59l-0.43,0.11l-0.66,1.27l-0.03,0.21l0.21,0.89l-0.6,0.45Z\", \"name\": \"Saudi Arabia\"}, \"SE\": {\"path\": \"M476.42,90.44l-0.15,0.1l-2.43,2.86l-0.07,0.24l0.36,2.31l-3.84,3.1l-4.83,3.38l-0.11,0.15l-1.82,5.45l0.03,0.26l1.78,2.68l2.27,1.99l-2.13,3.88l-2.49,0.82l-0.2,0.24l-0.95,6.05l-1.32,3.09l-2.82,-0.32l-0.3,0.16l-1.34,2.64l-2.48,0.14l-0.76,-3.15l-2.09,-4.04l-1.85,-5.01l1.03,-1.98l2.06,-2.53l0.06,-0.13l0.83,-4.45l-0.06,-0.25l-1.54,-1.86l-0.15,-5.0l1.52,-3.48l2.28,0.06l0.27,-0.16l0.87,-1.59l-0.01,-0.31l-0.8,-1.21l3.79,-5.63l4.07,-7.54l2.23,0.01l0.29,-0.22l0.59,-2.15l4.46,0.66l0.34,-0.26l0.34,-2.64l1.21,-0.14l3.24,2.08l3.78,2.85l0.06,6.37l0.03,0.14l0.67,1.29l-3.95,1.07Z\", \"name\": \"Sweden\"}, \"SD\": {\"path\": \"M505.98,259.75l-0.31,-0.9l-0.1,-0.14l-1.2,-0.93l-0.27,-1.66l0.29,-1.83l-0.25,-0.34l-1.16,-0.17l-0.33,0.21l-0.11,0.37l-1.3,0.11l-0.21,0.49l0.55,0.68l0.18,1.29l-1.31,1.33l-1.18,1.72l-1.04,0.21l-2.0,-1.4l-0.32,-0.02l-0.95,0.52l-0.14,0.16l-0.21,0.6l-1.16,0.43l-0.19,0.23l-0.04,0.27l-2.08,0.0l-0.25,-0.39l-0.24,-0.13l-1.81,-0.09l-0.14,0.03l-0.8,0.38l-0.49,-0.16l-1.22,-1.39l-0.42,-0.67l-0.31,-0.14l-1.81,0.35l-0.2,0.14l-0.72,1.24l-0.61,2.14l-0.73,0.4l-0.62,0.22l-0.83,-0.68l-0.12,-0.6l0.38,-0.97l0.01,-1.14l-0.08,-0.2l-1.39,-1.53l-0.25,-0.97l0.03,-0.57l-0.11,-0.25l-0.81,-0.66l-0.03,-1.34l-0.04,-0.14l-0.52,-0.98l-0.31,-0.15l-0.42,0.07l0.12,-0.44l0.63,-1.03l0.03,-0.23l-0.24,-0.88l0.69,-0.66l0.02,-0.41l-0.4,-0.46l0.58,-1.39l1.04,-1.71l1.97,0.16l0.32,-0.3l-0.12,-10.24l0.02,-0.8l2.59,-0.01l0.3,-0.3l0.0,-4.92l29.19,0.0l0.68,2.17l-0.4,0.35l-0.1,0.27l0.36,2.69l0.93,3.15l0.12,0.16l2.05,1.4l-0.99,1.15l-1.75,0.4l-0.15,0.08l-0.79,0.79l-0.08,0.17l-0.24,1.69l-1.07,3.75l-0.0,0.16l0.25,0.96l-0.38,2.1l-0.98,2.41l-1.52,1.3l-1.07,1.94l-0.25,0.99l-1.08,0.64l-0.13,0.18l-0.46,1.65Z\", \"name\": \"Sudan\"}, \"DO\": {\"path\": \"M241.7,234.97l0.15,-0.22l1.73,0.01l1.43,0.64l0.15,0.03l0.45,-0.04l0.36,0.74l0.28,0.17l1.02,-0.04l-0.04,0.43l0.27,0.33l1.03,0.09l0.91,0.7l-0.57,0.64l-0.99,-0.47l-0.16,-0.03l-1.11,0.11l-0.79,-0.12l-0.26,0.09l-0.38,0.4l-0.66,0.11l-0.28,-0.45l-0.38,-0.12l-0.83,0.37l-0.14,0.13l-0.85,1.49l-0.27,-0.17l-0.1,-0.58l0.05,-0.67l-0.07,-0.21l-0.44,-0.53l0.35,-0.25l0.12,-0.19l0.19,-1.0l-0.2,-1.4Z\", \"name\": \"Dominican Republic\"}, \"DJ\": {\"path\": \"M528.78,253.36l0.34,0.45l-0.06,0.76l-1.26,0.54l-0.05,0.53l0.82,0.53l-0.57,0.83l-0.3,-0.25l-0.27,-0.05l-0.56,0.17l-1.07,-0.03l-0.04,-0.56l-0.16,-0.56l0.76,-1.07l0.76,-0.97l0.89,0.18l0.25,-0.06l0.51,-0.42Z\", \"name\": \"Djibouti\"}, \"DK\": {\"path\": \"M452.4,129.07l-1.27,2.39l-2.25,-1.69l-0.26,-1.08l3.15,-1.0l0.63,1.39ZM447.87,126.25l-0.35,0.76l-0.47,-0.24l-0.38,0.09l-1.8,2.53l-0.03,0.29l0.56,1.4l-1.22,0.4l-1.68,-0.41l-0.92,-1.76l-0.07,-3.47l0.38,-0.88l0.62,-0.93l2.07,-0.21l0.19,-0.1l0.84,-0.95l1.5,-0.76l-0.06,1.26l-0.7,1.1l-0.03,0.25l0.3,1.0l0.18,0.19l1.06,0.42Z\", \"name\": \"Denmark\"}, \"DE\": {\"path\": \"M445.51,131.69l0.03,0.94l0.21,0.28l2.32,0.74l-0.02,1.0l0.37,0.3l2.55,-0.65l1.36,-0.89l2.63,1.27l1.09,1.01l0.51,1.51l-0.6,0.78l-0.0,0.36l0.88,1.17l0.58,1.68l-0.18,1.08l0.03,0.18l0.87,1.81l-0.66,0.2l-0.55,-0.32l-0.36,0.05l-0.58,0.58l-1.73,0.62l-0.99,0.84l-1.77,0.7l-0.16,0.4l0.42,0.94l0.26,1.34l0.14,0.2l1.25,0.76l1.22,1.2l-0.71,1.2l-0.81,0.37l-0.17,0.32l0.34,1.99l-0.04,0.09l-0.47,-0.39l-0.17,-0.07l-1.2,-0.1l-1.85,0.57l-2.15,-0.13l-0.29,0.18l-0.21,0.5l-0.96,-0.67l-0.24,-0.05l-0.67,0.16l-2.6,-0.94l-0.34,0.1l-0.42,0.57l-1.64,-0.02l0.26,-1.88l1.24,-2.15l-0.21,-0.45l-3.54,-0.58l-0.98,-0.71l0.12,-1.26l-0.05,-0.2l-0.44,-0.64l0.27,-2.18l-0.38,-3.14l1.17,-0.0l0.27,-0.17l0.63,-1.26l0.65,-3.17l-0.02,-0.17l-0.41,-1.0l0.32,-0.47l1.77,-0.16l0.37,0.6l0.47,0.06l1.7,-1.69l0.06,-0.33l-0.55,-1.24l-0.09,-1.51l1.5,0.36l0.16,-0.01l1.22,-0.4Z\", \"name\": \"Germany\"}, \"YE\": {\"path\": \"M553.53,242.65l-1.51,0.58l-0.17,0.16l-0.48,1.14l-0.07,0.79l-2.31,1.0l-3.98,1.19l-2.28,1.8l-0.97,0.12l-0.7,-0.14l-0.23,0.05l-1.42,1.03l-1.51,0.47l-2.07,0.13l-0.68,0.15l-0.17,0.1l-0.49,0.6l-0.57,0.16l-0.18,0.13l-0.3,0.49l-1.06,-0.05l-0.13,0.02l-0.73,0.32l-1.48,-0.11l-0.55,-1.26l0.07,-1.32l-0.04,-0.16l-0.39,-0.72l-0.48,-1.85l-0.52,-0.79l0.08,-0.02l0.22,-0.36l-0.23,-1.05l0.24,-0.39l0.04,-0.19l-0.09,-0.95l0.96,-0.72l0.11,-0.31l-0.23,-0.98l0.46,-0.88l0.75,0.49l0.26,0.03l0.63,-0.22l2.76,-0.06l0.5,0.25l2.42,0.26l0.85,-0.11l0.52,0.71l0.35,0.1l1.17,-0.43l0.15,-0.12l1.75,-2.64l2.22,-1.11l6.95,-0.96l2.55,5.58Z\", \"name\": \"Yemen\"}, \"AT\": {\"path\": \"M463.17,154.15l-0.14,0.99l-1.15,0.01l-0.24,0.47l0.39,0.56l-0.75,1.84l-0.36,0.4l-2.06,0.07l-0.14,0.04l-1.18,0.67l-1.96,-0.23l-3.43,-0.78l-0.5,-0.97l-0.33,-0.16l-2.47,0.55l-0.2,0.16l-0.18,0.37l-1.27,-0.38l-1.28,-0.09l-0.81,-0.41l0.25,-0.51l0.03,-0.18l-0.05,-0.28l0.35,-0.08l1.16,0.81l0.45,-0.13l0.27,-0.64l2.0,0.12l1.84,-0.57l1.05,0.09l0.71,0.59l0.47,-0.11l0.23,-0.54l0.02,-0.17l-0.32,-1.85l0.69,-0.31l0.13,-0.12l0.73,-1.23l1.61,0.89l0.35,-0.04l1.35,-1.27l0.7,-0.19l1.84,0.93l0.18,0.03l1.08,-0.15l0.81,0.43l-0.07,0.15l-0.02,0.2l0.24,1.06Z\", \"name\": \"Austria\"}, \"DZ\": {\"path\": \"M450.58,224.94l-8.31,4.86l-7.23,5.12l-3.46,1.13l-2.42,0.22l-0.02,-1.33l-0.2,-0.28l-1.15,-0.42l-1.45,-0.69l-0.55,-1.13l-0.1,-0.12l-8.45,-5.72l-17.72,-12.17l0.03,-0.38l-0.02,-3.21l3.84,-1.91l2.46,-0.41l2.1,-0.75l0.14,-0.11l0.9,-1.3l2.84,-1.06l0.19,-0.27l0.09,-1.81l1.21,-0.2l0.15,-0.07l1.06,-0.96l3.19,-0.46l0.23,-0.18l0.46,-1.08l-0.08,-0.34l-0.6,-0.54l-0.83,-2.85l-0.18,-1.8l-0.82,-1.57l2.13,-1.37l2.65,-0.49l0.13,-0.05l1.55,-1.15l2.34,-0.85l4.2,-0.51l4.07,-0.23l1.21,0.41l0.23,-0.01l2.3,-1.11l2.52,-0.02l0.94,0.62l0.2,0.05l1.25,-0.13l-0.36,1.03l-0.01,0.14l0.39,2.66l-0.56,2.2l-1.49,1.52l-0.08,0.24l0.22,2.12l0.11,0.2l1.94,1.58l0.02,0.54l0.12,0.23l1.45,1.06l1.04,4.85l0.81,2.42l0.13,1.19l-0.43,2.17l0.17,1.28l-0.31,1.53l0.2,1.56l-0.9,1.02l-0.01,0.38l1.43,1.88l0.09,1.06l0.04,0.13l0.89,1.48l0.37,0.12l1.03,-0.43l1.79,1.12l0.89,1.34Z\", \"name\": \"Algeria\"}, \"US\": {\"path\": \"M892.64,99.05l1.16,0.57l0.21,0.02l1.45,-0.38l1.92,0.99l2.17,0.47l-1.65,0.72l-1.75,-0.79l-0.93,-0.7l-0.21,-0.06l-2.11,0.22l-0.35,-0.2l0.09,-0.87ZM183.29,150.37l0.39,1.54l0.12,0.17l0.78,0.55l0.14,0.05l1.74,0.2l2.52,0.5l2.4,0.98l0.17,0.02l1.96,-0.4l3.01,0.81l0.91,-0.02l2.22,-0.88l4.67,2.33l3.86,2.01l0.21,0.71l0.15,0.18l0.33,0.17l-0.02,0.05l0.23,0.43l0.67,0.1l0.21,-0.05l0.1,-0.07l0.05,0.29l0.09,0.16l0.5,0.5l0.21,0.09l0.56,0.0l0.13,0.13l-0.2,0.36l0.12,0.41l2.49,1.39l0.99,5.24l-0.69,1.68l-1.16,1.64l-0.6,1.18l-0.06,0.31l0.04,0.22l0.28,0.43l0.11,0.1l0.85,0.47l0.15,0.04l0.63,0.0l0.14,-0.04l2.87,-1.58l2.6,-0.49l3.28,-1.5l0.17,-0.23l0.04,-0.43l-0.23,-0.93l-0.24,-0.39l0.74,-0.32l4.7,-0.01l0.25,-0.13l0.77,-1.15l2.9,-2.41l1.04,-0.52l8.35,-0.02l0.28,-0.21l0.2,-0.6l0.7,-0.14l1.06,-0.48l0.13,-0.11l0.92,-1.49l0.75,-2.39l1.67,-2.08l0.59,0.6l0.3,0.07l1.52,-0.49l0.88,0.72l-0.0,4.14l0.08,0.2l1.6,1.72l0.31,0.72l-2.42,1.35l-2.55,1.05l-2.64,0.9l-0.14,0.11l-1.33,1.81l-0.44,0.7l-0.05,0.15l-0.03,1.6l0.03,0.14l0.83,1.59l0.24,0.16l0.78,0.06l-1.15,0.33l-1.25,-0.04l-1.83,0.52l-2.51,0.29l-2.17,0.88l-0.17,0.36l0.33,0.22l3.55,-0.54l0.15,0.11l-2.87,0.73l-1.19,0.0l-0.16,-0.33l-0.36,0.06l-0.76,0.82l0.17,0.5l0.42,0.08l-0.45,1.75l-1.4,1.74l-0.04,-0.17l-0.21,-0.22l-0.48,-0.13l-0.77,-0.69l-0.36,-0.03l-0.12,0.34l0.52,1.58l0.09,0.14l0.52,0.43l0.03,0.87l-0.74,1.05l-0.39,0.63l0.05,-0.12l-0.08,-0.34l-1.19,-1.03l-0.28,-2.31l-0.26,-0.26l-0.32,0.19l-0.48,1.27l-0.01,0.19l0.39,1.33l-1.14,-0.31l-0.36,0.18l0.14,0.38l1.57,0.85l0.1,2.58l0.22,0.28l0.55,0.15l0.21,0.81l0.33,2.72l-1.46,1.94l-2.5,0.81l-0.12,0.07l-1.58,1.58l-1.15,0.17l-0.15,0.06l-1.27,1.03l-0.09,0.13l-0.32,0.85l-2.71,1.79l-1.45,1.37l-1.18,1.64l-0.05,0.12l-0.39,1.96l0.0,0.13l0.44,1.91l0.85,2.37l1.1,1.91l0.03,1.2l1.16,3.07l-0.08,1.74l-0.1,0.99l-0.57,1.48l-0.54,0.24l-0.97,-0.26l-0.34,-1.02l-0.12,-0.16l-0.89,-0.58l-2.44,-4.28l-0.34,-0.94l0.49,-1.71l-0.02,-0.21l-0.7,-1.5l-2.0,-2.35l-0.11,-0.08l-0.98,-0.42l-0.25,0.01l-2.42,1.19l-0.26,-0.08l-1.26,-1.29l-1.57,-0.68l-0.16,-0.02l-2.79,0.34l-2.18,-0.3l-1.98,0.19l-1.12,0.45l-0.14,0.44l0.4,0.65l-0.04,1.02l0.09,0.22l0.29,0.3l-0.06,0.05l-0.77,-0.33l-0.26,0.01l-0.87,0.48l-1.64,-0.08l-1.79,-1.39l-0.23,-0.06l-2.11,0.33l-1.75,-0.61l-0.14,-0.01l-1.61,0.2l-2.11,0.64l-0.11,0.06l-2.25,1.99l-2.53,1.21l-1.43,1.38l-0.58,1.22l-0.03,0.12l-0.03,1.86l0.13,1.32l0.3,0.62l-0.46,0.04l-1.71,-0.57l-1.85,-0.79l-0.63,-1.14l-0.54,-1.85l-0.07,-0.12l-1.45,-1.51l-0.86,-1.58l-1.26,-1.87l-0.09,-0.09l-1.76,-1.09l-0.17,-0.04l-2.05,0.05l-0.23,0.12l-1.44,1.97l-1.84,-0.72l-1.19,-0.76l-0.6,-1.45l-0.9,-1.52l-1.49,-1.21l-1.27,-0.87l-0.89,-0.96l-0.22,-0.1l-4.34,-0.0l-0.3,0.3l-0.0,0.84l-6.62,0.02l-5.66,-1.93l-3.48,-1.24l0.11,-0.25l-0.3,-0.42l-3.18,0.3l-2.6,0.2l-0.35,-1.19l-0.08,-0.13l-1.62,-1.61l-0.13,-0.08l-1.02,-0.29l-0.22,-0.66l-0.25,-0.2l-1.31,-0.13l-0.82,-0.7l-0.16,-0.07l-2.25,-0.27l-0.48,-0.34l-0.28,-1.44l-0.07,-0.14l-2.41,-2.84l-2.03,-3.89l0.08,-0.58l-0.1,-0.27l-1.08,-0.94l-1.87,-2.36l-0.33,-2.31l-0.07,-0.15l-1.24,-1.5l0.52,-2.4l-0.09,-2.57l-0.78,-2.3l0.96,-2.83l0.61,-5.66l-0.46,-4.26l-0.79,-2.71l-0.68,-1.4l0.13,-0.26l3.24,0.97l1.28,2.88l0.52,0.06l0.62,-0.84l0.06,-0.22l-0.4,-2.61l-0.74,-2.29l68.9,-0.0l0.3,-0.3l0.01,-0.95l0.32,-0.01ZM32.5,67.43l1.75,1.99l0.41,0.04l1.02,-0.81l3.79,0.25l-0.1,0.72l0.24,0.34l3.83,0.77l2.6,-0.44l5.21,1.41l4.84,0.43l1.9,0.57l0.15,0.01l3.25,-0.71l3.72,1.32l2.52,0.58l-0.03,38.14l0.29,0.3l2.41,0.11l2.34,1.0l1.7,1.59l2.22,2.42l0.42,0.03l2.41,-2.04l2.25,-1.08l1.23,1.76l1.71,1.53l2.24,1.62l1.54,2.56l2.56,4.09l0.11,0.11l4.1,2.17l0.06,1.93l-1.12,1.35l-1.22,-1.14l-2.08,-1.05l-0.68,-2.94l-0.09,-0.16l-3.18,-2.84l-1.32,-3.35l-0.25,-0.19l-2.43,-0.24l-3.93,-0.09l-2.85,-1.02l-5.24,-3.85l-6.77,-2.04l-3.52,0.3l-4.84,-1.7l-2.96,-1.6l-0.23,-0.02l-2.78,0.8l-0.21,0.35l0.46,2.31l-1.11,0.19l-2.9,0.78l-2.24,1.26l-2.42,0.68l-0.29,-1.79l1.07,-3.49l2.54,-1.11l0.12,-0.45l-0.69,-0.96l-0.41,-0.07l-3.19,2.12l-1.76,2.54l-3.57,2.62l-0.03,0.46l1.63,1.59l-2.14,2.38l-2.64,1.49l-2.49,1.09l-0.16,0.17l-0.58,1.48l-3.8,1.79l-0.14,0.14l-0.75,1.57l-2.75,1.41l-1.62,-0.25l-0.16,0.02l-2.35,0.98l-2.54,1.19l-2.06,1.15l-4.05,0.93l-0.1,-0.15l2.45,-1.45l2.49,-1.1l2.61,-1.88l3.03,-0.39l0.19,-0.1l1.2,-1.41l3.43,-2.11l0.61,-0.75l1.81,-1.24l0.13,-0.2l0.42,-2.7l1.24,-2.12l-0.03,-0.35l-0.34,-0.09l-2.73,1.05l-0.67,-0.53l-0.39,0.02l-1.13,1.11l-1.43,-1.62l-0.49,0.06l-0.41,0.8l-0.67,-1.31l-0.42,-0.12l-2.43,1.43l-1.18,-0.0l-0.18,-1.86l0.43,-1.3l-0.09,-0.33l-1.61,-1.33l-0.26,-0.06l-3.11,0.68l-2.0,-1.66l-1.61,-0.85l-0.01,-1.97l-0.11,-0.23l-1.76,-1.48l0.86,-1.96l2.01,-2.13l0.88,-1.94l1.79,-0.25l1.65,0.6l0.31,-0.06l1.91,-1.8l1.67,0.31l0.22,-0.04l1.91,-1.23l0.13,-0.33l-0.47,-1.82l-0.15,-0.19l-1.0,-0.52l1.51,-1.27l0.09,-0.34l-0.29,-0.19l-1.62,0.06l-2.66,0.88l-0.13,0.09l-0.62,0.72l-1.77,-0.8l-0.16,-0.02l-3.48,0.44l-3.5,-0.92l-1.06,-1.61l-2.78,-2.09l3.07,-1.51l5.52,-2.01l1.65,0.0l-0.28,1.73l0.31,0.35l5.29,-0.16l0.23,-0.49l-2.03,-2.59l-0.1,-0.08l-3.03,-1.58l-1.79,-2.12l-2.4,-1.83l-3.18,-1.27l1.13,-1.84l4.28,-0.14l0.15,-0.05l3.16,-2.0l0.13,-0.17l0.57,-2.07l2.43,-2.02l2.42,-0.52l4.67,-1.98l2.22,0.29l0.2,-0.04l3.74,-2.37l3.57,0.91ZM37.66,123.49l-2.31,1.26l-1.04,-0.75l-0.31,-1.35l2.06,-1.16l1.24,-0.51l1.48,0.22l0.76,0.81l-1.89,1.49ZM30.89,233.84l1.2,0.57l0.35,0.3l0.48,0.69l-1.6,0.86l-0.3,0.31l-0.24,-0.14l0.05,-0.54l-0.02,-0.15l-0.36,-0.83l0.05,-0.12l0.39,-0.38l0.07,-0.31l-0.09,-0.27ZM29.06,231.89l0.5,0.14l0.31,0.19l-0.46,0.1l-0.34,-0.43ZM25.02,230.13l0.2,-0.11l0.4,0.47l-0.43,-0.05l-0.17,-0.31ZM21.29,228.68l0.1,-0.07l0.22,0.02l0.02,0.21l-0.02,0.02l-0.32,-0.18ZM6.0,113.33l-1.19,0.45l-1.5,-0.64l-0.94,-0.63l1.76,-0.46l1.71,0.29l0.16,0.98Z\", \"name\": \"United States of America\"}, \"LV\": {\"path\": \"M473.99,127.16l0.07,-2.15l1.15,-2.11l2.05,-1.07l1.84,2.48l0.25,0.12l2.01,-0.07l0.29,-0.25l0.45,-2.58l1.85,-0.56l0.98,0.4l2.13,1.33l0.16,0.05l1.97,0.01l1.02,0.7l0.21,1.67l0.71,1.84l-2.44,1.23l-1.36,0.53l-2.28,-1.62l-0.12,-0.05l-1.18,-0.2l-0.28,-0.6l-0.31,-0.17l-2.43,0.35l-4.17,-0.23l-0.12,0.02l-2.45,0.93Z\", \"name\": \"Latvia\"}, \"UY\": {\"path\": \"M276.9,363.17l1.3,-0.23l2.4,2.04l0.22,0.07l0.82,-0.07l2.48,1.7l1.93,1.5l1.28,1.67l-0.95,1.14l-0.04,0.31l0.63,1.45l-0.96,1.57l-2.65,1.47l-1.73,-0.53l-0.15,-0.01l-1.25,0.28l-2.22,-1.16l-0.16,-0.03l-1.56,0.08l-1.33,-1.36l0.17,-1.58l0.48,-0.55l0.07,-0.2l-0.02,-2.74l0.66,-2.8l0.57,-2.02Z\", \"name\": \"Uruguay\"}, \"LB\": {\"path\": \"M510.44,198.11l-0.48,0.03l-0.26,0.17l-0.15,0.32l-0.21,-0.0l0.72,-1.85l1.19,-1.9l0.74,0.09l0.27,0.73l-1.19,0.93l-0.09,0.13l-0.54,1.36Z\", \"name\": \"Lebanon\"}, \"LA\": {\"path\": \"M684.87,248.8l0.61,-0.86l0.05,-0.16l0.11,-2.17l-0.08,-0.22l-1.96,-2.16l-0.15,-2.44l-0.08,-0.18l-1.9,-2.1l-0.19,-0.1l-1.89,-0.18l-0.29,0.15l-0.42,0.76l-1.21,0.06l-0.67,-0.41l-0.31,-0.0l-2.2,1.29l-0.05,-1.77l0.61,-2.7l-0.27,-0.37l-1.44,-0.1l-0.12,-1.31l-0.12,-0.21l-0.87,-0.65l0.38,-0.68l1.76,-1.41l0.08,0.22l0.27,0.2l1.33,0.07l0.31,-0.34l-0.35,-2.75l0.85,-0.25l1.32,1.88l1.11,2.36l0.27,0.17l2.89,0.02l0.78,1.82l-1.32,0.56l-0.12,0.09l-0.72,0.93l0.1,0.45l2.93,1.52l3.62,5.27l1.88,1.78l0.58,1.67l-0.38,2.11l-1.87,-0.79l-0.37,0.11l-0.99,1.54l-1.51,-0.73Z\", \"name\": \"Laos\"}, \"TW\": {\"path\": \"M725.6,222.5l-1.5,4.22l-0.82,1.65l-1.01,-1.7l-0.26,-1.8l1.4,-2.48l1.8,-1.81l0.76,0.53l-0.38,1.39Z\", \"name\": \"Taiwan\"}, \"TT\": {\"path\": \"M266.35,259.46l0.41,-0.39l0.09,-0.23l-0.04,-0.75l1.14,-0.26l0.2,0.03l-0.07,1.37l-1.73,0.23Z\", \"name\": \"Trinidad and Tobago\"}, \"TR\": {\"path\": \"M513.25,175.38l3.63,1.17l0.14,0.01l2.88,-0.45l2.11,0.26l0.18,-0.03l2.9,-1.53l2.51,-0.13l2.25,1.37l0.36,0.88l-0.23,1.36l0.19,0.33l1.81,0.72l0.61,0.53l-1.31,0.64l-0.16,0.34l0.76,3.24l-0.44,0.8l0.01,0.3l1.19,2.02l-0.71,0.29l-0.74,-0.62l-0.15,-0.07l-2.91,-0.37l-0.15,0.02l-1.04,0.43l-2.78,0.44l-1.44,-0.03l-2.83,1.06l-1.95,0.01l-1.28,-0.52l-0.2,-0.01l-2.62,0.76l-0.7,-0.48l-0.47,0.22l-0.13,1.49l-1.01,0.94l-0.58,-0.82l0.79,-0.9l0.04,-0.34l-0.31,-0.15l-1.46,0.23l-2.03,-0.64l-0.3,0.07l-1.65,1.58l-3.58,0.3l-1.94,-1.47l-0.17,-0.06l-2.7,-0.1l-0.28,0.17l-0.51,1.06l-1.47,0.29l-2.32,-1.46l-0.17,-0.05l-2.55,0.05l-1.4,-2.7l-1.72,-1.54l1.11,-2.06l-0.07,-0.37l-1.35,-1.19l2.47,-2.51l3.74,-0.11l0.26,-0.17l0.96,-2.07l4.56,0.38l0.19,-0.05l2.97,-1.92l2.84,-0.83l4.03,-0.06l4.31,2.08ZM488.85,176.8l-1.81,1.38l-0.57,-1.01l0.02,-0.36l0.45,-0.25l0.13,-0.15l0.78,-1.87l-0.11,-0.37l-0.72,-0.47l1.91,-0.71l1.89,0.35l0.25,0.97l0.17,0.2l1.87,0.83l-0.19,0.31l-2.82,0.16l-0.18,0.07l-1.06,0.91Z\", \"name\": \"Turkey\"}, \"LK\": {\"path\": \"M625.44,266.07l-0.35,2.4l-0.9,0.61l-1.91,0.5l-1.04,-1.75l-0.43,-3.5l1.0,-3.6l1.34,1.09l1.13,1.72l1.16,2.52Z\", \"name\": \"Sri Lanka\"}, \"TN\": {\"path\": \"M444.91,206.18l-0.99,-4.57l-0.12,-0.18l-1.43,-1.04l-0.02,-0.53l-0.11,-0.22l-1.95,-1.59l-0.19,-1.85l1.44,-1.47l0.08,-0.14l0.59,-2.34l-0.38,-2.77l0.44,-1.28l2.52,-1.08l1.41,0.28l-0.06,1.2l0.43,0.28l1.81,-0.9l0.02,0.06l-1.14,1.28l-0.08,0.2l-0.02,1.32l0.11,0.24l0.74,0.6l-0.29,2.18l-1.56,1.35l-0.09,0.32l0.48,1.54l0.28,0.21l1.11,0.04l0.55,1.17l0.15,0.14l0.76,0.35l-0.12,1.79l-1.1,0.72l-0.8,0.91l-1.68,1.04l-0.13,0.32l0.25,1.08l-0.18,0.96l-0.74,0.39Z\", \"name\": \"Tunisia\"}, \"TL\": {\"path\": \"M734.21,307.22l0.17,-0.34l1.99,-0.52l1.72,-0.08l0.78,-0.3l0.29,0.1l-0.43,0.32l-2.57,1.09l-1.71,0.59l-0.05,-0.49l-0.19,-0.36Z\", \"name\": \"East Timor\"}, \"TM\": {\"path\": \"M553.16,173.51l-0.12,1.0l-0.26,-0.65l0.38,-0.34ZM553.54,173.16l0.13,-0.12l0.43,-0.09l-0.56,0.21ZM555.68,172.6l0.65,-0.14l1.53,0.76l1.71,2.29l0.27,0.12l1.27,-0.14l2.81,-0.04l0.29,-0.38l-0.35,-1.27l1.98,-0.97l1.96,-1.63l3.05,1.44l0.25,2.23l0.14,0.22l0.96,0.61l0.18,0.05l2.61,-0.13l0.68,0.44l1.2,2.97l0.1,0.13l2.85,2.03l1.67,1.41l2.66,1.45l3.13,1.17l-0.05,1.23l-0.36,-0.04l-1.12,-0.73l-0.44,0.14l-0.34,0.89l-1.96,0.52l-0.22,0.23l-0.47,2.17l-1.26,0.78l-1.93,0.42l-0.21,0.18l-0.46,1.14l-1.64,0.33l-2.3,-0.97l-0.2,-2.23l-0.28,-0.27l-1.76,-0.1l-2.78,-2.48l-0.15,-0.07l-1.95,-0.31l-2.82,-1.48l-1.78,-0.27l-0.18,0.03l-1.03,0.51l-1.6,-0.08l-0.22,0.08l-1.72,1.6l-1.83,0.46l-0.39,-1.7l0.36,-3.0l-0.16,-0.3l-1.73,-0.88l0.57,-1.77l-0.25,-0.39l-1.33,-0.14l0.41,-1.85l2.05,0.63l0.21,-0.01l2.2,-0.95l0.09,-0.49l-1.78,-1.75l-0.69,-1.66l-0.07,-0.03Z\", \"name\": \"Turkmenistan\"}, \"TJ\": {\"path\": \"M597.99,178.71l-0.23,0.23l-2.57,-0.47l-0.35,0.25l-0.24,1.7l0.32,0.34l2.66,-0.22l3.15,0.95l4.47,-0.42l0.58,2.45l0.39,0.21l0.71,-0.25l1.22,0.53l-0.06,1.01l0.29,1.28l-2.19,-0.0l-1.71,-0.21l-0.23,0.07l-1.51,1.25l-1.05,0.27l-0.77,0.51l-0.71,-0.67l0.22,-2.28l-0.24,-0.32l-0.43,-0.08l0.17,-0.57l-0.16,-0.36l-1.36,-0.66l-0.34,0.05l-1.08,1.01l-0.09,0.15l-0.25,1.09l-0.24,0.26l-1.36,-0.05l-0.27,0.14l-0.65,1.06l-0.58,-0.39l-0.3,-0.02l-1.68,0.86l-0.36,-0.16l1.28,-2.65l0.02,-0.2l-0.54,-2.17l-0.18,-0.21l-1.53,-0.58l0.41,-0.82l1.89,0.13l0.26,-0.12l1.19,-1.63l0.77,-1.82l2.66,-0.55l-0.33,0.87l0.01,0.23l0.36,0.82l0.3,0.18l0.23,-0.02Z\", \"name\": \"Tajikistan\"}, \"LS\": {\"path\": \"M493.32,359.69l0.69,0.65l-0.65,1.12l-0.38,0.8l-1.27,0.39l-0.18,0.15l-0.4,0.77l-0.59,0.18l-1.59,-1.78l1.16,-1.5l1.3,-1.02l0.97,-0.46l0.94,0.72Z\", \"name\": \"Lesotho\"}, \"TH\": {\"path\": \"M677.42,253.68l-1.7,-0.88l-0.14,-0.03l-1.77,0.04l0.3,-1.64l-0.3,-0.35l-2.21,0.01l-0.3,0.28l-0.2,2.76l-2.15,5.9l-0.02,0.13l0.17,1.83l0.28,0.27l1.45,0.07l0.93,2.1l0.44,2.15l0.08,0.15l1.4,1.44l0.16,0.09l1.43,0.27l1.04,1.05l-0.58,0.73l-1.24,0.22l-0.15,-0.99l-0.15,-0.22l-2.04,-1.1l-0.36,0.06l-0.23,0.23l-0.72,-0.71l-0.41,-1.18l-0.06,-0.11l-1.33,-1.42l-1.22,-1.2l-0.5,0.13l-0.15,0.54l-0.14,-0.41l0.26,-1.48l0.73,-2.38l1.2,-2.57l1.37,-2.35l0.02,-0.27l-0.95,-2.26l0.03,-1.19l-0.29,-1.42l-0.06,-0.13l-1.65,-2.0l-0.46,-0.99l0.62,-0.34l0.13,-0.15l0.92,-2.23l-0.02,-0.27l-1.05,-1.74l-1.57,-1.86l-1.04,-1.96l0.76,-0.34l0.16,-0.16l1.07,-2.63l1.58,-0.1l0.16,-0.06l1.43,-1.11l1.24,-0.52l0.84,0.62l0.13,1.43l0.28,0.27l1.34,0.09l-0.54,2.39l0.05,2.39l0.45,0.25l2.48,-1.45l0.6,0.36l0.17,0.04l1.47,-0.07l0.25,-0.15l0.41,-0.73l1.58,0.15l1.76,1.93l0.15,2.44l0.08,0.18l1.94,2.15l-0.1,1.96l-0.66,0.93l-2.25,-0.34l-3.24,0.49l-0.19,0.12l-1.6,2.12l-0.06,0.24l0.48,2.46Z\", \"name\": \"Thailand\"}, \"TF\": {\"path\": \"M593.76,417.73l1.38,0.84l2.15,0.37l0.04,0.31l-0.59,1.24l-3.36,0.19l-0.05,-1.38l0.43,-1.56Z\", \"name\": \"French Southern and Antarctic Lands\"}, \"TG\": {\"path\": \"M425.23,269.29l-1.49,0.4l-0.43,-0.68l-0.64,-1.54l-0.18,-1.16l0.54,-2.21l-0.04,-0.24l-0.59,-0.86l-0.23,-1.9l0.0,-1.82l-0.07,-0.19l-0.95,-1.19l0.1,-0.41l1.58,0.04l-0.23,0.97l0.08,0.28l1.55,1.55l0.09,1.13l0.08,0.19l0.42,0.43l-0.11,5.66l0.52,1.53Z\", \"name\": \"Togo\"}, \"TD\": {\"path\": \"M457.57,252.46l0.23,-1.08l-0.28,-0.36l-1.32,-0.05l0.0,-1.35l-0.1,-0.22l-0.9,-0.82l0.99,-3.1l3.12,-2.37l0.12,-0.23l0.13,-3.33l0.95,-5.2l0.53,-1.09l-0.07,-0.36l-0.94,-0.81l-0.03,-0.7l-0.12,-0.23l-0.84,-0.61l-0.57,-3.76l2.21,-1.26l19.67,9.88l0.12,9.74l-1.83,-0.15l-0.28,0.14l-1.14,1.89l-0.68,1.62l0.05,0.31l0.33,0.38l-0.61,0.58l-0.08,0.3l0.25,0.93l-0.58,0.95l-0.29,1.01l0.34,0.37l0.67,-0.11l0.39,0.73l0.03,1.4l0.11,0.23l0.8,0.65l-0.01,0.24l-1.38,0.37l-0.11,0.06l-1.27,1.03l-1.83,2.76l-2.21,1.1l-2.34,-0.15l-0.82,0.25l-0.2,0.37l0.19,0.68l-1.16,0.79l-1.01,0.94l-2.92,0.89l-0.5,-0.46l-0.17,-0.08l-0.41,-0.05l-0.28,0.12l-0.38,0.54l-1.36,0.12l0.1,-0.18l0.01,-0.27l-0.78,-1.72l-0.35,-1.03l-0.17,-0.18l-1.03,-0.41l-1.29,-1.28l0.36,-0.78l0.9,0.2l0.14,-0.0l0.67,-0.17l1.36,0.02l0.26,-0.45l-1.32,-2.22l0.09,-1.64l-0.17,-1.68l-0.04,-0.13l-0.93,-1.53Z\", \"name\": \"Chad\"}, \"LY\": {\"path\": \"M457.99,226.38l-1.57,0.87l-1.25,-1.28l-0.13,-0.08l-3.85,-1.11l-1.04,-1.57l-0.09,-0.09l-1.98,-1.23l-0.27,-0.02l-0.93,0.39l-0.72,-1.2l-0.09,-1.07l-0.06,-0.16l-1.33,-1.75l0.83,-0.94l0.07,-0.24l-0.21,-1.64l0.31,-1.43l-0.17,-1.29l0.43,-2.26l-0.15,-1.33l-0.73,-2.18l0.99,-0.52l0.16,-0.21l0.22,-1.16l-0.22,-1.06l1.54,-0.95l0.81,-0.92l1.19,-0.78l0.14,-0.23l0.12,-1.76l2.57,0.84l0.16,0.01l0.99,-0.23l2.01,0.45l3.19,1.2l1.12,2.36l0.2,0.16l2.24,0.53l3.5,1.14l2.65,1.36l0.29,-0.01l1.22,-0.71l1.27,-1.32l0.07,-0.29l-0.55,-2.0l0.69,-1.19l1.7,-1.23l1.61,-0.35l3.2,0.54l0.78,1.14l0.24,0.13l0.85,0.01l0.84,0.47l2.35,0.31l0.42,0.63l-0.79,1.16l-0.04,0.26l0.35,1.08l-0.61,1.6l-0.0,0.2l0.73,2.16l0.0,24.24l-2.58,0.01l-0.3,0.29l-0.02,0.62l-19.55,-9.83l-0.28,0.01l-2.53,1.44Z\", \"name\": \"Libya\"}, \"AE\": {\"path\": \"M550.59,223.8l0.12,0.08l1.92,-0.41l3.54,0.15l0.23,-0.09l1.71,-1.79l1.86,-1.7l1.31,-1.36l0.26,0.5l0.28,1.72l-0.93,0.01l-0.3,0.26l-0.21,1.73l0.11,0.27l0.08,0.06l-0.7,0.32l-0.17,0.27l-0.01,0.99l-0.68,1.02l-0.05,0.15l-0.06,0.96l-0.32,0.36l-7.19,-1.27l-0.79,-2.22Z\", \"name\": \"United Arab Emirates\"}, \"VE\": {\"path\": \"M240.66,256.5l0.65,0.91l-0.03,1.13l-1.05,1.39l-0.03,0.31l0.95,2.0l0.32,0.17l1.08,-0.16l0.24,-0.21l0.56,-1.83l-0.06,-0.29l-0.71,-0.81l-0.1,-1.58l2.9,-0.96l0.19,-0.37l-0.29,-1.02l0.45,-0.41l0.72,1.43l0.26,0.16l1.65,0.04l1.46,1.27l0.08,0.72l0.3,0.27l2.28,0.02l2.55,-0.25l1.34,1.06l0.14,0.06l1.92,0.31l0.2,-0.03l1.4,-0.79l0.15,-0.25l0.02,-0.36l2.82,-0.14l1.17,-0.01l-0.41,0.14l-0.14,0.46l0.86,1.19l0.22,0.12l1.93,0.18l1.73,1.13l0.37,1.9l0.31,0.24l1.21,-0.05l0.52,0.32l-1.63,1.21l-0.11,0.17l-0.22,0.92l0.07,0.27l0.63,0.69l-0.31,0.24l-1.48,0.39l-0.22,0.3l0.04,1.03l-0.59,0.6l-0.01,0.41l1.67,1.87l0.23,0.48l-0.72,0.76l-2.71,0.91l-1.78,0.39l-0.13,0.06l-0.6,0.49l-1.84,-0.58l-1.89,-0.33l-0.18,0.03l-0.47,0.23l-0.02,0.53l0.96,0.56l-0.08,1.58l0.35,1.58l0.26,0.23l1.91,0.19l0.02,0.07l-1.54,0.62l-0.18,0.2l-0.25,0.92l-0.88,0.35l-1.85,0.58l-0.16,0.13l-0.4,0.64l-1.66,0.14l-1.22,-1.18l-0.79,-2.52l-0.67,-0.88l-0.66,-0.43l0.99,-0.98l0.09,-0.26l-0.09,-0.56l-0.08,-0.16l-0.66,-0.69l-0.47,-1.54l0.18,-1.67l0.55,-0.85l0.45,-1.35l-0.15,-0.36l-0.89,-0.43l-0.19,-0.02l-1.39,0.28l-1.76,-0.13l-0.92,0.23l-1.64,-2.01l-0.17,-0.1l-1.54,-0.33l-3.05,0.23l-0.5,-0.73l-0.15,-0.12l-0.45,-0.15l-0.05,-0.28l0.28,-0.86l0.01,-0.15l-0.2,-1.01l-0.08,-0.15l-0.5,-0.5l-0.3,-1.08l-0.25,-0.22l-0.89,-0.12l0.54,-1.18l0.29,-1.73l0.66,-0.85l0.94,-0.7l0.09,-0.11l0.3,-0.6Z\", \"name\": \"Venezuela\"}, \"AF\": {\"path\": \"M574.42,192.1l2.24,0.95l0.18,0.02l1.89,-0.38l0.22,-0.18l0.46,-1.14l1.82,-0.4l1.5,-0.91l0.14,-0.19l0.46,-2.12l1.93,-0.51l0.2,-0.18l0.26,-0.68l0.87,0.57l0.13,0.05l0.79,0.09l1.35,0.02l1.83,0.59l0.75,0.34l0.26,-0.01l1.66,-0.85l0.7,0.46l0.42,-0.09l0.72,-1.17l1.32,0.05l0.23,-0.1l0.39,-0.43l0.07,-0.14l0.24,-1.08l0.86,-0.81l0.94,0.46l-0.2,0.64l0.23,0.38l0.49,0.09l-0.21,2.15l0.09,0.25l0.99,0.94l0.38,0.03l0.83,-0.57l1.06,-0.27l0.12,-0.06l1.46,-1.21l1.63,0.2l2.4,0.0l0.17,0.32l-1.12,0.25l-1.23,0.52l-2.86,0.33l-2.69,0.6l-0.13,0.06l-1.46,1.25l-0.07,0.36l0.58,1.18l0.25,1.21l-1.13,1.08l-0.09,0.25l0.09,0.98l-0.53,0.79l-2.22,-0.08l-0.28,0.44l0.83,1.57l-1.3,0.58l-0.13,0.11l-1.06,1.69l-0.05,0.18l0.13,1.51l-0.73,0.58l-0.78,-0.22l-0.14,-0.01l-1.91,0.36l-0.23,0.19l-0.2,0.57l-1.65,-0.0l-0.22,0.1l-1.4,1.56l-0.08,0.19l-0.08,2.13l-2.99,1.05l-1.67,-0.23l-0.27,0.1l-0.39,0.46l-1.43,-0.31l-2.43,0.4l-3.69,-1.23l1.96,-2.15l0.08,-0.24l-0.21,-1.78l-0.23,-0.26l-1.69,-0.42l-0.19,-1.62l-0.77,-2.08l0.98,-1.41l-0.14,-0.45l-0.82,-0.31l0.6,-1.79l0.93,-3.21Z\", \"name\": \"Afghanistan\"}, \"IQ\": {\"path\": \"M534.42,190.89l0.13,0.14l1.5,0.78l0.15,1.34l-1.13,0.87l-0.11,0.16l-0.58,2.2l0.04,0.24l1.73,2.67l0.12,0.1l2.99,1.49l1.18,1.94l-0.39,1.89l0.29,0.36l0.5,-0.0l0.02,1.17l0.08,0.2l0.83,0.86l-2.36,-0.29l-0.29,0.13l-1.74,2.49l-4.4,-0.21l-7.03,-5.49l-3.73,-1.94l-2.92,-0.74l-0.89,-3.0l5.33,-2.81l0.15,-0.19l0.95,-3.43l-0.2,-2.0l1.19,-0.61l0.11,-0.09l1.23,-1.73l0.92,-0.38l2.75,0.35l0.81,0.68l0.31,0.05l0.94,-0.38l1.5,3.17Z\", \"name\": \"Iraq\"}, \"IS\": {\"path\": \"M384.26,87.96l-0.51,2.35l0.08,0.28l2.61,2.58l-2.99,2.83l-7.16,2.72l-2.08,0.7l-9.51,-1.71l1.89,-1.36l-0.07,-0.53l-4.4,-1.59l3.33,-0.59l0.25,-0.32l-0.11,-1.2l-0.25,-0.27l-4.82,-0.88l1.38,-2.2l3.54,-0.57l3.8,2.74l0.33,0.01l3.68,-2.18l3.02,1.12l0.25,-0.02l4.01,-2.18l3.72,0.27Z\", \"name\": \"Iceland\"}, \"IR\": {\"path\": \"M556.2,187.5l2.05,-0.52l0.13,-0.07l1.69,-1.57l1.55,0.08l0.15,-0.03l1.02,-0.5l1.64,0.25l2.82,1.48l1.91,0.3l2.8,2.49l0.18,0.08l1.61,0.09l0.19,2.09l-1.0,3.47l-0.69,2.04l0.18,0.38l0.73,0.28l-0.85,1.22l-0.04,0.28l0.81,2.19l0.19,1.72l0.23,0.26l1.69,0.42l0.17,1.43l-2.18,2.39l-0.01,0.4l1.22,1.42l1.0,1.62l0.12,0.11l2.23,1.11l0.06,2.2l0.2,0.27l1.03,0.38l0.14,0.83l-3.38,1.3l-0.18,0.19l-0.87,2.85l-4.44,-0.76l-2.75,-0.62l-2.64,-0.32l-1.01,-3.11l-0.17,-0.19l-1.2,-0.48l-0.18,-0.01l-1.99,0.51l-2.42,1.25l-2.89,-0.84l-2.48,-2.03l-2.41,-0.79l-1.61,-2.47l-1.84,-3.63l-0.36,-0.15l-1.22,0.4l-1.48,-0.84l-0.37,0.06l-0.72,0.82l-1.08,-1.12l-0.02,-1.35l-0.3,-0.29l-0.43,0.0l0.34,-1.64l-0.04,-0.22l-1.29,-2.11l-0.12,-0.11l-3.0,-1.49l-1.62,-2.49l0.52,-1.98l1.18,-0.92l0.11,-0.27l-0.19,-1.66l-0.16,-0.23l-1.55,-0.81l-1.58,-3.33l-1.3,-2.2l0.41,-0.75l0.03,-0.21l-0.73,-3.12l1.2,-0.59l0.35,0.9l1.26,1.35l0.15,0.09l1.81,0.39l0.91,-0.09l0.15,-0.06l2.9,-2.13l0.7,-0.16l0.48,0.56l-0.75,1.26l0.05,0.37l1.56,1.53l0.28,0.08l0.37,-0.09l0.7,1.89l0.21,0.19l2.31,0.59l1.69,1.4l0.15,0.07l3.66,0.49l3.91,-0.76l0.23,-0.19l0.19,-0.52Z\", \"name\": \"Iran\"}, \"AM\": {\"path\": \"M530.51,176.08l2.91,-0.39l0.41,0.63l0.11,0.1l0.66,0.36l-0.32,0.47l0.07,0.41l1.1,0.84l-0.53,0.7l0.06,0.42l1.06,0.8l1.01,0.44l0.04,1.56l-0.44,0.04l-0.88,-1.46l0.01,-0.37l-0.3,-0.31l-0.98,0.01l-0.65,-0.69l-0.26,-0.09l-0.38,0.06l-0.97,-0.82l-1.64,-0.65l0.2,-1.2l-0.02,-0.16l-0.28,-0.69Z\", \"name\": \"Armenia\"}, \"IT\": {\"path\": \"M451.68,158.58l0.2,0.16l3.3,0.75l-0.22,1.26l0.02,0.18l0.35,0.78l-1.4,-0.32l-0.21,0.03l-2.04,1.1l-0.16,0.29l0.13,1.47l-0.29,0.82l0.02,0.24l0.82,1.57l0.1,0.11l2.28,1.5l1.29,2.53l2.79,2.43l0.2,0.07l1.83,-0.02l0.31,0.34l-0.46,0.39l0.06,0.5l4.06,1.97l2.06,1.49l0.17,0.36l-0.24,0.53l-1.08,-1.07l-0.15,-0.08l-2.18,-0.49l-0.33,0.15l-1.05,1.91l0.11,0.4l1.63,0.98l-0.22,1.12l-0.84,0.14l-0.22,0.15l-1.27,2.38l-0.54,0.12l0.01,-0.47l0.48,-1.46l0.5,-0.58l0.03,-0.35l-0.97,-1.69l-0.76,-1.48l-0.17,-0.15l-0.94,-0.33l-0.68,-1.18l-0.16,-0.13l-1.53,-0.52l-1.03,-1.14l-0.19,-0.1l-1.78,-0.19l-1.88,-1.3l-2.27,-1.94l-1.64,-1.68l-0.76,-2.94l-0.21,-0.21l-1.22,-0.35l-2.01,-1.0l-0.24,-0.01l-1.15,0.42l-0.11,0.07l-1.38,1.36l-0.5,0.11l0.19,-0.87l-0.21,-0.35l-1.19,-0.34l-0.56,-2.06l0.76,-0.82l0.03,-0.36l-0.68,-1.08l0.04,-0.31l0.68,0.42l0.19,0.04l1.21,-0.15l0.14,-0.06l1.18,-0.89l0.25,0.29l0.25,0.1l1.19,-0.1l0.25,-0.18l0.45,-1.04l1.61,0.34l0.19,-0.02l1.1,-0.53l0.17,-0.22l0.15,-0.95l1.19,0.35l0.35,-0.16l0.23,-0.47l2.11,-0.47l0.45,0.89ZM459.35,184.63l-0.71,1.81l0.0,0.23l0.33,0.79l-0.37,1.03l-1.6,-0.91l-1.33,-0.34l-3.24,-1.36l0.23,-0.99l2.73,0.24l3.95,-0.5ZM443.95,175.91l1.26,1.77l-0.31,3.47l-0.82,-0.13l-0.26,0.08l-0.83,0.79l-0.64,-0.52l-0.1,-3.42l-0.44,-1.34l0.91,0.1l0.21,-0.06l1.01,-0.74Z\", \"name\": \"Italy\"}, \"VN\": {\"path\": \"M690.8,230.21l-2.86,1.93l-2.09,2.46l-0.06,0.11l-0.55,1.8l0.04,0.26l4.26,6.1l2.31,1.63l1.46,1.97l1.12,4.62l-0.32,4.3l-1.97,1.57l-2.85,1.62l-2.09,2.14l-2.83,2.13l-0.67,-1.19l0.65,-1.58l-0.09,-0.35l-1.47,-1.14l1.67,-0.79l2.57,-0.18l0.22,-0.47l-0.89,-1.24l3.88,-1.8l0.17,-0.24l0.31,-3.05l-0.01,-0.13l-0.56,-1.63l0.44,-2.48l-0.01,-0.15l-0.63,-1.81l-0.08,-0.12l-1.87,-1.77l-3.64,-5.3l-0.11,-0.1l-2.68,-1.39l0.45,-0.59l1.53,-0.65l0.16,-0.39l-0.97,-2.27l-0.27,-0.18l-2.89,-0.02l-1.04,-2.21l-1.28,-1.83l0.96,-0.46l1.97,0.01l2.43,-0.3l0.13,-0.05l1.95,-1.29l1.04,0.85l0.13,0.06l1.98,0.42l-0.32,1.21l0.09,0.3l1.19,1.07l0.12,0.07l1.88,0.51Z\", \"name\": \"Vietnam\"}, \"AR\": {\"path\": \"M258.11,341.34l1.4,1.81l0.51,-0.06l0.89,-1.94l2.51,0.1l0.36,0.49l4.6,4.31l0.15,0.08l1.99,0.39l3.01,1.93l2.5,1.01l0.28,0.91l-2.4,3.97l0.17,0.44l2.57,0.74l2.81,0.41l2.09,-0.44l0.14,-0.07l2.27,-2.06l0.09,-0.17l0.38,-2.2l0.88,-0.36l1.05,1.29l-0.04,1.88l-1.98,1.4l-1.72,1.13l-2.84,2.65l-3.34,3.73l-0.07,0.12l-0.63,2.22l-0.67,2.85l0.02,2.73l-0.47,0.54l-0.07,0.17l-0.36,3.28l0.12,0.27l3.03,2.32l-0.31,1.78l0.11,0.29l1.44,1.15l-0.11,1.17l-2.32,3.57l-3.59,1.51l-4.95,0.6l-2.72,-0.29l-0.32,0.38l0.5,1.67l-0.49,2.13l0.01,0.16l0.4,1.29l-1.27,0.88l-2.41,0.39l-2.33,-1.05l-0.31,0.04l-0.97,0.78l-0.11,0.27l0.35,2.98l0.16,0.23l1.69,0.91l0.31,-0.02l1.08,-0.75l0.46,0.96l-2.1,0.88l-2.01,1.89l-0.09,0.18l-0.36,3.05l-0.51,1.42l-2.16,0.01l-0.19,0.07l-1.96,1.59l-0.1,0.15l-0.72,2.34l0.08,0.31l2.46,2.31l0.13,0.07l2.09,0.56l-0.74,2.45l-2.86,1.75l-0.12,0.14l-1.59,3.71l-2.2,1.24l-0.1,0.09l-1.03,1.54l-0.04,0.23l0.81,3.45l0.06,0.13l1.13,1.32l-2.59,-0.57l-5.89,-0.44l-0.92,-1.73l0.05,-2.4l-0.34,-0.3l-1.49,0.19l-0.72,-0.98l-0.2,-3.21l1.79,-1.33l0.1,-0.13l0.79,-2.04l0.02,-0.16l-0.27,-1.52l1.31,-2.69l0.91,-4.15l-0.23,-1.72l0.91,-0.49l0.15,-0.33l-0.27,-1.16l-0.15,-0.2l-0.87,-0.46l0.65,-1.01l-0.04,-0.37l-1.06,-1.09l-0.54,-3.2l0.83,-0.51l0.14,-0.29l-0.42,-3.6l0.58,-2.98l0.64,-2.5l1.41,-1.0l0.12,-0.32l-0.75,-2.8l-0.01,-2.48l1.81,-1.78l0.09,-0.22l-0.06,-2.3l1.39,-2.69l0.03,-0.14l0.01,-2.58l-0.11,-0.24l-0.57,-0.45l-1.1,-4.59l1.49,-2.73l0.04,-0.17l-0.23,-2.59l0.86,-2.38l1.6,-2.48l1.74,-1.65l0.04,-0.39l-0.64,-0.89l0.42,-0.7l0.04,-0.16l-0.08,-4.26l2.55,-1.23l0.16,-0.18l0.86,-2.75l-0.01,-0.22l-0.22,-0.48l1.84,-2.1l3.0,0.59ZM256.77,438.98l-2.1,0.15l-1.18,-1.14l-0.19,-0.08l-1.53,-0.09l-2.38,-0.0l-0.0,-6.28l0.4,0.65l1.25,2.55l0.11,0.12l3.26,2.07l3.19,0.8l-0.82,1.26Z\", \"name\": \"Argentina\"}, \"AU\": {\"path\": \"M705.55,353.06l0.09,0.09l0.37,0.05l0.13,-0.35l-0.57,-1.69l0.48,0.3l0.71,0.99l0.34,0.11l0.2,-0.29l-0.04,-1.37l-0.04,-0.14l-1.22,-2.07l-0.28,-0.9l-0.51,-0.69l0.24,-1.33l0.52,-0.7l0.34,-1.32l0.01,-0.13l-0.25,-1.44l0.51,-0.94l0.1,1.03l0.23,0.26l0.32,-0.14l1.01,-1.72l1.94,-0.84l1.27,-1.14l1.84,-0.92l1.0,-0.18l0.6,0.28l0.26,-0.0l1.94,-0.96l1.48,-0.28l0.19,-0.13l0.32,-0.49l0.51,-0.18l1.42,0.05l2.63,-0.76l0.11,-0.06l1.36,-1.15l0.08,-0.1l0.61,-1.33l1.42,-1.27l0.1,-0.19l0.11,-1.03l0.06,-1.32l1.39,-1.74l0.85,1.79l0.4,0.14l1.07,-0.51l0.11,-0.45l-0.77,-1.05l0.53,-0.84l0.86,0.43l0.43,-0.22l0.29,-1.85l1.29,-1.19l0.6,-0.98l1.16,-0.4l0.2,-0.27l0.02,-0.34l0.74,0.2l0.38,-0.27l0.03,-0.44l1.98,-0.61l1.7,1.08l1.36,1.48l0.22,0.1l1.55,0.02l1.57,0.24l0.33,-0.4l-0.48,-1.27l1.09,-1.86l1.06,-0.63l0.1,-0.42l-0.28,-0.46l0.93,-1.24l1.36,-0.8l1.16,0.27l0.14,0.0l2.1,-0.48l0.23,-0.3l-0.05,-1.3l-0.18,-0.26l-1.08,-0.49l0.44,-0.12l1.52,0.58l1.39,1.06l2.11,0.65l0.19,-0.0l0.59,-0.21l1.44,0.72l0.27,0.0l1.37,-0.68l0.84,0.2l0.26,-0.06l0.37,-0.3l0.82,0.89l-0.56,1.14l-0.84,0.91l-0.75,0.07l-0.26,0.38l0.26,0.9l-0.67,1.15l-0.88,1.24l-0.05,0.25l0.18,0.72l0.12,0.17l1.99,1.42l1.96,0.84l1.25,0.86l1.8,1.51l0.19,0.07l0.63,-0.0l1.15,0.58l0.34,0.7l0.17,0.15l2.39,0.88l0.24,-0.02l1.65,-0.88l0.14,-0.16l0.49,-1.37l0.52,-1.19l0.31,-1.39l0.75,-2.02l0.01,-0.19l-0.33,-1.16l0.16,-0.67l0.0,-0.13l-0.28,-1.41l0.3,-1.78l0.42,-0.45l0.05,-0.33l-0.33,-0.73l0.56,-1.25l0.48,-1.39l0.07,-0.69l0.58,-0.59l0.48,0.84l0.17,1.53l0.17,0.24l0.47,0.23l0.09,0.9l0.05,0.14l0.87,1.23l0.17,1.33l-0.09,0.89l0.03,0.15l0.9,2.0l0.43,0.13l1.38,-0.83l0.71,0.92l1.06,0.88l-0.22,0.96l0.0,0.14l0.53,2.2l0.38,1.3l0.15,0.18l0.52,0.26l0.62,2.01l-0.23,1.27l0.02,0.18l0.81,1.76l0.14,0.14l2.69,1.35l3.21,2.21l-0.2,0.4l0.04,0.34l1.39,1.6l0.95,2.78l0.43,0.16l0.79,-0.46l0.85,0.96l0.39,0.05l0.22,-0.15l0.36,2.33l0.09,0.18l1.78,1.63l1.16,1.01l1.9,2.1l0.67,2.05l0.06,1.47l-0.17,1.64l0.03,0.17l1.16,2.22l-0.14,2.28l-0.43,1.24l-0.68,2.44l0.04,1.63l-0.48,1.92l-1.06,2.43l-1.79,1.32l-0.1,0.12l-0.91,2.15l-0.82,1.37l-0.76,2.47l-0.98,1.46l-0.63,2.14l-0.33,2.02l0.1,0.82l-1.21,0.85l-2.71,0.1l-0.13,0.03l-2.31,1.19l-1.21,1.17l-1.34,1.11l-1.89,-1.18l-1.33,-0.46l0.32,-1.24l-0.4,-0.35l-1.46,0.61l-2.06,1.98l-1.99,-0.73l-1.43,-0.46l-1.45,-0.22l-2.32,-0.81l-1.51,-1.67l-0.45,-2.11l-0.6,-1.5l-0.07,-0.11l-1.23,-1.16l-0.16,-0.08l-1.96,-0.28l0.59,-0.99l0.03,-0.24l-0.61,-2.1l-0.54,-0.08l-1.16,1.85l-1.23,0.29l0.73,-0.88l0.06,-0.12l0.37,-1.57l0.93,-1.33l0.05,-0.2l-0.2,-2.07l-0.53,-0.17l-2.01,2.35l-1.52,0.94l-0.12,0.14l-0.82,1.93l-1.5,-0.9l0.07,-1.32l-0.06,-0.2l-1.57,-2.04l-1.15,-0.92l0.3,-0.41l-0.1,-0.44l-3.21,-1.69l-0.13,-0.03l-1.69,-0.08l-2.35,-1.31l-0.16,-0.04l-4.55,0.27l-3.24,0.99l-2.8,0.91l-2.33,-0.18l-0.17,0.03l-2.63,1.41l-2.14,0.64l-0.2,0.19l-0.47,1.42l-0.8,0.99l-1.99,0.06l-1.55,0.24l-2.27,-0.5l-1.79,0.3l-1.71,0.13l-0.19,0.09l-1.38,1.39l-0.58,-0.1l-0.21,0.04l-1.26,0.8l-1.13,0.85l-1.72,-0.1l-1.6,-0.0l-2.58,-1.76l-1.21,-0.49l0.04,-1.19l1.04,-0.32l0.16,-0.12l0.42,-0.64l0.05,-0.19l-0.09,-0.97l0.3,-2.0l-0.28,-1.64l-1.34,-2.84l-0.39,-1.49l0.1,-1.51l-0.04,-0.17l-0.96,-1.72l-0.06,-0.73l-0.09,-0.19l-1.04,-1.01l-0.3,-2.02l-0.05,-0.12l-1.23,-1.83ZM784.95,393.35l2.39,1.01l0.2,0.01l3.26,-0.96l1.19,0.16l0.16,3.19l-0.78,0.95l-0.07,0.16l-0.19,1.83l-0.43,-0.41l-0.44,0.03l-1.61,1.96l-0.4,-0.12l-1.38,-0.09l-1.43,-2.42l-0.37,-2.03l-1.4,-2.53l0.04,-0.94l1.27,0.2Z\", \"name\": \"Australia\"}, \"IL\": {\"path\": \"M509.04,199.22l0.71,0.0l0.27,-0.17l0.15,-0.33l0.19,-0.01l0.02,0.73l-0.27,0.34l0.02,0.08l-0.32,0.62l-0.65,-0.27l-0.41,0.19l-0.52,1.85l0.16,0.35l0.14,0.07l-0.17,0.1l-0.14,0.21l-0.11,0.73l0.39,0.33l0.81,-0.26l0.03,0.64l-0.97,3.43l-1.28,-3.67l0.62,-0.78l-0.03,-0.41l0.58,-1.16l0.5,-2.07l0.27,-0.54Z\", \"name\": \"Israel\"}, \"IN\": {\"path\": \"M615.84,192.58l2.4,2.97l-0.24,2.17l0.05,0.2l0.94,1.35l-0.06,0.97l-1.46,-0.3l-0.35,0.36l0.7,3.06l0.12,0.18l2.46,1.75l3.11,1.72l-1.23,0.96l-0.1,0.13l-0.97,2.55l0.16,0.38l2.41,1.02l2.37,1.33l3.27,1.52l3.43,0.37l1.37,1.3l0.17,0.08l1.92,0.25l3.0,0.62l2.15,-0.04l0.28,-0.22l0.29,-1.06l0.0,-0.13l-0.32,-1.66l0.16,-0.94l1.0,-0.37l0.23,2.28l0.18,0.24l2.28,1.02l0.2,0.02l1.52,-0.41l2.06,0.18l2.08,-0.08l0.29,-0.27l0.18,-1.66l-0.1,-0.26l-0.53,-0.44l1.38,-0.23l0.15,-0.07l2.26,-2.0l2.75,-1.65l1.97,0.63l0.25,-0.03l1.54,-0.99l0.89,1.28l-0.72,0.97l0.2,0.48l2.49,0.37l0.11,0.61l-0.69,0.39l-0.15,0.3l0.15,1.22l-1.36,-0.37l-0.23,0.03l-3.24,1.86l-0.15,0.28l0.07,1.44l-1.33,2.16l-0.04,0.13l-0.12,1.24l-0.98,1.91l-1.72,-0.53l-0.39,0.28l-0.09,2.66l-0.52,0.83l-0.04,0.23l0.21,0.89l-0.71,0.36l-1.21,-3.85l-0.29,-0.21l-0.69,0.01l-0.29,0.23l-0.28,1.17l-0.84,-0.84l0.6,-1.17l0.97,-0.13l0.23,-0.16l1.15,-2.25l-0.18,-0.42l-1.54,-0.47l-2.3,0.04l-2.13,-0.33l-0.19,-1.63l-0.26,-0.26l-1.13,-0.13l-1.93,-1.13l-0.42,0.13l-0.88,1.82l0.08,0.37l1.47,1.15l-1.21,0.77l-0.1,0.1l-0.56,0.97l0.13,0.42l1.31,0.61l-0.36,1.35l0.01,0.2l0.85,1.95l0.37,2.05l-0.26,0.68l-1.55,-0.02l-3.09,0.54l-0.25,0.32l0.13,1.84l-1.21,1.4l-3.64,1.79l-2.79,3.04l-1.86,1.61l-2.48,1.68l-0.13,0.25l-0.0,1.0l-1.07,0.55l-2.21,0.9l-1.13,0.13l-0.25,0.19l-0.75,1.96l-0.02,0.15l0.52,3.31l0.13,2.03l-1.03,2.35l-0.03,0.12l-0.01,4.03l-1.02,0.1l-0.23,0.15l-1.14,1.93l0.04,0.36l0.44,0.48l-1.83,0.57l-0.18,0.15l-0.81,1.65l-0.74,0.53l-2.14,-2.12l-1.14,-3.47l-0.96,-2.57l-0.9,-1.26l-1.3,-2.38l-0.61,-3.14l-0.44,-1.62l-2.29,-3.56l-1.03,-4.94l-0.74,-3.29l0.01,-3.12l-0.49,-2.51l-0.41,-0.22l-3.56,1.53l-1.59,-0.28l-2.96,-2.87l0.94,-0.74l0.06,-0.41l-0.74,-1.03l-2.73,-2.1l1.35,-1.43l5.38,0.01l0.29,-0.36l-0.5,-2.29l-0.09,-0.15l-1.33,-1.28l-0.27,-1.96l-0.12,-0.2l-1.36,-1.0l2.42,-2.48l2.77,0.2l0.24,-0.1l2.62,-2.85l1.59,-2.8l2.41,-2.74l0.07,-0.2l-0.04,-1.82l2.01,-1.51l-0.01,-0.49l-1.95,-1.33l-0.83,-1.81l-0.82,-2.27l0.98,-0.97l3.64,0.66l2.89,-0.42l0.17,-0.08l2.18,-2.15Z\", \"name\": \"India\"}, \"TZ\": {\"path\": \"M505.77,287.58l0.36,0.23l8.95,5.03l0.15,1.3l0.13,0.21l3.4,2.37l-1.07,2.88l-0.02,0.14l0.15,1.42l0.15,0.23l1.47,0.84l0.05,0.42l-0.66,1.44l-0.02,0.18l0.13,0.72l-0.16,1.16l0.03,0.19l0.87,1.57l1.03,2.48l0.12,0.14l0.53,0.32l-1.59,1.18l-2.64,0.95l-1.45,-0.04l-0.2,0.07l-0.81,0.69l-1.64,0.06l-0.68,0.3l-2.9,-0.69l-1.71,0.17l-0.65,-3.18l-0.05,-0.12l-1.35,-1.88l-0.19,-0.12l-2.41,-0.46l-1.38,-0.74l-1.63,-0.44l-0.96,-0.41l-0.95,-0.58l-1.31,-3.09l-1.47,-1.46l-0.45,-1.31l0.24,-1.34l-0.39,-1.99l0.71,-0.08l0.18,-0.09l0.91,-0.91l0.98,-1.31l0.59,-0.5l0.11,-0.24l-0.02,-0.81l-0.08,-0.2l-0.47,-0.5l-0.1,-0.67l0.51,-0.23l0.18,-0.25l0.14,-1.47l-0.05,-0.2l-0.76,-1.09l0.45,-0.15l2.71,0.03l5.01,-0.19Z\", \"name\": \"Tanzania\"}, \"AZ\": {\"path\": \"M539.36,175.66l0.16,0.09l1.11,0.2l0.32,-0.15l0.4,-0.71l1.22,-0.99l1.11,1.33l1.26,2.09l0.22,0.14l1.06,0.13l0.28,0.29l-1.46,0.17l-0.26,0.24l-0.43,2.26l-0.39,0.92l-0.85,0.63l-0.12,0.25l0.06,1.2l-0.22,0.05l-1.28,-1.25l0.74,-1.25l-0.03,-0.35l-0.74,-0.86l-0.3,-0.1l-1.05,0.27l-2.49,1.82l-0.04,-1.46l-0.18,-0.27l-1.09,-0.47l-0.8,-0.6l0.53,-0.7l-0.06,-0.42l-1.11,-0.84l0.34,-0.51l-0.11,-0.43l-0.89,-0.48l-0.33,-0.49l0.25,-0.2l1.78,0.81l1.35,0.18l0.25,-0.09l0.34,-0.35l0.02,-0.39l-1.04,-1.36l0.28,-0.18l0.49,0.07l1.65,1.74ZM533.53,180.16l0.63,0.67l0.22,0.09l0.8,-0.0l0.04,0.31l0.66,1.09l-0.94,-0.21l-1.16,-1.24l-0.25,-0.71Z\", \"name\": \"Azerbaijan\"}, \"IE\": {\"path\": \"M405.17,135.35l0.36,2.16l-1.78,2.84l-4.28,1.91l-3.02,-0.43l1.81,-3.13l0.02,-0.26l-1.23,-3.26l3.24,-2.56l1.54,-1.32l0.37,1.33l-0.49,1.77l0.3,0.38l1.49,-0.05l1.68,0.63Z\", \"name\": \"Ireland\"}, \"ID\": {\"path\": \"M756.56,287.86l0.69,4.02l0.15,0.21l2.59,1.5l0.39,-0.07l2.05,-2.61l2.75,-1.45l2.09,-0.0l2.08,0.85l1.85,0.89l2.52,0.46l0.08,15.44l-1.72,-1.6l-0.15,-0.07l-2.54,-0.51l-0.29,0.1l-0.53,0.62l-2.53,0.06l0.78,-1.51l1.48,-0.66l0.17,-0.34l-0.65,-2.74l-1.23,-2.19l-0.14,-0.13l-4.85,-2.13l-2.09,-0.23l-3.7,-2.28l-0.41,0.1l-0.67,1.11l-0.63,0.14l-0.41,-0.67l-0.01,-1.01l-0.14,-0.25l-1.39,-0.89l2.05,-0.69l1.73,0.05l0.29,-0.39l-0.21,-0.66l-0.29,-0.21l-3.5,-0.0l-0.9,-1.36l-0.19,-0.13l-2.14,-0.44l-0.65,-0.76l2.86,-0.51l1.28,-0.79l3.75,0.96l0.32,0.76ZM758.01,300.37l-0.79,1.04l-0.14,-1.07l0.4,-0.81l0.29,-0.47l0.24,0.31l-0.0,1.0ZM747.45,292.9l0.48,1.02l-1.45,-0.69l-2.09,-0.21l-1.45,0.16l-1.28,-0.07l0.35,-0.81l2.86,-0.1l2.58,0.68ZM741.15,285.69l-0.16,-0.25l-0.72,-3.08l0.47,-1.86l0.35,-0.38l0.1,0.73l0.25,0.26l1.28,0.19l0.18,0.78l-0.11,1.8l-0.96,-0.18l-0.35,0.22l-0.38,1.52l0.05,0.24ZM741.19,285.75l0.76,0.97l-0.11,0.05l-0.65,-1.02ZM739.18,293.52l-0.61,0.54l-1.44,-0.38l-0.25,-0.55l1.93,-0.09l0.36,0.48ZM728.4,295.87l-0.27,-0.07l-2.26,0.89l-0.37,-0.41l0.27,-0.8l-0.09,-0.33l-1.68,-1.37l0.17,-2.29l-0.42,-0.3l-1.67,0.76l-0.17,0.29l0.21,2.92l0.09,3.34l-1.22,0.28l-0.78,-0.54l0.65,-2.1l0.01,-0.14l-0.39,-2.42l-0.29,-0.25l-0.86,-0.02l-0.63,-1.4l0.99,-1.61l0.35,-1.97l1.24,-3.73l0.49,-0.96l1.95,-1.7l1.86,0.69l3.16,0.35l2.92,-0.1l0.17,-0.06l2.24,-1.65l0.11,0.14l-1.8,2.22l-1.72,0.44l-2.41,-0.48l-4.21,0.13l-2.19,0.36l-0.25,0.24l-0.36,1.9l0.08,0.27l2.24,2.23l0.4,0.02l1.29,-1.08l3.19,-0.58l-0.19,0.06l-1.04,1.4l-2.13,0.94l-0.12,0.45l2.26,3.06l-0.37,0.69l0.03,0.32l1.51,1.95ZM728.48,295.97l0.59,0.76l-0.02,1.37l-1.0,0.55l-0.64,-0.58l1.09,-1.84l-0.02,-0.26ZM728.64,286.95l0.79,-0.14l-0.07,0.39l-0.72,-0.24ZM732.38,310.1l-1.89,0.49l-0.06,-0.06l0.17,-0.64l1.0,-1.42l2.14,-0.87l0.1,0.2l0.04,0.58l-1.49,1.72ZM728.26,305.71l-0.17,0.63l-3.53,0.67l-3.02,-0.28l-0.0,-0.42l1.66,-0.44l1.47,0.71l0.16,0.03l1.75,-0.21l1.69,-0.69ZM722.98,310.33l-0.74,0.03l-2.52,-1.35l1.42,-0.3l1.19,0.7l0.72,0.63l-0.06,0.28ZM716.24,305.63l0.66,0.49l0.22,0.06l1.35,-0.18l0.31,0.53l-4.18,0.77l-0.8,-0.01l0.51,-0.86l1.2,-0.02l0.24,-0.12l0.49,-0.65ZM715.84,280.21l0.09,0.34l2.25,1.86l-2.25,0.22l-0.24,0.17l-0.84,1.71l-0.03,0.15l0.1,2.11l-2.27,1.62l-0.13,0.24l-0.06,2.46l-0.74,2.92l-0.02,-0.05l-0.39,-0.16l-2.62,1.04l-0.86,-1.33l-0.23,-0.14l-1.71,-0.14l-1.19,-0.76l-0.25,-0.03l-2.78,0.84l-0.79,-1.05l-0.26,-0.12l-1.61,0.13l-1.8,-0.25l-0.36,-3.13l-0.15,-0.23l-1.18,-0.65l-1.13,-2.02l-0.33,-2.1l0.27,-2.19l1.05,-1.17l0.28,1.12l0.1,0.16l1.71,1.41l0.28,0.05l1.55,-0.49l1.54,0.17l0.23,-0.07l1.4,-1.21l1.05,-0.19l2.3,0.68l0.16,0.0l2.04,-0.53l0.21,-0.19l1.26,-3.41l0.91,-0.82l0.09,-0.14l0.8,-2.64l2.63,0.0l1.71,0.33l-1.19,1.89l0.02,0.34l1.74,2.24l-0.37,1.0ZM692.67,302.0l0.26,0.19l4.8,0.25l0.28,-0.16l0.44,-0.83l4.29,1.12l0.85,1.52l0.23,0.15l3.71,0.45l2.37,1.15l-2.06,0.69l-2.77,-1.0l-2.25,0.07l-2.57,-0.18l-2.31,-0.45l-2.94,-0.97l-1.84,-0.25l-0.13,0.01l-0.97,0.29l-4.34,-0.98l-0.38,-0.94l-0.25,-0.19l-1.76,-0.14l1.31,-1.84l2.81,0.14l1.97,0.96l0.95,0.19l0.28,0.74ZM685.63,299.27l-2.36,0.04l-2.07,-2.05l-3.17,-2.02l-1.06,-1.5l-1.88,-2.02l-1.22,-1.85l-1.9,-3.49l-2.2,-2.11l-0.71,-2.08l-0.94,-1.99l-0.1,-0.12l-2.21,-1.54l-1.35,-2.17l-1.86,-1.39l-2.53,-2.68l-0.14,-0.81l1.22,0.08l3.76,0.47l2.16,2.4l1.94,1.7l1.37,1.04l2.35,2.67l0.22,0.1l2.44,0.04l1.99,1.62l1.42,2.06l0.09,0.09l1.67,1.0l-0.88,1.8l0.11,0.39l1.44,0.87l0.13,0.04l0.68,0.05l0.41,1.62l0.87,1.4l0.22,0.14l1.71,0.21l1.06,1.38l-0.61,3.04l-0.09,3.6Z\", \"name\": \"Indonesia\"}, \"UA\": {\"path\": \"M500.54,141.42l0.9,0.13l0.27,-0.11l0.52,-0.62l0.68,0.13l2.43,-0.3l1.32,1.57l-0.45,0.48l-0.07,0.26l0.21,1.03l0.27,0.24l1.85,0.15l0.76,1.22l-0.05,0.55l0.2,0.31l3.18,1.15l0.18,0.01l1.75,-0.47l1.42,1.41l0.22,0.09l1.42,-0.03l3.44,0.99l0.02,0.65l-0.97,1.62l-0.03,0.24l0.52,1.67l-0.29,0.79l-2.24,0.22l-0.14,0.05l-1.29,0.89l-0.13,0.23l-0.07,1.16l-1.75,0.22l-0.12,0.04l-1.6,0.98l-2.27,0.16l-0.12,0.04l-2.16,1.17l-0.16,0.29l0.15,1.94l0.14,0.23l1.23,0.75l0.18,0.04l2.06,-0.15l-0.22,0.51l-2.67,0.54l-3.27,1.72l-1.0,-0.45l0.45,-1.19l-0.19,-0.39l-2.34,-0.78l0.15,-0.2l2.32,-1.0l0.09,-0.49l-0.73,-0.72l-0.15,-0.08l-3.69,-0.75l-0.14,-0.96l-0.35,-0.25l-2.32,0.39l-0.21,0.15l-0.91,1.7l-1.77,2.1l-0.93,-0.44l-0.24,-0.0l-1.05,0.45l-0.48,-0.25l0.13,-0.07l0.14,-0.15l0.43,-1.04l0.67,-0.97l0.04,-0.26l-0.1,-0.31l0.04,-0.02l0.11,0.19l0.24,0.15l1.48,0.09l0.78,-0.25l0.07,-0.53l-0.27,-0.19l0.09,-0.25l-0.08,-0.33l-0.81,-0.74l-0.34,-1.24l-0.14,-0.18l-0.73,-0.42l0.15,-0.87l-0.11,-0.29l-1.13,-0.86l-0.15,-0.06l-0.97,-0.11l-1.79,-0.97l-0.2,-0.03l-1.66,0.32l-0.13,0.06l-0.52,0.41l-0.95,-0.0l-0.23,0.11l-0.56,0.66l-1.74,0.29l-0.79,0.43l-1.01,-0.68l-0.16,-0.05l-1.57,-0.01l-1.52,-0.35l-0.23,0.04l-0.71,0.45l-0.09,-0.43l-0.13,-0.19l-1.18,-0.74l0.38,-1.02l0.53,-0.64l0.35,0.12l0.37,-0.41l-0.57,-1.29l2.1,-2.5l1.16,-0.36l0.2,-0.2l0.27,-0.92l-0.01,-0.2l-1.1,-2.52l0.79,-0.09l0.13,-0.05l1.3,-0.86l1.83,-0.07l2.48,0.26l2.84,0.8l1.91,0.06l0.88,0.45l0.29,-0.01l0.72,-0.44l0.49,0.58l0.25,0.11l2.2,-0.16l0.94,0.3l0.39,-0.26l0.15,-1.57l0.61,-0.59l2.01,-0.19Z\", \"name\": \"Ukraine\"}, \"QA\": {\"path\": \"M548.47,221.47l-0.15,-1.72l0.59,-1.23l0.38,-0.16l0.54,0.6l0.04,1.4l-0.47,1.37l-0.41,0.11l-0.53,-0.37Z\", \"name\": \"Qatar\"}, \"MZ\": {\"path\": \"M507.71,314.14l1.65,-0.18l2.96,0.7l0.2,-0.02l0.6,-0.29l1.68,-0.06l0.18,-0.07l0.8,-0.69l1.5,0.02l2.74,-0.98l1.74,-1.27l0.25,0.7l-0.1,2.47l0.31,2.27l0.1,3.97l0.42,1.24l-0.7,1.71l-0.94,1.73l-1.52,1.52l-5.06,2.21l-2.88,2.8l-1.01,0.51l-1.72,1.81l-0.99,0.58l-0.15,0.23l-0.21,1.86l0.04,0.19l1.17,1.95l0.47,1.47l0.03,0.74l0.39,0.28l0.05,-0.01l-0.06,2.13l-0.39,1.19l0.1,0.33l0.42,0.32l-0.28,0.83l-0.95,0.86l-2.03,0.88l-3.08,1.49l-1.1,0.99l-0.09,0.28l0.21,1.13l0.21,0.23l0.38,0.11l-0.14,0.89l-1.39,-0.02l-0.17,-0.94l-0.38,-1.23l-0.2,-0.89l0.44,-2.91l-0.01,-0.14l-0.65,-1.88l-1.15,-3.55l2.52,-2.85l0.68,-1.89l0.29,-0.18l0.14,-0.2l0.28,-1.53l-0.03,-0.19l-0.36,-0.7l0.1,-1.83l0.49,-1.84l-0.01,-3.26l-0.14,-0.25l-1.3,-0.83l-0.11,-0.04l-1.08,-0.17l-0.47,-0.55l-0.1,-0.08l-1.16,-0.54l-0.13,-0.03l-1.83,0.04l-0.32,-2.25l7.19,-1.99l1.32,1.12l0.29,0.06l0.55,-0.19l0.75,0.49l0.11,0.81l-0.49,1.11l-0.02,0.15l0.19,1.81l0.09,0.18l1.63,1.59l0.48,-0.1l0.72,-1.68l0.99,-0.49l0.17,-0.29l-0.21,-3.29l-0.04,-0.13l-1.11,-1.92l-0.9,-0.82l-0.21,-0.08l-0.62,0.03l-0.63,-2.98l0.61,-1.67Z\", \"name\": \"Mozambique\"}}, \"height\": 440.7063107441331, \"projection\": {\"type\": \"mill\", \"centralMeridian\": 11.5}, \"width\": 900.0});"
  },
  {
    "path": "public/static/plugins/knob/jquery.knob.js",
    "content": "/*!jQuery Knob*/\n/**\n * Downward compatible, touchable dial\n *\n * Version: 1.2.11\n * Requires: jQuery v1.7+\n *\n * Copyright (c) 2012 Anthony Terrien\n * Under MIT License (http://www.opensource.org/licenses/mit-license.php)\n *\n * Thanks to vor, eskimoblood, spiffistan, FabrizioC\n */\n(function (factory) {\n    if (typeof exports === 'object') {\n        // CommonJS\n        module.exports = factory(require('jquery'));\n    } else if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(['jquery'], factory);\n    } else {\n        // Browser globals\n        factory(jQuery);\n    }\n}(function ($) {\n\n    /**\n     * Kontrol library\n     */\n    \"use strict\";\n\n    /**\n     * Definition of globals and core\n     */\n    var k = {}, // kontrol\n        max = Math.max,\n        min = Math.min;\n\n    k.c = {};\n    k.c.d = $(document);\n    k.c.t = function (e) {\n        return e.originalEvent.touches.length - 1;\n    };\n\n    /**\n     * Kontrol Object\n     *\n     * Definition of an abstract UI control\n     *\n     * Each concrete component must call this one.\n     * <code>\n     * k.o.call(this);\n     * </code>\n     */\n    k.o = function () {\n        var s = this;\n\n        this.o = null; // array of options\n        this.$ = null; // jQuery wrapped element\n        this.i = null; // mixed HTMLInputElement or array of HTMLInputElement\n        this.g = null; // deprecated 2D graphics context for 'pre-rendering'\n        this.v = null; // value ; mixed array or integer\n        this.cv = null; // change value ; not commited value\n        this.x = 0; // canvas x position\n        this.y = 0; // canvas y position\n        this.w = 0; // canvas width\n        this.h = 0; // canvas height\n        this.$c = null; // jQuery canvas element\n        this.c = null; // rendered canvas context\n        this.t = 0; // touches index\n        this.isInit = false;\n        this.fgColor = null; // main color\n        this.pColor = null; // previous color\n        this.dH = null; // draw hook\n        this.cH = null; // change hook\n        this.eH = null; // cancel hook\n        this.rH = null; // release hook\n        this.scale = 1; // scale factor\n        this.relative = false;\n        this.relativeWidth = false;\n        this.relativeHeight = false;\n        this.$div = null; // component div\n\n        this.run = function () {\n            var cf = function (e, conf) {\n                var k;\n                for (k in conf) {\n                    s.o[k] = conf[k];\n                }\n                s._carve().init();\n                s._configure()\n                 ._draw();\n            };\n\n            if (this.$.data('kontroled')) return;\n            this.$.data('kontroled', true);\n\n            this.extend();\n            this.o = $.extend({\n                    // Config\n                    min: this.$.data('min') !== undefined ? this.$.data('min') : 0,\n                    max: this.$.data('max') !== undefined ? this.$.data('max') : 100,\n                    stopper: true,\n                    readOnly: this.$.data('readonly') || (this.$.attr('readonly') === 'readonly'),\n\n                    // UI\n                    cursor: this.$.data('cursor') === true && 30\n                            || this.$.data('cursor') || 0,\n                    thickness: this.$.data('thickness')\n                               && Math.max(Math.min(this.$.data('thickness'), 1), 0.01)\n                               || 0.35,\n                    lineCap: this.$.data('linecap') || 'butt',\n                    width: this.$.data('width') || 200,\n                    height: this.$.data('height') || 200,\n                    displayInput: this.$.data('displayinput') == null || this.$.data('displayinput'),\n                    displayPrevious: this.$.data('displayprevious'),\n                    fgColor: this.$.data('fgcolor') || '#87CEEB',\n                    inputColor: this.$.data('inputcolor'),\n                    font: this.$.data('font') || 'Arial',\n                    fontWeight: this.$.data('font-weight') || 'bold',\n                    inline: false,\n                    step: this.$.data('step') || 1,\n                    rotation: this.$.data('rotation'),\n\n                    // Hooks\n                    draw: null, // function () {}\n                    change: null, // function (value) {}\n                    cancel: null, // function () {}\n                    release: null, // function (value) {}\n\n                    // Output formatting, allows to add unit: %, ms ...\n                    format: function(v) {\n                        return v;\n                    },\n                    parse: function (v) {\n                        return parseFloat(v);\n                    }\n                }, this.o\n            );\n\n            // finalize options\n            this.o.flip = this.o.rotation === 'anticlockwise' || this.o.rotation === 'acw';\n            if (!this.o.inputColor) {\n                this.o.inputColor = this.o.fgColor;\n            }\n\n            // routing value\n            if (this.$.is('fieldset')) {\n\n                // fieldset = array of integer\n                this.v = {};\n                this.i = this.$.find('input');\n                this.i.each(function(k) {\n                    var $this = $(this);\n                    s.i[k] = $this;\n                    s.v[k] = s.o.parse($this.val());\n\n                    $this.bind(\n                        'change blur',\n                        function () {\n                            var val = {};\n                            val[k] = $this.val();\n                            s.val(s._validate(val));\n                        }\n                    );\n                });\n                this.$.find('legend').remove();\n            } else {\n\n                // input = integer\n                this.i = this.$;\n                this.v = this.o.parse(this.$.val());\n                this.v === '' && (this.v = this.o.min);\n                this.$.bind(\n                    'change blur',\n                    function () {\n                        s.val(s._validate(s.o.parse(s.$.val())));\n                    }\n                );\n\n            }\n\n            !this.o.displayInput && this.$.hide();\n\n            // adds needed DOM elements (canvas, div)\n            this.$c = $(document.createElement('canvas')).attr({\n                width: this.o.width,\n                height: this.o.height\n            });\n\n            // wraps all elements in a div\n            // add to DOM before Canvas init is triggered\n            this.$div = $('<div style=\"'\n                + (this.o.inline ? 'display:inline;' : '')\n                + 'width:' + this.o.width + 'px;height:' + this.o.height + 'px;'\n                + '\"></div>');\n\n            this.$.wrap(this.$div).before(this.$c);\n            this.$div = this.$.parent();\n\n            if (typeof G_vmlCanvasManager !== 'undefined') {\n                G_vmlCanvasManager.initElement(this.$c[0]);\n            }\n\n            this.c = this.$c[0].getContext ? this.$c[0].getContext('2d') : null;\n\n            if (!this.c) {\n                throw {\n                    name:        \"CanvasNotSupportedException\",\n                    message:     \"Canvas not supported. Please use excanvas on IE8.0.\",\n                    toString:    function(){return this.name + \": \" + this.message}\n                }\n            }\n\n            // hdpi support\n            this.scale = (window.devicePixelRatio || 1) / (\n                            this.c.webkitBackingStorePixelRatio ||\n                            this.c.mozBackingStorePixelRatio ||\n                            this.c.msBackingStorePixelRatio ||\n                            this.c.oBackingStorePixelRatio ||\n                            this.c.backingStorePixelRatio || 1\n                         );\n\n            // detects relative width / height\n            this.relativeWidth =  this.o.width % 1 !== 0\n                                  && this.o.width.indexOf('%');\n            this.relativeHeight = this.o.height % 1 !== 0\n                                  && this.o.height.indexOf('%');\n            this.relative = this.relativeWidth || this.relativeHeight;\n\n            // computes size and carves the component\n            this._carve();\n\n            // prepares props for transaction\n            if (this.v instanceof Object) {\n                this.cv = {};\n                this.copy(this.v, this.cv);\n            } else {\n                this.cv = this.v;\n            }\n\n            // binds configure event\n            this.$\n                .bind(\"configure\", cf)\n                .parent()\n                .bind(\"configure\", cf);\n\n            // finalize init\n            this._listen()\n                ._configure()\n                ._xy()\n                .init();\n\n            this.isInit = true;\n\n            this.$.val(this.o.format(this.v));\n            this._draw();\n\n            return this;\n        };\n\n        this._carve = function() {\n            if (this.relative) {\n                var w = this.relativeWidth ?\n                        this.$div.parent().width() *\n                        parseInt(this.o.width) / 100\n                        : this.$div.parent().width(),\n                    h = this.relativeHeight ?\n                        this.$div.parent().height() *\n                        parseInt(this.o.height) / 100\n                        : this.$div.parent().height();\n\n                // apply relative\n                this.w = this.h = Math.min(w, h);\n            } else {\n                this.w = this.o.width;\n                this.h = this.o.height;\n            }\n\n            // finalize div\n            this.$div.css({\n                'width': this.w + 'px',\n                'height': this.h + 'px'\n            });\n\n            // finalize canvas with computed width\n            this.$c.attr({\n                width: this.w,\n                height: this.h\n            });\n\n            // scaling\n            if (this.scale !== 1) {\n                this.$c[0].width = this.$c[0].width * this.scale;\n                this.$c[0].height = this.$c[0].height * this.scale;\n                this.$c.width(this.w);\n                this.$c.height(this.h);\n            }\n\n            return this;\n        }\n\n        this._draw = function () {\n\n            // canvas pre-rendering\n            var d = true;\n\n            s.g = s.c;\n\n            s.clear();\n\n            s.dH && (d = s.dH());\n\n            d !== false && s.draw();\n        };\n\n        this._touch = function (e) {\n            var touchMove = function (e) {\n                var v = s.xy2val(\n                            e.originalEvent.touches[s.t].pageX,\n                            e.originalEvent.touches[s.t].pageY\n                        );\n\n                if (v == s.cv) return;\n\n                if (s.cH && s.cH(v) === false) return;\n\n                s.change(s._validate(v));\n                s._draw();\n            };\n\n            // get touches index\n            this.t = k.c.t(e);\n\n            // First touch\n            touchMove(e);\n\n            // Touch events listeners\n            k.c.d\n                .bind(\"touchmove.k\", touchMove)\n                .bind(\n                    \"touchend.k\",\n                    function () {\n                        k.c.d.unbind('touchmove.k touchend.k');\n                        s.val(s.cv);\n                    }\n                );\n\n            return this;\n        };\n\n        this._mouse = function (e) {\n            var mouseMove = function (e) {\n                var v = s.xy2val(e.pageX, e.pageY);\n\n                if (v == s.cv) return;\n\n                if (s.cH && (s.cH(v) === false)) return;\n\n                s.change(s._validate(v));\n                s._draw();\n            };\n\n            // First click\n            mouseMove(e);\n\n            // Mouse events listeners\n            k.c.d\n                .bind(\"mousemove.k\", mouseMove)\n                .bind(\n                    // Escape key cancel current change\n                    \"keyup.k\",\n                    function (e) {\n                        if (e.keyCode === 27) {\n                            k.c.d.unbind(\"mouseup.k mousemove.k keyup.k\");\n\n                            if (s.eH && s.eH() === false)\n                                return;\n\n                            s.cancel();\n                        }\n                    }\n                )\n                .bind(\n                    \"mouseup.k\",\n                    function (e) {\n                        k.c.d.unbind('mousemove.k mouseup.k keyup.k');\n                        s.val(s.cv);\n                    }\n                );\n\n            return this;\n        };\n\n        this._xy = function () {\n            var o = this.$c.offset();\n            this.x = o.left;\n            this.y = o.top;\n\n            return this;\n        };\n\n        this._listen = function () {\n            if (!this.o.readOnly) {\n                this.$c\n                    .bind(\n                        \"mousedown\",\n                        function (e) {\n                            e.preventDefault();\n                            s._xy()._mouse(e);\n                        }\n                    )\n                    .bind(\n                        \"touchstart\",\n                        function (e) {\n                            e.preventDefault();\n                            s._xy()._touch(e);\n                        }\n                    );\n\n                this.listen();\n            } else {\n                this.$.attr('readonly', 'readonly');\n            }\n\n            if (this.relative) {\n                $(window).resize(function() {\n                    s._carve().init();\n                    s._draw();\n                });\n            }\n\n            return this;\n        };\n\n        this._configure = function () {\n\n            // Hooks\n            if (this.o.draw) this.dH = this.o.draw;\n            if (this.o.change) this.cH = this.o.change;\n            if (this.o.cancel) this.eH = this.o.cancel;\n            if (this.o.release) this.rH = this.o.release;\n\n            if (this.o.displayPrevious) {\n                this.pColor = this.h2rgba(this.o.fgColor, \"0.4\");\n                this.fgColor = this.h2rgba(this.o.fgColor, \"0.6\");\n            } else {\n                this.fgColor = this.o.fgColor;\n            }\n\n            return this;\n        };\n\n        this._clear = function () {\n            this.$c[0].width = this.$c[0].width;\n        };\n\n        this._validate = function (v) {\n            var val = (~~ (((v < 0) ? -0.5 : 0.5) + (v/this.o.step))) * this.o.step;\n            return Math.round(val * 100) / 100;\n        };\n\n        // Abstract methods\n        this.listen = function () {}; // on start, one time\n        this.extend = function () {}; // each time configure triggered\n        this.init = function () {}; // each time configure triggered\n        this.change = function (v) {}; // on change\n        this.val = function (v) {}; // on release\n        this.xy2val = function (x, y) {}; //\n        this.draw = function () {}; // on change / on release\n        this.clear = function () { this._clear(); };\n\n        // Utils\n        this.h2rgba = function (h, a) {\n            var rgb;\n            h = h.substring(1,7)\n            rgb = [\n                parseInt(h.substring(0,2), 16),\n                parseInt(h.substring(2,4), 16),\n                parseInt(h.substring(4,6), 16)\n            ];\n\n            return \"rgba(\" + rgb[0] + \",\" + rgb[1] + \",\" + rgb[2] + \",\" + a + \")\";\n        };\n\n        this.copy = function (f, t) {\n            for (var i in f) {\n                t[i] = f[i];\n            }\n        };\n    };\n\n\n    /**\n     * k.Dial\n     */\n    k.Dial = function () {\n        k.o.call(this);\n\n        this.startAngle = null;\n        this.xy = null;\n        this.radius = null;\n        this.lineWidth = null;\n        this.cursorExt = null;\n        this.w2 = null;\n        this.PI2 = 2*Math.PI;\n\n        this.extend = function () {\n            this.o = $.extend({\n                bgColor: this.$.data('bgcolor') || '#EEEEEE',\n                angleOffset: this.$.data('angleoffset') || 0,\n                angleArc: this.$.data('anglearc') || 360,\n                inline: true\n            }, this.o);\n        };\n\n        this.val = function (v, triggerRelease) {\n            if (null != v) {\n\n                // reverse format\n                v = this.o.parse(v);\n\n                if (triggerRelease !== false\n                    && v != this.v\n                    && this.rH\n                    && this.rH(v) === false) { return; }\n\n                this.cv = this.o.stopper ? max(min(v, this.o.max), this.o.min) : v;\n                this.v = this.cv;\n                this.$.val(this.o.format(this.v));\n                this._draw();\n            } else {\n                return this.v;\n            }\n        };\n\n        this.xy2val = function (x, y) {\n            var a, ret;\n\n            a = Math.atan2(\n                        x - (this.x + this.w2),\n                        - (y - this.y - this.w2)\n                    ) - this.angleOffset;\n\n            if (this.o.flip) {\n                a = this.angleArc - a - this.PI2;\n            }\n\n            if (this.angleArc != this.PI2 && (a < 0) && (a > -0.5)) {\n\n                // if isset angleArc option, set to min if .5 under min\n                a = 0;\n            } else if (a < 0) {\n                a += this.PI2;\n            }\n\n            ret = (a * (this.o.max - this.o.min) / this.angleArc) + this.o.min;\n\n            this.o.stopper && (ret = max(min(ret, this.o.max), this.o.min));\n\n            return ret;\n        };\n\n        this.listen = function () {\n\n            // bind MouseWheel\n            var s = this, mwTimerStop,\n                mwTimerRelease,\n                mw = function (e) {\n                    e.preventDefault();\n\n                    var ori = e.originalEvent,\n                        deltaX = ori.detail || ori.wheelDeltaX,\n                        deltaY = ori.detail || ori.wheelDeltaY,\n                        v = s._validate(s.o.parse(s.$.val()))\n                            + (\n                                deltaX > 0 || deltaY > 0\n                                ? s.o.step\n                                : deltaX < 0 || deltaY < 0 ? -s.o.step : 0\n                              );\n\n                    v = max(min(v, s.o.max), s.o.min);\n\n                    s.val(v, false);\n\n                    if (s.rH) {\n                        // Handle mousewheel stop\n                        clearTimeout(mwTimerStop);\n                        mwTimerStop = setTimeout(function () {\n                            s.rH(v);\n                            mwTimerStop = null;\n                        }, 100);\n\n                        // Handle mousewheel releases\n                        if (!mwTimerRelease) {\n                            mwTimerRelease = setTimeout(function () {\n                                if (mwTimerStop)\n                                    s.rH(v);\n                                mwTimerRelease = null;\n                            }, 200);\n                        }\n                    }\n                },\n                kval,\n                to,\n                m = 1,\n                kv = {\n                    37: -s.o.step,\n                    38: s.o.step,\n                    39: s.o.step,\n                    40: -s.o.step\n                };\n\n            this.$\n                .bind(\n                    \"keydown\",\n                    function (e) {\n                        var kc = e.keyCode;\n\n                        // numpad support\n                        if (kc >= 96 && kc <= 105) {\n                            kc = e.keyCode = kc - 48;\n                        }\n\n                        kval = parseInt(String.fromCharCode(kc));\n\n                        if (isNaN(kval)) {\n                            (kc !== 13)                     // enter\n                            && kc !== 8                     // bs\n                            && kc !== 9                     // tab\n                            && kc !== 189                   // -\n                            && (kc !== 190\n                                || s.$.val().match(/\\./))   // . allowed once\n                            && e.preventDefault();\n\n                            // arrows\n                            if ($.inArray(kc,[37,38,39,40]) > -1) {\n                                e.preventDefault();\n\n                                var v = s.o.parse(s.$.val()) + kv[kc] * m;\n                                s.o.stopper && (v = max(min(v, s.o.max), s.o.min));\n\n                                s.change(s._validate(v));\n                                s._draw();\n\n                                // long time keydown speed-up\n                                to = window.setTimeout(function () {\n                                    m *= 2;\n                                }, 30);\n                            }\n                        }\n                    }\n                )\n                .bind(\n                    \"keyup\",\n                    function (e) {\n                        if (isNaN(kval)) {\n                            if (to) {\n                                window.clearTimeout(to);\n                                to = null;\n                                m = 1;\n                                s.val(s.$.val());\n                            }\n                        } else {\n                            // kval postcond\n                            (s.$.val() > s.o.max && s.$.val(s.o.max))\n                            || (s.$.val() < s.o.min && s.$.val(s.o.min));\n                        }\n                    }\n                );\n\n            this.$c.bind(\"mousewheel DOMMouseScroll\", mw);\n            this.$.bind(\"mousewheel DOMMouseScroll\", mw)\n        };\n\n        this.init = function () {\n            if (this.v < this.o.min\n                || this.v > this.o.max) { this.v = this.o.min; }\n\n            this.$.val(this.v);\n            this.w2 = this.w / 2;\n            this.cursorExt = this.o.cursor / 100;\n            this.xy = this.w2 * this.scale;\n            this.lineWidth = this.xy * this.o.thickness;\n            this.lineCap = this.o.lineCap;\n            this.radius = this.xy - this.lineWidth / 2;\n\n            this.o.angleOffset\n            && (this.o.angleOffset = isNaN(this.o.angleOffset) ? 0 : this.o.angleOffset);\n\n            this.o.angleArc\n            && (this.o.angleArc = isNaN(this.o.angleArc) ? this.PI2 : this.o.angleArc);\n\n            // deg to rad\n            this.angleOffset = this.o.angleOffset * Math.PI / 180;\n            this.angleArc = this.o.angleArc * Math.PI / 180;\n\n            // compute start and end angles\n            this.startAngle = 1.5 * Math.PI + this.angleOffset;\n            this.endAngle = 1.5 * Math.PI + this.angleOffset + this.angleArc;\n\n            var s = max(\n                String(Math.abs(this.o.max)).length,\n                String(Math.abs(this.o.min)).length,\n                2\n            ) + 2;\n\n            this.o.displayInput\n                && this.i.css({\n                        'width' : ((this.w / 2 + 4) >> 0) + 'px',\n                        'height' : ((this.w / 3) >> 0) + 'px',\n                        'position' : 'absolute',\n                        'vertical-align' : 'middle',\n                        'margin-top' : ((this.w / 3) >> 0) + 'px',\n                        'margin-left' : '-' + ((this.w * 3 / 4 + 2) >> 0) + 'px',\n                        'border' : 0,\n                        'background' : 'none',\n                        'font' : this.o.fontWeight + ' ' + ((this.w / s) >> 0) + 'px ' + this.o.font,\n                        'text-align' : 'center',\n                        'color' : this.o.inputColor || this.o.fgColor,\n                        'padding' : '0px',\n                        '-webkit-appearance': 'none'\n                        }) || this.i.css({\n                            'width': '0px',\n                            'visibility': 'hidden'\n                        });\n        };\n\n        this.change = function (v) {\n            this.cv = v;\n            this.$.val(this.o.format(v));\n        };\n\n        this.angle = function (v) {\n            return (v - this.o.min) * this.angleArc / (this.o.max - this.o.min);\n        };\n\n        this.arc = function (v) {\n          var sa, ea;\n          v = this.angle(v);\n          if (this.o.flip) {\n              sa = this.endAngle + 0.00001;\n              ea = sa - v - 0.00001;\n          } else {\n              sa = this.startAngle - 0.00001;\n              ea = sa + v + 0.00001;\n          }\n          this.o.cursor\n              && (sa = ea - this.cursorExt)\n              && (ea = ea + this.cursorExt);\n\n          return {\n              s: sa,\n              e: ea,\n              d: this.o.flip && !this.o.cursor\n          };\n        };\n\n        this.draw = function () {\n            var c = this.g,                 // context\n                a = this.arc(this.cv),      // Arc\n                pa,                         // Previous arc\n                r = 1;\n\n            c.lineWidth = this.lineWidth;\n            c.lineCap = this.lineCap;\n\n            if (this.o.bgColor !== \"none\") {\n                c.beginPath();\n                    c.strokeStyle = this.o.bgColor;\n                    c.arc(this.xy, this.xy, this.radius, this.endAngle - 0.00001, this.startAngle + 0.00001, true);\n                c.stroke();\n            }\n\n            if (this.o.displayPrevious) {\n                pa = this.arc(this.v);\n                c.beginPath();\n                c.strokeStyle = this.pColor;\n                c.arc(this.xy, this.xy, this.radius, pa.s, pa.e, pa.d);\n                c.stroke();\n                r = this.cv == this.v;\n            }\n\n            c.beginPath();\n            c.strokeStyle = r ? this.o.fgColor : this.fgColor ;\n            c.arc(this.xy, this.xy, this.radius, a.s, a.e, a.d);\n            c.stroke();\n        };\n\n        this.cancel = function () {\n            this.val(this.v);\n        };\n    };\n\n    $.fn.dial = $.fn.knob = function (o) {\n        return this.each(\n            function () {\n                var d = new k.Dial();\n                d.o = o;\n                d.$ = $(this);\n                d.run();\n            }\n        ).parent();\n    };\n\n}));\n"
  },
  {
    "path": "public/static/plugins/layer/extend/layer.ext.js",
    "content": "/*! layer弹层组件拓展类 */\n;!function(){layer.use(\"skin/layer.ext.css\",function(){layer.layui_layer_extendlayerextjs=!0});var a=layer.cache||{},b=function(b){return a.skin?\" \"+a.skin+\" \"+a.skin+\"-\"+b:\"\"};layer.prompt=function(a,c){a=a||{},\"function\"==typeof a&&(c=a);var d,e=2==a.formType?'<textarea class=\"layui-layer-input\">'+(a.value||\"\")+\"</textarea>\":function(){return'<input type=\"'+(1==a.formType?\"password\":\"text\")+'\" class=\"layui-layer-input\" value=\"'+(a.value||\"\")+'\">'}();return layer.open($.extend({btn:[\"&#x786E;&#x5B9A;\",\"&#x53D6;&#x6D88;\"],content:e,skin:\"layui-layer-prompt\"+b(\"prompt\"),success:function(a){d=a.find(\".layui-layer-input\"),d.focus()},yes:function(b){var e=d.val();\"\"===e?d.focus():e.length>(a.maxlength||500)?layer.tips(\"&#x6700;&#x591A;&#x8F93;&#x5165;\"+(a.maxlength||500)+\"&#x4E2A;&#x5B57;&#x6570;\",d,{tips:1}):c&&c(e,b,d)}},a))},layer.tab=function(a){a=a||{};var c=a.tab||{};return layer.open($.extend({type:1,skin:\"layui-layer-tab\"+b(\"tab\"),title:function(){var a=c.length,b=1,d=\"\";if(a>0)for(d='<span class=\"layui-layer-tabnow\">'+c[0].title+\"</span>\";a>b;b++)d+=\"<span>\"+c[b].title+\"</span>\";return d}(),content:'<ul class=\"layui-layer-tabmain\">'+function(){var a=c.length,b=1,d=\"\";if(a>0)for(d='<li class=\"layui-layer-tabli xubox_tab_layer\">'+(c[0].content||\"no content\")+\"</li>\";a>b;b++)d+='<li class=\"layui-layer-tabli\">'+(c[b].content||\"no  content\")+\"</li>\";return d}()+\"</ul>\",success:function(a){var b=a.find(\".layui-layer-title\").children(),c=a.find(\".layui-layer-tabmain\").children();b.on(\"mousedown\",function(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0;var b=$(this),d=b.index();b.addClass(\"layui-layer-tabnow\").siblings().removeClass(\"layui-layer-tabnow\"),c.eq(d).show().siblings().hide()})}},a))},layer.photos=function(a,c,d){function e(a,b,c){var d=new Image;d.onload=function(){d.onload=null,b(d)},d.onerror=function(a){d.onload=null,c(a)},d.src=a}var f={};if(a=a||{},a.photos){var g=a.photos.constructor===Object,h=g?a.photos:{},i=h.data||[],j=h.start||0;if(f.imgIndex=j+1,g){if(0===i.length)return void layer.msg(\"&#x6CA1;&#x6709;&#x56FE;&#x7247;\")}else{var k=$(a.photos),l=k.find(a.img||\"img\");if(0===l.length)return;if(c||k.find(h.img||\"img\").each(function(b){var c=$(this);i.push({alt:c.attr(\"alt\"),pid:c.attr(\"layer-pid\"),src:c.attr(\"layer-src\")||c.attr(\"src\"),thumb:c.attr(\"src\")}),c.on(\"click\",function(){layer.photos($.extend(a,{photos:{start:b,data:i,tab:a.tab},full:a.full}),!0)})}),!c)return}f.imgprev=function(a){f.imgIndex--,f.imgIndex<1&&(f.imgIndex=i.length),f.tabimg(a)},f.imgnext=function(a){f.imgIndex++,f.imgIndex>i.length&&(f.imgIndex=1),f.tabimg(a)},f.keyup=function(a){if(!f.end){var b=a.keyCode;a.preventDefault(),37===b?f.imgprev(!0):39===b?f.imgnext(!0):27===b&&layer.close(f.index)}},f.tabimg=function(b){i.length<=1||(h.start=f.imgIndex-1,layer.close(f.index),layer.photos(a,!0,b))},f.event=function(){f.bigimg.hover(function(){f.imgsee.show()},function(){f.imgsee.hide()}),f.bigimg.find(\".layui-layer-imgprev\").on(\"click\",function(a){a.preventDefault(),f.imgprev()}),f.bigimg.find(\".layui-layer-imgnext\").on(\"click\",function(a){a.preventDefault(),f.imgnext()}),$(document).on(\"keyup\",f.keyup)},f.loadi=layer.load(1,{shade:\"shade\"in a?!1:.9,scrollbar:!1}),e(i[j].src,function(c){layer.close(f.loadi),f.index=layer.open($.extend({type:1,area:function(){var b=[c.width,c.height],d=[$(window).width()-100,$(window).height()-100];return!a.full&&b[0]>d[0]&&(b[0]=d[0],b[1]=b[0]*d[1]/b[0]),[b[0]+\"px\",b[1]+\"px\"]}(),title:!1,shade:.9,shadeClose:!0,closeBtn:!1,move:\".layui-layer-phimg img\",moveType:1,scrollbar:!1,moveOut:!0,shift:5*Math.random()|0,skin:\"layui-layer-photos\"+b(\"photos\"),content:'<div class=\"layui-layer-phimg\"><img src=\"'+i[j].src+'\" alt=\"'+(i[j].alt||\"\")+'\" layer-pid=\"'+i[j].pid+'\"><div class=\"layui-layer-imgsee\">'+(i.length>1?'<span class=\"layui-layer-imguide\"><a href=\"javascript:;\" class=\"layui-layer-iconext layui-layer-imgprev\"></a><a href=\"javascript:;\" class=\"layui-layer-iconext layui-layer-imgnext\"></a></span>':\"\")+'<div class=\"layui-layer-imgbar\" style=\"display:'+(d?\"block\":\"\")+'\"><span class=\"layui-layer-imgtit\"><a href=\"javascript:;\">'+(i[j].alt||\"\")+\"</a><em>\"+f.imgIndex+\"/\"+i.length+\"</em></span></div></div></div>\",success:function(b,c){f.bigimg=b.find(\".layui-layer-phimg\"),f.imgsee=b.find(\".layui-layer-imguide,.layui-layer-imgbar\"),f.event(b),a.tab&&a.tab(i[j],b)},end:function(){f.end=!0,$(document).off(\"keyup\",f.keyup)}},a))},function(){layer.close(f.loadi),layer.msg(\"&#x5F53;&#x524D;&#x56FE;&#x7247;&#x5730;&#x5740;&#x5F02;&#x5E38;\",{time:2e3},function(){i.length>1&&f.imgnext(!0)})})}}}();"
  },
  {
    "path": "public/static/plugins/layer/layer.js",
    "content": "/*! layer-v2.0 弹层组件 License LGPL  http://layer.layui.com/ By 贤心 */\n;!function(a,b){\"use strict\";var c,d,e={getPath:function(){var a=document.scripts,b=a[a.length-1],c=b.src;if(!b.getAttribute(\"merge\"))return c.substring(0,c.lastIndexOf(\"/\")+1)}(),enter:function(a){13===a.keyCode&&a.preventDefault()},config:{},end:{},btn:[\"&#x786E;&#x5B9A;\",\"&#x53D6;&#x6D88;\"],type:[\"dialog\",\"page\",\"iframe\",\"loading\",\"tips\"]},f={v:\"2.0\",ie6:!!a.ActiveXObject&&!a.XMLHttpRequest,index:0,path:e.getPath,config:function(a,b){var d=0;return a=a||{},f.cache=e.config=c.extend(e.config,a),f.path=e.config.path||f.path,\"string\"==typeof a.extend&&(a.extend=[a.extend]),f.use(\"skin/layer.css\",a.extend&&a.extend.length>0?function g(){var c=a.extend;f.use(c[c[d]?d:d-1],d<c.length?function(){return++d,g}():b)}():b),this},use:function(a,b,d){var e=c(\"head\")[0],a=a.replace(/\\s/g,\"\"),g=/\\.css$/.test(a),h=document.createElement(g?\"link\":\"script\"),i=\"layui_layer_\"+a.replace(/\\.|\\//g,\"\");return f.path?(g&&(h.rel=\"stylesheet\"),h[g?\"href\":\"src\"]=/^http:\\/\\//.test(a)?a:f.path+a,h.id=i,c(\"#\"+i)[0]||e.appendChild(h),function j(){(g?1989===parseInt(c(\"#\"+i).css(\"width\")):f[d||i])?function(){b&&b();try{g||e.removeChild(h)}catch(a){}}():setTimeout(j,100)}(),this):void 0},ready:function(a,b){var d=\"function\"==typeof a;return d&&(b=a),f.config(c.extend(e.config,function(){return d?{}:{path:a}}()),b),this},alert:function(a,b,d){var e=\"function\"==typeof b;return e&&(d=b),f.open(c.extend({content:a,yes:d},e?{}:b))},confirm:function(a,b,d,g){var h=\"function\"==typeof b;return h&&(g=d,d=b),f.open(c.extend({content:a,btn:e.btn,yes:d,cancel:g},h?{}:b))},msg:function(a,d,g){var i=\"function\"==typeof d,j=e.config.skin,k=(j?j+\" \"+j+\"-msg\":\"\")||\"layui-layer-msg\",l=h.anim.length-1;return i&&(g=d),f.open(c.extend({content:a,time:3e3,shade:!1,skin:k,title:!1,closeBtn:!1,btn:!1,end:g},i&&!e.config.skin?{skin:k+\" layui-layer-hui\",shift:l}:function(){return d=d||{},(-1===d.icon||d.icon===b&&!e.config.skin)&&(d.skin=k+\" \"+(d.skin||\"layui-layer-hui\")),d}()))},load:function(a,b){return f.open(c.extend({type:3,icon:a||0,shade:.01},b))},tips:function(a,b,d){return f.open(c.extend({type:4,content:[a,b],closeBtn:!1,time:3e3,maxWidth:210},d))}},g=function(a){var b=this;b.index=++f.index,b.config=c.extend({},b.config,e.config,a),b.creat()};g.pt=g.prototype;var h=[\"layui-layer\",\".layui-layer-title\",\".layui-layer-main\",\".layui-layer-dialog\",\"layui-layer-iframe\",\"layui-layer-content\",\"layui-layer-btn\",\"layui-layer-close\"];h.anim=[\"layui-anim\",\"layui-anim-01\",\"layui-anim-02\",\"layui-anim-03\",\"layui-anim-04\",\"layui-anim-05\",\"layui-anim-06\"],g.pt.config={type:0,shade:.3,fix:!0,move:h[1],title:\"&#x4FE1;&#x606F;\",offset:\"auto\",area:\"auto\",closeBtn:1,time:0,zIndex:19891014,maxWidth:360,shift:0,icon:-1,scrollbar:!0,tips:2},g.pt.vessel=function(a,b){var c=this,d=c.index,f=c.config,g=f.zIndex+d,i=\"object\"==typeof f.title,j=f.maxmin&&(1===f.type||2===f.type),k=f.title?'<div class=\"layui-layer-title\" style=\"'+(i?f.title[1]:\"\")+'\">'+(i?f.title[0]:f.title)+\"</div>\":\"\";return f.zIndex=g,b([f.shade?'<div class=\"layui-layer-shade\" id=\"layui-layer-shade'+d+'\" times=\"'+d+'\" style=\"'+(\"z-index:\"+(g-1)+\"; background-color:\"+(f.shade[1]||\"#000\")+\"; opacity:\"+(f.shade[0]||f.shade)+\"; filter:alpha(opacity=\"+(100*f.shade[0]||100*f.shade)+\");\")+'\"></div>':\"\",'<div class=\"'+h[0]+\" \"+(h.anim[f.shift]||\"\")+(\" layui-layer-\"+e.type[f.type])+(0!=f.type&&2!=f.type||f.shade?\"\":\" layui-layer-border\")+\" \"+(f.skin||\"\")+'\" id=\"'+h[0]+d+'\" type=\"'+e.type[f.type]+'\" times=\"'+d+'\" showtime=\"'+f.time+'\" conType=\"'+(a?\"object\":\"string\")+'\" style=\"z-index: '+g+\"; width:\"+f.area[0]+\";height:\"+f.area[1]+(f.fix?\"\":\";position:absolute;\")+'\">'+(a&&2!=f.type?\"\":k)+'<div class=\"layui-layer-content'+(0==f.type&&-1!==f.icon?\" layui-layer-padding\":\"\")+(3==f.type?\" layui-layer-loading\"+f.icon:\"\")+'\">'+(0==f.type&&-1!==f.icon?'<i class=\"layui-layer-ico layui-layer-ico'+f.icon+'\"></i>':\"\")+(1==f.type&&a?\"\":f.content||\"\")+'</div><span class=\"layui-layer-setwin\">'+function(){var a=j?'<a class=\"layui-layer-min\" href=\"javascript:;\"><cite></cite></a><a class=\"layui-layer-ico layui-layer-max\" href=\"javascript:;\"></a>':\"\";return f.closeBtn&&(a+='<a class=\"layui-layer-ico '+h[7]+\" \"+h[7]+(f.title?f.closeBtn:4==f.type?\"1\":\"2\")+'\" href=\"javascript:;\"></a>'),a}()+\"</span>\"+(f.btn?function(){var a=\"\";\"string\"==typeof f.btn&&(f.btn=[f.btn]);for(var b=0,c=f.btn.length;c>b;b++)a+='<a class=\"'+h[6]+b+'\">'+f.btn[b]+\"</a>\";return'<div class=\"'+h[6]+'\">'+a+\"</div>\"}():\"\")+\"</div>\"],k),c},g.pt.creat=function(){var a=this,b=a.config,g=a.index,i=b.content,j=\"object\"==typeof i;switch(\"string\"==typeof b.area&&(b.area=\"auto\"===b.area?[\"\",\"\"]:[b.area,\"\"]),b.type){case 0:b.btn=\"btn\"in b?b.btn:e.btn[0],f.closeAll(\"dialog\");break;case 2:var i=b.content=j?b.content:[b.content||\"http://sentsin.com?from=layer\",\"auto\"];b.content='<iframe scrolling=\"'+(b.content[1]||\"auto\")+'\" allowtransparency=\"true\" id=\"'+h[4]+g+'\" name=\"'+h[4]+g+'\" onload=\"this.className=\\'\\';\" class=\"layui-layer-load\" frameborder=\"0\" src=\"'+b.content[0]+'\"></iframe>';break;case 3:b.title=!1,b.closeBtn=!1,-1===b.icon&&0===b.icon,f.closeAll(\"loading\");break;case 4:j||(b.content=[b.content,\"body\"]),b.follow=b.content[1],b.content=b.content[0]+'<i class=\"layui-layer-TipsG\"></i>',b.title=!1,b.shade=!1,b.fix=!1,b.tips=\"object\"==typeof b.tips?b.tips:[b.tips,!0],b.tipsMore||f.closeAll(\"tips\")}a.vessel(j,function(d,e){c(\"body\").append(d[0]),j?function(){2==b.type||4==b.type?function(){c(\"body\").append(d[1])}():function(){i.parents(\".\"+h[0])[0]||(i.show().addClass(\"layui-layer-wrap\").wrap(d[1]),c(\"#\"+h[0]+g).find(\".\"+h[5]).before(e))}()}():c(\"body\").append(d[1]),a.layero=c(\"#\"+h[0]+g),b.scrollbar||h.html.css(\"overflow\",\"hidden\").attr(\"layer-full\",g)}).auto(g),2==b.type&&f.ie6&&a.layero.find(\"iframe\").attr(\"src\",i[0]),c(document).off(\"keydown\",e.enter).on(\"keydown\",e.enter),4==b.type?a.tips():a.offset(),b.fix&&d.on(\"resize\",function(){a.offset(),(/^\\d+%$/.test(b.area[0])||/^\\d+%$/.test(b.area[1]))&&a.auto(g),4==b.type&&a.tips()}),b.time<=0||setTimeout(function(){f.close(a.index)},b.time),a.move().callback()},g.pt.auto=function(a){function b(a){a=g.find(a),a.height(i[1]-j-k-2*(0|parseFloat(a.css(\"padding\"))))}var e=this,f=e.config,g=c(\"#\"+h[0]+a);\"\"===f.area[0]&&f.maxWidth>0&&(/MSIE 7/.test(navigator.userAgent)&&f.btn&&g.width(g.innerWidth()),g.outerWidth()>f.maxWidth&&g.width(f.maxWidth));var i=[g.innerWidth(),g.innerHeight()],j=g.find(h[1]).outerHeight()||0,k=g.find(\".\"+h[6]).outerHeight()||0;switch(f.type){case 2:b(\"iframe\");break;default:\"\"===f.area[1]?f.fix&&i[1]>=d.height()&&(i[1]=d.height(),b(\".\"+h[5])):b(\".\"+h[5])}return e},g.pt.offset=function(){var a=this,b=a.config,c=a.layero,e=[c.outerWidth(),c.outerHeight()],f=\"object\"==typeof b.offset;a.offsetTop=(d.height()-e[1])/2,a.offsetLeft=(d.width()-e[0])/2,f?(a.offsetTop=b.offset[0],a.offsetLeft=b.offset[1]||a.offsetLeft):\"auto\"!==b.offset&&(a.offsetTop=b.offset,\"rb\"===b.offset&&(a.offsetTop=d.height()-e[1],a.offsetLeft=d.width()-e[0])),b.fix||(a.offsetTop=/%$/.test(a.offsetTop)?d.height()*parseFloat(a.offsetTop)/100:parseFloat(a.offsetTop),a.offsetLeft=/%$/.test(a.offsetLeft)?d.width()*parseFloat(a.offsetLeft)/100:parseFloat(a.offsetLeft),a.offsetTop+=d.scrollTop(),a.offsetLeft+=d.scrollLeft()),c.css({top:a.offsetTop,left:a.offsetLeft})},g.pt.tips=function(){var a=this,b=a.config,e=a.layero,f=[e.outerWidth(),e.outerHeight()],g=c(b.follow);g[0]||(g=c(\"body\"));var i={width:g.outerWidth(),height:g.outerHeight(),top:g.offset().top,left:g.offset().left},j=e.find(\".layui-layer-TipsG\"),k=b.tips[0];b.tips[1]||j.remove(),i.autoLeft=function(){i.left+f[0]-d.width()>0?(i.tipLeft=i.left+i.width-f[0],j.css({right:12,left:\"auto\"})):i.tipLeft=i.left},i.where=[function(){i.autoLeft(),i.tipTop=i.top-f[1]-10,j.removeClass(\"layui-layer-TipsB\").addClass(\"layui-layer-TipsT\").css(\"border-right-color\",b.tips[1])},function(){i.tipLeft=i.left+i.width+10,i.tipTop=i.top,j.removeClass(\"layui-layer-TipsL\").addClass(\"layui-layer-TipsR\").css(\"border-bottom-color\",b.tips[1])},function(){i.autoLeft(),i.tipTop=i.top+i.height+10,j.removeClass(\"layui-layer-TipsT\").addClass(\"layui-layer-TipsB\").css(\"border-right-color\",b.tips[1])},function(){i.tipLeft=i.left-f[0]-10,i.tipTop=i.top,j.removeClass(\"layui-layer-TipsR\").addClass(\"layui-layer-TipsL\").css(\"border-bottom-color\",b.tips[1])}],i.where[k-1](),1===k?i.top-(d.scrollTop()+f[1]+16)<0&&i.where[2]():2===k?d.width()-(i.left+i.width+f[0]+16)>0||i.where[3]():3===k?i.top-d.scrollTop()+i.height+f[1]+16-d.height()>0&&i.where[0]():4===k&&f[0]+16-i.left>0&&i.where[1](),e.find(\".\"+h[5]).css({\"background-color\":b.tips[1],\"padding-right\":b.closeBtn?\"30px\":\"\"}),e.css({left:i.tipLeft,top:i.tipTop})},g.pt.move=function(){var a=this,b=a.config,e={setY:0,moveLayer:function(){var a=e.layero,b=parseInt(a.css(\"margin-left\")),c=parseInt(e.move.css(\"left\"));0===b||(c-=b),\"fixed\"!==a.css(\"position\")&&(c-=a.parent().offset().left,e.setY=0),a.css({left:c,top:parseInt(e.move.css(\"top\"))-e.setY})}},f=a.layero.find(b.move);return b.move&&f.attr(\"move\",\"ok\"),f.css({cursor:b.move?\"move\":\"auto\"}),c(b.move).on(\"mousedown\",function(a){if(a.preventDefault(),\"ok\"===c(this).attr(\"move\")){e.ismove=!0,e.layero=c(this).parents(\".\"+h[0]);var f=e.layero.offset().left,g=e.layero.offset().top,i=e.layero.outerWidth()-6,j=e.layero.outerHeight()-6;c(\"#layui-layer-moves\")[0]||c(\"body\").append('<div id=\"layui-layer-moves\" class=\"layui-layer-moves\" style=\"left:'+f+\"px; top:\"+g+\"px; width:\"+i+\"px; height:\"+j+'px; z-index:2147483584\"></div>'),e.move=c(\"#layui-layer-moves\"),b.moveType&&e.move.css({visibility:\"hidden\"}),e.moveX=a.pageX-e.move.position().left,e.moveY=a.pageY-e.move.position().top,\"fixed\"!==e.layero.css(\"position\")||(e.setY=d.scrollTop())}}),c(document).mousemove(function(a){if(e.ismove){var c=a.pageX-e.moveX,f=a.pageY-e.moveY;if(a.preventDefault(),!b.moveOut){e.setY=d.scrollTop();var g=d.width()-e.move.outerWidth(),h=e.setY;0>c&&(c=0),c>g&&(c=g),h>f&&(f=h),f>d.height()-e.move.outerHeight()+e.setY&&(f=d.height()-e.move.outerHeight()+e.setY)}e.move.css({left:c,top:f}),b.moveType&&e.moveLayer(),c=f=g=h=null}}).mouseup(function(){try{e.ismove&&(e.moveLayer(),e.move.remove(),b.moveEnd&&b.moveEnd()),e.ismove=!1}catch(a){e.ismove=!1}}),a},g.pt.callback=function(){function a(){var a=g.cancel&&g.cancel(b.index);a===!1||f.close(b.index)}var b=this,d=b.layero,g=b.config;b.openLayer(),g.success&&(2==g.type?d.find(\"iframe\")[0].onload=function(){this.className=\"\",g.success(d,b.index)}:g.success(d,b.index)),f.ie6&&b.IE6(d),d.find(\".\"+h[6]).children(\"a\").on(\"click\",function(){var e=c(this).index();g[\"btn\"+(e+1)]&&g[\"btn\"+(e+1)](b.index,d),0===e?g.yes?g.yes(b.index,d):f.close(b.index):1===e?a():g[\"btn\"+(e+1)]||f.close(b.index)}),d.find(\".\"+h[7]).on(\"click\",a),g.shadeClose&&c(\"#layui-layer-shade\"+b.index).on(\"click\",function(){f.close(b.index)}),d.find(\".layui-layer-min\").on(\"click\",function(){f.min(b.index,g),g.min&&g.min(d)}),d.find(\".layui-layer-max\").on(\"click\",function(){c(this).hasClass(\"layui-layer-maxmin\")?(f.restore(b.index),g.restore&&g.restore(d)):(f.full(b.index,g),g.full&&g.full(d))}),g.end&&(e.end[b.index]=g.end)},e.reselect=function(){c.each(c(\"select\"),function(a,b){var d=c(this);d.parents(\".\"+h[0])[0]||1==d.attr(\"layer\")&&c(\".\"+h[0]).length<1&&d.removeAttr(\"layer\").show(),d=null})},g.pt.IE6=function(a){function b(){a.css({top:f+(e.config.fix?d.scrollTop():0)})}var e=this,f=a.offset().top;b(),d.scroll(b),c(\"select\").each(function(a,b){var d=c(this);d.parents(\".\"+h[0])[0]||\"none\"===d.css(\"display\")||d.attr({layer:\"1\"}).hide(),d=null})},g.pt.openLayer=function(){var a=this;f.zIndex=a.config.zIndex,f.setTop=function(a){var b=function(){f.zIndex++,a.css(\"z-index\",f.zIndex+1)};return f.zIndex=parseInt(a[0].style.zIndex),a.on(\"mousedown\",b),f.zIndex}},e.record=function(a){var b=[a.outerWidth(),a.outerHeight(),a.position().top,a.position().left+parseFloat(a.css(\"margin-left\"))];a.find(\".layui-layer-max\").addClass(\"layui-layer-maxmin\"),a.attr({area:b})},e.rescollbar=function(a){h.html.attr(\"layer-full\")==a&&(h.html[0].style.removeProperty?h.html[0].style.removeProperty(\"overflow\"):h.html[0].style.removeAttribute(\"overflow\"),h.html.removeAttr(\"layer-full\"))},f.getChildFrame=function(a,b){return b=b||c(\".\"+h[4]).attr(\"times\"),c(\"#\"+h[0]+b).find(\"iframe\").contents().find(a)},f.getFrameIndex=function(a){return c(\"#\"+a).parents(\".\"+h[4]).attr(\"times\")},f.iframeAuto=function(a){if(a){var b=f.getChildFrame(\"html\",a).outerHeight(),d=c(\"#\"+h[0]+a),e=d.find(h[1]).outerHeight()||0,g=d.find(\".\"+h[6]).outerHeight()||0;d.css({height:b+e+g}),d.find(\"iframe\").css({height:b})}},f.iframeSrc=function(a,b){c(\"#\"+h[0]+a).find(\"iframe\").attr(\"src\",b)},f.style=function(a,b){var d=c(\"#\"+h[0]+a),f=d.attr(\"type\"),g=d.find(h[1]).outerHeight()||0,i=d.find(\".\"+h[6]).outerHeight()||0;(f===e.type[1]||f===e.type[2])&&(d.css(b),f===e.type[2]&&d.find(\"iframe\").css({height:parseFloat(b.height)-g-i}))},f.min=function(a,b){var d=c(\"#\"+h[0]+a),g=d.find(h[1]).outerHeight()||0;e.record(d),f.style(a,{width:180,height:g,overflow:\"hidden\"}),d.find(\".layui-layer-min\").hide(),\"page\"===d.attr(\"type\")&&d.find(h[4]).hide(),e.rescollbar(a)},f.restore=function(a){var b=c(\"#\"+h[0]+a),d=b.attr(\"area\").split(\",\");b.attr(\"type\");f.style(a,{width:parseFloat(d[0]),height:parseFloat(d[1]),top:parseFloat(d[2]),left:parseFloat(d[3]),overflow:\"visible\"}),b.find(\".layui-layer-max\").removeClass(\"layui-layer-maxmin\"),b.find(\".layui-layer-min\").show(),\"page\"===b.attr(\"type\")&&b.find(h[4]).show(),e.rescollbar(a)},f.full=function(a){var b,g=c(\"#\"+h[0]+a);e.record(g),h.html.attr(\"layer-full\")||h.html.css(\"overflow\",\"hidden\").attr(\"layer-full\",a),clearTimeout(b),b=setTimeout(function(){var b=\"fixed\"===g.css(\"position\");f.style(a,{top:b?0:d.scrollTop(),left:b?0:d.scrollLeft(),width:d.width(),height:d.height()}),g.find(\".layui-layer-min\").hide()},100)},f.title=function(a,b){var d=c(\"#\"+h[0]+(b||f.index)).find(h[1]);d.html(a)},f.close=function(a){var b=c(\"#\"+h[0]+a),d=b.attr(\"type\");if(b[0]){if(d===e.type[1]&&\"object\"===b.attr(\"conType\")){b.children(\":not(.\"+h[5]+\")\").remove();for(var g=0;2>g;g++)b.find(\".layui-layer-wrap\").unwrap().hide()}else{if(d===e.type[2])try{var i=c(\"#\"+h[4]+a)[0];i.contentWindow.document.write(\"\"),i.contentWindow.close(),b.find(\".\"+h[5])[0].removeChild(i)}catch(j){}b[0].innerHTML=\"\",b.remove()}c(\"#layui-layer-moves, #layui-layer-shade\"+a).remove(),f.ie6&&e.reselect(),e.rescollbar(a),c(document).off(\"keydown\",e.enter),\"function\"==typeof e.end[a]&&e.end[a](),delete e.end[a]}},f.closeAll=function(a){c.each(c(\".\"+h[0]),function(){var b=c(this),d=a?b.attr(\"type\")===a:1;d&&f.close(b.attr(\"times\")),d=null})},e.run=function(){c=jQuery,d=c(a),h.html=c(\"html\"),f.open=function(a){var b=new g(a);return b.index}},\"function\"==typeof define?define(function(){return e.run(),f}):function(){a.layer=f,e.run(),f.use(\"skin/layer.css\")}()}(window);"
  },
  {
    "path": "public/static/plugins/layer/skin/layer.css",
    "content": "/*!\r\n \r\n @Name: layer's style\r\n @Author: 贤心\r\n @Blog： sentsin.com\r\n \r\n */*html{background-image:url(about:blank);background-attachment:fixed}html #layui_layer_skinlayercss{display:none;position:absolute;width:1989px}.layui-layer,.layui-layer-shade{position:fixed;_position:absolute;pointer-events:auto}.layui-layer-shade{top:0;left:0;width:100%;height:100%;_height:expression(document.body.offsetHeight+\"px\")}.layui-layer{top:150px;left:50%;margin:0;padding:0;background-color:#fff;-webkit-background-clip:content;box-shadow:1px 1px 50px rgba(0,0,0,.3);border-radius:2px;-webkit-animation-fill-mode:both;animation-fill-mode:both;-webkit-animation-duration:.3s;animation-duration:.3s}.layui-layer-close{position:absolute}.layui-layer-content{position:relative}.layui-layer-border{border:1px solid #B2B2B2;border:1px solid rgba(0,0,0,.3);box-shadow:1px 1px 5px rgba(0,0,0,.2)}.layui-layer-moves{position:absolute;border:3px solid #666;border:3px solid rgba(0,0,0,.5);cursor:move;background-color:#fff;background-color:rgba(255,255,255,.3);filter:alpha(opacity=50)}.layui-layer-load{background:url(default/loading-0.gif) center center no-repeat #fff}.layui-layer-ico{background:url(default/icon.png) no-repeat}.layui-layer-btn a,.layui-layer-dialog .layui-layer-ico,.layui-layer-setwin a{display:inline-block;*display:inline;*zoom:1;vertical-align:top}@-webkit-keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceIn{0%{opacity:0;-webkit-transform:scale(.5);-ms-transform:scale(.5);transform:scale(.5)}100%{opacity:1;-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layui-anim{-webkit-animation-name:bounceIn;animation-name:bounceIn}@-webkit-keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.03);transform:scale(1.03)}0%{-webkit-transform:scale(1);transform:scale(1)}}@keyframes bounceOut{100%{opacity:0;-webkit-transform:scale(.7);-ms-transform:scale(.7);transform:scale(.7)}30%{-webkit-transform:scale(1.03);-ms-transform:scale(1.03);transform:scale(1.03)}0%{-webkit-transform:scale(1);-ms-transform:scale(1);transform:scale(1)}}.layui-anim-close{-webkit-animation-name:bounceOut;animation-name:bounceOut;-webkit-animation-duration:.2s;animation-duration:.2s}@-webkit-keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInDown{0%{opacity:0;-webkit-transform:scale(.1) translateY(-2000px);-ms-transform:scale(.1) translateY(-2000px);transform:scale(.1) translateY(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateY(60px);-ms-transform:scale(.475) translateY(60px);transform:scale(.475) translateY(60px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layui-anim-01{-webkit-animation-name:zoomInDown;animation-name:zoomInDown}@-webkit-keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes fadeInUpBig{0%{opacity:0;-webkit-transform:translateY(2000px);-ms-transform:translateY(2000px);transform:translateY(2000px)}100%{opacity:1;-webkit-transform:translateY(0);-ms-transform:translateY(0);transform:translateY(0)}}.layui-anim-02{-webkit-animation-name:fadeInUpBig;animation-name:fadeInUpBig}@-webkit-keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}@keyframes zoomInLeft{0%{opacity:0;-webkit-transform:scale(.1) translateX(-2000px);-ms-transform:scale(.1) translateX(-2000px);transform:scale(.1) translateX(-2000px);-webkit-animation-timing-function:ease-in-out;animation-timing-function:ease-in-out}60%{opacity:1;-webkit-transform:scale(.475) translateX(48px);-ms-transform:scale(.475) translateX(48px);transform:scale(.475) translateX(48px);-webkit-animation-timing-function:ease-out;animation-timing-function:ease-out}}.layui-anim-03{-webkit-animation-name:zoomInLeft;animation-name:zoomInLeft}@-webkit-keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}@keyframes rollIn{0%{opacity:0;-webkit-transform:translateX(-100%) rotate(-120deg);-ms-transform:translateX(-100%) rotate(-120deg);transform:translateX(-100%) rotate(-120deg)}100%{opacity:1;-webkit-transform:translateX(0) rotate(0);-ms-transform:translateX(0) rotate(0);transform:translateX(0) rotate(0)}}.layui-anim-04{-webkit-animation-name:rollIn;animation-name:rollIn}@keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-anim-05{-webkit-animation-name:fadeIn;animation-name:fadeIn}@-webkit-keyframes shake{0%,100%{-webkit-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);transform:translateX(10px)}}@keyframes shake{0%,100%{-webkit-transform:translateX(0);-ms-transform:translateX(0);transform:translateX(0)}10%,30%,50%,70%,90%{-webkit-transform:translateX(-10px);-ms-transform:translateX(-10px);transform:translateX(-10px)}20%,40%,60%,80%{-webkit-transform:translateX(10px);-ms-transform:translateX(10px);transform:translateX(10px)}}.layui-anim-06{-webkit-animation-name:shake;animation-name:shake}@-webkit-keyframes fadeIn{0%{opacity:0}100%{opacity:1}}.layui-layer-title{padding:0 80px 0 20px;height:42px;line-height:42px;border-bottom:1px solid #eee;font-size:14px;color:#333;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;background-color:#F8F8F8;border-radius:2px 2px 0 0}.layui-layer-setwin{position:absolute;right:15px;*right:0;top:15px;font-size:0;line-height:initial}.layui-layer-setwin a{position:relative;width:16px;height:16px;margin-left:10px;font-size:12px;_overflow:hidden}.layui-layer-setwin .layui-layer-min cite{position:absolute;width:14px;height:2px;left:0;top:50%;margin-top:-1px;background-color:#2E2D3C;cursor:pointer;_overflow:hidden}.layui-layer-setwin .layui-layer-min:hover cite{background-color:#2D93CA}.layui-layer-setwin .layui-layer-max{background-position:-32px -40px}.layui-layer-setwin .layui-layer-max:hover{background-position:-16px -40px}.layui-layer-setwin .layui-layer-maxmin{background-position:-65px -40px}.layui-layer-setwin .layui-layer-maxmin:hover{background-position:-49px -40px}.layui-layer-setwin .layui-layer-close1{background-position:0 -40px;cursor:pointer}.layui-layer-setwin .layui-layer-close1:hover{opacity:.7}.layui-layer-setwin .layui-layer-close2{position:absolute;right:-28px;top:-28px;width:30px;height:30px;margin-left:0;background-position:-150px -31px;*right:-18px;_display:none}.layui-layer-setwin .layui-layer-close2:hover{background-position:-181px -31px}.layui-layer-btn{text-align:right;padding:0 10px 12px;pointer-events:auto}.layui-layer-btn a{height:28px;line-height:28px;margin:0 6px;padding:0 15px;border:1px solid #dedede;background-color:#f1f1f1;color:#333;border-radius:2px;font-weight:400;cursor:pointer;text-decoration:none}.layui-layer-btn a:hover{opacity:.9;text-decoration:none}.layui-layer-btn a:active{opacity:.7}.layui-layer-btn .layui-layer-btn0{border-color:#4898d5;background-color:#2e8ded;color:#fff}.layui-layer-dialog{min-width:260px}.layui-layer-dialog .layui-layer-content{position:relative;padding:20px;line-height:24px;word-break:break-all;font-size:14px;overflow:auto}.layui-layer-dialog .layui-layer-content .layui-layer-ico{position:absolute;top:16px;left:15px;_left:-40px;width:30px;height:30px}.layui-layer-ico1{background-position:-30px 0}.layui-layer-ico2{background-position:-60px 0}.layui-layer-ico3{background-position:-90px 0}.layui-layer-ico4{background-position:-120px 0}.layui-layer-ico5{background-position:-150px 0}.layui-layer-ico6{background-position:-180px 0}.layui-layer-rim{border:6px solid #8D8D8D;border:6px solid rgba(0,0,0,.3);border-radius:5px;box-shadow:none}.layui-layer-msg{min-width:180px;border:1px solid #D3D4D3;box-shadow:none}.layui-layer-hui{min-width:100px;background-color:#000;filter:alpha(opacity=60);background-color:rgba(0,0,0,.6);color:#fff;border:none}.layui-layer-hui .layui-layer-content{padding:12px 25px;text-align:center}.layui-layer-dialog .layui-layer-padding{padding:20px 20px 20px 55px;text-align:left}.layui-layer-page .layui-layer-content{position:relative;overflow:auto}.layui-layer-iframe .layui-layer-btn,.layui-layer-page .layui-layer-btn{padding-top:10px}.layui-layer-nobg{background:0 0}.layui-layer-iframe .layui-layer-content{overflow:hidden}.layui-layer-iframe iframe{display:block;width:100%}.layui-layer-loading{border-radius:100%;background:0 0;box-shadow:none;border:none}.layui-layer-loading .layui-layer-content{width:60px;height:24px;background:url(default/loading-0.gif) no-repeat}.layui-layer-loading .layui-layer-loading1{width:37px;height:37px;background:url(default/loading-1.gif) no-repeat}.layui-layer-ico16,.layui-layer-loading .layui-layer-loading2{width:32px;height:32px;background:url(default/loading-2.gif) no-repeat}.layui-layer-tips{background:0 0;box-shadow:none;border:none}.layui-layer-tips .layui-layer-content{position:relative;line-height:22px;min-width:12px;padding:5px 10px;font-size:12px;_float:left;border-radius:3px;box-shadow:1px 1px 3px rgba(0,0,0,.3);background-color:#F90;color:#fff}.layui-layer-tips .layui-layer-close{right:-2px;top:-1px}.layui-layer-tips i.layui-layer-TipsG{position:absolute;width:0;height:0;border-width:8px;border-color:transparent;border-style:dashed;*overflow:hidden}.layui-layer-tips i.layui-layer-TipsB,.layui-layer-tips i.layui-layer-TipsT{left:5px;border-right-style:solid;border-right-color:#F90}.layui-layer-tips i.layui-layer-TipsT{bottom:-8px}.layui-layer-tips i.layui-layer-TipsB{top:-8px}.layui-layer-tips i.layui-layer-TipsL,.layui-layer-tips i.layui-layer-TipsR{top:1px;border-bottom-style:solid;border-bottom-color:#F90}.layui-layer-tips i.layui-layer-TipsR{left:-8px}.layui-layer-tips i.layui-layer-TipsL{right:-8px}.layui-layer-lan[type=dialog]{min-width:280px}.layui-layer-lan .layui-layer-title{background:#4476A7;color:#fff;border:none}.layui-layer-lan .layui-layer-lan .layui-layer-btn{padding:10px;text-align:right;border-top:1px solid #E9E7E7}.layui-layer-lan .layui-layer-btn a{background:#BBB5B5;border:none}.layui-layer-lan .layui-layer-btn .layui-layer-btn1{background:#C9C5C5}.layui-layer-molv .layui-layer-title{background:#009f95;color:#fff;border:none}.layui-layer-molv .layui-layer-btn a{background:#009f95}.layui-layer-molv .layui-layer-btn .layui-layer-btn1{background:#92B8B1}"
  },
  {
    "path": "public/static/plugins/layer/skin/layer.ext.css",
    "content": "/*!\r\n \r\n @Name: layer拓展样式\r\n @Date: 2012.12.13\r\n @Author: 贤心\r\n @blog: sentsin.com\r\n \r\n */.layui-layer-imgbar,.layui-layer-imgtit a,.layui-layer-tab .layui-layer-title span{text-overflow:ellipsis;white-space:nowrap}.layui-layer-iconext{background:url(default/icon-ext.png) no-repeat}html #layui_layer_skinlayerextcss{display:none;position:absolute;width:1989px}.layui-layer-prompt .layui-layer-input{display:block;width:220px;height:30px;margin:0 auto;line-height:30px;padding:0 5px;border:1px solid #ccc;box-shadow:1px 1px 5px rgba(0,0,0,.1) inset;color:#333}.layui-layer-prompt textarea.layui-layer-input{width:300px;height:100px;line-height:20px}.layui-layer-tab{box-shadow:1px 1px 50px rgba(0,0,0,.4)}.layui-layer-tab .layui-layer-title{padding-left:0;border-bottom:1px solid #ccc;background-color:#eee;overflow:visible}.layui-layer-tab .layui-layer-title span{position:relative;float:left;min-width:80px;max-width:260px;padding:0 20px;text-align:center;cursor:default;overflow:hidden}.layui-layer-tab .layui-layer-title span.layui-layer-tabnow{height:43px;border-left:1px solid #ccc;border-right:1px solid #ccc;background-color:#fff;z-index:10}.layui-layer-tab .layui-layer-title span:first-child{border-left:none}.layui-layer-tabmain{line-height:24px;clear:both}.layui-layer-tabmain .layui-layer-tabli{display:none}.layui-layer-tabmain .layui-layer-tabli.xubox_tab_layer{display:block}.xubox_tabclose{position:absolute;right:10px;top:5px;cursor:pointer}.layui-layer-photos{-webkit-animation-duration:1s;animation-duration:1s;background:url(default/xubox_loading1.gif) center center no-repeat #000}.layui-layer-photos .layui-layer-content{overflow:hidden;text-align:center}.layui-layer-photos .layui-layer-phimg img{position:relative;width:100%;display:inline-block;*display:inline;*zoom:1;vertical-align:top}.layui-layer-imgbar,.layui-layer-imguide{display:none}.layui-layer-imgnext,.layui-layer-imgprev{position:absolute;top:50%;width:27px;_width:44px;height:44px;margin-top:-22px;outline:0;blr:expression(this.onFocus=this.blur())}.layui-layer-imgprev{left:10px;background-position:-5px -5px;_background-position:-70px -5px}.layui-layer-imgprev:hover{background-position:-33px -5px;_background-position:-120px -5px}.layui-layer-imgnext{right:10px;_right:8px;background-position:-5px -50px;_background-position:-70px -50px}.layui-layer-imgnext:hover{background-position:-33px -50px;_background-position:-120px -50px}.layui-layer-imgbar{position:absolute;left:0;bottom:0;width:100%;height:32px;line-height:32px;background-color:rgba(0,0,0,.8);background-color:#000\\9;filter:Alpha(opacity=80);color:#fff;overflow:hidden;font-size:0}.layui-layer-imgtit *{display:inline-block;*display:inline;*zoom:1;vertical-align:top;font-size:12px}.layui-layer-imgtit a{max-width:65%;overflow:hidden;color:#fff}.layui-layer-imgtit a:hover{color:#fff;text-decoration:underline}.layui-layer-imgtit em{padding-left:10px;font-style:normal}"
  },
  {
    "path": "public/static/plugins/morris/morris.css",
    "content": ".morris-hover{position:absolute;z-index:1090;}.morris-hover.morris-default-style{border-radius:10px;padding:6px;color:#f9f9f9;background:rgba(0, 0, 0, 0.8);border:solid 2px rgba(0, 0, 0, 0.9);font-weight: 600;font-size:14px;text-align:center;}.morris-hover.morris-default-style .morris-hover-row-label{font-weight:bold;margin:0.25em 0;}\n.morris-hover.morris-default-style .morris-hover-point{white-space:nowrap;margin:0.1em 0;}\n"
  },
  {
    "path": "public/static/plugins/morris/morris.js",
    "content": "/* @license\nmorris.js v0.5.0\nCopyright 2014 Olly Smith All rights reserved.\nLicensed under the BSD-2-Clause License.\n*/\n\n\n(function() {\n  var $, Morris, minutesSpecHelper, secondsSpecHelper,\n    __slice = [].slice,\n    __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; },\n    __hasProp = {}.hasOwnProperty,\n    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },\n    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };\n\n  Morris = window.Morris = {};\n\n  $ = jQuery;\n\n  Morris.EventEmitter = (function() {\n    function EventEmitter() {}\n\n    EventEmitter.prototype.on = function(name, handler) {\n      if (this.handlers == null) {\n        this.handlers = {};\n      }\n      if (this.handlers[name] == null) {\n        this.handlers[name] = [];\n      }\n      this.handlers[name].push(handler);\n      return this;\n    };\n\n    EventEmitter.prototype.fire = function() {\n      var args, handler, name, _i, _len, _ref, _results;\n      name = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n      if ((this.handlers != null) && (this.handlers[name] != null)) {\n        _ref = this.handlers[name];\n        _results = [];\n        for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n          handler = _ref[_i];\n          _results.push(handler.apply(null, args));\n        }\n        return _results;\n      }\n    };\n\n    return EventEmitter;\n\n  })();\n\n  Morris.commas = function(num) {\n    var absnum, intnum, ret, strabsnum;\n    if (num != null) {\n      ret = num < 0 ? \"-\" : \"\";\n      absnum = Math.abs(num);\n      intnum = Math.floor(absnum).toFixed(0);\n      ret += intnum.replace(/(?=(?:\\d{3})+$)(?!^)/g, ',');\n      strabsnum = absnum.toString();\n      if (strabsnum.length > intnum.length) {\n        ret += strabsnum.slice(intnum.length);\n      }\n      return ret;\n    } else {\n      return '-';\n    }\n  };\n\n  Morris.pad2 = function(number) {\n    return (number < 10 ? '0' : '') + number;\n  };\n\n  Morris.Grid = (function(_super) {\n    __extends(Grid, _super);\n\n    function Grid(options) {\n      this.resizeHandler = __bind(this.resizeHandler, this);\n      var _this = this;\n      if (typeof options.element === 'string') {\n        this.el = $(document.getElementById(options.element));\n      } else {\n        this.el = $(options.element);\n      }\n      if ((this.el == null) || this.el.length === 0) {\n        throw new Error(\"Graph container element not found\");\n      }\n      if (this.el.css('position') === 'static') {\n        this.el.css('position', 'relative');\n      }\n      this.options = $.extend({}, this.gridDefaults, this.defaults || {}, options);\n      if (typeof this.options.units === 'string') {\n        this.options.postUnits = options.units;\n      }\n      this.raphael = new Raphael(this.el[0]);\n      this.elementWidth = null;\n      this.elementHeight = null;\n      this.dirty = false;\n      this.selectFrom = null;\n      if (this.init) {\n        this.init();\n      }\n      this.setData(this.options.data);\n      this.el.bind('mousemove', function(evt) {\n        var left, offset, right, width, x;\n        offset = _this.el.offset();\n        x = evt.pageX - offset.left;\n        if (_this.selectFrom) {\n          left = _this.data[_this.hitTest(Math.min(x, _this.selectFrom))]._x;\n          right = _this.data[_this.hitTest(Math.max(x, _this.selectFrom))]._x;\n          width = right - left;\n          return _this.selectionRect.attr({\n            x: left,\n            width: width\n          });\n        } else {\n          return _this.fire('hovermove', x, evt.pageY - offset.top);\n        }\n      });\n      this.el.bind('mouseleave', function(evt) {\n        if (_this.selectFrom) {\n          _this.selectionRect.hide();\n          _this.selectFrom = null;\n        }\n        return _this.fire('hoverout');\n      });\n      this.el.bind('touchstart touchmove touchend', function(evt) {\n        var offset, touch;\n        touch = evt.originalEvent.touches[0] || evt.originalEvent.changedTouches[0];\n        offset = _this.el.offset();\n        return _this.fire('hovermove', touch.pageX - offset.left, touch.pageY - offset.top);\n      });\n      this.el.bind('click', function(evt) {\n        var offset;\n        offset = _this.el.offset();\n        return _this.fire('gridclick', evt.pageX - offset.left, evt.pageY - offset.top);\n      });\n      if (this.options.rangeSelect) {\n        this.selectionRect = this.raphael.rect(0, 0, 0, this.el.innerHeight()).attr({\n          fill: this.options.rangeSelectColor,\n          stroke: false\n        }).toBack().hide();\n        this.el.bind('mousedown', function(evt) {\n          var offset;\n          offset = _this.el.offset();\n          return _this.startRange(evt.pageX - offset.left);\n        });\n        this.el.bind('mouseup', function(evt) {\n          var offset;\n          offset = _this.el.offset();\n          _this.endRange(evt.pageX - offset.left);\n          return _this.fire('hovermove', evt.pageX - offset.left, evt.pageY - offset.top);\n        });\n      }\n      if (this.options.resize) {\n        $(window).bind('resize', function(evt) {\n          if (_this.timeoutId != null) {\n            window.clearTimeout(_this.timeoutId);\n          }\n          return _this.timeoutId = window.setTimeout(_this.resizeHandler, 100);\n        });\n      }\n      this.el.css('-webkit-tap-highlight-color', 'rgba(0,0,0,0)');\n      if (this.postInit) {\n        this.postInit();\n      }\n    }\n\n    Grid.prototype.gridDefaults = {\n      dateFormat: null,\n      axes: true,\n      grid: true,\n      gridLineColor: '#aaa',\n      gridStrokeWidth: 0.5,\n      gridTextColor: '#888',\n      gridTextSize: 12,\n      gridTextFamily: 'sans-serif',\n      gridTextWeight: 'normal',\n      hideHover: false,\n      yLabelFormat: null,\n      xLabelAngle: 0,\n      numLines: 5,\n      padding: 25,\n      parseTime: true,\n      postUnits: '',\n      preUnits: '',\n      ymax: 'auto',\n      ymin: 'auto 0',\n      goals: [],\n      goalStrokeWidth: 1.0,\n      goalLineColors: ['#666633', '#999966', '#cc6666', '#663333'],\n      events: [],\n      eventStrokeWidth: 1.0,\n      eventLineColors: ['#005a04', '#ccffbb', '#3a5f0b', '#005502'],\n      rangeSelect: null,\n      rangeSelectColor: '#eef',\n      resize: false\n    };\n\n    Grid.prototype.setData = function(data, redraw) {\n      var e, idx, index, maxGoal, minGoal, ret, row, step, total, y, ykey, ymax, ymin, yval, _ref;\n      if (redraw == null) {\n        redraw = true;\n      }\n      this.options.data = data;\n      if ((data == null) || data.length === 0) {\n        this.data = [];\n        this.raphael.clear();\n        if (this.hover != null) {\n          this.hover.hide();\n        }\n        return;\n      }\n      ymax = this.cumulative ? 0 : null;\n      ymin = this.cumulative ? 0 : null;\n      if (this.options.goals.length > 0) {\n        minGoal = Math.min.apply(Math, this.options.goals);\n        maxGoal = Math.max.apply(Math, this.options.goals);\n        ymin = ymin != null ? Math.min(ymin, minGoal) : minGoal;\n        ymax = ymax != null ? Math.max(ymax, maxGoal) : maxGoal;\n      }\n      this.data = (function() {\n        var _i, _len, _results;\n        _results = [];\n        for (index = _i = 0, _len = data.length; _i < _len; index = ++_i) {\n          row = data[index];\n          ret = {\n            src: row\n          };\n          ret.label = row[this.options.xkey];\n          if (this.options.parseTime) {\n            ret.x = Morris.parseDate(ret.label);\n            if (this.options.dateFormat) {\n              ret.label = this.options.dateFormat(ret.x);\n            } else if (typeof ret.label === 'number') {\n              ret.label = new Date(ret.label).toString();\n            }\n          } else {\n            ret.x = index;\n            if (this.options.xLabelFormat) {\n              ret.label = this.options.xLabelFormat(ret);\n            }\n          }\n          total = 0;\n          ret.y = (function() {\n            var _j, _len1, _ref, _results1;\n            _ref = this.options.ykeys;\n            _results1 = [];\n            for (idx = _j = 0, _len1 = _ref.length; _j < _len1; idx = ++_j) {\n              ykey = _ref[idx];\n              yval = row[ykey];\n              if (typeof yval === 'string') {\n                yval = parseFloat(yval);\n              }\n              if ((yval != null) && typeof yval !== 'number') {\n                yval = null;\n              }\n              if (yval != null) {\n                if (this.cumulative) {\n                  total += yval;\n                } else {\n                  if (ymax != null) {\n                    ymax = Math.max(yval, ymax);\n                    ymin = Math.min(yval, ymin);\n                  } else {\n                    ymax = ymin = yval;\n                  }\n                }\n              }\n              if (this.cumulative && (total != null)) {\n                ymax = Math.max(total, ymax);\n                ymin = Math.min(total, ymin);\n              }\n              _results1.push(yval);\n            }\n            return _results1;\n          }).call(this);\n          _results.push(ret);\n        }\n        return _results;\n      }).call(this);\n      if (this.options.parseTime) {\n        this.data = this.data.sort(function(a, b) {\n          return (a.x > b.x) - (b.x > a.x);\n        });\n      }\n      this.xmin = this.data[0].x;\n      this.xmax = this.data[this.data.length - 1].x;\n      this.events = [];\n      if (this.options.events.length > 0) {\n        if (this.options.parseTime) {\n          this.events = (function() {\n            var _i, _len, _ref, _results;\n            _ref = this.options.events;\n            _results = [];\n            for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n              e = _ref[_i];\n              _results.push(Morris.parseDate(e));\n            }\n            return _results;\n          }).call(this);\n        } else {\n          this.events = this.options.events;\n        }\n        this.xmax = Math.max(this.xmax, Math.max.apply(Math, this.events));\n        this.xmin = Math.min(this.xmin, Math.min.apply(Math, this.events));\n      }\n      if (this.xmin === this.xmax) {\n        this.xmin -= 1;\n        this.xmax += 1;\n      }\n      this.ymin = this.yboundary('min', ymin);\n      this.ymax = this.yboundary('max', ymax);\n      if (this.ymin === this.ymax) {\n        if (ymin) {\n          this.ymin -= 1;\n        }\n        this.ymax += 1;\n      }\n      if (((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'y') || this.options.grid === true) {\n        if (this.options.ymax === this.gridDefaults.ymax && this.options.ymin === this.gridDefaults.ymin) {\n          this.grid = this.autoGridLines(this.ymin, this.ymax, this.options.numLines);\n          this.ymin = Math.min(this.ymin, this.grid[0]);\n          this.ymax = Math.max(this.ymax, this.grid[this.grid.length - 1]);\n        } else {\n          step = (this.ymax - this.ymin) / (this.options.numLines - 1);\n          this.grid = (function() {\n            var _i, _ref1, _ref2, _results;\n            _results = [];\n            for (y = _i = _ref1 = this.ymin, _ref2 = this.ymax; step > 0 ? _i <= _ref2 : _i >= _ref2; y = _i += step) {\n              _results.push(y);\n            }\n            return _results;\n          }).call(this);\n        }\n      }\n      this.dirty = true;\n      if (redraw) {\n        return this.redraw();\n      }\n    };\n\n    Grid.prototype.yboundary = function(boundaryType, currentValue) {\n      var boundaryOption, suggestedValue;\n      boundaryOption = this.options[\"y\" + boundaryType];\n      if (typeof boundaryOption === 'string') {\n        if (boundaryOption.slice(0, 4) === 'auto') {\n          if (boundaryOption.length > 5) {\n            suggestedValue = parseInt(boundaryOption.slice(5), 10);\n            if (currentValue == null) {\n              return suggestedValue;\n            }\n            return Math[boundaryType](currentValue, suggestedValue);\n          } else {\n            if (currentValue != null) {\n              return currentValue;\n            } else {\n              return 0;\n            }\n          }\n        } else {\n          return parseInt(boundaryOption, 10);\n        }\n      } else {\n        return boundaryOption;\n      }\n    };\n\n    Grid.prototype.autoGridLines = function(ymin, ymax, nlines) {\n      var gmax, gmin, grid, smag, span, step, unit, y, ymag;\n      span = ymax - ymin;\n      ymag = Math.floor(Math.log(span) / Math.log(10));\n      unit = Math.pow(10, ymag);\n      gmin = Math.floor(ymin / unit) * unit;\n      gmax = Math.ceil(ymax / unit) * unit;\n      step = (gmax - gmin) / (nlines - 1);\n      if (unit === 1 && step > 1 && Math.ceil(step) !== step) {\n        step = Math.ceil(step);\n        gmax = gmin + step * (nlines - 1);\n      }\n      if (gmin < 0 && gmax > 0) {\n        gmin = Math.floor(ymin / step) * step;\n        gmax = Math.ceil(ymax / step) * step;\n      }\n      if (step < 1) {\n        smag = Math.floor(Math.log(step) / Math.log(10));\n        grid = (function() {\n          var _i, _results;\n          _results = [];\n          for (y = _i = gmin; step > 0 ? _i <= gmax : _i >= gmax; y = _i += step) {\n            _results.push(parseFloat(y.toFixed(1 - smag)));\n          }\n          return _results;\n        })();\n      } else {\n        grid = (function() {\n          var _i, _results;\n          _results = [];\n          for (y = _i = gmin; step > 0 ? _i <= gmax : _i >= gmax; y = _i += step) {\n            _results.push(y);\n          }\n          return _results;\n        })();\n      }\n      return grid;\n    };\n\n    Grid.prototype._calc = function() {\n      var bottomOffsets, gridLine, h, i, w, yLabelWidths, _ref, _ref1;\n      w = this.el.width();\n      h = this.el.height();\n      if (this.elementWidth !== w || this.elementHeight !== h || this.dirty) {\n        this.elementWidth = w;\n        this.elementHeight = h;\n        this.dirty = false;\n        this.left = this.options.padding;\n        this.right = this.elementWidth - this.options.padding;\n        this.top = this.options.padding;\n        this.bottom = this.elementHeight - this.options.padding;\n        if ((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'y') {\n          yLabelWidths = (function() {\n            var _i, _len, _ref1, _results;\n            _ref1 = this.grid;\n            _results = [];\n            for (_i = 0, _len = _ref1.length; _i < _len; _i++) {\n              gridLine = _ref1[_i];\n              _results.push(this.measureText(this.yAxisFormat(gridLine)).width);\n            }\n            return _results;\n          }).call(this);\n          this.left += Math.max.apply(Math, yLabelWidths);\n        }\n        if ((_ref1 = this.options.axes) === true || _ref1 === 'both' || _ref1 === 'x') {\n          bottomOffsets = (function() {\n            var _i, _ref2, _results;\n            _results = [];\n            for (i = _i = 0, _ref2 = this.data.length; 0 <= _ref2 ? _i < _ref2 : _i > _ref2; i = 0 <= _ref2 ? ++_i : --_i) {\n              _results.push(this.measureText(this.data[i].text, -this.options.xLabelAngle).height);\n            }\n            return _results;\n          }).call(this);\n          this.bottom -= Math.max.apply(Math, bottomOffsets);\n        }\n        this.width = Math.max(1, this.right - this.left);\n        this.height = Math.max(1, this.bottom - this.top);\n        this.dx = this.width / (this.xmax - this.xmin);\n        this.dy = this.height / (this.ymax - this.ymin);\n        if (this.calc) {\n          return this.calc();\n        }\n      }\n    };\n\n    Grid.prototype.transY = function(y) {\n      return this.bottom - (y - this.ymin) * this.dy;\n    };\n\n    Grid.prototype.transX = function(x) {\n      if (this.data.length === 1) {\n        return (this.left + this.right) / 2;\n      } else {\n        return this.left + (x - this.xmin) * this.dx;\n      }\n    };\n\n    Grid.prototype.redraw = function() {\n      this.raphael.clear();\n      this._calc();\n      this.drawGrid();\n      this.drawGoals();\n      this.drawEvents();\n      if (this.draw) {\n        return this.draw();\n      }\n    };\n\n    Grid.prototype.measureText = function(text, angle) {\n      var ret, tt;\n      if (angle == null) {\n        angle = 0;\n      }\n      tt = this.raphael.text(100, 100, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).rotate(angle);\n      ret = tt.getBBox();\n      tt.remove();\n      return ret;\n    };\n\n    Grid.prototype.yAxisFormat = function(label) {\n      return this.yLabelFormat(label);\n    };\n\n    Grid.prototype.yLabelFormat = function(label) {\n      if (typeof this.options.yLabelFormat === 'function') {\n        return this.options.yLabelFormat(label);\n      } else {\n        return \"\" + this.options.preUnits + (Morris.commas(label)) + this.options.postUnits;\n      }\n    };\n\n    Grid.prototype.drawGrid = function() {\n      var lineY, y, _i, _len, _ref, _ref1, _ref2, _results;\n      if (this.options.grid === false && ((_ref = this.options.axes) !== true && _ref !== 'both' && _ref !== 'y')) {\n        return;\n      }\n      _ref1 = this.grid;\n      _results = [];\n      for (_i = 0, _len = _ref1.length; _i < _len; _i++) {\n        lineY = _ref1[_i];\n        y = this.transY(lineY);\n        if ((_ref2 = this.options.axes) === true || _ref2 === 'both' || _ref2 === 'y') {\n          this.drawYAxisLabel(this.left - this.options.padding / 2, y, this.yAxisFormat(lineY));\n        }\n        if (this.options.grid) {\n          _results.push(this.drawGridLine(\"M\" + this.left + \",\" + y + \"H\" + (this.left + this.width)));\n        } else {\n          _results.push(void 0);\n        }\n      }\n      return _results;\n    };\n\n    Grid.prototype.drawGoals = function() {\n      var color, goal, i, _i, _len, _ref, _results;\n      _ref = this.options.goals;\n      _results = [];\n      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {\n        goal = _ref[i];\n        color = this.options.goalLineColors[i % this.options.goalLineColors.length];\n        _results.push(this.drawGoal(goal, color));\n      }\n      return _results;\n    };\n\n    Grid.prototype.drawEvents = function() {\n      var color, event, i, _i, _len, _ref, _results;\n      _ref = this.events;\n      _results = [];\n      for (i = _i = 0, _len = _ref.length; _i < _len; i = ++_i) {\n        event = _ref[i];\n        color = this.options.eventLineColors[i % this.options.eventLineColors.length];\n        _results.push(this.drawEvent(event, color));\n      }\n      return _results;\n    };\n\n    Grid.prototype.drawGoal = function(goal, color) {\n      return this.raphael.path(\"M\" + this.left + \",\" + (this.transY(goal)) + \"H\" + this.right).attr('stroke', color).attr('stroke-width', this.options.goalStrokeWidth);\n    };\n\n    Grid.prototype.drawEvent = function(event, color) {\n      return this.raphael.path(\"M\" + (this.transX(event)) + \",\" + this.bottom + \"V\" + this.top).attr('stroke', color).attr('stroke-width', this.options.eventStrokeWidth);\n    };\n\n    Grid.prototype.drawYAxisLabel = function(xPos, yPos, text) {\n      return this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor).attr('text-anchor', 'end');\n    };\n\n    Grid.prototype.drawGridLine = function(path) {\n      return this.raphael.path(path).attr('stroke', this.options.gridLineColor).attr('stroke-width', this.options.gridStrokeWidth);\n    };\n\n    Grid.prototype.startRange = function(x) {\n      this.hover.hide();\n      this.selectFrom = x;\n      return this.selectionRect.attr({\n        x: x,\n        width: 0\n      }).show();\n    };\n\n    Grid.prototype.endRange = function(x) {\n      var end, start;\n      if (this.selectFrom) {\n        start = Math.min(this.selectFrom, x);\n        end = Math.max(this.selectFrom, x);\n        this.options.rangeSelect.call(this.el, {\n          start: this.data[this.hitTest(start)].x,\n          end: this.data[this.hitTest(end)].x\n        });\n        return this.selectFrom = null;\n      }\n    };\n\n    Grid.prototype.resizeHandler = function() {\n      this.timeoutId = null;\n      this.raphael.setSize(this.el.width(), this.el.height());\n      return this.redraw();\n    };\n\n    return Grid;\n\n  })(Morris.EventEmitter);\n\n  Morris.parseDate = function(date) {\n    var isecs, m, msecs, n, o, offsetmins, p, q, r, ret, secs;\n    if (typeof date === 'number') {\n      return date;\n    }\n    m = date.match(/^(\\d+) Q(\\d)$/);\n    n = date.match(/^(\\d+)-(\\d+)$/);\n    o = date.match(/^(\\d+)-(\\d+)-(\\d+)$/);\n    p = date.match(/^(\\d+) W(\\d+)$/);\n    q = date.match(/^(\\d+)-(\\d+)-(\\d+)[ T](\\d+):(\\d+)(Z|([+-])(\\d\\d):?(\\d\\d))?$/);\n    r = date.match(/^(\\d+)-(\\d+)-(\\d+)[ T](\\d+):(\\d+):(\\d+(\\.\\d+)?)(Z|([+-])(\\d\\d):?(\\d\\d))?$/);\n    if (m) {\n      return new Date(parseInt(m[1], 10), parseInt(m[2], 10) * 3 - 1, 1).getTime();\n    } else if (n) {\n      return new Date(parseInt(n[1], 10), parseInt(n[2], 10) - 1, 1).getTime();\n    } else if (o) {\n      return new Date(parseInt(o[1], 10), parseInt(o[2], 10) - 1, parseInt(o[3], 10)).getTime();\n    } else if (p) {\n      ret = new Date(parseInt(p[1], 10), 0, 1);\n      if (ret.getDay() !== 4) {\n        ret.setMonth(0, 1 + ((4 - ret.getDay()) + 7) % 7);\n      }\n      return ret.getTime() + parseInt(p[2], 10) * 604800000;\n    } else if (q) {\n      if (!q[6]) {\n        return new Date(parseInt(q[1], 10), parseInt(q[2], 10) - 1, parseInt(q[3], 10), parseInt(q[4], 10), parseInt(q[5], 10)).getTime();\n      } else {\n        offsetmins = 0;\n        if (q[6] !== 'Z') {\n          offsetmins = parseInt(q[8], 10) * 60 + parseInt(q[9], 10);\n          if (q[7] === '+') {\n            offsetmins = 0 - offsetmins;\n          }\n        }\n        return Date.UTC(parseInt(q[1], 10), parseInt(q[2], 10) - 1, parseInt(q[3], 10), parseInt(q[4], 10), parseInt(q[5], 10) + offsetmins);\n      }\n    } else if (r) {\n      secs = parseFloat(r[6]);\n      isecs = Math.floor(secs);\n      msecs = Math.round((secs - isecs) * 1000);\n      if (!r[8]) {\n        return new Date(parseInt(r[1], 10), parseInt(r[2], 10) - 1, parseInt(r[3], 10), parseInt(r[4], 10), parseInt(r[5], 10), isecs, msecs).getTime();\n      } else {\n        offsetmins = 0;\n        if (r[8] !== 'Z') {\n          offsetmins = parseInt(r[10], 10) * 60 + parseInt(r[11], 10);\n          if (r[9] === '+') {\n            offsetmins = 0 - offsetmins;\n          }\n        }\n        return Date.UTC(parseInt(r[1], 10), parseInt(r[2], 10) - 1, parseInt(r[3], 10), parseInt(r[4], 10), parseInt(r[5], 10) + offsetmins, isecs, msecs);\n      }\n    } else {\n      return new Date(parseInt(date, 10), 0, 1).getTime();\n    }\n  };\n\n  Morris.Hover = (function() {\n    Hover.defaults = {\n      \"class\": 'morris-hover morris-default-style'\n    };\n\n    function Hover(options) {\n      if (options == null) {\n        options = {};\n      }\n      this.options = $.extend({}, Morris.Hover.defaults, options);\n      this.el = $(\"<div class='\" + this.options[\"class\"] + \"'></div>\");\n      this.el.hide();\n      this.options.parent.append(this.el);\n    }\n\n    Hover.prototype.update = function(html, x, y) {\n      if (!html) {\n        return this.hide();\n      } else {\n        this.html(html);\n        this.show();\n        return this.moveTo(x, y);\n      }\n    };\n\n    Hover.prototype.html = function(content) {\n      return this.el.html(content);\n    };\n\n    Hover.prototype.moveTo = function(x, y) {\n      var hoverHeight, hoverWidth, left, parentHeight, parentWidth, top;\n      parentWidth = this.options.parent.innerWidth();\n      parentHeight = this.options.parent.innerHeight();\n      hoverWidth = this.el.outerWidth();\n      hoverHeight = this.el.outerHeight();\n      left = Math.min(Math.max(0, x - hoverWidth / 2), parentWidth - hoverWidth);\n      if (y != null) {\n        top = y - hoverHeight - 10;\n        if (top < 0) {\n          top = y + 10;\n          if (top + hoverHeight > parentHeight) {\n            top = parentHeight / 2 - hoverHeight / 2;\n          }\n        }\n      } else {\n        top = parentHeight / 2 - hoverHeight / 2;\n      }\n      return this.el.css({\n        left: left + \"px\",\n        top: parseInt(top) + \"px\"\n      });\n    };\n\n    Hover.prototype.show = function() {\n      return this.el.show();\n    };\n\n    Hover.prototype.hide = function() {\n      return this.el.hide();\n    };\n\n    return Hover;\n\n  })();\n\n  Morris.Line = (function(_super) {\n    __extends(Line, _super);\n\n    function Line(options) {\n      this.hilight = __bind(this.hilight, this);\n      this.onHoverOut = __bind(this.onHoverOut, this);\n      this.onHoverMove = __bind(this.onHoverMove, this);\n      this.onGridClick = __bind(this.onGridClick, this);\n      if (!(this instanceof Morris.Line)) {\n        return new Morris.Line(options);\n      }\n      Line.__super__.constructor.call(this, options);\n    }\n\n    Line.prototype.init = function() {\n      if (this.options.hideHover !== 'always') {\n        this.hover = new Morris.Hover({\n          parent: this.el\n        });\n        this.on('hovermove', this.onHoverMove);\n        this.on('hoverout', this.onHoverOut);\n        return this.on('gridclick', this.onGridClick);\n      }\n    };\n\n    Line.prototype.defaults = {\n      lineWidth: 3,\n      pointSize: 4,\n      lineColors: ['#0b62a4', '#7A92A3', '#4da74d', '#afd8f8', '#edc240', '#cb4b4b', '#9440ed'],\n      pointStrokeWidths: [1],\n      pointStrokeColors: ['#ffffff'],\n      pointFillColors: [],\n      smooth: true,\n      xLabels: 'auto',\n      xLabelFormat: null,\n      xLabelMargin: 24,\n      hideHover: false\n    };\n\n    Line.prototype.calc = function() {\n      this.calcPoints();\n      return this.generatePaths();\n    };\n\n    Line.prototype.calcPoints = function() {\n      var row, y, _i, _len, _ref, _results;\n      _ref = this.data;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        row = _ref[_i];\n        row._x = this.transX(row.x);\n        row._y = (function() {\n          var _j, _len1, _ref1, _results1;\n          _ref1 = row.y;\n          _results1 = [];\n          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n            y = _ref1[_j];\n            if (y != null) {\n              _results1.push(this.transY(y));\n            } else {\n              _results1.push(y);\n            }\n          }\n          return _results1;\n        }).call(this);\n        _results.push(row._ymax = Math.min.apply(Math, [this.bottom].concat((function() {\n          var _j, _len1, _ref1, _results1;\n          _ref1 = row._y;\n          _results1 = [];\n          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n            y = _ref1[_j];\n            if (y != null) {\n              _results1.push(y);\n            }\n          }\n          return _results1;\n        })())));\n      }\n      return _results;\n    };\n\n    Line.prototype.hitTest = function(x) {\n      var index, r, _i, _len, _ref;\n      if (this.data.length === 0) {\n        return null;\n      }\n      _ref = this.data.slice(1);\n      for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {\n        r = _ref[index];\n        if (x < (r._x + this.data[index]._x) / 2) {\n          break;\n        }\n      }\n      return index;\n    };\n\n    Line.prototype.onGridClick = function(x, y) {\n      var index;\n      index = this.hitTest(x);\n      return this.fire('click', index, this.data[index].src, x, y);\n    };\n\n    Line.prototype.onHoverMove = function(x, y) {\n      var index;\n      index = this.hitTest(x);\n      return this.displayHoverForRow(index);\n    };\n\n    Line.prototype.onHoverOut = function() {\n      if (this.options.hideHover !== false) {\n        return this.displayHoverForRow(null);\n      }\n    };\n\n    Line.prototype.displayHoverForRow = function(index) {\n      var _ref;\n      if (index != null) {\n        (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index));\n        return this.hilight(index);\n      } else {\n        this.hover.hide();\n        return this.hilight();\n      }\n    };\n\n    Line.prototype.hoverContentForRow = function(index) {\n      var content, j, row, y, _i, _len, _ref;\n      row = this.data[index];\n      content = \"<div class='morris-hover-row-label'>\" + row.label + \"</div>\";\n      _ref = row.y;\n      for (j = _i = 0, _len = _ref.length; _i < _len; j = ++_i) {\n        y = _ref[j];\n        content += \"<div class='morris-hover-point' style='color: \" + (this.colorFor(row, j, 'label')) + \"'>\\n  \" + this.options.labels[j] + \":\\n  \" + (this.yLabelFormat(y)) + \"\\n</div>\";\n      }\n      if (typeof this.options.hoverCallback === 'function') {\n        content = this.options.hoverCallback(index, this.options, content, row.src);\n      }\n      return [content, row._x, row._ymax];\n    };\n\n    Line.prototype.generatePaths = function() {\n      var coords, i, r, smooth;\n      return this.paths = (function() {\n        var _i, _ref, _ref1, _results;\n        _results = [];\n        for (i = _i = 0, _ref = this.options.ykeys.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n          smooth = typeof this.options.smooth === \"boolean\" ? this.options.smooth : (_ref1 = this.options.ykeys[i], __indexOf.call(this.options.smooth, _ref1) >= 0);\n          coords = (function() {\n            var _j, _len, _ref2, _results1;\n            _ref2 = this.data;\n            _results1 = [];\n            for (_j = 0, _len = _ref2.length; _j < _len; _j++) {\n              r = _ref2[_j];\n              if (r._y[i] !== void 0) {\n                _results1.push({\n                  x: r._x,\n                  y: r._y[i]\n                });\n              }\n            }\n            return _results1;\n          }).call(this);\n          if (coords.length > 1) {\n            _results.push(Morris.Line.createPath(coords, smooth, this.bottom));\n          } else {\n            _results.push(null);\n          }\n        }\n        return _results;\n      }).call(this);\n    };\n\n    Line.prototype.draw = function() {\n      var _ref;\n      if ((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'x') {\n        this.drawXAxis();\n      }\n      this.drawSeries();\n      if (this.options.hideHover === false) {\n        return this.displayHoverForRow(this.data.length - 1);\n      }\n    };\n\n    Line.prototype.drawXAxis = function() {\n      var drawLabel, l, labels, prevAngleMargin, prevLabelMargin, row, ypos, _i, _len, _results,\n        _this = this;\n      ypos = this.bottom + this.options.padding / 2;\n      prevLabelMargin = null;\n      prevAngleMargin = null;\n      drawLabel = function(labelText, xpos) {\n        var label, labelBox, margin, offset, textBox;\n        label = _this.drawXAxisLabel(_this.transX(xpos), ypos, labelText);\n        textBox = label.getBBox();\n        label.transform(\"r\" + (-_this.options.xLabelAngle));\n        labelBox = label.getBBox();\n        label.transform(\"t0,\" + (labelBox.height / 2) + \"...\");\n        if (_this.options.xLabelAngle !== 0) {\n          offset = -0.5 * textBox.width * Math.cos(_this.options.xLabelAngle * Math.PI / 180.0);\n          label.transform(\"t\" + offset + \",0...\");\n        }\n        labelBox = label.getBBox();\n        if (((prevLabelMargin == null) || prevLabelMargin >= labelBox.x + labelBox.width || (prevAngleMargin != null) && prevAngleMargin >= labelBox.x) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < _this.el.width()) {\n          if (_this.options.xLabelAngle !== 0) {\n            margin = 1.25 * _this.options.gridTextSize / Math.sin(_this.options.xLabelAngle * Math.PI / 180.0);\n            prevAngleMargin = labelBox.x - margin;\n          }\n          return prevLabelMargin = labelBox.x - _this.options.xLabelMargin;\n        } else {\n          return label.remove();\n        }\n      };\n      if (this.options.parseTime) {\n        if (this.data.length === 1 && this.options.xLabels === 'auto') {\n          labels = [[this.data[0].label, this.data[0].x]];\n        } else {\n          labels = Morris.labelSeries(this.xmin, this.xmax, this.width, this.options.xLabels, this.options.xLabelFormat);\n        }\n      } else {\n        labels = (function() {\n          var _i, _len, _ref, _results;\n          _ref = this.data;\n          _results = [];\n          for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n            row = _ref[_i];\n            _results.push([row.label, row.x]);\n          }\n          return _results;\n        }).call(this);\n      }\n      labels.reverse();\n      _results = [];\n      for (_i = 0, _len = labels.length; _i < _len; _i++) {\n        l = labels[_i];\n        _results.push(drawLabel(l[0], l[1]));\n      }\n      return _results;\n    };\n\n    Line.prototype.drawSeries = function() {\n      var i, _i, _j, _ref, _ref1, _results;\n      this.seriesPoints = [];\n      for (i = _i = _ref = this.options.ykeys.length - 1; _ref <= 0 ? _i <= 0 : _i >= 0; i = _ref <= 0 ? ++_i : --_i) {\n        this._drawLineFor(i);\n      }\n      _results = [];\n      for (i = _j = _ref1 = this.options.ykeys.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; i = _ref1 <= 0 ? ++_j : --_j) {\n        _results.push(this._drawPointFor(i));\n      }\n      return _results;\n    };\n\n    Line.prototype._drawPointFor = function(index) {\n      var circle, row, _i, _len, _ref, _results;\n      this.seriesPoints[index] = [];\n      _ref = this.data;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        row = _ref[_i];\n        circle = null;\n        if (row._y[index] != null) {\n          circle = this.drawLinePoint(row._x, row._y[index], this.colorFor(row, index, 'point'), index);\n        }\n        _results.push(this.seriesPoints[index].push(circle));\n      }\n      return _results;\n    };\n\n    Line.prototype._drawLineFor = function(index) {\n      var path;\n      path = this.paths[index];\n      if (path !== null) {\n        return this.drawLinePath(path, this.colorFor(null, index, 'line'), index);\n      }\n    };\n\n    Line.createPath = function(coords, smooth, bottom) {\n      var coord, g, grads, i, ix, lg, path, prevCoord, x1, x2, y1, y2, _i, _len;\n      path = \"\";\n      if (smooth) {\n        grads = Morris.Line.gradients(coords);\n      }\n      prevCoord = {\n        y: null\n      };\n      for (i = _i = 0, _len = coords.length; _i < _len; i = ++_i) {\n        coord = coords[i];\n        if (coord.y != null) {\n          if (prevCoord.y != null) {\n            if (smooth) {\n              g = grads[i];\n              lg = grads[i - 1];\n              ix = (coord.x - prevCoord.x) / 4;\n              x1 = prevCoord.x + ix;\n              y1 = Math.min(bottom, prevCoord.y + ix * lg);\n              x2 = coord.x - ix;\n              y2 = Math.min(bottom, coord.y - ix * g);\n              path += \"C\" + x1 + \",\" + y1 + \",\" + x2 + \",\" + y2 + \",\" + coord.x + \",\" + coord.y;\n            } else {\n              path += \"L\" + coord.x + \",\" + coord.y;\n            }\n          } else {\n            if (!smooth || (grads[i] != null)) {\n              path += \"M\" + coord.x + \",\" + coord.y;\n            }\n          }\n        }\n        prevCoord = coord;\n      }\n      return path;\n    };\n\n    Line.gradients = function(coords) {\n      var coord, grad, i, nextCoord, prevCoord, _i, _len, _results;\n      grad = function(a, b) {\n        return (a.y - b.y) / (a.x - b.x);\n      };\n      _results = [];\n      for (i = _i = 0, _len = coords.length; _i < _len; i = ++_i) {\n        coord = coords[i];\n        if (coord.y != null) {\n          nextCoord = coords[i + 1] || {\n            y: null\n          };\n          prevCoord = coords[i - 1] || {\n            y: null\n          };\n          if ((prevCoord.y != null) && (nextCoord.y != null)) {\n            _results.push(grad(prevCoord, nextCoord));\n          } else if (prevCoord.y != null) {\n            _results.push(grad(prevCoord, coord));\n          } else if (nextCoord.y != null) {\n            _results.push(grad(coord, nextCoord));\n          } else {\n            _results.push(null);\n          }\n        } else {\n          _results.push(null);\n        }\n      }\n      return _results;\n    };\n\n    Line.prototype.hilight = function(index) {\n      var i, _i, _j, _ref, _ref1;\n      if (this.prevHilight !== null && this.prevHilight !== index) {\n        for (i = _i = 0, _ref = this.seriesPoints.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {\n          if (this.seriesPoints[i][this.prevHilight]) {\n            this.seriesPoints[i][this.prevHilight].animate(this.pointShrinkSeries(i));\n          }\n        }\n      }\n      if (index !== null && this.prevHilight !== index) {\n        for (i = _j = 0, _ref1 = this.seriesPoints.length - 1; 0 <= _ref1 ? _j <= _ref1 : _j >= _ref1; i = 0 <= _ref1 ? ++_j : --_j) {\n          if (this.seriesPoints[i][index]) {\n            this.seriesPoints[i][index].animate(this.pointGrowSeries(i));\n          }\n        }\n      }\n      return this.prevHilight = index;\n    };\n\n    Line.prototype.colorFor = function(row, sidx, type) {\n      if (typeof this.options.lineColors === 'function') {\n        return this.options.lineColors.call(this, row, sidx, type);\n      } else if (type === 'point') {\n        return this.options.pointFillColors[sidx % this.options.pointFillColors.length] || this.options.lineColors[sidx % this.options.lineColors.length];\n      } else {\n        return this.options.lineColors[sidx % this.options.lineColors.length];\n      }\n    };\n\n    Line.prototype.drawXAxisLabel = function(xPos, yPos, text) {\n      return this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor);\n    };\n\n    Line.prototype.drawLinePath = function(path, lineColor, lineIndex) {\n      return this.raphael.path(path).attr('stroke', lineColor).attr('stroke-width', this.lineWidthForSeries(lineIndex));\n    };\n\n    Line.prototype.drawLinePoint = function(xPos, yPos, pointColor, lineIndex) {\n      return this.raphael.circle(xPos, yPos, this.pointSizeForSeries(lineIndex)).attr('fill', pointColor).attr('stroke-width', this.pointStrokeWidthForSeries(lineIndex)).attr('stroke', this.pointStrokeColorForSeries(lineIndex));\n    };\n\n    Line.prototype.pointStrokeWidthForSeries = function(index) {\n      return this.options.pointStrokeWidths[index % this.options.pointStrokeWidths.length];\n    };\n\n    Line.prototype.pointStrokeColorForSeries = function(index) {\n      return this.options.pointStrokeColors[index % this.options.pointStrokeColors.length];\n    };\n\n    Line.prototype.lineWidthForSeries = function(index) {\n      if (this.options.lineWidth instanceof Array) {\n        return this.options.lineWidth[index % this.options.lineWidth.length];\n      } else {\n        return this.options.lineWidth;\n      }\n    };\n\n    Line.prototype.pointSizeForSeries = function(index) {\n      if (this.options.pointSize instanceof Array) {\n        return this.options.pointSize[index % this.options.pointSize.length];\n      } else {\n        return this.options.pointSize;\n      }\n    };\n\n    Line.prototype.pointGrowSeries = function(index) {\n      return Raphael.animation({\n        r: this.pointSizeForSeries(index) + 3\n      }, 25, 'linear');\n    };\n\n    Line.prototype.pointShrinkSeries = function(index) {\n      return Raphael.animation({\n        r: this.pointSizeForSeries(index)\n      }, 25, 'linear');\n    };\n\n    return Line;\n\n  })(Morris.Grid);\n\n  Morris.labelSeries = function(dmin, dmax, pxwidth, specName, xLabelFormat) {\n    var d, d0, ddensity, name, ret, s, spec, t, _i, _len, _ref;\n    ddensity = 200 * (dmax - dmin) / pxwidth;\n    d0 = new Date(dmin);\n    spec = Morris.LABEL_SPECS[specName];\n    if (spec === void 0) {\n      _ref = Morris.AUTO_LABEL_ORDER;\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        name = _ref[_i];\n        s = Morris.LABEL_SPECS[name];\n        if (ddensity >= s.span) {\n          spec = s;\n          break;\n        }\n      }\n    }\n    if (spec === void 0) {\n      spec = Morris.LABEL_SPECS[\"second\"];\n    }\n    if (xLabelFormat) {\n      spec = $.extend({}, spec, {\n        fmt: xLabelFormat\n      });\n    }\n    d = spec.start(d0);\n    ret = [];\n    while ((t = d.getTime()) <= dmax) {\n      if (t >= dmin) {\n        ret.push([spec.fmt(d), t]);\n      }\n      spec.incr(d);\n    }\n    return ret;\n  };\n\n  minutesSpecHelper = function(interval) {\n    return {\n      span: interval * 60 * 1000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours());\n      },\n      fmt: function(d) {\n        return \"\" + (Morris.pad2(d.getHours())) + \":\" + (Morris.pad2(d.getMinutes()));\n      },\n      incr: function(d) {\n        return d.setUTCMinutes(d.getUTCMinutes() + interval);\n      }\n    };\n  };\n\n  secondsSpecHelper = function(interval) {\n    return {\n      span: interval * 1000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes());\n      },\n      fmt: function(d) {\n        return \"\" + (Morris.pad2(d.getHours())) + \":\" + (Morris.pad2(d.getMinutes())) + \":\" + (Morris.pad2(d.getSeconds()));\n      },\n      incr: function(d) {\n        return d.setUTCSeconds(d.getUTCSeconds() + interval);\n      }\n    };\n  };\n\n  Morris.LABEL_SPECS = {\n    \"decade\": {\n      span: 172800000000,\n      start: function(d) {\n        return new Date(d.getFullYear() - d.getFullYear() % 10, 0, 1);\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear());\n      },\n      incr: function(d) {\n        return d.setFullYear(d.getFullYear() + 10);\n      }\n    },\n    \"year\": {\n      span: 17280000000,\n      start: function(d) {\n        return new Date(d.getFullYear(), 0, 1);\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear());\n      },\n      incr: function(d) {\n        return d.setFullYear(d.getFullYear() + 1);\n      }\n    },\n    \"month\": {\n      span: 2419200000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), 1);\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear()) + \"-\" + (Morris.pad2(d.getMonth() + 1));\n      },\n      incr: function(d) {\n        return d.setMonth(d.getMonth() + 1);\n      }\n    },\n    \"week\": {\n      span: 604800000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear()) + \"-\" + (Morris.pad2(d.getMonth() + 1)) + \"-\" + (Morris.pad2(d.getDate()));\n      },\n      incr: function(d) {\n        return d.setDate(d.getDate() + 7);\n      }\n    },\n    \"day\": {\n      span: 86400000,\n      start: function(d) {\n        return new Date(d.getFullYear(), d.getMonth(), d.getDate());\n      },\n      fmt: function(d) {\n        return \"\" + (d.getFullYear()) + \"-\" + (Morris.pad2(d.getMonth() + 1)) + \"-\" + (Morris.pad2(d.getDate()));\n      },\n      incr: function(d) {\n        return d.setDate(d.getDate() + 1);\n      }\n    },\n    \"hour\": minutesSpecHelper(60),\n    \"30min\": minutesSpecHelper(30),\n    \"15min\": minutesSpecHelper(15),\n    \"10min\": minutesSpecHelper(10),\n    \"5min\": minutesSpecHelper(5),\n    \"minute\": minutesSpecHelper(1),\n    \"30sec\": secondsSpecHelper(30),\n    \"15sec\": secondsSpecHelper(15),\n    \"10sec\": secondsSpecHelper(10),\n    \"5sec\": secondsSpecHelper(5),\n    \"second\": secondsSpecHelper(1)\n  };\n\n  Morris.AUTO_LABEL_ORDER = [\"decade\", \"year\", \"month\", \"week\", \"day\", \"hour\", \"30min\", \"15min\", \"10min\", \"5min\", \"minute\", \"30sec\", \"15sec\", \"10sec\", \"5sec\", \"second\"];\n\n  Morris.Area = (function(_super) {\n    var areaDefaults;\n\n    __extends(Area, _super);\n\n    areaDefaults = {\n      fillOpacity: 'auto',\n      behaveLikeLine: false\n    };\n\n    function Area(options) {\n      var areaOptions;\n      if (!(this instanceof Morris.Area)) {\n        return new Morris.Area(options);\n      }\n      areaOptions = $.extend({}, areaDefaults, options);\n      this.cumulative = !areaOptions.behaveLikeLine;\n      if (areaOptions.fillOpacity === 'auto') {\n        areaOptions.fillOpacity = areaOptions.behaveLikeLine ? .8 : 1;\n      }\n      Area.__super__.constructor.call(this, areaOptions);\n    }\n\n    Area.prototype.calcPoints = function() {\n      var row, total, y, _i, _len, _ref, _results;\n      _ref = this.data;\n      _results = [];\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        row = _ref[_i];\n        row._x = this.transX(row.x);\n        total = 0;\n        row._y = (function() {\n          var _j, _len1, _ref1, _results1;\n          _ref1 = row.y;\n          _results1 = [];\n          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n            y = _ref1[_j];\n            if (this.options.behaveLikeLine) {\n              _results1.push(this.transY(y));\n            } else {\n              total += y || 0;\n              _results1.push(this.transY(total));\n            }\n          }\n          return _results1;\n        }).call(this);\n        _results.push(row._ymax = Math.max.apply(Math, row._y));\n      }\n      return _results;\n    };\n\n    Area.prototype.drawSeries = function() {\n      var i, range, _i, _j, _k, _len, _ref, _ref1, _results, _results1, _results2;\n      this.seriesPoints = [];\n      if (this.options.behaveLikeLine) {\n        range = (function() {\n          _results = [];\n          for (var _i = 0, _ref = this.options.ykeys.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; 0 <= _ref ? _i++ : _i--){ _results.push(_i); }\n          return _results;\n        }).apply(this);\n      } else {\n        range = (function() {\n          _results1 = [];\n          for (var _j = _ref1 = this.options.ykeys.length - 1; _ref1 <= 0 ? _j <= 0 : _j >= 0; _ref1 <= 0 ? _j++ : _j--){ _results1.push(_j); }\n          return _results1;\n        }).apply(this);\n      }\n      _results2 = [];\n      for (_k = 0, _len = range.length; _k < _len; _k++) {\n        i = range[_k];\n        this._drawFillFor(i);\n        this._drawLineFor(i);\n        _results2.push(this._drawPointFor(i));\n      }\n      return _results2;\n    };\n\n    Area.prototype._drawFillFor = function(index) {\n      var path;\n      path = this.paths[index];\n      if (path !== null) {\n        path = path + (\"L\" + (this.transX(this.xmax)) + \",\" + this.bottom + \"L\" + (this.transX(this.xmin)) + \",\" + this.bottom + \"Z\");\n        return this.drawFilledPath(path, this.fillForSeries(index));\n      }\n    };\n\n    Area.prototype.fillForSeries = function(i) {\n      var color;\n      color = Raphael.rgb2hsl(this.colorFor(this.data[i], i, 'line'));\n      return Raphael.hsl(color.h, this.options.behaveLikeLine ? color.s * 0.9 : color.s * 0.75, Math.min(0.98, this.options.behaveLikeLine ? color.l * 1.2 : color.l * 1.25));\n    };\n\n    Area.prototype.drawFilledPath = function(path, fill) {\n      return this.raphael.path(path).attr('fill', fill).attr('fill-opacity', this.options.fillOpacity).attr('stroke', 'none');\n    };\n\n    return Area;\n\n  })(Morris.Line);\n\n  Morris.Bar = (function(_super) {\n    __extends(Bar, _super);\n\n    function Bar(options) {\n      this.onHoverOut = __bind(this.onHoverOut, this);\n      this.onHoverMove = __bind(this.onHoverMove, this);\n      this.onGridClick = __bind(this.onGridClick, this);\n      if (!(this instanceof Morris.Bar)) {\n        return new Morris.Bar(options);\n      }\n      Bar.__super__.constructor.call(this, $.extend({}, options, {\n        parseTime: false\n      }));\n    }\n\n    Bar.prototype.init = function() {\n      this.cumulative = this.options.stacked;\n      if (this.options.hideHover !== 'always') {\n        this.hover = new Morris.Hover({\n          parent: this.el\n        });\n        this.on('hovermove', this.onHoverMove);\n        this.on('hoverout', this.onHoverOut);\n        return this.on('gridclick', this.onGridClick);\n      }\n    };\n\n    Bar.prototype.defaults = {\n      barSizeRatio: 0.75,\n      barGap: 3,\n      barColors: ['#0b62a4', '#7a92a3', '#4da74d', '#afd8f8', '#edc240', '#cb4b4b', '#9440ed'],\n      barOpacity: 1.0,\n      barRadius: [0, 0, 0, 0],\n      xLabelMargin: 50\n    };\n\n    Bar.prototype.calc = function() {\n      var _ref;\n      this.calcBars();\n      if (this.options.hideHover === false) {\n        return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(this.data.length - 1));\n      }\n    };\n\n    Bar.prototype.calcBars = function() {\n      var idx, row, y, _i, _len, _ref, _results;\n      _ref = this.data;\n      _results = [];\n      for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {\n        row = _ref[idx];\n        row._x = this.left + this.width * (idx + 0.5) / this.data.length;\n        _results.push(row._y = (function() {\n          var _j, _len1, _ref1, _results1;\n          _ref1 = row.y;\n          _results1 = [];\n          for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {\n            y = _ref1[_j];\n            if (y != null) {\n              _results1.push(this.transY(y));\n            } else {\n              _results1.push(null);\n            }\n          }\n          return _results1;\n        }).call(this));\n      }\n      return _results;\n    };\n\n    Bar.prototype.draw = function() {\n      var _ref;\n      if ((_ref = this.options.axes) === true || _ref === 'both' || _ref === 'x') {\n        this.drawXAxis();\n      }\n      return this.drawSeries();\n    };\n\n    Bar.prototype.drawXAxis = function() {\n      var i, label, labelBox, margin, offset, prevAngleMargin, prevLabelMargin, row, textBox, ypos, _i, _ref, _results;\n      ypos = this.bottom + (this.options.xAxisLabelTopPadding || this.options.padding / 2);\n      prevLabelMargin = null;\n      prevAngleMargin = null;\n      _results = [];\n      for (i = _i = 0, _ref = this.data.length; 0 <= _ref ? _i < _ref : _i > _ref; i = 0 <= _ref ? ++_i : --_i) {\n        row = this.data[this.data.length - 1 - i];\n        label = this.drawXAxisLabel(row._x, ypos, row.label);\n        textBox = label.getBBox();\n        label.transform(\"r\" + (-this.options.xLabelAngle));\n        labelBox = label.getBBox();\n        label.transform(\"t0,\" + (labelBox.height / 2) + \"...\");\n        if (this.options.xLabelAngle !== 0) {\n          offset = -0.5 * textBox.width * Math.cos(this.options.xLabelAngle * Math.PI / 180.0);\n          label.transform(\"t\" + offset + \",0...\");\n        }\n        if (((prevLabelMargin == null) || prevLabelMargin >= labelBox.x + labelBox.width || (prevAngleMargin != null) && prevAngleMargin >= labelBox.x) && labelBox.x >= 0 && (labelBox.x + labelBox.width) < this.el.width()) {\n          if (this.options.xLabelAngle !== 0) {\n            margin = 1.25 * this.options.gridTextSize / Math.sin(this.options.xLabelAngle * Math.PI / 180.0);\n            prevAngleMargin = labelBox.x - margin;\n          }\n          _results.push(prevLabelMargin = labelBox.x - this.options.xLabelMargin);\n        } else {\n          _results.push(label.remove());\n        }\n      }\n      return _results;\n    };\n\n    Bar.prototype.drawSeries = function() {\n      var barWidth, bottom, groupWidth, idx, lastTop, left, leftPadding, numBars, row, sidx, size, spaceLeft, top, ypos, zeroPos;\n      groupWidth = this.width / this.options.data.length;\n      numBars = this.options.stacked ? 1 : this.options.ykeys.length;\n      barWidth = (groupWidth * this.options.barSizeRatio - this.options.barGap * (numBars - 1)) / numBars;\n      if (this.options.barSize) {\n        barWidth = Math.min(barWidth, this.options.barSize);\n      }\n      spaceLeft = groupWidth - barWidth * numBars - this.options.barGap * (numBars - 1);\n      leftPadding = spaceLeft / 2;\n      zeroPos = this.ymin <= 0 && this.ymax >= 0 ? this.transY(0) : null;\n      return this.bars = (function() {\n        var _i, _len, _ref, _results;\n        _ref = this.data;\n        _results = [];\n        for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {\n          row = _ref[idx];\n          lastTop = 0;\n          _results.push((function() {\n            var _j, _len1, _ref1, _results1;\n            _ref1 = row._y;\n            _results1 = [];\n            for (sidx = _j = 0, _len1 = _ref1.length; _j < _len1; sidx = ++_j) {\n              ypos = _ref1[sidx];\n              if (ypos !== null) {\n                if (zeroPos) {\n                  top = Math.min(ypos, zeroPos);\n                  bottom = Math.max(ypos, zeroPos);\n                } else {\n                  top = ypos;\n                  bottom = this.bottom;\n                }\n                left = this.left + idx * groupWidth + leftPadding;\n                if (!this.options.stacked) {\n                  left += sidx * (barWidth + this.options.barGap);\n                }\n                size = bottom - top;\n                if (this.options.verticalGridCondition && this.options.verticalGridCondition(row.x)) {\n                  this.drawBar(this.left + idx * groupWidth, this.top, groupWidth, Math.abs(this.top - this.bottom), this.options.verticalGridColor, this.options.verticalGridOpacity, this.options.barRadius);\n                }\n                if (this.options.stacked) {\n                  top -= lastTop;\n                }\n                this.drawBar(left, top, barWidth, size, this.colorFor(row, sidx, 'bar'), this.options.barOpacity, this.options.barRadius);\n                _results1.push(lastTop += size);\n              } else {\n                _results1.push(null);\n              }\n            }\n            return _results1;\n          }).call(this));\n        }\n        return _results;\n      }).call(this);\n    };\n\n    Bar.prototype.colorFor = function(row, sidx, type) {\n      var r, s;\n      if (typeof this.options.barColors === 'function') {\n        r = {\n          x: row.x,\n          y: row.y[sidx],\n          label: row.label\n        };\n        s = {\n          index: sidx,\n          key: this.options.ykeys[sidx],\n          label: this.options.labels[sidx]\n        };\n        return this.options.barColors.call(this, r, s, type);\n      } else {\n        return this.options.barColors[sidx % this.options.barColors.length];\n      }\n    };\n\n    Bar.prototype.hitTest = function(x) {\n      if (this.data.length === 0) {\n        return null;\n      }\n      x = Math.max(Math.min(x, this.right), this.left);\n      return Math.min(this.data.length - 1, Math.floor((x - this.left) / (this.width / this.data.length)));\n    };\n\n    Bar.prototype.onGridClick = function(x, y) {\n      var index;\n      index = this.hitTest(x);\n      return this.fire('click', index, this.data[index].src, x, y);\n    };\n\n    Bar.prototype.onHoverMove = function(x, y) {\n      var index, _ref;\n      index = this.hitTest(x);\n      return (_ref = this.hover).update.apply(_ref, this.hoverContentForRow(index));\n    };\n\n    Bar.prototype.onHoverOut = function() {\n      if (this.options.hideHover !== false) {\n        return this.hover.hide();\n      }\n    };\n\n    Bar.prototype.hoverContentForRow = function(index) {\n      var content, j, row, x, y, _i, _len, _ref;\n      row = this.data[index];\n      content = \"<div class='morris-hover-row-label'>\" + row.label + \"</div>\";\n      _ref = row.y;\n      for (j = _i = 0, _len = _ref.length; _i < _len; j = ++_i) {\n        y = _ref[j];\n        content += \"<div class='morris-hover-point' style='color: \" + (this.colorFor(row, j, 'label')) + \"'>\\n  \" + this.options.labels[j] + \":\\n  \" + (this.yLabelFormat(y)) + \"\\n</div>\";\n      }\n      if (typeof this.options.hoverCallback === 'function') {\n        content = this.options.hoverCallback(index, this.options, content, row.src);\n      }\n      x = this.left + (index + 0.5) * this.width / this.data.length;\n      return [content, x];\n    };\n\n    Bar.prototype.drawXAxisLabel = function(xPos, yPos, text) {\n      var label;\n      return label = this.raphael.text(xPos, yPos, text).attr('font-size', this.options.gridTextSize).attr('font-family', this.options.gridTextFamily).attr('font-weight', this.options.gridTextWeight).attr('fill', this.options.gridTextColor);\n    };\n\n    Bar.prototype.drawBar = function(xPos, yPos, width, height, barColor, opacity, radiusArray) {\n      var maxRadius, path;\n      maxRadius = Math.max.apply(Math, radiusArray);\n      if (maxRadius === 0 || maxRadius > height) {\n        path = this.raphael.rect(xPos, yPos, width, height);\n      } else {\n        path = this.raphael.path(this.roundedRect(xPos, yPos, width, height, radiusArray));\n      }\n      return path.attr('fill', barColor).attr('fill-opacity', opacity).attr('stroke', 'none');\n    };\n\n    Bar.prototype.roundedRect = function(x, y, w, h, r) {\n      if (r == null) {\n        r = [0, 0, 0, 0];\n      }\n      return [\"M\", x, r[0] + y, \"Q\", x, y, x + r[0], y, \"L\", x + w - r[1], y, \"Q\", x + w, y, x + w, y + r[1], \"L\", x + w, y + h - r[2], \"Q\", x + w, y + h, x + w - r[2], y + h, \"L\", x + r[3], y + h, \"Q\", x, y + h, x, y + h - r[3], \"Z\"];\n    };\n\n    return Bar;\n\n  })(Morris.Grid);\n\n  Morris.Donut = (function(_super) {\n    __extends(Donut, _super);\n\n    Donut.prototype.defaults = {\n      colors: ['#0B62A4', '#3980B5', '#679DC6', '#95BBD7', '#B0CCE1', '#095791', '#095085', '#083E67', '#052C48', '#042135'],\n      backgroundColor: '#FFFFFF',\n      labelColor: '#000000',\n      formatter: Morris.commas,\n      resize: false\n    };\n\n    function Donut(options) {\n      this.resizeHandler = __bind(this.resizeHandler, this);\n      this.select = __bind(this.select, this);\n      this.click = __bind(this.click, this);\n      var _this = this;\n      if (!(this instanceof Morris.Donut)) {\n        return new Morris.Donut(options);\n      }\n      this.options = $.extend({}, this.defaults, options);\n      if (typeof options.element === 'string') {\n        this.el = $(document.getElementById(options.element));\n      } else {\n        this.el = $(options.element);\n      }\n      if (this.el === null || this.el.length === 0) {\n        throw new Error(\"Graph placeholder not found.\");\n      }\n      if (options.data === void 0 || options.data.length === 0) {\n        return;\n      }\n      this.raphael = new Raphael(this.el[0]);\n      if (this.options.resize) {\n        $(window).bind('resize', function(evt) {\n          if (_this.timeoutId != null) {\n            window.clearTimeout(_this.timeoutId);\n          }\n          return _this.timeoutId = window.setTimeout(_this.resizeHandler, 100);\n        });\n      }\n      this.setData(options.data);\n    }\n\n    Donut.prototype.redraw = function() {\n      var C, cx, cy, i, idx, last, max_value, min, next, seg, total, value, w, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _results;\n      this.raphael.clear();\n      cx = this.el.width() / 2;\n      cy = this.el.height() / 2;\n      w = (Math.min(cx, cy) - 10) / 3;\n      total = 0;\n      _ref = this.values;\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        value = _ref[_i];\n        total += value;\n      }\n      min = 5 / (2 * w);\n      C = 1.9999 * Math.PI - min * this.data.length;\n      last = 0;\n      idx = 0;\n      this.segments = [];\n      _ref1 = this.values;\n      for (i = _j = 0, _len1 = _ref1.length; _j < _len1; i = ++_j) {\n        value = _ref1[i];\n        next = last + min + C * (value / total);\n        seg = new Morris.DonutSegment(cx, cy, w * 2, w, last, next, this.data[i].color || this.options.colors[idx % this.options.colors.length], this.options.backgroundColor, idx, this.raphael);\n        seg.render();\n        this.segments.push(seg);\n        seg.on('hover', this.select);\n        seg.on('click', this.click);\n        last = next;\n        idx += 1;\n      }\n      this.text1 = this.drawEmptyDonutLabel(cx, cy - 10, this.options.labelColor, 15, 800);\n      this.text2 = this.drawEmptyDonutLabel(cx, cy + 10, this.options.labelColor, 14);\n      max_value = Math.max.apply(Math, this.values);\n      idx = 0;\n      _ref2 = this.values;\n      _results = [];\n      for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {\n        value = _ref2[_k];\n        if (value === max_value) {\n          this.select(idx);\n          break;\n        }\n        _results.push(idx += 1);\n      }\n      return _results;\n    };\n\n    Donut.prototype.setData = function(data) {\n      var row;\n      this.data = data;\n      this.values = (function() {\n        var _i, _len, _ref, _results;\n        _ref = this.data;\n        _results = [];\n        for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n          row = _ref[_i];\n          _results.push(parseFloat(row.value));\n        }\n        return _results;\n      }).call(this);\n      return this.redraw();\n    };\n\n    Donut.prototype.click = function(idx) {\n      return this.fire('click', idx, this.data[idx]);\n    };\n\n    Donut.prototype.select = function(idx) {\n      var row, s, segment, _i, _len, _ref;\n      _ref = this.segments;\n      for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n        s = _ref[_i];\n        s.deselect();\n      }\n      segment = this.segments[idx];\n      segment.select();\n      row = this.data[idx];\n      return this.setLabels(row.label, this.options.formatter(row.value, row));\n    };\n\n    Donut.prototype.setLabels = function(label1, label2) {\n      var inner, maxHeightBottom, maxHeightTop, maxWidth, text1bbox, text1scale, text2bbox, text2scale;\n      inner = (Math.min(this.el.width() / 2, this.el.height() / 2) - 10) * 2 / 3;\n      maxWidth = 1.8 * inner;\n      maxHeightTop = inner / 2;\n      maxHeightBottom = inner / 3;\n      this.text1.attr({\n        text: label1,\n        transform: ''\n      });\n      text1bbox = this.text1.getBBox();\n      text1scale = Math.min(maxWidth / text1bbox.width, maxHeightTop / text1bbox.height);\n      this.text1.attr({\n        transform: \"S\" + text1scale + \",\" + text1scale + \",\" + (text1bbox.x + text1bbox.width / 2) + \",\" + (text1bbox.y + text1bbox.height)\n      });\n      this.text2.attr({\n        text: label2,\n        transform: ''\n      });\n      text2bbox = this.text2.getBBox();\n      text2scale = Math.min(maxWidth / text2bbox.width, maxHeightBottom / text2bbox.height);\n      return this.text2.attr({\n        transform: \"S\" + text2scale + \",\" + text2scale + \",\" + (text2bbox.x + text2bbox.width / 2) + \",\" + text2bbox.y\n      });\n    };\n\n    Donut.prototype.drawEmptyDonutLabel = function(xPos, yPos, color, fontSize, fontWeight) {\n      var text;\n      text = this.raphael.text(xPos, yPos, '').attr('font-size', fontSize).attr('fill', color);\n      if (fontWeight != null) {\n        text.attr('font-weight', fontWeight);\n      }\n      return text;\n    };\n\n    Donut.prototype.resizeHandler = function() {\n      this.timeoutId = null;\n      this.raphael.setSize(this.el.width(), this.el.height());\n      return this.redraw();\n    };\n\n    return Donut;\n\n  })(Morris.EventEmitter);\n\n  Morris.DonutSegment = (function(_super) {\n    __extends(DonutSegment, _super);\n\n    function DonutSegment(cx, cy, inner, outer, p0, p1, color, backgroundColor, index, raphael) {\n      this.cx = cx;\n      this.cy = cy;\n      this.inner = inner;\n      this.outer = outer;\n      this.color = color;\n      this.backgroundColor = backgroundColor;\n      this.index = index;\n      this.raphael = raphael;\n      this.deselect = __bind(this.deselect, this);\n      this.select = __bind(this.select, this);\n      this.sin_p0 = Math.sin(p0);\n      this.cos_p0 = Math.cos(p0);\n      this.sin_p1 = Math.sin(p1);\n      this.cos_p1 = Math.cos(p1);\n      this.is_long = (p1 - p0) > Math.PI ? 1 : 0;\n      this.path = this.calcSegment(this.inner + 3, this.inner + this.outer - 5);\n      this.selectedPath = this.calcSegment(this.inner + 3, this.inner + this.outer);\n      this.hilight = this.calcArc(this.inner);\n    }\n\n    DonutSegment.prototype.calcArcPoints = function(r) {\n      return [this.cx + r * this.sin_p0, this.cy + r * this.cos_p0, this.cx + r * this.sin_p1, this.cy + r * this.cos_p1];\n    };\n\n    DonutSegment.prototype.calcSegment = function(r1, r2) {\n      var ix0, ix1, iy0, iy1, ox0, ox1, oy0, oy1, _ref, _ref1;\n      _ref = this.calcArcPoints(r1), ix0 = _ref[0], iy0 = _ref[1], ix1 = _ref[2], iy1 = _ref[3];\n      _ref1 = this.calcArcPoints(r2), ox0 = _ref1[0], oy0 = _ref1[1], ox1 = _ref1[2], oy1 = _ref1[3];\n      return (\"M\" + ix0 + \",\" + iy0) + (\"A\" + r1 + \",\" + r1 + \",0,\" + this.is_long + \",0,\" + ix1 + \",\" + iy1) + (\"L\" + ox1 + \",\" + oy1) + (\"A\" + r2 + \",\" + r2 + \",0,\" + this.is_long + \",1,\" + ox0 + \",\" + oy0) + \"Z\";\n    };\n\n    DonutSegment.prototype.calcArc = function(r) {\n      var ix0, ix1, iy0, iy1, _ref;\n      _ref = this.calcArcPoints(r), ix0 = _ref[0], iy0 = _ref[1], ix1 = _ref[2], iy1 = _ref[3];\n      return (\"M\" + ix0 + \",\" + iy0) + (\"A\" + r + \",\" + r + \",0,\" + this.is_long + \",0,\" + ix1 + \",\" + iy1);\n    };\n\n    DonutSegment.prototype.render = function() {\n      var _this = this;\n      this.arc = this.drawDonutArc(this.hilight, this.color);\n      return this.seg = this.drawDonutSegment(this.path, this.color, this.backgroundColor, function() {\n        return _this.fire('hover', _this.index);\n      }, function() {\n        return _this.fire('click', _this.index);\n      });\n    };\n\n    DonutSegment.prototype.drawDonutArc = function(path, color) {\n      return this.raphael.path(path).attr({\n        stroke: color,\n        'stroke-width': 2,\n        opacity: 0\n      });\n    };\n\n    DonutSegment.prototype.drawDonutSegment = function(path, fillColor, strokeColor, hoverFunction, clickFunction) {\n      return this.raphael.path(path).attr({\n        fill: fillColor,\n        stroke: strokeColor,\n        'stroke-width': 3\n      }).hover(hoverFunction).click(clickFunction);\n    };\n\n    DonutSegment.prototype.select = function() {\n      if (!this.selected) {\n        this.seg.animate({\n          path: this.selectedPath\n        }, 150, '<>');\n        this.arc.animate({\n          opacity: 1\n        }, 150, '<>');\n        return this.selected = true;\n      }\n    };\n\n    DonutSegment.prototype.deselect = function() {\n      if (this.selected) {\n        this.seg.animate({\n          path: this.path\n        }, 150, '<>');\n        this.arc.animate({\n          opacity: 0\n        }, 150, '<>');\n        return this.selected = false;\n      }\n    };\n\n    return DonutSegment;\n\n  })(Morris.EventEmitter);\n\n}).call(this);"
  },
  {
    "path": "public/static/plugins/nprogress/nprogress.css",
    "content": "/* Make clicks pass-through */\n#nprogress {\n  pointer-events: none;\n}\n\n#nprogress .bar {\n  background: #29d;\n\n  position: fixed;\n  z-index: 1031;\n  top: 0;\n  left: 0;\n\n  width: 100%;\n  height: 2px;\n}\n\n/* Fancy blur effect */\n#nprogress .peg {\n  display: block;\n  position: absolute;\n  right: 0px;\n  width: 100px;\n  height: 100%;\n  box-shadow: 0 0 10px #29d, 0 0 5px #29d;\n  opacity: 1.0;\n\n  -webkit-transform: rotate(3deg) translate(0px, -4px);\n      -ms-transform: rotate(3deg) translate(0px, -4px);\n          transform: rotate(3deg) translate(0px, -4px);\n}\n\n/* Remove these to get rid of the spinner */\n#nprogress .spinner {\n  display: block;\n  position: fixed;\n  z-index: 1031;\n  top: 15px;\n  right: 15px;\n}\n\n#nprogress .spinner-icon {\n  width: 18px;\n  height: 18px;\n  box-sizing: border-box;\n\n  border: solid 2px transparent;\n  border-top-color: #29d;\n  border-left-color: #29d;\n  border-radius: 50%;\n\n  -webkit-animation: nprogress-spinner 400ms linear infinite;\n          animation: nprogress-spinner 400ms linear infinite;\n}\n\n.nprogress-custom-parent {\n  overflow: hidden;\n  position: relative;\n}\n\n.nprogress-custom-parent #nprogress .spinner,\n.nprogress-custom-parent #nprogress .bar {\n  position: absolute;\n}\n\n@-webkit-keyframes nprogress-spinner {\n  0%   { -webkit-transform: rotate(0deg); }\n  100% { -webkit-transform: rotate(360deg); }\n}\n@keyframes nprogress-spinner {\n  0%   { transform: rotate(0deg); }\n  100% { transform: rotate(360deg); }\n}\n\n"
  },
  {
    "path": "public/static/plugins/nprogress/nprogress.js",
    "content": "/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress\n * @license MIT */\n\n;(function(root, factory) {\n\n  if (typeof define === 'function' && define.amd) {\n    define(factory);\n  } else if (typeof exports === 'object') {\n    module.exports = factory();\n  } else {\n    root.NProgress = factory();\n  }\n\n})(this, function() {\n  var NProgress = {};\n\n  NProgress.version = '0.2.0';\n\n  var Settings = NProgress.settings = {\n    minimum: 0.08,\n    easing: 'ease',\n    positionUsing: '',\n    speed: 200,\n    trickle: true,\n    trickleRate: 0.02,\n    trickleSpeed: 800,\n    showSpinner: true,\n    barSelector: '[role=\"bar\"]',\n    spinnerSelector: '[role=\"spinner\"]',\n    parent: 'body',\n    template: '<div class=\"bar\" role=\"bar\"><div class=\"peg\"></div></div><div class=\"spinner\" role=\"spinner\"><div class=\"spinner-icon\"></div></div>'\n  };\n\n  /**\n   * Updates configuration.\n   *\n   *     NProgress.configure({\n   *       minimum: 0.1\n   *     });\n   */\n  NProgress.configure = function(options) {\n    var key, value;\n    for (key in options) {\n      value = options[key];\n      if (value !== undefined && options.hasOwnProperty(key)) Settings[key] = value;\n    }\n\n    return this;\n  };\n\n  /**\n   * Last number.\n   */\n\n  NProgress.status = null;\n\n  /**\n   * Sets the progress bar status, where `n` is a number from `0.0` to `1.0`.\n   *\n   *     NProgress.set(0.4);\n   *     NProgress.set(1.0);\n   */\n\n  NProgress.set = function(n) {\n    var started = NProgress.isStarted();\n\n    n = clamp(n, Settings.minimum, 1);\n    NProgress.status = (n === 1 ? null : n);\n\n    var progress = NProgress.render(!started),\n        bar      = progress.querySelector(Settings.barSelector),\n        speed    = Settings.speed,\n        ease     = Settings.easing;\n\n    progress.offsetWidth; /* Repaint */\n\n    queue(function(next) {\n      // Set positionUsing if it hasn't already been set\n      if (Settings.positionUsing === '') Settings.positionUsing = NProgress.getPositioningCSS();\n\n      // Add transition\n      css(bar, barPositionCSS(n, speed, ease));\n\n      if (n === 1) {\n        // Fade out\n        css(progress, { \n          transition: 'none', \n          opacity: 1 \n        });\n        progress.offsetWidth; /* Repaint */\n\n        setTimeout(function() {\n          css(progress, { \n            transition: 'all ' + speed + 'ms linear', \n            opacity: 0 \n          });\n          setTimeout(function() {\n            NProgress.remove();\n            next();\n          }, speed);\n        }, speed);\n      } else {\n        setTimeout(next, speed);\n      }\n    });\n\n    return this;\n  };\n\n  NProgress.isStarted = function() {\n    return typeof NProgress.status === 'number';\n  };\n\n  /**\n   * Shows the progress bar.\n   * This is the same as setting the status to 0%, except that it doesn't go backwards.\n   *\n   *     NProgress.start();\n   *\n   */\n  NProgress.start = function() {\n    if (!NProgress.status) NProgress.set(0);\n\n    var work = function() {\n      setTimeout(function() {\n        if (!NProgress.status) return;\n        NProgress.trickle();\n        work();\n      }, Settings.trickleSpeed);\n    };\n\n    if (Settings.trickle) work();\n\n    return this;\n  };\n\n  /**\n   * Hides the progress bar.\n   * This is the *sort of* the same as setting the status to 100%, with the\n   * difference being `done()` makes some placebo effect of some realistic motion.\n   *\n   *     NProgress.done();\n   *\n   * If `true` is passed, it will show the progress bar even if its hidden.\n   *\n   *     NProgress.done(true);\n   */\n\n  NProgress.done = function(force) {\n    if (!force && !NProgress.status) return this;\n\n    return NProgress.inc(0.3 + 0.5 * Math.random()).set(1);\n  };\n\n  /**\n   * Increments by a random amount.\n   */\n\n  NProgress.inc = function(amount) {\n    var n = NProgress.status;\n\n    if (!n) {\n      return NProgress.start();\n    } else {\n      if (typeof amount !== 'number') {\n        amount = (1 - n) * clamp(Math.random() * n, 0.1, 0.95);\n      }\n\n      n = clamp(n + amount, 0, 0.994);\n      return NProgress.set(n);\n    }\n  };\n\n  NProgress.trickle = function() {\n    return NProgress.inc(Math.random() * Settings.trickleRate);\n  };\n\n  /**\n   * Waits for all supplied jQuery promises and\n   * increases the progress as the promises resolve.\n   *\n   * @param $promise jQUery Promise\n   */\n  (function() {\n    var initial = 0, current = 0;\n\n    NProgress.promise = function($promise) {\n      if (!$promise || $promise.state() === \"resolved\") {\n        return this;\n      }\n\n      if (current === 0) {\n        NProgress.start();\n      }\n\n      initial++;\n      current++;\n\n      $promise.always(function() {\n        current--;\n        if (current === 0) {\n            initial = 0;\n            NProgress.done();\n        } else {\n            NProgress.set((initial - current) / initial);\n        }\n      });\n\n      return this;\n    };\n\n  })();\n\n  /**\n   * (Internal) renders the progress bar markup based on the `template`\n   * setting.\n   */\n\n  NProgress.render = function(fromStart) {\n    if (NProgress.isRendered()) return document.getElementById('nprogress');\n\n    addClass(document.documentElement, 'nprogress-busy');\n    \n    var progress = document.createElement('div');\n    progress.id = 'nprogress';\n    progress.innerHTML = Settings.template;\n\n    var bar      = progress.querySelector(Settings.barSelector),\n        perc     = fromStart ? '-100' : toBarPerc(NProgress.status || 0),\n        parent   = document.querySelector(Settings.parent),\n        spinner;\n    \n    css(bar, {\n      transition: 'all 0 linear',\n      transform: 'translate3d(' + perc + '%,0,0)'\n    });\n\n    if (!Settings.showSpinner) {\n      spinner = progress.querySelector(Settings.spinnerSelector);\n      spinner && removeElement(spinner);\n    }\n\n    if (parent != document.body) {\n      addClass(parent, 'nprogress-custom-parent');\n    }\n\n    parent.appendChild(progress);\n    return progress;\n  };\n\n  /**\n   * Removes the element. Opposite of render().\n   */\n\n  NProgress.remove = function() {\n    removeClass(document.documentElement, 'nprogress-busy');\n    removeClass(document.querySelector(Settings.parent), 'nprogress-custom-parent');\n    var progress = document.getElementById('nprogress');\n    progress && removeElement(progress);\n  };\n\n  /**\n   * Checks if the progress bar is rendered.\n   */\n\n  NProgress.isRendered = function() {\n    return !!document.getElementById('nprogress');\n  };\n\n  /**\n   * Determine which positioning CSS rule to use.\n   */\n\n  NProgress.getPositioningCSS = function() {\n    // Sniff on document.body.style\n    var bodyStyle = document.body.style;\n\n    // Sniff prefixes\n    var vendorPrefix = ('WebkitTransform' in bodyStyle) ? 'Webkit' :\n                       ('MozTransform' in bodyStyle) ? 'Moz' :\n                       ('msTransform' in bodyStyle) ? 'ms' :\n                       ('OTransform' in bodyStyle) ? 'O' : '';\n\n    if (vendorPrefix + 'Perspective' in bodyStyle) {\n      // Modern browsers with 3D support, e.g. Webkit, IE10\n      return 'translate3d';\n    } else if (vendorPrefix + 'Transform' in bodyStyle) {\n      // Browsers without 3D support, e.g. IE9\n      return 'translate';\n    } else {\n      // Browsers without translate() support, e.g. IE7-8\n      return 'margin';\n    }\n  };\n\n  /**\n   * Helpers\n   */\n\n  function clamp(n, min, max) {\n    if (n < min) return min;\n    if (n > max) return max;\n    return n;\n  }\n\n  /**\n   * (Internal) converts a percentage (`0..1`) to a bar translateX\n   * percentage (`-100%..0%`).\n   */\n\n  function toBarPerc(n) {\n    return (-1 + n) * 100;\n  }\n\n\n  /**\n   * (Internal) returns the correct CSS for changing the bar's\n   * position given an n percentage, and speed and ease from Settings\n   */\n\n  function barPositionCSS(n, speed, ease) {\n    var barCSS;\n\n    if (Settings.positionUsing === 'translate3d') {\n      barCSS = { transform: 'translate3d('+toBarPerc(n)+'%,0,0)' };\n    } else if (Settings.positionUsing === 'translate') {\n      barCSS = { transform: 'translate('+toBarPerc(n)+'%,0)' };\n    } else {\n      barCSS = { 'margin-left': toBarPerc(n)+'%' };\n    }\n\n    barCSS.transition = 'all '+speed+'ms '+ease;\n\n    return barCSS;\n  }\n\n  /**\n   * (Internal) Queues a function to be executed.\n   */\n\n  var queue = (function() {\n    var pending = [];\n    \n    function next() {\n      var fn = pending.shift();\n      if (fn) {\n        fn(next);\n      }\n    }\n\n    return function(fn) {\n      pending.push(fn);\n      if (pending.length == 1) next();\n    };\n  })();\n\n  /**\n   * (Internal) Applies css properties to an element, similar to the jQuery \n   * css method.\n   *\n   * While this helper does assist with vendor prefixed property names, it \n   * does not perform any manipulation of values prior to setting styles.\n   */\n\n  var css = (function() {\n    var cssPrefixes = [ 'Webkit', 'O', 'Moz', 'ms' ],\n        cssProps    = {};\n\n    function camelCase(string) {\n      return string.replace(/^-ms-/, 'ms-').replace(/-([\\da-z])/gi, function(match, letter) {\n        return letter.toUpperCase();\n      });\n    }\n\n    function getVendorProp(name) {\n      var style = document.body.style;\n      if (name in style) return name;\n\n      var i = cssPrefixes.length,\n          capName = name.charAt(0).toUpperCase() + name.slice(1),\n          vendorName;\n      while (i--) {\n        vendorName = cssPrefixes[i] + capName;\n        if (vendorName in style) return vendorName;\n      }\n\n      return name;\n    }\n\n    function getStyleProp(name) {\n      name = camelCase(name);\n      return cssProps[name] || (cssProps[name] = getVendorProp(name));\n    }\n\n    function applyCss(element, prop, value) {\n      prop = getStyleProp(prop);\n      element.style[prop] = value;\n    }\n\n    return function(element, properties) {\n      var args = arguments,\n          prop, \n          value;\n\n      if (args.length == 2) {\n        for (prop in properties) {\n          value = properties[prop];\n          if (value !== undefined && properties.hasOwnProperty(prop)) applyCss(element, prop, value);\n        }\n      } else {\n        applyCss(element, args[1], args[2]);\n      }\n    }\n  })();\n\n  /**\n   * (Internal) Determines if an element or space separated list of class names contains a class name.\n   */\n\n  function hasClass(element, name) {\n    var list = typeof element == 'string' ? element : classList(element);\n    return list.indexOf(' ' + name + ' ') >= 0;\n  }\n\n  /**\n   * (Internal) Adds a class to an element.\n   */\n\n  function addClass(element, name) {\n    var oldList = classList(element),\n        newList = oldList + name;\n\n    if (hasClass(oldList, name)) return; \n\n    // Trim the opening space.\n    element.className = newList.substring(1);\n  }\n\n  /**\n   * (Internal) Removes a class from an element.\n   */\n\n  function removeClass(element, name) {\n    var oldList = classList(element),\n        newList;\n\n    if (!hasClass(element, name)) return;\n\n    // Replace the class name.\n    newList = oldList.replace(' ' + name + ' ', ' ');\n\n    // Trim the opening and closing spaces.\n    element.className = newList.substring(1, newList.length - 1);\n  }\n\n  /**\n   * (Internal) Gets a space separated list of the class names on the element. \n   * The list is wrapped with a single space on each end to facilitate finding \n   * matches within the list.\n   */\n\n  function classList(element) {\n    return (' ' + (element.className || '') + ' ').replace(/\\s+/gi, ' ');\n  }\n\n  /**\n   * (Internal) Removes an element from the DOM.\n   */\n\n  function removeElement(element) {\n    element && element.parentNode && element.parentNode.removeChild(element);\n  }\n\n  return NProgress;\n});\n\n"
  },
  {
    "path": "public/static/plugins/pace/pace.css",
    "content": ".pace {\n  -webkit-pointer-events: none;\n  pointer-events: none;\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  user-select: none;\n}\n\n.pace-inactive {\n  display: none;\n}\n\n.pace .pace-progress {\n  background: #fff;\n  position: fixed;\n  z-index: 2000;\n  top: 0;\n  right: 100%;\n  width: 100%;\n  height: 2px;\n}\n\n.pace .pace-progress-inner {\n  display: block;\n  position: absolute;\n  right: 0px;\n  width: 100px;\n  height: 100%;\n  box-shadow: 0 0 10px #fff, 0 0 5px #fff;\n  opacity: 1.0;\n  -webkit-transform: rotate(3deg) translate(0px, -4px);\n  -moz-transform: rotate(3deg) translate(0px, -4px);\n  -ms-transform: rotate(3deg) translate(0px, -4px);\n  -o-transform: rotate(3deg) translate(0px, -4px);\n  transform: rotate(3deg) translate(0px, -4px);\n}\n\n.pace .pace-activity {\n  display: block;\n  position: fixed;\n  z-index: 2000;\n  top: 15px;\n  right: 50%;\n  width: 14px;\n  height: 14px;\n  border: solid 2px transparent;\n  border-top-color: #fff;\n  border-left-color: #fff;\n  border-radius: 10px;\n  -webkit-animation: pace-spinner 400ms linear infinite;\n  -moz-animation: pace-spinner 400ms linear infinite;\n  -ms-animation: pace-spinner 400ms linear infinite;\n  -o-animation: pace-spinner 400ms linear infinite;\n  animation: pace-spinner 400ms linear infinite;\n}\n\n@media (max-width: 767px) {\n\t.pace .pace-activity {\n\t  top: 15px;\n\t  right: 15px;\n\t  width: 14px;\n\t  height: 14px;\n\t}\n}\n\n@-webkit-keyframes pace-spinner {\n  0% { -webkit-transform: rotate(0deg); transform: rotate(0deg); }\n  100% { -webkit-transform: rotate(360deg); transform: rotate(360deg); }\n}\n@-moz-keyframes pace-spinner {\n  0% { -moz-transform: rotate(0deg); transform: rotate(0deg); }\n  100% { -moz-transform: rotate(360deg); transform: rotate(360deg); }\n}\n@-o-keyframes pace-spinner {\n  0% { -o-transform: rotate(0deg); transform: rotate(0deg); }\n  100% { -o-transform: rotate(360deg); transform: rotate(360deg); }\n}\n@-ms-keyframes pace-spinner {\n  0% { -ms-transform: rotate(0deg); transform: rotate(0deg); }\n  100% { -ms-transform: rotate(360deg); transform: rotate(360deg); }\n}\n@keyframes pace-spinner {\n  0% { transform: rotate(0deg); transform: rotate(0deg); }\n  100% { transform: rotate(360deg); transform: rotate(360deg); }\n}"
  },
  {
    "path": "public/static/plugins/pace/pace.js",
    "content": "(function() {\n  var AjaxMonitor, Bar, DocumentMonitor, ElementMonitor, ElementTracker, EventLagMonitor, Evented, Events, NoTargetError, Pace, RequestIntercept, SOURCE_KEYS, Scaler, SocketRequestTracker, XHRRequestTracker, animation, avgAmplitude, bar, cancelAnimation, cancelAnimationFrame, defaultOptions, extend, extendNative, getFromDOM, getIntercept, handlePushState, ignoreStack, init, now, options, requestAnimationFrame, result, runAnimation, scalers, shouldIgnoreURL, shouldTrack, source, sources, uniScaler, _WebSocket, _XDomainRequest, _XMLHttpRequest, _i, _intercept, _len, _pushState, _ref, _ref1, _replaceState,\n    __slice = [].slice,\n    __hasProp = {}.hasOwnProperty,\n    __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },\n    __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };\n\n  defaultOptions = {\n    catchupTime: 100,\n    initialRate: .03,\n    minTime: 250,\n    ghostTime: 100,\n    maxProgressPerFrame: 20,\n    easeFactor: 1.25,\n    startOnPageLoad: true,\n    restartOnPushState: true,\n    restartOnRequestAfter: 500,\n    target: 'body',\n    elements: {\n      checkInterval: 100,\n      selectors: ['body']\n    },\n    eventLag: {\n      minSamples: 10,\n      sampleCount: 3,\n      lagThreshold: 3\n    },\n    ajax: {\n      trackMethods: ['GET'],\n      trackWebSockets: true,\n      ignoreURLs: []\n    }\n  };\n\n  now = function() {\n    var _ref;\n    return (_ref = typeof performance !== \"undefined\" && performance !== null ? typeof performance.now === \"function\" ? performance.now() : void 0 : void 0) != null ? _ref : +(new Date);\n  };\n\n  requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;\n\n  cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame;\n\n  if (requestAnimationFrame == null) {\n    requestAnimationFrame = function(fn) {\n      return setTimeout(fn, 50);\n    };\n    cancelAnimationFrame = function(id) {\n      return clearTimeout(id);\n    };\n  }\n\n  runAnimation = function(fn) {\n    var last, tick;\n    last = now();\n    tick = function() {\n      var diff;\n      diff = now() - last;\n      if (diff >= 33) {\n        last = now();\n        return fn(diff, function() {\n          return requestAnimationFrame(tick);\n        });\n      } else {\n        return setTimeout(tick, 33 - diff);\n      }\n    };\n    return tick();\n  };\n\n  result = function() {\n    var args, key, obj;\n    obj = arguments[0], key = arguments[1], args = 3 <= arguments.length ? __slice.call(arguments, 2) : [];\n    if (typeof obj[key] === 'function') {\n      return obj[key].apply(obj, args);\n    } else {\n      return obj[key];\n    }\n  };\n\n  extend = function() {\n    var key, out, source, sources, val, _i, _len;\n    out = arguments[0], sources = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n    for (_i = 0, _len = sources.length; _i < _len; _i++) {\n      source = sources[_i];\n      if (source) {\n        for (key in source) {\n          if (!__hasProp.call(source, key)) continue;\n          val = source[key];\n          if ((out[key] != null) && typeof out[key] === 'object' && (val != null) && typeof val === 'object') {\n            extend(out[key], val);\n          } else {\n            out[key] = val;\n          }\n        }\n      }\n    }\n    return out;\n  };\n\n  avgAmplitude = function(arr) {\n    var count, sum, v, _i, _len;\n    sum = count = 0;\n    for (_i = 0, _len = arr.length; _i < _len; _i++) {\n      v = arr[_i];\n      sum += Math.abs(v);\n      count++;\n    }\n    return sum / count;\n  };\n\n  getFromDOM = function(key, json) {\n    var data, e, el;\n    if (key == null) {\n      key = 'options';\n    }\n    if (json == null) {\n      json = true;\n    }\n    el = document.querySelector(\"[data-pace-\" + key + \"]\");\n    if (!el) {\n      return;\n    }\n    data = el.getAttribute(\"data-pace-\" + key);\n    if (!json) {\n      return data;\n    }\n    try {\n      return JSON.parse(data);\n    } catch (_error) {\n      e = _error;\n      return typeof console !== \"undefined\" && console !== null ? console.error(\"Error parsing inline pace options\", e) : void 0;\n    }\n  };\n\n  Evented = (function() {\n    function Evented() {}\n\n    Evented.prototype.on = function(event, handler, ctx, once) {\n      var _base;\n      if (once == null) {\n        once = false;\n      }\n      if (this.bindings == null) {\n        this.bindings = {};\n      }\n      if ((_base = this.bindings)[event] == null) {\n        _base[event] = [];\n      }\n      return this.bindings[event].push({\n        handler: handler,\n        ctx: ctx,\n        once: once\n      });\n    };\n\n    Evented.prototype.once = function(event, handler, ctx) {\n      return this.on(event, handler, ctx, true);\n    };\n\n    Evented.prototype.off = function(event, handler) {\n      var i, _ref, _results;\n      if (((_ref = this.bindings) != null ? _ref[event] : void 0) == null) {\n        return;\n      }\n      if (handler == null) {\n        return delete this.bindings[event];\n      } else {\n        i = 0;\n        _results = [];\n        while (i < this.bindings[event].length) {\n          if (this.bindings[event][i].handler === handler) {\n            _results.push(this.bindings[event].splice(i, 1));\n          } else {\n            _results.push(i++);\n          }\n        }\n        return _results;\n      }\n    };\n\n    Evented.prototype.trigger = function() {\n      var args, ctx, event, handler, i, once, _ref, _ref1, _results;\n      event = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n      if ((_ref = this.bindings) != null ? _ref[event] : void 0) {\n        i = 0;\n        _results = [];\n        while (i < this.bindings[event].length) {\n          _ref1 = this.bindings[event][i], handler = _ref1.handler, ctx = _ref1.ctx, once = _ref1.once;\n          handler.apply(ctx != null ? ctx : this, args);\n          if (once) {\n            _results.push(this.bindings[event].splice(i, 1));\n          } else {\n            _results.push(i++);\n          }\n        }\n        return _results;\n      }\n    };\n\n    return Evented;\n\n  })();\n\n  Pace = window.Pace || {};\n\n  window.Pace = Pace;\n\n  extend(Pace, Evented.prototype);\n\n  options = Pace.options = extend({}, defaultOptions, window.paceOptions, getFromDOM());\n\n  _ref = ['ajax', 'document', 'eventLag', 'elements'];\n  for (_i = 0, _len = _ref.length; _i < _len; _i++) {\n    source = _ref[_i];\n    if (options[source] === true) {\n      options[source] = defaultOptions[source];\n    }\n  }\n\n  NoTargetError = (function(_super) {\n    __extends(NoTargetError, _super);\n\n    function NoTargetError() {\n      _ref1 = NoTargetError.__super__.constructor.apply(this, arguments);\n      return _ref1;\n    }\n\n    return NoTargetError;\n\n  })(Error);\n\n  Bar = (function() {\n    function Bar() {\n      this.progress = 0;\n    }\n\n    Bar.prototype.getElement = function() {\n      var targetElement;\n      if (this.el == null) {\n        targetElement = document.querySelector(options.target);\n        if (!targetElement) {\n          throw new NoTargetError;\n        }\n        this.el = document.createElement('div');\n        this.el.className = \"pace pace-active\";\n        document.body.className = document.body.className.replace(/pace-done/g, '');\n        document.body.className += ' pace-running';\n        this.el.innerHTML = '<div class=\"pace-progress\">\\n  <div class=\"pace-progress-inner\"></div>\\n</div>\\n<div class=\"pace-activity\"></div>';\n        if (targetElement.firstChild != null) {\n          targetElement.insertBefore(this.el, targetElement.firstChild);\n        } else {\n          targetElement.appendChild(this.el);\n        }\n      }\n      return this.el;\n    };\n\n    Bar.prototype.finish = function() {\n      var el;\n      el = this.getElement();\n      el.className = el.className.replace('pace-active', '');\n      el.className += ' pace-inactive';\n      document.body.className = document.body.className.replace('pace-running', '');\n      return document.body.className += ' pace-done';\n    };\n\n    Bar.prototype.update = function(prog) {\n      this.progress = prog;\n      return this.render();\n    };\n\n    Bar.prototype.destroy = function() {\n      try {\n        this.getElement().parentNode.removeChild(this.getElement());\n      } catch (_error) {\n        NoTargetError = _error;\n      }\n      return this.el = void 0;\n    };\n\n    Bar.prototype.render = function() {\n      var el, key, progressStr, transform, _j, _len1, _ref2;\n      if (document.querySelector(options.target) == null) {\n        return false;\n      }\n      el = this.getElement();\n      transform = \"translate3d(\" + this.progress + \"%, 0, 0)\";\n      _ref2 = ['webkitTransform', 'msTransform', 'transform'];\n      for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {\n        key = _ref2[_j];\n        el.children[0].style[key] = transform;\n      }\n      if (!this.lastRenderedProgress || this.lastRenderedProgress | 0 !== this.progress | 0) {\n        el.children[0].setAttribute('data-progress-text', \"\" + (this.progress | 0) + \"%\");\n        if (this.progress >= 100) {\n          progressStr = '99';\n        } else {\n          progressStr = this.progress < 10 ? \"0\" : \"\";\n          progressStr += this.progress | 0;\n        }\n        el.children[0].setAttribute('data-progress', \"\" + progressStr);\n      }\n      return this.lastRenderedProgress = this.progress;\n    };\n\n    Bar.prototype.done = function() {\n      return this.progress >= 100;\n    };\n\n    return Bar;\n\n  })();\n\n  Events = (function() {\n    function Events() {\n      this.bindings = {};\n    }\n\n    Events.prototype.trigger = function(name, val) {\n      var binding, _j, _len1, _ref2, _results;\n      if (this.bindings[name] != null) {\n        _ref2 = this.bindings[name];\n        _results = [];\n        for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {\n          binding = _ref2[_j];\n          _results.push(binding.call(this, val));\n        }\n        return _results;\n      }\n    };\n\n    Events.prototype.on = function(name, fn) {\n      var _base;\n      if ((_base = this.bindings)[name] == null) {\n        _base[name] = [];\n      }\n      return this.bindings[name].push(fn);\n    };\n\n    return Events;\n\n  })();\n\n  _XMLHttpRequest = window.XMLHttpRequest;\n\n  _XDomainRequest = window.XDomainRequest;\n\n  _WebSocket = window.WebSocket;\n\n  extendNative = function(to, from) {\n    var e, key, _results;\n    _results = [];\n    for (key in from.prototype) {\n      try {\n        if ((to[key] == null) && typeof from[key] !== 'function') {\n          if (typeof Object.defineProperty === 'function') {\n            _results.push(Object.defineProperty(to, key, {\n              get: function() {\n                return from.prototype[key];\n              },\n              configurable: true,\n              enumerable: true\n            }));\n          } else {\n            _results.push(to[key] = from.prototype[key]);\n          }\n        } else {\n          _results.push(void 0);\n        }\n      } catch (_error) {\n        e = _error;\n      }\n    }\n    return _results;\n  };\n\n  ignoreStack = [];\n\n  Pace.ignore = function() {\n    var args, fn, ret;\n    fn = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n    ignoreStack.unshift('ignore');\n    ret = fn.apply(null, args);\n    ignoreStack.shift();\n    return ret;\n  };\n\n  Pace.track = function() {\n    var args, fn, ret;\n    fn = arguments[0], args = 2 <= arguments.length ? __slice.call(arguments, 1) : [];\n    ignoreStack.unshift('track');\n    ret = fn.apply(null, args);\n    ignoreStack.shift();\n    return ret;\n  };\n\n  shouldTrack = function(method) {\n    var _ref2;\n    if (method == null) {\n      method = 'GET';\n    }\n    if (ignoreStack[0] === 'track') {\n      return 'force';\n    }\n    if (!ignoreStack.length && options.ajax) {\n      if (method === 'socket' && options.ajax.trackWebSockets) {\n        return true;\n      } else if (_ref2 = method.toUpperCase(), __indexOf.call(options.ajax.trackMethods, _ref2) >= 0) {\n        return true;\n      }\n    }\n    return false;\n  };\n\n  RequestIntercept = (function(_super) {\n    __extends(RequestIntercept, _super);\n\n    function RequestIntercept() {\n      var monitorXHR,\n        _this = this;\n      RequestIntercept.__super__.constructor.apply(this, arguments);\n      monitorXHR = function(req) {\n        var _open;\n        _open = req.open;\n        return req.open = function(type, url, async) {\n          if (shouldTrack(type)) {\n            _this.trigger('request', {\n              type: type,\n              url: url,\n              request: req\n            });\n          }\n          return _open.apply(req, arguments);\n        };\n      };\n      window.XMLHttpRequest = function(flags) {\n        var req;\n        req = new _XMLHttpRequest(flags);\n        monitorXHR(req);\n        return req;\n      };\n      try {\n        extendNative(window.XMLHttpRequest, _XMLHttpRequest);\n      } catch (_error) {}\n      if (_XDomainRequest != null) {\n        window.XDomainRequest = function() {\n          var req;\n          req = new _XDomainRequest;\n          monitorXHR(req);\n          return req;\n        };\n        try {\n          extendNative(window.XDomainRequest, _XDomainRequest);\n        } catch (_error) {}\n      }\n      if ((_WebSocket != null) && options.ajax.trackWebSockets) {\n        window.WebSocket = function(url, protocols) {\n          var req;\n          if (protocols != null) {\n            req = new _WebSocket(url, protocols);\n          } else {\n            req = new _WebSocket(url);\n          }\n          if (shouldTrack('socket')) {\n            _this.trigger('request', {\n              type: 'socket',\n              url: url,\n              protocols: protocols,\n              request: req\n            });\n          }\n          return req;\n        };\n        try {\n          extendNative(window.WebSocket, _WebSocket);\n        } catch (_error) {}\n      }\n    }\n\n    return RequestIntercept;\n\n  })(Events);\n\n  _intercept = null;\n\n  getIntercept = function() {\n    if (_intercept == null) {\n      _intercept = new RequestIntercept;\n    }\n    return _intercept;\n  };\n\n  shouldIgnoreURL = function(url) {\n    var pattern, _j, _len1, _ref2;\n    _ref2 = options.ajax.ignoreURLs;\n    for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {\n      pattern = _ref2[_j];\n      if (typeof pattern === 'string') {\n        if (url.indexOf(pattern) !== -1) {\n          return true;\n        }\n      } else {\n        if (pattern.test(url)) {\n          return true;\n        }\n      }\n    }\n    return false;\n  };\n\n  getIntercept().on('request', function(_arg) {\n    var after, args, request, type, url;\n    type = _arg.type, request = _arg.request, url = _arg.url;\n    if (shouldIgnoreURL(url)) {\n      return;\n    }\n    if (!Pace.running && (options.restartOnRequestAfter !== false || shouldTrack(type) === 'force')) {\n      args = arguments;\n      after = options.restartOnRequestAfter || 0;\n      if (typeof after === 'boolean') {\n        after = 0;\n      }\n      return setTimeout(function() {\n        var stillActive, _j, _len1, _ref2, _ref3, _results;\n        if (type === 'socket') {\n          stillActive = request.readyState < 2;\n        } else {\n          stillActive = (0 < (_ref2 = request.readyState) && _ref2 < 4);\n        }\n        if (stillActive) {\n          Pace.restart();\n          _ref3 = Pace.sources;\n          _results = [];\n          for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {\n            source = _ref3[_j];\n            if (source instanceof AjaxMonitor) {\n              source.watch.apply(source, args);\n              break;\n            } else {\n              _results.push(void 0);\n            }\n          }\n          return _results;\n        }\n      }, after);\n    }\n  });\n\n  AjaxMonitor = (function() {\n    function AjaxMonitor() {\n      var _this = this;\n      this.elements = [];\n      getIntercept().on('request', function() {\n        return _this.watch.apply(_this, arguments);\n      });\n    }\n\n    AjaxMonitor.prototype.watch = function(_arg) {\n      var request, tracker, type, url;\n      type = _arg.type, request = _arg.request, url = _arg.url;\n      if (shouldIgnoreURL(url)) {\n        return;\n      }\n      if (type === 'socket') {\n        tracker = new SocketRequestTracker(request);\n      } else {\n        tracker = new XHRRequestTracker(request);\n      }\n      return this.elements.push(tracker);\n    };\n\n    return AjaxMonitor;\n\n  })();\n\n  XHRRequestTracker = (function() {\n    function XHRRequestTracker(request) {\n      var event, size, _j, _len1, _onreadystatechange, _ref2,\n        _this = this;\n      this.progress = 0;\n      if (window.ProgressEvent != null) {\n        size = null;\n        request.addEventListener('progress', function(evt) {\n          if (evt.lengthComputable) {\n            return _this.progress = 100 * evt.loaded / evt.total;\n          } else {\n            return _this.progress = _this.progress + (100 - _this.progress) / 2;\n          }\n        }, false);\n        _ref2 = ['load', 'abort', 'timeout', 'error'];\n        for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {\n          event = _ref2[_j];\n          request.addEventListener(event, function() {\n            return _this.progress = 100;\n          }, false);\n        }\n      } else {\n        _onreadystatechange = request.onreadystatechange;\n        request.onreadystatechange = function() {\n          var _ref3;\n          if ((_ref3 = request.readyState) === 0 || _ref3 === 4) {\n            _this.progress = 100;\n          } else if (request.readyState === 3) {\n            _this.progress = 50;\n          }\n          return typeof _onreadystatechange === \"function\" ? _onreadystatechange.apply(null, arguments) : void 0;\n        };\n      }\n    }\n\n    return XHRRequestTracker;\n\n  })();\n\n  SocketRequestTracker = (function() {\n    function SocketRequestTracker(request) {\n      var event, _j, _len1, _ref2,\n        _this = this;\n      this.progress = 0;\n      _ref2 = ['error', 'open'];\n      for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {\n        event = _ref2[_j];\n        request.addEventListener(event, function() {\n          return _this.progress = 100;\n        }, false);\n      }\n    }\n\n    return SocketRequestTracker;\n\n  })();\n\n  ElementMonitor = (function() {\n    function ElementMonitor(options) {\n      var selector, _j, _len1, _ref2;\n      if (options == null) {\n        options = {};\n      }\n      this.elements = [];\n      if (options.selectors == null) {\n        options.selectors = [];\n      }\n      _ref2 = options.selectors;\n      for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {\n        selector = _ref2[_j];\n        this.elements.push(new ElementTracker(selector));\n      }\n    }\n\n    return ElementMonitor;\n\n  })();\n\n  ElementTracker = (function() {\n    function ElementTracker(selector) {\n      this.selector = selector;\n      this.progress = 0;\n      this.check();\n    }\n\n    ElementTracker.prototype.check = function() {\n      var _this = this;\n      if (document.querySelector(this.selector)) {\n        return this.done();\n      } else {\n        return setTimeout((function() {\n          return _this.check();\n        }), options.elements.checkInterval);\n      }\n    };\n\n    ElementTracker.prototype.done = function() {\n      return this.progress = 100;\n    };\n\n    return ElementTracker;\n\n  })();\n\n  DocumentMonitor = (function() {\n    DocumentMonitor.prototype.states = {\n      loading: 0,\n      interactive: 50,\n      complete: 100\n    };\n\n    function DocumentMonitor() {\n      var _onreadystatechange, _ref2,\n        _this = this;\n      this.progress = (_ref2 = this.states[document.readyState]) != null ? _ref2 : 100;\n      _onreadystatechange = document.onreadystatechange;\n      document.onreadystatechange = function() {\n        if (_this.states[document.readyState] != null) {\n          _this.progress = _this.states[document.readyState];\n        }\n        return typeof _onreadystatechange === \"function\" ? _onreadystatechange.apply(null, arguments) : void 0;\n      };\n    }\n\n    return DocumentMonitor;\n\n  })();\n\n  EventLagMonitor = (function() {\n    function EventLagMonitor() {\n      var avg, interval, last, points, samples,\n        _this = this;\n      this.progress = 0;\n      avg = 0;\n      samples = [];\n      points = 0;\n      last = now();\n      interval = setInterval(function() {\n        var diff;\n        diff = now() - last - 50;\n        last = now();\n        samples.push(diff);\n        if (samples.length > options.eventLag.sampleCount) {\n          samples.shift();\n        }\n        avg = avgAmplitude(samples);\n        if (++points >= options.eventLag.minSamples && avg < options.eventLag.lagThreshold) {\n          _this.progress = 100;\n          return clearInterval(interval);\n        } else {\n          return _this.progress = 100 * (3 / (avg + 3));\n        }\n      }, 50);\n    }\n\n    return EventLagMonitor;\n\n  })();\n\n  Scaler = (function() {\n    function Scaler(source) {\n      this.source = source;\n      this.last = this.sinceLastUpdate = 0;\n      this.rate = options.initialRate;\n      this.catchup = 0;\n      this.progress = this.lastProgress = 0;\n      if (this.source != null) {\n        this.progress = result(this.source, 'progress');\n      }\n    }\n\n    Scaler.prototype.tick = function(frameTime, val) {\n      var scaling;\n      if (val == null) {\n        val = result(this.source, 'progress');\n      }\n      if (val >= 100) {\n        this.done = true;\n      }\n      if (val === this.last) {\n        this.sinceLastUpdate += frameTime;\n      } else {\n        if (this.sinceLastUpdate) {\n          this.rate = (val - this.last) / this.sinceLastUpdate;\n        }\n        this.catchup = (val - this.progress) / options.catchupTime;\n        this.sinceLastUpdate = 0;\n        this.last = val;\n      }\n      if (val > this.progress) {\n        this.progress += this.catchup * frameTime;\n      }\n      scaling = 1 - Math.pow(this.progress / 100, options.easeFactor);\n      this.progress += scaling * this.rate * frameTime;\n      this.progress = Math.min(this.lastProgress + options.maxProgressPerFrame, this.progress);\n      this.progress = Math.max(0, this.progress);\n      this.progress = Math.min(100, this.progress);\n      this.lastProgress = this.progress;\n      return this.progress;\n    };\n\n    return Scaler;\n\n  })();\n\n  sources = null;\n\n  scalers = null;\n\n  bar = null;\n\n  uniScaler = null;\n\n  animation = null;\n\n  cancelAnimation = null;\n\n  Pace.running = false;\n\n  handlePushState = function() {\n    if (options.restartOnPushState) {\n      return Pace.restart();\n    }\n  };\n\n  if (window.history.pushState != null) {\n    _pushState = window.history.pushState;\n    window.history.pushState = function() {\n      handlePushState();\n      return _pushState.apply(window.history, arguments);\n    };\n  }\n\n  if (window.history.replaceState != null) {\n    _replaceState = window.history.replaceState;\n    window.history.replaceState = function() {\n      handlePushState();\n      return _replaceState.apply(window.history, arguments);\n    };\n  }\n\n  SOURCE_KEYS = {\n    ajax: AjaxMonitor,\n    elements: ElementMonitor,\n    document: DocumentMonitor,\n    eventLag: EventLagMonitor\n  };\n\n  (init = function() {\n    var type, _j, _k, _len1, _len2, _ref2, _ref3, _ref4;\n    Pace.sources = sources = [];\n    _ref2 = ['ajax', 'elements', 'document', 'eventLag'];\n    for (_j = 0, _len1 = _ref2.length; _j < _len1; _j++) {\n      type = _ref2[_j];\n      if (options[type] !== false) {\n        sources.push(new SOURCE_KEYS[type](options[type]));\n      }\n    }\n    _ref4 = (_ref3 = options.extraSources) != null ? _ref3 : [];\n    for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {\n      source = _ref4[_k];\n      sources.push(new source(options));\n    }\n    Pace.bar = bar = new Bar;\n    scalers = [];\n    return uniScaler = new Scaler;\n  })();\n\n  Pace.stop = function() {\n    Pace.trigger('stop');\n    Pace.running = false;\n    bar.destroy();\n    cancelAnimation = true;\n    if (animation != null) {\n      if (typeof cancelAnimationFrame === \"function\") {\n        cancelAnimationFrame(animation);\n      }\n      animation = null;\n    }\n    return init();\n  };\n\n  Pace.restart = function() {\n    Pace.trigger('restart');\n    Pace.stop();\n    return Pace.start();\n  };\n\n  Pace.go = function() {\n    var start;\n    Pace.running = true;\n    bar.render();\n    start = now();\n    cancelAnimation = false;\n    return animation = runAnimation(function(frameTime, enqueueNextFrame) {\n      var avg, count, done, element, elements, i, j, remaining, scaler, scalerList, sum, _j, _k, _len1, _len2, _ref2;\n      remaining = 100 - bar.progress;\n      count = sum = 0;\n      done = true;\n      for (i = _j = 0, _len1 = sources.length; _j < _len1; i = ++_j) {\n        source = sources[i];\n        scalerList = scalers[i] != null ? scalers[i] : scalers[i] = [];\n        elements = (_ref2 = source.elements) != null ? _ref2 : [source];\n        for (j = _k = 0, _len2 = elements.length; _k < _len2; j = ++_k) {\n          element = elements[j];\n          scaler = scalerList[j] != null ? scalerList[j] : scalerList[j] = new Scaler(element);\n          done &= scaler.done;\n          if (scaler.done) {\n            continue;\n          }\n          count++;\n          sum += scaler.tick(frameTime);\n        }\n      }\n      avg = sum / count;\n      bar.update(uniScaler.tick(frameTime, avg));\n      if (bar.done() || done || cancelAnimation) {\n        bar.update(100);\n        Pace.trigger('done');\n        return setTimeout(function() {\n          bar.finish();\n          Pace.running = false;\n          return Pace.trigger('hide');\n        }, Math.max(options.ghostTime, Math.max(options.minTime - (now() - start), 0)));\n      } else {\n        return enqueueNextFrame();\n      }\n    });\n  };\n\n  Pace.start = function(_options) {\n    extend(options, _options);\n    Pace.running = true;\n    try {\n      bar.render();\n    } catch (_error) {\n      NoTargetError = _error;\n    }\n    if (!document.querySelector('.pace')) {\n      return setTimeout(Pace.start, 50);\n    } else {\n      Pace.trigger('start');\n      return Pace.go();\n    }\n  };\n\n  if (typeof define === 'function' && define.amd) {\n    define(['pace'], function() {\n      return Pace;\n    });\n  } else if (typeof exports === 'object') {\n    module.exports = Pace;\n  } else {\n    if (options.startOnPageLoad) {\n      Pace.start();\n    }\n  }\n\n}).call(this);\n"
  },
  {
    "path": "public/static/plugins/pjax/jquery.pjax.js",
    "content": "/*!\n * Copyright 2012, Chris Wanstrath\n * Released under the MIT License\n * https://github.com/defunkt/jquery-pjax\n */\n\n(function($){\n\n// When called on a container with a selector, fetches the href with\n// ajax into the container or with the data-pjax attribute on the link\n// itself.\n//\n// Tries to make sure the back button and ctrl+click work the way\n// you'd expect.\n//\n// Exported as $.fn.pjax\n//\n// Accepts a jQuery ajax options object that may include these\n// pjax specific options:\n//\n//\n// container - Where to stick the response body. Usually a String selector.\n//             $(container).html(xhr.responseBody)\n//             (default: current jquery context)\n//      push - Whether to pushState the URL. Defaults to true (of course).\n//   replace - Want to use replaceState instead? That's cool.\n//\n// For convenience the second parameter can be either the container or\n// the options object.\n//\n// Returns the jQuery object\nfunction fnPjax(selector, container, options) {\n  var context = this\n  return this.on('click.pjax', selector, function(event) {\n    var opts = $.extend({}, optionsFor(container, options))\n    if (!opts.container)\n      opts.container = $(this).attr('data-pjax') || context\n    handleClick(event, opts)\n  })\n}\n\n// Public: pjax on click handler\n//\n// Exported as $.pjax.click.\n//\n// event   - \"click\" jQuery.Event\n// options - pjax options\n//\n// Examples\n//\n//   $(document).on('click', 'a', $.pjax.click)\n//   // is the same as\n//   $(document).pjax('a')\n//\n//  $(document).on('click', 'a', function(event) {\n//    var container = $(this).closest('[data-pjax-container]')\n//    $.pjax.click(event, container)\n//  })\n//\n// Returns nothing.\nfunction handleClick(event, container, options) {\n  options = optionsFor(container, options)\n\n  var link = event.currentTarget\n\n  if (link.tagName.toUpperCase() !== 'A')\n    throw \"$.fn.pjax or $.pjax.click requires an anchor element\"\n\n  // Middle click, cmd click, and ctrl click should open\n  // links in a new tab as normal.\n  if ( event.which > 1 || event.metaKey || event.ctrlKey || event.shiftKey || event.altKey )\n    return\n\n  // Ignore cross origin links\n  if ( location.protocol !== link.protocol || location.hostname !== link.hostname )\n    return\n\n  // Ignore case when a hash is being tacked on the current URL\n  if ( link.href.indexOf('#') > -1 && stripHash(link) == stripHash(location) )\n    return\n\n  // Ignore event with default prevented\n  if (event.isDefaultPrevented())\n    return\n\n  var defaults = {\n    url: link.href,\n    container: $(link).attr('data-pjax'),\n    target: link\n  }\n\n  var opts = $.extend({}, defaults, options)\n  var clickEvent = $.Event('pjax:click')\n  $(link).trigger(clickEvent, [opts])\n\n  if (!clickEvent.isDefaultPrevented()) {\n    pjax(opts)\n    event.preventDefault()\n    $(link).trigger('pjax:clicked', [opts])\n  }\n}\n\n// Public: pjax on form submit handler\n//\n// Exported as $.pjax.submit\n//\n// event   - \"click\" jQuery.Event\n// options - pjax options\n//\n// Examples\n//\n//  $(document).on('submit', 'form', function(event) {\n//    var container = $(this).closest('[data-pjax-container]')\n//    $.pjax.submit(event, container)\n//  })\n//\n// Returns nothing.\nfunction handleSubmit(event, container, options) {\n  options = optionsFor(container, options)\n\n  var form = event.currentTarget\n  var $form = $(form)\n\n  if (form.tagName.toUpperCase() !== 'FORM')\n    throw \"$.pjax.submit requires a form element\"\n\n  var defaults = {\n    type: ($form.attr('method') || 'GET').toUpperCase(),\n    url: $form.attr('action'),\n    container: $form.attr('data-pjax'),\n    target: form\n  }\n\n  if (defaults.type !== 'GET' && window.FormData !== undefined) {\n    defaults.data = new FormData(form);\n    defaults.processData = false;\n    defaults.contentType = false;\n  } else {\n    // Can't handle file uploads, exit\n    if ($(form).find(':file').length) {\n      return;\n    }\n\n    // Fallback to manually serializing the fields\n    defaults.data = $(form).serializeArray();\n  }\n\n  pjax($.extend({}, defaults, options))\n\n  event.preventDefault()\n}\n\n// Loads a URL with ajax, puts the response body inside a container,\n// then pushState()'s the loaded URL.\n//\n// Works just like $.ajax in that it accepts a jQuery ajax\n// settings object (with keys like url, type, data, etc).\n//\n// Accepts these extra keys:\n//\n// container - Where to stick the response body.\n//             $(container).html(xhr.responseBody)\n//      push - Whether to pushState the URL. Defaults to true (of course).\n//   replace - Want to use replaceState instead? That's cool.\n//\n// Use it just like $.ajax:\n//\n//   var xhr = $.pjax({ url: this.href, container: '#main' })\n//   console.log( xhr.readyState )\n//\n// Returns whatever $.ajax returns.\nfunction pjax(options) {\n  options = $.extend(true, {}, $.ajaxSettings, pjax.defaults, options)\n\n  if ($.isFunction(options.url)) {\n    options.url = options.url()\n  }\n\n  var target = options.target\n\n  var hash = parseURL(options.url).hash\n\n  var context = options.context = findContainerFor(options.container)\n\n  // We want the browser to maintain two separate internal caches: one\n  // for pjax'd partial page loads and one for normal page loads.\n  // Without adding this secret parameter, some browsers will often\n  // confuse the two.\n  if (!options.data) options.data = {}\n  if ($.isArray(options.data)) {\n    options.data.push({name: '_pjax', value: context.selector})\n  } else {\n    options.data._pjax = context.selector\n  }\n\n  function fire(type, args, props) {\n    if (!props) props = {}\n    props.relatedTarget = target\n    var event = $.Event(type, props)\n    context.trigger(event, args)\n    return !event.isDefaultPrevented()\n  }\n\n  var timeoutTimer\n\n  options.beforeSend = function(xhr, settings) {\n    // No timeout for non-GET requests\n    // Its not safe to request the resource again with a fallback method.\n    if (settings.type !== 'GET') {\n      settings.timeout = 0\n    }\n\n    xhr.setRequestHeader('X-PJAX', 'true')\n    xhr.setRequestHeader('X-PJAX-Container', context.selector)\n\n    if (!fire('pjax:beforeSend', [xhr, settings]))\n      return false\n\n    if (settings.timeout > 0) {\n      timeoutTimer = setTimeout(function() {\n        if (fire('pjax:timeout', [xhr, options]))\n          xhr.abort('timeout')\n      }, settings.timeout)\n\n      // Clear timeout setting so jquerys internal timeout isn't invoked\n      settings.timeout = 0\n    }\n\n    var url = parseURL(settings.url)\n    if (hash) url.hash = hash\n    options.requestUrl = stripInternalParams(url)\n  }\n\n  options.complete = function(xhr, textStatus) {\n    if (timeoutTimer)\n      clearTimeout(timeoutTimer)\n\n    fire('pjax:complete', [xhr, textStatus, options])\n\n    fire('pjax:end', [xhr, options])\n  }\n\n  options.error = function(xhr, textStatus, errorThrown) {\n    var container = extractContainer(\"\", xhr, options)\n\n    var allowed = fire('pjax:error', [xhr, textStatus, errorThrown, options])\n    if (options.type == 'GET' && textStatus !== 'abort' && allowed) {\n      locationReplace(container.url)\n    }\n  }\n\n  options.success = function(data, status, xhr) {\n    var previousState = pjax.state;\n\n    // If $.pjax.defaults.version is a function, invoke it first.\n    // Otherwise it can be a static string.\n    var currentVersion = (typeof $.pjax.defaults.version === 'function') ?\n      $.pjax.defaults.version() :\n      $.pjax.defaults.version\n\n    var latestVersion = xhr.getResponseHeader('X-PJAX-Version')\n\n    var container = extractContainer(data, xhr, options)\n\n    var url = parseURL(container.url)\n    if (hash) {\n      url.hash = hash\n      container.url = url.href\n    }\n\n    // If there is a layout version mismatch, hard load the new url\n    if (currentVersion && latestVersion && currentVersion !== latestVersion) {\n      locationReplace(container.url)\n      return\n    }\n\n    // If the new response is missing a body, hard load the page\n    if (!container.contents) {\n      locationReplace(container.url)\n      return\n    }\n\n    pjax.state = {\n      id: options.id || uniqueId(),\n      url: container.url,\n      title: container.title,\n      container: context.selector,\n      fragment: options.fragment,\n      timeout: options.timeout\n    }\n\n    if (options.push || options.replace) {\n      window.history.replaceState(pjax.state, container.title, container.url)\n    }\n\n    // Only blur the focus if the focused element is within the container.\n    var blurFocus = $.contains(options.container, document.activeElement)\n\n    // Clear out any focused controls before inserting new page contents.\n    if (blurFocus) {\n      try {\n        document.activeElement.blur()\n      } catch (e) { }\n    }\n\n    if (container.title) document.title = container.title\n\n    fire('pjax:beforeReplace', [container.contents, options], {\n      state: pjax.state,\n      previousState: previousState\n    })\n    context.html(container.contents)\n\n    // FF bug: Won't autofocus fields that are inserted via JS.\n    // This behavior is incorrect. So if theres no current focus, autofocus\n    // the last field.\n    //\n    // http://www.w3.org/html/wg/drafts/html/master/forms.html\n    var autofocusEl = context.find('input[autofocus], textarea[autofocus]').last()[0]\n    if (autofocusEl && document.activeElement !== autofocusEl) {\n      autofocusEl.focus();\n    }\n\n    executeScriptTags(container.scripts)\n\n    var scrollTo = options.scrollTo\n\n    // Ensure browser scrolls to the element referenced by the URL anchor\n    if (hash) {\n      var name = decodeURIComponent(hash.slice(1))\n      var target = document.getElementById(name) || document.getElementsByName(name)[0]\n      if (target) scrollTo = $(target).offset().top\n    }\n\n    if (typeof scrollTo == 'number') $(window).scrollTop(scrollTo)\n\n    fire('pjax:success', [data, status, xhr, options])\n  }\n\n\n  // Initialize pjax.state for the initial page load. Assume we're\n  // using the container and options of the link we're loading for the\n  // back button to the initial page. This ensures good back button\n  // behavior.\n  if (!pjax.state) {\n    pjax.state = {\n      id: uniqueId(),\n      url: window.location.href,\n      title: document.title,\n      container: context.selector,\n      fragment: options.fragment,\n      timeout: options.timeout\n    }\n    window.history.replaceState(pjax.state, document.title)\n  }\n\n  // Cancel the current request if we're already pjaxing\n  abortXHR(pjax.xhr)\n\n  pjax.options = options\n  var xhr = pjax.xhr = $.ajax(options)\n\n  if (xhr.readyState > 0) {\n    if (options.push && !options.replace) {\n      // Cache current container element before replacing it\n      cachePush(pjax.state.id, cloneContents(context))\n\n      window.history.pushState(null, \"\", options.requestUrl)\n    }\n\n    fire('pjax:start', [xhr, options])\n    fire('pjax:send', [xhr, options])\n  }\n\n  return pjax.xhr\n}\n\n// Public: Reload current page with pjax.\n//\n// Returns whatever $.pjax returns.\nfunction pjaxReload(container, options) {\n  var defaults = {\n    url: window.location.href,\n    push: false,\n    replace: true,\n    scrollTo: false\n  }\n\n  return pjax($.extend(defaults, optionsFor(container, options)))\n}\n\n// Internal: Hard replace current state with url.\n//\n// Work for around WebKit\n//   https://bugs.webkit.org/show_bug.cgi?id=93506\n//\n// Returns nothing.\nfunction locationReplace(url) {\n  window.history.replaceState(null, \"\", pjax.state.url)\n  window.location.replace(url)\n}\n\n\nvar initialPop = true\nvar initialURL = window.location.href\nvar initialState = window.history.state\n\n// Initialize $.pjax.state if possible\n// Happens when reloading a page and coming forward from a different\n// session history.\nif (initialState && initialState.container) {\n  pjax.state = initialState\n}\n\n// Non-webkit browsers don't fire an initial popstate event\nif ('state' in window.history) {\n  initialPop = false\n}\n\n// popstate handler takes care of the back and forward buttons\n//\n// You probably shouldn't use pjax on pages with other pushState\n// stuff yet.\nfunction onPjaxPopstate(event) {\n\n  // Hitting back or forward should override any pending PJAX request.\n  if (!initialPop) {\n    abortXHR(pjax.xhr)\n  }\n\n  var previousState = pjax.state\n  var state = event.state\n  var direction\n\n  if (state && state.container) {\n    // When coming forward from a separate history session, will get an\n    // initial pop with a state we are already at. Skip reloading the current\n    // page.\n    if (initialPop && initialURL == state.url) return\n\n    if (previousState) {\n      // If popping back to the same state, just skip.\n      // Could be clicking back from hashchange rather than a pushState.\n      if (previousState.id === state.id) return\n\n      // Since state IDs always increase, we can deduce the navigation direction\n      direction = previousState.id < state.id ? 'forward' : 'back'\n    }\n\n    var cache = cacheMapping[state.id] || []\n    var container = $(cache[0] || state.container), contents = cache[1]\n\n    if (container.length) {\n      if (previousState) {\n        // Cache current container before replacement and inform the\n        // cache which direction the history shifted.\n        cachePop(direction, previousState.id, cloneContents(container))\n      }\n\n      var popstateEvent = $.Event('pjax:popstate', {\n        state: state,\n        direction: direction\n      })\n      container.trigger(popstateEvent)\n\n      var options = {\n        id: state.id,\n        url: state.url,\n        container: container,\n        push: false,\n        fragment: state.fragment,\n        timeout: state.timeout,\n        scrollTo: false\n      }\n\n      if (contents) {\n        container.trigger('pjax:start', [null, options])\n\n        pjax.state = state\n        if (state.title) document.title = state.title\n        var beforeReplaceEvent = $.Event('pjax:beforeReplace', {\n          state: state,\n          previousState: previousState\n        })\n        container.trigger(beforeReplaceEvent, [contents, options])\n        container.html(contents)\n\n        container.trigger('pjax:end', [null, options])\n      } else {\n        pjax(options)\n      }\n\n      // Force reflow/relayout before the browser tries to restore the\n      // scroll position.\n      container[0].offsetHeight\n    } else {\n      locationReplace(location.href)\n    }\n  }\n  initialPop = false\n}\n\n// Fallback version of main pjax function for browsers that don't\n// support pushState.\n//\n// Returns nothing since it retriggers a hard form submission.\nfunction fallbackPjax(options) {\n  var url = $.isFunction(options.url) ? options.url() : options.url,\n      method = options.type ? options.type.toUpperCase() : 'GET'\n\n  var form = $('<form>', {\n    method: method === 'GET' ? 'GET' : 'POST',\n    action: url,\n    style: 'display:none'\n  })\n\n  if (method !== 'GET' && method !== 'POST') {\n    form.append($('<input>', {\n      type: 'hidden',\n      name: '_method',\n      value: method.toLowerCase()\n    }))\n  }\n\n  var data = options.data\n  if (typeof data === 'string') {\n    $.each(data.split('&'), function(index, value) {\n      var pair = value.split('=')\n      form.append($('<input>', {type: 'hidden', name: pair[0], value: pair[1]}))\n    })\n  } else if ($.isArray(data)) {\n    $.each(data, function(index, value) {\n      form.append($('<input>', {type: 'hidden', name: value.name, value: value.value}))\n    })\n  } else if (typeof data === 'object') {\n    var key\n    for (key in data)\n      form.append($('<input>', {type: 'hidden', name: key, value: data[key]}))\n  }\n\n  $(document.body).append(form)\n  form.submit()\n}\n\n// Internal: Abort an XmlHttpRequest if it hasn't been completed,\n// also removing its event handlers.\nfunction abortXHR(xhr) {\n  if ( xhr && xhr.readyState < 4) {\n    xhr.onreadystatechange = $.noop\n    xhr.abort()\n  }\n}\n\n// Internal: Generate unique id for state object.\n//\n// Use a timestamp instead of a counter since ids should still be\n// unique across page loads.\n//\n// Returns Number.\nfunction uniqueId() {\n  return (new Date).getTime()\n}\n\nfunction cloneContents(container) {\n  var cloned = container.clone()\n  // Unmark script tags as already being eval'd so they can get executed again\n  // when restored from cache. HAXX: Uses jQuery internal method.\n  cloned.find('script').each(function(){\n    if (!this.src) jQuery._data(this, 'globalEval', false)\n  })\n  return [container.selector, cloned.contents()]\n}\n\n// Internal: Strip internal query params from parsed URL.\n//\n// Returns sanitized url.href String.\nfunction stripInternalParams(url) {\n  url.search = url.search.replace(/([?&])(_pjax|_)=[^&]*/g, '')\n  return url.href.replace(/\\?($|#)/, '$1')\n}\n\n// Internal: Parse URL components and returns a Locationish object.\n//\n// url - String URL\n//\n// Returns HTMLAnchorElement that acts like Location.\nfunction parseURL(url) {\n  var a = document.createElement('a')\n  a.href = url\n  return a\n}\n\n// Internal: Return the `href` component of given URL object with the hash\n// portion removed.\n//\n// location - Location or HTMLAnchorElement\n//\n// Returns String\nfunction stripHash(location) {\n  return location.href.replace(/#.*/, '')\n}\n\n// Internal: Build options Object for arguments.\n//\n// For convenience the first parameter can be either the container or\n// the options object.\n//\n// Examples\n//\n//   optionsFor('#container')\n//   // => {container: '#container'}\n//\n//   optionsFor('#container', {push: true})\n//   // => {container: '#container', push: true}\n//\n//   optionsFor({container: '#container', push: true})\n//   // => {container: '#container', push: true}\n//\n// Returns options Object.\nfunction optionsFor(container, options) {\n  // Both container and options\n  if ( container && options )\n    options.container = container\n\n  // First argument is options Object\n  else if ( $.isPlainObject(container) )\n    options = container\n\n  // Only container\n  else\n    options = {container: container}\n\n  // Find and validate container\n  if (options.container)\n    options.container = findContainerFor(options.container)\n\n  return options\n}\n\n// Internal: Find container element for a variety of inputs.\n//\n// Because we can't persist elements using the history API, we must be\n// able to find a String selector that will consistently find the Element.\n//\n// container - A selector String, jQuery object, or DOM Element.\n//\n// Returns a jQuery object whose context is `document` and has a selector.\nfunction findContainerFor(container) {\n  container = $(container)\n\n  if ( !container.length ) {\n    throw \"no pjax container for \" + container.selector\n  } else if ( container.selector !== '' && container.context === document ) {\n    return container\n  } else if ( container.attr('id') ) {\n    return $('#' + container.attr('id'))\n  } else {\n    throw \"cant get selector for pjax container!\"\n  }\n}\n\n// Internal: Filter and find all elements matching the selector.\n//\n// Where $.fn.find only matches descendants, findAll will test all the\n// top level elements in the jQuery object as well.\n//\n// elems    - jQuery object of Elements\n// selector - String selector to match\n//\n// Returns a jQuery object.\nfunction findAll(elems, selector) {\n  return elems.filter(selector).add(elems.find(selector));\n}\n\nfunction parseHTML(html) {\n  return $.parseHTML(html, document, true)\n}\n\n// Internal: Extracts container and metadata from response.\n//\n// 1. Extracts X-PJAX-URL header if set\n// 2. Extracts inline <title> tags\n// 3. Builds response Element and extracts fragment if set\n//\n// data    - String response data\n// xhr     - XHR response\n// options - pjax options Object\n//\n// Returns an Object with url, title, and contents keys.\nfunction extractContainer(data, xhr, options) {\n  var obj = {}, fullDocument = /<html/i.test(data)\n\n  // Prefer X-PJAX-URL header if it was set, otherwise fallback to\n  // using the original requested url.\n  var serverUrl = xhr.getResponseHeader('X-PJAX-URL')\n  obj.url = serverUrl ? stripInternalParams(parseURL(serverUrl)) : options.requestUrl\n\n  // Attempt to parse response html into elements\n  if (fullDocument) {\n    var $head = $(parseHTML(data.match(/<head[^>]*>([\\s\\S.]*)<\\/head>/i)[0]))\n    var $body = $(parseHTML(data.match(/<body[^>]*>([\\s\\S.]*)<\\/body>/i)[0]))\n  } else {\n    var $head = $body = $(parseHTML(data))\n  }\n\n  // If response data is empty, return fast\n  if ($body.length === 0)\n    return obj\n\n  // If there's a <title> tag in the header, use it as\n  // the page's title.\n  obj.title = findAll($head, 'title').last().text()\n\n  if (options.fragment) {\n    // If they specified a fragment, look for it in the response\n    // and pull it out.\n    if (options.fragment === 'body') {\n      var $fragment = $body\n    } else {\n      var $fragment = findAll($body, options.fragment).first()\n    }\n\n    if ($fragment.length) {\n      obj.contents = options.fragment === 'body' ? $fragment : $fragment.contents()\n\n      // If there's no title, look for data-title and title attributes\n      // on the fragment\n      if (!obj.title)\n        obj.title = $fragment.attr('title') || $fragment.data('title')\n    }\n\n  } else if (!fullDocument) {\n    obj.contents = $body\n  }\n\n  // Clean up any <title> tags\n  if (obj.contents) {\n    // Remove any parent title elements\n    obj.contents = obj.contents.not(function() { return $(this).is('title') })\n\n    // Then scrub any titles from their descendants\n    obj.contents.find('title').remove()\n\n    // Gather all script[src] elements\n    obj.scripts = findAll(obj.contents, 'script[src]').remove()\n    obj.contents = obj.contents.not(obj.scripts)\n  }\n\n  // Trim any whitespace off the title\n  if (obj.title) obj.title = $.trim(obj.title)\n\n  return obj\n}\n\n// Load an execute scripts using standard script request.\n//\n// Avoids jQuery's traditional $.getScript which does a XHR request and\n// globalEval.\n//\n// scripts - jQuery object of script Elements\n//\n// Returns nothing.\nfunction executeScriptTags(scripts) {\n  if (!scripts) return\n\n  var existingScripts = $('script[src]')\n\n  scripts.each(function() {\n    var src = this.src\n    var matchedScripts = existingScripts.filter(function() {\n      return this.src === src\n    })\n    if (matchedScripts.length) return\n\n    var script = document.createElement('script')\n    var type = $(this).attr('type')\n    if (type) script.type = type\n    script.src = $(this).attr('src')\n    document.head.appendChild(script)\n  })\n}\n\n// Internal: History DOM caching class.\nvar cacheMapping      = {}\nvar cacheForwardStack = []\nvar cacheBackStack    = []\n\n// Push previous state id and container contents into the history\n// cache. Should be called in conjunction with `pushState` to save the\n// previous container contents.\n//\n// id    - State ID Number\n// value - DOM Element to cache\n//\n// Returns nothing.\nfunction cachePush(id, value) {\n  cacheMapping[id] = value\n  cacheBackStack.push(id)\n\n  // Remove all entries in forward history stack after pushing a new page.\n  trimCacheStack(cacheForwardStack, 0)\n\n  // Trim back history stack to max cache length.\n  trimCacheStack(cacheBackStack, pjax.defaults.maxCacheLength)\n}\n\n// Shifts cache from directional history cache. Should be\n// called on `popstate` with the previous state id and container\n// contents.\n//\n// direction - \"forward\" or \"back\" String\n// id        - State ID Number\n// value     - DOM Element to cache\n//\n// Returns nothing.\nfunction cachePop(direction, id, value) {\n  var pushStack, popStack\n  cacheMapping[id] = value\n\n  if (direction === 'forward') {\n    pushStack = cacheBackStack\n    popStack  = cacheForwardStack\n  } else {\n    pushStack = cacheForwardStack\n    popStack  = cacheBackStack\n  }\n\n  pushStack.push(id)\n  if (id = popStack.pop())\n    delete cacheMapping[id]\n\n  // Trim whichever stack we just pushed to to max cache length.\n  trimCacheStack(pushStack, pjax.defaults.maxCacheLength)\n}\n\n// Trim a cache stack (either cacheBackStack or cacheForwardStack) to be no\n// longer than the specified length, deleting cached DOM elements as necessary.\n//\n// stack  - Array of state IDs\n// length - Maximum length to trim to\n//\n// Returns nothing.\nfunction trimCacheStack(stack, length) {\n  while (stack.length > length)\n    delete cacheMapping[stack.shift()]\n}\n\n// Public: Find version identifier for the initial page load.\n//\n// Returns String version or undefined.\nfunction findVersion() {\n  return $('meta').filter(function() {\n    var name = $(this).attr('http-equiv')\n    return name && name.toUpperCase() === 'X-PJAX-VERSION'\n  }).attr('content')\n}\n\n// Install pjax functions on $.pjax to enable pushState behavior.\n//\n// Does nothing if already enabled.\n//\n// Examples\n//\n//     $.pjax.enable()\n//\n// Returns nothing.\nfunction enable() {\n  $.fn.pjax = fnPjax\n  $.pjax = pjax\n  $.pjax.enable = $.noop\n  $.pjax.disable = disable\n  $.pjax.click = handleClick\n  $.pjax.submit = handleSubmit\n  $.pjax.reload = pjaxReload\n  $.pjax.defaults = {\n    timeout: 650,\n    push: true,\n    replace: false,\n    type: 'GET',\n    dataType: 'html',\n    scrollTo: 0,\n    maxCacheLength: 20,\n    version: findVersion\n  }\n  $(window).on('popstate.pjax', onPjaxPopstate)\n}\n\n// Disable pushState behavior.\n//\n// This is the case when a browser doesn't support pushState. It is\n// sometimes useful to disable pushState for debugging on a modern\n// browser.\n//\n// Examples\n//\n//     $.pjax.disable()\n//\n// Returns nothing.\nfunction disable() {\n  $.fn.pjax = function() { return this }\n  $.pjax = fallbackPjax\n  $.pjax.enable = enable\n  $.pjax.disable = $.noop\n  $.pjax.click = $.noop\n  $.pjax.submit = $.noop\n  $.pjax.reload = function() { window.location.reload() }\n\n  $(window).off('popstate.pjax', onPjaxPopstate)\n}\n\n\n// Add the state property to jQuery's event object so we can use it in\n// $(window).bind('popstate')\nif ( $.inArray('state', $.event.props) < 0 )\n  $.event.props.push('state')\n\n// Is pjax supported by this browser?\n$.support.pjax =\n  window.history && window.history.pushState && window.history.replaceState &&\n  // pushState isn't reliable on iOS until 5.\n  !navigator.userAgent.match(/((iPod|iPhone|iPad).+\\bOS\\s+[1-4]\\D|WebApps\\/.+CFNetwork)/)\n\n$.support.pjax ? enable() : disable()\n\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/select2/i18n/ar.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ar\",[],function(){return{errorLoading:function(){return\"لا يمكن تحميل النتائج\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"الرجاء حذف \"+t+\" عناصر\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"الرجاء إضافة \"+t+\" عناصر\";return n},loadingMore:function(){return\"جاري تحميل نتائج إضافية...\"},maximumSelected:function(e){var t=\"تستطيع إختيار \"+e.maximum+\" بنود فقط\";return t},noResults:function(){return\"لم يتم العثور على أي نتائج\"},searching:function(){return\"جاري البحث…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/az.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/az\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return t+\" simvol silin\"},inputTooShort:function(e){var t=e.minimum-e.input.length;return t+\" simvol daxil edin\"},loadingMore:function(){return\"Daha çox nəticə yüklənir…\"},maximumSelected:function(e){return\"Sadəcə \"+e.maximum+\" element seçə bilərsiniz\"},noResults:function(){return\"Nəticə tapılmadı\"},searching:function(){return\"Axtarılır…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/bg.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/bg\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Моля въведете с \"+t+\" по-малко символ\";return t>1&&(n+=\"a\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Моля въведете още \"+t+\" символ\";return t>1&&(n+=\"a\"),n},loadingMore:function(){return\"Зареждат се още…\"},maximumSelected:function(e){var t=\"Можете да направите до \"+e.maximum+\" \";return e.maximum>1?t+=\"избора\":t+=\"избор\",t},noResults:function(){return\"Няма намерени съвпадения\"},searching:function(){return\"Търсене…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/ca.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ca\",[],function(){return{errorLoading:function(){return\"La càrrega ha fallat\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Si us plau, elimina \"+t+\" car\";return t==1?n+=\"àcter\":n+=\"àcters\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Si us plau, introdueix \"+t+\" car\";return t==1?n+=\"àcter\":n+=\"àcters\",n},loadingMore:function(){return\"Carregant més resultats…\"},maximumSelected:function(e){var t=\"Només es pot seleccionar \"+e.maximum+\" element\";return e.maximum!=1&&(t+=\"s\"),t},noResults:function(){return\"No s'han trobat resultats\"},searching:function(){return\"Cercant…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/cs.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/cs\",[],function(){function e(e,t){switch(e){case 2:return t?\"dva\":\"dvě\";case 3:return\"tři\";case 4:return\"čtyři\"}return\"\"}return{errorLoading:function(){return\"Výsledky nemohly být načteny.\"},inputTooLong:function(t){var n=t.input.length-t.maximum;return n==1?\"Prosím zadejte o jeden znak méně\":n<=4?\"Prosím zadejte o \"+e(n,!0)+\" znaky méně\":\"Prosím zadejte o \"+n+\" znaků méně\"},inputTooShort:function(t){var n=t.minimum-t.input.length;return n==1?\"Prosím zadejte ještě jeden znak\":n<=4?\"Prosím zadejte ještě další \"+e(n,!0)+\" znaky\":\"Prosím zadejte ještě dalších \"+n+\" znaků\"},loadingMore:function(){return\"Načítají se další výsledky…\"},maximumSelected:function(t){var n=t.maximum;return n==1?\"Můžete zvolit jen jednu položku\":n<=4?\"Můžete zvolit maximálně \"+e(n,!1)+\" položky\":\"Můžete zvolit maximálně \"+n+\" položek\"},noResults:function(){return\"Nenalezeny žádné položky\"},searching:function(){return\"Vyhledávání…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/da.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/da\",[],function(){return{errorLoading:function(){return\"Resultaterne kunne ikke indlæses.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Angiv venligst \"+t+\" tegn mindre\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Angiv venligst \"+t+\" tegn mere\";return n},loadingMore:function(){return\"Indlæser flere resultater…\"},maximumSelected:function(e){var t=\"Du kan kun vælge \"+e.maximum+\" emne\";return e.maximum!=1&&(t+=\"r\"),t},noResults:function(){return\"Ingen resultater fundet\"},searching:function(){return\"Søger…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/de.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/de\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return\"Bitte \"+t+\" Zeichen weniger eingeben\"},inputTooShort:function(e){var t=e.minimum-e.input.length;return\"Bitte \"+t+\" Zeichen mehr eingeben\"},loadingMore:function(){return\"Lade mehr Ergebnisse…\"},maximumSelected:function(e){var t=\"Sie können nur \"+e.maximum+\" Eintr\";return e.maximum===1?t+=\"ag\":t+=\"äge\",t+=\" auswählen\",t},noResults:function(){return\"Keine Übereinstimmungen gefunden\"},searching:function(){return\"Suche…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/en.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/en\",[],function(){return{errorLoading:function(){return\"The results could not be loaded.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Please delete \"+t+\" character\";return t!=1&&(n+=\"s\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Please enter \"+t+\" or more characters\";return n},loadingMore:function(){return\"Loading more results…\"},maximumSelected:function(e){var t=\"You can only select \"+e.maximum+\" item\";return e.maximum!=1&&(t+=\"s\"),t},noResults:function(){return\"No results found\"},searching:function(){return\"Searching…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/es.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/es\",[],function(){return{errorLoading:function(){return\"La carga falló\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Por favor, elimine \"+t+\" car\";return t==1?n+=\"ácter\":n+=\"acteres\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Por favor, introduzca \"+t+\" car\";return t==1?n+=\"ácter\":n+=\"acteres\",n},loadingMore:function(){return\"Cargando más resultados…\"},maximumSelected:function(e){var t=\"Sólo puede seleccionar \"+e.maximum+\" elemento\";return e.maximum!=1&&(t+=\"s\"),t},noResults:function(){return\"No se encontraron resultados\"},searching:function(){return\"Buscando…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/et.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/et\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Sisesta \"+t+\" täht\";return t!=1&&(n+=\"e\"),n+=\" vähem\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Sisesta \"+t+\" täht\";return t!=1&&(n+=\"e\"),n+=\" rohkem\",n},loadingMore:function(){return\"Laen tulemusi…\"},maximumSelected:function(e){var t=\"Saad vaid \"+e.maximum+\" tulemus\";return e.maximum==1?t+=\"e\":t+=\"t\",t+=\" valida\",t},noResults:function(){return\"Tulemused puuduvad\"},searching:function(){return\"Otsin…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/eu.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/eu\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Idatzi \";return t==1?n+=\"karaktere bat\":n+=t+\" karaktere\",n+=\" gutxiago\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Idatzi \";return t==1?n+=\"karaktere bat\":n+=t+\" karaktere\",n+=\" gehiago\",n},loadingMore:function(){return\"Emaitza gehiago kargatzen…\"},maximumSelected:function(e){return e.maximum===1?\"Elementu bakarra hauta dezakezu\":e.maximum+\" elementu hauta ditzakezu soilik\"},noResults:function(){return\"Ez da bat datorrenik aurkitu\"},searching:function(){return\"Bilatzen…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/fa.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/fa\",[],function(){return{errorLoading:function(){return\"امکان بارگذاری نتایج وجود ندارد.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"لطفاً \"+t+\" کاراکتر را حذف نمایید\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"لطفاً تعداد \"+t+\" کاراکتر یا بیشتر وارد نمایید\";return n},loadingMore:function(){return\"در حال بارگذاری نتایج بیشتر...\"},maximumSelected:function(e){var t=\"شما تنها می‌توانید \"+e.maximum+\" آیتم را انتخاب نمایید\";return t},noResults:function(){return\"هیچ نتیجه‌ای یافت نشد\"},searching:function(){return\"در حال جستجو...\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/fi.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/fi\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return\"Ole hyvä ja anna \"+t+\" merkkiä vähemmän\"},inputTooShort:function(e){var t=e.minimum-e.input.length;return\"Ole hyvä ja anna \"+t+\" merkkiä lisää\"},loadingMore:function(){return\"Ladataan lisää tuloksia…\"},maximumSelected:function(e){return\"Voit valita ainoastaan \"+e.maximum+\" kpl\"},noResults:function(){return\"Ei tuloksia\"},searching:function(){}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/fr.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/fr\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Supprimez \"+t+\" caractère\";return t!==1&&(n+=\"s\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Saisissez \"+t+\" caractère\";return t!==1&&(n+=\"s\"),n},loadingMore:function(){return\"Chargement de résultats supplémentaires…\"},maximumSelected:function(e){var t=\"Vous pouvez seulement sélectionner \"+e.maximum+\" élément\";return e.maximum!==1&&(t+=\"s\"),t},noResults:function(){return\"Aucun résultat trouvé\"},searching:function(){return\"Recherche en cours…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/gl.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/gl\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Elimine \";return t===1?n+=\"un carácter\":n+=t+\" caracteres\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Engada \";return t===1?n+=\"un carácter\":n+=t+\" caracteres\",n},loadingMore:function(){return\"Cargando máis resultados…\"},maximumSelected:function(e){var t=\"Só pode \";return e.maximum===1?t+=\"un elemento\":t+=e.maximum+\" elementos\",t},noResults:function(){return\"Non se atoparon resultados\"},searching:function(){return\"Buscando…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/he.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/he\",[],function(){return{errorLoading:function(){return\"שגיאה בטעינת התוצאות\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"נא למחוק \";return t===1?n+=\"תו אחד\":n+=t+\" תווים\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"נא להכניס \";return t===1?n+=\"תו אחד\":n+=t+\" תווים\",n+=\" או יותר\",n},loadingMore:function(){return\"טוען תוצאות נוספות…\"},maximumSelected:function(e){var t=\"באפשרותך לבחור עד \";return e.maximum===1?t+=\"פריט אחד\":t+=e.maximum+\" פריטים\",t},noResults:function(){return\"לא נמצאו תוצאות\"},searching:function(){return\"מחפש…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/hi.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/hi\",[],function(){return{errorLoading:function(){return\"परिणामों को लोड नहीं किया जा सका।\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+\" अक्षर को हटा दें\";return t>1&&(n=t+\" अक्षरों को हटा दें \"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"कृपया \"+t+\" या अधिक अक्षर दर्ज करें\";return n},loadingMore:function(){return\"अधिक परिणाम लोड हो रहे है...\"},maximumSelected:function(e){var t=\"आप केवल \"+e.maximum+\" आइटम का चयन कर सकते हैं\";return t},noResults:function(){return\"कोई परिणाम नहीं मिला\"},searching:function(){return\"खोज रहा है...\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/hr.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/hr\",[],function(){function e(e){var t=\" \"+e+\" znak\";return e%10<5&&e%10>0&&(e%100<5||e%100>19)?e%10>1&&(t+=\"a\"):t+=\"ova\",t}return{errorLoading:function(){return\"Preuzimanje nije uspjelo.\"},inputTooLong:function(t){var n=t.input.length-t.maximum;return\"Unesite \"+e(n)},inputTooShort:function(t){var n=t.minimum-t.input.length;return\"Unesite još \"+e(n)},loadingMore:function(){return\"Učitavanje rezultata…\"},maximumSelected:function(e){return\"Maksimalan broj odabranih stavki je \"+e.maximum},noResults:function(){return\"Nema rezultata\"},searching:function(){return\"Pretraga…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/hu.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/hu\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return\"Túl hosszú. \"+t+\" karakterrel több, mint kellene.\"},inputTooShort:function(e){var t=e.minimum-e.input.length;return\"Túl rövid. Még \"+t+\" karakter hiányzik.\"},loadingMore:function(){return\"Töltés…\"},maximumSelected:function(e){return\"Csak \"+e.maximum+\" elemet lehet kiválasztani.\"},noResults:function(){return\"Nincs találat.\"},searching:function(){return\"Keresés…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/id.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/id\",[],function(){return{errorLoading:function(){return\"Data tidak boleh diambil.\"},inputTooLong:function(e){var t=e.input.length-e.maximum;return\"Hapuskan \"+t+\" huruf\"},inputTooShort:function(e){var t=e.minimum-e.input.length;return\"Masukkan \"+t+\" huruf lagi\"},loadingMore:function(){return\"Mengambil data…\"},maximumSelected:function(e){return\"Anda hanya dapat memilih \"+e.maximum+\" pilihan\"},noResults:function(){return\"Tidak ada data yang sesuai\"},searching:function(){return\"Mencari…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/is.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/is\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Vinsamlegast styttið texta um \"+t+\" staf\";return t<=1?n:n+\"i\"},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Vinsamlegast skrifið \"+t+\" staf\";return t>1&&(n+=\"i\"),n+=\" í viðbót\",n},loadingMore:function(){return\"Sæki fleiri niðurstöður…\"},maximumSelected:function(e){return\"Þú getur aðeins valið \"+e.maximum+\" atriði\"},noResults:function(){return\"Ekkert fannst\"},searching:function(){return\"Leita…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/it.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/it\",[],function(){return{errorLoading:function(){return\"I risultati non possono essere caricati.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Per favore cancella \"+t+\" caratter\";return t!==1?n+=\"i\":n+=\"e\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Per favore inserisci \"+t+\" o più caratteri\";return n},loadingMore:function(){return\"Caricando più risultati…\"},maximumSelected:function(e){var t=\"Puoi selezionare solo \"+e.maximum+\" element\";return e.maximum!==1?t+=\"i\":t+=\"o\",t},noResults:function(){return\"Nessun risultato trovato\"},searching:function(){return\"Sto cercando…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/ja.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ja\",[],function(){return{errorLoading:function(){return\"結果が読み込まれませんでした\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+\" 文字を削除してください\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"少なくとも \"+t+\" 文字を入力してください\";return n},loadingMore:function(){return\"読み込み中…\"},maximumSelected:function(e){var t=e.maximum+\" 件しか選択できません\";return t},noResults:function(){return\"対象が見つかりません\"},searching:function(){return\"検索しています…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/ko.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ko\",[],function(){return{errorLoading:function(){return\"결과를 불러올 수 없습니다.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"너무 깁니다. \"+t+\" 글자 지워주세요.\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"너무 짧습니다. \"+t+\" 글자 더 입력해주세요.\";return n},loadingMore:function(){return\"불러오는 중…\"},maximumSelected:function(e){var t=\"최대 \"+e.maximum+\"개까지만 선택 가능합니다.\";return t},noResults:function(){return\"결과가 없습니다.\"},searching:function(){return\"검색 중…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/lt.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/lt\",[],function(){function e(e,t,n,r){return e%100>9&&e%100<21||e%10===0?e%10>1?n:r:t}return{inputTooLong:function(t){var n=t.input.length-t.maximum,r=\"Pašalinkite \"+n+\" simbol\";return r+=e(n,\"ių\",\"ius\",\"į\"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r=\"Įrašykite dar \"+n+\" simbol\";return r+=e(n,\"ių\",\"ius\",\"į\"),r},loadingMore:function(){return\"Kraunama daugiau rezultatų…\"},maximumSelected:function(t){var n=\"Jūs galite pasirinkti tik \"+t.maximum+\" element\";return n+=e(t.maximum,\"ų\",\"us\",\"ą\"),n},noResults:function(){return\"Atitikmenų nerasta\"},searching:function(){return\"Ieškoma…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/lv.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/lv\",[],function(){function e(e,t,n,r){return e===11?t:e%10===1?n:r}return{inputTooLong:function(t){var n=t.input.length-t.maximum,r=\"Lūdzu ievadiet par  \"+n;return r+=\" simbol\"+e(n,\"iem\",\"u\",\"iem\"),r+\" mazāk\"},inputTooShort:function(t){var n=t.minimum-t.input.length,r=\"Lūdzu ievadiet vēl \"+n;return r+=\" simbol\"+e(n,\"us\",\"u\",\"us\"),r},loadingMore:function(){return\"Datu ielāde…\"},maximumSelected:function(t){var n=\"Jūs varat izvēlēties ne vairāk kā \"+t.maximum;return n+=\" element\"+e(t.maximum,\"us\",\"u\",\"us\"),n},noResults:function(){return\"Sakritību nav\"},searching:function(){return\"Meklēšana…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/mk.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/mk\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Ве молиме внесете \"+e.maximum+\" помалку карактер\";return e.maximum!==1&&(n+=\"и\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Ве молиме внесете уште \"+e.maximum+\" карактер\";return e.maximum!==1&&(n+=\"и\"),n},loadingMore:function(){return\"Вчитување резултати…\"},maximumSelected:function(e){var t=\"Можете да изберете само \"+e.maximum+\" ставк\";return e.maximum===1?t+=\"а\":t+=\"и\",t},noResults:function(){return\"Нема пронајдено совпаѓања\"},searching:function(){return\"Пребарување…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/ms.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ms\",[],function(){return{errorLoading:function(){return\"Keputusan tidak berjaya dimuatkan.\"},inputTooLong:function(e){var t=e.input.length-e.maximum;return\"Sila hapuskan \"+t+\" aksara\"},inputTooShort:function(e){var t=e.minimum-e.input.length;return\"Sila masukkan \"+t+\" atau lebih aksara\"},loadingMore:function(){return\"Sedang memuatkan keputusan…\"},maximumSelected:function(e){return\"Anda hanya boleh memilih \"+e.maximum+\" pilihan\"},noResults:function(){return\"Tiada padanan yang ditemui\"},searching:function(){return\"Mencari…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/nb.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/nb\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum;return\"Vennligst fjern \"+t+\" tegn\"},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Vennligst skriv inn \";return t>1?n+=\" flere tegn\":n+=\" tegn til\",n},loadingMore:function(){return\"Laster flere resultater…\"},maximumSelected:function(e){return\"Du kan velge maks \"+e.maximum+\" elementer\"},noResults:function(){return\"Ingen treff\"},searching:function(){return\"Søker…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/nl.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/nl\",[],function(){return{errorLoading:function(){return\"De resultaten konden niet worden geladen.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Gelieve \"+t+\" karakters te verwijderen\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Gelieve \"+t+\" of meer karakters in te voeren\";return n},loadingMore:function(){return\"Meer resultaten laden…\"},maximumSelected:function(e){var t=e.maximum==1?\"kan\":\"kunnen\",n=\"Er \"+t+\" maar \"+e.maximum+\" item\";return e.maximum!=1&&(n+=\"s\"),n+=\" worden geselecteerd\",n},noResults:function(){return\"Geen resultaten gevonden…\"},searching:function(){return\"Zoeken…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/pl.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/pl\",[],function(){var e=[\"znak\",\"znaki\",\"znaków\"],t=[\"element\",\"elementy\",\"elementów\"],n=function(t,n){if(t===1)return n[0];if(t>1&&t<=4)return n[1];if(t>=5)return n[2]};return{errorLoading:function(){return\"Nie można załadować wyników.\"},inputTooLong:function(t){var r=t.input.length-t.maximum;return\"Usuń \"+r+\" \"+n(r,e)},inputTooShort:function(t){var r=t.minimum-t.input.length;return\"Podaj przynajmniej \"+r+\" \"+n(r,e)},loadingMore:function(){return\"Trwa ładowanie…\"},maximumSelected:function(e){return\"Możesz zaznaczyć tylko \"+e.maximum+\" \"+n(e.maximum,t)},noResults:function(){return\"Brak wyników\"},searching:function(){return\"Trwa wyszukiwanie…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/pt-BR.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/pt-BR\",[],function(){return{errorLoading:function(){return\"Os resultados não puderam ser carregados.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Apague \"+t+\" caracter\";return t!=1&&(n+=\"es\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Digite \"+t+\" ou mais caracteres\";return n},loadingMore:function(){return\"Carregando mais resultados…\"},maximumSelected:function(e){var t=\"Você só pode selecionar \"+e.maximum+\" ite\";return e.maximum==1?t+=\"m\":t+=\"ns\",t},noResults:function(){return\"Nenhum resultado encontrado\"},searching:function(){return\"Buscando…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/pt.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/pt\",[],function(){return{errorLoading:function(){return\"Os resultados não puderam ser carregados.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Por favor apague \"+t+\" \";return n+=t!=1?\"caracteres\":\"carácter\",n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Introduza \"+t+\" ou mais caracteres\";return n},loadingMore:function(){return\"A carregar mais resultados…\"},maximumSelected:function(e){var t=\"Apenas pode seleccionar \"+e.maximum+\" \";return t+=e.maximum!=1?\"itens\":\"item\",t},noResults:function(){return\"Sem resultados\"},searching:function(){return\"A procurar…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/ro.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ro\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Vă rugăm să introduceți mai puțin de \"+t;return n+=\" caracter\",n!==1&&(n+=\"e\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Vă rugăm să introduceți incă \"+t;return n+=\" caracter\",n!==1&&(n+=\"e\"),n},loadingMore:function(){return\"Se încarcă…\"},maximumSelected:function(e){var t=\"Aveți voie să selectați cel mult \"+e.maximum;return t+=\" element\",t!==1&&(t+=\"e\"),t},noResults:function(){return\"Nu a fost găsit nimic\"},searching:function(){return\"Căutare…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/ru.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/ru\",[],function(){function e(e,t,n,r){return e%10<5&&e%10>0&&e%100<5||e%100>20?e%10>1?n:t:r}return{errorLoading:function(){return\"Невозможно загрузить результаты\"},inputTooLong:function(t){var n=t.input.length-t.maximum,r=\"Пожалуйста, введите на \"+n+\" символ\";return r+=e(n,\"\",\"a\",\"ов\"),r+=\" меньше\",r},inputTooShort:function(t){var n=t.minimum-t.input.length,r=\"Пожалуйста, введите еще хотя бы \"+n+\" символ\";return r+=e(n,\"\",\"a\",\"ов\"),r},loadingMore:function(){return\"Загрузка данных…\"},maximumSelected:function(t){var n=\"Вы можете выбрать не более \"+t.maximum+\" элемент\";return n+=e(t.maximum,\"\",\"a\",\"ов\"),n},noResults:function(){return\"Совпадений не найдено\"},searching:function(){return\"Поиск…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/sk.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/sk\",[],function(){var e={2:function(e){return e?\"dva\":\"dve\"},3:function(){return\"tri\"},4:function(){return\"štyri\"}};return{inputTooLong:function(t){var n=t.input.length-t.maximum;return n==1?\"Prosím, zadajte o jeden znak menej\":n>=2&&n<=4?\"Prosím, zadajte o \"+e[n](!0)+\" znaky menej\":\"Prosím, zadajte o \"+n+\" znakov menej\"},inputTooShort:function(t){var n=t.minimum-t.input.length;return n==1?\"Prosím, zadajte ešte jeden znak\":n<=4?\"Prosím, zadajte ešte ďalšie \"+e[n](!0)+\" znaky\":\"Prosím, zadajte ešte ďalších \"+n+\" znakov\"},loadingMore:function(){return\"Loading more results…\"},maximumSelected:function(t){return t.maximum==1?\"Môžete zvoliť len jednu položku\":t.maximum>=2&&t.maximum<=4?\"Môžete zvoliť najviac \"+e[t.maximum](!1)+\" položky\":\"Môžete zvoliť najviac \"+t.maximum+\" položiek\"},noResults:function(){return\"Nenašli sa žiadne položky\"},searching:function(){return\"Vyhľadávanie…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/sr-Cyrl.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/sr-Cyrl\",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return\"Преузимање није успело.\"},inputTooLong:function(t){var n=t.input.length-t.maximum,r=\"Обришите \"+n+\" симбол\";return r+=e(n,\"\",\"а\",\"а\"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r=\"Укуцајте бар још \"+n+\" симбол\";return r+=e(n,\"\",\"а\",\"а\"),r},loadingMore:function(){return\"Преузимање још резултата…\"},maximumSelected:function(t){var n=\"Можете изабрати само \"+t.maximum+\" ставк\";return n+=e(t.maximum,\"у\",\"е\",\"и\"),n},noResults:function(){return\"Ништа није пронађено\"},searching:function(){return\"Претрага…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/sr.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/sr\",[],function(){function e(e,t,n,r){return e%10==1&&e%100!=11?t:e%10>=2&&e%10<=4&&(e%100<12||e%100>14)?n:r}return{errorLoading:function(){return\"Preuzimanje nije uspelo.\"},inputTooLong:function(t){var n=t.input.length-t.maximum,r=\"Obrišite \"+n+\" simbol\";return r+=e(n,\"\",\"a\",\"a\"),r},inputTooShort:function(t){var n=t.minimum-t.input.length,r=\"Ukucajte bar još \"+n+\" simbol\";return r+=e(n,\"\",\"a\",\"a\"),r},loadingMore:function(){return\"Preuzimanje još rezultata…\"},maximumSelected:function(t){var n=\"Možete izabrati samo \"+t.maximum+\" stavk\";return n+=e(t.maximum,\"u\",\"e\",\"i\"),n},noResults:function(){return\"Ništa nije pronađeno\"},searching:function(){return\"Pretraga…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/sv.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/sv\",[],function(){return{errorLoading:function(){return\"Resultat kunde inte laddas.\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Vänligen sudda ut \"+t+\" tecken\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Vänligen skriv in \"+t+\" eller fler tecken\";return n},loadingMore:function(){return\"Laddar fler resultat…\"},maximumSelected:function(e){var t=\"Du kan max välja \"+e.maximum+\" element\";return t},noResults:function(){return\"Inga träffar\"},searching:function(){return\"Söker…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/th.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/th\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"โปรดลบออก \"+t+\" ตัวอักษร\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"โปรดพิมพ์เพิ่มอีก \"+t+\" ตัวอักษร\";return n},loadingMore:function(){return\"กำลังค้นข้อมูลเพิ่ม…\"},maximumSelected:function(e){var t=\"คุณสามารถเลือกได้ไม่เกิน \"+e.maximum+\" รายการ\";return t},noResults:function(){return\"ไม่พบข้อมูล\"},searching:function(){return\"กำลังค้นข้อมูล…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/tr.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/tr\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=t+\" karakter daha girmelisiniz\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"En az \"+t+\" karakter daha girmelisiniz\";return n},loadingMore:function(){return\"Daha fazla…\"},maximumSelected:function(e){var t=\"Sadece \"+e.maximum+\" seçim yapabilirsiniz\";return t},noResults:function(){return\"Sonuç bulunamadı\"},searching:function(){return\"Aranıyor…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/uk.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/uk\",[],function(){function e(e,t,n,r){return e%100>10&&e%100<15?r:e%10===1?t:e%10>1&&e%10<5?n:r}return{errorLoading:function(){return\"Неможливо завантажити результати\"},inputTooLong:function(t){var n=t.input.length-t.maximum;return\"Будь ласка, видаліть \"+n+\" \"+e(t.maximum,\"літеру\",\"літери\",\"літер\")},inputTooShort:function(e){var t=e.minimum-e.input.length;return\"Будь ласка, введіть \"+t+\" або більше літер\"},loadingMore:function(){return\"Завантаження інших результатів…\"},maximumSelected:function(t){return\"Ви можете вибрати лише \"+t.maximum+\" \"+e(t.maximum,\"пункт\",\"пункти\",\"пунктів\")},noResults:function(){return\"Нічого не знайдено\"},searching:function(){return\"Пошук…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/vi.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/vi\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"Vui lòng nhập ít hơn \"+t+\" ký tự\";return t!=1&&(n+=\"s\"),n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"Vui lòng nhập nhiều hơn \"+t+' ký tự\"';return n},loadingMore:function(){return\"Đang lấy thêm kết quả…\"},maximumSelected:function(e){var t=\"Chỉ có thể chọn được \"+e.maximum+\" lựa chọn\";return t},noResults:function(){return\"Không tìm thấy kết quả\"},searching:function(){return\"Đang tìm…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/zh-CN.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/zh-CN\",[],function(){return{errorLoading:function(){return\"无法载入结果。\"},inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"请删除\"+t+\"个字符\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"请再输入至少\"+t+\"个字符\";return n},loadingMore:function(){return\"载入更多结果…\"},maximumSelected:function(e){var t=\"最多只能选择\"+e.maximum+\"个项目\";return t},noResults:function(){return\"未找到结果\"},searching:function(){return\"搜索中…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/i18n/zh-TW.js",
    "content": "/*! Select2 4.0.1 | https://github.com/select2/select2/blob/master/LICENSE.md */\n\n(function(){if(jQuery&&jQuery.fn&&jQuery.fn.select2&&jQuery.fn.select2.amd)var e=jQuery.fn.select2.amd;return e.define(\"select2/i18n/zh-TW\",[],function(){return{inputTooLong:function(e){var t=e.input.length-e.maximum,n=\"請刪掉\"+t+\"個字元\";return n},inputTooShort:function(e){var t=e.minimum-e.input.length,n=\"請再輸入\"+t+\"個字元\";return n},loadingMore:function(){return\"載入中…\"},maximumSelected:function(e){var t=\"你只能選擇最多\"+e.maximum+\"項\";return t},noResults:function(){return\"沒有找到相符的項目\"},searching:function(){return\"搜尋中…\"}}}),{define:e.define,require:e.require}})();"
  },
  {
    "path": "public/static/plugins/select2/select2.css",
    "content": ".select2-container {\n  box-sizing: border-box;\n  display: inline-block;\n  margin: 0;\n  position: relative;\n  vertical-align: middle; }\n  .select2-container .select2-selection--single {\n    box-sizing: border-box;\n    cursor: pointer;\n    display: block;\n    height: 28px;\n    user-select: none;\n    -webkit-user-select: none; }\n    .select2-container .select2-selection--single .select2-selection__rendered {\n      display: block;\n      padding-left: 8px;\n      padding-right: 20px;\n      overflow: hidden;\n      text-overflow: ellipsis;\n      white-space: nowrap; }\n    .select2-container .select2-selection--single .select2-selection__clear {\n      position: relative; }\n  .select2-container[dir=\"rtl\"] .select2-selection--single .select2-selection__rendered {\n    padding-right: 8px;\n    padding-left: 20px; }\n  .select2-container .select2-selection--multiple {\n    box-sizing: border-box;\n    cursor: pointer;\n    display: block;\n    min-height: 32px;\n    user-select: none;\n    -webkit-user-select: none; }\n    .select2-container .select2-selection--multiple .select2-selection__rendered {\n      display: inline-block;\n      overflow: hidden;\n      padding-left: 8px;\n      text-overflow: ellipsis;\n      white-space: nowrap; }\n  .select2-container .select2-search--inline {\n    float: left; }\n    .select2-container .select2-search--inline .select2-search__field {\n      box-sizing: border-box;\n      border: none;\n      font-size: 100%;\n      margin-top: 5px;\n      padding: 0; }\n      .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button {\n        -webkit-appearance: none; }\n\n.select2-dropdown {\n  background-color: white;\n  border: 1px solid #aaa;\n  border-radius: 4px;\n  box-sizing: border-box;\n  display: block;\n  position: absolute;\n  left: -100000px;\n  width: 100%;\n  z-index: 1051; }\n\n.select2-results {\n  display: block; }\n\n.select2-results__options {\n  list-style: none;\n  margin: 0;\n  padding: 0; }\n\n.select2-results__option {\n  padding: 6px;\n  user-select: none;\n  -webkit-user-select: none; }\n  .select2-results__option[aria-selected] {\n    cursor: pointer; }\n\n.select2-container--open .select2-dropdown {\n  left: 0; }\n\n.select2-container--open .select2-dropdown--above {\n  border-bottom: none;\n  border-bottom-left-radius: 0;\n  border-bottom-right-radius: 0; }\n\n.select2-container--open .select2-dropdown--below {\n  border-top: none;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0; }\n\n.select2-search--dropdown {\n  display: block;\n  padding: 4px; }\n  .select2-search--dropdown .select2-search__field {\n    padding: 4px;\n    width: 100%;\n    box-sizing: border-box; }\n    .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button {\n      -webkit-appearance: none; }\n  .select2-search--dropdown.select2-search--hide {\n    display: none; }\n\n.select2-close-mask {\n  border: 0;\n  margin: 0;\n  padding: 0;\n  display: block;\n  position: fixed;\n  left: 0;\n  top: 0;\n  min-height: 100%;\n  min-width: 100%;\n  height: auto;\n  width: auto;\n  opacity: 0;\n  z-index: 99;\n  background-color: #fff;\n  filter: alpha(opacity=0); }\n\n.select2-hidden-accessible {\n  border: 0 !important;\n  clip: rect(0 0 0 0) !important;\n  height: 1px !important;\n  margin: -1px !important;\n  overflow: hidden !important;\n  padding: 0 !important;\n  position: absolute !important;\n  width: 1px !important; }\n\n.select2-container--default .select2-selection--single {\n  background-color: #fff;\n  border: 1px solid #aaa;\n  border-radius: 4px; }\n  .select2-container--default .select2-selection--single .select2-selection__rendered {\n    color: #444;\n    line-height: 28px; }\n  .select2-container--default .select2-selection--single .select2-selection__clear {\n    cursor: pointer;\n    float: right;\n    font-weight: bold; }\n  .select2-container--default .select2-selection--single .select2-selection__placeholder {\n    color: #999; }\n  .select2-container--default .select2-selection--single .select2-selection__arrow {\n    height: 26px;\n    position: absolute;\n    top: 1px;\n    right: 1px;\n    width: 20px; }\n    .select2-container--default .select2-selection--single .select2-selection__arrow b {\n      border-color: #888 transparent transparent transparent;\n      border-style: solid;\n      border-width: 5px 4px 0 4px;\n      height: 0;\n      left: 50%;\n      margin-left: -4px;\n      margin-top: -2px;\n      position: absolute;\n      top: 50%;\n      width: 0; }\n\n.select2-container--default[dir=\"rtl\"] .select2-selection--single .select2-selection__clear {\n  float: left; }\n\n.select2-container--default[dir=\"rtl\"] .select2-selection--single .select2-selection__arrow {\n  left: 1px;\n  right: auto; }\n\n.select2-container--default.select2-container--disabled .select2-selection--single {\n  background-color: #eee;\n  cursor: default; }\n  .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear {\n    display: none; }\n\n.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b {\n  border-color: transparent transparent #888 transparent;\n  border-width: 0 4px 5px 4px; }\n\n.select2-container--default .select2-selection--multiple {\n  background-color: white;\n  border: 1px solid #aaa;\n  border-radius: 4px;\n  cursor: text; }\n  .select2-container--default .select2-selection--multiple .select2-selection__rendered {\n    box-sizing: border-box;\n    list-style: none;\n    margin: 0;\n    padding: 0 5px;\n    width: 100%; }\n  .select2-container--default .select2-selection--multiple .select2-selection__placeholder {\n    color: #999;\n    margin-top: 5px;\n    float: left; }\n  .select2-container--default .select2-selection--multiple .select2-selection__clear {\n    cursor: pointer;\n    float: right;\n    font-weight: bold;\n    margin-top: 5px;\n    margin-right: 10px; }\n  .select2-container--default .select2-selection--multiple .select2-selection__choice {\n    background-color: #e4e4e4;\n    border: 1px solid #aaa;\n    border-radius: 4px;\n    cursor: default;\n    float: left;\n    margin-right: 5px;\n    margin-top: 5px;\n    padding: 0 5px; }\n  .select2-container--default .select2-selection--multiple .select2-selection__choice__remove {\n    color: #999;\n    cursor: pointer;\n    display: inline-block;\n    font-weight: bold;\n    margin-right: 2px; }\n    .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover {\n      color: #333; }\n\n.select2-container--default[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir=\"rtl\"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir=\"rtl\"] .select2-selection--multiple .select2-search--inline {\n  float: right; }\n\n.select2-container--default[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice {\n  margin-left: 5px;\n  margin-right: auto; }\n\n.select2-container--default[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice__remove {\n  margin-left: 2px;\n  margin-right: auto; }\n\n.select2-container--default.select2-container--focus .select2-selection--multiple {\n  border: solid black 1px;\n  outline: 0; }\n\n.select2-container--default.select2-container--disabled .select2-selection--multiple {\n  background-color: #eee;\n  cursor: default; }\n\n.select2-container--default.select2-container--disabled .select2-selection__choice__remove {\n  display: none; }\n\n.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple {\n  border-top-left-radius: 0;\n  border-top-right-radius: 0; }\n\n.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple {\n  border-bottom-left-radius: 0;\n  border-bottom-right-radius: 0; }\n\n.select2-container--default .select2-search--dropdown .select2-search__field {\n  border: 1px solid #aaa; }\n\n.select2-container--default .select2-search--inline .select2-search__field {\n  background: transparent;\n  border: none;\n  outline: 0;\n  box-shadow: none;\n  -webkit-appearance: textfield; }\n\n.select2-container--default .select2-results > .select2-results__options {\n  max-height: 200px;\n  overflow-y: auto; }\n\n.select2-container--default .select2-results__option[role=group] {\n  padding: 0; }\n\n.select2-container--default .select2-results__option[aria-disabled=true] {\n  color: #999; }\n\n.select2-container--default .select2-results__option[aria-selected=true] {\n  background-color: #ddd; }\n\n.select2-container--default .select2-results__option .select2-results__option {\n  padding-left: 1em; }\n  .select2-container--default .select2-results__option .select2-results__option .select2-results__group {\n    padding-left: 0; }\n  .select2-container--default .select2-results__option .select2-results__option .select2-results__option {\n    margin-left: -1em;\n    padding-left: 2em; }\n    .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option {\n      margin-left: -2em;\n      padding-left: 3em; }\n      .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {\n        margin-left: -3em;\n        padding-left: 4em; }\n        .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {\n          margin-left: -4em;\n          padding-left: 5em; }\n          .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option {\n            margin-left: -5em;\n            padding-left: 6em; }\n\n.select2-container--default .select2-results__option--highlighted[aria-selected] {\n  background-color: #5897fb;\n  color: white; }\n\n.select2-container--default .select2-results__group {\n  cursor: default;\n  display: block;\n  padding: 6px; }\n\n.select2-container--classic .select2-selection--single {\n  background-color: #f7f7f7;\n  border: 1px solid #aaa;\n  border-radius: 4px;\n  outline: 0;\n  background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%);\n  background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%);\n  background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }\n  .select2-container--classic .select2-selection--single:focus {\n    border: 1px solid #5897fb; }\n  .select2-container--classic .select2-selection--single .select2-selection__rendered {\n    color: #444;\n    line-height: 28px; }\n  .select2-container--classic .select2-selection--single .select2-selection__clear {\n    cursor: pointer;\n    float: right;\n    font-weight: bold;\n    margin-right: 10px; }\n  .select2-container--classic .select2-selection--single .select2-selection__placeholder {\n    color: #999; }\n  .select2-container--classic .select2-selection--single .select2-selection__arrow {\n    background-color: #ddd;\n    border: none;\n    border-left: 1px solid #aaa;\n    border-top-right-radius: 4px;\n    border-bottom-right-radius: 4px;\n    height: 26px;\n    position: absolute;\n    top: 1px;\n    right: 1px;\n    width: 20px;\n    background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%);\n    background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%);\n    background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%);\n    background-repeat: repeat-x;\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); }\n    .select2-container--classic .select2-selection--single .select2-selection__arrow b {\n      border-color: #888 transparent transparent transparent;\n      border-style: solid;\n      border-width: 5px 4px 0 4px;\n      height: 0;\n      left: 50%;\n      margin-left: -4px;\n      margin-top: -2px;\n      position: absolute;\n      top: 50%;\n      width: 0; }\n\n.select2-container--classic[dir=\"rtl\"] .select2-selection--single .select2-selection__clear {\n  float: left; }\n\n.select2-container--classic[dir=\"rtl\"] .select2-selection--single .select2-selection__arrow {\n  border: none;\n  border-right: 1px solid #aaa;\n  border-radius: 0;\n  border-top-left-radius: 4px;\n  border-bottom-left-radius: 4px;\n  left: 1px;\n  right: auto; }\n\n.select2-container--classic.select2-container--open .select2-selection--single {\n  border: 1px solid #5897fb; }\n  .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow {\n    background: transparent;\n    border: none; }\n    .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b {\n      border-color: transparent transparent #888 transparent;\n      border-width: 0 4px 5px 4px; }\n\n.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single {\n  border-top: none;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0;\n  background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%);\n  background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%);\n  background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); }\n\n.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single {\n  border-bottom: none;\n  border-bottom-left-radius: 0;\n  border-bottom-right-radius: 0;\n  background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%);\n  background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%);\n  background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%);\n  background-repeat: repeat-x;\n  filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); }\n\n.select2-container--classic .select2-selection--multiple {\n  background-color: white;\n  border: 1px solid #aaa;\n  border-radius: 4px;\n  cursor: text;\n  outline: 0; }\n  .select2-container--classic .select2-selection--multiple:focus {\n    border: 1px solid #5897fb; }\n  .select2-container--classic .select2-selection--multiple .select2-selection__rendered {\n    list-style: none;\n    margin: 0;\n    padding: 0 5px; }\n  .select2-container--classic .select2-selection--multiple .select2-selection__clear {\n    display: none; }\n  .select2-container--classic .select2-selection--multiple .select2-selection__choice {\n    background-color: #e4e4e4;\n    border: 1px solid #aaa;\n    border-radius: 4px;\n    cursor: default;\n    float: left;\n    margin-right: 5px;\n    margin-top: 5px;\n    padding: 0 5px; }\n  .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove {\n    color: #888;\n    cursor: pointer;\n    display: inline-block;\n    font-weight: bold;\n    margin-right: 2px; }\n    .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover {\n      color: #555; }\n\n.select2-container--classic[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice {\n  float: right; }\n\n.select2-container--classic[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice {\n  margin-left: 5px;\n  margin-right: auto; }\n\n.select2-container--classic[dir=\"rtl\"] .select2-selection--multiple .select2-selection__choice__remove {\n  margin-left: 2px;\n  margin-right: auto; }\n\n.select2-container--classic.select2-container--open .select2-selection--multiple {\n  border: 1px solid #5897fb; }\n\n.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple {\n  border-top: none;\n  border-top-left-radius: 0;\n  border-top-right-radius: 0; }\n\n.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple {\n  border-bottom: none;\n  border-bottom-left-radius: 0;\n  border-bottom-right-radius: 0; }\n\n.select2-container--classic .select2-search--dropdown .select2-search__field {\n  border: 1px solid #aaa;\n  outline: 0; }\n\n.select2-container--classic .select2-search--inline .select2-search__field {\n  outline: 0;\n  box-shadow: none; }\n\n.select2-container--classic .select2-dropdown {\n  background-color: white;\n  border: 1px solid transparent; }\n\n.select2-container--classic .select2-dropdown--above {\n  border-bottom: none; }\n\n.select2-container--classic .select2-dropdown--below {\n  border-top: none; }\n\n.select2-container--classic .select2-results > .select2-results__options {\n  max-height: 200px;\n  overflow-y: auto; }\n\n.select2-container--classic .select2-results__option[role=group] {\n  padding: 0; }\n\n.select2-container--classic .select2-results__option[aria-disabled=true] {\n  color: grey; }\n\n.select2-container--classic .select2-results__option--highlighted[aria-selected] {\n  background-color: #3875d7;\n  color: white; }\n\n.select2-container--classic .select2-results__group {\n  cursor: default;\n  display: block;\n  padding: 6px; }\n\n.select2-container--classic.select2-container--open .select2-dropdown {\n  border-color: #5897fb; }\n"
  },
  {
    "path": "public/static/plugins/select2/select2.full.js",
    "content": "/*!\n * Select2 4.0.1\n * https://select2.github.io\n *\n * Released under the MIT license\n * https://github.com/select2/select2/blob/master/LICENSE.md\n */\n(function(factory) {\n    if (typeof define === 'function' && define.amd) {\n        // AMD. Register as an anonymous module.\n        define(['jquery'], factory);\n    } else if (typeof exports === 'object') {\n        // Node/CommonJS\n        factory(require('jquery'));\n    } else {\n        // Browser globals\n        factory(jQuery);\n    }\n}(function(jQuery) {\n    // This is needed so we can catch the AMD loader configuration and use it\n    // The inner file should be wrapped (by `banner.start.js`) in a function that\n    // returns the AMD loader references.\n    var S2 =\n        (function() {\n            // Restore the Select2 AMD loader so it can be used\n            // Needed mostly in the language files, where the loader is not inserted\n            if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {\n                var S2 = jQuery.fn.select2.amd;\n            }\n            var S2;\n            (function() {\n                if (!S2 || !S2.requirejs) {\n                    if (!S2) { S2 = {}; } else { require = S2; }\n                    /**\n                     * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.\n                     * Available via the MIT or new BSD license.\n                     * see: http://github.com/jrburke/almond for details\n                     */\n                    //Going sloppy to avoid 'use strict' string cost, but strict practices should\n                    //be followed.\n                    /*jslint sloppy: true */\n                    /*global setTimeout: false */\n\n                    var requirejs, require, define;\n                    (function(undef) {\n                        var main, req, makeMap, handlers,\n                            defined = {},\n                            waiting = {},\n                            config = {},\n                            defining = {},\n                            hasOwn = Object.prototype.hasOwnProperty,\n                            aps = [].slice,\n                            jsSuffixRegExp = /\\.js$/;\n\n                        function hasProp(obj, prop) {\n                            return hasOwn.call(obj, prop);\n                        }\n\n                        /**\n                         * Given a relative module name, like ./something, normalize it to\n                         * a real name that can be mapped to a path.\n                         * @param {String} name the relative name\n                         * @param {String} baseName a real name that the name arg is relative\n                         * to.\n                         * @returns {String} normalized name\n                         */\n                        function normalize(name, baseName) {\n                            var nameParts, nameSegment, mapValue, foundMap, lastIndex,\n                                foundI, foundStarMap, starI, i, j, part,\n                                baseParts = baseName && baseName.split(\"/\"),\n                                map = config.map,\n                                starMap = (map && map['*']) || {};\n\n                            //Adjust any relative paths.\n                            if (name && name.charAt(0) === \".\") {\n                                //If have a base name, try to normalize against it,\n                                //otherwise, assume it is a top-level require that will\n                                //be relative to baseUrl in the end.\n                                if (baseName) {\n                                    name = name.split('/');\n                                    lastIndex = name.length - 1;\n\n                                    // Node .js allowance:\n                                    if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {\n                                        name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');\n                                    }\n\n                                    //Lop off the last part of baseParts, so that . matches the\n                                    //\"directory\" and not name of the baseName's module. For instance,\n                                    //baseName of \"one/two/three\", maps to \"one/two/three.js\", but we\n                                    //want the directory, \"one/two\" for this normalization.\n                                    name = baseParts.slice(0, baseParts.length - 1).concat(name);\n\n                                    //start trimDots\n                                    for (i = 0; i < name.length; i += 1) {\n                                        part = name[i];\n                                        if (part === \".\") {\n                                            name.splice(i, 1);\n                                            i -= 1;\n                                        } else if (part === \"..\") {\n                                            if (i === 1 && (name[2] === '..' || name[0] === '..')) {\n                                                //End of the line. Keep at least one non-dot\n                                                //path segment at the front so it can be mapped\n                                                //correctly to disk. Otherwise, there is likely\n                                                //no path mapping for a path starting with '..'.\n                                                //This can still fail, but catches the most reasonable\n                                                //uses of ..\n                                                break;\n                                            } else if (i > 0) {\n                                                name.splice(i - 1, 2);\n                                                i -= 2;\n                                            }\n                                        }\n                                    }\n                                    //end trimDots\n\n                                    name = name.join(\"/\");\n                                } else if (name.indexOf('./') === 0) {\n                                    // No baseName, so this is ID is resolved relative\n                                    // to baseUrl, pull off the leading dot.\n                                    name = name.substring(2);\n                                }\n                            }\n\n                            //Apply map config if available.\n                            if ((baseParts || starMap) && map) {\n                                nameParts = name.split('/');\n\n                                for (i = nameParts.length; i > 0; i -= 1) {\n                                    nameSegment = nameParts.slice(0, i).join(\"/\");\n\n                                    if (baseParts) {\n                                        //Find the longest baseName segment match in the config.\n                                        //So, do joins on the biggest to smallest lengths of baseParts.\n                                        for (j = baseParts.length; j > 0; j -= 1) {\n                                            mapValue = map[baseParts.slice(0, j).join('/')];\n\n                                            //baseName segment has  config, find if it has one for\n                                            //this name.\n                                            if (mapValue) {\n                                                mapValue = mapValue[nameSegment];\n                                                if (mapValue) {\n                                                    //Match, update name to the new value.\n                                                    foundMap = mapValue;\n                                                    foundI = i;\n                                                    break;\n                                                }\n                                            }\n                                        }\n                                    }\n\n                                    if (foundMap) {\n                                        break;\n                                    }\n\n                                    //Check for a star map match, but just hold on to it,\n                                    //if there is a shorter segment match later in a matching\n                                    //config, then favor over this star map.\n                                    if (!foundStarMap && starMap && starMap[nameSegment]) {\n                                        foundStarMap = starMap[nameSegment];\n                                        starI = i;\n                                    }\n                                }\n\n                                if (!foundMap && foundStarMap) {\n                                    foundMap = foundStarMap;\n                                    foundI = starI;\n                                }\n\n                                if (foundMap) {\n                                    nameParts.splice(0, foundI, foundMap);\n                                    name = nameParts.join('/');\n                                }\n                            }\n\n                            return name;\n                        }\n\n                        function makeRequire(relName, forceSync) {\n                            return function() {\n                                //A version of a require function that passes a moduleName\n                                //value for items that may need to\n                                //look up paths relative to the moduleName\n                                var args = aps.call(arguments, 0);\n\n                                //If first arg is not require('string'), and there is only\n                                //one arg, it is the array form without a callback. Insert\n                                //a null so that the following concat is correct.\n                                if (typeof args[0] !== 'string' && args.length === 1) {\n                                    args.push(null);\n                                }\n                                return req.apply(undef, args.concat([relName, forceSync]));\n                            };\n                        }\n\n                        function makeNormalize(relName) {\n                            return function(name) {\n                                return normalize(name, relName);\n                            };\n                        }\n\n                        function makeLoad(depName) {\n                            return function(value) {\n                                defined[depName] = value;\n                            };\n                        }\n\n                        function callDep(name) {\n                            if (hasProp(waiting, name)) {\n                                var args = waiting[name];\n                                delete waiting[name];\n                                defining[name] = true;\n                                main.apply(undef, args);\n                            }\n\n                            if (!hasProp(defined, name) && !hasProp(defining, name)) {\n                                throw new Error('No ' + name);\n                            }\n                            return defined[name];\n                        }\n\n                        //Turns a plugin!resource to [plugin, resource]\n                        //with the plugin being undefined if the name\n                        //did not have a plugin prefix.\n                        function splitPrefix(name) {\n                            var prefix,\n                                index = name ? name.indexOf('!') : -1;\n                            if (index > -1) {\n                                prefix = name.substring(0, index);\n                                name = name.substring(index + 1, name.length);\n                            }\n                            return [prefix, name];\n                        }\n\n                        /**\n                         * Makes a name map, normalizing the name, and using a plugin\n                         * for normalization if necessary. Grabs a ref to plugin\n                         * too, as an optimization.\n                         */\n                        makeMap = function(name, relName) {\n                            var plugin,\n                                parts = splitPrefix(name),\n                                prefix = parts[0];\n\n                            name = parts[1];\n\n                            if (prefix) {\n                                prefix = normalize(prefix, relName);\n                                plugin = callDep(prefix);\n                            }\n\n                            //Normalize according\n                            if (prefix) {\n                                if (plugin && plugin.normalize) {\n                                    name = plugin.normalize(name, makeNormalize(relName));\n                                } else {\n                                    name = normalize(name, relName);\n                                }\n                            } else {\n                                name = normalize(name, relName);\n                                parts = splitPrefix(name);\n                                prefix = parts[0];\n                                name = parts[1];\n                                if (prefix) {\n                                    plugin = callDep(prefix);\n                                }\n                            }\n\n                            //Using ridiculous property names for space reasons\n                            return {\n                                f: prefix ? prefix + '!' + name : name, //fullName\n                                n: name,\n                                pr: prefix,\n                                p: plugin\n                            };\n                        };\n\n                        function makeConfig(name) {\n                            return function() {\n                                return (config && config.config && config.config[name]) || {};\n                            };\n                        }\n\n                        handlers = {\n                            require: function(name) {\n                                return makeRequire(name);\n                            },\n                            exports: function(name) {\n                                var e = defined[name];\n                                if (typeof e !== 'undefined') {\n                                    return e;\n                                } else {\n                                    return (defined[name] = {});\n                                }\n                            },\n                            module: function(name) {\n                                return {\n                                    id: name,\n                                    uri: '',\n                                    exports: defined[name],\n                                    config: makeConfig(name)\n                                };\n                            }\n                        };\n\n                        main = function(name, deps, callback, relName) {\n                            var cjsModule, depName, ret, map, i,\n                                args = [],\n                                callbackType = typeof callback,\n                                usingExports;\n\n                            //Use name if no relName\n                            relName = relName || name;\n\n                            //Call the callback to define the module, if necessary.\n                            if (callbackType === 'undefined' || callbackType === 'function') {\n                                //Pull out the defined dependencies and pass the ordered\n                                //values to the callback.\n                                //Default to [require, exports, module] if no deps\n                                deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;\n                                for (i = 0; i < deps.length; i += 1) {\n                                    map = makeMap(deps[i], relName);\n                                    depName = map.f;\n\n                                    //Fast path CommonJS standard dependencies.\n                                    if (depName === \"require\") {\n                                        args[i] = handlers.require(name);\n                                    } else if (depName === \"exports\") {\n                                        //CommonJS module spec 1.1\n                                        args[i] = handlers.exports(name);\n                                        usingExports = true;\n                                    } else if (depName === \"module\") {\n                                        //CommonJS module spec 1.1\n                                        cjsModule = args[i] = handlers.module(name);\n                                    } else if (hasProp(defined, depName) ||\n                                        hasProp(waiting, depName) ||\n                                        hasProp(defining, depName)) {\n                                        args[i] = callDep(depName);\n                                    } else if (map.p) {\n                                        map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});\n                                        args[i] = defined[depName];\n                                    } else {\n                                        throw new Error(name + ' missing ' + depName);\n                                    }\n                                }\n\n                                ret = callback ? callback.apply(defined[name], args) : undefined;\n\n                                if (name) {\n                                    //If setting exports via \"module\" is in play,\n                                    //favor that over return value and exports. After that,\n                                    //favor a non-undefined return value over exports use.\n                                    if (cjsModule && cjsModule.exports !== undef &&\n                                        cjsModule.exports !== defined[name]) {\n                                        defined[name] = cjsModule.exports;\n                                    } else if (ret !== undef || !usingExports) {\n                                        //Use the return value from the function.\n                                        defined[name] = ret;\n                                    }\n                                }\n                            } else if (name) {\n                                //May just be an object definition for the module. Only\n                                //worry about defining if have a module name.\n                                defined[name] = callback;\n                            }\n                        };\n\n                        requirejs = require = req = function(deps, callback, relName, forceSync, alt) {\n                            if (typeof deps === \"string\") {\n                                if (handlers[deps]) {\n                                    //callback in this case is really relName\n                                    return handlers[deps](callback);\n                                }\n                                //Just return the module wanted. In this scenario, the\n                                //deps arg is the module name, and second arg (if passed)\n                                //is just the relName.\n                                //Normalize module name, if it contains . or ..\n                                return callDep(makeMap(deps, callback).f);\n                            } else if (!deps.splice) {\n                                //deps is a config object, not an array.\n                                config = deps;\n                                if (config.deps) {\n                                    req(config.deps, config.callback);\n                                }\n                                if (!callback) {\n                                    return;\n                                }\n\n                                if (callback.splice) {\n                                    //callback is an array, which means it is a dependency list.\n                                    //Adjust args if there are dependencies\n                                    deps = callback;\n                                    callback = relName;\n                                    relName = null;\n                                } else {\n                                    deps = undef;\n                                }\n                            }\n\n                            //Support require(['a'])\n                            callback = callback || function() {};\n\n                            //If relName is a function, it is an errback handler,\n                            //so remove it.\n                            if (typeof relName === 'function') {\n                                relName = forceSync;\n                                forceSync = alt;\n                            }\n\n                            //Simulate async callback;\n                            if (forceSync) {\n                                main(undef, deps, callback, relName);\n                            } else {\n                                //Using a non-zero value because of concern for what old browsers\n                                //do, and latest browsers \"upgrade\" to 4 if lower value is used:\n                                //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:\n                                //If want a value immediately, use require('id') instead -- something\n                                //that works in almond on the global level, but not guaranteed and\n                                //unlikely to work in other AMD implementations.\n                                setTimeout(function() {\n                                    main(undef, deps, callback, relName);\n                                }, 4);\n                            }\n\n                            return req;\n                        };\n\n                        /**\n                         * Just drops the config on the floor, but returns req in case\n                         * the config return value is used.\n                         */\n                        req.config = function(cfg) {\n                            return req(cfg);\n                        };\n\n                        /**\n                         * Expose module registry for debugging and tooling\n                         */\n                        requirejs._defined = defined;\n\n                        define = function(name, deps, callback) {\n                            if (typeof name !== 'string') {\n                                throw new Error('See almond README: incorrect module build, no module name');\n                            }\n\n                            //This module may not have dependencies\n                            if (!deps.splice) {\n                                //deps is not an array, so probably means\n                                //an object literal or factory function for\n                                //the value. Adjust args.\n                                callback = deps;\n                                deps = [];\n                            }\n\n                            if (!hasProp(defined, name) && !hasProp(waiting, name)) {\n                                waiting[name] = [name, deps, callback];\n                            }\n                        };\n\n                        define.amd = {\n                            jQuery: true\n                        };\n                    }());\n\n                    S2.requirejs = requirejs;\n                    S2.require = require;\n                    S2.define = define;\n                }\n            }());\n            S2.define(\"almond\", function() {});\n\n            /* global jQuery:false, $:false */\n            S2.define('jquery', [], function() {\n                var _$ = jQuery || $;\n\n                if (_$ == null && console && console.error) {\n                    console.error(\n                        'Select2: An instance of jQuery or a jQuery-compatible library was not ' +\n                        'found. Make sure that you are including jQuery before Select2 on your ' +\n                        'web page.'\n                    );\n                }\n\n                return _$;\n            });\n\n            S2.define('select2/utils', [\n                'jquery'\n            ], function($) {\n                var Utils = {};\n\n                Utils.Extend = function(ChildClass, SuperClass) {\n                    var __hasProp = {}.hasOwnProperty;\n\n                    function BaseConstructor() {\n                        this.constructor = ChildClass;\n                    }\n\n                    for (var key in SuperClass) {\n                        if (__hasProp.call(SuperClass, key)) {\n                            ChildClass[key] = SuperClass[key];\n                        }\n                    }\n\n                    BaseConstructor.prototype = SuperClass.prototype;\n                    ChildClass.prototype = new BaseConstructor();\n                    ChildClass.__super__ = SuperClass.prototype;\n\n                    return ChildClass;\n                };\n\n                function getMethods(theClass) {\n                    var proto = theClass.prototype;\n\n                    var methods = [];\n\n                    for (var methodName in proto) {\n                        var m = proto[methodName];\n\n                        if (typeof m !== 'function') {\n                            continue;\n                        }\n\n                        if (methodName === 'constructor') {\n                            continue;\n                        }\n\n                        methods.push(methodName);\n                    }\n\n                    return methods;\n                }\n\n                Utils.Decorate = function(SuperClass, DecoratorClass) {\n                    var decoratedMethods = getMethods(DecoratorClass);\n                    var superMethods = getMethods(SuperClass);\n\n                    function DecoratedClass() {\n                        var unshift = Array.prototype.unshift;\n\n                        var argCount = DecoratorClass.prototype.constructor.length;\n\n                        var calledConstructor = SuperClass.prototype.constructor;\n\n                        if (argCount > 0) {\n                            unshift.call(arguments, SuperClass.prototype.constructor);\n\n                            calledConstructor = DecoratorClass.prototype.constructor;\n                        }\n\n                        calledConstructor.apply(this, arguments);\n                    }\n\n                    DecoratorClass.displayName = SuperClass.displayName;\n\n                    function ctr() {\n                        this.constructor = DecoratedClass;\n                    }\n\n                    DecoratedClass.prototype = new ctr();\n\n                    for (var m = 0; m < superMethods.length; m++) {\n                        var superMethod = superMethods[m];\n\n                        DecoratedClass.prototype[superMethod] =\n                            SuperClass.prototype[superMethod];\n                    }\n\n                    var calledMethod = function(methodName) {\n                        // Stub out the original method if it's not decorating an actual method\n                        var originalMethod = function() {};\n\n                        if (methodName in DecoratedClass.prototype) {\n                            originalMethod = DecoratedClass.prototype[methodName];\n                        }\n\n                        var decoratedMethod = DecoratorClass.prototype[methodName];\n\n                        return function() {\n                            var unshift = Array.prototype.unshift;\n\n                            unshift.call(arguments, originalMethod);\n\n                            return decoratedMethod.apply(this, arguments);\n                        };\n                    };\n\n                    for (var d = 0; d < decoratedMethods.length; d++) {\n                        var decoratedMethod = decoratedMethods[d];\n\n                        DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);\n                    }\n\n                    return DecoratedClass;\n                };\n\n                var Observable = function() {\n                    this.listeners = {};\n                };\n\n                Observable.prototype.on = function(event, callback) {\n                    this.listeners = this.listeners || {};\n\n                    if (event in this.listeners) {\n                        this.listeners[event].push(callback);\n                    } else {\n                        this.listeners[event] = [callback];\n                    }\n                };\n\n                Observable.prototype.trigger = function(event) {\n                    var slice = Array.prototype.slice;\n\n                    this.listeners = this.listeners || {};\n\n                    if (event in this.listeners) {\n                        this.invoke(this.listeners[event], slice.call(arguments, 1));\n                    }\n\n                    if ('*' in this.listeners) {\n                        this.invoke(this.listeners['*'], arguments);\n                    }\n                };\n\n                Observable.prototype.invoke = function(listeners, params) {\n                    for (var i = 0, len = listeners.length; i < len; i++) {\n                        listeners[i].apply(this, params);\n                    }\n                };\n\n                Utils.Observable = Observable;\n\n                Utils.generateChars = function(length) {\n                    var chars = '';\n\n                    for (var i = 0; i < length; i++) {\n                        var randomChar = Math.floor(Math.random() * 36);\n                        chars += randomChar.toString(36);\n                    }\n\n                    return chars;\n                };\n\n                Utils.bind = function(func, context) {\n                    return function() {\n                        func.apply(context, arguments);\n                    };\n                };\n\n                Utils._convertData = function(data) {\n                    for (var originalKey in data) {\n                        var keys = originalKey.split('-');\n\n                        var dataLevel = data;\n\n                        if (keys.length === 1) {\n                            continue;\n                        }\n\n                        for (var k = 0; k < keys.length; k++) {\n                            var key = keys[k];\n\n                            // Lowercase the first letter\n                            // By default, dash-separated becomes camelCase\n                            key = key.substring(0, 1).toLowerCase() + key.substring(1);\n\n                            if (!(key in dataLevel)) {\n                                dataLevel[key] = {};\n                            }\n\n                            if (k == keys.length - 1) {\n                                dataLevel[key] = data[originalKey];\n                            }\n\n                            dataLevel = dataLevel[key];\n                        }\n\n                        delete data[originalKey];\n                    }\n\n                    return data;\n                };\n\n                Utils.hasScroll = function(index, el) {\n                    // Adapted from the function created by @ShadowScripter\n                    // and adapted by @BillBarry on the Stack Exchange Code Review website.\n                    // The original code can be found at\n                    // http://codereview.stackexchange.com/q/13338\n                    // and was designed to be used with the Sizzle selector engine.\n\n                    var $el = $(el);\n                    var overflowX = el.style.overflowX;\n                    var overflowY = el.style.overflowY;\n\n                    //Check both x and y declarations\n                    if (overflowX === overflowY &&\n                        (overflowY === 'hidden' || overflowY === 'visible')) {\n                        return false;\n                    }\n\n                    if (overflowX === 'scroll' || overflowY === 'scroll') {\n                        return true;\n                    }\n\n                    return ($el.innerHeight() < el.scrollHeight ||\n                        $el.innerWidth() < el.scrollWidth);\n                };\n\n                Utils.escapeMarkup = function(markup) {\n                    var replaceMap = {\n                        '\\\\': '&#92;',\n                        '&': '&amp;',\n                        '<': '&lt;',\n                        '>': '&gt;',\n                        '\"': '&quot;',\n                        '\\'': '&#39;',\n                        '/': '&#47;'\n                    };\n\n                    // Do not try to escape the markup if it's not a string\n                    if (typeof markup !== 'string') {\n                        return markup;\n                    }\n\n                    return String(markup).replace(/[&<>\"'\\/\\\\]/g, function(match) {\n                        return replaceMap[match];\n                    });\n                };\n\n                // Append an array of jQuery nodes to a given element.\n                Utils.appendMany = function($element, $nodes) {\n                    // jQuery 1.7.x does not support $.fn.append() with an array\n                    // Fall back to a jQuery object collection using $.fn.add()\n                    if ($.fn.jquery.substr(0, 3) === '1.7') {\n                        var $jqNodes = $();\n\n                        $.map($nodes, function(node) {\n                            $jqNodes = $jqNodes.add(node);\n                        });\n\n                        $nodes = $jqNodes;\n                    }\n\n                    $element.append($nodes);\n                };\n\n                return Utils;\n            });\n\n            S2.define('select2/results', [\n                'jquery',\n                './utils'\n            ], function($, Utils) {\n                function Results($element, options, dataAdapter) {\n                    this.$element = $element;\n                    this.data = dataAdapter;\n                    this.options = options;\n\n                    Results.__super__.constructor.call(this);\n                }\n\n                Utils.Extend(Results, Utils.Observable);\n\n                Results.prototype.render = function() {\n                    var $results = $(\n                        '<ul class=\"select2-results__options\" role=\"tree\"></ul>'\n                    );\n\n                    if (this.options.get('multiple')) {\n                        $results.attr('aria-multiselectable', 'true');\n                    }\n\n                    this.$results = $results;\n\n                    return $results;\n                };\n\n                Results.prototype.clear = function() {\n                    this.$results.empty();\n                };\n\n                Results.prototype.displayMessage = function(params) {\n                    var escapeMarkup = this.options.get('escapeMarkup');\n\n                    this.clear();\n                    this.hideLoading();\n\n                    var $message = $(\n                        '<li role=\"treeitem\" aria-live=\"assertive\"' +\n                        ' class=\"select2-results__option\"></li>'\n                    );\n\n                    var message = this.options.get('translations').get(params.message);\n\n                    $message.append(\n                        escapeMarkup(\n                            message(params.args)\n                        )\n                    );\n\n                    $message[0].className += ' select2-results__message';\n\n                    this.$results.append($message);\n                };\n\n                Results.prototype.hideMessages = function() {\n                    this.$results.find('.select2-results__message').remove();\n                };\n\n                Results.prototype.append = function(data) {\n                    this.hideLoading();\n\n                    var $options = [];\n\n                    if (data.results == null || data.results.length === 0) {\n                        if (this.$results.children().length === 0) {\n                            this.trigger('results:message', {\n                                message: 'noResults'\n                            });\n                        }\n\n                        return;\n                    }\n\n                    data.results = this.sort(data.results);\n\n                    for (var d = 0; d < data.results.length; d++) {\n                        var item = data.results[d];\n\n                        var $option = this.option(item);\n\n                        $options.push($option);\n                    }\n\n                    this.$results.append($options);\n                };\n\n                Results.prototype.position = function($results, $dropdown) {\n                    var $resultsContainer = $dropdown.find('.select2-results');\n                    $resultsContainer.append($results);\n                };\n\n                Results.prototype.sort = function(data) {\n                    var sorter = this.options.get('sorter');\n\n                    return sorter(data);\n                };\n\n                Results.prototype.setClasses = function() {\n                    var self = this;\n\n                    this.data.current(function(selected) {\n                        var selectedIds = $.map(selected, function(s) {\n                            return s.id.toString();\n                        });\n\n                        var $options = self.$results\n                            .find('.select2-results__option[aria-selected]');\n\n                        $options.each(function() {\n                            var $option = $(this);\n\n                            var item = $.data(this, 'data');\n\n                            // id needs to be converted to a string when comparing\n                            var id = '' + item.id;\n\n                            if ((item.element != null && item.element.selected) ||\n                                (item.element == null && $.inArray(id, selectedIds) > -1)) {\n                                $option.attr('aria-selected', 'true');\n                            } else {\n                                $option.attr('aria-selected', 'false');\n                            }\n                        });\n\n                        var $selected = $options.filter('[aria-selected=true]');\n\n                        // Check if there are any selected options\n                        if ($selected.length > 0) {\n                            // If there are selected options, highlight the first\n                            $selected.first().trigger('mouseenter');\n                        } else {\n                            // If there are no selected options, highlight the first option\n                            // in the dropdown\n                            $options.first().trigger('mouseenter');\n                        }\n                    });\n                };\n\n                Results.prototype.showLoading = function(params) {\n                    this.hideLoading();\n\n                    var loadingMore = this.options.get('translations').get('searching');\n\n                    var loading = {\n                        disabled: true,\n                        loading: true,\n                        text: loadingMore(params)\n                    };\n                    var $loading = this.option(loading);\n                    $loading.className += ' loading-results';\n\n                    this.$results.prepend($loading);\n                };\n\n                Results.prototype.hideLoading = function() {\n                    this.$results.find('.loading-results').remove();\n                };\n\n                Results.prototype.option = function(data) {\n                    var option = document.createElement('li');\n                    option.className = 'select2-results__option';\n\n                    var attrs = {\n                        'role': 'treeitem',\n                        'aria-selected': 'false'\n                    };\n\n                    if (data.disabled) {\n                        delete attrs['aria-selected'];\n                        attrs['aria-disabled'] = 'true';\n                    }\n\n                    if (data.id == null) {\n                        delete attrs['aria-selected'];\n                    }\n\n                    if (data._resultId != null) {\n                        option.id = data._resultId;\n                    }\n\n                    if (data.title) {\n                        option.title = data.title;\n                    }\n\n                    if (data.children) {\n                        attrs.role = 'group';\n                        attrs['aria-label'] = data.text;\n                        delete attrs['aria-selected'];\n                    }\n\n                    for (var attr in attrs) {\n                        var val = attrs[attr];\n\n                        option.setAttribute(attr, val);\n                    }\n\n                    if (data.children) {\n                        var $option = $(option);\n\n                        var label = document.createElement('strong');\n                        label.className = 'select2-results__group';\n\n                        var $label = $(label);\n                        this.template(data, label);\n\n                        var $children = [];\n\n                        for (var c = 0; c < data.children.length; c++) {\n                            var child = data.children[c];\n\n                            var $child = this.option(child);\n\n                            $children.push($child);\n                        }\n\n                        var $childrenContainer = $('<ul></ul>', {\n                            'class': 'select2-results__options select2-results__options--nested'\n                        });\n\n                        $childrenContainer.append($children);\n\n                        $option.append(label);\n                        $option.append($childrenContainer);\n                    } else {\n                        this.template(data, option);\n                    }\n\n                    $.data(option, 'data', data);\n\n                    return option;\n                };\n\n                Results.prototype.bind = function(container, $container) {\n                    var self = this;\n\n                    var id = container.id + '-results';\n\n                    this.$results.attr('id', id);\n\n                    container.on('results:all', function(params) {\n                        self.clear();\n                        self.append(params.data);\n\n                        if (container.isOpen()) {\n                            self.setClasses();\n                        }\n                    });\n\n                    container.on('results:append', function(params) {\n                        self.append(params.data);\n\n                        if (container.isOpen()) {\n                            self.setClasses();\n                        }\n                    });\n\n                    container.on('query', function(params) {\n                        self.hideMessages();\n                        self.showLoading(params);\n                    });\n\n                    container.on('select', function() {\n                        if (!container.isOpen()) {\n                            return;\n                        }\n\n                        self.setClasses();\n                    });\n\n                    container.on('unselect', function() {\n                        if (!container.isOpen()) {\n                            return;\n                        }\n\n                        self.setClasses();\n                    });\n\n                    container.on('open', function() {\n                        // When the dropdown is open, aria-expended=\"true\"\n                        self.$results.attr('aria-expanded', 'true');\n                        self.$results.attr('aria-hidden', 'false');\n\n                        self.setClasses();\n                        self.ensureHighlightVisible();\n                    });\n\n                    container.on('close', function() {\n                        // When the dropdown is closed, aria-expended=\"false\"\n                        self.$results.attr('aria-expanded', 'false');\n                        self.$results.attr('aria-hidden', 'true');\n                        self.$results.removeAttr('aria-activedescendant');\n                    });\n\n                    container.on('results:toggle', function() {\n                        var $highlighted = self.getHighlightedResults();\n\n                        if ($highlighted.length === 0) {\n                            return;\n                        }\n\n                        $highlighted.trigger('mouseup');\n                    });\n\n                    container.on('results:select', function() {\n                        var $highlighted = self.getHighlightedResults();\n\n                        if ($highlighted.length === 0) {\n                            return;\n                        }\n\n                        var data = $highlighted.data('data');\n\n                        if ($highlighted.attr('aria-selected') == 'true') {\n                            self.trigger('close', {});\n                        } else {\n                            self.trigger('select', {\n                                data: data\n                            });\n                        }\n                    });\n\n                    container.on('results:previous', function() {\n                        var $highlighted = self.getHighlightedResults();\n\n                        var $options = self.$results.find('[aria-selected]');\n\n                        var currentIndex = $options.index($highlighted);\n\n                        // If we are already at te top, don't move further\n                        if (currentIndex === 0) {\n                            return;\n                        }\n\n                        var nextIndex = currentIndex - 1;\n\n                        // If none are highlighted, highlight the first\n                        if ($highlighted.length === 0) {\n                            nextIndex = 0;\n                        }\n\n                        var $next = $options.eq(nextIndex);\n\n                        $next.trigger('mouseenter');\n\n                        var currentOffset = self.$results.offset().top;\n                        var nextTop = $next.offset().top;\n                        var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);\n\n                        if (nextIndex === 0) {\n                            self.$results.scrollTop(0);\n                        } else if (nextTop - currentOffset < 0) {\n                            self.$results.scrollTop(nextOffset);\n                        }\n                    });\n\n                    container.on('results:next', function() {\n                        var $highlighted = self.getHighlightedResults();\n\n                        var $options = self.$results.find('[aria-selected]');\n\n                        var currentIndex = $options.index($highlighted);\n\n                        var nextIndex = currentIndex + 1;\n\n                        // If we are at the last option, stay there\n                        if (nextIndex >= $options.length) {\n                            return;\n                        }\n\n                        var $next = $options.eq(nextIndex);\n\n                        $next.trigger('mouseenter');\n\n                        var currentOffset = self.$results.offset().top +\n                            self.$results.outerHeight(false);\n                        var nextBottom = $next.offset().top + $next.outerHeight(false);\n                        var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;\n\n                        if (nextIndex === 0) {\n                            self.$results.scrollTop(0);\n                        } else if (nextBottom > currentOffset) {\n                            self.$results.scrollTop(nextOffset);\n                        }\n                    });\n\n                    container.on('results:focus', function(params) {\n                        params.element.addClass('select2-results__option--highlighted');\n                    });\n\n                    container.on('results:message', function(params) {\n                        self.displayMessage(params);\n                    });\n\n                    if ($.fn.mousewheel) {\n                        this.$results.on('mousewheel', function(e) {\n                            var top = self.$results.scrollTop();\n\n                            var bottom = (\n                                self.$results.get(0).scrollHeight -\n                                self.$results.scrollTop() +\n                                e.deltaY\n                            );\n\n                            var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;\n                            var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();\n\n                            if (isAtTop) {\n                                self.$results.scrollTop(0);\n\n                                e.preventDefault();\n                                e.stopPropagation();\n                            } else if (isAtBottom) {\n                                self.$results.scrollTop(\n                                    self.$results.get(0).scrollHeight - self.$results.height()\n                                );\n\n                                e.preventDefault();\n                                e.stopPropagation();\n                            }\n                        });\n                    }\n\n                    this.$results.on('mouseup', '.select2-results__option[aria-selected]',\n                        function(evt) {\n                            var $this = $(this);\n\n                            var data = $this.data('data');\n\n                            if ($this.attr('aria-selected') === 'true') {\n                                if (self.options.get('multiple')) {\n                                    self.trigger('unselect', {\n                                        originalEvent: evt,\n                                        data: data\n                                    });\n                                } else {\n                                    self.trigger('close', {});\n                                }\n\n                                return;\n                            }\n\n                            self.trigger('select', {\n                                originalEvent: evt,\n                                data: data\n                            });\n                        });\n\n                    this.$results.on('mouseenter', '.select2-results__option[aria-selected]',\n                        function(evt) {\n                            var data = $(this).data('data');\n\n                            self.getHighlightedResults()\n                                .removeClass('select2-results__option--highlighted');\n\n                            self.trigger('results:focus', {\n                                data: data,\n                                element: $(this)\n                            });\n                        });\n                };\n\n                Results.prototype.getHighlightedResults = function() {\n                    var $highlighted = this.$results\n                        .find('.select2-results__option--highlighted');\n\n                    return $highlighted;\n                };\n\n                Results.prototype.destroy = function() {\n                    this.$results.remove();\n                };\n\n                Results.prototype.ensureHighlightVisible = function() {\n                    var $highlighted = this.getHighlightedResults();\n\n                    if ($highlighted.length === 0) {\n                        return;\n                    }\n\n                    var $options = this.$results.find('[aria-selected]');\n\n                    var currentIndex = $options.index($highlighted);\n\n                    var currentOffset = this.$results.offset().top;\n                    var nextTop = $highlighted.offset().top;\n                    var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);\n\n                    var offsetDelta = nextTop - currentOffset;\n                    nextOffset -= $highlighted.outerHeight(false) * 2;\n\n                    if (currentIndex <= 2) {\n                        this.$results.scrollTop(0);\n                    } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {\n                        this.$results.scrollTop(nextOffset);\n                    }\n                };\n\n                Results.prototype.template = function(result, container) {\n                    var template = this.options.get('templateResult');\n                    var escapeMarkup = this.options.get('escapeMarkup');\n\n                    var content = template(result, container);\n\n                    if (content == null) {\n                        container.style.display = 'none';\n                    } else if (typeof content === 'string') {\n                        container.innerHTML = escapeMarkup(content);\n                    } else {\n                        $(container).append(content);\n                    }\n                };\n\n                return Results;\n            });\n\n            S2.define('select2/keys', [\n\n            ], function() {\n                var KEYS = {\n                    BACKSPACE: 8,\n                    TAB: 9,\n                    ENTER: 13,\n                    SHIFT: 16,\n                    CTRL: 17,\n                    ALT: 18,\n                    ESC: 27,\n                    SPACE: 32,\n                    PAGE_UP: 33,\n                    PAGE_DOWN: 34,\n                    END: 35,\n                    HOME: 36,\n                    LEFT: 37,\n                    UP: 38,\n                    RIGHT: 39,\n                    DOWN: 40,\n                    DELETE: 46\n                };\n\n                return KEYS;\n            });\n\n            S2.define('select2/selection/base', [\n                'jquery',\n                '../utils',\n                '../keys'\n            ], function($, Utils, KEYS) {\n                function BaseSelection($element, options) {\n                    this.$element = $element;\n                    this.options = options;\n\n                    BaseSelection.__super__.constructor.call(this);\n                }\n\n                Utils.Extend(BaseSelection, Utils.Observable);\n\n                BaseSelection.prototype.render = function() {\n                    var $selection = $(\n                        '<span class=\"select2-selection\" role=\"combobox\" ' +\n                        ' aria-haspopup=\"true\" aria-expanded=\"false\">' +\n                        '</span>'\n                    );\n\n                    this._tabindex = 0;\n\n                    if (this.$element.data('old-tabindex') != null) {\n                        this._tabindex = this.$element.data('old-tabindex');\n                    } else if (this.$element.attr('tabindex') != null) {\n                        this._tabindex = this.$element.attr('tabindex');\n                    }\n\n                    $selection.attr('title', this.$element.attr('title'));\n                    $selection.attr('tabindex', this._tabindex);\n\n                    this.$selection = $selection;\n\n                    return $selection;\n                };\n\n                BaseSelection.prototype.bind = function(container, $container) {\n                    var self = this;\n\n                    var id = container.id + '-container';\n                    var resultsId = container.id + '-results';\n\n                    this.container = container;\n\n                    this.$selection.on('focus', function(evt) {\n                        self.trigger('focus', evt);\n                    });\n\n                    this.$selection.on('blur', function(evt) {\n                        self._handleBlur(evt);\n                    });\n\n                    this.$selection.on('keydown', function(evt) {\n                        self.trigger('keypress', evt);\n\n                        if (evt.which === KEYS.SPACE) {\n                            evt.preventDefault();\n                        }\n                    });\n\n                    container.on('results:focus', function(params) {\n                        self.$selection.attr('aria-activedescendant', params.data._resultId);\n                    });\n\n                    container.on('selection:update', function(params) {\n                        self.update(params.data);\n                    });\n\n                    container.on('open', function() {\n                        // When the dropdown is open, aria-expanded=\"true\"\n                        self.$selection.attr('aria-expanded', 'true');\n                        self.$selection.attr('aria-owns', resultsId);\n\n                        self._attachCloseHandler(container);\n                    });\n\n                    container.on('close', function() {\n                        // When the dropdown is closed, aria-expanded=\"false\"\n                        self.$selection.attr('aria-expanded', 'false');\n                        self.$selection.removeAttr('aria-activedescendant');\n                        self.$selection.removeAttr('aria-owns');\n\n                        self.$selection.focus();\n\n                        self._detachCloseHandler(container);\n                    });\n\n                    container.on('enable', function() {\n                        self.$selection.attr('tabindex', self._tabindex);\n                    });\n\n                    container.on('disable', function() {\n                        self.$selection.attr('tabindex', '-1');\n                    });\n                };\n\n                BaseSelection.prototype._handleBlur = function(evt) {\n                    var self = this;\n\n                    // This needs to be delayed as the active element is the body when the tab\n                    // key is pressed, possibly along with others.\n                    window.setTimeout(function() {\n                        // Don't trigger `blur` if the focus is still in the selection\n                        if (\n                            (document.activeElement == self.$selection[0]) ||\n                            ($.contains(self.$selection[0], document.activeElement))\n                        ) {\n                            return;\n                        }\n\n                        self.trigger('blur', evt);\n                    }, 1);\n                };\n\n                BaseSelection.prototype._attachCloseHandler = function(container) {\n                    var self = this;\n\n                    $(document.body).on('mousedown.select2.' + container.id, function(e) {\n                        var $target = $(e.target);\n\n                        var $select = $target.closest('.select2');\n\n                        var $all = $('.select2.select2-container--open');\n\n                        $all.each(function() {\n                            var $this = $(this);\n\n                            if (this == $select[0]) {\n                                return;\n                            }\n\n                            var $element = $this.data('element');\n\n                            $element.select2('close');\n                        });\n                    });\n                };\n\n                BaseSelection.prototype._detachCloseHandler = function(container) {\n                    $(document.body).off('mousedown.select2.' + container.id);\n                };\n\n                BaseSelection.prototype.position = function($selection, $container) {\n                    var $selectionContainer = $container.find('.selection');\n                    $selectionContainer.append($selection);\n                };\n\n                BaseSelection.prototype.destroy = function() {\n                    this._detachCloseHandler(this.container);\n                };\n\n                BaseSelection.prototype.update = function(data) {\n                    throw new Error('The `update` method must be defined in child classes.');\n                };\n\n                return BaseSelection;\n            });\n\n            S2.define('select2/selection/single', [\n                'jquery',\n                './base',\n                '../utils',\n                '../keys'\n            ], function($, BaseSelection, Utils, KEYS) {\n                function SingleSelection() {\n                    SingleSelection.__super__.constructor.apply(this, arguments);\n                }\n\n                Utils.Extend(SingleSelection, BaseSelection);\n\n                SingleSelection.prototype.render = function() {\n                    var $selection = SingleSelection.__super__.render.call(this);\n\n                    $selection.addClass('select2-selection--single');\n\n                    $selection.html(\n                        '<span class=\"select2-selection__rendered\"></span>' +\n                        '<span class=\"select2-selection__arrow\" role=\"presentation\">' +\n                        '<b role=\"presentation\"></b>' +\n                        '</span>'\n                    );\n\n                    return $selection;\n                };\n\n                SingleSelection.prototype.bind = function(container, $container) {\n                    var self = this;\n\n                    SingleSelection.__super__.bind.apply(this, arguments);\n\n                    var id = container.id + '-container';\n\n                    this.$selection.find('.select2-selection__rendered').attr('id', id);\n                    this.$selection.attr('aria-labelledby', id);\n\n                    this.$selection.on('mousedown', function(evt) {\n                        // Only respond to left clicks\n                        if (evt.which !== 1) {\n                            return;\n                        }\n\n                        self.trigger('toggle', {\n                            originalEvent: evt\n                        });\n                    });\n\n                    this.$selection.on('focus', function(evt) {\n                        // User focuses on the container\n                    });\n\n                    this.$selection.on('blur', function(evt) {\n                        // User exits the container\n                    });\n\n                    container.on('selection:update', function(params) {\n                        self.update(params.data);\n                    });\n                };\n\n                SingleSelection.prototype.clear = function() {\n                    this.$selection.find('.select2-selection__rendered').empty();\n                };\n\n                SingleSelection.prototype.display = function(data, container) {\n                    var template = this.options.get('templateSelection');\n                    var escapeMarkup = this.options.get('escapeMarkup');\n\n                    return escapeMarkup(template(data, container));\n                };\n\n                SingleSelection.prototype.selectionContainer = function() {\n                    return $('<span></span>');\n                };\n\n                SingleSelection.prototype.update = function(data) {\n                    if (data.length === 0) {\n                        this.clear();\n                        return;\n                    }\n\n                    var selection = data[0];\n\n                    var $rendered = this.$selection.find('.select2-selection__rendered');\n                    var formatted = this.display(selection, $rendered);\n\n                    $rendered.empty().append(formatted);\n                    $rendered.prop('title', selection.title || selection.text);\n                };\n\n                return SingleSelection;\n            });\n\n            S2.define('select2/selection/multiple', [\n                'jquery',\n                './base',\n                '../utils'\n            ], function($, BaseSelection, Utils) {\n                function MultipleSelection($element, options) {\n                    MultipleSelection.__super__.constructor.apply(this, arguments);\n                }\n\n                Utils.Extend(MultipleSelection, BaseSelection);\n\n                MultipleSelection.prototype.render = function() {\n                    var $selection = MultipleSelection.__super__.render.call(this);\n\n                    $selection.addClass('select2-selection--multiple');\n\n                    $selection.html(\n                        '<ul class=\"select2-selection__rendered\"></ul>'\n                    );\n\n                    return $selection;\n                };\n\n                MultipleSelection.prototype.bind = function(container, $container) {\n                    var self = this;\n\n                    MultipleSelection.__super__.bind.apply(this, arguments);\n\n                    this.$selection.on('click', function(evt) {\n                        self.trigger('toggle', {\n                            originalEvent: evt\n                        });\n                    });\n\n                    this.$selection.on(\n                        'click',\n                        '.select2-selection__choice__remove',\n                        function(evt) {\n                            // Ignore the event if it is disabled\n                            if (self.options.get('disabled')) {\n                                return;\n                            }\n\n                            var $remove = $(this);\n                            var $selection = $remove.parent();\n\n                            var data = $selection.data('data');\n\n                            self.trigger('unselect', {\n                                originalEvent: evt,\n                                data: data\n                            });\n                        }\n                    );\n                };\n\n                MultipleSelection.prototype.clear = function() {\n                    this.$selection.find('.select2-selection__rendered').empty();\n                };\n\n                MultipleSelection.prototype.display = function(data, container) {\n                    var template = this.options.get('templateSelection');\n                    var escapeMarkup = this.options.get('escapeMarkup');\n\n                    return escapeMarkup(template(data, container));\n                };\n\n                MultipleSelection.prototype.selectionContainer = function() {\n                    var $container = $(\n                        '<li class=\"select2-selection__choice\">' +\n                        '<span class=\"select2-selection__choice__remove\" role=\"presentation\">' +\n                        '&times;' +\n                        '</span>' +\n                        '</li>'\n                    );\n\n                    return $container;\n                };\n\n                MultipleSelection.prototype.update = function(data) {\n                    this.clear();\n\n                    if (data.length === 0) {\n                        return;\n                    }\n\n                    var $selections = [];\n\n                    for (var d = 0; d < data.length; d++) {\n                        var selection = data[d];\n\n                        var $selection = this.selectionContainer();\n                        var formatted = this.display(selection, $selection);\n\n                        $selection.append(formatted);\n                        $selection.prop('title', selection.title || selection.text);\n\n                        $selection.data('data', selection);\n\n                        $selections.push($selection);\n                    }\n\n                    var $rendered = this.$selection.find('.select2-selection__rendered');\n\n                    Utils.appendMany($rendered, $selections);\n                };\n\n                return MultipleSelection;\n            });\n\n            S2.define('select2/selection/placeholder', [\n                '../utils'\n            ], function(Utils) {\n                function Placeholder(decorated, $element, options) {\n                    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));\n\n                    decorated.call(this, $element, options);\n                }\n\n                Placeholder.prototype.normalizePlaceholder = function(_, placeholder) {\n                    if (typeof placeholder === 'string') {\n                        placeholder = {\n                            id: '',\n                            text: placeholder\n                        };\n                    }\n\n                    return placeholder;\n                };\n\n                Placeholder.prototype.createPlaceholder = function(decorated, placeholder) {\n                    var $placeholder = this.selectionContainer();\n\n                    $placeholder.html(this.display(placeholder));\n                    $placeholder.addClass('select2-selection__placeholder')\n                        .removeClass('select2-selection__choice');\n\n                    return $placeholder;\n                };\n\n                Placeholder.prototype.update = function(decorated, data) {\n                    var singlePlaceholder = (\n                        data.length == 1 && data[0].id != this.placeholder.id\n                    );\n                    var multipleSelections = data.length > 1;\n\n                    if (multipleSelections || singlePlaceholder) {\n                        return decorated.call(this, data);\n                    }\n\n                    this.clear();\n\n                    var $placeholder = this.createPlaceholder(this.placeholder);\n\n                    this.$selection.find('.select2-selection__rendered').append($placeholder);\n                };\n\n                return Placeholder;\n            });\n\n            S2.define('select2/selection/allowClear', [\n                'jquery',\n                '../keys'\n            ], function($, KEYS) {\n                function AllowClear() {}\n\n                AllowClear.prototype.bind = function(decorated, container, $container) {\n                    var self = this;\n\n                    decorated.call(this, container, $container);\n\n                    if (this.placeholder == null) {\n                        if (this.options.get('debug') && window.console && console.error) {\n                            console.error(\n                                'Select2: The `allowClear` option should be used in combination ' +\n                                'with the `placeholder` option.'\n                            );\n                        }\n                    }\n\n                    this.$selection.on('mousedown', '.select2-selection__clear',\n                        function(evt) {\n                            self._handleClear(evt);\n                        });\n\n                    container.on('keypress', function(evt) {\n                        self._handleKeyboardClear(evt, container);\n                    });\n                };\n\n                AllowClear.prototype._handleClear = function(_, evt) {\n                    // Ignore the event if it is disabled\n                    if (this.options.get('disabled')) {\n                        return;\n                    }\n\n                    var $clear = this.$selection.find('.select2-selection__clear');\n\n                    // Ignore the event if nothing has been selected\n                    if ($clear.length === 0) {\n                        return;\n                    }\n\n                    evt.stopPropagation();\n\n                    var data = $clear.data('data');\n\n                    for (var d = 0; d < data.length; d++) {\n                        var unselectData = {\n                            data: data[d]\n                        };\n\n                        // Trigger the `unselect` event, so people can prevent it from being\n                        // cleared.\n                        this.trigger('unselect', unselectData);\n\n                        // If the event was prevented, don't clear it out.\n                        if (unselectData.prevented) {\n                            return;\n                        }\n                    }\n\n                    this.$element.val(this.placeholder.id).trigger('change');\n\n                    this.trigger('toggle', {});\n                };\n\n                AllowClear.prototype._handleKeyboardClear = function(_, evt, container) {\n                    if (container.isOpen()) {\n                        return;\n                    }\n\n                    if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {\n                        this._handleClear(evt);\n                    }\n                };\n\n                AllowClear.prototype.update = function(decorated, data) {\n                    decorated.call(this, data);\n\n                    if (this.$selection.find('.select2-selection__placeholder').length > 0 ||\n                        data.length === 0) {\n                        return;\n                    }\n\n                    var $remove = $(\n                        '<span class=\"select2-selection__clear\">' +\n                        '&times;' +\n                        '</span>'\n                    );\n                    $remove.data('data', data);\n\n                    this.$selection.find('.select2-selection__rendered').prepend($remove);\n                };\n\n                return AllowClear;\n            });\n\n            S2.define('select2/selection/search', [\n                'jquery',\n                '../utils',\n                '../keys'\n            ], function($, Utils, KEYS) {\n                function Search(decorated, $element, options) {\n                    decorated.call(this, $element, options);\n                }\n\n                Search.prototype.render = function(decorated) {\n                    var $search = $(\n                        '<li class=\"select2-search select2-search--inline\">' +\n                        '<input class=\"select2-search__field\" type=\"search\" tabindex=\"-1\"' +\n                        ' autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\"' +\n                        ' spellcheck=\"false\" role=\"textbox\" aria-autocomplete=\"list\" />' +\n                        '</li>'\n                    );\n\n                    this.$searchContainer = $search;\n                    this.$search = $search.find('input');\n\n                    var $rendered = decorated.call(this);\n\n                    this._transferTabIndex();\n\n                    return $rendered;\n                };\n\n                Search.prototype.bind = function(decorated, container, $container) {\n                    var self = this;\n\n                    decorated.call(this, container, $container);\n\n                    container.on('open', function() {\n                        self.$search.trigger('focus');\n                    });\n\n                    container.on('close', function() {\n                        self.$search.val('');\n                        self.$search.removeAttr('aria-activedescendant');\n                        self.$search.trigger('focus');\n                    });\n\n                    container.on('enable', function() {\n                        self.$search.prop('disabled', false);\n\n                        self._transferTabIndex();\n                    });\n\n                    container.on('disable', function() {\n                        self.$search.prop('disabled', true);\n                    });\n\n                    container.on('focus', function(evt) {\n                        self.$search.trigger('focus');\n                    });\n\n                    container.on('results:focus', function(params) {\n                        self.$search.attr('aria-activedescendant', params.id);\n                    });\n\n                    this.$selection.on('focusin', '.select2-search--inline', function(evt) {\n                        self.trigger('focus', evt);\n                    });\n\n                    this.$selection.on('focusout', '.select2-search--inline', function(evt) {\n                        self._handleBlur(evt);\n                    });\n\n                    this.$selection.on('keydown', '.select2-search--inline', function(evt) {\n                        evt.stopPropagation();\n\n                        self.trigger('keypress', evt);\n\n                        self._keyUpPrevented = evt.isDefaultPrevented();\n\n                        var key = evt.which;\n\n                        if (key === KEYS.BACKSPACE && self.$search.val() === '') {\n                            var $previousChoice = self.$searchContainer\n                                .prev('.select2-selection__choice');\n\n                            if ($previousChoice.length > 0) {\n                                var item = $previousChoice.data('data');\n\n                                self.searchRemoveChoice(item);\n\n                                evt.preventDefault();\n                            }\n                        }\n                    });\n\n                    // Try to detect the IE version should the `documentMode` property that\n                    // is stored on the document. This is only implemented in IE and is\n                    // slightly cleaner than doing a user agent check.\n                    // This property is not available in Edge, but Edge also doesn't have\n                    // this bug.\n                    var msie = document.documentMode;\n                    var disableInputEvents = msie && msie <= 11;\n\n                    // Workaround for browsers which do not support the `input` event\n                    // This will prevent double-triggering of events for browsers which support\n                    // both the `keyup` and `input` events.\n                    this.$selection.on(\n                        'input.searchcheck',\n                        '.select2-search--inline',\n                        function(evt) {\n                            // IE will trigger the `input` event when a placeholder is used on a\n                            // search box. To get around this issue, we are forced to ignore all\n                            // `input` events in IE and keep using `keyup`.\n                            if (disableInputEvents) {\n                                self.$selection.off('input.search input.searchcheck');\n                                return;\n                            }\n\n                            // Unbind the duplicated `keyup` event\n                            self.$selection.off('keyup.search');\n                        }\n                    );\n\n                    this.$selection.on(\n                        'keyup.search input.search',\n                        '.select2-search--inline',\n                        function(evt) {\n                            // IE will trigger the `input` event when a placeholder is used on a\n                            // search box. To get around this issue, we are forced to ignore all\n                            // `input` events in IE and keep using `keyup`.\n                            if (disableInputEvents && evt.type === 'input') {\n                                self.$selection.off('input.search input.searchcheck');\n                                return;\n                            }\n\n                            var key = evt.which;\n\n                            // We can freely ignore events from modifier keys\n                            if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {\n                                return;\n                            }\n\n                            // Tabbing will be handled during the `keydown` phase\n                            if (key == KEYS.TAB) {\n                                return;\n                            }\n\n                            self.handleSearch(evt);\n                        }\n                    );\n                };\n\n                /**\n                 * This method will transfer the tabindex attribute from the rendered\n                 * selection to the search box. This allows for the search box to be used as\n                 * the primary focus instead of the selection container.\n                 *\n                 * @private\n                 */\n                Search.prototype._transferTabIndex = function(decorated) {\n                    this.$search.attr('tabindex', this.$selection.attr('tabindex'));\n                    this.$selection.attr('tabindex', '-1');\n                };\n\n                Search.prototype.createPlaceholder = function(decorated, placeholder) {\n                    this.$search.attr('placeholder', placeholder.text);\n                };\n\n                Search.prototype.update = function(decorated, data) {\n                    var searchHadFocus = this.$search[0] == document.activeElement;\n\n                    this.$search.attr('placeholder', '');\n\n                    decorated.call(this, data);\n\n                    this.$selection.find('.select2-selection__rendered')\n                        .append(this.$searchContainer);\n\n                    this.resizeSearch();\n                    if (searchHadFocus) {\n                        this.$search.focus();\n                    }\n                };\n\n                Search.prototype.handleSearch = function() {\n                    this.resizeSearch();\n\n                    if (!this._keyUpPrevented) {\n                        var input = this.$search.val();\n\n                        this.trigger('query', {\n                            term: input\n                        });\n                    }\n\n                    this._keyUpPrevented = false;\n                };\n\n                Search.prototype.searchRemoveChoice = function(decorated, item) {\n                    this.trigger('unselect', {\n                        data: item\n                    });\n\n                    this.$search.val(item.text);\n                    this.handleSearch();\n                };\n\n                Search.prototype.resizeSearch = function() {\n                    this.$search.css('width', '25px');\n\n                    var width = '';\n\n                    if (this.$search.attr('placeholder') !== '') {\n                        width = this.$selection.find('.select2-selection__rendered').innerWidth();\n                    } else {\n                        var minimumWidth = this.$search.val().length + 1;\n\n                        width = (minimumWidth * 0.75) + 'em';\n                    }\n\n                    this.$search.css('width', width);\n                };\n\n                return Search;\n            });\n\n            S2.define('select2/selection/eventRelay', [\n                'jquery'\n            ], function($) {\n                function EventRelay() {}\n\n                EventRelay.prototype.bind = function(decorated, container, $container) {\n                    var self = this;\n                    var relayEvents = [\n                        'open', 'opening',\n                        'close', 'closing',\n                        'select', 'selecting',\n                        'unselect', 'unselecting'\n                    ];\n\n                    var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];\n\n                    decorated.call(this, container, $container);\n\n                    container.on('*', function(name, params) {\n                        // Ignore events that should not be relayed\n                        if ($.inArray(name, relayEvents) === -1) {\n                            return;\n                        }\n\n                        // The parameters should always be an object\n                        params = params || {};\n\n                        // Generate the jQuery event for the Select2 event\n                        var evt = $.Event('select2:' + name, {\n                            params: params\n                        });\n\n                        self.$element.trigger(evt);\n\n                        // Only handle preventable events if it was one\n                        if ($.inArray(name, preventableEvents) === -1) {\n                            return;\n                        }\n\n                        params.prevented = evt.isDefaultPrevented();\n                    });\n                };\n\n                return EventRelay;\n            });\n\n            S2.define('select2/translation', [\n                'jquery',\n                'require'\n            ], function($, require) {\n                function Translation(dict) {\n                    this.dict = dict || {};\n                }\n\n                Translation.prototype.all = function() {\n                    return this.dict;\n                };\n\n                Translation.prototype.get = function(key) {\n                    return this.dict[key];\n                };\n\n                Translation.prototype.extend = function(translation) {\n                    this.dict = $.extend({}, translation.all(), this.dict);\n                };\n\n                // Static functions\n\n                Translation._cache = {};\n\n                Translation.loadPath = function(path) {\n                    if (!(path in Translation._cache)) {\n                        var translations = require(path);\n\n                        Translation._cache[path] = translations;\n                    }\n\n                    return new Translation(Translation._cache[path]);\n                };\n\n                return Translation;\n            });\n\n            S2.define('select2/diacritics', [\n\n            ], function() {\n                var diacritics = {\n                    '\\u24B6': 'A',\n                    '\\uFF21': 'A',\n                    '\\u00C0': 'A',\n                    '\\u00C1': 'A',\n                    '\\u00C2': 'A',\n                    '\\u1EA6': 'A',\n                    '\\u1EA4': 'A',\n                    '\\u1EAA': 'A',\n                    '\\u1EA8': 'A',\n                    '\\u00C3': 'A',\n                    '\\u0100': 'A',\n                    '\\u0102': 'A',\n                    '\\u1EB0': 'A',\n                    '\\u1EAE': 'A',\n                    '\\u1EB4': 'A',\n                    '\\u1EB2': 'A',\n                    '\\u0226': 'A',\n                    '\\u01E0': 'A',\n                    '\\u00C4': 'A',\n                    '\\u01DE': 'A',\n                    '\\u1EA2': 'A',\n                    '\\u00C5': 'A',\n                    '\\u01FA': 'A',\n                    '\\u01CD': 'A',\n                    '\\u0200': 'A',\n                    '\\u0202': 'A',\n                    '\\u1EA0': 'A',\n                    '\\u1EAC': 'A',\n                    '\\u1EB6': 'A',\n                    '\\u1E00': 'A',\n                    '\\u0104': 'A',\n                    '\\u023A': 'A',\n                    '\\u2C6F': 'A',\n                    '\\uA732': 'AA',\n                    '\\u00C6': 'AE',\n                    '\\u01FC': 'AE',\n                    '\\u01E2': 'AE',\n                    '\\uA734': 'AO',\n                    '\\uA736': 'AU',\n                    '\\uA738': 'AV',\n                    '\\uA73A': 'AV',\n                    '\\uA73C': 'AY',\n                    '\\u24B7': 'B',\n                    '\\uFF22': 'B',\n                    '\\u1E02': 'B',\n                    '\\u1E04': 'B',\n                    '\\u1E06': 'B',\n                    '\\u0243': 'B',\n                    '\\u0182': 'B',\n                    '\\u0181': 'B',\n                    '\\u24B8': 'C',\n                    '\\uFF23': 'C',\n                    '\\u0106': 'C',\n                    '\\u0108': 'C',\n                    '\\u010A': 'C',\n                    '\\u010C': 'C',\n                    '\\u00C7': 'C',\n                    '\\u1E08': 'C',\n                    '\\u0187': 'C',\n                    '\\u023B': 'C',\n                    '\\uA73E': 'C',\n                    '\\u24B9': 'D',\n                    '\\uFF24': 'D',\n                    '\\u1E0A': 'D',\n                    '\\u010E': 'D',\n                    '\\u1E0C': 'D',\n                    '\\u1E10': 'D',\n                    '\\u1E12': 'D',\n                    '\\u1E0E': 'D',\n                    '\\u0110': 'D',\n                    '\\u018B': 'D',\n                    '\\u018A': 'D',\n                    '\\u0189': 'D',\n                    '\\uA779': 'D',\n                    '\\u01F1': 'DZ',\n                    '\\u01C4': 'DZ',\n                    '\\u01F2': 'Dz',\n                    '\\u01C5': 'Dz',\n                    '\\u24BA': 'E',\n                    '\\uFF25': 'E',\n                    '\\u00C8': 'E',\n                    '\\u00C9': 'E',\n                    '\\u00CA': 'E',\n                    '\\u1EC0': 'E',\n                    '\\u1EBE': 'E',\n                    '\\u1EC4': 'E',\n                    '\\u1EC2': 'E',\n                    '\\u1EBC': 'E',\n                    '\\u0112': 'E',\n                    '\\u1E14': 'E',\n                    '\\u1E16': 'E',\n                    '\\u0114': 'E',\n                    '\\u0116': 'E',\n                    '\\u00CB': 'E',\n                    '\\u1EBA': 'E',\n                    '\\u011A': 'E',\n                    '\\u0204': 'E',\n                    '\\u0206': 'E',\n                    '\\u1EB8': 'E',\n                    '\\u1EC6': 'E',\n                    '\\u0228': 'E',\n                    '\\u1E1C': 'E',\n                    '\\u0118': 'E',\n                    '\\u1E18': 'E',\n                    '\\u1E1A': 'E',\n                    '\\u0190': 'E',\n                    '\\u018E': 'E',\n                    '\\u24BB': 'F',\n                    '\\uFF26': 'F',\n                    '\\u1E1E': 'F',\n                    '\\u0191': 'F',\n                    '\\uA77B': 'F',\n                    '\\u24BC': 'G',\n                    '\\uFF27': 'G',\n                    '\\u01F4': 'G',\n                    '\\u011C': 'G',\n                    '\\u1E20': 'G',\n                    '\\u011E': 'G',\n                    '\\u0120': 'G',\n                    '\\u01E6': 'G',\n                    '\\u0122': 'G',\n                    '\\u01E4': 'G',\n                    '\\u0193': 'G',\n                    '\\uA7A0': 'G',\n                    '\\uA77D': 'G',\n                    '\\uA77E': 'G',\n                    '\\u24BD': 'H',\n                    '\\uFF28': 'H',\n                    '\\u0124': 'H',\n                    '\\u1E22': 'H',\n                    '\\u1E26': 'H',\n                    '\\u021E': 'H',\n                    '\\u1E24': 'H',\n                    '\\u1E28': 'H',\n                    '\\u1E2A': 'H',\n                    '\\u0126': 'H',\n                    '\\u2C67': 'H',\n                    '\\u2C75': 'H',\n                    '\\uA78D': 'H',\n                    '\\u24BE': 'I',\n                    '\\uFF29': 'I',\n                    '\\u00CC': 'I',\n                    '\\u00CD': 'I',\n                    '\\u00CE': 'I',\n                    '\\u0128': 'I',\n                    '\\u012A': 'I',\n                    '\\u012C': 'I',\n                    '\\u0130': 'I',\n                    '\\u00CF': 'I',\n                    '\\u1E2E': 'I',\n                    '\\u1EC8': 'I',\n                    '\\u01CF': 'I',\n                    '\\u0208': 'I',\n                    '\\u020A': 'I',\n                    '\\u1ECA': 'I',\n                    '\\u012E': 'I',\n                    '\\u1E2C': 'I',\n                    '\\u0197': 'I',\n                    '\\u24BF': 'J',\n                    '\\uFF2A': 'J',\n                    '\\u0134': 'J',\n                    '\\u0248': 'J',\n                    '\\u24C0': 'K',\n                    '\\uFF2B': 'K',\n                    '\\u1E30': 'K',\n                    '\\u01E8': 'K',\n                    '\\u1E32': 'K',\n                    '\\u0136': 'K',\n                    '\\u1E34': 'K',\n                    '\\u0198': 'K',\n                    '\\u2C69': 'K',\n                    '\\uA740': 'K',\n                    '\\uA742': 'K',\n                    '\\uA744': 'K',\n                    '\\uA7A2': 'K',\n                    '\\u24C1': 'L',\n                    '\\uFF2C': 'L',\n                    '\\u013F': 'L',\n                    '\\u0139': 'L',\n                    '\\u013D': 'L',\n                    '\\u1E36': 'L',\n                    '\\u1E38': 'L',\n                    '\\u013B': 'L',\n                    '\\u1E3C': 'L',\n                    '\\u1E3A': 'L',\n                    '\\u0141': 'L',\n                    '\\u023D': 'L',\n                    '\\u2C62': 'L',\n                    '\\u2C60': 'L',\n                    '\\uA748': 'L',\n                    '\\uA746': 'L',\n                    '\\uA780': 'L',\n                    '\\u01C7': 'LJ',\n                    '\\u01C8': 'Lj',\n                    '\\u24C2': 'M',\n                    '\\uFF2D': 'M',\n                    '\\u1E3E': 'M',\n                    '\\u1E40': 'M',\n                    '\\u1E42': 'M',\n                    '\\u2C6E': 'M',\n                    '\\u019C': 'M',\n                    '\\u24C3': 'N',\n                    '\\uFF2E': 'N',\n                    '\\u01F8': 'N',\n                    '\\u0143': 'N',\n                    '\\u00D1': 'N',\n                    '\\u1E44': 'N',\n                    '\\u0147': 'N',\n                    '\\u1E46': 'N',\n                    '\\u0145': 'N',\n                    '\\u1E4A': 'N',\n                    '\\u1E48': 'N',\n                    '\\u0220': 'N',\n                    '\\u019D': 'N',\n                    '\\uA790': 'N',\n                    '\\uA7A4': 'N',\n                    '\\u01CA': 'NJ',\n                    '\\u01CB': 'Nj',\n                    '\\u24C4': 'O',\n                    '\\uFF2F': 'O',\n                    '\\u00D2': 'O',\n                    '\\u00D3': 'O',\n                    '\\u00D4': 'O',\n                    '\\u1ED2': 'O',\n                    '\\u1ED0': 'O',\n                    '\\u1ED6': 'O',\n                    '\\u1ED4': 'O',\n                    '\\u00D5': 'O',\n                    '\\u1E4C': 'O',\n                    '\\u022C': 'O',\n                    '\\u1E4E': 'O',\n                    '\\u014C': 'O',\n                    '\\u1E50': 'O',\n                    '\\u1E52': 'O',\n                    '\\u014E': 'O',\n                    '\\u022E': 'O',\n                    '\\u0230': 'O',\n                    '\\u00D6': 'O',\n                    '\\u022A': 'O',\n                    '\\u1ECE': 'O',\n                    '\\u0150': 'O',\n                    '\\u01D1': 'O',\n                    '\\u020C': 'O',\n                    '\\u020E': 'O',\n                    '\\u01A0': 'O',\n                    '\\u1EDC': 'O',\n                    '\\u1EDA': 'O',\n                    '\\u1EE0': 'O',\n                    '\\u1EDE': 'O',\n                    '\\u1EE2': 'O',\n                    '\\u1ECC': 'O',\n                    '\\u1ED8': 'O',\n                    '\\u01EA': 'O',\n                    '\\u01EC': 'O',\n                    '\\u00D8': 'O',\n                    '\\u01FE': 'O',\n                    '\\u0186': 'O',\n                    '\\u019F': 'O',\n                    '\\uA74A': 'O',\n                    '\\uA74C': 'O',\n                    '\\u01A2': 'OI',\n                    '\\uA74E': 'OO',\n                    '\\u0222': 'OU',\n                    '\\u24C5': 'P',\n                    '\\uFF30': 'P',\n                    '\\u1E54': 'P',\n                    '\\u1E56': 'P',\n                    '\\u01A4': 'P',\n                    '\\u2C63': 'P',\n                    '\\uA750': 'P',\n                    '\\uA752': 'P',\n                    '\\uA754': 'P',\n                    '\\u24C6': 'Q',\n                    '\\uFF31': 'Q',\n                    '\\uA756': 'Q',\n                    '\\uA758': 'Q',\n                    '\\u024A': 'Q',\n                    '\\u24C7': 'R',\n                    '\\uFF32': 'R',\n                    '\\u0154': 'R',\n                    '\\u1E58': 'R',\n                    '\\u0158': 'R',\n                    '\\u0210': 'R',\n                    '\\u0212': 'R',\n                    '\\u1E5A': 'R',\n                    '\\u1E5C': 'R',\n                    '\\u0156': 'R',\n                    '\\u1E5E': 'R',\n                    '\\u024C': 'R',\n                    '\\u2C64': 'R',\n                    '\\uA75A': 'R',\n                    '\\uA7A6': 'R',\n                    '\\uA782': 'R',\n                    '\\u24C8': 'S',\n                    '\\uFF33': 'S',\n                    '\\u1E9E': 'S',\n                    '\\u015A': 'S',\n                    '\\u1E64': 'S',\n                    '\\u015C': 'S',\n                    '\\u1E60': 'S',\n                    '\\u0160': 'S',\n                    '\\u1E66': 'S',\n                    '\\u1E62': 'S',\n                    '\\u1E68': 'S',\n                    '\\u0218': 'S',\n                    '\\u015E': 'S',\n                    '\\u2C7E': 'S',\n                    '\\uA7A8': 'S',\n                    '\\uA784': 'S',\n                    '\\u24C9': 'T',\n                    '\\uFF34': 'T',\n                    '\\u1E6A': 'T',\n                    '\\u0164': 'T',\n                    '\\u1E6C': 'T',\n                    '\\u021A': 'T',\n                    '\\u0162': 'T',\n                    '\\u1E70': 'T',\n                    '\\u1E6E': 'T',\n                    '\\u0166': 'T',\n                    '\\u01AC': 'T',\n                    '\\u01AE': 'T',\n                    '\\u023E': 'T',\n                    '\\uA786': 'T',\n                    '\\uA728': 'TZ',\n                    '\\u24CA': 'U',\n                    '\\uFF35': 'U',\n                    '\\u00D9': 'U',\n                    '\\u00DA': 'U',\n                    '\\u00DB': 'U',\n                    '\\u0168': 'U',\n                    '\\u1E78': 'U',\n                    '\\u016A': 'U',\n                    '\\u1E7A': 'U',\n                    '\\u016C': 'U',\n                    '\\u00DC': 'U',\n                    '\\u01DB': 'U',\n                    '\\u01D7': 'U',\n                    '\\u01D5': 'U',\n                    '\\u01D9': 'U',\n                    '\\u1EE6': 'U',\n                    '\\u016E': 'U',\n                    '\\u0170': 'U',\n                    '\\u01D3': 'U',\n                    '\\u0214': 'U',\n                    '\\u0216': 'U',\n                    '\\u01AF': 'U',\n                    '\\u1EEA': 'U',\n                    '\\u1EE8': 'U',\n                    '\\u1EEE': 'U',\n                    '\\u1EEC': 'U',\n                    '\\u1EF0': 'U',\n                    '\\u1EE4': 'U',\n                    '\\u1E72': 'U',\n                    '\\u0172': 'U',\n                    '\\u1E76': 'U',\n                    '\\u1E74': 'U',\n                    '\\u0244': 'U',\n                    '\\u24CB': 'V',\n                    '\\uFF36': 'V',\n                    '\\u1E7C': 'V',\n                    '\\u1E7E': 'V',\n                    '\\u01B2': 'V',\n                    '\\uA75E': 'V',\n                    '\\u0245': 'V',\n                    '\\uA760': 'VY',\n                    '\\u24CC': 'W',\n                    '\\uFF37': 'W',\n                    '\\u1E80': 'W',\n                    '\\u1E82': 'W',\n                    '\\u0174': 'W',\n                    '\\u1E86': 'W',\n                    '\\u1E84': 'W',\n                    '\\u1E88': 'W',\n                    '\\u2C72': 'W',\n                    '\\u24CD': 'X',\n                    '\\uFF38': 'X',\n                    '\\u1E8A': 'X',\n                    '\\u1E8C': 'X',\n                    '\\u24CE': 'Y',\n                    '\\uFF39': 'Y',\n                    '\\u1EF2': 'Y',\n                    '\\u00DD': 'Y',\n                    '\\u0176': 'Y',\n                    '\\u1EF8': 'Y',\n                    '\\u0232': 'Y',\n                    '\\u1E8E': 'Y',\n                    '\\u0178': 'Y',\n                    '\\u1EF6': 'Y',\n                    '\\u1EF4': 'Y',\n                    '\\u01B3': 'Y',\n                    '\\u024E': 'Y',\n                    '\\u1EFE': 'Y',\n                    '\\u24CF': 'Z',\n                    '\\uFF3A': 'Z',\n                    '\\u0179': 'Z',\n                    '\\u1E90': 'Z',\n                    '\\u017B': 'Z',\n                    '\\u017D': 'Z',\n                    '\\u1E92': 'Z',\n                    '\\u1E94': 'Z',\n                    '\\u01B5': 'Z',\n                    '\\u0224': 'Z',\n                    '\\u2C7F': 'Z',\n                    '\\u2C6B': 'Z',\n                    '\\uA762': 'Z',\n                    '\\u24D0': 'a',\n                    '\\uFF41': 'a',\n                    '\\u1E9A': 'a',\n                    '\\u00E0': 'a',\n                    '\\u00E1': 'a',\n                    '\\u00E2': 'a',\n                    '\\u1EA7': 'a',\n                    '\\u1EA5': 'a',\n                    '\\u1EAB': 'a',\n                    '\\u1EA9': 'a',\n                    '\\u00E3': 'a',\n                    '\\u0101': 'a',\n                    '\\u0103': 'a',\n                    '\\u1EB1': 'a',\n                    '\\u1EAF': 'a',\n                    '\\u1EB5': 'a',\n                    '\\u1EB3': 'a',\n                    '\\u0227': 'a',\n                    '\\u01E1': 'a',\n                    '\\u00E4': 'a',\n                    '\\u01DF': 'a',\n                    '\\u1EA3': 'a',\n                    '\\u00E5': 'a',\n                    '\\u01FB': 'a',\n                    '\\u01CE': 'a',\n                    '\\u0201': 'a',\n                    '\\u0203': 'a',\n                    '\\u1EA1': 'a',\n                    '\\u1EAD': 'a',\n                    '\\u1EB7': 'a',\n                    '\\u1E01': 'a',\n                    '\\u0105': 'a',\n                    '\\u2C65': 'a',\n                    '\\u0250': 'a',\n                    '\\uA733': 'aa',\n                    '\\u00E6': 'ae',\n                    '\\u01FD': 'ae',\n                    '\\u01E3': 'ae',\n                    '\\uA735': 'ao',\n                    '\\uA737': 'au',\n                    '\\uA739': 'av',\n                    '\\uA73B': 'av',\n                    '\\uA73D': 'ay',\n                    '\\u24D1': 'b',\n                    '\\uFF42': 'b',\n                    '\\u1E03': 'b',\n                    '\\u1E05': 'b',\n                    '\\u1E07': 'b',\n                    '\\u0180': 'b',\n                    '\\u0183': 'b',\n                    '\\u0253': 'b',\n                    '\\u24D2': 'c',\n                    '\\uFF43': 'c',\n                    '\\u0107': 'c',\n                    '\\u0109': 'c',\n                    '\\u010B': 'c',\n                    '\\u010D': 'c',\n                    '\\u00E7': 'c',\n                    '\\u1E09': 'c',\n                    '\\u0188': 'c',\n                    '\\u023C': 'c',\n                    '\\uA73F': 'c',\n                    '\\u2184': 'c',\n                    '\\u24D3': 'd',\n                    '\\uFF44': 'd',\n                    '\\u1E0B': 'd',\n                    '\\u010F': 'd',\n                    '\\u1E0D': 'd',\n                    '\\u1E11': 'd',\n                    '\\u1E13': 'd',\n                    '\\u1E0F': 'd',\n                    '\\u0111': 'd',\n                    '\\u018C': 'd',\n                    '\\u0256': 'd',\n                    '\\u0257': 'd',\n                    '\\uA77A': 'd',\n                    '\\u01F3': 'dz',\n                    '\\u01C6': 'dz',\n                    '\\u24D4': 'e',\n                    '\\uFF45': 'e',\n                    '\\u00E8': 'e',\n                    '\\u00E9': 'e',\n                    '\\u00EA': 'e',\n                    '\\u1EC1': 'e',\n                    '\\u1EBF': 'e',\n                    '\\u1EC5': 'e',\n                    '\\u1EC3': 'e',\n                    '\\u1EBD': 'e',\n                    '\\u0113': 'e',\n                    '\\u1E15': 'e',\n                    '\\u1E17': 'e',\n                    '\\u0115': 'e',\n                    '\\u0117': 'e',\n                    '\\u00EB': 'e',\n                    '\\u1EBB': 'e',\n                    '\\u011B': 'e',\n                    '\\u0205': 'e',\n                    '\\u0207': 'e',\n                    '\\u1EB9': 'e',\n                    '\\u1EC7': 'e',\n                    '\\u0229': 'e',\n                    '\\u1E1D': 'e',\n                    '\\u0119': 'e',\n                    '\\u1E19': 'e',\n                    '\\u1E1B': 'e',\n                    '\\u0247': 'e',\n                    '\\u025B': 'e',\n                    '\\u01DD': 'e',\n                    '\\u24D5': 'f',\n                    '\\uFF46': 'f',\n                    '\\u1E1F': 'f',\n                    '\\u0192': 'f',\n                    '\\uA77C': 'f',\n                    '\\u24D6': 'g',\n                    '\\uFF47': 'g',\n                    '\\u01F5': 'g',\n                    '\\u011D': 'g',\n                    '\\u1E21': 'g',\n                    '\\u011F': 'g',\n                    '\\u0121': 'g',\n                    '\\u01E7': 'g',\n                    '\\u0123': 'g',\n                    '\\u01E5': 'g',\n                    '\\u0260': 'g',\n                    '\\uA7A1': 'g',\n                    '\\u1D79': 'g',\n                    '\\uA77F': 'g',\n                    '\\u24D7': 'h',\n                    '\\uFF48': 'h',\n                    '\\u0125': 'h',\n                    '\\u1E23': 'h',\n                    '\\u1E27': 'h',\n                    '\\u021F': 'h',\n                    '\\u1E25': 'h',\n                    '\\u1E29': 'h',\n                    '\\u1E2B': 'h',\n                    '\\u1E96': 'h',\n                    '\\u0127': 'h',\n                    '\\u2C68': 'h',\n                    '\\u2C76': 'h',\n                    '\\u0265': 'h',\n                    '\\u0195': 'hv',\n                    '\\u24D8': 'i',\n                    '\\uFF49': 'i',\n                    '\\u00EC': 'i',\n                    '\\u00ED': 'i',\n                    '\\u00EE': 'i',\n                    '\\u0129': 'i',\n                    '\\u012B': 'i',\n                    '\\u012D': 'i',\n                    '\\u00EF': 'i',\n                    '\\u1E2F': 'i',\n                    '\\u1EC9': 'i',\n                    '\\u01D0': 'i',\n                    '\\u0209': 'i',\n                    '\\u020B': 'i',\n                    '\\u1ECB': 'i',\n                    '\\u012F': 'i',\n                    '\\u1E2D': 'i',\n                    '\\u0268': 'i',\n                    '\\u0131': 'i',\n                    '\\u24D9': 'j',\n                    '\\uFF4A': 'j',\n                    '\\u0135': 'j',\n                    '\\u01F0': 'j',\n                    '\\u0249': 'j',\n                    '\\u24DA': 'k',\n                    '\\uFF4B': 'k',\n                    '\\u1E31': 'k',\n                    '\\u01E9': 'k',\n                    '\\u1E33': 'k',\n                    '\\u0137': 'k',\n                    '\\u1E35': 'k',\n                    '\\u0199': 'k',\n                    '\\u2C6A': 'k',\n                    '\\uA741': 'k',\n                    '\\uA743': 'k',\n                    '\\uA745': 'k',\n                    '\\uA7A3': 'k',\n                    '\\u24DB': 'l',\n                    '\\uFF4C': 'l',\n                    '\\u0140': 'l',\n                    '\\u013A': 'l',\n                    '\\u013E': 'l',\n                    '\\u1E37': 'l',\n                    '\\u1E39': 'l',\n                    '\\u013C': 'l',\n                    '\\u1E3D': 'l',\n                    '\\u1E3B': 'l',\n                    '\\u017F': 'l',\n                    '\\u0142': 'l',\n                    '\\u019A': 'l',\n                    '\\u026B': 'l',\n                    '\\u2C61': 'l',\n                    '\\uA749': 'l',\n                    '\\uA781': 'l',\n                    '\\uA747': 'l',\n                    '\\u01C9': 'lj',\n                    '\\u24DC': 'm',\n                    '\\uFF4D': 'm',\n                    '\\u1E3F': 'm',\n                    '\\u1E41': 'm',\n                    '\\u1E43': 'm',\n                    '\\u0271': 'm',\n                    '\\u026F': 'm',\n                    '\\u24DD': 'n',\n                    '\\uFF4E': 'n',\n                    '\\u01F9': 'n',\n                    '\\u0144': 'n',\n                    '\\u00F1': 'n',\n                    '\\u1E45': 'n',\n                    '\\u0148': 'n',\n                    '\\u1E47': 'n',\n                    '\\u0146': 'n',\n                    '\\u1E4B': 'n',\n                    '\\u1E49': 'n',\n                    '\\u019E': 'n',\n                    '\\u0272': 'n',\n                    '\\u0149': 'n',\n                    '\\uA791': 'n',\n                    '\\uA7A5': 'n',\n                    '\\u01CC': 'nj',\n                    '\\u24DE': 'o',\n                    '\\uFF4F': 'o',\n                    '\\u00F2': 'o',\n                    '\\u00F3': 'o',\n                    '\\u00F4': 'o',\n                    '\\u1ED3': 'o',\n                    '\\u1ED1': 'o',\n                    '\\u1ED7': 'o',\n                    '\\u1ED5': 'o',\n                    '\\u00F5': 'o',\n                    '\\u1E4D': 'o',\n                    '\\u022D': 'o',\n                    '\\u1E4F': 'o',\n                    '\\u014D': 'o',\n                    '\\u1E51': 'o',\n                    '\\u1E53': 'o',\n                    '\\u014F': 'o',\n                    '\\u022F': 'o',\n                    '\\u0231': 'o',\n                    '\\u00F6': 'o',\n                    '\\u022B': 'o',\n                    '\\u1ECF': 'o',\n                    '\\u0151': 'o',\n                    '\\u01D2': 'o',\n                    '\\u020D': 'o',\n                    '\\u020F': 'o',\n                    '\\u01A1': 'o',\n                    '\\u1EDD': 'o',\n                    '\\u1EDB': 'o',\n                    '\\u1EE1': 'o',\n                    '\\u1EDF': 'o',\n                    '\\u1EE3': 'o',\n                    '\\u1ECD': 'o',\n                    '\\u1ED9': 'o',\n                    '\\u01EB': 'o',\n                    '\\u01ED': 'o',\n                    '\\u00F8': 'o',\n                    '\\u01FF': 'o',\n                    '\\u0254': 'o',\n                    '\\uA74B': 'o',\n                    '\\uA74D': 'o',\n                    '\\u0275': 'o',\n                    '\\u01A3': 'oi',\n                    '\\u0223': 'ou',\n                    '\\uA74F': 'oo',\n                    '\\u24DF': 'p',\n                    '\\uFF50': 'p',\n                    '\\u1E55': 'p',\n                    '\\u1E57': 'p',\n                    '\\u01A5': 'p',\n                    '\\u1D7D': 'p',\n                    '\\uA751': 'p',\n                    '\\uA753': 'p',\n                    '\\uA755': 'p',\n                    '\\u24E0': 'q',\n                    '\\uFF51': 'q',\n                    '\\u024B': 'q',\n                    '\\uA757': 'q',\n                    '\\uA759': 'q',\n                    '\\u24E1': 'r',\n                    '\\uFF52': 'r',\n                    '\\u0155': 'r',\n                    '\\u1E59': 'r',\n                    '\\u0159': 'r',\n                    '\\u0211': 'r',\n                    '\\u0213': 'r',\n                    '\\u1E5B': 'r',\n                    '\\u1E5D': 'r',\n                    '\\u0157': 'r',\n                    '\\u1E5F': 'r',\n                    '\\u024D': 'r',\n                    '\\u027D': 'r',\n                    '\\uA75B': 'r',\n                    '\\uA7A7': 'r',\n                    '\\uA783': 'r',\n                    '\\u24E2': 's',\n                    '\\uFF53': 's',\n                    '\\u00DF': 's',\n                    '\\u015B': 's',\n                    '\\u1E65': 's',\n                    '\\u015D': 's',\n                    '\\u1E61': 's',\n                    '\\u0161': 's',\n                    '\\u1E67': 's',\n                    '\\u1E63': 's',\n                    '\\u1E69': 's',\n                    '\\u0219': 's',\n                    '\\u015F': 's',\n                    '\\u023F': 's',\n                    '\\uA7A9': 's',\n                    '\\uA785': 's',\n                    '\\u1E9B': 's',\n                    '\\u24E3': 't',\n                    '\\uFF54': 't',\n                    '\\u1E6B': 't',\n                    '\\u1E97': 't',\n                    '\\u0165': 't',\n                    '\\u1E6D': 't',\n                    '\\u021B': 't',\n                    '\\u0163': 't',\n                    '\\u1E71': 't',\n                    '\\u1E6F': 't',\n                    '\\u0167': 't',\n                    '\\u01AD': 't',\n                    '\\u0288': 't',\n                    '\\u2C66': 't',\n                    '\\uA787': 't',\n                    '\\uA729': 'tz',\n                    '\\u24E4': 'u',\n                    '\\uFF55': 'u',\n                    '\\u00F9': 'u',\n                    '\\u00FA': 'u',\n                    '\\u00FB': 'u',\n                    '\\u0169': 'u',\n                    '\\u1E79': 'u',\n                    '\\u016B': 'u',\n                    '\\u1E7B': 'u',\n                    '\\u016D': 'u',\n                    '\\u00FC': 'u',\n                    '\\u01DC': 'u',\n                    '\\u01D8': 'u',\n                    '\\u01D6': 'u',\n                    '\\u01DA': 'u',\n                    '\\u1EE7': 'u',\n                    '\\u016F': 'u',\n                    '\\u0171': 'u',\n                    '\\u01D4': 'u',\n                    '\\u0215': 'u',\n                    '\\u0217': 'u',\n                    '\\u01B0': 'u',\n                    '\\u1EEB': 'u',\n                    '\\u1EE9': 'u',\n                    '\\u1EEF': 'u',\n                    '\\u1EED': 'u',\n                    '\\u1EF1': 'u',\n                    '\\u1EE5': 'u',\n                    '\\u1E73': 'u',\n                    '\\u0173': 'u',\n                    '\\u1E77': 'u',\n                    '\\u1E75': 'u',\n                    '\\u0289': 'u',\n                    '\\u24E5': 'v',\n                    '\\uFF56': 'v',\n                    '\\u1E7D': 'v',\n                    '\\u1E7F': 'v',\n                    '\\u028B': 'v',\n                    '\\uA75F': 'v',\n                    '\\u028C': 'v',\n                    '\\uA761': 'vy',\n                    '\\u24E6': 'w',\n                    '\\uFF57': 'w',\n                    '\\u1E81': 'w',\n                    '\\u1E83': 'w',\n                    '\\u0175': 'w',\n                    '\\u1E87': 'w',\n                    '\\u1E85': 'w',\n                    '\\u1E98': 'w',\n                    '\\u1E89': 'w',\n                    '\\u2C73': 'w',\n                    '\\u24E7': 'x',\n                    '\\uFF58': 'x',\n                    '\\u1E8B': 'x',\n                    '\\u1E8D': 'x',\n                    '\\u24E8': 'y',\n                    '\\uFF59': 'y',\n                    '\\u1EF3': 'y',\n                    '\\u00FD': 'y',\n                    '\\u0177': 'y',\n                    '\\u1EF9': 'y',\n                    '\\u0233': 'y',\n                    '\\u1E8F': 'y',\n                    '\\u00FF': 'y',\n                    '\\u1EF7': 'y',\n                    '\\u1E99': 'y',\n                    '\\u1EF5': 'y',\n                    '\\u01B4': 'y',\n                    '\\u024F': 'y',\n                    '\\u1EFF': 'y',\n                    '\\u24E9': 'z',\n                    '\\uFF5A': 'z',\n                    '\\u017A': 'z',\n                    '\\u1E91': 'z',\n                    '\\u017C': 'z',\n                    '\\u017E': 'z',\n                    '\\u1E93': 'z',\n                    '\\u1E95': 'z',\n                    '\\u01B6': 'z',\n                    '\\u0225': 'z',\n                    '\\u0240': 'z',\n                    '\\u2C6C': 'z',\n                    '\\uA763': 'z',\n                    '\\u0386': '\\u0391',\n                    '\\u0388': '\\u0395',\n                    '\\u0389': '\\u0397',\n                    '\\u038A': '\\u0399',\n                    '\\u03AA': '\\u0399',\n                    '\\u038C': '\\u039F',\n                    '\\u038E': '\\u03A5',\n                    '\\u03AB': '\\u03A5',\n                    '\\u038F': '\\u03A9',\n                    '\\u03AC': '\\u03B1',\n                    '\\u03AD': '\\u03B5',\n                    '\\u03AE': '\\u03B7',\n                    '\\u03AF': '\\u03B9',\n                    '\\u03CA': '\\u03B9',\n                    '\\u0390': '\\u03B9',\n                    '\\u03CC': '\\u03BF',\n                    '\\u03CD': '\\u03C5',\n                    '\\u03CB': '\\u03C5',\n                    '\\u03B0': '\\u03C5',\n                    '\\u03C9': '\\u03C9',\n                    '\\u03C2': '\\u03C3'\n                };\n\n                return diacritics;\n            });\n\n            S2.define('select2/data/base', [\n                '../utils'\n            ], function(Utils) {\n                function BaseAdapter($element, options) {\n                    BaseAdapter.__super__.constructor.call(this);\n                }\n\n                Utils.Extend(BaseAdapter, Utils.Observable);\n\n                BaseAdapter.prototype.current = function(callback) {\n                    throw new Error('The `current` method must be defined in child classes.');\n                };\n\n                BaseAdapter.prototype.query = function(params, callback) {\n                    throw new Error('The `query` method must be defined in child classes.');\n                };\n\n                BaseAdapter.prototype.bind = function(container, $container) {\n                    // Can be implemented in subclasses\n                };\n\n                BaseAdapter.prototype.destroy = function() {\n                    // Can be implemented in subclasses\n                };\n\n                BaseAdapter.prototype.generateResultId = function(container, data) {\n                    var id = container.id + '-result-';\n\n                    id += Utils.generateChars(4);\n\n                    if (data.id != null) {\n                        id += '-' + data.id.toString();\n                    } else {\n                        id += '-' + Utils.generateChars(4);\n                    }\n                    return id;\n                };\n\n                return BaseAdapter;\n            });\n\n            S2.define('select2/data/select', [\n                './base',\n                '../utils',\n                'jquery'\n            ], function(BaseAdapter, Utils, $) {\n                function SelectAdapter($element, options) {\n                    this.$element = $element;\n                    this.options = options;\n\n                    SelectAdapter.__super__.constructor.call(this);\n                }\n\n                Utils.Extend(SelectAdapter, BaseAdapter);\n\n                SelectAdapter.prototype.current = function(callback) {\n                    var data = [];\n                    var self = this;\n\n                    this.$element.find(':selected').each(function() {\n                        var $option = $(this);\n\n                        var option = self.item($option);\n\n                        data.push(option);\n                    });\n\n                    callback(data);\n                };\n\n                SelectAdapter.prototype.select = function(data) {\n                    var self = this;\n\n                    data.selected = true;\n\n                    // If data.element is a DOM node, use it instead\n                    if ($(data.element).is('option')) {\n                        data.element.selected = true;\n\n                        this.$element.trigger('change');\n\n                        return;\n                    }\n\n                    if (this.$element.prop('multiple')) {\n                        this.current(function(currentData) {\n                            var val = [];\n\n                            data = [data];\n                            data.push.apply(data, currentData);\n\n                            for (var d = 0; d < data.length; d++) {\n                                var id = data[d].id;\n\n                                if ($.inArray(id, val) === -1) {\n                                    val.push(id);\n                                }\n                            }\n\n                            self.$element.val(val);\n                            self.$element.trigger('change');\n                        });\n                    } else {\n                        var val = data.id;\n\n                        this.$element.val(val);\n                        this.$element.trigger('change');\n                    }\n                };\n\n                SelectAdapter.prototype.unselect = function(data) {\n                    var self = this;\n\n                    if (!this.$element.prop('multiple')) {\n                        return;\n                    }\n\n                    data.selected = false;\n\n                    if ($(data.element).is('option')) {\n                        data.element.selected = false;\n\n                        this.$element.trigger('change');\n\n                        return;\n                    }\n\n                    this.current(function(currentData) {\n                        var val = [];\n\n                        for (var d = 0; d < currentData.length; d++) {\n                            var id = currentData[d].id;\n\n                            if (id !== data.id && $.inArray(id, val) === -1) {\n                                val.push(id);\n                            }\n                        }\n\n                        self.$element.val(val);\n\n                        self.$element.trigger('change');\n                    });\n                };\n\n                SelectAdapter.prototype.bind = function(container, $container) {\n                    var self = this;\n\n                    this.container = container;\n\n                    container.on('select', function(params) {\n                        self.select(params.data);\n                    });\n\n                    container.on('unselect', function(params) {\n                        self.unselect(params.data);\n                    });\n                };\n\n                SelectAdapter.prototype.destroy = function() {\n                    // Remove anything added to child elements\n                    this.$element.find('*').each(function() {\n                        // Remove any custom data set by Select2\n                        $.removeData(this, 'data');\n                    });\n                };\n\n                SelectAdapter.prototype.query = function(params, callback) {\n                    var data = [];\n                    var self = this;\n\n                    var $options = this.$element.children();\n\n                    $options.each(function() {\n                        var $option = $(this);\n\n                        if (!$option.is('option') && !$option.is('optgroup')) {\n                            return;\n                        }\n\n                        var option = self.item($option);\n\n                        var matches = self.matches(params, option);\n\n                        if (matches !== null) {\n                            data.push(matches);\n                        }\n                    });\n\n                    callback({\n                        results: data\n                    });\n                };\n\n                SelectAdapter.prototype.addOptions = function($options) {\n                    Utils.appendMany(this.$element, $options);\n                };\n\n                SelectAdapter.prototype.option = function(data) {\n                    var option;\n\n                    if (data.children) {\n                        option = document.createElement('optgroup');\n                        option.label = data.text;\n                    } else {\n                        option = document.createElement('option');\n\n                        if (option.textContent !== undefined) {\n                            option.textContent = data.text;\n                        } else {\n                            option.innerText = data.text;\n                        }\n                    }\n\n                    if (data.id) {\n                        option.value = data.id;\n                    }\n\n                    if (data.disabled) {\n                        option.disabled = true;\n                    }\n\n                    if (data.selected) {\n                        option.selected = true;\n                    }\n\n                    if (data.title) {\n                        option.title = data.title;\n                    }\n\n                    var $option = $(option);\n\n                    var normalizedData = this._normalizeItem(data);\n                    normalizedData.element = option;\n\n                    // Override the option's data with the combined data\n                    $.data(option, 'data', normalizedData);\n\n                    return $option;\n                };\n\n                SelectAdapter.prototype.item = function($option) {\n                    var data = {};\n\n                    data = $.data($option[0], 'data');\n\n                    if (data != null) {\n                        return data;\n                    }\n\n                    if ($option.is('option')) {\n                        data = {\n                            id: $option.val(),\n                            text: $option.text(),\n                            disabled: $option.prop('disabled'),\n                            selected: $option.prop('selected'),\n                            title: $option.prop('title')\n                        };\n                    } else if ($option.is('optgroup')) {\n                        data = {\n                            text: $option.prop('label'),\n                            children: [],\n                            title: $option.prop('title')\n                        };\n\n                        var $children = $option.children('option');\n                        var children = [];\n\n                        for (var c = 0; c < $children.length; c++) {\n                            var $child = $($children[c]);\n\n                            var child = this.item($child);\n\n                            children.push(child);\n                        }\n\n                        data.children = children;\n                    }\n\n                    data = this._normalizeItem(data);\n                    data.element = $option[0];\n\n                    $.data($option[0], 'data', data);\n\n                    return data;\n                };\n\n                SelectAdapter.prototype._normalizeItem = function(item) {\n                    if (!$.isPlainObject(item)) {\n                        item = {\n                            id: item,\n                            text: item\n                        };\n                    }\n\n                    item = $.extend({}, {\n                        text: ''\n                    }, item);\n\n                    var defaults = {\n                        selected: false,\n                        disabled: false\n                    };\n\n                    if (item.id != null) {\n                        item.id = item.id.toString();\n                    }\n\n                    if (item.text != null) {\n                        item.text = item.text.toString();\n                    }\n\n                    if (item._resultId == null && item.id && this.container != null) {\n                        item._resultId = this.generateResultId(this.container, item);\n                    }\n\n                    return $.extend({}, defaults, item);\n                };\n\n                SelectAdapter.prototype.matches = function(params, data) {\n                    var matcher = this.options.get('matcher');\n\n                    return matcher(params, data);\n                };\n\n                return SelectAdapter;\n            });\n\n            S2.define('select2/data/array', [\n                './select',\n                '../utils',\n                'jquery'\n            ], function(SelectAdapter, Utils, $) {\n                function ArrayAdapter($element, options) {\n                    var data = options.get('data') || [];\n\n                    ArrayAdapter.__super__.constructor.call(this, $element, options);\n\n                    this.addOptions(this.convertToOptions(data));\n                }\n\n                Utils.Extend(ArrayAdapter, SelectAdapter);\n\n                ArrayAdapter.prototype.select = function(data) {\n                    var $option = this.$element.find('option').filter(function(i, elm) {\n                        return elm.value == data.id.toString();\n                    });\n\n                    if ($option.length === 0) {\n                        $option = this.option(data);\n\n                        this.addOptions($option);\n                    }\n\n                    ArrayAdapter.__super__.select.call(this, data);\n                };\n\n                ArrayAdapter.prototype.convertToOptions = function(data) {\n                    var self = this;\n\n                    var $existing = this.$element.find('option');\n                    var existingIds = $existing.map(function() {\n                        return self.item($(this)).id;\n                    }).get();\n\n                    var $options = [];\n\n                    // Filter out all items except for the one passed in the argument\n                    function onlyItem(item) {\n                        return function() {\n                            return $(this).val() == item.id;\n                        };\n                    }\n\n                    for (var d = 0; d < data.length; d++) {\n                        var item = this._normalizeItem(data[d]);\n\n                        // Skip items which were pre-loaded, only merge the data\n                        if ($.inArray(item.id, existingIds) >= 0) {\n                            var $existingOption = $existing.filter(onlyItem(item));\n\n                            var existingData = this.item($existingOption);\n                            var newData = $.extend(true, {}, existingData, item);\n\n                            var $newOption = this.option(newData);\n\n                            $existingOption.replaceWith($newOption);\n\n                            continue;\n                        }\n\n                        var $option = this.option(item);\n\n                        if (item.children) {\n                            var $children = this.convertToOptions(item.children);\n\n                            Utils.appendMany($option, $children);\n                        }\n\n                        $options.push($option);\n                    }\n\n                    return $options;\n                };\n\n                return ArrayAdapter;\n            });\n\n            S2.define('select2/data/ajax', [\n                './array',\n                '../utils',\n                'jquery'\n            ], function(ArrayAdapter, Utils, $) {\n                function AjaxAdapter($element, options) {\n                    this.ajaxOptions = this._applyDefaults(options.get('ajax'));\n\n                    if (this.ajaxOptions.processResults != null) {\n                        this.processResults = this.ajaxOptions.processResults;\n                    }\n\n                    AjaxAdapter.__super__.constructor.call(this, $element, options);\n                }\n\n                Utils.Extend(AjaxAdapter, ArrayAdapter);\n\n                AjaxAdapter.prototype._applyDefaults = function(options) {\n                    var defaults = {\n                        data: function(params) {\n                            return $.extend({}, params, {\n                                q: params.term\n                            });\n                        },\n                        transport: function(params, success, failure) {\n                            var $request = $.ajax(params);\n\n                            $request.then(success);\n                            $request.fail(failure);\n\n                            return $request;\n                        }\n                    };\n\n                    return $.extend({}, defaults, options, true);\n                };\n\n                AjaxAdapter.prototype.processResults = function(results) {\n                    return results;\n                };\n\n                AjaxAdapter.prototype.query = function(params, callback) {\n                    var matches = [];\n                    var self = this;\n\n                    if (this._request != null) {\n                        // JSONP requests cannot always be aborted\n                        if ($.isFunction(this._request.abort)) {\n                            this._request.abort();\n                        }\n\n                        this._request = null;\n                    }\n\n                    var options = $.extend({\n                        type: 'GET'\n                    }, this.ajaxOptions);\n\n                    if (typeof options.url === 'function') {\n                        options.url = options.url.call(this.$element, params);\n                    }\n\n                    if (typeof options.data === 'function') {\n                        options.data = options.data.call(this.$element, params);\n                    }\n\n                    function request() {\n                        var $request = options.transport(options, function(data) {\n                            var results = self.processResults(data, params);\n\n                            if (self.options.get('debug') && window.console && console.error) {\n                                // Check to make sure that the response included a `results` key.\n                                if (!results || !results.results || !$.isArray(results.results)) {\n                                    console.error(\n                                        'Select2: The AJAX results did not return an array in the ' +\n                                        '`results` key of the response.'\n                                    );\n                                }\n                            }\n\n                            callback(results);\n                        }, function() {\n                            // TODO: Handle AJAX errors\n                        });\n\n                        self._request = $request;\n                    }\n\n                    if (this.ajaxOptions.delay && params.term !== '') {\n                        if (this._queryTimeout) {\n                            window.clearTimeout(this._queryTimeout);\n                        }\n\n                        this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);\n                    } else {\n                        request();\n                    }\n                };\n\n                return AjaxAdapter;\n            });\n\n            S2.define('select2/data/tags', [\n                'jquery'\n            ], function($) {\n                function Tags(decorated, $element, options) {\n                    var tags = options.get('tags');\n\n                    var createTag = options.get('createTag');\n\n                    if (createTag !== undefined) {\n                        this.createTag = createTag;\n                    }\n\n                    decorated.call(this, $element, options);\n\n                    if ($.isArray(tags)) {\n                        for (var t = 0; t < tags.length; t++) {\n                            var tag = tags[t];\n                            var item = this._normalizeItem(tag);\n\n                            var $option = this.option(item);\n\n                            this.$element.append($option);\n                        }\n                    }\n                }\n\n                Tags.prototype.query = function(decorated, params, callback) {\n                    var self = this;\n\n                    this._removeOldTags();\n\n                    if (params.term == null || params.page != null) {\n                        decorated.call(this, params, callback);\n                        return;\n                    }\n\n                    function wrapper(obj, child) {\n                        var data = obj.results;\n\n                        for (var i = 0; i < data.length; i++) {\n                            var option = data[i];\n\n                            var checkChildren = (\n                                option.children != null &&\n                                !wrapper({\n                                    results: option.children\n                                }, true)\n                            );\n\n                            var checkText = option.text === params.term;\n\n                            if (checkText || checkChildren) {\n                                if (child) {\n                                    return false;\n                                }\n\n                                obj.data = data;\n                                callback(obj);\n\n                                return;\n                            }\n                        }\n\n                        if (child) {\n                            return true;\n                        }\n\n                        var tag = self.createTag(params);\n\n                        if (tag != null) {\n                            var $option = self.option(tag);\n                            $option.attr('data-select2-tag', true);\n\n                            self.addOptions([$option]);\n\n                            self.insertTag(data, tag);\n                        }\n\n                        obj.results = data;\n\n                        callback(obj);\n                    }\n\n                    decorated.call(this, params, wrapper);\n                };\n\n                Tags.prototype.createTag = function(decorated, params) {\n                    var term = $.trim(params.term);\n\n                    if (term === '') {\n                        return null;\n                    }\n\n                    return {\n                        id: term,\n                        text: term\n                    };\n                };\n\n                Tags.prototype.insertTag = function(_, data, tag) {\n                    data.unshift(tag);\n                };\n\n                Tags.prototype._removeOldTags = function(_) {\n                    var tag = this._lastTag;\n\n                    var $options = this.$element.find('option[data-select2-tag]');\n\n                    $options.each(function() {\n                        if (this.selected) {\n                            return;\n                        }\n\n                        $(this).remove();\n                    });\n                };\n\n                return Tags;\n            });\n\n            S2.define('select2/data/tokenizer', [\n                'jquery'\n            ], function($) {\n                function Tokenizer(decorated, $element, options) {\n                    var tokenizer = options.get('tokenizer');\n\n                    if (tokenizer !== undefined) {\n                        this.tokenizer = tokenizer;\n                    }\n\n                    decorated.call(this, $element, options);\n                }\n\n                Tokenizer.prototype.bind = function(decorated, container, $container) {\n                    decorated.call(this, container, $container);\n\n                    this.$search = container.dropdown.$search || container.selection.$search ||\n                        $container.find('.select2-search__field');\n                };\n\n                Tokenizer.prototype.query = function(decorated, params, callback) {\n                    var self = this;\n\n                    function select(data) {\n                        self.trigger('select', {\n                            data: data\n                        });\n                    }\n\n                    params.term = params.term || '';\n\n                    var tokenData = this.tokenizer(params, this.options, select);\n\n                    if (tokenData.term !== params.term) {\n                        // Replace the search term if we have the search box\n                        if (this.$search.length) {\n                            this.$search.val(tokenData.term);\n                            this.$search.focus();\n                        }\n\n                        params.term = tokenData.term;\n                    }\n\n                    decorated.call(this, params, callback);\n                };\n\n                Tokenizer.prototype.tokenizer = function(_, params, options, callback) {\n                    var separators = options.get('tokenSeparators') || [];\n                    var term = params.term;\n                    var i = 0;\n\n                    var createTag = this.createTag || function(params) {\n                        return {\n                            id: params.term,\n                            text: params.term\n                        };\n                    };\n\n                    while (i < term.length) {\n                        var termChar = term[i];\n\n                        if ($.inArray(termChar, separators) === -1) {\n                            i++;\n\n                            continue;\n                        }\n\n                        var part = term.substr(0, i);\n                        var partParams = $.extend({}, params, {\n                            term: part\n                        });\n\n                        var data = createTag(partParams);\n\n                        if (data == null) {\n                            i++;\n                            continue;\n                        }\n\n                        callback(data);\n\n                        // Reset the term to not include the tokenized portion\n                        term = term.substr(i + 1) || '';\n                        i = 0;\n                    }\n\n                    return {\n                        term: term\n                    };\n                };\n\n                return Tokenizer;\n            });\n\n            S2.define('select2/data/minimumInputLength', [\n\n            ], function() {\n                function MinimumInputLength(decorated, $e, options) {\n                    this.minimumInputLength = options.get('minimumInputLength');\n\n                    decorated.call(this, $e, options);\n                }\n\n                MinimumInputLength.prototype.query = function(decorated, params, callback) {\n                    params.term = params.term || '';\n\n                    if (params.term.length < this.minimumInputLength) {\n                        this.trigger('results:message', {\n                            message: 'inputTooShort',\n                            args: {\n                                minimum: this.minimumInputLength,\n                                input: params.term,\n                                params: params\n                            }\n                        });\n\n                        return;\n                    }\n\n                    decorated.call(this, params, callback);\n                };\n\n                return MinimumInputLength;\n            });\n\n            S2.define('select2/data/maximumInputLength', [\n\n            ], function() {\n                function MaximumInputLength(decorated, $e, options) {\n                    this.maximumInputLength = options.get('maximumInputLength');\n\n                    decorated.call(this, $e, options);\n                }\n\n                MaximumInputLength.prototype.query = function(decorated, params, callback) {\n                    params.term = params.term || '';\n\n                    if (this.maximumInputLength > 0 &&\n                        params.term.length > this.maximumInputLength) {\n                        this.trigger('results:message', {\n                            message: 'inputTooLong',\n                            args: {\n                                maximum: this.maximumInputLength,\n                                input: params.term,\n                                params: params\n                            }\n                        });\n\n                        return;\n                    }\n\n                    decorated.call(this, params, callback);\n                };\n\n                return MaximumInputLength;\n            });\n\n            S2.define('select2/data/maximumSelectionLength', [\n\n            ], function() {\n                function MaximumSelectionLength(decorated, $e, options) {\n                    this.maximumSelectionLength = options.get('maximumSelectionLength');\n\n                    decorated.call(this, $e, options);\n                }\n\n                MaximumSelectionLength.prototype.query =\n                    function(decorated, params, callback) {\n                        var self = this;\n\n                        this.current(function(currentData) {\n                            var count = currentData != null ? currentData.length : 0;\n                            if (self.maximumSelectionLength > 0 &&\n                                count >= self.maximumSelectionLength) {\n                                self.trigger('results:message', {\n                                    message: 'maximumSelected',\n                                    args: {\n                                        maximum: self.maximumSelectionLength\n                                    }\n                                });\n                                return;\n                            }\n                            decorated.call(self, params, callback);\n                        });\n                    };\n\n                return MaximumSelectionLength;\n            });\n\n            S2.define('select2/dropdown', [\n                'jquery',\n                './utils'\n            ], function($, Utils) {\n                function Dropdown($element, options) {\n                    this.$element = $element;\n                    this.options = options;\n\n                    Dropdown.__super__.constructor.call(this);\n                }\n\n                Utils.Extend(Dropdown, Utils.Observable);\n\n                Dropdown.prototype.render = function() {\n                    var $dropdown = $(\n                        '<span class=\"select2-dropdown\">' +\n                        '<span class=\"select2-results\"></span>' +\n                        '</span>'\n                    );\n\n                    $dropdown.attr('dir', this.options.get('dir'));\n\n                    this.$dropdown = $dropdown;\n\n                    return $dropdown;\n                };\n\n                Dropdown.prototype.bind = function() {\n                    // Should be implemented in subclasses\n                };\n\n                Dropdown.prototype.position = function($dropdown, $container) {\n                    // Should be implmented in subclasses\n                };\n\n                Dropdown.prototype.destroy = function() {\n                    // Remove the dropdown from the DOM\n                    this.$dropdown.remove();\n                };\n\n                return Dropdown;\n            });\n\n            S2.define('select2/dropdown/search', [\n                'jquery',\n                '../utils'\n            ], function($, Utils) {\n                function Search() {}\n\n                Search.prototype.render = function(decorated) {\n                    var $rendered = decorated.call(this);\n\n                    var $search = $(\n                        '<span class=\"select2-search select2-search--dropdown\">' +\n                        '<input class=\"select2-search__field\" type=\"search\" tabindex=\"-1\"' +\n                        ' autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\"' +\n                        ' spellcheck=\"false\" role=\"textbox\" />' +\n                        '</span>'\n                    );\n\n                    this.$searchContainer = $search;\n                    this.$search = $search.find('input');\n\n                    $rendered.prepend($search);\n\n                    return $rendered;\n                };\n\n                Search.prototype.bind = function(decorated, container, $container) {\n                    var self = this;\n\n                    decorated.call(this, container, $container);\n\n                    this.$search.on('keydown', function(evt) {\n                        self.trigger('keypress', evt);\n\n                        self._keyUpPrevented = evt.isDefaultPrevented();\n                    });\n\n                    // Workaround for browsers which do not support the `input` event\n                    // This will prevent double-triggering of events for browsers which support\n                    // both the `keyup` and `input` events.\n                    this.$search.on('input', function(evt) {\n                        // Unbind the duplicated `keyup` event\n                        $(this).off('keyup');\n                    });\n\n                    this.$search.on('keyup input', function(evt) {\n                        self.handleSearch(evt);\n                    });\n\n                    container.on('open', function() {\n                        self.$search.attr('tabindex', 0);\n\n                        self.$search.focus();\n\n                        window.setTimeout(function() {\n                            self.$search.focus();\n                        }, 0);\n                    });\n\n                    container.on('close', function() {\n                        self.$search.attr('tabindex', -1);\n\n                        self.$search.val('');\n                    });\n\n                    container.on('results:all', function(params) {\n                        if (params.query.term == null || params.query.term === '') {\n                            var showSearch = self.showSearch(params);\n\n                            if (showSearch) {\n                                self.$searchContainer.removeClass('select2-search--hide');\n                            } else {\n                                self.$searchContainer.addClass('select2-search--hide');\n                            }\n                        }\n                    });\n                };\n\n                Search.prototype.handleSearch = function(evt) {\n                    if (!this._keyUpPrevented) {\n                        var input = this.$search.val();\n\n                        this.trigger('query', {\n                            term: input\n                        });\n                    }\n\n                    this._keyUpPrevented = false;\n                };\n\n                Search.prototype.showSearch = function(_, params) {\n                    return true;\n                };\n\n                return Search;\n            });\n\n            S2.define('select2/dropdown/hidePlaceholder', [\n\n            ], function() {\n                function HidePlaceholder(decorated, $element, options, dataAdapter) {\n                    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));\n\n                    decorated.call(this, $element, options, dataAdapter);\n                }\n\n                HidePlaceholder.prototype.append = function(decorated, data) {\n                    data.results = this.removePlaceholder(data.results);\n\n                    decorated.call(this, data);\n                };\n\n                HidePlaceholder.prototype.normalizePlaceholder = function(_, placeholder) {\n                    if (typeof placeholder === 'string') {\n                        placeholder = {\n                            id: '',\n                            text: placeholder\n                        };\n                    }\n\n                    return placeholder;\n                };\n\n                HidePlaceholder.prototype.removePlaceholder = function(_, data) {\n                    var modifiedData = data.slice(0);\n\n                    for (var d = data.length - 1; d >= 0; d--) {\n                        var item = data[d];\n\n                        if (this.placeholder.id === item.id) {\n                            modifiedData.splice(d, 1);\n                        }\n                    }\n\n                    return modifiedData;\n                };\n\n                return HidePlaceholder;\n            });\n\n            S2.define('select2/dropdown/infiniteScroll', [\n                'jquery'\n            ], function($) {\n                function InfiniteScroll(decorated, $element, options, dataAdapter) {\n                    this.lastParams = {};\n\n                    decorated.call(this, $element, options, dataAdapter);\n\n                    this.$loadingMore = this.createLoadingMore();\n                    this.loading = false;\n                }\n\n                InfiniteScroll.prototype.append = function(decorated, data) {\n                    this.$loadingMore.remove();\n                    this.loading = false;\n\n                    decorated.call(this, data);\n\n                    if (this.showLoadingMore(data)) {\n                        this.$results.append(this.$loadingMore);\n                    }\n                };\n\n                InfiniteScroll.prototype.bind = function(decorated, container, $container) {\n                    var self = this;\n\n                    decorated.call(this, container, $container);\n\n                    container.on('query', function(params) {\n                        self.lastParams = params;\n                        self.loading = true;\n                    });\n\n                    container.on('query:append', function(params) {\n                        self.lastParams = params;\n                        self.loading = true;\n                    });\n\n                    this.$results.on('scroll', function() {\n                        var isLoadMoreVisible = $.contains(\n                            document.documentElement,\n                            self.$loadingMore[0]\n                        );\n\n                        if (self.loading || !isLoadMoreVisible) {\n                            return;\n                        }\n\n                        var currentOffset = self.$results.offset().top +\n                            self.$results.outerHeight(false);\n                        var loadingMoreOffset = self.$loadingMore.offset().top +\n                            self.$loadingMore.outerHeight(false);\n\n                        if (currentOffset + 50 >= loadingMoreOffset) {\n                            self.loadMore();\n                        }\n                    });\n                };\n\n                InfiniteScroll.prototype.loadMore = function() {\n                    this.loading = true;\n\n                    var params = $.extend({}, { page: 1 }, this.lastParams);\n\n                    params.page++;\n\n                    this.trigger('query:append', params);\n                };\n\n                InfiniteScroll.prototype.showLoadingMore = function(_, data) {\n                    return data.pagination && data.pagination.more;\n                };\n\n                InfiniteScroll.prototype.createLoadingMore = function() {\n                    var $option = $(\n                        '<li ' +\n                        'class=\"select2-results__option select2-results__option--load-more\"' +\n                        'role=\"treeitem\" aria-disabled=\"true\"></li>'\n                    );\n\n                    var message = this.options.get('translations').get('loadingMore');\n\n                    $option.html(message(this.lastParams));\n\n                    return $option;\n                };\n\n                return InfiniteScroll;\n            });\n\n            S2.define('select2/dropdown/attachBody', [\n                'jquery',\n                '../utils'\n            ], function($, Utils) {\n                function AttachBody(decorated, $element, options) {\n                    this.$dropdownParent = options.get('dropdownParent') || $(document.body);\n\n                    decorated.call(this, $element, options);\n                }\n\n                AttachBody.prototype.bind = function(decorated, container, $container) {\n                    var self = this;\n\n                    var setupResultsEvents = false;\n\n                    decorated.call(this, container, $container);\n\n                    container.on('open', function() {\n                        self._showDropdown();\n                        self._attachPositioningHandler(container);\n\n                        if (!setupResultsEvents) {\n                            setupResultsEvents = true;\n\n                            container.on('results:all', function() {\n                                self._positionDropdown();\n                                self._resizeDropdown();\n                            });\n\n                            container.on('results:append', function() {\n                                self._positionDropdown();\n                                self._resizeDropdown();\n                            });\n                        }\n                    });\n\n                    container.on('close', function() {\n                        self._hideDropdown();\n                        self._detachPositioningHandler(container);\n                    });\n\n                    this.$dropdownContainer.on('mousedown', function(evt) {\n                        evt.stopPropagation();\n                    });\n                };\n\n                AttachBody.prototype.destroy = function(decorated) {\n                    decorated.call(this);\n\n                    this.$dropdownContainer.remove();\n                };\n\n                AttachBody.prototype.position = function(decorated, $dropdown, $container) {\n                    // Clone all of the container classes\n                    $dropdown.attr('class', $container.attr('class'));\n\n                    $dropdown.removeClass('select2');\n                    $dropdown.addClass('select2-container--open');\n\n                    $dropdown.css({\n                        position: 'absolute',\n                        top: -999999\n                    });\n\n                    this.$container = $container;\n                };\n\n                AttachBody.prototype.render = function(decorated) {\n                    var $container = $('<span></span>');\n\n                    var $dropdown = decorated.call(this);\n                    $container.append($dropdown);\n\n                    this.$dropdownContainer = $container;\n\n                    return $container;\n                };\n\n                AttachBody.prototype._hideDropdown = function(decorated) {\n                    this.$dropdownContainer.detach();\n                };\n\n                AttachBody.prototype._attachPositioningHandler =\n                    function(decorated, container) {\n                        var self = this;\n\n                        var scrollEvent = 'scroll.select2.' + container.id;\n                        var resizeEvent = 'resize.select2.' + container.id;\n                        var orientationEvent = 'orientationchange.select2.' + container.id;\n\n                        var $watchers = this.$container.parents().filter(Utils.hasScroll);\n                        $watchers.each(function() {\n                            $(this).data('select2-scroll-position', {\n                                x: $(this).scrollLeft(),\n                                y: $(this).scrollTop()\n                            });\n                        });\n\n                        $watchers.on(scrollEvent, function(ev) {\n                            var position = $(this).data('select2-scroll-position');\n                            $(this).scrollTop(position.y);\n                        });\n\n                        $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,\n                            function(e) {\n                                self._positionDropdown();\n                                self._resizeDropdown();\n                            });\n                    };\n\n                AttachBody.prototype._detachPositioningHandler =\n                    function(decorated, container) {\n                        var scrollEvent = 'scroll.select2.' + container.id;\n                        var resizeEvent = 'resize.select2.' + container.id;\n                        var orientationEvent = 'orientationchange.select2.' + container.id;\n\n                        var $watchers = this.$container.parents().filter(Utils.hasScroll);\n                        $watchers.off(scrollEvent);\n\n                        $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);\n                    };\n\n                AttachBody.prototype._positionDropdown = function() {\n                    var $window = $(window);\n\n                    var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');\n                    var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');\n\n                    var newDirection = null;\n\n                    var position = this.$container.position();\n                    var offset = this.$container.offset();\n\n                    offset.bottom = offset.top + this.$container.outerHeight(false);\n\n                    var container = {\n                        height: this.$container.outerHeight(false)\n                    };\n\n                    container.top = offset.top;\n                    container.bottom = offset.top + container.height;\n\n                    var dropdown = {\n                        height: this.$dropdown.outerHeight(false)\n                    };\n\n                    var viewport = {\n                        top: $window.scrollTop(),\n                        bottom: $window.scrollTop() + $window.height()\n                    };\n\n                    var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);\n                    var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);\n\n                    var css = {\n                        left: offset.left,\n                        top: container.bottom\n                    };\n\n                    // Fix positioning with static parents\n                    if (this.$dropdownParent[0].style.position !== 'static') {\n                        var parentOffset = this.$dropdownParent.offset();\n\n                        css.top -= parentOffset.top;\n                        css.left -= parentOffset.left;\n                    }\n\n                    if (!isCurrentlyAbove && !isCurrentlyBelow) {\n                        newDirection = 'below';\n                    }\n\n                    if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {\n                        newDirection = 'above';\n                    } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {\n                        newDirection = 'below';\n                    }\n\n                    if (newDirection == 'above' ||\n                        (isCurrentlyAbove && newDirection !== 'below')) {\n                        css.top = container.top - dropdown.height;\n                    }\n\n                    if (newDirection != null) {\n                        this.$dropdown\n                            .removeClass('select2-dropdown--below select2-dropdown--above')\n                            .addClass('select2-dropdown--' + newDirection);\n                        this.$container\n                            .removeClass('select2-container--below select2-container--above')\n                            .addClass('select2-container--' + newDirection);\n                    }\n\n                    this.$dropdownContainer.css(css);\n                };\n\n                AttachBody.prototype._resizeDropdown = function() {\n                    var css = {\n                        width: this.$container.outerWidth(false) + 'px'\n                    };\n\n                    if (this.options.get('dropdownAutoWidth')) {\n                        css.minWidth = css.width;\n                        css.width = 'auto';\n                    }\n\n                    this.$dropdown.css(css);\n                };\n\n                AttachBody.prototype._showDropdown = function(decorated) {\n                    this.$dropdownContainer.appendTo(this.$dropdownParent);\n\n                    this._positionDropdown();\n                    this._resizeDropdown();\n                };\n\n                return AttachBody;\n            });\n\n            S2.define('select2/dropdown/minimumResultsForSearch', [\n\n            ], function() {\n                function countResults(data) {\n                    var count = 0;\n\n                    for (var d = 0; d < data.length; d++) {\n                        var item = data[d];\n\n                        if (item.children) {\n                            count += countResults(item.children);\n                        } else {\n                            count++;\n                        }\n                    }\n\n                    return count;\n                }\n\n                function MinimumResultsForSearch(decorated, $element, options, dataAdapter) {\n                    this.minimumResultsForSearch = options.get('minimumResultsForSearch');\n\n                    if (this.minimumResultsForSearch < 0) {\n                        this.minimumResultsForSearch = Infinity;\n                    }\n\n                    decorated.call(this, $element, options, dataAdapter);\n                }\n\n                MinimumResultsForSearch.prototype.showSearch = function(decorated, params) {\n                    if (countResults(params.data.results) < this.minimumResultsForSearch) {\n                        return false;\n                    }\n\n                    return decorated.call(this, params);\n                };\n\n                return MinimumResultsForSearch;\n            });\n\n            S2.define('select2/dropdown/selectOnClose', [\n\n            ], function() {\n                function SelectOnClose() {}\n\n                SelectOnClose.prototype.bind = function(decorated, container, $container) {\n                    var self = this;\n\n                    decorated.call(this, container, $container);\n\n                    container.on('close', function() {\n                        self._handleSelectOnClose();\n                    });\n                };\n\n                SelectOnClose.prototype._handleSelectOnClose = function() {\n                    var $highlightedResults = this.getHighlightedResults();\n\n                    // Only select highlighted results\n                    if ($highlightedResults.length < 1) {\n                        return;\n                    }\n\n                    var data = $highlightedResults.data('data');\n\n                    // Don't re-select already selected resulte\n                    if (\n                        (data.element != null && data.element.selected) ||\n                        (data.element == null && data.selected)\n                    ) {\n                        return;\n                    }\n\n                    this.trigger('select', {\n                        data: data\n                    });\n                };\n\n                return SelectOnClose;\n            });\n\n            S2.define('select2/dropdown/closeOnSelect', [\n\n            ], function() {\n                function CloseOnSelect() {}\n\n                CloseOnSelect.prototype.bind = function(decorated, container, $container) {\n                    var self = this;\n\n                    decorated.call(this, container, $container);\n\n                    container.on('select', function(evt) {\n                        self._selectTriggered(evt);\n                    });\n\n                    container.on('unselect', function(evt) {\n                        self._selectTriggered(evt);\n                    });\n                };\n\n                CloseOnSelect.prototype._selectTriggered = function(_, evt) {\n                    var originalEvent = evt.originalEvent;\n\n                    // Don't close if the control key is being held\n                    if (originalEvent && originalEvent.ctrlKey) {\n                        return;\n                    }\n\n                    this.trigger('close', {});\n                };\n\n                return CloseOnSelect;\n            });\n\n            S2.define('select2/i18n/en', [], function() {\n                // English\n                return {\n                    errorLoading: function() {\n                        return 'The results could not be loaded.';\n                    },\n                    inputTooLong: function(args) {\n                        var overChars = args.input.length - args.maximum;\n\n                        var message = 'Please delete ' + overChars + ' character';\n\n                        if (overChars != 1) {\n                            message += 's';\n                        }\n\n                        return message;\n                    },\n                    inputTooShort: function(args) {\n                        var remainingChars = args.minimum - args.input.length;\n\n                        var message = 'Please enter ' + remainingChars + ' or more characters';\n\n                        return message;\n                    },\n                    loadingMore: function() {\n                        return 'Loading more results…';\n                    },\n                    maximumSelected: function(args) {\n                        var message = 'You can only select ' + args.maximum + ' item';\n\n                        if (args.maximum != 1) {\n                            message += 's';\n                        }\n\n                        return message;\n                    },\n                    noResults: function() {\n                        return 'No results found';\n                    },\n                    searching: function() {\n                        return 'Searching…';\n                    }\n                };\n            });\n\n            S2.define('select2/defaults', [\n                'jquery',\n                'require',\n\n                './results',\n\n                './selection/single',\n                './selection/multiple',\n                './selection/placeholder',\n                './selection/allowClear',\n                './selection/search',\n                './selection/eventRelay',\n\n                './utils',\n                './translation',\n                './diacritics',\n\n                './data/select',\n                './data/array',\n                './data/ajax',\n                './data/tags',\n                './data/tokenizer',\n                './data/minimumInputLength',\n                './data/maximumInputLength',\n                './data/maximumSelectionLength',\n\n                './dropdown',\n                './dropdown/search',\n                './dropdown/hidePlaceholder',\n                './dropdown/infiniteScroll',\n                './dropdown/attachBody',\n                './dropdown/minimumResultsForSearch',\n                './dropdown/selectOnClose',\n                './dropdown/closeOnSelect',\n\n                './i18n/en'\n            ], function($, require,\n\n                ResultsList,\n\n                SingleSelection, MultipleSelection, Placeholder, AllowClear,\n                SelectionSearch, EventRelay,\n\n                Utils, Translation, DIACRITICS,\n\n                SelectData, ArrayData, AjaxData, Tags, Tokenizer,\n                MinimumInputLength, MaximumInputLength, MaximumSelectionLength,\n\n                Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,\n                AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,\n\n                EnglishTranslation) {\n                function Defaults() {\n                    this.reset();\n                }\n\n                Defaults.prototype.apply = function(options) {\n                    options = $.extend({}, this.defaults, options);\n\n                    if (options.dataAdapter == null) {\n                        if (options.ajax != null) {\n                            options.dataAdapter = AjaxData;\n                        } else if (options.data != null) {\n                            options.dataAdapter = ArrayData;\n                        } else {\n                            options.dataAdapter = SelectData;\n                        }\n\n                        if (options.minimumInputLength > 0) {\n                            options.dataAdapter = Utils.Decorate(\n                                options.dataAdapter,\n                                MinimumInputLength\n                            );\n                        }\n\n                        if (options.maximumInputLength > 0) {\n                            options.dataAdapter = Utils.Decorate(\n                                options.dataAdapter,\n                                MaximumInputLength\n                            );\n                        }\n\n                        if (options.maximumSelectionLength > 0) {\n                            options.dataAdapter = Utils.Decorate(\n                                options.dataAdapter,\n                                MaximumSelectionLength\n                            );\n                        }\n\n                        if (options.tags) {\n                            options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);\n                        }\n\n                        if (options.tokenSeparators != null || options.tokenizer != null) {\n                            options.dataAdapter = Utils.Decorate(\n                                options.dataAdapter,\n                                Tokenizer\n                            );\n                        }\n\n                        if (options.query != null) {\n                            var Query = require(options.amdBase + 'compat/query');\n\n                            options.dataAdapter = Utils.Decorate(\n                                options.dataAdapter,\n                                Query\n                            );\n                        }\n\n                        if (options.initSelection != null) {\n                            var InitSelection = require(options.amdBase + 'compat/initSelection');\n\n                            options.dataAdapter = Utils.Decorate(\n                                options.dataAdapter,\n                                InitSelection\n                            );\n                        }\n                    }\n\n                    if (options.resultsAdapter == null) {\n                        options.resultsAdapter = ResultsList;\n\n                        if (options.ajax != null) {\n                            options.resultsAdapter = Utils.Decorate(\n                                options.resultsAdapter,\n                                InfiniteScroll\n                            );\n                        }\n\n                        if (options.placeholder != null) {\n                            options.resultsAdapter = Utils.Decorate(\n                                options.resultsAdapter,\n                                HidePlaceholder\n                            );\n                        }\n\n                        if (options.selectOnClose) {\n                            options.resultsAdapter = Utils.Decorate(\n                                options.resultsAdapter,\n                                SelectOnClose\n                            );\n                        }\n                    }\n\n                    if (options.dropdownAdapter == null) {\n                        if (options.multiple) {\n                            options.dropdownAdapter = Dropdown;\n                        } else {\n                            var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);\n\n                            options.dropdownAdapter = SearchableDropdown;\n                        }\n\n                        if (options.minimumResultsForSearch !== 0) {\n                            options.dropdownAdapter = Utils.Decorate(\n                                options.dropdownAdapter,\n                                MinimumResultsForSearch\n                            );\n                        }\n\n                        if (options.closeOnSelect) {\n                            options.dropdownAdapter = Utils.Decorate(\n                                options.dropdownAdapter,\n                                CloseOnSelect\n                            );\n                        }\n\n                        if (\n                            options.dropdownCssClass != null ||\n                            options.dropdownCss != null ||\n                            options.adaptDropdownCssClass != null\n                        ) {\n                            var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');\n\n                            options.dropdownAdapter = Utils.Decorate(\n                                options.dropdownAdapter,\n                                DropdownCSS\n                            );\n                        }\n\n                        options.dropdownAdapter = Utils.Decorate(\n                            options.dropdownAdapter,\n                            AttachBody\n                        );\n                    }\n\n                    if (options.selectionAdapter == null) {\n                        if (options.multiple) {\n                            options.selectionAdapter = MultipleSelection;\n                        } else {\n                            options.selectionAdapter = SingleSelection;\n                        }\n\n                        // Add the placeholder mixin if a placeholder was specified\n                        if (options.placeholder != null) {\n                            options.selectionAdapter = Utils.Decorate(\n                                options.selectionAdapter,\n                                Placeholder\n                            );\n                        }\n\n                        if (options.allowClear) {\n                            options.selectionAdapter = Utils.Decorate(\n                                options.selectionAdapter,\n                                AllowClear\n                            );\n                        }\n\n                        if (options.multiple) {\n                            options.selectionAdapter = Utils.Decorate(\n                                options.selectionAdapter,\n                                SelectionSearch\n                            );\n                        }\n\n                        if (\n                            options.containerCssClass != null ||\n                            options.containerCss != null ||\n                            options.adaptContainerCssClass != null\n                        ) {\n                            var ContainerCSS = require(options.amdBase + 'compat/containerCss');\n\n                            options.selectionAdapter = Utils.Decorate(\n                                options.selectionAdapter,\n                                ContainerCSS\n                            );\n                        }\n\n                        options.selectionAdapter = Utils.Decorate(\n                            options.selectionAdapter,\n                            EventRelay\n                        );\n                    }\n\n                    if (typeof options.language === 'string') {\n                        // Check if the language is specified with a region\n                        if (options.language.indexOf('-') > 0) {\n                            // Extract the region information if it is included\n                            var languageParts = options.language.split('-');\n                            var baseLanguage = languageParts[0];\n\n                            options.language = [options.language, baseLanguage];\n                        } else {\n                            options.language = [options.language];\n                        }\n                    }\n\n                    if ($.isArray(options.language)) {\n                        var languages = new Translation();\n                        options.language.push('en');\n\n                        var languageNames = options.language;\n\n                        for (var l = 0; l < languageNames.length; l++) {\n                            var name = languageNames[l];\n                            var language = {};\n\n                            try {\n                                // Try to load it with the original name\n                                language = Translation.loadPath(name);\n                            } catch (e) {\n                                try {\n                                    // If we couldn't load it, check if it wasn't the full path\n                                    name = this.defaults.amdLanguageBase + name;\n                                    language = Translation.loadPath(name);\n                                } catch (ex) {\n                                    // The translation could not be loaded at all. Sometimes this is\n                                    // because of a configuration problem, other times this can be\n                                    // because of how Select2 helps load all possible translation files.\n                                    if (options.debug && window.console && console.warn) {\n                                        console.warn(\n                                            'Select2: The language file for \"' + name + '\" could not be ' +\n                                            'automatically loaded. A fallback will be used instead.'\n                                        );\n                                    }\n\n                                    continue;\n                                }\n                            }\n\n                            languages.extend(language);\n                        }\n\n                        options.translations = languages;\n                    } else {\n                        var baseTranslation = Translation.loadPath(\n                            this.defaults.amdLanguageBase + 'en'\n                        );\n                        var customTranslation = new Translation(options.language);\n\n                        customTranslation.extend(baseTranslation);\n\n                        options.translations = customTranslation;\n                    }\n\n                    return options;\n                };\n\n                Defaults.prototype.reset = function() {\n                    function stripDiacritics(text) {\n                        // Used 'uni range + named function' from http://jsperf.com/diacritics/18\n                        function match(a) {\n                            return DIACRITICS[a] || a;\n                        }\n\n                        return text.replace(/[^\\u0000-\\u007E]/g, match);\n                    }\n\n                    function matcher(params, data) {\n                        // Always return the object if there is nothing to compare\n                        if ($.trim(params.term) === '') {\n                            return data;\n                        }\n\n                        // Do a recursive check for options with children\n                        if (data.children && data.children.length > 0) {\n                            // Clone the data object if there are children\n                            // This is required as we modify the object to remove any non-matches\n                            var match = $.extend(true, {}, data);\n\n                            // Check each child of the option\n                            for (var c = data.children.length - 1; c >= 0; c--) {\n                                var child = data.children[c];\n\n                                var matches = matcher(params, child);\n\n                                // If there wasn't a match, remove the object in the array\n                                if (matches == null) {\n                                    match.children.splice(c, 1);\n                                }\n                            }\n\n                            // If any children matched, return the new object\n                            if (match.children.length > 0) {\n                                return match;\n                            }\n\n                            // If there were no matching children, check just the plain object\n                            return matcher(params, match);\n                        }\n\n                        var original = stripDiacritics(data.text).toUpperCase();\n                        var term = stripDiacritics(params.term).toUpperCase();\n\n                        // Check if the text contains the term\n                        if (original.indexOf(term) > -1) {\n                            return data;\n                        }\n\n                        // If it doesn't contain the term, don't return anything\n                        return null;\n                    }\n\n                    this.defaults = {\n                        amdBase: './',\n                        amdLanguageBase: './i18n/',\n                        closeOnSelect: true,\n                        debug: false,\n                        dropdownAutoWidth: false,\n                        escapeMarkup: Utils.escapeMarkup,\n                        language: EnglishTranslation,\n                        matcher: matcher,\n                        minimumInputLength: 0,\n                        maximumInputLength: 0,\n                        maximumSelectionLength: 0,\n                        minimumResultsForSearch: 0,\n                        selectOnClose: false,\n                        sorter: function(data) {\n                            return data;\n                        },\n                        templateResult: function(result) {\n                            return result.text;\n                        },\n                        templateSelection: function(selection) {\n                            return selection.text;\n                        },\n                        theme: 'default',\n                        width: 'resolve'\n                    };\n                };\n\n                Defaults.prototype.set = function(key, value) {\n                    var camelKey = $.camelCase(key);\n\n                    var data = {};\n                    data[camelKey] = value;\n\n                    var convertedData = Utils._convertData(data);\n\n                    $.extend(this.defaults, convertedData);\n                };\n\n                var defaults = new Defaults();\n\n                return defaults;\n            });\n\n            S2.define('select2/options', [\n                'require',\n                'jquery',\n                './defaults',\n                './utils'\n            ], function(require, $, Defaults, Utils) {\n                function Options(options, $element) {\n                    this.options = options;\n\n                    if ($element != null) {\n                        this.fromElement($element);\n                    }\n\n                    this.options = Defaults.apply(this.options);\n\n                    if ($element && $element.is('input')) {\n                        var InputCompat = require(this.get('amdBase') + 'compat/inputData');\n\n                        this.options.dataAdapter = Utils.Decorate(\n                            this.options.dataAdapter,\n                            InputCompat\n                        );\n                    }\n                }\n\n                Options.prototype.fromElement = function($e) {\n                    var excludedData = ['select2'];\n\n                    if (this.options.multiple == null) {\n                        this.options.multiple = $e.prop('multiple');\n                    }\n\n                    if (this.options.disabled == null) {\n                        this.options.disabled = $e.prop('disabled');\n                    }\n\n                    if (this.options.language == null) {\n                        if ($e.prop('lang')) {\n                            this.options.language = $e.prop('lang').toLowerCase();\n                        } else if ($e.closest('[lang]').prop('lang')) {\n                            this.options.language = $e.closest('[lang]').prop('lang');\n                        }\n                    }\n\n                    if (this.options.dir == null) {\n                        if ($e.prop('dir')) {\n                            this.options.dir = $e.prop('dir');\n                        } else if ($e.closest('[dir]').prop('dir')) {\n                            this.options.dir = $e.closest('[dir]').prop('dir');\n                        } else {\n                            this.options.dir = 'ltr';\n                        }\n                    }\n\n                    $e.prop('disabled', this.options.disabled);\n                    $e.prop('multiple', this.options.multiple);\n\n                    if ($e.data('select2Tags')) {\n                        if (this.options.debug && window.console && console.warn) {\n                            console.warn(\n                                'Select2: The `data-select2-tags` attribute has been changed to ' +\n                                'use the `data-data` and `data-tags=\"true\"` attributes and will be ' +\n                                'removed in future versions of Select2.'\n                            );\n                        }\n\n                        $e.data('data', $e.data('select2Tags'));\n                        $e.data('tags', true);\n                    }\n\n                    if ($e.data('ajaxUrl')) {\n                        if (this.options.debug && window.console && console.warn) {\n                            console.warn(\n                                'Select2: The `data-ajax-url` attribute has been changed to ' +\n                                '`data-ajax--url` and support for the old attribute will be removed' +\n                                ' in future versions of Select2.'\n                            );\n                        }\n\n                        $e.attr('ajax--url', $e.data('ajaxUrl'));\n                        $e.data('ajax--url', $e.data('ajaxUrl'));\n                    }\n\n                    var dataset = {};\n\n                    // Prefer the element's `dataset` attribute if it exists\n                    // jQuery 1.x does not correctly handle data attributes with multiple dashes\n                    if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {\n                        dataset = $.extend(true, {}, $e[0].dataset, $e.data());\n                    } else {\n                        dataset = $e.data();\n                    }\n\n                    var data = $.extend(true, {}, dataset);\n\n                    data = Utils._convertData(data);\n\n                    for (var key in data) {\n                        if ($.inArray(key, excludedData) > -1) {\n                            continue;\n                        }\n\n                        if ($.isPlainObject(this.options[key])) {\n                            $.extend(this.options[key], data[key]);\n                        } else {\n                            this.options[key] = data[key];\n                        }\n                    }\n\n                    return this;\n                };\n\n                Options.prototype.get = function(key) {\n                    return this.options[key];\n                };\n\n                Options.prototype.set = function(key, val) {\n                    this.options[key] = val;\n                };\n\n                return Options;\n            });\n\n            S2.define('select2/core', [\n                'jquery',\n                './options',\n                './utils',\n                './keys'\n            ], function($, Options, Utils, KEYS) {\n                var Select2 = function($element, options) {\n                    if ($element.data('select2') != null) {\n                        $element.data('select2').destroy();\n                    }\n\n                    this.$element = $element;\n\n                    this.id = this._generateId($element);\n\n                    options = options || {};\n\n                    this.options = new Options(options, $element);\n\n                    Select2.__super__.constructor.call(this);\n\n                    // Set up the tabindex\n\n                    var tabindex = $element.attr('tabindex') || 0;\n                    $element.data('old-tabindex', tabindex);\n                    $element.attr('tabindex', '-1');\n\n                    // Set up containers and adapters\n\n                    var DataAdapter = this.options.get('dataAdapter');\n                    this.dataAdapter = new DataAdapter($element, this.options);\n\n                    var $container = this.render();\n\n                    this._placeContainer($container);\n\n                    var SelectionAdapter = this.options.get('selectionAdapter');\n                    this.selection = new SelectionAdapter($element, this.options);\n                    this.$selection = this.selection.render();\n\n                    this.selection.position(this.$selection, $container);\n\n                    var DropdownAdapter = this.options.get('dropdownAdapter');\n                    this.dropdown = new DropdownAdapter($element, this.options);\n                    this.$dropdown = this.dropdown.render();\n\n                    this.dropdown.position(this.$dropdown, $container);\n\n                    var ResultsAdapter = this.options.get('resultsAdapter');\n                    this.results = new ResultsAdapter($element, this.options, this.dataAdapter);\n                    this.$results = this.results.render();\n\n                    this.results.position(this.$results, this.$dropdown);\n\n                    // Bind events\n\n                    var self = this;\n\n                    // Bind the container to all of the adapters\n                    this._bindAdapters();\n\n                    // Register any DOM event handlers\n                    this._registerDomEvents();\n\n                    // Register any internal event handlers\n                    this._registerDataEvents();\n                    this._registerSelectionEvents();\n                    this._registerDropdownEvents();\n                    this._registerResultsEvents();\n                    this._registerEvents();\n\n                    // Set the initial state\n                    this.dataAdapter.current(function(initialData) {\n                        self.trigger('selection:update', {\n                            data: initialData\n                        });\n                    });\n\n                    // Hide the original select\n                    $element.addClass('select2-hidden-accessible');\n                    $element.attr('aria-hidden', 'true');\n\n                    // Synchronize any monitored attributes\n                    this._syncAttributes();\n\n                    $element.data('select2', this);\n                };\n\n                Utils.Extend(Select2, Utils.Observable);\n\n                Select2.prototype._generateId = function($element) {\n                    var id = '';\n\n                    if ($element.attr('id') != null) {\n                        id = $element.attr('id');\n                    } else if ($element.attr('name') != null) {\n                        id = $element.attr('name') + '-' + Utils.generateChars(2);\n                    } else {\n                        id = Utils.generateChars(4);\n                    }\n\n                    id = 'select2-' + id;\n\n                    return id;\n                };\n\n                Select2.prototype._placeContainer = function($container) {\n                    $container.insertAfter(this.$element);\n\n                    var width = this._resolveWidth(this.$element, this.options.get('width'));\n\n                    if (width != null) {\n                        $container.css('width', width);\n                    }\n                };\n\n                Select2.prototype._resolveWidth = function($element, method) {\n                    var WIDTH = /^width:(([-+]?([0-9]*\\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;\n\n                    if (method == 'resolve') {\n                        var styleWidth = this._resolveWidth($element, 'style');\n\n                        if (styleWidth != null) {\n                            return styleWidth;\n                        }\n\n                        return this._resolveWidth($element, 'element');\n                    }\n\n                    if (method == 'element') {\n                        var elementWidth = $element.outerWidth(false);\n\n                        if (elementWidth <= 0) {\n                            return 'auto';\n                        }\n\n                        return elementWidth + 'px';\n                    }\n\n                    if (method == 'style') {\n                        var style = $element.attr('style');\n\n                        if (typeof(style) !== 'string') {\n                            return null;\n                        }\n\n                        var attrs = style.split(';');\n\n                        for (var i = 0, l = attrs.length; i < l; i = i + 1) {\n                            var attr = attrs[i].replace(/\\s/g, '');\n                            var matches = attr.match(WIDTH);\n\n                            if (matches !== null && matches.length >= 1) {\n                                return matches[1];\n                            }\n                        }\n\n                        return null;\n                    }\n\n                    return method;\n                };\n\n                Select2.prototype._bindAdapters = function() {\n                    this.dataAdapter.bind(this, this.$container);\n                    this.selection.bind(this, this.$container);\n\n                    this.dropdown.bind(this, this.$container);\n                    this.results.bind(this, this.$container);\n                };\n\n                Select2.prototype._registerDomEvents = function() {\n                    var self = this;\n\n                    this.$element.on('change.select2', function() {\n                        self.dataAdapter.current(function(data) {\n                            self.trigger('selection:update', {\n                                data: data\n                            });\n                        });\n                    });\n\n                    this._sync = Utils.bind(this._syncAttributes, this);\n\n                    if (this.$element[0].attachEvent) {\n                        this.$element[0].attachEvent('onpropertychange', this._sync);\n                    }\n\n                    var observer = window.MutationObserver ||\n                        window.WebKitMutationObserver ||\n                        window.MozMutationObserver;\n\n                    if (observer != null) {\n                        this._observer = new observer(function(mutations) {\n                            $.each(mutations, self._sync);\n                        });\n                        this._observer.observe(this.$element[0], {\n                            attributes: true,\n                            subtree: false\n                        });\n                    } else if (this.$element[0].addEventListener) {\n                        this.$element[0].addEventListener('DOMAttrModified', self._sync, false);\n                    }\n                };\n\n                Select2.prototype._registerDataEvents = function() {\n                    var self = this;\n\n                    this.dataAdapter.on('*', function(name, params) {\n                        self.trigger(name, params);\n                    });\n                };\n\n                Select2.prototype._registerSelectionEvents = function() {\n                    var self = this;\n                    var nonRelayEvents = ['toggle', 'focus'];\n\n                    this.selection.on('toggle', function() {\n                        self.toggleDropdown();\n                    });\n\n                    this.selection.on('focus', function(params) {\n                        self.focus(params);\n                    });\n\n                    this.selection.on('*', function(name, params) {\n                        if ($.inArray(name, nonRelayEvents) !== -1) {\n                            return;\n                        }\n\n                        self.trigger(name, params);\n                    });\n                };\n\n                Select2.prototype._registerDropdownEvents = function() {\n                    var self = this;\n\n                    this.dropdown.on('*', function(name, params) {\n                        self.trigger(name, params);\n                    });\n                };\n\n                Select2.prototype._registerResultsEvents = function() {\n                    var self = this;\n\n                    this.results.on('*', function(name, params) {\n                        self.trigger(name, params);\n                    });\n                };\n\n                Select2.prototype._registerEvents = function() {\n                    var self = this;\n\n                    this.on('open', function() {\n                        self.$container.addClass('select2-container--open');\n                    });\n\n                    this.on('close', function() {\n                        self.$container.removeClass('select2-container--open');\n                    });\n\n                    this.on('enable', function() {\n                        self.$container.removeClass('select2-container--disabled');\n                    });\n\n                    this.on('disable', function() {\n                        self.$container.addClass('select2-container--disabled');\n                    });\n\n                    this.on('blur', function() {\n                        self.$container.removeClass('select2-container--focus');\n                    });\n\n                    this.on('query', function(params) {\n                        if (!self.isOpen()) {\n                            self.trigger('open', {});\n                        }\n\n                        this.dataAdapter.query(params, function(data) {\n                            self.trigger('results:all', {\n                                data: data,\n                                query: params\n                            });\n                        });\n                    });\n\n                    this.on('query:append', function(params) {\n                        this.dataAdapter.query(params, function(data) {\n                            self.trigger('results:append', {\n                                data: data,\n                                query: params\n                            });\n                        });\n                    });\n\n                    this.on('keypress', function(evt) {\n                        var key = evt.which;\n\n                        if (self.isOpen()) {\n                            if (key === KEYS.ESC || key === KEYS.TAB ||\n                                (key === KEYS.UP && evt.altKey)) {\n                                self.close();\n\n                                evt.preventDefault();\n                            } else if (key === KEYS.ENTER) {\n                                self.trigger('results:select', {});\n\n                                evt.preventDefault();\n                            } else if ((key === KEYS.SPACE && evt.ctrlKey)) {\n                                self.trigger('results:toggle', {});\n\n                                evt.preventDefault();\n                            } else if (key === KEYS.UP) {\n                                self.trigger('results:previous', {});\n\n                                evt.preventDefault();\n                            } else if (key === KEYS.DOWN) {\n                                self.trigger('results:next', {});\n\n                                evt.preventDefault();\n                            }\n                        } else {\n                            if (key === KEYS.ENTER || key === KEYS.SPACE ||\n                                (key === KEYS.DOWN && evt.altKey)) {\n                                self.open();\n\n                                evt.preventDefault();\n                            }\n                        }\n                    });\n                };\n\n                Select2.prototype._syncAttributes = function() {\n                    this.options.set('disabled', this.$element.prop('disabled'));\n\n                    if (this.options.get('disabled')) {\n                        if (this.isOpen()) {\n                            this.close();\n                        }\n\n                        this.trigger('disable', {});\n                    } else {\n                        this.trigger('enable', {});\n                    }\n                };\n\n                /**\n                 * Override the trigger method to automatically trigger pre-events when\n                 * there are events that can be prevented.\n                 */\n                Select2.prototype.trigger = function(name, args) {\n                    var actualTrigger = Select2.__super__.trigger;\n                    var preTriggerMap = {\n                        'open': 'opening',\n                        'close': 'closing',\n                        'select': 'selecting',\n                        'unselect': 'unselecting'\n                    };\n\n                    if (args === undefined) {\n                        args = {};\n                    }\n\n                    if (name in preTriggerMap) {\n                        var preTriggerName = preTriggerMap[name];\n                        var preTriggerArgs = {\n                            prevented: false,\n                            name: name,\n                            args: args\n                        };\n\n                        actualTrigger.call(this, preTriggerName, preTriggerArgs);\n\n                        if (preTriggerArgs.prevented) {\n                            args.prevented = true;\n\n                            return;\n                        }\n                    }\n\n                    actualTrigger.call(this, name, args);\n                };\n\n                Select2.prototype.toggleDropdown = function() {\n                    if (this.options.get('disabled')) {\n                        return;\n                    }\n\n                    if (this.isOpen()) {\n                        this.close();\n                    } else {\n                        this.open();\n                    }\n                };\n\n                Select2.prototype.open = function() {\n                    if (this.isOpen()) {\n                        return;\n                    }\n\n                    this.trigger('query', {});\n                };\n\n                Select2.prototype.close = function() {\n                    if (!this.isOpen()) {\n                        return;\n                    }\n\n                    this.trigger('close', {});\n                };\n\n                Select2.prototype.isOpen = function() {\n                    return this.$container.hasClass('select2-container--open');\n                };\n\n                Select2.prototype.hasFocus = function() {\n                    return this.$container.hasClass('select2-container--focus');\n                };\n\n                Select2.prototype.focus = function(data) {\n                    // No need to re-trigger focus events if we are already focused\n                    if (this.hasFocus()) {\n                        return;\n                    }\n\n                    this.$container.addClass('select2-container--focus');\n                    this.trigger('focus', {});\n                };\n\n                Select2.prototype.enable = function(args) {\n                    if (this.options.get('debug') && window.console && console.warn) {\n                        console.warn(\n                            'Select2: The `select2(\"enable\")` method has been deprecated and will' +\n                            ' be removed in later Select2 versions. Use $element.prop(\"disabled\")' +\n                            ' instead.'\n                        );\n                    }\n\n                    if (args == null || args.length === 0) {\n                        args = [true];\n                    }\n\n                    var disabled = !args[0];\n\n                    this.$element.prop('disabled', disabled);\n                };\n\n                Select2.prototype.data = function() {\n                    if (this.options.get('debug') &&\n                        arguments.length > 0 && window.console && console.warn) {\n                        console.warn(\n                            'Select2: Data can no longer be set using `select2(\"data\")`. You ' +\n                            'should consider setting the value instead using `$element.val()`.'\n                        );\n                    }\n\n                    var data = [];\n\n                    this.dataAdapter.current(function(currentData) {\n                        data = currentData;\n                    });\n\n                    return data;\n                };\n\n                Select2.prototype.val = function(args) {\n                    if (this.options.get('debug') && window.console && console.warn) {\n                        console.warn(\n                            'Select2: The `select2(\"val\")` method has been deprecated and will be' +\n                            ' removed in later Select2 versions. Use $element.val() instead.'\n                        );\n                    }\n\n                    if (args == null || args.length === 0) {\n                        return this.$element.val();\n                    }\n\n                    var newVal = args[0];\n\n                    if ($.isArray(newVal)) {\n                        newVal = $.map(newVal, function(obj) {\n                            return obj.toString();\n                        });\n                    }\n\n                    this.$element.val(newVal).trigger('change');\n                };\n\n                Select2.prototype.destroy = function() {\n                    this.$container.remove();\n\n                    if (this.$element[0].detachEvent) {\n                        this.$element[0].detachEvent('onpropertychange', this._sync);\n                    }\n\n                    if (this._observer != null) {\n                        this._observer.disconnect();\n                        this._observer = null;\n                    } else if (this.$element[0].removeEventListener) {\n                        this.$element[0]\n                            .removeEventListener('DOMAttrModified', this._sync, false);\n                    }\n\n                    this._sync = null;\n\n                    this.$element.off('.select2');\n                    this.$element.attr('tabindex', this.$element.data('old-tabindex'));\n\n                    this.$element.removeClass('select2-hidden-accessible');\n                    this.$element.attr('aria-hidden', 'false');\n                    this.$element.removeData('select2');\n\n                    this.dataAdapter.destroy();\n                    this.selection.destroy();\n                    this.dropdown.destroy();\n                    this.results.destroy();\n\n                    this.dataAdapter = null;\n                    this.selection = null;\n                    this.dropdown = null;\n                    this.results = null;\n                };\n\n                Select2.prototype.render = function() {\n                    var $container = $(\n                        '<span class=\"select2 select2-container\">' +\n                        '<span class=\"selection\"></span>' +\n                        '<span class=\"dropdown-wrapper\" aria-hidden=\"true\"></span>' +\n                        '</span>'\n                    );\n\n                    $container.attr('dir', this.options.get('dir'));\n\n                    this.$container = $container;\n\n                    this.$container.addClass('select2-container--' + this.options.get('theme'));\n\n                    $container.data('element', this.$element);\n\n                    return $container;\n                };\n\n                return Select2;\n            });\n\n            S2.define('select2/compat/utils', [\n                'jquery'\n            ], function($) {\n                function syncCssClasses($dest, $src, adapter) {\n                    var classes, replacements = [],\n                        adapted;\n\n                    classes = $.trim($dest.attr('class'));\n\n                    if (classes) {\n                        classes = '' + classes; // for IE which returns object\n\n                        $(classes.split(/\\s+/)).each(function() {\n                            // Save all Select2 classes\n                            if (this.indexOf('select2-') === 0) {\n                                replacements.push(this);\n                            }\n                        });\n                    }\n\n                    classes = $.trim($src.attr('class'));\n\n                    if (classes) {\n                        classes = '' + classes; // for IE which returns object\n\n                        $(classes.split(/\\s+/)).each(function() {\n                            // Only adapt non-Select2 classes\n                            if (this.indexOf('select2-') !== 0) {\n                                adapted = adapter(this);\n\n                                if (adapted != null) {\n                                    replacements.push(adapted);\n                                }\n                            }\n                        });\n                    }\n\n                    $dest.attr('class', replacements.join(' '));\n                }\n\n                return {\n                    syncCssClasses: syncCssClasses\n                };\n            });\n\n            S2.define('select2/compat/containerCss', [\n                'jquery',\n                './utils'\n            ], function($, CompatUtils) {\n                // No-op CSS adapter that discards all classes by default\n                function _containerAdapter(clazz) {\n                    return null;\n                }\n\n                function ContainerCSS() {}\n\n                ContainerCSS.prototype.render = function(decorated) {\n                    var $container = decorated.call(this);\n\n                    var containerCssClass = this.options.get('containerCssClass') || '';\n\n                    if ($.isFunction(containerCssClass)) {\n                        containerCssClass = containerCssClass(this.$element);\n                    }\n\n                    var containerCssAdapter = this.options.get('adaptContainerCssClass');\n                    containerCssAdapter = containerCssAdapter || _containerAdapter;\n\n                    if (containerCssClass.indexOf(':all:') !== -1) {\n                        containerCssClass = containerCssClass.replace(':all:', '');\n\n                        var _cssAdapter = containerCssAdapter;\n\n                        containerCssAdapter = function(clazz) {\n                            var adapted = _cssAdapter(clazz);\n\n                            if (adapted != null) {\n                                // Append the old one along with the adapted one\n                                return adapted + ' ' + clazz;\n                            }\n\n                            return clazz;\n                        };\n                    }\n\n                    var containerCss = this.options.get('containerCss') || {};\n\n                    if ($.isFunction(containerCss)) {\n                        containerCss = containerCss(this.$element);\n                    }\n\n                    CompatUtils.syncCssClasses($container, this.$element, containerCssAdapter);\n\n                    $container.css(containerCss);\n                    $container.addClass(containerCssClass);\n\n                    return $container;\n                };\n\n                return ContainerCSS;\n            });\n\n            S2.define('select2/compat/dropdownCss', [\n                'jquery',\n                './utils'\n            ], function($, CompatUtils) {\n                // No-op CSS adapter that discards all classes by default\n                function _dropdownAdapter(clazz) {\n                    return null;\n                }\n\n                function DropdownCSS() {}\n\n                DropdownCSS.prototype.render = function(decorated) {\n                    var $dropdown = decorated.call(this);\n\n                    var dropdownCssClass = this.options.get('dropdownCssClass') || '';\n\n                    if ($.isFunction(dropdownCssClass)) {\n                        dropdownCssClass = dropdownCssClass(this.$element);\n                    }\n\n                    var dropdownCssAdapter = this.options.get('adaptDropdownCssClass');\n                    dropdownCssAdapter = dropdownCssAdapter || _dropdownAdapter;\n\n                    if (dropdownCssClass.indexOf(':all:') !== -1) {\n                        dropdownCssClass = dropdownCssClass.replace(':all:', '');\n\n                        var _cssAdapter = dropdownCssAdapter;\n\n                        dropdownCssAdapter = function(clazz) {\n                            var adapted = _cssAdapter(clazz);\n\n                            if (adapted != null) {\n                                // Append the old one along with the adapted one\n                                return adapted + ' ' + clazz;\n                            }\n\n                            return clazz;\n                        };\n                    }\n\n                    var dropdownCss = this.options.get('dropdownCss') || {};\n\n                    if ($.isFunction(dropdownCss)) {\n                        dropdownCss = dropdownCss(this.$element);\n                    }\n\n                    CompatUtils.syncCssClasses($dropdown, this.$element, dropdownCssAdapter);\n\n                    $dropdown.css(dropdownCss);\n                    $dropdown.addClass(dropdownCssClass);\n\n                    return $dropdown;\n                };\n\n                return DropdownCSS;\n            });\n\n            S2.define('select2/compat/initSelection', [\n                'jquery'\n            ], function($) {\n                function InitSelection(decorated, $element, options) {\n                    if (options.get('debug') && window.console && console.warn) {\n                        console.warn(\n                            'Select2: The `initSelection` option has been deprecated in favor' +\n                            ' of a custom data adapter that overrides the `current` method. ' +\n                            'This method is now called multiple times instead of a single ' +\n                            'time when the instance is initialized. Support will be removed ' +\n                            'for the `initSelection` option in future versions of Select2'\n                        );\n                    }\n\n                    this.initSelection = options.get('initSelection');\n                    this._isInitialized = false;\n\n                    decorated.call(this, $element, options);\n                }\n\n                InitSelection.prototype.current = function(decorated, callback) {\n                    var self = this;\n\n                    if (this._isInitialized) {\n                        decorated.call(this, callback);\n\n                        return;\n                    }\n\n                    this.initSelection.call(null, this.$element, function(data) {\n                        self._isInitialized = true;\n\n                        if (!$.isArray(data)) {\n                            data = [data];\n                        }\n\n                        callback(data);\n                    });\n                };\n\n                return InitSelection;\n            });\n\n            S2.define('select2/compat/inputData', [\n                'jquery'\n            ], function($) {\n                function InputData(decorated, $element, options) {\n                    this._currentData = [];\n                    this._valueSeparator = options.get('valueSeparator') || ',';\n\n                    if ($element.prop('type') === 'hidden') {\n                        if (options.get('debug') && console && console.warn) {\n                            console.warn(\n                                'Select2: Using a hidden input with Select2 is no longer ' +\n                                'supported and may stop working in the future. It is recommended ' +\n                                'to use a `<select>` element instead.'\n                            );\n                        }\n                    }\n\n                    decorated.call(this, $element, options);\n                }\n\n                InputData.prototype.current = function(_, callback) {\n                    function getSelected(data, selectedIds) {\n                        var selected = [];\n\n                        if (data.selected || $.inArray(data.id, selectedIds) !== -1) {\n                            data.selected = true;\n                            selected.push(data);\n                        } else {\n                            data.selected = false;\n                        }\n\n                        if (data.children) {\n                            selected.push.apply(selected, getSelected(data.children, selectedIds));\n                        }\n\n                        return selected;\n                    }\n\n                    var selected = [];\n\n                    for (var d = 0; d < this._currentData.length; d++) {\n                        var data = this._currentData[d];\n\n                        selected.push.apply(\n                            selected,\n                            getSelected(\n                                data,\n                                this.$element.val().split(\n                                    this._valueSeparator\n                                )\n                            )\n                        );\n                    }\n\n                    callback(selected);\n                };\n\n                InputData.prototype.select = function(_, data) {\n                    if (!this.options.get('multiple')) {\n                        this.current(function(allData) {\n                            $.map(allData, function(data) {\n                                data.selected = false;\n                            });\n                        });\n\n                        this.$element.val(data.id);\n                        this.$element.trigger('change');\n                    } else {\n                        var value = this.$element.val();\n                        value += this._valueSeparator + data.id;\n\n                        this.$element.val(value);\n                        this.$element.trigger('change');\n                    }\n                };\n\n                InputData.prototype.unselect = function(_, data) {\n                    var self = this;\n\n                    data.selected = false;\n\n                    this.current(function(allData) {\n                        var values = [];\n\n                        for (var d = 0; d < allData.length; d++) {\n                            var item = allData[d];\n\n                            if (data.id == item.id) {\n                                continue;\n                            }\n\n                            values.push(item.id);\n                        }\n\n                        self.$element.val(values.join(self._valueSeparator));\n                        self.$element.trigger('change');\n                    });\n                };\n\n                InputData.prototype.query = function(_, params, callback) {\n                    var results = [];\n\n                    for (var d = 0; d < this._currentData.length; d++) {\n                        var data = this._currentData[d];\n\n                        var matches = this.matches(params, data);\n\n                        if (matches !== null) {\n                            results.push(matches);\n                        }\n                    }\n\n                    callback({\n                        results: results\n                    });\n                };\n\n                InputData.prototype.addOptions = function(_, $options) {\n                    var options = $.map($options, function($option) {\n                        return $.data($option[0], 'data');\n                    });\n\n                    this._currentData.push.apply(this._currentData, options);\n                };\n\n                return InputData;\n            });\n\n            S2.define('select2/compat/matcher', [\n                'jquery'\n            ], function($) {\n                function oldMatcher(matcher) {\n                    function wrappedMatcher(params, data) {\n                        var match = $.extend(true, {}, data);\n\n                        if (params.term == null || $.trim(params.term) === '') {\n                            return match;\n                        }\n\n                        if (data.children) {\n                            for (var c = data.children.length - 1; c >= 0; c--) {\n                                var child = data.children[c];\n\n                                // Check if the child object matches\n                                // The old matcher returned a boolean true or false\n                                var doesMatch = matcher(params.term, child.text, child);\n\n                                // If the child didn't match, pop it off\n                                if (!doesMatch) {\n                                    match.children.splice(c, 1);\n                                }\n                            }\n\n                            if (match.children.length > 0) {\n                                return match;\n                            }\n                        }\n\n                        if (matcher(params.term, data.text, data)) {\n                            return match;\n                        }\n\n                        return null;\n                    }\n\n                    return wrappedMatcher;\n                }\n\n                return oldMatcher;\n            });\n\n            S2.define('select2/compat/query', [\n\n            ], function() {\n                function Query(decorated, $element, options) {\n                    if (options.get('debug') && window.console && console.warn) {\n                        console.warn(\n                            'Select2: The `query` option has been deprecated in favor of a ' +\n                            'custom data adapter that overrides the `query` method. Support ' +\n                            'will be removed for the `query` option in future versions of ' +\n                            'Select2.'\n                        );\n                    }\n\n                    decorated.call(this, $element, options);\n                }\n\n                Query.prototype.query = function(_, params, callback) {\n                    params.callback = callback;\n\n                    var query = this.options.get('query');\n\n                    query.call(null, params);\n                };\n\n                return Query;\n            });\n\n            S2.define('select2/dropdown/attachContainer', [\n\n            ], function() {\n                function AttachContainer(decorated, $element, options) {\n                    decorated.call(this, $element, options);\n                }\n\n                AttachContainer.prototype.position =\n                    function(decorated, $dropdown, $container) {\n                        var $dropdownContainer = $container.find('.dropdown-wrapper');\n                        $dropdownContainer.append($dropdown);\n\n                        $dropdown.addClass('select2-dropdown--below');\n                        $container.addClass('select2-container--below');\n                    };\n\n                return AttachContainer;\n            });\n\n            S2.define('select2/dropdown/stopPropagation', [\n\n            ], function() {\n                function StopPropagation() {}\n\n                StopPropagation.prototype.bind = function(decorated, container, $container) {\n                    decorated.call(this, container, $container);\n\n                    var stoppedEvents = [\n                        'blur',\n                        'change',\n                        'click',\n                        'dblclick',\n                        'focus',\n                        'focusin',\n                        'focusout',\n                        'input',\n                        'keydown',\n                        'keyup',\n                        'keypress',\n                        'mousedown',\n                        'mouseenter',\n                        'mouseleave',\n                        'mousemove',\n                        'mouseover',\n                        'mouseup',\n                        'search',\n                        'touchend',\n                        'touchstart'\n                    ];\n\n                    this.$dropdown.on(stoppedEvents.join(' '), function(evt) {\n                        evt.stopPropagation();\n                    });\n                };\n\n                return StopPropagation;\n            });\n\n            S2.define('select2/selection/stopPropagation', [\n\n            ], function() {\n                function StopPropagation() {}\n\n                StopPropagation.prototype.bind = function(decorated, container, $container) {\n                    decorated.call(this, container, $container);\n\n                    var stoppedEvents = [\n                        'blur',\n                        'change',\n                        'click',\n                        'dblclick',\n                        'focus',\n                        'focusin',\n                        'focusout',\n                        'input',\n                        'keydown',\n                        'keyup',\n                        'keypress',\n                        'mousedown',\n                        'mouseenter',\n                        'mouseleave',\n                        'mousemove',\n                        'mouseover',\n                        'mouseup',\n                        'search',\n                        'touchend',\n                        'touchstart'\n                    ];\n\n                    this.$selection.on(stoppedEvents.join(' '), function(evt) {\n                        evt.stopPropagation();\n                    });\n                };\n\n                return StopPropagation;\n            });\n\n            /*!\n             * jQuery Mousewheel 3.1.13\n             *\n             * Copyright jQuery Foundation and other contributors\n             * Released under the MIT license\n             * http://jquery.org/license\n             */\n\n            (function(factory) {\n                if (typeof S2.define === 'function' && S2.define.amd) {\n                    // AMD. Register as an anonymous module.\n                    S2.define('jquery-mousewheel', ['jquery'], factory);\n                } else if (typeof exports === 'object') {\n                    // Node/CommonJS style for Browserify\n                    module.exports = factory;\n                } else {\n                    // Browser globals\n                    factory(jQuery);\n                }\n            }(function($) {\n\n                var toFix = ['wheel', 'mousewheel', 'DOMMouseScroll', 'MozMousePixelScroll'],\n                    toBind = ('onwheel' in document || document.documentMode >= 9) ? ['wheel'] : ['mousewheel', 'DomMouseScroll', 'MozMousePixelScroll'],\n                    slice = Array.prototype.slice,\n                    nullLowestDeltaTimeout, lowestDelta;\n\n                if ($.event.fixHooks) {\n                    for (var i = toFix.length; i;) {\n                        $.event.fixHooks[toFix[--i]] = $.event.mouseHooks;\n                    }\n                }\n\n                var special = $.event.special.mousewheel = {\n                    version: '3.1.12',\n\n                    setup: function() {\n                        if (this.addEventListener) {\n                            for (var i = toBind.length; i;) {\n                                this.addEventListener(toBind[--i], handler, false);\n                            }\n                        } else {\n                            this.onmousewheel = handler;\n                        }\n                        // Store the line height and page height for this particular element\n                        $.data(this, 'mousewheel-line-height', special.getLineHeight(this));\n                        $.data(this, 'mousewheel-page-height', special.getPageHeight(this));\n                    },\n\n                    teardown: function() {\n                        if (this.removeEventListener) {\n                            for (var i = toBind.length; i;) {\n                                this.removeEventListener(toBind[--i], handler, false);\n                            }\n                        } else {\n                            this.onmousewheel = null;\n                        }\n                        // Clean up the data we added to the element\n                        $.removeData(this, 'mousewheel-line-height');\n                        $.removeData(this, 'mousewheel-page-height');\n                    },\n\n                    getLineHeight: function(elem) {\n                        var $elem = $(elem),\n                            $parent = $elem['offsetParent' in $.fn ? 'offsetParent' : 'parent']();\n                        if (!$parent.length) {\n                            $parent = $('body');\n                        }\n                        return parseInt($parent.css('fontSize'), 10) || parseInt($elem.css('fontSize'), 10) || 16;\n                    },\n\n                    getPageHeight: function(elem) {\n                        return $(elem).height();\n                    },\n\n                    settings: {\n                        adjustOldDeltas: true, // see shouldAdjustOldDeltas() below\n                        normalizeOffset: true // calls getBoundingClientRect for each event\n                    }\n                };\n\n                $.fn.extend({\n                    mousewheel: function(fn) {\n                        return fn ? this.bind('mousewheel', fn) : this.trigger('mousewheel');\n                    },\n\n                    unmousewheel: function(fn) {\n                        return this.unbind('mousewheel', fn);\n                    }\n                });\n\n\n                function handler(event) {\n                    var orgEvent = event || window.event,\n                        args = slice.call(arguments, 1),\n                        delta = 0,\n                        deltaX = 0,\n                        deltaY = 0,\n                        absDelta = 0,\n                        offsetX = 0,\n                        offsetY = 0;\n                    event = $.event.fix(orgEvent);\n                    event.type = 'mousewheel';\n\n                    // Old school scrollwheel delta\n                    if ('detail' in orgEvent) { deltaY = orgEvent.detail * -1; }\n                    if ('wheelDelta' in orgEvent) { deltaY = orgEvent.wheelDelta; }\n                    if ('wheelDeltaY' in orgEvent) { deltaY = orgEvent.wheelDeltaY; }\n                    if ('wheelDeltaX' in orgEvent) { deltaX = orgEvent.wheelDeltaX * -1; }\n\n                    // Firefox < 17 horizontal scrolling related to DOMMouseScroll event\n                    if ('axis' in orgEvent && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) {\n                        deltaX = deltaY * -1;\n                        deltaY = 0;\n                    }\n\n                    // Set delta to be deltaY or deltaX if deltaY is 0 for backwards compatabilitiy\n                    delta = deltaY === 0 ? deltaX : deltaY;\n\n                    // New school wheel delta (wheel event)\n                    if ('deltaY' in orgEvent) {\n                        deltaY = orgEvent.deltaY * -1;\n                        delta = deltaY;\n                    }\n                    if ('deltaX' in orgEvent) {\n                        deltaX = orgEvent.deltaX;\n                        if (deltaY === 0) { delta = deltaX * -1; }\n                    }\n\n                    // No change actually happened, no reason to go any further\n                    if (deltaY === 0 && deltaX === 0) {\n                        return; }\n\n                    // Need to convert lines and pages to pixels if we aren't already in pixels\n                    // There are three delta modes:\n                    //   * deltaMode 0 is by pixels, nothing to do\n                    //   * deltaMode 1 is by lines\n                    //   * deltaMode 2 is by pages\n                    if (orgEvent.deltaMode === 1) {\n                        var lineHeight = $.data(this, 'mousewheel-line-height');\n                        delta *= lineHeight;\n                        deltaY *= lineHeight;\n                        deltaX *= lineHeight;\n                    } else if (orgEvent.deltaMode === 2) {\n                        var pageHeight = $.data(this, 'mousewheel-page-height');\n                        delta *= pageHeight;\n                        deltaY *= pageHeight;\n                        deltaX *= pageHeight;\n                    }\n\n                    // Store lowest absolute delta to normalize the delta values\n                    absDelta = Math.max(Math.abs(deltaY), Math.abs(deltaX));\n\n                    if (!lowestDelta || absDelta < lowestDelta) {\n                        lowestDelta = absDelta;\n\n                        // Adjust older deltas if necessary\n                        if (shouldAdjustOldDeltas(orgEvent, absDelta)) {\n                            lowestDelta /= 40;\n                        }\n                    }\n\n                    // Adjust older deltas if necessary\n                    if (shouldAdjustOldDeltas(orgEvent, absDelta)) {\n                        // Divide all the things by 40!\n                        delta /= 40;\n                        deltaX /= 40;\n                        deltaY /= 40;\n                    }\n\n                    // Get a whole, normalized value for the deltas\n                    delta = Math[delta >= 1 ? 'floor' : 'ceil'](delta / lowestDelta);\n                    deltaX = Math[deltaX >= 1 ? 'floor' : 'ceil'](deltaX / lowestDelta);\n                    deltaY = Math[deltaY >= 1 ? 'floor' : 'ceil'](deltaY / lowestDelta);\n\n                    // Normalise offsetX and offsetY properties\n                    if (special.settings.normalizeOffset && this.getBoundingClientRect) {\n                        var boundingRect = this.getBoundingClientRect();\n                        offsetX = event.clientX - boundingRect.left;\n                        offsetY = event.clientY - boundingRect.top;\n                    }\n\n                    // Add information to the event object\n                    event.deltaX = deltaX;\n                    event.deltaY = deltaY;\n                    event.deltaFactor = lowestDelta;\n                    event.offsetX = offsetX;\n                    event.offsetY = offsetY;\n                    // Go ahead and set deltaMode to 0 since we converted to pixels\n                    // Although this is a little odd since we overwrite the deltaX/Y\n                    // properties with normalized deltas.\n                    event.deltaMode = 0;\n\n                    // Add event and delta to the front of the arguments\n                    args.unshift(event, delta, deltaX, deltaY);\n\n                    // Clearout lowestDelta after sometime to better\n                    // handle multiple device types that give different\n                    // a different lowestDelta\n                    // Ex: trackpad = 3 and mouse wheel = 120\n                    if (nullLowestDeltaTimeout) { clearTimeout(nullLowestDeltaTimeout); }\n                    nullLowestDeltaTimeout = setTimeout(nullLowestDelta, 200);\n\n                    return ($.event.dispatch || $.event.handle).apply(this, args);\n                }\n\n                function nullLowestDelta() {\n                    lowestDelta = null;\n                }\n\n                function shouldAdjustOldDeltas(orgEvent, absDelta) {\n                    // If this is an older event and the delta is divisable by 120,\n                    // then we are assuming that the browser is treating this as an\n                    // older mouse wheel event and that we should divide the deltas\n                    // by 40 to try and get a more usable deltaFactor.\n                    // Side note, this actually impacts the reported scroll distance\n                    // in older browsers and can cause scrolling to be slower than native.\n                    // Turn this off by setting $.event.special.mousewheel.settings.adjustOldDeltas to false.\n                    return special.settings.adjustOldDeltas && orgEvent.type === 'mousewheel' && absDelta % 120 === 0;\n                }\n\n            }));\n\n            S2.define('jquery.select2', [\n                'jquery',\n                'jquery-mousewheel',\n\n                './select2/core',\n                './select2/defaults'\n            ], function($, _, Select2, Defaults) {\n                if ($.fn.select2 == null) {\n                    // All methods that should return the element\n                    var thisMethods = ['open', 'close', 'destroy'];\n\n                    $.fn.select2 = function(options) {\n                        options = options || {};\n\n                        if (typeof options === 'object') {\n                            this.each(function() {\n                                var instanceOptions = $.extend(true, {}, options);\n\n                                var instance = new Select2($(this), instanceOptions);\n                            });\n\n                            return this;\n                        } else if (typeof options === 'string') {\n                            var ret;\n\n                            this.each(function() {\n                                var instance = $(this).data('select2');\n\n                                if (instance == null && window.console && console.error) {\n                                    console.error(\n                                        'The select2(\\'' + options + '\\') method was called on an ' +\n                                        'element that is not using Select2.'\n                                    );\n                                }\n\n                                var args = Array.prototype.slice.call(arguments, 1);\n\n                                ret = instance[options].apply(instance, args);\n                            });\n\n                            // Check if we should be returning `this`\n                            if ($.inArray(options, thisMethods) > -1) {\n                                return this;\n                            }\n\n                            return ret;\n                        } else {\n                            throw new Error('Invalid arguments for Select2: ' + options);\n                        }\n                    };\n                }\n\n                if ($.fn.select2.defaults == null) {\n                    $.fn.select2.defaults = Defaults;\n                }\n\n                return Select2;\n            });\n\n            // Return the AMD loader configuration so it can be used outside of this file\n            return {\n                define: S2.define,\n                require: S2.require\n            };\n        }());\n\n    // Autoload the jQuery bindings\n    // We know that all of the modules exist above this, so we're safe\n    var select2 = S2.require('jquery.select2');\n\n    // Hold the AMD module references on the jQuery function that was just loaded\n    // This allows Select2 to use the internal loader outside of this file, such\n    // as in the language files.\n    jQuery.fn.select2.amd = S2;\n\n    // Return the Select2 instance for anyone who is importing it.\n    return select2;\n}));\n"
  },
  {
    "path": "public/static/plugins/select2/select2.js",
    "content": "/*!\n * Select2 4.0.1\n * https://select2.github.io\n *\n * Released under the MIT license\n * https://github.com/select2/select2/blob/master/LICENSE.md\n */\n(function (factory) {\n  if (typeof define === 'function' && define.amd) {\n    // AMD. Register as an anonymous module.\n    define(['jquery'], factory);\n  } else if (typeof exports === 'object') {\n    // Node/CommonJS\n    factory(require('jquery'));\n  } else {\n    // Browser globals\n    factory(jQuery);\n  }\n}(function (jQuery) {\n  // This is needed so we can catch the AMD loader configuration and use it\n  // The inner file should be wrapped (by `banner.start.js`) in a function that\n  // returns the AMD loader references.\n  var S2 =\n(function () {\n  // Restore the Select2 AMD loader so it can be used\n  // Needed mostly in the language files, where the loader is not inserted\n  if (jQuery && jQuery.fn && jQuery.fn.select2 && jQuery.fn.select2.amd) {\n    var S2 = jQuery.fn.select2.amd;\n  }\nvar S2;(function () { if (!S2 || !S2.requirejs) {\nif (!S2) { S2 = {}; } else { require = S2; }\n/**\n * @license almond 0.3.1 Copyright (c) 2011-2014, The Dojo Foundation All Rights Reserved.\n * Available via the MIT or new BSD license.\n * see: http://github.com/jrburke/almond for details\n */\n//Going sloppy to avoid 'use strict' string cost, but strict practices should\n//be followed.\n/*jslint sloppy: true */\n/*global setTimeout: false */\n\nvar requirejs, require, define;\n(function (undef) {\n    var main, req, makeMap, handlers,\n        defined = {},\n        waiting = {},\n        config = {},\n        defining = {},\n        hasOwn = Object.prototype.hasOwnProperty,\n        aps = [].slice,\n        jsSuffixRegExp = /\\.js$/;\n\n    function hasProp(obj, prop) {\n        return hasOwn.call(obj, prop);\n    }\n\n    /**\n     * Given a relative module name, like ./something, normalize it to\n     * a real name that can be mapped to a path.\n     * @param {String} name the relative name\n     * @param {String} baseName a real name that the name arg is relative\n     * to.\n     * @returns {String} normalized name\n     */\n    function normalize(name, baseName) {\n        var nameParts, nameSegment, mapValue, foundMap, lastIndex,\n            foundI, foundStarMap, starI, i, j, part,\n            baseParts = baseName && baseName.split(\"/\"),\n            map = config.map,\n            starMap = (map && map['*']) || {};\n\n        //Adjust any relative paths.\n        if (name && name.charAt(0) === \".\") {\n            //If have a base name, try to normalize against it,\n            //otherwise, assume it is a top-level require that will\n            //be relative to baseUrl in the end.\n            if (baseName) {\n                name = name.split('/');\n                lastIndex = name.length - 1;\n\n                // Node .js allowance:\n                if (config.nodeIdCompat && jsSuffixRegExp.test(name[lastIndex])) {\n                    name[lastIndex] = name[lastIndex].replace(jsSuffixRegExp, '');\n                }\n\n                //Lop off the last part of baseParts, so that . matches the\n                //\"directory\" and not name of the baseName's module. For instance,\n                //baseName of \"one/two/three\", maps to \"one/two/three.js\", but we\n                //want the directory, \"one/two\" for this normalization.\n                name = baseParts.slice(0, baseParts.length - 1).concat(name);\n\n                //start trimDots\n                for (i = 0; i < name.length; i += 1) {\n                    part = name[i];\n                    if (part === \".\") {\n                        name.splice(i, 1);\n                        i -= 1;\n                    } else if (part === \"..\") {\n                        if (i === 1 && (name[2] === '..' || name[0] === '..')) {\n                            //End of the line. Keep at least one non-dot\n                            //path segment at the front so it can be mapped\n                            //correctly to disk. Otherwise, there is likely\n                            //no path mapping for a path starting with '..'.\n                            //This can still fail, but catches the most reasonable\n                            //uses of ..\n                            break;\n                        } else if (i > 0) {\n                            name.splice(i - 1, 2);\n                            i -= 2;\n                        }\n                    }\n                }\n                //end trimDots\n\n                name = name.join(\"/\");\n            } else if (name.indexOf('./') === 0) {\n                // No baseName, so this is ID is resolved relative\n                // to baseUrl, pull off the leading dot.\n                name = name.substring(2);\n            }\n        }\n\n        //Apply map config if available.\n        if ((baseParts || starMap) && map) {\n            nameParts = name.split('/');\n\n            for (i = nameParts.length; i > 0; i -= 1) {\n                nameSegment = nameParts.slice(0, i).join(\"/\");\n\n                if (baseParts) {\n                    //Find the longest baseName segment match in the config.\n                    //So, do joins on the biggest to smallest lengths of baseParts.\n                    for (j = baseParts.length; j > 0; j -= 1) {\n                        mapValue = map[baseParts.slice(0, j).join('/')];\n\n                        //baseName segment has  config, find if it has one for\n                        //this name.\n                        if (mapValue) {\n                            mapValue = mapValue[nameSegment];\n                            if (mapValue) {\n                                //Match, update name to the new value.\n                                foundMap = mapValue;\n                                foundI = i;\n                                break;\n                            }\n                        }\n                    }\n                }\n\n                if (foundMap) {\n                    break;\n                }\n\n                //Check for a star map match, but just hold on to it,\n                //if there is a shorter segment match later in a matching\n                //config, then favor over this star map.\n                if (!foundStarMap && starMap && starMap[nameSegment]) {\n                    foundStarMap = starMap[nameSegment];\n                    starI = i;\n                }\n            }\n\n            if (!foundMap && foundStarMap) {\n                foundMap = foundStarMap;\n                foundI = starI;\n            }\n\n            if (foundMap) {\n                nameParts.splice(0, foundI, foundMap);\n                name = nameParts.join('/');\n            }\n        }\n\n        return name;\n    }\n\n    function makeRequire(relName, forceSync) {\n        return function () {\n            //A version of a require function that passes a moduleName\n            //value for items that may need to\n            //look up paths relative to the moduleName\n            var args = aps.call(arguments, 0);\n\n            //If first arg is not require('string'), and there is only\n            //one arg, it is the array form without a callback. Insert\n            //a null so that the following concat is correct.\n            if (typeof args[0] !== 'string' && args.length === 1) {\n                args.push(null);\n            }\n            return req.apply(undef, args.concat([relName, forceSync]));\n        };\n    }\n\n    function makeNormalize(relName) {\n        return function (name) {\n            return normalize(name, relName);\n        };\n    }\n\n    function makeLoad(depName) {\n        return function (value) {\n            defined[depName] = value;\n        };\n    }\n\n    function callDep(name) {\n        if (hasProp(waiting, name)) {\n            var args = waiting[name];\n            delete waiting[name];\n            defining[name] = true;\n            main.apply(undef, args);\n        }\n\n        if (!hasProp(defined, name) && !hasProp(defining, name)) {\n            throw new Error('No ' + name);\n        }\n        return defined[name];\n    }\n\n    //Turns a plugin!resource to [plugin, resource]\n    //with the plugin being undefined if the name\n    //did not have a plugin prefix.\n    function splitPrefix(name) {\n        var prefix,\n            index = name ? name.indexOf('!') : -1;\n        if (index > -1) {\n            prefix = name.substring(0, index);\n            name = name.substring(index + 1, name.length);\n        }\n        return [prefix, name];\n    }\n\n    /**\n     * Makes a name map, normalizing the name, and using a plugin\n     * for normalization if necessary. Grabs a ref to plugin\n     * too, as an optimization.\n     */\n    makeMap = function (name, relName) {\n        var plugin,\n            parts = splitPrefix(name),\n            prefix = parts[0];\n\n        name = parts[1];\n\n        if (prefix) {\n            prefix = normalize(prefix, relName);\n            plugin = callDep(prefix);\n        }\n\n        //Normalize according\n        if (prefix) {\n            if (plugin && plugin.normalize) {\n                name = plugin.normalize(name, makeNormalize(relName));\n            } else {\n                name = normalize(name, relName);\n            }\n        } else {\n            name = normalize(name, relName);\n            parts = splitPrefix(name);\n            prefix = parts[0];\n            name = parts[1];\n            if (prefix) {\n                plugin = callDep(prefix);\n            }\n        }\n\n        //Using ridiculous property names for space reasons\n        return {\n            f: prefix ? prefix + '!' + name : name, //fullName\n            n: name,\n            pr: prefix,\n            p: plugin\n        };\n    };\n\n    function makeConfig(name) {\n        return function () {\n            return (config && config.config && config.config[name]) || {};\n        };\n    }\n\n    handlers = {\n        require: function (name) {\n            return makeRequire(name);\n        },\n        exports: function (name) {\n            var e = defined[name];\n            if (typeof e !== 'undefined') {\n                return e;\n            } else {\n                return (defined[name] = {});\n            }\n        },\n        module: function (name) {\n            return {\n                id: name,\n                uri: '',\n                exports: defined[name],\n                config: makeConfig(name)\n            };\n        }\n    };\n\n    main = function (name, deps, callback, relName) {\n        var cjsModule, depName, ret, map, i,\n            args = [],\n            callbackType = typeof callback,\n            usingExports;\n\n        //Use name if no relName\n        relName = relName || name;\n\n        //Call the callback to define the module, if necessary.\n        if (callbackType === 'undefined' || callbackType === 'function') {\n            //Pull out the defined dependencies and pass the ordered\n            //values to the callback.\n            //Default to [require, exports, module] if no deps\n            deps = !deps.length && callback.length ? ['require', 'exports', 'module'] : deps;\n            for (i = 0; i < deps.length; i += 1) {\n                map = makeMap(deps[i], relName);\n                depName = map.f;\n\n                //Fast path CommonJS standard dependencies.\n                if (depName === \"require\") {\n                    args[i] = handlers.require(name);\n                } else if (depName === \"exports\") {\n                    //CommonJS module spec 1.1\n                    args[i] = handlers.exports(name);\n                    usingExports = true;\n                } else if (depName === \"module\") {\n                    //CommonJS module spec 1.1\n                    cjsModule = args[i] = handlers.module(name);\n                } else if (hasProp(defined, depName) ||\n                           hasProp(waiting, depName) ||\n                           hasProp(defining, depName)) {\n                    args[i] = callDep(depName);\n                } else if (map.p) {\n                    map.p.load(map.n, makeRequire(relName, true), makeLoad(depName), {});\n                    args[i] = defined[depName];\n                } else {\n                    throw new Error(name + ' missing ' + depName);\n                }\n            }\n\n            ret = callback ? callback.apply(defined[name], args) : undefined;\n\n            if (name) {\n                //If setting exports via \"module\" is in play,\n                //favor that over return value and exports. After that,\n                //favor a non-undefined return value over exports use.\n                if (cjsModule && cjsModule.exports !== undef &&\n                        cjsModule.exports !== defined[name]) {\n                    defined[name] = cjsModule.exports;\n                } else if (ret !== undef || !usingExports) {\n                    //Use the return value from the function.\n                    defined[name] = ret;\n                }\n            }\n        } else if (name) {\n            //May just be an object definition for the module. Only\n            //worry about defining if have a module name.\n            defined[name] = callback;\n        }\n    };\n\n    requirejs = require = req = function (deps, callback, relName, forceSync, alt) {\n        if (typeof deps === \"string\") {\n            if (handlers[deps]) {\n                //callback in this case is really relName\n                return handlers[deps](callback);\n            }\n            //Just return the module wanted. In this scenario, the\n            //deps arg is the module name, and second arg (if passed)\n            //is just the relName.\n            //Normalize module name, if it contains . or ..\n            return callDep(makeMap(deps, callback).f);\n        } else if (!deps.splice) {\n            //deps is a config object, not an array.\n            config = deps;\n            if (config.deps) {\n                req(config.deps, config.callback);\n            }\n            if (!callback) {\n                return;\n            }\n\n            if (callback.splice) {\n                //callback is an array, which means it is a dependency list.\n                //Adjust args if there are dependencies\n                deps = callback;\n                callback = relName;\n                relName = null;\n            } else {\n                deps = undef;\n            }\n        }\n\n        //Support require(['a'])\n        callback = callback || function () {};\n\n        //If relName is a function, it is an errback handler,\n        //so remove it.\n        if (typeof relName === 'function') {\n            relName = forceSync;\n            forceSync = alt;\n        }\n\n        //Simulate async callback;\n        if (forceSync) {\n            main(undef, deps, callback, relName);\n        } else {\n            //Using a non-zero value because of concern for what old browsers\n            //do, and latest browsers \"upgrade\" to 4 if lower value is used:\n            //http://www.whatwg.org/specs/web-apps/current-work/multipage/timers.html#dom-windowtimers-settimeout:\n            //If want a value immediately, use require('id') instead -- something\n            //that works in almond on the global level, but not guaranteed and\n            //unlikely to work in other AMD implementations.\n            setTimeout(function () {\n                main(undef, deps, callback, relName);\n            }, 4);\n        }\n\n        return req;\n    };\n\n    /**\n     * Just drops the config on the floor, but returns req in case\n     * the config return value is used.\n     */\n    req.config = function (cfg) {\n        return req(cfg);\n    };\n\n    /**\n     * Expose module registry for debugging and tooling\n     */\n    requirejs._defined = defined;\n\n    define = function (name, deps, callback) {\n        if (typeof name !== 'string') {\n            throw new Error('See almond README: incorrect module build, no module name');\n        }\n\n        //This module may not have dependencies\n        if (!deps.splice) {\n            //deps is not an array, so probably means\n            //an object literal or factory function for\n            //the value. Adjust args.\n            callback = deps;\n            deps = [];\n        }\n\n        if (!hasProp(defined, name) && !hasProp(waiting, name)) {\n            waiting[name] = [name, deps, callback];\n        }\n    };\n\n    define.amd = {\n        jQuery: true\n    };\n}());\n\nS2.requirejs = requirejs;S2.require = require;S2.define = define;\n}\n}());\nS2.define(\"almond\", function(){});\n\n/* global jQuery:false, $:false */\nS2.define('jquery',[],function () {\n  var _$ = jQuery || $;\n\n  if (_$ == null && console && console.error) {\n    console.error(\n      'Select2: An instance of jQuery or a jQuery-compatible library was not ' +\n      'found. Make sure that you are including jQuery before Select2 on your ' +\n      'web page.'\n    );\n  }\n\n  return _$;\n});\n\nS2.define('select2/utils',[\n  'jquery'\n], function ($) {\n  var Utils = {};\n\n  Utils.Extend = function (ChildClass, SuperClass) {\n    var __hasProp = {}.hasOwnProperty;\n\n    function BaseConstructor () {\n      this.constructor = ChildClass;\n    }\n\n    for (var key in SuperClass) {\n      if (__hasProp.call(SuperClass, key)) {\n        ChildClass[key] = SuperClass[key];\n      }\n    }\n\n    BaseConstructor.prototype = SuperClass.prototype;\n    ChildClass.prototype = new BaseConstructor();\n    ChildClass.__super__ = SuperClass.prototype;\n\n    return ChildClass;\n  };\n\n  function getMethods (theClass) {\n    var proto = theClass.prototype;\n\n    var methods = [];\n\n    for (var methodName in proto) {\n      var m = proto[methodName];\n\n      if (typeof m !== 'function') {\n        continue;\n      }\n\n      if (methodName === 'constructor') {\n        continue;\n      }\n\n      methods.push(methodName);\n    }\n\n    return methods;\n  }\n\n  Utils.Decorate = function (SuperClass, DecoratorClass) {\n    var decoratedMethods = getMethods(DecoratorClass);\n    var superMethods = getMethods(SuperClass);\n\n    function DecoratedClass () {\n      var unshift = Array.prototype.unshift;\n\n      var argCount = DecoratorClass.prototype.constructor.length;\n\n      var calledConstructor = SuperClass.prototype.constructor;\n\n      if (argCount > 0) {\n        unshift.call(arguments, SuperClass.prototype.constructor);\n\n        calledConstructor = DecoratorClass.prototype.constructor;\n      }\n\n      calledConstructor.apply(this, arguments);\n    }\n\n    DecoratorClass.displayName = SuperClass.displayName;\n\n    function ctr () {\n      this.constructor = DecoratedClass;\n    }\n\n    DecoratedClass.prototype = new ctr();\n\n    for (var m = 0; m < superMethods.length; m++) {\n        var superMethod = superMethods[m];\n\n        DecoratedClass.prototype[superMethod] =\n          SuperClass.prototype[superMethod];\n    }\n\n    var calledMethod = function (methodName) {\n      // Stub out the original method if it's not decorating an actual method\n      var originalMethod = function () {};\n\n      if (methodName in DecoratedClass.prototype) {\n        originalMethod = DecoratedClass.prototype[methodName];\n      }\n\n      var decoratedMethod = DecoratorClass.prototype[methodName];\n\n      return function () {\n        var unshift = Array.prototype.unshift;\n\n        unshift.call(arguments, originalMethod);\n\n        return decoratedMethod.apply(this, arguments);\n      };\n    };\n\n    for (var d = 0; d < decoratedMethods.length; d++) {\n      var decoratedMethod = decoratedMethods[d];\n\n      DecoratedClass.prototype[decoratedMethod] = calledMethod(decoratedMethod);\n    }\n\n    return DecoratedClass;\n  };\n\n  var Observable = function () {\n    this.listeners = {};\n  };\n\n  Observable.prototype.on = function (event, callback) {\n    this.listeners = this.listeners || {};\n\n    if (event in this.listeners) {\n      this.listeners[event].push(callback);\n    } else {\n      this.listeners[event] = [callback];\n    }\n  };\n\n  Observable.prototype.trigger = function (event) {\n    var slice = Array.prototype.slice;\n\n    this.listeners = this.listeners || {};\n\n    if (event in this.listeners) {\n      this.invoke(this.listeners[event], slice.call(arguments, 1));\n    }\n\n    if ('*' in this.listeners) {\n      this.invoke(this.listeners['*'], arguments);\n    }\n  };\n\n  Observable.prototype.invoke = function (listeners, params) {\n    for (var i = 0, len = listeners.length; i < len; i++) {\n      listeners[i].apply(this, params);\n    }\n  };\n\n  Utils.Observable = Observable;\n\n  Utils.generateChars = function (length) {\n    var chars = '';\n\n    for (var i = 0; i < length; i++) {\n      var randomChar = Math.floor(Math.random() * 36);\n      chars += randomChar.toString(36);\n    }\n\n    return chars;\n  };\n\n  Utils.bind = function (func, context) {\n    return function () {\n      func.apply(context, arguments);\n    };\n  };\n\n  Utils._convertData = function (data) {\n    for (var originalKey in data) {\n      var keys = originalKey.split('-');\n\n      var dataLevel = data;\n\n      if (keys.length === 1) {\n        continue;\n      }\n\n      for (var k = 0; k < keys.length; k++) {\n        var key = keys[k];\n\n        // Lowercase the first letter\n        // By default, dash-separated becomes camelCase\n        key = key.substring(0, 1).toLowerCase() + key.substring(1);\n\n        if (!(key in dataLevel)) {\n          dataLevel[key] = {};\n        }\n\n        if (k == keys.length - 1) {\n          dataLevel[key] = data[originalKey];\n        }\n\n        dataLevel = dataLevel[key];\n      }\n\n      delete data[originalKey];\n    }\n\n    return data;\n  };\n\n  Utils.hasScroll = function (index, el) {\n    // Adapted from the function created by @ShadowScripter\n    // and adapted by @BillBarry on the Stack Exchange Code Review website.\n    // The original code can be found at\n    // http://codereview.stackexchange.com/q/13338\n    // and was designed to be used with the Sizzle selector engine.\n\n    var $el = $(el);\n    var overflowX = el.style.overflowX;\n    var overflowY = el.style.overflowY;\n\n    //Check both x and y declarations\n    if (overflowX === overflowY &&\n        (overflowY === 'hidden' || overflowY === 'visible')) {\n      return false;\n    }\n\n    if (overflowX === 'scroll' || overflowY === 'scroll') {\n      return true;\n    }\n\n    return ($el.innerHeight() < el.scrollHeight ||\n      $el.innerWidth() < el.scrollWidth);\n  };\n\n  Utils.escapeMarkup = function (markup) {\n    var replaceMap = {\n      '\\\\': '&#92;',\n      '&': '&amp;',\n      '<': '&lt;',\n      '>': '&gt;',\n      '\"': '&quot;',\n      '\\'': '&#39;',\n      '/': '&#47;'\n    };\n\n    // Do not try to escape the markup if it's not a string\n    if (typeof markup !== 'string') {\n      return markup;\n    }\n\n    return String(markup).replace(/[&<>\"'\\/\\\\]/g, function (match) {\n      return replaceMap[match];\n    });\n  };\n\n  // Append an array of jQuery nodes to a given element.\n  Utils.appendMany = function ($element, $nodes) {\n    // jQuery 1.7.x does not support $.fn.append() with an array\n    // Fall back to a jQuery object collection using $.fn.add()\n    if ($.fn.jquery.substr(0, 3) === '1.7') {\n      var $jqNodes = $();\n\n      $.map($nodes, function (node) {\n        $jqNodes = $jqNodes.add(node);\n      });\n\n      $nodes = $jqNodes;\n    }\n\n    $element.append($nodes);\n  };\n\n  return Utils;\n});\n\nS2.define('select2/results',[\n  'jquery',\n  './utils'\n], function ($, Utils) {\n  function Results ($element, options, dataAdapter) {\n    this.$element = $element;\n    this.data = dataAdapter;\n    this.options = options;\n\n    Results.__super__.constructor.call(this);\n  }\n\n  Utils.Extend(Results, Utils.Observable);\n\n  Results.prototype.render = function () {\n    var $results = $(\n      '<ul class=\"select2-results__options\" role=\"tree\"></ul>'\n    );\n\n    if (this.options.get('multiple')) {\n      $results.attr('aria-multiselectable', 'true');\n    }\n\n    this.$results = $results;\n\n    return $results;\n  };\n\n  Results.prototype.clear = function () {\n    this.$results.empty();\n  };\n\n  Results.prototype.displayMessage = function (params) {\n    var escapeMarkup = this.options.get('escapeMarkup');\n\n    this.clear();\n    this.hideLoading();\n\n    var $message = $(\n      '<li role=\"treeitem\" aria-live=\"assertive\"' +\n      ' class=\"select2-results__option\"></li>'\n    );\n\n    var message = this.options.get('translations').get(params.message);\n\n    $message.append(\n      escapeMarkup(\n        message(params.args)\n      )\n    );\n\n    $message[0].className += ' select2-results__message';\n\n    this.$results.append($message);\n  };\n\n  Results.prototype.hideMessages = function () {\n    this.$results.find('.select2-results__message').remove();\n  };\n\n  Results.prototype.append = function (data) {\n    this.hideLoading();\n\n    var $options = [];\n\n    if (data.results == null || data.results.length === 0) {\n      if (this.$results.children().length === 0) {\n        this.trigger('results:message', {\n          message: 'noResults'\n        });\n      }\n\n      return;\n    }\n\n    data.results = this.sort(data.results);\n\n    for (var d = 0; d < data.results.length; d++) {\n      var item = data.results[d];\n\n      var $option = this.option(item);\n\n      $options.push($option);\n    }\n\n    this.$results.append($options);\n  };\n\n  Results.prototype.position = function ($results, $dropdown) {\n    var $resultsContainer = $dropdown.find('.select2-results');\n    $resultsContainer.append($results);\n  };\n\n  Results.prototype.sort = function (data) {\n    var sorter = this.options.get('sorter');\n\n    return sorter(data);\n  };\n\n  Results.prototype.setClasses = function () {\n    var self = this;\n\n    this.data.current(function (selected) {\n      var selectedIds = $.map(selected, function (s) {\n        return s.id.toString();\n      });\n\n      var $options = self.$results\n        .find('.select2-results__option[aria-selected]');\n\n      $options.each(function () {\n        var $option = $(this);\n\n        var item = $.data(this, 'data');\n\n        // id needs to be converted to a string when comparing\n        var id = '' + item.id;\n\n        if ((item.element != null && item.element.selected) ||\n            (item.element == null && $.inArray(id, selectedIds) > -1)) {\n          $option.attr('aria-selected', 'true');\n        } else {\n          $option.attr('aria-selected', 'false');\n        }\n      });\n\n      var $selected = $options.filter('[aria-selected=true]');\n\n      // Check if there are any selected options\n      if ($selected.length > 0) {\n        // If there are selected options, highlight the first\n        $selected.first().trigger('mouseenter');\n      } else {\n        // If there are no selected options, highlight the first option\n        // in the dropdown\n        $options.first().trigger('mouseenter');\n      }\n    });\n  };\n\n  Results.prototype.showLoading = function (params) {\n    this.hideLoading();\n\n    var loadingMore = this.options.get('translations').get('searching');\n\n    var loading = {\n      disabled: true,\n      loading: true,\n      text: loadingMore(params)\n    };\n    var $loading = this.option(loading);\n    $loading.className += ' loading-results';\n\n    this.$results.prepend($loading);\n  };\n\n  Results.prototype.hideLoading = function () {\n    this.$results.find('.loading-results').remove();\n  };\n\n  Results.prototype.option = function (data) {\n    var option = document.createElement('li');\n    option.className = 'select2-results__option';\n\n    var attrs = {\n      'role': 'treeitem',\n      'aria-selected': 'false'\n    };\n\n    if (data.disabled) {\n      delete attrs['aria-selected'];\n      attrs['aria-disabled'] = 'true';\n    }\n\n    if (data.id == null) {\n      delete attrs['aria-selected'];\n    }\n\n    if (data._resultId != null) {\n      option.id = data._resultId;\n    }\n\n    if (data.title) {\n      option.title = data.title;\n    }\n\n    if (data.children) {\n      attrs.role = 'group';\n      attrs['aria-label'] = data.text;\n      delete attrs['aria-selected'];\n    }\n\n    for (var attr in attrs) {\n      var val = attrs[attr];\n\n      option.setAttribute(attr, val);\n    }\n\n    if (data.children) {\n      var $option = $(option);\n\n      var label = document.createElement('strong');\n      label.className = 'select2-results__group';\n\n      var $label = $(label);\n      this.template(data, label);\n\n      var $children = [];\n\n      for (var c = 0; c < data.children.length; c++) {\n        var child = data.children[c];\n\n        var $child = this.option(child);\n\n        $children.push($child);\n      }\n\n      var $childrenContainer = $('<ul></ul>', {\n        'class': 'select2-results__options select2-results__options--nested'\n      });\n\n      $childrenContainer.append($children);\n\n      $option.append(label);\n      $option.append($childrenContainer);\n    } else {\n      this.template(data, option);\n    }\n\n    $.data(option, 'data', data);\n\n    return option;\n  };\n\n  Results.prototype.bind = function (container, $container) {\n    var self = this;\n\n    var id = container.id + '-results';\n\n    this.$results.attr('id', id);\n\n    container.on('results:all', function (params) {\n      self.clear();\n      self.append(params.data);\n\n      if (container.isOpen()) {\n        self.setClasses();\n      }\n    });\n\n    container.on('results:append', function (params) {\n      self.append(params.data);\n\n      if (container.isOpen()) {\n        self.setClasses();\n      }\n    });\n\n    container.on('query', function (params) {\n      self.hideMessages();\n      self.showLoading(params);\n    });\n\n    container.on('select', function () {\n      if (!container.isOpen()) {\n        return;\n      }\n\n      self.setClasses();\n    });\n\n    container.on('unselect', function () {\n      if (!container.isOpen()) {\n        return;\n      }\n\n      self.setClasses();\n    });\n\n    container.on('open', function () {\n      // When the dropdown is open, aria-expended=\"true\"\n      self.$results.attr('aria-expanded', 'true');\n      self.$results.attr('aria-hidden', 'false');\n\n      self.setClasses();\n      self.ensureHighlightVisible();\n    });\n\n    container.on('close', function () {\n      // When the dropdown is closed, aria-expended=\"false\"\n      self.$results.attr('aria-expanded', 'false');\n      self.$results.attr('aria-hidden', 'true');\n      self.$results.removeAttr('aria-activedescendant');\n    });\n\n    container.on('results:toggle', function () {\n      var $highlighted = self.getHighlightedResults();\n\n      if ($highlighted.length === 0) {\n        return;\n      }\n\n      $highlighted.trigger('mouseup');\n    });\n\n    container.on('results:select', function () {\n      var $highlighted = self.getHighlightedResults();\n\n      if ($highlighted.length === 0) {\n        return;\n      }\n\n      var data = $highlighted.data('data');\n\n      if ($highlighted.attr('aria-selected') == 'true') {\n        self.trigger('close', {});\n      } else {\n        self.trigger('select', {\n          data: data\n        });\n      }\n    });\n\n    container.on('results:previous', function () {\n      var $highlighted = self.getHighlightedResults();\n\n      var $options = self.$results.find('[aria-selected]');\n\n      var currentIndex = $options.index($highlighted);\n\n      // If we are already at te top, don't move further\n      if (currentIndex === 0) {\n        return;\n      }\n\n      var nextIndex = currentIndex - 1;\n\n      // If none are highlighted, highlight the first\n      if ($highlighted.length === 0) {\n        nextIndex = 0;\n      }\n\n      var $next = $options.eq(nextIndex);\n\n      $next.trigger('mouseenter');\n\n      var currentOffset = self.$results.offset().top;\n      var nextTop = $next.offset().top;\n      var nextOffset = self.$results.scrollTop() + (nextTop - currentOffset);\n\n      if (nextIndex === 0) {\n        self.$results.scrollTop(0);\n      } else if (nextTop - currentOffset < 0) {\n        self.$results.scrollTop(nextOffset);\n      }\n    });\n\n    container.on('results:next', function () {\n      var $highlighted = self.getHighlightedResults();\n\n      var $options = self.$results.find('[aria-selected]');\n\n      var currentIndex = $options.index($highlighted);\n\n      var nextIndex = currentIndex + 1;\n\n      // If we are at the last option, stay there\n      if (nextIndex >= $options.length) {\n        return;\n      }\n\n      var $next = $options.eq(nextIndex);\n\n      $next.trigger('mouseenter');\n\n      var currentOffset = self.$results.offset().top +\n        self.$results.outerHeight(false);\n      var nextBottom = $next.offset().top + $next.outerHeight(false);\n      var nextOffset = self.$results.scrollTop() + nextBottom - currentOffset;\n\n      if (nextIndex === 0) {\n        self.$results.scrollTop(0);\n      } else if (nextBottom > currentOffset) {\n        self.$results.scrollTop(nextOffset);\n      }\n    });\n\n    container.on('results:focus', function (params) {\n      params.element.addClass('select2-results__option--highlighted');\n    });\n\n    container.on('results:message', function (params) {\n      self.displayMessage(params);\n    });\n\n    if ($.fn.mousewheel) {\n      this.$results.on('mousewheel', function (e) {\n        var top = self.$results.scrollTop();\n\n        var bottom = (\n          self.$results.get(0).scrollHeight -\n          self.$results.scrollTop() +\n          e.deltaY\n        );\n\n        var isAtTop = e.deltaY > 0 && top - e.deltaY <= 0;\n        var isAtBottom = e.deltaY < 0 && bottom <= self.$results.height();\n\n        if (isAtTop) {\n          self.$results.scrollTop(0);\n\n          e.preventDefault();\n          e.stopPropagation();\n        } else if (isAtBottom) {\n          self.$results.scrollTop(\n            self.$results.get(0).scrollHeight - self.$results.height()\n          );\n\n          e.preventDefault();\n          e.stopPropagation();\n        }\n      });\n    }\n\n    this.$results.on('mouseup', '.select2-results__option[aria-selected]',\n      function (evt) {\n      var $this = $(this);\n\n      var data = $this.data('data');\n\n      if ($this.attr('aria-selected') === 'true') {\n        if (self.options.get('multiple')) {\n          self.trigger('unselect', {\n            originalEvent: evt,\n            data: data\n          });\n        } else {\n          self.trigger('close', {});\n        }\n\n        return;\n      }\n\n      self.trigger('select', {\n        originalEvent: evt,\n        data: data\n      });\n    });\n\n    this.$results.on('mouseenter', '.select2-results__option[aria-selected]',\n      function (evt) {\n      var data = $(this).data('data');\n\n      self.getHighlightedResults()\n          .removeClass('select2-results__option--highlighted');\n\n      self.trigger('results:focus', {\n        data: data,\n        element: $(this)\n      });\n    });\n  };\n\n  Results.prototype.getHighlightedResults = function () {\n    var $highlighted = this.$results\n    .find('.select2-results__option--highlighted');\n\n    return $highlighted;\n  };\n\n  Results.prototype.destroy = function () {\n    this.$results.remove();\n  };\n\n  Results.prototype.ensureHighlightVisible = function () {\n    var $highlighted = this.getHighlightedResults();\n\n    if ($highlighted.length === 0) {\n      return;\n    }\n\n    var $options = this.$results.find('[aria-selected]');\n\n    var currentIndex = $options.index($highlighted);\n\n    var currentOffset = this.$results.offset().top;\n    var nextTop = $highlighted.offset().top;\n    var nextOffset = this.$results.scrollTop() + (nextTop - currentOffset);\n\n    var offsetDelta = nextTop - currentOffset;\n    nextOffset -= $highlighted.outerHeight(false) * 2;\n\n    if (currentIndex <= 2) {\n      this.$results.scrollTop(0);\n    } else if (offsetDelta > this.$results.outerHeight() || offsetDelta < 0) {\n      this.$results.scrollTop(nextOffset);\n    }\n  };\n\n  Results.prototype.template = function (result, container) {\n    var template = this.options.get('templateResult');\n    var escapeMarkup = this.options.get('escapeMarkup');\n\n    var content = template(result, container);\n\n    if (content == null) {\n      container.style.display = 'none';\n    } else if (typeof content === 'string') {\n      container.innerHTML = escapeMarkup(content);\n    } else {\n      $(container).append(content);\n    }\n  };\n\n  return Results;\n});\n\nS2.define('select2/keys',[\n\n], function () {\n  var KEYS = {\n    BACKSPACE: 8,\n    TAB: 9,\n    ENTER: 13,\n    SHIFT: 16,\n    CTRL: 17,\n    ALT: 18,\n    ESC: 27,\n    SPACE: 32,\n    PAGE_UP: 33,\n    PAGE_DOWN: 34,\n    END: 35,\n    HOME: 36,\n    LEFT: 37,\n    UP: 38,\n    RIGHT: 39,\n    DOWN: 40,\n    DELETE: 46\n  };\n\n  return KEYS;\n});\n\nS2.define('select2/selection/base',[\n  'jquery',\n  '../utils',\n  '../keys'\n], function ($, Utils, KEYS) {\n  function BaseSelection ($element, options) {\n    this.$element = $element;\n    this.options = options;\n\n    BaseSelection.__super__.constructor.call(this);\n  }\n\n  Utils.Extend(BaseSelection, Utils.Observable);\n\n  BaseSelection.prototype.render = function () {\n    var $selection = $(\n      '<span class=\"select2-selection\" role=\"combobox\" ' +\n      ' aria-haspopup=\"true\" aria-expanded=\"false\">' +\n      '</span>'\n    );\n\n    this._tabindex = 0;\n\n    if (this.$element.data('old-tabindex') != null) {\n      this._tabindex = this.$element.data('old-tabindex');\n    } else if (this.$element.attr('tabindex') != null) {\n      this._tabindex = this.$element.attr('tabindex');\n    }\n\n    $selection.attr('title', this.$element.attr('title'));\n    $selection.attr('tabindex', this._tabindex);\n\n    this.$selection = $selection;\n\n    return $selection;\n  };\n\n  BaseSelection.prototype.bind = function (container, $container) {\n    var self = this;\n\n    var id = container.id + '-container';\n    var resultsId = container.id + '-results';\n\n    this.container = container;\n\n    this.$selection.on('focus', function (evt) {\n      self.trigger('focus', evt);\n    });\n\n    this.$selection.on('blur', function (evt) {\n      self._handleBlur(evt);\n    });\n\n    this.$selection.on('keydown', function (evt) {\n      self.trigger('keypress', evt);\n\n      if (evt.which === KEYS.SPACE) {\n        evt.preventDefault();\n      }\n    });\n\n    container.on('results:focus', function (params) {\n      self.$selection.attr('aria-activedescendant', params.data._resultId);\n    });\n\n    container.on('selection:update', function (params) {\n      self.update(params.data);\n    });\n\n    container.on('open', function () {\n      // When the dropdown is open, aria-expanded=\"true\"\n      self.$selection.attr('aria-expanded', 'true');\n      self.$selection.attr('aria-owns', resultsId);\n\n      self._attachCloseHandler(container);\n    });\n\n    container.on('close', function () {\n      // When the dropdown is closed, aria-expanded=\"false\"\n      self.$selection.attr('aria-expanded', 'false');\n      self.$selection.removeAttr('aria-activedescendant');\n      self.$selection.removeAttr('aria-owns');\n\n      self.$selection.focus();\n\n      self._detachCloseHandler(container);\n    });\n\n    container.on('enable', function () {\n      self.$selection.attr('tabindex', self._tabindex);\n    });\n\n    container.on('disable', function () {\n      self.$selection.attr('tabindex', '-1');\n    });\n  };\n\n  BaseSelection.prototype._handleBlur = function (evt) {\n    var self = this;\n\n    // This needs to be delayed as the active element is the body when the tab\n    // key is pressed, possibly along with others.\n    window.setTimeout(function () {\n      // Don't trigger `blur` if the focus is still in the selection\n      if (\n        (document.activeElement == self.$selection[0]) ||\n        ($.contains(self.$selection[0], document.activeElement))\n      ) {\n        return;\n      }\n\n      self.trigger('blur', evt);\n    }, 1);\n  };\n\n  BaseSelection.prototype._attachCloseHandler = function (container) {\n    var self = this;\n\n    $(document.body).on('mousedown.select2.' + container.id, function (e) {\n      var $target = $(e.target);\n\n      var $select = $target.closest('.select2');\n\n      var $all = $('.select2.select2-container--open');\n\n      $all.each(function () {\n        var $this = $(this);\n\n        if (this == $select[0]) {\n          return;\n        }\n\n        var $element = $this.data('element');\n\n        $element.select2('close');\n      });\n    });\n  };\n\n  BaseSelection.prototype._detachCloseHandler = function (container) {\n    $(document.body).off('mousedown.select2.' + container.id);\n  };\n\n  BaseSelection.prototype.position = function ($selection, $container) {\n    var $selectionContainer = $container.find('.selection');\n    $selectionContainer.append($selection);\n  };\n\n  BaseSelection.prototype.destroy = function () {\n    this._detachCloseHandler(this.container);\n  };\n\n  BaseSelection.prototype.update = function (data) {\n    throw new Error('The `update` method must be defined in child classes.');\n  };\n\n  return BaseSelection;\n});\n\nS2.define('select2/selection/single',[\n  'jquery',\n  './base',\n  '../utils',\n  '../keys'\n], function ($, BaseSelection, Utils, KEYS) {\n  function SingleSelection () {\n    SingleSelection.__super__.constructor.apply(this, arguments);\n  }\n\n  Utils.Extend(SingleSelection, BaseSelection);\n\n  SingleSelection.prototype.render = function () {\n    var $selection = SingleSelection.__super__.render.call(this);\n\n    $selection.addClass('select2-selection--single');\n\n    $selection.html(\n      '<span class=\"select2-selection__rendered\"></span>' +\n      '<span class=\"select2-selection__arrow\" role=\"presentation\">' +\n        '<b role=\"presentation\"></b>' +\n      '</span>'\n    );\n\n    return $selection;\n  };\n\n  SingleSelection.prototype.bind = function (container, $container) {\n    var self = this;\n\n    SingleSelection.__super__.bind.apply(this, arguments);\n\n    var id = container.id + '-container';\n\n    this.$selection.find('.select2-selection__rendered').attr('id', id);\n    this.$selection.attr('aria-labelledby', id);\n\n    this.$selection.on('mousedown', function (evt) {\n      // Only respond to left clicks\n      if (evt.which !== 1) {\n        return;\n      }\n\n      self.trigger('toggle', {\n        originalEvent: evt\n      });\n    });\n\n    this.$selection.on('focus', function (evt) {\n      // User focuses on the container\n    });\n\n    this.$selection.on('blur', function (evt) {\n      // User exits the container\n    });\n\n    container.on('selection:update', function (params) {\n      self.update(params.data);\n    });\n  };\n\n  SingleSelection.prototype.clear = function () {\n    this.$selection.find('.select2-selection__rendered').empty();\n  };\n\n  SingleSelection.prototype.display = function (data, container) {\n    var template = this.options.get('templateSelection');\n    var escapeMarkup = this.options.get('escapeMarkup');\n\n    return escapeMarkup(template(data, container));\n  };\n\n  SingleSelection.prototype.selectionContainer = function () {\n    return $('<span></span>');\n  };\n\n  SingleSelection.prototype.update = function (data) {\n    if (data.length === 0) {\n      this.clear();\n      return;\n    }\n\n    var selection = data[0];\n\n    var $rendered = this.$selection.find('.select2-selection__rendered');\n    var formatted = this.display(selection, $rendered);\n\n    $rendered.empty().append(formatted);\n    $rendered.prop('title', selection.title || selection.text);\n  };\n\n  return SingleSelection;\n});\n\nS2.define('select2/selection/multiple',[\n  'jquery',\n  './base',\n  '../utils'\n], function ($, BaseSelection, Utils) {\n  function MultipleSelection ($element, options) {\n    MultipleSelection.__super__.constructor.apply(this, arguments);\n  }\n\n  Utils.Extend(MultipleSelection, BaseSelection);\n\n  MultipleSelection.prototype.render = function () {\n    var $selection = MultipleSelection.__super__.render.call(this);\n\n    $selection.addClass('select2-selection--multiple');\n\n    $selection.html(\n      '<ul class=\"select2-selection__rendered\"></ul>'\n    );\n\n    return $selection;\n  };\n\n  MultipleSelection.prototype.bind = function (container, $container) {\n    var self = this;\n\n    MultipleSelection.__super__.bind.apply(this, arguments);\n\n    this.$selection.on('click', function (evt) {\n      self.trigger('toggle', {\n        originalEvent: evt\n      });\n    });\n\n    this.$selection.on(\n      'click',\n      '.select2-selection__choice__remove',\n      function (evt) {\n        // Ignore the event if it is disabled\n        if (self.options.get('disabled')) {\n          return;\n        }\n\n        var $remove = $(this);\n        var $selection = $remove.parent();\n\n        var data = $selection.data('data');\n\n        self.trigger('unselect', {\n          originalEvent: evt,\n          data: data\n        });\n      }\n    );\n  };\n\n  MultipleSelection.prototype.clear = function () {\n    this.$selection.find('.select2-selection__rendered').empty();\n  };\n\n  MultipleSelection.prototype.display = function (data, container) {\n    var template = this.options.get('templateSelection');\n    var escapeMarkup = this.options.get('escapeMarkup');\n\n    return escapeMarkup(template(data, container));\n  };\n\n  MultipleSelection.prototype.selectionContainer = function () {\n    var $container = $(\n      '<li class=\"select2-selection__choice\">' +\n        '<span class=\"select2-selection__choice__remove\" role=\"presentation\">' +\n          '&times;' +\n        '</span>' +\n      '</li>'\n    );\n\n    return $container;\n  };\n\n  MultipleSelection.prototype.update = function (data) {\n    this.clear();\n\n    if (data.length === 0) {\n      return;\n    }\n\n    var $selections = [];\n\n    for (var d = 0; d < data.length; d++) {\n      var selection = data[d];\n\n      var $selection = this.selectionContainer();\n      var formatted = this.display(selection, $selection);\n\n      $selection.append(formatted);\n      $selection.prop('title', selection.title || selection.text);\n\n      $selection.data('data', selection);\n\n      $selections.push($selection);\n    }\n\n    var $rendered = this.$selection.find('.select2-selection__rendered');\n\n    Utils.appendMany($rendered, $selections);\n  };\n\n  return MultipleSelection;\n});\n\nS2.define('select2/selection/placeholder',[\n  '../utils'\n], function (Utils) {\n  function Placeholder (decorated, $element, options) {\n    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));\n\n    decorated.call(this, $element, options);\n  }\n\n  Placeholder.prototype.normalizePlaceholder = function (_, placeholder) {\n    if (typeof placeholder === 'string') {\n      placeholder = {\n        id: '',\n        text: placeholder\n      };\n    }\n\n    return placeholder;\n  };\n\n  Placeholder.prototype.createPlaceholder = function (decorated, placeholder) {\n    var $placeholder = this.selectionContainer();\n\n    $placeholder.html(this.display(placeholder));\n    $placeholder.addClass('select2-selection__placeholder')\n                .removeClass('select2-selection__choice');\n\n    return $placeholder;\n  };\n\n  Placeholder.prototype.update = function (decorated, data) {\n    var singlePlaceholder = (\n      data.length == 1 && data[0].id != this.placeholder.id\n    );\n    var multipleSelections = data.length > 1;\n\n    if (multipleSelections || singlePlaceholder) {\n      return decorated.call(this, data);\n    }\n\n    this.clear();\n\n    var $placeholder = this.createPlaceholder(this.placeholder);\n\n    this.$selection.find('.select2-selection__rendered').append($placeholder);\n  };\n\n  return Placeholder;\n});\n\nS2.define('select2/selection/allowClear',[\n  'jquery',\n  '../keys'\n], function ($, KEYS) {\n  function AllowClear () { }\n\n  AllowClear.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    decorated.call(this, container, $container);\n\n    if (this.placeholder == null) {\n      if (this.options.get('debug') && window.console && console.error) {\n        console.error(\n          'Select2: The `allowClear` option should be used in combination ' +\n          'with the `placeholder` option.'\n        );\n      }\n    }\n\n    this.$selection.on('mousedown', '.select2-selection__clear',\n      function (evt) {\n        self._handleClear(evt);\n    });\n\n    container.on('keypress', function (evt) {\n      self._handleKeyboardClear(evt, container);\n    });\n  };\n\n  AllowClear.prototype._handleClear = function (_, evt) {\n    // Ignore the event if it is disabled\n    if (this.options.get('disabled')) {\n      return;\n    }\n\n    var $clear = this.$selection.find('.select2-selection__clear');\n\n    // Ignore the event if nothing has been selected\n    if ($clear.length === 0) {\n      return;\n    }\n\n    evt.stopPropagation();\n\n    var data = $clear.data('data');\n\n    for (var d = 0; d < data.length; d++) {\n      var unselectData = {\n        data: data[d]\n      };\n\n      // Trigger the `unselect` event, so people can prevent it from being\n      // cleared.\n      this.trigger('unselect', unselectData);\n\n      // If the event was prevented, don't clear it out.\n      if (unselectData.prevented) {\n        return;\n      }\n    }\n\n    this.$element.val(this.placeholder.id).trigger('change');\n\n    this.trigger('toggle', {});\n  };\n\n  AllowClear.prototype._handleKeyboardClear = function (_, evt, container) {\n    if (container.isOpen()) {\n      return;\n    }\n\n    if (evt.which == KEYS.DELETE || evt.which == KEYS.BACKSPACE) {\n      this._handleClear(evt);\n    }\n  };\n\n  AllowClear.prototype.update = function (decorated, data) {\n    decorated.call(this, data);\n\n    if (this.$selection.find('.select2-selection__placeholder').length > 0 ||\n        data.length === 0) {\n      return;\n    }\n\n    var $remove = $(\n      '<span class=\"select2-selection__clear\">' +\n        '&times;' +\n      '</span>'\n    );\n    $remove.data('data', data);\n\n    this.$selection.find('.select2-selection__rendered').prepend($remove);\n  };\n\n  return AllowClear;\n});\n\nS2.define('select2/selection/search',[\n  'jquery',\n  '../utils',\n  '../keys'\n], function ($, Utils, KEYS) {\n  function Search (decorated, $element, options) {\n    decorated.call(this, $element, options);\n  }\n\n  Search.prototype.render = function (decorated) {\n    var $search = $(\n      '<li class=\"select2-search select2-search--inline\">' +\n        '<input class=\"select2-search__field\" type=\"search\" tabindex=\"-1\"' +\n        ' autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\"' +\n        ' spellcheck=\"false\" role=\"textbox\" aria-autocomplete=\"list\" />' +\n      '</li>'\n    );\n\n    this.$searchContainer = $search;\n    this.$search = $search.find('input');\n\n    var $rendered = decorated.call(this);\n\n    this._transferTabIndex();\n\n    return $rendered;\n  };\n\n  Search.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    decorated.call(this, container, $container);\n\n    container.on('open', function () {\n      self.$search.trigger('focus');\n    });\n\n    container.on('close', function () {\n      self.$search.val('');\n      self.$search.removeAttr('aria-activedescendant');\n      self.$search.trigger('focus');\n    });\n\n    container.on('enable', function () {\n      self.$search.prop('disabled', false);\n\n      self._transferTabIndex();\n    });\n\n    container.on('disable', function () {\n      self.$search.prop('disabled', true);\n    });\n\n    container.on('focus', function (evt) {\n      self.$search.trigger('focus');\n    });\n\n    container.on('results:focus', function (params) {\n      self.$search.attr('aria-activedescendant', params.id);\n    });\n\n    this.$selection.on('focusin', '.select2-search--inline', function (evt) {\n      self.trigger('focus', evt);\n    });\n\n    this.$selection.on('focusout', '.select2-search--inline', function (evt) {\n      self._handleBlur(evt);\n    });\n\n    this.$selection.on('keydown', '.select2-search--inline', function (evt) {\n      evt.stopPropagation();\n\n      self.trigger('keypress', evt);\n\n      self._keyUpPrevented = evt.isDefaultPrevented();\n\n      var key = evt.which;\n\n      if (key === KEYS.BACKSPACE && self.$search.val() === '') {\n        var $previousChoice = self.$searchContainer\n          .prev('.select2-selection__choice');\n\n        if ($previousChoice.length > 0) {\n          var item = $previousChoice.data('data');\n\n          self.searchRemoveChoice(item);\n\n          evt.preventDefault();\n        }\n      }\n    });\n\n    // Try to detect the IE version should the `documentMode` property that\n    // is stored on the document. This is only implemented in IE and is\n    // slightly cleaner than doing a user agent check.\n    // This property is not available in Edge, but Edge also doesn't have\n    // this bug.\n    var msie = document.documentMode;\n    var disableInputEvents = msie && msie <= 11;\n\n    // Workaround for browsers which do not support the `input` event\n    // This will prevent double-triggering of events for browsers which support\n    // both the `keyup` and `input` events.\n    this.$selection.on(\n      'input.searchcheck',\n      '.select2-search--inline',\n      function (evt) {\n        // IE will trigger the `input` event when a placeholder is used on a\n        // search box. To get around this issue, we are forced to ignore all\n        // `input` events in IE and keep using `keyup`.\n        if (disableInputEvents) {\n          self.$selection.off('input.search input.searchcheck');\n          return;\n        }\n\n        // Unbind the duplicated `keyup` event\n        self.$selection.off('keyup.search');\n      }\n    );\n\n    this.$selection.on(\n      'keyup.search input.search',\n      '.select2-search--inline',\n      function (evt) {\n        // IE will trigger the `input` event when a placeholder is used on a\n        // search box. To get around this issue, we are forced to ignore all\n        // `input` events in IE and keep using `keyup`.\n        if (disableInputEvents && evt.type === 'input') {\n          self.$selection.off('input.search input.searchcheck');\n          return;\n        }\n\n        var key = evt.which;\n\n        // We can freely ignore events from modifier keys\n        if (key == KEYS.SHIFT || key == KEYS.CTRL || key == KEYS.ALT) {\n          return;\n        }\n\n        // Tabbing will be handled during the `keydown` phase\n        if (key == KEYS.TAB) {\n          return;\n        }\n\n        self.handleSearch(evt);\n      }\n    );\n  };\n\n  /**\n   * This method will transfer the tabindex attribute from the rendered\n   * selection to the search box. This allows for the search box to be used as\n   * the primary focus instead of the selection container.\n   *\n   * @private\n   */\n  Search.prototype._transferTabIndex = function (decorated) {\n    this.$search.attr('tabindex', this.$selection.attr('tabindex'));\n    this.$selection.attr('tabindex', '-1');\n  };\n\n  Search.prototype.createPlaceholder = function (decorated, placeholder) {\n    this.$search.attr('placeholder', placeholder.text);\n  };\n\n  Search.prototype.update = function (decorated, data) {\n    var searchHadFocus = this.$search[0] == document.activeElement;\n\n    this.$search.attr('placeholder', '');\n\n    decorated.call(this, data);\n\n    this.$selection.find('.select2-selection__rendered')\n                   .append(this.$searchContainer);\n\n    this.resizeSearch();\n    if (searchHadFocus) {\n      this.$search.focus();\n    }\n  };\n\n  Search.prototype.handleSearch = function () {\n    this.resizeSearch();\n\n    if (!this._keyUpPrevented) {\n      var input = this.$search.val();\n\n      this.trigger('query', {\n        term: input\n      });\n    }\n\n    this._keyUpPrevented = false;\n  };\n\n  Search.prototype.searchRemoveChoice = function (decorated, item) {\n    this.trigger('unselect', {\n      data: item\n    });\n\n    this.$search.val(item.text);\n    this.handleSearch();\n  };\n\n  Search.prototype.resizeSearch = function () {\n    this.$search.css('width', '25px');\n\n    var width = '';\n\n    if (this.$search.attr('placeholder') !== '') {\n      width = this.$selection.find('.select2-selection__rendered').innerWidth();\n    } else {\n      var minimumWidth = this.$search.val().length + 1;\n\n      width = (minimumWidth * 0.75) + 'em';\n    }\n\n    this.$search.css('width', width);\n  };\n\n  return Search;\n});\n\nS2.define('select2/selection/eventRelay',[\n  'jquery'\n], function ($) {\n  function EventRelay () { }\n\n  EventRelay.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n    var relayEvents = [\n      'open', 'opening',\n      'close', 'closing',\n      'select', 'selecting',\n      'unselect', 'unselecting'\n    ];\n\n    var preventableEvents = ['opening', 'closing', 'selecting', 'unselecting'];\n\n    decorated.call(this, container, $container);\n\n    container.on('*', function (name, params) {\n      // Ignore events that should not be relayed\n      if ($.inArray(name, relayEvents) === -1) {\n        return;\n      }\n\n      // The parameters should always be an object\n      params = params || {};\n\n      // Generate the jQuery event for the Select2 event\n      var evt = $.Event('select2:' + name, {\n        params: params\n      });\n\n      self.$element.trigger(evt);\n\n      // Only handle preventable events if it was one\n      if ($.inArray(name, preventableEvents) === -1) {\n        return;\n      }\n\n      params.prevented = evt.isDefaultPrevented();\n    });\n  };\n\n  return EventRelay;\n});\n\nS2.define('select2/translation',[\n  'jquery',\n  'require'\n], function ($, require) {\n  function Translation (dict) {\n    this.dict = dict || {};\n  }\n\n  Translation.prototype.all = function () {\n    return this.dict;\n  };\n\n  Translation.prototype.get = function (key) {\n    return this.dict[key];\n  };\n\n  Translation.prototype.extend = function (translation) {\n    this.dict = $.extend({}, translation.all(), this.dict);\n  };\n\n  // Static functions\n\n  Translation._cache = {};\n\n  Translation.loadPath = function (path) {\n    if (!(path in Translation._cache)) {\n      var translations = require(path);\n\n      Translation._cache[path] = translations;\n    }\n\n    return new Translation(Translation._cache[path]);\n  };\n\n  return Translation;\n});\n\nS2.define('select2/diacritics',[\n\n], function () {\n  var diacritics = {\n    '\\u24B6': 'A',\n    '\\uFF21': 'A',\n    '\\u00C0': 'A',\n    '\\u00C1': 'A',\n    '\\u00C2': 'A',\n    '\\u1EA6': 'A',\n    '\\u1EA4': 'A',\n    '\\u1EAA': 'A',\n    '\\u1EA8': 'A',\n    '\\u00C3': 'A',\n    '\\u0100': 'A',\n    '\\u0102': 'A',\n    '\\u1EB0': 'A',\n    '\\u1EAE': 'A',\n    '\\u1EB4': 'A',\n    '\\u1EB2': 'A',\n    '\\u0226': 'A',\n    '\\u01E0': 'A',\n    '\\u00C4': 'A',\n    '\\u01DE': 'A',\n    '\\u1EA2': 'A',\n    '\\u00C5': 'A',\n    '\\u01FA': 'A',\n    '\\u01CD': 'A',\n    '\\u0200': 'A',\n    '\\u0202': 'A',\n    '\\u1EA0': 'A',\n    '\\u1EAC': 'A',\n    '\\u1EB6': 'A',\n    '\\u1E00': 'A',\n    '\\u0104': 'A',\n    '\\u023A': 'A',\n    '\\u2C6F': 'A',\n    '\\uA732': 'AA',\n    '\\u00C6': 'AE',\n    '\\u01FC': 'AE',\n    '\\u01E2': 'AE',\n    '\\uA734': 'AO',\n    '\\uA736': 'AU',\n    '\\uA738': 'AV',\n    '\\uA73A': 'AV',\n    '\\uA73C': 'AY',\n    '\\u24B7': 'B',\n    '\\uFF22': 'B',\n    '\\u1E02': 'B',\n    '\\u1E04': 'B',\n    '\\u1E06': 'B',\n    '\\u0243': 'B',\n    '\\u0182': 'B',\n    '\\u0181': 'B',\n    '\\u24B8': 'C',\n    '\\uFF23': 'C',\n    '\\u0106': 'C',\n    '\\u0108': 'C',\n    '\\u010A': 'C',\n    '\\u010C': 'C',\n    '\\u00C7': 'C',\n    '\\u1E08': 'C',\n    '\\u0187': 'C',\n    '\\u023B': 'C',\n    '\\uA73E': 'C',\n    '\\u24B9': 'D',\n    '\\uFF24': 'D',\n    '\\u1E0A': 'D',\n    '\\u010E': 'D',\n    '\\u1E0C': 'D',\n    '\\u1E10': 'D',\n    '\\u1E12': 'D',\n    '\\u1E0E': 'D',\n    '\\u0110': 'D',\n    '\\u018B': 'D',\n    '\\u018A': 'D',\n    '\\u0189': 'D',\n    '\\uA779': 'D',\n    '\\u01F1': 'DZ',\n    '\\u01C4': 'DZ',\n    '\\u01F2': 'Dz',\n    '\\u01C5': 'Dz',\n    '\\u24BA': 'E',\n    '\\uFF25': 'E',\n    '\\u00C8': 'E',\n    '\\u00C9': 'E',\n    '\\u00CA': 'E',\n    '\\u1EC0': 'E',\n    '\\u1EBE': 'E',\n    '\\u1EC4': 'E',\n    '\\u1EC2': 'E',\n    '\\u1EBC': 'E',\n    '\\u0112': 'E',\n    '\\u1E14': 'E',\n    '\\u1E16': 'E',\n    '\\u0114': 'E',\n    '\\u0116': 'E',\n    '\\u00CB': 'E',\n    '\\u1EBA': 'E',\n    '\\u011A': 'E',\n    '\\u0204': 'E',\n    '\\u0206': 'E',\n    '\\u1EB8': 'E',\n    '\\u1EC6': 'E',\n    '\\u0228': 'E',\n    '\\u1E1C': 'E',\n    '\\u0118': 'E',\n    '\\u1E18': 'E',\n    '\\u1E1A': 'E',\n    '\\u0190': 'E',\n    '\\u018E': 'E',\n    '\\u24BB': 'F',\n    '\\uFF26': 'F',\n    '\\u1E1E': 'F',\n    '\\u0191': 'F',\n    '\\uA77B': 'F',\n    '\\u24BC': 'G',\n    '\\uFF27': 'G',\n    '\\u01F4': 'G',\n    '\\u011C': 'G',\n    '\\u1E20': 'G',\n    '\\u011E': 'G',\n    '\\u0120': 'G',\n    '\\u01E6': 'G',\n    '\\u0122': 'G',\n    '\\u01E4': 'G',\n    '\\u0193': 'G',\n    '\\uA7A0': 'G',\n    '\\uA77D': 'G',\n    '\\uA77E': 'G',\n    '\\u24BD': 'H',\n    '\\uFF28': 'H',\n    '\\u0124': 'H',\n    '\\u1E22': 'H',\n    '\\u1E26': 'H',\n    '\\u021E': 'H',\n    '\\u1E24': 'H',\n    '\\u1E28': 'H',\n    '\\u1E2A': 'H',\n    '\\u0126': 'H',\n    '\\u2C67': 'H',\n    '\\u2C75': 'H',\n    '\\uA78D': 'H',\n    '\\u24BE': 'I',\n    '\\uFF29': 'I',\n    '\\u00CC': 'I',\n    '\\u00CD': 'I',\n    '\\u00CE': 'I',\n    '\\u0128': 'I',\n    '\\u012A': 'I',\n    '\\u012C': 'I',\n    '\\u0130': 'I',\n    '\\u00CF': 'I',\n    '\\u1E2E': 'I',\n    '\\u1EC8': 'I',\n    '\\u01CF': 'I',\n    '\\u0208': 'I',\n    '\\u020A': 'I',\n    '\\u1ECA': 'I',\n    '\\u012E': 'I',\n    '\\u1E2C': 'I',\n    '\\u0197': 'I',\n    '\\u24BF': 'J',\n    '\\uFF2A': 'J',\n    '\\u0134': 'J',\n    '\\u0248': 'J',\n    '\\u24C0': 'K',\n    '\\uFF2B': 'K',\n    '\\u1E30': 'K',\n    '\\u01E8': 'K',\n    '\\u1E32': 'K',\n    '\\u0136': 'K',\n    '\\u1E34': 'K',\n    '\\u0198': 'K',\n    '\\u2C69': 'K',\n    '\\uA740': 'K',\n    '\\uA742': 'K',\n    '\\uA744': 'K',\n    '\\uA7A2': 'K',\n    '\\u24C1': 'L',\n    '\\uFF2C': 'L',\n    '\\u013F': 'L',\n    '\\u0139': 'L',\n    '\\u013D': 'L',\n    '\\u1E36': 'L',\n    '\\u1E38': 'L',\n    '\\u013B': 'L',\n    '\\u1E3C': 'L',\n    '\\u1E3A': 'L',\n    '\\u0141': 'L',\n    '\\u023D': 'L',\n    '\\u2C62': 'L',\n    '\\u2C60': 'L',\n    '\\uA748': 'L',\n    '\\uA746': 'L',\n    '\\uA780': 'L',\n    '\\u01C7': 'LJ',\n    '\\u01C8': 'Lj',\n    '\\u24C2': 'M',\n    '\\uFF2D': 'M',\n    '\\u1E3E': 'M',\n    '\\u1E40': 'M',\n    '\\u1E42': 'M',\n    '\\u2C6E': 'M',\n    '\\u019C': 'M',\n    '\\u24C3': 'N',\n    '\\uFF2E': 'N',\n    '\\u01F8': 'N',\n    '\\u0143': 'N',\n    '\\u00D1': 'N',\n    '\\u1E44': 'N',\n    '\\u0147': 'N',\n    '\\u1E46': 'N',\n    '\\u0145': 'N',\n    '\\u1E4A': 'N',\n    '\\u1E48': 'N',\n    '\\u0220': 'N',\n    '\\u019D': 'N',\n    '\\uA790': 'N',\n    '\\uA7A4': 'N',\n    '\\u01CA': 'NJ',\n    '\\u01CB': 'Nj',\n    '\\u24C4': 'O',\n    '\\uFF2F': 'O',\n    '\\u00D2': 'O',\n    '\\u00D3': 'O',\n    '\\u00D4': 'O',\n    '\\u1ED2': 'O',\n    '\\u1ED0': 'O',\n    '\\u1ED6': 'O',\n    '\\u1ED4': 'O',\n    '\\u00D5': 'O',\n    '\\u1E4C': 'O',\n    '\\u022C': 'O',\n    '\\u1E4E': 'O',\n    '\\u014C': 'O',\n    '\\u1E50': 'O',\n    '\\u1E52': 'O',\n    '\\u014E': 'O',\n    '\\u022E': 'O',\n    '\\u0230': 'O',\n    '\\u00D6': 'O',\n    '\\u022A': 'O',\n    '\\u1ECE': 'O',\n    '\\u0150': 'O',\n    '\\u01D1': 'O',\n    '\\u020C': 'O',\n    '\\u020E': 'O',\n    '\\u01A0': 'O',\n    '\\u1EDC': 'O',\n    '\\u1EDA': 'O',\n    '\\u1EE0': 'O',\n    '\\u1EDE': 'O',\n    '\\u1EE2': 'O',\n    '\\u1ECC': 'O',\n    '\\u1ED8': 'O',\n    '\\u01EA': 'O',\n    '\\u01EC': 'O',\n    '\\u00D8': 'O',\n    '\\u01FE': 'O',\n    '\\u0186': 'O',\n    '\\u019F': 'O',\n    '\\uA74A': 'O',\n    '\\uA74C': 'O',\n    '\\u01A2': 'OI',\n    '\\uA74E': 'OO',\n    '\\u0222': 'OU',\n    '\\u24C5': 'P',\n    '\\uFF30': 'P',\n    '\\u1E54': 'P',\n    '\\u1E56': 'P',\n    '\\u01A4': 'P',\n    '\\u2C63': 'P',\n    '\\uA750': 'P',\n    '\\uA752': 'P',\n    '\\uA754': 'P',\n    '\\u24C6': 'Q',\n    '\\uFF31': 'Q',\n    '\\uA756': 'Q',\n    '\\uA758': 'Q',\n    '\\u024A': 'Q',\n    '\\u24C7': 'R',\n    '\\uFF32': 'R',\n    '\\u0154': 'R',\n    '\\u1E58': 'R',\n    '\\u0158': 'R',\n    '\\u0210': 'R',\n    '\\u0212': 'R',\n    '\\u1E5A': 'R',\n    '\\u1E5C': 'R',\n    '\\u0156': 'R',\n    '\\u1E5E': 'R',\n    '\\u024C': 'R',\n    '\\u2C64': 'R',\n    '\\uA75A': 'R',\n    '\\uA7A6': 'R',\n    '\\uA782': 'R',\n    '\\u24C8': 'S',\n    '\\uFF33': 'S',\n    '\\u1E9E': 'S',\n    '\\u015A': 'S',\n    '\\u1E64': 'S',\n    '\\u015C': 'S',\n    '\\u1E60': 'S',\n    '\\u0160': 'S',\n    '\\u1E66': 'S',\n    '\\u1E62': 'S',\n    '\\u1E68': 'S',\n    '\\u0218': 'S',\n    '\\u015E': 'S',\n    '\\u2C7E': 'S',\n    '\\uA7A8': 'S',\n    '\\uA784': 'S',\n    '\\u24C9': 'T',\n    '\\uFF34': 'T',\n    '\\u1E6A': 'T',\n    '\\u0164': 'T',\n    '\\u1E6C': 'T',\n    '\\u021A': 'T',\n    '\\u0162': 'T',\n    '\\u1E70': 'T',\n    '\\u1E6E': 'T',\n    '\\u0166': 'T',\n    '\\u01AC': 'T',\n    '\\u01AE': 'T',\n    '\\u023E': 'T',\n    '\\uA786': 'T',\n    '\\uA728': 'TZ',\n    '\\u24CA': 'U',\n    '\\uFF35': 'U',\n    '\\u00D9': 'U',\n    '\\u00DA': 'U',\n    '\\u00DB': 'U',\n    '\\u0168': 'U',\n    '\\u1E78': 'U',\n    '\\u016A': 'U',\n    '\\u1E7A': 'U',\n    '\\u016C': 'U',\n    '\\u00DC': 'U',\n    '\\u01DB': 'U',\n    '\\u01D7': 'U',\n    '\\u01D5': 'U',\n    '\\u01D9': 'U',\n    '\\u1EE6': 'U',\n    '\\u016E': 'U',\n    '\\u0170': 'U',\n    '\\u01D3': 'U',\n    '\\u0214': 'U',\n    '\\u0216': 'U',\n    '\\u01AF': 'U',\n    '\\u1EEA': 'U',\n    '\\u1EE8': 'U',\n    '\\u1EEE': 'U',\n    '\\u1EEC': 'U',\n    '\\u1EF0': 'U',\n    '\\u1EE4': 'U',\n    '\\u1E72': 'U',\n    '\\u0172': 'U',\n    '\\u1E76': 'U',\n    '\\u1E74': 'U',\n    '\\u0244': 'U',\n    '\\u24CB': 'V',\n    '\\uFF36': 'V',\n    '\\u1E7C': 'V',\n    '\\u1E7E': 'V',\n    '\\u01B2': 'V',\n    '\\uA75E': 'V',\n    '\\u0245': 'V',\n    '\\uA760': 'VY',\n    '\\u24CC': 'W',\n    '\\uFF37': 'W',\n    '\\u1E80': 'W',\n    '\\u1E82': 'W',\n    '\\u0174': 'W',\n    '\\u1E86': 'W',\n    '\\u1E84': 'W',\n    '\\u1E88': 'W',\n    '\\u2C72': 'W',\n    '\\u24CD': 'X',\n    '\\uFF38': 'X',\n    '\\u1E8A': 'X',\n    '\\u1E8C': 'X',\n    '\\u24CE': 'Y',\n    '\\uFF39': 'Y',\n    '\\u1EF2': 'Y',\n    '\\u00DD': 'Y',\n    '\\u0176': 'Y',\n    '\\u1EF8': 'Y',\n    '\\u0232': 'Y',\n    '\\u1E8E': 'Y',\n    '\\u0178': 'Y',\n    '\\u1EF6': 'Y',\n    '\\u1EF4': 'Y',\n    '\\u01B3': 'Y',\n    '\\u024E': 'Y',\n    '\\u1EFE': 'Y',\n    '\\u24CF': 'Z',\n    '\\uFF3A': 'Z',\n    '\\u0179': 'Z',\n    '\\u1E90': 'Z',\n    '\\u017B': 'Z',\n    '\\u017D': 'Z',\n    '\\u1E92': 'Z',\n    '\\u1E94': 'Z',\n    '\\u01B5': 'Z',\n    '\\u0224': 'Z',\n    '\\u2C7F': 'Z',\n    '\\u2C6B': 'Z',\n    '\\uA762': 'Z',\n    '\\u24D0': 'a',\n    '\\uFF41': 'a',\n    '\\u1E9A': 'a',\n    '\\u00E0': 'a',\n    '\\u00E1': 'a',\n    '\\u00E2': 'a',\n    '\\u1EA7': 'a',\n    '\\u1EA5': 'a',\n    '\\u1EAB': 'a',\n    '\\u1EA9': 'a',\n    '\\u00E3': 'a',\n    '\\u0101': 'a',\n    '\\u0103': 'a',\n    '\\u1EB1': 'a',\n    '\\u1EAF': 'a',\n    '\\u1EB5': 'a',\n    '\\u1EB3': 'a',\n    '\\u0227': 'a',\n    '\\u01E1': 'a',\n    '\\u00E4': 'a',\n    '\\u01DF': 'a',\n    '\\u1EA3': 'a',\n    '\\u00E5': 'a',\n    '\\u01FB': 'a',\n    '\\u01CE': 'a',\n    '\\u0201': 'a',\n    '\\u0203': 'a',\n    '\\u1EA1': 'a',\n    '\\u1EAD': 'a',\n    '\\u1EB7': 'a',\n    '\\u1E01': 'a',\n    '\\u0105': 'a',\n    '\\u2C65': 'a',\n    '\\u0250': 'a',\n    '\\uA733': 'aa',\n    '\\u00E6': 'ae',\n    '\\u01FD': 'ae',\n    '\\u01E3': 'ae',\n    '\\uA735': 'ao',\n    '\\uA737': 'au',\n    '\\uA739': 'av',\n    '\\uA73B': 'av',\n    '\\uA73D': 'ay',\n    '\\u24D1': 'b',\n    '\\uFF42': 'b',\n    '\\u1E03': 'b',\n    '\\u1E05': 'b',\n    '\\u1E07': 'b',\n    '\\u0180': 'b',\n    '\\u0183': 'b',\n    '\\u0253': 'b',\n    '\\u24D2': 'c',\n    '\\uFF43': 'c',\n    '\\u0107': 'c',\n    '\\u0109': 'c',\n    '\\u010B': 'c',\n    '\\u010D': 'c',\n    '\\u00E7': 'c',\n    '\\u1E09': 'c',\n    '\\u0188': 'c',\n    '\\u023C': 'c',\n    '\\uA73F': 'c',\n    '\\u2184': 'c',\n    '\\u24D3': 'd',\n    '\\uFF44': 'd',\n    '\\u1E0B': 'd',\n    '\\u010F': 'd',\n    '\\u1E0D': 'd',\n    '\\u1E11': 'd',\n    '\\u1E13': 'd',\n    '\\u1E0F': 'd',\n    '\\u0111': 'd',\n    '\\u018C': 'd',\n    '\\u0256': 'd',\n    '\\u0257': 'd',\n    '\\uA77A': 'd',\n    '\\u01F3': 'dz',\n    '\\u01C6': 'dz',\n    '\\u24D4': 'e',\n    '\\uFF45': 'e',\n    '\\u00E8': 'e',\n    '\\u00E9': 'e',\n    '\\u00EA': 'e',\n    '\\u1EC1': 'e',\n    '\\u1EBF': 'e',\n    '\\u1EC5': 'e',\n    '\\u1EC3': 'e',\n    '\\u1EBD': 'e',\n    '\\u0113': 'e',\n    '\\u1E15': 'e',\n    '\\u1E17': 'e',\n    '\\u0115': 'e',\n    '\\u0117': 'e',\n    '\\u00EB': 'e',\n    '\\u1EBB': 'e',\n    '\\u011B': 'e',\n    '\\u0205': 'e',\n    '\\u0207': 'e',\n    '\\u1EB9': 'e',\n    '\\u1EC7': 'e',\n    '\\u0229': 'e',\n    '\\u1E1D': 'e',\n    '\\u0119': 'e',\n    '\\u1E19': 'e',\n    '\\u1E1B': 'e',\n    '\\u0247': 'e',\n    '\\u025B': 'e',\n    '\\u01DD': 'e',\n    '\\u24D5': 'f',\n    '\\uFF46': 'f',\n    '\\u1E1F': 'f',\n    '\\u0192': 'f',\n    '\\uA77C': 'f',\n    '\\u24D6': 'g',\n    '\\uFF47': 'g',\n    '\\u01F5': 'g',\n    '\\u011D': 'g',\n    '\\u1E21': 'g',\n    '\\u011F': 'g',\n    '\\u0121': 'g',\n    '\\u01E7': 'g',\n    '\\u0123': 'g',\n    '\\u01E5': 'g',\n    '\\u0260': 'g',\n    '\\uA7A1': 'g',\n    '\\u1D79': 'g',\n    '\\uA77F': 'g',\n    '\\u24D7': 'h',\n    '\\uFF48': 'h',\n    '\\u0125': 'h',\n    '\\u1E23': 'h',\n    '\\u1E27': 'h',\n    '\\u021F': 'h',\n    '\\u1E25': 'h',\n    '\\u1E29': 'h',\n    '\\u1E2B': 'h',\n    '\\u1E96': 'h',\n    '\\u0127': 'h',\n    '\\u2C68': 'h',\n    '\\u2C76': 'h',\n    '\\u0265': 'h',\n    '\\u0195': 'hv',\n    '\\u24D8': 'i',\n    '\\uFF49': 'i',\n    '\\u00EC': 'i',\n    '\\u00ED': 'i',\n    '\\u00EE': 'i',\n    '\\u0129': 'i',\n    '\\u012B': 'i',\n    '\\u012D': 'i',\n    '\\u00EF': 'i',\n    '\\u1E2F': 'i',\n    '\\u1EC9': 'i',\n    '\\u01D0': 'i',\n    '\\u0209': 'i',\n    '\\u020B': 'i',\n    '\\u1ECB': 'i',\n    '\\u012F': 'i',\n    '\\u1E2D': 'i',\n    '\\u0268': 'i',\n    '\\u0131': 'i',\n    '\\u24D9': 'j',\n    '\\uFF4A': 'j',\n    '\\u0135': 'j',\n    '\\u01F0': 'j',\n    '\\u0249': 'j',\n    '\\u24DA': 'k',\n    '\\uFF4B': 'k',\n    '\\u1E31': 'k',\n    '\\u01E9': 'k',\n    '\\u1E33': 'k',\n    '\\u0137': 'k',\n    '\\u1E35': 'k',\n    '\\u0199': 'k',\n    '\\u2C6A': 'k',\n    '\\uA741': 'k',\n    '\\uA743': 'k',\n    '\\uA745': 'k',\n    '\\uA7A3': 'k',\n    '\\u24DB': 'l',\n    '\\uFF4C': 'l',\n    '\\u0140': 'l',\n    '\\u013A': 'l',\n    '\\u013E': 'l',\n    '\\u1E37': 'l',\n    '\\u1E39': 'l',\n    '\\u013C': 'l',\n    '\\u1E3D': 'l',\n    '\\u1E3B': 'l',\n    '\\u017F': 'l',\n    '\\u0142': 'l',\n    '\\u019A': 'l',\n    '\\u026B': 'l',\n    '\\u2C61': 'l',\n    '\\uA749': 'l',\n    '\\uA781': 'l',\n    '\\uA747': 'l',\n    '\\u01C9': 'lj',\n    '\\u24DC': 'm',\n    '\\uFF4D': 'm',\n    '\\u1E3F': 'm',\n    '\\u1E41': 'm',\n    '\\u1E43': 'm',\n    '\\u0271': 'm',\n    '\\u026F': 'm',\n    '\\u24DD': 'n',\n    '\\uFF4E': 'n',\n    '\\u01F9': 'n',\n    '\\u0144': 'n',\n    '\\u00F1': 'n',\n    '\\u1E45': 'n',\n    '\\u0148': 'n',\n    '\\u1E47': 'n',\n    '\\u0146': 'n',\n    '\\u1E4B': 'n',\n    '\\u1E49': 'n',\n    '\\u019E': 'n',\n    '\\u0272': 'n',\n    '\\u0149': 'n',\n    '\\uA791': 'n',\n    '\\uA7A5': 'n',\n    '\\u01CC': 'nj',\n    '\\u24DE': 'o',\n    '\\uFF4F': 'o',\n    '\\u00F2': 'o',\n    '\\u00F3': 'o',\n    '\\u00F4': 'o',\n    '\\u1ED3': 'o',\n    '\\u1ED1': 'o',\n    '\\u1ED7': 'o',\n    '\\u1ED5': 'o',\n    '\\u00F5': 'o',\n    '\\u1E4D': 'o',\n    '\\u022D': 'o',\n    '\\u1E4F': 'o',\n    '\\u014D': 'o',\n    '\\u1E51': 'o',\n    '\\u1E53': 'o',\n    '\\u014F': 'o',\n    '\\u022F': 'o',\n    '\\u0231': 'o',\n    '\\u00F6': 'o',\n    '\\u022B': 'o',\n    '\\u1ECF': 'o',\n    '\\u0151': 'o',\n    '\\u01D2': 'o',\n    '\\u020D': 'o',\n    '\\u020F': 'o',\n    '\\u01A1': 'o',\n    '\\u1EDD': 'o',\n    '\\u1EDB': 'o',\n    '\\u1EE1': 'o',\n    '\\u1EDF': 'o',\n    '\\u1EE3': 'o',\n    '\\u1ECD': 'o',\n    '\\u1ED9': 'o',\n    '\\u01EB': 'o',\n    '\\u01ED': 'o',\n    '\\u00F8': 'o',\n    '\\u01FF': 'o',\n    '\\u0254': 'o',\n    '\\uA74B': 'o',\n    '\\uA74D': 'o',\n    '\\u0275': 'o',\n    '\\u01A3': 'oi',\n    '\\u0223': 'ou',\n    '\\uA74F': 'oo',\n    '\\u24DF': 'p',\n    '\\uFF50': 'p',\n    '\\u1E55': 'p',\n    '\\u1E57': 'p',\n    '\\u01A5': 'p',\n    '\\u1D7D': 'p',\n    '\\uA751': 'p',\n    '\\uA753': 'p',\n    '\\uA755': 'p',\n    '\\u24E0': 'q',\n    '\\uFF51': 'q',\n    '\\u024B': 'q',\n    '\\uA757': 'q',\n    '\\uA759': 'q',\n    '\\u24E1': 'r',\n    '\\uFF52': 'r',\n    '\\u0155': 'r',\n    '\\u1E59': 'r',\n    '\\u0159': 'r',\n    '\\u0211': 'r',\n    '\\u0213': 'r',\n    '\\u1E5B': 'r',\n    '\\u1E5D': 'r',\n    '\\u0157': 'r',\n    '\\u1E5F': 'r',\n    '\\u024D': 'r',\n    '\\u027D': 'r',\n    '\\uA75B': 'r',\n    '\\uA7A7': 'r',\n    '\\uA783': 'r',\n    '\\u24E2': 's',\n    '\\uFF53': 's',\n    '\\u00DF': 's',\n    '\\u015B': 's',\n    '\\u1E65': 's',\n    '\\u015D': 's',\n    '\\u1E61': 's',\n    '\\u0161': 's',\n    '\\u1E67': 's',\n    '\\u1E63': 's',\n    '\\u1E69': 's',\n    '\\u0219': 's',\n    '\\u015F': 's',\n    '\\u023F': 's',\n    '\\uA7A9': 's',\n    '\\uA785': 's',\n    '\\u1E9B': 's',\n    '\\u24E3': 't',\n    '\\uFF54': 't',\n    '\\u1E6B': 't',\n    '\\u1E97': 't',\n    '\\u0165': 't',\n    '\\u1E6D': 't',\n    '\\u021B': 't',\n    '\\u0163': 't',\n    '\\u1E71': 't',\n    '\\u1E6F': 't',\n    '\\u0167': 't',\n    '\\u01AD': 't',\n    '\\u0288': 't',\n    '\\u2C66': 't',\n    '\\uA787': 't',\n    '\\uA729': 'tz',\n    '\\u24E4': 'u',\n    '\\uFF55': 'u',\n    '\\u00F9': 'u',\n    '\\u00FA': 'u',\n    '\\u00FB': 'u',\n    '\\u0169': 'u',\n    '\\u1E79': 'u',\n    '\\u016B': 'u',\n    '\\u1E7B': 'u',\n    '\\u016D': 'u',\n    '\\u00FC': 'u',\n    '\\u01DC': 'u',\n    '\\u01D8': 'u',\n    '\\u01D6': 'u',\n    '\\u01DA': 'u',\n    '\\u1EE7': 'u',\n    '\\u016F': 'u',\n    '\\u0171': 'u',\n    '\\u01D4': 'u',\n    '\\u0215': 'u',\n    '\\u0217': 'u',\n    '\\u01B0': 'u',\n    '\\u1EEB': 'u',\n    '\\u1EE9': 'u',\n    '\\u1EEF': 'u',\n    '\\u1EED': 'u',\n    '\\u1EF1': 'u',\n    '\\u1EE5': 'u',\n    '\\u1E73': 'u',\n    '\\u0173': 'u',\n    '\\u1E77': 'u',\n    '\\u1E75': 'u',\n    '\\u0289': 'u',\n    '\\u24E5': 'v',\n    '\\uFF56': 'v',\n    '\\u1E7D': 'v',\n    '\\u1E7F': 'v',\n    '\\u028B': 'v',\n    '\\uA75F': 'v',\n    '\\u028C': 'v',\n    '\\uA761': 'vy',\n    '\\u24E6': 'w',\n    '\\uFF57': 'w',\n    '\\u1E81': 'w',\n    '\\u1E83': 'w',\n    '\\u0175': 'w',\n    '\\u1E87': 'w',\n    '\\u1E85': 'w',\n    '\\u1E98': 'w',\n    '\\u1E89': 'w',\n    '\\u2C73': 'w',\n    '\\u24E7': 'x',\n    '\\uFF58': 'x',\n    '\\u1E8B': 'x',\n    '\\u1E8D': 'x',\n    '\\u24E8': 'y',\n    '\\uFF59': 'y',\n    '\\u1EF3': 'y',\n    '\\u00FD': 'y',\n    '\\u0177': 'y',\n    '\\u1EF9': 'y',\n    '\\u0233': 'y',\n    '\\u1E8F': 'y',\n    '\\u00FF': 'y',\n    '\\u1EF7': 'y',\n    '\\u1E99': 'y',\n    '\\u1EF5': 'y',\n    '\\u01B4': 'y',\n    '\\u024F': 'y',\n    '\\u1EFF': 'y',\n    '\\u24E9': 'z',\n    '\\uFF5A': 'z',\n    '\\u017A': 'z',\n    '\\u1E91': 'z',\n    '\\u017C': 'z',\n    '\\u017E': 'z',\n    '\\u1E93': 'z',\n    '\\u1E95': 'z',\n    '\\u01B6': 'z',\n    '\\u0225': 'z',\n    '\\u0240': 'z',\n    '\\u2C6C': 'z',\n    '\\uA763': 'z',\n    '\\u0386': '\\u0391',\n    '\\u0388': '\\u0395',\n    '\\u0389': '\\u0397',\n    '\\u038A': '\\u0399',\n    '\\u03AA': '\\u0399',\n    '\\u038C': '\\u039F',\n    '\\u038E': '\\u03A5',\n    '\\u03AB': '\\u03A5',\n    '\\u038F': '\\u03A9',\n    '\\u03AC': '\\u03B1',\n    '\\u03AD': '\\u03B5',\n    '\\u03AE': '\\u03B7',\n    '\\u03AF': '\\u03B9',\n    '\\u03CA': '\\u03B9',\n    '\\u0390': '\\u03B9',\n    '\\u03CC': '\\u03BF',\n    '\\u03CD': '\\u03C5',\n    '\\u03CB': '\\u03C5',\n    '\\u03B0': '\\u03C5',\n    '\\u03C9': '\\u03C9',\n    '\\u03C2': '\\u03C3'\n  };\n\n  return diacritics;\n});\n\nS2.define('select2/data/base',[\n  '../utils'\n], function (Utils) {\n  function BaseAdapter ($element, options) {\n    BaseAdapter.__super__.constructor.call(this);\n  }\n\n  Utils.Extend(BaseAdapter, Utils.Observable);\n\n  BaseAdapter.prototype.current = function (callback) {\n    throw new Error('The `current` method must be defined in child classes.');\n  };\n\n  BaseAdapter.prototype.query = function (params, callback) {\n    throw new Error('The `query` method must be defined in child classes.');\n  };\n\n  BaseAdapter.prototype.bind = function (container, $container) {\n    // Can be implemented in subclasses\n  };\n\n  BaseAdapter.prototype.destroy = function () {\n    // Can be implemented in subclasses\n  };\n\n  BaseAdapter.prototype.generateResultId = function (container, data) {\n    var id = container.id + '-result-';\n\n    id += Utils.generateChars(4);\n\n    if (data.id != null) {\n      id += '-' + data.id.toString();\n    } else {\n      id += '-' + Utils.generateChars(4);\n    }\n    return id;\n  };\n\n  return BaseAdapter;\n});\n\nS2.define('select2/data/select',[\n  './base',\n  '../utils',\n  'jquery'\n], function (BaseAdapter, Utils, $) {\n  function SelectAdapter ($element, options) {\n    this.$element = $element;\n    this.options = options;\n\n    SelectAdapter.__super__.constructor.call(this);\n  }\n\n  Utils.Extend(SelectAdapter, BaseAdapter);\n\n  SelectAdapter.prototype.current = function (callback) {\n    var data = [];\n    var self = this;\n\n    this.$element.find(':selected').each(function () {\n      var $option = $(this);\n\n      var option = self.item($option);\n\n      data.push(option);\n    });\n\n    callback(data);\n  };\n\n  SelectAdapter.prototype.select = function (data) {\n    var self = this;\n\n    data.selected = true;\n\n    // If data.element is a DOM node, use it instead\n    if ($(data.element).is('option')) {\n      data.element.selected = true;\n\n      this.$element.trigger('change');\n\n      return;\n    }\n\n    if (this.$element.prop('multiple')) {\n      this.current(function (currentData) {\n        var val = [];\n\n        data = [data];\n        data.push.apply(data, currentData);\n\n        for (var d = 0; d < data.length; d++) {\n          var id = data[d].id;\n\n          if ($.inArray(id, val) === -1) {\n            val.push(id);\n          }\n        }\n\n        self.$element.val(val);\n        self.$element.trigger('change');\n      });\n    } else {\n      var val = data.id;\n\n      this.$element.val(val);\n      this.$element.trigger('change');\n    }\n  };\n\n  SelectAdapter.prototype.unselect = function (data) {\n    var self = this;\n\n    if (!this.$element.prop('multiple')) {\n      return;\n    }\n\n    data.selected = false;\n\n    if ($(data.element).is('option')) {\n      data.element.selected = false;\n\n      this.$element.trigger('change');\n\n      return;\n    }\n\n    this.current(function (currentData) {\n      var val = [];\n\n      for (var d = 0; d < currentData.length; d++) {\n        var id = currentData[d].id;\n\n        if (id !== data.id && $.inArray(id, val) === -1) {\n          val.push(id);\n        }\n      }\n\n      self.$element.val(val);\n\n      self.$element.trigger('change');\n    });\n  };\n\n  SelectAdapter.prototype.bind = function (container, $container) {\n    var self = this;\n\n    this.container = container;\n\n    container.on('select', function (params) {\n      self.select(params.data);\n    });\n\n    container.on('unselect', function (params) {\n      self.unselect(params.data);\n    });\n  };\n\n  SelectAdapter.prototype.destroy = function () {\n    // Remove anything added to child elements\n    this.$element.find('*').each(function () {\n      // Remove any custom data set by Select2\n      $.removeData(this, 'data');\n    });\n  };\n\n  SelectAdapter.prototype.query = function (params, callback) {\n    var data = [];\n    var self = this;\n\n    var $options = this.$element.children();\n\n    $options.each(function () {\n      var $option = $(this);\n\n      if (!$option.is('option') && !$option.is('optgroup')) {\n        return;\n      }\n\n      var option = self.item($option);\n\n      var matches = self.matches(params, option);\n\n      if (matches !== null) {\n        data.push(matches);\n      }\n    });\n\n    callback({\n      results: data\n    });\n  };\n\n  SelectAdapter.prototype.addOptions = function ($options) {\n    Utils.appendMany(this.$element, $options);\n  };\n\n  SelectAdapter.prototype.option = function (data) {\n    var option;\n\n    if (data.children) {\n      option = document.createElement('optgroup');\n      option.label = data.text;\n    } else {\n      option = document.createElement('option');\n\n      if (option.textContent !== undefined) {\n        option.textContent = data.text;\n      } else {\n        option.innerText = data.text;\n      }\n    }\n\n    if (data.id) {\n      option.value = data.id;\n    }\n\n    if (data.disabled) {\n      option.disabled = true;\n    }\n\n    if (data.selected) {\n      option.selected = true;\n    }\n\n    if (data.title) {\n      option.title = data.title;\n    }\n\n    var $option = $(option);\n\n    var normalizedData = this._normalizeItem(data);\n    normalizedData.element = option;\n\n    // Override the option's data with the combined data\n    $.data(option, 'data', normalizedData);\n\n    return $option;\n  };\n\n  SelectAdapter.prototype.item = function ($option) {\n    var data = {};\n\n    data = $.data($option[0], 'data');\n\n    if (data != null) {\n      return data;\n    }\n\n    if ($option.is('option')) {\n      data = {\n        id: $option.val(),\n        text: $option.text(),\n        disabled: $option.prop('disabled'),\n        selected: $option.prop('selected'),\n        title: $option.prop('title')\n      };\n    } else if ($option.is('optgroup')) {\n      data = {\n        text: $option.prop('label'),\n        children: [],\n        title: $option.prop('title')\n      };\n\n      var $children = $option.children('option');\n      var children = [];\n\n      for (var c = 0; c < $children.length; c++) {\n        var $child = $($children[c]);\n\n        var child = this.item($child);\n\n        children.push(child);\n      }\n\n      data.children = children;\n    }\n\n    data = this._normalizeItem(data);\n    data.element = $option[0];\n\n    $.data($option[0], 'data', data);\n\n    return data;\n  };\n\n  SelectAdapter.prototype._normalizeItem = function (item) {\n    if (!$.isPlainObject(item)) {\n      item = {\n        id: item,\n        text: item\n      };\n    }\n\n    item = $.extend({}, {\n      text: ''\n    }, item);\n\n    var defaults = {\n      selected: false,\n      disabled: false\n    };\n\n    if (item.id != null) {\n      item.id = item.id.toString();\n    }\n\n    if (item.text != null) {\n      item.text = item.text.toString();\n    }\n\n    if (item._resultId == null && item.id && this.container != null) {\n      item._resultId = this.generateResultId(this.container, item);\n    }\n\n    return $.extend({}, defaults, item);\n  };\n\n  SelectAdapter.prototype.matches = function (params, data) {\n    var matcher = this.options.get('matcher');\n\n    return matcher(params, data);\n  };\n\n  return SelectAdapter;\n});\n\nS2.define('select2/data/array',[\n  './select',\n  '../utils',\n  'jquery'\n], function (SelectAdapter, Utils, $) {\n  function ArrayAdapter ($element, options) {\n    var data = options.get('data') || [];\n\n    ArrayAdapter.__super__.constructor.call(this, $element, options);\n\n    this.addOptions(this.convertToOptions(data));\n  }\n\n  Utils.Extend(ArrayAdapter, SelectAdapter);\n\n  ArrayAdapter.prototype.select = function (data) {\n    var $option = this.$element.find('option').filter(function (i, elm) {\n      return elm.value == data.id.toString();\n    });\n\n    if ($option.length === 0) {\n      $option = this.option(data);\n\n      this.addOptions($option);\n    }\n\n    ArrayAdapter.__super__.select.call(this, data);\n  };\n\n  ArrayAdapter.prototype.convertToOptions = function (data) {\n    var self = this;\n\n    var $existing = this.$element.find('option');\n    var existingIds = $existing.map(function () {\n      return self.item($(this)).id;\n    }).get();\n\n    var $options = [];\n\n    // Filter out all items except for the one passed in the argument\n    function onlyItem (item) {\n      return function () {\n        return $(this).val() == item.id;\n      };\n    }\n\n    for (var d = 0; d < data.length; d++) {\n      var item = this._normalizeItem(data[d]);\n\n      // Skip items which were pre-loaded, only merge the data\n      if ($.inArray(item.id, existingIds) >= 0) {\n        var $existingOption = $existing.filter(onlyItem(item));\n\n        var existingData = this.item($existingOption);\n        var newData = $.extend(true, {}, existingData, item);\n\n        var $newOption = this.option(newData);\n\n        $existingOption.replaceWith($newOption);\n\n        continue;\n      }\n\n      var $option = this.option(item);\n\n      if (item.children) {\n        var $children = this.convertToOptions(item.children);\n\n        Utils.appendMany($option, $children);\n      }\n\n      $options.push($option);\n    }\n\n    return $options;\n  };\n\n  return ArrayAdapter;\n});\n\nS2.define('select2/data/ajax',[\n  './array',\n  '../utils',\n  'jquery'\n], function (ArrayAdapter, Utils, $) {\n  function AjaxAdapter ($element, options) {\n    this.ajaxOptions = this._applyDefaults(options.get('ajax'));\n\n    if (this.ajaxOptions.processResults != null) {\n      this.processResults = this.ajaxOptions.processResults;\n    }\n\n    AjaxAdapter.__super__.constructor.call(this, $element, options);\n  }\n\n  Utils.Extend(AjaxAdapter, ArrayAdapter);\n\n  AjaxAdapter.prototype._applyDefaults = function (options) {\n    var defaults = {\n      data: function (params) {\n        return $.extend({}, params, {\n          q: params.term\n        });\n      },\n      transport: function (params, success, failure) {\n        var $request = $.ajax(params);\n\n        $request.then(success);\n        $request.fail(failure);\n\n        return $request;\n      }\n    };\n\n    return $.extend({}, defaults, options, true);\n  };\n\n  AjaxAdapter.prototype.processResults = function (results) {\n    return results;\n  };\n\n  AjaxAdapter.prototype.query = function (params, callback) {\n    var matches = [];\n    var self = this;\n\n    if (this._request != null) {\n      // JSONP requests cannot always be aborted\n      if ($.isFunction(this._request.abort)) {\n        this._request.abort();\n      }\n\n      this._request = null;\n    }\n\n    var options = $.extend({\n      type: 'GET'\n    }, this.ajaxOptions);\n\n    if (typeof options.url === 'function') {\n      options.url = options.url.call(this.$element, params);\n    }\n\n    if (typeof options.data === 'function') {\n      options.data = options.data.call(this.$element, params);\n    }\n\n    function request () {\n      var $request = options.transport(options, function (data) {\n        var results = self.processResults(data, params);\n\n        if (self.options.get('debug') && window.console && console.error) {\n          // Check to make sure that the response included a `results` key.\n          if (!results || !results.results || !$.isArray(results.results)) {\n            console.error(\n              'Select2: The AJAX results did not return an array in the ' +\n              '`results` key of the response.'\n            );\n          }\n        }\n\n        callback(results);\n      }, function () {\n        // TODO: Handle AJAX errors\n      });\n\n      self._request = $request;\n    }\n\n    if (this.ajaxOptions.delay && params.term !== '') {\n      if (this._queryTimeout) {\n        window.clearTimeout(this._queryTimeout);\n      }\n\n      this._queryTimeout = window.setTimeout(request, this.ajaxOptions.delay);\n    } else {\n      request();\n    }\n  };\n\n  return AjaxAdapter;\n});\n\nS2.define('select2/data/tags',[\n  'jquery'\n], function ($) {\n  function Tags (decorated, $element, options) {\n    var tags = options.get('tags');\n\n    var createTag = options.get('createTag');\n\n    if (createTag !== undefined) {\n      this.createTag = createTag;\n    }\n\n    decorated.call(this, $element, options);\n\n    if ($.isArray(tags)) {\n      for (var t = 0; t < tags.length; t++) {\n        var tag = tags[t];\n        var item = this._normalizeItem(tag);\n\n        var $option = this.option(item);\n\n        this.$element.append($option);\n      }\n    }\n  }\n\n  Tags.prototype.query = function (decorated, params, callback) {\n    var self = this;\n\n    this._removeOldTags();\n\n    if (params.term == null || params.page != null) {\n      decorated.call(this, params, callback);\n      return;\n    }\n\n    function wrapper (obj, child) {\n      var data = obj.results;\n\n      for (var i = 0; i < data.length; i++) {\n        var option = data[i];\n\n        var checkChildren = (\n          option.children != null &&\n          !wrapper({\n            results: option.children\n          }, true)\n        );\n\n        var checkText = option.text === params.term;\n\n        if (checkText || checkChildren) {\n          if (child) {\n            return false;\n          }\n\n          obj.data = data;\n          callback(obj);\n\n          return;\n        }\n      }\n\n      if (child) {\n        return true;\n      }\n\n      var tag = self.createTag(params);\n\n      if (tag != null) {\n        var $option = self.option(tag);\n        $option.attr('data-select2-tag', true);\n\n        self.addOptions([$option]);\n\n        self.insertTag(data, tag);\n      }\n\n      obj.results = data;\n\n      callback(obj);\n    }\n\n    decorated.call(this, params, wrapper);\n  };\n\n  Tags.prototype.createTag = function (decorated, params) {\n    var term = $.trim(params.term);\n\n    if (term === '') {\n      return null;\n    }\n\n    return {\n      id: term,\n      text: term\n    };\n  };\n\n  Tags.prototype.insertTag = function (_, data, tag) {\n    data.unshift(tag);\n  };\n\n  Tags.prototype._removeOldTags = function (_) {\n    var tag = this._lastTag;\n\n    var $options = this.$element.find('option[data-select2-tag]');\n\n    $options.each(function () {\n      if (this.selected) {\n        return;\n      }\n\n      $(this).remove();\n    });\n  };\n\n  return Tags;\n});\n\nS2.define('select2/data/tokenizer',[\n  'jquery'\n], function ($) {\n  function Tokenizer (decorated, $element, options) {\n    var tokenizer = options.get('tokenizer');\n\n    if (tokenizer !== undefined) {\n      this.tokenizer = tokenizer;\n    }\n\n    decorated.call(this, $element, options);\n  }\n\n  Tokenizer.prototype.bind = function (decorated, container, $container) {\n    decorated.call(this, container, $container);\n\n    this.$search =  container.dropdown.$search || container.selection.$search ||\n      $container.find('.select2-search__field');\n  };\n\n  Tokenizer.prototype.query = function (decorated, params, callback) {\n    var self = this;\n\n    function select (data) {\n      self.trigger('select', {\n        data: data\n      });\n    }\n\n    params.term = params.term || '';\n\n    var tokenData = this.tokenizer(params, this.options, select);\n\n    if (tokenData.term !== params.term) {\n      // Replace the search term if we have the search box\n      if (this.$search.length) {\n        this.$search.val(tokenData.term);\n        this.$search.focus();\n      }\n\n      params.term = tokenData.term;\n    }\n\n    decorated.call(this, params, callback);\n  };\n\n  Tokenizer.prototype.tokenizer = function (_, params, options, callback) {\n    var separators = options.get('tokenSeparators') || [];\n    var term = params.term;\n    var i = 0;\n\n    var createTag = this.createTag || function (params) {\n      return {\n        id: params.term,\n        text: params.term\n      };\n    };\n\n    while (i < term.length) {\n      var termChar = term[i];\n\n      if ($.inArray(termChar, separators) === -1) {\n        i++;\n\n        continue;\n      }\n\n      var part = term.substr(0, i);\n      var partParams = $.extend({}, params, {\n        term: part\n      });\n\n      var data = createTag(partParams);\n\n      if (data == null) {\n        i++;\n        continue;\n      }\n\n      callback(data);\n\n      // Reset the term to not include the tokenized portion\n      term = term.substr(i + 1) || '';\n      i = 0;\n    }\n\n    return {\n      term: term\n    };\n  };\n\n  return Tokenizer;\n});\n\nS2.define('select2/data/minimumInputLength',[\n\n], function () {\n  function MinimumInputLength (decorated, $e, options) {\n    this.minimumInputLength = options.get('minimumInputLength');\n\n    decorated.call(this, $e, options);\n  }\n\n  MinimumInputLength.prototype.query = function (decorated, params, callback) {\n    params.term = params.term || '';\n\n    if (params.term.length < this.minimumInputLength) {\n      this.trigger('results:message', {\n        message: 'inputTooShort',\n        args: {\n          minimum: this.minimumInputLength,\n          input: params.term,\n          params: params\n        }\n      });\n\n      return;\n    }\n\n    decorated.call(this, params, callback);\n  };\n\n  return MinimumInputLength;\n});\n\nS2.define('select2/data/maximumInputLength',[\n\n], function () {\n  function MaximumInputLength (decorated, $e, options) {\n    this.maximumInputLength = options.get('maximumInputLength');\n\n    decorated.call(this, $e, options);\n  }\n\n  MaximumInputLength.prototype.query = function (decorated, params, callback) {\n    params.term = params.term || '';\n\n    if (this.maximumInputLength > 0 &&\n        params.term.length > this.maximumInputLength) {\n      this.trigger('results:message', {\n        message: 'inputTooLong',\n        args: {\n          maximum: this.maximumInputLength,\n          input: params.term,\n          params: params\n        }\n      });\n\n      return;\n    }\n\n    decorated.call(this, params, callback);\n  };\n\n  return MaximumInputLength;\n});\n\nS2.define('select2/data/maximumSelectionLength',[\n\n], function (){\n  function MaximumSelectionLength (decorated, $e, options) {\n    this.maximumSelectionLength = options.get('maximumSelectionLength');\n\n    decorated.call(this, $e, options);\n  }\n\n  MaximumSelectionLength.prototype.query =\n    function (decorated, params, callback) {\n      var self = this;\n\n      this.current(function (currentData) {\n        var count = currentData != null ? currentData.length : 0;\n        if (self.maximumSelectionLength > 0 &&\n          count >= self.maximumSelectionLength) {\n          self.trigger('results:message', {\n            message: 'maximumSelected',\n            args: {\n              maximum: self.maximumSelectionLength\n            }\n          });\n          return;\n        }\n        decorated.call(self, params, callback);\n      });\n  };\n\n  return MaximumSelectionLength;\n});\n\nS2.define('select2/dropdown',[\n  'jquery',\n  './utils'\n], function ($, Utils) {\n  function Dropdown ($element, options) {\n    this.$element = $element;\n    this.options = options;\n\n    Dropdown.__super__.constructor.call(this);\n  }\n\n  Utils.Extend(Dropdown, Utils.Observable);\n\n  Dropdown.prototype.render = function () {\n    var $dropdown = $(\n      '<span class=\"select2-dropdown\">' +\n        '<span class=\"select2-results\"></span>' +\n      '</span>'\n    );\n\n    $dropdown.attr('dir', this.options.get('dir'));\n\n    this.$dropdown = $dropdown;\n\n    return $dropdown;\n  };\n\n  Dropdown.prototype.bind = function () {\n    // Should be implemented in subclasses\n  };\n\n  Dropdown.prototype.position = function ($dropdown, $container) {\n    // Should be implmented in subclasses\n  };\n\n  Dropdown.prototype.destroy = function () {\n    // Remove the dropdown from the DOM\n    this.$dropdown.remove();\n  };\n\n  return Dropdown;\n});\n\nS2.define('select2/dropdown/search',[\n  'jquery',\n  '../utils'\n], function ($, Utils) {\n  function Search () { }\n\n  Search.prototype.render = function (decorated) {\n    var $rendered = decorated.call(this);\n\n    var $search = $(\n      '<span class=\"select2-search select2-search--dropdown\">' +\n        '<input class=\"select2-search__field\" type=\"search\" tabindex=\"-1\"' +\n        ' autocomplete=\"off\" autocorrect=\"off\" autocapitalize=\"off\"' +\n        ' spellcheck=\"false\" role=\"textbox\" />' +\n      '</span>'\n    );\n\n    this.$searchContainer = $search;\n    this.$search = $search.find('input');\n\n    $rendered.prepend($search);\n\n    return $rendered;\n  };\n\n  Search.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    decorated.call(this, container, $container);\n\n    this.$search.on('keydown', function (evt) {\n      self.trigger('keypress', evt);\n\n      self._keyUpPrevented = evt.isDefaultPrevented();\n    });\n\n    // Workaround for browsers which do not support the `input` event\n    // This will prevent double-triggering of events for browsers which support\n    // both the `keyup` and `input` events.\n    this.$search.on('input', function (evt) {\n      // Unbind the duplicated `keyup` event\n      $(this).off('keyup');\n    });\n\n    this.$search.on('keyup input', function (evt) {\n      self.handleSearch(evt);\n    });\n\n    container.on('open', function () {\n      self.$search.attr('tabindex', 0);\n\n      self.$search.focus();\n\n      window.setTimeout(function () {\n        self.$search.focus();\n      }, 0);\n    });\n\n    container.on('close', function () {\n      self.$search.attr('tabindex', -1);\n\n      self.$search.val('');\n    });\n\n    container.on('results:all', function (params) {\n      if (params.query.term == null || params.query.term === '') {\n        var showSearch = self.showSearch(params);\n\n        if (showSearch) {\n          self.$searchContainer.removeClass('select2-search--hide');\n        } else {\n          self.$searchContainer.addClass('select2-search--hide');\n        }\n      }\n    });\n  };\n\n  Search.prototype.handleSearch = function (evt) {\n    if (!this._keyUpPrevented) {\n      var input = this.$search.val();\n\n      this.trigger('query', {\n        term: input\n      });\n    }\n\n    this._keyUpPrevented = false;\n  };\n\n  Search.prototype.showSearch = function (_, params) {\n    return true;\n  };\n\n  return Search;\n});\n\nS2.define('select2/dropdown/hidePlaceholder',[\n\n], function () {\n  function HidePlaceholder (decorated, $element, options, dataAdapter) {\n    this.placeholder = this.normalizePlaceholder(options.get('placeholder'));\n\n    decorated.call(this, $element, options, dataAdapter);\n  }\n\n  HidePlaceholder.prototype.append = function (decorated, data) {\n    data.results = this.removePlaceholder(data.results);\n\n    decorated.call(this, data);\n  };\n\n  HidePlaceholder.prototype.normalizePlaceholder = function (_, placeholder) {\n    if (typeof placeholder === 'string') {\n      placeholder = {\n        id: '',\n        text: placeholder\n      };\n    }\n\n    return placeholder;\n  };\n\n  HidePlaceholder.prototype.removePlaceholder = function (_, data) {\n    var modifiedData = data.slice(0);\n\n    for (var d = data.length - 1; d >= 0; d--) {\n      var item = data[d];\n\n      if (this.placeholder.id === item.id) {\n        modifiedData.splice(d, 1);\n      }\n    }\n\n    return modifiedData;\n  };\n\n  return HidePlaceholder;\n});\n\nS2.define('select2/dropdown/infiniteScroll',[\n  'jquery'\n], function ($) {\n  function InfiniteScroll (decorated, $element, options, dataAdapter) {\n    this.lastParams = {};\n\n    decorated.call(this, $element, options, dataAdapter);\n\n    this.$loadingMore = this.createLoadingMore();\n    this.loading = false;\n  }\n\n  InfiniteScroll.prototype.append = function (decorated, data) {\n    this.$loadingMore.remove();\n    this.loading = false;\n\n    decorated.call(this, data);\n\n    if (this.showLoadingMore(data)) {\n      this.$results.append(this.$loadingMore);\n    }\n  };\n\n  InfiniteScroll.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    decorated.call(this, container, $container);\n\n    container.on('query', function (params) {\n      self.lastParams = params;\n      self.loading = true;\n    });\n\n    container.on('query:append', function (params) {\n      self.lastParams = params;\n      self.loading = true;\n    });\n\n    this.$results.on('scroll', function () {\n      var isLoadMoreVisible = $.contains(\n        document.documentElement,\n        self.$loadingMore[0]\n      );\n\n      if (self.loading || !isLoadMoreVisible) {\n        return;\n      }\n\n      var currentOffset = self.$results.offset().top +\n        self.$results.outerHeight(false);\n      var loadingMoreOffset = self.$loadingMore.offset().top +\n        self.$loadingMore.outerHeight(false);\n\n      if (currentOffset + 50 >= loadingMoreOffset) {\n        self.loadMore();\n      }\n    });\n  };\n\n  InfiniteScroll.prototype.loadMore = function () {\n    this.loading = true;\n\n    var params = $.extend({}, {page: 1}, this.lastParams);\n\n    params.page++;\n\n    this.trigger('query:append', params);\n  };\n\n  InfiniteScroll.prototype.showLoadingMore = function (_, data) {\n    return data.pagination && data.pagination.more;\n  };\n\n  InfiniteScroll.prototype.createLoadingMore = function () {\n    var $option = $(\n      '<li ' +\n      'class=\"select2-results__option select2-results__option--load-more\"' +\n      'role=\"treeitem\" aria-disabled=\"true\"></li>'\n    );\n\n    var message = this.options.get('translations').get('loadingMore');\n\n    $option.html(message(this.lastParams));\n\n    return $option;\n  };\n\n  return InfiniteScroll;\n});\n\nS2.define('select2/dropdown/attachBody',[\n  'jquery',\n  '../utils'\n], function ($, Utils) {\n  function AttachBody (decorated, $element, options) {\n    this.$dropdownParent = options.get('dropdownParent') || $(document.body);\n\n    decorated.call(this, $element, options);\n  }\n\n  AttachBody.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    var setupResultsEvents = false;\n\n    decorated.call(this, container, $container);\n\n    container.on('open', function () {\n      self._showDropdown();\n      self._attachPositioningHandler(container);\n\n      if (!setupResultsEvents) {\n        setupResultsEvents = true;\n\n        container.on('results:all', function () {\n          self._positionDropdown();\n          self._resizeDropdown();\n        });\n\n        container.on('results:append', function () {\n          self._positionDropdown();\n          self._resizeDropdown();\n        });\n      }\n    });\n\n    container.on('close', function () {\n      self._hideDropdown();\n      self._detachPositioningHandler(container);\n    });\n\n    this.$dropdownContainer.on('mousedown', function (evt) {\n      evt.stopPropagation();\n    });\n  };\n\n  AttachBody.prototype.destroy = function (decorated) {\n    decorated.call(this);\n\n    this.$dropdownContainer.remove();\n  };\n\n  AttachBody.prototype.position = function (decorated, $dropdown, $container) {\n    // Clone all of the container classes\n    $dropdown.attr('class', $container.attr('class'));\n\n    $dropdown.removeClass('select2');\n    $dropdown.addClass('select2-container--open');\n\n    $dropdown.css({\n      position: 'absolute',\n      top: -999999\n    });\n\n    this.$container = $container;\n  };\n\n  AttachBody.prototype.render = function (decorated) {\n    var $container = $('<span></span>');\n\n    var $dropdown = decorated.call(this);\n    $container.append($dropdown);\n\n    this.$dropdownContainer = $container;\n\n    return $container;\n  };\n\n  AttachBody.prototype._hideDropdown = function (decorated) {\n    this.$dropdownContainer.detach();\n  };\n\n  AttachBody.prototype._attachPositioningHandler =\n      function (decorated, container) {\n    var self = this;\n\n    var scrollEvent = 'scroll.select2.' + container.id;\n    var resizeEvent = 'resize.select2.' + container.id;\n    var orientationEvent = 'orientationchange.select2.' + container.id;\n\n    var $watchers = this.$container.parents().filter(Utils.hasScroll);\n    $watchers.each(function () {\n      $(this).data('select2-scroll-position', {\n        x: $(this).scrollLeft(),\n        y: $(this).scrollTop()\n      });\n    });\n\n    $watchers.on(scrollEvent, function (ev) {\n      var position = $(this).data('select2-scroll-position');\n      $(this).scrollTop(position.y);\n    });\n\n    $(window).on(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent,\n      function (e) {\n      self._positionDropdown();\n      self._resizeDropdown();\n    });\n  };\n\n  AttachBody.prototype._detachPositioningHandler =\n      function (decorated, container) {\n    var scrollEvent = 'scroll.select2.' + container.id;\n    var resizeEvent = 'resize.select2.' + container.id;\n    var orientationEvent = 'orientationchange.select2.' + container.id;\n\n    var $watchers = this.$container.parents().filter(Utils.hasScroll);\n    $watchers.off(scrollEvent);\n\n    $(window).off(scrollEvent + ' ' + resizeEvent + ' ' + orientationEvent);\n  };\n\n  AttachBody.prototype._positionDropdown = function () {\n    var $window = $(window);\n\n    var isCurrentlyAbove = this.$dropdown.hasClass('select2-dropdown--above');\n    var isCurrentlyBelow = this.$dropdown.hasClass('select2-dropdown--below');\n\n    var newDirection = null;\n\n    var position = this.$container.position();\n    var offset = this.$container.offset();\n\n    offset.bottom = offset.top + this.$container.outerHeight(false);\n\n    var container = {\n      height: this.$container.outerHeight(false)\n    };\n\n    container.top = offset.top;\n    container.bottom = offset.top + container.height;\n\n    var dropdown = {\n      height: this.$dropdown.outerHeight(false)\n    };\n\n    var viewport = {\n      top: $window.scrollTop(),\n      bottom: $window.scrollTop() + $window.height()\n    };\n\n    var enoughRoomAbove = viewport.top < (offset.top - dropdown.height);\n    var enoughRoomBelow = viewport.bottom > (offset.bottom + dropdown.height);\n\n    var css = {\n      left: offset.left,\n      top: container.bottom\n    };\n\n    // Fix positioning with static parents\n    if (this.$dropdownParent[0].style.position !== 'static') {\n      var parentOffset = this.$dropdownParent.offset();\n\n      css.top -= parentOffset.top;\n      css.left -= parentOffset.left;\n    }\n\n    if (!isCurrentlyAbove && !isCurrentlyBelow) {\n      newDirection = 'below';\n    }\n\n    if (!enoughRoomBelow && enoughRoomAbove && !isCurrentlyAbove) {\n      newDirection = 'above';\n    } else if (!enoughRoomAbove && enoughRoomBelow && isCurrentlyAbove) {\n      newDirection = 'below';\n    }\n\n    if (newDirection == 'above' ||\n      (isCurrentlyAbove && newDirection !== 'below')) {\n      css.top = container.top - dropdown.height;\n    }\n\n    if (newDirection != null) {\n      this.$dropdown\n        .removeClass('select2-dropdown--below select2-dropdown--above')\n        .addClass('select2-dropdown--' + newDirection);\n      this.$container\n        .removeClass('select2-container--below select2-container--above')\n        .addClass('select2-container--' + newDirection);\n    }\n\n    this.$dropdownContainer.css(css);\n  };\n\n  AttachBody.prototype._resizeDropdown = function () {\n    var css = {\n      width: this.$container.outerWidth(false) + 'px'\n    };\n\n    if (this.options.get('dropdownAutoWidth')) {\n      css.minWidth = css.width;\n      css.width = 'auto';\n    }\n\n    this.$dropdown.css(css);\n  };\n\n  AttachBody.prototype._showDropdown = function (decorated) {\n    this.$dropdownContainer.appendTo(this.$dropdownParent);\n\n    this._positionDropdown();\n    this._resizeDropdown();\n  };\n\n  return AttachBody;\n});\n\nS2.define('select2/dropdown/minimumResultsForSearch',[\n\n], function () {\n  function countResults (data) {\n    var count = 0;\n\n    for (var d = 0; d < data.length; d++) {\n      var item = data[d];\n\n      if (item.children) {\n        count += countResults(item.children);\n      } else {\n        count++;\n      }\n    }\n\n    return count;\n  }\n\n  function MinimumResultsForSearch (decorated, $element, options, dataAdapter) {\n    this.minimumResultsForSearch = options.get('minimumResultsForSearch');\n\n    if (this.minimumResultsForSearch < 0) {\n      this.minimumResultsForSearch = Infinity;\n    }\n\n    decorated.call(this, $element, options, dataAdapter);\n  }\n\n  MinimumResultsForSearch.prototype.showSearch = function (decorated, params) {\n    if (countResults(params.data.results) < this.minimumResultsForSearch) {\n      return false;\n    }\n\n    return decorated.call(this, params);\n  };\n\n  return MinimumResultsForSearch;\n});\n\nS2.define('select2/dropdown/selectOnClose',[\n\n], function () {\n  function SelectOnClose () { }\n\n  SelectOnClose.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    decorated.call(this, container, $container);\n\n    container.on('close', function () {\n      self._handleSelectOnClose();\n    });\n  };\n\n  SelectOnClose.prototype._handleSelectOnClose = function () {\n    var $highlightedResults = this.getHighlightedResults();\n\n    // Only select highlighted results\n    if ($highlightedResults.length < 1) {\n      return;\n    }\n\n    var data = $highlightedResults.data('data');\n\n    // Don't re-select already selected resulte\n    if (\n      (data.element != null && data.element.selected) ||\n      (data.element == null && data.selected)\n    ) {\n      return;\n    }\n\n    this.trigger('select', {\n        data: data\n    });\n  };\n\n  return SelectOnClose;\n});\n\nS2.define('select2/dropdown/closeOnSelect',[\n\n], function () {\n  function CloseOnSelect () { }\n\n  CloseOnSelect.prototype.bind = function (decorated, container, $container) {\n    var self = this;\n\n    decorated.call(this, container, $container);\n\n    container.on('select', function (evt) {\n      self._selectTriggered(evt);\n    });\n\n    container.on('unselect', function (evt) {\n      self._selectTriggered(evt);\n    });\n  };\n\n  CloseOnSelect.prototype._selectTriggered = function (_, evt) {\n    var originalEvent = evt.originalEvent;\n\n    // Don't close if the control key is being held\n    if (originalEvent && originalEvent.ctrlKey) {\n      return;\n    }\n\n    this.trigger('close', {});\n  };\n\n  return CloseOnSelect;\n});\n\nS2.define('select2/i18n/en',[],function () {\n  // English\n  return {\n    errorLoading: function () {\n      return 'The results could not be loaded.';\n    },\n    inputTooLong: function (args) {\n      var overChars = args.input.length - args.maximum;\n\n      var message = 'Please delete ' + overChars + ' character';\n\n      if (overChars != 1) {\n        message += 's';\n      }\n\n      return message;\n    },\n    inputTooShort: function (args) {\n      var remainingChars = args.minimum - args.input.length;\n\n      var message = 'Please enter ' + remainingChars + ' or more characters';\n\n      return message;\n    },\n    loadingMore: function () {\n      return 'Loading more results…';\n    },\n    maximumSelected: function (args) {\n      var message = 'You can only select ' + args.maximum + ' item';\n\n      if (args.maximum != 1) {\n        message += 's';\n      }\n\n      return message;\n    },\n    noResults: function () {\n      return 'No results found';\n    },\n    searching: function () {\n      return 'Searching…';\n    }\n  };\n});\n\nS2.define('select2/defaults',[\n  'jquery',\n  'require',\n\n  './results',\n\n  './selection/single',\n  './selection/multiple',\n  './selection/placeholder',\n  './selection/allowClear',\n  './selection/search',\n  './selection/eventRelay',\n\n  './utils',\n  './translation',\n  './diacritics',\n\n  './data/select',\n  './data/array',\n  './data/ajax',\n  './data/tags',\n  './data/tokenizer',\n  './data/minimumInputLength',\n  './data/maximumInputLength',\n  './data/maximumSelectionLength',\n\n  './dropdown',\n  './dropdown/search',\n  './dropdown/hidePlaceholder',\n  './dropdown/infiniteScroll',\n  './dropdown/attachBody',\n  './dropdown/minimumResultsForSearch',\n  './dropdown/selectOnClose',\n  './dropdown/closeOnSelect',\n\n  './i18n/en'\n], function ($, require,\n\n             ResultsList,\n\n             SingleSelection, MultipleSelection, Placeholder, AllowClear,\n             SelectionSearch, EventRelay,\n\n             Utils, Translation, DIACRITICS,\n\n             SelectData, ArrayData, AjaxData, Tags, Tokenizer,\n             MinimumInputLength, MaximumInputLength, MaximumSelectionLength,\n\n             Dropdown, DropdownSearch, HidePlaceholder, InfiniteScroll,\n             AttachBody, MinimumResultsForSearch, SelectOnClose, CloseOnSelect,\n\n             EnglishTranslation) {\n  function Defaults () {\n    this.reset();\n  }\n\n  Defaults.prototype.apply = function (options) {\n    options = $.extend({}, this.defaults, options);\n\n    if (options.dataAdapter == null) {\n      if (options.ajax != null) {\n        options.dataAdapter = AjaxData;\n      } else if (options.data != null) {\n        options.dataAdapter = ArrayData;\n      } else {\n        options.dataAdapter = SelectData;\n      }\n\n      if (options.minimumInputLength > 0) {\n        options.dataAdapter = Utils.Decorate(\n          options.dataAdapter,\n          MinimumInputLength\n        );\n      }\n\n      if (options.maximumInputLength > 0) {\n        options.dataAdapter = Utils.Decorate(\n          options.dataAdapter,\n          MaximumInputLength\n        );\n      }\n\n      if (options.maximumSelectionLength > 0) {\n        options.dataAdapter = Utils.Decorate(\n          options.dataAdapter,\n          MaximumSelectionLength\n        );\n      }\n\n      if (options.tags) {\n        options.dataAdapter = Utils.Decorate(options.dataAdapter, Tags);\n      }\n\n      if (options.tokenSeparators != null || options.tokenizer != null) {\n        options.dataAdapter = Utils.Decorate(\n          options.dataAdapter,\n          Tokenizer\n        );\n      }\n\n      if (options.query != null) {\n        var Query = require(options.amdBase + 'compat/query');\n\n        options.dataAdapter = Utils.Decorate(\n          options.dataAdapter,\n          Query\n        );\n      }\n\n      if (options.initSelection != null) {\n        var InitSelection = require(options.amdBase + 'compat/initSelection');\n\n        options.dataAdapter = Utils.Decorate(\n          options.dataAdapter,\n          InitSelection\n        );\n      }\n    }\n\n    if (options.resultsAdapter == null) {\n      options.resultsAdapter = ResultsList;\n\n      if (options.ajax != null) {\n        options.resultsAdapter = Utils.Decorate(\n          options.resultsAdapter,\n          InfiniteScroll\n        );\n      }\n\n      if (options.placeholder != null) {\n        options.resultsAdapter = Utils.Decorate(\n          options.resultsAdapter,\n          HidePlaceholder\n        );\n      }\n\n      if (options.selectOnClose) {\n        options.resultsAdapter = Utils.Decorate(\n          options.resultsAdapter,\n          SelectOnClose\n        );\n      }\n    }\n\n    if (options.dropdownAdapter == null) {\n      if (options.multiple) {\n        options.dropdownAdapter = Dropdown;\n      } else {\n        var SearchableDropdown = Utils.Decorate(Dropdown, DropdownSearch);\n\n        options.dropdownAdapter = SearchableDropdown;\n      }\n\n      if (options.minimumResultsForSearch !== 0) {\n        options.dropdownAdapter = Utils.Decorate(\n          options.dropdownAdapter,\n          MinimumResultsForSearch\n        );\n      }\n\n      if (options.closeOnSelect) {\n        options.dropdownAdapter = Utils.Decorate(\n          options.dropdownAdapter,\n          CloseOnSelect\n        );\n      }\n\n      if (\n        options.dropdownCssClass != null ||\n        options.dropdownCss != null ||\n        options.adaptDropdownCssClass != null\n      ) {\n        var DropdownCSS = require(options.amdBase + 'compat/dropdownCss');\n\n        options.dropdownAdapter = Utils.Decorate(\n          options.dropdownAdapter,\n          DropdownCSS\n        );\n      }\n\n      options.dropdownAdapter = Utils.Decorate(\n        options.dropdownAdapter,\n        AttachBody\n      );\n    }\n\n    if (options.selectionAdapter == null) {\n      if (options.multiple) {\n        options.selectionAdapter = MultipleSelection;\n      } else {\n        options.selectionAdapter = SingleSelection;\n      }\n\n      // Add the placeholder mixin if a placeholder was specified\n      if (options.placeholder != null) {\n        options.selectionAdapter = Utils.Decorate(\n          options.selectionAdapter,\n          Placeholder\n        );\n      }\n\n      if (options.allowClear) {\n        options.selectionAdapter = Utils.Decorate(\n          options.selectionAdapter,\n          AllowClear\n        );\n      }\n\n      if (options.multiple) {\n        options.selectionAdapter = Utils.Decorate(\n          options.selectionAdapter,\n          SelectionSearch\n        );\n      }\n\n      if (\n        options.containerCssClass != null ||\n        options.containerCss != null ||\n        options.adaptContainerCssClass != null\n      ) {\n        var ContainerCSS = require(options.amdBase + 'compat/containerCss');\n\n        options.selectionAdapter = Utils.Decorate(\n          options.selectionAdapter,\n          ContainerCSS\n        );\n      }\n\n      options.selectionAdapter = Utils.Decorate(\n        options.selectionAdapter,\n        EventRelay\n      );\n    }\n\n    if (typeof options.language === 'string') {\n      // Check if the language is specified with a region\n      if (options.language.indexOf('-') > 0) {\n        // Extract the region information if it is included\n        var languageParts = options.language.split('-');\n        var baseLanguage = languageParts[0];\n\n        options.language = [options.language, baseLanguage];\n      } else {\n        options.language = [options.language];\n      }\n    }\n\n    if ($.isArray(options.language)) {\n      var languages = new Translation();\n      options.language.push('en');\n\n      var languageNames = options.language;\n\n      for (var l = 0; l < languageNames.length; l++) {\n        var name = languageNames[l];\n        var language = {};\n\n        try {\n          // Try to load it with the original name\n          language = Translation.loadPath(name);\n        } catch (e) {\n          try {\n            // If we couldn't load it, check if it wasn't the full path\n            name = this.defaults.amdLanguageBase + name;\n            language = Translation.loadPath(name);\n          } catch (ex) {\n            // The translation could not be loaded at all. Sometimes this is\n            // because of a configuration problem, other times this can be\n            // because of how Select2 helps load all possible translation files.\n            if (options.debug && window.console && console.warn) {\n              console.warn(\n                'Select2: The language file for \"' + name + '\" could not be ' +\n                'automatically loaded. A fallback will be used instead.'\n              );\n            }\n\n            continue;\n          }\n        }\n\n        languages.extend(language);\n      }\n\n      options.translations = languages;\n    } else {\n      var baseTranslation = Translation.loadPath(\n        this.defaults.amdLanguageBase + 'en'\n      );\n      var customTranslation = new Translation(options.language);\n\n      customTranslation.extend(baseTranslation);\n\n      options.translations = customTranslation;\n    }\n\n    return options;\n  };\n\n  Defaults.prototype.reset = function () {\n    function stripDiacritics (text) {\n      // Used 'uni range + named function' from http://jsperf.com/diacritics/18\n      function match(a) {\n        return DIACRITICS[a] || a;\n      }\n\n      return text.replace(/[^\\u0000-\\u007E]/g, match);\n    }\n\n    function matcher (params, data) {\n      // Always return the object if there is nothing to compare\n      if ($.trim(params.term) === '') {\n        return data;\n      }\n\n      // Do a recursive check for options with children\n      if (data.children && data.children.length > 0) {\n        // Clone the data object if there are children\n        // This is required as we modify the object to remove any non-matches\n        var match = $.extend(true, {}, data);\n\n        // Check each child of the option\n        for (var c = data.children.length - 1; c >= 0; c--) {\n          var child = data.children[c];\n\n          var matches = matcher(params, child);\n\n          // If there wasn't a match, remove the object in the array\n          if (matches == null) {\n            match.children.splice(c, 1);\n          }\n        }\n\n        // If any children matched, return the new object\n        if (match.children.length > 0) {\n          return match;\n        }\n\n        // If there were no matching children, check just the plain object\n        return matcher(params, match);\n      }\n\n      var original = stripDiacritics(data.text).toUpperCase();\n      var term = stripDiacritics(params.term).toUpperCase();\n\n      // Check if the text contains the term\n      if (original.indexOf(term) > -1) {\n        return data;\n      }\n\n      // If it doesn't contain the term, don't return anything\n      return null;\n    }\n\n    this.defaults = {\n      amdBase: './',\n      amdLanguageBase: './i18n/',\n      closeOnSelect: true,\n      debug: false,\n      dropdownAutoWidth: false,\n      escapeMarkup: Utils.escapeMarkup,\n      language: EnglishTranslation,\n      matcher: matcher,\n      minimumInputLength: 0,\n      maximumInputLength: 0,\n      maximumSelectionLength: 0,\n      minimumResultsForSearch: 0,\n      selectOnClose: false,\n      sorter: function (data) {\n        return data;\n      },\n      templateResult: function (result) {\n        return result.text;\n      },\n      templateSelection: function (selection) {\n        return selection.text;\n      },\n      theme: 'default',\n      width: 'resolve'\n    };\n  };\n\n  Defaults.prototype.set = function (key, value) {\n    var camelKey = $.camelCase(key);\n\n    var data = {};\n    data[camelKey] = value;\n\n    var convertedData = Utils._convertData(data);\n\n    $.extend(this.defaults, convertedData);\n  };\n\n  var defaults = new Defaults();\n\n  return defaults;\n});\n\nS2.define('select2/options',[\n  'require',\n  'jquery',\n  './defaults',\n  './utils'\n], function (require, $, Defaults, Utils) {\n  function Options (options, $element) {\n    this.options = options;\n\n    if ($element != null) {\n      this.fromElement($element);\n    }\n\n    this.options = Defaults.apply(this.options);\n\n    if ($element && $element.is('input')) {\n      var InputCompat = require(this.get('amdBase') + 'compat/inputData');\n\n      this.options.dataAdapter = Utils.Decorate(\n        this.options.dataAdapter,\n        InputCompat\n      );\n    }\n  }\n\n  Options.prototype.fromElement = function ($e) {\n    var excludedData = ['select2'];\n\n    if (this.options.multiple == null) {\n      this.options.multiple = $e.prop('multiple');\n    }\n\n    if (this.options.disabled == null) {\n      this.options.disabled = $e.prop('disabled');\n    }\n\n    if (this.options.language == null) {\n      if ($e.prop('lang')) {\n        this.options.language = $e.prop('lang').toLowerCase();\n      } else if ($e.closest('[lang]').prop('lang')) {\n        this.options.language = $e.closest('[lang]').prop('lang');\n      }\n    }\n\n    if (this.options.dir == null) {\n      if ($e.prop('dir')) {\n        this.options.dir = $e.prop('dir');\n      } else if ($e.closest('[dir]').prop('dir')) {\n        this.options.dir = $e.closest('[dir]').prop('dir');\n      } else {\n        this.options.dir = 'ltr';\n      }\n    }\n\n    $e.prop('disabled', this.options.disabled);\n    $e.prop('multiple', this.options.multiple);\n\n    if ($e.data('select2Tags')) {\n      if (this.options.debug && window.console && console.warn) {\n        console.warn(\n          'Select2: The `data-select2-tags` attribute has been changed to ' +\n          'use the `data-data` and `data-tags=\"true\"` attributes and will be ' +\n          'removed in future versions of Select2.'\n        );\n      }\n\n      $e.data('data', $e.data('select2Tags'));\n      $e.data('tags', true);\n    }\n\n    if ($e.data('ajaxUrl')) {\n      if (this.options.debug && window.console && console.warn) {\n        console.warn(\n          'Select2: The `data-ajax-url` attribute has been changed to ' +\n          '`data-ajax--url` and support for the old attribute will be removed' +\n          ' in future versions of Select2.'\n        );\n      }\n\n      $e.attr('ajax--url', $e.data('ajaxUrl'));\n      $e.data('ajax--url', $e.data('ajaxUrl'));\n    }\n\n    var dataset = {};\n\n    // Prefer the element's `dataset` attribute if it exists\n    // jQuery 1.x does not correctly handle data attributes with multiple dashes\n    if ($.fn.jquery && $.fn.jquery.substr(0, 2) == '1.' && $e[0].dataset) {\n      dataset = $.extend(true, {}, $e[0].dataset, $e.data());\n    } else {\n      dataset = $e.data();\n    }\n\n    var data = $.extend(true, {}, dataset);\n\n    data = Utils._convertData(data);\n\n    for (var key in data) {\n      if ($.inArray(key, excludedData) > -1) {\n        continue;\n      }\n\n      if ($.isPlainObject(this.options[key])) {\n        $.extend(this.options[key], data[key]);\n      } else {\n        this.options[key] = data[key];\n      }\n    }\n\n    return this;\n  };\n\n  Options.prototype.get = function (key) {\n    return this.options[key];\n  };\n\n  Options.prototype.set = function (key, val) {\n    this.options[key] = val;\n  };\n\n  return Options;\n});\n\nS2.define('select2/core',[\n  'jquery',\n  './options',\n  './utils',\n  './keys'\n], function ($, Options, Utils, KEYS) {\n  var Select2 = function ($element, options) {\n    if ($element.data('select2') != null) {\n      $element.data('select2').destroy();\n    }\n\n    this.$element = $element;\n\n    this.id = this._generateId($element);\n\n    options = options || {};\n\n    this.options = new Options(options, $element);\n\n    Select2.__super__.constructor.call(this);\n\n    // Set up the tabindex\n\n    var tabindex = $element.attr('tabindex') || 0;\n    $element.data('old-tabindex', tabindex);\n    $element.attr('tabindex', '-1');\n\n    // Set up containers and adapters\n\n    var DataAdapter = this.options.get('dataAdapter');\n    this.dataAdapter = new DataAdapter($element, this.options);\n\n    var $container = this.render();\n\n    this._placeContainer($container);\n\n    var SelectionAdapter = this.options.get('selectionAdapter');\n    this.selection = new SelectionAdapter($element, this.options);\n    this.$selection = this.selection.render();\n\n    this.selection.position(this.$selection, $container);\n\n    var DropdownAdapter = this.options.get('dropdownAdapter');\n    this.dropdown = new DropdownAdapter($element, this.options);\n    this.$dropdown = this.dropdown.render();\n\n    this.dropdown.position(this.$dropdown, $container);\n\n    var ResultsAdapter = this.options.get('resultsAdapter');\n    this.results = new ResultsAdapter($element, this.options, this.dataAdapter);\n    this.$results = this.results.render();\n\n    this.results.position(this.$results, this.$dropdown);\n\n    // Bind events\n\n    var self = this;\n\n    // Bind the container to all of the adapters\n    this._bindAdapters();\n\n    // Register any DOM event handlers\n    this._registerDomEvents();\n\n    // Register any internal event handlers\n    this._registerDataEvents();\n    this._registerSelectionEvents();\n    this._registerDropdownEvents();\n    this._registerResultsEvents();\n    this._registerEvents();\n\n    // Set the initial state\n    this.dataAdapter.current(function (initialData) {\n      self.trigger('selection:update', {\n        data: initialData\n      });\n    });\n\n    // Hide the original select\n    $element.addClass('select2-hidden-accessible');\n    $element.attr('aria-hidden', 'true');\n\n    // Synchronize any monitored attributes\n    this._syncAttributes();\n\n    $element.data('select2', this);\n  };\n\n  Utils.Extend(Select2, Utils.Observable);\n\n  Select2.prototype._generateId = function ($element) {\n    var id = '';\n\n    if ($element.attr('id') != null) {\n      id = $element.attr('id');\n    } else if ($element.attr('name') != null) {\n      id = $element.attr('name') + '-' + Utils.generateChars(2);\n    } else {\n      id = Utils.generateChars(4);\n    }\n\n    id = 'select2-' + id;\n\n    return id;\n  };\n\n  Select2.prototype._placeContainer = function ($container) {\n    $container.insertAfter(this.$element);\n\n    var width = this._resolveWidth(this.$element, this.options.get('width'));\n\n    if (width != null) {\n      $container.css('width', width);\n    }\n  };\n\n  Select2.prototype._resolveWidth = function ($element, method) {\n    var WIDTH = /^width:(([-+]?([0-9]*\\.)?[0-9]+)(px|em|ex|%|in|cm|mm|pt|pc))/i;\n\n    if (method == 'resolve') {\n      var styleWidth = this._resolveWidth($element, 'style');\n\n      if (styleWidth != null) {\n        return styleWidth;\n      }\n\n      return this._resolveWidth($element, 'element');\n    }\n\n    if (method == 'element') {\n      var elementWidth = $element.outerWidth(false);\n\n      if (elementWidth <= 0) {\n        return 'auto';\n      }\n\n      return elementWidth + 'px';\n    }\n\n    if (method == 'style') {\n      var style = $element.attr('style');\n\n      if (typeof(style) !== 'string') {\n        return null;\n      }\n\n      var attrs = style.split(';');\n\n      for (var i = 0, l = attrs.length; i < l; i = i + 1) {\n        var attr = attrs[i].replace(/\\s/g, '');\n        var matches = attr.match(WIDTH);\n\n        if (matches !== null && matches.length >= 1) {\n          return matches[1];\n        }\n      }\n\n      return null;\n    }\n\n    return method;\n  };\n\n  Select2.prototype._bindAdapters = function () {\n    this.dataAdapter.bind(this, this.$container);\n    this.selection.bind(this, this.$container);\n\n    this.dropdown.bind(this, this.$container);\n    this.results.bind(this, this.$container);\n  };\n\n  Select2.prototype._registerDomEvents = function () {\n    var self = this;\n\n    this.$element.on('change.select2', function () {\n      self.dataAdapter.current(function (data) {\n        self.trigger('selection:update', {\n          data: data\n        });\n      });\n    });\n\n    this._sync = Utils.bind(this._syncAttributes, this);\n\n    if (this.$element[0].attachEvent) {\n      this.$element[0].attachEvent('onpropertychange', this._sync);\n    }\n\n    var observer = window.MutationObserver ||\n      window.WebKitMutationObserver ||\n      window.MozMutationObserver\n    ;\n\n    if (observer != null) {\n      this._observer = new observer(function (mutations) {\n        $.each(mutations, self._sync);\n      });\n      this._observer.observe(this.$element[0], {\n        attributes: true,\n        subtree: false\n      });\n    } else if (this.$element[0].addEventListener) {\n      this.$element[0].addEventListener('DOMAttrModified', self._sync, false);\n    }\n  };\n\n  Select2.prototype._registerDataEvents = function () {\n    var self = this;\n\n    this.dataAdapter.on('*', function (name, params) {\n      self.trigger(name, params);\n    });\n  };\n\n  Select2.prototype._registerSelectionEvents = function () {\n    var self = this;\n    var nonRelayEvents = ['toggle', 'focus'];\n\n    this.selection.on('toggle', function () {\n      self.toggleDropdown();\n    });\n\n    this.selection.on('focus', function (params) {\n      self.focus(params);\n    });\n\n    this.selection.on('*', function (name, params) {\n      if ($.inArray(name, nonRelayEvents) !== -1) {\n        return;\n      }\n\n      self.trigger(name, params);\n    });\n  };\n\n  Select2.prototype._registerDropdownEvents = function () {\n    var self = this;\n\n    this.dropdown.on('*', function (name, params) {\n      self.trigger(name, params);\n    });\n  };\n\n  Select2.prototype._registerResultsEvents = function () {\n    var self = this;\n\n    this.results.on('*', function (name, params) {\n      self.trigger(name, params);\n    });\n  };\n\n  Select2.prototype._registerEvents = function () {\n    var self = this;\n\n    this.on('open', function () {\n      self.$container.addClass('select2-container--open');\n    });\n\n    this.on('close', function () {\n      self.$container.removeClass('select2-container--open');\n    });\n\n    this.on('enable', function () {\n      self.$container.removeClass('select2-container--disabled');\n    });\n\n    this.on('disable', function () {\n      self.$container.addClass('select2-container--disabled');\n    });\n\n    this.on('blur', function () {\n      self.$container.removeClass('select2-container--focus');\n    });\n\n    this.on('query', function (params) {\n      if (!self.isOpen()) {\n        self.trigger('open', {});\n      }\n\n      this.dataAdapter.query(params, function (data) {\n        self.trigger('results:all', {\n          data: data,\n          query: params\n        });\n      });\n    });\n\n    this.on('query:append', function (params) {\n      this.dataAdapter.query(params, function (data) {\n        self.trigger('results:append', {\n          data: data,\n          query: params\n        });\n      });\n    });\n\n    this.on('keypress', function (evt) {\n      var key = evt.which;\n\n      if (self.isOpen()) {\n        if (key === KEYS.ESC || key === KEYS.TAB ||\n            (key === KEYS.UP && evt.altKey)) {\n          self.close();\n\n          evt.preventDefault();\n        } else if (key === KEYS.ENTER) {\n          self.trigger('results:select', {});\n\n          evt.preventDefault();\n        } else if ((key === KEYS.SPACE && evt.ctrlKey)) {\n          self.trigger('results:toggle', {});\n\n          evt.preventDefault();\n        } else if (key === KEYS.UP) {\n          self.trigger('results:previous', {});\n\n          evt.preventDefault();\n        } else if (key === KEYS.DOWN) {\n          self.trigger('results:next', {});\n\n          evt.preventDefault();\n        }\n      } else {\n        if (key === KEYS.ENTER || key === KEYS.SPACE ||\n            (key === KEYS.DOWN && evt.altKey)) {\n          self.open();\n\n          evt.preventDefault();\n        }\n      }\n    });\n  };\n\n  Select2.prototype._syncAttributes = function () {\n    this.options.set('disabled', this.$element.prop('disabled'));\n\n    if (this.options.get('disabled')) {\n      if (this.isOpen()) {\n        this.close();\n      }\n\n      this.trigger('disable', {});\n    } else {\n      this.trigger('enable', {});\n    }\n  };\n\n  /**\n   * Override the trigger method to automatically trigger pre-events when\n   * there are events that can be prevented.\n   */\n  Select2.prototype.trigger = function (name, args) {\n    var actualTrigger = Select2.__super__.trigger;\n    var preTriggerMap = {\n      'open': 'opening',\n      'close': 'closing',\n      'select': 'selecting',\n      'unselect': 'unselecting'\n    };\n\n    if (args === undefined) {\n      args = {};\n    }\n\n    if (name in preTriggerMap) {\n      var preTriggerName = preTriggerMap[name];\n      var preTriggerArgs = {\n        prevented: false,\n        name: name,\n        args: args\n      };\n\n      actualTrigger.call(this, preTriggerName, preTriggerArgs);\n\n      if (preTriggerArgs.prevented) {\n        args.prevented = true;\n\n        return;\n      }\n    }\n\n    actualTrigger.call(this, name, args);\n  };\n\n  Select2.prototype.toggleDropdown = function () {\n    if (this.options.get('disabled')) {\n      return;\n    }\n\n    if (this.isOpen()) {\n      this.close();\n    } else {\n      this.open();\n    }\n  };\n\n  Select2.prototype.open = function () {\n    if (this.isOpen()) {\n      return;\n    }\n\n    this.trigger('query', {});\n  };\n\n  Select2.prototype.close = function () {\n    if (!this.isOpen()) {\n      return;\n    }\n\n    this.trigger('close', {});\n  };\n\n  Select2.prototype.isOpen = function () {\n    return this.$container.hasClass('select2-container--open');\n  };\n\n  Select2.prototype.hasFocus = function () {\n    return this.$container.hasClass('select2-container--focus');\n  };\n\n  Select2.prototype.focus = function (data) {\n    // No need to re-trigger focus events if we are already focused\n    if (this.hasFocus()) {\n      return;\n    }\n\n    this.$container.addClass('select2-container--focus');\n    this.trigger('focus', {});\n  };\n\n  Select2.prototype.enable = function (args) {\n    if (this.options.get('debug') && window.console && console.warn) {\n      console.warn(\n        'Select2: The `select2(\"enable\")` method has been deprecated and will' +\n        ' be removed in later Select2 versions. Use $element.prop(\"disabled\")' +\n        ' instead.'\n      );\n    }\n\n    if (args == null || args.length === 0) {\n      args = [true];\n    }\n\n    var disabled = !args[0];\n\n    this.$element.prop('disabled', disabled);\n  };\n\n  Select2.prototype.data = function () {\n    if (this.options.get('debug') &&\n        arguments.length > 0 && window.console && console.warn) {\n      console.warn(\n        'Select2: Data can no longer be set using `select2(\"data\")`. You ' +\n        'should consider setting the value instead using `$element.val()`.'\n      );\n    }\n\n    var data = [];\n\n    this.dataAdapter.current(function (currentData) {\n      data = currentData;\n    });\n\n    return data;\n  };\n\n  Select2.prototype.val = function (args) {\n    if (this.options.get('debug') && window.console && console.warn) {\n      console.warn(\n        'Select2: The `select2(\"val\")` method has been deprecated and will be' +\n        ' removed in later Select2 versions. Use $element.val() instead.'\n      );\n    }\n\n    if (args == null || args.length === 0) {\n      return this.$element.val();\n    }\n\n    var newVal = args[0];\n\n    if ($.isArray(newVal)) {\n      newVal = $.map(newVal, function (obj) {\n        return obj.toString();\n      });\n    }\n\n    this.$element.val(newVal).trigger('change');\n  };\n\n  Select2.prototype.destroy = function () {\n    this.$container.remove();\n\n    if (this.$element[0].detachEvent) {\n      this.$element[0].detachEvent('onpropertychange', this._sync);\n    }\n\n    if (this._observer != null) {\n      this._observer.disconnect();\n      this._observer = null;\n    } else if (this.$element[0].removeEventListener) {\n      this.$element[0]\n        .removeEventListener('DOMAttrModified', this._sync, false);\n    }\n\n    this._sync = null;\n\n    this.$element.off('.select2');\n    this.$element.attr('tabindex', this.$element.data('old-tabindex'));\n\n    this.$element.removeClass('select2-hidden-accessible');\n    this.$element.attr('aria-hidden', 'false');\n    this.$element.removeData('select2');\n\n    this.dataAdapter.destroy();\n    this.selection.destroy();\n    this.dropdown.destroy();\n    this.results.destroy();\n\n    this.dataAdapter = null;\n    this.selection = null;\n    this.dropdown = null;\n    this.results = null;\n  };\n\n  Select2.prototype.render = function () {\n    var $container = $(\n      '<span class=\"select2 select2-container\">' +\n        '<span class=\"selection\"></span>' +\n        '<span class=\"dropdown-wrapper\" aria-hidden=\"true\"></span>' +\n      '</span>'\n    );\n\n    $container.attr('dir', this.options.get('dir'));\n\n    this.$container = $container;\n\n    this.$container.addClass('select2-container--' + this.options.get('theme'));\n\n    $container.data('element', this.$element);\n\n    return $container;\n  };\n\n  return Select2;\n});\n\nS2.define('jquery-mousewheel',[\n  'jquery'\n], function ($) {\n  // Used to shim jQuery.mousewheel for non-full builds.\n  return $;\n});\n\nS2.define('jquery.select2',[\n  'jquery',\n  'jquery-mousewheel',\n\n  './select2/core',\n  './select2/defaults'\n], function ($, _, Select2, Defaults) {\n  if ($.fn.select2 == null) {\n    // All methods that should return the element\n    var thisMethods = ['open', 'close', 'destroy'];\n\n    $.fn.select2 = function (options) {\n      options = options || {};\n\n      if (typeof options === 'object') {\n        this.each(function () {\n          var instanceOptions = $.extend(true, {}, options);\n\n          var instance = new Select2($(this), instanceOptions);\n        });\n\n        return this;\n      } else if (typeof options === 'string') {\n        var ret;\n\n        this.each(function () {\n          var instance = $(this).data('select2');\n\n          if (instance == null && window.console && console.error) {\n            console.error(\n              'The select2(\\'' + options + '\\') method was called on an ' +\n              'element that is not using Select2.'\n            );\n          }\n\n          var args = Array.prototype.slice.call(arguments, 1);\n\n          ret = instance[options].apply(instance, args);\n        });\n\n        // Check if we should be returning `this`\n        if ($.inArray(options, thisMethods) > -1) {\n          return this;\n        }\n\n        return ret;\n      } else {\n        throw new Error('Invalid arguments for Select2: ' + options);\n      }\n    };\n  }\n\n  if ($.fn.select2.defaults == null) {\n    $.fn.select2.defaults = Defaults;\n  }\n\n  return Select2;\n});\n\n  // Return the AMD loader configuration so it can be used outside of this file\n  return {\n    define: S2.define,\n    require: S2.require\n  };\n}());\n\n  // Autoload the jQuery bindings\n  // We know that all of the modules exist above this, so we're safe\n  var select2 = S2.require('jquery.select2');\n\n  // Hold the AMD module references on the jQuery function that was just loaded\n  // This allows Select2 to use the internal loader outside of this file, such\n  // as in the language files.\n  jQuery.fn.select2.amd = S2;\n\n  // Return the Select2 instance for anyone who is importing it.\n  return select2;\n}));\n"
  },
  {
    "path": "public/static/plugins/slimScroll/jquery.slimscroll.js",
    "content": "/*! Copyright (c) 2011 Piotr Rochala (http://rocha.la)\n * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)\n * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.\n *\n * Version: 1.3.3\n *\n */\n(function ($) {\n\n  $.fn.extend({\n    slimScroll: function (options) {\n\n      var defaults = {\n        // width in pixels of the visible scroll area\n        width: 'auto',\n        // height in pixels of the visible scroll area\n        height: '250px',\n        // width in pixels of the scrollbar and rail\n        size: '7px',\n        // scrollbar color, accepts any hex/color value\n        color: '#000',\n        // scrollbar position - left/right\n        position: 'right',\n        // distance in pixels between the side edge and the scrollbar\n        distance: '1px',\n        // default scroll position on load - top / bottom / $('selector')\n        start: 'top',\n        // sets scrollbar opacity\n        opacity: .4,\n        // enables always-on mode for the scrollbar\n        alwaysVisible: false,\n        // check if we should hide the scrollbar when user is hovering over\n        disableFadeOut: false,\n        // sets visibility of the rail\n        railVisible: false,\n        // sets rail color\n        railColor: '#333',\n        // sets rail opacity\n        railOpacity: .2,\n        // whether  we should use jQuery UI Draggable to enable bar dragging\n        railDraggable: true,\n        // defautlt CSS class of the slimscroll rail\n        railClass: 'slimScrollRail',\n        // defautlt CSS class of the slimscroll bar\n        barClass: 'slimScrollBar',\n        // defautlt CSS class of the slimscroll wrapper\n        wrapperClass: 'slimScrollDiv',\n        // check if mousewheel should scroll the window if we reach top/bottom\n        allowPageScroll: false,\n        // scroll amount applied to each mouse wheel step\n        wheelStep: 20,\n        // scroll amount applied when user is using gestures\n        touchScrollStep: 200,\n        // sets border radius\n        borderRadius: '7px',\n        // sets border radius of the rail\n        railBorderRadius: '7px'\n      };\n\n      var o = $.extend(defaults, options);\n\n      // do it for every element that matches selector\n      this.each(function () {\n\n        var isOverPanel, isOverBar, isDragg, queueHide, touchDif,\n                barHeight, percentScroll, lastScroll,\n                divS = '<div></div>',\n                minBarHeight = 30,\n                releaseScroll = false;\n\n        // used in event handlers and for better minification\n        var me = $(this);\n\n        // ensure we are not binding it again\n        if (me.parent().hasClass(o.wrapperClass))\n        {\n          // start from last bar position\n          var offset = me.scrollTop();\n\n          // find bar and rail\n          bar = me.parent().find('.' + o.barClass);\n          rail = me.parent().find('.' + o.railClass);\n\n          getBarHeight();\n\n          // check if we should scroll existing instance\n          if ($.isPlainObject(options))\n          {\n            // Pass height: auto to an existing slimscroll object to force a resize after contents have changed\n            if ('height' in options && options.height == 'auto') {\n              me.parent().css('height', 'auto');\n              me.css('height', 'auto');\n              var height = me.parent().parent().height();\n              me.parent().css('height', height);\n              me.css('height', height);\n            }\n\n            if ('scrollTo' in options)\n            {\n              // jump to a static point\n              offset = parseInt(o.scrollTo);\n            }\n            else if ('scrollBy' in options)\n            {\n              // jump by value pixels\n              offset += parseInt(o.scrollBy);\n            }\n            else if ('destroy' in options)\n            {\n              // remove slimscroll elements\n              bar.remove();\n              rail.remove();\n              me.unwrap();\n              return;\n            }\n\n            // scroll content by the given offset\n            scrollContent(offset, false, true);\n          }\n\n          return;\n        }\n        else if ($.isPlainObject(options))\n        {\n          if ('destroy' in options)\n          {\n            return;\n          }\n        }\n\n        // optionally set height to the parent's height\n        o.height = (o.height == 'auto') ? me.parent().height() : o.height;\n\n        // wrap content\n        var wrapper = $(divS)\n                .addClass(o.wrapperClass)\n                .css({\n                  position: 'relative',\n                  overflow: 'hidden',\n                  width: o.width,\n                  height: o.height\n                });\n\n        // update style for the div\n        me.css({\n          overflow: 'hidden',\n          width: o.width,\n          height: o.height,\n          //Fix for IE10\n          \"-ms-touch-action\": \"none\"\n        });\n\n        // create scrollbar rail\n        var rail = $(divS)\n                .addClass(o.railClass)\n                .css({\n                  width: o.size,\n                  height: '100%',\n                  position: 'absolute',\n                  top: 0,\n                  display: (o.alwaysVisible && o.railVisible) ? 'block' : 'none',\n                  'border-radius': o.railBorderRadius,\n                  background: o.railColor,\n                  opacity: o.railOpacity,\n                  zIndex: 90\n                });\n\n        // create scrollbar\n        var bar = $(divS)\n                .addClass(o.barClass)\n                .css({\n                  background: o.color,\n                  width: o.size,\n                  position: 'absolute',\n                  top: 0,\n                  opacity: o.opacity,\n                  display: o.alwaysVisible ? 'block' : 'none',\n                  'border-radius': o.borderRadius,\n                  BorderRadius: o.borderRadius,\n                  MozBorderRadius: o.borderRadius,\n                  WebkitBorderRadius: o.borderRadius,\n                  zIndex: 99\n                });\n\n        // set position\n        var posCss = (o.position == 'right') ? {right: o.distance} : {left: o.distance};\n        rail.css(posCss);\n        bar.css(posCss);\n\n        // wrap it\n        me.wrap(wrapper);\n\n        // append to parent div\n        me.parent().append(bar);\n        me.parent().append(rail);\n\n        // make it draggable and no longer dependent on the jqueryUI\n        if (o.railDraggable) {\n          bar.bind(\"mousedown\", function (e) {\n            var $doc = $(document);\n            isDragg = true;\n            t = parseFloat(bar.css('top'));\n            pageY = e.pageY;\n\n            $doc.bind(\"mousemove.slimscroll\", function (e) {\n              currTop = t + e.pageY - pageY;\n              bar.css('top', currTop);\n              scrollContent(0, bar.position().top, false);// scroll content\n            });\n\n            $doc.bind(\"mouseup.slimscroll\", function (e) {\n              isDragg = false;\n              hideBar();\n              $doc.unbind('.slimscroll');\n            });\n            return false;\n          }).bind(\"selectstart.slimscroll\", function (e) {\n            e.stopPropagation();\n            e.preventDefault();\n            return false;\n          });\n        }\n\n        // on rail over\n        rail.hover(function () {\n          showBar();\n        }, function () {\n          hideBar();\n        });\n\n        // on bar over\n        bar.hover(function () {\n          isOverBar = true;\n        }, function () {\n          isOverBar = false;\n        });\n\n        // show on parent mouseover\n        me.hover(function () {\n          isOverPanel = true;\n          showBar();\n          hideBar();\n        }, function () {\n          isOverPanel = false;\n          hideBar();\n        });\n\n        if (window.navigator.msPointerEnabled) {          \n          // support for mobile\n          me.bind('MSPointerDown', function (e, b) {\n            if (e.originalEvent.targetTouches.length)\n            {\n              // record where touch started\n              touchDif = e.originalEvent.targetTouches[0].pageY;\n            }\n          });\n\n          me.bind('MSPointerMove', function (e) {\n            // prevent scrolling the page if necessary\n            e.originalEvent.preventDefault();\n            if (e.originalEvent.targetTouches.length)\n            {\n              // see how far user swiped\n              var diff = (touchDif - e.originalEvent.targetTouches[0].pageY) / o.touchScrollStep;\n              // scroll content\n              scrollContent(diff, true);\n              touchDif = e.originalEvent.targetTouches[0].pageY;\n              \n            }\n          });\n        } else {\n          // support for mobile\n          me.bind('touchstart', function (e, b) {\n            if (e.originalEvent.touches.length)\n            {\n              // record where touch started\n              touchDif = e.originalEvent.touches[0].pageY;\n            }\n          });\n\n          me.bind('touchmove', function (e) {\n            // prevent scrolling the page if necessary\n            if (!releaseScroll)\n            {\n              e.originalEvent.preventDefault();\n            }\n            if (e.originalEvent.touches.length)\n            {\n              // see how far user swiped\n              var diff = (touchDif - e.originalEvent.touches[0].pageY) / o.touchScrollStep;\n              // scroll content\n              scrollContent(diff, true);\n              touchDif = e.originalEvent.touches[0].pageY;\n            }\n          });\n        }\n\n        // set up initial height\n        getBarHeight();\n\n        // check start position\n        if (o.start === 'bottom')\n        {\n          // scroll content to bottom\n          bar.css({top: me.outerHeight() - bar.outerHeight()});\n          scrollContent(0, true);\n        }\n        else if (o.start !== 'top')\n        {\n          // assume jQuery selector\n          scrollContent($(o.start).position().top, null, true);\n\n          // make sure bar stays hidden\n          if (!o.alwaysVisible) {\n            bar.hide();\n          }\n        }\n\n        // attach scroll events\n        attachWheel();\n\n        function _onWheel(e)\n        {\n          // use mouse wheel only when mouse is over\n          if (!isOverPanel) {\n            return;\n          }\n\n          var e = e || window.event;\n\n          var delta = 0;\n          if (e.wheelDelta) {\n            delta = -e.wheelDelta / 120;\n          }\n          if (e.detail) {\n            delta = e.detail / 3;\n          }\n\n          var target = e.target || e.srcTarget || e.srcElement;\n          if ($(target).closest('.' + o.wrapperClass).is(me.parent())) {\n            // scroll content\n            scrollContent(delta, true);\n          }\n\n          // stop window scroll\n          if (e.preventDefault && !releaseScroll) {\n            e.preventDefault();\n          }\n          if (!releaseScroll) {\n            e.returnValue = false;\n          }\n        }\n\n        function scrollContent(y, isWheel, isJump)\n        {\n          releaseScroll = false;\n          var delta = y;\n          var maxTop = me.outerHeight() - bar.outerHeight();\n\n          if (isWheel)\n          {\n            // move bar with mouse wheel\n            delta = parseInt(bar.css('top')) + y * parseInt(o.wheelStep) / 100 * bar.outerHeight();\n\n            // move bar, make sure it doesn't go out\n            delta = Math.min(Math.max(delta, 0), maxTop);\n\n            // if scrolling down, make sure a fractional change to the\n            // scroll position isn't rounded away when the scrollbar's CSS is set\n            // this flooring of delta would happened automatically when\n            // bar.css is set below, but we floor here for clarity\n            delta = (y > 0) ? Math.ceil(delta) : Math.floor(delta);\n\n            // scroll the scrollbar\n            bar.css({top: delta + 'px'});\n          }\n\n          // calculate actual scroll amount\n          percentScroll = parseInt(bar.css('top')) / (me.outerHeight() - bar.outerHeight());\n          delta = percentScroll * (me[0].scrollHeight - me.outerHeight());\n\n          if (isJump)\n          {\n            delta = y;\n            var offsetTop = delta / me[0].scrollHeight * me.outerHeight();\n            offsetTop = Math.min(Math.max(offsetTop, 0), maxTop);\n            bar.css({top: offsetTop + 'px'});\n          }\n\n          // scroll content\n          me.scrollTop(delta);\n\n          // fire scrolling event\n          me.trigger('slimscrolling', ~~delta);\n\n          // ensure bar is visible\n          showBar();\n\n          // trigger hide when scroll is stopped\n          hideBar();\n        }\n\n        function attachWheel()\n        {\n          if (window.addEventListener)\n          {\n            this.addEventListener('DOMMouseScroll', _onWheel, false);\n            this.addEventListener('mousewheel', _onWheel, false);\n          }\n          else\n          {\n            document.attachEvent(\"onmousewheel\", _onWheel)\n          }\n        }\n\n        function getBarHeight()\n        {\n          // calculate scrollbar height and make sure it is not too small\n          barHeight = Math.max((me.outerHeight() / me[0].scrollHeight) * me.outerHeight(), minBarHeight);\n          bar.css({height: barHeight + 'px'});\n\n          // hide scrollbar if content is not long enough\n          var display = barHeight == me.outerHeight() ? 'none' : 'block';\n          bar.css({display: display});\n        }\n\n        function showBar()\n        {\n          // recalculate bar height\n          getBarHeight();\n          clearTimeout(queueHide);\n\n          // when bar reached top or bottom\n          if (percentScroll == ~~percentScroll)\n          {\n            //release wheel\n            releaseScroll = o.allowPageScroll;\n\n            // publish approporiate event\n            if (lastScroll != percentScroll)\n            {\n              var msg = (~~percentScroll == 0) ? 'top' : 'bottom';\n              me.trigger('slimscroll', msg);\n            }\n          }\n          else\n          {\n            releaseScroll = false;\n          }\n          lastScroll = percentScroll;\n\n          // show only when required\n          if (barHeight >= me.outerHeight()) {\n            //allow window scroll\n            releaseScroll = true;\n            return;\n          }\n          bar.stop(true, true).fadeIn('fast');\n          if (o.railVisible) {\n            rail.stop(true, true).fadeIn('fast');\n          }\n        }\n\n        function hideBar()\n        {\n          // only hide when options allow it\n          if (!o.alwaysVisible)\n          {\n            queueHide = setTimeout(function () {\n              if (!(o.disableFadeOut && isOverPanel) && !isOverBar && !isDragg)\n              {\n                bar.fadeOut('slow');\n                rail.fadeOut('slow');\n              }\n            }, 1000);\n          }\n        }\n\n      });\n\n      // maintain chainability\n      return this;\n    }\n  });\n\n  $.fn.extend({\n    slimscroll: $.fn.slimScroll\n  });\n\n})(jQuery);\n"
  },
  {
    "path": "public/static/plugins/sparkline/jquery.sparkline.js",
    "content": "/**\n*\n* jquery.sparkline.js\n*\n* v2.1.2\n* (c) Splunk, Inc\n* Contact: Gareth Watts (gareth@splunk.com)\n* http://omnipotent.net/jquery.sparkline/\n*\n* Generates inline sparkline charts from data supplied either to the method\n* or inline in HTML\n*\n* Compatible with Internet Explorer 6.0+ and modern browsers equipped with the canvas tag\n* (Firefox 2.0+, Safari, Opera, etc)\n*\n* License: New BSD License\n*\n* Copyright (c) 2012, Splunk Inc.\n* All rights reserved.\n*\n* Redistribution and use in source and binary forms, with or without modification,\n* are permitted provided that the following conditions are met:\n*\n*     * Redistributions of source code must retain the above copyright notice,\n*       this list of conditions and the following disclaimer.\n*     * Redistributions in binary form must reproduce the above copyright notice,\n*       this list of conditions and the following disclaimer in the documentation\n*       and/or other materials provided with the distribution.\n*     * Neither the name of Splunk Inc nor the names of its contributors may\n*       be used to endorse or promote products derived from this software without\n*       specific prior written permission.\n*\n* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n* SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,\n* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT\n* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,\n* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n*\n*\n* Usage:\n*  $(selector).sparkline(values, options)\n*\n* If values is undefined or set to 'html' then the data values are read from the specified tag:\n*   <p>Sparkline: <span class=\"sparkline\">1,4,6,6,8,5,3,5</span></p>\n*   $('.sparkline').sparkline();\n* There must be no spaces in the enclosed data set\n*\n* Otherwise values must be an array of numbers or null values\n*    <p>Sparkline: <span id=\"sparkline1\">This text replaced if the browser is compatible</span></p>\n*    $('#sparkline1').sparkline([1,4,6,6,8,5,3,5])\n*    $('#sparkline2').sparkline([1,4,6,null,null,5,3,5])\n*\n* Values can also be specified in an HTML comment, or as a values attribute:\n*    <p>Sparkline: <span class=\"sparkline\"><!--1,4,6,6,8,5,3,5 --></span></p>\n*    <p>Sparkline: <span class=\"sparkline\" values=\"1,4,6,6,8,5,3,5\"></span></p>\n*    $('.sparkline').sparkline();\n*\n* For line charts, x values can also be specified:\n*   <p>Sparkline: <span class=\"sparkline\">1:1,2.7:4,3.4:6,5:6,6:8,8.7:5,9:3,10:5</span></p>\n*    $('#sparkline1').sparkline([ [1,1], [2.7,4], [3.4,6], [5,6], [6,8], [8.7,5], [9,3], [10,5] ])\n*\n* By default, options should be passed in as teh second argument to the sparkline function:\n*   $('.sparkline').sparkline([1,2,3,4], {type: 'bar'})\n*\n* Options can also be set by passing them on the tag itself.  This feature is disabled by default though\n* as there's a slight performance overhead:\n*   $('.sparkline').sparkline([1,2,3,4], {enableTagOptions: true})\n*   <p>Sparkline: <span class=\"sparkline\" sparkType=\"bar\" sparkBarColor=\"red\">loading</span></p>\n* Prefix all options supplied as tag attribute with \"spark\" (configurable by setting tagOptionPrefix)\n*\n* Supported options:\n*   lineColor - Color of the line used for the chart\n*   fillColor - Color used to fill in the chart - Set to '' or false for a transparent chart\n*   width - Width of the chart - Defaults to 3 times the number of values in pixels\n*   height - Height of the chart - Defaults to the height of the containing element\n*   chartRangeMin - Specify the minimum value to use for the Y range of the chart - Defaults to the minimum value supplied\n*   chartRangeMax - Specify the maximum value to use for the Y range of the chart - Defaults to the maximum value supplied\n*   chartRangeClip - Clip out of range values to the max/min specified by chartRangeMin and chartRangeMax\n*   chartRangeMinX - Specify the minimum value to use for the X range of the chart - Defaults to the minimum value supplied\n*   chartRangeMaxX - Specify the maximum value to use for the X range of the chart - Defaults to the maximum value supplied\n*   composite - If true then don't erase any existing chart attached to the tag, but draw\n*           another chart over the top - Note that width and height are ignored if an\n*           existing chart is detected.\n*   tagValuesAttribute - Name of tag attribute to check for data values - Defaults to 'values'\n*   enableTagOptions - Whether to check tags for sparkline options\n*   tagOptionPrefix - Prefix used for options supplied as tag attributes - Defaults to 'spark'\n*   disableHiddenCheck - If set to true, then the plugin will assume that charts will never be drawn into a\n*           hidden dom element, avoding a browser reflow\n*   disableInteraction - If set to true then all mouseover/click interaction behaviour will be disabled,\n*       making the plugin perform much like it did in 1.x\n*   disableTooltips - If set to true then tooltips will be disabled - Defaults to false (tooltips enabled)\n*   disableHighlight - If set to true then highlighting of selected chart elements on mouseover will be disabled\n*       defaults to false (highlights enabled)\n*   highlightLighten - Factor to lighten/darken highlighted chart values by - Defaults to 1.4 for a 40% increase\n*   tooltipContainer - Specify which DOM element the tooltip should be rendered into - defaults to document.body\n*   tooltipClassname - Optional CSS classname to apply to tooltips - If not specified then a default style will be applied\n*   tooltipOffsetX - How many pixels away from the mouse pointer to render the tooltip on the X axis\n*   tooltipOffsetY - How many pixels away from the mouse pointer to render the tooltip on the r axis\n*   tooltipFormatter  - Optional callback that allows you to override the HTML displayed in the tooltip\n*       callback is given arguments of (sparkline, options, fields)\n*   tooltipChartTitle - If specified then the tooltip uses the string specified by this setting as a title\n*   tooltipFormat - A format string or SPFormat object  (or an array thereof for multiple entries)\n*       to control the format of the tooltip\n*   tooltipPrefix - A string to prepend to each field displayed in a tooltip\n*   tooltipSuffix - A string to append to each field displayed in a tooltip\n*   tooltipSkipNull - If true then null values will not have a tooltip displayed (defaults to true)\n*   tooltipValueLookups - An object or range map to map field values to tooltip strings\n*       (eg. to map -1 to \"Lost\", 0 to \"Draw\", and 1 to \"Win\")\n*   numberFormatter - Optional callback for formatting numbers in tooltips\n*   numberDigitGroupSep - Character to use for group separator in numbers \"1,234\" - Defaults to \",\"\n*   numberDecimalMark - Character to use for the decimal point when formatting numbers - Defaults to \".\"\n*   numberDigitGroupCount - Number of digits between group separator - Defaults to 3\n*\n* There are 7 types of sparkline, selected by supplying a \"type\" option of 'line' (default),\n* 'bar', 'tristate', 'bullet', 'discrete', 'pie' or 'box'\n*    line - Line chart.  Options:\n*       spotColor - Set to '' to not end each line in a circular spot\n*       minSpotColor - If set, color of spot at minimum value\n*       maxSpotColor - If set, color of spot at maximum value\n*       spotRadius - Radius in pixels\n*       lineWidth - Width of line in pixels\n*       normalRangeMin\n*       normalRangeMax - If set draws a filled horizontal bar between these two values marking the \"normal\"\n*                      or expected range of values\n*       normalRangeColor - Color to use for the above bar\n*       drawNormalOnTop - Draw the normal range above the chart fill color if true\n*       defaultPixelsPerValue - Defaults to 3 pixels of width for each value in the chart\n*       highlightSpotColor - The color to use for drawing a highlight spot on mouseover - Set to null to disable\n*       highlightLineColor - The color to use for drawing a highlight line on mouseover - Set to null to disable\n*       valueSpots - Specify which points to draw spots on, and in which color.  Accepts a range map\n*\n*   bar - Bar chart.  Options:\n*       barColor - Color of bars for postive values\n*       negBarColor - Color of bars for negative values\n*       zeroColor - Color of bars with zero values\n*       nullColor - Color of bars with null values - Defaults to omitting the bar entirely\n*       barWidth - Width of bars in pixels\n*       colorMap - Optional mappnig of values to colors to override the *BarColor values above\n*                  can be an Array of values to control the color of individual bars or a range map\n*                  to specify colors for individual ranges of values\n*       barSpacing - Gap between bars in pixels\n*       zeroAxis - Centers the y-axis around zero if true\n*\n*   tristate - Charts values of win (>0), lose (<0) or draw (=0)\n*       posBarColor - Color of win values\n*       negBarColor - Color of lose values\n*       zeroBarColor - Color of draw values\n*       barWidth - Width of bars in pixels\n*       barSpacing - Gap between bars in pixels\n*       colorMap - Optional mappnig of values to colors to override the *BarColor values above\n*                  can be an Array of values to control the color of individual bars or a range map\n*                  to specify colors for individual ranges of values\n*\n*   discrete - Options:\n*       lineHeight - Height of each line in pixels - Defaults to 30% of the graph height\n*       thesholdValue - Values less than this value will be drawn using thresholdColor instead of lineColor\n*       thresholdColor\n*\n*   bullet - Values for bullet graphs msut be in the order: target, performance, range1, range2, range3, ...\n*       options:\n*       targetColor - The color of the vertical target marker\n*       targetWidth - The width of the target marker in pixels\n*       performanceColor - The color of the performance measure horizontal bar\n*       rangeColors - Colors to use for each qualitative range background color\n*\n*   pie - Pie chart. Options:\n*       sliceColors - An array of colors to use for pie slices\n*       offset - Angle in degrees to offset the first slice - Try -90 or +90\n*       borderWidth - Width of border to draw around the pie chart, in pixels - Defaults to 0 (no border)\n*       borderColor - Color to use for the pie chart border - Defaults to #000\n*\n*   box - Box plot. Options:\n*       raw - Set to true to supply pre-computed plot points as values\n*             values should be: low_outlier, low_whisker, q1, median, q3, high_whisker, high_outlier\n*             When set to false you can supply any number of values and the box plot will\n*             be computed for you.  Default is false.\n*       showOutliers - Set to true (default) to display outliers as circles\n*       outlierIQR - Interquartile range used to determine outliers.  Default 1.5\n*       boxLineColor - Outline color of the box\n*       boxFillColor - Fill color for the box\n*       whiskerColor - Line color used for whiskers\n*       outlierLineColor - Outline color of outlier circles\n*       outlierFillColor - Fill color of the outlier circles\n*       spotRadius - Radius of outlier circles\n*       medianColor - Line color of the median line\n*       target - Draw a target cross hair at the supplied value (default undefined)\n*\n*\n*\n*   Examples:\n*   $('#sparkline1').sparkline(myvalues, { lineColor: '#f00', fillColor: false });\n*   $('.barsparks').sparkline('html', { type:'bar', height:'40px', barWidth:5 });\n*   $('#tristate').sparkline([1,1,-1,1,0,0,-1], { type:'tristate' }):\n*   $('#discrete').sparkline([1,3,4,5,5,3,4,5], { type:'discrete' });\n*   $('#bullet').sparkline([10,12,12,9,7], { type:'bullet' });\n*   $('#pie').sparkline([1,1,2], { type:'pie' });\n*/\n\n/*jslint regexp: true, browser: true, jquery: true, white: true, nomen: false, plusplus: false, maxerr: 500, indent: 4 */\n\n(function(document, Math, undefined) { // performance/minified-size optimization\n(function(factory) {\n    if(typeof define === 'function' && define.amd) {\n        define(['jquery'], factory);\n    } else if (jQuery && !jQuery.fn.sparkline) {\n        factory(jQuery);\n    }\n}\n(function($) {\n    'use strict';\n\n    var UNSET_OPTION = {},\n        getDefaults, createClass, SPFormat, clipval, quartile, normalizeValue, normalizeValues,\n        remove, isNumber, all, sum, addCSS, ensureArray, formatNumber, RangeMap,\n        MouseHandler, Tooltip, barHighlightMixin,\n        line, bar, tristate, discrete, bullet, pie, box, defaultStyles, initStyles,\n        VShape, VCanvas_base, VCanvas_canvas, VCanvas_vml, pending, shapeCount = 0;\n\n    /**\n     * Default configuration settings\n     */\n    getDefaults = function () {\n        return {\n            // Settings common to most/all chart types\n            common: {\n                type: 'line',\n                lineColor: '#00f',\n                fillColor: '#cdf',\n                defaultPixelsPerValue: 3,\n                width: 'auto',\n                height: 'auto',\n                composite: false,\n                tagValuesAttribute: 'values',\n                tagOptionsPrefix: 'spark',\n                enableTagOptions: false,\n                enableHighlight: true,\n                highlightLighten: 1.4,\n                tooltipSkipNull: true,\n                tooltipPrefix: '',\n                tooltipSuffix: '',\n                disableHiddenCheck: false,\n                numberFormatter: false,\n                numberDigitGroupCount: 3,\n                numberDigitGroupSep: ',',\n                numberDecimalMark: '.',\n                disableTooltips: false,\n                disableInteraction: false\n            },\n            // Defaults for line charts\n            line: {\n                spotColor: '#f80',\n                highlightSpotColor: '#5f5',\n                highlightLineColor: '#f22',\n                spotRadius: 1.5,\n                minSpotColor: '#f80',\n                maxSpotColor: '#f80',\n                lineWidth: 1,\n                normalRangeMin: undefined,\n                normalRangeMax: undefined,\n                normalRangeColor: '#ccc',\n                drawNormalOnTop: false,\n                chartRangeMin: undefined,\n                chartRangeMax: undefined,\n                chartRangeMinX: undefined,\n                chartRangeMaxX: undefined,\n                tooltipFormat: new SPFormat('<span style=\"color: {{color}}\">&#9679;</span> {{prefix}}{{y}}{{suffix}}')\n            },\n            // Defaults for bar charts\n            bar: {\n                barColor: '#3366cc',\n                negBarColor: '#f44',\n                stackedBarColor: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00',\n                    '#dd4477', '#0099c6', '#990099'],\n                zeroColor: undefined,\n                nullColor: undefined,\n                zeroAxis: true,\n                barWidth: 4,\n                barSpacing: 1,\n                chartRangeMax: undefined,\n                chartRangeMin: undefined,\n                chartRangeClip: false,\n                colorMap: undefined,\n                tooltipFormat: new SPFormat('<span style=\"color: {{color}}\">&#9679;</span> {{prefix}}{{value}}{{suffix}}')\n            },\n            // Defaults for tristate charts\n            tristate: {\n                barWidth: 4,\n                barSpacing: 1,\n                posBarColor: '#6f6',\n                negBarColor: '#f44',\n                zeroBarColor: '#999',\n                colorMap: {},\n                tooltipFormat: new SPFormat('<span style=\"color: {{color}}\">&#9679;</span> {{value:map}}'),\n                tooltipValueLookups: { map: { '-1': 'Loss', '0': 'Draw', '1': 'Win' } }\n            },\n            // Defaults for discrete charts\n            discrete: {\n                lineHeight: 'auto',\n                thresholdColor: undefined,\n                thresholdValue: 0,\n                chartRangeMax: undefined,\n                chartRangeMin: undefined,\n                chartRangeClip: false,\n                tooltipFormat: new SPFormat('{{prefix}}{{value}}{{suffix}}')\n            },\n            // Defaults for bullet charts\n            bullet: {\n                targetColor: '#f33',\n                targetWidth: 3, // width of the target bar in pixels\n                performanceColor: '#33f',\n                rangeColors: ['#d3dafe', '#a8b6ff', '#7f94ff'],\n                base: undefined, // set this to a number to change the base start number\n                tooltipFormat: new SPFormat('{{fieldkey:fields}} - {{value}}'),\n                tooltipValueLookups: { fields: {r: 'Range', p: 'Performance', t: 'Target'} }\n            },\n            // Defaults for pie charts\n            pie: {\n                offset: 0,\n                sliceColors: ['#3366cc', '#dc3912', '#ff9900', '#109618', '#66aa00',\n                    '#dd4477', '#0099c6', '#990099'],\n                borderWidth: 0,\n                borderColor: '#000',\n                tooltipFormat: new SPFormat('<span style=\"color: {{color}}\">&#9679;</span> {{value}} ({{percent.1}}%)')\n            },\n            // Defaults for box plots\n            box: {\n                raw: false,\n                boxLineColor: '#000',\n                boxFillColor: '#cdf',\n                whiskerColor: '#000',\n                outlierLineColor: '#333',\n                outlierFillColor: '#fff',\n                medianColor: '#f00',\n                showOutliers: true,\n                outlierIQR: 1.5,\n                spotRadius: 1.5,\n                target: undefined,\n                targetColor: '#4a2',\n                chartRangeMax: undefined,\n                chartRangeMin: undefined,\n                tooltipFormat: new SPFormat('{{field:fields}}: {{value}}'),\n                tooltipFormatFieldlistKey: 'field',\n                tooltipValueLookups: { fields: { lq: 'Lower Quartile', med: 'Median',\n                    uq: 'Upper Quartile', lo: 'Left Outlier', ro: 'Right Outlier',\n                    lw: 'Left Whisker', rw: 'Right Whisker'} }\n            }\n        };\n    };\n\n    // You can have tooltips use a css class other than jqstooltip by specifying tooltipClassname\n    defaultStyles = '.jqstooltip { ' +\n            'position: absolute;' +\n            'left: 0px;' +\n            'top: 0px;' +\n            'visibility: hidden;' +\n            'background: rgb(0, 0, 0) transparent;' +\n            'background-color: rgba(0,0,0,0.6);' +\n            'filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000);' +\n            '-ms-filter: \"progid:DXImageTransform.Microsoft.gradient(startColorstr=#99000000, endColorstr=#99000000)\";' +\n            'color: white;' +\n            'font: 10px arial, san serif;' +\n            'text-align: left;' +\n            'white-space: nowrap;' +\n            'padding: 5px;' +\n            'border: 1px solid white;' +\n            'z-index: 10000;' +\n            '}' +\n            '.jqsfield { ' +\n            'color: white;' +\n            'font: 10px arial, san serif;' +\n            'text-align: left;' +\n            '}';\n\n    /**\n     * Utilities\n     */\n\n    createClass = function (/* [baseclass, [mixin, ...]], definition */) {\n        var Class, args;\n        Class = function () {\n            this.init.apply(this, arguments);\n        };\n        if (arguments.length > 1) {\n            if (arguments[0]) {\n                Class.prototype = $.extend(new arguments[0](), arguments[arguments.length - 1]);\n                Class._super = arguments[0].prototype;\n            } else {\n                Class.prototype = arguments[arguments.length - 1];\n            }\n            if (arguments.length > 2) {\n                args = Array.prototype.slice.call(arguments, 1, -1);\n                args.unshift(Class.prototype);\n                $.extend.apply($, args);\n            }\n        } else {\n            Class.prototype = arguments[0];\n        }\n        Class.prototype.cls = Class;\n        return Class;\n    };\n\n    /**\n     * Wraps a format string for tooltips\n     * {{x}}\n     * {{x.2}\n     * {{x:months}}\n     */\n    $.SPFormatClass = SPFormat = createClass({\n        fre: /\\{\\{([\\w.]+?)(:(.+?))?\\}\\}/g,\n        precre: /(\\w+)\\.(\\d+)/,\n\n        init: function (format, fclass) {\n            this.format = format;\n            this.fclass = fclass;\n        },\n\n        render: function (fieldset, lookups, options) {\n            var self = this,\n                fields = fieldset,\n                match, token, lookupkey, fieldvalue, prec;\n            return this.format.replace(this.fre, function () {\n                var lookup;\n                token = arguments[1];\n                lookupkey = arguments[3];\n                match = self.precre.exec(token);\n                if (match) {\n                    prec = match[2];\n                    token = match[1];\n                } else {\n                    prec = false;\n                }\n                fieldvalue = fields[token];\n                if (fieldvalue === undefined) {\n                    return '';\n                }\n                if (lookupkey && lookups && lookups[lookupkey]) {\n                    lookup = lookups[lookupkey];\n                    if (lookup.get) { // RangeMap\n                        return lookups[lookupkey].get(fieldvalue) || fieldvalue;\n                    } else {\n                        return lookups[lookupkey][fieldvalue] || fieldvalue;\n                    }\n                }\n                if (isNumber(fieldvalue)) {\n                    if (options.get('numberFormatter')) {\n                        fieldvalue = options.get('numberFormatter')(fieldvalue);\n                    } else {\n                        fieldvalue = formatNumber(fieldvalue, prec,\n                            options.get('numberDigitGroupCount'),\n                            options.get('numberDigitGroupSep'),\n                            options.get('numberDecimalMark'));\n                    }\n                }\n                return fieldvalue;\n            });\n        }\n    });\n\n    // convience method to avoid needing the new operator\n    $.spformat = function(format, fclass) {\n        return new SPFormat(format, fclass);\n    };\n\n    clipval = function (val, min, max) {\n        if (val < min) {\n            return min;\n        }\n        if (val > max) {\n            return max;\n        }\n        return val;\n    };\n\n    quartile = function (values, q) {\n        var vl;\n        if (q === 2) {\n            vl = Math.floor(values.length / 2);\n            return values.length % 2 ? values[vl] : (values[vl-1] + values[vl]) / 2;\n        } else {\n            if (values.length % 2 ) { // odd\n                vl = (values.length * q + q) / 4;\n                return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 : values[vl-1];\n            } else { //even\n                vl = (values.length * q + 2) / 4;\n                return vl % 1 ? (values[Math.floor(vl)] + values[Math.floor(vl) - 1]) / 2 :  values[vl-1];\n\n            }\n        }\n    };\n\n    normalizeValue = function (val) {\n        var nf;\n        switch (val) {\n            case 'undefined':\n                val = undefined;\n                break;\n            case 'null':\n                val = null;\n                break;\n            case 'true':\n                val = true;\n                break;\n            case 'false':\n                val = false;\n                break;\n            default:\n                nf = parseFloat(val);\n                if (val == nf) {\n                    val = nf;\n                }\n        }\n        return val;\n    };\n\n    normalizeValues = function (vals) {\n        var i, result = [];\n        for (i = vals.length; i--;) {\n            result[i] = normalizeValue(vals[i]);\n        }\n        return result;\n    };\n\n    remove = function (vals, filter) {\n        var i, vl, result = [];\n        for (i = 0, vl = vals.length; i < vl; i++) {\n            if (vals[i] !== filter) {\n                result.push(vals[i]);\n            }\n        }\n        return result;\n    };\n\n    isNumber = function (num) {\n        return !isNaN(parseFloat(num)) && isFinite(num);\n    };\n\n    formatNumber = function (num, prec, groupsize, groupsep, decsep) {\n        var p, i;\n        num = (prec === false ? parseFloat(num).toString() : num.toFixed(prec)).split('');\n        p = (p = $.inArray('.', num)) < 0 ? num.length : p;\n        if (p < num.length) {\n            num[p] = decsep;\n        }\n        for (i = p - groupsize; i > 0; i -= groupsize) {\n            num.splice(i, 0, groupsep);\n        }\n        return num.join('');\n    };\n\n    // determine if all values of an array match a value\n    // returns true if the array is empty\n    all = function (val, arr, ignoreNull) {\n        var i;\n        for (i = arr.length; i--; ) {\n            if (ignoreNull && arr[i] === null) continue;\n            if (arr[i] !== val) {\n                return false;\n            }\n        }\n        return true;\n    };\n\n    // sums the numeric values in an array, ignoring other values\n    sum = function (vals) {\n        var total = 0, i;\n        for (i = vals.length; i--;) {\n            total += typeof vals[i] === 'number' ? vals[i] : 0;\n        }\n        return total;\n    };\n\n    ensureArray = function (val) {\n        return $.isArray(val) ? val : [val];\n    };\n\n    // http://paulirish.com/2008/bookmarklet-inject-new-css-rules/\n    addCSS = function(css) {\n        var tag;\n        //if ('\\v' == 'v') /* ie only */ {\n        if (document.createStyleSheet) {\n            document.createStyleSheet().cssText = css;\n        } else {\n            tag = document.createElement('style');\n            tag.type = 'text/css';\n            document.getElementsByTagName('head')[0].appendChild(tag);\n            tag[(typeof document.body.style.WebkitAppearance == 'string') /* webkit only */ ? 'innerText' : 'innerHTML'] = css;\n        }\n    };\n\n    // Provide a cross-browser interface to a few simple drawing primitives\n    $.fn.simpledraw = function (width, height, useExisting, interact) {\n        var target, mhandler;\n        if (useExisting && (target = this.data('_jqs_vcanvas'))) {\n            return target;\n        }\n\n        if ($.fn.sparkline.canvas === false) {\n            // We've already determined that neither Canvas nor VML are available\n            return false;\n\n        } else if ($.fn.sparkline.canvas === undefined) {\n            // No function defined yet -- need to see if we support Canvas or VML\n            var el = document.createElement('canvas');\n            if (!!(el.getContext && el.getContext('2d'))) {\n                // Canvas is available\n                $.fn.sparkline.canvas = function(width, height, target, interact) {\n                    return new VCanvas_canvas(width, height, target, interact);\n                };\n            } else if (document.namespaces && !document.namespaces.v) {\n                // VML is available\n                document.namespaces.add('v', 'urn:schemas-microsoft-com:vml', '#default#VML');\n                $.fn.sparkline.canvas = function(width, height, target, interact) {\n                    return new VCanvas_vml(width, height, target);\n                };\n            } else {\n                // Neither Canvas nor VML are available\n                $.fn.sparkline.canvas = false;\n                return false;\n            }\n        }\n\n        if (width === undefined) {\n            width = $(this).innerWidth();\n        }\n        if (height === undefined) {\n            height = $(this).innerHeight();\n        }\n\n        target = $.fn.sparkline.canvas(width, height, this, interact);\n\n        mhandler = $(this).data('_jqs_mhandler');\n        if (mhandler) {\n            mhandler.registerCanvas(target);\n        }\n        return target;\n    };\n\n    $.fn.cleardraw = function () {\n        var target = this.data('_jqs_vcanvas');\n        if (target) {\n            target.reset();\n        }\n    };\n\n    $.RangeMapClass = RangeMap = createClass({\n        init: function (map) {\n            var key, range, rangelist = [];\n            for (key in map) {\n                if (map.hasOwnProperty(key) && typeof key === 'string' && key.indexOf(':') > -1) {\n                    range = key.split(':');\n                    range[0] = range[0].length === 0 ? -Infinity : parseFloat(range[0]);\n                    range[1] = range[1].length === 0 ? Infinity : parseFloat(range[1]);\n                    range[2] = map[key];\n                    rangelist.push(range);\n                }\n            }\n            this.map = map;\n            this.rangelist = rangelist || false;\n        },\n\n        get: function (value) {\n            var rangelist = this.rangelist,\n                i, range, result;\n            if ((result = this.map[value]) !== undefined) {\n                return result;\n            }\n            if (rangelist) {\n                for (i = rangelist.length; i--;) {\n                    range = rangelist[i];\n                    if (range[0] <= value && range[1] >= value) {\n                        return range[2];\n                    }\n                }\n            }\n            return undefined;\n        }\n    });\n\n    // Convenience function\n    $.range_map = function(map) {\n        return new RangeMap(map);\n    };\n\n    MouseHandler = createClass({\n        init: function (el, options) {\n            var $el = $(el);\n            this.$el = $el;\n            this.options = options;\n            this.currentPageX = 0;\n            this.currentPageY = 0;\n            this.el = el;\n            this.splist = [];\n            this.tooltip = null;\n            this.over = false;\n            this.displayTooltips = !options.get('disableTooltips');\n            this.highlightEnabled = !options.get('disableHighlight');\n        },\n\n        registerSparkline: function (sp) {\n            this.splist.push(sp);\n            if (this.over) {\n                this.updateDisplay();\n            }\n        },\n\n        registerCanvas: function (canvas) {\n            var $canvas = $(canvas.canvas);\n            this.canvas = canvas;\n            this.$canvas = $canvas;\n            $canvas.mouseenter($.proxy(this.mouseenter, this));\n            $canvas.mouseleave($.proxy(this.mouseleave, this));\n            $canvas.click($.proxy(this.mouseclick, this));\n        },\n\n        reset: function (removeTooltip) {\n            this.splist = [];\n            if (this.tooltip && removeTooltip) {\n                this.tooltip.remove();\n                this.tooltip = undefined;\n            }\n        },\n\n        mouseclick: function (e) {\n            var clickEvent = $.Event('sparklineClick');\n            clickEvent.originalEvent = e;\n            clickEvent.sparklines = this.splist;\n            this.$el.trigger(clickEvent);\n        },\n\n        mouseenter: function (e) {\n            $(document.body).unbind('mousemove.jqs');\n            $(document.body).bind('mousemove.jqs', $.proxy(this.mousemove, this));\n            this.over = true;\n            this.currentPageX = e.pageX;\n            this.currentPageY = e.pageY;\n            this.currentEl = e.target;\n            if (!this.tooltip && this.displayTooltips) {\n                this.tooltip = new Tooltip(this.options);\n                this.tooltip.updatePosition(e.pageX, e.pageY);\n            }\n            this.updateDisplay();\n        },\n\n        mouseleave: function () {\n            $(document.body).unbind('mousemove.jqs');\n            var splist = this.splist,\n                 spcount = splist.length,\n                 needsRefresh = false,\n                 sp, i;\n            this.over = false;\n            this.currentEl = null;\n\n            if (this.tooltip) {\n                this.tooltip.remove();\n                this.tooltip = null;\n            }\n\n            for (i = 0; i < spcount; i++) {\n                sp = splist[i];\n                if (sp.clearRegionHighlight()) {\n                    needsRefresh = true;\n                }\n            }\n\n            if (needsRefresh) {\n                this.canvas.render();\n            }\n        },\n\n        mousemove: function (e) {\n            this.currentPageX = e.pageX;\n            this.currentPageY = e.pageY;\n            this.currentEl = e.target;\n            if (this.tooltip) {\n                this.tooltip.updatePosition(e.pageX, e.pageY);\n            }\n            this.updateDisplay();\n        },\n\n        updateDisplay: function () {\n            var splist = this.splist,\n                 spcount = splist.length,\n                 needsRefresh = false,\n                 offset = this.$canvas.offset(),\n                 localX = this.currentPageX - offset.left,\n                 localY = this.currentPageY - offset.top,\n                 tooltiphtml, sp, i, result, changeEvent;\n            if (!this.over) {\n                return;\n            }\n            for (i = 0; i < spcount; i++) {\n                sp = splist[i];\n                result = sp.setRegionHighlight(this.currentEl, localX, localY);\n                if (result) {\n                    needsRefresh = true;\n                }\n            }\n            if (needsRefresh) {\n                changeEvent = $.Event('sparklineRegionChange');\n                changeEvent.sparklines = this.splist;\n                this.$el.trigger(changeEvent);\n                if (this.tooltip) {\n                    tooltiphtml = '';\n                    for (i = 0; i < spcount; i++) {\n                        sp = splist[i];\n                        tooltiphtml += sp.getCurrentRegionTooltip();\n                    }\n                    this.tooltip.setContent(tooltiphtml);\n                }\n                if (!this.disableHighlight) {\n                    this.canvas.render();\n                }\n            }\n            if (result === null) {\n                this.mouseleave();\n            }\n        }\n    });\n\n\n    Tooltip = createClass({\n        sizeStyle: 'position: static !important;' +\n            'display: block !important;' +\n            'visibility: hidden !important;' +\n            'float: left !important;',\n\n        init: function (options) {\n            var tooltipClassname = options.get('tooltipClassname', 'jqstooltip'),\n                sizetipStyle = this.sizeStyle,\n                offset;\n            this.container = options.get('tooltipContainer') || document.body;\n            this.tooltipOffsetX = options.get('tooltipOffsetX', 10);\n            this.tooltipOffsetY = options.get('tooltipOffsetY', 12);\n            // remove any previous lingering tooltip\n            $('#jqssizetip').remove();\n            $('#jqstooltip').remove();\n            this.sizetip = $('<div/>', {\n                id: 'jqssizetip',\n                style: sizetipStyle,\n                'class': tooltipClassname\n            });\n            this.tooltip = $('<div/>', {\n                id: 'jqstooltip',\n                'class': tooltipClassname\n            }).appendTo(this.container);\n            // account for the container's location\n            offset = this.tooltip.offset();\n            this.offsetLeft = offset.left;\n            this.offsetTop = offset.top;\n            this.hidden = true;\n            $(window).unbind('resize.jqs scroll.jqs');\n            $(window).bind('resize.jqs scroll.jqs', $.proxy(this.updateWindowDims, this));\n            this.updateWindowDims();\n        },\n\n        updateWindowDims: function () {\n            this.scrollTop = $(window).scrollTop();\n            this.scrollLeft = $(window).scrollLeft();\n            this.scrollRight = this.scrollLeft + $(window).width();\n            this.updatePosition();\n        },\n\n        getSize: function (content) {\n            this.sizetip.html(content).appendTo(this.container);\n            this.width = this.sizetip.width() + 1;\n            this.height = this.sizetip.height();\n            this.sizetip.remove();\n        },\n\n        setContent: function (content) {\n            if (!content) {\n                this.tooltip.css('visibility', 'hidden');\n                this.hidden = true;\n                return;\n            }\n            this.getSize(content);\n            this.tooltip.html(content)\n                .css({\n                    'width': this.width,\n                    'height': this.height,\n                    'visibility': 'visible'\n                });\n            if (this.hidden) {\n                this.hidden = false;\n                this.updatePosition();\n            }\n        },\n\n        updatePosition: function (x, y) {\n            if (x === undefined) {\n                if (this.mousex === undefined) {\n                    return;\n                }\n                x = this.mousex - this.offsetLeft;\n                y = this.mousey - this.offsetTop;\n\n            } else {\n                this.mousex = x = x - this.offsetLeft;\n                this.mousey = y = y - this.offsetTop;\n            }\n            if (!this.height || !this.width || this.hidden) {\n                return;\n            }\n\n            y -= this.height + this.tooltipOffsetY;\n            x += this.tooltipOffsetX;\n\n            if (y < this.scrollTop) {\n                y = this.scrollTop;\n            }\n            if (x < this.scrollLeft) {\n                x = this.scrollLeft;\n            } else if (x + this.width > this.scrollRight) {\n                x = this.scrollRight - this.width;\n            }\n\n            this.tooltip.css({\n                'left': x,\n                'top': y\n            });\n        },\n\n        remove: function () {\n            this.tooltip.remove();\n            this.sizetip.remove();\n            this.sizetip = this.tooltip = undefined;\n            $(window).unbind('resize.jqs scroll.jqs');\n        }\n    });\n\n    initStyles = function() {\n        addCSS(defaultStyles);\n    };\n\n    $(initStyles);\n\n    pending = [];\n    $.fn.sparkline = function (userValues, userOptions) {\n        return this.each(function () {\n            var options = new $.fn.sparkline.options(this, userOptions),\n                 $this = $(this),\n                 render, i;\n            render = function () {\n                var values, width, height, tmp, mhandler, sp, vals;\n                if (userValues === 'html' || userValues === undefined) {\n                    vals = this.getAttribute(options.get('tagValuesAttribute'));\n                    if (vals === undefined || vals === null) {\n                        vals = $this.html();\n                    }\n                    values = vals.replace(/(^\\s*<!--)|(-->\\s*$)|\\s+/g, '').split(',');\n                } else {\n                    values = userValues;\n                }\n\n                width = options.get('width') === 'auto' ? values.length * options.get('defaultPixelsPerValue') : options.get('width');\n                if (options.get('height') === 'auto') {\n                    if (!options.get('composite') || !$.data(this, '_jqs_vcanvas')) {\n                        // must be a better way to get the line height\n                        tmp = document.createElement('span');\n                        tmp.innerHTML = 'a';\n                        $this.html(tmp);\n                        height = $(tmp).innerHeight() || $(tmp).height();\n                        $(tmp).remove();\n                        tmp = null;\n                    }\n                } else {\n                    height = options.get('height');\n                }\n\n                if (!options.get('disableInteraction')) {\n                    mhandler = $.data(this, '_jqs_mhandler');\n                    if (!mhandler) {\n                        mhandler = new MouseHandler(this, options);\n                        $.data(this, '_jqs_mhandler', mhandler);\n                    } else if (!options.get('composite')) {\n                        mhandler.reset();\n                    }\n                } else {\n                    mhandler = false;\n                }\n\n                if (options.get('composite') && !$.data(this, '_jqs_vcanvas')) {\n                    if (!$.data(this, '_jqs_errnotify')) {\n                        alert('Attempted to attach a composite sparkline to an element with no existing sparkline');\n                        $.data(this, '_jqs_errnotify', true);\n                    }\n                    return;\n                }\n\n                sp = new $.fn.sparkline[options.get('type')](this, values, options, width, height);\n\n                sp.render();\n\n                if (mhandler) {\n                    mhandler.registerSparkline(sp);\n                }\n            };\n            if (($(this).html() && !options.get('disableHiddenCheck') && $(this).is(':hidden')) || !$(this).parents('body').length) {\n                if (!options.get('composite') && $.data(this, '_jqs_pending')) {\n                    // remove any existing references to the element\n                    for (i = pending.length; i; i--) {\n                        if (pending[i - 1][0] == this) {\n                            pending.splice(i - 1, 1);\n                        }\n                    }\n                }\n                pending.push([this, render]);\n                $.data(this, '_jqs_pending', true);\n            } else {\n                render.call(this);\n            }\n        });\n    };\n\n    $.fn.sparkline.defaults = getDefaults();\n\n\n    $.sparkline_display_visible = function () {\n        var el, i, pl;\n        var done = [];\n        for (i = 0, pl = pending.length; i < pl; i++) {\n            el = pending[i][0];\n            if ($(el).is(':visible') && !$(el).parents().is(':hidden')) {\n                pending[i][1].call(el);\n                $.data(pending[i][0], '_jqs_pending', false);\n                done.push(i);\n            } else if (!$(el).closest('html').length && !$.data(el, '_jqs_pending')) {\n                // element has been inserted and removed from the DOM\n                // If it was not yet inserted into the dom then the .data request\n                // will return true.\n                // removing from the dom causes the data to be removed.\n                $.data(pending[i][0], '_jqs_pending', false);\n                done.push(i);\n            }\n        }\n        for (i = done.length; i; i--) {\n            pending.splice(done[i - 1], 1);\n        }\n    };\n\n\n    /**\n     * User option handler\n     */\n    $.fn.sparkline.options = createClass({\n        init: function (tag, userOptions) {\n            var extendedOptions, defaults, base, tagOptionType;\n            this.userOptions = userOptions = userOptions || {};\n            this.tag = tag;\n            this.tagValCache = {};\n            defaults = $.fn.sparkline.defaults;\n            base = defaults.common;\n            this.tagOptionsPrefix = userOptions.enableTagOptions && (userOptions.tagOptionsPrefix || base.tagOptionsPrefix);\n\n            tagOptionType = this.getTagSetting('type');\n            if (tagOptionType === UNSET_OPTION) {\n                extendedOptions = defaults[userOptions.type || base.type];\n            } else {\n                extendedOptions = defaults[tagOptionType];\n            }\n            this.mergedOptions = $.extend({}, base, extendedOptions, userOptions);\n        },\n\n\n        getTagSetting: function (key) {\n            var prefix = this.tagOptionsPrefix,\n                val, i, pairs, keyval;\n            if (prefix === false || prefix === undefined) {\n                return UNSET_OPTION;\n            }\n            if (this.tagValCache.hasOwnProperty(key)) {\n                val = this.tagValCache.key;\n            } else {\n                val = this.tag.getAttribute(prefix + key);\n                if (val === undefined || val === null) {\n                    val = UNSET_OPTION;\n                } else if (val.substr(0, 1) === '[') {\n                    val = val.substr(1, val.length - 2).split(',');\n                    for (i = val.length; i--;) {\n                        val[i] = normalizeValue(val[i].replace(/(^\\s*)|(\\s*$)/g, ''));\n                    }\n                } else if (val.substr(0, 1) === '{') {\n                    pairs = val.substr(1, val.length - 2).split(',');\n                    val = {};\n                    for (i = pairs.length; i--;) {\n                        keyval = pairs[i].split(':', 2);\n                        val[keyval[0].replace(/(^\\s*)|(\\s*$)/g, '')] = normalizeValue(keyval[1].replace(/(^\\s*)|(\\s*$)/g, ''));\n                    }\n                } else {\n                    val = normalizeValue(val);\n                }\n                this.tagValCache.key = val;\n            }\n            return val;\n        },\n\n        get: function (key, defaultval) {\n            var tagOption = this.getTagSetting(key),\n                result;\n            if (tagOption !== UNSET_OPTION) {\n                return tagOption;\n            }\n            return (result = this.mergedOptions[key]) === undefined ? defaultval : result;\n        }\n    });\n\n\n    $.fn.sparkline._base = createClass({\n        disabled: false,\n\n        init: function (el, values, options, width, height) {\n            this.el = el;\n            this.$el = $(el);\n            this.values = values;\n            this.options = options;\n            this.width = width;\n            this.height = height;\n            this.currentRegion = undefined;\n        },\n\n        /**\n         * Setup the canvas\n         */\n        initTarget: function () {\n            var interactive = !this.options.get('disableInteraction');\n            if (!(this.target = this.$el.simpledraw(this.width, this.height, this.options.get('composite'), interactive))) {\n                this.disabled = true;\n            } else {\n                this.canvasWidth = this.target.pixelWidth;\n                this.canvasHeight = this.target.pixelHeight;\n            }\n        },\n\n        /**\n         * Actually render the chart to the canvas\n         */\n        render: function () {\n            if (this.disabled) {\n                this.el.innerHTML = '';\n                return false;\n            }\n            return true;\n        },\n\n        /**\n         * Return a region id for a given x/y co-ordinate\n         */\n        getRegion: function (x, y) {\n        },\n\n        /**\n         * Highlight an item based on the moused-over x,y co-ordinate\n         */\n        setRegionHighlight: function (el, x, y) {\n            var currentRegion = this.currentRegion,\n                highlightEnabled = !this.options.get('disableHighlight'),\n                newRegion;\n            if (x > this.canvasWidth || y > this.canvasHeight || x < 0 || y < 0) {\n                return null;\n            }\n            newRegion = this.getRegion(el, x, y);\n            if (currentRegion !== newRegion) {\n                if (currentRegion !== undefined && highlightEnabled) {\n                    this.removeHighlight();\n                }\n                this.currentRegion = newRegion;\n                if (newRegion !== undefined && highlightEnabled) {\n                    this.renderHighlight();\n                }\n                return true;\n            }\n            return false;\n        },\n\n        /**\n         * Reset any currently highlighted item\n         */\n        clearRegionHighlight: function () {\n            if (this.currentRegion !== undefined) {\n                this.removeHighlight();\n                this.currentRegion = undefined;\n                return true;\n            }\n            return false;\n        },\n\n        renderHighlight: function () {\n            this.changeHighlight(true);\n        },\n\n        removeHighlight: function () {\n            this.changeHighlight(false);\n        },\n\n        changeHighlight: function (highlight)  {},\n\n        /**\n         * Fetch the HTML to display as a tooltip\n         */\n        getCurrentRegionTooltip: function () {\n            var options = this.options,\n                header = '',\n                entries = [],\n                fields, formats, formatlen, fclass, text, i,\n                showFields, showFieldsKey, newFields, fv,\n                formatter, format, fieldlen, j;\n            if (this.currentRegion === undefined) {\n                return '';\n            }\n            fields = this.getCurrentRegionFields();\n            formatter = options.get('tooltipFormatter');\n            if (formatter) {\n                return formatter(this, options, fields);\n            }\n            if (options.get('tooltipChartTitle')) {\n                header += '<div class=\"jqs jqstitle\">' + options.get('tooltipChartTitle') + '</div>\\n';\n            }\n            formats = this.options.get('tooltipFormat');\n            if (!formats) {\n                return '';\n            }\n            if (!$.isArray(formats)) {\n                formats = [formats];\n            }\n            if (!$.isArray(fields)) {\n                fields = [fields];\n            }\n            showFields = this.options.get('tooltipFormatFieldlist');\n            showFieldsKey = this.options.get('tooltipFormatFieldlistKey');\n            if (showFields && showFieldsKey) {\n                // user-selected ordering of fields\n                newFields = [];\n                for (i = fields.length; i--;) {\n                    fv = fields[i][showFieldsKey];\n                    if ((j = $.inArray(fv, showFields)) != -1) {\n                        newFields[j] = fields[i];\n                    }\n                }\n                fields = newFields;\n            }\n            formatlen = formats.length;\n            fieldlen = fields.length;\n            for (i = 0; i < formatlen; i++) {\n                format = formats[i];\n                if (typeof format === 'string') {\n                    format = new SPFormat(format);\n                }\n                fclass = format.fclass || 'jqsfield';\n                for (j = 0; j < fieldlen; j++) {\n                    if (!fields[j].isNull || !options.get('tooltipSkipNull')) {\n                        $.extend(fields[j], {\n                            prefix: options.get('tooltipPrefix'),\n                            suffix: options.get('tooltipSuffix')\n                        });\n                        text = format.render(fields[j], options.get('tooltipValueLookups'), options);\n                        entries.push('<div class=\"' + fclass + '\">' + text + '</div>');\n                    }\n                }\n            }\n            if (entries.length) {\n                return header + entries.join('\\n');\n            }\n            return '';\n        },\n\n        getCurrentRegionFields: function () {},\n\n        calcHighlightColor: function (color, options) {\n            var highlightColor = options.get('highlightColor'),\n                lighten = options.get('highlightLighten'),\n                parse, mult, rgbnew, i;\n            if (highlightColor) {\n                return highlightColor;\n            }\n            if (lighten) {\n                // extract RGB values\n                parse = /^#([0-9a-f])([0-9a-f])([0-9a-f])$/i.exec(color) || /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(color);\n                if (parse) {\n                    rgbnew = [];\n                    mult = color.length === 4 ? 16 : 1;\n                    for (i = 0; i < 3; i++) {\n                        rgbnew[i] = clipval(Math.round(parseInt(parse[i + 1], 16) * mult * lighten), 0, 255);\n                    }\n                    return 'rgb(' + rgbnew.join(',') + ')';\n                }\n\n            }\n            return color;\n        }\n\n    });\n\n    barHighlightMixin = {\n        changeHighlight: function (highlight) {\n            var currentRegion = this.currentRegion,\n                target = this.target,\n                shapeids = this.regionShapes[currentRegion],\n                newShapes;\n            // will be null if the region value was null\n            if (shapeids) {\n                newShapes = this.renderRegion(currentRegion, highlight);\n                if ($.isArray(newShapes) || $.isArray(shapeids)) {\n                    target.replaceWithShapes(shapeids, newShapes);\n                    this.regionShapes[currentRegion] = $.map(newShapes, function (newShape) {\n                        return newShape.id;\n                    });\n                } else {\n                    target.replaceWithShape(shapeids, newShapes);\n                    this.regionShapes[currentRegion] = newShapes.id;\n                }\n            }\n        },\n\n        render: function () {\n            var values = this.values,\n                target = this.target,\n                regionShapes = this.regionShapes,\n                shapes, ids, i, j;\n\n            if (!this.cls._super.render.call(this)) {\n                return;\n            }\n            for (i = values.length; i--;) {\n                shapes = this.renderRegion(i);\n                if (shapes) {\n                    if ($.isArray(shapes)) {\n                        ids = [];\n                        for (j = shapes.length; j--;) {\n                            shapes[j].append();\n                            ids.push(shapes[j].id);\n                        }\n                        regionShapes[i] = ids;\n                    } else {\n                        shapes.append();\n                        regionShapes[i] = shapes.id; // store just the shapeid\n                    }\n                } else {\n                    // null value\n                    regionShapes[i] = null;\n                }\n            }\n            target.render();\n        }\n    };\n\n    /**\n     * Line charts\n     */\n    $.fn.sparkline.line = line = createClass($.fn.sparkline._base, {\n        type: 'line',\n\n        init: function (el, values, options, width, height) {\n            line._super.init.call(this, el, values, options, width, height);\n            this.vertices = [];\n            this.regionMap = [];\n            this.xvalues = [];\n            this.yvalues = [];\n            this.yminmax = [];\n            this.hightlightSpotId = null;\n            this.lastShapeId = null;\n            this.initTarget();\n        },\n\n        getRegion: function (el, x, y) {\n            var i,\n                regionMap = this.regionMap; // maps regions to value positions\n            for (i = regionMap.length; i--;) {\n                if (regionMap[i] !== null && x >= regionMap[i][0] && x <= regionMap[i][1]) {\n                    return regionMap[i][2];\n                }\n            }\n            return undefined;\n        },\n\n        getCurrentRegionFields: function () {\n            var currentRegion = this.currentRegion;\n            return {\n                isNull: this.yvalues[currentRegion] === null,\n                x: this.xvalues[currentRegion],\n                y: this.yvalues[currentRegion],\n                color: this.options.get('lineColor'),\n                fillColor: this.options.get('fillColor'),\n                offset: currentRegion\n            };\n        },\n\n        renderHighlight: function () {\n            var currentRegion = this.currentRegion,\n                target = this.target,\n                vertex = this.vertices[currentRegion],\n                options = this.options,\n                spotRadius = options.get('spotRadius'),\n                highlightSpotColor = options.get('highlightSpotColor'),\n                highlightLineColor = options.get('highlightLineColor'),\n                highlightSpot, highlightLine;\n\n            if (!vertex) {\n                return;\n            }\n            if (spotRadius && highlightSpotColor) {\n                highlightSpot = target.drawCircle(vertex[0], vertex[1],\n                    spotRadius, undefined, highlightSpotColor);\n                this.highlightSpotId = highlightSpot.id;\n                target.insertAfterShape(this.lastShapeId, highlightSpot);\n            }\n            if (highlightLineColor) {\n                highlightLine = target.drawLine(vertex[0], this.canvasTop, vertex[0],\n                    this.canvasTop + this.canvasHeight, highlightLineColor);\n                this.highlightLineId = highlightLine.id;\n                target.insertAfterShape(this.lastShapeId, highlightLine);\n            }\n        },\n\n        removeHighlight: function () {\n            var target = this.target;\n            if (this.highlightSpotId) {\n                target.removeShapeId(this.highlightSpotId);\n                this.highlightSpotId = null;\n            }\n            if (this.highlightLineId) {\n                target.removeShapeId(this.highlightLineId);\n                this.highlightLineId = null;\n            }\n        },\n\n        scanValues: function () {\n            var values = this.values,\n                valcount = values.length,\n                xvalues = this.xvalues,\n                yvalues = this.yvalues,\n                yminmax = this.yminmax,\n                i, val, isStr, isArray, sp;\n            for (i = 0; i < valcount; i++) {\n                val = values[i];\n                isStr = typeof(values[i]) === 'string';\n                isArray = typeof(values[i]) === 'object' && values[i] instanceof Array;\n                sp = isStr && values[i].split(':');\n                if (isStr && sp.length === 2) { // x:y\n                    xvalues.push(Number(sp[0]));\n                    yvalues.push(Number(sp[1]));\n                    yminmax.push(Number(sp[1]));\n                } else if (isArray) {\n                    xvalues.push(val[0]);\n                    yvalues.push(val[1]);\n                    yminmax.push(val[1]);\n                } else {\n                    xvalues.push(i);\n                    if (values[i] === null || values[i] === 'null') {\n                        yvalues.push(null);\n                    } else {\n                        yvalues.push(Number(val));\n                        yminmax.push(Number(val));\n                    }\n                }\n            }\n            if (this.options.get('xvalues')) {\n                xvalues = this.options.get('xvalues');\n            }\n\n            this.maxy = this.maxyorg = Math.max.apply(Math, yminmax);\n            this.miny = this.minyorg = Math.min.apply(Math, yminmax);\n\n            this.maxx = Math.max.apply(Math, xvalues);\n            this.minx = Math.min.apply(Math, xvalues);\n\n            this.xvalues = xvalues;\n            this.yvalues = yvalues;\n            this.yminmax = yminmax;\n\n        },\n\n        processRangeOptions: function () {\n            var options = this.options,\n                normalRangeMin = options.get('normalRangeMin'),\n                normalRangeMax = options.get('normalRangeMax');\n\n            if (normalRangeMin !== undefined) {\n                if (normalRangeMin < this.miny) {\n                    this.miny = normalRangeMin;\n                }\n                if (normalRangeMax > this.maxy) {\n                    this.maxy = normalRangeMax;\n                }\n            }\n            if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.miny)) {\n                this.miny = options.get('chartRangeMin');\n            }\n            if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.maxy)) {\n                this.maxy = options.get('chartRangeMax');\n            }\n            if (options.get('chartRangeMinX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMinX') < this.minx)) {\n                this.minx = options.get('chartRangeMinX');\n            }\n            if (options.get('chartRangeMaxX') !== undefined && (options.get('chartRangeClipX') || options.get('chartRangeMaxX') > this.maxx)) {\n                this.maxx = options.get('chartRangeMaxX');\n            }\n\n        },\n\n        drawNormalRange: function (canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey) {\n            var normalRangeMin = this.options.get('normalRangeMin'),\n                normalRangeMax = this.options.get('normalRangeMax'),\n                ytop = canvasTop + Math.round(canvasHeight - (canvasHeight * ((normalRangeMax - this.miny) / rangey))),\n                height = Math.round((canvasHeight * (normalRangeMax - normalRangeMin)) / rangey);\n            this.target.drawRect(canvasLeft, ytop, canvasWidth, height, undefined, this.options.get('normalRangeColor')).append();\n        },\n\n        render: function () {\n            var options = this.options,\n                target = this.target,\n                canvasWidth = this.canvasWidth,\n                canvasHeight = this.canvasHeight,\n                vertices = this.vertices,\n                spotRadius = options.get('spotRadius'),\n                regionMap = this.regionMap,\n                rangex, rangey, yvallast,\n                canvasTop, canvasLeft,\n                vertex, path, paths, x, y, xnext, xpos, xposnext,\n                last, next, yvalcount, lineShapes, fillShapes, plen,\n                valueSpots, hlSpotsEnabled, color, xvalues, yvalues, i;\n\n            if (!line._super.render.call(this)) {\n                return;\n            }\n\n            this.scanValues();\n            this.processRangeOptions();\n\n            xvalues = this.xvalues;\n            yvalues = this.yvalues;\n\n            if (!this.yminmax.length || this.yvalues.length < 2) {\n                // empty or all null valuess\n                return;\n            }\n\n            canvasTop = canvasLeft = 0;\n\n            rangex = this.maxx - this.minx === 0 ? 1 : this.maxx - this.minx;\n            rangey = this.maxy - this.miny === 0 ? 1 : this.maxy - this.miny;\n            yvallast = this.yvalues.length - 1;\n\n            if (spotRadius && (canvasWidth < (spotRadius * 4) || canvasHeight < (spotRadius * 4))) {\n                spotRadius = 0;\n            }\n            if (spotRadius) {\n                // adjust the canvas size as required so that spots will fit\n                hlSpotsEnabled = options.get('highlightSpotColor') &&  !options.get('disableInteraction');\n                if (hlSpotsEnabled || options.get('minSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.miny)) {\n                    canvasHeight -= Math.ceil(spotRadius);\n                }\n                if (hlSpotsEnabled || options.get('maxSpotColor') || (options.get('spotColor') && yvalues[yvallast] === this.maxy)) {\n                    canvasHeight -= Math.ceil(spotRadius);\n                    canvasTop += Math.ceil(spotRadius);\n                }\n                if (hlSpotsEnabled ||\n                     ((options.get('minSpotColor') || options.get('maxSpotColor')) && (yvalues[0] === this.miny || yvalues[0] === this.maxy))) {\n                    canvasLeft += Math.ceil(spotRadius);\n                    canvasWidth -= Math.ceil(spotRadius);\n                }\n                if (hlSpotsEnabled || options.get('spotColor') ||\n                    (options.get('minSpotColor') || options.get('maxSpotColor') &&\n                        (yvalues[yvallast] === this.miny || yvalues[yvallast] === this.maxy))) {\n                    canvasWidth -= Math.ceil(spotRadius);\n                }\n            }\n\n\n            canvasHeight--;\n\n            if (options.get('normalRangeMin') !== undefined && !options.get('drawNormalOnTop')) {\n                this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey);\n            }\n\n            path = [];\n            paths = [path];\n            last = next = null;\n            yvalcount = yvalues.length;\n            for (i = 0; i < yvalcount; i++) {\n                x = xvalues[i];\n                xnext = xvalues[i + 1];\n                y = yvalues[i];\n                xpos = canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex));\n                xposnext = i < yvalcount - 1 ? canvasLeft + Math.round((xnext - this.minx) * (canvasWidth / rangex)) : canvasWidth;\n                next = xpos + ((xposnext - xpos) / 2);\n                regionMap[i] = [last || 0, next, i];\n                last = next;\n                if (y === null) {\n                    if (i) {\n                        if (yvalues[i - 1] !== null) {\n                            path = [];\n                            paths.push(path);\n                        }\n                        vertices.push(null);\n                    }\n                } else {\n                    if (y < this.miny) {\n                        y = this.miny;\n                    }\n                    if (y > this.maxy) {\n                        y = this.maxy;\n                    }\n                    if (!path.length) {\n                        // previous value was null\n                        path.push([xpos, canvasTop + canvasHeight]);\n                    }\n                    vertex = [xpos, canvasTop + Math.round(canvasHeight - (canvasHeight * ((y - this.miny) / rangey)))];\n                    path.push(vertex);\n                    vertices.push(vertex);\n                }\n            }\n\n            lineShapes = [];\n            fillShapes = [];\n            plen = paths.length;\n            for (i = 0; i < plen; i++) {\n                path = paths[i];\n                if (path.length) {\n                    if (options.get('fillColor')) {\n                        path.push([path[path.length - 1][0], (canvasTop + canvasHeight)]);\n                        fillShapes.push(path.slice(0));\n                        path.pop();\n                    }\n                    // if there's only a single point in this path, then we want to display it\n                    // as a vertical line which means we keep path[0]  as is\n                    if (path.length > 2) {\n                        // else we want the first value\n                        path[0] = [path[0][0], path[1][1]];\n                    }\n                    lineShapes.push(path);\n                }\n            }\n\n            // draw the fill first, then optionally the normal range, then the line on top of that\n            plen = fillShapes.length;\n            for (i = 0; i < plen; i++) {\n                target.drawShape(fillShapes[i],\n                    options.get('fillColor'), options.get('fillColor')).append();\n            }\n\n            if (options.get('normalRangeMin') !== undefined && options.get('drawNormalOnTop')) {\n                this.drawNormalRange(canvasLeft, canvasTop, canvasHeight, canvasWidth, rangey);\n            }\n\n            plen = lineShapes.length;\n            for (i = 0; i < plen; i++) {\n                target.drawShape(lineShapes[i], options.get('lineColor'), undefined,\n                    options.get('lineWidth')).append();\n            }\n\n            if (spotRadius && options.get('valueSpots')) {\n                valueSpots = options.get('valueSpots');\n                if (valueSpots.get === undefined) {\n                    valueSpots = new RangeMap(valueSpots);\n                }\n                for (i = 0; i < yvalcount; i++) {\n                    color = valueSpots.get(yvalues[i]);\n                    if (color) {\n                        target.drawCircle(canvasLeft + Math.round((xvalues[i] - this.minx) * (canvasWidth / rangex)),\n                            canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[i] - this.miny) / rangey))),\n                            spotRadius, undefined,\n                            color).append();\n                    }\n                }\n\n            }\n            if (spotRadius && options.get('spotColor') && yvalues[yvallast] !== null) {\n                target.drawCircle(canvasLeft + Math.round((xvalues[xvalues.length - 1] - this.minx) * (canvasWidth / rangex)),\n                    canvasTop + Math.round(canvasHeight - (canvasHeight * ((yvalues[yvallast] - this.miny) / rangey))),\n                    spotRadius, undefined,\n                    options.get('spotColor')).append();\n            }\n            if (this.maxy !== this.minyorg) {\n                if (spotRadius && options.get('minSpotColor')) {\n                    x = xvalues[$.inArray(this.minyorg, yvalues)];\n                    target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)),\n                        canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.minyorg - this.miny) / rangey))),\n                        spotRadius, undefined,\n                        options.get('minSpotColor')).append();\n                }\n                if (spotRadius && options.get('maxSpotColor')) {\n                    x = xvalues[$.inArray(this.maxyorg, yvalues)];\n                    target.drawCircle(canvasLeft + Math.round((x - this.minx) * (canvasWidth / rangex)),\n                        canvasTop + Math.round(canvasHeight - (canvasHeight * ((this.maxyorg - this.miny) / rangey))),\n                        spotRadius, undefined,\n                        options.get('maxSpotColor')).append();\n                }\n            }\n\n            this.lastShapeId = target.getLastShapeId();\n            this.canvasTop = canvasTop;\n            target.render();\n        }\n    });\n\n    /**\n     * Bar charts\n     */\n    $.fn.sparkline.bar = bar = createClass($.fn.sparkline._base, barHighlightMixin, {\n        type: 'bar',\n\n        init: function (el, values, options, width, height) {\n            var barWidth = parseInt(options.get('barWidth'), 10),\n                barSpacing = parseInt(options.get('barSpacing'), 10),\n                chartRangeMin = options.get('chartRangeMin'),\n                chartRangeMax = options.get('chartRangeMax'),\n                chartRangeClip = options.get('chartRangeClip'),\n                stackMin = Infinity,\n                stackMax = -Infinity,\n                isStackString, groupMin, groupMax, stackRanges,\n                numValues, i, vlen, range, zeroAxis, xaxisOffset, min, max, clipMin, clipMax,\n                stacked, vlist, j, slen, svals, val, yoffset, yMaxCalc, canvasHeightEf;\n            bar._super.init.call(this, el, values, options, width, height);\n\n            // scan values to determine whether to stack bars\n            for (i = 0, vlen = values.length; i < vlen; i++) {\n                val = values[i];\n                isStackString = typeof(val) === 'string' && val.indexOf(':') > -1;\n                if (isStackString || $.isArray(val)) {\n                    stacked = true;\n                    if (isStackString) {\n                        val = values[i] = normalizeValues(val.split(':'));\n                    }\n                    val = remove(val, null); // min/max will treat null as zero\n                    groupMin = Math.min.apply(Math, val);\n                    groupMax = Math.max.apply(Math, val);\n                    if (groupMin < stackMin) {\n                        stackMin = groupMin;\n                    }\n                    if (groupMax > stackMax) {\n                        stackMax = groupMax;\n                    }\n                }\n            }\n\n            this.stacked = stacked;\n            this.regionShapes = {};\n            this.barWidth = barWidth;\n            this.barSpacing = barSpacing;\n            this.totalBarWidth = barWidth + barSpacing;\n            this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing);\n\n            this.initTarget();\n\n            if (chartRangeClip) {\n                clipMin = chartRangeMin === undefined ? -Infinity : chartRangeMin;\n                clipMax = chartRangeMax === undefined ? Infinity : chartRangeMax;\n            }\n\n            numValues = [];\n            stackRanges = stacked ? [] : numValues;\n            var stackTotals = [];\n            var stackRangesNeg = [];\n            for (i = 0, vlen = values.length; i < vlen; i++) {\n                if (stacked) {\n                    vlist = values[i];\n                    values[i] = svals = [];\n                    stackTotals[i] = 0;\n                    stackRanges[i] = stackRangesNeg[i] = 0;\n                    for (j = 0, slen = vlist.length; j < slen; j++) {\n                        val = svals[j] = chartRangeClip ? clipval(vlist[j], clipMin, clipMax) : vlist[j];\n                        if (val !== null) {\n                            if (val > 0) {\n                                stackTotals[i] += val;\n                            }\n                            if (stackMin < 0 && stackMax > 0) {\n                                if (val < 0) {\n                                    stackRangesNeg[i] += Math.abs(val);\n                                } else {\n                                    stackRanges[i] += val;\n                                }\n                            } else {\n                                stackRanges[i] += Math.abs(val - (val < 0 ? stackMax : stackMin));\n                            }\n                            numValues.push(val);\n                        }\n                    }\n                } else {\n                    val = chartRangeClip ? clipval(values[i], clipMin, clipMax) : values[i];\n                    val = values[i] = normalizeValue(val);\n                    if (val !== null) {\n                        numValues.push(val);\n                    }\n                }\n            }\n            this.max = max = Math.max.apply(Math, numValues);\n            this.min = min = Math.min.apply(Math, numValues);\n            this.stackMax = stackMax = stacked ? Math.max.apply(Math, stackTotals) : max;\n            this.stackMin = stackMin = stacked ? Math.min.apply(Math, numValues) : min;\n\n            if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < min)) {\n                min = options.get('chartRangeMin');\n            }\n            if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > max)) {\n                max = options.get('chartRangeMax');\n            }\n\n            this.zeroAxis = zeroAxis = options.get('zeroAxis', true);\n            if (min <= 0 && max >= 0 && zeroAxis) {\n                xaxisOffset = 0;\n            } else if (zeroAxis == false) {\n                xaxisOffset = min;\n            } else if (min > 0) {\n                xaxisOffset = min;\n            } else {\n                xaxisOffset = max;\n            }\n            this.xaxisOffset = xaxisOffset;\n\n            range = stacked ? (Math.max.apply(Math, stackRanges) + Math.max.apply(Math, stackRangesNeg)) : max - min;\n\n            // as we plot zero/min values a single pixel line, we add a pixel to all other\n            // values - Reduce the effective canvas size to suit\n            this.canvasHeightEf = (zeroAxis && min < 0) ? this.canvasHeight - 2 : this.canvasHeight - 1;\n\n            if (min < xaxisOffset) {\n                yMaxCalc = (stacked && max >= 0) ? stackMax : max;\n                yoffset = (yMaxCalc - xaxisOffset) / range * this.canvasHeight;\n                if (yoffset !== Math.ceil(yoffset)) {\n                    this.canvasHeightEf -= 2;\n                    yoffset = Math.ceil(yoffset);\n                }\n            } else {\n                yoffset = this.canvasHeight;\n            }\n            this.yoffset = yoffset;\n\n            if ($.isArray(options.get('colorMap'))) {\n                this.colorMapByIndex = options.get('colorMap');\n                this.colorMapByValue = null;\n            } else {\n                this.colorMapByIndex = null;\n                this.colorMapByValue = options.get('colorMap');\n                if (this.colorMapByValue && this.colorMapByValue.get === undefined) {\n                    this.colorMapByValue = new RangeMap(this.colorMapByValue);\n                }\n            }\n\n            this.range = range;\n        },\n\n        getRegion: function (el, x, y) {\n            var result = Math.floor(x / this.totalBarWidth);\n            return (result < 0 || result >= this.values.length) ? undefined : result;\n        },\n\n        getCurrentRegionFields: function () {\n            var currentRegion = this.currentRegion,\n                values = ensureArray(this.values[currentRegion]),\n                result = [],\n                value, i;\n            for (i = values.length; i--;) {\n                value = values[i];\n                result.push({\n                    isNull: value === null,\n                    value: value,\n                    color: this.calcColor(i, value, currentRegion),\n                    offset: currentRegion\n                });\n            }\n            return result;\n        },\n\n        calcColor: function (stacknum, value, valuenum) {\n            var colorMapByIndex = this.colorMapByIndex,\n                colorMapByValue = this.colorMapByValue,\n                options = this.options,\n                color, newColor;\n            if (this.stacked) {\n                color = options.get('stackedBarColor');\n            } else {\n                color = (value < 0) ? options.get('negBarColor') : options.get('barColor');\n            }\n            if (value === 0 && options.get('zeroColor') !== undefined) {\n                color = options.get('zeroColor');\n            }\n            if (colorMapByValue && (newColor = colorMapByValue.get(value))) {\n                color = newColor;\n            } else if (colorMapByIndex && colorMapByIndex.length > valuenum) {\n                color = colorMapByIndex[valuenum];\n            }\n            return $.isArray(color) ? color[stacknum % color.length] : color;\n        },\n\n        /**\n         * Render bar(s) for a region\n         */\n        renderRegion: function (valuenum, highlight) {\n            var vals = this.values[valuenum],\n                options = this.options,\n                xaxisOffset = this.xaxisOffset,\n                result = [],\n                range = this.range,\n                stacked = this.stacked,\n                target = this.target,\n                x = valuenum * this.totalBarWidth,\n                canvasHeightEf = this.canvasHeightEf,\n                yoffset = this.yoffset,\n                y, height, color, isNull, yoffsetNeg, i, valcount, val, minPlotted, allMin;\n\n            vals = $.isArray(vals) ? vals : [vals];\n            valcount = vals.length;\n            val = vals[0];\n            isNull = all(null, vals);\n            allMin = all(xaxisOffset, vals, true);\n\n            if (isNull) {\n                if (options.get('nullColor')) {\n                    color = highlight ? options.get('nullColor') : this.calcHighlightColor(options.get('nullColor'), options);\n                    y = (yoffset > 0) ? yoffset - 1 : yoffset;\n                    return target.drawRect(x, y, this.barWidth - 1, 0, color, color);\n                } else {\n                    return undefined;\n                }\n            }\n            yoffsetNeg = yoffset;\n            for (i = 0; i < valcount; i++) {\n                val = vals[i];\n\n                if (stacked && val === xaxisOffset) {\n                    if (!allMin || minPlotted) {\n                        continue;\n                    }\n                    minPlotted = true;\n                }\n\n                if (range > 0) {\n                    height = Math.floor(canvasHeightEf * ((Math.abs(val - xaxisOffset) / range))) + 1;\n                } else {\n                    height = 1;\n                }\n                if (val < xaxisOffset || (val === xaxisOffset && yoffset === 0)) {\n                    y = yoffsetNeg;\n                    yoffsetNeg += height;\n                } else {\n                    y = yoffset - height;\n                    yoffset -= height;\n                }\n                color = this.calcColor(i, val, valuenum);\n                if (highlight) {\n                    color = this.calcHighlightColor(color, options);\n                }\n                result.push(target.drawRect(x, y, this.barWidth - 1, height - 1, color, color));\n            }\n            if (result.length === 1) {\n                return result[0];\n            }\n            return result;\n        }\n    });\n\n    /**\n     * Tristate charts\n     */\n    $.fn.sparkline.tristate = tristate = createClass($.fn.sparkline._base, barHighlightMixin, {\n        type: 'tristate',\n\n        init: function (el, values, options, width, height) {\n            var barWidth = parseInt(options.get('barWidth'), 10),\n                barSpacing = parseInt(options.get('barSpacing'), 10);\n            tristate._super.init.call(this, el, values, options, width, height);\n\n            this.regionShapes = {};\n            this.barWidth = barWidth;\n            this.barSpacing = barSpacing;\n            this.totalBarWidth = barWidth + barSpacing;\n            this.values = $.map(values, Number);\n            this.width = width = (values.length * barWidth) + ((values.length - 1) * barSpacing);\n\n            if ($.isArray(options.get('colorMap'))) {\n                this.colorMapByIndex = options.get('colorMap');\n                this.colorMapByValue = null;\n            } else {\n                this.colorMapByIndex = null;\n                this.colorMapByValue = options.get('colorMap');\n                if (this.colorMapByValue && this.colorMapByValue.get === undefined) {\n                    this.colorMapByValue = new RangeMap(this.colorMapByValue);\n                }\n            }\n            this.initTarget();\n        },\n\n        getRegion: function (el, x, y) {\n            return Math.floor(x / this.totalBarWidth);\n        },\n\n        getCurrentRegionFields: function () {\n            var currentRegion = this.currentRegion;\n            return {\n                isNull: this.values[currentRegion] === undefined,\n                value: this.values[currentRegion],\n                color: this.calcColor(this.values[currentRegion], currentRegion),\n                offset: currentRegion\n            };\n        },\n\n        calcColor: function (value, valuenum) {\n            var values = this.values,\n                options = this.options,\n                colorMapByIndex = this.colorMapByIndex,\n                colorMapByValue = this.colorMapByValue,\n                color, newColor;\n\n            if (colorMapByValue && (newColor = colorMapByValue.get(value))) {\n                color = newColor;\n            } else if (colorMapByIndex && colorMapByIndex.length > valuenum) {\n                color = colorMapByIndex[valuenum];\n            } else if (values[valuenum] < 0) {\n                color = options.get('negBarColor');\n            } else if (values[valuenum] > 0) {\n                color = options.get('posBarColor');\n            } else {\n                color = options.get('zeroBarColor');\n            }\n            return color;\n        },\n\n        renderRegion: function (valuenum, highlight) {\n            var values = this.values,\n                options = this.options,\n                target = this.target,\n                canvasHeight, height, halfHeight,\n                x, y, color;\n\n            canvasHeight = target.pixelHeight;\n            halfHeight = Math.round(canvasHeight / 2);\n\n            x = valuenum * this.totalBarWidth;\n            if (values[valuenum] < 0) {\n                y = halfHeight;\n                height = halfHeight - 1;\n            } else if (values[valuenum] > 0) {\n                y = 0;\n                height = halfHeight - 1;\n            } else {\n                y = halfHeight - 1;\n                height = 2;\n            }\n            color = this.calcColor(values[valuenum], valuenum);\n            if (color === null) {\n                return;\n            }\n            if (highlight) {\n                color = this.calcHighlightColor(color, options);\n            }\n            return target.drawRect(x, y, this.barWidth - 1, height - 1, color, color);\n        }\n    });\n\n    /**\n     * Discrete charts\n     */\n    $.fn.sparkline.discrete = discrete = createClass($.fn.sparkline._base, barHighlightMixin, {\n        type: 'discrete',\n\n        init: function (el, values, options, width, height) {\n            discrete._super.init.call(this, el, values, options, width, height);\n\n            this.regionShapes = {};\n            this.values = values = $.map(values, Number);\n            this.min = Math.min.apply(Math, values);\n            this.max = Math.max.apply(Math, values);\n            this.range = this.max - this.min;\n            this.width = width = options.get('width') === 'auto' ? values.length * 2 : this.width;\n            this.interval = Math.floor(width / values.length);\n            this.itemWidth = width / values.length;\n            if (options.get('chartRangeMin') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMin') < this.min)) {\n                this.min = options.get('chartRangeMin');\n            }\n            if (options.get('chartRangeMax') !== undefined && (options.get('chartRangeClip') || options.get('chartRangeMax') > this.max)) {\n                this.max = options.get('chartRangeMax');\n            }\n            this.initTarget();\n            if (this.target) {\n                this.lineHeight = options.get('lineHeight') === 'auto' ? Math.round(this.canvasHeight * 0.3) : options.get('lineHeight');\n            }\n        },\n\n        getRegion: function (el, x, y) {\n            return Math.floor(x / this.itemWidth);\n        },\n\n        getCurrentRegionFields: function () {\n            var currentRegion = this.currentRegion;\n            return {\n                isNull: this.values[currentRegion] === undefined,\n                value: this.values[currentRegion],\n                offset: currentRegion\n            };\n        },\n\n        renderRegion: function (valuenum, highlight) {\n            var values = this.values,\n                options = this.options,\n                min = this.min,\n                max = this.max,\n                range = this.range,\n                interval = this.interval,\n                target = this.target,\n                canvasHeight = this.canvasHeight,\n                lineHeight = this.lineHeight,\n                pheight = canvasHeight - lineHeight,\n                ytop, val, color, x;\n\n            val = clipval(values[valuenum], min, max);\n            x = valuenum * interval;\n            ytop = Math.round(pheight - pheight * ((val - min) / range));\n            color = (options.get('thresholdColor') && val < options.get('thresholdValue')) ? options.get('thresholdColor') : options.get('lineColor');\n            if (highlight) {\n                color = this.calcHighlightColor(color, options);\n            }\n            return target.drawLine(x, ytop, x, ytop + lineHeight, color);\n        }\n    });\n\n    /**\n     * Bullet charts\n     */\n    $.fn.sparkline.bullet = bullet = createClass($.fn.sparkline._base, {\n        type: 'bullet',\n\n        init: function (el, values, options, width, height) {\n            var min, max, vals;\n            bullet._super.init.call(this, el, values, options, width, height);\n\n            // values: target, performance, range1, range2, range3\n            this.values = values = normalizeValues(values);\n            // target or performance could be null\n            vals = values.slice();\n            vals[0] = vals[0] === null ? vals[2] : vals[0];\n            vals[1] = values[1] === null ? vals[2] : vals[1];\n            min = Math.min.apply(Math, values);\n            max = Math.max.apply(Math, values);\n            if (options.get('base') === undefined) {\n                min = min < 0 ? min : 0;\n            } else {\n                min = options.get('base');\n            }\n            this.min = min;\n            this.max = max;\n            this.range = max - min;\n            this.shapes = {};\n            this.valueShapes = {};\n            this.regiondata = {};\n            this.width = width = options.get('width') === 'auto' ? '4.0em' : width;\n            this.target = this.$el.simpledraw(width, height, options.get('composite'));\n            if (!values.length) {\n                this.disabled = true;\n            }\n            this.initTarget();\n        },\n\n        getRegion: function (el, x, y) {\n            var shapeid = this.target.getShapeAt(el, x, y);\n            return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;\n        },\n\n        getCurrentRegionFields: function () {\n            var currentRegion = this.currentRegion;\n            return {\n                fieldkey: currentRegion.substr(0, 1),\n                value: this.values[currentRegion.substr(1)],\n                region: currentRegion\n            };\n        },\n\n        changeHighlight: function (highlight) {\n            var currentRegion = this.currentRegion,\n                shapeid = this.valueShapes[currentRegion],\n                shape;\n            delete this.shapes[shapeid];\n            switch (currentRegion.substr(0, 1)) {\n                case 'r':\n                    shape = this.renderRange(currentRegion.substr(1), highlight);\n                    break;\n                case 'p':\n                    shape = this.renderPerformance(highlight);\n                    break;\n                case 't':\n                    shape = this.renderTarget(highlight);\n                    break;\n            }\n            this.valueShapes[currentRegion] = shape.id;\n            this.shapes[shape.id] = currentRegion;\n            this.target.replaceWithShape(shapeid, shape);\n        },\n\n        renderRange: function (rn, highlight) {\n            var rangeval = this.values[rn],\n                rangewidth = Math.round(this.canvasWidth * ((rangeval - this.min) / this.range)),\n                color = this.options.get('rangeColors')[rn - 2];\n            if (highlight) {\n                color = this.calcHighlightColor(color, this.options);\n            }\n            return this.target.drawRect(0, 0, rangewidth - 1, this.canvasHeight - 1, color, color);\n        },\n\n        renderPerformance: function (highlight) {\n            var perfval = this.values[1],\n                perfwidth = Math.round(this.canvasWidth * ((perfval - this.min) / this.range)),\n                color = this.options.get('performanceColor');\n            if (highlight) {\n                color = this.calcHighlightColor(color, this.options);\n            }\n            return this.target.drawRect(0, Math.round(this.canvasHeight * 0.3), perfwidth - 1,\n                Math.round(this.canvasHeight * 0.4) - 1, color, color);\n        },\n\n        renderTarget: function (highlight) {\n            var targetval = this.values[0],\n                x = Math.round(this.canvasWidth * ((targetval - this.min) / this.range) - (this.options.get('targetWidth') / 2)),\n                targettop = Math.round(this.canvasHeight * 0.10),\n                targetheight = this.canvasHeight - (targettop * 2),\n                color = this.options.get('targetColor');\n            if (highlight) {\n                color = this.calcHighlightColor(color, this.options);\n            }\n            return this.target.drawRect(x, targettop, this.options.get('targetWidth') - 1, targetheight - 1, color, color);\n        },\n\n        render: function () {\n            var vlen = this.values.length,\n                target = this.target,\n                i, shape;\n            if (!bullet._super.render.call(this)) {\n                return;\n            }\n            for (i = 2; i < vlen; i++) {\n                shape = this.renderRange(i).append();\n                this.shapes[shape.id] = 'r' + i;\n                this.valueShapes['r' + i] = shape.id;\n            }\n            if (this.values[1] !== null) {\n                shape = this.renderPerformance().append();\n                this.shapes[shape.id] = 'p1';\n                this.valueShapes.p1 = shape.id;\n            }\n            if (this.values[0] !== null) {\n                shape = this.renderTarget().append();\n                this.shapes[shape.id] = 't0';\n                this.valueShapes.t0 = shape.id;\n            }\n            target.render();\n        }\n    });\n\n    /**\n     * Pie charts\n     */\n    $.fn.sparkline.pie = pie = createClass($.fn.sparkline._base, {\n        type: 'pie',\n\n        init: function (el, values, options, width, height) {\n            var total = 0, i;\n\n            pie._super.init.call(this, el, values, options, width, height);\n\n            this.shapes = {}; // map shape ids to value offsets\n            this.valueShapes = {}; // maps value offsets to shape ids\n            this.values = values = $.map(values, Number);\n\n            if (options.get('width') === 'auto') {\n                this.width = this.height;\n            }\n\n            if (values.length > 0) {\n                for (i = values.length; i--;) {\n                    total += values[i];\n                }\n            }\n            this.total = total;\n            this.initTarget();\n            this.radius = Math.floor(Math.min(this.canvasWidth, this.canvasHeight) / 2);\n        },\n\n        getRegion: function (el, x, y) {\n            var shapeid = this.target.getShapeAt(el, x, y);\n            return (shapeid !== undefined && this.shapes[shapeid] !== undefined) ? this.shapes[shapeid] : undefined;\n        },\n\n        getCurrentRegionFields: function () {\n            var currentRegion = this.currentRegion;\n            return {\n                isNull: this.values[currentRegion] === undefined,\n                value: this.values[currentRegion],\n                percent: this.values[currentRegion] / this.total * 100,\n                color: this.options.get('sliceColors')[currentRegion % this.options.get('sliceColors').length],\n                offset: currentRegion\n            };\n        },\n\n        changeHighlight: function (highlight) {\n            var currentRegion = this.currentRegion,\n                 newslice = this.renderSlice(currentRegion, highlight),\n                 shapeid = this.valueShapes[currentRegion];\n            delete this.shapes[shapeid];\n            this.target.replaceWithShape(shapeid, newslice);\n            this.valueShapes[currentRegion] = newslice.id;\n            this.shapes[newslice.id] = currentRegion;\n        },\n\n        renderSlice: function (valuenum, highlight) {\n            var target = this.target,\n                options = this.options,\n                radius = this.radius,\n                borderWidth = options.get('borderWidth'),\n                offset = options.get('offset'),\n                circle = 2 * Math.PI,\n                values = this.values,\n                total = this.total,\n                next = offset ? (2*Math.PI)*(offset/360) : 0,\n                start, end, i, vlen, color;\n\n            vlen = values.length;\n            for (i = 0; i < vlen; i++) {\n                start = next;\n                end = next;\n                if (total > 0) {  // avoid divide by zero\n                    end = next + (circle * (values[i] / total));\n                }\n                if (valuenum === i) {\n                    color = options.get('sliceColors')[i % options.get('sliceColors').length];\n                    if (highlight) {\n                        color = this.calcHighlightColor(color, options);\n                    }\n\n                    return target.drawPieSlice(radius, radius, radius - borderWidth, start, end, undefined, color);\n                }\n                next = end;\n            }\n        },\n\n        render: function () {\n            var target = this.target,\n                values = this.values,\n                options = this.options,\n                radius = this.radius,\n                borderWidth = options.get('borderWidth'),\n                shape, i;\n\n            if (!pie._super.render.call(this)) {\n                return;\n            }\n            if (borderWidth) {\n                target.drawCircle(radius, radius, Math.floor(radius - (borderWidth / 2)),\n                    options.get('borderColor'), undefined, borderWidth).append();\n            }\n            for (i = values.length; i--;) {\n                if (values[i]) { // don't render zero values\n                    shape = this.renderSlice(i).append();\n                    this.valueShapes[i] = shape.id; // store just the shapeid\n                    this.shapes[shape.id] = i;\n                }\n            }\n            target.render();\n        }\n    });\n\n    /**\n     * Box plots\n     */\n    $.fn.sparkline.box = box = createClass($.fn.sparkline._base, {\n        type: 'box',\n\n        init: function (el, values, options, width, height) {\n            box._super.init.call(this, el, values, options, width, height);\n            this.values = $.map(values, Number);\n            this.width = options.get('width') === 'auto' ? '4.0em' : width;\n            this.initTarget();\n            if (!this.values.length) {\n                this.disabled = 1;\n            }\n        },\n\n        /**\n         * Simulate a single region\n         */\n        getRegion: function () {\n            return 1;\n        },\n\n        getCurrentRegionFields: function () {\n            var result = [\n                { field: 'lq', value: this.quartiles[0] },\n                { field: 'med', value: this.quartiles[1] },\n                { field: 'uq', value: this.quartiles[2] }\n            ];\n            if (this.loutlier !== undefined) {\n                result.push({ field: 'lo', value: this.loutlier});\n            }\n            if (this.routlier !== undefined) {\n                result.push({ field: 'ro', value: this.routlier});\n            }\n            if (this.lwhisker !== undefined) {\n                result.push({ field: 'lw', value: this.lwhisker});\n            }\n            if (this.rwhisker !== undefined) {\n                result.push({ field: 'rw', value: this.rwhisker});\n            }\n            return result;\n        },\n\n        render: function () {\n            var target = this.target,\n                values = this.values,\n                vlen = values.length,\n                options = this.options,\n                canvasWidth = this.canvasWidth,\n                canvasHeight = this.canvasHeight,\n                minValue = options.get('chartRangeMin') === undefined ? Math.min.apply(Math, values) : options.get('chartRangeMin'),\n                maxValue = options.get('chartRangeMax') === undefined ? Math.max.apply(Math, values) : options.get('chartRangeMax'),\n                canvasLeft = 0,\n                lwhisker, loutlier, iqr, q1, q2, q3, rwhisker, routlier, i,\n                size, unitSize;\n\n            if (!box._super.render.call(this)) {\n                return;\n            }\n\n            if (options.get('raw')) {\n                if (options.get('showOutliers') && values.length > 5) {\n                    loutlier = values[0];\n                    lwhisker = values[1];\n                    q1 = values[2];\n                    q2 = values[3];\n                    q3 = values[4];\n                    rwhisker = values[5];\n                    routlier = values[6];\n                } else {\n                    lwhisker = values[0];\n                    q1 = values[1];\n                    q2 = values[2];\n                    q3 = values[3];\n                    rwhisker = values[4];\n                }\n            } else {\n                values.sort(function (a, b) { return a - b; });\n                q1 = quartile(values, 1);\n                q2 = quartile(values, 2);\n                q3 = quartile(values, 3);\n                iqr = q3 - q1;\n                if (options.get('showOutliers')) {\n                    lwhisker = rwhisker = undefined;\n                    for (i = 0; i < vlen; i++) {\n                        if (lwhisker === undefined && values[i] > q1 - (iqr * options.get('outlierIQR'))) {\n                            lwhisker = values[i];\n                        }\n                        if (values[i] < q3 + (iqr * options.get('outlierIQR'))) {\n                            rwhisker = values[i];\n                        }\n                    }\n                    loutlier = values[0];\n                    routlier = values[vlen - 1];\n                } else {\n                    lwhisker = values[0];\n                    rwhisker = values[vlen - 1];\n                }\n            }\n            this.quartiles = [q1, q2, q3];\n            this.lwhisker = lwhisker;\n            this.rwhisker = rwhisker;\n            this.loutlier = loutlier;\n            this.routlier = routlier;\n\n            unitSize = canvasWidth / (maxValue - minValue + 1);\n            if (options.get('showOutliers')) {\n                canvasLeft = Math.ceil(options.get('spotRadius'));\n                canvasWidth -= 2 * Math.ceil(options.get('spotRadius'));\n                unitSize = canvasWidth / (maxValue - minValue + 1);\n                if (loutlier < lwhisker) {\n                    target.drawCircle((loutlier - minValue) * unitSize + canvasLeft,\n                        canvasHeight / 2,\n                        options.get('spotRadius'),\n                        options.get('outlierLineColor'),\n                        options.get('outlierFillColor')).append();\n                }\n                if (routlier > rwhisker) {\n                    target.drawCircle((routlier - minValue) * unitSize + canvasLeft,\n                        canvasHeight / 2,\n                        options.get('spotRadius'),\n                        options.get('outlierLineColor'),\n                        options.get('outlierFillColor')).append();\n                }\n            }\n\n            // box\n            target.drawRect(\n                Math.round((q1 - minValue) * unitSize + canvasLeft),\n                Math.round(canvasHeight * 0.1),\n                Math.round((q3 - q1) * unitSize),\n                Math.round(canvasHeight * 0.8),\n                options.get('boxLineColor'),\n                options.get('boxFillColor')).append();\n            // left whisker\n            target.drawLine(\n                Math.round((lwhisker - minValue) * unitSize + canvasLeft),\n                Math.round(canvasHeight / 2),\n                Math.round((q1 - minValue) * unitSize + canvasLeft),\n                Math.round(canvasHeight / 2),\n                options.get('lineColor')).append();\n            target.drawLine(\n                Math.round((lwhisker - minValue) * unitSize + canvasLeft),\n                Math.round(canvasHeight / 4),\n                Math.round((lwhisker - minValue) * unitSize + canvasLeft),\n                Math.round(canvasHeight - canvasHeight / 4),\n                options.get('whiskerColor')).append();\n            // right whisker\n            target.drawLine(Math.round((rwhisker - minValue) * unitSize + canvasLeft),\n                Math.round(canvasHeight / 2),\n                Math.round((q3 - minValue) * unitSize + canvasLeft),\n                Math.round(canvasHeight / 2),\n                options.get('lineColor')).append();\n            target.drawLine(\n                Math.round((rwhisker - minValue) * unitSize + canvasLeft),\n                Math.round(canvasHeight / 4),\n                Math.round((rwhisker - minValue) * unitSize + canvasLeft),\n                Math.round(canvasHeight - canvasHeight / 4),\n                options.get('whiskerColor')).append();\n            // median line\n            target.drawLine(\n                Math.round((q2 - minValue) * unitSize + canvasLeft),\n                Math.round(canvasHeight * 0.1),\n                Math.round((q2 - minValue) * unitSize + canvasLeft),\n                Math.round(canvasHeight * 0.9),\n                options.get('medianColor')).append();\n            if (options.get('target')) {\n                size = Math.ceil(options.get('spotRadius'));\n                target.drawLine(\n                    Math.round((options.get('target') - minValue) * unitSize + canvasLeft),\n                    Math.round((canvasHeight / 2) - size),\n                    Math.round((options.get('target') - minValue) * unitSize + canvasLeft),\n                    Math.round((canvasHeight / 2) + size),\n                    options.get('targetColor')).append();\n                target.drawLine(\n                    Math.round((options.get('target') - minValue) * unitSize + canvasLeft - size),\n                    Math.round(canvasHeight / 2),\n                    Math.round((options.get('target') - minValue) * unitSize + canvasLeft + size),\n                    Math.round(canvasHeight / 2),\n                    options.get('targetColor')).append();\n            }\n            target.render();\n        }\n    });\n\n    // Setup a very simple \"virtual canvas\" to make drawing the few shapes we need easier\n    // This is accessible as $(foo).simpledraw()\n\n    VShape = createClass({\n        init: function (target, id, type, args) {\n            this.target = target;\n            this.id = id;\n            this.type = type;\n            this.args = args;\n        },\n        append: function () {\n            this.target.appendShape(this);\n            return this;\n        }\n    });\n\n    VCanvas_base = createClass({\n        _pxregex: /(\\d+)(px)?\\s*$/i,\n\n        init: function (width, height, target) {\n            if (!width) {\n                return;\n            }\n            this.width = width;\n            this.height = height;\n            this.target = target;\n            this.lastShapeId = null;\n            if (target[0]) {\n                target = target[0];\n            }\n            $.data(target, '_jqs_vcanvas', this);\n        },\n\n        drawLine: function (x1, y1, x2, y2, lineColor, lineWidth) {\n            return this.drawShape([[x1, y1], [x2, y2]], lineColor, lineWidth);\n        },\n\n        drawShape: function (path, lineColor, fillColor, lineWidth) {\n            return this._genShape('Shape', [path, lineColor, fillColor, lineWidth]);\n        },\n\n        drawCircle: function (x, y, radius, lineColor, fillColor, lineWidth) {\n            return this._genShape('Circle', [x, y, radius, lineColor, fillColor, lineWidth]);\n        },\n\n        drawPieSlice: function (x, y, radius, startAngle, endAngle, lineColor, fillColor) {\n            return this._genShape('PieSlice', [x, y, radius, startAngle, endAngle, lineColor, fillColor]);\n        },\n\n        drawRect: function (x, y, width, height, lineColor, fillColor) {\n            return this._genShape('Rect', [x, y, width, height, lineColor, fillColor]);\n        },\n\n        getElement: function () {\n            return this.canvas;\n        },\n\n        /**\n         * Return the most recently inserted shape id\n         */\n        getLastShapeId: function () {\n            return this.lastShapeId;\n        },\n\n        /**\n         * Clear and reset the canvas\n         */\n        reset: function () {\n            alert('reset not implemented');\n        },\n\n        _insert: function (el, target) {\n            $(target).html(el);\n        },\n\n        /**\n         * Calculate the pixel dimensions of the canvas\n         */\n        _calculatePixelDims: function (width, height, canvas) {\n            // XXX This should probably be a configurable option\n            var match;\n            match = this._pxregex.exec(height);\n            if (match) {\n                this.pixelHeight = match[1];\n            } else {\n                this.pixelHeight = $(canvas).height();\n            }\n            match = this._pxregex.exec(width);\n            if (match) {\n                this.pixelWidth = match[1];\n            } else {\n                this.pixelWidth = $(canvas).width();\n            }\n        },\n\n        /**\n         * Generate a shape object and id for later rendering\n         */\n        _genShape: function (shapetype, shapeargs) {\n            var id = shapeCount++;\n            shapeargs.unshift(id);\n            return new VShape(this, id, shapetype, shapeargs);\n        },\n\n        /**\n         * Add a shape to the end of the render queue\n         */\n        appendShape: function (shape) {\n            alert('appendShape not implemented');\n        },\n\n        /**\n         * Replace one shape with another\n         */\n        replaceWithShape: function (shapeid, shape) {\n            alert('replaceWithShape not implemented');\n        },\n\n        /**\n         * Insert one shape after another in the render queue\n         */\n        insertAfterShape: function (shapeid, shape) {\n            alert('insertAfterShape not implemented');\n        },\n\n        /**\n         * Remove a shape from the queue\n         */\n        removeShapeId: function (shapeid) {\n            alert('removeShapeId not implemented');\n        },\n\n        /**\n         * Find a shape at the specified x/y co-ordinates\n         */\n        getShapeAt: function (el, x, y) {\n            alert('getShapeAt not implemented');\n        },\n\n        /**\n         * Render all queued shapes onto the canvas\n         */\n        render: function () {\n            alert('render not implemented');\n        }\n    });\n\n    VCanvas_canvas = createClass(VCanvas_base, {\n        init: function (width, height, target, interact) {\n            VCanvas_canvas._super.init.call(this, width, height, target);\n            this.canvas = document.createElement('canvas');\n            if (target[0]) {\n                target = target[0];\n            }\n            $.data(target, '_jqs_vcanvas', this);\n            $(this.canvas).css({ display: 'inline-block', width: width, height: height, verticalAlign: 'top' });\n            this._insert(this.canvas, target);\n            this._calculatePixelDims(width, height, this.canvas);\n            this.canvas.width = this.pixelWidth;\n            this.canvas.height = this.pixelHeight;\n            this.interact = interact;\n            this.shapes = {};\n            this.shapeseq = [];\n            this.currentTargetShapeId = undefined;\n            $(this.canvas).css({width: this.pixelWidth, height: this.pixelHeight});\n        },\n\n        _getContext: function (lineColor, fillColor, lineWidth) {\n            var context = this.canvas.getContext('2d');\n            if (lineColor !== undefined) {\n                context.strokeStyle = lineColor;\n            }\n            context.lineWidth = lineWidth === undefined ? 1 : lineWidth;\n            if (fillColor !== undefined) {\n                context.fillStyle = fillColor;\n            }\n            return context;\n        },\n\n        reset: function () {\n            var context = this._getContext();\n            context.clearRect(0, 0, this.pixelWidth, this.pixelHeight);\n            this.shapes = {};\n            this.shapeseq = [];\n            this.currentTargetShapeId = undefined;\n        },\n\n        _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) {\n            var context = this._getContext(lineColor, fillColor, lineWidth),\n                i, plen;\n            context.beginPath();\n            context.moveTo(path[0][0] + 0.5, path[0][1] + 0.5);\n            for (i = 1, plen = path.length; i < plen; i++) {\n                context.lineTo(path[i][0] + 0.5, path[i][1] + 0.5); // the 0.5 offset gives us crisp pixel-width lines\n            }\n            if (lineColor !== undefined) {\n                context.stroke();\n            }\n            if (fillColor !== undefined) {\n                context.fill();\n            }\n            if (this.targetX !== undefined && this.targetY !== undefined &&\n                context.isPointInPath(this.targetX, this.targetY)) {\n                this.currentTargetShapeId = shapeid;\n            }\n        },\n\n        _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) {\n            var context = this._getContext(lineColor, fillColor, lineWidth);\n            context.beginPath();\n            context.arc(x, y, radius, 0, 2 * Math.PI, false);\n            if (this.targetX !== undefined && this.targetY !== undefined &&\n                context.isPointInPath(this.targetX, this.targetY)) {\n                this.currentTargetShapeId = shapeid;\n            }\n            if (lineColor !== undefined) {\n                context.stroke();\n            }\n            if (fillColor !== undefined) {\n                context.fill();\n            }\n        },\n\n        _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {\n            var context = this._getContext(lineColor, fillColor);\n            context.beginPath();\n            context.moveTo(x, y);\n            context.arc(x, y, radius, startAngle, endAngle, false);\n            context.lineTo(x, y);\n            context.closePath();\n            if (lineColor !== undefined) {\n                context.stroke();\n            }\n            if (fillColor) {\n                context.fill();\n            }\n            if (this.targetX !== undefined && this.targetY !== undefined &&\n                context.isPointInPath(this.targetX, this.targetY)) {\n                this.currentTargetShapeId = shapeid;\n            }\n        },\n\n        _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) {\n            return this._drawShape(shapeid, [[x, y], [x + width, y], [x + width, y + height], [x, y + height], [x, y]], lineColor, fillColor);\n        },\n\n        appendShape: function (shape) {\n            this.shapes[shape.id] = shape;\n            this.shapeseq.push(shape.id);\n            this.lastShapeId = shape.id;\n            return shape.id;\n        },\n\n        replaceWithShape: function (shapeid, shape) {\n            var shapeseq = this.shapeseq,\n                i;\n            this.shapes[shape.id] = shape;\n            for (i = shapeseq.length; i--;) {\n                if (shapeseq[i] == shapeid) {\n                    shapeseq[i] = shape.id;\n                }\n            }\n            delete this.shapes[shapeid];\n        },\n\n        replaceWithShapes: function (shapeids, shapes) {\n            var shapeseq = this.shapeseq,\n                shapemap = {},\n                sid, i, first;\n\n            for (i = shapeids.length; i--;) {\n                shapemap[shapeids[i]] = true;\n            }\n            for (i = shapeseq.length; i--;) {\n                sid = shapeseq[i];\n                if (shapemap[sid]) {\n                    shapeseq.splice(i, 1);\n                    delete this.shapes[sid];\n                    first = i;\n                }\n            }\n            for (i = shapes.length; i--;) {\n                shapeseq.splice(first, 0, shapes[i].id);\n                this.shapes[shapes[i].id] = shapes[i];\n            }\n\n        },\n\n        insertAfterShape: function (shapeid, shape) {\n            var shapeseq = this.shapeseq,\n                i;\n            for (i = shapeseq.length; i--;) {\n                if (shapeseq[i] === shapeid) {\n                    shapeseq.splice(i + 1, 0, shape.id);\n                    this.shapes[shape.id] = shape;\n                    return;\n                }\n            }\n        },\n\n        removeShapeId: function (shapeid) {\n            var shapeseq = this.shapeseq,\n                i;\n            for (i = shapeseq.length; i--;) {\n                if (shapeseq[i] === shapeid) {\n                    shapeseq.splice(i, 1);\n                    break;\n                }\n            }\n            delete this.shapes[shapeid];\n        },\n\n        getShapeAt: function (el, x, y) {\n            this.targetX = x;\n            this.targetY = y;\n            this.render();\n            return this.currentTargetShapeId;\n        },\n\n        render: function () {\n            var shapeseq = this.shapeseq,\n                shapes = this.shapes,\n                shapeCount = shapeseq.length,\n                context = this._getContext(),\n                shapeid, shape, i;\n            context.clearRect(0, 0, this.pixelWidth, this.pixelHeight);\n            for (i = 0; i < shapeCount; i++) {\n                shapeid = shapeseq[i];\n                shape = shapes[shapeid];\n                this['_draw' + shape.type].apply(this, shape.args);\n            }\n            if (!this.interact) {\n                // not interactive so no need to keep the shapes array\n                this.shapes = {};\n                this.shapeseq = [];\n            }\n        }\n\n    });\n\n    VCanvas_vml = createClass(VCanvas_base, {\n        init: function (width, height, target) {\n            var groupel;\n            VCanvas_vml._super.init.call(this, width, height, target);\n            if (target[0]) {\n                target = target[0];\n            }\n            $.data(target, '_jqs_vcanvas', this);\n            this.canvas = document.createElement('span');\n            $(this.canvas).css({ display: 'inline-block', position: 'relative', overflow: 'hidden', width: width, height: height, margin: '0px', padding: '0px', verticalAlign: 'top'});\n            this._insert(this.canvas, target);\n            this._calculatePixelDims(width, height, this.canvas);\n            this.canvas.width = this.pixelWidth;\n            this.canvas.height = this.pixelHeight;\n            groupel = '<v:group coordorigin=\"0 0\" coordsize=\"' + this.pixelWidth + ' ' + this.pixelHeight + '\"' +\n                    ' style=\"position:absolute;top:0;left:0;width:' + this.pixelWidth + 'px;height=' + this.pixelHeight + 'px;\"></v:group>';\n            this.canvas.insertAdjacentHTML('beforeEnd', groupel);\n            this.group = $(this.canvas).children()[0];\n            this.rendered = false;\n            this.prerender = '';\n        },\n\n        _drawShape: function (shapeid, path, lineColor, fillColor, lineWidth) {\n            var vpath = [],\n                initial, stroke, fill, closed, vel, plen, i;\n            for (i = 0, plen = path.length; i < plen; i++) {\n                vpath[i] = '' + (path[i][0]) + ',' + (path[i][1]);\n            }\n            initial = vpath.splice(0, 1);\n            lineWidth = lineWidth === undefined ? 1 : lineWidth;\n            stroke = lineColor === undefined ? ' stroked=\"false\" ' : ' strokeWeight=\"' + lineWidth + 'px\" strokeColor=\"' + lineColor + '\" ';\n            fill = fillColor === undefined ? ' filled=\"false\"' : ' fillColor=\"' + fillColor + '\" filled=\"true\" ';\n            closed = vpath[0] === vpath[vpath.length - 1] ? 'x ' : '';\n            vel = '<v:shape coordorigin=\"0 0\" coordsize=\"' + this.pixelWidth + ' ' + this.pixelHeight + '\" ' +\n                 ' id=\"jqsshape' + shapeid + '\" ' +\n                 stroke +\n                 fill +\n                ' style=\"position:absolute;left:0px;top:0px;height:' + this.pixelHeight + 'px;width:' + this.pixelWidth + 'px;padding:0px;margin:0px;\" ' +\n                ' path=\"m ' + initial + ' l ' + vpath.join(', ') + ' ' + closed + 'e\">' +\n                ' </v:shape>';\n            return vel;\n        },\n\n        _drawCircle: function (shapeid, x, y, radius, lineColor, fillColor, lineWidth) {\n            var stroke, fill, vel;\n            x -= radius;\n            y -= radius;\n            stroke = lineColor === undefined ? ' stroked=\"false\" ' : ' strokeWeight=\"' + lineWidth + 'px\" strokeColor=\"' + lineColor + '\" ';\n            fill = fillColor === undefined ? ' filled=\"false\"' : ' fillColor=\"' + fillColor + '\" filled=\"true\" ';\n            vel = '<v:oval ' +\n                 ' id=\"jqsshape' + shapeid + '\" ' +\n                stroke +\n                fill +\n                ' style=\"position:absolute;top:' + y + 'px; left:' + x + 'px; width:' + (radius * 2) + 'px; height:' + (radius * 2) + 'px\"></v:oval>';\n            return vel;\n\n        },\n\n        _drawPieSlice: function (shapeid, x, y, radius, startAngle, endAngle, lineColor, fillColor) {\n            var vpath, startx, starty, endx, endy, stroke, fill, vel;\n            if (startAngle === endAngle) {\n                return '';  // VML seems to have problem when start angle equals end angle.\n            }\n            if ((endAngle - startAngle) === (2 * Math.PI)) {\n                startAngle = 0.0;  // VML seems to have a problem when drawing a full circle that doesn't start 0\n                endAngle = (2 * Math.PI);\n            }\n\n            startx = x + Math.round(Math.cos(startAngle) * radius);\n            starty = y + Math.round(Math.sin(startAngle) * radius);\n            endx = x + Math.round(Math.cos(endAngle) * radius);\n            endy = y + Math.round(Math.sin(endAngle) * radius);\n\n            if (startx === endx && starty === endy) {\n                if ((endAngle - startAngle) < Math.PI) {\n                    // Prevent very small slices from being mistaken as a whole pie\n                    return '';\n                }\n                // essentially going to be the entire circle, so ignore startAngle\n                startx = endx = x + radius;\n                starty = endy = y;\n            }\n\n            if (startx === endx && starty === endy && (endAngle - startAngle) < Math.PI) {\n                return '';\n            }\n\n            vpath = [x - radius, y - radius, x + radius, y + radius, startx, starty, endx, endy];\n            stroke = lineColor === undefined ? ' stroked=\"false\" ' : ' strokeWeight=\"1px\" strokeColor=\"' + lineColor + '\" ';\n            fill = fillColor === undefined ? ' filled=\"false\"' : ' fillColor=\"' + fillColor + '\" filled=\"true\" ';\n            vel = '<v:shape coordorigin=\"0 0\" coordsize=\"' + this.pixelWidth + ' ' + this.pixelHeight + '\" ' +\n                 ' id=\"jqsshape' + shapeid + '\" ' +\n                 stroke +\n                 fill +\n                ' style=\"position:absolute;left:0px;top:0px;height:' + this.pixelHeight + 'px;width:' + this.pixelWidth + 'px;padding:0px;margin:0px;\" ' +\n                ' path=\"m ' + x + ',' + y + ' wa ' + vpath.join(', ') + ' x e\">' +\n                ' </v:shape>';\n            return vel;\n        },\n\n        _drawRect: function (shapeid, x, y, width, height, lineColor, fillColor) {\n            return this._drawShape(shapeid, [[x, y], [x, y + height], [x + width, y + height], [x + width, y], [x, y]], lineColor, fillColor);\n        },\n\n        reset: function () {\n            this.group.innerHTML = '';\n        },\n\n        appendShape: function (shape) {\n            var vel = this['_draw' + shape.type].apply(this, shape.args);\n            if (this.rendered) {\n                this.group.insertAdjacentHTML('beforeEnd', vel);\n            } else {\n                this.prerender += vel;\n            }\n            this.lastShapeId = shape.id;\n            return shape.id;\n        },\n\n        replaceWithShape: function (shapeid, shape) {\n            var existing = $('#jqsshape' + shapeid),\n                vel = this['_draw' + shape.type].apply(this, shape.args);\n            existing[0].outerHTML = vel;\n        },\n\n        replaceWithShapes: function (shapeids, shapes) {\n            // replace the first shapeid with all the new shapes then toast the remaining old shapes\n            var existing = $('#jqsshape' + shapeids[0]),\n                replace = '',\n                slen = shapes.length,\n                i;\n            for (i = 0; i < slen; i++) {\n                replace += this['_draw' + shapes[i].type].apply(this, shapes[i].args);\n            }\n            existing[0].outerHTML = replace;\n            for (i = 1; i < shapeids.length; i++) {\n                $('#jqsshape' + shapeids[i]).remove();\n            }\n        },\n\n        insertAfterShape: function (shapeid, shape) {\n            var existing = $('#jqsshape' + shapeid),\n                 vel = this['_draw' + shape.type].apply(this, shape.args);\n            existing[0].insertAdjacentHTML('afterEnd', vel);\n        },\n\n        removeShapeId: function (shapeid) {\n            var existing = $('#jqsshape' + shapeid);\n            this.group.removeChild(existing[0]);\n        },\n\n        getShapeAt: function (el, x, y) {\n            var shapeid = el.id.substr(8);\n            return shapeid;\n        },\n\n        render: function () {\n            if (!this.rendered) {\n                // batch the intial render into a single repaint\n                this.group.innerHTML = this.prerender;\n                this.rendered = true;\n            }\n        }\n    });\n\n}))}(document, Math));\n"
  },
  {
    "path": "public/static/plugins/timepicker/bootstrap-timepicker.css",
    "content": "/*!\n * Timepicker Component for Twitter Bootstrap\n *\n * Copyright 2013 Joris de Wit\n *\n * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n.bootstrap-timepicker {\n  position: relative;\n}\n.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu {\n  left: auto;\n  right: 0;\n}\n.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:before {\n  left: auto;\n  right: 12px;\n}\n.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:after {\n  left: auto;\n  right: 13px;\n}\n.bootstrap-timepicker .add-on {\n  cursor: pointer;\n}\n.bootstrap-timepicker .add-on i {\n  display: inline-block;\n  width: 16px;\n  height: 16px;\n}\n.bootstrap-timepicker-widget.dropdown-menu {\n  padding: 2px 3px 2px 2px;\n}\n.bootstrap-timepicker-widget.dropdown-menu.open {\n  display: inline-block;\n}\n.bootstrap-timepicker-widget.dropdown-menu:before {\n  border-bottom: 7px solid rgba(0, 0, 0, 0.2);\n  border-left: 7px solid transparent;\n  border-right: 7px solid transparent;\n  content: \"\";\n  display: inline-block;\n  left: 9px;\n  position: absolute;\n  top: -7px;\n}\n.bootstrap-timepicker-widget.dropdown-menu:after {\n  border-bottom: 6px solid #FFFFFF;\n  border-left: 6px solid transparent;\n  border-right: 6px solid transparent;\n  content: \"\";\n  display: inline-block;\n  left: 10px;\n  position: absolute;\n  top: -6px;\n}\n.bootstrap-timepicker-widget a.btn,\n.bootstrap-timepicker-widget input {\n  border-radius: 4px;\n}\n.bootstrap-timepicker-widget table {\n  width: 100%;\n  margin: 0;\n}\n.bootstrap-timepicker-widget table td {\n  text-align: center;\n  height: 30px;\n  margin: 0;\n  padding: 2px;\n}\n.bootstrap-timepicker-widget table td:not(.separator) {\n  min-width: 30px;\n}\n.bootstrap-timepicker-widget table td span {\n  width: 100%;\n}\n.bootstrap-timepicker-widget table td a {\n  border: 1px transparent solid;\n  width: 100%;\n  display: inline-block;\n  margin: 0;\n  padding: 8px 0;\n  outline: 0;\n  color: #333;\n}\n.bootstrap-timepicker-widget table td a:hover {\n  text-decoration: none;\n  background-color: #eee;\n  -webkit-border-radius: 4px;\n  -moz-border-radius: 4px;\n  border-radius: 4px;\n  border-color: #ddd;\n}\n.bootstrap-timepicker-widget table td a i {\n  margin-top: 2px;\n}\n.bootstrap-timepicker-widget table td input {\n  width: 25px;\n  margin: 0;\n  text-align: center;\n}\n.bootstrap-timepicker-widget .modal-content {\n  padding: 4px;\n}\n@media (min-width: 767px) {\n  .bootstrap-timepicker-widget.modal {\n    width: 200px;\n    margin-left: -100px;\n  }\n}\n@media (max-width: 767px) {\n  .bootstrap-timepicker {\n    width: 100%;\n  }\n  .bootstrap-timepicker .dropdown-menu {\n    width: 100%;\n  }\n}\n"
  },
  {
    "path": "public/static/plugins/timepicker/bootstrap-timepicker.js",
    "content": "//TODO: move arrow styles and button click code into configurable items, with defaults matching the existing code\n\n/*!\n* Timepicker Component for Twitter Bootstrap\n*\n* Copyright 2013 Joris de Wit\n*\n* Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors\n*\n* For the full copyright and license information, please view the LICENSE\n* file that was distributed with this source code.\n*/\n(function($, window, document, undefined) {\n  'use strict';\n\n  // TIMEPICKER PUBLIC CLASS DEFINITION\n  var Timepicker = function(element, options) {\n    this.widget = '';\n    this.$element = $(element);\n    this.defaultTime = options.defaultTime;\n    this.disableFocus = options.disableFocus;\n    this.isOpen = options.isOpen;\n    this.minuteStep = options.minuteStep;\n    this.modalBackdrop = options.modalBackdrop;\n    this.secondStep = options.secondStep;\n    this.showInputs = options.showInputs;\n    this.showMeridian = options.showMeridian;\n    this.showSeconds = options.showSeconds;\n    this.template = options.template;\n    this.appendWidgetTo = options.appendWidgetTo;\n\tthis.upArrowStyle = options.upArrowStyle;\n\tthis.downArrowStyle = options.downArrowStyle;\n\tthis.containerClass = options.containerClass;\n\n    this._init();\n  };\n\n  Timepicker.prototype = {\n\n    constructor: Timepicker,\n\n    _init: function() {\n      var self = this;\n\n      if (this.$element.parent().hasClass('input-append') || this.$element.parent().hasClass('input-prepend')) {\n\t\tif (this.$element.parent('.input-append, .input-prepend').find('.add-on').length) {\n\t\t\tthis.$element.parent('.input-append, .input-prepend').find('.add-on').on({\n\t\t\t  'click.timepicker': $.proxy(this.showWidget, this)\n\t\t\t});\t\t\n\t\t} else {\n\t\t\tthis.$element.closest(this.containerClass).find('.add-on').on({\n\t\t\t  'click.timepicker': $.proxy(this.showWidget, this)\n\t\t\t});\t\t\n\t\t}\n\t\t\n        this.$element.on({\n          'focus.timepicker': $.proxy(this.highlightUnit, this),\n          'click.timepicker': $.proxy(this.highlightUnit, this),\n          'keydown.timepicker': $.proxy(this.elementKeydown, this),\n          'blur.timepicker': $.proxy(this.blurElement, this)\n        });\n      } else {\n        if (this.template) {\n          this.$element.on({\n            'focus.timepicker': $.proxy(this.showWidget, this),\n            'click.timepicker': $.proxy(this.showWidget, this),\n            'blur.timepicker': $.proxy(this.blurElement, this)\n          });\n        } else {\n          this.$element.on({\n            'focus.timepicker': $.proxy(this.highlightUnit, this),\n            'click.timepicker': $.proxy(this.highlightUnit, this),\n            'keydown.timepicker': $.proxy(this.elementKeydown, this),\n            'blur.timepicker': $.proxy(this.blurElement, this)\n          });\n        }\n      }\n\n      if (this.template !== false) {\n        this.$widget = $(this.getTemplate()).prependTo(this.$element.parents(this.appendWidgetTo)).on('click', $.proxy(this.widgetClick, this));\n      } else {\n        this.$widget = false;\n      }\n\n      if (this.showInputs && this.$widget !== false) {\n        this.$widget.find('input').each(function() {\n          $(this).on({\n            'click.timepicker': function() { $(this).select(); },\n            'keydown.timepicker': $.proxy(self.widgetKeydown, self)\n          });\n        });\n      }\n\n      this.setDefaultTime(this.defaultTime);\n    },\n\n    blurElement: function() {\n      this.highlightedUnit = undefined;\n      this.updateFromElementVal();\n    },\n\n    decrementHour: function() {\n      if (this.showMeridian) {\n        if (this.hour === 1) {\n          this.hour = 12;\n        } else if (this.hour === 12) {\n          this.hour--;\n\n          return this.toggleMeridian();\n        } else if (this.hour === 0) {\n          this.hour = 11;\n\n          return this.toggleMeridian();\n        } else {\n          this.hour--;\n        }\n      } else {\n        if (this.hour === 0) {\n          this.hour = 23;\n        } else {\n          this.hour--;\n        }\n      }\n      this.update();\n    },\n\n    decrementMinute: function(step) {\n      var newVal;\n\n      if (step) {\n        newVal = this.minute - step;\n      } else {\n        newVal = this.minute - this.minuteStep;\n      }\n\n      if (newVal < 0) {\n        this.decrementHour();\n        this.minute = newVal + 60;\n      } else {\n        this.minute = newVal;\n      }\n      this.update();\n    },\n\n    decrementSecond: function() {\n      var newVal = this.second - this.secondStep;\n\n      if (newVal < 0) {\n        this.decrementMinute(true);\n        this.second = newVal + 60;\n      } else {\n        this.second = newVal;\n      }\n      this.update();\n    },\n\n    elementKeydown: function(e) {\n      switch (e.keyCode) {\n      case 9: //tab\n        this.updateFromElementVal();\n\n        switch (this.highlightedUnit) {\n        case 'hour':\n          e.preventDefault();\n          this.highlightNextUnit();\n          break;\n        case 'minute':\n          if (this.showMeridian || this.showSeconds) {\n            e.preventDefault();\n            this.highlightNextUnit();\n          }\n          break;\n        case 'second':\n          if (this.showMeridian) {\n            e.preventDefault();\n            this.highlightNextUnit();\n          }\n          break;\n        }\n        break;\n      case 27: // escape\n        this.updateFromElementVal();\n        break;\n      case 37: // left arrow\n        e.preventDefault();\n        this.highlightPrevUnit();\n        this.updateFromElementVal();\n        break;\n      case 38: // up arrow\n        e.preventDefault();\n        switch (this.highlightedUnit) {\n        case 'hour':\n          this.incrementHour();\n          this.highlightHour();\n          break;\n        case 'minute':\n          this.incrementMinute();\n          this.highlightMinute();\n          break;\n        case 'second':\n          this.incrementSecond();\n          this.highlightSecond();\n          break;\n        case 'meridian':\n          this.toggleMeridian();\n          this.highlightMeridian();\n          break;\n        }\n        break;\n      case 39: // right arrow\n        e.preventDefault();\n        this.updateFromElementVal();\n        this.highlightNextUnit();\n        break;\n      case 40: // down arrow\n        e.preventDefault();\n        switch (this.highlightedUnit) {\n        case 'hour':\n          this.decrementHour();\n          this.highlightHour();\n          break;\n        case 'minute':\n          this.decrementMinute();\n          this.highlightMinute();\n          break;\n        case 'second':\n          this.decrementSecond();\n          this.highlightSecond();\n          break;\n        case 'meridian':\n          this.toggleMeridian();\n          this.highlightMeridian();\n          break;\n        }\n        break;\n      }\n    },\n\n    formatTime: function(hour, minute, second, meridian) {\n      hour = hour < 10 ? '0' + hour : hour;\n      minute = minute < 10 ? '0' + minute : minute;\n      second = second < 10 ? '0' + second : second;\n\n      return hour + ':' + minute + (this.showSeconds ? ':' + second : '') + (this.showMeridian ? ' ' + meridian : '');\n    },\n\n    getCursorPosition: function() {\n      var input = this.$element.get(0);\n\n      if ('selectionStart' in input) {// Standard-compliant browsers\n\n        return input.selectionStart;\n      } else if (document.selection) {// IE fix\n        input.focus();\n        var sel = document.selection.createRange(),\n          selLen = document.selection.createRange().text.length;\n\n        sel.moveStart('character', - input.value.length);\n\n        return sel.text.length - selLen;\n      }\n    },\n\n    getTemplate: function() {\n      var template,\n        hourTemplate,\n        minuteTemplate,\n        secondTemplate,\n        meridianTemplate,\n        templateContent;\n\n      if (this.showInputs) {\n        hourTemplate = '<input type=\"text\" name=\"hour\" class=\"bootstrap-timepicker-hour form-control\" maxlength=\"2\"/>';\n        minuteTemplate = '<input type=\"text\" name=\"minute\" class=\"bootstrap-timepicker-minute form-control\" maxlength=\"2\"/>';\n        secondTemplate = '<input type=\"text\" name=\"second\" class=\"bootstrap-timepicker-second form-control\" maxlength=\"2\"/>';\n        meridianTemplate = '<input type=\"text\" name=\"meridian\" class=\"bootstrap-timepicker-meridian form-control\" maxlength=\"2\"/>';\n      } else {\n        hourTemplate = '<span class=\"bootstrap-timepicker-hour\"></span>';\n        minuteTemplate = '<span class=\"bootstrap-timepicker-minute\"></span>';\n        secondTemplate = '<span class=\"bootstrap-timepicker-second\"></span>';\n        meridianTemplate = '<span class=\"bootstrap-timepicker-meridian\"></span>';\n      }\n\n      templateContent = '<table>'+\n         '<tr>'+\n           '<td><a href=\"#\" data-action=\"incrementHour\"><i class=\"' + this.upArrowStyle + '\"></i></a></td>'+\n           '<td class=\"separator\">&nbsp;</td>'+\n           '<td><a href=\"#\" data-action=\"incrementMinute\"><i class=\"' + this.upArrowStyle + '\"></i></a></td>'+\n           (this.showSeconds ?\n             '<td class=\"separator\">&nbsp;</td>'+\n             '<td><a href=\"#\" data-action=\"incrementSecond\"><i class=\"' + this.upArrowStyle + '\"></i></a></td>'\n           : '') +\n           (this.showMeridian ?\n             '<td class=\"separator\">&nbsp;</td>'+\n             '<td class=\"meridian-column\"><a href=\"#\" data-action=\"toggleMeridian\"><i class=\"' + this.upArrowStyle + '\"></i></a></td>'\n           : '') +\n         '</tr>'+\n         '<tr>'+\n           '<td>'+ hourTemplate +'</td> '+\n           '<td class=\"separator\">:</td>'+\n           '<td>'+ minuteTemplate +'</td> '+\n           (this.showSeconds ?\n            '<td class=\"separator\">:</td>'+\n            '<td>'+ secondTemplate +'</td>'\n           : '') +\n           (this.showMeridian ?\n            '<td class=\"separator\">&nbsp;</td>'+\n            '<td>'+ meridianTemplate +'</td>'\n           : '') +\n         '</tr>'+\n         '<tr>'+\n           '<td><a href=\"#\" data-action=\"decrementHour\"><i class=\"' + this.downArrowStyle + '\"></i></a></td>'+\n           '<td class=\"separator\"></td>'+\n           '<td><a href=\"#\" data-action=\"decrementMinute\"><i class=\"' + this.downArrowStyle + '\"></i></a></td>'+\n           (this.showSeconds ?\n            '<td class=\"separator\">&nbsp;</td>'+\n            '<td><a href=\"#\" data-action=\"decrementSecond\"><i class=\"' + this.downArrowStyle + '\"></i></a></td>'\n           : '') +\n           (this.showMeridian ?\n            '<td class=\"separator\">&nbsp;</td>'+\n            '<td><a href=\"#\" data-action=\"toggleMeridian\"><i class=\"' + this.downArrowStyle + '\"></i></a></td>'\n           : '') +\n         '</tr>'+\n       '</table>';\n\n      switch(this.template) {\n      case 'modal':\n        template = '<div class=\"bootstrap-timepicker-widget modal hide fade in\" data-backdrop=\"'+ (this.modalBackdrop ? 'true' : 'false') +'\">'+\n          '<div class=\"modal-header\">'+\n            '<a href=\"#\" class=\"close\" data-dismiss=\"modal\">×</a>'+\n            '<h3>Pick a Time</h3>'+\n          '</div>'+\n          '<div class=\"modal-content\">'+\n            templateContent +\n          '</div>'+\n          '<div class=\"modal-footer\">'+\n            '<a href=\"#\" class=\"btn btn-primary\" data-dismiss=\"modal\">OK</a>'+\n          '</div>'+\n        '</div>';\n        break;\n      case 'dropdown':\n        template = '<div class=\"bootstrap-timepicker-widget dropdown-menu\">'+ templateContent +'</div>';\n        break;\n      }\n\n      return template;\n    },\n\n    getTime: function() {\n      return this.formatTime(this.hour, this.minute, this.second, this.meridian);\n    },\n\n    hideWidget: function() {\n      if (this.isOpen === false) {\n        return;\n      }\n\n                        if (this.showInputs) {\n                                this.updateFromWidgetInputs();\n                        }\n\n      this.$element.trigger({\n        'type': 'hide.timepicker',\n        'time': {\n          'value': this.getTime(),\n          'hours': this.hour,\n          'minutes': this.minute,\n          'seconds': this.second,\n          'meridian': this.meridian\n        }\n      });\n\n      if (this.template === 'modal' && this.$widget.modal) {\n        this.$widget.modal('hide');\n      } else {\n        this.$widget.removeClass('open');\n      }\n\n      $(document).off('mousedown.timepicker');\n\n      this.isOpen = false;\n    },\n\n    highlightUnit: function() {\n      this.position = this.getCursorPosition();\n      if (this.position >= 0 && this.position <= 2) {\n        this.highlightHour();\n      } else if (this.position >= 3 && this.position <= 5) {\n        this.highlightMinute();\n      } else if (this.position >= 6 && this.position <= 8) {\n        if (this.showSeconds) {\n          this.highlightSecond();\n        } else {\n          this.highlightMeridian();\n        }\n      } else if (this.position >= 9 && this.position <= 11) {\n        this.highlightMeridian();\n      }\n    },\n\n    highlightNextUnit: function() {\n      switch (this.highlightedUnit) {\n      case 'hour':\n        this.highlightMinute();\n        break;\n      case 'minute':\n        if (this.showSeconds) {\n          this.highlightSecond();\n        } else if (this.showMeridian){\n          this.highlightMeridian();\n        } else {\n          this.highlightHour();\n        }\n        break;\n      case 'second':\n        if (this.showMeridian) {\n          this.highlightMeridian();\n        } else {\n          this.highlightHour();\n        }\n        break;\n      case 'meridian':\n        this.highlightHour();\n        break;\n      }\n    },\n\n    highlightPrevUnit: function() {\n      switch (this.highlightedUnit) {\n      case 'hour':\n        this.highlightMeridian();\n        break;\n      case 'minute':\n        this.highlightHour();\n        break;\n      case 'second':\n        this.highlightMinute();\n        break;\n      case 'meridian':\n        if (this.showSeconds) {\n          this.highlightSecond();\n        } else {\n          this.highlightMinute();\n        }\n        break;\n      }\n    },\n\n    highlightHour: function() {\n      var $element = this.$element.get(0);\n\n      this.highlightedUnit = 'hour';\n\n                        if ($element.setSelectionRange) {\n                                setTimeout(function() {\n                                        $element.setSelectionRange(0,2);\n                                }, 0);\n                        }\n    },\n\n    highlightMinute: function() {\n      var $element = this.$element.get(0);\n\n      this.highlightedUnit = 'minute';\n\n                        if ($element.setSelectionRange) {\n                                setTimeout(function() {\n                                        $element.setSelectionRange(3,5);\n                                }, 0);\n                        }\n    },\n\n    highlightSecond: function() {\n      var $element = this.$element.get(0);\n\n      this.highlightedUnit = 'second';\n\n                        if ($element.setSelectionRange) {\n                                setTimeout(function() {\n                                        $element.setSelectionRange(6,8);\n                                }, 0);\n                        }\n    },\n\n    highlightMeridian: function() {\n      var $element = this.$element.get(0);\n\n      this.highlightedUnit = 'meridian';\n\n                        if ($element.setSelectionRange) {\n                                if (this.showSeconds) {\n                                        setTimeout(function() {\n                                                $element.setSelectionRange(9,11);\n                                        }, 0);\n                                } else {\n                                        setTimeout(function() {\n                                                $element.setSelectionRange(6,8);\n                                        }, 0);\n                                }\n                        }\n    },\n\n    incrementHour: function() {\n      if (this.showMeridian) {\n        if (this.hour === 11) {\n          this.hour++;\n          return this.toggleMeridian();\n        } else if (this.hour === 12) {\n          this.hour = 0;\n        }\n      }\n      if (this.hour === 23) {\n        this.hour = 0;\n\n        return;\n      }\n      this.hour++;\n      this.update();\n    },\n\n    incrementMinute: function(step) {\n      var newVal;\n\n      if (step) {\n        newVal = this.minute + step;\n      } else {\n        newVal = this.minute + this.minuteStep - (this.minute % this.minuteStep);\n      }\n\n      if (newVal > 59) {\n        this.incrementHour();\n        this.minute = newVal - 60;\n      } else {\n        this.minute = newVal;\n      }\n      this.update();\n    },\n\n    incrementSecond: function() {\n      var newVal = this.second + this.secondStep - (this.second % this.secondStep);\n\n      if (newVal > 59) {\n        this.incrementMinute(true);\n        this.second = newVal - 60;\n      } else {\n        this.second = newVal;\n      }\n      this.update();\n    },\n\n    remove: function() {\n      $('document').off('.timepicker');\n      if (this.$widget) {\n        this.$widget.remove();\n      }\n      delete this.$element.data().timepicker;\n    },\n\n    setDefaultTime: function(defaultTime){\n      if (!this.$element.val()) {\n        if (defaultTime === 'current') {\n          var dTime = new Date(),\n            hours = dTime.getHours(),\n            minutes = Math.floor(dTime.getMinutes() / this.minuteStep) * this.minuteStep,\n            seconds = Math.floor(dTime.getSeconds() / this.secondStep) * this.secondStep,\n            meridian = 'AM';\n\n          if (this.showMeridian) {\n            if (hours === 0) {\n              hours = 12;\n            } else if (hours >= 12) {\n              if (hours > 12) {\n                hours = hours - 12;\n              }\n              meridian = 'PM';\n            } else {\n              meridian = 'AM';\n            }\n          }\n\n          this.hour = hours;\n          this.minute = minutes;\n          this.second = seconds;\n          this.meridian = meridian;\n\n          this.update();\n\n        } else if (defaultTime === false) {\n          this.hour = 0;\n          this.minute = 0;\n          this.second = 0;\n          this.meridian = 'AM';\n        } else {\n          this.setTime(defaultTime);\n        }\n      } else {\n        this.updateFromElementVal();\n      }\n    },\n\n    setTime: function(time) {\n      var arr,\n        timeArray;\n\n      if (this.showMeridian) {\n        arr = time.split(' ');\n        timeArray = arr[0].split(':');\n        this.meridian = arr[1];\n      } else {\n        timeArray = time.split(':');\n      }\n\n      this.hour = parseInt(timeArray[0], 10);\n      this.minute = parseInt(timeArray[1], 10);\n      this.second = parseInt(timeArray[2], 10);\n\n      if (isNaN(this.hour)) {\n        this.hour = 0;\n      }\n      if (isNaN(this.minute)) {\n        this.minute = 0;\n      }\n\n      if (this.showMeridian) {\n        if (this.hour > 12) {\n          this.hour = 12;\n        } else if (this.hour < 1) {\n          this.hour = 12;\n        }\n\n        if (this.meridian === 'am' || this.meridian === 'a') {\n          this.meridian = 'AM';\n        } else if (this.meridian === 'pm' || this.meridian === 'p') {\n          this.meridian = 'PM';\n        }\n\n        if (this.meridian !== 'AM' && this.meridian !== 'PM') {\n          this.meridian = 'AM';\n        }\n      } else {\n        if (this.hour >= 24) {\n          this.hour = 23;\n        } else if (this.hour < 0) {\n          this.hour = 0;\n        }\n      }\n\n      if (this.minute < 0) {\n        this.minute = 0;\n      } else if (this.minute >= 60) {\n        this.minute = 59;\n      }\n\n      if (this.showSeconds) {\n        if (isNaN(this.second)) {\n          this.second = 0;\n        } else if (this.second < 0) {\n          this.second = 0;\n        } else if (this.second >= 60) {\n          this.second = 59;\n        }\n      }\n\n      this.update();\n    },\n\n    showWidget: function() {\n      if (this.isOpen) {\n        return;\n      }\n\n      if (this.$element.is(':disabled')) {\n        return;\n      }\n\n      var self = this;\n      $(document).on('mousedown.timepicker', function (e) {\n        // Clicked outside the timepicker, hide it\n        if ($(e.target).closest('.bootstrap-timepicker-widget').length === 0) {\n          self.hideWidget();\n        }\n      });\n\n      this.$element.trigger({\n        'type': 'show.timepicker',\n        'time': {\n          'value': this.getTime(),\n          'hours': this.hour,\n          'minutes': this.minute,\n          'seconds': this.second,\n          'meridian': this.meridian\n        }\n      });\n\n      if (this.disableFocus) {\n        this.$element.blur();\n      }\n\n      this.updateFromElementVal();\n\n      if (this.template === 'modal' && this.$widget.modal) {\n        this.$widget.modal('show').on('hidden', $.proxy(this.hideWidget, this));\n      } else {\n        if (this.isOpen === false) {\n          this.$widget.addClass('open');\n        }\n      }\n\n      this.isOpen = true;\n    },\n\n    toggleMeridian: function() {\n      this.meridian = this.meridian === 'AM' ? 'PM' : 'AM';\n      this.update();\n    },\n\n    update: function() {\n      this.$element.trigger({\n        'type': 'changeTime.timepicker',\n        'time': {\n          'value': this.getTime(),\n          'hours': this.hour,\n          'minutes': this.minute,\n          'seconds': this.second,\n          'meridian': this.meridian\n        }\n      });\n\n      this.updateElement();\n      this.updateWidget();\n    },\n\n    updateElement: function() {\n      this.$element.val(this.getTime()).change();\n    },\n\n    updateFromElementVal: function() {\n                        var val = this.$element.val();\n\n                        if (val) {\n                                this.setTime(val);\n                        }\n    },\n\n    updateWidget: function() {\n      if (this.$widget === false) {\n        return;\n      }\n\n      var hour = this.hour < 10 ? '0' + this.hour : this.hour,\n          minute = this.minute < 10 ? '0' + this.minute : this.minute,\n          second = this.second < 10 ? '0' + this.second : this.second;\n\n      if (this.showInputs) {\n        this.$widget.find('input.bootstrap-timepicker-hour').val(hour);\n        this.$widget.find('input.bootstrap-timepicker-minute').val(minute);\n\n        if (this.showSeconds) {\n          this.$widget.find('input.bootstrap-timepicker-second').val(second);\n        }\n        if (this.showMeridian) {\n          this.$widget.find('input.bootstrap-timepicker-meridian').val(this.meridian);\n        }\n      } else {\n        this.$widget.find('span.bootstrap-timepicker-hour').text(hour);\n        this.$widget.find('span.bootstrap-timepicker-minute').text(minute);\n\n        if (this.showSeconds) {\n          this.$widget.find('span.bootstrap-timepicker-second').text(second);\n        }\n        if (this.showMeridian) {\n          this.$widget.find('span.bootstrap-timepicker-meridian').text(this.meridian);\n        }\n      }\n    },\n\n    updateFromWidgetInputs: function() {\n      if (this.$widget === false) {\n        return;\n      }\n      var time = $('input.bootstrap-timepicker-hour', this.$widget).val() + ':' +\n        $('input.bootstrap-timepicker-minute', this.$widget).val() +\n        (this.showSeconds ? ':' + $('input.bootstrap-timepicker-second', this.$widget).val() : '') +\n        (this.showMeridian ? ' ' + $('input.bootstrap-timepicker-meridian', this.$widget).val() : '');\n\n      this.setTime(time);\n    },\n\n    widgetClick: function(e) {\n      e.stopPropagation();\n      e.preventDefault();\n\n      var action = $(e.target).closest('a').data('action');\n      if (action) {\n        this[action]();\n      }\n    },\n\n    widgetKeydown: function(e) {\n      var $input = $(e.target).closest('input'),\n          name = $input.attr('name');\n\n      switch (e.keyCode) {\n      case 9: //tab\n        if (this.showMeridian) {\n          if (name === 'meridian') {\n            return this.hideWidget();\n          }\n        } else {\n          if (this.showSeconds) {\n            if (name === 'second') {\n              return this.hideWidget();\n            }\n          } else {\n            if (name === 'minute') {\n              return this.hideWidget();\n            }\n          }\n        }\n\n        this.updateFromWidgetInputs();\n        break;\n      case 27: // escape\n        this.hideWidget();\n        break;\n      case 38: // up arrow\n        e.preventDefault();\n        switch (name) {\n        case 'hour':\n          this.incrementHour();\n          break;\n        case 'minute':\n          this.incrementMinute();\n          break;\n        case 'second':\n          this.incrementSecond();\n          break;\n        case 'meridian':\n          this.toggleMeridian();\n          break;\n        }\n        break;\n      case 40: // down arrow\n        e.preventDefault();\n        switch (name) {\n        case 'hour':\n          this.decrementHour();\n          break;\n        case 'minute':\n          this.decrementMinute();\n          break;\n        case 'second':\n          this.decrementSecond();\n          break;\n        case 'meridian':\n          this.toggleMeridian();\n          break;\n        }\n        break;\n      }\n    }\n  };\n\n\n  //TIMEPICKER PLUGIN DEFINITION\n  $.fn.timepicker = function(option) {\n    var args = Array.apply(null, arguments);\n    args.shift();\n    return this.each(function() {\n      var $this = $(this),\n        data = $this.data('timepicker'),\n        options = typeof option === 'object' && option;\n\n      if (!data) {\n        $this.data('timepicker', (data = new Timepicker(this, $.extend({}, $.fn.timepicker.defaults, options, $(this).data()))));\n      }\n\n      if (typeof option === 'string') {\n        data[option].apply(data, args);\n      }\n    });\n  };\n\n  $.fn.timepicker.defaults = {\n    defaultTime: 'current',\n    disableFocus: false,\n    isOpen: false,\n    minuteStep: 15,\n    modalBackdrop: false,\n    secondStep: 15,\n    showSeconds: false,\n    showInputs: true,\n    showMeridian: true,\n    template: 'dropdown',\n    appendWidgetTo: '.bootstrap-timepicker',\n\tupArrowStyle: 'glyphicon glyphicon-chevron-up',\n\tdownArrowStyle: 'glyphicon glyphicon-chevron-down',\n\tcontainerClass: 'bootstrap-timepicker'\n  };\n\n  $.fn.timepicker.Constructor = Timepicker;\n\n})(jQuery, window, document);\n"
  },
  {
    "path": "public/static/plugins/toastr/toastr.css",
    "content": ".toast-title {\n  font-weight: bold;\n}\n.toast-message {\n  -ms-word-wrap: break-word;\n  word-wrap: break-word;\n}\n.toast-message a,\n.toast-message label {\n  color: #ffffff;\n}\n.toast-message a:hover {\n  color: #cccccc;\n  text-decoration: none;\n}\n.toast-close-button {\n  position: relative;\n  right: -0.3em;\n  top: -0.3em;\n  float: right;\n  font-size: 20px;\n  font-weight: bold;\n  color: #ffffff;\n  -webkit-text-shadow: 0 1px 0 #ffffff;\n  text-shadow: 0 1px 0 #ffffff;\n  opacity: 0.8;\n  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);\n  filter: alpha(opacity=80);\n}\n.toast-close-button:hover,\n.toast-close-button:focus {\n  color: #000000;\n  text-decoration: none;\n  cursor: pointer;\n  opacity: 0.4;\n  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);\n  filter: alpha(opacity=40);\n}\n/*Additional properties for button version\n iOS requires the button element instead of an anchor tag.\n If you want the anchor version, it requires `href=\"#\"`.*/\nbutton.toast-close-button {\n  padding: 0;\n  cursor: pointer;\n  background: transparent;\n  border: 0;\n  -webkit-appearance: none;\n}\n.toast-top-center {\n  top: 0;\n  right: 0;\n  width: 100%;\n}\n.toast-bottom-center {\n  bottom: 0;\n  right: 0;\n  width: 100%;\n}\n.toast-top-full-width {\n  top: 0;\n  right: 0;\n  width: 100%;\n}\n.toast-bottom-full-width {\n  bottom: 0;\n  right: 0;\n  width: 100%;\n}\n.toast-top-left {\n  top: 12px;\n  left: 12px;\n}\n.toast-top-right {\n  top: 12px;\n  right: 12px;\n}\n.toast-bottom-right {\n  right: 12px;\n  bottom: 12px;\n}\n.toast-bottom-left {\n  bottom: 12px;\n  left: 12px;\n}\n#toast-container {\n  position: fixed;\n  z-index: 999999;\n  pointer-events: none;\n  /*overrides*/\n}\n#toast-container * {\n  -moz-box-sizing: border-box;\n  -webkit-box-sizing: border-box;\n  box-sizing: border-box;\n}\n#toast-container > div {\n  position: relative;\n  pointer-events: auto;\n  overflow: hidden;\n  margin: 0 0 6px;\n  padding: 15px 15px 15px 50px;\n  width: 300px;\n  -moz-border-radius: 3px 3px 3px 3px;\n  -webkit-border-radius: 3px 3px 3px 3px;\n  border-radius: 3px 3px 3px 3px;\n  background-position: 15px center;\n  background-repeat: no-repeat;\n  -moz-box-shadow: 0 0 12px #999999;\n  -webkit-box-shadow: 0 0 12px #999999;\n  box-shadow: 0 0 12px #999999;\n  color: #ffffff;\n  opacity: 0.8;\n  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=80);\n  filter: alpha(opacity=80);\n}\n#toast-container > :hover {\n  -moz-box-shadow: 0 0 12px #000000;\n  -webkit-box-shadow: 0 0 12px #000000;\n  box-shadow: 0 0 12px #000000;\n  opacity: 1;\n  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=100);\n  filter: alpha(opacity=100);\n  cursor: pointer;\n}\n#toast-container > .toast-info {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=\") !important;\n}\n#toast-container > .toast-error {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=\") !important;\n}\n#toast-container > .toast-success {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==\") !important;\n}\n#toast-container > .toast-warning {\n  background-image: url(\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=\") !important;\n}\n#toast-container.toast-top-center > div,\n#toast-container.toast-bottom-center > div {\n  width: 300px;\n  margin-left: auto;\n  margin-right: auto;\n}\n#toast-container.toast-top-full-width > div,\n#toast-container.toast-bottom-full-width > div {\n  width: 96%;\n  margin-left: auto;\n  margin-right: auto;\n}\n.toast {\n  background-color: #030303;\n}\n.toast-success {\n  background-color: #51a351;\n}\n.toast-error {\n  background-color: #bd362f;\n}\n.toast-info {\n  background-color: #2f96b4;\n}\n.toast-warning {\n  background-color: #f89406;\n}\n.toast-progress {\n  position: absolute;\n  left: 0;\n  bottom: 0;\n  height: 4px;\n  background-color: #000000;\n  opacity: 0.4;\n  -ms-filter: progid:DXImageTransform.Microsoft.Alpha(Opacity=40);\n  filter: alpha(opacity=40);\n}\n/*Responsive Design*/\n@media all and (max-width: 240px) {\n  #toast-container > div {\n    padding: 8px 8px 8px 50px;\n    width: 11em;\n  }\n  #toast-container .toast-close-button {\n    right: -0.2em;\n    top: -0.2em;\n  }\n}\n@media all and (min-width: 241px) and (max-width: 480px) {\n  #toast-container > div {\n    padding: 8px 8px 8px 50px;\n    width: 18em;\n  }\n  #toast-container .toast-close-button {\n    right: -0.2em;\n    top: -0.2em;\n  }\n}\n@media all and (min-width: 481px) and (max-width: 768px) {\n  #toast-container > div {\n    padding: 15px 15px 15px 50px;\n    width: 25em;\n  }\n}\n"
  },
  {
    "path": "public/static/plugins/wangeditor/css/wangEditor.css",
    "content": "/* 编辑器边框颜色 */\n/* 菜单颜色、上边框颜色 */\n/* 菜单选中状态的颜色 */\n/* input focus 时的颜色 */\n/* 按钮颜色 */\n/* tab selected 状态下的颜色 */\n.wangEditor-container {\n  position: relative;\n  background-color: #fff;\n  border: 1px solid #ccc;\n  z-index: 1;\n  width: 100%;\n}\n.wangEditor-container a:focus,\n.wangEditor-container button:focus {\n  outline: none;\n}\n.wangEditor-container,\n.wangEditor-container * {\n  margin: 0;\n  padding: 0;\n  box-sizing: border-box;\n  line-height: 1;\n}\n.wangEditor-container img {\n  border: none;\n}\n.wangEditor-container .clearfix:after {\n  content: '';\n  display: table;\n  clear: both;\n}\n.wangEditor-container .clearfix {\n  *zoom: 1;\n}\n.wangEditor-container textarea {\n  border: none;\n}\n.wangEditor-container textarea:focus {\n  outline: none;\n}\n.wangEditor-container .height-tip {\n  position: absolute;\n  width: 3px;\n  background-color: #ccc;\n  left: 0;\n  transition: top .2s;\n}\n.wangEditor-container .txt-toolbar {\n  position: absolute;\n  background-color: #fff;\n  padding: 3px 5px;\n  border-top: 2px solid #666;\n  box-shadow: 1px 3px 3px #999;\n  border-left: 1px\\9 solid\\9 #ccc\\9;\n  border-bottom: 1px\\9 solid\\9 #999\\9;\n  border-right: 1px\\9 solid\\9 #999\\9;\n}\n.wangEditor-container .txt-toolbar .tip-triangle {\n  display: block;\n  position: absolute;\n  width: 0;\n  height: 0;\n  border: 5px solid;\n  border-color: transparent transparent #666 transparent;\n  top: -12px;\n  left: 50%;\n  margin-left: -5px;\n}\n.wangEditor-container .txt-toolbar a {\n  color: #666;\n  display: inline-block;\n  margin: 0 3px;\n  padding: 5px;\n  text-decoration: none;\n  border-radius: 3px;\n}\n.wangEditor-container .txt-toolbar a:hover {\n  background-color: #f1f1f1;\n}\n.wangEditor-container .img-drag-point {\n  display: block;\n  position: absolute;\n  width: 12px;\n  height: 12px;\n  border-radius: 50%;\n  cursor: se-resize;\n  background-color: #666;\n  margin-left: -6px;\n  margin-top: -6px;\n  box-shadow: 1px 1px 5px #999;\n}\n.wangEditor-container .wangEditor-upload-progress {\n  position: absolute;\n  height: 1px;\n  background: #1e88e5;\n  width: 0;\n  display: none;\n  -webkit-transition: width .5s;\n  -o-transition: width .5s;\n  transition: width .5s;\n}\n.wangEditor-fullscreen {\n  position: fixed;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n}\n.wangEditor-container .code-textarea {\n  resize: none;\n  width: 100%;\n  font-size: 14px;\n  line-height: 1.5;\n  font-family: 'Verdana';\n  color: #333;\n  padding: 0 15px 0 15px;\n}\n.wangEditor-menu-container {\n  width: 100%;\n  border-bottom: 1px solid #f1f1f1;\n  background-color: #fff;\n}\n.wangEditor-menu-container a {\n  text-decoration: none;\n}\n.wangEditor-menu-container .menu-group {\n  float: left;\n  padding: 0 8px;\n  border-right: 1px solid #f1f1f1;\n}\n.wangEditor-menu-container .menu-item {\n  float: left;\n  position: relative;\n  text-align: center;\n  height: 31px;\n  width: 35px;\n}\n.wangEditor-menu-container .menu-item:hover {\n  background-color: #f1f1f1;\n}\n.wangEditor-menu-container .menu-item a {\n  display: block;\n  text-align: center;\n  color: #666;\n  width: 100%;\n  padding: 8px 0;\n  font-size: 0.9em;\n}\n.wangEditor-menu-container .menu-item .selected {\n  color: #1e88e5;\n}\n.wangEditor-menu-container .menu-item .active {\n  background-color: #f1f1f1;\n}\n.wangEditor-menu-container .menu-item .disable {\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n.wangEditor-menu-container .menu-tip {\n  display: block;\n  position: absolute;\n  z-index: 20;\n  width: 60px;\n  text-align: center;\n  background-color: #666;\n  color: #fff;\n  padding: 7px 0;\n  font-size: 12px;\n  top: 100%;\n  left: 50%;\n  margin-left: -30px;\n  border-radius: 2px;\n  box-shadow: 1px 1px 5px #999;\n  display: none;\n  /*// 小三角\n        .tip-triangle {\n            display: block;\n            position: absolute;\n            width: 0;\n            height: 0;\n            border:5px solid;\n            border-color: transparent transparent @fore-color transparent;\n            top: -10px;\n            left: 50%;\n            margin-left: -5px;\n        }*/\n}\n.wangEditor-menu-container .menu-tip-40 {\n  width: 40px;\n  margin-left: -20px;\n}\n.wangEditor-menu-container .menu-tip-50 {\n  width: 50px;\n  margin-left: -25px;\n}\n.wangEditor-menu-shadow {\n  /*border-bottom-width: 0;*/\n  border-bottom: 1px\\9 solid\\9 #f1f1f1\\9;\n  box-shadow: 0 1px 3px #999;\n}\n.wangEditor-container .wangEditor-txt {\n  width: 100%;\n  text-align: left;\n  padding: 15px;\n  padding-top: 0;\n  margin-top: 5px;\n  overflow-y: auto;\n}\n.wangEditor-container .wangEditor-txt p,\n.wangEditor-container .wangEditor-txt h1,\n.wangEditor-container .wangEditor-txt h2,\n.wangEditor-container .wangEditor-txt h3,\n.wangEditor-container .wangEditor-txt h4,\n.wangEditor-container .wangEditor-txt h5 {\n  margin: 10px 0;\n  line-height: 1.8;\n}\n.wangEditor-container .wangEditor-txt p *,\n.wangEditor-container .wangEditor-txt h1 *,\n.wangEditor-container .wangEditor-txt h2 *,\n.wangEditor-container .wangEditor-txt h3 *,\n.wangEditor-container .wangEditor-txt h4 *,\n.wangEditor-container .wangEditor-txt h5 * {\n  line-height: 1.8;\n}\n.wangEditor-container .wangEditor-txt ul,\n.wangEditor-container .wangEditor-txt ol {\n  padding-left: 20px;\n}\n.wangEditor-container .wangEditor-txt img {\n  cursor: pointer;\n}\n.wangEditor-container .wangEditor-txt img.clicked {\n  box-shadow: 1px 1px 10px #999;\n}\n.wangEditor-container .wangEditor-txt table.clicked {\n  box-shadow: 1px 1px 10px #999;\n}\n.wangEditor-container .wangEditor-txt pre code {\n  line-height: 1.5;\n}\n.wangEditor-container .wangEditor-txt:focus {\n  outline: none;\n}\n.wangEditor-container .wangEditor-txt blockquote {\n  display: block;\n  border-left: 8px solid #d0e5f2;\n  padding: 5px 10px;\n  margin: 10px 0;\n  line-height: 1.4;\n  font-size: 100%;\n  background-color: #f1f1f1;\n}\n.wangEditor-container .wangEditor-txt table {\n  border: none;\n  border-collapse: collapse;\n}\n.wangEditor-container .wangEditor-txt table td,\n.wangEditor-container .wangEditor-txt table th {\n  border: 1px solid #999;\n  padding: 3px 5px;\n  min-width: 50px;\n  height: 20px;\n}\n.wangEditor-container .wangEditor-txt pre {\n  border: 1px solid #ccc;\n  background-color: #f8f8f8;\n  padding: 10px;\n  margin: 5px 0px;\n  font-size: 0.8em;\n  border-radius: 3px;\n}\n.wangEditor-drop-list {\n  display: none;\n  position: absolute;\n  background-color: #fff;\n  overflow: hidden;\n  z-index: 10;\n  transition: height .7s;\n  border-top: 1px solid #f1f1f1;\n  box-shadow: 1px 3px 3px #999;\n  border-left: 1px\\9 solid\\9 #ccc\\9;\n  border-bottom: 1px\\9 solid\\9 #999\\9;\n  border-right: 1px\\9 solid\\9 #999\\9;\n}\n.wangEditor-drop-list a {\n  text-decoration: none;\n  display: block;\n  color: #666;\n  padding: 3px 5px;\n}\n.wangEditor-drop-list a:hover {\n  background-color: #f1f1f1;\n}\n.wangEditor-drop-panel,\n.txt-toolbar {\n  display: none;\n  position: absolute;\n  padding: 10px;\n  font-size: 14px;\n  /*border: 1px\\9 solid\\9 #cccccc\\9;*/\n  background-color: #fff;\n  z-index: 10;\n  border-top: 2px solid #666;\n  box-shadow: 1px 3px 3px #999;\n  border-left: 1px\\9 solid\\9 #ccc\\9;\n  border-bottom: 1px\\9 solid\\9 #999\\9;\n  border-right: 1px\\9 solid\\9 #999\\9;\n}\n.wangEditor-drop-panel .tip-triangle,\n.txt-toolbar .tip-triangle {\n  display: block;\n  position: absolute;\n  width: 0;\n  height: 0;\n  border: 5px solid;\n  border-color: transparent transparent #666 transparent;\n  top: -12px;\n  left: 50%;\n  margin-left: -5px;\n}\n.wangEditor-drop-panel a,\n.txt-toolbar a {\n  text-decoration: none;\n}\n.wangEditor-drop-panel input[type=text],\n.txt-toolbar input[type=text] {\n  border: none;\n  border-bottom: 1px solid #ccc;\n  font-size: 14px;\n  height: 20px;\n  color: #333;\n  padding: 3px 0;\n}\n.wangEditor-drop-panel input[type=text]:focus,\n.txt-toolbar input[type=text]:focus {\n  outline: none;\n  border-bottom: 2px solid #1e88e5;\n}\n.wangEditor-drop-panel input[type=text].block,\n.txt-toolbar input[type=text].block {\n  display: block;\n  width: 100%;\n}\n.wangEditor-drop-panel textarea,\n.txt-toolbar textarea {\n  border: 1px solid #ccc;\n}\n.wangEditor-drop-panel textarea:focus,\n.txt-toolbar textarea:focus {\n  outline: none;\n  border-color: #1e88e5;\n}\n.wangEditor-drop-panel button,\n.txt-toolbar button {\n  font-size: 14px;\n  color: #1e88e5;\n  border: none;\n  padding: 10px;\n  background-color: #fff;\n  cursor: pointer;\n  border-radius: 3px;\n}\n.wangEditor-drop-panel button:hover,\n.txt-toolbar button:hover {\n  background-color: #f1f1f1;\n}\n.wangEditor-drop-panel button:focus,\n.txt-toolbar button:focus {\n  outline: none;\n}\n.wangEditor-drop-panel button.right,\n.txt-toolbar button.right {\n  float: right;\n  margin-left: 10px;\n}\n.wangEditor-drop-panel button.gray,\n.txt-toolbar button.gray {\n  color: #999;\n}\n.wangEditor-drop-panel button.link,\n.txt-toolbar button.link {\n  padding: 5px 10px;\n}\n.wangEditor-drop-panel button.link:hover,\n.txt-toolbar button.link:hover {\n  background-color: #fff;\n  text-decoration: underline;\n}\n.wangEditor-drop-panel .color-item,\n.txt-toolbar .color-item {\n  display: block;\n  float: left;\n  width: 25px;\n  height: 25px;\n  text-align: center;\n  padding: 2px;\n  border-radius: 2px;\n  text-decoration: underline;\n}\n.wangEditor-drop-panel .color-item:hover,\n.txt-toolbar .color-item:hover {\n  background-color: #f1f1f1;\n}\n.wangEditor-drop-panel .list-menu-item,\n.txt-toolbar .list-menu-item {\n  display: block;\n  float: left;\n  color: #333;\n  padding: 5px 5px;\n  border-radius: 2px;\n}\n.wangEditor-drop-panel .list-menu-item:hover,\n.txt-toolbar .list-menu-item:hover {\n  background-color: #f1f1f1;\n}\n.wangEditor-drop-panel table.choose-table,\n.txt-toolbar table.choose-table {\n  border: none;\n  border-collapse: collapse;\n}\n.wangEditor-drop-panel table.choose-table td,\n.txt-toolbar table.choose-table td {\n  border: 1px solid #ccc;\n  width: 16px;\n  height: 12px;\n}\n.wangEditor-drop-panel table.choose-table td.active,\n.txt-toolbar table.choose-table td.active {\n  background-color: #ccc;\n  opacity: .5;\n  filter: alpha(opacity=50);\n}\n.wangEditor-drop-panel .panel-tab .tab-container,\n.txt-toolbar .panel-tab .tab-container {\n  margin-bottom: 5px;\n}\n.wangEditor-drop-panel .panel-tab .tab-container a,\n.txt-toolbar .panel-tab .tab-container a {\n  display: inline-block;\n  color: #999;\n  text-align: center;\n  margin: 0 5px;\n  padding: 5px 5px;\n}\n.wangEditor-drop-panel .panel-tab .tab-container a.selected,\n.txt-toolbar .panel-tab .tab-container a.selected {\n  color: #1e88e5;\n  border-bottom: 2px solid #1e88e5;\n}\n.wangEditor-drop-panel .panel-tab .content-container .content,\n.txt-toolbar .panel-tab .content-container .content {\n  display: none;\n}\n.wangEditor-drop-panel .panel-tab .content-container .content a,\n.txt-toolbar .panel-tab .content-container .content a {\n  display: inline-block;\n  margin: 2px;\n  padding: 2px;\n  border-radius: 2px;\n}\n.wangEditor-drop-panel .panel-tab .content-container .content a:hover,\n.txt-toolbar .panel-tab .content-container .content a:hover {\n  background-color: #f1f1f1;\n}\n.wangEditor-drop-panel .panel-tab .content-container .selected,\n.txt-toolbar .panel-tab .content-container .selected {\n  display: block;\n}\n.wangEditor-drop-panel .panel-tab .emotion-content-container,\n.txt-toolbar .panel-tab .emotion-content-container {\n  height: 200px;\n  overflow-y: auto;\n}\n.wangEditor-drop-panel .upload-icon-container,\n.txt-toolbar .upload-icon-container {\n  color: #ccc;\n  text-align: center;\n  margin: 20px 20px 15px 20px !important;\n  padding: 5px !important;\n  font-size: 65px;\n  cursor: pointer;\n  border: 2px dotted #f1f1f1;\n  display: block !important;\n}\n.wangEditor-drop-panel .upload-icon-container:hover,\n.txt-toolbar .upload-icon-container:hover {\n  color: #666;\n  border-color: #ccc;\n}\n.wangEditor-modal {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  background-color: #fff;\n  border-top: 1px solid #f1f1f1;\n  box-shadow: 1px 3px 3px #999;\n  border-top: 1px\\9 solid\\9 #ccc\\9;\n  border-left: 1px\\9 solid\\9 #ccc\\9;\n  border-bottom: 1px\\9 solid\\9 #999\\9;\n  border-right: 1px\\9 solid\\9 #999\\9;\n}\n.wangEditor-modal .wangEditor-modal-close {\n  position: absolute;\n  top: 0;\n  right: 0;\n  margin-top: -25px;\n  margin-right: -25px;\n  font-size: 1.5em;\n  color: #666;\n  cursor: pointer;\n}\n@font-face {\n  font-family: 'icomoon';\n  src: url('../fonts/icomoon.eot?-qdfu1s');\n  src: url('../fonts/icomoon.eot?#iefix-qdfu1s') format('embedded-opentype'), url('../fonts/icomoon.ttf?-qdfu1s') format('truetype'), url('../fonts/icomoon.woff?-qdfu1s') format('woff'), url('../fonts/icomoon.svg?-qdfu1s#icomoon') format('svg');\n  font-weight: normal;\n  font-style: normal;\n}\n[class^=\"wangeditor-menu-img-\"],\n[class*=\" wangeditor-menu-img-\"] {\n  font-family: 'icomoon';\n  speak: none;\n  font-style: normal;\n  font-weight: normal;\n  font-variant: normal;\n  text-transform: none;\n  line-height: 1;\n  /* Better Font Rendering =========== */\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n.wangeditor-menu-img-link:before {\n  content: \"\\e800\";\n}\n.wangeditor-menu-img-unlink:before {\n  content: \"\\e801\";\n}\n.wangeditor-menu-img-code:before {\n  content: \"\\e802\";\n}\n.wangeditor-menu-img-cancel:before {\n  content: \"\\e803\";\n}\n.wangeditor-menu-img-terminal:before {\n  content: \"\\e804\";\n}\n.wangeditor-menu-img-angle-down:before {\n  content: \"\\e805\";\n}\n.wangeditor-menu-img-font:before {\n  content: \"\\e806\";\n}\n.wangeditor-menu-img-bold:before {\n  content: \"\\e807\";\n}\n.wangeditor-menu-img-italic:before {\n  content: \"\\e808\";\n}\n.wangeditor-menu-img-header:before {\n  content: \"\\e809\";\n}\n.wangeditor-menu-img-align-left:before {\n  content: \"\\e80a\";\n}\n.wangeditor-menu-img-align-center:before {\n  content: \"\\e80b\";\n}\n.wangeditor-menu-img-align-right:before {\n  content: \"\\e80c\";\n}\n.wangeditor-menu-img-list-bullet:before {\n  content: \"\\e80d\";\n}\n.wangeditor-menu-img-indent-left:before {\n  content: \"\\e80e\";\n}\n.wangeditor-menu-img-indent-right:before {\n  content: \"\\e80f\";\n}\n.wangeditor-menu-img-list-numbered:before {\n  content: \"\\e810\";\n}\n.wangeditor-menu-img-underline:before {\n  content: \"\\e811\";\n}\n.wangeditor-menu-img-table:before {\n  content: \"\\e812\";\n}\n.wangeditor-menu-img-eraser:before {\n  content: \"\\e813\";\n}\n.wangeditor-menu-img-text-height:before {\n  content: \"\\e814\";\n}\n.wangeditor-menu-img-brush:before {\n  content: \"\\e815\";\n}\n.wangeditor-menu-img-pencil:before {\n  content: \"\\e816\";\n}\n.wangeditor-menu-img-minus:before {\n  content: \"\\e817\";\n}\n.wangeditor-menu-img-picture:before {\n  content: \"\\e818\";\n}\n.wangeditor-menu-img-file-image:before {\n  content: \"\\e819\";\n}\n.wangeditor-menu-img-cw:before {\n  content: \"\\e81a\";\n}\n.wangeditor-menu-img-ccw:before {\n  content: \"\\e81b\";\n}\n.wangeditor-menu-img-music:before {\n  content: \"\\e911\";\n}\n.wangeditor-menu-img-play:before {\n  content: \"\\e912\";\n}\n.wangeditor-menu-img-location:before {\n  content: \"\\e947\";\n}\n.wangeditor-menu-img-happy:before {\n  content: \"\\e9df\";\n}\n.wangeditor-menu-img-sigma:before {\n  content: \"\\ea67\";\n}\n.wangeditor-menu-img-enlarge2:before {\n  content: \"\\e98b\";\n}\n.wangeditor-menu-img-shrink2:before {\n  content: \"\\e98c\";\n}\n.wangeditor-menu-img-newspaper:before {\n  content: \"\\e904\";\n}\n.wangeditor-menu-img-camera:before {\n  content: \"\\e90f\";\n}\n.wangeditor-menu-img-video-camera:before {\n  content: \"\\e914\";\n}\n.wangeditor-menu-img-file-zip:before {\n  content: \"\\e92b\";\n}\n.wangeditor-menu-img-stack:before {\n  content: \"\\e92e\";\n}\n.wangeditor-menu-img-credit-card:before {\n  content: \"\\e93f\";\n}\n.wangeditor-menu-img-address-book:before {\n  content: \"\\e944\";\n}\n.wangeditor-menu-img-envelop:before {\n  content: \"\\e945\";\n}\n.wangeditor-menu-img-drawer:before {\n  content: \"\\e95c\";\n}\n.wangeditor-menu-img-download:before {\n  content: \"\\e960\";\n}\n.wangeditor-menu-img-upload:before {\n  content: \"\\e961\";\n}\n.wangeditor-menu-img-lock:before {\n  content: \"\\e98f\";\n}\n.wangeditor-menu-img-unlocked:before {\n  content: \"\\e990\";\n}\n.wangeditor-menu-img-wrench:before {\n  content: \"\\e991\";\n}\n.wangeditor-menu-img-eye:before {\n  content: \"\\e9ce\";\n}\n.wangeditor-menu-img-eye-blocked:before {\n  content: \"\\e9d1\";\n}\n.wangeditor-menu-img-command:before {\n  content: \"\\ea4e\";\n}\n.wangeditor-menu-img-font2:before {\n  content: \"\\ea5c\";\n}\n.wangeditor-menu-img-libreoffice:before {\n  content: \"\\eade\";\n}\n.wangeditor-menu-img-quotes-left:before {\n  content: \"\\e977\";\n}\n.wangeditor-menu-img-strikethrough:before {\n  content: \"\\ea65\";\n}\n.wangeditor-menu-img-desktop:before {\n  content: \"\\f108\";\n}\n.wangeditor-menu-img-tablet:before {\n  content: \"\\f10a\";\n}\n.wangeditor-menu-img-search-plus:before {\n  content: \"\\f00e\";\n}\n.wangeditor-menu-img-search-minus:before {\n  content: \"\\f010\";\n}\n.wangeditor-menu-img-trash-o:before {\n  content: \"\\f014\";\n}\n.wangeditor-menu-img-align-justify:before {\n  content: \"\\f039\";\n}\n.wangeditor-menu-img-arrows-v:before {\n  content: \"\\f07d\";\n}\n.wangeditor-menu-img-sigma2:before {\n  content: \"\\ea68\";\n}\n.wangeditor-menu-img-omega:before {\n  content: \"\\e900\";\n}\n.wangeditor-menu-img-cancel-circle:before {\n  content: \"\\e901\";\n}\n.hljs {\n  display: block;\n  overflow-x: auto;\n  padding: 0.5em;\n  color: #333;\n  background: #f8f8f8;\n  -webkit-text-size-adjust: none;\n}\n.hljs-comment,\n.diff .hljs-header {\n  color: #998;\n  font-style: italic;\n}\n.hljs-keyword,\n.css .rule .hljs-keyword,\n.hljs-winutils,\n.nginx .hljs-title,\n.hljs-subst,\n.hljs-request,\n.hljs-status {\n  color: #333;\n  font-weight: bold;\n}\n.hljs-number,\n.hljs-hexcolor,\n.ruby .hljs-constant {\n  color: #008080;\n}\n.hljs-string,\n.hljs-tag .hljs-value,\n.hljs-doctag,\n.tex .hljs-formula {\n  color: #d14;\n}\n.hljs-title,\n.hljs-id,\n.scss .hljs-preprocessor {\n  color: #900;\n  font-weight: bold;\n}\n.hljs-list .hljs-keyword,\n.hljs-subst {\n  font-weight: normal;\n}\n.hljs-class .hljs-title,\n.hljs-type,\n.vhdl .hljs-literal,\n.tex .hljs-command {\n  color: #458;\n  font-weight: bold;\n}\n.hljs-tag,\n.hljs-tag .hljs-title,\n.hljs-rule .hljs-property,\n.django .hljs-tag .hljs-keyword {\n  color: #000080;\n  font-weight: normal;\n}\n.hljs-attribute,\n.hljs-variable,\n.lisp .hljs-body,\n.hljs-name {\n  color: #008080;\n}\n.hljs-regexp {\n  color: #009926;\n}\n.hljs-symbol,\n.ruby .hljs-symbol .hljs-string,\n.lisp .hljs-keyword,\n.clojure .hljs-keyword,\n.scheme .hljs-keyword,\n.tex .hljs-special,\n.hljs-prompt {\n  color: #990073;\n}\n.hljs-built_in {\n  color: #0086b3;\n}\n.hljs-preprocessor,\n.hljs-pragma,\n.hljs-pi,\n.hljs-doctype,\n.hljs-shebang,\n.hljs-cdata {\n  color: #999;\n  font-weight: bold;\n}\n.hljs-deletion {\n  background: #fdd;\n}\n.hljs-addition {\n  background: #dfd;\n}\n.diff .hljs-change {\n  background: #0086b3;\n}\n.hljs-chunk {\n  color: #aaa;\n}\n"
  },
  {
    "path": "public/static/plugins/wangeditor/css/wangEditor.less",
    "content": "\n// ---------- begin 全局颜色配置 ------------\n\n/* 编辑器边框颜色 */\n@border-color: #ccc;\n\n/* 菜单颜色、上边框颜色 */\n@fore-color: #666;\n\n/* 菜单选中状态的颜色 */\n@selected-color: #1e88e5;\n\n/* input focus 时的颜色 */\n@focus-input-color: #1e88e5;\n\n/* 按钮颜色 */\n@button-color: #1e88e5;\n\n/* tab selected 状态下的颜色 */\n@selected-tab-color: #1e88e5;\n\n// ---------- end 全局颜色配置 ------------\n\n\n.wangEditor-container {\n    position: relative;\n    background-color: #fff;\n    border: 1px solid @border-color;\n    z-index: 1;\n    width: 100%;\n\n    a:focus,\n    button:focus{\n        outline:none;\n    }\n\n    &,* {\n        margin: 0;\n        padding: 0;\n        box-sizing: border-box;\n        line-height: 1;\n    }\n\n    img {\n        border: none;\n    }\n\n    .clearfix:after {\n        content: '';\n        display: table;\n        clear: both;\n    }\n    .clearfix {\n        *zoom: 1;\n    }\n\n    textarea {\n        border: none;\n        &:focus{\n            outline: none; \n        }\n    }\n\n    // 显示p head 高度的 tip\n    .height-tip {\n        position: absolute;\n        width: 3px;\n        background-color: #ccc;\n        left: 0;\n        transition: top .2s;\n    }\n\n    // 设置 img table 的 toolbar\n    .txt-toolbar {\n        position: absolute;\n        background-color: #fff;\n        padding: 3px 5px;\n        border-top: 2px solid @fore-color;\n        box-shadow: 1px 3px 3px #999;\n\n        // for IE8\n        border-left: 1px\\9 solid\\9 #ccc\\9;\n        border-bottom: 1px\\9 solid\\9 #999\\9;\n        border-right: 1px\\9 solid\\9 #999\\9;\n\n        // 小三角\n        .tip-triangle {\n            display: block;\n            position: absolute;\n            width: 0;\n            height: 0;\n            border: 5px solid;\n            border-color: transparent transparent @fore-color transparent;\n            top: -12px;\n            left: 50%;\n            margin-left: -5px;\n        }\n\n        a {\n            color: @fore-color;\n            display: inline-block;\n            margin: 0 3px;\n            padding: 5px;\n            text-decoration: none;\n            border-radius: 3px;\n\n            &:hover {\n                background-color: #f1f1f1;\n            }\n        }\n    }\n    // 图品拖拽大小\n    .img-drag-point {\n        display: block;\n        position: absolute;\n        width: 12px;\n        height: 12px;\n        border-radius: 50%;\n        cursor: se-resize;\n        background-color: @fore-color;\n        margin-left: -6px;\n        margin-top: -6px;\n        box-shadow: 1px 1px 5px #999;\n    }\n\n    // 进度条\n    .wangEditor-upload-progress {\n        position: absolute;\n        height: 1px;\n        background: #1e88e5;\n        width: 0;\n        display: none;\n        -webkit-transition: width .5s;\n        -o-transition: width .5s;\n        transition: width .5s;\n    }\n}\n.wangEditor-fullscreen {\n    position: fixed;\n    top: 0;\n    bottom: 0;\n    left: 0;\n    right: 0;\n}\n.wangEditor-container {\n    .code-textarea {\n        resize: none;\n        width: 100%;\n        font-size: 14px;\n        line-height: 1.5;\n        font-family: 'Verdana';\n        color: #333;\n        padding: 0 15px 0 15px;\n    }\n}\n.wangEditor-menu-container {\n\n    width: 100%;\n    border-bottom: 1px solid #f1f1f1;\n    background-color: #fff;\n    \n    a {\n        text-decoration: none;\n    }\n\n    // 菜单组\n    .menu-group {\n        float: left;\n        padding: 0 8px;\n        border-right: 1px solid #f1f1f1;\n    }\n\n    // 单个菜单容器\n    .menu-item {\n        float: left;\n        position: relative;\n        text-align: center;\n        height: 31px;\n        width: 35px;\n\n        &:hover {\n            background-color: #f1f1f1;\n        }\n\n        // 菜单\n        a {\n            display: block;\n            text-align: center;\n            color: @fore-color;\n            width: 100%;\n            padding: 8px 0;\n            font-size: 0.9em;\n        }\n\n         // 菜单选中状态\n        .selected {\n            color: @selected-color;\n        }\n\n        // 激活状态\n        .active {\n            background-color: #f1f1f1;\n        }\n\n        // 禁用状态\n        .disable {\n            opacity: 0.5;\n            filter: Alpha(opacity=50);\n        }\n    }\n\n    // tip提示\n    .menu-tip {\n        display: block;\n        position: absolute;\n        z-index: 20;\n        width: 60px;\n        text-align: center;\n        background-color: @fore-color;\n        color: #fff;\n        padding: 7px 0;\n        font-size: 12px;\n        top: 100%;\n        left: 50%;\n        margin-left: -30px;\n        border-radius: 2px;\n        box-shadow: 1px 1px 5px #999;\n\n        display: none;\n\n        /*// 小三角\n        .tip-triangle {\n            display: block;\n            position: absolute;\n            width: 0;\n            height: 0;\n            border:5px solid;\n            border-color: transparent transparent @fore-color transparent;\n            top: -10px;\n            left: 50%;\n            margin-left: -5px;\n        }*/\n    }\n    .menu-tip-40 {\n        width: 40px;\n        margin-left: -20px;\n    }\n    .menu-tip-50 {\n        width: 50px;\n        margin-left: -25px;\n    }\n}\n.wangEditor-menu-shadow {\n    /*border-bottom-width: 0;*/\n    border-bottom: 1px\\9 solid\\9 #f1f1f1\\9;\n    box-shadow: 0 1px 3px #999;\n}\n.wangEditor-container {\n    .wangEditor-txt{\n        width: 100%;\n        text-align: left;\n        padding: 15px;\n        padding-top: 0;\n        margin-top: 5px;\n        overflow-y: auto;\n\n        p,h1,h2,h3,h4,h5 {\n            margin: 10px 0;\n            line-height: 1.8;\n\n            * {\n                line-height: 1.8;\n            }\n        }\n\n        ul, ol {\n            padding-left: 20px;\n        }\n\n        img {\n            cursor: pointer;\n        }\n        img.clicked {\n            box-shadow: 1px 1px 10px #999;\n        }\n\n        table.clicked {\n            box-shadow: 1px 1px 10px #999;\n        }\n\n        pre code {\n            line-height: 1.5;\n        }\n\n        &:focus{\n            outline: none; \n        }\n    }\n}\n.wangEditor-container {\n    .wangEditor-txt {\n        blockquote {\n            display: block; \n            border-left: 8px solid #d0e5f2;\n            padding: 5px 10px;\n            margin: 10px 0; \n            line-height: 1.4; \n            font-size: 100%;\n            background-color: #f1f1f1;\n        }\n        table {\n            border: none;\n            border-collapse: collapse;\n        }\n        table td,\n        table th {\n            border: 1px solid #999;\n            padding: 3px 5px;\n            min-width: 50px;\n            height: 20px;\n        }\n        pre {\n            border: 1px solid #ccc; \n            background-color: #f8f8f8; \n            padding: 10px; \n            margin: 5px 0px;\n            font-size: 0.8em;\n            border-radius: 3px;\n        }\n    }\n}\n.wangEditor-drop-list {\n    display: none;\n    position: absolute;\n    background-color: #fff;\n    overflow: hidden;\n    z-index: 10;\n\n    transition: height .7s;\n    \n    border-top: 1px solid #f1f1f1;\n    box-shadow: 1px 3px 3px #999;\n\n    // for IE8\n    border-left: 1px\\9 solid\\9 #ccc\\9;\n    border-bottom: 1px\\9 solid\\9 #999\\9;\n    border-right: 1px\\9 solid\\9 #999\\9;\n\n    a {\n        text-decoration: none;\n        display: block;\n        color: @fore-color;\n        padding: 3px 5px;\n\n        &:hover {\n            background-color: #f1f1f1;\n        }\n    }\n}\n.wangEditor-drop-panel,\n.txt-toolbar {\n    display: none;\n    position: absolute;\n    padding: 10px;\n    font-size: 14px;\n    /*border: 1px\\9 solid\\9 #cccccc\\9;*/\n\n    background-color: #fff;\n    z-index: 10;\n    \n    border-top: 2px solid @fore-color;\n    box-shadow: 1px 3px 3px #999;\n\n    // for IE8\n    border-left: 1px\\9 solid\\9 #ccc\\9;\n    border-bottom: 1px\\9 solid\\9 #999\\9;\n    border-right: 1px\\9 solid\\9 #999\\9;\n\n    // 小三角\n    .tip-triangle {\n        display: block;\n        position: absolute;\n        width: 0;\n        height: 0;\n        border: 5px solid;\n        border-color: transparent transparent @fore-color transparent;\n        top: -12px;\n        left: 50%;\n        margin-left: -5px;\n    }\n\n    a {\n        text-decoration: none;\n    }\n\n    // 输入框\n    input[type=text] {\n        border: none;\n        border-bottom: 1px solid #ccc;\n        font-size: 14px;\n        height: 20px;\n        color: #333;\n        padding: 3px 0;\n\n        &:focus{\n            outline: none;\n            border-bottom: 2px solid @focus-input-color;\n        }\n    }\n    input[type=text].block {\n        display: block;\n        width: 100%;\n    }\n    textarea {\n        border: 1px solid #ccc;\n        &:focus {\n            outline: none;\n            border-color: @focus-input-color;\n        }\n    }\n\n    // 按钮\n    button {\n        font-size: 14px;\n        color: @button-color;\n        border: none;\n        padding: 10px;\n        background-color: #fff;\n        cursor: pointer;\n        border-radius: 3px;\n        \n        &:hover {\n            background-color: #f1f1f1;\n        }\n        &:focus{\n            outline: none; \n        }\n    }\n    button.right {\n        float: right;\n        margin-left: 10px;\n    }\n    button.gray {\n        color: #999;\n    }\n    button.link {\n        padding: 5px 10px;\n        &:hover {\n            background-color: #fff;\n            text-decoration: underline;\n        }\n    }\n    \n    // 颜色块\n    .color-item {\n        display: block;\n        float: left;\n        width: 25px;\n        height: 25px;\n        text-align: center;\n        padding: 2px;\n        border-radius: 2px;\n        text-decoration: underline;\n\n        &:hover {\n            background-color: #f1f1f1;\n        }\n    }\n\n    // 列表\n    .list-menu-item {\n        display: block;\n        float: left;\n        color: #333;\n        padding: 5px 5px;\n        border-radius: 2px;\n\n        &:hover {\n            background-color: #f1f1f1;\n        }\n    }\n\n    // 表格\n    table.choose-table {\n        border: none;\n        border-collapse: collapse;\n\n        td {\n            border: 1px solid #ccc;\n            width: 16px;\n            height: 12px;\n        }\n        td.active {\n            background-color: #ccc;\n            opacity: .5;\n            filter: Alpha(opacity=50);\n        }\n    }\n\n    // tab\n    .panel-tab {\n        .tab-container {\n            margin-bottom: 5px;\n\n            a {\n                display: inline-block;\n                color: #999;\n                text-align: center;\n                margin: 0 5px;\n                padding: 5px 5px;\n            }\n\n            a.selected {\n                color: @selected-tab-color;\n                border-bottom: 2px solid @selected-tab-color;\n            }\n        }\n        .content-container {\n            .content {\n                display: none;\n\n                a {\n                    display: inline-block;\n                    margin: 2px;\n                    padding: 2px;\n                    border-radius: 2px;\n\n                    &:hover {\n                        background-color: #f1f1f1;\n                    }\n                }\n            }\n            .selected {\n                display: block;\n            }\n        }\n        .emotion-content-container {\n            height: 200px;\n            overflow-y: auto;\n        }\n    }\n\n    // 上传图片\n    .upload-icon-container {\n        color: #ccc;\n        text-align: center;\n        margin: 20px 20px 15px 20px !important;\n        padding: 5px !important;\n        font-size: 65px;\n        cursor: pointer;\n        border: 2px dotted #f1f1f1;\n        display: block !important;\n\n        &:hover {\n            color: #666;\n            border-color: #ccc;\n        }\n    }\n}\n.wangEditor-modal {\n    position: absolute;\n    top: 50%;\n    left: 50%;\n    background-color: #fff;\n    \n    border-top: 1px solid #f1f1f1;\n    box-shadow: 1px 3px 3px #999;\n\n    // for IE8\n    border-top: 1px\\9 solid\\9 #ccc\\9;\n    border-left: 1px\\9 solid\\9 #ccc\\9;\n    border-bottom: 1px\\9 solid\\9 #999\\9;\n    border-right: 1px\\9 solid\\9 #999\\9;\n\n    // 关闭按钮\n    .wangEditor-modal-close {\n        position: absolute;\n        top: 0;\n        right: 0;\n        margin-top: -25px;\n        margin-right: -25px;\n        font-size: 1.5em;\n        color: #666;\n        cursor: pointer;\n    }\n    \n}\n@font-face {\n    font-family: 'icomoon';\n    src:url('../fonts/icomoon.eot?-qdfu1s');\n    src:url('../fonts/icomoon.eot?#iefix-qdfu1s') format('embedded-opentype'),\n        url('../fonts/icomoon.ttf?-qdfu1s') format('truetype'),\n        url('../fonts/icomoon.woff?-qdfu1s') format('woff'),\n        url('../fonts/icomoon.svg?-qdfu1s#icomoon') format('svg');\n    font-weight: normal;\n    font-style: normal;\n}\n\n[class^=\"wangeditor-menu-img-\"], [class*=\" wangeditor-menu-img-\"] {\n    font-family: 'icomoon';\n    speak: none;\n    font-style: normal;\n    font-weight: normal;\n    font-variant: normal;\n    text-transform: none;\n    line-height: 1;\n\n    /* Better Font Rendering =========== */\n    -webkit-font-smoothing: antialiased;\n    -moz-osx-font-smoothing: grayscale;\n}\n.wangeditor-menu-img-link:before {content: \"\\e800\";}\n.wangeditor-menu-img-unlink:before {content: \"\\e801\";}\n.wangeditor-menu-img-code:before {content: \"\\e802\";}\n.wangeditor-menu-img-cancel:before {content: \"\\e803\";}\n.wangeditor-menu-img-terminal:before {content: \"\\e804\";}\n.wangeditor-menu-img-angle-down:before {content: \"\\e805\";}\n.wangeditor-menu-img-font:before {content: \"\\e806\";}\n.wangeditor-menu-img-bold:before {content: \"\\e807\";}\n.wangeditor-menu-img-italic:before {content: \"\\e808\";}\n.wangeditor-menu-img-header:before {content: \"\\e809\";}\n.wangeditor-menu-img-align-left:before {content: \"\\e80a\";}\n.wangeditor-menu-img-align-center:before {content: \"\\e80b\";}\n.wangeditor-menu-img-align-right:before {content: \"\\e80c\";}\n.wangeditor-menu-img-list-bullet:before {content: \"\\e80d\";}\n.wangeditor-menu-img-indent-left:before {content: \"\\e80e\";}\n.wangeditor-menu-img-indent-right:before {content: \"\\e80f\";}\n.wangeditor-menu-img-list-numbered:before {content: \"\\e810\";}\n.wangeditor-menu-img-underline:before {content: \"\\e811\";}\n.wangeditor-menu-img-table:before {content: \"\\e812\";}\n.wangeditor-menu-img-eraser:before {content: \"\\e813\";}\n.wangeditor-menu-img-text-height:before {content: \"\\e814\";}\n.wangeditor-menu-img-brush:before {content: \"\\e815\";}\n.wangeditor-menu-img-pencil:before {content: \"\\e816\";}\n.wangeditor-menu-img-minus:before {content: \"\\e817\";}\n.wangeditor-menu-img-picture:before {content: \"\\e818\";}\n.wangeditor-menu-img-file-image:before {content: \"\\e819\";}\n.wangeditor-menu-img-cw:before {content: \"\\e81a\";}\n.wangeditor-menu-img-ccw:before {content: \"\\e81b\";}\n.wangeditor-menu-img-music:before {content: \"\\e911\";}\n.wangeditor-menu-img-play:before {content: \"\\e912\";}\n.wangeditor-menu-img-location:before {content: \"\\e947\";}\n.wangeditor-menu-img-happy:before {content: \"\\e9df\";}\n.wangeditor-menu-img-sigma:before {content: \"\\ea67\";}\n.wangeditor-menu-img-enlarge2:before {content: \"\\e98b\";}\n.wangeditor-menu-img-shrink2:before {content: \"\\e98c\";}\n.wangeditor-menu-img-newspaper:before{content: \"\\e904\";}\n.wangeditor-menu-img-camera:before{content: \"\\e90f\";}\n.wangeditor-menu-img-video-camera:before{content: \"\\e914\";}\n.wangeditor-menu-img-file-zip:before{content: \"\\e92b\";}\n.wangeditor-menu-img-stack:before{content: \"\\e92e\";}\n.wangeditor-menu-img-credit-card:before{content: \"\\e93f\";}\n.wangeditor-menu-img-address-book:before{content: \"\\e944\";}\n.wangeditor-menu-img-envelop:before{content: \"\\e945\";}\n.wangeditor-menu-img-drawer:before{content: \"\\e95c\";}\n.wangeditor-menu-img-download:before{content: \"\\e960\";}\n.wangeditor-menu-img-upload:before{content: \"\\e961\";}\n.wangeditor-menu-img-lock:before{content: \"\\e98f\";}\n.wangeditor-menu-img-unlocked:before{content: \"\\e990\";}\n.wangeditor-menu-img-wrench:before{content: \"\\e991\";}\n.wangeditor-menu-img-eye:before{content: \"\\e9ce\";}\n.wangeditor-menu-img-eye-blocked:before{content: \"\\e9d1\";}\n.wangeditor-menu-img-command:before{content: \"\\ea4e\";}\n.wangeditor-menu-img-font2:before{content: \"\\ea5c\";}\n.wangeditor-menu-img-libreoffice:before{content: \"\\eade\";}\n.wangeditor-menu-img-quotes-left:before{content: \"\\e977\";}\n.wangeditor-menu-img-strikethrough:before{content: \"\\ea65\";}\n.wangeditor-menu-img-desktop:before{content: \"\\f108\";}\n.wangeditor-menu-img-tablet:before{content: \"\\f10a\";}\n.wangeditor-menu-img-search-plus:before {\n    content: \"\\f00e\";\n}\n.wangeditor-menu-img-search-minus:before {\n    content: \"\\f010\";\n}\n.wangeditor-menu-img-trash-o:before {\n    content: \"\\f014\";\n}\n.wangeditor-menu-img-align-justify:before {\n    content: \"\\f039\";\n}\n.wangeditor-menu-img-arrows-v:before {\n    content: \"\\f07d\";\n}\n.wangeditor-menu-img-sigma2:before {\n    content: \"\\ea68\";\n}\n.wangeditor-menu-img-omega:before {\n    content: \"\\e900\";\n}\n.wangeditor-menu-img-cancel-circle:before {\n    content: \"\\e901\";\n}\n.hljs {\n  display: block;\n  overflow-x: auto;\n  padding: 0.5em;\n  color: #333;\n  background: #f8f8f8;\n  -webkit-text-size-adjust: none;\n}\n\n.hljs-comment,\n.diff .hljs-header {\n  color: #998;\n  font-style: italic;\n}\n\n.hljs-keyword,\n.css .rule .hljs-keyword,\n.hljs-winutils,\n.nginx .hljs-title,\n.hljs-subst,\n.hljs-request,\n.hljs-status {\n  color: #333;\n  font-weight: bold;\n}\n\n.hljs-number,\n.hljs-hexcolor,\n.ruby .hljs-constant {\n  color: #008080;\n}\n\n.hljs-string,\n.hljs-tag .hljs-value,\n.hljs-doctag,\n.tex .hljs-formula {\n  color: #d14;\n}\n\n.hljs-title,\n.hljs-id,\n.scss .hljs-preprocessor {\n  color: #900;\n  font-weight: bold;\n}\n\n.hljs-list .hljs-keyword,\n.hljs-subst {\n  font-weight: normal;\n}\n\n.hljs-class .hljs-title,\n.hljs-type,\n.vhdl .hljs-literal,\n.tex .hljs-command {\n  color: #458;\n  font-weight: bold;\n}\n\n.hljs-tag,\n.hljs-tag .hljs-title,\n.hljs-rule .hljs-property,\n.django .hljs-tag .hljs-keyword {\n  color: #000080;\n  font-weight: normal;\n}\n\n.hljs-attribute,\n.hljs-variable,\n.lisp .hljs-body,\n.hljs-name {\n  color: #008080;\n}\n\n.hljs-regexp {\n  color: #009926;\n}\n\n.hljs-symbol,\n.ruby .hljs-symbol .hljs-string,\n.lisp .hljs-keyword,\n.clojure .hljs-keyword,\n.scheme .hljs-keyword,\n.tex .hljs-special,\n.hljs-prompt {\n  color: #990073;\n}\n\n.hljs-built_in {\n  color: #0086b3;\n}\n\n.hljs-preprocessor,\n.hljs-pragma,\n.hljs-pi,\n.hljs-doctype,\n.hljs-shebang,\n.hljs-cdata {\n  color: #999;\n  font-weight: bold;\n}\n\n.hljs-deletion {\n  background: #fdd;\n}\n\n.hljs-addition {\n  background: #dfd;\n}\n\n.diff .hljs-change {\n  background: #0086b3;\n}\n\n.hljs-chunk {\n  color: #aaa;\n}"
  },
  {
    "path": "public/static/plugins/wangeditor/css/wangEditor2.css",
    "content": "/* 在 wangEditor.less 文件的最上方加上下一行代码 */\n#editor-container {\n  /* 编辑器边框颜色 */\n\n  /* 菜单颜色、上边框颜色 */\n\n  /* 菜单选中状态的颜色 */\n\n  /* input focus 时的颜色 */\n\n  /* 按钮颜色 */\n\n  /* tab selected 状态下的颜色 */\n\n}\n#editor-container .wangEditor-container {\n  position: relative;\n  background-color: #fff;\n  border: 1px solid #cccccc;\n  z-index: 1;\n  width: 100%;\n}\n#editor-container .wangEditor-container a:focus,\n#editor-container .wangEditor-container button:focus {\n  outline: none;\n}\n#editor-container .wangEditor-container,\n#editor-container .wangEditor-container * {\n  margin: 0;\n  padding: 0;\n  box-sizing: border-box;\n  line-height: 1;\n}\n#editor-container .wangEditor-container img {\n  border: none;\n}\n#editor-container .wangEditor-container .clearfix:after {\n  content: '';\n  display: table;\n  clear: both;\n}\n#editor-container .wangEditor-container .clearfix {\n  *zoom: 1;\n}\n#editor-container .wangEditor-container textarea {\n  border: none;\n}\n#editor-container .wangEditor-container textarea:focus {\n  outline: none;\n}\n#editor-container .wangEditor-container .height-tip {\n  position: absolute;\n  width: 3px;\n  background-color: #ccc;\n  left: 0;\n  transition: top .2s;\n}\n#editor-container .wangEditor-container .txt-toolbar {\n  position: absolute;\n  background-color: #fff;\n  padding: 3px 5px;\n  border-top: 2px solid #666666;\n  box-shadow: 1px 3px 3px #999;\n  border-left: 1px\\9 solid\\9 #ccc\\9;\n  border-bottom: 1px\\9 solid\\9 #999\\9;\n  border-right: 1px\\9 solid\\9 #999\\9;\n}\n#editor-container .wangEditor-container .txt-toolbar .tip-triangle {\n  display: block;\n  position: absolute;\n  width: 0;\n  height: 0;\n  border: 5px solid;\n  border-color: transparent transparent #666666 transparent;\n  top: -12px;\n  left: 50%;\n  margin-left: -5px;\n}\n#editor-container .wangEditor-container .txt-toolbar a {\n  color: #666666;\n  display: inline-block;\n  margin: 0 3px;\n  padding: 5px;\n  text-decoration: none;\n  border-radius: 3px;\n}\n#editor-container .wangEditor-container .txt-toolbar a:hover {\n  background-color: #f1f1f1;\n}\n#editor-container .wangEditor-container .img-drag-point {\n  display: block;\n  position: absolute;\n  width: 12px;\n  height: 12px;\n  border-radius: 50%;\n  cursor: se-resize;\n  background-color: #666666;\n  margin-left: -6px;\n  margin-top: -6px;\n  box-shadow: 1px 1px 5px #999;\n}\n#editor-container .wangEditor-container .wangEditor-upload-progress {\n  position: absolute;\n  height: 1px;\n  background: #1e88e5;\n  width: 0;\n  display: none;\n  -webkit-transition: width .5s;\n  -o-transition: width .5s;\n  transition: width .5s;\n}\n#editor-container .wangEditor-fullscreen {\n  position: fixed;\n  top: 0;\n  bottom: 0;\n  left: 0;\n  right: 0;\n}\n#editor-container .wangEditor-container .code-textarea {\n  resize: none;\n  width: 100%;\n  font-size: 14px;\n  line-height: 1.5;\n  font-family: 'Verdana';\n  color: #333;\n  padding: 0 15px 0 15px;\n}\n#editor-container .wangEditor-menu-container {\n  width: 100%;\n  border-bottom: 1px solid #f1f1f1;\n  background-color: #fff;\n}\n#editor-container .wangEditor-menu-container a {\n  text-decoration: none;\n}\n#editor-container .wangEditor-menu-container .menu-group {\n  float: left;\n  padding: 0 8px;\n  border-right: 1px solid #f1f1f1;\n}\n#editor-container .wangEditor-menu-container .menu-item {\n  float: left;\n  position: relative;\n  text-align: center;\n  height: 31px;\n  width: 35px;\n}\n#editor-container .wangEditor-menu-container .menu-item:hover {\n  background-color: #f1f1f1;\n}\n#editor-container .wangEditor-menu-container .menu-item a {\n  display: block;\n  text-align: center;\n  color: #666666;\n  width: 100%;\n  padding: 8px 0;\n  font-size: 0.9em;\n}\n#editor-container .wangEditor-menu-container .menu-item .selected {\n  color: #1e88e5;\n}\n#editor-container .wangEditor-menu-container .menu-item .active {\n  background-color: #f1f1f1;\n}\n#editor-container .wangEditor-menu-container .menu-item .disable {\n  opacity: 0.5;\n  filter: alpha(opacity=50);\n}\n#editor-container .wangEditor-menu-container .menu-tip {\n  display: block;\n  position: absolute;\n  z-index: 20;\n  width: 60px;\n  text-align: center;\n  background-color: #666666;\n  color: #fff;\n  padding: 7px 0;\n  font-size: 12px;\n  top: 100%;\n  left: 50%;\n  margin-left: -30px;\n  border-radius: 2px;\n  box-shadow: 1px 1px 5px #999;\n  display: none;\n  /*// 小三角\n        .tip-triangle {\n            display: block;\n            position: absolute;\n            width: 0;\n            height: 0;\n            border:5px solid;\n            border-color: transparent transparent @fore-color transparent;\n            top: -10px;\n            left: 50%;\n            margin-left: -5px;\n        }*/\n\n}\n#editor-container .wangEditor-menu-container .menu-tip-40 {\n  width: 40px;\n  margin-left: -20px;\n}\n#editor-container .wangEditor-menu-container .menu-tip-50 {\n  width: 50px;\n  margin-left: -25px;\n}\n#editor-container .wangEditor-menu-shadow {\n  /*border-bottom-width: 0;*/\n\n  border-bottom: 1px\\9 solid\\9 #f1f1f1\\9;\n  box-shadow: 0 1px 3px #999;\n}\n#editor-container .wangEditor-container .wangEditor-txt {\n  width: 100%;\n  text-align: left;\n  padding: 15px;\n  padding-top: 0;\n  margin-top: 5px;\n  overflow-y: auto;\n}\n#editor-container .wangEditor-container .wangEditor-txt p,\n#editor-container .wangEditor-container .wangEditor-txt h1,\n#editor-container .wangEditor-container .wangEditor-txt h2,\n#editor-container .wangEditor-container .wangEditor-txt h3,\n#editor-container .wangEditor-container .wangEditor-txt h4,\n#editor-container .wangEditor-container .wangEditor-txt h5 {\n  margin: 10px 0;\n  line-height: 1.8;\n}\n#editor-container .wangEditor-container .wangEditor-txt p *,\n#editor-container .wangEditor-container .wangEditor-txt h1 *,\n#editor-container .wangEditor-container .wangEditor-txt h2 *,\n#editor-container .wangEditor-container .wangEditor-txt h3 *,\n#editor-container .wangEditor-container .wangEditor-txt h4 *,\n#editor-container .wangEditor-container .wangEditor-txt h5 * {\n  line-height: 1.8;\n}\n#editor-container .wangEditor-container .wangEditor-txt ul,\n#editor-container .wangEditor-container .wangEditor-txt ol {\n  padding-left: 20px;\n}\n#editor-container .wangEditor-container .wangEditor-txt img {\n  cursor: pointer;\n}\n#editor-container .wangEditor-container .wangEditor-txt img.clicked {\n  box-shadow: 1px 1px 10px #999;\n}\n#editor-container .wangEditor-container .wangEditor-txt table.clicked {\n  box-shadow: 1px 1px 10px #999;\n}\n#editor-container .wangEditor-container .wangEditor-txt pre code {\n  line-height: 1.5;\n}\n#editor-container .wangEditor-container .wangEditor-txt:focus {\n  outline: none;\n}\n#editor-container .wangEditor-container .wangEditor-txt blockquote {\n  display: block;\n  border-left: 8px solid #d0e5f2;\n  padding: 5px 10px;\n  margin: 10px 0;\n  line-height: 1.4;\n  font-size: 100%;\n  background-color: #f1f1f1;\n}\n#editor-container .wangEditor-container .wangEditor-txt table {\n  border: none;\n  border-collapse: collapse;\n}\n#editor-container .wangEditor-container .wangEditor-txt table td,\n#editor-container .wangEditor-container .wangEditor-txt table th {\n  border: 1px solid #999;\n  padding: 3px 5px;\n  min-width: 50px;\n  height: 20px;\n}\n#editor-container .wangEditor-container .wangEditor-txt pre {\n  border: 1px solid #ccc;\n  background-color: #f8f8f8;\n  padding: 10px;\n  margin: 5px 0px;\n  font-size: 0.8em;\n  border-radius: 3px;\n}\n#editor-container .wangEditor-drop-list {\n  display: none;\n  position: absolute;\n  background-color: #fff;\n  overflow: hidden;\n  z-index: 10;\n  transition: height .7s;\n  border-top: 1px solid #f1f1f1;\n  box-shadow: 1px 3px 3px #999;\n  border-left: 1px\\9 solid\\9 #ccc\\9;\n  border-bottom: 1px\\9 solid\\9 #999\\9;\n  border-right: 1px\\9 solid\\9 #999\\9;\n}\n#editor-container .wangEditor-drop-list a {\n  text-decoration: none;\n  display: block;\n  color: #666666;\n  padding: 3px 5px;\n}\n#editor-container .wangEditor-drop-list a:hover {\n  background-color: #f1f1f1;\n}\n#editor-container .wangEditor-drop-panel,\n#editor-container .txt-toolbar {\n  display: none;\n  position: absolute;\n  padding: 10px;\n  font-size: 14px;\n  /*border: 1px\\9 solid\\9 #cccccc\\9;*/\n\n  background-color: #fff;\n  z-index: 10;\n  border-top: 2px solid #666666;\n  box-shadow: 1px 3px 3px #999;\n  border-left: 1px\\9 solid\\9 #ccc\\9;\n  border-bottom: 1px\\9 solid\\9 #999\\9;\n  border-right: 1px\\9 solid\\9 #999\\9;\n}\n#editor-container .wangEditor-drop-panel .tip-triangle,\n#editor-container .txt-toolbar .tip-triangle {\n  display: block;\n  position: absolute;\n  width: 0;\n  height: 0;\n  border: 5px solid;\n  border-color: transparent transparent #666666 transparent;\n  top: -12px;\n  left: 50%;\n  margin-left: -5px;\n}\n#editor-container .wangEditor-drop-panel a,\n#editor-container .txt-toolbar a {\n  text-decoration: none;\n}\n#editor-container .wangEditor-drop-panel input[type=text],\n#editor-container .txt-toolbar input[type=text] {\n  border: none;\n  border-bottom: 1px solid #ccc;\n  font-size: 14px;\n  height: 20px;\n  color: #333;\n  padding: 3px 0;\n}\n#editor-container .wangEditor-drop-panel input[type=text]:focus,\n#editor-container .txt-toolbar input[type=text]:focus {\n  outline: none;\n  border-bottom: 2px solid #1e88e5;\n}\n#editor-container .wangEditor-drop-panel input[type=text].block,\n#editor-container .txt-toolbar input[type=text].block {\n  display: block;\n  width: 100%;\n}\n#editor-container .wangEditor-drop-panel textarea,\n#editor-container .txt-toolbar textarea {\n  border: 1px solid #ccc;\n}\n#editor-container .wangEditor-drop-panel textarea:focus,\n#editor-container .txt-toolbar textarea:focus {\n  outline: none;\n  border-color: #1e88e5;\n}\n#editor-container .wangEditor-drop-panel button,\n#editor-container .txt-toolbar button {\n  font-size: 14px;\n  color: #1e88e5;\n  border: none;\n  padding: 10px;\n  background-color: #fff;\n  cursor: pointer;\n  border-radius: 3px;\n}\n#editor-container .wangEditor-drop-panel button:hover,\n#editor-container .txt-toolbar button:hover {\n  background-color: #f1f1f1;\n}\n#editor-container .wangEditor-drop-panel button:focus,\n#editor-container .txt-toolbar button:focus {\n  outline: none;\n}\n#editor-container .wangEditor-drop-panel button.right,\n#editor-container .txt-toolbar button.right {\n  float: right;\n  margin-left: 10px;\n}\n#editor-container .wangEditor-drop-panel button.gray,\n#editor-container .txt-toolbar button.gray {\n  color: #999;\n}\n#editor-container .wangEditor-drop-panel button.link,\n#editor-container .txt-toolbar button.link {\n  padding: 5px 10px;\n}\n#editor-container .wangEditor-drop-panel button.link:hover,\n#editor-container .txt-toolbar button.link:hover {\n  background-color: #fff;\n  text-decoration: underline;\n}\n#editor-container .wangEditor-drop-panel .color-item,\n#editor-container .txt-toolbar .color-item {\n  display: block;\n  float: left;\n  width: 25px;\n  height: 25px;\n  text-align: center;\n  padding: 2px;\n  border-radius: 2px;\n  text-decoration: underline;\n}\n#editor-container .wangEditor-drop-panel .color-item:hover,\n#editor-container .txt-toolbar .color-item:hover {\n  background-color: #f1f1f1;\n}\n#editor-container .wangEditor-drop-panel .list-menu-item,\n#editor-container .txt-toolbar .list-menu-item {\n  display: block;\n  float: left;\n  color: #333;\n  padding: 5px 5px;\n  border-radius: 2px;\n}\n#editor-container .wangEditor-drop-panel .list-menu-item:hover,\n#editor-container .txt-toolbar .list-menu-item:hover {\n  background-color: #f1f1f1;\n}\n#editor-container .wangEditor-drop-panel table.choose-table,\n#editor-container .txt-toolbar table.choose-table {\n  border: none;\n  border-collapse: collapse;\n}\n#editor-container .wangEditor-drop-panel table.choose-table td,\n#editor-container .txt-toolbar table.choose-table td {\n  border: 1px solid #ccc;\n  width: 16px;\n  height: 12px;\n}\n#editor-container .wangEditor-drop-panel table.choose-table td.active,\n#editor-container .txt-toolbar table.choose-table td.active {\n  background-color: #ccc;\n  opacity: .5;\n  filter: alpha(opacity=50);\n}\n#editor-container .wangEditor-drop-panel .panel-tab .tab-container,\n#editor-container .txt-toolbar .panel-tab .tab-container {\n  margin-bottom: 5px;\n}\n#editor-container .wangEditor-drop-panel .panel-tab .tab-container a,\n#editor-container .txt-toolbar .panel-tab .tab-container a {\n  display: inline-block;\n  color: #999;\n  text-align: center;\n  margin: 0 5px;\n  padding: 5px 5px;\n}\n#editor-container .wangEditor-drop-panel .panel-tab .tab-container a.selected,\n#editor-container .txt-toolbar .panel-tab .tab-container a.selected {\n  color: #1e88e5;\n  border-bottom: 2px solid #1e88e5;\n}\n#editor-container .wangEditor-drop-panel .panel-tab .content-container .content,\n#editor-container .txt-toolbar .panel-tab .content-container .content {\n  display: none;\n}\n#editor-container .wangEditor-drop-panel .panel-tab .content-container .content a,\n#editor-container .txt-toolbar .panel-tab .content-container .content a {\n  display: inline-block;\n  margin: 2px;\n  padding: 2px;\n  border-radius: 2px;\n}\n#editor-container .wangEditor-drop-panel .panel-tab .content-container .content a:hover,\n#editor-container .txt-toolbar .panel-tab .content-container .content a:hover {\n  background-color: #f1f1f1;\n}\n#editor-container .wangEditor-drop-panel .panel-tab .content-container .selected,\n#editor-container .txt-toolbar .panel-tab .content-container .selected {\n  display: block;\n}\n#editor-container .wangEditor-drop-panel .panel-tab .emotion-content-container,\n#editor-container .txt-toolbar .panel-tab .emotion-content-container {\n  height: 200px;\n  overflow-y: auto;\n}\n#editor-container .wangEditor-drop-panel .upload-icon-container,\n#editor-container .txt-toolbar .upload-icon-container {\n  color: #ccc;\n  text-align: center;\n  margin: 20px 20px 15px 20px !important;\n  padding: 5px !important;\n  font-size: 65px;\n  cursor: pointer;\n  border: 2px dotted #f1f1f1;\n  display: block !important;\n}\n#editor-container .wangEditor-drop-panel .upload-icon-container:hover,\n#editor-container .txt-toolbar .upload-icon-container:hover {\n  color: #666;\n  border-color: #ccc;\n}\n#editor-container .wangEditor-modal {\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  background-color: #fff;\n  border-top: 1px solid #f1f1f1;\n  box-shadow: 1px 3px 3px #999;\n  border-top: 1px\\9 solid\\9 #ccc\\9;\n  border-left: 1px\\9 solid\\9 #ccc\\9;\n  border-bottom: 1px\\9 solid\\9 #999\\9;\n  border-right: 1px\\9 solid\\9 #999\\9;\n}\n#editor-container .wangEditor-modal .wangEditor-modal-close {\n  position: absolute;\n  top: 0;\n  right: 0;\n  margin-top: -25px;\n  margin-right: -25px;\n  font-size: 1.5em;\n  color: #666;\n  cursor: pointer;\n}\n@font-face {\n  font-family: 'icomoon';\nsrc: url('../fonts/icomoon.eot?-qdfu1s');\nsrc: url('../fonts/icomoon.eot?#iefix-qdfu1s') format('embedded-opentype'), url('../fonts/icomoon.ttf?-qdfu1s') format('truetype'), url('../fonts/icomoon.woff?-qdfu1s') format('woff'), url('../fonts/icomoon.svg?-qdfu1s#icomoon') format('svg');\nfont-weight: normal;\nfont-style: normal;\n}\n#editor-container [class^=\"wangeditor-menu-img-\"],\n#editor-container [class*=\" wangeditor-menu-img-\"] {\n  font-family: 'icomoon';\n  speak: none;\n  font-style: normal;\n  font-weight: normal;\n  font-variant: normal;\n  text-transform: none;\n  line-height: 1;\n  /* Better Font Rendering =========== */\n\n  -webkit-font-smoothing: antialiased;\n  -moz-osx-font-smoothing: grayscale;\n}\n#editor-container .wangeditor-menu-img-link:before {\n  content: \"\\e800\";\n}\n#editor-container .wangeditor-menu-img-unlink:before {\n  content: \"\\e801\";\n}\n#editor-container .wangeditor-menu-img-code:before {\n  content: \"\\e802\";\n}\n#editor-container .wangeditor-menu-img-cancel:before {\n  content: \"\\e803\";\n}\n#editor-container .wangeditor-menu-img-terminal:before {\n  content: \"\\e804\";\n}\n#editor-container .wangeditor-menu-img-angle-down:before {\n  content: \"\\e805\";\n}\n#editor-container .wangeditor-menu-img-font:before {\n  content: \"\\e806\";\n}\n#editor-container .wangeditor-menu-img-bold:before {\n  content: \"\\e807\";\n}\n#editor-container .wangeditor-menu-img-italic:before {\n  content: \"\\e808\";\n}\n#editor-container .wangeditor-menu-img-header:before {\n  content: \"\\e809\";\n}\n#editor-container .wangeditor-menu-img-align-left:before {\n  content: \"\\e80a\";\n}\n#editor-container .wangeditor-menu-img-align-center:before {\n  content: \"\\e80b\";\n}\n#editor-container .wangeditor-menu-img-align-right:before {\n  content: \"\\e80c\";\n}\n#editor-container .wangeditor-menu-img-list-bullet:before {\n  content: \"\\e80d\";\n}\n#editor-container .wangeditor-menu-img-indent-left:before {\n  content: \"\\e80e\";\n}\n#editor-container .wangeditor-menu-img-indent-right:before {\n  content: \"\\e80f\";\n}\n#editor-container .wangeditor-menu-img-list-numbered:before {\n  content: \"\\e810\";\n}\n#editor-container .wangeditor-menu-img-underline:before {\n  content: \"\\e811\";\n}\n#editor-container .wangeditor-menu-img-table:before {\n  content: \"\\e812\";\n}\n#editor-container .wangeditor-menu-img-eraser:before {\n  content: \"\\e813\";\n}\n#editor-container .wangeditor-menu-img-text-height:before {\n  content: \"\\e814\";\n}\n#editor-container .wangeditor-menu-img-brush:before {\n  content: \"\\e815\";\n}\n#editor-container .wangeditor-menu-img-pencil:before {\n  content: \"\\e816\";\n}\n#editor-container .wangeditor-menu-img-minus:before {\n  content: \"\\e817\";\n}\n#editor-container .wangeditor-menu-img-picture:before {\n  content: \"\\e818\";\n}\n#editor-container .wangeditor-menu-img-file-image:before {\n  content: \"\\e819\";\n}\n#editor-container .wangeditor-menu-img-cw:before {\n  content: \"\\e81a\";\n}\n#editor-container .wangeditor-menu-img-ccw:before {\n  content: \"\\e81b\";\n}\n#editor-container .wangeditor-menu-img-music:before {\n  content: \"\\e911\";\n}\n#editor-container .wangeditor-menu-img-play:before {\n  content: \"\\e912\";\n}\n#editor-container .wangeditor-menu-img-location:before {\n  content: \"\\e947\";\n}\n#editor-container .wangeditor-menu-img-happy:before {\n  content: \"\\e9df\";\n}\n#editor-container .wangeditor-menu-img-sigma:before {\n  content: \"\\ea67\";\n}\n#editor-container .wangeditor-menu-img-enlarge2:before {\n  content: \"\\e98b\";\n}\n#editor-container .wangeditor-menu-img-shrink2:before {\n  content: \"\\e98c\";\n}\n#editor-container .wangeditor-menu-img-newspaper:before {\n  content: \"\\e904\";\n}\n#editor-container .wangeditor-menu-img-camera:before {\n  content: \"\\e90f\";\n}\n#editor-container .wangeditor-menu-img-video-camera:before {\n  content: \"\\e914\";\n}\n#editor-container .wangeditor-menu-img-file-zip:before {\n  content: \"\\e92b\";\n}\n#editor-container .wangeditor-menu-img-stack:before {\n  content: \"\\e92e\";\n}\n#editor-container .wangeditor-menu-img-credit-card:before {\n  content: \"\\e93f\";\n}\n#editor-container .wangeditor-menu-img-address-book:before {\n  content: \"\\e944\";\n}\n#editor-container .wangeditor-menu-img-envelop:before {\n  content: \"\\e945\";\n}\n#editor-container .wangeditor-menu-img-drawer:before {\n  content: \"\\e95c\";\n}\n#editor-container .wangeditor-menu-img-download:before {\n  content: \"\\e960\";\n}\n#editor-container .wangeditor-menu-img-upload:before {\n  content: \"\\e961\";\n}\n#editor-container .wangeditor-menu-img-lock:before {\n  content: \"\\e98f\";\n}\n#editor-container .wangeditor-menu-img-unlocked:before {\n  content: \"\\e990\";\n}\n#editor-container .wangeditor-menu-img-wrench:before {\n  content: \"\\e991\";\n}\n#editor-container .wangeditor-menu-img-eye:before {\n  content: \"\\e9ce\";\n}\n#editor-container .wangeditor-menu-img-eye-blocked:before {\n  content: \"\\e9d1\";\n}\n#editor-container .wangeditor-menu-img-command:before {\n  content: \"\\ea4e\";\n}\n#editor-container .wangeditor-menu-img-font2:before {\n  content: \"\\ea5c\";\n}\n#editor-container .wangeditor-menu-img-libreoffice:before {\n  content: \"\\eade\";\n}\n#editor-container .wangeditor-menu-img-quotes-left:before {\n  content: \"\\e977\";\n}\n#editor-container .wangeditor-menu-img-strikethrough:before {\n  content: \"\\ea65\";\n}\n#editor-container .wangeditor-menu-img-desktop:before {\n  content: \"\\f108\";\n}\n#editor-container .wangeditor-menu-img-tablet:before {\n  content: \"\\f10a\";\n}\n#editor-container .wangeditor-menu-img-search-plus:before {\n  content: \"\\f00e\";\n}\n#editor-container .wangeditor-menu-img-search-minus:before {\n  content: \"\\f010\";\n}\n#editor-container .wangeditor-menu-img-trash-o:before {\n  content: \"\\f014\";\n}\n#editor-container .wangeditor-menu-img-align-justify:before {\n  content: \"\\f039\";\n}\n#editor-container .wangeditor-menu-img-arrows-v:before {\n  content: \"\\f07d\";\n}\n#editor-container .wangeditor-menu-img-sigma2:before {\n  content: \"\\ea68\";\n}\n#editor-container .wangeditor-menu-img-omega:before {\n  content: \"\\e900\";\n}\n#editor-container .wangeditor-menu-img-cancel-circle:before {\n  content: \"\\e901\";\n}\n#editor-container .hljs {\n  display: block;\n  overflow-x: auto;\n  padding: 0.5em;\n  color: #333;\n  background: #f8f8f8;\n  -webkit-text-size-adjust: none;\n}\n#editor-container .hljs-comment,\n#editor-container .diff .hljs-header {\n  color: #998;\n  font-style: italic;\n}\n#editor-container .hljs-keyword,\n#editor-container .css .rule .hljs-keyword,\n#editor-container .hljs-winutils,\n#editor-container .nginx .hljs-title,\n#editor-container .hljs-subst,\n#editor-container .hljs-request,\n#editor-container .hljs-status {\n  color: #333;\n  font-weight: bold;\n}\n#editor-container .hljs-number,\n#editor-container .hljs-hexcolor,\n#editor-container .ruby .hljs-constant {\n  color: #008080;\n}\n#editor-container .hljs-string,\n#editor-container .hljs-tag .hljs-value,\n#editor-container .hljs-doctag,\n#editor-container .tex .hljs-formula {\n  color: #d14;\n}\n#editor-container .hljs-title,\n#editor-container .hljs-id,\n#editor-container .scss .hljs-preprocessor {\n  color: #900;\n  font-weight: bold;\n}\n#editor-container .hljs-list .hljs-keyword,\n#editor-container .hljs-subst {\n  font-weight: normal;\n}\n#editor-container .hljs-class .hljs-title,\n#editor-container .hljs-type,\n#editor-container .vhdl .hljs-literal,\n#editor-container .tex .hljs-command {\n  color: #458;\n  font-weight: bold;\n}\n#editor-container .hljs-tag,\n#editor-container .hljs-tag .hljs-title,\n#editor-container .hljs-rule .hljs-property,\n#editor-container .django .hljs-tag .hljs-keyword {\n  color: #000080;\n  font-weight: normal;\n}\n#editor-container .hljs-attribute,\n#editor-container .hljs-variable,\n#editor-container .lisp .hljs-body,\n#editor-container .hljs-name {\n  color: #008080;\n}\n#editor-container .hljs-regexp {\n  color: #009926;\n}\n#editor-container .hljs-symbol,\n#editor-container .ruby .hljs-symbol .hljs-string,\n#editor-container .lisp .hljs-keyword,\n#editor-container .clojure .hljs-keyword,\n#editor-container .scheme .hljs-keyword,\n#editor-container .tex .hljs-special,\n#editor-container .hljs-prompt {\n  color: #990073;\n}\n#editor-container .hljs-built_in {\n  color: #0086b3;\n}\n#editor-container .hljs-preprocessor,\n#editor-container .hljs-pragma,\n#editor-container .hljs-pi,\n#editor-container .hljs-doctype,\n#editor-container .hljs-shebang,\n#editor-container .hljs-cdata {\n  color: #999;\n  font-weight: bold;\n}\n#editor-container .hljs-deletion {\n  background: #fdd;\n}\n#editor-container .hljs-addition {\n  background: #dfd;\n}\n#editor-container .diff .hljs-change {\n  background: #0086b3;\n}\n#editor-container .hljs-chunk {\n  color: #aaa;\n}\n"
  },
  {
    "path": "public/static/plugins/wangeditor/js/lib/jquery-2.2.1.js",
    "content": "/*!\n * jQuery JavaScript Library v2.2.1\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2016-02-22T19:11Z\n */\n\n(function( global, factory ) {\n\n\tif ( typeof module === \"object\" && typeof module.exports === \"object\" ) {\n\t\t// For CommonJS and CommonJS-like environments where a proper `window`\n\t\t// is present, execute the factory and get jQuery.\n\t\t// For environments that do not have a `window` with a `document`\n\t\t// (such as Node.js), expose a factory as module.exports.\n\t\t// This accentuates the need for the creation of a real `window`.\n\t\t// e.g. var jQuery = require(\"jquery\")(window);\n\t\t// See ticket #14549 for more info.\n\t\tmodule.exports = global.document ?\n\t\t\tfactory( global, true ) :\n\t\t\tfunction( w ) {\n\t\t\t\tif ( !w.document ) {\n\t\t\t\t\tthrow new Error( \"jQuery requires a window with a document\" );\n\t\t\t\t}\n\t\t\t\treturn factory( w );\n\t\t\t};\n\t} else {\n\t\tfactory( global );\n\t}\n\n// Pass this if window is not defined yet\n}(typeof window !== \"undefined\" ? window : this, function( window, noGlobal ) {\n\n// Support: Firefox 18+\n// Can't be in strict mode, several libs including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n//\"use strict\";\nvar arr = [];\n\nvar document = window.document;\n\nvar slice = arr.slice;\n\nvar concat = arr.concat;\n\nvar push = arr.push;\n\nvar indexOf = arr.indexOf;\n\nvar class2type = {};\n\nvar toString = class2type.toString;\n\nvar hasOwn = class2type.hasOwnProperty;\n\nvar support = {};\n\n\n\nvar\n\tversion = \"2.2.1\",\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\t// Need init if jQuery is called (just allow error to be thrown if not included)\n\t\treturn new jQuery.fn.init( selector, context );\n\t},\n\n\t// Support: Android<4.1\n\t// Make sure we trim BOM and NBSP\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t};\n\njQuery.fn = jQuery.prototype = {\n\n\t// The current version of jQuery being used\n\tjquery: version,\n\n\tconstructor: jQuery,\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num != null ?\n\n\t\t\t// Return just the one element from the set\n\t\t\t( num < 0 ? this[ num + this.length ] : this[ num ] ) :\n\n\t\t\t// Return all the elements in a clean array\n\t\t\tslice.call( this );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\teach: function( callback ) {\n\t\treturn jQuery.each( this, callback );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map( this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t} ) );\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor();\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: push,\n\tsort: arr.sort,\n\tsplice: arr.splice\n};\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar options, name, src, copy, copyIsArray, clone,\n\t\ttarget = arguments[ 0 ] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\n\t\t// Skip the boolean and the target\n\t\ttarget = arguments[ i ] || {};\n\t\ti++;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction( target ) ) {\n\t\ttarget = {};\n\t}\n\n\t// Extend jQuery itself if only one argument is passed\n\tif ( i === length ) {\n\t\ttarget = this;\n\t\ti--;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\n\t\t// Only deal with non-null/undefined values\n\t\tif ( ( options = arguments[ i ] ) != null ) {\n\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject( copy ) ||\n\t\t\t\t\t( copyIsArray = jQuery.isArray( copy ) ) ) ) {\n\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray( src ) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject( src ) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend( {\n\n\t// Unique for each copy of jQuery on the page\n\texpando: \"jQuery\" + ( version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\t// Assume jQuery is ready without the ready module\n\tisReady: true,\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\tnoop: function() {},\n\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type( obj ) === \"function\";\n\t},\n\n\tisArray: Array.isArray,\n\n\tisWindow: function( obj ) {\n\t\treturn obj != null && obj === obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\n\t\t// parseFloat NaNs numeric-cast false positives (null|true|false|\"\")\n\t\t// ...but misinterprets leading-number strings, particularly hex literals (\"0x...\")\n\t\t// subtraction forces infinities to NaN\n\t\t// adding 1 corrects loss of precision from parseFloat (#15100)\n\t\tvar realStringObj = obj && obj.toString();\n\t\treturn !jQuery.isArray( obj ) && ( realStringObj - parseFloat( realStringObj ) + 1 ) >= 0;\n\t},\n\n\tisPlainObject: function( obj ) {\n\n\t\t// Not plain objects:\n\t\t// - Any object or value whose internal [[Class]] property is not \"[object Object]\"\n\t\t// - DOM nodes\n\t\t// - window\n\t\tif ( jQuery.type( obj ) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif ( obj.constructor &&\n\t\t\t\t!hasOwn.call( obj.constructor.prototype, \"isPrototypeOf\" ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\t// If the function hasn't returned already, we're confident that\n\t\t// |obj| is a plain object, created by {} or constructed with new Object\n\t\treturn true;\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn obj + \"\";\n\t\t}\n\n\t\t// Support: Android<4.0, iOS<6 (functionish RegExp)\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ toString.call( obj ) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\t// Evaluates a script in a global context\n\tglobalEval: function( code ) {\n\t\tvar script,\n\t\t\tindirect = eval;\n\n\t\tcode = jQuery.trim( code );\n\n\t\tif ( code ) {\n\n\t\t\t// If the code includes a valid, prologue position\n\t\t\t// strict mode pragma, execute code by injecting a\n\t\t\t// script tag into the document.\n\t\t\tif ( code.indexOf( \"use strict\" ) === 1 ) {\n\t\t\t\tscript = document.createElement( \"script\" );\n\t\t\t\tscript.text = code;\n\t\t\t\tdocument.head.appendChild( script ).parentNode.removeChild( script );\n\t\t\t} else {\n\n\t\t\t\t// Otherwise, avoid the DOM node creation, insertion\n\t\t\t\t// and removal by using an indirect global eval\n\n\t\t\t\tindirect( code );\n\t\t\t}\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Support: IE9-11+\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\teach: function( obj, callback ) {\n\t\tvar length, i = 0;\n\n\t\tif ( isArrayLike( obj ) ) {\n\t\t\tlength = obj.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tfor ( i in obj ) {\n\t\t\t\tif ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Support: Android<4.1\n\ttrim: function( text ) {\n\t\treturn text == null ?\n\t\t\t\"\" :\n\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArrayLike( Object( arr ) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tpush.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\treturn arr == null ? -1 : indexOf.call( arr, elem, i );\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar len = +second.length,\n\t\t\tj = 0,\n\t\t\ti = first.length;\n\n\t\tfor ( ; j < len; j++ ) {\n\t\t\tfirst[ i++ ] = second[ j ];\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, invert ) {\n\t\tvar callbackInverse,\n\t\t\tmatches = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tcallbackExpect = !invert;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tcallbackInverse = !callback( elems[ i ], i );\n\t\t\tif ( callbackInverse !== callbackExpect ) {\n\t\t\t\tmatches.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn matches;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar length, value,\n\t\t\ti = 0,\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their new values\n\t\tif ( isArrayLike( elems ) ) {\n\t\t\tlength = elems.length;\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret.push( value );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar tmp, args, proxy;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\tnow: Date.now,\n\n\t// jQuery.support is not used in Core but other projects attach their\n\t// properties to it so it needs to exist.\n\tsupport: support\n} );\n\n// JSHint would error on this code due to the Symbol not being defined in ES5.\n// Defining this global in .jshintrc would create a danger of using the global\n// unguarded in another place, it seems safer to just disable JSHint for these\n// three lines.\n/* jshint ignore: start */\nif ( typeof Symbol === \"function\" ) {\n\tjQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];\n}\n/* jshint ignore: end */\n\n// Populate the class2type map\njQuery.each( \"Boolean Number String Function Array Date RegExp Object Error Symbol\".split( \" \" ),\nfunction( i, name ) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n} );\n\nfunction isArrayLike( obj ) {\n\n\t// Support: iOS 8.2 (not reproducible in simulator)\n\t// `in` check used to prevent JIT error (gh-2145)\n\t// hasOwn isn't used here due to false negatives\n\t// regarding Nodelist length in IE\n\tvar length = !!obj && \"length\" in obj && obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( type === \"function\" || jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\treturn type === \"array\" || length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj;\n}\nvar Sizzle =\n/*!\n * Sizzle CSS Selector Engine v2.2.1\n * http://sizzlejs.com/\n *\n * Copyright jQuery Foundation and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2015-10-17\n */\n(function( window ) {\n\nvar i,\n\tsupport,\n\tExpr,\n\tgetText,\n\tisXML,\n\ttokenize,\n\tcompile,\n\tselect,\n\toutermostContext,\n\tsortInput,\n\thasDuplicate,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + 1 * new Date(),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf as it's faster than native\n\t// http://jsperf.com/thor-indexof-vs-for/5\n\tindexOf = function( list, elem ) {\n\t\tvar i = 0,\n\t\t\tlen = list.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( list[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\n\t// http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + identifier + \")(?:\" + whitespace +\n\t\t// Operator (capture 2)\n\t\t\"*([*^$|!~]?=)\" + whitespace +\n\t\t// \"Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]\"\n\t\t\"*(?:'((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\"|(\" + identifier + \"))|)\" + whitespace +\n\t\t\"*\\\\]\",\n\n\tpseudos = \":(\" + identifier + \")(?:\\\\((\" +\n\t\t// To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:\n\t\t// 1. quoted (capture 3; capture 4 or capture 5)\n\t\t\"('((?:\\\\\\\\.|[^\\\\\\\\'])*)'|\\\"((?:\\\\\\\\.|[^\\\\\\\\\\\"])*)\\\")|\" +\n\t\t// 2. simple (capture 6)\n\t\t\"((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes + \")*)|\" +\n\t\t// 3. anything else (capture 2)\n\t\t\".*\" +\n\t\t\")\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trwhitespace = new RegExp( whitespace + \"+\", \"g\" ),\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*?)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + identifier + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + identifier + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + identifier + \"|[*])\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trsibling = /[+~]/,\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox<24\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\thigh < 0 ?\n\t\t\t\t// BMP codepoint\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t},\n\n\t// Used for iframes\n\t// See setDocument()\n\t// Removing the function wrapper causes a \"Permission Denied\"\n\t// error in IE\n\tunloadHandler = function() {\n\t\tsetDocument();\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar m, i, elem, nid, nidselect, match, groups, newSelector,\n\t\tnewContext = context && context.ownerDocument,\n\n\t\t// nodeType defaults to 9, since context defaults to document\n\t\tnodeType = context ? context.nodeType : 9;\n\n\tresults = results || [];\n\n\t// Return early from calls with invalid selector or context\n\tif ( typeof selector !== \"string\" || !selector ||\n\t\tnodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {\n\n\t\treturn results;\n\t}\n\n\t// Try to shortcut find operations (as opposed to filters) in HTML documents\n\tif ( !seed ) {\n\n\t\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\t\tsetDocument( context );\n\t\t}\n\t\tcontext = context || document;\n\n\t\tif ( documentIsHTML ) {\n\n\t\t\t// If the selector is sufficiently simple, try using a \"get*By*\" DOM method\n\t\t\t// (excepting DocumentFragment context, where the methods don't exist)\n\t\t\tif ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {\n\n\t\t\t\t// ID selector\n\t\t\t\tif ( (m = match[1]) ) {\n\n\t\t\t\t\t// Document context\n\t\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\t\tif ( (elem = context.getElementById( m )) ) {\n\n\t\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// Element context\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// Support: IE, Opera, Webkit\n\t\t\t\t\t\t// TODO: identify versions\n\t\t\t\t\t\t// getElementById can match elements by name instead of ID\n\t\t\t\t\t\tif ( newContext && (elem = newContext.getElementById( m )) &&\n\t\t\t\t\t\t\tcontains( context, elem ) &&\n\t\t\t\t\t\t\telem.id === m ) {\n\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t// Type selector\n\t\t\t\t} else if ( match[2] ) {\n\t\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\t\treturn results;\n\n\t\t\t\t// Class selector\n\t\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName &&\n\t\t\t\t\tcontext.getElementsByClassName ) {\n\n\t\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Take advantage of querySelectorAll\n\t\t\tif ( support.qsa &&\n\t\t\t\t!compilerCache[ selector + \" \" ] &&\n\t\t\t\t(!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\n\t\t\t\tif ( nodeType !== 1 ) {\n\t\t\t\t\tnewContext = context;\n\t\t\t\t\tnewSelector = selector;\n\n\t\t\t\t// qSA looks outside Element context, which is not what we want\n\t\t\t\t// Thanks to Andrew Dupont for this workaround technique\n\t\t\t\t// Support: IE <=8\n\t\t\t\t// Exclude object elements\n\t\t\t\t} else if ( context.nodeName.toLowerCase() !== \"object\" ) {\n\n\t\t\t\t\t// Capture the context ID, setting it first if necessary\n\t\t\t\t\tif ( (nid = context.getAttribute( \"id\" )) ) {\n\t\t\t\t\t\tnid = nid.replace( rescape, \"\\\\$&\" );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcontext.setAttribute( \"id\", (nid = expando) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prefix every selector in the list\n\t\t\t\t\tgroups = tokenize( selector );\n\t\t\t\t\ti = groups.length;\n\t\t\t\t\tnidselect = ridentifier.test( nid ) ? \"#\" + nid : \"[id='\" + nid + \"']\";\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tgroups[i] = nidselect + \" \" + toSelector( groups[i] );\n\t\t\t\t\t}\n\t\t\t\t\tnewSelector = groups.join( \",\" );\n\n\t\t\t\t\t// Expand context for sibling selectors\n\t\t\t\t\tnewContext = rsibling.test( selector ) && testContext( context.parentNode ) ||\n\t\t\t\t\t\tcontext;\n\t\t\t\t}\n\n\t\t\t\tif ( newSelector ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t\t);\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t} catch ( qsaError ) {\n\t\t\t\t\t} finally {\n\t\t\t\t\t\tif ( nid === expando ) {\n\t\t\t\t\t\t\tcontext.removeAttribute( \"id\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {function(string, object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key + \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key + \" \" ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = arr.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Checks a node for validity as a Sizzle context\n * @param {Element|Object=} context\n * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value\n */\nfunction testContext( context ) {\n\treturn context && typeof context.getElementsByTagName !== \"undefined\" && context;\n}\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Detects XML nodes\n * @param {Element|Object} elem An element or a document\n * @returns {Boolean} True iff elem is a non-HTML XML node\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar hasCompare, parent,\n\t\tdoc = node ? node.ownerDocument || node : preferredDoc;\n\n\t// Return early if doc is invalid or already selected\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Update global variables\n\tdocument = doc;\n\tdocElem = document.documentElement;\n\tdocumentIsHTML = !isXML( document );\n\n\t// Support: IE 9-11, Edge\n\t// Accessing iframe documents after unload throws \"permission denied\" errors (jQuery #13936)\n\tif ( (parent = document.defaultView) && parent.top !== parent ) {\n\t\t// Support: IE 11\n\t\tif ( parent.addEventListener ) {\n\t\t\tparent.addEventListener( \"unload\", unloadHandler, false );\n\n\t\t// Support: IE 9 - 10 only\n\t\t} else if ( parent.attachEvent ) {\n\t\t\tparent.attachEvent( \"onunload\", unloadHandler );\n\t\t}\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties\n\t// (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( document.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Support: IE<9\n\tsupport.getElementsByClassName = rnative.test( document.getElementsByClassName );\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !document.getElementsByName || !document.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== \"undefined\" && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\treturn m ? [ m ] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== \"undefined\" &&\n\t\t\t\t\telem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== \"undefined\" ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\n\t\t\t// DocumentFragment nodes don't have gEBTN\n\t\t\t} else if ( support.qsa ) {\n\t\t\t\treturn context.querySelectorAll( tag );\n\t\t\t}\n\t\t} :\n\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\t// By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes too\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== \"undefined\" && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( document.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdocElem.appendChild( div ).innerHTML = \"<a id='\" + expando + \"'></a>\" +\n\t\t\t\t\"<select id='\" + expando + \"-\\r\\\\' msallowcapture=''>\" +\n\t\t\t\t\"<option selected=''></option></select>\";\n\n\t\t\t// Support: IE8, Opera 11-12.16\n\t\t\t// Nothing should be selected when empty strings follow ^= or $= or *=\n\t\t\t// The test attribute must be unknown in Opera but \"safe\" for WinRT\n\t\t\t// http://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section\n\t\t\tif ( div.querySelectorAll(\"[msallowcapture^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+\n\t\t\tif ( !div.querySelectorAll( \"[id~=\" + expando + \"-]\" ).length ) {\n\t\t\t\trbuggyQSA.push(\"~=\");\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\n\t\t\t// Support: Safari 8+, iOS 8+\n\t\t\t// https://bugs.webkit.org/show_bug.cgi?id=136851\n\t\t\t// In-page `selector#id sibing-combinator selector` fails\n\t\t\tif ( !div.querySelectorAll( \"a#\" + expando + \"+*\" ).length ) {\n\t\t\t\trbuggyQSA.push(\".#.+[+~]\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type and name attributes are restricted during .innerHTML assignment\n\t\t\tvar input = document.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"name\", \"D\" );\n\n\t\t\t// Support: IE8\n\t\t\t// Enforce case-sensitivity of name attribute\n\t\t\tif ( div.querySelectorAll(\"[name=d]\").length ) {\n\t\t\t\trbuggyQSA.push( \"name\" + whitespace + \"*[*^$|!~]?=\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||\n\t\tdocElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\thasCompare = rnative.test( docElem.compareDocumentPosition );\n\n\t// Element contains another\n\t// Purposefully self-exclusive\n\t// As in, an element does not contain itself\n\tcontains = hasCompare || rnative.test( docElem.contains ) ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = hasCompare ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Sort on method existence if only one input has compareDocumentPosition\n\t\tvar compare = !a.compareDocumentPosition - !b.compareDocumentPosition;\n\t\tif ( compare ) {\n\t\t\treturn compare;\n\t\t}\n\n\t\t// Calculate position if both inputs belong to the same document\n\t\tcompare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?\n\t\t\ta.compareDocumentPosition( b ) :\n\n\t\t\t// Otherwise we know they are disconnected\n\t\t\t1;\n\n\t\t// Disconnected nodes\n\t\tif ( compare & 1 ||\n\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t// Choose the first element that is related to our preferred document\n\t\t\tif ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\tif ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) ) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t// Maintain original order\n\t\t\treturn sortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\t\t}\n\n\t\treturn compare & 4 ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\tif ( !aup || !bup ) {\n\t\t\treturn a === document ? -1 :\n\t\t\t\tb === document ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn document;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t!compilerCache[ expr + \" \" ] &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch (e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [ elem ] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val !== undefined ?\n\t\tval :\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\t// Clear input after sorting to release objects\n\t// See https://github.com/jquery/sizzle/pull/225\n\tsortInput = null;\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\twhile ( (node = elem[i++]) ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (jQuery #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[3] || match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[6] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] ) {\n\t\t\t\tmatch[2] = match[4] || match[5] || \"\";\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== \"undefined\" && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result.replace( rwhitespace, \" \" ) + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, uniqueCache, outerCache, node, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType,\n\t\t\t\t\t\tdiff = false;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) {\n\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\n\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\tnode = parent;\n\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\tdiff = nodeIndex && cache[ 2 ];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t// ...in a gzip-friendly way\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\tcache = uniqueCache[ type ] || [];\n\t\t\t\t\t\t\t\tnodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];\n\t\t\t\t\t\t\t\tdiff = nodeIndex;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// xml :nth-child(...)\n\t\t\t\t\t\t\t// or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t\tif ( diff === false ) {\n\t\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t\tif ( ( ofType ?\n\t\t\t\t\t\t\t\t\t\tnode.nodeName.toLowerCase() === name :\n\t\t\t\t\t\t\t\t\t\tnode.nodeType === 1 ) &&\n\t\t\t\t\t\t\t\t\t\t++diff ) {\n\n\t\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t\touterCache = node[ expando ] || (node[ expando ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache = outerCache[ node.uniqueID ] ||\n\t\t\t\t\t\t\t\t\t\t\t\t(outerCache[ node.uniqueID ] = {});\n\n\t\t\t\t\t\t\t\t\t\t\tuniqueCache[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\t// Don't keep the element (issue #299)\n\t\t\t\t\tinput[0] = null;\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\ttext = text.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 5),\n\t\t\t//   but not by others (comment: 8; processing instruction: 7; etc.)\n\t\t\t// nodeType < 6 works because attributes (2) do not appear as children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeType < 6 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\n\t\t\t\t// Support: IE<8\n\t\t\t\t// New HTML5 attribute values (e.g., \"search\") appear with elem.type === \"text\"\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === \"text\" );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\ntokenize = Sizzle.tokenize = function( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( (tokens = []) );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n};\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar oldCache, uniqueCache, outerCache,\n\t\t\t\tnewCache = [ dirruns, doneName ];\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from combinator caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\n\t\t\t\t\t\t// Support: IE <9 only\n\t\t\t\t\t\t// Defend against cloned attroperties (jQuery gh-1709)\n\t\t\t\t\t\tuniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ elem.uniqueID ] = {});\n\n\t\t\t\t\t\tif ( (oldCache = uniqueCache[ dir ]) &&\n\t\t\t\t\t\t\toldCache[ 0 ] === dirruns && oldCache[ 1 ] === doneName ) {\n\n\t\t\t\t\t\t\t// Assign to newCache so results back-propagate to previous elements\n\t\t\t\t\t\t\treturn (newCache[ 2 ] = oldCache[ 2 ]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Reuse newcache so results back-propagate to previous elements\n\t\t\t\t\t\t\tuniqueCache[ dir ] = newCache;\n\n\t\t\t\t\t\t\t// A match means we're done; a fail means we have to keep checking\n\t\t\t\t\t\t\tif ( (newCache[ 2 ] = matcher( elem, context, xml )) ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\tvar ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t\t// Avoid hanging onto element (issue #299)\n\t\t\tcheckContext = null;\n\t\t\treturn ret;\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\tvar bySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, outermost ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\tsetMatched = [],\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or outermost context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", outermost ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),\n\t\t\t\tlen = elems.length;\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context === document || context || outermost;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Support: IE<9, Safari\n\t\t\t// Tolerate NodeList properties (IE: \"length\"; Safari: <number>) matching elements by id\n\t\t\tfor ( ; i !== len && (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\tif ( !context && elem.ownerDocument !== document ) {\n\t\t\t\t\t\tsetDocument( elem );\n\t\t\t\t\t\txml = !documentIsHTML;\n\t\t\t\t\t}\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context || document, xml) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// `i` is now the count of elements visited above, and adding it to `matchedCount`\n\t\t\t// makes the latter nonnegative.\n\t\t\tmatchedCount += i;\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\t// NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`\n\t\t\t// equals `i`), unless we didn't visit _any_ elements in the above loop because we have\n\t\t\t// no element matchers and no seed.\n\t\t\t// Incrementing an initially-string \"0\" `i` allows `i` to remain a string only in that\n\t\t\t// case, which will result in a \"00\" `matchedCount` that differs from `i` but is also\n\t\t\t// numerically zero.\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !match ) {\n\t\t\tmatch = tokenize( selector );\n\t\t}\n\t\ti = match.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( match[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\n\t\t// Save selector and tokenization\n\t\tcached.selector = selector;\n\t}\n\treturn cached;\n};\n\n/**\n * A low-level selection function that works with Sizzle's compiled\n *  selector functions\n * @param {String|Function} selector A selector or a pre-compiled\n *  selector function built with Sizzle.compile\n * @param {Element} context\n * @param {Array} [results]\n * @param {Array} [seed] A set of elements to match against\n */\nselect = Sizzle.select = function( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tcompiled = typeof selector === \"function\" && selector,\n\t\tmatch = !seed && tokenize( (selector = compiled.selector || selector) );\n\n\tresults = results || [];\n\n\t// Try to minimize operations if there is only one selector in the list and no seed\n\t// (the latter of which guarantees us context)\n\tif ( match.length === 1 ) {\n\n\t\t// Reduce context if the leading compound selector is an ID\n\t\ttokens = match[0] = match[0].slice( 0 );\n\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\tif ( !context ) {\n\t\t\t\treturn results;\n\n\t\t\t// Precompiled matchers will still verify ancestry, so step up a level\n\t\t\t} else if ( compiled ) {\n\t\t\t\tcontext = context.parentNode;\n\t\t\t}\n\n\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t}\n\n\t\t// Fetch a seed set for right-to-left matching\n\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\twhile ( i-- ) {\n\t\t\ttoken = tokens[i];\n\n\t\t\t// Abort if we hit a combinator\n\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\tif ( (seed = find(\n\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\trsibling.test( tokens[0].type ) && testContext( context.parentNode ) || context\n\t\t\t\t)) ) {\n\n\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function if one is not provided\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\t( compiled || compile( selector, match ) )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\t!context || rsibling.test( selector ) && testContext( context.parentNode ) || context\n\t);\n\treturn results;\n};\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome 14-35+\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = !!hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"<input/>\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn elem[ name ] === true ? name.toLowerCase() :\n\t\t\t\t\t(val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\t\tval.value :\n\t\t\t\tnull;\n\t\t}\n\t});\n}\n\nreturn Sizzle;\n\n})( window );\n\n\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[ \":\" ] = jQuery.expr.pseudos;\njQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n\nvar dir = function( elem, dir, until ) {\n\tvar matched = [],\n\t\ttruncate = until !== undefined;\n\n\twhile ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {\n\t\tif ( elem.nodeType === 1 ) {\n\t\t\tif ( truncate && jQuery( elem ).is( until ) ) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tmatched.push( elem );\n\t\t}\n\t}\n\treturn matched;\n};\n\n\nvar siblings = function( n, elem ) {\n\tvar matched = [];\n\n\tfor ( ; n; n = n.nextSibling ) {\n\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\tmatched.push( n );\n\t\t}\n\t}\n\n\treturn matched;\n};\n\n\nvar rneedsContext = jQuery.expr.match.needsContext;\n\nvar rsingleTag = ( /^<([\\w-]+)\\s*\\/?>(?:<\\/\\1>|)$/ );\n\n\n\nvar risSimple = /^.[^:#\\[\\.,]*$/;\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t} );\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t} );\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( risSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( indexOf.call( qualifier, elem ) > -1 ) !== not;\n\t} );\n}\n\njQuery.filter = function( expr, elems, not ) {\n\tvar elem = elems[ 0 ];\n\n\tif ( not ) {\n\t\texpr = \":not(\" + expr + \")\";\n\t}\n\n\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\treturn elem.nodeType === 1;\n\t\t} ) );\n};\n\njQuery.fn.extend( {\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tlen = this.length,\n\t\t\tret = [],\n\t\t\tself = this;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter( function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} ) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], false ) );\n\t},\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow( this, selector || [], true ) );\n\t},\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t}\n} );\n\n\n// Initialize a jQuery object\n\n\n// A central reference to the root jQuery(document)\nvar rootjQuery,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\tinit = jQuery.fn.init = function( selector, context, root ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Method init() accepts an alternate rootjQuery\n\t\t// so migrate can support jQuery.sub (gh-2101)\n\t\troot = root || rootjQuery;\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector[ 0 ] === \"<\" &&\n\t\t\t\tselector[ selector.length - 1 ] === \">\" &&\n\t\t\t\tselector.length >= 3 ) {\n\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && ( match[ 1 ] || !context ) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[ 1 ] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[ 0 ] : context;\n\n\t\t\t\t\t// Option to run scripts is true for back-compat\n\t\t\t\t\t// Intentionally let the error be thrown if parseHTML is not present\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[ 1 ],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[ 2 ] );\n\n\t\t\t\t\t// Support: Blackberry 4.6\n\t\t\t\t\t// gEBID returns nodes no longer in the document (#6963)\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\n\t\t\t\t\t\t// Inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[ 0 ] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || root ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[ 0 ] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn root.ready !== undefined ?\n\t\t\t\troot.ready( selector ) :\n\n\t\t\t\t// Execute immediately if ready is not present\n\t\t\t\tselector( jQuery );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t};\n\n// Give the init function the jQuery prototype for later instantiation\ninit.prototype = jQuery.fn;\n\n// Initialize central reference\nrootjQuery = jQuery( document );\n\n\nvar rparentsprev = /^(?:parents|prev(?:Until|All))/,\n\n\t// Methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend( {\n\thas: function( target ) {\n\t\tvar targets = jQuery( target, this ),\n\t\t\tl = targets.length;\n\n\t\treturn this.filter( function() {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[ i ] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tmatched = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {\n\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && ( pos ?\n\t\t\t\t\tpos.index( cur ) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector( cur, selectors ) ) ) {\n\n\t\t\t\t\tmatched.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );\n\t},\n\n\t// Determine the position of an element within the set\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// Index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn indexOf.call( jQuery( elem ), this[ 0 ] );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn indexOf.call( this,\n\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[ 0 ] : elem\n\t\t);\n\t},\n\n\tadd: function( selector, context ) {\n\t\treturn this.pushStack(\n\t\t\tjQuery.uniqueSort(\n\t\t\t\tjQuery.merge( this.get(), jQuery( selector, context ) )\n\t\t\t)\n\t\t);\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter( selector )\n\t\t);\n\t}\n} );\n\nfunction sibling( cur, dir ) {\n\twhile ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}\n\treturn cur;\n}\n\njQuery.each( {\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn siblings( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn siblings( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn elem.contentDocument || jQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar matched = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tmatched = jQuery.filter( selector, matched );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tjQuery.uniqueSort( matched );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tmatched.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( matched );\n\t};\n} );\nvar rnotwhite = ( /\\S+/g );\n\n\n\n// Convert String-formatted options into Object-formatted ones\nfunction createOptions( options ) {\n\tvar object = {};\n\tjQuery.each( options.match( rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t} );\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\tcreateOptions( options ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\n\t\t// Last fire value for non-forgettable lists\n\t\tmemory,\n\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\n\t\t// Flag to prevent firing\n\t\tlocked,\n\n\t\t// Actual callback list\n\t\tlist = [],\n\n\t\t// Queue of execution data for repeatable lists\n\t\tqueue = [],\n\n\t\t// Index of currently firing callback (modified by add/remove as needed)\n\t\tfiringIndex = -1,\n\n\t\t// Fire callbacks\n\t\tfire = function() {\n\n\t\t\t// Enforce single-firing\n\t\t\tlocked = options.once;\n\n\t\t\t// Execute callbacks for all pending executions,\n\t\t\t// respecting firingIndex overrides and runtime changes\n\t\t\tfired = firing = true;\n\t\t\tfor ( ; queue.length; firingIndex = -1 ) {\n\t\t\t\tmemory = queue.shift();\n\t\t\t\twhile ( ++firingIndex < list.length ) {\n\n\t\t\t\t\t// Run callback and check for early termination\n\t\t\t\t\tif ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false &&\n\t\t\t\t\t\toptions.stopOnFalse ) {\n\n\t\t\t\t\t\t// Jump to end and forget the data so .add doesn't re-fire\n\t\t\t\t\t\tfiringIndex = list.length;\n\t\t\t\t\t\tmemory = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Forget the data if we're done with it\n\t\t\tif ( !options.memory ) {\n\t\t\t\tmemory = false;\n\t\t\t}\n\n\t\t\tfiring = false;\n\n\t\t\t// Clean up if we're done firing for good\n\t\t\tif ( locked ) {\n\n\t\t\t\t// Keep an empty list if we have data for future add calls\n\t\t\t\tif ( memory ) {\n\t\t\t\t\tlist = [];\n\n\t\t\t\t// Otherwise, this object is spent\n\t\t\t\t} else {\n\t\t\t\t\tlist = \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t// Actual Callbacks object\n\t\tself = {\n\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\n\t\t\t\t\t// If we have memory from a past run, we should fire after adding\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfiringIndex = list.length - 1;\n\t\t\t\t\t\tqueue.push( memory );\n\t\t\t\t\t}\n\n\t\t\t\t\t( function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tif ( jQuery.isFunction( arg ) ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && jQuery.type( arg ) !== \"string\" ) {\n\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} );\n\t\t\t\t\t} )( arguments );\n\n\t\t\t\t\tif ( memory && !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\tvar index;\n\t\t\t\t\twhile ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\tlist.splice( index, 1 );\n\n\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ?\n\t\t\t\t\tjQuery.inArray( fn, list ) > -1 :\n\t\t\t\t\tlist.length > 0;\n\t\t\t},\n\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Disable .fire and .add\n\t\t\t// Abort any current/pending executions\n\t\t\t// Clear all callbacks and values\n\t\t\tdisable: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tlist = memory = \"\";\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\n\t\t\t// Disable .fire\n\t\t\t// Also disable .add unless we have memory (since it would have no effect)\n\t\t\t// Abort any pending executions\n\t\t\tlock: function() {\n\t\t\t\tlocked = queue = [];\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tlist = memory = \"\";\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\tlocked: function() {\n\t\t\t\treturn !!locked;\n\t\t\t},\n\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( !locked ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tqueue.push( args );\n\t\t\t\t\tif ( !firing ) {\n\t\t\t\t\t\tfire();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\n\n\njQuery.extend( {\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks( \"once memory\" ), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks( \"once memory\" ), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks( \"memory\" ) ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred( function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar fn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[ 1 ] ]( function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify )\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ tuple[ 0 ] + \"With\" ](\n\t\t\t\t\t\t\t\t\t\tthis === promise ? newDefer.promise() : this,\n\t\t\t\t\t\t\t\t\t\tfn ? [ returned ] : arguments\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t} );\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t} ).promise();\n\t\t\t\t},\n\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[ 1 ] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add( function() {\n\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[ 0 ] ] = function() {\n\t\t\t\tdeferred[ tuple[ 0 ] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[ 0 ] + \"With\" ] = list.fireWith;\n\t\t} );\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 ||\n\t\t\t\t( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred.\n\t\t\t// If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? slice.call( arguments ) : value;\n\t\t\t\t\tif ( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\t\t\t\t\t} else if ( !( --remaining ) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// Add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) )\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n} );\n\n\n// The deferred used on DOM ready\nvar readyList;\n\njQuery.fn.ready = function( fn ) {\n\n\t// Add the callback\n\tjQuery.ready.promise().done( fn );\n\n\treturn this;\n};\n\njQuery.extend( {\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.triggerHandler ) {\n\t\t\tjQuery( document ).triggerHandler( \"ready\" );\n\t\t\tjQuery( document ).off( \"ready\" );\n\t\t}\n\t}\n} );\n\n/**\n * The ready event handler and self cleanup method\n */\nfunction completed() {\n\tdocument.removeEventListener( \"DOMContentLoaded\", completed );\n\twindow.removeEventListener( \"load\", completed );\n\tjQuery.ready();\n}\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called\n\t\t// after the browser event has already occurred.\n\t\t// Support: IE9-10 only\n\t\t// Older IE sometimes signals \"interactive\" too soon\n\t\tif ( document.readyState === \"complete\" ||\n\t\t\t( document.readyState !== \"loading\" && !document.documentElement.doScroll ) ) {\n\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\twindow.setTimeout( jQuery.ready );\n\n\t\t} else {\n\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed );\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n// Kick off the DOM ready check even if the user does not\njQuery.ready.promise();\n\n\n\n\n// Multifunctional method to get and set values of a collection\n// The value/s can optionally be executed if it's a function\nvar access = function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\tvar i = 0,\n\t\tlen = elems.length,\n\t\tbulk = key == null;\n\n\t// Sets many values\n\tif ( jQuery.type( key ) === \"object\" ) {\n\t\tchainable = true;\n\t\tfor ( i in key ) {\n\t\t\taccess( elems, fn, i, key[ i ], true, emptyGet, raw );\n\t\t}\n\n\t// Sets one value\n\t} else if ( value !== undefined ) {\n\t\tchainable = true;\n\n\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\traw = true;\n\t\t}\n\n\t\tif ( bulk ) {\n\n\t\t\t// Bulk operations run against the entire set\n\t\t\tif ( raw ) {\n\t\t\t\tfn.call( elems, value );\n\t\t\t\tfn = null;\n\n\t\t\t// ...except when executing function values\n\t\t\t} else {\n\t\t\t\tbulk = fn;\n\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tif ( fn ) {\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\tfn(\n\t\t\t\t\telems[ i ], key, raw ?\n\t\t\t\t\tvalue :\n\t\t\t\t\tvalue.call( elems[ i ], i, fn( elems[ i ], key ) )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\treturn chainable ?\n\t\telems :\n\n\t\t// Gets\n\t\tbulk ?\n\t\t\tfn.call( elems ) :\n\t\t\tlen ? fn( elems[ 0 ], key ) : emptyGet;\n};\nvar acceptData = function( owner ) {\n\n\t// Accepts only:\n\t//  - Node\n\t//    - Node.ELEMENT_NODE\n\t//    - Node.DOCUMENT_NODE\n\t//  - Object\n\t//    - Any\n\t/* jshint -W018 */\n\treturn owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );\n};\n\n\n\n\nfunction Data() {\n\tthis.expando = jQuery.expando + Data.uid++;\n}\n\nData.uid = 1;\n\nData.prototype = {\n\n\tregister: function( owner, initial ) {\n\t\tvar value = initial || {};\n\n\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t// use plain assignment\n\t\tif ( owner.nodeType ) {\n\t\t\towner[ this.expando ] = value;\n\n\t\t// Otherwise secure it in a non-enumerable, non-writable property\n\t\t// configurability must be true to allow the property to be\n\t\t// deleted with the delete operator\n\t\t} else {\n\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\tvalue: value,\n\t\t\t\twritable: true,\n\t\t\t\tconfigurable: true\n\t\t\t} );\n\t\t}\n\t\treturn owner[ this.expando ];\n\t},\n\tcache: function( owner ) {\n\n\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t// but we should not, see #8335.\n\t\t// Always return an empty object.\n\t\tif ( !acceptData( owner ) ) {\n\t\t\treturn {};\n\t\t}\n\n\t\t// Check if the owner object already has a cache\n\t\tvar value = owner[ this.expando ];\n\n\t\t// If not, create one\n\t\tif ( !value ) {\n\t\t\tvalue = {};\n\n\t\t\t// We can accept data for non-element nodes in modern browsers,\n\t\t\t// but we should not, see #8335.\n\t\t\t// Always return an empty object.\n\t\t\tif ( acceptData( owner ) ) {\n\n\t\t\t\t// If it is a node unlikely to be stringify-ed or looped over\n\t\t\t\t// use plain assignment\n\t\t\t\tif ( owner.nodeType ) {\n\t\t\t\t\towner[ this.expando ] = value;\n\n\t\t\t\t// Otherwise secure it in a non-enumerable property\n\t\t\t\t// configurable must be true to allow the property to be\n\t\t\t\t// deleted when data is removed\n\t\t\t\t} else {\n\t\t\t\t\tObject.defineProperty( owner, this.expando, {\n\t\t\t\t\t\tvalue: value,\n\t\t\t\t\t\tconfigurable: true\n\t\t\t\t\t} );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn value;\n\t},\n\tset: function( owner, data, value ) {\n\t\tvar prop,\n\t\t\tcache = this.cache( owner );\n\n\t\t// Handle: [ owner, key, value ] args\n\t\tif ( typeof data === \"string\" ) {\n\t\t\tcache[ data ] = value;\n\n\t\t// Handle: [ owner, { properties } ] args\n\t\t} else {\n\n\t\t\t// Copy the properties one-by-one to the cache object\n\t\t\tfor ( prop in data ) {\n\t\t\t\tcache[ prop ] = data[ prop ];\n\t\t\t}\n\t\t}\n\t\treturn cache;\n\t},\n\tget: function( owner, key ) {\n\t\treturn key === undefined ?\n\t\t\tthis.cache( owner ) :\n\t\t\towner[ this.expando ] && owner[ this.expando ][ key ];\n\t},\n\taccess: function( owner, key, value ) {\n\t\tvar stored;\n\n\t\t// In cases where either:\n\t\t//\n\t\t//   1. No key was specified\n\t\t//   2. A string key was specified, but no value provided\n\t\t//\n\t\t// Take the \"read\" path and allow the get method to determine\n\t\t// which value to return, respectively either:\n\t\t//\n\t\t//   1. The entire cache object\n\t\t//   2. The data stored at the key\n\t\t//\n\t\tif ( key === undefined ||\n\t\t\t\t( ( key && typeof key === \"string\" ) && value === undefined ) ) {\n\n\t\t\tstored = this.get( owner, key );\n\n\t\t\treturn stored !== undefined ?\n\t\t\t\tstored : this.get( owner, jQuery.camelCase( key ) );\n\t\t}\n\n\t\t// When the key is not a string, or both a key and value\n\t\t// are specified, set or extend (existing objects) with either:\n\t\t//\n\t\t//   1. An object of properties\n\t\t//   2. A key and value\n\t\t//\n\t\tthis.set( owner, key, value );\n\n\t\t// Since the \"set\" path can have two possible entry points\n\t\t// return the expected data based on which path was taken[*]\n\t\treturn value !== undefined ? value : key;\n\t},\n\tremove: function( owner, key ) {\n\t\tvar i, name, camel,\n\t\t\tcache = owner[ this.expando ];\n\n\t\tif ( cache === undefined ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( key === undefined ) {\n\t\t\tthis.register( owner );\n\n\t\t} else {\n\n\t\t\t// Support array or space separated string of keys\n\t\t\tif ( jQuery.isArray( key ) ) {\n\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = key.concat( key.map( jQuery.camelCase ) );\n\t\t\t} else {\n\t\t\t\tcamel = jQuery.camelCase( key );\n\n\t\t\t\t// Try the string as a key before any manipulation\n\t\t\t\tif ( key in cache ) {\n\t\t\t\t\tname = [ key, camel ];\n\t\t\t\t} else {\n\n\t\t\t\t\t// If a key with the spaces exists, use it.\n\t\t\t\t\t// Otherwise, create an array by matching non-whitespace\n\t\t\t\t\tname = camel;\n\t\t\t\t\tname = name in cache ?\n\t\t\t\t\t\t[ name ] : ( name.match( rnotwhite ) || [] );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\ti = name.length;\n\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete cache[ name[ i ] ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if there's no more data\n\t\tif ( key === undefined || jQuery.isEmptyObject( cache ) ) {\n\n\t\t\t// Support: Chrome <= 35-45+\n\t\t\t// Webkit & Blink performance suffers when deleting properties\n\t\t\t// from DOM nodes, so set to undefined instead\n\t\t\t// https://code.google.com/p/chromium/issues/detail?id=378607\n\t\t\tif ( owner.nodeType ) {\n\t\t\t\towner[ this.expando ] = undefined;\n\t\t\t} else {\n\t\t\t\tdelete owner[ this.expando ];\n\t\t\t}\n\t\t}\n\t},\n\thasData: function( owner ) {\n\t\tvar cache = owner[ this.expando ];\n\t\treturn cache !== undefined && !jQuery.isEmptyObject( cache );\n\t}\n};\nvar dataPriv = new Data();\n\nvar dataUser = new Data();\n\n\n\n//\tImplementation Summary\n//\n//\t1. Enforce API surface and semantic compatibility with 1.9.x branch\n//\t2. Improve the module's maintainability by reducing the storage\n//\t\tpaths to a single mechanism.\n//\t3. Use the same single mechanism to support \"private\" and \"user\" data.\n//\t4. _Never_ expose \"private\" data to user code (TODO: Drop _data, _removeData)\n//\t5. Avoid exposing implementation details on user objects (eg. expando properties)\n//\t6. Provide a clear path for implementation upgrade to WeakMap in 2014\n\nvar rbrace = /^(?:\\{[\\w\\W]*\\}|\\[[\\w\\W]*\\])$/,\n\trmultiDash = /[A-Z]/g;\n\nfunction dataAttr( elem, key, data ) {\n\tvar name;\n\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\t\tname = \"data-\" + key.replace( rmultiDash, \"-$&\" ).toLowerCase();\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\tdata;\n\t\t\t} catch ( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tdataUser.set( elem, key, data );\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\treturn data;\n}\n\njQuery.extend( {\n\thasData: function( elem ) {\n\t\treturn dataUser.hasData( elem ) || dataPriv.hasData( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn dataUser.access( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\tdataUser.remove( elem, name );\n\t},\n\n\t// TODO: Now that all calls to _data and _removeData have been replaced\n\t// with direct calls to dataPriv methods, these can be deprecated.\n\t_data: function( elem, name, data ) {\n\t\treturn dataPriv.access( elem, name, data );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\tdataPriv.remove( elem, name );\n\t}\n} );\n\njQuery.fn.extend( {\n\tdata: function( key, value ) {\n\t\tvar i, name, data,\n\t\t\telem = this[ 0 ],\n\t\t\tattrs = elem && elem.attributes;\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = dataUser.get( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !dataPriv.get( elem, \"hasDataAttrs\" ) ) {\n\t\t\t\t\ti = attrs.length;\n\t\t\t\t\twhile ( i-- ) {\n\n\t\t\t\t\t\t// Support: IE11+\n\t\t\t\t\t\t// The attrs elements can be null (#14894)\n\t\t\t\t\t\tif ( attrs[ i ] ) {\n\t\t\t\t\t\t\tname = attrs[ i ].name;\n\t\t\t\t\t\t\tif ( name.indexOf( \"data-\" ) === 0 ) {\n\t\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice( 5 ) );\n\t\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tdataPriv.set( elem, \"hasDataAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each( function() {\n\t\t\t\tdataUser.set( this, key );\n\t\t\t} );\n\t\t}\n\n\t\treturn access( this, function( value ) {\n\t\t\tvar data, camelKey;\n\n\t\t\t// The calling jQuery object (element matches) is not empty\n\t\t\t// (and therefore has an element appears at this[ 0 ]) and the\n\t\t\t// `value` parameter was not undefined. An empty jQuery object\n\t\t\t// will result in `undefined` for elem = this[ 0 ] which will\n\t\t\t// throw an exception if an attempt to read a data cache is made.\n\t\t\tif ( elem && value === undefined ) {\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// with the key as-is\n\t\t\t\tdata = dataUser.get( elem, key ) ||\n\n\t\t\t\t\t// Try to find dashed key if it exists (gh-2779)\n\t\t\t\t\t// This is for 2.2.x only\n\t\t\t\t\tdataUser.get( elem, key.replace( rmultiDash, \"-$&\" ).toLowerCase() );\n\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\tcamelKey = jQuery.camelCase( key );\n\n\t\t\t\t// Attempt to get data from the cache\n\t\t\t\t// with the key camelized\n\t\t\t\tdata = dataUser.get( elem, camelKey );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// Attempt to \"discover\" the data in\n\t\t\t\t// HTML5 custom data-* attrs\n\t\t\t\tdata = dataAttr( elem, camelKey, undefined );\n\t\t\t\tif ( data !== undefined ) {\n\t\t\t\t\treturn data;\n\t\t\t\t}\n\n\t\t\t\t// We tried really hard, but the data doesn't exist.\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Set the data...\n\t\t\tcamelKey = jQuery.camelCase( key );\n\t\t\tthis.each( function() {\n\n\t\t\t\t// First, attempt to store a copy or reference of any\n\t\t\t\t// data that might've been store with a camelCased key.\n\t\t\t\tvar data = dataUser.get( this, camelKey );\n\n\t\t\t\t// For HTML5 data-* attribute interop, we have to\n\t\t\t\t// store property names with dashes in a camelCase form.\n\t\t\t\t// This might not apply to all properties...*\n\t\t\t\tdataUser.set( this, camelKey, value );\n\n\t\t\t\t// *... In the case of properties that might _actually_\n\t\t\t\t// have dashes, we need to also store a copy of that\n\t\t\t\t// unchanged property.\n\t\t\t\tif ( key.indexOf( \"-\" ) > -1 && data !== undefined ) {\n\t\t\t\t\tdataUser.set( this, key, value );\n\t\t\t\t}\n\t\t\t} );\n\t\t}, null, value, arguments.length > 1, null, true );\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each( function() {\n\t\t\tdataUser.remove( this, key );\n\t\t} );\n\t}\n} );\n\n\njQuery.extend( {\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = dataPriv.get( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray( data ) ) {\n\t\t\t\t\tqueue = dataPriv.access( elem, type, jQuery.makeArray( data ) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// Clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// Not public - generate a queueHooks object, or return the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn dataPriv.get( elem, key ) || dataPriv.access( elem, key, {\n\t\t\tempty: jQuery.Callbacks( \"once memory\" ).add( function() {\n\t\t\t\tdataPriv.remove( elem, [ type + \"queue\", key ] );\n\t\t\t} )\n\t\t} );\n\t}\n} );\n\njQuery.fn.extend( {\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[ 0 ], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each( function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// Ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[ 0 ] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t} );\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t} );\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile ( i-- ) {\n\t\t\ttmp = dataPriv.get( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n} );\nvar pnum = ( /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/ ).source;\n\nvar rcssNum = new RegExp( \"^(?:([+-])=|)(\" + pnum + \")([a-z%]*)$\", \"i\" );\n\n\nvar cssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ];\n\nvar isHidden = function( elem, el ) {\n\n\t\t// isHidden might be called from jQuery#filter function;\n\t\t// in that case, element will be second argument\n\t\telem = el || elem;\n\t\treturn jQuery.css( elem, \"display\" ) === \"none\" ||\n\t\t\t!jQuery.contains( elem.ownerDocument, elem );\n\t};\n\n\n\nfunction adjustCSS( elem, prop, valueParts, tween ) {\n\tvar adjusted,\n\t\tscale = 1,\n\t\tmaxIterations = 20,\n\t\tcurrentValue = tween ?\n\t\t\tfunction() { return tween.cur(); } :\n\t\t\tfunction() { return jQuery.css( elem, prop, \"\" ); },\n\t\tinitial = currentValue(),\n\t\tunit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t// Starting value computation is required for potential unit mismatches\n\t\tinitialInUnit = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +initial ) &&\n\t\t\trcssNum.exec( jQuery.css( elem, prop ) );\n\n\tif ( initialInUnit && initialInUnit[ 3 ] !== unit ) {\n\n\t\t// Trust units reported by jQuery.css\n\t\tunit = unit || initialInUnit[ 3 ];\n\n\t\t// Make sure we update the tween properties later on\n\t\tvalueParts = valueParts || [];\n\n\t\t// Iteratively approximate from a nonzero starting point\n\t\tinitialInUnit = +initial || 1;\n\n\t\tdo {\n\n\t\t\t// If previous iteration zeroed out, double until we get *something*.\n\t\t\t// Use string for doubling so we don't accidentally see scale as unchanged below\n\t\t\tscale = scale || \".5\";\n\n\t\t\t// Adjust and apply\n\t\t\tinitialInUnit = initialInUnit / scale;\n\t\t\tjQuery.style( elem, prop, initialInUnit + unit );\n\n\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t// Break the loop if scale is unchanged or perfect, or if we've just had enough.\n\t\t} while (\n\t\t\tscale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations\n\t\t);\n\t}\n\n\tif ( valueParts ) {\n\t\tinitialInUnit = +initialInUnit || +initial || 0;\n\n\t\t// Apply relative offset (+=/-=) if specified\n\t\tadjusted = valueParts[ 1 ] ?\n\t\t\tinitialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :\n\t\t\t+valueParts[ 2 ];\n\t\tif ( tween ) {\n\t\t\ttween.unit = unit;\n\t\t\ttween.start = initialInUnit;\n\t\t\ttween.end = adjusted;\n\t\t}\n\t}\n\treturn adjusted;\n}\nvar rcheckableType = ( /^(?:checkbox|radio)$/i );\n\nvar rtagName = ( /<([\\w:-]+)/ );\n\nvar rscriptType = ( /^$|\\/(?:java|ecma)script/i );\n\n\n\n// We have to close these tags to support XHTML (#13200)\nvar wrapMap = {\n\n\t// Support: IE9\n\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\n\t// XHTML parsers do not magically insert elements in the\n\t// same way that tag soup parsers do. So we cannot shorten\n\t// this by omitting <tbody> or other required elements.\n\tthead: [ 1, \"<table>\", \"</table>\" ],\n\tcol: [ 2, \"<table><colgroup>\", \"</colgroup></table>\" ],\n\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t_default: [ 0, \"\", \"\" ]\n};\n\n// Support: IE9\nwrapMap.optgroup = wrapMap.option;\n\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\n\nfunction getAll( context, tag ) {\n\n\t// Support: IE9-11+\n\t// Use typeof to avoid zero-argument method invocation on host objects (#15151)\n\tvar ret = typeof context.getElementsByTagName !== \"undefined\" ?\n\t\t\tcontext.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== \"undefined\" ?\n\t\t\t\tcontext.querySelectorAll( tag || \"*\" ) :\n\t\t\t[];\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], ret ) :\n\t\tret;\n}\n\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar i = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\tdataPriv.set(\n\t\t\telems[ i ],\n\t\t\t\"globalEval\",\n\t\t\t!refElements || dataPriv.get( refElements[ i ], \"globalEval\" )\n\t\t);\n\t}\n}\n\n\nvar rhtml = /<|&#?\\w+;/;\n\nfunction buildFragment( elems, context, scripts, selection, ignored ) {\n\tvar elem, tmp, tag, wrap, contains, j,\n\t\tfragment = context.createDocumentFragment(),\n\t\tnodes = [],\n\t\ti = 0,\n\t\tl = elems.length;\n\n\tfor ( ; i < l; i++ ) {\n\t\telem = elems[ i ];\n\n\t\tif ( elem || elem === 0 ) {\n\n\t\t\t// Add nodes directly\n\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\n\t\t\t\t// Support: Android<4.1, PhantomJS<2\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t// Convert non-html into a text node\n\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t// Convert html into DOM nodes\n\t\t\t} else {\n\t\t\t\ttmp = tmp || fragment.appendChild( context.createElement( \"div\" ) );\n\n\t\t\t\t// Deserialize a standard representation\n\t\t\t\ttag = ( rtagName.exec( elem ) || [ \"\", \"\" ] )[ 1 ].toLowerCase();\n\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\t\t\t\ttmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];\n\n\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\tj = wrap[ 0 ];\n\t\t\t\twhile ( j-- ) {\n\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t}\n\n\t\t\t\t// Support: Android<4.1, PhantomJS<2\n\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t// Remember the top-level container\n\t\t\t\ttmp = fragment.firstChild;\n\n\t\t\t\t// Ensure the created nodes are orphaned (#12392)\n\t\t\t\ttmp.textContent = \"\";\n\t\t\t}\n\t\t}\n\t}\n\n\t// Remove wrapper from fragment\n\tfragment.textContent = \"\";\n\n\ti = 0;\n\twhile ( ( elem = nodes[ i++ ] ) ) {\n\n\t\t// Skip elements already in the context collection (trac-4087)\n\t\tif ( selection && jQuery.inArray( elem, selection ) > -1 ) {\n\t\t\tif ( ignored ) {\n\t\t\t\tignored.push( elem );\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\n\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Append to fragment\n\t\ttmp = getAll( fragment.appendChild( elem ), \"script\" );\n\n\t\t// Preserve script evaluation history\n\t\tif ( contains ) {\n\t\t\tsetGlobalEval( tmp );\n\t\t}\n\n\t\t// Capture executables\n\t\tif ( scripts ) {\n\t\t\tj = 0;\n\t\t\twhile ( ( elem = tmp[ j++ ] ) ) {\n\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\tscripts.push( elem );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn fragment;\n}\n\n\n( function() {\n\tvar fragment = document.createDocumentFragment(),\n\t\tdiv = fragment.appendChild( document.createElement( \"div\" ) ),\n\t\tinput = document.createElement( \"input\" );\n\n\t// Support: Android 4.0-4.3, Safari<=5.1\n\t// Check state lost if the name is set (#11217)\n\t// Support: Windows Web Apps (WWA)\n\t// `name` and `type` must use .setAttribute for WWA (#14901)\n\tinput.setAttribute( \"type\", \"radio\" );\n\tinput.setAttribute( \"checked\", \"checked\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tdiv.appendChild( input );\n\n\t// Support: Safari<=5.1, Android<4.2\n\t// Older WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE<=11+\n\t// Make sure textarea (and checkbox) defaultValue is properly cloned\n\tdiv.innerHTML = \"<textarea>x</textarea>\";\n\tsupport.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;\n} )();\n\n\nvar\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\n// Support: IE9\n// See #13393 for more info\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\nfunction on( elem, types, selector, data, fn, one ) {\n\tvar origFn, type;\n\n\t// Types can be a map of types/handlers\n\tif ( typeof types === \"object\" ) {\n\n\t\t// ( types-Object, selector, data )\n\t\tif ( typeof selector !== \"string\" ) {\n\n\t\t\t// ( types-Object, data )\n\t\t\tdata = data || selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tfor ( type in types ) {\n\t\t\ton( elem, type, selector, data, types[ type ], one );\n\t\t}\n\t\treturn elem;\n\t}\n\n\tif ( data == null && fn == null ) {\n\n\t\t// ( types, fn )\n\t\tfn = selector;\n\t\tdata = selector = undefined;\n\t} else if ( fn == null ) {\n\t\tif ( typeof selector === \"string\" ) {\n\n\t\t\t// ( types, selector, fn )\n\t\t\tfn = data;\n\t\t\tdata = undefined;\n\t\t} else {\n\n\t\t\t// ( types, data, fn )\n\t\t\tfn = data;\n\t\t\tdata = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t}\n\tif ( fn === false ) {\n\t\tfn = returnFalse;\n\t} else if ( !fn ) {\n\t\treturn elem;\n\t}\n\n\tif ( one === 1 ) {\n\t\torigFn = fn;\n\t\tfn = function( event ) {\n\n\t\t\t// Can use an empty set, since event contains the info\n\t\t\tjQuery().off( event );\n\t\t\treturn origFn.apply( this, arguments );\n\t\t};\n\n\t\t// Use same guid so caller can remove using origFn\n\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t}\n\treturn elem.each( function() {\n\t\tjQuery.event.add( this, types, fn, data, selector );\n\t} );\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\n\t\tvar handleObjIn, eventHandle, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.get( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !( events = elemData.events ) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !( eventHandle = elemData.handle ) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== \"undefined\" && jQuery.event.triggered !== e.type ?\n\t\t\t\t\tjQuery.event.dispatch.apply( elem, arguments ) : undefined;\n\t\t\t};\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend( {\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join( \".\" )\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !( handlers = events[ type ] ) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener if the special events handler returns false\n\t\t\t\tif ( !special.setup ||\n\t\t\t\t\tspecial.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\n\t\tvar j, origCount, tmp,\n\t\t\tevents, t, handleObj,\n\t\t\tspecial, handlers, type, namespaces, origType,\n\t\t\telemData = dataPriv.hasData( elem ) && dataPriv.get( elem );\n\n\t\tif ( !elemData || !( events = elemData.events ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( rnotwhite ) || [ \"\" ];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[ t ] ) || [];\n\t\t\ttype = origType = tmp[ 1 ];\n\t\t\tnamespaces = ( tmp[ 2 ] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[ 2 ] &&\n\t\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector ||\n\t\t\t\t\t\tselector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown ||\n\t\t\t\t\tspecial.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove data and the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdataPriv.remove( elem, \"handle events\" );\n\t\t}\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, j, ret, matched, handleObj,\n\t\t\thandlerQueue = [],\n\t\t\targs = slice.call( arguments ),\n\t\t\thandlers = ( dataPriv.get( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[ 0 ] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( ( handleObj = matched.handlers[ j++ ] ) &&\n\t\t\t\t!event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or 2) have namespace(s)\n\t\t\t\t// a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||\n\t\t\t\t\t\thandleObj.handler ).apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( ( event.result = ret ) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar i, matches, sel, handleObj,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Support (at least): Chrome, IE9\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t//\n\t\t// Support: Firefox<=42+\n\t\t// Avoid non-left-click in FF but don't block IE radio events (#3861, gh-2343)\n\t\tif ( delegateCount && cur.nodeType &&\n\t\t\t( event.type !== \"click\" || isNaN( event.button ) || event.button < 1 ) ) {\n\n\t\t\tfor ( ; cur !== this; cur = cur.parentNode || this ) {\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && ( cur.disabled !== true || event.type !== \"click\" ) ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) > -1 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push( { elem: cur, handlers: matches } );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push( { elem: this, handlers: handlers.slice( delegateCount ) } );\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\tprops: ( \"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase \" +\n\t\t\"metaKey relatedTarget shiftKey target timeStamp view which\" ).split( \" \" ),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split( \" \" ),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: ( \"button buttons clientX clientY offsetX offsetY pageX pageY \" +\n\t\t\t\"screenX screenY toElement\" ).split( \" \" ),\n\t\tfilter: function( event, original ) {\n\t\t\tvar eventDoc, doc, body,\n\t\t\t\tbutton = original.button;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX +\n\t\t\t\t\t( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) -\n\t\t\t\t\t( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY +\n\t\t\t\t\t( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) -\n\t\t\t\t\t( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Support: Cordova 2.5 (WebKit) (#13255)\n\t\t// All events should have a target; Cordova deviceready doesn't\n\t\tif ( !event.target ) {\n\t\t\tevent.target = document;\n\t\t}\n\n\t\t// Support: Safari 6.0+, Chrome<28\n\t\t// Target should not be a text node (#504, #13143)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\tspecial: {\n\t\tload: {\n\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\tthis.focus();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this.type === \"checkbox\" && this.click && jQuery.nodeName( this, \"input\" ) ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Support: Firefox 20+\n\t\t\t\t// Firefox doesn't alert if the returnValue field is not set.\n\t\t\t\tif ( event.result !== undefined && event.originalEvent ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n};\n\njQuery.removeEvent = function( elem, type, handle ) {\n\n\t// This \"if\" is needed for plain objects\n\tif ( elem.removeEventListener ) {\n\t\telem.removeEventListener( type, handle );\n\t}\n};\n\njQuery.Event = function( src, props ) {\n\n\t// Allow instantiation without the 'new' keyword\n\tif ( !( this instanceof jQuery.Event ) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = src.defaultPrevented ||\n\t\t\t\tsrc.defaultPrevented === undefined &&\n\n\t\t\t\t// Support: Android<4.0\n\t\t\t\tsrc.returnValue === false ?\n\t\t\treturnTrue :\n\t\t\treturnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tconstructor: jQuery.Event,\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\n\t\tif ( e ) {\n\t\t\te.preventDefault();\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\n\t\tif ( e ) {\n\t\t\te.stopPropagation();\n\t\t}\n\t},\n\tstopImmediatePropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\n\t\tif ( e ) {\n\t\t\te.stopImmediatePropagation();\n\t\t}\n\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\n// so that event delegation works in jQuery.\n// Do the same for pointerenter/pointerleave and pointerover/pointerout\n//\n// Support: Safari 7 only\n// Safari sends mouseenter too often; see:\n// https://code.google.com/p/chromium/issues/detail?id=470258\n// for the description of the bug (it existed in older Chrome versions as well).\njQuery.each( {\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\",\n\tpointerenter: \"pointerover\",\n\tpointerleave: \"pointerout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mouseenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n} );\n\njQuery.fn.extend( {\n\ton: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn );\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn on( this, types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ?\n\t\t\t\t\thandleObj.origType + \".\" + handleObj.namespace :\n\t\t\t\t\thandleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t} );\n\t}\n} );\n\n\nvar\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:-]+)[^>]*)\\/>/gi,\n\n\t// Support: IE 10-11, Edge 10240+\n\t// In IE/Edge using regex groups here causes severe slowdowns.\n\t// See https://connect.microsoft.com/IE/feedback/details/1736512/\n\trnoInnerhtml = /<script|<style|<link/i,\n\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g;\n\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType !== 11 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName( \"tbody\" )[ 0 ] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement( \"tbody\" ) ) :\n\t\telem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = ( elem.getAttribute( \"type\" ) !== null ) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\n\tif ( match ) {\n\t\telem.type = match[ 1 ];\n\t} else {\n\t\telem.removeAttribute( \"type\" );\n\t}\n\n\treturn elem;\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\tvar i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;\n\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\t// 1. Copy private data: events, handlers, etc.\n\tif ( dataPriv.hasData( src ) ) {\n\t\tpdataOld = dataPriv.access( src );\n\t\tpdataCur = dataPriv.set( dest, pdataOld );\n\t\tevents = pdataOld.events;\n\n\t\tif ( events ) {\n\t\t\tdelete pdataCur.handle;\n\t\t\tpdataCur.events = {};\n\n\t\t\tfor ( type in events ) {\n\t\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// 2. Copy user data\n\tif ( dataUser.hasData( src ) ) {\n\t\tudataOld = dataUser.access( src );\n\t\tudataCur = jQuery.extend( {}, udataOld );\n\n\t\tdataUser.set( dest, udataCur );\n\t}\n}\n\n// Fix IE bugs, see support tests\nfunction fixInput( src, dest ) {\n\tvar nodeName = dest.nodeName.toLowerCase();\n\n\t// Fails to persist the checked state of a cloned checkbox or radio button.\n\tif ( nodeName === \"input\" && rcheckableType.test( src.type ) ) {\n\t\tdest.checked = src.checked;\n\n\t// Fails to return the selected option to the default selected state when cloning options\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\nfunction domManip( collection, args, callback, ignored ) {\n\n\t// Flatten any nested arrays\n\targs = concat.apply( [], args );\n\n\tvar fragment, first, scripts, hasScripts, node, doc,\n\t\ti = 0,\n\t\tl = collection.length,\n\t\tiNoClone = l - 1,\n\t\tvalue = args[ 0 ],\n\t\tisFunction = jQuery.isFunction( value );\n\n\t// We can't cloneNode fragments that contain checked, in WebKit\n\tif ( isFunction ||\n\t\t\t( l > 1 && typeof value === \"string\" &&\n\t\t\t\t!support.checkClone && rchecked.test( value ) ) ) {\n\t\treturn collection.each( function( index ) {\n\t\t\tvar self = collection.eq( index );\n\t\t\tif ( isFunction ) {\n\t\t\t\targs[ 0 ] = value.call( this, index, self.html() );\n\t\t\t}\n\t\t\tdomManip( self, args, callback, ignored );\n\t\t} );\n\t}\n\n\tif ( l ) {\n\t\tfragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );\n\t\tfirst = fragment.firstChild;\n\n\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\tfragment = first;\n\t\t}\n\n\t\t// Require either new content or an interest in ignored elements to invoke the callback\n\t\tif ( first || ignored ) {\n\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\thasScripts = scripts.length;\n\n\t\t\t// Use the original fragment for the last item\n\t\t\t// instead of the first because it can end up\n\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\tnode = fragment;\n\n\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\tif ( hasScripts ) {\n\n\t\t\t\t\t\t// Support: Android<4.1, PhantomJS<2\n\t\t\t\t\t\t// push.apply(_, arraylike) throws on ancient WebKit\n\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tcallback.call( collection[ i ], node, i );\n\t\t\t}\n\n\t\t\tif ( hasScripts ) {\n\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t// Reenable scripts\n\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t!dataPriv.access( node, \"globalEval\" ) &&\n\t\t\t\t\t\tjQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\tif ( node.src ) {\n\n\t\t\t\t\t\t\t// Optional AJAX dependency, but won't run scripts if not present\n\t\t\t\t\t\t\tif ( jQuery._evalUrl ) {\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tjQuery.globalEval( node.textContent.replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn collection;\n}\n\nfunction remove( elem, selector, keepData ) {\n\tvar node,\n\t\tnodes = selector ? jQuery.filter( selector, elem ) : elem,\n\t\ti = 0;\n\n\tfor ( ; ( node = nodes[ i ] ) != null; i++ ) {\n\t\tif ( !keepData && node.nodeType === 1 ) {\n\t\t\tjQuery.cleanData( getAll( node ) );\n\t\t}\n\n\t\tif ( node.parentNode ) {\n\t\t\tif ( keepData && jQuery.contains( node.ownerDocument, node ) ) {\n\t\t\t\tsetGlobalEval( getAll( node, \"script\" ) );\n\t\t\t}\n\t\t\tnode.parentNode.removeChild( node );\n\t\t}\n\t}\n\n\treturn elem;\n}\n\njQuery.extend( {\n\thtmlPrefilter: function( html ) {\n\t\treturn html.replace( rxhtmlTag, \"<$1></$2>\" );\n\t},\n\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar i, l, srcElements, destElements,\n\t\t\tclone = elem.cloneNode( true ),\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t// Fix IE cloning issues\n\t\tif ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&\n\t\t\t\t!jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\tfixInput( srcElements[ i ], destElements[ i ] );\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0, l = srcElements.length; i < l; i++ ) {\n\t\t\t\t\tcloneCopyEvent( srcElements[ i ], destElements[ i ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tcleanData: function( elems ) {\n\t\tvar data, elem, type,\n\t\t\tspecial = jQuery.event.special,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {\n\t\t\tif ( acceptData( elem ) ) {\n\t\t\t\tif ( ( data = elem[ dataPriv.expando ] ) ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Support: Chrome <= 35-45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataPriv.expando ] = undefined;\n\t\t\t\t}\n\t\t\t\tif ( elem[ dataUser.expando ] ) {\n\n\t\t\t\t\t// Support: Chrome <= 35-45+\n\t\t\t\t\t// Assign undefined instead of using delete, see Data#remove\n\t\t\t\t\telem[ dataUser.expando ] = undefined;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n} );\n\njQuery.fn.extend( {\n\n\t// Keep domManip exposed until 3.0 (gh-2225)\n\tdomManip: domManip,\n\n\tdetach: function( selector ) {\n\t\treturn remove( this, selector, true );\n\t},\n\n\tremove: function( selector ) {\n\t\treturn remove( this, selector );\n\t},\n\n\ttext: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().each( function() {\n\t\t\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\t\t\tthis.textContent = value;\n\t\t\t\t\t}\n\t\t\t\t} );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t} );\n\t},\n\n\tprepend: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t} );\n\t},\n\n\tbefore: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t} );\n\t},\n\n\tafter: function() {\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t} );\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; ( elem = this[ i ] ) != null; i++ ) {\n\t\t\tif ( elem.nodeType === 1 ) {\n\n\t\t\t\t// Prevent memory leaks\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\n\t\t\t\t// Remove any remaining nodes\n\t\t\t\telem.textContent = \"\";\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function() {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t} );\n\t},\n\n\thtml: function( value ) {\n\t\treturn access( this, function( value ) {\n\t\t\tvar elem = this[ 0 ] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined && elem.nodeType === 1 ) {\n\t\t\t\treturn elem.innerHTML;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [ \"\", \"\" ] )[ 1 ].toLowerCase() ] ) {\n\n\t\t\t\tvalue = jQuery.htmlPrefilter( value );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\t\telem = this[ i ] || {};\n\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch ( e ) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar ignored = [];\n\n\t\t// Make the changes, replacing each non-ignored context element with the new content\n\t\treturn domManip( this, arguments, function( elem ) {\n\t\t\tvar parent = this.parentNode;\n\n\t\t\tif ( jQuery.inArray( this, ignored ) < 0 ) {\n\t\t\t\tjQuery.cleanData( getAll( this ) );\n\t\t\t\tif ( parent ) {\n\t\t\t\t\tparent.replaceChild( elem, this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Force callback invocation\n\t\t}, ignored );\n\t}\n} );\n\njQuery.each( {\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1,\n\t\t\ti = 0;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone( true );\n\t\t\tjQuery( insert[ i ] )[ original ]( elems );\n\n\t\t\t// Support: QtWebKit\n\t\t\t// .get() because push.apply(_, arraylike) throws\n\t\t\tpush.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n} );\n\n\nvar iframe,\n\telemdisplay = {\n\n\t\t// Support: Firefox\n\t\t// We have to pre-define these values for FF (#10227)\n\t\tHTML: \"block\",\n\t\tBODY: \"block\"\n\t};\n\n/**\n * Retrieve the actual display of a element\n * @param {String} name nodeName of the element\n * @param {Object} doc Document object\n */\n\n// Called only from within defaultDisplay\nfunction actualDisplay( name, doc ) {\n\tvar elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\n\t\tdisplay = jQuery.css( elem[ 0 ], \"display\" );\n\n\t// We don't have any data stored on the element,\n\t// so use \"detach\" method as fast way to get rid of the element\n\telem.detach();\n\n\treturn display;\n}\n\n/**\n * Try to determine the default display value of an element\n * @param {String} nodeName\n */\nfunction defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\n\t\t// If the simple way fails, read from inside an iframe\n\t\tif ( display === \"none\" || !display ) {\n\n\t\t\t// Use the already-created iframe if possible\n\t\t\tiframe = ( iframe || jQuery( \"<iframe frameborder='0' width='0' height='0'/>\" ) )\n\t\t\t\t.appendTo( doc.documentElement );\n\n\t\t\t// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse\n\t\t\tdoc = iframe[ 0 ].contentDocument;\n\n\t\t\t// Support: IE\n\t\t\tdoc.write();\n\t\t\tdoc.close();\n\n\t\t\tdisplay = actualDisplay( nodeName, doc );\n\t\t\tiframe.detach();\n\t\t}\n\n\t\t// Store the correct default display\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn display;\n}\nvar rmargin = ( /^margin/ );\n\nvar rnumnonpx = new RegExp( \"^(\" + pnum + \")(?!px)[a-z%]+$\", \"i\" );\n\nvar getStyles = function( elem ) {\n\n\t\t// Support: IE<=11+, Firefox<=30+ (#15098, #14150)\n\t\t// IE throws on elements created in popups\n\t\t// FF meanwhile throws on frame elements through \"defaultView.getComputedStyle\"\n\t\tvar view = elem.ownerDocument.defaultView;\n\n\t\tif ( !view || !view.opener ) {\n\t\t\tview = window;\n\t\t}\n\n\t\treturn view.getComputedStyle( elem );\n\t};\n\nvar swap = function( elem, options, callback, args ) {\n\tvar ret, name,\n\t\told = {};\n\n\t// Remember the old values, and insert the new ones\n\tfor ( name in options ) {\n\t\told[ name ] = elem.style[ name ];\n\t\telem.style[ name ] = options[ name ];\n\t}\n\n\tret = callback.apply( elem, args || [] );\n\n\t// Revert the old values\n\tfor ( name in options ) {\n\t\telem.style[ name ] = old[ name ];\n\t}\n\n\treturn ret;\n};\n\n\nvar documentElement = document.documentElement;\n\n\n\n( function() {\n\tvar pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,\n\t\tcontainer = document.createElement( \"div\" ),\n\t\tdiv = document.createElement( \"div\" );\n\n\t// Finish early in limited (non-browser) environments\n\tif ( !div.style ) {\n\t\treturn;\n\t}\n\n\t// Support: IE9-11+\n\t// Style of cloned element affects source element cloned (#8908)\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\tcontainer.style.cssText = \"border:0;width:8px;height:0;top:0;left:-9999px;\" +\n\t\t\"padding:0;margin-top:1px;position:absolute\";\n\tcontainer.appendChild( div );\n\n\t// Executing both pixelPosition & boxSizingReliable tests require only one layout\n\t// so they're executed at the same time to save the second computation.\n\tfunction computeStyleTests() {\n\t\tdiv.style.cssText =\n\n\t\t\t// Support: Firefox<29, Android 2.3\n\t\t\t// Vendor-prefix box-sizing\n\t\t\t\"-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;\" +\n\t\t\t\"position:relative;display:block;\" +\n\t\t\t\"margin:auto;border:1px;padding:1px;\" +\n\t\t\t\"top:1%;width:50%\";\n\t\tdiv.innerHTML = \"\";\n\t\tdocumentElement.appendChild( container );\n\n\t\tvar divStyle = window.getComputedStyle( div );\n\t\tpixelPositionVal = divStyle.top !== \"1%\";\n\t\treliableMarginLeftVal = divStyle.marginLeft === \"2px\";\n\t\tboxSizingReliableVal = divStyle.width === \"4px\";\n\n\t\t// Support: Android 4.0 - 4.3 only\n\t\t// Some styles come back with percentage values, even though they shouldn't\n\t\tdiv.style.marginRight = \"50%\";\n\t\tpixelMarginRightVal = divStyle.marginRight === \"4px\";\n\n\t\tdocumentElement.removeChild( container );\n\t}\n\n\tjQuery.extend( support, {\n\t\tpixelPosition: function() {\n\n\t\t\t// This test is executed only once but we still do memoizing\n\t\t\t// since we can use the boxSizingReliable pre-computing.\n\t\t\t// No need to check if the test was already performed, though.\n\t\t\tcomputeStyleTests();\n\t\t\treturn pixelPositionVal;\n\t\t},\n\t\tboxSizingReliable: function() {\n\t\t\tif ( boxSizingReliableVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn boxSizingReliableVal;\n\t\t},\n\t\tpixelMarginRight: function() {\n\n\t\t\t// Support: Android 4.0-4.3\n\t\t\t// We're checking for boxSizingReliableVal here instead of pixelMarginRightVal\n\t\t\t// since that compresses better and they're computed together anyway.\n\t\t\tif ( boxSizingReliableVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn pixelMarginRightVal;\n\t\t},\n\t\treliableMarginLeft: function() {\n\n\t\t\t// Support: IE <=8 only, Android 4.0 - 4.3 only, Firefox <=3 - 37\n\t\t\tif ( boxSizingReliableVal == null ) {\n\t\t\t\tcomputeStyleTests();\n\t\t\t}\n\t\t\treturn reliableMarginLeftVal;\n\t\t},\n\t\treliableMarginRight: function() {\n\n\t\t\t// Support: Android 2.3\n\t\t\t// Check if div with explicit width and no margin-right incorrectly\n\t\t\t// gets computed margin-right based on width of container. (#3333)\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t// This support function is only executed once so no memoizing is needed.\n\t\t\tvar ret,\n\t\t\t\tmarginDiv = div.appendChild( document.createElement( \"div\" ) );\n\n\t\t\t// Reset CSS: box-sizing; display; margin; border; padding\n\t\t\tmarginDiv.style.cssText = div.style.cssText =\n\n\t\t\t\t// Support: Android 2.3\n\t\t\t\t// Vendor-prefix box-sizing\n\t\t\t\t\"-webkit-box-sizing:content-box;box-sizing:content-box;\" +\n\t\t\t\t\"display:block;margin:0;border:0;padding:0\";\n\t\t\tmarginDiv.style.marginRight = marginDiv.style.width = \"0\";\n\t\t\tdiv.style.width = \"1px\";\n\t\t\tdocumentElement.appendChild( container );\n\n\t\t\tret = !parseFloat( window.getComputedStyle( marginDiv ).marginRight );\n\n\t\t\tdocumentElement.removeChild( container );\n\t\t\tdiv.removeChild( marginDiv );\n\n\t\t\treturn ret;\n\t\t}\n\t} );\n} )();\n\n\nfunction curCSS( elem, name, computed ) {\n\tvar width, minWidth, maxWidth, ret,\n\t\tstyle = elem.style;\n\n\tcomputed = computed || getStyles( elem );\n\tret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined;\n\n\t// Support: Opera 12.1x only\n\t// Fall back to style even without computed\n\t// computed is undefined for elems on document fragments\n\tif ( ( ret === \"\" || ret === undefined ) && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\tret = jQuery.style( elem, name );\n\t}\n\n\t// Support: IE9\n\t// getPropertyValue is only needed for .css('filter') (#12537)\n\tif ( computed ) {\n\n\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t// Android Browser returns percentage for some values,\n\t\t// but width seems to be reliably pixels.\n\t\t// This is against the CSSOM draft spec:\n\t\t// http://dev.w3.org/csswg/cssom/#resolved-values\n\t\tif ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\twidth = style.width;\n\t\t\tminWidth = style.minWidth;\n\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\tret = computed.width;\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.width = width;\n\t\t\tstyle.minWidth = minWidth;\n\t\t\tstyle.maxWidth = maxWidth;\n\t\t}\n\t}\n\n\treturn ret !== undefined ?\n\n\t\t// Support: IE9-11+\n\t\t// IE returns zIndex value as an integer.\n\t\tret + \"\" :\n\t\tret;\n}\n\n\nfunction addGetHookIf( conditionFn, hookFn ) {\n\n\t// Define the hook, we'll check on the first run if it's really needed.\n\treturn {\n\t\tget: function() {\n\t\t\tif ( conditionFn() ) {\n\n\t\t\t\t// Hook not needed (or it's not possible to use it due\n\t\t\t\t// to missing dependency), remove it.\n\t\t\t\tdelete this.get;\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// Hook needed; redefine it so that the support test is not executed again.\n\t\t\treturn ( this.get = hookFn ).apply( this, arguments );\n\t\t}\n\t};\n}\n\n\nvar\n\n\t// Swappable if display is none or starts with table\n\t// except \"table\", \"table-cell\", or \"table-caption\"\n\t// See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: \"0\",\n\t\tfontWeight: \"400\"\n\t},\n\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ],\n\temptyStyle = document.createElement( \"div\" ).style;\n\n// Return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( name ) {\n\n\t// Shortcut for names that are not vendor prefixed\n\tif ( name in emptyStyle ) {\n\t\treturn name;\n\t}\n\n\t// Check for vendor prefixed names\n\tvar capName = name[ 0 ].toUpperCase() + name.slice( 1 ),\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in emptyStyle ) {\n\t\t\treturn name;\n\t\t}\n\t}\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\n\t// Any relative (+/-) values have already been\n\t// normalized at this point\n\tvar matches = rcssNum.exec( value );\n\treturn matches ?\n\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\n\t\t// Both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// At this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\n\t\t\t// At this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// At this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar valueIsBorderBox = true,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// Support: IE11 only\n\t// In IE 11 fullscreen elements inside of an iframe have\n\t// 100x too small dimensions (gh-1764).\n\tif ( document.msFullscreenElement && window.top !== window ) {\n\n\t\t// Support: IE11 only\n\t\t// Running getBoundingClientRect on a disconnected node\n\t\t// in IE throws an error.\n\t\tif ( elem.getClientRects().length ) {\n\t\t\tval = Math.round( elem.getBoundingClientRect()[ name ] * 100 );\n\t\t}\n\t}\n\n\t// Some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test( val ) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// Check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox &&\n\t\t\t( support.boxSizingReliable() || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// Use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem, hidden,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalues[ index ] = dataPriv.get( elem, \"olddisplay\" );\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\n\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t// being hidden by cascaded rules or not\n\t\t\tif ( !values[ index ] && display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\n\t\t\t// Set elements which have been overridden with display: none\n\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t// for such an element\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = dataPriv.access(\n\t\t\t\t\telem,\n\t\t\t\t\t\"olddisplay\",\n\t\t\t\t\tdefaultDisplay( elem.nodeName )\n\t\t\t\t);\n\t\t\t}\n\t\t} else {\n\t\t\thidden = isHidden( elem );\n\n\t\t\tif ( display !== \"none\" || !hidden ) {\n\t\t\t\tdataPriv.set(\n\t\t\t\t\telem,\n\t\t\t\t\t\"olddisplay\",\n\t\t\t\t\thidden ? display : jQuery.css( elem, \"display\" )\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of most of the elements in a second loop\n\t// to avoid the constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.extend( {\n\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"animationIterationCount\": true,\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"flexGrow\": true,\n\t\t\"flexShrink\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t\"float\": \"cssFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] ||\n\t\t\t( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );\n\n\t\t// Gets hook for the prefixed version, then unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// Convert \"+=\" or \"-=\" to relative numbers (#7345)\n\t\t\tif ( type === \"string\" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {\n\t\t\t\tvalue = adjustCSS( elem, name, ret );\n\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that null and NaN values aren't set (#7116)\n\t\t\tif ( value == null || value !== value ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add the unit (except for certain CSS properties)\n\t\t\tif ( type === \"number\" ) {\n\t\t\t\tvalue += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? \"\" : \"px\" );\n\t\t\t}\n\n\t\t\t// Support: IE9-11+\n\t\t\t// background-* props affect original clone's values\n\t\t\tif ( !support.clearCloneStyle && value === \"\" && name.indexOf( \"background\" ) === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !( \"set\" in hooks ) ||\n\t\t\t\t( value = hooks.set( elem, value, extra ) ) !== undefined ) {\n\n\t\t\t\tstyle[ name ] = value;\n\t\t\t}\n\n\t\t} else {\n\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks &&\n\t\t\t\t( ret = hooks.get( elem, false, extra ) ) !== undefined ) {\n\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar val, num, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] ||\n\t\t\t( jQuery.cssProps[ origName ] = vendorPropName( origName ) || origName );\n\n\t\t// Try prefixed name followed by the unprefixed name\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t// Convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Make numeric if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || isFinite( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n} );\n\njQuery.each( [ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\n\t\t\t\t// Certain elements can have dimension info if we invisibly show them\n\t\t\t\t// but it must have a current display style that would benefit\n\t\t\t\treturn rdisplayswap.test( jQuery.css( elem, \"display\" ) ) &&\n\t\t\t\t\telem.offsetWidth === 0 ?\n\t\t\t\t\t\tswap( elem, cssShow, function() {\n\t\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t\t} ) :\n\t\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar matches,\n\t\t\t\tstyles = extra && getStyles( elem ),\n\t\t\t\tsubtract = extra && augmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tjQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t);\n\n\t\t\t// Convert to pixels if value adjustment is needed\n\t\t\tif ( subtract && ( matches = rcssNum.exec( value ) ) &&\n\t\t\t\t( matches[ 3 ] || \"px\" ) !== \"px\" ) {\n\n\t\t\t\telem.style[ name ] = value;\n\t\t\t\tvalue = jQuery.css( elem, name );\n\t\t\t}\n\n\t\t\treturn setPositiveNumber( elem, value, subtract );\n\t\t}\n\t};\n} );\n\njQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn ( parseFloat( curCSS( elem, \"marginLeft\" ) ) ||\n\t\t\t\telem.getBoundingClientRect().left -\n\t\t\t\t\tswap( elem, { marginLeft: 0 }, function() {\n\t\t\t\t\t\treturn elem.getBoundingClientRect().left;\n\t\t\t\t\t} )\n\t\t\t\t) + \"px\";\n\t\t}\n\t}\n);\n\n// Support: Android 2.3\njQuery.cssHooks.marginRight = addGetHookIf( support.reliableMarginRight,\n\tfunction( elem, computed ) {\n\t\tif ( computed ) {\n\t\t\treturn swap( elem, { \"display\": \"inline-block\" },\n\t\t\t\tcurCSS, [ elem, \"marginRight\" ] );\n\t\t}\n\t}\n);\n\n// These hooks are used by animate to expand properties\njQuery.each( {\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// Assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split( \" \" ) : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n} );\n\njQuery.fn.extend( {\n\tcss: function( name, value ) {\n\t\treturn access( this, function( elem, name, value ) {\n\t\t\tvar styles, len,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tif ( isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t} );\n\t}\n} );\n\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || jQuery.easing._default;\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\t// Use a property on the element directly when it is not a DOM element,\n\t\t\t// or when there is no matching style property that exists.\n\t\t\tif ( tween.elem.nodeType !== 1 ||\n\t\t\t\ttween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// Passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails.\n\t\t\t// Simple values such as \"10px\" are parsed to Float;\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as-is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\n\t\t\t// Use step hook for back compat.\n\t\t\t// Use cssHook if its there.\n\t\t\t// Use .style if available and use plain properties where available.\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.nodeType === 1 &&\n\t\t\t\t( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||\n\t\t\t\t\tjQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE9\n// Panic based approach to setting things on disconnected nodes\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p * Math.PI ) / 2;\n\t},\n\t_default: \"swing\"\n};\n\njQuery.fx = Tween.prototype.init;\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\n\n\n\nvar\n\tfxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trrun = /queueHooks$/;\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\twindow.setTimeout( function() {\n\t\tfxNow = undefined;\n\t} );\n\treturn ( fxNow = jQuery.now() );\n}\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\ti = 0,\n\t\tattrs = { height: type };\n\n\t// If we include width, step value is 1 to do all cssExpand values,\n\t// otherwise step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth ? 1 : 0;\n\tfor ( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {\n\n\t\t\t// We're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction defaultPrefilter( elem, props, opts ) {\n\t/* jshint validthis: true */\n\tvar prop, value, toggle, tween, hooks, oldfire, display, checkDisplay,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHidden( elem ),\n\t\tdataShow = dataPriv.get( elem, \"fxshow\" );\n\n\t// Handle queue: false promises\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always( function() {\n\n\t\t\t// Ensure the complete handler is called before this completes\n\t\t\tanim.always( function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t} );\n\t\t} );\n\t}\n\n\t// Height/width overflow pass\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\n\t\t// Make sure that nothing sneaks out\n\t\t// Record all 3 overflow attributes because IE9-10 do not\n\t\t// change the overflow attribute when overflowX and\n\t\t// overflowY are set to the same value\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Set display property to inline-block for height/width\n\t\t// animations on inline elements that are having width/height animated\n\t\tdisplay = jQuery.css( elem, \"display\" );\n\n\t\t// Test default display if display is currently \"none\"\n\t\tcheckDisplay = display === \"none\" ?\n\t\t\tdataPriv.get( elem, \"olddisplay\" ) || defaultDisplay( elem.nodeName ) : display;\n\n\t\tif ( checkDisplay === \"inline\" && jQuery.css( elem, \"float\" ) === \"none\" ) {\n\t\t\tstyle.display = \"inline-block\";\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tanim.always( function() {\n\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t} );\n\t}\n\n\t// show/hide pass\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\n\t\t\t\t// If there is dataShow left over from a stopped hide or show\n\t\t\t\t// and we are going to proceed with show, we should pretend to be hidden\n\t\t\t\tif ( value === \"show\" && dataShow && dataShow[ prop ] !== undefined ) {\n\t\t\t\t\thidden = true;\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\n\t\t// Any non-fx value stops us from restoring the original display value\n\t\t} else {\n\t\t\tdisplay = undefined;\n\t\t}\n\t}\n\n\tif ( !jQuery.isEmptyObject( orig ) ) {\n\t\tif ( dataShow ) {\n\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\thidden = dataShow.hidden;\n\t\t\t}\n\t\t} else {\n\t\t\tdataShow = dataPriv.access( elem, \"fxshow\", {} );\n\t\t}\n\n\t\t// Store state if its toggle - enables .stop().toggle() to \"reverse\"\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done( function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t} );\n\t\t}\n\t\tanim.done( function() {\n\t\t\tvar prop;\n\n\t\t\tdataPriv.remove( elem, \"fxshow\" );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t} );\n\t\tfor ( prop in orig ) {\n\t\t\ttween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t// If this is a noop like .hide().hide(), restore an overwritten display value\n\t} else if ( ( display === \"none\" ? defaultDisplay( elem.nodeName ) : display ) === \"inline\" ) {\n\t\tstyle.display = display;\n\t}\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// Not quite $.extend, this won't overwrite existing keys.\n\t\t\t// Reusing 'index' because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = Animation.prefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\n\t\t\t// Don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t} ),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\n\t\t\t\t// Support: Android 2.3\n\t\t\t\t// Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ] );\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise( {\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, {\n\t\t\t\tspecialEasing: {},\n\t\t\t\teasing: jQuery.easing._default\n\t\t\t}, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\n\t\t\t\t\t// If we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// Resolve when we played the last frame; otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.notifyWith( elem, [ animation, 1, 0 ] );\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t} ),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\tif ( jQuery.isFunction( result.stop ) ) {\n\t\t\t\tjQuery._queueHooks( animation.elem, animation.opts.queue ).stop =\n\t\t\t\t\tjQuery.proxy( result.stop, result );\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t} )\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\ttweeners: {\n\t\t\"*\": [ function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value );\n\t\t\tadjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );\n\t\t\treturn tween;\n\t\t} ]\n\t},\n\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.match( rnotwhite );\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\tAnimation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];\n\t\t\tAnimation.tweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilters: [ defaultPrefilter ],\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tAnimation.prefilters.unshift( callback );\n\t\t} else {\n\t\t\tAnimation.prefilters.push( callback );\n\t\t}\n\t}\n} );\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ?\n\t\topt.duration : opt.duration in jQuery.fx.speeds ?\n\t\t\tjQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n\t// Normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.fn.extend( {\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// Show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n\t\t\t// Animate to the value specified\n\t\t\t.end().animate( { opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || dataPriv.get( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = dataPriv.get( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this &&\n\t\t\t\t\t( type == null || timers[ index ].queue === type ) ) {\n\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Start the next in the queue if the last step wasn't forced.\n\t\t\t// Timers currently will call their complete callbacks, which\n\t\t\t// will dequeue but only if they were gotoEnd.\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t} );\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tvar index,\n\t\t\t\tdata = dataPriv.get( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// Enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// Empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// Look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t} );\n\t}\n} );\n\njQuery.each( [ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n} );\n\n// Generate shortcuts for custom animations\njQuery.each( {\n\tslideDown: genFx( \"show\" ),\n\tslideUp: genFx( \"hide\" ),\n\tslideToggle: genFx( \"toggle\" ),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n} );\n\njQuery.timers = [];\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ti = 0,\n\t\ttimers = jQuery.timers;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tjQuery.timers.push( timer );\n\tif ( timer() ) {\n\t\tjQuery.fx.start();\n\t} else {\n\t\tjQuery.timers.pop();\n\t}\n};\n\njQuery.fx.interval = 13;\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = window.setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\twindow.clearInterval( timerId );\n\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\n\t// Default speed\n\t_default: 400\n};\n\n\n// Based off of the plugin by Clint Helfers, with permission.\n// http://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/\njQuery.fn.delay = function( time, type ) {\n\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\ttype = type || \"fx\";\n\n\treturn this.queue( type, function( next, hooks ) {\n\t\tvar timeout = window.setTimeout( next, time );\n\t\thooks.stop = function() {\n\t\t\twindow.clearTimeout( timeout );\n\t\t};\n\t} );\n};\n\n\n( function() {\n\tvar input = document.createElement( \"input\" ),\n\t\tselect = document.createElement( \"select\" ),\n\t\topt = select.appendChild( document.createElement( \"option\" ) );\n\n\tinput.type = \"checkbox\";\n\n\t// Support: iOS<=5.1, Android<=4.2+\n\t// Default value for a checkbox should be \"on\"\n\tsupport.checkOn = input.value !== \"\";\n\n\t// Support: IE<=11+\n\t// Must access selectedIndex to make default options select\n\tsupport.optSelected = opt.selected;\n\n\t// Support: Android<=2.3\n\t// Options inside disabled selects are incorrectly marked as disabled\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Support: IE<=11+\n\t// An input loses its value after becoming a radio\n\tinput = document.createElement( \"input\" );\n\tinput.value = \"t\";\n\tinput.type = \"radio\";\n\tsupport.radioValue = input.value === \"t\";\n} )();\n\n\nvar boolHook,\n\tattrHandle = jQuery.expr.attrHandle;\n\njQuery.fn.extend( {\n\tattr: function( name, value ) {\n\t\treturn access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tattr: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set attributes on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === \"undefined\" ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// All attributes are lowercase\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\treturn value;\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\tret = jQuery.find.attr( elem, name );\n\n\t\t// Non-existent attributes return null, we normalize to undefined\n\t\treturn ret == null ? undefined : ret;\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !support.radioValue && value === \"radio\" &&\n\t\t\t\t\tjQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name, propName,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( ( name = attrNames[ i++ ] ) ) {\n\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\n\t\t\t\t// Boolean attributes get special treatment (#10870)\n\t\t\t\tif ( jQuery.expr.match.bool.test( name ) ) {\n\n\t\t\t\t\t// Set corresponding property to false\n\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t}\n\n\t\t\t\telem.removeAttribute( name );\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else {\n\t\t\telem.setAttribute( name, name );\n\t\t}\n\t\treturn name;\n\t}\n};\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = attrHandle[ name ] || jQuery.find.attr;\n\n\tattrHandle[ name ] = function( elem, name, isXML ) {\n\t\tvar ret, handle;\n\t\tif ( !isXML ) {\n\n\t\t\t// Avoid an infinite loop by temporarily removing this function from the getter\n\t\t\thandle = attrHandle[ name ];\n\t\t\tattrHandle[ name ] = ret;\n\t\t\tret = getter( elem, name, isXML ) != null ?\n\t\t\t\tname.toLowerCase() :\n\t\t\t\tnull;\n\t\t\tattrHandle[ name ] = handle;\n\t\t}\n\t\treturn ret;\n\t};\n} );\n\n\n\n\nvar rfocusable = /^(?:input|select|textarea|button)$/i,\n\trclickable = /^(?:a|area)$/i;\n\njQuery.fn.extend( {\n\tprop: function( name, value ) {\n\t\treturn access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\treturn this.each( function() {\n\t\t\tdelete this[ jQuery.propFix[ name ] || name ];\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks,\n\t\t\tnType = elem.nodeType;\n\n\t\t// Don't get/set properties on text, comment and attribute nodes\n\t\tif ( nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\tif ( hooks && \"set\" in hooks &&\n\t\t\t\t( ret = hooks.set( elem, value, name ) ) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\treturn ( elem[ name ] = value );\n\t\t}\n\n\t\tif ( hooks && \"get\" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {\n\t\t\treturn ret;\n\t\t}\n\n\t\treturn elem[ name ];\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// elem.tabIndex doesn't always return the\n\t\t\t\t// correct value when it hasn't been explicitly set\n\t\t\t\t// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\treturn tabindex ?\n\t\t\t\t\tparseInt( tabindex, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) ||\n\t\t\t\t\t\trclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t\t0 :\n\t\t\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t}\n} );\n\nif ( !support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\t\t\tif ( parent && parent.parentNode ) {\n\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\njQuery.each( [\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n} );\n\n\n\n\nvar rclass = /[\\t\\r\\n\\f]/g;\n\nfunction getClass( elem ) {\n\treturn elem.getAttribute && elem.getAttribute( \"class\" ) || \"\";\n}\n\njQuery.fn.extend( {\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( typeof value === \"string\" && value ) {\n\t\t\tclasses = value.match( rnotwhite ) || [];\n\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\t\t\t\tcur = elem.nodeType === 1 &&\n\t\t\t\t\t( \" \" + curValue + \" \" ).replace( rclass, \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, curValue, clazz, j, finalValue,\n\t\t\ti = 0;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( !arguments.length ) {\n\t\t\treturn this.attr( \"class\", \"\" );\n\t\t}\n\n\t\tif ( typeof value === \"string\" && value ) {\n\t\t\tclasses = value.match( rnotwhite ) || [];\n\n\t\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\t\tcurValue = getClass( elem );\n\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 &&\n\t\t\t\t\t( \" \" + curValue + \" \" ).replace( rclass, \" \" );\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( ( clazz = classes[ j++ ] ) ) {\n\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) > -1 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Only assign if different to avoid unneeded rendering.\n\t\t\t\t\tfinalValue = jQuery.trim( cur );\n\t\t\t\t\tif ( curValue !== finalValue ) {\n\t\t\t\t\t\telem.setAttribute( \"class\", finalValue );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).toggleClass(\n\t\t\t\t\tvalue.call( this, i, getClass( this ), stateVal ),\n\t\t\t\t\tstateVal\n\t\t\t\t);\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar className, i, self, classNames;\n\n\t\t\tif ( type === \"string\" ) {\n\n\t\t\t\t// Toggle individual class names\n\t\t\t\ti = 0;\n\t\t\t\tself = jQuery( this );\n\t\t\t\tclassNames = value.match( rnotwhite ) || [];\n\n\t\t\t\twhile ( ( className = classNames[ i++ ] ) ) {\n\n\t\t\t\t\t// Check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( value === undefined || type === \"boolean\" ) {\n\t\t\t\tclassName = getClass( this );\n\t\t\t\tif ( className ) {\n\n\t\t\t\t\t// Store className if set\n\t\t\t\t\tdataPriv.set( this, \"__className__\", className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed `false`,\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tif ( this.setAttribute ) {\n\t\t\t\t\tthis.setAttribute( \"class\",\n\t\t\t\t\t\tclassName || value === false ?\n\t\t\t\t\t\t\"\" :\n\t\t\t\t\t\tdataPriv.get( this, \"__className__\" ) || \"\"\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t} );\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className, elem,\n\t\t\ti = 0;\n\n\t\tclassName = \" \" + selector + \" \";\n\t\twhile ( ( elem = this[ i++ ] ) ) {\n\t\t\tif ( elem.nodeType === 1 &&\n\t\t\t\t( \" \" + getClass( elem ) + \" \" ).replace( rclass, \" \" )\n\t\t\t\t\t.indexOf( className ) > -1\n\t\t\t) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n} );\n\n\n\n\nvar rreturn = /\\r/g;\n\njQuery.fn.extend( {\n\tval: function( value ) {\n\t\tvar hooks, ret, isFunction,\n\t\t\telem = this[ 0 ];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] ||\n\t\t\t\t\tjQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks &&\n\t\t\t\t\t\"get\" in hooks &&\n\t\t\t\t\t( ret = hooks.get( elem, \"value\" ) ) !== undefined\n\t\t\t\t) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\n\t\t\t\t\t// Handle most common string cases\n\t\t\t\t\tret.replace( rreturn, \"\" ) :\n\n\t\t\t\t\t// Handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each( function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map( val, function( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t} );\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !( \"set\" in hooks ) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t} );\n\t}\n} );\n\njQuery.extend( {\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\n\t\t\t\t// Support: IE<11\n\t\t\t\t// option.value not trimmed (#14858)\n\t\t\t\treturn jQuery.trim( elem.value );\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// IE8-9 doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t( support.optDisabled ?\n\t\t\t\t\t\t\t\t!option.disabled : option.getAttribute( \"disabled\" ) === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled ||\n\t\t\t\t\t\t\t\t!jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\t\t\t\t\tif ( option.selected =\n\t\t\t\t\t\t\tjQuery.inArray( jQuery.valHooks.option.get( option ), values ) > -1\n\t\t\t\t\t) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t}\n} );\n\n// Radios and checkboxes getter/setter\njQuery.each( [ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\treturn elem.getAttribute( \"value\" ) === null ? \"on\" : elem.value;\n\t\t};\n\t}\n} );\n\n\n\n\n// Return jQuery for attributes-only inclusion\n\n\nvar rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;\n\njQuery.extend( jQuery.event, {\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\n\t\tvar i, cur, tmp, bubbleType, ontype, handle, special,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = hasOwn.call( event, \"namespace\" ) ? event.namespace.split( \".\" ) : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf( \".\" ) > -1 ) {\n\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split( \".\" );\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf( \":\" ) < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join( \".\" );\n\t\tevent.rnamespace = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join( \"\\\\.(?:.*\\\\.|)\" ) + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === ( elem.ownerDocument || document ) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( dataPriv.get( cur, \"events\" ) || {} )[ event.type ] &&\n\t\t\t\tdataPriv.get( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && handle.apply && acceptData( cur ) ) {\n\t\t\t\tevent.result = handle.apply( cur, data );\n\t\t\t\tif ( event.result === false ) {\n\t\t\t\t\tevent.preventDefault();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( ( !special._default ||\n\t\t\t\tspecial._default.apply( eventPath.pop(), data ) === false ) &&\n\t\t\t\tacceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\telem[ type ]();\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\t// Piggyback on a donor event to simulate a different one\n\tsimulate: function( type, elem, event ) {\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true\n\n\t\t\t\t// Previously, `originalEvent: {}` was set here, so stopPropagation call\n\t\t\t\t// would not be triggered on donor event, since in our own\n\t\t\t\t// jQuery.event.stopPropagation function we had a check for existence of\n\t\t\t\t// originalEvent.stopPropagation method, so, consequently it would be a noop.\n\t\t\t\t//\n\t\t\t\t// But now, this \"simulate\" function is used only for events\n\t\t\t\t// for which stopPropagation() is noop, so there is no need for that anymore.\n\t\t\t\t//\n\t\t\t\t// For the 1.x branch though, guard for \"click\" and \"submit\"\n\t\t\t\t// events is still used, but was moved to jQuery.event.stopPropagation function\n\t\t\t\t// because `originalEvent` should point to the original event for the constancy\n\t\t\t\t// with other events and for more focused logic\n\t\t\t}\n\t\t);\n\n\t\tjQuery.event.trigger( e, null, elem );\n\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n\n} );\n\njQuery.fn.extend( {\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t} );\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[ 0 ];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n} );\n\n\njQuery.each( ( \"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\" ).split( \" \" ),\n\tfunction( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n} );\n\njQuery.fn.extend( {\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t}\n} );\n\n\n\n\nsupport.focusin = \"onfocusin\" in window;\n\n\n// Support: Firefox\n// Firefox doesn't have focus(in | out) events\n// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787\n//\n// Support: Chrome, Safari\n// focus(in | out) events fire after focus & blur events,\n// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order\n// Related ticket - https://code.google.com/p/chromium/issues/detail?id=449857\nif ( !support.focusin ) {\n\tjQuery.each( { focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler on the document while someone wants focusin/focusout\n\t\tvar handler = function( event ) {\n\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );\n\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix );\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t\tdataPriv.access( doc, fix, ( attaches || 0 ) + 1 );\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tvar doc = this.ownerDocument || this,\n\t\t\t\t\tattaches = dataPriv.access( doc, fix ) - 1;\n\n\t\t\t\tif ( !attaches ) {\n\t\t\t\t\tdoc.removeEventListener( orig, handler, true );\n\t\t\t\t\tdataPriv.remove( doc, fix );\n\n\t\t\t\t} else {\n\t\t\t\t\tdataPriv.access( doc, fix, attaches );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t} );\n}\nvar location = window.location;\n\nvar nonce = jQuery.now();\n\nvar rquery = ( /\\?/ );\n\n\n\n// Support: Android 2.3\n// Workaround failure to string-cast null input\njQuery.parseJSON = function( data ) {\n\treturn JSON.parse( data + \"\" );\n};\n\n\n// Cross-browser xml parsing\njQuery.parseXML = function( data ) {\n\tvar xml;\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\n\t// Support: IE9\n\ttry {\n\t\txml = ( new window.DOMParser() ).parseFromString( data, \"text/xml\" );\n\t} catch ( e ) {\n\t\txml = undefined;\n\t}\n\n\tif ( !xml || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\tjQuery.error( \"Invalid XML: \" + data );\n\t}\n\treturn xml;\n};\n\n\nvar\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)$/mg,\n\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat( \"*\" ),\n\n\t// Anchor tag for parsing the document origin\n\toriginAnchor = document.createElement( \"a\" );\n\toriginAnchor.href = location.href;\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( ( dataType = dataTypes[ i++ ] ) ) {\n\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[ 0 ] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t( structure[ dataType ] = structure[ dataType ] || [] ).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif ( typeof dataTypeOrTransport === \"string\" &&\n\t\t\t\t!seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t} );\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar key, deep,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\n\tvar ct, type, finalDataType, firstDataType,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile ( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader( \"Content-Type\" );\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[ 0 ] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s.throws ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\tstate: \"parsererror\",\n\t\t\t\t\t\t\t\terror: conv ? e : \"No conversion from \" + prev + \" to \" + current\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n\njQuery.extend( {\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: location.href,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( location.protocol ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /\\bxml\\b/,\n\t\t\thtml: /\\bhtml/,\n\t\t\tjson: /\\bjson\\b/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar transport,\n\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\n\t\t\t// Response headers\n\t\t\tresponseHeadersString,\n\t\t\tresponseHeaders,\n\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// Url cleanup var\n\t\t\turlAnchor,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\t// Loop variable\n\t\t\ti,\n\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context &&\n\t\t\t\t( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\t\tjQuery.event,\n\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks( \"once memory\" ),\n\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( ( match = rheaders.exec( responseHeadersString ) ) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[ 1 ].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\t\t\tfor ( code in map ) {\n\n\t\t\t\t\t\t\t\t// Lazy-add the new callback in a way that preserves old ones\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR ).complete = completeDeferred.add;\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (prefilters might expect it)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || location.href ) + \"\" ).replace( rhash, \"\" )\n\t\t\t.replace( rprotocol, location.protocol + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( rnotwhite ) || [ \"\" ];\n\n\t\t// A cross-domain request is in order when the origin doesn't match the current origin.\n\t\tif ( s.crossDomain == null ) {\n\t\t\turlAnchor = document.createElement( \"a\" );\n\n\t\t\t// Support: IE8-11+\n\t\t\t// IE throws exception if url is malformed, e.g. http://example.com:80x/\n\t\t\ttry {\n\t\t\t\turlAnchor.href = s.url;\n\n\t\t\t\t// Support: IE8-11+\n\t\t\t\t// Anchor's host property isn't correctly set when s.url is relative\n\t\t\t\turlAnchor.href = urlAnchor.href;\n\t\t\t\ts.crossDomain = originAnchor.protocol + \"//\" + originAnchor.host !==\n\t\t\t\t\turlAnchor.protocol + \"//\" + urlAnchor.host;\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// If there is an error parsing the URL, assume it is crossDomain,\n\t\t\t\t// it can be rejected by the transport if it is invalid\n\t\t\t\ts.crossDomain = true;\n\t\t\t}\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\t// Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)\n\t\tfireGlobals = jQuery.event && s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger( \"ajaxStart\" );\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\tcacheURL = s.url;\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL = ( s.url += ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\ts.url = rts.test( cacheURL ) ?\n\n\t\t\t\t\t// If there is already a '_' parameter, set its value\n\t\t\t\t\tcacheURL.replace( rts, \"$1_=\" + nonce++ ) :\n\n\t\t\t\t\t// Otherwise add one to the end\n\t\t\t\t\tcacheURL + ( rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + nonce++;\n\t\t\t}\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[ 0 ] ] +\n\t\t\t\t\t( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend &&\n\t\t\t( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// Aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\n\t\t\t// If request was aborted inside ajaxSend, stop there\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn jqXHR;\n\t\t\t}\n\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = window.setTimeout( function() {\n\t\t\t\t\tjqXHR.abort( \"timeout\" );\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\twindow.clearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"Last-Modified\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader( \"etag\" );\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\n\t\t\t\t// Extract error from statusText and normalize for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger( \"ajaxStop\" );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n} );\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\n\t\t// Shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\t// The url can be an options object (which then must have .url)\n\t\treturn jQuery.ajax( jQuery.extend( {\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t}, jQuery.isPlainObject( url ) && url ) );\n\t};\n} );\n\n\njQuery._evalUrl = function( url ) {\n\treturn jQuery.ajax( {\n\t\turl: url,\n\n\t\t// Make this explicit, since user can override this through ajaxSetup (#11264)\n\t\ttype: \"GET\",\n\t\tdataType: \"script\",\n\t\tasync: false,\n\t\tglobal: false,\n\t\t\"throws\": true\n\t} );\n};\n\n\njQuery.fn.extend( {\n\twrapAll: function( html ) {\n\t\tvar wrap;\n\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapAll( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\tif ( this[ 0 ] ) {\n\n\t\t\t// The elements to wrap the target around\n\t\t\twrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );\n\n\t\t\tif ( this[ 0 ].parentNode ) {\n\t\t\t\twrap.insertBefore( this[ 0 ] );\n\t\t\t}\n\n\t\t\twrap.map( function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstElementChild ) {\n\t\t\t\t\telem = elem.firstElementChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t} ).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each( function( i ) {\n\t\t\t\tjQuery( this ).wrapInner( html.call( this, i ) );\n\t\t\t} );\n\t\t}\n\n\t\treturn this.each( function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t} );\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each( function( i ) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );\n\t\t} );\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each( function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t} ).end();\n\t}\n} );\n\n\njQuery.expr.filters.hidden = function( elem ) {\n\treturn !jQuery.expr.filters.visible( elem );\n};\njQuery.expr.filters.visible = function( elem ) {\n\n\t// Support: Opera <= 12.12\n\t// Opera reports offsetWidths and offsetHeights less than zero on some elements\n\t// Use OR instead of AND as the element is not visible if either is true\n\t// See tickets #10406 and #13132\n\treturn elem.offsetWidth > 0 || elem.offsetHeight > 0 || elem.getClientRects().length > 0;\n};\n\n\n\n\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams(\n\t\t\t\t\tprefix + \"[\" + ( typeof v === \"object\" && v != null ? i : \"\" ) + \"]\",\n\t\t\t\t\tv,\n\t\t\t\t\ttraditional,\n\t\t\t\t\tadd\n\t\t\t\t);\n\t\t\t}\n\t\t} );\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\n\n// Serialize an array of form elements or a set of\n// key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\n\t\t\t// If value is a function, invoke it and return its value\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\n\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t} );\n\n\t} else {\n\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\njQuery.fn.extend( {\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map( function() {\n\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t} )\n\t\t.filter( function() {\n\t\t\tvar type = this.type;\n\n\t\t\t// Use .is( \":disabled\" ) so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !rcheckableType.test( type ) );\n\t\t} )\n\t\t.map( function( i, elem ) {\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ) {\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t} ) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t} ).get();\n\t}\n} );\n\n\njQuery.ajaxSettings.xhr = function() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch ( e ) {}\n};\n\nvar xhrSuccessStatus = {\n\n\t\t// File protocol always yields status code 0, assume 200\n\t\t0: 200,\n\n\t\t// Support: IE9\n\t\t// #1450: sometimes IE returns 1223 when it should be 204\n\t\t1223: 204\n\t},\n\txhrSupported = jQuery.ajaxSettings.xhr();\n\nsupport.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nsupport.ajax = xhrSupported = !!xhrSupported;\n\njQuery.ajaxTransport( function( options ) {\n\tvar callback, errorCallback;\n\n\t// Cross domain only allowed if supported through XMLHttpRequest\n\tif ( support.cors || xhrSupported && !options.crossDomain ) {\n\t\treturn {\n\t\t\tsend: function( headers, complete ) {\n\t\t\t\tvar i,\n\t\t\t\t\txhr = options.xhr();\n\n\t\t\t\txhr.open(\n\t\t\t\t\toptions.type,\n\t\t\t\t\toptions.url,\n\t\t\t\t\toptions.async,\n\t\t\t\t\toptions.username,\n\t\t\t\t\toptions.password\n\t\t\t\t);\n\n\t\t\t\t// Apply custom fields if provided\n\t\t\t\tif ( options.xhrFields ) {\n\t\t\t\t\tfor ( i in options.xhrFields ) {\n\t\t\t\t\t\txhr[ i ] = options.xhrFields[ i ];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Override mime type if needed\n\t\t\t\tif ( options.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\txhr.overrideMimeType( options.mimeType );\n\t\t\t\t}\n\n\t\t\t\t// X-Requested-With header\n\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\tif ( !options.crossDomain && !headers[ \"X-Requested-With\" ] ) {\n\t\t\t\t\theaders[ \"X-Requested-With\" ] = \"XMLHttpRequest\";\n\t\t\t\t}\n\n\t\t\t\t// Set headers\n\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t}\n\n\t\t\t\t// Callback\n\t\t\t\tcallback = function( type ) {\n\t\t\t\t\treturn function() {\n\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\tcallback = errorCallback = xhr.onload =\n\t\t\t\t\t\t\t\txhr.onerror = xhr.onabort = xhr.onreadystatechange = null;\n\n\t\t\t\t\t\t\tif ( type === \"abort\" ) {\n\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t} else if ( type === \"error\" ) {\n\n\t\t\t\t\t\t\t\t// Support: IE9\n\t\t\t\t\t\t\t\t// On a manual native abort, IE9 throws\n\t\t\t\t\t\t\t\t// errors on any property access that is not readyState\n\t\t\t\t\t\t\t\tif ( typeof xhr.status !== \"number\" ) {\n\t\t\t\t\t\t\t\t\tcomplete( 0, \"error\" );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tcomplete(\n\n\t\t\t\t\t\t\t\t\t\t// File: protocol always yields status 0; see #8605, #14207\n\t\t\t\t\t\t\t\t\t\txhr.status,\n\t\t\t\t\t\t\t\t\t\txhr.statusText\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tcomplete(\n\t\t\t\t\t\t\t\t\txhrSuccessStatus[ xhr.status ] || xhr.status,\n\t\t\t\t\t\t\t\t\txhr.statusText,\n\n\t\t\t\t\t\t\t\t\t// Support: IE9 only\n\t\t\t\t\t\t\t\t\t// IE9 has no XHR2 but throws on binary (trac-11426)\n\t\t\t\t\t\t\t\t\t// For XHR2 non-text, let the caller handle it (gh-2498)\n\t\t\t\t\t\t\t\t\t( xhr.responseType || \"text\" ) !== \"text\"  ||\n\t\t\t\t\t\t\t\t\ttypeof xhr.responseText !== \"string\" ?\n\t\t\t\t\t\t\t\t\t\t{ binary: xhr.response } :\n\t\t\t\t\t\t\t\t\t\t{ text: xhr.responseText },\n\t\t\t\t\t\t\t\t\txhr.getAllResponseHeaders()\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t};\n\n\t\t\t\t// Listen to events\n\t\t\t\txhr.onload = callback();\n\t\t\t\terrorCallback = xhr.onerror = callback( \"error\" );\n\n\t\t\t\t// Support: IE9\n\t\t\t\t// Use onreadystatechange to replace onabort\n\t\t\t\t// to handle uncaught aborts\n\t\t\t\tif ( xhr.onabort !== undefined ) {\n\t\t\t\t\txhr.onabort = errorCallback;\n\t\t\t\t} else {\n\t\t\t\t\txhr.onreadystatechange = function() {\n\n\t\t\t\t\t\t// Check readyState before timeout as it changes\n\t\t\t\t\t\tif ( xhr.readyState === 4 ) {\n\n\t\t\t\t\t\t\t// Allow onerror to be called first,\n\t\t\t\t\t\t\t// but that will not handle a native abort\n\t\t\t\t\t\t\t// Also, save errorCallback to a variable\n\t\t\t\t\t\t\t// as xhr.onerror cannot be accessed\n\t\t\t\t\t\t\twindow.setTimeout( function() {\n\t\t\t\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\t\t\t\terrorCallback();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\t\t\t\t}\n\n\t\t\t\t// Create the abort callback\n\t\t\t\tcallback = callback( \"abort\" );\n\n\t\t\t\ttry {\n\n\t\t\t\t\t// Do send the request (this may raise an exception)\n\t\t\t\t\txhr.send( options.hasContent && options.data || null );\n\t\t\t\t} catch ( e ) {\n\n\t\t\t\t\t// #14683: Only rethrow if this hasn't been notified as an error yet\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tthrow e;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\n// Install script dataType\njQuery.ajaxSetup( {\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, \" +\n\t\t\t\"application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /\\b(?:java|ecma)script\\b/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n} );\n\n// Handle cache's special case and crossDomain\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t}\n} );\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function( s ) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\t\tvar script, callback;\n\t\treturn {\n\t\t\tsend: function( _, complete ) {\n\t\t\t\tscript = jQuery( \"<script>\" ).prop( {\n\t\t\t\t\tcharset: s.scriptCharset,\n\t\t\t\t\tsrc: s.url\n\t\t\t\t} ).on(\n\t\t\t\t\t\"load error\",\n\t\t\t\t\tcallback = function( evt ) {\n\t\t\t\t\t\tscript.remove();\n\t\t\t\t\t\tcallback = null;\n\t\t\t\t\t\tif ( evt ) {\n\t\t\t\t\t\t\tcomplete( evt.type === \"error\" ? 404 : 200, evt.type );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\tdocument.head.appendChild( script[ 0 ] );\n\t\t\t},\n\t\t\tabort: function() {\n\t\t\t\tif ( callback ) {\n\t\t\t\t\tcallback();\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n} );\n\n\n\n\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup( {\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n} );\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" &&\n\t\t\t\t( s.contentType || \"\" )\n\t\t\t\t\t.indexOf( \"application/x-www-form-urlencoded\" ) === 0 &&\n\t\t\t\trjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[ \"script json\" ] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// Force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always( function() {\n\n\t\t\t// If previous value didn't exist - remove it\n\t\t\tif ( overwritten === undefined ) {\n\t\t\t\tjQuery( window ).removeProp( callbackName );\n\n\t\t\t// Otherwise restore preexisting value\n\t\t\t} else {\n\t\t\t\twindow[ callbackName ] = overwritten;\n\t\t\t}\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\n\t\t\t\t// Make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// Save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t} );\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n} );\n\n\n\n\n// Support: Safari 8+\n// In Safari 8 documents created via document.implementation.createHTMLDocument\n// collapse sibling forms: the second one becomes a child of the first one.\n// Because of that, this security measure has to be disabled in Safari 8.\n// https://bugs.webkit.org/show_bug.cgi?id=137337\nsupport.createHTMLDocument = ( function() {\n\tvar body = document.implementation.createHTMLDocument( \"\" ).body;\n\tbody.innerHTML = \"<form></form><form></form>\";\n\treturn body.childNodes.length === 2;\n} )();\n\n\n// Argument \"data\" should be string of html\n// context (optional): If specified, the fragment will be created in this context,\n// defaults to document\n// keepScripts (optional): If true, will include scripts passed in the html string\njQuery.parseHTML = function( data, context, keepScripts ) {\n\tif ( !data || typeof data !== \"string\" ) {\n\t\treturn null;\n\t}\n\tif ( typeof context === \"boolean\" ) {\n\t\tkeepScripts = context;\n\t\tcontext = false;\n\t}\n\n\t// Stop scripts or inline event handlers from being executed immediately\n\t// by using document.implementation\n\tcontext = context || ( support.createHTMLDocument ?\n\t\tdocument.implementation.createHTMLDocument( \"\" ) :\n\t\tdocument );\n\n\tvar parsed = rsingleTag.exec( data ),\n\t\tscripts = !keepScripts && [];\n\n\t// Single tag\n\tif ( parsed ) {\n\t\treturn [ context.createElement( parsed[ 1 ] ) ];\n\t}\n\n\tparsed = buildFragment( [ data ], context, scripts );\n\n\tif ( scripts && scripts.length ) {\n\t\tjQuery( scripts ).remove();\n\t}\n\n\treturn jQuery.merge( [], parsed.childNodes );\n};\n\n\n// Keep a copy of the old load method\nvar _load = jQuery.fn.load;\n\n/**\n * Load a url into a page\n */\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\tvar selector, type, response,\n\t\tself = this,\n\t\toff = url.indexOf( \" \" );\n\n\tif ( off > -1 ) {\n\t\tselector = jQuery.trim( url.slice( off ) );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax( {\n\t\t\turl: url,\n\n\t\t\t// If \"type\" variable is undefined, then \"GET\" method will be used.\n\t\t\t// Make value of this field explicit since\n\t\t\t// user can override it through ajaxSetup method\n\t\t\ttype: type || \"GET\",\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t} ).done( function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery( \"<div>\" ).append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t// If the request succeeds, this function gets \"data\", \"status\", \"jqXHR\"\n\t\t// but they are ignored because response was set above.\n\t\t// If it fails, this function gets \"jqXHR\", \"status\", \"error\"\n\t\t} ).always( callback && function( jqXHR, status ) {\n\t\t\tself.each( function() {\n\t\t\t\tcallback.apply( self, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t\t} );\n\t\t} );\n\t}\n\n\treturn this;\n};\n\n\n\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [\n\t\"ajaxStart\",\n\t\"ajaxStop\",\n\t\"ajaxComplete\",\n\t\"ajaxError\",\n\t\"ajaxSuccess\",\n\t\"ajaxSend\"\n], function( i, type ) {\n\tjQuery.fn[ type ] = function( fn ) {\n\t\treturn this.on( type, fn );\n\t};\n} );\n\n\n\n\njQuery.expr.filters.animated = function( elem ) {\n\treturn jQuery.grep( jQuery.timers, function( fn ) {\n\t\treturn elem === fn.elem;\n\t} ).length;\n};\n\n\n\n\n/**\n * Gets a window from an element\n */\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ? elem : elem.nodeType === 9 && elem.defaultView;\n}\n\njQuery.offset = {\n\tsetOffset: function( elem, options, i ) {\n\t\tvar curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,\n\t\t\tposition = jQuery.css( elem, \"position\" ),\n\t\t\tcurElem = jQuery( elem ),\n\t\t\tprops = {};\n\n\t\t// Set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tcurOffset = curElem.offset();\n\t\tcurCSSTop = jQuery.css( elem, \"top\" );\n\t\tcurCSSLeft = jQuery.css( elem, \"left\" );\n\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) &&\n\t\t\t( curCSSTop + curCSSLeft ).indexOf( \"auto\" ) > -1;\n\n\t\t// Need to be able to calculate position if either\n\t\t// top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\n\t\t\t// Use jQuery.extend here to allow modification of coordinates argument (gh-1848)\n\t\t\toptions = options.call( elem, i, jQuery.extend( {}, curOffset ) );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\njQuery.fn.extend( {\n\toffset: function( options ) {\n\t\tif ( arguments.length ) {\n\t\t\treturn options === undefined ?\n\t\t\t\tthis :\n\t\t\t\tthis.each( function( i ) {\n\t\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t\t} );\n\t\t}\n\n\t\tvar docElem, win,\n\t\t\telem = this[ 0 ],\n\t\t\tbox = { top: 0, left: 0 },\n\t\t\tdoc = elem && elem.ownerDocument;\n\n\t\tif ( !doc ) {\n\t\t\treturn;\n\t\t}\n\n\t\tdocElem = doc.documentElement;\n\n\t\t// Make sure it's not a disconnected DOM node\n\t\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\t\treturn box;\n\t\t}\n\n\t\tbox = elem.getBoundingClientRect();\n\t\twin = getWindow( doc );\n\t\treturn {\n\t\t\ttop: box.top + win.pageYOffset - docElem.clientTop,\n\t\t\tleft: box.left + win.pageXOffset - docElem.clientLeft\n\t\t};\n\t},\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\telem = this[ 0 ],\n\t\t\tparentOffset = { top: 0, left: 0 };\n\n\t\t// Fixed elements are offset from window (parentOffset = {top:0, left: 0},\n\t\t// because it is its only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\n\t\t\t// Assume getBoundingClientRect is there when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\n\t\t} else {\n\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset.top += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n\t\t\tparentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\treturn {\n\t\t\ttop: offset.top - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true )\n\t\t};\n\t},\n\n\t// This method will return documentElement in the following cases:\n\t// 1) For the element inside the iframe without offsetParent, this method will return\n\t//    documentElement of the parent window\n\t// 2) For the hidden or detached element\n\t// 3) For body or html element, i.e. in case of the html node - it will return itself\n\t//\n\t// but those exceptions were never presented as a real life use-cases\n\t// and might be considered as more preferable results.\n\t//\n\t// This logic, however, is not guaranteed and can change at any point in the future\n\toffsetParent: function() {\n\t\treturn this.map( function() {\n\t\t\tvar offsetParent = this.offsetParent;\n\n\t\t\twhile ( offsetParent && jQuery.css( offsetParent, \"position\" ) === \"static\" ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\n\t\t\treturn offsetParent || documentElement;\n\t\t} );\n\t}\n} );\n\n// Create scrollLeft and scrollTop methods\njQuery.each( { scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\" }, function( method, prop ) {\n\tvar top = \"pageYOffset\" === prop;\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? win[ prop ] : elem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : win.pageXOffset,\n\t\t\t\t\ttop ? val : win.pageYOffset\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length );\n\t};\n} );\n\n// Support: Safari<7-8+, Chrome<37-44+\n// Add the top/left cssHooks using jQuery.fn.position\n// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n// Blink bug: https://code.google.com/p/chromium/issues/detail?id=229280\n// getComputedStyle returns percent when specified for top/left/bottom/right;\n// rather than make the css module depend on the offset module, just check for it here\njQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\tjQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,\n\t\tfunction( elem, computed ) {\n\t\t\tif ( computed ) {\n\t\t\t\tcomputed = curCSS( elem, prop );\n\n\t\t\t\t// If curCSS returns percentage, fallback to offset\n\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\tcomputed;\n\t\t\t}\n\t\t}\n\t);\n} );\n\n\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name },\n\t\tfunction( defaultExtra, funcName ) {\n\n\t\t// Margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n\t\t\t\t\t// isn't a whole lot we can do. See pull request at this URL for discussion:\n\t\t\t\t\t// https://github.com/jquery/jquery/pull/764\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height],\n\t\t\t\t\t// whichever is greatest\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t} );\n} );\n\n\njQuery.fn.extend( {\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ?\n\t\t\tthis.off( selector, \"**\" ) :\n\t\t\tthis.off( types, selector || \"**\", fn );\n\t},\n\tsize: function() {\n\t\treturn this.length;\n\t}\n} );\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n\n\n\n// Register as a named AMD module, since jQuery can be concatenated with other\n// files that may use define, but not via a proper concatenation script that\n// understands anonymous AMD modules. A named AMD is safest and most robust\n// way to register. Lowercase jquery is used because AMD module names are\n// derived from file names, and jQuery is normally delivered in a lowercase\n// file name. Do this after creating the global so that if an AMD module wants\n// to call noConflict to hide this version of jQuery, it will work.\n\n// Note that for maximum portability, libraries that are not jQuery should\n// declare themselves as anonymous modules, and avoid setting a global if an\n// AMD loader is present. jQuery is a special case. For more information, see\n// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon\n\nif ( typeof define === \"function\" && define.amd ) {\n\tdefine( \"jquery\", [], function() {\n\t\treturn jQuery;\n\t} );\n}\n\n\n\nvar\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$;\n\njQuery.noConflict = function( deep ) {\n\tif ( window.$ === jQuery ) {\n\t\twindow.$ = _$;\n\t}\n\n\tif ( deep && window.jQuery === jQuery ) {\n\t\twindow.jQuery = _jQuery;\n\t}\n\n\treturn jQuery;\n};\n\n// Expose jQuery and $ identifiers, even in AMD\n// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)\n// and CommonJS for browser emulators (#13566)\nif ( !noGlobal ) {\n\twindow.jQuery = window.$ = jQuery;\n}\n\nreturn jQuery;\n}));\n"
  },
  {
    "path": "public/static/plugins/wangeditor/js/wangEditor.js",
    "content": "(function (factory) {\n    if (typeof window.define === 'function') {\n        if (window.define.amd) {\n            // AMD模式\n            window.define('wangEditor', [\"jquery\"], factory);\n        } else if (window.define.cmd) {\n            // CMD模式\n            window.define(function (require, exports, module) {\n                return factory;\n            });\n        } else {\n            // 全局模式\n            factory(window.jQuery);\n        }\n    } else if (typeof module === \"object\" && typeof module.exports === \"object\") {\n        // commonjs\n\n        // 引用 css —— webapck\n        window.wangEditorCssPath ? require(window.wangEditorCssPath) : require('../css/wangEditor.css');\n        module.exports = factory(\n            // 传入 jquery ，支持使用 npm 方式或者自己定义jquery的路径\n            window.wangEditorJQueryPath ? require(window.wangEditorJQueryPath) : require('jquery')\n        );\n    } else {\n        // 全局模式\n        factory(window.jQuery);\n    }\n})(function($){\n    \n    // 验证是否引用jquery\n    if (!$ || !$.fn || !$.fn.jquery) {\n        alert('在引用wangEditor.js之前，先引用jQuery，否则无法使用 wangEditor');\n        return;\n    }\n\n    // 定义扩展函数\n    var _e = function (fn) {\n        var E = window.wangEditor;\n        if (E) {\n            // 执行传入的函数\n            fn(E, $);\n        }\n    };\n// 定义构造函数\n(function (window, $) {\n    if (window.wangEditor) {\n        // 重复引用\n        alert('一个页面不能重复引用 wangEditor.js 或 wangEditor.min.js ！！！');\n        return;\n    }\n\n    // 编辑器（整体）构造函数\n    var E = function (elem) {\n        // 支持 id 和 element 两种形式\n        if (typeof elem === 'string') {\n            elem = '#' + elem;\n        }\n\n        // ---------------获取基本节点------------------\n        var $elem = $(elem);\n        if ($elem.length !== 1) {\n            return;\n        }\n        var nodeName = $elem[0].nodeName;\n        if (nodeName !== 'TEXTAREA' && nodeName !== 'DIV') {\n            // 只能是 textarea 和 div ，其他类型的元素不行\n            return;   \n        }\n        this.valueNodeName = nodeName.toLowerCase();\n        this.$valueContainer = $elem;\n\n        // 记录 elem 的 prev 和 parent（最后渲染 editor 要用到）\n        this.$prev = $elem.prev();\n        this.$parent = $elem.parent();\n\n        // ------------------初始化------------------\n        this.init();\n    };\n\n    E.fn = E.prototype;\n\n    E.$body = $('body');\n    E.$document = $(document);\n    E.$window = $(window);\n    E.userAgent = navigator.userAgent;\n    E.getComputedStyle = window.getComputedStyle;\n    E.w3cRange = typeof document.createRange === 'function';\n    E.hostname = location.hostname.toLowerCase();\n    E.websiteHost = 'wangeditor.github.io|www.wangeditor.com|wangeditor.coding.me';\n    E.isOnWebsite = E.websiteHost.indexOf(E.hostname) >= 0;\n    E.docsite = 'http://www.kancloud.cn/wangfupeng/wangeditor2/113961';\n\n    // 暴露给全局对象\n    window.wangEditor = E;\n\n    // 注册 plugin 事件，用于用户自定义插件\n    // 用户在引用 wangEditor.js 之后，还可以通过 E.plugin() 注入自定义函数，\n    // 该函数将会在 editor.create() 方法的最后一步执行\n    E.plugin = function (fn) {\n        if (!E._plugins) {\n            E._plugins = [];\n        }\n\n        if (typeof fn === 'function') {\n            E._plugins.push(fn);\n        }\n    };\n\n})(window, $);\n// editor 绑定事件\n_e(function (E, $) {\n\n    E.fn.init = function () {\n\n        // 初始化 editor 默认配置\n        this.initDefaultConfig();\n\n        // 增加container\n        this.addEditorContainer();\n\n        // 增加编辑区域\n        this.addTxt();\n\n        // 增加menuContainer\n        this.addMenuContainer();\n\n        // 初始化菜单集合\n        this.menus = {};\n\n        // 初始化commandHooks\n        this.commandHooks();\n\n    };\n\n});\n// editor api\n_e(function (E, $) {\n\n    // 预定义 ready 事件\n    E.fn.ready = function (fn) {\n\n        if (!this.readyFns) {\n            this.readyFns = [];\n        }\n\n        this.readyFns.push(fn);\n    };\n\n    // 处理ready事件\n    E.fn.readyHeadler = function () {\n        var fns = this.readyFns;\n\n        while (fns.length) {\n            fns.shift().call(this);\n        }\n    };\n\n    // 更新内容到 $valueContainer\n    E.fn.updateValue = function () {\n        var editor = this;\n        var $valueContainer = editor.$valueContainer;\n        var $txt = editor.txt.$txt;\n\n        if ($valueContainer === $txt) {\n            // 传入生成编辑器的div，即是编辑区域\n            return;\n        }\n\n        var value = $txt.html();\n        $valueContainer.val(value);\n    };\n\n    // 获取初始化的内容\n    E.fn.getInitValue = function () {\n        var editor = this;\n        var $valueContainer = editor.$valueContainer;\n        var currentValue = '';\n        var nodeName = editor.valueNodeName;\n        if (nodeName === 'div') {\n            currentValue = $valueContainer.html();\n        } else if (nodeName === 'textarea') {\n            currentValue = $valueContainer.val();\n        }\n\n        return currentValue;\n    };\n\n    // 触发菜单updatestyle\n    E.fn.updateMenuStyle = function () {\n        var menus = this.menus;\n\n        $.each(menus, function (k, menu) {\n            menu.updateSelected();\n        });\n    };\n\n    // 除了传入的 menuIds，其他全部启用\n    E.fn.enableMenusExcept = function (menuIds) {\n        if (this._disabled) {\n            // 编辑器处于禁用状态，则不执行改操作\n            return;\n        }\n        // menuIds参数：支持数组和字符串\n        menuIds = menuIds || [];\n        if (typeof menuIds === 'string') {\n            menuIds = [menuIds];\n        }\n\n        $.each(this.menus, function (k, menu) {\n            if (menuIds.indexOf(k) >= 0) {\n                return;\n            }\n            menu.disabled(false);\n        });\n    };\n\n    // 除了传入的 menuIds，其他全部禁用\n    E.fn.disableMenusExcept = function (menuIds) {\n        if (this._disabled) {\n            // 编辑器处于禁用状态，则不执行改操作\n            return;\n        }\n        // menuIds参数：支持数组和字符串\n        menuIds = menuIds || [];\n        if (typeof menuIds === 'string') {\n            menuIds = [menuIds];\n        }\n\n        $.each(this.menus, function (k, menu) {\n            if (menuIds.indexOf(k) >= 0) {\n                return;\n            }\n            menu.disabled(true);\n        });\n    };\n\n    // 隐藏所有 dropPanel droplist modal\n    E.fn.hideDropPanelAndModal = function () {\n        var menus = this.menus;\n\n        $.each(menus, function (k, menu) {\n            var m = menu.dropPanel || menu.dropList || menu.modal;\n            if (m && m.hide) {\n                m.hide();\n            }\n        });\n    };\n\n});\n// selection range API\n_e(function (E, $) {\n\n    // 用到 w3c range 的函数，如果检测到浏览器不支持 w3c range，则赋值为空函数\n    var ieRange = !E.w3cRange;\n    function emptyFn() {}\n\n    // 设置或读取当前的range\n    E.fn.currentRange = function (cr){\n        if (cr) {\n            this._rangeData = cr;\n        } else {\n            return this._rangeData;\n        }\n    };\n\n    // 将当前选区折叠\n    E.fn.collapseRange = function (range, opt) {\n        // opt 参数说明：'start'-折叠到开始; 'end'-折叠到结束\n        opt = opt || 'end';\n        opt = opt === 'start' ? true : false;\n\n        range = range || this.currentRange();\n        \n        if (range) {\n            // 合并，保存\n            range.collapse(opt);\n            this.currentRange(range);\n        }\n    };\n\n    // 获取选区的文字\n    E.fn.getRangeText = ieRange ? emptyFn : function (range) {\n        range = range || this.currentRange();\n        if (!range) {\n            return;\n        }\n        return range.toString();\n    };\n\n    // 获取选区对应的DOM对象\n    E.fn.getRangeElem = ieRange ? emptyFn : function (range) {\n        range = range || this.currentRange();\n        var dom = range.commonAncestorContainer;\n\n        if (dom.nodeType === 1) {\n            return dom;\n        } else {\n            return dom.parentNode;\n        }\n    };\n\n    // 选区内容是否为空？\n    E.fn.isRangeEmpty = ieRange ? emptyFn : function (range) {\n        range = range || this.currentRange();\n\n        if (range && range.startContainer) {\n            if (range.startContainer === range.endContainer) {\n                if (range.startOffset === range.endOffset) {\n                    return true;\n                }\n            }\n        }\n\n        return false;\n    };\n\n    // 保存选区数据\n    E.fn.saveSelection = ieRange ? emptyFn : function (range) {\n        var self = this,\n            _parentElem,\n            selection,\n            txt = self.txt.$txt.get(0);\n\n        if (range) {\n            _parentElem = range.commonAncestorContainer;\n        } else {\n            selection = document.getSelection();\n            if (selection.getRangeAt && selection.rangeCount) {\n                range = document.getSelection().getRangeAt(0);\n                _parentElem = range.commonAncestorContainer;\n            }\n        }\n        // 确定父元素一定要包含在编辑器区域内\n        if (_parentElem && ($.contains(txt, _parentElem) || txt === _parentElem) ) {\n            // 保存选择区域\n            self.currentRange(range);\n        }\n    };\n\n    // 恢复选中区域\n    E.fn.restoreSelection = ieRange ? emptyFn : function (range) {\n        var selection;\n\n        range = range || this.currentRange();\n\n        if (!range) {\n            return;\n        }\n\n        // 使用 try catch 来防止 IE 某些情况报错\n        try {\n            selection = document.getSelection();\n            selection.removeAllRanges();\n            selection.addRange(range);\n        } catch (ex) {\n            E.error('执行 editor.restoreSelection 时，IE可能会有异常，不影响使用');\n        }\n    };\n\n    // 根据elem恢复选区\n    E.fn.restoreSelectionByElem = ieRange ? emptyFn : function (elem, opt) {\n        // opt参数说明：'start'-折叠到开始，'end'-折叠到结束，'all'-全部选中\n        if (!elem) {\n            return;\n        }\n        opt = opt || 'end'; // 默认为折叠到结束\n\n        // 根据elem获取选区\n        this.setRangeByElem(elem);\n\n        // 根据 opt 折叠选区\n        if (opt === 'start') {\n            this.collapseRange(this.currentRange(), 'start');\n        }\n        if (opt === 'end') {\n            this.collapseRange(this.currentRange(), 'end');\n        }\n        \n        // 恢复选区\n        this.restoreSelection();\n    };\n\n    // 初始化选区\n    E.fn.initSelection = ieRange ? emptyFn : function () {\n        var editor = this;\n        if( editor.currentRange() ){\n            //如果currentRange有值，则不用再初始化\n            return;\n        }\n\n        var range;\n        var $txt = editor.txt.$txt;\n        var $firstChild = $txt.children().first();\n        \n        if ($firstChild.length) {\n            editor.restoreSelectionByElem($firstChild.get(0));\n        }\n    };\n\n    // 根据元素创建选区\n    E.fn.setRangeByElem = ieRange ? emptyFn : function (elem) {\n        var editor = this;\n        var txtElem = editor.txt.$txt.get(0);\n        if (!elem || !$.contains(txtElem, elem)) {\n            return;\n        }\n\n        // 找到elem的第一个 textNode 和 最后一个 textNode\n        var firstTextNode = elem.firstChild;\n        while (firstTextNode) {\n            if (firstTextNode.nodeType === 3) {\n                break;\n            }\n            // 继续向下\n            firstTextNode = firstTextNode.firstChild;\n        }\n        var lastTextNode = elem.lastChild;\n        while (lastTextNode) {\n            if (lastTextNode.nodeType === 3) {\n                break;\n            }\n            // 继续向下\n            lastTextNode = lastTextNode.lastChild;\n        }\n        \n        var range = document.createRange();\n        if (firstTextNode && lastTextNode) {\n            // 说明 elem 有内容，能取到子元素\n            range.setStart(firstTextNode, 0);\n            range.setEnd(lastTextNode, lastTextNode.textContent.length);\n        } else {\n            // 说明 elem 无内容\n            range.setStart(elem, 0);\n            range.setEnd(elem, 0);\n        }\n\n        // 保存选区\n        editor.saveSelection(range);\n    };\n\n});\n// selection range API - IE8及以下\n_e(function (E, $) {\n\n    if (E.w3cRange) {\n        // 说明支持 W3C 的range方法\n        return;\n    }\n\n    // -----------------IE8时，需要重写以下方法-------------------\n\n    // 获取选区的文字\n    E.fn.getRangeText = function (range) {\n        range = range || this.currentRange();\n        if (!range) {\n            return;\n        }\n        return range.text;\n    };\n\n    // 获取选区对应的DOM对象\n    E.fn.getRangeElem = function (range) {\n        range = range || this.currentRange();\n        if (!range) {\n            return;\n        }\n        var dom = range.parentElement();\n\n        if (dom.nodeType === 1) {\n            return dom;\n        } else {\n            return dom.parentNode;\n        }\n    };\n\n    // 选区内容是否为空？\n    E.fn.isRangeEmpty = function (range) {\n        range = range || this.currentRange();\n\n        if (range && range.text) {\n            return false;\n        }\n\n        return true;\n    };\n\n    // 保存选区数据\n    E.fn.saveSelection = function (range) {\n        var self = this,\n            _parentElem,\n            selection,\n            txt = self.txt.$txt.get(0);\n\n        if (range) {\n            _parentElem = range.parentElement();\n        } else {\n            range = document.selection.createRange();\n            if(typeof range.parentElement === 'undefined'){\n                //IE6、7中，insertImage后会执行此处\n                //由于找不到range.parentElement，所以干脆将_parentElem赋值为null\n                _parentElem = null;\n            }else{\n                _parentElem = range.parentElement();\n            }\n        }\n\n        // 确定父元素一定要包含在编辑器区域内\n        if (_parentElem && ($.contains(txt, _parentElem) || txt === _parentElem) ) {\n            // 保存选择区域\n            self.currentRange(range);\n        }\n    };\n\n    // 恢复选中区域\n    E.fn.restoreSelection = function (currentRange){\n        var editor = this,\n            selection,\n            range;\n\n        currentRange = currentRange || editor.currentRange();\n        if(!currentRange){\n            return;\n        }\n\n        range = document.selection.createRange();\n        try {\n            // 此处，plupload上传上传图片时，IE8-会报一个『参数无效』的错误\n            range.setEndPoint('EndToEnd', currentRange);\n        } catch (ex) {\n\n        }\n        \n        if(currentRange.text.length === 0){\n            try {\n                // IE8 插入表情会报错\n                range.collapse(false);\n            } catch (ex) {\n                \n            }\n            \n        }else{\n            range.setEndPoint('StartToStart', currentRange);\n        }\n        range.select();\n    };\n\n});\n// editor command hooks\n_e(function (E, $) {\n    \n    E.fn.commandHooks = function () {\n        var editor = this;\n        var commandHooks = {};\n        \n        // insertHtml\n        commandHooks.insertHtml = function (html) {\n            var $elem = $(html);\n            var rangeElem = editor.getRangeElem();\n            var targetElem;\n            \n            targetElem = editor.getLegalTags(rangeElem);\n            if (!targetElem) {\n                return;\n            }\n\n            $(targetElem).after($elem);\n        };\n\n        // 保存到对象\n        editor.commandHooks = commandHooks;\n    };\n\n});\n// editor command API\n_e(function (E, $) {\n\n    // 基本命令\n    E.fn.command = function (e, commandName, commandValue, callback) {\n        var editor = this;\n        var hooks;\n        \n        function commandFn() {\n            if (!commandName) {\n                return;\n            }\n            if (editor.queryCommandSupported(commandName)) {\n                // 默认命令\n                document.execCommand(commandName, false, commandValue);\n            } else {\n                // hooks 命令\n                hooks = editor.commandHooks;\n                if (commandName in hooks) {\n                    hooks[commandName](commandValue);\n                }\n            }\n        }\n\n        this.customCommand(e, commandFn, callback);\n    };\n\n    // 针对一个elem对象执行基础命令\n    E.fn.commandForElem = function (elemOpt, e, commandName, commandValue, callback) {\n        // 取得查询elem的查询条件和验证函数\n        var selector;\n        var check;\n        if (typeof elemOpt === 'string') {\n            selector = elemOpt;\n        } else {\n            selector = elemOpt.selector;\n            check = elemOpt.check;\n        }\n\n        // 查询elem\n        var rangeElem = this.getRangeElem();\n        rangeElem = this.getSelfOrParentByName(rangeElem, selector, check);\n\n        // 根据elem设置range\n        if (rangeElem) {\n            this.setRangeByElem(rangeElem);\n        }\n\n        // 然后执行基础命令\n        this.command(e, commandName, commandValue, callback);\n    };\n\n    // 自定义命令\n    E.fn.customCommand = function (e, commandFn, callback) {\n        var editor = this;\n        var range = editor.currentRange();\n\n        if (!range) {\n            // 目前没有选区，则无法执行命令\n            e && e.preventDefault();\n            return;\n        }\n        // 记录内容，以便撤销（执行命令之前就要记录）\n        editor.undoRecord();\n\n        // 恢复选区（有 range 参数）\n        this.restoreSelection(range);\n\n        // 执行命令事件\n        commandFn.call(editor);\n\n        // 保存选区（无参数，要从浏览器直接获取range信息）\n        this.saveSelection();\n        // 重新恢复选区（无参数，要取得刚刚从浏览器得到的range信息）\n        this.restoreSelection();\n\n        // 执行 callback\n        if (callback && typeof callback === 'function') {\n            callback.call(editor);\n        }\n\n        // 最后插入空行\n        editor.txt.insertEmptyP();\n\n        // 包裹暴露的img和text\n        editor.txt.wrapImgAndText();\n\n        // 更新内容\n        editor.updateValue();\n\n        // 更新菜单样式\n        editor.updateMenuStyle();\n\n        // 隐藏 dropPanel dropList modal  设置 200ms 间隔\n        function hidePanelAndModal() {\n            editor.hideDropPanelAndModal();\n        } \n        setTimeout(hidePanelAndModal, 200);\n\n        if (e) {\n            e.preventDefault();\n        }\n    };\n\n    // 封装 document.queryCommandValue 函数\n    // IE8 直接执行偶尔会报错，因此直接用 try catch 封装一下\n    E.fn.queryCommandValue = function (commandName) {\n        var result = '';\n        try {\n            result = document.queryCommandValue(commandName);\n        } catch (ex) {\n\n        }\n        return result;\n    };\n\n    // 封装 document.queryCommandState 函数\n    // IE8 直接执行偶尔会报错，因此直接用 try catch 封装一下\n    E.fn.queryCommandState = function (commandName) {\n        var result = false;\n        try {\n            result = document.queryCommandState(commandName);\n        } catch (ex) {\n\n        }\n        return result;\n    };\n\n    // 封装 document.queryCommandSupported 函数\n    E.fn.queryCommandSupported = function (commandName) {\n        var result = false;\n        try {\n            result = document.queryCommandSupported(commandName);\n        } catch (ex) {\n\n        }\n        return result;\n    };\n\n});\n// dom selector\n_e(function (E, $) {\n\n    var matchesSelector;\n\n    // matchesSelector hook\n    function _matchesSelectorForIE(selector) {\n        var elem = this;\n        var $elems = $(selector);\n        var result = false;\n\n        // 用jquery查找 selector 所有对象，如果其中有一个和传入 elem 相同，则证明 elem 符合 selector\n        $elems.each(function () {\n            if (this === elem) {\n                result = true;\n                return false;\n            }\n        });\n\n        return result;\n    }\n\n    // 从当前的elem，往上去查找合法标签 如 p head table blockquote ul ol 等\n    E.fn.getLegalTags = function (elem) {\n        var legalTags = this.config.legalTags;\n        if (!legalTags) {\n            E.error('配置项中缺少 legalTags 的配置');\n            return;\n        }\n        return this.getSelfOrParentByName(elem, legalTags);\n    };\n\n    // 根据条件，查询自身或者父元素，符合即返回\n    E.fn.getSelfOrParentByName = function (elem, selector, check) {\n\n        if (!elem || !selector) {\n            return;\n        }\n\n        if (!matchesSelector) {\n            // 定义 matchesSelector 函数\n            matchesSelector = elem.webkitMatchesSelector || \n                              elem.mozMatchesSelector ||\n                              elem.oMatchesSelector || \n                              elem.matchesSelector;\n        }\n        if (!matchesSelector) {\n            // 如果浏览器本身不支持 matchesSelector 则使用自定义的hook\n            matchesSelector = _matchesSelectorForIE;\n        }\n\n        var txt = this.txt.$txt.get(0);\n\n        while (elem && txt !== elem && $.contains(txt, elem)) {\n            if (matchesSelector.call(elem, selector)) {\n                // 符合 selector 查询条件\n\n                if (!check) {\n                    // 没有 check 验证函数，直接返回即可\n                    return elem;\n                }\n\n                if (check(elem)) {\n                    // 如果有 check 验证函数，还需 check 函数的确认\n                    return elem;\n                }\n            }\n\n            // 如果上一步没经过验证，则将跳转到父元素\n            elem = elem.parentNode;\n        }\n\n        return;\n    };\n\n});\n// undo redo\n_e(function (E, $) {\n\n    var length = 20;  // 缓存的最大长度\n    function _getRedoList(editor) {\n        if (editor._redoList == null) {\n            editor._redoList = [];\n        }\n        return editor._redoList;\n    }\n    function _getUndoList(editor) {\n        if (editor._undoList == null) {\n            editor._undoList = [];\n        }\n        return editor._undoList;\n    }\n\n    // 数据处理\n    function _handle(editor, data, type) {\n        // var range = data.range;\n        // var range2 = range.cloneRange && range.cloneRange();\n        var val = data.val;\n        var html = editor.txt.$txt.html();\n\n        if(val == null) {\n            return;\n        }\n\n        if (val === html) {\n            if (type === 'redo') { \n                editor.redo();\n                return;\n            } else if (type === 'undo') {\n                editor.undo();\n                return;\n            } else {\n                return;\n            }\n        }\n\n        // 保存数据\n        editor.txt.$txt.html(val);\n        // 更新数据到textarea（有必要的话）\n        editor.updateValue();\n\n        // onchange 事件\n        if (editor.onchange && typeof editor.onchange === 'function') {\n            editor.onchange.call(editor);\n        }\n\n        // ?????\n        // 注释：$txt 被重新赋值之后，range会被重置，cloneRange() 也不好使\n        // // 重置选区\n        // if (range2) {\n        //     editor.restoreSelection(range2);\n        // }\n    }\n\n    // 记录\n    E.fn.undoRecord = function () {\n        var editor = this;\n        var $txt = editor.txt.$txt;\n        var val = $txt.html();\n        var undoList = _getUndoList(editor);\n        var redoList = _getRedoList(editor);\n        var currentVal = undoList.length ? undoList[0] : '';\n\n        if (val === currentVal.val) {\n            return;\n        }\n\n        // 清空 redolist\n        if (redoList.length) {\n            redoList = [];\n        }\n\n        // 添加数据到 undoList\n        undoList.unshift({\n            range: editor.currentRange(),  // 将当前的range也记录下\n            val: val\n        });\n\n        // 限制 undoList 长度\n        if (undoList.length > length) {\n            undoList.pop();\n        }\n    };\n\n    // undo 操作\n    E.fn.undo = function () {\n        var editor = this;\n        var undoList = _getUndoList(editor);\n        var redoList = _getRedoList(editor);\n\n        if (!undoList.length) {\n            return;\n        }\n\n        // 取出 undolist 第一个值，加入 redolist\n        var data = undoList.shift();\n        redoList.unshift(data);\n\n        // 并修改编辑器的内容\n        _handle(this, data, 'undo');\n    };\n\n    // redo 操作\n    E.fn.redo = function () {\n        var editor = this;\n        var undoList = _getUndoList(editor);\n        var redoList = _getRedoList(editor);\n        if (!redoList.length) {\n            return;\n        }\n\n        // 取出 redolist 第一个值，加入 undolist\n        var data = redoList.shift();\n        undoList.unshift(data);\n\n        // 并修改编辑器的内容\n        _handle(this, data, 'redo');\n    };\n});\n// 暴露给用户的 API\n_e(function (E, $) {\n\n    // 创建编辑器\n    E.fn.create = function () {\n        var editor = this;\n\n        // 检查 E.$body 是否有值\n        // 如果在 body 之前引用了 js 文件，body 尚未加载，可能没有值\n        if (!E.$body || E.$body.length === 0) {\n            E.$body = $('body');\n            E.$document = $(document);\n            E.$window = $(window);\n        }\n\n        // 执行 addMenus 之前：\n        // 1. 允许用户修改 editor.UI 自定义配置UI\n        // 2. 允许用户通过修改 editor.menus 来自定义配置菜单\n        // 因此要在 create 时执行，而不是 init           \n        editor.addMenus();\n\n        // 渲染\n        editor.renderMenus();\n        editor.renderMenuContainer();\n        editor.renderTxt();\n        editor.renderEditorContainer();\n\n        // 绑定事件\n        editor.eventMenus();\n        editor.eventMenuContainer();\n        editor.eventTxt();\n\n        // 处理ready事件\n        editor.readyHeadler();\n\n        // 初始化选区\n        editor.initSelection();\n\n        // $txt 快捷方式\n        editor.$txt = editor.txt.$txt;\n\n        // 执行用户自定义事件，通过 E.ready() 添加\n        var _plugins = E._plugins;\n        if (_plugins && _plugins.length) {\n            $.each(_plugins, function (k, val) {\n                val.call(editor);\n            });\n        }\n    };\n\n    // 禁用编辑器\n    E.fn.disable = function () {\n        this.txt.$txt.removeAttr('contenteditable');\n        this.disableMenusExcept();\n\n        // 先禁用，再记录状态\n        this._disabled = true;\n    };\n    // 启用编辑器\n    E.fn.enable = function () {\n        // 先解除状态记录，再启用\n        this._disabled = false;\n        this.txt.$txt.attr('contenteditable', 'true');\n        this.enableMenusExcept();\n    };\n\n    // 销毁编辑器\n    E.fn.destroy = function () {\n        var self = this;\n        var $valueContainer = self.$valueContainer;\n        var $editorContainer = self.$editorContainer;\n        var valueNodeName = self.valueNodeName;\n\n        if (valueNodeName === 'div') {\n            // div 生成的编辑器\n            $valueContainer.removeAttr('contenteditable');\n            $editorContainer.after($valueContainer);\n            $editorContainer.hide();\n        } else {\n            // textarea 生成的编辑器\n            $valueContainer.show();\n            $editorContainer.hide();\n        }\n    };\n\n    // 撤销 销毁编辑器\n    E.fn.undestroy = function () {\n        var self = this;\n        var $valueContainer = self.$valueContainer;\n        var $editorContainer = self.$editorContainer;\n        var $menuContainer = self.menuContainer.$menuContainer;\n        var valueNodeName = self.valueNodeName;\n\n        if (valueNodeName === 'div') {\n            // div 生成的编辑器\n            $valueContainer.attr('contenteditable', 'true');\n            $menuContainer.after($valueContainer);\n            $editorContainer.show();\n        } else {\n            // textarea 生成的编辑器\n            $valueContainer.hide();\n            $editorContainer.show();\n        }\n    };\n\n    // 清空内容的快捷方式\n    E.fn.clear = function () {\n        var editor = this;\n        var $txt = editor.txt.$txt;\n        $txt.html('<p><br></p>');\n        editor.restoreSelectionByElem($txt.find('p').get(0));\n    };\n\n});\n// menuContainer 构造函数\n_e(function (E, $) {\n\n    // 定义构造函数\n    var MenuContainer = function (editor) {\n        this.editor = editor;\n        this.init();\n    };\n\n    MenuContainer.fn = MenuContainer.prototype;\n\n    // 暴露给 E 即 window.wangEditor\n    E.MenuContainer = MenuContainer;\n\n});\n// MenuContainer.fn bind fn\n_e(function (E, $) {\n\n    var MenuContainer = E.MenuContainer;\n\n    // 初始化\n    MenuContainer.fn.init = function () {\n        var self = this;\n        var $menuContainer = $('<div class=\"wangEditor-menu-container clearfix\"></div>');\n\n        self.$menuContainer = $menuContainer;\n\n        // change shadow\n        self.changeShadow();\n    };\n\n    // 编辑区域滚动时，增加shadow\n    MenuContainer.fn.changeShadow = function () {\n        var $menuContainer = this.$menuContainer;\n        var editor = this.editor;\n        var $txt = editor.txt.$txt;\n\n        $txt.on('scroll', function () {\n            if ($txt.scrollTop() > 10) {\n                $menuContainer.addClass('wangEditor-menu-shadow');\n            } else {\n                $menuContainer.removeClass('wangEditor-menu-shadow');\n            }\n        });\n    };\n\n});\n// MenuContainer.fn API\n_e(function (E, $) {\n\n    var MenuContainer = E.MenuContainer;\n\n    MenuContainer.fn.render = function () {\n        var $menuContainer = this.$menuContainer;\n        var $editorContainer = this.editor.$editorContainer;\n\n        $editorContainer.append($menuContainer);\n    };\n    \n    // 获取菜单栏的高度\n    MenuContainer.fn.height = function () {\n        var $menuContainer = this.$menuContainer;\n        return $menuContainer.height();\n    };\n\n    // 添加菜单\n    MenuContainer.fn.appendMenu = function (groupIdx, menu) {\n        // 判断是否需要新增一个菜单组\n        this._addGroup(groupIdx);\n        // 增加菜单（返回 $menuItem）\n        return this._addOneMenu(menu);\n    };\n    MenuContainer.fn._addGroup = function (groupIdx) {\n        var $menuContainer = this.$menuContainer;\n        var $menuGroup;\n        if (!this.$currentGroup || this.currentGroupIdx !== groupIdx) {\n            $menuGroup = $('<div class=\"menu-group clearfix\"></div>');\n            $menuContainer.append($menuGroup);\n\n            this.$currentGroup = $menuGroup;\n            this.currentGroupIdx = groupIdx;\n        }\n    };\n    MenuContainer.fn._addOneMenu = function (menu) {\n        var $menuNormal = menu.$domNormal;\n        var $menuSelected = menu.$domSelected;\n\n        var $menuGroup = this.$currentGroup;\n        var $item = $('<div class=\"menu-item clearfix\"></div>');\n        $menuSelected.hide();\n        $item.append($menuNormal).append($menuSelected);\n        $menuGroup.append($item);\n\n        return $item;\n    };\n\n});\n// menu 构造函数\n_e(function (E, $) {\n\n    // 定义构造函数\n    var Menu = function (opt) {\n        this.editor = opt.editor;\n        this.id = opt.id;\n        this.title = opt.title;\n        this.$domNormal = opt.$domNormal;\n        this.$domSelected = opt.$domSelected || opt.$domNormal;\n\n        // document.execCommand 的参数\n        this.commandName = opt.commandName;\n        this.commandValue = opt.commandValue;\n        this.commandNameSelected = opt.commandNameSelected || opt.commandName;\n        this.commandValueSelected = opt.commandValueSelected || opt.commandValue;\n    };\n\n    Menu.fn = Menu.prototype;\n\n    // 暴露给 E 即 window.wangEditor\n    E.Menu = Menu;\n});\n// Menu.fn 初始化绑定的事件\n_e(function (E, $) {\n\n    var Menu = E.Menu;\n\n    // 初始化UI\n    Menu.fn.initUI = function () {\n        var editor = this.editor;\n        var uiConfig = editor.UI.menus;\n        var menuId = this.id;\n        var menuUI = uiConfig[menuId];\n\n        if (this.$domNormal && this.$domSelected) {\n            // 自定义的菜单中，已经传入了 $dom 无需从配置文件中查找生成\n            return;\n        }\n\n        if (menuUI == null) {\n            E.warn('editor.UI配置中，没有菜单 \"' + menuId + '\" 的UI配置，只能取默认值');\n            \n            // 必须写成 uiConfig['default'];\n            // 写成 uiConfig.default IE8会报错\n            menuUI = uiConfig['default'];\n        }\n\n        // 正常状态\n        this.$domNormal = $(menuUI.normal);\n\n        // 选中状态\n        if (/^\\./.test(menuUI.selected)) {\n            // 增加一个样式\n            this.$domSelected = this.$domNormal.clone().addClass(menuUI.selected.slice(1));\n        } else {\n            // 一个新的dom对象\n            this.$domSelected = $(menuUI.selected);\n        }\n    };\n\n});\n// Menu.fn API\n_e(function (E, $) {\n\n    var Menu = E.Menu;\n\n    // 渲染菜单\n    Menu.fn.render = function (groupIdx) {\n        // 渲染UI\n        this.initUI();\n        \n        var editor = this.editor;\n        var menuContainer = editor.menuContainer;\n        var $menuItem = menuContainer.appendMenu(groupIdx, this);\n        var onRender = this.onRender;\n\n        // 渲染tip\n        this._renderTip($menuItem);\n\n        // 执行 onRender 函数\n        if (onRender && typeof onRender === 'function') {\n            onRender.call(this);\n        }\n    };\n    Menu.fn._renderTip = function ($menuItem) {\n        var self = this;\n        var editor = self.editor;\n        var title = self.title;\n        var $tip = $('<div class=\"menu-tip\"></div>');\n        // var $triangle = $('<i class=\"tip-triangle\"></i>'); // 小三角\n\n        // 计算 tip 宽度\n        var $tempDiv;\n        if (!self.tipWidth) {\n            // 设置一个纯透明的 p（absolute;top:-10000px;不会显示在内容区域）\n            // 内容赋值为 title ，为了计算tip宽度\n            $tempDiv = $('<p style=\"opacity:0; filter:Alpha(opacity=0); position:absolute;top:-10000px;\">' + title + '</p>');\n            // 先添加到body，计算完再 remove\n            E.$body.append($tempDiv);\n            editor.ready(function () {\n                var editor = this;\n                var titleWidth = $tempDiv.outerWidth() + 5; // 多出 5px 的冗余\n                var currentWidth = $tip.outerWidth();\n                var currentMarginLeft = parseFloat($tip.css('margin-left'), 10);\n                // 计算完，拿到数据，则弃用\n                $tempDiv.remove();\n                $tempDiv = null;\n\n                // 重新设置样式\n                $tip.css({\n                    width: titleWidth,\n                    'margin-left': currentMarginLeft + (currentWidth - titleWidth)/2\n                });\n\n                // 存储\n                self.tipWidth = titleWidth;\n            });\n        }\n\n        // $tip.append($triangle);\n        $tip.append(title);\n        $menuItem.append($tip);\n\n        function show() {\n            $tip.show();\n        }\n        function hide() {\n            $tip.hide();\n        }\n\n        var timeoutId;\n        $menuItem.find('a').on('mouseenter', function (e) {\n            if (!self.active() && !self.disabled()) {\n                timeoutId = setTimeout(show, 200);\n            }\n        }).on('mouseleave', function (e) {\n            timeoutId && clearTimeout(timeoutId);\n            hide();\n        }).on('click', hide);\n    };\n\n    // 绑定事件\n    Menu.fn.bindEvent = function () {\n        var self = this;\n\n        var $domNormal = self.$domNormal;\n        var $domSelected = self.$domSelected;\n\n        // 试图获取该菜单定义的事件（未selected），没有则自己定义\n        var clickEvent = self.clickEvent;\n        if (!clickEvent) {\n            clickEvent = function (e) {\n                // -----------dropPanel dropList modal-----------\n                var dropObj = self.dropPanel || self.dropList || self.modal;\n                if (dropObj && dropObj.show) {\n                    if (dropObj.isShowing) {\n                        dropObj.hide();\n                    } else {\n                        dropObj.show();\n                    }\n                    return;\n                }\n\n                // -----------command-----------\n                var editor = self.editor;\n                var commandName;\n                var commandValue;\n\n                var selected = self.selected;\n                if (selected) {\n                    commandName = self.commandNameSelected;\n                    commandValue = self.commandValueSelected;\n                } else {\n                    commandName = self.commandName;\n                    commandValue = self.commandValue;\n                }\n\n                if (commandName) {\n                    // 执行命令\n                    editor.command(e, commandName, commandValue);\n                } else {\n                    // 提示\n                    E.warn('菜单 \"' + self.id + '\" 未定义click事件');\n                    e.preventDefault();\n                }\n            };\n        }\n        // 获取菜单定义的selected情况下的点击事件\n        var clickEventSelected = self.clickEventSelected || clickEvent;\n\n        // 将事件绑定到菜单dom上\n        $domNormal.click(function (e) {\n            if (!self.disabled()) {\n                clickEvent.call(self, e);\n                self.updateSelected();\n            }\n            e.preventDefault();\n        });\n        $domSelected.click(function (e) {\n            if (!self.disabled()) {\n                clickEventSelected.call(self, e);\n                self.updateSelected();\n            }\n            e.preventDefault();\n        });\n    };\n\n    // 更新选中状态\n    Menu.fn.updateSelected = function () {\n        var self = this;\n        var editor = self.editor;\n\n        // 试图获取用户自定义的判断事件\n        var updateSelectedEvent = self.updateSelectedEvent;\n        if (!updateSelectedEvent) {\n            // 用户未自定义，则设置默认值\n            updateSelectedEvent = function () {\n                var self = this;\n                var editor = self.editor;\n                var commandName = self.commandName;\n                var commandValue = self.commandValue;\n\n                if (commandValue) {\n                    if (editor.queryCommandValue(commandName).toLowerCase() === commandValue.toLowerCase()) {\n                        return true;\n                    }\n                } else if (editor.queryCommandState(commandName)) {\n                    return true;\n                }\n\n                return false;\n            };\n        }\n\n        // 获取结果\n        var result = updateSelectedEvent.call(self);\n        result = !!result;\n\n        // 存储结果、显示效果\n        self.changeSelectedState(result);\n    };\n\n    // 切换选中状态、显示效果\n    Menu.fn.changeSelectedState = function (state) {\n        var self = this;\n        var selected = self.selected;\n\n        if (state != null && typeof state === 'boolean') {\n            if (selected === state) {\n                // 计算结果和当前的状态一样\n                return;\n            }\n            // 存储结果\n            self.selected = state;\n\n            // 切换菜单的显示\n            if (state) {\n                // 选中\n                self.$domNormal.hide();\n                self.$domSelected.show();\n            } else {\n                // 未选中\n                self.$domNormal.show();\n                self.$domSelected.hide();\n            }\n        } // if\n    };\n\n    // 点击菜单，显示了 dropPanel modal 时，菜单的状态 \n    Menu.fn.active = function (active) {\n        if (active == null) {\n            return this._activeState;\n        }\n        this._activeState = active;\n    };\n    Menu.fn.activeStyle = function (active) {\n        var selected = this.selected;\n        var $dom = this.$domNormal;\n        var $domSelected = this.$domSelected;\n\n        if (active) {\n            $dom.addClass('active');\n            $domSelected.addClass('active');\n        } else {\n            $dom.removeClass('active');\n            $domSelected.removeClass('active');\n        }\n\n        // 记录状态 （ menu hover 时会取状态用 ）\n        this.active(active);\n    };\n\n    // 菜单的启用和禁用\n    Menu.fn.disabled = function (opt) {\n        // 参数为空，取值\n        if (opt == null) {\n            return !!this._disabled;\n        }\n\n        if (this._disabled === opt) {\n            // 要设置的参数值和当前参数只一样，无需再次设置\n            return;\n        }\n\n        var $dom = this.$domNormal;\n        var $domSelected = this.$domSelected;\n\n        // 设置样式\n        if (opt) {\n            $dom.addClass('disable');\n            $domSelected.addClass('disable');\n        } else {\n            $dom.removeClass('disable');\n            $domSelected.removeClass('disable');\n        }\n\n        // 存储\n        this._disabled = opt;\n    };\n\n});\n// dropList 构造函数\n_e(function (E, $) {\n\n    // 定义构造函数\n    var DropList = function (editor, menu, opt) {\n        this.editor = editor;\n        this.menu = menu;\n\n        // list 的数据源，格式 {'commandValue': 'title', ...}\n        this.data = opt.data;\n        // 要为每个item自定义的模板\n        this.tpl = opt.tpl;\n        // 为了执行 editor.commandForElem 而传入的elem查询方式\n        this.selectorForELemCommand = opt.selectorForELemCommand;\n\n        // 执行事件前后的钩子\n        this.beforeEvent = opt.beforeEvent;\n        this.afterEvent = opt.afterEvent;\n\n        // 初始化\n        this.init();\n    };\n\n    DropList.fn = DropList.prototype;\n\n    // 暴露给 E 即 window.wangEditor\n    E.DropList = DropList;\n});\n// dropList fn bind\n_e(function (E, $) {\n\n    var DropList = E.DropList;\n\n    // init\n    DropList.fn.init = function () {\n        var self = this;\n\n        // 生成dom对象\n        self.initDOM();\n\n        // 绑定command事件\n        self.bindEvent();\n\n        // 声明隐藏的事件\n        self.initHideEvent();\n    };\n\n    // 初始化dom结构\n    DropList.fn.initDOM = function () {\n        var self = this;\n        var data = self.data;\n        var tpl = self.tpl || '<span>{#title}</span>';\n        var $list = $('<div class=\"wangEditor-drop-list clearfix\"></div>');\n\n        var itemContent;\n        var $item;\n        $.each(data, function (commandValue, title) {\n            itemContent = tpl.replace(/{#commandValue}/ig, commandValue).replace(/{#title}/ig, title);\n            $item = $('<a href=\"#\" commandValue=\"' + commandValue + '\"></a>');\n            $item.append(itemContent);\n            $list.append($item);\n        });\n\n        self.$list = $list;\n    };\n\n    // 绑定事件\n    DropList.fn.bindEvent = function () {\n        var self = this;\n        var editor = self.editor;\n        var menu = self.menu;\n        var commandName = menu.commandName;\n        var selectorForELemCommand = self.selectorForELemCommand;\n        var $list = self.$list;\n\n        // 执行事件前后的钩子函数\n        var beforeEvent = self.beforeEvent;\n        var afterEvent = self.afterEvent;\n\n        $list.on('click', 'a[commandValue]', function (e) {\n            // 正式命令执行之前\n            if (beforeEvent && typeof beforeEvent === 'function') {\n                beforeEvent.call(e);\n            }\n\n            // 执行命令\n            var commandValue = $(e.currentTarget).attr('commandValue');\n            if (menu.selected && editor.isRangeEmpty() && selectorForELemCommand) {\n                // 当前处于选中状态，并且选中内容为空\n                editor.commandForElem(selectorForELemCommand, e, commandName, commandValue);\n            } else {\n                // 当前未处于选中状态，或者有选中内容。则执行默认命令\n                editor.command(e, commandName, commandValue);\n            }\n\n            // 正式命令之后的钩子\n            if (afterEvent && typeof afterEvent === 'function') {\n                afterEvent.call(e);\n            }\n        });\n    };\n\n    // 点击其他地方，立即隐藏 droplist\n    DropList.fn.initHideEvent = function () {\n        var self = this;\n\n        // 获取 list elem\n        var thisList = self.$list.get(0);\n\n        E.$body.on('click', function (e) {\n            if (!self.isShowing) {\n                return;\n            }\n            var trigger = e.target;\n\n            // 获取菜单elem\n            var menu = self.menu;\n            var menuDom;\n            if (menu.selected) {\n                menuDom = menu.$domSelected.get(0);\n            } else {\n                menuDom = menu.$domNormal.get(0);\n            }\n\n            if (menuDom === trigger || $.contains(menuDom, trigger)) {\n                // 说明由本菜单点击触发的\n                return;\n            }\n\n            if (thisList === trigger || $.contains(thisList, trigger)) {\n                // 说明由本list点击触发的\n                return;\n            }\n\n            // 其他情况，隐藏 list\n            self.hide();\n        });\n\n        E.$window.scroll(function () {\n            self.hide();\n        });\n\n        E.$window.on('resize', function () {\n            self.hide();\n        });\n    };\n\n});\n// dropListfn api\n_e(function (E, $) {\n    \n    var DropList = E.DropList;\n\n    // 渲染\n    DropList.fn._render = function () {\n        var self = this;\n        var editor = self.editor;\n        var $list = self.$list;\n\n        // 渲染到页面\n        editor.$editorContainer.append($list);\n\n        // 记录状态\n        self.rendered = true;\n    };\n\n    // 定位\n    DropList.fn._position = function () {\n        var self = this;\n        var $list = self.$list;\n        var editor = self.editor;\n        var menu = self.menu;\n        var $menuContainer = editor.menuContainer.$menuContainer;\n        var $menuDom = menu.selected ? menu.$domSelected : menu.$domNormal;\n        // 注意这里的 offsetParent() 要返回 .menu-item 的 position\n        // 因为 .menu-item 是 position:relative\n        var menuPosition = $menuDom.offsetParent().position();\n\n        // 取得 menu 的位置、尺寸属性\n        var menuTop = menuPosition.top;\n        var menuLeft = menuPosition.left;\n        var menuHeight = $menuDom.offsetParent().height();\n        var menuWidth = $menuDom.offsetParent().width();\n\n        // 取得 list 的尺寸属性\n        var listWidth = $list.outerWidth();\n        // var listHeight = $list.outerHeight();\n\n        // 取得 $txt 的尺寸\n        var txtWidth = editor.txt.$txt.outerWidth();\n\n        // ------------开始计算-------------\n\n        // 初步计算 list 位置属性\n        var top = menuTop + menuHeight;\n        var left = menuLeft + menuWidth/2;\n        var marginLeft = 0 - menuWidth/2;\n\n        // 如果超出了有边界，则要左移（且和右侧有间隙）\n        var valWithTxt = (left + listWidth) - txtWidth;\n        if (valWithTxt > -10) {\n            marginLeft = marginLeft - valWithTxt - 10;\n        }\n        // 设置样式\n        $list.css({\n            top: top,\n            left: left,\n            'margin-left': marginLeft\n        });\n\n        // 如果因为向下滚动而导致菜单fixed，则再加一步处理\n        if (editor._isMenufixed) {\n            top = top + (($menuContainer.offset().top + $menuContainer.outerHeight()) - $list.offset().top);\n\n            // 重新设置top\n            $list.css({\n                top: top\n            });\n        }\n    };\n\n    // 显示\n    DropList.fn.show = function () {\n        var self = this;\n        var menu = self.menu;\n        if (!self.rendered) {\n            // 第一次show之前，先渲染\n            self._render();\n        }\n\n        if (self.isShowing) {\n            return;\n        }\n\n        var $list = self.$list;\n        $list.show();\n\n        // 定位\n        self._position();\n\n        // 记录状态\n        self.isShowing = true;\n\n        // 菜单状态\n        menu.activeStyle(true);\n    };\n\n    // 隐藏\n    DropList.fn.hide = function () {\n        var self = this;\n        var menu = self.menu;\n        if (!self.isShowing) {\n            return;\n        }\n\n        var $list = self.$list;\n        $list.hide();\n\n        // 记录状态\n        self.isShowing = false;\n\n        // 菜单状态\n        menu.activeStyle(false);\n    };\n});\n// dropPanel 构造函数\n_e(function (E, $) {\n\n    // 定义构造函数\n    var DropPanel = function (editor, menu, opt) {\n        this.editor = editor;\n        this.menu = menu;\n        this.$content = opt.$content;\n        this.width = opt.width || 200;\n        this.height = opt.height;\n        this.onRender = opt.onRender;\n\n        // init\n        this.init();\n    };\n\n    DropPanel.fn = DropPanel.prototype;\n\n    // 暴露给 E 即 window.wangEditor\n    E.DropPanel = DropPanel;\n});\n// dropPanel fn bind\n_e(function (E, $) {\n\n    var DropPanel = E.DropPanel;\n\n    // init\n    DropPanel.fn.init = function () {\n        var self = this;\n\n        // 生成dom对象\n        self.initDOM();\n\n        // 声明隐藏的事件\n        self.initHideEvent();\n    };\n\n    // init DOM\n    DropPanel.fn.initDOM = function () {\n        var self = this;\n        var $content = self.$content;\n        var width = self.width;\n        var height = self.height;\n        var $panel = $('<div class=\"wangEditor-drop-panel clearfix\"></div>');\n        var $triangle = $('<div class=\"tip-triangle\"></div>');\n\n        $panel.css({\n            width: width,\n            height: height ? height : 'auto'\n        });\n        $panel.append($triangle);\n        $panel.append($content);\n\n        // 添加对象数据\n        self.$panel = $panel;\n        self.$triangle = $triangle;\n    };\n\n    // 点击其他地方，立即隐藏 dropPanel\n    DropPanel.fn.initHideEvent = function () {\n        var self = this;\n\n        // 获取 panel elem\n        var thisPanle = self.$panel.get(0);\n\n        E.$body.on('click', function (e) {\n            if (!self.isShowing) {\n                return;\n            }\n            var trigger = e.target;\n\n            // 获取菜单elem\n            var menu = self.menu;\n            var menuDom;\n            if (menu.selected) {\n                menuDom = menu.$domSelected.get(0);\n            } else {\n                menuDom = menu.$domNormal.get(0);\n            }\n\n            if (menuDom === trigger || $.contains(menuDom, trigger)) {\n                // 说明由本菜单点击触发的\n                return;\n            }\n\n            if (thisPanle === trigger || $.contains(thisPanle, trigger)) {\n                // 说明由本panel点击触发的\n                return;\n            }\n\n            // 其他情况，隐藏 panel\n            self.hide();\n        });\n\n        E.$window.scroll(function (e) {\n            self.hide();\n        });\n\n        E.$window.on('resize', function () {\n            self.hide();\n        });\n    };\n\n});\n// dropPanel fn api\n_e(function (E, $) {\n   \n    var DropPanel = E.DropPanel;\n\n    // 渲染\n    DropPanel.fn._render = function () {\n        var self = this;\n        var onRender = self.onRender;\n        var editor = self.editor;\n        var $panel = self.$panel;\n\n        // 渲染到页面\n        editor.$editorContainer.append($panel);\n\n        // 渲染后的回调事件\n        onRender && onRender.call(self);\n\n        // 记录状态\n        self.rendered = true;\n    };\n\n    // 定位\n    DropPanel.fn._position = function () {\n        var self = this;\n        var $panel = self.$panel;\n        var $triangle = self.$triangle;\n        var editor = self.editor;\n        var $menuContainer = editor.menuContainer.$menuContainer;\n        var menu = self.menu;\n        var $menuDom = menu.selected ? menu.$domSelected : menu.$domNormal;\n        // 注意这里的 offsetParent() 要返回 .menu-item 的 position\n        // 因为 .menu-item 是 position:relative\n        var menuPosition = $menuDom.offsetParent().position();\n\n        // 取得 menu 的位置、尺寸属性\n        var menuTop = menuPosition.top;\n        var menuLeft = menuPosition.left;\n        var menuHeight = $menuDom.offsetParent().height();\n        var menuWidth = $menuDom.offsetParent().width();\n\n        // 取得 panel 的尺寸属性\n        var panelWidth = $panel.outerWidth();\n        // var panelHeight = $panel.outerHeight();\n\n        // 取得 $txt 的尺寸\n        var txtWidth = editor.txt.$txt.outerWidth();\n\n        // ------------开始计算-------------\n\n        // 初步计算 panel 位置属性\n        var top = menuTop + menuHeight;\n        var left = menuLeft + menuWidth/2;\n        var marginLeft = 0 - panelWidth/2;\n        var marginLeft2 = marginLeft;  // 下文用于和 marginLeft 比较，来设置三角形tip的位置\n\n        // 如果超出了左边界，则移动回来（要和左侧有10px间隙）\n        if ((0 - marginLeft) > (left - 10)) {\n            marginLeft = 0 - (left - 10);\n        }\n\n        // 如果超出了有边界，则要左移（且和右侧有10px间隙）\n        var valWithTxt = (left + panelWidth + marginLeft) - txtWidth;\n        if (valWithTxt > -10) {\n            marginLeft = marginLeft - valWithTxt - 10;\n        }\n\n        // 设置样式\n        $panel.css({\n            top: top,\n            left: left,\n            'margin-left': marginLeft\n        });\n\n        // 如果因为向下滚动而导致菜单fixed，则再加一步处理\n        if (editor._isMenufixed) {\n            top = top + (($menuContainer.offset().top + $menuContainer.outerHeight()) - $panel.offset().top);\n\n            // 重新设置top\n            $panel.css({\n                top: top\n            });\n        }\n\n        // 设置三角形 tip 的位置\n        $triangle.css({\n            'margin-left': marginLeft2 - marginLeft - 5\n        });\n    };\n\n    // focus 第一个 input\n    DropPanel.fn.focusFirstInput = function () {\n        var self = this;\n        var $panel = self.$panel;\n        $panel.find('input[type=text],textarea').each(function () {\n            var $input = $(this);\n            if ($input.attr('disabled') == null) {\n                $input.focus();\n                return false;\n            }\n        });\n    };\n\n    // 显示\n    DropPanel.fn.show = function () {\n        var self = this;\n        var menu = self.menu;\n        if (!self.rendered) {\n            // 第一次show之前，先渲染\n            self._render();\n        }\n\n        if (self.isShowing) {\n            return;\n        }\n\n        var $panel = self.$panel;\n        $panel.show();\n\n        // 定位\n        self._position();\n\n        // 记录状态\n        self.isShowing = true;\n\n        // 菜单状态\n        menu.activeStyle(true);\n\n        if (E.w3cRange) {\n            // 高级浏览器\n            self.focusFirstInput();\n        } else {\n            // 兼容 IE8 input placeholder\n            E.placeholderForIE8($panel);\n        }\n    };\n\n    // 隐藏\n    DropPanel.fn.hide = function () {\n        var self = this;\n        var menu = self.menu;\n        if (!self.isShowing) {\n            return;\n        }\n\n        var $panel = self.$panel;\n        $panel.hide();\n\n        // 记录状态\n        self.isShowing = false;\n\n        // 菜单状态\n        menu.activeStyle(false);\n    };\n\n});\n// modal 构造函数\n_e(function (E, $) {\n\n    // 定义构造函数\n    var Modal = function (editor, menu, opt) {\n        this.editor = editor;\n        this.menu = menu;\n        this.$content = opt.$content;\n\n        this.init();\n    };\n\n    Modal.fn = Modal.prototype;\n\n    // 暴露给 E 即 window.wangEditor\n    E.Modal = Modal;\n});\n// modal fn bind\n_e(function (E, $) {\n\n    var Modal = E.Modal;\n\n    Modal.fn.init = function () {\n        var self = this;\n\n        // 初始化dom\n        self.initDom();\n\n        // 初始化隐藏事件\n        self.initHideEvent();\n    };\n\n    // 初始化dom\n    Modal.fn.initDom = function () {\n        var self = this;\n        var $content = self.$content;\n        var $modal = $('<div class=\"wangEditor-modal\"></div>');\n        var $close = $('<div class=\"wangEditor-modal-close\"><i class=\"wangeditor-menu-img-cancel-circle\"></i></div>');\n\n        $modal.append($close);\n        $modal.append($content);\n\n        // 记录数据\n        self.$modal = $modal;\n        self.$close = $close;\n    };\n\n    // 初始化隐藏事件\n    Modal.fn.initHideEvent = function () {\n        var self = this;\n        var $close = self.$close;\n        var modal = self.$modal.get(0);\n\n        // 点击 $close 按钮，隐藏\n        $close.click(function () {\n            self.hide();\n        });\n\n        // 点击其他部分，隐藏\n        E.$body.on('click', function (e) {\n            if (!self.isShowing) {\n                return;\n            }\n            var trigger = e.target;\n\n            // 获取菜单elem\n            var menu = self.menu;\n            var menuDom;\n            if (menu) {\n                if (menu.selected) {\n                    menuDom = menu.$domSelected.get(0);\n                } else {\n                    menuDom = menu.$domNormal.get(0);\n                }\n\n                if (menuDom === trigger || $.contains(menuDom, trigger)) {\n                    // 说明由本菜单点击触发的\n                    return;\n                }\n            }\n\n            if (modal === trigger || $.contains(modal, trigger)) {\n                // 说明由本panel点击触发的\n                return;\n            }\n\n            // 其他情况，隐藏 panel\n            self.hide();\n        });\n    };\n});\n// modal fn api\n_e(function (E, $) {\n\n    var Modal = E.Modal;\n\n    // 渲染\n    Modal.fn._render = function () {\n        var self = this;\n        var editor = self.editor;\n        var $modal = self.$modal;\n\n        // $modal的z-index，在配置的z-index基础上再 +10\n        $modal.css('z-index', editor.config.zindex + 10 + '');\n\n        // 渲染到body最后面\n        E.$body.append($modal);\n\n        // 记录状态\n        self.rendered = true;\n    };\n\n    // 定位\n    Modal.fn._position = function () {\n        var self = this;\n        var $modal = self.$modal;\n        var top = $modal.offset().top;\n        var width = $modal.outerWidth();\n        var height = $modal.outerHeight();\n        var marginLeft = 0 - (width / 2);\n        var marginTop = 0 - (height / 2);\n        var sTop = E.$window.scrollTop();\n\n        // 保证modal最顶部，不超过浏览器上边框\n        if ((height / 2) > top) {\n            marginTop = 0 - top;\n        }\n\n        $modal.css({\n            'margin-left': marginLeft + 'px',\n            'margin-top': (marginTop + sTop) + 'px'\n        });\n    };\n\n    // 显示\n    Modal.fn.show = function () {\n        var self = this;\n        var menu = self.menu;\n        if (!self.rendered) {\n            // 第一次show之前，先渲染\n            self._render();\n        }\n\n        if (self.isShowing) {\n            return;\n        }\n        // 记录状态\n        self.isShowing = true;\n\n        var $modal = self.$modal;\n        $modal.show();\n\n        // 定位\n        self._position();\n\n        // 激活菜单状态\n        menu && menu.activeStyle(true);\n    };\n\n    // 隐藏\n    Modal.fn.hide = function () {\n        var self = this;\n        var menu = self.menu;\n        if (!self.isShowing) {\n            return;\n        }\n        // 记录状态\n        self.isShowing = false;\n\n        // 隐藏\n        var $modal = self.$modal;\n        $modal.hide();\n\n        // 菜单状态\n        menu && menu.activeStyle(false);\n    };\n});\n// txt 构造函数\n_e(function (E, $) {\n\n    // 定义构造函数\n    var Txt = function (editor) {\n        this.editor = editor;\n\n        // 初始化\n        this.init();\n    };\n\n    Txt.fn = Txt.prototype;\n\n    // 暴露给 E 即 window.wangEditor\n    E.Txt = Txt;\n});\n// Txt.fn bind fn\n_e(function (E, $) {\n\n    var Txt = E.Txt;\n\n    // 初始化\n    Txt.fn.init = function () {\n        var self = this;\n        var editor = self.editor;\n        var $valueContainer = editor.$valueContainer;\n        var currentValue = editor.getInitValue();\n        var $txt;\n\n        if ($valueContainer.get(0).nodeName === 'DIV') {\n            // 如果传入生成编辑器的元素就是div，则直接使用\n            $txt = $valueContainer;\n            $txt.addClass(\"wangEditor-txt\");\n            $txt.attr('contentEditable', 'true');\n        } else {\n            // 如果不是div（是textarea），则创建一个div\n            $txt = $(\n                '<div class=\"wangEditor-txt\" contentEditable=\"true\">' +\n                    currentValue +\n                '</div>'\n            );\n        }\n\n        // 试图最后插入一个空行，ready之后才行\n        editor.ready(function () {\n            self.insertEmptyP();\n        });\n\n        self.$txt = $txt;\n\n        // 删除时，如果没有内容了，就添加一个 <p><br></p>\n        self.contentEmptyHandle();\n\n        // enter时，不能使用 div 换行\n        self.bindEnterForDiv();\n\n        // enter时，用 p 包裹 text\n        self.bindEnterForText();\n\n        // tab 插入4个空格\n        self.bindTabEvent();\n\n        // 处理粘贴内容\n        self.bindPasteFilter();\n\n        // $txt.formatText() 方法\n        self.bindFormatText();\n\n        // 定义 $txt.html() 方法\n        self.bindHtml();\n    };\n\n    // 删除时，如果没有内容了，就添加一个 <p><br></p>\n    Txt.fn.contentEmptyHandle = function () {\n        var self = this;\n        var editor = self.editor;\n        var $txt = self.$txt;\n        var $p;\n\n        $txt.on('keydown', function (e) {\n            if (e.keyCode !== 8) {\n                return;\n            }\n            var txtHtml = $.trim($txt.html().toLowerCase());\n            if (txtHtml === '<p><br></p>') {\n                // 如果最后还剩余一个空行，就不再继续删除了\n                e.preventDefault();\n                return;\n            }\n        });\n\n        $txt.on('keyup', function (e) {\n            if (e.keyCode !== 8) {\n                return;\n            }\n            var txtHtml = $.trim($txt.html().toLowerCase());\n            // ff时用 txtHtml === '<br>' 判断，其他用 !txtHtml 判断\n            if (!txtHtml || txtHtml === '<br>') {\n                // 内容空了\n                $p = $('<p><br/></p>');\n                $txt.html(''); // 一定要先清空，否则在 ff 下有问题\n                $txt.append($p);\n                editor.restoreSelectionByElem($p.get(0));\n            }\n        });\n    };\n\n    // enter时，不能使用 div 换行\n    Txt.fn.bindEnterForDiv = function () {\n        var tags = E.config.legalTags; // 配置中编辑器要求的合法标签，如 p head table blockquote ul ol 等\n        var self = this;\n        var editor = self.editor;\n        var $txt = self.$txt;\n\n        var $keydownDivElem;\n        function divHandler() {\n            if (!$keydownDivElem) {\n                return;\n            }\n\n            var $pElem = $('<p>' + $keydownDivElem.html() + '</p>');\n            $keydownDivElem.after($pElem);\n            $keydownDivElem.remove();\n        }\n\n        $txt.on('keydown keyup', function (e) {\n            if (e.keyCode !== 13) {\n                return;\n            }\n            // 查找合法标签\n            var rangeElem = editor.getRangeElem();\n            var targetElem = editor.getLegalTags(rangeElem);\n            var $targetElem;\n            var $pElem;\n\n            if (!targetElem) {\n                // 没找到合法标签，就去查找 div\n                targetElem = editor.getSelfOrParentByName(rangeElem, 'div');\n                if (!targetElem) {\n                    return;\n                }\n                $targetElem = $(targetElem);\n\n                if (e.type === 'keydown') {\n                    // 异步执行（同步执行会出现问题）\n                    $keydownDivElem = $targetElem;\n                    setTimeout(divHandler, 0);\n                }\n\n                if (e.type === 'keyup') {\n                    // 将 div 的内容移动到 p 里面，并移除 div\n                    $pElem = $('<p>' + $targetElem.html() + '</p>');\n                    $targetElem.after($pElem);\n                    $targetElem.remove();\n\n                    // 如果是回车结束，将选区定位到行首\n                    editor.restoreSelectionByElem($pElem.get(0), 'start');\n                }\n            }\n        });\n    };\n\n    // enter时，用 p 包裹 text\n    Txt.fn.bindEnterForText = function () {\n        var self = this;\n        var $txt = self.$txt;\n        var handle;\n        $txt.on('keyup', function (e) {\n            if (e.keyCode !== 13) {\n                return;\n            }\n            if (!handle) {\n                handle = function() {\n                    self.wrapImgAndText();\n                };\n            }\n            setTimeout(handle);\n        });\n    };\n\n    // tab 时，插入4个空格\n    Txt.fn.bindTabEvent = function () {\n        var self = this;\n        var editor = self.editor;\n        var $txt = self.$txt;\n\n        $txt.on('keydown', function (e) {\n            if (e.keyCode !== 9) {\n                // 只监听 tab 按钮\n                return;\n            }\n            // 如果浏览器支持 insertHtml 则插入4个空格。如果不支持，就不管了\n            if (editor.queryCommandSupported('insertHtml')) {\n                editor.command(e, 'insertHtml', '&nbsp;&nbsp;&nbsp;&nbsp;');\n            }\n        });\n    };\n\n    // 处理粘贴内容\n    Txt.fn.bindPasteFilter = function () {\n        var self = this;\n        var editor = self.editor;\n        var resultHtml = '';  //存储最终的结果\n        var $txt = self.$txt;\n        var legalTags = editor.config.legalTags;\n        var legalTagArr = legalTags.split(',');\n\n        $txt.on('paste', function (e) {\n            if (!editor.config.pasteFilter) {\n                // 配置中取消了粘贴过滤\n                return;\n            }\n\n            var currentNodeName = editor.getRangeElem().nodeName;\n            if (currentNodeName === 'TD' || currentNodeName === 'TH') {\n                // 在表格的单元格中粘贴，忽略所有内容。否则会出现异常情况\n                return;\n            }\n\n            resultHtml = ''; // 先清空 resultHtml\n\n            var pasteHtml, $paste;\n            var data = e.clipboardData || e.originalEvent.clipboardData;\n            var ieData = window.clipboardData;\n\n            if (editor.config.pasteText) {\n                // 只粘贴纯文本\n\n                if (data && data.getData) {\n                    // w3c\n                    pasteHtml = data.getData('text/plain');\n                } else if (ieData && ieData.getData) {\n                    // IE\n                    pasteHtml = ieData.getData('text');\n                } else {\n                    // 其他情况\n                    return;\n                }\n\n                // 拼接为 <p> 标签\n                if (pasteHtml) {\n                    resultHtml = '<p>' + pasteHtml + '</p>';\n                }\n\n            } else {\n                // 粘贴过滤了样式的、只有标签的 html\n\n                if (data && data.getData) {\n                    // w3c\n\n                    // 获取粘贴过来的html\n                    pasteHtml = data.getData('text/html');\n                    if (pasteHtml) {\n                        // 创建dom\n                        $paste = $('<div>' + pasteHtml + '</div>');\n                        // 处理，并将结果存储到 resultHtml 『全局』变量\n                        handle($paste.get(0));\n                    } else {\n                        // 得不到html，试图获取text\n                        pasteHtml = data.getData('text/plain');\n                        if (pasteHtml) {\n                            // 替换特殊字符\n                            pasteHtml = pasteHtml.replace(/[ ]/g, '&nbsp;')\n                                                 .replace(/</g, '&lt;')\n                                                 .replace(/>/g, '&gt;')\n                                                 .replace(/\\n/g, '</p><p>');\n                            // 拼接\n                            resultHtml = '<p>' + pasteHtml + '</p>';\n\n                            // 查询链接\n                            resultHtml = resultHtml.replace(/<p>(https?:\\/\\/.*?)<\\/p>/ig, function (match, link) {\n                                return '<p><a href=\"' + link + '\" target=\"_blank\">' + link + '</p>';\n                            });\n                        }\n                    }\n                    \n                } else if (ieData && ieData.getData) {\n                    // IE 直接从剪切板中取出纯文本格式\n                    resultHtml = ieData.getData('text');\n                    if (!resultHtml) {\n                        return;\n                    }\n                    // 拼接为 <p> 标签\n                    resultHtml = '<p>' + resultHtml + '</p>';\n                    resultHtml = resultHtml.replace(new RegExp('\\n', 'g'), '</p><p>');\n                } else {\n                    // 其他情况\n                    return;\n                }\n            }\n\n            // 执行命令\n            if (resultHtml) {\n                editor.command(e, 'insertHtml', resultHtml);\n\n                // 删除内容为空的 p 和嵌套的 p\n                self.clearEmptyOrNestP();\n            }\n        });\n\n        // 处理粘贴的内容\n        function handle(elem) {\n            if (!elem || !elem.nodeType || !elem.nodeName) {\n                return;\n            }\n            var $elem;\n            var nodeName = elem.nodeName.toLowerCase();\n            var nodeType = elem.nodeType;\n            var childNodesClone;\n\n            // 只处理文本和普通node标签\n            if (nodeType !== 3 && nodeType !== 1) {\n                return;\n            }\n\n            $elem = $(elem);\n\n            // 如果是容器，则继续深度遍历\n            if (nodeName === 'div') {\n                childNodesClone = [];\n                $.each(elem.childNodes, function (index, item) {\n                    // elem.childNodes 可获取TEXT节点，而 $elem.children() 就获取不到\n                    // 先将 elem.childNodes 拷贝一份，一面在循环递归过程中 elem 发生变化\n                    childNodesClone.push(item);\n                });\n                // 遍历子元素，执行操作\n                $.each(childNodesClone, function () {\n                    handle(this);\n                });\n                return;\n            }\n            \n            if (legalTagArr.indexOf(nodeName) >= 0) {\n                // 如果是合法标签之内的，则根据元素类型，获取值\n                resultHtml += getResult(elem);\n            } else if (nodeType === 3) {\n                // 如果是文本，则直接插入 p 标签\n                resultHtml += '<p>' + elem.textContent + '</p>';\n            } else if (nodeName === 'br') {\n                // <br>保留\n                resultHtml += '<br/>';\n            }\n            else {\n                // 忽略的标签\n                if (['meta', 'style', 'script', 'object', 'form', 'iframe', 'hr'].indexOf(nodeName) >= 0) {\n                    return;\n                }\n                // 其他标签，移除属性，插入 p 标签\n                $elem = $(removeAttrs(elem));\n                // 注意，这里的 clone() 是必须的，否则会出错\n                resultHtml += $('<div>').append($elem.clone()).html();\n            }\n        }\n\n        // 获取元素的结果\n        function getResult(elem) {\n            var nodeName = elem.nodeName.toLowerCase();\n            var $elem;\n            var htmlForP = '';\n            var htmlForLi = '';\n\n            if (['blockquote'].indexOf(nodeName) >= 0) {\n\n                // 直接取出元素text即可\n                $elem = $(elem);\n                return '<' + nodeName + '>' + $elem.text() + '</' + nodeName + '>';\n\n            } else if (['p', 'h1', 'h2', 'h3', 'h4', 'h5'].indexOf(nodeName) >= 0) {\n\n                //p head 取出 text 和链接\n                elem = removeAttrs(elem);\n                $elem = $(elem);\n                htmlForP = $elem.html();\n\n                // 剔除 a img 之外的元素\n                htmlForP = htmlForP.replace(/<.*?>/ig, function (tag) {\n                    if (tag === '</a>' || tag.indexOf('<a ') === 0 || tag.indexOf('<img ') === 0) {\n                        return tag;\n                    } else {\n                        return '';\n                    }\n                });\n\n                return '<' + nodeName + '>' + htmlForP + '</' + nodeName + '>';\n\n            } else if (['ul', 'ol'].indexOf(nodeName) >= 0) {\n                \n                // ul ol元素，获取子元素（li元素）的text link img，再拼接\n                $elem = $(elem);\n                $elem.children().each(function () {\n                    var $li = $(removeAttrs(this));\n                    var html = $li.html();\n\n                    html = html.replace(/<.*?>/ig, function (tag) {\n                        if (tag === '</a>' || tag.indexOf('<a ') === 0 || tag.indexOf('<img ') === 0) {\n                            return tag;\n                        } else {\n                            return '';\n                        }\n                    });\n\n                    htmlForLi += '<li>' + html + '</li>';\n                });\n                return '<' + nodeName + '>' + htmlForLi + '</' + nodeName + '>';\n            \n            } else {\n                \n                // 其他元素，移除元素属性\n                $elem = $(removeAttrs(elem));\n                return $('<div>').append($elem).html();\n            }\n        }\n\n        // 移除一个元素（子元素）的attr\n        function removeAttrs(elem) {\n            var attrs = elem.attributes || [];\n            var attrNames = [];\n            var exception = ['href', 'target', 'src', 'alt', 'rowspan', 'colspan']; //例外情况\n\n            // 先存储下elem中所有 attr 的名称\n            $.each(attrs, function (key, attr) {\n                if (attr && attr.nodeType === 2) {\n                    attrNames.push(attr.nodeName);\n                }\n            });\n            // 再根据名称删除所有attr\n            $.each(attrNames, function (key, attr) {\n                if (exception.indexOf(attr) < 0) {\n                    // 除了 exception 规定的例外情况，删除其他属性\n                    elem.removeAttribute(attr);\n                }\n            });\n\n\n            // 递归子节点\n            var children = elem.childNodes;\n            if (children.length) {\n                $.each(children, function (key, value) {\n                    removeAttrs(value);\n                });\n            }\n\n            return elem;\n        }\n    };\n\n    // 绑定 $txt.formatText() 方法\n    Txt.fn.bindFormatText = function () {\n        var self = this;\n        var editor = self.editor;\n        var $txt = self.$txt;\n        var legalTags = E.config.legalTags;\n        var legalTagArr = legalTags.split(',');\n        var length = legalTagArr.length;\n        var regArr = [];\n\n        // 将 E.config.legalTags 配置的有效字符，生成正则表达式\n        $.each(legalTagArr, function (k, tag) {\n            var reg = '\\>\\\\s*\\<(' + tag + ')\\>';\n            regArr.push(new RegExp(reg, 'ig'));\n        });\n\n        // 增加 li \n        regArr.push(new RegExp('\\>\\\\s*\\<(li)\\>', 'ig'));\n\n        // 增加 tr\n        regArr.push(new RegExp('\\>\\\\s*\\<(tr)\\>', 'ig'));\n\n        // 增加 code\n        regArr.push(new RegExp('\\>\\\\s*\\<(code)\\>', 'ig'));\n\n        // 生成 formatText 方法\n        $txt.formatText = function () {\n            var $temp = $('<div>');\n            var html = $txt.html();\n\n            // 去除空格\n            html = html.replace(/\\s*</ig, '<');\n\n            // 段落、表格之间换行\n            $.each(regArr, function (k, reg) {\n                if (!reg.test(html)) {\n                    return;\n                }\n                html = html.replace(reg, function (matchStr, tag) {\n                    return '>\\n<' + tag + '>';\n                });\n            });\n\n            $temp.html(html);\n            return $temp.text();\n        };\n    };\n\n    // 定制 $txt.html 方法\n    Txt.fn.bindHtml = function () {\n        var self = this;\n        var editor = self.editor;\n        var $txt = self.$txt;\n        var $valueContainer = editor.$valueContainer;\n        var valueNodeName = editor.valueNodeName;\n\n        $txt.html = function (html) {\n            var result;\n\n            if (valueNodeName === 'div') {\n                // div 生成的编辑器，取值、赋值，都直接触发jquery的html方法\n                result = $.fn.html.call($txt, html);\n            }\n\n            // textarea 生成的编辑器，则需要考虑赋值时，也给textarea赋值\n\n            if (html === undefined) {\n                // 取值，直接触发jquery原生html方法\n                result = $.fn.html.call($txt);\n\n                // 替换 html 中，src和href属性中的 & 字符。\n                // 因为 .html() 或者 .innerHTML 会把所有的 & 字符都改成 &amp; 但是 src 和 href 中的要保持 &\n                result = result.replace(/(href|src)\\=\\\"(.*)\\\"/igm, function (a, b, c) {\n                    return b + '=\"' + c.replace('&amp;', '&') + '\"';\n                });\n            } else {\n                // 赋值，需要同时给 textarea 赋值\n                result = $.fn.html.call($txt, html);\n                $valueContainer.val(html);\n            }\n\n            if (html === undefined) {\n                return result;\n            } else {\n                // 手动触发 change 事件，因为 $txt 监控了 change 事件来判断是否需要执行 editor.onchange \n                $txt.change();\n            }\n        };\n    };\n});\n// Txt.fn api\n_e(function (E, $) {\n\n    var Txt = E.Txt;\n\n    var txtChangeEventNames = 'propertychange change click keyup input paste';\n\n    // 渲染\n    Txt.fn.render = function () {\n        var $txt = this.$txt;\n        var $editorContainer = this.editor.$editorContainer;\n        $editorContainer.append($txt);\n    };\n\n    // 计算高度\n    Txt.fn.initHeight = function () {\n        var editor = this.editor;\n        var $txt = this.$txt;\n        var valueContainerHeight = editor.$valueContainer.height();\n        var menuHeight = editor.menuContainer.height();\n        var txtHeight = valueContainerHeight - menuHeight;\n\n        // 限制最小为 50px\n        txtHeight = txtHeight < 50 ? 50 : txtHeight;\n\n        $txt.height(txtHeight);\n\n        // 记录原始高度\n        editor.valueContainerHeight = valueContainerHeight;\n\n        // 设置 max-height\n        this.initMaxHeight(txtHeight, menuHeight);\n    };\n\n    // 计算最大高度\n    Txt.fn.initMaxHeight = function (txtHeight, menuHeight) {\n        var editor = this.editor;\n        var $menuContainer = editor.menuContainer.$menuContainer;\n        var $txt = this.$txt;\n        var $wrap = $('<div>');\n\n        // 需要浏览器支持 max-height，否则不管\n        if (window.getComputedStyle && 'max-height'in window.getComputedStyle($txt.get(0))) {\n            // 获取 max-height 并判断是否有值\n            var maxHeight = parseInt(editor.$valueContainer.css('max-height'));\n            if (isNaN(maxHeight)) {\n                return;\n            }\n\n            // max-height 和『全屏』暂时有冲突\n            if (editor.menus.fullscreen) {\n                E.warn('max-height和『全屏』菜单一起使用时，会有一些问题尚未解决，请暂时不要两个同时使用');\n                return;\n            }\n\n            // 标记\n            editor.useMaxHeight = true;\n\n            // 设置maxheight\n            $wrap.css({\n                'max-height': (maxHeight - menuHeight) + 'px',\n                'overflow-y': 'auto'\n            });\n            $txt.css({\n                'height': 'auto',\n                'overflow-y': 'visible',\n                'min-height': txtHeight + 'px'\n            });\n\n            // 滚动式，菜单阴影\n            $wrap.on('scroll', function () {\n                if ($txt.parent().scrollTop() > 10) {\n                    $menuContainer.addClass('wangEditor-menu-shadow');\n                } else {\n                    $menuContainer.removeClass('wangEditor-menu-shadow');\n                }\n            });\n\n            // 需在编辑器区域外面再包裹一层\n            $txt.wrap($wrap);\n        }\n    };\n\n    // 保存选区\n    Txt.fn.saveSelectionEvent = function () {\n        var $txt = this.$txt;\n        var editor = this.editor;\n        var timeoutId;\n        var dt = Date.now();\n\n        function save() {\n            editor.saveSelection();\n        }\n\n        // 同步保存选区\n        function saveSync() {\n            // 100ms之内，不重复保存\n            if (Date.now() - dt < 100) {\n                return;\n            }\n\n            dt = Date.now();\n            save();\n        }\n\n        // 异步保存选区\n        function saveAync() {\n            // 节流，防止高频率重复操作\n            if (timeoutId) {\n                clearTimeout(timeoutId);\n            }\n            timeoutId = setTimeout(save, 300);\n        }\n\n        // txt change 、focus、blur 时随时保存选区\n        $txt.on(txtChangeEventNames + ' focus blur', function (e) {\n            // 先同步保存选区，为了让接下来就马上要执行 editor.getRangeElem() 的程序\n            // 能够获取到正确的 rangeElem\n            saveSync();\n\n            // 再异步保存选区，为了确定更加准确的选区，为后续的操作做准备\n            saveAync();\n        });\n\n        // 鼠标拖拽选择时，可能会拖拽到编辑器区域外面再松手，此时 $txt 就监听不到 click事件了\n        $txt.on('mousedown', function () {\n            $txt.on('mouseleave.saveSelection', function (e) {\n                // 先同步后异步，如上述注释\n                saveSync();\n                saveAync();\n\n                // 顺道吧菜单状态也更新了\n                editor.updateMenuStyle();\n            });\n        }).on('mouseup', function () {\n            $txt.off('mouseleave.saveSelection');\n        });\n        \n    };\n\n    // 随时更新 value\n    Txt.fn.updateValueEvent = function () {\n        var $txt = this.$txt;\n        var editor = this.editor;\n        var timeoutId, oldValue;\n\n        // 触发 onchange 事件\n        function doOnchange() {\n            var val = $txt.html();\n            if (oldValue === val) {\n                // 无变化\n                return;\n            }\n\n            // 触发 onchange 事件\n            if (editor.onchange && typeof editor.onchange === 'function') {\n                editor.onchange.call(editor);\n            }\n\n            // 更新内容\n            editor.updateValue();\n\n            // 记录最新内容\n            oldValue = val;\n        }\n\n        // txt change 时随时更新内容\n        $txt.on(txtChangeEventNames, function (e) {\n            // 初始化\n            if (oldValue == null) {\n                oldValue = $txt.html();\n            }\n\n            // 监控内容变化（停止操作 100ms 之后立即执行）\n            if (timeoutId) {\n                clearTimeout(timeoutId);\n            }\n            timeoutId = setTimeout(doOnchange, 100);\n        });\n    };\n\n    // 随时更新 menustyle\n    Txt.fn.updateMenuStyleEvent = function () {\n        var $txt = this.$txt;\n        var editor = this.editor;\n\n        // txt change 时随时更新内容\n        $txt.on(txtChangeEventNames, function (e) {\n            editor.updateMenuStyle();\n        });\n    };\n\n    // 最后插入试图插入 <p><br><p>\n    Txt.fn.insertEmptyP = function () {\n        var $txt = this.$txt;\n        var $children = $txt.children();\n\n        if ($children.length === 0) {\n            $txt.append($('<p><br></p>'));\n            return;\n        }\n\n        if ($.trim($children.last().html()).toLowerCase() !== '<br>') {\n            $txt.append($('<p><br></p>'));\n        }\n    };\n\n    // 将编辑器暴露出来的文字和图片，都用 p 来包裹\n    Txt.fn.wrapImgAndText = function () {\n        var $txt = this.$txt;\n        var $imgs = $txt.children('img');\n        var txt = $txt[0];\n        var childNodes = txt.childNodes;\n        var childrenLength = childNodes.length;\n        var i, childNode, p;\n\n        // 处理图片\n        $imgs.length && $imgs.each(function () {\n            $(this).wrap('<p>');\n        });\n\n        // 处理文字\n        for (i = 0; i < childrenLength; i++) {\n            childNode = childNodes[i];\n            if (childNode.nodeType === 3 && childNode.textContent && $.trim(childNode.textContent)) {\n                $(childNode).wrap('<p>');\n            }\n        }\n    };\n\n    // 清空内容为空的<p>，以及重复包裹的<p>（在windows下的chrome粘贴文字之后，会出现上述情况）\n    Txt.fn.clearEmptyOrNestP = function () {\n        var $txt = this.$txt;\n        var $pList = $txt.find('p');\n\n        $pList.each(function () {\n            var $p = $(this);\n            var $children = $p.children();\n            var childrenLength = $children.length;\n            var $firstChild;\n            var content = $.trim($p.html());\n\n            // 内容为空的p\n            if (!content) {\n                $p.remove();\n                return;\n            }\n\n            // 嵌套的p\n            if (childrenLength === 1) {\n                $firstChild = $children.first();\n                if ($firstChild.get(0) && $firstChild.get(0).nodeName === 'P') {\n                    $p.html( $firstChild.html() );\n                }\n            }\n        });\n    };\n\n    // 获取 scrollTop\n    Txt.fn.scrollTop = function (val) {\n        var self = this;\n        var editor = self.editor;\n        var $txt = self.$txt;\n\n        if (editor.useMaxHeight) {\n            return $txt.parent().scrollTop(val);\n        } else {\n            return $txt.scrollTop(val);\n        }\n    };\n\n    // 鼠标hover时候，显示p、head的高度\n    Txt.fn.showHeightOnHover = function () {\n        var editor = this.editor;\n        var $editorContainer = editor.$editorContainer;\n        var menuContainer = editor.menuContainer;\n        var $txt = this.$txt;\n        var $tip = $('<i class=\"height-tip\"><i>');\n        var isTipInTxt = false;\n\n        function addAndShowTip($target) {\n            if (!isTipInTxt) {\n                $editorContainer.append($tip);\n                isTipInTxt = true;\n            }\n\n            var txtTop = $txt.position().top;\n            var txtHeight = $txt.outerHeight();\n\n            var height = $target.height();\n            var top = $target.position().top;\n            var marginTop = parseInt($target.css('margin-top'), 10);\n            var paddingTop = parseInt($target.css('padding-top'), 10);\n            var marginBottom = parseInt($target.css('margin-bottom'), 10);\n            var paddingBottom = parseInt($target.css('padding-bottom'), 10);\n\n            // 计算初步的结果\n            var resultHeight = height + paddingTop + marginTop + paddingBottom + marginBottom;\n            var resultTop = top + menuContainer.height();\n            \n            // var spaceValue;\n\n            // // 判断是否超出下边界\n            // spaceValue = (resultTop + resultHeight) - (txtTop + txtHeight);\n            // if (spaceValue > 0) {\n            //     resultHeight = resultHeight - spaceValue;\n            // }\n\n            // // 判断是否超出了下边界\n            // spaceValue = txtTop > resultTop;\n            // if (spaceValue) {\n            //     resultHeight = resultHeight - spaceValue;\n            //     top = top + spaceValue;\n            // }\n\n            // 按照最终结果渲染\n            $tip.css({\n                height: height + paddingTop + marginTop + paddingBottom + marginBottom,\n                top: top + menuContainer.height()\n            });\n        }\n        function removeTip() {\n            if (!isTipInTxt) {\n                return;\n            }\n            $tip.remove();\n            isTipInTxt = false;\n        }\n\n        $txt.on('mouseenter', 'ul,ol,blockquote,p,h1,h2,h3,h4,h5,table,pre', function (e) {\n            addAndShowTip($(e.currentTarget));\n        }).on('mouseleave', function () {\n            removeTip();\n        });\n    };\n\n});\n// 工具函数\n_e(function (E, $) {\n\n    // IE8 [].indexOf()\n    if(!Array.prototype.indexOf){\n        //IE低版本不支持 arr.indexOf \n        Array.prototype.indexOf = function(elem){\n            var i = 0,\n                length = this.length;\n            for(; i<length; i++){\n                if(this[i] === elem){\n                    return i;\n                }\n            }\n            return -1;\n        };\n        //IE低版本不支持 arr.lastIndexOf\n        Array.prototype.lastIndexOf = function(elem){\n            var length = this.length;\n            for(length = length - 1; length >= 0; length--){\n                if(this[length] === elem){\n                    return length;\n                }\n            }\n            return -1;\n        };\n    }\n\n    // IE8 Date.now()\n    if (!Date.now) {\n        Date.now = function () {\n            return new Date().valueOf(); \n        };\n    }\n\n    // console.log && console.warn && console.error\n    var console = window.console;\n    var emptyFn = function () {};\n    $.each(['info', 'log', 'warn', 'error'], function (key, value) {\n        if (console == null) {\n            E[value] = emptyFn;\n        } else {\n            E[value] = function (info) {\n                // 通过配置来控制打印输出\n                if (E.config && E.config.printLog) {\n                    console[value]('wangEditor提示: ' + info);\n                }\n            };\n        }\n    });\n\n    // 获取随机数\n    E.random = function () {\n        return Math.random().toString().slice(2);\n    };\n\n    // 浏览器是否支持 placeholder\n    E.placeholder = 'placeholder' in document.createElement('input');\n\n    // 兼容IE8的 input placeholder\n    E.placeholderForIE8 = function ($container) {\n        if (E.placeholder) {\n            return;\n        }\n        $container.find('input[placeholder]').each(function () {\n            var $input = $(this);\n            var placeholder = $input.attr('placeholder');\n\n            if ($input.val() === '') {\n                $input.css('color', '#666');\n                $input.val(placeholder);\n\n                $input.on('focus.placeholder click.placeholder', function () {\n                    $input.val('');\n                    $input.css('color', '#333');\n                    $input.off('focus.placeholder click.placeholder');\n                });\n            }\n        });\n    };\n});\n// 语言包\n_e(function (E, $) {\n    E.langs = {};\n    \n    // 中文\n    E.langs['zh-cn'] = {\n        bold: '粗体',\n        underline: '下划线',\n        italic: '斜体',\n        forecolor: '文字颜色',\n        bgcolor: '背景色',\n        strikethrough: '删除线',\n        eraser: '清空格式',\n        source: '源码',\n        quote: '引用',\n        fontfamily: '字体',\n        fontsize: '字号',\n        head: '标题',\n        orderlist: '有序列表',\n        unorderlist: '无序列表',\n        alignleft: '左对齐',\n        aligncenter: '居中',\n        alignright: '右对齐',\n        link: '链接',\n        text: '文本',\n        submit: '提交',\n        cancel: '取消',\n        unlink: '取消链接',\n        table: '表格',\n        emotion: '表情',\n        img: '图片',\n        video: '视频',\n        'width': '宽',\n        'height': '高',\n        location: '位置',\n        loading: '加载中',\n        searchlocation: '搜索位置',\n        dynamicMap: '动态地图',\n        clearLocation: '清除位置',\n        langDynamicOneLocation: '动态地图只能显示一个位置',\n        insertcode: '插入代码',\n        undo: '撤销',\n        redo: '重复',\n        fullscreen: '全屏',\n        openLink: '打开链接'\n    };\n\n    // 英文\n    E.langs.en = {\n        bold: 'Bold',\n        underline: 'Underline',\n        italic: 'Italic',\n        forecolor: 'Color',\n        bgcolor: 'Backcolor',\n        strikethrough: 'Strikethrough',\n        eraser: 'Eraser',\n        source: 'Codeview',\n        quote: 'Quote',\n        fontfamily: 'Font family',\n        fontsize: 'Font size',\n        head: 'Head',\n        orderlist: 'Ordered list',\n        unorderlist: 'Unordered list',\n        alignleft: 'Align left',\n        aligncenter: 'Align center',\n        alignright: 'Align right',\n        link: 'Insert link',\n        text: 'Text',\n        submit: 'Submit',\n        cancel: 'Cancel',\n        unlink: 'Unlink',\n        table: 'Table',\n        emotion: 'Emotions',\n        img: 'Image',\n        video: 'Video',\n        'width': 'width',\n        'height': 'height',\n        location: 'Location',\n        loading: 'Loading',\n        searchlocation: 'search',\n        dynamicMap: 'Dynamic',\n        clearLocation: 'Clear',\n        langDynamicOneLocation: 'Only one location in dynamic map',\n        insertcode: 'Insert Code',\n        undo: 'Undo',\n        redo: 'Redo',\n        fullscreen: 'Full screnn',\n        openLink: 'open link'\n    };\n});\n// 全局配置\n_e(function (E, $) {\n\n    E.config = {};\n\n    // 全屏时的 z-index\n    E.config.zindex = 10000;\n\n    // 是否打印log\n    E.config.printLog = true;\n\n    // 菜单吸顶：false - 不吸顶；number - 吸顶，值为top值\n    E.config.menuFixed = 0;\n\n    // 编辑源码时，过滤 javascript\n    E.config.jsFilter = true;\n\n    // 编辑器允许的标签\n    E.config.legalTags = 'p,h1,h2,h3,h4,h5,h6,blockquote,table,ul,ol,pre';\n\n    // 语言包\n    E.config.lang = E.langs['zh-cn'];\n\n    // 菜单配置\n    E.config.menus = [\n        'source',\n        '|',\n        'bold',\n        'underline',\n        'italic',\n        'strikethrough',\n        'eraser',\n        'forecolor',\n        'bgcolor',\n        '|',\n        'quote',\n        'fontfamily',\n        'fontsize',\n        'head',\n        'unorderlist',\n        'orderlist',\n        'alignleft',\n        'aligncenter',\n        'alignright',\n        '|',\n        'link',\n        'unlink',\n        'table',\n        'emotion',\n        '|',\n        'img',\n        'video',\n        'location',\n        'insertcode',\n        '|',\n        'undo',\n        'redo',\n        'fullscreen'\n    ];\n\n    // 颜色配置\n    E.config.colors = {\n        // 'value': 'title'\n        '#880000': '暗红色',\n        '#800080': '紫色',\n        '#ff0000': '红色',\n        '#ff00ff': '鲜粉色',\n        '#000080': '深蓝色',\n        '#0000ff': '蓝色',\n        '#00ffff': '湖蓝色',\n        '#008080': '蓝绿色',\n        '#008000': '绿色',\n        '#808000': '橄榄色',\n        '#00ff00': '浅绿色',\n        '#ffcc00': '橙黄色',\n        '#808080': '灰色',\n        '#c0c0c0': '银色',\n        '#000000': '黑色',\n        '#ffffff': '白色'\n    };\n\n    // 字体\n    E.config.familys = [\n        '宋体', '黑体', '楷体', '微软雅黑',\n        'Arial', 'Verdana', 'Georgia',\n        'Times New Roman', 'Microsoft JhengHei',\n        'Trebuchet MS', 'Courier New', 'Impact', 'Comic Sans MS', 'Consolas'\n    ];\n\n    // 字号\n    E.config.fontsizes = {\n        // 格式：'value': 'title'\n        1: '12px',\n        2: '13px',\n        3: '16px',\n        4: '18px',\n        5: '24px',\n        6: '32px',\n        7: '48px'\n    };\n\n    // 表情包\n    E.config.emotionsShow = 'icon'; // 显示项，默认为'icon'，也可以配置成'value'\n    E.config.emotions = {\n        // 'default': {\n        //     title: '默认',\n        //     data: './emotions.data'\n        // },\n        'weibo': {\n            title: '微博表情',\n            data: [\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/7a/shenshou_thumb.gif',\n                    value: '[草泥马]'    \n                },\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/60/horse2_thumb.gif',\n                    value: '[神马]'    \n                },\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/bc/fuyun_thumb.gif',\n                    value: '[浮云]'    \n                },\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/c9/geili_thumb.gif',\n                    value: '[给力]'    \n                },\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/f2/wg_thumb.gif',\n                    value: '[围观]'    \n                },\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/70/vw_thumb.gif',\n                    value: '[威武]'\n                },\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/6e/panda_thumb.gif',\n                    value: '[熊猫]'\n                },\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/81/rabbit_thumb.gif',\n                    value: '[兔子]'\n                },\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/bc/otm_thumb.gif',\n                    value: '[奥特曼]'\n                },\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/15/j_thumb.gif',\n                    value: '[囧]'\n                },\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/89/hufen_thumb.gif',\n                    value: '[互粉]'\n                },\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/c4/liwu_thumb.gif',\n                    value: '[礼物]'\n                },\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/ac/smilea_thumb.gif',\n                    value: '[呵呵]'\n                },\n                {\n                    icon: 'http://img.t.sinajs.cn/t35/style/images/common/face/ext/normal/0b/tootha_thumb.gif',\n                    value: '[哈哈]'\n                }\n            ]\n        }\n    };\n\n    // 百度地图的key\n    E.config.mapAk = 'TVhjYjq1ICT2qqL5LdS8mwas';\n\n    // 上传图片的配置\n    // server地址\n    E.config.uploadImgUrl = '';\n    // 超时时间\n    E.config.uploadTimeout = 20 * 1000;\n    // 用于存储上传回调事件\n    E.config.uploadImgFns = {};\n    // 自定义上传图片的filename\n    // E.config.uploadImgFileName = 'customFileName';\n\n    // 自定义上传，设置为 true 之后，显示上传图标\n    E.config.customUpload = false;\n    // 自定义上传的init事件\n    // E.config.customUploadInit = function () {....};\n\n    // 自定义上传时传递的参数（如 token）\n    E.config.uploadParams = {\n        /* token: 'abcdef12345' */\n    };\n\n    // 自定义上传是的header参数\n    E.config.uploadHeaders = {\n         /* 'Accept' : 'text/x-json' */\n    };\n\n    // 隐藏网络图片，默认为 false\n    E.config.hideLinkImg = false;\n\n    // 是否过滤粘贴内容\n    E.config.pasteFilter = true;\n\n    // 是否粘贴纯文本，当 editor.config.pasteFilter === false 时候，此配置将失效\n    E.config.pasteText = false;\n\n    // 插入代码时，默认的语言\n    E.config.codeDefaultLang = 'javascript';\n\n});\n// 全局UI\n_e(function (E, $) {\n\n     E.UI = {};\n\n     // 为菜单自定义配置的UI\n     E.UI.menus = {\n        // 这个 default 不加引号，在 IE8 会报错\n        'default': {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-command\"></i></a>',\n            selected: '.selected'\n        },\n        bold: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-bold\"></i></a>',\n            selected: '.selected'\n        },\n        underline: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-underline\"></i></a>',\n            selected: '.selected'\n        },\n        italic: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-italic\"></i></a>',\n            selected: '.selected'\n        },\n        forecolor: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-pencil\"></i></a>',\n            selected: '.selected'\n        },\n        bgcolor: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-brush\"></i></a>',\n            selected: '.selected'\n        },\n        strikethrough: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-strikethrough\"></i></a>',\n            selected: '.selected'\n        },\n        eraser: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-eraser\"></i></a>',\n            selected: '.selected'\n        },\n        quote: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-quotes-left\"></i></a>',\n            selected: '.selected'\n        },\n        source: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-code\"></i></a>',\n            selected: '.selected'\n        },\n        fontfamily: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-font2\"></i></a>',\n            selected: '.selected'\n        },\n        fontsize: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-text-height\"></i></a>',\n            selected: '.selected'\n        },\n        head: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-header\"></i></a>',\n            selected: '.selected'\n        },\n        orderlist: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-list-numbered\"></i></a>',\n            selected: '.selected'\n        },\n        unorderlist: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-list-bullet\"></i></a>',\n            selected: '.selected'\n        },\n        alignleft: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-align-left\"></i></a>',\n            selected: '.selected'\n        },\n        aligncenter: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-align-center\"></i></a>',\n            selected: '.selected'\n        },\n        alignright: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-align-right\"></i></a>',\n            selected: '.selected'\n        },\n        link: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-link\"></i></a>',\n            selected: '.selected'\n        },\n        unlink: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-unlink\"></i></a>',\n            selected: '.selected'\n        },\n        table: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-table\"></i></a>',\n            selected: '.selected'\n        },\n        emotion: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-happy\"></i></a>',\n            selected: '.selected'\n        },\n        img: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-picture\"></i></a>',\n            selected: '.selected'\n        },\n        video: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-play\"></i></a>',\n            selected: '.selected'\n        },\n        location: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-location\"></i></a>',\n            selected: '.selected'\n        },\n        insertcode: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-terminal\"></i></a>',\n            selected: '.selected'\n        },\n        undo: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-ccw\"></i></a>',\n            selected: '.selected'\n        },\n        redo: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-cw\"></i></a>',\n            selected: '.selected'\n        },\n        fullscreen: {\n            normal: '<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-enlarge2\"></i></a>',\n            selected: '<a href=\"#\" tabindex=\"-1\" class=\"selected\"><i class=\"wangeditor-menu-img-shrink2\"></i></a>'\n        }\n     };\n     \n});\n// 对象配置\n_e(function (E, $) {\n\n    E.fn.initDefaultConfig = function () {\n        var editor = this;\n        editor.config = $.extend({}, E.config);\n        editor.UI = $.extend({}, E.UI);\n    };\n\n});\n// 增加 container\n_e(function (E, $) {\n\n    E.fn.addEditorContainer = function () {\n        this.$editorContainer = $('<div class=\"wangEditor-container\"></div>');\n    };\n\n});\n// 增加编辑区域对象\n_e(function (E, $) {\n\n    E.fn.addTxt = function () {\n        var editor = this;\n        var txt = new E.Txt(editor);\n\n        editor.txt = txt;\n    };\n\n});\n// 增加menuContainer对象\n_e(function (E, $) {\n\n    E.fn.addMenuContainer = function () {\n        var editor = this;\n        editor.menuContainer = new E.MenuContainer(editor);\n    };\n\n});\n// 增加menus\n_e(function (E, $) {\n\n    // 存储创建菜单的函数\n    E.createMenuFns = [];\n    E.createMenu = function (fn) {\n        E.createMenuFns.push(fn);\n    };\n\n    // 创建所有菜单\n    E.fn.addMenus = function () {\n        var editor = this;\n        var menuIds = editor.config.menus;\n\n        // 检验 menuId 是否在配置中存在\n        function check(menuId) {\n            if (menuIds.indexOf(menuId) >= 0) {\n                return true;\n            }\n            return false;\n        }\n\n        // 遍历所有的菜单创建函数，并执行\n        $.each(E.createMenuFns, function (k, createMenuFn) {\n            createMenuFn.call(editor, check);\n        });\n    };\n\n});\n// bold菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'bold';\n        if (!check(menuId)) {\n            return;\n        }\n\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.bold,\n            commandName: 'Bold'\n        });\n\n        // 定义选中状态下的click事件\n        menu.clickEventSelected = function (e) {\n            var isRangeEmpty = editor.isRangeEmpty();\n            if (!isRangeEmpty) {\n                // 如果选区有内容，则执行基础命令\n                editor.command(e, 'Bold');\n            } else {\n                // 如果选区没有内容\n                editor.commandForElem('b,strong,h1,h2,h3,h4,h5', e, 'Bold');\n            }\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// underline菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'underline';\n        if (!check(menuId)) {\n            return;\n        }\n\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.underline,\n            commandName: 'Underline'\n        });\n\n        // 定义选中状态下的click事件\n        menu.clickEventSelected = function (e) {\n            var isRangeEmpty = editor.isRangeEmpty();\n            if (!isRangeEmpty) {\n                // 如果选区有内容，则执行基础命令\n                editor.command(e, 'Underline');\n            } else {\n                // 如果选区没有内容\n                editor.commandForElem('u,a', e, 'Underline');\n            }\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// italic 菜单\n_e(function (E, $) {\n    \n    E.createMenu(function (check) {\n        var menuId = 'italic';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.italic,\n            commandName: 'Italic'\n        });\n\n        // 定义选中状态下的click事件\n        menu.clickEventSelected = function (e) {\n            var isRangeEmpty = editor.isRangeEmpty();\n            if (!isRangeEmpty) {\n                // 如果选区有内容，则执行基础命令\n                editor.command(e, 'Italic');\n            } else {\n                // 如果选区没有内容\n                editor.commandForElem('i', e, 'Italic');\n            }\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// forecolor 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'forecolor';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n        var configColors = editor.config.colors;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.forecolor\n        });\n\n        // 创建 dropPanel\n        var $content = $('<div></div>');\n        $.each(configColors, function (k, v) {\n            $content.append(\n                [\n                    '<a href=\"#\" class=\"color-item\"',\n                    '    title=\"' + v + '\" commandValue=\"' + k + '\" ',\n                    '    style=\"color: ' + k + '\" ',\n                    '><i class=\"wangeditor-menu-img-pencil\"></i></a>'\n                ].join('')\n            );\n        });\n        $content.on('click', 'a[commandValue]', function (e) {\n            // 执行命令\n            var $elem = $(this);\n            var commandValue = $elem.attr('commandValue');\n\n            if (menu.selected && editor.isRangeEmpty()) {\n                // 当前处于选中状态，并且选中内容为空\n                editor.commandForElem('font[color]', e, 'forecolor', commandValue);\n            } else {\n                // 当前未处于选中状态，或者有选中内容。则执行默认命令\n                editor.command(e, 'forecolor', commandValue);\n            }\n        });\n        menu.dropPanel = new E.DropPanel(editor, menu, {\n            $content: $content,\n            width: 125\n        });\n\n        // 定义 update selected 事件\n        menu.updateSelectedEvent = function () {\n            var rangeElem = editor.getRangeElem();\n            rangeElem = editor.getSelfOrParentByName(rangeElem, 'font[color]');\n            if (rangeElem) {\n                return true;\n            }\n            return false;\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// bgcolor 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'bgcolor';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n        var configColors = editor.config.colors;\n\n        // 检查元素是否有 background-color: 内联样式\n        function checkElemFn(elem) {\n            var cssText;\n            if (elem && elem.style && elem.style.cssText != null) {\n                cssText = elem.style.cssText;\n                if (cssText && cssText.indexOf('background-color:') >= 0) {\n                    return true;\n                }\n            }\n            return false;\n        }\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.bgcolor\n        });\n\n        // 创建 dropPanel\n        var $content = $('<div></div>');\n        $.each(configColors, function (k, v) {\n            $content.append(\n                [\n                    '<a href=\"#\" class=\"color-item\"',\n                    '    title=\"' + v + '\" commandValue=\"' + k + '\" ',\n                    '    style=\"color: ' + k + '\" ',\n                    '><i class=\"wangeditor-menu-img-brush\"></i></a>'\n                ].join('')\n            );\n        });\n        $content.on('click', 'a[commandValue]', function (e) {\n            // 执行命令\n\n            var $elem = $(this);\n            var commandValue = $elem.attr('commandValue');\n\n            if (menu.selected && editor.isRangeEmpty()) {\n                // 当前处于选中状态，并且选中内容为空。使用 commandForElem 执行命令\n                editor.commandForElem({\n                    selector: 'span,font',\n                    check: checkElemFn\n                }, e, 'BackColor', commandValue);\n            } else {\n                // 当前未处于选中状态，或者有选中内容。则执行默认命令\n                editor.command(e, 'BackColor', commandValue);\n            }\n        });\n        menu.dropPanel = new E.DropPanel(editor, menu, {\n            $content: $content,\n            width: 125\n        });\n\n        // 定义 update selected 事件\n        menu.updateSelectedEvent = function () {\n            var rangeElem = editor.getRangeElem();\n            rangeElem = editor.getSelfOrParentByName(rangeElem, 'span,font', checkElemFn);\n            \n            if (rangeElem) {\n                return true;\n            }\n            return false;\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// strikethrough 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'strikethrough';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.strikethrough,\n            commandName: 'StrikeThrough'\n        });\n\n        // 定义选中状态下的click事件\n        menu.clickEventSelected = function (e) {\n            var isRangeEmpty = editor.isRangeEmpty();\n            if (!isRangeEmpty) {\n                // 如果选区有内容，则执行基础命令\n                editor.command(e, 'StrikeThrough');\n            } else {\n                // 如果选区没有内容\n                editor.commandForElem('strike', e, 'StrikeThrough');\n            }\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// eraser 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'eraser';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.eraser,\n            commandName: 'RemoveFormat'\n        });\n\n        // 定义点击事件\n        menu.clickEvent = function (e) {\n            var isRangeEmpty = editor.isRangeEmpty();\n\n            if (!isRangeEmpty) {\n                // 选区不是空的，则执行默认命令\n                editor.command(e, 'RemoveFormat');\n                return;\n            }\n\n            var $clearElem;\n\n            // 自定义的命令函数\n            function commandFn() {\n                var editor = this;\n                var rangeElem;\n                var pElem, $pElem;\n                var quoteElem, $quoteElem;\n                var listElem, $listElem;\n\n                // 获取选区 elem\n                rangeElem = editor.getRangeElem();\n                // 第一步，获取 quote 父元素\n                quoteElem = editor.getSelfOrParentByName(rangeElem, 'blockquote');\n                if (quoteElem) {\n                    $quoteElem = $(quoteElem);\n                    $clearElem = $('<p>' + $quoteElem.text() + '</p>');\n                    $quoteElem.after($clearElem).remove();\n                }\n                // 第二步，获取 p h 父元素\n                pElem = editor.getSelfOrParentByName(rangeElem, 'p,h1,h2,h3,h4,h5');\n                if (pElem) {\n                    $pElem = $(pElem);\n                    $clearElem = $('<p>' + $pElem.text() + '</p>');\n                    $pElem.after($clearElem).remove();\n                }\n                // 第三步，获取list\n                listElem = editor.getSelfOrParentByName(rangeElem, 'ul,ol');\n                if (listElem) {\n                    $listElem = $(listElem);\n                    $clearElem = $('<p>' + $listElem.text() + '</p>');\n                    $listElem.after($clearElem).remove();\n                }\n            }\n\n            // 自定义 callback 事件\n            function callback() {\n                // callback中，设置range为clearElem\n                var editor = this;\n                if ($clearElem) {\n                    editor.restoreSelectionByElem($clearElem.get(0));\n                }\n            }\n\n            // 执行自定义命令\n            editor.customCommand(e, commandFn, callback);\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// source 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'source';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n        var txtHtml;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.source\n        });\n\n        menu.isShowCode = false;\n\n        // 更新内容\n        function updateValue() {\n            var $code = menu.$codeTextarea;\n            var $txt = editor.txt.$txt;\n            var value = $.trim($code.val()); // 取值\n\n            if (!value) {\n                value = '<p><br></p>';\n            }\n            \n            // 过滤js代码\n            if (editor.config.jsFilter) {\n                \n                value = value.replace(/<script[\\s\\S]*?<\\/script>/ig, '');\n            }\n            // 赋值\n            try {\n                $txt.html(value);\n            } catch (ex) {\n                // 更新 html 源码出错，一般都是取消了 js 过滤之后，js报错导致的\n            }\n        }\n\n        // 定义click事件\n        menu.clickEvent = function (e) {\n            var self = this;\n            var editor = self.editor;\n            var $txt = editor.txt.$txt;\n            var txtOuterHeight = $txt.outerHeight();\n            var txtHeight = $txt.height();\n\n            if (!self.$codeTextarea) {\n                self.$codeTextarea = $('<textarea class=\"code-textarea\"></textarea>');\n            }\n            var $code = self.$codeTextarea;\n            $code.css({\n                height: txtHeight,\n                'margin-top': txtOuterHeight - txtHeight\n            });\n\n            // 赋值\n            $code.val($txt.html());\n\n            // 监控变化\n            $code.on('change', function (e) {\n                updateValue();\n            });\n\n            // 渲染\n            $txt.after($code).hide();\n            $code.show();\n\n            // 更新状态\n            menu.isShowCode = true;\n\n            // 执行 updateSelected 事件\n            this.updateSelected();\n\n            // 禁用其他菜单\n            editor.disableMenusExcept('source');\n\n            // 记录当前html值\n            txtHtml = $txt.html();\n        };\n\n        // 定义选中状态下的click事件\n        menu.clickEventSelected = function (e) {\n            var self = this;\n            var editor = self.editor;\n            var $txt = editor.txt.$txt;\n            var $code = self.$codeTextarea;\n            var value;\n\n            if (!$code) {\n                return;\n            }\n\n            // 更新内容\n            updateValue();\n\n            // 渲染\n            $code.after($txt).hide();\n            $txt.show();\n\n            // 更新状态\n            menu.isShowCode = false;\n\n            // 执行 updateSelected 事件\n            this.updateSelected();\n\n            // 启用其他菜单\n            editor.enableMenusExcept('source');\n\n            // 判断是否执行 onchange 事件\n            if ($txt.html() !== txtHtml) {\n                if (editor.onchange && typeof editor.onchange === 'function') {\n                    editor.onchange.call(editor);\n                }\n            }\n        };\n\n        // 定义切换选中状态事件\n        menu.updateSelectedEvent = function () {\n            return this.isShowCode;\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// quote 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'quote';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.quote,\n            commandName: 'formatBlock',\n            commandValue: 'blockquote'\n        });\n\n        // 定义click事件\n        menu.clickEvent = function (e) {\n            var rangeElem = editor.getRangeElem();\n            var $rangeElem;\n            if (!rangeElem) {\n                e.preventDefault();\n                return;\n            }\n            var currentQuote = editor.getSelfOrParentByName(rangeElem, 'blockquote');\n            var $quote;\n\n            if (currentQuote) {\n                // 说明当前在quote之内，不做任何处理\n                e.preventDefault();\n                return;\n            }\n\n            rangeElem = editor.getLegalTags(rangeElem);\n            $rangeElem = $(rangeElem);\n\n            // 无文字，则不允许执行引用\n            if (!$rangeElem.text()) {\n                return;\n            }\n\n\n            if (!rangeElem) {\n                // 执行默认命令\n                // IE8 下执行此处（不过，经测试代码无效，也不报错）\n                editor.command(e, 'formatBlock', 'blockquote');\n                return;\n            }\n\n            // 自定义command事件\n            function commandFn() {\n                $quote = $('<p>' + $rangeElem.text() + '</p>');\n                $rangeElem.after($quote).remove();\n                $quote.wrap('<blockquote>');\n            }\n\n            // 自定义 callback 事件\n            function callback() {\n                // callback中，设置range为quote\n                var editor = this;\n                if ($quote) {\n                    editor.restoreSelectionByElem($quote.get(0));\n                }\n            }\n\n            // 执行自定义命令\n            editor.customCommand(e, commandFn, callback);\n        };\n\n        // 定义选中状态下的click事件\n        menu.clickEventSelected = function (e) {\n            var rangeElem;\n            var quoteElem;\n            var $lastChild;\n\n            // 获取当前选区的elem，并试图往上找 quote 元素\n            rangeElem = editor.getRangeElem();\n            quoteElem = editor.getSelfOrParentByName(rangeElem, 'blockquote');\n            if (!quoteElem) {\n                // 没找到，则返回\n                e.preventDefault();\n                return;\n            }\n\n            // 自定义的command事件\n            function commandFn() {\n                var $quoteElem;\n                var $children;\n\n                $quoteElem = $(quoteElem);\n                $children = $quoteElem.children();\n                if ($children.length) {\n                    $children.each(function (k) {\n                        var $item = $(this);\n                        if ($item.get(0).nodeName === 'P') {\n                            $quoteElem.after($item);\n                        } else {\n                            $quoteElem.after('<p>' + $item.text() + '</p>');\n                        }\n                        $lastChild = $item;  // 记录最后一个子元素，用于callback中的range定位\n                    });\n                    $quoteElem.remove();\n                    return;\n                }\n            }\n\n            // 自定义的callback函数\n            function callback() {\n                // callback中，设置range为lastChild\n                var editor = this;\n                if ($lastChild) {\n                    editor.restoreSelectionByElem($lastChild.get(0));\n                }\n            }\n\n            // 执行自定义命令\n            editor.customCommand(e, commandFn, callback);\n        };\n\n        // 定义更新选中状态的事件\n        menu.updateSelectedEvent = function () {\n            var self = this; //菜单对象\n            var editor = self.editor;\n            var rangeElem;\n\n            rangeElem = editor.getRangeElem();\n            rangeElem = editor.getSelfOrParentByName(rangeElem, 'blockquote');\n\n            if (rangeElem) {\n                return true;\n            }\n\n            return false;\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n\n        // --------------- 两次点击 enter 跳出引用 ---------------\n        editor.ready(function () {\n            var editor = this;\n            var $txt = editor.txt.$txt;\n            var isPrevEnter = false;  // 是不是刚刚在quote中按了 enter 键\n            $txt.on('keydown', function (e) {\n                if (e.keyCode !== 13) {\n                    // 不是 enter 键\n                    isPrevEnter = false;\n                    return;\n                }\n\n                var rangeElem = editor.getRangeElem();\n                rangeElem = editor.getSelfOrParentByName(rangeElem, 'blockquote');\n                if (!rangeElem) {\n                    // 选区不是 quote\n                    isPrevEnter = false;\n                    return;\n                }\n\n                if (!isPrevEnter) {\n                    // 最近没有在qote中按enter键\n                    isPrevEnter = true;\n                    return;\n                }\n\n                var currentRangeElem = editor.getRangeElem();\n                var $currentRangeElem = $(currentRangeElem);\n                if ($currentRangeElem.length) {\n                    $currentRangeElem.parent().after($currentRangeElem);\n                }\n\n                // 设置选区\n                editor.restoreSelectionByElem(currentRangeElem, 'start');\n\n                isPrevEnter = false;\n                // 阻止默认行文\n                e.preventDefault();\n\n            });\n        }); // editor.ready(\n\n        // --------------- 处理quote中无内容时不能删除的问题 ---------------\n        editor.ready(function () {\n            var editor = this;\n            var $txt = editor.txt.$txt;\n            var $rangeElem;\n\n            function commandFn() {\n                $rangeElem && $rangeElem.remove();\n            }\n            function callback() {\n                if (!$rangeElem) {\n                    return;\n                }\n                var $prev = $rangeElem.prev();\n                if ($prev.length) {\n                    // 有 prev 则定位到 prev 最后\n                    editor.restoreSelectionByElem($prev.get(0));\n                } else {\n                    // 无 prev 则初始化选区\n                    editor.initSelection();\n                }\n            }\n\n            $txt.on('keydown', function (e) {\n                if (e.keyCode !== 8) {\n                    // 不是 backspace 键\n                    return;\n                }\n\n                var rangeElem = editor.getRangeElem();\n                rangeElem = editor.getSelfOrParentByName(rangeElem, 'blockquote');\n                if (!rangeElem) {\n                    // 选区不是 quote\n                    return;\n                }\n                $rangeElem = $(rangeElem);\n\n                var text = $rangeElem.text();\n                if (text) {\n                    // quote 中还有内容\n                    return;\n                }\n                editor.customCommand(e, commandFn, callback);\n\n            }); // $txt.on\n        }); // editor.ready(\n    });\n\n});\n// 字体 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'fontfamily';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n        var configFamilys = editor.config.familys;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.fontfamily,\n            commandName: 'fontName'\n        });\n\n        // 初始化数据\n        var data  = {};\n        /*\n            data 需要的结构\n            {\n                'commandValue': 'title'\n                ...\n            }\n        */\n        $.each(configFamilys, function (k, v) {\n            // configFamilys 是数组，data 是对象\n            data[v] = v;\n        });\n\n        // 创建droplist\n        var tpl = '<span style=\"font-family:{#commandValue};\">{#title}</span>';\n        menu.dropList = new E.DropList(editor, menu, {\n            data: data,\n            tpl: tpl,\n            selectorForELemCommand: 'font[face]'  // 为了执行 editor.commandForElem 而传入的elem查询方式\n        });\n\n        // 定义 update selected 事件\n        menu.updateSelectedEvent = function () {\n            var rangeElem = editor.getRangeElem();\n            rangeElem = editor.getSelfOrParentByName(rangeElem, 'font[face]');\n            if (rangeElem) {\n                return true;\n            }\n            return false;\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n});\n// 字号 菜单\n_e(function (E, $) {\n    E.createMenu(function (check) {\n        var menuId = 'fontsize';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n        var configSize = editor.config.fontsizes;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.fontsize,\n            commandName: 'fontSize'\n        });\n\n        // 初始化数据\n        var data  = configSize;\n        /*\n            data 需要的结构\n            {\n                'commandValue': 'title'\n                ...\n            }\n        */\n\n        // 创建droplist\n        var tpl = '<span style=\"font-size:{#title};\">{#title}</span>';\n        menu.dropList = new E.DropList(editor, menu, {\n            data: data,\n            tpl: tpl,\n            selectorForELemCommand: 'font[size]'  // 为了执行 editor.commandForElem 而传入的elem查询方式\n        });\n\n        // 定义 update selected 事件\n        menu.updateSelectedEvent = function () {\n            var rangeElem = editor.getRangeElem();\n            rangeElem = editor.getSelfOrParentByName(rangeElem, 'font[size]');\n            if (rangeElem) {\n                return true;\n            }\n            return false;\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n});\n// head 菜单\n_e(function (E, $) {\n    E.createMenu(function (check) {\n        var menuId = 'head';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.head,\n            commandName: 'formatBlock'\n        });\n\n        // 初始化数据\n        var data  = {\n            '<h1>': '标题1',\n            '<h2>': '标题2',\n            '<h3>': '标题3',\n            '<h4>': '标题4',\n            '<h5>': '标题5'\n        };\n        /*\n            data 需要的结构\n            {\n                'commandValue': 'title'\n                ...\n            }\n        */\n\n        var isOrderedList;\n        function beforeEvent(e) {\n            if (editor.queryCommandState('InsertOrderedList')) {\n                isOrderedList = true;\n\n                // 先取消有序列表\n                editor.command(e, 'InsertOrderedList');\n            } else {\n                isOrderedList = false;\n            }\n        }\n\n        function afterEvent(e) {\n            if (isOrderedList) {\n                // 再设置有序列表\n                editor.command(e, 'InsertOrderedList');\n            }\n        }\n\n        // 创建droplist\n        var tpl = '{#commandValue}{#title}';\n        menu.dropList = new E.DropList(editor, menu, {\n            data: data,\n            tpl: tpl,\n            // 对 ol 直接设置 head，会出现每个 li 的 index 都变成 1 的问题，因此要先取消 ol，然后设置 head，最后再增加上 ol\n            beforeEvent: beforeEvent,\n            afterEvent: afterEvent\n        });\n\n        // 定义 update selected 事件\n        menu.updateSelectedEvent = function () {\n            var rangeElem = editor.getRangeElem();\n            rangeElem = editor.getSelfOrParentByName(rangeElem, 'h1,h2,h3,h4,h5');\n            if (rangeElem) {\n                return true;\n            }\n            return false;\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n});\n// unorderlist 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'unorderlist';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.unorderlist,\n            commandName: 'InsertUnorderedList'\n        });\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// orderlist 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'orderlist';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.orderlist,\n            commandName: 'InsertOrderedList'\n        });\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// alignleft 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'alignleft';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.alignleft,\n            commandName: 'JustifyLeft'\n        });\n\n        // 定义 update selected 事件\n        menu.updateSelectedEvent = function () {\n            var rangeElem = editor.getRangeElem();\n            rangeElem = editor.getSelfOrParentByName(rangeElem, 'p,h1,h2,h3,h4,h5,li', function (elem) {\n                var cssText;\n                if (elem && elem.style && elem.style.cssText != null) {\n                    cssText = elem.style.cssText;\n                    if (cssText && /text-align:\\s*left;/.test(cssText)) {\n                        return true;\n                    }\n                }\n                if ($(elem).attr('align') === 'left') {\n                    // ff 中，设置align-left之后，会是 <p align=\"left\">xxx</p>\n                    return true;\n                }\n                return false;\n            });\n            if (rangeElem) {\n                return true;\n            }\n            return false;\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// aligncenter 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'aligncenter';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.aligncenter,\n            commandName: 'JustifyCenter'\n        });\n\n        // 定义 update selected 事件\n        menu.updateSelectedEvent = function () {\n            var rangeElem = editor.getRangeElem();\n            rangeElem = editor.getSelfOrParentByName(rangeElem, 'p,h1,h2,h3,h4,h5,li', function (elem) {\n                var cssText;\n                if (elem && elem.style && elem.style.cssText != null) {\n                    cssText = elem.style.cssText;\n                    if (cssText && /text-align:\\s*center;/.test(cssText)) {\n                        return true;\n                    }\n                }\n                if ($(elem).attr('align') === 'center') {\n                    // ff 中，设置align-center之后，会是 <p align=\"center\">xxx</p>\n                    return true;\n                }\n                return false;\n            });\n            if (rangeElem) {\n                return true;\n            }\n            return false;\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// alignright 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'alignright';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.alignright,\n            commandName: 'JustifyRight'\n        });\n\n        // 定义 update selected 事件\n        menu.updateSelectedEvent = function () {\n            var rangeElem = editor.getRangeElem();\n            rangeElem = editor.getSelfOrParentByName(rangeElem, 'p,h1,h2,h3,h4,h5,li', function (elem) {\n                var cssText;\n                if (elem && elem.style && elem.style.cssText != null) {\n                    cssText = elem.style.cssText;\n                    if (cssText && /text-align:\\s*right;/.test(cssText)) {\n                        return true;\n                    }\n                }\n                if ($(elem).attr('align') === 'right') {\n                    // ff 中，设置align-right之后，会是 <p align=\"right\">xxx</p>\n                    return true;\n                }\n                return false;\n            });\n            if (rangeElem) {\n                return true;\n            }\n            return false;\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// link 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'link';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.link\n        });\n\n        // 创建 dropPanel\n        var $content = $('<div></div>');\n        var $div1 = $('<div style=\"margin:20px 10px;\" class=\"clearfix\"></div>');\n        var $div2 = $div1.clone();\n        var $div3 = $div1.clone().css('margin', '0 10px');\n        var $textInput = $('<input type=\"text\" class=\"block\" placeholder=\"' + lang.text + '\"/>');\n        var $urlInput = $('<input type=\"text\" class=\"block\" placeholder=\"' + lang.link + '\"/>');\n        var $btnSubmit = $('<button class=\"right\">' + lang.submit + '</button>');\n        var $btnCancel = $('<button class=\"right gray\">' + lang.cancel + '</button>');\n\n        $div1.append($textInput);\n        $div2.append($urlInput);\n        $div3.append($btnSubmit).append($btnCancel);\n        $content.append($div1).append($div2).append($div3);\n        \n        menu.dropPanel = new E.DropPanel(editor, menu, {\n            $content: $content,\n            width: 300\n        });\n\n        // 定义click事件\n        menu.clickEvent = function (e) {\n            var menu = this;\n            var dropPanel = menu.dropPanel;\n\n            // -------------隐藏----------------\n            if (dropPanel.isShowing) {\n                dropPanel.hide();\n                return;\n            }\n\n            // -------------显示----------------\n\n            // 重置 input\n            $textInput.val('');\n            $urlInput.val('http://');\n\n            // 获取url\n            var url = '';\n            var rangeElem = editor.getRangeElem();\n            rangeElem = editor.getSelfOrParentByName(rangeElem, 'a');\n            if (rangeElem) {\n                url = rangeElem.href || '';\n            }\n\n            // 获取 text\n            var text = '';\n            var isRangeEmpty = editor.isRangeEmpty();\n            if (!isRangeEmpty) {\n                // 选区不是空\n                text = editor.getRangeText() || '';\n            } else if (rangeElem) {\n                // 如果选区空，并且在 a 标签之内\n                text = rangeElem.textContent || rangeElem.innerHTML;\n            }\n\n            // 设置 url 和 text\n            url && $urlInput.val(url);\n            text && $textInput.val(text);\n\n            // 如果有选区内容，textinput 不能修改\n            if (!isRangeEmpty) {\n                $textInput.attr('disabled', true);\n            } else {\n                $textInput.removeAttr('disabled');\n            }\n\n            // 显示（要设置好了所有input的值和属性之后再显示）\n            dropPanel.show();\n        };\n\n        // 定义 update selected 事件\n        menu.updateSelectedEvent = function () {\n            var rangeElem = editor.getRangeElem();\n            rangeElem = editor.getSelfOrParentByName(rangeElem, 'a');\n            if (rangeElem) {\n                return true;\n            }\n            return false;\n        };\n\n        // 『取消』 按钮\n        $btnCancel.click(function (e) {\n            e.preventDefault();\n            menu.dropPanel.hide();\n        });\n\n        // 『确定』按钮\n        $btnSubmit.click(function (e) {\n            e.preventDefault();\n            var rangeElem = editor.getRangeElem();\n            var targetElem = editor.getSelfOrParentByName(rangeElem, 'a');\n            var isRangeEmpty = editor.isRangeEmpty();\n\n            var $linkElem, linkHtml;\n            var commandFn, callback;\n            var $txt = editor.txt.$txt;\n            var $oldLinks, $newLinks;\n            var uniqId = 'link' + E.random();\n\n            // 获取数据\n            var url = $.trim($urlInput.val());\n            var text = $.trim($textInput.val());\n\n            if (!url) {\n                menu.dropPanel.focusFirstInput();\n                return;\n            }\n            if (!text) {\n                text = url;\n            }\n\n            if (!isRangeEmpty) {\n                // 选中区域有内容，则执行默认命令\n\n                // 获取目前 txt 内所有链接，并为当前链接做一个标记\n                $oldLinks = $txt.find('a');\n                $oldLinks.attr(uniqId, '1');\n\n                // 执行命令 \n                editor.command(e, 'createLink', url);\n\n                // 去的没有标记的链接，即刚刚插入的链接\n                $newLinks = $txt.find('a').not('[' + uniqId + ']');\n                $newLinks.attr('target', '_blank'); // 增加 _blank\n\n                // 去掉之前做的标记\n                $oldLinks.removeAttr(uniqId);\n\n            } else if (targetElem) {\n                // 无选中区域，在 a 标签之内，修改该 a 标签的内容和链接\n                $linkElem = $(targetElem);\n                commandFn = function () {\n                    $linkElem.attr('href', url);\n                    $linkElem.text(text);\n                };\n                callback = function () {\n                    var editor = this;\n                    editor.restoreSelectionByElem(targetElem);\n                };\n                // 执行命令\n                editor.customCommand(e, commandFn, callback);\n            } else {\n                // 无选中区域，不在 a 标签之内，插入新的链接\n\n                linkHtml = '<a href=\"' + url + '\" target=\"_blank\">' + text + '</a>';\n                if (E.userAgent.indexOf('Firefox') > 0) {\n                    linkHtml += '<span>&nbsp;</span>';\n                }\n                editor.command(e, 'insertHtml', linkHtml);\n            }\n\n        });\n        \n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// unlink 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'unlink';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.unlink,\n            commandName: 'unLink'\n        });\n\n        // click 事件\n        menu.clickEvent = function  (e) {\n            var isRangeEmpty = editor.isRangeEmpty();\n            if (!isRangeEmpty) {\n                // 有选中区域，或者IE8，执行默认命令\n                editor.command(e, 'unLink');\n                return;\n            }\n\n            // 无选中区域...\n\n            var rangeElem = editor.getRangeElem();\n            var aElem = editor.getSelfOrParentByName(rangeElem, 'a');\n            if (!aElem) {\n                // 不在 a 之内，返回\n                e.preventDefault();\n                return;\n            }\n\n            // 在 a 之内\n            var $a = $(aElem);\n            var $span = $('<span>' + $a.text() + '</span>');\n            function commandFn() {\n                $a.after($span).remove();\n            }\n            function callback() {\n                editor.restoreSelectionByElem($span.get(0));\n            }\n            editor.customCommand(e, commandFn, callback);\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// table 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'table';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.table\n        });\n\n        // dropPanel 内容\n        var $content = $('<div style=\"font-size: 14px; color: #666; text-align:right;\"></div>');\n        var $table = $('<table class=\"choose-table\" style=\"margin-bottom:10px;margin-top:5px;\">');\n        var $row = $('<span>0</span>');\n        var $rowspan = $('<span> 行 </span>');\n        var $col = $('<span>0</span>');\n        var $colspan = $('<span> 列</span>');\n        var $tr;\n        var i, j;\n\n        // 创建一个n行n列的表格\n        for (i = 0; i < 15; i++) {\n            $tr = $('<tr index=\"' + (i + 1) + '\">');\n            for (j = 0; j < 20; j++) {\n                $tr.append($('<td index=\"' + (j + 1) + '\">'));\n            }\n            $table.append($tr);\n        }\n        $content.append($table);\n        $content.append($row).append($rowspan).append($col).append($colspan);\n\n        // 定义table事件\n        $table.on('mouseenter', 'td', function (e) {\n            var $currentTd = $(e.currentTarget);\n            var currentTdIndex = $currentTd.attr('index');\n            var $currentTr = $currentTd.parent();\n            var currentTrIndex = $currentTr.attr('index');\n\n            // 显示\n            $row.text(currentTrIndex);\n            $col.text(currentTdIndex);\n\n            // 遍历设置背景颜色\n            $table.find('tr').each(function () {\n                var $tr = $(this);\n                var trIndex = $tr.attr('index');\n                if (parseInt(trIndex, 10) <= parseInt(currentTrIndex, 10)) {\n                    // 该行需要可能需要设置背景色\n                    $tr.find('td').each(function () {\n                        var $td = $(this);\n                        var tdIndex = $td.attr('index');\n                        if (parseInt(tdIndex, 10) <= parseInt(currentTdIndex, 10)) {\n                            // 需要设置背景色\n                            $td.addClass('active');\n                        } else {\n                            // 需要移除背景色\n                            $td.removeClass('active');\n                        }\n                    });\n                } else {\n                    // 改行不需要设置背景色\n                    $tr.find('td').removeClass('active');\n                }\n            });\n        }).on('mouseleave', function (e) {\n            // mouseleave 删除背景色\n            $table.find('td').removeClass('active');\n\n            $row.text(0);\n            $col.text(0);\n        });\n\n        // 插入表格\n        $table.on('click', 'td', function (e) {\n            var $currentTd = $(e.currentTarget);\n            var currentTdIndex = $currentTd.attr('index');\n            var $currentTr = $currentTd.parent();\n            var currentTrIndex = $currentTr.attr('index');\n\n            var rownum = parseInt(currentTrIndex, 10);\n            var colnum = parseInt(currentTdIndex, 10);\n\n            // -------- 拼接tabel html --------\n\n            var i, j;\n            var tableHtml = '<table>';\n            for (i = 0; i < rownum; i++) {\n                tableHtml += '<tr>';\n\n                for (j = 0; j < colnum; j++) {\n                    tableHtml += '<td><span>&nbsp;</span></td>';\n                }\n                tableHtml += '</tr>';\n            }\n            tableHtml += '</table>';\n\n            // -------- 执行命令 --------\n            editor.command(e, 'insertHtml', tableHtml);\n        });\n\n        // 创建 panel\n        menu.dropPanel = new E.DropPanel(editor, menu, {\n            $content: $content,\n            width: 262\n        });\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// emotion 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'emotion';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var config = editor.config;\n        var lang = config.lang;\n        var configEmotions = config.emotions;\n        var emotionsShow = config.emotionsShow;\n\n        // 记录每一个表情图片的地址\n        editor.emotionUrls = [];\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.emotion\n        });\n\n        // 添加表情图片的函数\n        function insertEmotionImgs(data, $tabContent) {\n            // 添加表情图片\n            $.each(data, function (k, emotion) {\n                var src = emotion.icon || emotion.url;\n                var value = emotion.value || emotion.title;\n                // 通过配置 editor.config.emotionsShow 的值来修改插入到编辑器的内容（图片/value）\n                var commandValue = emotionsShow === 'icon' ? src : value;\n                var $command = $('<a href=\"#\" commandValue=\"' + commandValue + '\"></a>');\n                var $img = $('<img>');\n                $img.attr('_src', src);  // 先将 src 复制到 '_src' 属性，先不加载\n\n                $command.append($img);\n                $tabContent.append($command);\n\n                // 记录下每一个表情图片的地址\n                editor.emotionUrls.push(src);\n            });\n        }\n\n        // 拼接 dropPanel 内容\n        var $panelContent = $('<div class=\"panel-tab\"></div>');\n        var $tabContainer = $('<div class=\"tab-container\"></div>');\n        var $contentContainer = $('<div class=\"content-container emotion-content-container\"></div>');\n        $.each(configEmotions, function (k, emotion) {\n            var title = emotion.title;\n            var data = emotion.data;\n\n            E.log('正在处理 ' + title + ' 表情的数据...');\n\n            // 增加该组表情的tab和content\n            var $tab = $('<a href=\"#\">' + title +' </a>');\n            $tabContainer.append($tab);\n            var $tabContent = $('<div class=\"content\"></div>');\n            $contentContainer.append($tabContent);\n\n            // tab 切换事件\n            $tab.click(function (e) {\n                $tabContainer.children().removeClass('selected');\n                $contentContainer.children().removeClass('selected');\n                $tabContent.addClass('selected');\n                $tab.addClass('selected');\n                e.preventDefault();\n            });\n\n            // 处理data\n            if (typeof data === 'string') {\n                // url 形式，需要通过ajax从该url获取数据\n                E.log('将通过 ' + data + ' 地址ajax下载表情包');\n                $.get(data, function (result) {\n                    result = $.parseJSON(result);\n                    E.log('下载完毕，得到 ' + result.length + ' 个表情');\n                    insertEmotionImgs(result, $tabContent);\n                });\n                \n            } else if ( Object.prototype.toString.call(data).toLowerCase().indexOf('array') > 0 ) {\n                // 数组，即 data 直接就是表情包数据\n                insertEmotionImgs(data, $tabContent);\n            } else {\n                // 其他情况，data格式不对\n                E.error('data 数据格式错误，请修改为正确格式，参考文档：' + E.docsite);\n                return;\n            }\n        });\n        $panelContent.append($tabContainer).append($contentContainer);\n\n        // 默认显示第一个tab\n        $tabContainer.children().first().addClass('selected');\n        $contentContainer.children().first().addClass('selected');\n\n        // 插入表情command事件\n        $contentContainer.on('click', 'a[commandValue]', function (e) {\n            var $a = $(e.currentTarget);\n            var commandValue = $a.attr('commandValue');\n            var img;\n\n            // commandValue 有可能是图片url，也有可能是表情的 value，需要区别对待\n\n            if (emotionsShow === 'icon') {\n                // 插入图片\n                editor.command(e, 'InsertImage', commandValue);\n            } else {\n                // 插入value\n                editor.command(e, 'insertHtml', '<span>' + commandValue + '</span>');\n            }\n\n            e.preventDefault();\n        });\n\n        // 添加panel\n        menu.dropPanel = new E.DropPanel(editor, menu, {\n            $content: $panelContent,\n            width: 350\n        });\n\n        // 定义click事件（异步加载表情图片）\n        menu.clickEvent = function (e) {\n            var menu = this;\n            var dropPanel = menu.dropPanel;\n\n            // -------------隐藏-------------\n            if (dropPanel.isShowing) {\n                dropPanel.hide();\n                return;\n            }\n\n            // -------------显示-------------\n            dropPanel.show();\n\n            // 异步加载图片\n            if (menu.imgLoaded) {\n                return;\n            }\n            $contentContainer.find('img').each(function () {\n                var $img = $(this);\n                var _src = $img.attr('_src');\n                $img.on('error', function () {\n                    E.error('加载不出表情图片 ' + _src);\n                });\n                $img.attr('src', _src);\n                $img.removeAttr('_src');\n            });\n            menu.imgLoaded = true;\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// img 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'img';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.img\n        });\n\n        // 创建 panel content\n        var $panelContent = $('<div class=\"panel-tab\"></div>');\n        var $tabContainer = $('<div class=\"tab-container\"></div>');\n        var $contentContainer = $('<div class=\"content-container\"></div>');\n        $panelContent.append($tabContainer).append($contentContainer);\n\n        // tab\n        var $uploadTab = $('<a href=\"#\">上传图片</a>');\n        var $linkTab = $('<a href=\"#\">网络图片</a>');\n        $tabContainer.append($uploadTab).append($linkTab);\n\n        // 上传图片 content\n        var $uploadContent = $('<div class=\"content\"></div>');\n        $contentContainer.append($uploadContent);\n\n        // 网络图片 content\n        var $linkContent = $('<div class=\"content\"></div>');\n        $contentContainer.append($linkContent);\n        linkContentHandler(editor, menu, $linkContent);\n\n        // 添加panel\n        menu.dropPanel = new E.DropPanel(editor, menu, {\n            $content: $panelContent,\n            width: 400,\n            onRender: function () {\n                // 渲染后的回调事件，用于执行自定义上传的init\n                // 因为渲染之后，上传面板的dom才会被渲染到页面，才能让第三方空间获取到\n                var init = editor.config.customUploadInit;\n                init && init.call(editor);\n            }\n        });\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n\n        // tab 切换事件\n        function tabToggle() {\n            $uploadTab.click(function (e) {\n                $tabContainer.children().removeClass('selected');\n                $contentContainer.children().removeClass('selected');\n                $uploadContent.addClass('selected');\n                $uploadTab.addClass('selected');\n                e.preventDefault();\n            });\n            $linkTab.click(function (e) {\n                $tabContainer.children().removeClass('selected');\n                $contentContainer.children().removeClass('selected');\n                $linkContent.addClass('selected');\n                $linkTab.addClass('selected');\n                e.preventDefault();\n\n                // focus input\n                if (E.placeholder) {\n                    $linkContent.find('input[type=text]').focus();\n                }\n            });\n\n            // 默认情况\n            // $uploadTab.addClass('selected');\n            // $uploadContent.addClass('selected');\n            $uploadTab.click();\n        }\n\n        // 隐藏上传图片\n        function hideUploadImg() {\n            $tabContainer.remove();\n            $uploadContent.remove();\n            $linkContent.addClass('selected');\n        }\n\n        // 隐藏网络图片\n        function hideLinkImg() {\n            $tabContainer.remove();\n            $linkContent.remove();\n            $uploadContent.addClass('selected');\n        }\n\n        // 判断用户是否配置了上传图片\n        editor.ready(function () {\n            var editor = this;\n            var config = editor.config;\n            var uploadImgUrl = config.uploadImgUrl;\n            var customUpload = config.customUpload;\n            var linkImg = config.hideLinkImg;\n            var $uploadImgPanel;\n\n            if (uploadImgUrl || customUpload) {\n                // 第一，暴露出 $uploadContent 以便用户自定义 ！！！重要\n                editor.$uploadContent = $uploadContent;\n\n                // 第二，绑定tab切换事件\n                tabToggle();\n\n                if (linkImg) {\n                    // 隐藏网络图片\n                    hideLinkImg();\n                }\n            } else {\n                // 未配置上传图片功能\n                hideUploadImg();\n            }\n\n            // 点击 $uploadContent 立即隐藏 dropPanel\n            // 为了兼容IE8、9的上传，因为IE8、9使用 modal 上传\n            // 这里使用异步，为了不妨碍高级浏览器通过点击 $uploadContent 选择文件\n            function hidePanel() {\n                menu.dropPanel.hide();\n            }\n            $uploadContent.click(function () {\n                setTimeout(hidePanel);\n            });\n        });\n    });\n\n    // --------------- 处理网络图片content ---------------\n    function linkContentHandler (editor, menu, $linkContent) {\n        var lang = editor.config.lang;\n        var $urlContainer = $('<div style=\"margin:20px 10px 10px 10px;\"></div>');\n        var $urlInput = $('<input type=\"text\" class=\"block\" placeholder=\"http://\"/>');\n        $urlContainer.append($urlInput);\n        var $btnSubmit = $('<button class=\"right\">' + lang.submit + '</button>');\n        var $btnCancel = $('<button class=\"right gray\">' + lang.cancel + '</button>');\n\n        $linkContent.append($urlContainer).append($btnSubmit).append($btnCancel);\n\n        // 取消\n        $btnCancel.click(function (e) {\n            e.preventDefault();\n            menu.dropPanel.hide();\n        });\n\n        // callback \n        function callback() {\n            $urlInput.val('');\n        }\n\n        // 确定\n        $btnSubmit.click(function (e) {\n            e.preventDefault();\n            var url = $.trim($urlInput.val());\n            if (!url) {\n                // 无内容\n                $urlInput.focus();\n                return;\n            }\n\n            var imgHtml = '<img style=\"max-width:100%;\" src=\"' + url + '\"/>';\n            editor.command(e, 'insertHtml', imgHtml, callback);\n        });\n    }\n\n});\n// video 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'video';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n        var reg = /^<(iframe)|(embed)/i;  // <iframe... 或者 <embed... 格式\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.video\n        });\n\n        // 创建 panel 内容\n        var $content = $('<div></div>');\n        var $linkInputContainer = $('<div style=\"margin:20px 10px;\"></div>');\n        var $linkInput = $('<input type=\"text\" class=\"block\" placeholder=\\'格式如：<iframe src=\"...\" frameborder=0 allowfullscreen></iframe>\\'/>');\n        $linkInputContainer.append($linkInput);\n        var $sizeContainer = $('<div style=\"margin:20px 10px;\"></div>');\n        var $widthInput = $('<input type=\"text\" value=\"640\" style=\"width:50px;text-align:center;\"/>');\n        var $heightInput = $('<input type=\"text\" value=\"498\" style=\"width:50px;text-align:center;\"/>');\n        $sizeContainer.append('<span> ' + lang.width + ' </span>')\n                      .append($widthInput)\n                      .append('<span> px &nbsp;&nbsp;&nbsp;</span>')\n                      .append('<span> ' + lang.height + ' </span>')\n                      .append($heightInput)\n                      .append('<span> px </span>');\n        var $btnContainer = $('<div></div>');\n        var $howToCopy = $('<a href=\"http://www.kancloud.cn/wangfupeng/wangeditor2/134973\" target=\"_blank\" style=\"display:inline-block;margin-top:10px;margin-left:10px;color:#999;\">如何复制视频链接？</a>');\n        var $btnSubmit = $('<button class=\"right\">' + lang.submit + '</button>');\n        var $btnCancel = $('<button class=\"right gray\">' + lang.cancel + '</button>');\n        $btnContainer.append($howToCopy).append($btnSubmit).append($btnCancel);\n        $content.append($linkInputContainer).append($sizeContainer).append($btnContainer);\n\n        // 取消按钮\n        $btnCancel.click(function (e) {\n            e.preventDefault();\n            $linkInput.val('');\n            menu.dropPanel.hide();\n        });\n\n        // 确定按钮\n        $btnSubmit.click(function (e) {\n            e.preventDefault();\n            var link = $.trim($linkInput.val());\n            var $link;\n            var width = parseInt($widthInput.val());\n            var height = parseInt($heightInput.val());\n            var $div = $('<div>');\n            var html = '<p>{content}</p>';\n\n            // 验证数据\n            if (!link) {\n                menu.dropPanel.focusFirstInput();\n                return;\n            }\n\n            if (!reg.test(link)) {\n                alert('视频链接格式错误！');\n                menu.dropPanel.focusFirstInput();\n                return;\n            }\n\n            if (isNaN(width) || isNaN(height)) {\n                alert('宽度或高度不是数字！');\n                return;\n            }\n\n            $link = $(link);\n\n            // 设置高度和宽度\n            $link.attr('width', width)\n                 .attr('height', height);\n\n            // 拼接字符串\n            html = html.replace('{content}', $div.append($link).html());\n\n            // 执行命令\n            editor.command(e, 'insertHtml', html);\n            $linkInput.val('');\n        });\n\n        // 创建panel\n        menu.dropPanel = new E.DropPanel(editor, menu, {\n            $content: $content,\n            width: 400\n        });\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// location 菜单\n_e(function (E, $) {\n\n    // 判断浏览器的 input 是否支持 keyup\n    var inputKeyup = (function (input) {\n        return 'onkeyup' in input;\n    })(document.createElement('input'));\n\n    // 百度地图的key\n    E.baiduMapAk = 'TVhjYjq1ICT2qqL5LdS8mwas';\n\n    // 一个页面中，如果有多个编辑器，地图会出现问题。这个参数记录一下，如果超过 1 就提示\n    E.numberOfLocation = 0;\n\n    E.createMenu(function (check) {\n        var menuId = 'location';\n        if (!check(menuId)) {\n            return;\n        }\n\n        if (++E.numberOfLocation > 1) {\n            E.error('目前不支持在一个页面多个编辑器上同时使用地图，可通过自定义菜单配置去掉地图菜单');\n            return;\n        }\n\n        var editor = this;\n        var config = editor.config;\n        var lang = config.lang;\n        var ak = config.mapAk;\n\n        // 地图的变量存储到这个地方\n        editor.mapData = {};\n        var mapData = editor.mapData;\n\n        // ---------- 地图事件 ----------\n        mapData.markers = [];\n        mapData.mapContainerId = 'map' + E.random();\n\n        mapData.clearLocations = function () {\n            var map = mapData.map;\n            if (!map) {\n                return;\n            }\n            map.clearOverlays();\n\n            //同时，清空marker数组\n            mapData.markers = [];\n        };\n\n        mapData.searchMap = function () {\n            var map = mapData.map;\n            if (!map) {\n                return;\n            }\n\n            var BMap = window.BMap;\n            var cityName = $cityInput.val();\n            var locationName = $searchInput.val();\n            var myGeo, marker;\n\n            if(cityName !== ''){\n                if(!locationName || locationName === ''){\n                    map.centerAndZoom(cityName, 11);\n                }\n\n                //地址解析\n                if(locationName && locationName !== ''){\n                    myGeo = new BMap.Geocoder();\n                    // 将地址解析结果显示在地图上,并调整地图视野\n                    myGeo.getPoint(locationName, function(point){\n                        if (point) {\n                            map.centerAndZoom(point, 13);\n                            marker = new BMap.Marker(point);\n                            map.addOverlay(marker);\n                            marker.enableDragging();  //允许拖拽\n                            mapData.markers.push(marker);  //将marker加入到数组中\n                        }else{\n                            // alert('未找到');\n                            map.centerAndZoom(cityName, 11);  //找不到则重新定位到城市\n                        }\n                    }, cityName);\n                }\n            } // if(cityName !== '')\n        };\n\n        // load script 之后的 callback\n        var hasCallback = false;\n        window.baiduMapCallBack = function(){\n            // 避免重复加载\n            if (hasCallback) {\n                return;\n            } else {\n                hasCallback = true;\n            }\n\n            var BMap = window.BMap;\n            if (!mapData.map) {\n                // 创建Map实例\n                mapData.map = new BMap.Map(mapData.mapContainerId);\n            }\n            var map = mapData.map;\n\n            map.centerAndZoom(new BMap.Point(116.404, 39.915), 11);  // 初始化地图,设置中心点坐标和地图级别\n            map.addControl(new BMap.MapTypeControl());   //添加地图类型控件\n            map.setCurrentCity(\"北京\");          // 设置地图显示的城市 此项是必须设置的\n            map.enableScrollWheelZoom(true);     //开启鼠标滚轮缩放\n\n            //根据IP定位\n            function locationFun(result){\n                var cityName = result.name;\n                map.setCenter(cityName);\n\n                // 设置城市名称\n                $cityInput.val(cityName);\n                if (E.placeholder) {\n                    $searchInput.focus();\n                }\n                var timeoutId, searchFn;\n                if (inputKeyup) {\n                   // 并绑定搜索事件 - input 支持 keyup\n                   searchFn = function (e) {\n                       if (e.type === 'keyup' && e.keyCode === 13) {\n                           e.preventDefault();\n                       }\n                       if (timeoutId) {\n                           clearTimeout(timeoutId);\n                       }\n                       timeoutId = setTimeout(mapData.searchMap, 500);\n                   };\n                   $cityInput.on('keyup change paste', searchFn);\n                   $searchInput.on('keyup change paste', searchFn); \n                } else {\n                    // 并绑定搜索事件 - input 不支持 keyup\n                    searchFn = function () {\n                        if (!$content.is(':visible')) {\n                            // panel 不显示了，就不用再监控了\n                            clearTimeout(timeoutId);\n                            return;\n                        }\n\n                        var currentCity = '';\n                        var currentSearch = '';\n                        var city = $cityInput.val();\n                        var search = $searchInput.val();\n\n                        if (city !== currentCity || search !== currentSearch) {\n                            // 刚获取的数据和之前的数据不一致，执行查询\n                            mapData.searchMap();\n                            // 更新数据\n                            currentCity = city;\n                            currentSearch = search;\n                        }\n\n                        // 继续监控\n                        if (timeoutId) {\n                            clearTimeout(timeoutId);\n                        }\n                        timeoutId = setTimeout(searchFn, 1000);\n                    };\n                    // 开始监控\n                    timeoutId = setTimeout(searchFn, 1000);\n                }\n            }\n            var myCity = new BMap.LocalCity();\n            myCity.get(locationFun);\n\n            //鼠标点击，创建位置\n            map.addEventListener(\"click\", function(e){\n                var marker = new BMap.Marker(new BMap.Point(e.point.lng, e.point.lat)); \n                map.addOverlay(marker);  \n                marker.enableDragging();\n                mapData.markers.push(marker);  //加入到数组中\n            }, false);\n        };\n\n        mapData.loadMapScript = function () {\n            var script = document.createElement(\"script\");\n            script.type = \"text/javascript\";\n            script.src = \"https://api.map.baidu.com/api?v=2.0&ak=\" + ak + \"&s=1&callback=baiduMapCallBack\";  // baiduMapCallBack是一个本地函数\n            try {\n                // IE10- 报错\n                document.body.appendChild(script);\n            } catch (ex) {\n                E.error('加载地图过程中发生错误');\n            }\n        };\n\n        // 初始化地图\n        mapData.initMap = function () {\n            if (window.BMap) {\n                // 不是第一次，直接处理地图即可\n                window.baiduMapCallBack();\n            } else {\n                // 第一次，先加载地图 script，再处理地图（script加载完自动执行处理）\n                mapData.loadMapScript();\n            }\n        };\n\n        // ---------- 创建 menu 对象 ----------\n\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.location\n        });\n\n        editor.menus[menuId] = menu;\n\n        // ---------- 构建UI ----------\n\n        // panel content \n        var $content = $('<div></div>');\n\n        // 搜索框\n        var $inputContainer = $('<div style=\"margin:10px 0;\"></div>');\n        var $cityInput = $('<input type=\"text\"/>');\n        $cityInput.css({\n            width: '80px',\n            'text-align': 'center'\n        });\n        var $searchInput = $('<input type=\"text\"/>');\n        $searchInput.css({\n            width: '300px',\n            'margin-left': '10px'\n        }).attr('placeholder', lang.searchlocation);\n        var $clearBtn = $('<button class=\"right link\">' + lang.clearLocation + '</button>');\n        $inputContainer.append($clearBtn)\n                       .append($cityInput)\n                       .append($searchInput);\n        $content.append($inputContainer);\n\n        // 清除位置按钮\n        $clearBtn.click(function (e) {\n            $searchInput.val('');\n            $searchInput.focus();\n            mapData.clearLocations();\n            e.preventDefault();\n        });\n\n        // 地图\n        var $map = $('<div id=\"' + mapData.mapContainerId + '\"></div>');\n        $map.css({\n            height: '260px',\n            width: '100%',\n            position: 'relative',\n            'margin-top': '10px',\n            border: '1px solid #f1f1f1'\n        });\n        var $mapLoading = $('<span>' + lang.loading + '</span>');\n        $mapLoading.css({\n            position: 'absolute',\n            width: '100px',\n            'text-align': 'center',\n            top: '45%',\n            left: '50%',\n            'margin-left': '-50px'\n        });\n        $map.append($mapLoading);\n        $content.append($map);\n\n        // 按钮\n        var $btnContainer = $('<div style=\"margin:10px 0;\"></div>');\n        var $btnSubmit = $('<button class=\"right\">' + lang.submit + '</button>');\n        var $btnCancel = $('<button class=\"right gray\">' + lang.cancel + '</button>');\n        var $checkLabel = $('<label style=\"display:inline-block;margin-top:10px;color:#666;\"></label>');\n        var $check = $('<input type=\"checkbox\">');\n        $checkLabel.append($check).append('<span style=\"display:inline-block;margin-left:5px;\">  ' + lang.dynamicMap + '</span>');\n        $btnContainer.append($checkLabel)\n                     .append($btnSubmit)\n                     .append($btnCancel);\n        $content.append($btnContainer);\n\n        function callback() {\n            $searchInput.val('');\n        }\n\n        // 『取消』按钮事件\n        $btnCancel.click(function (e) {\n            e.preventDefault();\n            callback();\n            menu.dropPanel.hide();\n        });\n\n        // 『确定』按钮事件\n        $btnSubmit.click(function (e) {\n            e.preventDefault();\n            var map = mapData.map,\n                isDynamic = $check.is(':checked'),\n                markers =  mapData.markers,\n\n                center = map.getCenter(),\n                centerLng = center.lng,\n                centerLat = center.lat,\n\n                zoom = map.getZoom(),\n\n                size = map.getSize(),\n                sizeWidth = size.width,\n                sizeHeight = size.height,\n\n                position,\n                src,\n                iframe;\n\n            if(isDynamic){\n                //动态地址\n                src = 'http://ueditor.baidu.com/ueditor/dialogs/map/show.html#';\n            }else{\n                //静态地址\n                src = 'http://api.map.baidu.com/staticimage?';\n            }\n\n            //src参数\n            src = src +'center=' + centerLng + ',' + centerLat +\n                '&zoom=' + zoom +\n                '&width=' + sizeWidth +\n                '&height=' + sizeHeight;\n            if(markers.length > 0){\n                src = src + '&markers=';\n\n                //添加所有的marker\n                $.each(markers, function(key, value){\n                    position = value.getPosition();\n                    if(key > 0){\n                        src = src + '|';\n                    }\n                    src = src + position.lng + ',' + position.lat;\n                });\n            }\n\n            if(isDynamic){\n                if(markers.length > 1){\n                    alert( lang.langDynamicOneLocation );\n                    return;\n                }\n\n                src += '&markerStyles=l,A';\n\n                //插入iframe\n                iframe = '<iframe class=\"ueditor_baidumap\" src=\"{src}\" frameborder=\"0\" width=\"' + sizeWidth + '\" height=\"' + sizeHeight + '\"></iframe>';\n                iframe = iframe.replace('{src}', src);\n                editor.command(e, 'insertHtml', iframe, callback);\n            }else{\n                //插入图片\n                editor.command(e, 'insertHtml', '<img style=\"max-width:100%;\" src=\"' + src + '\"/>', callback);\n            }\n        });\n\n        // 根据 UI 创建菜单 panel\n        menu.dropPanel = new E.DropPanel(editor, menu, {\n            $content: $content,\n            width: 500\n        });\n\n        // ---------- 事件 ----------\n\n        // render 时执行事件\n        menu.onRender = function () {\n            if (ak === E.baiduMapAk) {\n                E.warn('建议在配置中自定义百度地图的mapAk，否则可能影响地图功能，文档：' + E.docsite);\n            }\n        };\n\n        // click 事件\n        menu.clickEvent = function (e) {\n            var menu = this;\n            var dropPanel = menu.dropPanel;\n            var firstTime = false;\n\n            // -------------隐藏-------------\n            if (dropPanel.isShowing) {\n                dropPanel.hide();\n                return;\n            }\n\n            // -------------显示-------------\n            if (!mapData.map) {\n                // 第一次，先加载地图\n                firstTime = true;\n            }\n            \n            dropPanel.show();\n            mapData.initMap();\n\n            if (!firstTime) {\n                $searchInput.focus();\n            }\n        };\n\n    });\n\n});\n// insertcode 菜单\n_e(function (E, $) {\n\n    // 加载 highlightjs 代码\n    function loadHljs() {\n        if (E.userAgent.indexOf('MSIE 8') > 0) {\n            // 不支持 IE8\n            return;\n        }\n        if (window.hljs) {\n            // 不要重复加载\n            return;\n        }\n        var script = document.createElement(\"script\");\n        script.type = \"text/javascript\";\n        script.src = \"//cdn.bootcss.com/highlight.js/9.2.0/highlight.min.js\";\n        document.body.appendChild(script);\n    }\n    \n\n    E.createMenu(function (check) {\n        var menuId = 'insertcode';\n        if (!check(menuId)) {\n            return;\n        }\n\n        // 加载 highlightjs 代码\n        setTimeout(loadHljs, 0);\n\n        var editor = this;\n        var config = editor.config;\n        var lang = config.lang;\n        var $txt = editor.txt.$txt;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.insertcode\n        });\n\n        // click 事件\n        menu.clickEvent = function (e) {\n            var menu = this;\n            var dropPanel = menu.dropPanel;\n\n            // 隐藏\n            if (dropPanel.isShowing) {\n                dropPanel.hide();\n                return;\n            }\n\n            // 显示\n            $textarea.val('');\n            dropPanel.show();\n\n            // highlightjs 语言列表\n            var hljs = window.hljs;\n            if (hljs && hljs.listLanguages) {\n                if ($langSelect.children().length !== 0) {\n                    return;\n                }\n                $langSelect.css({\n                    'margin-top': '9px',\n                    'margin-left': '5px'\n                });\n                $.each(hljs.listLanguages(), function (key, lang) {\n                    if (lang === 'xml') {\n                        lang = 'html';\n                    }\n                    if (lang === config.codeDefaultLang) {\n                        $langSelect.append('<option value=\"' + lang + '\" selected=\"selected\">' + lang + '</option>');\n                    } else {\n                        $langSelect.append('<option value=\"' + lang + '\">' + lang + '</option>');\n                    }\n                });\n            } else {\n                $langSelect.hide();\n            }\n        };\n\n        // 选中状态下的 click 事件\n        menu.clickEventSelected = function (e) {\n            var menu = this;\n            var dropPanel = menu.dropPanel;\n\n            // 隐藏\n            if (dropPanel.isShowing) {\n                dropPanel.hide();\n                return;\n            }\n\n            // 显示\n            dropPanel.show();\n\n            var rangeElem = editor.getRangeElem();\n            var targetElem = editor.getSelfOrParentByName(rangeElem, 'pre');\n            var $targetElem;\n            var className;\n            if (targetElem) {\n                // 确定找到 pre 之后，再找 code\n                targetElem = editor.getSelfOrParentByName(rangeElem, 'code');\n            }\n            if (!targetElem) {\n                return;\n            }\n            $targetElem = $(targetElem);\n\n            // 赋值内容\n            $textarea.val($targetElem.text());\n            if ($langSelect) {\n                // 赋值语言\n                className = $targetElem.attr('class');\n                if (className) {\n                    $langSelect.val(className.split(' ')[0]);\n                }\n            }\n        };\n\n        // 定义更新选中状态的事件\n        menu.updateSelectedEvent = function () {\n            var self = this; //菜单对象\n            var editor = self.editor;\n            var rangeElem;\n\n            rangeElem = editor.getRangeElem();\n            rangeElem = editor.getSelfOrParentByName(rangeElem, 'pre');\n\n            if (rangeElem) {\n                return true;\n            }\n\n            return false;\n        };\n\n        // 创建 panel\n        var $content = $('<div></div>');\n        var $textarea = $('<textarea></textarea>');\n        var $langSelect = $('<select></select>');\n        contentHandle($content);\n        menu.dropPanel = new E.DropPanel(editor, menu, {\n            $content: $content,\n            width: 500\n        });\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n\n        // ------ 增加 content 内容 ------\n        function contentHandle($content) {\n            // textarea 区域\n            var $textareaContainer = $('<div></div>');\n            $textareaContainer.css({\n                margin: '15px 5px 5px 5px',\n                height: '160px',\n                'text-align': 'center'\n            });\n            $textarea.css({\n                width: '100%',\n                height: '100%',\n                padding: '10px'\n            });\n            $textarea.on('keydown', function (e) {\n                // 取消 tab 键默认行为\n                if (e.keyCode === 9) {\n                    e.preventDefault();\n                }\n            });\n            $textareaContainer.append($textarea);\n            $content.append($textareaContainer);\n\n            // 按钮区域\n            var $btnContainer = $('<div></div>');\n            var $btnSubmit = $('<button class=\"right\">' + lang.submit + '</button>');\n            var $btnCancel = $('<button class=\"right gray\">' + lang.cancel + '</button>');\n\n            $btnContainer.append($btnSubmit).append($btnCancel).append($langSelect);\n            $content.append($btnContainer);\n\n            // 取消按钮\n            $btnCancel.click(function (e) {\n                e.preventDefault();\n                menu.dropPanel.hide();\n            });\n\n            // 确定按钮\n            var codeTpl = '<pre style=\"max-width:100%;overflow-x:auto;\"><code{#langClass}>{#content}</code></pre>';\n            $btnSubmit.click(function (e) {\n                e.preventDefault();\n                var val = $textarea.val();\n                if (!val) {\n                    // 无内容\n                    $textarea.focus();\n                    return;\n                }\n\n                var rangeElem = editor.getRangeElem();\n                if ($.trim($(rangeElem).text()) && codeTpl.indexOf('<p><br></p>') !== 0) {\n                    codeTpl = '<p><br></p>' + codeTpl;\n                }\n\n                var lang = $langSelect ? $langSelect.val() : ''; // 获取高亮语言\n                var langClass = '';\n                var doHightlight = function () {\n                    $txt.find('pre code').each(function (i, block) {\n                        var $block = $(block);\n                        if ($block.attr('codemark')) {\n                            // 有 codemark 标记的代码块，就不再重新格式化了\n                            return;\n                        } else if (window.hljs) {\n                            // 新代码块，格式化之后，立即标记 codemark\n                            window.hljs.highlightBlock(block);\n                            $block.attr('codemark', '1');\n                        }\n                    });\n                };\n\n                // 语言高亮样式\n                if (lang) {\n                    langClass = ' class=\"' + lang + ' hljs\"';\n                }\n\n                // 替换标签\n                val = val.replace(/&/gm, '&amp;')\n                         .replace(/</gm, '&lt;')\n                         .replace(/>/gm, '&gt;');\n\n                // ---- menu 未选中状态 ----\n                if (!menu.selected) {\n                    // 拼接html\n                    var html = codeTpl.replace('{#langClass}', langClass).replace('{#content}', val);\n                    editor.command(e, 'insertHtml', html, doHightlight);\n                    return;\n                }\n\n                // ---- menu 选中状态 ----\n                var targetElem = editor.getSelfOrParentByName(rangeElem, 'pre');\n                var $targetElem;\n                if (targetElem) {\n                    // 确定找到 pre 之后，再找 code\n                    targetElem = editor.getSelfOrParentByName(rangeElem, 'code');\n                }\n                if (!targetElem) {\n                    return;\n                }\n                $targetElem = $(targetElem);\n\n                function commandFn() {\n                    var className;\n                    if (lang) {\n                        className = $targetElem.attr('class');\n                        if (className !== lang + ' hljs') {\n                            $targetElem.attr('class', lang + ' hljs');\n                        }\n                    }\n                    $targetElem.html(val);\n                }\n                function callback() {\n                    editor.restoreSelectionByElem(targetElem);\n                    doHightlight();\n                }\n                editor.customCommand(e, commandFn, callback);\n            });\n        }\n\n        // ------ enter 时，不另起标签，只换行 ------\n        $txt.on('keydown', function (e) {\n            if (e.keyCode !== 13) {\n                return;\n            }\n            var rangeElem = editor.getRangeElem();\n            var targetElem = editor.getSelfOrParentByName(rangeElem, 'code');\n            if (!targetElem) {\n                return;\n            }\n\n            editor.command(e, 'insertHtml', '\\n');\n        });\n\n        // ------ 点击时，禁用其他标签 ------\n        function updateMenu() {\n            var rangeElem = editor.getRangeElem();\n            var targetElem = editor.getSelfOrParentByName(rangeElem, 'code');\n            if (targetElem) {\n                // 在 code 之内，禁用其他菜单\n                editor.disableMenusExcept('insertcode');\n            } else {\n                // 不是在 code 之内，启用其他菜单\n                editor.enableMenusExcept('insertcode');\n            }\n        }\n        $txt.on('keydown click', function (e) {\n            // 此处必须使用 setTimeout 异步处理，否则不对\n            setTimeout(updateMenu);\n        });\n    });\n\n});\n// undo 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'undo';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.undo\n        });\n\n        // click 事件\n        menu.clickEvent = function (e) {\n            editor.undo();\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n\n\n        // ------------ 初始化时、enter 时、打字中断时，做记录 ------------\n        // ------------ ctrl + z 是调用记录撤销，而不是使用浏览器默认的撤销 ------------\n        editor.ready(function () {\n            var editor = this;\n            var $txt = editor.txt.$txt;\n            var timeoutId;\n\n            // 执行undo记录\n            function undo() {\n                editor.undoRecord();\n            }\n\n            $txt.on('keydown', function (e) {\n                var keyCode = e.keyCode;\n\n                // 撤销 ctrl + z\n                if (e.ctrlKey && keyCode === 90) {\n                    editor.undo();\n                    return;\n                }\n\n                if (keyCode === 13) {\n                    // enter 做记录\n                    undo();\n                } else {\n                    // keyup 之后 1s 之内不操作，则做一次记录\n                    if (timeoutId) {\n                        clearTimeout(timeoutId);\n                    }\n                    timeoutId = setTimeout(undo, 1000);\n                }\n            });\n\n            // 初始化做记录\n            editor.undoRecord();\n        });\n    });\n\n});\n// redo 菜单\n_e(function (E, $) {\n\n    E.createMenu(function (check) {\n        var menuId = 'redo';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var lang = editor.config.lang;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.redo\n        });\n\n        // click 事件\n        menu.clickEvent = function (e) {\n            editor.redo();\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// 全屏 菜单\n_e(function (E, $) {\n\n    // 记录全屏时的scrollTop\n    var scrollTopWhenFullScreen;\n\n    E.createMenu(function (check) {\n        var menuId = 'fullscreen';\n        if (!check(menuId)) {\n            return;\n        }\n        var editor = this;\n        var $txt = editor.txt.$txt;\n        var config = editor.config;\n        var zIndexConfig = config.zindex || 10000;\n        var lang = config.lang;\n\n        var isSelected = false;\n        var zIndex;\n\n        var maxHeight;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,\n            id: menuId,\n            title: lang.fullscreen\n        });\n\n        // 定义click事件\n        menu.clickEvent = function (e) {\n            // 增加样式\n            var $editorContainer = editor.$editorContainer;\n            $editorContainer.addClass('wangEditor-fullscreen');\n\n            // （先保存当前的）再设置z-index\n            zIndex = $editorContainer.css('z-index');\n            $editorContainer.css('z-index', zIndexConfig);\n\n            var $wrapper;\n            var txtHeight = $txt.height();\n            var txtOuterHeight = $txt.outerHeight();\n\n            if (editor.useMaxHeight) {\n                // 记录 max-height，并暂时去掉maxheight\n                maxHeight = $txt.css('max-height');\n                $txt.css('max-height', 'none');\n\n                // 如果使用了maxHeight， 将$txt从它的父元素中移出来\n                $wrapper = $txt.parent();\n                $wrapper.after($txt);\n                $wrapper.remove();\n                $txt.css('overflow-y', 'auto');\n            }\n\n            // 设置高度到全屏\n            var menuContainer = editor.menuContainer;\n            $txt.height(\n                E.$window.height() - \n                menuContainer.height() - \n                (txtOuterHeight - txtHeight)  // 去掉内边距和外边距\n            );\n\n            // 取消menuContainer的内联样式（menu吸顶时，会为 menuContainer 设置一些内联样式）\n            editor.menuContainer.$menuContainer.attr('style', '');\n\n            // 保存状态\n            isSelected = true;\n\n            // 记录编辑器是否全屏\n            editor.isFullScreen = true;\n\n            // 记录设置全屏时的高度\n            scrollTopWhenFullScreen = E.$window.scrollTop();\n        };\n\n        // 定义选中状态的 click 事件\n        menu.clickEventSelected = function (e) {\n            // 取消样式\n            var $editorContainer = editor.$editorContainer;\n            $editorContainer.removeClass('wangEditor-fullscreen');\n            $editorContainer.css('z-index', zIndex);\n\n            // 还原height\n            if (editor.useMaxHeight) {\n                $txt.css('max-height', maxHeight);\n            } else {\n                // editor.valueContainerHeight 在 editor.txt.initHeight() 中事先保存了\n                editor.$valueContainer.css('height', editor.valueContainerHeight);\n            }\n\n            // 重新计算高度\n            editor.txt.initHeight();\n\n            // 保存状态\n            isSelected = false;\n\n            // 记录编辑器是否全屏\n            editor.isFullScreen = false;\n\n            // 还原scrollTop\n            if (scrollTopWhenFullScreen != null) {\n                E.$window.scrollTop(scrollTopWhenFullScreen);\n            }\n        };\n\n        // 定义选中事件\n        menu.updateSelectedEvent = function (e) {\n            return isSelected;\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// 渲染menus\n_e(function (E, $) {\n\n    E.fn.renderMenus = function () {\n\n        var editor = this;\n        var menus = editor.menus;\n        var menuIds = editor.config.menus;\n        var menuContainer = editor.menuContainer;\n\n        var menu;\n        var groupIdx = 0;\n        $.each(menuIds, function (k, v) {\n            if (v === '|') {\n                groupIdx++;\n                return;\n            }\n\n            menu = menus[v];\n            if (menu) {\n                menu.render(groupIdx);\n            }\n        });\n    };\n\n});\n// 渲染menus\n_e(function (E, $) {\n\n    E.fn.renderMenuContainer = function () {\n\n        var editor = this;\n        var menuContainer = editor.menuContainer;\n        var $editorContainer = editor.$editorContainer;\n\n        menuContainer.render();\n\n    };\n\n});\n// 渲染 txt\n_e(function (E, $) {\n\n    E.fn.renderTxt = function () {\n\n        var editor = this;\n        var txt = editor.txt;\n\n        txt.render();\n\n        // ready 时候，计算txt的高度\n        editor.ready(function () {\n            txt.initHeight();\n        });\n    };\n\n});\n// 渲染 container\n_e(function (E, $) {\n\n    E.fn.renderEditorContainer = function () {\n\n        var editor = this;\n        var $valueContainer = editor.$valueContainer;\n        var $editorContainer = editor.$editorContainer;\n        var $txt = editor.txt.$txt;\n        var $prev, $parent;\n\n        // 将编辑器渲染到页面中\n        if ($valueContainer === $txt) {\n            $prev = editor.$prev;\n            $parent = editor.$parent;\n\n            if ($prev && $prev.length) {\n                // 有前置节点，就插入到前置节点的后面\n                $prev.after($editorContainer);\n            } else {\n                // 没有前置节点，就直接插入到父元素\n                $parent.prepend($editorContainer);\n            }\n\n        } else {\n            $valueContainer.after($editorContainer);\n            $valueContainer.hide();\n        }\n\n        // 设置宽度（这样设置宽度有问题）\n        // $editorContainer.css('width', $valueContainer.css('width'));\n    };\n\n});\n// 菜单事件\n_e(function (E, $) {\n\n    // 绑定每个菜单的click事件\n    E.fn.eventMenus = function () {\n\n        var menus = this.menus;\n\n        // 绑定菜单的点击事件\n        $.each(menus, function (k, v) {\n            v.bindEvent();\n        });\n\n    };\n\n});\n// 菜单container事件\n_e(function (E, $) {\n\n    E.fn.eventMenuContainer = function () {\n\n    };\n\n});\n// 编辑区域事件\n_e(function (E, $) {\n\n    E.fn.eventTxt = function () {\n\n        var txt = this.txt;\n\n        // txt内容变化时，保存选区\n        txt.saveSelectionEvent();\n\n        // txt内容变化时，随时更新 value\n        txt.updateValueEvent();\n\n        // txt内容变化时，随时更新 menu style\n        txt.updateMenuStyleEvent();\n\n        // // 鼠标hover时，显示 p head 高度（暂时关闭这个功能）\n        // if (!/ie/i.test(E.userAgent)) {\n        //     // 暂时不支持IE\n        //     txt.showHeightOnHover();\n        // }\n    };\n\n});\n// 上传图片事件\n_e(function (E, $) {\n\n    E.plugin(function () {\n        var editor = this;\n        var fns = editor.config.uploadImgFns; // editor.config.uploadImgFns = {} 在config文件中定义了\n\n        // -------- 定义load函数 --------\n        fns.onload || (fns.onload = function (resultText, xhr) {\n            //koahubjs后台返回数据处理\n            var resultText = JSON.parse(resultText).data;\n            E.log('上传结束，返回结果为 ' + resultText);\n\n            var editor = this;\n            var originalName = editor.uploadImgOriginalName || '';  // 上传图片时，已经将图片的名字存在 editor.uploadImgOriginalName\n            var img;\n            if (resultText.indexOf('error|') === 0) {\n                // 提示错误\n                E.warn('上传失败：' + resultText.split('|')[1]);\n                alert(resultText.split('|')[1]);\n            } else {\n                E.log('上传成功，即将插入编辑区域，结果为：' + resultText);\n\n                // 将结果插入编辑器\n                img = document.createElement('img');\n                img.onload = function () {\n                    var html = '<img src=\"' + resultText + '\" alt=\"' + originalName + '\" style=\"max-width:100%;\"/>';\n                    editor.command(null, 'insertHtml', html);\n\n                    E.log('已插入图片，地址 ' + resultText);\n                    img = null;\n                };\n                img.onerror = function () {\n                    E.error('使用返回的结果获取图片，发生错误。请确认以下结果是否正确：' + resultText);\n                    img = null;\n                };\n                img.src = resultText;\n            }\n\n        });\n\n        // -------- 定义tiemout函数 --------\n        fns.ontimeout || (fns.ontimeout = function (xhr) {\n            E.error('上传图片超时');\n            alert('上传图片超时');\n        });\n\n        // -------- 定义error函数 --------\n        fns.onerror || (fns.onerror = function (xhr) {\n            E.error('上传上图片发生错误');\n            alert('上传上图片发生错误');\n        });\n\n    });\n});\n// xhr 上传图片\n_e(function (E, $) {\n\n    if (!window.FileReader || !window.FormData) {\n        // 如果不支持html5的文档操作，直接返回\n        return;\n    }\n\n    E.plugin(function () {\n\n        var editor = this;\n        var config = editor.config;\n        var uploadImgUrl = config.uploadImgUrl;\n        var uploadTimeout = config.uploadTimeout;\n\n        // 获取配置中的上传事件\n        var uploadImgFns = config.uploadImgFns;\n        var onload = uploadImgFns.onload;\n        var ontimeout = uploadImgFns.ontimeout;\n        var onerror = uploadImgFns.onerror;\n\n        if (!uploadImgUrl) {\n            return;\n        }\n\n        // -------- 将以base64的图片url数据转换为Blob --------\n        function convertBase64UrlToBlob(urlData, filetype){\n            //去掉url的头，并转换为byte\n            var bytes = window.atob(urlData.split(',')[1]);\n            \n            //处理异常,将ascii码小于0的转换为大于0\n            var ab = new ArrayBuffer(bytes.length);\n            var ia = new Uint8Array(ab);\n            var i;\n            for (i = 0; i < bytes.length; i++) {\n                ia[i] = bytes.charCodeAt(i);\n            }\n\n            return new Blob([ab], {type : filetype});\n        }\n\n        // -------- 插入图片的方法 --------\n        function insertImg(src, event) {\n            var img = document.createElement('img');\n            img.onload = function () {\n                var html = '<img src=\"' + src + '\" style=\"max-width:100%;\"/>';\n                editor.command(event, 'insertHtml', html);\n\n                E.log('已插入图片，地址 ' + src);\n                img = null;\n            };\n            img.onerror = function () {\n                E.error('使用返回的结果获取图片，发生错误。请确认以下结果是否正确：' + src);\n                img = null;\n            };\n            img.src = src;\n        }\n\n        // -------- onprogress 事件 --------\n        function updateProgress(e) {\n            if (e.lengthComputable) {\n                var percentComplete = e.loaded / e.total;\n                editor.showUploadProgress(percentComplete * 100);\n            }\n        }\n\n        // -------- xhr 上传图片 --------\n        editor.xhrUploadImg = function (opt) {\n            // opt 数据\n            var event = opt.event;\n            var fileName = opt.filename || '';\n            var base64 = opt.base64;\n            var fileType = opt.fileType || 'image/png'; // 无扩展名则默认使用 png\n            var name = opt.name || 'wangEditor_upload_file';\n            var loadfn = opt.loadfn || onload;\n            var errorfn = opt.errorfn || onerror;\n            var timeoutfn = opt.timeoutfn || ontimeout;\n\n            // 上传参数（如 token）\n            var params = editor.config.uploadParams || {};\n\n            // headers\n            var headers = editor.config.uploadHeaders || {};\n\n            // 获取文件扩展名\n            var fileExt = 'png';  // 默认为 png\n            if (fileName.indexOf('.') > 0) {\n                // 原来的文件名有扩展名\n                fileExt = fileName.slice(fileName.lastIndexOf('.') - fileName.length + 1);\n            } else if (fileType.indexOf('/') > 0 && fileType.split('/')[1]) {\n                // 文件名没有扩展名，通过类型获取，如从 'image/png' 取 'png'\n                fileExt = fileType.split('/')[1];\n            }\n\n            // ------------ begin 预览模拟上传 ------------\n            if (E.isOnWebsite) {\n                E.log('预览模拟上传');\n                insertImg(base64, event);\n                return;\n            }\n            // ------------ end 预览模拟上传 ------------\n\n            // 变量声明\n            var xhr = new XMLHttpRequest();\n            var timeoutId;\n            var src;\n            var formData = new FormData();\n\n            // 超时处理\n            function timeoutCallback() {\n                if (timeoutId) {\n                    clearTimeout(timeoutId);\n                }\n                if (xhr && xhr.abort) {\n                    xhr.abort();\n                }\n\n                // 超时了就阻止默认行为\n                event.preventDefault();\n\n                // 执行回调函数，提示什么内容，都应该在回调函数中定义\n                timeoutfn && timeoutfn.call(editor, xhr);\n\n                // 隐藏进度条\n                editor.hideUploadProgress();\n            }\n\n            xhr.onload = function () {\n                if (timeoutId) {\n                    clearTimeout(timeoutId);\n                }\n\n                // 记录文件名到 editor.uploadImgOriginalName ，插入图片时，可做 alt 属性用\n                editor.uploadImgOriginalName = fileName;\n                if (fileName.indexOf('.') > 0) {\n                    editor.uploadImgOriginalName = fileName.split('.')[0];\n                }\n\n                // 执行load函数，任何操作，都应该在load函数中定义\n                loadfn && loadfn.call(editor, xhr.responseText, xhr);\n\n                // 隐藏进度条\n                editor.hideUploadProgress();\n            };\n            xhr.onerror = function () {\n                if (timeoutId) {\n                    clearTimeout(timeoutId);\n                }\n\n                // 超时了就阻止默认行为\n                event.preventDefault();\n\n                // 执行error函数，错误提示，应该在error函数中定义\n                errorfn && errorfn.call(editor, xhr);\n\n                // 隐藏进度条\n                editor.hideUploadProgress();\n            };\n            // xhr.onprogress = updateProgress;\n            xhr.upload.onprogress = updateProgress;\n\n            // 填充数据\n            formData.append(name, convertBase64UrlToBlob(base64, fileType), E.random() + '.' + fileExt);\n\n            // 添加参数\n            $.each(params, function (key, value) {\n                formData.append(key, value);\n            });\n\n            // 开始上传\n            xhr.open('POST', uploadImgUrl, true);\n            // xhr.setRequestHeader(\"Content-type\",\"application/x-www-form-urlencoded\");  // 将参数解析成传统form的方式上传\n\n            // 修改自定义配置的headers\n            $.each(headers, function (key, value) {\n                xhr.setRequestHeader(key, value);\n            });\n\n            // 跨域上传时，传cookie\n            xhr.withCredentials = true;\n\n            // 发送数据\n            xhr.send(formData);\n            timeoutId = setTimeout(timeoutCallback, uploadTimeout);\n\n            E.log('开始上传...并开始超时计算');\n        };\n    });\n});\n// 进度条\n_e(function (E, $) {\n\n    E.plugin(function () {\n\n        var editor = this;\n        var menuContainer = editor.menuContainer;\n        var menuHeight = menuContainer.height();\n        var $editorContainer = editor.$editorContainer;\n        var width = $editorContainer.width();\n        var $progress = $('<div class=\"wangEditor-upload-progress\"></div>');\n\n        // 渲染事件\n        var isRender = false;\n        function render() {\n            if (isRender) {\n                return;\n            }\n            isRender = true;\n\n            $progress.css({\n                top: menuHeight + 'px'\n            });\n            $editorContainer.append($progress);\n        }\n\n        // ------ 显示进度 ------\n        editor.showUploadProgress = function (progress) {\n            if (timeoutId) {\n                clearTimeout(timeoutId);\n            }\n\n            // 显示之前，先判断是否渲染\n            render();\n\n            $progress.show();\n            $progress.width(progress * width / 100);\n        };\n\n        // ------ 隐藏进度条 ------\n        var timeoutId;\n        function hideProgress() {\n            $progress.hide();\n            timeoutId = null;\n        }\n        editor.hideUploadProgress = function (time) {\n            if (timeoutId) {\n                clearTimeout(timeoutId);\n            }\n            time = time || 750;\n            timeoutId = setTimeout(hideProgress, time);\n        };\n    });\n});\n// upload img 插件\n_e(function (E, $) {\n\n    E.plugin(function () {\n        var editor = this;\n        var config = editor.config;\n        var uploadImgUrl = config.uploadImgUrl;\n        var uploadTimeout = config.uploadTimeout;\n        var event;\n\n        if (!uploadImgUrl) {\n            return;\n        }\n\n        // 获取editor的上传dom\n        var $uploadContent = editor.$uploadContent;\n        if (!$uploadContent) {\n            return;\n        }\n\n        // 自定义UI，并添加到上传dom节点上\n        var $uploadIcon = $('<div class=\"upload-icon-container\"><i class=\"wangeditor-menu-img-upload\"></i></div>');\n        $uploadContent.append($uploadIcon);\n\n        // ---------- 构建上传对象 ----------\n        var upfile = new E.UploadFile({\n            editor: editor,\n            uploadUrl: uploadImgUrl,\n            timeout: uploadTimeout,\n            fileAccept: 'image/jpg,image/jpeg,image/png,image/gif,image/bmp'    // 只允许选择图片 \n        });\n\n        // 选择本地文件，上传\n        $uploadIcon.click(function (e) {\n            event = e;\n            upfile.selectFiles();\n        });\n    });\n});\n// h5 方式上传图片\n_e(function (E, $) {\n\n    if (!window.FileReader || !window.FormData) {\n        // 如果不支持html5的文档操作，直接返回\n        return;\n    }\n\n    // 构造函数\n    var UploadFile = function (opt) {\n        this.editor = opt.editor;\n        this.uploadUrl = opt.uploadUrl;\n        this.timeout = opt.timeout;\n        this.fileAccept = opt.fileAccept;\n        this.multiple = true;\n    };\n\n    UploadFile.fn = UploadFile.prototype;\n\n    // clear\n    UploadFile.fn.clear = function () {\n        this.$input.val('');\n        E.log('input value 已清空');\n    };\n\n    // 渲染\n    UploadFile.fn.render = function () {\n        var self = this;\n        if (self._hasRender) {\n            // 不要重复渲染\n            return;\n        }\n\n        E.log('渲染dom');\n\n        var fileAccept = self.fileAccept;\n        var acceptTpl = fileAccept ? 'accept=\"' + fileAccept + '\"' : '';\n        var multiple = self.multiple;\n        var multipleTpl = multiple ? 'multiple=\"multiple\"' : '';\n        var $input = $('<input type=\"file\" ' + acceptTpl + ' ' + multipleTpl + '/>');\n        var $container = $('<div style=\"visibility:hidden;\"></div>');\n\n        $container.append($input);\n        E.$body.append($container);\n\n        // onchange 事件\n        $input.on('change', function (e) {\n            self.selected(e, $input.get(0));\n        });\n\n        // 记录对象数据\n        self.$input = $input;\n\n        // 记录\n        self._hasRender = true;\n    };\n\n    // 选择\n    UploadFile.fn.selectFiles = function () {\n        var self = this;\n\n        E.log('使用 html5 方式上传');\n\n        // 先渲染\n        self.render();\n\n        // 选择\n        E.log('选择文件');\n        self.$input.click();\n    };\n\n    // 选中文件之后\n    UploadFile.fn.selected = function (e, input) {\n        var self = this;\n        var files = input.files || [];\n        if (files.length === 0) {\n            return;\n        }\n\n        E.log('选中 ' + files.length + ' 个文件');\n\n        // 遍历选中的文件，预览、上传\n        $.each(files, function (key, value) {\n            self.upload(value);\n        });\n    };\n\n    // 上传单个文件\n    UploadFile.fn.upload = function (file) {\n        var self = this;\n        var editor = self.editor;\n        var filename = file.name || '';\n        var fileType = file.type || '';\n        var uploadImgFns = editor.config.uploadImgFns;\n        var uploadFileName = editor.config.uploadImgFileName || 'wangEditorH5File';\n        var onload = uploadImgFns.onload;\n        var ontimeout = uploadImgFns.ontimeout;\n        var onerror = uploadImgFns.onerror;\n        var reader = new FileReader();\n\n        if (!onload || !ontimeout || !onerror) {\n            E.error('请为编辑器配置上传图片的 onload ontimeout onerror 回调事件');\n            return;\n        }\n\n\n        E.log('开始执行 ' + filename + ' 文件的上传');\n\n        // 清空 input 数据\n        function clearInput() {\n            self.clear();\n        }\n\n        // onload事件\n        reader.onload = function (e) {\n            E.log('已读取' + filename + '文件');\n\n            var base64 = e.target.result || this.result;\n            editor.xhrUploadImg({\n                event: e,\n                filename: filename,\n                base64: base64,\n                fileType: fileType,\n                name: uploadFileName,\n                loadfn: function (resultText, xhr) {\n                    clearInput();\n                    // 执行配置中的方法\n                    var editor = this;\n                    onload.call(editor, resultText, xhr);\n                },\n                errorfn: function (xhr) {\n                    clearInput();\n                    if (E.isOnWebsite) {\n                        alert('wangEditor官网暂时没有服务端，因此报错。实际项目中不会发生');\n                    }\n                    // 执行配置中的方法\n                    var editor = this;\n                    onerror.call(editor, xhr);\n                },\n                timeoutfn: function (xhr) {\n                    clearInput();\n                    if (E.isOnWebsite) {\n                        alert('wangEditor官网暂时没有服务端，因此超时。实际项目中不会发生');\n                    }\n                    // 执行配置中的方法\n                    var editor = this;\n                    ontimeout(editor, xhr);\n                }\n            });\n        };\n\n        // 开始取文件\n        reader.readAsDataURL(file);\n    };\n\n    // 暴露给 E\n    E.UploadFile = UploadFile;\n\n});\n// form方式上传图片\n_e(function (E, $) {\n\n    if (window.FileReader && window.FormData) {\n        // 如果支持 html5 上传，则返回\n        return;\n    }\n    \n    // 构造函数\n    var UploadFile = function (opt) {\n        this.editor = opt.editor;\n        this.uploadUrl = opt.uploadUrl;\n        this.timeout = opt.timeout;\n        this.fileAccept = opt.fileAccept;\n        this.multiple = false;\n    };\n\n    UploadFile.fn = UploadFile.prototype;\n\n    // clear\n    UploadFile.fn.clear = function () {\n        this.$input.val('');\n        E.log('input value 已清空');\n    };\n\n    // 隐藏modal\n    UploadFile.fn.hideModal = function () {\n        this.modal.hide();\n    };\n\n    // 渲染\n    UploadFile.fn.render = function () {\n        var self = this;\n        var editor = self.editor;\n        var uploadFileName = editor.config.uploadImgFileName || 'wangEditorFormFile';\n        if (self._hasRender) {\n            // 不要重复渲染\n            return;\n        }\n\n        // 服务器端路径\n        var uploadUrl = self.uploadUrl;\n\n        E.log('渲染dom');\n\n        // 创建 form 和 iframe\n        var iframeId = 'iframe' + E.random();\n        var $iframe = $('<iframe name=\"' + iframeId + '\" id=\"' + iframeId + '\" frameborder=\"0\" width=\"0\" height=\"0\"></iframe>');\n        var multiple = self.multiple;\n        var multipleTpl = multiple ? 'multiple=\"multiple\"' : '';\n        var $p = $('<p>选择图片并上传</p>');\n        var $input = $('<input type=\"file\" ' + multipleTpl + ' name=\"' + uploadFileName + '\"/>');\n        var $btn = $('<input type=\"submit\" value=\"上传\"/>');\n        var $form = $('<form enctype=\"multipart/form-data\" method=\"post\" action=\"' + uploadUrl + '\" target=\"' + iframeId + '\"></form>');\n        var $container = $('<div style=\"margin:10px 20px;\"></div>');\n\n        $form.append($p).append($input).append($btn);\n\n        // 增加用户配置的参数，如 token\n        $.each(editor.config.uploadParams, function (key, value) {\n            $form.append( $('<input type=\"hidden\" name=\"' + key + '\" value=\"' + value + '\"/>') );\n        });\n\n        $container.append($form);\n        $container.append($iframe);\n\n        self.$input = $input;\n        self.$iframe = $iframe;\n\n        // 生成 modal\n        var modal = new E.Modal(editor, undefined, {\n            $content: $container\n        });\n        self.modal = modal;\n\n        // 记录\n        self._hasRender = true;\n    };\n\n    // 绑定 iframe load 事件\n    UploadFile.fn.bindLoadEvent = function () {\n        var self = this;\n        if (self._hasBindLoad) {\n            // 不要重复绑定\n            return;\n        }\n\n        var editor = self.editor;\n        var $iframe = self.$iframe;\n        var iframe = $iframe.get(0);\n        var iframeWindow = iframe.contentWindow;\n        var onload = editor.config.uploadImgFns.onload;\n\n        // 定义load事件\n        function onloadFn() {\n            var resultText = $.trim(iframeWindow.document.body.innerHTML);\n            if (!resultText) {\n                return;\n            }\n\n            // 获取文件名\n            var fileFullName = self.$input.val();  // 结果如 C:\\folder\\abc.png 格式\n            var fileOriginalName = fileFullName;\n            if (fileFullName.lastIndexOf('\\\\') >= 0) {\n                // 获取 abc.png 格式\n                fileOriginalName = fileFullName.slice(fileFullName.lastIndexOf('\\\\') + 1);\n                if (fileOriginalName.indexOf('.') > 0) {\n                    // 获取 abc （即不带扩展名的文件名）\n                    fileOriginalName = fileOriginalName.split('.')[0];\n                }\n            }\n\n            // 将文件名暂存到 editor.uploadImgOriginalName ，插入图片时，可作为 alt 属性来用\n            editor.uploadImgOriginalName = fileOriginalName;\n\n            // 执行load函数，插入图片的操作，应该在load函数中执行\n            onload.call(editor, resultText);\n\n            // 清空 input 数据\n            self.clear();\n\n            // 隐藏modal\n            self.hideModal();\n        }\n\n        // 绑定 load 事件\n        if (iframe.attachEvent) {\n            iframe.attachEvent('onload', onloadFn);\n        } else {\n            iframe.onload = onloadFn;\n        }\n\n        // 记录\n        self._hasBindLoad = true;\n    };\n\n    UploadFile.fn.show = function () {\n        var self = this;\n        var modal = self.modal;\n\n        function show() {\n            modal.show();\n            self.bindLoadEvent();\n        }\n        setTimeout(show);\n    };\n\n    // 选择\n    UploadFile.fn.selectFiles = function () {\n        var self = this;\n\n        E.log('使用 form 方式上传');\n\n        // 先渲染\n        self.render();\n\n        // 先清空\n        self.clear();\n\n        // 显示\n        self.show();\n    };\n\n    // 暴露给 E\n    E.UploadFile = UploadFile;\n\n});\n// upload img 插件 粘贴图片\n_e(function (E, $) {\n    \n    E.plugin(function () {\n        var editor = this;\n        var txt = editor.txt;\n        var $txt = txt.$txt;\n        var config = editor.config;\n        var uploadImgUrl = config.uploadImgUrl;\n        var uploadFileName = config.uploadImgFileName || 'wangEditorPasteFile';\n        var pasteEvent;\n        var $imgsBeforePaste;\n\n        // 未配置上传图片url，则忽略\n        if (!uploadImgUrl) {\n            return;\n        }\n\n        // -------- 非 chrome 下，通过查找粘贴的图片的方式上传 --------\n        function findPasteImgAndUpload() {\n            var reg = /^data:(image\\/\\w+);base64/;\n            var $imgs = $txt.find('img');\n\n            E.log('粘贴后，检查到编辑器有' + $imgs.length + '个图片。开始遍历图片，试图找到刚刚粘贴过来的图片');\n\n            $.each($imgs, function () {\n                var img = this;\n                var $img = $(img);\n                var flag;\n                var base64 = $img.attr('src');\n                var type;\n\n                // 判断当前图片是否是粘贴之前的\n                $imgsBeforePaste.each(function () {\n                    if (img === this) {\n                        // 当前图片是粘贴之前的\n                        flag = true;\n                        return false;\n                    }\n                });\n\n                // 当前图片是粘贴之前的，则忽略\n                if (flag) {\n                    return;\n                }\n\n                E.log('找到一个粘贴过来的图片');\n\n                if (reg.test(base64)) {\n                    // 得到的粘贴的图片是 base64 格式，符合要求\n                    E.log('src 是 base64 格式，可以上传');\n                    type = base64.match(reg)[1];\n                    editor.xhrUploadImg({\n                        event: pasteEvent,\n                        base64: base64,\n                        fileType: type,\n                        name: uploadFileName\n                    });\n                } else {\n                    E.log('src 为 ' + base64 + ' ，不是 base64 格式，暂时不支持上传');\n                }\n\n                // 最终移除原图片\n                $img.remove();\n            });\n\n            E.log('遍历结束');\n        }\n\n        // 开始监控粘贴事件\n        $txt.on('paste', function (e) {\n            pasteEvent = e;\n            var data = pasteEvent.clipboardData || pasteEvent.originalEvent.clipboardData;\n            var text;\n            var items;\n\n            // -------- 试图获取剪切板中的文字，有文字的情况下，就不处理图片粘贴 --------\n            if (data == null) {\n                text = window.clipboardData && window.clipboardData.getData('text');\n            } else {\n                text = data.getData('text/plain') || data.getData('text/html');\n            }\n            if (text) {\n                return;\n            }\n\n            items = data && data.items;\n            if (items) {\n                // -------- chrome 可以用 data.items 取出图片 -----\n                E.log('通过 data.items 得到了数据');\n\n                $.each(items, function (key, value) {\n                    var fileType = value.type || '';\n                    if(fileType.indexOf('image') < 0) {\n                        // 不是图片\n                        return;\n                    }\n\n                    var file = value.getAsFile();\n                    var reader = new FileReader();\n\n                    E.log('得到一个粘贴图片');\n\n                    reader.onload = function (e) {\n                        E.log('读取到粘贴的图片');\n\n                        // 执行上传\n                        var base64 = e.target.result || this.result;\n                        editor.xhrUploadImg({\n                            event: pasteEvent,\n                            base64: base64,\n                            fileType: fileType,\n                            name: uploadFileName\n                        });\n                    };\n\n                    //读取粘贴的文件\n                    reader.readAsDataURL(file);\n                });\n            } else {\n                // -------- 非 chrome 不能用 data.items 取图片 -----\n\n                E.log('未从 data.items 得到数据，使用检测粘贴图片的方式');\n\n                // 获取\n                $imgsBeforePaste = $txt.find('img');\n                E.log('粘贴前，检查到编辑器有' + $imgsBeforePaste.length + '个图片');\n\n                // 异步上传找到的图片\n                setTimeout(findPasteImgAndUpload, 0);\n            }\n        });\n\n    });\n});\n// 拖拽上传图片 插件 \n_e(function (E, $) {\n\n    E.plugin(function () {\n\n        var editor = this;\n        var txt = editor.txt;\n        var $txt = txt.$txt;\n        var config = editor.config;\n        var uploadImgUrl = config.uploadImgUrl;\n        var uploadFileName = config.uploadImgFileName || 'wangEditorDragFile';\n\n        // 未配置上传图片url，则忽略\n        if (!uploadImgUrl) {\n            return;\n        }\n\n        // 阻止浏览器默认行为\n        E.$document.on('dragleave drop dragenter dragover', function (e) {\n            e.preventDefault();\n        });\n\n        // 监控 $txt drop 事件\n        $txt.on('drop', function (dragEvent) {\n            dragEvent.preventDefault();\n\n            var originalEvent = dragEvent.originalEvent;\n            var files = originalEvent.dataTransfer && originalEvent.dataTransfer.files;\n\n            if (!files || !files.length) {\n                return;\n            }\n\n            $.each(files, function (k, file) {\n                var type = file.type;\n                var name = file.name;\n\n                if (type.indexOf('image/') < 0) {\n                    // 只接收图片\n                    return;\n                }\n\n                E.log('得到图片 ' + name);\n\n                var reader = new FileReader();\n                reader.onload = function (e) {\n                    E.log('读取到图片 ' + name);\n\n                    // 执行上传\n                    var base64 = e.target.result || this.result;\n                    editor.xhrUploadImg({\n                        event: dragEvent,\n                        base64: base64,\n                        fileType: type,\n                        name: uploadFileName\n                    });\n                };\n\n                //读取粘贴的文件\n                reader.readAsDataURL(file);\n\n            });\n        });\n    });\n\n});\n// 编辑器区域 table toolbar\n_e(function (E, $) {\n\n    E.plugin(function () {\n        var editor = this;\n        var txt = editor.txt;\n        var $txt = txt.$txt;\n        var html = '';\n        // 说明：设置了 max-height 之后，$txt.parent() 负责滚动处理\n        var $currentTxt = editor.useMaxHeight ? $txt.parent() : $txt;\n        var $currentTable;\n\n        // 用到的dom节点\n        var isRendered = false;\n        var $toolbar = $('<div class=\"txt-toolbar\"></div>');\n        var $triangle = $('<div class=\"tip-triangle\"></div>');\n        var $delete = $('<a href=\"#\"><i class=\"wangeditor-menu-img-trash-o\"></i></a>');\n        var $zoomSmall = $('<a href=\"#\"><i class=\"wangeditor-menu-img-search-minus\"></i></a>');\n        var $zoomBig = $('<a href=\"#\"><i class=\"wangeditor-menu-img-search-plus\"></i></a>');\n\n        // 渲染到页面\n        function render() {\n            if (isRendered) {\n                return;\n            }\n            \n            // 绑定事件\n            bindEvent();\n\n            // 拼接 渲染到页面上\n            $toolbar.append($triangle)\n                    .append($delete)\n                    .append($zoomSmall)\n                    .append($zoomBig);\n            editor.$editorContainer.append($toolbar);\n            isRendered = true;\n        }\n\n        // 绑定事件\n        function bindEvent() {\n            // 统一执行命令的方法\n            var commandFn;\n            function command(e, callback) {\n                // 执行命令之前，先存储html内容\n                html = $txt.html();\n                // 监控内容变化\n                var cb = function  () {\n                    if (callback) {\n                        callback();\n                    }\n                    if (html !== $txt.html()) {\n                        $txt.change();\n                    }\n                };\n                // 执行命令\n                if (commandFn) {\n                    editor.customCommand(e, commandFn, cb);\n                }\n            }\n\n            // 删除\n            $delete.click(function (e) {\n                commandFn = function () {\n                    $currentTable.remove();\n                };\n                command(e, function () {\n                    setTimeout(hide, 100);\n                });\n            });\n\n            // 放大\n            $zoomBig.click(function (e) {\n                commandFn = function () {\n                    $currentTable.css({\n                        width: '100%'\n                    });\n                };\n                command(e, function () {\n                    setTimeout(show);\n                });\n            });\n\n            // 缩小\n            $zoomSmall.click(function (e) {\n                commandFn = function () {\n                    $currentTable.css({\n                        width: 'auto'\n                    });\n                };\n                command(e, function () {\n                    setTimeout(show);\n                });\n            });\n        }\n\n        // 显示 toolbar\n        function show() {\n            if (editor._disabled) {\n                // 编辑器已经被禁用，则不让显示\n                return;\n            }\n            if ($currentTable == null) {\n                return;\n            }\n            $currentTable.addClass('clicked');\n            var tablePosition = $currentTable.position();\n            var tableTop = tablePosition.top;\n            var tableLeft = tablePosition.left;\n            var tableHeight = $currentTable.outerHeight();\n            var tableWidth = $currentTable.outerWidth();\n\n            // --- 定位 toolbar ---\n\n            // 计算初步结果\n            var top = tableTop + tableHeight;\n            var left = tableLeft;\n            var marginLeft = 0;\n\n            var txtTop = $currentTxt.position().top;\n            var txtHeight = $currentTxt.outerHeight();\n            if (top > (txtTop + txtHeight)) {\n                // top 不得超出编辑范围\n                top = txtTop + txtHeight;\n            }\n\n            // 显示（方便计算 margin）\n            $toolbar.show();\n\n            // 计算 margin\n            var width = $toolbar.outerWidth();\n            marginLeft = tableWidth / 2 - width / 2;\n\n            // 定位\n            $toolbar.css({\n                top: top + 5,\n                left: left,\n                'margin-left': marginLeft\n            });\n            // 如果定位太靠左了\n            if (marginLeft < 0) {\n                // 得到三角形的margin-left\n                $toolbar.css('margin-left', '0');\n                $triangle.hide();\n            } else {\n                $triangle.show();\n            }\n        }\n        \n        // 隐藏 toolbar\n        function hide() {\n            if ($currentTable == null) {\n                return;\n            }\n            $currentTable.removeClass('clicked');\n            $currentTable = null;\n            $toolbar.hide();\n        }\n\n        // click table 事件\n        $currentTxt.on('click', 'table', function (e) {\n            var $table = $(e.currentTarget);\n\n            // 渲染\n            render();\n\n            if ($currentTable && ($currentTable.get(0) === $table.get(0))) {\n                setTimeout(hide, 100);\n                return;\n            }\n\n            // 显示 toolbar\n            $currentTable = $table;\n            show();\n\n            // 阻止冒泡\n            e.preventDefault();\n            e.stopPropagation();\n            \n        }).on('click keydown scroll', function (e) {\n            setTimeout(hide, 100);\n        });\n        E.$body.on('click keydown scroll', function (e) {\n            setTimeout(hide, 100);\n        });\n    });\n\n});\n// 编辑器区域 img toolbar\n_e(function (E, $) {\n\n    if (E.userAgent.indexOf('MSIE 8') > 0) {\n        return;\n    }\n    \n    E.plugin(function () {\n        var editor = this;\n        var lang = editor.config.lang;\n        var txt = editor.txt;\n        var $txt = txt.$txt;\n        var html = '';\n        // 说明：设置了 max-height 之后，$txt.parent() 负责滚动处理\n        var $currentTxt = editor.useMaxHeight ? $txt.parent() : $txt;\n        var $editorContainer = editor.$editorContainer;\n        var $currentImg;\n        var currentLink = '';\n\n        // 用到的dom节点\n        var isRendered = false;\n        var $dragPoint = $('<div class=\"img-drag-point\"></div>');\n\n        var $toolbar = $('<div class=\"txt-toolbar\"></div>');\n        var $triangle = $('<div class=\"tip-triangle\"></div>');\n\n        var $menuContainer = $('<div></div>');\n        var $delete = $('<a href=\"#\"><i class=\"wangeditor-menu-img-trash-o\"></i></a>');\n        var $zoomSmall = $('<a href=\"#\"><i class=\"wangeditor-menu-img-search-minus\"></i></a>');\n        var $zoomBig = $('<a href=\"#\"><i class=\"wangeditor-menu-img-search-plus\"></i></a>');\n        // var $floatLeft = $('<a href=\"#\"><i class=\"wangeditor-menu-img-align-left\"></i></a>');\n        // var $noFloat = $('<a href=\"#\"><i class=\"wangeditor-menu-img-align-justify\"></i></a>');\n        // var $floatRight = $('<a href=\"#\"><i class=\"wangeditor-menu-img-align-right\"></i></a>');\n        var $alignLeft = $('<a href=\"#\"><i class=\"wangeditor-menu-img-align-left\"></i></a>');\n        var $alignCenter = $('<a href=\"#\"><i class=\"wangeditor-menu-img-align-center\"></i></a>');\n        var $alignRight = $('<a href=\"#\"><i class=\"wangeditor-menu-img-align-right\"></i></a>');\n        var $link = $('<a href=\"#\"><i class=\"wangeditor-menu-img-link\"></i></a>');\n        var $unLink = $('<a href=\"#\"><i class=\"wangeditor-menu-img-unlink\"></i></a>');\n\n        var $linkInputContainer = $('<div style=\"display:none;\"></div>');\n        var $linkInput = $('<input type=\"text\" style=\"height:26px; margin-left:10px; width:200px;\"/>');\n        var $linkBtnSubmit = $('<button class=\"right\">' + lang.submit + '</button>');\n        var $linkBtnCancel = $('<button class=\"right gray\">' + lang.cancel + '</button>');\n\n        // 记录是否正在拖拽\n        var isOnDrag = false;\n\n        // 获取 / 设置 链接\n        function imgLink(e, url) {\n            if (!$currentImg) {\n                return;\n            }\n            var commandFn;\n            var callback = function () {\n                // 及时保存currentLink\n                if (url != null) {\n                    currentLink = url;\n                }\n                if (html !== $txt.html()) {\n                    $txt.change();\n                }\n            };\n            var $link;\n            var inLink = false;\n            var $parent = $currentImg.parent();\n            if ($parent.get(0).nodeName.toLowerCase() === 'a') {\n                // 父元素就是图片链接\n                $link = $parent;\n                inLink = true;\n            } else {\n                // 父元素不是图片链接，则重新创建一个链接\n                $link = $('<a target=\"_blank\"></a>');\n            }\n\n            if (url == null) {\n                // url 无值，是获取链接\n                return $link.attr('href') || '';\n            } else if (url === '') {\n                // url 是空字符串，是取消链接\n                if (inLink) {\n                    commandFn = function () {\n                        $currentImg.unwrap();\n                    };\n                }\n            } else {\n                // url 有值，是设置链接\n                if (url === currentLink) {\n                    return;\n                }\n                commandFn = function () {\n                    $link.attr('href', url);\n\n                    if (!inLink) {\n                        // 当前图片未包含在链接中，则包含进来\n                        $currentImg.wrap($link);\n                    }\n                };\n            }\n\n            // 执行命令\n            if (commandFn) {\n                // 记录下执行命令之前的html内容\n                html = $txt.html();\n                // 执行命令\n                editor.customCommand(e, commandFn, callback);\n            }\n        }\n\n        // 渲染到页面\n        function render() {\n            if (isRendered) {\n                return;\n            }\n            \n            // 绑定事件\n            bindToolbarEvent();\n            bindDragEvent();\n\n            // 菜单放入 container\n            $menuContainer.append($delete)\n                            .append($zoomSmall)\n                            .append($zoomBig)\n                            // .append($floatLeft)\n                            // .append($noFloat)\n                            // .append($floatRight);\n                            .append($alignLeft)\n                            .append($alignCenter)\n                            .append($alignRight)\n                            .append($link)\n                            .append($unLink);\n\n            // 链接input放入container\n            $linkInputContainer.append($linkInput)\n                               .append($linkBtnCancel)\n                               .append($linkBtnSubmit);\n\n            // 拼接 渲染到页面上\n            $toolbar.append($triangle)\n                    .append($menuContainer)\n                    .append($linkInputContainer);\n                    \n            editor.$editorContainer.append($toolbar).append($dragPoint);\n            isRendered = true;\n        }\n\n        // 绑定toolbar事件\n        function bindToolbarEvent() {\n            // 统一执行命令的方法\n            var commandFn;\n            function customCommand(e, callback) {\n                var cb;\n                // 记录下执行命令之前的html内容\n                html = $txt.html();\n                cb = function () {\n                    if (callback) {\n                        callback();\n                    }\n                    if (html !== $txt.html()) {\n                        $txt.change();\n                    }\n                };\n                // 执行命令\n                if (commandFn) {\n                    editor.customCommand(e, commandFn, cb);\n                }\n            }\n\n            // 删除\n            $delete.click(function (e) {\n                // 删除之前先unlink\n                imgLink(e, '');\n\n                // 删除图片\n                commandFn = function () {\n                    $currentImg.remove();\n                };\n                customCommand(e, function () {\n                    setTimeout(hide, 100);\n                });\n            });\n\n            // 放大\n            $zoomBig.click(function (e) {\n                commandFn = function () {\n                    var img = $currentImg.get(0);\n                    var width = img.width;\n                    var height = img.height;\n                    width = width * 1.1;\n                    height = height * 1.1;\n\n                    $currentImg.css({\n                        width: width + 'px',\n                        height: height + 'px'\n                    });\n                };\n                customCommand(e, function () {\n                    setTimeout(show);\n                });\n            });\n\n            // 缩小\n            $zoomSmall.click(function (e) {\n                commandFn = function () {\n                    var img = $currentImg.get(0);\n                    var width = img.width;\n                    var height = img.height;\n                    width = width * 0.9;\n                    height = height * 0.9;\n\n                    $currentImg.css({\n                        width: width + 'px',\n                        height: height + 'px'\n                    });\n                };\n                customCommand(e, function () {\n                    setTimeout(show);\n                });\n            });\n\n            // // 左浮动\n            // $floatLeft.click(function (e) {\n            //     commandFn = function () {\n            //         $currentImg.css({\n            //             float: 'left'\n            //         });\n            //     };\n            //     customCommand(e, function () {\n            //         setTimeout(hide, 100);\n            //     });\n            // });\n\n            // alignLeft\n            $alignLeft.click(function (e) {\n                commandFn = function () {\n                    // 如果 img 增加了链接，那么 img.parent() 就是 a 标签，设置 align 没用的，因此必须找到 P 父节点来设置 align\n                    $currentImg.parents('p').css({\n                        'text-align': 'left'\n                    }).attr('align', 'left');\n                };\n                customCommand(e, function () {\n                    setTimeout(hide, 100);\n                });\n            });\n\n            // // 右浮动\n            // $floatRight.click(function (e) {\n            //     commandFn = function () {\n            //         $currentImg.css({\n            //             float: 'right'\n            //         });\n            //     };\n            //     customCommand(e, function () {\n            //         setTimeout(hide, 100);\n            //     });\n            // });\n\n            // alignRight\n            $alignRight.click(function (e) {\n                commandFn = function () {\n                    // 如果 img 增加了链接，那么 img.parent() 就是 a 标签，设置 align 没用的，因此必须找到 P 父节点来设置 align\n                    $currentImg.parents('p').css({\n                        'text-align': 'right'\n                    }).attr('align', 'right');\n                };\n                customCommand(e, function () {\n                    setTimeout(hide, 100);\n                });\n            });\n\n            // // 无浮动\n            // $noFloat.click(function (e) {\n            //     commandFn = function () {\n            //         $currentImg.css({\n            //             float: 'none'\n            //         });\n            //     };\n            //     customCommand(e, function () {\n            //         setTimeout(hide, 100);\n            //     });\n            // });\n\n            // alignCenter\n            $alignCenter.click(function (e) {\n                commandFn = function () {\n                    // 如果 img 增加了链接，那么 img.parent() 就是 a 标签，设置 align 没用的，因此必须找到 P 父节点来设置 align\n                    $currentImg.parents('p').css({\n                        'text-align': 'center'\n                    }).attr('align', 'center');\n                };\n                customCommand(e, function () {\n                    setTimeout(hide, 100);\n                });\n            });\n\n            // link\n            // 显示链接input\n            $link.click(function (e) {\n                e.preventDefault();\n\n                // 获取当前链接，并显示\n                currentLink = imgLink(e);\n                $linkInput.val(currentLink);\n\n                $menuContainer.hide();\n                $linkInputContainer.show();\n            });\n            // 设置链接\n            $linkBtnSubmit.click(function (e) {\n                e.preventDefault();\n\n                var url = $.trim($linkInput.val());\n                if (url) {\n                    // 设置链接，同时会自动更新 currentLink 的值\n                    imgLink(e, url);\n                }\n\n                // 隐藏 toolbar\n                setTimeout(hide);\n            });\n            // 取消设置链接\n            $linkBtnCancel.click(function (e) {\n                e.preventDefault();\n\n                // 重置链接 input\n                $linkInput.val(currentLink);\n\n                $menuContainer.show();\n                $linkInputContainer.hide();\n            });\n\n            // unlink\n            $unLink.click(function (e) {\n                e.preventDefault();\n\n                // 执行 unlink\n                imgLink(e, '');\n\n                // 隐藏 toolbar\n                setTimeout(hide);\n            });\n        }\n\n        // 绑定drag事件\n        function bindDragEvent() {\n            var _x, _y;\n            var dragMarginLeft, dragMarginTop;\n            var imgWidth, imgHeight;\n\n            function mousemove (e) {\n                var diffX, diffY;\n\n                // 计算差额\n                diffX = e.pageX - _x;\n                diffY = e.pageY - _y;\n\n                // --------- 计算拖拽点的位置 ---------\n                var currentDragMarginLeft = dragMarginLeft + diffX;\n                var currentDragMarginTop = dragMarginTop + diffY;\n                $dragPoint.css({\n                    'margin-left': currentDragMarginLeft,\n                    'margin-top': currentDragMarginTop\n                });\n\n                // --------- 计算图片的大小 ---------\n                var currentImgWidth = imgWidth + diffX;\n                var currentImggHeight = imgHeight + diffY;\n                $currentImg && $currentImg.css({\n                    width: currentImgWidth,\n                    height: currentImggHeight\n                });\n            }\n\n            $dragPoint.on('mousedown', function(e){\n                if (!$currentImg) {\n                    return;\n                }\n                // 当前鼠标位置\n                _x = e.pageX;\n                _y = e.pageY;\n\n                // 当前拖拽点的位置\n                dragMarginLeft = parseFloat($dragPoint.css('margin-left'), 10);\n                dragMarginTop = parseFloat($dragPoint.css('margin-top'), 10);\n\n                // 当前图片的大小\n                imgWidth = $currentImg.width();\n                imgHeight = $currentImg.height();\n\n                // 隐藏 $toolbar\n                $toolbar.hide();\n\n                // 绑定计算事件\n                E.$document.on('mousemove._dragResizeImg', mousemove);\n                E.$document.on('mouseup._dragResizeImg', function (e) {\n                    // 取消绑定\n                    E.$document.off('mousemove._dragResizeImg');\n                    E.$document.off('mouseup._dragResizeImg');\n\n                    // 隐藏，并还原拖拽点的位置\n                    hide();\n                    $dragPoint.css({\n                        'margin-left': dragMarginLeft,\n                        'margin-top': dragMarginTop\n                    });\n\n                    // 记录\n                    isOnDrag = false;\n                });\n\n                // 记录\n                isOnDrag = true;\n            });\n        }\n\n        // 显示 toolbar\n        function show() {\n            if (editor._disabled) {\n                // 编辑器已经被禁用，则不让显示\n                return;\n            }\n            if ($currentImg == null) {\n                return;\n            }\n            $currentImg.addClass('clicked');\n            var imgPosition = $currentImg.position();\n            var imgTop = imgPosition.top;\n            var imgLeft = imgPosition.left;\n            var imgHeight = $currentImg.outerHeight();\n            var imgWidth = $currentImg.outerWidth();\n\n\n            // --- 定位 dragpoint ---\n            $dragPoint.css({\n                top: imgTop + imgHeight,\n                left: imgLeft + imgWidth\n            });\n\n            // --- 定位 toolbar ---\n\n            // 计算初步结果\n            var top = imgTop + imgHeight;\n            var left = imgLeft;\n            var marginLeft = 0;\n\n            var txtTop = $currentTxt.position().top;\n            var txtHeight = $currentTxt.outerHeight();\n            if (top > (txtTop + txtHeight)) {\n                // top 不得超出编辑范围\n                top = txtTop + txtHeight;\n            } else {\n                // top 超出编辑范围，dragPoint就不显示了\n                $dragPoint.show();\n            }\n\n            // 显示（方便计算 margin）\n            $toolbar.show();\n\n            // 计算 margin\n            var width = $toolbar.outerWidth();\n            marginLeft = imgWidth / 2 - width / 2;\n\n            // 定位\n            $toolbar.css({\n                top: top + 5,\n                left: left,\n                'margin-left': marginLeft\n            });\n            // 如果定位太靠左了\n            if (marginLeft < 0) {\n                // 得到三角形的margin-left\n                $toolbar.css('margin-left', '0');\n                $triangle.hide();\n            } else {\n                $triangle.show();\n            }\n\n            // disable 菜单\n            editor.disableMenusExcept();\n        }\n        \n        // 隐藏 toolbar\n        function hide() {\n            if ($currentImg == null) {\n                return;\n            }\n            $currentImg.removeClass('clicked');\n            $currentImg = null;\n\n            $toolbar.hide();\n            $dragPoint.hide();\n\n            // enable 菜单\n            editor.enableMenusExcept();\n        }\n\n        // 判断img是否是一个表情\n        function isEmotion(imgSrc) {\n            var result = false;\n            if (!editor.emotionUrls) {\n                return result;\n            }\n            $.each(editor.emotionUrls, function (index, url) {\n                var flag = false;\n                if (imgSrc === url) {\n                    result = true;\n                    flag = true;\n                }\n                if (flag) {\n                    return false;  // break 循环\n                }\n            });\n            return result;\n        }\n\n        // click img 事件\n        $currentTxt.on('mousedown', 'img', function (e) {\n            e.preventDefault();\n        }).on('click', 'img', function (e) {\n            var $img = $(e.currentTarget);\n            var src = $img.attr('src');\n\n            if (!src || isEmotion(src)) {\n                // 是一个表情图标\n                return;\n            }\n\n            // ---------- 不是表情图标 ---------- \n\n            // 渲染\n            render();\n\n            if ($currentImg && ($currentImg.get(0) === $img.get(0))) {\n                setTimeout(hide, 100);\n                return;\n            }\n\n            // 显示 toolbar\n            $currentImg = $img;\n            show();\n\n            // 默认显示menuContainer，其他默认隐藏\n            $menuContainer.show();\n            $linkInputContainer.hide();\n\n            // 阻止冒泡\n            e.preventDefault();\n            e.stopPropagation();\n            \n        }).on('click keydown scroll', function (e) {\n            if (!isOnDrag) {\n                setTimeout(hide, 100);\n            }\n        });\n\n    });\n\n});\n// 编辑区域 link toolbar\n_e(function (E, $) {\n    E.plugin(function () {\n        var editor = this;\n        var lang = editor.config.lang;\n        var $txt = editor.txt.$txt;\n\n        // 当前命中的链接\n        var $currentLink;\n\n        var $toolbar = $('<div class=\"txt-toolbar\"></div>');\n        var $triangle = $('<div class=\"tip-triangle\"></div>');\n        var $triggerLink = $('<a href=\"#\" target=\"_blank\"><i class=\"wangeditor-menu-img-link\"></i> ' + lang.openLink + '</a>');\n        var isRendered;\n\n        // 记录当前的显示/隐藏状态\n        var isShow = false;\n\n        var showTimeoutId, hideTimeoutId;\n        var showTimeoutIdByToolbar, hideTimeoutIdByToolbar;\n\n        // 渲染 dom\n        function render() {\n            if (isRendered) {\n                return;\n            }\n\n            $toolbar.append($triangle)\n                    .append($triggerLink);\n\n            editor.$editorContainer.append($toolbar);\n\n            isRendered = true;\n        }\n\n        // 定位\n        function setPosition() {\n            if (!$currentLink) {\n                return;\n            }\n\n            var position = $currentLink.position();\n            var left = position.left;\n            var top = position.top;\n            var height = $currentLink.height();\n\n            // 初步计算top值\n            var topResult = top + height + 5;\n\n            // 判断 toolbar 是否超过了编辑器区域的下边界\n            var menuHeight = editor.menuContainer.height();\n            var txtHeight = editor.txt.$txt.outerHeight();\n            if (topResult > menuHeight + txtHeight) {\n                topResult = menuHeight + txtHeight + 5;\n            }\n\n            // 最终设置\n            $toolbar.css({\n                top: topResult,\n                left: left\n            });\n        }\n\n        // 显示 toolbar\n        function show() {\n            if (isShow) {\n                return;\n            }\n\n            if (!$currentLink) {\n                return;\n            }\n\n            render();\n\n            $toolbar.show();\n\n            // 设置链接\n            var href = $currentLink.attr('href');\n            $triggerLink.attr('href', href);\n\n            // 定位\n            setPosition();\n\n            isShow = true;\n        }\n\n        // 隐藏 toolbar\n        function hide() {\n            if (!isShow) {\n                return;\n            }\n\n            if (!$currentLink) {\n                return;\n            }\n\n            $toolbar.hide();\n            isShow = false;\n        }\n\n        // $txt 绑定事件\n        $txt.on('mouseenter', 'a', function (e) {\n            // 延时 500ms 显示toolbar\n            if (showTimeoutId) {\n                clearTimeout(showTimeoutId);\n            }\n            showTimeoutId = setTimeout(function () {\n                var a = e.currentTarget;\n                var $a = $(a);\n                $currentLink = $a;\n\n                var $img = $a.children('img');\n                if ($img.length) {\n                    // 该链接下包含一个图片\n\n                    // 图片点击时，隐藏toolbar\n                    $img.click(function (e) {\n                        hide();\n                    });\n\n                    if ($img.hasClass('clicked')) {\n                        // 图片还处于clicked状态，则不显示toolbar\n                        return;\n                    }\n                }\n\n                // 显示toolbar\n                show();\n            }, 500);\n        }).on('mouseleave', 'a', function (e) {\n            // 延时 500ms 隐藏toolbar\n            if (hideTimeoutId) {\n                clearTimeout(hideTimeoutId);\n            }\n            hideTimeoutId = setTimeout(hide, 500);\n        }).on('click keydown scroll', function (e) {\n            setTimeout(hide, 100);\n        });\n        // $toolbar 绑定事件\n        $toolbar.on('mouseenter', function (e) {\n            // 先中断掉 $txt.mouseleave 导致的隐藏\n            if (hideTimeoutId) {\n                clearTimeout(hideTimeoutId);\n            }\n        }).on('mouseleave', function (e) {\n            // 延时 500ms 显示toolbar\n            if (showTimeoutIdByToolbar) {\n                clearTimeout(showTimeoutIdByToolbar);\n            }\n            showTimeoutIdByToolbar = setTimeout(hide, 500);\n        });\n    });\n});\n// menu吸顶\n_e(function (E, $) {\n\n    E.plugin(function () {\n        var editor = this;\n        var menuFixed = editor.config.menuFixed;\n        if (menuFixed === false || typeof menuFixed !== 'number') {\n            // 没有配置菜单吸顶\n            return;\n        }\n        var bodyMarginTop = parseFloat(E.$body.css('margin-top'), 10);\n        if (isNaN(bodyMarginTop)) {\n            bodyMarginTop = 0;\n        }\n\n        var $editorContainer = editor.$editorContainer;\n        var editorTop = $editorContainer.offset().top;\n        var editorHeight = $editorContainer.outerHeight();\n        \n        var $menuContainer = editor.menuContainer.$menuContainer;\n        var menuCssPosition = $menuContainer.css('position');\n        var menuCssTop = $menuContainer.css('top');\n        var menuTop = $menuContainer.offset().top;\n        var menuHeight = $menuContainer.outerHeight();\n        \n        var $txt = editor.txt.$txt;\n\n        E.$window.scroll(function () {\n            //全屏模式不支持\n            if (editor.isFullScreen) {\n                return;\n            }\n\n            var sTop = E.$window.scrollTop();\n\n            // 需要重新计算宽度，因为浏览器可能此时出现滚动条\n            var menuWidth = $menuContainer.width();\n\n            // 如果 menuTop === 0 说明此前编辑器一直隐藏，后来显示出来了，要重新计算相关数据\n            if (menuTop === 0) {\n                menuTop = $menuContainer.offset().top;\n                editorTop = $editorContainer.offset().top;\n                editorHeight = $editorContainer.outerHeight();\n                menuHeight = $menuContainer.outerHeight();\n            }\n\n            if (sTop >= menuTop && sTop + menuFixed + menuHeight + 30 < editorTop + editorHeight) {\n                // 吸顶\n                $menuContainer.css({\n                    position: 'fixed',\n                    top: menuFixed\n                });\n\n                // 固定宽度\n                $menuContainer.width(menuWidth);\n\n                // 增加body margin-top\n                E.$body.css({\n                    'margin-top': bodyMarginTop + menuHeight\n                });\n\n                // 记录\n                if (!editor._isMenufixed) {\n                    editor._isMenufixed = true;\n                }\n            } else {\n                // 取消吸顶\n                $menuContainer.css({\n                    position: menuCssPosition,\n                    top: menuCssTop\n                });\n\n                // 取消宽度固定\n                $menuContainer.css('width', '100%');\n\n                // 还原 body margin-top\n                E.$body.css({\n                    'margin-top': bodyMarginTop\n                });\n\n                // 撤销记录\n                if (editor._isMenufixed) {\n                    editor._isMenufixed = false;\n                }\n            }\n        });\n    });\n\n});\n// 缩进 菜单插件\n_e(function (E, $) {\n\n    // 用 createMenu 方法创建菜单\n    E.createMenu(function (check) {\n\n        // 定义菜单id，不要和其他菜单id重复。编辑器自带的所有菜单id，可通过『参数配置-自定义菜单』一节查看\n        var menuId = 'indent';\n\n        // check将检查菜单配置（『参数配置-自定义菜单』一节描述）中是否该菜单id，如果没有，则忽略下面的代码。\n        if (!check(menuId)) {\n            return;\n        }\n\n        // this 指向 editor 对象自身\n        var editor = this;\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,  // 编辑器对象\n            id: menuId,  // 菜单id\n            title: '缩进', // 菜单标题\n\n            // 正常状态和选中装下的dom对象，样式需要自定义\n            $domNormal: $('<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-indent-left\"></i></a>'),\n            $domSelected: $('<a href=\"#\" tabindex=\"-1\" class=\"selected\"><i class=\"wangeditor-menu-img-indent-left\"></i></a>')\n        });\n\n        // 菜单正常状态下，点击将触发该事件\n        menu.clickEvent = function (e) {\n            var elem = editor.getRangeElem();\n            var p = editor.getSelfOrParentByName(elem, 'p');\n            var $p;\n\n            if (!p) {\n                // 未找到 p 元素，则忽略\n                return e.preventDefault();\n            }\n            $p = $(p);\n\n            // 使用自定义命令\n            function commandFn() {\n                $p.css('text-indent', '2em');\n            }\n            editor.customCommand(e, commandFn);\n        };\n\n        // 菜单选中状态下，点击将触发该事件\n        menu.clickEventSelected = function (e) {\n            var elem = editor.getRangeElem();\n            var p = editor.getSelfOrParentByName(elem, 'p');\n            var $p;\n\n            if (!p) {\n                // 未找到 p 元素，则忽略\n                return e.preventDefault();\n            }\n            $p = $(p);\n\n            // 使用自定义命令\n            function commandFn() {\n                $p.css('text-indent', '0');\n            }\n            editor.customCommand(e, commandFn);\n        };\n\n        // 根据当前选区，自定义更新菜单的选中状态或者正常状态\n        menu.updateSelectedEvent = function () {\n            // 获取当前选区所在的父元素\n            var elem = editor.getRangeElem();\n            var p = editor.getSelfOrParentByName(elem, 'p');\n            var $p;\n            var indent;\n\n            if (!p) {\n                // 未找到 p 元素，则标记为未处于选中状态\n                return false;\n            }\n            $p = $(p);\n            indent = $p.css('text-indent');\n\n            if (!indent || indent === '0px') {\n                // 得到的p，text-indent 属性是 0，则标记为未处于选中状态\n                return false;\n            }\n\n            // 找到 p 元素，并且 text-indent 不是 0，则标记为选中状态\n            return true;\n        };\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n    });\n\n});\n// 行高 菜单插件\n_e(function (E, $) {\n\n    // 用 createMenu 方法创建菜单\n    E.createMenu(function (check) {\n\n        // 定义菜单id，不要和其他菜单id重复。编辑器自带的所有菜单id，可通过『参数配置-自定义菜单』一节查看\n        var menuId = 'lineheight';\n\n        // check将检查菜单配置（『参数配置-自定义菜单』一节描述）中是否该菜单id，如果没有，则忽略下面的代码。\n        if (!check(menuId)) {\n            return;\n        }\n\n        // this 指向 editor 对象自身\n        var editor = this;\n\n        // 由于浏览器自身不支持 lineHeight 命令，因此要做一个hook\n        editor.commandHooks.lineHeight = function (value) {\n            var rangeElem = editor.getRangeElem();\n            var targetElem = editor.getSelfOrParentByName(rangeElem, 'p,h1,h2,h3,h4,h5,pre');\n            if (!targetElem) {\n                return;\n            }\n            $(targetElem).css('line-height', value + '');\n        };\n\n        // 创建 menu 对象\n        var menu = new E.Menu({\n            editor: editor,  // 编辑器对象\n            id: menuId,  // 菜单id\n            title: '行高', // 菜单标题\n            commandName: 'lineHeight', // 命令名称\n\n            // 正常状态和选中装下的dom对象，样式需要自定义\n            $domNormal: $('<a href=\"#\" tabindex=\"-1\"><i class=\"wangeditor-menu-img-arrows-v\"></i></a>'),\n            $domSelected: $('<a href=\"#\" tabindex=\"-1\" class=\"selected\"><i class=\"wangeditor-menu-img-arrows-v\"></i></a>')\n        });\n\n        // 数据源\n        var data  = {\n            // 格式： 'value' : 'title'\n            '1.0': '1.0倍',\n            '1.5': '1.5倍',\n            '1.8': '1.8倍',\n            '2.0': '2.0倍',\n            '2.5': '2.5倍',\n            '3.0': '3.0倍'\n        };\n\n        // 为menu创建droplist对象\n        var tpl = '<span style=\"line-height:{#commandValue}\">{#title}</span>';\n        menu.dropList = new E.DropList(editor, menu, {\n            data: data,  // 传入数据源\n            tpl: tpl  // 传入模板\n        });\n\n        // 增加到editor对象中\n        editor.menus[menuId] = menu;\n\n    });\n\n});\n// 自定义上传\n_e(function (E, $) {\n\n    E.plugin(function () {\n\n        var editor = this;\n        var customUpload = editor.config.customUpload;\n        if (!customUpload) {\n            return;\n        } else if (editor.config.uploadImgUrl) {\n            alert('自定义上传无效，详看浏览器日志console.log');\n            E.error('已经配置了 uploadImgUrl ，就不能再配置 customUpload ，两者冲突。将导致自定义上传无效。');\n            return;\n        }\n\n        var $uploadContent = editor.$uploadContent;\n        if (!$uploadContent) {\n            E.error('自定义上传，无法获取 editor.$uploadContent');\n        }\n\n        // UI\n        var $uploadIcon = $('<div class=\"upload-icon-container\"><i class=\"wangeditor-menu-img-upload\"></i></div>');\n        $uploadContent.append($uploadIcon);\n\n        // 设置id，并暴露\n        var btnId = 'upload' + E.random();\n        var containerId = 'upload' + E.random();\n        $uploadIcon.attr('id', btnId);\n        $uploadContent.attr('id', containerId);\n\n        editor.customUploadBtnId = btnId;\n        editor.customUploadContainerId = containerId;\n    });\n\n});\n// 版权提示\n_e(function (E, $) {\n    E.info('本页面富文本编辑器由 wangEditor 提供 http://wangeditor.github.io/ ');\n});\n    \n    // 最终返回wangEditor构造函数\n    return window.wangEditor;\n});"
  },
  {
    "path": "public/static/ueditor/dialogs/anchor/anchor.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n    \"http://www.w3.org/TR/html4/loose.dtd\">\r\n<html>\r\n    <head>\r\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\r\n        <title></title>\r\n        <style type=\"text/css\">\r\n            *{color: #838383;margin: 0;padding: 0}\r\n            html,body {font-size: 12px;overflow: hidden; }\r\n            .content{padding:5px 0 0 15px;}\r\n            input{width:210px;height:21px;line-height:21px;margin-left: 4px;}\r\n        </style>\r\n    </head>\r\n    <body>\r\n        <div class=\"content\">\r\n            <span><var id=\"lang_input_anchorName\"></var></span><input id=\"anchorName\"  value=\"\" />\r\n        </div>\r\n        <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n        <script type=\"text/javascript\">\r\n            var anchorInput = $G('anchorName'),\r\n                node = editor.selection.getRange().getClosedNode();\r\n            if(node && node.tagName == 'IMG' && (node = node.getAttribute('anchorname'))){\r\n                anchorInput.value = node;\r\n            }\r\n            anchorInput.onkeydown = function(evt){\r\n                evt = evt || window.event;\r\n                if(evt.keyCode == 13){\r\n                    editor.execCommand('anchor', anchorInput.value);\r\n                    dialog.close();\r\n                    domUtils.preventDefault(evt)\r\n                }\r\n            };\r\n            dialog.onok = function (){\r\n                editor.execCommand('anchor', anchorInput.value);\r\n                dialog.close();\r\n            };\r\n            $focus(anchorInput);\r\n        </script>\r\n    </body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/attachment/attachment.css",
    "content": "@charset \"utf-8\";\r\n/* dialog样式 */\r\n.wrapper {\r\n    zoom: 1;\r\n    width: 630px;\r\n    *width: 626px;\r\n    height: 380px;\r\n    margin: 0 auto;\r\n    padding: 10px;\r\n    position: relative;\r\n    font-family: sans-serif;\r\n}\r\n\r\n/*tab样式框大小*/\r\n.tabhead {\r\n    float:left;\r\n}\r\n.tabbody {\r\n    width: 100%;\r\n    height: 346px;\r\n    position: relative;\r\n    clear: both;\r\n}\r\n\r\n.tabbody .panel {\r\n    position: absolute;\r\n    width: 0;\r\n    height: 0;\r\n    background: #fff;\r\n    overflow: hidden;\r\n    display: none;\r\n}\r\n\r\n.tabbody .panel.focus {\r\n    width: 100%;\r\n    height: 346px;\r\n    display: block;\r\n}\r\n\r\n/* 上传附件 */\r\n.tabbody #upload.panel {\r\n    width: 0;\r\n    height: 0;\r\n    overflow: hidden;\r\n    position: absolute !important;\r\n    clip: rect(1px, 1px, 1px, 1px);\r\n    background: #fff;\r\n    display: block;\r\n}\r\n\r\n.tabbody #upload.panel.focus {\r\n    width: 100%;\r\n    height: 346px;\r\n    display: block;\r\n    clip: auto;\r\n}\r\n\r\n#upload .queueList {\r\n    margin: 0;\r\n    width: 100%;\r\n    height: 100%;\r\n    position: absolute;\r\n    overflow: hidden;\r\n}\r\n\r\n#upload p {\r\n    margin: 0;\r\n}\r\n\r\n.element-invisible {\r\n    width: 0 !important;\r\n    height: 0 !important;\r\n    border: 0;\r\n    padding: 0;\r\n    margin: 0;\r\n    overflow: hidden;\r\n    position: absolute !important;\r\n    clip: rect(1px, 1px, 1px, 1px);\r\n}\r\n\r\n#upload .placeholder {\r\n    margin: 10px;\r\n    border: 2px dashed #e6e6e6;\r\n    *border: 0px dashed #e6e6e6;\r\n    height: 172px;\r\n    padding-top: 150px;\r\n    text-align: center;\r\n    background: url(./images/image.png) center 70px no-repeat;\r\n    color: #cccccc;\r\n    font-size: 18px;\r\n    position: relative;\r\n    top:0;\r\n    *top: 10px;\r\n}\r\n\r\n#upload .placeholder .webuploader-pick {\r\n    font-size: 18px;\r\n    background: #00b7ee;\r\n    border-radius: 3px;\r\n    line-height: 44px;\r\n    padding: 0 30px;\r\n    *width: 120px;\r\n    color: #fff;\r\n    display: inline-block;\r\n    margin: 0 auto 20px auto;\r\n    cursor: pointer;\r\n    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n#upload .placeholder .webuploader-pick-hover {\r\n    background: #00a2d4;\r\n}\r\n\r\n\r\n#filePickerContainer {\r\n    text-align: center;\r\n}\r\n\r\n#upload .placeholder .flashTip {\r\n    color: #666666;\r\n    font-size: 12px;\r\n    position: absolute;\r\n    width: 100%;\r\n    text-align: center;\r\n    bottom: 20px;\r\n}\r\n\r\n#upload .placeholder .flashTip a {\r\n    color: #0785d1;\r\n    text-decoration: none;\r\n}\r\n\r\n#upload .placeholder .flashTip a:hover {\r\n    text-decoration: underline;\r\n}\r\n\r\n#upload .placeholder.webuploader-dnd-over {\r\n    border-color: #999999;\r\n}\r\n\r\n#upload .filelist {\r\n    list-style: none;\r\n    margin: 0;\r\n    padding: 0;\r\n    overflow-x: hidden;\r\n    overflow-y: auto;\r\n    position: relative;\r\n    height: 300px;\r\n}\r\n\r\n#upload .filelist:after {\r\n    content: '';\r\n    display: block;\r\n    width: 0;\r\n    height: 0;\r\n    overflow: hidden;\r\n    clear: both;\r\n}\r\n\r\n#upload .filelist li {\r\n    width: 113px;\r\n    height: 113px;\r\n    background: url(./images/bg.png);\r\n    text-align: center;\r\n    margin: 9px 0 0 9px;\r\n    *margin: 6px 0 0 6px;\r\n    position: relative;\r\n    display: block;\r\n    float: left;\r\n    overflow: hidden;\r\n    font-size: 12px;\r\n}\r\n\r\n#upload .filelist li p.log {\r\n    position: relative;\r\n    top: -45px;\r\n}\r\n\r\n#upload .filelist li p.title {\r\n    position: absolute;\r\n    top: 0;\r\n    left: 0;\r\n    width: 100%;\r\n    overflow: hidden;\r\n    white-space: nowrap;\r\n    text-overflow: ellipsis;\r\n    top: 5px;\r\n    text-indent: 5px;\r\n    text-align: left;\r\n}\r\n\r\n#upload .filelist li p.progress {\r\n    position: absolute;\r\n    width: 100%;\r\n    bottom: 0;\r\n    left: 0;\r\n    height: 8px;\r\n    overflow: hidden;\r\n    z-index: 50;\r\n    margin: 0;\r\n    border-radius: 0;\r\n    background: none;\r\n    -webkit-box-shadow: 0 0 0;\r\n}\r\n\r\n#upload .filelist li p.progress span {\r\n    display: none;\r\n    overflow: hidden;\r\n    width: 0;\r\n    height: 100%;\r\n    background: #1483d8 url(./images/progress.png) repeat-x;\r\n\r\n    -webit-transition: width 200ms linear;\r\n    -moz-transition: width 200ms linear;\r\n    -o-transition: width 200ms linear;\r\n    -ms-transition: width 200ms linear;\r\n    transition: width 200ms linear;\r\n\r\n    -webkit-animation: progressmove 2s linear infinite;\r\n    -moz-animation: progressmove 2s linear infinite;\r\n    -o-animation: progressmove 2s linear infinite;\r\n    -ms-animation: progressmove 2s linear infinite;\r\n    animation: progressmove 2s linear infinite;\r\n\r\n    -webkit-transform: translateZ(0);\r\n}\r\n\r\n@-webkit-keyframes progressmove {\r\n    0% {\r\n        background-position: 0 0;\r\n    }\r\n    100% {\r\n        background-position: 17px 0;\r\n    }\r\n}\r\n\r\n@-moz-keyframes progressmove {\r\n    0% {\r\n        background-position: 0 0;\r\n    }\r\n    100% {\r\n        background-position: 17px 0;\r\n    }\r\n}\r\n\r\n@keyframes progressmove {\r\n    0% {\r\n        background-position: 0 0;\r\n    }\r\n    100% {\r\n        background-position: 17px 0;\r\n    }\r\n}\r\n\r\n#upload .filelist li p.imgWrap {\r\n    position: relative;\r\n    z-index: 2;\r\n    line-height: 113px;\r\n    vertical-align: middle;\r\n    overflow: hidden;\r\n    width: 113px;\r\n    height: 113px;\r\n\r\n    -webkit-transform-origin: 50% 50%;\r\n    -moz-transform-origin: 50% 50%;\r\n    -o-transform-origin: 50% 50%;\r\n    -ms-transform-origin: 50% 50%;\r\n    transform-origin: 50% 50%;\r\n\r\n    -webit-transition: 200ms ease-out;\r\n    -moz-transition: 200ms ease-out;\r\n    -o-transition: 200ms ease-out;\r\n    -ms-transition: 200ms ease-out;\r\n    transition: 200ms ease-out;\r\n}\r\n#upload .filelist li p.imgWrap.notimage {\r\n    margin-top: 0;\r\n    width: 111px;\r\n    height: 111px;\r\n    border: 1px #eeeeee solid;\r\n}\r\n#upload .filelist li p.imgWrap.notimage i.file-preview {\r\n    margin-top: 15px;\r\n}\r\n\r\n#upload .filelist li img {\r\n    width: 100%;\r\n}\r\n\r\n#upload .filelist li p.error {\r\n    background: #f43838;\r\n    color: #fff;\r\n    position: absolute;\r\n    bottom: 0;\r\n    left: 0;\r\n    height: 28px;\r\n    line-height: 28px;\r\n    width: 100%;\r\n    z-index: 100;\r\n    display:none;\r\n}\r\n\r\n#upload .filelist li .success {\r\n    display: block;\r\n    position: absolute;\r\n    left: 0;\r\n    bottom: 0;\r\n    height: 40px;\r\n    width: 100%;\r\n    z-index: 200;\r\n    background: url(./images/success.png) no-repeat right bottom;\r\n    background-image: url(./images/success.gif) \\9;\r\n}\r\n\r\n#upload .filelist li.filePickerBlock {\r\n    width: 113px;\r\n    height: 113px;\r\n    background: url(./images/image.png) no-repeat center 12px;\r\n    border: 1px solid #eeeeee;\r\n    border-radius: 0;\r\n}\r\n#upload .filelist li.filePickerBlock div.webuploader-pick  {\r\n    width: 100%;\r\n    height: 100%;\r\n    margin: 0;\r\n    padding: 0;\r\n    opacity: 0;\r\n    background: none;\r\n    font-size: 0;\r\n}\r\n\r\n#upload .filelist div.file-panel {\r\n    position: absolute;\r\n    height: 0;\r\n    filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#80000000', endColorstr='#80000000') \\0;\r\n    background: rgba(0, 0, 0, 0.5);\r\n    width: 100%;\r\n    top: 0;\r\n    left: 0;\r\n    overflow: hidden;\r\n    z-index: 300;\r\n}\r\n\r\n#upload .filelist div.file-panel span {\r\n    width: 24px;\r\n    height: 24px;\r\n    display: inline;\r\n    float: right;\r\n    text-indent: -9999px;\r\n    overflow: hidden;\r\n    background: url(./images/icons.png) no-repeat;\r\n    background: url(./images/icons.gif) no-repeat \\9;\r\n    margin: 5px 1px 1px;\r\n    cursor: pointer;\r\n    -webkit-tap-highlight-color: rgba(0,0,0,0);\r\n    -webkit-user-select: none;\r\n    -moz-user-select: none;\r\n    -ms-user-select: none;\r\n    user-select: none;\r\n}\r\n\r\n#upload .filelist div.file-panel span.rotateLeft {\r\n    display:none;\r\n    background-position: 0 -24px;\r\n}\r\n\r\n#upload .filelist div.file-panel span.rotateLeft:hover {\r\n    background-position: 0 0;\r\n}\r\n\r\n#upload .filelist div.file-panel span.rotateRight {\r\n    display:none;\r\n    background-position: -24px -24px;\r\n}\r\n\r\n#upload .filelist div.file-panel span.rotateRight:hover {\r\n    background-position: -24px 0;\r\n}\r\n\r\n#upload .filelist div.file-panel span.cancel {\r\n    background-position: -48px -24px;\r\n}\r\n\r\n#upload .filelist div.file-panel span.cancel:hover {\r\n    background-position: -48px 0;\r\n}\r\n\r\n#upload .statusBar {\r\n    height: 45px;\r\n    border-bottom: 1px solid #dadada;\r\n    margin: 0 10px;\r\n    padding: 0;\r\n    line-height: 45px;\r\n    vertical-align: middle;\r\n    position: relative;\r\n}\r\n\r\n#upload .statusBar .progress {\r\n    border: 1px solid #1483d8;\r\n    width: 198px;\r\n    background: #fff;\r\n    height: 18px;\r\n    position: absolute;\r\n    top: 12px;\r\n    display: none;\r\n    text-align: center;\r\n    line-height: 18px;\r\n    color: #6dbfff;\r\n    margin: 0 10px 0 0;\r\n}\r\n#upload .statusBar .progress span.percentage {\r\n    width: 0;\r\n    height: 100%;\r\n    left: 0;\r\n    top: 0;\r\n    background: #1483d8;\r\n    position: absolute;\r\n}\r\n#upload .statusBar .progress span.text {\r\n    position: relative;\r\n    z-index: 10;\r\n}\r\n\r\n#upload .statusBar .info {\r\n    display: inline-block;\r\n    font-size: 14px;\r\n    color: #666666;\r\n}\r\n\r\n#upload .statusBar .btns {\r\n    position: absolute;\r\n    top: 7px;\r\n    right: 0;\r\n    line-height: 30px;\r\n}\r\n\r\n#filePickerBtn {\r\n    display: inline-block;\r\n    float: left;\r\n}\r\n#upload .statusBar .btns .webuploader-pick,\r\n#upload .statusBar .btns .uploadBtn,\r\n#upload .statusBar .btns .uploadBtn.state-uploading,\r\n#upload .statusBar .btns .uploadBtn.state-paused {\r\n    background: #ffffff;\r\n    border: 1px solid #cfcfcf;\r\n    color: #565656;\r\n    padding: 0 18px;\r\n    display: inline-block;\r\n    border-radius: 3px;\r\n    margin-left: 10px;\r\n    cursor: pointer;\r\n    font-size: 14px;\r\n    float: left;\r\n    -webkit-user-select: none;\r\n    -moz-user-select: none;\r\n    -ms-user-select: none;\r\n    user-select: none;\r\n}\r\n#upload .statusBar .btns .webuploader-pick-hover,\r\n#upload .statusBar .btns .uploadBtn:hover,\r\n#upload .statusBar .btns .uploadBtn.state-uploading:hover,\r\n#upload .statusBar .btns .uploadBtn.state-paused:hover {\r\n    background: #f0f0f0;\r\n}\r\n\r\n#upload .statusBar .btns .uploadBtn,\r\n#upload .statusBar .btns .uploadBtn.state-paused{\r\n    background: #00b7ee;\r\n    color: #fff;\r\n    border-color: transparent;\r\n}\r\n#upload .statusBar .btns .uploadBtn:hover,\r\n#upload .statusBar .btns .uploadBtn.state-paused:hover{\r\n    background: #00a2d4;\r\n}\r\n\r\n#upload .statusBar .btns .uploadBtn.disabled {\r\n    pointer-events: none;\r\n    filter:alpha(opacity=60);\r\n    -moz-opacity:0.6;\r\n    -khtml-opacity: 0.6;\r\n    opacity: 0.6;\r\n}\r\n\r\n\r\n\r\n/* 图片管理样式 */\r\n#online {\r\n    width: 100%;\r\n    height: 336px;\r\n    padding: 10px 0 0 0;\r\n}\r\n#online #fileList{\r\n    width: 100%;\r\n    height: 100%;\r\n    overflow-x: hidden;\r\n    overflow-y: auto;\r\n    position: relative;\r\n}\r\n#online ul {\r\n    display: block;\r\n    list-style: none;\r\n    margin: 0;\r\n    padding: 0;\r\n}\r\n#online li {\r\n    float: left;\r\n    display: block;\r\n    list-style: none;\r\n    padding: 0;\r\n    width: 113px;\r\n    height: 113px;\r\n    margin: 0 0 9px 9px;\r\n    *margin: 0 0 6px 6px;\r\n    background-color: #eee;\r\n    overflow: hidden;\r\n    cursor: pointer;\r\n    position: relative;\r\n}\r\n#online li.clearFloat {\r\n    float: none;\r\n    clear: both;\r\n    display: block;\r\n    width:0;\r\n    height:0;\r\n    margin: 0;\r\n    padding: 0;\r\n}\r\n#online li img {\r\n    cursor: pointer;\r\n}\r\n#online li div.file-wrapper {\r\n    cursor: pointer;\r\n    position: absolute;\r\n    display: block;\r\n    width: 111px;\r\n    height: 111px;\r\n    border: 1px solid #eee;\r\n    background: url(\"./images/bg.png\") repeat;\r\n}\r\n#online li div span.file-title{\r\n    display: block;\r\n    padding: 0 3px;\r\n    margin: 3px 0 0 0;\r\n    font-size: 12px;\r\n    height: 13px;\r\n    color: #555555;\r\n    text-align: center;\r\n    width: 107px;\r\n    white-space: nowrap;\r\n    word-break: break-all;\r\n    overflow: hidden;\r\n    text-overflow: ellipsis;\r\n}\r\n#online li .icon {\r\n    cursor: pointer;\r\n    width: 113px;\r\n    height: 113px;\r\n    position: absolute;\r\n    top: 0;\r\n    left: 0;\r\n    z-index: 2;\r\n    border: 0;\r\n    background-repeat: no-repeat;\r\n}\r\n#online li .icon:hover {\r\n    width: 107px;\r\n    height: 107px;\r\n    border: 3px solid #1094fa;\r\n}\r\n#online li.selected .icon {\r\n    background-image: url(images/success.png);\r\n    background-image: url(images/success.gif) \\9;\r\n    background-position: 75px 75px;\r\n}\r\n#online li.selected .icon:hover {\r\n    width: 107px;\r\n    height: 107px;\r\n    border: 3px solid #1094fa;\r\n    background-position: 72px 72px;\r\n}\r\n\r\n\r\n/* 在线文件的文件预览图标 */\r\ni.file-preview {\r\n    display: block;\r\n    margin: 10px auto;\r\n    width: 70px;\r\n    height: 70px;\r\n    background-image: url(\"./images/file-icons.png\");\r\n    background-image: url(\"./images/file-icons.gif\") \\9;\r\n    background-position: -140px center;\r\n    background-repeat: no-repeat;\r\n}\r\ni.file-preview.file-type-dir{\r\n    background-position: 0 center;\r\n}\r\ni.file-preview.file-type-file{\r\n    background-position: -140px center;\r\n}\r\ni.file-preview.file-type-filelist{\r\n    background-position: -210px center;\r\n}\r\ni.file-preview.file-type-zip,\r\ni.file-preview.file-type-rar,\r\ni.file-preview.file-type-7z,\r\ni.file-preview.file-type-tar,\r\ni.file-preview.file-type-gz,\r\ni.file-preview.file-type-bz2{\r\n    background-position: -280px center;\r\n}\r\ni.file-preview.file-type-xls,\r\ni.file-preview.file-type-xlsx{\r\n    background-position: -350px center;\r\n}\r\ni.file-preview.file-type-doc,\r\ni.file-preview.file-type-docx{\r\n    background-position: -420px center;\r\n}\r\ni.file-preview.file-type-ppt,\r\ni.file-preview.file-type-pptx{\r\n    background-position: -490px center;\r\n}\r\ni.file-preview.file-type-vsd{\r\n    background-position: -560px center;\r\n}\r\ni.file-preview.file-type-pdf{\r\n    background-position: -630px center;\r\n}\r\ni.file-preview.file-type-txt,\r\ni.file-preview.file-type-md,\r\ni.file-preview.file-type-json,\r\ni.file-preview.file-type-htm,\r\ni.file-preview.file-type-xml,\r\ni.file-preview.file-type-html,\r\ni.file-preview.file-type-js,\r\ni.file-preview.file-type-css,\r\ni.file-preview.file-type-php,\r\ni.file-preview.file-type-jsp,\r\ni.file-preview.file-type-asp{\r\n    background-position: -700px center;\r\n}\r\ni.file-preview.file-type-apk{\r\n    background-position: -770px center;\r\n}\r\ni.file-preview.file-type-exe{\r\n    background-position: -840px center;\r\n}\r\ni.file-preview.file-type-ipa{\r\n    background-position: -910px center;\r\n}\r\ni.file-preview.file-type-mp4,\r\ni.file-preview.file-type-swf,\r\ni.file-preview.file-type-mkv,\r\ni.file-preview.file-type-avi,\r\ni.file-preview.file-type-flv,\r\ni.file-preview.file-type-mov,\r\ni.file-preview.file-type-mpg,\r\ni.file-preview.file-type-mpeg,\r\ni.file-preview.file-type-ogv,\r\ni.file-preview.file-type-webm,\r\ni.file-preview.file-type-rm,\r\ni.file-preview.file-type-rmvb{\r\n    background-position: -980px center;\r\n}\r\ni.file-preview.file-type-ogg,\r\ni.file-preview.file-type-wav,\r\ni.file-preview.file-type-wmv,\r\ni.file-preview.file-type-mid,\r\ni.file-preview.file-type-mp3{\r\n    background-position: -1050px center;\r\n}\r\ni.file-preview.file-type-jpg,\r\ni.file-preview.file-type-jpeg,\r\ni.file-preview.file-type-gif,\r\ni.file-preview.file-type-bmp,\r\ni.file-preview.file-type-png,\r\ni.file-preview.file-type-psd{\r\n    background-position: -140px center;\r\n}"
  },
  {
    "path": "public/static/ueditor/dialogs/attachment/attachment.html",
    "content": "<!doctype html>\r\n<html>\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <title>ueditor图片对话框</title>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n\r\n    <!-- jquery -->\r\n    <script type=\"text/javascript\" src=\"../../third-party/jquery-1.10.2.min.js\"></script>\r\n\r\n    <!-- webuploader -->\r\n    <script src=\"../../third-party/webuploader/webuploader.min.js\"></script>\r\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../../third-party/webuploader/webuploader.css\">\r\n\r\n    <!-- attachment dialog -->\r\n    <link rel=\"stylesheet\" href=\"attachment.css\" type=\"text/css\" />\r\n</head>\r\n<body>\r\n\r\n    <div class=\"wrapper\">\r\n        <div id=\"tabhead\" class=\"tabhead\">\r\n            <span class=\"tab focus\" data-content-id=\"upload\"><var id=\"lang_tab_upload\"></var></span>\r\n            <span class=\"tab\" data-content-id=\"online\"><var id=\"lang_tab_online\"></var></span>\r\n        </div>\r\n        <div id=\"tabbody\" class=\"tabbody\">\r\n            <!-- 上传图片 -->\r\n            <div id=\"upload\" class=\"panel focus\">\r\n                <div id=\"queueList\" class=\"queueList\">\r\n                    <div class=\"statusBar element-invisible\">\r\n                        <div class=\"progress\">\r\n                            <span class=\"text\">0%</span>\r\n                            <span class=\"percentage\"></span>\r\n                        </div><div class=\"info\"></div>\r\n                        <div class=\"btns\">\r\n                            <div id=\"filePickerBtn\"></div>\r\n                            <div class=\"uploadBtn\"><var id=\"lang_start_upload\"></var></div>\r\n                        </div>\r\n                    </div>\r\n                    <div id=\"dndArea\" class=\"placeholder\">\r\n                        <div class=\"filePickerContainer\">\r\n                            <div id=\"filePickerReady\"></div>\r\n                        </div>\r\n                    </div>\r\n                    <ul class=\"filelist element-invisible\">\r\n                        <li id=\"filePickerBlock\" class=\"filePickerBlock\"></li>\r\n                    </ul>\r\n                </div>\r\n            </div>\r\n\r\n            <!-- 在线图片 -->\r\n            <div id=\"online\" class=\"panel\">\r\n                <div id=\"fileList\"><var id=\"lang_imgLoading\"></var></div>\r\n            </div>\r\n\r\n        </div>\r\n    </div>\r\n    <script type=\"text/javascript\" src=\"attachment.js\"></script>\r\n\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/attachment/attachment.js",
    "content": "/**\n * User: Jinqn\n * Date: 14-04-08\n * Time: 下午16:34\n * 上传图片对话框逻辑代码,包括tab: 远程图片/上传图片/在线图片/搜索图片\n */\n\n(function () {\n\n    var uploadFile,\n        onlineFile;\n\n    window.onload = function () {\n        initTabs();\n        initButtons();\n    };\n\n    /* 初始化tab标签 */\n    function initTabs() {\n        var tabs = $G('tabhead').children;\n        for (var i = 0; i < tabs.length; i++) {\n            domUtils.on(tabs[i], \"click\", function (e) {\n                var target = e.target || e.srcElement;\n                setTabFocus(target.getAttribute('data-content-id'));\n            });\n        }\n\n        setTabFocus('upload');\n    }\n\n    /* 初始化tabbody */\n    function setTabFocus(id) {\n        if(!id) return;\n        var i, bodyId, tabs = $G('tabhead').children;\n        for (i = 0; i < tabs.length; i++) {\n            bodyId = tabs[i].getAttribute('data-content-id')\n            if (bodyId == id) {\n                domUtils.addClass(tabs[i], 'focus');\n                domUtils.addClass($G(bodyId), 'focus');\n            } else {\n                domUtils.removeClasses(tabs[i], 'focus');\n                domUtils.removeClasses($G(bodyId), 'focus');\n            }\n        }\n        switch (id) {\n            case 'upload':\n                uploadFile = uploadFile || new UploadFile('queueList');\n                break;\n            case 'online':\n                onlineFile = onlineFile || new OnlineFile('fileList');\n                break;\n        }\n    }\n\n    /* 初始化onok事件 */\n    function initButtons() {\n\n        dialog.onok = function () {\n            var list = [], id, tabs = $G('tabhead').children;\n            for (var i = 0; i < tabs.length; i++) {\n                if (domUtils.hasClass(tabs[i], 'focus')) {\n                    id = tabs[i].getAttribute('data-content-id');\n                    break;\n                }\n            }\n\n            switch (id) {\n                case 'upload':\n                    list = uploadFile.getInsertList();\n                    var count = uploadFile.getQueueCount();\n                    if (count) {\n                        $('.info', '#queueList').html('<span style=\"color:red;\">' + '还有2个未上传文件'.replace(/[\\d]/, count) + '</span>');\n                        return false;\n                    }\n                    break;\n                case 'online':\n                    list = onlineFile.getInsertList();\n                    break;\n            }\n\n            editor.execCommand('insertfile', list);\n        };\n    }\n\n\n    /* 上传附件 */\n    function UploadFile(target) {\n        this.$wrap = target.constructor == String ? $('#' + target) : $(target);\n        this.init();\n    }\n    UploadFile.prototype = {\n        init: function () {\n            this.fileList = [];\n            this.initContainer();\n            this.initUploader();\n        },\n        initContainer: function () {\n            this.$queue = this.$wrap.find('.filelist');\n        },\n        /* 初始化容器 */\n        initUploader: function () {\n            var _this = this,\n                $ = jQuery,    // just in case. Make sure it's not an other libaray.\n                $wrap = _this.$wrap,\n            // 图片容器\n                $queue = $wrap.find('.filelist'),\n            // 状态栏，包括进度和控制按钮\n                $statusBar = $wrap.find('.statusBar'),\n            // 文件总体选择信息。\n                $info = $statusBar.find('.info'),\n            // 上传按钮\n                $upload = $wrap.find('.uploadBtn'),\n            // 上传按钮\n                $filePickerBtn = $wrap.find('.filePickerBtn'),\n            // 上传按钮\n                $filePickerBlock = $wrap.find('.filePickerBlock'),\n            // 没选择文件之前的内容。\n                $placeHolder = $wrap.find('.placeholder'),\n            // 总体进度条\n                $progress = $statusBar.find('.progress').hide(),\n            // 添加的文件数量\n                fileCount = 0,\n            // 添加的文件总大小\n                fileSize = 0,\n            // 优化retina, 在retina下这个值是2\n                ratio = window.devicePixelRatio || 1,\n            // 缩略图大小\n                thumbnailWidth = 113 * ratio,\n                thumbnailHeight = 113 * ratio,\n            // 可能有pedding, ready, uploading, confirm, done.\n                state = '',\n            // 所有文件的进度信息，key为file id\n                percentages = {},\n                supportTransition = (function () {\n                    var s = document.createElement('p').style,\n                        r = 'transition' in s ||\n                            'WebkitTransition' in s ||\n                            'MozTransition' in s ||\n                            'msTransition' in s ||\n                            'OTransition' in s;\n                    s = null;\n                    return r;\n                })(),\n            // WebUploader实例\n                uploader,\n                actionUrl = editor.getActionUrl(editor.getOpt('fileActionName')),\n                fileMaxSize = editor.getOpt('fileMaxSize'),\n                acceptExtensions = (editor.getOpt('fileAllowFiles') || []).join('').replace(/\\./g, ',').replace(/^[,]/, '');;\n\n            if (!WebUploader.Uploader.support()) {\n                $('#filePickerReady').after($('<div>').html(lang.errorNotSupport)).hide();\n                return;\n            } else if (!editor.getOpt('fileActionName')) {\n                $('#filePickerReady').after($('<div>').html(lang.errorLoadConfig)).hide();\n                return;\n            }\n\n            uploader = _this.uploader = WebUploader.create({\n                pick: {\n                    id: '#filePickerReady',\n                    label: lang.uploadSelectFile\n                },\n                swf: '../../third-party/webuploader/Uploader.swf',\n                server: actionUrl,\n                fileVal: editor.getOpt('fileFieldName'),\n                duplicate: true,\n                fileSingleSizeLimit: fileMaxSize,\n                compress: false\n            });\n            uploader.addButton({\n                id: '#filePickerBlock'\n            });\n            uploader.addButton({\n                id: '#filePickerBtn',\n                label: lang.uploadAddFile\n            });\n\n            setState('pedding');\n\n            // 当有文件添加进来时执行，负责view的创建\n            function addFile(file) {\n                var $li = $('<li id=\"' + file.id + '\">' +\n                        '<p class=\"title\">' + file.name + '</p>' +\n                        '<p class=\"imgWrap\"></p>' +\n                        '<p class=\"progress\"><span></span></p>' +\n                        '</li>'),\n\n                    $btns = $('<div class=\"file-panel\">' +\n                        '<span class=\"cancel\">' + lang.uploadDelete + '</span>' +\n                        '<span class=\"rotateRight\">' + lang.uploadTurnRight + '</span>' +\n                        '<span class=\"rotateLeft\">' + lang.uploadTurnLeft + '</span></div>').appendTo($li),\n                    $prgress = $li.find('p.progress span'),\n                    $wrap = $li.find('p.imgWrap'),\n                    $info = $('<p class=\"error\"></p>').hide().appendTo($li),\n\n                    showError = function (code) {\n                        switch (code) {\n                            case 'exceed_size':\n                                text = lang.errorExceedSize;\n                                break;\n                            case 'interrupt':\n                                text = lang.errorInterrupt;\n                                break;\n                            case 'http':\n                                text = lang.errorHttp;\n                                break;\n                            case 'not_allow_type':\n                                text = lang.errorFileType;\n                                break;\n                            default:\n                                text = lang.errorUploadRetry;\n                                break;\n                        }\n                        $info.text(text).show();\n                    };\n\n                if (file.getStatus() === 'invalid') {\n                    showError(file.statusText);\n                } else {\n                    $wrap.text(lang.uploadPreview);\n                    if ('|png|jpg|jpeg|bmp|gif|'.indexOf('|'+file.ext.toLowerCase()+'|') == -1) {\n                        $wrap.empty().addClass('notimage').append('<i class=\"file-preview file-type-' + file.ext.toLowerCase() + '\"></i>' +\n                        '<span class=\"file-title\" title=\"' + file.name + '\">' + file.name + '</span>');\n                    } else {\n                        if (browser.ie && browser.version <= 7) {\n                            $wrap.text(lang.uploadNoPreview);\n                        } else {\n                            uploader.makeThumb(file, function (error, src) {\n                                if (error || !src) {\n                                    $wrap.text(lang.uploadNoPreview);\n                                } else {\n                                    var $img = $('<img src=\"' + src + '\">');\n                                    $wrap.empty().append($img);\n                                    $img.on('error', function () {\n                                        $wrap.text(lang.uploadNoPreview);\n                                    });\n                                }\n                            }, thumbnailWidth, thumbnailHeight);\n                        }\n                    }\n                    percentages[ file.id ] = [ file.size, 0 ];\n                    file.rotation = 0;\n\n                    /* 检查文件格式 */\n                    if (!file.ext || acceptExtensions.indexOf(file.ext.toLowerCase()) == -1) {\n                        showError('not_allow_type');\n                        uploader.removeFile(file);\n                    }\n                }\n\n                file.on('statuschange', function (cur, prev) {\n                    if (prev === 'progress') {\n                        $prgress.hide().width(0);\n                    } else if (prev === 'queued') {\n                        $li.off('mouseenter mouseleave');\n                        $btns.remove();\n                    }\n                    // 成功\n                    if (cur === 'error' || cur === 'invalid') {\n                        showError(file.statusText);\n                        percentages[ file.id ][ 1 ] = 1;\n                    } else if (cur === 'interrupt') {\n                        showError('interrupt');\n                    } else if (cur === 'queued') {\n                        percentages[ file.id ][ 1 ] = 0;\n                    } else if (cur === 'progress') {\n                        $info.hide();\n                        $prgress.css('display', 'block');\n                    } else if (cur === 'complete') {\n                    }\n\n                    $li.removeClass('state-' + prev).addClass('state-' + cur);\n                });\n\n                $li.on('mouseenter', function () {\n                    $btns.stop().animate({height: 30});\n                });\n                $li.on('mouseleave', function () {\n                    $btns.stop().animate({height: 0});\n                });\n\n                $btns.on('click', 'span', function () {\n                    var index = $(this).index(),\n                        deg;\n\n                    switch (index) {\n                        case 0:\n                            uploader.removeFile(file);\n                            return;\n                        case 1:\n                            file.rotation += 90;\n                            break;\n                        case 2:\n                            file.rotation -= 90;\n                            break;\n                    }\n\n                    if (supportTransition) {\n                        deg = 'rotate(' + file.rotation + 'deg)';\n                        $wrap.css({\n                            '-webkit-transform': deg,\n                            '-mos-transform': deg,\n                            '-o-transform': deg,\n                            'transform': deg\n                        });\n                    } else {\n                        $wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')');\n                    }\n\n                });\n\n                $li.insertBefore($filePickerBlock);\n            }\n\n            // 负责view的销毁\n            function removeFile(file) {\n                var $li = $('#' + file.id);\n                delete percentages[ file.id ];\n                updateTotalProgress();\n                $li.off().find('.file-panel').off().end().remove();\n            }\n\n            function updateTotalProgress() {\n                var loaded = 0,\n                    total = 0,\n                    spans = $progress.children(),\n                    percent;\n\n                $.each(percentages, function (k, v) {\n                    total += v[ 0 ];\n                    loaded += v[ 0 ] * v[ 1 ];\n                });\n\n                percent = total ? loaded / total : 0;\n\n                spans.eq(0).text(Math.round(percent * 100) + '%');\n                spans.eq(1).css('width', Math.round(percent * 100) + '%');\n                updateStatus();\n            }\n\n            function setState(val, files) {\n\n                if (val != state) {\n\n                    var stats = uploader.getStats();\n\n                    $upload.removeClass('state-' + state);\n                    $upload.addClass('state-' + val);\n\n                    switch (val) {\n\n                        /* 未选择文件 */\n                        case 'pedding':\n                            $queue.addClass('element-invisible');\n                            $statusBar.addClass('element-invisible');\n                            $placeHolder.removeClass('element-invisible');\n                            $progress.hide(); $info.hide();\n                            uploader.refresh();\n                            break;\n\n                        /* 可以开始上传 */\n                        case 'ready':\n                            $placeHolder.addClass('element-invisible');\n                            $queue.removeClass('element-invisible');\n                            $statusBar.removeClass('element-invisible');\n                            $progress.hide(); $info.show();\n                            $upload.text(lang.uploadStart);\n                            uploader.refresh();\n                            break;\n\n                        /* 上传中 */\n                        case 'uploading':\n                            $progress.show(); $info.hide();\n                            $upload.text(lang.uploadPause);\n                            break;\n\n                        /* 暂停上传 */\n                        case 'paused':\n                            $progress.show(); $info.hide();\n                            $upload.text(lang.uploadContinue);\n                            break;\n\n                        case 'confirm':\n                            $progress.show(); $info.hide();\n                            $upload.text(lang.uploadStart);\n\n                            stats = uploader.getStats();\n                            if (stats.successNum && !stats.uploadFailNum) {\n                                setState('finish');\n                                return;\n                            }\n                            break;\n\n                        case 'finish':\n                            $progress.hide(); $info.show();\n                            if (stats.uploadFailNum) {\n                                $upload.text(lang.uploadRetry);\n                            } else {\n                                $upload.text(lang.uploadStart);\n                            }\n                            break;\n                    }\n\n                    state = val;\n                    updateStatus();\n\n                }\n\n                if (!_this.getQueueCount()) {\n                    $upload.addClass('disabled')\n                } else {\n                    $upload.removeClass('disabled')\n                }\n\n            }\n\n            function updateStatus() {\n                var text = '', stats;\n\n                if (state === 'ready') {\n                    text = lang.updateStatusReady.replace('_', fileCount).replace('_KB', WebUploader.formatSize(fileSize));\n                } else if (state === 'confirm') {\n                    stats = uploader.getStats();\n                    if (stats.uploadFailNum) {\n                        text = lang.updateStatusConfirm.replace('_', stats.successNum).replace('_', stats.successNum);\n                    }\n                } else {\n                    stats = uploader.getStats();\n                    text = lang.updateStatusFinish.replace('_', fileCount).\n                        replace('_KB', WebUploader.formatSize(fileSize)).\n                        replace('_', stats.successNum);\n\n                    if (stats.uploadFailNum) {\n                        text += lang.updateStatusError.replace('_', stats.uploadFailNum);\n                    }\n                }\n\n                $info.html(text);\n            }\n\n            uploader.on('fileQueued', function (file) {\n                fileCount++;\n                fileSize += file.size;\n\n                if (fileCount === 1) {\n                    $placeHolder.addClass('element-invisible');\n                    $statusBar.show();\n                }\n\n                addFile(file);\n            });\n\n            uploader.on('fileDequeued', function (file) {\n                fileCount--;\n                fileSize -= file.size;\n\n                removeFile(file);\n                updateTotalProgress();\n            });\n\n            uploader.on('filesQueued', function (file) {\n                if (!uploader.isInProgress() && (state == 'pedding' || state == 'finish' || state == 'confirm' || state == 'ready')) {\n                    setState('ready');\n                }\n                updateTotalProgress();\n            });\n\n            uploader.on('all', function (type, files) {\n                switch (type) {\n                    case 'uploadFinished':\n                        setState('confirm', files);\n                        break;\n                    case 'startUpload':\n                        /* 添加额外的GET参数 */\n                        var params = utils.serializeParam(editor.queryCommandValue('serverparam')) || '',\n                            url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + 'encode=utf-8&' + params);\n                        uploader.option('server', url);\n                        setState('uploading', files);\n                        break;\n                    case 'stopUpload':\n                        setState('paused', files);\n                        break;\n                }\n            });\n\n            uploader.on('uploadBeforeSend', function (file, data, header) {\n                //这里可以通过data对象添加POST参数\n                header['X_Requested_With'] = 'XMLHttpRequest';\n            });\n\n            uploader.on('uploadProgress', function (file, percentage) {\n                var $li = $('#' + file.id),\n                    $percent = $li.find('.progress span');\n\n                $percent.css('width', percentage * 100 + '%');\n                percentages[ file.id ][ 1 ] = percentage;\n                updateTotalProgress();\n            });\n\n            uploader.on('uploadSuccess', function (file, ret) {\n                var $file = $('#' + file.id);\n                try {\n                    var responseText = (ret._raw || ret),\n                        json = utils.str2json(responseText);\n                    if (json.state == 'SUCCESS') {\n                        _this.fileList.push(json);\n                        $file.append('<span class=\"success\"></span>');\n                    } else {\n                        $file.find('.error').text(json.state).show();\n                    }\n                } catch (e) {\n                    $file.find('.error').text(lang.errorServerUpload).show();\n                }\n            });\n\n            uploader.on('uploadError', function (file, code) {\n            });\n            uploader.on('error', function (code, file) {\n                if (code == 'Q_TYPE_DENIED' || code == 'F_EXCEED_SIZE') {\n                    addFile(file);\n                }\n            });\n            uploader.on('uploadComplete', function (file, ret) {\n            });\n\n            $upload.on('click', function () {\n                if ($(this).hasClass('disabled')) {\n                    return false;\n                }\n\n                if (state === 'ready') {\n                    uploader.upload();\n                } else if (state === 'paused') {\n                    uploader.upload();\n                } else if (state === 'uploading') {\n                    uploader.stop();\n                }\n            });\n\n            $upload.addClass('state-' + state);\n            updateTotalProgress();\n        },\n        getQueueCount: function () {\n            var file, i, status, readyFile = 0, files = this.uploader.getFiles();\n            for (i = 0; file = files[i++]; ) {\n                status = file.getStatus();\n                if (status == 'queued' || status == 'uploading' || status == 'progress') readyFile++;\n            }\n            return readyFile;\n        },\n        getInsertList: function () {\n            var i, link, data, list = [],\n                prefix = editor.getOpt('fileUrlPrefix');\n            for (i = 0; i < this.fileList.length; i++) {\n                data = this.fileList[i];\n                link = data.url;\n                list.push({\n                    title: data.original || link.substr(link.lastIndexOf('/') + 1),\n                    url: prefix + link\n                });\n            }\n            return list;\n        }\n    };\n\n\n    /* 在线附件 */\n    function OnlineFile(target) {\n        this.container = utils.isString(target) ? document.getElementById(target) : target;\n        this.init();\n    }\n    OnlineFile.prototype = {\n        init: function () {\n            this.initContainer();\n            this.initEvents();\n            this.initData();\n        },\n        /* 初始化容器 */\n        initContainer: function () {\n            this.container.innerHTML = '';\n            this.list = document.createElement('ul');\n            this.clearFloat = document.createElement('li');\n\n            domUtils.addClass(this.list, 'list');\n            domUtils.addClass(this.clearFloat, 'clearFloat');\n\n            this.list.appendChild(this.clearFloat);\n            this.container.appendChild(this.list);\n        },\n        /* 初始化滚动事件,滚动到地步自动拉取数据 */\n        initEvents: function () {\n            var _this = this;\n\n            /* 滚动拉取图片 */\n            domUtils.on($G('fileList'), 'scroll', function(e){\n                var panel = this;\n                if (panel.scrollHeight - (panel.offsetHeight + panel.scrollTop) < 10) {\n                    _this.getFileData();\n                }\n            });\n            /* 选中图片 */\n            domUtils.on(this.list, 'click', function (e) {\n                var target = e.target || e.srcElement,\n                    li = target.parentNode;\n\n                if (li.tagName.toLowerCase() == 'li') {\n                    if (domUtils.hasClass(li, 'selected')) {\n                        domUtils.removeClasses(li, 'selected');\n                    } else {\n                        domUtils.addClass(li, 'selected');\n                    }\n                }\n            });\n        },\n        /* 初始化第一次的数据 */\n        initData: function () {\n\n            /* 拉取数据需要使用的值 */\n            this.state = 0;\n            this.listSize = editor.getOpt('fileManagerListSize');\n            this.listIndex = 0;\n            this.listEnd = false;\n\n            /* 第一次拉取数据 */\n            this.getFileData();\n        },\n        /* 向后台拉取图片列表数据 */\n        getFileData: function () {\n            var _this = this;\n\n            if(!_this.listEnd && !this.isLoadingData) {\n                this.isLoadingData = true;\n                ajax.request(editor.getActionUrl(editor.getOpt('fileManagerActionName')), {\n                    timeout: 100000,\n                    data: utils.extend({\n                            start: this.listIndex,\n                            size: this.listSize\n                        }, editor.queryCommandValue('serverparam')),\n                    method: 'get',\n                    onsuccess: function (r) {\n                        try {\n                            var json = eval('(' + r.responseText + ')');\n                            if (json.state == 'SUCCESS') {\n                                _this.pushData(json.list);\n                                _this.listIndex = parseInt(json.start) + parseInt(json.list.length);\n                                if(_this.listIndex >= json.total) {\n                                    _this.listEnd = true;\n                                }\n                                _this.isLoadingData = false;\n                            }\n                        } catch (e) {\n                            if(r.responseText.indexOf('ue_separate_ue') != -1) {\n                                var list = r.responseText.split(r.responseText);\n                                _this.pushData(list);\n                                _this.listIndex = parseInt(list.length);\n                                _this.listEnd = true;\n                                _this.isLoadingData = false;\n                            }\n                        }\n                    },\n                    onerror: function () {\n                        _this.isLoadingData = false;\n                    }\n                });\n            }\n        },\n        /* 添加图片到列表界面上 */\n        pushData: function (list) {\n            var i, item, img, filetype, preview, icon, _this = this,\n                urlPrefix = editor.getOpt('fileManagerUrlPrefix');\n            for (i = 0; i < list.length; i++) {\n                if(list[i] && list[i].url) {\n                    item = document.createElement('li');\n                    icon = document.createElement('span');\n                    filetype = list[i].url.substr(list[i].url.lastIndexOf('.') + 1);\n\n                    if ( \"png|jpg|jpeg|gif|bmp\".indexOf(filetype) != -1 ) {\n                        preview = document.createElement('img');\n                        domUtils.on(preview, 'load', (function(image){\n                            return function(){\n                                _this.scale(image, image.parentNode.offsetWidth, image.parentNode.offsetHeight);\n                            };\n                        })(preview));\n                        preview.width = 113;\n                        preview.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) );\n                    } else {\n                        var ic = document.createElement('i'),\n                            textSpan = document.createElement('span');\n                        textSpan.innerHTML = list[i].url.substr(list[i].url.lastIndexOf('/') + 1);\n                        preview = document.createElement('div');\n                        preview.appendChild(ic);\n                        preview.appendChild(textSpan);\n                        domUtils.addClass(preview, 'file-wrapper');\n                        domUtils.addClass(textSpan, 'file-title');\n                        domUtils.addClass(ic, 'file-type-' + filetype);\n                        domUtils.addClass(ic, 'file-preview');\n                    }\n                    domUtils.addClass(icon, 'icon');\n                    item.setAttribute('data-url', urlPrefix + list[i].url);\n                    if (list[i].original) {\n                        item.setAttribute('data-title', list[i].original);\n                    }\n\n                    item.appendChild(preview);\n                    item.appendChild(icon);\n                    this.list.insertBefore(item, this.clearFloat);\n                }\n            }\n        },\n        /* 改变图片大小 */\n        scale: function (img, w, h, type) {\n            var ow = img.width,\n                oh = img.height;\n\n            if (type == 'justify') {\n                if (ow >= oh) {\n                    img.width = w;\n                    img.height = h * oh / ow;\n                    img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';\n                } else {\n                    img.width = w * ow / oh;\n                    img.height = h;\n                    img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';\n                }\n            } else {\n                if (ow >= oh) {\n                    img.width = w * ow / oh;\n                    img.height = h;\n                    img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';\n                } else {\n                    img.width = w;\n                    img.height = h * oh / ow;\n                    img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';\n                }\n            }\n        },\n        getInsertList: function () {\n            var i, lis = this.list.children, list = [];\n            for (i = 0; i < lis.length; i++) {\n                if (domUtils.hasClass(lis[i], 'selected')) {\n                    var url = lis[i].getAttribute('data-url');\n                    var title = lis[i].getAttribute('data-title') || url.substr(url.lastIndexOf('/') + 1);\n                    list.push({\n                        title: title,\n                        url: url\n                    });\n                }\n            }\n            return list;\n        }\n    };\n\n\n})();"
  },
  {
    "path": "public/static/ueditor/dialogs/background/background.css",
    "content": ".wrapper{ width: 424px;margin: 10px auto; zoom:1;position: relative}\r\n.tabbody{height:225px;}\r\n.tabbody .panel { position: absolute;width:100%; height:100%;background: #fff; display: none;}\r\n.tabbody .focus { display: block;}\r\n\r\nbody{font-size: 12px;color: #888;overflow: hidden;}\r\ninput,label{vertical-align:middle}\r\n.clear{clear: both;}\r\n.pl{padding-left: 18px;padding-left: 23px\\9;}\r\n\r\n#imageList {width: 420px;height: 215px;margin-top: 10px;overflow: hidden;overflow-y: auto;}\r\n#imageList div {float: left;width: 100px;height: 95px;margin: 5px 10px;}\r\n#imageList img {cursor: pointer;border: 2px solid white;}\r\n\r\n.bgarea{margin: 10px;padding: 5px;height: 84%;border: 1px solid #A8A297;}\r\n.content div{margin: 10px 0 10px 5px;}\r\n.content .iptradio{margin: 0px 5px 5px 0px;}\r\n.txt{width:280px;}\r\n\r\n.wrapcolor{height: 19px;}\r\ndiv.color{float: left;margin: 0;}\r\n#colorPicker{width: 17px;height: 17px;border: 1px solid #CCC;display: inline-block;border-radius: 3px;box-shadow: 2px 2px 5px #D3D6DA;margin: 0;float: left;}\r\ndiv.alignment,#custom{margin-left: 23px;margin-left: 28px\\9;}\r\n#custom input{height: 15px;min-height: 15px;width:20px;}\r\n#repeatType{width:100px;}\r\n\r\n\r\n/* 图片管理样式 */\r\n#imgManager {\r\n    width: 100%;\r\n    height: 225px;\r\n}\r\n#imgManager #imageList{\r\n    width: 100%;\r\n    overflow-x: hidden;\r\n    overflow-y: auto;\r\n}\r\n#imgManager ul {\r\n    display: block;\r\n    list-style: none;\r\n    margin: 0;\r\n    padding: 0;\r\n}\r\n#imgManager li {\r\n    float: left;\r\n    display: block;\r\n    list-style: none;\r\n    padding: 0;\r\n    width: 113px;\r\n    height: 113px;\r\n    margin: 9px 0 0 19px;\r\n    background-color: #eee;\r\n    overflow: hidden;\r\n    cursor: pointer;\r\n    position: relative;\r\n}\r\n#imgManager li.clearFloat {\r\n    float: none;\r\n    clear: both;\r\n    display: block;\r\n    width:0;\r\n    height:0;\r\n    margin: 0;\r\n    padding: 0;\r\n}\r\n#imgManager li img {\r\n    cursor: pointer;\r\n}\r\n#imgManager li .icon {\r\n    cursor: pointer;\r\n    width: 113px;\r\n    height: 113px;\r\n    position: absolute;\r\n    top: 0;\r\n    left: 0;\r\n    z-index: 2;\r\n    border: 0;\r\n    background-repeat: no-repeat;\r\n}\r\n#imgManager li .icon:hover {\r\n    width: 107px;\r\n    height: 107px;\r\n    border: 3px solid #1094fa;\r\n}\r\n#imgManager li.selected .icon {\r\n    background-image: url(images/success.png);\r\n    background-position: 75px 75px;\r\n}\r\n#imgManager li.selected .icon:hover {\r\n    width: 107px;\r\n    height: 107px;\r\n    border: 3px solid #1094fa;\r\n    background-position: 72px 72px;\r\n}"
  },
  {
    "path": "public/static/ueditor/dialogs/background/background.html",
    "content": "<!DOCTYPE HTML>\r\n<html>\r\n<head>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"background.css\">\r\n</head>\r\n<body>\r\n    <div id=\"bg_container\" class=\"wrapper\">\r\n        <div id=\"tabHeads\" class=\"tabhead\">\r\n            <span class=\"focus\" data-content-id=\"normal\"><var id=\"lang_background_normal\"></var></span>\r\n            <span class=\"\" data-content-id=\"imgManager\"><var id=\"lang_background_local\"></var></span>\r\n        </div>\r\n        <div id=\"tabBodys\" class=\"tabbody\">\r\n            <div id=\"normal\" class=\"panel focus\">\r\n                <fieldset class=\"bgarea\">\r\n                    <legend><var id=\"lang_background_set\"></var></legend>\r\n                    <div class=\"content\">\r\n                        <div>\r\n                            <label><input id=\"nocolorRadio\" class=\"iptradio\" type=\"radio\" name=\"t\" value=\"none\" checked=\"checked\"><var id=\"lang_background_none\"></var></label>\r\n                            <label><input id=\"coloredRadio\" class=\"iptradio\" type=\"radio\" name=\"t\" value=\"color\"><var id=\"lang_background_colored\"></var></label>\r\n                        </div>\r\n                        <div class=\"wrapcolor pl\">\r\n                            <div class=\"color\">\r\n                                <var id=\"lang_background_color\"></var>:\r\n                            </div>\r\n                            <div id=\"colorPicker\"></div>\r\n                            <div class=\"clear\"></div>\r\n                        </div>\r\n                        <div class=\"wrapcolor pl\">\r\n                            <label><var id=\"lang_background_netimg\"></var>:</label><input class=\"txt\" type=\"text\" id=\"url\">\r\n                        </div>\r\n                        <div id=\"alignment\" class=\"alignment\">\r\n                            <var id=\"lang_background_align\"></var>:<select id=\"repeatType\">\r\n                                <option value=\"center\"></option>\r\n                                <option value=\"repeat-x\"></option>\r\n                                <option value=\"repeat-y\"></option>\r\n                                <option value=\"repeat\"></option>\r\n                                <option value=\"self\"></option>\r\n                            </select>\r\n                        </div>\r\n                        <div id=\"custom\" >\r\n                            <var id=\"lang_background_position\"></var>:x:<input type=\"text\" size=\"1\" id=\"x\" maxlength=\"4\" value=\"0\">px&nbsp;&nbsp;y:<input type=\"text\" size=\"1\" id=\"y\" maxlength=\"4\" value=\"0\">px\r\n                        </div>\r\n                    </div>\r\n                </fieldset>\r\n\r\n            </div>\r\n            <div id=\"imgManager\" class=\"panel\">\r\n                <div id=\"imageList\" style=\"\"></div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n    <script type=\"text/javascript\" src=\"background.js\"></script>\r\n</body>\r\n</html>\r\n"
  },
  {
    "path": "public/static/ueditor/dialogs/background/background.js",
    "content": "(function () {\r\n\r\n    var onlineImage,\r\n        backupStyle = editor.queryCommandValue('background');\r\n\r\n    window.onload = function () {\r\n        initTabs();\r\n        initColorSelector();\r\n    };\r\n\r\n    /* 初始化tab标签 */\r\n    function initTabs(){\r\n        var tabs = $G('tabHeads').children;\r\n        for (var i = 0; i < tabs.length; i++) {\r\n            domUtils.on(tabs[i], \"click\", function (e) {\r\n                var target = e.target || e.srcElement;\r\n                for (var j = 0; j < tabs.length; j++) {\r\n                    if(tabs[j] == target){\r\n                        tabs[j].className = \"focus\";\r\n                        var contentId = tabs[j].getAttribute('data-content-id');\r\n                        $G(contentId).style.display = \"block\";\r\n                        if(contentId == 'imgManager') {\r\n                            initImagePanel();\r\n                        }\r\n                    }else {\r\n                        tabs[j].className = \"\";\r\n                        $G(tabs[j].getAttribute('data-content-id')).style.display = \"none\";\r\n                    }\r\n                }\r\n            });\r\n        }\r\n    }\r\n\r\n    /* 初始化颜色设置 */\r\n    function initColorSelector () {\r\n        var obj = editor.queryCommandValue('background');\r\n        if (obj) {\r\n            var color = obj['background-color'],\r\n                repeat = obj['background-repeat'] || 'repeat',\r\n                image = obj['background-image'] || '',\r\n                position = obj['background-position'] || 'center center',\r\n                pos = position.split(' '),\r\n                x = parseInt(pos[0]) || 0,\r\n                y = parseInt(pos[1]) || 0;\r\n\r\n            if(repeat == 'no-repeat' && (x || y)) repeat = 'self';\r\n\r\n            image = image.match(/url[\\s]*\\(([^\\)]*)\\)/);\r\n            image = image ? image[1]:'';\r\n            updateFormState('colored', color, image, repeat, x, y);\r\n        } else {\r\n            updateFormState();\r\n        }\r\n\r\n        var updateHandler = function () {\r\n            updateFormState();\r\n            updateBackground();\r\n        }\r\n        domUtils.on($G('nocolorRadio'), 'click', updateBackground);\r\n        domUtils.on($G('coloredRadio'), 'click', updateHandler);\r\n        domUtils.on($G('url'), 'keyup', function(){\r\n            if($G('url').value && $G('alignment').style.display == \"none\") {\r\n                utils.each($G('repeatType').children, function(item){\r\n                    item.selected = ('repeat' == item.getAttribute('value') ? 'selected':false);\r\n                });\r\n            }\r\n            updateHandler();\r\n        });\r\n        domUtils.on($G('repeatType'), 'change', updateHandler);\r\n        domUtils.on($G('x'), 'keyup', updateBackground);\r\n        domUtils.on($G('y'), 'keyup', updateBackground);\r\n\r\n        initColorPicker();\r\n    }\r\n\r\n    /* 初始化颜色选择器 */\r\n    function initColorPicker() {\r\n        var me = editor,\r\n            cp = $G(\"colorPicker\");\r\n\r\n        /* 生成颜色选择器ui对象 */\r\n        var popup = new UE.ui.Popup({\r\n            content: new UE.ui.ColorPicker({\r\n                noColorText: me.getLang(\"clearColor\"),\r\n                editor: me,\r\n                onpickcolor: function (t, color) {\r\n                    updateFormState('colored', color);\r\n                    updateBackground();\r\n                    UE.ui.Popup.postHide();\r\n                },\r\n                onpicknocolor: function (t, color) {\r\n                    updateFormState('colored', 'transparent');\r\n                    updateBackground();\r\n                    UE.ui.Popup.postHide();\r\n                }\r\n            }),\r\n            editor: me,\r\n            onhide: function () {\r\n            }\r\n        });\r\n\r\n        /* 设置颜色选择器 */\r\n        domUtils.on(cp, \"click\", function () {\r\n            popup.showAnchor(this);\r\n        });\r\n        domUtils.on(document, 'mousedown', function (evt) {\r\n            var el = evt.target || evt.srcElement;\r\n            UE.ui.Popup.postHide(el);\r\n        });\r\n        domUtils.on(window, 'scroll', function () {\r\n            UE.ui.Popup.postHide();\r\n        });\r\n    }\r\n\r\n    /* 初始化在线图片列表 */\r\n    function initImagePanel() {\r\n        onlineImage = onlineImage || new OnlineImage('imageList');\r\n    }\r\n\r\n    /* 更新背景色设置面板 */\r\n    function updateFormState (radio, color, url, align, x, y) {\r\n        var nocolorRadio = $G('nocolorRadio'),\r\n            coloredRadio = $G('coloredRadio');\r\n\r\n        if(radio) {\r\n            nocolorRadio.checked = (radio == 'colored' ? false:'checked');\r\n            coloredRadio.checked = (radio == 'colored' ? 'checked':false);\r\n        }\r\n        if(color) {\r\n            domUtils.setStyle($G(\"colorPicker\"), \"background-color\", color);\r\n        }\r\n\r\n        if(url && /^\\//.test(url)) {\r\n            var a = document.createElement('a');\r\n            a.href = url;\r\n            browser.ie && (a.href = a.href);\r\n            url = browser.ie ? a.href:(a.protocol + '//' + a.host + a.pathname + a.search + a.hash);\r\n        }\r\n\r\n        if(url || url === '') {\r\n            $G('url').value = url;\r\n        }\r\n        if(align) {\r\n            utils.each($G('repeatType').children, function(item){\r\n                item.selected = (align == item.getAttribute('value') ? 'selected':false);\r\n            });\r\n        }\r\n        if(x || y) {\r\n            $G('x').value = parseInt(x) || 0;\r\n            $G('y').value = parseInt(y) || 0;\r\n        }\r\n\r\n        $G('alignment').style.display = coloredRadio.checked && $G('url').value ? '':'none';\r\n        $G('custom').style.display = coloredRadio.checked && $G('url').value && $G('repeatType').value == 'self' ? '':'none';\r\n    }\r\n\r\n    /* 更新背景颜色 */\r\n    function updateBackground () {\r\n        if ($G('coloredRadio').checked) {\r\n            var color = domUtils.getStyle($G(\"colorPicker\"), \"background-color\"),\r\n                bgimg = $G(\"url\").value,\r\n                align = $G(\"repeatType\").value,\r\n                backgroundObj = {\r\n                    \"background-repeat\": \"no-repeat\",\r\n                    \"background-position\": \"center center\"\r\n                };\r\n\r\n            if (color) backgroundObj[\"background-color\"] = color;\r\n            if (bgimg) backgroundObj[\"background-image\"] = 'url(' + bgimg + ')';\r\n            if (align == 'self') {\r\n                backgroundObj[\"background-position\"] = $G(\"x\").value + \"px \" + $G(\"y\").value + \"px\";\r\n            } else if (align == 'repeat-x' || align == 'repeat-y' || align == 'repeat') {\r\n                backgroundObj[\"background-repeat\"] = align;\r\n            }\r\n\r\n            editor.execCommand('background', backgroundObj);\r\n        } else {\r\n            editor.execCommand('background', null);\r\n        }\r\n    }\r\n\r\n\r\n    /* 在线图片 */\r\n    function OnlineImage(target) {\r\n        this.container = utils.isString(target) ? document.getElementById(target) : target;\r\n        this.init();\r\n    }\r\n    OnlineImage.prototype = {\r\n        init: function () {\r\n            this.reset();\r\n            this.initEvents();\r\n        },\r\n        /* 初始化容器 */\r\n        initContainer: function () {\r\n            this.container.innerHTML = '';\r\n            this.list = document.createElement('ul');\r\n            this.clearFloat = document.createElement('li');\r\n\r\n            domUtils.addClass(this.list, 'list');\r\n            domUtils.addClass(this.clearFloat, 'clearFloat');\r\n\r\n            this.list.id = 'imageListUl';\r\n            this.list.appendChild(this.clearFloat);\r\n            this.container.appendChild(this.list);\r\n        },\r\n        /* 初始化滚动事件,滚动到地步自动拉取数据 */\r\n        initEvents: function () {\r\n            var _this = this;\r\n\r\n            /* 滚动拉取图片 */\r\n            domUtils.on($G('imageList'), 'scroll', function(e){\r\n                var panel = this;\r\n                if (panel.scrollHeight - (panel.offsetHeight + panel.scrollTop) < 10) {\r\n                    _this.getImageData();\r\n                }\r\n            });\r\n            /* 选中图片 */\r\n            domUtils.on(this.container, 'click', function (e) {\r\n                var target = e.target || e.srcElement,\r\n                    li = target.parentNode,\r\n                    nodes = $G('imageListUl').childNodes;\r\n\r\n                if (li.tagName.toLowerCase() == 'li') {\r\n                    updateFormState('nocolor', null, '');\r\n                    for (var i = 0, node; node = nodes[i++];) {\r\n                        if (node == li && !domUtils.hasClass(node, 'selected')) {\r\n                            domUtils.addClass(node, 'selected');\r\n                            updateFormState('colored', null, li.firstChild.getAttribute(\"_src\"), 'repeat');\r\n                        } else {\r\n                            domUtils.removeClasses(node, 'selected');\r\n                        }\r\n                    }\r\n                    updateBackground();\r\n                }\r\n            });\r\n        },\r\n        /* 初始化第一次的数据 */\r\n        initData: function () {\r\n\r\n            /* 拉取数据需要使用的值 */\r\n            this.state = 0;\r\n            this.listSize = editor.getOpt('imageManagerListSize');\r\n            this.listIndex = 0;\r\n            this.listEnd = false;\r\n\r\n            /* 第一次拉取数据 */\r\n            this.getImageData();\r\n        },\r\n        /* 重置界面 */\r\n        reset: function() {\r\n            this.initContainer();\r\n            this.initData();\r\n        },\r\n        /* 向后台拉取图片列表数据 */\r\n        getImageData: function () {\r\n            var _this = this;\r\n\r\n            if(!_this.listEnd && !this.isLoadingData) {\r\n                this.isLoadingData = true;\r\n                var url = editor.getActionUrl(editor.getOpt('imageManagerActionName')),\r\n                    isJsonp = utils.isCrossDomainUrl(url);\r\n                ajax.request(url, {\r\n                    'timeout': 100000,\r\n                    'dataType': isJsonp ? 'jsonp':'',\r\n                    'data': utils.extend({\r\n                            start: this.listIndex,\r\n                            size: this.listSize\r\n                        }, editor.queryCommandValue('serverparam')),\r\n                    'method': 'get',\r\n                    'onsuccess': function (r) {\r\n                        try {\r\n                            var json = isJsonp ? r:eval('(' + r.responseText + ')');\r\n                            if (json.state == 'SUCCESS') {\r\n                                _this.pushData(json.list);\r\n                                _this.listIndex = parseInt(json.start) + parseInt(json.list.length);\r\n                                if(_this.listIndex >= json.total) {\r\n                                    _this.listEnd = true;\r\n                                }\r\n                                _this.isLoadingData = false;\r\n                            }\r\n                        } catch (e) {\r\n                            if(r.responseText.indexOf('ue_separate_ue') != -1) {\r\n                                var list = r.responseText.split(r.responseText);\r\n                                _this.pushData(list);\r\n                                _this.listIndex = parseInt(list.length);\r\n                                _this.listEnd = true;\r\n                                _this.isLoadingData = false;\r\n                            }\r\n                        }\r\n                    },\r\n                    'onerror': function () {\r\n                        _this.isLoadingData = false;\r\n                    }\r\n                });\r\n            }\r\n        },\r\n        /* 添加图片到列表界面上 */\r\n        pushData: function (list) {\r\n            var i, item, img, icon, _this = this,\r\n                urlPrefix = editor.getOpt('imageManagerUrlPrefix');\r\n            for (i = 0; i < list.length; i++) {\r\n                if(list[i] && list[i].url) {\r\n                    item = document.createElement('li');\r\n                    img = document.createElement('img');\r\n                    icon = document.createElement('span');\r\n\r\n                    domUtils.on(img, 'load', (function(image){\r\n                        return function(){\r\n                            _this.scale(image, image.parentNode.offsetWidth, image.parentNode.offsetHeight);\r\n                        }\r\n                    })(img));\r\n                    img.width = 113;\r\n                    img.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) );\r\n                    img.setAttribute('_src', urlPrefix + list[i].url);\r\n                    domUtils.addClass(icon, 'icon');\r\n\r\n                    item.appendChild(img);\r\n                    item.appendChild(icon);\r\n                    this.list.insertBefore(item, this.clearFloat);\r\n                }\r\n            }\r\n        },\r\n        /* 改变图片大小 */\r\n        scale: function (img, w, h, type) {\r\n            var ow = img.width,\r\n                oh = img.height;\r\n\r\n            if (type == 'justify') {\r\n                if (ow >= oh) {\r\n                    img.width = w;\r\n                    img.height = h * oh / ow;\r\n                    img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';\r\n                } else {\r\n                    img.width = w * ow / oh;\r\n                    img.height = h;\r\n                    img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';\r\n                }\r\n            } else {\r\n                if (ow >= oh) {\r\n                    img.width = w * ow / oh;\r\n                    img.height = h;\r\n                    img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';\r\n                } else {\r\n                    img.width = w;\r\n                    img.height = h * oh / ow;\r\n                    img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';\r\n                }\r\n            }\r\n        },\r\n        getInsertList: function () {\r\n            var i, lis = this.list.children, list = [], align = getAlign();\r\n            for (i = 0; i < lis.length; i++) {\r\n                if (domUtils.hasClass(lis[i], 'selected')) {\r\n                    var img = lis[i].firstChild,\r\n                        src = img.getAttribute('_src');\r\n                    list.push({\r\n                        src: src,\r\n                        _src: src,\r\n                        floatStyle: align\r\n                    });\r\n                }\r\n\r\n            }\r\n            return list;\r\n        }\r\n    };\r\n\r\n    dialog.onok = function () {\r\n        updateBackground();\r\n        editor.fireEvent('saveScene');\r\n    };\r\n    dialog.oncancel = function () {\r\n        editor.execCommand('background', backupStyle);\r\n    };\r\n\r\n})();"
  },
  {
    "path": "public/static/ueditor/dialogs/charts/chart.config.js",
    "content": "/*\n * 图表配置文件\n * */\n\n\n//不同类型的配置\nvar typeConfig = [\n    {\n        chart: {\n            type: 'line'\n        },\n        plotOptions: {\n            line: {\n                dataLabels: {\n                    enabled: false\n                },\n                enableMouseTracking: true\n            }\n        }\n    }, {\n        chart: {\n            type: 'line'\n        },\n        plotOptions: {\n            line: {\n                dataLabels: {\n                    enabled: true\n                },\n                enableMouseTracking: false\n            }\n        }\n    }, {\n        chart: {\n            type: 'area'\n        }\n    }, {\n        chart: {\n            type: 'bar'\n        }\n    }, {\n        chart: {\n            type: 'column'\n        }\n    }, {\n        chart: {\n            plotBackgroundColor: null,\n            plotBorderWidth: null,\n            plotShadow: false\n        },\n        plotOptions: {\n            pie: {\n                allowPointSelect: true,\n                cursor: 'pointer',\n                dataLabels: {\n                    enabled: true,\n                    color: '#000000',\n                    connectorColor: '#000000',\n                    formatter: function() {\n                        return '<b>'+ this.point.name +'</b>: '+ ( Math.round( this.point.percentage*100 ) / 100 ) +' %';\n                    }\n                }\n            }\n        }\n    }\n];\n"
  },
  {
    "path": "public/static/ueditor/dialogs/charts/charts.css",
    "content": "html, body {\n    width: 100%;\n    height: 100%;\n    margin: 0;\n    padding: 0;\n    overflow-x: hidden;\n}\n\n.main {\n    width: 100%;\n    overflow: hidden;\n}\n\n.table-view {\n    height: 100%;\n    float: left;\n    margin: 20px;\n    width: 40%;\n}\n\n.table-view .table-container {\n    width: 100%;\n    margin-bottom: 50px;\n    overflow: scroll;\n}\n\n.table-view th {\n    padding: 5px 10px;\n    background-color: #F7F7F7;\n}\n\n.table-view td {\n    width: 50px;\n    text-align: center;\n    padding:0;\n}\n\n.table-container input {\n    width: 40px;\n    padding: 5px;\n    border: none;\n    outline: none;\n}\n\n.table-view caption {\n    font-size: 18px;\n    text-align: left;\n}\n\n.charts-view {\n    /*margin-left: 49%!important;*/\n    width: 50%;\n    margin-left: 49%;\n    height: 400px;\n}\n\n.charts-container {\n    border-left: 1px solid #c3c3c3;\n}\n\n.charts-format fieldset {\n    padding-left: 20px;\n    margin-bottom: 50px;\n}\n\n.charts-format legend {\n    padding-left: 10px;\n    padding-right: 10px;\n}\n\n.format-item-container {\n    padding: 20px;\n}\n\n.format-item-container label {\n    display: block;\n    margin: 10px 0;\n}\n\n.charts-format .data-item {\n    border: 1px solid black;\n    outline: none;\n    padding: 2px 3px;\n}\n\n/* 图表类型 */\n\n.charts-type {\n    margin-top: 50px;\n    height: 300px;\n}\n\n.scroll-view {\n    border: 1px solid #c3c3c3;\n    border-left: none;\n    border-right: none;\n    overflow: hidden;\n}\n\n.scroll-container {\n    margin: 20px;\n    width: 100%;\n    overflow: hidden;\n}\n\n.scroll-bed {\n    width: 10000px;\n    _margin-top: 20px;\n    -webkit-transition: margin-left .5s ease;\n    -moz-transition: margin-left .5s ease;\n    transition: margin-left .5s ease;\n}\n\n.view-box {\n    display: inline-block;\n    *display: inline;\n    *zoom: 1;\n    margin-right: 20px;\n    border: 2px solid white;\n    line-height: 0;\n    overflow: hidden;\n    cursor: pointer;\n}\n\n.view-box img {\n    border: 1px solid #cecece;\n}\n\n.view-box.selected {\n    border-color: #7274A7;\n}\n\n.button-container {\n    margin-bottom: 20px;\n    text-align: center;\n}\n\n.button-container a {\n    display: inline-block;\n    width: 100px;\n    height: 25px;\n    line-height: 25px;\n    border: 1px solid #c2ccd1;\n    margin-right: 30px;\n    text-decoration: none;\n    color: black;\n    -webkit-border-radius: 2px;\n    -moz-border-radius: 2px;\n    border-radius: 2px;\n}\n\n.button-container a:HOVER {\n    background: #fcfcfc;\n}\n\n.button-container a:ACTIVE {\n    border-top-color: #c2ccd1;\n    box-shadow:inset 0 5px 4px -4px rgba(49, 49, 64, 0.1);\n}\n\n.edui-charts-not-data {\n    height: 100px;\n    line-height: 100px;\n    text-align: center;\n}"
  },
  {
    "path": "public/static/ueditor/dialogs/charts/charts.html",
    "content": "<!DOCTYPE html>\r\n<html>\r\n    <head>\r\n        <title>chart</title>\r\n        <meta chartset=\"utf-8\">\r\n        <link rel=\"stylesheet\" type=\"text/css\" href=\"charts.css\">\r\n        <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    </head>\r\n    <body>\r\n        <div class=\"main\">\r\n            <div class=\"table-view\">\r\n                <h3><var id=\"lang_data_source\"></var></h3>\r\n                <div id=\"tableContainer\" class=\"table-container\"></div>\r\n                <h3><var id=\"lang_chart_format\"></var></h3>\r\n                <form name=\"data-form\">\r\n                    <div class=\"charts-format\">\r\n                        <fieldset>\r\n                            <legend><var id=\"lang_data_align\"></var></legend>\r\n                            <div class=\"format-item-container\">\r\n                                <label>\r\n                                    <input type=\"radio\" class=\"format-ctrl not-pie-item\" name=\"charts-format\" value=\"1\" checked=\"checked\">\r\n                                    <var id=\"lang_chart_align_same\"></var>\r\n                                </label>\r\n                                <label>\r\n                                    <input type=\"radio\" class=\"format-ctrl not-pie-item\" name=\"charts-format\" value=\"-1\">\r\n                                    <var id=\"lang_chart_align_reverse\"></var>\r\n                                </label>\r\n                                <br>\r\n                            </div>\r\n                        </fieldset>\r\n                        <fieldset>\r\n                            <legend><var id=\"lang_chart_title\"></var></legend>\r\n                            <div class=\"format-item-container\">\r\n                                <label>\r\n                                    <var id=\"lang_chart_main_title\"></var><input type=\"text\" name=\"title\" class=\"data-item\">\r\n                                </label>\r\n                                <label>\r\n                                    <var id=\"lang_chart_sub_title\"></var><input type=\"text\" name=\"sub-title\" class=\"data-item not-pie-item\">\r\n                                </label>\r\n                                <label>\r\n                                    <var id=\"lang_chart_x_title\"></var><input type=\"text\" name=\"x-title\" class=\"data-item not-pie-item\">\r\n                                </label>\r\n                                <label>\r\n                                    <var id=\"lang_chart_y_title\"></var><input type=\"text\" name=\"y-title\" class=\"data-item not-pie-item\">\r\n                                </label>\r\n                            </div>\r\n                        </fieldset>\r\n                        <fieldset>\r\n                            <legend><var id=\"lang_chart_tip\"></var></legend>\r\n                            <div class=\"format-item-container\">\r\n                                <label>\r\n                                    <var id=\"lang_cahrt_tip_prefix\"></var>\r\n                                    <input type=\"text\" id=\"tipInput\" name=\"tip\" class=\"data-item\" disabled=\"disabled\">\r\n                                </label>\r\n                                <p><var id=\"lang_cahrt_tip_description\"></var></p>\r\n                            </div>\r\n                        </fieldset>\r\n                        <fieldset>\r\n                            <legend><var id=\"lang_chart_data_unit\"></var></legend>\r\n                            <div class=\"format-item-container\">\r\n                                <label><var id=\"lang_chart_data_unit_title\"></var><input type=\"text\" name=\"unit\" class=\"data-item\"></label>\r\n                                <p><var id=\"lang_chart_data_unit_description\"></var></p>\r\n                            </div>\r\n                        </fieldset>\r\n                    </div>\r\n                </form>\r\n            </div>\r\n            <div class=\"charts-view\">\r\n                <div id=\"chartsContainer\" class=\"charts-container\"></div>\r\n                <div id=\"chartsType\" class=\"charts-type\">\r\n                    <h3><var id=\"lang_chart_type\"></var></h3>\r\n                    <div class=\"scroll-view\">\r\n                        <div class=\"scroll-container\">\r\n                            <div id=\"scrollBed\" class=\"scroll-bed\"></div>\r\n                        </div>\r\n                        <div id=\"buttonContainer\" class=\"button-container\">\r\n                            <a href=\"#\" data-title=\"prev\"><var id=\"lang_prev_btn\"></var></a>\r\n                            <a href=\"#\" data-title=\"next\"><var id=\"lang_next_btn\"></var></a>\r\n                        </div>\r\n                    </div>\r\n                </div>\r\n            </div>\r\n        </div>\r\n        <script src=\"../../third-party/jquery-1.10.2.min.js\"></script>\r\n        <script src=\"../../third-party/highcharts/highcharts.js\"></script>\r\n        <script src=\"chart.config.js\"></script>\r\n        <script src=\"charts.js\"></script>\r\n    </body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/charts/charts.js",
    "content": "/*\n * 图片转换对话框脚本\n **/\n\nvar tableData = [],\n    //编辑器页面table\n    editorTable = null,\n    chartsConfig = window.typeConfig,\n    resizeTimer = null,\n    //初始默认图表类型\n    currentChartType = 0;\n\nwindow.onload = function () {\n\n    editorTable = domUtils.findParentByTagName( editor.selection.getRange().startContainer, 'table', true);\n\n    //未找到表格， 显示错误页面\n    if ( !editorTable ) {\n        document.body.innerHTML = \"<div class='edui-charts-not-data'>未找到数据</div>\";\n        return;\n    }\n\n    //初始化图表类型选择\n    initChartsTypeView();\n    renderTable( editorTable );\n    initEvent();\n    initUserConfig( editorTable.getAttribute( \"data-chart\" ) );\n    $( \"#scrollBed .view-box:eq(\"+ currentChartType +\")\" ).trigger( \"click\" );\n    updateViewType( currentChartType );\n\n    dialog.addListener( \"resize\", function () {\n\n        if ( resizeTimer != null ) {\n            window.clearTimeout( resizeTimer );\n        }\n\n        resizeTimer = window.setTimeout( function () {\n\n            resizeTimer = null;\n\n            renderCharts();\n\n        }, 500 );\n\n    } );\n\n};\n\nfunction initChartsTypeView () {\n\n    var contents = [];\n\n    for ( var i = 0, len = chartsConfig.length; i<len; i++ ) {\n\n        contents.push( '<div class=\"view-box\" data-chart-type=\"'+ i +'\"><img width=\"300\" src=\"images/charts'+ i +'.png\"></div>' );\n\n    }\n\n    $( \"#scrollBed\" ).html( contents.join( \"\" ) );\n\n}\n\n//渲染table， 以便用户修改数据\nfunction renderTable ( table ) {\n\n    var tableHtml = [];\n\n    //构造数据\n    for ( var i = 0, row; row = table.rows[ i ]; i++ ) {\n\n        tableData[ i ] = [];\n        tableHtml[ i ] = [];\n\n        for ( var j = 0, cell; cell = row.cells[ j ]; j++ ) {\n\n            var value = getCellValue( cell );\n\n            if ( i > 0 && j > 0 ) {\n                value = +value;\n            }\n\n            if ( i === 0 || j === 0 ) {\n                tableHtml[ i ].push( '<th>'+ value +'</th>' );\n            } else {\n                tableHtml[ i ].push( '<td><input type=\"text\" class=\"data-item\" value=\"'+ value +'\"></td>' );\n            }\n\n            tableData[ i ][ j ] = value;\n\n        }\n\n        tableHtml[ i ] = tableHtml[ i ].join( \"\" );\n\n    }\n\n    //draw 表格\n    $( \"#tableContainer\" ).html( '<table id=\"showTable\" border=\"1\"><tbody><tr>'+ tableHtml.join( \"</tr><tr>\" ) +'</tr></tbody></table>' );\n\n}\n\n/*\n * 根据表格已有的图表属性初始化当前图表属性\n */\nfunction initUserConfig ( config ) {\n\n    var parsedConfig = {};\n\n    if ( !config ) {\n        return;\n    }\n\n    config = config.split( \";\" );\n\n    $.each( config, function ( index, item ) {\n\n        item = item.split( \":\" );\n        parsedConfig[ item[ 0 ] ] = item[ 1 ];\n\n    } );\n\n    setUserConfig( parsedConfig );\n\n}\n\nfunction initEvent () {\n\n    var cacheValue = null,\n        //图表类型数\n        typeViewCount = chartsConfig.length- 1,\n        $chartsTypeViewBox = $( '#scrollBed .view-box' );\n\n    $( \".charts-format\" ).delegate( \".format-ctrl\", \"change\", function () {\n\n        renderCharts();\n\n    } )\n\n    $( \".table-view\" ).delegate( \".data-item\", \"focus\", function () {\n\n        cacheValue = this.value;\n\n    } ).delegate( \".data-item\", \"blur\", function () {\n\n        if ( this.value !== cacheValue ) {\n            renderCharts();\n        }\n\n        cacheValue = null;\n\n    } );\n\n    $( \"#buttonContainer\" ).delegate( \"a\", \"click\", function (e) {\n\n        e.preventDefault();\n\n        if ( this.getAttribute( \"data-title\" ) === 'prev' ) {\n\n            if ( currentChartType > 0 ) {\n                currentChartType--;\n                updateViewType( currentChartType );\n            }\n\n        } else {\n\n            if ( currentChartType < typeViewCount ) {\n                currentChartType++;\n                updateViewType( currentChartType );\n            }\n\n        }\n\n    } );\n\n    //图表类型变化\n    $( '#scrollBed' ).delegate( \".view-box\", \"click\", function (e) {\n\n        var index = $( this ).attr( \"data-chart-type\" );\n        $chartsTypeViewBox.removeClass( \"selected\" );\n        $( $chartsTypeViewBox[ index ] ).addClass( \"selected\" );\n\n        currentChartType = index | 0;\n\n        //饼图， 禁用部分配置\n        if ( currentChartType === chartsConfig.length - 1 ) {\n\n            disableNotPieConfig();\n\n        //启用完整配置\n        } else {\n\n            enableNotPieConfig();\n\n        }\n\n        renderCharts();\n\n    } );\n\n}\n\nfunction renderCharts () {\n\n    var data = collectData();\n\n    $('#chartsContainer').highcharts( $.extend( {}, chartsConfig[ currentChartType ], {\n\n        credits: {\n            enabled: false\n        },\n        exporting: {\n            enabled: false\n        },\n        title: {\n            text: data.title,\n            x: -20 //center\n        },\n        subtitle: {\n            text: data.subTitle,\n            x: -20\n        },\n        xAxis: {\n            title: {\n                text: data.xTitle\n            },\n            categories: data.categories\n        },\n        yAxis: {\n            title: {\n                text: data.yTitle\n            },\n            plotLines: [{\n                value: 0,\n                width: 1,\n                color: '#808080'\n            }]\n        },\n        tooltip: {\n            enabled: true,\n            valueSuffix: data.suffix\n        },\n        legend: {\n            layout: 'vertical',\n            align: 'right',\n            verticalAlign: 'middle',\n            borderWidth: 1\n        },\n        series: data.series\n\n    } ));\n\n}\n\nfunction updateViewType ( index ) {\n\n    $( \"#scrollBed\" ).css( 'marginLeft', -index*324+'px' );\n\n}\n\nfunction collectData () {\n\n    var form = document.forms[ 'data-form' ],\n        data = null;\n\n    if ( currentChartType !== chartsConfig.length - 1 ) {\n\n        data = getSeriesAndCategories();\n        $.extend( data, getUserConfig() );\n\n    //饼图数据格式\n    } else {\n        data = getSeriesForPieChart();\n        data.title = form[ 'title' ].value;\n        data.suffix = form[ 'unit' ].value;\n    }\n\n    return data;\n\n}\n\n/**\n * 获取用户配置信息\n */\nfunction getUserConfig () {\n\n    var form = document.forms[ 'data-form' ],\n        info = {\n            title: form[ 'title' ].value,\n            subTitle: form[ 'sub-title' ].value,\n            xTitle: form[ 'x-title' ].value,\n            yTitle: form[ 'y-title' ].value,\n            suffix: form[ 'unit' ].value,\n            //数据对齐方式\n            tableDataFormat: getTableDataFormat (),\n            //饼图提示文字\n            tip: $( \"#tipInput\" ).val()\n        };\n\n    return info;\n\n}\n\nfunction setUserConfig ( config ) {\n\n    var form = document.forms[ 'data-form' ];\n\n    config.title && ( form[ 'title' ].value = config.title );\n    config.subTitle && ( form[ 'sub-title' ].value = config.subTitle );\n    config.xTitle && ( form[ 'x-title' ].value = config.xTitle );\n    config.yTitle && ( form[ 'y-title' ].value = config.yTitle );\n    config.suffix && ( form[ 'unit' ].value = config.suffix );\n    config.dataFormat == \"-1\" && ( form[ 'charts-format' ][ 1 ].checked = true );\n    config.tip && ( form[ 'tip' ].value = config.tip );\n    currentChartType = config.chartType || 0;\n\n}\n\nfunction getSeriesAndCategories () {\n\n    var form = document.forms[ 'data-form' ],\n        series = [],\n        categories = [],\n        tmp = [],\n        tableData = getTableData();\n\n    //反转数据\n    if ( getTableDataFormat() === \"-1\" ) {\n\n        for ( var i = 0, len = tableData.length; i < len; i++ ) {\n\n            for ( var j = 0, jlen = tableData[ i ].length; j < jlen; j++ ) {\n\n                if ( !tmp[ j ] ) {\n                    tmp[ j ] = [];\n                }\n\n                tmp[ j ][ i ] = tableData[ i ][ j ];\n\n            }\n\n        }\n\n        tableData = tmp;\n\n    }\n\n    categories = tableData[0].slice( 1 );\n\n    for ( var i = 1, data; data = tableData[ i ]; i++ ) {\n\n        series.push( {\n            name: data[ 0 ],\n            data: data.slice( 1 )\n        } );\n\n    }\n\n    return {\n        series: series,\n        categories: categories\n    };\n\n}\n\n/*\n * 获取数据源数据对齐方式\n */\nfunction getTableDataFormat () {\n\n    var form = document.forms[ 'data-form' ],\n        items = form['charts-format'];\n\n    return items[ 0 ].checked ? items[ 0 ].value : items[ 1 ].value;\n\n}\n\n/*\n * 禁用非饼图类型的配置项\n */\nfunction disableNotPieConfig() {\n\n    updateConfigItem( 'disable' );\n\n}\n\n/*\n * 启用非饼图类型的配置项\n */\nfunction enableNotPieConfig() {\n\n    updateConfigItem( 'enable' );\n\n}\n\nfunction updateConfigItem ( value ) {\n\n    var table = $( \"#showTable\" )[ 0 ],\n        isDisable = value === 'disable' ? true : false;\n\n    //table中的input处理\n    for ( var i = 2 , row; row = table.rows[ i ]; i++ ) {\n\n        for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) {\n\n            $( \"input\", cell ).attr( \"disabled\", isDisable );\n\n        }\n\n    }\n\n    //其他项处理\n    $( \"input.not-pie-item\" ).attr( \"disabled\", isDisable );\n    $( \"#tipInput\" ).attr( \"disabled\", !isDisable )\n\n}\n\n/*\n * 获取饼图数据\n * 饼图的数据只取第一行的\n **/\nfunction getSeriesForPieChart () {\n\n    var series = {\n            type: 'pie',\n            name: $(\"#tipInput\").val(),\n            data: []\n        },\n        tableData = getTableData();\n\n\n    for ( var j = 1, jlen = tableData[ 0 ].length; j < jlen; j++ ) {\n\n        var title = tableData[ 0 ][ j ],\n            val = tableData[ 1 ][ j ];\n\n        series.data.push( [ title, val ] );\n\n    }\n\n    return {\n        series: [ series ]\n    };\n\n}\n\nfunction getTableData () {\n\n    var table = document.getElementById( \"showTable\" ),\n        xCount = table.rows[0].cells.length - 1,\n        values = getTableInputValue();\n\n    for ( var i = 0, value; value = values[ i ]; i++ ) {\n\n        tableData[ Math.floor( i / xCount ) + 1 ][ i % xCount + 1 ] = values[ i ];\n\n    }\n\n    return tableData;\n\n}\n\nfunction getTableInputValue () {\n\n    var table = document.getElementById( \"showTable\" ),\n        inputs = table.getElementsByTagName( \"input\" ),\n        values = [];\n\n    for ( var i = 0, input; input = inputs[ i ]; i++ ) {\n        values.push( input.value | 0 );\n    }\n\n    return values;\n\n}\n\nfunction getCellValue ( cell ) {\n\n    var value = utils.trim( ( cell.innerText || cell.textContent || '' ) );\n\n    return value.replace( new RegExp( UE.dom.domUtils.fillChar, 'g' ), '' ).replace( /^\\s+|\\s+$/g, '' );\n\n}\n\n\n//dialog确认事件\ndialog.onok = function () {\n\n    //收集信息\n    var form = document.forms[ 'data-form' ],\n        info = getUserConfig();\n\n    //添加图表类型\n    info.chartType = currentChartType;\n\n    //同步表格数据到编辑器\n    syncTableData();\n\n    //执行图表命令\n    editor.execCommand( 'charts', info );\n\n};\n\n/*\n * 同步图表编辑视图的表格数据到编辑器里的原始表格\n */\nfunction syncTableData () {\n\n    var tableData = getTableData();\n\n    for ( var i = 1, row; row = editorTable.rows[ i ]; i++ ) {\n\n        for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) {\n\n            cell.innerHTML = tableData[ i ] [ j ];\n\n        }\n\n    }\n\n}"
  },
  {
    "path": "public/static/ueditor/dialogs/emotion/emotion.css",
    "content": ".jd img{\r\n    background:transparent url(images/jxface2.gif?v=1.1) no-repeat scroll left top;\r\n    cursor:pointer;width:35px;height:35px;display:block;\r\n}\r\n.pp img{\r\n    background:transparent url(images/fface.gif?v=1.1) no-repeat scroll left top;\r\n    cursor:pointer;width:25px;height:25px;display:block;\r\n}\r\n.ldw img{\r\n    background:transparent url(images/wface.gif?v=1.1) no-repeat scroll left top;\r\n    cursor:pointer;width:35px;height:35px;display:block;\r\n}\r\n.tsj img{\r\n    background:transparent url(images/tface.gif?v=1.1) no-repeat scroll left top;\r\n    cursor:pointer;width:35px;height:35px;display:block;\r\n}\r\n.cat img{\r\n    background:transparent url(images/cface.gif?v=1.1) no-repeat scroll left top;\r\n    cursor:pointer;width:35px;height:35px;display:block;\r\n}\r\n.bb img{\r\n    background:transparent url(images/bface.gif?v=1.1) no-repeat scroll left top;\r\n    cursor:pointer;width:35px;height:35px;display:block;\r\n}\r\n.youa img{\r\n    background:transparent url(images/yface.gif?v=1.1) no-repeat scroll left top;\r\n    cursor:pointer;width:35px;height:35px;display:block;\r\n}\r\n\r\n.smileytable td {height: 37px;}\r\n#tabPanel{margin-left:5px;overflow: hidden;}\r\n#tabContent {float:left;background:#FFFFFF;}\r\n#tabContent div{display: none;width:480px;overflow:hidden;}\r\n#tabIconReview.show{left:17px;display:block;}\r\n.menuFocus{background:#ACCD3C;}\r\n.menuDefault{background:#FFFFFF;}\r\n#tabIconReview{position:absolute;left:406px;left:398px \\9;top:41px;z-index:65533;width:90px;height:76px;}\r\nimg.review{width:90px;height:76px;border:2px solid #9cb945;background:#FFFFFF;background-position:center;background-repeat:no-repeat;}\r\n\r\n.wrapper .tabbody{position:relative;float:left;clear:both;padding:10px;width: 95%;}\r\n.tabbody table{width: 100%;}\r\n.tabbody td{border:1px solid #BAC498;}\r\n.tabbody td span{display: block;zoom:1;padding:0 4px;}"
  },
  {
    "path": "public/static/ueditor/dialogs/emotion/emotion.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\" >\r\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\r\n<head>\r\n    <title></title>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\r\n    <meta name=\"robots\" content=\"noindex, nofollow\"/>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"emotion.css\">\r\n</head>\r\n<body>\r\n<div id=\"tabPanel\" class=\"wrapper\">\r\n    <div id=\"tabHeads\" class=\"tabhead\">\r\n        <span><var id=\"lang_input_choice\"></var></span>\r\n        <span><var id=\"lang_input_Tuzki\"></var></span>\r\n        <span><var id=\"lang_input_lvdouwa\"></var></span>\r\n        <span><var id=\"lang_input_BOBO\"></var></span>\r\n        <span><var id=\"lang_input_babyCat\"></var></span>\r\n        <span><var id=\"lang_input_bubble\"></var></span>\r\n        <span><var id=\"lang_input_youa\"></var></span>\r\n    </div>\r\n    <div id=\"tabBodys\" class=\"tabbody\">\r\n        <div id=\"tab0\"></div>\r\n        <div id=\"tab1\"></div>\r\n        <div id=\"tab2\"></div>\r\n        <div id=\"tab3\"></div>\r\n        <div id=\"tab4\"></div>\r\n        <div id=\"tab5\"></div>\r\n        <div id=\"tab6\"></div>\r\n    </div>\r\n</div>\r\n<div id=\"tabIconReview\">\r\n    <img id='faceReview' class='review' src=\"../../themes/default/images/spacer.gif\"/>\r\n</div>\r\n<script type=\"text/javascript\" src=\"emotion.js\"></script>\r\n<script type=\"text/javascript\">\r\n    var emotion = {\r\n        tabNum:7, //切换面板数量\r\n        SmilmgName:{ tab0:['j_00', 84], tab1:['t_00', 40], tab2:['w_00', 52], tab3:['B_00', 63], tab4:['C_00', 20], tab5:['i_f', 50], tab6:['y_00', 40] }, //图片前缀名\r\n        imageFolders:{ tab0:'jx2/', tab1:'tsj/', tab2:'ldw/', tab3:'bobo/', tab4:'babycat/', tab5:'face/', tab6:'youa/'}, //图片对应文件夹路径\r\n        imageCss:{tab0:'jd', tab1:'tsj', tab2:'ldw', tab3:'bb', tab4:'cat', tab5:'pp', tab6:'youa'}, //图片css类名\r\n        imageCssOffset:{tab0:35, tab1:35, tab2:35, tab3:35, tab4:35, tab5:25, tab6:35}, //图片偏移\r\n        SmileyInfor:{\r\n            tab0:['Kiss', 'Love', 'Yeah', '啊！', '背扭', '顶', '抖胸', '88', '汗', '瞌睡', '鲁拉', '拍砖', '揉脸', '生日快乐', '大笑', '瀑布汗~', '惊讶', '臭美', '傻笑', '抛媚眼', '发怒', '打酱油', '俯卧撑', '气愤', '?', '吻', '怒', '胜利', 'HI', 'KISS', '不说', '不要', '扯花', '大心', '顶', '大惊', '飞吻', '鬼脸', '害羞', '口水', '狂哭', '来', '发财了', '吃西瓜', '套牢', '害羞', '庆祝', '我来了', '敲打', '晕了', '胜利', '臭美', '被打了', '贪吃', '迎接', '酷', '微笑', '亲吻', '调皮', '惊恐', '耍酷', '发火', '害羞', '汗水', '大哭', '', '加油', '困', '你NB', '晕倒', '开心', '偷笑', '大哭', '滴汗', '叹气', '超赞', '??', '飞吻', '天使', '撒花', '生气', '被砸', '吓傻', '随意吐'],\r\n            tab1:['Kiss', 'Love', 'Yeah', '啊！', '背扭', '顶', '抖胸', '88', '汗', '瞌睡', '鲁拉', '拍砖', '揉脸', '生日快乐', '摊手', '睡觉', '瘫坐', '无聊', '星星闪', '旋转', '也不行', '郁闷', '正Music', '抓墙', '撞墙至死', '歪头', '戳眼', '飘过', '互相拍砖', '砍死你', '扔桌子', '少林寺', '什么？', '转头', '我爱牛奶', '我踢', '摇晃', '晕厥', '在笼子里', '震荡'],\r\n            tab2:['大笑', '瀑布汗~', '惊讶', '臭美', '傻笑', '抛媚眼', '发怒', '我错了', 'money', '气愤', '挑逗', '吻', '怒', '胜利', '委屈', '受伤', '说啥呢？', '闭嘴', '不', '逗你玩儿', '飞吻', '眩晕', '魔法', '我来了', '睡了', '我打', '闭嘴', '打', '打晕了', '刷牙', '爆揍', '炸弹', '倒立', '刮胡子', '邪恶的笑', '不要不要', '爱恋中', '放大仔细看', '偷窥', '超高兴', '晕', '松口气', '我跑', '享受', '修养', '哭', '汗', '啊~', '热烈欢迎', '打酱油', '俯卧撑', '?'],\r\n            tab3:['HI', 'KISS', '不说', '不要', '扯花', '大心', '顶', '大惊', '飞吻', '鬼脸', '害羞', '口水', '狂哭', '来', '泪眼', '流泪', '生气', '吐舌', '喜欢', '旋转', '再见', '抓狂', '汗', '鄙视', '拜', '吐血', '嘘', '打人', '蹦跳', '变脸', '扯肉', '吃To', '吃花', '吹泡泡糖', '大变身', '飞天舞', '回眸', '可怜', '猛抽', '泡泡', '苹果', '亲', '', '骚舞', '烧香', '睡', '套娃娃', '捅捅', '舞倒', '西红柿', '爱慕', '摇', '摇摆', '杂耍', '招财', '被殴', '被球闷', '大惊', '理想', '欧打', '呕吐', '碎', '吐痰'],\r\n            tab4:['发财了', '吃西瓜', '套牢', '害羞', '庆祝', '我来了', '敲打', '晕了', '胜利', '臭美', '被打了', '贪吃', '迎接', '酷', '顶', '幸运', '爱心', '躲', '送花', '选择'],\r\n            tab5:['微笑', '亲吻', '调皮', '惊讶', '耍酷', '发火', '害羞', '汗水', '大哭', '得意', '鄙视', '困', '夸奖', '晕倒', '疑问', '媒婆', '狂吐', '青蛙', '发愁', '亲吻', '', '爱心', '心碎', '玫瑰', '礼物', '哭', '奸笑', '可爱', '得意', '呲牙', '暴汗', '楚楚可怜', '困', '哭', '生气', '惊讶', '口水', '彩虹', '夜空', '太阳', '钱钱', '灯泡', '咖啡', '蛋糕', '音乐', '爱', '胜利', '赞', '鄙视', 'OK'],\r\n            tab6:['男兜', '女兜', '开心', '乖乖', '偷笑', '大笑', '抽泣', '大哭', '无奈', '滴汗', '叹气', '狂晕', '委屈', '超赞', '??', '疑问', '飞吻', '天使', '撒花', '生气', '被砸', '口水', '泪奔', '吓傻', '吐舌头', '点头', '随意吐', '旋转', '困困', '鄙视', '狂顶', '篮球', '再见', '欢迎光临', '恭喜发财', '稍等', '我在线', '恕不议价', '库房有货', '货在路上']\r\n        }\r\n    };\r\n</script>\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/emotion/emotion.js",
    "content": "window.onload = function () {\r\n    editor.setOpt({\r\n        emotionLocalization:false\r\n    });\r\n\r\n    emotion.SmileyPath = editor.options.emotionLocalization === true ? 'images/' : \"http://img.baidu.com/hi/\";\r\n    emotion.SmileyBox = createTabList( emotion.tabNum );\r\n    emotion.tabExist = createArr( emotion.tabNum );\r\n\r\n    initImgName();\r\n    initEvtHandler( \"tabHeads\" );\r\n};\r\n\r\nfunction initImgName() {\r\n    for ( var pro in emotion.SmilmgName ) {\r\n        var tempName = emotion.SmilmgName[pro],\r\n                tempBox = emotion.SmileyBox[pro],\r\n                tempStr = \"\";\r\n\r\n        if ( tempBox.length ) return;\r\n        for ( var i = 1; i <= tempName[1]; i++ ) {\r\n            tempStr = tempName[0];\r\n            if ( i < 10 ) tempStr = tempStr + '0';\r\n            tempStr = tempStr + i + '.gif';\r\n            tempBox.push( tempStr );\r\n        }\r\n    }\r\n}\r\n\r\nfunction initEvtHandler( conId ) {\r\n    var tabHeads = $G( conId );\r\n    for ( var i = 0, j = 0; i < tabHeads.childNodes.length; i++ ) {\r\n        var tabObj = tabHeads.childNodes[i];\r\n        if ( tabObj.nodeType == 1 ) {\r\n            domUtils.on( tabObj, \"click\", (function ( index ) {\r\n                return function () {\r\n                    switchTab( index );\r\n                };\r\n            })( j ) );\r\n            j++;\r\n        }\r\n    }\r\n    switchTab( 0 );\r\n    $G( \"tabIconReview\" ).style.display = 'none';\r\n}\r\n\r\nfunction InsertSmiley( url, evt ) {\r\n    var obj = {\r\n        src:editor.options.emotionLocalization ? editor.options.UEDITOR_HOME_URL + \"dialogs/emotion/\" + url : url\r\n    };\r\n    obj._src = obj.src;\r\n    editor.execCommand( 'insertimage', obj );\r\n    if ( !evt.ctrlKey ) {\r\n        dialog.popup.hide();\r\n    }\r\n}\r\n\r\nfunction switchTab( index ) {\r\n\r\n    autoHeight( index );\r\n    if ( emotion.tabExist[index] == 0 ) {\r\n        emotion.tabExist[index] = 1;\r\n        createTab( 'tab' + index );\r\n    }\r\n    //获取呈现元素句柄数组\r\n    var tabHeads = $G( \"tabHeads\" ).getElementsByTagName( \"span\" ),\r\n            tabBodys = $G( \"tabBodys\" ).getElementsByTagName( \"div\" ),\r\n            i = 0, L = tabHeads.length;\r\n    //隐藏所有呈现元素\r\n    for ( ; i < L; i++ ) {\r\n        tabHeads[i].className = \"\";\r\n        tabBodys[i].style.display = \"none\";\r\n    }\r\n    //显示对应呈现元素\r\n    tabHeads[index].className = \"focus\";\r\n    tabBodys[index].style.display = \"block\";\r\n}\r\n\r\nfunction autoHeight( index ) {\r\n    var iframe = dialog.getDom( \"iframe\" ),\r\n            parent = iframe.parentNode.parentNode;\r\n    switch ( index ) {\r\n        case 0:\r\n            iframe.style.height = \"380px\";\r\n            parent.style.height = \"392px\";\r\n            break;\r\n        case 1:\r\n            iframe.style.height = \"220px\";\r\n            parent.style.height = \"232px\";\r\n            break;\r\n        case 2:\r\n            iframe.style.height = \"260px\";\r\n            parent.style.height = \"272px\";\r\n            break;\r\n        case 3:\r\n            iframe.style.height = \"300px\";\r\n            parent.style.height = \"312px\";\r\n            break;\r\n        case 4:\r\n            iframe.style.height = \"140px\";\r\n            parent.style.height = \"152px\";\r\n            break;\r\n        case 5:\r\n            iframe.style.height = \"260px\";\r\n            parent.style.height = \"272px\";\r\n            break;\r\n        case 6:\r\n            iframe.style.height = \"230px\";\r\n            parent.style.height = \"242px\";\r\n            break;\r\n        default:\r\n\r\n    }\r\n}\r\n\r\n\r\nfunction createTab( tabName ) {\r\n    var faceVersion = \"?v=1.1\", //版本号\r\n            tab = $G( tabName ), //获取将要生成的Div句柄\r\n            imagePath = emotion.SmileyPath + emotion.imageFolders[tabName], //获取显示表情和预览表情的路径\r\n            positionLine = 11 / 2, //中间数\r\n            iWidth = iHeight = 35, //图片长宽\r\n            iColWidth = 3, //表格剩余空间的显示比例\r\n            tableCss = emotion.imageCss[tabName],\r\n            cssOffset = emotion.imageCssOffset[tabName],\r\n            textHTML = ['<table class=\"smileytable\">'],\r\n            i = 0, imgNum = emotion.SmileyBox[tabName].length, imgColNum = 11, faceImage,\r\n            sUrl, realUrl, posflag, offset, infor;\r\n\r\n    for ( ; i < imgNum; ) {\r\n        textHTML.push( '<tr>' );\r\n        for ( var j = 0; j < imgColNum; j++, i++ ) {\r\n            faceImage = emotion.SmileyBox[tabName][i];\r\n            if ( faceImage ) {\r\n                sUrl = imagePath + faceImage + faceVersion;\r\n                realUrl = imagePath + faceImage;\r\n                posflag = j < positionLine ? 0 : 1;\r\n                offset = cssOffset * i * (-1) - 1;\r\n                infor = emotion.SmileyInfor[tabName][i];\r\n\r\n                textHTML.push( '<td  class=\"' + tableCss + '\"   border=\"1\" width=\"' + iColWidth + '%\" style=\"border-collapse:collapse;\" align=\"center\"  bgcolor=\"transparent\" onclick=\"InsertSmiley(\\'' + realUrl.replace( /'/g, \"\\\\'\" ) + '\\',event)\" onmouseover=\"over(this,\\'' + sUrl + '\\',\\'' + posflag + '\\')\" onmouseout=\"out(this)\">' );\r\n                textHTML.push( '<span>' );\r\n                textHTML.push( '<img  style=\"background-position:left ' + offset + 'px;\" title=\"' + infor + '\" src=\"' + emotion.SmileyPath + (editor.options.emotionLocalization ? '0.gif\" width=\"' : 'default/0.gif\" width=\"') + iWidth + '\" height=\"' + iHeight + '\"></img>' );\r\n                textHTML.push( '</span>' );\r\n            } else {\r\n                textHTML.push( '<td width=\"' + iColWidth + '%\"   bgcolor=\"#FFFFFF\">' );\r\n            }\r\n            textHTML.push( '</td>' );\r\n        }\r\n        textHTML.push( '</tr>' );\r\n    }\r\n    textHTML.push( '</table>' );\r\n    textHTML = textHTML.join( \"\" );\r\n    tab.innerHTML = textHTML;\r\n}\r\n\r\nfunction over( td, srcPath, posFlag ) {\r\n    td.style.backgroundColor = \"#ACCD3C\";\r\n    $G( 'faceReview' ).style.backgroundImage = \"url(\" + srcPath + \")\";\r\n    if ( posFlag == 1 ) $G( \"tabIconReview\" ).className = \"show\";\r\n    $G( \"tabIconReview\" ).style.display = 'block';\r\n}\r\n\r\nfunction out( td ) {\r\n    td.style.backgroundColor = \"transparent\";\r\n    var tabIconRevew = $G( \"tabIconReview\" );\r\n    tabIconRevew.className = \"\";\r\n    tabIconRevew.style.display = 'none';\r\n}\r\n\r\nfunction createTabList( tabNum ) {\r\n    var obj = {};\r\n    for ( var i = 0; i < tabNum; i++ ) {\r\n        obj[\"tab\" + i] = [];\r\n    }\r\n    return obj;\r\n}\r\n\r\nfunction createArr( tabNum ) {\r\n    var arr = [];\r\n    for ( var i = 0; i < tabNum; i++ ) {\r\n        arr[i] = 0;\r\n    }\r\n    return arr;\r\n}\r\n\r\n"
  },
  {
    "path": "public/static/ueditor/dialogs/gmap/gmap.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n        \"http://www.w3.org/TR/html4/loose.dtd\">\r\n<html>\r\n<head>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n    <title></title>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <style type=\"text/css\">\r\n        .content{width:530px; height: 350px;margin: 10px auto;}\r\n        .content table{width: 100%}\r\n        .content table td{vertical-align: middle;}\r\n        #address{width:220px;height:21px;background: #FFF;border:1px solid #d7d7d7; line-height: 21px;}\r\n    </style>\r\n    <script type=\"text/javascript\" src=\"http://maps.googleapis.com/maps/api/js?sensor=false\"></script>\r\n</head>\r\n<body>\r\n<div class=\"content\">\r\n    <table>\r\n        <tr>\r\n            <td><label for=\"address\"><var id=\"lang_input_address\"></var></label></td>\r\n            <td><input id=\"address\" type=\"text\" /></td>\r\n            <td><a id=\"doSearch\" href=\"javascript:void(0)\" class=\"button\"><var id=\"lang_input_search\"></var></a></td>\r\n        </tr>\r\n    </table>\r\n    <div id=\"container\" style=\"width: 100%; height: 340px;margin: 5px auto; border: 1px solid gray;\"></div>\r\n</div>\r\n<script type=\"text/javascript\">\r\n    domUtils.on(window,\"load\",function(){\r\n        var map = new google.maps.Map(document.getElementById('container'), {\r\n                zoom: 3,\r\n                streetViewControl: false,\r\n                scaleControl: true,\r\n                mapTypeId: google.maps.MapTypeId.ROADMAP\r\n            });\r\n            var imgcss;\r\n            var marker = new google.maps.Marker({\r\n                map: map,\r\n                draggable: true\r\n            });\r\n            function doSearch(){\r\n                var address = document.getElementById('address').value;\r\n                var geocoder = new google.maps.Geocoder();\r\n                geocoder.geocode( { 'address': address}, function (results, status) {\r\n                    if (status == google.maps.GeocoderStatus.OK) {\r\n                        var bounds = results[0].geometry.viewport;\r\n                        map.fitBounds(bounds);\r\n                        marker.setPosition(results[0].geometry.location);\r\n                        marker.setTitle(address);\r\n                    } else alert(lang.searchError);\r\n                });\r\n            }\r\n            $G('address').onkeydown = function (evt){\r\n                evt = evt || event;\r\n                if (evt.keyCode == 13) {\r\n                    doSearch();\r\n                }\r\n            };\r\n            $G(\"doSearch\").onclick = doSearch;\r\n            dialog.onok = function (){\r\n                var center = map.getCenter();\r\n                var point = marker.getPosition();\r\n                var url = \"http://maps.googleapis.com/maps/api/staticmap?center=\" + center.lat() + ',' + center.lng() + \"&zoom=\" + map.zoom + \"&size=520x340&maptype=\" + map.getMapTypeId() + \"&markers=\" + point.lat() + ',' + point.lng() + \"&sensor=false\";\r\n                editor.execCommand('inserthtml', '<img width=\"520\" height=\"340\" src=\"' + url + '\"' + (imgcss ? ' style=\"' + imgcss + '\"' :'') + '/>');\r\n            };\r\n\r\n            function getPars(str,par){\r\n                var reg = new RegExp(par+\"=((\\\\d+|[.,])*)\",\"g\");\r\n                return reg.exec(str)[1];\r\n            }\r\n            var img = editor.selection.getRange().getClosedNode();\r\n            if(img && img.src.indexOf(\"http://maps.googleapis.com/maps/api/staticmap\")!=-1){\r\n                var url = img.getAttribute(\"src\");\r\n                var centers = getPars(url,\"center\").split(\",\");\r\n                point = new google.maps.LatLng(Number(centers[0]),Number(centers[1]));\r\n                map.setCenter(point);\r\n                map.setZoom(Number(getPars(url,\"zoom\")));\r\n                centers = getPars(url,\"markers\").split(\",\");\r\n                marker.setPosition(new google.maps.LatLng(Number(centers[0]),Number(centers[1])));\r\n                imgcss = img.style.cssText;\r\n            }else{\r\n                setTimeout(function(){\r\n                    doSearch();\r\n                },30)\r\n            }\r\n    });\r\n\r\n</script>\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/help/help.css",
    "content": ".wrapper{width: 370px;margin: 10px auto;zoom: 1;}\r\n.tabbody{height: 360px;}\r\n.tabbody .panel{width:100%;height: 360px;position: absolute;background: #fff;}\r\n.tabbody .panel h1{font-size:26px;margin: 5px 0 0 5px;}\r\n.tabbody .panel p{font-size:12px;margin: 5px 0 0 5px;}\r\n.tabbody table{width:90%;line-height: 20px;margin: 5px 0 0 5px;;}\r\n.tabbody table thead{font-weight: bold;line-height: 25px;}"
  },
  {
    "path": "public/static/ueditor/dialogs/help/help.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n        \"http://www.w3.org/TR/html4/loose.dtd\">\r\n<html>\r\n<head>\r\n    <title>帮助</title>\r\n    <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\"/>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"help.css\">\r\n</head>\r\n<body>\r\n<div class=\"wrapper\" id=\"helptab\">\r\n    <div id=\"tabHeads\" class=\"tabhead\">\r\n        <span class=\"focus\" tabsrc=\"about\"><var id=\"lang_input_about\"></var></span>\r\n        <span tabsrc=\"shortcuts\"><var id=\"lang_input_shortcuts\"></var></span>\r\n    </div>\r\n    <div id=\"tabBodys\" class=\"tabbody\">\r\n        <div id=\"about\" class=\"panel\">\r\n            <h1>UEditor</h1>\r\n            <p id=\"version\"></p>\r\n            <p><var id=\"lang_input_introduction\"></var></p>\r\n        </div>\r\n        <div id=\"shortcuts\" class=\"panel\">\r\n            <table>\r\n                <thead>\r\n                <tr>\r\n                    <td><var id=\"lang_Txt_shortcuts\"></var></td>\r\n                    <td><var id=\"lang_Txt_func\"></var></td>\r\n                </tr>\r\n                </thead>\r\n                <tbody>\r\n                <tr>\r\n                    <td>ctrl+b</td>\r\n                    <td><var id=\"lang_Txt_bold\"></var></td>\r\n                </tr>\r\n                <tr>\r\n                    <td>ctrl+c</td>\r\n                    <td><var id=\"lang_Txt_copy\"></var></td>\r\n                </tr>\r\n                <tr>\r\n                    <td>ctrl+x</td>\r\n                    <td><var id=\"lang_Txt_cut\"></var></td>\r\n                </tr>\r\n                <tr>\r\n                    <td>ctrl+v</td>\r\n                    <td><var id=\"lang_Txt_Paste\"></var></td>\r\n                </tr>\r\n                <tr>\r\n                    <td>ctrl+y</td>\r\n                    <td><var id=\"lang_Txt_undo\"></var></td>\r\n                </tr>\r\n                <tr>\r\n                    <td>ctrl+z</td>\r\n                    <td><var id=\"lang_Txt_redo\"></var></td>\r\n                </tr>\r\n                <tr>\r\n                    <td>ctrl+i</td>\r\n                    <td><var id=\"lang_Txt_italic\"></var></td>\r\n                </tr>\r\n                <tr>\r\n                    <td>ctrl+u</td>\r\n                    <td><var id=\"lang_Txt_underline\"></var></td>\r\n                </tr>\r\n                <tr>\r\n                    <td>ctrl+a</td>\r\n                    <td><var id=\"lang_Txt_selectAll\"></var></td>\r\n                </tr>\r\n                <tr>\r\n                    <td>shift+enter</td>\r\n                    <td><var id=\"lang_Txt_visualEnter\"></var></td>\r\n                </tr>\r\n                <tr>\r\n                    <td>alt+z</td>\r\n                    <td><var id=\"lang_Txt_fullscreen\"></var></td>\r\n                </tr>\r\n                </tbody>\r\n            </table>\r\n        </div>\r\n    </div>\r\n</div>\r\n<script type=\"text/javascript\" src=\"help.js\"></script>\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/help/help.js",
    "content": "/**\r\n * Created with JetBrains PhpStorm.\r\n * User: xuheng\r\n * Date: 12-9-26\r\n * Time: 下午1:06\r\n * To change this template use File | Settings | File Templates.\r\n */\r\n/**\r\n * tab点击处理事件\r\n * @param tabHeads\r\n * @param tabBodys\r\n * @param obj\r\n */\r\nfunction clickHandler( tabHeads,tabBodys,obj ) {\r\n    //head样式更改\r\n    for ( var k = 0, len = tabHeads.length; k < len; k++ ) {\r\n        tabHeads[k].className = \"\";\r\n    }\r\n    obj.className = \"focus\";\r\n    //body显隐\r\n    var tabSrc = obj.getAttribute( \"tabSrc\" );\r\n    for ( var j = 0, length = tabBodys.length; j < length; j++ ) {\r\n        var body = tabBodys[j],\r\n            id = body.getAttribute( \"id\" );\r\n        body.onclick = function(){\r\n            this.style.zoom = 1;\r\n        };\r\n        if ( id != tabSrc ) {\r\n            body.style.zIndex = 1;\r\n        } else {\r\n            body.style.zIndex = 200;\r\n        }\r\n    }\r\n\r\n}\r\n\r\n/**\r\n * TAB切换\r\n * @param tabParentId  tab的父节点ID或者对象本身\r\n */\r\nfunction switchTab( tabParentId ) {\r\n    var tabElements = $G( tabParentId ).children,\r\n        tabHeads = tabElements[0].children,\r\n        tabBodys = tabElements[1].children;\r\n\r\n    for ( var i = 0, length = tabHeads.length; i < length; i++ ) {\r\n        var head = tabHeads[i];\r\n        if ( head.className === \"focus\" )clickHandler(tabHeads,tabBodys, head );\r\n        head.onclick = function () {\r\n            clickHandler(tabHeads,tabBodys,this);\r\n        }\r\n    }\r\n}\r\nswitchTab(\"helptab\");\r\n\r\ndocument.getElementById('version').innerHTML = parent.UE.version;"
  },
  {
    "path": "public/static/ueditor/dialogs/image/image.css",
    "content": "@charset \"utf-8\";\r\n/* dialog样式 */\r\n.wrapper {\r\n    zoom: 1;\r\n    width: 630px;\r\n    *width: 626px;\r\n    height: 380px;\r\n    margin: 0 auto;\r\n    padding: 10px;\r\n    position: relative;\r\n    font-family: sans-serif;\r\n}\r\n\r\n/*tab样式框大小*/\r\n.tabhead {\r\n    float:left;\r\n}\r\n.tabbody {\r\n    width: 100%;\r\n    height: 346px;\r\n    position: relative;\r\n    clear: both;\r\n}\r\n\r\n.tabbody .panel {\r\n    position: absolute;\r\n    width: 0;\r\n    height: 0;\r\n    background: #fff;\r\n    overflow: hidden;\r\n    display: none;\r\n}\r\n\r\n.tabbody .panel.focus {\r\n    width: 100%;\r\n    height: 346px;\r\n    display: block;\r\n}\r\n\r\n/* 图片对齐方式 */\r\n.alignBar{\r\n    float:right;\r\n    margin-top: 5px;\r\n    position: relative;\r\n}\r\n\r\n.alignBar .algnLabel{\r\n    float:left;\r\n    height: 20px;\r\n    line-height: 20px;\r\n}\r\n\r\n.alignBar #alignIcon{\r\n    zoom:1;\r\n    _display: inline;\r\n    display: inline-block;\r\n    position: relative;\r\n}\r\n.alignBar #alignIcon span{\r\n    float: left;\r\n    cursor: pointer;\r\n    display: block;\r\n    width: 19px;\r\n    height: 17px;\r\n    margin-right: 3px;\r\n    margin-left: 3px;\r\n    background-image: url(./images/alignicon.jpg);\r\n}\r\n.alignBar #alignIcon .none-align{\r\n    background-position: 0 -18px;\r\n}\r\n.alignBar #alignIcon .left-align{\r\n    background-position: -20px -18px;\r\n}\r\n.alignBar #alignIcon .right-align{\r\n    background-position: -40px -18px;\r\n}\r\n.alignBar #alignIcon .center-align{\r\n    background-position: -60px -18px;\r\n}\r\n.alignBar #alignIcon .none-align.focus{\r\n    background-position: 0 0;\r\n}\r\n.alignBar #alignIcon .left-align.focus{\r\n    background-position: -20px 0;\r\n}\r\n.alignBar #alignIcon .right-align.focus{\r\n    background-position: -40px 0;\r\n}\r\n.alignBar #alignIcon .center-align.focus{\r\n    background-position: -60px 0;\r\n}\r\n\r\n\r\n\r\n\r\n/* 远程图片样式 */\r\n#remote {\r\n    z-index: 200;\r\n}\r\n\r\n#remote .top{\r\n    width: 100%;\r\n    margin-top: 25px;\r\n}\r\n#remote .left{\r\n    display: block;\r\n    float: left;\r\n    width: 300px;\r\n    height:10px;\r\n}\r\n#remote .right{\r\n    display: block;\r\n    float: right;\r\n    width: 300px;\r\n    height:10px;\r\n}\r\n#remote .row{\r\n    margin-left: 20px;\r\n    clear: both;\r\n    height: 40px;\r\n}\r\n\r\n#remote .row label{\r\n    text-align: center;\r\n    width: 50px;\r\n    zoom:1;\r\n    _display: inline;\r\n    display:inline-block;\r\n    vertical-align: middle;\r\n}\r\n#remote .row label.algnLabel{\r\n    float: left;\r\n\r\n}\r\n\r\n#remote input.text{\r\n    width: 150px;\r\n    padding: 3px 6px;\r\n    font-size: 14px;\r\n    line-height: 1.42857143;\r\n    color: #555;\r\n    background-color: #fff;\r\n    background-image: none;\r\n    border: 1px solid #ccc;\r\n    border-radius: 4px;\r\n    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\r\n    box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\r\n    -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\r\n    transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\r\n}\r\n#remote input.text:focus {\r\n    border-color: #66afe9;\r\n    outline: 0;\r\n    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);\r\n    box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);\r\n}\r\n#remote #url{\r\n    width: 500px;\r\n    margin-bottom: 2px;\r\n}\r\n#remote #width,\r\n#remote #height{\r\n    width: 20px;\r\n    margin-left: 2px;\r\n    margin-right: 2px;\r\n}\r\n#remote #border,\r\n#remote #vhSpace,\r\n#remote #title{\r\n    width: 180px;\r\n    margin-right: 5px;\r\n}\r\n#remote #lock{\r\n}\r\n#remote #lockicon{\r\n    zoom: 1;\r\n    _display:inline;\r\n    display: inline-block;\r\n    width: 20px;\r\n    height: 20px;\r\n    background: url(\"../../themes/default/images/lock.gif\") -13px -13px no-repeat;\r\n    vertical-align: middle;\r\n}\r\n#remote #preview{\r\n    clear: both;\r\n    width: 260px;\r\n    height: 240px;\r\n    z-index: 9999;\r\n    margin-top: 10px;\r\n    background-color: #eee;\r\n    overflow: hidden;\r\n}\r\n\r\n/* 上传图片 */\r\n.tabbody #upload.panel {\r\n    width: 0;\r\n    height: 0;\r\n    overflow: hidden;\r\n    position: absolute !important;\r\n    clip: rect(1px, 1px, 1px, 1px);\r\n    background: #fff;\r\n    display: block;\r\n}\r\n\r\n.tabbody #upload.panel.focus {\r\n    width: 100%;\r\n    height: 346px;\r\n    display: block;\r\n    clip: auto;\r\n}\r\n\r\n#upload .queueList {\r\n    margin: 0;\r\n    width: 100%;\r\n    height: 100%;\r\n    position: absolute;\r\n    overflow: hidden;\r\n}\r\n\r\n#upload p {\r\n    margin: 0;\r\n}\r\n\r\n.element-invisible {\r\n    width: 0 !important;\r\n    height: 0 !important;\r\n    border: 0;\r\n    padding: 0;\r\n    margin: 0;\r\n    overflow: hidden;\r\n    position: absolute !important;\r\n    clip: rect(1px, 1px, 1px, 1px);\r\n}\r\n\r\n#upload .placeholder {\r\n    margin: 10px;\r\n    border: 2px dashed #e6e6e6;\r\n    *border: 0px dashed #e6e6e6;\r\n    height: 172px;\r\n    padding-top: 150px;\r\n    text-align: center;\r\n    background: url(./images/image.png) center 70px no-repeat;\r\n    color: #cccccc;\r\n    font-size: 18px;\r\n    position: relative;\r\n    top:0;\r\n    *top: 10px;\r\n}\r\n\r\n#upload .placeholder .webuploader-pick {\r\n    font-size: 18px;\r\n    background: #00b7ee;\r\n    border-radius: 3px;\r\n    line-height: 44px;\r\n    padding: 0 30px;\r\n    *width: 120px;\r\n    color: #fff;\r\n    display: inline-block;\r\n    margin: 0 auto 20px auto;\r\n    cursor: pointer;\r\n    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n#upload .placeholder .webuploader-pick-hover {\r\n    background: #00a2d4;\r\n}\r\n\r\n\r\n#filePickerContainer {\r\n    text-align: center;\r\n}\r\n\r\n#upload .placeholder .flashTip {\r\n    color: #666666;\r\n    font-size: 12px;\r\n    position: absolute;\r\n    width: 100%;\r\n    text-align: center;\r\n    bottom: 20px;\r\n}\r\n\r\n#upload .placeholder .flashTip a {\r\n    color: #0785d1;\r\n    text-decoration: none;\r\n}\r\n\r\n#upload .placeholder .flashTip a:hover {\r\n    text-decoration: underline;\r\n}\r\n\r\n#upload .placeholder.webuploader-dnd-over {\r\n    border-color: #999999;\r\n}\r\n\r\n#upload .filelist {\r\n    list-style: none;\r\n    margin: 0;\r\n    padding: 0;\r\n    overflow-x: hidden;\r\n    overflow-y: auto;\r\n    position: relative;\r\n    height: 300px;\r\n}\r\n\r\n#upload .filelist:after {\r\n    content: '';\r\n    display: block;\r\n    width: 0;\r\n    height: 0;\r\n    overflow: hidden;\r\n    clear: both;\r\n    position: relative;\r\n}\r\n\r\n#upload .filelist li {\r\n    width: 113px;\r\n    height: 113px;\r\n    background: url(./images/bg.png);\r\n    text-align: center;\r\n    margin: 9px 0 0 9px;\r\n    *margin: 6px 0 0 6px;\r\n    position: relative;\r\n    display: block;\r\n    float: left;\r\n    overflow: hidden;\r\n    font-size: 12px;\r\n}\r\n\r\n#upload .filelist li p.log {\r\n    position: relative;\r\n    top: -45px;\r\n}\r\n\r\n#upload .filelist li p.title {\r\n    position: absolute;\r\n    top: 0;\r\n    left: 0;\r\n    width: 100%;\r\n    overflow: hidden;\r\n    white-space: nowrap;\r\n    text-overflow: ellipsis;\r\n    top: 5px;\r\n    text-indent: 5px;\r\n    text-align: left;\r\n}\r\n\r\n#upload .filelist li p.progress {\r\n    position: absolute;\r\n    width: 100%;\r\n    bottom: 0;\r\n    left: 0;\r\n    height: 8px;\r\n    overflow: hidden;\r\n    z-index: 50;\r\n    margin: 0;\r\n    border-radius: 0;\r\n    background: none;\r\n    -webkit-box-shadow: 0 0 0;\r\n}\r\n\r\n#upload .filelist li p.progress span {\r\n    display: none;\r\n    overflow: hidden;\r\n    width: 0;\r\n    height: 100%;\r\n    background: #1483d8 url(./images/progress.png) repeat-x;\r\n\r\n    -webit-transition: width 200ms linear;\r\n    -moz-transition: width 200ms linear;\r\n    -o-transition: width 200ms linear;\r\n    -ms-transition: width 200ms linear;\r\n    transition: width 200ms linear;\r\n\r\n    -webkit-animation: progressmove 2s linear infinite;\r\n    -moz-animation: progressmove 2s linear infinite;\r\n    -o-animation: progressmove 2s linear infinite;\r\n    -ms-animation: progressmove 2s linear infinite;\r\n    animation: progressmove 2s linear infinite;\r\n\r\n    -webkit-transform: translateZ(0);\r\n}\r\n\r\n@-webkit-keyframes progressmove {\r\n    0% {\r\n        background-position: 0 0;\r\n    }\r\n    100% {\r\n        background-position: 17px 0;\r\n    }\r\n}\r\n\r\n@-moz-keyframes progressmove {\r\n    0% {\r\n        background-position: 0 0;\r\n    }\r\n    100% {\r\n        background-position: 17px 0;\r\n    }\r\n}\r\n\r\n@keyframes progressmove {\r\n    0% {\r\n        background-position: 0 0;\r\n    }\r\n    100% {\r\n        background-position: 17px 0;\r\n    }\r\n}\r\n\r\n#upload .filelist li p.imgWrap {\r\n    position: relative;\r\n    z-index: 2;\r\n    line-height: 113px;\r\n    vertical-align: middle;\r\n    overflow: hidden;\r\n    width: 113px;\r\n    height: 113px;\r\n\r\n    -webkit-transform-origin: 50% 50%;\r\n    -moz-transform-origin: 50% 50%;\r\n    -o-transform-origin: 50% 50%;\r\n    -ms-transform-origin: 50% 50%;\r\n    transform-origin: 50% 50%;\r\n\r\n    -webit-transition: 200ms ease-out;\r\n    -moz-transition: 200ms ease-out;\r\n    -o-transition: 200ms ease-out;\r\n    -ms-transition: 200ms ease-out;\r\n    transition: 200ms ease-out;\r\n}\r\n\r\n#upload .filelist li img {\r\n    width: 100%;\r\n}\r\n\r\n#upload .filelist li p.error {\r\n    background: #f43838;\r\n    color: #fff;\r\n    position: absolute;\r\n    bottom: 0;\r\n    left: 0;\r\n    height: 28px;\r\n    line-height: 28px;\r\n    width: 100%;\r\n    z-index: 100;\r\n    display:none;\r\n}\r\n\r\n#upload .filelist li .success {\r\n    display: block;\r\n    position: absolute;\r\n    left: 0;\r\n    bottom: 0;\r\n    height: 40px;\r\n    width: 100%;\r\n    z-index: 200;\r\n    background: url(./images/success.png) no-repeat right bottom;\r\n    background: url(./images/success.gif) no-repeat right bottom \\9;\r\n}\r\n\r\n#upload .filelist li.filePickerBlock {\r\n    width: 113px;\r\n    height: 113px;\r\n    background: url(./images/image.png) no-repeat center 12px;\r\n    border: 1px solid #eeeeee;\r\n    border-radius: 0;\r\n}\r\n#upload .filelist li.filePickerBlock div.webuploader-pick  {\r\n    width: 100%;\r\n    height: 100%;\r\n    margin: 0;\r\n    padding: 0;\r\n    opacity: 0;\r\n    background: none;\r\n    font-size: 0;\r\n}\r\n\r\n#upload .filelist div.file-panel {\r\n    position: absolute;\r\n    height: 0;\r\n    filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#80000000', endColorstr='#80000000') \\0;\r\n    background: rgba(0, 0, 0, 0.5);\r\n    width: 100%;\r\n    top: 0;\r\n    left: 0;\r\n    overflow: hidden;\r\n    z-index: 300;\r\n}\r\n\r\n#upload .filelist div.file-panel span {\r\n    width: 24px;\r\n    height: 24px;\r\n    display: inline;\r\n    float: right;\r\n    text-indent: -9999px;\r\n    overflow: hidden;\r\n    background: url(./images/icons.png) no-repeat;\r\n    background: url(./images/icons.gif) no-repeat \\9;\r\n    margin: 5px 1px 1px;\r\n    cursor: pointer;\r\n    -webkit-tap-highlight-color: rgba(0,0,0,0);\r\n    -webkit-user-select: none;\r\n    -moz-user-select: none;\r\n    -ms-user-select: none;\r\n    user-select: none;\r\n}\r\n\r\n#upload .filelist div.file-panel span.rotateLeft {\r\n    display:none;\r\n    background-position: 0 -24px;\r\n}\r\n\r\n#upload .filelist div.file-panel span.rotateLeft:hover {\r\n    background-position: 0 0;\r\n}\r\n\r\n#upload .filelist div.file-panel span.rotateRight {\r\n    display:none;\r\n    background-position: -24px -24px;\r\n}\r\n\r\n#upload .filelist div.file-panel span.rotateRight:hover {\r\n    background-position: -24px 0;\r\n}\r\n\r\n#upload .filelist div.file-panel span.cancel {\r\n    background-position: -48px -24px;\r\n}\r\n\r\n#upload .filelist div.file-panel span.cancel:hover {\r\n    background-position: -48px 0;\r\n}\r\n\r\n#upload .statusBar {\r\n    height: 45px;\r\n    border-bottom: 1px solid #dadada;\r\n    margin: 0 10px;\r\n    padding: 0;\r\n    line-height: 45px;\r\n    vertical-align: middle;\r\n    position: relative;\r\n}\r\n\r\n#upload .statusBar .progress {\r\n    border: 1px solid #1483d8;\r\n    width: 198px;\r\n    background: #fff;\r\n    height: 18px;\r\n    position: absolute;\r\n    top: 12px;\r\n    display: none;\r\n    text-align: center;\r\n    line-height: 18px;\r\n    color: #6dbfff;\r\n    margin: 0 10px 0 0;\r\n}\r\n#upload .statusBar .progress span.percentage {\r\n    width: 0;\r\n    height: 100%;\r\n    left: 0;\r\n    top: 0;\r\n    background: #1483d8;\r\n    position: absolute;\r\n}\r\n#upload .statusBar .progress span.text {\r\n    position: relative;\r\n    z-index: 10;\r\n}\r\n\r\n#upload .statusBar .info {\r\n    display: inline-block;\r\n    font-size: 14px;\r\n    color: #666666;\r\n}\r\n\r\n#upload .statusBar .btns {\r\n    position: absolute;\r\n    top: 7px;\r\n    right: 0;\r\n    line-height: 30px;\r\n}\r\n\r\n#filePickerBtn {\r\n    display: inline-block;\r\n    float: left;\r\n}\r\n#upload .statusBar .btns .webuploader-pick,\r\n#upload .statusBar .btns .uploadBtn,\r\n#upload .statusBar .btns .uploadBtn.state-uploading,\r\n#upload .statusBar .btns .uploadBtn.state-paused {\r\n    background: #ffffff;\r\n    border: 1px solid #cfcfcf;\r\n    color: #565656;\r\n    padding: 0 18px;\r\n    display: inline-block;\r\n    border-radius: 3px;\r\n    margin-left: 10px;\r\n    cursor: pointer;\r\n    font-size: 14px;\r\n    float: left;\r\n    -webkit-user-select: none;\r\n    -moz-user-select: none;\r\n    -ms-user-select: none;\r\n    user-select: none;\r\n}\r\n#upload .statusBar .btns .webuploader-pick-hover,\r\n#upload .statusBar .btns .uploadBtn:hover,\r\n#upload .statusBar .btns .uploadBtn.state-uploading:hover,\r\n#upload .statusBar .btns .uploadBtn.state-paused:hover {\r\n    background: #f0f0f0;\r\n}\r\n\r\n#upload .statusBar .btns .uploadBtn,\r\n#upload .statusBar .btns .uploadBtn.state-paused{\r\n    background: #00b7ee;\r\n    color: #fff;\r\n    border-color: transparent;\r\n}\r\n#upload .statusBar .btns .uploadBtn:hover,\r\n#upload .statusBar .btns .uploadBtn.state-paused:hover{\r\n    background: #00a2d4;\r\n}\r\n\r\n#upload .statusBar .btns .uploadBtn.disabled {\r\n    pointer-events: none;\r\n    filter:alpha(opacity=60);\r\n    -moz-opacity:0.6;\r\n    -khtml-opacity: 0.6;\r\n    opacity: 0.6;\r\n}\r\n\r\n\r\n\r\n/* 图片管理样式 */\r\n#online {\r\n    width: 100%;\r\n    height: 336px;\r\n    padding: 10px 0 0 0;\r\n}\r\n#online #imageList{\r\n    width: 100%;\r\n    height: 100%;\r\n    overflow-x: hidden;\r\n    overflow-y: auto;\r\n    position: relative;\r\n}\r\n#online ul {\r\n    display: block;\r\n    list-style: none;\r\n    margin: 0;\r\n    padding: 0;\r\n}\r\n#online li {\r\n    float: left;\r\n    display: block;\r\n    list-style: none;\r\n    padding: 0;\r\n    width: 113px;\r\n    height: 113px;\r\n    margin: 0 0 9px 9px;\r\n    *margin: 0 0 6px 6px;\r\n    background-color: #eee;\r\n    overflow: hidden;\r\n    cursor: pointer;\r\n    position: relative;\r\n}\r\n#online li.clearFloat {\r\n    float: none;\r\n    clear: both;\r\n    display: block;\r\n    width:0;\r\n    height:0;\r\n    margin: 0;\r\n    padding: 0;\r\n}\r\n#online li img {\r\n    cursor: pointer;\r\n}\r\n#online li .icon {\r\n    cursor: pointer;\r\n    width: 113px;\r\n    height: 113px;\r\n    position: absolute;\r\n    top: 0;\r\n    left: 0;\r\n    z-index: 2;\r\n    border: 0;\r\n    background-repeat: no-repeat;\r\n}\r\n#online li .icon:hover {\r\n    width: 107px;\r\n    height: 107px;\r\n    border: 3px solid #1094fa;\r\n}\r\n#online li.selected .icon {\r\n    background-image: url(images/success.png);\r\n    background-image: url(images/success.gif)\\9;\r\n    background-position: 75px 75px;\r\n}\r\n#online li.selected .icon:hover {\r\n    width: 107px;\r\n    height: 107px;\r\n    border: 3px solid #1094fa;\r\n    background-position: 72px 72px;\r\n}\r\n\r\n\r\n/* 图片搜索样式 */\r\n#search .searchBar {\r\n    width: 100%;\r\n    height: 30px;\r\n    margin: 10px 0 5px 0;\r\n    padding: 0;\r\n}\r\n\r\n#search input.text{\r\n    width: 150px;\r\n    padding: 3px 6px;\r\n    font-size: 14px;\r\n    line-height: 1.42857143;\r\n    color: #555;\r\n    background-color: #fff;\r\n    background-image: none;\r\n    border: 1px solid #ccc;\r\n    border-radius: 4px;\r\n    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\r\n    box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075);\r\n    -webkit-transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\r\n    transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s;\r\n}\r\n#search input.text:focus {\r\n    border-color: #66afe9;\r\n    outline: 0;\r\n    -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);\r\n    box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075), 0 0 8px rgba(102, 175, 233, .6);\r\n}\r\n#search input.searchTxt {\r\n    margin-left:5px;\r\n    padding-left: 5px;\r\n    background: #FFF;\r\n    width: 300px;\r\n    *width: 260px;\r\n    height: 21px;\r\n    line-height: 21px;\r\n    float: left;\r\n    dislay: block;\r\n}\r\n\r\n#search .searchType {\r\n    width: 65px;\r\n    height: 28px;\r\n    padding:0;\r\n    line-height: 28px;\r\n    border: 1px solid #d7d7d7;\r\n    border-radius: 0;\r\n    vertical-align: top;\r\n    margin-left: 5px;\r\n    float: left;\r\n    dislay: block;\r\n}\r\n\r\n#search #searchBtn,\r\n#search #searchReset {\r\n    display: inline-block;\r\n    margin-bottom: 0;\r\n    margin-right: 5px;\r\n    padding: 4px 10px;\r\n    font-weight: 400;\r\n    text-align: center;\r\n    vertical-align: middle;\r\n    cursor: pointer;\r\n    background-image: none;\r\n    border: 1px solid transparent;\r\n    white-space: nowrap;\r\n    font-size: 14px;\r\n    border-radius: 4px;\r\n    -webkit-user-select: none;\r\n    -moz-user-select: none;\r\n    -ms-user-select: none;\r\n    user-select: none;\r\n    vertical-align: top;\r\n    float: right;\r\n}\r\n\r\n#search #searchBtn {\r\n    color: white;\r\n    border-color: #285e8e;\r\n    background-color: #3b97d7;\r\n}\r\n#search #searchReset {\r\n    color: #333;\r\n    border-color: #ccc;\r\n    background-color: #fff;\r\n}\r\n#search #searchBtn:hover {\r\n    background-color: #3276b1;\r\n}\r\n#search #searchReset:hover {\r\n    background-color: #eee;\r\n}\r\n\r\n#search .msg {\r\n    margin-left: 5px;\r\n}\r\n\r\n#search .searchList{\r\n    width: 100%;\r\n    height: 300px;\r\n    overflow: hidden;\r\n    clear: both;\r\n}\r\n#search .searchList ul{\r\n    margin:0;\r\n    padding:0;\r\n    list-style:none;\r\n    clear: both;\r\n    width: 100%;\r\n    height: 100%;\r\n    overflow-x: hidden;\r\n    overflow-y: auto;\r\n    zoom: 1;\r\n    position: relative;\r\n}\r\n\r\n#search .searchList li {\r\n    list-style:none;\r\n    float: left;\r\n    display: block;\r\n    width: 115px;\r\n    margin: 5px 10px 5px 20px;\r\n    *margin: 5px 10px 5px 15px;\r\n    padding:0;\r\n    font-size: 12px;\r\n    box-shadow: 0 1px 3px rgba(0, 0, 0, .3);\r\n    -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, .3);\r\n    -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, .3);\r\n    position: relative;\r\n    vertical-align: top;\r\n    text-align: center;\r\n    overflow: hidden;\r\n    cursor: pointer;\r\n    filter: alpha(Opacity=100);\r\n    -moz-opacity: 1;\r\n    opacity: 1;\r\n    border: 2px solid #eee;\r\n}\r\n\r\n#search .searchList li.selected {\r\n    filter: alpha(Opacity=40);\r\n    -moz-opacity: 0.4;\r\n    opacity: 0.4;\r\n    border: 2px solid #00a0e9;\r\n}\r\n\r\n#search .searchList li p {\r\n    background-color: #eee;\r\n    margin: 0;\r\n    padding: 0;\r\n    position: relative;\r\n    width:100%;\r\n    height:115px;\r\n    overflow: hidden;\r\n}\r\n\r\n#search .searchList li p img {\r\n    cursor: pointer;\r\n    border: 0;\r\n}\r\n\r\n#search .searchList li a {\r\n    color: #999;\r\n    border-top: 1px solid #F2F2F2;\r\n    background: #FAFAFA;\r\n    text-align: center;\r\n    display: block;\r\n    padding: 0 5px;\r\n    width: 105px;\r\n    height:32px;\r\n    line-height:32px;\r\n    white-space:nowrap;\r\n    text-overflow:ellipsis;\r\n    text-decoration: none;\r\n    overflow: hidden;\r\n    word-break: break-all;\r\n}\r\n\r\n#search .searchList a:hover {\r\n    text-decoration: underline;\r\n    color: #333;\r\n}\r\n#search .searchList .clearFloat{\r\n    clear: both;\r\n}"
  },
  {
    "path": "public/static/ueditor/dialogs/image/image.html",
    "content": "<!doctype html>\r\n<html>\r\n<head>\r\n    <meta charset=\"UTF-8\">\r\n    <title>ueditor图片对话框</title>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n\r\n    <!-- jquery -->\r\n    <script type=\"text/javascript\" src=\"../../third-party/jquery-1.10.2.min.js\"></script>\r\n\r\n    <!-- webuploader -->\r\n    <script src=\"../../third-party/webuploader/webuploader.min.js\"></script>\r\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"../../third-party/webuploader/webuploader.css\">\r\n\r\n    <!-- image dialog -->\r\n    <link rel=\"stylesheet\" href=\"image.css\" type=\"text/css\" />\r\n</head>\r\n<body>\r\n\r\n    <div class=\"wrapper\">\r\n        <div id=\"tabhead\" class=\"tabhead\">\r\n            <span class=\"tab\" data-content-id=\"remote\"><var id=\"lang_tab_remote\"></var></span>\r\n            <span class=\"tab focus\" data-content-id=\"upload\"><var id=\"lang_tab_upload\"></var></span>\r\n            <span class=\"tab\" data-content-id=\"online\"><var id=\"lang_tab_online\"></var></span>\r\n            <span class=\"tab\" data-content-id=\"search\"><var id=\"lang_tab_search\"></var></span>\r\n        </div>\r\n        <div class=\"alignBar\">\r\n            <label class=\"algnLabel\"><var id=\"lang_input_align\"></var></label>\r\n                    <span id=\"alignIcon\">\r\n                        <span id=\"noneAlign\" class=\"none-align focus\" data-align=\"none\"></span>\r\n                        <span id=\"leftAlign\" class=\"left-align\" data-align=\"left\"></span>\r\n                        <span id=\"rightAlign\" class=\"right-align\" data-align=\"right\"></span>\r\n                        <span id=\"centerAlign\" class=\"center-align\" data-align=\"center\"></span>\r\n                    </span>\r\n            <input id=\"align\" name=\"align\" type=\"hidden\" value=\"none\"/>\r\n        </div>\r\n        <div id=\"tabbody\" class=\"tabbody\">\r\n\r\n            <!-- 远程图片 -->\r\n            <div id=\"remote\" class=\"panel\">\r\n                <div class=\"top\">\r\n                    <div class=\"row\">\r\n                        <label for=\"url\"><var id=\"lang_input_url\"></var></label>\r\n                        <span><input class=\"text\" id=\"url\" type=\"text\"/></span>\r\n                    </div>\r\n                </div>\r\n                <div class=\"left\">\r\n                    <div class=\"row\">\r\n                        <label><var id=\"lang_input_size\"></var></label>\r\n                        <span><var id=\"lang_input_width\">&nbsp;&nbsp;</var><input class=\"text\" type=\"text\" id=\"width\"/>px </span>\r\n                        <span><var id=\"lang_input_height\">&nbsp;&nbsp;</var><input class=\"text\" type=\"text\" id=\"height\"/>px </span>\r\n                        <span><input id=\"lock\" type=\"checkbox\" disabled=\"disabled\"><span id=\"lockicon\"></span></span>\r\n                    </div>\r\n                    <div class=\"row\">\r\n                        <label><var id=\"lang_input_border\"></var></label>\r\n                        <span><input class=\"text\" type=\"text\" id=\"border\"/>px </span>\r\n                    </div>\r\n                    <div class=\"row\">\r\n                        <label><var id=\"lang_input_vhspace\"></var></label>\r\n                        <span><input class=\"text\" type=\"text\" id=\"vhSpace\"/>px </span>\r\n                    </div>\r\n                    <div class=\"row\">\r\n                        <label><var id=\"lang_input_title\"></var></label>\r\n                        <span><input class=\"text\" type=\"text\" id=\"title\"/></span>\r\n                    </div>\r\n                </div>\r\n                <div class=\"right\"><div id=\"preview\"></div></div>\r\n            </div>\r\n\r\n            <!-- 上传图片 -->\r\n            <div id=\"upload\" class=\"panel focus\">\r\n                <div id=\"queueList\" class=\"queueList\">\r\n                    <div class=\"statusBar element-invisible\">\r\n                        <div class=\"progress\">\r\n                            <span class=\"text\">0%</span>\r\n                            <span class=\"percentage\"></span>\r\n                        </div><div class=\"info\"></div>\r\n                        <div class=\"btns\">\r\n                            <div id=\"filePickerBtn\"></div>\r\n                            <div class=\"uploadBtn\"><var id=\"lang_start_upload\"></var></div>\r\n                        </div>\r\n                    </div>\r\n                    <div id=\"dndArea\" class=\"placeholder\">\r\n                        <div class=\"filePickerContainer\">\r\n                            <div id=\"filePickerReady\"></div>\r\n                        </div>\r\n                    </div>\r\n                    <ul class=\"filelist element-invisible\">\r\n                        <li id=\"filePickerBlock\" class=\"filePickerBlock\"></li>\r\n                    </ul>\r\n                </div>\r\n            </div>\r\n\r\n            <!-- 在线图片 -->\r\n            <div id=\"online\" class=\"panel\">\r\n                <div id=\"imageList\"><var id=\"lang_imgLoading\"></var></div>\r\n            </div>\r\n\r\n            <!-- 搜索图片 -->\r\n            <div id=\"search\" class=\"panel\">\r\n                <div class=\"searchBar\">\r\n                    <input id=\"searchTxt\" class=\"searchTxt text\" type=\"text\" />\r\n                    <select id=\"searchType\" class=\"searchType\">\r\n                        <option value=\"&s=4&z=0\"></option>\r\n                        <option value=\"&s=1&z=19\"></option>\r\n                        <option value=\"&s=2&z=0\"></option>\r\n                        <option value=\"&s=3&z=0\"></option>\r\n                    </select>\r\n                    <input id=\"searchReset\" type=\"button\"  />\r\n                    <input id=\"searchBtn\" type=\"button\"  />\r\n                </div>\r\n                <div id=\"searchList\" class=\"searchList\"><ul id=\"searchListUl\"></ul></div>\r\n            </div>\r\n\r\n        </div>\r\n    </div>\r\n    <script type=\"text/javascript\" src=\"image.js\"></script>\r\n\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/image/image.js",
    "content": "/**\r\n * User: Jinqn\r\n * Date: 14-04-08\r\n * Time: 下午16:34\r\n * 上传图片对话框逻辑代码,包括tab: 远程图片/上传图片/在线图片/搜索图片\r\n */\r\n\r\n(function () {\r\n\r\n    var remoteImage,\r\n        uploadImage,\r\n        onlineImage,\r\n        searchImage;\r\n\r\n    window.onload = function () {\r\n        initTabs();\r\n        initAlign();\r\n        initButtons();\r\n    };\r\n\r\n    /* 初始化tab标签 */\r\n    function initTabs() {\r\n        var tabs = $G('tabhead').children;\r\n        for (var i = 0; i < tabs.length; i++) {\r\n            domUtils.on(tabs[i], \"click\", function (e) {\r\n                var target = e.target || e.srcElement;\r\n                setTabFocus(target.getAttribute('data-content-id'));\r\n            });\r\n        }\r\n\r\n        var img = editor.selection.getRange().getClosedNode();\r\n        if (img && img.tagName && img.tagName.toLowerCase() == 'img') {\r\n            setTabFocus('remote');\r\n        } else {\r\n            setTabFocus('upload');\r\n        }\r\n    }\r\n\r\n    /* 初始化tabbody */\r\n    function setTabFocus(id) {\r\n        if(!id) return;\r\n        var i, bodyId, tabs = $G('tabhead').children;\r\n        for (i = 0; i < tabs.length; i++) {\r\n            bodyId = tabs[i].getAttribute('data-content-id');\r\n            if (bodyId == id) {\r\n                domUtils.addClass(tabs[i], 'focus');\r\n                domUtils.addClass($G(bodyId), 'focus');\r\n            } else {\r\n                domUtils.removeClasses(tabs[i], 'focus');\r\n                domUtils.removeClasses($G(bodyId), 'focus');\r\n            }\r\n        }\r\n        switch (id) {\r\n            case 'remote':\r\n                remoteImage = remoteImage || new RemoteImage();\r\n                break;\r\n            case 'upload':\r\n                setAlign(editor.getOpt('imageInsertAlign'));\r\n                uploadImage = uploadImage || new UploadImage('queueList');\r\n                break;\r\n            case 'online':\r\n                setAlign(editor.getOpt('imageManagerInsertAlign'));\r\n                onlineImage = onlineImage || new OnlineImage('imageList');\r\n                onlineImage.reset();\r\n                break;\r\n            case 'search':\r\n                setAlign(editor.getOpt('imageManagerInsertAlign'));\r\n                searchImage = searchImage || new SearchImage();\r\n                break;\r\n        }\r\n    }\r\n\r\n    /* 初始化onok事件 */\r\n    function initButtons() {\r\n\r\n        dialog.onok = function () {\r\n            var remote = false, list = [], id, tabs = $G('tabhead').children;\r\n            for (var i = 0; i < tabs.length; i++) {\r\n                if (domUtils.hasClass(tabs[i], 'focus')) {\r\n                    id = tabs[i].getAttribute('data-content-id');\r\n                    break;\r\n                }\r\n            }\r\n\r\n            switch (id) {\r\n                case 'remote':\r\n                    list = remoteImage.getInsertList();\r\n                    break;\r\n                case 'upload':\r\n                    list = uploadImage.getInsertList();\r\n                    var count = uploadImage.getQueueCount();\r\n                    if (count) {\r\n                        $('.info', '#queueList').html('<span style=\"color:red;\">' + '还有2个未上传文件'.replace(/[\\d]/, count) + '</span>');\r\n                        return false;\r\n                    }\r\n                    break;\r\n                case 'online':\r\n                    list = onlineImage.getInsertList();\r\n                    break;\r\n                case 'search':\r\n                    list = searchImage.getInsertList();\r\n                    remote = true;\r\n                    break;\r\n            }\r\n\r\n            if(list) {\r\n                editor.execCommand('insertimage', list);\r\n                remote && editor.fireEvent(\"catchRemoteImage\");\r\n            }\r\n        };\r\n    }\r\n\r\n\r\n    /* 初始化对其方式的点击事件 */\r\n    function initAlign(){\r\n        /* 点击align图标 */\r\n        domUtils.on($G(\"alignIcon\"), 'click', function(e){\r\n            var target = e.target || e.srcElement;\r\n            if(target.className && target.className.indexOf('-align') != -1) {\r\n                setAlign(target.getAttribute('data-align'));\r\n            }\r\n        });\r\n    }\r\n\r\n    /* 设置对齐方式 */\r\n    function setAlign(align){\r\n        align = align || 'none';\r\n        var aligns = $G(\"alignIcon\").children;\r\n        for(i = 0; i < aligns.length; i++){\r\n            if(aligns[i].getAttribute('data-align') == align) {\r\n                domUtils.addClass(aligns[i], 'focus');\r\n                $G(\"align\").value = aligns[i].getAttribute('data-align');\r\n            } else {\r\n                domUtils.removeClasses(aligns[i], 'focus');\r\n            }\r\n        }\r\n    }\r\n    /* 获取对齐方式 */\r\n    function getAlign(){\r\n        var align = $G(\"align\").value || 'none';\r\n        return align == 'none' ? '':align;\r\n    }\r\n\r\n\r\n    /* 在线图片 */\r\n    function RemoteImage(target) {\r\n        this.container = utils.isString(target) ? document.getElementById(target) : target;\r\n        this.init();\r\n    }\r\n    RemoteImage.prototype = {\r\n        init: function () {\r\n            this.initContainer();\r\n            this.initEvents();\r\n        },\r\n        initContainer: function () {\r\n            this.dom = {\r\n                'url': $G('url'),\r\n                'width': $G('width'),\r\n                'height': $G('height'),\r\n                'border': $G('border'),\r\n                'vhSpace': $G('vhSpace'),\r\n                'title': $G('title'),\r\n                'align': $G('align')\r\n            };\r\n            var img = editor.selection.getRange().getClosedNode();\r\n            if (img) {\r\n                this.setImage(img);\r\n            }\r\n        },\r\n        initEvents: function () {\r\n            var _this = this,\r\n                locker = $G('lock');\r\n\r\n            /* 改变url */\r\n            domUtils.on($G(\"url\"), 'keyup', updatePreview);\r\n            domUtils.on($G(\"border\"), 'keyup', updatePreview);\r\n            domUtils.on($G(\"title\"), 'keyup', updatePreview);\r\n\r\n            domUtils.on($G(\"width\"), 'keyup', function(){\r\n                updatePreview();\r\n                if(locker.checked) {\r\n                    var proportion =locker.getAttribute('data-proportion');\r\n                    $G('height').value = Math.round(this.value / proportion);\r\n                } else {\r\n                    _this.updateLocker();\r\n                }\r\n            });\r\n            domUtils.on($G(\"height\"), 'keyup', function(){\r\n                updatePreview();\r\n                if(locker.checked) {\r\n                    var proportion =locker.getAttribute('data-proportion');\r\n                    $G('width').value = Math.round(this.value * proportion);\r\n                } else {\r\n                    _this.updateLocker();\r\n                }\r\n            });\r\n            domUtils.on($G(\"lock\"), 'change', function(){\r\n                var proportion = parseInt($G(\"width\").value) /parseInt($G(\"height\").value);\r\n                locker.setAttribute('data-proportion', proportion);\r\n            });\r\n\r\n            function updatePreview(){\r\n                _this.setPreview();\r\n            }\r\n        },\r\n        updateLocker: function(){\r\n            var width = $G('width').value,\r\n                height = $G('height').value,\r\n                locker = $G('lock');\r\n            if(width && height && width == parseInt(width) && height == parseInt(height)) {\r\n                locker.disabled = false;\r\n                locker.title = '';\r\n            } else {\r\n                locker.checked = false;\r\n                locker.disabled = 'disabled';\r\n                locker.title = lang.remoteLockError;\r\n            }\r\n        },\r\n        setImage: function(img){\r\n            /* 不是正常的图片 */\r\n            if (!img.tagName || img.tagName.toLowerCase() != 'img' && !img.getAttribute(\"src\") || !img.src) return;\r\n\r\n            var wordImgFlag = img.getAttribute(\"word_img\"),\r\n                src = wordImgFlag ? wordImgFlag.replace(\"&amp;\", \"&\") : (img.getAttribute('_src') || img.getAttribute(\"src\", 2).replace(\"&amp;\", \"&\")),\r\n                align = editor.queryCommandValue(\"imageFloat\");\r\n\r\n            /* 防止onchange事件循环调用 */\r\n            if (src !== $G(\"url\").value) $G(\"url\").value = src;\r\n            if(src) {\r\n                /* 设置表单内容 */\r\n                $G(\"width\").value = img.width || '';\r\n                $G(\"height\").value = img.height || '';\r\n                $G(\"border\").value = img.getAttribute(\"border\") || '0';\r\n                $G(\"vhSpace\").value = img.getAttribute(\"vspace\") || '0';\r\n                $G(\"title\").value = img.title || img.alt || '';\r\n                setAlign(align);\r\n                this.setPreview();\r\n                this.updateLocker();\r\n            }\r\n        },\r\n        getData: function(){\r\n            var data = {};\r\n            for(var k in this.dom){\r\n                data[k] = this.dom[k].value;\r\n            }\r\n            return data;\r\n        },\r\n        setPreview: function(){\r\n            var url = $G('url').value,\r\n                ow = parseInt($G('width').value, 10) || 0,\r\n                oh = parseInt($G('height').value, 10) || 0,\r\n                border = parseInt($G('border').value, 10) || 0,\r\n                title = $G('title').value,\r\n                preview = $G('preview'),\r\n                width,\r\n                height;\r\n\r\n            url = utils.unhtmlForUrl(url);\r\n            title = utils.unhtml(title);\r\n\r\n            width = ((!ow || !oh) ? preview.offsetWidth:Math.min(ow, preview.offsetWidth));\r\n            width = width+(border*2) > preview.offsetWidth ? width:(preview.offsetWidth - (border*2));\r\n            height = (!ow || !oh) ? '':width*oh/ow;\r\n\r\n            if(url) {\r\n                preview.innerHTML = '<img src=\"' + url + '\" width=\"' + width + '\" height=\"' + height + '\" border=\"' + border + 'px solid #000\" title=\"' + title + '\" />';\r\n            }\r\n        },\r\n        getInsertList: function () {\r\n            var data = this.getData();\r\n            if(data['url']) {\r\n                return [{\r\n                    src: data['url'],\r\n                    _src: data['url'],\r\n                    width: data['width'] || '',\r\n                    height: data['height'] || '',\r\n                    border: data['border'] || '',\r\n                    floatStyle: data['align'] || '',\r\n                    vspace: data['vhSpace'] || '',\r\n                    title: data['title'] || '',\r\n                    alt: data['title'] || '',\r\n                    style: \"width:\" + data['width'] + \"px;height:\" + data['height'] + \"px;\"\r\n                }];\r\n            } else {\r\n                return [];\r\n            }\r\n        }\r\n    };\r\n\r\n\r\n\r\n    /* 上传图片 */\r\n    function UploadImage(target) {\r\n        this.$wrap = target.constructor == String ? $('#' + target) : $(target);\r\n        this.init();\r\n    }\r\n    UploadImage.prototype = {\r\n        init: function () {\r\n            this.imageList = [];\r\n            this.initContainer();\r\n            this.initUploader();\r\n        },\r\n        initContainer: function () {\r\n            this.$queue = this.$wrap.find('.filelist');\r\n        },\r\n        /* 初始化容器 */\r\n        initUploader: function () {\r\n            var _this = this,\r\n                $ = jQuery,    // just in case. Make sure it's not an other libaray.\r\n                $wrap = _this.$wrap,\r\n            // 图片容器\r\n                $queue = $wrap.find('.filelist'),\r\n            // 状态栏，包括进度和控制按钮\r\n                $statusBar = $wrap.find('.statusBar'),\r\n            // 文件总体选择信息。\r\n                $info = $statusBar.find('.info'),\r\n            // 上传按钮\r\n                $upload = $wrap.find('.uploadBtn'),\r\n            // 上传按钮\r\n                $filePickerBtn = $wrap.find('.filePickerBtn'),\r\n            // 上传按钮\r\n                $filePickerBlock = $wrap.find('.filePickerBlock'),\r\n            // 没选择文件之前的内容。\r\n                $placeHolder = $wrap.find('.placeholder'),\r\n            // 总体进度条\r\n                $progress = $statusBar.find('.progress').hide(),\r\n            // 添加的文件数量\r\n                fileCount = 0,\r\n            // 添加的文件总大小\r\n                fileSize = 0,\r\n            // 优化retina, 在retina下这个值是2\r\n                ratio = window.devicePixelRatio || 1,\r\n            // 缩略图大小\r\n                thumbnailWidth = 113 * ratio,\r\n                thumbnailHeight = 113 * ratio,\r\n            // 可能有pedding, ready, uploading, confirm, done.\r\n                state = '',\r\n            // 所有文件的进度信息，key为file id\r\n                percentages = {},\r\n                supportTransition = (function () {\r\n                    var s = document.createElement('p').style,\r\n                        r = 'transition' in s ||\r\n                            'WebkitTransition' in s ||\r\n                            'MozTransition' in s ||\r\n                            'msTransition' in s ||\r\n                            'OTransition' in s;\r\n                    s = null;\r\n                    return r;\r\n                })(),\r\n            // WebUploader实例\r\n                uploader,\r\n                actionUrl = editor.getActionUrl(editor.getOpt('imageActionName')),\r\n                acceptExtensions = (editor.getOpt('imageAllowFiles') || []).join('').replace(/\\./g, ',').replace(/^[,]/, ''),\r\n                imageMaxSize = editor.getOpt('imageMaxSize'),\r\n                imageCompressBorder = editor.getOpt('imageCompressBorder');\r\n\r\n            if (!WebUploader.Uploader.support()) {\r\n                $('#filePickerReady').after($('<div>').html(lang.errorNotSupport)).hide();\r\n                return;\r\n            } else if (!editor.getOpt('imageActionName')) {\r\n                $('#filePickerReady').after($('<div>').html(lang.errorLoadConfig)).hide();\r\n                return;\r\n            }\r\n\r\n            uploader = _this.uploader = WebUploader.create({\r\n                pick: {\r\n                    id: '#filePickerReady',\r\n                    label: lang.uploadSelectFile\r\n                },\r\n                accept: {\r\n                    title: 'Images',\r\n                    extensions: acceptExtensions,\r\n                    mimeTypes: 'image/*'\r\n                },\r\n                swf: '../../third-party/webuploader/Uploader.swf',\r\n                server: actionUrl,\r\n                fileVal: editor.getOpt('imageFieldName'),\r\n                duplicate: true,\r\n                fileSingleSizeLimit: imageMaxSize,    // 默认 2 M\r\n                compress: editor.getOpt('imageCompressEnable') ? {\r\n                    width: imageCompressBorder,\r\n                    height: imageCompressBorder,\r\n                    // 图片质量，只有type为`image/jpeg`的时候才有效。\r\n                    quality: 90,\r\n                    // 是否允许放大，如果想要生成小图的时候不失真，此选项应该设置为false.\r\n                    allowMagnify: false,\r\n                    // 是否允许裁剪。\r\n                    crop: false,\r\n                    // 是否保留头部meta信息。\r\n                    preserveHeaders: true\r\n                }:false\r\n            });\r\n            uploader.addButton({\r\n                id: '#filePickerBlock'\r\n            });\r\n            uploader.addButton({\r\n                id: '#filePickerBtn',\r\n                label: lang.uploadAddFile\r\n            });\r\n\r\n            setState('pedding');\r\n\r\n            // 当有文件添加进来时执行，负责view的创建\r\n            function addFile(file) {\r\n                var $li = $('<li id=\"' + file.id + '\">' +\r\n                        '<p class=\"title\">' + file.name + '</p>' +\r\n                        '<p class=\"imgWrap\"></p>' +\r\n                        '<p class=\"progress\"><span></span></p>' +\r\n                        '</li>'),\r\n\r\n                    $btns = $('<div class=\"file-panel\">' +\r\n                        '<span class=\"cancel\">' + lang.uploadDelete + '</span>' +\r\n                        '<span class=\"rotateRight\">' + lang.uploadTurnRight + '</span>' +\r\n                        '<span class=\"rotateLeft\">' + lang.uploadTurnLeft + '</span></div>').appendTo($li),\r\n                    $prgress = $li.find('p.progress span'),\r\n                    $wrap = $li.find('p.imgWrap'),\r\n                    $info = $('<p class=\"error\"></p>').hide().appendTo($li),\r\n\r\n                    showError = function (code) {\r\n                        switch (code) {\r\n                            case 'exceed_size':\r\n                                text = lang.errorExceedSize;\r\n                                break;\r\n                            case 'interrupt':\r\n                                text = lang.errorInterrupt;\r\n                                break;\r\n                            case 'http':\r\n                                text = lang.errorHttp;\r\n                                break;\r\n                            case 'not_allow_type':\r\n                                text = lang.errorFileType;\r\n                                break;\r\n                            default:\r\n                                text = lang.errorUploadRetry;\r\n                                break;\r\n                        }\r\n                        $info.text(text).show();\r\n                    };\r\n\r\n                if (file.getStatus() === 'invalid') {\r\n                    showError(file.statusText);\r\n                } else {\r\n                    $wrap.text(lang.uploadPreview);\r\n                    if (browser.ie && browser.version <= 7) {\r\n                        $wrap.text(lang.uploadNoPreview);\r\n                    } else {\r\n                        uploader.makeThumb(file, function (error, src) {\r\n                            if (error || !src) {\r\n                                $wrap.text(lang.uploadNoPreview);\r\n                            } else {\r\n                                var $img = $('<img src=\"' + src + '\">');\r\n                                $wrap.empty().append($img);\r\n                                $img.on('error', function () {\r\n                                    $wrap.text(lang.uploadNoPreview);\r\n                                });\r\n                            }\r\n                        }, thumbnailWidth, thumbnailHeight);\r\n                    }\r\n                    percentages[ file.id ] = [ file.size, 0 ];\r\n                    file.rotation = 0;\r\n\r\n                    /* 检查文件格式 */\r\n                    if (!file.ext || acceptExtensions.indexOf(file.ext.toLowerCase()) == -1) {\r\n                        showError('not_allow_type');\r\n                        uploader.removeFile(file);\r\n                    }\r\n                }\r\n\r\n                file.on('statuschange', function (cur, prev) {\r\n                    if (prev === 'progress') {\r\n                        $prgress.hide().width(0);\r\n                    } else if (prev === 'queued') {\r\n                        $li.off('mouseenter mouseleave');\r\n                        $btns.remove();\r\n                    }\r\n                    // 成功\r\n                    if (cur === 'error' || cur === 'invalid') {\r\n                        showError(file.statusText);\r\n                        percentages[ file.id ][ 1 ] = 1;\r\n                    } else if (cur === 'interrupt') {\r\n                        showError('interrupt');\r\n                    } else if (cur === 'queued') {\r\n                        percentages[ file.id ][ 1 ] = 0;\r\n                    } else if (cur === 'progress') {\r\n                        $info.hide();\r\n                        $prgress.css('display', 'block');\r\n                    } else if (cur === 'complete') {\r\n                    }\r\n\r\n                    $li.removeClass('state-' + prev).addClass('state-' + cur);\r\n                });\r\n\r\n                $li.on('mouseenter', function () {\r\n                    $btns.stop().animate({height: 30});\r\n                });\r\n                $li.on('mouseleave', function () {\r\n                    $btns.stop().animate({height: 0});\r\n                });\r\n\r\n                $btns.on('click', 'span', function () {\r\n                    var index = $(this).index(),\r\n                        deg;\r\n\r\n                    switch (index) {\r\n                        case 0:\r\n                            uploader.removeFile(file);\r\n                            return;\r\n                        case 1:\r\n                            file.rotation += 90;\r\n                            break;\r\n                        case 2:\r\n                            file.rotation -= 90;\r\n                            break;\r\n                    }\r\n\r\n                    if (supportTransition) {\r\n                        deg = 'rotate(' + file.rotation + 'deg)';\r\n                        $wrap.css({\r\n                            '-webkit-transform': deg,\r\n                            '-mos-transform': deg,\r\n                            '-o-transform': deg,\r\n                            'transform': deg\r\n                        });\r\n                    } else {\r\n                        $wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')');\r\n                    }\r\n\r\n                });\r\n\r\n                $li.insertBefore($filePickerBlock);\r\n            }\r\n\r\n            // 负责view的销毁\r\n            function removeFile(file) {\r\n                var $li = $('#' + file.id);\r\n                delete percentages[ file.id ];\r\n                updateTotalProgress();\r\n                $li.off().find('.file-panel').off().end().remove();\r\n            }\r\n\r\n            function updateTotalProgress() {\r\n                var loaded = 0,\r\n                    total = 0,\r\n                    spans = $progress.children(),\r\n                    percent;\r\n\r\n                $.each(percentages, function (k, v) {\r\n                    total += v[ 0 ];\r\n                    loaded += v[ 0 ] * v[ 1 ];\r\n                });\r\n\r\n                percent = total ? loaded / total : 0;\r\n\r\n                spans.eq(0).text(Math.round(percent * 100) + '%');\r\n                spans.eq(1).css('width', Math.round(percent * 100) + '%');\r\n                updateStatus();\r\n            }\r\n\r\n            function setState(val, files) {\r\n\r\n                if (val != state) {\r\n\r\n                    var stats = uploader.getStats();\r\n\r\n                    $upload.removeClass('state-' + state);\r\n                    $upload.addClass('state-' + val);\r\n\r\n                    switch (val) {\r\n\r\n                        /* 未选择文件 */\r\n                        case 'pedding':\r\n                            $queue.addClass('element-invisible');\r\n                            $statusBar.addClass('element-invisible');\r\n                            $placeHolder.removeClass('element-invisible');\r\n                            $progress.hide(); $info.hide();\r\n                            uploader.refresh();\r\n                            break;\r\n\r\n                        /* 可以开始上传 */\r\n                        case 'ready':\r\n                            $placeHolder.addClass('element-invisible');\r\n                            $queue.removeClass('element-invisible');\r\n                            $statusBar.removeClass('element-invisible');\r\n                            $progress.hide(); $info.show();\r\n                            $upload.text(lang.uploadStart);\r\n                            uploader.refresh();\r\n                            break;\r\n\r\n                        /* 上传中 */\r\n                        case 'uploading':\r\n                            $progress.show(); $info.hide();\r\n                            $upload.text(lang.uploadPause);\r\n                            break;\r\n\r\n                        /* 暂停上传 */\r\n                        case 'paused':\r\n                            $progress.show(); $info.hide();\r\n                            $upload.text(lang.uploadContinue);\r\n                            break;\r\n\r\n                        case 'confirm':\r\n                            $progress.show(); $info.hide();\r\n                            $upload.text(lang.uploadStart);\r\n\r\n                            stats = uploader.getStats();\r\n                            if (stats.successNum && !stats.uploadFailNum) {\r\n                                setState('finish');\r\n                                return;\r\n                            }\r\n                            break;\r\n\r\n                        case 'finish':\r\n                            $progress.hide(); $info.show();\r\n                            if (stats.uploadFailNum) {\r\n                                $upload.text(lang.uploadRetry);\r\n                            } else {\r\n                                $upload.text(lang.uploadStart);\r\n                            }\r\n                            break;\r\n                    }\r\n\r\n                    state = val;\r\n                    updateStatus();\r\n\r\n                }\r\n\r\n                if (!_this.getQueueCount()) {\r\n                    $upload.addClass('disabled')\r\n                } else {\r\n                    $upload.removeClass('disabled')\r\n                }\r\n\r\n            }\r\n\r\n            function updateStatus() {\r\n                var text = '', stats;\r\n\r\n                if (state === 'ready') {\r\n                    text = lang.updateStatusReady.replace('_', fileCount).replace('_KB', WebUploader.formatSize(fileSize));\r\n                } else if (state === 'confirm') {\r\n                    stats = uploader.getStats();\r\n                    if (stats.uploadFailNum) {\r\n                        text = lang.updateStatusConfirm.replace('_', stats.successNum).replace('_', stats.successNum);\r\n                    }\r\n                } else {\r\n                    stats = uploader.getStats();\r\n                    text = lang.updateStatusFinish.replace('_', fileCount).\r\n                        replace('_KB', WebUploader.formatSize(fileSize)).\r\n                        replace('_', stats.successNum);\r\n\r\n                    if (stats.uploadFailNum) {\r\n                        text += lang.updateStatusError.replace('_', stats.uploadFailNum);\r\n                    }\r\n                }\r\n\r\n                $info.html(text);\r\n            }\r\n\r\n            uploader.on('fileQueued', function (file) {\r\n                fileCount++;\r\n                fileSize += file.size;\r\n\r\n                if (fileCount === 1) {\r\n                    $placeHolder.addClass('element-invisible');\r\n                    $statusBar.show();\r\n                }\r\n\r\n                addFile(file);\r\n            });\r\n\r\n            uploader.on('fileDequeued', function (file) {\r\n                fileCount--;\r\n                fileSize -= file.size;\r\n\r\n                removeFile(file);\r\n                updateTotalProgress();\r\n            });\r\n\r\n            uploader.on('filesQueued', function (file) {\r\n                if (!uploader.isInProgress() && (state == 'pedding' || state == 'finish' || state == 'confirm' || state == 'ready')) {\r\n                    setState('ready');\r\n                }\r\n                updateTotalProgress();\r\n            });\r\n\r\n            uploader.on('all', function (type, files) {\r\n                switch (type) {\r\n                    case 'uploadFinished':\r\n                        setState('confirm', files);\r\n                        break;\r\n                    case 'startUpload':\r\n                        /* 添加额外的GET参数 */\r\n                        var params = utils.serializeParam(editor.queryCommandValue('serverparam')) || '',\r\n                            url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + 'encode=utf-8&' + params);\r\n                        uploader.option('server', url);\r\n                        setState('uploading', files);\r\n                        break;\r\n                    case 'stopUpload':\r\n                        setState('paused', files);\r\n                        break;\r\n                }\r\n            });\r\n\r\n            uploader.on('uploadBeforeSend', function (file, data, header) {\r\n                //这里可以通过data对象添加POST参数\r\n                header['X_Requested_With'] = 'XMLHttpRequest';\r\n            });\r\n\r\n            uploader.on('uploadProgress', function (file, percentage) {\r\n                var $li = $('#' + file.id),\r\n                    $percent = $li.find('.progress span');\r\n\r\n                $percent.css('width', percentage * 100 + '%');\r\n                percentages[ file.id ][ 1 ] = percentage;\r\n                updateTotalProgress();\r\n            });\r\n\r\n            uploader.on('uploadSuccess', function (file, ret) {\r\n                var $file = $('#' + file.id);\r\n                try {\r\n                    var responseText = (ret._raw || ret),\r\n                        json = utils.str2json(responseText);\r\n                    if (json.state == 'SUCCESS') {\r\n                        _this.imageList.push(json);\r\n                        $file.append('<span class=\"success\"></span>');\r\n                    } else {\r\n                        $file.find('.error').text(json.state).show();\r\n                    }\r\n                } catch (e) {\r\n                    $file.find('.error').text(lang.errorServerUpload).show();\r\n                }\r\n            });\r\n\r\n            uploader.on('uploadError', function (file, code) {\r\n            });\r\n            uploader.on('error', function (code, file) {\r\n                if (code == 'Q_TYPE_DENIED' || code == 'F_EXCEED_SIZE') {\r\n                    addFile(file);\r\n                }\r\n            });\r\n            uploader.on('uploadComplete', function (file, ret) {\r\n            });\r\n\r\n            $upload.on('click', function () {\r\n                if ($(this).hasClass('disabled')) {\r\n                    return false;\r\n                }\r\n\r\n                if (state === 'ready') {\r\n                    uploader.upload();\r\n                } else if (state === 'paused') {\r\n                    uploader.upload();\r\n                } else if (state === 'uploading') {\r\n                    uploader.stop();\r\n                }\r\n            });\r\n\r\n            $upload.addClass('state-' + state);\r\n            updateTotalProgress();\r\n        },\r\n        getQueueCount: function () {\r\n            var file, i, status, readyFile = 0, files = this.uploader.getFiles();\r\n            for (i = 0; file = files[i++]; ) {\r\n                status = file.getStatus();\r\n                if (status == 'queued' || status == 'uploading' || status == 'progress') readyFile++;\r\n            }\r\n            return readyFile;\r\n        },\r\n        destroy: function () {\r\n            this.$wrap.remove();\r\n        },\r\n        getInsertList: function () {\r\n            var i, data, list = [],\r\n                align = getAlign(),\r\n                prefix = editor.getOpt('imageUrlPrefix');\r\n            for (i = 0; i < this.imageList.length; i++) {\r\n                data = this.imageList[i];\r\n                list.push({\r\n                    src: prefix + data.url,\r\n                    _src: prefix + data.url,\r\n                    title: data.title,\r\n                    alt: data.original,\r\n                    floatStyle: align\r\n                });\r\n            }\r\n            return list;\r\n        }\r\n    };\r\n\r\n\r\n    /* 在线图片 */\r\n    function OnlineImage(target) {\r\n        this.container = utils.isString(target) ? document.getElementById(target) : target;\r\n        this.init();\r\n    }\r\n    OnlineImage.prototype = {\r\n        init: function () {\r\n            this.reset();\r\n            this.initEvents();\r\n        },\r\n        /* 初始化容器 */\r\n        initContainer: function () {\r\n            this.container.innerHTML = '';\r\n            this.list = document.createElement('ul');\r\n            this.clearFloat = document.createElement('li');\r\n\r\n            domUtils.addClass(this.list, 'list');\r\n            domUtils.addClass(this.clearFloat, 'clearFloat');\r\n\r\n            this.list.appendChild(this.clearFloat);\r\n            this.container.appendChild(this.list);\r\n        },\r\n        /* 初始化滚动事件,滚动到地步自动拉取数据 */\r\n        initEvents: function () {\r\n            var _this = this;\r\n\r\n            /* 滚动拉取图片 */\r\n            domUtils.on($G('imageList'), 'scroll', function(e){\r\n                var panel = this;\r\n                if (panel.scrollHeight - (panel.offsetHeight + panel.scrollTop) < 10) {\r\n                    _this.getImageData();\r\n                }\r\n            });\r\n            /* 选中图片 */\r\n            domUtils.on(this.container, 'click', function (e) {\r\n                var target = e.target || e.srcElement,\r\n                    li = target.parentNode;\r\n\r\n                if (li.tagName.toLowerCase() == 'li') {\r\n                    if (domUtils.hasClass(li, 'selected')) {\r\n                        domUtils.removeClasses(li, 'selected');\r\n                    } else {\r\n                        domUtils.addClass(li, 'selected');\r\n                    }\r\n                }\r\n            });\r\n        },\r\n        /* 初始化第一次的数据 */\r\n        initData: function () {\r\n\r\n            /* 拉取数据需要使用的值 */\r\n            this.state = 0;\r\n            this.listSize = editor.getOpt('imageManagerListSize');\r\n            this.listIndex = 0;\r\n            this.listEnd = false;\r\n\r\n            /* 第一次拉取数据 */\r\n            this.getImageData();\r\n        },\r\n        /* 重置界面 */\r\n        reset: function() {\r\n            this.initContainer();\r\n            this.initData();\r\n        },\r\n        /* 向后台拉取图片列表数据 */\r\n        getImageData: function () {\r\n            var _this = this;\r\n\r\n            if(!_this.listEnd && !this.isLoadingData) {\r\n                this.isLoadingData = true;\r\n                var url = editor.getActionUrl(editor.getOpt('imageManagerActionName')),\r\n                    isJsonp = utils.isCrossDomainUrl(url);\r\n                ajax.request(url, {\r\n                    'timeout': 100000,\r\n                    'dataType': isJsonp ? 'jsonp':'',\r\n                    'data': utils.extend({\r\n                            start: this.listIndex,\r\n                            size: this.listSize\r\n                        }, editor.queryCommandValue('serverparam')),\r\n                    'method': 'get',\r\n                    'onsuccess': function (r) {\r\n                        try {\r\n                            var json = isJsonp ? r:eval('(' + r.responseText + ')');\r\n                            if (json.state == 'SUCCESS') {\r\n                                _this.pushData(json.list);\r\n                                _this.listIndex = parseInt(json.start) + parseInt(json.list.length);\r\n                                if(_this.listIndex >= json.total) {\r\n                                    _this.listEnd = true;\r\n                                }\r\n                                _this.isLoadingData = false;\r\n                            }\r\n                        } catch (e) {\r\n                            if(r.responseText.indexOf('ue_separate_ue') != -1) {\r\n                                var list = r.responseText.split(r.responseText);\r\n                                _this.pushData(list);\r\n                                _this.listIndex = parseInt(list.length);\r\n                                _this.listEnd = true;\r\n                                _this.isLoadingData = false;\r\n                            }\r\n                        }\r\n                    },\r\n                    'onerror': function () {\r\n                        _this.isLoadingData = false;\r\n                    }\r\n                });\r\n            }\r\n        },\r\n        /* 添加图片到列表界面上 */\r\n        pushData: function (list) {\r\n            var i, item, img, icon, _this = this,\r\n                urlPrefix = editor.getOpt('imageManagerUrlPrefix');\r\n            for (i = 0; i < list.length; i++) {\r\n                if(list[i] && list[i].url) {\r\n                    item = document.createElement('li');\r\n                    img = document.createElement('img');\r\n                    icon = document.createElement('span');\r\n\r\n                    domUtils.on(img, 'load', (function(image){\r\n                        return function(){\r\n                            _this.scale(image, image.parentNode.offsetWidth, image.parentNode.offsetHeight);\r\n                        }\r\n                    })(img));\r\n                    img.width = 113;\r\n                    img.setAttribute('src', urlPrefix + list[i].url + (list[i].url.indexOf('?') == -1 ? '?noCache=':'&noCache=') + (+new Date()).toString(36) );\r\n                    img.setAttribute('_src', urlPrefix + list[i].url);\r\n                    domUtils.addClass(icon, 'icon');\r\n\r\n                    item.appendChild(img);\r\n                    item.appendChild(icon);\r\n                    this.list.insertBefore(item, this.clearFloat);\r\n                }\r\n            }\r\n        },\r\n        /* 改变图片大小 */\r\n        scale: function (img, w, h, type) {\r\n            var ow = img.width,\r\n                oh = img.height;\r\n\r\n            if (type == 'justify') {\r\n                if (ow >= oh) {\r\n                    img.width = w;\r\n                    img.height = h * oh / ow;\r\n                    img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';\r\n                } else {\r\n                    img.width = w * ow / oh;\r\n                    img.height = h;\r\n                    img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';\r\n                }\r\n            } else {\r\n                if (ow >= oh) {\r\n                    img.width = w * ow / oh;\r\n                    img.height = h;\r\n                    img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';\r\n                } else {\r\n                    img.width = w;\r\n                    img.height = h * oh / ow;\r\n                    img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';\r\n                }\r\n            }\r\n        },\r\n        getInsertList: function () {\r\n            var i, lis = this.list.children, list = [], align = getAlign();\r\n            for (i = 0; i < lis.length; i++) {\r\n                if (domUtils.hasClass(lis[i], 'selected')) {\r\n                    var img = lis[i].firstChild,\r\n                        src = img.getAttribute('_src');\r\n                    list.push({\r\n                        src: src,\r\n                        _src: src,\r\n                        alt: src.substr(src.lastIndexOf('/') + 1),\r\n                        floatStyle: align\r\n                    });\r\n                }\r\n\r\n            }\r\n            return list;\r\n        }\r\n    };\r\n\r\n    /*搜索图片 */\r\n    function SearchImage() {\r\n        this.init();\r\n    }\r\n    SearchImage.prototype = {\r\n        init: function () {\r\n            this.initEvents();\r\n        },\r\n        initEvents: function(){\r\n            var _this = this;\r\n\r\n            /* 点击搜索按钮 */\r\n            domUtils.on($G('searchBtn'), 'click', function(){\r\n                var key = $G('searchTxt').value;\r\n                if(key && key != lang.searchRemind) {\r\n                    _this.getImageData();\r\n                }\r\n            });\r\n            /* 点击清除妞 */\r\n            domUtils.on($G('searchReset'), 'click', function(){\r\n                $G('searchTxt').value = lang.searchRemind;\r\n                $G('searchListUl').innerHTML = '';\r\n                $G('searchType').selectedIndex = 0;\r\n            });\r\n            /* 搜索框聚焦 */\r\n            domUtils.on($G('searchTxt'), 'focus', function(){\r\n                var key = $G('searchTxt').value;\r\n                if(key && key == lang.searchRemind) {\r\n                    $G('searchTxt').value = '';\r\n                }\r\n            });\r\n            /* 搜索框回车键搜索 */\r\n            domUtils.on($G('searchTxt'), 'keydown', function(e){\r\n                var keyCode = e.keyCode || e.which;\r\n                if (keyCode == 13) {\r\n                    $G('searchBtn').click();\r\n                }\r\n            });\r\n\r\n            /* 选中图片 */\r\n            domUtils.on($G('searchList'), 'click', function(e){\r\n                var target = e.target || e.srcElement,\r\n                    li = target.parentNode.parentNode;\r\n\r\n                if (li.tagName.toLowerCase() == 'li') {\r\n                    if (domUtils.hasClass(li, 'selected')) {\r\n                        domUtils.removeClasses(li, 'selected');\r\n                    } else {\r\n                        domUtils.addClass(li, 'selected');\r\n                    }\r\n                }\r\n            });\r\n        },\r\n        encodeToGb2312:function (str){\r\n            if(!str) return '';\r\n            var strOut = \"\",\r\n                z = 'D2BBB6A18140C6DF814181428143CDF2D5C9C8FDC9CFCFC2D8A2B2BBD3EB8144D8A4B3F38145D7A8C7D2D8A7CAC08146C7F0B1FBD2B5B4D4B6ABCBBFD8A9814781488149B6AA814AC1BDD1CF814BC9A5D8AD814CB8F6D1BEE3DCD6D0814D814EB7E1814FB4AE8150C1D98151D8BC8152CDE8B5A4CEAAD6F78153C0F6BED9D8AF815481558156C4CB8157BEC38158D8B1C3B4D2E58159D6AECEDAD5A7BAF5B7A6C0D6815AC6B9C5D2C7C7815BB9D4815CB3CBD2D2815D815ED8BFBEC5C6F2D2B2CFB0CFE7815F816081618162CAE981638164D8C081658166816781688169816AC2F2C2D2816BC8E9816C816D816E816F817081718172817381748175C7AC8176817781788179817A817B817CC1CB817DD3E8D5F9817ECAC2B6FED8A1D3DABFF78180D4C6BBA5D8C1CEE5BEAE81818182D8A88183D1C7D0A9818481858186D8BDD9EFCDF6BFBA8187BDBBBAA5D2E0B2FABAE0C4B68188CFEDBEA9CDA4C1C18189818A818BC7D7D9F1818CD9F4818D818E818F8190C8CBD8E9819181928193D2DACAB2C8CAD8ECD8EAD8C6BDF6C6CDB3F08194D8EBBDF1BDE98195C8D4B4D381968197C2D88198B2D6D7D0CACBCBFBD5CCB8B6CFC98199819A819BD9DAD8F0C7AA819CD8EE819DB4FAC1EED2D4819E819FD8ED81A0D2C7D8EFC3C781A181A281A3D1F681A4D6D9D8F281A5D8F5BCFEBCDB81A681A781A8C8CE81A9B7DD81AAB7C281ABC6F381AC81AD81AE81AF81B081B181B2D8F8D2C181B381B4CEE9BCBFB7FCB7A5D0DD81B581B681B781B881B9D6DAD3C5BBEFBBE1D8F181BA81BBC9A1CEB0B4AB81BCD8F381BDC9CBD8F6C2D7D8F781BE81BFCEB1D8F981C081C181C2B2AEB9C081C3D9A381C4B0E981C5C1E681C6C9EC81C7CBC581C8CBC6D9A481C981CA81CB81CC81CDB5E881CE81CFB5AB81D081D181D281D381D481D5CEBBB5CDD7A1D7F4D3D381D6CCE581D7BACE81D8D9A2D9DCD3E0D8FDB7F0D7F7D8FED8FAD9A1C4E381D981DAD3B6D8F4D9DD81DBD8FB81DCC5E581DD81DEC0D081DF81E0D1F0B0DB81E181E2BCD1D9A681E3D9A581E481E581E681E7D9ACD9AE81E8D9ABCAB981E981EA81EBD9A9D6B681EC81ED81EEB3DED9A881EFC0FD81F0CACC81F1D9AA81F2D9A781F381F4D9B081F581F6B6B181F781F881F9B9A981FAD2C081FB81FCCFC081FD81FEC2C28240BDC4D5ECB2E0C7C8BFEBD9AD8241D9AF8242CEEABAEE82438244824582468247C7D682488249824A824B824C824D824E824F8250B1E3825182528253B4D9B6EDD9B48254825582568257BFA182588259825AD9DEC7CEC0FED9B8825B825C825D825E825FCBD7B7FD8260D9B58261D9B7B1A3D3E1D9B98262D0C58263D9B682648265D9B18266D9B2C1A9D9B382678268BCF3D0DEB8A98269BEE3826AD9BD826B826C826D826ED9BA826FB0B3827082718272D9C28273827482758276827782788279827A827B827C827D827E8280D9C4B1B68281D9BF82828283B5B98284BEF3828582868287CCC8BAF2D2D08288D9C38289828ABDE8828BB3AB828C828D828ED9C5BEEB828FD9C6D9BBC4DF8290D9BED9C1D9C0829182928293829482958296829782988299829A829BD5AE829CD6B5829DC7E3829E829F82A082A1D9C882A282A382A4BCD9D9CA82A582A682A7D9BC82A8D9CBC6AB82A982AA82AB82AC82ADD9C982AE82AF82B082B1D7F682B2CDA382B382B482B582B682B782B882B982BABDA182BB82BC82BD82BE82BF82C0D9CC82C182C282C382C482C582C682C782C882C9C5BCCDB582CA82CB82CCD9CD82CD82CED9C7B3A5BFFE82CF82D082D182D2B8B582D382D4C0FC82D582D682D782D8B0F882D982DA82DB82DC82DD82DE82DF82E082E182E282E382E482E582E682E782E882E982EA82EB82EC82EDB4F682EED9CE82EFD9CFB4A2D9D082F082F1B4DF82F282F382F482F582F6B0C182F782F882F982FA82FB82FC82FDD9D1C9B582FE8340834183428343834483458346834783488349834A834B834C834D834E834F83508351CFF1835283538354835583568357D9D283588359835AC1C5835B835C835D835E835F836083618362836383648365D9D6C9AE8366836783688369D9D5D9D4D9D7836A836B836C836DCBDB836EBDA9836F8370837183728373C6A7837483758376837783788379837A837B837C837DD9D3D9D8837E83808381D9D9838283838384838583868387C8E583888389838A838B838C838D838E838F839083918392839383948395C0DC8396839783988399839A839B839C839D839E839F83A083A183A283A383A483A583A683A783A883A983AA83AB83AC83AD83AE83AF83B083B183B2B6F9D8A3D4CA83B3D4AAD0D6B3E4D5D783B4CFC8B9E283B5BFCB83B6C3E283B783B883B9B6D283BA83BBCDC3D9EED9F083BC83BD83BEB5B383BFB6B583C083C183C283C383C4BEA483C583C6C8EB83C783C8C8AB83C983CAB0CBB9ABC1F9D9E283CBC0BCB9B283CCB9D8D0CBB1F8C6E4BEDFB5E4D7C883CDD1F8BCE6CADE83CE83CFBCBDD9E6D8E783D083D1C4DA83D283D3B8D4C8BD83D483D5B2E1D4D983D683D783D883D9C3B083DA83DBC3E1DAA2C8DF83DCD0B483DDBEFCC5A983DE83DF83E0B9DA83E1DAA383E2D4A9DAA483E383E483E583E683E7D9FBB6AC83E883E9B7EBB1F9D9FCB3E5BEF683EABFF6D2B1C0E483EB83EC83EDB6B3D9FED9FD83EE83EFBEBB83F083F183F2C6E083F3D7BCDAA183F4C1B983F5B5F2C1E883F683F7BCF583F8B4D583F983FA83FB83FC83FD83FE844084418442C1DD8443C4FD84448445BCB8B7B284468447B7EF84488449844A844B844C844DD9EC844EC6BE844FBFADBBCB84508451B5CA8452DBC9D0D78453CDB9B0BCB3F6BBF7DBCABAAF8454D4E4B5B6B5F3D8D6C8D084558456B7D6C7D0D8D78457BFAF84588459DBBBD8D8845A845BD0CCBBAE845C845D845EEBBEC1D0C1F5D4F2B8D5B4B4845FB3F584608461C9BE846284638464C5D0846584668467C5D9C0FB8468B1F08469D8D9B9CE846AB5BD846B846CD8DA846D846ED6C6CBA2C8AFC9B2B4CCBFCC846FB9F48470D8DBD8DCB6E7BCC1CCEA847184728473847484758476CFF78477D8DDC7B084788479B9D0BDA3847A847BCCDE847CC6CA847D847E848084818482D8E08483D8DE84848485D8DF848684878488B0FE8489BEE7848ACAA3BCF4848B848C848D848EB8B1848F8490B8EE849184928493849484958496849784988499849AD8E2849BBDCB849CD8E4D8E3849D849E849F84A084A1C5FC84A284A384A484A584A684A784A8D8E584A984AAD8E684AB84AC84AD84AE84AF84B084B1C1A684B2C8B0B0ECB9A6BCD3CEF1DBBDC1D384B384B484B584B6B6AFD6FAC5ACBDD9DBBEDBBF84B784B884B9C0F8BEA2C0CD84BA84BB84BC84BD84BE84BF84C084C184C284C3DBC0CAC684C484C584C6B2AA84C784C884C9D3C284CAC3E384CBD1AB84CC84CD84CE84CFDBC284D0C0D584D184D284D3DBC384D4BFB184D584D684D784D884D984DAC4BC84DB84DC84DD84DEC7DA84DF84E084E184E284E384E484E584E684E784E884E9DBC484EA84EB84EC84ED84EE84EF84F084F1D9E8C9D784F284F384F4B9B4CEF0D4C884F584F684F784F8B0FCB4D284F9D0D984FA84FB84FC84FDD9E984FEDECBD9EB8540854185428543D8B0BBAFB1B18544B3D7D8CE85458546D4D185478548BDB3BFEF8549CFBB854A854BD8D0854C854D854EB7CB854F85508551D8D185528553855485558556855785588559855A855BC6A5C7F8D2BD855C855DD8D2C4E4855ECAAE855FC7A78560D8A68561C9FDCEE7BBDCB0EB856285638564BBAAD0AD8565B1B0D7E4D7BF8566B5A5C2F4C4CF85678568B2A98569B2B7856AB1E5DFB2D5BCBFA8C2ACD8D5C2B1856BD8D4CED4856CDAE0856DCEC0856E856FD8B4C3AED3A1CEA38570BCB4C8B4C2D18571BEEDD0B68572DAE18573857485758576C7E485778578B3A78579B6F2CCFCC0FA857A857BC0F7857CD1B9D1E1D8C7857D857E85808581858285838584B2DE85858586C0E58587BAF185888589D8C8858AD4AD858B858CCFE1D8C9858DD8CACFC3858EB3F8BEC7858F859085918592D8CB8593859485958596859785988599DBCC859A859B859C859DC8A5859E859F85A0CFD885A1C8FEB2CE85A285A385A485A585A6D3D6B2E6BCB0D3D1CBABB7B485A785A885A9B7A285AA85ABCAE585ACC8A1CADCB1E4D0F085ADC5D185AE85AF85B0DBC5B5FE85B185B2BFDAB9C5BEE4C1ED85B3DFB6DFB5D6BBBDD0D5D9B0C8B6A3BFC9CCA8DFB3CAB7D3D285B4D8CFD2B6BAC5CBBECCBE85B5DFB7B5F0DFB485B685B785B8D3F585B9B3D4B8F785BADFBA85BBBACFBCAAB5F585BCCDACC3FBBAF3C0F4CDC2CFF2DFB8CFC585BDC2C0DFB9C2F085BE85BF85C0BEFD85C1C1DFCDCCD2F7B7CDDFC185C2DFC485C385C4B7F1B0C9B6D6B7D485C5BAACCCFDBFD4CBB1C6F485C6D6A8DFC585C7CEE2B3B385C885C9CEFCB4B585CACEC7BAF085CBCEE185CCD1BD85CD85CEDFC085CF85D0B4F485D1B3CA85D2B8E6DFBB85D385D485D585D6C4C585D7DFBCDFBDDFBEC5BBDFBFDFC2D4B1DFC385D8C7BACED885D985DA85DB85DC85DDC4D885DEDFCA85DFDFCF85E0D6DC85E185E285E385E485E585E685E785E8DFC9DFDACEB685E9BAC7DFCEDFC8C5DE85EA85EBC9EBBAF4C3FC85EC85EDBED785EEDFC685EFDFCD85F0C5D885F185F285F385F4D5A6BACD85F5BECCD3BDB8C085F6D6E485F7DFC7B9BEBFA785F885F9C1FCDFCBDFCC85FADFD085FB85FC85FD85FE8640DFDBDFE58641DFD7DFD6D7C9DFE3DFE4E5EBD2A7DFD28642BFA98643D4DB8644BFC8DFD4864586468647CFCC86488649DFDD864AD1CA864BDFDEB0A7C6B7DFD3864CBAE5864DB6DFCDDBB9FED4D5864E864FDFDFCFECB0A5DFE7DFD1D1C6DFD5DFD8DFD9DFDC8650BBA98651DFE0DFE18652DFE2DFE6DFE8D3B486538654865586568657B8E7C5B6DFEAC9DAC1A8C4C486588659BFDECFF8865A865B865CD5DCDFEE865D865E865F866086618662B2B88663BADFDFEC8664DBC18665D1E48666866786688669CBF4B4BD866AB0A6866B866C866D866E866FDFF1CCC6DFF286708671DFED867286738674867586768677DFE986788679867A867BDFEB867CDFEFDFF0BBBD867D867EDFF386808681DFF48682BBA38683CADBCEA8E0A7B3AA8684E0A6868586868687E0A186888689868A868BDFFE868CCDD9DFFC868DDFFA868EBFD0D7C4868FC9CC86908691DFF8B0A186928693869486958696DFFD869786988699869ADFFBE0A2869B869C869D869E869FE0A886A086A186A286A3B7C886A486A5C6A1C9B6C0B2DFF586A686A7C5BE86A8D8C4DFF9C4F686A986AA86AB86AC86AD86AEE0A3E0A4E0A5D0A586AF86B0E0B4CCE486B1E0B186B2BFA6E0AFCEB9E0ABC9C686B386B4C0AEE0AEBAEDBAB0E0A986B586B686B7DFF686B8E0B386B986BAE0B886BB86BC86BDB4ADE0B986BE86BFCFB2BAC886C0E0B086C186C286C386C486C586C686C7D0FA86C886C986CA86CB86CC86CD86CE86CF86D0E0AC86D1D4FB86D2DFF786D3C5E786D4E0AD86D5D3F786D6E0B6E0B786D786D886D986DA86DBE0C4D0E186DC86DD86DEE0BC86DF86E0E0C9E0CA86E186E286E3E0BEE0AAC9A4E0C186E4E0B286E586E686E786E886E9CAC8E0C386EAE0B586EBCECB86ECCBC3E0CDE0C6E0C286EDE0CB86EEE0BAE0BFE0C086EF86F0E0C586F186F2E0C7E0C886F3E0CC86F4E0BB86F586F686F786F886F9CBD4E0D586FAE0D6E0D286FB86FC86FD86FE87408741E0D0BCCE87428743E0D18744B8C2D8C587458746874787488749874A874B874CD0EA874D874EC2EF874F8750E0CFE0BD875187528753E0D4E0D387548755E0D78756875787588759E0DCE0D8875A875B875CD6F6B3B0875DD7EC875ECBBB875F8760E0DA8761CEFB876287638764BAD987658766876787688769876A876B876C876D876E876F8770E0E1E0DDD2AD87718772877387748775E0E287768777E0DBE0D9E0DF87788779E0E0877A877B877C877D877EE0DE8780E0E4878187828783C6F7D8ACD4EBE0E6CAC98784878587868787E0E587888789878A878BB8C1878C878D878E878FE0E7E0E887908791879287938794879587968797E0E9E0E387988799879A879B879C879D879EBABFCCE7879F87A087A1E0EA87A287A387A487A587A687A787A887A987AA87AB87AC87AD87AE87AF87B0CFF987B187B287B387B487B587B687B787B887B987BA87BBE0EB87BC87BD87BE87BF87C087C187C2C8C287C387C487C587C6BDC087C787C887C987CA87CB87CC87CD87CE87CF87D087D187D287D3C4D287D487D587D687D787D887D987DA87DB87DCE0EC87DD87DEE0ED87DF87E0C7F4CBC487E1E0EEBBD8D8B6D2F2E0EFCDC587E2B6DA87E387E487E587E687E787E8E0F187E9D4B087EA87EBC0A7B4D187EC87EDCEA7E0F087EE87EF87F0E0F2B9CC87F187F2B9FACDBCE0F387F387F487F5C6D4E0F487F6D4B287F7C8A6E0F6E0F587F887F987FA87FB87FC87FD87FE8840884188428843884488458846884788488849E0F7884A884BCDC1884C884D884ECAA5884F885088518852D4DADBD7DBD98853DBD8B9E7DBDCDBDDB5D888548855DBDA8856885788588859885ADBDBB3A1DBDF885B885CBBF8885DD6B7885EDBE0885F886088618862BEF988638864B7BB8865DBD0CCAEBFB2BBB5D7F8BFD38866886788688869886ABFE9886B886CBCE1CCB3DBDEB0D3CEEBB7D8D7B9C6C2886D886EC0A4886FCCB98870DBE7DBE1C6BADBE38871DBE88872C5F7887388748875DBEA88768877DBE9BFC088788879887ADBE6DBE5887B887C887D887E8880B4B9C0ACC2A2DBE2DBE48881888288838884D0CDDBED88858886888788888889C0DDDBF2888A888B888C888D888E888F8890B6E28891889288938894DBF3DBD2B9B8D4ABDBEC8895BFD1DBF08896DBD18897B5E68898DBEBBFE58899889A889BDBEE889CDBF1889D889E889FDBF988A088A188A288A388A488A588A688A788A8B9A1B0A388A988AA88AB88AC88AD88AE88AFC2F188B088B1B3C7DBEF88B288B3DBF888B4C6D2DBF488B588B6DBF5DBF7DBF688B788B8DBFE88B9D3F2B2BA88BA88BB88BCDBFD88BD88BE88BF88C088C188C288C388C4DCA488C5DBFB88C688C788C888C9DBFA88CA88CB88CCDBFCC5E0BBF988CD88CEDCA388CF88D0DCA588D1CCC388D288D388D4B6D1DDC088D588D688D7DCA188D8DCA288D988DA88DBC7B588DC88DD88DEB6E988DF88E088E1DCA788E288E388E488E5DCA688E6DCA9B1A488E788E8B5CC88E988EA88EB88EC88EDBFB088EE88EF88F088F188F2D1DF88F388F488F588F6B6C288F788F888F988FA88FB88FC88FD88FE894089418942894389448945DCA88946894789488949894A894B894CCBFAEBF3894D894E894FCBDC89508951CBFE895289538954CCC189558956895789588959C8FB895A895B895C895D895E895FDCAA89608961896289638964CCEEDCAB89658966896789688969896A896B896C896D896E896F897089718972897389748975DBD38976DCAFDCAC8977BEB38978CAFB8979897A897BDCAD897C897D897E89808981898289838984C9CAC4B989858986898789888989C7BDDCAE898A898B898CD4F6D0E6898D898E898F89908991899289938994C4ABB6D589958996899789988999899A899B899C899D899E899F89A089A189A289A389A489A589A6DBD489A789A889A989AAB1DA89AB89AC89ADDBD589AE89AF89B089B189B289B389B489B589B689B789B8DBD689B989BA89BBBABE89BC89BD89BE89BF89C089C189C289C389C489C589C689C789C889C9C8C089CA89CB89CC89CD89CE89CFCABFC8C989D0D7B389D1C9F989D289D3BFC789D489D5BAF889D689D7D2BC89D889D989DA89DB89DC89DD89DE89DFE2BA89E0B4A689E189E2B1B889E389E489E589E689E7B8B489E8CFC489E989EA89EB89ECD9E7CFA6CDE289ED89EED9EDB6E089EFD2B989F089F1B9BB89F289F389F489F5E2B9E2B789F6B4F389F7CCECCCABB7F289F8D8B2D1EBBABB89F9CAA789FA89FBCDB789FC89FDD2C4BFE4BCD0B6E189FEDEC58A408A418A428A43DEC6DBBC8A44D1D98A458A46C6E6C4CEB7EE8A47B7DC8A488A49BFFCD7E08A4AC6F58A4B8A4CB1BCDEC8BDB1CCD7DECA8A4DDEC98A4E8A4F8A508A518A52B5EC8A53C9DD8A548A55B0C28A568A578A588A598A5A8A5B8A5C8A5D8A5E8A5F8A608A618A62C5AEC5AB8A63C4CC8A64BCE9CBFD8A658A668A67BAC38A688A698A6AE5F9C8E7E5FACDFD8A6BD7B1B8BEC2E88A6CC8D18A6D8A6EE5FB8A6F8A708A718A72B6CABCCB8A738A74D1FDE6A18A75C3EE8A768A778A788A79E6A48A7A8A7B8A7C8A7DE5FEE6A5CDD78A7E8A80B7C1E5FCE5FDE6A38A818A82C4DDE6A88A838A84E6A78A858A868A878A888A898A8AC3C38A8BC6DE8A8C8A8DE6AA8A8E8A8F8A908A918A928A938A94C4B78A958A968A97E6A2CABC8A988A998A9A8A9BBDE3B9C3E6A6D0D5CEAF8A9C8A9DE6A9E6B08A9ED2A68A9FBDAAE6AD8AA08AA18AA28AA38AA4E6AF8AA5C0D18AA68AA7D2CC8AA88AA98AAABCA78AAB8AAC8AAD8AAE8AAF8AB08AB18AB28AB38AB48AB58AB6E6B18AB7D2F68AB88AB98ABAD7CB8ABBCDFE8ABCCDDEC2A6E6ABE6ACBDBFE6AEE6B38ABD8ABEE6B28ABF8AC08AC18AC2E6B68AC3E6B88AC48AC58AC68AC7C4EF8AC88AC98ACAC4C88ACB8ACCBEEAC9EF8ACD8ACEE6B78ACFB6F08AD08AD18AD2C3E48AD38AD48AD58AD68AD78AD88AD9D3E9E6B48ADAE6B58ADBC8A28ADC8ADD8ADE8ADF8AE0E6BD8AE18AE28AE3E6B98AE48AE58AE68AE78AE8C6C58AE98AEACDF1E6BB8AEB8AEC8AED8AEE8AEF8AF08AF18AF28AF38AF4E6BC8AF58AF68AF78AF8BBE98AF98AFA8AFB8AFC8AFD8AFE8B40E6BE8B418B428B438B44E6BA8B458B46C0B78B478B488B498B4A8B4B8B4C8B4D8B4E8B4FD3A4E6BFC9F4E6C38B508B51E6C48B528B538B548B55D0F68B568B578B588B598B5A8B5B8B5C8B5D8B5E8B5F8B608B618B628B638B648B658B668B67C3BD8B688B698B6A8B6B8B6C8B6D8B6EC3C4E6C28B6F8B708B718B728B738B748B758B768B778B788B798B7A8B7B8B7CE6C18B7D8B7E8B808B818B828B838B84E6C7CFB18B85EBF48B868B87E6CA8B888B898B8A8B8B8B8CE6C58B8D8B8EBCDEC9A98B8F8B908B918B928B938B94BCB58B958B96CFD38B978B988B998B9A8B9BE6C88B9CE6C98B9DE6CE8B9EE6D08B9F8BA08BA1E6D18BA28BA38BA4E6CBB5D58BA5E6CC8BA68BA7E6CF8BA88BA9C4DB8BAAE6C68BAB8BAC8BAD8BAE8BAFE6CD8BB08BB18BB28BB38BB48BB58BB68BB78BB88BB98BBA8BBB8BBC8BBD8BBE8BBF8BC08BC18BC28BC38BC48BC58BC6E6D28BC78BC88BC98BCA8BCB8BCC8BCD8BCE8BCF8BD08BD18BD2E6D4E6D38BD38BD48BD58BD68BD78BD88BD98BDA8BDB8BDC8BDD8BDE8BDF8BE08BE18BE28BE38BE48BE58BE68BE78BE88BE98BEA8BEB8BECE6D58BEDD9F88BEE8BEFE6D68BF08BF18BF28BF38BF48BF58BF68BF7E6D78BF88BF98BFA8BFB8BFC8BFD8BFE8C408C418C428C438C448C458C468C47D7D3E6DD8C48E6DEBFD7D4D08C49D7D6B4E6CBEFE6DAD8C3D7CED0A28C4AC3CF8C4B8C4CE6DFBCBEB9C2E6DBD1A78C4D8C4EBAA2C2CF8C4FD8AB8C508C518C52CAEBE5EE8C53E6DC8C54B7F58C558C568C578C58C8E68C598C5AC4F58C5B8C5CE5B2C4FE8C5DCBFCE5B3D5AC8C5ED3EECAD8B0B28C5FCBCECDEA8C608C61BAEA8C628C638C64E5B58C65E5B48C66D7DAB9D9D6E6B6A8CDF0D2CBB1A6CAB58C67B3E8C9F3BFCDD0FBCAD2E5B6BBC28C688C698C6ACFDCB9AC8C6B8C6C8C6D8C6ED4D78C6F8C70BAA6D1E7CFFCBCD28C71E5B7C8DD8C728C738C74BFEDB1F6CBDE8C758C76BCC58C77BCC4D2FAC3DCBFDC8C788C798C7A8C7BB8BB8C7C8C7D8C7EC3C28C80BAAED4A28C818C828C838C848C858C868C878C888C89C7DEC4AFB2EC8C8AB9D18C8B8C8CE5BBC1C88C8D8C8ED5AF8C8F8C908C918C928C93E5BC8C94E5BE8C958C968C978C988C998C9A8C9BB4E7B6D4CBC2D1B0B5BC8C9C8C9DCAD98C9EB7E28C9F8CA0C9E48CA1BDAB8CA28CA3CEBED7F08CA48CA58CA68CA7D0A18CA8C9D98CA98CAAB6FBE6D8BCE28CABB3BE8CACC9D08CADE6D9B3A28CAE8CAF8CB08CB1DECC8CB2D3C8DECD8CB3D2A28CB48CB58CB68CB7DECE8CB88CB98CBA8CBBBECD8CBC8CBDDECF8CBE8CBF8CC0CAACD2FCB3DFE5EAC4E1BEA1CEB2C4F2BED6C6A8B2E38CC18CC2BED38CC38CC4C7FCCCEBBDECCEDD8CC58CC6CABAC6C1E5ECD0BC8CC78CC88CC9D5B98CCA8CCB8CCCE5ED8CCD8CCE8CCF8CD0CAF48CD1CDC0C2C58CD2E5EF8CD3C2C4E5F08CD48CD58CD68CD78CD88CD98CDAE5F8CDCD8CDBC9BD8CDC8CDD8CDE8CDF8CE08CE18CE2D2D9E1A88CE38CE48CE58CE6D3EC8CE7CBEAC6F18CE88CE98CEA8CEB8CECE1AC8CED8CEE8CEFE1A7E1A98CF08CF1E1AAE1AF8CF28CF3B2ED8CF4E1ABB8DAE1ADE1AEE1B0B5BAE1B18CF58CF68CF78CF88CF9E1B3E1B88CFA8CFB8CFC8CFD8CFED1D28D40E1B6E1B5C1EB8D418D428D43E1B78D44D4C08D45E1B28D46E1BAB0B68D478D488D498D4AE1B48D4BBFF98D4CE1B98D4D8D4EE1BB8D4F8D508D518D528D538D54E1BE8D558D568D578D588D598D5AE1BC8D5B8D5C8D5D8D5E8D5F8D60D6C58D618D628D638D648D658D668D67CFBF8D688D69E1BDE1BFC2CD8D6AB6EB8D6BD3F88D6C8D6DC7CD8D6E8D6FB7E58D708D718D728D738D748D758D768D778D788D79BEFE8D7A8D7B8D7C8D7D8D7E8D80E1C0E1C18D818D82E1C7B3E78D838D848D858D868D878D88C6E98D898D8A8D8B8D8C8D8DB4DE8D8ED1C28D8F8D908D918D92E1C88D938D94E1C68D958D968D978D988D99E1C58D9AE1C3E1C28D9BB1C08D9C8D9D8D9ED5B8E1C48D9F8DA08DA18DA28DA3E1CB8DA48DA58DA68DA78DA88DA98DAA8DABE1CCE1CA8DAC8DAD8DAE8DAF8DB08DB18DB28DB3EFFA8DB48DB5E1D3E1D2C7B68DB68DB78DB88DB98DBA8DBB8DBC8DBD8DBE8DBF8DC0E1C98DC18DC2E1CE8DC3E1D08DC48DC58DC68DC78DC88DC98DCA8DCB8DCC8DCD8DCEE1D48DCFE1D1E1CD8DD08DD1E1CF8DD28DD38DD48DD5E1D58DD68DD78DD88DD98DDA8DDB8DDC8DDD8DDE8DDF8DE08DE18DE2E1D68DE38DE48DE58DE68DE78DE88DE98DEA8DEB8DEC8DED8DEE8DEF8DF08DF18DF28DF38DF48DF58DF68DF78DF8E1D78DF98DFA8DFBE1D88DFC8DFD8DFE8E408E418E428E438E448E458E468E478E488E498E4A8E4B8E4C8E4D8E4E8E4F8E508E518E528E538E548E55E1DA8E568E578E588E598E5A8E5B8E5C8E5D8E5E8E5F8E608E618E62E1DB8E638E648E658E668E678E688E69CEA18E6A8E6B8E6C8E6D8E6E8E6F8E708E718E728E738E748E758E76E7DD8E77B4A8D6DD8E788E79D1B2B3B28E7A8E7BB9A4D7F3C7C9BEDEB9AE8E7CCED78E7D8E7EB2EEDBCF8E80BCBAD2D1CBC8B0CD8E818E82CFEF8E838E848E858E868E87D9E3BDED8E888E89B1D2CAD0B2BC8E8ACBA7B7AB8E8BCAA68E8C8E8D8E8ECFA38E8F8E90E0F8D5CAE0FB8E918E92E0FAC5C1CCFB8E93C1B1E0F9D6E3B2AFD6C4B5DB8E948E958E968E978E988E998E9A8E9BB4F8D6A18E9C8E9D8E9E8E9F8EA0CFAFB0EF8EA18EA2E0FC8EA38EA48EA58EA68EA7E1A1B3A38EA88EA9E0FDE0FEC3B18EAA8EAB8EAC8EADC3DD8EAEE1A2B7F98EAF8EB08EB18EB28EB38EB4BBCF8EB58EB68EB78EB88EB98EBA8EBBE1A3C4BB8EBC8EBD8EBE8EBF8EC0E1A48EC18EC2E1A58EC38EC4E1A6B4B18EC58EC68EC78EC88EC98ECA8ECB8ECC8ECD8ECE8ECF8ED08ED18ED28ED3B8C9C6BDC4EA8ED4B2A28ED5D0D28ED6E7DBBBC3D3D7D3C48ED7B9E3E2CF8ED88ED98EDAD7AF8EDBC7ECB1D38EDC8EDDB4B2E2D18EDE8EDF8EE0D0F2C2AEE2D08EE1BFE2D3A6B5D7E2D2B5EA8EE2C3EDB8FD8EE3B8AE8EE4C5D3B7CFE2D48EE58EE68EE78EE8E2D3B6C8D7F98EE98EEA8EEB8EEC8EEDCDA58EEE8EEF8EF08EF18EF2E2D88EF3E2D6CAFCBFB5D3B9E2D58EF48EF58EF68EF7E2D78EF88EF98EFA8EFB8EFC8EFD8EFE8F408F418F42C1AEC0C88F438F448F458F468F478F48E2DBE2DAC0AA8F498F4AC1CE8F4B8F4C8F4D8F4EE2DC8F4F8F508F518F528F538F548F558F568F578F588F598F5AE2DD8F5BE2DE8F5C8F5D8F5E8F5F8F608F618F628F638F64DBC88F65D1D3CDA28F668F67BDA88F688F698F6ADEC3D8A5BFAADBCDD2ECC6FAC5AA8F6B8F6C8F6DDEC48F6EB1D7DFAE8F6F8F708F71CABD8F72DFB18F73B9AD8F74D2FD8F75B8A5BAEB8F768F77B3DA8F788F798F7AB5DCD5C58F7B8F7C8F7D8F7EC3D6CFD2BBA18F80E5F3E5F28F818F82E5F48F83CDE48F84C8F58F858F868F878F888F898F8A8F8BB5AFC7BF8F8CE5F68F8D8F8E8F8FECB08F908F918F928F938F948F958F968F978F988F998F9A8F9B8F9C8F9D8F9EE5E68F9FB9E9B5B18FA0C2BCE5E8E5E7E5E98FA18FA28FA38FA4D2CD8FA58FA68FA7E1EAD0CE8FA8CDAE8FA9D1E58FAA8FABB2CAB1EB8FACB1F2C5ED8FAD8FAED5C3D3B08FAFE1DC8FB08FB18FB2E1DD8FB3D2DB8FB4B3B9B1CB8FB58FB68FB7CDF9D5F7E1DE8FB8BEB6B4FD8FB9E1DFBADCE1E0BBB2C2C9E1E18FBA8FBB8FBCD0EC8FBDCDBD8FBE8FBFE1E28FC0B5C3C5C7E1E38FC18FC2E1E48FC38FC48FC58FC6D3F98FC78FC88FC98FCA8FCB8FCCE1E58FCDD1AD8FCE8FCFE1E6CEA28FD08FD18FD28FD38FD48FD5E1E78FD6B5C28FD78FD88FD98FDAE1E8BBD58FDB8FDC8FDD8FDE8FDFD0C4E2E0B1D8D2E48FE08FE1E2E18FE28FE3BCC9C8CC8FE4E2E3ECFEECFDDFAF8FE58FE68FE7E2E2D6BECDFCC3A68FE88FE98FEAE3C38FEB8FECD6D2E2E78FED8FEEE2E88FEF8FF0D3C78FF18FF2E2ECBFEC8FF3E2EDE2E58FF48FF5B3C08FF68FF78FF8C4EE8FF98FFAE2EE8FFB8FFCD0C38FFDBAF6E2E9B7DEBBB3CCACCBCBE2E4E2E6E2EAE2EB8FFE90409041E2F790429043E2F4D4F5E2F390449045C5AD9046D5FAC5C2B2C090479048E2EF9049E2F2C1AFCBBC904A904BB5A1E2F9904C904D904EBCB1E2F1D0D4D4B9E2F5B9D6E2F6904F90509051C7D390529053905490559056E2F0905790589059905A905BD7DCEDA1905C905DE2F8905EEDA5E2FECAD1905F906090619062906390649065C1B59066BBD090679068BFD69069BAE3906A906BCBA1906C906D906EEDA6EDA3906F9070EDA29071907290739074BBD6EDA7D0F490759076EDA4BADEB6F7E3A1B6B2CCF1B9A79077CFA2C7A190789079BFD2907A907BB6F1907CE2FAE2FBE2FDE2FCC4D5E3A2907DD3C1907E90809081E3A7C7C49082908390849085CFA490869087E3A9BAB790889089908A908BE3A8908CBBDA908DE3A3908E908F9090E3A4E3AA9091E3A69092CEF2D3C690939094BBBC90959096D4C39097C4FA90989099EDA8D0FCE3A5909AC3F5909BE3ADB1AF909CE3B2909D909E909FBCC290A090A1E3ACB5BF90A290A390A490A590A690A790A890A9C7E9E3B090AA90AB90ACBEAACDEF90AD90AE90AF90B090B1BBF390B290B390B4CCE890B590B6E3AF90B7E3B190B8CFA7E3AE90B9CEA9BBDD90BA90BB90BC90BD90BEB5EBBEE5B2D2B3CD90BFB1B9E3ABB2D1B5ACB9DFB6E890C090C1CFEBE3B790C2BBCC90C390C4C8C7D0CA90C590C690C790C890C9E3B8B3EE90CA90CB90CC90CDEDA990CED3FAD3E490CF90D090D1EDAAE3B9D2E290D290D390D490D590D6E3B590D790D890D990DAD3DE90DB90DC90DD90DEB8D0E3B390DF90E0E3B6B7DF90E1E3B4C0A290E290E390E4E3BA90E590E690E790E890E990EA90EB90EC90ED90EE90EF90F090F190F290F390F490F590F690F7D4B890F890F990FA90FB90FC90FD90FE9140B4C89141E3BB9142BBC59143C9F791449145C9E5914691479148C4BD9149914A914B914C914D914E914FEDAB9150915191529153C2FD9154915591569157BBDBBFAE91589159915A915B915C915D915ECEBF915F916091619162E3BC9163BFB6916491659166916791689169916A916B916C916D916E916F9170917191729173917491759176B1EF91779178D4F79179917A917B917C917DE3BE917E9180918191829183918491859186EDAD918791889189918A918B918C918D918E918FE3BFBAA9EDAC91909191E3BD91929193919491959196919791989199919A919BE3C0919C919D919E919F91A091A1BAB691A291A391A4B6AE91A591A691A791A891A9D0B891AAB0C3EDAE91AB91AC91AD91AE91AFEDAFC0C191B0E3C191B191B291B391B491B591B691B791B891B991BA91BB91BC91BD91BE91BF91C091C1C5B391C291C391C491C591C691C791C891C991CA91CB91CC91CD91CE91CFE3C291D091D191D291D391D491D591D691D791D8DCB291D991DA91DB91DC91DD91DEEDB091DFB8EA91E0CEECEAA7D0E7CAF9C8D6CFB7B3C9CED2BDE491E191E2E3DEBBF2EAA8D5BD91E3C6DDEAA991E491E591E6EAAA91E7EAACEAAB91E8EAAEEAAD91E991EA91EB91ECBDD891EDEAAF91EEC2BE91EF91F091F191F2B4C1B4F791F391F4BBA791F591F691F791F891F9ECE6ECE5B7BFCBF9B1E291FAECE791FB91FC91FDC9C8ECE8ECE991FECAD6DED0B2C5D4FA92409241C6CBB0C7B4F2C8D3924292439244CDD092459246BFB8924792489249924A924B924C924DBFDB924E924FC7A4D6B49250C0A9DED1C9A8D1EFC5A4B0E7B3B6C8C592519252B0E292539254B7F692559256C5FA92579258B6F39259D5D2B3D0BCBC925A925B925CB3AD925D925E925F9260BEF1B0D1926192629263926492659266D2D6CAE3D7A59267CDB6B6B6BFB9D5DB9268B8A7C5D79269926A926BDED2BFD9C2D5C7C0926CBBA4B1A8926D926EC5EA926F9270C5FBCCA79271927292739274B1A7927592769277B5D692789279927AC4A8927BDED3D1BAB3E9927CC3F2927D927EB7F79280D6F4B5A3B2F0C4B4C4E9C0ADDED49281B0E8C5C4C1E09282B9D59283BEDCCDD8B0CE9284CDCFDED6BED0D7BEDED5D5D0B0DD92859286C4E292879288C2A3BCF09289D3B5C0B9C5A1B2A6D4F1928A928BC0A8CAC3DED7D5FC928CB9B0928DC8ADCBA9928EDED9BFBD928F929092919292C6B4D7A7CAB0C4C39293B3D6B9D29294929592969297D6B8EAFCB0B492989299929A929BBFE6929C929DCCF4929E929F92A092A1CDDA92A292A392A4D6BFC2CE92A5CECECCA2D0AEC4D3B5B2DED8D5F5BCB7BBD392A692A7B0A492A8C5B2B4EC92A992AA92ABD5F192AC92ADEAFD92AE92AF92B092B192B292B3DEDACDA692B492B5CDEC92B692B792B892B9CEE6DEDC92BACDB1C0A692BB92BCD7BD92BDDEDBB0C6BAB4C9D3C4F3BEE892BE92BF92C092C1B2B692C292C392C492C592C692C792C892C9C0CCCBF092CABCF1BBBBB5B792CB92CC92CDC5F592CEDEE692CF92D092D1DEE3BEDD92D292D3DEDF92D492D592D692D7B4B7BDDD92D892D9DEE0C4ED92DA92DB92DC92DDCFC692DEB5E092DF92E092E192E2B6DECADAB5F4DEE592E3D5C692E4DEE1CCCDC6FE92E5C5C592E692E792E8D2B492E9BEF292EA92EB92EC92ED92EE92EF92F0C2D392F1CCBDB3B892F2BDD392F3BFD8CDC6D1DAB4EB92F4DEE4DEDDDEE792F5EAFE92F692F7C2B0DEE292F892F9D6C0B5A792FAB2F492FBDEE892FCDEF292FD92FE934093419342DEED9343DEF193449345C8E0934693479348D7E1DEEFC3E8CCE19349B2E5934A934B934CD2BE934D934E934F9350935193529353DEEE9354DEEBCED59355B4A79356935793589359935ABFABBEBE935B935CBDD2935D935E935F9360DEE99361D4AE9362DEDE9363DEEA9364936593669367C0BF9368DEECB2F3B8E9C2A79369936ABDC1936B936C936D936E936FDEF5DEF893709371B2ABB4A493729373B4EAC9A6937493759376937793789379DEF6CBD1937AB8E3937BDEF7DEFA937C937D937E9380DEF9938193829383CCC29384B0E1B4EE93859386938793889389938AE5BA938B938C938D938E938FD0AF93909391B2EB9392EBA19393DEF493949395C9E3DEF3B0DAD2A1B1F79396CCAF939793989399939A939B939C939DDEF0939ECBA4939F93A093A1D5AA93A293A393A493A593A6DEFB93A793A893A993AA93AB93AC93AD93AEB4DD93AFC4A693B093B193B2DEFD93B393B493B593B693B793B893B993BA93BB93BCC3FEC4A1DFA193BD93BE93BF93C093C193C293C3C1CC93C4DEFCBEEF93C5C6B293C693C793C893C993CA93CB93CC93CD93CEB3C5C8F693CF93D0CBBADEFE93D193D2DFA493D393D493D593D6D7B293D793D893D993DA93DBB3B793DC93DD93DE93DFC1C393E093E1C7CBB2A5B4E993E2D7AB93E393E493E593E6C4EC93E7DFA2DFA393E8DFA593E9BAB393EA93EB93ECDFA693EDC0DE93EE93EFC9C393F093F193F293F393F493F593F6B2D9C7E693F7DFA793F8C7DC93F993FA93FB93FCDFA8EBA293FD93FE944094419442CBD3944394449445DFAA9446DFA99447B2C194489449944A944B944C944D944E944F9450945194529453945494559456945794589459945A945B945C945D945E945F9460C5CA94619462946394649465946694679468DFAB9469946A946B946C946D946E946F9470D4DC94719472947394749475C8C19476947794789479947A947B947C947D947E948094819482DFAC94839484948594869487BEF094889489DFADD6A7948A948B948C948DEAB7EBB6CAD5948ED8FCB8C4948FB9A594909491B7C5D5FE94929493949494959496B9CA94979498D0A7F4CD9499949AB5D0949B949CC3F4949DBEC8949E949F94A0EBB7B0BD94A194A2BDCC94A3C1B294A4B1D6B3A894A594A694A7B8D2C9A294A894A9B6D894AA94AB94AC94ADEBB8BEB494AE94AF94B0CAFD94B1C7C394B2D5FB94B394B4B7F394B594B694B794B894B994BA94BB94BC94BD94BE94BF94C094C194C294C3CEC494C494C594C6D5ABB1F394C794C894C9ECB3B0DF94CAECB594CB94CC94CDB6B794CEC1CF94CFF5FAD0B194D094D1D5E594D2CED394D394D4BDEFB3E294D5B8AB94D6D5B694D7EDBD94D8B6CF94D9CBB9D0C294DA94DB94DC94DD94DE94DF94E094E1B7BD94E294E3ECB6CAA994E494E594E6C5D494E7ECB9ECB8C2C3ECB794E894E994EA94EBD0FDECBA94ECECBBD7E594ED94EEECBC94EF94F094F1ECBDC6EC94F294F394F494F594F694F794F894F9CEDE94FABCC894FB94FCC8D5B5A9BEC9D6BCD4E794FD94FED1AED0F1EAB8EAB9EABABAB59540954195429543CAB1BFF595449545CDFA9546954795489549954AEAC0954BB0BAEABE954C954DC0A5954E954F9550EABB9551B2FD9552C3F7BBE8955395549555D2D7CEF4EABF955695579558EABC9559955A955BEAC3955CD0C7D3B3955D955E955F9560B4BA9561C3C1D7F29562956395649565D5D19566CAC79567EAC595689569EAC4EAC7EAC6956A956B956C956D956ED6E7956FCFD495709571EACB9572BBCE9573957495759576957795789579BDFAC9CE957A957BEACC957C957DC9B9CFFEEACAD4CEEACDEACF957E9580CDED9581958295839584EAC99585EACE95869587CEEE9588BBDE9589B3BF958A958B958C958D958EC6D5BEB0CEFA958F95909591C7E79592BEA7EAD095939594D6C7959595969597C1C095989599959AD4DD959BEAD1959C959DCFBE959E959F95A095A1EAD295A295A395A495A5CAEE95A695A795A895A9C5AFB0B595AA95AB95AC95AD95AEEAD495AF95B095B195B295B395B495B595B695B7EAD3F4DF95B895B995BA95BB95BCC4BA95BD95BE95BF95C095C1B1A995C295C395C495C5E5DF95C695C795C895C9EAD595CA95CB95CC95CD95CE95CF95D095D195D295D395D495D595D695D795D895D995DA95DB95DC95DD95DE95DF95E095E195E295E3CAEF95E4EAD6EAD7C6D895E595E695E795E895E995EA95EB95ECEAD895ED95EEEAD995EF95F095F195F295F395F4D4BB95F5C7FAD2B7B8FC95F695F7EAC295F8B2DC95F995FAC2FC95FBD4F8CCE6D7EE95FC95FD95FE9640964196429643D4C2D3D0EBC3C5F39644B7FE96459646EBD4964796489649CBB7EBDE964AC0CA964B964C964DCDFB964EB3AF964FC6DA965096519652965396549655EBFC9656C4BE9657CEB4C4A9B1BED4FD9658CAF59659D6EC965A965BC6D3B6E4965C965D965E965FBBFA96609661D0E096629663C9B19664D4D3C8A896659666B8CB9667E8BEC9BC96689669E8BB966AC0EED0D3B2C4B4E5966BE8BC966C966DD5C8966E966F967096719672B6C59673E8BDCAF8B8DCCCF5967496759676C0B496779678D1EEE8BFE8C29679967ABABC967BB1ADBDDC967CEABDE8C3967DE8C6967EE8CB9680968196829683E8CC9684CBC9B0E59685BCAB96869687B9B996889689E8C1968ACDF7968BE8CA968C968D968E968FCEF69690969196929693D5ED9694C1D6E8C49695C3B69696B9FBD6A6E8C8969796989699CAE0D4E6969AE8C0969BE8C5E8C7969CC7B9B7E3969DE8C9969EBFDDE8D2969F96A0E8D796A1E8D5BCDCBCCFE8DB96A296A396A496A596A696A796A896A9E8DE96AAE8DAB1FA96AB96AC96AD96AE96AF96B096B196B296B396B4B0D8C4B3B8CCC6E2C8BEC8E196B596B696B7E8CFE8D4E8D696B8B9F1E8D8D7F596B9C4FB96BAE8DC96BB96BCB2E996BD96BE96BFE8D196C096C1BCED96C296C3BFC2E8CDD6F996C4C1F8B2F196C596C696C796C896C996CA96CB96CCE8DF96CDCAC1E8D996CE96CF96D096D1D5A496D2B1EAD5BBE8CEE8D0B6B0E8D396D3E8DDC0B896D4CAF796D5CBA896D696D7C6DCC0F596D896D996DA96DB96DCE8E996DD96DE96DFD0A396E096E196E296E396E496E596E6E8F2D6EA96E796E896E996EA96EB96EC96EDE8E0E8E196EE96EF96F0D1F9BACBB8F996F196F2B8F1D4D4E8EF96F3E8EEE8ECB9F0CCD2E8E6CEA6BFF296F4B0B8E8F1E8F096F5D7C096F6E8E496F7CDA9C9A396F8BBB8BDDBE8EA96F996FA96FB96FC96FD96FE9740974197429743E8E2E8E3E8E5B5B5E8E7C7C5E8EBE8EDBDB0D7AE9744E8F897459746974797489749974A974B974CE8F5974DCDB0E8F6974E974F9750975197529753975497559756C1BA9757E8E89758C3B7B0F09759975A975B975C975D975E975F9760E8F4976197629763E8F7976497659766B9A3976797689769976A976B976C976D976E976F9770C9D2977197729773C3CECEE0C0E69774977597769777CBF39778CCDDD0B59779977ACAE1977BE8F3977C977D977E9780978197829783978497859786BCEC9787E8F997889789978A978B978C978DC3DE978EC6E5978FB9F79790979197929793B0F497949795D7D897969797BCAC9798C5EF9799979A979B979C979DCCC4979E979FE9A697A097A197A297A397A497A597A697A797A897A9C9AD97AAE9A2C0E297AB97AC97ADBFC397AE97AF97B0E8FEB9D797B1E8FB97B297B397B497B5E9A497B697B797B8D2CE97B997BA97BB97BC97BDE9A397BED6B2D7B597BFE9A797C0BDB797C197C297C397C497C597C697C797C897C997CA97CB97CCE8FCE8FD97CD97CE97CFE9A197D097D197D297D397D497D597D697D7CDD697D897D9D2AC97DA97DB97DCE9B297DD97DE97DF97E0E9A997E197E297E3B4AA97E4B4BB97E597E6E9AB97E797E897E997EA97EB97EC97ED97EE97EF97F097F197F297F397F497F597F697F7D0A897F897F9E9A597FA97FBB3FE97FC97FDE9ACC0E397FEE9AA98409841E9B998429843E9B89844984598469847E9AE98489849E8FA984A984BE9A8984C984D984E984F9850BFACE9B1E9BA98519852C2A5985398549855E9AF9856B8C59857E9AD9858D3DCE9B4E9B5E9B79859985A985BE9C7985C985D985E985F98609861C0C6E9C598629863E9B098649865E9BBB0F19866986798689869986A986B986C986D986E986FE9BCD5A598709871E9BE9872E9BF987398749875E9C198769877C1F198789879C8B6987A987B987CE9BD987D987E988098819882E9C29883988498859886988798889889988AE9C3988BE9B3988CE9B6988DBBB1988E988F9890E9C0989198929893989498959896BCF7989798989899E9C4E9C6989A989B989C989D989E989F98A098A198A298A398A498A5E9CA98A698A798A898A9E9CE98AA98AB98AC98AD98AE98AF98B098B198B298B3B2DB98B4E9C898B598B698B798B898B998BA98BB98BC98BD98BEB7AE98BF98C098C198C298C398C498C598C698C798C898C998CAE9CBE9CC98CB98CC98CD98CE98CF98D0D5C198D1C4A398D298D398D498D598D698D7E9D898D8BAE198D998DA98DB98DCE9C998DDD3A398DE98DF98E0E9D498E198E298E398E498E598E698E7E9D7E9D098E898E998EA98EB98ECE9CF98ED98EEC7C198EF98F098F198F298F398F498F598F6E9D298F798F898F998FA98FB98FC98FDE9D9B3C898FEE9D399409941994299439944CFF0994599469947E9CD99489949994A994B994C994D994E994F995099519952B3F79953995499559956995799589959E9D6995A995BE9DA995C995D995ECCB4995F99609961CFAD99629963996499659966996799689969996AE9D5996BE9DCE9DB996C996D996E996F9970E9DE99719972997399749975997699779978E9D19979997A997B997C997D997E99809981E9DD9982E9DFC3CA9983998499859986998799889989998A998B998C998D998E998F9990999199929993999499959996999799989999999A999B999C999D999E999F99A099A199A299A399A499A599A699A799A899A999AA99AB99AC99AD99AE99AF99B099B199B299B399B499B599B699B799B899B999BA99BB99BC99BD99BE99BF99C099C199C299C399C499C599C699C799C899C999CA99CB99CC99CD99CE99CF99D099D199D299D399D499D599D699D799D899D999DA99DB99DC99DD99DE99DF99E099E199E299E399E499E599E699E799E899E999EA99EB99EC99ED99EE99EF99F099F199F299F399F499F5C7B7B4CEBBB6D0C0ECA399F699F7C5B799F899F999FA99FB99FC99FD99FE9A409A419A42D3FB9A439A449A459A46ECA49A47ECA5C6DB9A489A499A4ABFEE9A4B9A4C9A4D9A4EECA69A4F9A50ECA7D0AA9A51C7B89A529A53B8E89A549A559A569A579A589A599A5A9A5B9A5C9A5D9A5E9A5FECA89A609A619A629A639A649A659A669A67D6B9D5FDB4CBB2BDCEE4C6E79A689A69CDE19A6A9A6B9A6C9A6D9A6E9A6F9A709A719A729A739A749A759A769A77B4F59A78CBC0BCDF9A799A7A9A7B9A7CE9E2E9E3D1EAE9E59A7DB4F9E9E49A7ED1B3CAE2B2D09A80E9E89A819A829A839A84E9E6E9E79A859A86D6B39A879A889A89E9E9E9EA9A8A9A8B9A8C9A8D9A8EE9EB9A8F9A909A919A929A939A949A959A96E9EC9A979A989A999A9A9A9B9A9C9A9D9A9EECAFC5B9B6CE9A9FD2F39AA09AA19AA29AA39AA49AA59AA6B5EE9AA7BBD9ECB19AA89AA9D2E39AAA9AAB9AAC9AAD9AAECEE39AAFC4B89AB0C3BF9AB19AB2B6BED8B9B1C8B1CFB1D1C5FE9AB3B1D09AB4C3AB9AB59AB69AB79AB89AB9D5B19ABA9ABB9ABC9ABD9ABE9ABF9AC09AC1EBA4BAC19AC29AC39AC4CCBA9AC59AC69AC7EBA59AC8EBA79AC99ACA9ACBEBA89ACC9ACD9ACEEBA69ACF9AD09AD19AD29AD39AD49AD5EBA9EBABEBAA9AD69AD79AD89AD99ADAEBAC9ADBCACFD8B5C3F19ADCC3A5C6F8EBADC4CA9ADDEBAEEBAFEBB0B7D59ADE9ADF9AE0B7FA9AE1EBB1C7E29AE2EBB39AE3BAA4D1F5B0B1EBB2EBB49AE49AE59AE6B5AAC2C8C7E89AE7EBB59AE8CBAEE3DF9AE99AEAD3C09AEB9AEC9AED9AEED9DB9AEF9AF0CDA1D6ADC7F39AF19AF29AF3D9E0BBE39AF4BABAE3E29AF59AF69AF79AF89AF9CFAB9AFA9AFB9AFCE3E0C9C79AFDBAB99AFE9B409B41D1B4E3E1C8EAB9AFBDADB3D8CEDB9B429B43CCC09B449B459B46E3E8E3E9CDF49B479B489B499B4A9B4BCCAD9B4CBCB39B4DE3EA9B4EE3EB9B4F9B50D0DA9B519B529B53C6FBB7DA9B549B55C7DFD2CACED69B56E3E4E3EC9B57C9F2B3C19B589B59E3E79B5A9B5BC6E3E3E59B5C9B5DEDB3E3E69B5E9B5F9B609B61C9B39B62C5E69B639B649B65B9B59B66C3BB9B67E3E3C5BDC1A4C2D9B2D79B68E3EDBBA6C4AD9B69E3F0BEDA9B6A9B6BE3FBE3F5BAD39B6C9B6D9B6E9B6FB7D0D3CD9B70D6CED5D3B9C1D5B4D1D89B719B729B739B74D0B9C7F69B759B769B77C8AAB2B49B78C3DA9B799B7A9B7BE3EE9B7C9B7DE3FCE3EFB7A8E3F7E3F49B7E9B809B81B7BA9B829B83C5A29B84E3F6C5DDB2A8C6FC9B85C4E09B869B87D7A29B88C0E1E3F99B899B8AE3FAE3FDCCA9E3F39B8BD3BE9B8CB1C3EDB4E3F1E3F29B8DE3F8D0BAC6C3D4F3E3FE9B8E9B8FBDE09B909B91E4A79B929B93E4A69B949B959B96D1F3E4A39B97E4A99B989B999B9AC8F79B9B9B9C9B9D9B9ECFB49B9FE4A8E4AEC2E59BA09BA1B6B49BA29BA39BA49BA59BA69BA7BDF29BA8E4A29BA99BAABAE9E4AA9BAB9BACE4AC9BAD9BAEB6FDD6DEE4B29BAFE4AD9BB09BB19BB2E4A19BB3BBEECDDDC7A2C5C99BB49BB5C1F79BB6E4A49BB7C7B3BDACBDBDE4A59BB8D7C7B2E29BB9E4ABBCC3E4AF9BBABBEBE4B0C5A8E4B19BBB9BBC9BBD9BBED5E3BFA39BBFE4BA9BC0E4B79BC1E4BB9BC29BC3E4BD9BC49BC5C6D69BC69BC7BAC6C0CB9BC89BC99BCAB8A1E4B49BCB9BCC9BCD9BCED4A19BCF9BD0BAA3BDFE9BD19BD29BD3E4BC9BD49BD59BD69BD79BD8CDBF9BD99BDAC4F99BDB9BDCCFFBC9E69BDD9BDED3BF9BDFCFD19BE09BE1E4B39BE2E4B8E4B9CCE99BE39BE49BE59BE69BE7CCCE9BE8C0D4E4B5C1B0E4B6CED09BE9BBC1B5D39BEAC8F3BDA7D5C7C9ACB8A2E4CA9BEB9BECE4CCD1C49BED9BEED2BA9BEF9BF0BAAD9BF19BF2BAD49BF39BF49BF59BF69BF79BF8E4C3B5ED9BF99BFA9BFBD7CDE4C0CFFDE4BF9BFC9BFD9BFEC1DCCCCA9C409C419C429C43CAE79C449C459C469C47C4D79C48CCD4E4C89C499C4A9C4BE4C7E4C19C4CE4C4B5AD9C4D9C4ED3D99C4FE4C69C509C519C529C53D2F9B4E39C54BBB49C559C56C9EE9C57B4BE9C589C599C5ABBEC9C5BD1CD9C5CCCEDEDB59C5D9C5E9C5F9C609C619C629C639C64C7E59C659C669C679C68D4A89C69E4CBD7D5E4C29C6ABDA5E4C59C6B9C6CD3E69C6DE4C9C9F89C6E9C6FE4BE9C709C71D3E59C729C73C7FEB6C99C74D4FCB2B3E4D79C759C769C77CEC29C78E4CD9C79CEBC9C7AB8DB9C7B9C7CE4D69C7DBFCA9C7E9C809C81D3CE9C82C3EC9C839C849C859C869C879C889C899C8AC5C8E4D89C8B9C8C9C8D9C8E9C8F9C909C919C92CDC4E4CF9C939C949C959C96E4D4E4D59C97BAFE9C98CFE69C999C9AD5BF9C9B9C9C9C9DE4D29C9E9C9F9CA09CA19CA29CA39CA49CA59CA69CA79CA8E4D09CA99CAAE4CE9CAB9CAC9CAD9CAE9CAF9CB09CB19CB29CB39CB49CB59CB69CB79CB89CB9CDE5CAAA9CBA9CBB9CBCC0A39CBDBDA6E4D39CBE9CBFB8C89CC09CC19CC29CC39CC4E4E7D4B49CC59CC69CC79CC89CC99CCA9CCBE4DB9CCC9CCD9CCEC1EF9CCF9CD0E4E99CD19CD2D2E79CD39CD4E4DF9CD5E4E09CD69CD7CFAA9CD89CD99CDA9CDBCBDD9CDCE4DAE4D19CDDE4E59CDEC8DCE4E39CDF9CE0C4E7E4E29CE1E4E19CE29CE39CE4B3FCE4E89CE59CE69CE79CE8B5E19CE99CEA9CEBD7CC9CEC9CED9CEEE4E69CEFBBAC9CF0D7D2CCCFEBF89CF1E4E49CF29CF3B9F69CF49CF59CF6D6CDE4D9E4DCC2FAE4DE9CF7C2CBC0C4C2D09CF8B1F5CCB29CF99CFA9CFB9CFC9CFD9CFE9D409D419D429D43B5CE9D449D459D469D47E4EF9D489D499D4A9D4B9D4C9D4D9D4E9D4FC6AF9D509D519D52C6E19D539D54E4F59D559D569D579D589D59C2A99D5A9D5B9D5CC0ECD1DDE4EE9D5D9D5E9D5F9D609D619D629D639D649D659D66C4AE9D679D689D69E4ED9D6A9D6B9D6C9D6DE4F6E4F4C2FE9D6EE4DD9D6FE4F09D70CAFE9D71D5C49D729D73E4F19D749D759D769D779D789D799D7AD1FA9D7B9D7C9D7D9D7E9D809D819D82E4EBE4EC9D839D849D85E4F29D86CEAB9D879D889D899D8A9D8B9D8C9D8D9D8E9D8F9D90C5CB9D919D929D93C7B19D94C2BA9D959D969D97E4EA9D989D999D9AC1CA9D9B9D9C9D9D9D9E9D9F9DA0CCB6B3B19DA19DA29DA3E4FB9DA4E4F39DA59DA69DA7E4FA9DA8E4FD9DA9E4FC9DAA9DAB9DAC9DAD9DAE9DAF9DB0B3CE9DB19DB29DB3B3BAE4F79DB49DB5E4F9E4F8C5EC9DB69DB79DB89DB99DBA9DBB9DBC9DBD9DBE9DBF9DC09DC19DC2C0BD9DC39DC49DC59DC6D4E89DC79DC89DC99DCA9DCBE5A29DCC9DCD9DCE9DCF9DD09DD19DD29DD39DD49DD59DD6B0C49DD79DD8E5A49DD99DDAE5A39DDB9DDC9DDD9DDE9DDF9DE0BCA49DE1E5A59DE29DE39DE49DE59DE69DE7E5A19DE89DE99DEA9DEB9DEC9DED9DEEE4FEB1F49DEF9DF09DF19DF29DF39DF49DF59DF69DF79DF89DF9E5A89DFAE5A9E5A69DFB9DFC9DFD9DFE9E409E419E429E439E449E459E469E47E5A7E5AA9E489E499E4A9E4B9E4C9E4D9E4E9E4F9E509E519E529E539E549E559E569E579E589E599E5A9E5B9E5C9E5D9E5E9E5F9E609E619E629E639E649E659E669E679E68C6D99E699E6A9E6B9E6C9E6D9E6E9E6F9E70E5ABE5AD9E719E729E739E749E759E769E77E5AC9E789E799E7A9E7B9E7C9E7D9E7E9E809E819E829E839E849E859E869E879E889E89E5AF9E8A9E8B9E8CE5AE9E8D9E8E9E8F9E909E919E929E939E949E959E969E979E989E999E9A9E9B9E9C9E9D9E9EB9E09E9F9EA0E5B09EA19EA29EA39EA49EA59EA69EA79EA89EA99EAA9EAB9EAC9EAD9EAEE5B19EAF9EB09EB19EB29EB39EB49EB59EB69EB79EB89EB99EBABBF0ECE1C3F09EBBB5C6BBD29EBC9EBD9EBE9EBFC1E9D4EE9EC0BEC49EC19EC29EC3D7C69EC4D4D6B2D3ECBE9EC59EC69EC79EC8EAC19EC99ECA9ECBC2AFB4B69ECC9ECD9ECED1D79ECF9ED09ED1B3B49ED2C8B2BFBBECC09ED39ED4D6CB9ED59ED6ECBFECC19ED79ED89ED99EDA9EDB9EDC9EDD9EDE9EDF9EE09EE19EE29EE3ECC5BEE6CCBFC5DABEBC9EE4ECC69EE5B1FE9EE69EE79EE8ECC4D5A8B5E39EE9ECC2C1B6B3E39EEA9EEBECC3CBB8C0C3CCFE9EEC9EED9EEE9EEFC1D29EF0ECC89EF19EF29EF39EF49EF59EF69EF79EF89EF99EFA9EFB9EFC9EFDBAE6C0D39EFED6F29F409F419F42D1CC9F439F449F459F46BFBE9F47B7B3C9D5ECC7BBE29F48CCCCBDFDC8C89F49CFA99F4A9F4B9F4C9F4D9F4E9F4F9F50CDE99F51C5EB9F529F539F54B7E99F559F569F579F589F599F5A9F5B9F5C9F5D9F5E9F5FD1C9BAB89F609F619F629F639F64ECC99F659F66ECCA9F67BBC0ECCB9F68ECE2B1BAB7D99F699F6A9F6B9F6C9F6D9F6E9F6F9F709F719F729F73BDB99F749F759F769F779F789F799F7A9F7BECCCD1E6ECCD9F7C9F7D9F7E9F80C8BB9F819F829F839F849F859F869F879F889F899F8A9F8B9F8C9F8D9F8EECD19F8F9F909F919F92ECD39F93BBCD9F94BCE59F959F969F979F989F999F9A9F9B9F9C9F9D9F9E9F9F9FA09FA1ECCF9FA2C9B79FA39FA49FA59FA69FA7C3BA9FA8ECE3D5D5ECD09FA99FAA9FAB9FAC9FADD6F39FAE9FAF9FB0ECD2ECCE9FB19FB29FB39FB4ECD49FB5ECD59FB69FB7C9BF9FB89FB99FBA9FBB9FBC9FBDCFA89FBE9FBF9FC09FC19FC2D0DC9FC39FC49FC59FC6D1AC9FC79FC89FC99FCAC8DB9FCB9FCC9FCDECD6CEF59FCE9FCF9FD09FD19FD2CAECECDA9FD39FD49FD59FD69FD79FD89FD9ECD99FDA9FDB9FDCB0BE9FDD9FDE9FDF9FE09FE19FE2ECD79FE3ECD89FE49FE59FE6ECE49FE79FE89FE99FEA9FEB9FEC9FED9FEE9FEFC8BC9FF09FF19FF29FF39FF49FF59FF69FF79FF89FF9C1C79FFA9FFB9FFC9FFD9FFEECDCD1E0A040A041A042A043A044A045A046A047A048A049ECDBA04AA04BA04CA04DD4EFA04EECDDA04FA050A051A052A053A054DBC6A055A056A057A058A059A05AA05BA05CA05DA05EECDEA05FA060A061A062A063A064A065A066A067A068A069A06AB1ACA06BA06CA06DA06EA06FA070A071A072A073A074A075A076A077A078A079A07AA07BA07CA07DA07EA080A081ECDFA082A083A084A085A086A087A088A089A08AA08BECE0A08CD7A6A08DC5C0A08EA08FA090EBBCB0AEA091A092A093BEF4B8B8D2AFB0D6B5F9A094D8B3A095CBACA096E3DDA097A098A099A09AA09BA09CA09DC6ACB0E6A09EA09FA0A0C5C6EBB9A0A1A0A2A0A3A0A4EBBAA0A5A0A6A0A7EBBBA0A8A0A9D1C0A0AAC5A3A0ABEAF2A0ACC4B2A0ADC4B5C0CEA0AEA0AFA0B0EAF3C4C1A0B1CEEFA0B2A0B3A0B4A0B5EAF0EAF4A0B6A0B7C9FCA0B8A0B9C7A3A0BAA0BBA0BCCCD8CEFEA0BDA0BEA0BFEAF5EAF6CFACC0E7A0C0A0C1EAF7A0C2A0C3A0C4A0C5A0C6B6BFEAF8A0C7EAF9A0C8EAFAA0C9A0CAEAFBA0CBA0CCA0CDA0CEA0CFA0D0A0D1A0D2A0D3A0D4A0D5A0D6EAF1A0D7A0D8A0D9A0DAA0DBA0DCA0DDA0DEA0DFA0E0A0E1A0E2C8AEE1EBA0E3B7B8E1ECA0E4A0E5A0E6E1EDA0E7D7B4E1EEE1EFD3CCA0E8A0E9A0EAA0EBA0ECA0EDA0EEE1F1BFF1E1F0B5D2A0EFA0F0A0F1B1B7A0F2A0F3A0F4A0F5E1F3E1F2A0F6BAFCA0F7E1F4A0F8A0F9A0FAA0FBB9B7A0FCBED1A0FDA0FEAA40AA41C4FCAA42BADDBDC6AA43AA44AA45AA46AA47AA48E1F5E1F7AA49AA4AB6C0CFC1CAA8E1F6D5F8D3FCE1F8E1FCE1F9AA4BAA4CE1FAC0EAAA4DE1FEE2A1C0C7AA4EAA4FAA50AA51E1FBAA52E1FDAA53AA54AA55AA56AA57AA58E2A5AA59AA5AAA5BC1D4AA5CAA5DAA5EAA5FE2A3AA60E2A8B2FEE2A2AA61AA62AA63C3CDB2C2E2A7E2A6AA64AA65E2A4E2A9AA66AA67E2ABAA68AA69AA6AD0C9D6EDC3A8E2ACAA6BCFD7AA6CAA6DE2AEAA6EAA6FBAEFAA70AA71E9E0E2ADE2AAAA72AA73AA74AA75BBABD4B3AA76AA77AA78AA79AA7AAA7BAA7CAA7DAA7EAA80AA81AA82AA83E2B0AA84AA85E2AFAA86E9E1AA87AA88AA89AA8AE2B1AA8BAA8CAA8DAA8EAA8FAA90AA91AA92E2B2AA93AA94AA95AA96AA97AA98AA99AA9AAA9BAA9CAA9DE2B3CCA1AA9EE2B4AA9FAAA0AB40AB41AB42AB43AB44AB45AB46AB47AB48AB49AB4AAB4BE2B5AB4CAB4DAB4EAB4FAB50D0FEAB51AB52C2CAAB53D3F1AB54CDF5AB55AB56E7E0AB57AB58E7E1AB59AB5AAB5BAB5CBEC1AB5DAB5EAB5FAB60C2EAAB61AB62AB63E7E4AB64AB65E7E3AB66AB67AB68AB69AB6AAB6BCDE6AB6CC3B5AB6DAB6EE7E2BBB7CFD6AB6FC1E1E7E9AB70AB71AB72E7E8AB73AB74E7F4B2A3AB75AB76AB77AB78E7EAAB79E7E6AB7AAB7BAB7CAB7DAB7EE7ECE7EBC9BAAB80AB81D5E4AB82E7E5B7A9E7E7AB83AB84AB85AB86AB87AB88AB89E7EEAB8AAB8BAB8CAB8DE7F3AB8ED6E9AB8FAB90AB91AB92E7EDAB93E7F2AB94E7F1AB95AB96AB97B0E0AB98AB99AB9AAB9BE7F5AB9CAB9DAB9EAB9FABA0AC40AC41AC42AC43AC44AC45AC46AC47AC48AC49AC4AC7F2AC4BC0C5C0EDAC4CAC4DC1F0E7F0AC4EAC4FAC50AC51E7F6CBF6AC52AC53AC54AC55AC56AC57AC58AC59AC5AE8A2E8A1AC5BAC5CAC5DAC5EAC5FAC60D7C1AC61AC62E7FAE7F9AC63E7FBAC64E7F7AC65E7FEAC66E7FDAC67E7FCAC68AC69C1D5C7D9C5FDC5C3AC6AAC6BAC6CAC6DAC6EC7EDAC6FAC70AC71AC72E8A3AC73AC74AC75AC76AC77AC78AC79AC7AAC7BAC7CAC7DAC7EAC80AC81AC82AC83AC84AC85AC86E8A6AC87E8A5AC88E8A7BAF7E7F8E8A4AC89C8F0C9AAAC8AAC8BAC8CAC8DAC8EAC8FAC90AC91AC92AC93AC94AC95AC96E8A9AC97AC98B9E5AC99AC9AAC9BAC9CAC9DD1FEE8A8AC9EAC9FACA0AD40AD41AD42E8AAAD43E8ADE8AEAD44C1A7AD45AD46AD47E8AFAD48AD49AD4AE8B0AD4BAD4CE8ACAD4DE8B4AD4EAD4FAD50AD51AD52AD53AD54AD55AD56AD57AD58E8ABAD59E8B1AD5AAD5BAD5CAD5DAD5EAD5FAD60AD61E8B5E8B2E8B3AD62AD63AD64AD65AD66AD67AD68AD69AD6AAD6BAD6CAD6DAD6EAD6FAD70AD71E8B7AD72AD73AD74AD75AD76AD77AD78AD79AD7AAD7BAD7CAD7DAD7EAD80AD81AD82AD83AD84AD85AD86AD87AD88AD89E8B6AD8AAD8BAD8CAD8DAD8EAD8FAD90AD91AD92B9CFAD93F0ACAD94F0ADAD95C6B0B0EAC8BFAD96CDDFAD97AD98AD99AD9AAD9BAD9CAD9DCECDEAB1AD9EAD9FADA0AE40EAB2AE41C6BFB4C9AE42AE43AE44AE45AE46AE47AE48EAB3AE49AE4AAE4BAE4CD5E7AE4DAE4EAE4FAE50AE51AE52AE53AE54DDF9AE55EAB4AE56EAB5AE57EAB6AE58AE59AE5AAE5BB8CADFB0C9F5AE5CCCF0AE5DAE5EC9FAAE5FAE60AE61AE62AE63C9FBAE64AE65D3C3CBA6AE66B8A6F0AEB1C2AE67E5B8CCEFD3C9BCD7C9EAAE68B5E7AE69C4D0B5E9AE6AEEAEBBADAE6BAE6CE7DEAE6DEEAFAE6EAE6FAE70AE71B3A9AE72AE73EEB2AE74AE75EEB1BDE7AE76EEB0CEB7AE77AE78AE79AE7AC5CFAE7BAE7CAE7DAE7EC1F4DBCEEEB3D0F3AE80AE81AE82AE83AE84AE85AE86AE87C2D4C6E8AE88AE89AE8AB7ACAE8BAE8CAE8DAE8EAE8FAE90AE91EEB4AE92B3EBAE93AE94AE95BBFBEEB5AE96AE97AE98AE99AE9AE7DCAE9BAE9CAE9DEEB6AE9EAE9FBDAEAEA0AF40AF41AF42F1E2AF43AF44AF45CAE8AF46D2C9F0DAAF47F0DBAF48F0DCC1C6AF49B8EDBECEAF4AAF4BF0DEAF4CC5B1F0DDD1F1AF4DF0E0B0CCBDEAAF4EAF4FAF50AF51AF52D2DFF0DFAF53B4AFB7E8F0E6F0E5C6A3F0E1F0E2B4C3AF54AF55F0E3D5EEAF56AF57CCDBBED2BCB2AF58AF59AF5AF0E8F0E7F0E4B2A1AF5BD6A2D3B8BEB7C8ACAF5CAF5DF0EAAF5EAF5FAF60AF61D1F7AF62D6CCBADBF0E9AF63B6BBAF64AF65CDB4AF66AF67C6A6AF68AF69AF6AC1A1F0EBF0EEAF6BF0EDF0F0F0ECAF6CBBBEF0EFAF6DAF6EAF6FAF70CCB5F0F2AF71AF72B3D5AF73AF74AF75AF76B1D4AF77AF78F0F3AF79AF7AF0F4F0F6B4E1AF7BF0F1AF7CF0F7AF7DAF7EAF80AF81F0FAAF82F0F8AF83AF84AF85F0F5AF86AF87AF88AF89F0FDAF8AF0F9F0FCF0FEAF8BF1A1AF8CAF8DAF8ECEC1F1A4AF8FF1A3AF90C1F6F0FBCADDAF91AF92B4F1B1F1CCB1AF93F1A6AF94AF95F1A7AF96AF97F1ACD5CEF1A9AF98AF99C8B3AF9AAF9BAF9CF1A2AF9DF1ABF1A8F1A5AF9EAF9FF1AAAFA0B040B041B042B043B044B045B046B0A9F1ADB047B048B049B04AB04BB04CF1AFB04DF1B1B04EB04FB050B051B052F1B0B053F1AEB054B055B056B057D1A2B058B059B05AB05BB05CB05DB05EF1B2B05FB060B061F1B3B062B063B064B065B066B067B068B069B9EFB06AB06BB5C7B06CB0D7B0D9B06DB06EB06FD4EDB070B5C4B071BDD4BBCAF0A7B072B073B8DEB074B075F0A8B076B077B0A8B078F0A9B079B07ACDEEB07BB07CF0AAB07DB07EB080B081B082B083B084B085B086B087F0ABB088B089B08AB08BB08CB08DB08EB08FB090C6A4B091B092D6E5F1E4B093F1E5B094B095B096B097B098B099B09AB09BB09CB09DC3F3B09EB09FD3DBB0A0B140D6D1C5E8B141D3AFB142D2E6B143B144EEC1B0BBD5B5D1CEBCE0BAD0B145BFF8B146B8C7B5C1C5CCB147B148CAA2B149B14AB14BC3CBB14CB14DB14EB14FB150EEC2B151B152B153B154B155B156B157B158C4BFB6A2B159EDECC3A4B15AD6B1B15BB15CB15DCFE0EDEFB15EB15FC5CEB160B6DCB161B162CAA1B163B164EDEDB165B166EDF0EDF1C3BCB167BFB4B168EDEEB169B16AB16BB16CB16DB16EB16FB170B171B172B173EDF4EDF2B174B175B176B177D5E6C3DFB178EDF3B179B17AB17BEDF6B17CD5A3D1A3B17DB17EB180EDF5B181C3D0B182B183B184B185B186EDF7BFF4BEECEDF8B187CCF7B188D1DBB189B18AB18BD7C5D5F6B18CEDFCB18DB18EB18FEDFBB190B191B192B193B194B195B196B197EDF9EDFAB198B199B19AB19BB19CB19DB19EB19FEDFDBEA6B1A0B240B241B242B243CBAFEEA1B6BDB244EEA2C4C0B245EDFEB246B247BDDEB2C7B248B249B24AB24BB24CB24DB24EB24FB250B251B252B253B6C3B254B255B256EEA5D8BAEEA3EEA6B257B258B259C3E9B3F2B25AB25BB25CB25DB25EB25FEEA7EEA4CFB9B260B261EEA8C2F7B262B263B264B265B266B267B268B269B26AB26BB26CB26DEEA9EEAAB26EDEABB26FB270C6B3B271C7C6B272D6F5B5C9B273CBB2B274B275B276EEABB277B278CDABB279EEACB27AB27BB27CB27DB27ED5B0B280EEADB281F6C4B282B283B284B285B286B287B288B289B28AB28BB28CB28DB28EDBC7B28FB290B291B292B293B294B295B296B297B4A3B298B299B29AC3ACF1E6B29BB29CB29DB29EB29FCAB8D2D3B2A0D6AAB340EFF2B341BED8B342BDC3EFF3B6CCB0ABB343B344B345B346CAAFB347B348EDB6B349EDB7B34AB34BB34CB34DCEF9B7AFBFF3EDB8C2EBC9B0B34EB34FB350B351B352B353EDB9B354B355C6F6BFB3B356B357B358EDBCC5F8B359D1D0B35AD7A9EDBAEDBBB35BD1E2B35CEDBFEDC0B35DEDC4B35EB35FB360EDC8B361EDC6EDCED5E8B362EDC9B363B364EDC7EDBEB365B366C5E9B367B368B369C6C6B36AB36BC9E9D4D2EDC1EDC2EDC3EDC5B36CC0F9B36DB4A1B36EB36FB370B371B9E8B372EDD0B373B374B375B376EDD1B377EDCAB378EDCFB379CEF8B37AB37BCBB6EDCCEDCDB37CB37DB37EB380B381CFF5B382B383B384B385B386B387B388B389B38AB38BB38CB38DEDD2C1F2D3B2EDCBC8B7B38EB38FB390B391B392B393B394B395BCEFB396B397B398B399C5F0B39AB39BB39CB39DB39EB39FB3A0B440B441B442EDD6B443B5EFB444B445C2B5B0ADCBE9B446B447B1AEB448EDD4B449B44AB44BCDEBB5E2B44CEDD5EDD3EDD7B44DB44EB5FAB44FEDD8B450EDD9B451EDDCB452B1CCB453B454B455B456B457B458B459B45AC5F6BCEEEDDACCBCB2EAB45BB45CB45DB45EEDDBB45FB460B461B462C4EBB463B464B4C5B465B466B467B0F5B468B469B46AEDDFC0DAB4E8B46BB46CB46DB46EC5CDB46FB470B471EDDDBFC4B472B473B474EDDEB475B476B477B478B479B47AB47BB47CB47DB47EB480B481B482B483C4A5B484B485B486EDE0B487B488B489B48AB48BEDE1B48CEDE3B48DB48EC1D7B48FB490BBC7B491B492B493B494B495B496BDB8B497B498B499EDE2B49AB49BB49CB49DB49EB49FB4A0B540B541B542B543B544B545EDE4B546B547B548B549B54AB54BB54CB54DB54EB54FEDE6B550B551B552B553B554EDE5B555B556B557B558B559B55AB55BB55CB55DB55EB55FB560B561B562B563EDE7B564B565B566B567B568CABEECEAC0F1B569C9E7B56AECEBC6EEB56BB56CB56DB56EECECB56FC6EDECEDB570B571B572B573B574B575B576B577B578ECF0B579B57AD7E6ECF3B57BB57CECF1ECEEECEFD7A3C9F1CBEEECF4B57DECF2B57EB580CFE9B581ECF6C6B1B582B583B584B585BCC0B586ECF5B587B588B589B58AB58BB58CB58DB5BBBBF6B58EECF7B58FB590B591B592B593D9F7BDFBB594B595C2BBECF8B596B597B598B599ECF9B59AB59BB59CB59DB8A3B59EB59FB5A0B640B641B642B643B644B645B646ECFAB647B648B649B64AB64BB64CB64DB64EB64FB650B651B652ECFBB653B654B655B656B657B658B659B65AB65BB65CB65DECFCB65EB65FB660B661B662D3EDD8AEC0EBB663C7DDBACCB664D0E3CBBDB665CDBAB666B667B8D1B668B669B1FCB66AC7EFB66BD6D6B66CB66DB66EBFC6C3EBB66FB670EFF5B671B672C3D8B673B674B675B676B677B678D7E2B679B67AB67BEFF7B3D3B67CC7D8D1EDB67DD6C8B67EEFF8B680EFF6B681BBFDB3C6B682B683B684B685B686B687B688BDD5B689B68AD2C6B68BBBE0B68CB68DCFA1B68EEFFCEFFBB68FB690EFF9B691B692B693B694B3CCB695C9D4CBB0B696B697B698B699B69AEFFEB69BB69CB0DEB69DB69ED6C9B69FB6A0B740EFFDB741B3EDB742B743F6D5B744B745B746B747B748B749B74AB74BB74CB74DB74EB74FB750B751B752CEC8B753B754B755F0A2B756F0A1B757B5BEBCDABBFCB758B8E5B759B75AB75BB75CB75DB75EC4C2B75FB760B761B762B763B764B765B766B767B768F0A3B769B76AB76BB76CB76DCBEBB76EB76FB770B771B772B773B774B775B776B777B778B779B77AB77BB77CB77DB77EB780B781B782B783B784B785B786F0A6B787B788B789D1A8B78ABEBFC7EEF1B6F1B7BFD5B78BB78CB78DB78EB4A9F1B8CDBBB78FC7D4D5ADB790F1B9B791F1BAB792B793B794B795C7CFB796B797B798D2A4D6CFB799B79AF1BBBDD1B4B0BEBDB79BB79CB79DB4DCCED1B79EBFDFF1BDB79FB7A0B840B841BFFAF1BCB842F1BFB843B844B845F1BEF1C0B846B847B848B849B84AF1C1B84BB84CB84DB84EB84FB850B851B852B853B854B855C1FEB856B857B858B859B85AB85BB85CB85DB85EB85FB860C1A2B861B862B863B864B865B866B867B868B869B86ACAFAB86BB86CD5BEB86DB86EB86FB870BEBABEB9D5C2B871B872BFA2B873CDAFF1B5B874B875B876B877B878B879BDDFB87AB6CBB87BB87CB87DB87EB880B881B882B883B884D6F1F3C3B885B886F3C4B887B8CDB888B889B88AF3C6F3C7B88BB0CAB88CF3C5B88DF3C9CBF1B88EB88FB890F3CBB891D0A6B892B893B1CAF3C8B894B895B896F3CFB897B5D1B898B899F3D7B89AF3D2B89BB89CB89DF3D4F3D3B7FBB89EB1BFB89FF3CEF3CAB5DAB8A0F3D0B940B941F3D1B942F3D5B943B944B945B946F3CDB947BCE3B948C1FDB949F3D6B94AB94BB94CB94DB94EB94FF3DAB950F3CCB951B5C8B952BDEEF3DCB953B954B7A4BFF0D6FECDB2B955B4F0B956B2DFB957F3D8B958F3D9C9B8B959F3DDB95AB95BF3DEB95CF3E1B95DB95EB95FB960B961B962B963B964B965B966B967F3DFB968B969F3E3F3E2B96AB96BF3DBB96CBFEAB96DB3EFB96EF3E0B96FB970C7A9B971BCF2B972B973B974B975F3EBB976B977B978B979B97AB97BB97CB9BFB97DB97EF3E4B980B981B982B2ADBBFEB983CBE3B984B985B986B987F3EDF3E9B988B989B98AB9DCF3EEB98BB98CB98DF3E5F3E6F3EAC2E1F3ECF3EFF3E8BCFDB98EB98FB990CFE4B991B992F3F0B993B994B995F3E7B996B997B998B999B99AB99BB99CB99DF3F2B99EB99FB9A0BA40D7ADC6AABA41BA42BA43BA44F3F3BA45BA46BA47BA48F3F1BA49C2A8BA4ABA4BBA4CBA4DBA4EB8DDF3F5BA4FBA50F3F4BA51BA52BA53B4DBBA54BA55BA56F3F6F3F7BA57BA58BA59F3F8BA5ABA5BBA5CC0BABA5DBA5EC0E9BA5FBA60BA61BA62BA63C5F1BA64BA65BA66BA67F3FBBA68F3FABA69BA6ABA6BBA6CBA6DBA6EBA6FBA70B4D8BA71BA72BA73F3FEF3F9BA74BA75F3FCBA76BA77BA78BA79BA7ABA7BF3FDBA7CBA7DBA7EBA80BA81BA82BA83BA84F4A1BA85BA86BA87BA88BA89BA8AF4A3BBC9BA8BBA8CF4A2BA8DBA8EBA8FBA90BA91BA92BA93BA94BA95BA96BA97BA98BA99F4A4BA9ABA9BBA9CBA9DBA9EBA9FB2BEF4A6F4A5BAA0BB40BB41BB42BB43BB44BB45BB46BB47BB48BB49BCAEBB4ABB4BBB4CBB4DBB4EBB4FBB50BB51BB52BB53BB54BB55BB56BB57BB58BB59BB5ABB5BBB5CBB5DBB5EBB5FBB60BB61BB62BB63BB64BB65BB66BB67BB68BB69BB6ABB6BBB6CBB6DBB6EC3D7D9E1BB6FBB70BB71BB72BB73BB74C0E0F4CCD7D1BB75BB76BB77BB78BB79BB7ABB7BBB7CBB7DBB7EBB80B7DBBB81BB82BB83BB84BB85BB86BB87F4CEC1A3BB88BB89C6C9BB8AB4D6D5B3BB8BBB8CBB8DF4D0F4CFF4D1CBDABB8EBB8FF4D2BB90D4C1D6E0BB91BB92BB93BB94B7E0BB95BB96BB97C1B8BB98BB99C1BBF4D3BEACBB9ABB9BBB9CBB9DBB9EB4E2BB9FBBA0F4D4F4D5BEABBC40BC41F4D6BC42BC43BC44F4DBBC45F4D7F4DABC46BAFDBC47F4D8F4D9BC48BC49BC4ABC4BBC4CBC4DBC4EB8E2CCC7F4DCBC4FB2DABC50BC51C3D3BC52BC53D4E3BFB7BC54BC55BC56BC57BC58BC59BC5AF4DDBC5BBC5CBC5DBC5EBC5FBC60C5B4BC61BC62BC63BC64BC65BC66BC67BC68F4E9BC69BC6ACFB5BC6BBC6CBC6DBC6EBC6FBC70BC71BC72BC73BC74BC75BC76BC77BC78CEC9BC79BC7ABC7BBC7CBC7DBC7EBC80BC81BC82BC83BC84BC85BC86BC87BC88BC89BC8ABC8BBC8CBC8DBC8ECBD8BC8FCBF7BC90BC91BC92BC93BDF4BC94BC95BC96D7CFBC97BC98BC99C0DBBC9ABC9BBC9CBC9DBC9EBC9FBCA0BD40BD41BD42BD43BD44BD45BD46BD47BD48BD49BD4ABD4BBD4CBD4DBD4EBD4FBD50BD51BD52BD53BD54BD55BD56BD57BD58BD59BD5ABD5BBD5CBD5DBD5EBD5FBD60BD61BD62BD63BD64BD65BD66BD67BD68BD69BD6ABD6BBD6CBD6DBD6EBD6FBD70BD71BD72BD73BD74BD75BD76D0F5BD77BD78BD79BD7ABD7BBD7CBD7DBD7EF4EABD80BD81BD82BD83BD84BD85BD86BD87BD88BD89BD8ABD8BBD8CBD8DBD8EBD8FBD90BD91BD92BD93BD94BD95BD96BD97BD98BD99BD9ABD9BBD9CBD9DBD9EBD9FBDA0BE40BE41BE42BE43BE44BE45BE46BE47BE48BE49BE4ABE4BBE4CF4EBBE4DBE4EBE4FBE50BE51BE52BE53F4ECBE54BE55BE56BE57BE58BE59BE5ABE5BBE5CBE5DBE5EBE5FBE60BE61BE62BE63BE64BE65BE66BE67BE68BE69BE6ABE6BBE6CBE6DBE6EBE6FBE70BE71BE72BE73BE74BE75BE76BE77BE78BE79BE7ABE7BBE7CBE7DBE7EBE80BE81BE82BE83BE84BE85BE86BE87BE88BE89BE8ABE8BBE8CBE8DBE8EBE8FBE90BE91BE92BE93BE94BE95BE96BE97BE98BE99BE9ABE9BBE9CBE9DBE9EBE9FBEA0BF40BF41BF42BF43BF44BF45BF46BF47BF48BF49BF4ABF4BBF4CBF4DBF4EBF4FBF50BF51BF52BF53BF54BF55BF56BF57BF58BF59BF5ABF5BBF5CBF5DBF5EBF5FBF60BF61BF62BF63BF64BF65BF66BF67BF68BF69BF6ABF6BBF6CBF6DBF6EBF6FBF70BF71BF72BF73BF74BF75BF76BF77BF78BF79BF7ABF7BBF7CBF7DBF7EBF80F7E3BF81BF82BF83BF84BF85B7B1BF86BF87BF88BF89BF8AF4EDBF8BBF8CBF8DBF8EBF8FBF90BF91BF92BF93BF94BF95BF96BF97BF98BF99BF9ABF9BBF9CBF9DBF9EBF9FBFA0C040C041C042C043C044C045C046C047C048C049C04AC04BC04CC04DC04EC04FC050C051C052C053C054C055C056C057C058C059C05AC05BC05CC05DC05EC05FC060C061C062C063D7EBC064C065C066C067C068C069C06AC06BC06CC06DC06EC06FC070C071C072C073C074C075C076C077C078C079C07AC07BF4EEC07CC07DC07EE6F9BEC0E6FABAECE6FBCFCBE6FCD4BCBCB6E6FDE6FEBCCDC8D2CEB3E7A1C080B4BFE7A2C9B4B8D9C4C9C081D7DDC2DAB7D7D6BDCEC6B7C4C082C083C5A6E7A3CFDFE7A4E7A5E7A6C1B7D7E9C9F0CFB8D6AFD6D5E7A7B0EDE7A8E7A9C9DCD2EFBEADE7AAB0F3C8DEBDE1E7ABC8C6C084E7ACBBE6B8F8D1A4E7ADC2E7BEF8BDCACDB3E7AEE7AFBEEED0E5C085CBE7CCD0BCCCE7B0BCA8D0F7E7B1C086D0F8E7B2E7B3B4C2E7B4E7B5C9FECEACC3E0E7B7B1C1B3F1C087E7B8E7B9D7DBD5C0E7BAC2CCD7BAE7BBE7BCE7BDBCEAC3E5C0C2E7BEE7BFBCA9C088E7C0E7C1E7B6B6D0E7C2C089E7C3E7C4BBBAB5DEC2C6B1E0E7C5D4B5E7C6B8BFE7C8E7C7B7ECC08AE7C9B2F8E7CAE7CBE7CCE7CDE7CEE7CFE7D0D3A7CBF5E7D1E7D2E7D3E7D4C9C9E7D5E7D6E7D7E7D8E7D9BDC9E7DAF3BEC08BB8D7C08CC8B1C08DC08EC08FC090C091C092C093F3BFC094F3C0F3C1C095C096C097C098C099C09AC09BC09CC09DC09EB9DECDF8C09FC0A0D8E8BAB1C140C2DEEEB7C141B7A3C142C143C144C145EEB9C146EEB8B0D5C147C148C149C14AC14BEEBBD5D6D7EFC14CC14DC14ED6C3C14FC150EEBDCAF0C151EEBCC152C153C154C155EEBEC156C157C158C159EEC0C15AC15BEEBFC15CC15DC15EC15FC160C161C162C163D1F2C164C7BCC165C3C0C166C167C168C169C16AB8E1C16BC16CC16DC16EC16FC1E7C170C171F4C6D0DFF4C7C172CFDBC173C174C8BAC175C176F4C8C177C178C179C17AC17BC17CC17DF4C9F4CAC17EF4CBC180C181C182C183C184D9FAB8FEC185C186E5F1D3F0C187F4E0C188CECCC189C18AC18BB3E1C18CC18DC18EC18FF1B4C190D2EEC191F4E1C192C193C194C195C196CFE8F4E2C197C198C7CCC199C19AC19BC19CC19DC19EB5D4B4E4F4E4C19FC1A0C240F4E3F4E5C241C242F4E6C243C244C245C246F4E7C247BAB2B0BFC248F4E8C249C24AC24BC24CC24DC24EC24FB7ADD2EDC250C251C252D2ABC0CFC253BFBCEBA3D5DFEAC8C254C255C256C257F1F3B6F8CBA3C258C259C4CDC25AF1E7C25BF1E8B8FBF1E9BAC4D4C5B0D2C25CC25DF1EAC25EC25FC260F1EBC261F1ECC262C263F1EDF1EEF1EFF1F1F1F0C5D5C264C265C266C267C268C269F1F2C26AB6FAC26BF1F4D2AEDEC7CBCAC26CC26DB3DCC26EB5A2C26FB9A2C270C271C4F4F1F5C272C273F1F6C274C275C276C1C4C1FBD6B0F1F7C277C278C279C27AF1F8C27BC1AAC27CC27DC27EC6B8C280BEDBC281C282C283C284C285C286C287C288C289C28AC28BC28CC28DC28EF1F9B4CFC28FC290C291C292C293C294F1FAC295C296C297C298C299C29AC29BC29CC29DC29EC29FC2A0C340EDB2EDB1C341C342CBE0D2DEC343CBC1D5D8C344C8E2C345C0DFBCA1C346C347C348C349C34AC34BEBC1C34CC34DD0A4C34ED6E2C34FB6C7B8D8EBC0B8CEC350EBBFB3A6B9C9D6ABC351B7F4B7CAC352C353C354BCE7B7BEEBC6C355EBC7B0B9BFCFC356EBC5D3FDC357EBC8C358C359EBC9C35AC35BB7CEC35CEBC2EBC4C9F6D6D7D5CDD0B2EBCFCEB8EBD0C35DB5A8C35EC35FC360C361C362B1B3EBD2CCA5C363C364C365C366C367C368C369C5D6EBD3C36AEBD1C5DFEBCECAA4EBD5B0FBC36BC36CBAFAC36DC36ED8B7F1E3C36FEBCAEBCBEBCCEBCDEBD6E6C0EBD9C370BFE8D2C8EBD7EBDCB8ECEBD8C371BDBAC372D0D8C373B0B7C374EBDDC4DCC375C376C377C378D6ACC379C37AC37BB4E0C37CC37DC2F6BCB9C37EC380EBDAEBDBD4E0C6EAC4D4EBDFC5A7D9F5C381B2B1C382EBE4C383BDC5C384C385C386EBE2C387C388C389C38AC38BC38CC38DC38EC38FC390C391C392C393EBE3C394C395B8ACC396CDD1EBE5C397C398C399EBE1C39AC1B3C39BC39CC39DC39EC39FC6A2C3A0C440C441C442C443C444C445CCF3C446EBE6C447C0B0D2B8EBE7C448C449C44AB8AFB8ADC44BEBE8C7BBCDF3C44CC44DC44EEBEAEBEBC44FC450C451C452C453EBEDC454C455C456C457D0C8C458EBF2C459EBEEC45AC45BC45CEBF1C8F9C45DD1FCEBECC45EC45FEBE9C460C461C462C463B8B9CFD9C4E5EBEFEBF0CCDACDC8B0F2C464EBF6C465C466C467C468C469EBF5C46AB2B2C46BC46CC46DC46EB8E0C46FEBF7C470C471C472C473C474C475B1ECC476C477CCC5C4A4CFA5C478C479C47AC47BC47CEBF9C47DC47EECA2C480C5F2C481EBFAC482C483C484C485C486C487C488C489C9C5C48AC48BC48CC48DC48EC48FE2DFEBFEC490C491C492C493CDCEECA1B1DBD3B7C494C495D2DCC496C497C498EBFDC499EBFBC49AC49BC49CC49DC49EC49FC4A0C540C541C542C543C544C545C546C547C548C549C54AC54BC54CC54DC54EB3BCC54FC550C551EAB0C552C553D7D4C554F4ABB3F4C555C556C557C558C559D6C1D6C2C55AC55BC55CC55DC55EC55FD5E9BECAC560F4A7C561D2A8F4A8F4A9C562F4AABECBD3DFC563C564C565C566C567C9E0C9E1C568C569F3C2C56ACAE6C56BCCF2C56CC56DC56EC56FC570C571E2B6CBB4C572CEE8D6DBC573F4ADF4AEF4AFC574C575C576C577F4B2C578BABDF4B3B0E3F4B0C579F4B1BDA2B2D5C57AF4B6F4B7B6E6B2B0CFCFF4B4B4ACC57BF4B5C57CC57DF4B8C57EC580C581C582C583F4B9C584C585CDA7C586F4BAC587F4BBC588C589C58AF4BCC58BC58CC58DC58EC58FC590C591C592CBD2C593F4BDC594C595C596C597F4BEC598C599C59AC59BC59CC59DC59EC59FF4BFC5A0C640C641C642C643F4DEC1BCBCE8C644C9ABD1DEE5F5C645C646C647C648DCB3D2D5C649C64ADCB4B0ACDCB5C64BC64CBDDAC64DDCB9C64EC64FC650D8C2C651DCB7D3F3C652C9D6DCBADCB6C653DCBBC3A2C654C655C656C657DCBCDCC5DCBDC658C659CEDFD6A5C65ADCCFC65BDCCDC65CC65DDCD2BDE6C2ABC65EDCB8DCCBDCCEDCBEB7D2B0C5DCC7D0BEDCC1BBA8C65FB7BCDCCCC660C661DCC6DCBFC7DBC662C663C664D1BFDCC0C665C666DCCAC667C668DCD0C669C66ACEADDCC2C66BDCC3DCC8DCC9B2D4DCD1CBD5C66CD4B7DCDBDCDFCCA6DCE6C66DC3E7DCDCC66EC66FBFC1DCD9C670B0FAB9B6DCE5DCD3C671DCC4DCD6C8F4BFE0C672C673C674C675C9BBC676C677C678B1BDC679D3A2C67AC67BDCDAC67CC67DDCD5C67EC6BBC680DCDEC681C682C683C684C685D7C2C3AFB7B6C7D1C3A9DCE2DCD8DCEBDCD4C686C687DCDDC688BEA5DCD7C689DCE0C68AC68BDCE3DCE4C68CDCF8C68DC68EDCE1DDA2DCE7C68FC690C691C692C693C694C695C696C697C698BCEBB4C4C699C69AC3A3B2E7DCFAC69BDCF2C69CDCEFC69DDCFCDCEED2F0B2E8C69EC8D7C8E3DCFBC69FDCEDC6A0C740C741DCF7C742C743DCF5C744C745BEA3DCF4C746B2DDC747C748C749C74AC74BDCF3BCF6DCE8BBC4C74CC0F3C74DC74EC74FC750C751BCD4DCE9DCEAC752DCF1DCF6DCF9B5B4C753C8D9BBE7DCFEDCFDD3ABDDA1DDA3DDA5D2F1DDA4DDA6DDA7D2A9C754C755C756C757C758C759C75ABAC9DDA9C75BC75CDDB6DDB1DDB4C75DC75EC75FC760C761C762C763DDB0C6CEC764C765C0F2C766C767C768C769C9AFC76AC76BC76CDCECDDAEC76DC76EC76FC770DDB7C771C772DCF0DDAFC773DDB8C774DDACC775C776C777C778C779C77AC77BDDB9DDB3DDADC4AAC77CC77DC77EC780DDA8C0B3C1ABDDAADDABC781DDB2BBF1DDB5D3A8DDBAC782DDBBC3A7C783C784DDD2DDBCC785C786C787DDD1C788B9BDC789C78ABED5C78BBEFAC78CC78DBACAC78EC78FC790C791DDCAC792DDC5C793DDBFC794C795C796B2CBDDC3C797DDCBB2A4DDD5C798C799C79ADDBEC79BC79CC79DC6D0DDD0C79EC79FC7A0C840C841DDD4C1E2B7C6C842C843C844C845C846DDCEDDCFC847C848C849DDC4C84AC84BC84CDDBDC84DDDCDCCD1C84EDDC9C84FC850C851C852DDC2C3C8C6BCCEAEDDCCC853DDC8C854C855C856C857C858C859DDC1C85AC85BC85CDDC6C2DCC85DC85EC85FC860C861C862D3A9D3AADDD3CFF4C8F8C863C864C865C866C867C868C869C86ADDE6C86BC86CC86DC86EC86FC870DDC7C871C872C873DDE0C2E4C874C875C876C877C878C879C87AC87BDDE1C87CC87DC87EC880C881C882C883C884C885C886DDD7C887C888C889C88AC88BD6F8C88CDDD9DDD8B8F0DDD6C88DC88EC88FC890C6CFC891B6ADC892C893C894C895C896DDE2C897BAF9D4E1DDE7C898C899C89AB4D0C89BDDDAC89CBFFBDDE3C89DDDDFC89EDDDDC89FC8A0C940C941C942C943C944B5D9C945C946C947C948DDDBDDDCDDDEC949BDAFDDE4C94ADDE5C94BC94CC94DC94EC94FC950C951C952DDF5C953C3C9C954C955CBE2C956C957C958C959DDF2C95AC95BC95CC95DC95EC95FC960C961C962C963C964C965C966D8E1C967C968C6D1C969DDF4C96AC96BC96CD5F4DDF3DDF0C96DC96EDDECC96FDDEFC970DDE8C971C972D0EEC973C974C975C976C8D8DDEEC977C978DDE9C979C97ADDEACBF2C97BDDEDC97CC97DB1CDC97EC980C981C982C983C984C0B6C985BCBBDDF1C986C987DDF7C988DDF6DDEBC989C98AC98BC98CC98DC5EEC98EC98FC990DDFBC991C992C993C994C995C996C997C998C999C99AC99BDEA4C99CC99DDEA3C99EC99FC9A0CA40CA41CA42CA43CA44CA45CA46CA47CA48DDF8CA49CA4ACA4BCA4CC3EFCA4DC2FBCA4ECA4FCA50D5E1CA51CA52CEB5CA53CA54CA55CA56DDFDCA57B2CCCA58CA59CA5ACA5BCA5CCA5DCA5ECA5FCA60C4E8CADFCA61CA62CA63CA64CA65CA66CA67CA68CA69CA6AC7BEDDFADDFCDDFEDEA2B0AAB1CECA6BCA6CCA6DCA6ECA6FDEACCA70CA71CA72CA73DEA6BDB6C8EFCA74CA75CA76CA77CA78CA79CA7ACA7BCA7CCA7DCA7EDEA1CA80CA81DEA5CA82CA83CA84CA85DEA9CA86CA87CA88CA89CA8ADEA8CA8BCA8CCA8DDEA7CA8ECA8FCA90CA91CA92CA93CA94CA95CA96DEADCA97D4CCCA98CA99CA9ACA9BDEB3DEAADEAECA9CCA9DC0D9CA9ECA9FCAA0CB40CB41B1A1DEB6CB42DEB1CB43CB44CB45CB46CB47CB48CB49DEB2CB4ACB4BCB4CCB4DCB4ECB4FCB50CB51CB52CB53CB54D1A6DEB5CB55CB56CB57CB58CB59CB5ACB5BDEAFCB5CCB5DCB5EDEB0CB5FD0BDCB60CB61CB62DEB4CAEDDEB9CB63CB64CB65CB66CB67CB68DEB8CB69DEB7CB6ACB6BCB6CCB6DCB6ECB6FCB70DEBBCB71CB72CB73CB74CB75CB76CB77BDE5CB78CB79CB7ACB7BCB7CB2D8C3EACB7DCB7EDEBACB80C5BACB81CB82CB83CB84CB85CB86DEBCCB87CB88CB89CB8ACB8BCB8CCB8DCCD9CB8ECB8FCB90CB91B7AACB92CB93CB94CB95CB96CB97CB98CB99CB9ACB9BCB9CCB9DCB9ECB9FCBA0CC40CC41D4E5CC42CC43CC44DEBDCC45CC46CC47CC48CC49DEBFCC4ACC4BCC4CCC4DCC4ECC4FCC50CC51CC52CC53CC54C4A2CC55CC56CC57CC58DEC1CC59CC5ACC5BCC5CCC5DCC5ECC5FCC60CC61CC62CC63CC64CC65CC66CC67CC68DEBECC69DEC0CC6ACC6BCC6CCC6DCC6ECC6FCC70CC71CC72CC73CC74CC75CC76CC77D5BACC78CC79CC7ADEC2CC7BCC7CCC7DCC7ECC80CC81CC82CC83CC84CC85CC86CC87CC88CC89CC8ACC8BF2AEBBA2C2B2C5B0C2C7CC8CCC8DF2AFCC8ECC8FCC90CC91CC92D0E9CC93CC94CC95D3DDCC96CC97CC98EBBDCC99CC9ACC9BCC9CCC9DCC9ECC9FCCA0B3E6F2B0CD40F2B1CD41CD42CAADCD43CD44CD45CD46CD47CD48CD49BAE7F2B3F2B5F2B4CBE4CFBAF2B2CAB4D2CFC2ECCD4ACD4BCD4CCD4DCD4ECD4FCD50CEC3F2B8B0F6F2B7CD51CD52CD53CD54CD55F2BECD56B2CFCD57CD58CD59CD5ACD5BCD5CD1C1F2BACD5DCD5ECD5FCD60CD61F2BCD4E9CD62CD63F2BBF2B6F2BFF2BDCD64F2B9CD65CD66F2C7F2C4F2C6CD67CD68F2CAF2C2F2C0CD69CD6ACD6BF2C5CD6CCD6DCD6ECD6FCD70D6FBCD71CD72CD73F2C1CD74C7F9C9DFCD75F2C8B9C6B5B0CD76CD77F2C3F2C9F2D0F2D6CD78CD79BBD7CD7ACD7BCD7CF2D5CDDCCD7DD6EBCD7ECD80F2D2F2D4CD81CD82CD83CD84B8F2CD85CD86CD87CD88F2CBCD89CD8ACD8BF2CEC2F9CD8CD5DDF2CCF2CDF2CFF2D3CD8DCD8ECD8FF2D9D3BCCD90CD91CD92CD93B6EACD94CAF1CD95B7E4F2D7CD96CD97CD98F2D8F2DAF2DDF2DBCD99CD9AF2DCCD9BCD9CCD9DCD9ED1D1F2D1CD9FCDC9CDA0CECFD6A9CE40F2E3CE41C3DBCE42F2E0CE43CE44C0AFF2ECF2DECE45F2E1CE46CE47CE48F2E8CE49CE4ACE4BCE4CF2E2CE4DCE4EF2E7CE4FCE50F2E6CE51CE52F2E9CE53CE54CE55F2DFCE56CE57F2E4F2EACE58CE59CE5ACE5BCE5CCE5DCE5ED3ACF2E5B2F5CE5FCE60F2F2CE61D0ABCE62CE63CE64CE65F2F5CE66CE67CE68BBC8CE69F2F9CE6ACE6BCE6CCE6DCE6ECE6FF2F0CE70CE71F2F6F2F8F2FACE72CE73CE74CE75CE76CE77CE78CE79F2F3CE7AF2F1CE7BCE7CCE7DBAFBCE7EB5FBCE80CE81CE82CE83F2EFF2F7F2EDF2EECE84CE85CE86F2EBF3A6CE87F3A3CE88CE89F3A2CE8ACE8BF2F4CE8CC8DACE8DCE8ECE8FCE90CE91F2FBCE92CE93CE94F3A5CE95CE96CE97CE98CE99CE9ACE9BC3F8CE9CCE9DCE9ECE9FCEA0CF40CF41CF42F2FDCF43CF44F3A7F3A9F3A4CF45F2FCCF46CF47CF48F3ABCF49F3AACF4ACF4BCF4CCF4DC2DDCF4ECF4FF3AECF50CF51F3B0CF52CF53CF54CF55CF56F3A1CF57CF58CF59F3B1F3ACCF5ACF5BCF5CCF5DCF5EF3AFF2FEF3ADCF5FCF60CF61CF62CF63CF64CF65F3B2CF66CF67CF68CF69F3B4CF6ACF6BCF6CCF6DF3A8CF6ECF6FCF70CF71F3B3CF72CF73CF74F3B5CF75CF76CF77CF78CF79CF7ACF7BCF7CCF7DCF7ED0B7CF80CF81CF82CF83F3B8CF84CF85CF86CF87D9F9CF88CF89CF8ACF8BCF8CCF8DF3B9CF8ECF8FCF90CF91CF92CF93CF94CF95F3B7CF96C8E4F3B6CF97CF98CF99CF9AF3BACF9BCF9CCF9DCF9ECF9FF3BBB4C0CFA0D040D041D042D043D044D045D046D047D048D049D04AD04BD04CD04DEEC3D04ED04FD050D051D052D053F3BCD054D055F3BDD056D057D058D1AAD059D05AD05BF4ACD0C6D05CD05DD05ED05FD060D061D0D0D1DCD062D063D064D065D066D067CFCED068D069BDD6D06AD1C3D06BD06CD06DD06ED06FD070D071BAE2E1E9D2C2F1C2B2B9D072D073B1EDF1C3D074C9C0B3C4D075D9F2D076CBA5D077F1C4D078D079D07AD07BD6D4D07CD07DD07ED080D081F1C5F4C0F1C6D082D4ACF1C7D083B0C0F4C1D084D085F4C2D086D087B4FCD088C5DBD089D08AD08BD08CCCBBD08DD08ED08FD0E4D090D091D092D093D094CDE0D095D096D097D098D099F1C8D09AD9F3D09BD09CD09DD09ED09FD0A0B1BBD140CFAED141D142D143B8A4D144D145D146D147D148F1CAD149D14AD14BD14CF1CBD14DD14ED14FD150B2C3C1D1D151D152D7B0F1C9D153D154F1CCD155D156D157D158F1CED159D15AD15BD9F6D15CD2E1D4A3D15DD15EF4C3C8B9D15FD160D161D162D163F4C4D164D165F1CDF1CFBFE3F1D0D166D167F1D4D168D169D16AD16BD16CD16DD16EF1D6F1D1D16FC9D1C5E1D170D171D172C2E3B9FCD173D174F1D3D175F1D5D176D177D178B9D3D179D17AD17BD17CD17DD17ED180F1DBD181D182D183D184D185BAD6D186B0FDF1D9D187D188D189D18AD18BF1D8F1D2F1DAD18CD18DD18ED18FD190F1D7D191D192D193C8ECD194D195D196D197CDCAF1DDD198D199D19AD19BE5BDD19CD19DD19EF1DCD19FF1DED1A0D240D241D242D243D244D245D246D247D248F1DFD249D24ACFE5D24BD24CD24DD24ED24FD250D251D252D253D254D255D256D257D258D259D25AD25BD25CD25DD25ED25FD260D261D262D263F4C5BDF3D264D265D266D267D268D269F1E0D26AD26BD26CD26DD26ED26FD270D271D272D273D274D275D276D277D278D279D27AD27BD27CD27DF1E1D27ED280D281CEF7D282D2AAD283F1FBD284D285B8B2D286D287D288D289D28AD28BD28CD28DD28ED28FD290D291D292D293D294D295D296D297D298D299D29AD29BD29CD29DD29ED29FD2A0D340D341D342D343D344D345D346D347D348D349D34AD34BD34CD34DD34ED34FD350D351D352D353D354D355D356D357D358D359D35AD35BD35CD35DD35EBCFBB9DBD35FB9E6C3D9CAD3EAE8C0C0BEF5EAE9EAEAEAEBD360EAECEAEDEAEEEAEFBDC7D361D362D363F5FBD364D365D366F5FDD367F5FED368F5FCD369D36AD36BD36CBDE2D36DF6A1B4A5D36ED36FD370D371F6A2D372D373D374F6A3D375D376D377ECB2D378D379D37AD37BD37CD37DD37ED380D381D382D383D384D1D4D385D386D387D388D389D38AD9EAD38BD38CD38DD38ED38FD390D391D392D393D394D395D396D397D398D399D39AD39BD39CD39DD39ED39FD3A0D440D441D442D443D444D445D446D447D448D449D44AD44BD44CD44DD44ED44FD450D451D452D453D454D455D456D457D458D459D45AD45BD45CD45DD45ED45FF6A4D460D461D462D463D464D465D466D467D468EEBAD469D46AD46BD46CD46DD46ED46FD470D471D472D473D474D475D476D477D478D479D47AD47BD47CD47DD47ED480D481D482D483D484D485D486D487D488D489D48AD48BD48CD48DD48ED48FD490D491D492D493D494D495D496D497D498D499D5B2D49AD49BD49CD49DD49ED49FD4A0D540D541D542D543D544D545D546D547D3FECCDCD548D549D54AD54BD54CD54DD54ED54FCAC4D550D551D552D553D554D555D556D557D558D559D55AD55BD55CD55DD55ED55FD560D561D562D563D564D565D566D567D568D569D56AD56BD56CD56DD56ED56FD570D571D572D573D574D575D576D577D578D579D57AD57BD57CD57DD57ED580D581D582D583D584D585D586D587D588D589D58AD58BD58CD58DD58ED58FD590D591D592D593D594D595D596D597D598D599D59AD59BD59CD59DD59ED59FD5A0D640D641D642D643D644D645D646D647D648D649D64AD64BD64CD64DD64ED64FD650D651D652D653D654D655D656D657D658D659D65AD65BD65CD65DD65ED65FD660D661D662E5C0D663D664D665D666D667D668D669D66AD66BD66CD66DD66ED66FD670D671D672D673D674D675D676D677D678D679D67AD67BD67CD67DD67ED680D681F6A5D682D683D684D685D686D687D688D689D68AD68BD68CD68DD68ED68FD690D691D692D693D694D695D696D697D698D699D69AD69BD69CD69DD69ED69FD6A0D740D741D742D743D744D745D746D747D748D749D74AD74BD74CD74DD74ED74FD750D751D752D753D754D755D756D757D758D759D75AD75BD75CD75DD75ED75FBEAFD760D761D762D763D764C6A9D765D766D767D768D769D76AD76BD76CD76DD76ED76FD770D771D772D773D774D775D776D777D778D779D77AD77BD77CD77DD77ED780D781D782D783D784D785D786D787D788D789D78AD78BD78CD78DD78ED78FD790D791D792D793D794D795D796D797D798DAA5BCC6B6A9B8BCC8CFBCA5DAA6DAA7CCD6C8C3DAA8C6FDD799D1B5D2E9D1B6BCC7D79ABDB2BBE4DAA9DAAAD1C8DAABD0EDB6EFC2DBD79BCBCFB7EDC9E8B7C3BEF7D6A4DAACDAADC6C0D7E7CAB6D79CD5A9CBDFD5EFDAAED6DFB4CADAB0DAAFD79DD2EBDAB1DAB2DAB3CAD4DAB4CAABDAB5DAB6B3CFD6EFDAB7BBB0B5AEDAB8DAB9B9EED1AFD2E8DABAB8C3CFEAB2EFDABBDABCD79EBDEBCEDCD3EFDABDCEF3DABED3D5BBE5DABFCBB5CBD0DAC0C7EBD6EEDAC1C5B5B6C1DAC2B7CCBFCEDAC3DAC4CBADDAC5B5F7DAC6C1C2D7BBDAC7CCB8D79FD2EAC4B1DAC8B5FDBBD1DAC9D0B3DACADACBCEBDDACCDACDDACEB2F7DAD1DACFD1E8DAD0C3D5DAD2D7A0DAD3DAD4DAD5D0BBD2A5B0F9DAD6C7ABDAD7BDF7C3A1DAD8DAD9C3FDCCB7DADADADBC0BEC6D7DADCDADDC7B4DADEDADFB9C8D840D841D842D843D844D845D846D847D848BBEDD849D84AD84BD84CB6B9F4F8D84DF4F9D84ED84FCDE3D850D851D852D853D854D855D856D857F5B9D858D859D85AD85BEBE0D85CD85DD85ED85FD860D861CFF3BBBFD862D863D864D865D866D867D868BAC0D4A5D869D86AD86BD86CD86DD86ED86FE1D9D870D871D872D873F5F4B1AAB2F2D874D875D876D877D878D879D87AF5F5D87BD87CF5F7D87DD87ED880BAD1F5F6D881C3B2D882D883D884D885D886D887D888F5F9D889D88AD88BF5F8D88CD88DD88ED88FD890D891D892D893D894D895D896D897D898D899D89AD89BD89CD89DD89ED89FD8A0D940D941D942D943D944D945D946D947D948D949D94AD94BD94CD94DD94ED94FD950D951D952D953D954D955D956D957D958D959D95AD95BD95CD95DD95ED95FD960D961D962D963D964D965D966D967D968D969D96AD96BD96CD96DD96ED96FD970D971D972D973D974D975D976D977D978D979D97AD97BD97CD97DD97ED980D981D982D983D984D985D986D987D988D989D98AD98BD98CD98DD98ED98FD990D991D992D993D994D995D996D997D998D999D99AD99BD99CD99DD99ED99FD9A0DA40DA41DA42DA43DA44DA45DA46DA47DA48DA49DA4ADA4BDA4CDA4DDA4EB1B4D5EAB8BADA4FB9B1B2C6D4F0CFCDB0DCD5CBBBF5D6CAB7B7CCB0C6B6B1E1B9BAD6FCB9E1B7A1BCFAEADAEADBCCF9B9F3EADCB4FBC3B3B7D1BAD8EADDD4F4EADEBCD6BBDFEADFC1DEC2B8D4DFD7CAEAE0EAE1EAE4EAE2EAE3C9DEB8B3B6C4EAE5CAEAC9CDB4CDDA50DA51E2D9C5E2EAE6C0B5DA52D7B8EAE7D7ACC8FCD8D3D8CDD4DEDA53D4F9C9C4D3AEB8D3B3E0DA54C9E2F4F6DA55DA56DA57BAD5DA58F4F7DA59DA5AD7DFDA5BDA5CF4F1B8B0D5D4B8CFC6F0DA5DDA5EDA5FDA60DA61DA62DA63DA64DA65B3C3DA66DA67F4F2B3ACDA68DA69DA6ADA6BD4BDC7F7DA6CDA6DDA6EDA6FDA70F4F4DA71DA72F4F3DA73DA74DA75DA76DA77DA78DA79DA7ADA7BDA7CCCCBDA7DDA7EDA80C8A4DA81DA82DA83DA84DA85DA86DA87DA88DA89DA8ADA8BDA8CDA8DF4F5DA8ED7E3C5BFF5C0DA8FDA90F5BBDA91F5C3DA92F5C2DA93D6BAF5C1DA94DA95DA96D4BEF5C4DA97F5CCDA98DA99DA9ADA9BB0CFB5F8DA9CF5C9F5CADA9DC5DCDA9EDA9FDAA0DB40F5C5F5C6DB41DB42F5C7F5CBDB43BEE0F5C8B8FADB44DB45DB46F5D0F5D3DB47DB48DB49BFE7DB4AB9F2F5BCF5CDDB4BDB4CC2B7DB4DDB4EDB4FCCF8DB50BCF9DB51F5CEF5CFF5D1B6E5F5D2DB52F5D5DB53DB54DB55DB56DB57DB58DB59F5BDDB5ADB5BDB5CF5D4D3BBDB5DB3ECDB5EDB5FCCA4DB60DB61DB62DB63F5D6DB64DB65DB66DB67DB68DB69DB6ADB6BF5D7BEE1F5D8DB6CDB6DCCDFF5DBDB6EDB6FDB70DB71DB72B2C8D7D9DB73F5D9DB74F5DAF5DCDB75F5E2DB76DB77DB78F5E0DB79DB7ADB7BF5DFF5DDDB7CDB7DF5E1DB7EDB80F5DEF5E4F5E5DB81CCE3DB82DB83E5BFB5B8F5E3F5E8CCA3DB84DB85DB86DB87DB88F5E6F5E7DB89DB8ADB8BDB8CDB8DDB8EF5BEDB8FDB90DB91DB92DB93DB94DB95DB96DB97DB98DB99DB9AB1C4DB9BDB9CF5BFDB9DDB9EB5C5B2E4DB9FF5ECF5E9DBA0B6D7DC40F5EDDC41F5EADC42DC43DC44DC45DC46F5EBDC47DC48B4DADC49D4EADC4ADC4BDC4CF5EEDC4DB3F9DC4EDC4FDC50DC51DC52DC53DC54F5EFF5F1DC55DC56DC57F5F0DC58DC59DC5ADC5BDC5CDC5DDC5EF5F2DC5FF5F3DC60DC61DC62DC63DC64DC65DC66DC67DC68DC69DC6ADC6BC9EDB9AADC6CDC6DC7FBDC6EDC6FB6E3DC70DC71DC72DC73DC74DC75DC76CCC9DC77DC78DC79DC7ADC7BDC7CDC7DDC7EDC80DC81DC82DC83DC84DC85DC86DC87DC88DC89DC8AEAA6DC8BDC8CDC8DDC8EDC8FDC90DC91DC92DC93DC94DC95DC96DC97DC98DC99DC9ADC9BDC9CDC9DDC9EDC9FDCA0DD40DD41DD42DD43DD44DD45DD46DD47DD48DD49DD4ADD4BDD4CDD4DDD4EDD4FDD50DD51DD52DD53DD54DD55DD56DD57DD58DD59DD5ADD5BDD5CDD5DDD5EDD5FDD60DD61DD62DD63DD64DD65DD66DD67DD68DD69DD6ADD6BDD6CDD6DDD6EDD6FDD70DD71DD72DD73DD74DD75DD76DD77DD78DD79DD7ADD7BDD7CDD7DDD7EDD80DD81DD82DD83DD84DD85DD86DD87DD88DD89DD8ADD8BDD8CDD8DDD8EDD8FDD90DD91DD92DD93DD94DD95DD96DD97DD98DD99DD9ADD9BDD9CDD9DDD9EDD9FDDA0DE40DE41DE42DE43DE44DE45DE46DE47DE48DE49DE4ADE4BDE4CDE4DDE4EDE4FDE50DE51DE52DE53DE54DE55DE56DE57DE58DE59DE5ADE5BDE5CDE5DDE5EDE5FDE60B3B5D4FEB9ECD0F9DE61E9EDD7AAE9EEC2D6C8EDBAE4E9EFE9F0E9F1D6E1E9F2E9F3E9F5E9F4E9F6E9F7C7E1E9F8D4D8E9F9BDCEDE62E9FAE9FBBDCFE9FCB8A8C1BEE9FDB1B2BBD4B9F5E9FEDE63EAA1EAA2EAA3B7F8BCADDE64CAE4E0CED4AFCFBDD5B7EAA4D5DEEAA5D0C1B9BCDE65B4C7B1D9DE66DE67DE68C0B1DE69DE6ADE6BDE6CB1E6B1E7DE6DB1E8DE6EDE6FDE70DE71B3BDC8E8DE72DE73DE74DE75E5C1DE76DE77B1DFDE78DE79DE7AC1C9B4EFDE7BDE7CC7A8D3D8DE7DC6F9D1B8DE7EB9FDC2F5DE80DE81DE82DE83DE84D3ADDE85D4CBBDFCDE86E5C2B7B5E5C3DE87DE88BBB9D5E2DE89BDF8D4B6CEA5C1ACB3D9DE8ADE8BCCF6DE8CE5C6E5C4E5C8DE8DE5CAE5C7B5CFC6C8DE8EB5FCE5C5DE8FCAF6DE90DE91E5C9DE92DE93DE94C3D4B1C5BCA3DE95DE96DE97D7B7DE98DE99CDCBCBCDCACACCD3E5CCE5CBC4E6DE9ADE9BD1A1D1B7E5CDDE9CE5D0DE9DCDB8D6F0E5CFB5DDDE9ECDBEDE9FE5D1B6BADEA0DF40CDA8B9E4DF41CAC5B3D1CBD9D4ECE5D2B7EADF42DF43DF44E5CEDF45DF46DF47DF48DF49DF4AE5D5B4FEE5D6DF4BDF4CDF4DDF4EDF4FE5D3E5D4DF50D2DDDF51DF52C2DFB1C6DF53D3E2DF54DF55B6DDCBECDF56E5D7DF57DF58D3F6DF59DF5ADF5BDF5CDF5DB1E9DF5EB6F4E5DAE5D8E5D9B5C0DF5FDF60DF61D2C5E5DCDF62DF63E5DEDF64DF65DF66DF67DF68DF69E5DDC7B2DF6AD2A3DF6BDF6CE5DBDF6DDF6EDF6FDF70D4E2D5DADF71DF72DF73DF74DF75E5E0D7F1DF76DF77DF78DF79DF7ADF7BDF7CE5E1DF7DB1DCD1FBDF7EE5E2E5E4DF80DF81DF82DF83E5E3DF84DF85E5E5DF86DF87DF88DF89DF8AD2D8DF8BB5CBDF8CE7DFDF8DDAF5DF8EDAF8DF8FDAF6DF90DAF7DF91DF92DF93DAFAD0CFC4C7DF94DF95B0EEDF96DF97DF98D0B0DF99DAF9DF9AD3CABAAADBA2C7F1DF9BDAFCDAFBC9DBDAFDDF9CDBA1D7DEDAFEC1DADF9DDF9EDBA5DF9FDFA0D3F4E040E041DBA7DBA4E042DBA8E043E044BDBCE045E046E047C0C9DBA3DBA6D6A3E048DBA9E049E04AE04BDBADE04CE04DE04EDBAEDBACBAC2E04FE050E051BFA4DBABE052E053E054DBAAD4C7B2BFE055E056DBAFE057B9F9E058DBB0E059E05AE05BE05CB3BBE05DE05EE05FB5A6E060E061E062E063B6BCDBB1E064E065E066B6F5E067DBB2E068E069E06AE06BE06CE06DE06EE06FE070E071E072E073E074E075E076E077E078E079E07AE07BB1C9E07CE07DE07EE080DBB4E081E082E083DBB3DBB5E084E085E086E087E088E089E08AE08BE08CE08DE08EDBB7E08FDBB6E090E091E092E093E094E095E096DBB8E097E098E099E09AE09BE09CE09DE09EE09FDBB9E0A0E140DBBAE141E142D3CFF4FAC7F5D7C3C5E4F4FCF4FDF4FBE143BEC6E144E145E146E147D0EFE148E149B7D3E14AE14BD4CDCCAAE14CE14DF5A2F5A1BAA8F4FECBD6E14EE14FE150F5A4C0D2E151B3EAE152CDAAF5A5F5A3BDB4F5A8E153F5A9BDCDC3B8BFE1CBE1F5AAE154E155E156F5A6F5A7C4F0E157E158E159E15AE15BF5ACE15CB4BCE15DD7EDE15EB4D7F5ABF5AEE15FE160F5ADF5AFD0D1E161E162E163E164E165E166E167C3D1C8A9E168E169E16AE16BE16CE16DF5B0F5B1E16EE16FE170E171E172E173F5B2E174E175F5B3F5B4F5B5E176E177E178E179F5B7F5B6E17AE17BE17CE17DF5B8E17EE180E181E182E183E184E185E186E187E188E189E18AB2C9E18BD3D4CACDE18CC0EFD6D8D2B0C1BFE18DBDF0E18EE18FE190E191E192E193E194E195E196E197B8AAE198E199E19AE19BE19CE19DE19EE19FE1A0E240E241E242E243E244E245E246E247E248E249E24AE24BE24CE24DE24EE24FE250E251E252E253E254E255E256E257E258E259E25AE25BE25CE25DE25EE25FE260E261E262E263E264E265E266E267E268E269E26AE26BE26CE26DE26EE26FE270E271E272E273E274E275E276E277E278E279E27AE27BE27CE27DE27EE280E281E282E283E284E285E286E287E288E289E28AE28BE28CE28DE28EE28FE290E291E292E293E294E295E296E297E298E299E29AE29BE29CE29DE29EE29FE2A0E340E341E342E343E344E345E346E347E348E349E34AE34BE34CE34DE34EE34FE350E351E352E353E354E355E356E357E358E359E35AE35BE35CE35DE35EE35FE360E361E362E363E364E365E366E367E368E369E36AE36BE36CE36DBCF8E36EE36FE370E371E372E373E374E375E376E377E378E379E37AE37BE37CE37DE37EE380E381E382E383E384E385E386E387F6C6E388E389E38AE38BE38CE38DE38EE38FE390E391E392E393E394E395E396E397E398E399E39AE39BE39CE39DE39EE39FE3A0E440E441E442E443E444E445F6C7E446E447E448E449E44AE44BE44CE44DE44EE44FE450E451E452E453E454E455E456E457E458E459E45AE45BE45CE45DE45EF6C8E45FE460E461E462E463E464E465E466E467E468E469E46AE46BE46CE46DE46EE46FE470E471E472E473E474E475E476E477E478E479E47AE47BE47CE47DE47EE480E481E482E483E484E485E486E487E488E489E48AE48BE48CE48DE48EE48FE490E491E492E493E494E495E496E497E498E499E49AE49BE49CE49DE49EE49FE4A0E540E541E542E543E544E545E546E547E548E549E54AE54BE54CE54DE54EE54FE550E551E552E553E554E555E556E557E558E559E55AE55BE55CE55DE55EE55FE560E561E562E563E564E565E566E567E568E569E56AE56BE56CE56DE56EE56FE570E571E572E573F6C9E574E575E576E577E578E579E57AE57BE57CE57DE57EE580E581E582E583E584E585E586E587E588E589E58AE58BE58CE58DE58EE58FE590E591E592E593E594E595E596E597E598E599E59AE59BE59CE59DE59EE59FF6CAE5A0E640E641E642E643E644E645E646E647E648E649E64AE64BE64CE64DE64EE64FE650E651E652E653E654E655E656E657E658E659E65AE65BE65CE65DE65EE65FE660E661E662F6CCE663E664E665E666E667E668E669E66AE66BE66CE66DE66EE66FE670E671E672E673E674E675E676E677E678E679E67AE67BE67CE67DE67EE680E681E682E683E684E685E686E687E688E689E68AE68BE68CE68DE68EE68FE690E691E692E693E694E695E696E697E698E699E69AE69BE69CE69DF6CBE69EE69FE6A0E740E741E742E743E744E745E746E747F7E9E748E749E74AE74BE74CE74DE74EE74FE750E751E752E753E754E755E756E757E758E759E75AE75BE75CE75DE75EE75FE760E761E762E763E764E765E766E767E768E769E76AE76BE76CE76DE76EE76FE770E771E772E773E774E775E776E777E778E779E77AE77BE77CE77DE77EE780E781E782E783E784E785E786E787E788E789E78AE78BE78CE78DE78EE78FE790E791E792E793E794E795E796E797E798E799E79AE79BE79CE79DE79EE79FE7A0E840E841E842E843E844E845E846E847E848E849E84AE84BE84CE84DE84EF6CDE84FE850E851E852E853E854E855E856E857E858E859E85AE85BE85CE85DE85EE85FE860E861E862E863E864E865E866E867E868E869E86AE86BE86CE86DE86EE86FE870E871E872E873E874E875E876E877E878E879E87AF6CEE87BE87CE87DE87EE880E881E882E883E884E885E886E887E888E889E88AE88BE88CE88DE88EE88FE890E891E892E893E894EEC4EEC5EEC6D5EBB6A4EEC8EEC7EEC9EECAC7A5EECBEECCE895B7B0B5F6EECDEECFE896EECEE897B8C6EED0EED1EED2B6DBB3AED6D3C4C6B1B5B8D6EED3EED4D4BFC7D5BEFBCED9B9B3EED6EED5EED8EED7C5A5EED9EEDAC7AEEEDBC7AFEEDCB2A7EEDDEEDEEEDFEEE0EEE1D7EAEEE2EEE3BCD8EEE4D3CBCCFAB2ACC1E5EEE5C7A6C3ADE898EEE6EEE7EEE8EEE9EEEAEEEBEEECE899EEEDEEEEEEEFE89AE89BEEF0EEF1EEF2EEF4EEF3E89CEEF5CDADC2C1EEF6EEF7EEF8D5A1EEF9CFB3EEFAEEFBE89DEEFCEEFDEFA1EEFEEFA2B8F5C3FAEFA3EFA4BDC2D2BFB2F9EFA5EFA6EFA7D2F8EFA8D6FDEFA9C6CCE89EEFAAEFABC1B4EFACCFFACBF8EFAEEFADB3FAB9F8EFAFEFB0D0E2EFB1EFB2B7E6D0BFEFB3EFB4EFB5C8F1CCE0EFB6EFB7EFB8EFB9EFBAD5E0EFBBB4EDC3AAEFBCE89FEFBDEFBEEFBFE8A0CEFDEFC0C2E0B4B8D7B6BDF5E940CFC7EFC3EFC1EFC2EFC4B6A7BCFCBEE2C3CCEFC5EFC6E941EFC7EFCFEFC8EFC9EFCAC7C2EFF1B6CDEFCBE942EFCCEFCDB6C6C3BEEFCEE943EFD0EFD1EFD2D5F2E944EFD3C4F7E945EFD4C4F8EFD5EFD6B8E4B0F7EFD7EFD8EFD9E946EFDAEFDBEFDCEFDDE947EFDEBEB5EFE1EFDFEFE0E948EFE2EFE3C1CDEFE4EFE5EFE6EFE7EFE8EFE9EFEAEFEBEFECC0D8E949EFEDC1ADEFEEEFEFEFF0E94AE94BCFE2E94CE94DE94EE94FE950E951E952E953B3A4E954E955E956E957E958E959E95AE95BE95CE95DE95EE95FE960E961E962E963E964E965E966E967E968E969E96AE96BE96CE96DE96EE96FE970E971E972E973E974E975E976E977E978E979E97AE97BE97CE97DE97EE980E981E982E983E984E985E986E987E988E989E98AE98BE98CE98DE98EE98FE990E991E992E993E994E995E996E997E998E999E99AE99BE99CE99DE99EE99FE9A0EA40EA41EA42EA43EA44EA45EA46EA47EA48EA49EA4AEA4BEA4CEA4DEA4EEA4FEA50EA51EA52EA53EA54EA55EA56EA57EA58EA59EA5AEA5BC3C5E3C5C9C1E3C6EA5CB1D5CECAB4B3C8F2E3C7CFD0E3C8BCE4E3C9E3CAC3C6D5A2C4D6B9EBCEC5E3CBC3F6E3CCEA5DB7A7B8F3BAD2E3CDE3CED4C4E3CFEA5EE3D0D1CBE3D1E3D2E3D3E3D4D1D6E3D5B2FBC0BBE3D6EA5FC0ABE3D7E3D8E3D9EA60E3DAE3DBEA61B8B7DAE2EA62B6D3EA63DAE4DAE3EA64EA65EA66EA67EA68EA69EA6ADAE6EA6BEA6CEA6DC8EEEA6EEA6FDAE5B7C0D1F4D2F5D5F3BDD7EA70EA71EA72EA73D7E8DAE8DAE7EA74B0A2CDD3EA75DAE9EA76B8BDBCCAC2BDC2A4B3C2DAEAEA77C2AAC4B0BDB5EA78EA79CFDEEA7AEA7BEA7CDAEBC9C2EA7DEA7EEA80EA81EA82B1DDEA83EA84EA85DAECEA86B6B8D4BAEA87B3FDEA88EA89DAEDD4C9CFD5C5E3EA8ADAEEEA8BEA8CEA8DEA8EEA8FDAEFEA90DAF0C1EACCD5CFDDEA91EA92EA93EA94EA95EA96EA97EA98EA99EA9AEA9BEA9CEA9DD3E7C2A1EA9EDAF1EA9FEAA0CBE5EB40DAF2EB41CBE6D2FEEB42EB43EB44B8F4EB45EB46DAF3B0AFCFB6EB47EB48D5CFEB49EB4AEB4BEB4CEB4DEB4EEB4FEB50EB51EB52CBEDEB53EB54EB55EB56EB57EB58EB59EB5ADAF4EB5BEB5CE3C4EB5DEB5EC1A5EB5FEB60F6BFEB61EB62F6C0F6C1C4D1EB63C8B8D1E3EB64EB65D0DBD1C5BCAFB9CDEB66EFF4EB67EB68B4C6D3BAF6C2B3FBEB69EB6AF6C3EB6BEB6CB5F1EB6DEB6EEB6FEB70EB71EB72EB73EB74EB75EB76F6C5EB77EB78EB79EB7AEB7BEB7CEB7DD3EAF6A7D1A9EB7EEB80EB81EB82F6A9EB83EB84EB85F6A8EB86EB87C1E3C0D7EB88B1A2EB89EB8AEB8BEB8CCEEDEB8DD0E8F6ABEB8EEB8FCFF6EB90F6AAD5F0F6ACC3B9EB91EB92EB93BBF4F6AEF6ADEB94EB95EB96C4DEEB97EB98C1D8EB99EB9AEB9BEB9CEB9DCBAAEB9ECFBCEB9FEBA0EC40EC41EC42EC43EC44EC45EC46EC47EC48F6AFEC49EC4AF6B0EC4BEC4CF6B1EC4DC2B6EC4EEC4FEC50EC51EC52B0D4C5F9EC53EC54EC55EC56F6B2EC57EC58EC59EC5AEC5BEC5CEC5DEC5EEC5FEC60EC61EC62EC63EC64EC65EC66EC67EC68EC69C7E0F6A6EC6AEC6BBEB8EC6CEC6DBEB2EC6EB5E5EC6FEC70B7C7EC71BFBFC3D2C3E6EC72EC73D8CCEC74EC75EC76B8EFEC77EC78EC79EC7AEC7BEC7CEC7DEC7EEC80BDF9D1A5EC81B0D0EC82EC83EC84EC85EC86F7B0EC87EC88EC89EC8AEC8BEC8CEC8DEC8EF7B1EC8FEC90EC91EC92EC93D0ACEC94B0B0EC95EC96EC97F7B2F7B3EC98F7B4EC99EC9AEC9BC7CAEC9CEC9DEC9EEC9FECA0ED40ED41BECFED42ED43F7B7ED44ED45ED46ED47ED48ED49ED4AF7B6ED4BB1DEED4CF7B5ED4DED4EF7B8ED4FF7B9ED50ED51ED52ED53ED54ED55ED56ED57ED58ED59ED5AED5BED5CED5DED5EED5FED60ED61ED62ED63ED64ED65ED66ED67ED68ED69ED6AED6BED6CED6DED6EED6FED70ED71ED72ED73ED74ED75ED76ED77ED78ED79ED7AED7BED7CED7DED7EED80ED81CEA4C8CDED82BAABE8B8E8B9E8BABEC2ED83ED84ED85ED86ED87D2F4ED88D4CFC9D8ED89ED8AED8BED8CED8DED8EED8FED90ED91ED92ED93ED94ED95ED96ED97ED98ED99ED9AED9BED9CED9DED9EED9FEDA0EE40EE41EE42EE43EE44EE45EE46EE47EE48EE49EE4AEE4BEE4CEE4DEE4EEE4FEE50EE51EE52EE53EE54EE55EE56EE57EE58EE59EE5AEE5BEE5CEE5DEE5EEE5FEE60EE61EE62EE63EE64EE65EE66EE67EE68EE69EE6AEE6BEE6CEE6DEE6EEE6FEE70EE71EE72EE73EE74EE75EE76EE77EE78EE79EE7AEE7BEE7CEE7DEE7EEE80EE81EE82EE83EE84EE85EE86EE87EE88EE89EE8AEE8BEE8CEE8DEE8EEE8FEE90EE91EE92EE93EE94EE95EE96EE97EE98EE99EE9AEE9BEE9CEE9DEE9EEE9FEEA0EF40EF41EF42EF43EF44EF45D2B3B6A5C7EAF1FCCFEECBB3D0EBE7EFCDE7B9CBB6D9F1FDB0E4CBCCF1FED4A4C2ADC1ECC6C4BEB1F2A1BCD5EF46F2A2F2A3EF47F2A4D2C3C6B5EF48CDC7F2A5EF49D3B1BFC5CCE2EF4AF2A6F2A7D1D5B6EEF2A8F2A9B5DFF2AAF2ABEF4BB2FCF2ACF2ADC8A7EF4CEF4DEF4EEF4FEF50EF51EF52EF53EF54EF55EF56EF57EF58EF59EF5AEF5BEF5CEF5DEF5EEF5FEF60EF61EF62EF63EF64EF65EF66EF67EF68EF69EF6AEF6BEF6CEF6DEF6EEF6FEF70EF71B7E7EF72EF73ECA9ECAAECABEF74ECACEF75EF76C6AEECADECAEEF77EF78EF79B7C9CAB3EF7AEF7BEF7CEF7DEF7EEF80EF81E2B8F7CFEF82EF83EF84EF85EF86EF87EF88EF89EF8AEF8BEF8CEF8DEF8EEF8FEF90EF91EF92EF93EF94EF95EF96EF97EF98EF99EF9AEF9BEF9CEF9DEF9EEF9FEFA0F040F041F042F043F044F7D0F045F046B2CDF047F048F049F04AF04BF04CF04DF04EF04FF050F051F052F053F054F055F056F057F058F059F05AF05BF05CF05DF05EF05FF060F061F062F063F7D1F064F065F066F067F068F069F06AF06BF06CF06DF06EF06FF070F071F072F073F074F075F076F077F078F079F07AF07BF07CF07DF07EF080F081F082F083F084F085F086F087F088F089F7D3F7D2F08AF08BF08CF08DF08EF08FF090F091F092F093F094F095F096E2BBF097BCA2F098E2BCE2BDE2BEE2BFE2C0E2C1B7B9D2FBBDA4CACEB1A5CBC7F099E2C2B6FCC8C4E2C3F09AF09BBDC8F09CB1FDE2C4F09DB6F6E2C5C4D9F09EF09FE2C6CFDAB9DDE2C7C0A1F0A0E2C8B2F6F140E2C9F141C1F3E2CAE2CBC2F8E2CCE2CDE2CECAD7D8B8D9E5CFE3F142F143F144F145F146F147F148F149F14AF14BF14CF0A5F14DF14EDCB0F14FF150F151F152F153F154F155F156F157F158F159F15AF15BF15CF15DF15EF15FF160F161F162F163F164F165F166F167F168F169F16AF16BF16CF16DF16EF16FF170F171F172F173F174F175F176F177F178F179F17AF17BF17CF17DF17EF180F181F182F183F184F185F186F187F188F189F18AF18BF18CF18DF18EF18FF190F191F192F193F194F195F196F197F198F199F19AF19BF19CF19DF19EF19FF1A0F240F241F242F243F244F245F246F247F248F249F24AF24BF24CF24DF24EF24FF250F251F252F253F254F255F256F257F258F259F25AF25BF25CF25DF25EF25FF260F261F262F263F264F265F266F267F268F269F26AF26BF26CF26DF26EF26FF270F271F272F273F274F275F276F277F278F279F27AF27BF27CF27DF27EF280F281F282F283F284F285F286F287F288F289F28AF28BF28CF28DF28EF28FF290F291F292F293F294F295F296F297F298F299F29AF29BF29CF29DF29EF29FF2A0F340F341F342F343F344F345F346F347F348F349F34AF34BF34CF34DF34EF34FF350F351C2EDD4A6CDD4D1B1B3DBC7FDF352B2B5C2BFE6E0CABBE6E1E6E2BED4E6E3D7A4CDD5E6E5BCDDE6E4E6E6E6E7C2EEF353BDBEE6E8C2E6BAA7E6E9F354E6EAB3D2D1E9F355F356BFA5E6EBC6EFE6ECE6EDF357F358E6EEC6ADE6EFF359C9A7E6F0E6F1E6F2E5B9E6F3E6F4C2E2E6F5E6F6D6E8E6F7F35AE6F8B9C7F35BF35CF35DF35EF35FF360F361F7BBF7BAF362F363F364F365F7BEF7BCBAA1F366F7BFF367F7C0F368F369F36AF7C2F7C1F7C4F36BF36CF7C3F36DF36EF36FF370F371F7C5F7C6F372F373F374F375F7C7F376CBE8F377F378F379F37AB8DFF37BF37CF37DF37EF380F381F7D4F382F7D5F383F384F385F386F7D6F387F388F389F38AF7D8F38BF7DAF38CF7D7F38DF38EF38FF390F391F392F393F394F395F7DBF396F7D9F397F398F399F39AF39BF39CF39DD7D7F39EF39FF3A0F440F7DCF441F442F443F444F445F446F7DDF447F448F449F7DEF44AF44BF44CF44DF44EF44FF450F451F452F453F454F7DFF455F456F457F7E0F458F459F45AF45BF45CF45DF45EF45FF460F461F462DBCBF463F464D8AAF465F466F467F468F469F46AF46BF46CE5F7B9EDF46DF46EF46FF470BFFDBBEAF7C9C6C7F7C8F471F7CAF7CCF7CBF472F473F474F7CDF475CEBAF476F7CEF477F478C4A7F479F47AF47BF47CF47DF47EF480F481F482F483F484F485F486F487F488F489F48AF48BF48CF48DF48EF48FF490F491F492F493F494F495F496F497F498F499F49AF49BF49CF49DF49EF49FF4A0F540F541F542F543F544F545F546F547F548F549F54AF54BF54CF54DF54EF54FF550F551F552F553F554F555F556F557F558F559F55AF55BF55CF55DF55EF55FF560F561F562F563F564F565F566F567F568F569F56AF56BF56CF56DF56EF56FF570F571F572F573F574F575F576F577F578F579F57AF57BF57CF57DF57EF580F581F582F583F584F585F586F587F588F589F58AF58BF58CF58DF58EF58FF590F591F592F593F594F595F596F597F598F599F59AF59BF59CF59DF59EF59FF5A0F640F641F642F643F644F645F646F647F648F649F64AF64BF64CF64DF64EF64FF650F651F652F653F654F655F656F657F658F659F65AF65BF65CF65DF65EF65FF660F661F662F663F664F665F666F667F668F669F66AF66BF66CF66DF66EF66FF670F671F672F673F674F675F676F677F678F679F67AF67BF67CF67DF67EF680F681F682F683F684F685F686F687F688F689F68AF68BF68CF68DF68EF68FF690F691F692F693F694F695F696F697F698F699F69AF69BF69CF69DF69EF69FF6A0F740F741F742F743F744F745F746F747F748F749F74AF74BF74CF74DF74EF74FF750F751F752F753F754F755F756F757F758F759F75AF75BF75CF75DF75EF75FF760F761F762F763F764F765F766F767F768F769F76AF76BF76CF76DF76EF76FF770F771F772F773F774F775F776F777F778F779F77AF77BF77CF77DF77EF780D3E3F781F782F6CFF783C2B3F6D0F784F785F6D1F6D2F6D3F6D4F786F787F6D6F788B1ABF6D7F789F6D8F6D9F6DAF78AF6DBF6DCF78BF78CF78DF78EF6DDF6DECFCAF78FF6DFF6E0F6E1F6E2F6E3F6E4C0F0F6E5F6E6F6E7F6E8F6E9F790F6EAF791F6EBF6ECF792F6EDF6EEF6EFF6F0F6F1F6F2F6F3F6F4BEA8F793F6F5F6F6F6F7F6F8F794F795F796F797F798C8FAF6F9F6FAF6FBF6FCF799F79AF6FDF6FEF7A1F7A2F7A3F7A4F7A5F79BF79CF7A6F7A7F7A8B1EEF7A9F7AAF7ABF79DF79EF7ACF7ADC1DBF7AEF79FF7A0F7AFF840F841F842F843F844F845F846F847F848F849F84AF84BF84CF84DF84EF84FF850F851F852F853F854F855F856F857F858F859F85AF85BF85CF85DF85EF85FF860F861F862F863F864F865F866F867F868F869F86AF86BF86CF86DF86EF86FF870F871F872F873F874F875F876F877F878F879F87AF87BF87CF87DF87EF880F881F882F883F884F885F886F887F888F889F88AF88BF88CF88DF88EF88FF890F891F892F893F894F895F896F897F898F899F89AF89BF89CF89DF89EF89FF8A0F940F941F942F943F944F945F946F947F948F949F94AF94BF94CF94DF94EF94FF950F951F952F953F954F955F956F957F958F959F95AF95BF95CF95DF95EF95FF960F961F962F963F964F965F966F967F968F969F96AF96BF96CF96DF96EF96FF970F971F972F973F974F975F976F977F978F979F97AF97BF97CF97DF97EF980F981F982F983F984F985F986F987F988F989F98AF98BF98CF98DF98EF98FF990F991F992F993F994F995F996F997F998F999F99AF99BF99CF99DF99EF99FF9A0FA40FA41FA42FA43FA44FA45FA46FA47FA48FA49FA4AFA4BFA4CFA4DFA4EFA4FFA50FA51FA52FA53FA54FA55FA56FA57FA58FA59FA5AFA5BFA5CFA5DFA5EFA5FFA60FA61FA62FA63FA64FA65FA66FA67FA68FA69FA6AFA6BFA6CFA6DFA6EFA6FFA70FA71FA72FA73FA74FA75FA76FA77FA78FA79FA7AFA7BFA7CFA7DFA7EFA80FA81FA82FA83FA84FA85FA86FA87FA88FA89FA8AFA8BFA8CFA8DFA8EFA8FFA90FA91FA92FA93FA94FA95FA96FA97FA98FA99FA9AFA9BFA9CFA9DFA9EFA9FFAA0FB40FB41FB42FB43FB44FB45FB46FB47FB48FB49FB4AFB4BFB4CFB4DFB4EFB4FFB50FB51FB52FB53FB54FB55FB56FB57FB58FB59FB5AFB5BC4F1F0AFBCA6F0B0C3F9FB5CC5B8D1BBFB5DF0B1F0B2F0B3F0B4F0B5D1BCFB5ED1ECFB5FF0B7F0B6D4A7FB60CDD2F0B8F0BAF0B9F0BBF0BCFB61FB62B8EBF0BDBAE8FB63F0BEF0BFBEE9F0C0B6ECF0C1F0C2F0C3F0C4C8B5F0C5F0C6FB64F0C7C5F4FB65F0C8FB66FB67FB68F0C9FB69F0CAF7BDFB6AF0CBF0CCF0CDFB6BF0CEFB6CFB6DFB6EFB6FF0CFBAD7FB70F0D0F0D1F0D2F0D3F0D4F0D5F0D6F0D8FB71FB72D3A5F0D7FB73F0D9FB74FB75FB76FB77FB78FB79FB7AFB7BFB7CFB7DF5BAC2B9FB7EFB80F7E4FB81FB82FB83FB84F7E5F7E6FB85FB86F7E7FB87FB88FB89FB8AFB8BFB8CF7E8C2B4FB8DFB8EFB8FFB90FB91FB92FB93FB94FB95F7EAFB96F7EBFB97FB98FB99FB9AFB9BFB9CC2F3FB9DFB9EFB9FFBA0FC40FC41FC42FC43FC44FC45FC46FC47FC48F4F0FC49FC4AFC4BF4EFFC4CFC4DC2E9FC4EF7E1F7E2FC4FFC50FC51FC52FC53BBC6FC54FC55FC56FC57D9E4FC58FC59FC5ACAF2C0E8F0A4FC5BBADAFC5CFC5DC7ADFC5EFC5FFC60C4ACFC61FC62F7ECF7EDF7EEFC63F7F0F7EFFC64F7F1FC65FC66F7F4FC67F7F3FC68F7F2F7F5FC69FC6AFC6BFC6CF7F6FC6DFC6EFC6FFC70FC71FC72FC73FC74FC75EDE9FC76EDEAEDEBFC77F6BCFC78FC79FC7AFC7BFC7CFC7DFC7EFC80FC81FC82FC83FC84F6BDFC85F6BEB6A6FC86D8BEFC87FC88B9C4FC89FC8AFC8BD8BBFC8CDCB1FC8DFC8EFC8FFC90FC91FC92CAF3FC93F7F7FC94FC95FC96FC97FC98FC99FC9AFC9BFC9CF7F8FC9DFC9EF7F9FC9FFCA0FD40FD41FD42FD43FD44F7FBFD45F7FAFD46B1C7FD47F7FCF7FDFD48FD49FD4AFD4BFD4CF7FEFD4DFD4EFD4FFD50FD51FD52FD53FD54FD55FD56FD57C6EBECB4FD58FD59FD5AFD5BFD5CFD5DFD5EFD5FFD60FD61FD62FD63FD64FD65FD66FD67FD68FD69FD6AFD6BFD6CFD6DFD6EFD6FFD70FD71FD72FD73FD74FD75FD76FD77FD78FD79FD7AFD7BFD7CFD7DFD7EFD80FD81FD82FD83FD84FD85B3DDF6B3FD86FD87F6B4C1E4F6B5F6B6F6B7F6B8F6B9F6BAC8A3F6BBFD88FD89FD8AFD8BFD8CFD8DFD8EFD8FFD90FD91FD92FD93C1FAB9A8EDE8FD94FD95FD96B9EAD9DFFD97FD98FD99FD9AFD9';\r\n\r\n            for (var i = 0; i < str.length; i++) {\r\n                var c = str.charAt(i),\r\n                    code = str.charCodeAt(i);\r\n                if (c == \" \") strOut += \"+\";\r\n                else if (code >= 19968 && code <= 40869) {\r\n                    var index = code - 19968;\r\n                    strOut += \"%\" + z.substr(index * 4, 2) + \"%\" + z.substr(index * 4 + 2, 2);\r\n                } else {\r\n                    strOut += \"%\" + str.charCodeAt(i).toString(16);\r\n                }\r\n            }\r\n            return strOut;\r\n        },\r\n        /* 改变图片大小 */\r\n        scale: function (img, w, h) {\r\n            var ow = img.width,\r\n                oh = img.height;\r\n\r\n            if (ow >= oh) {\r\n                img.width = w * ow / oh;\r\n                img.height = h;\r\n                img.style.marginLeft = '-' + parseInt((img.width - w) / 2) + 'px';\r\n            } else {\r\n                img.width = w;\r\n                img.height = h * oh / ow;\r\n                img.style.marginTop = '-' + parseInt((img.height - h) / 2) + 'px';\r\n            }\r\n        },\r\n        getImageData: function(){\r\n            var _this = this,\r\n                key = $G('searchTxt').value,\r\n                type = $G('searchType').value,\r\n                keepOriginName = editor.options.keepOriginName ? \"1\" : \"0\",\r\n                url = \"http://image.baidu.com/i?ct=201326592&cl=2&lm=-1&st=-1&tn=baiduimagejson&istype=2&rn=32&fm=index&pv=&word=\" + _this.encodeToGb2312(key) + type + \"&keeporiginname=\" + keepOriginName + \"&\" + +new Date;\r\n\r\n            $G('searchListUl').innerHTML = lang.searchLoading;\r\n            ajax.request(url, {\r\n                'dataType': 'jsonp',\r\n                'charset': 'GB18030',\r\n                'onsuccess':function(json){\r\n                    var list = [];\r\n                    if(json && json.data) {\r\n                        for(var i = 0; i < json.data.length; i++) {\r\n                            if(json.data[i].objURL) {\r\n                                list.push({\r\n                                    title: json.data[i].fromPageTitleEnc,\r\n                                    src: json.data[i].objURL,\r\n                                    url: json.data[i].fromURL\r\n                                });\r\n                            }\r\n                        }\r\n                    }\r\n                    _this.setList(list);\r\n                },\r\n                'onerror':function(){\r\n                    $G('searchListUl').innerHTML = lang.searchRetry;\r\n                }\r\n            });\r\n        },\r\n        /* 添加图片到列表界面上 */\r\n        setList: function (list) {\r\n            var i, item, p, img, link, _this = this,\r\n                listUl = $G('searchListUl');\r\n\r\n            listUl.innerHTML = '';\r\n            if(list.length) {\r\n                for (i = 0; i < list.length; i++) {\r\n                    item = document.createElement('li');\r\n                    p = document.createElement('p');\r\n                    img = document.createElement('img');\r\n                    link = document.createElement('a');\r\n\r\n                    img.onload = function () {\r\n                        _this.scale(this, 113, 113);\r\n                    };\r\n                    img.width = 113;\r\n                    img.setAttribute('src', list[i].src);\r\n\r\n                    link.href = list[i].url;\r\n                    link.target = '_blank';\r\n                    link.title = list[i].title;\r\n                    link.innerHTML = list[i].title;\r\n\r\n                    p.appendChild(img);\r\n                    item.appendChild(p);\r\n                    item.appendChild(link);\r\n                    listUl.appendChild(item);\r\n                }\r\n            } else {\r\n                listUl.innerHTML = lang.searchRetry;\r\n            }\r\n        },\r\n        getInsertList: function () {\r\n            var child,\r\n                src,\r\n                align = getAlign(),\r\n                list = [],\r\n                items = $G('searchListUl').children;\r\n            for(var i = 0; i < items.length; i++) {\r\n                child = items[i].firstChild && items[i].firstChild.firstChild;\r\n                if(child.tagName && child.tagName.toLowerCase() == 'img' && domUtils.hasClass(items[i], 'selected')) {\r\n                    src = child.src;\r\n                    list.push({\r\n                        src: src,\r\n                        _src: src,\r\n                        alt: src.substr(src.lastIndexOf('/') + 1),\r\n                        floatStyle: align\r\n                    });\r\n                }\r\n            }\r\n            return list;\r\n        }\r\n    };\r\n\r\n})();\r\n"
  },
  {
    "path": "public/static/ueditor/dialogs/insertframe/insertframe.html",
    "content": "<!DOCTYPE html>\r\n<html>\r\n<head>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\r\n    <title></title>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <style type=\"text/css\">\r\n        .warp {width: 320px;height: 153px;margin-left:5px;padding: 20px 0 0 15px;position: relative;}\r\n        #url {width: 290px; margin-bottom: 2px; margin-left: -6px; margin-left: -2px\\9;*margin-left:0;_margin-left:0; }\r\n        .format span{display: inline-block; width: 58px;text-align: center; zoom:1;}\r\n        table td{padding:5px 0;}\r\n        #align{width: 65px;height: 23px;line-height: 22px;}\r\n    </style>\r\n</head>\r\n<body>\r\n<div class=\"warp\">\r\n        <table width=\"300\" cellpadding=\"0\" cellspacing=\"0\">\r\n            <tr>\r\n                <td colspan=\"2\" class=\"format\">\r\n                    <span><var id=\"lang_input_address\"></var></span>\r\n                    <input style=\"width:200px\" id=\"url\" type=\"text\" value=\"\"/>\r\n                </td>\r\n            </tr>\r\n            <tr>\r\n                <td colspan=\"2\" class=\"format\"><span><var id=\"lang_input_width\"></var></span><input style=\"width:200px\" type=\"text\" id=\"width\"/> px</td>\r\n\r\n            </tr>\r\n            <tr>\r\n                <td colspan=\"2\" class=\"format\"><span><var id=\"lang_input_height\"></var></span><input style=\"width:200px\" type=\"text\" id=\"height\"/> px</td>\r\n            </tr>\r\n            <tr>\r\n                <td><span><var id=\"lang_input_isScroll\"></var></span><input type=\"checkbox\" id=\"scroll\"/> </td>\r\n                <td><span><var id=\"lang_input_frameborder\"></var></span><input type=\"checkbox\" id=\"frameborder\"/> </td>\r\n            </tr>\r\n\r\n            <tr>\r\n                <td colspan=\"2\"><span><var id=\"lang_input_alignMode\"></var></span>\r\n                    <select id=\"align\">\r\n                        <option value=\"\"></option>\r\n                        <option value=\"left\"></option>\r\n                        <option value=\"right\"></option>\r\n                    </select>\r\n                </td>\r\n            </tr>\r\n        </table>\r\n</div>\r\n<script type=\"text/javascript\">\r\n    var iframe = editor._iframe;\r\n    if(iframe){\r\n        $G(\"url\").value = iframe.getAttribute(\"src\")||\"\";\r\n        $G(\"width\").value = iframe.getAttribute(\"width\")||iframe.style.width.replace(\"px\",\"\")||\"\";\r\n        $G(\"height\").value = iframe.getAttribute(\"height\") || iframe.style.height.replace(\"px\",\"\") ||\"\";\r\n        $G(\"scroll\").checked = (iframe.getAttribute(\"scrolling\") == \"yes\") ? true : false;\r\n        $G(\"frameborder\").checked = (iframe.getAttribute(\"frameborder\") == \"1\") ? true : false;\r\n        $G(\"align\").value = iframe.align ? iframe.align : \"\";\r\n    }\r\n    function queding(){\r\n        var  url = $G(\"url\").value.replace(/^\\s*|\\s*$/ig,\"\"),\r\n                width = $G(\"width\").value,\r\n                height = $G(\"height\").value,\r\n                scroll = $G(\"scroll\"),\r\n                frameborder = $G(\"frameborder\"),\r\n                float = $G(\"align\").value,\r\n                newIframe = editor.document.createElement(\"iframe\"),\r\n                div;\r\n        if(!url){\r\n            alert(lang.enterAddress);\r\n            return false;\r\n        }\r\n        newIframe.setAttribute(\"src\",/http:\\/\\/|https:\\/\\//ig.test(url) ? url : \"http://\"+url);\r\n        /^[1-9]+[.]?\\d*$/g.test( width ) ? newIframe.setAttribute(\"width\",width) : \"\";\r\n        /^[1-9]+[.]?\\d*$/g.test( height ) ? newIframe.setAttribute(\"height\",height) : \"\";\r\n        scroll.checked ?  newIframe.setAttribute(\"scrolling\",\"yes\") : newIframe.setAttribute(\"scrolling\",\"no\");\r\n        frameborder.checked ?  newIframe.setAttribute(\"frameborder\",\"1\",0) : newIframe.setAttribute(\"frameborder\",\"0\",0);\r\n        float ? newIframe.setAttribute(\"align\",float) :  newIframe.setAttribute(\"align\",\"\");\r\n        if(iframe){\r\n            iframe.parentNode.insertBefore(newIframe,iframe);\r\n            domUtils.remove(iframe);\r\n        }else{\r\n            div = editor.document.createElement(\"div\");\r\n            div.appendChild(newIframe);\r\n            editor.execCommand(\"inserthtml\",div.innerHTML);\r\n        }\r\n        editor._iframe = null;\r\n        dialog.close();\r\n    }\r\n    dialog.onok = queding;\r\n    $G(\"url\").onkeydown = function(evt){\r\n        evt = evt || event;\r\n        if(evt.keyCode == 13){\r\n            queding();\r\n        }\r\n    };\r\n    $focus($G( \"url\" ));\r\n\r\n</script>\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/internal.js",
    "content": "(function () {\r\n    var parent = window.parent;\r\n    //dialog对象\r\n    dialog = parent.$EDITORUI[window.frameElement.id.replace( /_iframe$/, '' )];\r\n    //当前打开dialog的编辑器实例\r\n    editor = dialog.editor;\r\n\r\n    UE = parent.UE;\r\n\r\n    domUtils = UE.dom.domUtils;\r\n\r\n    utils = UE.utils;\r\n\r\n    browser = UE.browser;\r\n\r\n    ajax = UE.ajax;\r\n\r\n    $G = function ( id ) {\r\n        return document.getElementById( id )\r\n    };\r\n    //focus元素\r\n    $focus = function ( node ) {\r\n        setTimeout( function () {\r\n            if ( browser.ie ) {\r\n                var r = node.createTextRange();\r\n                r.collapse( false );\r\n                r.select();\r\n            } else {\r\n                node.focus()\r\n            }\r\n        }, 0 )\r\n    };\r\n    utils.loadFile(document,{\r\n        href:editor.options.themePath + editor.options.theme + \"/dialogbase.css?cache=\"+Math.random(),\r\n        tag:\"link\",\r\n        type:\"text/css\",\r\n        rel:\"stylesheet\"\r\n    });\r\n    lang = editor.getLang(dialog.className.split( \"-\" )[2]);\r\n    if(lang){\r\n        domUtils.on(window,'load',function () {\r\n\r\n            var langImgPath = editor.options.langPath + editor.options.lang + \"/images/\";\r\n            //针对静态资源\r\n            for ( var i in lang[\"static\"] ) {\r\n                var dom = $G( i );\r\n                if(!dom) continue;\r\n                var tagName = dom.tagName,\r\n                    content = lang[\"static\"][i];\r\n                if(content.src){\r\n                    //clone\r\n                    content = utils.extend({},content,false);\r\n                    content.src = langImgPath + content.src;\r\n                }\r\n                if(content.style){\r\n                    content = utils.extend({},content,false);\r\n                    content.style = content.style.replace(/url\\s*\\(/g,\"url(\" + langImgPath)\r\n                }\r\n                switch ( tagName.toLowerCase() ) {\r\n                    case \"var\":\r\n                        dom.parentNode.replaceChild( document.createTextNode( content ), dom );\r\n                        break;\r\n                    case \"select\":\r\n                        var ops = dom.options;\r\n                        for ( var j = 0, oj; oj = ops[j]; ) {\r\n                            oj.innerHTML = content.options[j++];\r\n                        }\r\n                        for ( var p in content ) {\r\n                            p != \"options\" && dom.setAttribute( p, content[p] );\r\n                        }\r\n                        break;\r\n                    default :\r\n                        domUtils.setAttributes( dom, content);\r\n                }\r\n            }\r\n        } );\r\n    }\r\n\r\n\r\n})();\r\n\r\n"
  },
  {
    "path": "public/static/ueditor/dialogs/link/link.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n        \"http://www.w3.org/TR/html4/loose.dtd\">\r\n<html>\r\n<head>\r\n    <title></title>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <style type=\"text/css\">\r\n        *{margin:0;padding:0;color: #838383;}\r\n        table{font-size: 12px;margin: 10px;line-height: 30px}\r\n        .txt{width:300px;height:21px;line-height:21px;border:1px solid #d7d7d7;}\r\n    </style>\r\n</head>\r\n<body>\r\n    <table>\r\n        <tr>\r\n            <td><label for=\"text\"> <var id=\"lang_input_text\"></var></label></td>\r\n            <td><input class=\"txt\" id=\"text\" type=\"text\" disabled=\"true\"/></td>\r\n        </tr>\r\n        <tr>\r\n            <td><label for=\"href\"> <var id=\"lang_input_url\"></var></label></td>\r\n            <td><input class=\"txt\" id=\"href\" type=\"text\" /></td>\r\n        </tr>\r\n        <tr>\r\n            <td><label for=\"title\"> <var id=\"lang_input_title\"></var></label></td>\r\n            <td><input class=\"txt\" id=\"title\" type=\"text\"/></td>\r\n        </tr>\r\n        <tr>\r\n             <td colspan=\"2\">\r\n                 <label for=\"target\"><var id=\"lang_input_target\"></var></label>\r\n                 <input id=\"target\" type=\"checkbox\"/>\r\n             </td>\r\n        </tr>\r\n        <tr>\r\n            <td colspan=\"2\" id=\"msg\"></td>\r\n        </tr>\r\n    </table>\r\n<script type=\"text/javascript\">\r\n    var range = editor.selection.getRange(),\r\n        link = range.collapsed ? editor.queryCommandValue( \"link\" ) : editor.selection.getStart(),\r\n        url,\r\n        text = $G('text'),\r\n        rangeLink = domUtils.findParentByTagName(range.getCommonAncestor(),'a',true),\r\n        orgText;\r\n    link = domUtils.findParentByTagName( link, \"a\", true );\r\n    if(link){\r\n        url = utils.html(link.getAttribute( '_href' ) || link.getAttribute( 'href', 2 ));\r\n\r\n        if(rangeLink === link && !link.getElementsByTagName('img').length){\r\n            text.removeAttribute('disabled');\r\n            orgText = text.value = link[browser.ie ? 'innerText':'textContent'];\r\n        }else{\r\n            text.setAttribute('disabled','true');\r\n            text.value = lang.validLink;\r\n        }\r\n\r\n    }else{\r\n        if(range.collapsed){\r\n            text.removeAttribute('disabled');\r\n            text.value = '';\r\n        }else{\r\n            text.setAttribute('disabled','true');\r\n            text.value = lang.validLink;\r\n        }\r\n\r\n    }\r\n    $G(\"title\").value = url ? link.title : \"\";\r\n    $G(\"href\").value = url ? url: '';\r\n    $G(\"target\").checked = url && link.target == \"_blank\" ? true :  false;\r\n    $focus($G(\"href\"));\r\n\r\n    function handleDialogOk(){\r\n        var href =$G('href').value.replace(/^\\s+|\\s+$/g, '');\r\n        if(href){\r\n            if(!hrefStartWith(href,[\"http\",\"/\",\"ftp://\",'#'])) {\r\n                href  = \"http://\" + href;\r\n            }\r\n            var obj = {\r\n                'href' : href,\r\n                'target' : $G(\"target\").checked ? \"_blank\" : '_self',\r\n                'title' : $G(\"title\").value.replace(/^\\s+|\\s+$/g, ''),\r\n                '_href':href\r\n            };\r\n            //修改链接内容的情况太特殊了，所以先做到这里了\r\n            //todo:情况多的时候，做到command里\r\n            if(orgText && text.value != orgText){\r\n                link[browser.ie ? 'innerText' : 'textContent'] =  obj.textValue = text.value;\r\n                range.selectNode(link).select()\r\n            }\r\n            if(range.collapsed){\r\n                obj.textValue = text.value;\r\n            }\r\n            editor.execCommand('link',utils.clearEmptyAttrs(obj) );\r\n            dialog.close();\r\n        }\r\n    }\r\n    dialog.onok = handleDialogOk;\r\n    $G('href').onkeydown = $G('title').onkeydown = function(evt){\r\n        evt = evt || window.event;\r\n        if (evt.keyCode == 13) {\r\n            handleDialogOk();\r\n            return false;\r\n        }\r\n    };\r\n    $G('href').onblur = function(){\r\n        if(!hrefStartWith(this.value,[\"http\",\"/\",\"ftp://\",'#'])){\r\n            $G(\"msg\").innerHTML = \"<span style='color: red'>\"+lang.httpPrompt+\"</span>\";\r\n        }else{\r\n            $G(\"msg\").innerHTML = \"\";\r\n        }\r\n    };\r\n\r\n    function hrefStartWith(href,arr){\r\n        href = href.replace(/^\\s+|\\s+$/g, '');\r\n        for(var i=0,ai;ai=arr[i++];){\r\n            if(href.indexOf(ai)==0){\r\n                return true;\r\n            }\r\n        }\r\n        return false;\r\n    }\r\n\r\n\r\n</script>\r\n</body>\r\n</html>\r\n"
  },
  {
    "path": "public/static/ueditor/dialogs/map/map.html",
    "content": "<!DOCTYPE html>\r\n<html>\r\n<head>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n    <title></title>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <script type=\"text/javascript\" src=\"http://api.map.baidu.com/api?v=1.1&services=true\"></script>\r\n    <style type=\"text/css\">\r\n        .content{width:530px; height: 350px;margin: 10px auto;}\r\n        .content table{width: 100%}\r\n        .content table td{vertical-align: middle;}\r\n        #city,#address{height:21px;background: #FFF;border:1px solid #d7d7d7; line-height: 21px;}\r\n        #city{width:60px}\r\n        #address{width:130px}\r\n        #is_dynamic_label span{vertical-align:middle;margin: 3px 0px 3px 3px;}\r\n        #is_dynamic_label input{vertical-align:middle;margin: 3px 3px 3px 50px;}\r\n    </style>\r\n</head>\r\n<body>\r\n<div class=\"content\">\r\n    <table>\r\n        <tr>\r\n            <td><var id=\"lang_city\"></var>:</td>\r\n            <td><input id=\"city\" type=\"text\" /></td>\r\n            <td><var id=\"lang_address\"></var>:</td>\r\n            <td><input id=\"address\" type=\"text\" value=\"\" /></td>\r\n            <td><a href=\"javascript:doSearch()\" class=\"button\"><var id=\"lang_search\"></var></a></td>\r\n            <td><label id=\"is_dynamic_label\" for=\"is_dynamic\"><input id=\"is_dynamic\" type=\"checkbox\" name=\"is_dynamic\" /><span><var id=\"lang_dynamicmap\"></var></span></label></td>\r\n        </tr>\r\n    </table>\r\n    <div style=\"width:100%;height:340px;margin:5px auto;border:1px solid gray\" id=\"container\"></div>\r\n\r\n</div>\r\n<script type=\"text/javascript\">\r\n    var map = new BMap.Map(\"container\"),marker,point,styleStr;\r\n    map.enableScrollWheelZoom();\r\n    map.enableContinuousZoom();\r\n    function doSearch(){\r\n        if (!document.getElementById('city').value) {\r\n            alert(lang.cityMsg);\r\n            return;\r\n        }\r\n        var search = new BMap.LocalSearch(document.getElementById('city').value, {\r\n            onSearchComplete: function (results){\r\n                if (results && results.getNumPois()) {\r\n                    var points = [];\r\n                    for (var i=0; i<results.getCurrentNumPois(); i++) {\r\n                        points.push(results.getPoi(i).point);\r\n                    }\r\n                    if (points.length > 1) {\r\n                        map.setViewport(points);\r\n                    } else {\r\n                        map.centerAndZoom(points[0], 13);\r\n                    }\r\n                    point = map.getCenter();\r\n                    marker.setPoint(point);\r\n                } else {\r\n                    alert(lang.errorMsg);\r\n                }\r\n            }\r\n        });\r\n        search.search(document.getElementById('address').value || document.getElementById('city').value);\r\n    }\r\n    //获得参数\r\n    function getPars(str,par){\r\n        var reg = new RegExp(par+\"=((\\\\d+|[.,])*)\",\"g\");\r\n        return reg.exec(str)[1];\r\n    }\r\n    function init(){\r\n        var mapNode = editor.selection.getRange().getClosedNode(),\r\n            isMapImg = mapNode && /api[.]map[.]baidu[.]com/ig.test(mapNode.getAttribute(\"src\")),\r\n            isMapIframe = mapNode && domUtils.hasClass(mapNode, 'ueditor_baidumap');\r\n        if(isMapImg || isMapIframe){\r\n            var url, centerPos, markerPos;\r\n            if(isMapIframe) {\r\n                url = decodeURIComponent(mapNode.getAttribute(\"src\"));\r\n                $G('is_dynamic').checked = true;\r\n                styleStr = mapNode.style.cssText;\r\n            } else {\r\n                url = mapNode.getAttribute(\"src\");\r\n                styleStr = mapNode.style.cssText;\r\n            }\r\n\r\n            centerPos = getPars(url,\"center\").split(\",\");\r\n            markerPos = getPars(url, \"markers\").split(\",\");\r\n            point = new BMap.Point(Number(centerPos[0]),Number(centerPos[1]));\r\n            marker = new BMap.Marker(new BMap.Point(Number(markerPos[0]), Number(markerPos[1])));\r\n            map.addControl(new BMap.NavigationControl());\r\n            map.centerAndZoom(point, Number(getPars(url,\"zoom\")));\r\n        }else{\r\n            point = new BMap.Point(116.404, 39.915);    // 创建点坐标\r\n            marker = new BMap.Marker(point);\r\n            map.addControl(new BMap.NavigationControl());\r\n            map.centerAndZoom(point, 10);                     // 初始化地图,设置中心点坐标和地图级别。\r\n        }\r\n        marker.enableDragging();\r\n        map.addOverlay(marker);\r\n    }\r\n    init();\r\n    document.getElementById('address').onkeydown = function (evt){\r\n        evt = evt || event;\r\n        if (evt.keyCode == 13) {\r\n            doSearch();\r\n        }\r\n    };\r\n    dialog.onok = function (){\r\n        var center = map.getCenter();\r\n        var zoom = map.zoomLevel;\r\n        var size = map.getSize();\r\n        var mapWidth = size.width;\r\n        var mapHeight = size.height;\r\n        var point = marker.getPoint();\r\n\r\n        if($G('is_dynamic').checked) {\r\n            var URL = editor.options.UEDITOR_HOME_URL,\r\n                url = [URL + (/\\/$/.test(URL) ? '':'/') + \"dialogs/map/show.html\" +\r\n                    '#center=' + center.lng + ',' + center.lat,\r\n                    '&zoom=' + zoom,\r\n                    '&width=' + mapWidth,\r\n                    '&height=' + mapHeight,\r\n                    '&markers=' + point.lng + ',' + point.lat,\r\n                    '&markerStyles=' + 'l,A'].join('');\r\n            editor.execCommand('inserthtml', '<iframe class=\"ueditor_baidumap\" src=\"' + url + '\"' + (styleStr ? ' style=\"' + styleStr + '\"' :'') + ' frameborder=\"0\" width=\"' + (mapWidth+4) + '\" height=\"' + (mapHeight+4) + '\"></iframe>');\r\n        } else {\r\n            var url = \"http://api.map.baidu.com/staticimage?center=\" + center.lng + ',' + center.lat +\r\n                    \"&zoom=\" + zoom + \"&width=\" + size.width + '&height=' + size.height + \"&markers=\" + point.lng + ',' + point.lat;\r\n            editor.execCommand('inserthtml', '<img width=\"'+ size.width +'\"height=\"'+ size.height +'\" src=\"' + url + '\"' + (styleStr ? ' style=\"' + styleStr + '\"' :'') + '/>');\r\n        }\r\n    };\r\n    document.getElementById(\"address\").focus();\r\n</script>\r\n\r\n\r\n</body>\r\n</html>\r\n"
  },
  {
    "path": "public/static/ueditor/dialogs/map/show.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n        \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n    <meta charset=\"utf-8\"/>\n    <meta name=\"keywords\" content=\"百度地图,百度地图API，百度地图自定义工具，百度地图所见即所得工具\"/>\n    <meta name=\"description\" content=\"百度地图API自定义地图，帮助用户在可视化操作下生成百度地图\"/>\n    <title>百度地图API自定义地图</title>\n    <!--引用百度地图API-->\n    <style type=\"text/css\">\n        html, body {\n            margin: 0;\n            padding: 0;\n            overflow: hidden;\n        }\n    </style>\n    <script type=\"text/javascript\" src=\"http://api.map.baidu.com/api?key=&v=1.1&services=true\"></script>\n</head>\n\n<body onload=\"initMap();\">\n<!--百度地图容器-->\n<div style=\"width:697px;height:550px;border:#ccc solid 1px;\" id=\"dituContent\"></div>\n</body>\n<script type=\"text/javascript\">\n    function getParam(name) {\n        return location.href.match(new RegExp('[?#&]' + name + '=([^?#&]+)', 'i')) ? RegExp.$1 : '';\n    }\n    var map, marker;\n    var centerParam = getParam('center');\n    var zoomParam = getParam('zoom');\n    var widthParam = getParam('width');\n    var heightParam = getParam('height');\n    var markersParam = getParam('markers');\n    var markerStylesParam = getParam('markerStyles');\n\n    //创建和初始化地图函数：\n    function initMap() {\n        // [FF]切换模式后报错\n        if (!window.BMap) {\n            return;\n        }\n        var dituContent = document.getElementById('dituContent');\n        dituContent.style.width = widthParam + 'px';\n        dituContent.style.height = heightParam + 'px';\n\n        createMap();//创建地图\n        setMapEvent();//设置地图事件\n        addMapControl();//向地图添加控件\n\n        // 创建标注\n        var markersArr = markersParam.split(',');\n        var point = new BMap.Point(markersArr[0], markersArr[1]);\n        marker = new BMap.Marker(point);\n        marker.enableDragging();\n        map.addOverlay(marker); // 将标注添加到地图中\n\n        if(parent.editor && parent.document.body.contentEditable==\"true\") { //在编辑状态下\n            setMapListener();//地图改变修改外层的iframe标签src属性\n        }\n    }\n\n    //创建地图函数：\n    function createMap() {\n        map = new BMap.Map(\"dituContent\");//在百度地图容器中创建一个地图\n        var centerArr = centerParam.split(',');\n        var point = new BMap.Point(parseFloat(centerArr[0]), parseFloat(centerArr[1]));//定义一个中心点坐标\n        map.centerAndZoom(point, parseInt(zoomParam));//设定地图的中心点和坐标并将地图显示在地图容器中\n    }\n\n    //地图事件设置函数：\n    function setMapEvent() {\n        map.enableDragging();//启用地图拖拽事件，默认启用(可不写)\n        map.enableScrollWheelZoom();//启用地图滚轮放大缩小\n        map.enableDoubleClickZoom();//启用鼠标双击放大，默认启用(可不写)\n        map.enableKeyboard();//启用键盘上下左右键移动地图\n    }\n\n    //地图控件添加函数：\n    function addMapControl() {\n        //向地图中添加缩放控件\n        var ctrl_nav = new BMap.NavigationControl({anchor: BMAP_ANCHOR_TOP_LEFT, type: BMAP_NAVIGATION_CONTROL_LARGE});\n        map.addControl(ctrl_nav);\n        //向地图中添加缩略图控件\n        var ctrl_ove = new BMap.OverviewMapControl({anchor: BMAP_ANCHOR_BOTTOM_RIGHT, isOpen: 1});\n        map.addControl(ctrl_ove);\n        //向地图中添加比例尺控件\n        var ctrl_sca = new BMap.ScaleControl({anchor: BMAP_ANCHOR_BOTTOM_LEFT});\n        map.addControl(ctrl_sca);\n    }\n\n    function setMapListener() {\n        var editor = parent.editor, containerIframe,\n            iframes = parent.document.getElementsByTagName('iframe');\n        for (var key in iframes) {\n            if (iframes[key].contentWindow == window) {\n                containerIframe = iframes[key];\n                break;\n            }\n        }\n        if (containerIframe) {\n            map.addEventListener('moveend', mapListenerHandler);\n            map.addEventListener('zoomend', mapListenerHandler);\n            marker.addEventListener('dragend', mapListenerHandler);\n        }\n\n        function mapListenerHandler() {\n            var zoom = map.getZoom(),\n                center = map.getCenter(),\n                marker = window.marker.getPoint();\n            containerIframe.src = containerIframe.src.\n                replace(new RegExp('([?#&])center=([^?#&]+)', 'i'), '$1center=' + center.lng + ',' + center.lat).\n                replace(new RegExp('([?#&])markers=([^?#&]+)', 'i'), '$1markers=' + marker.lng + ',' + marker.lat).\n                replace(new RegExp('([?#&])zoom=([^?#&]+)', 'i'), '$1zoom=' + zoom);\n            editor.fireEvent('saveScene');\n        }\n    }\n</script>\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/music/music.css",
    "content": ".wrapper{margin: 5px 10px;}\r\n\r\n.searchBar{height:30px;padding:7px 0 3px;text-align:center;}\r\n.searchBtn{font-size:13px;height:24px;}\r\n\r\n.resultBar{width:460px;margin:5px auto;border: 1px solid #CCC;border-radius: 5px;box-shadow: 2px 2px 5px #D3D6DA;overflow: hidden;}\r\n\r\n.listPanel{overflow: hidden;}\r\n.panelon{display:block;}\r\n.paneloff{display:none}\r\n\r\n.page{width:220px;margin:20px auto;overflow: hidden;}\r\n.pageon{float:right;width:24px;line-height:24px;height:24px;margin-right: 5px;background: none;border: none;color: #000;font-weight: bold;text-align:center}\r\n.pageoff{float:right;width:24px;line-height:24px;height:24px;cursor:pointer;background-color: #fff;\r\n   border: 1px solid #E7ECF0;color: #2D64B3;margin-right: 5px;text-decoration: none;text-align:center;}\r\n\r\n.m-box{width:460px;}\r\n.m-m{float: left;line-height: 20px;height: 20px;}\r\n.m-h{height:24px;line-height:24px;padding-left: 46px;background-color:#FAFAFA;border-bottom: 1px solid #DAD8D8;font-weight: bold;font-size: 12px;color: #333;}\r\n.m-l{float:left;width:40px; }\r\n.m-t{float:left;width:140px;}\r\n.m-s{float:left;width:110px;}\r\n.m-z{float:left;width:100px;}\r\n.m-try-t{float: left;width: 60px;;}\r\n\r\n.m-try{float:left;width:20px;height:20px;background:url('http://static.tieba.baidu.com/tb/editor/images/try_music.gif') no-repeat ;}\r\n.m-trying{float:left;width:20px;height:20px;background:url('http://static.tieba.baidu.com/tb/editor/images/stop_music.gif') no-repeat ;}\r\n\r\n.loading{width:95px;height:7px;font-size:7px;margin:60px auto;background:url(http://static.tieba.baidu.com/tb/editor/images/loading.gif) no-repeat}\r\n.empty{width:300px;height:40px;padding:2px;margin:50px auto;line-height:40px; color:#006699;text-align:center;}"
  },
  {
    "path": "public/static/ueditor/dialogs/music/music.html",
    "content": "<!DOCTYPE html>\r\n<html>\r\n<head>\r\n    <meta http-equiv=\"content-type\" content=\"text/html; charset=utf-8\">\r\n    <title>插入音乐</title>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"music.css\">\r\n</head>\r\n<body>\r\n<div class=\"wrapper\">\r\n    <div class=\"searchBar\">\r\n        <input id=\"J_searchName\" type=\"text\"/>\r\n        <input type=\"button\" class=\"searchBtn\" id=\"J_searchBtn\">\r\n    </div>\r\n    <div class=\"resultBar\" id=\"J_resultBar\">\r\n        <div class=\"loading\" style=\"display:none\"></div>\r\n        <div class=\"empty\"><var id=\"lang_input_tips\"></var></div>\r\n    </div>\r\n    <div id=\"J_preview\"></div>\r\n</div>\r\n<script type=\"text/javascript\" src=\"music.js\"></script>\r\n<script type=\"text/javascript\">\r\n    var music = new Music;\r\n    dialog.onok = function () {\r\n        music.exec();\r\n    };\r\n    dialog.oncancel = function () {\r\n        $G('J_preview').innerHTML = \"\";\r\n    };\r\n</script>\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/music/music.js",
    "content": "function Music() {\r\n    this.init();\r\n}\r\n(function () {\r\n    var pages = [],\r\n        panels = [],\r\n        selectedItem = null;\r\n    Music.prototype = {\r\n        total:70,\r\n        pageSize:10,\r\n        dataUrl:\"http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.search.common\",\r\n        playerUrl:\"http://box.baidu.com/widget/flash/bdspacesong.swf\",\r\n\r\n        init:function () {\r\n            var me = this;\r\n            domUtils.on($G(\"J_searchName\"), \"keyup\", function (event) {\r\n                var e = window.event || event;\r\n                if (e.keyCode == 13) {\r\n                    me.dosearch();\r\n                }\r\n            });\r\n            domUtils.on($G(\"J_searchBtn\"), \"click\", function () {\r\n                me.dosearch();\r\n            });\r\n        },\r\n        callback:function (data) {\r\n            var me = this;\r\n            me.data = data.song_list;\r\n            setTimeout(function () {\r\n                $G('J_resultBar').innerHTML = me._renderTemplate(data.song_list);\r\n            }, 300);\r\n        },\r\n        dosearch:function () {\r\n            var me = this;\r\n            selectedItem = null;\r\n            var key = $G('J_searchName').value;\r\n            if (utils.trim(key) == \"\")return false;\r\n            key = encodeURIComponent(key);\r\n            me._sent(key);\r\n        },\r\n        doselect:function (i) {\r\n            var me = this;\r\n            if (typeof i == 'object') {\r\n                selectedItem = i;\r\n            } else if (typeof i == 'number') {\r\n                selectedItem = me.data[i];\r\n            }\r\n        },\r\n        onpageclick:function (id) {\r\n            var me = this;\r\n            for (var i = 0; i < pages.length; i++) {\r\n                $G(pages[i]).className = 'pageoff';\r\n                $G(panels[i]).className = 'paneloff';\r\n            }\r\n            $G('page' + id).className = 'pageon';\r\n            $G('panel' + id).className = 'panelon';\r\n        },\r\n        listenTest:function (elem) {\r\n            var me = this,\r\n                view = $G('J_preview'),\r\n                is_play_action = (elem.className == 'm-try'),\r\n                old_trying = me._getTryingElem();\r\n\r\n            if (old_trying) {\r\n                old_trying.className = 'm-try';\r\n                view.innerHTML = '';\r\n            }\r\n            if (is_play_action) {\r\n                elem.className = 'm-trying';\r\n                view.innerHTML = me._buildMusicHtml(me._getUrl(true));\r\n            }\r\n        },\r\n        _sent:function (param) {\r\n            var me = this;\r\n            $G('J_resultBar').innerHTML = '<div class=\"loading\"></div>';\r\n\r\n            utils.loadFile(document, {\r\n                src:me.dataUrl + '&query=' + param + '&page_size=' + me.total + '&callback=music.callback&.r=' + Math.random(),\r\n                tag:\"script\",\r\n                type:\"text/javascript\",\r\n                defer:\"defer\"\r\n            });\r\n        },\r\n        _removeHtml:function (str) {\r\n            var reg = /<\\s*\\/?\\s*[^>]*\\s*>/gi;\r\n            return str.replace(reg, \"\");\r\n        },\r\n        _getUrl:function (isTryListen) {\r\n            var me = this;\r\n            var param = 'from=tiebasongwidget&url=&name=' + encodeURIComponent(me._removeHtml(selectedItem.title)) + '&artist='\r\n                + encodeURIComponent(me._removeHtml(selectedItem.author)) + '&extra='\r\n                + encodeURIComponent(me._removeHtml(selectedItem.album_title))\r\n                + '&autoPlay='+isTryListen+'' + '&loop=true';\r\n            return  me.playerUrl + \"?\" + param;\r\n        },\r\n        _getTryingElem:function () {\r\n            var s = $G('J_listPanel').getElementsByTagName('span');\r\n\r\n            for (var i = 0; i < s.length; i++) {\r\n                if (s[i].className == 'm-trying')\r\n                    return s[i];\r\n            }\r\n            return null;\r\n        },\r\n        _buildMusicHtml:function (playerUrl) {\r\n            var html = '<embed class=\"BDE_try_Music\" allowfullscreen=\"false\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\"';\r\n            html += ' src=\"' + playerUrl + '\"';\r\n            html += ' width=\"1\" height=\"1\" style=\"position:absolute;left:-2000px;\"';\r\n            html += ' type=\"application/x-shockwave-flash\" wmode=\"transparent\" play=\"true\" loop=\"false\"';\r\n            html += ' menu=\"false\" allowscriptaccess=\"never\" scale=\"noborder\">';\r\n            return html;\r\n        },\r\n        _byteLength:function (str) {\r\n            return str.replace(/[^\\u0000-\\u007f]/g, \"\\u0061\\u0061\").length;\r\n        },\r\n        _getMaxText:function (s) {\r\n            var me = this;\r\n            s = me._removeHtml(s);\r\n            if (me._byteLength(s) > 12)\r\n                return s.substring(0, 5) + '...';\r\n            if (!s) s = \"&nbsp;\";\r\n            return s;\r\n        },\r\n        _rebuildData:function (data) {\r\n            var me = this,\r\n                newData = [],\r\n                d = me.pageSize,\r\n                itembox;\r\n            for (var i = 0; i < data.length; i++) {\r\n                if ((i + d) % d == 0) {\r\n                    itembox = [];\r\n                    newData.push(itembox)\r\n                }\r\n                itembox.push(data[i]);\r\n            }\r\n            return newData;\r\n        },\r\n        _renderTemplate:function (data) {\r\n            var me = this;\r\n            if (data.length == 0)return '<div class=\"empty\">' + lang.emptyTxt + '</div>';\r\n            data = me._rebuildData(data);\r\n            var s = [], p = [], t = [];\r\n            s.push('<div id=\"J_listPanel\" class=\"listPanel\">');\r\n            p.push('<div class=\"page\">');\r\n            for (var i = 0, tmpList; tmpList = data[i++];) {\r\n                panels.push('panel' + i);\r\n                pages.push('page' + i);\r\n                if (i == 1) {\r\n                    s.push('<div id=\"panel' + i + '\" class=\"panelon\">');\r\n                    if (data.length != 1) {\r\n                        t.push('<div id=\"page' + i + '\" onclick=\"music.onpageclick(' + i + ')\" class=\"pageon\">' + (i ) + '</div>');\r\n                    }\r\n                } else {\r\n                    s.push('<div id=\"panel' + i + '\" class=\"paneloff\">');\r\n                    t.push('<div id=\"page' + i + '\" onclick=\"music.onpageclick(' + i + ')\" class=\"pageoff\">' + (i ) + '</div>');\r\n                }\r\n                s.push('<div class=\"m-box\">');\r\n                s.push('<div class=\"m-h\"><span class=\"m-t\">' + lang.chapter + '</span><span class=\"m-s\">' + lang.singer\r\n                    + '</span><span class=\"m-z\">' + lang.special + '</span><span class=\"m-try-t\">' + lang.listenTest + '</span></div>');\r\n                for (var j = 0, tmpObj; tmpObj = tmpList[j++];) {\r\n                    s.push('<label for=\"radio-' + i + '-' + j + '\" class=\"m-m\">');\r\n                    s.push('<input type=\"radio\" id=\"radio-' + i + '-' + j + '\" name=\"musicId\" class=\"m-l\" onclick=\"music.doselect(' + (me.pageSize * (i-1) + (j-1)) + ')\"/>');\r\n                    s.push('<span class=\"m-t\">' + me._getMaxText(tmpObj.title) + '</span>');\r\n                    s.push('<span class=\"m-s\">' + me._getMaxText(tmpObj.author) + '</span>');\r\n                    s.push('<span class=\"m-z\">' + me._getMaxText(tmpObj.album_title) + '</span>');\r\n                    s.push('<span class=\"m-try\" onclick=\"music.doselect(' + (me.pageSize * (i-1) + (j-1)) + ');music.listenTest(this)\"></span>');\r\n                    s.push('</label>');\r\n                }\r\n                s.push('</div>');\r\n                s.push('</div>');\r\n            }\r\n            t.reverse();\r\n            p.push(t.join(''));\r\n            s.push('</div>');\r\n            p.push('</div>');\r\n            return s.join('') + p.join('');\r\n        },\r\n        exec:function () {\r\n            var me = this;\r\n            if (selectedItem == null)   return;\r\n            $G('J_preview').innerHTML = \"\";\r\n            editor.execCommand('music', {\r\n                url:me._getUrl(false),\r\n                width:400,\r\n                height:95\r\n            });\r\n        }\r\n    };\r\n})();\r\n\r\n\r\n\r\n"
  },
  {
    "path": "public/static/ueditor/dialogs/preview/preview.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\n    \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n    <head>\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\n        <style>\n            html,body{\n                height:100%;\n                width:100%;\n                padding:0;\n                margin:0;\n            }\n            #preview{\n                width:100%;\n                height:100%;\n                padding:0;\n                margin:0;\n            }\n            #preview *{font-family:sans-serif;font-size:16px;}\n        </style>\n        <script type=\"text/javascript\" src=\"../internal.js\"></script>\n        <script src=\"../../ueditor.parse.js\"></script>\n        <title></title>\n    </head>\n    <body class=\"view\">\n        <div id=\"preview\" style=\"margin:8px\">\n\n        </div>\n    </body>\n    <script>\n        document.getElementById('preview').innerHTML = editor.getContent();\n        uParse('#preview',{\n            rootPath : '../../',\n            chartContainerHeight:500\n        })\n        dialog.oncancel = function(){\n            document.getElementById('preview').innerHTML = '';\n        }\n    </script>\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/scrawl/scrawl.css",
    "content": "/*common\r\n*/\r\nbody{margin: 0;}\r\ntable{width:100%;}\r\ntable td{padding:2px 4px;vertical-align: middle;}\r\na{text-decoration: none;}\r\nem{font-style: normal;}\r\n.border_style1{border: 1px solid #ccc;border-radius: 5px;box-shadow:2px 2px 5px #d3d6da;}\r\n/*module\r\n*/\r\n.main{margin: 8px;overflow: hidden;}\r\n\r\n.hot{float:left;height:335px;}\r\n.drawBoard{position: relative; cursor: crosshair;}\r\n.brushBorad{position: absolute;left:0;top:0;z-index: 998;}\r\n.picBoard{border: none;text-align: center;line-height: 300px;cursor: default;}\r\n.operateBar{margin-top:10px;font-size:12px;text-align: center;}\r\n.operateBar span{margin-left: 10px;}\r\n\r\n.drawToolbar{float:right;width:110px;height:300px;overflow: hidden;}\r\n.colorBar{margin-top:10px;font-size: 12px;text-align: center;}\r\n.colorBar a{display:block;width: 10px;height: 10px;border:1px solid #1006F1;border-radius: 3px; box-shadow:2px 2px 5px #d3d6da;opacity: 0.3}\r\n.sectionBar{margin-top:15px;font-size: 12px;text-align: center;}\r\n.sectionBar a{display:inline-block;width:10px;height:12px;color: #888;text-indent: -999px;opacity: 0.3}\r\n.size1{background: url('images/size.png') 1px center no-repeat ;}\r\n.size2{background: url('images/size.png') -10px center no-repeat;}\r\n.size3{background: url('images/size.png') -22px center no-repeat;}\r\n.size4{background: url('images/size.png') -35px center no-repeat;}\r\n\r\n.addImgH{position: relative;}\r\n.addImgH_form{position: absolute;left: 18px;top: -1px;width: 75px;height: 21px;opacity: 0;cursor: pointer;}\r\n.addImgH_form input{width: 100%;}\r\n/*scrawl遮罩层\r\n*/\r\n.maskLayerNull{display: none;}\r\n.maskLayer{position: absolute;top:0;left:0;width: 100%; height: 100%;opacity: 0.7;\r\n    background-color: #fff;text-align:center;font-weight:bold;line-height:300px;z-index: 1000;}\r\n/*btn state\r\n*/\r\n.previousStepH .icon{display: inline-block;width:16px;height:16px;background-image: url('images/undoH.png');cursor: pointer;}\r\n.previousStepH .text{color:#888;cursor:pointer;}\r\n.previousStep .icon{display: inline-block;width:16px;height:16px;background-image: url('images/undo.png');cursor:default;}\r\n.previousStep .text{color:#ccc;cursor:default;}\r\n\r\n.nextStepH .icon{display: inline-block;width:16px;height:16px;background-image: url('images/redoH.png');cursor: pointer;}\r\n.nextStepH .text{color:#888;cursor:pointer;}\r\n.nextStep .icon{display: inline-block;width:16px;height:16px;background-image: url('images/redo.png');cursor:default;}\r\n.nextStep .text{color:#ccc;cursor:default;}\r\n\r\n.clearBoardH .icon{display: inline-block;width:16px;height:16px;background-image: url('images/emptyH.png');cursor: pointer;}\r\n.clearBoardH .text{color:#888;cursor:pointer;}\r\n.clearBoard .icon{display: inline-block;width:16px;height:16px;background-image: url('images/empty.png');cursor:default;}\r\n.clearBoard .text{color:#ccc;cursor:default;}\r\n\r\n.scaleBoardH .icon{display: inline-block;width:16px;height:16px;background-image: url('images/scaleH.png');cursor: pointer;}\r\n.scaleBoardH .text{color:#888;cursor:pointer;}\r\n.scaleBoard .icon{display: inline-block;width:16px;height:16px;background-image: url('images/scale.png');cursor:default;}\r\n.scaleBoard .text{color:#ccc;cursor:default;}\r\n\r\n.removeImgH .icon{display: inline-block;width:16px;height:16px;background-image: url('images/delimgH.png');cursor: pointer;}\r\n.removeImgH .text{color:#888;cursor:pointer;}\r\n.removeImg .icon{display: inline-block;width:16px;height:16px;background-image: url('images/delimg.png');cursor:default;}\r\n.removeImg .text{color:#ccc;cursor:default;}\r\n\r\n.addImgH .icon{vertical-align:top;display: inline-block;width:16px;height:16px;background-image: url('images/addimg.png')}\r\n.addImgH .text{color:#888;cursor:pointer;}\r\n/*icon\r\n*/\r\n.brushIcon{display: inline-block;width:16px;height:16px;background-image: url('images/brush.png')}\r\n.eraserIcon{display: inline-block;width:16px;height:16px;background-image: url('images/eraser.png')}\r\n\r\n\r\n"
  },
  {
    "path": "public/static/ueditor/dialogs/scrawl/scrawl.html",
    "content": "<!DOCTYPE html>\r\n<html>\r\n<head>\r\n    <title></title>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\r\n    <meta name=\"robots\" content=\"noindex, nofollow\"/>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"scrawl.css\">\r\n</head>\r\n<body>\r\n<div class=\"main\" id=\"J_wrap\">\r\n    <div class=\"hot\">\r\n        <div class=\"drawBoard border_style1\">\r\n            <canvas id=\"J_brushBoard\" class=\"brushBorad\" width=\"360\" height=\"300\"></canvas>\r\n            <div id=\"J_picBoard\" class=\"picBoard\" style=\"width: 360px;height: 300px\"></div>\r\n        </div>\r\n        <div id=\"J_operateBar\" class=\"operateBar\">\r\n            <span id=\"J_previousStep\" class=\"previousStep\">\r\n                <em class=\"icon\"></em>\r\n                <em class=\"text\"><var id=\"lang_input_previousStep\"></var></em>\r\n            </span>\r\n            <span id=\"J_nextStep\" class=\"nextStep\">\r\n                <em class=\"icon\"></em>\r\n                <em class=\"text\"><var id=\"lang_input_nextsStep\"></var></em>\r\n            </span>\r\n            <span id=\"J_clearBoard\" class=\"clearBoard\">\r\n                <em class=\"icon\"></em>\r\n                <em class=\"text\"><var id=\"lang_input_clear\"></var></em>\r\n            </span>\r\n            <span id=\"J_sacleBoard\" class=\"scaleBoard\">\r\n                <em class=\"icon\"></em>\r\n                <em class=\"text\"><var id=\"lang_input_ScalePic\"></var></em>\r\n            </span>\r\n        </div>\r\n    </div>\r\n    <div class=\"drawToolbar border_style1\">\r\n        <div id=\"J_colorBar\" class=\"colorBar\"></div>\r\n        <div id=\"J_brushBar\" class=\"sectionBar\">\r\n            <em class=\"brushIcon\"></em>\r\n            <a href=\"javascript:void(0)\" class=\"size1\">1</a>\r\n            <a href=\"javascript:void(0)\" class=\"size2\">3</a>\r\n            <a href=\"javascript:void(0)\" class=\"size3\">5</a>\r\n            <a href=\"javascript:void(0)\" class=\"size4\">7</a>\r\n        </div>\r\n        <div id=\"J_eraserBar\" class=\"sectionBar\">\r\n            <em class=\"eraserIcon\"></em>\r\n            <a href=\"javascript:void(0)\" class=\"size1\">1</a>\r\n            <a href=\"javascript:void(0)\" class=\"size2\">3</a>\r\n            <a href=\"javascript:void(0)\" class=\"size3\">5</a>\r\n            <a href=\"javascript:void(0)\" class=\"size4\">7</a>\r\n        </div>\r\n        <div class=\"sectionBar\">\r\n            <div id=\"J_addImg\" class=\"addImgH\">\r\n                <em class=\"icon\"></em>\r\n                <em class=\"text\"><var id=\"lang_input_addPic\"></var></em>\r\n                <form method=\"post\" id=\"fileForm\" enctype=\"multipart/form-data\" class=\"addImgH_form\" target=\"up\">\r\n                    <input type=\"file\" name=\"upfile\" id=\"J_imgTxt\"\r\n                           accept=\"image/gif,image/jpeg,image/png,image/jpg,image/bmp\"/>\r\n                </form>\r\n                <iframe name=\"up\" style=\"display: none\"></iframe>\r\n            </div>\r\n        </div>\r\n        <div class=\"sectionBar\">\r\n            <span id=\"J_removeImg\" class=\"removeImg\">\r\n                <em class=\"icon\"></em>\r\n                <em class=\"text\"><var id=\"lang_input_removePic\"></var></em>\r\n            </span>\r\n        </div>\r\n    </div>\r\n</div>\r\n<div id=\"J_maskLayer\" class=\"maskLayerNull\"></div>\r\n\r\n<script type=\"text/javascript\" src=\"scrawl.js\"></script>\r\n<script type=\"text/javascript\">\r\n    var settings = {\r\n        drawBrushSize:3, //画笔初始大小\r\n        drawBrushColor:\"#4bacc6\", //画笔初始颜色\r\n        colorList:['c00000', 'ff0000', 'ffc000', 'ffff00', '92d050', '00b050', '00b0f0', '0070c0', '002060', '7030a0', 'ffffff',\r\n            '000000', 'eeece1', '1f497d', '4f81bd', 'c0504d', '9bbb59', '8064a2', '4bacc6', 'f79646'], //画笔选择颜色\r\n        saveNum:10  //撤销次数\r\n    };\r\n\r\n    var scrawlObj = new scrawl( settings );\r\n    scrawlObj.isCancelScrawl = false;\r\n\r\n    dialog.onok = function () {\r\n        exec( scrawlObj );\r\n        return false;\r\n    };\r\n    dialog.oncancel = function () {\r\n        scrawlObj.isCancelScrawl = true;\r\n    };\r\n</script>\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/scrawl/scrawl.js",
    "content": "/**\r\n * Created with JetBrains PhpStorm.\r\n * User: xuheng\r\n * Date: 12-5-22\r\n * Time: 上午11:38\r\n * To change this template use File | Settings | File Templates.\r\n */\r\nvar scrawl = function (options) {\r\n    options && this.initOptions(options);\r\n};\r\n(function () {\r\n    var canvas = $G(\"J_brushBoard\"),\r\n        context = canvas.getContext('2d'),\r\n        drawStep = [], //undo redo存储\r\n        drawStepIndex = 0; //undo redo指针\r\n\r\n    scrawl.prototype = {\r\n        isScrawl:false, //是否涂鸦\r\n        brushWidth:-1, //画笔粗细\r\n        brushColor:\"\", //画笔颜色\r\n\r\n        initOptions:function (options) {\r\n            var me = this;\r\n            me.originalState(options);//初始页面状态\r\n            me._buildToolbarColor(options.colorList);//动态生成颜色选择集合\r\n\r\n            me._addBoardListener(options.saveNum);//添加画板处理\r\n            me._addOPerateListener(options.saveNum);//添加undo redo clearBoard处理\r\n            me._addColorBarListener();//添加颜色选择处理\r\n            me._addBrushBarListener();//添加画笔大小处理\r\n            me._addEraserBarListener();//添加橡皮大小处理\r\n            me._addAddImgListener();//添加增添背景图片处理\r\n            me._addRemoveImgListenter();//删除背景图片处理\r\n            me._addScalePicListenter();//添加缩放处理\r\n            me._addClearSelectionListenter();//添加清楚选中状态处理\r\n\r\n            me._originalColorSelect(options.drawBrushColor);//初始化颜色选中\r\n            me._originalBrushSelect(options.drawBrushSize);//初始化画笔选中\r\n            me._clearSelection();//清楚选中状态\r\n        },\r\n\r\n        originalState:function (options) {\r\n            var me = this;\r\n\r\n            me.brushWidth = options.drawBrushSize;//同步画笔粗细\r\n            me.brushColor = options.drawBrushColor;//同步画笔颜色\r\n\r\n            context.lineWidth = me.brushWidth;//初始画笔大小\r\n            context.strokeStyle = me.brushColor;//初始画笔颜色\r\n            context.fillStyle = \"transparent\";//初始画布背景颜色\r\n            context.lineCap = \"round\";//去除锯齿\r\n            context.fill();\r\n        },\r\n        _buildToolbarColor:function (colorList) {\r\n            var tmp = null, arr = [];\r\n            arr.push(\"<table id='J_colorList'>\");\r\n            for (var i = 0, color; color = colorList[i++];) {\r\n                if ((i - 1) % 5 == 0) {\r\n                    if (i != 1) {\r\n                        arr.push(\"</tr>\");\r\n                    }\r\n                    arr.push(\"<tr>\");\r\n                }\r\n                tmp = '#' + color;\r\n                arr.push(\"<td><a title='\" + tmp + \"' href='javascript:void(0)' style='background-color:\" + tmp + \"'></a></td>\");\r\n            }\r\n            arr.push(\"</tr></table>\");\r\n            $G(\"J_colorBar\").innerHTML = arr.join(\"\");\r\n        },\r\n\r\n        _addBoardListener:function (saveNum) {\r\n            var me = this,\r\n                margin = 0,\r\n                startX = -1,\r\n                startY = -1,\r\n                isMouseDown = false,\r\n                isMouseMove = false,\r\n                isMouseUp = false,\r\n                buttonPress = 0, button, flag = '';\r\n\r\n            margin = parseInt(domUtils.getComputedStyle($G(\"J_wrap\"), \"margin-left\"));\r\n            drawStep.push(context.getImageData(0, 0, context.canvas.width, context.canvas.height));\r\n            drawStepIndex += 1;\r\n\r\n            domUtils.on(canvas, [\"mousedown\", \"mousemove\", \"mouseup\", \"mouseout\"], function (e) {\r\n                button = browser.webkit ? e.which : buttonPress;\r\n                switch (e.type) {\r\n                    case 'mousedown':\r\n                        buttonPress = 1;\r\n                        flag = 1;\r\n                        isMouseDown = true;\r\n                        isMouseUp = false;\r\n                        isMouseMove = false;\r\n                        me.isScrawl = true;\r\n                        startX = e.clientX - margin;//10为外边距总和\r\n                        startY = e.clientY - margin;\r\n                        context.beginPath();\r\n                        break;\r\n                    case 'mousemove' :\r\n                        if (!flag && button == 0) {\r\n                            return;\r\n                        }\r\n                        if (!flag && button) {\r\n                            startX = e.clientX - margin;//10为外边距总和\r\n                            startY = e.clientY - margin;\r\n                            context.beginPath();\r\n                            flag = 1;\r\n                        }\r\n                        if (isMouseUp || !isMouseDown) {\r\n                            return;\r\n                        }\r\n                        var endX = e.clientX - margin,\r\n                            endY = e.clientY - margin;\r\n\r\n                        context.moveTo(startX, startY);\r\n                        context.lineTo(endX, endY);\r\n                        context.stroke();\r\n                        startX = endX;\r\n                        startY = endY;\r\n                        isMouseMove = true;\r\n                        break;\r\n                    case 'mouseup':\r\n                        buttonPress = 0;\r\n                        if (!isMouseDown)return;\r\n                        if (!isMouseMove) {\r\n                            context.arc(startX, startY, context.lineWidth, 0, Math.PI * 2, false);\r\n                            context.fillStyle = context.strokeStyle;\r\n                            context.fill();\r\n                        }\r\n                        context.closePath();\r\n                        me._saveOPerate(saveNum);\r\n                        isMouseDown = false;\r\n                        isMouseMove = false;\r\n                        isMouseUp = true;\r\n                        startX = -1;\r\n                        startY = -1;\r\n                        break;\r\n                    case 'mouseout':\r\n                        flag = '';\r\n                        buttonPress = 0;\r\n                        if (button == 1) return;\r\n                        context.closePath();\r\n                        break;\r\n                }\r\n            });\r\n        },\r\n        _addOPerateListener:function (saveNum) {\r\n            var me = this;\r\n            domUtils.on($G(\"J_previousStep\"), \"click\", function () {\r\n                if (drawStepIndex > 1) {\r\n                    drawStepIndex -= 1;\r\n                    context.clearRect(0, 0, context.canvas.width, context.canvas.height);\r\n                    context.putImageData(drawStep[drawStepIndex - 1], 0, 0);\r\n                    me.btn2Highlight(\"J_nextStep\");\r\n                    drawStepIndex == 1 && me.btn2disable(\"J_previousStep\");\r\n                }\r\n            });\r\n            domUtils.on($G(\"J_nextStep\"), \"click\", function () {\r\n                if (drawStepIndex > 0 && drawStepIndex < drawStep.length) {\r\n                    context.clearRect(0, 0, context.canvas.width, context.canvas.height);\r\n                    context.putImageData(drawStep[drawStepIndex], 0, 0);\r\n                    drawStepIndex += 1;\r\n                    me.btn2Highlight(\"J_previousStep\");\r\n                    drawStepIndex == drawStep.length && me.btn2disable(\"J_nextStep\");\r\n                }\r\n            });\r\n            domUtils.on($G(\"J_clearBoard\"), \"click\", function () {\r\n                context.clearRect(0, 0, context.canvas.width, context.canvas.height);\r\n                drawStep = [];\r\n                me._saveOPerate(saveNum);\r\n                drawStepIndex = 1;\r\n                me.isScrawl = false;\r\n                me.btn2disable(\"J_previousStep\");\r\n                me.btn2disable(\"J_nextStep\");\r\n                me.btn2disable(\"J_clearBoard\");\r\n            });\r\n        },\r\n        _addColorBarListener:function () {\r\n            var me = this;\r\n            domUtils.on($G(\"J_colorBar\"), \"click\", function (e) {\r\n                var target = me.getTarget(e),\r\n                    color = target.title;\r\n                if (!!color) {\r\n                    me._addColorSelect(target);\r\n\r\n                    me.brushColor = color;\r\n                    context.globalCompositeOperation = \"source-over\";\r\n                    context.lineWidth = me.brushWidth;\r\n                    context.strokeStyle = color;\r\n                }\r\n            });\r\n        },\r\n        _addBrushBarListener:function () {\r\n            var me = this;\r\n            domUtils.on($G(\"J_brushBar\"), \"click\", function (e) {\r\n                var target = me.getTarget(e),\r\n                    size = browser.ie ? target.innerText : target.text;\r\n                if (!!size) {\r\n                    me._addBESelect(target);\r\n\r\n                    context.globalCompositeOperation = \"source-over\";\r\n                    context.lineWidth = parseInt(size);\r\n                    context.strokeStyle = me.brushColor;\r\n                    me.brushWidth = context.lineWidth;\r\n                }\r\n            });\r\n        },\r\n        _addEraserBarListener:function () {\r\n            var me = this;\r\n            domUtils.on($G(\"J_eraserBar\"), \"click\", function (e) {\r\n                var target = me.getTarget(e),\r\n                    size = browser.ie ? target.innerText : target.text;\r\n                if (!!size) {\r\n                    me._addBESelect(target);\r\n\r\n                    context.lineWidth = parseInt(size);\r\n                    context.globalCompositeOperation = \"destination-out\";\r\n                    context.strokeStyle = \"#FFF\";\r\n                }\r\n            });\r\n        },\r\n        _addAddImgListener:function () {\r\n            var file = $G(\"J_imgTxt\");\r\n            if (!window.FileReader) {\r\n                $G(\"J_addImg\").style.display = 'none';\r\n                $G(\"J_removeImg\").style.display = 'none';\r\n                $G(\"J_sacleBoard\").style.display = 'none';\r\n            }\r\n            domUtils.on(file, \"change\", function (e) {\r\n                var frm = file.parentNode;\r\n                addMaskLayer(lang.backgroundUploading);\r\n\r\n                var target = e.target || e.srcElement,\r\n                    reader = new FileReader();\r\n                reader.onload = function(evt){\r\n                    var target = evt.target || evt.srcElement;\r\n                    ue_callback(target.result, 'SUCCESS');\r\n                };\r\n                reader.readAsDataURL(target.files[0]);\r\n                frm.reset();\r\n            });\r\n        },\r\n        _addRemoveImgListenter:function () {\r\n            var me = this;\r\n            domUtils.on($G(\"J_removeImg\"), \"click\", function () {\r\n                $G(\"J_picBoard\").innerHTML = \"\";\r\n                me.btn2disable(\"J_removeImg\");\r\n                me.btn2disable(\"J_sacleBoard\");\r\n            });\r\n        },\r\n        _addScalePicListenter:function () {\r\n            domUtils.on($G(\"J_sacleBoard\"), \"click\", function () {\r\n                var picBoard = $G(\"J_picBoard\"),\r\n                    scaleCon = $G(\"J_scaleCon\"),\r\n                    img = picBoard.children[0];\r\n\r\n                if (img) {\r\n                    if (!scaleCon) {\r\n                        picBoard.style.cssText = \"position:relative;z-index:999;\"+picBoard.style.cssText;\r\n                        img.style.cssText = \"position: absolute;top:\" + (canvas.height - img.height) / 2 + \"px;left:\" + (canvas.width - img.width) / 2 + \"px;\";\r\n                        var scale = new ScaleBoy();\r\n                        picBoard.appendChild(scale.init());\r\n                        scale.startScale(img);\r\n                    } else {\r\n                        if (scaleCon.style.visibility == \"visible\") {\r\n                            scaleCon.style.visibility = \"hidden\";\r\n                            picBoard.style.position = \"\";\r\n                            picBoard.style.zIndex = \"\";\r\n                        } else {\r\n                            scaleCon.style.visibility = \"visible\";\r\n                            picBoard.style.cssText += \"position:relative;z-index:999\";\r\n                        }\r\n                    }\r\n                }\r\n            });\r\n        },\r\n        _addClearSelectionListenter:function () {\r\n            var doc = document;\r\n            domUtils.on(doc, 'mousemove', function (e) {\r\n                if (browser.ie && browser.version < 11)\r\n                    doc.selection.clear();\r\n                else\r\n                    window.getSelection().removeAllRanges();\r\n            });\r\n        },\r\n        _clearSelection:function () {\r\n            var list = [\"J_operateBar\", \"J_colorBar\", \"J_brushBar\", \"J_eraserBar\", \"J_picBoard\"];\r\n            for (var i = 0, group; group = list[i++];) {\r\n                domUtils.unSelectable($G(group));\r\n            }\r\n        },\r\n\r\n        _saveOPerate:function (saveNum) {\r\n            var me = this;\r\n            if (drawStep.length <= saveNum) {\r\n                if(drawStepIndex<drawStep.length){\r\n                    me.btn2disable(\"J_nextStep\");\r\n                    drawStep.splice(drawStepIndex);\r\n                }\r\n                drawStep.push(context.getImageData(0, 0, context.canvas.width, context.canvas.height));\r\n                drawStepIndex = drawStep.length;\r\n            } else {\r\n                drawStep.shift();\r\n                drawStep.push(context.getImageData(0, 0, context.canvas.width, context.canvas.height));\r\n                drawStepIndex = drawStep.length;\r\n            }\r\n            me.btn2Highlight(\"J_previousStep\");\r\n            me.btn2Highlight(\"J_clearBoard\");\r\n        },\r\n\r\n        _originalColorSelect:function (title) {\r\n            var colorList = $G(\"J_colorList\").getElementsByTagName(\"td\");\r\n            for (var j = 0, cell; cell = colorList[j++];) {\r\n                if (cell.children[0].title.toLowerCase() == title) {\r\n                    cell.children[0].style.opacity = 1;\r\n                }\r\n            }\r\n        },\r\n        _originalBrushSelect:function (text) {\r\n            var brushList = $G(\"J_brushBar\").children;\r\n            for (var i = 0, ele; ele = brushList[i++];) {\r\n                if (ele.tagName.toLowerCase() == \"a\") {\r\n                    var size = browser.ie ? ele.innerText : ele.text;\r\n                    if (size.toLowerCase() == text) {\r\n                        ele.style.opacity = 1;\r\n                    }\r\n                }\r\n            }\r\n        },\r\n        _addColorSelect:function (target) {\r\n            var me = this,\r\n                colorList = $G(\"J_colorList\").getElementsByTagName(\"td\"),\r\n                eraserList = $G(\"J_eraserBar\").children,\r\n                brushList = $G(\"J_brushBar\").children;\r\n\r\n            for (var i = 0, cell; cell = colorList[i++];) {\r\n                cell.children[0].style.opacity = 0.3;\r\n            }\r\n            for (var k = 0, ele; ele = brushList[k++];) {\r\n                if (ele.tagName.toLowerCase() == \"a\") {\r\n                    ele.style.opacity = 0.3;\r\n                    var size = browser.ie ? ele.innerText : ele.text;\r\n                    if (size.toLowerCase() == this.brushWidth) {\r\n                        ele.style.opacity = 1;\r\n                    }\r\n                }\r\n            }\r\n            for (var j = 0, node; node = eraserList[j++];) {\r\n                if (node.tagName.toLowerCase() == \"a\") {\r\n                    node.style.opacity = 0.3;\r\n                }\r\n            }\r\n\r\n            target.style.opacity = 1;\r\n            target.blur();\r\n        },\r\n        _addBESelect:function (target) {\r\n            var brushList = $G(\"J_brushBar\").children;\r\n            var eraserList = $G(\"J_eraserBar\").children;\r\n\r\n            for (var i = 0, ele; ele = brushList[i++];) {\r\n                if (ele.tagName.toLowerCase() == \"a\") {\r\n                    ele.style.opacity = 0.3;\r\n                }\r\n            }\r\n            for (var j = 0, node; node = eraserList[j++];) {\r\n                if (node.tagName.toLowerCase() == \"a\") {\r\n                    node.style.opacity = 0.3;\r\n                }\r\n            }\r\n\r\n            target.style.opacity = 1;\r\n            target.blur();\r\n        },\r\n        getCanvasData:function () {\r\n            var picContainer = $G(\"J_picBoard\"),\r\n                img = picContainer.children[0];\r\n            if (img) {\r\n                var x, y;\r\n                if (img.style.position == \"absolute\") {\r\n                    x = parseInt(img.style.left);\r\n                    y = parseInt(img.style.top);\r\n                } else {\r\n                    x = (picContainer.offsetWidth - img.width) / 2;\r\n                    y = (picContainer.offsetHeight - img.height) / 2;\r\n                }\r\n                context.globalCompositeOperation = \"destination-over\";\r\n                context.drawImage(img, x, y, img.width, img.height);\r\n            } else {\r\n                context.globalCompositeOperation = \"destination-atop\";\r\n                context.fillStyle = \"#fff\";//重置画布背景白色\r\n                context.fillRect(0, 0, canvas.width, canvas.height);\r\n            }\r\n            try {\r\n                return canvas.toDataURL(\"image/png\").substring(22);\r\n            } catch (e) {\r\n                return \"\";\r\n            }\r\n        },\r\n        btn2Highlight:function (id) {\r\n            var cur = $G(id);\r\n            cur.className.indexOf(\"H\") == -1 && (cur.className += \"H\");\r\n        },\r\n        btn2disable:function (id) {\r\n            var cur = $G(id);\r\n            cur.className.indexOf(\"H\") != -1 && (cur.className = cur.className.replace(\"H\", \"\"));\r\n        },\r\n        getTarget:function (evt) {\r\n            return evt.target || evt.srcElement;\r\n        }\r\n    };\r\n})();\r\n\r\nvar ScaleBoy = function () {\r\n    this.dom = null;\r\n    this.scalingElement = null;\r\n};\r\n(function () {\r\n    function _appendStyle() {\r\n        var doc = document,\r\n            head = doc.getElementsByTagName('head')[0],\r\n            style = doc.createElement('style'),\r\n            cssText = '.scale{visibility:hidden;cursor:move;position:absolute;left:0;top:0;width:100px;height:50px;background-color:#fff;font-size:0;line-height:0;opacity:.4;filter:Alpha(opacity=40);}'\r\n                + '.scale span{position:absolute;left:0;top:0;width:6px;height:6px;background-color:#006DAE;}'\r\n                + '.scale .hand0, .scale .hand7{cursor:nw-resize;}'\r\n                + '.scale .hand1, .scale .hand6{left:50%;margin-left:-3px;cursor:n-resize;}'\r\n                + '.scale .hand2, .scale .hand4, .scale .hand7{left:100%;margin-left:-6px;}'\r\n                + '.scale .hand3, .scale .hand4{top:50%;margin-top:-3px;cursor:w-resize;}'\r\n                + '.scale .hand5, .scale .hand6, .scale .hand7{margin-top:-6px;top:100%;}'\r\n                + '.scale .hand2, .scale .hand5{cursor:ne-resize;}';\r\n        style.type = 'text/css';\r\n\r\n        try {\r\n            style.appendChild(doc.createTextNode(cssText));\r\n        } catch (e) {\r\n            style.styleSheet.cssText = cssText;\r\n        }\r\n        head.appendChild(style);\r\n    }\r\n\r\n    function _getDom() {\r\n        var doc = document,\r\n            hand,\r\n            arr = [],\r\n            scale = doc.createElement('div');\r\n\r\n        scale.id = 'J_scaleCon';\r\n        scale.className = 'scale';\r\n        for (var i = 0; i < 8; i++) {\r\n            arr.push(\"<span class='hand\" + i + \"'></span>\");\r\n        }\r\n        scale.innerHTML = arr.join(\"\");\r\n        return scale;\r\n    }\r\n\r\n    var rect = [\r\n        //[left, top, width, height]\r\n        [1, 1, -1, -1],\r\n        [0, 1, 0, -1],\r\n        [0, 1, 1, -1],\r\n        [1, 0, -1, 0],\r\n        [0, 0, 1, 0],\r\n        [1, 0, -1, 1],\r\n        [0, 0, 0, 1],\r\n        [0, 0, 1, 1]\r\n    ];\r\n    ScaleBoy.prototype = {\r\n        init:function () {\r\n            _appendStyle();\r\n            var me = this,\r\n                scale = me.dom = _getDom();\r\n\r\n            me.scaleMousemove.fp = me;\r\n            domUtils.on(scale, 'mousedown', function (e) {\r\n                var target = e.target || e.srcElement;\r\n                me.start = {x:e.clientX, y:e.clientY};\r\n                if (target.className.indexOf('hand') != -1) {\r\n                    me.dir = target.className.replace('hand', '');\r\n                }\r\n                domUtils.on(document.body, 'mousemove', me.scaleMousemove);\r\n                e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;\r\n            });\r\n            domUtils.on(document.body, 'mouseup', function (e) {\r\n                if (me.start) {\r\n                    domUtils.un(document.body, 'mousemove', me.scaleMousemove);\r\n                    if (me.moved) {\r\n                        me.updateScaledElement({position:{x:scale.style.left, y:scale.style.top}, size:{w:scale.style.width, h:scale.style.height}});\r\n                    }\r\n                    delete me.start;\r\n                    delete me.moved;\r\n                    delete me.dir;\r\n                }\r\n            });\r\n            return scale;\r\n        },\r\n        startScale:function (objElement) {\r\n            var me = this, Idom = me.dom;\r\n\r\n            Idom.style.cssText = 'visibility:visible;top:' + objElement.style.top + ';left:' + objElement.style.left + ';width:' + objElement.offsetWidth + 'px;height:' + objElement.offsetHeight + 'px;';\r\n            me.scalingElement = objElement;\r\n        },\r\n        updateScaledElement:function (objStyle) {\r\n            var cur = this.scalingElement,\r\n                pos = objStyle.position,\r\n                size = objStyle.size;\r\n            if (pos) {\r\n                typeof pos.x != 'undefined' && (cur.style.left = pos.x);\r\n                typeof pos.y != 'undefined' && (cur.style.top = pos.y);\r\n            }\r\n            if (size) {\r\n                size.w && (cur.style.width = size.w);\r\n                size.h && (cur.style.height = size.h);\r\n            }\r\n        },\r\n        updateStyleByDir:function (dir, offset) {\r\n            var me = this,\r\n                dom = me.dom, tmp;\r\n\r\n            rect['def'] = [1, 1, 0, 0];\r\n            if (rect[dir][0] != 0) {\r\n                tmp = parseInt(dom.style.left) + offset.x;\r\n                dom.style.left = me._validScaledProp('left', tmp) + 'px';\r\n            }\r\n            if (rect[dir][1] != 0) {\r\n                tmp = parseInt(dom.style.top) + offset.y;\r\n                dom.style.top = me._validScaledProp('top', tmp) + 'px';\r\n            }\r\n            if (rect[dir][2] != 0) {\r\n                tmp = dom.clientWidth + rect[dir][2] * offset.x;\r\n                dom.style.width = me._validScaledProp('width', tmp) + 'px';\r\n            }\r\n            if (rect[dir][3] != 0) {\r\n                tmp = dom.clientHeight + rect[dir][3] * offset.y;\r\n                dom.style.height = me._validScaledProp('height', tmp) + 'px';\r\n            }\r\n            if (dir === 'def') {\r\n                me.updateScaledElement({position:{x:dom.style.left, y:dom.style.top}});\r\n            }\r\n        },\r\n        scaleMousemove:function (e) {\r\n            var me = arguments.callee.fp,\r\n                start = me.start,\r\n                dir = me.dir || 'def',\r\n                offset = {x:e.clientX - start.x, y:e.clientY - start.y};\r\n\r\n            me.updateStyleByDir(dir, offset);\r\n            arguments.callee.fp.start = {x:e.clientX, y:e.clientY};\r\n            arguments.callee.fp.moved = 1;\r\n        },\r\n        _validScaledProp:function (prop, value) {\r\n            var ele = this.dom,\r\n                wrap = $G(\"J_picBoard\");\r\n\r\n            value = isNaN(value) ? 0 : value;\r\n            switch (prop) {\r\n                case 'left':\r\n                    return value < 0 ? 0 : (value + ele.clientWidth) > wrap.clientWidth ? wrap.clientWidth - ele.clientWidth : value;\r\n                case 'top':\r\n                    return value < 0 ? 0 : (value + ele.clientHeight) > wrap.clientHeight ? wrap.clientHeight - ele.clientHeight : value;\r\n                case 'width':\r\n                    return value <= 0 ? 1 : (value + ele.offsetLeft) > wrap.clientWidth ? wrap.clientWidth - ele.offsetLeft : value;\r\n                case 'height':\r\n                    return value <= 0 ? 1 : (value + ele.offsetTop) > wrap.clientHeight ? wrap.clientHeight - ele.offsetTop : value;\r\n            }\r\n        }\r\n    };\r\n})();\r\n\r\n//后台回调\r\nfunction ue_callback(url, state) {\r\n    var doc = document,\r\n        picBorard = $G(\"J_picBoard\"),\r\n        img = doc.createElement(\"img\");\r\n\r\n    //图片缩放\r\n    function scale(img, max, oWidth, oHeight) {\r\n        var width = 0, height = 0, percent, ow = img.width || oWidth, oh = img.height || oHeight;\r\n        if (ow > max || oh > max) {\r\n            if (ow >= oh) {\r\n                if (width = ow - max) {\r\n                    percent = (width / ow).toFixed(2);\r\n                    img.height = oh - oh * percent;\r\n                    img.width = max;\r\n                }\r\n            } else {\r\n                if (height = oh - max) {\r\n                    percent = (height / oh).toFixed(2);\r\n                    img.width = ow - ow * percent;\r\n                    img.height = max;\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    //移除遮罩层\r\n    removeMaskLayer();\r\n    //状态响应\r\n    if (state == \"SUCCESS\") {\r\n        picBorard.innerHTML = \"\";\r\n        img.onload = function () {\r\n            scale(this, 300);\r\n            picBorard.appendChild(img);\r\n\r\n            var obj = new scrawl();\r\n            obj.btn2Highlight(\"J_removeImg\");\r\n            //trace 2457\r\n            obj.btn2Highlight(\"J_sacleBoard\");\r\n        };\r\n        img.src = url;\r\n    } else {\r\n        alert(state);\r\n    }\r\n}\r\n//去掉遮罩层\r\nfunction removeMaskLayer() {\r\n    var maskLayer = $G(\"J_maskLayer\");\r\n    maskLayer.className = \"maskLayerNull\";\r\n    maskLayer.innerHTML = \"\";\r\n    dialog.buttons[0].setDisabled(false);\r\n}\r\n//添加遮罩层\r\nfunction addMaskLayer(html) {\r\n    var maskLayer = $G(\"J_maskLayer\");\r\n    dialog.buttons[0].setDisabled(true);\r\n    maskLayer.className = \"maskLayer\";\r\n    maskLayer.innerHTML = html;\r\n}\r\n//执行确认按钮方法\r\nfunction exec(scrawlObj) {\r\n    if (scrawlObj.isScrawl) {\r\n        addMaskLayer(lang.scrawlUpLoading);\r\n        var base64 = scrawlObj.getCanvasData();\r\n        if (!!base64) {\r\n            var options = {\r\n                timeout:100000,\r\n                onsuccess:function (xhr) {\r\n                    if (!scrawlObj.isCancelScrawl) {\r\n                        var responseObj;\r\n                        responseObj = eval(\"(\" + xhr.responseText + \")\");\r\n                        if (responseObj.state == \"SUCCESS\") {\r\n                            var imgObj = {},\r\n                                url = editor.options.scrawlUrlPrefix + responseObj.url;\r\n                            imgObj.src = url;\r\n                            imgObj._src = url;\r\n                            imgObj.alt = responseObj.original || '';\r\n                            imgObj.title = responseObj.title || '';\r\n                            editor.execCommand(\"insertImage\", imgObj);\r\n                            dialog.close();\r\n                        } else {\r\n                            alert(responseObj.state);\r\n                        }\r\n\r\n                    }\r\n                },\r\n                onerror:function () {\r\n                    alert(lang.imageError);\r\n                    dialog.close();\r\n                }\r\n            };\r\n            options[editor.getOpt('scrawlFieldName')] = base64;\r\n\r\n            var actionUrl = editor.getActionUrl(editor.getOpt('scrawlActionName')),\r\n                params = utils.serializeParam(editor.queryCommandValue('serverparam')) || '',\r\n                url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + params);\r\n            ajax.request(url, options);\r\n        }\r\n    } else {\r\n        addMaskLayer(lang.noScarwl + \"&nbsp;&nbsp;&nbsp;<input type='button' value='\" + lang.continueBtn + \"'  onclick='removeMaskLayer()'/>\");\r\n    }\r\n}\r\n\r\n"
  },
  {
    "path": "public/static/ueditor/dialogs/searchreplace/searchreplace.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n        \"http://www.w3.org/TR/html4/loose.dtd\">\r\n<html>\r\n<head>\r\n    <title></title>\r\n    <meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\"/>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <style type=\"text/css\">\r\n        .warpper{ position:relative;width: 380px; height: 100%; margin: 10px auto;}\r\n        .tabbody{height: 160px;}\r\n        .tabbody table{width:100%;border-collapse: separate;border-spacing: 3px;}\r\n        .tabbody .panel{width:373px;height:100%;padding-left: 5px;position: absolute;background-color: #fff;}\r\n        .tabbody input.int{ width:190px;height:21px;border:1px solid #d7d7d7;line-height:21px;}\r\n        .tabbody input.btn{padding: 0 5px; text-align:center;line-height:24px; text-decoration: none;height:24px;background:url(\"../../themes/default/images/dialog-title-bg.png\") repeat-x;border:1px solid #ccc; }\r\n    </style>\r\n</head>\r\n<body>\r\n<div class=\"warpper\" id=\"searchtab\">\r\n    <div id=\"head\" class=\"tabhead\">\r\n        <span  tabsrc=\"find\" class=\"focus\"><var id=\"lang_tab_search\"></var></span>\r\n        <span  tabsrc=\"replace\" ><var id=\"lang_tab_replace\"></var></span>\r\n    </div>\r\n    <div class=\"tabbody\">\r\n        <div class=\"panel\" id=\"find\">\r\n            <table>\r\n                <tr>\r\n                    <td width=\"80\"><var id=\"lang_search1\"></var>: </td>\r\n                    <td><input id=\"findtxt\" type=\"text\" class=\"int\" /></td>\r\n                </tr>\r\n                <!--<tr>-->\r\n\r\n                    <!--<td colspan=\"2\"><span style=\"color:red\"><var id=\"lang_searchReg\"></var></span></td>-->\r\n                <!--</tr>-->\r\n                <tr>\r\n                    <td><var id=\"lang_case_sensitive1\"></var></td>\r\n                    <td>\r\n                        <input id=\"matchCase\" type=\"checkbox\" />\r\n                    </td>\r\n                </tr>\r\n                <tr>\r\n                    <td colspan=\"2\">\r\n                        <input id=\"nextFindBtn\" type=\"button\" class=\"btn\" />\r\n                        <input id=\"preFindBtn\" type=\"button\" class=\"btn\" />\r\n                    </td>\r\n                </tr>\r\n                <tr>\r\n                    <td colspan=\"2\">\r\n                        &nbsp;\r\n                    </td>\r\n                </tr>\r\n                <tr>\r\n                    <td colspan=\"2\">\r\n                        <span id=\"search-msg\" style=\"color:red\"></span>\r\n                    </td>\r\n                </tr>\r\n            </table>\r\n        </div>\r\n        <div class=\"panel\" id=\"replace\">\r\n            <table>\r\n                <tr>\r\n                    <td width=\"80\"><var id=\"lang_search2\"></var>: </td>\r\n                    <td><input id=\"findtxt1\" type=\"text\" class=\"int\"  /></td>\r\n                </tr>\r\n                <!--<tr>-->\r\n\r\n                    <!--<td colspan=\"2\"><span style=\"color:red\"><var id=\"lang_searchReg1\"></var></span></td>-->\r\n                <!--</tr>-->\r\n                <tr>\r\n                    <td><var id=\"lang_replace\"></var>: </td>\r\n                    <td><input id=\"replacetxt\" type=\"text\" class=\"int\" /></td>\r\n                </tr>\r\n                <tr>\r\n                    <td><var id=\"lang_case_sensitive2\"></var></td>\r\n                    <td>\r\n                        <input id=\"matchCase1\" type=\"checkbox\" />\r\n                    </td>\r\n                </tr>\r\n                <tr>\r\n                    <td colspan=\"2\">\r\n                        <input id=\"nextReplaceBtn\" type=\"button\" class=\"btn\" />\r\n                        <input id=\"preReplaceBtn\" type=\"button\" class=\"btn\" />\r\n                        <input id=\"repalceBtn\" type=\"button\" class=\"btn\" />\r\n                        <input id=\"repalceAllBtn\" type=\"button\" class=\"btn\" />\r\n                    </td>\r\n                </tr>\r\n                <tr>\r\n                    <td colspan=\"2\">\r\n                        &nbsp;\r\n                    </td>\r\n                </tr>\r\n                <tr>\r\n                    <td colspan=\"2\">\r\n                        <span id=\"replace-msg\" style=\"color:red\"></span>\r\n                    </td>\r\n                </tr>\r\n            </table>\r\n        </div>\r\n    </div>\r\n</div>\r\n<script type=\"text/javascript\" src=\"searchreplace.js\"></script>\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/searchreplace/searchreplace.js",
    "content": "/**\r\n * Created with JetBrains PhpStorm.\r\n * User: xuheng\r\n * Date: 12-9-26\r\n * Time: 下午12:29\r\n * To change this template use File | Settings | File Templates.\r\n */\r\n\r\n//清空上次查选的痕迹\r\neditor.firstForSR = 0;\r\neditor.currentRangeForSR = null;\r\n//给tab注册切换事件\r\n/**\r\n * tab点击处理事件\r\n * @param tabHeads\r\n * @param tabBodys\r\n * @param obj\r\n */\r\nfunction clickHandler( tabHeads,tabBodys,obj ) {\r\n    //head样式更改\r\n    for ( var k = 0, len = tabHeads.length; k < len; k++ ) {\r\n        tabHeads[k].className = \"\";\r\n    }\r\n    obj.className = \"focus\";\r\n    //body显隐\r\n    var tabSrc = obj.getAttribute( \"tabSrc\" );\r\n    for ( var j = 0, length = tabBodys.length; j < length; j++ ) {\r\n        var body = tabBodys[j],\r\n            id = body.getAttribute( \"id\" );\r\n        if ( id != tabSrc ) {\r\n            body.style.zIndex = 1;\r\n        } else {\r\n            body.style.zIndex = 200;\r\n        }\r\n    }\r\n\r\n}\r\n\r\n/**\r\n * TAB切换\r\n * @param tabParentId  tab的父节点ID或者对象本身\r\n */\r\nfunction switchTab( tabParentId ) {\r\n    var tabElements = $G( tabParentId ).children,\r\n        tabHeads = tabElements[0].children,\r\n        tabBodys = tabElements[1].children;\r\n\r\n    for ( var i = 0, length = tabHeads.length; i < length; i++ ) {\r\n        var head = tabHeads[i];\r\n        if ( head.className === \"focus\" )clickHandler(tabHeads,tabBodys, head );\r\n        head.onclick = function () {\r\n            clickHandler(tabHeads,tabBodys,this);\r\n        }\r\n    }\r\n}\r\n$G('searchtab').onmousedown = function(){\r\n    $G('search-msg').innerHTML = '';\r\n    $G('replace-msg').innerHTML = ''\r\n}\r\n//是否区分大小写\r\nfunction getMatchCase(id) {\r\n    return $G(id).checked ? true : false;\r\n}\r\n//查找\r\n$G(\"nextFindBtn\").onclick = function (txt, dir, mcase) {\r\n    var findtxt = $G(\"findtxt\").value, obj;\r\n    if (!findtxt) {\r\n        return false;\r\n    }\r\n    obj = {\r\n        searchStr:findtxt,\r\n        dir:1,\r\n        casesensitive:getMatchCase(\"matchCase\")\r\n    };\r\n    if (!frCommond(obj)) {\r\n        var bk = editor.selection.getRange().createBookmark();\r\n        $G('search-msg').innerHTML = lang.getEnd;\r\n        editor.selection.getRange().moveToBookmark(bk).select();\r\n\r\n\r\n    }\r\n};\r\n$G(\"nextReplaceBtn\").onclick = function (txt, dir, mcase) {\r\n    var findtxt = $G(\"findtxt1\").value, obj;\r\n    if (!findtxt) {\r\n        return false;\r\n    }\r\n    obj = {\r\n        searchStr:findtxt,\r\n        dir:1,\r\n        casesensitive:getMatchCase(\"matchCase1\")\r\n    };\r\n    frCommond(obj);\r\n};\r\n$G(\"preFindBtn\").onclick = function (txt, dir, mcase) {\r\n    var findtxt = $G(\"findtxt\").value, obj;\r\n    if (!findtxt) {\r\n        return false;\r\n    }\r\n    obj = {\r\n        searchStr:findtxt,\r\n        dir:-1,\r\n        casesensitive:getMatchCase(\"matchCase\")\r\n    };\r\n    if (!frCommond(obj)) {\r\n        $G('search-msg').innerHTML = lang.getStart;\r\n    }\r\n};\r\n$G(\"preReplaceBtn\").onclick = function (txt, dir, mcase) {\r\n    var findtxt = $G(\"findtxt1\").value, obj;\r\n    if (!findtxt) {\r\n        return false;\r\n    }\r\n    obj = {\r\n        searchStr:findtxt,\r\n        dir:-1,\r\n        casesensitive:getMatchCase(\"matchCase1\")\r\n    };\r\n    frCommond(obj);\r\n};\r\n//替换\r\n$G(\"repalceBtn\").onclick = function () {\r\n    var findtxt = $G(\"findtxt1\").value.replace(/^\\s|\\s$/g, \"\"), obj,\r\n        replacetxt = $G(\"replacetxt\").value.replace(/^\\s|\\s$/g, \"\");\r\n    if (!findtxt) {\r\n        return false;\r\n    }\r\n    if (findtxt == replacetxt || (!getMatchCase(\"matchCase1\") && findtxt.toLowerCase() == replacetxt.toLowerCase())) {\r\n        return false;\r\n    }\r\n    obj = {\r\n        searchStr:findtxt,\r\n        dir:1,\r\n        casesensitive:getMatchCase(\"matchCase1\"),\r\n        replaceStr:replacetxt\r\n    };\r\n    frCommond(obj);\r\n};\r\n//全部替换\r\n$G(\"repalceAllBtn\").onclick = function () {\r\n    var findtxt = $G(\"findtxt1\").value.replace(/^\\s|\\s$/g, \"\"), obj,\r\n        replacetxt = $G(\"replacetxt\").value.replace(/^\\s|\\s$/g, \"\");\r\n    if (!findtxt) {\r\n        return false;\r\n    }\r\n    if (findtxt == replacetxt || (!getMatchCase(\"matchCase1\") && findtxt.toLowerCase() == replacetxt.toLowerCase())) {\r\n        return false;\r\n    }\r\n    obj = {\r\n        searchStr:findtxt,\r\n        casesensitive:getMatchCase(\"matchCase1\"),\r\n        replaceStr:replacetxt,\r\n        all:true\r\n    };\r\n    var num = frCommond(obj);\r\n    if (num) {\r\n        $G('replace-msg').innerHTML = lang.countMsg.replace(\"{#count}\", num);\r\n    }\r\n};\r\n//执行\r\nvar frCommond = function (obj) {\r\n    return editor.execCommand(\"searchreplace\", obj);\r\n};\r\nswitchTab(\"searchtab\");"
  },
  {
    "path": "public/static/ueditor/dialogs/snapscreen/snapscreen.html",
    "content": "<!DOCTYPE HTML>\r\n<html>\r\n    <head>\r\n        <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>\r\n        <title></title>\r\n        <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n        <style type=\"text/css\">\r\n            *{color: #838383}\r\n            html,body {\r\n                font-size: 12px;\r\n                width:100%;\r\n                height:100%;\r\n                overflow: hidden;\r\n                margin:0px;\r\n                padding:0px;\r\n            }\r\n            h2 { font-size: 16px; margin: 20px auto;}\r\n            .content{\r\n                padding:5px 15px 0 15px;\r\n                height:100%;\r\n            }\r\n            dt,dd { margin-left: 0; padding-left: 0;}\r\n            dt a { display: block;\r\n                    height: 30px;\r\n                    line-height: 30px;\r\n                    width: 55px;\r\n                    background: #EFEFEF;\r\n                    border: 1px solid #CCC;\r\n                    padding: 0 10px;\r\n                    text-decoration: none;\r\n            }\r\n            dt a:hover{\r\n                background: #e0e0e0;\r\n                border-color: #999\r\n            }\r\n            dt a:active{\r\n                background: #ccc;\r\n                border-color: #999;\r\n                color: #666;\r\n            }\r\n            dd { line-height:20px;margin-top: 10px;}\r\n            span{ padding-right:4px;}\r\n            input{width:210px;height:21px;background: #FFF;border:1px solid #d7d7d7;padding: 0px; margin: 0px; }\r\n\r\n\r\n        </style>\r\n    </head>\r\n    <body>\r\n        <div class=\"content\">\r\n            <h2><var id=\"lang_showMsg\"></var></h2>\r\n            <dl>\r\n                <dt><a href=\"../../third-party/snapscreen/UEditorSnapscreen.exe\" target=\"_blank\" id=\"downlink\"><var id=\"lang_download\"></var></a></dt>\r\n                <dd><var id=\"lang_step1\"></var></dd>\r\n                <dd><var id=\"lang_step2\"></var></dd>\r\n            </dl>\r\n        </div>\r\n    </body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/spechars/spechars.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n        \"http://www.w3.org/TR/html4/loose.dtd\">\r\n<html>\r\n<head>\r\n    <title></title>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <style type=\"text/css\">\r\n        html,body{overflow:hidden;}\r\n        #specharsTab{width: 97%;margin: 10px auto; zoom:1;position: relative}\r\n        .tabbody {height:447px;}\r\n        .tabbody span{ margin: 5px 3px;text-align: center;display:inline-block;width: 40px;height:16px;line-height: 16px;cursor: pointer; }\r\n    </style>\r\n</head>\r\n<body>\r\n    <div id=\"specharsTab\">\r\n        <div id=\"tabHeads\" class=\"tabhead\"></div><div id=\"tabBodys\" class=\"tabbody\"></div>\r\n    </div>\r\n<script type=\"text/javascript\" src=\"spechars.js\"></script>\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/spechars/spechars.js",
    "content": "/**\r\n * Created with JetBrains PhpStorm.\r\n * User: xuheng\r\n * Date: 12-9-26\r\n * Time: 下午1:09\r\n * To change this template use File | Settings | File Templates.\r\n */\r\nvar charsContent = [\r\n    { name:\"tsfh\", title:lang.tsfh, content:toArray(\"、,。,·,ˉ,ˇ,¨,〃,々,—,～,‖,…,‘,’,“,”,〔,〕,〈,〉,《,》,「,」,『,』,〖,〗,【,】,±,×,÷,∶,∧,∨,∑,∏,∪,∩,∈,∷,√,⊥,∥,∠,⌒,⊙,∫,∮,≡,≌,≈,∽,∝,≠,≮,≯,≤,≥,∞,∵,∴,♂,♀,°,′,″,℃,＄,¤,￠,￡,‰,§,№,☆,★,○,●,◎,◇,◆,□,■,△,▲,※,→,←,↑,↓,〓,〡,〢,〣,〤,〥,〦,〧,〨,〩,㊣,㎎,㎏,㎜,㎝,㎞,㎡,㏄,㏎,㏑,㏒,㏕,︰,￢,￤,℡,ˊ,ˋ,˙,–,―,‥,‵,℅,℉,↖,↗,↘,↙,∕,∟,∣,≒,≦,≧,⊿,═,║,╒,╓,╔,╕,╖,╗,╘,╙,╚,╛,╜,╝,╞,╟,╠,╡,╢,╣,╤,╥,╦,╧,╨,╩,╪,╫,╬,╭,╮,╯,╰,╱,╲,╳,▁,▂,▃,▄,▅,▆,▇,�,█,▉,▊,▋,▌,▍,▎,▏,▓,▔,▕,▼,▽,◢,◣,◤,◥,☉,⊕,〒,〝,〞\")},\r\n    { name:\"lmsz\", title:lang.lmsz, content:toArray(\"ⅰ,ⅱ,ⅲ,ⅳ,ⅴ,ⅵ,ⅶ,ⅷ,ⅸ,ⅹ,Ⅰ,Ⅱ,Ⅲ,Ⅳ,Ⅴ,Ⅵ,Ⅶ,Ⅷ,Ⅸ,Ⅹ,Ⅺ,Ⅻ\")},\r\n    { name:\"szfh\", title:lang.szfh, content:toArray(\"⒈,⒉,⒊,⒋,⒌,⒍,⒎,⒏,⒐,⒑,⒒,⒓,⒔,⒕,⒖,⒗,⒘,⒙,⒚,⒛,⑴,⑵,⑶,⑷,⑸,⑹,⑺,⑻,⑼,⑽,⑾,⑿,⒀,⒁,⒂,⒃,⒄,⒅,⒆,⒇,①,②,③,④,⑤,⑥,⑦,⑧,⑨,⑩,㈠,㈡,㈢,㈣,㈤,㈥,㈦,㈧,㈨,㈩\")},\r\n    { name:\"rwfh\", title:lang.rwfh, content:toArray(\"ぁ,あ,ぃ,い,ぅ,う,ぇ,え,ぉ,お,か,が,き,ぎ,く,ぐ,け,げ,こ,ご,さ,ざ,し,じ,す,ず,せ,ぜ,そ,ぞ,た,だ,ち,ぢ,っ,つ,づ,て,で,と,ど,な,に,ぬ,ね,の,は,ば,ぱ,ひ,び,ぴ,ふ,ぶ,ぷ,へ,べ,ぺ,ほ,ぼ,ぽ,ま,み,む,め,も,ゃ,や,ゅ,ゆ,ょ,よ,ら,り,る,れ,ろ,ゎ,わ,ゐ,ゑ,を,ん,ァ,ア,ィ,イ,ゥ,ウ,ェ,エ,ォ,オ,カ,ガ,キ,ギ,ク,グ,ケ,ゲ,コ,ゴ,サ,ザ,シ,ジ,ス,ズ,セ,ゼ,ソ,ゾ,タ,ダ,チ,ヂ,ッ,ツ,ヅ,テ,デ,ト,ド,ナ,ニ,ヌ,ネ,ノ,ハ,バ,パ,ヒ,ビ,ピ,フ,ブ,プ,ヘ,ベ,ペ,ホ,ボ,ポ,マ,ミ,ム,メ,モ,ャ,ヤ,ュ,ユ,ョ,ヨ,ラ,リ,ル,レ,ロ,ヮ,ワ,ヰ,ヱ,ヲ,ン,ヴ,ヵ,ヶ\")},\r\n    { name:\"xlzm\", title:lang.xlzm, content:toArray(\"Α,Β,Γ,Δ,Ε,Ζ,Η,Θ,Ι,Κ,Λ,Μ,Ν,Ξ,Ο,Π,Ρ,Σ,Τ,Υ,Φ,Χ,Ψ,Ω,α,β,γ,δ,ε,ζ,η,θ,ι,κ,λ,μ,ν,ξ,ο,π,ρ,σ,τ,υ,φ,χ,ψ,ω\")},\r\n    { name:\"ewzm\", title:lang.ewzm, content:toArray(\"А,Б,В,Г,Д,Е,Ё,Ж,З,И,Й,К,Л,М,Н,О,П,Р,С,Т,У,Ф,Х,Ц,Ч,Ш,Щ,Ъ,Ы,Ь,Э,Ю,Я,а,б,в,г,д,е,ё,ж,з,и,й,к,л,м,н,о,п,р,с,т,у,ф,х,ц,ч,ш,щ,ъ,ы,ь,э,ю,я\")},\r\n    { name:\"pyzm\", title:lang.pyzm, content:toArray(\"ā,á,ǎ,à,ē,é,ě,è,ī,í,ǐ,ì,ō,ó,ǒ,ò,ū,ú,ǔ,ù,ǖ,ǘ,ǚ,ǜ,ü\")},\r\n    { name:\"yyyb\", title:lang.yyyb, content:toArray(\"i:,i,e,æ,ʌ,ə:,ə,u:,u,ɔ:,ɔ,a:,ei,ai,ɔi,əu,au,iə,εə,uə,p,t,k,b,d,g,f,s,ʃ,θ,h,v,z,ʒ,ð,tʃ,tr,ts,dʒ,dr,dz,m,n,ŋ,l,r,w,j,\")},\r\n    { name:\"zyzf\", title:lang.zyzf, content:toArray(\"ㄅ,ㄆ,ㄇ,ㄈ,ㄉ,ㄊ,ㄋ,ㄌ,ㄍ,ㄎ,ㄏ,ㄐ,ㄑ,ㄒ,ㄓ,ㄔ,ㄕ,ㄖ,ㄗ,ㄘ,ㄙ,ㄚ,ㄛ,ㄜ,ㄝ,ㄞ,ㄟ,ㄠ,ㄡ,ㄢ,ㄣ,ㄤ,ㄥ,ㄦ,ㄧ,ㄨ\")}\r\n];\r\n(function createTab(content) {\r\n    for (var i = 0, ci; ci = content[i++];) {\r\n        var span = document.createElement(\"span\");\r\n        span.setAttribute(\"tabSrc\", ci.name);\r\n        span.innerHTML = ci.title;\r\n        if (i == 1)span.className = \"focus\";\r\n        domUtils.on(span, \"click\", function () {\r\n            var tmps = $G(\"tabHeads\").children;\r\n            for (var k = 0, sk; sk = tmps[k++];) {\r\n                sk.className = \"\";\r\n            }\r\n            tmps = $G(\"tabBodys\").children;\r\n            for (var k = 0, sk; sk = tmps[k++];) {\r\n                sk.style.display = \"none\";\r\n            }\r\n            this.className = \"focus\";\r\n            $G(this.getAttribute(\"tabSrc\")).style.display = \"\";\r\n        });\r\n        $G(\"tabHeads\").appendChild(span);\r\n        domUtils.insertAfter(span, document.createTextNode(\"\\n\"));\r\n        var div = document.createElement(\"div\");\r\n        div.id = ci.name;\r\n        div.style.display = (i == 1) ? \"\" : \"none\";\r\n        var cons = ci.content;\r\n        for (var j = 0, con; con = cons[j++];) {\r\n            var charSpan = document.createElement(\"span\");\r\n            charSpan.innerHTML = con;\r\n            domUtils.on(charSpan, \"click\", function () {\r\n                editor.execCommand(\"insertHTML\", this.innerHTML);\r\n                dialog.close();\r\n            });\r\n            div.appendChild(charSpan);\r\n        }\r\n        $G(\"tabBodys\").appendChild(div);\r\n    }\r\n})(charsContent);\r\nfunction toArray(str) {\r\n    return str.split(\",\");\r\n}\r\n"
  },
  {
    "path": "public/static/ueditor/dialogs/table/edittable.css",
    "content": "body{\n    overflow: hidden;\n    width: 540px;\n}\n.wrapper {\n    margin: 10px auto 0;\n    font-size: 12px;\n    overflow: hidden;\n    width: 520px;\n    height: 315px;\n}\n\n.clear {\n    clear: both;\n}\n\n.wrapper .left {\n    float: left;\n    margin-left: 10px;;\n}\n\n.wrapper .right {\n    float: right;\n    border-left: 2px dotted #EDEDED;\n    padding-left: 15px;\n}\n\n.section {\n    margin-bottom: 15px;\n    width: 240px;\n    overflow: hidden;\n}\n\n.section h3 {\n    font-weight: bold;\n    padding: 5px 0;\n    margin-bottom: 10px;\n    border-bottom: 1px solid #EDEDED;\n    font-size: 12px;\n}\n\n.section ul {\n    list-style: none;\n    overflow: hidden;\n    clear: both;\n\n}\n\n.section li {\n    float: left;\n    width: 120px;;\n}\n\n.section .tone {\n    width: 80px;;\n}\n\n.section .preview {\n    width: 220px;\n}\n\n.section .preview table {\n    text-align: center;\n    vertical-align: middle;\n    color: #666;\n}\n\n.section .preview caption {\n    font-weight: bold;\n}\n\n.section .preview td {\n    border-width: 1px;\n    border-style: solid;\n    height: 22px;\n}\n\n.section .preview th {\n    border-style: solid;\n    border-color: #DDD;\n    border-width: 2px 1px 1px 1px;\n    height: 22px;\n    background-color: #F7F7F7;\n}"
  },
  {
    "path": "public/static/ueditor/dialogs/table/edittable.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <title></title>\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"edittable.css\">\n</head>\n<body>\n<div class=\"wrapper\">\n    <div class=\"left\">\n        <div class=\"section\">\n            <h3><var id=\"lang_tableStyle\"></var></h3>\n            <ul>\n                <li>\n                    <label onselectstart=\"return false\"><input type=\"checkbox\" id=\"J_title\" name=\"style\"/><var id=\"lang_insertTitle\"></var></label>\n                </li>\n                <li>\n                    <label onselectstart=\"return false\"><input type=\"checkbox\" id=\"J_titleCol\" name=\"style\"/><var id=\"lang_insertTitleCol\"></var></label>\n                </li>\n            </ul>\n            <ul>\n                <li>\n                    <label onselectstart=\"return false\"><input type=\"checkbox\" id=\"J_caption\" name=\"style\"/><var id=\"lang_insertCaption\"></var></label>\n                </li>\n                <li>\n                    <label onselectstart=\"return false\"><input type=\"checkbox\" id=\"J_sorttable\" name=\"style\"/><var id=\"lang_orderbycontent\"></var></label>\n                </li>\n            </ul>\n            <div class=\"clear\"></div>\n        </div>\n        <div class=\"section\">\n            <h3><var id=\"lang_tableSize\"></var></h3>\n            <ul>\n                <li>\n                    <label><input type=\"radio\" id=\"J_autoSizeContent\" name=\"size\"/><var id=\"lang_autoSizeContent\"></var></label>\n                </li>\n                <li>\n                    <label><input type=\"radio\" id=\"J_autoSizePage\" name=\"size\"/><var id=\"lang_autoSizePage\"></var></label>\n                </li>\n            </ul>\n            <div class=\"clear\"></div>\n        </div>\n        <div class=\"section\">\n            <h3><var id=\"lang_borderStyle\"></var></h3>\n            <ul>\n                <li>\n                    <span><var id=\"lang_color\"></var></span>\n                    <input type=\"text\" class=\"tone\" id=\"J_tone\" readonly='readonly' />\n                </li>\n            </ul>\n            <div class=\"clear\"></div>\n        </div>\n    </div>\n    <div class=\"right\">\n        <div class=\"section\">\n            <h3><var id=\"lang_example\"></var></h3>\n            <div class=\"preview\" id=\"J_preview\">\n            </div>\n        </div>\n    </div>\n</div>\n<script type=\"text/javascript\" src=\"edittable.js\"></script>\n</body>\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/table/edittable.js",
    "content": "/**\n * Created with JetBrains PhpStorm.\n * User: xuheng\n * Date: 12-12-19\n * Time: 下午4:55\n * To change this template use File | Settings | File Templates.\n */\n(function () {\n    var title = $G(\"J_title\"),\n        titleCol = $G(\"J_titleCol\"),\n        caption = $G(\"J_caption\"),\n        sorttable = $G(\"J_sorttable\"),\n        autoSizeContent = $G(\"J_autoSizeContent\"),\n        autoSizePage = $G(\"J_autoSizePage\"),\n        tone = $G(\"J_tone\"),\n        me,\n        preview = $G(\"J_preview\");\n\n    var editTable = function () {\n        me = this;\n        me.init();\n    };\n    editTable.prototype = {\n        init:function () {\n            var colorPiker = new UE.ui.ColorPicker({\n                    editor:editor\n                }),\n                colorPop = new UE.ui.Popup({\n                    editor:editor,\n                    content:colorPiker\n                });\n\n            title.checked = editor.queryCommandState(\"inserttitle\") == -1;\n            titleCol.checked = editor.queryCommandState(\"inserttitlecol\") == -1;\n            caption.checked = editor.queryCommandState(\"insertcaption\") == -1;\n            sorttable.checked = editor.queryCommandState(\"enablesort\") == 1;\n\n            var enablesortState = editor.queryCommandState(\"enablesort\"),\n                disablesortState = editor.queryCommandState(\"disablesort\");\n\n            sorttable.checked = !!(enablesortState < 0 && disablesortState >=0);\n            sorttable.disabled = !!(enablesortState < 0 && disablesortState < 0);\n            sorttable.title = enablesortState < 0 && disablesortState < 0 ? lang.errorMsg:'';\n\n            me.createTable(title.checked, titleCol.checked, caption.checked);\n            me.setAutoSize();\n            me.setColor(me.getColor());\n\n            domUtils.on(title, \"click\", me.titleHanler);\n            domUtils.on(titleCol, \"click\", me.titleColHanler);\n            domUtils.on(caption, \"click\", me.captionHanler);\n            domUtils.on(sorttable, \"click\", me.sorttableHanler);\n            domUtils.on(autoSizeContent, \"click\", me.autoSizeContentHanler);\n            domUtils.on(autoSizePage, \"click\", me.autoSizePageHanler);\n\n            domUtils.on(tone, \"click\", function () {\n                colorPop.showAnchor(tone);\n            });\n            domUtils.on(document, 'mousedown', function () {\n                colorPop.hide();\n            });\n            colorPiker.addListener(\"pickcolor\", function () {\n                me.setColor(arguments[1]);\n                colorPop.hide();\n            });\n            colorPiker.addListener(\"picknocolor\", function () {\n                me.setColor(\"\");\n                colorPop.hide();\n            });\n        },\n\n        createTable:function (hasTitle, hasTitleCol, hasCaption) {\n            var arr = [],\n                sortSpan = '<span>^</span>';\n            arr.push(\"<table id='J_example'>\");\n            if (hasCaption) {\n                arr.push(\"<caption>\" + lang.captionName + \"</caption>\")\n            }\n            if (hasTitle) {\n                arr.push(\"<tr>\");\n                if(hasTitleCol) { arr.push(\"<th>\" + lang.titleName + \"</th>\"); }\n                for (var j = 0; j < 5; j++) {\n                    arr.push(\"<th>\" + lang.titleName + \"</th>\");\n                }\n                arr.push(\"</tr>\");\n            }\n            for (var i = 0; i < 6; i++) {\n                arr.push(\"<tr>\");\n                if(hasTitleCol) { arr.push(\"<th>\" + lang.titleName + \"</th>\") }\n                for (var k = 0; k < 5; k++) {\n                    arr.push(\"<td>\" + lang.cellsName + \"</td>\")\n                }\n                arr.push(\"</tr>\");\n            }\n            arr.push(\"</table>\");\n            preview.innerHTML = arr.join(\"\");\n            this.updateSortSpan();\n        },\n        titleHanler:function () {\n            var example = $G(\"J_example\"),\n                frg=document.createDocumentFragment(),\n                color = domUtils.getComputedStyle(domUtils.getElementsByTagName(example, \"td\")[0], \"border-color\"),\n                colCount = example.rows[0].children.length;\n\n            if (title.checked) {\n                example.insertRow(0);\n                for (var i = 0, node; i < colCount; i++) {\n                    node = document.createElement(\"th\");\n                    node.innerHTML = lang.titleName;\n                    frg.appendChild(node);\n                }\n                example.rows[0].appendChild(frg);\n\n            } else {\n                domUtils.remove(example.rows[0]);\n            }\n            me.setColor(color);\n            me.updateSortSpan();\n        },\n        titleColHanler:function () {\n            var example = $G(\"J_example\"),\n                color = domUtils.getComputedStyle(domUtils.getElementsByTagName(example, \"td\")[0], \"border-color\"),\n                colArr = example.rows,\n                colCount = colArr.length;\n\n            if (titleCol.checked) {\n                for (var i = 0, node; i < colCount; i++) {\n                    node = document.createElement(\"th\");\n                    node.innerHTML = lang.titleName;\n                    colArr[i].insertBefore(node, colArr[i].children[0]);\n                }\n            } else {\n                for (var i = 0; i < colCount; i++) {\n                    domUtils.remove(colArr[i].children[0]);\n                }\n            }\n            me.setColor(color);\n            me.updateSortSpan();\n        },\n        captionHanler:function () {\n            var example = $G(\"J_example\");\n            if (caption.checked) {\n                var row = document.createElement('caption');\n                row.innerHTML = lang.captionName;\n                example.insertBefore(row, example.firstChild);\n            } else {\n                domUtils.remove(domUtils.getElementsByTagName(example, 'caption')[0]);\n            }\n        },\n        sorttableHanler:function(){\n            me.updateSortSpan();\n        },\n        autoSizeContentHanler:function () {\n            var example = $G(\"J_example\");\n            example.removeAttribute(\"width\");\n        },\n        autoSizePageHanler:function () {\n            var example = $G(\"J_example\");\n            var tds = example.getElementsByTagName(example, \"td\");\n            utils.each(tds, function (td) {\n                td.removeAttribute(\"width\");\n            });\n            example.setAttribute('width', '100%');\n        },\n        updateSortSpan: function(){\n            var example = $G(\"J_example\"),\n                row = example.rows[0];\n\n            var spans = domUtils.getElementsByTagName(example,\"span\");\n            utils.each(spans,function(span){\n                span.parentNode.removeChild(span);\n            });\n            if (sorttable.checked) {\n                utils.each(row.cells, function(cell, i){\n                    var span = document.createElement(\"span\");\n                    span.innerHTML = \"^\";\n                    cell.appendChild(span);\n                });\n            }\n        },\n        getColor:function () {\n            var start = editor.selection.getStart(), color,\n                cell = domUtils.findParentByTagName(start, [\"td\", \"th\", \"caption\"], true);\n            color = cell && domUtils.getComputedStyle(cell, \"border-color\");\n            if (!color)  color = \"#DDDDDD\";\n            return color;\n        },\n        setColor:function (color) {\n            var example = $G(\"J_example\"),\n                arr = domUtils.getElementsByTagName(example, \"td\").concat(\n                    domUtils.getElementsByTagName(example, \"th\"),\n                    domUtils.getElementsByTagName(example, \"caption\")\n                );\n\n            tone.value = color;\n            utils.each(arr, function (node) {\n                node.style.borderColor = color;\n            });\n\n        },\n        setAutoSize:function () {\n            var me = this;\n            autoSizePage.checked = true;\n            me.autoSizePageHanler();\n        }\n    };\n\n    new editTable;\n\n    dialog.onok = function () {\n        editor.__hasEnterExecCommand = true;\n\n        var checks = {\n            title:\"inserttitle deletetitle\",\n            titleCol:\"inserttitlecol deletetitlecol\",\n            caption:\"insertcaption deletecaption\",\n            sorttable:\"enablesort disablesort\"\n        };\n        editor.fireEvent('saveScene');\n        for(var i in checks){\n            var cmds = checks[i].split(\" \"),\n                input = $G(\"J_\" + i);\n            if(input[\"checked\"]){\n                editor.queryCommandState(cmds[0])!=-1 &&editor.execCommand(cmds[0]);\n            }else{\n                editor.queryCommandState(cmds[1])!=-1 &&editor.execCommand(cmds[1]);\n            }\n        }\n\n        editor.execCommand(\"edittable\", tone.value);\n        autoSizeContent.checked ?editor.execCommand('adaptbytext') : \"\";\n        autoSizePage.checked ? editor.execCommand(\"adaptbywindow\") : \"\";\n        editor.fireEvent('saveScene');\n\n        editor.__hasEnterExecCommand = false;\n    };\n})();"
  },
  {
    "path": "public/static/ueditor/dialogs/table/edittd.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <title></title>\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\n    <style type=\"text/css\">\n        .section {\n            text-align: center;\n            margin-top: 10px;\n        }\n        .section input {\n            margin-left: 5px;\n            width: 70px;\n        }\n    </style>\n</head>\n<body>\n<div class=\"section\">\n    <span><var id=\"lang_tdBkColor\"></var></span>\n    <input type=\"text\" id=\"J_tone\"/>\n</div>\n<script type=\"text/javascript\">\n    var tone = $G(\"J_tone\"),\n            colorPiker = new UE.ui.ColorPicker({\n                editor:editor\n            }),\n            colorPop = new UE.ui.Popup({\n                editor:editor,\n                content:colorPiker\n            });\n    domUtils.on(tone, \"click\", function () {\n        colorPop.showAnchor(tone);\n    });\n    domUtils.on(document, 'mousedown', function () {\n        colorPop.hide();\n    });\n    colorPiker.addListener(\"pickcolor\", function () {\n        tone.value = arguments[1];\n        colorPop.hide();\n    });\n    colorPiker.addListener(\"picknocolor\", function () {\n        tone.value=\"\";\n        colorPop.hide();\n    });\n    dialog.onok=function(){\n        editor.execCommand(\"edittd\",tone.value);\n    };\n\n    var start = editor.selection.getStart(),\n        cell = start && domUtils.findParentByTagName(start, [\"td\", \"th\"], true);\n    if(cell){\n        var color = domUtils.getComputedStyle(cell,'background-color');\n        if(/^#/.test(color)){\n            tone.value = color\n        }\n\n    }\n\n</script>\n</body>\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/table/edittip.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n    <title>表格删除提示</title>\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\n    <style type=\"text/css\">\n        .section {\n            width: 200px;\n            margin: 10px auto 0;\n            font-size: 14px;\n        }\n\n        .item {\n            text-align: center;\n        }\n    </style>\n</head>\n<body>\n<div class=\"section\">\n    <div class=\"item\">\n        <label><input type=\"radio\" id=\"J_delRow\" name=\"cmd\" checked/><var id=\"lang_delRow\"></var></label>\n    </div>\n    <div class=\"item\">\n        <label><input type=\"radio\" id=\"J_delCol\" name=\"cmd\"/><var id=\"lang_delCol\"></var></label>\n    </div>\n</div>\n<script type=\"text/javascript\">\n    dialog.onok = function () {\n        $G(\"J_delRow\").checked ? editor.execCommand(\"deleterow\") : editor.execCommand(\"deletecol\");\n    };\n</script>\n</body>\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/template/config.js",
    "content": "/**\r\n * Created with JetBrains PhpStorm.\r\n * User: xuheng\r\n * Date: 12-8-8\r\n * Time: 下午2:00\r\n * To change this template use File | Settings | File Templates.\r\n */\r\nvar templates = [\r\n    {\r\n        \"pre\":\"pre0.png\",\r\n        'title':lang.blank,\r\n        'preHtml':'<p class=\"ue_t\">&nbsp;欢迎使用UEditor！</p>',\r\n        \"html\":'<p class=\"ue_t\">欢迎使用UEditor！</p>'\r\n\r\n    },\r\n    {\r\n        \"pre\":\"pre1.png\",\r\n        'title':lang.blog,\r\n        'preHtml':'<h1 label=\"Title center\" name=\"tc\" style=\"border-bottom-color:#cccccc;border-bottom-width:2px;border-bottom-style:solid;padding:0px 4px 0px 0px;text-align:center;margin:0px 0px 20px;\"><span style=\"color:#c0504d;\">深入理解Range</span></h1><p style=\"text-align:center;\"><strong class=\" \">UEditor二次开发</strong></p><h3><span class=\" \" style=\"font-family:幼圆\">什么是Range</span></h3><p style=\"text-indent:2em;\">对于“插入”选项卡上的库，在设计时都充分考虑了其中的项与文档整体外观的协调性。 </p><br /><h3><span class=\" \" style=\"font-family:幼圆\">Range能干什么</span></h3><p style=\"text-indent:2em;\">在“开始”选项卡上，通过从快速样式库中为所选文本选择一种外观，您可以方便地更改文档中所选文本的格式。</p>',\r\n        \"html\":'<h1 class=\"ue_t\" label=\"Title center\" name=\"tc\" style=\"border-bottom-color:#cccccc;border-bottom-width:2px;border-bottom-style:solid;padding:0px 4px 0px 0px;text-align:center;margin:0px 0px 20px;\"><span style=\"color:#c0504d;\">[键入文档标题]</span></h1><p style=\"text-align:center;\"><strong class=\"ue_t\">[键入文档副标题]</strong></p><h3><span class=\"ue_t\" style=\"font-family:幼圆\">[标题 1]</span></h3><p class=\"ue_t\"  style=\"text-indent:2em;\">对于“插入”选项卡上的库，在设计时都充分考虑了其中的项与文档整体外观的协调性。 您可以使用这些库来插入表格、页眉、页脚、列表、封面以及其他文档构建基块。 您创建的图片、图表或关系图也将与当前的文档外观协调一致。</p><h3><span class=\"ue_t\" style=\"font-family:幼圆\">[标题 2]</span></h3><p class=\"ue_t\"  style=\"text-indent:2em;\">在“开始”选项卡上，通过从快速样式库中为所选文本选择一种外观，您可以方便地更改文档中所选文本的格式。 您还可以使用“开始”选项卡上的其他控件来直接设置文本格式。大多数控件都允许您选择是使用当前主题外观，还是使用某种直接指定的格式。 </p><h3><span class=\"ue_t\" style=\"font-family:幼圆\">[标题 3]</span></h3><p class=\"ue_t\">对于“插入”选项卡上的库，在设计时都充分考虑了其中的项与文档整体外观的协调性。 您可以使用这些库来插入表格、页眉、页脚、列表、封面以及其他文档构建基块。 您创建的图片、图表或关系图也将与当前的文档外观协调一致。</p><p class=\"ue_t\"><br /></p>'\r\n\r\n    },\r\n    {\r\n        \"pre\":\"pre2.png\",\r\n        'title':lang.resume,\r\n        'preHtml':'<h1 label=\"Title left\" name=\"tl\" style=\"border-bottom-color:#cccccc;border-bottom-width:2px;border-bottom-style:solid;padding:0px 4px 0px 0px;margin:0px 0px 10px;\"><span style=\"color:#e36c09;\" class=\" \">WEB前端开发简历</span></h1><table width=\"100%\" border=\"1\" bordercolor=\"#95B3D7\" style=\"border-collapse:collapse;\"><tbody><tr><td width=\"100\" style=\"text-align:center;\"><p><span style=\"background-color:transparent;\">插</span><br /></p><p>入</p><p>照</p><p>片</p></td><td><p><span style=\"background-color:transparent;\"> 联系电话：</span><span class=\"ue_t\" style=\"background-color:transparent;\">[键入您的电话]</span><br /></p><p><span style=\"background-color:transparent;\"> 电子邮件：</span><span class=\"ue_t\" style=\"background-color:transparent;\">[键入您的电子邮件地址]</span><br /></p><p><span style=\"background-color:transparent;\"> 家庭住址：</span><span class=\"ue_t\" style=\"background-color:transparent;\">[键入您的地址]</span><br /></p></td></tr></tbody></table><h3><span style=\"color:#E36C09;font-size:20px;\">目标职位</span></h3><p style=\"text-indent:2em;\" class=\" \">WEB前端研发工程师</p><h3><span style=\"color:#e36c09;font-size:20px;\">学历</span></h3><p><span style=\"display:none;line-height:0px;\" id=\"_baidu_bookmark_start_26\">﻿</span></p><ol style=\"list-style-type:decimal;\"><li><p><span class=\"ue_t\">[起止时间]</span> <span class=\"ue_t\">[学校名称] </span> <span class=\"ue_t\">[所学专业]</span> <span class=\"ue_t\">[所获学位]</span></p></li></ol><h3><span style=\"color:#e36c09;font-size:20px;\" class=\"ue_t\">工作经验</span></h3><p><br /></p>',\r\n        \"html\":'<h1 label=\"Title left\" name=\"tl\" style=\"border-bottom-color:#cccccc;border-bottom-width:2px;border-bottom-style:solid;padding:0px 4px 0px 0px;margin:0px 0px 10px;\"><span style=\"color:#e36c09;\" class=\"ue_t\">[此处键入简历标题]</span></h1><p><span style=\"color:#e36c09;\"><br /></span></p><table width=\"100%\" border=\"1\" bordercolor=\"#95B3D7\" style=\"border-collapse:collapse;\"><tbody><tr><td width=\"200\" style=\"text-align:center;\" class=\"ue_t\">【此处插入照片】</td><td><p><br /></p><p> 联系电话：<span class=\"ue_t\">[键入您的电话]</span></p><p><br /></p><p> 电子邮件：<span class=\"ue_t\">[键入您的电子邮件地址]</span></p><p><br /></p><p> 家庭住址：<span class=\"ue_t\">[键入您的地址]</span></p><p><br /></p></td></tr></tbody></table><h3><span style=\"color:#e36c09;font-size:20px;\">目标职位</span></h3><p style=\"text-indent:2em;\" class=\"ue_t\">[此处键入您的期望职位]</p><h3><span style=\"color:#e36c09;font-size:20px;\">学历</span></h3><p><span style=\"display:none;line-height:0px;\" id=\"_baidu_bookmark_start_26\">﻿</span></p><ol style=\"list-style-type:decimal;\"><li><p><span class=\"ue_t\">[键入起止时间]</span> <span class=\"ue_t\">[键入学校名称] </span> <span class=\"ue_t\">[键入所学专业]</span> <span class=\"ue_t\">[键入所获学位]</span></p></li><li><p><span class=\"ue_t\">[键入起止时间]</span> <span class=\"ue_t\">[键入学校名称]</span> <span class=\"ue_t\">[键入所学专业]</span> <span class=\"ue_t\">[键入所获学位]</span></p></li></ol><h3><span style=\"color:#e36c09;font-size:20px;\" class=\"ue_t\">工作经验</span></h3><ol style=\"list-style-type:decimal;\"><li><p><span class=\"ue_t\">[键入起止时间]</span> <span class=\"ue_t\">[键入公司名称]</span> <span class=\"ue_t\">[键入职位名称]</span> </p></li><ol style=\"list-style-type:lower-alpha;\"><li><p><span class=\"ue_t\">[键入负责项目]</span> <span class=\"ue_t\">[键入项目简介]</span></p></li><li><p><span class=\"ue_t\">[键入负责项目]</span> <span class=\"ue_t\">[键入项目简介]</span></p></li></ol><li><p><span class=\"ue_t\">[键入起止时间]</span> <span class=\"ue_t\">[键入公司名称]</span> <span class=\"ue_t\">[键入职位名称]</span> </p></li><ol style=\"list-style-type:lower-alpha;\"><li><p><span class=\"ue_t\">[键入负责项目]</span> <span class=\"ue_t\">[键入项目简介]</span></p></li></ol></ol><p><span style=\"color:#e36c09;font-size:20px;\">掌握技能</span></p><p style=\"text-indent:2em;\"> &nbsp;<span class=\"ue_t\">[这里可以键入您所掌握的技能]</span><br /></p>'\r\n\r\n    },\r\n    {\r\n        \"pre\":\"pre3.png\",\r\n        'title':lang.richText,\r\n        'preHtml':'<h1 label=\"Title center\" name=\"tc\" style=\"border-bottom-color:#cccccc;border-bottom-width:2px;border-bottom-style:solid;padding:0px 4px 0px 0px;text-align:center;margin:0px 0px 20px;\" class=\"ue_t\">[此处键入文章标题]</h1><p><img src=\"http://img.baidu.com/hi/youa/y_0034.gif\" width=\"150\" height=\"100\" border=\"0\" hspace=\"0\" vspace=\"0\" style=\"width:150px;height:100px;float:left;\" />图文混排方法</p><p>图片居左，文字围绕图片排版</p><p>方法：在文字前面插入图片，设置居左对齐，然后即可在右边输入多行文</p><p><br /></p><p><img src=\"http://img.baidu.com/hi/youa/y_0040.gif\" width=\"100\" height=\"100\" border=\"0\" hspace=\"0\" vspace=\"0\" style=\"width:100px;height:100px;float:right;\" /></p><p>还有没有什么其他的环绕方式呢？这里是居右环绕</p><p><br /></p><p>欢迎大家多多尝试，为UEditor提供更多高质量模板！</p>',\r\n        \"html\":'<p><br /></p><h1 label=\"Title center\" name=\"tc\" style=\"border-bottom-color:#cccccc;border-bottom-width:2px;border-bottom-style:solid;padding:0px 4px 0px 0px;text-align:center;margin:0px 0px 20px;\" class=\"ue_t\">[此处键入文章标题]</h1><p><img src=\"http://img.baidu.com/hi/youa/y_0034.gif\" width=\"300\" height=\"200\" border=\"0\" hspace=\"0\" vspace=\"0\" style=\"width:300px;height:200px;float:left;\" />图文混排方法</p><p>1. 图片居左，文字围绕图片排版</p><p>方法：在文字前面插入图片，设置居左对齐，然后即可在右边输入多行文本</p><p><br /></p><p>2. 图片居右，文字围绕图片排版</p><p>方法：在文字前面插入图片，设置居右对齐，然后即可在左边输入多行文本</p><p><br /></p><p>3. 图片居中环绕排版</p><p>方法：亲，这个真心没有办法。。。</p><p><br /></p><p><br /></p><p><img src=\"http://img.baidu.com/hi/youa/y_0040.gif\" width=\"300\" height=\"300\" border=\"0\" hspace=\"0\" vspace=\"0\" style=\"width:300px;height:300px;float:right;\" /></p><p>还有没有什么其他的环绕方式呢？这里是居右环绕</p><p><br /></p><p>欢迎大家多多尝试，为UEditor提供更多高质量模板！</p><p><br /></p><p>占位</p><p><br /></p><p>占位</p><p><br /></p><p>占位</p><p><br /></p><p>占位</p><p><br /></p><p>占位</p><p><br /></p><p><br /></p>'\r\n    },\r\n    {\r\n        \"pre\":\"pre4.png\",\r\n        'title':lang.sciPapers,\r\n        'preHtml':'<h2 style=\"border-bottom-color:#cccccc;border-bottom-width:2px;border-bottom-style:solid;padding:0px 4px 0px 0px;margin:0px 0px 10px;text-align:center;\" class=\"ue_t\">[键入文章标题]</h2><p><strong><span style=\"font-size:12px;\">摘要</span></strong><span style=\"font-size:12px;\" class=\"ue_t\">：这里可以输入很长很长很长很长很长很长很长很长很差的摘要</span></p><p style=\"line-height:1.5em;\"><strong>标题 1</strong></p><p style=\"text-indent:2em;\"><span style=\"font-size:14px;\" class=\"ue_t\">这里可以输入很多内容，可以图文混排，可以有列表等。</span></p><p style=\"line-height:1.5em;\"><strong>标题 2</strong></p><ol style=\"list-style-type:lower-alpha;\"><li><p class=\"ue_t\">列表 1</p></li><li><p class=\"ue_t\">列表 2</p></li><ol style=\"list-style-type:lower-roman;\"><li><p class=\"ue_t\">多级列表 1</p></li><li><p class=\"ue_t\">多级列表 2</p></li></ol><li><p class=\"ue_t\">列表 3<br /></p></li></ol><p style=\"line-height:1.5em;\"><strong>标题 3</strong></p><p style=\"text-indent:2em;\"><span style=\"font-size:14px;\" class=\"ue_t\">来个文字图文混排的</span></p><p style=\"text-indent:2em;\"><br /></p>',\r\n        'html':'<h2 style=\"border-bottom-color:#cccccc;border-bottom-width:2px;border-bottom-style:solid;padding:0px 4px 0px 0px;margin:0px 0px 10px;text-align:center;\" class=\"ue_t\">[键入文章标题]</h2><p><strong><span style=\"font-size:12px;\">摘要</span></strong><span style=\"font-size:12px;\" class=\"ue_t\">：这里可以输入很长很长很长很长很长很长很长很长很差的摘要</span></p><p style=\"line-height:1.5em;\"><strong>标题 1</strong></p><p style=\"text-indent:2em;\"><span style=\"font-size:14px;\" class=\"ue_t\">这里可以输入很多内容，可以图文混排，可以有列表等。</span></p><p style=\"line-height:1.5em;\"><strong>标题 2</strong></p><p style=\"text-indent:2em;\"><span style=\"font-size:14px;\" class=\"ue_t\">来个列表瞅瞅：</span></p><ol style=\"list-style-type:lower-alpha;\"><li><p class=\"ue_t\">列表 1</p></li><li><p class=\"ue_t\">列表 2</p></li><ol style=\"list-style-type:lower-roman;\"><li><p class=\"ue_t\">多级列表 1</p></li><li><p class=\"ue_t\">多级列表 2</p></li></ol><li><p class=\"ue_t\">列表 3<br /></p></li></ol><p style=\"line-height:1.5em;\"><strong>标题 3</strong></p><p style=\"text-indent:2em;\"><span style=\"font-size:14px;\" class=\"ue_t\">来个文字图文混排的</span></p><p style=\"text-indent:2em;\"><span style=\"font-size:14px;\" class=\"ue_t\">这里可以多行</span></p><p style=\"text-indent:2em;\"><span style=\"font-size:14px;\" class=\"ue_t\">右边是图片</span></p><p style=\"text-indent:2em;\"><span style=\"font-size:14px;\" class=\"ue_t\">绝对没有问题的，不信你也可以试试看</span></p><p><br /></p>'\r\n    }\r\n];"
  },
  {
    "path": "public/static/ueditor/dialogs/template/template.css",
    "content": ".wrap{ padding: 5px;font-size: 14px;}\r\n.left{width:425px;float: left;}\r\n.right{width:160px;border: 1px solid #ccc;float: right;padding: 5px;margin-right: 5px;}\r\n.right .pre{height: 332px;overflow-y: auto;}\r\n.right .preitem{border: white 1px solid;margin: 5px 0;padding: 2px 0;}\r\n.right .preitem:hover{background-color: lemonChiffon;cursor: pointer;border: #ccc 1px solid;}\r\n.right .preitem img{display: block;margin: 0 auto;width:100px;}\r\n.clear{clear: both;}\r\n.top{height:26px;line-height: 26px;padding: 5px;}\r\n.bottom{height:320px;width:100%;margin: 0 auto;}\r\n.transparent{ background: url(\"images/bg.gif\") repeat;}\r\n.bottom table tr td{border:1px dashed #ccc;}\r\n#colorPicker{width: 17px;height: 17px;border: 1px solid #CCC;display: inline-block;border-radius: 3px;box-shadow: 2px 2px 5px #D3D6DA;}\r\n.border_style1{padding:2px;border: 1px solid #ccc;border-radius: 5px;box-shadow:2px 2px 5px #d3d6da;}\r\np{margin: 5px 0}\r\ntable{clear:both;margin-bottom:10px;border-collapse:collapse;word-break:break-all;}\r\nli{clear:both}\r\nol{padding-left:40px; }"
  },
  {
    "path": "public/static/ueditor/dialogs/template/template.html",
    "content": "<!DOCTYPE HTML>\r\n<html>\r\n<head>\r\n    <title></title>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"template.css\">\r\n</head>\r\n<body>\r\n    <div class=\"wrap\">\r\n        <div class=\"left\">\r\n            <div class=\"top\">\r\n                <label><var id=\"lang_template_clear\"></var>：<input id=\"issave\" type=\"checkbox\"></label>\r\n            </div>\r\n            <div class=\"bottom border_style1\" id=\"preview\"></div>\r\n        </div>\r\n        <fieldset  class=\"right border_style1\">\r\n            <legend><var id=\"lang_template_select\"></var></legend>\r\n            <div class=\"pre\" id=\"preitem\"></div>\r\n        </fieldset>\r\n        <div class=\"clear\"></div>\r\n    </div>\r\n    <script type=\"text/javascript\" src=\"config.js\"></script>\r\n    <script type=\"text/javascript\" src=\"template.js\"></script>\r\n</body>\r\n</html>\r\n"
  },
  {
    "path": "public/static/ueditor/dialogs/template/template.js",
    "content": "/**\r\n * Created with JetBrains PhpStorm.\r\n * User: xuheng\r\n * Date: 12-8-8\r\n * Time: 下午2:09\r\n * To change this template use File | Settings | File Templates.\r\n */\r\n(function () {\r\n    var me = editor,\r\n            preview = $G( \"preview\" ),\r\n            preitem = $G( \"preitem\" ),\r\n            tmps = templates,\r\n            currentTmp;\r\n    var initPre = function () {\r\n        var str = \"\";\r\n        for ( var i = 0, tmp; tmp = tmps[i++]; ) {\r\n            str += '<div class=\"preitem\" onclick=\"pre(' + i + ')\"><img src=\"' + \"images/\" + tmp.pre + '\" ' + (tmp.title ? \"alt=\" + tmp.title + \" title=\" + tmp.title + \"\" : \"\") + '></div>';\r\n        }\r\n        preitem.innerHTML = str;\r\n    };\r\n    var pre = function ( n ) {\r\n        var tmp = tmps[n - 1];\r\n        currentTmp = tmp;\r\n        clearItem();\r\n        domUtils.setStyles( preitem.childNodes[n - 1], {\r\n            \"background-color\":\"lemonChiffon\",\r\n            \"border\":\"#ccc 1px solid\"\r\n        } );\r\n        preview.innerHTML = tmp.preHtml ? tmp.preHtml : \"\";\r\n    };\r\n    var clearItem = function () {\r\n        var items = preitem.children;\r\n        for ( var i = 0, item; item = items[i++]; ) {\r\n            domUtils.setStyles( item, {\r\n                \"background-color\":\"\",\r\n                \"border\":\"white 1px solid\"\r\n            } );\r\n        }\r\n    };\r\n    dialog.onok = function () {\r\n        if ( !$G( \"issave\" ).checked ){\r\n            me.execCommand( \"cleardoc\" );\r\n        }\r\n        var obj = {\r\n            html:currentTmp && currentTmp.html\r\n        };\r\n        me.execCommand( \"template\", obj );\r\n    };\r\n    initPre();\r\n    window.pre = pre;\r\n    pre(2)\r\n\r\n})();"
  },
  {
    "path": "public/static/ueditor/dialogs/video/video.css",
    "content": "@charset \"utf-8\";\r\n.wrapper{ width: 570px;_width:575px;margin: 10px auto; zoom:1;position: relative}\r\n.tabbody{height: 335px;}\r\n.tabbody .panel {\r\n    position: absolute;\r\n    width: 0;\r\n    height: 0;\r\n    background: #fff;\r\n    overflow: hidden;\r\n    display: none;\r\n}\r\n.tabbody .panel.focus {\r\n    width: 100%;\r\n    height: 335px;\r\n    display: block;\r\n}\r\n\r\n.tabbody .panel table td{vertical-align: middle;}\r\n#videoUrl {\r\n    width: 490px;\r\n    height: 21px;\r\n    line-height: 21px;\r\n    margin: 8px 5px;\r\n    background: #FFF;\r\n    border: 1px solid #d7d7d7;\r\n}\r\n#videoSearchTxt{margin-left:15px;background: #FFF;width:200px;height:21px;line-height:21px;border: 1px solid #d7d7d7;}\r\n#searchList{width: 570px;overflow: auto;zoom:1;height: 270px;}\r\n#searchList div{float: left;width: 120px;height: 135px;margin: 5px 15px;}\r\n#searchList img{margin: 2px 8px;cursor: pointer;border: 2px solid #fff} /*不用缩略图*/\r\n#searchList p{margin-left: 10px;}\r\n#videoType{\r\n    width: 65px;\r\n    height: 23px;\r\n    line-height: 22px;\r\n    border: 1px solid #d7d7d7;\r\n}\r\n#videoSearchBtn,#videoSearchReset{\r\n    /*width: 80px;*/\r\n    height: 25px;\r\n    line-height: 25px;\r\n    background: #eee;\r\n    border: 1px solid #d7d7d7;\r\n    cursor: pointer;\r\n    padding: 0 5px;\r\n}\r\n\r\n\r\n\r\n#preview{position: relative;width: 420px;padding:0;overflow: hidden; margin-left: 10px; _margin-left:5px; height: 280px;background-color: #ddd;float: left}\r\n#preview .previewMsg {position:absolute;top:0;margin:0;padding:0;height:280px;width:100%;background-color: #666;}\r\n#preview .previewMsg span{display:block;margin: 125px auto 0 auto;text-align:center;font-size:18px;color:#fff;}\r\n#preview .previewVideo {position:absolute;top:0;margin:0;padding:0;height:280px;width:100%;}\r\n.edui-video-wrapper fieldset{\r\n    border: 1px solid #ddd;\r\n    padding-left: 5px;\r\n    margin-bottom: 20px;\r\n    padding-bottom: 5px;\r\n    width: 115px;\r\n}\r\n\r\n#videoInfo {width: 120px;float: left;margin-left: 10px;_margin-left:7px;}\r\nfieldset{\r\n    border: 1px solid #ddd;\r\n    padding-left: 5px;\r\n    margin-bottom: 20px;\r\n    padding-bottom: 5px;\r\n    width: 115px;\r\n}\r\nfieldset legend{font-weight: bold;}\r\nfieldset p{line-height: 30px;}\r\nfieldset input.txt{\r\n    width: 65px;\r\n    height: 21px;\r\n    line-height: 21px;\r\n    margin: 8px 5px;\r\n    background: #FFF;\r\n    border: 1px solid #d7d7d7;\r\n}\r\nlabel.url{font-weight: bold;margin-left: 5px;color: #06c;}\r\n#videoFloat div{cursor:pointer;opacity: 0.5;filter: alpha(opacity = 50);margin:9px;_margin:5px;width:38px;height:36px;float:left;}\r\n#videoFloat .focus{opacity: 1;filter: alpha(opacity = 100)}\r\nspan.view{display: inline-block;width: 30px;float: right;cursor: pointer;color: blue}\r\n\r\n\r\n\r\n\r\n/* upload video */\r\n.tabbody #upload.panel {\r\n    width: 0;\r\n    height: 0;\r\n    overflow: hidden;\r\n    position: absolute !important;\r\n    clip: rect(1px, 1px, 1px, 1px);\r\n    background: #fff;\r\n    display: block;\r\n}\r\n.tabbody #upload.panel.focus {\r\n    width: 100%;\r\n    height: 335px;\r\n    display: block;\r\n    clip: auto;\r\n}\r\n#upload_alignment div{cursor:pointer;opacity: 0.5;filter: alpha(opacity = 50);margin:9px;_margin:5px;width:38px;height:36px;float:left;}\r\n#upload_alignment .focus{opacity: 1;filter: alpha(opacity = 100)}\r\n#upload_left { width:427px; float:left; }\r\n#upload_left .controller { height: 30px; clear: both; }\r\n#uploadVideoInfo{margin-top:10px;float:right;padding-right:8px;}\r\n\r\n#upload .queueList {\r\n    margin: 0;\r\n}\r\n\r\n#upload p {\r\n    margin: 0;\r\n}\r\n\r\n.element-invisible {\r\n    width: 0 !important;\r\n    height: 0 !important;\r\n    border: 0;\r\n    padding: 0;\r\n    margin: 0;\r\n    overflow: hidden;\r\n    position: absolute !important;\r\n    clip: rect(1px, 1px, 1px, 1px);\r\n}\r\n\r\n#upload .placeholder {\r\n    margin: 10px;\r\n    margin-right:0;\r\n    border: 2px dashed #e6e6e6;\r\n    *border: 0px dashed #e6e6e6;\r\n    height: 161px;\r\n    padding-top: 150px;\r\n    text-align: center;\r\n    width: 97%;\r\n    float: left;\r\n    background: url(./images/image.png) center 70px no-repeat;\r\n    color: #cccccc;\r\n    font-size: 18px;\r\n    position: relative;\r\n    top:0;\r\n    *margin-left: 0;\r\n    *left: 10px;\r\n}\r\n\r\n#upload .placeholder .webuploader-pick {\r\n    font-size: 18px;\r\n    background: #00b7ee;\r\n    border-radius: 3px;\r\n    line-height: 44px;\r\n    padding: 0 30px;\r\n    *width: 120px;\r\n    color: #fff;\r\n    display: inline-block;\r\n    margin: 0 auto 20px auto;\r\n    cursor: pointer;\r\n    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.1);\r\n}\r\n\r\n#upload .placeholder .webuploader-pick-hover {\r\n    background: #00a2d4;\r\n}\r\n\r\n\r\n#filePickerContainer {\r\n    text-align: center;\r\n}\r\n\r\n#upload .placeholder .flashTip {\r\n    color: #666666;\r\n    font-size: 12px;\r\n    position: absolute;\r\n    width: 100%;\r\n    text-align: center;\r\n    bottom: 20px;\r\n}\r\n\r\n#upload .placeholder .flashTip a {\r\n    color: #0785d1;\r\n    text-decoration: none;\r\n}\r\n\r\n#upload .placeholder .flashTip a:hover {\r\n    text-decoration: underline;\r\n}\r\n\r\n#upload .placeholder.webuploader-dnd-over {\r\n    border-color: #999999;\r\n}\r\n\r\n#upload .filelist {\r\n    list-style: none;\r\n    margin: 0;\r\n    padding: 0;\r\n    overflow-x: hidden;\r\n    overflow-y: auto;\r\n    position: relative;\r\n    height: 285px;\r\n}\r\n\r\n#upload .filelist:after {\r\n    content: '';\r\n    display: block;\r\n    width: 0;\r\n    height: 0;\r\n    overflow: hidden;\r\n    clear: both;\r\n}\r\n\r\n#upload .filelist li {\r\n    width: 113px;\r\n    height: 113px;\r\n    background: url(./images/bg.png);\r\n    text-align: center;\r\n    margin: 15px 0 0 20px;\r\n    *margin: 15px 0 0 15px;\r\n    position: relative;\r\n    display: block;\r\n    float: left;\r\n    overflow: hidden;\r\n    font-size: 12px;\r\n}\r\n\r\n#upload .filelist li p.log {\r\n    position: relative;\r\n    top: -45px;\r\n}\r\n\r\n#upload .filelist li p.title {\r\n    position: absolute;\r\n    top: 0;\r\n    left: 0;\r\n    width: 100%;\r\n    overflow: hidden;\r\n    white-space: nowrap;\r\n    text-overflow: ellipsis;\r\n    top: 5px;\r\n    text-indent: 5px;\r\n    text-align: left;\r\n}\r\n\r\n#upload .filelist li p.progress {\r\n    position: absolute;\r\n    width: 100%;\r\n    bottom: 0;\r\n    left: 0;\r\n    height: 8px;\r\n    overflow: hidden;\r\n    z-index: 50;\r\n    margin: 0;\r\n    border-radius: 0;\r\n    background: none;\r\n    -webkit-box-shadow: 0 0 0;\r\n}\r\n\r\n#upload .filelist li p.progress span {\r\n    display: none;\r\n    overflow: hidden;\r\n    width: 0;\r\n    height: 100%;\r\n    background: #1483d8 url(./images/progress.png) repeat-x;\r\n\r\n    -webit-transition: width 200ms linear;\r\n    -moz-transition: width 200ms linear;\r\n    -o-transition: width 200ms linear;\r\n    -ms-transition: width 200ms linear;\r\n    transition: width 200ms linear;\r\n\r\n    -webkit-animation: progressmove 2s linear infinite;\r\n    -moz-animation: progressmove 2s linear infinite;\r\n    -o-animation: progressmove 2s linear infinite;\r\n    -ms-animation: progressmove 2s linear infinite;\r\n    animation: progressmove 2s linear infinite;\r\n\r\n    -webkit-transform: translateZ(0);\r\n}\r\n\r\n@-webkit-keyframes progressmove {\r\n    0% {\r\n        background-position: 0 0;\r\n    }\r\n    100% {\r\n        background-position: 17px 0;\r\n    }\r\n}\r\n\r\n@-moz-keyframes progressmove {\r\n    0% {\r\n        background-position: 0 0;\r\n    }\r\n    100% {\r\n        background-position: 17px 0;\r\n    }\r\n}\r\n\r\n@keyframes progressmove {\r\n    0% {\r\n        background-position: 0 0;\r\n    }\r\n    100% {\r\n        background-position: 17px 0;\r\n    }\r\n}\r\n\r\n#upload .filelist li p.imgWrap {\r\n    position: relative;\r\n    z-index: 2;\r\n    line-height: 113px;\r\n    vertical-align: middle;\r\n    overflow: hidden;\r\n    width: 113px;\r\n    height: 113px;\r\n\r\n    -webkit-transform-origin: 50% 50%;\r\n    -moz-transform-origin: 50% 50%;\r\n    -o-transform-origin: 50% 50%;\r\n    -ms-transform-origin: 50% 50%;\r\n    transform-origin: 50% 50%;\r\n\r\n    -webit-transition: 200ms ease-out;\r\n    -moz-transition: 200ms ease-out;\r\n    -o-transition: 200ms ease-out;\r\n    -ms-transition: 200ms ease-out;\r\n    transition: 200ms ease-out;\r\n}\r\n#upload .filelist li p.imgWrap.notimage {\r\n    margin-top: 0;\r\n    width: 111px;\r\n    height: 111px;\r\n    border: 1px #eeeeee solid;\r\n}\r\n#upload .filelist li p.imgWrap.notimage i.file-preview {\r\n    margin-top: 15px;\r\n}\r\n\r\n#upload .filelist li img {\r\n    width: 100%;\r\n}\r\n\r\n#upload .filelist li p.error {\r\n    background: #f43838;\r\n    color: #fff;\r\n    position: absolute;\r\n    bottom: 0;\r\n    left: 0;\r\n    height: 28px;\r\n    line-height: 28px;\r\n    width: 100%;\r\n    z-index: 100;\r\n    display:none;\r\n}\r\n\r\n#upload .filelist li .success {\r\n    display: block;\r\n    position: absolute;\r\n    left: 0;\r\n    bottom: 0;\r\n    height: 40px;\r\n    width: 100%;\r\n    z-index: 200;\r\n    background: url(./images/success.png) no-repeat right bottom;\r\n    background-image: url(./images/success.gif) \\9;\r\n}\r\n\r\n#upload .filelist li.filePickerBlock {\r\n    width: 113px;\r\n    height: 113px;\r\n    background: url(./images/image.png) no-repeat center 12px;\r\n    border: 1px solid #eeeeee;\r\n    border-radius: 0;\r\n}\r\n#upload .filelist li.filePickerBlock div.webuploader-pick  {\r\n    width: 100%;\r\n    height: 100%;\r\n    margin: 0;\r\n    padding: 0;\r\n    opacity: 0;\r\n    background: none;\r\n    font-size: 0;\r\n}\r\n\r\n#upload .filelist div.file-panel {\r\n    position: absolute;\r\n    height: 0;\r\n    filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#80000000', endColorstr='#80000000') \\0;\r\n    background: rgba(0, 0, 0, 0.5);\r\n    width: 100%;\r\n    top: 0;\r\n    left: 0;\r\n    overflow: hidden;\r\n    z-index: 300;\r\n}\r\n\r\n#upload .filelist div.file-panel span {\r\n    width: 24px;\r\n    height: 24px;\r\n    display: inline;\r\n    float: right;\r\n    text-indent: -9999px;\r\n    overflow: hidden;\r\n    background: url(./images/icons.png) no-repeat;\r\n    background: url(./images/icons.gif) no-repeat \\9;\r\n    margin: 5px 1px 1px;\r\n    cursor: pointer;\r\n    -webkit-tap-highlight-color: rgba(0,0,0,0);\r\n    -webkit-user-select: none;\r\n    -moz-user-select: none;\r\n    -ms-user-select: none;\r\n    user-select: none;\r\n}\r\n\r\n#upload .filelist div.file-panel span.rotateLeft {\r\n    display:none;\r\n    background-position: 0 -24px;\r\n}\r\n\r\n#upload .filelist div.file-panel span.rotateLeft:hover {\r\n    background-position: 0 0;\r\n}\r\n\r\n#upload .filelist div.file-panel span.rotateRight {\r\n    display:none;\r\n    background-position: -24px -24px;\r\n}\r\n\r\n#upload .filelist div.file-panel span.rotateRight:hover {\r\n    background-position: -24px 0;\r\n}\r\n\r\n#upload .filelist div.file-panel span.cancel {\r\n    background-position: -48px -24px;\r\n}\r\n\r\n#upload .filelist div.file-panel span.cancel:hover {\r\n    background-position: -48px 0;\r\n}\r\n\r\n#upload .statusBar {\r\n    height: 45px;\r\n    border-bottom: 1px solid #dadada;\r\n    margin: 0 10px;\r\n    padding: 0;\r\n    line-height: 45px;\r\n    vertical-align: middle;\r\n    position: relative;\r\n}\r\n\r\n#upload .statusBar .progress {\r\n    border: 1px solid #1483d8;\r\n    width: 198px;\r\n    background: #fff;\r\n    height: 18px;\r\n    position: absolute;\r\n    top: 12px;\r\n    display: none;\r\n    text-align: center;\r\n    line-height: 18px;\r\n    color: #6dbfff;\r\n    margin: 0 10px 0 0;\r\n}\r\n#upload .statusBar .progress span.percentage {\r\n    width: 0;\r\n    height: 100%;\r\n    left: 0;\r\n    top: 0;\r\n    background: #1483d8;\r\n    position: absolute;\r\n}\r\n#upload .statusBar .progress span.text {\r\n    position: relative;\r\n    z-index: 10;\r\n}\r\n\r\n#upload .statusBar .info {\r\n    display: inline-block;\r\n    font-size: 14px;\r\n    color: #666666;\r\n}\r\n\r\n#upload .statusBar .btns {\r\n    position: absolute;\r\n    top: 7px;\r\n    right: 0;\r\n    line-height: 30px;\r\n}\r\n\r\n#filePickerBtn {\r\n    display: inline-block;\r\n    float: left;\r\n}\r\n#upload .statusBar .btns .webuploader-pick,\r\n#upload .statusBar .btns .uploadBtn,\r\n#upload .statusBar .btns .uploadBtn.state-uploading,\r\n#upload .statusBar .btns .uploadBtn.state-paused {\r\n    background: #ffffff;\r\n    border: 1px solid #cfcfcf;\r\n    color: #565656;\r\n    padding: 0 18px;\r\n    display: inline-block;\r\n    border-radius: 3px;\r\n    margin-left: 10px;\r\n    cursor: pointer;\r\n    font-size: 14px;\r\n    float: left;\r\n    -webkit-user-select: none;\r\n    -moz-user-select: none;\r\n    -ms-user-select: none;\r\n    user-select: none;\r\n}\r\n#upload .statusBar .btns .webuploader-pick-hover,\r\n#upload .statusBar .btns .uploadBtn:hover,\r\n#upload .statusBar .btns .uploadBtn.state-uploading:hover,\r\n#upload .statusBar .btns .uploadBtn.state-paused:hover {\r\n    background: #f0f0f0;\r\n}\r\n\r\n#upload .statusBar .btns .uploadBtn,\r\n#upload .statusBar .btns .uploadBtn.state-paused{\r\n    background: #00b7ee;\r\n    color: #fff;\r\n    border-color: transparent;\r\n}\r\n#upload .statusBar .btns .uploadBtn:hover,\r\n#upload .statusBar .btns .uploadBtn.state-paused:hover{\r\n    background: #00a2d4;\r\n}\r\n\r\n#upload .statusBar .btns .uploadBtn.disabled {\r\n    pointer-events: none;\r\n    filter:alpha(opacity=60);\r\n    -moz-opacity:0.6;\r\n    -khtml-opacity: 0.6;\r\n    opacity: 0.6;\r\n}\r\n\r\n\r\n/* 在线文件的文件预览图标 */\r\ni.file-preview {\r\n    display: block;\r\n    margin: 10px auto;\r\n    width: 70px;\r\n    height: 70px;\r\n    background-image: url(\"./images/file-icons.png\");\r\n    background-image: url(\"./images/file-icons.gif\") \\9;\r\n    background-position: -140px center;\r\n    background-repeat: no-repeat;\r\n}\r\ni.file-preview.file-type-dir{\r\n    background-position: 0 center;\r\n}\r\ni.file-preview.file-type-file{\r\n    background-position: -140px center;\r\n}\r\ni.file-preview.file-type-filelist{\r\n    background-position: -210px center;\r\n}\r\ni.file-preview.file-type-zip,\r\ni.file-preview.file-type-rar,\r\ni.file-preview.file-type-7z,\r\ni.file-preview.file-type-tar,\r\ni.file-preview.file-type-gz,\r\ni.file-preview.file-type-bz2{\r\n    background-position: -280px center;\r\n}\r\ni.file-preview.file-type-xls,\r\ni.file-preview.file-type-xlsx{\r\n    background-position: -350px center;\r\n}\r\ni.file-preview.file-type-doc,\r\ni.file-preview.file-type-docx{\r\n    background-position: -420px center;\r\n}\r\ni.file-preview.file-type-ppt,\r\ni.file-preview.file-type-pptx{\r\n    background-position: -490px center;\r\n}\r\ni.file-preview.file-type-vsd{\r\n    background-position: -560px center;\r\n}\r\ni.file-preview.file-type-pdf{\r\n    background-position: -630px center;\r\n}\r\ni.file-preview.file-type-txt,\r\ni.file-preview.file-type-md,\r\ni.file-preview.file-type-json,\r\ni.file-preview.file-type-htm,\r\ni.file-preview.file-type-xml,\r\ni.file-preview.file-type-html,\r\ni.file-preview.file-type-js,\r\ni.file-preview.file-type-css,\r\ni.file-preview.file-type-php,\r\ni.file-preview.file-type-jsp,\r\ni.file-preview.file-type-asp{\r\n    background-position: -700px center;\r\n}\r\ni.file-preview.file-type-apk{\r\n    background-position: -770px center;\r\n}\r\ni.file-preview.file-type-exe{\r\n    background-position: -840px center;\r\n}\r\ni.file-preview.file-type-ipa{\r\n    background-position: -910px center;\r\n}\r\ni.file-preview.file-type-mp4,\r\ni.file-preview.file-type-swf,\r\ni.file-preview.file-type-mkv,\r\ni.file-preview.file-type-avi,\r\ni.file-preview.file-type-flv,\r\ni.file-preview.file-type-mov,\r\ni.file-preview.file-type-mpg,\r\ni.file-preview.file-type-mpeg,\r\ni.file-preview.file-type-ogv,\r\ni.file-preview.file-type-webm,\r\ni.file-preview.file-type-rm,\r\ni.file-preview.file-type-rmvb{\r\n    background-position: -980px center;\r\n}\r\ni.file-preview.file-type-ogg,\r\ni.file-preview.file-type-wav,\r\ni.file-preview.file-type-wmv,\r\ni.file-preview.file-type-mid,\r\ni.file-preview.file-type-mp3{\r\n    background-position: -1050px center;\r\n}\r\ni.file-preview.file-type-jpg,\r\ni.file-preview.file-type-jpeg,\r\ni.file-preview.file-type-gif,\r\ni.file-preview.file-type-bmp,\r\ni.file-preview.file-type-png,\r\ni.file-preview.file-type-psd{\r\n    background-position: -140px center;\r\n}"
  },
  {
    "path": "public/static/ueditor/dialogs/video/video.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n        \"http://www.w3.org/TR/html4/loose.dtd\">\r\n<html>\r\n<head>\r\n    <title></title>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <link rel=\"stylesheet\" type=\"text/css\" href=\"video.css\" />\r\n</head>\r\n<body>\r\n<div class=\"wrapper\">\r\n    <div id=\"videoTab\">\r\n        <div id=\"tabHeads\" class=\"tabhead\">\r\n            <span tabSrc=\"video\" class=\"focus\" data-content-id=\"video\"><var id=\"lang_tab_insertV\"></var></span>\r\n            <span tabSrc=\"upload\" data-content-id=\"upload\"><var id=\"lang_tab_uploadV\"></var></span>\r\n        </div>\r\n        <div id=\"tabBodys\" class=\"tabbody\">\r\n            <div id=\"video\" class=\"panel focus\">\r\n               <table><tr><td><label for=\"videoUrl\" class=\"url\"><var id=\"lang_video_url\"></var></label></td><td><input id=\"videoUrl\" type=\"text\"></td></tr></table>\r\n               <div id=\"preview\"></div>\r\n               <div id=\"videoInfo\">\r\n                   <fieldset>\r\n                       <legend><var id=\"lang_video_size\"></var></legend>\r\n                       <table>\r\n                           <tr><td><label for=\"videoWidth\"><var id=\"lang_videoW\"></var></label></td><td><input class=\"txt\" id=\"videoWidth\" type=\"text\"/></td></tr>\r\n                           <tr><td><label for=\"videoHeight\"><var id=\"lang_videoH\"></var></label></td><td><input class=\"txt\" id=\"videoHeight\" type=\"text\"/></td></tr>\r\n                       </table>\r\n                   </fieldset>\r\n                   <fieldset>\r\n                      <legend><var id=\"lang_alignment\"></var></legend>\r\n                      <div id=\"videoFloat\"></div>\r\n                  </fieldset>\r\n               </div>\r\n            </div>\r\n            <div id=\"upload\" class=\"panel\">\r\n                <div id=\"upload_left\">\r\n                    <div id=\"queueList\" class=\"queueList\">\r\n                        <div class=\"statusBar element-invisible\">\r\n                            <div class=\"progress\">\r\n                                <span class=\"text\">0%</span>\r\n                                <span class=\"percentage\"></span>\r\n                            </div><div class=\"info\"></div>\r\n                            <div class=\"btns\">\r\n                                <div id=\"filePickerBtn\"></div>\r\n                                <div class=\"uploadBtn\"><var id=\"lang_start_upload\"></var></div>\r\n                            </div>\r\n                        </div>\r\n                        <div id=\"dndArea\" class=\"placeholder\">\r\n                            <div class=\"filePickerContainer\">\r\n                                <div id=\"filePickerReady\"></div>\r\n                            </div>\r\n                        </div>\r\n                        <ul class=\"filelist element-invisible\">\r\n                            <li id=\"filePickerBlock\" class=\"filePickerBlock\"></li>\r\n                        </ul>\r\n                    </div>\r\n                </div>\r\n                <div id=\"uploadVideoInfo\">\r\n                    <fieldset>\r\n                        <legend><var id=\"lang_upload_size\"></var></legend>\r\n                        <table>\r\n                            <tr><td><label><var id=\"lang_upload_width\"></var></label></td><td><input class=\"txt\" id=\"upload_width\" type=\"text\"/></td></tr>\r\n                            <tr><td><label><var id=\"lang_upload_height\"></var></label></td><td><input class=\"txt\" id=\"upload_height\" type=\"text\"/></td></tr>\r\n                        </table>\r\n                    </fieldset>\r\n                    <fieldset>\r\n                        <legend><var id=\"lang_upload_alignment\"></var></legend>\r\n                        <div id=\"upload_alignment\"></div>\r\n                    </fieldset>\r\n                </div>\r\n            </div>\r\n        </div>\r\n    </div>\r\n</div>\r\n\r\n<!-- jquery -->\r\n<script type=\"text/javascript\" src=\"../../third-party/jquery-1.10.2.min.js\"></script>\r\n\r\n<!-- webuploader -->\r\n<script type=\"text/javascript\" src=\"../../third-party/webuploader/webuploader.min.js\"></script>\r\n<link rel=\"stylesheet\" type=\"text/css\" href=\"../../third-party/webuploader/webuploader.css\">\r\n\r\n<!-- video -->\r\n<script type=\"text/javascript\" src=\"video.js\"></script>\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/video/video.js",
    "content": "/**\r\n * Created by JetBrains PhpStorm.\r\n * User: taoqili\r\n * Date: 12-2-20\r\n * Time: 上午11:19\r\n * To change this template use File | Settings | File Templates.\r\n */\r\n\r\n(function(){\r\n\r\n    var video = {},\r\n        uploadVideoList = [],\r\n        isModifyUploadVideo = false,\r\n        uploadFile;\r\n\r\n    window.onload = function(){\r\n        $focus($G(\"videoUrl\"));\r\n        initTabs();\r\n        initVideo();\r\n        initUpload();\r\n    };\r\n\r\n    /* 初始化tab标签 */\r\n    function initTabs(){\r\n        var tabs = $G('tabHeads').children;\r\n        for (var i = 0; i < tabs.length; i++) {\r\n            domUtils.on(tabs[i], \"click\", function (e) {\r\n                var j, bodyId, target = e.target || e.srcElement;\r\n                for (j = 0; j < tabs.length; j++) {\r\n                    bodyId = tabs[j].getAttribute('data-content-id');\r\n                    if(tabs[j] == target){\r\n                        domUtils.addClass(tabs[j], 'focus');\r\n                        domUtils.addClass($G(bodyId), 'focus');\r\n                    }else {\r\n                        domUtils.removeClasses(tabs[j], 'focus');\r\n                        domUtils.removeClasses($G(bodyId), 'focus');\r\n                    }\r\n                }\r\n            });\r\n        }\r\n    }\r\n\r\n    function initVideo(){\r\n        createAlignButton( [\"videoFloat\", \"upload_alignment\"] );\r\n        addUrlChangeListener($G(\"videoUrl\"));\r\n        addOkListener();\r\n\r\n        //编辑视频时初始化相关信息\r\n        (function(){\r\n            var img = editor.selection.getRange().getClosedNode(),url;\r\n            if(img && img.className){\r\n                var hasFakedClass = (img.className == \"edui-faked-video\"),\r\n                    hasUploadClass = img.className.indexOf(\"edui-upload-video\")!=-1;\r\n                if(hasFakedClass || hasUploadClass) {\r\n                    $G(\"videoUrl\").value = url = img.getAttribute(\"_url\");\r\n                    $G(\"videoWidth\").value = img.width;\r\n                    $G(\"videoHeight\").value = img.height;\r\n                    var align = domUtils.getComputedStyle(img,\"float\"),\r\n                        parentAlign = domUtils.getComputedStyle(img.parentNode,\"text-align\");\r\n                    updateAlignButton(parentAlign===\"center\"?\"center\":align);\r\n                }\r\n                if(hasUploadClass) {\r\n                    isModifyUploadVideo = true;\r\n                }\r\n            }\r\n            createPreviewVideo(url);\r\n        })();\r\n    }\r\n\r\n    /**\r\n     * 监听确认和取消两个按钮事件，用户执行插入或者清空正在播放的视频实例操作\r\n     */\r\n    function addOkListener(){\r\n        dialog.onok = function(){\r\n            $G(\"preview\").innerHTML = \"\";\r\n            var currentTab =  findFocus(\"tabHeads\",\"tabSrc\");\r\n            switch(currentTab){\r\n                case \"video\":\r\n                    return insertSingle();\r\n                    break;\r\n                case \"videoSearch\":\r\n                    return insertSearch(\"searchList\");\r\n                    break;\r\n                case \"upload\":\r\n                    return insertUpload();\r\n                    break;\r\n            }\r\n        };\r\n        dialog.oncancel = function(){\r\n            $G(\"preview\").innerHTML = \"\";\r\n        };\r\n    }\r\n\r\n    /**\r\n     * 依据传入的align值更新按钮信息\r\n     * @param align\r\n     */\r\n    function updateAlignButton( align ) {\r\n        var aligns = $G( \"videoFloat\" ).children;\r\n        for ( var i = 0, ci; ci = aligns[i++]; ) {\r\n            if ( ci.getAttribute( \"name\" ) == align ) {\r\n                if ( ci.className !=\"focus\" ) {\r\n                    ci.className = \"focus\";\r\n                }\r\n            } else {\r\n                if ( ci.className ==\"focus\" ) {\r\n                    ci.className = \"\";\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 将单个视频信息插入编辑器中\r\n     */\r\n    function insertSingle(){\r\n        var width = $G(\"videoWidth\"),\r\n            height = $G(\"videoHeight\"),\r\n            url=$G('videoUrl').value,\r\n            align = findFocus(\"videoFloat\",\"name\");\r\n        if(!url) return false;\r\n        if ( !checkNum( [width, height] ) ) return false;\r\n        editor.execCommand('insertvideo', {\r\n            url: convert_url(url),\r\n            width: width.value,\r\n            height: height.value,\r\n            align: align\r\n        }, isModifyUploadVideo ? 'upload':null);\r\n    }\r\n\r\n    /**\r\n     * 将元素id下的所有代表视频的图片插入编辑器中\r\n     * @param id\r\n     */\r\n    function insertSearch(id){\r\n        var imgs = domUtils.getElementsByTagName($G(id),\"img\"),\r\n            videoObjs=[];\r\n        for(var i=0,img; img=imgs[i++];){\r\n            if(img.getAttribute(\"selected\")){\r\n                videoObjs.push({\r\n                    url:img.getAttribute(\"ue_video_url\"),\r\n                    width:420,\r\n                    height:280,\r\n                    align:\"none\"\r\n                });\r\n            }\r\n        }\r\n        editor.execCommand('insertvideo',videoObjs);\r\n    }\r\n\r\n    /**\r\n     * 找到id下具有focus类的节点并返回该节点下的某个属性\r\n     * @param id\r\n     * @param returnProperty\r\n     */\r\n    function findFocus( id, returnProperty ) {\r\n        var tabs = $G( id ).children,\r\n                property;\r\n        for ( var i = 0, ci; ci = tabs[i++]; ) {\r\n            if ( ci.className==\"focus\" ) {\r\n                property = ci.getAttribute( returnProperty );\r\n                break;\r\n            }\r\n        }\r\n        return property;\r\n    }\r\n    function convert_url(url){\r\n        if ( !url ) return '';\r\n        url = utils.trim(url)\r\n            .replace(/v\\.youku\\.com\\/v_show\\/id_([\\w\\-=]+)\\.html/i, 'player.youku.com/player.php/sid/$1/v.swf')\r\n            .replace(/(www\\.)?youtube\\.com\\/watch\\?v=([\\w\\-]+)/i, \"www.youtube.com/v/$2\")\r\n            .replace(/youtu.be\\/(\\w+)$/i, \"www.youtube.com/v/$1\")\r\n            .replace(/v\\.ku6\\.com\\/.+\\/([\\w\\.]+)\\.html.*$/i, \"player.ku6.com/refer/$1/v.swf\")\r\n            .replace(/www\\.56\\.com\\/u\\d+\\/v_([\\w\\-]+)\\.html/i, \"player.56.com/v_$1.swf\")\r\n            .replace(/www.56.com\\/w\\d+\\/play_album\\-aid\\-\\d+_vid\\-([^.]+)\\.html/i, \"player.56.com/v_$1.swf\")\r\n            .replace(/v\\.pps\\.tv\\/play_([\\w]+)\\.html.*$/i, \"player.pps.tv/player/sid/$1/v.swf\")\r\n            .replace(/www\\.letv\\.com\\/ptv\\/vplay\\/([\\d]+)\\.html.*$/i, \"i7.imgs.letv.com/player/swfPlayer.swf?id=$1&autoplay=0\")\r\n            .replace(/www\\.tudou\\.com\\/programs\\/view\\/([\\w\\-]+)\\/?/i, \"www.tudou.com/v/$1\")\r\n            .replace(/v\\.qq\\.com\\/cover\\/[\\w]+\\/[\\w]+\\/([\\w]+)\\.html/i, \"static.video.qq.com/TPout.swf?vid=$1\")\r\n            .replace(/v\\.qq\\.com\\/.+[\\?\\&]vid=([^&]+).*$/i, \"static.video.qq.com/TPout.swf?vid=$1\")\r\n            .replace(/my\\.tv\\.sohu\\.com\\/[\\w]+\\/[\\d]+\\/([\\d]+)\\.shtml.*$/i, \"share.vrs.sohu.com/my/v.swf&id=$1\");\r\n\r\n        return url;\r\n    }\r\n\r\n    /**\r\n      * 检测传入的所有input框中输入的长宽是否是正数\r\n      * @param nodes input框集合，\r\n      */\r\n     function checkNum( nodes ) {\r\n         for ( var i = 0, ci; ci = nodes[i++]; ) {\r\n             var value = ci.value;\r\n             if ( !isNumber( value ) && value) {\r\n                 alert( lang.numError );\r\n                 ci.value = \"\";\r\n                 ci.focus();\r\n                 return false;\r\n             }\r\n         }\r\n         return true;\r\n     }\r\n\r\n    /**\r\n     * 数字判断\r\n     * @param value\r\n     */\r\n    function isNumber( value ) {\r\n        return /(0|^[1-9]\\d*$)/.test( value );\r\n    }\r\n\r\n    /**\r\n      * 创建图片浮动选择按钮\r\n      * @param ids\r\n      */\r\n     function createAlignButton( ids ) {\r\n         for ( var i = 0, ci; ci = ids[i++]; ) {\r\n             var floatContainer = $G( ci ),\r\n                     nameMaps = {\"none\":lang['default'], \"left\":lang.floatLeft, \"right\":lang.floatRight, \"center\":lang.block};\r\n             for ( var j in nameMaps ) {\r\n                 var div = document.createElement( \"div\" );\r\n                 div.setAttribute( \"name\", j );\r\n                 if ( j == \"none\" ) div.className=\"focus\";\r\n                 div.style.cssText = \"background:url(images/\" + j + \"_focus.jpg);\";\r\n                 div.setAttribute( \"title\", nameMaps[j] );\r\n                 floatContainer.appendChild( div );\r\n             }\r\n             switchSelect( ci );\r\n         }\r\n     }\r\n\r\n    /**\r\n     * 选择切换\r\n     * @param selectParentId\r\n     */\r\n    function switchSelect( selectParentId ) {\r\n        var selects = $G( selectParentId ).children;\r\n        for ( var i = 0, ci; ci = selects[i++]; ) {\r\n            domUtils.on( ci, \"click\", function () {\r\n                for ( var j = 0, cj; cj = selects[j++]; ) {\r\n                    cj.className = \"\";\r\n                    cj.removeAttribute && cj.removeAttribute( \"class\" );\r\n                }\r\n                this.className = \"focus\";\r\n            } )\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 监听url改变事件\r\n     * @param url\r\n     */\r\n    function addUrlChangeListener(url){\r\n        if (browser.ie) {\r\n            url.onpropertychange = function () {\r\n                createPreviewVideo( this.value );\r\n            }\r\n        } else {\r\n            url.addEventListener( \"input\", function () {\r\n                createPreviewVideo( this.value );\r\n            }, false );\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 根据url生成视频预览\r\n     * @param url\r\n     */\r\n    function createPreviewVideo(url){\r\n        if ( !url )return;\r\n\r\n        var conUrl = convert_url(url);\r\n\r\n        conUrl = utils.unhtmlForUrl(conUrl);\r\n\r\n        $G(\"preview\").innerHTML = '<div class=\"previewMsg\"><span>'+lang.urlError+'</span></div>'+\r\n        '<embed class=\"previewVideo\" type=\"application/x-shockwave-flash\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\"' +\r\n            ' src=\"' + conUrl + '\"' +\r\n            ' width=\"' + 420  + '\"' +\r\n            ' height=\"' + 280  + '\"' +\r\n            ' wmode=\"transparent\" play=\"true\" loop=\"false\" menu=\"false\" allowscriptaccess=\"never\" allowfullscreen=\"true\" >' +\r\n        '</embed>';\r\n    }\r\n\r\n\r\n    /* 插入上传视频 */\r\n    function insertUpload(){\r\n        var videoObjs=[],\r\n            uploadDir = editor.getOpt('videoUrlPrefix'),\r\n            width = parseInt($G('upload_width').value, 10) || 420,\r\n            height = parseInt($G('upload_height').value, 10) || 280,\r\n            align = findFocus(\"upload_alignment\",\"name\") || 'none';\r\n        for(var key in uploadVideoList) {\r\n            var file = uploadVideoList[key];\r\n            videoObjs.push({\r\n                url: uploadDir + file.url,\r\n                width:width,\r\n                height:height,\r\n                align:align\r\n            });\r\n        }\r\n\r\n        var count = uploadFile.getQueueCount();\r\n        if (count) {\r\n            $('.info', '#queueList').html('<span style=\"color:red;\">' + '还有2个未上传文件'.replace(/[\\d]/, count) + '</span>');\r\n            return false;\r\n        } else {\r\n            editor.execCommand('insertvideo', videoObjs, 'upload');\r\n        }\r\n    }\r\n\r\n    /*初始化上传标签*/\r\n    function initUpload(){\r\n        uploadFile = new UploadFile('queueList');\r\n    }\r\n\r\n\r\n    /* 上传附件 */\r\n    function UploadFile(target) {\r\n        this.$wrap = target.constructor == String ? $('#' + target) : $(target);\r\n        this.init();\r\n    }\r\n    UploadFile.prototype = {\r\n        init: function () {\r\n            this.fileList = [];\r\n            this.initContainer();\r\n            this.initUploader();\r\n        },\r\n        initContainer: function () {\r\n            this.$queue = this.$wrap.find('.filelist');\r\n        },\r\n        /* 初始化容器 */\r\n        initUploader: function () {\r\n            var _this = this,\r\n                $ = jQuery,    // just in case. Make sure it's not an other libaray.\r\n                $wrap = _this.$wrap,\r\n            // 图片容器\r\n                $queue = $wrap.find('.filelist'),\r\n            // 状态栏，包括进度和控制按钮\r\n                $statusBar = $wrap.find('.statusBar'),\r\n            // 文件总体选择信息。\r\n                $info = $statusBar.find('.info'),\r\n            // 上传按钮\r\n                $upload = $wrap.find('.uploadBtn'),\r\n            // 上传按钮\r\n                $filePickerBtn = $wrap.find('.filePickerBtn'),\r\n            // 上传按钮\r\n                $filePickerBlock = $wrap.find('.filePickerBlock'),\r\n            // 没选择文件之前的内容。\r\n                $placeHolder = $wrap.find('.placeholder'),\r\n            // 总体进度条\r\n                $progress = $statusBar.find('.progress').hide(),\r\n            // 添加的文件数量\r\n                fileCount = 0,\r\n            // 添加的文件总大小\r\n                fileSize = 0,\r\n            // 优化retina, 在retina下这个值是2\r\n                ratio = window.devicePixelRatio || 1,\r\n            // 缩略图大小\r\n                thumbnailWidth = 113 * ratio,\r\n                thumbnailHeight = 113 * ratio,\r\n            // 可能有pedding, ready, uploading, confirm, done.\r\n                state = '',\r\n            // 所有文件的进度信息，key为file id\r\n                percentages = {},\r\n                supportTransition = (function () {\r\n                    var s = document.createElement('p').style,\r\n                        r = 'transition' in s ||\r\n                            'WebkitTransition' in s ||\r\n                            'MozTransition' in s ||\r\n                            'msTransition' in s ||\r\n                            'OTransition' in s;\r\n                    s = null;\r\n                    return r;\r\n                })(),\r\n            // WebUploader实例\r\n                uploader,\r\n                actionUrl = editor.getActionUrl(editor.getOpt('videoActionName')),\r\n                fileMaxSize = editor.getOpt('videoMaxSize'),\r\n                acceptExtensions = (editor.getOpt('videoAllowFiles') || []).join('').replace(/\\./g, ',').replace(/^[,]/, '');;\r\n\r\n            if (!WebUploader.Uploader.support()) {\r\n                $('#filePickerReady').after($('<div>').html(lang.errorNotSupport)).hide();\r\n                return;\r\n            } else if (!editor.getOpt('videoActionName')) {\r\n                $('#filePickerReady').after($('<div>').html(lang.errorLoadConfig)).hide();\r\n                return;\r\n            }\r\n\r\n            uploader = _this.uploader = WebUploader.create({\r\n                pick: {\r\n                    id: '#filePickerReady',\r\n                    label: lang.uploadSelectFile\r\n                },\r\n                swf: '../../third-party/webuploader/Uploader.swf',\r\n                server: actionUrl,\r\n                fileVal: editor.getOpt('videoFieldName'),\r\n                duplicate: true,\r\n                fileSingleSizeLimit: fileMaxSize,\r\n                compress: false\r\n            });\r\n            uploader.addButton({\r\n                id: '#filePickerBlock'\r\n            });\r\n            uploader.addButton({\r\n                id: '#filePickerBtn',\r\n                label: lang.uploadAddFile\r\n            });\r\n\r\n            setState('pedding');\r\n\r\n            // 当有文件添加进来时执行，负责view的创建\r\n            function addFile(file) {\r\n                var $li = $('<li id=\"' + file.id + '\">' +\r\n                        '<p class=\"title\">' + file.name + '</p>' +\r\n                        '<p class=\"imgWrap\"></p>' +\r\n                        '<p class=\"progress\"><span></span></p>' +\r\n                        '</li>'),\r\n\r\n                    $btns = $('<div class=\"file-panel\">' +\r\n                        '<span class=\"cancel\">' + lang.uploadDelete + '</span>' +\r\n                        '<span class=\"rotateRight\">' + lang.uploadTurnRight + '</span>' +\r\n                        '<span class=\"rotateLeft\">' + lang.uploadTurnLeft + '</span></div>').appendTo($li),\r\n                    $prgress = $li.find('p.progress span'),\r\n                    $wrap = $li.find('p.imgWrap'),\r\n                    $info = $('<p class=\"error\"></p>').hide().appendTo($li),\r\n\r\n                    showError = function (code) {\r\n                        switch (code) {\r\n                            case 'exceed_size':\r\n                                text = lang.errorExceedSize;\r\n                                break;\r\n                            case 'interrupt':\r\n                                text = lang.errorInterrupt;\r\n                                break;\r\n                            case 'http':\r\n                                text = lang.errorHttp;\r\n                                break;\r\n                            case 'not_allow_type':\r\n                                text = lang.errorFileType;\r\n                                break;\r\n                            default:\r\n                                text = lang.errorUploadRetry;\r\n                                break;\r\n                        }\r\n                        $info.text(text).show();\r\n                    };\r\n\r\n                if (file.getStatus() === 'invalid') {\r\n                    showError(file.statusText);\r\n                } else {\r\n                    $wrap.text(lang.uploadPreview);\r\n                    if ('|png|jpg|jpeg|bmp|gif|'.indexOf('|'+file.ext.toLowerCase()+'|') == -1) {\r\n                        $wrap.empty().addClass('notimage').append('<i class=\"file-preview file-type-' + file.ext.toLowerCase() + '\"></i>' +\r\n                            '<span class=\"file-title\">' + file.name + '</span>');\r\n                    } else {\r\n                        if (browser.ie && browser.version <= 7) {\r\n                            $wrap.text(lang.uploadNoPreview);\r\n                        } else {\r\n                            uploader.makeThumb(file, function (error, src) {\r\n                                if (error || !src || (/^data:/.test(src) && browser.ie && browser.version <= 7)) {\r\n                                    $wrap.text(lang.uploadNoPreview);\r\n                                } else {\r\n                                    var $img = $('<img src=\"' + src + '\">');\r\n                                    $wrap.empty().append($img);\r\n                                    $img.on('error', function () {\r\n                                        $wrap.text(lang.uploadNoPreview);\r\n                                    });\r\n                                }\r\n                            }, thumbnailWidth, thumbnailHeight);\r\n                        }\r\n                    }\r\n                    percentages[ file.id ] = [ file.size, 0 ];\r\n                    file.rotation = 0;\r\n\r\n                    /* 检查文件格式 */\r\n                    if (!file.ext || acceptExtensions.indexOf(file.ext.toLowerCase()) == -1) {\r\n                        showError('not_allow_type');\r\n                        uploader.removeFile(file);\r\n                    }\r\n                }\r\n\r\n                file.on('statuschange', function (cur, prev) {\r\n                    if (prev === 'progress') {\r\n                        $prgress.hide().width(0);\r\n                    } else if (prev === 'queued') {\r\n                        $li.off('mouseenter mouseleave');\r\n                        $btns.remove();\r\n                    }\r\n                    // 成功\r\n                    if (cur === 'error' || cur === 'invalid') {\r\n                        showError(file.statusText);\r\n                        percentages[ file.id ][ 1 ] = 1;\r\n                    } else if (cur === 'interrupt') {\r\n                        showError('interrupt');\r\n                    } else if (cur === 'queued') {\r\n                        percentages[ file.id ][ 1 ] = 0;\r\n                    } else if (cur === 'progress') {\r\n                        $info.hide();\r\n                        $prgress.css('display', 'block');\r\n                    } else if (cur === 'complete') {\r\n                    }\r\n\r\n                    $li.removeClass('state-' + prev).addClass('state-' + cur);\r\n                });\r\n\r\n                $li.on('mouseenter', function () {\r\n                    $btns.stop().animate({height: 30});\r\n                });\r\n                $li.on('mouseleave', function () {\r\n                    $btns.stop().animate({height: 0});\r\n                });\r\n\r\n                $btns.on('click', 'span', function () {\r\n                    var index = $(this).index(),\r\n                        deg;\r\n\r\n                    switch (index) {\r\n                        case 0:\r\n                            uploader.removeFile(file);\r\n                            return;\r\n                        case 1:\r\n                            file.rotation += 90;\r\n                            break;\r\n                        case 2:\r\n                            file.rotation -= 90;\r\n                            break;\r\n                    }\r\n\r\n                    if (supportTransition) {\r\n                        deg = 'rotate(' + file.rotation + 'deg)';\r\n                        $wrap.css({\r\n                            '-webkit-transform': deg,\r\n                            '-mos-transform': deg,\r\n                            '-o-transform': deg,\r\n                            'transform': deg\r\n                        });\r\n                    } else {\r\n                        $wrap.css('filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation=' + (~~((file.rotation / 90) % 4 + 4) % 4) + ')');\r\n                    }\r\n\r\n                });\r\n\r\n                $li.insertBefore($filePickerBlock);\r\n            }\r\n\r\n            // 负责view的销毁\r\n            function removeFile(file) {\r\n                var $li = $('#' + file.id);\r\n                delete percentages[ file.id ];\r\n                updateTotalProgress();\r\n                $li.off().find('.file-panel').off().end().remove();\r\n            }\r\n\r\n            function updateTotalProgress() {\r\n                var loaded = 0,\r\n                    total = 0,\r\n                    spans = $progress.children(),\r\n                    percent;\r\n\r\n                $.each(percentages, function (k, v) {\r\n                    total += v[ 0 ];\r\n                    loaded += v[ 0 ] * v[ 1 ];\r\n                });\r\n\r\n                percent = total ? loaded / total : 0;\r\n\r\n                spans.eq(0).text(Math.round(percent * 100) + '%');\r\n                spans.eq(1).css('width', Math.round(percent * 100) + '%');\r\n                updateStatus();\r\n            }\r\n\r\n            function setState(val, files) {\r\n\r\n                if (val != state) {\r\n\r\n                    var stats = uploader.getStats();\r\n\r\n                    $upload.removeClass('state-' + state);\r\n                    $upload.addClass('state-' + val);\r\n\r\n                    switch (val) {\r\n\r\n                        /* 未选择文件 */\r\n                        case 'pedding':\r\n                            $queue.addClass('element-invisible');\r\n                            $statusBar.addClass('element-invisible');\r\n                            $placeHolder.removeClass('element-invisible');\r\n                            $progress.hide(); $info.hide();\r\n                            uploader.refresh();\r\n                            break;\r\n\r\n                        /* 可以开始上传 */\r\n                        case 'ready':\r\n                            $placeHolder.addClass('element-invisible');\r\n                            $queue.removeClass('element-invisible');\r\n                            $statusBar.removeClass('element-invisible');\r\n                            $progress.hide(); $info.show();\r\n                            $upload.text(lang.uploadStart);\r\n                            uploader.refresh();\r\n                            break;\r\n\r\n                        /* 上传中 */\r\n                        case 'uploading':\r\n                            $progress.show(); $info.hide();\r\n                            $upload.text(lang.uploadPause);\r\n                            break;\r\n\r\n                        /* 暂停上传 */\r\n                        case 'paused':\r\n                            $progress.show(); $info.hide();\r\n                            $upload.text(lang.uploadContinue);\r\n                            break;\r\n\r\n                        case 'confirm':\r\n                            $progress.show(); $info.hide();\r\n                            $upload.text(lang.uploadStart);\r\n\r\n                            stats = uploader.getStats();\r\n                            if (stats.successNum && !stats.uploadFailNum) {\r\n                                setState('finish');\r\n                                return;\r\n                            }\r\n                            break;\r\n\r\n                        case 'finish':\r\n                            $progress.hide(); $info.show();\r\n                            if (stats.uploadFailNum) {\r\n                                $upload.text(lang.uploadRetry);\r\n                            } else {\r\n                                $upload.text(lang.uploadStart);\r\n                            }\r\n                            break;\r\n                    }\r\n\r\n                    state = val;\r\n                    updateStatus();\r\n\r\n                }\r\n\r\n                if (!_this.getQueueCount()) {\r\n                    $upload.addClass('disabled')\r\n                } else {\r\n                    $upload.removeClass('disabled')\r\n                }\r\n\r\n            }\r\n\r\n            function updateStatus() {\r\n                var text = '', stats;\r\n\r\n                if (state === 'ready') {\r\n                    text = lang.updateStatusReady.replace('_', fileCount).replace('_KB', WebUploader.formatSize(fileSize));\r\n                } else if (state === 'confirm') {\r\n                    stats = uploader.getStats();\r\n                    if (stats.uploadFailNum) {\r\n                        text = lang.updateStatusConfirm.replace('_', stats.successNum).replace('_', stats.successNum);\r\n                    }\r\n                } else {\r\n                    stats = uploader.getStats();\r\n                    text = lang.updateStatusFinish.replace('_', fileCount).\r\n                        replace('_KB', WebUploader.formatSize(fileSize)).\r\n                        replace('_', stats.successNum);\r\n\r\n                    if (stats.uploadFailNum) {\r\n                        text += lang.updateStatusError.replace('_', stats.uploadFailNum);\r\n                    }\r\n                }\r\n\r\n                $info.html(text);\r\n            }\r\n\r\n            uploader.on('fileQueued', function (file) {\r\n                fileCount++;\r\n                fileSize += file.size;\r\n\r\n                if (fileCount === 1) {\r\n                    $placeHolder.addClass('element-invisible');\r\n                    $statusBar.show();\r\n                }\r\n\r\n                addFile(file);\r\n            });\r\n\r\n            uploader.on('fileDequeued', function (file) {\r\n                fileCount--;\r\n                fileSize -= file.size;\r\n\r\n                removeFile(file);\r\n                updateTotalProgress();\r\n            });\r\n\r\n            uploader.on('filesQueued', function (file) {\r\n                if (!uploader.isInProgress() && (state == 'pedding' || state == 'finish' || state == 'confirm' || state == 'ready')) {\r\n                    setState('ready');\r\n                }\r\n                updateTotalProgress();\r\n            });\r\n\r\n            uploader.on('all', function (type, files) {\r\n                switch (type) {\r\n                    case 'uploadFinished':\r\n                        setState('confirm', files);\r\n                        break;\r\n                    case 'startUpload':\r\n                        /* 添加额外的GET参数 */\r\n                        var params = utils.serializeParam(editor.queryCommandValue('serverparam')) || '',\r\n                            url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + 'encode=utf-8&' + params);\r\n                        uploader.option('server', url);\r\n                        setState('uploading', files);\r\n                        break;\r\n                    case 'stopUpload':\r\n                        setState('paused', files);\r\n                        break;\r\n                }\r\n            });\r\n\r\n            uploader.on('uploadBeforeSend', function (file, data, header) {\r\n                //这里可以通过data对象添加POST参数\r\n                header['X_Requested_With'] = 'XMLHttpRequest';\r\n            });\r\n\r\n            uploader.on('uploadProgress', function (file, percentage) {\r\n                var $li = $('#' + file.id),\r\n                    $percent = $li.find('.progress span');\r\n\r\n                $percent.css('width', percentage * 100 + '%');\r\n                percentages[ file.id ][ 1 ] = percentage;\r\n                updateTotalProgress();\r\n            });\r\n\r\n            uploader.on('uploadSuccess', function (file, ret) {\r\n                var $file = $('#' + file.id);\r\n                try {\r\n                    var responseText = (ret._raw || ret),\r\n                        json = utils.str2json(responseText);\r\n                    if (json.state == 'SUCCESS') {\r\n                        uploadVideoList.push({\r\n                            'url': json.url,\r\n                            'type': json.type,\r\n                            'original':json.original\r\n                        });\r\n                        $file.append('<span class=\"success\"></span>');\r\n                    } else {\r\n                        $file.find('.error').text(json.state).show();\r\n                    }\r\n                } catch (e) {\r\n                    $file.find('.error').text(lang.errorServerUpload).show();\r\n                }\r\n            });\r\n\r\n            uploader.on('uploadError', function (file, code) {\r\n            });\r\n            uploader.on('error', function (code, file) {\r\n                if (code == 'Q_TYPE_DENIED' || code == 'F_EXCEED_SIZE') {\r\n                    addFile(file);\r\n                }\r\n            });\r\n            uploader.on('uploadComplete', function (file, ret) {\r\n            });\r\n\r\n            $upload.on('click', function () {\r\n                if ($(this).hasClass('disabled')) {\r\n                    return false;\r\n                }\r\n\r\n                if (state === 'ready') {\r\n                    uploader.upload();\r\n                } else if (state === 'paused') {\r\n                    uploader.upload();\r\n                } else if (state === 'uploading') {\r\n                    uploader.stop();\r\n                }\r\n            });\r\n\r\n            $upload.addClass('state-' + state);\r\n            updateTotalProgress();\r\n        },\r\n        getQueueCount: function () {\r\n            var file, i, status, readyFile = 0, files = this.uploader.getFiles();\r\n            for (i = 0; file = files[i++]; ) {\r\n                status = file.getStatus();\r\n                if (status == 'queued' || status == 'uploading' || status == 'progress') readyFile++;\r\n            }\r\n            return readyFile;\r\n        },\r\n        refresh: function(){\r\n            this.uploader.refresh();\r\n        }\r\n    };\r\n\r\n})();\r\n"
  },
  {
    "path": "public/static/ueditor/dialogs/webapp/webapp.html",
    "content": "<!DOCTYPE>\r\n<html>\r\n<head>\r\n    <title></title>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <style type=\"text/css\">\r\n        .wrapper{width: 540px; margin: 10px auto;}\r\n        #appShow {border: 1px solid #ddd;}\r\n        .errorMsg{font-size: 13px;margin: 10px;color: #dd0000}\r\n    </style>\r\n</head>\r\n<body>\r\n    <div class=\"wrapper\">\r\n        <div id=\"appShow\"></div>\r\n    </div>\r\n    <script type=\"text/javascript\">\r\n        //此处配置您在百度上申请到的appkey。\r\n        var apikey = editor.options.webAppKey;\r\n        if ( apikey && apikey.length == 24 ) {\r\n            var searchConfig = {\r\n                container:'appShow', //容器ID\r\n                tips:\"\", //该值用于自动清空\r\n                search:1, //是否显示搜索框\r\n                ps:12, //每页显示的条数\r\n                suggest:1, //是否开启搜索自动完成\r\n                limit:0, //搜索结果显示条数，0表示无限制\r\n                searchNow:0, //是否在初始化完成时立即搜索\r\n                apikey:apikey, //每人得\r\n                pager:1,\r\n                cid:7134562,\r\n                outputHTML:1\r\n            },baiduApp;\r\n\r\n            function clickCallback() {\r\n                baiduApp.addEventListener( 'getAppHTML', function ( e, data ) {\r\n                    var url = 'http://app.baidu.com/app/enter?appid='+data.data['app_id'] +'&tn=app_canvas&app_spce_id=1&apikey='+apikey+'&api_key=' + apikey;\r\n                    editor.execCommand( \"webapp\", {url:url,width:data.uniWidth,height:data.uniHeight+60,logo:data.data['app_logo'],title:data.data['app_name']});\r\n                    dialog.close();\r\n                } );\r\n            }\r\n\r\n            var script = document.createElement( \"script\" );\r\n            script.type = \"text/javascript\";\r\n            script.src = \"http://app.baidu.com/appweb/api/search?auto=yes&container=container&apikey=\" + apikey + \"&instanceName=baiduApp&callback=clickCallback&config=searchConfig\";\r\n            document.body.appendChild( script );\r\n        } else {\r\n            $G( \"appShow\" ).innerHTML = \"<p class='errorMsg'>\"+lang.tip1+\"<a title='\"+lang.anthorApi+\"' href='http://app.baidu.com/static/cms/getapikey.html' target='_blank'>\"+lang.applyFor+\"</a></p><p class='errorMsg'>\"+lang.tip2+\"</p>\" ;\r\n        }\r\n\r\n    </script>\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/wordimage/tangram.js",
    "content": "// Copyright (c) 2009, Baidu Inc. All rights reserved.\n// \n// Licensed under the BSD License\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n// \n//      http:// tangram.baidu.com/license.html\n// \n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS-IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n /**\n * @namespace T Tangram七巧板\n * @name T\n * @version 1.6.0\n*/\n\n/**\n * 声明baidu包\n * @author: allstar, erik, meizz, berg\n */\nvar T,\n    baidu = T = baidu || {version: \"1.5.0\"};\nbaidu.guid = \"$BAIDU$\";\nbaidu.$$ = window[baidu.guid] = window[baidu.guid] || {global:{}};\n\n/**\n * 使用flash资源封装的一些功能\n * @namespace baidu.flash\n */\nbaidu.flash = baidu.flash || {};\n\n/**\n * 操作dom的方法\n * @namespace baidu.dom \n */\nbaidu.dom = baidu.dom || {};\n\n\n/**\n * 从文档中获取指定的DOM元素\n * @name baidu.dom.g\n * @function\n * @grammar baidu.dom.g(id)\n * @param {string|HTMLElement} id 元素的id或DOM元素.\n * @shortcut g,T.G\n * @meta standard\n * @see baidu.dom.q\n *\n * @return {HTMLElement|null} 获取的元素，查找不到时返回null,如果参数不合法，直接返回参数.\n */\nbaidu.dom.g = function(id) {\n    if (!id) return null;\n    if ('string' == typeof id || id instanceof String) {\n        return document.getElementById(id);\n    } else if (id.nodeName && (id.nodeType == 1 || id.nodeType == 9)) {\n        return id;\n    }\n    return null;\n};\nbaidu.g = baidu.G = baidu.dom.g;\n\n\n/**\n * 操作数组的方法\n * @namespace baidu.array\n */\n\nbaidu.array = baidu.array || {};\n\n\n/**\n * 遍历数组中所有元素\n * @name baidu.array.each\n * @function\n * @grammar baidu.array.each(source, iterator[, thisObject])\n * @param {Array} source 需要遍历的数组\n * @param {Function} iterator 对每个数组元素进行调用的函数，该函数有两个参数，第一个为数组元素，第二个为数组索引值，function (item, index)。\n * @param {Object} [thisObject] 函数调用时的this指针，如果没有此参数，默认是当前遍历的数组\n * @remark\n * each方法不支持对Object的遍历,对Object的遍历使用baidu.object.each 。\n * @shortcut each\n * @meta standard\n *             \n * @returns {Array} 遍历的数组\n */\n \nbaidu.each = baidu.array.forEach = baidu.array.each = function (source, iterator, thisObject) {\n    var returnValue, item, i, len = source.length;\n    \n    if ('function' == typeof iterator) {\n        for (i = 0; i < len; i++) {\n            item = source[i];\n            returnValue = iterator.call(thisObject || source, item, i);\n    \n            if (returnValue === false) {\n                break;\n            }\n        }\n    }\n    return source;\n};\n\n/**\n * 对语言层面的封装，包括类型判断、模块扩展、继承基类以及对象自定义事件的支持。\n * @namespace baidu.lang\n */\nbaidu.lang = baidu.lang || {};\n\n\n/**\n * 判断目标参数是否为function或Function实例\n * @name baidu.lang.isFunction\n * @function\n * @grammar baidu.lang.isFunction(source)\n * @param {Any} source 目标参数\n * @version 1.2\n * @see baidu.lang.isString,baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isArray,baidu.lang.isElement,baidu.lang.isBoolean,baidu.lang.isDate\n * @meta standard\n * @returns {boolean} 类型判断结果\n */\nbaidu.lang.isFunction = function (source) {\n    return '[object Function]' == Object.prototype.toString.call(source);\n};\n\n/**\n * 判断目标参数是否string类型或String对象\n * @name baidu.lang.isString\n * @function\n * @grammar baidu.lang.isString(source)\n * @param {Any} source 目标参数\n * @shortcut isString\n * @meta standard\n * @see baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isArray,baidu.lang.isElement,baidu.lang.isBoolean,baidu.lang.isDate\n *             \n * @returns {boolean} 类型判断结果\n */\nbaidu.lang.isString = function (source) {\n    return '[object String]' == Object.prototype.toString.call(source);\n};\nbaidu.isString = baidu.lang.isString;\n\n\n/**\n * 判断浏览器类型和特性的属性\n * @namespace baidu.browser\n */\nbaidu.browser = baidu.browser || {};\n\n\n/**\n * 判断是否为opera浏览器\n * @property opera opera版本号\n * @grammar baidu.browser.opera\n * @meta standard\n * @see baidu.browser.ie,baidu.browser.firefox,baidu.browser.safari,baidu.browser.chrome\n * @returns {Number} opera版本号\n */\n\n/**\n * opera 从10开始不是用opera后面的字符串进行版本的判断\n * 在Browser identification最后添加Version + 数字进行版本标识\n * opera后面的数字保持在9.80不变\n */\nbaidu.browser.opera = /opera(\\/| )(\\d+(\\.\\d+)?)(.+?(version\\/(\\d+(\\.\\d+)?)))?/i.test(navigator.userAgent) ?  + ( RegExp[\"\\x246\"] || RegExp[\"\\x242\"] ) : undefined;\n\n\n/**\n * 在目标元素的指定位置插入HTML代码\n * @name baidu.dom.insertHTML\n * @function\n * @grammar baidu.dom.insertHTML(element, position, html)\n * @param {HTMLElement|string} element 目标元素或目标元素的id\n * @param {string} position 插入html的位置信息，取值为beforeBegin,afterBegin,beforeEnd,afterEnd\n * @param {string} html 要插入的html\n * @remark\n * \n * 对于position参数，大小写不敏感<br>\n * 参数的意思：beforeBegin&lt;span&gt;afterBegin   this is span! beforeEnd&lt;/span&gt; afterEnd <br />\n * 此外，如果使用本函数插入带有script标签的HTML字符串，script标签对应的脚本将不会被执行。\n * \n * @shortcut insertHTML\n * @meta standard\n *             \n * @returns {HTMLElement} 目标元素\n */\nbaidu.dom.insertHTML = function (element, position, html) {\n    element = baidu.dom.g(element);\n    var range,begin;\n    if (element.insertAdjacentHTML && !baidu.browser.opera) {\n        element.insertAdjacentHTML(position, html);\n    } else {\n        range = element.ownerDocument.createRange();\n        position = position.toUpperCase();\n        if (position == 'AFTERBEGIN' || position == 'BEFOREEND') {\n            range.selectNodeContents(element);\n            range.collapse(position == 'AFTERBEGIN');\n        } else {\n            begin = position == 'BEFOREBEGIN';\n            range[begin ? 'setStartBefore' : 'setEndAfter'](element);\n            range.collapse(begin);\n        }\n        range.insertNode(range.createContextualFragment(html));\n    }\n    return element;\n};\n\nbaidu.insertHTML = baidu.dom.insertHTML;\n\n/**\n * 操作flash对象的方法，包括创建flash对象、获取flash对象以及判断flash插件的版本号\n * @namespace baidu.swf\n */\nbaidu.swf = baidu.swf || {};\n\n\n/**\n * 浏览器支持的flash插件版本\n * @property version 浏览器支持的flash插件版本\n * @grammar baidu.swf.version\n * @return {String} 版本号\n * @meta standard\n */\nbaidu.swf.version = (function () {\n    var n = navigator;\n    if (n.plugins && n.mimeTypes.length) {\n        var plugin = n.plugins[\"Shockwave Flash\"];\n        if (plugin && plugin.description) {\n            return plugin.description\n                    .replace(/([a-zA-Z]|\\s)+/, \"\")\n                    .replace(/(\\s)+r/, \".\") + \".0\";\n        }\n    } else if (window.ActiveXObject && !window.opera) {\n        for (var i = 12; i >= 2; i--) {\n            try {\n                var c = new ActiveXObject('ShockwaveFlash.ShockwaveFlash.' + i);\n                if (c) {\n                    var version = c.GetVariable(\"$version\");\n                    return version.replace(/WIN/g,'').replace(/,/g,'.');\n                }\n            } catch(e) {}\n        }\n    }\n})();\n\n/**\n * 操作字符串的方法\n * @namespace baidu.string\n */\nbaidu.string = baidu.string || {};\n\n\n/**\n * 对目标字符串进行html编码\n * @name baidu.string.encodeHTML\n * @function\n * @grammar baidu.string.encodeHTML(source)\n * @param {string} source 目标字符串\n * @remark\n * 编码字符有5个：&<>\"'\n * @shortcut encodeHTML\n * @meta standard\n * @see baidu.string.decodeHTML\n *             \n * @returns {string} html编码后的字符串\n */\nbaidu.string.encodeHTML = function (source) {\n    return String(source)\n                .replace(/&/g,'&amp;')\n                .replace(/</g,'&lt;')\n                .replace(/>/g,'&gt;')\n                .replace(/\"/g, \"&quot;\")\n                .replace(/'/g, \"&#39;\");\n};\n\nbaidu.encodeHTML = baidu.string.encodeHTML;\n\n/**\n * 创建flash对象的html字符串\n * @name baidu.swf.createHTML\n * @function\n * @grammar baidu.swf.createHTML(options)\n * \n * @param {Object} \toptions \t\t\t\t\t创建flash的选项参数\n * @param {string} \toptions.id \t\t\t\t\t要创建的flash的标识\n * @param {string} \toptions.url \t\t\t\tflash文件的url\n * @param {String} \toptions.errorMessage \t\t未安装flash player或flash player版本号过低时的提示\n * @param {string} \toptions.ver \t\t\t\t最低需要的flash player版本号\n * @param {string} \toptions.width \t\t\t\tflash的宽度\n * @param {string} \toptions.height \t\t\t\tflash的高度\n * @param {string} \toptions.align \t\t\t\tflash的对齐方式，允许值：middle/left/right/top/bottom\n * @param {string} \toptions.base \t\t\t\t设置用于解析swf文件中的所有相对路径语句的基本目录或URL\n * @param {string} \toptions.bgcolor \t\t\tswf文件的背景色\n * @param {string} \toptions.salign \t\t\t\t设置缩放的swf文件在由width和height设置定义的区域内的位置。允许值：l/r/t/b/tl/tr/bl/br\n * @param {boolean} options.menu \t\t\t\t是否显示右键菜单，允许值：true/false\n * @param {boolean} options.loop \t\t\t\t播放到最后一帧时是否重新播放，允许值： true/false\n * @param {boolean} options.play \t\t\t\tflash是否在浏览器加载时就开始播放。允许值：true/false\n * @param {string} \toptions.quality \t\t\t设置flash播放的画质，允许值：low/medium/high/autolow/autohigh/best\n * @param {string} \toptions.scale \t\t\t\t设置flash内容如何缩放来适应设置的宽高。允许值：showall/noborder/exactfit\n * @param {string} \toptions.wmode \t\t\t\t设置flash的显示模式。允许值：window/opaque/transparent\n * @param {string} \toptions.allowscriptaccess \t设置flash与页面的通信权限。允许值：always/never/sameDomain\n * @param {string} \toptions.allownetworking \t设置swf文件中允许使用的网络API。允许值：all/internal/none\n * @param {boolean} options.allowfullscreen \t是否允许flash全屏。允许值：true/false\n * @param {boolean} options.seamlesstabbing \t允许设置执行无缝跳格，从而使用户能跳出flash应用程序。该参数只能在安装Flash7及更高版本的Windows中使用。允许值：true/false\n * @param {boolean} options.devicefont \t\t\t设置静态文本对象是否以设备字体呈现。允许值：true/false\n * @param {boolean} options.swliveconnect \t\t第一次加载flash时浏览器是否应启动Java。允许值：true/false\n * @param {Object} \toptions.vars \t\t\t\t要传递给flash的参数，支持JSON或string类型。\n * \n * @see baidu.swf.create\n * @meta standard\n * @returns {string} flash对象的html字符串\n */\nbaidu.swf.createHTML = function (options) {\n    options = options || {};\n    var version = baidu.swf.version, \n        needVersion = options['ver'] || '6.0.0', \n        vUnit1, vUnit2, i, k, len, item, tmpOpt = {},\n        encodeHTML = baidu.string.encodeHTML;\n    for (k in options) {\n        tmpOpt[k] = options[k];\n    }\n    options = tmpOpt;\n    if (version) {\n        version = version.split('.');\n        needVersion = needVersion.split('.');\n        for (i = 0; i < 3; i++) {\n            vUnit1 = parseInt(version[i], 10);\n            vUnit2 = parseInt(needVersion[i], 10);\n            if (vUnit2 < vUnit1) {\n                break;\n            } else if (vUnit2 > vUnit1) {\n                return '';\n            }\n        }\n    } else {\n        return '';\n    }\n    \n    var vars = options['vars'],\n        objProperties = ['classid', 'codebase', 'id', 'width', 'height', 'align'];\n    options['align'] = options['align'] || 'middle';\n    options['classid'] = 'clsid:d27cdb6e-ae6d-11cf-96b8-444553540000';\n    options['codebase'] = 'http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0';\n    options['movie'] = options['url'] || '';\n    delete options['vars'];\n    delete options['url'];\n    if ('string' == typeof vars) {\n        options['flashvars'] = vars;\n    } else {\n        var fvars = [];\n        for (k in vars) {\n            item = vars[k];\n            fvars.push(k + \"=\" + encodeURIComponent(item));\n        }\n        options['flashvars'] = fvars.join('&');\n    }\n    var str = ['<object '];\n    for (i = 0, len = objProperties.length; i < len; i++) {\n        item = objProperties[i];\n        str.push(' ', item, '=\"', encodeHTML(options[item]), '\"');\n    }\n    str.push('>');\n    var params = {\n        'wmode'             : 1,\n        'scale'             : 1,\n        'quality'           : 1,\n        'play'              : 1,\n        'loop'              : 1,\n        'menu'              : 1,\n        'salign'            : 1,\n        'bgcolor'           : 1,\n        'base'              : 1,\n        'allowscriptaccess' : 1,\n        'allownetworking'   : 1,\n        'allowfullscreen'   : 1,\n        'seamlesstabbing'   : 1,\n        'devicefont'        : 1,\n        'swliveconnect'     : 1,\n        'flashvars'         : 1,\n        'movie'             : 1\n    };\n    \n    for (k in options) {\n        item = options[k];\n        k = k.toLowerCase();\n        if (params[k] && (item || item === false || item === 0)) {\n            str.push('<param name=\"' + k + '\" value=\"' + encodeHTML(item) + '\" />');\n        }\n    }\n    options['src']  = options['movie'];\n    options['name'] = options['id'];\n    delete options['id'];\n    delete options['movie'];\n    delete options['classid'];\n    delete options['codebase'];\n    options['type'] = 'application/x-shockwave-flash';\n    options['pluginspage'] = 'http://www.macromedia.com/go/getflashplayer';\n    str.push('<embed');\n    var salign;\n    for (k in options) {\n        item = options[k];\n        if (item || item === false || item === 0) {\n            if ((new RegExp(\"^salign\\x24\", \"i\")).test(k)) {\n                salign = item;\n                continue;\n            }\n            \n            str.push(' ', k, '=\"', encodeHTML(item), '\"');\n        }\n    }\n    \n    if (salign) {\n        str.push(' salign=\"', encodeHTML(salign), '\"');\n    }\n    str.push('></embed></object>');\n    \n    return str.join('');\n};\n\n\n/**\n * 在页面中创建一个flash对象\n * @name baidu.swf.create\n * @function\n * @grammar baidu.swf.create(options[, container])\n * \n * @param {Object} \toptions \t\t\t\t\t创建flash的选项参数\n * @param {string} \toptions.id \t\t\t\t\t要创建的flash的标识\n * @param {string} \toptions.url \t\t\t\tflash文件的url\n * @param {String} \toptions.errorMessage \t\t未安装flash player或flash player版本号过低时的提示\n * @param {string} \toptions.ver \t\t\t\t最低需要的flash player版本号\n * @param {string} \toptions.width \t\t\t\tflash的宽度\n * @param {string} \toptions.height \t\t\t\tflash的高度\n * @param {string} \toptions.align \t\t\t\tflash的对齐方式，允许值：middle/left/right/top/bottom\n * @param {string} \toptions.base \t\t\t\t设置用于解析swf文件中的所有相对路径语句的基本目录或URL\n * @param {string} \toptions.bgcolor \t\t\tswf文件的背景色\n * @param {string} \toptions.salign \t\t\t\t设置缩放的swf文件在由width和height设置定义的区域内的位置。允许值：l/r/t/b/tl/tr/bl/br\n * @param {boolean} options.menu \t\t\t\t是否显示右键菜单，允许值：true/false\n * @param {boolean} options.loop \t\t\t\t播放到最后一帧时是否重新播放，允许值： true/false\n * @param {boolean} options.play \t\t\t\tflash是否在浏览器加载时就开始播放。允许值：true/false\n * @param {string} \toptions.quality \t\t\t设置flash播放的画质，允许值：low/medium/high/autolow/autohigh/best\n * @param {string} \toptions.scale \t\t\t\t设置flash内容如何缩放来适应设置的宽高。允许值：showall/noborder/exactfit\n * @param {string} \toptions.wmode \t\t\t\t设置flash的显示模式。允许值：window/opaque/transparent\n * @param {string} \toptions.allowscriptaccess \t设置flash与页面的通信权限。允许值：always/never/sameDomain\n * @param {string} \toptions.allownetworking \t设置swf文件中允许使用的网络API。允许值：all/internal/none\n * @param {boolean} options.allowfullscreen \t是否允许flash全屏。允许值：true/false\n * @param {boolean} options.seamlesstabbing \t允许设置执行无缝跳格，从而使用户能跳出flash应用程序。该参数只能在安装Flash7及更高版本的Windows中使用。允许值：true/false\n * @param {boolean} options.devicefont \t\t\t设置静态文本对象是否以设备字体呈现。允许值：true/false\n * @param {boolean} options.swliveconnect \t\t第一次加载flash时浏览器是否应启动Java。允许值：true/false\n * @param {Object} \toptions.vars \t\t\t\t要传递给flash的参数，支持JSON或string类型。\n * \n * @param {HTMLElement|string} [container] \t\tflash对象的父容器元素，不传递该参数时在当前代码位置创建flash对象。\n * @meta standard\n * @see baidu.swf.createHTML,baidu.swf.getMovie\n */\nbaidu.swf.create = function (options, target) {\n    options = options || {};\n    var html = baidu.swf.createHTML(options) \n               || options['errorMessage'] \n               || '';\n                \n    if (target && 'string' == typeof target) {\n        target = document.getElementById(target);\n    }\n    baidu.dom.insertHTML( target || document.body ,'beforeEnd',html );\n};\n/**\n * 判断是否为ie浏览器\n * @name baidu.browser.ie\n * @field\n * @grammar baidu.browser.ie\n * @returns {Number} IE版本号\n */\nbaidu.browser.ie = baidu.ie = /msie (\\d+\\.\\d+)/i.test(navigator.userAgent) ? (document.documentMode || + RegExp['\\x241']) : undefined;\n\n/**\n * 移除数组中的项\n * @name baidu.array.remove\n * @function\n * @grammar baidu.array.remove(source, match)\n * @param {Array} source 需要移除项的数组\n * @param {Any} match 要移除的项\n * @meta standard\n * @see baidu.array.removeAt\n *             \n * @returns {Array} 移除后的数组\n */\nbaidu.array.remove = function (source, match) {\n    var len = source.length;\n        \n    while (len--) {\n        if (len in source && source[len] === match) {\n            source.splice(len, 1);\n        }\n    }\n    return source;\n};\n\n/**\n * 判断目标参数是否Array对象\n * @name baidu.lang.isArray\n * @function\n * @grammar baidu.lang.isArray(source)\n * @param {Any} source 目标参数\n * @meta standard\n * @see baidu.lang.isString,baidu.lang.isObject,baidu.lang.isNumber,baidu.lang.isElement,baidu.lang.isBoolean,baidu.lang.isDate\n *             \n * @returns {boolean} 类型判断结果\n */\nbaidu.lang.isArray = function (source) {\n    return '[object Array]' == Object.prototype.toString.call(source);\n};\n\n\n\n/**\n * 将一个变量转换成array\n * @name baidu.lang.toArray\n * @function\n * @grammar baidu.lang.toArray(source)\n * @param {mix} source 需要转换成array的变量\n * @version 1.3\n * @meta standard\n * @returns {array} 转换后的array\n */\nbaidu.lang.toArray = function (source) {\n    if (source === null || source === undefined)\n        return [];\n    if (baidu.lang.isArray(source))\n        return source;\n    if (typeof source.length !== 'number' || typeof source === 'string' || baidu.lang.isFunction(source)) {\n        return [source];\n    }\n    if (source.item) {\n        var l = source.length, array = new Array(l);\n        while (l--)\n            array[l] = source[l];\n        return array;\n    }\n\n    return [].slice.call(source);\n};\n\n/**\n * 获得flash对象的实例\n * @name baidu.swf.getMovie\n * @function\n * @grammar baidu.swf.getMovie(name)\n * @param {string} name flash对象的名称\n * @see baidu.swf.create\n * @meta standard\n * @returns {HTMLElement} flash对象的实例\n */\nbaidu.swf.getMovie = function (name) {\n\tvar movie = document[name], ret;\n    return baidu.browser.ie == 9 ?\n    \tmovie && movie.length ? \n    \t\t(ret = baidu.array.remove(baidu.lang.toArray(movie),function(item){\n    \t\t\treturn item.tagName.toLowerCase() != \"embed\";\n    \t\t})).length == 1 ? ret[0] : ret\n    \t\t: movie\n    \t: movie || window[name];\n};\n\n\nbaidu.flash._Base = (function(){\n   \n    var prefix = 'bd__flash__';\n\n    /**\n     * 创建一个随机的字符串\n     * @private\n     * @return {String}\n     */\n    function _createString(){\n        return  prefix + Math.floor(Math.random() * 2147483648).toString(36);\n    };\n   \n    /**\n     * 检查flash状态\n     * @private\n     * @param {Object} target flash对象\n     * @return {Boolean}\n     */\n    function _checkReady(target){\n        if(typeof target !== 'undefined' && typeof target.flashInit !== 'undefined' && target.flashInit()){\n            return true;\n        }else{\n            return false;\n        }\n    };\n\n    /**\n     * 调用之前进行压栈的函数\n     * @private\n     * @param {Array} callQueue 调用队列\n     * @param {Object} target flash对象\n     * @return {Null}\n     */\n    function _callFn(callQueue, target){\n        var result = null;\n        \n        callQueue = callQueue.reverse();\n        baidu.each(callQueue, function(item){\n            result = target.call(item.fnName, item.params);\n            item.callBack(result);\n        });\n    };\n\n    /**\n     * 为传入的匿名函数创建函数名\n     * @private\n     * @param {String|Function} fun 传入的匿名函数或者函数名\n     * @return {String}\n     */\n    function _createFunName(fun){\n        var name = '';\n\n        if(baidu.lang.isFunction(fun)){\n            name = _createString();\n            window[name] = function(){\n                fun.apply(window, arguments);\n            };\n\n            return name;\n        }else if(baidu.lang.isString){\n            return fun;\n        }\n    };\n\n    /**\n     * 绘制flash\n     * @private\n     * @param {Object} options 创建参数\n     * @return {Object} \n     */\n    function _render(options){\n        if(!options.id){\n            options.id = _createString();\n        }\n        \n        var container = options.container || '';\n        delete(options.container);\n        \n        baidu.swf.create(options, container);\n        \n        return baidu.swf.getMovie(options.id);\n    };\n\n    return function(options, callBack){\n        var me = this,\n            autoRender = (typeof options.autoRender !== 'undefined' ? options.autoRender : true),\n            createOptions = options.createOptions || {},\n            target = null,\n            isReady = false,\n            callQueue = [],\n            timeHandle = null,\n            callBack = callBack || [];\n\n        /**\n         * 将flash文件绘制到页面上\n         * @public\n         * @return {Null}\n         */\n        me.render = function(){\n            target = _render(createOptions);\n            \n            if(callBack.length > 0){\n                baidu.each(callBack, function(funName, index){\n                    callBack[index] = _createFunName(options[funName] || new Function());\n                });    \n            }\n            me.call('setJSFuncName', [callBack]);\n        };\n\n        /**\n         * 返回flash状态\n         * @return {Boolean}\n         */\n        me.isReady = function(){\n            return isReady;\n        };\n\n        /**\n         * 调用flash接口的统一入口\n         * @param {String} fnName 调用的函数名\n         * @param {Array} params 传入的参数组成的数组,若不许要参数，需传入空数组\n         * @param {Function} [callBack] 异步调用后将返回值作为参数的调用回调函数，如无返回值，可以不传入此参数\n         * @return {Null}\n        */\n        me.call = function(fnName, params, callBack){\n            if(!fnName) return null;\n            callBack = callBack || new Function();\n\n            var result = null;\n    \n            if(isReady){\n                result = target.call(fnName, params);\n                callBack(result);\n            }else{\n                callQueue.push({\n                    fnName: fnName,\n                    params: params,\n                    callBack: callBack\n                });\n    \n                (!timeHandle) && (timeHandle = setInterval(_check, 200));\n            }\n        };\n    \n        /**\n         * 为传入的匿名函数创建函数名\n         * @public\n         * @param {String|Function} fun 传入的匿名函数或者函数名\n         * @return {String}\n         */\n        me.createFunName = function(fun){\n            return _createFunName(fun);    \n        };\n\n        /**\n         * 检查flash是否ready， 并进行调用\n         * @private\n         * @return {Null}\n         */\n        function _check(){\n            if(_checkReady(target)){\n                clearInterval(timeHandle);\n                timeHandle = null;\n                _call();\n\n                isReady = true;\n            }               \n        };\n\n        /**\n         * 调用之前进行压栈的函数\n         * @private\n         * @return {Null}\n         */\n        function _call(){\n            _callFn(callQueue, target);\n            callQueue = [];\n        }\n\n        autoRender && me.render(); \n    };\n})();\n\n\n\n/**\n * 创建flash based imageUploader\n * @class\n * @grammar baidu.flash.imageUploader(options)\n * @param {Object} createOptions 创建flash时需要的参数，请参照baidu.swf.create文档\n * @config {Object} vars 创建imageUploader时所需要的参数\n * @config {Number} vars.gridWidth 每一个预览图片所占的宽度，应该为flash寛的整除\n * @config {Number} vars.gridHeight 每一个预览图片所占的高度，应该为flash高的整除\n * @config {Number} vars.picWidth 单张预览图片的宽度\n * @config {Number} vars.picHeight 单张预览图片的高度\n * @config {String} vars.uploadDataFieldName POST请求中图片数据的key,默认值'picdata'\n * @config {String} vars.picDescFieldName POST请求中图片描述的key,默认值'picDesc'\n * @config {Number} vars.maxSize 文件的最大体积,单位'MB'\n * @config {Number} vars.compressSize 上传前如果图片体积超过该值，会先压缩\n * @config {Number} vars.maxNum:32 最大上传多少个文件\n * @config {Number} vars.compressLength 能接受的最大边长，超过该值会等比压缩\n * @config {String} vars.url 上传的url地址\n * @config {Number} vars.mode mode == 0时，是使用滚动条，mode == 1时，拉伸flash, 默认值为0\n * @see baidu.swf.createHTML\n * @param {String} backgroundUrl 背景图片路径\n * @param {String} listBacgroundkUrl 布局控件背景\n * @param {String} buttonUrl 按钮图片不背景\n * @param {String|Function} selectFileCallback 选择文件的回调\n * @param {String|Function} exceedFileCallback文件超出限制的最大体积时的回调\n * @param {String|Function} deleteFileCallback 删除文件的回调\n * @param {String|Function} startUploadCallback 开始上传某个文件时的回调\n * @param {String|Function} uploadCompleteCallback 某个文件上传完成的回调\n * @param {String|Function} uploadErrorCallback 某个文件上传失败的回调\n * @param {String|Function} allCompleteCallback 全部上传完成时的回调\n * @param {String|Function} changeFlashHeight 改变Flash的高度，mode==1的时候才有用\n */ \nbaidu.flash.imageUploader = baidu.flash.imageUploader || function(options){\n   \n    var me = this,\n        options = options || {},\n        _flash = new baidu.flash._Base(options, [\n            'selectFileCallback', \n            'exceedFileCallback', \n            'deleteFileCallback', \n            'startUploadCallback',\n            'uploadCompleteCallback',\n            'uploadErrorCallback',\n            'allCompleteCallback',\n            'changeFlashHeight'\n        ]);\n    /**\n     * 开始或回复上传图片\n     * @public\n     * @return {Null}\n     */\n    me.upload = function(){\n        _flash.call('upload');\n    };\n\n    /**\n     * 暂停上传图片\n     * @public\n     * @return {Null}\n     */\n    me.pause = function(){\n        _flash.call('pause');\n    };\n    me.addCustomizedParams = function(index,obj){\n        _flash.call('addCustomizedParams',[index,obj]);\n    }\n};\n\n/**\n * 操作原生对象的方法\n * @namespace baidu.object\n */\nbaidu.object = baidu.object || {};\n\n\n/**\n * 将源对象的所有属性拷贝到目标对象中\n * @author erik\n * @name baidu.object.extend\n * @function\n * @grammar baidu.object.extend(target, source)\n * @param {Object} target 目标对象\n * @param {Object} source 源对象\n * @see baidu.array.merge\n * @remark\n * \n1.目标对象中，与源对象key相同的成员将会被覆盖。<br>\n2.源对象的prototype成员不会拷贝。\n\t\t\n * @shortcut extend\n * @meta standard\n *             \n * @returns {Object} 目标对象\n */\nbaidu.extend =\nbaidu.object.extend = function (target, source) {\n    for (var p in source) {\n        if (source.hasOwnProperty(p)) {\n            target[p] = source[p];\n        }\n    }\n    \n    return target;\n};\n\n\n\n\n\n/**\n * 创建flash based fileUploader\n * @class\n * @grammar baidu.flash.fileUploader(options)\n * @param {Object} options\n * @config {Object} createOptions 创建flash时需要的参数，请参照baidu.swf.create文档\n * @config {String} createOptions.width\n * @config {String} createOptions.height\n * @config {Number} maxNum 最大可选文件数\n * @config {Function|String} selectFile\n * @config {Function|String} exceedMaxSize\n * @config {Function|String} deleteFile\n * @config {Function|String} uploadStart\n * @config {Function|String} uploadComplete\n * @config {Function|String} uploadError\n * @config {Function|String} uploadProgress\n */\nbaidu.flash.fileUploader = baidu.flash.fileUploader || function(options){\n    var me = this,\n        options = options || {};\n    \n    options.createOptions = baidu.extend({\n        wmod: 'transparent'\n    },options.createOptions || {});\n    \n    var _flash = new baidu.flash._Base(options, [\n        'selectFile',\n        'exceedMaxSize',\n        'deleteFile',\n        'uploadStart',\n        'uploadComplete',\n        'uploadError', \n        'uploadProgress'\n    ]);\n\n    _flash.call('setMaxNum', options.maxNum ? [options.maxNum] : [1]);\n\n    /**\n     * 设置当鼠标移动到flash上时，是否变成手型\n     * @public\n     * @param {Boolean} isCursor\n     * @return {Null}\n     */\n    me.setHandCursor = function(isCursor){\n        _flash.call('setHandCursor', [isCursor || false]);\n    };\n\n    /**\n     * 设置鼠标相应函数名\n     * @param {String|Function} fun\n     */\n    me.setMSFunName = function(fun){\n        _flash.call('setMSFunName',[_flash.createFunName(fun)]);\n    }; \n\n    /**\n     * 执行上传操作\n     * @param {String} url 上传的url\n     * @param {String} fieldName 上传的表单字段名\n     * @param {Object} postData 键值对，上传的POST数据\n     * @param {Number|Array|null|-1} [index]上传的文件序列\n     *                            Int值上传该文件\n     *                            Array一次串行上传该序列文件\n     *                            -1/null上传所有文件\n     * @return {Null}\n     */\n    me.upload = function(url, fieldName, postData, index){\n\n        if(typeof url !== 'string' || typeof fieldName !== 'string') return null;\n        if(typeof index === 'undefined') index = -1;\n\n        _flash.call('upload', [url, fieldName, postData, index]);\n    };\n\n    /**\n     * 取消上传操作\n     * @public\n     * @param {Number|-1} index\n     */\n    me.cancel = function(index){\n        if(typeof index === 'undefined') index = -1;\n        _flash.call('cancel', [index]);\n    };\n\n    /**\n     * 删除文件\n     * @public\n     * @param {Number|Array} [index] 要删除的index，不传则全部删除\n     * @param {Function} callBack\n     * */\n    me.deleteFile = function(index, callBack){\n\n        var callBackAll = function(list){\n                callBack && callBack(list);\n            };\n\n        if(typeof index === 'undefined'){\n            _flash.call('deleteFilesAll', [], callBackAll);\n            return;\n        };\n        \n        if(typeof index === 'Number') index = [index];\n        index.sort(function(a,b){\n            return b-a;\n        });\n        baidu.each(index, function(item){\n            _flash.call('deleteFileBy', item, callBackAll);\n        });\n    };\n\n    /**\n     * 添加文件类型，支持macType\n     * @public\n     * @param {Object|Array[Object]} type {description:String, extention:String}\n     * @return {Null};\n     */\n    me.addFileType = function(type){\n        var type = type || [[]];\n        \n        if(type instanceof Array) type = [type];\n        else type = [[type]];\n        _flash.call('addFileTypes', type);\n    };\n    \n    /**\n     * 设置文件类型，支持macType\n     * @public\n     * @param {Object|Array[Object]} type {description:String, extention:String}\n     * @return {Null};\n     */\n    me.setFileType = function(type){\n        var type = type || [[]];\n        \n        if(type instanceof Array) type = [type];\n        else type = [[type]];\n        _flash.call('setFileTypes', type);\n    };\n\n    /**\n     * 设置可选文件的数量限制\n     * @public\n     * @param {Number} num\n     * @return {Null}\n     */\n    me.setMaxNum = function(num){\n        _flash.call('setMaxNum', [num]);\n    };\n\n    /**\n     * 设置可选文件大小限制，以兆M为单位\n     * @public\n     * @param {Number} num,0为无限制\n     * @return {Null}\n     */\n    me.setMaxSize = function(num){\n        _flash.call('setMaxSize', [num]);\n    };\n\n    /**\n     * @public\n     */\n    me.getFileAll = function(callBack){\n        _flash.call('getFileAll', [], callBack);\n    };\n\n    /**\n     * @public\n     * @param {Number} index\n     * @param {Function} [callBack]\n     */\n    me.getFileByIndex = function(index, callBack){\n        _flash.call('getFileByIndex', [], callBack);\n    };\n\n    /**\n     * @public\n     * @param {Number} index\n     * @param {function} [callBack]\n     */\n    me.getStatusByIndex = function(index, callBack){\n        _flash.call('getStatusByIndex', [], callBack);\n    };\n};\n\n/**\n * 使用动态script标签请求服务器资源，包括由服务器端的回调和浏览器端的回调\n * @namespace baidu.sio\n */\nbaidu.sio = baidu.sio || {};\n\n/**\n * \n * @param {HTMLElement} src script节点\n * @param {String} url script节点的地址\n * @param {String} [charset] 编码\n */\nbaidu.sio._createScriptTag = function(scr, url, charset){\n    scr.setAttribute('type', 'text/javascript');\n    charset && scr.setAttribute('charset', charset);\n    scr.setAttribute('src', url);\n    document.getElementsByTagName('head')[0].appendChild(scr);\n};\n\n/**\n * 删除script的属性，再删除script标签，以解决修复内存泄漏的问题\n * \n * @param {HTMLElement} src script节点\n */\nbaidu.sio._removeScriptTag = function(scr){\n    if (scr.clearAttributes) {\n        scr.clearAttributes();\n    } else {\n        for (var attr in scr) {\n            if (scr.hasOwnProperty(attr)) {\n                delete scr[attr];\n            }\n        }\n    }\n    if(scr && scr.parentNode){\n        scr.parentNode.removeChild(scr);\n    }\n    scr = null;\n};\n\n\n/**\n * 通过script标签加载数据，加载完成由浏览器端触发回调\n * @name baidu.sio.callByBrowser\n * @function\n * @grammar baidu.sio.callByBrowser(url, opt_callback, opt_options)\n * @param {string} url 加载数据的url\n * @param {Function|string} opt_callback 数据加载结束时调用的函数或函数名\n * @param {Object} opt_options 其他可选项\n * @config {String} [charset] script的字符集\n * @config {Integer} [timeOut] 超时时间，超过这个时间将不再响应本请求，并触发onfailure函数\n * @config {Function} [onfailure] timeOut设定后才生效，到达超时时间时触发本函数\n * @remark\n * 1、与callByServer不同，callback参数只支持Function类型，不支持string。\n * 2、如果请求了一个不存在的页面，callback函数在IE/opera下也会被调用，因此使用者需要在onsuccess函数中判断数据是否正确加载。\n * @meta standard\n * @see baidu.sio.callByServer\n */\nbaidu.sio.callByBrowser = function (url, opt_callback, opt_options) {\n    var scr = document.createElement(\"SCRIPT\"),\n        scriptLoaded = 0,\n        options = opt_options || {},\n        charset = options['charset'],\n        callback = opt_callback || function(){},\n        timeOut = options['timeOut'] || 0,\n        timer;\n    scr.onload = scr.onreadystatechange = function () {\n        if (scriptLoaded) {\n            return;\n        }\n        \n        var readyState = scr.readyState;\n        if ('undefined' == typeof readyState\n            || readyState == \"loaded\"\n            || readyState == \"complete\") {\n            scriptLoaded = 1;\n            try {\n                callback();\n                clearTimeout(timer);\n            } finally {\n                scr.onload = scr.onreadystatechange = null;\n                baidu.sio._removeScriptTag(scr);\n            }\n        }\n    };\n\n    if( timeOut ){\n        timer = setTimeout(function(){\n            scr.onload = scr.onreadystatechange = null;\n            baidu.sio._removeScriptTag(scr);\n            options.onfailure && options.onfailure();\n        }, timeOut);\n    }\n    \n    baidu.sio._createScriptTag(scr, url, charset);\n};\n\n/**\n * 通过script标签加载数据，加载完成由服务器端触发回调\n * @name baidu.sio.callByServer\n * @function\n * @grammar baidu.sio.callByServer(url, callback[, opt_options])\n * @param {string} url 加载数据的url.\n * @param {Function|string} callback 服务器端调用的函数或函数名。如果没有指定本参数，将在URL中寻找options['queryField']做为callback的方法名.\n * @param {Object} opt_options 加载数据时的选项.\n * @config {string} [charset] script的字符集\n * @config {string} [queryField] 服务器端callback请求字段名，默认为callback\n * @config {Integer} [timeOut] 超时时间(单位：ms)，超过这个时间将不再响应本请求，并触发onfailure函数\n * @config {Function} [onfailure] timeOut设定后才生效，到达超时时间时触发本函数\n * @remark\n * 如果url中已经包含key为“options['queryField']”的query项，将会被替换成callback中参数传递或自动生成的函数名。\n * @meta standard\n * @see baidu.sio.callByBrowser\n */\nbaidu.sio.callByServer = /**@function*/function(url, callback, opt_options) {\n    var scr = document.createElement('SCRIPT'),\n        prefix = 'bd__cbs__',\n        callbackName,\n        callbackImpl,\n        options = opt_options || {},\n        charset = options['charset'],\n        queryField = options['queryField'] || 'callback',\n        timeOut = options['timeOut'] || 0,\n        timer,\n        reg = new RegExp('(\\\\?|&)' + queryField + '=([^&]*)'),\n        matches;\n\n    if (baidu.lang.isFunction(callback)) {\n        callbackName = prefix + Math.floor(Math.random() * 2147483648).toString(36);\n        window[callbackName] = getCallBack(0);\n    } else if(baidu.lang.isString(callback)){\n        callbackName = callback;\n    } else {\n        if (matches = reg.exec(url)) {\n            callbackName = matches[2];\n        }\n    }\n\n    if( timeOut ){\n        timer = setTimeout(getCallBack(1), timeOut);\n    }\n    url = url.replace(reg, '\\x241' + queryField + '=' + callbackName);\n    \n    if (url.search(reg) < 0) {\n        url += (url.indexOf('?') < 0 ? '?' : '&') + queryField + '=' + callbackName;\n    }\n    baidu.sio._createScriptTag(scr, url, charset);\n\n    /*\n     * 返回一个函数，用于立即（挂在window上）或者超时（挂在setTimeout中）时执行\n     */\n    function getCallBack(onTimeOut){\n        /*global callbackName, callback, scr, options;*/\n        return function(){\n            try {\n                if( onTimeOut ){\n                    options.onfailure && options.onfailure();\n                }else{\n                    callback.apply(window, arguments);\n                    clearTimeout(timer);\n                }\n                window[callbackName] = null;\n                delete window[callbackName];\n            } catch (exception) {\n            } finally {\n                baidu.sio._removeScriptTag(scr);\n            }\n        }\n    }\n};\n\n/**\n * 通过请求一个图片的方式令服务器存储一条日志\n * @function\n * @grammar baidu.sio.log(url)\n * @param {string} url 要发送的地址.\n * @author: int08h,leeight\n */\nbaidu.sio.log = function(url) {\n  var img = new Image(),\n      key = 'tangram_sio_log_' + Math.floor(Math.random() *\n            2147483648).toString(36);\n  window[key] = img;\n\n  img.onload = img.onerror = img.onabort = function() {\n    img.onload = img.onerror = img.onabort = null;\n\n    window[key] = null;\n    img = null;\n  };\n  img.src = url;\n};\n\n\n\n/*\n * Tangram\n * Copyright 2009 Baidu Inc. All rights reserved.\n * \n * path: baidu/json.js\n * author: erik\n * version: 1.1.0\n * date: 2009/12/02\n */\n\n\n/**\n * 操作json对象的方法\n * @namespace baidu.json\n */\nbaidu.json = baidu.json || {};\n/*\n * Tangram\n * Copyright 2009 Baidu Inc. All rights reserved.\n * \n * path: baidu/json/parse.js\n * author: erik, berg\n * version: 1.2\n * date: 2009/11/23\n */\n\n\n\n/**\n * 将字符串解析成json对象。注：不会自动祛除空格\n * @name baidu.json.parse\n * @function\n * @grammar baidu.json.parse(data)\n * @param {string} source 需要解析的字符串\n * @remark\n * 该方法的实现与ecma-262第五版中规定的JSON.parse不同，暂时只支持传入一个参数。后续会进行功能丰富。\n * @meta standard\n * @see baidu.json.stringify,baidu.json.decode\n *             \n * @returns {JSON} 解析结果json对象\n */\nbaidu.json.parse = function (data) {\n    //2010/12/09：更新至不使用原生parse，不检测用户输入是否正确\n    return (new Function(\"return (\" + data + \")\"))();\n};\n/*\n * Tangram\n * Copyright 2009 Baidu Inc. All rights reserved.\n * \n * path: baidu/json/decode.js\n * author: erik, cat\n * version: 1.3.4\n * date: 2010/12/23\n */\n\n\n\n/**\n * 将字符串解析成json对象，为过时接口，今后会被baidu.json.parse代替\n * @name baidu.json.decode\n * @function\n * @grammar baidu.json.decode(source)\n * @param {string} source 需要解析的字符串\n * @meta out\n * @see baidu.json.encode,baidu.json.parse\n *             \n * @returns {JSON} 解析结果json对象\n */\nbaidu.json.decode = baidu.json.parse;\n/*\n * Tangram\n * Copyright 2009 Baidu Inc. All rights reserved.\n * \n * path: baidu/json/stringify.js\n * author: erik\n * version: 1.1.0\n * date: 2010/01/11\n */\n\n\n\n/**\n * 将json对象序列化\n * @name baidu.json.stringify\n * @function\n * @grammar baidu.json.stringify(value)\n * @param {JSON} value 需要序列化的json对象\n * @remark\n * 该方法的实现与ecma-262第五版中规定的JSON.stringify不同，暂时只支持传入一个参数。后续会进行功能丰富。\n * @meta standard\n * @see baidu.json.parse,baidu.json.encode\n *             \n * @returns {string} 序列化后的字符串\n */\nbaidu.json.stringify = (function () {\n    /**\n     * 字符串处理时需要转义的字符表\n     * @private\n     */\n    var escapeMap = {\n        \"\\b\": '\\\\b',\n        \"\\t\": '\\\\t',\n        \"\\n\": '\\\\n',\n        \"\\f\": '\\\\f',\n        \"\\r\": '\\\\r',\n        '\"' : '\\\\\"',\n        \"\\\\\": '\\\\\\\\'\n    };\n    \n    /**\n     * 字符串序列化\n     * @private\n     */\n    function encodeString(source) {\n        if (/[\"\\\\\\x00-\\x1f]/.test(source)) {\n            source = source.replace(\n                /[\"\\\\\\x00-\\x1f]/g, \n                function (match) {\n                    var c = escapeMap[match];\n                    if (c) {\n                        return c;\n                    }\n                    c = match.charCodeAt();\n                    return \"\\\\u00\" \n                            + Math.floor(c / 16).toString(16) \n                            + (c % 16).toString(16);\n                });\n        }\n        return '\"' + source + '\"';\n    }\n    \n    /**\n     * 数组序列化\n     * @private\n     */\n    function encodeArray(source) {\n        var result = [\"[\"], \n            l = source.length,\n            preComma, i, item;\n            \n        for (i = 0; i < l; i++) {\n            item = source[i];\n            \n            switch (typeof item) {\n            case \"undefined\":\n            case \"function\":\n            case \"unknown\":\n                break;\n            default:\n                if(preComma) {\n                    result.push(',');\n                }\n                result.push(baidu.json.stringify(item));\n                preComma = 1;\n            }\n        }\n        result.push(\"]\");\n        return result.join(\"\");\n    }\n    \n    /**\n     * 处理日期序列化时的补零\n     * @private\n     */\n    function pad(source) {\n        return source < 10 ? '0' + source : source;\n    }\n    \n    /**\n     * 日期序列化\n     * @private\n     */\n    function encodeDate(source){\n        return '\"' + source.getFullYear() + \"-\" \n                + pad(source.getMonth() + 1) + \"-\" \n                + pad(source.getDate()) + \"T\" \n                + pad(source.getHours()) + \":\" \n                + pad(source.getMinutes()) + \":\" \n                + pad(source.getSeconds()) + '\"';\n    }\n    \n    return function (value) {\n        switch (typeof value) {\n        case 'undefined':\n            return 'undefined';\n            \n        case 'number':\n            return isFinite(value) ? String(value) : \"null\";\n            \n        case 'string':\n            return encodeString(value);\n            \n        case 'boolean':\n            return String(value);\n            \n        default:\n            if (value === null) {\n                return 'null';\n            } else if (value instanceof Array) {\n                return encodeArray(value);\n            } else if (value instanceof Date) {\n                return encodeDate(value);\n            } else {\n                var result = ['{'],\n                    encode = baidu.json.stringify,\n                    preComma,\n                    item;\n                    \n                for (var key in value) {\n                    if (Object.prototype.hasOwnProperty.call(value, key)) {\n                        item = value[key];\n                        switch (typeof item) {\n                        case 'undefined':\n                        case 'unknown':\n                        case 'function':\n                            break;\n                        default:\n                            if (preComma) {\n                                result.push(',');\n                            }\n                            preComma = 1;\n                            result.push(encode(key) + ':' + encode(item));\n                        }\n                    }\n                }\n                result.push('}');\n                return result.join('');\n            }\n        }\n    };\n})();\n/*\n * Tangram\n * Copyright 2009 Baidu Inc. All rights reserved.\n * \n * path: baidu/json/encode.js\n * author: erik, cat\n * version: 1.3.4\n * date: 2010/12/23\n */\n\n\n\n/**\n * 将json对象序列化，为过时接口，今后会被baidu.json.stringify代替\n * @name baidu.json.encode\n * @function\n * @grammar baidu.json.encode(value)\n * @param {JSON} value 需要序列化的json对象\n * @meta out\n * @see baidu.json.decode,baidu.json.stringify\n *             \n * @returns {string} 序列化后的字符串\n */\nbaidu.json.encode = baidu.json.stringify;\n"
  },
  {
    "path": "public/static/ueditor/dialogs/wordimage/wordimage.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n        \"http://www.w3.org/TR/html4/loose.dtd\">\r\n<html>\r\n<head>\r\n    <title></title>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/>\r\n    <script type=\"text/javascript\" src=\"../internal.js\"></script>\r\n    <style type=\"text/css\">\r\n        .wrapper{width: 600px;padding: 10px;height: 352px;overflow: hidden;position: relative;border-bottom: 1px solid #d7d7d7}\r\n        .localPath input{float: left;width: 350px;line-height: 20px;height: 20px;}\r\n        #clipboard{float:left;width: 70px;height: 30px; }\r\n        .description{ color: #0066cc; margin-top: 2px; width: 450px; height: 45px;float: left;line-height: 22px}\r\n        #upload{width: 100px;height: 30px;float: right; margin:10px 2px 0 0;cursor: pointer;}\r\n        #msg{ width: 140px; height: 30px; line-height:25px;float: left;color: red}\r\n    </style>\r\n</head>\r\n<body>\r\n    <div class=\"wrapper\">\r\n        <div class=\"localPath\">\r\n            <input id=\"localPath\" type=\"text\" readonly />\r\n            <div id=\"clipboard\"></div>\r\n            <div id=\"msg\"></div>\r\n        </div>\r\n        <div id=\"flashContainer\"></div>\r\n        <div>\r\n            <div id=\"upload\" style=\"display: none\" ><img id=\"uploadBtn\"></div>\r\n            <div class=\"description\">\r\n                <span style=\"color: red\"><var id=\"lang_resave\"></var>: </span><var id=\"lang_step\"></var>\r\n            </div>\r\n          </div>\r\n    </div>\r\n    <script type=\"text/javascript\" src=\"tangram.js\"></script>\r\n    <script type=\"text/javascript\" src=\"wordimage.js\"></script>\r\n    <script type=\"text/javascript\">\r\n        editor.setOpt({\r\n            wordImageFieldName:\"upfile\",\r\n            compressSide:0,\r\n            maxImageSideLength:900\r\n        });\r\n\r\n            //全局变量\r\n        var imageUrls = [],          //用于保存从服务器返回的图片信息数组\r\n            selectedImageCount = 0,  //当前已选择的但未上传的图片数量\r\n            optImageUrl = editor.getActionUrl(editor.getOpt('imageActionName')),\r\n            optImageFieldName = editor.getOpt('imageFieldName'),\r\n            optImageCompressBorder = editor.getOpt('imageCompressEnable') ? editor.getOpt('imageCompressBorder'):null,\r\n            maxSize = editor.getOpt('imageMaxSize') / 1024,\r\n            extension = editor.getOpt('imageAllowFiles').join(';').replace(/\\./g, '*.');\r\n\r\n        /* 添加额外的GET参数 */\r\n        var params = utils.serializeParam(editor.queryCommandValue('serverparam')) || '',\r\n            urlWidthParams = optImageUrl + (optImageUrl.indexOf('?') == -1 ? '?':'&') + params;\r\n\r\n        utils.domReady(function(){\r\n            //创建Flash相关的参数集合\r\n            var flashOptions = {\r\n                container:\"flashContainer\",                                                    //flash容器id\r\n                url:urlWidthParams,                                           // 上传处理页面的url地址\r\n                ext:editor.queryCommandValue('serverParam') || {},                                 //可向服务器提交的自定义参数列表\r\n                fileType:'{\"description\":\"'+lang.fileType+'\", \"extension\":\"' + extension + '\"}',     //上传文件格式限制\r\n                flashUrl:'imageUploader.swf',                                                  //上传用的flash组件地址\r\n                width:600,          //flash的宽度\r\n                height:272,         //flash的高度\r\n                gridWidth:120,     // 每一个预览图片所占的宽度\r\n                gridHeight:120,    // 每一个预览图片所占的高度\r\n                picWidth:100,      // 单张预览图片的宽度\r\n                picHeight:100,     // 单张预览图片的高度\r\n                uploadDataFieldName: optImageFieldName,    // POST请求中图片数据的key\r\n                picDescFieldName:'pictitle',      // POST请求中图片描述的key\r\n                maxSize: maxSize,                         // 文件的最大体积,单位M\r\n                compressSize:1,                   // 上传前如果图片体积超过该值，会先压缩,单位M\r\n                maxNum:32,                         // 单次最大可上传多少个文件\r\n                compressSide: 0,                 //等比压缩的基准，0为按照最长边，1为按照宽度，2为按照高度\r\n                compressLength: optImageCompressBorder        //能接受的最大边长，超过该值Flash会自动等比压缩\r\n            };\r\n            //回调函数集合，支持传递函数名的字符串、函数句柄以及函数本身三种类型\r\n            var callbacks={\r\n                selectFileCallback: function(selectFiles){                // 选择文件的回调\r\n                    selectedImageCount += selectFiles.length;\r\n                    if(selectedImageCount) baidu.g(\"upload\").style.display = \"\";\r\n                    dialog.buttons[0].setDisabled(true); //初始化时置灰确定按钮\r\n                },\r\n                deleteFileCallback: function(delFiles){                 // 删除文件的回调\r\n                    selectedImageCount -= delFiles.length;\r\n                    if (!selectedImageCount) {\r\n                        baidu.g(\"upload\").style.display = \"none\";\r\n                        dialog.buttons[0].setDisabled(false);         //没有选择图片时重新点亮按钮\r\n                    }\r\n                },\r\n                uploadCompleteCallback: function(data){               // 单个文件上传完成的回调\r\n                    try{var info = eval(\"(\" + data.info + \")\");\r\n                    info && imageUrls.push(info);\r\n                    selectedImageCount--;\r\n                    }catch(e){}\r\n                },\r\n                uploadErrorCallback: function (data){         // 单个文件上传失败的回调,\r\n                    console && console.log(data);\r\n                },\r\n                allCompleteCallback: function(){              // 全部上传完成时的回调\r\n                    dialog.buttons[0].setDisabled(false);    //上传完毕后点亮按钮\r\n                }\r\n                //exceedFileCallback: 'exceedFileCallback',   // 文件超出限制的最大体积时的回调\r\n                //startUploadCallback: startUploadCallback    // 开始上传某个文件时的回调\r\n            };\r\n            wordImage.init(flashOptions,callbacks);\r\n        });\r\n\r\n    </script>\r\n\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/dialogs/wordimage/wordimage.js",
    "content": "/**\r\n * Created by JetBrains PhpStorm.\r\n * User: taoqili\r\n * Date: 12-1-30\r\n * Time: 下午12:50\r\n * To change this template use File | Settings | File Templates.\r\n */\r\n\r\n\r\n\r\nvar wordImage = {};\r\n//(function(){\r\nvar g = baidu.g,\r\n\tflashObj,flashContainer;\r\n\r\nwordImage.init = function(opt, callbacks) {\r\n\tshowLocalPath(\"localPath\");\r\n\t//createCopyButton(\"clipboard\",\"localPath\");\r\n\tcreateFlashUploader(opt, callbacks);\r\n\taddUploadListener();\r\n\taddOkListener();\r\n};\r\n\r\nfunction hideFlash(){\r\n    flashObj = null;\r\n    flashContainer.innerHTML = \"\";\r\n}\r\nfunction addOkListener() {\r\n\tdialog.onok = function() {\r\n\t\tif (!imageUrls.length) return;\r\n\t\tvar urlPrefix = editor.getOpt('imageUrlPrefix'),\r\n            images = domUtils.getElementsByTagName(editor.document,\"img\");\r\n        editor.fireEvent('saveScene');\r\n\t\tfor (var i = 0,img; img = images[i++];) {\r\n\t\t\tvar src = img.getAttribute(\"word_img\");\r\n\t\t\tif (!src) continue;\r\n\t\t\tfor (var j = 0,url; url = imageUrls[j++];) {\r\n\t\t\t\tif (src.indexOf(url.original.replace(\" \",\"\")) != -1) {\r\n\t\t\t\t\timg.src = urlPrefix + url.url;\r\n\t\t\t\t\timg.setAttribute(\"_src\", urlPrefix + url.url);  //同时修改\"_src\"属性\r\n\t\t\t\t\timg.setAttribute(\"title\",url.title);\r\n                    domUtils.removeAttributes(img, [\"word_img\",\"style\",\"width\",\"height\"]);\r\n\t\t\t\t\teditor.fireEvent(\"selectionchange\");\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n        editor.fireEvent('saveScene');\r\n        hideFlash();\r\n\t};\r\n    dialog.oncancel = function(){\r\n        hideFlash();\r\n    }\r\n}\r\n\r\n/**\r\n * 绑定开始上传事件\r\n */\r\nfunction addUploadListener() {\r\n\tg(\"upload\").onclick = function () {\r\n\t\tflashObj.upload();\r\n\t\tthis.style.display = \"none\";\r\n\t};\r\n}\r\n\r\nfunction showLocalPath(id) {\r\n    //单张编辑\r\n    var img = editor.selection.getRange().getClosedNode();\r\n    var images = editor.execCommand('wordimage');\r\n    if(images.length==1 || img && img.tagName == 'IMG'){\r\n        g(id).value = images[0];\r\n        return;\r\n    }\r\n\tvar path = images[0];\r\n    var leftSlashIndex  = path.lastIndexOf(\"/\")||0,  //不同版本的doc和浏览器都可能影响到这个符号，故直接判断两种\r\n        rightSlashIndex = path.lastIndexOf(\"\\\\\")||0,\r\n        separater = leftSlashIndex > rightSlashIndex ? \"/\":\"\\\\\" ;\r\n\r\n\tpath = path.substring(0, path.lastIndexOf(separater)+1);\r\n\tg(id).value = path;\r\n}\r\n\r\nfunction createFlashUploader(opt, callbacks) {\r\n    //由于lang.flashI18n是静态属性，不可以直接进行修改，否则会影响到后续内容\r\n    var i18n = utils.extend({},lang.flashI18n);\r\n    //处理图片资源地址的编码，补全等问题\r\n    for(var i in i18n){\r\n        if(!(i in {\"lang\":1,\"uploadingTF\":1,\"imageTF\":1,\"textEncoding\":1}) && i18n[i]){\r\n            i18n[i] = encodeURIComponent(editor.options.langPath + editor.options.lang + \"/images/\" + i18n[i]);\r\n        }\r\n    }\r\n    opt = utils.extend(opt,i18n,false);\r\n\tvar option = {\r\n\t\tcreateOptions:{\r\n\t\t\tid:'flash',\r\n\t\t\turl:opt.flashUrl,\r\n\t\t\twidth:opt.width,\r\n\t\t\theight:opt.height,\r\n\t\t\terrorMessage:lang.flashError,\r\n\t\t\twmode:browser.safari ? 'transparent' : 'window',\r\n\t\t\tver:'10.0.0',\r\n\t\t\tvars:opt,\r\n\t\t\tcontainer:opt.container\r\n\t\t}\r\n\t};\r\n\r\n\toption = extendProperty(callbacks, option);\r\n\tflashObj = new baidu.flash.imageUploader(option);\r\n    flashContainer = $G(opt.container);\r\n}\r\n\r\nfunction extendProperty(fromObj, toObj) {\r\n\tfor (var i in fromObj) {\r\n\t\tif (!toObj[i]) {\r\n\t\t\ttoObj[i] = fromObj[i];\r\n\t\t}\r\n\t}\r\n\treturn toObj;\r\n}\r\n\r\n//})();\r\n\r\nfunction getPasteData(id) {\r\n\tbaidu.g(\"msg\").innerHTML = lang.copySuccess + \"</br>\";\r\n\tsetTimeout(function() {\r\n\t\tbaidu.g(\"msg\").innerHTML = \"\";\r\n\t}, 5000);\r\n\treturn baidu.g(id).value;\r\n}\r\n\r\nfunction createCopyButton(id, dataFrom) {\r\n\tbaidu.swf.create({\r\n\t\t\tid:\"copyFlash\",\r\n\t\t\turl:\"fClipboard_ueditor.swf\",\r\n\t\t\twidth:\"58\",\r\n\t\t\theight:\"25\",\r\n\t\t\terrorMessage:\"\",\r\n\t\t\tbgColor:\"#CBCBCB\",\r\n\t\t\twmode:\"transparent\",\r\n\t\t\tver:\"10.0.0\",\r\n\t\t\tvars:{\r\n\t\t\t\ttid:dataFrom\r\n\t\t\t}\r\n\t\t}, id\r\n\t);\r\n\r\n\tvar clipboard = baidu.swf.getMovie(\"copyFlash\");\r\n\tvar clipinterval = setInterval(function() {\r\n\t\tif (clipboard && clipboard.flashInit) {\r\n\t\t\tclearInterval(clipinterval);\r\n\t\t\tclipboard.setHandCursor(true);\r\n\t\t\tclipboard.setContentFuncName(\"getPasteData\");\r\n\t\t\t//clipboard.setMEFuncName(\"mouseEventHandler\");\r\n\t\t}\r\n\t}, 500);\r\n}\r\ncreateCopyButton(\"clipboard\", \"localPath\");"
  },
  {
    "path": "public/static/ueditor/index.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\"\r\n        \"http://www.w3.org/TR/html4/loose.dtd\">\r\n<html>\r\n<head>\r\n    <title>完整demo</title>\r\n    <meta http-equiv=\"Content-Type\" content=\"text/html;charset=utf-8\"/>\r\n    <script type=\"text/javascript\" charset=\"utf-8\" src=\"ueditor.config.js\"></script>\r\n    <script type=\"text/javascript\" charset=\"utf-8\" src=\"ueditor.all.min.js\"> </script>\r\n    <!--建议手动加在语言，避免在ie下有时因为加载语言失败导致编辑器加载失败-->\r\n    <!--这里加载的语言文件会覆盖你在配置项目里添加的语言类型，比如你在配置项目里配置的是英文，这里加载的中文，那最后就是中文-->\r\n    <script type=\"text/javascript\" charset=\"utf-8\" src=\"lang/zh-cn/zh-cn.js\"></script>\r\n\r\n    <style type=\"text/css\">\r\n        div{\r\n            width:100%;\r\n        }\r\n    </style>\r\n</head>\r\n<body>\r\n<div>\r\n    <h1>完整demo</h1>\r\n    <script id=\"editor\" type=\"text/plain\" style=\"width:1024px;height:500px;\"></script>\r\n</div>\r\n<div id=\"btns\">\r\n    <div>\r\n        <button onclick=\"getAllHtml()\">获得整个html的内容</button>\r\n        <button onclick=\"getContent()\">获得内容</button>\r\n        <button onclick=\"setContent()\">写入内容</button>\r\n        <button onclick=\"setContent(true)\">追加内容</button>\r\n        <button onclick=\"getContentTxt()\">获得纯文本</button>\r\n        <button onclick=\"getPlainTxt()\">获得带格式的纯文本</button>\r\n        <button onclick=\"hasContent()\">判断是否有内容</button>\r\n        <button onclick=\"setFocus()\">使编辑器获得焦点</button>\r\n        <button onmousedown=\"isFocus(event)\">编辑器是否获得焦点</button>\r\n        <button onmousedown=\"setblur(event)\" >编辑器失去焦点</button>\r\n\r\n    </div>\r\n    <div>\r\n        <button onclick=\"getText()\">获得当前选中的文本</button>\r\n        <button onclick=\"insertHtml()\">插入给定的内容</button>\r\n        <button id=\"enable\" onclick=\"setEnabled()\">可以编辑</button>\r\n        <button onclick=\"setDisabled()\">不可编辑</button>\r\n        <button onclick=\" UE.getEditor('editor').setHide()\">隐藏编辑器</button>\r\n        <button onclick=\" UE.getEditor('editor').setShow()\">显示编辑器</button>\r\n        <button onclick=\" UE.getEditor('editor').setHeight(300)\">设置高度为300默认关闭了自动长高</button>\r\n    </div>\r\n\r\n    <div>\r\n        <button onclick=\"getLocalData()\" >获取草稿箱内容</button>\r\n        <button onclick=\"clearLocalData()\" >清空草稿箱</button>\r\n    </div>\r\n\r\n</div>\r\n<div>\r\n    <button onclick=\"createEditor()\">\r\n    创建编辑器</button>\r\n    <button onclick=\"deleteEditor()\">\r\n    删除编辑器</button>\r\n</div>\r\n\r\n<script type=\"text/javascript\">\r\n\r\n    //实例化编辑器\r\n    //建议使用工厂方法getEditor创建和引用编辑器实例，如果在某个闭包下引用该编辑器，直接调用UE.getEditor('editor')就能拿到相关的实例\r\n    var ue = UE.getEditor('editor');\r\n\r\n\r\n    function isFocus(e){\r\n        alert(UE.getEditor('editor').isFocus());\r\n        UE.dom.domUtils.preventDefault(e)\r\n    }\r\n    function setblur(e){\r\n        UE.getEditor('editor').blur();\r\n        UE.dom.domUtils.preventDefault(e)\r\n    }\r\n    function insertHtml() {\r\n        var value = prompt('插入html代码', '');\r\n        UE.getEditor('editor').execCommand('insertHtml', value)\r\n    }\r\n    function createEditor() {\r\n        enableBtn();\r\n        UE.getEditor('editor');\r\n    }\r\n    function getAllHtml() {\r\n        alert(UE.getEditor('editor').getAllHtml())\r\n    }\r\n    function getContent() {\r\n        var arr = [];\r\n        arr.push(\"使用editor.getContent()方法可以获得编辑器的内容\");\r\n        arr.push(\"内容为：\");\r\n        arr.push(UE.getEditor('editor').getContent());\r\n        alert(arr.join(\"\\n\"));\r\n    }\r\n    function getPlainTxt() {\r\n        var arr = [];\r\n        arr.push(\"使用editor.getPlainTxt()方法可以获得编辑器的带格式的纯文本内容\");\r\n        arr.push(\"内容为：\");\r\n        arr.push(UE.getEditor('editor').getPlainTxt());\r\n        alert(arr.join('\\n'))\r\n    }\r\n    function setContent(isAppendTo) {\r\n        var arr = [];\r\n        arr.push(\"使用editor.setContent('欢迎使用ueditor')方法可以设置编辑器的内容\");\r\n        UE.getEditor('editor').setContent('欢迎使用ueditor', isAppendTo);\r\n        alert(arr.join(\"\\n\"));\r\n    }\r\n    function setDisabled() {\r\n        UE.getEditor('editor').setDisabled('fullscreen');\r\n        disableBtn(\"enable\");\r\n    }\r\n\r\n    function setEnabled() {\r\n        UE.getEditor('editor').setEnabled();\r\n        enableBtn();\r\n    }\r\n\r\n    function getText() {\r\n        //当你点击按钮时编辑区域已经失去了焦点，如果直接用getText将不会得到内容，所以要在选回来，然后取得内容\r\n        var range = UE.getEditor('editor').selection.getRange();\r\n        range.select();\r\n        var txt = UE.getEditor('editor').selection.getText();\r\n        alert(txt)\r\n    }\r\n\r\n    function getContentTxt() {\r\n        var arr = [];\r\n        arr.push(\"使用editor.getContentTxt()方法可以获得编辑器的纯文本内容\");\r\n        arr.push(\"编辑器的纯文本内容为：\");\r\n        arr.push(UE.getEditor('editor').getContentTxt());\r\n        alert(arr.join(\"\\n\"));\r\n    }\r\n    function hasContent() {\r\n        var arr = [];\r\n        arr.push(\"使用editor.hasContents()方法判断编辑器里是否有内容\");\r\n        arr.push(\"判断结果为：\");\r\n        arr.push(UE.getEditor('editor').hasContents());\r\n        alert(arr.join(\"\\n\"));\r\n    }\r\n    function setFocus() {\r\n        UE.getEditor('editor').focus();\r\n    }\r\n    function deleteEditor() {\r\n        disableBtn();\r\n        UE.getEditor('editor').destroy();\r\n    }\r\n    function disableBtn(str) {\r\n        var div = document.getElementById('btns');\r\n        var btns = UE.dom.domUtils.getElementsByTagName(div, \"button\");\r\n        for (var i = 0, btn; btn = btns[i++];) {\r\n            if (btn.id == str) {\r\n                UE.dom.domUtils.removeAttributes(btn, [\"disabled\"]);\r\n            } else {\r\n                btn.setAttribute(\"disabled\", \"true\");\r\n            }\r\n        }\r\n    }\r\n    function enableBtn() {\r\n        var div = document.getElementById('btns');\r\n        var btns = UE.dom.domUtils.getElementsByTagName(div, \"button\");\r\n        for (var i = 0, btn; btn = btns[i++];) {\r\n            UE.dom.domUtils.removeAttributes(btn, [\"disabled\"]);\r\n        }\r\n    }\r\n\r\n    function getLocalData () {\r\n        alert(UE.getEditor('editor').execCommand( \"getlocaldata\" ));\r\n    }\r\n\r\n    function clearLocalData () {\r\n        UE.getEditor('editor').execCommand( \"clearlocaldata\" );\r\n        alert(\"已清空草稿箱\")\r\n    }\r\n</script>\r\n</body>\r\n</html>"
  },
  {
    "path": "public/static/ueditor/lang/en/en.js",
    "content": "/**\r\n * Created with JetBrains PhpStorm.\r\n * User: taoqili\r\n * Date: 12-6-12\r\n * Time: 下午6:57\r\n * To change this template use File | Settings | File Templates.\r\n */\r\nUE.I18N['en'] = {\r\n    'labelMap':{\r\n        'anchor':'Anchor', 'undo':'Undo', 'redo':'Redo', 'bold':'Bold', 'indent':'Indent', 'snapscreen':'SnapScreen',\r\n        'italic':'Italic', 'underline':'Underline', 'strikethrough':'Strikethrough', 'subscript':'SubScript','fontborder':'text border',\r\n        'superscript':'SuperScript', 'formatmatch':'Format Match', 'source':'Source', 'blockquote':'BlockQuote',\r\n        'pasteplain':'PastePlain', 'selectall':'SelectAll', 'print':'Print', 'preview':'Preview',\r\n        'horizontal':'Horizontal', 'removeformat':'RemoveFormat', 'time':'Time', 'date':'Date',\r\n        'unlink':'Unlink', 'insertrow':'InsertRow', 'insertcol':'InsertCol', 'mergeright':'MergeRight', 'mergedown':'MergeDown',\r\n        'deleterow':'DeleteRow', 'deletecol':'DeleteCol', 'splittorows':'SplitToRows','insertcode':'insert code',\r\n        'splittocols':'SplitToCols', 'splittocells':'SplitToCells','deletecaption':'DeleteCaption','inserttitle':'InsertTitle',\r\n        'mergecells':'MergeCells', 'deletetable':'DeleteTable', 'cleardoc':'Clear', 'insertparagraphbeforetable':\"InsertParagraphBeforeTable\",\r\n        'fontfamily':'FontFamily', 'fontsize':'FontSize', 'paragraph':'Paragraph','simpleupload':'Single Image','insertimage':'Multi Image','edittable':'Edit Table', 'edittd':'Edit Td','link':'Link',\r\n        'emotion':'Emotion', 'spechars':'Spechars', 'searchreplace':'SearchReplace', 'map':'BaiduMap', 'gmap':'GoogleMap',\r\n        'insertvideo':'Video', 'help':'Help', 'justifyleft':'JustifyLeft', 'justifyright':'JustifyRight', 'justifycenter':'JustifyCenter',\r\n        'justifyjustify':'Justify', 'forecolor':'FontColor', 'backcolor':'BackColor', 'insertorderedlist':'OL',\r\n        'insertunorderedlist':'UL', 'fullscreen':'FullScreen', 'directionalityltr':'EnterFromLeft', 'directionalityrtl':'EnterFromRight',\r\n        'rowspacingtop':'RowSpacingTop', 'rowspacingbottom':'RowSpacingBottom', 'pagebreak':'PageBreak', 'insertframe':'Iframe', 'imagenone':'Default',\r\n        'imageleft':'ImageLeft', 'imageright':'ImageRight', 'attachment':'Attachment', 'imagecenter':'ImageCenter', 'wordimage':'WordImage',\r\n        'lineheight':'LineHeight','edittip':'EditTip','customstyle':'CustomStyle', 'scrawl':'Scrawl', 'autotypeset':'AutoTypeset',\r\n        'webapp':'WebAPP', 'touppercase':'UpperCase', 'tolowercase':'LowerCase','template':'Template','background':'Background','inserttable':'InsertTable',\r\n        'music':'Music', 'charts': 'charts','drafts': 'Load from Drafts'\r\n    },\r\n    'insertorderedlist':{\r\n        'num':'1,2,3...',\r\n        'num1':'1),2),3)...',\r\n        'num2':'(1),(2),(3)...',\r\n        'cn':'一,二,三....',\r\n        'cn1':'一),二),三)....',\r\n        'cn2':'(一),(二),(三)....',\r\n        'decimal':'1,2,3...',\r\n        'lower-alpha':'a,b,c...',\r\n        'lower-roman':'i,ii,iii...',\r\n        'upper-alpha':'A,B,C...',\r\n        'upper-roman':'I,II,III...'\r\n    },\r\n    'insertunorderedlist':{\r\n        'circle':'○ Circle',\r\n        'disc':'● Circle dot',\r\n        'square':'■ Rectangle ',\r\n        'dash' :'－ Dash',\r\n        'dot' : '。dot'\r\n    },\r\n    'paragraph':{'p':'Paragraph', 'h1':'Title 1', 'h2':'Title 2', 'h3':'Title 3', 'h4':'Title 4', 'h5':'Title 5', 'h6':'Title 6'},\r\n    'fontfamily':{\r\n        'songti':'Sim Sun',\r\n        'kaiti':'Sim Kai',\r\n        'heiti':'Sim Hei',\r\n        'lishu':'Sim Li',\r\n        'yahei': 'Microsoft YaHei',\r\n        'andaleMono':'Andale Mono',\r\n        'arial': 'Arial',\r\n        'arialBlack':'Arial Black',\r\n        'comicSansMs':'Comic Sans MS',\r\n        'impact':'Impact',\r\n        'timesNewRoman':'Times New Roman'\r\n    },\r\n    'customstyle':{\r\n        'tc':'Title center',\r\n        'tl':'Title left',\r\n        'im':'Important',\r\n        'hi':'Highlight'\r\n    },\r\n    'autoupload': {\r\n        'exceedSizeError': 'File Size Exceed',\r\n        'exceedTypeError': 'File Type Not Allow',\r\n        'jsonEncodeError': 'Server Return Format Error',\r\n        'loading':\"loading...\",\r\n        'loadError':\"load error\",\r\n        'errorLoadConfig': 'Server config not loaded, upload can not work.',\r\n    },\r\n    'simpleupload':{\r\n        'exceedSizeError': 'File Size Exceed',\r\n        'exceedTypeError': 'File Type Not Allow',\r\n        'jsonEncodeError': 'Server Return Format Error',\r\n        'loading':\"loading...\",\r\n        'loadError':\"load error\",\r\n        'errorLoadConfig': 'Server config not loaded, upload can not work.',\r\n    },\r\n    'elementPathTip':\"Path\",\r\n    'wordCountTip':\"Word Count\",\r\n    'wordCountMsg':'{#count} characters entered,{#leave} left. ',\r\n    'wordOverFlowMsg':'<span style=\"color:red;\">The number of characters has exceeded allowable maximum values, the server may refuse to save!</span>',\r\n    'ok':\"OK\",\r\n    'cancel':\"Cancel\",\r\n    'closeDialog':\"closeDialog\",\r\n    'tableDrag':\"You must import the file uiUtils.js before drag! \",\r\n    'autofloatMsg':\"The plugin AutoFloat depends on EditorUI!\",\r\n    'loadconfigError': 'Get server config error.',\r\n    'loadconfigFormatError': 'Server config format error.',\r\n    'loadconfigHttpError': 'Get server config http error.',\r\n    'snapScreen_plugin':{\r\n        'browserMsg':\"Only IE supported!\",\r\n        'callBackErrorMsg':\"The callback data is wrong,please check the config!\",\r\n        'uploadErrorMsg':\"Upload error,please check your server environment! \"\r\n    },\r\n    'insertcode':{\r\n        'as3':'ActionScript 3',\r\n        'bash':'Bash/Shell',\r\n        'cpp':'C/C++',\r\n        'css':'CSS',\r\n        'cf':'ColdFusion',\r\n        'c#':'C#',\r\n        'delphi':'Delphi',\r\n        'diff':'Diff',\r\n        'erlang':'Erlang',\r\n        'groovy':'Groovy',\r\n        'html':'HTML',\r\n        'java':'Java',\r\n        'jfx':'JavaFX',\r\n        'js':'JavaScript',\r\n        'pl':'Perl',\r\n        'php':'PHP',\r\n        'plain':'Plain Text',\r\n        'ps':'PowerShell',\r\n        'python':'Python',\r\n        'ruby':'Ruby',\r\n        'scala':'Scala',\r\n        'sql':'SQL',\r\n        'vb':'Visual Basic',\r\n        'xml':'XML'\r\n    },\r\n    'confirmClear':\"Do you confirm to clear the Document?\",\r\n    'contextMenu':{\r\n        'delete':\"Delete\",\r\n        'selectall':\"Select all\",\r\n        'deletecode':\"Delete Code\",\r\n        'cleardoc':\"Clear Document\",\r\n        'confirmclear':\"Do you confirm to clear the Document?\",\r\n        'unlink':\"Unlink\",\r\n        'paragraph':\"Paragraph\",\r\n        'edittable':\"Table property\",\r\n        'aligncell':'Align cell',\r\n        'aligntable':'Table alignment',\r\n        'tableleft':'Left float',\r\n        'tablecenter':'Center',\r\n        'tableright':'Right float',\r\n        'aligntd':'Cell alignment',\r\n        'edittd':\"Cell property\",\r\n        'setbordervisible':'set table edge visible',\r\n        'table':\"Table\",\r\n        'justifyleft':'Justify Left',\r\n        'justifyright':'Justify Right',\r\n        'justifycenter':'Justify Center',\r\n        'justifyjustify':'Default',\r\n        'deletetable':\"Delete table\",\r\n        'insertparagraphbefore':\"InsertedBeforeLine\",\r\n        'insertparagraphafter':'InsertedAfterLine',\r\n        'inserttable':'Insert table',\r\n        'insertcaption':'Insert caption',\r\n        'deletecaption':'Delete Caption',\r\n        'inserttitle':'Insert Title',\r\n        'deletetitle':'Delete Title',\r\n        'inserttitlecol':'Insert Title Col',\r\n        'deletetitlecol':'Delete Title Col',\r\n        'averageDiseRow':'AverageDise Row',\r\n        'averageDisCol':'AverageDis Col',\r\n        'deleterow':\"Delete row\",\r\n        'deletecol':\"Delete col\",\r\n        'insertrow':\"Insert row\",\r\n        'insertcol':\"Insert col\",\r\n        'insertrownext':'Insert Row Next',\r\n        'insertcolnext':'Insert Col Next',\r\n        'mergeright':\"Merge right\",\r\n        'mergeleft':\"Merge left\",\r\n        'mergedown':\"Merge down\",\r\n        'mergecells':\"Merge cells\",\r\n        'splittocells':\"Split to cells\",\r\n        'splittocols':\"Split to Cols\",\r\n        'splittorows':\"Split to Rows\",\r\n        'tablesort':'Table sorting',\r\n        'enablesort':'Sorting Enable',\r\n        'disablesort':'Sorting Disable',\r\n        'reversecurrent':'Reverse current',\r\n        'orderbyasc':'Order By ASCII',\r\n        'reversebyasc':'Reverse By ASCII',\r\n        'orderbynum':'Order By Num',\r\n        'reversebynum':'Reverse By Num',\r\n        'borderbk':'Border shading',\r\n        'setcolor':'interlaced color',\r\n        'unsetcolor':'Cancel interlacedcolor',\r\n        'setbackground':'Background interlaced',\r\n        'unsetbackground':'Cancel Bk interlaced',\r\n        'redandblue':'Blue and red',\r\n        'threecolorgradient':'Three-color gradient',\r\n        'copy':\"Copy(Ctrl + c)\",\r\n        'copymsg':\"Browser does not support. Please use 'Ctrl + c' instead!\",\r\n        'paste':\"Paste(Ctrl + v)\",\r\n        'pastemsg':\"Browser does not support. Please use 'Ctrl + v' instead!\"\r\n    },\r\n    'copymsg': \"Browser does not support. Please use 'Ctrl + c' instead!\",\r\n    'pastemsg': \"Browser does not support. Please use 'Ctrl + v' instead!\",\r\n    'anthorMsg':\"Link\",\r\n    'clearColor':'Clear',\r\n    'standardColor':'Standard color',\r\n    'themeColor':'Theme color',\r\n    'property':'Property',\r\n    'default':'Default',\r\n    'modify':'Modify',\r\n    'justifyleft':'Justify Left',\r\n    'justifyright':'Justify Right',\r\n    'justifycenter':'Justify Center',\r\n    'justify':'Default',\r\n    'clear':'Clear',\r\n    'anchorMsg':'Anchor',\r\n    'delete':'Delete',\r\n    'clickToUpload':\"Click to upload\",\r\n    'unset':'Language hasn\\'t been set!',\r\n    't_row':'row',\r\n    't_col':'col',\r\n    'pasteOpt':'Paste Option',\r\n    'pasteSourceFormat':\"Keep Source Formatting\",\r\n    'tagFormat':'Keep tag',\r\n    'pasteTextFormat':'Keep Text only',\r\n    'more':'More',\r\n    'autoTypeSet':{\r\n        'mergeLine':\"Merge empty line\",\r\n        'delLine':\"Del empty line\",\r\n        'removeFormat':\"Remove format\",\r\n        'indent':\"Indent\",\r\n        'alignment':\"Alignment\",\r\n        'imageFloat':\"Image float\",\r\n        'removeFontsize':\"Remove font size\",\r\n        'removeFontFamily':\"Remove fontFamily\",\r\n        'removeHtml':\"Remove redundant HTML code\",\r\n        'pasteFilter':\"Paste filter\",\r\n        'run':\"Done\",\r\n        'symbol':'Symbol Conversion',\r\n        'bdc2sb':'Full-width to Half-width',\r\n        'tobdc':'Half-width to Full-width'\r\n    },\r\n\r\n    'background':{\r\n        'static':{\r\n            'lang_background_normal':'Normal',\r\n            'lang_background_local':'Online',\r\n            'lang_background_set':'Background Set',\r\n            'lang_background_none':'No Background',\r\n            'lang_background_colored':'Colored Background',\r\n            'lang_background_color':'Color Set',\r\n            'lang_background_netimg':'Net-Image',\r\n            'lang_background_align':'Align Type',\r\n            'lang_background_position':'Position',\r\n            'repeatType':{'options':[\"Center\", \"Repeat-x\", \"Repeat-y\", \"Tile\",\"Custom\"]}\r\n        },\r\n        'noUploadImage':\"No pictures has been uploaded！\",\r\n        'toggleSelect':'Change the active state by click!\\n Image Size: '\r\n    },\r\n    //===============dialog i18N=======================\r\n    'insertimage':{\r\n        'static':{\r\n            'lang_tab_remote':\"Insert\",\r\n            'lang_tab_upload':\"Local\",\r\n            'lang_tab_online':\"Manager\",\r\n            'lang_tab_search':\"Search\",\r\n            'lang_input_url':\"Address:\",\r\n            'lang_input_size':\"Size:\",\r\n            'lang_input_width':\"Width\",\r\n            'lang_input_height':\"Height\",\r\n            'lang_input_border':\"Border:\",\r\n            'lang_input_vhspace':\"Margins:\",\r\n            'lang_input_title':\"Title:\",\r\n            'lang_input_align':'Image Float Style:',\r\n            'lang_imgLoading':\"Loading...\",\r\n            'lang_start_upload':\"Start Upload\",\r\n            'lock':{'title':\"Lock rate\"},\r\n            'searchType':{'title':\"ImageType\", 'options':[\"News\", \"Wallpaper\", \"emotions\", \"photo\"]},\r\n            'searchTxt':{'value':\"Enter the search keyword!\"},\r\n            'searchBtn':{'value':\"Search\"},\r\n            'searchReset':{'value':\"Clear\"},\r\n            'noneAlign':{'title':'None Float'},\r\n            'leftAlign':{'title':'Left Float'},\r\n            'rightAlign':{'title':'Right Float'},\r\n            'centerAlign':{'title':'Center In A Line'}\r\n        },\r\n        'uploadSelectFile':'Select File',\r\n        'uploadAddFile':'Add File',\r\n        'uploadStart':'Start Upload',\r\n        'uploadPause':'Pause Upload',\r\n        'uploadContinue':'Continue Upload',\r\n        'uploadRetry':'Retry Upload',\r\n        'uploadDelete':'Delete',\r\n        'uploadTurnLeft':'Turn Left',\r\n        'uploadTurnRight':'Turn Right',\r\n        'uploadPreview':'Doing Preview',\r\n        'uploadNoPreview':'Can Not Preview',\r\n        'updateStatusReady': 'Selected _ pictures, total _KB.',\r\n        'updateStatusConfirm': '_ uploaded successfully and _ upload failed',\r\n        'updateStatusFinish': 'Total _ pictures (_KB), _  uploaded successfully',\r\n        'updateStatusError': ' and _ upload failed',\r\n        'errorNotSupport': 'WebUploader does not support the browser you are using. Please upgrade your browser or flash player',\r\n        'errorLoadConfig': 'Server config not loaded, upload can not work.',\r\n        'errorExceedSize':'File Size Exceed',\r\n        'errorFileType':'File Type Not Allow',\r\n        'errorInterrupt':'File Upload Interrupted',\r\n        'errorUploadRetry':'Upload Error, Please Retry.',\r\n        'errorHttp':'Http Error',\r\n        'errorServerUpload':'Server Result Error.',\r\n        'remoteLockError':\"Cannot Lock the Proportion between width and height\",\r\n        'numError':\"Please enter the correct Num. e.g 123,400\",\r\n        'imageUrlError':\"The image format may be wrong!\",\r\n        'imageLoadError':\"Error,please check the network or URL！\",\r\n        'searchRemind':\"Enter the search keyword!\",\r\n        'searchLoading':\"Image is loading,please wait...\",\r\n        'searchRetry':\" Sorry,can't find the image,please try again!\"\r\n    },\r\n    'attachment':{\r\n        'static':{\r\n            'lang_tab_upload': 'Upload',\r\n            'lang_tab_online': 'Online',\r\n            'lang_start_upload':\"Start upload\",\r\n            'lang_drop_remind':\"You can drop files here, a single maximum of 300 files\"\r\n        },\r\n        'uploadSelectFile':'Select File',\r\n        'uploadAddFile':'Add File',\r\n        'uploadStart':'Start Upload',\r\n        'uploadPause':'Pause Upload',\r\n        'uploadContinue':'Continue Upload',\r\n        'uploadRetry':'Retry Upload',\r\n        'uploadDelete':'Delete',\r\n        'uploadTurnLeft':'Turn Left',\r\n        'uploadTurnRight':'Turn Right',\r\n        'uploadPreview':'Doing Preview',\r\n        'updateStatusReady': 'Selected _ files, total _KB.',\r\n        'updateStatusConfirm': '_ uploaded successfully and _ upload failed',\r\n        'updateStatusFinish': 'Total _ files (_KB), _  uploaded successfully',\r\n        'updateStatusError': ' and _ upload failed',\r\n        'errorNotSupport': 'WebUploader does not support the browser you are using. Please upgrade your browser or flash player',\r\n        'errorLoadConfig': 'Server config not loaded, upload can not work.',\r\n        'errorExceedSize':'File Size Exceed',\r\n        'errorFileType':'File Type Not Allow',\r\n        'errorInterrupt':'File Upload Interrupted',\r\n        'errorUploadRetry':'Upload Error, Please Retry.',\r\n        'errorHttp':'Http Error',\r\n        'errorServerUpload':'Server Result Error.'\r\n    },\r\n\r\n    'insertvideo':{\r\n        'static':{\r\n            'lang_tab_insertV':\"Video\",\r\n            'lang_tab_searchV':\"Search\",\r\n            'lang_tab_uploadV':\"Upload\",\r\n            'lang_video_url':\" URL \",\r\n            'lang_video_size':\"Video Size\",\r\n            'lang_videoW':\"Width\",\r\n            'lang_videoH':\"Height\",\r\n            'lang_alignment':\"Alignment\",\r\n            'videoSearchTxt':{'value':\"Enter the search keyword!\"},\r\n            'videoType':{'options':[\"All\", \"Hot\", \"Entertainment\", \"Funny\", \"Sports\", \"Science\", \"variety\"]},\r\n            'videoSearchBtn':{'value':\"Search in Baidu\"},\r\n            'videoSearchReset':{'value':\"Clear result\"},\r\n\r\n            'lang_input_fileStatus':' No file uploaded!',\r\n            'startUpload':{'style':\"background:url(upload.png) no-repeat;\"},\r\n\r\n            'lang_upload_size':\"Video Size\",\r\n            'lang_upload_width':\"Width\",\r\n            'lang_upload_height':\"Height\",\r\n            'lang_upload_alignment':\"Alignment\",\r\n            'lang_format_advice':\"Recommends mp4 format.\"\r\n        },\r\n        'numError':\"Please enter the correct Num. e.g 123,400\",\r\n        'floatLeft':\"Float left\",\r\n        'floatRight':\"Float right\",\r\n        'default':\"Default\",\r\n        'block':\"Display in block\",\r\n        'urlError':\"The video url format may be wrong!\",\r\n        'loading':\" &nbsp;The video is loading, please wait…\",\r\n        'clickToSelect':\"Click to select\",\r\n        'goToSource':'Visit source video ',\r\n        'noVideo':\" &nbsp; &nbsp;Sorry,can't find the video,please try again!\",\r\n\r\n        'browseFiles':'Open files',\r\n        'uploadSuccess':'Upload Successful!',\r\n        'delSuccessFile':'Remove from the success of the queue',\r\n        'delFailSaveFile':'Remove the save failed file',\r\n        'statusPrompt':' file(s) uploaded! ',\r\n        'flashVersionError':'The current Flash version is too low, please update FlashPlayer,then try again!',\r\n        'flashLoadingError':'The Flash failed loading! Please check the path or network state',\r\n        'fileUploadReady':'Wait for uploading...',\r\n        'delUploadQueue':'Remove from the uploading queue ',\r\n        'limitPrompt1':'Can not choose more than single',\r\n        'limitPrompt2':'file(s)！Please choose again！',\r\n        'delFailFile':'Remove failure file',\r\n        'fileSizeLimit':'File size exceeds the limit！',\r\n        'emptyFile':'Can not upload an empty file！',\r\n        'fileTypeError':'File type error！',\r\n        'unknownError':'Unknown error！',\r\n        'fileUploading':'Uploading,please wait...',\r\n        'cancelUpload':'Cancel upload',\r\n        'netError':'Network error',\r\n        'failUpload':'Upload failed',\r\n        'serverIOError':'Server IO error！',\r\n        'noAuthority':'No Permission！',\r\n        'fileNumLimit':'Upload limit to the number',\r\n        'failCheck':'Authentication fails, the upload is skipped!',\r\n        'fileCanceling':'Cancel, please wait...',\r\n        'stopUploading':'Upload has stopped...',\r\n\r\n        'uploadSelectFile':'Select File',\r\n        'uploadAddFile':'Add File',\r\n        'uploadStart':'Start Upload',\r\n        'uploadPause':'Pause Upload',\r\n        'uploadContinue':'Continue Upload',\r\n        'uploadRetry':'Retry Upload',\r\n        'uploadDelete':'Delete',\r\n        'uploadTurnLeft':'Turn Left',\r\n        'uploadTurnRight':'Turn Right',\r\n        'uploadPreview':'Doing Preview',\r\n        'updateStatusReady': 'Selected _ files, total _KB.',\r\n        'updateStatusConfirm': '_ uploaded successfully and _ upload failed',\r\n        'updateStatusFinish': 'Total _ files (_KB), _  uploaded successfully',\r\n        'updateStatusError': ' and _ upload failed',\r\n        'errorNotSupport': 'WebUploader does not support the browser you are using. Please upgrade your browser or flash player',\r\n        'errorLoadConfig': 'Server config not loaded, upload can not work.',\r\n        'errorExceedSize':'File Size Exceed',\r\n        'errorFileType':'File Type Not Allow',\r\n        'errorInterrupt':'File Upload Interrupted',\r\n        'errorUploadRetry':'Upload Error, Please Retry.',\r\n        'errorHttp':'Http Error',\r\n        'errorServerUpload':'Server Result Error.'\r\n    },\r\n    'webapp':{\r\n        'tip1':\"This function provided by Baidu APP,please apply for baidu APPKey webmaster first!\",\r\n        'tip2':\"And then open the file ueditor.config.js to set it! \",\r\n        'applyFor':\"APPLY FOR\",\r\n        'anthorApi':\"Baidu API\"\r\n    },\r\n    'template':{\r\n        'static':{\r\n            'lang_template_bkcolor':'Background Color',\r\n            'lang_template_clear' : 'Keep Content',\r\n            'lang_template_select':'Select Template'\r\n        },\r\n        'blank':\"Blank\",\r\n        'blog':\"Blog\",\r\n        'resume':\"Resume\",\r\n        'richText':\"Rich Text\",\r\n        'scrPapers':\"Scientific Papers\"\r\n    },\r\n    scrawl:{\r\n        'static':{\r\n            'lang_input_previousStep':\"Previous\",\r\n            'lang_input_nextsStep':\"Next\",\r\n            'lang_input_clear':'Clear',\r\n            'lang_input_addPic':'AddImage',\r\n            'lang_input_ScalePic':'ScaleImage',\r\n            'lang_input_removePic':'RemoveImage',\r\n            'J_imgTxt':{title:'Add background image'}\r\n        },\r\n        'noScarwl':\"No paint, a white paper...\",\r\n        'scrawlUpLoading':\"Image is uploading, please wait...\",\r\n        'continueBtn':\"Try again\",\r\n        'imageError':\"Image failed to load!\",\r\n        'backgroundUploading':'Image is uploading,please wait...'\r\n    },\r\n    'music':{\r\n        'static':{\r\n            'lang_input_tips':\"Input singer/song/album, search you interested in music!\",\r\n            'J_searchBtn':{value:'Search songs'}\r\n        },\r\n        'emptyTxt':'Not search to the relevant music results, please change a keyword try.',\r\n        'chapter':'Songs',\r\n        'singer':'Singer',\r\n        'special':'Album',\r\n        'listenTest':'Audition'\r\n    },\r\n    anchor:{\r\n        'static':{\r\n            'lang_input_anchorName':'Anchor Name:'\r\n        }\r\n    },\r\n    'charts':{\r\n        'static':{\r\n            'lang_data_source':'Data source:',\r\n            'lang_chart_format': 'Chart format:',\r\n            'lang_data_align': 'Align',\r\n            'lang_chart_align_same': 'Consistent with the X-axis Y-axis',\r\n            'lang_chart_align_reverse': 'X-axis Y-axis opposite',\r\n            'lang_chart_title': 'Title',\r\n            'lang_chart_main_title': 'main title:',\r\n            'lang_chart_sub_title': 'sub title:',\r\n            'lang_chart_x_title': 'X-axis title:',\r\n            'lang_chart_y_title': 'Y-axis title:',\r\n            'lang_chart_tip': 'Prompt',\r\n            'lang_cahrt_tip_prefix': 'prefix:',\r\n            'lang_cahrt_tip_description': '仅饼图有效， 当鼠标移动到饼图中相应的块上时，提示框内的文字的前缀',\r\n            'lang_chart_data_unit': 'Unit',\r\n            'lang_chart_data_unit_title': 'unit:',\r\n            'lang_chart_data_unit_description': '显示在每个数据点上的数据的单位， 比如： 温度的单位 ℃',\r\n            'lang_chart_type': 'Chart type:',\r\n            'lang_prev_btn': 'Previous',\r\n            'lang_next_btn': 'Next'\r\n        }\r\n    },\r\n    emotion:{\r\n        'static':{\r\n            'lang_input_choice':'Choice',\r\n            'lang_input_Tuzki':'Tuzki',\r\n            'lang_input_lvdouwa':'LvDouWa',\r\n            'lang_input_BOBO':'BOBO',\r\n            'lang_input_babyCat':'BabyCat',\r\n            'lang_input_bubble':'Bubble',\r\n            'lang_input_youa':'YouA'\r\n        }\r\n    },\r\n    gmap:{\r\n        'static':{\r\n            'lang_input_address':'Address:',\r\n            'lang_input_search':'Search',\r\n            'address':{value:\"Beijing\"}\r\n        },\r\n        searchError:'Unable to locate the address!'\r\n    },\r\n    help:{\r\n        'static':{\r\n            'lang_input_about':'About',\r\n            'lang_input_shortcuts':'Shortcuts',\r\n            'lang_input_introduction':\"UEditor is developed by Baidu Co.ltd.  It is lightweight, customizable , focusing on user experience and etc. , UEditor is based on open source BSD license , allowing free use and redistribution.\",\r\n            'lang_Txt_shortcuts':'Shortcuts',\r\n            'lang_Txt_func':'Function',\r\n            'lang_Txt_bold':'Bold',\r\n            'lang_Txt_copy':'Copy',\r\n            'lang_Txt_cut':'Cut',\r\n            'lang_Txt_Paste':'Paste',\r\n            'lang_Txt_undo':'Undo',\r\n            'lang_Txt_redo':'Redo',\r\n            'lang_Txt_italic':'Italic',\r\n            'lang_Txt_underline':'Underline',\r\n            'lang_Txt_selectAll':'Select All',\r\n            'lang_Txt_visualEnter':'Submit',\r\n            'lang_Txt_fullscreen':'Fullscreen'\r\n        }\r\n    },\r\n    insertframe:{\r\n        'static':{\r\n            'lang_input_address':'Address：',\r\n            'lang_input_width':'Width：',\r\n            'lang_input_height':'height：',\r\n            'lang_input_isScroll':'Enable scrollbars：',\r\n            'lang_input_frameborder':'Show frame border：',\r\n            'lang_input_alignMode':'Alignment：',\r\n            'align':{title:\"Alignment\", options:[\"Default\", \"Left\", \"Right\", \"Center\"]}\r\n        },\r\n        'enterAddress':'Please enter an address!'\r\n    },\r\n    link:{\r\n        'static':{\r\n            'lang_input_text':'Text：',\r\n            'lang_input_url':'URL：',\r\n            'lang_input_title':'Title：',\r\n            'lang_input_target':'open in new window：'\r\n        },\r\n        'validLink':'Supports only effective when a link is selected',\r\n        'httpPrompt':'The hyperlink you enter should start with \"http|https|ftp://\"!'\r\n    },\r\n    map:{\r\n        'static':{\r\n            lang_city:\"City\",\r\n            lang_address:\"Address\",\r\n            city:{value:\"Beijing\"},\r\n            lang_search:\"Search\",\r\n            lang_dynamicmap:\"Dynamic map\"\r\n        },\r\n        cityMsg:\"Please enter the city name!\",\r\n        errorMsg:\"Can't find the place!\"\r\n    },\r\n    searchreplace:{\r\n        'static':{\r\n            lang_tab_search:\"Search\",\r\n            lang_tab_replace:\"Replace\",\r\n            lang_search1:\"Search\",\r\n            lang_search2:\"Search\",\r\n            lang_replace:\"Replace\",\r\n            lang_searchReg:'Support regular expression ,which starts and ends with a slash ,for example \"/expression/\"',\r\n            lang_searchReg1:'Support regular expression ,which starts and ends with a slash ,for example \"/expression/\"',\r\n            lang_case_sensitive1:\"Case sense\",\r\n            lang_case_sensitive2:\"Case sense\",\r\n            nextFindBtn:{value:\"Next\"},\r\n            preFindBtn:{value:\"Preview\"},\r\n            nextReplaceBtn:{value:\"Next\"},\r\n            preReplaceBtn:{value:\"Preview\"},\r\n            repalceBtn:{value:\"Replace\"},\r\n            repalceAllBtn:{value:\"Replace all\"}\r\n        },\r\n        getEnd:\"Has the search to the bottom!\",\r\n        getStart:\"Has the search to the top!\",\r\n        countMsg:\"Altogether replaced {#count} character(s)!\"\r\n    },\r\n    snapscreen:{\r\n        'static':{\r\n            lang_showMsg:\"You should install the UEditor screenshots program first!\",\r\n            lang_download:\"Download!\",\r\n            lang_step1:\"Step1:Download the program and then run it\",\r\n            lang_step2:\"Step2:After complete install,try to click the button again\"\r\n        }\r\n    },\r\n    spechars:{\r\n        'static':{},\r\n        tsfh:\"Special\",\r\n        lmsz:\"Roman\",\r\n        szfh:\"Numeral\",\r\n        rwfh:\"Japanese\",\r\n        xlzm:\"The Greek\",\r\n        ewzm:\"Russian\",\r\n        pyzm:\"Phonetic\",\r\n        yyyb:\"English\",\r\n        zyzf:\"Others\"\r\n    },\r\n    'edittable':{\r\n        'static':{\r\n            'lang_tableStyle':'Table style',\r\n            'lang_insertCaption':'Add table header row',\r\n            'lang_insertTitle':'Add table title row',\r\n            'lang_insertTitleCol':'Add table title col',\r\n            'lang_tableSize':'Automatically adjust table size',\r\n            'lang_autoSizeContent':'Adaptive by form text',\r\n            'lang_orderbycontent':\"Table of contents sortable\",\r\n            'lang_autoSizePage':'Page width adaptive',\r\n            'lang_example':'Example',\r\n            'lang_borderStyle':'Table Border',\r\n            'lang_color':'Color:'\r\n        },\r\n        captionName:'Caption',\r\n        titleName:'Title',\r\n        cellsName:'text',\r\n        errorMsg:'There are merged cells, can not sort.'\r\n    },\r\n    'edittip':{\r\n        'static':{\r\n            lang_delRow:'Delete entire row',\r\n            lang_delCol:'Delete entire col'\r\n        }\r\n    },\r\n    'edittd':{\r\n        'static':{\r\n            lang_tdBkColor:'Background Color:'\r\n        }\r\n    },\r\n    'formula':{\r\n        'static':{\r\n        }\r\n    },\r\n    wordimage:{\r\n        'static':{\r\n            lang_resave:\"The re-save step\",\r\n            uploadBtn:{src:\"upload.png\", alt:\"Upload\"},\r\n            clipboard:{style:\"background: url(copy.png) -153px -1px no-repeat;\"},\r\n            lang_step:\" 1. Click top button to copy the url and then open the dialog to paste it. 2. Open after choose photos uploaded process.\"\r\n        },\r\n        fileType:\"Image\",\r\n        flashError:\"Flash initialization failed!\",\r\n        netError:\"Network error! Please try again!\",\r\n        copySuccess:\"URL has been copied!\",\r\n\r\n        'flashI18n':{\r\n            lang:encodeURI( '{\"UploadingState\":\"totalNum: ${a},uploadComplete: ${b}\", \"BeforeUpload\":\"waitingNum: ${a}\", \"ExceedSize\":\"Size exceed${a}\", \"ErrorInPreview\":\"Preview failed\", \"DefaultDescription\":\"Description\", \"LoadingImage\":\"Loading...\"}' ),\r\n            uploadingTF:encodeURI( '{\"font\":\"Arial\", \"size\":12, \"color\":\"0x000\", \"bold\":\"true\", \"italic\":\"false\", \"underline\":\"false\"}' ),\r\n            imageTF:encodeURI( '{\"font\":\"Arial\", \"size\":11, \"color\":\"red\", \"bold\":\"false\", \"italic\":\"false\", \"underline\":\"false\"}' ),\r\n            textEncoding:\"utf-8\",\r\n            addImageSkinURL:\"addImage.png\",\r\n            allDeleteBtnUpSkinURL:\"allDeleteBtnUpSkin.png\",\r\n            allDeleteBtnHoverSkinURL:\"allDeleteBtnHoverSkin.png\",\r\n            rotateLeftBtnEnableSkinURL:\"rotateLeftEnable.png\",\r\n            rotateLeftBtnDisableSkinURL:\"rotateLeftDisable.png\",\r\n            rotateRightBtnEnableSkinURL:\"rotateRightEnable.png\",\r\n            rotateRightBtnDisableSkinURL:\"rotateRightDisable.png\",\r\n            deleteBtnEnableSkinURL:\"deleteEnable.png\",\r\n            deleteBtnDisableSkinURL:\"deleteDisable.png\",\r\n            backgroundURL:'',\r\n            listBackgroundURL:'',\r\n            buttonURL:'button.png'\r\n        }\r\n    },\r\n    'autosave': {\r\n        'success':'Local conservation success'\r\n    }\r\n};\r\n"
  },
  {
    "path": "public/static/ueditor/lang/zh-cn/zh-cn.js",
    "content": "/**\r\n * Created with JetBrains PhpStorm.\r\n * User: taoqili\r\n * Date: 12-6-12\r\n * Time: 下午5:02\r\n * To change this template use File | Settings | File Templates.\r\n */\r\nUE.I18N['zh-cn'] = {\r\n    'labelMap':{\r\n        'anchor':'锚点', 'undo':'撤销', 'redo':'重做', 'bold':'加粗', 'indent':'首行缩进', 'snapscreen':'截图',\r\n        'italic':'斜体', 'underline':'下划线', 'strikethrough':'删除线', 'subscript':'下标','fontborder':'字符边框',\r\n        'superscript':'上标', 'formatmatch':'格式刷', 'source':'源代码', 'blockquote':'引用',\r\n        'pasteplain':'纯文本粘贴模式', 'selectall':'全选', 'print':'打印', 'preview':'预览',\r\n        'horizontal':'分隔线', 'removeformat':'清除格式', 'time':'时间', 'date':'日期',\r\n        'unlink':'取消链接', 'insertrow':'前插入行', 'insertcol':'前插入列', 'mergeright':'右合并单元格', 'mergedown':'下合并单元格',\r\n        'deleterow':'删除行', 'deletecol':'删除列', 'splittorows':'拆分成行',\r\n        'splittocols':'拆分成列', 'splittocells':'完全拆分单元格','deletecaption':'删除表格标题','inserttitle':'插入标题',\r\n        'mergecells':'合并多个单元格', 'deletetable':'删除表格', 'cleardoc':'清空文档','insertparagraphbeforetable':\"表格前插入行\",'insertcode':'代码语言',\r\n        'fontfamily':'字体', 'fontsize':'字号', 'paragraph':'段落格式', 'simpleupload':'单图上传', 'insertimage':'多图上传','edittable':'表格属性','edittd':'单元格属性', 'link':'超链接',\r\n        'emotion':'表情', 'spechars':'特殊字符', 'searchreplace':'查询替换', 'map':'Baidu地图', 'gmap':'Google地图',\r\n        'insertvideo':'视频', 'help':'帮助', 'justifyleft':'居左对齐', 'justifyright':'居右对齐', 'justifycenter':'居中对齐',\r\n        'justifyjustify':'两端对齐', 'forecolor':'字体颜色', 'backcolor':'背景色', 'insertorderedlist':'有序列表',\r\n        'insertunorderedlist':'无序列表', 'fullscreen':'全屏', 'directionalityltr':'从左向右输入', 'directionalityrtl':'从右向左输入',\r\n        'rowspacingtop':'段前距', 'rowspacingbottom':'段后距',  'pagebreak':'分页', 'insertframe':'插入Iframe', 'imagenone':'默认',\r\n        'imageleft':'左浮动', 'imageright':'右浮动', 'attachment':'附件', 'imagecenter':'居中', 'wordimage':'图片转存',\r\n        'lineheight':'行间距','edittip' :'编辑提示','customstyle':'自定义标题', 'autotypeset':'自动排版',\r\n        'webapp':'百度应用','touppercase':'字母大写', 'tolowercase':'字母小写','background':'背景','template':'模板','scrawl':'涂鸦',\r\n        'music':'音乐','inserttable':'插入表格','drafts': '从草稿箱加载', 'charts': '图表'\r\n    },\r\n    'insertorderedlist':{\r\n        'num':'1,2,3...',\r\n        'num1':'1),2),3)...',\r\n        'num2':'(1),(2),(3)...',\r\n        'cn':'一,二,三....',\r\n        'cn1':'一),二),三)....',\r\n        'cn2':'(一),(二),(三)....',\r\n        'decimal':'1,2,3...',\r\n        'lower-alpha':'a,b,c...',\r\n        'lower-roman':'i,ii,iii...',\r\n        'upper-alpha':'A,B,C...',\r\n        'upper-roman':'I,II,III...'\r\n    },\r\n    'insertunorderedlist':{\r\n        'circle':'○ 大圆圈',\r\n        'disc':'● 小黑点',\r\n        'square':'■ 小方块 ',\r\n        'dash' :'— 破折号',\r\n        'dot':' 。 小圆圈'\r\n    },\r\n    'paragraph':{'p':'段落', 'h1':'标题 1', 'h2':'标题 2', 'h3':'标题 3', 'h4':'标题 4', 'h5':'标题 5', 'h6':'标题 6'},\r\n    'fontfamily':{\r\n        'songti':'宋体',\r\n        'kaiti':'楷体',\r\n        'heiti':'黑体',\r\n        'lishu':'隶书',\r\n        'yahei':'微软雅黑',\r\n        'andaleMono':'andale mono',\r\n        'arial': 'arial',\r\n        'arialBlack':'arial black',\r\n        'comicSansMs':'comic sans ms',\r\n        'impact':'impact',\r\n        'timesNewRoman':'times new roman'\r\n    },\r\n    'customstyle':{\r\n        'tc':'标题居中',\r\n        'tl':'标题居左',\r\n        'im':'强调',\r\n        'hi':'明显强调'\r\n    },\r\n    'autoupload': {\r\n        'exceedSizeError': '文件大小超出限制',\r\n        'exceedTypeError': '文件格式不允许',\r\n        'jsonEncodeError': '服务器返回格式错误',\r\n        'loading':\"正在上传...\",\r\n        'loadError':\"上传错误\",\r\n        'errorLoadConfig': '后端配置项没有正常加载，上传插件不能正常使用！'\r\n    },\r\n    'simpleupload':{\r\n        'exceedSizeError': '文件大小超出限制',\r\n        'exceedTypeError': '文件格式不允许',\r\n        'jsonEncodeError': '服务器返回格式错误',\r\n        'loading':\"正在上传...\",\r\n        'loadError':\"上传错误\",\r\n        'errorLoadConfig': '后端配置项没有正常加载，上传插件不能正常使用！'\r\n    },\r\n    'elementPathTip':\"元素路径\",\r\n    'wordCountTip':\"字数统计\",\r\n    'wordCountMsg':'当前已输入{#count}个字符, 您还可以输入{#leave}个字符。 ',\r\n    'wordOverFlowMsg':'<span style=\"color:red;\">字数超出最大允许值，服务器可能拒绝保存！</span>',\r\n    'ok':\"确认\",\r\n    'cancel':\"取消\",\r\n    'closeDialog':\"关闭对话框\",\r\n    'tableDrag':\"表格拖动必须引入uiUtils.js文件！\",\r\n    'autofloatMsg':\"工具栏浮动依赖编辑器UI，您首先需要引入UI文件!\",\r\n    'loadconfigError': '获取后台配置项请求出错，上传功能将不能正常使用！',\r\n    'loadconfigFormatError': '后台配置项返回格式出错，上传功能将不能正常使用！',\r\n    'loadconfigHttpError': '请求后台配置项http错误，上传功能将不能正常使用！',\r\n    'snapScreen_plugin':{\r\n        'browserMsg':\"仅支持IE浏览器！\",\r\n        'callBackErrorMsg':\"服务器返回数据有误，请检查配置项之后重试。\",\r\n        'uploadErrorMsg':\"截图上传失败，请检查服务器端环境! \"\r\n    },\r\n    'insertcode':{\r\n        'as3':'ActionScript 3',\r\n        'bash':'Bash/Shell',\r\n        'cpp':'C/C++',\r\n        'css':'CSS',\r\n        'cf':'ColdFusion',\r\n        'c#':'C#',\r\n        'delphi':'Delphi',\r\n        'diff':'Diff',\r\n        'erlang':'Erlang',\r\n        'groovy':'Groovy',\r\n        'html':'HTML',\r\n        'java':'Java',\r\n        'jfx':'JavaFX',\r\n        'js':'JavaScript',\r\n        'pl':'Perl',\r\n        'php':'PHP',\r\n        'plain':'Plain Text',\r\n        'ps':'PowerShell',\r\n        'python':'Python',\r\n        'ruby':'Ruby',\r\n        'scala':'Scala',\r\n        'sql':'SQL',\r\n        'vb':'Visual Basic',\r\n        'xml':'XML'\r\n    },\r\n    'confirmClear':\"确定清空当前文档么？\",\r\n    'contextMenu':{\r\n        'delete':\"删除\",\r\n        'selectall':\"全选\",\r\n        'deletecode':\"删除代码\",\r\n        'cleardoc':\"清空文档\",\r\n        'confirmclear':\"确定清空当前文档么？\",\r\n        'unlink':\"删除超链接\",\r\n        'paragraph':\"段落格式\",\r\n        'edittable':\"表格属性\",\r\n        'aligntd':\"单元格对齐方式\",\r\n        'aligntable':'表格对齐方式',\r\n        'tableleft':'左浮动',\r\n        'tablecenter':'居中显示',\r\n        'tableright':'右浮动',\r\n        'edittd':\"单元格属性\",\r\n        'setbordervisible':'设置表格边线可见',\r\n        'justifyleft':'左对齐',\r\n        'justifyright':'右对齐',\r\n        'justifycenter':'居中对齐',\r\n        'justifyjustify':'两端对齐',\r\n        'table':\"表格\",\r\n        'inserttable':'插入表格',\r\n        'deletetable':\"删除表格\",\r\n        'insertparagraphbefore':\"前插入段落\",\r\n        'insertparagraphafter':'后插入段落',\r\n        'deleterow':\"删除当前行\",\r\n        'deletecol':\"删除当前列\",\r\n        'insertrow':\"前插入行\",\r\n        'insertcol':\"左插入列\",\r\n        'insertrownext':'后插入行',\r\n        'insertcolnext':'右插入列',\r\n        'insertcaption':'插入表格名称',\r\n        'deletecaption':'删除表格名称',\r\n        'inserttitle':'插入表格标题行',\r\n        'deletetitle':'删除表格标题行',\r\n        'inserttitlecol':'插入表格标题列',\r\n        'deletetitlecol':'删除表格标题列',\r\n        'averageDiseRow':'平均分布各行',\r\n        'averageDisCol':'平均分布各列',\r\n        'mergeright':\"向右合并\",\r\n        'mergeleft':\"向左合并\",\r\n        'mergedown':\"向下合并\",\r\n        'mergecells':\"合并单元格\",\r\n        'splittocells':\"完全拆分单元格\",\r\n        'splittocols':\"拆分成列\",\r\n        'splittorows':\"拆分成行\",\r\n        'tablesort':'表格排序',\r\n        'enablesort':'设置表格可排序',\r\n        'disablesort':'取消表格可排序',\r\n        'reversecurrent':'逆序当前',\r\n        'orderbyasc':'按ASCII字符升序',\r\n        'reversebyasc':'按ASCII字符降序',\r\n        'orderbynum':'按数值大小升序',\r\n        'reversebynum':'按数值大小降序',\r\n        'borderbk':'边框底纹',\r\n        'setcolor':'表格隔行变色',\r\n        'unsetcolor':'取消表格隔行变色',\r\n        'setbackground':'选区背景隔行',\r\n        'unsetbackground':'取消选区背景',\r\n        'redandblue':'红蓝相间',\r\n        'threecolorgradient':'三色渐变',\r\n        'copy':\"复制(Ctrl + c)\",\r\n        'copymsg': \"浏览器不支持,请使用 'Ctrl + c'\",\r\n        'paste':\"粘贴(Ctrl + v)\",\r\n         'pastemsg': \"浏览器不支持,请使用 'Ctrl + v'\"\r\n    },\r\n    'copymsg': \"浏览器不支持,请使用 'Ctrl + c'\",\r\n    'pastemsg': \"浏览器不支持,请使用 'Ctrl + v'\",\r\n    'anthorMsg':\"链接\",\r\n    'clearColor':'清空颜色',\r\n    'standardColor':'标准颜色',\r\n    'themeColor':'主题颜色',\r\n    'property':'属性',\r\n    'default':'默认',\r\n    'modify':'修改',\r\n    'justifyleft':'左对齐',\r\n    'justifyright':'右对齐',\r\n    'justifycenter':'居中',\r\n    'justify':'默认',\r\n    'clear':'清除',\r\n    'anchorMsg':'锚点',\r\n    'delete':'删除',\r\n    'clickToUpload':\"点击上传\",\r\n    'unset':'尚未设置语言文件',\r\n    't_row':'行',\r\n    't_col':'列',\r\n    'more':'更多',\r\n    'pasteOpt':'粘贴选项',\r\n    'pasteSourceFormat':\"保留源格式\",\r\n    'tagFormat':'只保留标签',\r\n    'pasteTextFormat':'只保留文本',\r\n    'autoTypeSet':{\r\n        'mergeLine':\"合并空行\",\r\n        'delLine':\"清除空行\",\r\n        'removeFormat':\"清除格式\",\r\n        'indent':\"首行缩进\",\r\n        'alignment':\"对齐方式\",\r\n        'imageFloat':\"图片浮动\",\r\n        'removeFontsize':\"清除字号\",\r\n        'removeFontFamily':\"清除字体\",\r\n        'removeHtml':\"清除冗余HTML代码\",\r\n        'pasteFilter':\"粘贴过滤\",\r\n        'run':\"执行\",\r\n        'symbol':'符号转换',\r\n        'bdc2sb':'全角转半角',\r\n        'tobdc':'半角转全角'\r\n    },\r\n\r\n    'background':{\r\n        'static':{\r\n            'lang_background_normal':'背景设置',\r\n            'lang_background_local':'在线图片',\r\n            'lang_background_set':'选项',\r\n            'lang_background_none':'无背景色',\r\n            'lang_background_colored':'有背景色',\r\n            'lang_background_color':'颜色设置',\r\n            'lang_background_netimg':'网络图片',\r\n            'lang_background_align':'对齐方式',\r\n            'lang_background_position':'精确定位',\r\n            'repeatType':{'options':[\"居中\", \"横向重复\", \"纵向重复\", \"平铺\",\"自定义\"]}\r\n\r\n        },\r\n        'noUploadImage':\"当前未上传过任何图片！\",\r\n        'toggleSelect':\"单击可切换选中状态\\n原图尺寸: \"\r\n    },\r\n    //===============dialog i18N=======================\r\n    'insertimage':{\r\n        'static':{\r\n            'lang_tab_remote':\"插入图片\", //节点\r\n            'lang_tab_upload':\"本地上传\",\r\n            'lang_tab_online':\"在线管理\",\r\n            'lang_tab_search':\"图片搜索\",\r\n            'lang_input_url':\"地 址：\",\r\n            'lang_input_size':\"大 小：\",\r\n            'lang_input_width':\"宽度\",\r\n            'lang_input_height':\"高度\",\r\n            'lang_input_border':\"边 框：\",\r\n            'lang_input_vhspace':\"边 距：\",\r\n            'lang_input_title':\"描 述：\",\r\n            'lang_input_align':'图片浮动方式：',\r\n            'lang_imgLoading':\"　图片加载中……\",\r\n            'lang_start_upload':\"开始上传\",\r\n            'lock':{'title':\"锁定宽高比例\"}, //属性\r\n            'searchType':{'title':\"图片类型\", 'options':[\"新闻\", \"壁纸\", \"表情\", \"头像\"]}, //select的option\r\n            'searchTxt':{'value':\"请输入搜索关键词\"},\r\n            'searchBtn':{'value':\"百度一下\"},\r\n            'searchReset':{'value':\"清空搜索\"},\r\n            'noneAlign':{'title':'无浮动'},\r\n            'leftAlign':{'title':'左浮动'},\r\n            'rightAlign':{'title':'右浮动'},\r\n            'centerAlign':{'title':'居中独占一行'}\r\n        },\r\n        'uploadSelectFile':'点击选择图片',\r\n        'uploadAddFile':'继续添加',\r\n        'uploadStart':'开始上传',\r\n        'uploadPause':'暂停上传',\r\n        'uploadContinue':'继续上传',\r\n        'uploadRetry':'重试上传',\r\n        'uploadDelete':'删除',\r\n        'uploadTurnLeft':'向左旋转',\r\n        'uploadTurnRight':'向右旋转',\r\n        'uploadPreview':'预览中',\r\n        'uploadNoPreview':'不能预览',\r\n        'updateStatusReady': '选中_张图片，共_KB。',\r\n        'updateStatusConfirm': '已成功上传_张照片，_张照片上传失败',\r\n        'updateStatusFinish': '共_张（_KB），_张上传成功',\r\n        'updateStatusError': '，_张上传失败。',\r\n        'errorNotSupport': 'WebUploader 不支持您的浏览器！如果你使用的是IE浏览器，请尝试升级 flash 播放器。',\r\n        'errorLoadConfig': '后端配置项没有正常加载，上传插件不能正常使用！',\r\n        'errorExceedSize':'文件大小超出',\r\n        'errorFileType':'文件格式不允许',\r\n        'errorInterrupt':'文件传输中断',\r\n        'errorUploadRetry':'上传失败，请重试',\r\n        'errorHttp':'http请求错误',\r\n        'errorServerUpload':'服务器返回出错',\r\n        'remoteLockError':\"宽高不正确,不能所定比例\",\r\n        'numError':\"请输入正确的长度或者宽度值！例如：123，400\",\r\n        'imageUrlError':\"不允许的图片格式或者图片域！\",\r\n        'imageLoadError':\"图片加载失败！请检查链接地址或网络状态！\",\r\n        'searchRemind':\"请输入搜索关键词\",\r\n        'searchLoading':\"图片加载中，请稍后……\",\r\n        'searchRetry':\" :( ，抱歉，没有找到图片！请重试一次！\"\r\n    },\r\n    'attachment':{\r\n        'static':{\r\n            'lang_tab_upload': '上传附件',\r\n            'lang_tab_online': '在线附件',\r\n            'lang_start_upload':\"开始上传\",\r\n            'lang_drop_remind':\"可以将文件拖到这里，单次最多可选100个文件\"\r\n        },\r\n        'uploadSelectFile':'点击选择文件',\r\n        'uploadAddFile':'继续添加',\r\n        'uploadStart':'开始上传',\r\n        'uploadPause':'暂停上传',\r\n        'uploadContinue':'继续上传',\r\n        'uploadRetry':'重试上传',\r\n        'uploadDelete':'删除',\r\n        'uploadTurnLeft':'向左旋转',\r\n        'uploadTurnRight':'向右旋转',\r\n        'uploadPreview':'预览中',\r\n        'updateStatusReady': '选中_个文件，共_KB。',\r\n        'updateStatusConfirm': '已成功上传_个文件，_个文件上传失败',\r\n        'updateStatusFinish': '共_个（_KB），_个上传成功',\r\n        'updateStatusError': '，_张上传失败。',\r\n        'errorNotSupport': 'WebUploader 不支持您的浏览器！如果你使用的是IE浏览器，请尝试升级 flash 播放器。',\r\n        'errorLoadConfig': '后端配置项没有正常加载，上传插件不能正常使用！',\r\n        'errorExceedSize':'文件大小超出',\r\n        'errorFileType':'文件格式不允许',\r\n        'errorInterrupt':'文件传输中断',\r\n        'errorUploadRetry':'上传失败，请重试',\r\n        'errorHttp':'http请求错误',\r\n        'errorServerUpload':'服务器返回出错'\r\n    },\r\n    'insertvideo':{\r\n        'static':{\r\n            'lang_tab_insertV':\"插入视频\",\r\n            'lang_tab_searchV':\"搜索视频\",\r\n            'lang_tab_uploadV':\"上传视频\",\r\n            'lang_video_url':\"视频网址\",\r\n            'lang_video_size':\"视频尺寸\",\r\n            'lang_videoW':\"宽度\",\r\n            'lang_videoH':\"高度\",\r\n            'lang_alignment':\"对齐方式\",\r\n            'videoSearchTxt':{'value':\"请输入搜索关键字！\"},\r\n            'videoType':{'options':[\"全部\", \"热门\", \"娱乐\", \"搞笑\", \"体育\", \"科技\", \"综艺\"]},\r\n            'videoSearchBtn':{'value':\"百度一下\"},\r\n            'videoSearchReset':{'value':\"清空结果\"},\r\n\r\n            'lang_input_fileStatus':' 当前未上传文件',\r\n            'startUpload':{'style':\"background:url(upload.png) no-repeat;\"},\r\n\r\n            'lang_upload_size':\"视频尺寸\",\r\n            'lang_upload_width':\"宽度\",\r\n            'lang_upload_height':\"高度\",\r\n            'lang_upload_alignment':\"对齐方式\",\r\n            'lang_format_advice':\"建议使用mp4格式.\"\r\n\r\n        },\r\n        'numError':\"请输入正确的数值，如123,400\",\r\n        'floatLeft':\"左浮动\",\r\n        'floatRight':\"右浮动\",\r\n        '\"default\"':\"默认\",\r\n        'block':\"独占一行\",\r\n        'urlError':\"输入的视频地址有误，请检查后再试！\",\r\n        'loading':\" &nbsp;视频加载中，请等待……\",\r\n        'clickToSelect':\"点击选中\",\r\n        'goToSource':'访问源视频',\r\n        'noVideo':\" &nbsp; &nbsp;抱歉，找不到对应的视频，请重试！\",\r\n\r\n        'browseFiles':'浏览文件',\r\n        'uploadSuccess':'上传成功!',\r\n        'delSuccessFile':'从成功队列中移除',\r\n        'delFailSaveFile':'移除保存失败文件',\r\n        'statusPrompt':' 个文件已上传！ ',\r\n        'flashVersionError':'当前Flash版本过低，请更新FlashPlayer后重试！',\r\n        'flashLoadingError':'Flash加载失败!请检查路径或网络状态',\r\n        'fileUploadReady':'等待上传……',\r\n        'delUploadQueue':'从上传队列中移除',\r\n        'limitPrompt1':'单次不能选择超过',\r\n        'limitPrompt2':'个文件！请重新选择！',\r\n        'delFailFile':'移除失败文件',\r\n        'fileSizeLimit':'文件大小超出限制！',\r\n        'emptyFile':'空文件无法上传！',\r\n        'fileTypeError':'文件类型不允许！',\r\n        'unknownError':'未知错误！',\r\n        'fileUploading':'上传中，请等待……',\r\n        'cancelUpload':'取消上传',\r\n        'netError':'网络错误',\r\n        'failUpload':'上传失败!',\r\n        'serverIOError':'服务器IO错误！',\r\n        'noAuthority':'无权限！',\r\n        'fileNumLimit':'上传个数限制',\r\n        'failCheck':'验证失败，本次上传被跳过！',\r\n        'fileCanceling':'取消中，请等待……',\r\n        'stopUploading':'上传已停止……',\r\n\r\n        'uploadSelectFile':'点击选择文件',\r\n        'uploadAddFile':'继续添加',\r\n        'uploadStart':'开始上传',\r\n        'uploadPause':'暂停上传',\r\n        'uploadContinue':'继续上传',\r\n        'uploadRetry':'重试上传',\r\n        'uploadDelete':'删除',\r\n        'uploadTurnLeft':'向左旋转',\r\n        'uploadTurnRight':'向右旋转',\r\n        'uploadPreview':'预览中',\r\n        'updateStatusReady': '选中_个文件，共_KB。',\r\n        'updateStatusConfirm': '成功上传_个，_个失败',\r\n        'updateStatusFinish': '共_个(_KB)，_个成功上传',\r\n        'updateStatusError': '，_张上传失败。',\r\n        'errorNotSupport': 'WebUploader 不支持您的浏览器！如果你使用的是IE浏览器，请尝试升级 flash 播放器。',\r\n        'errorLoadConfig': '后端配置项没有正常加载，上传插件不能正常使用！',\r\n        'errorExceedSize':'文件大小超出',\r\n        'errorFileType':'文件格式不允许',\r\n        'errorInterrupt':'文件传输中断',\r\n        'errorUploadRetry':'上传失败，请重试',\r\n        'errorHttp':'http请求错误',\r\n        'errorServerUpload':'服务器返回出错'\r\n    },\r\n    'webapp':{\r\n        'tip1':\"本功能由百度APP提供，如看到此页面，请各位站长首先申请百度APPKey!\",\r\n        'tip2':\"申请完成之后请至ueditor.config.js中配置获得的appkey! \",\r\n        'applyFor':\"点此申请\",\r\n        'anthorApi':\"百度API\"\r\n    },\r\n    'template':{\r\n        'static':{\r\n            'lang_template_bkcolor':'背景颜色',\r\n            'lang_template_clear' : '保留原有内容',\r\n            'lang_template_select' : '选择模板'\r\n        },\r\n        'blank':\"空白文档\",\r\n        'blog':\"博客文章\",\r\n        'resume':\"个人简历\",\r\n        'richText':\"图文混排\",\r\n        'sciPapers':\"科技论文\"\r\n\r\n\r\n    },\r\n    'scrawl':{\r\n        'static':{\r\n            'lang_input_previousStep':\"上一步\",\r\n            'lang_input_nextsStep':\"下一步\",\r\n            'lang_input_clear':'清空',\r\n            'lang_input_addPic':'添加背景',\r\n            'lang_input_ScalePic':'缩放背景',\r\n            'lang_input_removePic':'删除背景',\r\n            'J_imgTxt':{title:'添加背景图片'}\r\n        },\r\n        'noScarwl':\"尚未作画，白纸一张~\",\r\n        'scrawlUpLoading':\"涂鸦上传中,别急哦~\",\r\n        'continueBtn':\"继续\",\r\n        'imageError':\"糟糕，图片读取失败了！\",\r\n        'backgroundUploading':'背景图片上传中,别急哦~'\r\n    },\r\n    'music':{\r\n        'static':{\r\n            'lang_input_tips':\"输入歌手/歌曲/专辑，搜索您感兴趣的音乐！\",\r\n            'J_searchBtn':{value:'搜索歌曲'}\r\n        },\r\n        'emptyTxt':'未搜索到相关音乐结果，请换一个关键词试试。',\r\n        'chapter':'歌曲',\r\n        'singer':'歌手',\r\n        'special':'专辑',\r\n        'listenTest':'试听'\r\n    },\r\n    'anchor':{\r\n        'static':{\r\n            'lang_input_anchorName':'锚点名字：'\r\n        }\r\n    },\r\n    'charts':{\r\n        'static':{\r\n            'lang_data_source':'数据源：',\r\n            'lang_chart_format': '图表格式：',\r\n            'lang_data_align': '数据对齐方式',\r\n            'lang_chart_align_same': '数据源与图表X轴Y轴一致',\r\n            'lang_chart_align_reverse': '数据源与图表X轴Y轴相反',\r\n            'lang_chart_title': '图表标题',\r\n            'lang_chart_main_title': '主标题：',\r\n            'lang_chart_sub_title': '子标题：',\r\n            'lang_chart_x_title': 'X轴标题：',\r\n            'lang_chart_y_title': 'Y轴标题：',\r\n            'lang_chart_tip': '提示文字',\r\n            'lang_cahrt_tip_prefix': '提示文字前缀：',\r\n            'lang_cahrt_tip_description': '仅饼图有效， 当鼠标移动到饼图中相应的块上时，提示框内的文字的前缀',\r\n            'lang_chart_data_unit': '数据单位',\r\n            'lang_chart_data_unit_title': '单位：',\r\n            'lang_chart_data_unit_description': '显示在每个数据点上的数据的单位， 比如： 温度的单位 ℃',\r\n            'lang_chart_type': '图表类型：',\r\n            'lang_prev_btn': '上一个',\r\n            'lang_next_btn': '下一个'\r\n        }\r\n    },\r\n    'emotion':{\r\n        'static':{\r\n            'lang_input_choice':'精选',\r\n            'lang_input_Tuzki':'兔斯基',\r\n            'lang_input_BOBO':'BOBO',\r\n            'lang_input_lvdouwa':'绿豆蛙',\r\n            'lang_input_babyCat':'baby猫',\r\n            'lang_input_bubble':'泡泡',\r\n            'lang_input_youa':'有啊'\r\n        }\r\n    },\r\n    'gmap':{\r\n        'static':{\r\n            'lang_input_address':'地址',\r\n            'lang_input_search':'搜索',\r\n            'address':{value:\"北京\"}\r\n        },\r\n        searchError:'无法定位到该地址!'\r\n    },\r\n    'help':{\r\n        'static':{\r\n            'lang_input_about':'关于UEditor',\r\n            'lang_input_shortcuts':'快捷键',\r\n            'lang_input_introduction':'UEditor是由百度web前端研发部开发的所见即所得富文本web编辑器，具有轻量，可定制，注重用户体验等特点。开源基于BSD协议，允许自由使用和修改代码。',\r\n            'lang_Txt_shortcuts':'快捷键',\r\n            'lang_Txt_func':'功能',\r\n            'lang_Txt_bold':'给选中字设置为加粗',\r\n            'lang_Txt_copy':'复制选中内容',\r\n            'lang_Txt_cut':'剪切选中内容',\r\n            'lang_Txt_Paste':'粘贴',\r\n            'lang_Txt_undo':'重新执行上次操作',\r\n            'lang_Txt_redo':'撤销上一次操作',\r\n            'lang_Txt_italic':'给选中字设置为斜体',\r\n            'lang_Txt_underline':'给选中字加下划线',\r\n            'lang_Txt_selectAll':'全部选中',\r\n            'lang_Txt_visualEnter':'软回车',\r\n            'lang_Txt_fullscreen':'全屏'\r\n        }\r\n    },\r\n    'insertframe':{\r\n        'static':{\r\n            'lang_input_address':'地址：',\r\n            'lang_input_width':'宽度：',\r\n            'lang_input_height':'高度：',\r\n            'lang_input_isScroll':'允许滚动条：',\r\n            'lang_input_frameborder':'显示框架边框：',\r\n            'lang_input_alignMode':'对齐方式：',\r\n            'align':{title:\"对齐方式\", options:[\"默认\", \"左对齐\", \"右对齐\", \"居中\"]}\r\n        },\r\n        'enterAddress':'请输入地址!'\r\n    },\r\n    'link':{\r\n        'static':{\r\n            'lang_input_text':'文本内容：',\r\n            'lang_input_url':'链接地址：',\r\n            'lang_input_title':'标题：',\r\n            'lang_input_target':'是否在新窗口打开：'\r\n        },\r\n        'validLink':'只支持选中一个链接时生效',\r\n        'httpPrompt':'您输入的超链接中不包含http等协议名称，默认将为您添加http://前缀'\r\n    },\r\n    'map':{\r\n        'static':{\r\n            lang_city:\"城市\",\r\n            lang_address:\"地址\",\r\n            city:{value:\"北京\"},\r\n            lang_search:\"搜索\",\r\n            lang_dynamicmap:\"插入动态地图\"\r\n        },\r\n        cityMsg:\"请选择城市\",\r\n        errorMsg:\"抱歉，找不到该位置！\"\r\n    },\r\n    'searchreplace':{\r\n        'static':{\r\n            lang_tab_search:\"查找\",\r\n            lang_tab_replace:\"替换\",\r\n            lang_search1:\"查找\",\r\n            lang_search2:\"查找\",\r\n            lang_replace:\"替换\",\r\n            lang_searchReg:'支持正则表达式，添加前后斜杠标示为正则表达式，例如“/表达式/”',\r\n            lang_searchReg1:'支持正则表达式，添加前后斜杠标示为正则表达式，例如“/表达式/”',\r\n            lang_case_sensitive1:\"区分大小写\",\r\n            lang_case_sensitive2:\"区分大小写\",\r\n            nextFindBtn:{value:\"下一个\"},\r\n            preFindBtn:{value:\"上一个\"},\r\n            nextReplaceBtn:{value:\"下一个\"},\r\n            preReplaceBtn:{value:\"上一个\"},\r\n            repalceBtn:{value:\"替换\"},\r\n            repalceAllBtn:{value:\"全部替换\"}\r\n        },\r\n        getEnd:\"已经搜索到文章末尾！\",\r\n        getStart:\"已经搜索到文章头部\",\r\n        countMsg:\"总共替换了{#count}处！\"\r\n    },\r\n    'snapscreen':{\r\n        'static':{\r\n            lang_showMsg:\"截图功能需要首先安装UEditor截图插件！ \",\r\n            lang_download:\"点此下载\",\r\n            lang_step1:\"第一步，下载UEditor截图插件并运行安装。\",\r\n            lang_step2:\"第二步，插件安装完成后即可使用，如不生效，请重启浏览器后再试！\"\r\n        }\r\n    },\r\n    'spechars':{\r\n        'static':{},\r\n        tsfh:\"特殊字符\",\r\n        lmsz:\"罗马字符\",\r\n        szfh:\"数学字符\",\r\n        rwfh:\"日文字符\",\r\n        xlzm:\"希腊字母\",\r\n        ewzm:\"俄文字符\",\r\n        pyzm:\"拼音字母\",\r\n        yyyb:\"英语音标\",\r\n        zyzf:\"其他\"\r\n    },\r\n    'edittable':{\r\n        'static':{\r\n            'lang_tableStyle':'表格样式',\r\n            'lang_insertCaption':'添加表格名称行',\r\n            'lang_insertTitle':'添加表格标题行',\r\n            'lang_insertTitleCol':'添加表格标题列',\r\n            'lang_orderbycontent':\"使表格内容可排序\",\r\n            'lang_tableSize':'自动调整表格尺寸',\r\n            'lang_autoSizeContent':'按表格文字自适应',\r\n            'lang_autoSizePage':'按页面宽度自适应',\r\n            'lang_example':'示例',\r\n            'lang_borderStyle':'表格边框',\r\n            'lang_color':'颜色:'\r\n        },\r\n        captionName:'表格名称',\r\n        titleName:'标题',\r\n        cellsName:'内容',\r\n        errorMsg:'有合并单元格，不可排序'\r\n    },\r\n    'edittip':{\r\n        'static':{\r\n            lang_delRow:'删除整行',\r\n            lang_delCol:'删除整列'\r\n        }\r\n    },\r\n    'edittd':{\r\n        'static':{\r\n            lang_tdBkColor:'背景颜色:'\r\n        }\r\n    },\r\n    'formula':{\r\n        'static':{\r\n        }\r\n    },\r\n    'wordimage':{\r\n        'static':{\r\n            lang_resave:\"转存步骤\",\r\n            uploadBtn:{src:\"upload.png\",alt:\"上传\"},\r\n            clipboard:{style:\"background: url(copy.png) -153px -1px no-repeat;\"},\r\n            lang_step:\"1、点击顶部复制按钮，将地址复制到剪贴板；2、点击添加照片按钮，在弹出的对话框中使用Ctrl+V粘贴地址；3、点击打开后选择图片上传流程。\"\r\n        },\r\n        'fileType':\"图片\",\r\n        'flashError':\"FLASH初始化失败，请检查FLASH插件是否正确安装！\",\r\n        'netError':\"网络连接错误，请重试！\",\r\n        'copySuccess':\"图片地址已经复制！\",\r\n        'flashI18n':{} //留空默认中文\r\n    },\r\n    'autosave': {\r\n        'saving':'保存中...',\r\n        'success':'本地保存成功'\r\n    }\r\n};\r\n"
  },
  {
    "path": "public/static/ueditor/php/Uploader.class.php",
    "content": "<?php\r\n\r\n/**\r\n * Created by JetBrains PhpStorm.\r\n * User: taoqili\r\n * Date: 12-7-18\r\n * Time: 上午11: 32\r\n * UEditor编辑器通用上传类\r\n */\r\nclass Uploader\r\n{\r\n    private $fileField; //文件域名\r\n    private $file; //文件上传对象\r\n    private $base64; //文件上传对象\r\n    private $config; //配置信息\r\n    private $oriName; //原始文件名\r\n    private $fileName; //新文件名\r\n    private $fullName; //完整文件名,即从当前配置目录开始的URL\r\n    private $filePath; //完整文件名,即从当前配置目录开始的URL\r\n    private $fileSize; //文件大小\r\n    private $fileType; //文件类型\r\n    private $stateInfo; //上传状态信息,\r\n    private $stateMap = array( //上传状态映射表，国际化用户需考虑此处数据的国际化\r\n        \"SUCCESS\", //上传成功标记，在UEditor中内不可改变，否则flash判断会出错\r\n        \"文件大小超出 upload_max_filesize 限制\",\r\n        \"文件大小超出 MAX_FILE_SIZE 限制\",\r\n        \"文件未被完整上传\",\r\n        \"没有文件被上传\",\r\n        \"上传文件为空\",\r\n        \"ERROR_TMP_FILE\" => \"临时文件错误\",\r\n        \"ERROR_TMP_FILE_NOT_FOUND\" => \"找不到临时文件\",\r\n        \"ERROR_SIZE_EXCEED\" => \"文件大小超出网站限制\",\r\n        \"ERROR_TYPE_NOT_ALLOWED\" => \"文件类型不允许\",\r\n        \"ERROR_CREATE_DIR\" => \"目录创建失败\",\r\n        \"ERROR_DIR_NOT_WRITEABLE\" => \"目录没有写权限\",\r\n        \"ERROR_FILE_MOVE\" => \"文件保存时出错\",\r\n        \"ERROR_FILE_NOT_FOUND\" => \"找不到上传文件\",\r\n        \"ERROR_WRITE_CONTENT\" => \"写入文件内容错误\",\r\n        \"ERROR_UNKNOWN\" => \"未知错误\",\r\n        \"ERROR_DEAD_LINK\" => \"链接不可用\",\r\n        \"ERROR_HTTP_LINK\" => \"链接不是http链接\",\r\n        \"ERROR_HTTP_CONTENTTYPE\" => \"链接contentType不正确\",\r\n        \"INVALID_URL\" => \"非法 URL\",\r\n        \"INVALID_IP\" => \"非法 IP\"\r\n    );\r\n\r\n    /**\r\n     * 构造函数\r\n     * @param string $fileField 表单名称\r\n     * @param array $config 配置项\r\n     * @param bool $base64 是否解析base64编码，可省略。若开启，则$fileField代表的是base64编码的字符串表单名\r\n     */\r\n    public function __construct($fileField, $config, $type = \"upload\")\r\n    {\r\n        $this->fileField = $fileField;\r\n        $this->config = $config;\r\n        $this->type = $type;\r\n        if ($type == \"remote\") {\r\n            $this->saveRemote();\r\n        } else if($type == \"base64\") {\r\n            $this->upBase64();\r\n        } else {\r\n            $this->upFile();\r\n        }\r\n\r\n        $this->stateMap['ERROR_TYPE_NOT_ALLOWED'] = iconv('unicode', 'utf-8', $this->stateMap['ERROR_TYPE_NOT_ALLOWED']);\r\n    }\r\n\r\n    /**\r\n     * 上传文件的主处理方法\r\n     * @return mixed\r\n     */\r\n    private function upFile()\r\n    {\r\n        $file = $this->file = $_FILES[$this->fileField];\r\n        if (!$file) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_FILE_NOT_FOUND\");\r\n            return;\r\n        }\r\n        if ($this->file['error']) {\r\n            $this->stateInfo = $this->getStateInfo($file['error']);\r\n            return;\r\n        } else if (!file_exists($file['tmp_name'])) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_TMP_FILE_NOT_FOUND\");\r\n            return;\r\n        } else if (!is_uploaded_file($file['tmp_name'])) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_TMPFILE\");\r\n            return;\r\n        }\r\n\r\n        $this->oriName = $file['name'];\r\n        $this->fileSize = $file['size'];\r\n        $this->fileType = $this->getFileExt();\r\n        $this->fullName = $this->getFullName();\r\n        $this->filePath = $this->getFilePath();\r\n        $this->fileName = $this->getFileName();\r\n        $dirname = dirname($this->filePath);\r\n\r\n        //检查文件大小是否超出限制\r\n        if (!$this->checkSize()) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_SIZE_EXCEED\");\r\n            return;\r\n        }\r\n\r\n        //检查是否不允许的文件格式\r\n        if (!$this->checkType()) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_TYPE_NOT_ALLOWED\");\r\n            return;\r\n        }\r\n\r\n        //创建目录失败\r\n        if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_CREATE_DIR\");\r\n            return;\r\n        } else if (!is_writeable($dirname)) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_DIR_NOT_WRITEABLE\");\r\n            return;\r\n        }\r\n\r\n        //移动文件\r\n        if (!(move_uploaded_file($file[\"tmp_name\"], $this->filePath) && file_exists($this->filePath))) { //移动失败\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_FILE_MOVE\");\r\n        } else { //移动成功\r\n            $this->stateInfo = $this->stateMap[0];\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 处理base64编码的图片上传\r\n     * @return mixed\r\n     */\r\n    private function upBase64()\r\n    {\r\n        $base64Data = $_POST[$this->fileField];\r\n        $img = base64_decode($base64Data);\r\n\r\n        $this->oriName = $this->config['oriName'];\r\n        $this->fileSize = strlen($img);\r\n        $this->fileType = $this->getFileExt();\r\n        $this->fullName = $this->getFullName();\r\n        $this->filePath = $this->getFilePath();\r\n        $this->fileName = $this->getFileName();\r\n        $dirname = dirname($this->filePath);\r\n\r\n        //检查文件大小是否超出限制\r\n        if (!$this->checkSize()) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_SIZE_EXCEED\");\r\n            return;\r\n        }\r\n\r\n        //创建目录失败\r\n        if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_CREATE_DIR\");\r\n            return;\r\n        } else if (!is_writeable($dirname)) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_DIR_NOT_WRITEABLE\");\r\n            return;\r\n        }\r\n\r\n        //移动文件\r\n        if (!(file_put_contents($this->filePath, $img) && file_exists($this->filePath))) { //移动失败\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_WRITE_CONTENT\");\r\n        } else { //移动成功\r\n            $this->stateInfo = $this->stateMap[0];\r\n        }\r\n\r\n    }\r\n\r\n    /**\r\n     * 拉取远程图片\r\n     * @return mixed\r\n     */\r\n    private function saveRemote()\r\n    {\r\n        $imgUrl = htmlspecialchars($this->fileField);\r\n        $imgUrl = str_replace(\"&amp;\", \"&\", $imgUrl);\r\n\r\n        //http开头验证\r\n        if (strpos($imgUrl, \"http\") !== 0) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_HTTP_LINK\");\r\n            return;\r\n        }\r\n\r\n        preg_match('/(^https*:\\/\\/[^:\\/]+)/', $imgUrl, $matches);\r\n        $host_with_protocol = count($matches) > 1 ? $matches[1] : '';\r\n\r\n        // 判断是否是合法 url\r\n        if (!filter_var($host_with_protocol, FILTER_VALIDATE_URL)) {\r\n            $this->stateInfo = $this->getStateInfo(\"INVALID_URL\");\r\n            return;\r\n        }\r\n\r\n        preg_match('/^https*:\\/\\/(.+)/', $host_with_protocol, $matches);\r\n        $host_without_protocol = count($matches) > 1 ? $matches[1] : '';\r\n\r\n        // 此时提取出来的可能是 ip 也有可能是域名，先获取 ip\r\n        $ip = gethostbyname($host_without_protocol);\r\n        // 判断是否是私有 ip\r\n        if(!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_NO_PRIV_RANGE)) {\r\n            $this->stateInfo = $this->getStateInfo(\"INVALID_IP\");\r\n            return;\r\n        }\r\n\r\n        //获取请求头并检测死链\r\n        $heads = get_headers($imgUrl, 1);\r\n        if (!(stristr($heads[0], \"200\") && stristr($heads[0], \"OK\"))) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_DEAD_LINK\");\r\n            return;\r\n        }\r\n        //格式验证(扩展名验证和Content-Type验证)\r\n        $fileType = strtolower(strrchr($imgUrl, '.'));\r\n        if (!in_array($fileType, $this->config['allowFiles']) || !isset($heads['Content-Type']) || !stristr($heads['Content-Type'], \"image\")) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_HTTP_CONTENTTYPE\");\r\n            return;\r\n        }\r\n\r\n        //打开输出缓冲区并获取远程图片\r\n        ob_start();\r\n        $context = stream_context_create(\r\n            array('http' => array(\r\n                'follow_location' => false // don't follow redirects\r\n            ))\r\n        );\r\n        readfile($imgUrl, false, $context);\r\n        $img = ob_get_contents();\r\n        ob_end_clean();\r\n        preg_match(\"/[\\/]([^\\/]*)[\\.]?[^\\.\\/]*$/\", $imgUrl, $m);\r\n\r\n        $this->oriName = $m ? $m[1]:\"\";\r\n        $this->fileSize = strlen($img);\r\n        $this->fileType = $this->getFileExt();\r\n        $this->fullName = $this->getFullName();\r\n        $this->filePath = $this->getFilePath();\r\n        $this->fileName = $this->getFileName();\r\n        $dirname = dirname($this->filePath);\r\n\r\n        //检查文件大小是否超出限制\r\n        if (!$this->checkSize()) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_SIZE_EXCEED\");\r\n            return;\r\n        }\r\n\r\n        //创建目录失败\r\n        if (!file_exists($dirname) && !mkdir($dirname, 0777, true)) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_CREATE_DIR\");\r\n            return;\r\n        } else if (!is_writeable($dirname)) {\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_DIR_NOT_WRITEABLE\");\r\n            return;\r\n        }\r\n\r\n        //移动文件\r\n        if (!(file_put_contents($this->filePath, $img) && file_exists($this->filePath))) { //移动失败\r\n            $this->stateInfo = $this->getStateInfo(\"ERROR_WRITE_CONTENT\");\r\n        } else { //移动成功\r\n            $this->stateInfo = $this->stateMap[0];\r\n        }\r\n\r\n    }\r\n\r\n    /**\r\n     * 上传错误检查\r\n     * @param $errCode\r\n     * @return string\r\n     */\r\n    private function getStateInfo($errCode)\r\n    {\r\n        return !$this->stateMap[$errCode] ? $this->stateMap[\"ERROR_UNKNOWN\"] : $this->stateMap[$errCode];\r\n    }\r\n\r\n    /**\r\n     * 获取文件扩展名\r\n     * @return string\r\n     */\r\n    private function getFileExt()\r\n    {\r\n        return strtolower(strrchr($this->oriName, '.'));\r\n    }\r\n\r\n    /**\r\n     * 重命名文件\r\n     * @return string\r\n     */\r\n    private function getFullName()\r\n    {\r\n        //替换日期事件\r\n        $t = time();\r\n        $d = explode('-', date(\"Y-y-m-d-H-i-s\"));\r\n        $format = $this->config[\"pathFormat\"];\r\n        $format = str_replace(\"{yyyy}\", $d[0], $format);\r\n        $format = str_replace(\"{yy}\", $d[1], $format);\r\n        $format = str_replace(\"{mm}\", $d[2], $format);\r\n        $format = str_replace(\"{dd}\", $d[3], $format);\r\n        $format = str_replace(\"{hh}\", $d[4], $format);\r\n        $format = str_replace(\"{ii}\", $d[5], $format);\r\n        $format = str_replace(\"{ss}\", $d[6], $format);\r\n        $format = str_replace(\"{time}\", $t, $format);\r\n\r\n        //过滤文件名的非法自负,并替换文件名\r\n        $oriName = substr($this->oriName, 0, strrpos($this->oriName, '.'));\r\n        $oriName = preg_replace(\"/[\\|\\?\\\"\\<\\>\\/\\*\\\\\\\\]+/\", '', $oriName);\r\n        $format = str_replace(\"{filename}\", $oriName, $format);\r\n\r\n        //替换随机字符串\r\n        $randNum = rand(1, 10000000000) . rand(1, 10000000000);\r\n        if (preg_match(\"/\\{rand\\:([\\d]*)\\}/i\", $format, $matches)) {\r\n            $format = preg_replace(\"/\\{rand\\:[\\d]*\\}/i\", substr($randNum, 0, $matches[1]), $format);\r\n        }\r\n\r\n        $ext = $this->getFileExt();\r\n        return $format . $ext;\r\n    }\r\n\r\n    /**\r\n     * 获取文件名\r\n     * @return string\r\n     */\r\n    private function getFileName () {\r\n        return substr($this->filePath, strrpos($this->filePath, '/') + 1);\r\n    }\r\n\r\n    /**\r\n     * 获取文件完整路径\r\n     * @return string\r\n     */\r\n    private function getFilePath()\r\n    {\r\n        $fullname = $this->fullName;\r\n        $rootPath = $_SERVER['DOCUMENT_ROOT'];\r\n\r\n        if (substr($fullname, 0, 1) != '/') {\r\n            $fullname = '/' . $fullname;\r\n        }\r\n\r\n        return $rootPath . $fullname;\r\n    }\r\n\r\n    /**\r\n     * 文件类型检测\r\n     * @return bool\r\n     */\r\n    private function checkType()\r\n    {\r\n        return in_array($this->getFileExt(), $this->config[\"allowFiles\"]);\r\n    }\r\n\r\n    /**\r\n     * 文件大小检测\r\n     * @return bool\r\n     */\r\n    private function  checkSize()\r\n    {\r\n        return $this->fileSize <= ($this->config[\"maxSize\"]);\r\n    }\r\n\r\n    /**\r\n     * 获取当前上传成功文件的各项信息\r\n     * @return array\r\n     */\r\n    public function getFileInfo()\r\n    {\r\n        return array(\r\n            \"state\" => $this->stateInfo,\r\n            \"url\" => $this->fullName,\r\n            \"title\" => $this->fileName,\r\n            \"original\" => $this->oriName,\r\n            \"type\" => $this->fileType,\r\n            \"size\" => $this->fileSize\r\n        );\r\n    }\r\n\r\n}"
  },
  {
    "path": "public/static/ueditor/php/action_crawler.php",
    "content": "<?php\n/**\n * 抓取远程图片\n * User: Jinqn\n * Date: 14-04-14\n * Time: 下午19:18\n */\nset_time_limit(0);\ninclude(\"Uploader.class.php\");\n\n/* 上传配置 */\n$config = array(\n    \"pathFormat\" => $CONFIG['catcherPathFormat'],\n    \"maxSize\" => $CONFIG['catcherMaxSize'],\n    \"allowFiles\" => $CONFIG['catcherAllowFiles'],\n    \"oriName\" => \"remote.png\"\n);\n$fieldName = $CONFIG['catcherFieldName'];\n\n/* 抓取远程图片 */\n$list = array();\nif (isset($_POST[$fieldName])) {\n    $source = $_POST[$fieldName];\n} else {\n    $source = $_GET[$fieldName];\n}\nforeach ($source as $imgUrl) {\n    $item = new Uploader($imgUrl, $config, \"remote\");\n    $info = $item->getFileInfo();\n    array_push($list, array(\n        \"state\" => $info[\"state\"],\n        \"url\" => $info[\"url\"],\n        \"size\" => $info[\"size\"],\n        \"title\" => htmlspecialchars($info[\"title\"]),\n        \"original\" => htmlspecialchars($info[\"original\"]),\n        \"source\" => htmlspecialchars($imgUrl)\n    ));\n}\n\n/* 返回抓取数据 */\nreturn json_encode(array(\n    'state'=> count($list) ? 'SUCCESS':'ERROR',\n    'list'=> $list\n));"
  },
  {
    "path": "public/static/ueditor/php/action_list.php",
    "content": "<?php\n/**\n * 获取已上传的文件列表\n * User: Jinqn\n * Date: 14-04-09\n * Time: 上午10:17\n */\ninclude \"Uploader.class.php\";\n\n/* 判断类型 */\nswitch ($_GET['action']) {\n    /* 列出文件 */\n    case 'listfile':\n        $allowFiles = $CONFIG['fileManagerAllowFiles'];\n        $listSize = $CONFIG['fileManagerListSize'];\n        $path = $CONFIG['fileManagerListPath'];\n        break;\n    /* 列出图片 */\n    case 'listimage':\n    default:\n        $allowFiles = $CONFIG['imageManagerAllowFiles'];\n        $listSize = $CONFIG['imageManagerListSize'];\n        $path = $CONFIG['imageManagerListPath'];\n}\n$allowFiles = substr(str_replace(\".\", \"|\", join(\"\", $allowFiles)), 1);\n\n/* 获取参数 */\n$size = isset($_GET['size']) ? htmlspecialchars($_GET['size']) : $listSize;\n$start = isset($_GET['start']) ? htmlspecialchars($_GET['start']) : 0;\n$end = $start + $size;\n\n/* 获取文件列表 */\n$path = $_SERVER['DOCUMENT_ROOT'] . (substr($path, 0, 1) == \"/\" ? \"\":\"/\") . $path;\n$files = getfiles($path, $allowFiles);\nif (!count($files)) {\n    return json_encode(array(\n        \"state\" => \"no match file\",\n        \"list\" => array(),\n        \"start\" => $start,\n        \"total\" => count($files)\n    ));\n}\n\n/* 获取指定范围的列表 */\n$len = count($files);\nfor ($i = min($end, $len) - 1, $list = array(); $i < $len && $i >= 0 && $i >= $start; $i--){\n    $list[] = $files[$i];\n}\n//倒序\n//for ($i = $end, $list = array(); $i < $len && $i < $end; $i++){\n//    $list[] = $files[$i];\n//}\n\n/* 返回数据 */\n$result = json_encode(array(\n    \"state\" => \"SUCCESS\",\n    \"list\" => $list,\n    \"start\" => $start,\n    \"total\" => count($files)\n));\n\nreturn $result;\n\n\n/**\n * 遍历获取目录下的指定类型的文件\n * @param $path\n * @param array $files\n * @return array\n */\nfunction getfiles($path, $allowFiles, &$files = array())\n{\n    if (!is_dir($path)) return null;\n    if(substr($path, strlen($path) - 1) != '/') $path .= '/';\n    $handle = opendir($path);\n    while (false !== ($file = readdir($handle))) {\n        if ($file != '.' && $file != '..') {\n            $path2 = $path . $file;\n            if (is_dir($path2)) {\n                getfiles($path2, $allowFiles, $files);\n            } else {\n                if (preg_match(\"/\\.(\".$allowFiles.\")$/i\", $file)) {\n                    $files[] = array(\n                        'url'=> substr($path2, strlen($_SERVER['DOCUMENT_ROOT'])),\n                        'mtime'=> filemtime($path2)\n                    );\n                }\n            }\n        }\n    }\n    return $files;\n}"
  },
  {
    "path": "public/static/ueditor/php/action_upload.php",
    "content": "<?php\n/**\n * 上传附件和上传视频\n * User: Jinqn\n * Date: 14-04-09\n * Time: 上午10:17\n */\ninclude \"Uploader.class.php\";\n\n/* 上传配置 */\n$base64 = \"upload\";\nswitch (htmlspecialchars($_GET['action'])) {\n    case 'uploadimage':\n        $config = array(\n            \"pathFormat\" => $CONFIG['imagePathFormat'],\n            \"maxSize\" => $CONFIG['imageMaxSize'],\n            \"allowFiles\" => $CONFIG['imageAllowFiles']\n        );\n        $fieldName = $CONFIG['imageFieldName'];\n        break;\n    case 'uploadscrawl':\n        $config = array(\n            \"pathFormat\" => $CONFIG['scrawlPathFormat'],\n            \"maxSize\" => $CONFIG['scrawlMaxSize'],\n            \"allowFiles\" => $CONFIG['scrawlAllowFiles'],\n            \"oriName\" => \"scrawl.png\"\n        );\n        $fieldName = $CONFIG['scrawlFieldName'];\n        $base64 = \"base64\";\n        break;\n    case 'uploadvideo':\n        $config = array(\n            \"pathFormat\" => $CONFIG['videoPathFormat'],\n            \"maxSize\" => $CONFIG['videoMaxSize'],\n            \"allowFiles\" => $CONFIG['videoAllowFiles']\n        );\n        $fieldName = $CONFIG['videoFieldName'];\n        break;\n    case 'uploadfile':\n    default:\n        $config = array(\n            \"pathFormat\" => $CONFIG['filePathFormat'],\n            \"maxSize\" => $CONFIG['fileMaxSize'],\n            \"allowFiles\" => $CONFIG['fileAllowFiles']\n        );\n        $fieldName = $CONFIG['fileFieldName'];\n        break;\n}\n\n/* 生成上传实例对象并完成上传 */\n$up = new Uploader($fieldName, $config, $base64);\n\n/**\n * 得到上传文件所对应的各个参数,数组结构\n * array(\n *     \"state\" => \"\",          //上传状态，上传成功时必须返回\"SUCCESS\"\n *     \"url\" => \"\",            //返回的地址\n *     \"title\" => \"\",          //新文件名\n *     \"original\" => \"\",       //原始文件名\n *     \"type\" => \"\"            //文件类型\n *     \"size\" => \"\",           //文件大小\n * )\n */\n\n/* 返回数据 */\nreturn json_encode($up->getFileInfo());\n"
  },
  {
    "path": "public/static/ueditor/php/config.json",
    "content": "/* 前后端通信相关的配置,注释只允许使用多行方式 */\n{\n    /* 上传图片配置项 */\n    \"imageActionName\": \"uploadimage\", /* 执行上传图片的action名称 */\n    \"imageFieldName\": \"upfile\", /* 提交的图片表单名称 */\n    \"imageMaxSize\": 2048000, /* 上传大小限制，单位B */\n    \"imageAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* 上传图片格式显示 */\n    \"imageCompressEnable\": true, /* 是否压缩图片,默认是true */\n    \"imageCompressBorder\": 1600, /* 图片压缩最长边限制 */\n    \"imageInsertAlign\": \"none\", /* 插入的图片浮动方式 */\n    \"imageUrlPrefix\": \"\", /* 图片访问路径前缀 */\n    \"imagePathFormat\": \"/public/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\", /* 上传保存路径,可以自定义保存路径和文件名格式 */\n                                /* {filename} 会替换成原文件名,配置这项需要注意中文乱码问题 */\n                                /* {rand:6} 会替换成随机数,后面的数字是随机数的位数 */\n                                /* {time} 会替换成时间戳 */\n                                /* {yyyy} 会替换成四位年份 */\n                                /* {yy} 会替换成两位年份 */\n                                /* {mm} 会替换成两位月份 */\n                                /* {dd} 会替换成两位日期 */\n                                /* {hh} 会替换成两位小时 */\n                                /* {ii} 会替换成两位分钟 */\n                                /* {ss} 会替换成两位秒 */\n                                /* 非法字符 \\ : * ? \" < > | */\n                                /* 具请体看线上文档: fex.baidu.com/ueditor/#use-format_upload_filename */\n\n    /* 涂鸦图片上传配置项 */\n    \"scrawlActionName\": \"uploadscrawl\", /* 执行上传涂鸦的action名称 */\n    \"scrawlFieldName\": \"upfile\", /* 提交的图片表单名称 */\n    \"scrawlPathFormat\": \"/public/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\", /* 上传保存路径,可以自定义保存路径和文件名格式 */\n    \"scrawlMaxSize\": 2048000, /* 上传大小限制，单位B */\n    \"scrawlUrlPrefix\": \"\", /* 图片访问路径前缀 */\n    \"scrawlInsertAlign\": \"none\",\n\n    /* 截图工具上传 */\n    \"snapscreenActionName\": \"uploadimage\", /* 执行上传截图的action名称 */\n    \"snapscreenPathFormat\": \"/public/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\", /* 上传保存路径,可以自定义保存路径和文件名格式 */\n    \"snapscreenUrlPrefix\": \"\", /* 图片访问路径前缀 */\n    \"snapscreenInsertAlign\": \"none\", /* 插入的图片浮动方式 */\n\n    /* 抓取远程图片配置 */\n    \"catcherLocalDomain\": [\"127.0.0.1\", \"localhost\", \"img.baidu.com\"],\n    \"catcherActionName\": \"catchimage\", /* 执行抓取远程图片的action名称 */\n    \"catcherFieldName\": \"source\", /* 提交的图片列表表单名称 */\n    \"catcherPathFormat\": \"/public/ueditor/php/upload/image/{yyyy}{mm}{dd}/{time}{rand:6}\", /* 上传保存路径,可以自定义保存路径和文件名格式 */\n    \"catcherUrlPrefix\": \"\", /* 图片访问路径前缀 */\n    \"catcherMaxSize\": 2048000, /* 上传大小限制，单位B */\n    \"catcherAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* 抓取图片格式显示 */\n\n    /* 上传视频配置 */\n    \"videoActionName\": \"uploadvideo\", /* 执行上传视频的action名称 */\n    \"videoFieldName\": \"upfile\", /* 提交的视频表单名称 */\n    \"videoPathFormat\": \"/public/ueditor/php/upload/video/{yyyy}{mm}{dd}/{time}{rand:6}\", /* 上传保存路径,可以自定义保存路径和文件名格式 */\n    \"videoUrlPrefix\": \"\", /* 视频访问路径前缀 */\n    \"videoMaxSize\": 102400000, /* 上传大小限制，单位B，默认100MB */\n    \"videoAllowFiles\": [\n        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\"], /* 上传视频格式显示 */\n\n    /* 上传文件配置 */\n    \"fileActionName\": \"uploadfile\", /* controller里,执行上传视频的action名称 */\n    \"fileFieldName\": \"upfile\", /* 提交的文件表单名称 */\n    \"filePathFormat\": \"/public/ueditor/php/upload/file/{yyyy}{mm}{dd}/{time}{rand:6}\", /* 上传保存路径,可以自定义保存路径和文件名格式 */\n    \"fileUrlPrefix\": \"\", /* 文件访问路径前缀 */\n    \"fileMaxSize\": 51200000, /* 上传大小限制，单位B，默认50MB */\n    \"fileAllowFiles\": [\n        \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n        \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n        \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n    ], /* 上传文件格式显示 */\n\n    /* 列出指定目录下的图片 */\n    \"imageManagerActionName\": \"listimage\", /* 执行图片管理的action名称 */\n    \"imageManagerListPath\": \"/public/ueditor/php/upload/image/\", /* 指定要列出图片的目录 */\n    \"imageManagerListSize\": 20, /* 每次列出文件数量 */\n    \"imageManagerUrlPrefix\": \"\", /* 图片访问路径前缀 */\n    \"imageManagerInsertAlign\": \"none\", /* 插入的图片浮动方式 */\n    \"imageManagerAllowFiles\": [\".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\"], /* 列出的文件类型 */\n\n    /* 列出指定目录下的文件 */\n    \"fileManagerActionName\": \"listfile\", /* 执行文件管理的action名称 */\n    \"fileManagerListPath\": \"/public/ueditor/php/upload/file/\", /* 指定要列出文件的目录 */\n    \"fileManagerUrlPrefix\": \"\", /* 文件访问路径前缀 */\n    \"fileManagerListSize\": 20, /* 每次列出文件数量 */\n    \"fileManagerAllowFiles\": [\n        \".png\", \".jpg\", \".jpeg\", \".gif\", \".bmp\",\n        \".flv\", \".swf\", \".mkv\", \".avi\", \".rm\", \".rmvb\", \".mpeg\", \".mpg\",\n        \".ogg\", \".ogv\", \".mov\", \".wmv\", \".mp4\", \".webm\", \".mp3\", \".wav\", \".mid\",\n        \".rar\", \".zip\", \".tar\", \".gz\", \".7z\", \".bz2\", \".cab\", \".iso\",\n        \".doc\", \".docx\", \".xls\", \".xlsx\", \".ppt\", \".pptx\", \".pdf\", \".txt\", \".md\", \".xml\"\n    ] /* 列出的文件类型 */\n\n}"
  },
  {
    "path": "public/static/ueditor/php/controller.php",
    "content": "<?php\n//header('Access-Control-Allow-Origin: http://www.baidu.com'); //设置http://www.baidu.com允许跨域访问\n//header('Access-Control-Allow-Headers: X-Requested-With,X_Requested_With'); //设置允许的跨域header\ndate_default_timezone_set(\"Asia/chongqing\");\nerror_reporting(E_ERROR);\nheader(\"Content-Type: text/html; charset=utf-8\");\n\n$CONFIG = json_decode(preg_replace(\"/\\/\\*[\\s\\S]+?\\*\\//\", \"\", file_get_contents(\"config.json\")), true);\n$action = $_GET['action'];\n\nswitch ($action) {\n    case 'config':\n        $CONFIG['imageUrlPrefix'] = \"http://\" . $_SERVER['HTTP_HOST'];\n        $result =  json_encode($CONFIG);\n        break;\n\n    /* 上传图片 */\n    case 'uploadimage':\n    /* 上传涂鸦 */\n    case 'uploadscrawl':\n    /* 上传视频 */\n    case 'uploadvideo':\n    /* 上传文件 */\n    case 'uploadfile':\n        $result = include(\"action_upload.php\");\n        break;\n\n    /* 列出图片 */\n    case 'listimage':\n        $result = include(\"action_list.php\");\n        break;\n    /* 列出文件 */\n    case 'listfile':\n        $result = include(\"action_list.php\");\n        break;\n\n    /* 抓取远程文件 */\n    case 'catchimage':\n        $result = include(\"action_crawler.php\");\n        break;\n\n    default:\n        $result = json_encode(array(\n            'state'=> '请求地址出错'\n        ));\n        break;\n}\n\n/* 输出结果 */\nif (isset($_GET[\"callback\"])) {\n    if (preg_match(\"/^[\\w_]+$/\", $_GET[\"callback\"])) {\n        echo htmlspecialchars($_GET[\"callback\"]) . '(' . $result . ')';\n    } else {\n        echo json_encode(array(\n            'state'=> 'callback参数不合法'\n        ));\n    }\n} else {\n    echo $result;\n}"
  },
  {
    "path": "public/static/ueditor/themes/default/css/ueditor.css",
    "content": "/*基础UI构建\r\n*/\r\n/* common layer */\r\n.edui-default .edui-box {\r\n    border: none;\r\n    padding: 0;\r\n    margin: 0;\r\n    overflow: hidden;\r\n}\r\n\r\n.edui-default a.edui-box {\r\n    display: block;\r\n    text-decoration: none;\r\n    color: black;\r\n}\r\n\r\n.edui-default a.edui-box:hover {\r\n    text-decoration: none;\r\n}\r\n\r\n.edui-default a.edui-box:active {\r\n    text-decoration: none;\r\n}\r\n\r\n.edui-default table.edui-box {\r\n    border-collapse: collapse;\r\n}\r\n\r\n.edui-default ul.edui-box {\r\n    list-style-type: none;\r\n}\r\n\r\ndiv.edui-box {\r\n    position: relative;\r\n    display: -moz-inline-box !important;\r\n    display: inline-block !important;\r\n    vertical-align: top;\r\n}\r\n\r\n.edui-default .edui-clearfix {\r\n    zoom: 1\r\n}\r\n\r\n.edui-default .edui-clearfix:after {\r\n    content: '\\20';\r\n    display: block;\r\n    clear: both;\r\n}\r\n\r\n * html div.edui-box {\r\n    display: inline !important;\r\n}\r\n\r\n*:first-child+html div.edui-box {\r\n    display: inline !important;\r\n}\r\n\r\n/* control layout */\r\n.edui-default .edui-button-body, .edui-splitbutton-body, .edui-menubutton-body, .edui-combox-body {\r\n    position: relative;\r\n}\r\n\r\n.edui-default .edui-popup {\r\n    position: absolute;\r\n    -webkit-user-select: none;\r\n    -moz-user-select: none;\r\n}\r\n\r\n.edui-default .edui-popup .edui-shadow {\r\n    position: absolute;\r\n    z-index: -1;\r\n}\r\n\r\n.edui-default .edui-popup .edui-bordereraser {\r\n    position: absolute;\r\n    overflow: hidden;\r\n}\r\n\r\n.edui-default .edui-tablepicker .edui-canvas {\r\n    position: relative;\r\n}\r\n\r\n.edui-default .edui-tablepicker .edui-canvas .edui-overlay {\r\n    position: absolute;\r\n}\r\n\r\n.edui-default .edui-dialog-modalmask, .edui-dialog-dragmask {\r\n    position: absolute;\r\n    left: 0;\r\n    top: 0;\r\n    width: 100%;\r\n    height: 100%;\r\n}\r\n\r\n.edui-default .edui-toolbar {\r\n    position: relative;\r\n}\r\n\r\n/*\r\n * default theme\r\n */\r\n.edui-default .edui-label {\r\n    cursor: default;\r\n}\r\n\r\n.edui-default span.edui-clickable {\r\n    color: blue;\r\n    cursor: pointer;\r\n    text-decoration: underline;\r\n}\r\n\r\n.edui-default span.edui-unclickable {\r\n    color: gray;\r\n    cursor: default;\r\n}\n/* 工具栏 */\r\n.edui-default .edui-toolbar {\r\n    cursor: default;\r\n    -webkit-user-select: none;\r\n    -moz-user-select: none;\r\n    padding: 1px;\r\n    overflow: hidden; /*全屏下单独一行不占位*/\r\n    zoom: 1;\r\n    width:auto;\r\n    height:auto;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-button,\r\n.edui-default .edui-toolbar .edui-splitbutton,\r\n.edui-default .edui-toolbar .edui-menubutton,\r\n.edui-default .edui-toolbar .edui-combox {\r\n    margin: 1px;\r\n}\n/*UI工具栏、编辑区域、底部*/\r\n.edui-default .edui-editor {\r\n    border: 1px solid #d4d4d4;\r\n    background-color: white;\r\n    position: relative;\r\n    overflow: visible;\r\n    -webkit-border-radius: 4px;\r\n    -moz-border-radius: 4px;\r\n    border-radius: 4px;\r\n}\r\n.edui-editor div{\r\n    width:auto;\r\n    height:auto;\r\n}\r\n.edui-default .edui-editor-toolbarbox {\r\n    position: relative;\r\n    zoom: 1;\r\n    -webkit-box-shadow:0 1px 4px rgba(204, 204, 204, 0.6);\r\n    -moz-box-shadow:0 1px 4px rgba(204, 204, 204, 0.6);\r\n    box-shadow:0 1px 4px rgba(204, 204, 204, 0.6);\r\n    border-top-left-radius:2px;\r\n    border-top-right-radius:2px;\r\n}\r\n\r\n.edui-default .edui-editor-toolbarboxouter {\r\n    border-bottom: 1px solid #d4d4d4;\r\n    background-color: #fafafa;\r\n    background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2);\r\n    background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));\r\n    background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2);\r\n    background-image: -o-linear-gradient(top, #ffffff, #f2f2f2);\r\n    background-image: linear-gradient(to bottom, #ffffff, #f2f2f2);\r\n    background-repeat: repeat-x;\r\n    /*border: 1px solid #d4d4d4;*/\r\n    -webkit-border-radius: 4px 4px 0 0;\r\n    -moz-border-radius: 4px 4px 0 0;\r\n    border-radius: 4px 4px 0 0;\r\n    filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);\r\n    *zoom: 1;\r\n    -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);\r\n    -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);\r\n    box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);\r\n}\r\n\r\n.edui-default .edui-editor-toolbarboxinner {\r\n    padding: 2px;\r\n}\r\n\r\n.edui-default .edui-editor-iframeholder {\r\n    position: relative;\r\n    /*for fix ie6 toolbarmsg under iframe bug. relative -> static */\r\n    /*_position: static !important;*\r\n}\r\n\r\n.edui-default .edui-editor-iframeholder textarea {\r\n    font-family: consolas, \"Courier New\", \"lucida console\", monospace;\r\n    font-size: 12px;\r\n    line-height: 18px;\r\n}\r\n\r\n.edui-default .edui-editor-bottombar {\r\n    /*border-top: 1px solid #ccc;*/\r\n    /*height: 20px;*/\r\n    /*width: 40%;*/\r\n    /*float: left;*/\r\n    /*overflow: hidden;*/\r\n}\r\n\r\n.edui-default .edui-editor-bottomContainer {\r\n    overflow: hidden;\r\n}\r\n\r\n.edui-default .edui-editor-bottomContainer table {\r\n    width: 100%;\r\n    height: 0;\r\n    overflow: hidden;\r\n    border-spacing: 0;\r\n}\r\n\r\n.edui-default .edui-editor-bottomContainer td {\r\n    white-space: nowrap;\r\n    border-top: 1px solid #ccc;\r\n    line-height: 20px;\r\n    font-size: 12px;\r\n    font-family: Arial, Helvetica, Tahoma, Verdana, Sans-Serif;\r\n}\r\n\r\n.edui-default .edui-editor-wordcount {\r\n    text-align: right;\r\n    margin-right: 5px;\r\n    color: #aaa;\r\n}\r\n.edui-default .edui-editor-scale {\r\n    width: 12px;\r\n}\r\n.edui-default .edui-editor-scale .edui-editor-icon {\r\n    float: right;\r\n    width: 100%;\r\n    height: 12px;\r\n    margin-top: 10px;\r\n    background: url(../images/scale.png) no-repeat;\r\n    cursor: se-resize;\r\n}\r\n.edui-default .edui-editor-breadcrumb {\r\n    margin: 2px 0 0 3px;\r\n}\r\n\r\n.edui-default .edui-editor-breadcrumb span {\r\n    cursor: pointer;\r\n    text-decoration: underline;\r\n    color: blue;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-for-fullscreen {\r\n    float: right;\r\n}\r\n\r\n.edui-default .edui-bubble .edui-popup-content {\r\n    border: 1px solid #DCAC6C;\r\n    background-color: #fff6d9;\r\n    padding: 5px;\r\n    font-size: 10pt;\r\n    font-family: \"宋体\";\r\n}\r\n\r\n.edui-default .edui-bubble .edui-shadow {\r\n    /*box-shadow: 1px 1px 3px #818181;*/\r\n    /*-webkit-box-shadow: 2px 2px 3px #818181;*/\r\n    /*-moz-box-shadow: 2px 2px 3px #818181;*/\r\n    /*filter: progid:DXImageTransform.Microsoft.Blur(PixelRadius = '2', MakeShadow = 'true', ShadowOpacity = '0.5');*/\r\n}\r\n\r\n.edui-default .edui-editor-toolbarmsg {\r\n    background-color: #FFF6D9;\r\n    border-bottom: 1px solid #ccc;\r\n    position: absolute;\r\n    bottom: -25px;\r\n    left: 0;\r\n    z-index: 1009;\r\n    width: 99.9%;\r\n}\r\n\r\n.edui-default .edui-editor-toolbarmsg-upload {\r\n    font-size: 14px;\r\n    color: blue;\r\n    width: 100px;\r\n    height: 16px;\r\n    line-height: 16px;\r\n    cursor: pointer;\r\n    position: absolute;\r\n    top: 5px;\r\n    left: 350px;\r\n}\r\n\r\n.edui-default .edui-editor-toolbarmsg-label {\r\n    font-size: 12px;\r\n    line-height: 16px;\r\n    padding: 4px;\r\n}\r\n\r\n.edui-default .edui-editor-toolbarmsg-close {\r\n    float: right;\r\n    width: 20px;\r\n    height: 16px;\r\n    line-height: 16px;\r\n    cursor: pointer;\r\n    color: red;\r\n}\n/*可选中菜单按钮*/\r\n.edui-default .edui-list .edui-bordereraser {\r\n    display: none;\r\n}\r\n\r\n.edui-default .edui-listitem {\r\n    padding: 1px;\r\n    white-space: nowrap;\r\n}\r\n\r\n.edui-default .edui-list .edui-state-hover {\r\n    position: relative;\r\n    background-color: #fff5d4;\r\n    border: 1px solid #dcac6c;\r\n    padding: 0;\r\n}\r\n\r\n.edui-default .edui-for-fontfamily .edui-listitem-label {\r\n    min-width: 130px;\r\n    _width: 120px;\r\n    font-size: 12px;\r\n    height: 22px;\r\n    line-height: 22px;\r\n    padding-left: 5px;\r\n}\r\n.edui-default .edui-for-insertcode .edui-listitem-label {\r\n    min-width: 120px;\r\n    _width: 120px;\r\n    font-size: 12px;\r\n    height: 22px;\r\n    line-height: 22px;\r\n    padding-left: 5px;\r\n}\r\n.edui-default .edui-for-underline .edui-listitem-label {\r\n    min-width: 120px;\r\n    _width: 120px;\r\n    padding: 3px 5px;\r\n    font-size: 12px;\r\n}\r\n\r\n.edui-default .edui-for-fontsize .edui-listitem-label {\r\n    min-width: 120px;\r\n    _width: 120px;\r\n    padding: 3px 5px;\r\n\r\n}\r\n\r\n.edui-default .edui-for-paragraph .edui-listitem-label {\r\n    min-width: 200px;\r\n    _width: 200px;\r\n    padding: 2px 5px;\r\n}\r\n\r\n.edui-default .edui-for-rowspacingtop .edui-listitem-label,\r\n.edui-default .edui-for-rowspacingbottom .edui-listitem-label {\r\n    min-width: 53px;\r\n    _width: 53px;\r\n    padding: 2px 5px;\r\n}\r\n\r\n.edui-default .edui-for-lineheight .edui-listitem-label {\r\n    min-width: 53px;\r\n    _width: 53px;\r\n    padding: 2px 5px;\r\n}\r\n\r\n.edui-default .edui-for-customstyle .edui-listitem-label {\r\n    min-width: 200px;\r\n    _width: 200px;\r\n    width: 200px !important;\r\n    padding: 2px 5px;\r\n}\n/* 可选中按钮弹出菜单*/\r\n.edui-default .edui-menu {\r\n    z-index: 3000;\r\n}\r\n\r\n.edui-default .edui-menu .edui-popup-content {\r\n    padding: 3px;\r\n}\r\n\r\n.edui-default .edui-menu-body {\r\n    _width: 150px;\r\n    min-width: 170px;\r\n    background: url(\"../images/sparator_v.png\") repeat-y 25px;\r\n}\r\n\r\n.edui-default .edui-menuitem-body {\r\n}\r\n\r\n.edui-default .edui-menuitem {\r\n    height: 20px;\r\n    cursor: default;\r\n    vertical-align: top;\r\n}\r\n\r\n.edui-default .edui-menuitem .edui-icon {\r\n    width: 20px !important;\r\n    height: 20px !important;\r\n    background: url(../images/icons.png) 0 -4000px;\r\n    background: url(../images/icons.gif) 0 -4000px\\9;\r\n}\r\n\r\n.edui-default .edui-menuitem .edui-label {\r\n    font-size: 12px;\r\n    line-height: 20px;\r\n    height: 20px;\r\n    padding-left: 10px;\r\n}\r\n\r\n.edui-default .edui-state-checked .edui-menuitem-body {\r\n    background: url(\"../images/icons-all.gif\") no-repeat 6px -205px;\r\n}\r\n\r\n.edui-default .edui-state-disabled .edui-menuitem-label {\r\n    color: gray;\r\n}\r\n\r\n\n/*不可选中菜单按钮 */\r\n.edui-default .edui-toolbar .edui-combox-body .edui-button-body {\r\n    width: 60px;\r\n    font-size: 12px;\r\n    height: 20px;\r\n    line-height: 20px;\r\n    padding-left: 5px;\r\n    white-space: nowrap;\r\n    margin: 0 3px 0 0;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-combox-body .edui-arrow {\r\n    background: url(../images/icons.png) -741px 0;\r\n    _background: url(../images/icons.gif) -741px 0;\r\n    height: 20px;\r\n    width: 9px;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-combox .edui-combox-body {\r\n    border: 1px solid #CCC;\r\n    background-color: white;\r\n    border-radius: 2px;\r\n    -webkit-border-radius: 2px;\r\n    -moz-border-radius: 2px;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-combox-body .edui-splitborder {\r\n    display: none;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-combox-body .edui-arrow {\r\n    border-left: 1px solid #CCC;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-state-hover .edui-combox-body {\r\n    background-color: #fff5d4;\r\n    border: 1px solid #dcac6c;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-state-hover .edui-combox-body .edui-arrow {\r\n    border-left: 1px solid #dcac6c;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-state-checked .edui-combox-body {\r\n    background-color: #FFE69F;\r\n    border: 1px solid #DCAC6C;\r\n}\r\n\r\n.edui-toolbar .edui-state-checked .edui-combox-body .edui-arrow {\r\n    border-left: 1px solid #DCAC6C;\r\n}\r\n\r\n.edui-toolbar .edui-state-disabled .edui-combox-body {\r\n    background-color: #F0F0EE;\r\n    opacity: 0.3;\r\n    filter: alpha(opacity = 30);\r\n}\r\n\r\n.edui-toolbar .edui-state-opened .edui-combox-body {\r\n    background-color: white;\r\n    border: 1px solid gray;\r\n}\n/*普通按钮样式及状态*/\r\n.edui-default .edui-toolbar .edui-button .edui-icon,\r\n.edui-default .edui-toolbar .edui-menubutton .edui-icon,\r\n.edui-default .edui-toolbar .edui-splitbutton .edui-icon {\r\n    height: 20px !important;\r\n    width: 20px !important;\r\n    background-image: url(../images/icons.png);\r\n    background-image: url(../images/icons.gif) \\9;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-button .edui-button-wrap {\r\n    padding: 1px;\r\n    position: relative;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-button .edui-state-hover .edui-button-wrap {\r\n    background-color: #fff5d4;\r\n    padding: 0;\r\n    border: 1px solid #dcac6c;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-button .edui-state-checked .edui-button-wrap {\r\n    background-color: #ffe69f;\r\n    padding: 0;\r\n    border: 1px solid #dcac6c;\r\n    border-radius: 2px;\r\n    -webkit-border-radius: 2px;\r\n    -moz-border-radius: 2px;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-button .edui-state-active .edui-button-wrap {\r\n    background-color: #ffffff;\r\n    padding: 0;\r\n    border: 1px solid gray;\r\n}\r\n.edui-default .edui-toolbar .edui-state-disabled .edui-label {\r\n    color: #ccc;\r\n}\r\n.edui-default .edui-toolbar .edui-state-disabled .edui-icon {\r\n    opacity: 0.3;\r\n    filter: alpha(opacity = 30);\r\n}\r\n\n/* toolbar icons */\r\n.edui-default .edui-for-undo .edui-icon {\r\n    background-position: -160px 0;\r\n}\r\n\r\n.edui-default  .edui-for-redo .edui-icon {\r\n    background-position: -100px 0;\r\n}\r\n\r\n.edui-default  .edui-for-bold .edui-icon {\r\n    background-position: 0 0;\r\n}\r\n\r\n.edui-default  .edui-for-italic .edui-icon {\r\n    background-position: -60px 0;\r\n}\r\n\r\n.edui-default  .edui-for-fontborder .edui-icon {\r\n    background-position:-160px -40px;\r\n}\r\n.edui-default  .edui-for-underline .edui-icon {\r\n    background-position: -140px 0;\r\n}\r\n\r\n.edui-default  .edui-for-strikethrough .edui-icon {\r\n    background-position: -120px 0;\r\n}\r\n\r\n.edui-default  .edui-for-subscript .edui-icon {\r\n    background-position: -600px 0;\r\n}\r\n\r\n.edui-default  .edui-for-superscript .edui-icon {\r\n    background-position: -620px 0;\r\n}\r\n\r\n.edui-default  .edui-for-blockquote .edui-icon {\r\n    background-position: -220px 0;\r\n}\r\n\r\n.edui-default  .edui-for-forecolor .edui-icon {\r\n    background-position: -720px 0;\r\n}\r\n\r\n.edui-default  .edui-for-backcolor .edui-icon {\r\n    background-position: -760px 0;\r\n}\r\n\r\n.edui-default  .edui-for-inserttable .edui-icon {\r\n    background-position: -580px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-autotypeset .edui-icon {\r\n    background-position: -640px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-justifyleft .edui-icon {\r\n    background-position: -460px 0;\r\n}\r\n\r\n.edui-default  .edui-for-justifycenter .edui-icon {\r\n    background-position: -420px 0;\r\n}\r\n\r\n.edui-default  .edui-for-justifyright .edui-icon {\r\n    background-position: -480px 0;\r\n}\r\n\r\n.edui-default  .edui-for-justifyjustify .edui-icon {\r\n    background-position: -440px 0;\r\n}\r\n\r\n.edui-default  .edui-for-insertorderedlist .edui-icon {\r\n    background-position: -80px 0;\r\n}\r\n\r\n.edui-default  .edui-for-insertunorderedlist .edui-icon {\r\n    background-position: -20px 0;\r\n}\r\n\r\n.edui-default  .edui-for-lineheight .edui-icon {\r\n    background-position: -725px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-rowspacingbottom .edui-icon {\r\n    background-position: -745px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-rowspacingtop .edui-icon {\r\n    background-position: -765px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-horizontal .edui-icon {\r\n    background-position: -360px 0;\r\n}\r\n\r\n.edui-default  .edui-for-link .edui-icon {\r\n    background-position: -500px 0;\r\n}\r\n\r\n.edui-default  .edui-for-code .edui-icon {\r\n    background-position: -440px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-insertimage .edui-icon {\r\n    background-position: -726px -77px;\r\n}\r\n\r\n.edui-default  .edui-for-insertframe .edui-icon {\r\n    background-position: -240px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-emoticon .edui-icon {\r\n    background-position: -60px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-spechars .edui-icon {\r\n    background-position: -240px 0;\r\n}\r\n\r\n.edui-default  .edui-for-help .edui-icon {\r\n    background-position: -340px 0;\r\n}\r\n\r\n.edui-default  .edui-for-print .edui-icon {\r\n    background-position: -440px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-preview .edui-icon {\r\n    background-position: -420px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-selectall .edui-icon {\r\n    background-position: -400px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-searchreplace .edui-icon {\r\n    background-position: -520px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-map .edui-icon {\r\n    background-position: -40px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-gmap .edui-icon {\r\n    background-position: -260px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-insertvideo .edui-icon {\r\n    background-position: -320px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-time .edui-icon {\r\n    background-position: -160px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-date .edui-icon {\r\n    background-position: -140px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-cut .edui-icon {\r\n    background-position: -680px 0;\r\n}\r\n\r\n.edui-default  .edui-for-copy .edui-icon {\r\n    background-position: -700px 0;\r\n}\r\n\r\n.edui-default  .edui-for-paste .edui-icon {\r\n    background-position: -560px 0;\r\n}\r\n\r\n.edui-default  .edui-for-formatmatch .edui-icon {\r\n    background-position: -40px 0;\r\n}\r\n\r\n.edui-default  .edui-for-pasteplain .edui-icon {\r\n    background-position: -360px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-directionalityltr .edui-icon {\r\n    background-position: -20px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-directionalityrtl .edui-icon {\r\n    background-position: -40px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-source .edui-icon {\r\n    background-position: -261px -0px;\r\n}\r\n\r\n.edui-default  .edui-for-removeformat .edui-icon {\r\n    background-position: -580px 0;\r\n}\r\n\r\n.edui-default  .edui-for-unlink .edui-icon {\r\n    background-position: -640px 0;\r\n}\r\n\r\n.edui-default  .edui-for-touppercase .edui-icon {\r\n    background-position: -786px 0;\r\n}\r\n\r\n.edui-default  .edui-for-tolowercase .edui-icon {\r\n    background-position: -806px 0;\r\n}\r\n\r\n.edui-default  .edui-for-insertrow .edui-icon {\r\n    background-position: -478px -76px;\r\n}\r\n\r\n.edui-default  .edui-for-insertrownext .edui-icon {\r\n    background-position: -498px -76px;\r\n}\r\n\r\n.edui-default  .edui-for-insertcol .edui-icon {\r\n    background-position: -455px -76px;\r\n}\r\n\r\n.edui-default  .edui-for-insertcolnext  .edui-icon {\r\n    background-position: -429px -76px;\r\n}\r\n\r\n.edui-default  .edui-for-mergeright .edui-icon {\r\n    background-position: -60px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-mergedown .edui-icon {\r\n    background-position: -80px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-splittorows .edui-icon {\r\n    background-position: -100px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-splittocols .edui-icon {\r\n    background-position: -120px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-insertparagraphbeforetable .edui-icon {\r\n    background-position: -140px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-deleterow .edui-icon {\r\n    background-position: -660px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-deletecol .edui-icon {\r\n    background-position: -640px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-splittocells .edui-icon {\r\n    background-position: -800px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-mergecells .edui-icon {\r\n    background-position: -760px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-deletetable .edui-icon {\r\n    background-position: -620px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-cleardoc .edui-icon {\r\n    background-position: -520px 0;\r\n}\r\n\r\n.edui-default  .edui-for-fullscreen .edui-icon {\r\n    background-position: -100px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-anchor .edui-icon {\r\n    background-position: -200px 0;\r\n}\r\n\r\n.edui-default  .edui-for-pagebreak .edui-icon {\r\n    background-position: -460px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-imagenone .edui-icon {\r\n    background-position: -480px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-imageleft .edui-icon {\r\n    background-position: -500px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-wordimage .edui-icon {\r\n    background-position: -660px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-imageright .edui-icon {\r\n    background-position: -520px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-imagecenter .edui-icon {\r\n    background-position: -540px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-indent .edui-icon {\r\n    background-position: -400px 0;\r\n}\r\n\r\n.edui-default  .edui-for-outdent .edui-icon {\r\n    background-position: -540px 0;\r\n}\r\n\r\n.edui-default  .edui-for-webapp .edui-icon {\r\n    background-position: -601px -40px\r\n}\r\n\r\n.edui-default  .edui-for-table .edui-icon {\r\n    background-position: -580px -20px;\r\n}\r\n\r\n.edui-default  .edui-for-edittable .edui-icon {\r\n    background-position: -420px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-template .edui-icon {\r\n    background-position: -339px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-delete .edui-icon {\r\n    background-position: -360px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-attachment .edui-icon {\r\n    background-position: -620px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-edittd .edui-icon {\r\n    background-position: -700px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-snapscreen .edui-icon {\r\n    background-position: -581px -40px\r\n}\r\n\r\n.edui-default  .edui-for-scrawl .edui-icon {\r\n    background-position: -801px -41px\r\n}\r\n\r\n.edui-default  .edui-for-background .edui-icon {\r\n    background-position: -680px -40px;\r\n}\r\n\r\n.edui-default  .edui-for-music .edui-icon {\r\n    background-position: -18px -40px\r\n}\r\n\r\n.edui-default  .edui-for-formula .edui-icon {\r\n    background-position: -200px -40px\r\n}\r\n\r\n.edui-default  .edui-for-aligntd  .edui-icon {\r\n    background-position: -236px -76px;\r\n}\r\n\r\n.edui-default  .edui-for-insertparagraphtrue  .edui-icon {\r\n    background-position: -625px -76px;\r\n}\r\n\r\n.edui-default  .edui-for-insertparagraph  .edui-icon {\r\n    background-position: -602px -76px;\r\n}\r\n\r\n.edui-default  .edui-for-insertcaption  .edui-icon {\r\n    background-position: -336px -76px;\r\n}\r\n\r\n.edui-default  .edui-for-deletecaption  .edui-icon {\r\n    background-position: -362px -76px;\r\n}\r\n\r\n.edui-default  .edui-for-inserttitle  .edui-icon {\r\n    background-position: -286px -76px;\r\n}\r\n\r\n.edui-default  .edui-for-deletetitle  .edui-icon {\r\n    background-position: -311px -76px;\r\n}\r\n\r\n.edui-default  .edui-for-aligntable  .edui-icon {\r\n    background-position: -440px 0;\r\n}\r\n\r\n.edui-default  .edui-for-tablealignment-left  .edui-icon {\r\n    background-position: -460px 0;\r\n}\r\n\r\n.edui-default  .edui-for-tablealignment-center  .edui-icon {\r\n    background-position: -420px 0;\r\n}\r\n\r\n.edui-default  .edui-for-tablealignment-right  .edui-icon {\r\n    background-position: -480px 0;\r\n}\r\n\r\n.edui-default  .edui-for-drafts  .edui-icon {\r\n    background-position: -560px 0;\r\n}\r\n\r\n.edui-default  .edui-for-charts  .edui-icon {\r\n    background: url( ../images/charts.png ) no-repeat 2px 3px!important;\r\n}\r\n\r\n.edui-default  .edui-for-inserttitlecol  .edui-icon {\r\n    background-position: -673px -76px;\r\n}\r\n\r\n.edui-default  .edui-for-deletetitlecol  .edui-icon {\r\n    background-position: -698px -76px;\r\n}\r\n\r\n.edui-default  .edui-for-simpleupload  .edui-icon {\r\n    background-position: -380px 0px;\r\n}\n/*splitbutton*/\r\n.edui-default .edui-toolbar .edui-splitbutton-body .edui-arrow,\r\n.edui-default .edui-toolbar .edui-menubutton-body .edui-arrow {\r\n    background: url(../images/icons.png) -741px 0;\r\n    _background: url(../images/icons.gif) -741px 0;\r\n    height: 20px;\r\n    width: 9px;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-splitbutton .edui-splitbutton-body,\r\n.edui-default .edui-toolbar .edui-menubutton .edui-menubutton-body {\r\n    padding: 1px;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-splitborder {\r\n    width: 1px;\r\n    height: 20px;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-state-hover .edui-splitborder {\r\n    width: 1px;\r\n    border-left: 0px solid #dcac6c;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-state-active .edui-splitborder {\r\n    width: 0;\r\n    border-left: 1px solid gray;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-state-opened .edui-splitborder {\r\n    width: 1px;\r\n    border: 0;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-splitbutton .edui-state-hover .edui-splitbutton-body,\r\n.edui-default .edui-toolbar .edui-menubutton .edui-state-hover .edui-menubutton-body {\r\n    background-color: #fff5d4;\r\n    border: 1px solid #dcac6c;\r\n    padding: 0;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-splitbutton .edui-state-checked .edui-splitbutton-body,\r\n.edui-default .edui-toolbar .edui-menubutton .edui-state-checked .edui-menubutton-body {\r\n    background-color: #FFE69F;\r\n    border: 1px solid #DCAC6C;\r\n    padding: 0;\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-splitbutton .edui-state-active .edui-splitbutton-body,\r\n.edui-default .edui-toolbar .edui-menubutton .edui-state-active .edui-menubutton-body {\r\n    background-color: #ffffff;\r\n    border: 1px solid gray;\r\n    padding: 0;\r\n}\r\n\r\n.edui-default .edui-state-disabled .edui-arrow {\r\n    opacity: 0.3;\r\n    _filter: alpha(opacity = 30);\r\n}\r\n\r\n.edui-default .edui-toolbar .edui-splitbutton .edui-state-opened .edui-splitbutton-body,\r\n.edui-default .edui-toolbar .edui-menubutton .edui-state-opened .edui-menubutton-body {\r\n    background-color: white;\r\n    border: 1px solid gray;\r\n    padding: 0;\r\n}\r\n\r\n.edui-default .edui-for-insertorderedlist .edui-bordereraser,\r\n.edui-default .edui-for-lineheight .edui-bordereraser,\r\n.edui-default .edui-for-rowspacingtop .edui-bordereraser,\r\n.edui-default .edui-for-rowspacingbottom .edui-bordereraser,\r\n.edui-default .edui-for-insertunorderedlist .edui-bordereraser {\r\n    background-color: white;\r\n}\r\n\r\n/* 解决嵌套导致的图标问题 */\r\n.edui-default .edui-for-insertorderedlist .edui-popup-body .edui-icon,\r\n.edui-default .edui-for-lineheight .edui-popup-body .edui-icon,\r\n.edui-default .edui-for-rowspacingtop .edui-popup-body .edui-icon,\r\n.edui-default .edui-for-rowspacingbottom .edui-popup-body .edui-icon,\r\n.edui-default .edui-for-insertunorderedlist .edui-popup-body .edui-icon {\r\n    /*background-position: 0 -40px;*/\r\n    background-image: none  ;\r\n}\r\n\n/* 弹出菜单 */\r\n.edui-default .edui-popup {\r\n    z-index: 3000;\r\n    background-color: #ffffff;\r\n    width:auto;\r\n    height:auto;\r\n\r\n}\r\n\r\n.edui-default .edui-popup .edui-shadow {\r\n    left: 0;\r\n    top: 0;\r\n    width: 100%;\r\n    height: 100%;\r\n}\r\n\r\n.edui-default .edui-popup-content {\r\n    border:1px solid #ccc;\r\n    border: 1px solid rgba(0, 0, 0, 0.2);\r\n    *border-right-width: 2px;\r\n    *border-bottom-width: 2px;\r\n    -webkit-border-radius: 6px;\r\n    -moz-border-radius: 6px;\r\n    border-radius: 6px;\r\n    -webkit-box-shadow: 0 3px 4px rgba(0, 0, 0, 0.2);\r\n    -moz-box-shadow: 0 3px 4px rgba(0, 0, 0, 0.2);\r\n    box-shadow: 0 3px 4px rgba(0, 0, 0, 0.2);\r\n    -webkit-background-clip: padding-box;\r\n    -moz-background-clip: padding;\r\n    background-clip: padding-box;\r\n    padding: 5px;\r\n    background:#ffffff;\r\n}\r\n\r\n.edui-default .edui-popup .edui-bordereraser {\r\n    background-color: white;\r\n    height: 3px;\r\n}\r\n\r\n.edui-default .edui-menu .edui-bordereraser {\r\n    height: 3px;\r\n}\r\n\r\n.edui-default .edui-anchor-topleft .edui-bordereraser {\r\n    left: 1px;\r\n    top: -2px;\r\n}\r\n\r\n.edui-default .edui-anchor-topright .edui-bordereraser {\r\n    right: 1px;\r\n    top: -2px;\r\n}\r\n\r\n.edui-default .edui-anchor-bottomleft .edui-bordereraser {\r\n    left: 0;\r\n    bottom: -6px;\r\n    height: 7px;\r\n    border-left: 1px solid gray;\r\n    border-right: 1px solid gray;\r\n}\r\n\r\n.edui-default .edui-anchor-bottomright .edui-bordereraser {\r\n    right: 0;\r\n    bottom: -6px;\r\n    height: 7px;\r\n    border-left: 1px solid gray;\r\n    border-right: 1px solid gray;\r\n}\r\n\r\n.edui-popup div{\r\n    width:auto;\r\n    height:auto;\r\n}\n.edui-default .edui-editor-messageholder {\n    display: block;\n    width: 150px;\n    height: auto;\n    border: 0;\n    margin: 0;\n    padding: 0;\n    position: absolute;\n    top: 28px;\n    right: 3px;\n}\n\n.edui-default .edui-message{\n    min-height: 10px;\n    text-shadow: 0 1px 0 rgba(255,255,255,0.5);\n    padding: 0;\n    margin-bottom: 3px;\n    position: relative;\n}\n.edui-default .edui-message-body{\n    border-radius: 3px;\n    padding: 8px 15px 8px 8px;\n    color: #c09853;\n    background-color: #fcf8e3;\n    border: 1px solid #fbeed5;\n}\n.edui-default .edui-message-type-info{\n    color: #3a87ad;\n    background-color: #d9edf7;\n    border-color: #bce8f1\n}\n.edui-default .edui-message-type-success{\n    color: #468847;\n    background-color: #dff0d8;\n    border-color: #d6e9c6\n}\n.edui-default .edui-message-type-danger,\n.edui-default .edui-message-type-error{\n    color: #b94a48;\n    background-color: #f2dede;\n    border-color: #eed3d7\n}\n.edui-default .edui-message .edui-message-closer {\n    display: block;\n    width: 16px;\n    height: 16px;\n    line-height: 16px;\n    position: absolute;\n    top: 0;\n    right: 0;\n    padding: 0;\n    cursor: pointer;\n    background: transparent;\n    border: 0;\n    float: right;\n    font-size: 20px;\n    font-weight: bold;\n    color: #999;\n    text-shadow: 0 1px 0 #fff;\n    font-family: \"Helvetica Neue\",Helvetica,Arial,sans-serif;\n}\n.edui-default .edui-message .edui-message-content {\n    font-size: 10pt;\n    word-wrap: break-word;\n    word-break: normal;\n}\n/* 弹出对话框按钮和对话框大小 */\r\n.edui-default .edui-dialog {\r\n    z-index: 2000;\r\n    position: absolute;\r\n\r\n}\r\n\r\n.edui-dialog div{\r\n    width:auto;\r\n}\r\n\r\n.edui-default .edui-dialog-wrap {\r\n    margin-right: 6px;\r\n    margin-bottom: 6px;\r\n}\r\n\r\n.edui-default .edui-dialog-fullscreen-flag {\r\n    margin-right: 0;\r\n    margin-bottom: 0;\r\n}\r\n\r\n.edui-default .edui-dialog-body {\r\n    position: relative;\r\n    padding:2px 0 0 2px;\r\n    _zoom: 1;\r\n}\r\n\r\n.edui-default .edui-dialog-fullscreen-flag .edui-dialog-body {\r\n    padding: 0;\r\n}\r\n\r\n.edui-default .edui-dialog-shadow {\r\n    position: absolute;\r\n    z-index: -1;\r\n    left: 0;\r\n    top: 0;\r\n    width: 100%;\r\n    height: 100%;\r\n    background-color: #ffffff;\r\n    border: 1px solid #ccc;\r\n    border: 1px solid rgba(0, 0, 0, 0.2);\r\n    *border-right-width: 2px;\r\n    *border-bottom-width: 2px;\r\n    -webkit-border-radius: 6px;\r\n    -moz-border-radius: 6px;\r\n    border-radius: 6px;\r\n    -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\r\n    -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\r\n    box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);\r\n    -webkit-background-clip: padding-box;\r\n    -moz-background-clip: padding;\r\n    background-clip: padding-box;\r\n}\r\n\r\n.edui-default .edui-dialog-foot {\r\n    background-color: white;\r\n}\r\n\r\n.edui-default .edui-dialog-titlebar {\r\n    height: 26px;\r\n    border-bottom: 1px solid #c6c6c6;\r\n    background: url(../images/dialog-title-bg.png) repeat-x bottom;\r\n    position: relative;\r\n    cursor: move;\r\n}\r\n.edui-default .edui-dialog-caption {\r\n    font-weight: bold;\r\n    font-size: 12px;\r\n    line-height: 26px;\r\n    padding-left: 5px;\r\n}\r\n\r\n.edui-default .edui-dialog-draghandle {\r\n    height: 26px;\r\n}\r\n\r\n.edui-default .edui-dialog-closebutton {\r\n    position: absolute !important;\r\n    right: 5px;\r\n    top: 3px;\r\n}\r\n\r\n.edui-default .edui-dialog-closebutton .edui-button-body {\r\n    height: 20px;\r\n    width: 20px;\r\n    cursor: pointer;\r\n    background: url(\"../images/icons-all.gif\") no-repeat 0 -59px;\r\n}\r\n\r\n.edui-default .edui-dialog-closebutton .edui-state-hover .edui-button-body {\r\n    background: url(\"../images/icons-all.gif\") no-repeat 0 -89px;\r\n}\r\n\r\n.edui-default .edui-dialog-foot {\r\n    height: 40px;\r\n}\r\n\r\n.edui-default .edui-dialog-buttons {\r\n    position: absolute;\r\n    right: 0;\r\n}\r\n\r\n.edui-default .edui-dialog-buttons .edui-button {\r\n    margin-right: 10px;\r\n}\r\n\r\n.edui-default .edui-dialog-buttons .edui-button .edui-button-body {\r\n    background: url(\"../images/icons-all.gif\") no-repeat;\r\n    height: 24px;\r\n    width: 96px;\r\n    font-size: 12px;\r\n    line-height: 24px;\r\n    text-align: center;\r\n    cursor: default;\r\n}\r\n\r\n.edui-default .edui-dialog-buttons .edui-button .edui-state-hover .edui-button-body {\r\n    background: url(\"../images/icons-all.gif\") no-repeat 0 -30px;\r\n}\r\n\r\n.edui-default .edui-dialog iframe {\r\n    border: 0;\r\n    padding: 0;\r\n    margin: 0;\r\n    vertical-align: top;\r\n}\r\n\r\n.edui-default .edui-dialog-modalmask {\r\n    opacity: 0.3;\r\n    filter: alpha(opacity = 30);\r\n    background-color: #ccc;\r\n    position: absolute;\r\n    /*z-index: 1999;*/\r\n}\r\n\r\n.edui-default .edui-dialog-dragmask {\r\n    position: absolute;\r\n    /*z-index: 2001;*/\r\n    background-color: transparent;\r\n    cursor: move;\r\n}\r\n\r\n.edui-default .edui-dialog-content {\r\n    position: relative;\r\n}\r\n\r\n.edui-default .dialogcontmask {\r\n    cursor: move;\r\n    visibility: hidden;\r\n    display: block;\r\n    position: absolute;\r\n    width: 100%;\r\n    height: 100%;\r\n    opacity: 0;\r\n    filter: alpha(opacity = 0);\r\n}\r\n\r\n/*link-dialog*/\r\n.edui-default .edui-for-link .edui-dialog-content {\r\n    width: 420px;\r\n    height: 200px;\r\n    overflow: hidden;\r\n}\r\n/*background-dialog*/\r\n.edui-default .edui-for-background .edui-dialog-content {\r\n    width: 440px;\r\n    height: 280px;\r\n    overflow: hidden;\r\n}\r\n\r\n/*template-dialog*/\r\n.edui-default .edui-for-template .edui-dialog-content {\r\n    width: 630px;\r\n    height: 390px;\r\n    overflow: hidden;\r\n}\r\n\r\n/*scrawl-dialog*/\r\n.edui-default .edui-for-scrawl .edui-dialog-content {\r\n    width: 515px;\r\n    *width: 506px;\r\n    height: 360px;\r\n}\r\n\r\n/*spechars-dialog*/\r\n.edui-default .edui-for-spechars .edui-dialog-content {\r\n    width: 620px;\r\n    height: 500px;\r\n    *width: 630px;\r\n    *height: 570px;\r\n}\r\n\r\n/*image-dialog*/\r\n.edui-default .edui-for-insertimage .edui-dialog-content {\r\n    width: 650px;\r\n    height: 400px;\r\n    overflow: hidden;\r\n}\r\n/*webapp-dialog*/\r\n.edui-default .edui-for-webapp .edui-dialog-content {\r\n    width: 560px;\r\n    _width: 565px;\r\n    height: 450px;\r\n    overflow: hidden;\r\n}\r\n\r\n/*image-insertframe*/\r\n.edui-default .edui-for-insertframe .edui-dialog-content {\r\n    width: 350px;\r\n    height: 200px;\r\n    overflow: hidden;\r\n}\r\n\r\n/*wordImage-dialog*/\r\n.edui-default .edui-for-wordimage .edui-dialog-content {\r\n    width: 620px;\r\n    height: 380px;\r\n    overflow: hidden;\r\n}\r\n\r\n/*attachment-dialog*/\r\n.edui-default .edui-for-attachment .edui-dialog-content {\r\n    width: 650px;\r\n    height: 400px;\r\n    overflow: hidden;\r\n}\r\n\r\n\r\n/*map-dialog*/\r\n.edui-default .edui-for-map .edui-dialog-content {\r\n    width: 550px;\r\n    height: 400px;\r\n}\r\n\r\n/*gmap-dialog*/\r\n.edui-default .edui-for-gmap .edui-dialog-content {\r\n    width: 550px;\r\n    height: 400px;\r\n}\r\n\r\n/*video-dialog*/\r\n.edui-default .edui-for-insertvideo .edui-dialog-content {\r\n    width: 590px;\r\n    height: 390px;\r\n}\r\n\r\n/*anchor-dialog*/\r\n.edui-default .edui-for-anchor .edui-dialog-content {\r\n    width: 320px;\r\n    height: 60px;\r\n    overflow: hidden;\r\n}\r\n\r\n/*searchreplace-dialog*/\r\n.edui-default .edui-for-searchreplace .edui-dialog-content {\r\n    width: 400px;\r\n    height: 220px;\r\n}\r\n\r\n/*help-dialog*/\r\n.edui-default .edui-for-help .edui-dialog-content {\r\n    width: 400px;\r\n    height: 420px;\r\n}\r\n\r\n/*edittable-dialog*/\r\n.edui-default .edui-for-edittable .edui-dialog-content {\r\n    width: 540px;\r\n    _width:590px;\r\n    height: 335px;\r\n}\r\n\r\n/*edittip-dialog*/\r\n.edui-default .edui-for-edittip .edui-dialog-content {\r\n    width: 225px;\r\n    height: 60px;\r\n}\r\n\r\n/*edittd-dialog*/\r\n.edui-default .edui-for-edittd .edui-dialog-content {\r\n    width: 240px;\r\n    height: 50px;\r\n}\r\n/*snapscreen-dialog*/\r\n.edui-default .edui-for-snapscreen .edui-dialog-content {\r\n    width: 400px;\r\n    height: 220px;\r\n}\r\n\r\n/*music-dialog*/\r\n.edui-default .edui-for-music .edui-dialog-content {\r\n    width: 515px;\r\n    height: 360px;\r\n}\r\n\n/*段落弹出菜单*/\r\n.edui-default .edui-for-paragraph .edui-listitem-label {\r\n    font-family: Tahoma, Verdana, Arial, Helvetica;\r\n}\r\n\r\n.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-p {\r\n    font-size: 22px;\r\n    line-height: 27px;\r\n}\r\n\r\n.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h1 {\r\n    font-weight: bolder;\r\n    font-size: 32px;\r\n    line-height: 36px;\r\n}\r\n\r\n.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h2 {\r\n    font-weight: bolder;\r\n    font-size: 27px;\r\n    line-height: 29px;\r\n}\r\n\r\n.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h3 {\r\n    font-weight: bolder;\r\n    font-size: 19px;\r\n    line-height: 23px;\r\n}\r\n\r\n.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h4 {\r\n    font-weight: bolder;\r\n    font-size: 16px;\r\n    line-height: 19px\r\n}\r\n\r\n.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h5 {\r\n    font-weight: bolder;\r\n    font-size: 13px;\r\n    line-height: 16px;\r\n}\r\n\r\n.edui-default .edui-for-paragraph .edui-listitem-label .edui-for-h6 {\r\n    font-weight: bolder;\r\n    font-size: 12px;\r\n    line-height: 14px;\r\n}\n/* 表格弹出菜单 */\r\n.edui-default .edui-for-inserttable .edui-splitborder {\r\n    display: none\r\n}\r\n.edui-default .edui-for-inserttable  .edui-splitbutton-body .edui-arrow {\r\n    width: 0\r\n}\r\n.edui-default .edui-toolbar .edui-for-inserttable  .edui-state-active .edui-splitborder{\r\n    border-left: 1px solid transparent;\r\n}\r\n.edui-default .edui-tablepicker .edui-infoarea {\r\n    height: 14px;\r\n    line-height: 14px;\r\n    font-size: 12px;\r\n    width: 220px;\r\n    margin-bottom: 3px;\r\n    clear: both;\r\n}\r\n\r\n.edui-default .edui-tablepicker .edui-infoarea .edui-label {\r\n    float: left;\r\n}\r\n\r\n.edui-default .edui-dialog-buttons .edui-label {\r\n    line-height: 24px;\r\n}\r\n\r\n.edui-default .edui-tablepicker .edui-infoarea .edui-clickable {\r\n    float: right;\r\n}\r\n\r\n.edui-default .edui-tablepicker .edui-pickarea {\r\n    background: url(\"../images/unhighlighted.gif\") repeat;\r\n    height: 220px;\r\n    width: 220px;\r\n}\r\n\r\n.edui-default .edui-tablepicker .edui-pickarea .edui-overlay {\r\n    background: url(\"../images/highlighted.gif\") repeat;\r\n}\r\n\n/* 颜色弹出菜单 */\r\n.edui-default .edui-colorpicker-topbar {\r\n    height: 27px;\r\n    width: 200px;\r\n    /*border-bottom: 1px gray dashed;*/\r\n}\r\n\r\n.edui-default .edui-colorpicker-preview {\r\n    height: 20px;\r\n    border: 1px inset black;\r\n    margin-left: 1px;\r\n    width: 128px;\r\n    float: left;\r\n}\r\n\r\n.edui-default .edui-colorpicker-nocolor {\r\n    float: right;\r\n    margin-right: 1px;\r\n    font-size: 12px;\r\n    line-height: 14px;\r\n    height: 14px;\r\n    border: 1px solid #333;\r\n    padding: 3px 5px;\r\n    cursor: pointer;\r\n}\r\n\r\n.edui-default .edui-colorpicker-tablefirstrow {\r\n    height: 30px;\r\n}\r\n\r\n.edui-default .edui-colorpicker-colorcell {\r\n    width: 14px;\r\n    height: 14px;\r\n    display: block;\r\n    margin: 0;\r\n    cursor: pointer;\r\n}\r\n\r\n.edui-default .edui-colorpicker-colorcell:hover {\r\n    width: 14px;\r\n    height: 14px;\r\n    margin: 0;\r\n}\r\n.edui-default .edui-colorpicker-advbtn{\r\n    display: block;\r\n    text-align: center;\r\n    cursor: pointer;\r\n    height:20px;\r\n}\r\n.arrow_down{\r\n    background: white url('../images/arrow_down.png') no-repeat center;\r\n}\r\n.arrow_up{\r\n    background: white url('../images/arrow_up.png') no-repeat center;\r\n}\r\n/*高级的样式*/\r\n.edui-colorpicker-adv{\r\n    position: relative;\r\n    overflow: hidden;\r\n    height: 180px;\r\n    display: none;\r\n}\r\n.edui-colorpicker-plant, .edui-colorpicker-hue {\r\n    border: solid 1px #666;\r\n}\r\n.edui-colorpicker-pad {\r\n    width: 150px;\r\n    height: 150px;\r\n    left: 14px;\r\n    top: 13px;\r\n    position: absolute;\r\n    background: red;\r\n    overflow: hidden;\r\n    cursor: crosshair;\r\n}\r\n.edui-colorpicker-cover{\r\n    position: absolute;\r\n    top: 0;\r\n    left: 0;\r\n    width: 150px;\r\n    height: 150px;\r\n    background: url(\"../images/tangram-colorpicker.png\") -160px -200px;\r\n}\r\n.edui-colorpicker-padDot{\r\n    position: absolute;\r\n    top: 0;\r\n    left: 0;\r\n    width: 11px;\r\n    height: 11px;\r\n    overflow: hidden;\r\n    background: url(../images/tangram-colorpicker.png) 0px -200px repeat-x;\r\n    z-index: 1000;\r\n\r\n}\r\n.edui-colorpicker-sliderMain {\r\n    position: absolute;\r\n    left: 171px;\r\n    top: 13px;\r\n    width: 19px;\r\n    height: 152px;\r\n    background: url(../images/tangram-colorpicker.png) -179px -12px no-repeat;\r\n\r\n}\r\n.edui-colorpicker-slider {\r\n    width: 100%;\r\n    height: 100%;\r\n    cursor: pointer;\r\n}\r\n.edui-colorpicker-thumb{\r\n    position: absolute;\r\n    top: 0;\r\n    cursor: pointer;\r\n    height: 3px;\r\n    left: -1px;\r\n    right: -1px;\r\n    border: 1px solid black;\r\n    background: white;\r\n    opacity: .8;\r\n}\n/*自动排版弹出菜单*/\r\n.edui-default .edui-autotypesetpicker .edui-autotypesetpicker-body {\r\n    font-size: 12px;\r\n    margin-bottom: 3px;\r\n    clear: both;\r\n}\r\n\r\n.edui-default .edui-autotypesetpicker-body table {\r\n    border-collapse: separate;\r\n    border-spacing: 2px;\r\n}\r\n\r\n.edui-default .edui-autotypesetpicker-body td {\r\n    font-size: 12px;\r\n    word-wrap:break-word;\r\n}\r\n\r\n.edui-default .edui-autotypesetpicker-body td input {\r\n    margin: 3px 3px 3px 4px;\r\n    *margin: 1px 0 0 0;\r\n}\n/*自动排版弹出菜单*/\n.edui-default .edui-cellalignpicker .edui-cellalignpicker-body {\n    width: 70px;\n    font-size: 12px;\n    cursor: default;\n}\n\n.edui-default .edui-cellalignpicker-body table {\n    border-collapse: separate;\n    border-spacing: 0;\n}\n.edui-default .edui-cellalignpicker-body td{\n    padding: 1px;\n}\n.edui-default .edui-cellalignpicker-body .edui-icon{\n    height: 20px;\n    width: 20px;\n    padding: 1px;\n    background-image: url(../images/table-cell-align.png);\n}\n\n.edui-default .edui-cellalignpicker-body .edui-left{\n    background-position: 0 0;\n}\n\n.edui-default .edui-cellalignpicker-body .edui-center{\n    background-position: -25px 0;\n}\n.edui-default .edui-cellalignpicker-body .edui-right{\n    background-position: -51px 0;\n}\n\n.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-left{\n    background-position: -73px 0;\n}\n\n.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-center{\n    background-position: -98px 0;\n}\n\n.edui-default .edui-cellalignpicker-body td.edui-state-hover .edui-right{\n    background-position: -124px 0;\n}\n\n.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-left {\n    background-position: -146px 0;\n    background-color: #f1f4f5;\n}\n\n.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-center {\n    background-position: -245px 0;\n}\n\n.edui-default .edui-cellalignpicker-body td.edui-cellalign-selected .edui-right {\n    background-position: -271px 0;\n}\n/*分隔线*/\r\n.edui-default .edui-toolbar .edui-separator {\r\n    width: 2px;\r\n    height: 20px;\r\n    margin: 2px 4px 2px 3px;\r\n    background: url(../images/icons.png) -181px 0;\r\n    background: url(../images/icons.gif) -181px 0 \\9;\r\n}\r\n\n/*颜色按钮 */\r\n.edui-default .edui-toolbar .edui-colorbutton .edui-colorlump {\r\n    position: absolute;\r\n    overflow: hidden;\r\n    bottom: 1px;\r\n    left: 1px;\r\n    width: 18px;\r\n    height: 4px;\r\n}\n/*表情按钮及弹出菜单*/\r\n/*去除了表情的下拉箭头*/\r\n.edui-default .edui-for-emotion .edui-icon {\r\n    background-position: -60px -20px;\r\n}\r\n.edui-default .edui-for-emotion .edui-popup-content iframe\r\n{\r\n    width: 514px;\r\n    height: 380px;\r\n    overflow: hidden;\r\n}\r\n.edui-default .edui-for-emotion .edui-popup-content\r\n{\r\n    position: relative;\r\n    z-index: 555\r\n}\r\n\r\n.edui-default .edui-for-emotion .edui-splitborder {\r\n    display: none\r\n}\r\n\r\n.edui-default .edui-for-emotion .edui-splitbutton-body .edui-arrow\r\n{\r\n    width: 0\r\n}\r\n.edui-default .edui-toolbar .edui-for-emotion  .edui-state-active .edui-splitborder\r\n{\r\n    border-left: 1px solid transparent;\r\n}\n/*contextmenu*/\r\n.edui-default .edui-hassubmenu .edui-arrow {\r\n    height: 20px;\r\n    width: 20px;\r\n    float: right;\r\n    background: url(\"../images/icons-all.gif\") no-repeat 10px -233px;\r\n}\r\n\r\n.edui-default .edui-menu-body .edui-menuitem {\r\n    padding: 1px;\r\n}\r\n\r\n.edui-default .edui-menuseparator {\r\n    margin: 2px 0;\r\n    height: 1px;\r\n    overflow: hidden;\r\n}\r\n\r\n.edui-default .edui-menuseparator-inner {\r\n    border-bottom: 1px solid #e2e3e3;\r\n    margin-left: 29px;\r\n    margin-right: 1px;\r\n}\r\n\r\n.edui-default .edui-menu-body .edui-state-hover {\r\n    padding: 0 !important;\r\n    background-color: #fff5d4;\r\n    border: 1px solid #dcac6c;\r\n}\n/*弹出菜单*/\n.edui-default .edui-shortcutmenu {\n    padding: 2px;\n    width: 190px;\n    height: 50px;\n    background-color: #fff;\n    border: 1px solid #ccc;\n    border-radius: 5px;\n}\n\n/*粘贴弹出菜单*/\n.edui-default .edui-wordpastepop .edui-popup-content{\n    border: none;\n    padding: 0;\n    width: 54px;\n    height: 21px;\n}\n.edui-default  .edui-pasteicon {\n    width: 100%;\n    height: 100%;\n    background-image: url('../images/wordpaste.png');\n    background-position: 0 0;\n}\n\n.edui-default  .edui-pasteicon.edui-state-opened {\n    background-position: 0 -34px;\n}\n\n.edui-default  .edui-pastecontainer {\n    position: relative;\n    visibility: hidden;\n    width: 97px;\n    background: #fff;\n    border: 1px solid #ccc;\n}\n\n.edui-default  .edui-pastecontainer .edui-title {\n    font-weight: bold;\n    background: #F8F8FF;\n    height: 25px;\n    line-height: 25px;\n    font-size: 12px;\n    padding-left: 5px;\n}\n\n.edui-default  .edui-pastecontainer .edui-button {\n    overflow: hidden;\n    margin: 3px 0;\n}\n\n.edui-default  .edui-pastecontainer .edui-button .edui-richtxticon,\n.edui-default  .edui-pastecontainer .edui-button .edui-tagicon,\n.edui-default  .edui-pastecontainer .edui-button .edui-plaintxticon{\n    float: left;\n    cursor: pointer;\n    width: 29px;\n    height: 29px;\n    margin-left: 5px;\n    background-image: url('../images/wordpaste.png');\n    background-repeat: no-repeat;\n}\n.edui-default  .edui-pastecontainer .edui-button .edui-richtxticon {\n    margin-left: 0;\n    background-position: -109px 0;\n}\n.edui-default  .edui-pastecontainer .edui-button .edui-tagicon {\n    background-position: -148px 1px;\n}\n\n.edui-default  .edui-pastecontainer .edui-button .edui-plaintxticon {\n    background-position: -72px 0;\n}\n\n.edui-default  .edui-pastecontainer .edui-button .edui-state-hover .edui-richtxticon {\n    background-position: -109px -34px;\n}\n.edui-default  .edui-pastecontainer .edui-button .edui-state-hover .edui-tagicon{\n    background-position: -148px -34px;\n}\n.edui-default  .edui-pastecontainer .edui-button  .edui-state-hover .edui-plaintxticon{\n    background-position: -72px -34px;\n}"
  },
  {
    "path": "public/static/ueditor/themes/default/dialogbase.css",
    "content": "/*弹出对话框页面样式组件\r\n*/\r\n\r\n/*reset\r\n*/\r\nhtml, body, div, span, applet, object, iframe,\r\nh1, h2, h3, h4, h5, h6, p, blockquote, pre,\r\na, abbr, acronym, address, big, cite, code,\r\ndel, dfn, em, font, img, ins, kbd, q, s, samp,\r\nsmall, strike, strong, sub, sup, tt, var,\r\nb, u, i, center,\r\ndl, dt, dd, ol, ul, li,\r\nfieldset, form, label, legend,\r\ntable, caption, tbody, tfoot, thead, tr, th, td {\r\n    margin: 0;\r\n    padding: 0;\r\n    outline: 0;\r\n    font-size: 100%;\r\n}\r\n\r\nbody {\r\n    line-height: 1;\r\n}\r\n\r\nol, ul {\r\n    list-style: none;\r\n}\r\n\r\nblockquote, q {\r\n    quotes: none;\r\n}\r\n\r\nins {\r\n    text-decoration: none;\r\n}\r\n\r\ndel {\r\n    text-decoration: line-through;\r\n}\r\n\r\ntable {\r\n    border-collapse: collapse;\r\n    border-spacing: 0;\r\n}\r\n\r\n/*module\r\n*/\r\nbody {\r\n    background-color: #fff;\r\n    font: 12px/1.5 sans-serif, \"宋体\", \"Arial Narrow\", HELVETICA;\r\n    color: #646464;\r\n}\r\n\r\n/*tab*/\r\n.tabhead {\r\n    position: relative;\r\n    z-index: 10;\r\n}\r\n\r\n.tabhead span {\r\n    display: inline-block;\r\n    padding: 0 5px;\r\n    height: 30px;\r\n    border: 1px solid #ccc;\r\n    background: url(\"images/dialog-title-bg.png\") repeat-x;\r\n    text-align: center;\r\n    line-height: 30px;\r\n    cursor: pointer;\r\n    *margin-right: 5px;\r\n}\r\n\r\n.tabhead span.focus {\r\n    height: 31px;\r\n    border-bottom: none;\r\n    background: #fff;\r\n}\r\n\r\n.tabbody {\r\n    position: relative;\r\n    top: -1px;\r\n    margin: 0 auto;\r\n    border: 1px solid #ccc;\r\n}\r\n\r\n/*button*/\r\na.button {\r\n    display: block;\r\n    text-align: center;\r\n    line-height: 24px;\r\n    text-decoration: none;\r\n    height: 24px;\r\n    width: 95px;\r\n    border: 0;\r\n    color: #838383;\r\n    background: url(../../themes/default/images/icons-all.gif) no-repeat;\r\n}\r\n\r\na.button:hover {\r\n    background-position: 0 -30px;\r\n}"
  },
  {
    "path": "public/static/ueditor/themes/iframe.css",
    "content": "/*可以在这里添加你自己的css*/\r\n"
  },
  {
    "path": "public/static/ueditor/third-party/SyntaxHighlighter/shCore.js",
    "content": "// XRegExp 1.5.1\n// (c) 2007-2012 Steven Levithan\n// MIT License\n// <http://xregexp.com>\n// Provides an augmented, extensible, cross-browser implementation of regular expressions,\n// including support for additional syntax, flags, and methods\n\nvar XRegExp;\n\nif (XRegExp) {\n    // Avoid running twice, since that would break references to native globals\n    throw Error(\"can't load XRegExp twice in the same frame\");\n}\n\n// Run within an anonymous function to protect variables and avoid new globals\n(function (undefined) {\n\n    //---------------------------------\n    //  Constructor\n    //---------------------------------\n\n    // Accepts a pattern and flags; returns a new, extended `RegExp` object. Differs from a native\n    // regular expression in that additional syntax and flags are supported and cross-browser\n    // syntax inconsistencies are ameliorated. `XRegExp(/regex/)` clones an existing regex and\n    // converts to type XRegExp\n    XRegExp = function (pattern, flags) {\n        var output = [],\n            currScope = XRegExp.OUTSIDE_CLASS,\n            pos = 0,\n            context, tokenResult, match, chr, regex;\n\n        if (XRegExp.isRegExp(pattern)) {\n            if (flags !== undefined)\n                throw TypeError(\"can't supply flags when constructing one RegExp from another\");\n            return clone(pattern);\n        }\n        // Tokens become part of the regex construction process, so protect against infinite\n        // recursion when an XRegExp is constructed within a token handler or trigger\n        if (isInsideConstructor)\n            throw Error(\"can't call the XRegExp constructor within token definition functions\");\n\n        flags = flags || \"\";\n        context = { // `this` object for custom tokens\n            hasNamedCapture: false,\n            captureNames: [],\n            hasFlag: function (flag) {return flags.indexOf(flag) > -1;},\n            setFlag: function (flag) {flags += flag;}\n        };\n\n        while (pos < pattern.length) {\n            // Check for custom tokens at the current position\n            tokenResult = runTokens(pattern, pos, currScope, context);\n\n            if (tokenResult) {\n                output.push(tokenResult.output);\n                pos += (tokenResult.match[0].length || 1);\n            } else {\n                // Check for native multicharacter metasequences (excluding character classes) at\n                // the current position\n                if (match = nativ.exec.call(nativeTokens[currScope], pattern.slice(pos))) {\n                    output.push(match[0]);\n                    pos += match[0].length;\n                } else {\n                    chr = pattern.charAt(pos);\n                    if (chr === \"[\")\n                        currScope = XRegExp.INSIDE_CLASS;\n                    else if (chr === \"]\")\n                        currScope = XRegExp.OUTSIDE_CLASS;\n                    // Advance position one character\n                    output.push(chr);\n                    pos++;\n                }\n            }\n        }\n\n        regex = RegExp(output.join(\"\"), nativ.replace.call(flags, flagClip, \"\"));\n        regex._xregexp = {\n            source: pattern,\n            captureNames: context.hasNamedCapture ? context.captureNames : null\n        };\n        return regex;\n    };\n\n\n    //---------------------------------\n    //  Public properties\n    //---------------------------------\n\n    XRegExp.version = \"1.5.1\";\n\n    // Token scope bitflags\n    XRegExp.INSIDE_CLASS = 1;\n    XRegExp.OUTSIDE_CLASS = 2;\n\n\n    //---------------------------------\n    //  Private variables\n    //---------------------------------\n\n    var replacementToken = /\\$(?:(\\d\\d?|[$&`'])|{([$\\w]+)})/g,\n        flagClip = /[^gimy]+|([\\s\\S])(?=[\\s\\S]*\\1)/g, // Nonnative and duplicate flags\n        quantifier = /^(?:[?*+]|{\\d+(?:,\\d*)?})\\??/,\n        isInsideConstructor = false,\n        tokens = [],\n    // Copy native globals for reference (\"native\" is an ES3 reserved keyword)\n        nativ = {\n            exec: RegExp.prototype.exec,\n            test: RegExp.prototype.test,\n            match: String.prototype.match,\n            replace: String.prototype.replace,\n            split: String.prototype.split\n        },\n        compliantExecNpcg = nativ.exec.call(/()??/, \"\")[1] === undefined, // check `exec` handling of nonparticipating capturing groups\n        compliantLastIndexIncrement = function () {\n            var x = /^/g;\n            nativ.test.call(x, \"\");\n            return !x.lastIndex;\n        }(),\n        hasNativeY = RegExp.prototype.sticky !== undefined,\n        nativeTokens = {};\n\n    // `nativeTokens` match native multicharacter metasequences only (including deprecated octals,\n    // excluding character classes)\n    nativeTokens[XRegExp.INSIDE_CLASS] = /^(?:\\\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\\dA-Fa-f]{2}|u[\\dA-Fa-f]{4}|c[A-Za-z]|[\\s\\S]))/;\n    nativeTokens[XRegExp.OUTSIDE_CLASS] = /^(?:\\\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\\d*|x[\\dA-Fa-f]{2}|u[\\dA-Fa-f]{4}|c[A-Za-z]|[\\s\\S])|\\(\\?[:=!]|[?*+]\\?|{\\d+(?:,\\d*)?}\\??)/;\n\n\n    //---------------------------------\n    //  Public methods\n    //---------------------------------\n\n    // Lets you extend or change XRegExp syntax and create custom flags. This is used internally by\n    // the XRegExp library and can be used to create XRegExp plugins. This function is intended for\n    // users with advanced knowledge of JavaScript's regular expression syntax and behavior. It can\n    // be disabled by `XRegExp.freezeTokens`\n    XRegExp.addToken = function (regex, handler, scope, trigger) {\n        tokens.push({\n            pattern: clone(regex, \"g\" + (hasNativeY ? \"y\" : \"\")),\n            handler: handler,\n            scope: scope || XRegExp.OUTSIDE_CLASS,\n            trigger: trigger || null\n        });\n    };\n\n    // Accepts a pattern and flags; returns an extended `RegExp` object. If the pattern and flag\n    // combination has previously been cached, the cached copy is returned; otherwise the newly\n    // created regex is cached\n    XRegExp.cache = function (pattern, flags) {\n        var key = pattern + \"/\" + (flags || \"\");\n        return XRegExp.cache[key] || (XRegExp.cache[key] = XRegExp(pattern, flags));\n    };\n\n    // Accepts a `RegExp` instance; returns a copy with the `/g` flag set. The copy has a fresh\n    // `lastIndex` (set to zero). If you want to copy a regex without forcing the `global`\n    // property, use `XRegExp(regex)`. Do not use `RegExp(regex)` because it will not preserve\n    // special properties required for named capture\n    XRegExp.copyAsGlobal = function (regex) {\n        return clone(regex, \"g\");\n    };\n\n    // Accepts a string; returns the string with regex metacharacters escaped. The returned string\n    // can safely be used at any point within a regex to match the provided literal string. Escaped\n    // characters are [ ] { } ( ) * + ? - . , \\ ^ $ | # and whitespace\n    XRegExp.escape = function (str) {\n        return str.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\");\n    };\n\n    // Accepts a string to search, regex to search with, position to start the search within the\n    // string (default: 0), and an optional Boolean indicating whether matches must start at-or-\n    // after the position or at the specified position only. This function ignores the `lastIndex`\n    // of the provided regex in its own handling, but updates the property for compatibility\n    XRegExp.execAt = function (str, regex, pos, anchored) {\n        var r2 = clone(regex, \"g\" + ((anchored && hasNativeY) ? \"y\" : \"\")),\n            match;\n        r2.lastIndex = pos = pos || 0;\n        match = r2.exec(str); // Run the altered `exec` (required for `lastIndex` fix, etc.)\n        if (anchored && match && match.index !== pos)\n            match = null;\n        if (regex.global)\n            regex.lastIndex = match ? r2.lastIndex : 0;\n        return match;\n    };\n\n    // Breaks the unrestorable link to XRegExp's private list of tokens, thereby preventing\n    // syntax and flag changes. Should be run after XRegExp and any plugins are loaded\n    XRegExp.freezeTokens = function () {\n        XRegExp.addToken = function () {\n            throw Error(\"can't run addToken after freezeTokens\");\n        };\n    };\n\n    // Accepts any value; returns a Boolean indicating whether the argument is a `RegExp` object.\n    // Note that this is also `true` for regex literals and regexes created by the `XRegExp`\n    // constructor. This works correctly for variables created in another frame, when `instanceof`\n    // and `constructor` checks would fail to work as intended\n    XRegExp.isRegExp = function (o) {\n        return Object.prototype.toString.call(o) === \"[object RegExp]\";\n    };\n\n    // Executes `callback` once per match within `str`. Provides a simpler and cleaner way to\n    // iterate over regex matches compared to the traditional approaches of subverting\n    // `String.prototype.replace` or repeatedly calling `exec` within a `while` loop\n    XRegExp.iterate = function (str, regex, callback, context) {\n        var r2 = clone(regex, \"g\"),\n            i = -1, match;\n        while (match = r2.exec(str)) { // Run the altered `exec` (required for `lastIndex` fix, etc.)\n            if (regex.global)\n                regex.lastIndex = r2.lastIndex; // Doing this to follow expectations if `lastIndex` is checked within `callback`\n            callback.call(context, match, ++i, str, regex);\n            if (r2.lastIndex === match.index)\n                r2.lastIndex++;\n        }\n        if (regex.global)\n            regex.lastIndex = 0;\n    };\n\n    // Accepts a string and an array of regexes; returns the result of using each successive regex\n    // to search within the matches of the previous regex. The array of regexes can also contain\n    // objects with `regex` and `backref` properties, in which case the named or numbered back-\n    // references specified are passed forward to the next regex or returned. E.g.:\n    // var xregexpImgFileNames = XRegExp.matchChain(html, [\n    //     {regex: /<img\\b([^>]+)>/i, backref: 1}, // <img> tag attributes\n    //     {regex: XRegExp('(?ix) \\\\s src=\" (?<src> [^\"]+ )'), backref: \"src\"}, // src attribute values\n    //     {regex: XRegExp(\"^http://xregexp\\\\.com(/[^#?]+)\", \"i\"), backref: 1}, // xregexp.com paths\n    //     /[^\\/]+$/ // filenames (strip directory paths)\n    // ]);\n    XRegExp.matchChain = function (str, chain) {\n        return function recurseChain (values, level) {\n            var item = chain[level].regex ? chain[level] : {regex: chain[level]},\n                regex = clone(item.regex, \"g\"),\n                matches = [], i;\n            for (i = 0; i < values.length; i++) {\n                XRegExp.iterate(values[i], regex, function (match) {\n                    matches.push(item.backref ? (match[item.backref] || \"\") : match[0]);\n                });\n            }\n            return ((level === chain.length - 1) || !matches.length) ?\n                matches : recurseChain(matches, level + 1);\n        }([str], 0);\n    };\n\n\n    //---------------------------------\n    //  New RegExp prototype methods\n    //---------------------------------\n\n    // Accepts a context object and arguments array; returns the result of calling `exec` with the\n    // first value in the arguments array. the context is ignored but is accepted for congruity\n    // with `Function.prototype.apply`\n    RegExp.prototype.apply = function (context, args) {\n        return this.exec(args[0]);\n    };\n\n    // Accepts a context object and string; returns the result of calling `exec` with the provided\n    // string. the context is ignored but is accepted for congruity with `Function.prototype.call`\n    RegExp.prototype.call = function (context, str) {\n        return this.exec(str);\n    };\n\n\n    //---------------------------------\n    //  Overriden native methods\n    //---------------------------------\n\n    // Adds named capture support (with backreferences returned as `result.name`), and fixes two\n    // cross-browser issues per ES3:\n    // - Captured values for nonparticipating capturing groups should be returned as `undefined`,\n    //   rather than the empty string.\n    // - `lastIndex` should not be incremented after zero-length matches.\n    RegExp.prototype.exec = function (str) {\n        var match, name, r2, origLastIndex;\n        if (!this.global)\n            origLastIndex = this.lastIndex;\n        match = nativ.exec.apply(this, arguments);\n        if (match) {\n            // Fix browsers whose `exec` methods don't consistently return `undefined` for\n            // nonparticipating capturing groups\n            if (!compliantExecNpcg && match.length > 1 && indexOf(match, \"\") > -1) {\n                r2 = RegExp(this.source, nativ.replace.call(getNativeFlags(this), \"g\", \"\"));\n                // Using `str.slice(match.index)` rather than `match[0]` in case lookahead allowed\n                // matching due to characters outside the match\n                nativ.replace.call((str + \"\").slice(match.index), r2, function () {\n                    for (var i = 1; i < arguments.length - 2; i++) {\n                        if (arguments[i] === undefined)\n                            match[i] = undefined;\n                    }\n                });\n            }\n            // Attach named capture properties\n            if (this._xregexp && this._xregexp.captureNames) {\n                for (var i = 1; i < match.length; i++) {\n                    name = this._xregexp.captureNames[i - 1];\n                    if (name)\n                        match[name] = match[i];\n                }\n            }\n            // Fix browsers that increment `lastIndex` after zero-length matches\n            if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))\n                this.lastIndex--;\n        }\n        if (!this.global)\n            this.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows)\n        return match;\n    };\n\n    // Fix browser bugs in native method\n    RegExp.prototype.test = function (str) {\n        // Use the native `exec` to skip some processing overhead, even though the altered\n        // `exec` would take care of the `lastIndex` fixes\n        var match, origLastIndex;\n        if (!this.global)\n            origLastIndex = this.lastIndex;\n        match = nativ.exec.call(this, str);\n        // Fix browsers that increment `lastIndex` after zero-length matches\n        if (match && !compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))\n            this.lastIndex--;\n        if (!this.global)\n            this.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows)\n        return !!match;\n    };\n\n    // Adds named capture support and fixes browser bugs in native method\n    String.prototype.match = function (regex) {\n        if (!XRegExp.isRegExp(regex))\n            regex = RegExp(regex); // Native `RegExp`\n        if (regex.global) {\n            var result = nativ.match.apply(this, arguments);\n            regex.lastIndex = 0; // Fix IE bug\n            return result;\n        }\n        return regex.exec(this); // Run the altered `exec`\n    };\n\n    // Adds support for `${n}` tokens for named and numbered backreferences in replacement text,\n    // and provides named backreferences to replacement functions as `arguments[0].name`. Also\n    // fixes cross-browser differences in replacement text syntax when performing a replacement\n    // using a nonregex search value, and the value of replacement regexes' `lastIndex` property\n    // during replacement iterations. Note that this doesn't support SpiderMonkey's proprietary\n    // third (`flags`) parameter\n    String.prototype.replace = function (search, replacement) {\n        var isRegex = XRegExp.isRegExp(search),\n            captureNames, result, str, origLastIndex;\n\n        // There are too many combinations of search/replacement types/values and browser bugs that\n        // preclude passing to native `replace`, so don't try\n        //if (...)\n        //    return nativ.replace.apply(this, arguments);\n\n        if (isRegex) {\n            if (search._xregexp)\n                captureNames = search._xregexp.captureNames; // Array or `null`\n            if (!search.global)\n                origLastIndex = search.lastIndex;\n        } else {\n            search = search + \"\"; // Type conversion\n        }\n\n        if (Object.prototype.toString.call(replacement) === \"[object Function]\") {\n            result = nativ.replace.call(this + \"\", search, function () {\n                if (captureNames) {\n                    // Change the `arguments[0]` string primitive to a String object which can store properties\n                    arguments[0] = new String(arguments[0]);\n                    // Store named backreferences on `arguments[0]`\n                    for (var i = 0; i < captureNames.length; i++) {\n                        if (captureNames[i])\n                            arguments[0][captureNames[i]] = arguments[i + 1];\n                    }\n                }\n                // Update `lastIndex` before calling `replacement` (fix browsers)\n                if (isRegex && search.global)\n                    search.lastIndex = arguments[arguments.length - 2] + arguments[0].length;\n                return replacement.apply(null, arguments);\n            });\n        } else {\n            str = this + \"\"; // Type conversion, so `args[args.length - 1]` will be a string (given nonstring `this`)\n            result = nativ.replace.call(str, search, function () {\n                var args = arguments; // Keep this function's `arguments` available through closure\n                return nativ.replace.call(replacement + \"\", replacementToken, function ($0, $1, $2) {\n                    // Numbered backreference (without delimiters) or special variable\n                    if ($1) {\n                        switch ($1) {\n                            case \"$\": return \"$\";\n                            case \"&\": return args[0];\n                            case \"`\": return args[args.length - 1].slice(0, args[args.length - 2]);\n                            case \"'\": return args[args.length - 1].slice(args[args.length - 2] + args[0].length);\n                            // Numbered backreference\n                            default:\n                                // What does \"$10\" mean?\n                                // - Backreference 10, if 10 or more capturing groups exist\n                                // - Backreference 1 followed by \"0\", if 1-9 capturing groups exist\n                                // - Otherwise, it's the string \"$10\"\n                                // Also note:\n                                // - Backreferences cannot be more than two digits (enforced by `replacementToken`)\n                                // - \"$01\" is equivalent to \"$1\" if a capturing group exists, otherwise it's the string \"$01\"\n                                // - There is no \"$0\" token (\"$&\" is the entire match)\n                                var literalNumbers = \"\";\n                                $1 = +$1; // Type conversion; drop leading zero\n                                if (!$1) // `$1` was \"0\" or \"00\"\n                                    return $0;\n                                while ($1 > args.length - 3) {\n                                    literalNumbers = String.prototype.slice.call($1, -1) + literalNumbers;\n                                    $1 = Math.floor($1 / 10); // Drop the last digit\n                                }\n                                return ($1 ? args[$1] || \"\" : \"$\") + literalNumbers;\n                        }\n                        // Named backreference or delimited numbered backreference\n                    } else {\n                        // What does \"${n}\" mean?\n                        // - Backreference to numbered capture n. Two differences from \"$n\":\n                        //   - n can be more than two digits\n                        //   - Backreference 0 is allowed, and is the entire match\n                        // - Backreference to named capture n, if it exists and is not a number overridden by numbered capture\n                        // - Otherwise, it's the string \"${n}\"\n                        var n = +$2; // Type conversion; drop leading zeros\n                        if (n <= args.length - 3)\n                            return args[n];\n                        n = captureNames ? indexOf(captureNames, $2) : -1;\n                        return n > -1 ? args[n + 1] : $0;\n                    }\n                });\n            });\n        }\n\n        if (isRegex) {\n            if (search.global)\n                search.lastIndex = 0; // Fix IE, Safari bug (last tested IE 9.0.5, Safari 5.1.2 on Windows)\n            else\n                search.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows)\n        }\n\n        return result;\n    };\n\n    // A consistent cross-browser, ES3 compliant `split`\n    String.prototype.split = function (s /* separator */, limit) {\n        // If separator `s` is not a regex, use the native `split`\n        if (!XRegExp.isRegExp(s))\n            return nativ.split.apply(this, arguments);\n\n        var str = this + \"\", // Type conversion\n            output = [],\n            lastLastIndex = 0,\n            match, lastLength;\n\n        // Behavior for `limit`: if it's...\n        // - `undefined`: No limit\n        // - `NaN` or zero: Return an empty array\n        // - A positive number: Use `Math.floor(limit)`\n        // - A negative number: No limit\n        // - Other: Type-convert, then use the above rules\n        if (limit === undefined || +limit < 0) {\n            limit = Infinity;\n        } else {\n            limit = Math.floor(+limit);\n            if (!limit)\n                return [];\n        }\n\n        // This is required if not `s.global`, and it avoids needing to set `s.lastIndex` to zero\n        // and restore it to its original value when we're done using the regex\n        s = XRegExp.copyAsGlobal(s);\n\n        while (match = s.exec(str)) { // Run the altered `exec` (required for `lastIndex` fix, etc.)\n            if (s.lastIndex > lastLastIndex) {\n                output.push(str.slice(lastLastIndex, match.index));\n\n                if (match.length > 1 && match.index < str.length)\n                    Array.prototype.push.apply(output, match.slice(1));\n\n                lastLength = match[0].length;\n                lastLastIndex = s.lastIndex;\n\n                if (output.length >= limit)\n                    break;\n            }\n\n            if (s.lastIndex === match.index)\n                s.lastIndex++;\n        }\n\n        if (lastLastIndex === str.length) {\n            if (!nativ.test.call(s, \"\") || lastLength)\n                output.push(\"\");\n        } else {\n            output.push(str.slice(lastLastIndex));\n        }\n\n        return output.length > limit ? output.slice(0, limit) : output;\n    };\n\n\n    //---------------------------------\n    //  Private helper functions\n    //---------------------------------\n\n    // Supporting function for `XRegExp`, `XRegExp.copyAsGlobal`, etc. Returns a copy of a `RegExp`\n    // instance with a fresh `lastIndex` (set to zero), preserving properties required for named\n    // capture. Also allows adding new flags in the process of copying the regex\n    function clone (regex, additionalFlags) {\n        if (!XRegExp.isRegExp(regex))\n            throw TypeError(\"type RegExp expected\");\n        var x = regex._xregexp;\n        regex = XRegExp(regex.source, getNativeFlags(regex) + (additionalFlags || \"\"));\n        if (x) {\n            regex._xregexp = {\n                source: x.source,\n                captureNames: x.captureNames ? x.captureNames.slice(0) : null\n            };\n        }\n        return regex;\n    }\n\n    function getNativeFlags (regex) {\n        return (regex.global     ? \"g\" : \"\") +\n            (regex.ignoreCase ? \"i\" : \"\") +\n            (regex.multiline  ? \"m\" : \"\") +\n            (regex.extended   ? \"x\" : \"\") + // Proposed for ES4; included in AS3\n            (regex.sticky     ? \"y\" : \"\");\n    }\n\n    function runTokens (pattern, index, scope, context) {\n        var i = tokens.length,\n            result, match, t;\n        // Protect against constructing XRegExps within token handler and trigger functions\n        isInsideConstructor = true;\n        // Must reset `isInsideConstructor`, even if a `trigger` or `handler` throws\n        try {\n            while (i--) { // Run in reverse order\n                t = tokens[i];\n                if ((scope & t.scope) && (!t.trigger || t.trigger.call(context))) {\n                    t.pattern.lastIndex = index;\n                    match = t.pattern.exec(pattern); // Running the altered `exec` here allows use of named backreferences, etc.\n                    if (match && match.index === index) {\n                        result = {\n                            output: t.handler.call(context, match, scope),\n                            match: match\n                        };\n                        break;\n                    }\n                }\n            }\n        } catch (err) {\n            throw err;\n        } finally {\n            isInsideConstructor = false;\n        }\n        return result;\n    }\n\n    function indexOf (array, item, from) {\n        if (Array.prototype.indexOf) // Use the native array method if available\n            return array.indexOf(item, from);\n        for (var i = from || 0; i < array.length; i++) {\n            if (array[i] === item)\n                return i;\n        }\n        return -1;\n    }\n\n\n    //---------------------------------\n    //  Built-in tokens\n    //---------------------------------\n\n    // Augment XRegExp's regular expression syntax and flags. Note that when adding tokens, the\n    // third (`scope`) argument defaults to `XRegExp.OUTSIDE_CLASS`\n\n    // Comment pattern: (?# )\n    XRegExp.addToken(\n        /\\(\\?#[^)]*\\)/,\n        function (match) {\n            // Keep tokens separated unless the following token is a quantifier\n            return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? \"\" : \"(?:)\";\n        }\n    );\n\n    // Capturing group (match the opening parenthesis only).\n    // Required for support of named capturing groups\n    XRegExp.addToken(\n        /\\((?!\\?)/,\n        function () {\n            this.captureNames.push(null);\n            return \"(\";\n        }\n    );\n\n    // Named capturing group (match the opening delimiter only): (?<name>\n    XRegExp.addToken(\n        /\\(\\?<([$\\w]+)>/,\n        function (match) {\n            this.captureNames.push(match[1]);\n            this.hasNamedCapture = true;\n            return \"(\";\n        }\n    );\n\n    // Named backreference: \\k<name>\n    XRegExp.addToken(\n        /\\\\k<([\\w$]+)>/,\n        function (match) {\n            var index = indexOf(this.captureNames, match[1]);\n            // Keep backreferences separate from subsequent literal numbers. Preserve back-\n            // references to named groups that are undefined at this point as literal strings\n            return index > -1 ?\n                \"\\\\\" + (index + 1) + (isNaN(match.input.charAt(match.index + match[0].length)) ? \"\" : \"(?:)\") :\n                match[0];\n        }\n    );\n\n    // Empty character class: [] or [^]\n    XRegExp.addToken(\n        /\\[\\^?]/,\n        function (match) {\n            // For cross-browser compatibility with ES3, convert [] to \\b\\B and [^] to [\\s\\S].\n            // (?!) should work like \\b\\B, but is unreliable in Firefox\n            return match[0] === \"[]\" ? \"\\\\b\\\\B\" : \"[\\\\s\\\\S]\";\n        }\n    );\n\n    // Mode modifier at the start of the pattern only, with any combination of flags imsx: (?imsx)\n    // Does not support x(?i), (?-i), (?i-m), (?i: ), (?i)(?m), etc.\n    XRegExp.addToken(\n        /^\\(\\?([imsx]+)\\)/,\n        function (match) {\n            this.setFlag(match[1]);\n            return \"\";\n        }\n    );\n\n    // Whitespace and comments, in free-spacing (aka extended) mode only\n    XRegExp.addToken(\n        /(?:\\s+|#.*)+/,\n        function (match) {\n            // Keep tokens separated unless the following token is a quantifier\n            return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? \"\" : \"(?:)\";\n        },\n        XRegExp.OUTSIDE_CLASS,\n        function () {return this.hasFlag(\"x\");}\n    );\n\n    // Dot, in dotall (aka singleline) mode only\n    XRegExp.addToken(\n        /\\./,\n        function () {return \"[\\\\s\\\\S]\";},\n        XRegExp.OUTSIDE_CLASS,\n        function () {return this.hasFlag(\"s\");}\n    );\n\n\n    //---------------------------------\n    //  Backward compatibility\n    //---------------------------------\n\n    // Uncomment the following block for compatibility with XRegExp 1.0-1.2:\n    /*\n     XRegExp.matchWithinChain = XRegExp.matchChain;\n     RegExp.prototype.addFlags = function (s) {return clone(this, s);};\n     RegExp.prototype.execAll = function (s) {var r = []; XRegExp.iterate(s, this, function (m) {r.push(m);}); return r;};\n     RegExp.prototype.forEachExec = function (s, f, c) {return XRegExp.iterate(s, this, f, c);};\n     RegExp.prototype.validate = function (s) {var r = RegExp(\"^(?:\" + this.source + \")$(?!\\\\s)\", getNativeFlags(this)); if (this.global) this.lastIndex = 0; return s.search(r) === 0;};\n     */\n\n})();\n\n//\n// Begin anonymous function. This is used to contain local scope variables without polutting global scope.\n//\nif (typeof(SyntaxHighlighter) == 'undefined') var SyntaxHighlighter = function() {\n\n// CommonJS\n    if (typeof(require) != 'undefined' && typeof(XRegExp) == 'undefined')\n    {\n        XRegExp = require('XRegExp').XRegExp;\n    }\n\n// Shortcut object which will be assigned to the SyntaxHighlighter variable.\n// This is a shorthand for local reference in order to avoid long namespace\n// references to SyntaxHighlighter.whatever...\n    var sh = {\n        defaults : {\n            /** Additional CSS class names to be added to highlighter elements. */\n            'class-name' : '',\n\n            /** First line number. */\n            'first-line' : 1,\n\n            /**\n             * Pads line numbers. Possible values are:\n             *\n             *   false - don't pad line numbers.\n             *   true  - automaticaly pad numbers with minimum required number of leading zeroes.\n             *   [int] - length up to which pad line numbers.\n             */\n            'pad-line-numbers' : false,\n\n            /** Lines to highlight. */\n            'highlight' : false,\n\n            /** Title to be displayed above the code block. */\n            'title' : null,\n\n            /** Enables or disables smart tabs. */\n            'smart-tabs' : true,\n\n            /** Gets or sets tab size. */\n            'tab-size' : 4,\n\n            /** Enables or disables gutter. */\n            'gutter' : true,\n\n            /** Enables or disables toolbar. */\n            'toolbar' : true,\n\n            /** Enables quick code copy and paste from double click. */\n            'quick-code' : true,\n\n            /** Forces code view to be collapsed. */\n            'collapse' : false,\n\n            /** Enables or disables automatic links. */\n            'auto-links' : false,\n\n            /** Gets or sets light mode. Equavalent to turning off gutter and toolbar. */\n            'light' : false,\n\n            'unindent' : true,\n\n            'html-script' : false\n        },\n\n        config : {\n            space : '&nbsp;',\n\n            /** Enables use of <SCRIPT type=\"syntaxhighlighter\" /> tags. */\n            useScriptTags : true,\n\n            /** Blogger mode flag. */\n            bloggerMode : false,\n\n            stripBrs : false,\n\n            /** Name of the tag that SyntaxHighlighter will automatically look for. */\n            tagName : 'pre',\n\n            strings : {\n                expandSource : 'expand source',\n                help : '?',\n                alert: 'SyntaxHighlighter\\n\\n',\n                noBrush : 'Can\\'t find brush for: ',\n                brushNotHtmlScript : 'Brush wasn\\'t configured for html-script option: ',\n\n                // this is populated by the build script\n                aboutDialog : '@ABOUT@'\n            }\n        },\n\n        /** Internal 'global' variables. */\n        vars : {\n            discoveredBrushes : null,\n            highlighters : {}\n        },\n\n        /** This object is populated by user included external brush files. */\n        brushes : {},\n\n        /** Common regular expressions. */\n        regexLib : {\n            multiLineCComments\t\t\t: /\\/\\*[\\s\\S]*?\\*\\//gm,\n            singleLineCComments\t\t\t: /\\/\\/.*$/gm,\n            singleLinePerlComments\t\t: /#.*$/gm,\n            doubleQuotedString\t\t\t: /\"([^\\\\\"\\n]|\\\\.)*\"/g,\n            singleQuotedString\t\t\t: /'([^\\\\'\\n]|\\\\.)*'/g,\n            multiLineDoubleQuotedString\t: new XRegExp('\"([^\\\\\\\\\"]|\\\\\\\\.)*\"', 'gs'),\n            multiLineSingleQuotedString\t: new XRegExp(\"'([^\\\\\\\\']|\\\\\\\\.)*'\", 'gs'),\n            xmlComments\t\t\t\t\t: /(&lt;|<)!--[\\s\\S]*?--(&gt;|>)/gm,\n            url\t\t\t\t\t\t\t: /\\w+:\\/\\/[\\w-.\\/?%&=:@;#]*/g,\n\n            /** <?= ?> tags. */\n            phpScriptTags \t\t\t\t: { left: /(&lt;|<)\\?(?:=|php)?/g, right: /\\?(&gt;|>)/g, 'eof' : true },\n\n            /** <%= %> tags. */\n            aspScriptTags\t\t\t\t: { left: /(&lt;|<)%=?/g, right: /%(&gt;|>)/g },\n\n            /** <script> tags. */\n            scriptScriptTags\t\t\t: { left: /(&lt;|<)\\s*script.*?(&gt;|>)/gi, right: /(&lt;|<)\\/\\s*script\\s*(&gt;|>)/gi }\n        },\n\n        toolbar: {\n            /**\n             * Generates HTML markup for the toolbar.\n             * @param {Highlighter} highlighter Highlighter instance.\n             * @return {String} Returns HTML markup.\n             */\n            getHtml: function(highlighter)\n            {\n                var html = '<div class=\"toolbar\">',\n                    items = sh.toolbar.items,\n                    list = items.list\n                    ;\n\n                function defaultGetHtml(highlighter, name)\n                {\n                    return sh.toolbar.getButtonHtml(highlighter, name, sh.config.strings[name]);\n                };\n\n                for (var i = 0; i < list.length; i++)\n                    html += (items[list[i]].getHtml || defaultGetHtml)(highlighter, list[i]);\n\n                html += '</div>';\n\n                return html;\n            },\n\n            /**\n             * Generates HTML markup for a regular button in the toolbar.\n             * @param {Highlighter} highlighter Highlighter instance.\n             * @param {String} commandName\t\tCommand name that would be executed.\n             * @param {String} label\t\t\tLabel text to display.\n             * @return {String}\t\t\t\t\tReturns HTML markup.\n             */\n            getButtonHtml: function(highlighter, commandName, label)\n            {\n                return '<span><a href=\"#\" class=\"toolbar_item'\n                    + ' command_' + commandName\n                    + ' ' + commandName\n                    + '\">' + label + '</a></span>'\n                    ;\n            },\n\n            /**\n             * Event handler for a toolbar anchor.\n             */\n            handler: function(e)\n            {\n                var target = e.target,\n                    className = target.className || ''\n                    ;\n\n                function getValue(name)\n                {\n                    var r = new RegExp(name + '_(\\\\w+)'),\n                        match = r.exec(className)\n                        ;\n\n                    return match ? match[1] : null;\n                };\n\n                var highlighter = getHighlighterById(findParentElement(target, '.syntaxhighlighter').id),\n                    commandName = getValue('command')\n                    ;\n\n                // execute the toolbar command\n                if (highlighter && commandName)\n                    sh.toolbar.items[commandName].execute(highlighter);\n\n                // disable default A click behaviour\n                e.preventDefault();\n            },\n\n            /** Collection of toolbar items. */\n            items : {\n                // Ordered lis of items in the toolbar. Can't expect `for (var n in items)` to be consistent.\n                list: ['expandSource', 'help'],\n\n                expandSource: {\n                    getHtml: function(highlighter)\n                    {\n                        if (highlighter.getParam('collapse') != true)\n                            return '';\n\n                        var title = highlighter.getParam('title');\n                        return sh.toolbar.getButtonHtml(highlighter, 'expandSource', title ? title : sh.config.strings.expandSource);\n                    },\n\n                    execute: function(highlighter)\n                    {\n                        var div = getHighlighterDivById(highlighter.id);\n                        removeClass(div, 'collapsed');\n                    }\n                },\n\n                /** Command to display the about dialog window. */\n                help: {\n                    execute: function(highlighter)\n                    {\n                        var wnd = popup('', '_blank', 500, 250, 'scrollbars=0'),\n                            doc = wnd.document\n                            ;\n\n                        doc.write(sh.config.strings.aboutDialog);\n                        doc.close();\n                        wnd.focus();\n                    }\n                }\n            }\n        },\n\n        /**\n         * Finds all elements on the page which should be processes by SyntaxHighlighter.\n         *\n         * @param {Object} globalParams\t\tOptional parameters which override element's\n         * \t\t\t\t\t\t\t\t\tparameters. Only used if element is specified.\n         *\n         * @param {Object} element\tOptional element to highlight. If none is\n         * \t\t\t\t\t\t\tprovided, all elements in the current document\n         * \t\t\t\t\t\t\tare returned which qualify.\n         *\n         * @return {Array}\tReturns list of <code>{ target: DOMElement, params: Object }</code> objects.\n         */\n        findElements: function(globalParams, element)\n        {\n            var elements = element ? [element] : toArray(document.getElementsByTagName(sh.config.tagName)),\n                conf = sh.config,\n                result = []\n                ;\n\n            // support for <SCRIPT TYPE=\"syntaxhighlighter\" /> feature\n            if (conf.useScriptTags)\n                elements = elements.concat(getSyntaxHighlighterScriptTags());\n\n            if (elements.length === 0)\n                return result;\n\n            for (var i = 0; i < elements.length; i++)\n            {\n                var item = {\n                    target: elements[i],\n                    // local params take precedence over globals\n                    params: merge(globalParams, parseParams(elements[i].className))\n                };\n\n                if (item.params['brush'] == null)\n                    continue;\n\n                result.push(item);\n            }\n\n            return result;\n        },\n\n        /**\n         * Shorthand to highlight all elements on the page that are marked as\n         * SyntaxHighlighter source code.\n         *\n         * @param {Object} globalParams\t\tOptional parameters which override element's\n         * \t\t\t\t\t\t\t\t\tparameters. Only used if element is specified.\n         *\n         * @param {Object} element\tOptional element to highlight. If none is\n         * \t\t\t\t\t\t\tprovided, all elements in the current document\n         * \t\t\t\t\t\t\tare highlighted.\n         */\n        highlight: function(globalParams, element)\n        {\n            var elements = this.findElements(globalParams, element),\n                propertyName = 'innerHTML',\n                highlighter = null,\n                conf = sh.config\n                ;\n\n            if (elements.length === 0)\n                return;\n\n            for (var i = 0; i < elements.length; i++)\n            {\n                var element = elements[i],\n                    target = element.target,\n                    params = element.params,\n                    brushName = params.brush,\n                    code\n                    ;\n\n                if (brushName == null)\n                    continue;\n\n                // Instantiate a brush\n                if (params['html-script'] == 'true' || sh.defaults['html-script'] == true)\n                {\n                    highlighter = new sh.HtmlScript(brushName);\n                    brushName = 'htmlscript';\n                }\n                else\n                {\n                    var brush = findBrush(brushName);\n\n                    if (brush)\n                        highlighter = new brush();\n                    else\n                        continue;\n                }\n\n                code = target[propertyName];\n\n                // remove CDATA from <SCRIPT/> tags if it's present\n                if (conf.useScriptTags)\n                    code = stripCData(code);\n\n                // Inject title if the attribute is present\n                if ((target.title || '') != '')\n                    params.title = target.title;\n\n                params['brush'] = brushName;\n                highlighter.init(params);\n                element = highlighter.getDiv(code);\n\n                // carry over ID\n                if ((target.id || '') != '')\n                    element.id = target.id;\n                //by zhanyi 去掉多余的外围div\n                var tmp = element.firstChild.firstChild;\n                tmp.className = element.firstChild.className;\n\n                target.parentNode.replaceChild(tmp, target);\n            }\n        },\n\n        /**\n         * Main entry point for the SyntaxHighlighter.\n         * @param {Object} params Optional params to apply to all highlighted elements.\n         */\n        all: function(params)\n        {\n            attachEvent(\n                window,\n                'load',\n                function() { sh.highlight(params); }\n            );\n        }\n    }; // end of sh\n\n    /**\n     * Checks if target DOM elements has specified CSS class.\n     * @param {DOMElement} target Target DOM element to check.\n     * @param {String} className Name of the CSS class to check for.\n     * @return {Boolean} Returns true if class name is present, false otherwise.\n     */\n    function hasClass(target, className)\n    {\n        return target.className.indexOf(className) != -1;\n    };\n\n    /**\n     * Adds CSS class name to the target DOM element.\n     * @param {DOMElement} target Target DOM element.\n     * @param {String} className New CSS class to add.\n     */\n    function addClass(target, className)\n    {\n        if (!hasClass(target, className))\n            target.className += ' ' + className;\n    };\n\n    /**\n     * Removes CSS class name from the target DOM element.\n     * @param {DOMElement} target Target DOM element.\n     * @param {String} className CSS class to remove.\n     */\n    function removeClass(target, className)\n    {\n        target.className = target.className.replace(className, '');\n    };\n\n    /**\n     * Converts the source to array object. Mostly used for function arguments and\n     * lists returned by getElementsByTagName() which aren't Array objects.\n     * @param {List} source Source list.\n     * @return {Array} Returns array.\n     */\n    function toArray(source)\n    {\n        var result = [];\n\n        for (var i = 0; i < source.length; i++)\n            result.push(source[i]);\n\n        return result;\n    };\n\n    /**\n     * Splits block of text into lines.\n     * @param {String} block Block of text.\n     * @return {Array} Returns array of lines.\n     */\n    function splitLines(block)\n    {\n        return block.split(/\\r?\\n/);\n    }\n\n    /**\n     * Generates HTML ID for the highlighter.\n     * @param {String} highlighterId Highlighter ID.\n     * @return {String} Returns HTML ID.\n     */\n    function getHighlighterId(id)\n    {\n        var prefix = 'highlighter_';\n        return id.indexOf(prefix) == 0 ? id : prefix + id;\n    };\n\n    /**\n     * Finds Highlighter instance by ID.\n     * @param {String} highlighterId Highlighter ID.\n     * @return {Highlighter} Returns instance of the highlighter.\n     */\n    function getHighlighterById(id)\n    {\n        return sh.vars.highlighters[getHighlighterId(id)];\n    };\n\n    /**\n     * Finds highlighter's DIV container.\n     * @param {String} highlighterId Highlighter ID.\n     * @return {Element} Returns highlighter's DIV element.\n     */\n    function getHighlighterDivById(id)\n    {\n        return document.getElementById(getHighlighterId(id));\n    };\n\n    /**\n     * Stores highlighter so that getHighlighterById() can do its thing. Each\n     * highlighter must call this method to preserve itself.\n     * @param {Highilghter} highlighter Highlighter instance.\n     */\n    function storeHighlighter(highlighter)\n    {\n        sh.vars.highlighters[getHighlighterId(highlighter.id)] = highlighter;\n    };\n\n    /**\n     * Looks for a child or parent node which has specified classname.\n     * Equivalent to jQuery's $(container).find(\".className\")\n     * @param {Element} target Target element.\n     * @param {String} search Class name or node name to look for.\n     * @param {Boolean} reverse If set to true, will go up the node tree instead of down.\n     * @return {Element} Returns found child or parent element on null.\n     */\n    function findElement(target, search, reverse /* optional */)\n    {\n        if (target == null)\n            return null;\n\n        var nodes\t\t\t= reverse != true ? target.childNodes : [ target.parentNode ],\n            propertyToFind\t= { '#' : 'id', '.' : 'className' }[search.substr(0, 1)] || 'nodeName',\n            expectedValue,\n            found\n            ;\n\n        expectedValue = propertyToFind != 'nodeName'\n            ? search.substr(1)\n            : search.toUpperCase()\n        ;\n\n        // main return of the found node\n        if ((target[propertyToFind] || '').indexOf(expectedValue) != -1)\n            return target;\n\n        for (var i = 0; nodes && i < nodes.length && found == null; i++)\n            found = findElement(nodes[i], search, reverse);\n\n        return found;\n    };\n\n    /**\n     * Looks for a parent node which has specified classname.\n     * This is an alias to <code>findElement(container, className, true)</code>.\n     * @param {Element} target Target element.\n     * @param {String} className Class name to look for.\n     * @return {Element} Returns found parent element on null.\n     */\n    function findParentElement(target, className)\n    {\n        return findElement(target, className, true);\n    };\n\n    /**\n     * Finds an index of element in the array.\n     * @ignore\n     * @param {Object} searchElement\n     * @param {Number} fromIndex\n     * @return {Number} Returns index of element if found; -1 otherwise.\n     */\n    function indexOf(array, searchElement, fromIndex)\n    {\n        fromIndex = Math.max(fromIndex || 0, 0);\n\n        for (var i = fromIndex; i < array.length; i++)\n            if(array[i] == searchElement)\n                return i;\n\n        return -1;\n    };\n\n    /**\n     * Generates a unique element ID.\n     */\n    function guid(prefix)\n    {\n        return (prefix || '') + Math.round(Math.random() * 1000000).toString();\n    };\n\n    /**\n     * Merges two objects. Values from obj2 override values in obj1.\n     * Function is NOT recursive and works only for one dimensional objects.\n     * @param {Object} obj1 First object.\n     * @param {Object} obj2 Second object.\n     * @return {Object} Returns combination of both objects.\n     */\n    function merge(obj1, obj2)\n    {\n        var result = {}, name;\n\n        for (name in obj1)\n            result[name] = obj1[name];\n\n        for (name in obj2)\n            result[name] = obj2[name];\n\n        return result;\n    };\n\n    /**\n     * Attempts to convert string to boolean.\n     * @param {String} value Input string.\n     * @return {Boolean} Returns true if input was \"true\", false if input was \"false\" and value otherwise.\n     */\n    function toBoolean(value)\n    {\n        var result = { \"true\" : true, \"false\" : false }[value];\n        return result == null ? value : result;\n    };\n\n    /**\n     * Opens up a centered popup window.\n     * @param {String} url\t\tURL to open in the window.\n     * @param {String} name\t\tPopup name.\n     * @param {int} width\t\tPopup width.\n     * @param {int} height\t\tPopup height.\n     * @param {String} options\twindow.open() options.\n     * @return {Window}\t\t\tReturns window instance.\n     */\n    function popup(url, name, width, height, options)\n    {\n        var x = (screen.width - width) / 2,\n            y = (screen.height - height) / 2\n            ;\n\n        options +=\t', left=' + x +\n            ', top=' + y +\n            ', width=' + width +\n            ', height=' + height\n        ;\n        options = options.replace(/^,/, '');\n\n        var win = window.open(url, name, options);\n        win.focus();\n        return win;\n    };\n\n    /**\n     * Adds event handler to the target object.\n     * @param {Object} obj\t\tTarget object.\n     * @param {String} type\t\tName of the event.\n     * @param {Function} func\tHandling function.\n     */\n    function attachEvent(obj, type, func, scope)\n    {\n        function handler(e)\n        {\n            e = e || window.event;\n\n            if (!e.target)\n            {\n                e.target = e.srcElement;\n                e.preventDefault = function()\n                {\n                    this.returnValue = false;\n                };\n            }\n\n            func.call(scope || window, e);\n        };\n\n        if (obj.attachEvent)\n        {\n            obj.attachEvent('on' + type, handler);\n        }\n        else\n        {\n            obj.addEventListener(type, handler, false);\n        }\n    };\n\n    /**\n     * Displays an alert.\n     * @param {String} str String to display.\n     */\n    function alert(str)\n    {\n        window.alert(sh.config.strings.alert + str);\n    };\n\n    /**\n     * Finds a brush by its alias.\n     *\n     * @param {String} alias\t\tBrush alias.\n     * @param {Boolean} showAlert\tSuppresses the alert if false.\n     * @return {Brush}\t\t\t\tReturns bursh constructor if found, null otherwise.\n     */\n    function findBrush(alias, showAlert)\n    {\n        var brushes = sh.vars.discoveredBrushes,\n            result = null\n            ;\n\n        if (brushes == null)\n        {\n            brushes = {};\n\n            // Find all brushes\n            for (var brush in sh.brushes)\n            {\n                var info = sh.brushes[brush],\n                    aliases = info.aliases\n                    ;\n\n                if (aliases == null)\n                    continue;\n\n                // keep the brush name\n                info.brushName = brush.toLowerCase();\n\n                for (var i = 0; i < aliases.length; i++)\n                    brushes[aliases[i]] = brush;\n            }\n\n            sh.vars.discoveredBrushes = brushes;\n        }\n\n        result = sh.brushes[brushes[alias]];\n\n        if (result == null && showAlert)\n            alert(sh.config.strings.noBrush + alias);\n\n        return result;\n    };\n\n    /**\n     * Executes a callback on each line and replaces each line with result from the callback.\n     * @param {Object} str\t\t\tInput string.\n     * @param {Object} callback\t\tCallback function taking one string argument and returning a string.\n     */\n    function eachLine(str, callback)\n    {\n        var lines = splitLines(str);\n\n        for (var i = 0; i < lines.length; i++)\n            lines[i] = callback(lines[i], i);\n\n        // include \\r to enable copy-paste on windows (ie8) without getting everything on one line\n        return lines.join('\\r\\n');\n    };\n\n    /**\n     * This is a special trim which only removes first and last empty lines\n     * and doesn't affect valid leading space on the first line.\n     *\n     * @param {String} str   Input string\n     * @return {String}      Returns string without empty first and last lines.\n     */\n    function trimFirstAndLastLines(str)\n    {\n        return str.replace(/^[ ]*[\\n]+|[\\n]*[ ]*$/g, '');\n    };\n\n    /**\n     * Parses key/value pairs into hash object.\n     *\n     * Understands the following formats:\n     * - name: word;\n     * - name: [word, word];\n     * - name: \"string\";\n     * - name: 'string';\n     *\n     * For example:\n     *   name1: value; name2: [value, value]; name3: 'value'\n     *\n     * @param {String} str    Input string.\n     * @return {Object}       Returns deserialized object.\n     */\n    function parseParams(str)\n    {\n        var match,\n            result = {},\n            arrayRegex = new XRegExp(\"^\\\\[(?<values>(.*?))\\\\]$\"),\n            regex = new XRegExp(\n                \"(?<name>[\\\\w-]+)\" +\n                    \"\\\\s*:\\\\s*\" +\n                    \"(?<value>\" +\n                    \"[\\\\w-%#]+|\" +\t\t// word\n                    \"\\\\[.*?\\\\]|\" +\t\t// [] array\n                    '\".*?\"|' +\t\t\t// \"\" string\n                    \"'.*?'\" +\t\t\t// '' string\n                    \")\\\\s*;?\",\n                \"g\"\n            )\n            ;\n\n        while ((match = regex.exec(str)) != null)\n        {\n            var value = match.value\n                    .replace(/^['\"]|['\"]$/g, '') // strip quotes from end of strings\n                ;\n\n            // try to parse array value\n            if (value != null && arrayRegex.test(value))\n            {\n                var m = arrayRegex.exec(value);\n                value = m.values.length > 0 ? m.values.split(/\\s*,\\s*/) : [];\n            }\n\n            result[match.name] = value;\n        }\n\n        return result;\n    };\n\n    /**\n     * Wraps each line of the string into <code/> tag with given style applied to it.\n     *\n     * @param {String} str   Input string.\n     * @param {String} css   Style name to apply to the string.\n     * @return {String}      Returns input string with each line surrounded by <span/> tag.\n     */\n    function wrapLinesWithCode(str, css)\n    {\n        if (str == null || str.length == 0 || str == '\\n')\n            return str;\n\n        str = str.replace(/</g, '&lt;');\n\n        // Replace two or more sequential spaces with &nbsp; leaving last space untouched.\n        str = str.replace(/ {2,}/g, function(m)\n        {\n            var spaces = '';\n\n            for (var i = 0; i < m.length - 1; i++)\n                spaces += sh.config.space;\n\n            return spaces + ' ';\n        });\n\n        // Split each line and apply <span class=\"...\">...</span> to them so that\n        // leading spaces aren't included.\n        if (css != null)\n            str = eachLine(str, function(line)\n            {\n                if (line.length == 0)\n                    return '';\n\n                var spaces = '';\n\n                line = line.replace(/^(&nbsp;| )+/, function(s)\n                {\n                    spaces = s;\n                    return '';\n                });\n\n                if (line.length == 0)\n                    return spaces;\n\n                return spaces + '<code class=\"' + css + '\">' + line + '</code>';\n            });\n\n        return str;\n    };\n\n    /**\n     * Pads number with zeros until it's length is the same as given length.\n     *\n     * @param {Number} number\tNumber to pad.\n     * @param {Number} length\tMax string length with.\n     * @return {String}\t\t\tReturns a string padded with proper amount of '0'.\n     */\n    function padNumber(number, length)\n    {\n        var result = number.toString();\n\n        while (result.length < length)\n            result = '0' + result;\n\n        return result;\n    };\n\n    /**\n     * Replaces tabs with spaces.\n     *\n     * @param {String} code\t\tSource code.\n     * @param {Number} tabSize\tSize of the tab.\n     * @return {String}\t\t\tReturns code with all tabs replaces by spaces.\n     */\n    function processTabs(code, tabSize)\n    {\n        var tab = '';\n\n        for (var i = 0; i < tabSize; i++)\n            tab += ' ';\n\n        return code.replace(/\\t/g, tab);\n    };\n\n    /**\n     * Replaces tabs with smart spaces.\n     *\n     * @param {String} code    Code to fix the tabs in.\n     * @param {Number} tabSize Number of spaces in a column.\n     * @return {String}        Returns code with all tabs replaces with roper amount of spaces.\n     */\n    function processSmartTabs(code, tabSize)\n    {\n        var lines = splitLines(code),\n            tab = '\\t',\n            spaces = ''\n            ;\n\n        // Create a string with 1000 spaces to copy spaces from...\n        // It's assumed that there would be no indentation longer than that.\n        for (var i = 0; i < 50; i++)\n            spaces += '                    '; // 20 spaces * 50\n\n        // This function inserts specified amount of spaces in the string\n        // where a tab is while removing that given tab.\n        function insertSpaces(line, pos, count)\n        {\n            return line.substr(0, pos)\n                + spaces.substr(0, count)\n                + line.substr(pos + 1, line.length) // pos + 1 will get rid of the tab\n                ;\n        };\n\n        // Go through all the lines and do the 'smart tabs' magic.\n        code = eachLine(code, function(line)\n        {\n            if (line.indexOf(tab) == -1)\n                return line;\n\n            var pos = 0;\n\n            while ((pos = line.indexOf(tab)) != -1)\n            {\n                // This is pretty much all there is to the 'smart tabs' logic.\n                // Based on the position within the line and size of a tab,\n                // calculate the amount of spaces we need to insert.\n                var spaces = tabSize - pos % tabSize;\n                line = insertSpaces(line, pos, spaces);\n            }\n\n            return line;\n        });\n\n        return code;\n    };\n\n    /**\n     * Performs various string fixes based on configuration.\n     */\n    function fixInputString(str)\n    {\n        var br = /<br\\s*\\/?>|&lt;br\\s*\\/?&gt;/gi;\n\n        if (sh.config.bloggerMode == true)\n            str = str.replace(br, '\\n');\n\n        if (sh.config.stripBrs == true)\n            str = str.replace(br, '');\n\n        return str;\n    };\n\n    /**\n     * Removes all white space at the begining and end of a string.\n     *\n     * @param {String} str   String to trim.\n     * @return {String}      Returns string without leading and following white space characters.\n     */\n    function trim(str)\n    {\n        return str.replace(/^\\s+|\\s+$/g, '');\n    };\n\n    /**\n     * Unindents a block of text by the lowest common indent amount.\n     * @param {String} str   Text to unindent.\n     * @return {String}      Returns unindented text block.\n     */\n    function unindent(str)\n    {\n        var lines = splitLines(fixInputString(str)),\n            indents = new Array(),\n            regex = /^\\s*/,\n            min = 1000\n            ;\n\n        // go through every line and check for common number of indents\n        for (var i = 0; i < lines.length && min > 0; i++)\n        {\n            var line = lines[i];\n\n            if (trim(line).length == 0)\n                continue;\n\n            var matches = regex.exec(line);\n\n            // In the event that just one line doesn't have leading white space\n            // we can't unindent anything, so bail completely.\n            if (matches == null)\n                return str;\n\n            min = Math.min(matches[0].length, min);\n        }\n\n        // trim minimum common number of white space from the begining of every line\n        if (min > 0)\n            for (var i = 0; i < lines.length; i++)\n                lines[i] = lines[i].substr(min);\n\n        return lines.join('\\n');\n    };\n\n    /**\n     * Callback method for Array.sort() which sorts matches by\n     * index position and then by length.\n     *\n     * @param {Match} m1\tLeft object.\n     * @param {Match} m2    Right object.\n     * @return {Number}     Returns -1, 0 or -1 as a comparison result.\n     */\n    function matchesSortCallback(m1, m2)\n    {\n        // sort matches by index first\n        if(m1.index < m2.index)\n            return -1;\n        else if(m1.index > m2.index)\n            return 1;\n        else\n        {\n            // if index is the same, sort by length\n            if(m1.length < m2.length)\n                return -1;\n            else if(m1.length > m2.length)\n                return 1;\n        }\n\n        return 0;\n    };\n\n    /**\n     * Executes given regular expression on provided code and returns all\n     * matches that are found.\n     *\n     * @param {String} code    Code to execute regular expression on.\n     * @param {Object} regex   Regular expression item info from <code>regexList</code> collection.\n     * @return {Array}         Returns a list of Match objects.\n     */\n    function getMatches(code, regexInfo)\n    {\n        function defaultAdd(match, regexInfo)\n        {\n            return match[0];\n        };\n\n        var index = 0,\n            match = null,\n            matches = [],\n            func = regexInfo.func ? regexInfo.func : defaultAdd\n            ;\n\n        while((match = regexInfo.regex.exec(code)) != null)\n        {\n            var resultMatch = func(match, regexInfo);\n\n            if (typeof(resultMatch) == 'string')\n                resultMatch = [new sh.Match(resultMatch, match.index, regexInfo.css)];\n\n            matches = matches.concat(resultMatch);\n        }\n\n        return matches;\n    };\n\n    /**\n     * Turns all URLs in the code into <a/> tags.\n     * @param {String} code Input code.\n     * @return {String} Returns code with </a> tags.\n     */\n    function processUrls(code)\n    {\n        var gt = /(.*)((&gt;|&lt;).*)/;\n\n        return code.replace(sh.regexLib.url, function(m)\n        {\n            var suffix = '',\n                match = null\n                ;\n\n            // We include &lt; and &gt; in the URL for the common cases like <http://google.com>\n            // The problem is that they get transformed into &lt;http://google.com&gt;\n            // Where as &gt; easily looks like part of the URL string.\n\n            if (match = gt.exec(m))\n            {\n                m = match[1];\n                suffix = match[2];\n            }\n\n            return '<a href=\"' + m + '\">' + m + '</a>' + suffix;\n        });\n    };\n\n    /**\n     * Finds all <SCRIPT TYPE=\"syntaxhighlighter\" /> elementss.\n     * @return {Array} Returns array of all found SyntaxHighlighter tags.\n     */\n    function getSyntaxHighlighterScriptTags()\n    {\n        var tags = document.getElementsByTagName('script'),\n            result = []\n            ;\n\n        for (var i = 0; i < tags.length; i++)\n            if (tags[i].type == 'syntaxhighlighter')\n                result.push(tags[i]);\n\n        return result;\n    };\n\n    /**\n     * Strips <![CDATA[]]> from <SCRIPT /> content because it should be used\n     * there in most cases for XHTML compliance.\n     * @param {String} original\tInput code.\n     * @return {String} Returns code without leading <![CDATA[]]> tags.\n     */\n    function stripCData(original)\n    {\n        var left = '<![CDATA[',\n            right = ']]>',\n        // for some reason IE inserts some leading blanks here\n            copy = trim(original),\n            changed = false,\n            leftLength = left.length,\n            rightLength = right.length\n            ;\n\n        if (copy.indexOf(left) == 0)\n        {\n            copy = copy.substring(leftLength);\n            changed = true;\n        }\n\n        var copyLength = copy.length;\n\n        if (copy.indexOf(right) == copyLength - rightLength)\n        {\n            copy = copy.substring(0, copyLength - rightLength);\n            changed = true;\n        }\n\n        return changed ? copy : original;\n    };\n\n\n    /**\n     * Quick code mouse double click handler.\n     */\n    function quickCodeHandler(e)\n    {\n        var target = e.target,\n            highlighterDiv = findParentElement(target, '.syntaxhighlighter'),\n            container = findParentElement(target, '.container'),\n            textarea = document.createElement('textarea'),\n            highlighter\n            ;\n\n        if (!container || !highlighterDiv || findElement(container, 'textarea'))\n            return;\n\n        highlighter = getHighlighterById(highlighterDiv.id);\n\n        // add source class name\n        addClass(highlighterDiv, 'source');\n\n        // Have to go over each line and grab it's text, can't just do it on the\n        // container because Firefox loses all \\n where as Webkit doesn't.\n        var lines = container.childNodes,\n            code = []\n            ;\n\n        for (var i = 0; i < lines.length; i++)\n            code.push(lines[i].innerText || lines[i].textContent);\n\n        // using \\r instead of \\r or \\r\\n makes this work equally well on IE, FF and Webkit\n        code = code.join('\\r');\n\n        // For Webkit browsers, replace nbsp with a breaking space\n        code = code.replace(/\\u00a0/g, \" \");\n\n        // inject <textarea/> tag\n        textarea.appendChild(document.createTextNode(code));\n        container.appendChild(textarea);\n\n        // preselect all text\n        textarea.focus();\n        textarea.select();\n\n        // set up handler for lost focus\n        attachEvent(textarea, 'blur', function(e)\n        {\n            textarea.parentNode.removeChild(textarea);\n            removeClass(highlighterDiv, 'source');\n        });\n    };\n\n    /**\n     * Match object.\n     */\n    sh.Match = function(value, index, css)\n    {\n        this.value = value;\n        this.index = index;\n        this.length = value.length;\n        this.css = css;\n        this.brushName = null;\n    };\n\n    sh.Match.prototype.toString = function()\n    {\n        return this.value;\n    };\n\n    /**\n     * Simulates HTML code with a scripting language embedded.\n     *\n     * @param {String} scriptBrushName Brush name of the scripting language.\n     */\n    sh.HtmlScript = function(scriptBrushName)\n    {\n        var brushClass = findBrush(scriptBrushName),\n            scriptBrush,\n            xmlBrush = new sh.brushes.Xml(),\n            bracketsRegex = null,\n            ref = this,\n            methodsToExpose = 'getDiv getHtml init'.split(' ')\n            ;\n\n        if (brushClass == null)\n            return;\n\n        scriptBrush = new brushClass();\n\n        for(var i = 0; i < methodsToExpose.length; i++)\n            // make a closure so we don't lose the name after i changes\n            (function() {\n                var name = methodsToExpose[i];\n\n                ref[name] = function()\n                {\n                    return xmlBrush[name].apply(xmlBrush, arguments);\n                };\n            })();\n\n        if (scriptBrush.htmlScript == null)\n        {\n            alert(sh.config.strings.brushNotHtmlScript + scriptBrushName);\n            return;\n        }\n\n        xmlBrush.regexList.push(\n            { regex: scriptBrush.htmlScript.code, func: process }\n        );\n\n        function offsetMatches(matches, offset)\n        {\n            for (var j = 0; j < matches.length; j++)\n                matches[j].index += offset;\n        }\n\n        function process(match, info)\n        {\n            var code = match.code,\n                matches = [],\n                regexList = scriptBrush.regexList,\n                offset = match.index + match.left.length,\n                htmlScript = scriptBrush.htmlScript,\n                result\n                ;\n\n            // add all matches from the code\n            for (var i = 0; i < regexList.length; i++)\n            {\n                result = getMatches(code, regexList[i]);\n                offsetMatches(result, offset);\n                matches = matches.concat(result);\n            }\n\n            // add left script bracket\n            if (htmlScript.left != null && match.left != null)\n            {\n                result = getMatches(match.left, htmlScript.left);\n                offsetMatches(result, match.index);\n                matches = matches.concat(result);\n            }\n\n            // add right script bracket\n            if (htmlScript.right != null && match.right != null)\n            {\n                result = getMatches(match.right, htmlScript.right);\n                offsetMatches(result, match.index + match[0].lastIndexOf(match.right));\n                matches = matches.concat(result);\n            }\n\n            for (var j = 0; j < matches.length; j++)\n                matches[j].brushName = brushClass.brushName;\n\n            return matches;\n        }\n    };\n\n    /**\n     * Main Highlither class.\n     * @constructor\n     */\n    sh.Highlighter = function()\n    {\n        // not putting any code in here because of the prototype inheritance\n    };\n\n    sh.Highlighter.prototype = {\n        /**\n         * Returns value of the parameter passed to the highlighter.\n         * @param {String} name\t\t\t\tName of the parameter.\n         * @param {Object} defaultValue\t\tDefault value.\n         * @return {Object}\t\t\t\t\tReturns found value or default value otherwise.\n         */\n        getParam: function(name, defaultValue)\n        {\n            var result = this.params[name];\n            return toBoolean(result == null ? defaultValue : result);\n        },\n\n        /**\n         * Shortcut to document.createElement().\n         * @param {String} name\t\tName of the element to create (DIV, A, etc).\n         * @return {HTMLElement}\tReturns new HTML element.\n         */\n        create: function(name)\n        {\n            return document.createElement(name);\n        },\n\n        /**\n         * Applies all regular expression to the code and stores all found\n         * matches in the `this.matches` array.\n         * @param {Array} regexList\t\tList of regular expressions.\n         * @param {String} code\t\t\tSource code.\n         * @return {Array}\t\t\t\tReturns list of matches.\n         */\n        findMatches: function(regexList, code)\n        {\n            var result = [];\n\n            if (regexList != null)\n                for (var i = 0; i < regexList.length; i++)\n                    // BUG: length returns len+1 for array if methods added to prototype chain (oising@gmail.com)\n                    if (typeof (regexList[i]) == \"object\")\n                        result = result.concat(getMatches(code, regexList[i]));\n\n            // sort and remove nested the matches\n            return this.removeNestedMatches(result.sort(matchesSortCallback));\n        },\n\n        /**\n         * Checks to see if any of the matches are inside of other matches.\n         * This process would get rid of highligted strings inside comments,\n         * keywords inside strings and so on.\n         */\n        removeNestedMatches: function(matches)\n        {\n            // Optimized by Jose Prado (http://joseprado.com)\n            for (var i = 0; i < matches.length; i++)\n            {\n                if (matches[i] === null)\n                    continue;\n\n                var itemI = matches[i],\n                    itemIEndPos = itemI.index + itemI.length\n                    ;\n\n                for (var j = i + 1; j < matches.length && matches[i] !== null; j++)\n                {\n                    var itemJ = matches[j];\n\n                    if (itemJ === null)\n                        continue;\n                    else if (itemJ.index > itemIEndPos)\n                        break;\n                    else if (itemJ.index == itemI.index && itemJ.length > itemI.length)\n                        matches[i] = null;\n                    else if (itemJ.index >= itemI.index && itemJ.index < itemIEndPos)\n                        matches[j] = null;\n                }\n            }\n\n            return matches;\n        },\n\n        /**\n         * Creates an array containing integer line numbers starting from the 'first-line' param.\n         * @return {Array} Returns array of integers.\n         */\n        figureOutLineNumbers: function(code)\n        {\n            var lines = [],\n                firstLine = parseInt(this.getParam('first-line'))\n                ;\n\n            eachLine(code, function(line, index)\n            {\n                lines.push(index + firstLine);\n            });\n\n            return lines;\n        },\n\n        /**\n         * Determines if specified line number is in the highlighted list.\n         */\n        isLineHighlighted: function(lineNumber)\n        {\n            var list = this.getParam('highlight', []);\n\n            if (typeof(list) != 'object' && list.push == null)\n                list = [ list ];\n\n            return indexOf(list, lineNumber.toString()) != -1;\n        },\n\n        /**\n         * Generates HTML markup for a single line of code while determining alternating line style.\n         * @param {Integer} lineNumber\tLine number.\n         * @param {String} code Line\tHTML markup.\n         * @return {String}\t\t\t\tReturns HTML markup.\n         */\n        getLineHtml: function(lineIndex, lineNumber, code)\n        {\n            var classes = [\n                'line',\n                'number' + lineNumber,\n                'index' + lineIndex,\n                'alt' + (lineNumber % 2 == 0 ? 1 : 2).toString()\n            ];\n\n            if (this.isLineHighlighted(lineNumber))\n                classes.push('highlighted');\n\n            if (lineNumber == 0)\n                classes.push('break');\n\n            return '<div class=\"' + classes.join(' ') + '\">' + code + '</div>';\n        },\n\n        /**\n         * Generates HTML markup for line number column.\n         * @param {String} code\t\t\tComplete code HTML markup.\n         * @param {Array} lineNumbers\tCalculated line numbers.\n         * @return {String}\t\t\t\tReturns HTML markup.\n         */\n        getLineNumbersHtml: function(code, lineNumbers)\n        {\n            var html = '',\n                count = splitLines(code).length,\n                firstLine = parseInt(this.getParam('first-line')),\n                pad = this.getParam('pad-line-numbers')\n                ;\n\n            if (pad == true)\n                pad = (firstLine + count - 1).toString().length;\n            else if (isNaN(pad) == true)\n                pad = 0;\n\n            for (var i = 0; i < count; i++)\n            {\n                var lineNumber = lineNumbers ? lineNumbers[i] : firstLine + i,\n                    code = lineNumber == 0 ? sh.config.space : padNumber(lineNumber, pad)\n                    ;\n\n                html += this.getLineHtml(i, lineNumber, code);\n            }\n\n            return html;\n        },\n\n        /**\n         * Splits block of text into individual DIV lines.\n         * @param {String} code\t\t\tCode to highlight.\n         * @param {Array} lineNumbers\tCalculated line numbers.\n         * @return {String}\t\t\t\tReturns highlighted code in HTML form.\n         */\n        getCodeLinesHtml: function(html, lineNumbers)\n        {\n            html = trim(html);\n\n            var lines = splitLines(html),\n                padLength = this.getParam('pad-line-numbers'),\n                firstLine = parseInt(this.getParam('first-line')),\n                html = '',\n                brushName = this.getParam('brush')\n                ;\n\n            for (var i = 0; i < lines.length; i++)\n            {\n                var line = lines[i],\n                    indent = /^(&nbsp;|\\s)+/.exec(line),\n                    spaces = null,\n                    lineNumber = lineNumbers ? lineNumbers[i] : firstLine + i;\n                ;\n\n                if (indent != null)\n                {\n                    spaces = indent[0].toString();\n                    line = line.substr(spaces.length);\n                    spaces = spaces.replace(' ', sh.config.space);\n                }\n\n                line = trim(line);\n\n                if (line.length == 0)\n                    line = sh.config.space;\n\n                html += this.getLineHtml(\n                    i,\n                    lineNumber,\n                    (spaces != null ? '<code class=\"' + brushName + ' spaces\">' + spaces + '</code>' : '') + line\n                );\n            }\n\n            return html;\n        },\n\n        /**\n         * Returns HTML for the table title or empty string if title is null.\n         */\n        getTitleHtml: function(title)\n        {\n            return title ? '<caption>' + title + '</caption>' : '';\n        },\n\n        /**\n         * Finds all matches in the source code.\n         * @param {String} code\t\tSource code to process matches in.\n         * @param {Array} matches\tDiscovered regex matches.\n         * @return {String} Returns formatted HTML with processed mathes.\n         */\n        getMatchesHtml: function(code, matches)\n        {\n            var pos = 0,\n                result = '',\n                brushName = this.getParam('brush', '')\n                ;\n\n            function getBrushNameCss(match)\n            {\n                var result = match ? (match.brushName || brushName) : brushName;\n                return result ? result + ' ' : '';\n            };\n\n            // Finally, go through the final list of matches and pull the all\n            // together adding everything in between that isn't a match.\n            for (var i = 0; i < matches.length; i++)\n            {\n                var match = matches[i],\n                    matchBrushName\n                    ;\n\n                if (match === null || match.length === 0)\n                    continue;\n\n                matchBrushName = getBrushNameCss(match);\n\n                result += wrapLinesWithCode(code.substr(pos, match.index - pos), matchBrushName + 'plain')\n                    + wrapLinesWithCode(match.value, matchBrushName + match.css)\n                ;\n\n                pos = match.index + match.length + (match.offset || 0);\n            }\n\n            // don't forget to add whatever's remaining in the string\n            result += wrapLinesWithCode(code.substr(pos), getBrushNameCss() + 'plain');\n\n            return result;\n        },\n\n        /**\n         * Generates HTML markup for the whole syntax highlighter.\n         * @param {String} code Source code.\n         * @return {String} Returns HTML markup.\n         */\n        getHtml: function(code)\n        {\n            var html = '',\n                classes = [ 'syntaxhighlighter' ],\n                tabSize,\n                matches,\n                lineNumbers\n                ;\n\n            // process light mode\n            if (this.getParam('light') == true)\n                this.params.toolbar = this.params.gutter = false;\n\n            className = 'syntaxhighlighter';\n\n            if (this.getParam('collapse') == true)\n                classes.push('collapsed');\n\n            if ((gutter = this.getParam('gutter')) == false)\n                classes.push('nogutter');\n\n            // add custom user style name\n            classes.push(this.getParam('class-name'));\n\n            // add brush alias to the class name for custom CSS\n            classes.push(this.getParam('brush'));\n\n            code = trimFirstAndLastLines(code)\n                .replace(/\\r/g, ' ') // IE lets these buggers through\n            ;\n\n            tabSize = this.getParam('tab-size');\n\n            // replace tabs with spaces\n            code = this.getParam('smart-tabs') == true\n                ? processSmartTabs(code, tabSize)\n                : processTabs(code, tabSize)\n            ;\n\n            // unindent code by the common indentation\n            if (this.getParam('unindent'))\n                code = unindent(code);\n\n            if (gutter)\n                lineNumbers = this.figureOutLineNumbers(code);\n\n            // find matches in the code using brushes regex list\n            matches = this.findMatches(this.regexList, code);\n            // processes found matches into the html\n            html = this.getMatchesHtml(code, matches);\n            // finally, split all lines so that they wrap well\n            html = this.getCodeLinesHtml(html, lineNumbers);\n\n            // finally, process the links\n            if (this.getParam('auto-links'))\n                html = processUrls(html);\n\n            if (typeof(navigator) != 'undefined' && navigator.userAgent && navigator.userAgent.match(/MSIE/))\n                classes.push('ie');\n\n            html =\n                '<div id=\"' + getHighlighterId(this.id) + '\" class=\"' + classes.join(' ') + '\">'\n                    + (this.getParam('toolbar') ? sh.toolbar.getHtml(this) : '')\n                    + '<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">'\n                    + this.getTitleHtml(this.getParam('title'))\n                    + '<tbody>'\n                    + '<tr>'\n                    + (gutter ? '<td class=\"gutter\">' + this.getLineNumbersHtml(code) + '</td>' : '')\n                    + '<td class=\"code\">'\n                    + '<div class=\"container\">'\n                    + html\n                    + '</div>'\n                    + '</td>'\n                    + '</tr>'\n                    + '</tbody>'\n                    + '</table>'\n                    + '</div>'\n            ;\n\n            return html;\n        },\n\n        /**\n         * Highlights the code and returns complete HTML.\n         * @param {String} code     Code to highlight.\n         * @return {Element}        Returns container DIV element with all markup.\n         */\n        getDiv: function(code)\n        {\n            if (code === null)\n                code = '';\n\n            this.code = code;\n\n            var div = this.create('div');\n\n            // create main HTML\n            div.innerHTML = this.getHtml(code);\n\n            // set up click handlers\n            if (this.getParam('toolbar'))\n                attachEvent(findElement(div, '.toolbar'), 'click', sh.toolbar.handler);\n\n            if (this.getParam('quick-code'))\n                attachEvent(findElement(div, '.code'), 'dblclick', quickCodeHandler);\n\n            return div;\n        },\n\n        /**\n         * Initializes the highlighter/brush.\n         *\n         * Constructor isn't used for initialization so that nothing executes during necessary\n         * `new SyntaxHighlighter.Highlighter()` call when setting up brush inheritence.\n         *\n         * @param {Hash} params Highlighter parameters.\n         */\n        init: function(params)\n        {\n            this.id = guid();\n\n            // register this instance in the highlighters list\n            storeHighlighter(this);\n\n            // local params take precedence over defaults\n            this.params = merge(sh.defaults, params || {})\n\n            // process light mode\n            if (this.getParam('light') == true)\n                this.params.toolbar = this.params.gutter = false;\n        },\n\n        /**\n         * Converts space separated list of keywords into a regular expression string.\n         * @param {String} str    Space separated keywords.\n         * @return {String}       Returns regular expression string.\n         */\n        getKeywords: function(str)\n        {\n            str = str\n                .replace(/^\\s+|\\s+$/g, '')\n                .replace(/\\s+/g, '|')\n            ;\n\n            return '\\\\b(?:' + str + ')\\\\b';\n        },\n\n        /**\n         * Makes a brush compatible with the `html-script` functionality.\n         * @param {Object} regexGroup Object containing `left` and `right` regular expressions.\n         */\n        forHtmlScript: function(regexGroup)\n        {\n            var regex = { 'end' : regexGroup.right.source };\n\n            if(regexGroup.eof)\n                regex.end = \"(?:(?:\" + regex.end + \")|$)\";\n\n            this.htmlScript = {\n                left : { regex: regexGroup.left, css: 'script' },\n                right : { regex: regexGroup.right, css: 'script' },\n                code : new XRegExp(\n                    \"(?<left>\" + regexGroup.left.source + \")\" +\n                        \"(?<code>.*?)\" +\n                        \"(?<right>\" + regex.end + \")\",\n                    \"sgi\"\n                )\n            };\n        }\n    }; // end of Highlighter\n\n    return sh;\n}(); // end of anonymous function\n\n// CommonJS\ntypeof(exports) != 'undefined' ? exports.SyntaxHighlighter = SyntaxHighlighter : null;\n\n;(function()\n{\n    // CommonJS\n    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n    function Brush()\n    {\n        // Created by Peter Atoria @ http://iAtoria.com\n\n        var inits \t =  'class interface function package';\n\n        var keywords =\t'-Infinity ...rest Array as AS3 Boolean break case catch const continue Date decodeURI ' +\n                'decodeURIComponent default delete do dynamic each else encodeURI encodeURIComponent escape ' +\n                'extends false final finally flash_proxy for get if implements import in include Infinity ' +\n                'instanceof int internal is isFinite isNaN isXMLName label namespace NaN native new null ' +\n                'Null Number Object object_proxy override parseFloat parseInt private protected public ' +\n                'return set static String super switch this throw true try typeof uint undefined unescape ' +\n                'use void while with'\n            ;\n\n        this.regexList = [\n            { regex: SyntaxHighlighter.regexLib.singleLineCComments,\tcss: 'comments' },\t\t// one line comments\n            { regex: SyntaxHighlighter.regexLib.multiLineCComments,\t\tcss: 'comments' },\t\t// multiline comments\n            { regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\tcss: 'string' },\t\t// double quoted strings\n            { regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\tcss: 'string' },\t\t// single quoted strings\n            { regex: /\\b([\\d]+(\\.[\\d]+)?|0x[a-f0-9]+)\\b/gi,\t\t\t\tcss: 'value' },\t\t\t// numbers\n            { regex: new RegExp(this.getKeywords(inits), 'gm'),\t\t\tcss: 'color3' },\t\t// initializations\n            { regex: new RegExp(this.getKeywords(keywords), 'gm'),\t\tcss: 'keyword' },\t\t// keywords\n            { regex: new RegExp('var', 'gm'),\t\t\t\t\t\t\tcss: 'variable' },\t\t// variable\n            { regex: new RegExp('trace', 'gm'),\t\t\t\t\t\t\tcss: 'color1' }\t\t\t// trace\n        ];\n\n        this.forHtmlScript(SyntaxHighlighter.regexLib.scriptScriptTags);\n    };\n\n    Brush.prototype\t= new SyntaxHighlighter.Highlighter();\n    Brush.aliases\t= ['actionscript3', 'as3'];\n\n    SyntaxHighlighter.brushes.AS3 = Brush;\n\n    // CommonJS\n    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n\n;(function()\n{\n    // CommonJS\n    SyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n    function Brush()\n    {\n        // AppleScript brush by David Chambers\n        // http://davidchambersdesign.com/\n        var keywords   = 'after before beginning continue copy each end every from return get global in local named of set some that the then times to where whose with without';\n        var ordinals   = 'first second third fourth fifth sixth seventh eighth ninth tenth last front back middle';\n        var specials   = 'activate add alias AppleScript ask attachment boolean class constant delete duplicate empty exists false id integer list make message modal modified new no paragraph pi properties quit real record remove rest result reveal reverse run running save string true word yes';\n\n        this.regexList = [\n\n            { regex: /(--|#).*$/gm,\n                css: 'comments' },\n\n            { regex: /\\(\\*(?:[\\s\\S]*?\\(\\*[\\s\\S]*?\\*\\))*[\\s\\S]*?\\*\\)/gm, // support nested comments\n                css: 'comments' },\n\n            { regex: /\"[\\s\\S]*?\"/gm,\n                css: 'string' },\n\n            { regex: /(?:,|:|¬|'s\\b|\\(|\\)|\\{|\\}|«|\\b\\w*»)/g,\n                css: 'color1' },\n\n            { regex: /(-)?(\\d)+(\\.(\\d)?)?(E\\+(\\d)+)?/g, // numbers\n                css: 'color1' },\n\n            { regex: /(?:&(amp;|gt;|lt;)?|=|� |>|<|≥|>=|≤|<=|\\*|\\+|-|\\/|÷|\\^)/g,\n                css: 'color2' },\n\n            { regex: /\\b(?:and|as|div|mod|not|or|return(?!\\s&)(ing)?|equals|(is(n't| not)? )?equal( to)?|does(n't| not) equal|(is(n't| not)? )?(greater|less) than( or equal( to)?)?|(comes|does(n't| not) come) (after|before)|is(n't| not)?( in)? (back|front) of|is(n't| not)? behind|is(n't| not)?( (in|contained by))?|does(n't| not) contain|contain(s)?|(start|begin|end)(s)? with|((but|end) )?(consider|ignor)ing|prop(erty)?|(a )?ref(erence)?( to)?|repeat (until|while|with)|((end|exit) )?repeat|((else|end) )?if|else|(end )?(script|tell|try)|(on )?error|(put )?into|(of )?(it|me)|its|my|with (timeout( of)?|transaction)|end (timeout|transaction))\\b/g,\n                css: 'keyword' },\n\n            { regex: /\\b\\d+(st|nd|rd|th)\\b/g, // ordinals\n                css: 'keyword' },\n\n            { regex: /\\b(?:about|above|against|around|at|below|beneath|beside|between|by|(apart|aside) from|(instead|out) of|into|on(to)?|over|since|thr(ough|u)|under)\\b/g,\n                css: 'color3' },\n\n            { regex: /\\b(?:adding folder items to|after receiving|choose( ((remote )?application|color|folder|from list|URL))?|clipboard info|set the clipboard to|(the )?clipboard|entire contents|display(ing| (alert|dialog|mode))?|document( (edited|file|nib name))?|file( (name|type))?|(info )?for|giving up after|(name )?extension|quoted form|return(ed)?|second(?! item)(s)?|list (disks|folder)|text item(s| delimiters)?|(Unicode )?text|(disk )?item(s)?|((current|list) )?view|((container|key) )?window|with (data|icon( (caution|note|stop))?|parameter(s)?|prompt|properties|seed|title)|case|diacriticals|hyphens|numeric strings|punctuation|white space|folder creation|application(s( folder)?| (processes|scripts position|support))?|((desktop )?(pictures )?|(documents|downloads|favorites|home|keychain|library|movies|music|public|scripts|sites|system|users|utilities|workflows) )folder|desktop|Folder Action scripts|font(s| panel)?|help|internet plugins|modem scripts|(system )?preferences|printer descriptions|scripting (additions|components)|shared (documents|libraries)|startup (disk|items)|temporary items|trash|on server|in AppleTalk zone|((as|long|short) )?user name|user (ID|locale)|(with )?password|in (bundle( with identifier)?|directory)|(close|open for) access|read|write( permission)?|(g|s)et eof|using( delimiters)?|starting at|default (answer|button|color|country code|entr(y|ies)|identifiers|items|name|location|script editor)|hidden( answer)?|open(ed| (location|untitled))?|error (handling|reporting)|(do( shell)?|load|run|store) script|administrator privileges|altering line endings|get volume settings|(alert|boot|input|mount|output|set) volume|output muted|(fax|random )?number|round(ing)?|up|down|toward zero|to nearest|as taught in school|system (attribute|info)|((AppleScript( Studio)?|system) )?version|(home )?directory|(IPv4|primary Ethernet) address|CPU (type|speed)|physical memory|time (stamp|to GMT)|replacing|ASCII (character|number)|localized string|from table|offset|summarize|beep|delay|say|(empty|multiple) selections allowed|(of|preferred) type|invisibles|showing( package contents)?|editable URL|(File|FTP|News|Media|Web) [Ss]ervers|Telnet hosts|Directory services|Remote applications|waiting until completion|saving( (in|to))?|path (for|to( (((current|frontmost) )?application|resource))?)|POSIX (file|path)|(background|RGB) color|(OK|cancel) button name|cancel button|button(s)?|cubic ((centi)?met(re|er)s|yards|feet|inches)|square ((kilo)?met(re|er)s|miles|yards|feet)|(centi|kilo)?met(re|er)s|miles|yards|feet|inches|lit(re|er)s|gallons|quarts|(kilo)?grams|ounces|pounds|degrees (Celsius|Fahrenheit|Kelvin)|print( (dialog|settings))?|clos(e(able)?|ing)|(de)?miniaturized|miniaturizable|zoom(ed|able)|attribute run|action (method|property|title)|phone|email|((start|end)ing|home) page|((birth|creation|current|custom|modification) )?date|((((phonetic )?(first|last|middle))|computer|host|maiden|related) |nick)?name|aim|icq|jabber|msn|yahoo|address(es)?|save addressbook|should enable action|city|country( code)?|formatte(r|d address)|(palette )?label|state|street|zip|AIM [Hh]andle(s)?|my card|select(ion| all)?|unsaved|(alpha )?value|entr(y|ies)|group|(ICQ|Jabber|MSN) handle|person|people|company|department|icon image|job title|note|organization|suffix|vcard|url|copies|collating|pages (across|down)|request print time|target( printer)?|((GUI Scripting|Script menu) )?enabled|show Computer scripts|(de)?activated|awake from nib|became (key|main)|call method|of (class|object)|center|clicked toolbar item|closed|for document|exposed|(can )?hide|idle|keyboard (down|up)|event( (number|type))?|launch(ed)?|load (image|movie|nib|sound)|owner|log|mouse (down|dragged|entered|exited|moved|up)|move|column|localization|resource|script|register|drag (info|types)|resigned (active|key|main)|resiz(e(d)?|able)|right mouse (down|dragged|up)|scroll wheel|(at )?index|should (close|open( untitled)?|quit( after last window closed)?|zoom)|((proposed|screen) )?bounds|show(n)?|behind|in front of|size (mode|to fit)|update(d| toolbar item)?|was (hidden|miniaturized)|will (become active|close|finish launching|hide|miniaturize|move|open|quit|(resign )?active|((maximum|minimum|proposed) )?size|show|zoom)|bundle|data source|movie|pasteboard|sound|tool(bar| tip)|(color|open|save) panel|coordinate system|frontmost|main( (bundle|menu|window))?|((services|(excluded from )?windows) )?menu|((executable|frameworks|resource|scripts|shared (frameworks|support)) )?path|(selected item )?identifier|data|content(s| view)?|character(s)?|click count|(command|control|option|shift) key down|context|delta (x|y|z)|key( code)?|location|pressure|unmodified characters|types|(first )?responder|playing|(allowed|selectable) identifiers|allows customization|(auto saves )?configuration|visible|image( name)?|menu form representation|tag|user(-| )defaults|associated file name|(auto|needs) display|current field editor|floating|has (resize indicator|shadow)|hides when deactivated|level|minimized (image|title)|opaque|position|release when closed|sheet|title(d)?)\\b/g,\n                css: 'color3' },\n\n            { regex: new RegExp(this.getKeywords(specials), 'gm'), css: 'color3' },\n            { regex: new RegExp(this.getKeywords(keywords), 'gm'), css: 'keyword' },\n            { regex: new RegExp(this.getKeywords(ordinals), 'gm'), css: 'keyword' }\n        ];\n    };\n\n    Brush.prototype = new SyntaxHighlighter.Highlighter();\n    Brush.aliases = ['applescript'];\n\n    SyntaxHighlighter.brushes.AppleScript = Brush;\n\n    // CommonJS\n    typeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\tvar keywords =\t'if fi then elif else for do done until while break continue case esac function return in eq ne ge le';\n\t\tvar commands =  'alias apropos awk basename bash bc bg builtin bzip2 cal cat cd cfdisk chgrp chmod chown chroot' +\n\t\t\t\t\t\t'cksum clear cmp comm command cp cron crontab csplit cut date dc dd ddrescue declare df ' +\n\t\t\t\t\t\t'diff diff3 dig dir dircolors dirname dirs du echo egrep eject enable env ethtool eval ' +\n\t\t\t\t\t\t'exec exit expand export expr false fdformat fdisk fg fgrep file find fmt fold format ' +\n\t\t\t\t\t\t'free fsck ftp gawk getopts grep groups gzip hash head history hostname id ifconfig ' +\n\t\t\t\t\t\t'import install join kill less let ln local locate logname logout look lpc lpr lprint ' +\n\t\t\t\t\t\t'lprintd lprintq lprm ls lsof make man mkdir mkfifo mkisofs mknod more mount mtools ' +\n\t\t\t\t\t\t'mv netstat nice nl nohup nslookup open op passwd paste pathchk ping popd pr printcap ' +\n\t\t\t\t\t\t'printenv printf ps pushd pwd quota quotacheck quotactl ram rcp read readonly renice ' +\n\t\t\t\t\t\t'remsync rm rmdir rsync screen scp sdiff sed select seq set sftp shift shopt shutdown ' +\n\t\t\t\t\t\t'sleep sort source split ssh strace su sudo sum symlink sync tail tar tee test time ' +\n\t\t\t\t\t\t'times touch top traceroute trap tr true tsort tty type ulimit umask umount unalias ' +\n\t\t\t\t\t\t'uname unexpand uniq units unset unshar useradd usermod users uuencode uudecode v vdir ' +\n\t\t\t\t\t\t'vi watch wc whereis which who whoami Wget xargs yes'\n\t\t\t\t\t\t;\n\n\t\tthis.regexList = [\n\t\t\t{ regex: /^#!.*$/gm,\t\t\t\t\t\t\t\t\t\t\tcss: 'preprocessor bold' },\n\t\t\t{ regex: /\\/[\\w-\\/]+/gm,\t\t\t\t\t\t\t\t\t\tcss: 'plain' },\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleLinePerlComments,\t\tcss: 'comments' },\t\t// one line comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\t\tcss: 'string' },\t\t// double quoted strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\t\tcss: 'string' },\t\t// single quoted strings\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\t\t\tcss: 'keyword' },\t\t// keywords\n\t\t\t{ regex: new RegExp(this.getKeywords(commands), 'gm'),\t\t\tcss: 'functions' }\t\t// commands\n\t\t\t];\n\t}\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['bash', 'shell', 'sh'];\n\n\tSyntaxHighlighter.brushes.Bash = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\t// Contributed by Jen\n\t\t// http://www.jensbits.com/2009/05/14/coldfusion-brush-for-syntaxhighlighter-plus\n\t\n\t\tvar funcs\t=\t'Abs ACos AddSOAPRequestHeader AddSOAPResponseHeader AjaxLink AjaxOnLoad ArrayAppend ArrayAvg ArrayClear ArrayDeleteAt ' + \n\t\t\t\t\t\t'ArrayInsertAt ArrayIsDefined ArrayIsEmpty ArrayLen ArrayMax ArrayMin ArraySet ArraySort ArraySum ArraySwap ArrayToList ' + \n\t\t\t\t\t\t'Asc ASin Atn BinaryDecode BinaryEncode BitAnd BitMaskClear BitMaskRead BitMaskSet BitNot BitOr BitSHLN BitSHRN BitXor ' + \n\t\t\t\t\t\t'Ceiling CharsetDecode CharsetEncode Chr CJustify Compare CompareNoCase Cos CreateDate CreateDateTime CreateObject ' + \n\t\t\t\t\t\t'CreateODBCDate CreateODBCDateTime CreateODBCTime CreateTime CreateTimeSpan CreateUUID DateAdd DateCompare DateConvert ' + \n\t\t\t\t\t\t'DateDiff DateFormat DatePart Day DayOfWeek DayOfWeekAsString DayOfYear DaysInMonth DaysInYear DE DecimalFormat DecrementValue ' + \n\t\t\t\t\t\t'Decrypt DecryptBinary DeleteClientVariable DeserializeJSON DirectoryExists DollarFormat DotNetToCFType Duplicate Encrypt ' + \n\t\t\t\t\t\t'EncryptBinary Evaluate Exp ExpandPath FileClose FileCopy FileDelete FileExists FileIsEOF FileMove FileOpen FileRead ' + \n\t\t\t\t\t\t'FileReadBinary FileReadLine FileSetAccessMode FileSetAttribute FileSetLastModified FileWrite Find FindNoCase FindOneOf ' + \n\t\t\t\t\t\t'FirstDayOfMonth Fix FormatBaseN GenerateSecretKey GetAuthUser GetBaseTagData GetBaseTagList GetBaseTemplatePath ' + \n\t\t\t\t\t\t'GetClientVariablesList GetComponentMetaData GetContextRoot GetCurrentTemplatePath GetDirectoryFromPath GetEncoding ' + \n\t\t\t\t\t\t'GetException GetFileFromPath GetFileInfo GetFunctionList GetGatewayHelper GetHttpRequestData GetHttpTimeString ' + \n\t\t\t\t\t\t'GetK2ServerDocCount GetK2ServerDocCountLimit GetLocale GetLocaleDisplayName GetLocalHostIP GetMetaData GetMetricData ' + \n\t\t\t\t\t\t'GetPageContext GetPrinterInfo GetProfileSections GetProfileString GetReadableImageFormats GetSOAPRequest GetSOAPRequestHeader ' + \n\t\t\t\t\t\t'GetSOAPResponse GetSOAPResponseHeader GetTempDirectory GetTempFile GetTemplatePath GetTickCount GetTimeZoneInfo GetToken ' + \n\t\t\t\t\t\t'GetUserRoles GetWriteableImageFormats Hash Hour HTMLCodeFormat HTMLEditFormat IIf ImageAddBorder ImageBlur ImageClearRect ' + \n\t\t\t\t\t\t'ImageCopy ImageCrop ImageDrawArc ImageDrawBeveledRect ImageDrawCubicCurve ImageDrawLine ImageDrawLines ImageDrawOval ' + \n\t\t\t\t\t\t'ImageDrawPoint ImageDrawQuadraticCurve ImageDrawRect ImageDrawRoundRect ImageDrawText ImageFlip ImageGetBlob ImageGetBufferedImage ' + \n\t\t\t\t\t\t'ImageGetEXIFTag ImageGetHeight ImageGetIPTCTag ImageGetWidth ImageGrayscale ImageInfo ImageNegative ImageNew ImageOverlay ImagePaste ' + \n\t\t\t\t\t\t'ImageRead ImageReadBase64 ImageResize ImageRotate ImageRotateDrawingAxis ImageScaleToFit ImageSetAntialiasing ImageSetBackgroundColor ' + \n\t\t\t\t\t\t'ImageSetDrawingColor ImageSetDrawingStroke ImageSetDrawingTransparency ImageSharpen ImageShear ImageShearDrawingAxis ImageTranslate ' + \n\t\t\t\t\t\t'ImageTranslateDrawingAxis ImageWrite ImageWriteBase64 ImageXORDrawingMode IncrementValue InputBaseN Insert Int IsArray IsBinary ' + \n\t\t\t\t\t\t'IsBoolean IsCustomFunction IsDate IsDDX IsDebugMode IsDefined IsImage IsImageFile IsInstanceOf IsJSON IsLeapYear IsLocalHost ' + \n\t\t\t\t\t\t'IsNumeric IsNumericDate IsObject IsPDFFile IsPDFObject IsQuery IsSimpleValue IsSOAPRequest IsStruct IsUserInAnyRole IsUserInRole ' + \n\t\t\t\t\t\t'IsUserLoggedIn IsValid IsWDDX IsXML IsXmlAttribute IsXmlDoc IsXmlElem IsXmlNode IsXmlRoot JavaCast JSStringFormat LCase Left Len ' + \n\t\t\t\t\t\t'ListAppend ListChangeDelims ListContains ListContainsNoCase ListDeleteAt ListFind ListFindNoCase ListFirst ListGetAt ListInsertAt ' + \n\t\t\t\t\t\t'ListLast ListLen ListPrepend ListQualify ListRest ListSetAt ListSort ListToArray ListValueCount ListValueCountNoCase LJustify Log ' + \n\t\t\t\t\t\t'Log10 LSCurrencyFormat LSDateFormat LSEuroCurrencyFormat LSIsCurrency LSIsDate LSIsNumeric LSNumberFormat LSParseCurrency LSParseDateTime ' + \n\t\t\t\t\t\t'LSParseEuroCurrency LSParseNumber LSTimeFormat LTrim Max Mid Min Minute Month MonthAsString Now NumberFormat ParagraphFormat ParseDateTime ' + \n\t\t\t\t\t\t'Pi PrecisionEvaluate PreserveSingleQuotes Quarter QueryAddColumn QueryAddRow QueryConvertForGrid QueryNew QuerySetCell QuotedValueList Rand ' + \n\t\t\t\t\t\t'Randomize RandRange REFind REFindNoCase ReleaseComObject REMatch REMatchNoCase RemoveChars RepeatString Replace ReplaceList ReplaceNoCase ' + \n\t\t\t\t\t\t'REReplace REReplaceNoCase Reverse Right RJustify Round RTrim Second SendGatewayMessage SerializeJSON SetEncoding SetLocale SetProfileString ' + \n\t\t\t\t\t\t'SetVariable Sgn Sin Sleep SpanExcluding SpanIncluding Sqr StripCR StructAppend StructClear StructCopy StructCount StructDelete StructFind ' + \n\t\t\t\t\t\t'StructFindKey StructFindValue StructGet StructInsert StructIsEmpty StructKeyArray StructKeyExists StructKeyList StructKeyList StructNew ' + \n\t\t\t\t\t\t'StructSort StructUpdate Tan TimeFormat ToBase64 ToBinary ToScript ToString Trim UCase URLDecode URLEncodedFormat URLSessionFormat Val ' + \n\t\t\t\t\t\t'ValueList VerifyClient Week Wrap Wrap WriteOutput XmlChildPos XmlElemNew XmlFormat XmlGetNodeType XmlNew XmlParse XmlSearch XmlTransform ' + \n\t\t\t\t\t\t'XmlValidate Year YesNoFormat';\n\n\t\tvar keywords =\t'cfabort cfajaximport cfajaxproxy cfapplet cfapplication cfargument cfassociate cfbreak cfcache cfcalendar ' + \n\t\t\t\t\t\t'cfcase cfcatch cfchart cfchartdata cfchartseries cfcol cfcollection cfcomponent cfcontent cfcookie cfdbinfo ' + \n\t\t\t\t\t\t'cfdefaultcase cfdirectory cfdiv cfdocument cfdocumentitem cfdocumentsection cfdump cfelse cfelseif cferror ' + \n\t\t\t\t\t\t'cfexchangecalendar cfexchangeconnection cfexchangecontact cfexchangefilter cfexchangemail cfexchangetask ' + \n\t\t\t\t\t\t'cfexecute cfexit cffeed cffile cfflush cfform cfformgroup cfformitem cfftp cffunction cfgrid cfgridcolumn ' + \n\t\t\t\t\t\t'cfgridrow cfgridupdate cfheader cfhtmlhead cfhttp cfhttpparam cfif cfimage cfimport cfinclude cfindex ' + \n\t\t\t\t\t\t'cfinput cfinsert cfinterface cfinvoke cfinvokeargument cflayout cflayoutarea cfldap cflocation cflock cflog ' + \n\t\t\t\t\t\t'cflogin cfloginuser cflogout cfloop cfmail cfmailparam cfmailpart cfmenu cfmenuitem cfmodule cfNTauthenticate ' + \n\t\t\t\t\t\t'cfobject cfobjectcache cfoutput cfparam cfpdf cfpdfform cfpdfformparam cfpdfparam cfpdfsubform cfpod cfpop ' + \n\t\t\t\t\t\t'cfpresentation cfpresentationslide cfpresenter cfprint cfprocessingdirective cfprocparam cfprocresult ' + \n\t\t\t\t\t\t'cfproperty cfquery cfqueryparam cfregistry cfreport cfreportparam cfrethrow cfreturn cfsavecontent cfschedule ' + \n\t\t\t\t\t\t'cfscript cfsearch cfselect cfset cfsetting cfsilent cfslider cfsprydataset cfstoredproc cfswitch cftable ' + \n\t\t\t\t\t\t'cftextarea cfthread cfthrow cftimer cftooltip cftrace cftransaction cftree cftreeitem cftry cfupdate cfwddx ' + \n\t\t\t\t\t\t'cfwindow cfxml cfzip cfzipparam';\n\n\t\tvar operators =\t'all and any between cross in join like not null or outer some';\n\n\t\tthis.regexList = [\n\t\t\t{ regex: new RegExp('--(.*)$', 'gm'),\t\t\t\t\t\tcss: 'comments' },  // one line and multiline comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.xmlComments,\t\t\tcss: 'comments' },    // single quoted strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\tcss: 'string' },    // double quoted strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\tcss: 'string' },    // single quoted strings\n\t\t\t{ regex: new RegExp(this.getKeywords(funcs), 'gmi'),\t\tcss: 'functions' }, // functions\n\t\t\t{ regex: new RegExp(this.getKeywords(operators), 'gmi'),\tcss: 'color1' },    // operators and such\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gmi'),\t\tcss: 'keyword' }    // keyword\n\t\t\t];\n\t}\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['coldfusion','cf'];\n\t\n\tSyntaxHighlighter.brushes.ColdFusion = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\t// Copyright 2006 Shin, YoungJin\n\t\n\t\tvar datatypes =\t'ATOM BOOL BOOLEAN BYTE CHAR COLORREF DWORD DWORDLONG DWORD_PTR ' +\n\t\t\t\t\t\t'DWORD32 DWORD64 FLOAT HACCEL HALF_PTR HANDLE HBITMAP HBRUSH ' +\n\t\t\t\t\t\t'HCOLORSPACE HCONV HCONVLIST HCURSOR HDC HDDEDATA HDESK HDROP HDWP ' +\n\t\t\t\t\t\t'HENHMETAFILE HFILE HFONT HGDIOBJ HGLOBAL HHOOK HICON HINSTANCE HKEY ' +\n\t\t\t\t\t\t'HKL HLOCAL HMENU HMETAFILE HMODULE HMONITOR HPALETTE HPEN HRESULT ' +\n\t\t\t\t\t\t'HRGN HRSRC HSZ HWINSTA HWND INT INT_PTR INT32 INT64 LANGID LCID LCTYPE ' +\n\t\t\t\t\t\t'LGRPID LONG LONGLONG LONG_PTR LONG32 LONG64 LPARAM LPBOOL LPBYTE LPCOLORREF ' +\n\t\t\t\t\t\t'LPCSTR LPCTSTR LPCVOID LPCWSTR LPDWORD LPHANDLE LPINT LPLONG LPSTR LPTSTR ' +\n\t\t\t\t\t\t'LPVOID LPWORD LPWSTR LRESULT PBOOL PBOOLEAN PBYTE PCHAR PCSTR PCTSTR PCWSTR ' +\n\t\t\t\t\t\t'PDWORDLONG PDWORD_PTR PDWORD32 PDWORD64 PFLOAT PHALF_PTR PHANDLE PHKEY PINT ' +\n\t\t\t\t\t\t'PINT_PTR PINT32 PINT64 PLCID PLONG PLONGLONG PLONG_PTR PLONG32 PLONG64 POINTER_32 ' +\n\t\t\t\t\t\t'POINTER_64 PSHORT PSIZE_T PSSIZE_T PSTR PTBYTE PTCHAR PTSTR PUCHAR PUHALF_PTR ' +\n\t\t\t\t\t\t'PUINT PUINT_PTR PUINT32 PUINT64 PULONG PULONGLONG PULONG_PTR PULONG32 PULONG64 ' +\n\t\t\t\t\t\t'PUSHORT PVOID PWCHAR PWORD PWSTR SC_HANDLE SC_LOCK SERVICE_STATUS_HANDLE SHORT ' +\n\t\t\t\t\t\t'SIZE_T SSIZE_T TBYTE TCHAR UCHAR UHALF_PTR UINT UINT_PTR UINT32 UINT64 ULONG ' +\n\t\t\t\t\t\t'ULONGLONG ULONG_PTR ULONG32 ULONG64 USHORT USN VOID WCHAR WORD WPARAM WPARAM WPARAM ' +\n\t\t\t\t\t\t'char bool short int __int32 __int64 __int8 __int16 long float double __wchar_t ' +\n\t\t\t\t\t\t'clock_t _complex _dev_t _diskfree_t div_t ldiv_t _exception _EXCEPTION_POINTERS ' +\n\t\t\t\t\t\t'FILE _finddata_t _finddatai64_t _wfinddata_t _wfinddatai64_t __finddata64_t ' +\n\t\t\t\t\t\t'__wfinddata64_t _FPIEEE_RECORD fpos_t _HEAPINFO _HFILE lconv intptr_t ' +\n\t\t\t\t\t\t'jmp_buf mbstate_t _off_t _onexit_t _PNH ptrdiff_t _purecall_handler ' +\n\t\t\t\t\t\t'sig_atomic_t size_t _stat __stat64 _stati64 terminate_function ' +\n\t\t\t\t\t\t'time_t __time64_t _timeb __timeb64 tm uintptr_t _utimbuf ' +\n\t\t\t\t\t\t'va_list wchar_t wctrans_t wctype_t wint_t signed';\n\n\t\tvar keywords =\t'auto break case catch class const decltype __finally __exception __try ' +\n\t\t\t\t\t\t'const_cast continue private public protected __declspec ' +\n\t\t\t\t\t\t'default delete deprecated dllexport dllimport do dynamic_cast ' +\n\t\t\t\t\t\t'else enum explicit extern if for friend goto inline ' +\n\t\t\t\t\t\t'mutable naked namespace new noinline noreturn nothrow ' +\n\t\t\t\t\t\t'register reinterpret_cast return selectany ' +\n\t\t\t\t\t\t'sizeof static static_cast struct switch template this ' +\n\t\t\t\t\t\t'thread throw true false try typedef typeid typename union ' +\n\t\t\t\t\t\t'using uuid virtual void volatile whcar_t while';\n\t\t\t\t\t\n\t\tvar functions =\t'assert isalnum isalpha iscntrl isdigit isgraph islower isprint' +\n\t\t\t\t\t\t'ispunct isspace isupper isxdigit tolower toupper errno localeconv ' +\n\t\t\t\t\t\t'setlocale acos asin atan atan2 ceil cos cosh exp fabs floor fmod ' +\n\t\t\t\t\t\t'frexp ldexp log log10 modf pow sin sinh sqrt tan tanh jmp_buf ' +\n\t\t\t\t\t\t'longjmp setjmp raise signal sig_atomic_t va_arg va_end va_start ' +\n\t\t\t\t\t\t'clearerr fclose feof ferror fflush fgetc fgetpos fgets fopen ' +\n\t\t\t\t\t\t'fprintf fputc fputs fread freopen fscanf fseek fsetpos ftell ' +\n\t\t\t\t\t\t'fwrite getc getchar gets perror printf putc putchar puts remove ' +\n\t\t\t\t\t\t'rename rewind scanf setbuf setvbuf sprintf sscanf tmpfile tmpnam ' +\n\t\t\t\t\t\t'ungetc vfprintf vprintf vsprintf abort abs atexit atof atoi atol ' +\n\t\t\t\t\t\t'bsearch calloc div exit free getenv labs ldiv malloc mblen mbstowcs ' +\n\t\t\t\t\t\t'mbtowc qsort rand realloc srand strtod strtol strtoul system ' +\n\t\t\t\t\t\t'wcstombs wctomb memchr memcmp memcpy memmove memset strcat strchr ' +\n\t\t\t\t\t\t'strcmp strcoll strcpy strcspn strerror strlen strncat strncmp ' +\n\t\t\t\t\t\t'strncpy strpbrk strrchr strspn strstr strtok strxfrm asctime ' +\n\t\t\t\t\t\t'clock ctime difftime gmtime localtime mktime strftime time';\n\n\t\tthis.regexList = [\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleLineCComments,\tcss: 'comments' },\t\t\t// one line comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.multiLineCComments,\t\tcss: 'comments' },\t\t\t// multiline comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\tcss: 'string' },\t\t\t// strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\tcss: 'string' },\t\t\t// strings\n\t\t\t{ regex: /^ *#.*/gm,\t\t\t\t\t\t\t\t\t\tcss: 'preprocessor' },\n\t\t\t{ regex: new RegExp(this.getKeywords(datatypes), 'gm'),\t\tcss: 'color1 bold' },\n\t\t\t{ regex: new RegExp(this.getKeywords(functions), 'gm'),\t\tcss: 'functions bold' },\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\t\tcss: 'keyword bold' }\n\t\t\t];\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['cpp', 'c'];\n\n\tSyntaxHighlighter.brushes.Cpp = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\tvar keywords =\t'abstract as base bool break byte case catch char checked class const ' +\n\t\t\t\t\t\t'continue decimal default delegate do double else enum event explicit volatile ' +\n\t\t\t\t\t\t'extern false finally fixed float for foreach get goto if implicit in int ' +\n\t\t\t\t\t\t'interface internal is lock long namespace new null object operator out ' +\n\t\t\t\t\t\t'override params private protected public readonly ref return sbyte sealed set ' +\n\t\t\t\t\t\t'short sizeof stackalloc static string struct switch this throw true try ' +\n\t\t\t\t\t\t'typeof uint ulong unchecked unsafe ushort using virtual void while var ' +\n\t\t\t\t\t\t'from group by into select let where orderby join on equals ascending descending';\n\n\t\tfunction fixComments(match, regexInfo)\n\t\t{\n\t\t\tvar css = (match[0].indexOf(\"///\") == 0)\n\t\t\t\t? 'color1'\n\t\t\t\t: 'comments'\n\t\t\t\t;\n\t\t\t\n\t\t\treturn [new SyntaxHighlighter.Match(match[0], match.index, css)];\n\t\t}\n\n\t\tthis.regexList = [\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleLineCComments,\tfunc : fixComments },\t\t// one line comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.multiLineCComments,\t\tcss: 'comments' },\t\t\t// multiline comments\n\t\t\t{ regex: /@\"(?:[^\"]|\"\")*\"/g,\t\t\t\t\t\t\t\tcss: 'string' },\t\t\t// @-quoted strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\tcss: 'string' },\t\t\t// strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\tcss: 'string' },\t\t\t// strings\n\t\t\t{ regex: /^\\s*#.*/gm,\t\t\t\t\t\t\t\t\t\tcss: 'preprocessor' },\t\t// preprocessor tags like #region and #endregion\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\t\tcss: 'keyword' },\t\t\t// c# keyword\n\t\t\t{ regex: /\\bpartial(?=\\s+(?:class|interface|struct)\\b)/g,\tcss: 'keyword' },\t\t\t// contextual keyword: 'partial'\n\t\t\t{ regex: /\\byield(?=\\s+(?:return|break)\\b)/g,\t\t\t\tcss: 'keyword' }\t\t\t// contextual keyword: 'yield'\n\t\t\t];\n\t\t\n\t\tthis.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['c#', 'c-sharp', 'csharp'];\n\n\tSyntaxHighlighter.brushes.CSharp = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\tfunction getKeywordsCSS(str)\n\t\t{\n\t\t\treturn '\\\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\\\b|\\\\b([a-z_\\\\*]|\\\\*|)') + '(?=:)\\\\b';\n\t\t};\n\t\n\t\tfunction getValuesCSS(str)\n\t\t{\n\t\t\treturn '\\\\b' + str.replace(/ /g, '(?!-)(?!:)\\\\b|\\\\b()') + '\\:\\\\b';\n\t\t};\n\n\t\tvar keywords =\t'ascent azimuth background-attachment background-color background-image background-position ' +\n\t\t\t\t\t\t'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' +\n\t\t\t\t\t\t'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' +\n\t\t\t\t\t\t'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' +\n\t\t\t\t\t\t'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' +\n\t\t\t\t\t\t'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' +\n\t\t\t\t\t\t'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' +\n\t\t\t\t\t\t'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' +\n\t\t\t\t\t\t'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' +\n\t\t\t\t\t\t'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' +\n\t\t\t\t\t\t'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' +\n\t\t\t\t\t\t'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' +\n\t\t\t\t\t\t'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' +\n\t\t\t\t\t\t'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index';\n\n\t\tvar values =\t'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+\n\t\t\t\t\t\t'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+\n\t\t\t\t\t\t'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero default digits disc dotted double '+\n\t\t\t\t\t\t'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+\n\t\t\t\t\t\t'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+\n\t\t\t\t\t\t'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+\n\t\t\t\t\t\t'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+\n\t\t\t\t\t\t'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+\n\t\t\t\t\t\t'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+\n\t\t\t\t\t\t'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+\n\t\t\t\t\t\t'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+\n\t\t\t\t\t\t'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+\n\t\t\t\t\t\t'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+\n\t\t\t\t\t\t'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow';\n\n\t\tvar fonts =\t\t'[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif';\n\t\n\t\tthis.regexList = [\n\t\t\t{ regex: SyntaxHighlighter.regexLib.multiLineCComments,\t\tcss: 'comments' },\t// multiline comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\tcss: 'string' },\t// double quoted strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\tcss: 'string' },\t// single quoted strings\n\t\t\t{ regex: /\\#[a-fA-F0-9]{3,6}/g,\t\t\t\t\t\t\t\tcss: 'value' },\t\t// html colors\n\t\t\t{ regex: /(-?\\d+)(\\.\\d+)?(px|em|pt|\\:|\\%|)/g,\t\t\t\tcss: 'value' },\t\t// sizes\n\t\t\t{ regex: /!important/g,\t\t\t\t\t\t\t\t\t\tcss: 'color3' },\t// !important\n\t\t\t{ regex: new RegExp(getKeywordsCSS(keywords), 'gm'),\t\tcss: 'keyword' },\t// keywords\n\t\t\t{ regex: new RegExp(getValuesCSS(values), 'g'),\t\t\t\tcss: 'value' },\t\t// values\n\t\t\t{ regex: new RegExp(this.getKeywords(fonts), 'g'),\t\t\tcss: 'color1' }\t\t// fonts\n\t\t\t];\n\n\t\tthis.forHtmlScript({ \n\t\t\tleft: /(&lt;|<)\\s*style.*?(&gt;|>)/gi, \n\t\t\tright: /(&lt;|<)\\/\\s*style\\s*(&gt;|>)/gi \n\t\t\t});\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['css'];\n\n\tSyntaxHighlighter.brushes.CSS = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\tvar keywords =\t'abs addr and ansichar ansistring array as asm begin boolean byte cardinal ' +\n\t\t\t\t\t\t'case char class comp const constructor currency destructor div do double ' +\n\t\t\t\t\t\t'downto else end except exports extended false file finalization finally ' +\n\t\t\t\t\t\t'for function goto if implementation in inherited int64 initialization ' +\n\t\t\t\t\t\t'integer interface is label library longint longword mod nil not object ' +\n\t\t\t\t\t\t'of on or packed pansichar pansistring pchar pcurrency pdatetime pextended ' +\n\t\t\t\t\t\t'pint64 pointer private procedure program property pshortstring pstring ' +\n\t\t\t\t\t\t'pvariant pwidechar pwidestring protected public published raise real real48 ' +\n\t\t\t\t\t\t'record repeat set shl shortint shortstring shr single smallint string then ' +\n\t\t\t\t\t\t'threadvar to true try type unit until uses val var varirnt while widechar ' +\n\t\t\t\t\t\t'widestring with word write writeln xor';\n\n\t\tthis.regexList = [\n\t\t\t{ regex: /\\(\\*[\\s\\S]*?\\*\\)/gm,\t\t\t\t\t\t\t\tcss: 'comments' },  \t// multiline comments (* *)\n\t\t\t{ regex: /{(?!\\$)[\\s\\S]*?}/gm,\t\t\t\t\t\t\t\tcss: 'comments' },  \t// multiline comments { }\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleLineCComments,\tcss: 'comments' },  \t// one line\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\tcss: 'string' },\t\t// strings\n\t\t\t{ regex: /\\{\\$[a-zA-Z]+ .+\\}/g,\t\t\t\t\t\t\t\tcss: 'color1' },\t\t// compiler Directives and Region tags\n\t\t\t{ regex: /\\b[\\d\\.]+\\b/g,\t\t\t\t\t\t\t\t\tcss: 'value' },\t\t\t// numbers 12345\n\t\t\t{ regex: /\\$[a-zA-Z0-9]+\\b/g,\t\t\t\t\t\t\t\tcss: 'value' },\t\t\t// numbers $F5D3\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gmi'),\t\tcss: 'keyword' }\t\t// keyword\n\t\t\t];\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['delphi', 'pascal', 'pas'];\n\n\tSyntaxHighlighter.brushes.Delphi = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\tthis.regexList = [\n\t\t\t{ regex: /^\\+\\+\\+ .*$/gm,\tcss: 'color2' },\t// new file\n\t\t\t{ regex: /^\\-\\-\\- .*$/gm,\tcss: 'color2' },\t// old file\n\t\t\t{ regex: /^\\s.*$/gm,\t\tcss: 'color1' },\t// unchanged\n\t\t\t{ regex: /^@@.*@@.*$/gm,\tcss: 'variable' },\t// location\n\t\t\t{ regex: /^\\+.*$/gm,\t\tcss: 'string' },\t// additions\n\t\t\t{ regex: /^\\-.*$/gm,\t\tcss: 'color3' }\t\t// deletions\n\t\t\t];\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['diff', 'patch'];\n\n\tSyntaxHighlighter.brushes.Diff = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\t// Contributed by Jean-Lou Dupont\n\t\t// http://jldupont.blogspot.com/2009/06/erlang-syntax-highlighter.html  \n\n\t\t// According to: http://erlang.org/doc/reference_manual/introduction.html#1.5\n\t\tvar keywords = 'after and andalso band begin bnot bor bsl bsr bxor '+\n\t\t\t'case catch cond div end fun if let not of or orelse '+\n\t\t\t'query receive rem try when xor'+\n\t\t\t// additional\n\t\t\t' module export import define';\n\n\t\tthis.regexList = [\n\t\t\t{ regex: new RegExp(\"[A-Z][A-Za-z0-9_]+\", 'g'), \t\t\tcss: 'constants' },\n\t\t\t{ regex: new RegExp(\"\\\\%.+\", 'gm'), \t\t\t\t\t\tcss: 'comments' },\n\t\t\t{ regex: new RegExp(\"\\\\?[A-Za-z0-9_]+\", 'g'), \t\t\t\tcss: 'preprocessor' },\n\t\t\t{ regex: new RegExp(\"[a-z0-9_]+:[a-z0-9_]+\", 'g'), \t\t\tcss: 'functions' },\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\tcss: 'string' },\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\tcss: 'string' },\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords),\t'gm'),\t\tcss: 'keyword' }\n\t\t\t];\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['erl', 'erlang'];\n\n\tSyntaxHighlighter.brushes.Erland = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\t// Contributed by Andres Almiray\n\t\t// http://jroller.com/aalmiray/entry/nice_source_code_syntax_highlighter\n\n\t\tvar keywords =\t'as assert break case catch class continue def default do else extends finally ' +\n\t\t\t\t\t\t'if in implements import instanceof interface new package property return switch ' +\n\t\t\t\t\t\t'throw throws try while public protected private static';\n\t\tvar types    =  'void boolean byte char short int long float double';\n\t\tvar constants = 'null';\n\t\tvar methods   = 'allProperties count get size '+\n\t\t\t\t\t\t'collect each eachProperty eachPropertyName eachWithIndex find findAll ' +\n\t\t\t\t\t\t'findIndexOf grep inject max min reverseEach sort ' +\n\t\t\t\t\t\t'asImmutable asSynchronized flatten intersect join pop reverse subMap toList ' +\n\t\t\t\t\t\t'padRight padLeft contains eachMatch toCharacter toLong toUrl tokenize ' +\n\t\t\t\t\t\t'eachFile eachFileRecurse eachB yte eachLine readBytes readLine getText ' +\n\t\t\t\t\t\t'splitEachLine withReader append encodeBase64 decodeBase64 filterLine ' +\n\t\t\t\t\t\t'transformChar transformLine withOutputStream withPrintWriter withStream ' +\n\t\t\t\t\t\t'withStreams withWriter withWriterAppend write writeLine '+\n\t\t\t\t\t\t'dump inspect invokeMethod print println step times upto use waitForOrKill '+\n\t\t\t\t\t\t'getText';\n\n\t\tthis.regexList = [\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleLineCComments,\t\t\t\tcss: 'comments' },\t\t// one line comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.multiLineCComments,\t\t\t\t\tcss: 'comments' },\t\t// multiline comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\t\t\t\tcss: 'string' },\t\t// strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\t\t\t\tcss: 'string' },\t\t// strings\n\t\t\t{ regex: /\"\"\".*\"\"\"/g,\t\t\t\t\t\t\t\t\t\t\t\t\tcss: 'string' },\t\t// GStrings\n\t\t\t{ regex: new RegExp('\\\\b([\\\\d]+(\\\\.[\\\\d]+)?|0x[a-f0-9]+)\\\\b', 'gi'),\tcss: 'value' },\t\t\t// numbers\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\t\t\t\t\tcss: 'keyword' },\t\t// goovy keyword\n\t\t\t{ regex: new RegExp(this.getKeywords(types), 'gm'),\t\t\t\t\t\tcss: 'color1' },\t\t// goovy/java type\n\t\t\t{ regex: new RegExp(this.getKeywords(constants), 'gm'),\t\t\t\t\tcss: 'constants' },\t\t// constants\n\t\t\t{ regex: new RegExp(this.getKeywords(methods), 'gm'),\t\t\t\t\tcss: 'functions' }\t\t// methods\n\t\t\t];\n\n\t\tthis.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);\n\t}\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['groovy'];\n\n\tSyntaxHighlighter.brushes.Groovy = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\tvar keywords =\t'abstract assert boolean break byte case catch char class const ' +\n\t\t\t\t\t\t'continue default do double else enum extends ' +\n\t\t\t\t\t\t'false final finally float for goto if implements import ' +\n\t\t\t\t\t\t'instanceof int interface long native new null ' +\n\t\t\t\t\t\t'package private protected public return ' +\n\t\t\t\t\t\t'short static strictfp super switch synchronized this throw throws true ' +\n\t\t\t\t\t\t'transient try void volatile while';\n\n\t\tthis.regexList = [\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleLineCComments,\tcss: 'comments' },\t\t// one line comments\n\t\t\t{ regex: /\\/\\*([^\\*][\\s\\S]*)?\\*\\//gm,\t\t\t\t\t\tcss: 'comments' },\t \t// multiline comments\n\t\t\t{ regex: /\\/\\*(?!\\*\\/)\\*[\\s\\S]*?\\*\\//gm,\t\t\t\t\tcss: 'preprocessor' },\t// documentation comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\tcss: 'string' },\t\t// strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\tcss: 'string' },\t\t// strings\n\t\t\t{ regex: /\\b([\\d]+(\\.[\\d]+)?|0x[a-f0-9]+)\\b/gi,\t\t\t\tcss: 'value' },\t\t\t// numbers\n\t\t\t{ regex: /(?!\\@interface\\b)\\@[\\$\\w]+\\b/g,\t\t\t\t\tcss: 'color1' },\t\t// annotation @anno\n\t\t\t{ regex: /\\@interface\\b/g,\t\t\t\t\t\t\t\t\tcss: 'color2' },\t\t// @interface keyword\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\t\tcss: 'keyword' }\t\t// java keyword\n\t\t\t];\n\n\t\tthis.forHtmlScript({\n\t\t\tleft\t: /(&lt;|<)%[@!=]?/g, \n\t\t\tright\t: /%(&gt;|>)/g \n\t\t});\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['java'];\n\n\tSyntaxHighlighter.brushes.Java = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\t// Contributed by Patrick Webster\n\t\t// http://patrickwebster.blogspot.com/2009/04/javafx-brush-for-syntaxhighlighter.html\n\t\tvar datatypes =\t'Boolean Byte Character Double Duration '\n\t\t\t\t\t\t+ 'Float Integer Long Number Short String Void'\n\t\t\t\t\t\t;\n\n\t\tvar keywords = 'abstract after and as assert at before bind bound break catch class '\n\t\t\t\t\t\t+ 'continue def delete else exclusive extends false finally first for from '\n\t\t\t\t\t\t+ 'function if import in indexof init insert instanceof into inverse last '\n\t\t\t\t\t\t+ 'lazy mixin mod nativearray new not null on or override package postinit '\n\t\t\t\t\t\t+ 'protected public public-init public-read replace return reverse sizeof '\n\t\t\t\t\t\t+ 'step super then this throw true try tween typeof var where while with '\n\t\t\t\t\t\t+ 'attribute let private readonly static trigger'\n\t\t\t\t\t\t;\n\n\t\tthis.regexList = [\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleLineCComments,\tcss: 'comments' },\n\t\t\t{ regex: SyntaxHighlighter.regexLib.multiLineCComments,\t\tcss: 'comments' },\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\tcss: 'string' },\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\tcss: 'string' },\n\t\t\t{ regex: /(-?\\.?)(\\b(\\d*\\.?\\d+|\\d+\\.?\\d*)(e[+-]?\\d+)?|0x[a-f\\d]+)\\b\\.?/gi, css: 'color2' },\t// numbers\n\t\t\t{ regex: new RegExp(this.getKeywords(datatypes), 'gm'),\t\tcss: 'variable' },\t// datatypes\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\t\tcss: 'keyword' }\n\t\t];\n\t\tthis.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['jfx', 'javafx'];\n\n\tSyntaxHighlighter.brushes.JavaFX = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\tvar keywords =\t'break case catch continue ' +\n\t\t\t\t\t\t'default delete do else false  ' +\n\t\t\t\t\t\t'for function if in instanceof ' +\n\t\t\t\t\t\t'new null return super switch ' +\n\t\t\t\t\t\t'this throw true try typeof var while with'\n\t\t\t\t\t\t;\n\n\t\tvar r = SyntaxHighlighter.regexLib;\n\t\t\n\t\tthis.regexList = [\n\t\t\t{ regex: r.multiLineDoubleQuotedString,\t\t\t\t\tcss: 'string' },\t\t\t// double quoted strings\n\t\t\t{ regex: r.multiLineSingleQuotedString,\t\t\t\t\tcss: 'string' },\t\t\t// single quoted strings\n\t\t\t{ regex: r.singleLineCComments,\t\t\t\t\t\t\tcss: 'comments' },\t\t\t// one line comments\n\t\t\t{ regex: r.multiLineCComments,\t\t\t\t\t\t\tcss: 'comments' },\t\t\t// multiline comments\n\t\t\t{ regex: /\\s*#.*/gm,\t\t\t\t\t\t\t\t\tcss: 'preprocessor' },\t\t// preprocessor tags like #region and #endregion\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\tcss: 'keyword' }\t\t\t// keywords\n\t\t\t];\n\t\n\t\tthis.forHtmlScript(r.scriptScriptTags);\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['js', 'jscript', 'javascript'];\n\n\tSyntaxHighlighter.brushes.JScript = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\t// Contributed by David Simmons-Duffin and Marty Kube\n\t\n\t\tvar funcs = \n\t\t\t'abs accept alarm atan2 bind binmode chdir chmod chomp chop chown chr ' + \n\t\t\t'chroot close closedir connect cos crypt defined delete each endgrent ' + \n\t\t\t'endhostent endnetent endprotoent endpwent endservent eof exec exists ' + \n\t\t\t'exp fcntl fileno flock fork format formline getc getgrent getgrgid ' + \n\t\t\t'getgrnam gethostbyaddr gethostbyname gethostent getlogin getnetbyaddr ' + \n\t\t\t'getnetbyname getnetent getpeername getpgrp getppid getpriority ' + \n\t\t\t'getprotobyname getprotobynumber getprotoent getpwent getpwnam getpwuid ' + \n\t\t\t'getservbyname getservbyport getservent getsockname getsockopt glob ' + \n\t\t\t'gmtime grep hex index int ioctl join keys kill lc lcfirst length link ' + \n\t\t\t'listen localtime lock log lstat map mkdir msgctl msgget msgrcv msgsnd ' + \n\t\t\t'oct open opendir ord pack pipe pop pos print printf prototype push ' + \n\t\t\t'quotemeta rand read readdir readline readlink readpipe recv rename ' + \n\t\t\t'reset reverse rewinddir rindex rmdir scalar seek seekdir select semctl ' + \n\t\t\t'semget semop send setgrent sethostent setnetent setpgrp setpriority ' + \n\t\t\t'setprotoent setpwent setservent setsockopt shift shmctl shmget shmread ' + \n\t\t\t'shmwrite shutdown sin sleep socket socketpair sort splice split sprintf ' + \n\t\t\t'sqrt srand stat study substr symlink syscall sysopen sysread sysseek ' + \n\t\t\t'system syswrite tell telldir time times tr truncate uc ucfirst umask ' + \n\t\t\t'undef unlink unpack unshift utime values vec wait waitpid warn write ' +\n\t\t\t// feature\n\t\t\t'say';\n    \n\t\tvar keywords =  \n\t\t\t'bless caller continue dbmclose dbmopen die do dump else elsif eval exit ' +\n\t\t\t'for foreach goto if import last local my next no our package redo ref ' + \n\t\t\t'require return sub tie tied unless untie until use wantarray while ' +\n\t\t\t// feature\n\t\t\t'given when default ' +\n\t\t\t// Try::Tiny\n\t\t\t'try catch finally ' +\n\t\t\t// Moose\n\t\t\t'has extends with before after around override augment';\n    \n\t\tthis.regexList = [\n\t\t\t{ regex: /(<<|&lt;&lt;)((\\w+)|(['\"])(.+?)\\4)[\\s\\S]+?\\n\\3\\5\\n/g,\tcss: 'string' },\t// here doc (maybe html encoded)\n\t\t\t{ regex: /#.*$/gm,\t\t\t\t\t\t\t\t\t\tcss: 'comments' },\n\t\t\t{ regex: /^#!.*\\n/g,\t\t\t\t\t\t\t\t\tcss: 'preprocessor' },\t// shebang\n\t\t\t{ regex: /-?\\w+(?=\\s*=(>|&gt;))/g,\tcss: 'string' }, // fat comma\n\n\t\t\t// is this too much?\n\t\t\t{ regex: /\\bq[qwxr]?\\([\\s\\S]*?\\)/g,\tcss: 'string' }, // quote-like operators ()\n\t\t\t{ regex: /\\bq[qwxr]?\\{[\\s\\S]*?\\}/g,\tcss: 'string' }, // quote-like operators {}\n\t\t\t{ regex: /\\bq[qwxr]?\\[[\\s\\S]*?\\]/g,\tcss: 'string' }, // quote-like operators []\n\t\t\t{ regex: /\\bq[qwxr]?(<|&lt;)[\\s\\S]*?(>|&gt;)/g,\tcss: 'string' }, // quote-like operators <>\n\t\t\t{ regex: /\\bq[qwxr]?([^\\w({<[])[\\s\\S]*?\\1/g,\tcss: 'string' }, // quote-like operators non-paired\n\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\tcss: 'string' },\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\tcss: 'string' },\n\t\t\t// currently ignoring single quote package separator and utf8 names\n\t\t\t{ regex: /(?:&amp;|[$@%*]|\\$#)[a-zA-Z_](\\w+|::)*/g,   \t\tcss: 'variable' },\n\t\t\t{ regex: /\\b__(?:END|DATA)__\\b[\\s\\S]*$/g,\t\t\t\tcss: 'comments' },\n\t\t\t{ regex: /(^|\\n)=\\w[\\s\\S]*?(\\n=cut\\s*\\n|$)/g,\t\t\t\tcss: 'comments' },\t\t// pod\n\t\t\t{ regex: new RegExp(this.getKeywords(funcs), 'gm'),\t\tcss: 'functions' },\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\tcss: 'keyword' }\n\t\t];\n\n\t\tthis.forHtmlScript(SyntaxHighlighter.regexLib.phpScriptTags);\n\t}\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t\t= ['perl', 'Perl', 'pl'];\n\n\tSyntaxHighlighter.brushes.Perl = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\tvar funcs\t=\t'abs acos acosh addcslashes addslashes ' +\n\t\t\t\t\t\t'array_change_key_case array_chunk array_combine array_count_values array_diff '+\n\t\t\t\t\t\t'array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill '+\n\t\t\t\t\t\t'array_filter array_flip array_intersect array_intersect_assoc array_intersect_key '+\n\t\t\t\t\t\t'array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map '+\n\t\t\t\t\t\t'array_merge array_merge_recursive array_multisort array_pad array_pop array_product '+\n\t\t\t\t\t\t'array_push array_rand array_reduce array_reverse array_search array_shift '+\n\t\t\t\t\t\t'array_slice array_splice array_sum array_udiff array_udiff_assoc '+\n\t\t\t\t\t\t'array_udiff_uassoc array_uintersect array_uintersect_assoc '+\n\t\t\t\t\t\t'array_uintersect_uassoc array_unique array_unshift array_values array_walk '+\n\t\t\t\t\t\t'array_walk_recursive atan atan2 atanh base64_decode base64_encode base_convert '+\n\t\t\t\t\t\t'basename bcadd bccomp bcdiv bcmod bcmul bindec bindtextdomain bzclose bzcompress '+\n\t\t\t\t\t\t'bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite ceil chdir '+\n\t\t\t\t\t\t'checkdate checkdnsrr chgrp chmod chop chown chr chroot chunk_split class_exists '+\n\t\t\t\t\t\t'closedir closelog copy cos cosh count count_chars date decbin dechex decoct '+\n\t\t\t\t\t\t'deg2rad delete ebcdic2ascii echo empty end ereg ereg_replace eregi eregi_replace error_log '+\n\t\t\t\t\t\t'error_reporting escapeshellarg escapeshellcmd eval exec exit exp explode extension_loaded '+\n\t\t\t\t\t\t'feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents '+\n\t\t\t\t\t\t'fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype '+\n\t\t\t\t\t\t'floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv fputs fread fscanf '+\n\t\t\t\t\t\t'fseek fsockopen fstat ftell ftok getallheaders getcwd getdate getenv gethostbyaddr gethostbyname '+\n\t\t\t\t\t\t'gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt '+\n\t\t\t\t\t\t'getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext '+\n\t\t\t\t\t\t'gettimeofday gettype glob gmdate gmmktime ini_alter ini_get ini_get_all ini_restore ini_set '+\n\t\t\t\t\t\t'interface_exists intval ip2long is_a is_array is_bool is_callable is_dir is_double '+\n\t\t\t\t\t\t'is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long '+\n\t\t\t\t\t\t'is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault '+\n\t\t\t\t\t\t'is_string is_subclass_of is_uploaded_file is_writable is_writeable mkdir mktime nl2br '+\n\t\t\t\t\t\t'parse_ini_file parse_str parse_url passthru pathinfo print readlink realpath rewind rewinddir rmdir '+\n\t\t\t\t\t\t'round str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split '+\n\t\t\t\t\t\t'str_word_count strcasecmp strchr strcmp strcoll strcspn strftime strip_tags stripcslashes '+\n\t\t\t\t\t\t'stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk '+\n\t\t\t\t\t\t'strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime '+\n\t\t\t\t\t\t'strtoupper strtr strval substr substr_compare';\n\n\t\tvar keywords =\t'abstract and array as break case catch cfunction class clone const continue declare default die do ' +\n\t\t\t\t\t\t'else elseif enddeclare endfor endforeach endif endswitch endwhile extends final for foreach ' +\n\t\t\t\t\t\t'function global goto if implements include include_once interface instanceof insteadof namespace new ' +\n\t\t\t\t\t\t'old_function or private protected public return require require_once static switch ' +\n\t\t\t\t\t\t'trait throw try use var while xor ';\n\t\t\n\t\tvar constants\t= '__FILE__ __LINE__ __METHOD__ __FUNCTION__ __CLASS__';\n\n\t\tthis.regexList = [\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleLineCComments,\tcss: 'comments' },\t\t\t// one line comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.multiLineCComments,\t\tcss: 'comments' },\t\t\t// multiline comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\tcss: 'string' },\t\t\t// double quoted strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\tcss: 'string' },\t\t\t// single quoted strings\n\t\t\t{ regex: /\\$\\w+/g,\t\t\t\t\t\t\t\t\t\t\tcss: 'variable' },\t\t\t// variables\n\t\t\t{ regex: new RegExp(this.getKeywords(funcs), 'gmi'),\t\tcss: 'functions' },\t\t\t// common functions\n\t\t\t{ regex: new RegExp(this.getKeywords(constants), 'gmi'),\tcss: 'constants' },\t\t\t// constants\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\t\tcss: 'keyword' }\t\t\t// keyword\n\t\t\t];\n\n\t\tthis.forHtmlScript(SyntaxHighlighter.regexLib.phpScriptTags);\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['php'];\n\n\tSyntaxHighlighter.brushes.Php = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['text', 'plain'];\n\n\tSyntaxHighlighter.brushes.Plain = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\t// Contributed by Joel 'Jaykul' Bennett, http://PoshCode.org | http://HuddledMasses.org\n\t\tvar keywords =\t'while validateset validaterange validatepattern validatelength validatecount ' +\n\t\t\t\t\t\t'until trap switch return ref process param parameter in if global: '+\n\t\t\t\t\t\t'function foreach for finally filter end elseif else dynamicparam do default ' +\n\t\t\t\t\t\t'continue cmdletbinding break begin alias \\\\? % #script #private #local #global '+\n\t\t\t\t\t\t'mandatory parametersetname position valuefrompipeline ' +\n\t\t\t\t\t\t'valuefrompipelinebypropertyname valuefromremainingarguments helpmessage ';\n\n\t\tvar operators =\t' and as band bnot bor bxor casesensitive ccontains ceq cge cgt cle ' +\n\t\t\t\t\t\t'clike clt cmatch cne cnotcontains cnotlike cnotmatch contains ' +\n\t\t\t\t\t\t'creplace eq exact f file ge gt icontains ieq ige igt ile ilike ilt ' +\n\t\t\t\t\t\t'imatch ine inotcontains inotlike inotmatch ireplace is isnot le like ' +\n\t\t\t\t\t\t'lt match ne not notcontains notlike notmatch or regex replace wildcard';\n\t\t\t\t\t\t\n\t\tvar verbs =\t\t'write where wait use update unregister undo trace test tee take suspend ' +\n\t\t\t\t\t\t'stop start split sort skip show set send select scroll resume restore ' +\n\t\t\t\t\t\t'restart resolve resize reset rename remove register receive read push ' +\n\t\t\t\t\t\t'pop ping out new move measure limit join invoke import group get format ' +\n\t\t\t\t\t\t'foreach export expand exit enter enable disconnect disable debug cxnew ' +\n\t\t\t\t\t\t'copy convertto convertfrom convert connect complete compare clear ' +\n\t\t\t\t\t\t'checkpoint aggregate add';\n\n\t\t// I can't find a way to match the comment based help in multi-line comments, because SH won't highlight in highlights, and javascript doesn't support lookbehind\n\t\tvar commenthelp = ' component description example externalhelp forwardhelpcategory forwardhelptargetname forwardhelptargetname functionality inputs link notes outputs parameter remotehelprunspace role synopsis';\n\n\t\tthis.regexList = [\n\t\t\t{ regex: new RegExp('^\\\\s*#[#\\\\s]*\\\\.('+this.getKeywords(commenthelp)+').*$', 'gim'),\t\t\tcss: 'preprocessor help bold' },\t\t// comment-based help\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleLinePerlComments,\t\t\t\t\t\t\t\t\t\tcss: 'comments' },\t\t\t\t\t\t// one line comments\n\t\t\t{ regex: /(&lt;|<)#[\\s\\S]*?#(&gt;|>)/gm,\t\t\t\t\t\t\t\t\t\t\t\t\t\tcss: 'comments here' },\t\t\t\t\t// multi-line comments\n\t\t\t\n\t\t\t{ regex: new RegExp('@\"\\\\n[\\\\s\\\\S]*?\\\\n\"@', 'gm'),\t\t\t\t\t\t\t\t\t\t\t\tcss: 'script string here' },\t\t\t// double quoted here-strings\n\t\t\t{ regex: new RegExp(\"@'\\\\n[\\\\s\\\\S]*?\\\\n'@\", 'gm'),\t\t\t\t\t\t\t\t\t\t\t\tcss: 'script string single here' },\t\t// single quoted here-strings\n\t\t\t{ regex: new RegExp('\"(?:\\\\$\\\\([^\\\\)]*\\\\)|[^\"]|`\"|\"\")*[^`]\"','g'),\t\t\t\t\t\t\t\tcss: 'string' },\t\t\t\t\t\t// double quoted strings\n\t\t\t{ regex: new RegExp(\"'(?:[^']|'')*'\", 'g'),\t\t\t\t\t\t\t\t\t\t\t\t\t\tcss: 'string single' },\t\t\t\t\t// single quoted strings\n\t\t\t\n\t\t\t{ regex: new RegExp('[\\\\$|@|@@](?:(?:global|script|private|env):)?[A-Z0-9_]+', 'gi'),\t\t\tcss: 'variable' },\t\t\t\t\t\t// $variables\n\t\t\t{ regex: new RegExp('(?:\\\\b'+verbs.replace(/ /g, '\\\\b|\\\\b')+')-[a-zA-Z_][a-zA-Z0-9_]*', 'gmi'),\tcss: 'functions' },\t\t\t\t\t\t// functions and cmdlets\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gmi'),\t\t\t\t\t\t\t\t\t\t\tcss: 'keyword' },\t\t\t\t\t\t// keywords\n\t\t\t{ regex: new RegExp('-'+this.getKeywords(operators), 'gmi'),\t\t\t\t\t\t\t\t\tcss: 'operator value' },\t\t\t\t// operators\n\t\t\t{ regex: new RegExp('\\\\[[A-Z_\\\\[][A-Z0-9_. `,\\\\[\\\\]]*\\\\]', 'gi'),\t\t\t\t\t\t\t\tcss: 'constants' },\t\t\t\t\t\t// .Net [Type]s\n\t\t\t{ regex: new RegExp('\\\\s+-(?!'+this.getKeywords(operators)+')[a-zA-Z_][a-zA-Z0-9_]*', 'gmi'),\tcss: 'color1' },\t\t\t\t\t\t// parameters\t  \n\t\t];\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['powershell', 'ps', 'posh'];\n\n\tSyntaxHighlighter.brushes.PowerShell = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\t// Contributed by Gheorghe Milas and Ahmad Sherif\n\t\n\t\tvar keywords =  'and assert break class continue def del elif else ' +\n\t\t\t\t\t\t'except exec finally for from global if import in is ' +\n\t\t\t\t\t\t'lambda not or pass print raise return try yield while';\n\n\t\tvar funcs = '__import__ abs all any apply basestring bin bool buffer callable ' +\n\t\t\t\t\t'chr classmethod cmp coerce compile complex delattr dict dir ' +\n\t\t\t\t\t'divmod enumerate eval execfile file filter float format frozenset ' +\n\t\t\t\t\t'getattr globals hasattr hash help hex id input int intern ' +\n\t\t\t\t\t'isinstance issubclass iter len list locals long map max min next ' +\n\t\t\t\t\t'object oct open ord pow print property range raw_input reduce ' +\n\t\t\t\t\t'reload repr reversed round set setattr slice sorted staticmethod ' +\n\t\t\t\t\t'str sum super tuple type type unichr unicode vars xrange zip';\n\n\t\tvar special =  'None True False self cls class_';\n\n\t\tthis.regexList = [\n\t\t\t\t{ regex: SyntaxHighlighter.regexLib.singleLinePerlComments, css: 'comments' },\n\t\t\t\t{ regex: /^\\s*@\\w+/gm, \t\t\t\t\t\t\t\t\t\tcss: 'decorator' },\n\t\t\t\t{ regex: /(['\\\"]{3})([^\\1])*?\\1/gm, \t\t\t\t\t\tcss: 'comments' },\n\t\t\t\t{ regex: /\"(?!\")(?:\\.|\\\\\\\"|[^\\\"\"\\n])*\"/gm, \t\t\t\t\tcss: 'string' },\n\t\t\t\t{ regex: /'(?!')(?:\\.|(\\\\\\')|[^\\''\\n])*'/gm, \t\t\t\tcss: 'string' },\n\t\t\t\t{ regex: /\\+|\\-|\\*|\\/|\\%|=|==/gm, \t\t\t\t\t\t\tcss: 'keyword' },\n\t\t\t\t{ regex: /\\b\\d+\\.?\\w*/g, \t\t\t\t\t\t\t\t\tcss: 'value' },\n\t\t\t\t{ regex: new RegExp(this.getKeywords(funcs), 'gmi'),\t\tcss: 'functions' },\n\t\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'), \t\tcss: 'keyword' },\n\t\t\t\t{ regex: new RegExp(this.getKeywords(special), 'gm'), \t\tcss: 'color1' }\n\t\t\t\t];\n\t\t\t\n\t\tthis.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['py', 'python'];\n\n\tSyntaxHighlighter.brushes.Python = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\t// Contributed by Erik Peterson.\n\t\n\t\tvar keywords =\t'alias and BEGIN begin break case class def define_method defined do each else elsif ' +\n\t\t\t\t\t\t'END end ensure false for if in module new next nil not or raise redo rescue retry return ' +\n\t\t\t\t\t\t'self super then throw true undef unless until when while yield';\n\n\t\tvar builtins =\t'Array Bignum Binding Class Continuation Dir Exception FalseClass File::Stat File Fixnum Fload ' +\n\t\t\t\t\t\t'Hash Integer IO MatchData Method Module NilClass Numeric Object Proc Range Regexp String Struct::TMS Symbol ' +\n\t\t\t\t\t\t'ThreadGroup Thread Time TrueClass';\n\n\t\tthis.regexList = [\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleLinePerlComments,\tcss: 'comments' },\t\t// one line comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\tcss: 'string' },\t\t// double quoted strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\tcss: 'string' },\t\t// single quoted strings\n\t\t\t{ regex: /\\b[A-Z0-9_]+\\b/g,\t\t\t\t\t\t\t\t\tcss: 'constants' },\t\t// constants\n\t\t\t{ regex: /:[a-z][A-Za-z0-9_]*/g,\t\t\t\t\t\t\tcss: 'color2' },\t\t// symbols\n\t\t\t{ regex: /(\\$|@@|@)\\w+/g,\t\t\t\t\t\t\t\t\tcss: 'variable bold' },\t// $global, @instance, and @@class variables\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\t\tcss: 'keyword' },\t\t// keywords\n\t\t\t{ regex: new RegExp(this.getKeywords(builtins), 'gm'),\t\tcss: 'color1' }\t\t\t// builtins\n\t\t\t];\n\n\t\tthis.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['ruby', 'rails', 'ror', 'rb'];\n\n\tSyntaxHighlighter.brushes.Ruby = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\tfunction getKeywordsCSS(str)\n\t\t{\n\t\t\treturn '\\\\b([a-z_]|)' + str.replace(/ /g, '(?=:)\\\\b|\\\\b([a-z_\\\\*]|\\\\*|)') + '(?=:)\\\\b';\n\t\t};\n\t\n\t\tfunction getValuesCSS(str)\n\t\t{\n\t\t\treturn '\\\\b' + str.replace(/ /g, '(?!-)(?!:)\\\\b|\\\\b()') + '\\:\\\\b';\n\t\t};\n\n\t\tvar keywords =\t'ascent azimuth background-attachment background-color background-image background-position ' +\n\t\t\t\t\t\t'background-repeat background baseline bbox border-collapse border-color border-spacing border-style border-top ' +\n\t\t\t\t\t\t'border-right border-bottom border-left border-top-color border-right-color border-bottom-color border-left-color ' +\n\t\t\t\t\t\t'border-top-style border-right-style border-bottom-style border-left-style border-top-width border-right-width ' +\n\t\t\t\t\t\t'border-bottom-width border-left-width border-width border bottom cap-height caption-side centerline clear clip color ' +\n\t\t\t\t\t\t'content counter-increment counter-reset cue-after cue-before cue cursor definition-src descent direction display ' +\n\t\t\t\t\t\t'elevation empty-cells float font-size-adjust font-family font-size font-stretch font-style font-variant font-weight font ' +\n\t\t\t\t\t\t'height left letter-spacing line-height list-style-image list-style-position list-style-type list-style margin-top ' +\n\t\t\t\t\t\t'margin-right margin-bottom margin-left margin marker-offset marks mathline max-height max-width min-height min-width orphans ' +\n\t\t\t\t\t\t'outline-color outline-style outline-width outline overflow padding-top padding-right padding-bottom padding-left padding page ' +\n\t\t\t\t\t\t'page-break-after page-break-before page-break-inside pause pause-after pause-before pitch pitch-range play-during position ' +\n\t\t\t\t\t\t'quotes right richness size slope src speak-header speak-numeral speak-punctuation speak speech-rate stemh stemv stress ' +\n\t\t\t\t\t\t'table-layout text-align top text-decoration text-indent text-shadow text-transform unicode-bidi unicode-range units-per-em ' +\n\t\t\t\t\t\t'vertical-align visibility voice-family volume white-space widows width widths word-spacing x-height z-index';\n\t\t\n\t\tvar values =\t'above absolute all always aqua armenian attr aural auto avoid baseline behind below bidi-override black blink block blue bold bolder '+\n\t\t\t\t\t\t'both bottom braille capitalize caption center center-left center-right circle close-quote code collapse compact condensed '+\n\t\t\t\t\t\t'continuous counter counters crop cross crosshair cursive dashed decimal decimal-leading-zero digits disc dotted double '+\n\t\t\t\t\t\t'embed embossed e-resize expanded extra-condensed extra-expanded fantasy far-left far-right fast faster fixed format fuchsia '+\n\t\t\t\t\t\t'gray green groove handheld hebrew help hidden hide high higher icon inline-table inline inset inside invert italic '+\n\t\t\t\t\t\t'justify landscape large larger left-side left leftwards level lighter lime line-through list-item local loud lower-alpha '+\n\t\t\t\t\t\t'lowercase lower-greek lower-latin lower-roman lower low ltr marker maroon medium message-box middle mix move narrower '+\n\t\t\t\t\t\t'navy ne-resize no-close-quote none no-open-quote no-repeat normal nowrap n-resize nw-resize oblique olive once open-quote outset '+\n\t\t\t\t\t\t'outside overline pointer portrait pre print projection purple red relative repeat repeat-x repeat-y rgb ridge right right-side '+\n\t\t\t\t\t\t'rightwards rtl run-in screen scroll semi-condensed semi-expanded separate se-resize show silent silver slower slow '+\n\t\t\t\t\t\t'small small-caps small-caption smaller soft solid speech spell-out square s-resize static status-bar sub super sw-resize '+\n\t\t\t\t\t\t'table-caption table-cell table-column table-column-group table-footer-group table-header-group table-row table-row-group teal '+\n\t\t\t\t\t\t'text-bottom text-top thick thin top transparent tty tv ultra-condensed ultra-expanded underline upper-alpha uppercase upper-latin '+\n\t\t\t\t\t\t'upper-roman url visible wait white wider w-resize x-fast x-high x-large x-loud x-low x-slow x-small x-soft xx-large xx-small yellow';\n\t\t\n\t\tvar fonts =\t\t'[mM]onospace [tT]ahoma [vV]erdana [aA]rial [hH]elvetica [sS]ans-serif [sS]erif [cC]ourier mono sans serif';\n\t\t\n\t\tvar statements\t\t= '!important !default';\n\t\tvar preprocessor\t= '@import @extend @debug @warn @if @for @while @mixin @include';\n\t\t\n\t\tvar r = SyntaxHighlighter.regexLib;\n\t\t\n\t\tthis.regexList = [\n\t\t\t{ regex: r.multiLineCComments,\t\t\t\t\t\t\t\tcss: 'comments' },\t\t// multiline comments\n\t\t\t{ regex: r.singleLineCComments,\t\t\t\t\t\t\t\tcss: 'comments' },\t\t// singleline comments\n\t\t\t{ regex: r.doubleQuotedString,\t\t\t\t\t\t\t\tcss: 'string' },\t\t// double quoted strings\n\t\t\t{ regex: r.singleQuotedString,\t\t\t\t\t\t\t\tcss: 'string' },\t\t// single quoted strings\n\t\t\t{ regex: /\\#[a-fA-F0-9]{3,6}/g,\t\t\t\t\t\t\t\tcss: 'value' },\t\t\t// html colors\n\t\t\t{ regex: /\\b(-?\\d+)(\\.\\d+)?(px|em|pt|\\:|\\%|)\\b/g,\t\t\tcss: 'value' },\t\t\t// sizes\n\t\t\t{ regex: /\\$\\w+/g,\t\t\t\t\t\t\t\t\t\t\tcss: 'variable' },\t\t// variables\n\t\t\t{ regex: new RegExp(this.getKeywords(statements), 'g'),\t\tcss: 'color3' },\t\t// statements\n\t\t\t{ regex: new RegExp(this.getKeywords(preprocessor), 'g'),\tcss: 'preprocessor' },\t// preprocessor\n\t\t\t{ regex: new RegExp(getKeywordsCSS(keywords), 'gm'),\t\tcss: 'keyword' },\t\t// keywords\n\t\t\t{ regex: new RegExp(getValuesCSS(values), 'g'),\t\t\t\tcss: 'value' },\t\t\t// values\n\t\t\t{ regex: new RegExp(this.getKeywords(fonts), 'g'),\t\t\tcss: 'color1' }\t\t\t// fonts\n\t\t\t];\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['sass', 'scss'];\n\n\tSyntaxHighlighter.brushes.Sass = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\t// Contributed by Yegor Jbanov and David Bernard.\n\t\n\t\tvar keywords =\t'val sealed case def true trait implicit forSome import match object null finally super ' +\n\t\t\t\t\t\t'override try lazy for var catch throw type extends class while with new final yield abstract ' +\n\t\t\t\t\t\t'else do if return protected private this package false';\n\n\t\tvar keyops =\t'[_:=><%#@]+';\n\n\t\tthis.regexList = [\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleLineCComments,\t\t\tcss: 'comments' },\t// one line comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.multiLineCComments,\t\t\t\tcss: 'comments' },\t// multiline comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.multiLineSingleQuotedString,\tcss: 'string' },\t// multi-line strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.multiLineDoubleQuotedString,    css: 'string' },\t// double-quoted string\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\t\t\tcss: 'string' },\t// strings\n\t\t\t{ regex: /0x[a-f0-9]+|\\d+(\\.\\d+)?/gi,\t\t\t\t\t\t\t\tcss: 'value' },\t\t// numbers\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\t\t\t\tcss: 'keyword' },\t// keywords\n\t\t\t{ regex: new RegExp(keyops, 'gm'),\t\t\t\t\t\t\t\t\tcss: 'keyword' }\t// scala keyword\n\t\t\t];\n\t}\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['scala'];\n\n\tSyntaxHighlighter.brushes.Scala = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\tvar funcs\t=\t'abs avg case cast coalesce convert count current_timestamp ' +\n\t\t\t\t\t\t'current_user day isnull left lower month nullif replace right ' +\n\t\t\t\t\t\t'session_user space substring sum system_user upper user year';\n\n\t\tvar keywords =\t'absolute action add after alter as asc at authorization begin bigint ' +\n\t\t\t\t\t\t'binary bit by cascade char character check checkpoint close collate ' +\n\t\t\t\t\t\t'column commit committed connect connection constraint contains continue ' +\n\t\t\t\t\t\t'create cube current current_date current_time cursor database date ' +\n\t\t\t\t\t\t'deallocate dec decimal declare default delete desc distinct double drop ' +\n\t\t\t\t\t\t'dynamic else end end-exec escape except exec execute false fetch first ' +\n\t\t\t\t\t\t'float for force foreign forward free from full function global goto grant ' +\n\t\t\t\t\t\t'group grouping having hour ignore index inner insensitive insert instead ' +\n\t\t\t\t\t\t'int integer intersect into is isolation key last level load local max min ' +\n\t\t\t\t\t\t'minute modify move name national nchar next no numeric of off on only ' +\n\t\t\t\t\t\t'open option order out output partial password precision prepare primary ' +\n\t\t\t\t\t\t'prior privileges procedure public read real references relative repeatable ' +\n\t\t\t\t\t\t'restrict return returns revoke rollback rollup rows rule schema scroll ' +\n\t\t\t\t\t\t'second section select sequence serializable set size smallint static ' +\n\t\t\t\t\t\t'statistics table temp temporary then time timestamp to top transaction ' +\n\t\t\t\t\t\t'translation trigger true truncate uncommitted union unique update values ' +\n\t\t\t\t\t\t'varchar varying view when where with work';\n\n\t\tvar operators =\t'all and any between cross in join like not null or outer some';\n\n\t\tthis.regexList = [\n\t\t\t{ regex: /--(.*)$/gm,\t\t\t\t\t\t\t\t\t\t\t\tcss: 'comments' },\t\t\t// one line and multiline comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.multiLineDoubleQuotedString,\tcss: 'string' },\t\t\t// double quoted strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.multiLineSingleQuotedString,\tcss: 'string' },\t\t\t// single quoted strings\n\t\t\t{ regex: new RegExp(this.getKeywords(funcs), 'gmi'),\t\t\t\tcss: 'color2' },\t\t\t// functions\n\t\t\t{ regex: new RegExp(this.getKeywords(operators), 'gmi'),\t\t\tcss: 'color1' },\t\t\t// operators and such\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gmi'),\t\t\t\tcss: 'keyword' }\t\t\t// keyword\n\t\t\t];\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['sql'];\n\n\tSyntaxHighlighter.brushes.Sql = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\tvar keywords =\t'AddHandler AddressOf AndAlso Alias And Ansi As Assembly Auto ' +\n\t\t\t\t\t\t'Boolean ByRef Byte ByVal Call Case Catch CBool CByte CChar CDate ' +\n\t\t\t\t\t\t'CDec CDbl Char CInt Class CLng CObj Const CShort CSng CStr CType ' +\n\t\t\t\t\t\t'Date Decimal Declare Default Delegate Dim DirectCast Do Double Each ' +\n\t\t\t\t\t\t'Else ElseIf End Enum Erase Error Event Exit False Finally For Friend ' +\n\t\t\t\t\t\t'Function Get GetType GoSub GoTo Handles If Implements Imports In ' +\n\t\t\t\t\t\t'Inherits Integer Interface Is Let Lib Like Long Loop Me Mod Module ' +\n\t\t\t\t\t\t'MustInherit MustOverride MyBase MyClass Namespace New Next Not Nothing ' +\n\t\t\t\t\t\t'NotInheritable NotOverridable Object On Option Optional Or OrElse ' +\n\t\t\t\t\t\t'Overloads Overridable Overrides ParamArray Preserve Private Property ' +\n\t\t\t\t\t\t'Protected Public RaiseEvent ReadOnly ReDim REM RemoveHandler Resume ' +\n\t\t\t\t\t\t'Return Select Set Shadows Shared Short Single Static Step Stop String ' +\n\t\t\t\t\t\t'Structure Sub SyncLock Then Throw To True Try TypeOf Unicode Until ' +\n\t\t\t\t\t\t'Variant When While With WithEvents WriteOnly Xor';\n\n\t\tthis.regexList = [\n\t\t\t{ regex: /'.*$/gm,\t\t\t\t\t\t\t\t\t\tcss: 'comments' },\t\t\t// one line comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\tcss: 'string' },\t\t\t// strings\n\t\t\t{ regex: /^\\s*#.*$/gm,\t\t\t\t\t\t\t\t\tcss: 'preprocessor' },\t\t// preprocessor tags like #region and #endregion\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\tcss: 'keyword' }\t\t\t// vb keyword\n\t\t\t];\n\n\t\tthis.forHtmlScript(SyntaxHighlighter.regexLib.aspScriptTags);\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['vb', 'vbnet'];\n\n\tSyntaxHighlighter.brushes.Vb = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n;(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\tfunction process(match, regexInfo)\n\t\t{\n\t\t\tvar constructor = SyntaxHighlighter.Match,\n\t\t\t\tcode = match[0],\n\t\t\t\ttag = new XRegExp('(&lt;|<)[\\\\s\\\\/\\\\?]*(?<name>[:\\\\w-\\\\.]+)', 'xg').exec(code),\n\t\t\t\tresult = []\n\t\t\t\t;\n\t\t\n\t\t\tif (match.attributes != null) \n\t\t\t{\n\t\t\t\tvar attributes,\n\t\t\t\t\tregex = new XRegExp('(?<name> [\\\\w:\\\\-\\\\.]+)' +\n\t\t\t\t\t\t\t\t\t\t'\\\\s*=\\\\s*' +\n\t\t\t\t\t\t\t\t\t\t'(?<value> \".*?\"|\\'.*?\\'|\\\\w+)',\n\t\t\t\t\t\t\t\t\t\t'xg');\n\n\t\t\t\twhile ((attributes = regex.exec(code)) != null) \n\t\t\t\t{\n\t\t\t\t\tresult.push(new constructor(attributes.name, match.index + attributes.index, 'color1'));\n\t\t\t\t\tresult.push(new constructor(attributes.value, match.index + attributes.index + attributes[0].indexOf(attributes.value), 'string'));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (tag != null)\n\t\t\t\tresult.push(\n\t\t\t\t\tnew constructor(tag.name, match.index + tag[0].indexOf(tag.name), 'keyword')\n\t\t\t\t);\n\n\t\t\treturn result;\n\t\t}\n\t\n\t\tthis.regexList = [\n\t\t\t{ regex: new XRegExp('(\\\\&lt;|<)\\\\!\\\\[[\\\\w\\\\s]*?\\\\[(.|\\\\s)*?\\\\]\\\\](\\\\&gt;|>)', 'gm'),\t\t\tcss: 'color2' },\t// <![ ... [ ... ]]>\n\t\t\t{ regex: SyntaxHighlighter.regexLib.xmlComments,\t\t\t\t\t\t\t\t\t\t\t\tcss: 'comments' },\t// <!-- ... -->\n\t\t\t{ regex: new XRegExp('(&lt;|<)[\\\\s\\\\/\\\\?]*(\\\\w+)(?<attributes>.*?)[\\\\s\\\\/\\\\?]*(&gt;|>)', 'sg'), func: process }\n\t\t];\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['xml', 'xhtml', 'xslt', 'html'];\n\n\tSyntaxHighlighter.brushes.Xml = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n"
  },
  {
    "path": "public/static/ueditor/third-party/SyntaxHighlighter/shCoreDefault.css",
    "content": ".syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter,.syntaxhighlighter td,.syntaxhighlighter tr,.syntaxhighlighter tbody,.syntaxhighlighter thead,.syntaxhighlighter caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0!important;-webkit-border-radius:0 0 0 0!important;background:none!important;border:0!important;bottom:auto!important;float:none!important;left:auto!important;line-height:1.1em!important;margin:0!important;outline:0!important;overflow:visible!important;padding:0!important;position:static!important;right:auto!important;text-align:left!important;top:auto!important;vertical-align:baseline!important;width:auto!important;box-sizing:content-box!important;font-family:Monaco,Menlo,Consolas,\"Courier New\",monospace;font-weight:normal!important;font-style:normal!important;min-height:inherit!important;min-height:auto!important;font-size:13px!important}.syntaxhighlighter{width:100%!important;margin:.3em 0 .3em 0!important;position:relative!important;overflow:auto!important;background-color:#f5f5f5!important;border:1px solid #ccc!important;border-radius:4px!important;border-collapse:separate!important}.syntaxhighlighter.source{overflow:hidden!important}.syntaxhighlighter .bold{font-weight:bold!important}.syntaxhighlighter .italic{font-style:italic!important}.syntaxhighlighter .gutter div{white-space:pre!important;word-wrap:normal}.syntaxhighlighter caption{text-align:left!important;padding:.5em 0 .5em 1em!important}.syntaxhighlighter td.code{width:100%!important}.syntaxhighlighter td.code .container{position:relative!important}.syntaxhighlighter td.code .container textarea{box-sizing:border-box!important;position:absolute!important;left:0!important;top:0!important;width:100%!important;border:none!important;background:white!important;padding-left:1em!important;overflow:hidden!important;white-space:pre!important}.syntaxhighlighter td.gutter .line{text-align:right!important;padding:0 .5em 0 1em!important}.syntaxhighlighter td.code .line{padding:0 1em!important}.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0!important}.syntaxhighlighter.show{display:block!important}.syntaxhighlighter.collapsed table{display:none!important}.syntaxhighlighter.collapsed .toolbar{padding:.1em .8em 0 .8em!important;font-size:1em!important;position:static!important;width:auto!important}.syntaxhighlighter.collapsed .toolbar span{display:inline!important;margin-right:1em!important}.syntaxhighlighter.collapsed .toolbar span a{padding:0!important;display:none!important}.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline!important}.syntaxhighlighter .toolbar{position:absolute!important;right:1px!important;top:1px!important;width:11px!important;height:11px!important;font-size:10px!important;z-index:10!important}.syntaxhighlighter .toolbar span.title{display:inline!important}.syntaxhighlighter .toolbar a{display:block!important;text-align:center!important;text-decoration:none!important;padding-top:1px!important}.syntaxhighlighter .toolbar a.expandSource{display:none!important}.syntaxhighlighter.ie{font-size:.9em!important;padding:1px 0 1px 0!important}.syntaxhighlighter.ie .toolbar{line-height:8px!important}.syntaxhighlighter.ie .toolbar a{padding-top:0!important}.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none!important}.syntaxhighlighter.printing .line .number{color:#bbb!important}.syntaxhighlighter.printing .line .content{color:black!important}.syntaxhighlighter.printing .toolbar{display:none!important}.syntaxhighlighter.printing a{text-decoration:none!important}.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black!important}.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200!important}.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue!important}.syntaxhighlighter.printing .keyword{color:#ff7800!important;font-weight:bold!important}.syntaxhighlighter.printing .preprocessor{color:gray!important}.syntaxhighlighter.printing .variable{color:#a70!important}.syntaxhighlighter.printing .value{color:#090!important}.syntaxhighlighter.printing .functions{color:#ff1493!important}.syntaxhighlighter.printing .constants{color:#06c!important}.syntaxhighlighter.printing .script{font-weight:bold!important}.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray!important}.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493!important}.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red!important}.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black!important}.syntaxhighlighter{background-color:#f5f5f5!important}.syntaxhighlighter .line.highlighted.number{color:black!important}.syntaxhighlighter caption{color:black!important}.syntaxhighlighter .gutter{color:#afafaf!important;background-color:#f7f7f9!important;border-right:1px solid #e1e1e8!important;padding:9.5px 0 9.5px 9.5px!important;border-top-left-radius:4px!important;border-bottom-left-radius:4px!important;user-select:none!important;-moz-user-select:none!important;-webkit-user-select:none!important}.syntaxhighlighter .gutter .line.highlighted{background-color:#6ce26c!important;color:white!important}.syntaxhighlighter.printing .line .content{border:none!important}.syntaxhighlighter.collapsed{overflow:visible!important}.syntaxhighlighter.collapsed .toolbar{color:blue!important;background:white!important;border:1px solid #6ce26c!important}.syntaxhighlighter.collapsed .toolbar a{color:blue!important}.syntaxhighlighter.collapsed .toolbar a:hover{color:red!important}.syntaxhighlighter .toolbar{color:white!important;background:#6ce26c!important;border:none!important}.syntaxhighlighter .toolbar a{color:white!important}.syntaxhighlighter .toolbar a:hover{color:black!important}.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:black!important}.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#008200!important}.syntaxhighlighter .string,.syntaxhighlighter .string a{color:blue!important}.syntaxhighlighter .keyword{color:#ff7800!important}.syntaxhighlighter .preprocessor{color:gray!important}.syntaxhighlighter .variable{color:#a70!important}.syntaxhighlighter .value{color:#090!important}.syntaxhighlighter .functions{color:#ff1493!important}.syntaxhighlighter .constants{color:#06c!important}.syntaxhighlighter .script{font-weight:bold!important;color:#ff7800!important;background-color:none!important}.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:gray!important}.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff1493!important}.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:red!important}.syntaxhighlighter .keyword{font-weight:bold!important}"
  },
  {
    "path": "public/static/ueditor/third-party/codemirror/codemirror.css",
    "content": ".CodeMirror {\n    line-height: 1em;\n    font-family: monospace;\n}\n\n.CodeMirror-scroll {\n    overflow: auto;\n    height: 300px;\n    /* This is needed to prevent an IE[67] bug where the scrolled content\n       is visible outside of the scrolling box. */\n    position: relative;\n}\n\n.CodeMirror-gutter {\n    position: absolute; left: 0; top: 0;\n    z-index: 10;\n    background-color: #f7f7f7;\n    border-right: 1px solid #eee;\n    min-width: 2em;\n    height: 100%;\n}\n.CodeMirror-gutter-text {\n    color: #aaa;\n    text-align: right;\n    padding: .4em .2em .4em .4em;\n    white-space: pre !important;\n}\n.CodeMirror-lines {\n    padding: .4em;\n}\n\n.CodeMirror pre {\n    -moz-border-radius: 0;\n    -webkit-border-radius: 0;\n    -o-border-radius: 0;\n    border-radius: 0;\n    border-width: 0; margin: 0; padding: 0; background: transparent;\n    font-family: inherit;\n    font-size: inherit;\n    padding: 0; margin: 0;\n    white-space: pre;\n    word-wrap: normal;\n}\n\n.CodeMirror-wrap pre {\n    word-wrap: break-word;\n    white-space: pre-wrap;\n}\n.CodeMirror-wrap .CodeMirror-scroll {\n    overflow-x: hidden;\n}\n\n.CodeMirror textarea {\n    outline: none !important;\n}\n\n.CodeMirror pre.CodeMirror-cursor {\n    z-index: 10;\n    position: absolute;\n    visibility: hidden;\n    border-left: 1px solid black;\n}\n.CodeMirror-focused pre.CodeMirror-cursor {\n    visibility: visible;\n}\n\nspan.CodeMirror-selected { background: #d9d9d9; }\n.CodeMirror-focused span.CodeMirror-selected { background: #d2dcf8; }\n\n.CodeMirror-searching {background: #ffa;}\n\n/* Default theme */\n\n.cm-s-default span.cm-keyword {color: #708;}\n.cm-s-default span.cm-atom {color: #219;}\n.cm-s-default span.cm-number {color: #164;}\n.cm-s-default span.cm-def {color: #00f;}\n.cm-s-default span.cm-variable {color: black;}\n.cm-s-default span.cm-variable-2 {color: #05a;}\n.cm-s-default span.cm-variable-3 {color: #085;}\n.cm-s-default span.cm-property {color: black;}\n.cm-s-default span.cm-operator {color: black;}\n.cm-s-default span.cm-comment {color: #a50;}\n.cm-s-default span.cm-string {color: #a11;}\n.cm-s-default span.cm-string-2 {color: #f50;}\n.cm-s-default span.cm-meta {color: #555;}\n.cm-s-default span.cm-error {color: #f00;}\n.cm-s-default span.cm-qualifier {color: #555;}\n.cm-s-default span.cm-builtin {color: #30a;}\n.cm-s-default span.cm-bracket {color: #cc7;}\n.cm-s-default span.cm-tag {color: #170;}\n.cm-s-default span.cm-attribute {color: #00c;}\n.cm-s-default span.cm-header {color: #a0a;}\n.cm-s-default span.cm-quote {color: #090;}\n.cm-s-default span.cm-hr {color: #999;}\n.cm-s-default span.cm-link {color: #00c;}\n\nspan.cm-header, span.cm-strong {font-weight: bold;}\nspan.cm-em {font-style: italic;}\nspan.cm-emstrong {font-style: italic; font-weight: bold;}\nspan.cm-link {text-decoration: underline;}\n\ndiv.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}\ndiv.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}\n"
  },
  {
    "path": "public/static/ueditor/third-party/codemirror/codemirror.js",
    "content": "// CodeMirror version 2.2\r\n//\r\n// All functions that need access to the editor's state live inside\r\n// the CodeMirror function. Below that, at the bottom of the file,\r\n// some utilities are defined.\r\n\r\n// CodeMirror is the only global var we claim\r\nvar CodeMirror = (function() {\r\n    // This is the function that produces an editor instance. It's\r\n    // closure is used to store the editor state.\r\n    function CodeMirror(place, givenOptions) {\r\n        // Determine effective options based on given values and defaults.\r\n        var options = {}, defaults = CodeMirror.defaults;\r\n        for (var opt in defaults)\r\n            if (defaults.hasOwnProperty(opt))\r\n                options[opt] = (givenOptions && givenOptions.hasOwnProperty(opt) ? givenOptions : defaults)[opt];\r\n\r\n        var targetDocument = options[\"document\"];\r\n        // The element in which the editor lives.\r\n        var wrapper = targetDocument.createElement(\"div\");\r\n        wrapper.className = \"CodeMirror\" + (options.lineWrapping ? \" CodeMirror-wrap\" : \"\");\r\n        // This mess creates the base DOM structure for the editor.\r\n        wrapper.innerHTML =\r\n            '<div style=\"overflow: hidden; position: relative; width: 3px; height: 0px;\">' + // Wraps and hides input textarea\r\n                '<textarea style=\"position: absolute; padding: 0; width: 1px;\" wrap=\"off\" ' +\r\n                'autocorrect=\"off\" autocapitalize=\"off\"></textarea></div>' +\r\n                '<div class=\"CodeMirror-scroll\" tabindex=\"-1\">' +\r\n                '<div style=\"position: relative\">' + // Set to the height of the text, causes scrolling\r\n                '<div style=\"position: relative\">' + // Moved around its parent to cover visible view\r\n                '<div class=\"CodeMirror-gutter\"><div class=\"CodeMirror-gutter-text\"></div></div>' +\r\n                // Provides positioning relative to (visible) text origin\r\n                '<div class=\"CodeMirror-lines\"><div style=\"position: relative\">' +\r\n                '<div style=\"position: absolute; width: 100%; height: 0; overflow: hidden; visibility: hidden\"></div>' +\r\n                '<pre class=\"CodeMirror-cursor\">&#160;</pre>' + // Absolutely positioned blinky cursor\r\n                '<div></div>' + // This DIV contains the actual code\r\n                '</div></div></div></div></div>';\r\n        if (place.appendChild) place.appendChild(wrapper); else place(wrapper);\r\n        // I've never seen more elegant code in my life.\r\n        var inputDiv = wrapper.firstChild, input = inputDiv.firstChild,\r\n            scroller = wrapper.lastChild, code = scroller.firstChild,\r\n            mover = code.firstChild, gutter = mover.firstChild, gutterText = gutter.firstChild,\r\n            lineSpace = gutter.nextSibling.firstChild, measure = lineSpace.firstChild,\r\n            cursor = measure.nextSibling, lineDiv = cursor.nextSibling;\r\n        themeChanged();\r\n        // Needed to hide big blue blinking cursor on Mobile Safari\r\n        if (/AppleWebKit/.test(navigator.userAgent) && /Mobile\\/\\w+/.test(navigator.userAgent)) input.style.width = \"0px\";\r\n        if (!webkit) lineSpace.draggable = true;\r\n        if (options.tabindex != null) input.tabIndex = options.tabindex;\r\n        if (!options.gutter && !options.lineNumbers) gutter.style.display = \"none\";\r\n\r\n        // Check for problem with IE innerHTML not working when we have a\r\n        // P (or similar) parent node.\r\n        try { stringWidth(\"x\"); }\r\n        catch (e) {\r\n            if (e.message.match(/runtime/i))\r\n                e = new Error(\"A CodeMirror inside a P-style element does not work in Internet Explorer. (innerHTML bug)\");\r\n            throw e;\r\n        }\r\n\r\n        // Delayed object wrap timeouts, making sure only one is active. blinker holds an interval.\r\n        var poll = new Delayed(), highlight = new Delayed(), blinker;\r\n\r\n        // mode holds a mode API object. doc is the tree of Line objects,\r\n        // work an array of lines that should be parsed, and history the\r\n        // undo history (instance of History constructor).\r\n        var mode, doc = new BranchChunk([new LeafChunk([new Line(\"\")])]), work, focused;\r\n        loadMode();\r\n        // The selection. These are always maintained to point at valid\r\n        // positions. Inverted is used to remember that the user is\r\n        // selecting bottom-to-top.\r\n        var sel = {from: {line: 0, ch: 0}, to: {line: 0, ch: 0}, inverted: false};\r\n        // Selection-related flags. shiftSelecting obviously tracks\r\n        // whether the user is holding shift.\r\n        var shiftSelecting, lastClick, lastDoubleClick, draggingText, overwrite = false;\r\n        // Variables used by startOperation/endOperation to track what\r\n        // happened during the operation.\r\n        var updateInput, userSelChange, changes, textChanged, selectionChanged, leaveInputAlone,\r\n            gutterDirty, callbacks;\r\n        // Current visible range (may be bigger than the view window).\r\n        var displayOffset = 0, showingFrom = 0, showingTo = 0, lastSizeC = 0;\r\n        // bracketHighlighted is used to remember that a backet has been\r\n        // marked.\r\n        var bracketHighlighted;\r\n        // Tracks the maximum line length so that the horizontal scrollbar\r\n        // can be kept static when scrolling.\r\n        var maxLine = \"\", maxWidth, tabText = computeTabText();\r\n\r\n        // Initialize the content.\r\n        operation(function(){setValue(options.value || \"\"); updateInput = false;})();\r\n        var history = new History();\r\n\r\n        // Register our event handlers.\r\n        connect(scroller, \"mousedown\", operation(onMouseDown));\r\n        connect(scroller, \"dblclick\", operation(onDoubleClick));\r\n        connect(lineSpace, \"dragstart\", onDragStart);\r\n        connect(lineSpace, \"selectstart\", e_preventDefault);\r\n        // Gecko browsers fire contextmenu *after* opening the menu, at\r\n        // which point we can't mess with it anymore. Context menu is\r\n        // handled in onMouseDown for Gecko.\r\n        if (!gecko) connect(scroller, \"contextmenu\", onContextMenu);\r\n        connect(scroller, \"scroll\", function() {\r\n            updateDisplay([]);\r\n            if (options.fixedGutter) gutter.style.left = scroller.scrollLeft + \"px\";\r\n            if (options.onScroll) options.onScroll(instance);\r\n        });\r\n        connect(window, \"resize\", function() {updateDisplay(true);});\r\n        connect(input, \"keyup\", operation(onKeyUp));\r\n        connect(input, \"input\", fastPoll);\r\n        connect(input, \"keydown\", operation(onKeyDown));\r\n        connect(input, \"keypress\", operation(onKeyPress));\r\n        connect(input, \"focus\", onFocus);\r\n        connect(input, \"blur\", onBlur);\r\n\r\n        connect(scroller, \"dragenter\", e_stop);\r\n        connect(scroller, \"dragover\", e_stop);\r\n        connect(scroller, \"drop\", operation(onDrop));\r\n        connect(scroller, \"paste\", function(){focusInput(); fastPoll();});\r\n        connect(input, \"paste\", fastPoll);\r\n        connect(input, \"cut\", operation(function(){replaceSelection(\"\");}));\r\n\r\n        // IE throws unspecified error in certain cases, when\r\n        // trying to access activeElement before onload\r\n        var hasFocus; try { hasFocus = (targetDocument.activeElement == input); } catch(e) { }\r\n        if (hasFocus) setTimeout(onFocus, 20);\r\n        else onBlur();\r\n\r\n        function isLine(l) {return l >= 0 && l < doc.size;}\r\n        // The instance object that we'll return. Mostly calls out to\r\n        // local functions in the CodeMirror function. Some do some extra\r\n        // range checking and/or clipping. operation is used to wrap the\r\n        // call so that changes it makes are tracked, and the display is\r\n        // updated afterwards.\r\n        var instance = wrapper.CodeMirror = {\r\n            getValue: getValue,\r\n            setValue: operation(setValue),\r\n            getSelection: getSelection,\r\n            replaceSelection: operation(replaceSelection),\r\n            focus: function(){focusInput(); onFocus(); fastPoll();},\r\n            setOption: function(option, value) {\r\n                var oldVal = options[option];\r\n                options[option] = value;\r\n                if (option == \"mode\" || option == \"indentUnit\") loadMode();\r\n                else if (option == \"readOnly\" && value) {onBlur(); input.blur();}\r\n                else if (option == \"theme\") themeChanged();\r\n                else if (option == \"lineWrapping\" && oldVal != value) operation(wrappingChanged)();\r\n                else if (option == \"tabSize\") operation(tabsChanged)();\r\n                if (option == \"lineNumbers\" || option == \"gutter\" || option == \"firstLineNumber\" || option == \"theme\")\r\n                    operation(gutterChanged)();\r\n            },\r\n            getOption: function(option) {return options[option];},\r\n            undo: operation(undo),\r\n            redo: operation(redo),\r\n            indentLine: operation(function(n, dir) {\r\n                if (isLine(n)) indentLine(n, dir == null ? \"smart\" : dir ? \"add\" : \"subtract\");\r\n            }),\r\n            indentSelection: operation(indentSelected),\r\n            historySize: function() {return {undo: history.done.length, redo: history.undone.length};},\r\n            clearHistory: function() {history = new History();},\r\n            matchBrackets: operation(function(){matchBrackets(true);}),\r\n            getTokenAt: operation(function(pos) {\r\n                pos = clipPos(pos);\r\n                return getLine(pos.line).getTokenAt(mode, getStateBefore(pos.line), pos.ch);\r\n            }),\r\n            getStateAfter: function(line) {\r\n                line = clipLine(line == null ? doc.size - 1: line);\r\n                return getStateBefore(line + 1);\r\n            },\r\n            cursorCoords: function(start){\r\n                if (start == null) start = sel.inverted;\r\n                return pageCoords(start ? sel.from : sel.to);\r\n            },\r\n            charCoords: function(pos){return pageCoords(clipPos(pos));},\r\n            coordsChar: function(coords) {\r\n                var off = eltOffset(lineSpace);\r\n                return coordsChar(coords.x - off.left, coords.y - off.top);\r\n            },\r\n            markText: operation(markText),\r\n            setBookmark: setBookmark,\r\n            setMarker: operation(addGutterMarker),\r\n            clearMarker: operation(removeGutterMarker),\r\n            setLineClass: operation(setLineClass),\r\n            hideLine: operation(function(h) {return setLineHidden(h, true);}),\r\n            showLine: operation(function(h) {return setLineHidden(h, false);}),\r\n            onDeleteLine: function(line, f) {\r\n                if (typeof line == \"number\") {\r\n                    if (!isLine(line)) return null;\r\n                    line = getLine(line);\r\n                }\r\n                (line.handlers || (line.handlers = [])).push(f);\r\n                return line;\r\n            },\r\n            lineInfo: lineInfo,\r\n            addWidget: function(pos, node, scroll, vert, horiz) {\r\n                pos = localCoords(clipPos(pos));\r\n                var top = pos.yBot, left = pos.x;\r\n                node.style.position = \"absolute\";\r\n                code.appendChild(node);\r\n                if (vert == \"over\") top = pos.y;\r\n                else if (vert == \"near\") {\r\n                    var vspace = Math.max(scroller.offsetHeight, doc.height * textHeight()),\r\n                        hspace = Math.max(code.clientWidth, lineSpace.clientWidth) - paddingLeft();\r\n                    if (pos.yBot + node.offsetHeight > vspace && pos.y > node.offsetHeight)\r\n                        top = pos.y - node.offsetHeight;\r\n                    if (left + node.offsetWidth > hspace)\r\n                        left = hspace - node.offsetWidth;\r\n                }\r\n                node.style.top = (top + paddingTop()) + \"px\";\r\n                node.style.left = node.style.right = \"\";\r\n                if (horiz == \"right\") {\r\n                    left = code.clientWidth - node.offsetWidth;\r\n                    node.style.right = \"0px\";\r\n                } else {\r\n                    if (horiz == \"left\") left = 0;\r\n                    else if (horiz == \"middle\") left = (code.clientWidth - node.offsetWidth) / 2;\r\n                    node.style.left = (left + paddingLeft()) + \"px\";\r\n                }\r\n                if (scroll)\r\n                    scrollIntoView(left, top, left + node.offsetWidth, top + node.offsetHeight);\r\n            },\r\n\r\n            lineCount: function() {return doc.size;},\r\n            clipPos: clipPos,\r\n            getCursor: function(start) {\r\n                if (start == null) start = sel.inverted;\r\n                return copyPos(start ? sel.from : sel.to);\r\n            },\r\n            somethingSelected: function() {return !posEq(sel.from, sel.to);},\r\n            setCursor: operation(function(line, ch, user) {\r\n                if (ch == null && typeof line.line == \"number\") setCursor(line.line, line.ch, user);\r\n                else setCursor(line, ch, user);\r\n            }),\r\n            setSelection: operation(function(from, to, user) {\r\n                (user ? setSelectionUser : setSelection)(clipPos(from), clipPos(to || from));\r\n            }),\r\n            getLine: function(line) {if (isLine(line)) return getLine(line).text;},\r\n            getLineHandle: function(line) {if (isLine(line)) return getLine(line);},\r\n            setLine: operation(function(line, text) {\r\n                if (isLine(line)) replaceRange(text, {line: line, ch: 0}, {line: line, ch: getLine(line).text.length});\r\n            }),\r\n            removeLine: operation(function(line) {\r\n                if (isLine(line)) replaceRange(\"\", {line: line, ch: 0}, clipPos({line: line+1, ch: 0}));\r\n            }),\r\n            replaceRange: operation(replaceRange),\r\n            getRange: function(from, to) {return getRange(clipPos(from), clipPos(to));},\r\n\r\n            execCommand: function(cmd) {return commands[cmd](instance);},\r\n            // Stuff used by commands, probably not much use to outside code.\r\n            moveH: operation(moveH),\r\n            deleteH: operation(deleteH),\r\n            moveV: operation(moveV),\r\n            toggleOverwrite: function() {overwrite = !overwrite;},\r\n\r\n            posFromIndex: function(off) {\r\n                var lineNo = 0, ch;\r\n                doc.iter(0, doc.size, function(line) {\r\n                    var sz = line.text.length + 1;\r\n                    if (sz > off) { ch = off; return true; }\r\n                    off -= sz;\r\n                    ++lineNo;\r\n                });\r\n                return clipPos({line: lineNo, ch: ch});\r\n            },\r\n            indexFromPos: function (coords) {\r\n                if (coords.line < 0 || coords.ch < 0) return 0;\r\n                var index = coords.ch;\r\n                doc.iter(0, coords.line, function (line) {\r\n                    index += line.text.length + 1;\r\n                });\r\n                return index;\r\n            },\r\n\r\n            operation: function(f){return operation(f)();},\r\n            refresh: function(){updateDisplay(true);},\r\n            getInputField: function(){return input;},\r\n            getWrapperElement: function(){return wrapper;},\r\n            getScrollerElement: function(){return scroller;},\r\n            getGutterElement: function(){return gutter;}\r\n        };\r\n\r\n        function getLine(n) { return getLineAt(doc, n); }\r\n        function updateLineHeight(line, height) {\r\n            gutterDirty = true;\r\n            var diff = height - line.height;\r\n            for (var n = line; n; n = n.parent) n.height += diff;\r\n        }\r\n\r\n        function setValue(code) {\r\n            var top = {line: 0, ch: 0};\r\n            updateLines(top, {line: doc.size - 1, ch: getLine(doc.size-1).text.length},\r\n                splitLines(code), top, top);\r\n            updateInput = true;\r\n        }\r\n        function getValue(code) {\r\n            var text = [];\r\n            doc.iter(0, doc.size, function(line) { text.push(line.text); });\r\n            return text.join(\"\\n\");\r\n        }\r\n\r\n        function onMouseDown(e) {\r\n            setShift(e.shiftKey);\r\n            // Check whether this is a click in a widget\r\n            for (var n = e_target(e); n != wrapper; n = n.parentNode)\r\n                if (n.parentNode == code && n != mover) return;\r\n\r\n            // See if this is a click in the gutter\r\n            for (var n = e_target(e); n != wrapper; n = n.parentNode)\r\n                if (n.parentNode == gutterText) {\r\n                    if (options.onGutterClick)\r\n                        options.onGutterClick(instance, indexOf(gutterText.childNodes, n) + showingFrom, e);\r\n                    return e_preventDefault(e);\r\n                }\r\n\r\n            var start = posFromMouse(e);\r\n\r\n            switch (e_button(e)) {\r\n                case 3:\r\n                    if (gecko && !mac) onContextMenu(e);\r\n                    return;\r\n                case 2:\r\n                    if (start) setCursor(start.line, start.ch, true);\r\n                    return;\r\n            }\r\n            // For button 1, if it was clicked inside the editor\r\n            // (posFromMouse returning non-null), we have to adjust the\r\n            // selection.\r\n            if (!start) {if (e_target(e) == scroller) e_preventDefault(e); return;}\r\n\r\n            if (!focused) onFocus();\r\n\r\n            var now = +new Date;\r\n            if (lastDoubleClick && lastDoubleClick.time > now - 400 && posEq(lastDoubleClick.pos, start)) {\r\n                e_preventDefault(e);\r\n                setTimeout(focusInput, 20);\r\n                return selectLine(start.line);\r\n            } else if (lastClick && lastClick.time > now - 400 && posEq(lastClick.pos, start)) {\r\n                lastDoubleClick = {time: now, pos: start};\r\n                e_preventDefault(e);\r\n                return selectWordAt(start);\r\n            } else { lastClick = {time: now, pos: start}; }\r\n\r\n            var last = start, going;\r\n            if (dragAndDrop && !posEq(sel.from, sel.to) &&\r\n                !posLess(start, sel.from) && !posLess(sel.to, start)) {\r\n                // Let the drag handler handle this.\r\n                if (webkit) lineSpace.draggable = true;\r\n                var up = connect(targetDocument, \"mouseup\", operation(function(e2) {\r\n                    if (webkit) lineSpace.draggable = false;\r\n                    draggingText = false;\r\n                    up();\r\n                    if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {\r\n                        e_preventDefault(e2);\r\n                        setCursor(start.line, start.ch, true);\r\n                        focusInput();\r\n                    }\r\n                }), true);\r\n                draggingText = true;\r\n                return;\r\n            }\r\n            e_preventDefault(e);\r\n            setCursor(start.line, start.ch, true);\r\n\r\n            function extend(e) {\r\n                var cur = posFromMouse(e, true);\r\n                if (cur && !posEq(cur, last)) {\r\n                    if (!focused) onFocus();\r\n                    last = cur;\r\n                    setSelectionUser(start, cur);\r\n                    updateInput = false;\r\n                    var visible = visibleLines();\r\n                    if (cur.line >= visible.to || cur.line < visible.from)\r\n                        going = setTimeout(operation(function(){extend(e);}), 150);\r\n                }\r\n            }\r\n\r\n            var move = connect(targetDocument, \"mousemove\", operation(function(e) {\r\n                clearTimeout(going);\r\n                e_preventDefault(e);\r\n                extend(e);\r\n            }), true);\r\n            var up = connect(targetDocument, \"mouseup\", operation(function(e) {\r\n                clearTimeout(going);\r\n                var cur = posFromMouse(e);\r\n                if (cur) setSelectionUser(start, cur);\r\n                e_preventDefault(e);\r\n                focusInput();\r\n                updateInput = true;\r\n                move(); up();\r\n            }), true);\r\n        }\r\n        function onDoubleClick(e) {\r\n            for (var n = e_target(e); n != wrapper; n = n.parentNode)\r\n                if (n.parentNode == gutterText) return e_preventDefault(e);\r\n            var start = posFromMouse(e);\r\n            if (!start) return;\r\n            lastDoubleClick = {time: +new Date, pos: start};\r\n            e_preventDefault(e);\r\n            selectWordAt(start);\r\n        }\r\n        function onDrop(e) {\r\n            e.preventDefault();\r\n            var pos = posFromMouse(e, true), files = e.dataTransfer.files;\r\n            if (!pos || options.readOnly) return;\r\n            if (files && files.length && window.FileReader && window.File) {\r\n                function loadFile(file, i) {\r\n                    var reader = new FileReader;\r\n                    reader.onload = function() {\r\n                        text[i] = reader.result;\r\n                        if (++read == n) {\r\n                            pos = clipPos(pos);\r\n                            operation(function() {\r\n                                var end = replaceRange(text.join(\"\"), pos, pos);\r\n                                setSelectionUser(pos, end);\r\n                            })();\r\n                        }\r\n                    };\r\n                    reader.readAsText(file);\r\n                }\r\n                var n = files.length, text = Array(n), read = 0;\r\n                for (var i = 0; i < n; ++i) loadFile(files[i], i);\r\n            }\r\n            else {\r\n                try {\r\n                    var text = e.dataTransfer.getData(\"Text\");\r\n                    if (text) {\r\n                        var end = replaceRange(text, pos, pos);\r\n                        var curFrom = sel.from, curTo = sel.to;\r\n                        setSelectionUser(pos, end);\r\n                        if (draggingText) replaceRange(\"\", curFrom, curTo);\r\n                        focusInput();\r\n                    }\r\n                }\r\n                catch(e){}\r\n            }\r\n        }\r\n        function onDragStart(e) {\r\n            var txt = getSelection();\r\n            // This will reset escapeElement\r\n            htmlEscape(txt);\r\n            e.dataTransfer.setDragImage(escapeElement, 0, 0);\r\n            e.dataTransfer.setData(\"Text\", txt);\r\n        }\r\n        function handleKeyBinding(e) {\r\n            var name = keyNames[e.keyCode], next = keyMap[options.keyMap].auto, bound, dropShift;\r\n            if (name == null || e.altGraphKey) {\r\n                if (next) options.keyMap = next;\r\n                return null;\r\n            }\r\n            if (e.altKey) name = \"Alt-\" + name;\r\n            if (e.ctrlKey) name = \"Ctrl-\" + name;\r\n            if (e.metaKey) name = \"Cmd-\" + name;\r\n            if (e.shiftKey && (bound = lookupKey(\"Shift-\" + name, options.extraKeys, options.keyMap))) {\r\n                dropShift = true;\r\n            } else {\r\n                bound = lookupKey(name, options.extraKeys, options.keyMap);\r\n            }\r\n            if (typeof bound == \"string\") {\r\n                if (commands.propertyIsEnumerable(bound)) bound = commands[bound];\r\n                else bound = null;\r\n            }\r\n            if (next && (bound || !isModifierKey(e))) options.keyMap = next;\r\n            if (!bound) return false;\r\n            if (dropShift) {\r\n                var prevShift = shiftSelecting;\r\n                shiftSelecting = null;\r\n                bound(instance);\r\n                shiftSelecting = prevShift;\r\n            } else bound(instance);\r\n            e_preventDefault(e);\r\n            return true;\r\n        }\r\n        var lastStoppedKey = null;\r\n        function onKeyDown(e) {\r\n            if (!focused) onFocus();\r\n            var code = e.keyCode;\r\n            // IE does strange things with escape.\r\n            if (ie && code == 27) { e.returnValue = false; }\r\n            setShift(code == 16 || e.shiftKey);\r\n            // First give onKeyEvent option a chance to handle this.\r\n            if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;\r\n            var handled = handleKeyBinding(e);\r\n            if (window.opera) {\r\n                lastStoppedKey = handled ? e.keyCode : null;\r\n                // Opera has no cut event... we try to at least catch the key combo\r\n                if (!handled && (mac ? e.metaKey : e.ctrlKey) && e.keyCode == 88)\r\n                    replaceSelection(\"\");\r\n            }\r\n        }\r\n        function onKeyPress(e) {\r\n            if (window.opera && e.keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}\r\n            if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;\r\n            if (window.opera && !e.which && handleKeyBinding(e)) return;\r\n            if (options.electricChars && mode.electricChars) {\r\n                var ch = String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode);\r\n                if (mode.electricChars.indexOf(ch) > -1)\r\n                    setTimeout(operation(function() {indentLine(sel.to.line, \"smart\");}), 75);\r\n            }\r\n            fastPoll();\r\n        }\r\n        function onKeyUp(e) {\r\n            if (options.onKeyEvent && options.onKeyEvent(instance, addStop(e))) return;\r\n            if (e.keyCode == 16) shiftSelecting = null;\r\n        }\r\n\r\n        function onFocus() {\r\n            if (options.readOnly) return;\r\n            if (!focused) {\r\n                if (options.onFocus) options.onFocus(instance);\r\n                focused = true;\r\n                if (wrapper.className.search(/\\bCodeMirror-focused\\b/) == -1)\r\n                    wrapper.className += \" CodeMirror-focused\";\r\n                if (!leaveInputAlone) resetInput(true);\r\n            }\r\n            slowPoll();\r\n            restartBlink();\r\n        }\r\n        function onBlur() {\r\n            if (focused) {\r\n                if (options.onBlur) options.onBlur(instance);\r\n                focused = false;\r\n                wrapper.className = wrapper.className.replace(\" CodeMirror-focused\", \"\");\r\n            }\r\n            clearInterval(blinker);\r\n            setTimeout(function() {if (!focused) shiftSelecting = null;}, 150);\r\n        }\r\n\r\n        // Replace the range from from to to by the strings in newText.\r\n        // Afterwards, set the selection to selFrom, selTo.\r\n        function updateLines(from, to, newText, selFrom, selTo) {\r\n            if (history) {\r\n                var old = [];\r\n                doc.iter(from.line, to.line + 1, function(line) { old.push(line.text); });\r\n                history.addChange(from.line, newText.length, old);\r\n                while (history.done.length > options.undoDepth) history.done.shift();\r\n            }\r\n            updateLinesNoUndo(from, to, newText, selFrom, selTo);\r\n        }\r\n        function unredoHelper(from, to) {\r\n            var change = from.pop();\r\n            if (change) {\r\n                var replaced = [], end = change.start + change.added;\r\n                doc.iter(change.start, end, function(line) { replaced.push(line.text); });\r\n                to.push({start: change.start, added: change.old.length, old: replaced});\r\n                var pos = clipPos({line: change.start + change.old.length - 1,\r\n                    ch: editEnd(replaced[replaced.length-1], change.old[change.old.length-1])});\r\n                updateLinesNoUndo({line: change.start, ch: 0}, {line: end - 1, ch: getLine(end-1).text.length}, change.old, pos, pos);\r\n                updateInput = true;\r\n            }\r\n        }\r\n        function undo() {unredoHelper(history.done, history.undone);}\r\n        function redo() {unredoHelper(history.undone, history.done);}\r\n\r\n        function updateLinesNoUndo(from, to, newText, selFrom, selTo) {\r\n            var recomputeMaxLength = false, maxLineLength = maxLine.length;\r\n            if (!options.lineWrapping)\r\n                doc.iter(from.line, to.line, function(line) {\r\n                    if (line.text.length == maxLineLength) {recomputeMaxLength = true; return true;}\r\n                });\r\n            if (from.line != to.line || newText.length > 1) gutterDirty = true;\r\n\r\n            var nlines = to.line - from.line, firstLine = getLine(from.line), lastLine = getLine(to.line);\r\n            // First adjust the line structure, taking some care to leave highlighting intact.\r\n            if (from.ch == 0 && to.ch == 0 && newText[newText.length - 1] == \"\") {\r\n                // This is a whole-line replace. Treated specially to make\r\n                // sure line objects move the way they are supposed to.\r\n                var added = [], prevLine = null;\r\n                if (from.line) {\r\n                    prevLine = getLine(from.line - 1);\r\n                    prevLine.fixMarkEnds(lastLine);\r\n                } else lastLine.fixMarkStarts();\r\n                for (var i = 0, e = newText.length - 1; i < e; ++i)\r\n                    added.push(Line.inheritMarks(newText[i], prevLine));\r\n                if (nlines) doc.remove(from.line, nlines, callbacks);\r\n                if (added.length) doc.insert(from.line, added);\r\n            } else if (firstLine == lastLine) {\r\n                if (newText.length == 1)\r\n                    firstLine.replace(from.ch, to.ch, newText[0]);\r\n                else {\r\n                    lastLine = firstLine.split(to.ch, newText[newText.length-1]);\r\n                    firstLine.replace(from.ch, null, newText[0]);\r\n                    firstLine.fixMarkEnds(lastLine);\r\n                    var added = [];\r\n                    for (var i = 1, e = newText.length - 1; i < e; ++i)\r\n                        added.push(Line.inheritMarks(newText[i], firstLine));\r\n                    added.push(lastLine);\r\n                    doc.insert(from.line + 1, added);\r\n                }\r\n            } else if (newText.length == 1) {\r\n                firstLine.replace(from.ch, null, newText[0]);\r\n                lastLine.replace(null, to.ch, \"\");\r\n                firstLine.append(lastLine);\r\n                doc.remove(from.line + 1, nlines, callbacks);\r\n            } else {\r\n                var added = [];\r\n                firstLine.replace(from.ch, null, newText[0]);\r\n                lastLine.replace(null, to.ch, newText[newText.length-1]);\r\n                firstLine.fixMarkEnds(lastLine);\r\n                for (var i = 1, e = newText.length - 1; i < e; ++i)\r\n                    added.push(Line.inheritMarks(newText[i], firstLine));\r\n                if (nlines > 1) doc.remove(from.line + 1, nlines - 1, callbacks);\r\n                doc.insert(from.line + 1, added);\r\n            }\r\n            if (options.lineWrapping) {\r\n                var perLine = scroller.clientWidth / charWidth() - 3;\r\n                doc.iter(from.line, from.line + newText.length, function(line) {\r\n                    if (line.hidden) return;\r\n                    var guess = Math.ceil(line.text.length / perLine) || 1;\r\n                    if (guess != line.height) updateLineHeight(line, guess);\r\n                });\r\n            } else {\r\n                doc.iter(from.line, i + newText.length, function(line) {\r\n                    var l = line.text;\r\n                    if (l.length > maxLineLength) {\r\n                        maxLine = l; maxLineLength = l.length; maxWidth = null;\r\n                        recomputeMaxLength = false;\r\n                    }\r\n                });\r\n                if (recomputeMaxLength) {\r\n                    maxLineLength = 0; maxLine = \"\"; maxWidth = null;\r\n                    doc.iter(0, doc.size, function(line) {\r\n                        var l = line.text;\r\n                        if (l.length > maxLineLength) {\r\n                            maxLineLength = l.length; maxLine = l;\r\n                        }\r\n                    });\r\n                }\r\n            }\r\n\r\n            // Add these lines to the work array, so that they will be\r\n            // highlighted. Adjust work lines if lines were added/removed.\r\n            var newWork = [], lendiff = newText.length - nlines - 1;\r\n            for (var i = 0, l = work.length; i < l; ++i) {\r\n                var task = work[i];\r\n                if (task < from.line) newWork.push(task);\r\n                else if (task > to.line) newWork.push(task + lendiff);\r\n            }\r\n            var hlEnd = from.line + Math.min(newText.length, 500);\r\n            highlightLines(from.line, hlEnd);\r\n            newWork.push(hlEnd);\r\n            work = newWork;\r\n            startWorker(100);\r\n            // Remember that these lines changed, for updating the display\r\n            changes.push({from: from.line, to: to.line + 1, diff: lendiff});\r\n            var changeObj = {from: from, to: to, text: newText};\r\n            if (textChanged) {\r\n                for (var cur = textChanged; cur.next; cur = cur.next) {}\r\n                cur.next = changeObj;\r\n            } else textChanged = changeObj;\r\n\r\n            // Update the selection\r\n            function updateLine(n) {return n <= Math.min(to.line, to.line + lendiff) ? n : n + lendiff;}\r\n            setSelection(selFrom, selTo, updateLine(sel.from.line), updateLine(sel.to.line));\r\n\r\n            // Make sure the scroll-size div has the correct height.\r\n            code.style.height = (doc.height * textHeight() + 2 * paddingTop()) + \"px\";\r\n        }\r\n\r\n        function replaceRange(code, from, to) {\r\n            from = clipPos(from);\r\n            if (!to) to = from; else to = clipPos(to);\r\n            code = splitLines(code);\r\n            function adjustPos(pos) {\r\n                if (posLess(pos, from)) return pos;\r\n                if (!posLess(to, pos)) return end;\r\n                var line = pos.line + code.length - (to.line - from.line) - 1;\r\n                var ch = pos.ch;\r\n                if (pos.line == to.line)\r\n                    ch += code[code.length-1].length - (to.ch - (to.line == from.line ? from.ch : 0));\r\n                return {line: line, ch: ch};\r\n            }\r\n            var end;\r\n            replaceRange1(code, from, to, function(end1) {\r\n                end = end1;\r\n                return {from: adjustPos(sel.from), to: adjustPos(sel.to)};\r\n            });\r\n            return end;\r\n        }\r\n        function replaceSelection(code, collapse) {\r\n            replaceRange1(splitLines(code), sel.from, sel.to, function(end) {\r\n                if (collapse == \"end\") return {from: end, to: end};\r\n                else if (collapse == \"start\") return {from: sel.from, to: sel.from};\r\n                else return {from: sel.from, to: end};\r\n            });\r\n        }\r\n        function replaceRange1(code, from, to, computeSel) {\r\n            var endch = code.length == 1 ? code[0].length + from.ch : code[code.length-1].length;\r\n            var newSel = computeSel({line: from.line + code.length - 1, ch: endch});\r\n            updateLines(from, to, code, newSel.from, newSel.to);\r\n        }\r\n\r\n        function getRange(from, to) {\r\n            var l1 = from.line, l2 = to.line;\r\n            if (l1 == l2) return getLine(l1).text.slice(from.ch, to.ch);\r\n            var code = [getLine(l1).text.slice(from.ch)];\r\n            doc.iter(l1 + 1, l2, function(line) { code.push(line.text); });\r\n            code.push(getLine(l2).text.slice(0, to.ch));\r\n            return code.join(\"\\n\");\r\n        }\r\n        function getSelection() {\r\n            return getRange(sel.from, sel.to);\r\n        }\r\n\r\n        var pollingFast = false; // Ensures slowPoll doesn't cancel fastPoll\r\n        function slowPoll() {\r\n            if (pollingFast) return;\r\n            poll.set(options.pollInterval, function() {\r\n                startOperation();\r\n                readInput();\r\n                if (focused) slowPoll();\r\n                endOperation();\r\n            });\r\n        }\r\n        function fastPoll() {\r\n            var missed = false;\r\n            pollingFast = true;\r\n            function p() {\r\n                startOperation();\r\n                var changed = readInput();\r\n                if (!changed && !missed) {missed = true; poll.set(60, p);}\r\n                else {pollingFast = false; slowPoll();}\r\n                endOperation();\r\n            }\r\n            poll.set(20, p);\r\n        }\r\n\r\n        // Previnput is a hack to work with IME. If we reset the textarea\r\n        // on every change, that breaks IME. So we look for changes\r\n        // compared to the previous content instead. (Modern browsers have\r\n        // events that indicate IME taking place, but these are not widely\r\n        // supported or compatible enough yet to rely on.)\r\n        var prevInput = \"\";\r\n        function readInput() {\r\n            if (leaveInputAlone || !focused || hasSelection(input)) return false;\r\n            var text = input.value;\r\n            if (text == prevInput) return false;\r\n            shiftSelecting = null;\r\n            var same = 0, l = Math.min(prevInput.length, text.length);\r\n            while (same < l && prevInput[same] == text[same]) ++same;\r\n            if (same < prevInput.length)\r\n                sel.from = {line: sel.from.line, ch: sel.from.ch - (prevInput.length - same)};\r\n            else if (overwrite && posEq(sel.from, sel.to))\r\n                sel.to = {line: sel.to.line, ch: Math.min(getLine(sel.to.line).text.length, sel.to.ch + (text.length - same))};\r\n            replaceSelection(text.slice(same), \"end\");\r\n            prevInput = text;\r\n            return true;\r\n        }\r\n        function resetInput(user) {\r\n            if (!posEq(sel.from, sel.to)) {\r\n                prevInput = \"\";\r\n                input.value = getSelection();\r\n                input.select();\r\n            } else if (user) prevInput = input.value = \"\";\r\n        }\r\n\r\n        function focusInput() {\r\n            if (!options.readOnly) input.focus();\r\n        }\r\n\r\n        function scrollEditorIntoView() {\r\n            if (!cursor.getBoundingClientRect) return;\r\n            var rect = cursor.getBoundingClientRect();\r\n            // IE returns bogus coordinates when the instance sits inside of an iframe and the cursor is hidden\r\n            if (ie && rect.top == rect.bottom) return;\r\n            var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);\r\n            if (rect.top < 0 || rect.bottom > winH) cursor.scrollIntoView();\r\n        }\r\n        function scrollCursorIntoView() {\r\n            var cursor = localCoords(sel.inverted ? sel.from : sel.to);\r\n            var x = options.lineWrapping ? Math.min(cursor.x, lineSpace.offsetWidth) : cursor.x;\r\n            return scrollIntoView(x, cursor.y, x, cursor.yBot);\r\n        }\r\n        function scrollIntoView(x1, y1, x2, y2) {\r\n            var pl = paddingLeft(), pt = paddingTop(), lh = textHeight();\r\n            y1 += pt; y2 += pt; x1 += pl; x2 += pl;\r\n            var screen = scroller.clientHeight, screentop = scroller.scrollTop, scrolled = false, result = true;\r\n            if (y1 < screentop) {scroller.scrollTop = Math.max(0, y1 - 2*lh); scrolled = true;}\r\n            else if (y2 > screentop + screen) {scroller.scrollTop = y2 + lh - screen; scrolled = true;}\r\n\r\n            var screenw = scroller.clientWidth, screenleft = scroller.scrollLeft;\r\n            var gutterw = options.fixedGutter ? gutter.clientWidth : 0;\r\n            if (x1 < screenleft + gutterw) {\r\n                if (x1 < 50) x1 = 0;\r\n                scroller.scrollLeft = Math.max(0, x1 - 10 - gutterw);\r\n                scrolled = true;\r\n            }\r\n            else if (x2 > screenw + screenleft - 3) {\r\n                scroller.scrollLeft = x2 + 10 - screenw;\r\n                scrolled = true;\r\n                if (x2 > code.clientWidth) result = false;\r\n            }\r\n            if (scrolled && options.onScroll) options.onScroll(instance);\r\n            return result;\r\n        }\r\n\r\n        function visibleLines() {\r\n            var lh = textHeight(), top = scroller.scrollTop - paddingTop();\r\n            var from_height = Math.max(0, Math.floor(top / lh));\r\n            var to_height = Math.ceil((top + scroller.clientHeight) / lh);\r\n            return {from: lineAtHeight(doc, from_height),\r\n                to: lineAtHeight(doc, to_height)};\r\n        }\r\n        // Uses a set of changes plus the current scroll position to\r\n        // determine which DOM updates have to be made, and makes the\r\n        // updates.\r\n        function updateDisplay(changes, suppressCallback) {\r\n            if (!scroller.clientWidth) {\r\n                showingFrom = showingTo = displayOffset = 0;\r\n                return;\r\n            }\r\n            // Compute the new visible window\r\n            var visible = visibleLines();\r\n            // Bail out if the visible area is already rendered and nothing changed.\r\n            if (changes !== true && changes.length == 0 && visible.from >= showingFrom && visible.to <= showingTo) return;\r\n            var from = Math.max(visible.from - 100, 0), to = Math.min(doc.size, visible.to + 100);\r\n            if (showingFrom < from && from - showingFrom < 20) from = showingFrom;\r\n            if (showingTo > to && showingTo - to < 20) to = Math.min(doc.size, showingTo);\r\n\r\n            // Create a range of theoretically intact lines, and punch holes\r\n            // in that using the change info.\r\n            var intact = changes === true ? [] :\r\n                computeIntact([{from: showingFrom, to: showingTo, domStart: 0}], changes);\r\n            // Clip off the parts that won't be visible\r\n            var intactLines = 0;\r\n            for (var i = 0; i < intact.length; ++i) {\r\n                var range = intact[i];\r\n                if (range.from < from) {range.domStart += (from - range.from); range.from = from;}\r\n                if (range.to > to) range.to = to;\r\n                if (range.from >= range.to) intact.splice(i--, 1);\r\n                else intactLines += range.to - range.from;\r\n            }\r\n            if (intactLines == to - from) return;\r\n            intact.sort(function(a, b) {return a.domStart - b.domStart;});\r\n\r\n            var th = textHeight(), gutterDisplay = gutter.style.display;\r\n            lineDiv.style.display = gutter.style.display = \"none\";\r\n            patchDisplay(from, to, intact);\r\n            lineDiv.style.display = \"\";\r\n\r\n            // Position the mover div to align with the lines it's supposed\r\n            // to be showing (which will cover the visible display)\r\n            var different = from != showingFrom || to != showingTo || lastSizeC != scroller.clientHeight + th;\r\n            // This is just a bogus formula that detects when the editor is\r\n            // resized or the font size changes.\r\n            if (different) lastSizeC = scroller.clientHeight + th;\r\n            showingFrom = from; showingTo = to;\r\n            displayOffset = heightAtLine(doc, from);\r\n            mover.style.top = (displayOffset * th) + \"px\";\r\n            code.style.height = (doc.height * th + 2 * paddingTop()) + \"px\";\r\n\r\n            // Since this is all rather error prone, it is honoured with the\r\n            // only assertion in the whole file.\r\n            if (lineDiv.childNodes.length != showingTo - showingFrom)\r\n                throw new Error(\"BAD PATCH! \" + JSON.stringify(intact) + \" size=\" + (showingTo - showingFrom) +\r\n                    \" nodes=\" + lineDiv.childNodes.length);\r\n\r\n            if (options.lineWrapping) {\r\n                maxWidth = scroller.clientWidth;\r\n                var curNode = lineDiv.firstChild;\r\n                doc.iter(showingFrom, showingTo, function(line) {\r\n                    if (!line.hidden) {\r\n                        var height = Math.round(curNode.offsetHeight / th) || 1;\r\n                        if (line.height != height) {updateLineHeight(line, height); gutterDirty = true;}\r\n                    }\r\n                    curNode = curNode.nextSibling;\r\n                });\r\n            } else {\r\n                if (maxWidth == null) maxWidth = stringWidth(maxLine);\r\n                if (maxWidth > scroller.clientWidth) {\r\n                    lineSpace.style.width = maxWidth + \"px\";\r\n                    // Needed to prevent odd wrapping/hiding of widgets placed in here.\r\n                    code.style.width = \"\";\r\n                    code.style.width = scroller.scrollWidth + \"px\";\r\n                } else {\r\n                    lineSpace.style.width = code.style.width = \"\";\r\n                }\r\n            }\r\n            gutter.style.display = gutterDisplay;\r\n            if (different || gutterDirty) updateGutter();\r\n            updateCursor();\r\n            if (!suppressCallback && options.onUpdate) options.onUpdate(instance);\r\n            return true;\r\n        }\r\n\r\n        function computeIntact(intact, changes) {\r\n            for (var i = 0, l = changes.length || 0; i < l; ++i) {\r\n                var change = changes[i], intact2 = [], diff = change.diff || 0;\r\n                for (var j = 0, l2 = intact.length; j < l2; ++j) {\r\n                    var range = intact[j];\r\n                    if (change.to <= range.from && change.diff)\r\n                        intact2.push({from: range.from + diff, to: range.to + diff,\r\n                            domStart: range.domStart});\r\n                    else if (change.to <= range.from || change.from >= range.to)\r\n                        intact2.push(range);\r\n                    else {\r\n                        if (change.from > range.from)\r\n                            intact2.push({from: range.from, to: change.from, domStart: range.domStart});\r\n                        if (change.to < range.to)\r\n                            intact2.push({from: change.to + diff, to: range.to + diff,\r\n                                domStart: range.domStart + (change.to - range.from)});\r\n                    }\r\n                }\r\n                intact = intact2;\r\n            }\r\n            return intact;\r\n        }\r\n\r\n        function patchDisplay(from, to, intact) {\r\n            // The first pass removes the DOM nodes that aren't intact.\r\n            if (!intact.length) lineDiv.innerHTML = \"\";\r\n            else {\r\n                function killNode(node) {\r\n                    var tmp = node.nextSibling;\r\n                    node.parentNode.removeChild(node);\r\n                    return tmp;\r\n                }\r\n                var domPos = 0, curNode = lineDiv.firstChild, n;\r\n                for (var i = 0; i < intact.length; ++i) {\r\n                    var cur = intact[i];\r\n                    while (cur.domStart > domPos) {curNode = killNode(curNode); domPos++;}\r\n                    for (var j = 0, e = cur.to - cur.from; j < e; ++j) {curNode = curNode.nextSibling; domPos++;}\r\n                }\r\n                while (curNode) curNode = killNode(curNode);\r\n            }\r\n            // This pass fills in the lines that actually changed.\r\n            var nextIntact = intact.shift(), curNode = lineDiv.firstChild, j = from;\r\n            var sfrom = sel.from.line, sto = sel.to.line, inSel = sfrom < from && sto >= from;\r\n            var scratch = targetDocument.createElement(\"div\"), newElt;\r\n            doc.iter(from, to, function(line) {\r\n                var ch1 = null, ch2 = null;\r\n                if (inSel) {\r\n                    ch1 = 0;\r\n                    if (sto == j) {inSel = false; ch2 = sel.to.ch;}\r\n                } else if (sfrom == j) {\r\n                    if (sto == j) {ch1 = sel.from.ch; ch2 = sel.to.ch;}\r\n                    else {inSel = true; ch1 = sel.from.ch;}\r\n                }\r\n                if (nextIntact && nextIntact.to == j) nextIntact = intact.shift();\r\n                if (!nextIntact || nextIntact.from > j) {\r\n                    if (line.hidden) scratch.innerHTML = \"<pre></pre>\";\r\n                    else scratch.innerHTML = line.getHTML(ch1, ch2, true, tabText);\r\n                    lineDiv.insertBefore(scratch.firstChild, curNode);\r\n                } else {\r\n                    curNode = curNode.nextSibling;\r\n                }\r\n                ++j;\r\n            });\r\n        }\r\n\r\n        function updateGutter() {\r\n            if (!options.gutter && !options.lineNumbers) return;\r\n            var hText = mover.offsetHeight, hEditor = scroller.clientHeight;\r\n            gutter.style.height = (hText - hEditor < 2 ? hEditor : hText) + \"px\";\r\n            var html = [], i = showingFrom;\r\n            doc.iter(showingFrom, Math.max(showingTo, showingFrom + 1), function(line) {\r\n                if (line.hidden) {\r\n                    html.push(\"<pre></pre>\");\r\n                } else {\r\n                    var marker = line.gutterMarker;\r\n                    var text = options.lineNumbers ? i + options.firstLineNumber : null;\r\n                    if (marker && marker.text)\r\n                        text = marker.text.replace(\"%N%\", text != null ? text : \"\");\r\n                    else if (text == null)\r\n                        text = \"\\u00a0\";\r\n                    html.push((marker && marker.style ? '<pre class=\"' + marker.style + '\">' : \"<pre>\"), text);\r\n                    for (var j = 1; j < line.height; ++j) html.push(\"<br/>&#160;\");\r\n                    html.push(\"</pre>\");\r\n                }\r\n                ++i;\r\n            });\r\n            gutter.style.display = \"none\";\r\n            gutterText.innerHTML = html.join(\"\");\r\n            var minwidth = String(doc.size).length, firstNode = gutterText.firstChild, val = eltText(firstNode), pad = \"\";\r\n            while (val.length + pad.length < minwidth) pad += \"\\u00a0\";\r\n            if (pad) firstNode.insertBefore(targetDocument.createTextNode(pad), firstNode.firstChild);\r\n            gutter.style.display = \"\";\r\n            lineSpace.style.marginLeft = gutter.offsetWidth + \"px\";\r\n            gutterDirty = false;\r\n        }\r\n        function updateCursor() {\r\n            var head = sel.inverted ? sel.from : sel.to, lh = textHeight();\r\n            var pos = localCoords(head, true);\r\n            var wrapOff = eltOffset(wrapper), lineOff = eltOffset(lineDiv);\r\n            inputDiv.style.top = (pos.y + lineOff.top - wrapOff.top) + \"px\";\r\n            inputDiv.style.left = (pos.x + lineOff.left - wrapOff.left) + \"px\";\r\n            if (posEq(sel.from, sel.to)) {\r\n                cursor.style.top = pos.y + \"px\";\r\n                cursor.style.left = (options.lineWrapping ? Math.min(pos.x, lineSpace.offsetWidth) : pos.x) + \"px\";\r\n                cursor.style.display = \"\";\r\n            }\r\n            else cursor.style.display = \"none\";\r\n        }\r\n\r\n        function setShift(val) {\r\n            if (val) shiftSelecting = shiftSelecting || (sel.inverted ? sel.to : sel.from);\r\n            else shiftSelecting = null;\r\n        }\r\n        function setSelectionUser(from, to) {\r\n            var sh = shiftSelecting && clipPos(shiftSelecting);\r\n            if (sh) {\r\n                if (posLess(sh, from)) from = sh;\r\n                else if (posLess(to, sh)) to = sh;\r\n            }\r\n            setSelection(from, to);\r\n            userSelChange = true;\r\n        }\r\n        // Update the selection. Last two args are only used by\r\n        // updateLines, since they have to be expressed in the line\r\n        // numbers before the update.\r\n        function setSelection(from, to, oldFrom, oldTo) {\r\n            goalColumn = null;\r\n            if (oldFrom == null) {oldFrom = sel.from.line; oldTo = sel.to.line;}\r\n            if (posEq(sel.from, from) && posEq(sel.to, to)) return;\r\n            if (posLess(to, from)) {var tmp = to; to = from; from = tmp;}\r\n\r\n            // Skip over hidden lines.\r\n            if (from.line != oldFrom) from = skipHidden(from, oldFrom, sel.from.ch);\r\n            if (to.line != oldTo) to = skipHidden(to, oldTo, sel.to.ch);\r\n\r\n            if (posEq(from, to)) sel.inverted = false;\r\n            else if (posEq(from, sel.to)) sel.inverted = false;\r\n            else if (posEq(to, sel.from)) sel.inverted = true;\r\n\r\n            // Some ugly logic used to only mark the lines that actually did\r\n            // see a change in selection as changed, rather than the whole\r\n            // selected range.\r\n            if (posEq(from, to)) {\r\n                if (!posEq(sel.from, sel.to))\r\n                    changes.push({from: oldFrom, to: oldTo + 1});\r\n            }\r\n            else if (posEq(sel.from, sel.to)) {\r\n                changes.push({from: from.line, to: to.line + 1});\r\n            }\r\n            else {\r\n                if (!posEq(from, sel.from)) {\r\n                    if (from.line < oldFrom)\r\n                        changes.push({from: from.line, to: Math.min(to.line, oldFrom) + 1});\r\n                    else\r\n                        changes.push({from: oldFrom, to: Math.min(oldTo, from.line) + 1});\r\n                }\r\n                if (!posEq(to, sel.to)) {\r\n                    if (to.line < oldTo)\r\n                        changes.push({from: Math.max(oldFrom, from.line), to: oldTo + 1});\r\n                    else\r\n                        changes.push({from: Math.max(from.line, oldTo), to: to.line + 1});\r\n                }\r\n            }\r\n            sel.from = from; sel.to = to;\r\n            selectionChanged = true;\r\n        }\r\n        function skipHidden(pos, oldLine, oldCh) {\r\n            function getNonHidden(dir) {\r\n                var lNo = pos.line + dir, end = dir == 1 ? doc.size : -1;\r\n                while (lNo != end) {\r\n                    var line = getLine(lNo);\r\n                    if (!line.hidden) {\r\n                        var ch = pos.ch;\r\n                        if (ch > oldCh || ch > line.text.length) ch = line.text.length;\r\n                        return {line: lNo, ch: ch};\r\n                    }\r\n                    lNo += dir;\r\n                }\r\n            }\r\n            var line = getLine(pos.line);\r\n            if (!line.hidden) return pos;\r\n            if (pos.line >= oldLine) return getNonHidden(1) || getNonHidden(-1);\r\n            else return getNonHidden(-1) || getNonHidden(1);\r\n        }\r\n        function setCursor(line, ch, user) {\r\n            var pos = clipPos({line: line, ch: ch || 0});\r\n            (user ? setSelectionUser : setSelection)(pos, pos);\r\n        }\r\n\r\n        function clipLine(n) {return Math.max(0, Math.min(n, doc.size-1));}\r\n        function clipPos(pos) {\r\n            if (pos.line < 0) return {line: 0, ch: 0};\r\n            if (pos.line >= doc.size) return {line: doc.size-1, ch: getLine(doc.size-1).text.length};\r\n            var ch = pos.ch, linelen = getLine(pos.line).text.length;\r\n            if (ch == null || ch > linelen) return {line: pos.line, ch: linelen};\r\n            else if (ch < 0) return {line: pos.line, ch: 0};\r\n            else return pos;\r\n        }\r\n\r\n        function findPosH(dir, unit) {\r\n            var end = sel.inverted ? sel.from : sel.to, line = end.line, ch = end.ch;\r\n            var lineObj = getLine(line);\r\n            function findNextLine() {\r\n                for (var l = line + dir, e = dir < 0 ? -1 : doc.size; l != e; l += dir) {\r\n                    var lo = getLine(l);\r\n                    if (!lo.hidden) { line = l; lineObj = lo; return true; }\r\n                }\r\n            }\r\n            function moveOnce(boundToLine) {\r\n                if (ch == (dir < 0 ? 0 : lineObj.text.length)) {\r\n                    if (!boundToLine && findNextLine()) ch = dir < 0 ? lineObj.text.length : 0;\r\n                    else return false;\r\n                } else ch += dir;\r\n                return true;\r\n            }\r\n            if (unit == \"char\") moveOnce();\r\n            else if (unit == \"column\") moveOnce(true);\r\n            else if (unit == \"word\") {\r\n                var sawWord = false;\r\n                for (;;) {\r\n                    if (dir < 0) if (!moveOnce()) break;\r\n                    if (isWordChar(lineObj.text.charAt(ch))) sawWord = true;\r\n                    else if (sawWord) {if (dir < 0) {dir = 1; moveOnce();} break;}\r\n                    if (dir > 0) if (!moveOnce()) break;\r\n                }\r\n            }\r\n            return {line: line, ch: ch};\r\n        }\r\n        function moveH(dir, unit) {\r\n            var pos = dir < 0 ? sel.from : sel.to;\r\n            if (shiftSelecting || posEq(sel.from, sel.to)) pos = findPosH(dir, unit);\r\n            setCursor(pos.line, pos.ch, true);\r\n        }\r\n        function deleteH(dir, unit) {\r\n            if (!posEq(sel.from, sel.to)) replaceRange(\"\", sel.from, sel.to);\r\n            else if (dir < 0) replaceRange(\"\", findPosH(dir, unit), sel.to);\r\n            else replaceRange(\"\", sel.from, findPosH(dir, unit));\r\n            userSelChange = true;\r\n        }\r\n        var goalColumn = null;\r\n        function moveV(dir, unit) {\r\n            var dist = 0, pos = localCoords(sel.inverted ? sel.from : sel.to, true);\r\n            if (goalColumn != null) pos.x = goalColumn;\r\n            if (unit == \"page\") dist = scroller.clientHeight;\r\n            else if (unit == \"line\") dist = textHeight();\r\n            var target = coordsChar(pos.x, pos.y + dist * dir + 2);\r\n            setCursor(target.line, target.ch, true);\r\n            goalColumn = pos.x;\r\n        }\r\n\r\n        function selectWordAt(pos) {\r\n            var line = getLine(pos.line).text;\r\n            var start = pos.ch, end = pos.ch;\r\n            while (start > 0 && isWordChar(line.charAt(start - 1))) --start;\r\n            while (end < line.length && isWordChar(line.charAt(end))) ++end;\r\n            setSelectionUser({line: pos.line, ch: start}, {line: pos.line, ch: end});\r\n        }\r\n        function selectLine(line) {\r\n            setSelectionUser({line: line, ch: 0}, {line: line, ch: getLine(line).text.length});\r\n        }\r\n        function indentSelected(mode) {\r\n            if (posEq(sel.from, sel.to)) return indentLine(sel.from.line, mode);\r\n            var e = sel.to.line - (sel.to.ch ? 0 : 1);\r\n            for (var i = sel.from.line; i <= e; ++i) indentLine(i, mode);\r\n        }\r\n\r\n        function indentLine(n, how) {\r\n            if (!how) how = \"add\";\r\n            if (how == \"smart\") {\r\n                if (!mode.indent) how = \"prev\";\r\n                else var state = getStateBefore(n);\r\n            }\r\n\r\n            var line = getLine(n), curSpace = line.indentation(options.tabSize),\r\n                curSpaceString = line.text.match(/^\\s*/)[0], indentation;\r\n            if (how == \"prev\") {\r\n                if (n) indentation = getLine(n-1).indentation(options.tabSize);\r\n                else indentation = 0;\r\n            }\r\n            else if (how == \"smart\") indentation = mode.indent(state, line.text.slice(curSpaceString.length), line.text);\r\n            else if (how == \"add\") indentation = curSpace + options.indentUnit;\r\n            else if (how == \"subtract\") indentation = curSpace - options.indentUnit;\r\n            indentation = Math.max(0, indentation);\r\n            var diff = indentation - curSpace;\r\n\r\n            if (!diff) {\r\n                if (sel.from.line != n && sel.to.line != n) return;\r\n                var indentString = curSpaceString;\r\n            }\r\n            else {\r\n                var indentString = \"\", pos = 0;\r\n                if (options.indentWithTabs)\r\n                    for (var i = Math.floor(indentation / options.tabSize); i; --i) {pos += options.tabSize; indentString += \"\\t\";}\r\n                while (pos < indentation) {++pos; indentString += \" \";}\r\n            }\r\n\r\n            replaceRange(indentString, {line: n, ch: 0}, {line: n, ch: curSpaceString.length});\r\n        }\r\n\r\n        function loadMode() {\r\n            mode = CodeMirror.getMode(options, options.mode);\r\n            doc.iter(0, doc.size, function(line) { line.stateAfter = null; });\r\n            work = [0];\r\n            startWorker();\r\n        }\r\n        function gutterChanged() {\r\n            var visible = options.gutter || options.lineNumbers;\r\n            gutter.style.display = visible ? \"\" : \"none\";\r\n            if (visible) gutterDirty = true;\r\n            else lineDiv.parentNode.style.marginLeft = 0;\r\n        }\r\n        function wrappingChanged(from, to) {\r\n            if (options.lineWrapping) {\r\n                wrapper.className += \" CodeMirror-wrap\";\r\n                var perLine = scroller.clientWidth / charWidth() - 3;\r\n                doc.iter(0, doc.size, function(line) {\r\n                    if (line.hidden) return;\r\n                    var guess = Math.ceil(line.text.length / perLine) || 1;\r\n                    if (guess != 1) updateLineHeight(line, guess);\r\n                });\r\n                lineSpace.style.width = code.style.width = \"\";\r\n            } else {\r\n                wrapper.className = wrapper.className.replace(\" CodeMirror-wrap\", \"\");\r\n                maxWidth = null; maxLine = \"\";\r\n                doc.iter(0, doc.size, function(line) {\r\n                    if (line.height != 1 && !line.hidden) updateLineHeight(line, 1);\r\n                    if (line.text.length > maxLine.length) maxLine = line.text;\r\n                });\r\n            }\r\n            changes.push({from: 0, to: doc.size});\r\n        }\r\n        function computeTabText() {\r\n            for (var str = '<span class=\"cm-tab\">', i = 0; i < options.tabSize; ++i) str += \" \";\r\n            return str + \"</span>\";\r\n        }\r\n        function tabsChanged() {\r\n            tabText = computeTabText();\r\n            updateDisplay(true);\r\n        }\r\n        function themeChanged() {\r\n            scroller.className = scroller.className.replace(/\\s*cm-s-\\w+/g, \"\") +\r\n                options.theme.replace(/(^|\\s)\\s*/g, \" cm-s-\");\r\n        }\r\n\r\n        function TextMarker() { this.set = []; }\r\n        TextMarker.prototype.clear = operation(function() {\r\n            var min = Infinity, max = -Infinity;\r\n            for (var i = 0, e = this.set.length; i < e; ++i) {\r\n                var line = this.set[i], mk = line.marked;\r\n                if (!mk || !line.parent) continue;\r\n                var lineN = lineNo(line);\r\n                min = Math.min(min, lineN); max = Math.max(max, lineN);\r\n                for (var j = 0; j < mk.length; ++j)\r\n                    if (mk[j].set == this.set) mk.splice(j--, 1);\r\n            }\r\n            if (min != Infinity)\r\n                changes.push({from: min, to: max + 1});\r\n        });\r\n        TextMarker.prototype.find = function() {\r\n            var from, to;\r\n            for (var i = 0, e = this.set.length; i < e; ++i) {\r\n                var line = this.set[i], mk = line.marked;\r\n                for (var j = 0; j < mk.length; ++j) {\r\n                    var mark = mk[j];\r\n                    if (mark.set == this.set) {\r\n                        if (mark.from != null || mark.to != null) {\r\n                            var found = lineNo(line);\r\n                            if (found != null) {\r\n                                if (mark.from != null) from = {line: found, ch: mark.from};\r\n                                if (mark.to != null) to = {line: found, ch: mark.to};\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            return {from: from, to: to};\r\n        };\r\n\r\n        function markText(from, to, className) {\r\n            from = clipPos(from); to = clipPos(to);\r\n            var tm = new TextMarker();\r\n            function add(line, from, to, className) {\r\n                getLine(line).addMark(new MarkedText(from, to, className, tm.set));\r\n            }\r\n            if (from.line == to.line) add(from.line, from.ch, to.ch, className);\r\n            else {\r\n                add(from.line, from.ch, null, className);\r\n                for (var i = from.line + 1, e = to.line; i < e; ++i)\r\n                    add(i, null, null, className);\r\n                add(to.line, null, to.ch, className);\r\n            }\r\n            changes.push({from: from.line, to: to.line + 1});\r\n            return tm;\r\n        }\r\n\r\n        function setBookmark(pos) {\r\n            pos = clipPos(pos);\r\n            var bm = new Bookmark(pos.ch);\r\n            getLine(pos.line).addMark(bm);\r\n            return bm;\r\n        }\r\n\r\n        function addGutterMarker(line, text, className) {\r\n            if (typeof line == \"number\") line = getLine(clipLine(line));\r\n            line.gutterMarker = {text: text, style: className};\r\n            gutterDirty = true;\r\n            return line;\r\n        }\r\n        function removeGutterMarker(line) {\r\n            if (typeof line == \"number\") line = getLine(clipLine(line));\r\n            line.gutterMarker = null;\r\n            gutterDirty = true;\r\n        }\r\n\r\n        function changeLine(handle, op) {\r\n            var no = handle, line = handle;\r\n            if (typeof handle == \"number\") line = getLine(clipLine(handle));\r\n            else no = lineNo(handle);\r\n            if (no == null) return null;\r\n            if (op(line, no)) changes.push({from: no, to: no + 1});\r\n            else return null;\r\n            return line;\r\n        }\r\n        function setLineClass(handle, className) {\r\n            return changeLine(handle, function(line) {\r\n                if (line.className != className) {\r\n                    line.className = className;\r\n                    return true;\r\n                }\r\n            });\r\n        }\r\n        function setLineHidden(handle, hidden) {\r\n            return changeLine(handle, function(line, no) {\r\n                if (line.hidden != hidden) {\r\n                    line.hidden = hidden;\r\n                    updateLineHeight(line, hidden ? 0 : 1);\r\n                    if (hidden && (sel.from.line == no || sel.to.line == no))\r\n                        setSelection(skipHidden(sel.from, sel.from.line, sel.from.ch),\r\n                            skipHidden(sel.to, sel.to.line, sel.to.ch));\r\n                    return (gutterDirty = true);\r\n                }\r\n            });\r\n        }\r\n\r\n        function lineInfo(line) {\r\n            if (typeof line == \"number\") {\r\n                if (!isLine(line)) return null;\r\n                var n = line;\r\n                line = getLine(line);\r\n                if (!line) return null;\r\n            }\r\n            else {\r\n                var n = lineNo(line);\r\n                if (n == null) return null;\r\n            }\r\n            var marker = line.gutterMarker;\r\n            return {line: n, handle: line, text: line.text, markerText: marker && marker.text,\r\n                markerClass: marker && marker.style, lineClass: line.className};\r\n        }\r\n\r\n        function stringWidth(str) {\r\n            measure.innerHTML = \"<pre><span>x</span></pre>\";\r\n            measure.firstChild.firstChild.firstChild.nodeValue = str;\r\n            return measure.firstChild.firstChild.offsetWidth || 10;\r\n        }\r\n        // These are used to go from pixel positions to character\r\n        // positions, taking varying character widths into account.\r\n        function charFromX(line, x) {\r\n            if (x <= 0) return 0;\r\n            var lineObj = getLine(line), text = lineObj.text;\r\n            function getX(len) {\r\n                measure.innerHTML = \"<pre><span>\" + lineObj.getHTML(null, null, false, tabText, len) + \"</span></pre>\";\r\n                return measure.firstChild.firstChild.offsetWidth;\r\n            }\r\n            var from = 0, fromX = 0, to = text.length, toX;\r\n            // Guess a suitable upper bound for our search.\r\n            var estimated = Math.min(to, Math.ceil(x / charWidth()));\r\n            for (;;) {\r\n                var estX = getX(estimated);\r\n                if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));\r\n                else {toX = estX; to = estimated; break;}\r\n            }\r\n            if (x > toX) return to;\r\n            // Try to guess a suitable lower bound as well.\r\n            estimated = Math.floor(to * 0.8); estX = getX(estimated);\r\n            if (estX < x) {from = estimated; fromX = estX;}\r\n            // Do a binary search between these bounds.\r\n            for (;;) {\r\n                if (to - from <= 1) return (toX - x > x - fromX) ? from : to;\r\n                var middle = Math.ceil((from + to) / 2), middleX = getX(middle);\r\n                if (middleX > x) {to = middle; toX = middleX;}\r\n                else {from = middle; fromX = middleX;}\r\n            }\r\n        }\r\n\r\n        var tempId = Math.floor(Math.random() * 0xffffff).toString(16);\r\n        function measureLine(line, ch) {\r\n            var extra = \"\";\r\n            // Include extra text at the end to make sure the measured line is wrapped in the right way.\r\n            if (options.lineWrapping) {\r\n                var end = line.text.indexOf(\" \", ch + 2);\r\n                extra = htmlEscape(line.text.slice(ch + 1, end < 0 ? line.text.length : end + (ie ? 5 : 0)));\r\n            }\r\n            measure.innerHTML = \"<pre>\" + line.getHTML(null, null, false, tabText, ch) +\r\n                '<span id=\"CodeMirror-temp-' + tempId + '\">' + htmlEscape(line.text.charAt(ch) || \" \") + \"</span>\" +\r\n                extra + \"</pre>\";\r\n            var elt = document.getElementById(\"CodeMirror-temp-\" + tempId);\r\n            var top = elt.offsetTop, left = elt.offsetLeft;\r\n            // Older IEs report zero offsets for spans directly after a wrap\r\n            if (ie && ch && top == 0 && left == 0) {\r\n                var backup = document.createElement(\"span\");\r\n                backup.innerHTML = \"x\";\r\n                elt.parentNode.insertBefore(backup, elt.nextSibling);\r\n                top = backup.offsetTop;\r\n            }\r\n            return {top: top, left: left};\r\n        }\r\n        function localCoords(pos, inLineWrap) {\r\n            var x, lh = textHeight(), y = lh * (heightAtLine(doc, pos.line) - (inLineWrap ? displayOffset : 0));\r\n            if (pos.ch == 0) x = 0;\r\n            else {\r\n                var sp = measureLine(getLine(pos.line), pos.ch);\r\n                x = sp.left;\r\n                if (options.lineWrapping) y += Math.max(0, sp.top);\r\n            }\r\n            return {x: x, y: y, yBot: y + lh};\r\n        }\r\n        // Coords must be lineSpace-local\r\n        function coordsChar(x, y) {\r\n            if (y < 0) y = 0;\r\n            var th = textHeight(), cw = charWidth(), heightPos = displayOffset + Math.floor(y / th);\r\n            var lineNo = lineAtHeight(doc, heightPos);\r\n            if (lineNo >= doc.size) return {line: doc.size - 1, ch: getLine(doc.size - 1).text.length};\r\n            var lineObj = getLine(lineNo), text = lineObj.text;\r\n            var tw = options.lineWrapping, innerOff = tw ? heightPos - heightAtLine(doc, lineNo) : 0;\r\n            if (x <= 0 && innerOff == 0) return {line: lineNo, ch: 0};\r\n            function getX(len) {\r\n                var sp = measureLine(lineObj, len);\r\n                if (tw) {\r\n                    var off = Math.round(sp.top / th);\r\n                    return Math.max(0, sp.left + (off - innerOff) * scroller.clientWidth);\r\n                }\r\n                return sp.left;\r\n            }\r\n            var from = 0, fromX = 0, to = text.length, toX;\r\n            // Guess a suitable upper bound for our search.\r\n            var estimated = Math.min(to, Math.ceil((x + innerOff * scroller.clientWidth * .9) / cw));\r\n            for (;;) {\r\n                var estX = getX(estimated);\r\n                if (estX <= x && estimated < to) estimated = Math.min(to, Math.ceil(estimated * 1.2));\r\n                else {toX = estX; to = estimated; break;}\r\n            }\r\n            if (x > toX) return {line: lineNo, ch: to};\r\n            // Try to guess a suitable lower bound as well.\r\n            estimated = Math.floor(to * 0.8); estX = getX(estimated);\r\n            if (estX < x) {from = estimated; fromX = estX;}\r\n            // Do a binary search between these bounds.\r\n            for (;;) {\r\n                if (to - from <= 1) return {line: lineNo, ch: (toX - x > x - fromX) ? from : to};\r\n                var middle = Math.ceil((from + to) / 2), middleX = getX(middle);\r\n                if (middleX > x) {to = middle; toX = middleX;}\r\n                else {from = middle; fromX = middleX;}\r\n            }\r\n        }\r\n        function pageCoords(pos) {\r\n            var local = localCoords(pos, true), off = eltOffset(lineSpace);\r\n            return {x: off.left + local.x, y: off.top + local.y, yBot: off.top + local.yBot};\r\n        }\r\n\r\n        var cachedHeight, cachedHeightFor, measureText;\r\n        function textHeight() {\r\n            if (measureText == null) {\r\n                measureText = \"<pre>\";\r\n                for (var i = 0; i < 49; ++i) measureText += \"x<br/>\";\r\n                measureText += \"x</pre>\";\r\n            }\r\n            var offsetHeight = lineDiv.clientHeight;\r\n            if (offsetHeight == cachedHeightFor) return cachedHeight;\r\n            cachedHeightFor = offsetHeight;\r\n            measure.innerHTML = measureText;\r\n            cachedHeight = measure.firstChild.offsetHeight / 50 || 1;\r\n            measure.innerHTML = \"\";\r\n            return cachedHeight;\r\n        }\r\n        var cachedWidth, cachedWidthFor = 0;\r\n        function charWidth() {\r\n            if (scroller.clientWidth == cachedWidthFor) return cachedWidth;\r\n            cachedWidthFor = scroller.clientWidth;\r\n            return (cachedWidth = stringWidth(\"x\"));\r\n        }\r\n        function paddingTop() {return lineSpace.offsetTop;}\r\n        function paddingLeft() {return lineSpace.offsetLeft;}\r\n\r\n        function posFromMouse(e, liberal) {\r\n            var offW = eltOffset(scroller, true), x, y;\r\n            // Fails unpredictably on IE[67] when mouse is dragged around quickly.\r\n            try { x = e.clientX; y = e.clientY; } catch (e) { return null; }\r\n            // This is a mess of a heuristic to try and determine whether a\r\n            // scroll-bar was clicked or not, and to return null if one was\r\n            // (and !liberal).\r\n            if (!liberal && (x - offW.left > scroller.clientWidth || y - offW.top > scroller.clientHeight))\r\n                return null;\r\n            var offL = eltOffset(lineSpace, true);\r\n            return coordsChar(x - offL.left, y - offL.top);\r\n        }\r\n        function onContextMenu(e) {\r\n            var pos = posFromMouse(e);\r\n            if (!pos || window.opera) return; // Opera is difficult.\r\n            if (posEq(sel.from, sel.to) || posLess(pos, sel.from) || !posLess(pos, sel.to))\r\n                operation(setCursor)(pos.line, pos.ch);\r\n\r\n            var oldCSS = input.style.cssText;\r\n            inputDiv.style.position = \"absolute\";\r\n            input.style.cssText = \"position: fixed; width: 30px; height: 30px; top: \" + (e.clientY - 5) +\r\n                \"px; left: \" + (e.clientX - 5) + \"px; z-index: 1000; background: white; \" +\r\n                \"border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);\";\r\n            leaveInputAlone = true;\r\n            var val = input.value = getSelection();\r\n            focusInput();\r\n            input.select();\r\n            function rehide() {\r\n                var newVal = splitLines(input.value).join(\"\\n\");\r\n                if (newVal != val) operation(replaceSelection)(newVal, \"end\");\r\n                inputDiv.style.position = \"relative\";\r\n                input.style.cssText = oldCSS;\r\n                leaveInputAlone = false;\r\n                resetInput(true);\r\n                slowPoll();\r\n            }\r\n\r\n            if (gecko) {\r\n                e_stop(e);\r\n                var mouseup = connect(window, \"mouseup\", function() {\r\n                    mouseup();\r\n                    setTimeout(rehide, 20);\r\n                }, true);\r\n            }\r\n            else {\r\n                setTimeout(rehide, 50);\r\n            }\r\n        }\r\n\r\n        // Cursor-blinking\r\n        function restartBlink() {\r\n            clearInterval(blinker);\r\n            var on = true;\r\n            cursor.style.visibility = \"\";\r\n            blinker = setInterval(function() {\r\n                cursor.style.visibility = (on = !on) ? \"\" : \"hidden\";\r\n            }, 650);\r\n        }\r\n\r\n        var matching = {\"(\": \")>\", \")\": \"(<\", \"[\": \"]>\", \"]\": \"[<\", \"{\": \"}>\", \"}\": \"{<\"};\r\n        function matchBrackets(autoclear) {\r\n            var head = sel.inverted ? sel.from : sel.to, line = getLine(head.line), pos = head.ch - 1;\r\n            var match = (pos >= 0 && matching[line.text.charAt(pos)]) || matching[line.text.charAt(++pos)];\r\n            if (!match) return;\r\n            var ch = match.charAt(0), forward = match.charAt(1) == \">\", d = forward ? 1 : -1, st = line.styles;\r\n            for (var off = pos + 1, i = 0, e = st.length; i < e; i+=2)\r\n                if ((off -= st[i].length) <= 0) {var style = st[i+1]; break;}\r\n\r\n            var stack = [line.text.charAt(pos)], re = /[(){}[\\]]/;\r\n            function scan(line, from, to) {\r\n                if (!line.text) return;\r\n                var st = line.styles, pos = forward ? 0 : line.text.length - 1, cur;\r\n                for (var i = forward ? 0 : st.length - 2, e = forward ? st.length : -2; i != e; i += 2*d) {\r\n                    var text = st[i];\r\n                    if (st[i+1] != null && st[i+1] != style) {pos += d * text.length; continue;}\r\n                    for (var j = forward ? 0 : text.length - 1, te = forward ? text.length : -1; j != te; j += d, pos+=d) {\r\n                        if (pos >= from && pos < to && re.test(cur = text.charAt(j))) {\r\n                            var match = matching[cur];\r\n                            if (match.charAt(1) == \">\" == forward) stack.push(cur);\r\n                            else if (stack.pop() != match.charAt(0)) return {pos: pos, match: false};\r\n                            else if (!stack.length) return {pos: pos, match: true};\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            for (var i = head.line, e = forward ? Math.min(i + 100, doc.size) : Math.max(-1, i - 100); i != e; i+=d) {\r\n                var line = getLine(i), first = i == head.line;\r\n                var found = scan(line, first && forward ? pos + 1 : 0, first && !forward ? pos : line.text.length);\r\n                if (found) break;\r\n            }\r\n            if (!found) found = {pos: null, match: false};\r\n            var style = found.match ? \"CodeMirror-matchingbracket\" : \"CodeMirror-nonmatchingbracket\";\r\n            var one = markText({line: head.line, ch: pos}, {line: head.line, ch: pos+1}, style),\r\n                two = found.pos != null && markText({line: i, ch: found.pos}, {line: i, ch: found.pos + 1}, style);\r\n            var clear = operation(function(){one.clear(); two && two.clear();});\r\n            if (autoclear) setTimeout(clear, 800);\r\n            else bracketHighlighted = clear;\r\n        }\r\n\r\n        // Finds the line to start with when starting a parse. Tries to\r\n        // find a line with a stateAfter, so that it can start with a\r\n        // valid state. If that fails, it returns the line with the\r\n        // smallest indentation, which tends to need the least context to\r\n        // parse correctly.\r\n        function findStartLine(n) {\r\n            var minindent, minline;\r\n            for (var search = n, lim = n - 40; search > lim; --search) {\r\n                if (search == 0) return 0;\r\n                var line = getLine(search-1);\r\n                if (line.stateAfter) return search;\r\n                var indented = line.indentation(options.tabSize);\r\n                if (minline == null || minindent > indented) {\r\n                    minline = search - 1;\r\n                    minindent = indented;\r\n                }\r\n            }\r\n            return minline;\r\n        }\r\n        function getStateBefore(n) {\r\n            var start = findStartLine(n), state = start && getLine(start-1).stateAfter;\r\n            if (!state) state = startState(mode);\r\n            else state = copyState(mode, state);\r\n            doc.iter(start, n, function(line) {\r\n                line.highlight(mode, state, options.tabSize);\r\n                line.stateAfter = copyState(mode, state);\r\n            });\r\n            if (start < n) changes.push({from: start, to: n});\r\n            if (n < doc.size && !getLine(n).stateAfter) work.push(n);\r\n            return state;\r\n        }\r\n        function highlightLines(start, end) {\r\n            var state = getStateBefore(start);\r\n            doc.iter(start, end, function(line) {\r\n                line.highlight(mode, state, options.tabSize);\r\n                line.stateAfter = copyState(mode, state);\r\n            });\r\n        }\r\n        function highlightWorker() {\r\n            var end = +new Date + options.workTime;\r\n            var foundWork = work.length;\r\n            while (work.length) {\r\n                if (!getLine(showingFrom).stateAfter) var task = showingFrom;\r\n                else var task = work.pop();\r\n                if (task >= doc.size) continue;\r\n                var start = findStartLine(task), state = start && getLine(start-1).stateAfter;\r\n                if (state) state = copyState(mode, state);\r\n                else state = startState(mode);\r\n\r\n                var unchanged = 0, compare = mode.compareStates, realChange = false,\r\n                    i = start, bail = false;\r\n                doc.iter(i, doc.size, function(line) {\r\n                    var hadState = line.stateAfter;\r\n                    if (+new Date > end) {\r\n                        work.push(i);\r\n                        startWorker(options.workDelay);\r\n                        if (realChange) changes.push({from: task, to: i + 1});\r\n                        return (bail = true);\r\n                    }\r\n                    var changed = line.highlight(mode, state, options.tabSize);\r\n                    if (changed) realChange = true;\r\n                    line.stateAfter = copyState(mode, state);\r\n                    if (compare) {\r\n                        if (hadState && compare(hadState, state)) return true;\r\n                    } else {\r\n                        if (changed !== false || !hadState) unchanged = 0;\r\n                        else if (++unchanged > 3 && (!mode.indent || mode.indent(hadState, \"\") == mode.indent(state, \"\")))\r\n                            return true;\r\n                    }\r\n                    ++i;\r\n                });\r\n                if (bail) return;\r\n                if (realChange) changes.push({from: task, to: i + 1});\r\n            }\r\n            if (foundWork && options.onHighlightComplete)\r\n                options.onHighlightComplete(instance);\r\n        }\r\n        function startWorker(time) {\r\n            if (!work.length) return;\r\n            highlight.set(time, operation(highlightWorker));\r\n        }\r\n\r\n        // Operations are used to wrap changes in such a way that each\r\n        // change won't have to update the cursor and display (which would\r\n        // be awkward, slow, and error-prone), but instead updates are\r\n        // batched and then all combined and executed at once.\r\n        function startOperation() {\r\n            updateInput = userSelChange = textChanged = null;\r\n            changes = []; selectionChanged = false; callbacks = [];\r\n        }\r\n        function endOperation() {\r\n            var reScroll = false, updated;\r\n            if (selectionChanged) reScroll = !scrollCursorIntoView();\r\n            if (changes.length) updated = updateDisplay(changes, true);\r\n            else {\r\n                if (selectionChanged) updateCursor();\r\n                if (gutterDirty) updateGutter();\r\n            }\r\n            if (reScroll) scrollCursorIntoView();\r\n            if (selectionChanged) {scrollEditorIntoView(); restartBlink();}\r\n\r\n            if (focused && !leaveInputAlone &&\r\n                (updateInput === true || (updateInput !== false && selectionChanged)))\r\n                resetInput(userSelChange);\r\n\r\n            if (selectionChanged && options.matchBrackets)\r\n                setTimeout(operation(function() {\r\n                    if (bracketHighlighted) {bracketHighlighted(); bracketHighlighted = null;}\r\n                    if (posEq(sel.from, sel.to)) matchBrackets(false);\r\n                }), 20);\r\n            var tc = textChanged, cbs = callbacks; // these can be reset by callbacks\r\n            if (selectionChanged && options.onCursorActivity)\r\n                options.onCursorActivity(instance);\r\n            if (tc && options.onChange && instance)\r\n                options.onChange(instance, tc);\r\n            for (var i = 0; i < cbs.length; ++i) cbs[i](instance);\r\n            if (updated && options.onUpdate) options.onUpdate(instance);\r\n        }\r\n        var nestedOperation = 0;\r\n        function operation(f) {\r\n            return function() {\r\n                if (!nestedOperation++) startOperation();\r\n                try {var result = f.apply(this, arguments);}\r\n                finally {if (!--nestedOperation) endOperation();}\r\n                return result;\r\n            };\r\n        }\r\n\r\n        for (var ext in extensions)\r\n            if (extensions.propertyIsEnumerable(ext) &&\r\n                !instance.propertyIsEnumerable(ext))\r\n                instance[ext] = extensions[ext];\r\n        return instance;\r\n    } // (end of function CodeMirror)\r\n\r\n    // The default configuration options.\r\n    CodeMirror.defaults = {\r\n        value: \"\",\r\n        mode: null,\r\n        theme: \"default\",\r\n        indentUnit: 2,\r\n        indentWithTabs: false,\r\n        tabSize: 4,\r\n        keyMap: \"default\",\r\n        extraKeys: null,\r\n        electricChars: true,\r\n        onKeyEvent: null,\r\n        lineWrapping: false,\r\n        lineNumbers: false,\r\n        gutter: false,\r\n        fixedGutter: false,\r\n        firstLineNumber: 1,\r\n        readOnly: false,\r\n        onChange: null,\r\n        onCursorActivity: null,\r\n        onGutterClick: null,\r\n        onHighlightComplete: null,\r\n        onUpdate: null,\r\n        onFocus: null, onBlur: null, onScroll: null,\r\n        matchBrackets: false,\r\n        workTime: 100,\r\n        workDelay: 200,\r\n        pollInterval: 100,\r\n        undoDepth: 40,\r\n        tabindex: null,\r\n        document: window.document\r\n    };\r\n\r\n    var mac = /Mac/.test(navigator.platform);\r\n    var win = /Win/.test(navigator.platform);\r\n\r\n    // Known modes, by name and by MIME\r\n    var modes = {}, mimeModes = {};\r\n    CodeMirror.defineMode = function(name, mode) {\r\n        if (!CodeMirror.defaults.mode && name != \"null\") CodeMirror.defaults.mode = name;\r\n        modes[name] = mode;\r\n    };\r\n    CodeMirror.defineMIME = function(mime, spec) {\r\n        mimeModes[mime] = spec;\r\n    };\r\n    CodeMirror.getMode = function(options, spec) {\r\n        if (typeof spec == \"string\" && mimeModes.hasOwnProperty(spec))\r\n            spec = mimeModes[spec];\r\n        if (typeof spec == \"string\")\r\n            var mname = spec, config = {};\r\n        else if (spec != null)\r\n            var mname = spec.name, config = spec;\r\n        var mfactory = modes[mname];\r\n        if (!mfactory) {\r\n            if (window.console) console.warn(\"No mode \" + mname + \" found, falling back to plain text.\");\r\n            return CodeMirror.getMode(options, \"text/plain\");\r\n        }\r\n        return mfactory(options, config || {});\r\n    };\r\n    CodeMirror.listModes = function() {\r\n        var list = [];\r\n        for (var m in modes)\r\n            if (modes.propertyIsEnumerable(m)) list.push(m);\r\n        return list;\r\n    };\r\n    CodeMirror.listMIMEs = function() {\r\n        var list = [];\r\n        for (var m in mimeModes)\r\n            if (mimeModes.propertyIsEnumerable(m)) list.push({mime: m, mode: mimeModes[m]});\r\n        return list;\r\n    };\r\n\r\n    var extensions = CodeMirror.extensions = {};\r\n    CodeMirror.defineExtension = function(name, func) {\r\n        extensions[name] = func;\r\n    };\r\n\r\n    var commands = CodeMirror.commands = {\r\n        selectAll: function(cm) {cm.setSelection({line: 0, ch: 0}, {line: cm.lineCount() - 1});},\r\n        killLine: function(cm) {\r\n            var from = cm.getCursor(true), to = cm.getCursor(false), sel = !posEq(from, to);\r\n            if (!sel && cm.getLine(from.line).length == from.ch) cm.replaceRange(\"\", from, {line: from.line + 1, ch: 0});\r\n            else cm.replaceRange(\"\", from, sel ? to : {line: from.line});\r\n        },\r\n        deleteLine: function(cm) {var l = cm.getCursor().line; cm.replaceRange(\"\", {line: l, ch: 0}, {line: l});},\r\n        undo: function(cm) {cm.undo();},\r\n        redo: function(cm) {cm.redo();},\r\n        goDocStart: function(cm) {cm.setCursor(0, 0, true);},\r\n        goDocEnd: function(cm) {cm.setSelection({line: cm.lineCount() - 1}, null, true);},\r\n        goLineStart: function(cm) {cm.setCursor(cm.getCursor().line, 0, true);},\r\n        goLineStartSmart: function(cm) {\r\n            var cur = cm.getCursor();\r\n            var text = cm.getLine(cur.line), firstNonWS = Math.max(0, text.search(/\\S/));\r\n            cm.setCursor(cur.line, cur.ch <= firstNonWS && cur.ch ? 0 : firstNonWS, true);\r\n        },\r\n        goLineEnd: function(cm) {cm.setSelection({line: cm.getCursor().line}, null, true);},\r\n        goLineUp: function(cm) {cm.moveV(-1, \"line\");},\r\n        goLineDown: function(cm) {cm.moveV(1, \"line\");},\r\n        goPageUp: function(cm) {cm.moveV(-1, \"page\");},\r\n        goPageDown: function(cm) {cm.moveV(1, \"page\");},\r\n        goCharLeft: function(cm) {cm.moveH(-1, \"char\");},\r\n        goCharRight: function(cm) {cm.moveH(1, \"char\");},\r\n        goColumnLeft: function(cm) {cm.moveH(-1, \"column\");},\r\n        goColumnRight: function(cm) {cm.moveH(1, \"column\");},\r\n        goWordLeft: function(cm) {cm.moveH(-1, \"word\");},\r\n        goWordRight: function(cm) {cm.moveH(1, \"word\");},\r\n        delCharLeft: function(cm) {cm.deleteH(-1, \"char\");},\r\n        delCharRight: function(cm) {cm.deleteH(1, \"char\");},\r\n        delWordLeft: function(cm) {cm.deleteH(-1, \"word\");},\r\n        delWordRight: function(cm) {cm.deleteH(1, \"word\");},\r\n        indentAuto: function(cm) {cm.indentSelection(\"smart\");},\r\n        indentMore: function(cm) {cm.indentSelection(\"add\");},\r\n        indentLess: function(cm) {cm.indentSelection(\"subtract\");},\r\n        insertTab: function(cm) {cm.replaceSelection(\"\\t\", \"end\");},\r\n        transposeChars: function(cm) {\r\n            var cur = cm.getCursor(), line = cm.getLine(cur.line);\r\n            if (cur.ch > 0 && cur.ch < line.length - 1)\r\n                cm.replaceRange(line.charAt(cur.ch) + line.charAt(cur.ch - 1),\r\n                    {line: cur.line, ch: cur.ch - 1}, {line: cur.line, ch: cur.ch + 1});\r\n        },\r\n        newlineAndIndent: function(cm) {\r\n            cm.replaceSelection(\"\\n\", \"end\");\r\n            cm.indentLine(cm.getCursor().line);\r\n        },\r\n        toggleOverwrite: function(cm) {cm.toggleOverwrite();}\r\n    };\r\n\r\n    var keyMap = CodeMirror.keyMap = {};\r\n    keyMap.basic = {\r\n        \"Left\": \"goCharLeft\", \"Right\": \"goCharRight\", \"Up\": \"goLineUp\", \"Down\": \"goLineDown\",\r\n        \"End\": \"goLineEnd\", \"Home\": \"goLineStartSmart\", \"PageUp\": \"goPageUp\", \"PageDown\": \"goPageDown\",\r\n        \"Delete\": \"delCharRight\", \"Backspace\": \"delCharLeft\", \"Tab\": \"indentMore\", \"Shift-Tab\": \"indentLess\",\r\n        \"Enter\": \"newlineAndIndent\", \"Insert\": \"toggleOverwrite\"\r\n    };\r\n    // Note that the save and find-related commands aren't defined by\r\n    // default. Unknown commands are simply ignored.\r\n    keyMap.pcDefault = {\r\n        \"Ctrl-A\": \"selectAll\", \"Ctrl-D\": \"deleteLine\", \"Ctrl-Z\": \"undo\", \"Shift-Ctrl-Z\": \"redo\", \"Ctrl-Y\": \"redo\",\r\n        \"Ctrl-Home\": \"goDocStart\", \"Alt-Up\": \"goDocStart\", \"Ctrl-End\": \"goDocEnd\", \"Ctrl-Down\": \"goDocEnd\",\r\n        \"Ctrl-Left\": \"goWordLeft\", \"Ctrl-Right\": \"goWordRight\", \"Alt-Left\": \"goLineStart\", \"Alt-Right\": \"goLineEnd\",\r\n        \"Ctrl-Backspace\": \"delWordLeft\", \"Ctrl-Delete\": \"delWordRight\", \"Ctrl-S\": \"save\", \"Ctrl-F\": \"find\",\r\n        \"Ctrl-G\": \"findNext\", \"Shift-Ctrl-G\": \"findPrev\", \"Shift-Ctrl-F\": \"replace\", \"Shift-Ctrl-R\": \"replaceAll\",\r\n        fallthrough: \"basic\"\r\n    };\r\n    keyMap.macDefault = {\r\n        \"Cmd-A\": \"selectAll\", \"Cmd-D\": \"deleteLine\", \"Cmd-Z\": \"undo\", \"Shift-Cmd-Z\": \"redo\", \"Cmd-Y\": \"redo\",\r\n        \"Cmd-Up\": \"goDocStart\", \"Cmd-End\": \"goDocEnd\", \"Cmd-Down\": \"goDocEnd\", \"Alt-Left\": \"goWordLeft\",\r\n        \"Alt-Right\": \"goWordRight\", \"Cmd-Left\": \"goLineStart\", \"Cmd-Right\": \"goLineEnd\", \"Alt-Backspace\": \"delWordLeft\",\r\n        \"Ctrl-Alt-Backspace\": \"delWordRight\", \"Alt-Delete\": \"delWordRight\", \"Cmd-S\": \"save\", \"Cmd-F\": \"find\",\r\n        \"Cmd-G\": \"findNext\", \"Shift-Cmd-G\": \"findPrev\", \"Cmd-Alt-F\": \"replace\", \"Shift-Cmd-Alt-F\": \"replaceAll\",\r\n        fallthrough: [\"basic\", \"emacsy\"]\r\n    };\r\n    keyMap[\"default\"] = mac ? keyMap.macDefault : keyMap.pcDefault;\r\n    keyMap.emacsy = {\r\n        \"Ctrl-F\": \"goCharRight\", \"Ctrl-B\": \"goCharLeft\", \"Ctrl-P\": \"goLineUp\", \"Ctrl-N\": \"goLineDown\",\r\n        \"Alt-F\": \"goWordRight\", \"Alt-B\": \"goWordLeft\", \"Ctrl-A\": \"goLineStart\", \"Ctrl-E\": \"goLineEnd\",\r\n        \"Ctrl-V\": \"goPageUp\", \"Shift-Ctrl-V\": \"goPageDown\", \"Ctrl-D\": \"delCharRight\", \"Ctrl-H\": \"delCharLeft\",\r\n        \"Alt-D\": \"delWordRight\", \"Alt-Backspace\": \"delWordLeft\", \"Ctrl-K\": \"killLine\", \"Ctrl-T\": \"transposeChars\"\r\n    };\r\n\r\n    function lookupKey(name, extraMap, map) {\r\n        function lookup(name, map, ft) {\r\n            var found = map[name];\r\n            if (found != null) return found;\r\n            if (ft == null) ft = map.fallthrough;\r\n            if (ft == null) return map.catchall;\r\n            if (typeof ft == \"string\") return lookup(name, keyMap[ft]);\r\n            for (var i = 0, e = ft.length; i < e; ++i) {\r\n                found = lookup(name, keyMap[ft[i]]);\r\n                if (found != null) return found;\r\n            }\r\n            return null;\r\n        }\r\n        return extraMap ? lookup(name, extraMap, map) : lookup(name, keyMap[map]);\r\n    }\r\n    function isModifierKey(event) {\r\n        var name = keyNames[event.keyCode];\r\n        return name == \"Ctrl\" || name == \"Alt\" || name == \"Shift\" || name == \"Mod\";\r\n    }\r\n\r\n    CodeMirror.fromTextArea = function(textarea, options) {\r\n        if (!options) options = {};\r\n        options.value = textarea.value;\r\n        if (!options.tabindex && textarea.tabindex)\r\n            options.tabindex = textarea.tabindex;\r\n\r\n        function save() {textarea.value = instance.getValue();}\r\n        if (textarea.form) {\r\n            // Deplorable hack to make the submit method do the right thing.\r\n            var rmSubmit = connect(textarea.form, \"submit\", save, true);\r\n            if (typeof textarea.form.submit == \"function\") {\r\n                var realSubmit = textarea.form.submit;\r\n                function wrappedSubmit() {\r\n                    save();\r\n                    textarea.form.submit = realSubmit;\r\n                    textarea.form.submit();\r\n                    textarea.form.submit = wrappedSubmit;\r\n                }\r\n                textarea.form.submit = wrappedSubmit;\r\n            }\r\n        }\r\n\r\n        textarea.style.display = \"none\";\r\n        var instance = CodeMirror(function(node) {\r\n            textarea.parentNode.insertBefore(node, textarea.nextSibling);\r\n        }, options);\r\n        instance.save = save;\r\n        instance.getTextArea = function() { return textarea; };\r\n        instance.toTextArea = function() {\r\n            save();\r\n            textarea.parentNode.removeChild(instance.getWrapperElement());\r\n            textarea.style.display = \"\";\r\n            if (textarea.form) {\r\n                rmSubmit();\r\n                if (typeof textarea.form.submit == \"function\")\r\n                    textarea.form.submit = realSubmit;\r\n            }\r\n        };\r\n        return instance;\r\n    };\r\n\r\n    // Utility functions for working with state. Exported because modes\r\n    // sometimes need to do this.\r\n    function copyState(mode, state) {\r\n        if (state === true) return state;\r\n        if (mode.copyState) return mode.copyState(state);\r\n        var nstate = {};\r\n        for (var n in state) {\r\n            var val = state[n];\r\n            if (val instanceof Array) val = val.concat([]);\r\n            nstate[n] = val;\r\n        }\r\n        return nstate;\r\n    }\r\n    CodeMirror.copyState = copyState;\r\n    function startState(mode, a1, a2) {\r\n        return mode.startState ? mode.startState(a1, a2) : true;\r\n    }\r\n    CodeMirror.startState = startState;\r\n\r\n    // The character stream used by a mode's parser.\r\n    function StringStream(string, tabSize) {\r\n        this.pos = this.start = 0;\r\n        this.string = string;\r\n        this.tabSize = tabSize || 8;\r\n    }\r\n    StringStream.prototype = {\r\n        eol: function() {return this.pos >= this.string.length;},\r\n        sol: function() {return this.pos == 0;},\r\n        peek: function() {return this.string.charAt(this.pos);},\r\n        next: function() {\r\n            if (this.pos < this.string.length)\r\n                return this.string.charAt(this.pos++);\r\n        },\r\n        eat: function(match) {\r\n            var ch = this.string.charAt(this.pos);\r\n            if (typeof match == \"string\") var ok = ch == match;\r\n            else var ok = ch && (match.test ? match.test(ch) : match(ch));\r\n            if (ok) {++this.pos; return ch;}\r\n        },\r\n        eatWhile: function(match) {\r\n            var start = this.pos;\r\n            while (this.eat(match)){}\r\n            return this.pos > start;\r\n        },\r\n        eatSpace: function() {\r\n            var start = this.pos;\r\n            while (/[\\s\\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;\r\n            return this.pos > start;\r\n        },\r\n        skipToEnd: function() {this.pos = this.string.length;},\r\n        skipTo: function(ch) {\r\n            var found = this.string.indexOf(ch, this.pos);\r\n            if (found > -1) {this.pos = found; return true;}\r\n        },\r\n        backUp: function(n) {this.pos -= n;},\r\n        column: function() {return countColumn(this.string, this.start, this.tabSize);},\r\n        indentation: function() {return countColumn(this.string, null, this.tabSize);},\r\n        match: function(pattern, consume, caseInsensitive) {\r\n            if (typeof pattern == \"string\") {\r\n                function cased(str) {return caseInsensitive ? str.toLowerCase() : str;}\r\n                if (cased(this.string).indexOf(cased(pattern), this.pos) == this.pos) {\r\n                    if (consume !== false) this.pos += pattern.length;\r\n                    return true;\r\n                }\r\n            }\r\n            else {\r\n                var match = this.string.slice(this.pos).match(pattern);\r\n                if (match && consume !== false) this.pos += match[0].length;\r\n                return match;\r\n            }\r\n        },\r\n        current: function(){return this.string.slice(this.start, this.pos);}\r\n    };\r\n    CodeMirror.StringStream = StringStream;\r\n\r\n    function MarkedText(from, to, className, set) {\r\n        this.from = from; this.to = to; this.style = className; this.set = set;\r\n    }\r\n    MarkedText.prototype = {\r\n        attach: function(line) { this.set.push(line); },\r\n        detach: function(line) {\r\n            var ix = indexOf(this.set, line);\r\n            if (ix > -1) this.set.splice(ix, 1);\r\n        },\r\n        split: function(pos, lenBefore) {\r\n            if (this.to <= pos && this.to != null) return null;\r\n            var from = this.from < pos || this.from == null ? null : this.from - pos + lenBefore;\r\n            var to = this.to == null ? null : this.to - pos + lenBefore;\r\n            return new MarkedText(from, to, this.style, this.set);\r\n        },\r\n        dup: function() { return new MarkedText(null, null, this.style, this.set); },\r\n        clipTo: function(fromOpen, from, toOpen, to, diff) {\r\n            if (this.from != null && this.from >= from)\r\n                this.from = Math.max(to, this.from) + diff;\r\n            if (this.to != null && this.to > from)\r\n                this.to = to < this.to ? this.to + diff : from;\r\n            if (fromOpen && to > this.from && (to < this.to || this.to == null))\r\n                this.from = null;\r\n            if (toOpen && (from < this.to || this.to == null) && (from > this.from || this.from == null))\r\n                this.to = null;\r\n        },\r\n        isDead: function() { return this.from != null && this.to != null && this.from >= this.to; },\r\n        sameSet: function(x) { return this.set == x.set; }\r\n    };\r\n\r\n    function Bookmark(pos) {\r\n        this.from = pos; this.to = pos; this.line = null;\r\n    }\r\n    Bookmark.prototype = {\r\n        attach: function(line) { this.line = line; },\r\n        detach: function(line) { if (this.line == line) this.line = null; },\r\n        split: function(pos, lenBefore) {\r\n            if (pos < this.from) {\r\n                this.from = this.to = (this.from - pos) + lenBefore;\r\n                return this;\r\n            }\r\n        },\r\n        isDead: function() { return this.from > this.to; },\r\n        clipTo: function(fromOpen, from, toOpen, to, diff) {\r\n            if ((fromOpen || from < this.from) && (toOpen || to > this.to)) {\r\n                this.from = 0; this.to = -1;\r\n            } else if (this.from > from) {\r\n                this.from = this.to = Math.max(to, this.from) + diff;\r\n            }\r\n        },\r\n        sameSet: function(x) { return false; },\r\n        find: function() {\r\n            if (!this.line || !this.line.parent) return null;\r\n            return {line: lineNo(this.line), ch: this.from};\r\n        },\r\n        clear: function() {\r\n            if (this.line) {\r\n                var found = indexOf(this.line.marked, this);\r\n                if (found != -1) this.line.marked.splice(found, 1);\r\n                this.line = null;\r\n            }\r\n        }\r\n    };\r\n\r\n    // Line objects. These hold state related to a line, including\r\n    // highlighting info (the styles array).\r\n    function Line(text, styles) {\r\n        this.styles = styles || [text, null];\r\n        this.text = text;\r\n        this.height = 1;\r\n        this.marked = this.gutterMarker = this.className = this.handlers = null;\r\n        this.stateAfter = this.parent = this.hidden = null;\r\n    }\r\n    Line.inheritMarks = function(text, orig) {\r\n        var ln = new Line(text), mk = orig && orig.marked;\r\n        if (mk) {\r\n            for (var i = 0; i < mk.length; ++i) {\r\n                if (mk[i].to == null && mk[i].style) {\r\n                    var newmk = ln.marked || (ln.marked = []), mark = mk[i];\r\n                    var nmark = mark.dup(); newmk.push(nmark); nmark.attach(ln);\r\n                }\r\n            }\r\n        }\r\n        return ln;\r\n    }\r\n    Line.prototype = {\r\n        // Replace a piece of a line, keeping the styles around it intact.\r\n        replace: function(from, to_, text) {\r\n            var st = [], mk = this.marked, to = to_ == null ? this.text.length : to_;\r\n            copyStyles(0, from, this.styles, st);\r\n            if (text) st.push(text, null);\r\n            copyStyles(to, this.text.length, this.styles, st);\r\n            this.styles = st;\r\n            this.text = this.text.slice(0, from) + text + this.text.slice(to);\r\n            this.stateAfter = null;\r\n            if (mk) {\r\n                var diff = text.length - (to - from);\r\n                for (var i = 0, mark = mk[i]; i < mk.length; ++i) {\r\n                    mark.clipTo(from == null, from || 0, to_ == null, to, diff);\r\n                    if (mark.isDead()) {mark.detach(this); mk.splice(i--, 1);}\r\n                }\r\n            }\r\n        },\r\n        // Split a part off a line, keeping styles and markers intact.\r\n        split: function(pos, textBefore) {\r\n            var st = [textBefore, null], mk = this.marked;\r\n            copyStyles(pos, this.text.length, this.styles, st);\r\n            var taken = new Line(textBefore + this.text.slice(pos), st);\r\n            if (mk) {\r\n                for (var i = 0; i < mk.length; ++i) {\r\n                    var mark = mk[i];\r\n                    var newmark = mark.split(pos, textBefore.length);\r\n                    if (newmark) {\r\n                        if (!taken.marked) taken.marked = [];\r\n                        taken.marked.push(newmark); newmark.attach(taken);\r\n                    }\r\n                }\r\n            }\r\n            return taken;\r\n        },\r\n        append: function(line) {\r\n            var mylen = this.text.length, mk = line.marked, mymk = this.marked;\r\n            this.text += line.text;\r\n            copyStyles(0, line.text.length, line.styles, this.styles);\r\n            if (mymk) {\r\n                for (var i = 0; i < mymk.length; ++i)\r\n                    if (mymk[i].to == null) mymk[i].to = mylen;\r\n            }\r\n            if (mk && mk.length) {\r\n                if (!mymk) this.marked = mymk = [];\r\n                outer: for (var i = 0; i < mk.length; ++i) {\r\n                    var mark = mk[i];\r\n                    if (!mark.from) {\r\n                        for (var j = 0; j < mymk.length; ++j) {\r\n                            var mymark = mymk[j];\r\n                            if (mymark.to == mylen && mymark.sameSet(mark)) {\r\n                                mymark.to = mark.to == null ? null : mark.to + mylen;\r\n                                if (mymark.isDead()) {\r\n                                    mymark.detach(this);\r\n                                    mk.splice(i--, 1);\r\n                                }\r\n                                continue outer;\r\n                            }\r\n                        }\r\n                    }\r\n                    mymk.push(mark);\r\n                    mark.attach(this);\r\n                    mark.from += mylen;\r\n                    if (mark.to != null) mark.to += mylen;\r\n                }\r\n            }\r\n        },\r\n        fixMarkEnds: function(other) {\r\n            var mk = this.marked, omk = other.marked;\r\n            if (!mk) return;\r\n            for (var i = 0; i < mk.length; ++i) {\r\n                var mark = mk[i], close = mark.to == null;\r\n                if (close && omk) {\r\n                    for (var j = 0; j < omk.length; ++j)\r\n                        if (omk[j].sameSet(mark)) {close = false; break;}\r\n                }\r\n                if (close) mark.to = this.text.length;\r\n            }\r\n        },\r\n        fixMarkStarts: function() {\r\n            var mk = this.marked;\r\n            if (!mk) return;\r\n            for (var i = 0; i < mk.length; ++i)\r\n                if (mk[i].from == null) mk[i].from = 0;\r\n        },\r\n        addMark: function(mark) {\r\n            mark.attach(this);\r\n            if (this.marked == null) this.marked = [];\r\n            this.marked.push(mark);\r\n            this.marked.sort(function(a, b){return (a.from || 0) - (b.from || 0);});\r\n        },\r\n        // Run the given mode's parser over a line, update the styles\r\n        // array, which contains alternating fragments of text and CSS\r\n        // classes.\r\n        highlight: function(mode, state, tabSize) {\r\n            var stream = new StringStream(this.text, tabSize), st = this.styles, pos = 0;\r\n            var changed = false, curWord = st[0], prevWord;\r\n            if (this.text == \"\" && mode.blankLine) mode.blankLine(state);\r\n            while (!stream.eol()) {\r\n                var style = mode.token(stream, state);\r\n                var substr = this.text.slice(stream.start, stream.pos);\r\n                stream.start = stream.pos;\r\n                if (pos && st[pos-1] == style)\r\n                    st[pos-2] += substr;\r\n                else if (substr) {\r\n                    if (!changed && (st[pos+1] != style || (pos && st[pos-2] != prevWord))) changed = true;\r\n                    st[pos++] = substr; st[pos++] = style;\r\n                    prevWord = curWord; curWord = st[pos];\r\n                }\r\n                // Give up when line is ridiculously long\r\n                if (stream.pos > 5000) {\r\n                    st[pos++] = this.text.slice(stream.pos); st[pos++] = null;\r\n                    break;\r\n                }\r\n            }\r\n            if (st.length != pos) {st.length = pos; changed = true;}\r\n            if (pos && st[pos-2] != prevWord) changed = true;\r\n            // Short lines with simple highlights return null, and are\r\n            // counted as changed by the driver because they are likely to\r\n            // highlight the same way in various contexts.\r\n            return changed || (st.length < 5 && this.text.length < 10 ? null : false);\r\n        },\r\n        // Fetch the parser token for a given character. Useful for hacks\r\n        // that want to inspect the mode state (say, for completion).\r\n        getTokenAt: function(mode, state, ch) {\r\n            var txt = this.text, stream = new StringStream(txt);\r\n            while (stream.pos < ch && !stream.eol()) {\r\n                stream.start = stream.pos;\r\n                var style = mode.token(stream, state);\r\n            }\r\n            return {start: stream.start,\r\n                end: stream.pos,\r\n                string: stream.current(),\r\n                className: style || null,\r\n                state: state};\r\n        },\r\n        indentation: function(tabSize) {return countColumn(this.text, null, tabSize);},\r\n        // Produces an HTML fragment for the line, taking selection,\r\n        // marking, and highlighting into account.\r\n        getHTML: function(sfrom, sto, includePre, tabText, endAt) {\r\n            var html = [], first = true;\r\n            if (includePre)\r\n                html.push(this.className ? '<pre class=\"' + this.className + '\">': \"<pre>\");\r\n            function span(text, style) {\r\n                if (!text) return;\r\n                // Work around a bug where, in some compat modes, IE ignores leading spaces\r\n                if (first && ie && text.charAt(0) == \" \") text = \"\\u00a0\" + text.slice(1);\r\n                first = false;\r\n                if (style) html.push('<span class=\"', style, '\">', htmlEscape(text).replace(/\\t/g, tabText), \"</span>\");\r\n                else html.push(htmlEscape(text).replace(/\\t/g, tabText));\r\n            }\r\n            var st = this.styles, allText = this.text, marked = this.marked;\r\n            if (sfrom == sto) sfrom = null;\r\n            var len = allText.length;\r\n            if (endAt != null) len = Math.min(endAt, len);\r\n\r\n            if (!allText && endAt == null)\r\n                span(\" \", sfrom != null && sto == null ? \"CodeMirror-selected\" : null);\r\n            else if (!marked && sfrom == null)\r\n                for (var i = 0, ch = 0; ch < len; i+=2) {\r\n                    var str = st[i], style = st[i+1], l = str.length;\r\n                    if (ch + l > len) str = str.slice(0, len - ch);\r\n                    ch += l;\r\n                    span(str, style && \"cm-\" + style);\r\n                }\r\n            else {\r\n                var pos = 0, i = 0, text = \"\", style, sg = 0;\r\n                var markpos = -1, mark = null;\r\n                function nextMark() {\r\n                    if (marked) {\r\n                        markpos += 1;\r\n                        mark = (markpos < marked.length) ? marked[markpos] : null;\r\n                    }\r\n                }\r\n                nextMark();\r\n                while (pos < len) {\r\n                    var upto = len;\r\n                    var extraStyle = \"\";\r\n                    if (sfrom != null) {\r\n                        if (sfrom > pos) upto = sfrom;\r\n                        else if (sto == null || sto > pos) {\r\n                            extraStyle = \" CodeMirror-selected\";\r\n                            if (sto != null) upto = Math.min(upto, sto);\r\n                        }\r\n                    }\r\n                    while (mark && mark.to != null && mark.to <= pos) nextMark();\r\n                    if (mark) {\r\n                        if (mark.from > pos) upto = Math.min(upto, mark.from);\r\n                        else {\r\n                            extraStyle += \" \" + mark.style;\r\n                            if (mark.to != null) upto = Math.min(upto, mark.to);\r\n                        }\r\n                    }\r\n                    for (;;) {\r\n                        var end = pos + text.length;\r\n                        var appliedStyle = style;\r\n                        if (extraStyle) appliedStyle = style ? style + extraStyle : extraStyle;\r\n                        span(end > upto ? text.slice(0, upto - pos) : text, appliedStyle);\r\n                        if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}\r\n                        pos = end;\r\n                        text = st[i++]; style = \"cm-\" + st[i++];\r\n                    }\r\n                }\r\n                if (sfrom != null && sto == null) span(\" \", \"CodeMirror-selected\");\r\n            }\r\n            if (includePre) html.push(\"</pre>\");\r\n            return html.join(\"\");\r\n        },\r\n        cleanUp: function() {\r\n            this.parent = null;\r\n            if (this.marked)\r\n                for (var i = 0, e = this.marked.length; i < e; ++i) this.marked[i].detach(this);\r\n        }\r\n    };\r\n    // Utility used by replace and split above\r\n    function copyStyles(from, to, source, dest) {\r\n        for (var i = 0, pos = 0, state = 0; pos < to; i+=2) {\r\n            var part = source[i], end = pos + part.length;\r\n            if (state == 0) {\r\n                if (end > from) dest.push(part.slice(from - pos, Math.min(part.length, to - pos)), source[i+1]);\r\n                if (end >= from) state = 1;\r\n            }\r\n            else if (state == 1) {\r\n                if (end > to) dest.push(part.slice(0, to - pos), source[i+1]);\r\n                else dest.push(part, source[i+1]);\r\n            }\r\n            pos = end;\r\n        }\r\n    }\r\n\r\n    // Data structure that holds the sequence of lines.\r\n    function LeafChunk(lines) {\r\n        this.lines = lines;\r\n        this.parent = null;\r\n        for (var i = 0, e = lines.length, height = 0; i < e; ++i) {\r\n            lines[i].parent = this;\r\n            height += lines[i].height;\r\n        }\r\n        this.height = height;\r\n    }\r\n    LeafChunk.prototype = {\r\n        chunkSize: function() { return this.lines.length; },\r\n        remove: function(at, n, callbacks) {\r\n            for (var i = at, e = at + n; i < e; ++i) {\r\n                var line = this.lines[i];\r\n                this.height -= line.height;\r\n                line.cleanUp();\r\n                if (line.handlers)\r\n                    for (var j = 0; j < line.handlers.length; ++j) callbacks.push(line.handlers[j]);\r\n            }\r\n            this.lines.splice(at, n);\r\n        },\r\n        collapse: function(lines) {\r\n            lines.splice.apply(lines, [lines.length, 0].concat(this.lines));\r\n        },\r\n        insertHeight: function(at, lines, height) {\r\n            this.height += height;\r\n            this.lines.splice.apply(this.lines, [at, 0].concat(lines));\r\n            for (var i = 0, e = lines.length; i < e; ++i) lines[i].parent = this;\r\n        },\r\n        iterN: function(at, n, op) {\r\n            for (var e = at + n; at < e; ++at)\r\n                if (op(this.lines[at])) return true;\r\n        }\r\n    };\r\n    function BranchChunk(children) {\r\n        this.children = children;\r\n        var size = 0, height = 0;\r\n        for (var i = 0, e = children.length; i < e; ++i) {\r\n            var ch = children[i];\r\n            size += ch.chunkSize(); height += ch.height;\r\n            ch.parent = this;\r\n        }\r\n        this.size = size;\r\n        this.height = height;\r\n        this.parent = null;\r\n    }\r\n    BranchChunk.prototype = {\r\n        chunkSize: function() { return this.size; },\r\n        remove: function(at, n, callbacks) {\r\n            this.size -= n;\r\n            for (var i = 0; i < this.children.length; ++i) {\r\n                var child = this.children[i], sz = child.chunkSize();\r\n                if (at < sz) {\r\n                    var rm = Math.min(n, sz - at), oldHeight = child.height;\r\n                    child.remove(at, rm, callbacks);\r\n                    this.height -= oldHeight - child.height;\r\n                    if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }\r\n                    if ((n -= rm) == 0) break;\r\n                    at = 0;\r\n                } else at -= sz;\r\n            }\r\n            if (this.size - n < 25) {\r\n                var lines = [];\r\n                this.collapse(lines);\r\n                this.children = [new LeafChunk(lines)];\r\n            }\r\n        },\r\n        collapse: function(lines) {\r\n            for (var i = 0, e = this.children.length; i < e; ++i) this.children[i].collapse(lines);\r\n        },\r\n        insert: function(at, lines) {\r\n            var height = 0;\r\n            for (var i = 0, e = lines.length; i < e; ++i) height += lines[i].height;\r\n            this.insertHeight(at, lines, height);\r\n        },\r\n        insertHeight: function(at, lines, height) {\r\n            this.size += lines.length;\r\n            this.height += height;\r\n            for (var i = 0, e = this.children.length; i < e; ++i) {\r\n                var child = this.children[i], sz = child.chunkSize();\r\n                if (at <= sz) {\r\n                    child.insertHeight(at, lines, height);\r\n                    if (child.lines && child.lines.length > 50) {\r\n                        while (child.lines.length > 50) {\r\n                            var spilled = child.lines.splice(child.lines.length - 25, 25);\r\n                            var newleaf = new LeafChunk(spilled);\r\n                            child.height -= newleaf.height;\r\n                            this.children.splice(i + 1, 0, newleaf);\r\n                            newleaf.parent = this;\r\n                        }\r\n                        this.maybeSpill();\r\n                    }\r\n                    break;\r\n                }\r\n                at -= sz;\r\n            }\r\n        },\r\n        maybeSpill: function() {\r\n            if (this.children.length <= 10) return;\r\n            var me = this;\r\n            do {\r\n                var spilled = me.children.splice(me.children.length - 5, 5);\r\n                var sibling = new BranchChunk(spilled);\r\n                if (!me.parent) { // Become the parent node\r\n                    var copy = new BranchChunk(me.children);\r\n                    copy.parent = me;\r\n                    me.children = [copy, sibling];\r\n                    me = copy;\r\n                } else {\r\n                    me.size -= sibling.size;\r\n                    me.height -= sibling.height;\r\n                    var myIndex = indexOf(me.parent.children, me);\r\n                    me.parent.children.splice(myIndex + 1, 0, sibling);\r\n                }\r\n                sibling.parent = me.parent;\r\n            } while (me.children.length > 10);\r\n            me.parent.maybeSpill();\r\n        },\r\n        iter: function(from, to, op) { this.iterN(from, to - from, op); },\r\n        iterN: function(at, n, op) {\r\n            for (var i = 0, e = this.children.length; i < e; ++i) {\r\n                var child = this.children[i], sz = child.chunkSize();\r\n                if (at < sz) {\r\n                    var used = Math.min(n, sz - at);\r\n                    if (child.iterN(at, used, op)) return true;\r\n                    if ((n -= used) == 0) break;\r\n                    at = 0;\r\n                } else at -= sz;\r\n            }\r\n        }\r\n    };\r\n\r\n    function getLineAt(chunk, n) {\r\n        while (!chunk.lines) {\r\n            for (var i = 0;; ++i) {\r\n                var child = chunk.children[i], sz = child.chunkSize();\r\n                if (n < sz) { chunk = child; break; }\r\n                n -= sz;\r\n            }\r\n        }\r\n        return chunk.lines[n];\r\n    }\r\n    function lineNo(line) {\r\n        if (line.parent == null) return null;\r\n        var cur = line.parent, no = indexOf(cur.lines, line);\r\n        for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {\r\n            for (var i = 0, e = chunk.children.length; ; ++i) {\r\n                if (chunk.children[i] == cur) break;\r\n                no += chunk.children[i].chunkSize();\r\n            }\r\n        }\r\n        return no;\r\n    }\r\n    function lineAtHeight(chunk, h) {\r\n        var n = 0;\r\n        outer: do {\r\n            for (var i = 0, e = chunk.children.length; i < e; ++i) {\r\n                var child = chunk.children[i], ch = child.height;\r\n                if (h < ch) { chunk = child; continue outer; }\r\n                h -= ch;\r\n                n += child.chunkSize();\r\n            }\r\n            return n;\r\n        } while (!chunk.lines);\r\n        for (var i = 0, e = chunk.lines.length; i < e; ++i) {\r\n            var line = chunk.lines[i], lh = line.height;\r\n            if (h < lh) break;\r\n            h -= lh;\r\n        }\r\n        return n + i;\r\n    }\r\n    function heightAtLine(chunk, n) {\r\n        var h = 0;\r\n        outer: do {\r\n            for (var i = 0, e = chunk.children.length; i < e; ++i) {\r\n                var child = chunk.children[i], sz = child.chunkSize();\r\n                if (n < sz) { chunk = child; continue outer; }\r\n                n -= sz;\r\n                h += child.height;\r\n            }\r\n            return h;\r\n        } while (!chunk.lines);\r\n        for (var i = 0; i < n; ++i) h += chunk.lines[i].height;\r\n        return h;\r\n    }\r\n\r\n    // The history object 'chunks' changes that are made close together\r\n    // and at almost the same time into bigger undoable units.\r\n    function History() {\r\n        this.time = 0;\r\n        this.done = []; this.undone = [];\r\n    }\r\n    History.prototype = {\r\n        addChange: function(start, added, old) {\r\n            this.undone.length = 0;\r\n            var time = +new Date, last = this.done[this.done.length - 1];\r\n            if (time - this.time > 400 || !last ||\r\n                last.start > start + added || last.start + last.added < start - last.added + last.old.length)\r\n                this.done.push({start: start, added: added, old: old});\r\n            else {\r\n                var oldoff = 0;\r\n                if (start < last.start) {\r\n                    for (var i = last.start - start - 1; i >= 0; --i)\r\n                        last.old.unshift(old[i]);\r\n                    last.added += last.start - start;\r\n                    last.start = start;\r\n                }\r\n                else if (last.start < start) {\r\n                    oldoff = start - last.start;\r\n                    added += oldoff;\r\n                }\r\n                for (var i = last.added - oldoff, e = old.length; i < e; ++i)\r\n                    last.old.push(old[i]);\r\n                if (last.added < added) last.added = added;\r\n            }\r\n            this.time = time;\r\n        }\r\n    };\r\n\r\n    function stopMethod() {e_stop(this);}\r\n    // Ensure an event has a stop method.\r\n    function addStop(event) {\r\n        if (!event.stop) event.stop = stopMethod;\r\n        return event;\r\n    }\r\n\r\n    function e_preventDefault(e) {\r\n        if (e.preventDefault) e.preventDefault();\r\n        else e.returnValue = false;\r\n    }\r\n    function e_stopPropagation(e) {\r\n        if (e.stopPropagation) e.stopPropagation();\r\n        else e.cancelBubble = true;\r\n    }\r\n    function e_stop(e) {e_preventDefault(e); e_stopPropagation(e);}\r\n    CodeMirror.e_stop = e_stop;\r\n    CodeMirror.e_preventDefault = e_preventDefault;\r\n    CodeMirror.e_stopPropagation = e_stopPropagation;\r\n\r\n    function e_target(e) {return e.target || e.srcElement;}\r\n    function e_button(e) {\r\n        if (e.which) return e.which;\r\n        else if (e.button & 1) return 1;\r\n        else if (e.button & 2) return 3;\r\n        else if (e.button & 4) return 2;\r\n    }\r\n\r\n    // Event handler registration. If disconnect is true, it'll return a\r\n    // function that unregisters the handler.\r\n    function connect(node, type, handler, disconnect) {\r\n        if (typeof node.addEventListener == \"function\") {\r\n            node.addEventListener(type, handler, false);\r\n            if (disconnect) return function() {node.removeEventListener(type, handler, false);};\r\n        }\r\n        else {\r\n            var wrapHandler = function(event) {handler(event || window.event);};\r\n            node.attachEvent(\"on\" + type, wrapHandler);\r\n            if (disconnect) return function() {node.detachEvent(\"on\" + type, wrapHandler);};\r\n        }\r\n    }\r\n    CodeMirror.connect = connect;\r\n\r\n    function Delayed() {this.id = null;}\r\n    Delayed.prototype = {set: function(ms, f) {clearTimeout(this.id); this.id = setTimeout(f, ms);}};\r\n\r\n    // Detect drag-and-drop\r\n    var dragAndDrop = function() {\r\n        // IE8 has ondragstart and ondrop properties, but doesn't seem to\r\n        // actually support ondragstart the way it's supposed to work.\r\n        if (/MSIE [1-8]\\b/.test(navigator.userAgent)) return false;\r\n        var div = document.createElement('div');\r\n        return \"draggable\" in div;\r\n    }();\r\n\r\n    var gecko = /gecko\\/\\d{7}/i.test(navigator.userAgent);\r\n    var ie = /MSIE \\d/.test(navigator.userAgent);\r\n    var webkit = /WebKit\\//.test(navigator.userAgent);\r\n\r\n    var lineSep = \"\\n\";\r\n    // Feature-detect whether newlines in textareas are converted to \\r\\n\r\n    (function () {\r\n        var te = document.createElement(\"textarea\");\r\n        te.value = \"foo\\nbar\";\r\n        if (te.value.indexOf(\"\\r\") > -1) lineSep = \"\\r\\n\";\r\n    }());\r\n\r\n    // Counts the column offset in a string, taking tabs into account.\r\n    // Used mostly to find indentation.\r\n    function countColumn(string, end, tabSize) {\r\n        if (end == null) {\r\n            end = string.search(/[^\\s\\u00a0]/);\r\n            if (end == -1) end = string.length;\r\n        }\r\n        for (var i = 0, n = 0; i < end; ++i) {\r\n            if (string.charAt(i) == \"\\t\") n += tabSize - (n % tabSize);\r\n            else ++n;\r\n        }\r\n        return n;\r\n    }\r\n\r\n    function computedStyle(elt) {\r\n        if (elt.currentStyle) return elt.currentStyle;\r\n        return window.getComputedStyle(elt, null);\r\n    }\r\n\r\n    // Find the position of an element by following the offsetParent chain.\r\n    // If screen==true, it returns screen (rather than page) coordinates.\r\n    function eltOffset(node, screen) {\r\n        var bod = node.ownerDocument.body;\r\n        var x = 0, y = 0, skipBody = false;\r\n        for (var n = node; n; n = n.offsetParent) {\r\n            var ol = n.offsetLeft, ot = n.offsetTop;\r\n            // Firefox reports weird inverted offsets when the body has a border.\r\n            if (n == bod) { x += Math.abs(ol); y += Math.abs(ot); }\r\n            else { x += ol, y += ot; }\r\n            if (screen && computedStyle(n).position == \"fixed\")\r\n                skipBody = true;\r\n        }\r\n        var e = screen && !skipBody ? null : bod;\r\n        for (var n = node.parentNode; n != e; n = n.parentNode)\r\n            if (n.scrollLeft != null) { x -= n.scrollLeft; y -= n.scrollTop;}\r\n        return {left: x, top: y};\r\n    }\r\n    // Use the faster and saner getBoundingClientRect method when possible.\r\n    if (document.documentElement.getBoundingClientRect != null) eltOffset = function(node, screen) {\r\n        // Take the parts of bounding client rect that we are interested in so we are able to edit if need be,\r\n        // since the returned value cannot be changed externally (they are kept in sync as the element moves within the page)\r\n        try { var box = node.getBoundingClientRect(); box = { top: box.top, left: box.left }; }\r\n        catch(e) { box = {top: 0, left: 0}; }\r\n        if (!screen) {\r\n            // Get the toplevel scroll, working around browser differences.\r\n            if (window.pageYOffset == null) {\r\n                var t = document.documentElement || document.body.parentNode;\r\n                if (t.scrollTop == null) t = document.body;\r\n                box.top += t.scrollTop; box.left += t.scrollLeft;\r\n            } else {\r\n                box.top += window.pageYOffset; box.left += window.pageXOffset;\r\n            }\r\n        }\r\n        return box;\r\n    };\r\n\r\n    // Get a node's text content.\r\n    function eltText(node) {\r\n        return node.textContent || node.innerText || node.nodeValue || \"\";\r\n    }\r\n\r\n    // Operations on {line, ch} objects.\r\n    function posEq(a, b) {return a.line == b.line && a.ch == b.ch;}\r\n    function posLess(a, b) {return a.line < b.line || (a.line == b.line && a.ch < b.ch);}\r\n    function copyPos(x) {return {line: x.line, ch: x.ch};}\r\n\r\n    var escapeElement = document.createElement(\"pre\");\r\n    function htmlEscape(str) {\r\n        escapeElement.textContent = str;\r\n        return escapeElement.innerHTML;\r\n    }\r\n    // Recent (late 2011) Opera betas insert bogus newlines at the start\r\n    // of the textContent, so we strip those.\r\n    if (htmlEscape(\"a\") == \"\\na\")\r\n        htmlEscape = function(str) {\r\n            escapeElement.textContent = str;\r\n            return escapeElement.innerHTML.slice(1);\r\n        };\r\n    // Some IEs don't preserve tabs through innerHTML\r\n    else if (htmlEscape(\"\\t\") != \"\\t\")\r\n        htmlEscape = function(str) {\r\n            escapeElement.innerHTML = \"\";\r\n            escapeElement.appendChild(document.createTextNode(str));\r\n            return escapeElement.innerHTML;\r\n        };\r\n    CodeMirror.htmlEscape = htmlEscape;\r\n\r\n    // Used to position the cursor after an undo/redo by finding the\r\n    // last edited character.\r\n    function editEnd(from, to) {\r\n        if (!to) return from ? from.length : 0;\r\n        if (!from) return to.length;\r\n        for (var i = from.length, j = to.length; i >= 0 && j >= 0; --i, --j)\r\n            if (from.charAt(i) != to.charAt(j)) break;\r\n        return j + 1;\r\n    }\r\n\r\n    function indexOf(collection, elt) {\r\n        if (collection.indexOf) return collection.indexOf(elt);\r\n        for (var i = 0, e = collection.length; i < e; ++i)\r\n            if (collection[i] == elt) return i;\r\n        return -1;\r\n    }\r\n    function isWordChar(ch) {\r\n        return /\\w/.test(ch) || ch.toUpperCase() != ch.toLowerCase();\r\n    }\r\n\r\n    // See if \"\".split is the broken IE version, if so, provide an\r\n    // alternative way to split lines.\r\n    var splitLines = \"\\n\\nb\".split(/\\n/).length != 3 ? function(string) {\r\n        var pos = 0, nl, result = [];\r\n        while ((nl = string.indexOf(\"\\n\", pos)) > -1) {\r\n            result.push(string.slice(pos, string.charAt(nl-1) == \"\\r\" ? nl - 1 : nl));\r\n            pos = nl + 1;\r\n        }\r\n        result.push(string.slice(pos));\r\n        return result;\r\n    } : function(string){return string.split(/\\r?\\n/);};\r\n    CodeMirror.splitLines = splitLines;\r\n\r\n    var hasSelection = window.getSelection ? function(te) {\r\n        try { return te.selectionStart != te.selectionEnd; }\r\n        catch(e) { return false; }\r\n    } : function(te) {\r\n        try {var range = te.ownerDocument.selection.createRange();}\r\n        catch(e) {}\r\n        if (!range || range.parentElement() != te) return false;\r\n        return range.compareEndPoints(\"StartToEnd\", range) != 0;\r\n    };\r\n\r\n    CodeMirror.defineMode(\"null\", function() {\r\n        return {token: function(stream) {stream.skipToEnd();}};\r\n    });\r\n    CodeMirror.defineMIME(\"text/plain\", \"null\");\r\n\r\n    var keyNames = {3: \"Enter\", 8: \"Backspace\", 9: \"Tab\", 13: \"Enter\", 16: \"Shift\", 17: \"Ctrl\", 18: \"Alt\",\r\n        19: \"Pause\", 20: \"CapsLock\", 27: \"Esc\", 32: \"Space\", 33: \"PageUp\", 34: \"PageDown\", 35: \"End\",\r\n        36: \"Home\", 37: \"Left\", 38: \"Up\", 39: \"Right\", 40: \"Down\", 44: \"PrintScrn\", 45: \"Insert\",\r\n        46: \"Delete\", 59: \";\", 91: \"Mod\", 92: \"Mod\", 93: \"Mod\", 186: \";\", 187: \"=\", 188: \",\",\r\n        189: \"-\", 190: \".\", 191: \"/\", 192: \"`\", 219: \"[\", 220: \"\\\\\", 221: \"]\", 222: \"'\", 63276: \"PageUp\",\r\n        63277: \"PageDown\", 63275: \"End\", 63273: \"Home\", 63234: \"Left\", 63232: \"Up\", 63235: \"Right\",\r\n        63233: \"Down\", 63302: \"Insert\", 63272: \"Delete\"};\r\n    CodeMirror.keyNames = keyNames;\r\n    (function() {\r\n        // Number keys\r\n        for (var i = 0; i < 10; i++) keyNames[i + 48] = String(i);\r\n        // Alphabetic keys\r\n        for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);\r\n        // Function keys\r\n        for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = \"F\" + i;\r\n    })();\r\n\r\n    return CodeMirror;\r\n})();\r\nCodeMirror.defineMode(\"xml\", function(config, parserConfig) {\r\n    var indentUnit = config.indentUnit;\r\n    var Kludges = parserConfig.htmlMode ? {\r\n        autoSelfClosers: {\"br\": true, \"img\": true, \"hr\": true, \"link\": true, \"input\": true,\r\n            \"meta\": true, \"col\": true, \"frame\": true, \"base\": true, \"area\": true},\r\n        doNotIndent: {\"pre\": true},\r\n        allowUnquoted: true\r\n    } : {autoSelfClosers: {}, doNotIndent: {}, allowUnquoted: false};\r\n    var alignCDATA = parserConfig.alignCDATA;\r\n\r\n    // Return variables for tokenizers\r\n    var tagName, type;\r\n\r\n    function inText(stream, state) {\r\n        function chain(parser) {\r\n            state.tokenize = parser;\r\n            return parser(stream, state);\r\n        }\r\n\r\n        var ch = stream.next();\r\n        if (ch == \"<\") {\r\n            if (stream.eat(\"!\")) {\r\n                if (stream.eat(\"[\")) {\r\n                    if (stream.match(\"CDATA[\")) return chain(inBlock(\"atom\", \"]]>\"));\r\n                    else return null;\r\n                }\r\n                else if (stream.match(\"--\")) return chain(inBlock(\"comment\", \"-->\"));\r\n                else if (stream.match(\"DOCTYPE\", true, true)) {\r\n                    stream.eatWhile(/[\\w\\._\\-]/);\r\n                    return chain(doctype(1));\r\n                }\r\n                else return null;\r\n            }\r\n            else if (stream.eat(\"?\")) {\r\n                stream.eatWhile(/[\\w\\._\\-]/);\r\n                state.tokenize = inBlock(\"meta\", \"?>\");\r\n                return \"meta\";\r\n            }\r\n            else {\r\n                type = stream.eat(\"/\") ? \"closeTag\" : \"openTag\";\r\n                stream.eatSpace();\r\n                tagName = \"\";\r\n                var c;\r\n                while ((c = stream.eat(/[^\\s\\u00a0=<>\\\"\\'\\/?]/))) tagName += c;\r\n                state.tokenize = inTag;\r\n                return \"tag\";\r\n            }\r\n        }\r\n        else if (ch == \"&\") {\r\n            stream.eatWhile(/[^;]/);\r\n            stream.eat(\";\");\r\n            return \"atom\";\r\n        }\r\n        else {\r\n            stream.eatWhile(/[^&<]/);\r\n            return null;\r\n        }\r\n    }\r\n\r\n    function inTag(stream, state) {\r\n        var ch = stream.next();\r\n        if (ch == \">\" || (ch == \"/\" && stream.eat(\">\"))) {\r\n            state.tokenize = inText;\r\n            type = ch == \">\" ? \"endTag\" : \"selfcloseTag\";\r\n            return \"tag\";\r\n        }\r\n        else if (ch == \"=\") {\r\n            type = \"equals\";\r\n            return null;\r\n        }\r\n        else if (/[\\'\\\"]/.test(ch)) {\r\n            state.tokenize = inAttribute(ch);\r\n            return state.tokenize(stream, state);\r\n        }\r\n        else {\r\n            stream.eatWhile(/[^\\s\\u00a0=<>\\\"\\'\\/?]/);\r\n            return \"word\";\r\n        }\r\n    }\r\n\r\n    function inAttribute(quote) {\r\n        return function(stream, state) {\r\n            while (!stream.eol()) {\r\n                if (stream.next() == quote) {\r\n                    state.tokenize = inTag;\r\n                    break;\r\n                }\r\n            }\r\n            return \"string\";\r\n        };\r\n    }\r\n\r\n    function inBlock(style, terminator) {\r\n        return function(stream, state) {\r\n            while (!stream.eol()) {\r\n                if (stream.match(terminator)) {\r\n                    state.tokenize = inText;\r\n                    break;\r\n                }\r\n                stream.next();\r\n            }\r\n            return style;\r\n        };\r\n    }\r\n    function doctype(depth) {\r\n        return function(stream, state) {\r\n            var ch;\r\n            while ((ch = stream.next()) != null) {\r\n                if (ch == \"<\") {\r\n                    state.tokenize = doctype(depth + 1);\r\n                    return state.tokenize(stream, state);\r\n                } else if (ch == \">\") {\r\n                    if (depth == 1) {\r\n                        state.tokenize = inText;\r\n                        break;\r\n                    } else {\r\n                        state.tokenize = doctype(depth - 1);\r\n                        return state.tokenize(stream, state);\r\n                    }\r\n                }\r\n            }\r\n            return \"meta\";\r\n        };\r\n    }\r\n\r\n    var curState, setStyle;\r\n    function pass() {\r\n        for (var i = arguments.length - 1; i >= 0; i--) curState.cc.push(arguments[i]);\r\n    }\r\n    function cont() {\r\n        pass.apply(null, arguments);\r\n        return true;\r\n    }\r\n\r\n    function pushContext(tagName, startOfLine) {\r\n        var noIndent = Kludges.doNotIndent.hasOwnProperty(tagName) || (curState.context && curState.context.noIndent);\r\n        curState.context = {\r\n            prev: curState.context,\r\n            tagName: tagName,\r\n            indent: curState.indented,\r\n            startOfLine: startOfLine,\r\n            noIndent: noIndent\r\n        };\r\n    }\r\n    function popContext() {\r\n        if (curState.context) curState.context = curState.context.prev;\r\n    }\r\n\r\n    function element(type) {\r\n        if (type == \"openTag\") {\r\n            curState.tagName = tagName;\r\n            return cont(attributes, endtag(curState.startOfLine));\r\n        } else if (type == \"closeTag\") {\r\n            var err = false;\r\n            if (curState.context) {\r\n                err = curState.context.tagName != tagName;\r\n            } else {\r\n                err = true;\r\n            }\r\n            if (err) setStyle = \"error\";\r\n            return cont(endclosetag(err));\r\n        }\r\n        return cont();\r\n    }\r\n    function endtag(startOfLine) {\r\n        return function(type) {\r\n            if (type == \"selfcloseTag\" ||\r\n                (type == \"endTag\" && Kludges.autoSelfClosers.hasOwnProperty(curState.tagName.toLowerCase())))\r\n                return cont();\r\n            if (type == \"endTag\") {pushContext(curState.tagName, startOfLine); return cont();}\r\n            return cont();\r\n        };\r\n    }\r\n    function endclosetag(err) {\r\n        return function(type) {\r\n            if (err) setStyle = \"error\";\r\n            if (type == \"endTag\") { popContext(); return cont(); }\r\n            setStyle = \"error\";\r\n            return cont(arguments.callee);\r\n        }\r\n    }\r\n\r\n    function attributes(type) {\r\n        if (type == \"word\") {setStyle = \"attribute\"; return cont(attributes);}\r\n        if (type == \"equals\") return cont(attvalue, attributes);\r\n        if (type == \"string\") {setStyle = \"error\"; return cont(attributes);}\r\n        return pass();\r\n    }\r\n    function attvalue(type) {\r\n        if (type == \"word\" && Kludges.allowUnquoted) {setStyle = \"string\"; return cont();}\r\n        if (type == \"string\") return cont(attvaluemaybe);\r\n        return pass();\r\n    }\r\n    function attvaluemaybe(type) {\r\n        if (type == \"string\") return cont(attvaluemaybe);\r\n        else return pass();\r\n    }\r\n\r\n    return {\r\n        startState: function() {\r\n            return {tokenize: inText, cc: [], indented: 0, startOfLine: true, tagName: null, context: null};\r\n        },\r\n\r\n        token: function(stream, state) {\r\n            if (stream.sol()) {\r\n                state.startOfLine = true;\r\n                state.indented = stream.indentation();\r\n            }\r\n            if (stream.eatSpace()) return null;\r\n\r\n            setStyle = type = tagName = null;\r\n            var style = state.tokenize(stream, state);\r\n            state.type = type;\r\n            if ((style || type) && style != \"comment\") {\r\n                curState = state;\r\n                while (true) {\r\n                    var comb = state.cc.pop() || element;\r\n                    if (comb(type || style)) break;\r\n                }\r\n            }\r\n            state.startOfLine = false;\r\n            return setStyle || style;\r\n        },\r\n\r\n        indent: function(state, textAfter, fullLine) {\r\n            var context = state.context;\r\n            if ((state.tokenize != inTag && state.tokenize != inText) ||\r\n                context && context.noIndent)\r\n                return fullLine ? fullLine.match(/^(\\s*)/)[0].length : 0;\r\n            if (alignCDATA && /<!\\[CDATA\\[/.test(textAfter)) return 0;\r\n            if (context && /^<\\//.test(textAfter))\r\n                context = context.prev;\r\n            while (context && !context.startOfLine)\r\n                context = context.prev;\r\n            if (context) return context.indent + indentUnit;\r\n            else return 0;\r\n        },\r\n\r\n        compareStates: function(a, b) {\r\n            if (a.indented != b.indented || a.tokenize != b.tokenize) return false;\r\n            for (var ca = a.context, cb = b.context; ; ca = ca.prev, cb = cb.prev) {\r\n                if (!ca || !cb) return ca == cb;\r\n                if (ca.tagName != cb.tagName) return false;\r\n            }\r\n        },\r\n\r\n        electricChars: \"/\"\r\n    };\r\n});\r\n\r\nCodeMirror.defineMIME(\"application/xml\", \"xml\");\r\nCodeMirror.defineMIME(\"text/html\", {name: \"xml\", htmlMode: true});\r\nCodeMirror.defineMode(\"javascript\", function(config, parserConfig) {\r\n    var indentUnit = config.indentUnit;\r\n    var jsonMode = parserConfig.json;\r\n\r\n    // Tokenizer\r\n\r\n    var keywords = function(){\r\n        function kw(type) {return {type: type, style: \"keyword\"};}\r\n        var A = kw(\"keyword a\"), B = kw(\"keyword b\"), C = kw(\"keyword c\");\r\n        var operator = kw(\"operator\"), atom = {type: \"atom\", style: \"atom\"};\r\n        return {\r\n            \"if\": A, \"while\": A, \"with\": A, \"else\": B, \"do\": B, \"try\": B, \"finally\": B,\r\n            \"return\": C, \"break\": C, \"continue\": C, \"new\": C, \"delete\": C, \"throw\": C,\r\n            \"var\": kw(\"var\"), \"const\": kw(\"var\"), \"let\": kw(\"var\"),\r\n            \"function\": kw(\"function\"), \"catch\": kw(\"catch\"),\r\n            \"for\": kw(\"for\"), \"switch\": kw(\"switch\"), \"case\": kw(\"case\"), \"default\": kw(\"default\"),\r\n            \"in\": operator, \"typeof\": operator, \"instanceof\": operator,\r\n            \"true\": atom, \"false\": atom, \"null\": atom, \"undefined\": atom, \"NaN\": atom, \"Infinity\": atom\r\n        };\r\n    }();\r\n\r\n    var isOperatorChar = /[+\\-*&%=<>!?|]/;\r\n\r\n    function chain(stream, state, f) {\r\n        state.tokenize = f;\r\n        return f(stream, state);\r\n    }\r\n\r\n    function nextUntilUnescaped(stream, end) {\r\n        var escaped = false, next;\r\n        while ((next = stream.next()) != null) {\r\n            if (next == end && !escaped)\r\n                return false;\r\n            escaped = !escaped && next == \"\\\\\";\r\n        }\r\n        return escaped;\r\n    }\r\n\r\n    // Used as scratch variables to communicate multiple values without\r\n    // consing up tons of objects.\r\n    var type, content;\r\n    function ret(tp, style, cont) {\r\n        type = tp; content = cont;\r\n        return style;\r\n    }\r\n\r\n    function jsTokenBase(stream, state) {\r\n        var ch = stream.next();\r\n        if (ch == '\"' || ch == \"'\")\r\n            return chain(stream, state, jsTokenString(ch));\r\n        else if (/[\\[\\]{}\\(\\),;\\:\\.]/.test(ch))\r\n            return ret(ch);\r\n        else if (ch == \"0\" && stream.eat(/x/i)) {\r\n            stream.eatWhile(/[\\da-f]/i);\r\n            return ret(\"number\", \"number\");\r\n        }\r\n        else if (/\\d/.test(ch)) {\r\n            stream.match(/^\\d*(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/);\r\n            return ret(\"number\", \"number\");\r\n        }\r\n        else if (ch == \"/\") {\r\n            if (stream.eat(\"*\")) {\r\n                return chain(stream, state, jsTokenComment);\r\n            }\r\n            else if (stream.eat(\"/\")) {\r\n                stream.skipToEnd();\r\n                return ret(\"comment\", \"comment\");\r\n            }\r\n            else if (state.reAllowed) {\r\n                nextUntilUnescaped(stream, \"/\");\r\n                stream.eatWhile(/[gimy]/); // 'y' is \"sticky\" option in Mozilla\r\n                return ret(\"regexp\", \"string\");\r\n            }\r\n            else {\r\n                stream.eatWhile(isOperatorChar);\r\n                return ret(\"operator\", null, stream.current());\r\n            }\r\n        }\r\n        else if (ch == \"#\") {\r\n            stream.skipToEnd();\r\n            return ret(\"error\", \"error\");\r\n        }\r\n        else if (isOperatorChar.test(ch)) {\r\n            stream.eatWhile(isOperatorChar);\r\n            return ret(\"operator\", null, stream.current());\r\n        }\r\n        else {\r\n            stream.eatWhile(/[\\w\\$_]/);\r\n            var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];\r\n            return (known && state.kwAllowed) ? ret(known.type, known.style, word) :\r\n                ret(\"variable\", \"variable\", word);\r\n        }\r\n    }\r\n\r\n    function jsTokenString(quote) {\r\n        return function(stream, state) {\r\n            if (!nextUntilUnescaped(stream, quote))\r\n                state.tokenize = jsTokenBase;\r\n            return ret(\"string\", \"string\");\r\n        };\r\n    }\r\n\r\n    function jsTokenComment(stream, state) {\r\n        var maybeEnd = false, ch;\r\n        while (ch = stream.next()) {\r\n            if (ch == \"/\" && maybeEnd) {\r\n                state.tokenize = jsTokenBase;\r\n                break;\r\n            }\r\n            maybeEnd = (ch == \"*\");\r\n        }\r\n        return ret(\"comment\", \"comment\");\r\n    }\r\n\r\n    // Parser\r\n\r\n    var atomicTypes = {\"atom\": true, \"number\": true, \"variable\": true, \"string\": true, \"regexp\": true};\r\n\r\n    function JSLexical(indented, column, type, align, prev, info) {\r\n        this.indented = indented;\r\n        this.column = column;\r\n        this.type = type;\r\n        this.prev = prev;\r\n        this.info = info;\r\n        if (align != null) this.align = align;\r\n    }\r\n\r\n    function inScope(state, varname) {\r\n        for (var v = state.localVars; v; v = v.next)\r\n            if (v.name == varname) return true;\r\n    }\r\n\r\n    function parseJS(state, style, type, content, stream) {\r\n        var cc = state.cc;\r\n        // Communicate our context to the combinators.\r\n        // (Less wasteful than consing up a hundred closures on every call.)\r\n        cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc;\r\n\r\n        if (!state.lexical.hasOwnProperty(\"align\"))\r\n            state.lexical.align = true;\r\n\r\n        while(true) {\r\n            var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;\r\n            if (combinator(type, content)) {\r\n                while(cc.length && cc[cc.length - 1].lex)\r\n                    cc.pop()();\r\n                if (cx.marked) return cx.marked;\r\n                if (type == \"variable\" && inScope(state, content)) return \"variable-2\";\r\n                return style;\r\n            }\r\n        }\r\n    }\r\n\r\n    // Combinator utils\r\n\r\n    var cx = {state: null, column: null, marked: null, cc: null};\r\n    function pass() {\r\n        for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);\r\n    }\r\n    function cont() {\r\n        pass.apply(null, arguments);\r\n        return true;\r\n    }\r\n    function register(varname) {\r\n        var state = cx.state;\r\n        if (state.context) {\r\n            cx.marked = \"def\";\r\n            for (var v = state.localVars; v; v = v.next)\r\n                if (v.name == varname) return;\r\n            state.localVars = {name: varname, next: state.localVars};\r\n        }\r\n    }\r\n\r\n    // Combinators\r\n\r\n    var defaultVars = {name: \"this\", next: {name: \"arguments\"}};\r\n    function pushcontext() {\r\n        if (!cx.state.context) cx.state.localVars = defaultVars;\r\n        cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};\r\n    }\r\n    function popcontext() {\r\n        cx.state.localVars = cx.state.context.vars;\r\n        cx.state.context = cx.state.context.prev;\r\n    }\r\n    function pushlex(type, info) {\r\n        var result = function() {\r\n            var state = cx.state;\r\n            state.lexical = new JSLexical(state.indented, cx.stream.column(), type, null, state.lexical, info)\r\n        };\r\n        result.lex = true;\r\n        return result;\r\n    }\r\n    function poplex() {\r\n        var state = cx.state;\r\n        if (state.lexical.prev) {\r\n            if (state.lexical.type == \")\")\r\n                state.indented = state.lexical.indented;\r\n            state.lexical = state.lexical.prev;\r\n        }\r\n    }\r\n    poplex.lex = true;\r\n\r\n    function expect(wanted) {\r\n        return function expecting(type) {\r\n            if (type == wanted) return cont();\r\n            else if (wanted == \";\") return pass();\r\n            else return cont(arguments.callee);\r\n        };\r\n    }\r\n\r\n    function statement(type) {\r\n        if (type == \"var\") return cont(pushlex(\"vardef\"), vardef1, expect(\";\"), poplex);\r\n        if (type == \"keyword a\") return cont(pushlex(\"form\"), expression, statement, poplex);\r\n        if (type == \"keyword b\") return cont(pushlex(\"form\"), statement, poplex);\r\n        if (type == \"{\") return cont(pushlex(\"}\"), block, poplex);\r\n        if (type == \";\") return cont();\r\n        if (type == \"function\") return cont(functiondef);\r\n        if (type == \"for\") return cont(pushlex(\"form\"), expect(\"(\"), pushlex(\")\"), forspec1, expect(\")\"),\r\n            poplex, statement, poplex);\r\n        if (type == \"variable\") return cont(pushlex(\"stat\"), maybelabel);\r\n        if (type == \"switch\") return cont(pushlex(\"form\"), expression, pushlex(\"}\", \"switch\"), expect(\"{\"),\r\n            block, poplex, poplex);\r\n        if (type == \"case\") return cont(expression, expect(\":\"));\r\n        if (type == \"default\") return cont(expect(\":\"));\r\n        if (type == \"catch\") return cont(pushlex(\"form\"), pushcontext, expect(\"(\"), funarg, expect(\")\"),\r\n            statement, poplex, popcontext);\r\n        return pass(pushlex(\"stat\"), expression, expect(\";\"), poplex);\r\n    }\r\n    function expression(type) {\r\n        if (atomicTypes.hasOwnProperty(type)) return cont(maybeoperator);\r\n        if (type == \"function\") return cont(functiondef);\r\n        if (type == \"keyword c\") return cont(maybeexpression);\r\n        if (type == \"(\") return cont(pushlex(\")\"), expression, expect(\")\"), poplex, maybeoperator);\r\n        if (type == \"operator\") return cont(expression);\r\n        if (type == \"[\") return cont(pushlex(\"]\"), commasep(expression, \"]\"), poplex, maybeoperator);\r\n        if (type == \"{\") return cont(pushlex(\"}\"), commasep(objprop, \"}\"), poplex, maybeoperator);\r\n        return cont();\r\n    }\r\n    function maybeexpression(type) {\r\n        if (type.match(/[;\\}\\)\\],]/)) return pass();\r\n        return pass(expression);\r\n    }\r\n\r\n    function maybeoperator(type, value) {\r\n        if (type == \"operator\" && /\\+\\+|--/.test(value)) return cont(maybeoperator);\r\n        if (type == \"operator\") return cont(expression);\r\n        if (type == \";\") return;\r\n        if (type == \"(\") return cont(pushlex(\")\"), commasep(expression, \")\"), poplex, maybeoperator);\r\n        if (type == \".\") return cont(property, maybeoperator);\r\n        if (type == \"[\") return cont(pushlex(\"]\"), expression, expect(\"]\"), poplex, maybeoperator);\r\n    }\r\n    function maybelabel(type) {\r\n        if (type == \":\") return cont(poplex, statement);\r\n        return pass(maybeoperator, expect(\";\"), poplex);\r\n    }\r\n    function property(type) {\r\n        if (type == \"variable\") {cx.marked = \"property\"; return cont();}\r\n    }\r\n    function objprop(type) {\r\n        if (type == \"variable\") cx.marked = \"property\";\r\n        if (atomicTypes.hasOwnProperty(type)) return cont(expect(\":\"), expression);\r\n    }\r\n    function commasep(what, end) {\r\n        function proceed(type) {\r\n            if (type == \",\") return cont(what, proceed);\r\n            if (type == end) return cont();\r\n            return cont(expect(end));\r\n        }\r\n        return function commaSeparated(type) {\r\n            if (type == end) return cont();\r\n            else return pass(what, proceed);\r\n        };\r\n    }\r\n    function block(type) {\r\n        if (type == \"}\") return cont();\r\n        return pass(statement, block);\r\n    }\r\n    function vardef1(type, value) {\r\n        if (type == \"variable\"){register(value); return cont(vardef2);}\r\n        return cont();\r\n    }\r\n    function vardef2(type, value) {\r\n        if (value == \"=\") return cont(expression, vardef2);\r\n        if (type == \",\") return cont(vardef1);\r\n    }\r\n    function forspec1(type) {\r\n        if (type == \"var\") return cont(vardef1, forspec2);\r\n        if (type == \";\") return pass(forspec2);\r\n        if (type == \"variable\") return cont(formaybein);\r\n        return pass(forspec2);\r\n    }\r\n    function formaybein(type, value) {\r\n        if (value == \"in\") return cont(expression);\r\n        return cont(maybeoperator, forspec2);\r\n    }\r\n    function forspec2(type, value) {\r\n        if (type == \";\") return cont(forspec3);\r\n        if (value == \"in\") return cont(expression);\r\n        return cont(expression, expect(\";\"), forspec3);\r\n    }\r\n    function forspec3(type) {\r\n        if (type != \")\") cont(expression);\r\n    }\r\n    function functiondef(type, value) {\r\n        if (type == \"variable\") {register(value); return cont(functiondef);}\r\n        if (type == \"(\") return cont(pushlex(\")\"), pushcontext, commasep(funarg, \")\"), poplex, statement, popcontext);\r\n    }\r\n    function funarg(type, value) {\r\n        if (type == \"variable\") {register(value); return cont();}\r\n    }\r\n\r\n    // Interface\r\n\r\n    return {\r\n        startState: function(basecolumn) {\r\n            return {\r\n                tokenize: jsTokenBase,\r\n                reAllowed: true,\r\n                kwAllowed: true,\r\n                cc: [],\r\n                lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, \"block\", false),\r\n                localVars: null,\r\n                context: null,\r\n                indented: 0\r\n            };\r\n        },\r\n\r\n        token: function(stream, state) {\r\n            if (stream.sol()) {\r\n                if (!state.lexical.hasOwnProperty(\"align\"))\r\n                    state.lexical.align = false;\r\n                state.indented = stream.indentation();\r\n            }\r\n            if (stream.eatSpace()) return null;\r\n            var style = state.tokenize(stream, state);\r\n            if (type == \"comment\") return style;\r\n            state.reAllowed = type == \"operator\" || type == \"keyword c\" || type.match(/^[\\[{}\\(,;:]$/);\r\n            state.kwAllowed = type != '.';\r\n            return parseJS(state, style, type, content, stream);\r\n        },\r\n\r\n        indent: function(state, textAfter) {\r\n            if (state.tokenize != jsTokenBase) return 0;\r\n            var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical,\r\n                type = lexical.type, closing = firstChar == type;\r\n            if (type == \"vardef\") return lexical.indented + 4;\r\n            else if (type == \"form\" && firstChar == \"{\") return lexical.indented;\r\n            else if (type == \"stat\" || type == \"form\") return lexical.indented + indentUnit;\r\n            else if (lexical.info == \"switch\" && !closing)\r\n                return lexical.indented + (/^(?:case|default)\\b/.test(textAfter) ? indentUnit : 2 * indentUnit);\r\n            else if (lexical.align) return lexical.column + (closing ? 0 : 1);\r\n            else return lexical.indented + (closing ? 0 : indentUnit);\r\n        },\r\n\r\n        electricChars: \":{}\"\r\n    };\r\n});\r\n\r\nCodeMirror.defineMIME(\"text/javascript\", \"javascript\");\r\nCodeMirror.defineMIME(\"application/json\", {name: \"javascript\", json: true});\r\n\r\nCodeMirror.defineMode(\"css\", function(config) {\r\n    var indentUnit = config.indentUnit, type;\r\n    function ret(style, tp) {type = tp; return style;}\r\n\r\n    function tokenBase(stream, state) {\r\n        var ch = stream.next();\r\n        if (ch == \"@\") {stream.eatWhile(/[\\w\\\\\\-]/); return ret(\"meta\", stream.current());}\r\n        else if (ch == \"/\" && stream.eat(\"*\")) {\r\n            state.tokenize = tokenCComment;\r\n            return tokenCComment(stream, state);\r\n        }\r\n        else if (ch == \"<\" && stream.eat(\"!\")) {\r\n            state.tokenize = tokenSGMLComment;\r\n            return tokenSGMLComment(stream, state);\r\n        }\r\n        else if (ch == \"=\") ret(null, \"compare\");\r\n        else if ((ch == \"~\" || ch == \"|\") && stream.eat(\"=\")) return ret(null, \"compare\");\r\n        else if (ch == \"\\\"\" || ch == \"'\") {\r\n            state.tokenize = tokenString(ch);\r\n            return state.tokenize(stream, state);\r\n        }\r\n        else if (ch == \"#\") {\r\n            stream.eatWhile(/[\\w\\\\\\-]/);\r\n            return ret(\"atom\", \"hash\");\r\n        }\r\n        else if (ch == \"!\") {\r\n            stream.match(/^\\s*\\w*/);\r\n            return ret(\"keyword\", \"important\");\r\n        }\r\n        else if (/\\d/.test(ch)) {\r\n            stream.eatWhile(/[\\w.%]/);\r\n            return ret(\"number\", \"unit\");\r\n        }\r\n        else if (/[,.+>*\\/]/.test(ch)) {\r\n            return ret(null, \"select-op\");\r\n        }\r\n        else if (/[;{}:\\[\\]]/.test(ch)) {\r\n            return ret(null, ch);\r\n        }\r\n        else {\r\n            stream.eatWhile(/[\\w\\\\\\-]/);\r\n            return ret(\"variable\", \"variable\");\r\n        }\r\n    }\r\n\r\n    function tokenCComment(stream, state) {\r\n        var maybeEnd = false, ch;\r\n        while ((ch = stream.next()) != null) {\r\n            if (maybeEnd && ch == \"/\") {\r\n                state.tokenize = tokenBase;\r\n                break;\r\n            }\r\n            maybeEnd = (ch == \"*\");\r\n        }\r\n        return ret(\"comment\", \"comment\");\r\n    }\r\n\r\n    function tokenSGMLComment(stream, state) {\r\n        var dashes = 0, ch;\r\n        while ((ch = stream.next()) != null) {\r\n            if (dashes >= 2 && ch == \">\") {\r\n                state.tokenize = tokenBase;\r\n                break;\r\n            }\r\n            dashes = (ch == \"-\") ? dashes + 1 : 0;\r\n        }\r\n        return ret(\"comment\", \"comment\");\r\n    }\r\n\r\n    function tokenString(quote) {\r\n        return function(stream, state) {\r\n            var escaped = false, ch;\r\n            while ((ch = stream.next()) != null) {\r\n                if (ch == quote && !escaped)\r\n                    break;\r\n                escaped = !escaped && ch == \"\\\\\";\r\n            }\r\n            if (!escaped) state.tokenize = tokenBase;\r\n            return ret(\"string\", \"string\");\r\n        };\r\n    }\r\n\r\n    return {\r\n        startState: function(base) {\r\n            return {tokenize: tokenBase,\r\n                baseIndent: base || 0,\r\n                stack: []};\r\n        },\r\n\r\n        token: function(stream, state) {\r\n            if (stream.eatSpace()) return null;\r\n            var style = state.tokenize(stream, state);\r\n\r\n            var context = state.stack[state.stack.length-1];\r\n            if (type == \"hash\" && context == \"rule\") style = \"atom\";\r\n            else if (style == \"variable\") {\r\n                if (context == \"rule\") style = \"number\";\r\n                else if (!context || context == \"@media{\") style = \"tag\";\r\n            }\r\n\r\n            if (context == \"rule\" && /^[\\{\\};]$/.test(type))\r\n                state.stack.pop();\r\n            if (type == \"{\") {\r\n                if (context == \"@media\") state.stack[state.stack.length-1] = \"@media{\";\r\n                else state.stack.push(\"{\");\r\n            }\r\n            else if (type == \"}\") state.stack.pop();\r\n            else if (type == \"@media\") state.stack.push(\"@media\");\r\n            else if (context == \"{\" && type != \"comment\") state.stack.push(\"rule\");\r\n            return style;\r\n        },\r\n\r\n        indent: function(state, textAfter) {\r\n            var n = state.stack.length;\r\n            if (/^\\}/.test(textAfter))\r\n                n -= state.stack[state.stack.length-1] == \"rule\" ? 2 : 1;\r\n            return state.baseIndent + n * indentUnit;\r\n        },\r\n\r\n        electricChars: \"}\"\r\n    };\r\n});\r\n\r\nCodeMirror.defineMIME(\"text/css\", \"css\");\r\nCodeMirror.defineMode(\"htmlmixed\", function(config, parserConfig) {\r\n    var htmlMode = CodeMirror.getMode(config, {name: \"xml\", htmlMode: true});\r\n    var jsMode = CodeMirror.getMode(config, \"javascript\");\r\n    var cssMode = CodeMirror.getMode(config, \"css\");\r\n\r\n    function html(stream, state) {\r\n        var style = htmlMode.token(stream, state.htmlState);\r\n        if (style == \"tag\" && stream.current() == \">\" && state.htmlState.context) {\r\n            if (/^script$/i.test(state.htmlState.context.tagName)) {\r\n                state.token = javascript;\r\n                state.localState = jsMode.startState(htmlMode.indent(state.htmlState, \"\"));\r\n                state.mode = \"javascript\";\r\n            }\r\n            else if (/^style$/i.test(state.htmlState.context.tagName)) {\r\n                state.token = css;\r\n                state.localState = cssMode.startState(htmlMode.indent(state.htmlState, \"\"));\r\n                state.mode = \"css\";\r\n            }\r\n        }\r\n        return style;\r\n    }\r\n    function maybeBackup(stream, pat, style) {\r\n        var cur = stream.current();\r\n        var close = cur.search(pat);\r\n        if (close > -1) stream.backUp(cur.length - close);\r\n        return style;\r\n    }\r\n    function javascript(stream, state) {\r\n        if (stream.match(/^<\\/\\s*script\\s*>/i, false)) {\r\n            state.token = html;\r\n            state.curState = null;\r\n            state.mode = \"html\";\r\n            return html(stream, state);\r\n        }\r\n        return maybeBackup(stream, /<\\/\\s*script\\s*>/,\r\n            jsMode.token(stream, state.localState));\r\n    }\r\n    function css(stream, state) {\r\n        if (stream.match(/^<\\/\\s*style\\s*>/i, false)) {\r\n            state.token = html;\r\n            state.localState = null;\r\n            state.mode = \"html\";\r\n            return html(stream, state);\r\n        }\r\n        return maybeBackup(stream, /<\\/\\s*style\\s*>/,\r\n            cssMode.token(stream, state.localState));\r\n    }\r\n\r\n    return {\r\n        startState: function() {\r\n            var state = htmlMode.startState();\r\n            return {token: html, localState: null, mode: \"html\", htmlState: state};\r\n        },\r\n\r\n        copyState: function(state) {\r\n            if (state.localState)\r\n                var local = CodeMirror.copyState(state.token == css ? cssMode : jsMode, state.localState);\r\n            return {token: state.token, localState: local, mode: state.mode,\r\n                htmlState: CodeMirror.copyState(htmlMode, state.htmlState)};\r\n        },\r\n\r\n        token: function(stream, state) {\r\n            return state.token(stream, state);\r\n        },\r\n\r\n        indent: function(state, textAfter) {\r\n            if (state.token == html || /^\\s*<\\//.test(textAfter))\r\n                return htmlMode.indent(state.htmlState, textAfter);\r\n            else if (state.token == javascript)\r\n                return jsMode.indent(state.localState, textAfter);\r\n            else\r\n                return cssMode.indent(state.localState, textAfter);\r\n        },\r\n\r\n        compareStates: function(a, b) {\r\n            return htmlMode.compareStates(a.htmlState, b.htmlState);\r\n        },\r\n\r\n        electricChars: \"/{}:\"\r\n    }\r\n});\r\n\r\nCodeMirror.defineMIME(\"text/html\", \"htmlmixed\");\r\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/adapters/mootools-adapter.js",
    "content": "/*\n Highcharts JS v3.0.6 (2013-10-04)\n MooTools adapter\n\n (c) 2010-2013 Torstein Hønsi\n\n License: www.highcharts.com/license\n*/\n(function(){var e=window,h=document,f=e.MooTools.version.substring(0,3),i=f===\"1.2\"||f===\"1.1\",j=i||f===\"1.3\",g=e.$extend||function(){return Object.append.apply(Object,arguments)};e.HighchartsAdapter={init:function(a){var b=Fx.prototype,c=b.start,d=Fx.Morph.prototype,e=d.compute;b.start=function(b,d){var e=this.element;if(b.d)this.paths=a.init(e,e.d,this.toD);c.apply(this,arguments);return this};d.compute=function(b,c,d){var f=this.paths;if(f)this.element.attr(\"d\",a.step(f[0],f[1],d,this.toD));else return e.apply(this,\narguments)}},adapterRun:function(a,b){if(b===\"width\"||b===\"height\")return parseInt($(a).getStyle(b),10)},getScript:function(a,b){var c=h.getElementsByTagName(\"head\")[0],d=h.createElement(\"script\");d.type=\"text/javascript\";d.src=a;d.onload=b;c.appendChild(d)},animate:function(a,b,c){var d=a.attr,f=c&&c.complete;if(d&&!a.setStyle)a.getStyle=a.attr,a.setStyle=function(){var a=arguments;this.attr.call(this,a[0],a[1][0])},a.$family=function(){return!0};e.HighchartsAdapter.stop(a);c=new Fx.Morph(d?a:$(a),\ng({transition:Fx.Transitions.Quad.easeInOut},c));if(d)c.element=a;if(b.d)c.toD=b.d;f&&c.addEvent(\"complete\",f);c.start(b);a.fx=c},each:function(a,b){return i?$each(a,b):Array.each(a,b)},map:function(a,b){return a.map(b)},grep:function(a,b){return a.filter(b)},inArray:function(a,b,c){return b?b.indexOf(a,c):-1},offset:function(a){a=a.getPosition();return{left:a.x,top:a.y}},extendWithEvents:function(a){a.addEvent||(a.nodeName?$(a):g(a,new Events))},addEvent:function(a,b,c){typeof b===\"string\"&&(b===\n\"unload\"&&(b=\"beforeunload\"),e.HighchartsAdapter.extendWithEvents(a),a.addEvent(b,c))},removeEvent:function(a,b,c){typeof a!==\"string\"&&a.addEvent&&(b?(b===\"unload\"&&(b=\"beforeunload\"),c?a.removeEvent(b,c):a.removeEvents&&a.removeEvents(b)):a.removeEvents())},fireEvent:function(a,b,c,d){b={type:b,target:a};b=j?new Event(b):new DOMEvent(b);b=g(b,c);if(!b.target&&b.event)b.target=b.event.target;b.preventDefault=function(){d=null};a.fireEvent&&a.fireEvent(b.type,b);d&&d(b)},washMouseEvent:function(a){if(a.page)a.pageX=\na.page.x,a.pageY=a.page.y;return a},stop:function(a){a.fx&&a.fx.cancel()}}})();\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/adapters/mootools-adapter.src.js",
    "content": "/**\n * @license Highcharts JS v3.0.6 (2013-10-04)\n * MooTools adapter\n *\n * (c) 2010-2013 Torstein Hønsi\n *\n * License: www.highcharts.com/license\n */\n\n// JSLint options:\n/*global Fx, $, $extend, $each, $merge, Events, Event, DOMEvent */\n\n(function () {\n\nvar win = window,\n\tdoc = document,\n\tmooVersion = win.MooTools.version.substring(0, 3), // Get the first three characters of the version number\n\tlegacy = mooVersion === '1.2' || mooVersion === '1.1', // 1.1 && 1.2 considered legacy, 1.3 is not.\n\tlegacyEvent = legacy || mooVersion === '1.3', // In versions 1.1 - 1.3 the event class is named Event, in newer versions it is named DOMEvent.\n\t$extend = win.$extend || function () {\n\t\treturn Object.append.apply(Object, arguments);\n\t};\n\nwin.HighchartsAdapter = {\n\t/**\n\t * Initialize the adapter. This is run once as Highcharts is first run.\n\t * @param {Object} pathAnim The helper object to do animations across adapters.\n\t */\n\tinit: function (pathAnim) {\n\t\tvar fxProto = Fx.prototype,\n\t\t\tfxStart = fxProto.start,\n\t\t\tmorphProto = Fx.Morph.prototype,\n\t\t\tmorphCompute = morphProto.compute;\n\n\t\t// override Fx.start to allow animation of SVG element wrappers\n\t\t/*jslint unparam: true*//* allow unused parameters in fx functions */\n\t\tfxProto.start = function (from, to) {\n\t\t\tvar fx = this,\n\t\t\t\telem = fx.element;\n\n\t\t\t// special for animating paths\n\t\t\tif (from.d) {\n\t\t\t\t//this.fromD = this.element.d.split(' ');\n\t\t\t\tfx.paths = pathAnim.init(\n\t\t\t\t\telem,\n\t\t\t\t\telem.d,\n\t\t\t\t\tfx.toD\n\t\t\t\t);\n\t\t\t}\n\t\t\tfxStart.apply(fx, arguments);\n\n\t\t\treturn this; // chainable\n\t\t};\n\n\t\t// override Fx.step to allow animation of SVG element wrappers\n\t\tmorphProto.compute = function (from, to, delta) {\n\t\t\tvar fx = this,\n\t\t\t\tpaths = fx.paths;\n\n\t\t\tif (paths) {\n\t\t\t\tfx.element.attr(\n\t\t\t\t\t'd',\n\t\t\t\t\tpathAnim.step(paths[0], paths[1], delta, fx.toD)\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\treturn morphCompute.apply(fx, arguments);\n\t\t\t}\n\t\t};\n\t\t/*jslint unparam: false*/\n\t},\n\t\n\t/**\n\t * Run a general method on the framework, following jQuery syntax\n\t * @param {Object} el The HTML element\n\t * @param {String} method Which method to run on the wrapped element\n\t */\n\tadapterRun: function (el, method) {\n\t\t\n\t\t// This currently works for getting inner width and height. If adding\n\t\t// more methods later, we need a conditional implementation for each.\n\t\tif (method === 'width' || method === 'height') {\n\t\t\treturn parseInt($(el).getStyle(method), 10);\n\t\t}\n\t},\n\n\t/**\n\t * Downloads a script and executes a callback when done.\n\t * @param {String} scriptLocation\n\t * @param {Function} callback\n\t */\n\tgetScript: function (scriptLocation, callback) {\n\t\t// We cannot assume that Assets class from mootools-more is available so instead insert a script tag to download script.\n\t\tvar head = doc.getElementsByTagName('head')[0];\n\t\tvar script = doc.createElement('script');\n\n\t\tscript.type = 'text/javascript';\n\t\tscript.src = scriptLocation;\n\t\tscript.onload = callback;\n\n\t\thead.appendChild(script);\n\t},\n\n\t/**\n\t * Animate a HTML element or SVG element wrapper\n\t * @param {Object} el\n\t * @param {Object} params\n\t * @param {Object} options jQuery-like animation options: duration, easing, callback\n\t */\n\tanimate: function (el, params, options) {\n\t\tvar isSVGElement = el.attr,\n\t\t\teffect,\n\t\t\tcomplete = options && options.complete;\n\n\t\tif (isSVGElement && !el.setStyle) {\n\t\t\t// add setStyle and getStyle methods for internal use in Moo\n\t\t\tel.getStyle = el.attr;\n\t\t\tel.setStyle = function () { // property value is given as array in Moo - break it down\n\t\t\t\tvar args = arguments;\n\t\t\t\tthis.attr.call(this, args[0], args[1][0]);\n\t\t\t};\n\t\t\t// dirty hack to trick Moo into handling el as an element wrapper\n\t\t\tel.$family = function () { return true; };\n\t\t}\n\n\t\t// stop running animations\n\t\twin.HighchartsAdapter.stop(el);\n\n\t\t// define and run the effect\n\t\teffect = new Fx.Morph(\n\t\t\tisSVGElement ? el : $(el),\n\t\t\t$extend({\n\t\t\t\ttransition: Fx.Transitions.Quad.easeInOut\n\t\t\t}, options)\n\t\t);\n\n\t\t// Make sure that the element reference is set when animating svg elements\n\t\tif (isSVGElement) {\n\t\t\teffect.element = el;\n\t\t}\n\n\t\t// special treatment for paths\n\t\tif (params.d) {\n\t\t\teffect.toD = params.d;\n\t\t}\n\n\t\t// jQuery-like events\n\t\tif (complete) {\n\t\t\teffect.addEvent('complete', complete);\n\t\t}\n\n\t\t// run\n\t\teffect.start(params);\n\n\t\t// record for use in stop method\n\t\tel.fx = effect;\n\t},\n\n\t/**\n\t * MooTool's each function\n\t *\n\t */\n\teach: function (arr, fn) {\n\t\treturn legacy ?\n\t\t\t$each(arr, fn) :\n\t\t\tArray.each(arr, fn);\n\t},\n\n\t/**\n\t * Map an array\n\t * @param {Array} arr\n\t * @param {Function} fn\n\t */\n\tmap: function (arr, fn) {\n\t\treturn arr.map(fn);\n\t},\n\n\t/**\n\t * Grep or filter an array\n\t * @param {Array} arr\n\t * @param {Function} fn\n\t */\n\tgrep: function (arr, fn) {\n\t\treturn arr.filter(fn);\n\t},\n\t\n\t/**\n\t * Return the index of an item in an array, or -1 if not matched\n\t */\n\tinArray: function (item, arr, from) {\n\t\treturn arr ? arr.indexOf(item, from) : -1;\n\t},\n\n\t/**\n\t * Get the offset of an element relative to the top left corner of the web page\n\t */\n\toffset: function (el) {\n\t\tvar offsets = el.getPosition(); // #1496\n\t\treturn {\n\t\t\tleft: offsets.x,\n\t\t\ttop: offsets.y\n\t\t};\n\t},\n\n\t/**\n\t * Extends an object with Events, if its not done\n\t */\n\textendWithEvents: function (el) {\n\t\t// if the addEvent method is not defined, el is a custom Highcharts object\n\t\t// like series or point\n\t\tif (!el.addEvent) {\n\t\t\tif (el.nodeName) {\n\t\t\t\tel = $(el); // a dynamically generated node\n\t\t\t} else {\n\t\t\t\t$extend(el, new Events()); // a custom object\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Add an event listener\n\t * @param {Object} el HTML element or custom object\n\t * @param {String} type Event type\n\t * @param {Function} fn Event handler\n\t */\n\taddEvent: function (el, type, fn) {\n\t\tif (typeof type === 'string') { // chart broke due to el being string, type function\n\n\t\t\tif (type === 'unload') { // Moo self destructs before custom unload events\n\t\t\t\ttype = 'beforeunload';\n\t\t\t}\n\n\t\t\twin.HighchartsAdapter.extendWithEvents(el);\n\n\t\t\tel.addEvent(type, fn);\n\t\t}\n\t},\n\n\tremoveEvent: function (el, type, fn) {\n\t\tif (typeof el === 'string') {\n\t\t\t// el.removeEvents below apperantly calls this method again. Do not quite understand why, so for now just bail out.\n\t\t\treturn;\n\t\t}\n\t\t\n\t\tif (el.addEvent) { // If el doesn't have an addEvent method, there are no events to remove\n\t\t\tif (type) {\n\t\t\t\tif (type === 'unload') { // Moo self destructs before custom unload events\n\t\t\t\t\ttype = 'beforeunload';\n\t\t\t\t}\n\t\n\t\t\t\tif (fn) {\n\t\t\t\t\tel.removeEvent(type, fn);\n\t\t\t\t} else if (el.removeEvents) { // #958\n\t\t\t\t\tel.removeEvents(type);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tel.removeEvents();\n\t\t\t}\n\t\t}\n\t},\n\n\tfireEvent: function (el, event, eventArguments, defaultFunction) {\n\t\tvar eventArgs = {\n\t\t\ttype: event,\n\t\t\ttarget: el\n\t\t};\n\t\t// create an event object that keeps all functions\n\t\tevent = legacyEvent ? new Event(eventArgs) : new DOMEvent(eventArgs);\n\t\tevent = $extend(event, eventArguments);\n\n\t\t// When running an event on the Chart.prototype, MooTools nests the target in event.event\n\t\tif (!event.target && event.event) {\n\t\t\tevent.target = event.event.target;\n\t\t}\n\n\t\t// override the preventDefault function to be able to use\n\t\t// this for custom events\n\t\tevent.preventDefault = function () {\n\t\t\tdefaultFunction = null;\n\t\t};\n\t\t// if fireEvent is not available on the object, there hasn't been added\n\t\t// any events to it above\n\t\tif (el.fireEvent) {\n\t\t\tel.fireEvent(event.type, event);\n\t\t}\n\n\t\t// fire the default if it is passed and it is not prevented above\n\t\tif (defaultFunction) {\n\t\t\tdefaultFunction(event);\n\t\t}\n\t},\n\t\n\t/**\n\t * Set back e.pageX and e.pageY that MooTools has abstracted away. #1165, #1346.\n\t */\n\twashMouseEvent: function (e) {\n\t\tif (e.page) {\n\t\t\te.pageX = e.page.x;\n\t\t\te.pageY = e.page.y;\n\t\t}\n\t\treturn e;\n\t},\n\n\t/**\n\t * Stop running animations on the object\n\t */\n\tstop: function (el) {\n\t\tif (el.fx) {\n\t\t\tel.fx.cancel();\n\t\t}\n\t}\n};\n\n}());\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/adapters/prototype-adapter.js",
    "content": "/*\n Highcharts JS v3.0.6 (2013-10-04)\n Prototype adapter\n\n @author Michael Nelson, Torstein Hønsi.\n\n Feel free to use and modify this script.\n Highcharts license: www.highcharts.com/license.\n*/\nvar HighchartsAdapter=function(){var f=typeof Effect!==\"undefined\";return{init:function(a){if(f)Effect.HighchartsTransition=Class.create(Effect.Base,{initialize:function(b,c,d,g){var e;this.element=b;this.key=c;e=b.attr?b.attr(c):$(b).getStyle(c);if(c===\"d\")this.paths=a.init(b,b.d,d),this.toD=d,e=0,d=1;this.start(Object.extend(g||{},{from:e,to:d,attribute:c}))},setup:function(){HighchartsAdapter._extend(this.element);if(!this.element._highchart_animation)this.element._highchart_animation={};this.element._highchart_animation[this.key]=\nthis},update:function(b){var c=this.paths,d=this.element;c&&(b=a.step(c[0],c[1],b,this.toD));d.attr?d.element&&d.attr(this.options.attribute,b):(c={},c[this.options.attribute]=b,$(d).setStyle(c))},finish:function(){this.element&&this.element._highchart_animation&&delete this.element._highchart_animation[this.key]}})},adapterRun:function(a,b){return parseInt($(a).getStyle(b),10)},getScript:function(a,b){var c=$$(\"head\")[0];c&&c.appendChild((new Element(\"script\",{type:\"text/javascript\",src:a})).observe(\"load\",\nb))},addNS:function(a){var b=/^(?:click|mouse(?:down|up|over|move|out))$/;return/^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/.test(a)||b.test(a)?a:\"h:\"+a},addEvent:function(a,b,c){a.addEventListener||a.attachEvent?Event.observe($(a),HighchartsAdapter.addNS(b),c):(HighchartsAdapter._extend(a),a._highcharts_observe(b,c))},animate:function(a,b,c){var d,c=c||{};c.delay=0;c.duration=(c.duration||500)/1E3;c.afterFinish=c.complete;if(f)for(d in b)new Effect.HighchartsTransition($(a),\nd,b[d],c);else{if(a.attr)for(d in b)a.attr(d,b[d]);c.complete&&c.complete()}a.attr||$(a).setStyle(b)},stop:function(a){var b;if(a._highcharts_extended&&a._highchart_animation)for(b in a._highchart_animation)a._highchart_animation[b].cancel()},each:function(a,b){$A(a).each(b)},inArray:function(a,b,c){return b?b.indexOf(a,c):-1},offset:function(a){return $(a).cumulativeOffset()},fireEvent:function(a,b,c,d){a.fire?a.fire(HighchartsAdapter.addNS(b),c):a._highcharts_extended&&(c=c||{},a._highcharts_fire(b,\nc));c&&c.defaultPrevented&&(d=null);d&&d(c)},removeEvent:function(a,b,c){$(a).stopObserving&&(b&&(b=HighchartsAdapter.addNS(b)),$(a).stopObserving(b,c));window===a?Event.stopObserving(a,b,c):(HighchartsAdapter._extend(a),a._highcharts_stop_observing(b,c))},washMouseEvent:function(a){return a},grep:function(a,b){return a.findAll(b)},map:function(a,b){return a.map(b)},_extend:function(a){a._highcharts_extended||Object.extend(a,{_highchart_events:{},_highchart_animation:null,_highcharts_extended:!0,\n_highcharts_observe:function(b,a){this._highchart_events[b]=[this._highchart_events[b],a].compact().flatten()},_highcharts_stop_observing:function(b,a){b?a?this._highchart_events[b]=[this._highchart_events[b]].compact().flatten().without(a):delete this._highchart_events[b]:this._highchart_events={}},_highcharts_fire:function(a,c){var d=this;(this._highchart_events[a]||[]).each(function(a){if(!c.stopped)c.preventDefault=function(){c.defaultPrevented=!0},c.target=d,a.bind(this)(c)===!1&&c.preventDefault()}.bind(this))}})}}}();\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/adapters/prototype-adapter.src.js",
    "content": "/**\n * @license Highcharts JS v3.0.6 (2013-10-04)\n * Prototype adapter\n *\n * @author Michael Nelson, Torstein Hønsi.\n *\n * Feel free to use and modify this script.\n * Highcharts license: www.highcharts.com/license.\n */\n\n// JSLint options:\n/*global Effect, Class, Event, Element, $, $$, $A */\n\n// Adapter interface between prototype and the Highcharts charting library\nvar HighchartsAdapter = (function () {\n\nvar hasEffect = typeof Effect !== 'undefined';\n\nreturn {\n\n\t/**\n\t * Initialize the adapter. This is run once as Highcharts is first run.\n\t * @param {Object} pathAnim The helper object to do animations across adapters.\n\t */\n\tinit: function (pathAnim) {\n\t\tif (hasEffect) {\n\t\t\t/**\n\t\t\t * Animation for Highcharts SVG element wrappers only\n\t\t\t * @param {Object} element\n\t\t\t * @param {Object} attribute\n\t\t\t * @param {Object} to\n\t\t\t * @param {Object} options\n\t\t\t */\n\t\t\tEffect.HighchartsTransition = Class.create(Effect.Base, {\n\t\t\t\tinitialize: function (element, attr, to, options) {\n\t\t\t\t\tvar from,\n\t\t\t\t\t\topts;\n\n\t\t\t\t\tthis.element = element;\n\t\t\t\t\tthis.key = attr;\n\t\t\t\t\tfrom = element.attr ? element.attr(attr) : $(element).getStyle(attr);\n\n\t\t\t\t\t// special treatment for paths\n\t\t\t\t\tif (attr === 'd') {\n\t\t\t\t\t\tthis.paths = pathAnim.init(\n\t\t\t\t\t\t\telement,\n\t\t\t\t\t\t\telement.d,\n\t\t\t\t\t\t\tto\n\t\t\t\t\t\t);\n\t\t\t\t\t\tthis.toD = to;\n\n\n\t\t\t\t\t\t// fake values in order to read relative position as a float in update\n\t\t\t\t\t\tfrom = 0;\n\t\t\t\t\t\tto = 1;\n\t\t\t\t\t}\n\n\t\t\t\t\topts = Object.extend((options || {}), {\n\t\t\t\t\t\tfrom: from,\n\t\t\t\t\t\tto: to,\n\t\t\t\t\t\tattribute: attr\n\t\t\t\t\t});\n\t\t\t\t\tthis.start(opts);\n\t\t\t\t},\n\t\t\t\tsetup: function () {\n\t\t\t\t\tHighchartsAdapter._extend(this.element);\n\t\t\t\t\t// If this is the first animation on this object, create the _highcharts_animation helper that\n\t\t\t\t\t// contain pointers to the animation objects.\n\t\t\t\t\tif (!this.element._highchart_animation) {\n\t\t\t\t\t\tthis.element._highchart_animation = {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Store a reference to this animation instance.\n\t\t\t\t\tthis.element._highchart_animation[this.key] = this;\n\t\t\t\t},\n\t\t\t\tupdate: function (position) {\n\t\t\t\t\tvar paths = this.paths,\n\t\t\t\t\t\telement = this.element,\n\t\t\t\t\t\tobj;\n\n\t\t\t\t\tif (paths) {\n\t\t\t\t\t\tposition = pathAnim.step(paths[0], paths[1], position, this.toD);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (element.attr) { // SVGElement\n\t\t\t\t\t\t\n\t\t\t\t\t\tif (element.element) { // If not, it has been destroyed (#1405)\n\t\t\t\t\t\t\telement.attr(this.options.attribute, position);\n\t\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t} else { // HTML, #409\n\t\t\t\t\t\tobj = {};\n\t\t\t\t\t\tobj[this.options.attribute] = position;\n\t\t\t\t\t\t$(element).setStyle(obj);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t},\n\t\t\t\tfinish: function () {\n\t\t\t\t\t// Delete the property that holds this animation now that it is finished.\n\t\t\t\t\t// Both canceled animations and complete ones gets a 'finish' call.\n\t\t\t\t\tif (this.element && this.element._highchart_animation) { // #1405\n\t\t\t\t\t\tdelete this.element._highchart_animation[this.key];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t},\n\t\n\t/**\n\t * Run a general method on the framework, following jQuery syntax\n\t * @param {Object} el The HTML element\n\t * @param {String} method Which method to run on the wrapped element\n\t */\n\tadapterRun: function (el, method) {\n\t\t\n\t\t// This currently works for getting inner width and height. If adding\n\t\t// more methods later, we need a conditional implementation for each.\n\t\treturn parseInt($(el).getStyle(method), 10);\n\t\t\n\t},\n\n\t/**\n\t * Downloads a script and executes a callback when done.\n\t * @param {String} scriptLocation\n\t * @param {Function} callback\n\t */\n\tgetScript: function (scriptLocation, callback) {\n\t\tvar head = $$('head')[0]; // Returns an array, so pick the first element.\n\t\tif (head) {\n\t\t\t// Append a new 'script' element, set its type and src attributes, add a 'load' handler that calls the callback\n\t\t\thead.appendChild(new Element('script', { type: 'text/javascript', src: scriptLocation}).observe('load', callback));\n\t\t}\n\t},\n\n\t/**\n\t * Custom events in prototype needs to be namespaced. This method adds a namespace 'h:' in front of\n\t * events that are not recognized as native.\n\t */\n\taddNS: function (eventName) {\n\t\tvar HTMLEvents = /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/,\n\t\t\tMouseEvents = /^(?:click|mouse(?:down|up|over|move|out))$/;\n\t\treturn (HTMLEvents.test(eventName) || MouseEvents.test(eventName)) ?\n\t\t\teventName :\n\t\t\t'h:' + eventName;\n\t},\n\n\t// el needs an event to be attached. el is not necessarily a dom element\n\taddEvent: function (el, event, fn) {\n\t\tif (el.addEventListener || el.attachEvent) {\n\t\t\tEvent.observe($(el), HighchartsAdapter.addNS(event), fn);\n\n\t\t} else {\n\t\t\tHighchartsAdapter._extend(el);\n\t\t\tel._highcharts_observe(event, fn);\n\t\t}\n\t},\n\n\t// motion makes things pretty. use it if effects is loaded, if not... still get to the end result.\n\tanimate: function (el, params, options) {\n\t\tvar key,\n\t\t\tfx;\n\n\t\t// default options\n\t\toptions = options || {};\n\t\toptions.delay = 0;\n\t\toptions.duration = (options.duration || 500) / 1000;\n\t\toptions.afterFinish = options.complete;\n\n\t\t// animate wrappers and DOM elements\n\t\tif (hasEffect) {\n\t\t\tfor (key in params) {\n\t\t\t\t// The fx variable is seemingly thrown away here, but the Effect.setup will add itself to the _highcharts_animation object\n\t\t\t\t// on the element itself so its not really lost.\n\t\t\t\tfx = new Effect.HighchartsTransition($(el), key, params[key], options);\n\t\t\t}\n\t\t} else {\n\t\t\tif (el.attr) { // #409 without effects\n\t\t\t\tfor (key in params) {\n\t\t\t\t\tel.attr(key, params[key]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (options.complete) {\n\t\t\t\toptions.complete();\n\t\t\t}\n\t\t}\n\n\t\tif (!el.attr) { // HTML element, #409\n\t\t\t$(el).setStyle(params);\n\t\t}\n\t},\n\n\t// this only occurs in higcharts 2.0+\n\tstop: function (el) {\n\t\tvar key;\n\t\tif (el._highcharts_extended && el._highchart_animation) {\n\t\t\tfor (key in el._highchart_animation) {\n\t\t\t\t// Cancel the animation\n\t\t\t\t// The 'finish' function in the Effect object will remove the reference\n\t\t\t\tel._highchart_animation[key].cancel();\n\t\t\t}\n\t\t}\n\t},\n\n\t// um.. each\n\teach: function (arr, fn) {\n\t\t$A(arr).each(fn);\n\t},\n\t\n\tinArray: function (item, arr, from) {\n\t\treturn arr ? arr.indexOf(item, from) : -1;\n\t},\n\n\t/**\n\t * Get the cumulative offset relative to the top left of the page. This method, unlike its\n\t * jQuery and MooTools counterpart, still suffers from issue #208 regarding the position\n\t * of a chart within a fixed container.\n\t */\n\toffset: function (el) {\n\t\treturn $(el).cumulativeOffset();\n\t},\n\n\t// fire an event based on an event name (event) and an object (el).\n\t// again, el may not be a dom element\n\tfireEvent: function (el, event, eventArguments, defaultFunction) {\n\t\tif (el.fire) {\n\t\t\tel.fire(HighchartsAdapter.addNS(event), eventArguments);\n\t\t} else if (el._highcharts_extended) {\n\t\t\teventArguments = eventArguments || {};\n\t\t\tel._highcharts_fire(event, eventArguments);\n\t\t}\n\n\t\tif (eventArguments && eventArguments.defaultPrevented) {\n\t\t\tdefaultFunction = null;\n\t\t}\n\n\t\tif (defaultFunction) {\n\t\t\tdefaultFunction(eventArguments);\n\t\t}\n\t},\n\n\tremoveEvent: function (el, event, handler) {\n\t\tif ($(el).stopObserving) {\n\t\t\tif (event) {\n\t\t\t\tevent = HighchartsAdapter.addNS(event);\n\t\t\t}\n\t\t\t$(el).stopObserving(event, handler);\n\t\t} if (window === el) {\n\t\t\tEvent.stopObserving(el, event, handler);\n\t\t} else {\n\t\t\tHighchartsAdapter._extend(el);\n\t\t\tel._highcharts_stop_observing(event, handler);\n\t\t}\n\t},\n\t\n\twashMouseEvent: function (e) {\n\t\treturn e;\n\t},\n\n\t// um, grep\n\tgrep: function (arr, fn) {\n\t\treturn arr.findAll(fn);\n\t},\n\n\t// um, map\n\tmap: function (arr, fn) {\n\t\treturn arr.map(fn);\n\t},\n\n\t// extend an object to handle highchart events (highchart objects, not svg elements).\n\t// this is a very simple way of handling events but whatever, it works (i think)\n\t_extend: function (object) {\n\t\tif (!object._highcharts_extended) {\n\t\t\tObject.extend(object, {\n\t\t\t\t_highchart_events: {},\n\t\t\t\t_highchart_animation: null,\n\t\t\t\t_highcharts_extended: true,\n\t\t\t\t_highcharts_observe: function (name, fn) {\n\t\t\t\t\tthis._highchart_events[name] = [this._highchart_events[name], fn].compact().flatten();\n\t\t\t\t},\n\t\t\t\t_highcharts_stop_observing: function (name, fn) {\n\t\t\t\t\tif (name) {\n\t\t\t\t\t\tif (fn) {\n\t\t\t\t\t\t\tthis._highchart_events[name] = [this._highchart_events[name]].compact().flatten().without(fn);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tdelete this._highchart_events[name];\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthis._highchart_events = {};\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\t_highcharts_fire: function (name, args) {\n\t\t\t\t\tvar target = this;\n\t\t\t\t\t(this._highchart_events[name] || []).each(function (fn) {\n\t\t\t\t\t\t// args is never null here\n\t\t\t\t\t\tif (args.stopped) {\n\t\t\t\t\t\t\treturn; // \"throw $break\" wasn't working. i think because of the scope of 'this'.\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Attach a simple preventDefault function to skip default handler if called\n\t\t\t\t\t\targs.preventDefault = function () {\n\t\t\t\t\t\t\targs.defaultPrevented = true;\n\t\t\t\t\t\t};\n\t\t\t\t\t\targs.target = target;\n\n\t\t\t\t\t\t// If the event handler return false, prevent the default handler from executing\n\t\t\t\t\t\tif (fn.bind(this)(args) === false) {\n\t\t\t\t\t\t\targs.preventDefault();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n.bind(this));\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t}\n};\n}());\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/adapters/standalone-framework.js",
    "content": "/*\n Highcharts JS v3.0.6 (2013-10-04)\n\n Standalone Highcharts Framework\n\n License: MIT License\n*/\nvar HighchartsAdapter=function(){function o(c){function a(a,b,d){a.removeEventListener(b,d,!1)}function d(a,b,d){d=a.HCProxiedMethods[d.toString()];a.detachEvent(\"on\"+b,d)}function b(b,c){var f=b.HCEvents,i,g,k,j;if(b.removeEventListener)i=a;else if(b.attachEvent)i=d;else return;c?(g={},g[c]=!0):g=f;for(j in g)if(f[j])for(k=f[j].length;k--;)i(b,j,f[j][k])}c.HCExtended||Highcharts.extend(c,{HCExtended:!0,HCEvents:{},bind:function(b,a){var d=this,c=this.HCEvents,g;if(d.addEventListener)d.addEventListener(b,\na,!1);else if(d.attachEvent){g=function(b){a.call(d,b)};if(!d.HCProxiedMethods)d.HCProxiedMethods={};d.HCProxiedMethods[a.toString()]=g;d.attachEvent(\"on\"+b,g)}c[b]===r&&(c[b]=[]);c[b].push(a)},unbind:function(c,h){var f,i;c?(f=this.HCEvents[c]||[],h?(i=HighchartsAdapter.inArray(h,f),i>-1&&(f.splice(i,1),this.HCEvents[c]=f),this.removeEventListener?a(this,c,h):this.attachEvent&&d(this,c,h)):(b(this,c),this.HCEvents[c]=[])):(b(this),this.HCEvents={})},trigger:function(b,a){var d=this.HCEvents[b]||\n[],c=d.length,g,k,j;k=function(){a.defaultPrevented=!0};for(g=0;g<c;g++){j=d[g];if(a.stopped)break;a.preventDefault=k;a.target=this;a.type=b;j.call(this,a)===!1&&a.preventDefault()}}});return c}var r,l=document,p=[],m=[],q,n;Math.easeInOutSine=function(c,a,d,b){return-d/2*(Math.cos(Math.PI*c/b)-1)+a};return{init:function(c){if(!l.defaultView)this._getStyle=function(a,d){var b;return a.style[d]?a.style[d]:(d===\"opacity\"&&(d=\"filter\"),b=a.currentStyle[d.replace(/\\-(\\w)/g,function(a,b){return b.toUpperCase()})],\nd===\"filter\"&&(b=b.replace(/alpha\\(opacity=([0-9]+)\\)/,function(b,a){return a/100})),b===\"\"?1:b)},this.adapterRun=function(a,d){var b={width:\"clientWidth\",height:\"clientHeight\"}[d];if(b)return a.style.zoom=1,a[b]-2*parseInt(HighchartsAdapter._getStyle(a,\"padding\"),10)};if(!Array.prototype.forEach)this.each=function(a,d){for(var b=0,c=a.length;b<c;b++)if(d.call(a[b],a[b],b,a)===!1)return b};if(!Array.prototype.indexOf)this.inArray=function(a,d){var b,c=0;if(d)for(b=d.length;c<b;c++)if(d[c]===a)return c;\nreturn-1};if(!Array.prototype.filter)this.grep=function(a,d){for(var b=[],c=0,h=a.length;c<h;c++)d(a[c],c)&&b.push(a[c]);return b};n=function(a,c,b){this.options=c;this.elem=a;this.prop=b};n.prototype={update:function(){var a;a=this.paths;var d=this.elem,b=d.element;a&&b?d.attr(\"d\",c.step(a[0],a[1],this.now,this.toD)):d.attr?b&&d.attr(this.prop,this.now):(a={},a[d]=this.now+this.unit,Highcharts.css(d,a));this.options.step&&this.options.step.call(this.elem,this.now,this)},custom:function(a,c,b){var e=\nthis,h=function(a){return e.step(a)},f;this.startTime=+new Date;this.start=a;this.end=c;this.unit=b;this.now=this.start;this.pos=this.state=0;h.elem=this.elem;h()&&m.push(h)===1&&(q=setInterval(function(){for(f=0;f<m.length;f++)m[f]()||m.splice(f--,1);m.length||clearInterval(q)},13))},step:function(a){var c=+new Date,b;b=this.options;var e;if(this.elem.stopAnimation)b=!1;else if(a||c>=b.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();a=this.options.curAnim[this.prop]=\n!0;for(e in b.curAnim)b.curAnim[e]!==!0&&(a=!1);a&&b.complete&&b.complete.call(this.elem);b=!1}else e=c-this.startTime,this.state=e/b.duration,this.pos=b.easing(e,0,1,b.duration),this.now=this.start+(this.end-this.start)*this.pos,this.update(),b=!0;return b}};this.animate=function(a,d,b){var e,h=\"\",f,i,g;a.stopAnimation=!1;if(typeof b!==\"object\"||b===null)e=arguments,b={duration:e[2],easing:e[3],complete:e[4]};if(typeof b.duration!==\"number\")b.duration=400;b.easing=Math[b.easing]||Math.easeInOutSine;\nb.curAnim=Highcharts.extend({},d);for(g in d)i=new n(a,b,g),f=null,g===\"d\"?(i.paths=c.init(a,a.d,d.d),i.toD=d.d,e=0,f=1):a.attr?e=a.attr(g):(e=parseFloat(HighchartsAdapter._getStyle(a,g))||0,g!==\"opacity\"&&(h=\"px\")),f||(f=parseFloat(d[g])),i.custom(e,f,h)}},_getStyle:function(c,a){return window.getComputedStyle(c).getPropertyValue(a)},getScript:function(c,a){var d=l.getElementsByTagName(\"head\")[0],b=l.createElement(\"script\");b.type=\"text/javascript\";b.src=c;b.onload=a;d.appendChild(b)},inArray:function(c,\na){return a.indexOf?a.indexOf(c):p.indexOf.call(a,c)},adapterRun:function(c,a){return parseInt(HighchartsAdapter._getStyle(c,a),10)},grep:function(c,a){return p.filter.call(c,a)},map:function(c,a){for(var d=[],b=0,e=c.length;b<e;b++)d[b]=a.call(c[b],c[b],b,c);return d},offset:function(c){for(var a=0,d=0;c;)a+=c.offsetLeft,d+=c.offsetTop,c=c.offsetParent;return{left:a,top:d}},addEvent:function(c,a,d){o(c).bind(a,d)},removeEvent:function(c,a,d){o(c).unbind(a,d)},fireEvent:function(c,a,d,b){var e;l.createEvent&&\n(c.dispatchEvent||c.fireEvent)?(e=l.createEvent(\"Events\"),e.initEvent(a,!0,!0),e.target=c,Highcharts.extend(e,d),c.dispatchEvent?c.dispatchEvent(e):c.fireEvent(a,e)):c.HCExtended===!0&&(d=d||{},c.trigger(a,d));d&&d.defaultPrevented&&(b=null);b&&b(d)},washMouseEvent:function(c){return c},stop:function(c){c.stopAnimation=!0},each:function(c,a){return Array.prototype.forEach.call(c,a)}}}();\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/adapters/standalone-framework.src.js",
    "content": "/**\n * @license Highcharts JS v3.0.6 (2013-10-04)\n *\n * Standalone Highcharts Framework\n *\n * License: MIT License\n */\n\n\n/*global Highcharts */\nvar HighchartsAdapter = (function () {\n\nvar UNDEFINED,\n\tdoc = document,\n\temptyArray = [],\n\ttimers = [],\n\ttimerId,\n\tFx;\n\nMath.easeInOutSine = function (t, b, c, d) {\n\treturn -c / 2 * (Math.cos(Math.PI * t / d) - 1) + b;\n};\n\n\n\n/**\n * Extend given object with custom events\n */\nfunction augment(obj) {\n\tfunction removeOneEvent(el, type, fn) {\n\t\tel.removeEventListener(type, fn, false);\n\t}\n\n\tfunction IERemoveOneEvent(el, type, fn) {\n\t\tfn = el.HCProxiedMethods[fn.toString()];\n\t\tel.detachEvent('on' + type, fn);\n\t}\n\n\tfunction removeAllEvents(el, type) {\n\t\tvar events = el.HCEvents,\n\t\t\tremove,\n\t\t\ttypes,\n\t\t\tlen,\n\t\t\tn;\n\n\t\tif (el.removeEventListener) {\n\t\t\tremove = removeOneEvent;\n\t\t} else if (el.attachEvent) {\n\t\t\tremove = IERemoveOneEvent;\n\t\t} else {\n\t\t\treturn; // break on non-DOM events\n\t\t}\n\n\n\t\tif (type) {\n\t\t\ttypes = {};\n\t\t\ttypes[type] = true;\n\t\t} else {\n\t\t\ttypes = events;\n\t\t}\n\n\t\tfor (n in types) {\n\t\t\tif (events[n]) {\n\t\t\t\tlen = events[n].length;\n\t\t\t\twhile (len--) {\n\t\t\t\t\tremove(el, n, events[n][len]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\tif (!obj.HCExtended) {\n\t\tHighcharts.extend(obj, {\n\t\t\tHCExtended: true,\n\n\t\t\tHCEvents: {},\n\n\t\t\tbind: function (name, fn) {\n\t\t\t\tvar el = this,\n\t\t\t\t\tevents = this.HCEvents,\n\t\t\t\t\twrappedFn;\n\n\t\t\t\t// handle DOM events in modern browsers\n\t\t\t\tif (el.addEventListener) {\n\t\t\t\t\tel.addEventListener(name, fn, false);\n\n\t\t\t\t// handle old IE implementation\n\t\t\t\t} else if (el.attachEvent) {\n\t\t\t\t\t\n\t\t\t\t\twrappedFn = function (e) {\n\t\t\t\t\t\tfn.call(el, e);\n\t\t\t\t\t};\n\n\t\t\t\t\tif (!el.HCProxiedMethods) {\n\t\t\t\t\t\tel.HCProxiedMethods = {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// link wrapped fn with original fn, so we can get this in removeEvent\n\t\t\t\t\tel.HCProxiedMethods[fn.toString()] = wrappedFn;\n\n\t\t\t\t\tel.attachEvent('on' + name, wrappedFn);\n\t\t\t\t}\n\n\n\t\t\t\tif (events[name] === UNDEFINED) {\n\t\t\t\t\tevents[name] = [];\n\t\t\t\t}\n\n\t\t\t\tevents[name].push(fn);\n\t\t\t},\n\n\t\t\tunbind: function (name, fn) {\n\t\t\t\tvar events,\n\t\t\t\t\tindex;\n\n\t\t\t\tif (name) {\n\t\t\t\t\tevents = this.HCEvents[name] || [];\n\t\t\t\t\tif (fn) {\n\t\t\t\t\t\tindex = HighchartsAdapter.inArray(fn, events);\n\t\t\t\t\t\tif (index > -1) {\n\t\t\t\t\t\t\tevents.splice(index, 1);\n\t\t\t\t\t\t\tthis.HCEvents[name] = events;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (this.removeEventListener) {\n\t\t\t\t\t\t\tremoveOneEvent(this, name, fn);\n\t\t\t\t\t\t} else if (this.attachEvent) {\n\t\t\t\t\t\t\tIERemoveOneEvent(this, name, fn);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tremoveAllEvents(this, name);\n\t\t\t\t\t\tthis.HCEvents[name] = [];\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tremoveAllEvents(this);\n\t\t\t\t\tthis.HCEvents = {};\n\t\t\t\t}\n\t\t\t},\n\n\t\t\ttrigger: function (name, args) {\n\t\t\t\tvar events = this.HCEvents[name] || [],\n\t\t\t\t\ttarget = this,\n\t\t\t\t\tlen = events.length,\n\t\t\t\t\ti,\n\t\t\t\t\tpreventDefault,\n\t\t\t\t\tfn;\n\n\t\t\t\t// Attach a simple preventDefault function to skip default handler if called\n\t\t\t\tpreventDefault = function () {\n\t\t\t\t\targs.defaultPrevented = true;\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\t\tfn = events[i];\n\n\t\t\t\t\t// args is never null here\n\t\t\t\t\tif (args.stopped) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\targs.preventDefault = preventDefault;\n\t\t\t\t\targs.target = target;\n\t\t\t\t\targs.type = name; // #2297\t\n\t\t\t\t\t\n\t\t\t\t\t// If the event handler return false, prevent the default handler from executing\n\t\t\t\t\tif (fn.call(this, args) === false) {\n\t\t\t\t\t\targs.preventDefault();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t}\n\n\treturn obj;\n}\n\n\nreturn {\n\t/**\n\t * Initialize the adapter. This is run once as Highcharts is first run.\n\t */\n\tinit: function (pathAnim) {\n\n\t\t/**\n\t\t * Compatibility section to add support for legacy IE. This can be removed if old IE \n\t\t * support is not needed.\n\t\t */\n\t\tif (!doc.defaultView) {\n\t\t\tthis._getStyle = function (el, prop) {\n\t\t\t\tvar val;\n\t\t\t\tif (el.style[prop]) {\n\t\t\t\t\treturn el.style[prop];\n\t\t\t\t} else {\n\t\t\t\t\tif (prop === 'opacity') {\n\t\t\t\t\t\tprop = 'filter';\n\t\t\t\t\t}\n\t\t\t\t\t/*jslint unparam: true*/\n\t\t\t\t\tval = el.currentStyle[prop.replace(/\\-(\\w)/g, function (a, b) { return b.toUpperCase(); })];\n\t\t\t\t\tif (prop === 'filter') {\n\t\t\t\t\t\tval = val.replace(\n\t\t\t\t\t\t\t/alpha\\(opacity=([0-9]+)\\)/, \n\t\t\t\t\t\t\tfunction (a, b) { \n\t\t\t\t\t\t\t\treturn b / 100; \n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\t/*jslint unparam: false*/\n\t\t\t\t\treturn val === '' ? 1 : val;\n\t\t\t\t} \n\t\t\t};\n\t\t\tthis.adapterRun = function (elem, method) {\n\t\t\t\tvar alias = { width: 'clientWidth', height: 'clientHeight' }[method];\n\n\t\t\t\tif (alias) {\n\t\t\t\t\telem.style.zoom = 1;\n\t\t\t\t\treturn elem[alias] - 2 * parseInt(HighchartsAdapter._getStyle(elem, 'padding'), 10);\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tif (!Array.prototype.forEach) {\n\t\t\tthis.each = function (arr, fn) { // legacy\n\t\t\t\tvar i = 0, \n\t\t\t\t\tlen = arr.length;\n\t\t\t\tfor (; i < len; i++) {\n\t\t\t\t\tif (fn.call(arr[i], arr[i], i, arr) === false) {\n\t\t\t\t\t\treturn i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\n\t\tif (!Array.prototype.indexOf) {\n\t\t\tthis.inArray = function (item, arr) {\n\t\t\t\tvar len, \n\t\t\t\t\ti = 0;\n\n\t\t\t\tif (arr) {\n\t\t\t\t\tlen = arr.length;\n\t\t\t\t\t\n\t\t\t\t\tfor (; i < len; i++) {\n\t\t\t\t\t\tif (arr[i] === item) {\n\t\t\t\t\t\t\treturn i;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn -1;\n\t\t\t};\n\t\t}\n\n\t\tif (!Array.prototype.filter) {\n\t\t\tthis.grep = function (elements, callback) {\n\t\t\t\tvar ret = [],\n\t\t\t\t\ti = 0,\n\t\t\t\t\tlength = elements.length;\n\n\t\t\t\tfor (; i < length; i++) {\n\t\t\t\t\tif (!!callback(elements[i], i)) {\n\t\t\t\t\t\tret.push(elements[i]);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn ret;\n\t\t\t};\n\t\t}\n\n\t\t//--- End compatibility section ---\n\n\n\t\t/**\n\t\t * Start of animation specific code\n\t\t */\n\t\tFx = function (elem, options, prop) {\n\t\t\tthis.options = options;\n\t\t\tthis.elem = elem;\n\t\t\tthis.prop = prop;\n\t\t};\n\t\tFx.prototype = {\n\t\t\t\n\t\t\tupdate: function () {\n\t\t\t\tvar styles,\n\t\t\t\t\tpaths = this.paths,\n\t\t\t\t\telem = this.elem,\n\t\t\t\t\telemelem = elem.element; // if destroyed, it is null\n\n\t\t\t\t// Animating a path definition on SVGElement\n\t\t\t\tif (paths && elemelem) {\n\t\t\t\t\telem.attr('d', pathAnim.step(paths[0], paths[1], this.now, this.toD));\n\t\t\t\t\n\t\t\t\t// Other animations on SVGElement\n\t\t\t\t} else if (elem.attr) {\n\t\t\t\t\tif (elemelem) {\n\t\t\t\t\t\telem.attr(this.prop, this.now);\n\t\t\t\t\t}\n\n\t\t\t\t// HTML styles\n\t\t\t\t} else {\n\t\t\t\t\tstyles = {};\n\t\t\t\t\tstyles[elem] = this.now + this.unit;\n\t\t\t\t\tHighcharts.css(elem, styles);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (this.options.step) {\n\t\t\t\t\tthis.options.step.call(this.elem, this.now, this);\n\t\t\t\t}\n\n\t\t\t},\n\t\t\tcustom: function (from, to, unit) {\n\t\t\t\tvar self = this,\n\t\t\t\t\tt = function (gotoEnd) {\n\t\t\t\t\t\treturn self.step(gotoEnd);\n\t\t\t\t\t},\n\t\t\t\t\ti;\n\n\t\t\t\tthis.startTime = +new Date();\n\t\t\t\tthis.start = from;\n\t\t\t\tthis.end = to;\n\t\t\t\tthis.unit = unit;\n\t\t\t\tthis.now = this.start;\n\t\t\t\tthis.pos = this.state = 0;\n\n\t\t\t\tt.elem = this.elem;\n\n\t\t\t\tif (t() && timers.push(t) === 1) {\n\t\t\t\t\ttimerId = setInterval(function () {\n\t\t\t\t\t\t\n\t\t\t\t\t\tfor (i = 0; i < timers.length; i++) {\n\t\t\t\t\t\t\tif (!timers[i]()) {\n\t\t\t\t\t\t\t\ttimers.splice(i--, 1);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!timers.length) {\n\t\t\t\t\t\t\tclearInterval(timerId);\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 13);\n\t\t\t\t}\n\t\t\t},\n\t\t\t\n\t\t\tstep: function (gotoEnd) {\n\t\t\t\tvar t = +new Date(),\n\t\t\t\t\tret,\n\t\t\t\t\tdone,\n\t\t\t\t\toptions = this.options,\n\t\t\t\t\ti;\n\n\t\t\t\tif (this.elem.stopAnimation) {\n\t\t\t\t\tret = false;\n\n\t\t\t\t} else if (gotoEnd || t >= options.duration + this.startTime) {\n\t\t\t\t\tthis.now = this.end;\n\t\t\t\t\tthis.pos = this.state = 1;\n\t\t\t\t\tthis.update();\n\n\t\t\t\t\tthis.options.curAnim[this.prop] = true;\n\n\t\t\t\t\tdone = true;\n\t\t\t\t\tfor (i in options.curAnim) {\n\t\t\t\t\t\tif (options.curAnim[i] !== true) {\n\t\t\t\t\t\t\tdone = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (done) {\n\t\t\t\t\t\tif (options.complete) {\n\t\t\t\t\t\t\toptions.complete.call(this.elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tret = false;\n\n\t\t\t\t} else {\n\t\t\t\t\tvar n = t - this.startTime;\n\t\t\t\t\tthis.state = n / options.duration;\n\t\t\t\t\tthis.pos = options.easing(n, 0, 1, options.duration);\n\t\t\t\t\tthis.now = this.start + ((this.end - this.start) * this.pos);\n\t\t\t\t\tthis.update();\n\t\t\t\t\tret = true;\n\t\t\t\t}\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t};\n\n\t\t/**\n\t\t * The adapter animate method\n\t\t */\n\t\tthis.animate = function (el, prop, opt) {\n\t\t\tvar start,\n\t\t\t\tunit = '',\n\t\t\t\tend,\n\t\t\t\tfx,\n\t\t\t\targs,\n\t\t\t\tname;\n\n\t\t\tel.stopAnimation = false; // ready for new\n\n\t\t\tif (typeof opt !== 'object' || opt === null) {\n\t\t\t\targs = arguments;\n\t\t\t\topt = {\n\t\t\t\t\tduration: args[2],\n\t\t\t\t\teasing: args[3],\n\t\t\t\t\tcomplete: args[4]\n\t\t\t\t};\n\t\t\t}\n\t\t\tif (typeof opt.duration !== 'number') {\n\t\t\t\topt.duration = 400;\n\t\t\t}\n\t\t\topt.easing = Math[opt.easing] || Math.easeInOutSine;\n\t\t\topt.curAnim = Highcharts.extend({}, prop);\n\t\t\t\n\t\t\tfor (name in prop) {\n\t\t\t\tfx = new Fx(el, opt, name);\n\t\t\t\tend = null;\n\t\t\t\t\n\t\t\t\tif (name === 'd') {\n\t\t\t\t\tfx.paths = pathAnim.init(\n\t\t\t\t\t\tel,\n\t\t\t\t\t\tel.d,\n\t\t\t\t\t\tprop.d\n\t\t\t\t\t);\n\t\t\t\t\tfx.toD = prop.d;\n\t\t\t\t\tstart = 0;\n\t\t\t\t\tend = 1;\n\t\t\t\t} else if (el.attr) {\n\t\t\t\t\tstart = el.attr(name);\n\t\t\t\t} else {\n\t\t\t\t\tstart = parseFloat(HighchartsAdapter._getStyle(el, name)) || 0;\n\t\t\t\t\tif (name !== 'opacity') {\n\t\t\t\t\t\tunit = 'px';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\n\t\t\t\tif (!end) {\n\t\t\t\t\tend = parseFloat(prop[name]);\n\t\t\t\t}\n\t\t\t\tfx.custom(start, end, unit);\n\t\t\t}\t\n\t\t};\n\t},\n\n\t/**\n\t * Internal method to return CSS value for given element and property\n\t */\n\t_getStyle: function (el, prop) {\n\t\treturn window.getComputedStyle(el).getPropertyValue(prop);\n\t},\n\n\t/**\n\t * Downloads a script and executes a callback when done.\n\t * @param {String} scriptLocation\n\t * @param {Function} callback\n\t */\n\tgetScript: function (scriptLocation, callback) {\n\t\t// We cannot assume that Assets class from mootools-more is available so instead insert a script tag to download script.\n\t\tvar head = doc.getElementsByTagName('head')[0],\n\t\t\tscript = doc.createElement('script');\n\n\t\tscript.type = 'text/javascript';\n\t\tscript.src = scriptLocation;\n\t\tscript.onload = callback;\n\n\t\thead.appendChild(script);\n\t},\n\n\t/**\n\t * Return the index of an item in an array, or -1 if not found\n\t */\n\tinArray: function (item, arr) {\n\t\treturn arr.indexOf ? arr.indexOf(item) : emptyArray.indexOf.call(arr, item);\n\t},\n\n\n\t/**\n\t * A direct link to adapter methods\n\t */\n\tadapterRun: function (elem, method) {\n\t\treturn parseInt(HighchartsAdapter._getStyle(elem, method), 10);\n\t},\n\n\t/**\n\t * Filter an array\n\t */\n\tgrep: function (elements, callback) {\n\t\treturn emptyArray.filter.call(elements, callback);\n\t},\n\n\t/**\n\t * Map an array\n\t */\n\tmap: function (arr, fn) {\n\t\tvar results = [], i = 0, len = arr.length;\n\n\t\tfor (; i < len; i++) {\n\t\t\tresults[i] = fn.call(arr[i], arr[i], i, arr);\n\t\t}\n\n\t\treturn results;\n\t},\n\n\toffset: function (el) {\n\t\tvar left = 0,\n\t\t\ttop = 0;\n\n\t\twhile (el) {\n\t\t\tleft += el.offsetLeft;\n\t\t\ttop += el.offsetTop;\n\t\t\tel = el.offsetParent;\n\t\t}\n\n\t\treturn {\n\t\t\tleft: left,\n\t\t\ttop: top\n\t\t};\n\t},\n\n\t/**\n\t * Add an event listener\n\t */\n\taddEvent: function (el, type, fn) {\n\t\taugment(el).bind(type, fn);\n\t},\n\n\t/**\n\t * Remove event added with addEvent\n\t */\n\tremoveEvent: function (el, type, fn) {\n\t\taugment(el).unbind(type, fn);\n\t},\n\n\t/**\n\t * Fire an event on a custom object\n\t */\n\tfireEvent: function (el, type, eventArguments, defaultFunction) {\n\t\tvar e;\n\n\t\tif (doc.createEvent && (el.dispatchEvent || el.fireEvent)) {\n\t\t\te = doc.createEvent('Events');\n\t\t\te.initEvent(type, true, true);\n\t\t\te.target = el;\n\n\t\t\tHighcharts.extend(e, eventArguments);\n\n\t\t\tif (el.dispatchEvent) {\n\t\t\t\tel.dispatchEvent(e);\n\t\t\t} else {\n\t\t\t\tel.fireEvent(type, e);\n\t\t\t}\n\n\t\t} else if (el.HCExtended === true) {\n\t\t\teventArguments = eventArguments || {};\n\t\t\tel.trigger(type, eventArguments);\n\t\t}\n\n\t\tif (eventArguments && eventArguments.defaultPrevented) {\n\t\t\tdefaultFunction = null;\n\t\t}\n\n\t\tif (defaultFunction) {\n\t\t\tdefaultFunction(eventArguments);\n\t\t}\n\t},\n\n\twashMouseEvent: function (e) {\n\t\treturn e;\n\t},\n\n\n\t/**\n\t * Stop running animation\n\t */\n\tstop: function (el) {\n\t\tel.stopAnimation = true;\n\t},\n\n\t/**\n\t * Utility for iterating over an array. Parameters are reversed compared to jQuery.\n\t * @param {Array} arr\n\t * @param {Function} fn\n\t */\n\teach: function (arr, fn) { // modern browsers\n\t\treturn Array.prototype.forEach.call(arr, fn);\n\t}\n};\n}());\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/highcharts-more.js",
    "content": "/*\n Highcharts JS v3.0.6 (2013-10-04)\n\n (c) 2009-2013 Torstein Hønsi\n\n License: www.highcharts.com/license\n*/\n(function(j,C){function J(a,b,c){this.init.call(this,a,b,c)}function K(a,b,c){a.call(this,b,c);if(this.chart.polar)this.closeSegment=function(a){var c=this.xAxis.center;a.push(\"L\",c[0],c[1])},this.closedStacks=!0}function L(a,b){var c=this.chart,d=this.options.animation,g=this.group,f=this.markerGroup,e=this.xAxis.center,i=c.plotLeft,n=c.plotTop;if(c.polar){if(c.renderer.isSVG)if(d===!0&&(d={}),b){if(c={translateX:e[0]+i,translateY:e[1]+n,scaleX:0.001,scaleY:0.001},g.attr(c),f)f.attrSetters=g.attrSetters,\nf.attr(c)}else c={translateX:i,translateY:n,scaleX:1,scaleY:1},g.animate(c,d),f&&f.animate(c,d),this.animate=null}else a.call(this,b)}var P=j.arrayMin,Q=j.arrayMax,s=j.each,F=j.extend,p=j.merge,R=j.map,r=j.pick,v=j.pInt,m=j.getOptions().plotOptions,h=j.seriesTypes,x=j.extendClass,M=j.splat,o=j.wrap,N=j.Axis,u=j.Tick,z=j.Series,q=h.column.prototype,t=Math,D=t.round,A=t.floor,S=t.max,w=function(){};F(J.prototype,{init:function(a,b,c){var d=this,g=d.defaultOptions;d.chart=b;if(b.angular)g.background=\n{};d.options=a=p(g,a);(a=a.background)&&s([].concat(M(a)).reverse(),function(a){var b=a.backgroundColor,a=p(d.defaultBackgroundOptions,a);if(b)a.backgroundColor=b;a.color=a.backgroundColor;c.options.plotBands.unshift(a)})},defaultOptions:{center:[\"50%\",\"50%\"],size:\"85%\",startAngle:0},defaultBackgroundOptions:{shape:\"circle\",borderWidth:1,borderColor:\"silver\",backgroundColor:{linearGradient:{x1:0,y1:0,x2:0,y2:1},stops:[[0,\"#FFF\"],[1,\"#DDD\"]]},from:Number.MIN_VALUE,innerRadius:0,to:Number.MAX_VALUE,\nouterRadius:\"105%\"}});var G=N.prototype,u=u.prototype,T={getOffset:w,redraw:function(){this.isDirty=!1},render:function(){this.isDirty=!1},setScale:w,setCategories:w,setTitle:w},O={isRadial:!0,defaultRadialGaugeOptions:{labels:{align:\"center\",x:0,y:null},minorGridLineWidth:0,minorTickInterval:\"auto\",minorTickLength:10,minorTickPosition:\"inside\",minorTickWidth:1,plotBands:[],tickLength:10,tickPosition:\"inside\",tickWidth:2,title:{rotation:0},zIndex:2},defaultRadialXOptions:{gridLineWidth:1,labels:{align:null,\ndistance:15,x:0,y:null},maxPadding:0,minPadding:0,plotBands:[],showLastLabel:!1,tickLength:0},defaultRadialYOptions:{gridLineInterpolation:\"circle\",labels:{align:\"right\",x:-3,y:-2},plotBands:[],showLastLabel:!1,title:{x:4,text:null,rotation:90}},setOptions:function(a){this.options=p(this.defaultOptions,this.defaultRadialOptions,a)},getOffset:function(){G.getOffset.call(this);this.chart.axisOffset[this.side]=0},getLinePath:function(a,b){var c=this.center,b=r(b,c[2]/2-this.offset);return this.chart.renderer.symbols.arc(this.left+\nc[0],this.top+c[1],b,b,{start:this.startAngleRad,end:this.endAngleRad,open:!0,innerR:0})},setAxisTranslation:function(){G.setAxisTranslation.call(this);if(this.center&&(this.transA=this.isCircular?(this.endAngleRad-this.startAngleRad)/(this.max-this.min||1):this.center[2]/2/(this.max-this.min||1),this.isXAxis))this.minPixelPadding=this.transA*this.minPointOffset+(this.reversed?(this.endAngleRad-this.startAngleRad)/4:0)},beforeSetTickPositions:function(){this.autoConnect&&(this.max+=this.categories&&\n1||this.pointRange||this.closestPointRange||0)},setAxisSize:function(){G.setAxisSize.call(this);if(this.isRadial)this.center=this.pane.center=h.pie.prototype.getCenter.call(this.pane),this.len=this.width=this.height=this.isCircular?this.center[2]*(this.endAngleRad-this.startAngleRad)/2:this.center[2]/2},getPosition:function(a,b){if(!this.isCircular)b=this.translate(a),a=this.min;return this.postTranslate(this.translate(a),r(b,this.center[2]/2)-this.offset)},postTranslate:function(a,b){var c=this.chart,\nd=this.center,a=this.startAngleRad+a;return{x:c.plotLeft+d[0]+Math.cos(a)*b,y:c.plotTop+d[1]+Math.sin(a)*b}},getPlotBandPath:function(a,b,c){var d=this.center,g=this.startAngleRad,f=d[2]/2,e=[r(c.outerRadius,\"100%\"),c.innerRadius,r(c.thickness,10)],i=/%$/,n,l=this.isCircular;this.options.gridLineInterpolation===\"polygon\"?d=this.getPlotLinePath(a).concat(this.getPlotLinePath(b,!0)):(l||(e[0]=this.translate(a),e[1]=this.translate(b)),e=R(e,function(a){i.test(a)&&(a=v(a,10)*f/100);return a}),c.shape===\n\"circle\"||!l?(a=-Math.PI/2,b=Math.PI*1.5,n=!0):(a=g+this.translate(a),b=g+this.translate(b)),d=this.chart.renderer.symbols.arc(this.left+d[0],this.top+d[1],e[0],e[0],{start:a,end:b,innerR:r(e[1],e[0]-e[2]),open:n}));return d},getPlotLinePath:function(a,b){var c=this.center,d=this.chart,g=this.getPosition(a),f,e,i;this.isCircular?i=[\"M\",c[0]+d.plotLeft,c[1]+d.plotTop,\"L\",g.x,g.y]:this.options.gridLineInterpolation===\"circle\"?(a=this.translate(a))&&(i=this.getLinePath(0,a)):(f=d.xAxis[0],i=[],a=this.translate(a),\nc=f.tickPositions,f.autoConnect&&(c=c.concat([c[0]])),b&&(c=[].concat(c).reverse()),s(c,function(c,b){e=f.getPosition(c,a);i.push(b?\"L\":\"M\",e.x,e.y)}));return i},getTitlePosition:function(){var a=this.center,b=this.chart,c=this.options.title;return{x:b.plotLeft+a[0]+(c.x||0),y:b.plotTop+a[1]-{high:0.5,middle:0.25,low:0}[c.align]*a[2]+(c.y||0)}}};o(G,\"init\",function(a,b,c){var k;var d=b.angular,g=b.polar,f=c.isX,e=d&&f,i,n;n=b.options;var l=c.pane||0;if(d){if(F(this,e?T:O),i=!f)this.defaultRadialOptions=\nthis.defaultRadialGaugeOptions}else if(g)F(this,O),this.defaultRadialOptions=(i=f)?this.defaultRadialXOptions:p(this.defaultYAxisOptions,this.defaultRadialYOptions);a.call(this,b,c);if(!e&&(d||g)){a=this.options;if(!b.panes)b.panes=[];this.pane=(k=b.panes[l]=b.panes[l]||new J(M(n.pane)[l],b,this),l=k);l=l.options;b.inverted=!1;n.chart.zoomType=null;this.startAngleRad=b=(l.startAngle-90)*Math.PI/180;this.endAngleRad=n=(r(l.endAngle,l.startAngle+360)-90)*Math.PI/180;this.offset=a.offset||0;if((this.isCircular=\ni)&&c.max===C&&n-b===2*Math.PI)this.autoConnect=!0}});o(u,\"getPosition\",function(a,b,c,d,g){var f=this.axis;return f.getPosition?f.getPosition(c):a.call(this,b,c,d,g)});o(u,\"getLabelPosition\",function(a,b,c,d,g,f,e,i,n){var l=this.axis,k=f.y,h=f.align,j=(l.translate(this.pos)+l.startAngleRad+Math.PI/2)/Math.PI*180%360;l.isRadial?(a=l.getPosition(this.pos,l.center[2]/2+r(f.distance,-25)),f.rotation===\"auto\"?d.attr({rotation:j}):k===null&&(k=v(d.styles.lineHeight)*0.9-d.getBBox().height/2),h===null&&\n(h=l.isCircular?j>20&&j<160?\"left\":j>200&&j<340?\"right\":\"center\":\"center\",d.attr({align:h})),a.x+=f.x,a.y+=k):a=a.call(this,b,c,d,g,f,e,i,n);return a});o(u,\"getMarkPath\",function(a,b,c,d,g,f,e){var i=this.axis;i.isRadial?(a=i.getPosition(this.pos,i.center[2]/2+d),b=[\"M\",b,c,\"L\",a.x,a.y]):b=a.call(this,b,c,d,g,f,e);return b});m.arearange=p(m.area,{lineWidth:1,marker:null,threshold:null,tooltip:{pointFormat:'<span style=\"color:{series.color}\">{series.name}</span>: <b>{point.low}</b> - <b>{point.high}</b><br/>'},\ntrackByArea:!0,dataLabels:{verticalAlign:null,xLow:0,xHigh:0,yLow:0,yHigh:0}});h.arearange=j.extendClass(h.area,{type:\"arearange\",pointArrayMap:[\"low\",\"high\"],toYData:function(a){return[a.low,a.high]},pointValKey:\"low\",getSegments:function(){var a=this;s(a.points,function(b){if(!a.options.connectNulls&&(b.low===null||b.high===null))b.y=null;else if(b.low===null&&b.high!==null)b.y=b.high});z.prototype.getSegments.call(this)},translate:function(){var a=this.yAxis;h.area.prototype.translate.apply(this);\ns(this.points,function(b){var c=b.low,d=b.high,g=b.plotY;d===null&&c===null?b.y=null:c===null?(b.plotLow=b.plotY=null,b.plotHigh=a.translate(d,0,1,0,1)):d===null?(b.plotLow=g,b.plotHigh=null):(b.plotLow=g,b.plotHigh=a.translate(d,0,1,0,1))})},getSegmentPath:function(a){var b,c=[],d=a.length,g=z.prototype.getSegmentPath,f,e;e=this.options;var i=e.step;for(b=HighchartsAdapter.grep(a,function(a){return a.plotLow!==null});d--;)f=a[d],f.plotHigh!==null&&c.push({plotX:f.plotX,plotY:f.plotHigh});a=g.call(this,\nb);if(i)i===!0&&(i=\"left\"),e.step={left:\"right\",center:\"center\",right:\"left\"}[i];c=g.call(this,c);e.step=i;e=[].concat(a,c);c[0]=\"L\";this.areaPath=this.areaPath.concat(a,c);return e},drawDataLabels:function(){var a=this.data,b=a.length,c,d=[],g=z.prototype,f=this.options.dataLabels,e,i=this.chart.inverted;if(f.enabled||this._hasPointLabels){for(c=b;c--;)e=a[c],e.y=e.high,e.plotY=e.plotHigh,d[c]=e.dataLabel,e.dataLabel=e.dataLabelUpper,e.below=!1,i?(f.align=\"left\",f.x=f.xHigh):f.y=f.yHigh;g.drawDataLabels.apply(this,\narguments);for(c=b;c--;)e=a[c],e.dataLabelUpper=e.dataLabel,e.dataLabel=d[c],e.y=e.low,e.plotY=e.plotLow,e.below=!0,i?(f.align=\"right\",f.x=f.xLow):f.y=f.yLow;g.drawDataLabels.apply(this,arguments)}},alignDataLabel:h.column.prototype.alignDataLabel,getSymbol:h.column.prototype.getSymbol,drawPoints:w});m.areasplinerange=p(m.arearange);h.areasplinerange=x(h.arearange,{type:\"areasplinerange\",getPointSpline:h.spline.prototype.getPointSpline});m.columnrange=p(m.column,m.arearange,{lineWidth:1,pointRange:null});\nh.columnrange=x(h.arearange,{type:\"columnrange\",translate:function(){var a=this,b=a.yAxis,c;q.translate.apply(a);s(a.points,function(d){var g=d.shapeArgs,f=a.options.minPointLength,e;d.plotHigh=c=b.translate(d.high,0,1,0,1);d.plotLow=d.plotY;e=c;d=d.plotY-c;d<f&&(f-=d,d+=f,e-=f/2);g.height=d;g.y=e})},trackerGroups:[\"group\",\"dataLabels\"],drawGraph:w,pointAttrToOptions:q.pointAttrToOptions,drawPoints:q.drawPoints,drawTracker:q.drawTracker,animate:q.animate,getColumnMetrics:q.getColumnMetrics});m.gauge=\np(m.line,{dataLabels:{enabled:!0,y:15,borderWidth:1,borderColor:\"silver\",borderRadius:3,style:{fontWeight:\"bold\"},verticalAlign:\"top\",zIndex:2},dial:{},pivot:{},tooltip:{headerFormat:\"\"},showInLegend:!1});u={type:\"gauge\",pointClass:j.extendClass(j.Point,{setState:function(a){this.state=a}}),angular:!0,drawGraph:w,fixedBox:!0,trackerGroups:[\"group\",\"dataLabels\"],translate:function(){var a=this.yAxis,b=this.options,c=a.center;this.generatePoints();s(this.points,function(d){var g=p(b.dial,d.dial),f=\nv(r(g.radius,80))*c[2]/200,e=v(r(g.baseLength,70))*f/100,i=v(r(g.rearLength,10))*f/100,n=g.baseWidth||3,l=g.topWidth||1,k=a.startAngleRad+a.translate(d.y,null,null,null,!0);b.wrap===!1&&(k=Math.max(a.startAngleRad,Math.min(a.endAngleRad,k)));k=k*180/Math.PI;d.shapeType=\"path\";d.shapeArgs={d:g.path||[\"M\",-i,-n/2,\"L\",e,-n/2,f,-l/2,f,l/2,e,n/2,-i,n/2,\"z\"],translateX:c[0],translateY:c[1],rotation:k};d.plotX=c[0];d.plotY=c[1]})},drawPoints:function(){var a=this,b=a.yAxis.center,c=a.pivot,d=a.options,g=\nd.pivot,f=a.chart.renderer;s(a.points,function(c){var b=c.graphic,g=c.shapeArgs,l=g.d,k=p(d.dial,c.dial);b?(b.animate(g),g.d=l):c.graphic=f[c.shapeType](g).attr({stroke:k.borderColor||\"none\",\"stroke-width\":k.borderWidth||0,fill:k.backgroundColor||\"black\",rotation:g.rotation}).add(a.group)});c?c.animate({translateX:b[0],translateY:b[1]}):a.pivot=f.circle(0,0,r(g.radius,5)).attr({\"stroke-width\":g.borderWidth||0,stroke:g.borderColor||\"silver\",fill:g.backgroundColor||\"black\"}).translate(b[0],b[1]).add(a.group)},\nanimate:function(a){var b=this;if(!a)s(b.points,function(a){var d=a.graphic;d&&(d.attr({rotation:b.yAxis.startAngleRad*180/Math.PI}),d.animate({rotation:a.shapeArgs.rotation},b.options.animation))}),b.animate=null},render:function(){this.group=this.plotGroup(\"group\",\"series\",this.visible?\"visible\":\"hidden\",this.options.zIndex,this.chart.seriesGroup);h.pie.prototype.render.call(this);this.group.clip(this.chart.clipRect)},setData:h.pie.prototype.setData,drawTracker:h.column.prototype.drawTracker};h.gauge=\nj.extendClass(h.line,u);m.boxplot=p(m.column,{fillColor:\"#FFFFFF\",lineWidth:1,medianWidth:2,states:{hover:{brightness:-0.3}},threshold:null,tooltip:{pointFormat:'<span style=\"color:{series.color};font-weight:bold\">{series.name}</span><br/>Maximum: {point.high}<br/>Upper quartile: {point.q3}<br/>Median: {point.median}<br/>Lower quartile: {point.q1}<br/>Minimum: {point.low}<br/>'},whiskerLength:\"50%\",whiskerWidth:2});h.boxplot=x(h.column,{type:\"boxplot\",pointArrayMap:[\"low\",\"q1\",\"median\",\"q3\",\"high\"],\ntoYData:function(a){return[a.low,a.q1,a.median,a.q3,a.high]},pointValKey:\"high\",pointAttrToOptions:{fill:\"fillColor\",stroke:\"color\",\"stroke-width\":\"lineWidth\"},drawDataLabels:w,translate:function(){var a=this.yAxis,b=this.pointArrayMap;h.column.prototype.translate.apply(this);s(this.points,function(c){s(b,function(b){c[b]!==null&&(c[b+\"Plot\"]=a.translate(c[b],0,1,0,1))})})},drawPoints:function(){var a=this,b=a.points,c=a.options,d=a.chart.renderer,g,f,e,i,n,l,k,h,j,m,o,H,p,E,I,q,w,t,v,u,z,y,x=a.doQuartiles!==\n!1,B=parseInt(a.options.whiskerLength,10)/100;s(b,function(b){j=b.graphic;z=b.shapeArgs;o={};E={};q={};y=b.color||a.color;if(b.plotY!==C)if(g=b.pointAttr[b.selected?\"selected\":\"\"],w=z.width,t=A(z.x),v=t+w,u=D(w/2),f=A(x?b.q1Plot:b.lowPlot),e=A(x?b.q3Plot:b.lowPlot),i=A(b.highPlot),n=A(b.lowPlot),o.stroke=b.stemColor||c.stemColor||y,o[\"stroke-width\"]=r(b.stemWidth,c.stemWidth,c.lineWidth),o.dashstyle=b.stemDashStyle||c.stemDashStyle,E.stroke=b.whiskerColor||c.whiskerColor||y,E[\"stroke-width\"]=r(b.whiskerWidth,\nc.whiskerWidth,c.lineWidth),q.stroke=b.medianColor||c.medianColor||y,q[\"stroke-width\"]=r(b.medianWidth,c.medianWidth,c.lineWidth),k=o[\"stroke-width\"]%2/2,h=t+u+k,m=[\"M\",h,e,\"L\",h,i,\"M\",h,f,\"L\",h,n,\"z\"],x&&(k=g[\"stroke-width\"]%2/2,h=A(h)+k,f=A(f)+k,e=A(e)+k,t+=k,v+=k,H=[\"M\",t,e,\"L\",t,f,\"L\",v,f,\"L\",v,e,\"L\",t,e,\"z\"]),B&&(k=E[\"stroke-width\"]%2/2,i+=k,n+=k,p=[\"M\",h-u*B,i,\"L\",h+u*B,i,\"M\",h-u*B,n,\"L\",h+u*B,n]),k=q[\"stroke-width\"]%2/2,l=D(b.medianPlot)+k,I=[\"M\",t,l,\"L\",v,l,\"z\"],j)b.stem.animate({d:m}),B&&\nb.whiskers.animate({d:p}),x&&b.box.animate({d:H}),b.medianShape.animate({d:I});else{b.graphic=j=d.g().add(a.group);b.stem=d.path(m).attr(o).add(j);if(B)b.whiskers=d.path(p).attr(E).add(j);if(x)b.box=d.path(H).attr(g).add(j);b.medianShape=d.path(I).attr(q).add(j)}})}});m.errorbar=p(m.boxplot,{color:\"#000000\",grouping:!1,linkedTo:\":previous\",tooltip:{pointFormat:m.arearange.tooltip.pointFormat},whiskerWidth:null});h.errorbar=x(h.boxplot,{type:\"errorbar\",pointArrayMap:[\"low\",\"high\"],toYData:function(a){return[a.low,\na.high]},pointValKey:\"high\",doQuartiles:!1,getColumnMetrics:function(){return this.linkedParent&&this.linkedParent.columnMetrics||h.column.prototype.getColumnMetrics.call(this)}});m.waterfall=p(m.column,{lineWidth:1,lineColor:\"#333\",dashStyle:\"dot\",borderColor:\"#333\"});h.waterfall=x(h.column,{type:\"waterfall\",upColorProp:\"fill\",pointArrayMap:[\"low\",\"y\"],pointValKey:\"y\",init:function(a,b){b.stacking=!0;h.column.prototype.init.call(this,a,b)},translate:function(){var a=this.options,b=this.yAxis,c,d,\ng,f,e,i,n,l,k;c=a.threshold;a=a.borderWidth%2/2;h.column.prototype.translate.apply(this);l=c;g=this.points;for(d=0,c=g.length;d<c;d++){f=g[d];e=f.shapeArgs;i=this.getStack(d);k=i.points[this.index];if(isNaN(f.y))f.y=this.yData[d];n=S(l,l+f.y)+k[0];e.y=b.translate(n,0,1);f.isSum||f.isIntermediateSum?(e.y=b.translate(k[1],0,1),e.height=b.translate(k[0],0,1)-e.y):l+=i.total;e.height<0&&(e.y+=e.height,e.height*=-1);f.plotY=e.y=D(e.y)-a;e.height=D(e.height);f.yBottom=e.y+e.height}},processData:function(a){var b=\nthis.yData,c=this.points,d,g=b.length,f=this.options.threshold||0,e,i,h,l,k,j;i=e=h=l=f;for(j=0;j<g;j++)k=b[j],d=c&&c[j]?c[j]:{},k===\"sum\"||d.isSum?b[j]=i:k===\"intermediateSum\"||d.isIntermediateSum?(b[j]=e,e=f):(i+=k,e+=k),h=Math.min(i,h),l=Math.max(i,l);z.prototype.processData.call(this,a);this.dataMin=h;this.dataMax=l},toYData:function(a){if(a.isSum)return\"sum\";else if(a.isIntermediateSum)return\"intermediateSum\";return a.y},getAttribs:function(){h.column.prototype.getAttribs.apply(this,arguments);\nvar a=this.options,b=a.states,c=a.upColor||this.color,a=j.Color(c).brighten(0.1).get(),d=p(this.pointAttr),g=this.upColorProp;d[\"\"][g]=c;d.hover[g]=b.hover.upColor||a;d.select[g]=b.select.upColor||c;s(this.points,function(a){if(a.y>0&&!a.color)a.pointAttr=d,a.color=c})},getGraphPath:function(){var a=this.data,b=a.length,c=D(this.options.lineWidth+this.options.borderWidth)%2/2,d=[],g,f,e;for(e=1;e<b;e++)f=a[e].shapeArgs,g=a[e-1].shapeArgs,f=[\"M\",g.x+g.width,g.y+c,\"L\",f.x,g.y+c],a[e-1].y<0&&(f[2]+=\ng.height,f[5]+=g.height),d=d.concat(f);return d},getExtremes:w,getStack:function(a){var b=this.yAxis.stacks,c=this.stackKey;this.processedYData[a]<this.options.threshold&&(c=\"-\"+c);return b[c][a]},drawGraph:z.prototype.drawGraph});m.bubble=p(m.scatter,{dataLabels:{inside:!0,style:{color:\"white\",textShadow:\"0px 0px 3px black\"},verticalAlign:\"middle\"},marker:{lineColor:null,lineWidth:1},minSize:8,maxSize:\"20%\",tooltip:{pointFormat:\"({point.x}, {point.y}), Size: {point.z}\"},turboThreshold:0,zThreshold:0});\nh.bubble=x(h.scatter,{type:\"bubble\",pointArrayMap:[\"y\",\"z\"],trackerGroups:[\"group\",\"dataLabelsGroup\"],pointAttrToOptions:{stroke:\"lineColor\",\"stroke-width\":\"lineWidth\",fill:\"fillColor\"},applyOpacity:function(a){var b=this.options.marker,c=r(b.fillOpacity,0.5),a=a||b.fillColor||this.color;c!==1&&(a=j.Color(a).setOpacity(c).get(\"rgba\"));return a},convertAttribs:function(){var a=z.prototype.convertAttribs.apply(this,arguments);a.fill=this.applyOpacity(a.fill);return a},getRadii:function(a,b,c,d){var g,\nf,e,i=this.zData,h=[];for(f=0,g=i.length;f<g;f++)e=b-a,e=e>0?(i[f]-a)/(b-a):0.5,h.push(t.ceil(c+e*(d-c))/2);this.radii=h},animate:function(a){var b=this.options.animation;if(!a)s(this.points,function(a){var d=a.graphic,a=a.shapeArgs;d&&a&&(d.attr(\"r\",1),d.animate({r:a.r},b))}),this.animate=null},translate:function(){var a,b=this.data,c,d,g=this.radii;h.scatter.prototype.translate.call(this);for(a=b.length;a--;)c=b[a],d=g?g[a]:0,c.negative=c.z<(this.options.zThreshold||0),d>=this.minPxSize/2?(c.shapeType=\n\"circle\",c.shapeArgs={x:c.plotX,y:c.plotY,r:d},c.dlBox={x:c.plotX-d,y:c.plotY-d,width:2*d,height:2*d}):c.shapeArgs=c.plotY=c.dlBox=C},drawLegendSymbol:function(a,b){var c=v(a.itemStyle.fontSize)/2;b.legendSymbol=this.chart.renderer.circle(c,a.baseline-c,c).attr({zIndex:3}).add(b.legendGroup);b.legendSymbol.isMarker=!0},drawPoints:h.column.prototype.drawPoints,alignDataLabel:h.column.prototype.alignDataLabel});N.prototype.beforePadding=function(){var a=this,b=this.len,c=this.chart,d=0,g=b,f=this.isXAxis,\ne=f?\"xData\":\"yData\",i=this.min,h={},j=t.min(c.plotWidth,c.plotHeight),k=Number.MAX_VALUE,m=-Number.MAX_VALUE,o=this.max-i,p=b/o,q=[];this.tickPositions&&(s(this.series,function(b){var c=b.options;if(b.type===\"bubble\"&&b.visible&&(a.allowZoomOutside=!0,q.push(b),f))s([\"minSize\",\"maxSize\"],function(a){var b=c[a],d=/%$/.test(b),b=v(b);h[a]=d?j*b/100:b}),b.minPxSize=h.minSize,b=b.zData,b.length&&(k=t.min(k,t.max(P(b),c.displayNegative===!1?c.zThreshold:-Number.MAX_VALUE)),m=t.max(m,Q(b)))}),s(q,function(a){var b=\na[e],c=b.length,j;f&&a.getRadii(k,m,h.minSize,h.maxSize);if(o>0)for(;c--;)j=a.radii[c],d=Math.min((b[c]-i)*p-j,d),g=Math.max((b[c]-i)*p+j,g)}),q.length&&o>0&&r(this.options.min,this.userMin)===C&&r(this.options.max,this.userMax)===C&&(g-=b,p*=(b+d-g)/b,this.min+=d/p,this.max+=g/p))};var y=z.prototype,m=j.Pointer.prototype;y.toXY=function(a){var b,c=this.chart;b=a.plotX;var d=a.plotY;a.rectPlotX=b;a.rectPlotY=d;a.clientX=(b/Math.PI*180+this.xAxis.pane.options.startAngle)%360;b=this.xAxis.postTranslate(a.plotX,\nthis.yAxis.len-d);a.plotX=a.polarPlotX=b.x-c.plotLeft;a.plotY=a.polarPlotY=b.y-c.plotTop};y.orderTooltipPoints=function(a){if(this.chart.polar&&(a.sort(function(a,c){return a.clientX-c.clientX}),a[0]))a[0].wrappedClientX=a[0].clientX+360,a.push(a[0])};o(h.area.prototype,\"init\",K);o(h.areaspline.prototype,\"init\",K);o(h.spline.prototype,\"getPointSpline\",function(a,b,c,d){var g,f,e,i,h,j,k;if(this.chart.polar){g=c.plotX;f=c.plotY;a=b[d-1];e=b[d+1];this.connectEnds&&(a||(a=b[b.length-2]),e||(e=b[1]));\nif(a&&e)i=a.plotX,h=a.plotY,b=e.plotX,j=e.plotY,i=(1.5*g+i)/2.5,h=(1.5*f+h)/2.5,e=(1.5*g+b)/2.5,k=(1.5*f+j)/2.5,b=Math.sqrt(Math.pow(i-g,2)+Math.pow(h-f,2)),j=Math.sqrt(Math.pow(e-g,2)+Math.pow(k-f,2)),i=Math.atan2(h-f,i-g),h=Math.atan2(k-f,e-g),k=Math.PI/2+(i+h)/2,Math.abs(i-k)>Math.PI/2&&(k-=Math.PI),i=g+Math.cos(k)*b,h=f+Math.sin(k)*b,e=g+Math.cos(Math.PI+k)*j,k=f+Math.sin(Math.PI+k)*j,c.rightContX=e,c.rightContY=k;d?(c=[\"C\",a.rightContX||a.plotX,a.rightContY||a.plotY,i||g,h||f,g,f],a.rightContX=\na.rightContY=null):c=[\"M\",g,f]}else c=a.call(this,b,c,d);return c});o(y,\"translate\",function(a){a.call(this);if(this.chart.polar&&!this.preventPostTranslate)for(var a=this.points,b=a.length;b--;)this.toXY(a[b])});o(y,\"getSegmentPath\",function(a,b){var c=this.points;if(this.chart.polar&&this.options.connectEnds!==!1&&b[b.length-1]===c[c.length-1]&&c[0].y!==null)this.connectEnds=!0,b=[].concat(b,[c[0]]);return a.call(this,b)});o(y,\"animate\",L);o(q,\"animate\",L);o(y,\"setTooltipPoints\",function(a,b){this.chart.polar&&\nF(this.xAxis,{tooltipLen:360});return a.call(this,b)});o(q,\"translate\",function(a){var b=this.xAxis,c=this.yAxis.len,d=b.center,g=b.startAngleRad,f=this.chart.renderer,e,h;this.preventPostTranslate=!0;a.call(this);if(b.isRadial){b=this.points;for(h=b.length;h--;)e=b[h],a=e.barX+g,e.shapeType=\"path\",e.shapeArgs={d:f.symbols.arc(d[0],d[1],c-e.plotY,null,{start:a,end:a+e.pointWidth,innerR:c-r(e.yBottom,c)})},this.toXY(e)}});o(q,\"alignDataLabel\",function(a,b,c,d,g,f){if(this.chart.polar){a=b.rectPlotX/\nMath.PI*180;if(d.align===null)d.align=a>20&&a<160?\"left\":a>200&&a<340?\"right\":\"center\";if(d.verticalAlign===null)d.verticalAlign=a<45||a>315?\"bottom\":a>135&&a<225?\"top\":\"middle\";y.alignDataLabel.call(this,b,c,d,g,f)}else a.call(this,b,c,d,g,f)});o(m,\"getIndex\",function(a,b){var c,d=this.chart,g;d.polar?(g=d.xAxis[0].center,c=b.chartX-g[0]-d.plotLeft,d=b.chartY-g[1]-d.plotTop,c=180-Math.round(Math.atan2(c,d)/Math.PI*180)):c=a.call(this,b);return c});o(m,\"getCoordinates\",function(a,b){var c=this.chart,\nd={xAxis:[],yAxis:[]};c.polar?s(c.axes,function(a){var f=a.isXAxis,e=a.center,h=b.chartX-e[0]-c.plotLeft,e=b.chartY-e[1]-c.plotTop;d[f?\"xAxis\":\"yAxis\"].push({axis:a,value:a.translate(f?Math.PI-Math.atan2(h,e):Math.sqrt(Math.pow(h,2)+Math.pow(e,2)),!0)})}):d=a.call(this,b);return d})})(Highcharts);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/highcharts-more.src.js",
    "content": "// ==ClosureCompiler==\n// @compilation_level SIMPLE_OPTIMIZATIONS\n\n/**\n * @license Highcharts JS v3.0.6 (2013-10-04)\n *\n * (c) 2009-2013 Torstein Hønsi\n *\n * License: www.highcharts.com/license\n */\n\n// JSLint options:\n/*global Highcharts, HighchartsAdapter, document, window, navigator, setInterval, clearInterval, clearTimeout, setTimeout, location, jQuery, $, console */\n\n(function (Highcharts, UNDEFINED) {\nvar arrayMin = Highcharts.arrayMin,\n\tarrayMax = Highcharts.arrayMax,\n\teach = Highcharts.each,\n\textend = Highcharts.extend,\n\tmerge = Highcharts.merge,\n\tmap = Highcharts.map,\n\tpick = Highcharts.pick,\n\tpInt = Highcharts.pInt,\n\tdefaultPlotOptions = Highcharts.getOptions().plotOptions,\n\tseriesTypes = Highcharts.seriesTypes,\n\textendClass = Highcharts.extendClass,\n\tsplat = Highcharts.splat,\n\twrap = Highcharts.wrap,\n\tAxis = Highcharts.Axis,\n\tTick = Highcharts.Tick,\n\tSeries = Highcharts.Series,\n\tcolProto = seriesTypes.column.prototype,\n\tmath = Math,\n\tmathRound = math.round,\n\tmathFloor = math.floor,\n\tmathMax = math.max,\n\tnoop = function () {};/**\n * The Pane object allows options that are common to a set of X and Y axes.\n * \n * In the future, this can be extended to basic Highcharts and Highstock.\n */\nfunction Pane(options, chart, firstAxis) {\n\tthis.init.call(this, options, chart, firstAxis);\n}\n\n// Extend the Pane prototype\nextend(Pane.prototype, {\n\t\n\t/**\n\t * Initiate the Pane object\n\t */\n\tinit: function (options, chart, firstAxis) {\n\t\tvar pane = this,\n\t\t\tbackgroundOption,\n\t\t\tdefaultOptions = pane.defaultOptions;\n\t\t\n\t\tpane.chart = chart;\n\t\t\n\t\t// Set options\n\t\tif (chart.angular) { // gauges\n\t\t\tdefaultOptions.background = {}; // gets extended by this.defaultBackgroundOptions\n\t\t}\n\t\tpane.options = options = merge(defaultOptions, options);\n\t\t\n\t\tbackgroundOption = options.background;\n\t\t\n\t\t// To avoid having weighty logic to place, update and remove the backgrounds,\n\t\t// push them to the first axis' plot bands and borrow the existing logic there.\n\t\tif (backgroundOption) {\n\t\t\teach([].concat(splat(backgroundOption)).reverse(), function (config) {\n\t\t\t\tvar backgroundColor = config.backgroundColor; // if defined, replace the old one (specific for gradients)\n\t\t\t\tconfig = merge(pane.defaultBackgroundOptions, config);\n\t\t\t\tif (backgroundColor) {\n\t\t\t\t\tconfig.backgroundColor = backgroundColor;\n\t\t\t\t}\n\t\t\t\tconfig.color = config.backgroundColor; // due to naming in plotBands\n\t\t\t\tfirstAxis.options.plotBands.unshift(config);\n\t\t\t});\n\t\t}\n\t},\n\t\n\t/**\n\t * The default options object\n\t */\n\tdefaultOptions: {\n\t\t// background: {conditional},\n\t\tcenter: ['50%', '50%'],\n\t\tsize: '85%',\n\t\tstartAngle: 0\n\t\t//endAngle: startAngle + 360\n\t},\t\n\t\n\t/**\n\t * The default background options\n\t */\n\tdefaultBackgroundOptions: {\n\t\tshape: 'circle',\n\t\tborderWidth: 1,\n\t\tborderColor: 'silver',\n\t\tbackgroundColor: {\n\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\tstops: [\n\t\t\t\t[0, '#FFF'],\n\t\t\t\t[1, '#DDD']\n\t\t\t]\n\t\t},\n\t\tfrom: Number.MIN_VALUE, // corrected to axis min\n\t\tinnerRadius: 0,\n\t\tto: Number.MAX_VALUE, // corrected to axis max\n\t\touterRadius: '105%'\n\t}\n\t\n});\nvar axisProto = Axis.prototype,\n\ttickProto = Tick.prototype;\n\t\n/**\n * Augmented methods for the x axis in order to hide it completely, used for the X axis in gauges\n */\nvar hiddenAxisMixin = {\n\tgetOffset: noop,\n\tredraw: function () {\n\t\tthis.isDirty = false; // prevent setting Y axis dirty\n\t},\n\trender: function () {\n\t\tthis.isDirty = false; // prevent setting Y axis dirty\n\t},\n\tsetScale: noop,\n\tsetCategories: noop,\n\tsetTitle: noop\n};\n\n/**\n * Augmented methods for the value axis\n */\n/*jslint unparam: true*/\nvar radialAxisMixin = {\n\tisRadial: true,\n\t\n\t/**\n\t * The default options extend defaultYAxisOptions\n\t */\n\tdefaultRadialGaugeOptions: {\n\t\tlabels: {\n\t\t\talign: 'center',\n\t\t\tx: 0,\n\t\t\ty: null // auto\n\t\t},\n\t\tminorGridLineWidth: 0,\n\t\tminorTickInterval: 'auto',\n\t\tminorTickLength: 10,\n\t\tminorTickPosition: 'inside',\n\t\tminorTickWidth: 1,\n\t\tplotBands: [],\n\t\ttickLength: 10,\n\t\ttickPosition: 'inside',\n\t\ttickWidth: 2,\n\t\ttitle: {\n\t\t\trotation: 0\n\t\t},\n\t\tzIndex: 2 // behind dials, points in the series group\n\t},\n\t\n\t// Circular axis around the perimeter of a polar chart\n\tdefaultRadialXOptions: {\n\t\tgridLineWidth: 1, // spokes\n\t\tlabels: {\n\t\t\talign: null, // auto\n\t\t\tdistance: 15,\n\t\t\tx: 0,\n\t\t\ty: null // auto\n\t\t},\n\t\tmaxPadding: 0,\n\t\tminPadding: 0,\n\t\tplotBands: [],\n\t\tshowLastLabel: false, \n\t\ttickLength: 0\n\t},\n\t\n\t// Radial axis, like a spoke in a polar chart\n\tdefaultRadialYOptions: {\n\t\tgridLineInterpolation: 'circle',\n\t\tlabels: {\n\t\t\talign: 'right',\n\t\t\tx: -3,\n\t\t\ty: -2\n\t\t},\n\t\tplotBands: [],\n\t\tshowLastLabel: false,\n\t\ttitle: {\n\t\t\tx: 4,\n\t\t\ttext: null,\n\t\t\trotation: 90\n\t\t}\n\t},\n\t\n\t/**\n\t * Merge and set options\n\t */\n\tsetOptions: function (userOptions) {\n\t\t\n\t\tthis.options = merge(\n\t\t\tthis.defaultOptions,\n\t\t\tthis.defaultRadialOptions,\n\t\t\tuserOptions\n\t\t);\n\t\t\n\t},\n\t\n\t/**\n\t * Wrap the getOffset method to return zero offset for title or labels in a radial \n\t * axis\n\t */\n\tgetOffset: function () {\n\t\t// Call the Axis prototype method (the method we're in now is on the instance)\n\t\taxisProto.getOffset.call(this);\n\t\t\n\t\t// Title or label offsets are not counted\n\t\tthis.chart.axisOffset[this.side] = 0;\n\t},\n\n\n\t/**\n\t * Get the path for the axis line. This method is also referenced in the getPlotLinePath\n\t * method.\n\t */\n\tgetLinePath: function (lineWidth, radius) {\n\t\tvar center = this.center;\n\t\tradius = pick(radius, center[2] / 2 - this.offset);\n\t\t\n\t\treturn this.chart.renderer.symbols.arc(\n\t\t\tthis.left + center[0],\n\t\t\tthis.top + center[1],\n\t\t\tradius,\n\t\t\tradius, \n\t\t\t{\n\t\t\t\tstart: this.startAngleRad,\n\t\t\t\tend: this.endAngleRad,\n\t\t\t\topen: true,\n\t\t\t\tinnerR: 0\n\t\t\t}\n\t\t);\n\t},\n\n\t/**\n\t * Override setAxisTranslation by setting the translation to the difference\n\t * in rotation. This allows the translate method to return angle for \n\t * any given value.\n\t */\n\tsetAxisTranslation: function () {\n\t\t\n\t\t// Call uber method\t\t\n\t\taxisProto.setAxisTranslation.call(this);\n\t\t\t\n\t\t// Set transA and minPixelPadding\n\t\tif (this.center) { // it's not defined the first time\n\t\t\tif (this.isCircular) {\n\t\t\t\t\n\t\t\t\tthis.transA = (this.endAngleRad - this.startAngleRad) / \n\t\t\t\t\t((this.max - this.min) || 1);\n\t\t\t\t\t\n\t\t\t\t\n\t\t\t} else { \n\t\t\t\tthis.transA = (this.center[2] / 2) / ((this.max - this.min) || 1);\n\t\t\t}\n\t\t\t\n\t\t\tif (this.isXAxis) {\n\t\t\t\tthis.minPixelPadding = this.transA * this.minPointOffset +\n\t\t\t\t\t(this.reversed ? (this.endAngleRad - this.startAngleRad) / 4 : 0); // ???\n\t\t\t}\n\t\t}\n\t},\n\t\n\t/**\n\t * In case of auto connect, add one closestPointRange to the max value right before\n\t * tickPositions are computed, so that ticks will extend passed the real max.\n\t */\n\tbeforeSetTickPositions: function () {\n\t\tif (this.autoConnect) {\n\t\t\tthis.max += (this.categories && 1) || this.pointRange || this.closestPointRange || 0; // #1197, #2260\n\t\t}\n\t},\n\t\n\t/**\n\t * Override the setAxisSize method to use the arc's circumference as length. This\n\t * allows tickPixelInterval to apply to pixel lengths along the perimeter\n\t */\n\tsetAxisSize: function () {\n\t\t\n\t\taxisProto.setAxisSize.call(this);\n\n\t\tif (this.isRadial) {\n\n\t\t\t// Set the center array\n\t\t\tthis.center = this.pane.center = seriesTypes.pie.prototype.getCenter.call(this.pane);\n\t\t\t\n\t\t\tthis.len = this.width = this.height = this.isCircular ?\n\t\t\t\tthis.center[2] * (this.endAngleRad - this.startAngleRad) / 2 :\n\t\t\t\tthis.center[2] / 2;\n\t\t}\n\t},\n\t\n\t/**\n\t * Returns the x, y coordinate of a point given by a value and a pixel distance\n\t * from center\n\t */\n\tgetPosition: function (value, length) {\n\t\tif (!this.isCircular) {\n\t\t\tlength = this.translate(value);\n\t\t\tvalue = this.min;\t\n\t\t}\n\t\t\n\t\treturn this.postTranslate(\n\t\t\tthis.translate(value),\n\t\t\tpick(length, this.center[2] / 2) - this.offset\n\t\t);\t\t\n\t},\n\t\n\t/**\n\t * Translate from intermediate plotX (angle), plotY (axis.len - radius) to final chart coordinates. \n\t */\n\tpostTranslate: function (angle, radius) {\n\t\t\n\t\tvar chart = this.chart,\n\t\t\tcenter = this.center;\n\t\t\t\n\t\tangle = this.startAngleRad + angle;\n\t\t\n\t\treturn {\n\t\t\tx: chart.plotLeft + center[0] + Math.cos(angle) * radius,\n\t\t\ty: chart.plotTop + center[1] + Math.sin(angle) * radius\n\t\t}; \n\t\t\n\t},\n\t\n\t/**\n\t * Find the path for plot bands along the radial axis\n\t */\n\tgetPlotBandPath: function (from, to, options) {\n\t\tvar center = this.center,\n\t\t\tstartAngleRad = this.startAngleRad,\n\t\t\tfullRadius = center[2] / 2,\n\t\t\tradii = [\n\t\t\t\tpick(options.outerRadius, '100%'),\n\t\t\t\toptions.innerRadius,\n\t\t\t\tpick(options.thickness, 10)\n\t\t\t],\n\t\t\tpercentRegex = /%$/,\n\t\t\tstart,\n\t\t\tend,\n\t\t\topen,\n\t\t\tisCircular = this.isCircular, // X axis in a polar chart\n\t\t\tret;\n\t\t\t\n\t\t// Polygonal plot bands\n\t\tif (this.options.gridLineInterpolation === 'polygon') {\n\t\t\tret = this.getPlotLinePath(from).concat(this.getPlotLinePath(to, true));\n\t\t\n\t\t// Circular grid bands\n\t\t} else {\n\t\t\t\n\t\t\t// Plot bands on Y axis (radial axis) - inner and outer radius depend on to and from\n\t\t\tif (!isCircular) {\n\t\t\t\tradii[0] = this.translate(from);\n\t\t\t\tradii[1] = this.translate(to);\n\t\t\t}\n\t\t\t\n\t\t\t// Convert percentages to pixel values\n\t\t\tradii = map(radii, function (radius) {\n\t\t\t\tif (percentRegex.test(radius)) {\n\t\t\t\t\tradius = (pInt(radius, 10) * fullRadius) / 100;\n\t\t\t\t}\n\t\t\t\treturn radius;\n\t\t\t});\n\t\t\t\n\t\t\t// Handle full circle\n\t\t\tif (options.shape === 'circle' || !isCircular) {\n\t\t\t\tstart = -Math.PI / 2;\n\t\t\t\tend = Math.PI * 1.5;\n\t\t\t\topen = true;\n\t\t\t} else {\n\t\t\t\tstart = startAngleRad + this.translate(from);\n\t\t\t\tend = startAngleRad + this.translate(to);\n\t\t\t}\n\t\t\n\t\t\n\t\t\tret = this.chart.renderer.symbols.arc(\n\t\t\t\tthis.left + center[0],\n\t\t\t\tthis.top + center[1],\n\t\t\t\tradii[0],\n\t\t\t\tradii[0],\n\t\t\t\t{\n\t\t\t\t\tstart: start,\n\t\t\t\t\tend: end,\n\t\t\t\t\tinnerR: pick(radii[1], radii[0] - radii[2]),\n\t\t\t\t\topen: open\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\t\t \n\t\treturn ret;\n\t},\n\t\n\t/**\n\t * Find the path for plot lines perpendicular to the radial axis.\n\t */\n\tgetPlotLinePath: function (value, reverse) {\n\t\tvar axis = this,\n\t\t\tcenter = axis.center,\n\t\t\tchart = axis.chart,\n\t\t\tend = axis.getPosition(value),\n\t\t\txAxis,\n\t\t\txy,\n\t\t\ttickPositions,\n\t\t\tret;\n\t\t\n\t\t// Spokes\n\t\tif (axis.isCircular) {\n\t\t\tret = ['M', center[0] + chart.plotLeft, center[1] + chart.plotTop, 'L', end.x, end.y];\n\t\t\n\t\t// Concentric circles\t\t\t\n\t\t} else if (axis.options.gridLineInterpolation === 'circle') {\n\t\t\tvalue = axis.translate(value);\n\t\t\tif (value) { // a value of 0 is in the center\n\t\t\t\tret = axis.getLinePath(0, value);\n\t\t\t}\n\t\t// Concentric polygons \n\t\t} else {\n\t\t\txAxis = chart.xAxis[0];\n\t\t\tret = [];\n\t\t\tvalue = axis.translate(value);\n\t\t\ttickPositions = xAxis.tickPositions;\n\t\t\tif (xAxis.autoConnect) {\n\t\t\t\ttickPositions = tickPositions.concat([tickPositions[0]]);\n\t\t\t}\n\t\t\t// Reverse the positions for concatenation of polygonal plot bands\n\t\t\tif (reverse) {\n\t\t\t\ttickPositions = [].concat(tickPositions).reverse();\n\t\t\t}\n\t\t\t\t\n\t\t\teach(tickPositions, function (pos, i) {\n\t\t\t\txy = xAxis.getPosition(pos, value);\n\t\t\t\tret.push(i ? 'L' : 'M', xy.x, xy.y);\n\t\t\t});\n\t\t\t\n\t\t}\n\t\treturn ret;\n\t},\n\t\n\t/**\n\t * Find the position for the axis title, by default inside the gauge\n\t */\n\tgetTitlePosition: function () {\n\t\tvar center = this.center,\n\t\t\tchart = this.chart,\n\t\t\ttitleOptions = this.options.title;\n\t\t\n\t\treturn { \n\t\t\tx: chart.plotLeft + center[0] + (titleOptions.x || 0), \n\t\t\ty: chart.plotTop + center[1] - ({ high: 0.5, middle: 0.25, low: 0 }[titleOptions.align] * \n\t\t\t\tcenter[2]) + (titleOptions.y || 0)  \n\t\t};\n\t}\n\t\n};\n/*jslint unparam: false*/\n\n/**\n * Override axisProto.init to mix in special axis instance functions and function overrides\n */\nwrap(axisProto, 'init', function (proceed, chart, userOptions) {\n\tvar axis = this,\n\t\tangular = chart.angular,\n\t\tpolar = chart.polar,\n\t\tisX = userOptions.isX,\n\t\tisHidden = angular && isX,\n\t\tisCircular,\n\t\tstartAngleRad,\n\t\tendAngleRad,\n\t\toptions,\n\t\tchartOptions = chart.options,\n\t\tpaneIndex = userOptions.pane || 0,\n\t\tpane,\n\t\tpaneOptions;\n\t\t\n\t// Before prototype.init\n\tif (angular) {\n\t\textend(this, isHidden ? hiddenAxisMixin : radialAxisMixin);\n\t\tisCircular =  !isX;\n\t\tif (isCircular) {\n\t\t\tthis.defaultRadialOptions = this.defaultRadialGaugeOptions;\n\t\t}\n\t\t\n\t} else if (polar) {\n\t\t//extend(this, userOptions.isX ? radialAxisMixin : radialAxisMixin);\n\t\textend(this, radialAxisMixin);\n\t\tisCircular = isX;\n\t\tthis.defaultRadialOptions = isX ? this.defaultRadialXOptions : merge(this.defaultYAxisOptions, this.defaultRadialYOptions);\n\t\t\n\t}\n\t\n\t// Run prototype.init\n\tproceed.call(this, chart, userOptions);\n\t\n\tif (!isHidden && (angular || polar)) {\n\t\toptions = this.options;\n\t\t\n\t\t// Create the pane and set the pane options.\n\t\tif (!chart.panes) {\n\t\t\tchart.panes = [];\n\t\t}\n\t\tthis.pane = pane = chart.panes[paneIndex] = chart.panes[paneIndex] || new Pane(\n\t\t\tsplat(chartOptions.pane)[paneIndex],\n\t\t\tchart,\n\t\t\taxis\n\t\t);\n\t\tpaneOptions = pane.options;\n\t\t\n\t\t\t\n\t\t// Disable certain features on angular and polar axes\n\t\tchart.inverted = false;\n\t\tchartOptions.chart.zoomType = null;\n\t\t\n\t\t// Start and end angle options are\n\t\t// given in degrees relative to top, while internal computations are\n\t\t// in radians relative to right (like SVG).\n\t\tthis.startAngleRad = startAngleRad = (paneOptions.startAngle - 90) * Math.PI / 180;\n\t\tthis.endAngleRad = endAngleRad = (pick(paneOptions.endAngle, paneOptions.startAngle + 360)  - 90) * Math.PI / 180;\n\t\tthis.offset = options.offset || 0;\n\t\t\n\t\tthis.isCircular = isCircular;\n\t\t\n\t\t// Automatically connect grid lines?\n\t\tif (isCircular && userOptions.max === UNDEFINED && endAngleRad - startAngleRad === 2 * Math.PI) {\n\t\t\tthis.autoConnect = true;\n\t\t}\n\t}\n\t\n});\n\n/**\n * Add special cases within the Tick class' methods for radial axes.\n */\t\nwrap(tickProto, 'getPosition', function (proceed, horiz, pos, tickmarkOffset, old) {\n\tvar axis = this.axis;\n\t\n\treturn axis.getPosition ? \n\t\taxis.getPosition(pos) :\n\t\tproceed.call(this, horiz, pos, tickmarkOffset, old);\t\n});\n\n/**\n * Wrap the getLabelPosition function to find the center position of the label\n * based on the distance option\n */\t\nwrap(tickProto, 'getLabelPosition', function (proceed, x, y, label, horiz, labelOptions, tickmarkOffset, index, step) {\n\tvar axis = this.axis,\n\t\toptionsY = labelOptions.y,\n\t\tret,\n\t\talign = labelOptions.align,\n\t\tangle = ((axis.translate(this.pos) + axis.startAngleRad + Math.PI / 2) / Math.PI * 180) % 360;\n\t\n\tif (axis.isRadial) {\n\t\tret = axis.getPosition(this.pos, (axis.center[2] / 2) + pick(labelOptions.distance, -25));\n\t\t\n\t\t// Automatically rotated\n\t\tif (labelOptions.rotation === 'auto') {\n\t\t\tlabel.attr({ \n\t\t\t\trotation: angle\n\t\t\t});\n\t\t\n\t\t// Vertically centered\n\t\t} else if (optionsY === null) {\n\t\t\toptionsY = pInt(label.styles.lineHeight) * 0.9 - label.getBBox().height / 2;\n\t\t\n\t\t}\n\t\t\n\t\t// Automatic alignment\n\t\tif (align === null) {\n\t\t\tif (axis.isCircular) {\n\t\t\t\tif (angle > 20 && angle < 160) {\n\t\t\t\t\talign = 'left'; // right hemisphere\n\t\t\t\t} else if (angle > 200 && angle < 340) {\n\t\t\t\t\talign = 'right'; // left hemisphere\n\t\t\t\t} else {\n\t\t\t\t\talign = 'center'; // top or bottom\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\talign = 'center';\n\t\t\t}\n\t\t\tlabel.attr({\n\t\t\t\talign: align\n\t\t\t});\n\t\t}\n\t\t\n\t\tret.x += labelOptions.x;\n\t\tret.y += optionsY;\n\t\t\n\t} else {\n\t\tret = proceed.call(this, x, y, label, horiz, labelOptions, tickmarkOffset, index, step);\n\t}\n\treturn ret;\n});\n\n/**\n * Wrap the getMarkPath function to return the path of the radial marker\n */\nwrap(tickProto, 'getMarkPath', function (proceed, x, y, tickLength, tickWidth, horiz, renderer) {\n\tvar axis = this.axis,\n\t\tendPoint,\n\t\tret;\n\t\t\n\tif (axis.isRadial) {\n\t\tendPoint = axis.getPosition(this.pos, axis.center[2] / 2 + tickLength);\n\t\tret = [\n\t\t\t'M',\n\t\t\tx,\n\t\t\ty,\n\t\t\t'L',\n\t\t\tendPoint.x,\n\t\t\tendPoint.y\n\t\t];\n\t} else {\n\t\tret = proceed.call(this, x, y, tickLength, tickWidth, horiz, renderer);\n\t}\n\treturn ret;\n});/* \n * The AreaRangeSeries class\n * \n */\n\n/**\n * Extend the default options with map options\n */\ndefaultPlotOptions.arearange = merge(defaultPlotOptions.area, {\n\tlineWidth: 1,\n\tmarker: null,\n\tthreshold: null,\n\ttooltip: {\n\t\tpointFormat: '<span style=\"color:{series.color}\">{series.name}</span>: <b>{point.low}</b> - <b>{point.high}</b><br/>' \n\t},\n\ttrackByArea: true,\n\tdataLabels: {\n\t\tverticalAlign: null,\n\t\txLow: 0,\n\t\txHigh: 0,\n\t\tyLow: 0,\n\t\tyHigh: 0\t\n\t}\n});\n\n/**\n * Add the series type\n */\nseriesTypes.arearange = Highcharts.extendClass(seriesTypes.area, {\n\ttype: 'arearange',\n\tpointArrayMap: ['low', 'high'],\n\ttoYData: function (point) {\n\t\treturn [point.low, point.high];\n\t},\n\tpointValKey: 'low',\n\t\n\t/**\n\t * Extend getSegments to force null points if the higher value is null. #1703.\n\t */\n\tgetSegments: function () {\n\t\tvar series = this;\n\n\t\teach(series.points, function (point) {\n\t\t\tif (!series.options.connectNulls && (point.low === null || point.high === null)) {\n\t\t\t\tpoint.y = null;\n\t\t\t} else if (point.low === null && point.high !== null) {\n\t\t\t\tpoint.y = point.high;\n\t\t\t}\n\t\t});\n\t\tSeries.prototype.getSegments.call(this);\n\t},\n\t\n\t/**\n\t * Translate data points from raw values x and y to plotX and plotY\n\t */\n\ttranslate: function () {\n\t\tvar series = this,\n\t\t\tyAxis = series.yAxis;\n\n\t\tseriesTypes.area.prototype.translate.apply(series);\n\n\t\t// Set plotLow and plotHigh\n\t\teach(series.points, function (point) {\n\n\t\t\tvar low = point.low,\n\t\t\t\thigh = point.high,\n\t\t\t\tplotY = point.plotY;\n\n\t\t\tif (high === null && low === null) {\n\t\t\t\tpoint.y = null;\n\t\t\t} else if (low === null) {\n\t\t\t\tpoint.plotLow = point.plotY = null;\n\t\t\t\tpoint.plotHigh = yAxis.translate(high, 0, 1, 0, 1);\n\t\t\t} else if (high === null) {\n\t\t\t\tpoint.plotLow = plotY;\n\t\t\t\tpoint.plotHigh = null;\n\t\t\t} else {\n\t\t\t\tpoint.plotLow = plotY;\n\t\t\t\tpoint.plotHigh = yAxis.translate(high, 0, 1, 0, 1);\n\t\t\t}\n\t\t});\n\t},\n\t\n\t/**\n\t * Extend the line series' getSegmentPath method by applying the segment\n\t * path to both lower and higher values of the range\n\t */\n\tgetSegmentPath: function (segment) {\n\t\t\n\t\tvar lowSegment,\n\t\t\thighSegment = [],\n\t\t\ti = segment.length,\n\t\t\tbaseGetSegmentPath = Series.prototype.getSegmentPath,\n\t\t\tpoint,\n\t\t\tlinePath,\n\t\t\tlowerPath,\n\t\t\toptions = this.options,\n\t\t\tstep = options.step,\n\t\t\thigherPath;\n\t\t\t\n\t\t// Remove nulls from low segment\n\t\tlowSegment = HighchartsAdapter.grep(segment, function (point) {\n\t\t\treturn point.plotLow !== null;\n\t\t});\n\t\t\n\t\t// Make a segment with plotX and plotY for the top values\n\t\twhile (i--) {\n\t\t\tpoint = segment[i];\n\t\t\tif (point.plotHigh !== null) {\n\t\t\t\thighSegment.push({\n\t\t\t\t\tplotX: point.plotX,\n\t\t\t\t\tplotY: point.plotHigh\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Get the paths\n\t\tlowerPath = baseGetSegmentPath.call(this, lowSegment);\n\t\tif (step) {\n\t\t\tif (step === true) {\n\t\t\t\tstep = 'left';\n\t\t\t}\n\t\t\toptions.step = { left: 'right', center: 'center', right: 'left' }[step]; // swap for reading in getSegmentPath\n\t\t}\n\t\thigherPath = baseGetSegmentPath.call(this, highSegment);\n\t\toptions.step = step;\n\t\t\n\t\t// Create a line on both top and bottom of the range\n\t\tlinePath = [].concat(lowerPath, higherPath);\n\t\t\n\t\t// For the area path, we need to change the 'move' statement into 'lineTo' or 'curveTo'\n\t\thigherPath[0] = 'L'; // this probably doesn't work for spline\t\t\t\n\t\tthis.areaPath = this.areaPath.concat(lowerPath, higherPath);\n\t\t\n\t\treturn linePath;\n\t},\n\t\n\t/**\n\t * Extend the basic drawDataLabels method by running it for both lower and higher\n\t * values.\n\t */\n\tdrawDataLabels: function () {\n\t\t\n\t\tvar data = this.data,\n\t\t\tlength = data.length,\n\t\t\ti,\n\t\t\toriginalDataLabels = [],\n\t\t\tseriesProto = Series.prototype,\n\t\t\tdataLabelOptions = this.options.dataLabels,\n\t\t\tpoint,\n\t\t\tinverted = this.chart.inverted;\n\t\t\t\n\t\tif (dataLabelOptions.enabled || this._hasPointLabels) {\n\t\t\t\n\t\t\t// Step 1: set preliminary values for plotY and dataLabel and draw the upper labels\n\t\t\ti = length;\n\t\t\twhile (i--) {\n\t\t\t\tpoint = data[i];\n\t\t\t\t\n\t\t\t\t// Set preliminary values\n\t\t\t\tpoint.y = point.high;\n\t\t\t\tpoint.plotY = point.plotHigh;\n\t\t\t\t\n\t\t\t\t// Store original data labels and set preliminary label objects to be picked up \n\t\t\t\t// in the uber method\n\t\t\t\toriginalDataLabels[i] = point.dataLabel;\n\t\t\t\tpoint.dataLabel = point.dataLabelUpper;\n\t\t\t\t\n\t\t\t\t// Set the default offset\n\t\t\t\tpoint.below = false;\n\t\t\t\tif (inverted) {\n\t\t\t\t\tdataLabelOptions.align = 'left';\n\t\t\t\t\tdataLabelOptions.x = dataLabelOptions.xHigh;\t\t\t\t\t\t\t\t\n\t\t\t\t} else {\n\t\t\t\t\tdataLabelOptions.y = dataLabelOptions.yHigh;\n\t\t\t\t}\n\t\t\t}\n\t\t\tseriesProto.drawDataLabels.apply(this, arguments); // #1209\n\t\t\t\n\t\t\t// Step 2: reorganize and handle data labels for the lower values\n\t\t\ti = length;\n\t\t\twhile (i--) {\n\t\t\t\tpoint = data[i];\n\t\t\t\t\n\t\t\t\t// Move the generated labels from step 1, and reassign the original data labels\n\t\t\t\tpoint.dataLabelUpper = point.dataLabel;\n\t\t\t\tpoint.dataLabel = originalDataLabels[i];\n\t\t\t\t\n\t\t\t\t// Reset values\n\t\t\t\tpoint.y = point.low;\n\t\t\t\tpoint.plotY = point.plotLow;\n\t\t\t\t\n\t\t\t\t// Set the default offset\n\t\t\t\tpoint.below = true;\n\t\t\t\tif (inverted) {\n\t\t\t\t\tdataLabelOptions.align = 'right';\n\t\t\t\t\tdataLabelOptions.x = dataLabelOptions.xLow;\n\t\t\t\t} else {\n\t\t\t\t\tdataLabelOptions.y = dataLabelOptions.yLow;\n\t\t\t\t}\n\t\t\t}\n\t\t\tseriesProto.drawDataLabels.apply(this, arguments);\n\t\t}\n\t\n\t},\n\t\n\talignDataLabel: seriesTypes.column.prototype.alignDataLabel,\n\t\n\tgetSymbol: seriesTypes.column.prototype.getSymbol,\n\t\n\tdrawPoints: noop\n});/**\n * The AreaSplineRangeSeries class\n */\n\ndefaultPlotOptions.areasplinerange = merge(defaultPlotOptions.arearange);\n\n/**\n * AreaSplineRangeSeries object\n */\nseriesTypes.areasplinerange = extendClass(seriesTypes.arearange, {\n\ttype: 'areasplinerange',\n\tgetPointSpline: seriesTypes.spline.prototype.getPointSpline\n});/**\n * The ColumnRangeSeries class\n */\ndefaultPlotOptions.columnrange = merge(defaultPlotOptions.column, defaultPlotOptions.arearange, {\n\tlineWidth: 1,\n\tpointRange: null\n});\n\n/**\n * ColumnRangeSeries object\n */\nseriesTypes.columnrange = extendClass(seriesTypes.arearange, {\n\ttype: 'columnrange',\n\t/**\n\t * Translate data points from raw values x and y to plotX and plotY\n\t */\n\ttranslate: function () {\n\t\tvar series = this,\n\t\t\tyAxis = series.yAxis,\n\t\t\tplotHigh;\n\n\t\tcolProto.translate.apply(series);\n\n\t\t// Set plotLow and plotHigh\n\t\teach(series.points, function (point) {\n\t\t\tvar shapeArgs = point.shapeArgs,\n\t\t\t\tminPointLength = series.options.minPointLength,\n\t\t\t\theightDifference,\n\t\t\t\theight,\n\t\t\t\ty;\n\n\t\t\tpoint.plotHigh = plotHigh = yAxis.translate(point.high, 0, 1, 0, 1);\n\t\t\tpoint.plotLow = point.plotY;\n\n\t\t\t// adjust shape\n\t\t\ty = plotHigh;\n\t\t\theight = point.plotY - plotHigh;\n\n\t\t\tif (height < minPointLength) {\n\t\t\t\theightDifference = (minPointLength - height);\n\t\t\t\theight += heightDifference;\n\t\t\t\ty -= heightDifference / 2;\n\t\t\t}\n\t\t\tshapeArgs.height = height;\n\t\t\tshapeArgs.y = y;\n\t\t});\n\t},\n\ttrackerGroups: ['group', 'dataLabels'],\n\tdrawGraph: noop,\n\tpointAttrToOptions: colProto.pointAttrToOptions,\n\tdrawPoints: colProto.drawPoints,\n\tdrawTracker: colProto.drawTracker,\n\tanimate: colProto.animate,\n\tgetColumnMetrics: colProto.getColumnMetrics\n});\n/* \n * The GaugeSeries class\n */\n\n\n\n/**\n * Extend the default options\n */\ndefaultPlotOptions.gauge = merge(defaultPlotOptions.line, {\n\tdataLabels: {\n\t\tenabled: true,\n\t\ty: 15,\n\t\tborderWidth: 1,\n\t\tborderColor: 'silver',\n\t\tborderRadius: 3,\n\t\tstyle: {\n\t\t\tfontWeight: 'bold'\n\t\t},\n\t\tverticalAlign: 'top',\n\t\tzIndex: 2\n\t},\n\tdial: {\n\t\t// radius: '80%',\n\t\t// backgroundColor: 'black',\n\t\t// borderColor: 'silver',\n\t\t// borderWidth: 0,\n\t\t// baseWidth: 3,\n\t\t// topWidth: 1,\n\t\t// baseLength: '70%' // of radius\n\t\t// rearLength: '10%'\n\t},\n\tpivot: {\n\t\t//radius: 5,\n\t\t//borderWidth: 0\n\t\t//borderColor: 'silver',\n\t\t//backgroundColor: 'black'\n\t},\n\ttooltip: {\n\t\theaderFormat: ''\n\t},\n\tshowInLegend: false\n});\n\n/**\n * Extend the point object\n */\nvar GaugePoint = Highcharts.extendClass(Highcharts.Point, {\n\t/**\n\t * Don't do any hover colors or anything\n\t */\n\tsetState: function (state) {\n\t\tthis.state = state;\n\t}\n});\n\n\n/**\n * Add the series type\n */\nvar GaugeSeries = {\n\ttype: 'gauge',\n\tpointClass: GaugePoint,\n\t\n\t// chart.angular will be set to true when a gauge series is present, and this will\n\t// be used on the axes\n\tangular: true, \n\tdrawGraph: noop,\n\tfixedBox: true,\n\ttrackerGroups: ['group', 'dataLabels'],\n\t\n\t/**\n\t * Calculate paths etc\n\t */\n\ttranslate: function () {\n\t\t\n\t\tvar series = this,\n\t\t\tyAxis = series.yAxis,\n\t\t\toptions = series.options,\n\t\t\tcenter = yAxis.center;\n\t\t\t\n\t\tseries.generatePoints();\n\t\t\n\t\teach(series.points, function (point) {\n\t\t\t\n\t\t\tvar dialOptions = merge(options.dial, point.dial),\n\t\t\t\tradius = (pInt(pick(dialOptions.radius, 80)) * center[2]) / 200,\n\t\t\t\tbaseLength = (pInt(pick(dialOptions.baseLength, 70)) * radius) / 100,\n\t\t\t\trearLength = (pInt(pick(dialOptions.rearLength, 10)) * radius) / 100,\n\t\t\t\tbaseWidth = dialOptions.baseWidth || 3,\n\t\t\t\ttopWidth = dialOptions.topWidth || 1,\n\t\t\t\trotation = yAxis.startAngleRad + yAxis.translate(point.y, null, null, null, true);\n\n\t\t\t// Handle the wrap option\n\t\t\tif (options.wrap === false) {\n\t\t\t\trotation = Math.max(yAxis.startAngleRad, Math.min(yAxis.endAngleRad, rotation));\n\t\t\t}\n\t\t\trotation = rotation * 180 / Math.PI;\n\t\t\t\t\n\t\t\tpoint.shapeType = 'path';\n\t\t\tpoint.shapeArgs = {\n\t\t\t\td: dialOptions.path || [\n\t\t\t\t\t'M', \n\t\t\t\t\t-rearLength, -baseWidth / 2, \n\t\t\t\t\t'L', \n\t\t\t\t\tbaseLength, -baseWidth / 2,\n\t\t\t\t\tradius, -topWidth / 2,\n\t\t\t\t\tradius, topWidth / 2,\n\t\t\t\t\tbaseLength, baseWidth / 2,\n\t\t\t\t\t-rearLength, baseWidth / 2,\n\t\t\t\t\t'z'\n\t\t\t\t],\n\t\t\t\ttranslateX: center[0],\n\t\t\t\ttranslateY: center[1],\n\t\t\t\trotation: rotation\n\t\t\t};\n\t\t\t\n\t\t\t// Positions for data label\n\t\t\tpoint.plotX = center[0];\n\t\t\tpoint.plotY = center[1];\n\t\t});\n\t},\n\t\n\t/**\n\t * Draw the points where each point is one needle\n\t */\n\tdrawPoints: function () {\n\t\t\n\t\tvar series = this,\n\t\t\tcenter = series.yAxis.center,\n\t\t\tpivot = series.pivot,\n\t\t\toptions = series.options,\n\t\t\tpivotOptions = options.pivot,\n\t\t\trenderer = series.chart.renderer;\n\t\t\n\t\teach(series.points, function (point) {\n\t\t\t\n\t\t\tvar graphic = point.graphic,\n\t\t\t\tshapeArgs = point.shapeArgs,\n\t\t\t\td = shapeArgs.d,\n\t\t\t\tdialOptions = merge(options.dial, point.dial); // #1233\n\t\t\t\n\t\t\tif (graphic) {\n\t\t\t\tgraphic.animate(shapeArgs);\n\t\t\t\tshapeArgs.d = d; // animate alters it\n\t\t\t} else {\n\t\t\t\tpoint.graphic = renderer[point.shapeType](shapeArgs)\n\t\t\t\t\t.attr({\n\t\t\t\t\t\tstroke: dialOptions.borderColor || 'none',\n\t\t\t\t\t\t'stroke-width': dialOptions.borderWidth || 0,\n\t\t\t\t\t\tfill: dialOptions.backgroundColor || 'black',\n\t\t\t\t\t\trotation: shapeArgs.rotation // required by VML when animation is false\n\t\t\t\t\t})\n\t\t\t\t\t.add(series.group);\n\t\t\t}\n\t\t});\n\t\t\n\t\t// Add or move the pivot\n\t\tif (pivot) {\n\t\t\tpivot.animate({ // #1235\n\t\t\t\ttranslateX: center[0],\n\t\t\t\ttranslateY: center[1]\n\t\t\t});\n\t\t} else {\n\t\t\tseries.pivot = renderer.circle(0, 0, pick(pivotOptions.radius, 5))\n\t\t\t\t.attr({\n\t\t\t\t\t'stroke-width': pivotOptions.borderWidth || 0,\n\t\t\t\t\tstroke: pivotOptions.borderColor || 'silver',\n\t\t\t\t\tfill: pivotOptions.backgroundColor || 'black'\n\t\t\t\t})\n\t\t\t\t.translate(center[0], center[1])\n\t\t\t\t.add(series.group);\n\t\t}\n\t},\n\t\n\t/**\n\t * Animate the arrow up from startAngle\n\t */\n\tanimate: function (init) {\n\t\tvar series = this;\n\n\t\tif (!init) {\n\t\t\teach(series.points, function (point) {\n\t\t\t\tvar graphic = point.graphic;\n\n\t\t\t\tif (graphic) {\n\t\t\t\t\t// start value\n\t\t\t\t\tgraphic.attr({\n\t\t\t\t\t\trotation: series.yAxis.startAngleRad * 180 / Math.PI\n\t\t\t\t\t});\n\n\t\t\t\t\t// animate\n\t\t\t\t\tgraphic.animate({\n\t\t\t\t\t\trotation: point.shapeArgs.rotation\n\t\t\t\t\t}, series.options.animation);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// delete this function to allow it only once\n\t\t\tseries.animate = null;\n\t\t}\n\t},\n\t\n\trender: function () {\n\t\tthis.group = this.plotGroup(\n\t\t\t'group', \n\t\t\t'series', \n\t\t\tthis.visible ? 'visible' : 'hidden', \n\t\t\tthis.options.zIndex, \n\t\t\tthis.chart.seriesGroup\n\t\t);\n\t\tseriesTypes.pie.prototype.render.call(this);\n\t\tthis.group.clip(this.chart.clipRect);\n\t},\n\t\n\tsetData: seriesTypes.pie.prototype.setData,\n\tdrawTracker: seriesTypes.column.prototype.drawTracker\n};\nseriesTypes.gauge = Highcharts.extendClass(seriesTypes.line, GaugeSeries);/* ****************************************************************************\n * Start Box plot series code\t\t\t\t\t\t\t\t\t\t\t      *\n *****************************************************************************/\n\n// Set default options\ndefaultPlotOptions.boxplot = merge(defaultPlotOptions.column, {\n\tfillColor: '#FFFFFF',\n\tlineWidth: 1,\n\t//medianColor: null,\n\tmedianWidth: 2,\n\tstates: {\n\t\thover: {\n\t\t\tbrightness: -0.3\n\t\t}\n\t},\n\t//stemColor: null,\n\t//stemDashStyle: 'solid'\n\t//stemWidth: null,\n\tthreshold: null,\n\ttooltip: {\n\t\tpointFormat: '<span style=\"color:{series.color};font-weight:bold\">{series.name}</span><br/>' +\n\t\t\t'Maximum: {point.high}<br/>' +\n\t\t\t'Upper quartile: {point.q3}<br/>' +\n\t\t\t'Median: {point.median}<br/>' +\n\t\t\t'Lower quartile: {point.q1}<br/>' +\n\t\t\t'Minimum: {point.low}<br/>'\n\t\t\t\n\t},\n\t//whiskerColor: null,\n\twhiskerLength: '50%',\n\twhiskerWidth: 2\n});\n\n// Create the series object\nseriesTypes.boxplot = extendClass(seriesTypes.column, {\n\ttype: 'boxplot',\n\tpointArrayMap: ['low', 'q1', 'median', 'q3', 'high'], // array point configs are mapped to this\n\ttoYData: function (point) { // return a plain array for speedy calculation\n\t\treturn [point.low, point.q1, point.median, point.q3, point.high];\n\t},\n\tpointValKey: 'high', // defines the top of the tracker\n\t\n\t/**\n\t * One-to-one mapping from options to SVG attributes\n\t */\n\tpointAttrToOptions: { // mapping between SVG attributes and the corresponding options\n\t\tfill: 'fillColor',\n\t\tstroke: 'color',\n\t\t'stroke-width': 'lineWidth'\n\t},\n\t\n\t/**\n\t * Disable data labels for box plot\n\t */\n\tdrawDataLabels: noop,\n\n\t/**\n\t * Translate data points from raw values x and y to plotX and plotY\n\t */\n\ttranslate: function () {\n\t\tvar series = this,\n\t\t\tyAxis = series.yAxis,\n\t\t\tpointArrayMap = series.pointArrayMap;\n\n\t\tseriesTypes.column.prototype.translate.apply(series);\n\n\t\t// do the translation on each point dimension\n\t\teach(series.points, function (point) {\n\t\t\teach(pointArrayMap, function (key) {\n\t\t\t\tif (point[key] !== null) {\n\t\t\t\t\tpoint[key + 'Plot'] = yAxis.translate(point[key], 0, 1, 0, 1);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t},\n\n\t/**\n\t * Draw the data points\n\t */\n\tdrawPoints: function () {\n\t\tvar series = this,  //state = series.state,\n\t\t\tpoints = series.points,\n\t\t\toptions = series.options,\n\t\t\tchart = series.chart,\n\t\t\trenderer = chart.renderer,\n\t\t\tpointAttr,\n\t\t\tq1Plot,\n\t\t\tq3Plot,\n\t\t\thighPlot,\n\t\t\tlowPlot,\n\t\t\tmedianPlot,\n\t\t\tcrispCorr,\n\t\t\tcrispX,\n\t\t\tgraphic,\n\t\t\tstemPath,\n\t\t\tstemAttr,\n\t\t\tboxPath,\n\t\t\twhiskersPath,\n\t\t\twhiskersAttr,\n\t\t\tmedianPath,\n\t\t\tmedianAttr,\n\t\t\twidth,\n\t\t\tleft,\n\t\t\tright,\n\t\t\thalfWidth,\n\t\t\tshapeArgs,\n\t\t\tcolor,\n\t\t\tdoQuartiles = series.doQuartiles !== false, // error bar inherits this series type but doesn't do quartiles\n\t\t\twhiskerLength = parseInt(series.options.whiskerLength, 10) / 100;\n\n\n\t\teach(points, function (point) {\n\n\t\t\tgraphic = point.graphic;\n\t\t\tshapeArgs = point.shapeArgs; // the box\n\t\t\tstemAttr = {};\n\t\t\twhiskersAttr = {};\n\t\t\tmedianAttr = {};\n\t\t\tcolor = point.color || series.color;\n\t\t\t\n\t\t\tif (point.plotY !== UNDEFINED) {\n\n\t\t\t\tpointAttr = point.pointAttr[point.selected ? 'selected' : ''];\n\n\t\t\t\t// crisp vector coordinates\n\t\t\t\twidth = shapeArgs.width;\n\t\t\t\tleft = mathFloor(shapeArgs.x);\n\t\t\t\tright = left + width;\n\t\t\t\thalfWidth = mathRound(width / 2);\n\t\t\t\t//crispX = mathRound(left + halfWidth) + crispCorr;\n\t\t\t\tq1Plot = mathFloor(doQuartiles ? point.q1Plot : point.lowPlot);// + crispCorr;\n\t\t\t\tq3Plot = mathFloor(doQuartiles ? point.q3Plot : point.lowPlot);// + crispCorr;\n\t\t\t\thighPlot = mathFloor(point.highPlot);// + crispCorr;\n\t\t\t\tlowPlot = mathFloor(point.lowPlot);// + crispCorr;\n\t\t\t\t\n\t\t\t\t// Stem attributes\n\t\t\t\tstemAttr.stroke = point.stemColor || options.stemColor || color;\n\t\t\t\tstemAttr['stroke-width'] = pick(point.stemWidth, options.stemWidth, options.lineWidth);\n\t\t\t\tstemAttr.dashstyle = point.stemDashStyle || options.stemDashStyle;\n\t\t\t\t\n\t\t\t\t// Whiskers attributes\n\t\t\t\twhiskersAttr.stroke = point.whiskerColor || options.whiskerColor || color;\n\t\t\t\twhiskersAttr['stroke-width'] = pick(point.whiskerWidth, options.whiskerWidth, options.lineWidth);\n\t\t\t\t\n\t\t\t\t// Median attributes\n\t\t\t\tmedianAttr.stroke = point.medianColor || options.medianColor || color;\n\t\t\t\tmedianAttr['stroke-width'] = pick(point.medianWidth, options.medianWidth, options.lineWidth);\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t// The stem\n\t\t\t\tcrispCorr = (stemAttr['stroke-width'] % 2) / 2;\n\t\t\t\tcrispX = left + halfWidth + crispCorr;\t\t\t\t\n\t\t\t\tstemPath = [\n\t\t\t\t\t// stem up\n\t\t\t\t\t'M',\n\t\t\t\t\tcrispX, q3Plot,\n\t\t\t\t\t'L',\n\t\t\t\t\tcrispX, highPlot,\n\t\t\t\t\t\n\t\t\t\t\t// stem down\n\t\t\t\t\t'M',\n\t\t\t\t\tcrispX, q1Plot,\n\t\t\t\t\t'L',\n\t\t\t\t\tcrispX, lowPlot,\n\t\t\t\t\t'z'\n\t\t\t\t];\n\t\t\t\t\n\t\t\t\t// The box\n\t\t\t\tif (doQuartiles) {\n\t\t\t\t\tcrispCorr = (pointAttr['stroke-width'] % 2) / 2;\n\t\t\t\t\tcrispX = mathFloor(crispX) + crispCorr;\n\t\t\t\t\tq1Plot = mathFloor(q1Plot) + crispCorr;\n\t\t\t\t\tq3Plot = mathFloor(q3Plot) + crispCorr;\n\t\t\t\t\tleft += crispCorr;\n\t\t\t\t\tright += crispCorr;\n\t\t\t\t\tboxPath = [\n\t\t\t\t\t\t'M',\n\t\t\t\t\t\tleft, q3Plot,\n\t\t\t\t\t\t'L',\n\t\t\t\t\t\tleft, q1Plot,\n\t\t\t\t\t\t'L',\n\t\t\t\t\t\tright, q1Plot,\n\t\t\t\t\t\t'L',\n\t\t\t\t\t\tright, q3Plot,\n\t\t\t\t\t\t'L',\n\t\t\t\t\t\tleft, q3Plot,\n\t\t\t\t\t\t'z'\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// The whiskers\n\t\t\t\tif (whiskerLength) {\n\t\t\t\t\tcrispCorr = (whiskersAttr['stroke-width'] % 2) / 2;\n\t\t\t\t\thighPlot = highPlot + crispCorr;\n\t\t\t\t\tlowPlot = lowPlot + crispCorr;\n\t\t\t\t\twhiskersPath = [\n\t\t\t\t\t\t// High whisker\n\t\t\t\t\t\t'M',\n\t\t\t\t\t\tcrispX - halfWidth * whiskerLength, \n\t\t\t\t\t\thighPlot,\n\t\t\t\t\t\t'L',\n\t\t\t\t\t\tcrispX + halfWidth * whiskerLength, \n\t\t\t\t\t\thighPlot,\n\t\t\t\t\t\t\n\t\t\t\t\t\t// Low whisker\n\t\t\t\t\t\t'M',\n\t\t\t\t\t\tcrispX - halfWidth * whiskerLength, \n\t\t\t\t\t\tlowPlot,\n\t\t\t\t\t\t'L',\n\t\t\t\t\t\tcrispX + halfWidth * whiskerLength, \n\t\t\t\t\t\tlowPlot\n\t\t\t\t\t];\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// The median\n\t\t\t\tcrispCorr = (medianAttr['stroke-width'] % 2) / 2;\t\t\t\t\n\t\t\t\tmedianPlot = mathRound(point.medianPlot) + crispCorr;\n\t\t\t\tmedianPath = [\n\t\t\t\t\t'M',\n\t\t\t\t\tleft, \n\t\t\t\t\tmedianPlot,\n\t\t\t\t\t'L',\n\t\t\t\t\tright, \n\t\t\t\t\tmedianPlot,\n\t\t\t\t\t'z'\n\t\t\t\t];\n\t\t\t\t\n\t\t\t\t// Create or update the graphics\n\t\t\t\tif (graphic) { // update\n\t\t\t\t\t\n\t\t\t\t\tpoint.stem.animate({ d: stemPath });\n\t\t\t\t\tif (whiskerLength) {\n\t\t\t\t\t\tpoint.whiskers.animate({ d: whiskersPath });\n\t\t\t\t\t}\n\t\t\t\t\tif (doQuartiles) {\n\t\t\t\t\t\tpoint.box.animate({ d: boxPath });\n\t\t\t\t\t}\n\t\t\t\t\tpoint.medianShape.animate({ d: medianPath });\n\t\t\t\t\t\n\t\t\t\t} else { // create new\n\t\t\t\t\tpoint.graphic = graphic = renderer.g()\n\t\t\t\t\t\t.add(series.group);\n\t\t\t\t\t\n\t\t\t\t\tpoint.stem = renderer.path(stemPath)\n\t\t\t\t\t\t.attr(stemAttr)\n\t\t\t\t\t\t.add(graphic);\n\t\t\t\t\t\t\n\t\t\t\t\tif (whiskerLength) {\n\t\t\t\t\t\tpoint.whiskers = renderer.path(whiskersPath) \n\t\t\t\t\t\t\t.attr(whiskersAttr)\n\t\t\t\t\t\t\t.add(graphic);\n\t\t\t\t\t}\n\t\t\t\t\tif (doQuartiles) {\n\t\t\t\t\t\tpoint.box = renderer.path(boxPath)\n\t\t\t\t\t\t\t.attr(pointAttr)\n\t\t\t\t\t\t\t.add(graphic);\n\t\t\t\t\t}\t\n\t\t\t\t\tpoint.medianShape = renderer.path(medianPath)\n\t\t\t\t\t\t.attr(medianAttr)\n\t\t\t\t\t\t.add(graphic);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t}\n\n\n});\n\n/* ****************************************************************************\n * End Box plot series code\t\t\t\t\t\t\t\t\t\t\t\t*\n *****************************************************************************/\n/* ****************************************************************************\n * Start error bar series code                                                *\n *****************************************************************************/\n\n// 1 - set default options\ndefaultPlotOptions.errorbar = merge(defaultPlotOptions.boxplot, {\n\tcolor: '#000000',\n\tgrouping: false,\n\tlinkedTo: ':previous',\n\ttooltip: {\n\t\tpointFormat: defaultPlotOptions.arearange.tooltip.pointFormat\n\t},\n\twhiskerWidth: null\n});\n\n// 2 - Create the series object\nseriesTypes.errorbar = extendClass(seriesTypes.boxplot, {\n\ttype: 'errorbar',\n\tpointArrayMap: ['low', 'high'], // array point configs are mapped to this\n\ttoYData: function (point) { // return a plain array for speedy calculation\n\t\treturn [point.low, point.high];\n\t},\n\tpointValKey: 'high', // defines the top of the tracker\n\tdoQuartiles: false,\n\n\t/**\n\t * Get the width and X offset, either on top of the linked series column\n\t * or standalone\n\t */\n\tgetColumnMetrics: function () {\n\t\treturn (this.linkedParent && this.linkedParent.columnMetrics) || \n\t\t\tseriesTypes.column.prototype.getColumnMetrics.call(this);\n\t}\n});\n\n/* ****************************************************************************\n * End error bar series code                                                  *\n *****************************************************************************/\n/* ****************************************************************************\n * Start Waterfall series code                                                *\n *****************************************************************************/\n\n// 1 - set default options\ndefaultPlotOptions.waterfall = merge(defaultPlotOptions.column, {\n\tlineWidth: 1,\n\tlineColor: '#333',\n\tdashStyle: 'dot',\n\tborderColor: '#333'\n});\n\n\n// 2 - Create the series object\nseriesTypes.waterfall = extendClass(seriesTypes.column, {\n\ttype: 'waterfall',\n\n\tupColorProp: 'fill',\n\n\tpointArrayMap: ['low', 'y'],\n\n\tpointValKey: 'y',\n\n\t/**\n\t * Init waterfall series, force stacking\n\t */\n\tinit: function (chart, options) {\n\t\t// force stacking\n\t\toptions.stacking = true;\n\n\t\tseriesTypes.column.prototype.init.call(this, chart, options);\n\t},\n\n\n\t/**\n\t * Translate data points from raw values\n\t */\n\ttranslate: function () {\n\t\tvar series = this,\n\t\t\toptions = series.options,\n\t\t\taxis = series.yAxis,\n\t\t\tlen,\n\t\t\ti,\n\t\t\tpoints,\n\t\t\tpoint,\n\t\t\tshapeArgs,\n\t\t\tstack,\n\t\t\ty,\n\t\t\tpreviousY,\n\t\t\tstackPoint,\n\t\t\tthreshold = options.threshold,\n\t\t\tcrispCorr = (options.borderWidth % 2) / 2;\n\n\t\t// run column series translate\n\t\tseriesTypes.column.prototype.translate.apply(this);\n\n\t\tpreviousY = threshold;\n\t\tpoints = series.points;\n\n\t\tfor (i = 0, len = points.length; i < len; i++) {\n\t\t\t// cache current point object\n\t\t\tpoint = points[i];\n\t\t\tshapeArgs = point.shapeArgs;\n\n\t\t\t// get current stack\n\t\t\tstack = series.getStack(i);\n\t\t\tstackPoint = stack.points[series.index];\n\n\t\t\t// override point value for sums\n\t\t\tif (isNaN(point.y)) {\n\t\t\t\tpoint.y = series.yData[i];\n\t\t\t}\n\n\t\t\t// up points\n\t\t\ty = mathMax(previousY, previousY + point.y) + stackPoint[0];\n\t\t\tshapeArgs.y = axis.translate(y, 0, 1);\n\n\n\t\t\t// sum points\n\t\t\tif (point.isSum || point.isIntermediateSum) {\n\t\t\t\tshapeArgs.y = axis.translate(stackPoint[1], 0, 1);\n\t\t\t\tshapeArgs.height = axis.translate(stackPoint[0], 0, 1) - shapeArgs.y;\n\n\t\t\t// if it's not the sum point, update previous stack end position\n\t\t\t} else {\n\t\t\t\tpreviousY += stack.total;\n\t\t\t}\n\n\t\t\t// negative points\n\t\t\tif (shapeArgs.height < 0) {\n\t\t\t\tshapeArgs.y += shapeArgs.height;\n\t\t\t\tshapeArgs.height *= -1;\n\t\t\t}\n\n\t\t\tpoint.plotY = shapeArgs.y = mathRound(shapeArgs.y) - crispCorr;\n\t\t\tshapeArgs.height = mathRound(shapeArgs.height);\n\t\t\tpoint.yBottom = shapeArgs.y + shapeArgs.height;\n\t\t}\n\t},\n\n\t/**\n\t * Call default processData then override yData to reflect waterfall's extremes on yAxis\n\t */\n\tprocessData: function (force) {\n\t\tvar series = this,\n\t\t\toptions = series.options,\n\t\t\tyData = series.yData,\n\t\t\tpoints = series.points,\n\t\t\tpoint,\n\t\t\tdataLength = yData.length,\n\t\t\tthreshold = options.threshold || 0,\n\t\t\tsubSum,\n\t\t\tsum,\n\t\t\tdataMin,\n\t\t\tdataMax,\n\t\t\ty,\n\t\t\ti;\n\n\t\tsum = subSum = dataMin = dataMax = threshold;\n\n\t\tfor (i = 0; i < dataLength; i++) {\n\t\t\ty = yData[i];\n\t\t\tpoint = points && points[i] ? points[i] : {};\n\n\t\t\tif (y === \"sum\" || point.isSum) {\n\t\t\t\tyData[i] = sum;\n\t\t\t} else if (y === \"intermediateSum\" || point.isIntermediateSum) {\n\t\t\t\tyData[i] = subSum;\n\t\t\t\tsubSum = threshold;\n\t\t\t} else {\n\t\t\t\tsum += y;\n\t\t\t\tsubSum += y;\n\t\t\t}\n\t\t\tdataMin = Math.min(sum, dataMin);\n\t\t\tdataMax = Math.max(sum, dataMax);\n\t\t}\n\n\t\tSeries.prototype.processData.call(this, force);\n\n\t\t// Record extremes\n\t\tseries.dataMin = dataMin;\n\t\tseries.dataMax = dataMax;\n\t},\n\n\t/**\n\t * Return y value or string if point is sum\n\t */\n\ttoYData: function (pt) {\n\t\tif (pt.isSum) {\n\t\t\treturn \"sum\";\n\t\t} else if (pt.isIntermediateSum) {\n\t\t\treturn \"intermediateSum\";\n\t\t}\n\n\t\treturn pt.y;\n\t},\n\n\t/**\n\t * Postprocess mapping between options and SVG attributes\n\t */\n\tgetAttribs: function () {\n\t\tseriesTypes.column.prototype.getAttribs.apply(this, arguments);\n\n\t\tvar series = this,\n\t\t\toptions = series.options,\n\t\t\tstateOptions = options.states,\n\t\t\tupColor = options.upColor || series.color,\n\t\t\thoverColor = Highcharts.Color(upColor).brighten(0.1).get(),\n\t\t\tseriesDownPointAttr = merge(series.pointAttr),\n\t\t\tupColorProp = series.upColorProp;\n\n\t\tseriesDownPointAttr[''][upColorProp] = upColor;\n\t\tseriesDownPointAttr.hover[upColorProp] = stateOptions.hover.upColor || hoverColor;\n\t\tseriesDownPointAttr.select[upColorProp] = stateOptions.select.upColor || upColor;\n\n\t\teach(series.points, function (point) {\n\t\t\tif (point.y > 0 && !point.color) {\n\t\t\t\tpoint.pointAttr = seriesDownPointAttr;\n\t\t\t\tpoint.color = upColor;\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n\t * Draw columns' connector lines\n\t */\n\tgetGraphPath: function () {\n\n\t\tvar data = this.data,\n\t\t\tlength = data.length,\n\t\t\tlineWidth = this.options.lineWidth + this.options.borderWidth,\n\t\t\tnormalizer = mathRound(lineWidth) % 2 / 2,\n\t\t\tpath = [],\n\t\t\tM = 'M',\n\t\t\tL = 'L',\n\t\t\tprevArgs,\n\t\t\tpointArgs,\n\t\t\ti,\n\t\t\td;\n\n\t\tfor (i = 1; i < length; i++) {\n\t\t\tpointArgs = data[i].shapeArgs;\n\t\t\tprevArgs = data[i - 1].shapeArgs;\n\n\t\t\td = [\n\t\t\t\tM,\n\t\t\t\tprevArgs.x + prevArgs.width, prevArgs.y + normalizer,\n\t\t\t\tL,\n\t\t\t\tpointArgs.x, prevArgs.y + normalizer\n\t\t\t];\n\n\t\t\tif (data[i - 1].y < 0) {\n\t\t\t\td[2] += prevArgs.height;\n\t\t\t\td[5] += prevArgs.height;\n\t\t\t}\n\n\t\t\tpath = path.concat(d);\n\t\t}\n\n\t\treturn path;\n\t},\n\n\t/**\n\t * Extremes are recorded in processData\n\t */\n\tgetExtremes: noop,\n\n\t/**\n\t * Return stack for given index\n\t */\n\tgetStack: function (i) {\n\t\tvar axis = this.yAxis,\n\t\t\tstacks = axis.stacks,\n\t\t\tkey = this.stackKey;\n\n\t\tif (this.processedYData[i] < this.options.threshold) {\n\t\t\tkey = '-' + key;\n\t\t}\n\n\t\treturn stacks[key][i];\n\t},\n\n\tdrawGraph: Series.prototype.drawGraph\n});\n\n/* ****************************************************************************\n * End Waterfall series code                                                  *\n *****************************************************************************/\n/* ****************************************************************************\n * Start Bubble series code\t\t\t\t\t\t\t\t\t\t\t          *\n *****************************************************************************/\n\n// 1 - set default options\ndefaultPlotOptions.bubble = merge(defaultPlotOptions.scatter, {\n\tdataLabels: {\n\t\tinside: true,\n\t\tstyle: {\n\t\t\tcolor: 'white',\n\t\t\ttextShadow: '0px 0px 3px black'\n\t\t},\n\t\tverticalAlign: 'middle'\n\t},\n\t// displayNegative: true,\n\tmarker: {\n\t\t// fillOpacity: 0.5,\n\t\tlineColor: null, // inherit from series.color\n\t\tlineWidth: 1\n\t},\n\tminSize: 8,\n\tmaxSize: '20%',\n\t// negativeColor: null,\n\ttooltip: {\n\t\tpointFormat: '({point.x}, {point.y}), Size: {point.z}'\n\t},\n\tturboThreshold: 0,\n\tzThreshold: 0\n});\n\n// 2 - Create the series object\nseriesTypes.bubble = extendClass(seriesTypes.scatter, {\n\ttype: 'bubble',\n\tpointArrayMap: ['y', 'z'],\n\ttrackerGroups: ['group', 'dataLabelsGroup'],\n\t\n\t/**\n\t * Mapping between SVG attributes and the corresponding options\n\t */\n\tpointAttrToOptions: { \n\t\tstroke: 'lineColor',\n\t\t'stroke-width': 'lineWidth',\n\t\tfill: 'fillColor'\n\t},\n\t\n\t/**\n\t * Apply the fillOpacity to all fill positions\n\t */\n\tapplyOpacity: function (fill) {\n\t\tvar markerOptions = this.options.marker,\n\t\t\tfillOpacity = pick(markerOptions.fillOpacity, 0.5);\n\t\t\n\t\t// When called from Legend.colorizeItem, the fill isn't predefined\n\t\tfill = fill || markerOptions.fillColor || this.color; \n\t\t\n\t\tif (fillOpacity !== 1) {\n\t\t\tfill = Highcharts.Color(fill).setOpacity(fillOpacity).get('rgba');\n\t\t}\n\t\treturn fill;\n\t},\n\t\n\t/**\n\t * Extend the convertAttribs method by applying opacity to the fill\n\t */\n\tconvertAttribs: function () {\n\t\tvar obj = Series.prototype.convertAttribs.apply(this, arguments);\n\t\t\n\t\tobj.fill = this.applyOpacity(obj.fill);\n\t\t\n\t\treturn obj;\n\t},\n\n\t/**\n\t * Get the radius for each point based on the minSize, maxSize and each point's Z value. This\n\t * must be done prior to Series.translate because the axis needs to add padding in \n\t * accordance with the point sizes.\n\t */\n\tgetRadii: function (zMin, zMax, minSize, maxSize) {\n\t\tvar len,\n\t\t\ti,\n\t\t\tpos,\n\t\t\tzData = this.zData,\n\t\t\tradii = [],\n\t\t\tzRange;\n\t\t\n\t\t// Set the shape type and arguments to be picked up in drawPoints\n\t\tfor (i = 0, len = zData.length; i < len; i++) {\n\t\t\tzRange = zMax - zMin;\n\t\t\tpos = zRange > 0 ? // relative size, a number between 0 and 1\n\t\t\t\t(zData[i] - zMin) / (zMax - zMin) : \n\t\t\t\t0.5;\n\t\t\tradii.push(math.ceil(minSize + pos * (maxSize - minSize)) / 2);\n\t\t}\n\t\tthis.radii = radii;\n\t},\n\t\n\t/**\n\t * Perform animation on the bubbles\n\t */\n\tanimate: function (init) {\n\t\tvar animation = this.options.animation;\n\t\t\n\t\tif (!init) { // run the animation\n\t\t\teach(this.points, function (point) {\n\t\t\t\tvar graphic = point.graphic,\n\t\t\t\t\tshapeArgs = point.shapeArgs;\n\n\t\t\t\tif (graphic && shapeArgs) {\n\t\t\t\t\t// start values\n\t\t\t\t\tgraphic.attr('r', 1);\n\n\t\t\t\t\t// animate\n\t\t\t\t\tgraphic.animate({\n\t\t\t\t\t\tr: shapeArgs.r\n\t\t\t\t\t}, animation);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// delete this function to allow it only once\n\t\t\tthis.animate = null;\n\t\t}\n\t},\n\t\n\t/**\n\t * Extend the base translate method to handle bubble size\n\t */\n\ttranslate: function () {\n\t\t\n\t\tvar i,\n\t\t\tdata = this.data,\n\t\t\tpoint,\n\t\t\tradius,\n\t\t\tradii = this.radii;\n\t\t\n\t\t// Run the parent method\n\t\tseriesTypes.scatter.prototype.translate.call(this);\n\t\t\n\t\t// Set the shape type and arguments to be picked up in drawPoints\n\t\ti = data.length;\n\t\t\n\t\twhile (i--) {\n\t\t\tpoint = data[i];\n\t\t\tradius = radii ? radii[i] : 0; // #1737\n\n\t\t\t// Flag for negativeColor to be applied in Series.js\n\t\t\tpoint.negative = point.z < (this.options.zThreshold || 0);\n\t\t\t\n\t\t\tif (radius >= this.minPxSize / 2) {\n\t\t\t\t// Shape arguments\n\t\t\t\tpoint.shapeType = 'circle';\n\t\t\t\tpoint.shapeArgs = {\n\t\t\t\t\tx: point.plotX,\n\t\t\t\t\ty: point.plotY,\n\t\t\t\t\tr: radius\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\t// Alignment box for the data label\n\t\t\t\tpoint.dlBox = {\n\t\t\t\t\tx: point.plotX - radius,\n\t\t\t\t\ty: point.plotY - radius,\n\t\t\t\t\twidth: 2 * radius,\n\t\t\t\t\theight: 2 * radius\n\t\t\t\t};\n\t\t\t} else { // below zThreshold\n\t\t\t\tpoint.shapeArgs = point.plotY = point.dlBox = UNDEFINED; // #1691\n\t\t\t}\n\t\t}\n\t},\n\t\n\t/**\n\t * Get the series' symbol in the legend\n\t * \n\t * @param {Object} legend The legend object\n\t * @param {Object} item The series (this) or point\n\t */\n\tdrawLegendSymbol: function (legend, item) {\n\t\tvar radius = pInt(legend.itemStyle.fontSize) / 2;\n\t\t\n\t\titem.legendSymbol = this.chart.renderer.circle(\n\t\t\tradius,\n\t\t\tlegend.baseline - radius,\n\t\t\tradius\n\t\t).attr({\n\t\t\tzIndex: 3\n\t\t}).add(item.legendGroup);\n\t\titem.legendSymbol.isMarker = true;\t\n\t\t\n\t},\n\t\n\tdrawPoints: seriesTypes.column.prototype.drawPoints,\n\talignDataLabel: seriesTypes.column.prototype.alignDataLabel\n});\n\n/**\n * Add logic to pad each axis with the amount of pixels\n * necessary to avoid the bubbles to overflow.\n */\nAxis.prototype.beforePadding = function () {\n\tvar axis = this,\n\t\taxisLength = this.len,\n\t\tchart = this.chart,\n\t\tpxMin = 0, \n\t\tpxMax = axisLength,\n\t\tisXAxis = this.isXAxis,\n\t\tdataKey = isXAxis ? 'xData' : 'yData',\n\t\tmin = this.min,\n\t\textremes = {},\n\t\tsmallestSize = math.min(chart.plotWidth, chart.plotHeight),\n\t\tzMin = Number.MAX_VALUE,\n\t\tzMax = -Number.MAX_VALUE,\n\t\trange = this.max - min,\n\t\ttransA = axisLength / range,\n\t\tactiveSeries = [];\n\n\t// Handle padding on the second pass, or on redraw\n\tif (this.tickPositions) {\n\t\teach(this.series, function (series) {\n\n\t\t\tvar seriesOptions = series.options,\n\t\t\t\tzData;\n\n\t\t\tif (series.type === 'bubble' && series.visible) {\n\n\t\t\t\t// Correction for #1673\n\t\t\t\taxis.allowZoomOutside = true;\n\n\t\t\t\t// Cache it\n\t\t\t\tactiveSeries.push(series);\n\n\t\t\t\tif (isXAxis) { // because X axis is evaluated first\n\t\t\t\t\n\t\t\t\t\t// For each series, translate the size extremes to pixel values\n\t\t\t\t\teach(['minSize', 'maxSize'], function (prop) {\n\t\t\t\t\t\tvar length = seriesOptions[prop],\n\t\t\t\t\t\t\tisPercent = /%$/.test(length);\n\t\t\t\t\t\t\n\t\t\t\t\t\tlength = pInt(length);\n\t\t\t\t\t\textremes[prop] = isPercent ?\n\t\t\t\t\t\t\tsmallestSize * length / 100 :\n\t\t\t\t\t\t\tlength;\n\t\t\t\t\t\t\n\t\t\t\t\t});\n\t\t\t\t\tseries.minPxSize = extremes.minSize;\n\t\t\t\t\t\n\t\t\t\t\t// Find the min and max Z\n\t\t\t\t\tzData = series.zData;\n\t\t\t\t\tif (zData.length) { // #1735\n\t\t\t\t\t\tzMin = math.min(\n\t\t\t\t\t\t\tzMin,\n\t\t\t\t\t\t\tmath.max(\n\t\t\t\t\t\t\t\tarrayMin(zData), \n\t\t\t\t\t\t\t\tseriesOptions.displayNegative === false ? seriesOptions.zThreshold : -Number.MAX_VALUE\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t\tzMax = math.max(zMax, arrayMax(zData));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\teach(activeSeries, function (series) {\n\n\t\t\tvar data = series[dataKey],\n\t\t\t\ti = data.length,\n\t\t\t\tradius;\n\n\t\t\tif (isXAxis) {\n\t\t\t\tseries.getRadii(zMin, zMax, extremes.minSize, extremes.maxSize);\n\t\t\t}\n\t\t\t\n\t\t\tif (range > 0) {\n\t\t\t\twhile (i--) {\n\t\t\t\t\tradius = series.radii[i];\n\t\t\t\t\tpxMin = Math.min(((data[i] - min) * transA) - radius, pxMin);\n\t\t\t\t\tpxMax = Math.max(((data[i] - min) * transA) + radius, pxMax);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\t\n\t\tif (activeSeries.length && range > 0 && pick(this.options.min, this.userMin) === UNDEFINED && pick(this.options.max, this.userMax) === UNDEFINED) {\n\t\t\tpxMax -= axisLength;\n\t\t\ttransA *= (axisLength + pxMin - pxMax) / axisLength;\n\t\t\tthis.min += pxMin / transA;\n\t\t\tthis.max += pxMax / transA;\n\t\t}\n\t}\n};\n\n/* ****************************************************************************\n * End Bubble series code                                                     *\n *****************************************************************************/\n/**\n * Extensions for polar charts. Additionally, much of the geometry required for polar charts is\n * gathered in RadialAxes.js.\n * \n */\n\nvar seriesProto = Series.prototype,\n\tpointerProto = Highcharts.Pointer.prototype;\n\n\n\n/**\n * Translate a point's plotX and plotY from the internal angle and radius measures to \n * true plotX, plotY coordinates\n */\nseriesProto.toXY = function (point) {\n\tvar xy,\n\t\tchart = this.chart,\n\t\tplotX = point.plotX,\n\t\tplotY = point.plotY;\n\t\n\t// Save rectangular plotX, plotY for later computation\n\tpoint.rectPlotX = plotX;\n\tpoint.rectPlotY = plotY;\n\t\n\t// Record the angle in degrees for use in tooltip\n\tpoint.clientX = ((plotX / Math.PI * 180) + this.xAxis.pane.options.startAngle) % 360;\n\t\n\t// Find the polar plotX and plotY\n\txy = this.xAxis.postTranslate(point.plotX, this.yAxis.len - plotY);\n\tpoint.plotX = point.polarPlotX = xy.x - chart.plotLeft;\n\tpoint.plotY = point.polarPlotY = xy.y - chart.plotTop;\n};\n\n/** \n * Order the tooltip points to get the mouse capture ranges correct. #1915. \n */\nseriesProto.orderTooltipPoints = function (points) {\n\tif (this.chart.polar) {\n\t\tpoints.sort(function (a, b) {\n\t\t\treturn a.clientX - b.clientX;\n\t\t});\n\n\t\t// Wrap mouse tracking around to capture movement on the segment to the left\n\t\t// of the north point (#1469, #2093).\n\t\tif (points[0]) {\n\t\t\tpoints[0].wrappedClientX = points[0].clientX + 360;\n\t\t\tpoints.push(points[0]);\n\t\t}\n\t}\n};\n\n\n/**\n * Add some special init logic to areas and areasplines\n */\nfunction initArea(proceed, chart, options) {\n\tproceed.call(this, chart, options);\n\tif (this.chart.polar) {\n\t\t\n\t\t/**\n\t\t * Overridden method to close a segment path. While in a cartesian plane the area \n\t\t * goes down to the threshold, in the polar chart it goes to the center.\n\t\t */\n\t\tthis.closeSegment = function (path) {\n\t\t\tvar center = this.xAxis.center;\n\t\t\tpath.push(\n\t\t\t\t'L',\n\t\t\t\tcenter[0],\n\t\t\t\tcenter[1]\n\t\t\t);\t\t\t\n\t\t};\n\t\t\n\t\t// Instead of complicated logic to draw an area around the inner area in a stack,\n\t\t// just draw it behind\n\t\tthis.closedStacks = true;\n\t}\n}\nwrap(seriesTypes.area.prototype, 'init', initArea);\nwrap(seriesTypes.areaspline.prototype, 'init', initArea);\n\t\t\n\n/**\n * Overridden method for calculating a spline from one point to the next\n */\nwrap(seriesTypes.spline.prototype, 'getPointSpline', function (proceed, segment, point, i) {\n\t\n\tvar ret,\n\t\tsmoothing = 1.5, // 1 means control points midway between points, 2 means 1/3 from the point, 3 is 1/4 etc;\n\t\tdenom = smoothing + 1,\n\t\tplotX, \n\t\tplotY,\n\t\tlastPoint,\n\t\tnextPoint,\n\t\tlastX,\n\t\tlastY,\n\t\tnextX,\n\t\tnextY,\n\t\tleftContX,\n\t\tleftContY,\n\t\trightContX,\n\t\trightContY,\n\t\tdistanceLeftControlPoint,\n\t\tdistanceRightControlPoint,\n\t\tleftContAngle,\n\t\trightContAngle,\n\t\tjointAngle;\n\t\t\n\t\t\n\tif (this.chart.polar) {\n\t\t\n\t\tplotX = point.plotX;\n\t\tplotY = point.plotY;\n\t\tlastPoint = segment[i - 1];\n\t\tnextPoint = segment[i + 1];\n\t\t\t\n\t\t// Connect ends\n\t\tif (this.connectEnds) {\n\t\t\tif (!lastPoint) {\n\t\t\t\tlastPoint = segment[segment.length - 2]; // not the last but the second last, because the segment is already connected\n\t\t\t}\n\t\t\tif (!nextPoint) {\n\t\t\t\tnextPoint = segment[1];\n\t\t\t}\t\n\t\t}\n\n\t\t// find control points\n\t\tif (lastPoint && nextPoint) {\n\t\t\n\t\t\tlastX = lastPoint.plotX;\n\t\t\tlastY = lastPoint.plotY;\n\t\t\tnextX = nextPoint.plotX;\n\t\t\tnextY = nextPoint.plotY;\n\t\t\tleftContX = (smoothing * plotX + lastX) / denom;\n\t\t\tleftContY = (smoothing * plotY + lastY) / denom;\n\t\t\trightContX = (smoothing * plotX + nextX) / denom;\n\t\t\trightContY = (smoothing * plotY + nextY) / denom;\n\t\t\tdistanceLeftControlPoint = Math.sqrt(Math.pow(leftContX - plotX, 2) + Math.pow(leftContY - plotY, 2));\n\t\t\tdistanceRightControlPoint = Math.sqrt(Math.pow(rightContX - plotX, 2) + Math.pow(rightContY - plotY, 2));\n\t\t\tleftContAngle = Math.atan2(leftContY - plotY, leftContX - plotX);\n\t\t\trightContAngle = Math.atan2(rightContY - plotY, rightContX - plotX);\n\t\t\tjointAngle = (Math.PI / 2) + ((leftContAngle + rightContAngle) / 2);\n\t\t\t\t\n\t\t\t\t\n\t\t\t// Ensure the right direction, jointAngle should be in the same quadrant as leftContAngle\n\t\t\tif (Math.abs(leftContAngle - jointAngle) > Math.PI / 2) {\n\t\t\t\tjointAngle -= Math.PI;\n\t\t\t}\n\t\t\t\n\t\t\t// Find the corrected control points for a spline straight through the point\n\t\t\tleftContX = plotX + Math.cos(jointAngle) * distanceLeftControlPoint;\n\t\t\tleftContY = plotY + Math.sin(jointAngle) * distanceLeftControlPoint;\n\t\t\trightContX = plotX + Math.cos(Math.PI + jointAngle) * distanceRightControlPoint;\n\t\t\trightContY = plotY + Math.sin(Math.PI + jointAngle) * distanceRightControlPoint;\n\t\t\t\n\t\t\t// Record for drawing in next point\n\t\t\tpoint.rightContX = rightContX;\n\t\t\tpoint.rightContY = rightContY;\n\n\t\t}\n\t\t\n\t\t\n\t\t// moveTo or lineTo\n\t\tif (!i) {\n\t\t\tret = ['M', plotX, plotY];\n\t\t} else { // curve from last point to this\n\t\t\tret = [\n\t\t\t\t'C',\n\t\t\t\tlastPoint.rightContX || lastPoint.plotX,\n\t\t\t\tlastPoint.rightContY || lastPoint.plotY,\n\t\t\t\tleftContX || plotX,\n\t\t\t\tleftContY || plotY,\n\t\t\t\tplotX,\n\t\t\t\tplotY\n\t\t\t];\n\t\t\tlastPoint.rightContX = lastPoint.rightContY = null; // reset for updating series later\n\t\t}\n\t\t\n\t\t\n\t} else {\n\t\tret = proceed.call(this, segment, point, i);\n\t}\n\treturn ret;\n});\n\n/**\n * Extend translate. The plotX and plotY values are computed as if the polar chart were a\n * cartesian plane, where plotX denotes the angle in radians and (yAxis.len - plotY) is the pixel distance from\n * center. \n */\nwrap(seriesProto, 'translate', function (proceed) {\n\t\t\n\t// Run uber method\n\tproceed.call(this);\n\t\n\t// Postprocess plot coordinates\n\tif (this.chart.polar && !this.preventPostTranslate) {\n\t\tvar points = this.points,\n\t\t\ti = points.length;\n\t\twhile (i--) {\n\t\t\t// Translate plotX, plotY from angle and radius to true plot coordinates\n\t\t\tthis.toXY(points[i]);\n\t\t}\n\t}\n});\n\n/** \n * Extend getSegmentPath to allow connecting ends across 0 to provide a closed circle in \n * line-like series.\n */\nwrap(seriesProto, 'getSegmentPath', function (proceed, segment) {\n\t\t\n\tvar points = this.points;\n\t\n\t// Connect the path\n\tif (this.chart.polar && this.options.connectEnds !== false && \n\t\t\tsegment[segment.length - 1] === points[points.length - 1] && points[0].y !== null) {\n\t\tthis.connectEnds = true; // re-used in splines\n\t\tsegment = [].concat(segment, [points[0]]);\n\t}\n\t\n\t// Run uber method\n\treturn proceed.call(this, segment);\n\t\n});\n\n\nfunction polarAnimate(proceed, init) {\n\tvar chart = this.chart,\n\t\tanimation = this.options.animation,\n\t\tgroup = this.group,\n\t\tmarkerGroup = this.markerGroup,\n\t\tcenter = this.xAxis.center,\n\t\tplotLeft = chart.plotLeft,\n\t\tplotTop = chart.plotTop,\n\t\tattribs;\n\n\t// Specific animation for polar charts\n\tif (chart.polar) {\n\t\t\n\t\t// Enable animation on polar charts only in SVG. In VML, the scaling is different, plus animation\n\t\t// would be so slow it would't matter.\n\t\tif (chart.renderer.isSVG) {\n\n\t\t\tif (animation === true) {\n\t\t\t\tanimation = {};\n\t\t\t}\n\t\n\t\t\t// Initialize the animation\n\t\t\tif (init) {\n\t\t\t\t\n\t\t\t\t// Scale down the group and place it in the center\n\t\t\t\tattribs = {\n\t\t\t\t\ttranslateX: center[0] + plotLeft,\n\t\t\t\t\ttranslateY: center[1] + plotTop,\n\t\t\t\t\tscaleX: 0.001, // #1499\n\t\t\t\t\tscaleY: 0.001\n\t\t\t\t};\n\t\t\t\t\t\n\t\t\t\tgroup.attr(attribs);\n\t\t\t\tif (markerGroup) {\n\t\t\t\t\tmarkerGroup.attrSetters = group.attrSetters;\n\t\t\t\t\tmarkerGroup.attr(attribs);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t// Run the animation\n\t\t\t} else {\n\t\t\t\tattribs = {\n\t\t\t\t\ttranslateX: plotLeft,\n\t\t\t\t\ttranslateY: plotTop,\n\t\t\t\t\tscaleX: 1,\n\t\t\t\t\tscaleY: 1\n\t\t\t\t};\n\t\t\t\tgroup.animate(attribs, animation);\n\t\t\t\tif (markerGroup) {\n\t\t\t\t\tmarkerGroup.animate(attribs, animation);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Delete this function to allow it only once\n\t\t\t\tthis.animate = null;\n\t\t\t}\n\t\t}\n\t\n\t// For non-polar charts, revert to the basic animation\n\t} else {\n\t\tproceed.call(this, init);\n\t} \n}\n\n// Define the animate method for both regular series and column series and their derivatives\nwrap(seriesProto, 'animate', polarAnimate);\nwrap(colProto, 'animate', polarAnimate);\n\n\n/**\n * Throw in a couple of properties to let setTooltipPoints know we're indexing the points\n * in degrees (0-360), not plot pixel width.\n */\nwrap(seriesProto, 'setTooltipPoints', function (proceed, renew) {\n\t\t\n\tif (this.chart.polar) {\n\t\textend(this.xAxis, {\n\t\t\ttooltipLen: 360 // degrees are the resolution unit of the tooltipPoints array\n\t\t});\t\n\t}\n\t\n\t// Run uber method\n\treturn proceed.call(this, renew);\n});\n\n\n/**\n * Extend the column prototype's translate method\n */\nwrap(colProto, 'translate', function (proceed) {\n\t\t\n\tvar xAxis = this.xAxis,\n\t\tlen = this.yAxis.len,\n\t\tcenter = xAxis.center,\n\t\tstartAngleRad = xAxis.startAngleRad,\n\t\trenderer = this.chart.renderer,\n\t\tstart,\n\t\tpoints,\n\t\tpoint,\n\t\ti;\n\t\n\tthis.preventPostTranslate = true;\n\t\n\t// Run uber method\n\tproceed.call(this);\n\t\n\t// Postprocess plot coordinates\n\tif (xAxis.isRadial) {\n\t\tpoints = this.points;\n\t\ti = points.length;\n\t\twhile (i--) {\n\t\t\tpoint = points[i];\n\t\t\tstart = point.barX + startAngleRad;\n\t\t\tpoint.shapeType = 'path';\n\t\t\tpoint.shapeArgs = {\n\t\t\t\td: renderer.symbols.arc(\n\t\t\t\t\tcenter[0],\n\t\t\t\t\tcenter[1],\n\t\t\t\t\tlen - point.plotY,\n\t\t\t\t\tnull, \n\t\t\t\t\t{\n\t\t\t\t\t\tstart: start,\n\t\t\t\t\t\tend: start + point.pointWidth,\n\t\t\t\t\t\tinnerR: len - pick(point.yBottom, len)\n\t\t\t\t\t}\n\t\t\t\t)\n\t\t\t};\n\t\t\tthis.toXY(point); // provide correct plotX, plotY for tooltip\n\t\t}\n\t}\n});\n\n\n/**\n * Align column data labels outside the columns. #1199.\n */\nwrap(colProto, 'alignDataLabel', function (proceed, point, dataLabel, options, alignTo, isNew) {\n\t\n\tif (this.chart.polar) {\n\t\tvar angle = point.rectPlotX / Math.PI * 180,\n\t\t\talign,\n\t\t\tverticalAlign;\n\t\t\n\t\t// Align nicely outside the perimeter of the columns\n\t\tif (options.align === null) {\n\t\t\tif (angle > 20 && angle < 160) {\n\t\t\t\talign = 'left'; // right hemisphere\n\t\t\t} else if (angle > 200 && angle < 340) {\n\t\t\t\talign = 'right'; // left hemisphere\n\t\t\t} else {\n\t\t\t\talign = 'center'; // top or bottom\n\t\t\t}\n\t\t\toptions.align = align;\n\t\t}\n\t\tif (options.verticalAlign === null) {\n\t\t\tif (angle < 45 || angle > 315) {\n\t\t\t\tverticalAlign = 'bottom'; // top part\n\t\t\t} else if (angle > 135 && angle < 225) {\n\t\t\t\tverticalAlign = 'top'; // bottom part\n\t\t\t} else {\n\t\t\t\tverticalAlign = 'middle'; // left or right\n\t\t\t}\n\t\t\toptions.verticalAlign = verticalAlign;\n\t\t}\n\t\t\n\t\tseriesProto.alignDataLabel.call(this, point, dataLabel, options, alignTo, isNew);\n\t} else {\n\t\tproceed.call(this, point, dataLabel, options, alignTo, isNew);\n\t}\n\t\n});\n\n/**\n * Extend the mouse tracker to return the tooltip position index in terms of\n * degrees rather than pixels\n */\nwrap(pointerProto, 'getIndex', function (proceed, e) {\n\tvar ret,\n\t\tchart = this.chart,\n\t\tcenter,\n\t\tx,\n\t\ty;\n\t\n\tif (chart.polar) {\n\t\tcenter = chart.xAxis[0].center;\n\t\tx = e.chartX - center[0] - chart.plotLeft;\n\t\ty = e.chartY - center[1] - chart.plotTop;\n\t\t\n\t\tret = 180 - Math.round(Math.atan2(x, y) / Math.PI * 180);\n\t\n\t} else {\n\t\n\t\t// Run uber method\n\t\tret = proceed.call(this, e);\n\t}\n\treturn ret;\n});\n\n/**\n * Extend getCoordinates to prepare for polar axis values\n */\nwrap(pointerProto, 'getCoordinates', function (proceed, e) {\n\tvar chart = this.chart,\n\t\tret = {\n\t\t\txAxis: [],\n\t\t\tyAxis: []\n\t\t};\n\t\n\tif (chart.polar) {\t\n\n\t\teach(chart.axes, function (axis) {\n\t\t\tvar isXAxis = axis.isXAxis,\n\t\t\t\tcenter = axis.center,\n\t\t\t\tx = e.chartX - center[0] - chart.plotLeft,\n\t\t\t\ty = e.chartY - center[1] - chart.plotTop;\n\t\t\t\n\t\t\tret[isXAxis ? 'xAxis' : 'yAxis'].push({\n\t\t\t\taxis: axis,\n\t\t\t\tvalue: axis.translate(\n\t\t\t\t\tisXAxis ?\n\t\t\t\t\t\tMath.PI - Math.atan2(x, y) : // angle \n\t\t\t\t\t\tMath.sqrt(Math.pow(x, 2) + Math.pow(y, 2)), // distance from center\n\t\t\t\t\ttrue\n\t\t\t\t)\n\t\t\t});\n\t\t});\n\t\t\n\t} else {\n\t\tret = proceed.call(this, e);\n\t}\n\t\n\treturn ret;\n});\n}(Highcharts));\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/highcharts.js",
    "content": "/*\n Highcharts JS v3.0.6 (2013-10-04)\n\n (c) 2009-2013 Torstein Hønsi\n\n License: www.highcharts.com/license\n*/\n(function(){function r(a,b){var c;a||(a={});for(c in b)a[c]=b[c];return a}function x(){var a,b=arguments.length,c={},d=function(a,b){var c,h;typeof a!==\"object\"&&(a={});for(h in b)b.hasOwnProperty(h)&&(c=b[h],a[h]=c&&typeof c===\"object\"&&Object.prototype.toString.call(c)!==\"[object Array]\"&&typeof c.nodeType!==\"number\"?d(a[h]||{},c):b[h]);return a};for(a=0;a<b;a++)c=d(c,arguments[a]);return c}function C(a,b){return parseInt(a,b||10)}function ea(a){return typeof a===\"string\"}function T(a){return typeof a===\n\"object\"}function Ia(a){return Object.prototype.toString.call(a)===\"[object Array]\"}function sa(a){return typeof a===\"number\"}function na(a){return R.log(a)/R.LN10}function fa(a){return R.pow(10,a)}function ga(a,b){for(var c=a.length;c--;)if(a[c]===b){a.splice(c,1);break}}function u(a){return a!==w&&a!==null}function v(a,b,c){var d,e;if(ea(b))u(c)?a.setAttribute(b,c):a&&a.getAttribute&&(e=a.getAttribute(b));else if(u(b)&&T(b))for(d in b)a.setAttribute(d,b[d]);return e}function ja(a){return Ia(a)?\na:[a]}function o(){var a=arguments,b,c,d=a.length;for(b=0;b<d;b++)if(c=a[b],typeof c!==\"undefined\"&&c!==null)return c}function K(a,b){if(ta&&b&&b.opacity!==w)b.filter=\"alpha(opacity=\"+b.opacity*100+\")\";r(a.style,b)}function U(a,b,c,d,e){a=y.createElement(a);b&&r(a,b);e&&K(a,{padding:0,border:S,margin:0});c&&K(a,c);d&&d.appendChild(a);return a}function ha(a,b){var c=function(){};c.prototype=new a;r(c.prototype,b);return c}function Aa(a,b,c,d){var e=M.lang,a=+a||0,f=b===-1?(a.toString().split(\".\")[1]||\n\"\").length:isNaN(b=N(b))?2:b,b=c===void 0?e.decimalPoint:c,d=d===void 0?e.thousandsSep:d,e=a<0?\"-\":\"\",c=String(C(a=N(a).toFixed(f))),g=c.length>3?c.length%3:0;return e+(g?c.substr(0,g)+d:\"\")+c.substr(g).replace(/(\\d{3})(?=\\d)/g,\"$1\"+d)+(f?b+N(a-c).toFixed(f).slice(2):\"\")}function Ba(a,b){return Array((b||2)+1-String(a).length).join(0)+a}function mb(a,b,c){var d=a[b];a[b]=function(){var a=Array.prototype.slice.call(arguments);a.unshift(d);return c.apply(this,a)}}function Ca(a,b){for(var c=\"{\",d=!1,\ne,f,g,h,i,j=[];(c=a.indexOf(c))!==-1;){e=a.slice(0,c);if(d){f=e.split(\":\");g=f.shift().split(\".\");i=g.length;e=b;for(h=0;h<i;h++)e=e[g[h]];if(f.length)f=f.join(\":\"),g=/\\.([0-9])/,h=M.lang,i=void 0,/f$/.test(f)?(i=(i=f.match(g))?i[1]:-1,e=Aa(e,i,h.decimalPoint,f.indexOf(\",\")>-1?h.thousandsSep:\"\")):e=Xa(f,e)}j.push(e);a=a.slice(c+1);c=(d=!d)?\"}\":\"{\"}j.push(a);return j.join(\"\")}function nb(a){return R.pow(10,P(R.log(a)/R.LN10))}function ob(a,b,c,d){var e,c=o(c,1);e=a/c;b||(b=[1,2,2.5,5,10],d&&d.allowDecimals===\n!1&&(c===1?b=[1,2,5,10]:c<=0.1&&(b=[1/c])));for(d=0;d<b.length;d++)if(a=b[d],e<=(b[d]+(b[d+1]||b[d]))/2)break;a*=c;return a}function Cb(a,b){var c=b||[[Db,[1,2,5,10,20,25,50,100,200,500]],[pb,[1,2,5,10,15,30]],[Ya,[1,2,5,10,15,30]],[Qa,[1,2,3,4,6,8,12]],[ua,[1,2]],[Za,[1,2]],[Ra,[1,2,3,4,6]],[Da,null]],d=c[c.length-1],e=D[d[0]],f=d[1],g;for(g=0;g<c.length;g++)if(d=c[g],e=D[d[0]],f=d[1],c[g+1]&&a<=(e*f[f.length-1]+D[c[g+1][0]])/2)break;e===D[Da]&&a<5*e&&(f=[1,2,5]);c=ob(a/e,f,d[0]===Da?nb(a/e):1);\nreturn{unitRange:e,count:c,unitName:d[0]}}function Eb(a,b,c,d){var e=[],f={},g=M.global.useUTC,h,i=new Date(b),j=a.unitRange,k=a.count;if(u(b)){j>=D[pb]&&(i.setMilliseconds(0),i.setSeconds(j>=D[Ya]?0:k*P(i.getSeconds()/k)));if(j>=D[Ya])i[Fb](j>=D[Qa]?0:k*P(i[qb]()/k));if(j>=D[Qa])i[Gb](j>=D[ua]?0:k*P(i[rb]()/k));if(j>=D[ua])i[sb](j>=D[Ra]?1:k*P(i[Sa]()/k));j>=D[Ra]&&(i[Hb](j>=D[Da]?0:k*P(i[$a]()/k)),h=i[ab]());j>=D[Da]&&(h-=h%k,i[Ib](h));if(j===D[Za])i[sb](i[Sa]()-i[tb]()+o(d,1));b=1;h=i[ab]();for(var d=\ni.getTime(),l=i[$a](),m=i[Sa](),p=g?0:(864E5+i.getTimezoneOffset()*6E4)%864E5;d<c;)e.push(d),j===D[Da]?d=bb(h+b*k,0):j===D[Ra]?d=bb(h,l+b*k):!g&&(j===D[ua]||j===D[Za])?d=bb(h,l,m+b*k*(j===D[ua]?1:7)):d+=j*k,b++;e.push(d);n(ub(e,function(a){return j<=D[Qa]&&a%D[ua]===p}),function(a){f[a]=ua})}e.info=r(a,{higherRanks:f,totalRange:j*k});return e}function Jb(){this.symbol=this.color=0}function Kb(a,b){var c=a.length,d,e;for(e=0;e<c;e++)a[e].ss_i=e;a.sort(function(a,c){d=b(a,c);return d===0?a.ss_i-c.ss_i:\nd});for(e=0;e<c;e++)delete a[e].ss_i}function Ja(a){for(var b=a.length,c=a[0];b--;)a[b]<c&&(c=a[b]);return c}function va(a){for(var b=a.length,c=a[0];b--;)a[b]>c&&(c=a[b]);return c}function Ka(a,b){for(var c in a)a[c]&&a[c]!==b&&a[c].destroy&&a[c].destroy(),delete a[c]}function Ta(a){cb||(cb=U(Ea));a&&cb.appendChild(a);cb.innerHTML=\"\"}function ka(a,b){var c=\"Highcharts error #\"+a+\": www.highcharts.com/errors/\"+a;if(b)throw c;else O.console&&console.log(c)}function ia(a){return parseFloat(a.toPrecision(14))}\nfunction La(a,b){Fa=o(a,b.animation)}function Lb(){var a=M.global.useUTC,b=a?\"getUTC\":\"get\",c=a?\"setUTC\":\"set\";bb=a?Date.UTC:function(a,b,c,g,h,i){return(new Date(a,b,o(c,1),o(g,0),o(h,0),o(i,0))).getTime()};qb=b+\"Minutes\";rb=b+\"Hours\";tb=b+\"Day\";Sa=b+\"Date\";$a=b+\"Month\";ab=b+\"FullYear\";Fb=c+\"Minutes\";Gb=c+\"Hours\";sb=c+\"Date\";Hb=c+\"Month\";Ib=c+\"FullYear\"}function wa(){}function Ma(a,b,c,d){this.axis=a;this.pos=b;this.type=c||\"\";this.isNew=!0;!c&&!d&&this.addLabel()}function vb(a,b){this.axis=a;if(b)this.options=\nb,this.id=b.id}function Mb(a,b,c,d,e,f){var g=a.chart.inverted;this.axis=a;this.isNegative=c;this.options=b;this.x=d;this.total=null;this.points={};this.stack=e;this.percent=f===\"percent\";this.alignOptions={align:b.align||(g?c?\"left\":\"right\":\"center\"),verticalAlign:b.verticalAlign||(g?\"middle\":c?\"bottom\":\"top\"),y:o(b.y,g?4:c?14:-6),x:o(b.x,g?c?-6:6:0)};this.textAlign=b.textAlign||(g?c?\"right\":\"left\":\"center\")}function db(){this.init.apply(this,arguments)}function wb(){this.init.apply(this,arguments)}\nfunction xb(a,b){this.init(a,b)}function eb(a,b){this.init(a,b)}function yb(){this.init.apply(this,arguments)}var w,y=document,O=window,R=Math,t=R.round,P=R.floor,xa=R.ceil,s=R.max,I=R.min,N=R.abs,V=R.cos,ca=R.sin,ya=R.PI,Ua=ya*2/360,oa=navigator.userAgent,Nb=O.opera,ta=/msie/i.test(oa)&&!Nb,fb=y.documentMode===8,gb=/AppleWebKit/.test(oa),hb=/Firefox/.test(oa),Ob=/(Mobile|Android|Windows Phone)/.test(oa),za=\"http://www.w3.org/2000/svg\",Z=!!y.createElementNS&&!!y.createElementNS(za,\"svg\").createSVGRect,\nUb=hb&&parseInt(oa.split(\"Firefox/\")[1],10)<4,$=!Z&&!ta&&!!y.createElement(\"canvas\").getContext,Va,ib=y.documentElement.ontouchstart!==w,Pb={},zb=0,cb,M,Xa,Fa,Ab,D,pa=function(){},Ga=[],Ea=\"div\",S=\"none\",Qb=\"rgba(192,192,192,\"+(Z?1.0E-4:0.002)+\")\",Db=\"millisecond\",pb=\"second\",Ya=\"minute\",Qa=\"hour\",ua=\"day\",Za=\"week\",Ra=\"month\",Da=\"year\",Rb=\"stroke-width\",bb,qb,rb,tb,Sa,$a,ab,Fb,Gb,sb,Hb,Ib,W={};O.Highcharts=O.Highcharts?ka(16,!0):{};Xa=function(a,b,c){if(!u(b)||isNaN(b))return\"Invalid date\";var a=\no(a,\"%Y-%m-%d %H:%M:%S\"),d=new Date(b),e,f=d[rb](),g=d[tb](),h=d[Sa](),i=d[$a](),j=d[ab](),k=M.lang,l=k.weekdays,d=r({a:l[g].substr(0,3),A:l[g],d:Ba(h),e:h,b:k.shortMonths[i],B:k.months[i],m:Ba(i+1),y:j.toString().substr(2,2),Y:j,H:Ba(f),I:Ba(f%12||12),l:f%12||12,M:Ba(d[qb]()),p:f<12?\"AM\":\"PM\",P:f<12?\"am\":\"pm\",S:Ba(d.getSeconds()),L:Ba(t(b%1E3),3)},Highcharts.dateFormats);for(e in d)for(;a.indexOf(\"%\"+e)!==-1;)a=a.replace(\"%\"+e,typeof d[e]===\"function\"?d[e](b):d[e]);return c?a.substr(0,1).toUpperCase()+\na.substr(1):a};Jb.prototype={wrapColor:function(a){if(this.color>=a)this.color=0},wrapSymbol:function(a){if(this.symbol>=a)this.symbol=0}};D=function(){for(var a=0,b=arguments,c=b.length,d={};a<c;a++)d[b[a++]]=b[a];return d}(Db,1,pb,1E3,Ya,6E4,Qa,36E5,ua,864E5,Za,6048E5,Ra,26784E5,Da,31556952E3);Ab={init:function(a,b,c){var b=b||\"\",d=a.shift,e=b.indexOf(\"C\")>-1,f=e?7:3,g,b=b.split(\" \"),c=[].concat(c),h,i,j=function(a){for(g=a.length;g--;)a[g]===\"M\"&&a.splice(g+1,0,a[g+1],a[g+2],a[g+1],a[g+2])};e&&\n(j(b),j(c));a.isArea&&(h=b.splice(b.length-6,6),i=c.splice(c.length-6,6));if(d<=c.length/f&&b.length===c.length)for(;d--;)c=[].concat(c).splice(0,f).concat(c);a.shift=0;if(b.length)for(a=c.length;b.length<a;)d=[].concat(b).splice(b.length-f,f),e&&(d[f-6]=d[f-2],d[f-5]=d[f-1]),b=b.concat(d);h&&(b=b.concat(h),c=c.concat(i));return[b,c]},step:function(a,b,c,d){var e=[],f=a.length;if(c===1)e=d;else if(f===b.length&&c<1)for(;f--;)d=parseFloat(a[f]),e[f]=isNaN(d)?a[f]:c*parseFloat(b[f]-d)+d;else e=b;return e}};\n(function(a){O.HighchartsAdapter=O.HighchartsAdapter||a&&{init:function(b){var c=a.fx,d=c.step,e,f=a.Tween,g=f&&f.propHooks;e=a.cssHooks.opacity;a.extend(a.easing,{easeOutQuad:function(a,b,c,d,e){return-d*(b/=e)*(b-2)+c}});a.each([\"cur\",\"_default\",\"width\",\"height\",\"opacity\"],function(a,b){var e=d,k,l;b===\"cur\"?e=c.prototype:b===\"_default\"&&f&&(e=g[b],b=\"set\");(k=e[b])&&(e[b]=function(c){c=a?c:this;if(c.prop!==\"align\")return l=c.elem,l.attr?l.attr(c.prop,b===\"cur\"?w:c.now):k.apply(this,arguments)})});\nmb(e,\"get\",function(a,b,c){return b.attr?b.opacity||0:a.call(this,b,c)});e=function(a){var c=a.elem,d;if(!a.started)d=b.init(c,c.d,c.toD),a.start=d[0],a.end=d[1],a.started=!0;c.attr(\"d\",b.step(a.start,a.end,a.pos,c.toD))};f?g.d={set:e}:d.d=e;this.each=Array.prototype.forEach?function(a,b){return Array.prototype.forEach.call(a,b)}:function(a,b){for(var c=0,d=a.length;c<d;c++)if(b.call(a[c],a[c],c,a)===!1)return c};a.fn.highcharts=function(){var a=\"Chart\",b=arguments,c,d;ea(b[0])&&(a=b[0],b=Array.prototype.slice.call(b,\n1));c=b[0];if(c!==w)c.chart=c.chart||{},c.chart.renderTo=this[0],new Highcharts[a](c,b[1]),d=this;c===w&&(d=Ga[v(this[0],\"data-highcharts-chart\")]);return d}},getScript:a.getScript,inArray:a.inArray,adapterRun:function(b,c){return a(b)[c]()},grep:a.grep,map:function(a,c){for(var d=[],e=0,f=a.length;e<f;e++)d[e]=c.call(a[e],a[e],e,a);return d},offset:function(b){return a(b).offset()},addEvent:function(b,c,d){a(b).bind(c,d)},removeEvent:function(b,c,d){var e=y.removeEventListener?\"removeEventListener\":\n\"detachEvent\";y[e]&&b&&!b[e]&&(b[e]=function(){});a(b).unbind(c,d)},fireEvent:function(b,c,d,e){var f=a.Event(c),g=\"detached\"+c,h;!ta&&d&&(delete d.layerX,delete d.layerY);r(f,d);b[c]&&(b[g]=b[c],b[c]=null);a.each([\"preventDefault\",\"stopPropagation\"],function(a,b){var c=f[b];f[b]=function(){try{c.call(f)}catch(a){b===\"preventDefault\"&&(h=!0)}}});a(b).trigger(f);b[g]&&(b[c]=b[g],b[g]=null);e&&!f.isDefaultPrevented()&&!h&&e(f)},washMouseEvent:function(a){var c=a.originalEvent||a;if(c.pageX===w)c.pageX=\na.pageX,c.pageY=a.pageY;return c},animate:function(b,c,d){var e=a(b);if(!b.style)b.style={};if(c.d)b.toD=c.d,c.d=1;e.stop();c.opacity!==w&&b.attr&&(c.opacity+=\"px\");e.animate(c,d)},stop:function(b){a(b).stop()}}})(O.jQuery);var X=O.HighchartsAdapter,G=X||{};X&&X.init.call(X,Ab);var jb=G.adapterRun,Vb=G.getScript,qa=G.inArray,n=G.each,ub=G.grep,Wb=G.offset,Na=G.map,J=G.addEvent,aa=G.removeEvent,z=G.fireEvent,Xb=G.washMouseEvent,Bb=G.animate,Wa=G.stop,G={enabled:!0,x:0,y:15,style:{color:\"#666\",cursor:\"default\",\nfontSize:\"11px\",lineHeight:\"14px\"}};M={colors:\"#2f7ed8,#0d233a,#8bbc21,#910000,#1aadce,#492970,#f28f43,#77a1e5,#c42525,#a6c96a\".split(\",\"),symbols:[\"circle\",\"diamond\",\"square\",\"triangle\",\"triangle-down\"],lang:{loading:\"Loading...\",months:\"January,February,March,April,May,June,July,August,September,October,November,December\".split(\",\"),shortMonths:\"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec\".split(\",\"),weekdays:\"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday\".split(\",\"),decimalPoint:\".\",\nnumericSymbols:\"k,M,G,T,P,E\".split(\",\"),resetZoom:\"Reset zoom\",resetZoomTitle:\"Reset zoom level 1:1\",thousandsSep:\",\"},global:{useUTC:!0,canvasToolsURL:\"http://code.highcharts.com/3.0.6/modules/canvas-tools.js\",VMLRadialGradientURL:\"http://code.highcharts.com/3.0.6/gfx/vml-radial-gradient.png\"},chart:{borderColor:\"#4572A7\",borderRadius:5,defaultSeriesType:\"line\",ignoreHiddenSeries:!0,spacing:[10,10,15,10],style:{fontFamily:'\"Lucida Grande\", \"Lucida Sans Unicode\", Verdana, Arial, Helvetica, sans-serif',\nfontSize:\"12px\"},backgroundColor:\"#FFFFFF\",plotBorderColor:\"#C0C0C0\",resetZoomButton:{theme:{zIndex:20},position:{align:\"right\",x:-10,y:10}}},title:{text:\"Chart title\",align:\"center\",margin:15,style:{color:\"#274b6d\",fontSize:\"16px\"}},subtitle:{text:\"\",align:\"center\",style:{color:\"#4d759e\"}},plotOptions:{line:{allowPointSelect:!1,showCheckbox:!1,animation:{duration:1E3},events:{},lineWidth:2,marker:{enabled:!0,lineWidth:0,radius:4,lineColor:\"#FFFFFF\",states:{hover:{enabled:!0},select:{fillColor:\"#FFFFFF\",\nlineColor:\"#000000\",lineWidth:2}}},point:{events:{}},dataLabels:x(G,{align:\"center\",enabled:!1,formatter:function(){return this.y===null?\"\":Aa(this.y,-1)},verticalAlign:\"bottom\",y:0}),cropThreshold:300,pointRange:0,showInLegend:!0,states:{hover:{marker:{}},select:{marker:{}}},stickyTracking:!0}},labels:{style:{position:\"absolute\",color:\"#3E576F\"}},legend:{enabled:!0,align:\"center\",layout:\"horizontal\",labelFormatter:function(){return this.name},borderWidth:1,borderColor:\"#909090\",borderRadius:5,navigation:{activeColor:\"#274b6d\",\ninactiveColor:\"#CCC\"},shadow:!1,itemStyle:{cursor:\"pointer\",color:\"#274b6d\",fontSize:\"12px\"},itemHoverStyle:{color:\"#000\"},itemHiddenStyle:{color:\"#CCC\"},itemCheckboxStyle:{position:\"absolute\",width:\"13px\",height:\"13px\"},symbolWidth:16,symbolPadding:5,verticalAlign:\"bottom\",x:0,y:0,title:{style:{fontWeight:\"bold\"}}},loading:{labelStyle:{fontWeight:\"bold\",position:\"relative\",top:\"1em\"},style:{position:\"absolute\",backgroundColor:\"white\",opacity:0.5,textAlign:\"center\"}},tooltip:{enabled:!0,animation:Z,\nbackgroundColor:\"rgba(255, 255, 255, .85)\",borderWidth:1,borderRadius:3,dateTimeLabelFormats:{millisecond:\"%A, %b %e, %H:%M:%S.%L\",second:\"%A, %b %e, %H:%M:%S\",minute:\"%A, %b %e, %H:%M\",hour:\"%A, %b %e, %H:%M\",day:\"%A, %b %e, %Y\",week:\"Week from %A, %b %e, %Y\",month:\"%B %Y\",year:\"%Y\"},headerFormat:'<span style=\"font-size: 10px\">{point.key}</span><br/>',pointFormat:'<span style=\"color:{series.color}\">{series.name}</span>: <b>{point.y}</b><br/>',shadow:!0,snap:Ob?25:10,style:{color:\"#333333\",cursor:\"default\",\nfontSize:\"12px\",padding:\"8px\",whiteSpace:\"nowrap\"}},credits:{enabled:!0,text:\"Highcharts.com\",href:\"http://www.highcharts.com\",position:{align:\"right\",x:-10,verticalAlign:\"bottom\",y:-5},style:{cursor:\"pointer\",color:\"#909090\",fontSize:\"9px\"}}};var Y=M.plotOptions,X=Y.line;Lb();var ra=function(a){var b=[],c,d;(function(a){a&&a.stops?d=Na(a.stops,function(a){return ra(a[1])}):(c=/rgba\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]?(?:\\.[0-9]+)?)\\s*\\)/.exec(a))?b=[C(c[1]),C(c[2]),\nC(c[3]),parseFloat(c[4],10)]:(c=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(a))?b=[C(c[1],16),C(c[2],16),C(c[3],16),1]:(c=/rgb\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)/.exec(a))&&(b=[C(c[1]),C(c[2]),C(c[3]),1])})(a);return{get:function(c){var f;d?(f=x(a),f.stops=[].concat(f.stops),n(d,function(a,b){f.stops[b]=[f.stops[b][0],a.get(c)]})):f=b&&!isNaN(b[0])?c===\"rgb\"?\"rgb(\"+b[0]+\",\"+b[1]+\",\"+b[2]+\")\":c===\"a\"?b[3]:\"rgba(\"+b.join(\",\")+\")\":a;return f},brighten:function(a){if(d)n(d,\nfunction(b){b.brighten(a)});else if(sa(a)&&a!==0){var c;for(c=0;c<3;c++)b[c]+=C(a*255),b[c]<0&&(b[c]=0),b[c]>255&&(b[c]=255)}return this},rgba:b,setOpacity:function(a){b[3]=a;return this}}};wa.prototype={init:function(a,b){this.element=b===\"span\"?U(b):y.createElementNS(za,b);this.renderer=a;this.attrSetters={}},opacity:1,animate:function(a,b,c){b=o(b,Fa,!0);Wa(this);if(b){b=x(b);if(c)b.complete=c;Bb(this,a,b)}else this.attr(a),c&&c()},attr:function(a,b){var c,d,e,f,g=this.element,h=g.nodeName.toLowerCase(),\ni=this.renderer,j,k=this.attrSetters,l=this.shadows,m,p,q=this;ea(a)&&u(b)&&(c=a,a={},a[c]=b);if(ea(a))c=a,h===\"circle\"?c={x:\"cx\",y:\"cy\"}[c]||c:c===\"strokeWidth\"&&(c=\"stroke-width\"),q=v(g,c)||this[c]||0,c!==\"d\"&&c!==\"visibility\"&&c!==\"fill\"&&(q=parseFloat(q));else{for(c in a)if(j=!1,d=a[c],e=k[c]&&k[c].call(this,d,c),e!==!1){e!==w&&(d=e);if(c===\"d\")d&&d.join&&(d=d.join(\" \")),/(NaN| {2}|^$)/.test(d)&&(d=\"M 0 0\");else if(c===\"x\"&&h===\"text\")for(e=0;e<g.childNodes.length;e++)f=g.childNodes[e],v(f,\"x\")===\nv(g,\"x\")&&v(f,\"x\",d);else if(this.rotation&&(c===\"x\"||c===\"y\"))p=!0;else if(c===\"fill\")d=i.color(d,g,c);else if(h===\"circle\"&&(c===\"x\"||c===\"y\"))c={x:\"cx\",y:\"cy\"}[c]||c;else if(h===\"rect\"&&c===\"r\")v(g,{rx:d,ry:d}),j=!0;else if(c===\"translateX\"||c===\"translateY\"||c===\"rotation\"||c===\"verticalAlign\"||c===\"scaleX\"||c===\"scaleY\")j=p=!0;else if(c===\"stroke\")d=i.color(d,g,c);else if(c===\"dashstyle\")if(c=\"stroke-dasharray\",d=d&&d.toLowerCase(),d===\"solid\")d=S;else{if(d){d=d.replace(\"shortdashdotdot\",\"3,1,1,1,1,1,\").replace(\"shortdashdot\",\n\"3,1,1,1\").replace(\"shortdot\",\"1,1,\").replace(\"shortdash\",\"3,1,\").replace(\"longdash\",\"8,3,\").replace(/dot/g,\"1,3,\").replace(\"dash\",\"4,3,\").replace(/,$/,\"\").split(\",\");for(e=d.length;e--;)d[e]=C(d[e])*o(a[\"stroke-width\"],this[\"stroke-width\"]);d=d.join(\",\")}}else if(c===\"width\")d=C(d);else if(c===\"align\")c=\"text-anchor\",d={left:\"start\",center:\"middle\",right:\"end\"}[d];else if(c===\"title\")e=g.getElementsByTagName(\"title\")[0],e||(e=y.createElementNS(za,\"title\"),g.appendChild(e)),e.textContent=d;c===\"strokeWidth\"&&\n(c=\"stroke-width\");if(c===\"stroke-width\"||c===\"stroke\"){this[c]=d;if(this.stroke&&this[\"stroke-width\"])v(g,\"stroke\",this.stroke),v(g,\"stroke-width\",this[\"stroke-width\"]),this.hasStroke=!0;else if(c===\"stroke-width\"&&d===0&&this.hasStroke)g.removeAttribute(\"stroke\"),this.hasStroke=!1;j=!0}this.symbolName&&/^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(c)&&(m||(this.symbolAttr(a),m=!0),j=!0);if(l&&/^(width|height|visibility|x|y|d|transform|cx|cy|r)$/.test(c))for(e=l.length;e--;)v(l[e],\nc,c===\"height\"?s(d-(l[e].cutHeight||0),0):d);if((c===\"width\"||c===\"height\")&&h===\"rect\"&&d<0)d=0;this[c]=d;c===\"text\"?(d!==this.textStr&&delete this.bBox,this.textStr=d,this.added&&i.buildText(this)):j||v(g,c,d)}p&&this.updateTransform()}return q},addClass:function(a){var b=this.element,c=v(b,\"class\")||\"\";c.indexOf(a)===-1&&v(b,\"class\",c+\" \"+a);return this},symbolAttr:function(a){var b=this;n(\"x,y,r,start,end,width,height,innerR,anchorX,anchorY\".split(\",\"),function(c){b[c]=o(a[c],b[c])});b.attr({d:b.renderer.symbols[b.symbolName](b.x,\nb.y,b.width,b.height,b)})},clip:function(a){return this.attr(\"clip-path\",a?\"url(\"+this.renderer.url+\"#\"+a.id+\")\":S)},crisp:function(a,b,c,d,e){var f,g={},h={},i,a=a||this.strokeWidth||this.attr&&this.attr(\"stroke-width\")||0;i=t(a)%2/2;h.x=P(b||this.x||0)+i;h.y=P(c||this.y||0)+i;h.width=P((d||this.width||0)-2*i);h.height=P((e||this.height||0)-2*i);h.strokeWidth=a;for(f in h)this[f]!==h[f]&&(this[f]=g[f]=h[f]);return g},css:function(a){var b=this.element,c=a&&a.width&&b.nodeName.toLowerCase()===\"text\",\nd,e=\"\",f=function(a,b){return\"-\"+b.toLowerCase()};if(a&&a.color)a.fill=a.color;this.styles=a=r(this.styles,a);$&&c&&delete a.width;if(ta&&!Z)c&&delete a.width,K(this.element,a);else{for(d in a)e+=d.replace(/([A-Z])/g,f)+\":\"+a[d]+\";\";v(b,\"style\",e)}c&&this.added&&this.renderer.buildText(this);return this},on:function(a,b){var c=this,d=c.element;ib&&a===\"click\"?(d.ontouchstart=function(a){c.touchEventFired=Date.now();a.preventDefault();b.call(d,a)},d.onclick=function(a){(oa.indexOf(\"Android\")===-1||\nDate.now()-(c.touchEventFired||0)>1100)&&b.call(d,a)}):d[\"on\"+a]=b;return this},setRadialReference:function(a){this.element.radialReference=a;return this},translate:function(a,b){return this.attr({translateX:a,translateY:b})},invert:function(){this.inverted=!0;this.updateTransform();return this},htmlCss:function(a){var b=this.element;if(b=a&&b.tagName===\"SPAN\"&&a.width)delete a.width,this.textWidth=b,this.updateTransform();this.styles=r(this.styles,a);K(this.element,a);return this},htmlGetBBox:function(){var a=\nthis.element,b=this.bBox;if(!b){if(a.nodeName===\"text\")a.style.position=\"absolute\";b=this.bBox={x:a.offsetLeft,y:a.offsetTop,width:a.offsetWidth,height:a.offsetHeight}}return b},htmlUpdateTransform:function(){if(this.added){var a=this.renderer,b=this.element,c=this.translateX||0,d=this.translateY||0,e=this.x||0,f=this.y||0,g=this.textAlign||\"left\",h={left:0,center:0.5,right:1}[g],i=g&&g!==\"left\",j=this.shadows;K(b,{marginLeft:c,marginTop:d});j&&n(j,function(a){K(a,{marginLeft:c+1,marginTop:d+1})});\nthis.inverted&&n(b.childNodes,function(c){a.invertChild(c,b)});if(b.tagName===\"SPAN\"){var k,l,j=this.rotation,m;k=0;var p=1,q=0,ba;m=C(this.textWidth);var A=this.xCorr||0,L=this.yCorr||0,Sb=[j,g,b.innerHTML,this.textWidth].join(\",\");if(Sb!==this.cTT){u(j)&&(k=j*Ua,p=V(k),q=ca(k),this.setSpanRotation(j,q,p));k=o(this.elemWidth,b.offsetWidth);l=o(this.elemHeight,b.offsetHeight);if(k>m&&/[ \\-]/.test(b.textContent||b.innerText))K(b,{width:m+\"px\",display:\"block\",whiteSpace:\"normal\"}),k=m;m=a.fontMetrics(b.style.fontSize).b;\nA=p<0&&-k;L=q<0&&-l;ba=p*q<0;A+=q*m*(ba?1-h:h);L-=p*m*(j?ba?h:1-h:1);i&&(A-=k*h*(p<0?-1:1),j&&(L-=l*h*(q<0?-1:1)),K(b,{textAlign:g}));this.xCorr=A;this.yCorr=L}K(b,{left:e+A+\"px\",top:f+L+\"px\"});if(gb)l=b.offsetHeight;this.cTT=Sb}}else this.alignOnAdd=!0},setSpanRotation:function(a){var b={};b[ta?\"-ms-transform\":gb?\"-webkit-transform\":hb?\"MozTransform\":Nb?\"-o-transform\":\"\"]=b.transform=\"rotate(\"+a+\"deg)\";K(this.element,b)},updateTransform:function(){var a=this.translateX||0,b=this.translateY||0,c=\nthis.scaleX,d=this.scaleY,e=this.inverted,f=this.rotation;e&&(a+=this.attr(\"width\"),b+=this.attr(\"height\"));a=[\"translate(\"+a+\",\"+b+\")\"];e?a.push(\"rotate(90) scale(-1,1)\"):f&&a.push(\"rotate(\"+f+\" \"+(this.x||0)+\" \"+(this.y||0)+\")\");(u(c)||u(d))&&a.push(\"scale(\"+o(c,1)+\" \"+o(d,1)+\")\");a.length&&v(this.element,\"transform\",a.join(\" \"))},toFront:function(){var a=this.element;a.parentNode.appendChild(a);return this},align:function(a,b,c){var d,e,f,g,h={};e=this.renderer;f=e.alignedObjects;if(a){if(this.alignOptions=\na,this.alignByTranslate=b,!c||ea(c))this.alignTo=d=c||\"renderer\",ga(f,this),f.push(this),c=null}else a=this.alignOptions,b=this.alignByTranslate,d=this.alignTo;c=o(c,e[d],e);d=a.align;e=a.verticalAlign;f=(c.x||0)+(a.x||0);g=(c.y||0)+(a.y||0);if(d===\"right\"||d===\"center\")f+=(c.width-(a.width||0))/{right:1,center:2}[d];h[b?\"translateX\":\"x\"]=t(f);if(e===\"bottom\"||e===\"middle\")g+=(c.height-(a.height||0))/({bottom:1,middle:2}[e]||1);h[b?\"translateY\":\"y\"]=t(g);this[this.placed?\"animate\":\"attr\"](h);this.placed=\n!0;this.alignAttr=h;return this},getBBox:function(){var a=this.bBox,b=this.renderer,c,d=this.rotation;c=this.element;var e=this.styles,f=d*Ua;if(!a){if(c.namespaceURI===za||b.forExport){try{a=c.getBBox?r({},c.getBBox()):{width:c.offsetWidth,height:c.offsetHeight}}catch(g){}if(!a||a.width<0)a={width:0,height:0}}else a=this.htmlGetBBox();if(b.isSVG){b=a.width;c=a.height;if(ta&&e&&e.fontSize===\"11px\"&&c.toPrecision(3)===\"22.7\")a.height=c=14;if(d)a.width=N(c*ca(f))+N(b*V(f)),a.height=N(c*V(f))+N(b*ca(f))}this.bBox=\na}return a},show:function(){return this.attr({visibility:\"visible\"})},hide:function(){return this.attr({visibility:\"hidden\"})},fadeOut:function(a){var b=this;b.animate({opacity:0},{duration:a||150,complete:function(){b.hide()}})},add:function(a){var b=this.renderer,c=a||b,d=c.element||b.box,e=d.childNodes,f=this.element,g=v(f,\"zIndex\"),h;if(a)this.parentGroup=a;this.parentInverted=a&&a.inverted;this.textStr!==void 0&&b.buildText(this);if(g)c.handleZ=!0,g=C(g);if(c.handleZ)for(c=0;c<e.length;c++)if(a=\ne[c],b=v(a,\"zIndex\"),a!==f&&(C(b)>g||!u(g)&&u(b))){d.insertBefore(f,a);h=!0;break}h||d.appendChild(f);this.added=!0;z(this,\"add\");return this},safeRemoveChild:function(a){var b=a.parentNode;b&&b.removeChild(a)},destroy:function(){var a=this,b=a.element||{},c=a.shadows,d=a.renderer.isSVG&&b.nodeName===\"SPAN\"&&b.parentNode,e,f;b.onclick=b.onmouseout=b.onmouseover=b.onmousemove=b.point=null;Wa(a);if(a.clipPath)a.clipPath=a.clipPath.destroy();if(a.stops){for(f=0;f<a.stops.length;f++)a.stops[f]=a.stops[f].destroy();\na.stops=null}a.safeRemoveChild(b);for(c&&n(c,function(b){a.safeRemoveChild(b)});d&&d.childNodes.length===0;)b=d.parentNode,a.safeRemoveChild(d),d=b;a.alignTo&&ga(a.renderer.alignedObjects,a);for(e in a)delete a[e];return null},shadow:function(a,b,c){var d=[],e,f,g=this.element,h,i,j,k;if(a){i=o(a.width,3);j=(a.opacity||0.15)/i;k=this.parentInverted?\"(-1,-1)\":\"(\"+o(a.offsetX,1)+\", \"+o(a.offsetY,1)+\")\";for(e=1;e<=i;e++){f=g.cloneNode(0);h=i*2+1-2*e;v(f,{isShadow:\"true\",stroke:a.color||\"black\",\"stroke-opacity\":j*\ne,\"stroke-width\":h,transform:\"translate\"+k,fill:S});if(c)v(f,\"height\",s(v(f,\"height\")-h,0)),f.cutHeight=h;b?b.element.appendChild(f):g.parentNode.insertBefore(f,g);d.push(f)}this.shadows=d}return this}};var Ha=function(){this.init.apply(this,arguments)};Ha.prototype={Element:wa,init:function(a,b,c,d){var e=location,f,g;f=this.createElement(\"svg\").attr({version:\"1.1\"});g=f.element;a.appendChild(g);a.innerHTML.indexOf(\"xmlns\")===-1&&v(g,\"xmlns\",za);this.isSVG=!0;this.box=g;this.boxWrapper=f;this.alignedObjects=\n[];this.url=(hb||gb)&&y.getElementsByTagName(\"base\").length?e.href.replace(/#.*?$/,\"\").replace(/([\\('\\)])/g,\"\\\\$1\").replace(/ /g,\"%20\"):\"\";this.createElement(\"desc\").add().element.appendChild(y.createTextNode(\"Created with Highcharts 3.0.6\"));this.defs=this.createElement(\"defs\").add();this.forExport=d;this.gradients={};this.setSize(b,c,!1);var h;if(hb&&a.getBoundingClientRect)this.subPixelFix=b=function(){K(a,{left:0,top:0});h=a.getBoundingClientRect();K(a,{left:xa(h.left)-h.left+\"px\",top:xa(h.top)-\nh.top+\"px\"})},b(),J(O,\"resize\",b)},isHidden:function(){return!this.boxWrapper.getBBox().width},destroy:function(){var a=this.defs;this.box=null;this.boxWrapper=this.boxWrapper.destroy();Ka(this.gradients||{});this.gradients=null;if(a)this.defs=a.destroy();this.subPixelFix&&aa(O,\"resize\",this.subPixelFix);return this.alignedObjects=null},createElement:function(a){var b=new this.Element;b.init(this,a);return b},draw:function(){},buildText:function(a){for(var b=a.element,c=this,d=c.forExport,e=o(a.textStr,\n\"\").toString().replace(/<(b|strong)>/g,'<span style=\"font-weight:bold\">').replace(/<(i|em)>/g,'<span style=\"font-style:italic\">').replace(/<a/g,\"<span\").replace(/<\\/(b|strong|i|em|a)>/g,\"</span>\").split(/<br.*?>/g),f=b.childNodes,g=/style=\"([^\"]+)\"/,h=/href=\"(http[^\"]+)\"/,i=v(b,\"x\"),j=a.styles,k=j&&j.width&&C(j.width),l=j&&j.lineHeight,m=f.length;m--;)b.removeChild(f[m]);k&&!a.added&&this.box.appendChild(b);e[e.length-1]===\"\"&&e.pop();n(e,function(e,f){var m,o=0,e=e.replace(/<span/g,\"|||<span\").replace(/<\\/span>/g,\n\"</span>|||\");m=e.split(\"|||\");n(m,function(e){if(e!==\"\"||m.length===1){var p={},n=y.createElementNS(za,\"tspan\"),s;g.test(e)&&(s=e.match(g)[1].replace(/(;| |^)color([ :])/,\"$1fill$2\"),v(n,\"style\",s));h.test(e)&&!d&&(v(n,\"onclick\",'location.href=\"'+e.match(h)[1]+'\"'),K(n,{cursor:\"pointer\"}));e=(e.replace(/<(.|\\n)*?>/g,\"\")||\" \").replace(/&lt;/g,\"<\").replace(/&gt;/g,\">\");if(e!==\" \"&&(n.appendChild(y.createTextNode(e)),o?p.dx=0:p.x=i,v(n,p),!o&&f&&(!Z&&d&&K(n,{display:\"block\"}),v(n,\"dy\",l||c.fontMetrics(/px$/.test(n.style.fontSize)?\nn.style.fontSize:j.fontSize).h,gb&&n.offsetHeight)),b.appendChild(n),o++,k))for(var e=e.replace(/([^\\^])-/g,\"$1- \").split(\" \"),u,t,p=a._clipHeight,E=[],w=C(l||16),B=1;e.length||E.length;)delete a.bBox,u=a.getBBox(),t=u.width,u=t>k,!u||e.length===1?(e=E,E=[],e.length&&(B++,p&&B*w>p?(e=[\"...\"],a.attr(\"title\",a.textStr)):(n=y.createElementNS(za,\"tspan\"),v(n,{dy:w,x:i}),s&&v(n,\"style\",s),b.appendChild(n),t>k&&(k=t)))):(n.removeChild(n.firstChild),E.unshift(e.pop())),e.length&&n.appendChild(y.createTextNode(e.join(\" \").replace(/- /g,\n\"-\")))}})})},button:function(a,b,c,d,e,f,g,h){var i=this.label(a,b,c,null,null,null,null,null,\"button\"),j=0,k,l,m,p,q,n,a={x1:0,y1:0,x2:0,y2:1},e=x({\"stroke-width\":1,stroke:\"#CCCCCC\",fill:{linearGradient:a,stops:[[0,\"#FEFEFE\"],[1,\"#F6F6F6\"]]},r:2,padding:5,style:{color:\"black\"}},e);m=e.style;delete e.style;f=x(e,{stroke:\"#68A\",fill:{linearGradient:a,stops:[[0,\"#FFF\"],[1,\"#ACF\"]]}},f);p=f.style;delete f.style;g=x(e,{stroke:\"#68A\",fill:{linearGradient:a,stops:[[0,\"#9BD\"],[1,\"#CDF\"]]}},g);q=g.style;\ndelete g.style;h=x(e,{style:{color:\"#CCC\"}},h);n=h.style;delete h.style;J(i.element,ta?\"mouseover\":\"mouseenter\",function(){j!==3&&i.attr(f).css(p)});J(i.element,ta?\"mouseout\":\"mouseleave\",function(){j!==3&&(k=[e,f,g][j],l=[m,p,q][j],i.attr(k).css(l))});i.setState=function(a){(i.state=j=a)?a===2?i.attr(g).css(q):a===3&&i.attr(h).css(n):i.attr(e).css(m)};return i.on(\"click\",function(){j!==3&&d.call(i)}).attr(e).css(r({cursor:\"default\"},m))},crispLine:function(a,b){a[1]===a[4]&&(a[1]=a[4]=t(a[1])-b%\n2/2);a[2]===a[5]&&(a[2]=a[5]=t(a[2])+b%2/2);return a},path:function(a){var b={fill:S};Ia(a)?b.d=a:T(a)&&r(b,a);return this.createElement(\"path\").attr(b)},circle:function(a,b,c){a=T(a)?a:{x:a,y:b,r:c};return this.createElement(\"circle\").attr(a)},arc:function(a,b,c,d,e,f){if(T(a))b=a.y,c=a.r,d=a.innerR,e=a.start,f=a.end,a=a.x;a=this.symbol(\"arc\",a||0,b||0,c||0,c||0,{innerR:d||0,start:e||0,end:f||0});a.r=c;return a},rect:function(a,b,c,d,e,f){e=T(a)?a.r:e;e=this.createElement(\"rect\").attr({rx:e,ry:e,\nfill:S});return e.attr(T(a)?a:e.crisp(f,a,b,s(c,0),s(d,0)))},setSize:function(a,b,c){var d=this.alignedObjects,e=d.length;this.width=a;this.height=b;for(this.boxWrapper[o(c,!0)?\"animate\":\"attr\"]({width:a,height:b});e--;)d[e].align()},g:function(a){var b=this.createElement(\"g\");return u(a)?b.attr({\"class\":\"highcharts-\"+a}):b},image:function(a,b,c,d,e){var f={preserveAspectRatio:S};arguments.length>1&&r(f,{x:b,y:c,width:d,height:e});f=this.createElement(\"image\").attr(f);f.element.setAttributeNS?f.element.setAttributeNS(\"http://www.w3.org/1999/xlink\",\n\"href\",a):f.element.setAttribute(\"hc-svg-href\",a);return f},symbol:function(a,b,c,d,e,f){var g,h=this.symbols[a],h=h&&h(t(b),t(c),d,e,f),i=/^url\\((.*?)\\)$/,j,k;if(h)g=this.path(h),r(g,{symbolName:a,x:b,y:c,width:d,height:e}),f&&r(g,f);else if(i.test(a))k=function(a,b){a.element&&(a.attr({width:b[0],height:b[1]}),a.alignByTranslate||a.translate(t((d-b[0])/2),t((e-b[1])/2)))},j=a.match(i)[1],a=Pb[j],g=this.image(j).attr({x:b,y:c}),g.isImg=!0,a?k(g,a):(g.attr({width:0,height:0}),U(\"img\",{onload:function(){k(g,\nPb[j]=[this.width,this.height])},src:j}));return g},symbols:{circle:function(a,b,c,d){var e=0.166*c;return[\"M\",a+c/2,b,\"C\",a+c+e,b,a+c+e,b+d,a+c/2,b+d,\"C\",a-e,b+d,a-e,b,a+c/2,b,\"Z\"]},square:function(a,b,c,d){return[\"M\",a,b,\"L\",a+c,b,a+c,b+d,a,b+d,\"Z\"]},triangle:function(a,b,c,d){return[\"M\",a+c/2,b,\"L\",a+c,b+d,a,b+d,\"Z\"]},\"triangle-down\":function(a,b,c,d){return[\"M\",a,b,\"L\",a+c,b,a+c/2,b+d,\"Z\"]},diamond:function(a,b,c,d){return[\"M\",a+c/2,b,\"L\",a+c,b+d/2,a+c/2,b+d,a,b+d/2,\"Z\"]},arc:function(a,b,c,d,\ne){var f=e.start,c=e.r||c||d,g=e.end-0.001,d=e.innerR,h=e.open,i=V(f),j=ca(f),k=V(g),g=ca(g),e=e.end-f<ya?0:1;return[\"M\",a+c*i,b+c*j,\"A\",c,c,0,e,1,a+c*k,b+c*g,h?\"M\":\"L\",a+d*k,b+d*g,\"A\",d,d,0,e,0,a+d*i,b+d*j,h?\"\":\"Z\"]}},clipRect:function(a,b,c,d){var e=\"highcharts-\"+zb++,f=this.createElement(\"clipPath\").attr({id:e}).add(this.defs),a=this.rect(a,b,c,d,0).add(f);a.id=e;a.clipPath=f;return a},color:function(a,b,c){var d=this,e,f=/^rgba/,g,h,i,j,k,l,m,p=[];a&&a.linearGradient?g=\"linearGradient\":a&&a.radialGradient&&\n(g=\"radialGradient\");if(g){c=a[g];h=d.gradients;j=a.stops;b=b.radialReference;Ia(c)&&(a[g]=c={x1:c[0],y1:c[1],x2:c[2],y2:c[3],gradientUnits:\"userSpaceOnUse\"});g===\"radialGradient\"&&b&&!u(c.gradientUnits)&&(c=x(c,{cx:b[0]-b[2]/2+c.cx*b[2],cy:b[1]-b[2]/2+c.cy*b[2],r:c.r*b[2],gradientUnits:\"userSpaceOnUse\"}));for(m in c)m!==\"id\"&&p.push(m,c[m]);for(m in j)p.push(j[m]);p=p.join(\",\");h[p]?a=h[p].id:(c.id=a=\"highcharts-\"+zb++,h[p]=i=d.createElement(g).attr(c).add(d.defs),i.stops=[],n(j,function(a){f.test(a[1])?\n(e=ra(a[1]),k=e.get(\"rgb\"),l=e.get(\"a\")):(k=a[1],l=1);a=d.createElement(\"stop\").attr({offset:a[0],\"stop-color\":k,\"stop-opacity\":l}).add(i);i.stops.push(a)}));return\"url(\"+d.url+\"#\"+a+\")\"}else return f.test(a)?(e=ra(a),v(b,c+\"-opacity\",e.get(\"a\")),e.get(\"rgb\")):(b.removeAttribute(c+\"-opacity\"),a)},text:function(a,b,c,d){var e=M.chart.style,f=$||!Z&&this.forExport;if(d&&!this.forExport)return this.html(a,b,c);b=t(o(b,0));c=t(o(c,0));a=this.createElement(\"text\").attr({x:b,y:c,text:a}).css({fontFamily:e.fontFamily,\nfontSize:e.fontSize});f&&a.css({position:\"absolute\"});a.x=b;a.y=c;return a},html:function(a,b,c){var d=M.chart.style,e=this.createElement(\"span\"),f=e.attrSetters,g=e.element,h=e.renderer;f.text=function(a){a!==g.innerHTML&&delete this.bBox;g.innerHTML=a;return!1};f.x=f.y=f.align=function(a,b){b===\"align\"&&(b=\"textAlign\");e[b]=a;e.htmlUpdateTransform();return!1};e.attr({text:a,x:t(b),y:t(c)}).css({position:\"absolute\",whiteSpace:\"nowrap\",fontFamily:d.fontFamily,fontSize:d.fontSize});e.css=e.htmlCss;\nif(h.isSVG)e.add=function(a){var b,c=h.box.parentNode,d=[];if(a){if(b=a.div,!b){for(;a;)d.push(a),a=a.parentGroup;n(d.reverse(),function(a){var d;b=a.div=a.div||U(Ea,{className:v(a.element,\"class\")},{position:\"absolute\",left:(a.translateX||0)+\"px\",top:(a.translateY||0)+\"px\"},b||c);d=b.style;r(a.attrSetters,{translateX:function(a){d.left=a+\"px\"},translateY:function(a){d.top=a+\"px\"},visibility:function(a,b){d[b]=a}})})}}else b=c;b.appendChild(g);e.added=!0;e.alignOnAdd&&e.htmlUpdateTransform();return e};\nreturn e},fontMetrics:function(a){var a=C(a||11),a=a<24?a+4:t(a*1.2),b=t(a*0.8);return{h:a,b:b}},label:function(a,b,c,d,e,f,g,h,i){function j(){var a,b;a=o.element.style;L=(Oa===void 0||la===void 0||q.styles.textAlign)&&o.getBBox();q.width=(Oa||L.width||0)+2*da+kb;q.height=(la||L.height||0)+2*da;v=da+p.fontMetrics(a&&a.fontSize).b;if(C){if(!A)a=t(-s*da),b=h?-v:0,q.box=A=d?p.symbol(d,a,b,q.width,q.height):p.rect(a,b,q.width,q.height,0,lb[Rb]),A.add(q);A.isImg||A.attr(x({width:q.width,height:q.height},\nlb));lb=null}}function k(){var a=q.styles,a=a&&a.textAlign,b=kb+da*(1-s),c;c=h?0:v;if(u(Oa)&&(a===\"center\"||a===\"right\"))b+={center:0.5,right:1}[a]*(Oa-L.width);(b!==o.x||c!==o.y)&&o.attr({x:b,y:c});o.x=b;o.y=c}function l(a,b){A?A.attr(a,b):lb[a]=b}function m(){o.add(q);q.attr({text:a,x:b,y:c});A&&u(e)&&q.attr({anchorX:e,anchorY:f})}var p=this,q=p.g(i),o=p.text(\"\",0,0,g).attr({zIndex:1}),A,L,s=0,da=3,kb=0,Oa,la,E,H,B=0,lb={},v,g=q.attrSetters,C;J(q,\"add\",m);g.width=function(a){Oa=a;return!1};g.height=\nfunction(a){la=a;return!1};g.padding=function(a){u(a)&&a!==da&&(da=a,k());return!1};g.paddingLeft=function(a){u(a)&&a!==kb&&(kb=a,k());return!1};g.align=function(a){s={left:0,center:0.5,right:1}[a];return!1};g.text=function(a,b){o.attr(b,a);j();k();return!1};g[Rb]=function(a,b){C=!0;B=a%2/2;l(b,a);return!1};g.stroke=g.fill=g.r=function(a,b){b===\"fill\"&&(C=!0);l(b,a);return!1};g.anchorX=function(a,b){e=a;l(b,a+B-E);return!1};g.anchorY=function(a,b){f=a;l(b,a-H);return!1};g.x=function(a){q.x=a;a-=s*\n((Oa||L.width)+da);E=t(a);q.attr(\"translateX\",E);return!1};g.y=function(a){H=q.y=t(a);q.attr(\"translateY\",H);return!1};var y=q.css;return r(q,{css:function(a){if(a){var b={},a=x(a);n(\"fontSize,fontWeight,fontFamily,color,lineHeight,width,textDecoration,textShadow\".split(\",\"),function(c){a[c]!==w&&(b[c]=a[c],delete a[c])});o.css(b)}return y.call(q,a)},getBBox:function(){return{width:L.width+2*da,height:L.height+2*da,x:L.x-da,y:L.y-da}},shadow:function(a){A&&A.shadow(a);return q},destroy:function(){aa(q,\n\"add\",m);aa(q.element,\"mouseenter\");aa(q.element,\"mouseleave\");o&&(o=o.destroy());A&&(A=A.destroy());wa.prototype.destroy.call(q);q=p=j=k=l=m=null}})}};Va=Ha;var F;if(!Z&&!$){Highcharts.VMLElement=F={init:function(a,b){var c=[\"<\",b,' filled=\"f\" stroked=\"f\"'],d=[\"position: \",\"absolute\",\";\"],e=b===Ea;(b===\"shape\"||e)&&d.push(\"left:0;top:0;width:1px;height:1px;\");d.push(\"visibility: \",e?\"hidden\":\"visible\");c.push(' style=\"',d.join(\"\"),'\"/>');if(b)c=e||b===\"span\"||b===\"img\"?c.join(\"\"):a.prepVML(c),this.element=\nU(c);this.renderer=a;this.attrSetters={}},add:function(a){var b=this.renderer,c=this.element,d=b.box,d=a?a.element||a:d;a&&a.inverted&&b.invertChild(c,d);d.appendChild(c);this.added=!0;this.alignOnAdd&&!this.deferUpdateTransform&&this.updateTransform();z(this,\"add\");return this},updateTransform:wa.prototype.htmlUpdateTransform,setSpanRotation:function(a,b,c){K(this.element,{filter:a?[\"progid:DXImageTransform.Microsoft.Matrix(M11=\",c,\", M12=\",-b,\", M21=\",b,\", M22=\",c,\", sizingMethod='auto expand')\"].join(\"\"):\nS})},pathToVML:function(a){for(var b=a.length,c=[],d;b--;)if(sa(a[b]))c[b]=t(a[b]*10)-5;else if(a[b]===\"Z\")c[b]=\"x\";else if(c[b]=a[b],a.isArc&&(a[b]===\"wa\"||a[b]===\"at\"))d=a[b]===\"wa\"?1:-1,c[b+5]===c[b+7]&&(c[b+7]-=d),c[b+6]===c[b+8]&&(c[b+8]-=d);return c.join(\" \")||\"x\"},attr:function(a,b){var c,d,e,f=this.element||{},g=f.style,h=f.nodeName,i=this.renderer,j=this.symbolName,k,l=this.shadows,m,p=this.attrSetters,q=this;ea(a)&&u(b)&&(c=a,a={},a[c]=b);if(ea(a))c=a,q=c===\"strokeWidth\"||c===\"stroke-width\"?\nthis.strokeweight:this[c];else for(c in a)if(d=a[c],m=!1,e=p[c]&&p[c].call(this,d,c),e!==!1&&d!==null){e!==w&&(d=e);if(j&&/^(x|y|r|start|end|width|height|innerR|anchorX|anchorY)/.test(c))k||(this.symbolAttr(a),k=!0),m=!0;else if(c===\"d\"){d=d||[];this.d=d.join(\" \");f.path=d=this.pathToVML(d);if(l)for(e=l.length;e--;)l[e].path=l[e].cutOff?this.cutOffPath(d,l[e].cutOff):d;m=!0}else if(c===\"visibility\"){if(l)for(e=l.length;e--;)l[e].style[c]=d;h===\"DIV\"&&(d=d===\"hidden\"?\"-999em\":0,fb||(g[c]=d?\"visible\":\n\"hidden\"),c=\"top\");g[c]=d;m=!0}else if(c===\"zIndex\")d&&(g[c]=d),m=!0;else if(qa(c,[\"x\",\"y\",\"width\",\"height\"])!==-1)this[c]=d,c===\"x\"||c===\"y\"?c={x:\"left\",y:\"top\"}[c]:d=s(0,d),this.updateClipping?(this[c]=d,this.updateClipping()):g[c]=d,m=!0;else if(c===\"class\"&&h===\"DIV\")f.className=d;else if(c===\"stroke\")d=i.color(d,f,c),c=\"strokecolor\";else if(c===\"stroke-width\"||c===\"strokeWidth\")f.stroked=d?!0:!1,c=\"strokeweight\",this[c]=d,sa(d)&&(d+=\"px\");else if(c===\"dashstyle\")(f.getElementsByTagName(\"stroke\")[0]||\nU(i.prepVML([\"<stroke/>\"]),null,null,f))[c]=d||\"solid\",this.dashstyle=d,m=!0;else if(c===\"fill\")if(h===\"SPAN\")g.color=d;else{if(h!==\"IMG\")f.filled=d!==S?!0:!1,d=i.color(d,f,c,this),c=\"fillcolor\"}else if(c===\"opacity\")m=!0;else if(h===\"shape\"&&c===\"rotation\")this[c]=f.style[c]=d,f.style.left=-t(ca(d*Ua)+1)+\"px\",f.style.top=t(V(d*Ua))+\"px\";else if(c===\"translateX\"||c===\"translateY\"||c===\"rotation\")this[c]=d,this.updateTransform(),m=!0;else if(c===\"text\")this.bBox=null,f.innerHTML=d,m=!0;m||(fb?f[c]=\nd:v(f,c,d))}return q},clip:function(a){var b=this,c;a?(c=a.members,ga(c,b),c.push(b),b.destroyClip=function(){ga(c,b)},a=a.getCSS(b)):(b.destroyClip&&b.destroyClip(),a={clip:fb?\"inherit\":\"rect(auto)\"});return b.css(a)},css:wa.prototype.htmlCss,safeRemoveChild:function(a){a.parentNode&&Ta(a)},destroy:function(){this.destroyClip&&this.destroyClip();return wa.prototype.destroy.apply(this)},on:function(a,b){this.element[\"on\"+a]=function(){var a=O.event;a.target=a.srcElement;b(a)};return this},cutOffPath:function(a,\nb){var c,a=a.split(/[ ,]/);c=a.length;if(c===9||c===11)a[c-4]=a[c-2]=C(a[c-2])-10*b;return a.join(\" \")},shadow:function(a,b,c){var d=[],e,f=this.element,g=this.renderer,h,i=f.style,j,k=f.path,l,m,p,q;k&&typeof k.value!==\"string\"&&(k=\"x\");m=k;if(a){p=o(a.width,3);q=(a.opacity||0.15)/p;for(e=1;e<=3;e++){l=p*2+1-2*e;c&&(m=this.cutOffPath(k.value,l+0.5));j=['<shape isShadow=\"true\" strokeweight=\"',l,'\" filled=\"false\" path=\"',m,'\" coordsize=\"10 10\" style=\"',f.style.cssText,'\" />'];h=U(g.prepVML(j),null,\n{left:C(i.left)+o(a.offsetX,1),top:C(i.top)+o(a.offsetY,1)});if(c)h.cutOff=l+1;j=['<stroke color=\"',a.color||\"black\",'\" opacity=\"',q*e,'\"/>'];U(g.prepVML(j),null,null,h);b?b.element.appendChild(h):f.parentNode.insertBefore(h,f);d.push(h)}this.shadows=d}return this}};F=ha(wa,F);var ma={Element:F,isIE8:oa.indexOf(\"MSIE 8.0\")>-1,init:function(a,b,c){var d,e;this.alignedObjects=[];d=this.createElement(Ea);e=d.element;e.style.position=\"relative\";a.appendChild(d.element);this.isVML=!0;this.box=e;this.boxWrapper=\nd;this.setSize(b,c,!1);y.namespaces.hcv||(y.namespaces.add(\"hcv\",\"urn:schemas-microsoft-com:vml\"),(y.styleSheets.length?y.styleSheets[0]:y.createStyleSheet()).cssText+=\"hcv\\\\:fill, hcv\\\\:path, hcv\\\\:shape, hcv\\\\:stroke{ behavior:url(#default#VML); display: inline-block; } \")},isHidden:function(){return!this.box.offsetWidth},clipRect:function(a,b,c,d){var e=this.createElement(),f=T(a);return r(e,{members:[],left:(f?a.x:a)+1,top:(f?a.y:b)+1,width:(f?a.width:c)-1,height:(f?a.height:d)-1,getCSS:function(a){var b=\na.element,c=b.nodeName,a=a.inverted,d=this.top-(c===\"shape\"?b.offsetTop:0),e=this.left,b=e+this.width,f=d+this.height,d={clip:\"rect(\"+t(a?e:d)+\"px,\"+t(a?f:b)+\"px,\"+t(a?b:f)+\"px,\"+t(a?d:e)+\"px)\"};!a&&fb&&c===\"DIV\"&&r(d,{width:b+\"px\",height:f+\"px\"});return d},updateClipping:function(){n(e.members,function(a){a.css(e.getCSS(a))})}})},color:function(a,b,c,d){var e=this,f,g=/^rgba/,h,i,j=S;a&&a.linearGradient?i=\"gradient\":a&&a.radialGradient&&(i=\"pattern\");if(i){var k,l,m=a.linearGradient||a.radialGradient,\np,q,o,A,L,s=\"\",a=a.stops,u,t=[],w=function(){h=['<fill colors=\"'+t.join(\",\")+'\" opacity=\"',o,'\" o:opacity2=\"',q,'\" type=\"',i,'\" ',s,'focus=\"100%\" method=\"any\" />'];U(e.prepVML(h),null,null,b)};p=a[0];u=a[a.length-1];p[0]>0&&a.unshift([0,p[1]]);u[0]<1&&a.push([1,u[1]]);n(a,function(a,b){g.test(a[1])?(f=ra(a[1]),k=f.get(\"rgb\"),l=f.get(\"a\")):(k=a[1],l=1);t.push(a[0]*100+\"% \"+k);b?(o=l,A=k):(q=l,L=k)});if(c===\"fill\")if(i===\"gradient\")c=m.x1||m[0]||0,a=m.y1||m[1]||0,p=m.x2||m[2]||0,m=m.y2||m[3]||0,s='angle=\"'+\n(90-R.atan((m-a)/(p-c))*180/ya)+'\"',w();else{var j=m.r,r=j*2,E=j*2,H=m.cx,B=m.cy,x=b.radialReference,v,j=function(){x&&(v=d.getBBox(),H+=(x[0]-v.x)/v.width-0.5,B+=(x[1]-v.y)/v.height-0.5,r*=x[2]/v.width,E*=x[2]/v.height);s='src=\"'+M.global.VMLRadialGradientURL+'\" size=\"'+r+\",\"+E+'\" origin=\"0.5,0.5\" position=\"'+H+\",\"+B+'\" color2=\"'+L+'\" ';w()};d.added?j():J(d,\"add\",j);j=A}else j=k}else if(g.test(a)&&b.tagName!==\"IMG\")f=ra(a),h=[\"<\",c,' opacity=\"',f.get(\"a\"),'\"/>'],U(this.prepVML(h),null,null,b),j=\nf.get(\"rgb\");else{j=b.getElementsByTagName(c);if(j.length)j[0].opacity=1,j[0].type=\"solid\";j=a}return j},prepVML:function(a){var b=this.isIE8,a=a.join(\"\");b?(a=a.replace(\"/>\",' xmlns=\"urn:schemas-microsoft-com:vml\" />'),a=a.indexOf('style=\"')===-1?a.replace(\"/>\",' style=\"display:inline-block;behavior:url(#default#VML);\" />'):a.replace('style=\"','style=\"display:inline-block;behavior:url(#default#VML);')):a=a.replace(\"<\",\"<hcv:\");return a},text:Ha.prototype.html,path:function(a){var b={coordsize:\"10 10\"};\nIa(a)?b.d=a:T(a)&&r(b,a);return this.createElement(\"shape\").attr(b)},circle:function(a,b,c){var d=this.symbol(\"circle\");if(T(a))c=a.r,b=a.y,a=a.x;d.isCircle=!0;d.r=c;return d.attr({x:a,y:b})},g:function(a){var b;a&&(b={className:\"highcharts-\"+a,\"class\":\"highcharts-\"+a});return this.createElement(Ea).attr(b)},image:function(a,b,c,d,e){var f=this.createElement(\"img\").attr({src:a});arguments.length>1&&f.attr({x:b,y:c,width:d,height:e});return f},rect:function(a,b,c,d,e,f){var g=this.symbol(\"rect\");g.r=\nT(a)?a.r:e;return g.attr(T(a)?a:g.crisp(f,a,b,s(c,0),s(d,0)))},invertChild:function(a,b){var c=b.style;K(a,{flip:\"x\",left:C(c.width)-1,top:C(c.height)-1,rotation:-90})},symbols:{arc:function(a,b,c,d,e){var f=e.start,g=e.end,h=e.r||c||d,c=e.innerR,d=V(f),i=ca(f),j=V(g),k=ca(g);if(g-f===0)return[\"x\"];f=[\"wa\",a-h,b-h,a+h,b+h,a+h*d,b+h*i,a+h*j,b+h*k];e.open&&!c&&f.push(\"e\",\"M\",a,b);f.push(\"at\",a-c,b-c,a+c,b+c,a+c*j,b+c*k,a+c*d,b+c*i,\"x\",\"e\");f.isArc=!0;return f},circle:function(a,b,c,d,e){e&&(c=d=2*e.r);\ne&&e.isCircle&&(a-=c/2,b-=d/2);return[\"wa\",a,b,a+c,b+d,a+c,b+d/2,a+c,b+d/2,\"e\"]},rect:function(a,b,c,d,e){var f=a+c,g=b+d,h;!u(e)||!e.r?f=Ha.prototype.symbols.square.apply(0,arguments):(h=I(e.r,c,d),f=[\"M\",a+h,b,\"L\",f-h,b,\"wa\",f-2*h,b,f,b+2*h,f-h,b,f,b+h,\"L\",f,g-h,\"wa\",f-2*h,g-2*h,f,g,f,g-h,f-h,g,\"L\",a+h,g,\"wa\",a,g-2*h,a+2*h,g,a+h,g,a,g-h,\"L\",a,b+h,\"wa\",a,b,a+2*h,b+2*h,a,b+h,a+h,b,\"x\",\"e\"]);return f}}};Highcharts.VMLRenderer=F=function(){this.init.apply(this,arguments)};F.prototype=x(Ha.prototype,\nma);Va=F}var Tb;if($)Highcharts.CanVGRenderer=F=function(){za=\"http://www.w3.org/1999/xhtml\"},F.prototype.symbols={},Tb=function(){function a(){var a=b.length,d;for(d=0;d<a;d++)b[d]();b=[]}var b=[];return{push:function(c,d){b.length===0&&Vb(d,a);b.push(c)}}}(),Va=F;Ma.prototype={addLabel:function(){var a=this.axis,b=a.options,c=a.chart,d=a.horiz,e=a.categories,f=a.series[0]&&a.series[0].names,g=this.pos,h=b.labels,i=a.tickPositions,d=d&&e&&!h.step&&!h.staggerLines&&!h.rotation&&c.plotWidth/i.length||\n!d&&(c.margin[3]||c.chartWidth*0.33),j=g===i[0],k=g===i[i.length-1],l,f=e?o(e[g],f&&f[g],g):g,e=this.label,m=i.info;a.isDatetimeAxis&&m&&(l=b.dateTimeLabelFormats[m.higherRanks[g]||m.unitName]);this.isFirst=j;this.isLast=k;b=a.labelFormatter.call({axis:a,chart:c,isFirst:j,isLast:k,dateTimeLabelFormat:l,value:a.isLog?ia(fa(f)):f});g=d&&{width:s(1,t(d-2*(h.padding||10)))+\"px\"};g=r(g,h.style);if(u(e))e&&e.attr({text:b}).css(g);else{l={align:a.labelAlign};if(sa(h.rotation))l.rotation=h.rotation;if(d&&\nh.ellipsis)l._clipHeight=a.len/i.length;this.label=u(b)&&h.enabled?c.renderer.text(b,0,0,h.useHTML).attr(l).css(g).add(a.labelGroup):null}},getLabelSize:function(){var a=this.label,b=this.axis;return a?(this.labelBBox=a.getBBox())[b.horiz?\"height\":\"width\"]:0},getLabelSides:function(){var a=this.axis,b=this.labelBBox.width,a=b*{left:0,center:0.5,right:1}[a.labelAlign]-a.options.labels.x;return[-a,b-a]},handleOverflow:function(a,b){var c=!0,d=this.axis,e=d.chart,f=this.isFirst,g=this.isLast,h=b.x,i=\nd.reversed,j=d.tickPositions;if(f||g){var k=this.getLabelSides(),l=k[0],k=k[1],e=e.plotLeft,m=e+d.len,j=(d=d.ticks[j[a+(f?1:-1)]])&&d.label.xy&&d.label.xy.x+d.getLabelSides()[f?0:1];f&&!i||g&&i?h+l<e&&(h=e-l,d&&h+k>j&&(c=!1)):h+k>m&&(h=m-k,d&&h+l<j&&(c=!1));b.x=h}return c},getPosition:function(a,b,c,d){var e=this.axis,f=e.chart,g=d&&f.oldChartHeight||f.chartHeight;return{x:a?e.translate(b+c,null,null,d)+e.transB:e.left+e.offset+(e.opposite?(d&&f.oldChartWidth||f.chartWidth)-e.right-e.left:0),y:a?\ng-e.bottom+e.offset-(e.opposite?e.height:0):g-e.translate(b+c,null,null,d)-e.transB}},getLabelPosition:function(a,b,c,d,e,f,g,h){var i=this.axis,j=i.transA,k=i.reversed,l=i.staggerLines,m=i.chart.renderer.fontMetrics(e.style.fontSize).b,p=e.rotation,a=a+e.x-(f&&d?f*j*(k?-1:1):0),b=b+e.y-(f&&!d?f*j*(k?1:-1):0);p&&i.side===2&&(b-=m-m*V(p*Ua));!u(e.y)&&!p&&(b+=m-c.getBBox().height/2);l&&(b+=g/(h||1)%l*(i.labelOffset/l));return{x:a,y:b}},getMarkPath:function(a,b,c,d,e,f){return f.crispLine([\"M\",a,b,\"L\",\na+(e?0:-c),b+(e?c:0)],d)},render:function(a,b,c){var d=this.axis,e=d.options,f=d.chart.renderer,g=d.horiz,h=this.type,i=this.label,j=this.pos,k=e.labels,l=this.gridLine,m=h?h+\"Grid\":\"grid\",p=h?h+\"Tick\":\"tick\",q=e[m+\"LineWidth\"],n=e[m+\"LineColor\"],A=e[m+\"LineDashStyle\"],s=e[p+\"Length\"],m=e[p+\"Width\"]||0,u=e[p+\"Color\"],t=e[p+\"Position\"],p=this.mark,r=k.step,v=!0,x=d.tickmarkOffset,E=this.getPosition(g,j,x,b),H=E.x,E=E.y,B=g&&H===d.pos+d.len||!g&&E===d.pos?-1:1,C=d.staggerLines;this.isActive=!0;if(q){j=\nd.getPlotLinePath(j+x,q*B,b,!0);if(l===w){l={stroke:n,\"stroke-width\":q};if(A)l.dashstyle=A;if(!h)l.zIndex=1;if(b)l.opacity=0;this.gridLine=l=q?f.path(j).attr(l).add(d.gridGroup):null}if(!b&&l&&j)l[this.isNew?\"attr\":\"animate\"]({d:j,opacity:c})}if(m&&s)t===\"inside\"&&(s=-s),d.opposite&&(s=-s),b=this.getMarkPath(H,E,s,m*B,g,f),p?p.animate({d:b,opacity:c}):this.mark=f.path(b).attr({stroke:u,\"stroke-width\":m,opacity:c}).add(d.axisGroup);if(i&&!isNaN(H))i.xy=E=this.getLabelPosition(H,E,i,g,k,x,a,r),this.isFirst&&\n!this.isLast&&!o(e.showFirstLabel,1)||this.isLast&&!this.isFirst&&!o(e.showLastLabel,1)?v=!1:!C&&g&&k.overflow===\"justify\"&&!this.handleOverflow(a,E)&&(v=!1),r&&a%r&&(v=!1),v&&!isNaN(E.y)?(E.opacity=c,i[this.isNew?\"attr\":\"animate\"](E),this.isNew=!1):i.attr(\"y\",-9999)},destroy:function(){Ka(this,this.axis)}};vb.prototype={render:function(){var a=this,b=a.axis,c=b.horiz,d=(b.pointRange||0)/2,e=a.options,f=e.label,g=a.label,h=e.width,i=e.to,j=e.from,k=u(j)&&u(i),l=e.value,m=e.dashStyle,p=a.svgElem,q=\n[],n,A=e.color,L=e.zIndex,t=e.events,w=b.chart.renderer;b.isLog&&(j=na(j),i=na(i),l=na(l));if(h){if(q=b.getPlotLinePath(l,h),d={stroke:A,\"stroke-width\":h},m)d.dashstyle=m}else if(k){if(j=s(j,b.min-d),i=I(i,b.max+d),q=b.getPlotBandPath(j,i,e),d={fill:A},e.borderWidth)d.stroke=e.borderColor,d[\"stroke-width\"]=e.borderWidth}else return;if(u(L))d.zIndex=L;if(p)q?p.animate({d:q},null,p.onGetPath):(p.hide(),p.onGetPath=function(){p.show()});else if(q&&q.length&&(a.svgElem=p=w.path(q).attr(d).add(),t))for(n in e=\nfunction(b){p.on(b,function(c){t[b].apply(a,[c])})},t)e(n);if(f&&u(f.text)&&q&&q.length&&b.width>0&&b.height>0){f=x({align:c&&k&&\"center\",x:c?!k&&4:10,verticalAlign:!c&&k&&\"middle\",y:c?k?16:10:k?6:-4,rotation:c&&!k&&90},f);if(!g)a.label=g=w.text(f.text,0,0,f.useHTML).attr({align:f.textAlign||f.align,rotation:f.rotation,zIndex:L}).css(f.style).add();b=[q[1],q[4],o(q[6],q[1])];q=[q[2],q[5],o(q[7],q[2])];c=Ja(b);k=Ja(q);g.align(f,!1,{x:c,y:k,width:va(b)-c,height:va(q)-k});g.show()}else g&&g.hide();return a},\ndestroy:function(){ga(this.axis.plotLinesAndBands,this);delete this.axis;Ka(this)}};Mb.prototype={destroy:function(){Ka(this,this.axis)},render:function(a){var b=this.options,c=b.format,c=c?Ca(c,this):b.formatter.call(this);this.label?this.label.attr({text:c,visibility:\"hidden\"}):this.label=this.axis.chart.renderer.text(c,0,0,b.useHTML).css(b.style).attr({align:this.textAlign,rotation:b.rotation,visibility:\"hidden\"}).add(a)},setOffset:function(a,b){var c=this.axis,d=c.chart,e=d.inverted,f=this.isNegative,\ng=c.translate(this.percent?100:this.total,0,0,0,1),c=c.translate(0),c=N(g-c),h=d.xAxis[0].translate(this.x)+a,i=d.plotHeight,f={x:e?f?g:g-c:h,y:e?i-h-b:f?i-g-c:i-g,width:e?c:b,height:e?b:c};if(e=this.label)e.align(this.alignOptions,null,f),f=e.alignAttr,e.attr({visibility:this.options.crop===!1||d.isInsidePlot(f.x,f.y)?Z?\"inherit\":\"visible\":\"hidden\"})}};db.prototype={defaultOptions:{dateTimeLabelFormats:{millisecond:\"%H:%M:%S.%L\",second:\"%H:%M:%S\",minute:\"%H:%M\",hour:\"%H:%M\",day:\"%e. %b\",week:\"%e. %b\",\nmonth:\"%b '%y\",year:\"%Y\"},endOnTick:!1,gridLineColor:\"#C0C0C0\",labels:G,lineColor:\"#C0D0E0\",lineWidth:1,minPadding:0.01,maxPadding:0.01,minorGridLineColor:\"#E0E0E0\",minorGridLineWidth:1,minorTickColor:\"#A0A0A0\",minorTickLength:2,minorTickPosition:\"outside\",startOfWeek:1,startOnTick:!1,tickColor:\"#C0D0E0\",tickLength:5,tickmarkPlacement:\"between\",tickPixelInterval:100,tickPosition:\"outside\",tickWidth:1,title:{align:\"middle\",style:{color:\"#4d759e\",fontWeight:\"bold\"}},type:\"linear\"},defaultYAxisOptions:{endOnTick:!0,\ngridLineWidth:1,tickPixelInterval:72,showLastLabel:!0,labels:{x:-8,y:3},lineWidth:0,maxPadding:0.05,minPadding:0.05,startOnTick:!0,tickWidth:0,title:{rotation:270,text:\"Values\"},stackLabels:{enabled:!1,formatter:function(){return Aa(this.total,-1)},style:G.style}},defaultLeftAxisOptions:{labels:{x:-8,y:null},title:{rotation:270}},defaultRightAxisOptions:{labels:{x:8,y:null},title:{rotation:90}},defaultBottomAxisOptions:{labels:{x:0,y:14},title:{rotation:0}},defaultTopAxisOptions:{labels:{x:0,y:-5},\ntitle:{rotation:0}},init:function(a,b){var c=b.isX;this.horiz=a.inverted?!c:c;this.xOrY=(this.isXAxis=c)?\"x\":\"y\";this.opposite=b.opposite;this.side=this.horiz?this.opposite?0:2:this.opposite?1:3;this.setOptions(b);var d=this.options,e=d.type;this.labelFormatter=d.labels.formatter||this.defaultLabelFormatter;this.userOptions=b;this.minPixelPadding=0;this.chart=a;this.reversed=d.reversed;this.zoomEnabled=d.zoomEnabled!==!1;this.categories=d.categories||e===\"category\";this.isLog=e===\"logarithmic\";this.isDatetimeAxis=\ne===\"datetime\";this.isLinked=u(d.linkedTo);this.tickmarkOffset=this.categories&&d.tickmarkPlacement===\"between\"?0.5:0;this.ticks={};this.minorTicks={};this.plotLinesAndBands=[];this.alternateBands={};this.len=0;this.minRange=this.userMinRange=d.minRange||d.maxZoom;this.range=d.range;this.offset=d.offset||0;this.stacks={};this.oldStacks={};this.stackExtremes={};this.min=this.max=null;var f,d=this.options.events;qa(this,a.axes)===-1&&(a.axes.push(this),a[c?\"xAxis\":\"yAxis\"].push(this));this.series=this.series||\n[];if(a.inverted&&c&&this.reversed===w)this.reversed=!0;this.removePlotLine=this.removePlotBand=this.removePlotBandOrLine;for(f in d)J(this,f,d[f]);if(this.isLog)this.val2lin=na,this.lin2val=fa},setOptions:function(a){this.options=x(this.defaultOptions,this.isXAxis?{}:this.defaultYAxisOptions,[this.defaultTopAxisOptions,this.defaultRightAxisOptions,this.defaultBottomAxisOptions,this.defaultLeftAxisOptions][this.side],x(M[this.isXAxis?\"xAxis\":\"yAxis\"],a))},update:function(a,b){var c=this.chart,a=c.options[this.xOrY+\n\"Axis\"][this.options.index]=x(this.userOptions,a);this.destroy(!0);this._addedPlotLB=this.userMin=this.userMax=w;this.init(c,r(a,{events:w}));c.isDirtyBox=!0;o(b,!0)&&c.redraw()},remove:function(a){var b=this.chart,c=this.xOrY+\"Axis\";n(this.series,function(a){a.remove(!1)});ga(b.axes,this);ga(b[c],this);b.options[c].splice(this.options.index,1);n(b[c],function(a,b){a.options.index=b});this.destroy();b.isDirtyBox=!0;o(a,!0)&&b.redraw()},defaultLabelFormatter:function(){var a=this.axis,b=this.value,\nc=a.categories,d=this.dateTimeLabelFormat,e=M.lang.numericSymbols,f=e&&e.length,g,h=a.options.labels.format,a=a.isLog?b:a.tickInterval;if(h)g=Ca(h,this);else if(c)g=b;else if(d)g=Xa(d,b);else if(f&&a>=1E3)for(;f--&&g===w;)c=Math.pow(1E3,f+1),a>=c&&e[f]!==null&&(g=Aa(b/c,-1)+e[f]);g===w&&(g=b>=1E3?Aa(b,0):Aa(b,-1));return g},getSeriesExtremes:function(){var a=this,b=a.chart;a.hasVisibleSeries=!1;a.dataMin=a.dataMax=null;a.stackExtremes={};a.buildStacks();n(a.series,function(c){if(c.visible||!b.options.chart.ignoreHiddenSeries){var d;\nd=c.options.threshold;var e;a.hasVisibleSeries=!0;a.isLog&&d<=0&&(d=null);if(a.isXAxis){if(d=c.xData,d.length)a.dataMin=I(o(a.dataMin,d[0]),Ja(d)),a.dataMax=s(o(a.dataMax,d[0]),va(d))}else{c.getExtremes();e=c.dataMax;c=c.dataMin;if(u(c)&&u(e))a.dataMin=I(o(a.dataMin,c),c),a.dataMax=s(o(a.dataMax,e),e);if(u(d))if(a.dataMin>=d)a.dataMin=d,a.ignoreMinPadding=!0;else if(a.dataMax<d)a.dataMax=d,a.ignoreMaxPadding=!0}}})},translate:function(a,b,c,d,e,f){var g=this.len,h=1,i=0,j=d?this.oldTransA:this.transA,\nd=d?this.oldMin:this.min,k=this.minPixelPadding,e=(this.options.ordinal||this.isLog&&e)&&this.lin2val;if(!j)j=this.transA;c&&(h*=-1,i=g);this.reversed&&(h*=-1,i-=h*g);b?(a=a*h+i,a-=k,a=a/j+d,e&&(a=this.lin2val(a))):(e&&(a=this.val2lin(a)),f===\"between\"&&(f=0.5),a=h*(a-d)*j+i+h*k+(sa(f)?j*f*this.pointRange: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,\nb,c,d){var e=this.chart,f=this.left,g=this.top,h,i,j,a=this.translate(a,null,null,c),k=c&&e.oldChartHeight||e.chartHeight,l=c&&e.oldChartWidth||e.chartWidth,m;h=this.transB;c=i=t(a+h);h=j=t(k-a-h);if(isNaN(a))m=!0;else if(this.horiz){if(h=g,j=k-this.bottom,c<f||c>f+this.width)m=!0}else if(c=f,i=l-this.right,h<g||h>g+this.height)m=!0;return m&&!d?null:e.renderer.crispLine([\"M\",c,h,\"L\",i,j],b||0)},getPlotBandPath:function(a,b){var c=this.getPlotLinePath(b),d=this.getPlotLinePath(a);d&&c?d.push(c[4],\nc[5],c[1],c[2]):d=null;return d},getLinearTickPositions:function(a,b,c){for(var d,b=ia(P(b/a)*a),c=ia(xa(c/a)*a),e=[];b<=c;){e.push(b);b=ia(b+a);if(b===d)break;d=b}return e},getLogTickPositions:function(a,b,c,d){var e=this.options,f=this.len,g=[];if(!d)this._minorAutoInterval=null;if(a>=0.5)a=t(a),g=this.getLinearTickPositions(a,b,c);else if(a>=0.08)for(var f=P(b),h,i,j,k,l,e=a>0.3?[1,2,4]:a>0.15?[1,2,4,6,8]:[1,2,3,4,5,6,7,8,9];f<c+1&&!l;f++){i=e.length;for(h=0;h<i&&!l;h++)j=na(fa(f)*e[h]),j>b&&(!d||\nk<=c)&&g.push(k),k>c&&(l=!0),k=j}else if(b=fa(b),c=fa(c),a=e[d?\"minorTickInterval\":\"tickInterval\"],a=o(a===\"auto\"?null:a,this._minorAutoInterval,(c-b)*(e.tickPixelInterval/(d?5:1))/((d?f/this.tickPositions.length:f)||1)),a=ob(a,null,nb(a)),g=Na(this.getLinearTickPositions(a,b,c),na),!d)this._minorAutoInterval=a/5;if(!d)this.tickInterval=a;return g},getMinorTickPositions:function(){var a=this.options,b=this.tickPositions,c=this.minorTickInterval,d=[],e;if(this.isLog){e=b.length;for(a=1;a<e;a++)d=d.concat(this.getLogTickPositions(c,\nb[a-1],b[a],!0))}else if(this.isDatetimeAxis&&a.minorTickInterval===\"auto\")d=d.concat(Eb(Cb(c),this.min,this.max,a.startOfWeek)),d[0]<this.min&&d.shift();else for(b=this.min+(b[0]-this.min)%c;b<=this.max;b+=c)d.push(b);return d},adjustForMinRange:function(){var a=this.options,b=this.min,c=this.max,d,e=this.dataMax-this.dataMin>=this.minRange,f,g,h,i,j;if(this.isXAxis&&this.minRange===w&&!this.isLog)u(a.min)||u(a.max)?this.minRange=null:(n(this.series,function(a){i=a.xData;for(g=j=a.xIncrement?1:i.length-\n1;g>0;g--)if(h=i[g]-i[g-1],f===w||h<f)f=h}),this.minRange=I(f*5,this.dataMax-this.dataMin));if(c-b<this.minRange){var k=this.minRange;d=(k-c+b)/2;d=[b-d,o(a.min,b-d)];if(e)d[2]=this.dataMin;b=va(d);c=[b+k,o(a.max,b+k)];if(e)c[2]=this.dataMax;c=Ja(c);c-b<k&&(d[0]=c-k,d[1]=o(a.min,c-k),b=va(d))}this.min=b;this.max=c},setAxisTranslation:function(a){var b=this.max-this.min,c=0,d,e=0,f=0,g=this.linkedParent,h=this.transA;if(this.isXAxis)g?(e=g.minPointOffset,f=g.pointRangePadding):n(this.series,function(a){var g=\na.pointRange,h=a.options.pointPlacement,l=a.closestPointRange;g>b&&(g=0);c=s(c,g);e=s(e,ea(h)?0:g/2);f=s(f,h===\"on\"?0:g);!a.noSharedTooltip&&u(l)&&(d=u(d)?I(d,l):l)}),g=this.ordinalSlope&&d?this.ordinalSlope/d:1,this.minPointOffset=e*=g,this.pointRangePadding=f*=g,this.pointRange=I(c,b),this.closestPointRange=d;if(a)this.oldTransA=h;this.translationSlope=this.transA=h=this.len/(b+f||1);this.transB=this.horiz?this.left:this.bottom;this.minPixelPadding=h*e},setTickPositions:function(a){var b=this,c=\nb.chart,d=b.options,e=b.isLog,f=b.isDatetimeAxis,g=b.isXAxis,h=b.isLinked,i=b.options.tickPositioner,j=d.maxPadding,k=d.minPadding,l=d.tickInterval,m=d.minTickInterval,p=d.tickPixelInterval,q,ba=b.categories;h?(b.linkedParent=c[g?\"xAxis\":\"yAxis\"][d.linkedTo],c=b.linkedParent.getExtremes(),b.min=o(c.min,c.dataMin),b.max=o(c.max,c.dataMax),d.type!==b.linkedParent.options.type&&ka(11,1)):(b.min=o(b.userMin,d.min,b.dataMin),b.max=o(b.userMax,d.max,b.dataMax));if(e)!a&&I(b.min,o(b.dataMin,b.min))<=0&&\nka(10,1),b.min=ia(na(b.min)),b.max=ia(na(b.max));if(b.range&&(b.userMin=b.min=s(b.min,b.max-b.range),b.userMax=b.max,a))b.range=null;b.beforePadding&&b.beforePadding();b.adjustForMinRange();if(!ba&&!b.usePercentage&&!h&&u(b.min)&&u(b.max)&&(c=b.max-b.min)){if(!u(d.min)&&!u(b.userMin)&&k&&(b.dataMin<0||!b.ignoreMinPadding))b.min-=c*k;if(!u(d.max)&&!u(b.userMax)&&j&&(b.dataMax>0||!b.ignoreMaxPadding))b.max+=c*j}b.min===b.max||b.min===void 0||b.max===void 0?b.tickInterval=1:h&&!l&&p===b.linkedParent.options.tickPixelInterval?\nb.tickInterval=b.linkedParent.tickInterval:(b.tickInterval=o(l,ba?1:(b.max-b.min)*p/s(b.len,p)),!u(l)&&b.len<p&&!this.isRadial&&(q=!0,b.tickInterval/=4));g&&!a&&n(b.series,function(a){a.processData(b.min!==b.oldMin||b.max!==b.oldMax)});b.setAxisTranslation(!0);b.beforeSetTickPositions&&b.beforeSetTickPositions();if(b.postProcessTickInterval)b.tickInterval=b.postProcessTickInterval(b.tickInterval);if(b.pointRange)b.tickInterval=s(b.pointRange,b.tickInterval);if(!l&&b.tickInterval<m)b.tickInterval=\nm;if(!f&&!e&&!l)b.tickInterval=ob(b.tickInterval,null,nb(b.tickInterval),d);b.minorTickInterval=d.minorTickInterval===\"auto\"&&b.tickInterval?b.tickInterval/5:d.minorTickInterval;b.tickPositions=a=d.tickPositions?[].concat(d.tickPositions):i&&i.apply(b,[b.min,b.max]);if(!a)!b.ordinalPositions&&(b.max-b.min)/b.tickInterval>s(2*b.len,200)&&ka(19,!0),a=f?(b.getNonLinearTimeTicks||Eb)(Cb(b.tickInterval,d.units),b.min,b.max,d.startOfWeek,b.ordinalPositions,b.closestPointRange,!0):e?b.getLogTickPositions(b.tickInterval,\nb.min,b.max):b.getLinearTickPositions(b.tickInterval,b.min,b.max),q&&a.splice(1,a.length-2),b.tickPositions=a;if(!h)e=a[0],f=a[a.length-1],h=b.minPointOffset||0,d.startOnTick?b.min=e:b.min-h>e&&a.shift(),d.endOnTick?b.max=f:b.max+h<f&&a.pop(),a.length===1&&(b.min-=0.001,b.max+=0.001)},setMaxTicks:function(){var a=this.chart,b=a.maxTicks||{},c=this.tickPositions,d=this._maxTicksKey=[this.xOrY,this.pos,this.len].join(\"-\");if(!this.isLinked&&!this.isDatetimeAxis&&c&&c.length>(b[d]||0)&&this.options.alignTicks!==\n!1)b[d]=c.length;a.maxTicks=b},adjustTickAmount:function(){var a=this._maxTicksKey,b=this.tickPositions,c=this.chart.maxTicks;if(c&&c[a]&&!this.isDatetimeAxis&&!this.categories&&!this.isLinked&&this.options.alignTicks!==!1){var d=this.tickAmount,e=b.length;this.tickAmount=a=c[a];if(e<a){for(;b.length<a;)b.push(ia(b[b.length-1]+this.tickInterval));this.transA*=(e-1)/(a-1);this.max=b[b.length-1]}if(u(d)&&a!==d)this.isDirty=!0}},setScale:function(){var a=this.stacks,b,c,d,e;this.oldMin=this.min;this.oldMax=\nthis.max;this.oldAxisLength=this.len;this.setAxisSize();e=this.len!==this.oldAxisLength;n(this.series,function(a){if(a.isDirtyData||a.isDirty||a.xAxis.isDirty)d=!0});if(e||d||this.isLinked||this.forceRedraw||this.userMin!==this.oldUserMin||this.userMax!==this.oldUserMax){if(!this.isXAxis)for(b in a)delete a[b];this.forceRedraw=!1;this.getSeriesExtremes();this.setTickPositions();this.oldUserMin=this.userMin;this.oldUserMax=this.userMax;if(!this.isDirty)this.isDirty=e||this.min!==this.oldMin||this.max!==\nthis.oldMax}else if(!this.isXAxis){if(this.oldStacks)a=this.stacks=this.oldStacks;for(b in a)for(c in a[b])a[b][c].cum=a[b][c].total}this.setMaxTicks()},setExtremes:function(a,b,c,d,e){var f=this,g=f.chart,c=o(c,!0),e=r(e,{min:a,max:b});z(f,\"setExtremes\",e,function(){f.userMin=a;f.userMax=b;f.eventArgs=e;f.isDirtyExtremes=!0;c&&g.redraw(d)})},zoom:function(a,b){this.allowZoomOutside||(u(this.dataMin)&&a<=this.dataMin&&(a=w),u(this.dataMax)&&b>=this.dataMax&&(b=w));this.displayBtn=a!==w||b!==w;this.setExtremes(a,\nb,!1,w,{trigger:\"zoom\"});return!0},setAxisSize:function(){var a=this.chart,b=this.options,c=b.offsetLeft||0,d=b.offsetRight||0,e=this.horiz,f,g;this.left=g=o(b.left,a.plotLeft+c);this.top=f=o(b.top,a.plotTop);this.width=c=o(b.width,a.plotWidth-c+d);this.height=b=o(b.height,a.plotHeight);this.bottom=a.chartHeight-b-f;this.right=a.chartWidth-c-g;this.len=s(e?c:b,0);this.pos=e?g:f},getExtremes:function(){var a=this.isLog;return{min:a?ia(fa(this.min)):this.min,max:a?ia(fa(this.max)):this.max,dataMin:this.dataMin,\ndataMax:this.dataMax,userMin:this.userMin,userMax:this.userMax}},getThreshold:function(a){var b=this.isLog,c=b?fa(this.min):this.min,b=b?fa(this.max):this.max;c>a||a===null?a=c:b<a&&(a=b);return this.translate(a,0,1,0,1)},addPlotBand:function(a){this.addPlotBandOrLine(a,\"plotBands\")},addPlotLine:function(a){this.addPlotBandOrLine(a,\"plotLines\")},addPlotBandOrLine:function(a,b){var c=(new vb(this,a)).render(),d=this.userOptions;c&&(b&&(d[b]=d[b]||[],d[b].push(a)),this.plotLinesAndBands.push(c));return c},\nautoLabelAlign:function(a){a=(o(a,0)-this.side*90+720)%360;return a>15&&a<165?\"right\":a>195&&a<345?\"left\":\"center\"},getOffset:function(){var a=this,b=a.chart,c=b.renderer,d=a.options,e=a.tickPositions,f=a.ticks,g=a.horiz,h=a.side,i=b.inverted?[1,0,3,2][h]:h,j,k=0,l,m=0,p=d.title,q=d.labels,ba=0,A=b.axisOffset,L=b.clipOffset,t=[-1,1,1,-1][h],r,v=1,x=o(q.maxStaggerLines,5),la,E,H,B;a.hasData=j=a.hasVisibleSeries||u(a.min)&&u(a.max)&&!!e;a.showAxis=b=j||o(d.showEmpty,!0);a.staggerLines=a.horiz&&q.staggerLines;\nif(!a.axisGroup)a.gridGroup=c.g(\"grid\").attr({zIndex:d.gridZIndex||1}).add(),a.axisGroup=c.g(\"axis\").attr({zIndex:d.zIndex||2}).add(),a.labelGroup=c.g(\"axis-labels\").attr({zIndex:q.zIndex||7}).add();if(j||a.isLinked){a.labelAlign=o(q.align||a.autoLabelAlign(q.rotation));n(e,function(b){f[b]?f[b].addLabel():f[b]=new Ma(a,b)});if(a.horiz&&!a.staggerLines&&x&&!q.rotation){for(r=a.reversed?[].concat(e).reverse():e;v<x;){j=[];la=!1;for(q=0;q<r.length;q++)E=r[q],H=(H=f[E].label&&f[E].label.getBBox())?H.width:\n0,B=q%v,H&&(E=a.translate(E),j[B]!==w&&E<j[B]&&(la=!0),j[B]=E+H);if(la)v++;else break}if(v>1)a.staggerLines=v}n(e,function(b){if(h===0||h===2||{1:\"left\",3:\"right\"}[h]===a.labelAlign)ba=s(f[b].getLabelSize(),ba)});if(a.staggerLines)ba*=a.staggerLines,a.labelOffset=ba}else for(r in f)f[r].destroy(),delete f[r];if(p&&p.text&&p.enabled!==!1){if(!a.axisTitle)a.axisTitle=c.text(p.text,0,0,p.useHTML).attr({zIndex:7,rotation:p.rotation||0,align:p.textAlign||{low:\"left\",middle:\"center\",high:\"right\"}[p.align]}).css(p.style).add(a.axisGroup),\na.axisTitle.isNew=!0;if(b)k=a.axisTitle.getBBox()[g?\"height\":\"width\"],m=o(p.margin,g?5:10),l=p.offset;a.axisTitle[b?\"show\":\"hide\"]()}a.offset=t*o(d.offset,A[h]);a.axisTitleMargin=o(l,ba+m+(h!==2&&ba&&t*d.labels[g?\"y\":\"x\"]));A[h]=s(A[h],a.axisTitleMargin+k+t*a.offset);L[i]=s(L[i],P(d.lineWidth/2)*2)},getLinePath:function(a){var b=this.chart,c=this.opposite,d=this.offset,e=this.horiz,f=this.left+(c?this.width:0)+d,d=b.chartHeight-this.bottom-(c?this.height:0)+d;c&&(a*=-1);return b.renderer.crispLine([\"M\",\ne?this.left:f,e?d:this.top,\"L\",e?b.chartWidth-this.right:f,e?d:b.chartHeight-this.bottom],a)},getTitlePosition:function(){var a=this.horiz,b=this.left,c=this.top,d=this.len,e=this.options.title,f=a?b:c,g=this.opposite,h=this.offset,i=C(e.style.fontSize||12),d={low:f+(a?0:d),middle:f+d/2,high:f+(a?d:0)}[e.align],b=(a?c+this.height:b)+(a?1:-1)*(g?-1:1)*this.axisTitleMargin+(this.side===2?i:0);return{x:a?d:b+(g?this.width:0)+h+(e.x||0),y:a?b-(g?this.height:0)+h:d+(e.y||0)}},render:function(){var a=this,\nb=a.chart,c=b.renderer,d=a.options,e=a.isLog,f=a.isLinked,g=a.tickPositions,h=a.axisTitle,i=a.stacks,j=a.ticks,k=a.minorTicks,l=a.alternateBands,m=d.stackLabels,p=d.alternateGridColor,q=a.tickmarkOffset,o=d.lineWidth,A,s=b.hasRendered&&u(a.oldMin)&&!isNaN(a.oldMin);A=a.hasData;var t=a.showAxis,r,v;n([j,k,l],function(a){for(var b in a)a[b].isActive=!1});if(A||f)if(a.minorTickInterval&&!a.categories&&n(a.getMinorTickPositions(),function(b){k[b]||(k[b]=new Ma(a,b,\"minor\"));s&&k[b].isNew&&k[b].render(null,\n!0);k[b].render(null,!1,1)}),g.length&&(n(g.slice(1).concat([g[0]]),function(b,c){c=c===g.length-1?0:c+1;if(!f||b>=a.min&&b<=a.max)j[b]||(j[b]=new Ma(a,b)),s&&j[b].isNew&&j[b].render(c,!0),j[b].render(c,!1,1)}),q&&a.min===0&&(j[-1]||(j[-1]=new Ma(a,-1,null,!0)),j[-1].render(-1))),p&&n(g,function(b,c){if(c%2===0&&b<a.max)l[b]||(l[b]=new vb(a)),r=b+q,v=g[c+1]!==w?g[c+1]+q:a.max,l[b].options={from:e?fa(r):r,to:e?fa(v):v,color:p},l[b].render(),l[b].isActive=!0}),!a._addedPlotLB)n((d.plotLines||[]).concat(d.plotBands||\n[]),function(b){a.addPlotBandOrLine(b)}),a._addedPlotLB=!0;n([j,k,l],function(a){var c,d,e=[],f=Fa?Fa.duration||500:0,g=function(){for(d=e.length;d--;)a[e[d]]&&!a[e[d]].isActive&&(a[e[d]].destroy(),delete a[e[d]])};for(c in a)if(!a[c].isActive)a[c].render(c,!1,0),a[c].isActive=!1,e.push(c);a===l||!b.hasRendered||!f?g():f&&setTimeout(g,f)});if(o)A=a.getLinePath(o),a.axisLine?a.axisLine.animate({d:A}):a.axisLine=c.path(A).attr({stroke:d.lineColor,\"stroke-width\":o,zIndex:7}).add(a.axisGroup),a.axisLine[t?\n\"show\":\"hide\"]();if(h&&t)h[h.isNew?\"attr\":\"animate\"](a.getTitlePosition()),h.isNew=!1;if(m&&m.enabled){var x,la,d=a.stackTotalGroup;if(!d)a.stackTotalGroup=d=c.g(\"stack-labels\").attr({visibility:\"visible\",zIndex:6}).add();d.translate(b.plotLeft,b.plotTop);for(x in i)for(la in c=i[x],c)c[la].render(d)}a.isDirty=!1},removePlotBandOrLine:function(a){for(var b=this.plotLinesAndBands,c=this.options,d=this.userOptions,e=b.length;e--;)b[e].id===a&&b[e].destroy();n([c.plotLines||[],d.plotLines||[],c.plotBands||\n[],d.plotBands||[]],function(b){for(e=b.length;e--;)b[e].id===a&&ga(b,b[e])})},setTitle:function(a,b){this.update({title:a},b)},redraw:function(){var a=this.chart.pointer;a.reset&&a.reset(!0);this.render();n(this.plotLinesAndBands,function(a){a.render()});n(this.series,function(a){a.isDirty=!0})},buildStacks:function(){var a=this.series,b=a.length;if(!this.isXAxis){for(;b--;)a[b].setStackedPoints();if(this.usePercentage)for(b=0;b<a.length;b++)a[b].setPercentStacks()}},setCategories:function(a,b){this.update({categories:a},\nb)},destroy:function(a){var b=this,c=b.stacks,d,e=b.plotLinesAndBands;a||aa(b);for(d in c)Ka(c[d]),c[d]=null;n([b.ticks,b.minorTicks,b.alternateBands],function(a){Ka(a)});for(a=e.length;a--;)e[a].destroy();n(\"stackTotalGroup,axisLine,axisGroup,gridGroup,labelGroup,axisTitle\".split(\",\"),function(a){b[a]&&(b[a]=b[a].destroy())})}};wb.prototype={init:function(a,b){var c=b.borderWidth,d=b.style,e=C(d.padding);this.chart=a;this.options=b;this.crosshairs=[];this.now={x:0,y:0};this.isHidden=!0;this.label=\na.renderer.label(\"\",0,0,b.shape,null,null,b.useHTML,null,\"tooltip\").attr({padding:e,fill:b.backgroundColor,\"stroke-width\":c,r:b.borderRadius,zIndex:8}).css(d).css({padding:0}).add().attr({y:-999});$||this.label.shadow(b.shadow);this.shared=b.shared},destroy:function(){n(this.crosshairs,function(a){a&&a.destroy()});if(this.label)this.label=this.label.destroy();clearTimeout(this.hideTimer);clearTimeout(this.tooltipTimeout)},move:function(a,b,c,d){var e=this,f=e.now,g=e.options.animation!==!1&&!e.isHidden;\nr(f,{x:g?(2*f.x+a)/3:a,y:g?(f.y+b)/2:b,anchorX:g?(2*f.anchorX+c)/3:c,anchorY:g?(f.anchorY+d)/2:d});e.label.attr(f);if(g&&(N(a-f.x)>1||N(b-f.y)>1))clearTimeout(this.tooltipTimeout),this.tooltipTimeout=setTimeout(function(){e&&e.move(a,b,c,d)},32)},hide:function(){var a=this,b;clearTimeout(this.hideTimer);if(!this.isHidden)b=this.chart.hoverPoints,this.hideTimer=setTimeout(function(){a.label.fadeOut();a.isHidden=!0},o(this.options.hideDelay,500)),b&&n(b,function(a){a.setState()}),this.chart.hoverPoints=\nnull},hideCrosshairs:function(){n(this.crosshairs,function(a){a&&a.hide()})},getAnchor:function(a,b){var c,d=this.chart,e=d.inverted,f=d.plotTop,g=0,h=0,i,a=ja(a);c=a[0].tooltipPos;this.followPointer&&b&&(b.chartX===w&&(b=d.pointer.normalize(b)),c=[b.chartX-d.plotLeft,b.chartY-f]);c||(n(a,function(a){i=a.series.yAxis;g+=a.plotX;h+=(a.plotLow?(a.plotLow+a.plotHigh)/2:a.plotY)+(!e&&i?i.top-f:0)}),g/=a.length,h/=a.length,c=[e?d.plotWidth-h:g,this.shared&&!e&&a.length>1&&b?b.chartY-f:e?d.plotHeight-g:\nh]);return Na(c,t)},getPosition:function(a,b,c){var d=this.chart,e=d.plotLeft,f=d.plotTop,g=d.plotWidth,h=d.plotHeight,i=o(this.options.distance,12),j=c.plotX,c=c.plotY,d=j+e+(d.inverted?i:-a-i),k=c-b+f+15,l;d<7&&(d=e+s(j,0)+i);d+a>e+g&&(d-=d+a-(e+g),k=c-b+f-i,l=!0);k<f+5&&(k=f+5,l&&c>=k&&c<=k+b&&(k=c+f+i));k+b>f+h&&(k=s(f,f+h-b-i));return{x:d,y:k}},defaultFormatter:function(a){var b=this.points||ja(this),c=b[0].series,d;d=[c.tooltipHeaderFormatter(b[0])];n(b,function(a){c=a.series;d.push(c.tooltipFormatter&&\nc.tooltipFormatter(a)||a.point.tooltipFormatter(c.tooltipOptions.pointFormat))});d.push(a.options.footerFormat||\"\");return d.join(\"\")},refresh:function(a,b){var c=this.chart,d=this.label,e=this.options,f,g,h={},i,j=[];i=e.formatter||this.defaultFormatter;var h=c.hoverPoints,k,l=e.crosshairs,m=this.shared;clearTimeout(this.hideTimer);this.followPointer=ja(a)[0].series.tooltipOptions.followPointer;g=this.getAnchor(a,b);f=g[0];g=g[1];m&&(!a.series||!a.series.noSharedTooltip)?(c.hoverPoints=a,h&&n(h,\nfunction(a){a.setState()}),n(a,function(a){a.setState(\"hover\");j.push(a.getLabelConfig())}),h={x:a[0].category,y:a[0].y},h.points=j,a=a[0]):h=a.getLabelConfig();i=i.call(h,this);h=a.series;i===!1?this.hide():(this.isHidden&&(Wa(d),d.attr(\"opacity\",1).show()),d.attr({text:i}),k=e.borderColor||a.color||h.color||\"#606060\",d.attr({stroke:k}),this.updatePosition({plotX:f,plotY:g}),this.isHidden=!1);if(l){l=ja(l);for(d=l.length;d--;)if(m=a.series,e=m[d?\"yAxis\":\"xAxis\"],l[d]&&e)if(h=d?o(a.stackY,a.y):a.x,\ne.isLog&&(h=na(h)),d===1&&m.modifyValue&&(h=m.modifyValue(h)),e=e.getPlotLinePath(h,1),this.crosshairs[d])this.crosshairs[d].attr({d:e,visibility:\"visible\"});else{h={\"stroke-width\":l[d].width||1,stroke:l[d].color||\"#C0C0C0\",zIndex:l[d].zIndex||2};if(l[d].dashStyle)h.dashstyle=l[d].dashStyle;this.crosshairs[d]=c.renderer.path(e).attr(h).add()}}z(c,\"tooltipRefresh\",{text:i,x:f+c.plotLeft,y:g+c.plotTop,borderColor:k})},updatePosition:function(a){var b=this.chart,c=this.label,c=(this.options.positioner||\nthis.getPosition).call(this,c.width,c.height,a);this.move(t(c.x),t(c.y),a.plotX+b.plotLeft,a.plotY+b.plotTop)}};xb.prototype={init:function(a,b){var c=b.chart,d=c.events,e=$?\"\":c.zoomType,c=a.inverted,f;this.options=b;this.chart=a;this.zoomX=f=/x/.test(e);this.zoomY=e=/y/.test(e);this.zoomHor=f&&!c||e&&c;this.zoomVert=e&&!c||f&&c;this.runChartClick=d&&!!d.click;this.pinchDown=[];this.lastValidTouch={};if(b.tooltip.enabled)a.tooltip=new wb(a,b.tooltip);this.setDOMEvents()},normalize:function(a,b){var c,\nd,a=a||O.event;if(!a.target)a.target=a.srcElement;a=Xb(a);d=a.touches?a.touches.item(0):a;if(!b)this.chartPosition=b=Wb(this.chart.container);d.pageX===w?(c=s(a.x,a.clientX-b.left),d=a.y):(c=d.pageX-b.left,d=d.pageY-b.top);return r(a,{chartX:t(c),chartY:t(d)})},getCoordinates:function(a){var b={xAxis:[],yAxis:[]};n(this.chart.axes,function(c){b[c.isXAxis?\"xAxis\":\"yAxis\"].push({axis:c,value:c.toValue(a[c.horiz?\"chartX\":\"chartY\"])})});return b},getIndex:function(a){var b=this.chart;return b.inverted?\nb.plotHeight+b.plotTop-a.chartY:a.chartX-b.plotLeft},runPointActions:function(a){var b=this.chart,c=b.series,d=b.tooltip,e,f=b.hoverPoint,g=b.hoverSeries,h,i,j=b.chartWidth,k=this.getIndex(a);if(d&&this.options.tooltip.shared&&(!g||!g.noSharedTooltip)){e=[];h=c.length;for(i=0;i<h;i++)if(c[i].visible&&c[i].options.enableMouseTracking!==!1&&!c[i].noSharedTooltip&&c[i].tooltipPoints.length&&(b=c[i].tooltipPoints[k])&&b.series)b._dist=N(k-b.clientX),j=I(j,b._dist),e.push(b);for(h=e.length;h--;)e[h]._dist>\nj&&e.splice(h,1);if(e.length&&e[0].clientX!==this.hoverX)d.refresh(e,a),this.hoverX=e[0].clientX}if(g&&g.tracker){if((b=g.tooltipPoints[k])&&b!==f)b.onMouseOver(a)}else d&&d.followPointer&&!d.isHidden&&(a=d.getAnchor([{}],a),d.updatePosition({plotX:a[0],plotY:a[1]}))},reset:function(a){var b=this.chart,c=b.hoverSeries,d=b.hoverPoint,e=b.tooltip,b=e&&e.shared?b.hoverPoints:d;(a=a&&e&&b)&&ja(b)[0].plotX===w&&(a=!1);if(a)e.refresh(b);else{if(d)d.onMouseOut();if(c)c.onMouseOut();e&&(e.hide(),e.hideCrosshairs());\nthis.hoverX=null}},scaleGroups:function(a,b){var c=this.chart,d;n(c.series,function(e){d=a||e.getPlotBox();e.xAxis&&e.xAxis.zoomEnabled&&(e.group.attr(d),e.markerGroup&&(e.markerGroup.attr(d),e.markerGroup.clip(b?c.clipRect:null)),e.dataLabelsGroup&&e.dataLabelsGroup.attr(d))});c.clipRect.attr(b||c.clipBox)},pinchTranslateDirection:function(a,b,c,d,e,f,g){var h=this.chart,i=a?\"x\":\"y\",j=a?\"X\":\"Y\",k=\"chart\"+j,l=a?\"width\":\"height\",m=h[\"plot\"+(a?\"Left\":\"Top\")],p,q,o=1,n=h.inverted,s=h.bounds[a?\"h\":\"v\"],\nt=b.length===1,u=b[0][k],r=c[0][k],w=!t&&b[1][k],v=!t&&c[1][k],x,c=function(){!t&&N(u-w)>20&&(o=N(r-v)/N(u-w));q=(m-r)/o+u;p=h[\"plot\"+(a?\"Width\":\"Height\")]/o};c();b=q;b<s.min?(b=s.min,x=!0):b+p>s.max&&(b=s.max-p,x=!0);x?(r-=0.8*(r-g[i][0]),t||(v-=0.8*(v-g[i][1])),c()):g[i]=[r,v];n||(f[i]=q-m,f[l]=p);f=n?1/o:o;e[l]=p;e[i]=b;d[n?a?\"scaleY\":\"scaleX\":\"scale\"+j]=o;d[\"translate\"+j]=f*m+(r-f*u)},pinch:function(a){var b=this,c=b.chart,d=b.pinchDown,e=c.tooltip&&c.tooltip.options.followTouchMove,f=a.touches,\ng=f.length,h=b.lastValidTouch,i=b.zoomHor||b.pinchHor,j=b.zoomVert||b.pinchVert,k=i||j,l=b.selectionMarker,m={},p=g===1&&(b.inClass(a.target,\"highcharts-tracker\")&&c.runTrackerClick||c.runChartClick),q={};(k||e)&&!p&&a.preventDefault();Na(f,function(a){return b.normalize(a)});if(a.type===\"touchstart\")n(f,function(a,b){d[b]={chartX:a.chartX,chartY:a.chartY}}),h.x=[d[0].chartX,d[1]&&d[1].chartX],h.y=[d[0].chartY,d[1]&&d[1].chartY],n(c.axes,function(a){if(a.zoomEnabled){var b=c.bounds[a.horiz?\"h\":\"v\"],\nd=a.minPixelPadding,e=a.toPixels(a.dataMin),f=a.toPixels(a.dataMax),g=I(e,f),e=s(e,f);b.min=I(a.pos,g-d);b.max=s(a.pos+a.len,e+d)}});else if(d.length){if(!l)b.selectionMarker=l=r({destroy:pa},c.plotBox);i&&b.pinchTranslateDirection(!0,d,f,m,l,q,h);j&&b.pinchTranslateDirection(!1,d,f,m,l,q,h);b.hasPinched=k;b.scaleGroups(m,q);!k&&e&&g===1&&this.runPointActions(b.normalize(a))}},dragStart:function(a){var b=this.chart;b.mouseIsDown=a.type;b.cancelClick=!1;b.mouseDownX=this.mouseDownX=a.chartX;b.mouseDownY=\nthis.mouseDownY=a.chartY},drag:function(a){var b=this.chart,c=b.options.chart,d=a.chartX,e=a.chartY,f=this.zoomHor,g=this.zoomVert,h=b.plotLeft,i=b.plotTop,j=b.plotWidth,k=b.plotHeight,l,m=this.mouseDownX,p=this.mouseDownY;d<h?d=h:d>h+j&&(d=h+j);e<i?e=i:e>i+k&&(e=i+k);this.hasDragged=Math.sqrt(Math.pow(m-d,2)+Math.pow(p-e,2));if(this.hasDragged>10){l=b.isInsidePlot(m-h,p-i);if(b.hasCartesianSeries&&(this.zoomX||this.zoomY)&&l&&!this.selectionMarker)this.selectionMarker=b.renderer.rect(h,i,f?1:j,g?\n1:k,0).attr({fill:c.selectionMarkerFill||\"rgba(69,114,167,0.25)\",zIndex:7}).add();this.selectionMarker&&f&&(d-=m,this.selectionMarker.attr({width:N(d),x:(d>0?0:d)+m}));this.selectionMarker&&g&&(d=e-p,this.selectionMarker.attr({height:N(d),y:(d>0?0:d)+p}));l&&!this.selectionMarker&&c.panning&&b.pan(a,c.panning)}},drop:function(a){var b=this.chart,c=this.hasPinched;if(this.selectionMarker){var d={xAxis:[],yAxis:[],originalEvent:a.originalEvent||a},e=this.selectionMarker,f=e.x,g=e.y,h;if(this.hasDragged||\nc)n(b.axes,function(a){if(a.zoomEnabled){var b=a.horiz,c=a.toValue(b?f:g),b=a.toValue(b?f+e.width:g+e.height);!isNaN(c)&&!isNaN(b)&&(d[a.xOrY+\"Axis\"].push({axis:a,min:I(c,b),max:s(c,b)}),h=!0)}}),h&&z(b,\"selection\",d,function(a){b.zoom(r(a,c?{animation:!1}:null))});this.selectionMarker=this.selectionMarker.destroy();c&&this.scaleGroups()}if(b)K(b.container,{cursor:b._cursor}),b.cancelClick=this.hasDragged>10,b.mouseIsDown=this.hasDragged=this.hasPinched=!1,this.pinchDown=[]},onContainerMouseDown:function(a){a=\nthis.normalize(a);a.preventDefault&&a.preventDefault();this.dragStart(a)},onDocumentMouseUp:function(a){this.drop(a)},onDocumentMouseMove:function(a){var b=this.chart,c=this.chartPosition,d=b.hoverSeries,a=this.normalize(a,c);c&&d&&!this.inClass(a.target,\"highcharts-tracker\")&&!b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)&&this.reset()},onContainerMouseLeave:function(){this.reset();this.chartPosition=null},onContainerMouseMove:function(a){var b=this.chart,a=this.normalize(a);a.returnValue=\n!1;b.mouseIsDown===\"mousedown\"&&this.drag(a);(this.inClass(a.target,\"highcharts-tracker\")||b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop))&&!b.openMenu&&this.runPointActions(a)},inClass:function(a,b){for(var c;a;){if(c=v(a,\"class\"))if(c.indexOf(b)!==-1)return!0;else if(c.indexOf(\"highcharts-container\")!==-1)return!1;a=a.parentNode}},onTrackerMouseOut:function(a){var b=this.chart.hoverSeries;if(b&&!b.options.stickyTracking&&!this.inClass(a.toElement||a.relatedTarget,\"highcharts-tooltip\"))b.onMouseOut()},\nonContainerClick:function(a){var b=this.chart,c=b.hoverPoint,d=b.plotLeft,e=b.plotTop,f=b.inverted,g,h,i,a=this.normalize(a);a.cancelBubble=!0;if(!b.cancelClick)c&&this.inClass(a.target,\"highcharts-tracker\")?(g=this.chartPosition,h=c.plotX,i=c.plotY,r(c,{pageX:g.left+d+(f?b.plotWidth-i:h),pageY:g.top+e+(f?b.plotHeight-h:i)}),z(c.series,\"click\",r(a,{point:c})),b.hoverPoint&&c.firePointEvent(\"click\",a)):(r(a,this.getCoordinates(a)),b.isInsidePlot(a.chartX-d,a.chartY-e)&&z(b,\"click\",a))},onContainerTouchStart:function(a){var b=\nthis.chart;a.touches.length===1?(a=this.normalize(a),b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)?(this.runPointActions(a),this.pinch(a)):this.reset()):a.touches.length===2&&this.pinch(a)},onContainerTouchMove:function(a){(a.touches.length===1||a.touches.length===2)&&this.pinch(a)},onDocumentTouchEnd:function(a){this.drop(a)},setDOMEvents:function(){var a=this,b=a.chart.container,c;this._events=c=[[b,\"onmousedown\",\"onContainerMouseDown\"],[b,\"onmousemove\",\"onContainerMouseMove\"],[b,\"onclick\",\n\"onContainerClick\"],[b,\"mouseleave\",\"onContainerMouseLeave\"],[y,\"mousemove\",\"onDocumentMouseMove\"],[y,\"mouseup\",\"onDocumentMouseUp\"]];ib&&c.push([b,\"ontouchstart\",\"onContainerTouchStart\"],[b,\"ontouchmove\",\"onContainerTouchMove\"],[y,\"touchend\",\"onDocumentTouchEnd\"]);n(c,function(b){a[\"_\"+b[2]]=function(c){a[b[2]](c)};b[1].indexOf(\"on\")===0?b[0][b[1]]=a[\"_\"+b[2]]:J(b[0],b[1],a[\"_\"+b[2]])})},destroy:function(){var a=this;n(a._events,function(b){b[1].indexOf(\"on\")===0?b[0][b[1]]=null:aa(b[0],b[1],a[\"_\"+\nb[2]])});delete a._events;clearInterval(a.tooltipTimeout)}};eb.prototype={init:function(a,b){var c=this,d=b.itemStyle,e=o(b.padding,8),f=b.itemMarginTop||0;this.options=b;if(b.enabled)c.baseline=C(d.fontSize)+3+f,c.itemStyle=d,c.itemHiddenStyle=x(d,b.itemHiddenStyle),c.itemMarginTop=f,c.padding=e,c.initialItemX=e,c.initialItemY=e-5,c.maxItemWidth=0,c.chart=a,c.itemHeight=0,c.lastLineHeight=0,c.render(),J(c.chart,\"endResize\",function(){c.positionCheckboxes()})},colorizeItem:function(a,b){var c=this.options,\nd=a.legendItem,e=a.legendLine,f=a.legendSymbol,g=this.itemHiddenStyle.color,c=b?c.itemStyle.color:g,h=b?a.color:g,g=a.options&&a.options.marker,i={stroke:h,fill:h},j;d&&d.css({fill:c,color:c});e&&e.attr({stroke:h});if(f){if(g&&f.isMarker)for(j in g=a.convertAttribs(g),g)d=g[j],d!==w&&(i[j]=d);f.attr(i)}},positionItem:function(a){var b=this.options,c=b.symbolPadding,b=!b.rtl,d=a._legendItemPos,e=d[0],d=d[1],f=a.checkbox;a.legendGroup&&a.legendGroup.translate(b?e:this.legendWidth-e-2*c-4,d);if(f)f.x=\ne,f.y=d},destroyItem:function(a){var b=a.checkbox;n([\"legendItem\",\"legendLine\",\"legendSymbol\",\"legendGroup\"],function(b){a[b]&&(a[b]=a[b].destroy())});b&&Ta(a.checkbox)},destroy:function(){var a=this.group,b=this.box;if(b)this.box=b.destroy();if(a)this.group=a.destroy()},positionCheckboxes:function(a){var b=this.group.alignAttr,c,d=this.clipHeight||this.legendHeight;if(b)c=b.translateY,n(this.allItems,function(e){var f=e.checkbox,g;f&&(g=c+f.y+(a||0)+3,K(f,{left:b.translateX+e.legendItemWidth+f.x-\n20+\"px\",top:g+\"px\",display:g>c-6&&g<c+d-6?\"\":S}))})},renderTitle:function(){var a=this.padding,b=this.options.title,c=0;if(b.text){if(!this.title)this.title=this.chart.renderer.label(b.text,a-3,a-4,null,null,null,null,null,\"legend-title\").attr({zIndex:1}).css(b.style).add(this.group);a=this.title.getBBox();c=a.height;this.offsetWidth=a.width;this.contentGroup.attr({translateY:c})}this.titleHeight=c},renderItem:function(a){var B;var b=this,c=b.chart,d=c.renderer,e=b.options,f=e.layout===\"horizontal\",\ng=e.symbolWidth,h=e.symbolPadding,i=b.itemStyle,j=b.itemHiddenStyle,k=b.padding,l=f?o(e.itemDistance,8):0,m=!e.rtl,p=e.width,q=e.itemMarginBottom||0,n=b.itemMarginTop,A=b.initialItemX,t=a.legendItem,u=a.series||a,r=u.options,w=r.showCheckbox,v=e.useHTML;if(!t&&(a.legendGroup=d.g(\"legend-item\").attr({zIndex:1}).add(b.scrollGroup),u.drawLegendSymbol(b,a),a.legendItem=t=d.text(e.labelFormat?Ca(e.labelFormat,a):e.labelFormatter.call(a),m?g+h:-h,b.baseline,v).css(x(a.visible?i:j)).attr({align:m?\"left\":\n\"right\",zIndex:2}).add(a.legendGroup),(v?t:a.legendGroup).on(\"mouseover\",function(){a.setState(\"hover\");t.css(b.options.itemHoverStyle)}).on(\"mouseout\",function(){t.css(a.visible?i:j);a.setState()}).on(\"click\",function(b){var c=function(){a.setVisible()},b={browserEvent:b};a.firePointEvent?a.firePointEvent(\"legendItemClick\",b,c):z(a,\"legendItemClick\",b,c)}),b.colorizeItem(a,a.visible),r&&w))a.checkbox=U(\"input\",{type:\"checkbox\",checked:a.selected,defaultChecked:a.selected},e.itemCheckboxStyle,c.container),\nJ(a.checkbox,\"click\",function(b){z(a,\"checkboxClick\",{checked:b.target.checked},function(){a.select()})});d=t.getBBox();B=a.legendItemWidth=e.itemWidth||g+h+d.width+l+(w?20:0),e=B;b.itemHeight=g=d.height;if(f&&b.itemX-A+e>(p||c.chartWidth-2*k-A))b.itemX=A,b.itemY+=n+b.lastLineHeight+q,b.lastLineHeight=0;b.maxItemWidth=s(b.maxItemWidth,e);b.lastItemY=n+b.itemY+q;b.lastLineHeight=s(g,b.lastLineHeight);a._legendItemPos=[b.itemX,b.itemY];f?b.itemX+=e:(b.itemY+=n+g+q,b.lastLineHeight=g);b.offsetWidth=\np||s((f?b.itemX-A-l:e)+k,b.offsetWidth)},render:function(){var a=this,b=a.chart,c=b.renderer,d=a.group,e,f,g,h,i=a.box,j=a.options,k=a.padding,l=j.borderWidth,m=j.backgroundColor;a.itemX=a.initialItemX;a.itemY=a.initialItemY;a.offsetWidth=0;a.lastItemY=0;if(!d)a.group=d=c.g(\"legend\").attr({zIndex:7}).add(),a.contentGroup=c.g().attr({zIndex:1}).add(d),a.scrollGroup=c.g().add(a.contentGroup);a.renderTitle();e=[];n(b.series,function(a){var b=a.options;b.showInLegend&&!u(b.linkedTo)&&(e=e.concat(a.legendItems||\n(b.legendType===\"point\"?a.data:a)))});Kb(e,function(a,b){return(a.options&&a.options.legendIndex||0)-(b.options&&b.options.legendIndex||0)});j.reversed&&e.reverse();a.allItems=e;a.display=f=!!e.length;n(e,function(b){a.renderItem(b)});g=j.width||a.offsetWidth;h=a.lastItemY+a.lastLineHeight+a.titleHeight;h=a.handleOverflow(h);if(l||m){g+=k;h+=k;if(i){if(g>0&&h>0)i[i.isNew?\"attr\":\"animate\"](i.crisp(null,null,null,g,h)),i.isNew=!1}else a.box=i=c.rect(0,0,g,h,j.borderRadius,l||0).attr({stroke:j.borderColor,\n\"stroke-width\":l||0,fill:m||S}).add(d).shadow(j.shadow),i.isNew=!0;i[f?\"show\":\"hide\"]()}a.legendWidth=g;a.legendHeight=h;n(e,function(b){a.positionItem(b)});f&&d.align(r({width:g,height:h},j),!0,\"spacingBox\");b.isResizing||this.positionCheckboxes()},handleOverflow:function(a){var b=this,c=this.chart,d=c.renderer,e=this.options,f=e.y,f=c.spacingBox.height+(e.verticalAlign===\"top\"?-f:f)-this.padding,g=e.maxHeight,h=this.clipRect,i=e.navigation,j=o(i.animation,!0),k=i.arrowSize||12,l=this.nav;e.layout===\n\"horizontal\"&&(f/=2);g&&(f=I(f,g));if(a>f&&!e.useHTML){this.clipHeight=c=f-20-this.titleHeight;this.pageCount=xa(a/c);this.currentPage=o(this.currentPage,1);this.fullHeight=a;if(!h)h=b.clipRect=d.clipRect(0,0,9999,0),b.contentGroup.clip(h);h.attr({height:c});if(!l)this.nav=l=d.g().attr({zIndex:1}).add(this.group),this.up=d.symbol(\"triangle\",0,0,k,k).on(\"click\",function(){b.scroll(-1,j)}).add(l),this.pager=d.text(\"\",15,10).css(i.style).add(l),this.down=d.symbol(\"triangle-down\",0,0,k,k).on(\"click\",\nfunction(){b.scroll(1,j)}).add(l);b.scroll(0);a=f}else if(l)h.attr({height:c.chartHeight}),l.hide(),this.scrollGroup.attr({translateY:1}),this.clipHeight=0;return a},scroll:function(a,b){var c=this.pageCount,d=this.currentPage+a,e=this.clipHeight,f=this.options.navigation,g=f.activeColor,h=f.inactiveColor,f=this.pager,i=this.padding;d>c&&(d=c);if(d>0)b!==w&&La(b,this.chart),this.nav.attr({translateX:i,translateY:e+7+this.titleHeight,visibility:\"visible\"}),this.up.attr({fill:d===1?h:g}).css({cursor:d===\n1?\"default\":\"pointer\"}),f.attr({text:d+\"/\"+this.pageCount}),this.down.attr({x:18+this.pager.getBBox().width,fill:d===c?h:g}).css({cursor:d===c?\"default\":\"pointer\"}),e=-I(e*(d-1),this.fullHeight-e+i)+1,this.scrollGroup.animate({translateY:e}),f.attr({text:d+\"/\"+c}),this.currentPage=d,this.positionCheckboxes(e)}};/Trident.*?11\\.0/.test(oa)&&mb(eb.prototype,\"positionItem\",function(a,b){var c=this;setTimeout(function(){a.call(c,b)})});yb.prototype={init:function(a,b){var c,d=a.series;a.series=null;c=\nx(M,a);c.series=a.series=d;d=c.chart;this.margin=this.splashArray(\"margin\",d);this.spacing=this.splashArray(\"spacing\",d);var e=d.events;this.bounds={h:{},v:{}};this.callback=b;this.isResizing=0;this.options=c;this.axes=[];this.series=[];this.hasCartesianSeries=d.showAxes;var f=this,g;f.index=Ga.length;Ga.push(f);d.reflow!==!1&&J(f,\"load\",function(){f.initReflow()});if(e)for(g in e)J(f,g,e[g]);f.xAxis=[];f.yAxis=[];f.animation=$?!1:o(d.animation,!0);f.pointCount=0;f.counters=new Jb;f.firstRender()},\ninitSeries:function(a){var b=this.options.chart;(b=W[a.type||b.type||b.defaultSeriesType])||ka(17,!0);b=new b;b.init(this,a);return b},addSeries:function(a,b,c){var d,e=this;a&&(b=o(b,!0),z(e,\"addSeries\",{options:a},function(){d=e.initSeries(a);e.isDirtyLegend=!0;e.linkSeries();b&&e.redraw(c)}));return d},addAxis:function(a,b,c,d){var e=b?\"xAxis\":\"yAxis\",f=this.options;new db(this,x(a,{index:this[e].length,isX:b}));f[e]=ja(f[e]||{});f[e].push(a);o(c,!0)&&this.redraw(d)},isInsidePlot:function(a,b,\nc){var d=c?b:a,a=c?a:b;return d>=0&&d<=this.plotWidth&&a>=0&&a<=this.plotHeight},adjustTickAmounts:function(){this.options.chart.alignTicks!==!1&&n(this.axes,function(a){a.adjustTickAmount()});this.maxTicks=null},redraw:function(a){var b=this.axes,c=this.series,d=this.pointer,e=this.legend,f=this.isDirtyLegend,g,h,i=this.isDirtyBox,j=c.length,k=j,l=this.renderer,m=l.isHidden(),p=[];La(a,this);m&&this.cloneRenderTo();for(this.layOutTitles();k--;)if(a=c[k],a.options.stacking&&(g=!0,a.isDirty)){h=!0;\nbreak}if(h)for(k=j;k--;)if(a=c[k],a.options.stacking)a.isDirty=!0;n(c,function(a){a.isDirty&&a.options.legendType===\"point\"&&(f=!0)});if(f&&e.options.enabled)e.render(),this.isDirtyLegend=!1;g&&this.getStacks();if(this.hasCartesianSeries){if(!this.isResizing)this.maxTicks=null,n(b,function(a){a.setScale()});this.adjustTickAmounts();this.getMargins();n(b,function(a){a.isDirty&&(i=!0)});n(b,function(a){if(a.isDirtyExtremes)a.isDirtyExtremes=!1,p.push(function(){z(a,\"afterSetExtremes\",r(a.eventArgs,\na.getExtremes()));delete a.eventArgs});(i||g)&&a.redraw()})}i&&this.drawChartBox();n(c,function(a){a.isDirty&&a.visible&&(!a.isCartesian||a.xAxis)&&a.redraw()});d&&d.reset&&d.reset(!0);l.draw();z(this,\"redraw\");m&&this.cloneRenderTo(!0);n(p,function(a){a.call()})},showLoading:function(a){var b=this.options,c=this.loadingDiv,d=b.loading;if(!c)this.loadingDiv=c=U(Ea,{className:\"highcharts-loading\"},r(d.style,{zIndex:10,display:S}),this.container),this.loadingSpan=U(\"span\",null,d.labelStyle,c);this.loadingSpan.innerHTML=\na||b.lang.loading;if(!this.loadingShown)K(c,{opacity:0,display:\"\",left:this.plotLeft+\"px\",top:this.plotTop+\"px\",width:this.plotWidth+\"px\",height:this.plotHeight+\"px\"}),Bb(c,{opacity:d.style.opacity},{duration:d.showDuration||0}),this.loadingShown=!0},hideLoading:function(){var a=this.options,b=this.loadingDiv;b&&Bb(b,{opacity:0},{duration:a.loading.hideDuration||100,complete:function(){K(b,{display:S})}});this.loadingShown=!1},get:function(a){var b=this.axes,c=this.series,d,e;for(d=0;d<b.length;d++)if(b[d].options.id===\na)return b[d];for(d=0;d<c.length;d++)if(c[d].options.id===a)return c[d];for(d=0;d<c.length;d++){e=c[d].points||[];for(b=0;b<e.length;b++)if(e[b].id===a)return e[b]}return null},getAxes:function(){var a=this,b=this.options,c=b.xAxis=ja(b.xAxis||{}),b=b.yAxis=ja(b.yAxis||{});n(c,function(a,b){a.index=b;a.isX=!0});n(b,function(a,b){a.index=b});c=c.concat(b);n(c,function(b){new db(a,b)});a.adjustTickAmounts()},getSelectedPoints:function(){var a=[];n(this.series,function(b){a=a.concat(ub(b.points||[],\nfunction(a){return a.selected}))});return a},getSelectedSeries:function(){return ub(this.series,function(a){return a.selected})},getStacks:function(){var a=this;n(a.yAxis,function(a){if(a.stacks&&a.hasVisibleSeries)a.oldStacks=a.stacks});n(a.series,function(b){if(b.options.stacking&&(b.visible===!0||a.options.chart.ignoreHiddenSeries===!1))b.stackKey=b.type+o(b.options.stack,\"\")})},showResetZoom:function(){var a=this,b=M.lang,c=a.options.chart.resetZoomButton,d=c.theme,e=d.states,f=c.relativeTo===\n\"chart\"?null:\"plotBox\";this.resetZoomButton=a.renderer.button(b.resetZoom,null,null,function(){a.zoomOut()},d,e&&e.hover).attr({align:c.position.align,title:b.resetZoomTitle}).add().align(c.position,!1,f)},zoomOut:function(){var a=this;z(a,\"selection\",{resetSelection:!0},function(){a.zoom()})},zoom:function(a){var b,c=this.pointer,d=!1,e;!a||a.resetSelection?n(this.axes,function(a){b=a.zoom()}):n(a.xAxis.concat(a.yAxis),function(a){var e=a.axis,h=e.isXAxis;if(c[h?\"zoomX\":\"zoomY\"]||c[h?\"pinchX\":\"pinchY\"])b=\ne.zoom(a.min,a.max),e.displayBtn&&(d=!0)});e=this.resetZoomButton;if(d&&!e)this.showResetZoom();else if(!d&&T(e))this.resetZoomButton=e.destroy();b&&this.redraw(o(this.options.chart.animation,a&&a.animation,this.pointCount<100))},pan:function(a,b){var c=this,d=c.hoverPoints,e;d&&n(d,function(a){a.setState()});n(b===\"xy\"?[1,0]:[1],function(b){var d=a[b?\"chartX\":\"chartY\"],h=c[b?\"xAxis\":\"yAxis\"][0],i=c[b?\"mouseDownX\":\"mouseDownY\"],j=(h.pointRange||0)/2,k=h.getExtremes(),l=h.toValue(i-d,!0)+j,i=h.toValue(i+\nc[b?\"plotWidth\":\"plotHeight\"]-d,!0)-j;h.series.length&&l>I(k.dataMin,k.min)&&i<s(k.dataMax,k.max)&&(h.setExtremes(l,i,!1,!1,{trigger:\"pan\"}),e=!0);c[b?\"mouseDownX\":\"mouseDownY\"]=d});e&&c.redraw(!1);K(c.container,{cursor:\"move\"})},setTitle:function(a,b){var f;var c=this,d=c.options,e;e=d.title=x(d.title,a);f=d.subtitle=x(d.subtitle,b),d=f;n([[\"title\",a,e],[\"subtitle\",b,d]],function(a){var b=a[0],d=c[b],e=a[1],a=a[2];d&&e&&(c[b]=d=d.destroy());a&&a.text&&!d&&(c[b]=c.renderer.text(a.text,0,0,a.useHTML).attr({align:a.align,\n\"class\":\"highcharts-\"+b,zIndex:a.zIndex||4}).css(a.style).add())});c.layOutTitles()},layOutTitles:function(){var a=0,b=this.title,c=this.subtitle,d=this.options,e=d.title,d=d.subtitle,f=this.spacingBox.width-44;if(b&&(b.css({width:(e.width||f)+\"px\"}).align(r({y:15},e),!1,\"spacingBox\"),!e.floating&&!e.verticalAlign))a=b.getBBox().height,a>=18&&a<=25&&(a=15);c&&(c.css({width:(d.width||f)+\"px\"}).align(r({y:a+e.margin},d),!1,\"spacingBox\"),!d.floating&&!d.verticalAlign&&(a=xa(a+c.getBBox().height)));this.titleOffset=\na},getChartSize:function(){var a=this.options.chart,b=this.renderToClone||this.renderTo;this.containerWidth=jb(b,\"width\");this.containerHeight=jb(b,\"height\");this.chartWidth=s(0,a.width||this.containerWidth||600);this.chartHeight=s(0,o(a.height,this.containerHeight>19?this.containerHeight:400))},cloneRenderTo:function(a){var b=this.renderToClone,c=this.container;a?b&&(this.renderTo.appendChild(c),Ta(b),delete this.renderToClone):(c&&c.parentNode===this.renderTo&&this.renderTo.removeChild(c),this.renderToClone=\nb=this.renderTo.cloneNode(0),K(b,{position:\"absolute\",top:\"-9999px\",display:\"block\"}),y.body.appendChild(b),c&&b.appendChild(c))},getContainer:function(){var a,b=this.options.chart,c,d,e;this.renderTo=a=b.renderTo;e=\"highcharts-\"+zb++;if(ea(a))this.renderTo=a=y.getElementById(a);a||ka(13,!0);c=C(v(a,\"data-highcharts-chart\"));!isNaN(c)&&Ga[c]&&Ga[c].destroy();v(a,\"data-highcharts-chart\",this.index);a.innerHTML=\"\";a.offsetWidth||this.cloneRenderTo();this.getChartSize();c=this.chartWidth;d=this.chartHeight;\nthis.container=a=U(Ea,{className:\"highcharts-container\"+(b.className?\" \"+b.className:\"\"),id:e},r({position:\"relative\",overflow:\"hidden\",width:c+\"px\",height:d+\"px\",textAlign:\"left\",lineHeight:\"normal\",zIndex:0,\"-webkit-tap-highlight-color\":\"rgba(0,0,0,0)\"},b.style),this.renderToClone||a);this._cursor=a.style.cursor;this.renderer=b.forExport?new Ha(a,c,d,!0):new Va(a,c,d);$&&this.renderer.create(this,a,c,d)},getMargins:function(){var a=this.spacing,b,c=this.legend,d=this.margin,e=this.options.legend,\nf=o(e.margin,10),g=e.x,h=e.y,i=e.align,j=e.verticalAlign,k=this.titleOffset;this.resetMargins();b=this.axisOffset;if(k&&!u(d[0]))this.plotTop=s(this.plotTop,k+this.options.title.margin+a[0]);if(c.display&&!e.floating)if(i===\"right\"){if(!u(d[1]))this.marginRight=s(this.marginRight,c.legendWidth-g+f+a[1])}else if(i===\"left\"){if(!u(d[3]))this.plotLeft=s(this.plotLeft,c.legendWidth+g+f+a[3])}else if(j===\"top\"){if(!u(d[0]))this.plotTop=s(this.plotTop,c.legendHeight+h+f+a[0])}else if(j===\"bottom\"&&!u(d[2]))this.marginBottom=\ns(this.marginBottom,c.legendHeight-h+f+a[2]);this.extraBottomMargin&&(this.marginBottom+=this.extraBottomMargin);this.extraTopMargin&&(this.plotTop+=this.extraTopMargin);this.hasCartesianSeries&&n(this.axes,function(a){a.getOffset()});u(d[3])||(this.plotLeft+=b[3]);u(d[0])||(this.plotTop+=b[0]);u(d[2])||(this.marginBottom+=b[2]);u(d[1])||(this.marginRight+=b[1]);this.setChartSize()},initReflow:function(){function a(a){var g=c.width||jb(d,\"width\"),h=c.height||jb(d,\"height\"),a=a?a.target:O;if(!b.hasUserSize&&\ng&&h&&(a===O||a===y)){if(g!==b.containerWidth||h!==b.containerHeight)clearTimeout(e),b.reflowTimeout=e=setTimeout(function(){if(b.container)b.setSize(g,h,!1),b.hasUserSize=null},100);b.containerWidth=g;b.containerHeight=h}}var b=this,c=b.options.chart,d=b.renderTo,e;b.reflow=a;J(O,\"resize\",a);J(b,\"destroy\",function(){aa(O,\"resize\",a)})},setSize:function(a,b,c){var d=this,e,f,g;d.isResizing+=1;g=function(){d&&z(d,\"endResize\",null,function(){d.isResizing-=1})};La(c,d);d.oldChartHeight=d.chartHeight;\nd.oldChartWidth=d.chartWidth;if(u(a))d.chartWidth=e=s(0,t(a)),d.hasUserSize=!!e;if(u(b))d.chartHeight=f=s(0,t(b));K(d.container,{width:e+\"px\",height:f+\"px\"});d.setChartSize(!0);d.renderer.setSize(e,f,c);d.maxTicks=null;n(d.axes,function(a){a.isDirty=!0;a.setScale()});n(d.series,function(a){a.isDirty=!0});d.isDirtyLegend=!0;d.isDirtyBox=!0;d.getMargins();d.redraw(c);d.oldChartHeight=null;z(d,\"resize\");Fa===!1?g():setTimeout(g,Fa&&Fa.duration||500)},setChartSize:function(a){var b=this.inverted,c=this.renderer,\nd=this.chartWidth,e=this.chartHeight,f=this.options.chart,g=this.spacing,h=this.clipOffset,i,j,k,l;this.plotLeft=i=t(this.plotLeft);this.plotTop=j=t(this.plotTop);this.plotWidth=k=s(0,t(d-i-this.marginRight));this.plotHeight=l=s(0,t(e-j-this.marginBottom));this.plotSizeX=b?l:k;this.plotSizeY=b?k:l;this.plotBorderWidth=f.plotBorderWidth||0;this.spacingBox=c.spacingBox={x:g[3],y:g[0],width:d-g[3]-g[1],height:e-g[0]-g[2]};this.plotBox=c.plotBox={x:i,y:j,width:k,height:l};d=2*P(this.plotBorderWidth/2);\nb=xa(s(d,h[3])/2);c=xa(s(d,h[0])/2);this.clipBox={x:b,y:c,width:P(this.plotSizeX-s(d,h[1])/2-b),height:P(this.plotSizeY-s(d,h[2])/2-c)};a||n(this.axes,function(a){a.setAxisSize();a.setAxisTranslation()})},resetMargins:function(){var a=this.spacing,b=this.margin;this.plotTop=o(b[0],a[0]);this.marginRight=o(b[1],a[1]);this.marginBottom=o(b[2],a[2]);this.plotLeft=o(b[3],a[3]);this.axisOffset=[0,0,0,0];this.clipOffset=[0,0,0,0]},drawChartBox:function(){var a=this.options.chart,b=this.renderer,c=this.chartWidth,\nd=this.chartHeight,e=this.chartBackground,f=this.plotBackground,g=this.plotBorder,h=this.plotBGImage,i=a.borderWidth||0,j=a.backgroundColor,k=a.plotBackgroundColor,l=a.plotBackgroundImage,m=a.plotBorderWidth||0,p,q=this.plotLeft,o=this.plotTop,n=this.plotWidth,s=this.plotHeight,t=this.plotBox,u=this.clipRect,r=this.clipBox;p=i+(a.shadow?8:0);if(i||j)if(e)e.animate(e.crisp(null,null,null,c-p,d-p));else{e={fill:j||S};if(i)e.stroke=a.borderColor,e[\"stroke-width\"]=i;this.chartBackground=b.rect(p/2,p/\n2,c-p,d-p,a.borderRadius,i).attr(e).add().shadow(a.shadow)}if(k)f?f.animate(t):this.plotBackground=b.rect(q,o,n,s,0).attr({fill:k}).add().shadow(a.plotShadow);if(l)h?h.animate(t):this.plotBGImage=b.image(l,q,o,n,s).add();u?u.animate({width:r.width,height:r.height}):this.clipRect=b.clipRect(r);if(m)g?g.animate(g.crisp(null,q,o,n,s)):this.plotBorder=b.rect(q,o,n,s,0,-m).attr({stroke:a.plotBorderColor,\"stroke-width\":m,zIndex:1}).add();this.isDirtyBox=!1},propFromSeries:function(){var a=this,b=a.options.chart,\nc,d=a.options.series,e,f;n([\"inverted\",\"angular\",\"polar\"],function(g){c=W[b.type||b.defaultSeriesType];f=a[g]||b[g]||c&&c.prototype[g];for(e=d&&d.length;!f&&e--;)(c=W[d[e].type])&&c.prototype[g]&&(f=!0);a[g]=f})},linkSeries:function(){var a=this,b=a.series;n(b,function(a){a.linkedSeries.length=0});n(b,function(b){var d=b.options.linkedTo;if(ea(d)&&(d=d===\":previous\"?a.series[b.index-1]:a.get(d)))d.linkedSeries.push(b),b.linkedParent=d})},render:function(){var a=this,b=a.axes,c=a.renderer,d=a.options,\ne=d.labels,f=d.credits,g;a.setTitle();a.legend=new eb(a,d.legend);a.getStacks();n(b,function(a){a.setScale()});a.getMargins();a.maxTicks=null;n(b,function(a){a.setTickPositions(!0);a.setMaxTicks()});a.adjustTickAmounts();a.getMargins();a.drawChartBox();a.hasCartesianSeries&&n(b,function(a){a.render()});if(!a.seriesGroup)a.seriesGroup=c.g(\"series-group\").attr({zIndex:3}).add();n(a.series,function(a){a.translate();a.setTooltipPoints();a.render()});e.items&&n(e.items,function(b){var d=r(e.style,b.style),\nf=C(d.left)+a.plotLeft,g=C(d.top)+a.plotTop+12;delete d.left;delete d.top;c.text(b.html,f,g).attr({zIndex:2}).css(d).add()});if(f.enabled&&!a.credits)g=f.href,a.credits=c.text(f.text,0,0).on(\"click\",function(){if(g)location.href=g}).attr({align:f.position.align,zIndex:8}).css(f.style).add().align(f.position);a.hasRendered=!0},destroy:function(){var a=this,b=a.axes,c=a.series,d=a.container,e,f=d&&d.parentNode;z(a,\"destroy\");Ga[a.index]=w;a.renderTo.removeAttribute(\"data-highcharts-chart\");aa(a);for(e=\nb.length;e--;)b[e]=b[e].destroy();for(e=c.length;e--;)c[e]=c[e].destroy();n(\"title,subtitle,chartBackground,plotBackground,plotBGImage,plotBorder,seriesGroup,clipRect,credits,pointer,scroller,rangeSelector,legend,resetZoomButton,tooltip,renderer\".split(\",\"),function(b){var c=a[b];c&&c.destroy&&(a[b]=c.destroy())});if(d)d.innerHTML=\"\",aa(d),f&&Ta(d);for(e in a)delete a[e]},isReadyToRender:function(){var a=this;return!Z&&O==O.top&&y.readyState!==\"complete\"||$&&!O.canvg?($?Tb.push(function(){a.firstRender()},\na.options.global.canvasToolsURL):y.attachEvent(\"onreadystatechange\",function(){y.detachEvent(\"onreadystatechange\",a.firstRender);y.readyState===\"complete\"&&a.firstRender()}),!1):!0},firstRender:function(){var a=this,b=a.options,c=a.callback;if(a.isReadyToRender())a.getContainer(),z(a,\"init\"),a.resetMargins(),a.setChartSize(),a.propFromSeries(),a.getAxes(),n(b.series||[],function(b){a.initSeries(b)}),a.linkSeries(),z(a,\"beforeRender\"),a.pointer=new xb(a,b),a.render(),a.renderer.draw(),c&&c.apply(a,\n[a]),n(a.callbacks,function(b){b.apply(a,[a])}),a.cloneRenderTo(!0),z(a,\"load\")},splashArray:function(a,b){var c=b[a],c=T(c)?c:[c,c,c,c];return[o(b[a+\"Top\"],c[0]),o(b[a+\"Right\"],c[1]),o(b[a+\"Bottom\"],c[2]),o(b[a+\"Left\"],c[3])]}};yb.prototype.callbacks=[];var Pa=function(){};Pa.prototype={init:function(a,b,c){this.series=a;this.applyOptions(b,c);this.pointAttr={};if(a.options.colorByPoint&&(b=a.options.colors||a.chart.options.colors,this.color=this.color||b[a.colorCounter++],a.colorCounter===b.length))a.colorCounter=\n0;a.chart.pointCount++;return this},applyOptions:function(a,b){var c=this.series,d=c.pointValKey,a=Pa.prototype.optionsToObject.call(this,a);r(this,a);this.options=this.options?r(this.options,a):a;if(d)this.y=this[d];if(this.x===w&&c)this.x=b===w?c.autoIncrement():b;return this},optionsToObject:function(a){var b,c=this.series,d=c.pointArrayMap||[\"y\"],e=d.length,f=0,g=0;if(typeof a===\"number\"||a===null)b={y:a};else if(Ia(a)){b={};if(a.length>e){c=typeof a[0];if(c===\"string\")b.name=a[0];else if(c===\n\"number\")b.x=a[0];f++}for(;g<e;)b[d[g++]]=a[f++]}else if(typeof a===\"object\"){b=a;if(a.dataLabels)c._hasPointLabels=!0;if(a.marker)c._hasPointMarkers=!0}return b},destroy:function(){var a=this.series.chart,b=a.hoverPoints,c;a.pointCount--;if(b&&(this.setState(),ga(b,this),!b.length))a.hoverPoints=null;if(this===a.hoverPoint)this.onMouseOut();if(this.graphic||this.dataLabel)aa(this),this.destroyElements();this.legendItem&&a.legend.destroyItem(this);for(c in this)this[c]=null},destroyElements:function(){for(var a=\n\"graphic,dataLabel,dataLabelUpper,group,connector,shadowGroup\".split(\",\"),b,c=6;c--;)b=a[c],this[b]&&(this[b]=this[b].destroy())},getLabelConfig:function(){return{x:this.category,y:this.y,key:this.name||this.category,series:this.series,point:this,percentage:this.percentage,total:this.total||this.stackTotal}},select:function(a,b){var c=this,d=c.series,e=d.chart,a=o(a,!c.selected);c.firePointEvent(a?\"select\":\"unselect\",{accumulate:b},function(){c.selected=c.options.selected=a;d.options.data[qa(c,d.data)]=\nc.options;c.setState(a&&\"select\");b||n(e.getSelectedPoints(),function(a){if(a.selected&&a!==c)a.selected=a.options.selected=!1,d.options.data[qa(a,d.data)]=a.options,a.setState(\"\"),a.firePointEvent(\"unselect\")})})},onMouseOver:function(a){var b=this.series,c=b.chart,d=c.tooltip,e=c.hoverPoint;if(e&&e!==this)e.onMouseOut();this.firePointEvent(\"mouseOver\");d&&(!d.shared||b.noSharedTooltip)&&d.refresh(this,a);this.setState(\"hover\");c.hoverPoint=this},onMouseOut:function(){var a=this.series.chart,b=a.hoverPoints;\nif(!b||qa(this,b)===-1)this.firePointEvent(\"mouseOut\"),this.setState(),a.hoverPoint=null},tooltipFormatter:function(a){var b=this.series,c=b.tooltipOptions,d=o(c.valueDecimals,\"\"),e=c.valuePrefix||\"\",f=c.valueSuffix||\"\";n(b.pointArrayMap||[\"y\"],function(b){b=\"{point.\"+b;if(e||f)a=a.replace(b+\"}\",e+b+\"}\"+f);a=a.replace(b+\"}\",b+\":,.\"+d+\"f}\")});return Ca(a,{point:this,series:this.series})},update:function(a,b,c){var d=this,e=d.series,f=d.graphic,g,h=e.data,i=e.chart,j=e.options,b=o(b,!0);d.firePointEvent(\"update\",\n{options:a},function(){d.applyOptions(a);if(T(a)&&(e.getAttribs(),f))a.marker&&a.marker.symbol?d.graphic=f.destroy():f.attr(d.pointAttr[d.state||\"\"]);g=qa(d,h);e.xData[g]=d.x;e.yData[g]=e.toYData?e.toYData(d):d.y;e.zData[g]=d.z;j.data[g]=d.options;e.isDirty=e.isDirtyData=!0;if(!e.fixedBox&&e.hasCartesianSeries)i.isDirtyBox=!0;j.legendType===\"point\"&&i.legend.destroyItem(d);b&&i.redraw(c)})},remove:function(a,b){var c=this,d=c.series,e=d.points,f=d.chart,g,h=d.data;La(b,f);a=o(a,!0);c.firePointEvent(\"remove\",\nnull,function(){g=qa(c,h);h.length===e.length&&e.splice(g,1);h.splice(g,1);d.options.data.splice(g,1);d.xData.splice(g,1);d.yData.splice(g,1);d.zData.splice(g,1);c.destroy();d.isDirty=!0;d.isDirtyData=!0;a&&f.redraw()})},firePointEvent:function(a,b,c){var d=this,e=this.series.options;(e.point.events[a]||d.options&&d.options.events&&d.options.events[a])&&this.importEvents();a===\"click\"&&e.allowPointSelect&&(c=function(a){d.select(null,a.ctrlKey||a.metaKey||a.shiftKey)});z(this,a,b,c)},importEvents:function(){if(!this.hasImportedEvents){var a=\nx(this.series.options.point,this.options).events,b;this.events=a;for(b in a)J(this,b,a[b]);this.hasImportedEvents=!0}},setState:function(a){var b=this.plotX,c=this.plotY,d=this.series,e=d.options.states,f=Y[d.type].marker&&d.options.marker,g=f&&!f.enabled,h=f&&f.states[a],i=h&&h.enabled===!1,j=d.stateMarkerGraphic,k=this.marker||{},l=d.chart,m=this.pointAttr,a=a||\"\";if(!(a===this.state||this.selected&&a!==\"select\"||e[a]&&e[a].enabled===!1||a&&(i||g&&!h.enabled))){if(this.graphic)e=f&&this.graphic.symbolName&&\nm[a].r,this.graphic.attr(x(m[a],e?{x:b-e,y:c-e,width:2*e,height:2*e}:{}));else{if(a&&h)e=h.radius,k=k.symbol||d.symbol,j&&j.currentSymbol!==k&&(j=j.destroy()),j?j.attr({x:b-e,y:c-e}):(d.stateMarkerGraphic=j=l.renderer.symbol(k,b-e,c-e,2*e,2*e).attr(m[a]).add(d.markerGroup),j.currentSymbol=k);if(j)j[a&&l.isInsidePlot(b,c)?\"show\":\"hide\"]()}this.state=a}}};var Q=function(){};Q.prototype={isCartesian:!0,type:\"line\",pointClass:Pa,sorted:!0,requireSorting:!0,pointAttrToOptions:{stroke:\"lineColor\",\"stroke-width\":\"lineWidth\",\nfill:\"fillColor\",r:\"radius\"},colorCounter:0,init:function(a,b){var c,d,e=a.series;this.chart=a;this.options=b=this.setOptions(b);this.linkedSeries=[];this.bindAxes();r(this,{name:b.name,state:\"\",pointAttr:{},visible:b.visible!==!1,selected:b.selected===!0});if($)b.animation=!1;d=b.events;for(c in d)J(this,c,d[c]);if(d&&d.click||b.point&&b.point.events&&b.point.events.click||b.allowPointSelect)a.runTrackerClick=!0;this.getColor();this.getSymbol();this.setData(b.data,!1);if(this.isCartesian)a.hasCartesianSeries=\n!0;e.push(this);this._i=e.length-1;Kb(e,function(a,b){return o(a.options.index,a._i)-o(b.options.index,a._i)});n(e,function(a,b){a.index=b;a.name=a.name||\"Series \"+(b+1)})},bindAxes:function(){var a=this,b=a.options,c=a.chart,d;a.isCartesian&&n([\"xAxis\",\"yAxis\"],function(e){n(c[e],function(c){d=c.options;if(b[e]===d.index||b[e]!==w&&b[e]===d.id||b[e]===w&&d.index===0)c.series.push(a),a[e]=c,c.isDirty=!0});a[e]||ka(18,!0)})},autoIncrement:function(){var a=this.options,b=this.xIncrement,b=o(b,a.pointStart,\n0);this.pointInterval=o(this.pointInterval,a.pointInterval,1);this.xIncrement=b+this.pointInterval;return b},getSegments:function(){var a=-1,b=[],c,d=this.points,e=d.length;if(e)if(this.options.connectNulls){for(c=e;c--;)d[c].y===null&&d.splice(c,1);d.length&&(b=[d])}else n(d,function(c,g){c.y===null?(g>a+1&&b.push(d.slice(a+1,g)),a=g):g===e-1&&b.push(d.slice(a+1,g+1))});this.segments=b},setOptions:function(a){var b=this.chart.options,c=b.plotOptions,d=c[this.type];this.userOptions=a;a=x(d,c.series,\na);this.tooltipOptions=x(b.tooltip,a.tooltip);d.marker===null&&delete a.marker;return a},getColor:function(){var a=this.options,b=this.userOptions,c=this.chart.options.colors,d=this.chart.counters,e;e=a.color||Y[this.type].color;if(!e&&!a.colorByPoint)u(b._colorIndex)?a=b._colorIndex:(b._colorIndex=d.color,a=d.color++),e=c[a];this.color=e;d.wrapColor(c.length)},getSymbol:function(){var a=this.userOptions,b=this.options.marker,c=this.chart,d=c.options.symbols,c=c.counters;this.symbol=b.symbol;if(!this.symbol)u(a._symbolIndex)?\na=a._symbolIndex:(a._symbolIndex=c.symbol,a=c.symbol++),this.symbol=d[a];if(/^url/.test(this.symbol))b.radius=0;c.wrapSymbol(d.length)},drawLegendSymbol:function(a){var b=this.options,c=b.marker,d=a.options,e;e=d.symbolWidth;var f=this.chart.renderer,g=this.legendGroup,a=a.baseline-t(f.fontMetrics(d.itemStyle.fontSize).b*0.3);if(b.lineWidth){d={\"stroke-width\":b.lineWidth};if(b.dashStyle)d.dashstyle=b.dashStyle;this.legendLine=f.path([\"M\",0,a,\"L\",e,a]).attr(d).add(g)}if(c&&c.enabled)b=c.radius,this.legendSymbol=\ne=f.symbol(this.symbol,e/2-b,a-b,2*b,2*b).add(g),e.isMarker=!0},addPoint:function(a,b,c,d){var e=this.options,f=this.data,g=this.graph,h=this.area,i=this.chart,j=this.xData,k=this.yData,l=this.zData,m=this.names,p=g&&g.shift||0,q=e.data,s;La(d,i);c&&n([g,h,this.graphNeg,this.areaNeg],function(a){if(a)a.shift=p+1});if(h)h.isArea=!0;b=o(b,!0);d={series:this};this.pointClass.prototype.applyOptions.apply(d,[a]);g=d.x;h=j.length;if(this.requireSorting&&g<j[h-1])for(s=!0;h&&j[h-1]>g;)h--;j.splice(h,0,g);\nk.splice(h,0,this.toYData?this.toYData(d):d.y);l.splice(h,0,d.z);if(m)m[g]=d.name;q.splice(h,0,a);s&&(this.data.splice(h,0,null),this.processData());e.legendType===\"point\"&&this.generatePoints();c&&(f[0]&&f[0].remove?f[0].remove(!1):(f.shift(),j.shift(),k.shift(),l.shift(),q.shift()));this.isDirtyData=this.isDirty=!0;b&&(this.getAttribs(),i.redraw())},setData:function(a,b){var c=this.points,d=this.options,e=this.chart,f=null,g=this.xAxis,h=g&&g.categories&&!g.categories.length?[]:null,i;this.xIncrement=\nnull;this.pointRange=g&&g.categories?1:d.pointRange;this.colorCounter=0;var j=[],k=[],l=[],m=a?a.length:[];i=o(d.turboThreshold,1E3);var p=this.pointArrayMap,p=p&&p.length,q=!!this.toYData;if(i&&m>i){for(i=0;f===null&&i<m;)f=a[i],i++;if(sa(f)){f=o(d.pointStart,0);d=o(d.pointInterval,1);for(i=0;i<m;i++)j[i]=f,k[i]=a[i],f+=d;this.xIncrement=f}else if(Ia(f))if(p)for(i=0;i<m;i++)d=a[i],j[i]=d[0],k[i]=d.slice(1,p+1);else for(i=0;i<m;i++)d=a[i],j[i]=d[0],k[i]=d[1];else ka(12)}else for(i=0;i<m;i++)if(a[i]!==\nw&&(d={series:this},this.pointClass.prototype.applyOptions.apply(d,[a[i]]),j[i]=d.x,k[i]=q?this.toYData(d):d.y,l[i]=d.z,h&&d.name))h[d.x]=d.name;ea(k[0])&&ka(14,!0);this.data=[];this.options.data=a;this.xData=j;this.yData=k;this.zData=l;this.names=h;for(i=c&&c.length||0;i--;)c[i]&&c[i].destroy&&c[i].destroy();if(g)g.minRange=g.userMinRange;this.isDirty=this.isDirtyData=e.isDirtyBox=!0;o(b,!0)&&e.redraw(!1)},remove:function(a,b){var c=this,d=c.chart,a=o(a,!0);if(!c.isRemoving)c.isRemoving=!0,z(c,\"remove\",\nnull,function(){c.destroy();d.isDirtyLegend=d.isDirtyBox=!0;d.linkSeries();a&&d.redraw(b)});c.isRemoving=!1},processData:function(a){var b=this.xData,c=this.yData,d=b.length,e;e=0;var f,g,h=this.xAxis,i=this.options,j=i.cropThreshold,k=this.isCartesian;if(k&&!this.isDirty&&!h.isDirty&&!this.yAxis.isDirty&&!a)return!1;if(k&&this.sorted&&(!j||d>j||this.forceCrop))if(a=h.min,h=h.max,b[d-1]<a||b[0]>h)b=[],c=[];else if(b[0]<a||b[d-1]>h)e=this.cropData(this.xData,this.yData,a,h),b=e.xData,c=e.yData,e=e.start,\nf=!0;for(h=b.length-1;h>=0;h--)d=b[h]-b[h-1],d>0&&(g===w||d<g)?g=d:d<0&&this.requireSorting&&ka(15);this.cropped=f;this.cropStart=e;this.processedXData=b;this.processedYData=c;if(i.pointRange===null)this.pointRange=g||1;this.closestPointRange=g},cropData:function(a,b,c,d){var e=a.length,f=0,g=e,h=o(this.cropShoulder,1),i;for(i=0;i<e;i++)if(a[i]>=c){f=s(0,i-h);break}for(;i<e;i++)if(a[i]>d){g=i+h;break}return{xData:a.slice(f,g),yData:b.slice(f,g),start:f,end:g}},generatePoints:function(){var a=this.options.data,\nb=this.data,c,d=this.processedXData,e=this.processedYData,f=this.pointClass,g=d.length,h=this.cropStart||0,i,j=this.hasGroupedData,k,l=[],m;if(!b&&!j)b=[],b.length=a.length,b=this.data=b;for(m=0;m<g;m++)i=h+m,j?l[m]=(new f).init(this,[d[m]].concat(ja(e[m]))):(b[i]?k=b[i]:a[i]!==w&&(b[i]=k=(new f).init(this,a[i],d[m])),l[m]=k);if(b&&(g!==(c=b.length)||j))for(m=0;m<c;m++)if(m===h&&!j&&(m+=g),b[m])b[m].destroyElements(),b[m].plotX=w;this.data=b;this.points=l},setStackedPoints:function(){if(this.options.stacking&&\n!(this.visible!==!0&&this.chart.options.chart.ignoreHiddenSeries!==!1)){var a=this.processedXData,b=this.processedYData,c=[],d=b.length,e=this.options,f=e.threshold,g=e.stack,e=e.stacking,h=this.stackKey,i=\"-\"+h,j=this.negStacks,k=this.yAxis,l=k.stacks,m=k.oldStacks,p,q,o,n,t;for(o=0;o<d;o++){n=a[o];t=b[o];q=(p=j&&t<f)?i:h;l[q]||(l[q]={});if(!l[q][n])m[q]&&m[q][n]?(l[q][n]=m[q][n],l[q][n].total=null):l[q][n]=new Mb(k,k.options.stackLabels,p,n,g,e);q=l[q][n];q.points[this.index]=[q.cum||0];e===\"percent\"?\n(p=p?h:i,j&&l[p]&&l[p][n]?(p=l[p][n],q.total=p.total=s(p.total,q.total)+N(t)||0):q.total+=N(t)||0):q.total+=t||0;q.cum=(q.cum||0)+(t||0);q.points[this.index].push(q.cum);c[o]=q.cum}if(e===\"percent\")k.usePercentage=!0;this.stackedYData=c;k.oldStacks={}}},setPercentStacks:function(){var a=this,b=a.stackKey,c=a.yAxis.stacks;n([b,\"-\"+b],function(b){var d;for(var e=a.xData.length,f,g;e--;)if(f=a.xData[e],d=(g=c[b]&&c[b][f])&&g.points[a.index],f=d)g=g.total?100/g.total:0,f[0]=ia(f[0]*g),f[1]=ia(f[1]*g),\na.stackedYData[e]=f[1]})},getExtremes:function(){var a=this.yAxis,b=this.processedXData,c=this.stackedYData||this.processedYData,d=c.length,e=[],f=0,g=this.xAxis.getExtremes(),h=g.min,g=g.max,i,j,k,l;for(l=0;l<d;l++)if(j=b[l],k=c[l],i=k!==null&&k!==w&&(!a.isLog||k.length||k>0),j=this.getExtremesFromAll||this.cropped||(b[l+1]||j)>=h&&(b[l-1]||j)<=g,i&&j)if(i=k.length)for(;i--;)k[i]!==null&&(e[f++]=k[i]);else e[f++]=k;this.dataMin=o(void 0,Ja(e));this.dataMax=o(void 0,va(e))},translate:function(){this.processedXData||\nthis.processData();this.generatePoints();for(var a=this.options,b=a.stacking,c=this.xAxis,d=c.categories,e=this.yAxis,f=this.points,g=f.length,h=!!this.modifyValue,i=a.pointPlacement,j=i===\"between\"||sa(i),k=a.threshold,a=0;a<g;a++){var l=f[a],m=l.x,p=l.y,q=l.low,n=e.stacks[(this.negStacks&&p<k?\"-\":\"\")+this.stackKey];if(e.isLog&&p<=0)l.y=p=null;l.plotX=c.translate(m,0,0,0,1,i,this.type===\"flags\");if(b&&this.visible&&n&&n[m])n=n[m],p=n.points[this.index],q=p[0],p=p[1],q===0&&(q=o(k,e.min)),e.isLog&&\nq<=0&&(q=null),l.percentage=b===\"percent\"&&p,l.total=l.stackTotal=n.total,l.stackY=p,n.setOffset(this.pointXOffset||0,this.barW||0);l.yBottom=u(q)?e.translate(q,0,1,0,1):null;h&&(p=this.modifyValue(p,l));l.plotY=typeof p===\"number\"&&p!==Infinity?e.translate(p,0,1,0,1):w;l.clientX=j?c.translate(m,0,0,0,1):l.plotX;l.negative=l.y<(k||0);l.category=d&&d[l.x]!==w?d[l.x]:l.x}this.getSegments()},setTooltipPoints:function(a){var b=[],c,d,e=this.xAxis,f=e&&e.getExtremes(),g=e?e.tooltipLen||e.len:this.chart.plotSizeX,\nh,i,j=[];if(this.options.enableMouseTracking!==!1){if(a)this.tooltipPoints=null;n(this.segments||this.points,function(a){b=b.concat(a)});e&&e.reversed&&(b=b.reverse());this.orderTooltipPoints&&this.orderTooltipPoints(b);a=b.length;for(i=0;i<a;i++)if(e=b[i],c=e.x,c>=f.min&&c<=f.max){h=b[i+1];c=d===w?0:d+1;for(d=b[i+1]?I(s(0,P((e.clientX+(h?h.wrappedClientX||h.clientX:g))/2)),g):g;c>=0&&c<=d;)j[c++]=e}this.tooltipPoints=j}},tooltipHeaderFormatter:function(a){var b=this.tooltipOptions,c=b.xDateFormat,\nd=b.dateTimeLabelFormats,e=this.xAxis,f=e&&e.options.type===\"datetime\",b=b.headerFormat,e=e&&e.closestPointRange,g;if(f&&!c)if(e)for(g in D){if(D[g]>=e){c=d[g];break}}else c=d.day;f&&c&&sa(a.key)&&(b=b.replace(\"{point.key}\",\"{point.key:\"+c+\"}\"));return Ca(b,{point:a,series:this})},onMouseOver:function(){var a=this.chart,b=a.hoverSeries;if(b&&b!==this)b.onMouseOut();this.options.events.mouseOver&&z(this,\"mouseOver\");this.setState(\"hover\");a.hoverSeries=this},onMouseOut:function(){var a=this.options,\nb=this.chart,c=b.tooltip,d=b.hoverPoint;if(d)d.onMouseOut();this&&a.events.mouseOut&&z(this,\"mouseOut\");c&&!a.stickyTracking&&(!c.shared||this.noSharedTooltip)&&c.hide();this.setState();b.hoverSeries=null},animate:function(a){var b=this,c=b.chart,d=c.renderer,e;e=b.options.animation;var f=c.clipBox,g=c.inverted,h;if(e&&!T(e))e=Y[b.type].animation;h=\"_sharedClip\"+e.duration+e.easing;if(a)a=c[h],e=c[h+\"m\"],a||(c[h]=a=d.clipRect(r(f,{width:0})),c[h+\"m\"]=e=d.clipRect(-99,g?-c.plotLeft:-c.plotTop,99,g?\nc.chartWidth:c.chartHeight)),b.group.clip(a),b.markerGroup.clip(e),b.sharedClipKey=h;else{if(a=c[h])a.animate({width:c.plotSizeX},e),c[h+\"m\"].animate({width:c.plotSizeX+99},e);b.animate=null;b.animationTimeout=setTimeout(function(){b.afterAnimate()},e.duration)}},afterAnimate:function(){var a=this.chart,b=this.sharedClipKey,c=this.group;c&&this.options.clip!==!1&&(c.clip(a.clipRect),this.markerGroup.clip());setTimeout(function(){b&&a[b]&&(a[b]=a[b].destroy(),a[b+\"m\"]=a[b+\"m\"].destroy())},100)},drawPoints:function(){var a,\nb=this.points,c=this.chart,d,e,f,g,h,i,j,k,l=this.options.marker,m,p=this.markerGroup;if(l.enabled||this._hasPointMarkers)for(f=b.length;f--;)if(g=b[f],d=P(g.plotX),e=g.plotY,k=g.graphic,i=g.marker||{},a=l.enabled&&i.enabled===w||i.enabled,m=c.isInsidePlot(t(d),e,c.inverted),a&&e!==w&&!isNaN(e)&&g.y!==null)if(a=g.pointAttr[g.selected?\"select\":\"\"],h=a.r,i=o(i.symbol,this.symbol),j=i.indexOf(\"url\")===0,k)k.attr({visibility:m?Z?\"inherit\":\"visible\":\"hidden\"}).animate(r({x:d-h,y:e-h},k.symbolName?{width:2*\nh,height:2*h}:{}));else{if(m&&(h>0||j))g.graphic=c.renderer.symbol(i,d-h,e-h,2*h,2*h).attr(a).add(p)}else if(k)g.graphic=k.destroy()},convertAttribs:function(a,b,c,d){var e=this.pointAttrToOptions,f,g,h={},a=a||{},b=b||{},c=c||{},d=d||{};for(f in e)g=e[f],h[f]=o(a[g],b[f],c[f],d[f]);return h},getAttribs:function(){var a=this,b=a.options,c=Y[a.type].marker?b.marker:b,d=c.states,e=d.hover,f,g=a.color,h={stroke:g,fill:g},i=a.points||[],j=[],k,l=a.pointAttrToOptions,m=b.negativeColor,p=c.lineColor,q;\nb.marker?(e.radius=e.radius||c.radius+2,e.lineWidth=e.lineWidth||c.lineWidth+1):e.color=e.color||ra(e.color||g).brighten(e.brightness).get();j[\"\"]=a.convertAttribs(c,h);n([\"hover\",\"select\"],function(b){j[b]=a.convertAttribs(d[b],j[\"\"])});a.pointAttr=j;for(g=i.length;g--;){h=i[g];if((c=h.options&&h.options.marker||h.options)&&c.enabled===!1)c.radius=0;if(h.negative&&m)h.color=h.fillColor=m;f=b.colorByPoint||h.color;if(h.options)for(q in l)u(c[l[q]])&&(f=!0);if(f){c=c||{};k=[];d=c.states||{};f=d.hover=\nd.hover||{};if(!b.marker)f.color=ra(f.color||h.color).brighten(f.brightness||e.brightness).get();k[\"\"]=a.convertAttribs(r({color:h.color,fillColor:h.color,lineColor:p===null?h.color:w},c),j[\"\"]);k.hover=a.convertAttribs(d.hover,j.hover,k[\"\"]);k.select=a.convertAttribs(d.select,j.select,k[\"\"])}else k=j;h.pointAttr=k}},update:function(a,b){var c=this.chart,d=this.type,e=W[d].prototype,f,a=x(this.userOptions,{animation:!1,index:this.index,pointStart:this.xData[0]},{data:this.options.data},a);this.remove(!1);\nfor(f in e)e.hasOwnProperty(f)&&(this[f]=w);r(this,W[a.type||d].prototype);this.init(c,a);o(b,!0)&&c.redraw(!1)},destroy:function(){var a=this,b=a.chart,c=/AppleWebKit\\/533/.test(oa),d,e,f=a.data||[],g,h,i;z(a,\"destroy\");aa(a);n([\"xAxis\",\"yAxis\"],function(b){if(i=a[b])ga(i.series,a),i.isDirty=i.forceRedraw=!0,i.stacks={}});a.legendItem&&a.chart.legend.destroyItem(a);for(e=f.length;e--;)(g=f[e])&&g.destroy&&g.destroy();a.points=null;clearTimeout(a.animationTimeout);n(\"area,graph,dataLabelsGroup,group,markerGroup,tracker,graphNeg,areaNeg,posClip,negClip\".split(\",\"),\nfunction(b){a[b]&&(d=c&&b===\"group\"?\"hide\":\"destroy\",a[b][d]())});if(b.hoverSeries===a)b.hoverSeries=null;ga(b.series,a);for(h in a)delete a[h]},drawDataLabels:function(){var a=this,b=a.options.dataLabels,c=a.points,d,e,f,g;if(b.enabled||a._hasPointLabels)a.dlProcessOptions&&a.dlProcessOptions(b),g=a.plotGroup(\"dataLabelsGroup\",\"data-labels\",a.visible?\"visible\":\"hidden\",b.zIndex||6),e=b,n(c,function(c){var i,j=c.dataLabel,k,l,m=c.connector,p=!0;d=c.options&&c.options.dataLabels;i=o(d&&d.enabled,e.enabled);\nif(j&&!i)c.dataLabel=j.destroy();else if(i){b=x(e,d);i=b.rotation;k=c.getLabelConfig();f=b.format?Ca(b.format,k):b.formatter.call(k,b);b.style.color=o(b.color,b.style.color,a.color,\"black\");if(j)if(u(f))j.attr({text:f}),p=!1;else{if(c.dataLabel=j=j.destroy(),m)c.connector=m.destroy()}else if(u(f)){j={fill:b.backgroundColor,stroke:b.borderColor,\"stroke-width\":b.borderWidth,r:b.borderRadius||0,rotation:i,padding:b.padding,zIndex:1};for(l in j)j[l]===w&&delete j[l];j=c.dataLabel=a.chart.renderer[i?\"text\":\n\"label\"](f,0,-999,null,null,null,b.useHTML).attr(j).css(b.style).add(g).shadow(b.shadow)}j&&a.alignDataLabel(c,j,b,null,p)}})},alignDataLabel:function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=o(a.plotX,-999),i=o(a.plotY,-999),j=b.getBBox();if(a=this.visible&&f.isInsidePlot(a.plotX,a.plotY,g))d=r({x:g?f.plotWidth-i:h,y:t(g?f.plotHeight-h:i),width:0,height:0},d),r(c,{width:j.width,height:j.height}),c.rotation?(g={align:c.align,x:d.x+c.x+d.width/2,y:d.y+c.y+d.height/2},b[e?\"attr\":\"animate\"](g)):(b.align(c,\nnull,d),g=b.alignAttr,o(c.overflow,\"justify\")===\"justify\"?this.justifyDataLabel(b,c,g,j,d,e):o(c.crop,!0)&&(a=f.isInsidePlot(g.x,g.y)&&f.isInsidePlot(g.x+j.width,g.y+j.height)));a||b.attr({y:-999})},justifyDataLabel:function(a,b,c,d,e,f){var g=this.chart,h=b.align,i=b.verticalAlign,j,k;j=c.x;if(j<0)h===\"right\"?b.align=\"left\":b.x=-j,k=!0;j=c.x+d.width;if(j>g.plotWidth)h===\"left\"?b.align=\"right\":b.x=g.plotWidth-j,k=!0;j=c.y;if(j<0)i===\"bottom\"?b.verticalAlign=\"top\":b.y=-j,k=!0;j=c.y+d.height;if(j>g.plotHeight)i===\n\"top\"?b.verticalAlign=\"bottom\":b.y=g.plotHeight-j,k=!0;if(k)a.placed=!f,a.align(b,null,e)},getSegmentPath:function(a){var b=this,c=[],d=b.options.step;n(a,function(e,f){var g=e.plotX,h=e.plotY,i;b.getPointSpline?c.push.apply(c,b.getPointSpline(a,e,f)):(c.push(f?\"L\":\"M\"),d&&f&&(i=a[f-1],d===\"right\"?c.push(i.plotX,h):d===\"center\"?c.push((i.plotX+g)/2,i.plotY,(i.plotX+g)/2,h):c.push(g,i.plotY)),c.push(e.plotX,e.plotY))});return c},getGraphPath:function(){var a=this,b=[],c,d=[];n(a.segments,function(e){c=\na.getSegmentPath(e);e.length>1?b=b.concat(c):d.push(e[0])});a.singlePoints=d;return a.graphPath=b},drawGraph:function(){var a=this,b=this.options,c=[[\"graph\",b.lineColor||this.color]],d=b.lineWidth,e=b.dashStyle,f=this.getGraphPath(),g=b.negativeColor;g&&c.push([\"graphNeg\",g]);n(c,function(c,g){var j=c[0],k=a[j];if(k)Wa(k),k.animate({d:f});else if(d&&f.length)k={stroke:c[1],\"stroke-width\":d,zIndex:1},e?k.dashstyle=e:k[\"stroke-linecap\"]=k[\"stroke-linejoin\"]=\"round\",a[j]=a.chart.renderer.path(f).attr(k).add(a.group).shadow(!g&&\nb.shadow)})},clipNeg:function(){var a=this.options,b=this.chart,c=b.renderer,d=a.negativeColor||a.negativeFillColor,e,f=this.graph,g=this.area,h=this.posClip,i=this.negClip;e=b.chartWidth;var j=b.chartHeight,k=s(e,j),l=this.yAxis;if(d&&(f||g)){d=t(l.toPixels(a.threshold||0,!0));a={x:0,y:0,width:k,height:d};k={x:0,y:d,width:k,height:k};if(b.inverted)a.height=k.y=b.plotWidth-d,c.isVML&&(a={x:b.plotWidth-d-b.plotLeft,y:0,width:e,height:j},k={x:d+b.plotLeft-e,y:0,width:b.plotLeft+d,height:e});l.reversed?\n(b=k,e=a):(b=a,e=k);h?(h.animate(b),i.animate(e)):(this.posClip=h=c.clipRect(b),this.negClip=i=c.clipRect(e),f&&this.graphNeg&&(f.clip(h),this.graphNeg.clip(i)),g&&(g.clip(h),this.areaNeg.clip(i)))}},invertGroups:function(){function a(){var a={width:b.yAxis.len,height:b.xAxis.len};n([\"group\",\"markerGroup\"],function(c){b[c]&&b[c].attr(a).invert()})}var b=this,c=b.chart;if(b.xAxis)J(c,\"resize\",a),J(b,\"destroy\",function(){aa(c,\"resize\",a)}),a(),b.invertGroups=a},plotGroup:function(a,b,c,d,e){var f=this[a],\ng=!f;g&&(this[a]=f=this.chart.renderer.g(b).attr({visibility:c,zIndex:d||0.1}).add(e));f[g?\"attr\":\"animate\"](this.getPlotBox());return f},getPlotBox:function(){return{translateX:this.xAxis?this.xAxis.left:this.chart.plotLeft,translateY:this.yAxis?this.yAxis.top:this.chart.plotTop,scaleX:1,scaleY:1}},render:function(){var a=this.chart,b,c=this.options,d=c.animation&&!!this.animate&&a.renderer.isSVG,e=this.visible?\"visible\":\"hidden\",f=c.zIndex,g=this.hasRendered,h=a.seriesGroup;b=this.plotGroup(\"group\",\n\"series\",e,f,h);this.markerGroup=this.plotGroup(\"markerGroup\",\"markers\",e,f,h);d&&this.animate(!0);this.getAttribs();b.inverted=this.isCartesian?a.inverted:!1;this.drawGraph&&(this.drawGraph(),this.clipNeg());this.drawDataLabels();this.drawPoints();this.options.enableMouseTracking!==!1&&this.drawTracker();a.inverted&&this.invertGroups();c.clip!==!1&&!this.sharedClipKey&&!g&&b.clip(a.clipRect);d?this.animate():g||this.afterAnimate();this.isDirty=this.isDirtyData=!1;this.hasRendered=!0},redraw:function(){var a=\nthis.chart,b=this.isDirtyData,c=this.group,d=this.xAxis,e=this.yAxis;c&&(a.inverted&&c.attr({width:a.plotWidth,height:a.plotHeight}),c.animate({translateX:o(d&&d.left,a.plotLeft),translateY:o(e&&e.top,a.plotTop)}));this.translate();this.setTooltipPoints(!0);this.render();b&&z(this,\"updatedData\")},setState:function(a){var b=this.options,c=this.graph,d=this.graphNeg,e=b.states,b=b.lineWidth,a=a||\"\";if(this.state!==a)this.state=a,e[a]&&e[a].enabled===!1||(a&&(b=e[a].lineWidth||b+1),c&&!c.dashstyle&&\n(a={\"stroke-width\":b},c.attr(a),d&&d.attr(a)))},setVisible:function(a,b){var c=this,d=c.chart,e=c.legendItem,f,g=d.options.chart.ignoreHiddenSeries,h=c.visible;f=(c.visible=a=c.userOptions.visible=a===w?!h:a)?\"show\":\"hide\";n([\"group\",\"dataLabelsGroup\",\"markerGroup\",\"tracker\"],function(a){if(c[a])c[a][f]()});if(d.hoverSeries===c)c.onMouseOut();e&&d.legend.colorizeItem(c,a);c.isDirty=!0;c.options.stacking&&n(d.series,function(a){if(a.options.stacking&&a.visible)a.isDirty=!0});n(c.linkedSeries,function(b){b.setVisible(a,\n!1)});if(g)d.isDirtyBox=!0;b!==!1&&d.redraw();z(c,f)},show:function(){this.setVisible(!0)},hide:function(){this.setVisible(!1)},select:function(a){this.selected=a=a===w?!this.selected:a;if(this.checkbox)this.checkbox.checked=a;z(this,a?\"select\":\"unselect\")},drawTracker:function(){var a=this,b=a.options,c=b.trackByArea,d=[].concat(c?a.areaPath:a.graphPath),e=d.length,f=a.chart,g=f.pointer,h=f.renderer,i=f.options.tooltip.snap,j=a.tracker,k=b.cursor,l=k&&{cursor:k},k=a.singlePoints,m,p=function(){if(f.hoverSeries!==\na)a.onMouseOver()};if(e&&!c)for(m=e+1;m--;)d[m]===\"M\"&&d.splice(m+1,0,d[m+1]-i,d[m+2],\"L\"),(m&&d[m]===\"M\"||m===e)&&d.splice(m,0,\"L\",d[m-2]+i,d[m-1]);for(m=0;m<k.length;m++)e=k[m],d.push(\"M\",e.plotX-i,e.plotY,\"L\",e.plotX+i,e.plotY);j?j.attr({d:d}):(a.tracker=h.path(d).attr({\"stroke-linejoin\":\"round\",visibility:a.visible?\"visible\":\"hidden\",stroke:Qb,fill:c?Qb:S,\"stroke-width\":b.lineWidth+(c?0:2*i),zIndex:2}).add(a.group),n([a.tracker,a.markerGroup],function(a){a.addClass(\"highcharts-tracker\").on(\"mouseover\",\np).on(\"mouseout\",function(a){g.onTrackerMouseOut(a)}).css(l);if(ib)a.on(\"touchstart\",p)}))}};G=ha(Q);W.line=G;Y.area=x(X,{threshold:0});G=ha(Q,{type:\"area\",getSegments:function(){var a=[],b=[],c=[],d=this.xAxis,e=this.yAxis,f=e.stacks[this.stackKey],g={},h,i,j=this.points,k=this.options.connectNulls,l,m,p;if(this.options.stacking&&!this.cropped){for(m=0;m<j.length;m++)g[j[m].x]=j[m];for(p in f)c.push(+p);c.sort(function(a,b){return a-b});n(c,function(a){if(!k||g[a]&&g[a].y!==null)g[a]?b.push(g[a]):\n(h=d.translate(a),l=f[a].percent?f[a].total?f[a].cum*100/f[a].total:0:f[a].cum,i=e.toPixels(l,!0),b.push({y:null,plotX:h,clientX:h,plotY:i,yBottom:i,onMouseOver:pa}))});b.length&&a.push(b)}else Q.prototype.getSegments.call(this),a=this.segments;this.segments=a},getSegmentPath:function(a){var b=Q.prototype.getSegmentPath.call(this,a),c=[].concat(b),d,e=this.options;d=b.length;var f=this.yAxis.getThreshold(e.threshold),g;d===3&&c.push(\"L\",b[1],b[2]);if(e.stacking&&!this.closedStacks)for(d=a.length-\n1;d>=0;d--)g=o(a[d].yBottom,f),d<a.length-1&&e.step&&c.push(a[d+1].plotX,g),c.push(a[d].plotX,g);else this.closeSegment(c,a,f);this.areaPath=this.areaPath.concat(c);return b},closeSegment:function(a,b,c){a.push(\"L\",b[b.length-1].plotX,c,\"L\",b[0].plotX,c)},drawGraph:function(){this.areaPath=[];Q.prototype.drawGraph.apply(this);var a=this,b=this.areaPath,c=this.options,d=c.negativeColor,e=c.negativeFillColor,f=[[\"area\",this.color,c.fillColor]];(d||e)&&f.push([\"areaNeg\",d,e]);n(f,function(d){var e=d[0],\nf=a[e];f?f.animate({d:b}):a[e]=a.chart.renderer.path(b).attr({fill:o(d[2],ra(d[1]).setOpacity(o(c.fillOpacity,0.75)).get()),zIndex:0}).add(a.group)})},drawLegendSymbol:function(a,b){b.legendSymbol=this.chart.renderer.rect(0,a.baseline-11,a.options.symbolWidth,12,2).attr({zIndex:3}).add(b.legendGroup)}});W.area=G;Y.spline=x(X);F=ha(Q,{type:\"spline\",getPointSpline:function(a,b,c){var d=b.plotX,e=b.plotY,f=a[c-1],g=a[c+1],h,i,j,k;if(f&&g){a=f.plotY;j=g.plotX;var g=g.plotY,l;h=(1.5*d+f.plotX)/2.5;i=(1.5*\ne+a)/2.5;j=(1.5*d+j)/2.5;k=(1.5*e+g)/2.5;l=(k-i)*(j-d)/(j-h)+e-k;i+=l;k+=l;i>a&&i>e?(i=s(a,e),k=2*e-i):i<a&&i<e&&(i=I(a,e),k=2*e-i);k>g&&k>e?(k=s(g,e),i=2*e-k):k<g&&k<e&&(k=I(g,e),i=2*e-k);b.rightContX=j;b.rightContY=k}c?(b=[\"C\",f.rightContX||f.plotX,f.rightContY||f.plotY,h||d,i||e,d,e],f.rightContX=f.rightContY=null):b=[\"M\",d,e];return b}});W.spline=F;Y.areaspline=x(Y.area);ma=G.prototype;F=ha(F,{type:\"areaspline\",closedStacks:!0,getSegmentPath:ma.getSegmentPath,closeSegment:ma.closeSegment,drawGraph:ma.drawGraph,\ndrawLegendSymbol:ma.drawLegendSymbol});W.areaspline=F;Y.column=x(X,{borderColor:\"#FFFFFF\",borderWidth:1,borderRadius:0,groupPadding:0.2,marker:null,pointPadding:0.1,minPointLength:0,cropThreshold:50,pointRange:null,states:{hover:{brightness:0.1,shadow:!1},select:{color:\"#C0C0C0\",borderColor:\"#000000\",shadow:!1}},dataLabels:{align:null,verticalAlign:null,y:null},stickyTracking:!1,threshold:0});F=ha(Q,{type:\"column\",pointAttrToOptions:{stroke:\"borderColor\",\"stroke-width\":\"borderWidth\",fill:\"color\",\nr:\"borderRadius\"},cropShoulder:0,trackerGroups:[\"group\",\"dataLabelsGroup\"],negStacks:!0,init:function(){Q.prototype.init.apply(this,arguments);var a=this,b=a.chart;b.hasRendered&&n(b.series,function(b){if(b.type===a.type)b.isDirty=!0})},getColumnMetrics:function(){var a=this,b=a.options,c=a.xAxis,d=a.yAxis,e=c.reversed,f,g={},h,i=0;b.grouping===!1?i=1:n(a.chart.series,function(b){var c=b.options,e=b.yAxis;if(b.type===a.type&&b.visible&&d.len===e.len&&d.pos===e.pos)c.stacking?(f=b.stackKey,g[f]===\nw&&(g[f]=i++),h=g[f]):c.grouping!==!1&&(h=i++),b.columnIndex=h});var c=I(N(c.transA)*(c.ordinalSlope||b.pointRange||c.closestPointRange||1),c.len),j=c*b.groupPadding,k=(c-2*j)/i,l=b.pointWidth,b=u(l)?(k-l)/2:k*b.pointPadding,l=o(l,k-2*b);return a.columnMetrics={width:l,offset:b+(j+((e?i-(a.columnIndex||0):a.columnIndex)||0)*k-c/2)*(e?-1:1)}},translate:function(){var a=this.chart,b=this.options,c=b.borderWidth,d=this.yAxis,e=this.translatedThreshold=d.getThreshold(b.threshold),f=o(b.minPointLength,\n5),b=this.getColumnMetrics(),g=b.width,h=this.barW=xa(s(g,1+2*c)),i=this.pointXOffset=b.offset,j=-(c%2?0.5:0),k=c%2?0.5:1;a.renderer.isVML&&a.inverted&&(k+=1);Q.prototype.translate.apply(this);n(this.points,function(a){var b=o(a.yBottom,e),c=I(s(-999-b,a.plotY),d.len+999+b),n=a.plotX+i,u=h,r=I(c,b),w,c=s(c,b)-r;N(c)<f&&f&&(c=f,r=t(N(r-e)>f?b-f:e-(d.translate(a.y,0,1,0,1)<=e?f:0)));a.barX=n;a.pointWidth=g;b=N(n)<0.5;u=t(n+u)+j;n=t(n)+j;u-=n;w=N(r)<0.5;c=t(r+c)+k;r=t(r)+k;c-=r;b&&(n+=1,u-=1);w&&(r-=\n1,c+=1);a.shapeType=\"rect\";a.shapeArgs={x:n,y:r,width:u,height:c}})},getSymbol:pa,drawLegendSymbol:G.prototype.drawLegendSymbol,drawGraph:pa,drawPoints:function(){var a=this,b=a.options,c=a.chart.renderer,d;n(a.points,function(e){var f=e.plotY,g=e.graphic;if(f!==w&&!isNaN(f)&&e.y!==null)d=e.shapeArgs,g?(Wa(g),g.animate(x(d))):e.graphic=c[e.shapeType](d).attr(e.pointAttr[e.selected?\"select\":\"\"]).add(a.group).shadow(b.shadow,null,b.stacking&&!b.borderRadius);else if(g)e.graphic=g.destroy()})},drawTracker:function(){var a=\nthis,b=a.chart,c=b.pointer,d=a.options.cursor,e=d&&{cursor:d},f=function(c){var d=c.target,e;if(b.hoverSeries!==a)a.onMouseOver();for(;d&&!e;)e=d.point,d=d.parentNode;if(e!==w&&e!==b.hoverPoint)e.onMouseOver(c)};n(a.points,function(a){if(a.graphic)a.graphic.element.point=a;if(a.dataLabel)a.dataLabel.element.point=a});if(!a._hasTracking)n(a.trackerGroups,function(b){if(a[b]&&(a[b].addClass(\"highcharts-tracker\").on(\"mouseover\",f).on(\"mouseout\",function(a){c.onTrackerMouseOut(a)}).css(e),ib))a[b].on(\"touchstart\",\nf)}),a._hasTracking=!0},alignDataLabel:function(a,b,c,d,e){var f=this.chart,g=f.inverted,h=a.dlBox||a.shapeArgs,i=a.below||a.plotY>o(this.translatedThreshold,f.plotSizeY),j=o(c.inside,!!this.options.stacking);if(h&&(d=x(h),g&&(d={x:f.plotWidth-d.y-d.height,y:f.plotHeight-d.x-d.width,width:d.height,height:d.width}),!j))g?(d.x+=i?0:d.width,d.width=0):(d.y+=i?d.height:0,d.height=0);c.align=o(c.align,!g||j?\"center\":i?\"right\":\"left\");c.verticalAlign=o(c.verticalAlign,g||j?\"middle\":i?\"top\":\"bottom\");Q.prototype.alignDataLabel.call(this,\na,b,c,d,e)},animate:function(a){var b=this.yAxis,c=this.options,d=this.chart.inverted,e={};if(Z)a?(e.scaleY=0.001,a=I(b.pos+b.len,s(b.pos,b.toPixels(c.threshold))),d?e.translateX=a-b.len:e.translateY=a,this.group.attr(e)):(e.scaleY=1,e[d?\"translateX\":\"translateY\"]=b.pos,this.group.animate(e,this.options.animation),this.animate=null)},remove:function(){var a=this,b=a.chart;b.hasRendered&&n(b.series,function(b){if(b.type===a.type)b.isDirty=!0});Q.prototype.remove.apply(a,arguments)}});W.column=F;Y.bar=\nx(Y.column);ma=ha(F,{type:\"bar\",inverted:!0});W.bar=ma;Y.scatter=x(X,{lineWidth:0,tooltip:{headerFormat:'<span style=\"font-size: 10px; color:{series.color}\">{series.name}</span><br/>',pointFormat:\"x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>\",followPointer:!0},stickyTracking:!1});ma=ha(Q,{type:\"scatter\",sorted:!1,requireSorting:!1,noSharedTooltip:!0,trackerGroups:[\"markerGroup\"],drawTracker:F.prototype.drawTracker,setTooltipPoints:pa});W.scatter=ma;Y.pie=x(X,{borderColor:\"#FFFFFF\",borderWidth:1,\ncenter:[null,null],clip:!1,colorByPoint:!0,dataLabels:{distance:30,enabled:!0,formatter:function(){return this.point.name}},ignoreHiddenPoint:!0,legendType:\"point\",marker:null,size:null,showInLegend:!1,slicedOffset:10,states:{hover:{brightness:0.1,shadow:!1}},stickyTracking:!1,tooltip:{followPointer:!0}});X={type:\"pie\",isCartesian:!1,pointClass:ha(Pa,{init:function(){Pa.prototype.init.apply(this,arguments);var a=this,b;if(a.y<0)a.y=null;r(a,{visible:a.visible!==!1,name:o(a.name,\"Slice\")});b=function(b){a.slice(b.type===\n\"select\")};J(a,\"select\",b);J(a,\"unselect\",b);return a},setVisible:function(a){var b=this,c=b.series,d=c.chart,e;b.visible=b.options.visible=a=a===w?!b.visible:a;c.options.data[qa(b,c.data)]=b.options;e=a?\"show\":\"hide\";n([\"graphic\",\"dataLabel\",\"connector\",\"shadowGroup\"],function(a){if(b[a])b[a][e]()});b.legendItem&&d.legend.colorizeItem(b,a);if(!c.isDirty&&c.options.ignoreHiddenPoint)c.isDirty=!0,d.redraw()},slice:function(a,b,c){var d=this.series;La(c,d.chart);o(b,!0);this.sliced=this.options.sliced=\na=u(a)?a:!this.sliced;d.options.data[qa(this,d.data)]=this.options;a=a?this.slicedTranslation:{translateX:0,translateY:0};this.graphic.animate(a);this.shadowGroup&&this.shadowGroup.animate(a)}}),requireSorting:!1,noSharedTooltip:!0,trackerGroups:[\"group\",\"dataLabelsGroup\"],pointAttrToOptions:{stroke:\"borderColor\",\"stroke-width\":\"borderWidth\",fill:\"color\"},getColor:pa,animate:function(a){var b=this,c=b.points,d=b.startAngleRad;if(!a)n(c,function(a){var c=a.graphic,a=a.shapeArgs;c&&(c.attr({r:b.center[3]/\n2,start:d,end:d}),c.animate({r:a.r,start:a.start,end:a.end},b.options.animation))}),b.animate=null},setData:function(a,b){Q.prototype.setData.call(this,a,!1);this.processData();this.generatePoints();o(b,!0)&&this.chart.redraw()},generatePoints:function(){var a,b=0,c,d,e,f=this.options.ignoreHiddenPoint;Q.prototype.generatePoints.call(this);c=this.points;d=c.length;for(a=0;a<d;a++)e=c[a],b+=f&&!e.visible?0:e.y;this.total=b;for(a=0;a<d;a++)e=c[a],e.percentage=b>0?e.y/b*100:0,e.total=b},getCenter:function(){var a=\nthis.options,b=this.chart,c=2*(a.slicedOffset||0),d,e=b.plotWidth-2*c,f=b.plotHeight-2*c,b=a.center,a=[o(b[0],\"50%\"),o(b[1],\"50%\"),a.size||\"100%\",a.innerSize||0],g=I(e,f),h;return Na(a,function(a,b){h=/%$/.test(a);d=b<2||b===2&&h;return(h?[e,f,g,g][b]*C(a)/100:a)+(d?c:0)})},translate:function(a){this.generatePoints();var b=0,c=this.options,d=c.slicedOffset,e=d+c.borderWidth,f,g,h,i=c.startAngle||0,j=this.startAngleRad=ya/180*(i-90),i=(this.endAngleRad=ya/180*((c.endAngle||i+360)-90))-j,k=this.points,\nl=c.dataLabels.distance,c=c.ignoreHiddenPoint,m,n=k.length,o;if(!a)this.center=a=this.getCenter();this.getX=function(b,c){h=R.asin((b-a[1])/(a[2]/2+l));return a[0]+(c?-1:1)*V(h)*(a[2]/2+l)};for(m=0;m<n;m++){o=k[m];f=j+b*i;if(!c||o.visible)b+=o.percentage/100;g=j+b*i;o.shapeType=\"arc\";o.shapeArgs={x:a[0],y:a[1],r:a[2]/2,innerR:a[3]/2,start:t(f*1E3)/1E3,end:t(g*1E3)/1E3};h=(g+f)/2;h>0.75*i&&(h-=2*ya);o.slicedTranslation={translateX:t(V(h)*d),translateY:t(ca(h)*d)};f=V(h)*a[2]/2;g=ca(h)*a[2]/2;o.tooltipPos=\n[a[0]+f*0.7,a[1]+g*0.7];o.half=h<-ya/2||h>ya/2?1:0;o.angle=h;e=I(e,l/2);o.labelPos=[a[0]+f+V(h)*l,a[1]+g+ca(h)*l,a[0]+f+V(h)*e,a[1]+g+ca(h)*e,a[0]+f,a[1]+g,l<0?\"center\":o.half?\"right\":\"left\",h]}},setTooltipPoints:pa,drawGraph:null,drawPoints:function(){var a=this,b=a.chart.renderer,c,d,e=a.options.shadow,f,g;if(e&&!a.shadowGroup)a.shadowGroup=b.g(\"shadow\").add(a.group);n(a.points,function(h){d=h.graphic;g=h.shapeArgs;f=h.shadowGroup;if(e&&!f)f=h.shadowGroup=b.g(\"shadow\").add(a.shadowGroup);c=h.sliced?\nh.slicedTranslation:{translateX:0,translateY:0};f&&f.attr(c);d?d.animate(r(g,c)):h.graphic=d=b.arc(g).setRadialReference(a.center).attr(h.pointAttr[h.selected?\"select\":\"\"]).attr({\"stroke-linejoin\":\"round\"}).attr(c).add(a.group).shadow(e,f);h.visible===!1&&h.setVisible(!1)})},sortByAngle:function(a,b){a.sort(function(a,d){return a.angle!==void 0&&(d.angle-a.angle)*b})},drawDataLabels:function(){var a=this,b=a.data,c,d=a.chart,e=a.options.dataLabels,f=o(e.connectorPadding,10),g=o(e.connectorWidth,1),\nh=d.plotWidth,d=d.plotHeight,i,j,k=o(e.softConnector,!0),l=e.distance,m=a.center,p=m[2]/2,q=m[1],u=l>0,r,w,v,x,C=[[],[]],y,z,E,H,B,D=[0,0,0,0],I=function(a,b){return b.y-a.y};if(a.visible&&(e.enabled||a._hasPointLabels)){Q.prototype.drawDataLabels.apply(a);n(b,function(a){a.dataLabel&&C[a.half].push(a)});for(H=0;!x&&b[H];)x=b[H]&&b[H].dataLabel&&(b[H].dataLabel.getBBox().height||21),H++;for(H=2;H--;){var b=[],K=[],G=C[H],J=G.length,F;a.sortByAngle(G,H-0.5);if(l>0){for(B=q-p-l;B<=q+p+l;B+=x)b.push(B);\nw=b.length;if(J>w){c=[].concat(G);c.sort(I);for(B=J;B--;)c[B].rank=B;for(B=J;B--;)G[B].rank>=w&&G.splice(B,1);J=G.length}for(B=0;B<J;B++){c=G[B];v=c.labelPos;c=9999;var O,M;for(M=0;M<w;M++)O=N(b[M]-v[1]),O<c&&(c=O,F=M);if(F<B&&b[B]!==null)F=B;else for(w<J-B+F&&b[B]!==null&&(F=w-J+B);b[F]===null;)F++;K.push({i:F,y:b[F]});b[F]=null}K.sort(I)}for(B=0;B<J;B++){c=G[B];v=c.labelPos;r=c.dataLabel;E=c.visible===!1?\"hidden\":\"visible\";c=v[1];if(l>0){if(w=K.pop(),F=w.i,z=w.y,c>z&&b[F+1]!==null||c<z&&b[F-1]!==\nnull)z=c}else z=c;y=e.justify?m[0]+(H?-1:1)*(p+l):a.getX(F===0||F===b.length-1?c:z,H);r._attr={visibility:E,align:v[6]};r._pos={x:y+e.x+({left:f,right:-f}[v[6]]||0),y:z+e.y-10};r.connX=y;r.connY=z;if(this.options.size===null)w=r.width,y-w<f?D[3]=s(t(w-y+f),D[3]):y+w>h-f&&(D[1]=s(t(y+w-h+f),D[1])),z-x/2<0?D[0]=s(t(-z+x/2),D[0]):z+x/2>d&&(D[2]=s(t(z+x/2-d),D[2]))}}if(va(D)===0||this.verifyDataLabelOverflow(D))this.placeDataLabels(),u&&g&&n(this.points,function(b){i=b.connector;v=b.labelPos;if((r=b.dataLabel)&&\nr._pos)E=r._attr.visibility,y=r.connX,z=r.connY,j=k?[\"M\",y+(v[6]===\"left\"?5:-5),z,\"C\",y,z,2*v[2]-v[4],2*v[3]-v[5],v[2],v[3],\"L\",v[4],v[5]]:[\"M\",y+(v[6]===\"left\"?5:-5),z,\"L\",v[2],v[3],\"L\",v[4],v[5]],i?(i.animate({d:j}),i.attr(\"visibility\",E)):b.connector=i=a.chart.renderer.path(j).attr({\"stroke-width\":g,stroke:e.connectorColor||b.color||\"#606060\",visibility:E}).add(a.group);else if(i)b.connector=i.destroy()})}},verifyDataLabelOverflow:function(a){var b=this.center,c=this.options,d=c.center,e=c=c.minSize||\n80,f;d[0]!==null?e=s(b[2]-s(a[1],a[3]),c):(e=s(b[2]-a[1]-a[3],c),b[0]+=(a[3]-a[1])/2);d[1]!==null?e=s(I(e,b[2]-s(a[0],a[2])),c):(e=s(I(e,b[2]-a[0]-a[2]),c),b[1]+=(a[0]-a[2])/2);e<b[2]?(b[2]=e,this.translate(b),n(this.points,function(a){if(a.dataLabel)a.dataLabel._pos=null}),this.drawDataLabels()):f=!0;return f},placeDataLabels:function(){n(this.points,function(a){var a=a.dataLabel,b;if(a)(b=a._pos)?(a.attr(a._attr),a[a.moved?\"animate\":\"attr\"](b),a.moved=!0):a&&a.attr({y:-999})})},alignDataLabel:pa,\ndrawTracker:F.prototype.drawTracker,drawLegendSymbol:G.prototype.drawLegendSymbol,getSymbol:pa};X=ha(Q,X);W.pie=X;r(Highcharts,{Axis:db,Chart:yb,Color:ra,Legend:eb,Pointer:xb,Point:Pa,Tick:Ma,Tooltip:wb,Renderer:Va,Series:Q,SVGElement:wa,SVGRenderer:Ha,arrayMin:Ja,arrayMax:va,charts:Ga,dateFormat:Xa,format:Ca,pathAnim:Ab,getOptions:function(){return M},hasBidiBug:Ub,isTouchDevice:Ob,numberFormat:Aa,seriesTypes:W,setOptions:function(a){M=x(M,a);Lb();return M},addEvent:J,removeEvent:aa,createElement:U,\ndiscardElement:Ta,css:K,each:n,extend:r,map:Na,merge:x,pick:o,splat:ja,extendClass:ha,pInt:C,wrap:mb,svg:Z,canvas:$,vml:!Z&&!$,product:\"Highcharts\",version:\"3.0.6\"})})();\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/highcharts.src.js",
    "content": "// ==ClosureCompiler==\n// @compilation_level SIMPLE_OPTIMIZATIONS\n\n/**\n * @license Highcharts JS v3.0.6 (2013-10-04)\n *\n * (c) 2009-2013 Torstein Hønsi\n *\n * License: www.highcharts.com/license\n */\n\n// JSLint options:\n/*global Highcharts, document, window, navigator, setInterval, clearInterval, clearTimeout, setTimeout, location, jQuery, $, console, each, grep */\n\n(function () {\n// encapsulated variables\nvar UNDEFINED,\n\tdoc = document,\n\twin = window,\n\tmath = Math,\n\tmathRound = math.round,\n\tmathFloor = math.floor,\n\tmathCeil = math.ceil,\n\tmathMax = math.max,\n\tmathMin = math.min,\n\tmathAbs = math.abs,\n\tmathCos = math.cos,\n\tmathSin = math.sin,\n\tmathPI = math.PI,\n\tdeg2rad = mathPI * 2 / 360,\n\n\n\t// some variables\n\tuserAgent = navigator.userAgent,\n\tisOpera = win.opera,\n\tisIE = /msie/i.test(userAgent) && !isOpera,\n\tdocMode8 = doc.documentMode === 8,\n\tisWebKit = /AppleWebKit/.test(userAgent),\n\tisFirefox = /Firefox/.test(userAgent),\n\tisTouchDevice = /(Mobile|Android|Windows Phone)/.test(userAgent),\n\tSVG_NS = 'http://www.w3.org/2000/svg',\n\thasSVG = !!doc.createElementNS && !!doc.createElementNS(SVG_NS, 'svg').createSVGRect,\n\thasBidiBug = isFirefox && parseInt(userAgent.split('Firefox/')[1], 10) < 4, // issue #38\n\tuseCanVG = !hasSVG && !isIE && !!doc.createElement('canvas').getContext,\n\tRenderer,\n\thasTouch = doc.documentElement.ontouchstart !== UNDEFINED,\n\tsymbolSizes = {},\n\tidCounter = 0,\n\tgarbageBin,\n\tdefaultOptions,\n\tdateFormat, // function\n\tglobalAnimation,\n\tpathAnim,\n\ttimeUnits,\n\tnoop = function () {},\n\tcharts = [],\n\tPRODUCT = 'Highcharts',\n\tVERSION = '3.0.6',\n\n\t// some constants for frequently used strings\n\tDIV = 'div',\n\tABSOLUTE = 'absolute',\n\tRELATIVE = 'relative',\n\tHIDDEN = 'hidden',\n\tPREFIX = 'highcharts-',\n\tVISIBLE = 'visible',\n\tPX = 'px',\n\tNONE = 'none',\n\tM = 'M',\n\tL = 'L',\n\t/*\n\t * Empirical lowest possible opacities for TRACKER_FILL\n\t * IE6: 0.002\n\t * IE7: 0.002\n\t * IE8: 0.002\n\t * IE9: 0.00000000001 (unlimited)\n\t * IE10: 0.0001 (exporting only)\n\t * FF: 0.00000000001 (unlimited)\n\t * Chrome: 0.000001\n\t * Safari: 0.000001\n\t * Opera: 0.00000000001 (unlimited)\n\t */\n\tTRACKER_FILL = 'rgba(192,192,192,' + (hasSVG ? 0.0001 : 0.002) + ')', // invisible but clickable\n\t//TRACKER_FILL = 'rgba(192,192,192,0.5)',\n\tNORMAL_STATE = '',\n\tHOVER_STATE = 'hover',\n\tSELECT_STATE = 'select',\n\tMILLISECOND = 'millisecond',\n\tSECOND = 'second',\n\tMINUTE = 'minute',\n\tHOUR = 'hour',\n\tDAY = 'day',\n\tWEEK = 'week',\n\tMONTH = 'month',\n\tYEAR = 'year',\n\n\t// constants for attributes\n\tLINEAR_GRADIENT = 'linearGradient',\n\tSTOPS = 'stops',\n\tSTROKE_WIDTH = 'stroke-width',\n\n\t// time methods, changed based on whether or not UTC is used\n\tmakeTime,\n\tgetMinutes,\n\tgetHours,\n\tgetDay,\n\tgetDate,\n\tgetMonth,\n\tgetFullYear,\n\tsetMinutes,\n\tsetHours,\n\tsetDate,\n\tsetMonth,\n\tsetFullYear,\n\n\n\t// lookup over the types and the associated classes\n\tseriesTypes = {};\n\n// The Highcharts namespace\nwin.Highcharts = win.Highcharts ? error(16, true) : {};\n\n/**\n * Extend an object with the members of another\n * @param {Object} a The object to be extended\n * @param {Object} b The object to add to the first one\n */\nfunction extend(a, b) {\n\tvar n;\n\tif (!a) {\n\t\ta = {};\n\t}\n\tfor (n in b) {\n\t\ta[n] = b[n];\n\t}\n\treturn a;\n}\n\t\n/**\n * Deep merge two or more objects and return a third object.\n * Previously this function redirected to jQuery.extend(true), but this had two limitations.\n * First, it deep merged arrays, which lead to workarounds in Highcharts. Second,\n * it copied properties from extended prototypes. \n */\nfunction merge() {\n\tvar i,\n\t\tlen = arguments.length,\n\t\tret = {},\n\t\tdoCopy = function (copy, original) {\n\t\t\tvar value, key;\n\n\t\t\t// An object is replacing a primitive\n\t\t\tif (typeof copy !== 'object') {\n\t\t\t\tcopy = {};\n\t\t\t}\n\n\t\t\tfor (key in original) {\n\t\t\t\tif (original.hasOwnProperty(key)) {\n\t\t\t\t\tvalue = original[key];\n\n\t\t\t\t\t// Copy the contents of objects, but not arrays or DOM nodes\n\t\t\t\t\tif (value && typeof value === 'object' && Object.prototype.toString.call(value) !== '[object Array]'\n\t\t\t\t\t\t\t&& typeof value.nodeType !== 'number') {\n\t\t\t\t\t\tcopy[key] = doCopy(copy[key] || {}, value);\n\t\t\t\t\n\t\t\t\t\t// Primitives and arrays are copied over directly\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcopy[key] = original[key];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn copy;\n\t\t};\n\n\t// For each argument, extend the return\n\tfor (i = 0; i < len; i++) {\n\t\tret = doCopy(ret, arguments[i]);\n\t}\n\n\treturn ret;\n}\n\n/**\n * Take an array and turn into a hash with even number arguments as keys and odd numbers as\n * values. Allows creating constants for commonly used style properties, attributes etc.\n * Avoid it in performance critical situations like looping\n */\nfunction hash() {\n\tvar i = 0,\n\t\targs = arguments,\n\t\tlength = args.length,\n\t\tobj = {};\n\tfor (; i < length; i++) {\n\t\tobj[args[i++]] = args[i];\n\t}\n\treturn obj;\n}\n\n/**\n * Shortcut for parseInt\n * @param {Object} s\n * @param {Number} mag Magnitude\n */\nfunction pInt(s, mag) {\n\treturn parseInt(s, mag || 10);\n}\n\n/**\n * Check for string\n * @param {Object} s\n */\nfunction isString(s) {\n\treturn typeof s === 'string';\n}\n\n/**\n * Check for object\n * @param {Object} obj\n */\nfunction isObject(obj) {\n\treturn typeof obj === 'object';\n}\n\n/**\n * Check for array\n * @param {Object} obj\n */\nfunction isArray(obj) {\n\treturn Object.prototype.toString.call(obj) === '[object Array]';\n}\n\n/**\n * Check for number\n * @param {Object} n\n */\nfunction isNumber(n) {\n\treturn typeof n === 'number';\n}\n\nfunction log2lin(num) {\n\treturn math.log(num) / math.LN10;\n}\nfunction lin2log(num) {\n\treturn math.pow(10, num);\n}\n\n/**\n * Remove last occurence of an item from an array\n * @param {Array} arr\n * @param {Mixed} item\n */\nfunction erase(arr, item) {\n\tvar i = arr.length;\n\twhile (i--) {\n\t\tif (arr[i] === item) {\n\t\t\tarr.splice(i, 1);\n\t\t\tbreak;\n\t\t}\n\t}\n\t//return arr;\n}\n\n/**\n * Returns true if the object is not null or undefined. Like MooTools' $.defined.\n * @param {Object} obj\n */\nfunction defined(obj) {\n\treturn obj !== UNDEFINED && obj !== null;\n}\n\n/**\n * Set or get an attribute or an object of attributes. Can't use jQuery attr because\n * it attempts to set expando properties on the SVG element, which is not allowed.\n *\n * @param {Object} elem The DOM element to receive the attribute(s)\n * @param {String|Object} prop The property or an abject of key-value pairs\n * @param {String} value The value if a single property is set\n */\nfunction attr(elem, prop, value) {\n\tvar key,\n\t\tsetAttribute = 'setAttribute',\n\t\tret;\n\n\t// if the prop is a string\n\tif (isString(prop)) {\n\t\t// set the value\n\t\tif (defined(value)) {\n\n\t\t\telem[setAttribute](prop, value);\n\n\t\t// get the value\n\t\t} else if (elem && elem.getAttribute) { // elem not defined when printing pie demo...\n\t\t\tret = elem.getAttribute(prop);\n\t\t}\n\n\t// else if prop is defined, it is a hash of key/value pairs\n\t} else if (defined(prop) && isObject(prop)) {\n\t\tfor (key in prop) {\n\t\t\telem[setAttribute](key, prop[key]);\n\t\t}\n\t}\n\treturn ret;\n}\n/**\n * Check if an element is an array, and if not, make it into an array. Like\n * MooTools' $.splat.\n */\nfunction splat(obj) {\n\treturn isArray(obj) ? obj : [obj];\n}\n\n\n/**\n * Return the first value that is defined. Like MooTools' $.pick.\n */\nfunction pick() {\n\tvar args = arguments,\n\t\ti,\n\t\targ,\n\t\tlength = args.length;\n\tfor (i = 0; i < length; i++) {\n\t\targ = args[i];\n\t\tif (typeof arg !== 'undefined' && arg !== null) {\n\t\t\treturn arg;\n\t\t}\n\t}\n}\n\n/**\n * Set CSS on a given element\n * @param {Object} el\n * @param {Object} styles Style object with camel case property names\n */\nfunction css(el, styles) {\n\tif (isIE) {\n\t\tif (styles && styles.opacity !== UNDEFINED) {\n\t\t\tstyles.filter = 'alpha(opacity=' + (styles.opacity * 100) + ')';\n\t\t}\n\t}\n\textend(el.style, styles);\n}\n\n/**\n * Utility function to create element with attributes and styles\n * @param {Object} tag\n * @param {Object} attribs\n * @param {Object} styles\n * @param {Object} parent\n * @param {Object} nopad\n */\nfunction createElement(tag, attribs, styles, parent, nopad) {\n\tvar el = doc.createElement(tag);\n\tif (attribs) {\n\t\textend(el, attribs);\n\t}\n\tif (nopad) {\n\t\tcss(el, {padding: 0, border: NONE, margin: 0});\n\t}\n\tif (styles) {\n\t\tcss(el, styles);\n\t}\n\tif (parent) {\n\t\tparent.appendChild(el);\n\t}\n\treturn el;\n}\n\n/**\n * Extend a prototyped class by new members\n * @param {Object} parent\n * @param {Object} members\n */\nfunction extendClass(parent, members) {\n\tvar object = function () {};\n\tobject.prototype = new parent();\n\textend(object.prototype, members);\n\treturn object;\n}\n\n/**\n * Format a number and return a string based on input settings\n * @param {Number} number The input number to format\n * @param {Number} decimals The amount of decimals\n * @param {String} decPoint The decimal point, defaults to the one given in the lang options\n * @param {String} thousandsSep The thousands separator, defaults to the one given in the lang options\n */\nfunction numberFormat(number, decimals, decPoint, thousandsSep) {\n\tvar lang = defaultOptions.lang,\n\t\t// http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_number_format/\n\t\tn = +number || 0,\n\t\tc = decimals === -1 ?\n\t\t\t(n.toString().split('.')[1] || '').length : // preserve decimals\n\t\t\t(isNaN(decimals = mathAbs(decimals)) ? 2 : decimals),\n\t\td = decPoint === undefined ? lang.decimalPoint : decPoint,\n\t\tt = thousandsSep === undefined ? lang.thousandsSep : thousandsSep,\n\t\ts = n < 0 ? \"-\" : \"\",\n\t\ti = String(pInt(n = mathAbs(n).toFixed(c))),\n\t\tj = i.length > 3 ? i.length % 3 : 0;\n\n\treturn s + (j ? i.substr(0, j) + t : \"\") + i.substr(j).replace(/(\\d{3})(?=\\d)/g, \"$1\" + t) +\n\t\t(c ? d + mathAbs(n - i).toFixed(c).slice(2) : \"\");\n}\n\n/**\n * Pad a string to a given length by adding 0 to the beginning\n * @param {Number} number\n * @param {Number} length\n */\nfunction pad(number, length) {\n\t// Create an array of the remaining length +1 and join it with 0's\n\treturn new Array((length || 2) + 1 - String(number).length).join(0) + number;\n}\n\n/**\n * Wrap a method with extended functionality, preserving the original function\n * @param {Object} obj The context object that the method belongs to \n * @param {String} method The name of the method to extend\n * @param {Function} func A wrapper function callback. This function is called with the same arguments\n * as the original function, except that the original function is unshifted and passed as the first \n * argument. \n */\nfunction wrap(obj, method, func) {\n\tvar proceed = obj[method];\n\tobj[method] = function () {\n\t\tvar args = Array.prototype.slice.call(arguments);\n\t\targs.unshift(proceed);\n\t\treturn func.apply(this, args);\n\t};\n}\n\n/**\n * Based on http://www.php.net/manual/en/function.strftime.php\n * @param {String} format\n * @param {Number} timestamp\n * @param {Boolean} capitalize\n */\ndateFormat = function (format, timestamp, capitalize) {\n\tif (!defined(timestamp) || isNaN(timestamp)) {\n\t\treturn 'Invalid date';\n\t}\n\tformat = pick(format, '%Y-%m-%d %H:%M:%S');\n\n\tvar date = new Date(timestamp),\n\t\tkey, // used in for constuct below\n\t\t// get the basic time values\n\t\thours = date[getHours](),\n\t\tday = date[getDay](),\n\t\tdayOfMonth = date[getDate](),\n\t\tmonth = date[getMonth](),\n\t\tfullYear = date[getFullYear](),\n\t\tlang = defaultOptions.lang,\n\t\tlangWeekdays = lang.weekdays,\n\n\t\t// List all format keys. Custom formats can be added from the outside. \n\t\treplacements = extend({\n\n\t\t\t// Day\n\t\t\t'a': langWeekdays[day].substr(0, 3), // Short weekday, like 'Mon'\n\t\t\t'A': langWeekdays[day], // Long weekday, like 'Monday'\n\t\t\t'd': pad(dayOfMonth), // Two digit day of the month, 01 to 31\n\t\t\t'e': dayOfMonth, // Day of the month, 1 through 31\n\n\t\t\t// Week (none implemented)\n\t\t\t//'W': weekNumber(),\n\n\t\t\t// Month\n\t\t\t'b': lang.shortMonths[month], // Short month, like 'Jan'\n\t\t\t'B': lang.months[month], // Long month, like 'January'\n\t\t\t'm': pad(month + 1), // Two digit month number, 01 through 12\n\n\t\t\t// Year\n\t\t\t'y': fullYear.toString().substr(2, 2), // Two digits year, like 09 for 2009\n\t\t\t'Y': fullYear, // Four digits year, like 2009\n\n\t\t\t// Time\n\t\t\t'H': pad(hours), // Two digits hours in 24h format, 00 through 23\n\t\t\t'I': pad((hours % 12) || 12), // Two digits hours in 12h format, 00 through 11\n\t\t\t'l': (hours % 12) || 12, // Hours in 12h format, 1 through 12\n\t\t\t'M': pad(date[getMinutes]()), // Two digits minutes, 00 through 59\n\t\t\t'p': hours < 12 ? 'AM' : 'PM', // Upper case AM or PM\n\t\t\t'P': hours < 12 ? 'am' : 'pm', // Lower case AM or PM\n\t\t\t'S': pad(date.getSeconds()), // Two digits seconds, 00 through  59\n\t\t\t'L': pad(mathRound(timestamp % 1000), 3) // Milliseconds (naming from Ruby)\n\t\t}, Highcharts.dateFormats);\n\n\n\t// do the replaces\n\tfor (key in replacements) {\n\t\twhile (format.indexOf('%' + key) !== -1) { // regex would do it in one line, but this is faster\n\t\t\tformat = format.replace('%' + key, typeof replacements[key] === 'function' ? replacements[key](timestamp) : replacements[key]);\n\t\t}\n\t}\n\n\t// Optionally capitalize the string and return\n\treturn capitalize ? format.substr(0, 1).toUpperCase() + format.substr(1) : format;\n};\n\n/** \n * Format a single variable. Similar to sprintf, without the % prefix.\n */\nfunction formatSingle(format, val) {\n\tvar floatRegex = /f$/,\n\t\tdecRegex = /\\.([0-9])/,\n\t\tlang = defaultOptions.lang,\n\t\tdecimals;\n\n\tif (floatRegex.test(format)) { // float\n\t\tdecimals = format.match(decRegex);\n\t\tdecimals = decimals ? decimals[1] : -1;\n\t\tval = numberFormat(\n\t\t\tval,\n\t\t\tdecimals,\n\t\t\tlang.decimalPoint,\n\t\t\tformat.indexOf(',') > -1 ? lang.thousandsSep : ''\n\t\t);\n\t} else {\n\t\tval = dateFormat(format, val);\n\t}\n\treturn val;\n}\n\n/**\n * Format a string according to a subset of the rules of Python's String.format method.\n */\nfunction format(str, ctx) {\n\tvar splitter = '{',\n\t\tisInside = false,\n\t\tsegment,\n\t\tvalueAndFormat,\n\t\tpath,\n\t\ti,\n\t\tlen,\n\t\tret = [],\n\t\tval,\n\t\tindex;\n\t\n\twhile ((index = str.indexOf(splitter)) !== -1) {\n\t\t\n\t\tsegment = str.slice(0, index);\n\t\tif (isInside) { // we're on the closing bracket looking back\n\t\t\t\n\t\t\tvalueAndFormat = segment.split(':');\n\t\t\tpath = valueAndFormat.shift().split('.'); // get first and leave format\n\t\t\tlen = path.length;\n\t\t\tval = ctx;\n\n\t\t\t// Assign deeper paths\n\t\t\tfor (i = 0; i < len; i++) {\n\t\t\t\tval = val[path[i]];\n\t\t\t}\n\n\t\t\t// Format the replacement\n\t\t\tif (valueAndFormat.length) {\n\t\t\t\tval = formatSingle(valueAndFormat.join(':'), val);\n\t\t\t}\n\n\t\t\t// Push the result and advance the cursor\n\t\t\tret.push(val);\n\t\t\t\n\t\t} else {\n\t\t\tret.push(segment);\n\t\t\t\n\t\t}\n\t\tstr = str.slice(index + 1); // the rest\n\t\tisInside = !isInside; // toggle\n\t\tsplitter = isInside ? '}' : '{'; // now look for next matching bracket\n\t}\n\tret.push(str);\n\treturn ret.join('');\n}\n\n/**\n * Get the magnitude of a number\n */\nfunction getMagnitude(num) {\n\treturn math.pow(10, mathFloor(math.log(num) / math.LN10));\n}\n\n/**\n * Take an interval and normalize it to multiples of 1, 2, 2.5 and 5\n * @param {Number} interval\n * @param {Array} multiples\n * @param {Number} magnitude\n * @param {Object} options\n */\nfunction normalizeTickInterval(interval, multiples, magnitude, options) {\n\tvar normalized, i;\n\n\t// round to a tenfold of 1, 2, 2.5 or 5\n\tmagnitude = pick(magnitude, 1);\n\tnormalized = interval / magnitude;\n\n\t// multiples for a linear scale\n\tif (!multiples) {\n\t\tmultiples = [1, 2, 2.5, 5, 10];\n\n\t\t// the allowDecimals option\n\t\tif (options && options.allowDecimals === false) {\n\t\t\tif (magnitude === 1) {\n\t\t\t\tmultiples = [1, 2, 5, 10];\n\t\t\t} else if (magnitude <= 0.1) {\n\t\t\t\tmultiples = [1 / magnitude];\n\t\t\t}\n\t\t}\n\t}\n\n\t// normalize the interval to the nearest multiple\n\tfor (i = 0; i < multiples.length; i++) {\n\t\tinterval = multiples[i];\n\t\tif (normalized <= (multiples[i] + (multiples[i + 1] || multiples[i])) / 2) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// multiply back to the correct magnitude\n\tinterval *= magnitude;\n\n\treturn interval;\n}\n\n/**\n * Get a normalized tick interval for dates. Returns a configuration object with\n * unit range (interval), count and name. Used to prepare data for getTimeTicks. \n * Previously this logic was part of getTimeTicks, but as getTimeTicks now runs\n * of segments in stock charts, the normalizing logic was extracted in order to \n * prevent it for running over again for each segment having the same interval. \n * #662, #697.\n */\nfunction normalizeTimeTickInterval(tickInterval, unitsOption) {\n\tvar units = unitsOption || [[\n\t\t\t\tMILLISECOND, // unit name\n\t\t\t\t[1, 2, 5, 10, 20, 25, 50, 100, 200, 500] // allowed multiples\n\t\t\t], [\n\t\t\t\tSECOND,\n\t\t\t\t[1, 2, 5, 10, 15, 30]\n\t\t\t], [\n\t\t\t\tMINUTE,\n\t\t\t\t[1, 2, 5, 10, 15, 30]\n\t\t\t], [\n\t\t\t\tHOUR,\n\t\t\t\t[1, 2, 3, 4, 6, 8, 12]\n\t\t\t], [\n\t\t\t\tDAY,\n\t\t\t\t[1, 2]\n\t\t\t], [\n\t\t\t\tWEEK,\n\t\t\t\t[1, 2]\n\t\t\t], [\n\t\t\t\tMONTH,\n\t\t\t\t[1, 2, 3, 4, 6]\n\t\t\t], [\n\t\t\t\tYEAR,\n\t\t\t\tnull\n\t\t\t]],\n\t\tunit = units[units.length - 1], // default unit is years\n\t\tinterval = timeUnits[unit[0]],\n\t\tmultiples = unit[1],\n\t\tcount,\n\t\ti;\n\t\t\n\t// loop through the units to find the one that best fits the tickInterval\n\tfor (i = 0; i < units.length; i++) {\n\t\tunit = units[i];\n\t\tinterval = timeUnits[unit[0]];\n\t\tmultiples = unit[1];\n\n\n\t\tif (units[i + 1]) {\n\t\t\t// lessThan is in the middle between the highest multiple and the next unit.\n\t\t\tvar lessThan = (interval * multiples[multiples.length - 1] +\n\t\t\t\t\t\ttimeUnits[units[i + 1][0]]) / 2;\n\n\t\t\t// break and keep the current unit\n\t\t\tif (tickInterval <= lessThan) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// prevent 2.5 years intervals, though 25, 250 etc. are allowed\n\tif (interval === timeUnits[YEAR] && tickInterval < 5 * interval) {\n\t\tmultiples = [1, 2, 5];\n\t}\n\n\t// get the count\n\tcount = normalizeTickInterval(\n\t\ttickInterval / interval, \n\t\tmultiples,\n\t\tunit[0] === YEAR ? getMagnitude(tickInterval / interval) : 1 // #1913\n\t);\n\t\n\treturn {\n\t\tunitRange: interval,\n\t\tcount: count,\n\t\tunitName: unit[0]\n\t};\n}\n\n/**\n * Set the tick positions to a time unit that makes sense, for example\n * on the first of each month or on every Monday. Return an array\n * with the time positions. Used in datetime axes as well as for grouping\n * data on a datetime axis.\n *\n * @param {Object} normalizedInterval The interval in axis values (ms) and the count\n * @param {Number} min The minimum in axis values\n * @param {Number} max The maximum in axis values\n * @param {Number} startOfWeek\n */\nfunction getTimeTicks(normalizedInterval, min, max, startOfWeek) {\n\tvar tickPositions = [],\n\t\ti,\n\t\thigherRanks = {},\n\t\tuseUTC = defaultOptions.global.useUTC,\n\t\tminYear, // used in months and years as a basis for Date.UTC()\n\t\tminDate = new Date(min),\n\t\tinterval = normalizedInterval.unitRange,\n\t\tcount = normalizedInterval.count;\n\n\tif (defined(min)) { // #1300\n\t\tif (interval >= timeUnits[SECOND]) { // second\n\t\t\tminDate.setMilliseconds(0);\n\t\t\tminDate.setSeconds(interval >= timeUnits[MINUTE] ? 0 :\n\t\t\t\tcount * mathFloor(minDate.getSeconds() / count));\n\t\t}\n\t\n\t\tif (interval >= timeUnits[MINUTE]) { // minute\n\t\t\tminDate[setMinutes](interval >= timeUnits[HOUR] ? 0 :\n\t\t\t\tcount * mathFloor(minDate[getMinutes]() / count));\n\t\t}\n\t\n\t\tif (interval >= timeUnits[HOUR]) { // hour\n\t\t\tminDate[setHours](interval >= timeUnits[DAY] ? 0 :\n\t\t\t\tcount * mathFloor(minDate[getHours]() / count));\n\t\t}\n\t\n\t\tif (interval >= timeUnits[DAY]) { // day\n\t\t\tminDate[setDate](interval >= timeUnits[MONTH] ? 1 :\n\t\t\t\tcount * mathFloor(minDate[getDate]() / count));\n\t\t}\n\t\n\t\tif (interval >= timeUnits[MONTH]) { // month\n\t\t\tminDate[setMonth](interval >= timeUnits[YEAR] ? 0 :\n\t\t\t\tcount * mathFloor(minDate[getMonth]() / count));\n\t\t\tminYear = minDate[getFullYear]();\n\t\t}\n\t\n\t\tif (interval >= timeUnits[YEAR]) { // year\n\t\t\tminYear -= minYear % count;\n\t\t\tminDate[setFullYear](minYear);\n\t\t}\n\t\n\t\t// week is a special case that runs outside the hierarchy\n\t\tif (interval === timeUnits[WEEK]) {\n\t\t\t// get start of current week, independent of count\n\t\t\tminDate[setDate](minDate[getDate]() - minDate[getDay]() +\n\t\t\t\tpick(startOfWeek, 1));\n\t\t}\n\t\n\t\n\t\t// get tick positions\n\t\ti = 1;\n\t\tminYear = minDate[getFullYear]();\n\t\tvar time = minDate.getTime(),\n\t\t\tminMonth = minDate[getMonth](),\n\t\t\tminDateDate = minDate[getDate](),\n\t\t\ttimezoneOffset = useUTC ? \n\t\t\t\t0 : \n\t\t\t\t(24 * 3600 * 1000 + minDate.getTimezoneOffset() * 60 * 1000) % (24 * 3600 * 1000); // #950\n\t\n\t\t// iterate and add tick positions at appropriate values\n\t\twhile (time < max) {\n\t\t\ttickPositions.push(time);\n\t\n\t\t\t// if the interval is years, use Date.UTC to increase years\n\t\t\tif (interval === timeUnits[YEAR]) {\n\t\t\t\ttime = makeTime(minYear + i * count, 0);\n\t\n\t\t\t// if the interval is months, use Date.UTC to increase months\n\t\t\t} else if (interval === timeUnits[MONTH]) {\n\t\t\t\ttime = makeTime(minYear, minMonth + i * count);\n\t\n\t\t\t// if we're using global time, the interval is not fixed as it jumps\n\t\t\t// one hour at the DST crossover\n\t\t\t} else if (!useUTC && (interval === timeUnits[DAY] || interval === timeUnits[WEEK])) {\n\t\t\t\ttime = makeTime(minYear, minMonth, minDateDate +\n\t\t\t\t\ti * count * (interval === timeUnits[DAY] ? 1 : 7));\n\t\n\t\t\t// else, the interval is fixed and we use simple addition\n\t\t\t} else {\n\t\t\t\ttime += interval * count;\n\t\t\t}\n\t\n\t\t\ti++;\n\t\t}\n\t\n\t\t// push the last time\n\t\ttickPositions.push(time);\n\n\n\t\t// mark new days if the time is dividible by day (#1649, #1760)\n\t\teach(grep(tickPositions, function (time) {\n\t\t\treturn interval <= timeUnits[HOUR] && time % timeUnits[DAY] === timezoneOffset;\n\t\t}), function (time) {\n\t\t\thigherRanks[time] = DAY;\n\t\t});\n\t}\n\n\n\t// record information on the chosen unit - for dynamic label formatter\n\ttickPositions.info = extend(normalizedInterval, {\n\t\thigherRanks: higherRanks,\n\t\ttotalRange: interval * count\n\t});\n\n\treturn tickPositions;\n}\n\n/**\n * Helper class that contains variuos counters that are local to the chart.\n */\nfunction ChartCounters() {\n\tthis.color = 0;\n\tthis.symbol = 0;\n}\n\nChartCounters.prototype =  {\n\t/**\n\t * Wraps the color counter if it reaches the specified length.\n\t */\n\twrapColor: function (length) {\n\t\tif (this.color >= length) {\n\t\t\tthis.color = 0;\n\t\t}\n\t},\n\n\t/**\n\t * Wraps the symbol counter if it reaches the specified length.\n\t */\n\twrapSymbol: function (length) {\n\t\tif (this.symbol >= length) {\n\t\t\tthis.symbol = 0;\n\t\t}\n\t}\n};\n\n\n/**\n * Utility method that sorts an object array and keeping the order of equal items.\n * ECMA script standard does not specify the behaviour when items are equal.\n */\nfunction stableSort(arr, sortFunction) {\n\tvar length = arr.length,\n\t\tsortValue,\n\t\ti;\n\n\t// Add index to each item\n\tfor (i = 0; i < length; i++) {\n\t\tarr[i].ss_i = i; // stable sort index\n\t}\n\n\tarr.sort(function (a, b) {\n\t\tsortValue = sortFunction(a, b);\n\t\treturn sortValue === 0 ? a.ss_i - b.ss_i : sortValue;\n\t});\n\n\t// Remove index from items\n\tfor (i = 0; i < length; i++) {\n\t\tdelete arr[i].ss_i; // stable sort index\n\t}\n}\n\n/**\n * Non-recursive method to find the lowest member of an array. Math.min raises a maximum\n * call stack size exceeded error in Chrome when trying to apply more than 150.000 points. This\n * method is slightly slower, but safe.\n */\nfunction arrayMin(data) {\n\tvar i = data.length,\n\t\tmin = data[0];\n\n\twhile (i--) {\n\t\tif (data[i] < min) {\n\t\t\tmin = data[i];\n\t\t}\n\t}\n\treturn min;\n}\n\n/**\n * Non-recursive method to find the lowest member of an array. Math.min raises a maximum\n * call stack size exceeded error in Chrome when trying to apply more than 150.000 points. This\n * method is slightly slower, but safe.\n */\nfunction arrayMax(data) {\n\tvar i = data.length,\n\t\tmax = data[0];\n\n\twhile (i--) {\n\t\tif (data[i] > max) {\n\t\t\tmax = data[i];\n\t\t}\n\t}\n\treturn max;\n}\n\n/**\n * Utility method that destroys any SVGElement or VMLElement that are properties on the given object.\n * It loops all properties and invokes destroy if there is a destroy method. The property is\n * then delete'ed.\n * @param {Object} The object to destroy properties on\n * @param {Object} Exception, do not destroy this property, only delete it.\n */\nfunction destroyObjectProperties(obj, except) {\n\tvar n;\n\tfor (n in obj) {\n\t\t// If the object is non-null and destroy is defined\n\t\tif (obj[n] && obj[n] !== except && obj[n].destroy) {\n\t\t\t// Invoke the destroy\n\t\t\tobj[n].destroy();\n\t\t}\n\n\t\t// Delete the property from the object.\n\t\tdelete obj[n];\n\t}\n}\n\n\n/**\n * Discard an element by moving it to the bin and delete\n * @param {Object} The HTML node to discard\n */\nfunction discardElement(element) {\n\t// create a garbage bin element, not part of the DOM\n\tif (!garbageBin) {\n\t\tgarbageBin = createElement(DIV);\n\t}\n\n\t// move the node and empty bin\n\tif (element) {\n\t\tgarbageBin.appendChild(element);\n\t}\n\tgarbageBin.innerHTML = '';\n}\n\n/**\n * Provide error messages for debugging, with links to online explanation \n */\nfunction error(code, stop) {\n\tvar msg = 'Highcharts error #' + code + ': www.highcharts.com/errors/' + code;\n\tif (stop) {\n\t\tthrow msg;\n\t} else if (win.console) {\n\t\tconsole.log(msg);\n\t}\n}\n\n/**\n * Fix JS round off float errors\n * @param {Number} num\n */\nfunction correctFloat(num) {\n\treturn parseFloat(\n\t\tnum.toPrecision(14)\n\t);\n}\n\n/**\n * Set the global animation to either a given value, or fall back to the\n * given chart's animation option\n * @param {Object} animation\n * @param {Object} chart\n */\nfunction setAnimation(animation, chart) {\n\tglobalAnimation = pick(animation, chart.animation);\n}\n\n/**\n * The time unit lookup\n */\n/*jslint white: true*/\ntimeUnits = hash(\n\tMILLISECOND, 1,\n\tSECOND, 1000,\n\tMINUTE, 60000,\n\tHOUR, 3600000,\n\tDAY, 24 * 3600000,\n\tWEEK, 7 * 24 * 3600000,\n\tMONTH, 31 * 24 * 3600000,\n\tYEAR, 31556952000\n);\n/*jslint white: false*/\n/**\n * Path interpolation algorithm used across adapters\n */\npathAnim = {\n\t/**\n\t * Prepare start and end values so that the path can be animated one to one\n\t */\n\tinit: function (elem, fromD, toD) {\n\t\tfromD = fromD || '';\n\t\tvar shift = elem.shift,\n\t\t\tbezier = fromD.indexOf('C') > -1,\n\t\t\tnumParams = bezier ? 7 : 3,\n\t\t\tendLength,\n\t\t\tslice,\n\t\t\ti,\n\t\t\tstart = fromD.split(' '),\n\t\t\tend = [].concat(toD), // copy\n\t\t\tstartBaseLine,\n\t\t\tendBaseLine,\n\t\t\tsixify = function (arr) { // in splines make move points have six parameters like bezier curves\n\t\t\t\ti = arr.length;\n\t\t\t\twhile (i--) {\n\t\t\t\t\tif (arr[i] === M) {\n\t\t\t\t\t\tarr.splice(i + 1, 0, arr[i + 1], arr[i + 2], arr[i + 1], arr[i + 2]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\tif (bezier) {\n\t\t\tsixify(start);\n\t\t\tsixify(end);\n\t\t}\n\n\t\t// pull out the base lines before padding\n\t\tif (elem.isArea) {\n\t\t\tstartBaseLine = start.splice(start.length - 6, 6);\n\t\t\tendBaseLine = end.splice(end.length - 6, 6);\n\t\t}\n\n\t\t// if shifting points, prepend a dummy point to the end path\n\t\tif (shift <= end.length / numParams && start.length === end.length) {\n\t\t\twhile (shift--) {\n\t\t\t\tend = [].concat(end).splice(0, numParams).concat(end);\n\t\t\t}\n\t\t}\n\t\telem.shift = 0; // reset for following animations\n\n\t\t// copy and append last point until the length matches the end length\n\t\tif (start.length) {\n\t\t\tendLength = end.length;\n\t\t\twhile (start.length < endLength) {\n\n\t\t\t\t//bezier && sixify(start);\n\t\t\t\tslice = [].concat(start).splice(start.length - numParams, numParams);\n\t\t\t\tif (bezier) { // disable first control point\n\t\t\t\t\tslice[numParams - 6] = slice[numParams - 2];\n\t\t\t\t\tslice[numParams - 5] = slice[numParams - 1];\n\t\t\t\t}\n\t\t\t\tstart = start.concat(slice);\n\t\t\t}\n\t\t}\n\n\t\tif (startBaseLine) { // append the base lines for areas\n\t\t\tstart = start.concat(startBaseLine);\n\t\t\tend = end.concat(endBaseLine);\n\t\t}\n\t\treturn [start, end];\n\t},\n\n\t/**\n\t * Interpolate each value of the path and return the array\n\t */\n\tstep: function (start, end, pos, complete) {\n\t\tvar ret = [],\n\t\t\ti = start.length,\n\t\t\tstartVal;\n\n\t\tif (pos === 1) { // land on the final path without adjustment points appended in the ends\n\t\t\tret = complete;\n\n\t\t} else if (i === end.length && pos < 1) {\n\t\t\twhile (i--) {\n\t\t\t\tstartVal = parseFloat(start[i]);\n\t\t\t\tret[i] =\n\t\t\t\t\tisNaN(startVal) ? // a letter instruction like M or L\n\t\t\t\t\t\tstart[i] :\n\t\t\t\t\t\tpos * (parseFloat(end[i] - startVal)) + startVal;\n\n\t\t\t}\n\t\t} else { // if animation is finished or length not matching, land on right value\n\t\t\tret = end;\n\t\t}\n\t\treturn ret;\n\t}\n};\n\n(function ($) {\n\t/**\n\t * The default HighchartsAdapter for jQuery\n\t */\n\twin.HighchartsAdapter = win.HighchartsAdapter || ($ && {\n\t\t\n\t\t/**\n\t\t * Initialize the adapter by applying some extensions to jQuery\n\t\t */\n\t\tinit: function (pathAnim) {\n\t\t\t\n\t\t\t// extend the animate function to allow SVG animations\n\t\t\tvar Fx = $.fx,\n\t\t\t\tStep = Fx.step,\n\t\t\t\tdSetter,\n\t\t\t\tTween = $.Tween,\n\t\t\t\tpropHooks = Tween && Tween.propHooks,\n\t\t\t\topacityHook = $.cssHooks.opacity;\n\t\t\t\n\t\t\t/*jslint unparam: true*//* allow unused param x in this function */\n\t\t\t$.extend($.easing, {\n\t\t\t\teaseOutQuad: function (x, t, b, c, d) {\n\t\t\t\t\treturn -c * (t /= d) * (t - 2) + b;\n\t\t\t\t}\n\t\t\t});\n\t\t\t/*jslint unparam: false*/\n\t\t\n\t\t\t// extend some methods to check for elem.attr, which means it is a Highcharts SVG object\n\t\t\t$.each(['cur', '_default', 'width', 'height', 'opacity'], function (i, fn) {\n\t\t\t\tvar obj = Step,\n\t\t\t\t\tbase,\n\t\t\t\t\telem;\n\t\t\t\t\t\n\t\t\t\t// Handle different parent objects\n\t\t\t\tif (fn === 'cur') {\n\t\t\t\t\tobj = Fx.prototype; // 'cur', the getter, relates to Fx.prototype\n\t\t\t\t\n\t\t\t\t} else if (fn === '_default' && Tween) { // jQuery 1.8 model\n\t\t\t\t\tobj = propHooks[fn];\n\t\t\t\t\tfn = 'set';\n\t\t\t\t}\n\t\t\n\t\t\t\t// Overwrite the method\n\t\t\t\tbase = obj[fn];\n\t\t\t\tif (base) { // step.width and step.height don't exist in jQuery < 1.7\n\t\t\n\t\t\t\t\t// create the extended function replacement\n\t\t\t\t\tobj[fn] = function (fx) {\n\t\t\n\t\t\t\t\t\t// Fx.prototype.cur does not use fx argument\n\t\t\t\t\t\tfx = i ? fx : this;\n\n\t\t\t\t\t\t// Don't run animations on textual properties like align (#1821)\n\t\t\t\t\t\tif (fx.prop === 'align') {\n\t\t\t\t\t\t\treturn;\n\t\t\t\t\t\t}\n\t\t\n\t\t\t\t\t\t// shortcut\n\t\t\t\t\t\telem = fx.elem;\n\t\t\n\t\t\t\t\t\t// Fx.prototype.cur returns the current value. The other ones are setters\n\t\t\t\t\t\t// and returning a value has no effect.\n\t\t\t\t\t\treturn elem.attr ? // is SVG element wrapper\n\t\t\t\t\t\t\telem.attr(fx.prop, fn === 'cur' ? UNDEFINED : fx.now) : // apply the SVG wrapper's method\n\t\t\t\t\t\t\tbase.apply(this, arguments); // use jQuery's built-in method\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Extend the opacity getter, needed for fading opacity with IE9 and jQuery 1.10+\n\t\t\twrap(opacityHook, 'get', function (proceed, elem, computed) {\n\t\t\t\treturn elem.attr ? (elem.opacity || 0) : proceed.call(this, elem, computed);\n\t\t\t});\n\t\t\t\n\t\t\t\n\t\t\t// Define the setter function for d (path definitions)\n\t\t\tdSetter = function (fx) {\n\t\t\t\tvar elem = fx.elem,\n\t\t\t\t\tends;\n\t\t\n\t\t\t\t// Normally start and end should be set in state == 0, but sometimes,\n\t\t\t\t// for reasons unknown, this doesn't happen. Perhaps state == 0 is skipped\n\t\t\t\t// in these cases\n\t\t\t\tif (!fx.started) {\n\t\t\t\t\tends = pathAnim.init(elem, elem.d, elem.toD);\n\t\t\t\t\tfx.start = ends[0];\n\t\t\t\t\tfx.end = ends[1];\n\t\t\t\t\tfx.started = true;\n\t\t\t\t}\n\t\t\n\t\t\n\t\t\t\t// interpolate each value of the path\n\t\t\t\telem.attr('d', pathAnim.step(fx.start, fx.end, fx.pos, elem.toD));\n\t\t\t};\n\t\t\t\n\t\t\t// jQuery 1.8 style\n\t\t\tif (Tween) {\n\t\t\t\tpropHooks.d = {\n\t\t\t\t\tset: dSetter\n\t\t\t\t};\n\t\t\t// pre 1.8\n\t\t\t} else {\n\t\t\t\t// animate paths\n\t\t\t\tStep.d = dSetter;\n\t\t\t}\n\t\t\t\n\t\t\t/**\n\t\t\t * Utility for iterating over an array. Parameters are reversed compared to jQuery.\n\t\t\t * @param {Array} arr\n\t\t\t * @param {Function} fn\n\t\t\t */\n\t\t\tthis.each = Array.prototype.forEach ?\n\t\t\t\tfunction (arr, fn) { // modern browsers\n\t\t\t\t\treturn Array.prototype.forEach.call(arr, fn);\n\t\t\t\t\t\n\t\t\t\t} : \n\t\t\t\tfunction (arr, fn) { // legacy\n\t\t\t\t\tvar i = 0, \n\t\t\t\t\t\tlen = arr.length;\n\t\t\t\t\tfor (; i < len; i++) {\n\t\t\t\t\t\tif (fn.call(arr[i], arr[i], i, arr) === false) {\n\t\t\t\t\t\t\treturn i;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t\n\t\t\t/**\n\t\t\t * Register Highcharts as a plugin in the respective framework\n\t\t\t */\n\t\t\t$.fn.highcharts = function () {\n\t\t\t\tvar constr = 'Chart', // default constructor\n\t\t\t\t\targs = arguments,\n\t\t\t\t\toptions,\n\t\t\t\t\tret,\n\t\t\t\t\tchart;\n\n\t\t\t\tif (isString(args[0])) {\n\t\t\t\t\tconstr = args[0];\n\t\t\t\t\targs = Array.prototype.slice.call(args, 1); \n\t\t\t\t}\n\t\t\t\toptions = args[0];\n\n\t\t\t\t// Create the chart\n\t\t\t\tif (options !== UNDEFINED) {\n\t\t\t\t\t/*jslint unused:false*/\n\t\t\t\t\toptions.chart = options.chart || {};\n\t\t\t\t\toptions.chart.renderTo = this[0];\n\t\t\t\t\tchart = new Highcharts[constr](options, args[1]);\n\t\t\t\t\tret = this;\n\t\t\t\t\t/*jslint unused:true*/\n\t\t\t\t}\n\n\t\t\t\t// When called without parameters or with the return argument, get a predefined chart\n\t\t\t\tif (options === UNDEFINED) {\n\t\t\t\t\tret = charts[attr(this[0], 'data-highcharts-chart')];\n\t\t\t\t}\t\n\n\t\t\t\treturn ret;\n\t\t\t};\n\n\t\t},\n\n\t\t\n\t\t/**\n\t\t * Downloads a script and executes a callback when done.\n\t\t * @param {String} scriptLocation\n\t\t * @param {Function} callback\n\t\t */\n\t\tgetScript: $.getScript,\n\t\t\n\t\t/**\n\t\t * Return the index of an item in an array, or -1 if not found\n\t\t */\n\t\tinArray: $.inArray,\n\t\t\n\t\t/**\n\t\t * A direct link to jQuery methods. MooTools and Prototype adapters must be implemented for each case of method.\n\t\t * @param {Object} elem The HTML element\n\t\t * @param {String} method Which method to run on the wrapped element\n\t\t */\n\t\tadapterRun: function (elem, method) {\n\t\t\treturn $(elem)[method]();\n\t\t},\n\t\n\t\t/**\n\t\t * Filter an array\n\t\t */\n\t\tgrep: $.grep,\n\t\n\t\t/**\n\t\t * Map an array\n\t\t * @param {Array} arr\n\t\t * @param {Function} fn\n\t\t */\n\t\tmap: function (arr, fn) {\n\t\t\t//return jQuery.map(arr, fn);\n\t\t\tvar results = [],\n\t\t\t\ti = 0,\n\t\t\t\tlen = arr.length;\n\t\t\tfor (; i < len; i++) {\n\t\t\t\tresults[i] = fn.call(arr[i], arr[i], i, arr);\n\t\t\t}\n\t\t\treturn results;\n\t\n\t\t},\n\t\n\t\t/**\n\t\t * Get the position of an element relative to the top left of the page\n\t\t */\n\t\toffset: function (el) {\n\t\t\treturn $(el).offset();\n\t\t},\n\t\n\t\t/**\n\t\t * Add an event listener\n\t\t * @param {Object} el A HTML element or custom object\n\t\t * @param {String} event The event type\n\t\t * @param {Function} fn The event handler\n\t\t */\n\t\taddEvent: function (el, event, fn) {\n\t\t\t$(el).bind(event, fn);\n\t\t},\n\t\n\t\t/**\n\t\t * Remove event added with addEvent\n\t\t * @param {Object} el The object\n\t\t * @param {String} eventType The event type. Leave blank to remove all events.\n\t\t * @param {Function} handler The function to remove\n\t\t */\n\t\tremoveEvent: function (el, eventType, handler) {\n\t\t\t// workaround for jQuery issue with unbinding custom events:\n\t\t\t// http://forum.jQuery.com/topic/javascript-error-when-unbinding-a-custom-event-using-jQuery-1-4-2\n\t\t\tvar func = doc.removeEventListener ? 'removeEventListener' : 'detachEvent';\n\t\t\tif (doc[func] && el && !el[func]) {\n\t\t\t\tel[func] = function () {};\n\t\t\t}\n\t\n\t\t\t$(el).unbind(eventType, handler);\n\t\t},\n\t\n\t\t/**\n\t\t * Fire an event on a custom object\n\t\t * @param {Object} el\n\t\t * @param {String} type\n\t\t * @param {Object} eventArguments\n\t\t * @param {Function} defaultFunction\n\t\t */\n\t\tfireEvent: function (el, type, eventArguments, defaultFunction) {\n\t\t\tvar event = $.Event(type),\n\t\t\t\tdetachedType = 'detached' + type,\n\t\t\t\tdefaultPrevented;\n\t\n\t\t\t// Remove warnings in Chrome when accessing layerX and layerY. Although Highcharts\n\t\t\t// never uses these properties, Chrome includes them in the default click event and\n\t\t\t// raises the warning when they are copied over in the extend statement below.\n\t\t\t//\n\t\t\t// To avoid problems in IE (see #1010) where we cannot delete the properties and avoid\n\t\t\t// testing if they are there (warning in chrome) the only option is to test if running IE.\n\t\t\tif (!isIE && eventArguments) {\n\t\t\t\tdelete eventArguments.layerX;\n\t\t\t\tdelete eventArguments.layerY;\n\t\t\t}\n\t\n\t\t\textend(event, eventArguments);\n\t\n\t\t\t// Prevent jQuery from triggering the object method that is named the\n\t\t\t// same as the event. For example, if the event is 'select', jQuery\n\t\t\t// attempts calling el.select and it goes into a loop.\n\t\t\tif (el[type]) {\n\t\t\t\tel[detachedType] = el[type];\n\t\t\t\tel[type] = null;\n\t\t\t}\n\t\n\t\t\t// Wrap preventDefault and stopPropagation in try/catch blocks in\n\t\t\t// order to prevent JS errors when cancelling events on non-DOM\n\t\t\t// objects. #615.\n\t\t\t/*jslint unparam: true*/\n\t\t\t$.each(['preventDefault', 'stopPropagation'], function (i, fn) {\n\t\t\t\tvar base = event[fn];\n\t\t\t\tevent[fn] = function () {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tbase.call(event);\n\t\t\t\t\t} catch (e) {\n\t\t\t\t\t\tif (fn === 'preventDefault') {\n\t\t\t\t\t\t\tdefaultPrevented = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t});\n\t\t\t/*jslint unparam: false*/\n\t\n\t\t\t// trigger it\n\t\t\t$(el).trigger(event);\n\t\n\t\t\t// attach the method\n\t\t\tif (el[detachedType]) {\n\t\t\t\tel[type] = el[detachedType];\n\t\t\t\tel[detachedType] = null;\n\t\t\t}\n\t\n\t\t\tif (defaultFunction && !event.isDefaultPrevented() && !defaultPrevented) {\n\t\t\t\tdefaultFunction(event);\n\t\t\t}\n\t\t},\n\t\t\n\t\t/**\n\t\t * Extension method needed for MooTools\n\t\t */\n\t\twashMouseEvent: function (e) {\n\t\t\tvar ret = e.originalEvent || e;\n\t\t\t\n\t\t\t// computed by jQuery, needed by IE8\n\t\t\tif (ret.pageX === UNDEFINED) { // #1236\n\t\t\t\tret.pageX = e.pageX;\n\t\t\t\tret.pageY = e.pageY;\n\t\t\t}\n\t\t\t\n\t\t\treturn ret;\n\t\t},\n\t\n\t\t/**\n\t\t * Animate a HTML element or SVG element wrapper\n\t\t * @param {Object} el\n\t\t * @param {Object} params\n\t\t * @param {Object} options jQuery-like animation options: duration, easing, callback\n\t\t */\n\t\tanimate: function (el, params, options) {\n\t\t\tvar $el = $(el);\n\t\t\tif (!el.style) {\n\t\t\t\tel.style = {}; // #1881\n\t\t\t}\n\t\t\tif (params.d) {\n\t\t\t\tel.toD = params.d; // keep the array form for paths, used in $.fx.step.d\n\t\t\t\tparams.d = 1; // because in jQuery, animating to an array has a different meaning\n\t\t\t}\n\t\n\t\t\t$el.stop();\n\t\t\tif (params.opacity !== UNDEFINED && el.attr) {\n\t\t\t\tparams.opacity += 'px'; // force jQuery to use same logic as width and height (#2161)\n\t\t\t}\n\t\t\t$el.animate(params, options);\n\t\n\t\t},\n\t\t/**\n\t\t * Stop running animation\n\t\t */\n\t\tstop: function (el) {\n\t\t\t$(el).stop();\n\t\t}\n\t});\n}(win.jQuery));\n\n\n// check for a custom HighchartsAdapter defined prior to this file\nvar globalAdapter = win.HighchartsAdapter,\n\tadapter = globalAdapter || {};\n\t\n// Initialize the adapter\nif (globalAdapter) {\n\tglobalAdapter.init.call(globalAdapter, pathAnim);\n}\n\n\n// Utility functions. If the HighchartsAdapter is not defined, adapter is an empty object\n// and all the utility functions will be null. In that case they are populated by the\n// default adapters below.\nvar adapterRun = adapter.adapterRun,\n\tgetScript = adapter.getScript,\n\tinArray = adapter.inArray,\n\teach = adapter.each,\n\tgrep = adapter.grep,\n\toffset = adapter.offset,\n\tmap = adapter.map,\n\taddEvent = adapter.addEvent,\n\tremoveEvent = adapter.removeEvent,\n\tfireEvent = adapter.fireEvent,\n\twashMouseEvent = adapter.washMouseEvent,\n\tanimate = adapter.animate,\n\tstop = adapter.stop;\n\n\n\n/* ****************************************************************************\n * Handle the options                                                         *\n *****************************************************************************/\nvar\n\ndefaultLabelOptions = {\n\tenabled: true,\n\t// rotation: 0,\n\t// align: 'center',\n\tx: 0,\n\ty: 15,\n\t/*formatter: function () {\n\t\treturn this.value;\n\t},*/\n\tstyle: {\n\t\tcolor: '#666',\n\t\tcursor: 'default',\n\t\tfontSize: '11px',\n\t\tlineHeight: '14px'\n\t}\n};\n\ndefaultOptions = {\n\tcolors: ['#2f7ed8', '#0d233a', '#8bbc21', '#910000', '#1aadce', '#492970',\n\t\t'#f28f43', '#77a1e5', '#c42525', '#a6c96a'],\n\tsymbols: ['circle', 'diamond', 'square', 'triangle', 'triangle-down'],\n\tlang: {\n\t\tloading: 'Loading...',\n\t\tmonths: ['January', 'February', 'March', 'April', 'May', 'June', 'July',\n\t\t\t\t'August', 'September', 'October', 'November', 'December'],\n\t\tshortMonths: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],\n\t\tweekdays: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],\n\t\tdecimalPoint: '.',\n\t\tnumericSymbols: ['k', 'M', 'G', 'T', 'P', 'E'], // SI prefixes used in axis labels\n\t\tresetZoom: 'Reset zoom',\n\t\tresetZoomTitle: 'Reset zoom level 1:1',\n\t\tthousandsSep: ','\n\t},\n\tglobal: {\n\t\tuseUTC: true,\n\t\tcanvasToolsURL: 'http://code.highcharts.com/3.0.6/modules/canvas-tools.js',\n\t\tVMLRadialGradientURL: 'http://code.highcharts.com/3.0.6/gfx/vml-radial-gradient.png'\n\t},\n\tchart: {\n\t\t//animation: true,\n\t\t//alignTicks: false,\n\t\t//reflow: true,\n\t\t//className: null,\n\t\t//events: { load, selection },\n\t\t//margin: [null],\n\t\t//marginTop: null,\n\t\t//marginRight: null,\n\t\t//marginBottom: null,\n\t\t//marginLeft: null,\n\t\tborderColor: '#4572A7',\n\t\t//borderWidth: 0,\n\t\tborderRadius: 5,\n\t\tdefaultSeriesType: 'line',\n\t\tignoreHiddenSeries: true,\n\t\t//inverted: false,\n\t\t//shadow: false,\n\t\tspacing: [10, 10, 15, 10],\n\t\t//spacingTop: 10,\n\t\t//spacingRight: 10,\n\t\t//spacingBottom: 15,\n\t\t//spacingLeft: 10,\n\t\tstyle: {\n\t\t\tfontFamily: '\"Lucida Grande\", \"Lucida Sans Unicode\", Verdana, Arial, Helvetica, sans-serif', // default font\n\t\t\tfontSize: '12px'\n\t\t},\n\t\tbackgroundColor: '#FFFFFF',\n\t\t//plotBackgroundColor: null,\n\t\tplotBorderColor: '#C0C0C0',\n\t\t//plotBorderWidth: 0,\n\t\t//plotShadow: false,\n\t\t//zoomType: ''\n\t\tresetZoomButton: {\n\t\t\ttheme: {\n\t\t\t\tzIndex: 20\n\t\t\t},\n\t\t\tposition: {\n\t\t\t\talign: 'right',\n\t\t\t\tx: -10,\n\t\t\t\t//verticalAlign: 'top',\n\t\t\t\ty: 10\n\t\t\t}\n\t\t\t// relativeTo: 'plot'\n\t\t}\n\t},\n\ttitle: {\n\t\ttext: 'Chart title',\n\t\talign: 'center',\n\t\t// floating: false,\n\t\tmargin: 15,\n\t\t// x: 0,\n\t\t// verticalAlign: 'top',\n\t\t// y: null,\n\t\tstyle: {\n\t\t\tcolor: '#274b6d',//#3E576F',\n\t\t\tfontSize: '16px'\n\t\t}\n\n\t},\n\tsubtitle: {\n\t\ttext: '',\n\t\talign: 'center',\n\t\t// floating: false\n\t\t// x: 0,\n\t\t// verticalAlign: 'top',\n\t\t// y: null,\n\t\tstyle: {\n\t\t\tcolor: '#4d759e'\n\t\t}\n\t},\n\n\tplotOptions: {\n\t\tline: { // base series options\n\t\t\tallowPointSelect: false,\n\t\t\tshowCheckbox: false,\n\t\t\tanimation: {\n\t\t\t\tduration: 1000\n\t\t\t},\n\t\t\t//connectNulls: false,\n\t\t\t//cursor: 'default',\n\t\t\t//clip: true,\n\t\t\t//dashStyle: null,\n\t\t\t//enableMouseTracking: true,\n\t\t\tevents: {},\n\t\t\t//legendIndex: 0,\n\t\t\tlineWidth: 2,\n\t\t\t//shadow: false,\n\t\t\t// stacking: null,\n\t\t\tmarker: {\n\t\t\t\tenabled: true,\n\t\t\t\t//symbol: null,\n\t\t\t\tlineWidth: 0,\n\t\t\t\tradius: 4,\n\t\t\t\tlineColor: '#FFFFFF',\n\t\t\t\t//fillColor: null,\n\t\t\t\tstates: { // states for a single point\n\t\t\t\t\thover: {\n\t\t\t\t\t\tenabled: true\n\t\t\t\t\t\t//radius: base + 2\n\t\t\t\t\t},\n\t\t\t\t\tselect: {\n\t\t\t\t\t\tfillColor: '#FFFFFF',\n\t\t\t\t\t\tlineColor: '#000000',\n\t\t\t\t\t\tlineWidth: 2\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tpoint: {\n\t\t\t\tevents: {}\n\t\t\t},\n\t\t\tdataLabels: merge(defaultLabelOptions, {\n\t\t\t\talign: 'center',\n\t\t\t\tenabled: false,\n\t\t\t\tformatter: function () {\n\t\t\t\t\treturn this.y === null ? '' : numberFormat(this.y, -1);\n\t\t\t\t},\n\t\t\t\tverticalAlign: 'bottom', // above singular point\n\t\t\t\ty: 0\n\t\t\t\t// backgroundColor: undefined,\n\t\t\t\t// borderColor: undefined,\n\t\t\t\t// borderRadius: undefined,\n\t\t\t\t// borderWidth: undefined,\n\t\t\t\t// padding: 3,\n\t\t\t\t// shadow: false\n\t\t\t}),\n\t\t\tcropThreshold: 300, // draw points outside the plot area when the number of points is less than this\n\t\t\tpointRange: 0,\n\t\t\t//pointStart: 0,\n\t\t\t//pointInterval: 1,\n\t\t\tshowInLegend: true,\n\t\t\tstates: { // states for the entire series\n\t\t\t\thover: {\n\t\t\t\t\t//enabled: false,\n\t\t\t\t\t//lineWidth: base + 1,\n\t\t\t\t\tmarker: {\n\t\t\t\t\t\t// lineWidth: base + 1,\n\t\t\t\t\t\t// radius: base + 1\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tselect: {\n\t\t\t\t\tmarker: {}\n\t\t\t\t}\n\t\t\t},\n\t\t\tstickyTracking: true\n\t\t\t//tooltip: {\n\t\t\t\t//pointFormat: '<span style=\"color:{series.color}\">{series.name}</span>: <b>{point.y}</b>'\n\t\t\t\t//valueDecimals: null,\n\t\t\t\t//xDateFormat: '%A, %b %e, %Y',\n\t\t\t\t//valuePrefix: '',\n\t\t\t\t//ySuffix: ''\t\t\t\t\n\t\t\t//}\n\t\t\t// turboThreshold: 1000\n\t\t\t// zIndex: null\n\t\t}\n\t},\n\tlabels: {\n\t\t//items: [],\n\t\tstyle: {\n\t\t\t//font: defaultFont,\n\t\t\tposition: ABSOLUTE,\n\t\t\tcolor: '#3E576F'\n\t\t}\n\t},\n\tlegend: {\n\t\tenabled: true,\n\t\talign: 'center',\n\t\t//floating: false,\n\t\tlayout: 'horizontal',\n\t\tlabelFormatter: function () {\n\t\t\treturn this.name;\n\t\t},\n\t\tborderWidth: 1,\n\t\tborderColor: '#909090',\n\t\tborderRadius: 5,\n\t\tnavigation: {\n\t\t\t// animation: true,\n\t\t\tactiveColor: '#274b6d',\n\t\t\t// arrowSize: 12\n\t\t\tinactiveColor: '#CCC'\n\t\t\t// style: {} // text styles\n\t\t},\n\t\t// margin: 10,\n\t\t// reversed: false,\n\t\tshadow: false,\n\t\t// backgroundColor: null,\n\t\t/*style: {\n\t\t\tpadding: '5px'\n\t\t},*/\n\t\titemStyle: {\n\t\t\tcursor: 'pointer',\n\t\t\tcolor: '#274b6d',\n\t\t\tfontSize: '12px'\n\t\t},\n\t\titemHoverStyle: {\n\t\t\t//cursor: 'pointer', removed as of #601\n\t\t\tcolor: '#000'\n\t\t},\n\t\titemHiddenStyle: {\n\t\t\tcolor: '#CCC'\n\t\t},\n\t\titemCheckboxStyle: {\n\t\t\tposition: ABSOLUTE,\n\t\t\twidth: '13px', // for IE precision\n\t\t\theight: '13px'\n\t\t},\n\t\t// itemWidth: undefined,\n\t\tsymbolWidth: 16,\n\t\tsymbolPadding: 5,\n\t\tverticalAlign: 'bottom',\n\t\t// width: undefined,\n\t\tx: 0,\n\t\ty: 0,\n\t\ttitle: {\n\t\t\t//text: null,\n\t\t\tstyle: {\n\t\t\t\tfontWeight: 'bold'\n\t\t\t}\n\t\t}\t\t\t\n\t},\n\n\tloading: {\n\t\t// hideDuration: 100,\n\t\tlabelStyle: {\n\t\t\tfontWeight: 'bold',\n\t\t\tposition: RELATIVE,\n\t\t\ttop: '1em'\n\t\t},\n\t\t// showDuration: 0,\n\t\tstyle: {\n\t\t\tposition: ABSOLUTE,\n\t\t\tbackgroundColor: 'white',\n\t\t\topacity: 0.5,\n\t\t\ttextAlign: 'center'\n\t\t}\n\t},\n\n\ttooltip: {\n\t\tenabled: true,\n\t\tanimation: hasSVG,\n\t\t//crosshairs: null,\n\t\tbackgroundColor: 'rgba(255, 255, 255, .85)',\n\t\tborderWidth: 1,\n\t\tborderRadius: 3,\n\t\tdateTimeLabelFormats: { \n\t\t\tmillisecond: '%A, %b %e, %H:%M:%S.%L',\n\t\t\tsecond: '%A, %b %e, %H:%M:%S',\n\t\t\tminute: '%A, %b %e, %H:%M',\n\t\t\thour: '%A, %b %e, %H:%M',\n\t\t\tday: '%A, %b %e, %Y',\n\t\t\tweek: 'Week from %A, %b %e, %Y',\n\t\t\tmonth: '%B %Y',\n\t\t\tyear: '%Y'\n\t\t},\n\t\t//formatter: defaultFormatter,\n\t\theaderFormat: '<span style=\"font-size: 10px\">{point.key}</span><br/>',\n\t\tpointFormat: '<span style=\"color:{series.color}\">{series.name}</span>: <b>{point.y}</b><br/>',\n\t\tshadow: true,\n\t\t//shared: false,\n\t\tsnap: isTouchDevice ? 25 : 10,\n\t\tstyle: {\n\t\t\tcolor: '#333333',\n\t\t\tcursor: 'default',\n\t\t\tfontSize: '12px',\n\t\t\tpadding: '8px',\n\t\t\twhiteSpace: 'nowrap'\n\t\t}\n\t\t//xDateFormat: '%A, %b %e, %Y',\n\t\t//valueDecimals: null,\n\t\t//valuePrefix: '',\n\t\t//valueSuffix: ''\n\t},\n\n\tcredits: {\n\t\tenabled: true,\n\t\ttext: 'Highcharts.com',\n\t\thref: 'http://www.highcharts.com',\n\t\tposition: {\n\t\t\talign: 'right',\n\t\t\tx: -10,\n\t\t\tverticalAlign: 'bottom',\n\t\t\ty: -5\n\t\t},\n\t\tstyle: {\n\t\t\tcursor: 'pointer',\n\t\t\tcolor: '#909090',\n\t\t\tfontSize: '9px'\n\t\t}\n\t}\n};\n\n\n\n\n// Series defaults\nvar defaultPlotOptions = defaultOptions.plotOptions,\n\tdefaultSeriesOptions = defaultPlotOptions.line;\n\n// set the default time methods\nsetTimeMethods();\n\n\n\n/**\n * Set the time methods globally based on the useUTC option. Time method can be either\n * local time or UTC (default).\n */\nfunction setTimeMethods() {\n\tvar useUTC = defaultOptions.global.useUTC,\n\t\tGET = useUTC ? 'getUTC' : 'get',\n\t\tSET = useUTC ? 'setUTC' : 'set';\n\n\tmakeTime = useUTC ? Date.UTC : function (year, month, date, hours, minutes, seconds) {\n\t\treturn new Date(\n\t\t\tyear,\n\t\t\tmonth,\n\t\t\tpick(date, 1),\n\t\t\tpick(hours, 0),\n\t\t\tpick(minutes, 0),\n\t\t\tpick(seconds, 0)\n\t\t).getTime();\n\t};\n\tgetMinutes =  GET + 'Minutes';\n\tgetHours =    GET + 'Hours';\n\tgetDay =      GET + 'Day';\n\tgetDate =     GET + 'Date';\n\tgetMonth =    GET + 'Month';\n\tgetFullYear = GET + 'FullYear';\n\tsetMinutes =  SET + 'Minutes';\n\tsetHours =    SET + 'Hours';\n\tsetDate =     SET + 'Date';\n\tsetMonth =    SET + 'Month';\n\tsetFullYear = SET + 'FullYear';\n\n}\n\n/**\n * Merge the default options with custom options and return the new options structure\n * @param {Object} options The new custom options\n */\nfunction setOptions(options) {\n\t\n\t// Pull out axis options and apply them to the respective default axis options \n\t/*defaultXAxisOptions = merge(defaultXAxisOptions, options.xAxis);\n\tdefaultYAxisOptions = merge(defaultYAxisOptions, options.yAxis);\n\toptions.xAxis = options.yAxis = UNDEFINED;*/\n\t\n\t// Merge in the default options\n\tdefaultOptions = merge(defaultOptions, options);\n\t\n\t// Apply UTC\n\tsetTimeMethods();\n\n\treturn defaultOptions;\n}\n\n/**\n * Get the updated default options. Merely exposing defaultOptions for outside modules\n * isn't enough because the setOptions method creates a new object.\n */\nfunction getOptions() {\n\treturn defaultOptions;\n}\n\n\n/**\n * Handle color operations. The object methods are chainable.\n * @param {String} input The input color in either rbga or hex format\n */\nvar Color = function (input) {\n\t// declare variables\n\tvar rgba = [], result, stops;\n\n\t/**\n\t * Parse the input color to rgba array\n\t * @param {String} input\n\t */\n\tfunction init(input) {\n\n\t\t// Gradients\n\t\tif (input && input.stops) {\n\t\t\tstops = map(input.stops, function (stop) {\n\t\t\t\treturn Color(stop[1]);\n\t\t\t});\n\n\t\t// Solid colors\n\t\t} else {\n\t\t\t// rgba\n\t\t\tresult = /rgba\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]?(?:\\.[0-9]+)?)\\s*\\)/.exec(input);\n\t\t\tif (result) {\n\t\t\t\trgba = [pInt(result[1]), pInt(result[2]), pInt(result[3]), parseFloat(result[4], 10)];\n\t\t\t} else { \n\t\t\t\t// hex\n\t\t\t\tresult = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(input);\n\t\t\t\tif (result) {\n\t\t\t\t\trgba = [pInt(result[1], 16), pInt(result[2], 16), pInt(result[3], 16), 1];\n\t\t\t\t} else {\n\t\t\t\t\t// rgb\n\t\t\t\t\tresult = /rgb\\(\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*,\\s*([0-9]{1,3})\\s*\\)/.exec(input);\n\t\t\t\t\tif (result) {\n\t\t\t\t\t\trgba = [pInt(result[1]), pInt(result[2]), pInt(result[3]), 1];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\t\t\n\n\t}\n\t/**\n\t * Return the color a specified format\n\t * @param {String} format\n\t */\n\tfunction get(format) {\n\t\tvar ret;\n\n\t\tif (stops) {\n\t\t\tret = merge(input);\n\t\t\tret.stops = [].concat(ret.stops);\n\t\t\teach(stops, function (stop, i) {\n\t\t\t\tret.stops[i] = [ret.stops[i][0], stop.get(format)];\n\t\t\t});\n\n\t\t// it's NaN if gradient colors on a column chart\n\t\t} else if (rgba && !isNaN(rgba[0])) {\n\t\t\tif (format === 'rgb') {\n\t\t\t\tret = 'rgb(' + rgba[0] + ',' + rgba[1] + ',' + rgba[2] + ')';\n\t\t\t} else if (format === 'a') {\n\t\t\t\tret = rgba[3];\n\t\t\t} else {\n\t\t\t\tret = 'rgba(' + rgba.join(',') + ')';\n\t\t\t}\n\t\t} else {\n\t\t\tret = input;\n\t\t}\n\t\treturn ret;\n\t}\n\n\t/**\n\t * Brighten the color\n\t * @param {Number} alpha\n\t */\n\tfunction brighten(alpha) {\n\t\tif (stops) {\n\t\t\teach(stops, function (stop) {\n\t\t\t\tstop.brighten(alpha);\n\t\t\t});\n\t\t\n\t\t} else if (isNumber(alpha) && alpha !== 0) {\n\t\t\tvar i;\n\t\t\tfor (i = 0; i < 3; i++) {\n\t\t\t\trgba[i] += pInt(alpha * 255);\n\n\t\t\t\tif (rgba[i] < 0) {\n\t\t\t\t\trgba[i] = 0;\n\t\t\t\t}\n\t\t\t\tif (rgba[i] > 255) {\n\t\t\t\t\trgba[i] = 255;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn this;\n\t}\n\t/**\n\t * Set the color's opacity to a given alpha value\n\t * @param {Number} alpha\n\t */\n\tfunction setOpacity(alpha) {\n\t\trgba[3] = alpha;\n\t\treturn this;\n\t}\n\n\t// initialize: parse the input\n\tinit(input);\n\n\t// public methods\n\treturn {\n\t\tget: get,\n\t\tbrighten: brighten,\n\t\trgba: rgba,\n\t\tsetOpacity: setOpacity\n\t};\n};\n\n\n/**\n * A wrapper object for SVG elements\n */\nfunction SVGElement() {}\n\nSVGElement.prototype = {\n\t/**\n\t * Initialize the SVG renderer\n\t * @param {Object} renderer\n\t * @param {String} nodeName\n\t */\n\tinit: function (renderer, nodeName) {\n\t\tvar wrapper = this;\n\t\twrapper.element = nodeName === 'span' ?\n\t\t\tcreateElement(nodeName) :\n\t\t\tdoc.createElementNS(SVG_NS, nodeName);\n\t\twrapper.renderer = renderer;\n\t\t/**\n\t\t * A collection of attribute setters. These methods, if defined, are called right before a certain\n\t\t * attribute is set on an element wrapper. Returning false prevents the default attribute\n\t\t * setter to run. Returning a value causes the default setter to set that value. Used in\n\t\t * Renderer.label.\n\t\t */\n\t\twrapper.attrSetters = {};\n\t},\n\t/**\n\t * Default base for animation\n\t */\n\topacity: 1,\n\t/**\n\t * Animate a given attribute\n\t * @param {Object} params\n\t * @param {Number} options The same options as in jQuery animation\n\t * @param {Function} complete Function to perform at the end of animation\n\t */\n\tanimate: function (params, options, complete) {\n\t\tvar animOptions = pick(options, globalAnimation, true);\n\t\tstop(this); // stop regardless of animation actually running, or reverting to .attr (#607)\n\t\tif (animOptions) {\n\t\t\tanimOptions = merge(animOptions);\n\t\t\tif (complete) { // allows using a callback with the global animation without overwriting it\n\t\t\t\tanimOptions.complete = complete;\n\t\t\t}\n\t\t\tanimate(this, params, animOptions);\n\t\t} else {\n\t\t\tthis.attr(params);\n\t\t\tif (complete) {\n\t\t\t\tcomplete();\n\t\t\t}\n\t\t}\n\t},\n\t/**\n\t * Set or get a given attribute\n\t * @param {Object|String} hash\n\t * @param {Mixed|Undefined} val\n\t */\n\tattr: function (hash, val) {\n\t\tvar wrapper = this,\n\t\t\tkey,\n\t\t\tvalue,\n\t\t\tresult,\n\t\t\ti,\n\t\t\tchild,\n\t\t\telement = wrapper.element,\n\t\t\tnodeName = element.nodeName.toLowerCase(), // Android2 requires lower for \"text\"\n\t\t\trenderer = wrapper.renderer,\n\t\t\tskipAttr,\n\t\t\ttitleNode,\n\t\t\tattrSetters = wrapper.attrSetters,\n\t\t\tshadows = wrapper.shadows,\n\t\t\thasSetSymbolSize,\n\t\t\tdoTransform,\n\t\t\tret = wrapper;\n\n\t\t// single key-value pair\n\t\tif (isString(hash) && defined(val)) {\n\t\t\tkey = hash;\n\t\t\thash = {};\n\t\t\thash[key] = val;\n\t\t}\n\n\t\t// used as a getter: first argument is a string, second is undefined\n\t\tif (isString(hash)) {\n\t\t\tkey = hash;\n\t\t\tif (nodeName === 'circle') {\n\t\t\t\tkey = { x: 'cx', y: 'cy' }[key] || key;\n\t\t\t} else if (key === 'strokeWidth') {\n\t\t\t\tkey = 'stroke-width';\n\t\t\t}\n\t\t\tret = attr(element, key) || wrapper[key] || 0;\n\t\t\tif (key !== 'd' && key !== 'visibility' && key !== 'fill') { // 'd' is string in animation step\n\t\t\t\tret = parseFloat(ret);\n\t\t\t}\n\n\t\t// setter\n\t\t} else {\n\n\t\t\tfor (key in hash) {\n\t\t\t\tskipAttr = false; // reset\n\t\t\t\tvalue = hash[key];\n\n\t\t\t\t// check for a specific attribute setter\n\t\t\t\tresult = attrSetters[key] && attrSetters[key].call(wrapper, value, key);\n\n\t\t\t\tif (result !== false) {\n\t\t\t\t\tif (result !== UNDEFINED) {\n\t\t\t\t\t\tvalue = result; // the attribute setter has returned a new value to set\n\t\t\t\t\t}\n\n\n\t\t\t\t\t// paths\n\t\t\t\t\tif (key === 'd') {\n\t\t\t\t\t\tif (value && value.join) { // join path\n\t\t\t\t\t\t\tvalue = value.join(' ');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (/(NaN| {2}|^$)/.test(value)) {\n\t\t\t\t\t\t\tvalue = 'M 0 0';\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//wrapper.d = value; // shortcut for animations\n\n\t\t\t\t\t// update child tspans x values\n\t\t\t\t\t} else if (key === 'x' && nodeName === 'text') {\n\t\t\t\t\t\tfor (i = 0; i < element.childNodes.length; i++) {\n\t\t\t\t\t\t\tchild = element.childNodes[i];\n\t\t\t\t\t\t\t// if the x values are equal, the tspan represents a linebreak\n\t\t\t\t\t\t\tif (attr(child, 'x') === attr(element, 'x')) {\n\t\t\t\t\t\t\t\t//child.setAttribute('x', value);\n\t\t\t\t\t\t\t\tattr(child, 'x', value);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t} else if (wrapper.rotation && (key === 'x' || key === 'y')) {\n\t\t\t\t\t\tdoTransform = true;\n\n\t\t\t\t\t// apply gradients\n\t\t\t\t\t} else if (key === 'fill') {\n\t\t\t\t\t\tvalue = renderer.color(value, element, key);\n\n\t\t\t\t\t// circle x and y\n\t\t\t\t\t} else if (nodeName === 'circle' && (key === 'x' || key === 'y')) {\n\t\t\t\t\t\tkey = { x: 'cx', y: 'cy' }[key] || key;\n\n\t\t\t\t\t// rectangle border radius\n\t\t\t\t\t} else if (nodeName === 'rect' && key === 'r') {\n\t\t\t\t\t\tattr(element, {\n\t\t\t\t\t\t\trx: value,\n\t\t\t\t\t\t\try: value\n\t\t\t\t\t\t});\n\t\t\t\t\t\tskipAttr = true;\n\n\t\t\t\t\t// translation and text rotation\n\t\t\t\t\t} else if (key === 'translateX' || key === 'translateY' || key === 'rotation' ||\n\t\t\t\t\t\t\tkey === 'verticalAlign' || key === 'scaleX' || key === 'scaleY') {\n\t\t\t\t\t\tdoTransform = true;\n\t\t\t\t\t\tskipAttr = true;\n\n\t\t\t\t\t// apply opacity as subnode (required by legacy WebKit and Batik)\n\t\t\t\t\t} else if (key === 'stroke') {\n\t\t\t\t\t\tvalue = renderer.color(value, element, key);\n\n\t\t\t\t\t// emulate VML's dashstyle implementation\n\t\t\t\t\t} else if (key === 'dashstyle') {\n\t\t\t\t\t\tkey = 'stroke-dasharray';\n\t\t\t\t\t\tvalue = value && value.toLowerCase();\n\t\t\t\t\t\tif (value === 'solid') {\n\t\t\t\t\t\t\tvalue = NONE;\n\t\t\t\t\t\t} else if (value) {\n\t\t\t\t\t\t\tvalue = value\n\t\t\t\t\t\t\t\t.replace('shortdashdotdot', '3,1,1,1,1,1,')\n\t\t\t\t\t\t\t\t.replace('shortdashdot', '3,1,1,1')\n\t\t\t\t\t\t\t\t.replace('shortdot', '1,1,')\n\t\t\t\t\t\t\t\t.replace('shortdash', '3,1,')\n\t\t\t\t\t\t\t\t.replace('longdash', '8,3,')\n\t\t\t\t\t\t\t\t.replace(/dot/g, '1,3,')\n\t\t\t\t\t\t\t\t.replace('dash', '4,3,')\n\t\t\t\t\t\t\t\t.replace(/,$/, '')\n\t\t\t\t\t\t\t\t.split(','); // ending comma\n\n\t\t\t\t\t\t\ti = value.length;\n\t\t\t\t\t\t\twhile (i--) {\n\t\t\t\t\t\t\t\tvalue[i] = pInt(value[i]) * pick(hash['stroke-width'], wrapper['stroke-width']);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tvalue = value.join(',');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// IE9/MooTools combo: MooTools returns objects instead of numbers and IE9 Beta 2\n\t\t\t\t\t// is unable to cast them. Test again with final IE9.\n\t\t\t\t\t} else if (key === 'width') {\n\t\t\t\t\t\tvalue = pInt(value);\n\n\t\t\t\t\t// Text alignment\n\t\t\t\t\t} else if (key === 'align') {\n\t\t\t\t\t\tkey = 'text-anchor';\n\t\t\t\t\t\tvalue = { left: 'start', center: 'middle', right: 'end' }[value];\n\n\t\t\t\t\t// Title requires a subnode, #431\n\t\t\t\t\t} else if (key === 'title') {\n\t\t\t\t\t\ttitleNode = element.getElementsByTagName('title')[0];\n\t\t\t\t\t\tif (!titleNode) {\n\t\t\t\t\t\t\ttitleNode = doc.createElementNS(SVG_NS, 'title');\n\t\t\t\t\t\t\telement.appendChild(titleNode);\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttitleNode.textContent = value;\n\t\t\t\t\t}\n\n\t\t\t\t\t// jQuery animate changes case\n\t\t\t\t\tif (key === 'strokeWidth') {\n\t\t\t\t\t\tkey = 'stroke-width';\n\t\t\t\t\t}\n\n\t\t\t\t\t// In Chrome/Win < 6 as well as Batik, the stroke attribute can't be set when the stroke-\n\t\t\t\t\t// width is 0. #1369\n\t\t\t\t\tif (key === 'stroke-width' || key === 'stroke') {\n\t\t\t\t\t\twrapper[key] = value;\n\t\t\t\t\t\t// Only apply the stroke attribute if the stroke width is defined and larger than 0\n\t\t\t\t\t\tif (wrapper.stroke && wrapper['stroke-width']) {\n\t\t\t\t\t\t\tattr(element, 'stroke', wrapper.stroke);\n\t\t\t\t\t\t\tattr(element, 'stroke-width', wrapper['stroke-width']);\n\t\t\t\t\t\t\twrapper.hasStroke = true;\n\t\t\t\t\t\t} else if (key === 'stroke-width' && value === 0 && wrapper.hasStroke) {\n\t\t\t\t\t\t\telement.removeAttribute('stroke');\n\t\t\t\t\t\t\twrapper.hasStroke = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tskipAttr = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t// symbols\n\t\t\t\t\tif (wrapper.symbolName && /^(x|y|width|height|r|start|end|innerR|anchorX|anchorY)/.test(key)) {\n\n\n\t\t\t\t\t\tif (!hasSetSymbolSize) {\n\t\t\t\t\t\t\twrapper.symbolAttr(hash);\n\t\t\t\t\t\t\thasSetSymbolSize = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tskipAttr = true;\n\t\t\t\t\t}\n\n\t\t\t\t\t// let the shadow follow the main element\n\t\t\t\t\tif (shadows && /^(width|height|visibility|x|y|d|transform|cx|cy|r)$/.test(key)) {\n\t\t\t\t\t\ti = shadows.length;\n\t\t\t\t\t\twhile (i--) {\n\t\t\t\t\t\t\tattr(\n\t\t\t\t\t\t\t\tshadows[i],\n\t\t\t\t\t\t\t\tkey,\n\t\t\t\t\t\t\t\tkey === 'height' ?\n\t\t\t\t\t\t\t\t\tmathMax(value - (shadows[i].cutHeight || 0), 0) :\n\t\t\t\t\t\t\t\t\tvalue\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// validate heights\n\t\t\t\t\tif ((key === 'width' || key === 'height') && nodeName === 'rect' && value < 0) {\n\t\t\t\t\t\tvalue = 0;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Record for animation and quick access without polling the DOM\n\t\t\t\t\twrapper[key] = value;\n\n\n\t\t\t\t\tif (key === 'text') {\n\t\t\t\t\t\t// Delete bBox memo when the text changes\n\t\t\t\t\t\tif (value !== wrapper.textStr) {\n\t\t\t\t\t\t\tdelete wrapper.bBox;\n\t\t\t\t\t\t}\n\t\t\t\t\t\twrapper.textStr = value;\n\t\t\t\t\t\tif (wrapper.added) {\n\t\t\t\t\t\t\trenderer.buildText(wrapper);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (!skipAttr) {\n\t\t\t\t\t\tattr(element, key, value);\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\t// Update transform. Do this outside the loop to prevent redundant updating for batch setting\n\t\t\t// of attributes.\n\t\t\tif (doTransform) {\n\t\t\t\twrapper.updateTransform();\n\t\t\t}\n\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\n\t/**\n\t * Add a class name to an element\n\t */\n\taddClass: function (className) {\n\t\tvar element = this.element,\n\t\t\tcurrentClassName = attr(element, 'class') || '';\n\n\t\tif (currentClassName.indexOf(className) === -1) {\n\t\t\tattr(element, 'class', currentClassName + ' ' + className);\n\t\t}\n\t\treturn this;\n\t},\n\t/* hasClass and removeClass are not (yet) needed\n\thasClass: function (className) {\n\t\treturn attr(this.element, 'class').indexOf(className) !== -1;\n\t},\n\tremoveClass: function (className) {\n\t\tattr(this.element, 'class', attr(this.element, 'class').replace(className, ''));\n\t\treturn this;\n\t},\n\t*/\n\n\t/**\n\t * If one of the symbol size affecting parameters are changed,\n\t * check all the others only once for each call to an element's\n\t * .attr() method\n\t * @param {Object} hash\n\t */\n\tsymbolAttr: function (hash) {\n\t\tvar wrapper = this;\n\n\t\teach(['x', 'y', 'r', 'start', 'end', 'width', 'height', 'innerR', 'anchorX', 'anchorY'], function (key) {\n\t\t\twrapper[key] = pick(hash[key], wrapper[key]);\n\t\t});\n\n\t\twrapper.attr({\n\t\t\td: wrapper.renderer.symbols[wrapper.symbolName](\n\t\t\t\twrapper.x,\n\t\t\t\twrapper.y,\n\t\t\t\twrapper.width,\n\t\t\t\twrapper.height,\n\t\t\t\twrapper\n\t\t\t)\n\t\t});\n\t},\n\n\t/**\n\t * Apply a clipping path to this object\n\t * @param {String} id\n\t */\n\tclip: function (clipRect) {\n\t\treturn this.attr('clip-path', clipRect ? 'url(' + this.renderer.url + '#' + clipRect.id + ')' : NONE);\n\t},\n\n\t/**\n\t * Calculate the coordinates needed for drawing a rectangle crisply and return the\n\t * calculated attributes\n\t * @param {Number} strokeWidth\n\t * @param {Number} x\n\t * @param {Number} y\n\t * @param {Number} width\n\t * @param {Number} height\n\t */\n\tcrisp: function (strokeWidth, x, y, width, height) {\n\n\t\tvar wrapper = this,\n\t\t\tkey,\n\t\t\tattribs = {},\n\t\t\tvalues = {},\n\t\t\tnormalizer;\n\n\t\tstrokeWidth = strokeWidth || wrapper.strokeWidth || (wrapper.attr && wrapper.attr('stroke-width')) || 0;\n\t\tnormalizer = mathRound(strokeWidth) % 2 / 2; // mathRound because strokeWidth can sometimes have roundoff errors\n\n\t\t// normalize for crisp edges\n\t\tvalues.x = mathFloor(x || wrapper.x || 0) + normalizer;\n\t\tvalues.y = mathFloor(y || wrapper.y || 0) + normalizer;\n\t\tvalues.width = mathFloor((width || wrapper.width || 0) - 2 * normalizer);\n\t\tvalues.height = mathFloor((height || wrapper.height || 0) - 2 * normalizer);\n\t\tvalues.strokeWidth = strokeWidth;\n\n\t\tfor (key in values) {\n\t\t\tif (wrapper[key] !== values[key]) { // only set attribute if changed\n\t\t\t\twrapper[key] = attribs[key] = values[key];\n\t\t\t}\n\t\t}\n\n\t\treturn attribs;\n\t},\n\n\t/**\n\t * Set styles for the element\n\t * @param {Object} styles\n\t */\n\tcss: function (styles) {\n\t\t/*jslint unparam: true*//* allow unused param a in the regexp function below */\n\t\tvar elemWrapper = this,\n\t\t\telem = elemWrapper.element,\n\t\t\ttextWidth = styles && styles.width && elem.nodeName.toLowerCase() === 'text',\n\t\t\tn,\n\t\t\tserializedCss = '',\n\t\t\thyphenate = function (a, b) { return '-' + b.toLowerCase(); };\n\t\t/*jslint unparam: false*/\n\n\t\t// convert legacy\n\t\tif (styles && styles.color) {\n\t\t\tstyles.fill = styles.color;\n\t\t}\n\n\t\t// Merge the new styles with the old ones\n\t\tstyles = extend(\n\t\t\telemWrapper.styles,\n\t\t\tstyles\n\t\t);\n\n\t\t// store object\n\t\telemWrapper.styles = styles;\n\n\n\t\t// Don't handle line wrap on canvas\n\t\tif (useCanVG && textWidth) {\n\t\t\tdelete styles.width;\n\t\t}\n\n\t\t// serialize and set style attribute\n\t\tif (isIE && !hasSVG) { // legacy IE doesn't support setting style attribute\n\t\t\tif (textWidth) {\n\t\t\t\tdelete styles.width;\n\t\t\t}\n\t\t\tcss(elemWrapper.element, styles);\n\t\t} else {\n\t\t\tfor (n in styles) {\n\t\t\t\tserializedCss += n.replace(/([A-Z])/g, hyphenate) + ':' + styles[n] + ';';\n\t\t\t}\n\t\t\tattr(elem, 'style', serializedCss); // #1881\n\t\t}\n\n\n\t\t// re-build text\n\t\tif (textWidth && elemWrapper.added) {\n\t\t\telemWrapper.renderer.buildText(elemWrapper);\n\t\t}\n\n\t\treturn elemWrapper;\n\t},\n\n\t/**\n\t * Add an event listener\n\t * @param {String} eventType\n\t * @param {Function} handler\n\t */\n\ton: function (eventType, handler) {\n\t\tvar svgElement = this,\n\t\t\telement = svgElement.element;\n\t\t\n\t\t// touch\n\t\tif (hasTouch && eventType === 'click') {\n\t\t\telement.ontouchstart = function (e) {\t\t\t\n\t\t\t\tsvgElement.touchEventFired = Date.now();\t\t\t\t\n\t\t\t\te.preventDefault();\n\t\t\t\thandler.call(element, e);\n\t\t\t};\n\t\t\telement.onclick = function (e) {\t\t\t\t\t\t\t\t\t\t\t\t\n\t\t\t\tif (userAgent.indexOf('Android') === -1 || Date.now() - (svgElement.touchEventFired || 0) > 1100) { // #2269\n\t\t\t\t\thandler.call(element, e);\n\t\t\t\t}\n\t\t\t};\t\t\t\n\t\t} else {\n\t\t\t// simplest possible event model for internal use\n\t\t\telement['on' + eventType] = handler;\n\t\t}\n\t\treturn this;\n\t},\n\n\t/**\n\t * Set the coordinates needed to draw a consistent radial gradient across\n\t * pie slices regardless of positioning inside the chart. The format is\n\t * [centerX, centerY, diameter] in pixels.\n\t */\n\tsetRadialReference: function (coordinates) {\n\t\tthis.element.radialReference = coordinates;\n\t\treturn this;\n\t},\n\n\t/**\n\t * Move an object and its children by x and y values\n\t * @param {Number} x\n\t * @param {Number} y\n\t */\n\ttranslate: function (x, y) {\n\t\treturn this.attr({\n\t\t\ttranslateX: x,\n\t\t\ttranslateY: y\n\t\t});\n\t},\n\n\t/**\n\t * Invert a group, rotate and flip\n\t */\n\tinvert: function () {\n\t\tvar wrapper = this;\n\t\twrapper.inverted = true;\n\t\twrapper.updateTransform();\n\t\treturn wrapper;\n\t},\n\n\t/**\n\t * Apply CSS to HTML elements. This is used in text within SVG rendering and\n\t * by the VML renderer\n\t */\n\thtmlCss: function (styles) {\n\t\tvar wrapper = this,\n\t\t\telement = wrapper.element,\n\t\t\ttextWidth = styles && element.tagName === 'SPAN' && styles.width;\n\n\t\tif (textWidth) {\n\t\t\tdelete styles.width;\n\t\t\twrapper.textWidth = textWidth;\n\t\t\twrapper.updateTransform();\n\t\t}\n\n\t\twrapper.styles = extend(wrapper.styles, styles);\n\t\tcss(wrapper.element, styles);\n\n\t\treturn wrapper;\n\t},\n\n\n\n\t/**\n\t * VML and useHTML method for calculating the bounding box based on offsets\n\t * @param {Boolean} refresh Whether to force a fresh value from the DOM or to\n\t * use the cached value\n\t *\n\t * @return {Object} A hash containing values for x, y, width and height\n\t */\n\n\thtmlGetBBox: function () {\n\t\tvar wrapper = this,\n\t\t\telement = wrapper.element,\n\t\t\tbBox = wrapper.bBox;\n\n\t\t// faking getBBox in exported SVG in legacy IE\n\t\tif (!bBox) {\n\t\t\t// faking getBBox in exported SVG in legacy IE (is this a duplicate of the fix for #1079?)\n\t\t\tif (element.nodeName === 'text') {\n\t\t\t\telement.style.position = ABSOLUTE;\n\t\t\t}\n\n\t\t\tbBox = wrapper.bBox = {\n\t\t\t\tx: element.offsetLeft,\n\t\t\t\ty: element.offsetTop,\n\t\t\t\twidth: element.offsetWidth,\n\t\t\t\theight: element.offsetHeight\n\t\t\t};\n\t\t}\n\n\t\treturn bBox;\n\t},\n\n\t/**\n\t * VML override private method to update elements based on internal\n\t * properties based on SVG transform\n\t */\n\thtmlUpdateTransform: function () {\n\t\t// aligning non added elements is expensive\n\t\tif (!this.added) {\n\t\t\tthis.alignOnAdd = true;\n\t\t\treturn;\n\t\t}\n\n\t\tvar wrapper = this,\n\t\t\trenderer = wrapper.renderer,\n\t\t\telem = wrapper.element,\n\t\t\ttranslateX = wrapper.translateX || 0,\n\t\t\ttranslateY = wrapper.translateY || 0,\n\t\t\tx = wrapper.x || 0,\n\t\t\ty = wrapper.y || 0,\n\t\t\talign = wrapper.textAlign || 'left',\n\t\t\talignCorrection = { left: 0, center: 0.5, right: 1 }[align],\n\t\t\tnonLeft = align && align !== 'left',\n\t\t\tshadows = wrapper.shadows;\n\n\t\t// apply translate\n\t\tcss(elem, {\n\t\t\tmarginLeft: translateX,\n\t\t\tmarginTop: translateY\n\t\t});\n\t\tif (shadows) { // used in labels/tooltip\n\t\t\teach(shadows, function (shadow) {\n\t\t\t\tcss(shadow, {\n\t\t\t\t\tmarginLeft: translateX + 1,\n\t\t\t\t\tmarginTop: translateY + 1\n\t\t\t\t});\n\t\t\t});\n\t\t}\n\n\t\t// apply inversion\n\t\tif (wrapper.inverted) { // wrapper is a group\n\t\t\teach(elem.childNodes, function (child) {\n\t\t\t\trenderer.invertChild(child, elem);\n\t\t\t});\n\t\t}\n\n\t\tif (elem.tagName === 'SPAN') {\n\n\t\t\tvar width, height,\n\t\t\t\trotation = wrapper.rotation,\n\t\t\t\tbaseline,\n\t\t\t\tradians = 0,\n\t\t\t\tcostheta = 1,\n\t\t\t\tsintheta = 0,\n\t\t\t\tquad,\n\t\t\t\ttextWidth = pInt(wrapper.textWidth),\n\t\t\t\txCorr = wrapper.xCorr || 0,\n\t\t\t\tyCorr = wrapper.yCorr || 0,\n\t\t\t\tcurrentTextTransform = [rotation, align, elem.innerHTML, wrapper.textWidth].join(',');\n\n\t\t\tif (currentTextTransform !== wrapper.cTT) { // do the calculations and DOM access only if properties changed\n\n\t\t\t\tif (defined(rotation)) {\n\n\t\t\t\t\tradians = rotation * deg2rad; // deg to rad\n\t\t\t\t\tcostheta = mathCos(radians);\n\t\t\t\t\tsintheta = mathSin(radians);\n\n\t\t\t\t\twrapper.setSpanRotation(rotation, sintheta, costheta);\n\n\t\t\t\t}\n\n\t\t\t\twidth = pick(wrapper.elemWidth, elem.offsetWidth);\n\t\t\t\theight = pick(wrapper.elemHeight, elem.offsetHeight);\n\n\t\t\t\t// update textWidth\n\t\t\t\tif (width > textWidth && /[ \\-]/.test(elem.textContent || elem.innerText)) { // #983, #1254\n\t\t\t\t\tcss(elem, {\n\t\t\t\t\t\twidth: textWidth + PX,\n\t\t\t\t\t\tdisplay: 'block',\n\t\t\t\t\t\twhiteSpace: 'normal'\n\t\t\t\t\t});\n\t\t\t\t\twidth = textWidth;\n\t\t\t\t}\n\n\t\t\t\t// correct x and y\n\t\t\t\tbaseline = renderer.fontMetrics(elem.style.fontSize).b;\n\t\t\t\txCorr = costheta < 0 && -width;\n\t\t\t\tyCorr = sintheta < 0 && -height;\n\n\t\t\t\t// correct for baseline and corners spilling out after rotation\n\t\t\t\tquad = costheta * sintheta < 0;\n\t\t\t\txCorr += sintheta * baseline * (quad ? 1 - alignCorrection : alignCorrection);\n\t\t\t\tyCorr -= costheta * baseline * (rotation ? (quad ? alignCorrection : 1 - alignCorrection) : 1);\n\n\t\t\t\t// correct for the length/height of the text\n\t\t\t\tif (nonLeft) {\n\t\t\t\t\txCorr -= width * alignCorrection * (costheta < 0 ? -1 : 1);\n\t\t\t\t\tif (rotation) {\n\t\t\t\t\t\tyCorr -= height * alignCorrection * (sintheta < 0 ? -1 : 1);\n\t\t\t\t\t}\n\t\t\t\t\tcss(elem, {\n\t\t\t\t\t\ttextAlign: align\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\t// record correction\n\t\t\t\twrapper.xCorr = xCorr;\n\t\t\t\twrapper.yCorr = yCorr;\n\t\t\t}\n\n\t\t\t// apply position with correction\n\t\t\tcss(elem, {\n\t\t\t\tleft: (x + xCorr) + PX,\n\t\t\t\ttop: (y + yCorr) + PX\n\t\t\t});\n\n\t\t\t// force reflow in webkit to apply the left and top on useHTML element (#1249)\n\t\t\tif (isWebKit) {\n\t\t\t\theight = elem.offsetHeight; // assigned to height for JSLint purpose\n\t\t\t}\n\n\t\t\t// record current text transform\n\t\t\twrapper.cTT = currentTextTransform;\n\t\t}\n\t},\n\n\t/**\n\t * Set the rotation of an individual HTML span\n\t */\n\tsetSpanRotation: function (rotation) {\n\t\tvar rotationStyle = {},\n\t\t\tcssTransformKey = isIE ? '-ms-transform' : isWebKit ? '-webkit-transform' : isFirefox ? 'MozTransform' : isOpera ? '-o-transform' : '';\n\n\t\trotationStyle[cssTransformKey] = rotationStyle.transform = 'rotate(' + rotation + 'deg)';\n\t\tcss(this.element, rotationStyle);\n\t},\n\n\t/**\n\t * Private method to update the transform attribute based on internal\n\t * properties\n\t */\n\tupdateTransform: function () {\n\t\tvar wrapper = this,\n\t\t\ttranslateX = wrapper.translateX || 0,\n\t\t\ttranslateY = wrapper.translateY || 0,\n\t\t\tscaleX = wrapper.scaleX,\n\t\t\tscaleY = wrapper.scaleY,\n\t\t\tinverted = wrapper.inverted,\n\t\t\trotation = wrapper.rotation,\n\t\t\ttransform;\n\n\t\t// flipping affects translate as adjustment for flipping around the group's axis\n\t\tif (inverted) {\n\t\t\ttranslateX += wrapper.attr('width');\n\t\t\ttranslateY += wrapper.attr('height');\n\t\t}\n\n\t\t// Apply translate. Nearly all transformed elements have translation, so instead\n\t\t// of checking for translate = 0, do it always (#1767, #1846).\n\t\ttransform = ['translate(' + translateX + ',' + translateY + ')'];\n\n\t\t// apply rotation\n\t\tif (inverted) {\n\t\t\ttransform.push('rotate(90) scale(-1,1)');\n\t\t} else if (rotation) { // text rotation\n\t\t\ttransform.push('rotate(' + rotation + ' ' + (wrapper.x || 0) + ' ' + (wrapper.y || 0) + ')');\n\t\t}\n\n\t\t// apply scale\n\t\tif (defined(scaleX) || defined(scaleY)) {\n\t\t\ttransform.push('scale(' + pick(scaleX, 1) + ' ' + pick(scaleY, 1) + ')');\n\t\t}\n\n\t\tif (transform.length) {\n\t\t\tattr(wrapper.element, 'transform', transform.join(' '));\n\t\t}\n\t},\n\t/**\n\t * Bring the element to the front\n\t */\n\ttoFront: function () {\n\t\tvar element = this.element;\n\t\telement.parentNode.appendChild(element);\n\t\treturn this;\n\t},\n\n\n\t/**\n\t * Break down alignment options like align, verticalAlign, x and y\n\t * to x and y relative to the chart.\n\t *\n\t * @param {Object} alignOptions\n\t * @param {Boolean} alignByTranslate\n\t * @param {String[Object} box The box to align to, needs a width and height. When the\n\t *        box is a string, it refers to an object in the Renderer. For example, when\n\t *        box is 'spacingBox', it refers to Renderer.spacingBox which holds width, height\n\t *        x and y properties.\n\t *\n\t */\n\talign: function (alignOptions, alignByTranslate, box) {\n\t\tvar align,\n\t\t\tvAlign,\n\t\t\tx,\n\t\t\ty,\n\t\t\tattribs = {},\n\t\t\talignTo,\n\t\t\trenderer = this.renderer,\n\t\t\talignedObjects = renderer.alignedObjects;\n\n\t\t// First call on instanciate\n\t\tif (alignOptions) {\n\t\t\tthis.alignOptions = alignOptions;\n\t\t\tthis.alignByTranslate = alignByTranslate;\n\t\t\tif (!box || isString(box)) { // boxes other than renderer handle this internally\n\t\t\t\tthis.alignTo = alignTo = box || 'renderer';\n\t\t\t\terase(alignedObjects, this); // prevent duplicates, like legendGroup after resize\n\t\t\t\talignedObjects.push(this);\n\t\t\t\tbox = null; // reassign it below\n\t\t\t}\n\n\t\t// When called on resize, no arguments are supplied\n\t\t} else {\n\t\t\talignOptions = this.alignOptions;\n\t\t\talignByTranslate = this.alignByTranslate;\n\t\t\talignTo = this.alignTo;\n\t\t}\n\n\t\tbox = pick(box, renderer[alignTo], renderer);\n\n\t\t// Assign variables\n\t\talign = alignOptions.align;\n\t\tvAlign = alignOptions.verticalAlign;\n\t\tx = (box.x || 0) + (alignOptions.x || 0); // default: left align\n\t\ty = (box.y || 0) + (alignOptions.y || 0); // default: top align\n\n\t\t// Align\n\t\tif (align === 'right' || align === 'center') {\n\t\t\tx += (box.width - (alignOptions.width || 0)) /\n\t\t\t\t\t{ right: 1, center: 2 }[align];\n\t\t}\n\t\tattribs[alignByTranslate ? 'translateX' : 'x'] = mathRound(x);\n\n\n\t\t// Vertical align\n\t\tif (vAlign === 'bottom' || vAlign === 'middle') {\n\t\t\ty += (box.height - (alignOptions.height || 0)) /\n\t\t\t\t\t({ bottom: 1, middle: 2 }[vAlign] || 1);\n\n\t\t}\n\t\tattribs[alignByTranslate ? 'translateY' : 'y'] = mathRound(y);\n\n\t\t// Animate only if already placed\n\t\tthis[this.placed ? 'animate' : 'attr'](attribs);\n\t\tthis.placed = true;\n\t\tthis.alignAttr = attribs;\n\n\t\treturn this;\n\t},\n\n\t/**\n\t * Get the bounding box (width, height, x and y) for the element\n\t */\n\tgetBBox: function () {\n\t\tvar wrapper = this,\n\t\t\tbBox = wrapper.bBox,\n\t\t\trenderer = wrapper.renderer,\n\t\t\twidth,\n\t\t\theight,\n\t\t\trotation = wrapper.rotation,\n\t\t\telement = wrapper.element,\n\t\t\tstyles = wrapper.styles,\n\t\t\trad = rotation * deg2rad;\n\n\t\tif (!bBox) {\n\t\t\t// SVG elements\n\t\t\tif (element.namespaceURI === SVG_NS || renderer.forExport) {\n\t\t\t\ttry { // Fails in Firefox if the container has display: none.\n\n\t\t\t\t\tbBox = element.getBBox ?\n\t\t\t\t\t\t// SVG: use extend because IE9 is not allowed to change width and height in case\n\t\t\t\t\t\t// of rotation (below)\n\t\t\t\t\t\textend({}, element.getBBox()) :\n\t\t\t\t\t\t// Canvas renderer and legacy IE in export mode\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\twidth: element.offsetWidth,\n\t\t\t\t\t\t\theight: element.offsetHeight\n\t\t\t\t\t\t};\n\t\t\t\t} catch (e) {}\n\n\t\t\t\t// If the bBox is not set, the try-catch block above failed. The other condition\n\t\t\t\t// is for Opera that returns a width of -Infinity on hidden elements.\n\t\t\t\tif (!bBox || bBox.width < 0) {\n\t\t\t\t\tbBox = { width: 0, height: 0 };\n\t\t\t\t}\n\n\n\t\t\t// VML Renderer or useHTML within SVG\n\t\t\t} else {\n\n\t\t\t\tbBox = wrapper.htmlGetBBox();\n\n\t\t\t}\n\n\t\t\t// True SVG elements as well as HTML elements in modern browsers using the .useHTML option\n\t\t\t// need to compensated for rotation\n\t\t\tif (renderer.isSVG) {\n\t\t\t\twidth = bBox.width;\n\t\t\t\theight = bBox.height;\n\n\t\t\t\t// Workaround for wrong bounding box in IE9 and IE10 (#1101, #1505, #1669)\n\t\t\t\tif (isIE && styles && styles.fontSize === '11px' && height.toPrecision(3) === '22.7') {\n\t\t\t\t\tbBox.height = height = 14;\n\t\t\t\t}\n\n\t\t\t\t// Adjust for rotated text\n\t\t\t\tif (rotation) {\n\t\t\t\t\tbBox.width = mathAbs(height * mathSin(rad)) + mathAbs(width * mathCos(rad));\n\t\t\t\t\tbBox.height = mathAbs(height * mathCos(rad)) + mathAbs(width * mathSin(rad));\n\t\t\t\t}\n\t\t\t}\n\n\t\t\twrapper.bBox = bBox;\n\t\t}\n\t\treturn bBox;\n\t},\n\n\t/**\n\t * Show the element\n\t */\n\tshow: function () {\n\t\treturn this.attr({ visibility: VISIBLE });\n\t},\n\n\t/**\n\t * Hide the element\n\t */\n\thide: function () {\n\t\treturn this.attr({ visibility: HIDDEN });\n\t},\n\n\tfadeOut: function (duration) {\n\t\tvar elemWrapper = this;\n\t\telemWrapper.animate({\n\t\t\topacity: 0\n\t\t}, {\n\t\t\tduration: duration || 150,\n\t\t\tcomplete: function () {\n\t\t\t\telemWrapper.hide();\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n\t * Add the element\n\t * @param {Object|Undefined} parent Can be an element, an element wrapper or undefined\n\t *    to append the element to the renderer.box.\n\t */\n\tadd: function (parent) {\n\n\t\tvar renderer = this.renderer,\n\t\t\tparentWrapper = parent || renderer,\n\t\t\tparentNode = parentWrapper.element || renderer.box,\n\t\t\tchildNodes = parentNode.childNodes,\n\t\t\telement = this.element,\n\t\t\tzIndex = attr(element, 'zIndex'),\n\t\t\totherElement,\n\t\t\totherZIndex,\n\t\t\ti,\n\t\t\tinserted;\n\n\t\tif (parent) {\n\t\t\tthis.parentGroup = parent;\n\t\t}\n\n\t\t// mark as inverted\n\t\tthis.parentInverted = parent && parent.inverted;\n\n\t\t// build formatted text\n\t\tif (this.textStr !== undefined) {\n\t\t\trenderer.buildText(this);\n\t\t}\n\n\t\t// mark the container as having z indexed children\n\t\tif (zIndex) {\n\t\t\tparentWrapper.handleZ = true;\n\t\t\tzIndex = pInt(zIndex);\n\t\t}\n\n\t\t// insert according to this and other elements' zIndex\n\t\tif (parentWrapper.handleZ) { // this element or any of its siblings has a z index\n\t\t\tfor (i = 0; i < childNodes.length; i++) {\n\t\t\t\totherElement = childNodes[i];\n\t\t\t\totherZIndex = attr(otherElement, 'zIndex');\n\t\t\t\tif (otherElement !== element && (\n\t\t\t\t\t\t// insert before the first element with a higher zIndex\n\t\t\t\t\t\tpInt(otherZIndex) > zIndex ||\n\t\t\t\t\t\t// if no zIndex given, insert before the first element with a zIndex\n\t\t\t\t\t\t(!defined(zIndex) && defined(otherZIndex))\n\n\t\t\t\t\t\t)) {\n\t\t\t\t\tparentNode.insertBefore(element, otherElement);\n\t\t\t\t\tinserted = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// default: append at the end\n\t\tif (!inserted) {\n\t\t\tparentNode.appendChild(element);\n\t\t}\n\n\t\t// mark as added\n\t\tthis.added = true;\n\n\t\t// fire an event for internal hooks\n\t\tfireEvent(this, 'add');\n\n\t\treturn this;\n\t},\n\n\t/**\n\t * Removes a child either by removeChild or move to garbageBin.\n\t * Issue 490; in VML removeChild results in Orphaned nodes according to sIEve, discardElement does not.\n\t */\n\tsafeRemoveChild: function (element) {\n\t\tvar parentNode = element.parentNode;\n\t\tif (parentNode) {\n\t\t\tparentNode.removeChild(element);\n\t\t}\n\t},\n\n\t/**\n\t * Destroy the element and element wrapper\n\t */\n\tdestroy: function () {\n\t\tvar wrapper = this,\n\t\t\telement = wrapper.element || {},\n\t\t\tshadows = wrapper.shadows,\n\t\t\tparentToClean = wrapper.renderer.isSVG && element.nodeName === 'SPAN' && element.parentNode,\n\t\t\tgrandParent,\n\t\t\tkey,\n\t\t\ti;\n\n\t\t// remove events\n\t\telement.onclick = element.onmouseout = element.onmouseover = element.onmousemove = element.point = null;\n\t\tstop(wrapper); // stop running animations\n\n\t\tif (wrapper.clipPath) {\n\t\t\twrapper.clipPath = wrapper.clipPath.destroy();\n\t\t}\n\n\t\t// Destroy stops in case this is a gradient object\n\t\tif (wrapper.stops) {\n\t\t\tfor (i = 0; i < wrapper.stops.length; i++) {\n\t\t\t\twrapper.stops[i] = wrapper.stops[i].destroy();\n\t\t\t}\n\t\t\twrapper.stops = null;\n\t\t}\n\n\t\t// remove element\n\t\twrapper.safeRemoveChild(element);\n\n\t\t// destroy shadows\n\t\tif (shadows) {\n\t\t\teach(shadows, function (shadow) {\n\t\t\t\twrapper.safeRemoveChild(shadow);\n\t\t\t});\n\t\t}\n\n\t\t// In case of useHTML, clean up empty containers emulating SVG groups (#1960).\n\t\twhile (parentToClean && parentToClean.childNodes.length === 0) {\n\t\t\tgrandParent = parentToClean.parentNode;\n\t\t\twrapper.safeRemoveChild(parentToClean);\n\t\t\tparentToClean = grandParent;\n\t\t}\n\n\t\t// remove from alignObjects\n\t\tif (wrapper.alignTo) {\n\t\t\terase(wrapper.renderer.alignedObjects, wrapper);\n\t\t}\n\n\t\tfor (key in wrapper) {\n\t\t\tdelete wrapper[key];\n\t\t}\n\n\t\treturn null;\n\t},\n\n\t/**\n\t * Add a shadow to the element. Must be done after the element is added to the DOM\n\t * @param {Boolean|Object} shadowOptions\n\t */\n\tshadow: function (shadowOptions, group, cutOff) {\n\t\tvar shadows = [],\n\t\t\ti,\n\t\t\tshadow,\n\t\t\telement = this.element,\n\t\t\tstrokeWidth,\n\t\t\tshadowWidth,\n\t\t\tshadowElementOpacity,\n\n\t\t\t// compensate for inverted plot area\n\t\t\ttransform;\n\n\n\t\tif (shadowOptions) {\n\t\t\tshadowWidth = pick(shadowOptions.width, 3);\n\t\t\tshadowElementOpacity = (shadowOptions.opacity || 0.15) / shadowWidth;\n\t\t\ttransform = this.parentInverted ?\n\t\t\t\t'(-1,-1)' :\n\t\t\t\t'(' + pick(shadowOptions.offsetX, 1) + ', ' + pick(shadowOptions.offsetY, 1) + ')';\n\t\t\tfor (i = 1; i <= shadowWidth; i++) {\n\t\t\t\tshadow = element.cloneNode(0);\n\t\t\t\tstrokeWidth = (shadowWidth * 2) + 1 - (2 * i);\n\t\t\t\tattr(shadow, {\n\t\t\t\t\t'isShadow': 'true',\n\t\t\t\t\t'stroke': shadowOptions.color || 'black',\n\t\t\t\t\t'stroke-opacity': shadowElementOpacity * i,\n\t\t\t\t\t'stroke-width': strokeWidth,\n\t\t\t\t\t'transform': 'translate' + transform,\n\t\t\t\t\t'fill': NONE\n\t\t\t\t});\n\t\t\t\tif (cutOff) {\n\t\t\t\t\tattr(shadow, 'height', mathMax(attr(shadow, 'height') - strokeWidth, 0));\n\t\t\t\t\tshadow.cutHeight = strokeWidth;\n\t\t\t\t}\n\n\t\t\t\tif (group) {\n\t\t\t\t\tgroup.element.appendChild(shadow);\n\t\t\t\t} else {\n\t\t\t\t\telement.parentNode.insertBefore(shadow, element);\n\t\t\t\t}\n\n\t\t\t\tshadows.push(shadow);\n\t\t\t}\n\n\t\t\tthis.shadows = shadows;\n\t\t}\n\t\treturn this;\n\n\t}\n};\n\n\n/**\n * The default SVG renderer\n */\nvar SVGRenderer = function () {\n\tthis.init.apply(this, arguments);\n};\nSVGRenderer.prototype = {\n\tElement: SVGElement,\n\n\t/**\n\t * Initialize the SVGRenderer\n\t * @param {Object} container\n\t * @param {Number} width\n\t * @param {Number} height\n\t * @param {Boolean} forExport\n\t */\n\tinit: function (container, width, height, forExport) {\n\t\tvar renderer = this,\n\t\t\tloc = location,\n\t\t\tboxWrapper,\n\t\t\telement,\n\t\t\tdesc;\n\n\t\tboxWrapper = renderer.createElement('svg')\n\t\t\t.attr({\n\t\t\t\tversion: '1.1'\n\t\t\t});\n\t\telement = boxWrapper.element;\n\t\tcontainer.appendChild(element);\n\n\t\t// For browsers other than IE, add the namespace attribute (#1978)\n\t\tif (container.innerHTML.indexOf('xmlns') === -1) {\n\t\t\tattr(element, 'xmlns', SVG_NS);\n\t\t}\n\n\t\t// object properties\n\t\trenderer.isSVG = true;\n\t\trenderer.box = element;\n\t\trenderer.boxWrapper = boxWrapper;\n\t\trenderer.alignedObjects = [];\n\n\t\t// Page url used for internal references. #24, #672, #1070\n\t\trenderer.url = (isFirefox || isWebKit) && doc.getElementsByTagName('base').length ?\n\t\t\tloc.href\n\t\t\t\t.replace(/#.*?$/, '') // remove the hash\n\t\t\t\t.replace(/([\\('\\)])/g, '\\\\$1') // escape parantheses and quotes\n\t\t\t\t.replace(/ /g, '%20') : // replace spaces (needed for Safari only)\n\t\t\t'';\n\n\t\t// Add description\n\t\tdesc = this.createElement('desc').add();\n\t\tdesc.element.appendChild(doc.createTextNode('Created with ' + PRODUCT + ' ' + VERSION));\n\n\n\t\trenderer.defs = this.createElement('defs').add();\n\t\trenderer.forExport = forExport;\n\t\trenderer.gradients = {}; // Object where gradient SvgElements are stored\n\n\t\trenderer.setSize(width, height, false);\n\n\n\n\t\t// Issue 110 workaround:\n\t\t// In Firefox, if a div is positioned by percentage, its pixel position may land\n\t\t// between pixels. The container itself doesn't display this, but an SVG element\n\t\t// inside this container will be drawn at subpixel precision. In order to draw\n\t\t// sharp lines, this must be compensated for. This doesn't seem to work inside\n\t\t// iframes though (like in jsFiddle).\n\t\tvar subPixelFix, rect;\n\t\tif (isFirefox && container.getBoundingClientRect) {\n\t\t\trenderer.subPixelFix = subPixelFix = function () {\n\t\t\t\tcss(container, { left: 0, top: 0 });\n\t\t\t\trect = container.getBoundingClientRect();\n\t\t\t\tcss(container, {\n\t\t\t\t\tleft: (mathCeil(rect.left) - rect.left) + PX,\n\t\t\t\t\ttop: (mathCeil(rect.top) - rect.top) + PX\n\t\t\t\t});\n\t\t\t};\n\n\t\t\t// run the fix now\n\t\t\tsubPixelFix();\n\n\t\t\t// run it on resize\n\t\t\taddEvent(win, 'resize', subPixelFix);\n\t\t}\n\t},\n\n\t/**\n\t * Detect whether the renderer is hidden. This happens when one of the parent elements\n\t * has display: none. #608.\n\t */\n\tisHidden: function () {\n\t\treturn !this.boxWrapper.getBBox().width;\n\t},\n\n\t/**\n\t * Destroys the renderer and its allocated members.\n\t */\n\tdestroy: function () {\n\t\tvar renderer = this,\n\t\t\trendererDefs = renderer.defs;\n\t\trenderer.box = null;\n\t\trenderer.boxWrapper = renderer.boxWrapper.destroy();\n\n\t\t// Call destroy on all gradient elements\n\t\tdestroyObjectProperties(renderer.gradients || {});\n\t\trenderer.gradients = null;\n\n\t\t// Defs are null in VMLRenderer\n\t\t// Otherwise, destroy them here.\n\t\tif (rendererDefs) {\n\t\t\trenderer.defs = rendererDefs.destroy();\n\t\t}\n\n\t\t// Remove sub pixel fix handler\n\t\t// We need to check that there is a handler, otherwise all functions that are registered for event 'resize' are removed\n\t\t// See issue #982\n\t\tif (renderer.subPixelFix) {\n\t\t\tremoveEvent(win, 'resize', renderer.subPixelFix);\n\t\t}\n\n\t\trenderer.alignedObjects = null;\n\n\t\treturn null;\n\t},\n\n\t/**\n\t * Create a wrapper for an SVG element\n\t * @param {Object} nodeName\n\t */\n\tcreateElement: function (nodeName) {\n\t\tvar wrapper = new this.Element();\n\t\twrapper.init(this, nodeName);\n\t\treturn wrapper;\n\t},\n\n\t/**\n\t * Dummy function for use in canvas renderer\n\t */\n\tdraw: function () {},\n\n\t/**\n\t * Parse a simple HTML string into SVG tspans\n\t *\n\t * @param {Object} textNode The parent text SVG node\n\t */\n\tbuildText: function (wrapper) {\n\t\tvar textNode = wrapper.element,\n\t\t\trenderer = this,\n\t\t\tforExport = renderer.forExport,\n\t\t\tlines = pick(wrapper.textStr, '').toString()\n\t\t\t\t.replace(/<(b|strong)>/g, '<span style=\"font-weight:bold\">')\n\t\t\t\t.replace(/<(i|em)>/g, '<span style=\"font-style:italic\">')\n\t\t\t\t.replace(/<a/g, '<span')\n\t\t\t\t.replace(/<\\/(b|strong|i|em|a)>/g, '</span>')\n\t\t\t\t.split(/<br.*?>/g),\n\t\t\tchildNodes = textNode.childNodes,\n\t\t\tstyleRegex = /style=\"([^\"]+)\"/,\n\t\t\threfRegex = /href=\"(http[^\"]+)\"/,\n\t\t\tparentX = attr(textNode, 'x'),\n\t\t\ttextStyles = wrapper.styles,\n\t\t\twidth = textStyles && textStyles.width && pInt(textStyles.width),\n\t\t\ttextLineHeight = textStyles && textStyles.lineHeight,\n\t\t\ti = childNodes.length;\n\n\t\t/// remove old text\n\t\twhile (i--) {\n\t\t\ttextNode.removeChild(childNodes[i]);\n\t\t}\n\n\t\tif (width && !wrapper.added) {\n\t\t\tthis.box.appendChild(textNode); // attach it to the DOM to read offset width\n\t\t}\n\n\t\t// remove empty line at end\n\t\tif (lines[lines.length - 1] === '') {\n\t\t\tlines.pop();\n\t\t}\n\n\t\t// build the lines\n\t\teach(lines, function (line, lineNo) {\n\t\t\tvar spans, spanNo = 0;\n\n\t\t\tline = line.replace(/<span/g, '|||<span').replace(/<\\/span>/g, '</span>|||');\n\t\t\tspans = line.split('|||');\n\n\t\t\teach(spans, function (span) {\n\t\t\t\tif (span !== '' || spans.length === 1) {\n\t\t\t\t\tvar attributes = {},\n\t\t\t\t\t\ttspan = doc.createElementNS(SVG_NS, 'tspan'),\n\t\t\t\t\t\tspanStyle; // #390\n\t\t\t\t\tif (styleRegex.test(span)) {\n\t\t\t\t\t\tspanStyle = span.match(styleRegex)[1].replace(/(;| |^)color([ :])/, '$1fill$2');\n\t\t\t\t\t\tattr(tspan, 'style', spanStyle);\n\t\t\t\t\t}\n\t\t\t\t\tif (hrefRegex.test(span) && !forExport) { // Not for export - #1529\n\t\t\t\t\t\tattr(tspan, 'onclick', 'location.href=\\\"' + span.match(hrefRegex)[1] + '\\\"');\n\t\t\t\t\t\tcss(tspan, { cursor: 'pointer' });\n\t\t\t\t\t}\n\n\t\t\t\t\tspan = (span.replace(/<(.|\\n)*?>/g, '') || ' ')\n\t\t\t\t\t\t.replace(/&lt;/g, '<')\n\t\t\t\t\t\t.replace(/&gt;/g, '>');\n\n\t\t\t\t\t// Nested tags aren't supported, and cause crash in Safari (#1596)\n\t\t\t\t\tif (span !== ' ') {\n\n\t\t\t\t\t\t// add the text node\n\t\t\t\t\t\ttspan.appendChild(doc.createTextNode(span));\n\n\t\t\t\t\t\tif (!spanNo) { // first span in a line, align it to the left\n\t\t\t\t\t\t\tattributes.x = parentX;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tattributes.dx = 0; // #16\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// add attributes\n\t\t\t\t\t\tattr(tspan, attributes);\n\n\t\t\t\t\t\t// first span on subsequent line, add the line height\n\t\t\t\t\t\tif (!spanNo && lineNo) {\n\n\t\t\t\t\t\t\t// allow getting the right offset height in exporting in IE\n\t\t\t\t\t\t\tif (!hasSVG && forExport) {\n\t\t\t\t\t\t\t\tcss(tspan, { display: 'block' });\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Set the line height based on the font size of either\n\t\t\t\t\t\t\t// the text element or the tspan element\n\t\t\t\t\t\t\tattr(\n\t\t\t\t\t\t\t\ttspan,\n\t\t\t\t\t\t\t\t'dy',\n\t\t\t\t\t\t\t\ttextLineHeight || renderer.fontMetrics(\n\t\t\t\t\t\t\t\t\t/px$/.test(tspan.style.fontSize) ?\n\t\t\t\t\t\t\t\t\t\ttspan.style.fontSize :\n\t\t\t\t\t\t\t\t\t\ttextStyles.fontSize\n\t\t\t\t\t\t\t\t).h,\n\t\t\t\t\t\t\t\t// Safari 6.0.2 - too optimized for its own good (#1539)\n\t\t\t\t\t\t\t\t// TODO: revisit this with future versions of Safari\n\t\t\t\t\t\t\t\tisWebKit && tspan.offsetHeight\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Append it\n\t\t\t\t\t\ttextNode.appendChild(tspan);\n\n\t\t\t\t\t\tspanNo++;\n\n\t\t\t\t\t\t// check width and apply soft breaks\n\t\t\t\t\t\tif (width) {\n\t\t\t\t\t\t\tvar words = span.replace(/([^\\^])-/g, '$1- ').split(' '), // #1273\n\t\t\t\t\t\t\t\ttooLong,\n\t\t\t\t\t\t\t\tactualWidth,\n\t\t\t\t\t\t\t\tclipHeight = wrapper._clipHeight,\n\t\t\t\t\t\t\t\trest = [],\n\t\t\t\t\t\t\t\tdy = pInt(textLineHeight || 16),\n\t\t\t\t\t\t\t\tsoftLineNo = 1,\n\t\t\t\t\t\t\t\tbBox;\n\n\t\t\t\t\t\t\twhile (words.length || rest.length) {\n\t\t\t\t\t\t\t\tdelete wrapper.bBox; // delete cache\n\t\t\t\t\t\t\t\tbBox = wrapper.getBBox();\n\t\t\t\t\t\t\t\tactualWidth = bBox.width;\n\t\t\t\t\t\t\t\ttooLong = actualWidth > width;\n\t\t\t\t\t\t\t\tif (!tooLong || words.length === 1) { // new line needed\n\t\t\t\t\t\t\t\t\twords = rest;\n\t\t\t\t\t\t\t\t\trest = [];\n\t\t\t\t\t\t\t\t\tif (words.length) {\n\t\t\t\t\t\t\t\t\t\tsoftLineNo++;\n\n\t\t\t\t\t\t\t\t\t\tif (clipHeight && softLineNo * dy > clipHeight) {\n\t\t\t\t\t\t\t\t\t\t\twords = ['...'];\n\t\t\t\t\t\t\t\t\t\t\twrapper.attr('title', wrapper.textStr);\n\t\t\t\t\t\t\t\t\t\t} else {\n\n\t\t\t\t\t\t\t\t\t\t\ttspan = doc.createElementNS(SVG_NS, 'tspan');\n\t\t\t\t\t\t\t\t\t\t\tattr(tspan, {\n\t\t\t\t\t\t\t\t\t\t\t\tdy: dy,\n\t\t\t\t\t\t\t\t\t\t\t\tx: parentX\n\t\t\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\t\t\tif (spanStyle) { // #390\n\t\t\t\t\t\t\t\t\t\t\t\tattr(tspan, 'style', spanStyle);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\ttextNode.appendChild(tspan);\n\n\t\t\t\t\t\t\t\t\t\t\tif (actualWidth > width) { // a single word is pressing it out\n\t\t\t\t\t\t\t\t\t\t\t\twidth = actualWidth;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else { // append to existing line tspan\n\t\t\t\t\t\t\t\t\ttspan.removeChild(tspan.firstChild);\n\t\t\t\t\t\t\t\t\trest.unshift(words.pop());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (words.length) {\n\t\t\t\t\t\t\t\t\ttspan.appendChild(doc.createTextNode(words.join(' ').replace(/- /g, '-')));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t},\n\n\t/**\n\t * Create a button with preset states\n\t * @param {String} text\n\t * @param {Number} x\n\t * @param {Number} y\n\t * @param {Function} callback\n\t * @param {Object} normalState\n\t * @param {Object} hoverState\n\t * @param {Object} pressedState\n\t */\n\tbutton: function (text, x, y, callback, normalState, hoverState, pressedState, disabledState) {\n\t\tvar label = this.label(text, x, y, null, null, null, null, null, 'button'),\n\t\t\tcurState = 0,\n\t\t\tstateOptions,\n\t\t\tstateStyle,\n\t\t\tnormalStyle,\n\t\t\thoverStyle,\n\t\t\tpressedStyle,\n\t\t\tdisabledStyle,\n\t\t\tSTYLE = 'style',\n\t\t\tverticalGradient = { x1: 0, y1: 0, x2: 0, y2: 1 };\n\n\t\t// Normal state - prepare the attributes\n\t\tnormalState = merge({\n\t\t\t'stroke-width': 1,\n\t\t\tstroke: '#CCCCCC',\n\t\t\tfill: {\n\t\t\t\tlinearGradient: verticalGradient,\n\t\t\t\tstops: [\n\t\t\t\t\t[0, '#FEFEFE'],\n\t\t\t\t\t[1, '#F6F6F6']\n\t\t\t\t]\n\t\t\t},\n\t\t\tr: 2,\n\t\t\tpadding: 5,\n\t\t\tstyle: {\n\t\t\t\tcolor: 'black'\n\t\t\t}\n\t\t}, normalState);\n\t\tnormalStyle = normalState[STYLE];\n\t\tdelete normalState[STYLE];\n\n\t\t// Hover state\n\t\thoverState = merge(normalState, {\n\t\t\tstroke: '#68A',\n\t\t\tfill: {\n\t\t\t\tlinearGradient: verticalGradient,\n\t\t\t\tstops: [\n\t\t\t\t\t[0, '#FFF'],\n\t\t\t\t\t[1, '#ACF']\n\t\t\t\t]\n\t\t\t}\n\t\t}, hoverState);\n\t\thoverStyle = hoverState[STYLE];\n\t\tdelete hoverState[STYLE];\n\n\t\t// Pressed state\n\t\tpressedState = merge(normalState, {\n\t\t\tstroke: '#68A',\n\t\t\tfill: {\n\t\t\t\tlinearGradient: verticalGradient,\n\t\t\t\tstops: [\n\t\t\t\t\t[0, '#9BD'],\n\t\t\t\t\t[1, '#CDF']\n\t\t\t\t]\n\t\t\t}\n\t\t}, pressedState);\n\t\tpressedStyle = pressedState[STYLE];\n\t\tdelete pressedState[STYLE];\n\n\t\t// Disabled state\n\t\tdisabledState = merge(normalState, {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#CCC'\n\t\t\t}\n\t\t}, disabledState);\n\t\tdisabledStyle = disabledState[STYLE];\n\t\tdelete disabledState[STYLE];\n\n\t\t// Add the events. IE9 and IE10 need mouseover and mouseout to funciton (#667).\n\t\taddEvent(label.element, isIE ? 'mouseover' : 'mouseenter', function () {\n\t\t\tif (curState !== 3) {\n\t\t\t\tlabel.attr(hoverState)\n\t\t\t\t\t.css(hoverStyle);\n\t\t\t}\n\t\t});\n\t\taddEvent(label.element, isIE ? 'mouseout' : 'mouseleave', function () {\n\t\t\tif (curState !== 3) {\n\t\t\t\tstateOptions = [normalState, hoverState, pressedState][curState];\n\t\t\t\tstateStyle = [normalStyle, hoverStyle, pressedStyle][curState];\n\t\t\t\tlabel.attr(stateOptions)\n\t\t\t\t\t.css(stateStyle);\n\t\t\t}\n\t\t});\n\n\t\tlabel.setState = function (state) {\n\t\t\tlabel.state = curState = state;\n\t\t\tif (!state) {\n\t\t\t\tlabel.attr(normalState)\n\t\t\t\t\t.css(normalStyle);\n\t\t\t} else if (state === 2) {\n\t\t\t\tlabel.attr(pressedState)\n\t\t\t\t\t.css(pressedStyle);\n\t\t\t} else if (state === 3) {\n\t\t\t\tlabel.attr(disabledState)\n\t\t\t\t\t.css(disabledStyle);\n\t\t\t}\n\t\t};\n\n\t\treturn label\n\t\t\t.on('click', function () {\n\t\t\t\tif (curState !== 3) {\n\t\t\t\t\tcallback.call(label);\n\t\t\t\t}\n\t\t\t})\n\t\t\t.attr(normalState)\n\t\t\t.css(extend({ cursor: 'default' }, normalStyle));\n\t},\n\n\t/**\n\t * Make a straight line crisper by not spilling out to neighbour pixels\n\t * @param {Array} points\n\t * @param {Number} width\n\t */\n\tcrispLine: function (points, width) {\n\t\t// points format: [M, 0, 0, L, 100, 0]\n\t\t// normalize to a crisp line\n\t\tif (points[1] === points[4]) {\n\t\t\t// Substract due to #1129. Now bottom and left axis gridlines behave the same.\n\t\t\tpoints[1] = points[4] = mathRound(points[1]) - (width % 2 / 2);\n\t\t}\n\t\tif (points[2] === points[5]) {\n\t\t\tpoints[2] = points[5] = mathRound(points[2]) + (width % 2 / 2);\n\t\t}\n\t\treturn points;\n\t},\n\n\n\t/**\n\t * Draw a path\n\t * @param {Array} path An SVG path in array form\n\t */\n\tpath: function (path) {\n\t\tvar attr = {\n\t\t\tfill: NONE\n\t\t};\n\t\tif (isArray(path)) {\n\t\t\tattr.d = path;\n\t\t} else if (isObject(path)) { // attributes\n\t\t\textend(attr, path);\n\t\t}\n\t\treturn this.createElement('path').attr(attr);\n\t},\n\n\t/**\n\t * Draw and return an SVG circle\n\t * @param {Number} x The x position\n\t * @param {Number} y The y position\n\t * @param {Number} r The radius\n\t */\n\tcircle: function (x, y, r) {\n\t\tvar attr = isObject(x) ?\n\t\t\tx :\n\t\t\t{\n\t\t\t\tx: x,\n\t\t\t\ty: y,\n\t\t\t\tr: r\n\t\t\t};\n\n\t\treturn this.createElement('circle').attr(attr);\n\t},\n\n\t/**\n\t * Draw and return an arc\n\t * @param {Number} x X position\n\t * @param {Number} y Y position\n\t * @param {Number} r Radius\n\t * @param {Number} innerR Inner radius like used in donut charts\n\t * @param {Number} start Starting angle\n\t * @param {Number} end Ending angle\n\t */\n\tarc: function (x, y, r, innerR, start, end) {\n\t\tvar arc;\n\n\t\tif (isObject(x)) {\n\t\t\ty = x.y;\n\t\t\tr = x.r;\n\t\t\tinnerR = x.innerR;\n\t\t\tstart = x.start;\n\t\t\tend = x.end;\n\t\t\tx = x.x;\n\t\t}\n\n\t\t// Arcs are defined as symbols for the ability to set\n\t\t// attributes in attr and animate\n\t\tarc = this.symbol('arc', x || 0, y || 0, r || 0, r || 0, {\n\t\t\tinnerR: innerR || 0,\n\t\t\tstart: start || 0,\n\t\t\tend: end || 0\n\t\t});\n\t\tarc.r = r; // #959\n\t\treturn arc;\n\t},\n\n\t/**\n\t * Draw and return a rectangle\n\t * @param {Number} x Left position\n\t * @param {Number} y Top position\n\t * @param {Number} width\n\t * @param {Number} height\n\t * @param {Number} r Border corner radius\n\t * @param {Number} strokeWidth A stroke width can be supplied to allow crisp drawing\n\t */\n\trect: function (x, y, width, height, r, strokeWidth) {\n\n\t\tr = isObject(x) ? x.r : r;\n\n\t\tvar wrapper = this.createElement('rect').attr({\n\t\t\t\trx: r,\n\t\t\t\try: r,\n\t\t\t\tfill: NONE\n\t\t\t});\n\t\treturn wrapper.attr(\n\t\t\t\tisObject(x) ?\n\t\t\t\t\tx :\n\t\t\t\t\t// do not crispify when an object is passed in (as in column charts)\n\t\t\t\t\twrapper.crisp(strokeWidth, x, y, mathMax(width, 0), mathMax(height, 0))\n\t\t\t);\n\t},\n\n\t/**\n\t * Resize the box and re-align all aligned elements\n\t * @param {Object} width\n\t * @param {Object} height\n\t * @param {Boolean} animate\n\t *\n\t */\n\tsetSize: function (width, height, animate) {\n\t\tvar renderer = this,\n\t\t\talignedObjects = renderer.alignedObjects,\n\t\t\ti = alignedObjects.length;\n\n\t\trenderer.width = width;\n\t\trenderer.height = height;\n\n\t\trenderer.boxWrapper[pick(animate, true) ? 'animate' : 'attr']({\n\t\t\twidth: width,\n\t\t\theight: height\n\t\t});\n\n\t\twhile (i--) {\n\t\t\talignedObjects[i].align();\n\t\t}\n\t},\n\n\t/**\n\t * Create a group\n\t * @param {String} name The group will be given a class name of 'highcharts-{name}'.\n\t *     This can be used for styling and scripting.\n\t */\n\tg: function (name) {\n\t\tvar elem = this.createElement('g');\n\t\treturn defined(name) ? elem.attr({ 'class': PREFIX + name }) : elem;\n\t},\n\n\t/**\n\t * Display an image\n\t * @param {String} src\n\t * @param {Number} x\n\t * @param {Number} y\n\t * @param {Number} width\n\t * @param {Number} height\n\t */\n\timage: function (src, x, y, width, height) {\n\t\tvar attribs = {\n\t\t\t\tpreserveAspectRatio: NONE\n\t\t\t},\n\t\t\telemWrapper;\n\n\t\t// optional properties\n\t\tif (arguments.length > 1) {\n\t\t\textend(attribs, {\n\t\t\t\tx: x,\n\t\t\t\ty: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t});\n\t\t}\n\n\t\telemWrapper = this.createElement('image').attr(attribs);\n\n\t\t// set the href in the xlink namespace\n\t\tif (elemWrapper.element.setAttributeNS) {\n\t\t\telemWrapper.element.setAttributeNS('http://www.w3.org/1999/xlink',\n\t\t\t\t'href', src);\n\t\t} else {\n\t\t\t// could be exporting in IE\n\t\t\t// using href throws \"not supported\" in ie7 and under, requries regex shim to fix later\n\t\t\telemWrapper.element.setAttribute('hc-svg-href', src);\n\t}\n\n\t\treturn elemWrapper;\n\t},\n\n\t/**\n\t * Draw a symbol out of pre-defined shape paths from the namespace 'symbol' object.\n\t *\n\t * @param {Object} symbol\n\t * @param {Object} x\n\t * @param {Object} y\n\t * @param {Object} radius\n\t * @param {Object} options\n\t */\n\tsymbol: function (symbol, x, y, width, height, options) {\n\n\t\tvar obj,\n\n\t\t\t// get the symbol definition function\n\t\t\tsymbolFn = this.symbols[symbol],\n\n\t\t\t// check if there's a path defined for this symbol\n\t\t\tpath = symbolFn && symbolFn(\n\t\t\t\tmathRound(x),\n\t\t\t\tmathRound(y),\n\t\t\t\twidth,\n\t\t\t\theight,\n\t\t\t\toptions\n\t\t\t),\n\n\t\t\timageElement,\n\t\t\timageRegex = /^url\\((.*?)\\)$/,\n\t\t\timageSrc,\n\t\t\timageSize,\n\t\t\tcenterImage;\n\n\t\tif (path) {\n\n\t\t\tobj = this.path(path);\n\t\t\t// expando properties for use in animate and attr\n\t\t\textend(obj, {\n\t\t\t\tsymbolName: symbol,\n\t\t\t\tx: x,\n\t\t\t\ty: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t});\n\t\t\tif (options) {\n\t\t\t\textend(obj, options);\n\t\t\t}\n\n\n\t\t// image symbols\n\t\t} else if (imageRegex.test(symbol)) {\n\n\t\t\t// On image load, set the size and position\n\t\t\tcenterImage = function (img, size) {\n\t\t\t\tif (img.element) { // it may be destroyed in the meantime (#1390)\n\t\t\t\t\timg.attr({\n\t\t\t\t\t\twidth: size[0],\n\t\t\t\t\t\theight: size[1]\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!img.alignByTranslate) { // #185\n\t\t\t\t\t\timg.translate(\n\t\t\t\t\t\t\tmathRound((width - size[0]) / 2), // #1378\n\t\t\t\t\t\t\tmathRound((height - size[1]) / 2)\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\n\t\t\timageSrc = symbol.match(imageRegex)[1];\n\t\t\timageSize = symbolSizes[imageSrc];\n\n\t\t\t// Ireate the image synchronously, add attribs async\n\t\t\tobj = this.image(imageSrc)\n\t\t\t\t.attr({\n\t\t\t\t\tx: x,\n\t\t\t\t\ty: y\n\t\t\t\t});\n\t\t\tobj.isImg = true;\n\n\t\t\tif (imageSize) {\n\t\t\t\tcenterImage(obj, imageSize);\n\t\t\t} else {\n\t\t\t\t// Initialize image to be 0 size so export will still function if there's no cached sizes.\n\t\t\t\t//\n\t\t\t\tobj.attr({ width: 0, height: 0 });\n\n\t\t\t\t// Create a dummy JavaScript image to get the width and height. Due to a bug in IE < 8,\n\t\t\t\t// the created element must be assigned to a variable in order to load (#292).\n\t\t\t\timageElement = createElement('img', {\n\t\t\t\t\tonload: function () {\n\t\t\t\t\t\tcenterImage(obj, symbolSizes[imageSrc] = [this.width, this.height]);\n\t\t\t\t\t},\n\t\t\t\t\tsrc: imageSrc\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t/**\n\t * An extendable collection of functions for defining symbol paths.\n\t */\n\tsymbols: {\n\t\t'circle': function (x, y, w, h) {\n\t\t\tvar cpw = 0.166 * w;\n\t\t\treturn [\n\t\t\t\tM, x + w / 2, y,\n\t\t\t\t'C', x + w + cpw, y, x + w + cpw, y + h, x + w / 2, y + h,\n\t\t\t\t'C', x - cpw, y + h, x - cpw, y, x + w / 2, y,\n\t\t\t\t'Z'\n\t\t\t];\n\t\t},\n\n\t\t'square': function (x, y, w, h) {\n\t\t\treturn [\n\t\t\t\tM, x, y,\n\t\t\t\tL, x + w, y,\n\t\t\t\tx + w, y + h,\n\t\t\t\tx, y + h,\n\t\t\t\t'Z'\n\t\t\t];\n\t\t},\n\n\t\t'triangle': function (x, y, w, h) {\n\t\t\treturn [\n\t\t\t\tM, x + w / 2, y,\n\t\t\t\tL, x + w, y + h,\n\t\t\t\tx, y + h,\n\t\t\t\t'Z'\n\t\t\t];\n\t\t},\n\n\t\t'triangle-down': function (x, y, w, h) {\n\t\t\treturn [\n\t\t\t\tM, x, y,\n\t\t\t\tL, x + w, y,\n\t\t\t\tx + w / 2, y + h,\n\t\t\t\t'Z'\n\t\t\t];\n\t\t},\n\t\t'diamond': function (x, y, w, h) {\n\t\t\treturn [\n\t\t\t\tM, x + w / 2, y,\n\t\t\t\tL, x + w, y + h / 2,\n\t\t\t\tx + w / 2, y + h,\n\t\t\t\tx, y + h / 2,\n\t\t\t\t'Z'\n\t\t\t];\n\t\t},\n\t\t'arc': function (x, y, w, h, options) {\n\t\t\tvar start = options.start,\n\t\t\t\tradius = options.r || w || h,\n\t\t\t\tend = options.end - 0.001, // to prevent cos and sin of start and end from becoming equal on 360 arcs (related: #1561)\n\t\t\t\tinnerRadius = options.innerR,\n\t\t\t\topen = options.open,\n\t\t\t\tcosStart = mathCos(start),\n\t\t\t\tsinStart = mathSin(start),\n\t\t\t\tcosEnd = mathCos(end),\n\t\t\t\tsinEnd = mathSin(end),\n\t\t\t\tlongArc = options.end - start < mathPI ? 0 : 1;\n\n\t\t\treturn [\n\t\t\t\tM,\n\t\t\t\tx + radius * cosStart,\n\t\t\t\ty + radius * sinStart,\n\t\t\t\t'A', // arcTo\n\t\t\t\tradius, // x radius\n\t\t\t\tradius, // y radius\n\t\t\t\t0, // slanting\n\t\t\t\tlongArc, // long or short arc\n\t\t\t\t1, // clockwise\n\t\t\t\tx + radius * cosEnd,\n\t\t\t\ty + radius * sinEnd,\n\t\t\t\topen ? M : L,\n\t\t\t\tx + innerRadius * cosEnd,\n\t\t\t\ty + innerRadius * sinEnd,\n\t\t\t\t'A', // arcTo\n\t\t\t\tinnerRadius, // x radius\n\t\t\t\tinnerRadius, // y radius\n\t\t\t\t0, // slanting\n\t\t\t\tlongArc, // long or short arc\n\t\t\t\t0, // clockwise\n\t\t\t\tx + innerRadius * cosStart,\n\t\t\t\ty + innerRadius * sinStart,\n\n\t\t\t\topen ? '' : 'Z' // close\n\t\t\t];\n\t\t}\n\t},\n\n\t/**\n\t * Define a clipping rectangle\n\t * @param {String} id\n\t * @param {Number} x\n\t * @param {Number} y\n\t * @param {Number} width\n\t * @param {Number} height\n\t */\n\tclipRect: function (x, y, width, height) {\n\t\tvar wrapper,\n\t\t\tid = PREFIX + idCounter++,\n\n\t\t\tclipPath = this.createElement('clipPath').attr({\n\t\t\t\tid: id\n\t\t\t}).add(this.defs);\n\n\t\twrapper = this.rect(x, y, width, height, 0).add(clipPath);\n\t\twrapper.id = id;\n\t\twrapper.clipPath = clipPath;\n\n\t\treturn wrapper;\n\t},\n\n\n\t/**\n\t * Take a color and return it if it's a string, make it a gradient if it's a\n\t * gradient configuration object. Prior to Highstock, an array was used to define\n\t * a linear gradient with pixel positions relative to the SVG. In newer versions\n\t * we change the coordinates to apply relative to the shape, using coordinates\n\t * 0-1 within the shape. To preserve backwards compatibility, linearGradient\n\t * in this definition is an object of x1, y1, x2 and y2.\n\t *\n\t * @param {Object} color The color or config object\n\t */\n\tcolor: function (color, elem, prop) {\n\t\tvar renderer = this,\n\t\t\tcolorObject,\n\t\t\tregexRgba = /^rgba/,\n\t\t\tgradName,\n\t\t\tgradAttr,\n\t\t\tgradients,\n\t\t\tgradientObject,\n\t\t\tstops,\n\t\t\tstopColor,\n\t\t\tstopOpacity,\n\t\t\tradialReference,\n\t\t\tn,\n\t\t\tid,\n\t\t\tkey = [];\n\n\t\t// Apply linear or radial gradients\n\t\tif (color && color.linearGradient) {\n\t\t\tgradName = 'linearGradient';\n\t\t} else if (color && color.radialGradient) {\n\t\t\tgradName = 'radialGradient';\n\t\t}\n\n\t\tif (gradName) {\n\t\t\tgradAttr = color[gradName];\n\t\t\tgradients = renderer.gradients;\n\t\t\tstops = color.stops;\n\t\t\tradialReference = elem.radialReference;\n\n\t\t\t// Keep < 2.2 kompatibility\n\t\t\tif (isArray(gradAttr)) {\n\t\t\t\tcolor[gradName] = gradAttr = {\n\t\t\t\t\tx1: gradAttr[0],\n\t\t\t\t\ty1: gradAttr[1],\n\t\t\t\t\tx2: gradAttr[2],\n\t\t\t\t\ty2: gradAttr[3],\n\t\t\t\t\tgradientUnits: 'userSpaceOnUse'\n\t\t\t\t};\n\t\t\t}\n\n\t\t\t// Correct the radial gradient for the radial reference system\n\t\t\tif (gradName === 'radialGradient' && radialReference && !defined(gradAttr.gradientUnits)) {\n\t\t\t\tgradAttr = merge(gradAttr, {\n\t\t\t\t\tcx: (radialReference[0] - radialReference[2] / 2) + gradAttr.cx * radialReference[2],\n\t\t\t\t\tcy: (radialReference[1] - radialReference[2] / 2) + gradAttr.cy * radialReference[2],\n\t\t\t\t\tr: gradAttr.r * radialReference[2],\n\t\t\t\t\tgradientUnits: 'userSpaceOnUse'\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Build the unique key to detect whether we need to create a new element (#1282)\n\t\t\tfor (n in gradAttr) {\n\t\t\t\tif (n !== 'id') {\n\t\t\t\t\tkey.push(n, gradAttr[n]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor (n in stops) {\n\t\t\t\tkey.push(stops[n]);\n\t\t\t}\n\t\t\tkey = key.join(',');\n\n\t\t\t// Check if a gradient object with the same config object is created within this renderer\n\t\t\tif (gradients[key]) {\n\t\t\t\tid = gradients[key].id;\n\n\t\t\t} else {\n\n\t\t\t\t// Set the id and create the element\n\t\t\t\tgradAttr.id = id = PREFIX + idCounter++;\n\t\t\t\tgradients[key] = gradientObject = renderer.createElement(gradName)\n\t\t\t\t\t.attr(gradAttr)\n\t\t\t\t\t.add(renderer.defs);\n\n\n\t\t\t\t// The gradient needs to keep a list of stops to be able to destroy them\n\t\t\t\tgradientObject.stops = [];\n\t\t\t\teach(stops, function (stop) {\n\t\t\t\t\tvar stopObject;\n\t\t\t\t\tif (regexRgba.test(stop[1])) {\n\t\t\t\t\t\tcolorObject = Color(stop[1]);\n\t\t\t\t\t\tstopColor = colorObject.get('rgb');\n\t\t\t\t\t\tstopOpacity = colorObject.get('a');\n\t\t\t\t\t} else {\n\t\t\t\t\t\tstopColor = stop[1];\n\t\t\t\t\t\tstopOpacity = 1;\n\t\t\t\t\t}\n\t\t\t\t\tstopObject = renderer.createElement('stop').attr({\n\t\t\t\t\t\toffset: stop[0],\n\t\t\t\t\t\t'stop-color': stopColor,\n\t\t\t\t\t\t'stop-opacity': stopOpacity\n\t\t\t\t\t}).add(gradientObject);\n\n\t\t\t\t\t// Add the stop element to the gradient\n\t\t\t\t\tgradientObject.stops.push(stopObject);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Return the reference to the gradient object\n\t\t\treturn 'url(' + renderer.url + '#' + id + ')';\n\n\t\t// Webkit and Batik can't show rgba.\n\t\t} else if (regexRgba.test(color)) {\n\t\t\tcolorObject = Color(color);\n\t\t\tattr(elem, prop + '-opacity', colorObject.get('a'));\n\n\t\t\treturn colorObject.get('rgb');\n\n\n\t\t} else {\n\t\t\t// Remove the opacity attribute added above. Does not throw if the attribute is not there.\n\t\t\telem.removeAttribute(prop + '-opacity');\n\n\t\t\treturn color;\n\t\t}\n\n\t},\n\n\n\t/**\n\t * Add text to the SVG object\n\t * @param {String} str\n\t * @param {Number} x Left position\n\t * @param {Number} y Top position\n\t * @param {Boolean} useHTML Use HTML to render the text\n\t */\n\ttext: function (str, x, y, useHTML) {\n\n\t\t// declare variables\n\t\tvar renderer = this,\n\t\t\tdefaultChartStyle = defaultOptions.chart.style,\n\t\t\tfakeSVG = useCanVG || (!hasSVG && renderer.forExport),\n\t\t\twrapper;\n\n\t\tif (useHTML && !renderer.forExport) {\n\t\t\treturn renderer.html(str, x, y);\n\t\t}\n\n\t\tx = mathRound(pick(x, 0));\n\t\ty = mathRound(pick(y, 0));\n\n\t\twrapper = renderer.createElement('text')\n\t\t\t.attr({\n\t\t\t\tx: x,\n\t\t\t\ty: y,\n\t\t\t\ttext: str\n\t\t\t})\n\t\t\t.css({\n\t\t\t\tfontFamily: defaultChartStyle.fontFamily,\n\t\t\t\tfontSize: defaultChartStyle.fontSize\n\t\t\t});\n\n\t\t// Prevent wrapping from creating false offsetWidths in export in legacy IE (#1079, #1063)\n\t\tif (fakeSVG) {\n\t\t\twrapper.css({\n\t\t\t\tposition: ABSOLUTE\n\t\t\t});\n\t\t}\n\n\t\twrapper.x = x;\n\t\twrapper.y = y;\n\t\treturn wrapper;\n\t},\n\n\n\t/**\n\t * Create HTML text node. This is used by the VML renderer as well as the SVG\n\t * renderer through the useHTML option.\n\t *\n\t * @param {String} str\n\t * @param {Number} x\n\t * @param {Number} y\n\t */\n\thtml: function (str, x, y) {\n\t\tvar defaultChartStyle = defaultOptions.chart.style,\n\t\t\twrapper = this.createElement('span'),\n\t\t\tattrSetters = wrapper.attrSetters,\n\t\t\telement = wrapper.element,\n\t\t\trenderer = wrapper.renderer;\n\n\t\t// Text setter\n\t\tattrSetters.text = function (value) {\n\t\t\tif (value !== element.innerHTML) {\n\t\t\t\tdelete this.bBox;\n\t\t\t}\n\t\t\telement.innerHTML = value;\n\t\t\treturn false;\n\t\t};\n\n\t\t// Various setters which rely on update transform\n\t\tattrSetters.x = attrSetters.y = attrSetters.align = function (value, key) {\n\t\t\tif (key === 'align') {\n\t\t\t\tkey = 'textAlign'; // Do not overwrite the SVGElement.align method. Same as VML.\n\t\t\t}\n\t\t\twrapper[key] = value;\n\t\t\twrapper.htmlUpdateTransform();\n\t\t\treturn false;\n\t\t};\n\n\t\t// Set the default attributes\n\t\twrapper.attr({\n\t\t\t\ttext: str,\n\t\t\t\tx: mathRound(x),\n\t\t\t\ty: mathRound(y)\n\t\t\t})\n\t\t\t.css({\n\t\t\t\tposition: ABSOLUTE,\n\t\t\t\twhiteSpace: 'nowrap',\n\t\t\t\tfontFamily: defaultChartStyle.fontFamily,\n\t\t\t\tfontSize: defaultChartStyle.fontSize\n\t\t\t});\n\n\t\t// Use the HTML specific .css method\n\t\twrapper.css = wrapper.htmlCss;\n\n\t\t// This is specific for HTML within SVG\n\t\tif (renderer.isSVG) {\n\t\t\twrapper.add = function (svgGroupWrapper) {\n\n\t\t\t\tvar htmlGroup,\n\t\t\t\t\tcontainer = renderer.box.parentNode,\n\t\t\t\t\tparentGroup,\n\t\t\t\t\tparents = [];\n\n\t\t\t\t// Create a mock group to hold the HTML elements\n\t\t\t\tif (svgGroupWrapper) {\n\t\t\t\t\thtmlGroup = svgGroupWrapper.div;\n\t\t\t\t\tif (!htmlGroup) {\n\n\t\t\t\t\t\t// Read the parent chain into an array and read from top down\n\t\t\t\t\t\tparentGroup = svgGroupWrapper;\n\t\t\t\t\t\twhile (parentGroup) {\n\n\t\t\t\t\t\t\tparents.push(parentGroup);\n\n\t\t\t\t\t\t\t// Move up to the next parent group\n\t\t\t\t\t\t\tparentGroup = parentGroup.parentGroup;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Ensure dynamically updating position when any parent is translated\n\t\t\t\t\t\teach(parents.reverse(), function (parentGroup) {\n\t\t\t\t\t\t\tvar htmlGroupStyle;\n\n\t\t\t\t\t\t\t// Create a HTML div and append it to the parent div to emulate\n\t\t\t\t\t\t\t// the SVG group structure\n\t\t\t\t\t\t\thtmlGroup = parentGroup.div = parentGroup.div || createElement(DIV, {\n\t\t\t\t\t\t\t\tclassName: attr(parentGroup.element, 'class')\n\t\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\t\tposition: ABSOLUTE,\n\t\t\t\t\t\t\t\tleft: (parentGroup.translateX || 0) + PX,\n\t\t\t\t\t\t\t\ttop: (parentGroup.translateY || 0) + PX\n\t\t\t\t\t\t\t}, htmlGroup || container); // the top group is appended to container\n\n\t\t\t\t\t\t\t// Shortcut\n\t\t\t\t\t\t\thtmlGroupStyle = htmlGroup.style;\n\n\t\t\t\t\t\t\t// Set listeners to update the HTML div's position whenever the SVG group\n\t\t\t\t\t\t\t// position is changed\n\t\t\t\t\t\t\textend(parentGroup.attrSetters, {\n\t\t\t\t\t\t\t\ttranslateX: function (value) {\n\t\t\t\t\t\t\t\t\thtmlGroupStyle.left = value + PX;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\ttranslateY: function (value) {\n\t\t\t\t\t\t\t\t\thtmlGroupStyle.top = value + PX;\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tvisibility: function (value, key) {\n\t\t\t\t\t\t\t\t\thtmlGroupStyle[key] = value;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\thtmlGroup = container;\n\t\t\t\t}\n\n\t\t\t\thtmlGroup.appendChild(element);\n\n\t\t\t\t// Shared with VML:\n\t\t\t\twrapper.added = true;\n\t\t\t\tif (wrapper.alignOnAdd) {\n\t\t\t\t\twrapper.htmlUpdateTransform();\n\t\t\t\t}\n\n\t\t\t\treturn wrapper;\n\t\t\t};\n\t\t}\n\t\treturn wrapper;\n\t},\n\n\t/**\n\t * Utility to return the baseline offset and total line height from the font size\n\t */\n\tfontMetrics: function (fontSize) {\n\t\tfontSize = pInt(fontSize || 11);\n\n\t\t// Empirical values found by comparing font size and bounding box height.\n\t\t// Applies to the default font family. http://jsfiddle.net/highcharts/7xvn7/\n\t\tvar lineHeight = fontSize < 24 ? fontSize + 4 : mathRound(fontSize * 1.2),\n\t\t\tbaseline = mathRound(lineHeight * 0.8);\n\n\t\treturn {\n\t\t\th: lineHeight,\n\t\t\tb: baseline\n\t\t};\n\t},\n\n\t/**\n\t * Add a label, a text item that can hold a colored or gradient background\n\t * as well as a border and shadow.\n\t * @param {string} str\n\t * @param {Number} x\n\t * @param {Number} y\n\t * @param {String} shape\n\t * @param {Number} anchorX In case the shape has a pointer, like a flag, this is the\n\t *    coordinates it should be pinned to\n\t * @param {Number} anchorY\n\t * @param {Boolean} baseline Whether to position the label relative to the text baseline,\n\t *    like renderer.text, or to the upper border of the rectangle.\n\t * @param {String} className Class name for the group\n\t */\n\tlabel: function (str, x, y, shape, anchorX, anchorY, useHTML, baseline, className) {\n\n\t\tvar renderer = this,\n\t\t\twrapper = renderer.g(className),\n\t\t\ttext = renderer.text('', 0, 0, useHTML)\n\t\t\t\t.attr({\n\t\t\t\t\tzIndex: 1\n\t\t\t\t}),\n\t\t\t\t//.add(wrapper),\n\t\t\tbox,\n\t\t\tbBox,\n\t\t\talignFactor = 0,\n\t\t\tpadding = 3,\n\t\t\tpaddingLeft = 0,\n\t\t\twidth,\n\t\t\theight,\n\t\t\twrapperX,\n\t\t\twrapperY,\n\t\t\tcrispAdjust = 0,\n\t\t\tdeferredAttr = {},\n\t\t\tbaselineOffset,\n\t\t\tattrSetters = wrapper.attrSetters,\n\t\t\tneedsBox;\n\n\t\t/**\n\t\t * This function runs after the label is added to the DOM (when the bounding box is\n\t\t * available), and after the text of the label is updated to detect the new bounding\n\t\t * box and reflect it in the border box.\n\t\t */\n\t\tfunction updateBoxSize() {\n\t\t\tvar boxX,\n\t\t\t\tboxY,\n\t\t\t\tstyle = text.element.style;\n\n\t\t\tbBox = (width === undefined || height === undefined || wrapper.styles.textAlign) &&\n\t\t\t\ttext.getBBox();\n\t\t\twrapper.width = (width || bBox.width || 0) + 2 * padding + paddingLeft;\n\t\t\twrapper.height = (height || bBox.height || 0) + 2 * padding;\n\n\t\t\t// update the label-scoped y offset\n\t\t\tbaselineOffset = padding + renderer.fontMetrics(style && style.fontSize).b;\n\n\t\t\tif (needsBox) {\n\n\t\t\t\t// create the border box if it is not already present\n\t\t\t\tif (!box) {\n\t\t\t\t\tboxX = mathRound(-alignFactor * padding);\n\t\t\t\t\tboxY = baseline ? -baselineOffset : 0;\n\n\t\t\t\t\twrapper.box = box = shape ?\n\t\t\t\t\t\trenderer.symbol(shape, boxX, boxY, wrapper.width, wrapper.height) :\n\t\t\t\t\t\trenderer.rect(boxX, boxY, wrapper.width, wrapper.height, 0, deferredAttr[STROKE_WIDTH]);\n\t\t\t\t\tbox.add(wrapper);\n\t\t\t\t}\n\n\t\t\t\t// apply the box attributes\n\t\t\t\tif (!box.isImg) { // #1630\n\t\t\t\t\tbox.attr(merge({\n\t\t\t\t\t\twidth: wrapper.width,\n\t\t\t\t\t\theight: wrapper.height\n\t\t\t\t\t}, deferredAttr));\n\t\t\t\t}\n\t\t\t\tdeferredAttr = null;\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * This function runs after setting text or padding, but only if padding is changed\n\t\t */\n\t\tfunction updateTextPadding() {\n\t\t\tvar styles = wrapper.styles,\n\t\t\t\ttextAlign = styles && styles.textAlign,\n\t\t\t\tx = paddingLeft + padding * (1 - alignFactor),\n\t\t\t\ty;\n\n\t\t\t// determin y based on the baseline\n\t\t\ty = baseline ? 0 : baselineOffset;\n\n\t\t\t// compensate for alignment\n\t\t\tif (defined(width) && (textAlign === 'center' || textAlign === 'right')) {\n\t\t\t\tx += { center: 0.5, right: 1 }[textAlign] * (width - bBox.width);\n\t\t\t}\n\n\t\t\t// update if anything changed\n\t\t\tif (x !== text.x || y !== text.y) {\n\t\t\t\ttext.attr({\n\t\t\t\t\tx: x,\n\t\t\t\t\ty: y\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// record current values\n\t\t\ttext.x = x;\n\t\t\ttext.y = y;\n\t\t}\n\n\t\t/**\n\t\t * Set a box attribute, or defer it if the box is not yet created\n\t\t * @param {Object} key\n\t\t * @param {Object} value\n\t\t */\n\t\tfunction boxAttr(key, value) {\n\t\t\tif (box) {\n\t\t\t\tbox.attr(key, value);\n\t\t\t} else {\n\t\t\t\tdeferredAttr[key] = value;\n\t\t\t}\n\t\t}\n\n\t\tfunction getSizeAfterAdd() {\n\t\t\ttext.add(wrapper);\n\t\t\twrapper.attr({\n\t\t\t\ttext: str, // alignment is available now\n\t\t\t\tx: x,\n\t\t\t\ty: y\n\t\t\t});\n\n\t\t\tif (box && defined(anchorX)) {\n\t\t\t\twrapper.attr({\n\t\t\t\t\tanchorX: anchorX,\n\t\t\t\t\tanchorY: anchorY\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * After the text element is added, get the desired size of the border box\n\t\t * and add it before the text in the DOM.\n\t\t */\n\t\taddEvent(wrapper, 'add', getSizeAfterAdd);\n\n\t\t/*\n\t\t * Add specific attribute setters.\n\t\t */\n\n\t\t// only change local variables\n\t\tattrSetters.width = function (value) {\n\t\t\twidth = value;\n\t\t\treturn false;\n\t\t};\n\t\tattrSetters.height = function (value) {\n\t\t\theight = value;\n\t\t\treturn false;\n\t\t};\n\t\tattrSetters.padding =  function (value) {\n\t\t\tif (defined(value) && value !== padding) {\n\t\t\t\tpadding = value;\n\t\t\t\tupdateTextPadding();\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\t\tattrSetters.paddingLeft =  function (value) {\n\t\t\tif (defined(value) && value !== paddingLeft) {\n\t\t\t\tpaddingLeft = value;\n\t\t\t\tupdateTextPadding();\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\n\t\t// change local variable and set attribue as well\n\t\tattrSetters.align = function (value) {\n\t\t\talignFactor = { left: 0, center: 0.5, right: 1 }[value];\n\t\t\treturn false; // prevent setting text-anchor on the group\n\t\t};\n\n\t\t// apply these to the box and the text alike\n\t\tattrSetters.text = function (value, key) {\n\t\t\ttext.attr(key, value);\n\t\t\tupdateBoxSize();\n\t\t\tupdateTextPadding();\n\t\t\treturn false;\n\t\t};\n\n\t\t// apply these to the box but not to the text\n\t\tattrSetters[STROKE_WIDTH] = function (value, key) {\n\t\t\tneedsBox = true;\n\t\t\tcrispAdjust = value % 2 / 2;\n\t\t\tboxAttr(key, value);\n\t\t\treturn false;\n\t\t};\n\t\tattrSetters.stroke = attrSetters.fill = attrSetters.r = function (value, key) {\n\t\t\tif (key === 'fill') {\n\t\t\t\tneedsBox = true;\n\t\t\t}\n\t\t\tboxAttr(key, value);\n\t\t\treturn false;\n\t\t};\n\t\tattrSetters.anchorX = function (value, key) {\n\t\t\tanchorX = value;\n\t\t\tboxAttr(key, value + crispAdjust - wrapperX);\n\t\t\treturn false;\n\t\t};\n\t\tattrSetters.anchorY = function (value, key) {\n\t\t\tanchorY = value;\n\t\t\tboxAttr(key, value - wrapperY);\n\t\t\treturn false;\n\t\t};\n\n\t\t// rename attributes\n\t\tattrSetters.x = function (value) {\n\t\t\twrapper.x = value; // for animation getter\n\t\t\tvalue -= alignFactor * ((width || bBox.width) + padding);\n\t\t\twrapperX = mathRound(value);\n\n\t\t\twrapper.attr('translateX', wrapperX);\n\t\t\treturn false;\n\t\t};\n\t\tattrSetters.y = function (value) {\n\t\t\twrapperY = wrapper.y = mathRound(value);\n\t\t\twrapper.attr('translateY', wrapperY);\n\t\t\treturn false;\n\t\t};\n\n\t\t// Redirect certain methods to either the box or the text\n\t\tvar baseCss = wrapper.css;\n\t\treturn extend(wrapper, {\n\t\t\t/**\n\t\t\t * Pick up some properties and apply them to the text instead of the wrapper\n\t\t\t */\n\t\t\tcss: function (styles) {\n\t\t\t\tif (styles) {\n\t\t\t\t\tvar textStyles = {};\n\t\t\t\t\tstyles = merge(styles); // create a copy to avoid altering the original object (#537)\n\t\t\t\t\teach(['fontSize', 'fontWeight', 'fontFamily', 'color', 'lineHeight', 'width', 'textDecoration', 'textShadow'], function (prop) {\n\t\t\t\t\t\tif (styles[prop] !== UNDEFINED) {\n\t\t\t\t\t\t\ttextStyles[prop] = styles[prop];\n\t\t\t\t\t\t\tdelete styles[prop];\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\ttext.css(textStyles);\n\t\t\t\t}\n\t\t\t\treturn baseCss.call(wrapper, styles);\n\t\t\t},\n\t\t\t/**\n\t\t\t * Return the bounding box of the box, not the group\n\t\t\t */\n\t\t\tgetBBox: function () {\n\t\t\t\treturn {\n\t\t\t\t\twidth: bBox.width + 2 * padding,\n\t\t\t\t\theight: bBox.height + 2 * padding,\n\t\t\t\t\tx: bBox.x - padding,\n\t\t\t\t\ty: bBox.y - padding\n\t\t\t\t};\n\t\t\t},\n\t\t\t/**\n\t\t\t * Apply the shadow to the box\n\t\t\t */\n\t\t\tshadow: function (b) {\n\t\t\t\tif (box) {\n\t\t\t\t\tbox.shadow(b);\n\t\t\t\t}\n\t\t\t\treturn wrapper;\n\t\t\t},\n\t\t\t/**\n\t\t\t * Destroy and release memory.\n\t\t\t */\n\t\t\tdestroy: function () {\n\t\t\t\tremoveEvent(wrapper, 'add', getSizeAfterAdd);\n\n\t\t\t\t// Added by button implementation\n\t\t\t\tremoveEvent(wrapper.element, 'mouseenter');\n\t\t\t\tremoveEvent(wrapper.element, 'mouseleave');\n\n\t\t\t\tif (text) {\n\t\t\t\t\ttext = text.destroy();\n\t\t\t\t}\n\t\t\t\tif (box) {\n\t\t\t\t\tbox = box.destroy();\n\t\t\t\t}\n\t\t\t\t// Call base implementation to destroy the rest\n\t\t\t\tSVGElement.prototype.destroy.call(wrapper);\n\n\t\t\t\t// Release local pointers (#1298)\n\t\t\t\twrapper = renderer = updateBoxSize = updateTextPadding = boxAttr = getSizeAfterAdd = null;\n\t\t\t}\n\t\t});\n\t}\n}; // end SVGRenderer\n\n\n// general renderer\nRenderer = SVGRenderer;\n\n\n/* ****************************************************************************\n *                                                                            *\n * START OF INTERNET EXPLORER <= 8 SPECIFIC CODE                              *\n *                                                                            *\n * For applications and websites that don't need IE support, like platform    *\n * targeted mobile apps and web apps, this code can be removed.               *\n *                                                                            *\n *****************************************************************************/\n\n/**\n * @constructor\n */\nvar VMLRenderer, VMLElement;\nif (!hasSVG && !useCanVG) {\n\n/**\n * The VML element wrapper.\n */\nHighcharts.VMLElement = VMLElement = {\n\n\t/**\n\t * Initialize a new VML element wrapper. It builds the markup as a string\n\t * to minimize DOM traffic.\n\t * @param {Object} renderer\n\t * @param {Object} nodeName\n\t */\n\tinit: function (renderer, nodeName) {\n\t\tvar wrapper = this,\n\t\t\tmarkup =  ['<', nodeName, ' filled=\"f\" stroked=\"f\"'],\n\t\t\tstyle = ['position: ', ABSOLUTE, ';'],\n\t\t\tisDiv = nodeName === DIV;\n\n\t\t// divs and shapes need size\n\t\tif (nodeName === 'shape' || isDiv) {\n\t\t\tstyle.push('left:0;top:0;width:1px;height:1px;');\n\t\t}\n\t\tstyle.push('visibility: ', isDiv ? HIDDEN : VISIBLE);\n\n\t\tmarkup.push(' style=\"', style.join(''), '\"/>');\n\n\t\t// create element with default attributes and style\n\t\tif (nodeName) {\n\t\t\tmarkup = isDiv || nodeName === 'span' || nodeName === 'img' ?\n\t\t\t\tmarkup.join('')\n\t\t\t\t: renderer.prepVML(markup);\n\t\t\twrapper.element = createElement(markup);\n\t\t}\n\n\t\twrapper.renderer = renderer;\n\t\twrapper.attrSetters = {};\n\t},\n\n\t/**\n\t * Add the node to the given parent\n\t * @param {Object} parent\n\t */\n\tadd: function (parent) {\n\t\tvar wrapper = this,\n\t\t\trenderer = wrapper.renderer,\n\t\t\telement = wrapper.element,\n\t\t\tbox = renderer.box,\n\t\t\tinverted = parent && parent.inverted,\n\n\t\t\t// get the parent node\n\t\t\tparentNode = parent ?\n\t\t\t\tparent.element || parent :\n\t\t\t\tbox;\n\n\n\t\t// if the parent group is inverted, apply inversion on all children\n\t\tif (inverted) { // only on groups\n\t\t\trenderer.invertChild(element, parentNode);\n\t\t}\n\n\t\t// append it\n\t\tparentNode.appendChild(element);\n\n\t\t// align text after adding to be able to read offset\n\t\twrapper.added = true;\n\t\tif (wrapper.alignOnAdd && !wrapper.deferUpdateTransform) {\n\t\t\twrapper.updateTransform();\n\t\t}\n\n\t\t// fire an event for internal hooks\n\t\tfireEvent(wrapper, 'add');\n\n\t\treturn wrapper;\n\t},\n\n\t/**\n\t * VML always uses htmlUpdateTransform\n\t */\n\tupdateTransform: SVGElement.prototype.htmlUpdateTransform,\n\n\t/**\n\t * Set the rotation of a span with oldIE's filter\n\t */\n\tsetSpanRotation: function (rotation, sintheta, costheta) {\n\t\t// Adjust for alignment and rotation. Rotation of useHTML content is not yet implemented\n\t\t// but it can probably be implemented for Firefox 3.5+ on user request. FF3.5+\n\t\t// has support for CSS3 transform. The getBBox method also needs to be updated\n\t\t// to compensate for the rotation, like it currently does for SVG.\n\t\t// Test case: http://highcharts.com/tests/?file=text-rotation\n\t\tcss(this.element, {\n\t\t\tfilter: rotation ? ['progid:DXImageTransform.Microsoft.Matrix(M11=', costheta,\n\t\t\t\t', M12=', -sintheta, ', M21=', sintheta, ', M22=', costheta,\n\t\t\t\t', sizingMethod=\\'auto expand\\')'].join('') : NONE\n\t\t});\n\t},\n\n\t/**\n\t * Converts a subset of an SVG path definition to its VML counterpart. Takes an array\n\t * as the parameter and returns a string.\n\t */\n\tpathToVML: function (value) {\n\t\t// convert paths\n\t\tvar i = value.length,\n\t\t\tpath = [],\n\t\t\tclockwise;\n\n\t\twhile (i--) {\n\n\t\t\t// Multiply by 10 to allow subpixel precision.\n\t\t\t// Substracting half a pixel seems to make the coordinates\n\t\t\t// align with SVG, but this hasn't been tested thoroughly\n\t\t\tif (isNumber(value[i])) {\n\t\t\t\tpath[i] = mathRound(value[i] * 10) - 5;\n\t\t\t} else if (value[i] === 'Z') { // close the path\n\t\t\t\tpath[i] = 'x';\n\t\t\t} else {\n\t\t\t\tpath[i] = value[i];\n\n\t\t\t\t// When the start X and end X coordinates of an arc are too close,\n\t\t\t\t// they are rounded to the same value above. In this case, substract 1 from the end X\n\t\t\t\t// position. #760, #1371.\n\t\t\t\tif (value.isArc && (value[i] === 'wa' || value[i] === 'at')) {\n\t\t\t\t\tclockwise = value[i] === 'wa' ? 1 : -1; // #1642\n\t\t\t\t\tif (path[i + 5] === path[i + 7]) {\n\t\t\t\t\t\tpath[i + 7] -= clockwise;\n\t\t\t\t\t}\n\t\t\t\t\t// Start and end Y (#1410)\n\t\t\t\t\tif (path[i + 6] === path[i + 8]) {\n\t\t\t\t\t\tpath[i + 8] -= clockwise;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Loop up again to handle path shortcuts (#2132)\n\t\t/*while (i++ < path.length) {\n\t\t\tif (path[i] === 'H') { // horizontal line to\n\t\t\t\tpath[i] = 'L';\n\t\t\t\tpath.splice(i + 2, 0, path[i - 1]);\n\t\t\t} else if (path[i] === 'V') { // vertical line to\n\t\t\t\tpath[i] = 'L';\n\t\t\t\tpath.splice(i + 1, 0, path[i - 2]);\n\t\t\t}\n\t\t}*/\n\t\treturn path.join(' ') || 'x';\n\t},\n\n\t/**\n\t * Get or set attributes\n\t */\n\tattr: function (hash, val) {\n\t\tvar wrapper = this,\n\t\t\tkey,\n\t\t\tvalue,\n\t\t\ti,\n\t\t\tresult,\n\t\t\telement = wrapper.element || {},\n\t\t\telemStyle = element.style,\n\t\t\tnodeName = element.nodeName,\n\t\t\trenderer = wrapper.renderer,\n\t\t\tsymbolName = wrapper.symbolName,\n\t\t\thasSetSymbolSize,\n\t\t\tshadows = wrapper.shadows,\n\t\t\tskipAttr,\n\t\t\tattrSetters = wrapper.attrSetters,\n\t\t\tret = wrapper;\n\n\t\t// single key-value pair\n\t\tif (isString(hash) && defined(val)) {\n\t\t\tkey = hash;\n\t\t\thash = {};\n\t\t\thash[key] = val;\n\t\t}\n\n\t\t// used as a getter, val is undefined\n\t\tif (isString(hash)) {\n\t\t\tkey = hash;\n\t\t\tif (key === 'strokeWidth' || key === 'stroke-width') {\n\t\t\t\tret = wrapper.strokeweight;\n\t\t\t} else {\n\t\t\t\tret = wrapper[key];\n\t\t\t}\n\n\t\t// setter\n\t\t} else {\n\t\t\tfor (key in hash) {\n\t\t\t\tvalue = hash[key];\n\t\t\t\tskipAttr = false;\n\n\t\t\t\t// check for a specific attribute setter\n\t\t\t\tresult = attrSetters[key] && attrSetters[key].call(wrapper, value, key);\n\n\t\t\t\tif (result !== false && value !== null) { // #620\n\n\t\t\t\t\tif (result !== UNDEFINED) {\n\t\t\t\t\t\tvalue = result; // the attribute setter has returned a new value to set\n\t\t\t\t\t}\n\n\n\t\t\t\t\t// prepare paths\n\t\t\t\t\t// symbols\n\t\t\t\t\tif (symbolName && /^(x|y|r|start|end|width|height|innerR|anchorX|anchorY)/.test(key)) {\n\t\t\t\t\t\t// if one of the symbol size affecting parameters are changed,\n\t\t\t\t\t\t// check all the others only once for each call to an element's\n\t\t\t\t\t\t// .attr() method\n\t\t\t\t\t\tif (!hasSetSymbolSize) {\n\t\t\t\t\t\t\twrapper.symbolAttr(hash);\n\n\t\t\t\t\t\t\thasSetSymbolSize = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tskipAttr = true;\n\n\t\t\t\t\t} else if (key === 'd') {\n\t\t\t\t\t\tvalue = value || [];\n\t\t\t\t\t\twrapper.d = value.join(' '); // used in getter for animation\n\n\t\t\t\t\t\telement.path = value = wrapper.pathToVML(value);\n\n\t\t\t\t\t\t// update shadows\n\t\t\t\t\t\tif (shadows) {\n\t\t\t\t\t\t\ti = shadows.length;\n\t\t\t\t\t\t\twhile (i--) {\n\t\t\t\t\t\t\t\tshadows[i].path = shadows[i].cutOff ? this.cutOffPath(value, shadows[i].cutOff) : value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tskipAttr = true;\n\n\t\t\t\t\t// handle visibility\n\t\t\t\t\t} else if (key === 'visibility') {\n\n\t\t\t\t\t\t// let the shadow follow the main element\n\t\t\t\t\t\tif (shadows) {\n\t\t\t\t\t\t\ti = shadows.length;\n\t\t\t\t\t\t\twhile (i--) {\n\t\t\t\t\t\t\t\tshadows[i].style[key] = value;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Instead of toggling the visibility CSS property, move the div out of the viewport.\n\t\t\t\t\t\t// This works around #61 and #586\n\t\t\t\t\t\tif (nodeName === 'DIV') {\n\t\t\t\t\t\t\tvalue = value === HIDDEN ? '-999em' : 0;\n\n\t\t\t\t\t\t\t// In order to redraw, IE7 needs the div to be visible when tucked away\n\t\t\t\t\t\t\t// outside the viewport. So the visibility is actually opposite of\n\t\t\t\t\t\t\t// the expected value. This applies to the tooltip only.\n\t\t\t\t\t\t\tif (!docMode8) {\n\t\t\t\t\t\t\t\telemStyle[key] = value ? VISIBLE : HIDDEN;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tkey = 'top';\n\t\t\t\t\t\t}\n\t\t\t\t\t\telemStyle[key] = value;\n\t\t\t\t\t\tskipAttr = true;\n\n\t\t\t\t\t// directly mapped to css\n\t\t\t\t\t} else if (key === 'zIndex') {\n\n\t\t\t\t\t\tif (value) {\n\t\t\t\t\t\t\telemStyle[key] = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tskipAttr = true;\n\n\t\t\t\t\t// x, y, width, height\n\t\t\t\t\t} else if (inArray(key, ['x', 'y', 'width', 'height']) !== -1) {\n\n\t\t\t\t\t\twrapper[key] = value; // used in getter\n\n\t\t\t\t\t\tif (key === 'x' || key === 'y') {\n\t\t\t\t\t\t\tkey = { x: 'left', y: 'top' }[key];\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tvalue = mathMax(0, value); // don't set width or height below zero (#311)\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// clipping rectangle special\n\t\t\t\t\t\tif (wrapper.updateClipping) {\n\t\t\t\t\t\t\twrapper[key] = value; // the key is now 'left' or 'top' for 'x' and 'y'\n\t\t\t\t\t\t\twrapper.updateClipping();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// normal\n\t\t\t\t\t\t\telemStyle[key] = value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tskipAttr = true;\n\n\t\t\t\t\t// class name\n\t\t\t\t\t} else if (key === 'class' && nodeName === 'DIV') {\n\t\t\t\t\t\t// IE8 Standards mode has problems retrieving the className\n\t\t\t\t\t\telement.className = value;\n\n\t\t\t\t\t// stroke\n\t\t\t\t\t} else if (key === 'stroke') {\n\n\t\t\t\t\t\tvalue = renderer.color(value, element, key);\n\n\t\t\t\t\t\tkey = 'strokecolor';\n\n\t\t\t\t\t// stroke width\n\t\t\t\t\t} else if (key === 'stroke-width' || key === 'strokeWidth') {\n\t\t\t\t\t\telement.stroked = value ? true : false;\n\t\t\t\t\t\tkey = 'strokeweight';\n\t\t\t\t\t\twrapper[key] = value; // used in getter, issue #113\n\t\t\t\t\t\tif (isNumber(value)) {\n\t\t\t\t\t\t\tvalue += PX;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// dashStyle\n\t\t\t\t\t} else if (key === 'dashstyle') {\n\t\t\t\t\t\tvar strokeElem = element.getElementsByTagName('stroke')[0] ||\n\t\t\t\t\t\t\tcreateElement(renderer.prepVML(['<stroke/>']), null, null, element);\n\t\t\t\t\t\tstrokeElem[key] = value || 'solid';\n\t\t\t\t\t\twrapper.dashstyle = value; /* because changing stroke-width will change the dash length\n\t\t\t\t\t\t\tand cause an epileptic effect */\n\t\t\t\t\t\tskipAttr = true;\n\n\t\t\t\t\t// fill\n\t\t\t\t\t} else if (key === 'fill') {\n\n\t\t\t\t\t\tif (nodeName === 'SPAN') { // text color\n\t\t\t\t\t\t\telemStyle.color = value;\n\t\t\t\t\t\t} else if (nodeName !== 'IMG') { // #1336\n\t\t\t\t\t\t\telement.filled = value !== NONE ? true : false;\n\n\t\t\t\t\t\t\tvalue = renderer.color(value, element, key, wrapper);\n\n\t\t\t\t\t\t\tkey = 'fillcolor';\n\t\t\t\t\t\t}\n\n\t\t\t\t\t// opacity: don't bother - animation is too slow and filters introduce artifacts\n\t\t\t\t\t} else if (key === 'opacity') {\n\t\t\t\t\t\t/*css(element, {\n\t\t\t\t\t\t\topacity: value\n\t\t\t\t\t\t});*/\n\t\t\t\t\t\tskipAttr = true;\n\n\t\t\t\t\t// rotation on VML elements\n\t\t\t\t\t} else if (nodeName === 'shape' && key === 'rotation') {\n\n\t\t\t\t\t\twrapper[key] = element.style[key] = value; // style is for #1873\n\n\t\t\t\t\t\t// Correction for the 1x1 size of the shape container. Used in gauge needles.\n\t\t\t\t\t\telement.style.left = -mathRound(mathSin(value * deg2rad) + 1) + PX;\n\t\t\t\t\t\telement.style.top = mathRound(mathCos(value * deg2rad)) + PX;\n\n\t\t\t\t\t// translation for animation\n\t\t\t\t\t} else if (key === 'translateX' || key === 'translateY' || key === 'rotation') {\n\t\t\t\t\t\twrapper[key] = value;\n\t\t\t\t\t\twrapper.updateTransform();\n\n\t\t\t\t\t\tskipAttr = true;\n\n\t\t\t\t\t// text for rotated and non-rotated elements\n\t\t\t\t\t} else if (key === 'text') {\n\t\t\t\t\t\tthis.bBox = null;\n\t\t\t\t\t\telement.innerHTML = value;\n\t\t\t\t\t\tskipAttr = true;\n\t\t\t\t\t}\n\n\n\t\t\t\t\tif (!skipAttr) {\n\t\t\t\t\t\tif (docMode8) { // IE8 setAttribute bug\n\t\t\t\t\t\t\telement[key] = value;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tattr(element, key, value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t},\n\n\t/**\n\t * Set the element's clipping to a predefined rectangle\n\t *\n\t * @param {String} id The id of the clip rectangle\n\t */\n\tclip: function (clipRect) {\n\t\tvar wrapper = this,\n\t\t\tclipMembers,\n\t\t\tcssRet;\n\n\t\tif (clipRect) {\n\t\t\tclipMembers = clipRect.members;\n\t\t\terase(clipMembers, wrapper); // Ensure unique list of elements (#1258)\n\t\t\tclipMembers.push(wrapper);\n\t\t\twrapper.destroyClip = function () {\n\t\t\t\terase(clipMembers, wrapper);\n\t\t\t};\n\t\t\tcssRet = clipRect.getCSS(wrapper);\n\n\t\t} else {\n\t\t\tif (wrapper.destroyClip) {\n\t\t\t\twrapper.destroyClip();\n\t\t\t}\n\t\t\tcssRet = { clip: docMode8 ? 'inherit' : 'rect(auto)' }; // #1214\n\t\t}\n\n\t\treturn wrapper.css(cssRet);\n\n\t},\n\n\t/**\n\t * Set styles for the element\n\t * @param {Object} styles\n\t */\n\tcss: SVGElement.prototype.htmlCss,\n\n\t/**\n\t * Removes a child either by removeChild or move to garbageBin.\n\t * Issue 490; in VML removeChild results in Orphaned nodes according to sIEve, discardElement does not.\n\t */\n\tsafeRemoveChild: function (element) {\n\t\t// discardElement will detach the node from its parent before attaching it\n\t\t// to the garbage bin. Therefore it is important that the node is attached and have parent.\n\t\tif (element.parentNode) {\n\t\t\tdiscardElement(element);\n\t\t}\n\t},\n\n\t/**\n\t * Extend element.destroy by removing it from the clip members array\n\t */\n\tdestroy: function () {\n\t\tif (this.destroyClip) {\n\t\t\tthis.destroyClip();\n\t\t}\n\n\t\treturn SVGElement.prototype.destroy.apply(this);\n\t},\n\n\t/**\n\t * Add an event listener. VML override for normalizing event parameters.\n\t * @param {String} eventType\n\t * @param {Function} handler\n\t */\n\ton: function (eventType, handler) {\n\t\t// simplest possible event model for internal use\n\t\tthis.element['on' + eventType] = function () {\n\t\t\tvar evt = win.event;\n\t\t\tevt.target = evt.srcElement;\n\t\t\thandler(evt);\n\t\t};\n\t\treturn this;\n\t},\n\n\t/**\n\t * In stacked columns, cut off the shadows so that they don't overlap\n\t */\n\tcutOffPath: function (path, length) {\n\n\t\tvar len;\n\n\t\tpath = path.split(/[ ,]/);\n\t\tlen = path.length;\n\n\t\tif (len === 9 || len === 11) {\n\t\t\tpath[len - 4] = path[len - 2] = pInt(path[len - 2]) - 10 * length;\n\t\t}\n\t\treturn path.join(' ');\n\t},\n\n\t/**\n\t * Apply a drop shadow by copying elements and giving them different strokes\n\t * @param {Boolean|Object} shadowOptions\n\t */\n\tshadow: function (shadowOptions, group, cutOff) {\n\t\tvar shadows = [],\n\t\t\ti,\n\t\t\telement = this.element,\n\t\t\trenderer = this.renderer,\n\t\t\tshadow,\n\t\t\telemStyle = element.style,\n\t\t\tmarkup,\n\t\t\tpath = element.path,\n\t\t\tstrokeWidth,\n\t\t\tmodifiedPath,\n\t\t\tshadowWidth,\n\t\t\tshadowElementOpacity;\n\n\t\t// some times empty paths are not strings\n\t\tif (path && typeof path.value !== 'string') {\n\t\t\tpath = 'x';\n\t\t}\n\t\tmodifiedPath = path;\n\n\t\tif (shadowOptions) {\n\t\t\tshadowWidth = pick(shadowOptions.width, 3);\n\t\t\tshadowElementOpacity = (shadowOptions.opacity || 0.15) / shadowWidth;\n\t\t\tfor (i = 1; i <= 3; i++) {\n\n\t\t\t\tstrokeWidth = (shadowWidth * 2) + 1 - (2 * i);\n\n\t\t\t\t// Cut off shadows for stacked column items\n\t\t\t\tif (cutOff) {\n\t\t\t\t\tmodifiedPath = this.cutOffPath(path.value, strokeWidth + 0.5);\n\t\t\t\t}\n\n\t\t\t\tmarkup = ['<shape isShadow=\"true\" strokeweight=\"', strokeWidth,\n\t\t\t\t\t'\" filled=\"false\" path=\"', modifiedPath,\n\t\t\t\t\t'\" coordsize=\"10 10\" style=\"', element.style.cssText, '\" />'];\n\n\t\t\t\tshadow = createElement(renderer.prepVML(markup),\n\t\t\t\t\tnull, {\n\t\t\t\t\t\tleft: pInt(elemStyle.left) + pick(shadowOptions.offsetX, 1),\n\t\t\t\t\t\ttop: pInt(elemStyle.top) + pick(shadowOptions.offsetY, 1)\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t\tif (cutOff) {\n\t\t\t\t\tshadow.cutOff = strokeWidth + 1;\n\t\t\t\t}\n\n\t\t\t\t// apply the opacity\n\t\t\t\tmarkup = ['<stroke color=\"', shadowOptions.color || 'black', '\" opacity=\"', shadowElementOpacity * i, '\"/>'];\n\t\t\t\tcreateElement(renderer.prepVML(markup), null, null, shadow);\n\n\n\t\t\t\t// insert it\n\t\t\t\tif (group) {\n\t\t\t\t\tgroup.element.appendChild(shadow);\n\t\t\t\t} else {\n\t\t\t\t\telement.parentNode.insertBefore(shadow, element);\n\t\t\t\t}\n\n\t\t\t\t// record it\n\t\t\t\tshadows.push(shadow);\n\n\t\t\t}\n\n\t\t\tthis.shadows = shadows;\n\t\t}\n\t\treturn this;\n\n\t}\n};\nVMLElement = extendClass(SVGElement, VMLElement);\n\n/**\n * The VML renderer\n */\nvar VMLRendererExtension = { // inherit SVGRenderer\n\n\tElement: VMLElement,\n\tisIE8: userAgent.indexOf('MSIE 8.0') > -1,\n\n\n\t/**\n\t * Initialize the VMLRenderer\n\t * @param {Object} container\n\t * @param {Number} width\n\t * @param {Number} height\n\t */\n\tinit: function (container, width, height) {\n\t\tvar renderer = this,\n\t\t\tboxWrapper,\n\t\t\tbox;\n\n\t\trenderer.alignedObjects = [];\n\n\t\tboxWrapper = renderer.createElement(DIV);\n\t\tbox = boxWrapper.element;\n\t\tbox.style.position = RELATIVE; // for freeform drawing using renderer directly\n\t\tcontainer.appendChild(boxWrapper.element);\n\n\n\t\t// generate the containing box\n\t\trenderer.isVML = true;\n\t\trenderer.box = box;\n\t\trenderer.boxWrapper = boxWrapper;\n\n\n\t\trenderer.setSize(width, height, false);\n\n\t\t// The only way to make IE6 and IE7 print is to use a global namespace. However,\n\t\t// with IE8 the only way to make the dynamic shapes visible in screen and print mode\n\t\t// seems to be to add the xmlns attribute and the behaviour style inline.\n\t\tif (!doc.namespaces.hcv) {\n\n\t\t\tdoc.namespaces.add('hcv', 'urn:schemas-microsoft-com:vml');\n\n\t\t\t// Setup default CSS (#2153)\n\t\t\t(doc.styleSheets.length ? doc.styleSheets[0] : doc.createStyleSheet()).cssText +=\n\t\t\t\t'hcv\\\\:fill, hcv\\\\:path, hcv\\\\:shape, hcv\\\\:stroke' +\n\t\t\t\t'{ behavior:url(#default#VML); display: inline-block; } ';\n\n\t\t}\n\t},\n\n\n\t/**\n\t * Detect whether the renderer is hidden. This happens when one of the parent elements\n\t * has display: none\n\t */\n\tisHidden: function () {\n\t\treturn !this.box.offsetWidth;\n\t},\n\n\t/**\n\t * Define a clipping rectangle. In VML it is accomplished by storing the values\n\t * for setting the CSS style to all associated members.\n\t *\n\t * @param {Number} x\n\t * @param {Number} y\n\t * @param {Number} width\n\t * @param {Number} height\n\t */\n\tclipRect: function (x, y, width, height) {\n\n\t\t// create a dummy element\n\t\tvar clipRect = this.createElement(),\n\t\t\tisObj = isObject(x);\n\n\t\t// mimic a rectangle with its style object for automatic updating in attr\n\t\treturn extend(clipRect, {\n\t\t\tmembers: [],\n\t\t\tleft: (isObj ? x.x : x) + 1,\n\t\t\ttop: (isObj ? x.y : y) + 1,\n\t\t\twidth: (isObj ? x.width : width) - 1,\n\t\t\theight: (isObj ? x.height : height) - 1,\n\t\t\tgetCSS: function (wrapper) {\n\t\t\t\tvar element = wrapper.element,\n\t\t\t\t\tnodeName = element.nodeName,\n\t\t\t\t\tisShape = nodeName === 'shape',\n\t\t\t\t\tinverted = wrapper.inverted,\n\t\t\t\t\trect = this,\n\t\t\t\t\ttop = rect.top - (isShape ? element.offsetTop : 0),\n\t\t\t\t\tleft = rect.left,\n\t\t\t\t\tright = left + rect.width,\n\t\t\t\t\tbottom = top + rect.height,\n\t\t\t\t\tret = {\n\t\t\t\t\t\tclip: 'rect(' +\n\t\t\t\t\t\t\tmathRound(inverted ? left : top) + 'px,' +\n\t\t\t\t\t\t\tmathRound(inverted ? bottom : right) + 'px,' +\n\t\t\t\t\t\t\tmathRound(inverted ? right : bottom) + 'px,' +\n\t\t\t\t\t\t\tmathRound(inverted ? top : left) + 'px)'\n\t\t\t\t\t};\n\n\t\t\t\t// issue 74 workaround\n\t\t\t\tif (!inverted && docMode8 && nodeName === 'DIV') {\n\t\t\t\t\textend(ret, {\n\t\t\t\t\t\twidth: right + PX,\n\t\t\t\t\t\theight: bottom + PX\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn ret;\n\t\t\t},\n\n\t\t\t// used in attr and animation to update the clipping of all members\n\t\t\tupdateClipping: function () {\n\t\t\t\teach(clipRect.members, function (member) {\n\t\t\t\t\tmember.css(clipRect.getCSS(member));\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\n\t},\n\n\n\t/**\n\t * Take a color and return it if it's a string, make it a gradient if it's a\n\t * gradient configuration object, and apply opacity.\n\t *\n\t * @param {Object} color The color or config object\n\t */\n\tcolor: function (color, elem, prop, wrapper) {\n\t\tvar renderer = this,\n\t\t\tcolorObject,\n\t\t\tregexRgba = /^rgba/,\n\t\t\tmarkup,\n\t\t\tfillType,\n\t\t\tret = NONE;\n\n\t\t// Check for linear or radial gradient\n\t\tif (color && color.linearGradient) {\n\t\t\tfillType = 'gradient';\n\t\t} else if (color && color.radialGradient) {\n\t\t\tfillType = 'pattern';\n\t\t}\n\n\n\t\tif (fillType) {\n\n\t\t\tvar stopColor,\n\t\t\t\tstopOpacity,\n\t\t\t\tgradient = color.linearGradient || color.radialGradient,\n\t\t\t\tx1,\n\t\t\t\ty1,\n\t\t\t\tx2,\n\t\t\t\ty2,\n\t\t\t\topacity1,\n\t\t\t\topacity2,\n\t\t\t\tcolor1,\n\t\t\t\tcolor2,\n\t\t\t\tfillAttr = '',\n\t\t\t\tstops = color.stops,\n\t\t\t\tfirstStop,\n\t\t\t\tlastStop,\n\t\t\t\tcolors = [],\n\t\t\t\taddFillNode = function () {\n\t\t\t\t\t// Add the fill subnode. When colors attribute is used, the meanings of opacity and o:opacity2\n\t\t\t\t\t// are reversed.\n\t\t\t\t\tmarkup = ['<fill colors=\"' + colors.join(',') + '\" opacity=\"', opacity2, '\" o:opacity2=\"', opacity1,\n\t\t\t\t\t\t'\" type=\"', fillType, '\" ', fillAttr, 'focus=\"100%\" method=\"any\" />'];\n\t\t\t\t\tcreateElement(renderer.prepVML(markup), null, null, elem);\n\t\t\t\t};\n\n\t\t\t// Extend from 0 to 1\n\t\t\tfirstStop = stops[0];\n\t\t\tlastStop = stops[stops.length - 1];\n\t\t\tif (firstStop[0] > 0) {\n\t\t\t\tstops.unshift([\n\t\t\t\t\t0,\n\t\t\t\t\tfirstStop[1]\n\t\t\t\t]);\n\t\t\t}\n\t\t\tif (lastStop[0] < 1) {\n\t\t\t\tstops.push([\n\t\t\t\t\t1,\n\t\t\t\t\tlastStop[1]\n\t\t\t\t]);\n\t\t\t}\n\n\t\t\t// Compute the stops\n\t\t\teach(stops, function (stop, i) {\n\t\t\t\tif (regexRgba.test(stop[1])) {\n\t\t\t\t\tcolorObject = Color(stop[1]);\n\t\t\t\t\tstopColor = colorObject.get('rgb');\n\t\t\t\t\tstopOpacity = colorObject.get('a');\n\t\t\t\t} else {\n\t\t\t\t\tstopColor = stop[1];\n\t\t\t\t\tstopOpacity = 1;\n\t\t\t\t}\n\n\t\t\t\t// Build the color attribute\n\t\t\t\tcolors.push((stop[0] * 100) + '% ' + stopColor);\n\n\t\t\t\t// Only start and end opacities are allowed, so we use the first and the last\n\t\t\t\tif (!i) {\n\t\t\t\t\topacity1 = stopOpacity;\n\t\t\t\t\tcolor2 = stopColor;\n\t\t\t\t} else {\n\t\t\t\t\topacity2 = stopOpacity;\n\t\t\t\t\tcolor1 = stopColor;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Apply the gradient to fills only.\n\t\t\tif (prop === 'fill') {\n\n\t\t\t\t// Handle linear gradient angle\n\t\t\t\tif (fillType === 'gradient') {\n\t\t\t\t\tx1 = gradient.x1 || gradient[0] || 0;\n\t\t\t\t\ty1 = gradient.y1 || gradient[1] || 0;\n\t\t\t\t\tx2 = gradient.x2 || gradient[2] || 0;\n\t\t\t\t\ty2 = gradient.y2 || gradient[3] || 0;\n\t\t\t\t\tfillAttr = 'angle=\"' + (90  - math.atan(\n\t\t\t\t\t\t(y2 - y1) / // y vector\n\t\t\t\t\t\t(x2 - x1) // x vector\n\t\t\t\t\t\t) * 180 / mathPI) + '\"';\n\n\t\t\t\t\taddFillNode();\n\n\t\t\t\t// Radial (circular) gradient\n\t\t\t\t} else {\n\n\t\t\t\t\tvar r = gradient.r,\n\t\t\t\t\t\tsizex = r * 2,\n\t\t\t\t\t\tsizey = r * 2,\n\t\t\t\t\t\tcx = gradient.cx,\n\t\t\t\t\t\tcy = gradient.cy,\n\t\t\t\t\t\tradialReference = elem.radialReference,\n\t\t\t\t\t\tbBox,\n\t\t\t\t\t\tapplyRadialGradient = function () {\n\t\t\t\t\t\t\tif (radialReference) {\n\t\t\t\t\t\t\t\tbBox = wrapper.getBBox();\n\t\t\t\t\t\t\t\tcx += (radialReference[0] - bBox.x) / bBox.width - 0.5;\n\t\t\t\t\t\t\t\tcy += (radialReference[1] - bBox.y) / bBox.height - 0.5;\n\t\t\t\t\t\t\t\tsizex *= radialReference[2] / bBox.width;\n\t\t\t\t\t\t\t\tsizey *= radialReference[2] / bBox.height;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tfillAttr = 'src=\"' + defaultOptions.global.VMLRadialGradientURL + '\" ' +\n\t\t\t\t\t\t\t\t'size=\"' + sizex + ',' + sizey + '\" ' +\n\t\t\t\t\t\t\t\t'origin=\"0.5,0.5\" ' +\n\t\t\t\t\t\t\t\t'position=\"' + cx + ',' + cy + '\" ' +\n\t\t\t\t\t\t\t\t'color2=\"' + color2 + '\" ';\n\n\t\t\t\t\t\t\taddFillNode();\n\t\t\t\t\t\t};\n\n\t\t\t\t\t// Apply radial gradient\n\t\t\t\t\tif (wrapper.added) {\n\t\t\t\t\t\tapplyRadialGradient();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// We need to know the bounding box to get the size and position right\n\t\t\t\t\t\taddEvent(wrapper, 'add', applyRadialGradient);\n\t\t\t\t\t}\n\n\t\t\t\t\t// The fill element's color attribute is broken in IE8 standards mode, so we\n\t\t\t\t\t// need to set the parent shape's fillcolor attribute instead.\n\t\t\t\t\tret = color1;\n\t\t\t\t}\n\n\t\t\t// Gradients are not supported for VML stroke, return the first color. #722.\n\t\t\t} else {\n\t\t\t\tret = stopColor;\n\t\t\t}\n\n\t\t// if the color is an rgba color, split it and add a fill node\n\t\t// to hold the opacity component\n\t\t} else if (regexRgba.test(color) && elem.tagName !== 'IMG') {\n\n\t\t\tcolorObject = Color(color);\n\n\t\t\tmarkup = ['<', prop, ' opacity=\"', colorObject.get('a'), '\"/>'];\n\t\t\tcreateElement(this.prepVML(markup), null, null, elem);\n\n\t\t\tret = colorObject.get('rgb');\n\n\n\t\t} else {\n\t\t\tvar propNodes = elem.getElementsByTagName(prop); // 'stroke' or 'fill' node\n\t\t\tif (propNodes.length) {\n\t\t\t\tpropNodes[0].opacity = 1;\n\t\t\t\tpropNodes[0].type = 'solid';\n\t\t\t}\n\t\t\tret = color;\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\t/**\n\t * Take a VML string and prepare it for either IE8 or IE6/IE7.\n\t * @param {Array} markup A string array of the VML markup to prepare\n\t */\n\tprepVML: function (markup) {\n\t\tvar vmlStyle = 'display:inline-block;behavior:url(#default#VML);',\n\t\t\tisIE8 = this.isIE8;\n\n\t\tmarkup = markup.join('');\n\n\t\tif (isIE8) { // add xmlns and style inline\n\t\t\tmarkup = markup.replace('/>', ' xmlns=\"urn:schemas-microsoft-com:vml\" />');\n\t\t\tif (markup.indexOf('style=\"') === -1) {\n\t\t\t\tmarkup = markup.replace('/>', ' style=\"' + vmlStyle + '\" />');\n\t\t\t} else {\n\t\t\t\tmarkup = markup.replace('style=\"', 'style=\"' + vmlStyle);\n\t\t\t}\n\n\t\t} else { // add namespace\n\t\t\tmarkup = markup.replace('<', '<hcv:');\n\t\t}\n\n\t\treturn markup;\n\t},\n\n\t/**\n\t * Create rotated and aligned text\n\t * @param {String} str\n\t * @param {Number} x\n\t * @param {Number} y\n\t */\n\ttext: SVGRenderer.prototype.html,\n\n\t/**\n\t * Create and return a path element\n\t * @param {Array} path\n\t */\n\tpath: function (path) {\n\t\tvar attr = {\n\t\t\t// subpixel precision down to 0.1 (width and height = 1px)\n\t\t\tcoordsize: '10 10'\n\t\t};\n\t\tif (isArray(path)) {\n\t\t\tattr.d = path;\n\t\t} else if (isObject(path)) { // attributes\n\t\t\textend(attr, path);\n\t\t}\n\t\t// create the shape\n\t\treturn this.createElement('shape').attr(attr);\n\t},\n\n\t/**\n\t * Create and return a circle element. In VML circles are implemented as\n\t * shapes, which is faster than v:oval\n\t * @param {Number} x\n\t * @param {Number} y\n\t * @param {Number} r\n\t */\n\tcircle: function (x, y, r) {\n\t\tvar circle = this.symbol('circle');\n\t\tif (isObject(x)) {\n\t\t\tr = x.r;\n\t\t\ty = x.y;\n\t\t\tx = x.x;\n\t\t}\n\t\tcircle.isCircle = true; // Causes x and y to mean center (#1682)\n\t\tcircle.r = r;\n\t\treturn circle.attr({ x: x, y: y });\n\t},\n\n\t/**\n\t * Create a group using an outer div and an inner v:group to allow rotating\n\t * and flipping. A simple v:group would have problems with positioning\n\t * child HTML elements and CSS clip.\n\t *\n\t * @param {String} name The name of the group\n\t */\n\tg: function (name) {\n\t\tvar wrapper,\n\t\t\tattribs;\n\n\t\t// set the class name\n\t\tif (name) {\n\t\t\tattribs = { 'className': PREFIX + name, 'class': PREFIX + name };\n\t\t}\n\n\t\t// the div to hold HTML and clipping\n\t\twrapper = this.createElement(DIV).attr(attribs);\n\n\t\treturn wrapper;\n\t},\n\n\t/**\n\t * VML override to create a regular HTML image\n\t * @param {String} src\n\t * @param {Number} x\n\t * @param {Number} y\n\t * @param {Number} width\n\t * @param {Number} height\n\t */\n\timage: function (src, x, y, width, height) {\n\t\tvar obj = this.createElement('img')\n\t\t\t.attr({ src: src });\n\n\t\tif (arguments.length > 1) {\n\t\t\tobj.attr({\n\t\t\t\tx: x,\n\t\t\t\ty: y,\n\t\t\t\twidth: width,\n\t\t\t\theight: height\n\t\t\t});\n\t\t}\n\t\treturn obj;\n\t},\n\n\t/**\n\t * VML uses a shape for rect to overcome bugs and rotation problems\n\t */\n\trect: function (x, y, width, height, r, strokeWidth) {\n\n\t\tvar wrapper = this.symbol('rect');\n\t\twrapper.r = isObject(x) ? x.r : r;\n\n\t\t//return wrapper.attr(wrapper.crisp(strokeWidth, x, y, mathMax(width, 0), mathMax(height, 0)));\n\t\treturn wrapper.attr(\n\t\t\t\tisObject(x) ?\n\t\t\t\t\tx :\n\t\t\t\t\t// do not crispify when an object is passed in (as in column charts)\n\t\t\t\t\twrapper.crisp(strokeWidth, x, y, mathMax(width, 0), mathMax(height, 0))\n\t\t\t);\n\t},\n\n\t/**\n\t * In the VML renderer, each child of an inverted div (group) is inverted\n\t * @param {Object} element\n\t * @param {Object} parentNode\n\t */\n\tinvertChild: function (element, parentNode) {\n\t\tvar parentStyle = parentNode.style;\n\t\tcss(element, {\n\t\t\tflip: 'x',\n\t\t\tleft: pInt(parentStyle.width) - 1,\n\t\t\ttop: pInt(parentStyle.height) - 1,\n\t\t\trotation: -90\n\t\t});\n\t},\n\n\t/**\n\t * Symbol definitions that override the parent SVG renderer's symbols\n\t *\n\t */\n\tsymbols: {\n\t\t// VML specific arc function\n\t\tarc: function (x, y, w, h, options) {\n\t\t\tvar start = options.start,\n\t\t\t\tend = options.end,\n\t\t\t\tradius = options.r || w || h,\n\t\t\t\tinnerRadius = options.innerR,\n\t\t\t\tcosStart = mathCos(start),\n\t\t\t\tsinStart = mathSin(start),\n\t\t\t\tcosEnd = mathCos(end),\n\t\t\t\tsinEnd = mathSin(end),\n\t\t\t\tret;\n\n\t\t\tif (end - start === 0) { // no angle, don't show it.\n\t\t\t\treturn ['x'];\n\t\t\t}\n\n\t\t\tret = [\n\t\t\t\t'wa', // clockwise arc to\n\t\t\t\tx - radius, // left\n\t\t\t\ty - radius, // top\n\t\t\t\tx + radius, // right\n\t\t\t\ty + radius, // bottom\n\t\t\t\tx + radius * cosStart, // start x\n\t\t\t\ty + radius * sinStart, // start y\n\t\t\t\tx + radius * cosEnd, // end x\n\t\t\t\ty + radius * sinEnd  // end y\n\t\t\t];\n\n\t\t\tif (options.open && !innerRadius) {\n\t\t\t\tret.push(\n\t\t\t\t\t'e',\n\t\t\t\t\tM,\n\t\t\t\t\tx,// - innerRadius,\n\t\t\t\t\ty// - innerRadius\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tret.push(\n\t\t\t\t'at', // anti clockwise arc to\n\t\t\t\tx - innerRadius, // left\n\t\t\t\ty - innerRadius, // top\n\t\t\t\tx + innerRadius, // right\n\t\t\t\ty + innerRadius, // bottom\n\t\t\t\tx + innerRadius * cosEnd, // start x\n\t\t\t\ty + innerRadius * sinEnd, // start y\n\t\t\t\tx + innerRadius * cosStart, // end x\n\t\t\t\ty + innerRadius * sinStart, // end y\n\t\t\t\t'x', // finish path\n\t\t\t\t'e' // close\n\t\t\t);\n\n\t\t\tret.isArc = true;\n\t\t\treturn ret;\n\n\t\t},\n\t\t// Add circle symbol path. This performs significantly faster than v:oval.\n\t\tcircle: function (x, y, w, h, wrapper) {\n\n\t\t\tif (wrapper) {\n\t\t\t\tw = h = 2 * wrapper.r;\n\t\t\t}\n\n\t\t\t// Center correction, #1682\n\t\t\tif (wrapper && wrapper.isCircle) {\n\t\t\t\tx -= w / 2;\n\t\t\t\ty -= h / 2;\n\t\t\t}\n\n\t\t\t// Return the path\n\t\t\treturn [\n\t\t\t\t'wa', // clockwisearcto\n\t\t\t\tx, // left\n\t\t\t\ty, // top\n\t\t\t\tx + w, // right\n\t\t\t\ty + h, // bottom\n\t\t\t\tx + w, // start x\n\t\t\t\ty + h / 2,     // start y\n\t\t\t\tx + w, // end x\n\t\t\t\ty + h / 2,     // end y\n\t\t\t\t//'x', // finish path\n\t\t\t\t'e' // close\n\t\t\t];\n\t\t},\n\t\t/**\n\t\t * Add rectangle symbol path which eases rotation and omits arcsize problems\n\t\t * compared to the built-in VML roundrect shape\n\t\t *\n\t\t * @param {Number} left Left position\n\t\t * @param {Number} top Top position\n\t\t * @param {Number} r Border radius\n\t\t * @param {Object} options Width and height\n\t\t */\n\n\t\trect: function (left, top, width, height, options) {\n\n\t\t\tvar right = left + width,\n\t\t\t\tbottom = top + height,\n\t\t\t\tret,\n\t\t\t\tr;\n\n\t\t\t// No radius, return the more lightweight square\n\t\t\tif (!defined(options) || !options.r) {\n\t\t\t\tret = SVGRenderer.prototype.symbols.square.apply(0, arguments);\n\n\t\t\t// Has radius add arcs for the corners\n\t\t\t} else {\n\n\t\t\t\tr = mathMin(options.r, width, height);\n\t\t\t\tret = [\n\t\t\t\t\tM,\n\t\t\t\t\tleft + r, top,\n\n\t\t\t\t\tL,\n\t\t\t\t\tright - r, top,\n\t\t\t\t\t'wa',\n\t\t\t\t\tright - 2 * r, top,\n\t\t\t\t\tright, top + 2 * r,\n\t\t\t\t\tright - r, top,\n\t\t\t\t\tright, top + r,\n\n\t\t\t\t\tL,\n\t\t\t\t\tright, bottom - r,\n\t\t\t\t\t'wa',\n\t\t\t\t\tright - 2 * r, bottom - 2 * r,\n\t\t\t\t\tright, bottom,\n\t\t\t\t\tright, bottom - r,\n\t\t\t\t\tright - r, bottom,\n\n\t\t\t\t\tL,\n\t\t\t\t\tleft + r, bottom,\n\t\t\t\t\t'wa',\n\t\t\t\t\tleft, bottom - 2 * r,\n\t\t\t\t\tleft + 2 * r, bottom,\n\t\t\t\t\tleft + r, bottom,\n\t\t\t\t\tleft, bottom - r,\n\n\t\t\t\t\tL,\n\t\t\t\t\tleft, top + r,\n\t\t\t\t\t'wa',\n\t\t\t\t\tleft, top,\n\t\t\t\t\tleft + 2 * r, top + 2 * r,\n\t\t\t\t\tleft, top + r,\n\t\t\t\t\tleft + r, top,\n\n\n\t\t\t\t\t'x',\n\t\t\t\t\t'e'\n\t\t\t\t];\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t}\n};\nHighcharts.VMLRenderer = VMLRenderer = function () {\n\tthis.init.apply(this, arguments);\n};\nVMLRenderer.prototype = merge(SVGRenderer.prototype, VMLRendererExtension);\n\n\t// general renderer\n\tRenderer = VMLRenderer;\n}\n\n/* ****************************************************************************\n *                                                                            *\n * END OF INTERNET EXPLORER <= 8 SPECIFIC CODE                                *\n *                                                                            *\n *****************************************************************************/\n/* ****************************************************************************\n *                                                                            *\n * START OF ANDROID < 3 SPECIFIC CODE. THIS CAN BE REMOVED IF YOU'RE NOT      *\n * TARGETING THAT SYSTEM.                                                     *\n *                                                                            *\n *****************************************************************************/\nvar CanVGRenderer,\n\tCanVGController;\n\nif (useCanVG) {\n\t/**\n\t * The CanVGRenderer is empty from start to keep the source footprint small.\n\t * When requested, the CanVGController downloads the rest of the source packaged\n\t * together with the canvg library.\n\t */\n\tHighcharts.CanVGRenderer = CanVGRenderer = function () {\n\t\t// Override the global SVG namespace to fake SVG/HTML that accepts CSS\n\t\tSVG_NS = 'http://www.w3.org/1999/xhtml';\n\t};\n\n\t/**\n\t * Start with an empty symbols object. This is needed when exporting is used (exporting.src.js will add a few symbols), but \n\t * the implementation from SvgRenderer will not be merged in until first render.\n\t */\n\tCanVGRenderer.prototype.symbols = {};\n\n\t/**\n\t * Handles on demand download of canvg rendering support.\n\t */\n\tCanVGController = (function () {\n\t\t// List of renderering calls\n\t\tvar deferredRenderCalls = [];\n\n\t\t/**\n\t\t * When downloaded, we are ready to draw deferred charts.\n\t\t */\n\t\tfunction drawDeferred() {\n\t\t\tvar callLength = deferredRenderCalls.length,\n\t\t\t\tcallIndex;\n\n\t\t\t// Draw all pending render calls\n\t\t\tfor (callIndex = 0; callIndex < callLength; callIndex++) {\n\t\t\t\tdeferredRenderCalls[callIndex]();\n\t\t\t}\n\t\t\t// Clear the list\n\t\t\tdeferredRenderCalls = [];\n\t\t}\n\n\t\treturn {\n\t\t\tpush: function (func, scriptLocation) {\n\t\t\t\t// Only get the script once\n\t\t\t\tif (deferredRenderCalls.length === 0) {\n\t\t\t\t\tgetScript(scriptLocation, drawDeferred);\n\t\t\t\t}\n\t\t\t\t// Register render call\n\t\t\t\tdeferredRenderCalls.push(func);\n\t\t\t}\n\t\t};\n\t}());\n\n\tRenderer = CanVGRenderer;\n} // end CanVGRenderer\n\n/* ****************************************************************************\n *                                                                            *\n * END OF ANDROID < 3 SPECIFIC CODE                                           *\n *                                                                            *\n *****************************************************************************/\n\n/**\n * The Tick class\n */\nfunction Tick(axis, pos, type, noLabel) {\n\tthis.axis = axis;\n\tthis.pos = pos;\n\tthis.type = type || '';\n\tthis.isNew = true;\n\n\tif (!type && !noLabel) {\n\t\tthis.addLabel();\n\t}\n}\n\nTick.prototype = {\n\t/**\n\t * Write the tick label\n\t */\n\taddLabel: function () {\n\t\tvar tick = this,\n\t\t\taxis = tick.axis,\n\t\t\toptions = axis.options,\n\t\t\tchart = axis.chart,\n\t\t\thoriz = axis.horiz,\n\t\t\tcategories = axis.categories,\n\t\t\tnames = axis.series[0] && axis.series[0].names,\n\t\t\tpos = tick.pos,\n\t\t\tlabelOptions = options.labels,\n\t\t\tstr,\n\t\t\ttickPositions = axis.tickPositions,\n\t\t\twidth = (horiz && categories &&\n\t\t\t\t!labelOptions.step && !labelOptions.staggerLines &&\n\t\t\t\t!labelOptions.rotation &&\n\t\t\t\tchart.plotWidth / tickPositions.length) ||\n\t\t\t\t(!horiz && (chart.margin[3] || chart.chartWidth * 0.33)), // #1580, #1931\n\t\t\tisFirst = pos === tickPositions[0],\n\t\t\tisLast = pos === tickPositions[tickPositions.length - 1],\n\t\t\tcss,\n\t\t\tattr,\n\t\t\tvalue = categories ?\n\t\t\t\tpick(categories[pos], names && names[pos], pos) : \n\t\t\t\tpos,\n\t\t\tlabel = tick.label,\n\t\t\ttickPositionInfo = tickPositions.info,\n\t\t\tdateTimeLabelFormat;\n\n\t\t// Set the datetime label format. If a higher rank is set for this position, use that. If not,\n\t\t// use the general format.\n\t\tif (axis.isDatetimeAxis && tickPositionInfo) {\n\t\t\tdateTimeLabelFormat = options.dateTimeLabelFormats[tickPositionInfo.higherRanks[pos] || tickPositionInfo.unitName];\n\t\t}\n\n\t\t// set properties for access in render method\n\t\ttick.isFirst = isFirst;\n\t\ttick.isLast = isLast;\n\n\t\t// get the string\n\t\tstr = axis.labelFormatter.call({\n\t\t\taxis: axis,\n\t\t\tchart: chart,\n\t\t\tisFirst: isFirst,\n\t\t\tisLast: isLast,\n\t\t\tdateTimeLabelFormat: dateTimeLabelFormat,\n\t\t\tvalue: axis.isLog ? correctFloat(lin2log(value)) : value\n\t\t});\n\n\t\t// prepare CSS\n\t\tcss = width && { width: mathMax(1, mathRound(width - 2 * (labelOptions.padding || 10))) + PX };\n\t\tcss = extend(css, labelOptions.style);\n\n\t\t// first call\n\t\tif (!defined(label)) {\n\t\t\tattr = {\n\t\t\t\talign: axis.labelAlign\n\t\t\t};\n\t\t\tif (isNumber(labelOptions.rotation)) {\n\t\t\t\tattr.rotation = labelOptions.rotation;\n\t\t\t}\n\t\t\tif (width && labelOptions.ellipsis) {\n\t\t\t\tattr._clipHeight = axis.len / tickPositions.length;\n\t\t\t}\n\n\t\t\ttick.label =\n\t\t\t\tdefined(str) && labelOptions.enabled ?\n\t\t\t\t\tchart.renderer.text(\n\t\t\t\t\t\t\tstr,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\tlabelOptions.useHTML\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.attr(attr)\n\t\t\t\t\t\t// without position absolute, IE export sometimes is wrong\n\t\t\t\t\t\t.css(css)\n\t\t\t\t\t\t.add(axis.labelGroup) :\n\t\t\t\t\tnull;\n\n\t\t// update\n\t\t} else if (label) {\n\t\t\tlabel.attr({\n\t\t\t\t\ttext: str\n\t\t\t\t})\n\t\t\t\t.css(css);\n\t\t}\n\t},\n\n\t/**\n\t * Get the offset height or width of the label\n\t */\n\tgetLabelSize: function () {\n\t\tvar label = this.label,\n\t\t\taxis = this.axis;\n\t\treturn label ?\n\t\t\t((this.labelBBox = label.getBBox()))[axis.horiz ? 'height' : 'width'] :\n\t\t\t0;\n\t},\n\n\t/**\n\t * Find how far the labels extend to the right and left of the tick's x position. Used for anti-collision\n\t * detection with overflow logic.\n\t */\n\tgetLabelSides: function () {\n\t\tvar bBox = this.labelBBox, // assume getLabelSize has run at this point\n\t\t\taxis = this.axis,\n\t\t\toptions = axis.options,\n\t\t\tlabelOptions = options.labels,\n\t\t\twidth = bBox.width,\n\t\t\tleftSide = width * { left: 0, center: 0.5, right: 1 }[axis.labelAlign] - labelOptions.x;\n\n\t\treturn [-leftSide, width - leftSide];\n\t},\n\n\t/**\n\t * Handle the label overflow by adjusting the labels to the left and right edge, or\n\t * hide them if they collide into the neighbour label.\n\t */\n\thandleOverflow: function (index, xy) {\n\t\tvar show = true,\n\t\t\taxis = this.axis,\n\t\t\tchart = axis.chart,\n\t\t\tisFirst = this.isFirst,\n\t\t\tisLast = this.isLast,\n\t\t\tx = xy.x,\n\t\t\treversed = axis.reversed,\n\t\t\ttickPositions = axis.tickPositions;\n\n\t\tif (isFirst || isLast) {\n\n\t\t\tvar sides = this.getLabelSides(),\n\t\t\t\tleftSide = sides[0],\n\t\t\t\trightSide = sides[1],\n\t\t\t\tplotLeft = chart.plotLeft,\n\t\t\t\tplotRight = plotLeft + axis.len,\n\t\t\t\tneighbour = axis.ticks[tickPositions[index + (isFirst ? 1 : -1)]],\n\t\t\t\tneighbourEdge = neighbour && neighbour.label.xy && neighbour.label.xy.x + neighbour.getLabelSides()[isFirst ? 0 : 1];\n\n\t\t\tif ((isFirst && !reversed) || (isLast && reversed)) {\n\t\t\t\t// Is the label spilling out to the left of the plot area?\n\t\t\t\tif (x + leftSide < plotLeft) {\n\n\t\t\t\t\t// Align it to plot left\n\t\t\t\t\tx = plotLeft - leftSide;\n\n\t\t\t\t\t// Hide it if it now overlaps the neighbour label\n\t\t\t\t\tif (neighbour && x + rightSide > neighbourEdge) {\n\t\t\t\t\t\tshow = false;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\t// Is the label spilling out to the right of the plot area?\n\t\t\t\tif (x + rightSide > plotRight) {\n\n\t\t\t\t\t// Align it to plot right\n\t\t\t\t\tx = plotRight - rightSide;\n\n\t\t\t\t\t// Hide it if it now overlaps the neighbour label\n\t\t\t\t\tif (neighbour && x + leftSide < neighbourEdge) {\n\t\t\t\t\t\tshow = false;\n\t\t\t\t\t}\n\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set the modified x position of the label\n\t\t\txy.x = x;\n\t\t}\n\t\treturn show;\n\t},\n\n\t/**\n\t * Get the x and y position for ticks and labels\n\t */\n\tgetPosition: function (horiz, pos, tickmarkOffset, old) {\n\t\tvar axis = this.axis,\n\t\t\tchart = axis.chart,\n\t\t\tcHeight = (old && chart.oldChartHeight) || chart.chartHeight;\n\t\t\n\t\treturn {\n\t\t\tx: horiz ?\n\t\t\t\taxis.translate(pos + tickmarkOffset, null, null, old) + axis.transB :\n\t\t\t\taxis.left + axis.offset + (axis.opposite ? ((old && chart.oldChartWidth) || chart.chartWidth) - axis.right - axis.left : 0),\n\n\t\t\ty: horiz ?\n\t\t\t\tcHeight - axis.bottom + axis.offset - (axis.opposite ? axis.height : 0) :\n\t\t\t\tcHeight - axis.translate(pos + tickmarkOffset, null, null, old) - axis.transB\n\t\t};\n\t\t\n\t},\n\t\n\t/**\n\t * Get the x, y position of the tick label\n\t */\n\tgetLabelPosition: function (x, y, label, horiz, labelOptions, tickmarkOffset, index, step) {\n\t\tvar axis = this.axis,\n\t\t\ttransA = axis.transA,\n\t\t\treversed = axis.reversed,\n\t\t\tstaggerLines = axis.staggerLines,\n\t\t\tbaseline = axis.chart.renderer.fontMetrics(labelOptions.style.fontSize).b,\n\t\t\trotation = labelOptions.rotation;\n\t\t\t\n\t\tx = x + labelOptions.x - (tickmarkOffset && horiz ?\n\t\t\ttickmarkOffset * transA * (reversed ? -1 : 1) : 0);\n\t\ty = y + labelOptions.y - (tickmarkOffset && !horiz ?\n\t\t\ttickmarkOffset * transA * (reversed ? 1 : -1) : 0);\n\n\t\t// Correct for rotation (#1764)\n\t\tif (rotation && axis.side === 2) {\n\t\t\ty -= baseline - baseline * mathCos(rotation * deg2rad);\n\t\t}\n\t\t\n\t\t// Vertically centered\n\t\tif (!defined(labelOptions.y) && !rotation) { // #1951\n\t\t\ty += baseline - label.getBBox().height / 2;\n\t\t}\n\t\t\n\t\t// Correct for staggered labels\n\t\tif (staggerLines) {\n\t\t\ty += (index / (step || 1) % staggerLines) * (axis.labelOffset / staggerLines);\n\t\t}\n\t\t\n\t\treturn {\n\t\t\tx: x,\n\t\t\ty: y\n\t\t};\n\t},\n\t\n\t/**\n\t * Extendible method to return the path of the marker\n\t */\n\tgetMarkPath: function (x, y, tickLength, tickWidth, horiz, renderer) {\n\t\treturn renderer.crispLine([\n\t\t\t\tM,\n\t\t\t\tx,\n\t\t\t\ty,\n\t\t\t\tL,\n\t\t\t\tx + (horiz ? 0 : -tickLength),\n\t\t\t\ty + (horiz ? tickLength : 0)\n\t\t\t], tickWidth);\n\t},\n\n\t/**\n\t * Put everything in place\n\t *\n\t * @param index {Number}\n\t * @param old {Boolean} Use old coordinates to prepare an animation into new position\n\t */\n\trender: function (index, old, opacity) {\n\t\tvar tick = this,\n\t\t\taxis = tick.axis,\n\t\t\toptions = axis.options,\n\t\t\tchart = axis.chart,\n\t\t\trenderer = chart.renderer,\n\t\t\thoriz = axis.horiz,\n\t\t\ttype = tick.type,\n\t\t\tlabel = tick.label,\n\t\t\tpos = tick.pos,\n\t\t\tlabelOptions = options.labels,\n\t\t\tgridLine = tick.gridLine,\n\t\t\tgridPrefix = type ? type + 'Grid' : 'grid',\n\t\t\ttickPrefix = type ? type + 'Tick' : 'tick',\n\t\t\tgridLineWidth = options[gridPrefix + 'LineWidth'],\n\t\t\tgridLineColor = options[gridPrefix + 'LineColor'],\n\t\t\tdashStyle = options[gridPrefix + 'LineDashStyle'],\n\t\t\ttickLength = options[tickPrefix + 'Length'],\n\t\t\ttickWidth = options[tickPrefix + 'Width'] || 0,\n\t\t\ttickColor = options[tickPrefix + 'Color'],\n\t\t\ttickPosition = options[tickPrefix + 'Position'],\n\t\t\tgridLinePath,\n\t\t\tmark = tick.mark,\n\t\t\tmarkPath,\n\t\t\tstep = labelOptions.step,\n\t\t\tattribs,\n\t\t\tshow = true,\n\t\t\ttickmarkOffset = axis.tickmarkOffset,\n\t\t\txy = tick.getPosition(horiz, pos, tickmarkOffset, old),\n\t\t\tx = xy.x,\n\t\t\ty = xy.y,\n\t\t\treverseCrisp = ((horiz && x === axis.pos + axis.len) || (!horiz && y === axis.pos)) ? -1 : 1, // #1480, #1687\n\t\t\tstaggerLines = axis.staggerLines;\n\n\t\tthis.isActive = true;\n\t\t\n\t\t// create the grid line\n\t\tif (gridLineWidth) {\n\t\t\tgridLinePath = axis.getPlotLinePath(pos + tickmarkOffset, gridLineWidth * reverseCrisp, old, true);\n\n\t\t\tif (gridLine === UNDEFINED) {\n\t\t\t\tattribs = {\n\t\t\t\t\tstroke: gridLineColor,\n\t\t\t\t\t'stroke-width': gridLineWidth\n\t\t\t\t};\n\t\t\t\tif (dashStyle) {\n\t\t\t\t\tattribs.dashstyle = dashStyle;\n\t\t\t\t}\n\t\t\t\tif (!type) {\n\t\t\t\t\tattribs.zIndex = 1;\n\t\t\t\t}\n\t\t\t\tif (old) {\n\t\t\t\t\tattribs.opacity = 0;\n\t\t\t\t}\n\t\t\t\ttick.gridLine = gridLine =\n\t\t\t\t\tgridLineWidth ?\n\t\t\t\t\t\trenderer.path(gridLinePath)\n\t\t\t\t\t\t\t.attr(attribs).add(axis.gridGroup) :\n\t\t\t\t\t\tnull;\n\t\t\t}\n\n\t\t\t// If the parameter 'old' is set, the current call will be followed\n\t\t\t// by another call, therefore do not do any animations this time\n\t\t\tif (!old && gridLine && gridLinePath) {\n\t\t\t\tgridLine[tick.isNew ? 'attr' : 'animate']({\n\t\t\t\t\td: gridLinePath,\n\t\t\t\t\topacity: opacity\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// create the tick mark\n\t\tif (tickWidth && tickLength) {\n\n\t\t\t// negate the length\n\t\t\tif (tickPosition === 'inside') {\n\t\t\t\ttickLength = -tickLength;\n\t\t\t}\n\t\t\tif (axis.opposite) {\n\t\t\t\ttickLength = -tickLength;\n\t\t\t}\n\n\t\t\tmarkPath = tick.getMarkPath(x, y, tickLength, tickWidth * reverseCrisp, horiz, renderer);\n\n\t\t\tif (mark) { // updating\n\t\t\t\tmark.animate({\n\t\t\t\t\td: markPath,\n\t\t\t\t\topacity: opacity\n\t\t\t\t});\n\t\t\t} else { // first time\n\t\t\t\ttick.mark = renderer.path(\n\t\t\t\t\tmarkPath\n\t\t\t\t).attr({\n\t\t\t\t\tstroke: tickColor,\n\t\t\t\t\t'stroke-width': tickWidth,\n\t\t\t\t\topacity: opacity\n\t\t\t\t}).add(axis.axisGroup);\n\t\t\t}\n\t\t}\n\n\t\t// the label is created on init - now move it into place\n\t\tif (label && !isNaN(x)) {\n\t\t\tlabel.xy = xy = tick.getLabelPosition(x, y, label, horiz, labelOptions, tickmarkOffset, index, step);\n\n\t\t\t// Apply show first and show last. If the tick is both first and last, it is \n\t\t\t// a single centered tick, in which case we show the label anyway (#2100).\n\t\t\tif ((tick.isFirst && !tick.isLast && !pick(options.showFirstLabel, 1)) ||\n\t\t\t\t\t(tick.isLast && !tick.isFirst && !pick(options.showLastLabel, 1))) {\n\t\t\t\tshow = false;\n\n\t\t\t// Handle label overflow and show or hide accordingly\n\t\t\t} else if (!staggerLines && horiz && labelOptions.overflow === 'justify' && !tick.handleOverflow(index, xy)) {\n\t\t\t\tshow = false;\n\t\t\t}\n\n\t\t\t// apply step\n\t\t\tif (step && index % step) {\n\t\t\t\t// show those indices dividable by step\n\t\t\t\tshow = false;\n\t\t\t}\n\n\t\t\t// Set the new position, and show or hide\n\t\t\tif (show && !isNaN(xy.y)) {\n\t\t\t\txy.opacity = opacity;\n\t\t\t\tlabel[tick.isNew ? 'attr' : 'animate'](xy);\n\t\t\t\ttick.isNew = false;\n\t\t\t} else {\n\t\t\t\tlabel.attr('y', -9999); // #1338\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Destructor for the tick prototype\n\t */\n\tdestroy: function () {\n\t\tdestroyObjectProperties(this, this.axis);\n\t}\n};\n\n/**\n * The object wrapper for plot lines and plot bands\n * @param {Object} options\n */\nfunction PlotLineOrBand(axis, options) {\n\tthis.axis = axis;\n\n\tif (options) {\n\t\tthis.options = options;\n\t\tthis.id = options.id;\n\t}\n}\n\nPlotLineOrBand.prototype = {\n\t\n\t/**\n\t * Render the plot line or plot band. If it is already existing,\n\t * move it.\n\t */\n\trender: function () {\n\t\tvar plotLine = this,\n\t\t\taxis = plotLine.axis,\n\t\t\thoriz = axis.horiz,\n\t\t\thalfPointRange = (axis.pointRange || 0) / 2,\n\t\t\toptions = plotLine.options,\n\t\t\toptionsLabel = options.label,\n\t\t\tlabel = plotLine.label,\n\t\t\twidth = options.width,\n\t\t\tto = options.to,\n\t\t\tfrom = options.from,\n\t\t\tisBand = defined(from) && defined(to),\n\t\t\tvalue = options.value,\n\t\t\tdashStyle = options.dashStyle,\n\t\t\tsvgElem = plotLine.svgElem,\n\t\t\tpath = [],\n\t\t\taddEvent,\n\t\t\teventType,\n\t\t\txs,\n\t\t\tys,\n\t\t\tx,\n\t\t\ty,\n\t\t\tcolor = options.color,\n\t\t\tzIndex = options.zIndex,\n\t\t\tevents = options.events,\n\t\t\tattribs,\n\t\t\trenderer = axis.chart.renderer;\n\n\t\t// logarithmic conversion\n\t\tif (axis.isLog) {\n\t\t\tfrom = log2lin(from);\n\t\t\tto = log2lin(to);\n\t\t\tvalue = log2lin(value);\n\t\t}\n\n\t\t// plot line\n\t\tif (width) {\n\t\t\tpath = axis.getPlotLinePath(value, width);\n\t\t\tattribs = {\n\t\t\t\tstroke: color,\n\t\t\t\t'stroke-width': width\n\t\t\t};\n\t\t\tif (dashStyle) {\n\t\t\t\tattribs.dashstyle = dashStyle;\n\t\t\t}\n\t\t} else if (isBand) { // plot band\n\t\t\t\n\t\t\t// keep within plot area\n\t\t\tfrom = mathMax(from, axis.min - halfPointRange);\n\t\t\tto = mathMin(to, axis.max + halfPointRange);\n\t\t\t\n\t\t\tpath = axis.getPlotBandPath(from, to, options);\n\t\t\tattribs = {\n\t\t\t\tfill: color\n\t\t\t};\n\t\t\tif (options.borderWidth) {\n\t\t\t\tattribs.stroke = options.borderColor;\n\t\t\t\tattribs['stroke-width'] = options.borderWidth;\n\t\t\t}\n\t\t} else {\n\t\t\treturn;\n\t\t}\n\t\t// zIndex\n\t\tif (defined(zIndex)) {\n\t\t\tattribs.zIndex = zIndex;\n\t\t}\n\n\t\t// common for lines and bands\n\t\tif (svgElem) {\n\t\t\tif (path) {\n\t\t\t\tsvgElem.animate({\n\t\t\t\t\td: path\n\t\t\t\t}, null, svgElem.onGetPath);\n\t\t\t} else {\n\t\t\t\tsvgElem.hide();\n\t\t\t\tsvgElem.onGetPath = function () {\n\t\t\t\t\tsvgElem.show();\n\t\t\t\t};\n\t\t\t}\n\t\t} else if (path && path.length) {\n\t\t\tplotLine.svgElem = svgElem = renderer.path(path)\n\t\t\t\t.attr(attribs).add();\n\n\t\t\t// events\n\t\t\tif (events) {\n\t\t\t\taddEvent = function (eventType) {\n\t\t\t\t\tsvgElem.on(eventType, function (e) {\n\t\t\t\t\t\tevents[eventType].apply(plotLine, [e]);\n\t\t\t\t\t});\n\t\t\t\t};\n\t\t\t\tfor (eventType in events) {\n\t\t\t\t\taddEvent(eventType);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// the plot band/line label\n\t\tif (optionsLabel && defined(optionsLabel.text) && path && path.length && axis.width > 0 && axis.height > 0) {\n\t\t\t// apply defaults\n\t\t\toptionsLabel = merge({\n\t\t\t\talign: horiz && isBand && 'center',\n\t\t\t\tx: horiz ? !isBand && 4 : 10,\n\t\t\t\tverticalAlign : !horiz && isBand && 'middle',\n\t\t\t\ty: horiz ? isBand ? 16 : 10 : isBand ? 6 : -4,\n\t\t\t\trotation: horiz && !isBand && 90\n\t\t\t}, optionsLabel);\n\n\t\t\t// add the SVG element\n\t\t\tif (!label) {\n\t\t\t\tplotLine.label = label = renderer.text(\n\t\t\t\t\t\toptionsLabel.text,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\t0,\n\t\t\t\t\t\toptionsLabel.useHTML\n\t\t\t\t\t)\n\t\t\t\t\t.attr({\n\t\t\t\t\t\talign: optionsLabel.textAlign || optionsLabel.align,\n\t\t\t\t\t\trotation: optionsLabel.rotation,\n\t\t\t\t\t\tzIndex: zIndex\n\t\t\t\t\t})\n\t\t\t\t\t.css(optionsLabel.style)\n\t\t\t\t\t.add();\n\t\t\t}\n\n\t\t\t// get the bounding box and align the label\n\t\t\txs = [path[1], path[4], pick(path[6], path[1])];\n\t\t\tys = [path[2], path[5], pick(path[7], path[2])];\n\t\t\tx = arrayMin(xs);\n\t\t\ty = arrayMin(ys);\n\n\t\t\tlabel.align(optionsLabel, false, {\n\t\t\t\tx: x,\n\t\t\t\ty: y,\n\t\t\t\twidth: arrayMax(xs) - x,\n\t\t\t\theight: arrayMax(ys) - y\n\t\t\t});\n\t\t\tlabel.show();\n\n\t\t} else if (label) { // move out of sight\n\t\t\tlabel.hide();\n\t\t}\n\n\t\t// chainable\n\t\treturn plotLine;\n\t},\n\n\t/**\n\t * Remove the plot line or band\n\t */\n\tdestroy: function () {\n\t\t// remove it from the lookup\n\t\terase(this.axis.plotLinesAndBands, this);\n\t\t\n\t\tdelete this.axis;\n\t\tdestroyObjectProperties(this);\n\t}\n};\n/**\n * The class for stack items\n */\nfunction StackItem(axis, options, isNegative, x, stackOption, stacking) {\n\t\n\tvar inverted = axis.chart.inverted;\n\n\tthis.axis = axis;\n\n\t// Tells if the stack is negative\n\tthis.isNegative = isNegative;\n\n\t// Save the options to be able to style the label\n\tthis.options = options;\n\n\t// Save the x value to be able to position the label later\n\tthis.x = x;\n\n\t// Initialize total value\n\tthis.total = null;\n\n\t// This will keep each points' extremes stored by series.index\n\tthis.points = {};\n\n\t// Save the stack option on the series configuration object, and whether to treat it as percent\n\tthis.stack = stackOption;\n\tthis.percent = stacking === 'percent';\n\n\t// The align options and text align varies on whether the stack is negative and\n\t// if the chart is inverted or not.\n\t// First test the user supplied value, then use the dynamic.\n\tthis.alignOptions = {\n\t\talign: options.align || (inverted ? (isNegative ? 'left' : 'right') : 'center'),\n\t\tverticalAlign: options.verticalAlign || (inverted ? 'middle' : (isNegative ? 'bottom' : 'top')),\n\t\ty: pick(options.y, inverted ? 4 : (isNegative ? 14 : -6)),\n\t\tx: pick(options.x, inverted ? (isNegative ? -6 : 6) : 0)\n\t};\n\n\tthis.textAlign = options.textAlign || (inverted ? (isNegative ? 'right' : 'left') : 'center');\n}\n\nStackItem.prototype = {\n\tdestroy: function () {\n\t\tdestroyObjectProperties(this, this.axis);\n\t},\n\n\t/**\n\t * Renders the stack total label and adds it to the stack label group.\n\t */\n\trender: function (group) {\n\t\tvar options = this.options,\n\t\t\tformatOption = options.format,\n\t\t\tstr = formatOption ?\n\t\t\t\tformat(formatOption, this) : \n\t\t\t\toptions.formatter.call(this);  // format the text in the label\n\n\t\t// Change the text to reflect the new total and set visibility to hidden in case the serie is hidden\n\t\tif (this.label) {\n\t\t\tthis.label.attr({text: str, visibility: HIDDEN});\n\t\t// Create new label\n\t\t} else {\n\t\t\tthis.label =\n\t\t\t\tthis.axis.chart.renderer.text(str, 0, 0, options.useHTML)\t\t// dummy positions, actual position updated with setOffset method in columnseries\n\t\t\t\t\t.css(options.style)\t\t\t\t// apply style\n\t\t\t\t\t.attr({\n\t\t\t\t\t\talign: this.textAlign,\t\t\t\t// fix the text-anchor\n\t\t\t\t\t\trotation: options.rotation,\t// rotation\n\t\t\t\t\t\tvisibility: HIDDEN\t\t\t\t\t// hidden until setOffset is called\n\t\t\t\t\t})\t\t\t\t\n\t\t\t\t\t.add(group);\t\t\t\t\t\t\t// add to the labels-group\n\t\t}\n\t},\n\n\t/**\n\t * Sets the offset that the stack has from the x value and repositions the label.\n\t */\n\tsetOffset: function (xOffset, xWidth) {\n\t\tvar stackItem = this,\n\t\t\taxis = stackItem.axis,\n\t\t\tchart = axis.chart,\n\t\t\tinverted = chart.inverted,\n\t\t\tneg = this.isNegative,\t\t\t\t\t\t\t// special treatment is needed for negative stacks\n\t\t\ty = axis.translate(this.percent ? 100 : this.total, 0, 0, 0, 1), // stack value translated mapped to chart coordinates\n\t\t\tyZero = axis.translate(0),\t\t\t\t\t\t// stack origin\n\t\t\th = mathAbs(y - yZero),\t\t\t\t\t\t\t// stack height\n\t\t\tx = chart.xAxis[0].translate(this.x) + xOffset,\t// stack x position\n\t\t\tplotHeight = chart.plotHeight,\n\t\t\tstackBox = {\t// this is the box for the complete stack\n\t\t\t\tx: inverted ? (neg ? y : y - h) : x,\n\t\t\t\ty: inverted ? plotHeight - x - xWidth : (neg ? (plotHeight - y - h) : plotHeight - y),\n\t\t\t\twidth: inverted ? h : xWidth,\n\t\t\t\theight: inverted ? xWidth : h\n\t\t\t},\n\t\t\tlabel = this.label,\n\t\t\talignAttr;\n\t\t\n\t\tif (label) {\n\t\t\tlabel.align(this.alignOptions, null, stackBox);\t// align the label to the box\n\t\t\t\t\n\t\t\t// Set visibility (#678)\n\t\t\talignAttr = label.alignAttr;\n\t\t\tlabel.attr({ \n\t\t\t\tvisibility: this.options.crop === false || chart.isInsidePlot(alignAttr.x, alignAttr.y) ? \n\t\t\t\t\t(hasSVG ? 'inherit' : VISIBLE) : \n\t\t\t\t\tHIDDEN\n\t\t\t});\n\t\t}\n\t}\n};\n/**\n * Create a new axis object\n * @param {Object} chart\n * @param {Object} options\n */\nfunction Axis() {\n\tthis.init.apply(this, arguments);\n}\n\nAxis.prototype = {\n\t\n\t/**\n\t * Default options for the X axis - the Y axis has extended defaults \n\t */\n\tdefaultOptions: {\n\t\t// allowDecimals: null,\n\t\t// alternateGridColor: null,\n\t\t// categories: [],\n\t\tdateTimeLabelFormats: {\n\t\t\tmillisecond: '%H:%M:%S.%L',\n\t\t\tsecond: '%H:%M:%S',\n\t\t\tminute: '%H:%M',\n\t\t\thour: '%H:%M',\n\t\t\tday: '%e. %b',\n\t\t\tweek: '%e. %b',\n\t\t\tmonth: '%b \\'%y',\n\t\t\tyear: '%Y'\n\t\t},\n\t\tendOnTick: false,\n\t\tgridLineColor: '#C0C0C0',\n\t\t// gridLineDashStyle: 'solid',\n\t\t// gridLineWidth: 0,\n\t\t// reversed: false,\n\t\n\t\tlabels: defaultLabelOptions,\n\t\t\t// { step: null },\n\t\tlineColor: '#C0D0E0',\n\t\tlineWidth: 1,\n\t\t//linkedTo: null,\n\t\t//max: undefined,\n\t\t//min: undefined,\n\t\tminPadding: 0.01,\n\t\tmaxPadding: 0.01,\n\t\t//minRange: null,\n\t\tminorGridLineColor: '#E0E0E0',\n\t\t// minorGridLineDashStyle: null,\n\t\tminorGridLineWidth: 1,\n\t\tminorTickColor: '#A0A0A0',\n\t\t//minorTickInterval: null,\n\t\tminorTickLength: 2,\n\t\tminorTickPosition: 'outside', // inside or outside\n\t\t//minorTickWidth: 0,\n\t\t//opposite: false,\n\t\t//offset: 0,\n\t\t//plotBands: [{\n\t\t//\tevents: {},\n\t\t//\tzIndex: 1,\n\t\t//\tlabels: { align, x, verticalAlign, y, style, rotation, textAlign }\n\t\t//}],\n\t\t//plotLines: [{\n\t\t//\tevents: {}\n\t\t//  dashStyle: {}\n\t\t//\tzIndex:\n\t\t//\tlabels: { align, x, verticalAlign, y, style, rotation, textAlign }\n\t\t//}],\n\t\t//reversed: false,\n\t\t// showFirstLabel: true,\n\t\t// showLastLabel: true,\n\t\tstartOfWeek: 1,\n\t\tstartOnTick: false,\n\t\ttickColor: '#C0D0E0',\n\t\t//tickInterval: null,\n\t\ttickLength: 5,\n\t\ttickmarkPlacement: 'between', // on or between\n\t\ttickPixelInterval: 100,\n\t\ttickPosition: 'outside',\n\t\ttickWidth: 1,\n\t\ttitle: {\n\t\t\t//text: null,\n\t\t\talign: 'middle', // low, middle or high\n\t\t\t//margin: 0 for horizontal, 10 for vertical axes,\n\t\t\t//rotation: 0,\n\t\t\t//side: 'outside',\n\t\t\tstyle: {\n\t\t\t\tcolor: '#4d759e',\n\t\t\t\t//font: defaultFont.replace('normal', 'bold')\n\t\t\t\tfontWeight: 'bold'\n\t\t\t}\n\t\t\t//x: 0,\n\t\t\t//y: 0\n\t\t},\n\t\ttype: 'linear' // linear, logarithmic or datetime\n\t},\n\t\n\t/**\n\t * This options set extends the defaultOptions for Y axes\n\t */\n\tdefaultYAxisOptions: {\n\t\tendOnTick: true,\n\t\tgridLineWidth: 1,\n\t\ttickPixelInterval: 72,\n\t\tshowLastLabel: true,\n\t\tlabels: {\n\t\t\tx: -8,\n\t\t\ty: 3\n\t\t},\n\t\tlineWidth: 0,\n\t\tmaxPadding: 0.05,\n\t\tminPadding: 0.05,\n\t\tstartOnTick: true,\n\t\ttickWidth: 0,\n\t\ttitle: {\n\t\t\trotation: 270,\n\t\t\ttext: 'Values'\n\t\t},\n\t\tstackLabels: {\n\t\t\tenabled: false,\n\t\t\t//align: dynamic,\n\t\t\t//y: dynamic,\n\t\t\t//x: dynamic,\n\t\t\t//verticalAlign: dynamic,\n\t\t\t//textAlign: dynamic,\n\t\t\t//rotation: 0,\n\t\t\tformatter: function () {\n\t\t\t\treturn numberFormat(this.total, -1);\n\t\t\t},\n\t\t\tstyle: defaultLabelOptions.style\n\t\t}\n\t},\n\t\n\t/**\n\t * These options extend the defaultOptions for left axes\n\t */\n\tdefaultLeftAxisOptions: {\n\t\tlabels: {\n\t\t\tx: -8,\n\t\t\ty: null\n\t\t},\n\t\ttitle: {\n\t\t\trotation: 270\n\t\t}\n\t},\n\t\n\t/**\n\t * These options extend the defaultOptions for right axes\n\t */\n\tdefaultRightAxisOptions: {\n\t\tlabels: {\n\t\t\tx: 8,\n\t\t\ty: null\n\t\t},\n\t\ttitle: {\n\t\t\trotation: 90\n\t\t}\n\t},\n\t\n\t/**\n\t * These options extend the defaultOptions for bottom axes\n\t */\n\tdefaultBottomAxisOptions: {\n\t\tlabels: {\n\t\t\tx: 0,\n\t\t\ty: 14\n\t\t\t// overflow: undefined,\n\t\t\t// staggerLines: null\n\t\t},\n\t\ttitle: {\n\t\t\trotation: 0\n\t\t}\n\t},\n\t/**\n\t * These options extend the defaultOptions for left axes\n\t */\n\tdefaultTopAxisOptions: {\n\t\tlabels: {\n\t\t\tx: 0,\n\t\t\ty: -5\n\t\t\t// overflow: undefined\n\t\t\t// staggerLines: null\n\t\t},\n\t\ttitle: {\n\t\t\trotation: 0\n\t\t}\n\t},\n\t\n\t/**\n\t * Initialize the axis\n\t */\n\tinit: function (chart, userOptions) {\n\t\t\t\n\t\t\n\t\tvar isXAxis = userOptions.isX,\n\t\t\taxis = this;\n\t\n\t\t// Flag, is the axis horizontal\n\t\taxis.horiz = chart.inverted ? !isXAxis : isXAxis;\n\t\t\n\t\t// Flag, isXAxis\n\t\taxis.isXAxis = isXAxis;\n\t\taxis.xOrY = isXAxis ? 'x' : 'y';\n\t\n\t\n\t\taxis.opposite = userOptions.opposite; // needed in setOptions\n\t\taxis.side = axis.horiz ?\n\t\t\t\t(axis.opposite ? 0 : 2) : // top : bottom\n\t\t\t\t(axis.opposite ? 1 : 3);  // right : left\n\t\n\t\taxis.setOptions(userOptions);\n\t\t\n\t\n\t\tvar options = this.options,\n\t\t\ttype = options.type,\n\t\t\tisDatetimeAxis = type === 'datetime';\n\t\n\t\taxis.labelFormatter = options.labels.formatter || axis.defaultLabelFormatter; // can be overwritten by dynamic format\n\t\n\t\n\t\t// Flag, stagger lines or not\n\t\taxis.userOptions = userOptions;\n\t\n\t\t//axis.axisTitleMargin = UNDEFINED,// = options.title.margin,\n\t\taxis.minPixelPadding = 0;\n\t\t//axis.ignoreMinPadding = UNDEFINED; // can be set to true by a column or bar series\n\t\t//axis.ignoreMaxPadding = UNDEFINED;\n\t\n\t\taxis.chart = chart;\n\t\taxis.reversed = options.reversed;\n\t\taxis.zoomEnabled = options.zoomEnabled !== false;\n\t\n\t\t// Initial categories\n\t\taxis.categories = options.categories || type === 'category';\n\t\n\t\t// Elements\n\t\t//axis.axisGroup = UNDEFINED;\n\t\t//axis.gridGroup = UNDEFINED;\n\t\t//axis.axisTitle = UNDEFINED;\n\t\t//axis.axisLine = UNDEFINED;\n\t\n\t\t// Shorthand types\n\t\taxis.isLog = type === 'logarithmic';\n\t\taxis.isDatetimeAxis = isDatetimeAxis;\n\t\n\t\t// Flag, if axis is linked to another axis\n\t\taxis.isLinked = defined(options.linkedTo);\n\t\t// Linked axis.\n\t\t//axis.linkedParent = UNDEFINED;\t\n\t\t\n\t\t// Tick positions\n\t\t//axis.tickPositions = UNDEFINED; // array containing predefined positions\n\t\t// Tick intervals\n\t\t//axis.tickInterval = UNDEFINED;\n\t\t//axis.minorTickInterval = UNDEFINED;\n\t\t\n\t\taxis.tickmarkOffset = (axis.categories && options.tickmarkPlacement === 'between') ? 0.5 : 0;\n\t\n\t\t// Major ticks\n\t\taxis.ticks = {};\n\t\t// Minor ticks\n\t\taxis.minorTicks = {};\n\t\t//axis.tickAmount = UNDEFINED;\n\t\n\t\t// List of plotLines/Bands\n\t\taxis.plotLinesAndBands = [];\n\t\n\t\t// Alternate bands\n\t\taxis.alternateBands = {};\n\t\n\t\t// Axis metrics\n\t\t//axis.left = UNDEFINED;\n\t\t//axis.top = UNDEFINED;\n\t\t//axis.width = UNDEFINED;\n\t\t//axis.height = UNDEFINED;\n\t\t//axis.bottom = UNDEFINED;\n\t\t//axis.right = UNDEFINED;\n\t\t//axis.transA = UNDEFINED;\n\t\t//axis.transB = UNDEFINED;\n\t\t//axis.oldTransA = UNDEFINED;\n\t\taxis.len = 0;\n\t\t//axis.oldMin = UNDEFINED;\n\t\t//axis.oldMax = UNDEFINED;\n\t\t//axis.oldUserMin = UNDEFINED;\n\t\t//axis.oldUserMax = UNDEFINED;\n\t\t//axis.oldAxisLength = UNDEFINED;\n\t\taxis.minRange = axis.userMinRange = options.minRange || options.maxZoom;\n\t\taxis.range = options.range;\n\t\taxis.offset = options.offset || 0;\n\t\n\t\n\t\t// Dictionary for stacks\n\t\taxis.stacks = {};\n\t\taxis.oldStacks = {};\n\n\t\t// Dictionary for stacks max values\n\t\taxis.stackExtremes = {};\n\n\t\t// Min and max in the data\n\t\t//axis.dataMin = UNDEFINED,\n\t\t//axis.dataMax = UNDEFINED,\n\t\n\t\t// The axis range\n\t\taxis.max = null;\n\t\taxis.min = null;\n\t\n\t\t// User set min and max\n\t\t//axis.userMin = UNDEFINED,\n\t\t//axis.userMax = UNDEFINED,\n\n\t\t// Run Axis\n\t\t\n\t\tvar eventType,\n\t\t\tevents = axis.options.events;\n\n\t\t// Register\n\t\tif (inArray(axis, chart.axes) === -1) { // don't add it again on Axis.update()\n\t\t\tchart.axes.push(axis);\n\t\t\tchart[isXAxis ? 'xAxis' : 'yAxis'].push(axis);\n\t\t}\n\n\t\taxis.series = axis.series || []; // populated by Series\n\n\t\t// inverted charts have reversed xAxes as default\n\t\tif (chart.inverted && isXAxis && axis.reversed === UNDEFINED) {\n\t\t\taxis.reversed = true;\n\t\t}\n\n\t\taxis.removePlotBand = axis.removePlotBandOrLine;\n\t\taxis.removePlotLine = axis.removePlotBandOrLine;\n\n\n\t\t// register event listeners\n\t\tfor (eventType in events) {\n\t\t\taddEvent(axis, eventType, events[eventType]);\n\t\t}\n\n\t\t// extend logarithmic axis\n\t\tif (axis.isLog) {\n\t\t\taxis.val2lin = log2lin;\n\t\t\taxis.lin2val = lin2log;\n\t\t}\n\t},\n\t\n\t/**\n\t * Merge and set options\n\t */\n\tsetOptions: function (userOptions) {\n\t\tthis.options = merge(\n\t\t\tthis.defaultOptions,\n\t\t\tthis.isXAxis ? {} : this.defaultYAxisOptions,\n\t\t\t[this.defaultTopAxisOptions, this.defaultRightAxisOptions,\n\t\t\t\tthis.defaultBottomAxisOptions, this.defaultLeftAxisOptions][this.side],\n\t\t\tmerge(\n\t\t\t\tdefaultOptions[this.isXAxis ? 'xAxis' : 'yAxis'], // if set in setOptions (#1053)\n\t\t\t\tuserOptions\n\t\t\t)\n\t\t);\n\t},\n\n\t/**\n\t * Update the axis with a new options structure\n\t */\n\tupdate: function (newOptions, redraw) {\n\t\tvar chart = this.chart;\n\n\t\tnewOptions = chart.options[this.xOrY + 'Axis'][this.options.index] = merge(this.userOptions, newOptions);\n\n\t\tthis.destroy(true);\n\t\tthis._addedPlotLB = this.userMin = this.userMax = UNDEFINED; // #1611, #2306\n\n\t\tthis.init(chart, extend(newOptions, { events: UNDEFINED }));\n\n\t\tchart.isDirtyBox = true;\n\t\tif (pick(redraw, true)) {\n\t\t\tchart.redraw();\n\t\t}\n\t},\t\n\t\n\t/**\n     * Remove the axis from the chart\n     */\n\tremove: function (redraw) {\n\t\tvar chart = this.chart,\n\t\t\tkey = this.xOrY + 'Axis'; // xAxis or yAxis\n\n\t\t// Remove associated series\n\t\teach(this.series, function (series) {\n\t\t\tseries.remove(false);\n\t\t});\n\n\t\t// Remove the axis\n\t\terase(chart.axes, this);\n\t\terase(chart[key], this);\n\t\tchart.options[key].splice(this.options.index, 1);\n\t\teach(chart[key], function (axis, i) { // Re-index, #1706\n\t\t\taxis.options.index = i;\n\t\t});\n\t\tthis.destroy();\n\t\tchart.isDirtyBox = true;\n\n\t\tif (pick(redraw, true)) {\n\t\t\tchart.redraw();\n\t\t}\n\t},\n\t\n\t/** \n\t * The default label formatter. The context is a special config object for the label.\n\t */\n\tdefaultLabelFormatter: function () {\n\t\tvar axis = this.axis,\n\t\t\tvalue = this.value,\n\t\t\tcategories = axis.categories, \n\t\t\tdateTimeLabelFormat = this.dateTimeLabelFormat,\n\t\t\tnumericSymbols = defaultOptions.lang.numericSymbols,\n\t\t\ti = numericSymbols && numericSymbols.length,\n\t\t\tmulti,\n\t\t\tret,\n\t\t\tformatOption = axis.options.labels.format,\n\t\t\t\n\t\t\t// make sure the same symbol is added for all labels on a linear axis\n\t\t\tnumericSymbolDetector = axis.isLog ? value : axis.tickInterval;\n\n\t\tif (formatOption) {\n\t\t\tret = format(formatOption, this);\n\t\t\n\t\t} else if (categories) {\n\t\t\tret = value;\n\t\t\n\t\t} else if (dateTimeLabelFormat) { // datetime axis\n\t\t\tret = dateFormat(dateTimeLabelFormat, value);\n\t\t\n\t\t} else if (i && numericSymbolDetector >= 1000) {\n\t\t\t// Decide whether we should add a numeric symbol like k (thousands) or M (millions).\n\t\t\t// If we are to enable this in tooltip or other places as well, we can move this\n\t\t\t// logic to the numberFormatter and enable it by a parameter.\n\t\t\twhile (i-- && ret === UNDEFINED) {\n\t\t\t\tmulti = Math.pow(1000, i + 1);\n\t\t\t\tif (numericSymbolDetector >= multi && numericSymbols[i] !== null) {\n\t\t\t\t\tret = numberFormat(value / multi, -1) + numericSymbols[i];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\tif (ret === UNDEFINED) {\n\t\t\tif (value >= 1000) { // add thousands separators\n\t\t\t\tret = numberFormat(value, 0);\n\n\t\t\t} else { // small numbers\n\t\t\t\tret = numberFormat(value, -1);\n\t\t\t}\n\t\t}\n\t\t\n\t\treturn ret;\n\t},\n\n\t/**\n\t * Get the minimum and maximum for the series of each axis\n\t */\n\tgetSeriesExtremes: function () {\n\t\tvar axis = this,\n\t\t\tchart = axis.chart;\n\n\t\taxis.hasVisibleSeries = false;\n\n\t\t// reset dataMin and dataMax in case we're redrawing\n\t\taxis.dataMin = axis.dataMax = null;\n\n\t\t// reset cached stacking extremes\n\t\taxis.stackExtremes = {};\n\n\t\taxis.buildStacks();\n\n\t\t// loop through this axis' series\n\t\teach(axis.series, function (series) {\n\n\t\t\tif (series.visible || !chart.options.chart.ignoreHiddenSeries) {\n\n\t\t\t\tvar seriesOptions = series.options,\n\t\t\t\t\txData,\n\t\t\t\t\tthreshold = seriesOptions.threshold,\n\t\t\t\t\tseriesDataMin,\n\t\t\t\t\tseriesDataMax;\n\n\t\t\t\taxis.hasVisibleSeries = true;\n\n\t\t\t\t// Validate threshold in logarithmic axes\n\t\t\t\tif (axis.isLog && threshold <= 0) {\n\t\t\t\t\tthreshold = null;\n\t\t\t\t}\n\n\t\t\t\t// Get dataMin and dataMax for X axes\n\t\t\t\tif (axis.isXAxis) {\n\t\t\t\t\txData = series.xData;\n\t\t\t\t\tif (xData.length) {\n\t\t\t\t\t\taxis.dataMin = mathMin(pick(axis.dataMin, xData[0]), arrayMin(xData));\n\t\t\t\t\t\taxis.dataMax = mathMax(pick(axis.dataMax, xData[0]), arrayMax(xData));\n\t\t\t\t\t}\n\n\t\t\t\t// Get dataMin and dataMax for Y axes, as well as handle stacking and processed data\n\t\t\t\t} else {\n\n\t\t\t\t\t// Get this particular series extremes\n\t\t\t\t\tseries.getExtremes();\n\t\t\t\t\tseriesDataMax = series.dataMax;\n\t\t\t\t\tseriesDataMin = series.dataMin;\n\n\t\t\t\t\t// Get the dataMin and dataMax so far. If percentage is used, the min and max are\n\t\t\t\t\t// always 0 and 100. If seriesDataMin and seriesDataMax is null, then series\n\t\t\t\t\t// doesn't have active y data, we continue with nulls\n\t\t\t\t\tif (defined(seriesDataMin) && defined(seriesDataMax)) {\n\t\t\t\t\t\taxis.dataMin = mathMin(pick(axis.dataMin, seriesDataMin), seriesDataMin);\n\t\t\t\t\t\taxis.dataMax = mathMax(pick(axis.dataMax, seriesDataMax), seriesDataMax);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Adjust to threshold\n\t\t\t\t\tif (defined(threshold)) {\n\t\t\t\t\t\tif (axis.dataMin >= threshold) {\n\t\t\t\t\t\t\taxis.dataMin = threshold;\n\t\t\t\t\t\t\taxis.ignoreMinPadding = true;\n\t\t\t\t\t\t} else if (axis.dataMax < threshold) {\n\t\t\t\t\t\t\taxis.dataMax = threshold;\n\t\t\t\t\t\t\taxis.ignoreMaxPadding = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n\t * Translate from axis value to pixel position on the chart, or back\n\t *\n\t */\n\ttranslate: function (val, backwards, cvsCoord, old, handleLog, pointPlacement) {\n\t\tvar axis = this,\n\t\t\taxisLength = axis.len,\n\t\t\tsign = 1,\n\t\t\tcvsOffset = 0,\n\t\t\tlocalA = old ? axis.oldTransA : axis.transA,\n\t\t\tlocalMin = old ? axis.oldMin : axis.min,\n\t\t\treturnValue,\n\t\t\tminPixelPadding = axis.minPixelPadding,\n\t\t\tpostTranslate = (axis.options.ordinal || (axis.isLog && handleLog)) && axis.lin2val;\n\n\t\tif (!localA) {\n\t\t\tlocalA = axis.transA;\n\t\t}\n\n\t\t// In vertical axes, the canvas coordinates start from 0 at the top like in \n\t\t// SVG. \n\t\tif (cvsCoord) {\n\t\t\tsign *= -1; // canvas coordinates inverts the value\n\t\t\tcvsOffset = axisLength;\n\t\t}\n\n\t\t// Handle reversed axis\n\t\tif (axis.reversed) { \n\t\t\tsign *= -1;\n\t\t\tcvsOffset -= sign * axisLength;\n\t\t}\n\n\t\t// From pixels to value\n\t\tif (backwards) { // reverse translation\n\t\t\t\n\t\t\tval = val * sign + cvsOffset;\n\t\t\tval -= minPixelPadding;\n\t\t\treturnValue = val / localA + localMin; // from chart pixel to value\n\t\t\tif (postTranslate) { // log and ordinal axes\n\t\t\t\treturnValue = axis.lin2val(returnValue);\n\t\t\t}\n\n\t\t// From value to pixels\n\t\t} else {\n\t\t\tif (postTranslate) { // log and ordinal axes\n\t\t\t\tval = axis.val2lin(val);\n\t\t\t}\n\t\t\tif (pointPlacement === 'between') {\n\t\t\t\tpointPlacement = 0.5;\n\t\t\t}\n\t\t\treturnValue = sign * (val - localMin) * localA + cvsOffset + (sign * minPixelPadding) +\n\t\t\t\t(isNumber(pointPlacement) ? localA * pointPlacement * axis.pointRange : 0);\n\t\t}\n\n\t\treturn returnValue;\n\t},\n\n\t/**\n\t * Utility method to translate an axis value to pixel position. \n\t * @param {Number} value A value in terms of axis units\n\t * @param {Boolean} paneCoordinates Whether to return the pixel coordinate relative to the chart\n\t *        or just the axis/pane itself.\n\t */\n\ttoPixels: function (value, paneCoordinates) {\n\t\treturn this.translate(value, false, !this.horiz, null, true) + (paneCoordinates ? 0 : this.pos);\n\t},\n\n\t/*\n\t * Utility method to translate a pixel position in to an axis value\n\t * @param {Number} pixel The pixel value coordinate\n\t * @param {Boolean} paneCoordiantes Whether the input pixel is relative to the chart or just the\n\t *        axis/pane itself.\n\t */\n\ttoValue: function (pixel, paneCoordinates) {\n\t\treturn this.translate(pixel - (paneCoordinates ? 0 : this.pos), true, !this.horiz, null, true);\n\t},\n\n\t/**\n\t * Create the path for a plot line that goes from the given value on\n\t * this axis, across the plot to the opposite side\n\t * @param {Number} value\n\t * @param {Number} lineWidth Used for calculation crisp line\n\t * @param {Number] old Use old coordinates (for resizing and rescaling)\n\t */\n\tgetPlotLinePath: function (value, lineWidth, old, force) {\n\t\tvar axis = this,\n\t\t\tchart = axis.chart,\n\t\t\taxisLeft = axis.left,\n\t\t\taxisTop = axis.top,\n\t\t\tx1,\n\t\t\ty1,\n\t\t\tx2,\n\t\t\ty2,\n\t\t\ttranslatedValue = axis.translate(value, null, null, old),\n\t\t\tcHeight = (old && chart.oldChartHeight) || chart.chartHeight,\n\t\t\tcWidth = (old && chart.oldChartWidth) || chart.chartWidth,\n\t\t\tskip,\n\t\t\ttransB = axis.transB;\n\n\t\tx1 = x2 = mathRound(translatedValue + transB);\n\t\ty1 = y2 = mathRound(cHeight - translatedValue - transB);\n\n\t\tif (isNaN(translatedValue)) { // no min or max\n\t\t\tskip = true;\n\n\t\t} else if (axis.horiz) {\n\t\t\ty1 = axisTop;\n\t\t\ty2 = cHeight - axis.bottom;\n\t\t\tif (x1 < axisLeft || x1 > axisLeft + axis.width) {\n\t\t\t\tskip = true;\n\t\t\t}\n\t\t} else {\n\t\t\tx1 = axisLeft;\n\t\t\tx2 = cWidth - axis.right;\n\n\t\t\tif (y1 < axisTop || y1 > axisTop + axis.height) {\n\t\t\t\tskip = true;\n\t\t\t}\n\t\t}\n\t\treturn skip && !force ?\n\t\t\tnull :\n\t\t\tchart.renderer.crispLine([M, x1, y1, L, x2, y2], lineWidth || 0);\n\t},\n\t\n\t/**\n\t * Create the path for a plot band\n\t */\n\tgetPlotBandPath: function (from, to) {\n\n\t\tvar toPath = this.getPlotLinePath(to),\n\t\t\tpath = this.getPlotLinePath(from);\n\t\t\t\n\t\tif (path && toPath) {\n\t\t\tpath.push(\n\t\t\t\ttoPath[4],\n\t\t\t\ttoPath[5],\n\t\t\t\ttoPath[1],\n\t\t\t\ttoPath[2]\n\t\t\t);\n\t\t} else { // outside the axis area\n\t\t\tpath = null;\n\t\t}\n\t\t\n\t\treturn path;\n\t},\n\t\n\t/**\n\t * Set the tick positions of a linear axis to round values like whole tens or every five.\n\t */\n\tgetLinearTickPositions: function (tickInterval, min, max) {\n\t\tvar pos,\n\t\t\tlastPos,\n\t\t\troundedMin = correctFloat(mathFloor(min / tickInterval) * tickInterval),\n\t\t\troundedMax = correctFloat(mathCeil(max / tickInterval) * tickInterval),\n\t\t\ttickPositions = [];\n\n\t\t// Populate the intermediate values\n\t\tpos = roundedMin;\n\t\twhile (pos <= roundedMax) {\n\n\t\t\t// Place the tick on the rounded value\n\t\t\ttickPositions.push(pos);\n\n\t\t\t// Always add the raw tickInterval, not the corrected one.\n\t\t\tpos = correctFloat(pos + tickInterval);\n\n\t\t\t// If the interval is not big enough in the current min - max range to actually increase\n\t\t\t// the loop variable, we need to break out to prevent endless loop. Issue #619\n\t\t\tif (pos === lastPos) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Record the last value\n\t\t\tlastPos = pos;\n\t\t}\n\t\treturn tickPositions;\n\t},\n\t\n\t/**\n\t * Set the tick positions of a logarithmic axis\n\t */\n\tgetLogTickPositions: function (interval, min, max, minor) {\n\t\tvar axis = this,\n\t\t\toptions = axis.options,\n\t\t\taxisLength = axis.len,\n\t\t\t// Since we use this method for both major and minor ticks,\n\t\t\t// use a local variable and return the result\n\t\t\tpositions = []; \n\t\t\n\t\t// Reset\n\t\tif (!minor) {\n\t\t\taxis._minorAutoInterval = null;\n\t\t}\n\t\t\n\t\t// First case: All ticks fall on whole logarithms: 1, 10, 100 etc.\n\t\tif (interval >= 0.5) {\n\t\t\tinterval = mathRound(interval);\n\t\t\tpositions = axis.getLinearTickPositions(interval, min, max);\n\t\t\t\n\t\t// Second case: We need intermediary ticks. For example \n\t\t// 1, 2, 4, 6, 8, 10, 20, 40 etc. \n\t\t} else if (interval >= 0.08) {\n\t\t\tvar roundedMin = mathFloor(min),\n\t\t\t\tintermediate,\n\t\t\t\ti,\n\t\t\t\tj,\n\t\t\t\tlen,\n\t\t\t\tpos,\n\t\t\t\tlastPos,\n\t\t\t\tbreak2;\n\t\t\t\t\n\t\t\tif (interval > 0.3) {\n\t\t\t\tintermediate = [1, 2, 4];\n\t\t\t} else if (interval > 0.15) { // 0.2 equals five minor ticks per 1, 10, 100 etc\n\t\t\t\tintermediate = [1, 2, 4, 6, 8];\n\t\t\t} else { // 0.1 equals ten minor ticks per 1, 10, 100 etc\n\t\t\t\tintermediate = [1, 2, 3, 4, 5, 6, 7, 8, 9];\n\t\t\t}\n\t\t\t\n\t\t\tfor (i = roundedMin; i < max + 1 && !break2; i++) {\n\t\t\t\tlen = intermediate.length;\n\t\t\t\tfor (j = 0; j < len && !break2; j++) {\n\t\t\t\t\tpos = log2lin(lin2log(i) * intermediate[j]);\n\t\t\t\t\t\n\t\t\t\t\tif (pos > min && (!minor || lastPos <= max)) { // #1670\n\t\t\t\t\t\tpositions.push(lastPos);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tif (lastPos > max) {\n\t\t\t\t\t\tbreak2 = true;\n\t\t\t\t\t}\n\t\t\t\t\tlastPos = pos;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t// Third case: We are so deep in between whole logarithmic values that\n\t\t// we might as well handle the tick positions like a linear axis. For\n\t\t// example 1.01, 1.02, 1.03, 1.04.\n\t\t} else {\n\t\t\tvar realMin = lin2log(min),\n\t\t\t\trealMax = lin2log(max),\n\t\t\t\ttickIntervalOption = options[minor ? 'minorTickInterval' : 'tickInterval'],\n\t\t\t\tfilteredTickIntervalOption = tickIntervalOption === 'auto' ? null : tickIntervalOption,\n\t\t\t\ttickPixelIntervalOption = options.tickPixelInterval / (minor ? 5 : 1),\n\t\t\t\ttotalPixelLength = minor ? axisLength / axis.tickPositions.length : axisLength;\n\t\t\t\n\t\t\tinterval = pick(\n\t\t\t\tfilteredTickIntervalOption,\n\t\t\t\taxis._minorAutoInterval,\n\t\t\t\t(realMax - realMin) * tickPixelIntervalOption / (totalPixelLength || 1)\n\t\t\t);\n\t\t\t\n\t\t\tinterval = normalizeTickInterval(\n\t\t\t\tinterval, \n\t\t\t\tnull, \n\t\t\t\tgetMagnitude(interval)\n\t\t\t);\n\t\t\t\n\t\t\tpositions = map(axis.getLinearTickPositions(\n\t\t\t\tinterval, \n\t\t\t\trealMin,\n\t\t\t\trealMax\t\n\t\t\t), log2lin);\n\t\t\t\n\t\t\tif (!minor) {\n\t\t\t\taxis._minorAutoInterval = interval / 5;\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Set the axis-level tickInterval variable \n\t\tif (!minor) {\n\t\t\taxis.tickInterval = interval;\n\t\t}\n\t\treturn positions;\n\t},\n\n\t/**\n\t * Return the minor tick positions. For logarithmic axes, reuse the same logic\n\t * as for major ticks.\n\t */\n\tgetMinorTickPositions: function () {\n\t\tvar axis = this,\n\t\t\toptions = axis.options,\n\t\t\ttickPositions = axis.tickPositions,\n\t\t\tminorTickInterval = axis.minorTickInterval,\n\t\t\tminorTickPositions = [],\n\t\t\tpos,\n\t\t\ti,\n\t\t\tlen;\n\t\t\n\t\tif (axis.isLog) {\n\t\t\tlen = tickPositions.length;\n\t\t\tfor (i = 1; i < len; i++) {\n\t\t\t\tminorTickPositions = minorTickPositions.concat(\n\t\t\t\t\taxis.getLogTickPositions(minorTickInterval, tickPositions[i - 1], tickPositions[i], true)\n\t\t\t\t);\t\n\t\t\t}\n\t\t} else if (axis.isDatetimeAxis && options.minorTickInterval === 'auto') { // #1314\n\t\t\tminorTickPositions = minorTickPositions.concat(\n\t\t\t\tgetTimeTicks(\n\t\t\t\t\tnormalizeTimeTickInterval(minorTickInterval),\n\t\t\t\t\taxis.min,\n\t\t\t\t\taxis.max,\n\t\t\t\t\toptions.startOfWeek\n\t\t\t\t)\n\t\t\t);\n\t\t\tif (minorTickPositions[0] < axis.min) {\n\t\t\t\tminorTickPositions.shift();\n\t\t\t}\n\t\t} else {\t\t\t\n\t\t\tfor (pos = axis.min + (tickPositions[0] - axis.min) % minorTickInterval; pos <= axis.max; pos += minorTickInterval) {\n\t\t\t\tminorTickPositions.push(pos);\n\t\t\t}\n\t\t}\n\t\treturn minorTickPositions;\n\t},\n\n\t/**\n\t * Adjust the min and max for the minimum range. Keep in mind that the series data is \n\t * not yet processed, so we don't have information on data cropping and grouping, or \n\t * updated axis.pointRange or series.pointRange. The data can't be processed until\n\t * we have finally established min and max.\n\t */\n\tadjustForMinRange: function () {\n\t\tvar axis = this,\n\t\t\toptions = axis.options,\n\t\t\tmin = axis.min,\n\t\t\tmax = axis.max,\n\t\t\tzoomOffset,\n\t\t\tspaceAvailable = axis.dataMax - axis.dataMin >= axis.minRange,\n\t\t\tclosestDataRange,\n\t\t\ti,\n\t\t\tdistance,\n\t\t\txData,\n\t\t\tloopLength,\n\t\t\tminArgs,\n\t\t\tmaxArgs;\n\n\t\t// Set the automatic minimum range based on the closest point distance\n\t\tif (axis.isXAxis && axis.minRange === UNDEFINED && !axis.isLog) {\n\n\t\t\tif (defined(options.min) || defined(options.max)) {\n\t\t\t\taxis.minRange = null; // don't do this again\n\n\t\t\t} else {\n\n\t\t\t\t// Find the closest distance between raw data points, as opposed to\n\t\t\t\t// closestPointRange that applies to processed points (cropped and grouped)\n\t\t\t\teach(axis.series, function (series) {\n\t\t\t\t\txData = series.xData;\n\t\t\t\t\tloopLength = series.xIncrement ? 1 : xData.length - 1;\n\t\t\t\t\tfor (i = loopLength; i > 0; i--) {\n\t\t\t\t\t\tdistance = xData[i] - xData[i - 1];\n\t\t\t\t\t\tif (closestDataRange === UNDEFINED || distance < closestDataRange) {\n\t\t\t\t\t\t\tclosestDataRange = distance;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\taxis.minRange = mathMin(closestDataRange * 5, axis.dataMax - axis.dataMin);\n\t\t\t}\n\t\t}\n\n\t\t// if minRange is exceeded, adjust\n\t\tif (max - min < axis.minRange) {\n\t\t\tvar minRange = axis.minRange;\n\t\t\tzoomOffset = (minRange - max + min) / 2;\n\n\t\t\t// if min and max options have been set, don't go beyond it\n\t\t\tminArgs = [min - zoomOffset, pick(options.min, min - zoomOffset)];\n\t\t\tif (spaceAvailable) { // if space is available, stay within the data range\n\t\t\t\tminArgs[2] = axis.dataMin;\n\t\t\t}\n\t\t\tmin = arrayMax(minArgs);\n\n\t\t\tmaxArgs = [min + minRange, pick(options.max, min + minRange)];\n\t\t\tif (spaceAvailable) { // if space is availabe, stay within the data range\n\t\t\t\tmaxArgs[2] = axis.dataMax;\n\t\t\t}\n\n\t\t\tmax = arrayMin(maxArgs);\n\n\t\t\t// now if the max is adjusted, adjust the min back\n\t\t\tif (max - min < minRange) {\n\t\t\t\tminArgs[0] = max - minRange;\n\t\t\t\tminArgs[1] = pick(options.min, max - minRange);\n\t\t\t\tmin = arrayMax(minArgs);\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Record modified extremes\n\t\taxis.min = min;\n\t\taxis.max = max;\n\t},\n\n\t/**\n\t * Update translation information\n\t */\n\tsetAxisTranslation: function (saveOld) {\n\t\tvar axis = this,\n\t\t\trange = axis.max - axis.min,\n\t\t\tpointRange = 0,\n\t\t\tclosestPointRange,\n\t\t\tminPointOffset = 0,\n\t\t\tpointRangePadding = 0,\n\t\t\tlinkedParent = axis.linkedParent,\n\t\t\tordinalCorrection,\n\t\t\ttransA = axis.transA;\n\n\t\t// adjust translation for padding\n\t\tif (axis.isXAxis) {\n\t\t\tif (linkedParent) {\n\t\t\t\tminPointOffset = linkedParent.minPointOffset;\n\t\t\t\tpointRangePadding = linkedParent.pointRangePadding;\n\t\t\t\t\n\t\t\t} else {\n\t\t\t\teach(axis.series, function (series) {\n\t\t\t\t\tvar seriesPointRange = series.pointRange,\n\t\t\t\t\t\tpointPlacement = series.options.pointPlacement,\n\t\t\t\t\t\tseriesClosestPointRange = series.closestPointRange;\n\n\t\t\t\t\tif (seriesPointRange > range) { // #1446\n\t\t\t\t\t\tseriesPointRange = 0;\n\t\t\t\t\t}\n\t\t\t\t\tpointRange = mathMax(pointRange, seriesPointRange);\n\t\t\t\t\t\n\t\t\t\t\t// minPointOffset is the value padding to the left of the axis in order to make\n\t\t\t\t\t// room for points with a pointRange, typically columns. When the pointPlacement option\n\t\t\t\t\t// is 'between' or 'on', this padding does not apply.\n\t\t\t\t\tminPointOffset = mathMax(\n\t\t\t\t\t\tminPointOffset, \n\t\t\t\t\t\tisString(pointPlacement) ? 0 : seriesPointRange / 2\n\t\t\t\t\t);\n\t\t\t\t\t\n\t\t\t\t\t// Determine the total padding needed to the length of the axis to make room for the \n\t\t\t\t\t// pointRange. If the series' pointPlacement is 'on', no padding is added.\n\t\t\t\t\tpointRangePadding = mathMax(\n\t\t\t\t\t\tpointRangePadding,\n\t\t\t\t\t\tpointPlacement === 'on' ? 0 : seriesPointRange\n\t\t\t\t\t);\n\n\t\t\t\t\t// Set the closestPointRange\n\t\t\t\t\tif (!series.noSharedTooltip && defined(seriesClosestPointRange)) {\n\t\t\t\t\t\tclosestPointRange = defined(closestPointRange) ?\n\t\t\t\t\t\t\tmathMin(closestPointRange, seriesClosestPointRange) :\n\t\t\t\t\t\t\tseriesClosestPointRange;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\t\n\t\t\t// Record minPointOffset and pointRangePadding\n\t\t\tordinalCorrection = axis.ordinalSlope && closestPointRange ? axis.ordinalSlope / closestPointRange : 1; // #988, #1853\n\t\t\taxis.minPointOffset = minPointOffset = minPointOffset * ordinalCorrection;\n\t\t\taxis.pointRangePadding = pointRangePadding = pointRangePadding * ordinalCorrection;\n\n\t\t\t// pointRange means the width reserved for each point, like in a column chart\n\t\t\taxis.pointRange = mathMin(pointRange, range);\n\n\t\t\t// closestPointRange means the closest distance between points. In columns\n\t\t\t// it is mostly equal to pointRange, but in lines pointRange is 0 while closestPointRange\n\t\t\t// is some other value\n\t\t\taxis.closestPointRange = closestPointRange;\n\t\t}\n\n\t\t// Secondary values\n\t\tif (saveOld) {\n\t\t\taxis.oldTransA = transA;\n\t\t}\n\t\taxis.translationSlope = axis.transA = transA = axis.len / ((range + pointRangePadding) || 1);\n\t\taxis.transB = axis.horiz ? axis.left : axis.bottom; // translation addend\n\t\taxis.minPixelPadding = transA * minPointOffset;\n\t},\n\n\t/**\n\t * Set the tick positions to round values and optionally extend the extremes\n\t * to the nearest tick\n\t */\n\tsetTickPositions: function (secondPass) {\n\t\tvar axis = this,\n\t\t\tchart = axis.chart,\n\t\t\toptions = axis.options,\n\t\t\tisLog = axis.isLog,\n\t\t\tisDatetimeAxis = axis.isDatetimeAxis,\n\t\t\tisXAxis = axis.isXAxis,\n\t\t\tisLinked = axis.isLinked,\n\t\t\ttickPositioner = axis.options.tickPositioner,\n\t\t\tmaxPadding = options.maxPadding,\n\t\t\tminPadding = options.minPadding,\n\t\t\tlength,\n\t\t\tlinkedParentExtremes,\n\t\t\ttickIntervalOption = options.tickInterval,\n\t\t\tminTickIntervalOption = options.minTickInterval,\n\t\t\ttickPixelIntervalOption = options.tickPixelInterval,\n\t\t\ttickPositions,\n\t\t\tkeepTwoTicksOnly,\n\t\t\tcategories = axis.categories;\n\n\t\t// linked axis gets the extremes from the parent axis\n\t\tif (isLinked) {\n\t\t\taxis.linkedParent = chart[isXAxis ? 'xAxis' : 'yAxis'][options.linkedTo];\n\t\t\tlinkedParentExtremes = axis.linkedParent.getExtremes();\n\t\t\taxis.min = pick(linkedParentExtremes.min, linkedParentExtremes.dataMin);\n\t\t\taxis.max = pick(linkedParentExtremes.max, linkedParentExtremes.dataMax);\n\t\t\tif (options.type !== axis.linkedParent.options.type) {\n\t\t\t\terror(11, 1); // Can't link axes of different type\n\t\t\t}\n\t\t} else { // initial min and max from the extreme data values\n\t\t\taxis.min = pick(axis.userMin, options.min, axis.dataMin);\n\t\t\taxis.max = pick(axis.userMax, options.max, axis.dataMax);\n\t\t}\n\n\t\tif (isLog) {\n\t\t\tif (!secondPass && mathMin(axis.min, pick(axis.dataMin, axis.min)) <= 0) { // #978\n\t\t\t\terror(10, 1); // Can't plot negative values on log axis\n\t\t\t}\n\t\t\taxis.min = correctFloat(log2lin(axis.min)); // correctFloat cures #934\n\t\t\taxis.max = correctFloat(log2lin(axis.max));\n\t\t}\n\n\t\t// handle zoomed range\n\t\tif (axis.range) {\n\t\t\taxis.userMin = axis.min = mathMax(axis.min, axis.max - axis.range); // #618\n\t\t\taxis.userMax = axis.max;\n\t\t\tif (secondPass) {\n\t\t\t\taxis.range = null;  // don't use it when running setExtremes\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Hook for adjusting this.min and this.max. Used by bubble series.\n\t\tif (axis.beforePadding) {\n\t\t\taxis.beforePadding();\n\t\t}\n\n\t\t// adjust min and max for the minimum range\n\t\taxis.adjustForMinRange();\n\t\t\n\t\t// Pad the values to get clear of the chart's edges. To avoid tickInterval taking the padding\n\t\t// into account, we do this after computing tick interval (#1337).\n\t\tif (!categories && !axis.usePercentage && !isLinked && defined(axis.min) && defined(axis.max)) {\n\t\t\tlength = axis.max - axis.min;\n\t\t\tif (length) {\n\t\t\t\tif (!defined(options.min) && !defined(axis.userMin) && minPadding && (axis.dataMin < 0 || !axis.ignoreMinPadding)) {\n\t\t\t\t\taxis.min -= length * minPadding;\n\t\t\t\t}\n\t\t\t\tif (!defined(options.max) && !defined(axis.userMax)  && maxPadding && (axis.dataMax > 0 || !axis.ignoreMaxPadding)) {\n\t\t\t\t\taxis.max += length * maxPadding;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// get tickInterval\n\t\tif (axis.min === axis.max || axis.min === undefined || axis.max === undefined) {\n\t\t\taxis.tickInterval = 1;\n\t\t} else if (isLinked && !tickIntervalOption &&\n\t\t\t\ttickPixelIntervalOption === axis.linkedParent.options.tickPixelInterval) {\n\t\t\taxis.tickInterval = axis.linkedParent.tickInterval;\n\t\t} else {\n\t\t\taxis.tickInterval = pick(\n\t\t\t\ttickIntervalOption,\n\t\t\t\tcategories ? // for categoried axis, 1 is default, for linear axis use tickPix\n\t\t\t\t\t1 :\n\t\t\t\t\t// don't let it be more than the data range\n\t\t\t\t\t(axis.max - axis.min) * tickPixelIntervalOption / mathMax(axis.len, tickPixelIntervalOption)\n\t\t\t);\n\t\t\t// For squished axes, set only two ticks\n\t\t\tif (!defined(tickIntervalOption) && axis.len < tickPixelIntervalOption && !this.isRadial) {\n\t\t\t\tkeepTwoTicksOnly = true;\n\t\t\t\taxis.tickInterval /= 4; // tick extremes closer to the real values\n\t\t\t}\n\t\t}\n\n\t\t// Now we're finished detecting min and max, crop and group series data. This\n\t\t// is in turn needed in order to find tick positions in ordinal axes. \n\t\tif (isXAxis && !secondPass) {\n\t\t\teach(axis.series, function (series) {\n\t\t\t\tseries.processData(axis.min !== axis.oldMin || axis.max !== axis.oldMax);\n\t\t\t});\n\t\t}\n\n\t\t// set the translation factor used in translate function\n\t\taxis.setAxisTranslation(true);\n\n\t\t// hook for ordinal axes and radial axes\n\t\tif (axis.beforeSetTickPositions) {\n\t\t\taxis.beforeSetTickPositions();\n\t\t}\n\t\t\n\t\t// hook for extensions, used in Highstock ordinal axes\n\t\tif (axis.postProcessTickInterval) {\n\t\t\taxis.tickInterval = axis.postProcessTickInterval(axis.tickInterval);\n\t\t}\n\n\t\t// In column-like charts, don't cramp in more ticks than there are points (#1943)\n\t\tif (axis.pointRange) {\n\t\t\taxis.tickInterval = mathMax(axis.pointRange, axis.tickInterval);\n\t\t}\n\t\t\n\t\t// Before normalizing the tick interval, handle minimum tick interval. This applies only if tickInterval is not defined.\n\t\tif (!tickIntervalOption && axis.tickInterval < minTickIntervalOption) {\n\t\t\taxis.tickInterval = minTickIntervalOption;\n\t\t}\n\n\t\t// for linear axes, get magnitude and normalize the interval\n\t\tif (!isDatetimeAxis && !isLog) { // linear\n\t\t\tif (!tickIntervalOption) {\n\t\t\t\taxis.tickInterval = normalizeTickInterval(axis.tickInterval, null, getMagnitude(axis.tickInterval), options);\n\t\t\t}\n\t\t}\n\n\t\t// get minorTickInterval\n\t\taxis.minorTickInterval = options.minorTickInterval === 'auto' && axis.tickInterval ?\n\t\t\t\taxis.tickInterval / 5 : options.minorTickInterval;\n\n\t\t// find the tick positions\n\t\taxis.tickPositions = tickPositions = options.tickPositions ?\n\t\t\t[].concat(options.tickPositions) : // Work on a copy (#1565)\n\t\t\t(tickPositioner && tickPositioner.apply(axis, [axis.min, axis.max]));\n\t\tif (!tickPositions) {\n\t\t\t\n\t\t\t// Too many ticks\n\t\t\tif (!axis.ordinalPositions && (axis.max - axis.min) / axis.tickInterval > mathMax(2 * axis.len, 200)) {\n\t\t\t\terror(19, true);\n\t\t\t}\n\t\t\t\n\t\t\tif (isDatetimeAxis) {\n\t\t\t\ttickPositions = (axis.getNonLinearTimeTicks || getTimeTicks)(\n\t\t\t\t\tnormalizeTimeTickInterval(axis.tickInterval, options.units),\n\t\t\t\t\taxis.min,\n\t\t\t\t\taxis.max,\n\t\t\t\t\toptions.startOfWeek,\n\t\t\t\t\taxis.ordinalPositions,\n\t\t\t\t\taxis.closestPointRange,\n\t\t\t\t\ttrue\n\t\t\t\t);\n\t\t\t} else if (isLog) {\n\t\t\t\ttickPositions = axis.getLogTickPositions(axis.tickInterval, axis.min, axis.max);\n\t\t\t} else {\n\t\t\t\ttickPositions = axis.getLinearTickPositions(axis.tickInterval, axis.min, axis.max);\n\t\t\t}\n\t\t\tif (keepTwoTicksOnly) {\n\t\t\t\ttickPositions.splice(1, tickPositions.length - 2);\n\t\t\t}\n\n\t\t\taxis.tickPositions = tickPositions;\n\t\t}\n\n\t\tif (!isLinked) {\n\n\t\t\t// reset min/max or remove extremes based on start/end on tick\n\t\t\tvar roundedMin = tickPositions[0],\n\t\t\t\troundedMax = tickPositions[tickPositions.length - 1],\n\t\t\t\tminPointOffset = axis.minPointOffset || 0,\n\t\t\t\tsinglePad;\n\n\t\t\tif (options.startOnTick) {\n\t\t\t\taxis.min = roundedMin;\n\t\t\t} else if (axis.min - minPointOffset > roundedMin) {\n\t\t\t\ttickPositions.shift();\n\t\t\t}\n\n\t\t\tif (options.endOnTick) {\n\t\t\t\taxis.max = roundedMax;\n\t\t\t} else if (axis.max + minPointOffset < roundedMax) {\n\t\t\t\ttickPositions.pop();\n\t\t\t}\n\t\t\t\n\t\t\t// When there is only one point, or all points have the same value on this axis, then min\n\t\t\t// and max are equal and tickPositions.length is 1. In this case, add some padding\n\t\t\t// in order to center the point, but leave it with one tick. #1337.\n\t\t\tif (tickPositions.length === 1) {\n\t\t\t\tsinglePad = 0.001; // The lowest possible number to avoid extra padding on columns\n\t\t\t\taxis.min -= singlePad;\n\t\t\t\taxis.max += singlePad;\n\t\t\t}\n\t\t}\n\t},\n\t\n\t/**\n\t * Set the max ticks of either the x and y axis collection\n\t */\n\tsetMaxTicks: function () {\n\t\t\n\t\tvar chart = this.chart,\n\t\t\tmaxTicks = chart.maxTicks || {},\n\t\t\ttickPositions = this.tickPositions,\n\t\t\tkey = this._maxTicksKey = [this.xOrY, this.pos, this.len].join('-');\n\t\t\n\t\tif (!this.isLinked && !this.isDatetimeAxis && tickPositions && tickPositions.length > (maxTicks[key] || 0) && this.options.alignTicks !== false) {\n\t\t\tmaxTicks[key] = tickPositions.length;\n\t\t}\n\t\tchart.maxTicks = maxTicks;\n\t},\n\n\t/**\n\t * When using multiple axes, adjust the number of ticks to match the highest\n\t * number of ticks in that group\n\t */\n\tadjustTickAmount: function () {\n\t\tvar axis = this,\n\t\t\tchart = axis.chart,\n\t\t\tkey = axis._maxTicksKey,\n\t\t\ttickPositions = axis.tickPositions,\n\t\t\tmaxTicks = chart.maxTicks;\n\n\t\tif (maxTicks && maxTicks[key] && !axis.isDatetimeAxis && !axis.categories && !axis.isLinked && axis.options.alignTicks !== false) { // only apply to linear scale\n\t\t\tvar oldTickAmount = axis.tickAmount,\n\t\t\t\tcalculatedTickAmount = tickPositions.length,\n\t\t\t\ttickAmount;\n\n\t\t\t// set the axis-level tickAmount to use below\n\t\t\taxis.tickAmount = tickAmount = maxTicks[key];\n\n\t\t\tif (calculatedTickAmount < tickAmount) {\n\t\t\t\twhile (tickPositions.length < tickAmount) {\n\t\t\t\t\ttickPositions.push(correctFloat(\n\t\t\t\t\t\ttickPositions[tickPositions.length - 1] + axis.tickInterval\n\t\t\t\t\t));\n\t\t\t\t}\n\t\t\t\taxis.transA *= (calculatedTickAmount - 1) / (tickAmount - 1);\n\t\t\t\taxis.max = tickPositions[tickPositions.length - 1];\n\n\t\t\t}\n\t\t\tif (defined(oldTickAmount) && tickAmount !== oldTickAmount) {\n\t\t\t\taxis.isDirty = true;\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Set the scale based on data min and max, user set min and max or options\n\t *\n\t */\n\tsetScale: function () {\n\t\tvar axis = this,\n\t\t\tstacks = axis.stacks,\n\t\t\ttype,\n\t\t\ti,\n\t\t\tisDirtyData,\n\t\t\tisDirtyAxisLength;\n\n\t\taxis.oldMin = axis.min;\n\t\taxis.oldMax = axis.max;\n\t\taxis.oldAxisLength = axis.len;\n\n\t\t// set the new axisLength\n\t\taxis.setAxisSize();\n\t\t//axisLength = horiz ? axisWidth : axisHeight;\n\t\tisDirtyAxisLength = axis.len !== axis.oldAxisLength;\n\n\t\t// is there new data?\n\t\teach(axis.series, function (series) {\n\t\t\tif (series.isDirtyData || series.isDirty ||\n\t\t\t\t\tseries.xAxis.isDirty) { // when x axis is dirty, we need new data extremes for y as well\n\t\t\t\tisDirtyData = true;\n\t\t\t}\n\t\t});\n\n\t\t// do we really need to go through all this?\n\t\tif (isDirtyAxisLength || isDirtyData || axis.isLinked || axis.forceRedraw ||\n\t\t\taxis.userMin !== axis.oldUserMin || axis.userMax !== axis.oldUserMax) {\n\t\t\t\n\t\t\t// reset stacks\n\t\t\tif (!axis.isXAxis) {\n\t\t\t\tfor (type in stacks) {\n\t\t\t\t\tdelete stacks[type];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\taxis.forceRedraw = false;\n\n\t\t\t// get data extremes if needed\n\t\t\taxis.getSeriesExtremes();\n\n\t\t\t// get fixed positions based on tickInterval\n\t\t\taxis.setTickPositions();\n\n\t\t\t// record old values to decide whether a rescale is necessary later on (#540)\n\t\t\taxis.oldUserMin = axis.userMin;\n\t\t\taxis.oldUserMax = axis.userMax;\n\n\t\t\t// Mark as dirty if it is not already set to dirty and extremes have changed. #595.\n\t\t\tif (!axis.isDirty) {\n\t\t\t\taxis.isDirty = isDirtyAxisLength || axis.min !== axis.oldMin || axis.max !== axis.oldMax;\n\t\t\t}\n\t\t} else if (!axis.isXAxis) {\n\t\t\tif (axis.oldStacks) {\n\t\t\t\tstacks = axis.stacks = axis.oldStacks;\n\t\t\t}\n\n\t\t\t// reset stacks\n\t\t\tfor (type in stacks) {\n\t\t\t\tfor (i in stacks[type]) {\n\t\t\t\t\tstacks[type][i].cum = stacks[type][i].total;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Set the maximum tick amount\n\t\taxis.setMaxTicks();\n\t},\n\n\t/**\n\t * Set the extremes and optionally redraw\n\t * @param {Number} newMin\n\t * @param {Number} newMax\n\t * @param {Boolean} redraw\n\t * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\n\t *    configuration\n\t * @param {Object} eventArguments \n\t *\n\t */\n\tsetExtremes: function (newMin, newMax, redraw, animation, eventArguments) {\n\t\tvar axis = this,\n\t\t\tchart = axis.chart;\n\n\t\tredraw = pick(redraw, true); // defaults to true\n\n\t\t// Extend the arguments with min and max\n\t\teventArguments = extend(eventArguments, {\n\t\t\tmin: newMin,\n\t\t\tmax: newMax\n\t\t});\n\n\t\t// Fire the event\n\t\tfireEvent(axis, 'setExtremes', eventArguments, function () { // the default event handler\n\n\t\t\taxis.userMin = newMin;\n\t\t\taxis.userMax = newMax;\n\t\t\taxis.eventArgs = eventArguments;\n\n\t\t\t// Mark for running afterSetExtremes\n\t\t\taxis.isDirtyExtremes = true;\n\n\t\t\t// redraw\n\t\t\tif (redraw) {\n\t\t\t\tchart.redraw(animation);\n\t\t\t}\n\t\t});\n\t},\n\t\n\t/**\n\t * Overridable method for zooming chart. Pulled out in a separate method to allow overriding\n\t * in stock charts.\n\t */\n\tzoom: function (newMin, newMax) {\n\n\t\t// Prevent pinch zooming out of range. Check for defined is for #1946.\n\t\tif (!this.allowZoomOutside) {\n\t\t\tif (defined(this.dataMin) && newMin <= this.dataMin) {\n\t\t\t\tnewMin = UNDEFINED;\n\t\t\t}\n\t\t\tif (defined(this.dataMax) && newMax >= this.dataMax) {\n\t\t\t\tnewMax = UNDEFINED;\n\t\t\t}\n\t\t}\n\n\t\t// In full view, displaying the reset zoom button is not required\n\t\tthis.displayBtn = newMin !== UNDEFINED || newMax !== UNDEFINED;\n\t\t\n\t\t// Do it\n\t\tthis.setExtremes(\n\t\t\tnewMin,\n\t\t\tnewMax,\n\t\t\tfalse, \n\t\t\tUNDEFINED, \n\t\t\t{ trigger: 'zoom' }\n\t\t);\n\t\treturn true;\n\t},\n\t\n\t/**\n\t * Update the axis metrics\n\t */\n\tsetAxisSize: function () {\n\t\tvar chart = this.chart,\n\t\t\toptions = this.options,\n\t\t\toffsetLeft = options.offsetLeft || 0,\n\t\t\toffsetRight = options.offsetRight || 0,\n\t\t\thoriz = this.horiz,\n\t\t\twidth,\n\t\t\theight,\n\t\t\ttop,\n\t\t\tleft;\n\n\t\t// Expose basic values to use in Series object and navigator\n\t\tthis.left = left = pick(options.left, chart.plotLeft + offsetLeft);\n\t\tthis.top = top = pick(options.top, chart.plotTop);\n\t\tthis.width = width = pick(options.width, chart.plotWidth - offsetLeft + offsetRight);\n\t\tthis.height = height = pick(options.height, chart.plotHeight);\n\t\tthis.bottom = chart.chartHeight - height - top;\n\t\tthis.right = chart.chartWidth - width - left;\n\n\t\t// Direction agnostic properties\n\t\tthis.len = mathMax(horiz ? width : height, 0); // mathMax fixes #905\n\t\tthis.pos = horiz ? left : top; // distance from SVG origin\n\t},\n\n\t/**\n\t * Get the actual axis extremes\n\t */\n\tgetExtremes: function () {\n\t\tvar axis = this,\n\t\t\tisLog = axis.isLog;\n\n\t\treturn {\n\t\t\tmin: isLog ? correctFloat(lin2log(axis.min)) : axis.min,\n\t\t\tmax: isLog ? correctFloat(lin2log(axis.max)) : axis.max,\n\t\t\tdataMin: axis.dataMin,\n\t\t\tdataMax: axis.dataMax,\n\t\t\tuserMin: axis.userMin,\n\t\t\tuserMax: axis.userMax\n\t\t};\n\t},\n\n\t/**\n\t * Get the zero plane either based on zero or on the min or max value.\n\t * Used in bar and area plots\n\t */\n\tgetThreshold: function (threshold) {\n\t\tvar axis = this,\n\t\t\tisLog = axis.isLog;\n\n\t\tvar realMin = isLog ? lin2log(axis.min) : axis.min,\n\t\t\trealMax = isLog ? lin2log(axis.max) : axis.max;\n\t\t\n\t\tif (realMin > threshold || threshold === null) {\n\t\t\tthreshold = realMin;\n\t\t} else if (realMax < threshold) {\n\t\t\tthreshold = realMax;\n\t\t}\n\n\t\treturn axis.translate(threshold, 0, 1, 0, 1);\n\t},\n\n\taddPlotBand: function (options) {\n\t\tthis.addPlotBandOrLine(options, 'plotBands');\n\t},\n\t\n\taddPlotLine: function (options) {\n\t\tthis.addPlotBandOrLine(options, 'plotLines');\n\t},\n\n\t/**\n\t * Add a plot band or plot line after render time\n\t *\n\t * @param options {Object} The plotBand or plotLine configuration object\n\t */\n\taddPlotBandOrLine: function (options, coll) {\n\t\tvar obj = new PlotLineOrBand(this, options).render(),\n\t\t\tuserOptions = this.userOptions;\n\n\t\tif (obj) { // #2189\n\t\t\t// Add it to the user options for exporting and Axis.update\n\t\t\tif (coll) {\n\t\t\t\tuserOptions[coll] = userOptions[coll] || [];\n\t\t\t\tuserOptions[coll].push(options); \n\t\t\t}\n\t\t\tthis.plotLinesAndBands.push(obj); \n\t\t}\n\t\t\n\t\treturn obj;\n\t},\n\n\t/**\n\t * Compute auto alignment for the axis label based on which side the axis is on \n\t * and the given rotation for the label\n\t */\n\tautoLabelAlign: function (rotation) {\n\t\tvar ret, \n\t\t\tangle = (pick(rotation, 0) - (this.side * 90) + 720) % 360;\n\n\t\tif (angle > 15 && angle < 165) {\n\t\t\tret = 'right';\n\t\t} else if (angle > 195 && angle < 345) {\n\t\t\tret = 'left';\n\t\t} else {\n\t\t\tret = 'center';\n\t\t}\n\t\treturn ret;\n\t},\n\n\t/**\n\t * Render the tick labels to a preliminary position to get their sizes\n\t */\n\tgetOffset: function () {\n\t\tvar axis = this,\n\t\t\tchart = axis.chart,\n\t\t\trenderer = chart.renderer,\n\t\t\toptions = axis.options,\n\t\t\ttickPositions = axis.tickPositions,\n\t\t\tticks = axis.ticks,\n\t\t\thoriz = axis.horiz,\n\t\t\tside = axis.side,\n\t\t\tinvertedSide = chart.inverted ? [1, 0, 3, 2][side] : side,\n\t\t\thasData,\n\t\t\tshowAxis,\n\t\t\ttitleOffset = 0,\n\t\t\ttitleOffsetOption,\n\t\t\ttitleMargin = 0,\n\t\t\taxisTitleOptions = options.title,\n\t\t\tlabelOptions = options.labels,\n\t\t\tlabelOffset = 0, // reset\n\t\t\taxisOffset = chart.axisOffset,\n\t\t\tclipOffset = chart.clipOffset,\n\t\t\tdirectionFactor = [-1, 1, 1, -1][side],\n\t\t\tn,\n\t\t\ti,\n\t\t\tautoStaggerLines = 1,\n\t\t\tmaxStaggerLines = pick(labelOptions.maxStaggerLines, 5),\n\t\t\tsortedPositions,\n\t\t\tlastRight,\n\t\t\toverlap,\n\t\t\tpos,\n\t\t\tbBox,\n\t\t\tx,\n\t\t\tw,\n\t\t\tlineNo;\n\t\t\t\n\t\t// For reuse in Axis.render\n\t\taxis.hasData = hasData = (axis.hasVisibleSeries || (defined(axis.min) && defined(axis.max) && !!tickPositions));\n\t\taxis.showAxis = showAxis = hasData || pick(options.showEmpty, true);\n\n\t\t// Set/reset staggerLines\n\t\taxis.staggerLines = axis.horiz && labelOptions.staggerLines;\n\t\t\n\t\t// Create the axisGroup and gridGroup elements on first iteration\n\t\tif (!axis.axisGroup) {\n\t\t\taxis.gridGroup = renderer.g('grid')\n\t\t\t\t.attr({ zIndex: options.gridZIndex || 1 })\n\t\t\t\t.add();\n\t\t\taxis.axisGroup = renderer.g('axis')\n\t\t\t\t.attr({ zIndex: options.zIndex || 2 })\n\t\t\t\t.add();\n\t\t\taxis.labelGroup = renderer.g('axis-labels')\n\t\t\t\t.attr({ zIndex: labelOptions.zIndex || 7 })\n\t\t\t\t.add();\n\t\t}\n\n\t\tif (hasData || axis.isLinked) {\n\t\t\t\n\t\t\t// Set the explicit or automatic label alignment\n\t\t\taxis.labelAlign = pick(labelOptions.align || axis.autoLabelAlign(labelOptions.rotation));\n\n\t\t\teach(tickPositions, function (pos) {\n\t\t\t\tif (!ticks[pos]) {\n\t\t\t\t\tticks[pos] = new Tick(axis, pos);\n\t\t\t\t} else {\n\t\t\t\t\tticks[pos].addLabel(); // update labels depending on tick interval\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Handle automatic stagger lines\n\t\t\tif (axis.horiz && !axis.staggerLines && maxStaggerLines && !labelOptions.rotation) {\n\t\t\t\tsortedPositions = axis.reversed ? [].concat(tickPositions).reverse() : tickPositions;\n\t\t\t\twhile (autoStaggerLines < maxStaggerLines) {\n\t\t\t\t\tlastRight = [];\n\t\t\t\t\toverlap = false;\n\t\t\t\t\t\n\t\t\t\t\tfor (i = 0; i < sortedPositions.length; i++) {\n\t\t\t\t\t\tpos = sortedPositions[i];\n\t\t\t\t\t\tbBox = ticks[pos].label && ticks[pos].label.getBBox();\n\t\t\t\t\t\tw = bBox ? bBox.width : 0;\n\t\t\t\t\t\tlineNo = i % autoStaggerLines;\n\t\t\t\t\t\t\n\t\t\t\t\t\tif (w) {\n\t\t\t\t\t\t\tx = axis.translate(pos); // don't handle log\n\t\t\t\t\t\t\tif (lastRight[lineNo] !== UNDEFINED && x < lastRight[lineNo]) {\n\t\t\t\t\t\t\t\toverlap = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tlastRight[lineNo] = x + w;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (overlap) {\n\t\t\t\t\t\tautoStaggerLines++;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (autoStaggerLines > 1) {\n\t\t\t\t\taxis.staggerLines = autoStaggerLines;\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t\teach(tickPositions, function (pos) {\n\t\t\t\t// left side must be align: right and right side must have align: left for labels\n\t\t\t\tif (side === 0 || side === 2 || { 1: 'left', 3: 'right' }[side] === axis.labelAlign) {\n\n\t\t\t\t\t// get the highest offset\n\t\t\t\t\tlabelOffset = mathMax(\n\t\t\t\t\t\tticks[pos].getLabelSize(),\n\t\t\t\t\t\tlabelOffset\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t});\n\t\t\tif (axis.staggerLines) {\n\t\t\t\tlabelOffset *= axis.staggerLines;\n\t\t\t\taxis.labelOffset = labelOffset;\n\t\t\t}\n\t\t\t\n\n\t\t} else { // doesn't have data\n\t\t\tfor (n in ticks) {\n\t\t\t\tticks[n].destroy();\n\t\t\t\tdelete ticks[n];\n\t\t\t}\n\t\t}\n\n\t\tif (axisTitleOptions && axisTitleOptions.text && axisTitleOptions.enabled !== false) { \n\t\t\tif (!axis.axisTitle) {\n\t\t\t\taxis.axisTitle = renderer.text(\n\t\t\t\t\taxisTitleOptions.text,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\taxisTitleOptions.useHTML\n\t\t\t\t)\n\t\t\t\t.attr({\n\t\t\t\t\tzIndex: 7,\n\t\t\t\t\trotation: axisTitleOptions.rotation || 0,\n\t\t\t\t\talign:\n\t\t\t\t\t\taxisTitleOptions.textAlign ||\n\t\t\t\t\t\t{ low: 'left', middle: 'center', high: 'right' }[axisTitleOptions.align]\n\t\t\t\t})\n\t\t\t\t.css(axisTitleOptions.style)\n\t\t\t\t.add(axis.axisGroup);\n\t\t\t\taxis.axisTitle.isNew = true;\n\t\t\t}\n\n\t\t\tif (showAxis) {\n\t\t\t\ttitleOffset = axis.axisTitle.getBBox()[horiz ? 'height' : 'width'];\n\t\t\t\ttitleMargin = pick(axisTitleOptions.margin, horiz ? 5 : 10);\n\t\t\t\ttitleOffsetOption = axisTitleOptions.offset;\n\t\t\t}\n\n\t\t\t// hide or show the title depending on whether showEmpty is set\n\t\t\taxis.axisTitle[showAxis ? 'show' : 'hide']();\n\t\t}\n\t\t\n\t\t// handle automatic or user set offset\n\t\taxis.offset = directionFactor * pick(options.offset, axisOffset[side]);\n\t\t\n\t\taxis.axisTitleMargin =\n\t\t\tpick(titleOffsetOption,\n\t\t\t\tlabelOffset + titleMargin +\n\t\t\t\t(side !== 2 && labelOffset && directionFactor * options.labels[horiz ? 'y' : 'x'])\n\t\t\t);\n\n\t\taxisOffset[side] = mathMax(\n\t\t\taxisOffset[side],\n\t\t\taxis.axisTitleMargin + titleOffset + directionFactor * axis.offset\n\t\t);\n\t\tclipOffset[invertedSide] = mathMax(clipOffset[invertedSide], mathFloor(options.lineWidth / 2) * 2);\n\t},\n\t\n\t/**\n\t * Get the path for the axis line\n\t */\n\tgetLinePath: function (lineWidth) {\n\t\tvar chart = this.chart,\n\t\t\topposite = this.opposite,\n\t\t\toffset = this.offset,\n\t\t\thoriz = this.horiz,\n\t\t\tlineLeft = this.left + (opposite ? this.width : 0) + offset,\n\t\t\tlineTop = chart.chartHeight - this.bottom - (opposite ? this.height : 0) + offset;\n\t\t\t\n\t\tif (opposite) {\n\t\t\tlineWidth *= -1; // crispify the other way - #1480, #1687\n\t\t}\n\n\t\treturn chart.renderer.crispLine([\n\t\t\t\tM,\n\t\t\t\thoriz ?\n\t\t\t\t\tthis.left :\n\t\t\t\t\tlineLeft,\n\t\t\t\thoriz ?\n\t\t\t\t\tlineTop :\n\t\t\t\t\tthis.top,\n\t\t\t\tL,\n\t\t\t\thoriz ?\n\t\t\t\t\tchart.chartWidth - this.right :\n\t\t\t\t\tlineLeft,\n\t\t\t\thoriz ?\n\t\t\t\t\tlineTop :\n\t\t\t\t\tchart.chartHeight - this.bottom\n\t\t\t], lineWidth);\n\t},\n\t\n\t/**\n\t * Position the title\n\t */\n\tgetTitlePosition: function () {\n\t\t// compute anchor points for each of the title align options\n\t\tvar horiz = this.horiz,\n\t\t\taxisLeft = this.left,\n\t\t\taxisTop = this.top,\n\t\t\taxisLength = this.len,\n\t\t\taxisTitleOptions = this.options.title,\t\t\t\n\t\t\tmargin = horiz ? axisLeft : axisTop,\n\t\t\topposite = this.opposite,\n\t\t\toffset = this.offset,\n\t\t\tfontSize = pInt(axisTitleOptions.style.fontSize || 12),\n\t\t\t\n\t\t\t// the position in the length direction of the axis\n\t\t\talongAxis = {\n\t\t\t\tlow: margin + (horiz ? 0 : axisLength),\n\t\t\t\tmiddle: margin + axisLength / 2,\n\t\t\t\thigh: margin + (horiz ? axisLength : 0)\n\t\t\t}[axisTitleOptions.align],\n\t\n\t\t\t// the position in the perpendicular direction of the axis\n\t\t\toffAxis = (horiz ? axisTop + this.height : axisLeft) +\n\t\t\t\t(horiz ? 1 : -1) * // horizontal axis reverses the margin\n\t\t\t\t(opposite ? -1 : 1) * // so does opposite axes\n\t\t\t\tthis.axisTitleMargin +\n\t\t\t\t(this.side === 2 ? fontSize : 0);\n\n\t\treturn {\n\t\t\tx: horiz ?\n\t\t\t\talongAxis :\n\t\t\t\toffAxis + (opposite ? this.width : 0) + offset +\n\t\t\t\t\t(axisTitleOptions.x || 0), // x\n\t\t\ty: horiz ?\n\t\t\t\toffAxis - (opposite ? this.height : 0) + offset :\n\t\t\t\talongAxis + (axisTitleOptions.y || 0) // y\n\t\t};\n\t},\n\t\n\t/**\n\t * Render the axis\n\t */\n\trender: function () {\n\t\tvar axis = this,\n\t\t\tchart = axis.chart,\n\t\t\trenderer = chart.renderer,\n\t\t\toptions = axis.options,\n\t\t\tisLog = axis.isLog,\n\t\t\tisLinked = axis.isLinked,\n\t\t\ttickPositions = axis.tickPositions,\n\t\t\taxisTitle = axis.axisTitle,\n\t\t\tstacks = axis.stacks,\n\t\t\tticks = axis.ticks,\n\t\t\tminorTicks = axis.minorTicks,\n\t\t\talternateBands = axis.alternateBands,\n\t\t\tstackLabelOptions = options.stackLabels,\n\t\t\talternateGridColor = options.alternateGridColor,\n\t\t\ttickmarkOffset = axis.tickmarkOffset,\n\t\t\tlineWidth = options.lineWidth,\n\t\t\tlinePath,\n\t\t\thasRendered = chart.hasRendered,\n\t\t\tslideInTicks = hasRendered && defined(axis.oldMin) && !isNaN(axis.oldMin),\n\t\t\thasData = axis.hasData,\n\t\t\tshowAxis = axis.showAxis,\n\t\t\tfrom,\n\t\t\tto;\n\n\t\t// Mark all elements inActive before we go over and mark the active ones\n\t\teach([ticks, minorTicks, alternateBands], function (coll) {\n\t\t\tvar pos;\n\t\t\tfor (pos in coll) {\n\t\t\t\tcoll[pos].isActive = false;\n\t\t\t}\n\t\t});\n\n\t\t// If the series has data draw the ticks. Else only the line and title\n\t\tif (hasData || isLinked) {\n\n\t\t\t// minor ticks\n\t\t\tif (axis.minorTickInterval && !axis.categories) {\n\t\t\t\teach(axis.getMinorTickPositions(), function (pos) {\n\t\t\t\t\tif (!minorTicks[pos]) {\n\t\t\t\t\t\tminorTicks[pos] = new Tick(axis, pos, 'minor');\n\t\t\t\t\t}\n\n\t\t\t\t\t// render new ticks in old position\n\t\t\t\t\tif (slideInTicks && minorTicks[pos].isNew) {\n\t\t\t\t\t\tminorTicks[pos].render(null, true);\n\t\t\t\t\t}\n\n\t\t\t\t\tminorTicks[pos].render(null, false, 1);\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Major ticks. Pull out the first item and render it last so that\n\t\t\t// we can get the position of the neighbour label. #808.\n\t\t\tif (tickPositions.length) { // #1300\n\t\t\t\teach(tickPositions.slice(1).concat([tickPositions[0]]), function (pos, i) {\n\t\n\t\t\t\t\t// Reorganize the indices\n\t\t\t\t\ti = (i === tickPositions.length - 1) ? 0 : i + 1;\n\t\n\t\t\t\t\t// linked axes need an extra check to find out if\n\t\t\t\t\tif (!isLinked || (pos >= axis.min && pos <= axis.max)) {\n\t\n\t\t\t\t\t\tif (!ticks[pos]) {\n\t\t\t\t\t\t\tticks[pos] = new Tick(axis, pos);\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\t// render new ticks in old position\n\t\t\t\t\t\tif (slideInTicks && ticks[pos].isNew) {\n\t\t\t\t\t\t\tticks[pos].render(i, true);\n\t\t\t\t\t\t}\n\t\n\t\t\t\t\t\tticks[pos].render(i, false, 1);\n\t\t\t\t\t}\n\t\n\t\t\t\t});\n\t\t\t\t// In a categorized axis, the tick marks are displayed between labels. So\n\t\t\t\t// we need to add a tick mark and grid line at the left edge of the X axis.\n\t\t\t\tif (tickmarkOffset && axis.min === 0) {\n\t\t\t\t\tif (!ticks[-1]) {\n\t\t\t\t\t\tticks[-1] = new Tick(axis, -1, null, true);\n\t\t\t\t\t}\n\t\t\t\t\tticks[-1].render(-1);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t}\n\n\t\t\t// alternate grid color\n\t\t\tif (alternateGridColor) {\n\t\t\t\teach(tickPositions, function (pos, i) {\n\t\t\t\t\tif (i % 2 === 0 && pos < axis.max) {\n\t\t\t\t\t\tif (!alternateBands[pos]) {\n\t\t\t\t\t\t\talternateBands[pos] = new PlotLineOrBand(axis);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfrom = pos + tickmarkOffset; // #949\n\t\t\t\t\t\tto = tickPositions[i + 1] !== UNDEFINED ? tickPositions[i + 1] + tickmarkOffset : axis.max;\n\t\t\t\t\t\talternateBands[pos].options = {\n\t\t\t\t\t\t\tfrom: isLog ? lin2log(from) : from,\n\t\t\t\t\t\t\tto: isLog ? lin2log(to) : to,\n\t\t\t\t\t\t\tcolor: alternateGridColor\n\t\t\t\t\t\t};\n\t\t\t\t\t\talternateBands[pos].render();\n\t\t\t\t\t\talternateBands[pos].isActive = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// custom plot lines and bands\n\t\t\tif (!axis._addedPlotLB) { // only first time\n\t\t\t\teach((options.plotLines || []).concat(options.plotBands || []), function (plotLineOptions) {\n\t\t\t\t\taxis.addPlotBandOrLine(plotLineOptions);\n\t\t\t\t});\n\t\t\t\taxis._addedPlotLB = true;\n\t\t\t}\n\n\t\t} // end if hasData\n\n\t\t// Remove inactive ticks\n\t\teach([ticks, minorTicks, alternateBands], function (coll) {\n\t\t\tvar pos, \n\t\t\t\ti,\n\t\t\t\tforDestruction = [],\n\t\t\t\tdelay = globalAnimation ? globalAnimation.duration || 500 : 0,\n\t\t\t\tdestroyInactiveItems = function () {\n\t\t\t\t\ti = forDestruction.length;\n\t\t\t\t\twhile (i--) {\n\t\t\t\t\t\t// When resizing rapidly, the same items may be destroyed in different timeouts,\n\t\t\t\t\t\t// or the may be reactivated\n\t\t\t\t\t\tif (coll[forDestruction[i]] && !coll[forDestruction[i]].isActive) {\n\t\t\t\t\t\t\tcoll[forDestruction[i]].destroy();\n\t\t\t\t\t\t\tdelete coll[forDestruction[i]];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t};\n\n\t\t\tfor (pos in coll) {\n\n\t\t\t\tif (!coll[pos].isActive) {\n\t\t\t\t\t// Render to zero opacity\n\t\t\t\t\tcoll[pos].render(pos, false, 0);\n\t\t\t\t\tcoll[pos].isActive = false;\n\t\t\t\t\tforDestruction.push(pos);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// When the objects are finished fading out, destroy them\n\t\t\tif (coll === alternateBands || !chart.hasRendered || !delay) {\n\t\t\t\tdestroyInactiveItems();\n\t\t\t} else if (delay) {\n\t\t\t\tsetTimeout(destroyInactiveItems, delay);\n\t\t\t}\n\t\t});\n\n\t\t// Static items. As the axis group is cleared on subsequent calls\n\t\t// to render, these items are added outside the group.\n\t\t// axis line\n\t\tif (lineWidth) {\n\t\t\tlinePath = axis.getLinePath(lineWidth);\n\t\t\tif (!axis.axisLine) {\n\t\t\t\taxis.axisLine = renderer.path(linePath)\n\t\t\t\t\t.attr({\n\t\t\t\t\t\tstroke: options.lineColor,\n\t\t\t\t\t\t'stroke-width': lineWidth,\n\t\t\t\t\t\tzIndex: 7\n\t\t\t\t\t})\n\t\t\t\t\t.add(axis.axisGroup);\n\t\t\t} else {\n\t\t\t\taxis.axisLine.animate({ d: linePath });\n\t\t\t}\n\n\t\t\t// show or hide the line depending on options.showEmpty\n\t\t\taxis.axisLine[showAxis ? 'show' : 'hide']();\n\t\t}\n\n\t\tif (axisTitle && showAxis) {\n\t\t\t\n\t\t\taxisTitle[axisTitle.isNew ? 'attr' : 'animate'](\n\t\t\t\taxis.getTitlePosition()\n\t\t\t);\n\t\t\taxisTitle.isNew = false;\n\t\t}\n\n\t\t// Stacked totals:\n\t\tif (stackLabelOptions && stackLabelOptions.enabled) {\n\t\t\tvar stackKey, oneStack, stackCategory,\n\t\t\t\tstackTotalGroup = axis.stackTotalGroup;\n\n\t\t\t// Create a separate group for the stack total labels\n\t\t\tif (!stackTotalGroup) {\n\t\t\t\taxis.stackTotalGroup = stackTotalGroup =\n\t\t\t\t\trenderer.g('stack-labels')\n\t\t\t\t\t\t.attr({\n\t\t\t\t\t\t\tvisibility: VISIBLE,\n\t\t\t\t\t\t\tzIndex: 6\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.add();\n\t\t\t}\n\n\t\t\t// plotLeft/Top will change when y axis gets wider so we need to translate the\n\t\t\t// stackTotalGroup at every render call. See bug #506 and #516\n\t\t\tstackTotalGroup.translate(chart.plotLeft, chart.plotTop);\n\n\t\t\t// Render each stack total\n\t\t\tfor (stackKey in stacks) {\n\t\t\t\toneStack = stacks[stackKey];\n\t\t\t\tfor (stackCategory in oneStack) {\n\t\t\t\t\toneStack[stackCategory].render(stackTotalGroup);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// End stacked totals\n\n\t\taxis.isDirty = false;\n\t},\n\n\t/**\n\t * Remove a plot band or plot line from the chart by id\n\t * @param {Object} id\n\t */\n\tremovePlotBandOrLine: function (id) {\n\t\tvar plotLinesAndBands = this.plotLinesAndBands,\n\t\t\toptions = this.options,\n\t\t\tuserOptions = this.userOptions,\n\t\t\ti = plotLinesAndBands.length;\n\t\twhile (i--) {\n\t\t\tif (plotLinesAndBands[i].id === id) {\n\t\t\t\tplotLinesAndBands[i].destroy();\n\t\t\t}\n\t\t}\n\t\teach([options.plotLines || [], userOptions.plotLines || [], options.plotBands || [], userOptions.plotBands || []], function (arr) {\n\t\t\ti = arr.length;\n\t\t\twhile (i--) {\n\t\t\t\tif (arr[i].id === id) {\n\t\t\t\t\terase(arr, arr[i]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t},\n\n\t/**\n\t * Update the axis title by options\n\t */\n\tsetTitle: function (newTitleOptions, redraw) {\n\t\tthis.update({ title: newTitleOptions }, redraw);\n\t},\n\n\t/**\n\t * Redraw the axis to reflect changes in the data or axis extremes\n\t */\n\tredraw: function () {\n\t\tvar axis = this,\n\t\t\tchart = axis.chart,\n\t\t\tpointer = chart.pointer;\n\n\t\t// hide tooltip and hover states\n\t\tif (pointer.reset) {\n\t\t\tpointer.reset(true);\n\t\t}\n\n\t\t// render the axis\n\t\taxis.render();\n\n\t\t// move plot lines and bands\n\t\teach(axis.plotLinesAndBands, function (plotLine) {\n\t\t\tplotLine.render();\n\t\t});\n\n\t\t// mark associated series as dirty and ready for redraw\n\t\teach(axis.series, function (series) {\n\t\t\tseries.isDirty = true;\n\t\t});\n\n\t},\n\n\t/**\n\t * Build the stacks from top down\n\t */\n\tbuildStacks: function () {\n\t\tvar series = this.series,\n\t\t\ti = series.length;\n\t\tif (!this.isXAxis) {\n\t\t\twhile (i--) {\n\t\t\t\tseries[i].setStackedPoints();\n\t\t\t}\n\t\t\t// Loop up again to compute percent stack\n\t\t\tif (this.usePercentage) {\n\t\t\t\tfor (i = 0; i < series.length; i++) {\n\t\t\t\t\tseries[i].setPercentStacks();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Set new axis categories and optionally redraw\n\t * @param {Array} categories\n\t * @param {Boolean} redraw\n\t */\n\tsetCategories: function (categories, redraw) {\n\t\tthis.update({ categories: categories }, redraw);\n\t},\n\n\t/**\n\t * Destroys an Axis instance.\n\t */\n\tdestroy: function (keepEvents) {\n\t\tvar axis = this,\n\t\t\tstacks = axis.stacks,\n\t\t\tstackKey,\n\t\t\tplotLinesAndBands = axis.plotLinesAndBands,\n\t\t\ti;\n\n\t\t// Remove the events\n\t\tif (!keepEvents) {\n\t\t\tremoveEvent(axis);\n\t\t}\n\n\t\t// Destroy each stack total\n\t\tfor (stackKey in stacks) {\n\t\t\tdestroyObjectProperties(stacks[stackKey]);\n\n\t\t\tstacks[stackKey] = null;\n\t\t}\n\n\t\t// Destroy collections\n\t\teach([axis.ticks, axis.minorTicks, axis.alternateBands], function (coll) {\n\t\t\tdestroyObjectProperties(coll);\n\t\t});\n\t\ti = plotLinesAndBands.length;\n\t\twhile (i--) { // #1975\n\t\t\tplotLinesAndBands[i].destroy();\n\t\t}\n\n\t\t// Destroy local variables\n\t\teach(['stackTotalGroup', 'axisLine', 'axisGroup', 'gridGroup', 'labelGroup', 'axisTitle'], function (prop) {\n\t\t\tif (axis[prop]) {\n\t\t\t\taxis[prop] = axis[prop].destroy();\n\t\t\t}\n\t\t});\n\t}\n\n\t\n}; // end Axis\n\n/**\n * The tooltip object\n * @param {Object} chart The chart instance\n * @param {Object} options Tooltip options\n */\nfunction Tooltip() {\n\tthis.init.apply(this, arguments);\n}\n\nTooltip.prototype = {\n\n\tinit: function (chart, options) {\n\n\t\tvar borderWidth = options.borderWidth,\n\t\t\tstyle = options.style,\n\t\t\tpadding = pInt(style.padding);\n\n\t\t// Save the chart and options\n\t\tthis.chart = chart;\n\t\tthis.options = options;\n\n\t\t// Keep track of the current series\n\t\t//this.currentSeries = UNDEFINED;\n\n\t\t// List of crosshairs\n\t\tthis.crosshairs = [];\n\n\t\t// Current values of x and y when animating\n\t\tthis.now = { x: 0, y: 0 };\n\n\t\t// The tooltip is initially hidden\n\t\tthis.isHidden = true;\n\n\n\t\t// create the label\n\t\tthis.label = chart.renderer.label('', 0, 0, options.shape, null, null, options.useHTML, null, 'tooltip')\n\t\t\t.attr({\n\t\t\t\tpadding: padding,\n\t\t\t\tfill: options.backgroundColor,\n\t\t\t\t'stroke-width': borderWidth,\n\t\t\t\tr: options.borderRadius,\n\t\t\t\tzIndex: 8\n\t\t\t})\n\t\t\t.css(style)\n\t\t\t.css({ padding: 0 }) // Remove it from VML, the padding is applied as an attribute instead (#1117)\n\t\t\t.add()\n\t\t\t.attr({ y: -999 }); // #2301\n\n\t\t// When using canVG the shadow shows up as a gray circle\n\t\t// even if the tooltip is hidden.\n\t\tif (!useCanVG) {\n\t\t\tthis.label.shadow(options.shadow);\n\t\t}\n\n\t\t// Public property for getting the shared state.\n\t\tthis.shared = options.shared;\n\t},\n\n\t/**\n\t * Destroy the tooltip and its elements.\n\t */\n\tdestroy: function () {\n\t\teach(this.crosshairs, function (crosshair) {\n\t\t\tif (crosshair) {\n\t\t\t\tcrosshair.destroy();\n\t\t\t}\n\t\t});\n\n\t\t// Destroy and clear local variables\n\t\tif (this.label) {\n\t\t\tthis.label = this.label.destroy();\n\t\t}\n\t\tclearTimeout(this.hideTimer);\n\t\tclearTimeout(this.tooltipTimeout);\n\t},\n\n\t/**\n\t * Provide a soft movement for the tooltip\n\t *\n\t * @param {Number} x\n\t * @param {Number} y\n\t * @private\n\t */\n\tmove: function (x, y, anchorX, anchorY) {\n\t\tvar tooltip = this,\n\t\t\tnow = tooltip.now,\n\t\t\tanimate = tooltip.options.animation !== false && !tooltip.isHidden;\n\n\t\t// get intermediate values for animation\n\t\textend(now, {\n\t\t\tx: animate ? (2 * now.x + x) / 3 : x,\n\t\t\ty: animate ? (now.y + y) / 2 : y,\n\t\t\tanchorX: animate ? (2 * now.anchorX + anchorX) / 3 : anchorX,\n\t\t\tanchorY: animate ? (now.anchorY + anchorY) / 2 : anchorY\n\t\t});\n\n\t\t// move to the intermediate value\n\t\ttooltip.label.attr(now);\n\n\t\t\n\t\t// run on next tick of the mouse tracker\n\t\tif (animate && (mathAbs(x - now.x) > 1 || mathAbs(y - now.y) > 1)) {\n\t\t\n\t\t\t// never allow two timeouts\n\t\t\tclearTimeout(this.tooltipTimeout);\n\t\t\t\n\t\t\t// set the fixed interval ticking for the smooth tooltip\n\t\t\tthis.tooltipTimeout = setTimeout(function () {\n\t\t\t\t// The interval function may still be running during destroy, so check that the chart is really there before calling.\n\t\t\t\tif (tooltip) {\n\t\t\t\t\ttooltip.move(x, y, anchorX, anchorY);\n\t\t\t\t}\n\t\t\t}, 32);\n\t\t\t\n\t\t}\n\t},\n\n\t/**\n\t * Hide the tooltip\n\t */\n\thide: function () {\n\t\tvar tooltip = this,\n\t\t\thoverPoints;\n\t\t\n\t\tclearTimeout(this.hideTimer); // disallow duplicate timers (#1728, #1766)\n\t\tif (!this.isHidden) {\n\t\t\thoverPoints = this.chart.hoverPoints;\n\n\t\t\tthis.hideTimer = setTimeout(function () {\n\t\t\t\ttooltip.label.fadeOut();\n\t\t\t\ttooltip.isHidden = true;\n\t\t\t}, pick(this.options.hideDelay, 500));\n\n\t\t\t// hide previous hoverPoints and set new\n\t\t\tif (hoverPoints) {\n\t\t\t\teach(hoverPoints, function (point) {\n\t\t\t\t\tpoint.setState();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tthis.chart.hoverPoints = null;\n\t\t}\n\t},\n\n\t/**\n\t * Hide the crosshairs\n\t */\n\thideCrosshairs: function () {\n\t\teach(this.crosshairs, function (crosshair) {\n\t\t\tif (crosshair) {\n\t\t\t\tcrosshair.hide();\n\t\t\t}\n\t\t});\n\t},\n\t\n\t/** \n\t * Extendable method to get the anchor position of the tooltip\n\t * from a point or set of points\n\t */\n\tgetAnchor: function (points, mouseEvent) {\n\t\tvar ret,\n\t\t\tchart = this.chart,\n\t\t\tinverted = chart.inverted,\n\t\t\tplotTop = chart.plotTop,\n\t\t\tplotX = 0,\n\t\t\tplotY = 0,\n\t\t\tyAxis;\n\t\t\n\t\tpoints = splat(points);\n\t\t\n\t\t// Pie uses a special tooltipPos\n\t\tret = points[0].tooltipPos;\n\t\t\n\t\t// When tooltip follows mouse, relate the position to the mouse\n\t\tif (this.followPointer && mouseEvent) {\n\t\t\tif (mouseEvent.chartX === UNDEFINED) {\n\t\t\t\tmouseEvent = chart.pointer.normalize(mouseEvent);\n\t\t\t}\n\t\t\tret = [\n\t\t\t\tmouseEvent.chartX - chart.plotLeft,\n\t\t\t\tmouseEvent.chartY - plotTop\n\t\t\t];\n\t\t}\n\t\t// When shared, use the average position\n\t\tif (!ret) {\n\t\t\teach(points, function (point) {\n\t\t\t\tyAxis = point.series.yAxis;\n\t\t\t\tplotX += point.plotX;\n\t\t\t\tplotY += (point.plotLow ? (point.plotLow + point.plotHigh) / 2 : point.plotY) +\n\t\t\t\t\t(!inverted && yAxis ? yAxis.top - plotTop : 0); // #1151\n\t\t\t});\n\t\t\t\n\t\t\tplotX /= points.length;\n\t\t\tplotY /= points.length;\n\t\t\t\n\t\t\tret = [\n\t\t\t\tinverted ? chart.plotWidth - plotY : plotX,\n\t\t\t\tthis.shared && !inverted && points.length > 1 && mouseEvent ? \n\t\t\t\t\tmouseEvent.chartY - plotTop : // place shared tooltip next to the mouse (#424)\n\t\t\t\t\tinverted ? chart.plotHeight - plotX : plotY\n\t\t\t];\n\t\t}\n\n\t\treturn map(ret, mathRound);\n\t},\n\t\n\t/**\n\t * Place the tooltip in a chart without spilling over\n\t * and not covering the point it self.\n\t */\n\tgetPosition: function (boxWidth, boxHeight, point) {\n\t\t\n\t\t// Set up the variables\n\t\tvar chart = this.chart,\n\t\t\tplotLeft = chart.plotLeft,\n\t\t\tplotTop = chart.plotTop,\n\t\t\tplotWidth = chart.plotWidth,\n\t\t\tplotHeight = chart.plotHeight,\n\t\t\tdistance = pick(this.options.distance, 12),\n\t\t\tpointX = point.plotX,\n\t\t\tpointY = point.plotY,\n\t\t\tx = pointX + plotLeft + (chart.inverted ? distance : -boxWidth - distance),\n\t\t\ty = pointY - boxHeight + plotTop + 15, // 15 means the point is 15 pixels up from the bottom of the tooltip\n\t\t\talignedRight;\n\t\n\t\t// It is too far to the left, adjust it\n\t\tif (x < 7) {\n\t\t\tx = plotLeft + mathMax(pointX, 0) + distance;\n\t\t}\n\t\n\t\t// Test to see if the tooltip is too far to the right,\n\t\t// if it is, move it back to be inside and then up to not cover the point.\n\t\tif ((x + boxWidth) > (plotLeft + plotWidth)) {\n\t\t\tx -= (x + boxWidth) - (plotLeft + plotWidth);\n\t\t\ty = pointY - boxHeight + plotTop - distance;\n\t\t\talignedRight = true;\n\t\t}\n\t\n\t\t// If it is now above the plot area, align it to the top of the plot area\n\t\tif (y < plotTop + 5) {\n\t\t\ty = plotTop + 5;\n\t\n\t\t\t// If the tooltip is still covering the point, move it below instead\n\t\t\tif (alignedRight && pointY >= y && pointY <= (y + boxHeight)) {\n\t\t\t\ty = pointY + plotTop + distance; // below\n\t\t\t}\n\t\t} \n\t\n\t\t// Now if the tooltip is below the chart, move it up. It's better to cover the\n\t\t// point than to disappear outside the chart. #834.\n\t\tif (y + boxHeight > plotTop + plotHeight) {\n\t\t\ty = mathMax(plotTop, plotTop + plotHeight - boxHeight - distance); // below\n\t\t}\n\t\n\t\treturn {x: x, y: y};\n\t},\n\n\t/**\n\t * In case no user defined formatter is given, this will be used. Note that the context\n\t * here is an object holding point, series, x, y etc.\n\t */\n\tdefaultFormatter: function (tooltip) {\n\t\tvar items = this.points || splat(this),\n\t\t\tseries = items[0].series,\n\t\t\ts;\n\n\t\t// build the header\n\t\ts = [series.tooltipHeaderFormatter(items[0])];\n\n\t\t// build the values\n\t\teach(items, function (item) {\n\t\t\tseries = item.series;\n\t\t\ts.push((series.tooltipFormatter && series.tooltipFormatter(item)) ||\n\t\t\t\titem.point.tooltipFormatter(series.tooltipOptions.pointFormat));\n\t\t});\n\n\t\t// footer\n\t\ts.push(tooltip.options.footerFormat || '');\n\n\t\treturn s.join('');\n\t},\n\n\t/**\n\t * Refresh the tooltip's text and position.\n\t * @param {Object} point\n\t */\n\trefresh: function (point, mouseEvent) {\n\t\tvar tooltip = this,\n\t\t\tchart = tooltip.chart,\n\t\t\tlabel = tooltip.label,\n\t\t\toptions = tooltip.options,\n\t\t\tx,\n\t\t\ty,\n\t\t\tanchor,\n\t\t\ttextConfig = {},\n\t\t\ttext,\n\t\t\tpointConfig = [],\n\t\t\tformatter = options.formatter || tooltip.defaultFormatter,\n\t\t\thoverPoints = chart.hoverPoints,\n\t\t\tborderColor,\n\t\t\tcrosshairsOptions = options.crosshairs,\n\t\t\tshared = tooltip.shared,\n\t\t\tcurrentSeries;\n\t\t\t\n\t\tclearTimeout(this.hideTimer);\n\t\t\n\t\t// get the reference point coordinates (pie charts use tooltipPos)\n\t\ttooltip.followPointer = splat(point)[0].series.tooltipOptions.followPointer;\n\t\tanchor = tooltip.getAnchor(point, mouseEvent);\n\t\tx = anchor[0];\n\t\ty = anchor[1];\n\n\t\t// shared tooltip, array is sent over\n\t\tif (shared && !(point.series && point.series.noSharedTooltip)) {\n\t\t\t\n\t\t\t// hide previous hoverPoints and set new\n\t\t\t\n\t\t\tchart.hoverPoints = point;\n\t\t\tif (hoverPoints) {\n\t\t\t\teach(hoverPoints, function (point) {\n\t\t\t\t\tpoint.setState();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\teach(point, function (item) {\n\t\t\t\titem.setState(HOVER_STATE);\n\n\t\t\t\tpointConfig.push(item.getLabelConfig());\n\t\t\t});\n\n\t\t\ttextConfig = {\n\t\t\t\tx: point[0].category,\n\t\t\t\ty: point[0].y\n\t\t\t};\n\t\t\ttextConfig.points = pointConfig;\n\t\t\tpoint = point[0];\n\n\t\t// single point tooltip\n\t\t} else {\n\t\t\ttextConfig = point.getLabelConfig();\n\t\t}\n\t\ttext = formatter.call(textConfig, tooltip);\n\n\t\t// register the current series\n\t\tcurrentSeries = point.series;\n\n\t\t// update the inner HTML\n\t\tif (text === false) {\n\t\t\tthis.hide();\n\t\t} else {\n\n\t\t\t// show it\n\t\t\tif (tooltip.isHidden) {\n\t\t\t\tstop(label);\n\t\t\t\tlabel.attr('opacity', 1).show();\n\t\t\t}\n\n\t\t\t// update text\n\t\t\tlabel.attr({\n\t\t\t\ttext: text\n\t\t\t});\n\n\t\t\t// set the stroke color of the box\n\t\t\tborderColor = options.borderColor || point.color || currentSeries.color || '#606060';\n\t\t\tlabel.attr({\n\t\t\t\tstroke: borderColor\n\t\t\t});\n\t\t\t\n\t\t\ttooltip.updatePosition({ plotX: x, plotY: y });\n\t\t\n\t\t\tthis.isHidden = false;\n\t\t}\n\n\t\t// crosshairs\n\t\tif (crosshairsOptions) {\n\t\t\tcrosshairsOptions = splat(crosshairsOptions); // [x, y]\n\n\t\t\tvar path,\n\t\t\t\ti = crosshairsOptions.length,\n\t\t\t\tattribs,\n\t\t\t\taxis,\n\t\t\t\tval,\n\t\t\t\tseries;\n\n\t\t\twhile (i--) {\n\t\t\t\tseries = point.series;\n\t\t\t\taxis = series[i ? 'yAxis' : 'xAxis'];\n\t\t\t\tif (crosshairsOptions[i] && axis) {\n\t\t\t\t\tval = i ? pick(point.stackY, point.y) : point.x; // #814\n\t\t\t\t\tif (axis.isLog) { // #1671\n\t\t\t\t\t\tval = log2lin(val);\n\t\t\t\t\t}\n\t\t\t\t\tif (i === 1 && series.modifyValue) { // #1205, #2316\n\t\t\t\t\t\tval = series.modifyValue(val);\n\t\t\t\t\t}\n\n\t\t\t\t\tpath = axis.getPlotLinePath(\n\t\t\t\t\t\tval,\n\t\t\t\t\t\t1\n\t\t\t\t\t);\n\n\t\t\t\t\tif (tooltip.crosshairs[i]) {\n\t\t\t\t\t\ttooltip.crosshairs[i].attr({ d: path, visibility: VISIBLE });\n\t\t\t\t\t} else {\n\t\t\t\t\t\tattribs = {\n\t\t\t\t\t\t\t'stroke-width': crosshairsOptions[i].width || 1,\n\t\t\t\t\t\t\tstroke: crosshairsOptions[i].color || '#C0C0C0',\n\t\t\t\t\t\t\tzIndex: crosshairsOptions[i].zIndex || 2\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (crosshairsOptions[i].dashStyle) {\n\t\t\t\t\t\t\tattribs.dashstyle = crosshairsOptions[i].dashStyle;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttooltip.crosshairs[i] = chart.renderer.path(path)\n\t\t\t\t\t\t\t.attr(attribs)\n\t\t\t\t\t\t\t.add();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tfireEvent(chart, 'tooltipRefresh', {\n\t\t\t\ttext: text,\n\t\t\t\tx: x + chart.plotLeft,\n\t\t\t\ty: y + chart.plotTop,\n\t\t\t\tborderColor: borderColor\n\t\t\t});\n\t},\n\t\n\t/**\n\t * Find the new position and perform the move\n\t */\n\tupdatePosition: function (point) {\n\t\tvar chart = this.chart,\n\t\t\tlabel = this.label, \n\t\t\tpos = (this.options.positioner || this.getPosition).call(\n\t\t\t\tthis,\n\t\t\t\tlabel.width,\n\t\t\t\tlabel.height,\n\t\t\t\tpoint\n\t\t\t);\n\n\t\t// do the move\n\t\tthis.move(\n\t\t\tmathRound(pos.x), \n\t\t\tmathRound(pos.y), \n\t\t\tpoint.plotX + chart.plotLeft, \n\t\t\tpoint.plotY + chart.plotTop\n\t\t);\n\t}\n};\n/**\n * The mouse tracker object. All methods starting with \"on\" are primary DOM event handlers. \n * Subsequent methods should be named differently from what they are doing.\n * @param {Object} chart The Chart instance\n * @param {Object} options The root options object\n */\nfunction Pointer(chart, options) {\n\tthis.init(chart, options);\n}\n\nPointer.prototype = {\n\t/**\n\t * Initialize Pointer\n\t */\n\tinit: function (chart, options) {\n\t\t\n\t\tvar chartOptions = options.chart,\n\t\t\tchartEvents = chartOptions.events,\n\t\t\tzoomType = useCanVG ? '' : chartOptions.zoomType,\n\t\t\tinverted = chart.inverted,\n\t\t\tzoomX,\n\t\t\tzoomY;\n\n\t\t// Store references\n\t\tthis.options = options;\n\t\tthis.chart = chart;\n\t\t\n\t\t// Zoom status\n\t\tthis.zoomX = zoomX = /x/.test(zoomType);\n\t\tthis.zoomY = zoomY = /y/.test(zoomType);\n\t\tthis.zoomHor = (zoomX && !inverted) || (zoomY && inverted);\n\t\tthis.zoomVert = (zoomY && !inverted) || (zoomX && inverted);\n\n\t\t// Do we need to handle click on a touch device?\n\t\tthis.runChartClick = chartEvents && !!chartEvents.click;\n\n\t\tthis.pinchDown = [];\n\t\tthis.lastValidTouch = {};\n\n\t\tif (options.tooltip.enabled) {\n\t\t\tchart.tooltip = new Tooltip(chart, options.tooltip);\n\t\t}\n\n\t\tthis.setDOMEvents();\n\t}, \n\n\t/**\n\t * Add crossbrowser support for chartX and chartY\n\t * @param {Object} e The event object in standard browsers\n\t */\n\tnormalize: function (e, chartPosition) {\n\t\tvar chartX,\n\t\t\tchartY,\n\t\t\tePos;\n\n\t\t// common IE normalizing\n\t\te = e || win.event;\n\t\tif (!e.target) {\n\t\t\te.target = e.srcElement;\n\t\t}\n\n\t\t// Framework specific normalizing (#1165)\n\t\te = washMouseEvent(e);\n\t\t\n\t\t// iOS\n\t\tePos = e.touches ? e.touches.item(0) : e;\n\n\t\t// Get mouse position\n\t\tif (!chartPosition) {\n\t\t\tthis.chartPosition = chartPosition = offset(this.chart.container);\n\t\t}\n\n\t\t// chartX and chartY\n\t\tif (ePos.pageX === UNDEFINED) { // IE < 9. #886.\n\t\t\tchartX = mathMax(e.x, e.clientX - chartPosition.left); // #2005, #2129: the second case is \n\t\t\t\t// for IE10 quirks mode within framesets\n\t\t\tchartY = e.y;\n\t\t} else {\n\t\t\tchartX = ePos.pageX - chartPosition.left;\n\t\t\tchartY = ePos.pageY - chartPosition.top;\n\t\t}\n\n\t\treturn extend(e, {\n\t\t\tchartX: mathRound(chartX),\n\t\t\tchartY: mathRound(chartY)\n\t\t});\n\t},\n\n\t/**\n\t * Get the click position in terms of axis values.\n\t *\n\t * @param {Object} e A pointer event\n\t */\n\tgetCoordinates: function (e) {\n\t\tvar coordinates = {\n\t\t\t\txAxis: [],\n\t\t\t\tyAxis: []\n\t\t\t};\n\n\t\teach(this.chart.axes, function (axis) {\n\t\t\tcoordinates[axis.isXAxis ? 'xAxis' : 'yAxis'].push({\n\t\t\t\taxis: axis,\n\t\t\t\tvalue: axis.toValue(e[axis.horiz ? 'chartX' : 'chartY'])\n\t\t\t});\n\t\t});\n\t\treturn coordinates;\n\t},\n\t\n\t/**\n\t * Return the index in the tooltipPoints array, corresponding to pixel position in \n\t * the plot area.\n\t */\n\tgetIndex: function (e) {\n\t\tvar chart = this.chart;\n\t\treturn chart.inverted ? \n\t\t\tchart.plotHeight + chart.plotTop - e.chartY : \n\t\t\te.chartX - chart.plotLeft;\n\t},\n\n\t/**\n\t * With line type charts with a single tracker, get the point closest to the mouse.\n\t * Run Point.onMouseOver and display tooltip for the point or points.\n\t */\n\trunPointActions: function (e) {\n\t\tvar pointer = this,\n\t\t\tchart = pointer.chart,\n\t\t\tseries = chart.series,\n\t\t\ttooltip = chart.tooltip,\n\t\t\tpoint,\n\t\t\tpoints,\n\t\t\thoverPoint = chart.hoverPoint,\n\t\t\thoverSeries = chart.hoverSeries,\n\t\t\ti,\n\t\t\tj,\n\t\t\tdistance = chart.chartWidth,\n\t\t\tindex = pointer.getIndex(e),\n\t\t\tanchor;\n\n\t\t// shared tooltip\n\t\tif (tooltip && pointer.options.tooltip.shared && !(hoverSeries && hoverSeries.noSharedTooltip)) {\n\t\t\tpoints = [];\n\n\t\t\t// loop over all series and find the ones with points closest to the mouse\n\t\t\ti = series.length;\n\t\t\tfor (j = 0; j < i; j++) {\n\t\t\t\tif (series[j].visible &&\n\t\t\t\t\t\tseries[j].options.enableMouseTracking !== false &&\n\t\t\t\t\t\t!series[j].noSharedTooltip && series[j].tooltipPoints.length) {\n\t\t\t\t\tpoint = series[j].tooltipPoints[index];\n\t\t\t\t\tif (point && point.series) { // not a dummy point, #1544\n\t\t\t\t\t\tpoint._dist = mathAbs(index - point.clientX);\n\t\t\t\t\t\tdistance = mathMin(distance, point._dist);\n\t\t\t\t\t\tpoints.push(point);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t// remove furthest points\n\t\t\ti = points.length;\n\t\t\twhile (i--) {\n\t\t\t\tif (points[i]._dist > distance) {\n\t\t\t\t\tpoints.splice(i, 1);\n\t\t\t\t}\n\t\t\t}\n\t\t\t// refresh the tooltip if necessary\n\t\t\tif (points.length && (points[0].clientX !== pointer.hoverX)) {\n\t\t\t\ttooltip.refresh(points, e);\n\t\t\t\tpointer.hoverX = points[0].clientX;\n\t\t\t}\n\t\t}\n\n\t\t// separate tooltip and general mouse events\n\t\tif (hoverSeries && hoverSeries.tracker) { // only use for line-type series with common tracker\n\n\t\t\t// get the point\n\t\t\tpoint = hoverSeries.tooltipPoints[index];\n\n\t\t\t// a new point is hovered, refresh the tooltip\n\t\t\tif (point && point !== hoverPoint) {\n\n\t\t\t\t// trigger the events\n\t\t\t\tpoint.onMouseOver(e);\n\n\t\t\t}\n\t\t\t\n\t\t} else if (tooltip && tooltip.followPointer && !tooltip.isHidden) {\n\t\t\tanchor = tooltip.getAnchor([{}], e);\n\t\t\ttooltip.updatePosition({ plotX: anchor[0], plotY: anchor[1] });\n\t\t}\n\t},\n\n\n\n\t/**\n\t * Reset the tracking by hiding the tooltip, the hover series state and the hover point\n\t * \n\t * @param allowMove {Boolean} Instead of destroying the tooltip altogether, allow moving it if possible\n\t */\n\treset: function (allowMove) {\n\t\tvar pointer = this,\n\t\t\tchart = pointer.chart,\n\t\t\thoverSeries = chart.hoverSeries,\n\t\t\thoverPoint = chart.hoverPoint,\n\t\t\ttooltip = chart.tooltip,\n\t\t\ttooltipPoints = tooltip && tooltip.shared ? chart.hoverPoints : hoverPoint;\n\t\t\t\n\t\t// Narrow in allowMove\n\t\tallowMove = allowMove && tooltip && tooltipPoints;\n\t\t\t\n\t\t// Check if the points have moved outside the plot area, #1003\n\t\tif (allowMove && splat(tooltipPoints)[0].plotX === UNDEFINED) {\n\t\t\tallowMove = false;\n\t\t}\t\n\n\t\t// Just move the tooltip, #349\n\t\tif (allowMove) {\n\t\t\ttooltip.refresh(tooltipPoints);\n\n\t\t// Full reset\n\t\t} else {\n\n\t\t\tif (hoverPoint) {\n\t\t\t\thoverPoint.onMouseOut();\n\t\t\t}\n\n\t\t\tif (hoverSeries) {\n\t\t\t\thoverSeries.onMouseOut();\n\t\t\t}\n\n\t\t\tif (tooltip) {\n\t\t\t\ttooltip.hide();\n\t\t\t\ttooltip.hideCrosshairs();\n\t\t\t}\n\n\t\t\tpointer.hoverX = null;\n\n\t\t}\n\t},\n\n\t/**\n\t * Scale series groups to a certain scale and translation\n\t */\n\tscaleGroups: function (attribs, clip) {\n\n\t\tvar chart = this.chart,\n\t\t\tseriesAttribs;\n\n\t\t// Scale each series\n\t\teach(chart.series, function (series) {\n\t\t\tseriesAttribs = attribs || series.getPlotBox(); // #1701\n\t\t\tif (series.xAxis && series.xAxis.zoomEnabled) {\n\t\t\t\tseries.group.attr(seriesAttribs);\n\t\t\t\tif (series.markerGroup) {\n\t\t\t\t\tseries.markerGroup.attr(seriesAttribs);\n\t\t\t\t\tseries.markerGroup.clip(clip ? chart.clipRect : null);\n\t\t\t\t}\n\t\t\t\tif (series.dataLabelsGroup) {\n\t\t\t\t\tseries.dataLabelsGroup.attr(seriesAttribs);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t\t\n\t\t// Clip\n\t\tchart.clipRect.attr(clip || chart.clipBox);\n\t},\n\n\t/**\n\t * Run translation operations for each direction (horizontal and vertical) independently\n\t */\n\tpinchTranslateDirection: function (horiz, pinchDown, touches, transform, selectionMarker, clip, lastValidTouch) {\n\t\tvar chart = this.chart,\n\t\t\txy = horiz ? 'x' : 'y',\n\t\t\tXY = horiz ? 'X' : 'Y',\n\t\t\tsChartXY = 'chart' + XY,\n\t\t\twh = horiz ? 'width' : 'height',\n\t\t\tplotLeftTop = chart['plot' + (horiz ? 'Left' : 'Top')],\n\t\t\tselectionWH,\n\t\t\tselectionXY,\n\t\t\tclipXY,\n\t\t\tscale = 1,\n\t\t\tinverted = chart.inverted,\n\t\t\tbounds = chart.bounds[horiz ? 'h' : 'v'],\n\t\t\tsingleTouch = pinchDown.length === 1,\n\t\t\ttouch0Start = pinchDown[0][sChartXY],\n\t\t\ttouch0Now = touches[0][sChartXY],\n\t\t\ttouch1Start = !singleTouch && pinchDown[1][sChartXY],\n\t\t\ttouch1Now = !singleTouch && touches[1][sChartXY],\n\t\t\toutOfBounds,\n\t\t\ttransformScale,\n\t\t\tscaleKey,\n\t\t\tsetScale = function () {\n\t\t\t\tif (!singleTouch && mathAbs(touch0Start - touch1Start) > 20) { // Don't zoom if fingers are too close on this axis\n\t\t\t\t\tscale = mathAbs(touch0Now - touch1Now) / mathAbs(touch0Start - touch1Start);\t\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tclipXY = ((plotLeftTop - touch0Now) / scale) + touch0Start;\n\t\t\t\tselectionWH = chart['plot' + (horiz ? 'Width' : 'Height')] / scale;\n\t\t\t};\n\n\t\t// Set the scale, first pass\n\t\tsetScale();\n\n\t\tselectionXY = clipXY; // the clip position (x or y) is altered if out of bounds, the selection position is not\n\n\t\t// Out of bounds\n\t\tif (selectionXY < bounds.min) {\n\t\t\tselectionXY = bounds.min;\n\t\t\toutOfBounds = true;\n\t\t} else if (selectionXY + selectionWH > bounds.max) {\n\t\t\tselectionXY = bounds.max - selectionWH;\n\t\t\toutOfBounds = true;\n\t\t}\n\t\t\n\t\t// Is the chart dragged off its bounds, determined by dataMin and dataMax?\n\t\tif (outOfBounds) {\n\n\t\t\t// Modify the touchNow position in order to create an elastic drag movement. This indicates\n\t\t\t// to the user that the chart is responsive but can't be dragged further.\n\t\t\ttouch0Now -= 0.8 * (touch0Now - lastValidTouch[xy][0]);\n\t\t\tif (!singleTouch) {\n\t\t\t\ttouch1Now -= 0.8 * (touch1Now - lastValidTouch[xy][1]);\n\t\t\t}\n\n\t\t\t// Set the scale, second pass to adapt to the modified touchNow positions\n\t\t\tsetScale();\n\n\t\t} else {\n\t\t\tlastValidTouch[xy] = [touch0Now, touch1Now];\n\t\t}\n\n\t\t\n\t\t// Set geometry for clipping, selection and transformation\n\t\tif (!inverted) { // TODO: implement clipping for inverted charts\n\t\t\tclip[xy] = clipXY - plotLeftTop;\n\t\t\tclip[wh] = selectionWH;\n\t\t}\n\t\tscaleKey = inverted ? (horiz ? 'scaleY' : 'scaleX') : 'scale' + XY;\n\t\ttransformScale = inverted ? 1 / scale : scale;\n\n\t\tselectionMarker[wh] = selectionWH;\n\t\tselectionMarker[xy] = selectionXY;\n\t\ttransform[scaleKey] = scale;\n\t\ttransform['translate' + XY] = (transformScale * plotLeftTop) + (touch0Now - (transformScale * touch0Start));\n\t},\n\t\n\t/**\n\t * Handle touch events with two touches\n\t */\n\tpinch: function (e) {\n\n\t\tvar self = this,\n\t\t\tchart = self.chart,\n\t\t\tpinchDown = self.pinchDown,\n\t\t\tfollowTouchMove = chart.tooltip && chart.tooltip.options.followTouchMove,\n\t\t\ttouches = e.touches,\n\t\t\ttouchesLength = touches.length,\n\t\t\tlastValidTouch = self.lastValidTouch,\n\t\t\tzoomHor = self.zoomHor || self.pinchHor,\n\t\t\tzoomVert = self.zoomVert || self.pinchVert,\n\t\t\thasZoom = zoomHor || zoomVert,\n\t\t\tselectionMarker = self.selectionMarker,\n\t\t\ttransform = {},\n\t\t\tfireClickEvent = touchesLength === 1 && ((self.inClass(e.target, PREFIX + 'tracker') && \n\t\t\t\tchart.runTrackerClick) || chart.runChartClick),\n\t\t\tclip = {};\n\n\t\t// On touch devices, only proceed to trigger click if a handler is defined\n\t\tif ((hasZoom || followTouchMove) && !fireClickEvent) {\n\t\t\te.preventDefault();\n\t\t}\n\t\t\n\t\t// Normalize each touch\n\t\tmap(touches, function (e) {\n\t\t\treturn self.normalize(e);\n\t\t});\n\t\t\t\n\t\t// Register the touch start position\n\t\tif (e.type === 'touchstart') {\n\t\t\teach(touches, function (e, i) {\n\t\t\t\tpinchDown[i] = { chartX: e.chartX, chartY: e.chartY };\n\t\t\t});\n\t\t\tlastValidTouch.x = [pinchDown[0].chartX, pinchDown[1] && pinchDown[1].chartX];\n\t\t\tlastValidTouch.y = [pinchDown[0].chartY, pinchDown[1] && pinchDown[1].chartY];\n\n\t\t\t// Identify the data bounds in pixels\n\t\t\teach(chart.axes, function (axis) {\n\t\t\t\tif (axis.zoomEnabled) {\n\t\t\t\t\tvar bounds = chart.bounds[axis.horiz ? 'h' : 'v'],\n\t\t\t\t\t\tminPixelPadding = axis.minPixelPadding,\n\t\t\t\t\t\tmin = axis.toPixels(axis.dataMin),\n\t\t\t\t\t\tmax = axis.toPixels(axis.dataMax),\n\t\t\t\t\t\tabsMin = mathMin(min, max),\n\t\t\t\t\t\tabsMax = mathMax(min, max);\n\n\t\t\t\t\t// Store the bounds for use in the touchmove handler\n\t\t\t\t\tbounds.min = mathMin(axis.pos, absMin - minPixelPadding);\n\t\t\t\t\tbounds.max = mathMax(axis.pos + axis.len, absMax + minPixelPadding);\n\t\t\t\t}\n\t\t\t});\n\t\t\n\t\t// Event type is touchmove, handle panning and pinching\n\t\t} else if (pinchDown.length) { // can be 0 when releasing, if touchend fires first\n\t\t\t\n\n\t\t\t// Set the marker\n\t\t\tif (!selectionMarker) {\n\t\t\t\tself.selectionMarker = selectionMarker = extend({\n\t\t\t\t\tdestroy: noop\n\t\t\t\t}, chart.plotBox);\n\t\t\t}\n\n\t\t\t\n\n\t\t\tif (zoomHor) {\n\t\t\t\tself.pinchTranslateDirection(true, pinchDown, touches, transform, selectionMarker, clip, lastValidTouch);\n\t\t\t}\n\t\t\tif (zoomVert) {\n\t\t\t\tself.pinchTranslateDirection(false, pinchDown, touches, transform, selectionMarker, clip, lastValidTouch);\n\t\t\t}\n\n\t\t\tself.hasPinched = hasZoom;\n\n\t\t\t// Scale and translate the groups to provide visual feedback during pinching\n\t\t\tself.scaleGroups(transform, clip);\n\t\t\t\n\t\t\t// Optionally move the tooltip on touchmove\n\t\t\tif (!hasZoom && followTouchMove && touchesLength === 1) {\n\t\t\t\tthis.runPointActions(self.normalize(e));\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Start a drag operation\n\t */\n\tdragStart: function (e) {\n\t\tvar chart = this.chart;\n\n\t\t// Record the start position\n\t\tchart.mouseIsDown = e.type;\n\t\tchart.cancelClick = false;\n\t\tchart.mouseDownX = this.mouseDownX = e.chartX;\n\t\tchart.mouseDownY = this.mouseDownY = e.chartY;\n\t},\n\n\t/**\n\t * Perform a drag operation in response to a mousemove event while the mouse is down\n\t */\n\tdrag: function (e) {\n\n\t\tvar chart = this.chart,\n\t\t\tchartOptions = chart.options.chart,\n\t\t\tchartX = e.chartX,\n\t\t\tchartY = e.chartY,\n\t\t\tzoomHor = this.zoomHor,\n\t\t\tzoomVert = this.zoomVert,\n\t\t\tplotLeft = chart.plotLeft,\n\t\t\tplotTop = chart.plotTop,\n\t\t\tplotWidth = chart.plotWidth,\n\t\t\tplotHeight = chart.plotHeight,\n\t\t\tclickedInside,\n\t\t\tsize,\n\t\t\tmouseDownX = this.mouseDownX,\n\t\t\tmouseDownY = this.mouseDownY;\n\n\t\t// If the mouse is outside the plot area, adjust to cooordinates\n\t\t// inside to prevent the selection marker from going outside\n\t\tif (chartX < plotLeft) {\n\t\t\tchartX = plotLeft;\n\t\t} else if (chartX > plotLeft + plotWidth) {\n\t\t\tchartX = plotLeft + plotWidth;\n\t\t}\n\n\t\tif (chartY < plotTop) {\n\t\t\tchartY = plotTop;\n\t\t} else if (chartY > plotTop + plotHeight) {\n\t\t\tchartY = plotTop + plotHeight;\n\t\t}\n\t\t\n\t\t// determine if the mouse has moved more than 10px\n\t\tthis.hasDragged = Math.sqrt(\n\t\t\tMath.pow(mouseDownX - chartX, 2) +\n\t\t\tMath.pow(mouseDownY - chartY, 2)\n\t\t);\n\t\tif (this.hasDragged > 10) {\n\t\t\tclickedInside = chart.isInsidePlot(mouseDownX - plotLeft, mouseDownY - plotTop);\n\n\t\t\t// make a selection\n\t\t\tif (chart.hasCartesianSeries && (this.zoomX || this.zoomY) && clickedInside) {\n\t\t\t\tif (!this.selectionMarker) {\n\t\t\t\t\tthis.selectionMarker = chart.renderer.rect(\n\t\t\t\t\t\tplotLeft,\n\t\t\t\t\t\tplotTop,\n\t\t\t\t\t\tzoomHor ? 1 : plotWidth,\n\t\t\t\t\t\tzoomVert ? 1 : plotHeight,\n\t\t\t\t\t\t0\n\t\t\t\t\t)\n\t\t\t\t\t.attr({\n\t\t\t\t\t\tfill: chartOptions.selectionMarkerFill || 'rgba(69,114,167,0.25)',\n\t\t\t\t\t\tzIndex: 7\n\t\t\t\t\t})\n\t\t\t\t\t.add();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// adjust the width of the selection marker\n\t\t\tif (this.selectionMarker && zoomHor) {\n\t\t\t\tsize = chartX - mouseDownX;\n\t\t\t\tthis.selectionMarker.attr({\n\t\t\t\t\twidth: mathAbs(size),\n\t\t\t\t\tx: (size > 0 ? 0 : size) + mouseDownX\n\t\t\t\t});\n\t\t\t}\n\t\t\t// adjust the height of the selection marker\n\t\t\tif (this.selectionMarker && zoomVert) {\n\t\t\t\tsize = chartY - mouseDownY;\n\t\t\t\tthis.selectionMarker.attr({\n\t\t\t\t\theight: mathAbs(size),\n\t\t\t\t\ty: (size > 0 ? 0 : size) + mouseDownY\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// panning\n\t\t\tif (clickedInside && !this.selectionMarker && chartOptions.panning) {\n\t\t\t\tchart.pan(e, chartOptions.panning);\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * On mouse up or touch end across the entire document, drop the selection.\n\t */\n\tdrop: function (e) {\n\t\tvar chart = this.chart,\n\t\t\thasPinched = this.hasPinched;\n\n\t\tif (this.selectionMarker) {\n\t\t\tvar selectionData = {\n\t\t\t\t\txAxis: [],\n\t\t\t\t\tyAxis: [],\n\t\t\t\t\toriginalEvent: e.originalEvent || e\n\t\t\t\t},\n\t\t\t\tselectionBox = this.selectionMarker,\n\t\t\t\tselectionLeft = selectionBox.x,\n\t\t\t\tselectionTop = selectionBox.y,\n\t\t\t\trunZoom;\n\t\t\t// a selection has been made\n\t\t\tif (this.hasDragged || hasPinched) {\n\n\t\t\t\t// record each axis' min and max\n\t\t\t\teach(chart.axes, function (axis) {\n\t\t\t\t\tif (axis.zoomEnabled) {\n\t\t\t\t\t\tvar horiz = axis.horiz,\n\t\t\t\t\t\t\tselectionMin = axis.toValue((horiz ? selectionLeft : selectionTop)),\n\t\t\t\t\t\t\tselectionMax = axis.toValue((horiz ? selectionLeft + selectionBox.width : selectionTop + selectionBox.height));\n\n\t\t\t\t\t\tif (!isNaN(selectionMin) && !isNaN(selectionMax)) { // #859\n\t\t\t\t\t\t\tselectionData[axis.xOrY + 'Axis'].push({\n\t\t\t\t\t\t\t\taxis: axis,\n\t\t\t\t\t\t\t\tmin: mathMin(selectionMin, selectionMax), // for reversed axes,\n\t\t\t\t\t\t\t\tmax: mathMax(selectionMin, selectionMax)\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\trunZoom = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t\tif (runZoom) {\n\t\t\t\t\tfireEvent(chart, 'selection', selectionData, function (args) { \n\t\t\t\t\t\tchart.zoom(extend(args, hasPinched ? { animation: false } : null)); \n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t}\n\t\t\tthis.selectionMarker = this.selectionMarker.destroy();\n\n\t\t\t// Reset scaling preview\n\t\t\tif (hasPinched) {\n\t\t\t\tthis.scaleGroups();\n\t\t\t}\n\t\t}\n\n\t\t// Reset all\n\t\tif (chart) { // it may be destroyed on mouse up - #877\n\t\t\tcss(chart.container, { cursor: chart._cursor });\n\t\t\tchart.cancelClick = this.hasDragged > 10; // #370\n\t\t\tchart.mouseIsDown = this.hasDragged = this.hasPinched = false;\n\t\t\tthis.pinchDown = [];\n\t\t}\n\t},\n\n\tonContainerMouseDown: function (e) {\n\n\t\te = this.normalize(e);\n\n\t\t// issue #295, dragging not always working in Firefox\n\t\tif (e.preventDefault) {\n\t\t\te.preventDefault();\n\t\t}\n\t\t\n\t\tthis.dragStart(e);\n\t},\n\n\t\n\n\tonDocumentMouseUp: function (e) {\n\t\tthis.drop(e);\n\t},\n\n\t/**\n\t * Special handler for mouse move that will hide the tooltip when the mouse leaves the plotarea.\n\t * Issue #149 workaround. The mouseleave event does not always fire. \n\t */\n\tonDocumentMouseMove: function (e) {\n\t\tvar chart = this.chart,\n\t\t\tchartPosition = this.chartPosition,\n\t\t\thoverSeries = chart.hoverSeries;\n\n\t\te = this.normalize(e, chartPosition);\n\n\t\t// If we're outside, hide the tooltip\n\t\tif (chartPosition && hoverSeries && !this.inClass(e.target, 'highcharts-tracker') &&\n\t\t\t\t!chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) {\n\t\t\tthis.reset();\n\t\t}\n\t},\n\n\t/**\n\t * When mouse leaves the container, hide the tooltip.\n\t */\n\tonContainerMouseLeave: function () {\n\t\tthis.reset();\n\t\tthis.chartPosition = null; // also reset the chart position, used in #149 fix\n\t},\n\n\t// The mousemove, touchmove and touchstart event handler\n\tonContainerMouseMove: function (e) {\n\n\t\tvar chart = this.chart;\n\n\t\t// normalize\n\t\te = this.normalize(e);\n\n\t\t// #295\n\t\te.returnValue = false;\n\t\t\n\t\t\n\t\tif (chart.mouseIsDown === 'mousedown') {\n\t\t\tthis.drag(e);\n\t\t} \n\t\t\n\t\t// Show the tooltip and run mouse over events (#977)\n\t\tif ((this.inClass(e.target, 'highcharts-tracker') || \n\t\t\t\tchart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) && !chart.openMenu) {\n\t\t\tthis.runPointActions(e);\n\t\t}\n\t},\n\n\t/**\n\t * Utility to detect whether an element has, or has a parent with, a specific\n\t * class name. Used on detection of tracker objects and on deciding whether\n\t * hovering the tooltip should cause the active series to mouse out.\n\t */\n\tinClass: function (element, className) {\n\t\tvar elemClassName;\n\t\twhile (element) {\n\t\t\telemClassName = attr(element, 'class');\n\t\t\tif (elemClassName) {\n\t\t\t\tif (elemClassName.indexOf(className) !== -1) {\n\t\t\t\t\treturn true;\n\t\t\t\t} else if (elemClassName.indexOf(PREFIX + 'container') !== -1) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\telement = element.parentNode;\n\t\t}\t\t\n\t},\n\n\tonTrackerMouseOut: function (e) {\n\t\tvar series = this.chart.hoverSeries;\n\t\tif (series && !series.options.stickyTracking && !this.inClass(e.toElement || e.relatedTarget, PREFIX + 'tooltip')) {\n\t\t\tseries.onMouseOut();\n\t\t}\n\t},\n\n\tonContainerClick: function (e) {\n\t\tvar chart = this.chart,\n\t\t\thoverPoint = chart.hoverPoint, \n\t\t\tplotLeft = chart.plotLeft,\n\t\t\tplotTop = chart.plotTop,\n\t\t\tinverted = chart.inverted,\n\t\t\tchartPosition,\n\t\t\tplotX,\n\t\t\tplotY;\n\t\t\n\t\te = this.normalize(e);\n\t\te.cancelBubble = true; // IE specific\n\n\t\tif (!chart.cancelClick) {\n\t\t\t\n\t\t\t// On tracker click, fire the series and point events. #783, #1583\n\t\t\tif (hoverPoint && this.inClass(e.target, PREFIX + 'tracker')) {\n\t\t\t\tchartPosition = this.chartPosition;\n\t\t\t\tplotX = hoverPoint.plotX;\n\t\t\t\tplotY = hoverPoint.plotY;\n\n\t\t\t\t// add page position info\n\t\t\t\textend(hoverPoint, {\n\t\t\t\t\tpageX: chartPosition.left + plotLeft +\n\t\t\t\t\t\t(inverted ? chart.plotWidth - plotY : plotX),\n\t\t\t\t\tpageY: chartPosition.top + plotTop +\n\t\t\t\t\t\t(inverted ? chart.plotHeight - plotX : plotY)\n\t\t\t\t});\n\t\t\t\n\t\t\t\t// the series click event\n\t\t\t\tfireEvent(hoverPoint.series, 'click', extend(e, {\n\t\t\t\t\tpoint: hoverPoint\n\t\t\t\t}));\n\n\t\t\t\t// the point click event\n\t\t\t\tif (chart.hoverPoint) { // it may be destroyed (#1844)\n\t\t\t\t\thoverPoint.firePointEvent('click', e);\n\t\t\t\t}\n\n\t\t\t// When clicking outside a tracker, fire a chart event\n\t\t\t} else {\n\t\t\t\textend(e, this.getCoordinates(e));\n\n\t\t\t\t// fire a click event in the chart\n\t\t\t\tif (chart.isInsidePlot(e.chartX - plotLeft, e.chartY - plotTop)) {\n\t\t\t\t\tfireEvent(chart, 'click', e);\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t}\n\t},\n\n\tonContainerTouchStart: function (e) {\n\t\tvar chart = this.chart;\n\n\t\tif (e.touches.length === 1) {\n\n\t\t\te = this.normalize(e);\n\n\t\t\tif (chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) {\n\n\t\t\t\t// Prevent the click pseudo event from firing unless it is set in the options\n\t\t\t\t/*if (!chart.runChartClick) {\n\t\t\t\t\te.preventDefault();\n\t\t\t\t}*/\n\t\t\t\n\t\t\t\t// Run mouse events and display tooltip etc\n\t\t\t\tthis.runPointActions(e);\n\n\t\t\t\tthis.pinch(e);\n\n\t\t\t} else {\n\t\t\t\t// Hide the tooltip on touching outside the plot area (#1203)\n\t\t\t\tthis.reset();\n\t\t\t}\n\n\t\t} else if (e.touches.length === 2) {\n\t\t\tthis.pinch(e);\n\t\t}\t\t\n\t},\n\n\tonContainerTouchMove: function (e) {\n\t\tif (e.touches.length === 1 || e.touches.length === 2) {\n\t\t\tthis.pinch(e);\n\t\t}\n\t},\n\n\tonDocumentTouchEnd: function (e) {\n\t\tthis.drop(e);\n\t},\n\n\t/**\n\t * Set the JS DOM events on the container and document. This method should contain\n\t * a one-to-one assignment between methods and their handlers. Any advanced logic should\n\t * be moved to the handler reflecting the event's name.\n\t */\n\tsetDOMEvents: function () {\n\n\t\tvar pointer = this,\n\t\t\tcontainer = pointer.chart.container,\n\t\t\tevents;\n\n\t\tthis._events = events = [\n\t\t\t[container, 'onmousedown', 'onContainerMouseDown'],\n\t\t\t[container, 'onmousemove', 'onContainerMouseMove'],\n\t\t\t[container, 'onclick', 'onContainerClick'],\n\t\t\t[container, 'mouseleave', 'onContainerMouseLeave'],\n\t\t\t[doc, 'mousemove', 'onDocumentMouseMove'],\n\t\t\t[doc, 'mouseup', 'onDocumentMouseUp']\n\t\t];\n\n\t\tif (hasTouch) {\n\t\t\tevents.push(\n\t\t\t\t[container, 'ontouchstart', 'onContainerTouchStart'],\n\t\t\t\t[container, 'ontouchmove', 'onContainerTouchMove'],\n\t\t\t\t[doc, 'touchend', 'onDocumentTouchEnd']\n\t\t\t);\n\t\t}\n\n\t\teach(events, function (eventConfig) {\n\n\t\t\t// First, create the callback function that in turn calls the method on Pointer\n\t\t\tpointer['_' + eventConfig[2]] = function (e) {\n\t\t\t\tpointer[eventConfig[2]](e);\n\t\t\t};\n\n\t\t\t// Now attach the function, either as a direct property or through addEvent\n\t\t\tif (eventConfig[1].indexOf('on') === 0) {\n\t\t\t\teventConfig[0][eventConfig[1]] = pointer['_' + eventConfig[2]];\n\t\t\t} else {\n\t\t\t\taddEvent(eventConfig[0], eventConfig[1], pointer['_' + eventConfig[2]]);\n\t\t\t}\n\t\t});\n\n\t\t\n\t},\n\n\t/**\n\t * Destroys the Pointer object and disconnects DOM events.\n\t */\n\tdestroy: function () {\n\t\tvar pointer = this;\n\n\t\t// Release all DOM events\n\t\teach(pointer._events, function (eventConfig) {\t\n\t\t\tif (eventConfig[1].indexOf('on') === 0) {\n\t\t\t\teventConfig[0][eventConfig[1]] = null; // delete breaks oldIE\n\t\t\t} else {\t\t\n\t\t\t\tremoveEvent(eventConfig[0], eventConfig[1], pointer['_' + eventConfig[2]]);\n\t\t\t}\n\t\t});\n\t\tdelete pointer._events;\n\n\t\t// memory and CPU leak\n\t\tclearInterval(pointer.tooltipTimeout);\n\t}\n};\n/**\n * The overview of the chart's series\n */\nfunction Legend(chart, options) {\n\tthis.init(chart, options);\n}\n\nLegend.prototype = {\n\t\n\t/**\n\t * Initialize the legend\n\t */\n\tinit: function (chart, options) {\n\t\t\n\t\tvar legend = this,\n\t\t\titemStyle = options.itemStyle,\n\t\t\tpadding = pick(options.padding, 8),\n\t\t\titemMarginTop = options.itemMarginTop || 0;\n\t\n\t\tthis.options = options;\n\n\t\tif (!options.enabled) {\n\t\t\treturn;\n\t\t}\n\t\n\t\tlegend.baseline = pInt(itemStyle.fontSize) + 3 + itemMarginTop; // used in Series prototype\n\t\tlegend.itemStyle = itemStyle;\n\t\tlegend.itemHiddenStyle = merge(itemStyle, options.itemHiddenStyle);\n\t\tlegend.itemMarginTop = itemMarginTop;\n\t\tlegend.padding = padding;\n\t\tlegend.initialItemX = padding;\n\t\tlegend.initialItemY = padding - 5; // 5 is the number of pixels above the text\n\t\tlegend.maxItemWidth = 0;\n\t\tlegend.chart = chart;\n\t\tlegend.itemHeight = 0;\n\t\tlegend.lastLineHeight = 0;\n\n\t\t// Render it\n\t\tlegend.render();\n\n\t\t// move checkboxes\n\t\taddEvent(legend.chart, 'endResize', function () { \n\t\t\tlegend.positionCheckboxes();\n\t\t});\n\n\t},\n\n\t/**\n\t * Set the colors for the legend item\n\t * @param {Object} item A Series or Point instance\n\t * @param {Object} visible Dimmed or colored\n\t */\n\tcolorizeItem: function (item, visible) {\n\t\tvar legend = this,\n\t\t\toptions = legend.options,\n\t\t\tlegendItem = item.legendItem,\n\t\t\tlegendLine = item.legendLine,\n\t\t\tlegendSymbol = item.legendSymbol,\n\t\t\thiddenColor = legend.itemHiddenStyle.color,\n\t\t\ttextColor = visible ? options.itemStyle.color : hiddenColor,\n\t\t\tsymbolColor = visible ? item.color : hiddenColor,\n\t\t\tmarkerOptions = item.options && item.options.marker,\n\t\t\tsymbolAttr = {\n\t\t\t\tstroke: symbolColor,\n\t\t\t\tfill: symbolColor\n\t\t\t},\n\t\t\tkey,\n\t\t\tval;\n\t\t\n\t\tif (legendItem) {\n\t\t\tlegendItem.css({ fill: textColor, color: textColor }); // color for #1553, oldIE\n\t\t}\n\t\tif (legendLine) {\n\t\t\tlegendLine.attr({ stroke: symbolColor });\n\t\t}\n\t\t\n\t\tif (legendSymbol) {\n\t\t\t\n\t\t\t// Apply marker options\n\t\t\tif (markerOptions && legendSymbol.isMarker) { // #585\n\t\t\t\tmarkerOptions = item.convertAttribs(markerOptions);\n\t\t\t\tfor (key in markerOptions) {\n\t\t\t\t\tval = markerOptions[key];\n\t\t\t\t\tif (val !== UNDEFINED) {\n\t\t\t\t\t\tsymbolAttr[key] = val;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tlegendSymbol.attr(symbolAttr);\n\t\t}\n\t},\n\n\t/**\n\t * Position the legend item\n\t * @param {Object} item A Series or Point instance\n\t */\n\tpositionItem: function (item) {\n\t\tvar legend = this,\n\t\t\toptions = legend.options,\n\t\t\tsymbolPadding = options.symbolPadding,\n\t\t\tltr = !options.rtl,\n\t\t\tlegendItemPos = item._legendItemPos,\n\t\t\titemX = legendItemPos[0],\n\t\t\titemY = legendItemPos[1],\n\t\t\tcheckbox = item.checkbox;\n\n\t\tif (item.legendGroup) {\n\t\t\titem.legendGroup.translate(\n\t\t\t\tltr ? itemX : legend.legendWidth - itemX - 2 * symbolPadding - 4,\n\t\t\t\titemY\n\t\t\t);\n\t\t}\n\n\t\tif (checkbox) {\n\t\t\tcheckbox.x = itemX;\n\t\t\tcheckbox.y = itemY;\n\t\t}\n\t},\n\n\t/**\n\t * Destroy a single legend item\n\t * @param {Object} item The series or point\n\t */\n\tdestroyItem: function (item) {\n\t\tvar checkbox = item.checkbox;\n\n\t\t// destroy SVG elements\n\t\teach(['legendItem', 'legendLine', 'legendSymbol', 'legendGroup'], function (key) {\n\t\t\tif (item[key]) {\n\t\t\t\titem[key] = item[key].destroy();\n\t\t\t}\n\t\t});\n\n\t\tif (checkbox) {\n\t\t\tdiscardElement(item.checkbox);\n\t\t}\n\t},\n\n\t/**\n\t * Destroys the legend.\n\t */\n\tdestroy: function () {\n\t\tvar legend = this,\n\t\t\tlegendGroup = legend.group,\n\t\t\tbox = legend.box;\n\n\t\tif (box) {\n\t\t\tlegend.box = box.destroy();\n\t\t}\n\n\t\tif (legendGroup) {\n\t\t\tlegend.group = legendGroup.destroy();\n\t\t}\n\t},\n\n\t/**\n\t * Position the checkboxes after the width is determined\n\t */\n\tpositionCheckboxes: function (scrollOffset) {\n\t\tvar alignAttr = this.group.alignAttr,\n\t\t\ttranslateY,\n\t\t\tclipHeight = this.clipHeight || this.legendHeight;\n\n\t\tif (alignAttr) {\n\t\t\ttranslateY = alignAttr.translateY;\n\t\t\teach(this.allItems, function (item) {\n\t\t\t\tvar checkbox = item.checkbox,\n\t\t\t\t\ttop;\n\t\t\t\t\n\t\t\t\tif (checkbox) {\n\t\t\t\t\ttop = (translateY + checkbox.y + (scrollOffset || 0) + 3);\n\t\t\t\t\tcss(checkbox, {\n\t\t\t\t\t\tleft: (alignAttr.translateX + item.legendItemWidth + checkbox.x - 20) + PX,\n\t\t\t\t\t\ttop: top + PX,\n\t\t\t\t\t\tdisplay: top > translateY - 6 && top < translateY + clipHeight - 6 ? '' : NONE\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t},\n\t\n\t/**\n\t * Render the legend title on top of the legend\n\t */\n\trenderTitle: function () {\n\t\tvar options = this.options,\n\t\t\tpadding = this.padding,\n\t\t\ttitleOptions = options.title,\n\t\t\ttitleHeight = 0,\n\t\t\tbBox;\n\t\t\n\t\tif (titleOptions.text) {\n\t\t\tif (!this.title) {\n\t\t\t\tthis.title = this.chart.renderer.label(titleOptions.text, padding - 3, padding - 4, null, null, null, null, null, 'legend-title')\n\t\t\t\t\t.attr({ zIndex: 1 })\n\t\t\t\t\t.css(titleOptions.style)\n\t\t\t\t\t.add(this.group);\n\t\t\t}\n\t\t\tbBox = this.title.getBBox();\n\t\t\ttitleHeight = bBox.height;\n\t\t\tthis.offsetWidth = bBox.width; // #1717\n\t\t\tthis.contentGroup.attr({ translateY: titleHeight });\n\t\t}\n\t\tthis.titleHeight = titleHeight;\n\t},\n\n\t/**\n\t * Render a single specific legend item\n\t * @param {Object} item A series or point\n\t */\n\trenderItem: function (item) {\n\t\tvar legend = this,\n\t\t\tchart = legend.chart,\n\t\t\trenderer = chart.renderer,\n\t\t\toptions = legend.options,\n\t\t\thorizontal = options.layout === 'horizontal',\n\t\t\tsymbolWidth = options.symbolWidth,\n\t\t\tsymbolPadding = options.symbolPadding,\n\t\t\titemStyle = legend.itemStyle,\n\t\t\titemHiddenStyle = legend.itemHiddenStyle,\n\t\t\tpadding = legend.padding,\n\t\t\titemDistance = horizontal ? pick(options.itemDistance, 8) : 0,\n\t\t\tltr = !options.rtl,\n\t\t\titemHeight,\n\t\t\twidthOption = options.width,\n\t\t\titemMarginBottom = options.itemMarginBottom || 0,\n\t\t\titemMarginTop = legend.itemMarginTop,\n\t\t\tinitialItemX = legend.initialItemX,\n\t\t\tbBox,\n\t\t\titemWidth,\n\t\t\tli = item.legendItem,\n\t\t\tseries = item.series || item,\n\t\t\titemOptions = series.options,\n\t\t\tshowCheckbox = itemOptions.showCheckbox,\n\t\t\tuseHTML = options.useHTML;\n\n\t\tif (!li) { // generate it once, later move it\n\n\t\t\t// Generate the group box\n\t\t\t// A group to hold the symbol and text. Text is to be appended in Legend class.\n\t\t\titem.legendGroup = renderer.g('legend-item')\n\t\t\t\t.attr({ zIndex: 1 })\n\t\t\t\t.add(legend.scrollGroup);\n\n\t\t\t// Draw the legend symbol inside the group box\n\t\t\tseries.drawLegendSymbol(legend, item);\n\n\t\t\t// Generate the list item text and add it to the group\n\t\t\titem.legendItem = li = renderer.text(\n\t\t\t\t\toptions.labelFormat ? format(options.labelFormat, item) : options.labelFormatter.call(item),\n\t\t\t\t\tltr ? symbolWidth + symbolPadding : -symbolPadding,\n\t\t\t\t\tlegend.baseline,\n\t\t\t\t\tuseHTML\n\t\t\t\t)\n\t\t\t\t.css(merge(item.visible ? itemStyle : itemHiddenStyle)) // merge to prevent modifying original (#1021)\n\t\t\t\t.attr({\n\t\t\t\t\talign: ltr ? 'left' : 'right',\n\t\t\t\t\tzIndex: 2\n\t\t\t\t})\n\t\t\t\t.add(item.legendGroup);\n\n\t\t\t// Set the events on the item group, or in case of useHTML, the item itself (#1249)\n\t\t\t(useHTML ? li : item.legendGroup).on('mouseover', function () {\n\t\t\t\t\titem.setState(HOVER_STATE);\n\t\t\t\t\tli.css(legend.options.itemHoverStyle);\n\t\t\t\t})\n\t\t\t\t.on('mouseout', function () {\n\t\t\t\t\tli.css(item.visible ? itemStyle : itemHiddenStyle);\n\t\t\t\t\titem.setState();\n\t\t\t\t})\n\t\t\t\t.on('click', function (event) {\n\t\t\t\t\tvar strLegendItemClick = 'legendItemClick',\n\t\t\t\t\t\tfnLegendItemClick = function () {\n\t\t\t\t\t\t\titem.setVisible();\n\t\t\t\t\t\t};\n\t\t\t\t\t\t\n\t\t\t\t\t// Pass over the click/touch event. #4.\n\t\t\t\t\tevent = {\n\t\t\t\t\t\tbrowserEvent: event\n\t\t\t\t\t};\n\n\t\t\t\t\t// click the name or symbol\n\t\t\t\t\tif (item.firePointEvent) { // point\n\t\t\t\t\t\titem.firePointEvent(strLegendItemClick, event, fnLegendItemClick);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfireEvent(item, strLegendItemClick, event, fnLegendItemClick);\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t// Colorize the items\n\t\t\tlegend.colorizeItem(item, item.visible);\n\n\t\t\t// add the HTML checkbox on top\n\t\t\tif (itemOptions && showCheckbox) {\n\t\t\t\titem.checkbox = createElement('input', {\n\t\t\t\t\ttype: 'checkbox',\n\t\t\t\t\tchecked: item.selected,\n\t\t\t\t\tdefaultChecked: item.selected // required by IE7\n\t\t\t\t}, options.itemCheckboxStyle, chart.container);\n\n\t\t\t\taddEvent(item.checkbox, 'click', function (event) {\n\t\t\t\t\tvar target = event.target;\n\t\t\t\t\tfireEvent(item, 'checkboxClick', {\n\t\t\t\t\t\t\tchecked: target.checked\n\t\t\t\t\t\t},\n\t\t\t\t\t\tfunction () {\n\t\t\t\t\t\t\titem.select();\n\t\t\t\t\t\t}\n\t\t\t\t\t);\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\t// calculate the positions for the next line\n\t\tbBox = li.getBBox();\n\n\t\titemWidth = item.legendItemWidth =\n\t\t\toptions.itemWidth || symbolWidth + symbolPadding + bBox.width + itemDistance +\n\t\t\t(showCheckbox ? 20 : 0);\n\t\tlegend.itemHeight = itemHeight = bBox.height;\n\n\t\t// if the item exceeds the width, start a new line\n\t\tif (horizontal && legend.itemX - initialItemX + itemWidth >\n\t\t\t\t(widthOption || (chart.chartWidth - 2 * padding - initialItemX))) {\n\t\t\tlegend.itemX = initialItemX;\n\t\t\tlegend.itemY += itemMarginTop + legend.lastLineHeight + itemMarginBottom;\n\t\t\tlegend.lastLineHeight = 0; // reset for next line\n\t\t}\n\n\t\t// If the item exceeds the height, start a new column\n\t\t/*if (!horizontal && legend.itemY + options.y + itemHeight > chart.chartHeight - spacingTop - spacingBottom) {\n\t\t\tlegend.itemY = legend.initialItemY;\n\t\t\tlegend.itemX += legend.maxItemWidth;\n\t\t\tlegend.maxItemWidth = 0;\n\t\t}*/\n\n\t\t// Set the edge positions\n\t\tlegend.maxItemWidth = mathMax(legend.maxItemWidth, itemWidth);\n\t\tlegend.lastItemY = itemMarginTop + legend.itemY + itemMarginBottom;\n\t\tlegend.lastLineHeight = mathMax(itemHeight, legend.lastLineHeight); // #915\n\n\t\t// cache the position of the newly generated or reordered items\n\t\titem._legendItemPos = [legend.itemX, legend.itemY];\n\n\t\t// advance\n\t\tif (horizontal) {\n\t\t\tlegend.itemX += itemWidth;\n\n\t\t} else {\n\t\t\tlegend.itemY += itemMarginTop + itemHeight + itemMarginBottom;\n\t\t\tlegend.lastLineHeight = itemHeight;\n\t\t}\n\n\t\t// the width of the widest item\n\t\tlegend.offsetWidth = widthOption || mathMax(\n\t\t\t(horizontal ? legend.itemX - initialItemX - itemDistance : itemWidth) + padding,\n\t\t\tlegend.offsetWidth\n\t\t);\n\t},\n\n\t/**\n\t * Render the legend. This method can be called both before and after\n\t * chart.render. If called after, it will only rearrange items instead\n\t * of creating new ones.\n\t */\n\trender: function () {\n\t\tvar legend = this,\n\t\t\tchart = legend.chart,\n\t\t\trenderer = chart.renderer,\n\t\t\tlegendGroup = legend.group,\n\t\t\tallItems,\n\t\t\tdisplay,\n\t\t\tlegendWidth,\n\t\t\tlegendHeight,\n\t\t\tbox = legend.box,\n\t\t\toptions = legend.options,\n\t\t\tpadding = legend.padding,\n\t\t\tlegendBorderWidth = options.borderWidth,\n\t\t\tlegendBackgroundColor = options.backgroundColor;\n\n\t\tlegend.itemX = legend.initialItemX;\n\t\tlegend.itemY = legend.initialItemY;\n\t\tlegend.offsetWidth = 0;\n\t\tlegend.lastItemY = 0;\n\n\t\tif (!legendGroup) {\n\t\t\tlegend.group = legendGroup = renderer.g('legend')\n\t\t\t\t.attr({ zIndex: 7 }) \n\t\t\t\t.add();\n\t\t\tlegend.contentGroup = renderer.g()\n\t\t\t\t.attr({ zIndex: 1 }) // above background\n\t\t\t\t.add(legendGroup);\n\t\t\tlegend.scrollGroup = renderer.g()\n\t\t\t\t.add(legend.contentGroup);\n\t\t}\n\t\t\n\t\tlegend.renderTitle();\n\n\t\t// add each series or point\n\t\tallItems = [];\n\t\teach(chart.series, function (serie) {\n\t\t\tvar seriesOptions = serie.options;\n\n\t\t\tif (!seriesOptions.showInLegend || defined(seriesOptions.linkedTo)) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// use points or series for the legend item depending on legendType\n\t\t\tallItems = allItems.concat(\n\t\t\t\t\tserie.legendItems ||\n\t\t\t\t\t(seriesOptions.legendType === 'point' ?\n\t\t\t\t\t\t\tserie.data :\n\t\t\t\t\t\t\tserie)\n\t\t\t);\n\t\t});\n\n\t\t// sort by legendIndex\n\t\tstableSort(allItems, function (a, b) {\n\t\t\treturn ((a.options && a.options.legendIndex) || 0) - ((b.options && b.options.legendIndex) || 0);\n\t\t});\n\n\t\t// reversed legend\n\t\tif (options.reversed) {\n\t\t\tallItems.reverse();\n\t\t}\n\n\t\tlegend.allItems = allItems;\n\t\tlegend.display = display = !!allItems.length;\n\n\t\t// render the items\n\t\teach(allItems, function (item) {\n\t\t\tlegend.renderItem(item); \n\t\t});\n\n\t\t// Draw the border\n\t\tlegendWidth = options.width || legend.offsetWidth;\n\t\tlegendHeight = legend.lastItemY + legend.lastLineHeight + legend.titleHeight;\n\t\t\n\t\t\n\t\tlegendHeight = legend.handleOverflow(legendHeight);\n\n\t\tif (legendBorderWidth || legendBackgroundColor) {\n\t\t\tlegendWidth += padding;\n\t\t\tlegendHeight += padding;\n\n\t\t\tif (!box) {\n\t\t\t\tlegend.box = box = renderer.rect(\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\tlegendWidth,\n\t\t\t\t\tlegendHeight,\n\t\t\t\t\toptions.borderRadius,\n\t\t\t\t\tlegendBorderWidth || 0\n\t\t\t\t).attr({\n\t\t\t\t\tstroke: options.borderColor,\n\t\t\t\t\t'stroke-width': legendBorderWidth || 0,\n\t\t\t\t\tfill: legendBackgroundColor || NONE\n\t\t\t\t})\n\t\t\t\t.add(legendGroup)\n\t\t\t\t.shadow(options.shadow);\n\t\t\t\tbox.isNew = true;\n\n\t\t\t} else if (legendWidth > 0 && legendHeight > 0) {\n\t\t\t\tbox[box.isNew ? 'attr' : 'animate'](\n\t\t\t\t\tbox.crisp(null, null, null, legendWidth, legendHeight)\n\t\t\t\t);\n\t\t\t\tbox.isNew = false;\n\t\t\t}\n\n\t\t\t// hide the border if no items\n\t\t\tbox[display ? 'show' : 'hide']();\n\t\t}\n\t\t\n\t\tlegend.legendWidth = legendWidth;\n\t\tlegend.legendHeight = legendHeight;\n\n\t\t// Now that the legend width and height are established, put the items in the \n\t\t// final position\n\t\teach(allItems, function (item) {\n\t\t\tlegend.positionItem(item);\n\t\t});\n\n\t\t// 1.x compatibility: positioning based on style\n\t\t/*var props = ['left', 'right', 'top', 'bottom'],\n\t\t\tprop,\n\t\t\ti = 4;\n\t\twhile (i--) {\n\t\t\tprop = props[i];\n\t\t\tif (options.style[prop] && options.style[prop] !== 'auto') {\n\t\t\t\toptions[i < 2 ? 'align' : 'verticalAlign'] = prop;\n\t\t\t\toptions[i < 2 ? 'x' : 'y'] = pInt(options.style[prop]) * (i % 2 ? -1 : 1);\n\t\t\t}\n\t\t}*/\n\n\t\tif (display) {\n\t\t\tlegendGroup.align(extend({\n\t\t\t\twidth: legendWidth,\n\t\t\t\theight: legendHeight\n\t\t\t}, options), true, 'spacingBox');\n\t\t}\n\n\t\tif (!chart.isResizing) {\n\t\t\tthis.positionCheckboxes();\n\t\t}\n\t},\n\t\n\t/**\n\t * Set up the overflow handling by adding navigation with up and down arrows below the\n\t * legend.\n\t */\n\thandleOverflow: function (legendHeight) {\n\t\tvar legend = this,\n\t\t\tchart = this.chart,\n\t\t\trenderer = chart.renderer,\n\t\t\tpageCount,\n\t\t\toptions = this.options,\n\t\t\toptionsY = options.y,\n\t\t\talignTop = options.verticalAlign === 'top',\n\t\t\tspaceHeight = chart.spacingBox.height + (alignTop ? -optionsY : optionsY) - this.padding,\n\t\t\tmaxHeight = options.maxHeight,\n\t\t\tclipHeight,\n\t\t\tclipRect = this.clipRect,\n\t\t\tnavOptions = options.navigation,\n\t\t\tanimation = pick(navOptions.animation, true),\n\t\t\tarrowSize = navOptions.arrowSize || 12,\n\t\t\tnav = this.nav;\n\t\t\t\n\t\t// Adjust the height\n\t\tif (options.layout === 'horizontal') {\n\t\t\tspaceHeight /= 2;\n\t\t}\n\t\tif (maxHeight) {\n\t\t\tspaceHeight = mathMin(spaceHeight, maxHeight);\n\t\t}\n\t\t\n\t\t// Reset the legend height and adjust the clipping rectangle\n\t\tif (legendHeight > spaceHeight && !options.useHTML) {\n\n\t\t\tthis.clipHeight = clipHeight = spaceHeight - 20 - this.titleHeight;\n\t\t\tthis.pageCount = pageCount = mathCeil(legendHeight / clipHeight);\n\t\t\tthis.currentPage = pick(this.currentPage, 1);\n\t\t\tthis.fullHeight = legendHeight;\n\t\t\t\n\t\t\t// Only apply clipping if needed. Clipping causes blurred legend in PDF export (#1787)\n\t\t\tif (!clipRect) {\n\t\t\t\tclipRect = legend.clipRect = renderer.clipRect(0, 0, 9999, 0);\n\t\t\t\tlegend.contentGroup.clip(clipRect);\n\t\t\t}\n\t\t\tclipRect.attr({\n\t\t\t\theight: clipHeight\n\t\t\t});\n\t\t\t\n\t\t\t// Add navigation elements\n\t\t\tif (!nav) {\n\t\t\t\tthis.nav = nav = renderer.g().attr({ zIndex: 1 }).add(this.group);\n\t\t\t\tthis.up = renderer.symbol('triangle', 0, 0, arrowSize, arrowSize)\n\t\t\t\t\t.on('click', function () {\n\t\t\t\t\t\tlegend.scroll(-1, animation);\n\t\t\t\t\t})\n\t\t\t\t\t.add(nav);\n\t\t\t\tthis.pager = renderer.text('', 15, 10)\n\t\t\t\t\t.css(navOptions.style)\n\t\t\t\t\t.add(nav);\n\t\t\t\tthis.down = renderer.symbol('triangle-down', 0, 0, arrowSize, arrowSize)\n\t\t\t\t\t.on('click', function () {\n\t\t\t\t\t\tlegend.scroll(1, animation);\n\t\t\t\t\t})\n\t\t\t\t\t.add(nav);\n\t\t\t}\n\t\t\t\n\t\t\t// Set initial position\n\t\t\tlegend.scroll(0);\n\t\t\t\n\t\t\tlegendHeight = spaceHeight;\n\t\t\t\n\t\t} else if (nav) {\n\t\t\tclipRect.attr({\n\t\t\t\theight: chart.chartHeight\n\t\t\t});\n\t\t\tnav.hide();\n\t\t\tthis.scrollGroup.attr({\n\t\t\t\ttranslateY: 1\n\t\t\t});\n\t\t\tthis.clipHeight = 0; // #1379\n\t\t}\n\t\t\n\t\treturn legendHeight;\n\t},\n\t\n\t/**\n\t * Scroll the legend by a number of pages\n\t * @param {Object} scrollBy\n\t * @param {Object} animation\n\t */\n\tscroll: function (scrollBy, animation) {\n\t\tvar pageCount = this.pageCount,\n\t\t\tcurrentPage = this.currentPage + scrollBy,\n\t\t\tclipHeight = this.clipHeight,\n\t\t\tnavOptions = this.options.navigation,\n\t\t\tactiveColor = navOptions.activeColor,\n\t\t\tinactiveColor = navOptions.inactiveColor,\n\t\t\tpager = this.pager,\n\t\t\tpadding = this.padding,\n\t\t\tscrollOffset;\n\t\t\n\t\t// When resizing while looking at the last page\n\t\tif (currentPage > pageCount) {\n\t\t\tcurrentPage = pageCount;\n\t\t}\n\t\t\n\t\tif (currentPage > 0) {\n\t\t\t\n\t\t\tif (animation !== UNDEFINED) {\n\t\t\t\tsetAnimation(animation, this.chart);\n\t\t\t}\n\t\t\t\n\t\t\tthis.nav.attr({\n\t\t\t\ttranslateX: padding,\n\t\t\t\ttranslateY: clipHeight + 7 + this.titleHeight,\n\t\t\t\tvisibility: VISIBLE\n\t\t\t});\n\t\t\tthis.up.attr({\n\t\t\t\t\tfill: currentPage === 1 ? inactiveColor : activeColor\n\t\t\t\t})\n\t\t\t\t.css({\n\t\t\t\t\tcursor: currentPage === 1 ? 'default' : 'pointer'\n\t\t\t\t});\n\t\t\tpager.attr({\n\t\t\t\ttext: currentPage + '/' + this.pageCount\n\t\t\t});\n\t\t\tthis.down.attr({\n\t\t\t\t\tx: 18 + this.pager.getBBox().width, // adjust to text width\n\t\t\t\t\tfill: currentPage === pageCount ? inactiveColor : activeColor\n\t\t\t\t})\n\t\t\t\t.css({\n\t\t\t\t\tcursor: currentPage === pageCount ? 'default' : 'pointer'\n\t\t\t\t});\n\t\t\t\n\t\t\tscrollOffset = -mathMin(clipHeight * (currentPage - 1), this.fullHeight - clipHeight + padding) + 1;\n\t\t\tthis.scrollGroup.animate({\n\t\t\t\ttranslateY: scrollOffset\n\t\t\t});\n\t\t\tpager.attr({\n\t\t\t\ttext: currentPage + '/' + pageCount\n\t\t\t});\n\t\t\t\n\t\t\t\n\t\t\tthis.currentPage = currentPage;\n\t\t\tthis.positionCheckboxes(scrollOffset);\n\t\t}\n\t\t\t\n\t}\n\t\n};\n\n// Workaround for #2030, horizontal legend items not displaying in IE11 Preview.\n// TODO: When IE11 is released, check again for this bug, and remove the fix\n// or make a better one.\nif (/Trident.*?11\\.0/.test(userAgent)) {\n\twrap(Legend.prototype, 'positionItem', function (proceed, item) {\n\t\tvar legend = this;\n\t\tsetTimeout(function () {\n\t\t\tproceed.call(legend, item);\n\t\t});\n\t});\n}\n\n/**\n * The chart class\n * @param {Object} options\n * @param {Function} callback Function to run when the chart has loaded\n */\nfunction Chart() {\n\tthis.init.apply(this, arguments);\n}\n\nChart.prototype = {\n\n\t/**\n\t * Initialize the chart\n\t */\n\tinit: function (userOptions, callback) {\n\n\t\t// Handle regular options\n\t\tvar options,\n\t\t\tseriesOptions = userOptions.series; // skip merging data points to increase performance\n\n\t\tuserOptions.series = null;\n\t\toptions = merge(defaultOptions, userOptions); // do the merge\n\t\toptions.series = userOptions.series = seriesOptions; // set back the series data\n\n\t\tvar optionsChart = options.chart;\n\t\t\n\t\t// Create margin & spacing array\n\t\tthis.margin = this.splashArray('margin', optionsChart);\n\t\tthis.spacing = this.splashArray('spacing', optionsChart);\n\n\t\tvar chartEvents = optionsChart.events;\n\n\t\t//this.runChartClick = chartEvents && !!chartEvents.click;\n\t\tthis.bounds = { h: {}, v: {} }; // Pixel data bounds for touch zoom\n\n\t\tthis.callback = callback;\n\t\tthis.isResizing = 0;\n\t\tthis.options = options;\n\t\t//chartTitleOptions = UNDEFINED;\n\t\t//chartSubtitleOptions = UNDEFINED;\n\n\t\tthis.axes = [];\n\t\tthis.series = [];\n\t\tthis.hasCartesianSeries = optionsChart.showAxes;\n\t\t//this.axisOffset = UNDEFINED;\n\t\t//this.maxTicks = UNDEFINED; // handle the greatest amount of ticks on grouped axes\n\t\t//this.inverted = UNDEFINED;\n\t\t//this.loadingShown = UNDEFINED;\n\t\t//this.container = UNDEFINED;\n\t\t//this.chartWidth = UNDEFINED;\n\t\t//this.chartHeight = UNDEFINED;\n\t\t//this.marginRight = UNDEFINED;\n\t\t//this.marginBottom = UNDEFINED;\n\t\t//this.containerWidth = UNDEFINED;\n\t\t//this.containerHeight = UNDEFINED;\n\t\t//this.oldChartWidth = UNDEFINED;\n\t\t//this.oldChartHeight = UNDEFINED;\n\n\t\t//this.renderTo = UNDEFINED;\n\t\t//this.renderToClone = UNDEFINED;\n\n\t\t//this.spacingBox = UNDEFINED\n\n\t\t//this.legend = UNDEFINED;\n\n\t\t// Elements\n\t\t//this.chartBackground = UNDEFINED;\n\t\t//this.plotBackground = UNDEFINED;\n\t\t//this.plotBGImage = UNDEFINED;\n\t\t//this.plotBorder = UNDEFINED;\n\t\t//this.loadingDiv = UNDEFINED;\n\t\t//this.loadingSpan = UNDEFINED;\n\n\t\tvar chart = this,\n\t\t\teventType;\n\n\t\t// Add the chart to the global lookup\n\t\tchart.index = charts.length;\n\t\tcharts.push(chart);\n\n\t\t// Set up auto resize\n\t\tif (optionsChart.reflow !== false) {\n\t\t\taddEvent(chart, 'load', function () {\n\t\t\t\tchart.initReflow();\n\t\t\t});\n\t\t}\n\n\t\t// Chart event handlers\n\t\tif (chartEvents) {\n\t\t\tfor (eventType in chartEvents) {\n\t\t\t\taddEvent(chart, eventType, chartEvents[eventType]);\n\t\t\t}\n\t\t}\n\n\t\tchart.xAxis = [];\n\t\tchart.yAxis = [];\n\n\t\t// Expose methods and variables\n\t\tchart.animation = useCanVG ? false : pick(optionsChart.animation, true);\n\t\tchart.pointCount = 0;\n\t\tchart.counters = new ChartCounters();\n\n\t\tchart.firstRender();\n\t},\n\n\t/**\n\t * Initialize an individual series, called internally before render time\n\t */\n\tinitSeries: function (options) {\n\t\tvar chart = this,\n\t\t\toptionsChart = chart.options.chart,\n\t\t\ttype = options.type || optionsChart.type || optionsChart.defaultSeriesType,\n\t\t\tseries,\n\t\t\tconstr = seriesTypes[type];\n\n\t\t// No such series type\n\t\tif (!constr) {\n\t\t\terror(17, true);\n\t\t}\n\n\t\tseries = new constr();\n\t\tseries.init(this, options);\n\t\treturn series;\n\t},\n\n\t/**\n\t * Add a series dynamically after  time\n\t *\n\t * @param {Object} options The config options\n\t * @param {Boolean} redraw Whether to redraw the chart after adding. Defaults to true.\n\t * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\n\t *    configuration\n\t *\n\t * @return {Object} series The newly created series object\n\t */\n\taddSeries: function (options, redraw, animation) {\n\t\tvar series,\n\t\t\tchart = this;\n\n\t\tif (options) {\n\t\t\tredraw = pick(redraw, true); // defaults to true\n\n\t\t\tfireEvent(chart, 'addSeries', { options: options }, function () {\n\t\t\t\tseries = chart.initSeries(options);\n\t\t\t\t\n\t\t\t\tchart.isDirtyLegend = true; // the series array is out of sync with the display\n\t\t\t\tchart.linkSeries();\n\t\t\t\tif (redraw) {\n\t\t\t\t\tchart.redraw(animation);\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\treturn series;\n\t},\n\n\t/**\n     * Add an axis to the chart\n     * @param {Object} options The axis option\n     * @param {Boolean} isX Whether it is an X axis or a value axis\n     */\n\taddAxis: function (options, isX, redraw, animation) {\n\t\tvar key = isX ? 'xAxis' : 'yAxis',\n\t\t\tchartOptions = this.options,\n\t\t\taxis;\n\n\t\t/*jslint unused: false*/\n\t\taxis = new Axis(this, merge(options, {\n\t\t\tindex: this[key].length,\n\t\t\tisX: isX\n\t\t}));\n\t\t/*jslint unused: true*/\n\n\t\t// Push the new axis options to the chart options\n\t\tchartOptions[key] = splat(chartOptions[key] || {});\n\t\tchartOptions[key].push(options);\n\n\t\tif (pick(redraw, true)) {\n\t\t\tthis.redraw(animation);\n\t\t}\n\t},\n\n\t/**\n\t * Check whether a given point is within the plot area\n\t *\n\t * @param {Number} plotX Pixel x relative to the plot area\n\t * @param {Number} plotY Pixel y relative to the plot area\n\t * @param {Boolean} inverted Whether the chart is inverted\n\t */\n\tisInsidePlot: function (plotX, plotY, inverted) {\n\t\tvar x = inverted ? plotY : plotX,\n\t\t\ty = inverted ? plotX : plotY;\n\t\t\t\n\t\treturn x >= 0 &&\n\t\t\tx <= this.plotWidth &&\n\t\t\ty >= 0 &&\n\t\t\ty <= this.plotHeight;\n\t},\n\n\t/**\n\t * Adjust all axes tick amounts\n\t */\n\tadjustTickAmounts: function () {\n\t\tif (this.options.chart.alignTicks !== false) {\n\t\t\teach(this.axes, function (axis) {\n\t\t\t\taxis.adjustTickAmount();\n\t\t\t});\n\t\t}\n\t\tthis.maxTicks = null;\n\t},\n\n\t/**\n\t * Redraw legend, axes or series based on updated data\n\t *\n\t * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\n\t *    configuration\n\t */\n\tredraw: function (animation) {\n\t\tvar chart = this,\n\t\t\taxes = chart.axes,\n\t\t\tseries = chart.series,\n\t\t\tpointer = chart.pointer,\n\t\t\tlegend = chart.legend,\n\t\t\tredrawLegend = chart.isDirtyLegend,\n\t\t\thasStackedSeries,\n\t\t\thasDirtyStacks,\n\t\t\tisDirtyBox = chart.isDirtyBox, // todo: check if it has actually changed?\n\t\t\tseriesLength = series.length,\n\t\t\ti = seriesLength,\n\t\t\tserie,\n\t\t\trenderer = chart.renderer,\n\t\t\tisHiddenChart = renderer.isHidden(),\n\t\t\tafterRedraw = [];\n\t\t\t\n\t\tsetAnimation(animation, chart);\n\t\t\n\t\tif (isHiddenChart) {\n\t\t\tchart.cloneRenderTo();\n\t\t}\n\n\t\t// Adjust title layout (reflow multiline text)\n\t\tchart.layOutTitles();\n\n\t\t// link stacked series\n\t\twhile (i--) {\n\t\t\tserie = series[i];\n\n\t\t\tif (serie.options.stacking) {\n\t\t\t\thasStackedSeries = true;\n\t\t\t\t\n\t\t\t\tif (serie.isDirty) {\n\t\t\t\t\thasDirtyStacks = true;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (hasDirtyStacks) { // mark others as dirty\n\t\t\ti = seriesLength;\n\t\t\twhile (i--) {\n\t\t\t\tserie = series[i];\n\t\t\t\tif (serie.options.stacking) {\n\t\t\t\t\tserie.isDirty = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// handle updated data in the series\n\t\teach(series, function (serie) {\n\t\t\tif (serie.isDirty) { // prepare the data so axis can read it\n\t\t\t\tif (serie.options.legendType === 'point') {\n\t\t\t\t\tredrawLegend = true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\t// handle added or removed series\n\t\tif (redrawLegend && legend.options.enabled) { // series or pie points are added or removed\n\t\t\t// draw legend graphics\n\t\t\tlegend.render();\n\n\t\t\tchart.isDirtyLegend = false;\n\t\t}\n\n\t\t// reset stacks\n\t\tif (hasStackedSeries) {\n\t\t\tchart.getStacks();\n\t\t}\n\n\n\t\tif (chart.hasCartesianSeries) {\n\t\t\tif (!chart.isResizing) {\n\n\t\t\t\t// reset maxTicks\n\t\t\t\tchart.maxTicks = null;\n\n\t\t\t\t// set axes scales\n\t\t\t\teach(axes, function (axis) {\n\t\t\t\t\taxis.setScale();\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tchart.adjustTickAmounts();\n\t\t\tchart.getMargins();\n\n\t\t\t// If one axis is dirty, all axes must be redrawn (#792, #2169)\n\t\t\teach(axes, function (axis) {\n\t\t\t\tif (axis.isDirty) {\n\t\t\t\t\tisDirtyBox = true;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// redraw axes\n\t\t\teach(axes, function (axis) {\n\t\t\t\t\n\t\t\t\t// Fire 'afterSetExtremes' only if extremes are set\n\t\t\t\tif (axis.isDirtyExtremes) { // #821\n\t\t\t\t\taxis.isDirtyExtremes = false;\n\t\t\t\t\tafterRedraw.push(function () { // prevent a recursive call to chart.redraw() (#1119)\n\t\t\t\t\t\tfireEvent(axis, 'afterSetExtremes', extend(axis.eventArgs, axis.getExtremes())); // #747, #751\n\t\t\t\t\t\tdelete axis.eventArgs;\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (isDirtyBox || hasStackedSeries) {\n\t\t\t\t\taxis.redraw();\n\t\t\t\t}\n\t\t\t});\n\n\n\t\t}\n\t\t// the plot areas size has changed\n\t\tif (isDirtyBox) {\n\t\t\tchart.drawChartBox();\n\t\t}\n\n\n\t\t// redraw affected series\n\t\teach(series, function (serie) {\n\t\t\tif (serie.isDirty && serie.visible &&\n\t\t\t\t\t(!serie.isCartesian || serie.xAxis)) { // issue #153\n\t\t\t\tserie.redraw();\n\t\t\t}\n\t\t});\n\n\t\t// move tooltip or reset\n\t\tif (pointer && pointer.reset) {\n\t\t\tpointer.reset(true);\n\t\t}\n\n\t\t// redraw if canvas\n\t\trenderer.draw();\n\n\t\t// fire the event\n\t\tfireEvent(chart, 'redraw'); // jQuery breaks this when calling it from addEvent. Overwrites chart.redraw\n\t\t\n\t\tif (isHiddenChart) {\n\t\t\tchart.cloneRenderTo(true);\n\t\t}\n\t\t\n\t\t// Fire callbacks that are put on hold until after the redraw\n\t\teach(afterRedraw, function (callback) {\n\t\t\tcallback.call();\n\t\t});\n\t},\n\n\n\n\t/**\n\t * Dim the chart and show a loading text or symbol\n\t * @param {String} str An optional text to show in the loading label instead of the default one\n\t */\n\tshowLoading: function (str) {\n\t\tvar chart = this,\n\t\t\toptions = chart.options,\n\t\t\tloadingDiv = chart.loadingDiv;\n\n\t\tvar loadingOptions = options.loading;\n\n\t\t// create the layer at the first call\n\t\tif (!loadingDiv) {\n\t\t\tchart.loadingDiv = loadingDiv = createElement(DIV, {\n\t\t\t\tclassName: PREFIX + 'loading'\n\t\t\t}, extend(loadingOptions.style, {\n\t\t\t\tzIndex: 10,\n\t\t\t\tdisplay: NONE\n\t\t\t}), chart.container);\n\n\t\t\tchart.loadingSpan = createElement(\n\t\t\t\t'span',\n\t\t\t\tnull,\n\t\t\t\tloadingOptions.labelStyle,\n\t\t\t\tloadingDiv\n\t\t\t);\n\n\t\t}\n\n\t\t// update text\n\t\tchart.loadingSpan.innerHTML = str || options.lang.loading;\n\n\t\t// show it\n\t\tif (!chart.loadingShown) {\n\t\t\tcss(loadingDiv, { \n\t\t\t\topacity: 0, \n\t\t\t\tdisplay: '',\n\t\t\t\tleft: chart.plotLeft + PX,\n\t\t\t\ttop: chart.plotTop + PX,\n\t\t\t\twidth: chart.plotWidth + PX,\n\t\t\t\theight: chart.plotHeight + PX\n\t\t\t});\n\t\t\tanimate(loadingDiv, {\n\t\t\t\topacity: loadingOptions.style.opacity\n\t\t\t}, {\n\t\t\t\tduration: loadingOptions.showDuration || 0\n\t\t\t});\n\t\t\tchart.loadingShown = true;\n\t\t}\n\t},\n\n\t/**\n\t * Hide the loading layer\n\t */\n\thideLoading: function () {\n\t\tvar options = this.options,\n\t\t\tloadingDiv = this.loadingDiv;\n\n\t\tif (loadingDiv) {\n\t\t\tanimate(loadingDiv, {\n\t\t\t\topacity: 0\n\t\t\t}, {\n\t\t\t\tduration: options.loading.hideDuration || 100,\n\t\t\t\tcomplete: function () {\n\t\t\t\t\tcss(loadingDiv, { display: NONE });\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tthis.loadingShown = false;\n\t},\n\n\t/**\n\t * Get an axis, series or point object by id.\n\t * @param id {String} The id as given in the configuration options\n\t */\n\tget: function (id) {\n\t\tvar chart = this,\n\t\t\taxes = chart.axes,\n\t\t\tseries = chart.series;\n\n\t\tvar i,\n\t\t\tj,\n\t\t\tpoints;\n\n\t\t// search axes\n\t\tfor (i = 0; i < axes.length; i++) {\n\t\t\tif (axes[i].options.id === id) {\n\t\t\t\treturn axes[i];\n\t\t\t}\n\t\t}\n\n\t\t// search series\n\t\tfor (i = 0; i < series.length; i++) {\n\t\t\tif (series[i].options.id === id) {\n\t\t\t\treturn series[i];\n\t\t\t}\n\t\t}\n\n\t\t// search points\n\t\tfor (i = 0; i < series.length; i++) {\n\t\t\tpoints = series[i].points || [];\n\t\t\tfor (j = 0; j < points.length; j++) {\n\t\t\t\tif (points[j].id === id) {\n\t\t\t\t\treturn points[j];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t},\n\n\t/**\n\t * Create the Axis instances based on the config options\n\t */\n\tgetAxes: function () {\n\t\tvar chart = this,\n\t\t\toptions = this.options,\n\t\t\txAxisOptions = options.xAxis = splat(options.xAxis || {}),\n\t\t\tyAxisOptions = options.yAxis = splat(options.yAxis || {}),\n\t\t\toptionsArray,\n\t\t\taxis;\n\n\t\t// make sure the options are arrays and add some members\n\t\teach(xAxisOptions, function (axis, i) {\n\t\t\taxis.index = i;\n\t\t\taxis.isX = true;\n\t\t});\n\n\t\teach(yAxisOptions, function (axis, i) {\n\t\t\taxis.index = i;\n\t\t});\n\n\t\t// concatenate all axis options into one array\n\t\toptionsArray = xAxisOptions.concat(yAxisOptions);\n\n\t\teach(optionsArray, function (axisOptions) {\n\t\t\taxis = new Axis(chart, axisOptions);\n\t\t});\n\n\t\tchart.adjustTickAmounts();\n\t},\n\n\n\t/**\n\t * Get the currently selected points from all series\n\t */\n\tgetSelectedPoints: function () {\n\t\tvar points = [];\n\t\teach(this.series, function (serie) {\n\t\t\tpoints = points.concat(grep(serie.points || [], function (point) {\n\t\t\t\treturn point.selected;\n\t\t\t}));\n\t\t});\n\t\treturn points;\n\t},\n\n\t/**\n\t * Get the currently selected series\n\t */\n\tgetSelectedSeries: function () {\n\t\treturn grep(this.series, function (serie) {\n\t\t\treturn serie.selected;\n\t\t});\n\t},\n\n\t/**\n\t * Generate stacks for each series and calculate stacks total values\n\t */\n\tgetStacks: function () {\n\t\tvar chart = this;\n\n\t\t// reset stacks for each yAxis\n\t\teach(chart.yAxis, function (axis) {\n\t\t\tif (axis.stacks && axis.hasVisibleSeries) {\n\t\t\t\taxis.oldStacks = axis.stacks;\n\t\t\t}\n\t\t});\n\n\t\teach(chart.series, function (series) {\n\t\t\tif (series.options.stacking && (series.visible === true || chart.options.chart.ignoreHiddenSeries === false)) {\n\t\t\t\tseries.stackKey = series.type + pick(series.options.stack, '');\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n\t * Display the zoom button\n\t */\n\tshowResetZoom: function () {\n\t\tvar chart = this,\n\t\t\tlang = defaultOptions.lang,\n\t\t\tbtnOptions = chart.options.chart.resetZoomButton,\n\t\t\ttheme = btnOptions.theme,\n\t\t\tstates = theme.states,\n\t\t\talignTo = btnOptions.relativeTo === 'chart' ? null : 'plotBox';\n\t\t\t\n\t\tthis.resetZoomButton = chart.renderer.button(lang.resetZoom, null, null, function () { chart.zoomOut(); }, theme, states && states.hover)\n\t\t\t.attr({\n\t\t\t\talign: btnOptions.position.align,\n\t\t\t\ttitle: lang.resetZoomTitle\n\t\t\t})\n\t\t\t.add()\n\t\t\t.align(btnOptions.position, false, alignTo);\n\t\t\t\n\t},\n\n\t/**\n\t * Zoom out to 1:1\n\t */\n\tzoomOut: function () {\n\t\tvar chart = this;\n\t\tfireEvent(chart, 'selection', { resetSelection: true }, function () { \n\t\t\tchart.zoom();\n\t\t});\n\t},\n\n\t/**\n\t * Zoom into a given portion of the chart given by axis coordinates\n\t * @param {Object} event\n\t */\n\tzoom: function (event) {\n\t\tvar chart = this,\n\t\t\thasZoomed,\n\t\t\tpointer = chart.pointer,\n\t\t\tdisplayButton = false,\n\t\t\tresetZoomButton;\n\n\t\t// If zoom is called with no arguments, reset the axes\n\t\tif (!event || event.resetSelection) {\n\t\t\teach(chart.axes, function (axis) {\n\t\t\t\thasZoomed = axis.zoom();\n\t\t\t});\n\t\t} else { // else, zoom in on all axes\n\t\t\teach(event.xAxis.concat(event.yAxis), function (axisData) {\n\t\t\t\tvar axis = axisData.axis,\n\t\t\t\t\tisXAxis = axis.isXAxis;\n\n\t\t\t\t// don't zoom more than minRange\n\t\t\t\tif (pointer[isXAxis ? 'zoomX' : 'zoomY'] || pointer[isXAxis ? 'pinchX' : 'pinchY']) {\n\t\t\t\t\thasZoomed = axis.zoom(axisData.min, axisData.max);\n\t\t\t\t\tif (axis.displayBtn) {\n\t\t\t\t\t\tdisplayButton = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\t\n\t\t// Show or hide the Reset zoom button\n\t\tresetZoomButton = chart.resetZoomButton;\n\t\tif (displayButton && !resetZoomButton) {\n\t\t\tchart.showResetZoom();\n\t\t} else if (!displayButton && isObject(resetZoomButton)) {\n\t\t\tchart.resetZoomButton = resetZoomButton.destroy();\n\t\t}\n\t\t\n\n\t\t// Redraw\n\t\tif (hasZoomed) {\n\t\t\tchart.redraw(\n\t\t\t\tpick(chart.options.chart.animation, event && event.animation, chart.pointCount < 100) // animation\n\t\t\t);\n\t\t}\n\t},\n\n\t/**\n\t * Pan the chart by dragging the mouse across the pane. This function is called\n\t * on mouse move, and the distance to pan is computed from chartX compared to\n\t * the first chartX position in the dragging operation.\n\t */\n\tpan: function (e, panning) {\n\n\t\tvar chart = this,\n\t\t\thoverPoints = chart.hoverPoints,\n\t\t\tdoRedraw;\n\n\t\t// remove active points for shared tooltip\n\t\tif (hoverPoints) {\n\t\t\teach(hoverPoints, function (point) {\n\t\t\t\tpoint.setState();\n\t\t\t});\n\t\t}\n\n\t\teach(panning === 'xy' ? [1, 0] : [1], function (isX) { // xy is used in maps\n\t\t\tvar mousePos = e[isX ? 'chartX' : 'chartY'],\n\t\t\t\taxis = chart[isX ? 'xAxis' : 'yAxis'][0],\n\t\t\t\tstartPos = chart[isX ? 'mouseDownX' : 'mouseDownY'],\n\t\t\t\thalfPointRange = (axis.pointRange || 0) / 2,\n\t\t\t\textremes = axis.getExtremes(),\n\t\t\t\tnewMin = axis.toValue(startPos - mousePos, true) + halfPointRange,\n\t\t\t\tnewMax = axis.toValue(startPos + chart[isX ? 'plotWidth' : 'plotHeight'] - mousePos, true) - halfPointRange;\n\n\t\t\tif (axis.series.length && newMin > mathMin(extremes.dataMin, extremes.min) && newMax < mathMax(extremes.dataMax, extremes.max)) {\n\t\t\t\taxis.setExtremes(newMin, newMax, false, false, { trigger: 'pan' });\n\t\t\t\tdoRedraw = true;\n\t\t\t}\n\n\t\t\tchart[isX ? 'mouseDownX' : 'mouseDownY'] = mousePos; // set new reference for next run\n\t\t});\n\n\t\tif (doRedraw) {\n\t\t\tchart.redraw(false);\n\t\t}\n\t\tcss(chart.container, { cursor: 'move' });\n\t},\n\n\t/**\n\t * Show the title and subtitle of the chart\n\t *\n\t * @param titleOptions {Object} New title options\n\t * @param subtitleOptions {Object} New subtitle options\n\t *\n\t */\n\tsetTitle: function (titleOptions, subtitleOptions) {\n\t\tvar chart = this,\n\t\t\toptions = chart.options,\n\t\t\tchartTitleOptions,\n\t\t\tchartSubtitleOptions;\n\n\t\tchartTitleOptions = options.title = merge(options.title, titleOptions);\n\t\tchartSubtitleOptions = options.subtitle = merge(options.subtitle, subtitleOptions);\n\n\t\t// add title and subtitle\n\t\teach([\n\t\t\t['title', titleOptions, chartTitleOptions],\n\t\t\t['subtitle', subtitleOptions, chartSubtitleOptions]\n\t\t], function (arr) {\n\t\t\tvar name = arr[0],\n\t\t\t\ttitle = chart[name],\n\t\t\t\ttitleOptions = arr[1],\n\t\t\t\tchartTitleOptions = arr[2];\n\n\t\t\tif (title && titleOptions) {\n\t\t\t\tchart[name] = title = title.destroy(); // remove old\n\t\t\t}\n\t\t\t\n\t\t\tif (chartTitleOptions && chartTitleOptions.text && !title) {\n\t\t\t\tchart[name] = chart.renderer.text(\n\t\t\t\t\tchartTitleOptions.text,\n\t\t\t\t\t0,\n\t\t\t\t\t0,\n\t\t\t\t\tchartTitleOptions.useHTML\n\t\t\t\t)\n\t\t\t\t.attr({\n\t\t\t\t\talign: chartTitleOptions.align,\n\t\t\t\t\t'class': PREFIX + name,\n\t\t\t\t\tzIndex: chartTitleOptions.zIndex || 4\n\t\t\t\t})\n\t\t\t\t.css(chartTitleOptions.style)\n\t\t\t\t.add();\n\t\t\t}\t\n\t\t});\n\t\tchart.layOutTitles();\n\t},\n\n\t/**\n\t * Lay out the chart titles and cache the full offset height for use in getMargins\n\t */\n\tlayOutTitles: function () {\n\t\tvar titleOffset = 0,\n\t\t\ttitle = this.title,\n\t\t\tsubtitle = this.subtitle,\n\t\t\toptions = this.options,\n\t\t\ttitleOptions = options.title,\n\t\t\tsubtitleOptions = options.subtitle,\n\t\t\tautoWidth = this.spacingBox.width - 44; // 44 makes room for default context button\n\n\t\tif (title) {\n\t\t\ttitle\n\t\t\t\t.css({ width: (titleOptions.width || autoWidth) + PX })\n\t\t\t\t.align(extend({ y: 15 }, titleOptions), false, 'spacingBox');\n\t\t\t\n\t\t\tif (!titleOptions.floating && !titleOptions.verticalAlign) {\n\t\t\t\ttitleOffset = title.getBBox().height;\n\n\t\t\t\t// Adjust for browser consistency + backwards compat after #776 fix\n\t\t\t\tif (titleOffset >= 18 && titleOffset <= 25) {\n\t\t\t\t\ttitleOffset = 15; \n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (subtitle) {\n\t\t\tsubtitle\n\t\t\t\t.css({ width: (subtitleOptions.width || autoWidth) + PX })\n\t\t\t\t.align(extend({ y: titleOffset + titleOptions.margin }, subtitleOptions), false, 'spacingBox');\n\t\t\t\n\t\t\tif (!subtitleOptions.floating && !subtitleOptions.verticalAlign) {\n\t\t\t\ttitleOffset = mathCeil(titleOffset + subtitle.getBBox().height);\n\t\t\t}\n\t\t}\n\n\t\tthis.titleOffset = titleOffset; // used in getMargins\n\t},\n\n\t/**\n\t * Get chart width and height according to options and container size\n\t */\n\tgetChartSize: function () {\n\t\tvar chart = this,\n\t\t\toptionsChart = chart.options.chart,\n\t\t\trenderTo = chart.renderToClone || chart.renderTo;\n\n\t\t// get inner width and height from jQuery (#824)\n\t\tchart.containerWidth = adapterRun(renderTo, 'width');\n\t\tchart.containerHeight = adapterRun(renderTo, 'height');\n\t\t\n\t\tchart.chartWidth = mathMax(0, optionsChart.width || chart.containerWidth || 600); // #1393, 1460\n\t\tchart.chartHeight = mathMax(0, pick(optionsChart.height,\n\t\t\t// the offsetHeight of an empty container is 0 in standard browsers, but 19 in IE7:\n\t\t\tchart.containerHeight > 19 ? chart.containerHeight : 400));\n\t},\n\n\t/**\n\t * Create a clone of the chart's renderTo div and place it outside the viewport to allow\n\t * size computation on chart.render and chart.redraw\n\t */\n\tcloneRenderTo: function (revert) {\n\t\tvar clone = this.renderToClone,\n\t\t\tcontainer = this.container;\n\t\t\n\t\t// Destroy the clone and bring the container back to the real renderTo div\n\t\tif (revert) {\n\t\t\tif (clone) {\n\t\t\t\tthis.renderTo.appendChild(container);\n\t\t\t\tdiscardElement(clone);\n\t\t\t\tdelete this.renderToClone;\n\t\t\t}\n\t\t\n\t\t// Set up the clone\n\t\t} else {\n\t\t\tif (container && container.parentNode === this.renderTo) {\n\t\t\t\tthis.renderTo.removeChild(container); // do not clone this\n\t\t\t}\n\t\t\tthis.renderToClone = clone = this.renderTo.cloneNode(0);\n\t\t\tcss(clone, {\n\t\t\t\tposition: ABSOLUTE,\n\t\t\t\ttop: '-9999px',\n\t\t\t\tdisplay: 'block' // #833\n\t\t\t});\n\t\t\tdoc.body.appendChild(clone);\n\t\t\tif (container) {\n\t\t\t\tclone.appendChild(container);\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Get the containing element, determine the size and create the inner container\n\t * div to hold the chart\n\t */\n\tgetContainer: function () {\n\t\tvar chart = this,\n\t\t\tcontainer,\n\t\t\toptionsChart = chart.options.chart,\n\t\t\tchartWidth,\n\t\t\tchartHeight,\n\t\t\trenderTo,\n\t\t\tindexAttrName = 'data-highcharts-chart',\n\t\t\toldChartIndex,\n\t\t\tcontainerId;\n\n\t\tchart.renderTo = renderTo = optionsChart.renderTo;\n\t\tcontainerId = PREFIX + idCounter++;\n\n\t\tif (isString(renderTo)) {\n\t\t\tchart.renderTo = renderTo = doc.getElementById(renderTo);\n\t\t}\n\t\t\n\t\t// Display an error if the renderTo is wrong\n\t\tif (!renderTo) {\n\t\t\terror(13, true);\n\t\t}\n\t\t\n\t\t// If the container already holds a chart, destroy it\n\t\toldChartIndex = pInt(attr(renderTo, indexAttrName));\n\t\tif (!isNaN(oldChartIndex) && charts[oldChartIndex]) {\n\t\t\tcharts[oldChartIndex].destroy();\n\t\t}\t\t\n\t\t\n\t\t// Make a reference to the chart from the div\n\t\tattr(renderTo, indexAttrName, chart.index);\n\n\t\t// remove previous chart\n\t\trenderTo.innerHTML = '';\n\n\t\t// If the container doesn't have an offsetWidth, it has or is a child of a node\n\t\t// that has display:none. We need to temporarily move it out to a visible\n\t\t// state to determine the size, else the legend and tooltips won't render\n\t\t// properly\n\t\tif (!renderTo.offsetWidth) {\n\t\t\tchart.cloneRenderTo();\n\t\t}\n\n\t\t// get the width and height\n\t\tchart.getChartSize();\n\t\tchartWidth = chart.chartWidth;\n\t\tchartHeight = chart.chartHeight;\n\n\t\t// create the inner container\n\t\tchart.container = container = createElement(DIV, {\n\t\t\t\tclassName: PREFIX + 'container' +\n\t\t\t\t\t(optionsChart.className ? ' ' + optionsChart.className : ''),\n\t\t\t\tid: containerId\n\t\t\t}, extend({\n\t\t\t\tposition: RELATIVE,\n\t\t\t\toverflow: HIDDEN, // needed for context menu (avoid scrollbars) and\n\t\t\t\t\t// content overflow in IE\n\t\t\t\twidth: chartWidth + PX,\n\t\t\t\theight: chartHeight + PX,\n\t\t\t\ttextAlign: 'left',\n\t\t\t\tlineHeight: 'normal', // #427\n\t\t\t\tzIndex: 0, // #1072\n\t\t\t\t'-webkit-tap-highlight-color': 'rgba(0,0,0,0)'\n\t\t\t}, optionsChart.style),\n\t\t\tchart.renderToClone || renderTo\n\t\t);\n\n\t\t// cache the cursor (#1650)\n\t\tchart._cursor = container.style.cursor;\n\n\t\tchart.renderer =\n\t\t\toptionsChart.forExport ? // force SVG, used for SVG export\n\t\t\t\tnew SVGRenderer(container, chartWidth, chartHeight, true) :\n\t\t\t\tnew Renderer(container, chartWidth, chartHeight);\n\n\t\tif (useCanVG) {\n\t\t\t// If we need canvg library, extend and configure the renderer\n\t\t\t// to get the tracker for translating mouse events\n\t\t\tchart.renderer.create(chart, container, chartWidth, chartHeight);\n\t\t}\n\t},\n\n\t/**\n\t * Calculate margins by rendering axis labels in a preliminary position. Title,\n\t * subtitle and legend have already been rendered at this stage, but will be\n\t * moved into their final positions\n\t */\n\tgetMargins: function () {\n\t\tvar chart = this,\n\t\t\tspacing = chart.spacing,\n\t\t\taxisOffset,\n\t\t\tlegend = chart.legend,\n\t\t\tmargin = chart.margin,\n\t\t\tlegendOptions = chart.options.legend,\n\t\t\tlegendMargin = pick(legendOptions.margin, 10),\n\t\t\tlegendX = legendOptions.x,\n\t\t\tlegendY = legendOptions.y,\n\t\t\talign = legendOptions.align,\n\t\t\tverticalAlign = legendOptions.verticalAlign,\n\t\t\ttitleOffset = chart.titleOffset;\n\n\t\tchart.resetMargins();\n\t\taxisOffset = chart.axisOffset;\n\n\t\t// Adjust for title and subtitle\n\t\tif (titleOffset && !defined(margin[0])) {\n\t\t\tchart.plotTop = mathMax(chart.plotTop, titleOffset + chart.options.title.margin + spacing[0]);\n\t\t}\n\t\t\n\t\t// Adjust for legend\n\t\tif (legend.display && !legendOptions.floating) {\n\t\t\tif (align === 'right') { // horizontal alignment handled first\n\t\t\t\tif (!defined(margin[1])) {\n\t\t\t\t\tchart.marginRight = mathMax(\n\t\t\t\t\t\tchart.marginRight,\n\t\t\t\t\t\tlegend.legendWidth - legendX + legendMargin + spacing[1]\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t} else if (align === 'left') {\n\t\t\t\tif (!defined(margin[3])) {\n\t\t\t\t\tchart.plotLeft = mathMax(\n\t\t\t\t\t\tchart.plotLeft,\n\t\t\t\t\t\tlegend.legendWidth + legendX + legendMargin + spacing[3]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t} else if (verticalAlign === 'top') {\n\t\t\t\tif (!defined(margin[0])) {\n\t\t\t\t\tchart.plotTop = mathMax(\n\t\t\t\t\t\tchart.plotTop,\n\t\t\t\t\t\tlegend.legendHeight + legendY + legendMargin + spacing[0]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t} else if (verticalAlign === 'bottom') {\n\t\t\t\tif (!defined(margin[2])) {\n\t\t\t\t\tchart.marginBottom = mathMax(\n\t\t\t\t\t\tchart.marginBottom,\n\t\t\t\t\t\tlegend.legendHeight - legendY + legendMargin + spacing[2]\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// adjust for scroller\n\t\tif (chart.extraBottomMargin) {\n\t\t\tchart.marginBottom += chart.extraBottomMargin;\n\t\t}\n\t\tif (chart.extraTopMargin) {\n\t\t\tchart.plotTop += chart.extraTopMargin;\n\t\t}\n\n\t\t// pre-render axes to get labels offset width\n\t\tif (chart.hasCartesianSeries) {\n\t\t\teach(chart.axes, function (axis) {\n\t\t\t\taxis.getOffset();\n\t\t\t});\n\t\t}\n\t\t\n\t\tif (!defined(margin[3])) {\n\t\t\tchart.plotLeft += axisOffset[3];\n\t\t}\n\t\tif (!defined(margin[0])) {\n\t\t\tchart.plotTop += axisOffset[0];\n\t\t}\n\t\tif (!defined(margin[2])) {\n\t\t\tchart.marginBottom += axisOffset[2];\n\t\t}\n\t\tif (!defined(margin[1])) {\n\t\t\tchart.marginRight += axisOffset[1];\n\t\t}\n\n\t\tchart.setChartSize();\n\n\t},\n\n\t/**\n\t * Add the event handlers necessary for auto resizing\n\t *\n\t */\n\tinitReflow: function () {\n\t\tvar chart = this,\n\t\t\toptionsChart = chart.options.chart,\n\t\t\trenderTo = chart.renderTo,\n\t\t\treflowTimeout;\n\t\t\t\n\t\tfunction reflow(e) {\n\t\t\tvar width = optionsChart.width || adapterRun(renderTo, 'width'),\n\t\t\t\theight = optionsChart.height || adapterRun(renderTo, 'height'),\n\t\t\t\ttarget = e ? e.target : win; // #805 - MooTools doesn't supply e\n\t\t\t\t\n\t\t\t// Width and height checks for display:none. Target is doc in IE8 and Opera,\n\t\t\t// win in Firefox, Chrome and IE9.\n\t\t\tif (!chart.hasUserSize && width && height && (target === win || target === doc)) {\n\t\t\t\t\n\t\t\t\tif (width !== chart.containerWidth || height !== chart.containerHeight) {\n\t\t\t\t\tclearTimeout(reflowTimeout);\n\t\t\t\t\tchart.reflowTimeout = reflowTimeout = setTimeout(function () {\n\t\t\t\t\t\tif (chart.container) { // It may have been destroyed in the meantime (#1257)\n\t\t\t\t\t\t\tchart.setSize(width, height, false);\n\t\t\t\t\t\t\tchart.hasUserSize = null;\n\t\t\t\t\t\t}\n\t\t\t\t\t}, 100);\n\t\t\t\t}\n\t\t\t\tchart.containerWidth = width;\n\t\t\t\tchart.containerHeight = height;\n\t\t\t}\n\t\t}\n\t\tchart.reflow = reflow;\n\t\taddEvent(win, 'resize', reflow);\n\t\taddEvent(chart, 'destroy', function () {\n\t\t\tremoveEvent(win, 'resize', reflow);\n\t\t});\n\t},\n\n\t/**\n\t * Resize the chart to a given width and height\n\t * @param {Number} width\n\t * @param {Number} height\n\t * @param {Object|Boolean} animation\n\t */\n\tsetSize: function (width, height, animation) {\n\t\tvar chart = this,\n\t\t\tchartWidth,\n\t\t\tchartHeight,\n\t\t\tfireEndResize;\n\n\t\t// Handle the isResizing counter\n\t\tchart.isResizing += 1;\n\t\tfireEndResize = function () {\n\t\t\tif (chart) {\n\t\t\t\tfireEvent(chart, 'endResize', null, function () {\n\t\t\t\t\tchart.isResizing -= 1;\n\t\t\t\t});\n\t\t\t}\n\t\t};\n\n\t\t// set the animation for the current process\n\t\tsetAnimation(animation, chart);\n\n\t\tchart.oldChartHeight = chart.chartHeight;\n\t\tchart.oldChartWidth = chart.chartWidth;\n\t\tif (defined(width)) {\n\t\t\tchart.chartWidth = chartWidth = mathMax(0, mathRound(width));\n\t\t\tchart.hasUserSize = !!chartWidth;\n\t\t}\n\t\tif (defined(height)) {\n\t\t\tchart.chartHeight = chartHeight = mathMax(0, mathRound(height));\n\t\t}\n\n\t\tcss(chart.container, {\n\t\t\twidth: chartWidth + PX,\n\t\t\theight: chartHeight + PX\n\t\t});\n\t\tchart.setChartSize(true);\n\t\tchart.renderer.setSize(chartWidth, chartHeight, animation);\n\n\t\t// handle axes\n\t\tchart.maxTicks = null;\n\t\teach(chart.axes, function (axis) {\n\t\t\taxis.isDirty = true;\n\t\t\taxis.setScale();\n\t\t});\n\n\t\t// make sure non-cartesian series are also handled\n\t\teach(chart.series, function (serie) {\n\t\t\tserie.isDirty = true;\n\t\t});\n\n\t\tchart.isDirtyLegend = true; // force legend redraw\n\t\tchart.isDirtyBox = true; // force redraw of plot and chart border\n\n\t\tchart.getMargins();\n\n\t\tchart.redraw(animation);\n\n\n\t\tchart.oldChartHeight = null;\n\t\tfireEvent(chart, 'resize');\n\n\t\t// fire endResize and set isResizing back\n\t\t// If animation is disabled, fire without delay\n\t\tif (globalAnimation === false) {\n\t\t\tfireEndResize();\n\t\t} else { // else set a timeout with the animation duration\n\t\t\tsetTimeout(fireEndResize, (globalAnimation && globalAnimation.duration) || 500);\n\t\t}\n\t},\n\n\t/**\n\t * Set the public chart properties. This is done before and after the pre-render\n\t * to determine margin sizes\n\t */\n\tsetChartSize: function (skipAxes) {\n\t\tvar chart = this,\n\t\t\tinverted = chart.inverted,\n\t\t\trenderer = chart.renderer,\n\t\t\tchartWidth = chart.chartWidth,\n\t\t\tchartHeight = chart.chartHeight,\n\t\t\toptionsChart = chart.options.chart,\n\t\t\tspacing = chart.spacing,\n\t\t\tclipOffset = chart.clipOffset,\n\t\t\tclipX,\n\t\t\tclipY,\n\t\t\tplotLeft,\n\t\t\tplotTop,\n\t\t\tplotWidth,\n\t\t\tplotHeight,\n\t\t\tplotBorderWidth;\n\n\t\tchart.plotLeft = plotLeft = mathRound(chart.plotLeft);\n\t\tchart.plotTop = plotTop = mathRound(chart.plotTop);\n\t\tchart.plotWidth = plotWidth = mathMax(0, mathRound(chartWidth - plotLeft - chart.marginRight));\n\t\tchart.plotHeight = plotHeight = mathMax(0, mathRound(chartHeight - plotTop - chart.marginBottom));\n\n\t\tchart.plotSizeX = inverted ? plotHeight : plotWidth;\n\t\tchart.plotSizeY = inverted ? plotWidth : plotHeight;\n\t\t\n\t\tchart.plotBorderWidth = optionsChart.plotBorderWidth || 0;\n\n\t\t// Set boxes used for alignment\n\t\tchart.spacingBox = renderer.spacingBox = {\n\t\t\tx: spacing[3],\n\t\t\ty: spacing[0],\n\t\t\twidth: chartWidth - spacing[3] - spacing[1],\n\t\t\theight: chartHeight - spacing[0] - spacing[2]\n\t\t};\n\t\tchart.plotBox = renderer.plotBox = {\n\t\t\tx: plotLeft,\n\t\t\ty: plotTop,\n\t\t\twidth: plotWidth,\n\t\t\theight: plotHeight\n\t\t};\n\n\t\tplotBorderWidth = 2 * mathFloor(chart.plotBorderWidth / 2);\n\t\tclipX = mathCeil(mathMax(plotBorderWidth, clipOffset[3]) / 2);\n\t\tclipY = mathCeil(mathMax(plotBorderWidth, clipOffset[0]) / 2);\n\t\tchart.clipBox = {\n\t\t\tx: clipX, \n\t\t\ty: clipY, \n\t\t\twidth: mathFloor(chart.plotSizeX - mathMax(plotBorderWidth, clipOffset[1]) / 2 - clipX), \n\t\t\theight: mathFloor(chart.plotSizeY - mathMax(plotBorderWidth, clipOffset[2]) / 2 - clipY)\n\t\t};\n\n\t\tif (!skipAxes) {\n\t\t\teach(chart.axes, function (axis) {\n\t\t\t\taxis.setAxisSize();\n\t\t\t\taxis.setAxisTranslation();\n\t\t\t});\n\t\t}\n\t},\n\n\t/**\n\t * Initial margins before auto size margins are applied\n\t */\n\tresetMargins: function () {\n\t\tvar chart = this,\n\t\t\tspacing = chart.spacing,\n\t\t\tmargin = chart.margin;\n\n\t\tchart.plotTop = pick(margin[0], spacing[0]);\n\t\tchart.marginRight = pick(margin[1], spacing[1]);\n\t\tchart.marginBottom = pick(margin[2], spacing[2]);\n\t\tchart.plotLeft = pick(margin[3], spacing[3]);\n\t\tchart.axisOffset = [0, 0, 0, 0]; // top, right, bottom, left\n\t\tchart.clipOffset = [0, 0, 0, 0];\n\t},\n\n\t/**\n\t * Draw the borders and backgrounds for chart and plot area\n\t */\n\tdrawChartBox: function () {\n\t\tvar chart = this,\n\t\t\toptionsChart = chart.options.chart,\n\t\t\trenderer = chart.renderer,\n\t\t\tchartWidth = chart.chartWidth,\n\t\t\tchartHeight = chart.chartHeight,\n\t\t\tchartBackground = chart.chartBackground,\n\t\t\tplotBackground = chart.plotBackground,\n\t\t\tplotBorder = chart.plotBorder,\n\t\t\tplotBGImage = chart.plotBGImage,\n\t\t\tchartBorderWidth = optionsChart.borderWidth || 0,\n\t\t\tchartBackgroundColor = optionsChart.backgroundColor,\n\t\t\tplotBackgroundColor = optionsChart.plotBackgroundColor,\n\t\t\tplotBackgroundImage = optionsChart.plotBackgroundImage,\n\t\t\tplotBorderWidth = optionsChart.plotBorderWidth || 0,\n\t\t\tmgn,\n\t\t\tbgAttr,\n\t\t\tplotLeft = chart.plotLeft,\n\t\t\tplotTop = chart.plotTop,\n\t\t\tplotWidth = chart.plotWidth,\n\t\t\tplotHeight = chart.plotHeight,\n\t\t\tplotBox = chart.plotBox,\n\t\t\tclipRect = chart.clipRect,\n\t\t\tclipBox = chart.clipBox;\n\n\t\t// Chart area\n\t\tmgn = chartBorderWidth + (optionsChart.shadow ? 8 : 0);\n\n\t\tif (chartBorderWidth || chartBackgroundColor) {\n\t\t\tif (!chartBackground) {\n\t\t\t\t\n\t\t\t\tbgAttr = {\n\t\t\t\t\tfill: chartBackgroundColor || NONE\n\t\t\t\t};\n\t\t\t\tif (chartBorderWidth) { // #980\n\t\t\t\t\tbgAttr.stroke = optionsChart.borderColor;\n\t\t\t\t\tbgAttr['stroke-width'] = chartBorderWidth;\n\t\t\t\t}\n\t\t\t\tchart.chartBackground = renderer.rect(mgn / 2, mgn / 2, chartWidth - mgn, chartHeight - mgn,\n\t\t\t\t\t\toptionsChart.borderRadius, chartBorderWidth)\n\t\t\t\t\t.attr(bgAttr)\n\t\t\t\t\t.add()\n\t\t\t\t\t.shadow(optionsChart.shadow);\n\n\t\t\t} else { // resize\n\t\t\t\tchartBackground.animate(\n\t\t\t\t\tchartBackground.crisp(null, null, null, chartWidth - mgn, chartHeight - mgn)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\n\t\t// Plot background\n\t\tif (plotBackgroundColor) {\n\t\t\tif (!plotBackground) {\n\t\t\t\tchart.plotBackground = renderer.rect(plotLeft, plotTop, plotWidth, plotHeight, 0)\n\t\t\t\t\t.attr({\n\t\t\t\t\t\tfill: plotBackgroundColor\n\t\t\t\t\t})\n\t\t\t\t\t.add()\n\t\t\t\t\t.shadow(optionsChart.plotShadow);\n\t\t\t} else {\n\t\t\t\tplotBackground.animate(plotBox);\n\t\t\t}\n\t\t}\n\t\tif (plotBackgroundImage) {\n\t\t\tif (!plotBGImage) {\n\t\t\t\tchart.plotBGImage = renderer.image(plotBackgroundImage, plotLeft, plotTop, plotWidth, plotHeight)\n\t\t\t\t\t.add();\n\t\t\t} else {\n\t\t\t\tplotBGImage.animate(plotBox);\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Plot clip\n\t\tif (!clipRect) {\n\t\t\tchart.clipRect = renderer.clipRect(clipBox);\n\t\t} else {\n\t\t\tclipRect.animate({\n\t\t\t\twidth: clipBox.width,\n\t\t\t\theight: clipBox.height\n\t\t\t});\n\t\t}\n\n\t\t// Plot area border\n\t\tif (plotBorderWidth) {\n\t\t\tif (!plotBorder) {\n\t\t\t\tchart.plotBorder = renderer.rect(plotLeft, plotTop, plotWidth, plotHeight, 0, -plotBorderWidth)\n\t\t\t\t\t.attr({\n\t\t\t\t\t\tstroke: optionsChart.plotBorderColor,\n\t\t\t\t\t\t'stroke-width': plotBorderWidth,\n\t\t\t\t\t\tzIndex: 1\n\t\t\t\t\t})\n\t\t\t\t\t.add();\n\t\t\t} else {\n\t\t\t\tplotBorder.animate(\n\t\t\t\t\tplotBorder.crisp(null, plotLeft, plotTop, plotWidth, plotHeight)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// reset\n\t\tchart.isDirtyBox = false;\n\t},\n\n\t/**\n\t * Detect whether a certain chart property is needed based on inspecting its options\n\t * and series. This mainly applies to the chart.invert property, and in extensions to \n\t * the chart.angular and chart.polar properties.\n\t */\n\tpropFromSeries: function () {\n\t\tvar chart = this,\n\t\t\toptionsChart = chart.options.chart,\n\t\t\tklass,\n\t\t\tseriesOptions = chart.options.series,\n\t\t\ti,\n\t\t\tvalue;\n\t\t\t\n\t\t\t\n\t\teach(['inverted', 'angular', 'polar'], function (key) {\n\t\t\t\n\t\t\t// The default series type's class\n\t\t\tklass = seriesTypes[optionsChart.type || optionsChart.defaultSeriesType];\n\t\t\t\n\t\t\t// Get the value from available chart-wide properties\n\t\t\tvalue = (\n\t\t\t\tchart[key] || // 1. it is set before\n\t\t\t\toptionsChart[key] || // 2. it is set in the options\n\t\t\t\t(klass && klass.prototype[key]) // 3. it's default series class requires it\n\t\t\t);\n\t\n\t\t\t// 4. Check if any the chart's series require it\n\t\t\ti = seriesOptions && seriesOptions.length;\n\t\t\twhile (!value && i--) {\n\t\t\t\tklass = seriesTypes[seriesOptions[i].type];\n\t\t\t\tif (klass && klass.prototype[key]) {\n\t\t\t\t\tvalue = true;\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\t// Set the chart property\n\t\t\tchart[key] = value;\t\n\t\t});\n\t\t\n\t},\n\n\t/**\n\t * Link two or more series together. This is done initially from Chart.render,\n\t * and after Chart.addSeries and Series.remove.\n\t */\n\tlinkSeries: function () {\n\t\tvar chart = this,\n\t\t\tchartSeries = chart.series;\n\n\t\t// Reset links\n\t\teach(chartSeries, function (series) {\n\t\t\tseries.linkedSeries.length = 0;\n\t\t});\n\n\t\t// Apply new links\n\t\teach(chartSeries, function (series) {\n\t\t\tvar linkedTo = series.options.linkedTo;\n\t\t\tif (isString(linkedTo)) {\n\t\t\t\tif (linkedTo === ':previous') {\n\t\t\t\t\tlinkedTo = chart.series[series.index - 1];\n\t\t\t\t} else {\n\t\t\t\t\tlinkedTo = chart.get(linkedTo);\n\t\t\t\t}\n\t\t\t\tif (linkedTo) {\n\t\t\t\t\tlinkedTo.linkedSeries.push(series);\n\t\t\t\t\tseries.linkedParent = linkedTo;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n\t * Render all graphics for the chart\n\t */\n\trender: function () {\n\t\tvar chart = this,\n\t\t\taxes = chart.axes,\n\t\t\trenderer = chart.renderer,\n\t\t\toptions = chart.options;\n\n\t\tvar labels = options.labels,\n\t\t\tcredits = options.credits,\n\t\t\tcreditsHref;\n\n\t\t// Title\n\t\tchart.setTitle();\n\n\n\t\t// Legend\n\t\tchart.legend = new Legend(chart, options.legend);\n\n\t\tchart.getStacks(); // render stacks\n\n\t\t// Get margins by pre-rendering axes\n\t\t// set axes scales\n\t\teach(axes, function (axis) {\n\t\t\taxis.setScale();\n\t\t});\n\n\t\tchart.getMargins();\n\n\t\tchart.maxTicks = null; // reset for second pass\n\t\teach(axes, function (axis) {\n\t\t\taxis.setTickPositions(true); // update to reflect the new margins\n\t\t\taxis.setMaxTicks();\n\t\t});\n\t\tchart.adjustTickAmounts();\n\t\tchart.getMargins(); // second pass to check for new labels\n\n\n\t\t// Draw the borders and backgrounds\n\t\tchart.drawChartBox();\t\t\n\n\n\t\t// Axes\n\t\tif (chart.hasCartesianSeries) {\n\t\t\teach(axes, function (axis) {\n\t\t\t\taxis.render();\n\t\t\t});\n\t\t}\n\n\t\t// The series\n\t\tif (!chart.seriesGroup) {\n\t\t\tchart.seriesGroup = renderer.g('series-group')\n\t\t\t\t.attr({ zIndex: 3 })\n\t\t\t\t.add();\n\t\t}\n\t\teach(chart.series, function (serie) {\n\t\t\tserie.translate();\n\t\t\tserie.setTooltipPoints();\n\t\t\tserie.render();\n\t\t});\n\n\t\t// Labels\n\t\tif (labels.items) {\n\t\t\teach(labels.items, function (label) {\n\t\t\t\tvar style = extend(labels.style, label.style),\n\t\t\t\t\tx = pInt(style.left) + chart.plotLeft,\n\t\t\t\t\ty = pInt(style.top) + chart.plotTop + 12;\n\n\t\t\t\t// delete to prevent rewriting in IE\n\t\t\t\tdelete style.left;\n\t\t\t\tdelete style.top;\n\n\t\t\t\trenderer.text(\n\t\t\t\t\tlabel.html,\n\t\t\t\t\tx,\n\t\t\t\t\ty\n\t\t\t\t)\n\t\t\t\t.attr({ zIndex: 2 })\n\t\t\t\t.css(style)\n\t\t\t\t.add();\n\n\t\t\t});\n\t\t}\n\n\t\t// Credits\n\t\tif (credits.enabled && !chart.credits) {\n\t\t\tcreditsHref = credits.href;\n\t\t\tchart.credits = renderer.text(\n\t\t\t\tcredits.text,\n\t\t\t\t0,\n\t\t\t\t0\n\t\t\t)\n\t\t\t.on('click', function () {\n\t\t\t\tif (creditsHref) {\n\t\t\t\t\tlocation.href = creditsHref;\n\t\t\t\t}\n\t\t\t})\n\t\t\t.attr({\n\t\t\t\talign: credits.position.align,\n\t\t\t\tzIndex: 8\n\t\t\t})\n\t\t\t.css(credits.style)\n\t\t\t.add()\n\t\t\t.align(credits.position);\n\t\t}\n\n\t\t// Set flag\n\t\tchart.hasRendered = true;\n\n\t},\n\n\t/**\n\t * Clean up memory usage\n\t */\n\tdestroy: function () {\n\t\tvar chart = this,\n\t\t\taxes = chart.axes,\n\t\t\tseries = chart.series,\n\t\t\tcontainer = chart.container,\n\t\t\ti,\n\t\t\tparentNode = container && container.parentNode;\n\t\t\t\n\t\t// fire the chart.destoy event\n\t\tfireEvent(chart, 'destroy');\n\t\t\n\t\t// Delete the chart from charts lookup array\n\t\tcharts[chart.index] = UNDEFINED;\n\t\tchart.renderTo.removeAttribute('data-highcharts-chart');\n\n\t\t// remove events\n\t\tremoveEvent(chart);\n\n\t\t// ==== Destroy collections:\n\t\t// Destroy axes\n\t\ti = axes.length;\n\t\twhile (i--) {\n\t\t\taxes[i] = axes[i].destroy();\n\t\t}\n\n\t\t// Destroy each series\n\t\ti = series.length;\n\t\twhile (i--) {\n\t\t\tseries[i] = series[i].destroy();\n\t\t}\n\n\t\t// ==== Destroy chart properties:\n\t\teach(['title', 'subtitle', 'chartBackground', 'plotBackground', 'plotBGImage', \n\t\t\t\t'plotBorder', 'seriesGroup', 'clipRect', 'credits', 'pointer', 'scroller', \n\t\t\t\t'rangeSelector', 'legend', 'resetZoomButton', 'tooltip', 'renderer'], function (name) {\n\t\t\tvar prop = chart[name];\n\n\t\t\tif (prop && prop.destroy) {\n\t\t\t\tchart[name] = prop.destroy();\n\t\t\t}\n\t\t});\n\n\t\t// remove container and all SVG\n\t\tif (container) { // can break in IE when destroyed before finished loading\n\t\t\tcontainer.innerHTML = '';\n\t\t\tremoveEvent(container);\n\t\t\tif (parentNode) {\n\t\t\t\tdiscardElement(container);\n\t\t\t}\n\n\t\t}\n\n\t\t// clean it all up\n\t\tfor (i in chart) {\n\t\t\tdelete chart[i];\n\t\t}\n\n\t},\n\n\n\t/**\n\t * VML namespaces can't be added until after complete. Listening\n\t * for Perini's doScroll hack is not enough.\n\t */\n\tisReadyToRender: function () {\n\t\tvar chart = this;\n\n\t\t// Note: in spite of JSLint's complaints, win == win.top is required\n\t\t/*jslint eqeq: true*/\n\t\tif ((!hasSVG && (win == win.top && doc.readyState !== 'complete')) || (useCanVG && !win.canvg)) {\n\t\t/*jslint eqeq: false*/\n\t\t\tif (useCanVG) {\n\t\t\t\t// Delay rendering until canvg library is downloaded and ready\n\t\t\t\tCanVGController.push(function () { chart.firstRender(); }, chart.options.global.canvasToolsURL);\n\t\t\t} else {\n\t\t\t\tdoc.attachEvent('onreadystatechange', function () {\n\t\t\t\t\tdoc.detachEvent('onreadystatechange', chart.firstRender);\n\t\t\t\t\tif (doc.readyState === 'complete') {\n\t\t\t\t\t\tchart.firstRender();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\t/**\n\t * Prepare for first rendering after all data are loaded\n\t */\n\tfirstRender: function () {\n\t\tvar chart = this,\n\t\t\toptions = chart.options,\n\t\t\tcallback = chart.callback;\n\n\t\t// Check whether the chart is ready to render\n\t\tif (!chart.isReadyToRender()) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Create the container\n\t\tchart.getContainer();\n\n\t\t// Run an early event after the container and renderer are established\n\t\tfireEvent(chart, 'init');\n\n\t\t\n\t\tchart.resetMargins();\n\t\tchart.setChartSize();\n\n\t\t// Set the common chart properties (mainly invert) from the given series\n\t\tchart.propFromSeries();\n\n\t\t// get axes\n\t\tchart.getAxes();\n\n\t\t// Initialize the series\n\t\teach(options.series || [], function (serieOptions) {\n\t\t\tchart.initSeries(serieOptions);\n\t\t});\n\n\t\tchart.linkSeries();\n\n\t\t// Run an event after axes and series are initialized, but before render. At this stage,\n\t\t// the series data is indexed and cached in the xData and yData arrays, so we can access\n\t\t// those before rendering. Used in Highstock. \n\t\tfireEvent(chart, 'beforeRender'); \n\n\t\t// depends on inverted and on margins being set\n\t\tchart.pointer = new Pointer(chart, options);\n\n\t\tchart.render();\n\n\t\t// add canvas\n\t\tchart.renderer.draw();\n\t\t// run callbacks\n\t\tif (callback) {\n\t\t\tcallback.apply(chart, [chart]);\n\t\t}\n\t\teach(chart.callbacks, function (fn) {\n\t\t\tfn.apply(chart, [chart]);\n\t\t});\n\t\t\n\t\t\n\t\t// If the chart was rendered outside the top container, put it back in\n\t\tchart.cloneRenderTo(true);\n\n\t\tfireEvent(chart, 'load');\n\n\t},\n\n\t/**\n\t* Creates arrays for spacing and margin from given options.\n\t*/\n\tsplashArray: function (target, options) {\n\t\tvar oVar = options[target],\n\t\t\ttArray = isObject(oVar) ? oVar : [oVar, oVar, oVar, oVar];\n\n\t\treturn [pick(options[target + 'Top'], tArray[0]),\n\t\t\t\tpick(options[target + 'Right'], tArray[1]),\n\t\t\t\tpick(options[target + 'Bottom'], tArray[2]),\n\t\t\t\tpick(options[target + 'Left'], tArray[3])];\n\t}\n}; // end Chart\n\n// Hook for exporting module\nChart.prototype.callbacks = [];\n/**\n * The Point object and prototype. Inheritable and used as base for PiePoint\n */\nvar Point = function () {};\nPoint.prototype = {\n\n\t/**\n\t * Initialize the point\n\t * @param {Object} series The series object containing this point\n\t * @param {Object} options The data in either number, array or object format\n\t */\n\tinit: function (series, options, x) {\n\n\t\tvar point = this,\n\t\t\tcolors;\n\t\tpoint.series = series;\n\t\tpoint.applyOptions(options, x);\n\t\tpoint.pointAttr = {};\n\n\t\tif (series.options.colorByPoint) {\n\t\t\tcolors = series.options.colors || series.chart.options.colors;\n\t\t\tpoint.color = point.color || colors[series.colorCounter++];\n\t\t\t// loop back to zero\n\t\t\tif (series.colorCounter === colors.length) {\n\t\t\t\tseries.colorCounter = 0;\n\t\t\t}\n\t\t}\n\n\t\tseries.chart.pointCount++;\n\t\treturn point;\n\t},\n\t/**\n\t * Apply the options containing the x and y data and possible some extra properties.\n\t * This is called on point init or from point.update.\n\t *\n\t * @param {Object} options\n\t */\n\tapplyOptions: function (options, x) {\n\t\tvar point = this,\n\t\t\tseries = point.series,\n\t\t\tpointValKey = series.pointValKey;\n\n\t\toptions = Point.prototype.optionsToObject.call(this, options);\n\n\t\t// copy options directly to point\n\t\textend(point, options);\n\t\tpoint.options = point.options ? extend(point.options, options) : options;\n\t\t\t\n\t\t// For higher dimension series types. For instance, for ranges, point.y is mapped to point.low.\n\t\tif (pointValKey) {\n\t\t\tpoint.y = point[pointValKey];\n\t\t}\n\t\t\n\t\t// If no x is set by now, get auto incremented value. All points must have an\n\t\t// x value, however the y value can be null to create a gap in the series\n\t\tif (point.x === UNDEFINED && series) {\n\t\t\tpoint.x = x === UNDEFINED ? series.autoIncrement() : x;\n\t\t}\n\t\t\n\t\treturn point;\n\t},\n\n\t/**\n\t * Transform number or array configs into objects\n\t */\n\toptionsToObject: function (options) {\n\t\tvar ret,\n\t\t\tseries = this.series,\n\t\t\tpointArrayMap = series.pointArrayMap || ['y'],\n\t\t\tvalueCount = pointArrayMap.length,\n\t\t\tfirstItemType,\n\t\t\ti = 0,\n\t\t\tj = 0;\n\n\t\tif (typeof options === 'number' || options === null) {\n\t\t\tret = { y: options };\n\n\t\t} else if (isArray(options)) {\n\t\t\tret = {};\n\t\t\t// with leading x value\n\t\t\tif (options.length > valueCount) {\n\t\t\t\tfirstItemType = typeof options[0];\n\t\t\t\tif (firstItemType === 'string') {\n\t\t\t\t\tret.name = options[0];\n\t\t\t\t} else if (firstItemType === 'number') {\n\t\t\t\t\tret.x = options[0];\n\t\t\t\t}\n\t\t\t\ti++;\n\t\t\t}\n\t\t\twhile (j < valueCount) {\n\t\t\t\tret[pointArrayMap[j++]] = options[i++];\n\t\t\t}\t\t\t\n\t\t} else if (typeof options === 'object') {\n\t\t\tret = options;\n\n\t\t\t// This is the fastest way to detect if there are individual point dataLabels that need \n\t\t\t// to be considered in drawDataLabels. These can only occur in object configs.\n\t\t\tif (options.dataLabels) {\n\t\t\t\tseries._hasPointLabels = true;\n\t\t\t}\n\n\t\t\t// Same approach as above for markers\n\t\t\tif (options.marker) {\n\t\t\t\tseries._hasPointMarkers = true;\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t},\n\n\t/**\n\t * Destroy a point to clear memory. Its reference still stays in series.data.\n\t */\n\tdestroy: function () {\n\t\tvar point = this,\n\t\t\tseries = point.series,\n\t\t\tchart = series.chart,\n\t\t\thoverPoints = chart.hoverPoints,\n\t\t\tprop;\n\n\t\tchart.pointCount--;\n\n\t\tif (hoverPoints) {\n\t\t\tpoint.setState();\n\t\t\terase(hoverPoints, point);\n\t\t\tif (!hoverPoints.length) {\n\t\t\t\tchart.hoverPoints = null;\n\t\t\t}\n\n\t\t}\n\t\tif (point === chart.hoverPoint) {\n\t\t\tpoint.onMouseOut();\n\t\t}\n\t\t\n\t\t// remove all events\n\t\tif (point.graphic || point.dataLabel) { // removeEvent and destroyElements are performance expensive\n\t\t\tremoveEvent(point);\n\t\t\tpoint.destroyElements();\n\t\t}\n\n\t\tif (point.legendItem) { // pies have legend items\n\t\t\tchart.legend.destroyItem(point);\n\t\t}\n\n\t\tfor (prop in point) {\n\t\t\tpoint[prop] = null;\n\t\t}\n\n\n\t},\n\n\t/**\n\t * Destroy SVG elements associated with the point\n\t */\n\tdestroyElements: function () {\n\t\tvar point = this,\n\t\t\tprops = ['graphic', 'dataLabel', 'dataLabelUpper', 'group', 'connector', 'shadowGroup'],\n\t\t\tprop,\n\t\t\ti = 6;\n\t\twhile (i--) {\n\t\t\tprop = props[i];\n\t\t\tif (point[prop]) {\n\t\t\t\tpoint[prop] = point[prop].destroy();\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Return the configuration hash needed for the data label and tooltip formatters\n\t */\n\tgetLabelConfig: function () {\n\t\tvar point = this;\n\t\treturn {\n\t\t\tx: point.category,\n\t\t\ty: point.y,\n\t\t\tkey: point.name || point.category,\n\t\t\tseries: point.series,\n\t\t\tpoint: point,\n\t\t\tpercentage: point.percentage,\n\t\t\ttotal: point.total || point.stackTotal\n\t\t};\n\t},\n\n\t/**\n\t * Toggle the selection status of a point\n\t * @param {Boolean} selected Whether to select or unselect the point.\n\t * @param {Boolean} accumulate Whether to add to the previous selection. By default,\n\t *     this happens if the control key (Cmd on Mac) was pressed during clicking.\n\t */\n\tselect: function (selected, accumulate) {\n\t\tvar point = this,\n\t\t\tseries = point.series,\n\t\t\tchart = series.chart;\n\n\t\tselected = pick(selected, !point.selected);\n\n\t\t// fire the event with the defalut handler\n\t\tpoint.firePointEvent(selected ? 'select' : 'unselect', { accumulate: accumulate }, function () {\n\t\t\tpoint.selected = point.options.selected = selected;\n\t\t\tseries.options.data[inArray(point, series.data)] = point.options;\n\t\t\t\n\t\t\tpoint.setState(selected && SELECT_STATE);\n\n\t\t\t// unselect all other points unless Ctrl or Cmd + click\n\t\t\tif (!accumulate) {\n\t\t\t\teach(chart.getSelectedPoints(), function (loopPoint) {\n\t\t\t\t\tif (loopPoint.selected && loopPoint !== point) {\n\t\t\t\t\t\tloopPoint.selected = loopPoint.options.selected = false;\n\t\t\t\t\t\tseries.options.data[inArray(loopPoint, series.data)] = loopPoint.options;\n\t\t\t\t\t\tloopPoint.setState(NORMAL_STATE);\n\t\t\t\t\t\tloopPoint.firePointEvent('unselect');\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n\t * Runs on mouse over the point\n\t */\n\tonMouseOver: function (e) {\n\t\tvar point = this,\n\t\t\tseries = point.series,\n\t\t\tchart = series.chart,\n\t\t\ttooltip = chart.tooltip,\n\t\t\thoverPoint = chart.hoverPoint;\n\n\t\t// set normal state to previous series\n\t\tif (hoverPoint && hoverPoint !== point) {\n\t\t\thoverPoint.onMouseOut();\n\t\t}\n\n\t\t// trigger the event\n\t\tpoint.firePointEvent('mouseOver');\n\n\t\t// update the tooltip\n\t\tif (tooltip && (!tooltip.shared || series.noSharedTooltip)) {\n\t\t\ttooltip.refresh(point, e);\n\t\t}\n\n\t\t// hover this\n\t\tpoint.setState(HOVER_STATE);\n\t\tchart.hoverPoint = point;\n\t},\n\t\n\t/**\n\t * Runs on mouse out from the point\n\t */\n\tonMouseOut: function () {\n\t\tvar chart = this.series.chart,\n\t\t\thoverPoints = chart.hoverPoints;\n\t\t\n\t\tif (!hoverPoints || inArray(this, hoverPoints) === -1) { // #887\n\t\t\tthis.firePointEvent('mouseOut');\n\t\n\t\t\tthis.setState();\n\t\t\tchart.hoverPoint = null;\n\t\t}\n\t},\n\n\t/**\n\t * Extendable method for formatting each point's tooltip line\n\t *\n\t * @return {String} A string to be concatenated in to the common tooltip text\n\t */\n\ttooltipFormatter: function (pointFormat) {\n\t\t\n\t\t// Insert options for valueDecimals, valuePrefix, and valueSuffix\n\t\tvar series = this.series,\n\t\t\tseriesTooltipOptions = series.tooltipOptions,\n\t\t\tvalueDecimals = pick(seriesTooltipOptions.valueDecimals, ''),\n\t\t\tvaluePrefix = seriesTooltipOptions.valuePrefix || '',\n\t\t\tvalueSuffix = seriesTooltipOptions.valueSuffix || '';\n\t\t\t\n\t\t// Loop over the point array map and replace unformatted values with sprintf formatting markup\n\t\teach(series.pointArrayMap || ['y'], function (key) {\n\t\t\tkey = '{point.' + key; // without the closing bracket\n\t\t\tif (valuePrefix || valueSuffix) {\n\t\t\t\tpointFormat = pointFormat.replace(key + '}', valuePrefix + key + '}' + valueSuffix);\n\t\t\t}\n\t\t\tpointFormat = pointFormat.replace(key + '}', key + ':,.' + valueDecimals + 'f}');\n\t\t});\n\t\t\n\t\treturn format(pointFormat, {\n\t\t\tpoint: this,\n\t\t\tseries: this.series\n\t\t});\n\t},\n\n\t/**\n\t * Update the point with new options (typically x/y data) and optionally redraw the series.\n\t *\n\t * @param {Object} options Point options as defined in the series.data array\n\t * @param {Boolean} redraw Whether to redraw the chart or wait for an explicit call\n\t * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\n\t *    configuration\n\t *\n\t */\n\tupdate: function (options, redraw, animation) {\n\t\tvar point = this,\n\t\t\tseries = point.series,\n\t\t\tgraphic = point.graphic,\n\t\t\ti,\n\t\t\tdata = series.data,\n\t\t\tchart = series.chart,\n\t\t\tseriesOptions = series.options;\n\n\t\tredraw = pick(redraw, true);\n\n\t\t// fire the event with a default handler of doing the update\n\t\tpoint.firePointEvent('update', { options: options }, function () {\n\n\t\t\tpoint.applyOptions(options);\n\n\t\t\t// update visuals\n\t\t\tif (isObject(options)) {\n\t\t\t\tseries.getAttribs();\n\t\t\t\tif (graphic) {\n\t\t\t\t\tif (options.marker && options.marker.symbol) {\n\t\t\t\t\t\tpoint.graphic = graphic.destroy();\n\t\t\t\t\t} else {\n\t\t\t\t\t\tgraphic.attr(point.pointAttr[point.state || '']);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// record changes in the parallel arrays\n\t\t\ti = inArray(point, data);\n\t\t\tseries.xData[i] = point.x;\n\t\t\tseries.yData[i] = series.toYData ? series.toYData(point) : point.y;\n\t\t\tseries.zData[i] = point.z;\n\t\t\tseriesOptions.data[i] = point.options;\n\n\t\t\t// redraw\n\t\t\tseries.isDirty = series.isDirtyData = true;\n\t\t\tif (!series.fixedBox && series.hasCartesianSeries) { // #1906, #2320\n\t\t\t\tchart.isDirtyBox = true;\n\t\t\t}\n\t\t\t\n\t\t\tif (seriesOptions.legendType === 'point') { // #1831, #1885\n\t\t\t\tchart.legend.destroyItem(point);\n\t\t\t}\n\t\t\tif (redraw) {\n\t\t\t\tchart.redraw(animation);\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n\t * Remove a point and optionally redraw the series and if necessary the axes\n\t * @param {Boolean} redraw Whether to redraw the chart or wait for an explicit call\n\t * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\n\t *    configuration\n\t */\n\tremove: function (redraw, animation) {\n\t\tvar point = this,\n\t\t\tseries = point.series,\n\t\t\tpoints = series.points,\n\t\t\tchart = series.chart,\n\t\t\ti,\n\t\t\tdata = series.data;\n\n\t\tsetAnimation(animation, chart);\n\t\tredraw = pick(redraw, true);\n\n\t\t// fire the event with a default handler of removing the point\n\t\tpoint.firePointEvent('remove', null, function () {\n\n\t\t\t// splice all the parallel arrays\n\t\t\ti = inArray(point, data);\n\t\t\tif (data.length === points.length) {\n\t\t\t\tpoints.splice(i, 1);\t\t\t\n\t\t\t}\n\t\t\tdata.splice(i, 1);\n\t\t\tseries.options.data.splice(i, 1);\n\t\t\tseries.xData.splice(i, 1);\n\t\t\tseries.yData.splice(i, 1);\n\t\t\tseries.zData.splice(i, 1);\n\n\t\t\tpoint.destroy();\n\n\n\t\t\t// redraw\n\t\t\tseries.isDirty = true;\n\t\t\tseries.isDirtyData = true;\n\t\t\tif (redraw) {\n\t\t\t\tchart.redraw();\n\t\t\t}\n\t\t});\n\n\n\t},\n\n\t/**\n\t * Fire an event on the Point object. Must not be renamed to fireEvent, as this\n\t * causes a name clash in MooTools\n\t * @param {String} eventType\n\t * @param {Object} eventArgs Additional event arguments\n\t * @param {Function} defaultFunction Default event handler\n\t */\n\tfirePointEvent: function (eventType, eventArgs, defaultFunction) {\n\t\tvar point = this,\n\t\t\tseries = this.series,\n\t\t\tseriesOptions = series.options;\n\n\t\t// load event handlers on demand to save time on mouseover/out\n\t\tif (seriesOptions.point.events[eventType] || (point.options && point.options.events && point.options.events[eventType])) {\n\t\t\tthis.importEvents();\n\t\t}\n\n\t\t// add default handler if in selection mode\n\t\tif (eventType === 'click' && seriesOptions.allowPointSelect) {\n\t\t\tdefaultFunction = function (event) {\n\t\t\t\t// Control key is for Windows, meta (= Cmd key) for Mac, Shift for Opera\n\t\t\t\tpoint.select(null, event.ctrlKey || event.metaKey || event.shiftKey);\n\t\t\t};\n\t\t}\n\n\t\tfireEvent(this, eventType, eventArgs, defaultFunction);\n\t},\n\t/**\n\t * Import events from the series' and point's options. Only do it on\n\t * demand, to save processing time on hovering.\n\t */\n\timportEvents: function () {\n\t\tif (!this.hasImportedEvents) {\n\t\t\tvar point = this,\n\t\t\t\toptions = merge(point.series.options.point, point.options),\n\t\t\t\tevents = options.events,\n\t\t\t\teventType;\n\n\t\t\tpoint.events = events;\n\n\t\t\tfor (eventType in events) {\n\t\t\t\taddEvent(point, eventType, events[eventType]);\n\t\t\t}\n\t\t\tthis.hasImportedEvents = true;\n\n\t\t}\n\t},\n\n\t/**\n\t * Set the point's state\n\t * @param {String} state\n\t */\n\tsetState: function (state) {\n\t\tvar point = this,\n\t\t\tplotX = point.plotX,\n\t\t\tplotY = point.plotY,\n\t\t\tseries = point.series,\n\t\t\tstateOptions = series.options.states,\n\t\t\tmarkerOptions = defaultPlotOptions[series.type].marker && series.options.marker,\n\t\t\tnormalDisabled = markerOptions && !markerOptions.enabled,\n\t\t\tmarkerStateOptions = markerOptions && markerOptions.states[state],\n\t\t\tstateDisabled = markerStateOptions && markerStateOptions.enabled === false,\n\t\t\tstateMarkerGraphic = series.stateMarkerGraphic,\n\t\t\tpointMarker = point.marker || {},\n\t\t\tchart = series.chart,\n\t\t\tradius,\n\t\t\tnewSymbol,\n\t\t\tpointAttr = point.pointAttr;\n\n\t\tstate = state || NORMAL_STATE; // empty string\n\n\t\tif (\n\t\t\t\t// already has this state\n\t\t\t\tstate === point.state ||\n\t\t\t\t// selected points don't respond to hover\n\t\t\t\t(point.selected && state !== SELECT_STATE) ||\n\t\t\t\t// series' state options is disabled\n\t\t\t\t(stateOptions[state] && stateOptions[state].enabled === false) ||\n\t\t\t\t// point marker's state options is disabled\n\t\t\t\t(state && (stateDisabled || (normalDisabled && !markerStateOptions.enabled)))\n\n\t\t\t) {\n\t\t\treturn;\n\t\t}\n\n\t\t// apply hover styles to the existing point\n\t\tif (point.graphic) {\n\t\t\tradius = markerOptions && point.graphic.symbolName && pointAttr[state].r;\n\t\t\tpoint.graphic.attr(merge(\n\t\t\t\tpointAttr[state],\n\t\t\t\tradius ? { // new symbol attributes (#507, #612)\n\t\t\t\t\tx: plotX - radius,\n\t\t\t\t\ty: plotY - radius,\n\t\t\t\t\twidth: 2 * radius,\n\t\t\t\t\theight: 2 * radius\n\t\t\t\t} : {}\n\t\t\t));\n\t\t} else {\n\t\t\t// if a graphic is not applied to each point in the normal state, create a shared\n\t\t\t// graphic for the hover state\n\t\t\tif (state && markerStateOptions) {\n\t\t\t\tradius = markerStateOptions.radius;\n\t\t\t\tnewSymbol = pointMarker.symbol || series.symbol;\n\n\t\t\t\t// If the point has another symbol than the previous one, throw away the \n\t\t\t\t// state marker graphic and force a new one (#1459)\n\t\t\t\tif (stateMarkerGraphic && stateMarkerGraphic.currentSymbol !== newSymbol) {\t\t\t\t\n\t\t\t\t\tstateMarkerGraphic = stateMarkerGraphic.destroy();\n\t\t\t\t}\n\n\t\t\t\t// Add a new state marker graphic\n\t\t\t\tif (!stateMarkerGraphic) {\n\t\t\t\t\tseries.stateMarkerGraphic = stateMarkerGraphic = chart.renderer.symbol(\n\t\t\t\t\t\tnewSymbol,\n\t\t\t\t\t\tplotX - radius,\n\t\t\t\t\t\tplotY - radius,\n\t\t\t\t\t\t2 * radius,\n\t\t\t\t\t\t2 * radius\n\t\t\t\t\t)\n\t\t\t\t\t.attr(pointAttr[state])\n\t\t\t\t\t.add(series.markerGroup);\n\t\t\t\t\tstateMarkerGraphic.currentSymbol = newSymbol;\n\t\t\t\t\n\t\t\t\t// Move the existing graphic\n\t\t\t\t} else {\n\t\t\t\t\tstateMarkerGraphic.attr({ // #1054\n\t\t\t\t\t\tx: plotX - radius,\n\t\t\t\t\t\ty: plotY - radius\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (stateMarkerGraphic) {\n\t\t\t\tstateMarkerGraphic[state && chart.isInsidePlot(plotX, plotY) ? 'show' : 'hide']();\n\t\t\t}\n\t\t}\n\n\t\tpoint.state = state;\n\t}\n};\n\n/**\n * @classDescription The base function which all other series types inherit from. The data in the series is stored\n * in various arrays.\n *\n * - First, series.options.data contains all the original config options for\n * each point whether added by options or methods like series.addPoint.\n * - Next, series.data contains those values converted to points, but in case the series data length\n * exceeds the cropThreshold, or if the data is grouped, series.data doesn't contain all the points. It\n * only contains the points that have been created on demand.\n * - Then there's series.points that contains all currently visible point objects. In case of cropping,\n * the cropped-away points are not part of this array. The series.points array starts at series.cropStart\n * compared to series.data and series.options.data. If however the series data is grouped, these can't\n * be correlated one to one.\n * - series.xData and series.processedXData contain clean x values, equivalent to series.data and series.points.\n * - series.yData and series.processedYData contain clean x values, equivalent to series.data and series.points.\n *\n * @param {Object} chart\n * @param {Object} options\n */\nvar Series = function () {};\n\nSeries.prototype = {\n\n\tisCartesian: true,\n\ttype: 'line',\n\tpointClass: Point,\n\tsorted: true, // requires the data to be sorted\n\trequireSorting: true,\n\tpointAttrToOptions: { // mapping between SVG attributes and the corresponding options\n\t\tstroke: 'lineColor',\n\t\t'stroke-width': 'lineWidth',\n\t\tfill: 'fillColor',\n\t\tr: 'radius'\n\t},\n\tcolorCounter: 0,\n\tinit: function (chart, options) {\n\t\tvar series = this,\n\t\t\teventType,\n\t\t\tevents,\n\t\t\tchartSeries = chart.series;\n\n\t\tseries.chart = chart;\n\t\tseries.options = options = series.setOptions(options); // merge with plotOptions\n\t\tseries.linkedSeries = [];\n\n\t\t// bind the axes\n\t\tseries.bindAxes();\n\n\t\t// set some variables\n\t\textend(series, {\n\t\t\tname: options.name,\n\t\t\tstate: NORMAL_STATE,\n\t\t\tpointAttr: {},\n\t\t\tvisible: options.visible !== false, // true by default\n\t\t\tselected: options.selected === true // false by default\n\t\t});\n\t\t\n\t\t// special\n\t\tif (useCanVG) {\n\t\t\toptions.animation = false;\n\t\t}\n\n\t\t// register event listeners\n\t\tevents = options.events;\n\t\tfor (eventType in events) {\n\t\t\taddEvent(series, eventType, events[eventType]);\n\t\t}\n\t\tif (\n\t\t\t(events && events.click) ||\n\t\t\t(options.point && options.point.events && options.point.events.click) ||\n\t\t\toptions.allowPointSelect\n\t\t) {\n\t\t\tchart.runTrackerClick = true;\n\t\t}\n\n\t\tseries.getColor();\n\t\tseries.getSymbol();\n\n\t\t// set the data\n\t\tseries.setData(options.data, false);\n\t\t\n\t\t// Mark cartesian\n\t\tif (series.isCartesian) {\n\t\t\tchart.hasCartesianSeries = true;\n\t\t}\n\n\t\t// Register it in the chart\n\t\tchartSeries.push(series);\n\t\tseries._i = chartSeries.length - 1;\n\t\t\n\t\t// Sort series according to index option (#248, #1123)\n\t\tstableSort(chartSeries, function (a, b) {\n\t\t\treturn pick(a.options.index, a._i) - pick(b.options.index, a._i);\n\t\t});\n\t\teach(chartSeries, function (series, i) {\n\t\t\tseries.index = i;\n\t\t\tseries.name = series.name || 'Series ' + (i + 1);\n\t\t});\n\n\t},\n\t\n\t/**\n\t * Set the xAxis and yAxis properties of cartesian series, and register the series\n\t * in the axis.series array\n\t */\n\tbindAxes: function () {\n\t\tvar series = this,\n\t\t\tseriesOptions = series.options,\n\t\t\tchart = series.chart,\n\t\t\taxisOptions;\n\t\t\t\n\t\tif (series.isCartesian) {\n\t\t\t\n\t\t\teach(['xAxis', 'yAxis'], function (AXIS) { // repeat for xAxis and yAxis\n\t\t\t\t\n\t\t\t\teach(chart[AXIS], function (axis) { // loop through the chart's axis objects\n\t\t\t\t\t\n\t\t\t\t\taxisOptions = axis.options;\n\t\t\t\t\t\n\t\t\t\t\t// apply if the series xAxis or yAxis option mathches the number of the \n\t\t\t\t\t// axis, or if undefined, use the first axis\n\t\t\t\t\tif ((seriesOptions[AXIS] === axisOptions.index) ||\n\t\t\t\t\t\t\t(seriesOptions[AXIS] !== UNDEFINED && seriesOptions[AXIS] === axisOptions.id) ||\n\t\t\t\t\t\t\t(seriesOptions[AXIS] === UNDEFINED && axisOptions.index === 0)) {\n\t\t\t\t\t\t\n\t\t\t\t\t\t// register this series in the axis.series lookup\n\t\t\t\t\t\taxis.series.push(series);\n\t\t\t\t\t\t\n\t\t\t\t\t\t// set this series.xAxis or series.yAxis reference\n\t\t\t\t\t\tseries[AXIS] = axis;\n\t\t\t\t\t\t\n\t\t\t\t\t\t// mark dirty for redraw\n\t\t\t\t\t\taxis.isDirty = true;\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\t// The series needs an X and an Y axis\n\t\t\t\tif (!series[AXIS]) {\n\t\t\t\t\terror(18, true);\n\t\t\t\t}\n\n\t\t\t});\n\t\t}\n\t},\n\n\n\t/**\n\t * Return an auto incremented x value based on the pointStart and pointInterval options.\n\t * This is only used if an x value is not given for the point that calls autoIncrement.\n\t */\n\tautoIncrement: function () {\n\t\tvar series = this,\n\t\t\toptions = series.options,\n\t\t\txIncrement = series.xIncrement;\n\n\t\txIncrement = pick(xIncrement, options.pointStart, 0);\n\n\t\tseries.pointInterval = pick(series.pointInterval, options.pointInterval, 1);\n\n\t\tseries.xIncrement = xIncrement + series.pointInterval;\n\t\treturn xIncrement;\n\t},\n\n\t/**\n\t * Divide the series data into segments divided by null values.\n\t */\n\tgetSegments: function () {\n\t\tvar series = this,\n\t\t\tlastNull = -1,\n\t\t\tsegments = [],\n\t\t\ti,\n\t\t\tpoints = series.points,\n\t\t\tpointsLength = points.length;\n\n\t\tif (pointsLength) { // no action required for []\n\t\t\t\n\t\t\t// if connect nulls, just remove null points\n\t\t\tif (series.options.connectNulls) {\n\t\t\t\ti = pointsLength;\n\t\t\t\twhile (i--) {\n\t\t\t\t\tif (points[i].y === null) {\n\t\t\t\t\t\tpoints.splice(i, 1);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (points.length) {\n\t\t\t\t\tsegments = [points];\n\t\t\t\t}\n\t\t\t\t\n\t\t\t// else, split on null points\n\t\t\t} else {\n\t\t\t\teach(points, function (point, i) {\n\t\t\t\t\tif (point.y === null) {\n\t\t\t\t\t\tif (i > lastNull + 1) {\n\t\t\t\t\t\t\tsegments.push(points.slice(lastNull + 1, i));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tlastNull = i;\n\t\t\t\t\t} else if (i === pointsLength - 1) { // last value\n\t\t\t\t\t\tsegments.push(points.slice(lastNull + 1, i + 1));\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\t\t\n\t\t// register it\n\t\tseries.segments = segments;\n\t},\n\t\n\t/**\n\t * Set the series options by merging from the options tree\n\t * @param {Object} itemOptions\n\t */\n\tsetOptions: function (itemOptions) {\n\t\tvar chart = this.chart,\n\t\t\tchartOptions = chart.options,\n\t\t\tplotOptions = chartOptions.plotOptions,\n\t\t\ttypeOptions = plotOptions[this.type],\n\t\t\toptions;\n\n\t\tthis.userOptions = itemOptions;\n\n\t\toptions = merge(\n\t\t\ttypeOptions,\n\t\t\tplotOptions.series,\n\t\t\titemOptions\n\t\t);\n\t\t\n\t\t// the tooltip options are merged between global and series specific options\n\t\tthis.tooltipOptions = merge(chartOptions.tooltip, options.tooltip);\n\t\t\n\t\t// Delte marker object if not allowed (#1125)\n\t\tif (typeOptions.marker === null) {\n\t\t\tdelete options.marker;\n\t\t}\n\t\t\n\t\treturn options;\n\n\t},\n\t/**\n\t * Get the series' color\n\t */\n\tgetColor: function () {\n\t\tvar options = this.options,\n\t\t\tuserOptions = this.userOptions,\n\t\t\tdefaultColors = this.chart.options.colors,\n\t\t\tcounters = this.chart.counters,\n\t\t\tcolor,\n\t\t\tcolorIndex;\n\n\t\tcolor = options.color || defaultPlotOptions[this.type].color;\n\n\t\tif (!color && !options.colorByPoint) {\n\t\t\tif (defined(userOptions._colorIndex)) { // after Series.update()\n\t\t\t\tcolorIndex = userOptions._colorIndex;\n\t\t\t} else {\n\t\t\t\tuserOptions._colorIndex = counters.color;\n\t\t\t\tcolorIndex = counters.color++;\n\t\t\t}\n\t\t\tcolor = defaultColors[colorIndex];\n\t\t}\n\t\t\n\t\tthis.color = color;\n\t\tcounters.wrapColor(defaultColors.length);\n\t},\n\t/**\n\t * Get the series' symbol\n\t */\n\tgetSymbol: function () {\n\t\tvar series = this,\n\t\t\tuserOptions = series.userOptions,\n\t\t\tseriesMarkerOption = series.options.marker,\n\t\t\tchart = series.chart,\n\t\t\tdefaultSymbols = chart.options.symbols,\n\t\t\tcounters = chart.counters,\n\t\t\tsymbolIndex;\n\n\t\tseries.symbol = seriesMarkerOption.symbol;\n\t\tif (!series.symbol) {\n\t\t\tif (defined(userOptions._symbolIndex)) { // after Series.update()\n\t\t\t\tsymbolIndex = userOptions._symbolIndex;\n\t\t\t} else {\n\t\t\t\tuserOptions._symbolIndex = counters.symbol;\n\t\t\t\tsymbolIndex = counters.symbol++;\n\t\t\t}\n\t\t\tseries.symbol = defaultSymbols[symbolIndex];\n\t\t}\n\n\t\t// don't substract radius in image symbols (#604)\n\t\tif (/^url/.test(series.symbol)) {\n\t\t\tseriesMarkerOption.radius = 0;\n\t\t}\n\t\tcounters.wrapSymbol(defaultSymbols.length);\n\t},\n\n\t/**\n\t * Get the series' symbol in the legend. This method should be overridable to create custom \n\t * symbols through Highcharts.seriesTypes[type].prototype.drawLegendSymbols.\n\t * \n\t * @param {Object} legend The legend object\n\t */\n\tdrawLegendSymbol: function (legend) {\n\t\t\n\t\tvar options = this.options,\n\t\t\tmarkerOptions = options.marker,\n\t\t\tradius,\n\t\t\tlegendOptions = legend.options,\n\t\t\tlegendSymbol,\n\t\t\tsymbolWidth = legendOptions.symbolWidth,\n\t\t\trenderer = this.chart.renderer,\n\t\t\tlegendItemGroup = this.legendGroup,\n\t\t\tverticalCenter = legend.baseline - mathRound(renderer.fontMetrics(legendOptions.itemStyle.fontSize).b * 0.3),\n\t\t\tattr;\n\t\t\t\n\t\t// Draw the line\n\t\tif (options.lineWidth) {\n\t\t\tattr = {\n\t\t\t\t'stroke-width': options.lineWidth\n\t\t\t};\n\t\t\tif (options.dashStyle) {\n\t\t\t\tattr.dashstyle = options.dashStyle;\n\t\t\t}\n\t\t\tthis.legendLine = renderer.path([\n\t\t\t\tM,\n\t\t\t\t0,\n\t\t\t\tverticalCenter,\n\t\t\t\tL,\n\t\t\t\tsymbolWidth,\n\t\t\t\tverticalCenter\n\t\t\t])\n\t\t\t.attr(attr)\n\t\t\t.add(legendItemGroup);\n\t\t}\n\t\t\n\t\t// Draw the marker\n\t\tif (markerOptions && markerOptions.enabled) {\n\t\t\tradius = markerOptions.radius;\n\t\t\tthis.legendSymbol = legendSymbol = renderer.symbol(\n\t\t\t\tthis.symbol,\n\t\t\t\t(symbolWidth / 2) - radius,\n\t\t\t\tverticalCenter - radius,\n\t\t\t\t2 * radius,\n\t\t\t\t2 * radius\n\t\t\t)\n\t\t\t.add(legendItemGroup);\n\t\t\tlegendSymbol.isMarker = true;\n\t\t}\n\t},\n\n\t/**\n\t * Add a point dynamically after chart load time\n\t * @param {Object} options Point options as given in series.data\n\t * @param {Boolean} redraw Whether to redraw the chart or wait for an explicit call\n\t * @param {Boolean} shift If shift is true, a point is shifted off the start\n\t *    of the series as one is appended to the end.\n\t * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\n\t *    configuration\n\t */\n\taddPoint: function (options, redraw, shift, animation) {\n\t\tvar series = this,\n\t\t\tseriesOptions = series.options,\n\t\t\tdata = series.data,\n\t\t\tgraph = series.graph,\n\t\t\tarea = series.area,\n\t\t\tchart = series.chart,\n\t\t\txData = series.xData,\n\t\t\tyData = series.yData,\n\t\t\tzData = series.zData,\n\t\t\tnames = series.names,\n\t\t\tcurrentShift = (graph && graph.shift) || 0,\n\t\t\tdataOptions = seriesOptions.data,\n\t\t\tpoint,\n\t\t\tisInTheMiddle,\n\t\t\tx,\n\t\t\ti;\n\n\t\tsetAnimation(animation, chart);\n\n\t\t// Make graph animate sideways\n\t\tif (shift) {\n\t\t\teach([graph, area, series.graphNeg, series.areaNeg], function (shape) {\n\t\t\t\tif (shape) {\n\t\t\t\t\tshape.shift = currentShift + 1;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tif (area) {\n\t\t\tarea.isArea = true; // needed in animation, both with and without shift\n\t\t}\n\t\t\n\t\t// Optional redraw, defaults to true\n\t\tredraw = pick(redraw, true);\n\n\t\t// Get options and push the point to xData, yData and series.options. In series.generatePoints\n\t\t// the Point instance will be created on demand and pushed to the series.data array.\n\t\tpoint = { series: series };\n\t\tseries.pointClass.prototype.applyOptions.apply(point, [options]);\n\t\tx = point.x;\n\n\t\t// Get the insertion point\n\t\ti = xData.length;\n\t\tif (series.requireSorting && x < xData[i - 1]) {\n\t\t\tisInTheMiddle = true;\n\t\t\twhile (i && xData[i - 1] > x) {\n\t\t\t\ti--;\n\t\t\t}\n\t\t}\n\t\t\n\t\txData.splice(i, 0, x);\n\t\tyData.splice(i, 0, series.toYData ? series.toYData(point) : point.y);\n\t\tzData.splice(i, 0, point.z);\n\t\tif (names) {\n\t\t\tnames[x] = point.name;\n\t\t}\n\t\tdataOptions.splice(i, 0, options);\n\n\t\tif (isInTheMiddle) {\n\t\t\tseries.data.splice(i, 0, null);\n\t\t\tseries.processData();\n\t\t}\n\t\t\n\t\t// Generate points to be added to the legend (#1329) \n\t\tif (seriesOptions.legendType === 'point') {\n\t\t\tseries.generatePoints();\n\t\t}\n\n\t\t// Shift the first point off the parallel arrays\n\t\t// todo: consider series.removePoint(i) method\n\t\tif (shift) {\n\t\t\tif (data[0] && data[0].remove) {\n\t\t\t\tdata[0].remove(false);\n\t\t\t} else {\n\t\t\t\tdata.shift();\n\t\t\t\txData.shift();\n\t\t\t\tyData.shift();\n\t\t\t\tzData.shift();\n\t\t\t\tdataOptions.shift();\n\t\t\t}\n\t\t}\n\n\t\t// redraw\n\t\tseries.isDirty = true;\n\t\tseries.isDirtyData = true;\n\t\tif (redraw) {\n\t\t\tseries.getAttribs(); // #1937\n\t\t\tchart.redraw();\n\t\t}\n\t},\n\n\t/**\n\t * Replace the series data with a new set of data\n\t * @param {Object} data\n\t * @param {Object} redraw\n\t */\n\tsetData: function (data, redraw) {\n\t\tvar series = this,\n\t\t\toldData = series.points,\n\t\t\toptions = series.options,\n\t\t\tchart = series.chart,\n\t\t\tfirstPoint = null,\n\t\t\txAxis = series.xAxis,\n\t\t\tnames = xAxis && xAxis.categories && !xAxis.categories.length ? [] : null,\n\t\t\ti;\n\n\t\t// reset properties\n\t\tseries.xIncrement = null;\n\t\tseries.pointRange = xAxis && xAxis.categories ? 1 : options.pointRange;\n\n\t\tseries.colorCounter = 0; // for series with colorByPoint (#1547)\n\t\t\n\t\t// parallel arrays\n\t\tvar xData = [],\n\t\t\tyData = [],\n\t\t\tzData = [],\n\t\t\tdataLength = data ? data.length : [],\n\t\t\tturboThreshold = pick(options.turboThreshold, 1000),\n\t\t\tpt,\n\t\t\tpointArrayMap = series.pointArrayMap,\n\t\t\tvalueCount = pointArrayMap && pointArrayMap.length,\n\t\t\thasToYData = !!series.toYData;\n\n\t\t// In turbo mode, only one- or twodimensional arrays of numbers are allowed. The\n\t\t// first value is tested, and we assume that all the rest are defined the same\n\t\t// way. Although the 'for' loops are similar, they are repeated inside each\n\t\t// if-else conditional for max performance.\n\t\tif (turboThreshold && dataLength > turboThreshold) { \n\t\t\t\n\t\t\t// find the first non-null point\n\t\t\ti = 0;\n\t\t\twhile (firstPoint === null && i < dataLength) {\n\t\t\t\tfirstPoint = data[i];\n\t\t\t\ti++;\n\t\t\t}\n\t\t\n\t\t\n\t\t\tif (isNumber(firstPoint)) { // assume all points are numbers\n\t\t\t\tvar x = pick(options.pointStart, 0),\n\t\t\t\t\tpointInterval = pick(options.pointInterval, 1);\n\n\t\t\t\tfor (i = 0; i < dataLength; i++) {\n\t\t\t\t\txData[i] = x;\n\t\t\t\t\tyData[i] = data[i];\n\t\t\t\t\tx += pointInterval;\n\t\t\t\t}\n\t\t\t\tseries.xIncrement = x;\n\t\t\t} else if (isArray(firstPoint)) { // assume all points are arrays\n\t\t\t\tif (valueCount) { // [x, low, high] or [x, o, h, l, c]\n\t\t\t\t\tfor (i = 0; i < dataLength; i++) {\n\t\t\t\t\t\tpt = data[i];\n\t\t\t\t\t\txData[i] = pt[0];\n\t\t\t\t\t\tyData[i] = pt.slice(1, valueCount + 1);\n\t\t\t\t\t}\n\t\t\t\t} else { // [x, y]\n\t\t\t\t\tfor (i = 0; i < dataLength; i++) {\n\t\t\t\t\t\tpt = data[i];\n\t\t\t\t\t\txData[i] = pt[0];\n\t\t\t\t\t\tyData[i] = pt[1];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\terror(12); // Highcharts expects configs to be numbers or arrays in turbo mode\n\t\t\t}\n\t\t} else {\n\t\t\tfor (i = 0; i < dataLength; i++) {\n\t\t\t\tif (data[i] !== UNDEFINED) { // stray commas in oldIE\n\t\t\t\t\tpt = { series: series };\n\t\t\t\t\tseries.pointClass.prototype.applyOptions.apply(pt, [data[i]]);\n\t\t\t\t\txData[i] = pt.x;\n\t\t\t\t\tyData[i] = hasToYData ? series.toYData(pt) : pt.y;\n\t\t\t\t\tzData[i] = pt.z;\n\t\t\t\t\tif (names && pt.name) {\n\t\t\t\t\t\tnames[pt.x] = pt.name; // #2046\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Forgetting to cast strings to numbers is a common caveat when handling CSV or JSON\t\t\n\t\tif (isString(yData[0])) {\n\t\t\terror(14, true);\n\t\t} \n\n\t\tseries.data = [];\n\t\tseries.options.data = data;\n\t\tseries.xData = xData;\n\t\tseries.yData = yData;\n\t\tseries.zData = zData;\n\t\tseries.names = names;\n\n\t\t// destroy old points\n\t\ti = (oldData && oldData.length) || 0;\n\t\twhile (i--) {\n\t\t\tif (oldData[i] && oldData[i].destroy) {\n\t\t\t\toldData[i].destroy();\n\t\t\t}\n\t\t}\n\n\t\t// reset minRange (#878)\n\t\tif (xAxis) {\n\t\t\txAxis.minRange = xAxis.userMinRange;\n\t\t}\n\n\t\t// redraw\n\t\tseries.isDirty = series.isDirtyData = chart.isDirtyBox = true;\n\t\tif (pick(redraw, true)) {\n\t\t\tchart.redraw(false);\n\t\t}\n\t},\n\n\t/**\n\t * Remove a series and optionally redraw the chart\n\t *\n\t * @param {Boolean} redraw Whether to redraw the chart or wait for an explicit call\n\t * @param {Boolean|Object} animation Whether to apply animation, and optionally animation\n\t *    configuration\n\t */\n\n\tremove: function (redraw, animation) {\n\t\tvar series = this,\n\t\t\tchart = series.chart;\n\t\tredraw = pick(redraw, true);\n\n\t\tif (!series.isRemoving) {  /* prevent triggering native event in jQuery\n\t\t\t\t(calling the remove function from the remove event) */\n\t\t\tseries.isRemoving = true;\n\n\t\t\t// fire the event with a default handler of removing the point\n\t\t\tfireEvent(series, 'remove', null, function () {\n\n\n\t\t\t\t// destroy elements\n\t\t\t\tseries.destroy();\n\n\n\t\t\t\t// redraw\n\t\t\t\tchart.isDirtyLegend = chart.isDirtyBox = true;\n\t\t\t\tchart.linkSeries();\n\t\t\t\t\n\t\t\t\tif (redraw) {\n\t\t\t\t\tchart.redraw(animation);\n\t\t\t\t}\n\t\t\t});\n\n\t\t}\n\t\tseries.isRemoving = false;\n\t},\n\n\t/**\n\t * Process the data by cropping away unused data points if the series is longer\n\t * than the crop threshold. This saves computing time for lage series.\n\t */\n\tprocessData: function (force) {\n\t\tvar series = this,\n\t\t\tprocessedXData = series.xData, // copied during slice operation below\n\t\t\tprocessedYData = series.yData,\n\t\t\tdataLength = processedXData.length,\n\t\t\tcroppedData,\n\t\t\tcropStart = 0,\n\t\t\tcropped,\n\t\t\tdistance,\n\t\t\tclosestPointRange,\n\t\t\txAxis = series.xAxis,\n\t\t\ti, // loop variable\n\t\t\toptions = series.options,\n\t\t\tcropThreshold = options.cropThreshold,\n\t\t\tisCartesian = series.isCartesian;\n\n\t\t// If the series data or axes haven't changed, don't go through this. Return false to pass\n\t\t// the message on to override methods like in data grouping. \n\t\tif (isCartesian && !series.isDirty && !xAxis.isDirty && !series.yAxis.isDirty && !force) {\n\t\t\treturn false;\n\t\t}\n\t\t\n\n\t\t// optionally filter out points outside the plot area\n\t\tif (isCartesian && series.sorted && (!cropThreshold || dataLength > cropThreshold || series.forceCrop)) {\n\t\t\tvar min = xAxis.min,\n\t\t\t\tmax = xAxis.max;\n\n\t\t\t// it's outside current extremes\n\t\t\tif (processedXData[dataLength - 1] < min || processedXData[0] > max) {\n\t\t\t\tprocessedXData = [];\n\t\t\t\tprocessedYData = [];\n\t\t\t\n\t\t\t// only crop if it's actually spilling out\n\t\t\t} else if (processedXData[0] < min || processedXData[dataLength - 1] > max) {\n\t\t\t\tcroppedData = this.cropData(series.xData, series.yData, min, max);\n\t\t\t\tprocessedXData = croppedData.xData;\n\t\t\t\tprocessedYData = croppedData.yData;\n\t\t\t\tcropStart = croppedData.start;\n\t\t\t\tcropped = true;\n\t\t\t}\n\t\t}\n\t\t\n\t\t\n\t\t// Find the closest distance between processed points\n\t\tfor (i = processedXData.length - 1; i >= 0; i--) {\n\t\t\tdistance = processedXData[i] - processedXData[i - 1];\n\t\t\tif (distance > 0 && (closestPointRange === UNDEFINED || distance < closestPointRange)) {\n\t\t\t\tclosestPointRange = distance;\n\n\t\t\t// Unsorted data is not supported by the line tooltip, as well as data grouping and \n\t\t\t// navigation in Stock charts (#725) and width calculation of columns (#1900)\n\t\t\t} else if (distance < 0 && series.requireSorting) {\n\t\t\t\terror(15);\n\t\t\t}\n\t\t}\n\n\t\t// Record the properties\n\t\tseries.cropped = cropped; // undefined or true\n\t\tseries.cropStart = cropStart;\n\t\tseries.processedXData = processedXData;\n\t\tseries.processedYData = processedYData;\n\n\t\tif (options.pointRange === null) { // null means auto, as for columns, candlesticks and OHLC\n\t\t\tseries.pointRange = closestPointRange || 1;\n\t\t}\n\t\tseries.closestPointRange = closestPointRange;\n\t\t\n\t},\n\n\t/**\n\t * Iterate over xData and crop values between min and max. Returns object containing crop start/end\n\t * cropped xData with corresponding part of yData, dataMin and dataMax within the cropped range\n\t */\n\tcropData: function (xData, yData, min, max) {\n\t\tvar dataLength = xData.length,\n\t\t\tcropStart = 0,\n\t\t\tcropEnd = dataLength,\n\t\t\tcropShoulder = pick(this.cropShoulder, 1), // line-type series need one point outside\n\t\t\ti;\n\n\t\t// iterate up to find slice start\n\t\tfor (i = 0; i < dataLength; i++) {\n\t\t\tif (xData[i] >= min) {\n\t\t\t\tcropStart = mathMax(0, i - cropShoulder);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// proceed to find slice end\n\t\tfor (; i < dataLength; i++) {\n\t\t\tif (xData[i] > max) {\n\t\t\t\tcropEnd = i + cropShoulder;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn {\n\t\t\txData: xData.slice(cropStart, cropEnd),\n\t\t\tyData: yData.slice(cropStart, cropEnd),\n\t\t\tstart: cropStart,\n\t\t\tend: cropEnd\n\t\t};\n\t},\n\n\n\t/**\n\t * Generate the data point after the data has been processed by cropping away\n\t * unused points and optionally grouped in Highcharts Stock.\n\t */\n\tgeneratePoints: function () {\n\t\tvar series = this,\n\t\t\toptions = series.options,\n\t\t\tdataOptions = options.data,\n\t\t\tdata = series.data,\n\t\t\tdataLength,\n\t\t\tprocessedXData = series.processedXData,\n\t\t\tprocessedYData = series.processedYData,\n\t\t\tpointClass = series.pointClass,\n\t\t\tprocessedDataLength = processedXData.length,\n\t\t\tcropStart = series.cropStart || 0,\n\t\t\tcursor,\n\t\t\thasGroupedData = series.hasGroupedData,\n\t\t\tpoint,\n\t\t\tpoints = [],\n\t\t\ti;\n\n\t\tif (!data && !hasGroupedData) {\n\t\t\tvar arr = [];\n\t\t\tarr.length = dataOptions.length;\n\t\t\tdata = series.data = arr;\n\t\t}\n\n\t\tfor (i = 0; i < processedDataLength; i++) {\n\t\t\tcursor = cropStart + i;\n\t\t\tif (!hasGroupedData) {\n\t\t\t\tif (data[cursor]) {\n\t\t\t\t\tpoint = data[cursor];\n\t\t\t\t} else if (dataOptions[cursor] !== UNDEFINED) { // #970\n\t\t\t\t\tdata[cursor] = point = (new pointClass()).init(series, dataOptions[cursor], processedXData[i]);\n\t\t\t\t}\n\t\t\t\tpoints[i] = point;\n\t\t\t} else {\n\t\t\t\t// splat the y data in case of ohlc data array\n\t\t\t\tpoints[i] = (new pointClass()).init(series, [processedXData[i]].concat(splat(processedYData[i])));\n\t\t\t}\n\t\t}\n\n\t\t// Hide cropped-away points - this only runs when the number of points is above cropThreshold, or when\n\t\t// swithching view from non-grouped data to grouped data (#637)\t\n\t\tif (data && (processedDataLength !== (dataLength = data.length) || hasGroupedData)) {\n\t\t\tfor (i = 0; i < dataLength; i++) {\n\t\t\t\tif (i === cropStart && !hasGroupedData) { // when has grouped data, clear all points\n\t\t\t\t\ti += processedDataLength;\n\t\t\t\t}\n\t\t\t\tif (data[i]) {\n\t\t\t\t\tdata[i].destroyElements();\n\t\t\t\t\tdata[i].plotX = UNDEFINED; // #1003\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tseries.data = data;\n\t\tseries.points = points;\n\t},\n\n\t/**\n\t * Adds series' points value to corresponding stack\n\t */\n\tsetStackedPoints: function () {\n\t\tif (!this.options.stacking || (this.visible !== true && this.chart.options.chart.ignoreHiddenSeries !== false)) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar series = this,\n\t\t\txData = series.processedXData,\n\t\t\tyData = series.processedYData,\n\t\t\tstackedYData = [],\n\t\t\tyDataLength = yData.length,\n\t\t\tseriesOptions = series.options,\n\t\t\tthreshold = seriesOptions.threshold,\n\t\t\tstackOption = seriesOptions.stack,\n\t\t\tstacking = seriesOptions.stacking,\n\t\t\tstackKey = series.stackKey,\n\t\t\tnegKey = '-' + stackKey,\n\t\t\tnegStacks = series.negStacks,\n\t\t\tyAxis = series.yAxis,\n\t\t\tstacks = yAxis.stacks,\n\t\t\toldStacks = yAxis.oldStacks,\n\t\t\tisNegative,\n\t\t\tstack,\n\t\t\tother,\n\t\t\tkey,\n\t\t\ti,\n\t\t\tx,\n\t\t\ty;\n\n\t\t// loop over the non-null y values and read them into a local array\n\t\tfor (i = 0; i < yDataLength; i++) {\n\t\t\tx = xData[i];\n\t\t\ty = yData[i];\n\n\t\t\t// Read stacked values into a stack based on the x value,\n\t\t\t// the sign of y and the stack key. Stacking is also handled for null values (#739)\n\t\t\tisNegative = negStacks && y < threshold;\n\t\t\tkey = isNegative ? negKey : stackKey;\n\n\t\t\t// Create empty object for this stack if it doesn't exist yet\n\t\t\tif (!stacks[key]) {\n\t\t\t\tstacks[key] = {};\n\t\t\t}\n\n\t\t\t// Initialize StackItem for this x\n\t\t\tif (!stacks[key][x]) {\n\t\t\t\tif (oldStacks[key] && oldStacks[key][x]) {\n\t\t\t\t\tstacks[key][x] = oldStacks[key][x];\n\t\t\t\t\tstacks[key][x].total = null;\n\t\t\t\t} else {\n\t\t\t\t\tstacks[key][x] = new StackItem(yAxis, yAxis.options.stackLabels, isNegative, x, stackOption, stacking);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// If the StackItem doesn't exist, create it first\n\t\t\tstack = stacks[key][x];\n\t\t\tstack.points[series.index] = [stack.cum || 0];\n\n\t\t\t// Add value to the stack total\n\t\t\tif (stacking === 'percent') {\n\t\t\t\t\n\t\t\t\t// Percent stacked column, totals are the same for the positive and negative stacks\n\t\t\t\tother = isNegative ? stackKey : negKey;\n\t\t\t\tif (negStacks && stacks[other] && stacks[other][x]) {\n\t\t\t\t\tother = stacks[other][x];\n\t\t\t\t\tstack.total = other.total = mathMax(other.total, stack.total) + mathAbs(y) || 0;\n\n\t\t\t\t// Percent stacked areas\t\t\t\t\t\n\t\t\t\t} else {\n\t\t\t\t\tstack.total += mathAbs(y) || 0;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tstack.total += y || 0;\n\t\t\t}\n\n\t\t\tstack.cum = (stack.cum || 0) + (y || 0);\n\n\t\t\tstack.points[series.index].push(stack.cum);\n\t\t\tstackedYData[i] = stack.cum;\n\n\t\t}\n\n\t\tif (stacking === 'percent') {\n\t\t\tyAxis.usePercentage = true;\n\t\t}\n\n\t\tthis.stackedYData = stackedYData; // To be used in getExtremes\n\t\t\n\t\t// Reset old stacks\n\t\tyAxis.oldStacks = {};\n\t},\n\n\t/**\n\t * Iterate over all stacks and compute the absolute values to percent\n\t */\n\tsetPercentStacks: function () {\n\t\tvar series = this,\n\t\t\tstackKey = series.stackKey,\n\t\t\tstacks = series.yAxis.stacks;\n\t\t\n\t\teach([stackKey, '-' + stackKey], function (key) {\n\t\t\tvar i = series.xData.length,\n\t\t\t\tx,\n\t\t\t\tstack,\n\t\t\t\tpointExtremes,\n\t\t\t\ttotalFactor;\n\n\t\t\twhile (i--) {\n\t\t\t\tx = series.xData[i];\n\t\t\t\tstack = stacks[key] && stacks[key][x];\n\t\t\t\tpointExtremes = stack && stack.points[series.index];\n\t\t\t\tif (pointExtremes) {\n\t\t\t\t\ttotalFactor = stack.total ? 100 / stack.total : 0;\n\t\t\t\t\tpointExtremes[0] = correctFloat(pointExtremes[0] * totalFactor); // Y bottom value\n\t\t\t\t\tpointExtremes[1] = correctFloat(pointExtremes[1] * totalFactor); // Y value\n\t\t\t\t\tseries.stackedYData[i] = pointExtremes[1];\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n\t * Calculate Y extremes for visible data\n\t */\n\tgetExtremes: function () {\n\t\tvar xAxis = this.xAxis,\n\t\t\tyAxis = this.yAxis,\n\t\t\txData = this.processedXData,\n\t\t\tyData = this.stackedYData || this.processedYData,\n\t\t\tyDataLength = yData.length,\n\t\t\tactiveYData = [],\n\t\t\tactiveCounter = 0,\n\t\t\txExtremes = xAxis.getExtremes(), // #2117, need to compensate for log X axis\n\t\t\txMin = xExtremes.min,\n\t\t\txMax = xExtremes.max,\n\t\t\tvalidValue,\n\t\t\twithinRange,\n\t\t\tdataMin,\n\t\t\tdataMax,\n\t\t\tx,\n\t\t\ty,\n\t\t\ti,\n\t\t\tj;\n\n\t\tfor (i = 0; i < yDataLength; i++) {\n\t\t\t\n\t\t\tx = xData[i];\n\t\t\ty = yData[i];\n\n\t\t\t// For points within the visible range, including the first point outside the\n\t\t\t// visible range, consider y extremes\n\t\t\tvalidValue = y !== null && y !== UNDEFINED && (!yAxis.isLog || (y.length || y > 0));\n\t\t\twithinRange = this.getExtremesFromAll || this.cropped || ((xData[i + 1] || x) >= xMin && \n\t\t\t\t(xData[i - 1] || x) <= xMax);\n\n\t\t\tif (validValue && withinRange) {\n\n\t\t\t\tj = y.length;\n\t\t\t\tif (j) { // array, like ohlc or range data\n\t\t\t\t\twhile (j--) {\n\t\t\t\t\t\tif (y[j] !== null) {\n\t\t\t\t\t\t\tactiveYData[activeCounter++] = y[j];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tactiveYData[activeCounter++] = y;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tthis.dataMin = pick(dataMin, arrayMin(activeYData));\n\t\tthis.dataMax = pick(dataMax, arrayMax(activeYData));\n\t},\n\n\t/**\n\t * Translate data points from raw data values to chart specific positioning data\n\t * needed later in drawPoints, drawGraph and drawTracker.\n\t */\n\ttranslate: function () {\n\t\tif (!this.processedXData) { // hidden series\n\t\t\tthis.processData();\n\t\t}\n\t\tthis.generatePoints();\n\t\tvar series = this,\n\t\t\toptions = series.options,\n\t\t\tstacking = options.stacking,\n\t\t\txAxis = series.xAxis,\n\t\t\tcategories = xAxis.categories,\n\t\t\tyAxis = series.yAxis,\n\t\t\tpoints = series.points,\n\t\t\tdataLength = points.length,\n\t\t\thasModifyValue = !!series.modifyValue,\n\t\t\ti,\n\t\t\tpointPlacement = options.pointPlacement,\n\t\t\tdynamicallyPlaced = pointPlacement === 'between' || isNumber(pointPlacement),\n\t\t\tthreshold = options.threshold;\n\n\t\t\n\t\t// Translate each point\n\t\tfor (i = 0; i < dataLength; i++) {\n\t\t\tvar point = points[i],\n\t\t\t\txValue = point.x,\n\t\t\t\tyValue = point.y,\n\t\t\t\tyBottom = point.low,\n\t\t\t\tstack = yAxis.stacks[(series.negStacks && yValue < threshold ? '-' : '') + series.stackKey],\n\t\t\t\tpointStack,\n\t\t\t\tstackValues;\n\n\t\t\t// Discard disallowed y values for log axes\n\t\t\tif (yAxis.isLog && yValue <= 0) {\n\t\t\t\tpoint.y = yValue = null;\n\t\t\t}\n\t\t\t\n\t\t\t// Get the plotX translation\n\t\t\tpoint.plotX = xAxis.translate(xValue, 0, 0, 0, 1, pointPlacement, this.type === 'flags'); // Math.round fixes #591\n\t\t\t\n\n\t\t\t// Calculate the bottom y value for stacked series\n\t\t\tif (stacking && series.visible && stack && stack[xValue]) {\n\n\t\t\t\tpointStack = stack[xValue];\n\t\t\t\tstackValues = pointStack.points[series.index];\n\t\t\t\tyBottom = stackValues[0];\n\t\t\t\tyValue = stackValues[1];\n\n\t\t\t\tif (yBottom === 0) {\n\t\t\t\t\tyBottom = pick(threshold, yAxis.min);\n\t\t\t\t}\n\t\t\t\tif (yAxis.isLog && yBottom <= 0) { // #1200, #1232\n\t\t\t\t\tyBottom = null;\n\t\t\t\t}\n\n\t\t\t\tpoint.percentage = stacking === 'percent' && yValue;\n\t\t\t\tpoint.total = point.stackTotal = pointStack.total;\n\t\t\t\tpoint.stackY = yValue;\n\n\t\t\t\t// Place the stack label\n\t\t\t\tpointStack.setOffset(series.pointXOffset || 0, series.barW || 0);\n\t\t\t\t\n\t\t\t}\n\n\t\t\t// Set translated yBottom or remove it\n\t\t\tpoint.yBottom = defined(yBottom) ? \n\t\t\t\tyAxis.translate(yBottom, 0, 1, 0, 1) :\n\t\t\t\tnull;\n\t\t\t\t\n\t\t\t// general hook, used for Highstock compare mode\n\t\t\tif (hasModifyValue) {\n\t\t\t\tyValue = series.modifyValue(yValue, point);\n\t\t\t}\n\n\t\t\t// Set the the plotY value, reset it for redraws\n\t\t\tpoint.plotY = (typeof yValue === 'number' && yValue !== Infinity) ? \n\t\t\t\t//mathRound(yAxis.translate(yValue, 0, 1, 0, 1) * 10) / 10 : // Math.round fixes #591\n\t\t\t\tyAxis.translate(yValue, 0, 1, 0, 1) : \n\t\t\t\tUNDEFINED;\n\t\t\t\n\t\t\t// Set client related positions for mouse tracking\n\t\t\tpoint.clientX = dynamicallyPlaced ? xAxis.translate(xValue, 0, 0, 0, 1) : point.plotX; // #1514\n\t\t\t\t\n\t\t\tpoint.negative = point.y < (threshold || 0);\n\n\t\t\t// some API data\n\t\t\tpoint.category = categories && categories[point.x] !== UNDEFINED ?\n\t\t\t\tcategories[point.x] : point.x;\n\n\n\t\t}\n\n\t\t// now that we have the cropped data, build the segments\n\t\tseries.getSegments();\n\t},\n\t/**\n\t * Memoize tooltip texts and positions\n\t */\n\tsetTooltipPoints: function (renew) {\n\t\tvar series = this,\n\t\t\tpoints = [],\n\t\t\tpointsLength,\n\t\t\tlow,\n\t\t\thigh,\n\t\t\txAxis = series.xAxis,\n\t\t\txExtremes = xAxis && xAxis.getExtremes(),\n\t\t\taxisLength = xAxis ? (xAxis.tooltipLen || xAxis.len) : series.chart.plotSizeX, // tooltipLen and tooltipPosName used in polar\n\t\t\tpoint,\n\t\t\tpointX,\n\t\t\tnextPoint,\n\t\t\ti,\n\t\t\ttooltipPoints = []; // a lookup array for each pixel in the x dimension\n\n\t\t// don't waste resources if tracker is disabled\n\t\tif (series.options.enableMouseTracking === false) {\n\t\t\treturn;\n\t\t}\n\n\t\t// renew\n\t\tif (renew) {\n\t\t\tseries.tooltipPoints = null;\n\t\t}\n\n\t\t// concat segments to overcome null values\n\t\teach(series.segments || series.points, function (segment) {\n\t\t\tpoints = points.concat(segment);\n\t\t});\n\n\t\t// Reverse the points in case the X axis is reversed\n\t\tif (xAxis && xAxis.reversed) {\n\t\t\tpoints = points.reverse();\n\t\t}\n\n\t\t// Polar needs additional shaping\n\t\tif (series.orderTooltipPoints) {\n\t\t\tseries.orderTooltipPoints(points);\n\t\t}\n\n\t\t// Assign each pixel position to the nearest point\n\t\tpointsLength = points.length;\n\t\tfor (i = 0; i < pointsLength; i++) {\n\t\t\tpoint = points[i];\n\t\t\tpointX = point.x;\n\t\t\tif (pointX >= xExtremes.min && pointX <= xExtremes.max) { // #1149\n\t\t\t\tnextPoint = points[i + 1];\n\t\t\t\t\n\t\t\t\t// Set this range's low to the last range's high plus one\n\t\t\t\tlow = high === UNDEFINED ? 0 : high + 1;\n\t\t\t\t// Now find the new high\n\t\t\t\thigh = points[i + 1] ?\n\t\t\t\t\tmathMin(mathMax(0, mathFloor( // #2070\n\t\t\t\t\t\t(point.clientX + (nextPoint ? (nextPoint.wrappedClientX || nextPoint.clientX) : axisLength)) / 2\n\t\t\t\t\t)), axisLength) :\n\t\t\t\t\taxisLength;\n\n\t\t\t\twhile (low >= 0 && low <= high) {\n\t\t\t\t\ttooltipPoints[low++] = point;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tseries.tooltipPoints = tooltipPoints;\n\t},\n\n\t/**\n\t * Format the header of the tooltip\n\t */\n\ttooltipHeaderFormatter: function (point) {\n\t\tvar series = this,\n\t\t\ttooltipOptions = series.tooltipOptions,\n\t\t\txDateFormat = tooltipOptions.xDateFormat,\n\t\t\tdateTimeLabelFormats = tooltipOptions.dateTimeLabelFormats,\n\t\t\txAxis = series.xAxis,\n\t\t\tisDateTime = xAxis && xAxis.options.type === 'datetime',\n\t\t\theaderFormat = tooltipOptions.headerFormat,\n\t\t\tclosestPointRange = xAxis && xAxis.closestPointRange,\n\t\t\tn;\n\t\t\t\n\t\t// Guess the best date format based on the closest point distance (#568)\n\t\tif (isDateTime && !xDateFormat) {\n\t\t\tif (closestPointRange) {\n\t\t\t\tfor (n in timeUnits) {\n\t\t\t\t\tif (timeUnits[n] >= closestPointRange) {\n\t\t\t\t\t\txDateFormat = dateTimeLabelFormats[n];\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\txDateFormat = dateTimeLabelFormats.day;\n\t\t\t}\n\t\t}\n\t\t\n\t\t// Insert the header date format if any\n\t\tif (isDateTime && xDateFormat && isNumber(point.key)) {\n\t\t\theaderFormat = headerFormat.replace('{point.key}', '{point.key:' + xDateFormat + '}');\n\t\t}\n\t\t\n\t\treturn format(headerFormat, {\n\t\t\tpoint: point,\n\t\t\tseries: series\n\t\t});\n\t},\n\n\t/**\n\t * Series mouse over handler\n\t */\n\tonMouseOver: function () {\n\t\tvar series = this,\n\t\t\tchart = series.chart,\n\t\t\thoverSeries = chart.hoverSeries;\n\n\t\t// set normal state to previous series\n\t\tif (hoverSeries && hoverSeries !== series) {\n\t\t\thoverSeries.onMouseOut();\n\t\t}\n\n\t\t// trigger the event, but to save processing time,\n\t\t// only if defined\n\t\tif (series.options.events.mouseOver) {\n\t\t\tfireEvent(series, 'mouseOver');\n\t\t}\n\n\t\t// hover this\n\t\tseries.setState(HOVER_STATE);\n\t\tchart.hoverSeries = series;\n\t},\n\n\t/**\n\t * Series mouse out handler\n\t */\n\tonMouseOut: function () {\n\t\t// trigger the event only if listeners exist\n\t\tvar series = this,\n\t\t\toptions = series.options,\n\t\t\tchart = series.chart,\n\t\t\ttooltip = chart.tooltip,\n\t\t\thoverPoint = chart.hoverPoint;\n\n\t\t// trigger mouse out on the point, which must be in this series\n\t\tif (hoverPoint) {\n\t\t\thoverPoint.onMouseOut();\n\t\t}\n\n\t\t// fire the mouse out event\n\t\tif (series && options.events.mouseOut) {\n\t\t\tfireEvent(series, 'mouseOut');\n\t\t}\n\n\n\t\t// hide the tooltip\n\t\tif (tooltip && !options.stickyTracking && (!tooltip.shared || series.noSharedTooltip)) {\n\t\t\ttooltip.hide();\n\t\t}\n\n\t\t// set normal state\n\t\tseries.setState();\n\t\tchart.hoverSeries = null;\n\t},\n\n\t/**\n\t * Animate in the series\n\t */\n\tanimate: function (init) {\n\t\tvar series = this,\n\t\t\tchart = series.chart,\n\t\t\trenderer = chart.renderer,\n\t\t\tclipRect,\n\t\t\tmarkerClipRect,\n\t\t\tanimation = series.options.animation,\n\t\t\tclipBox = chart.clipBox,\n\t\t\tinverted = chart.inverted,\n\t\t\tsharedClipKey;\n\n\t\t// Animation option is set to true\n\t\tif (animation && !isObject(animation)) {\n\t\t\tanimation = defaultPlotOptions[series.type].animation;\n\t\t}\n\t\tsharedClipKey = '_sharedClip' + animation.duration + animation.easing;\n\n\t\t// Initialize the animation. Set up the clipping rectangle.\n\t\tif (init) { \n\t\t\t\n\t\t\t// If a clipping rectangle with the same properties is currently present in the chart, use that. \n\t\t\tclipRect = chart[sharedClipKey];\n\t\t\tmarkerClipRect = chart[sharedClipKey + 'm'];\n\t\t\tif (!clipRect) {\n\t\t\t\tchart[sharedClipKey] = clipRect = renderer.clipRect(\n\t\t\t\t\textend(clipBox, { width: 0 })\n\t\t\t\t);\n\t\t\t\t\n\t\t\t\tchart[sharedClipKey + 'm'] = markerClipRect = renderer.clipRect(\n\t\t\t\t\t-99, // include the width of the first marker\n\t\t\t\t\tinverted ? -chart.plotLeft : -chart.plotTop, \n\t\t\t\t\t99,\n\t\t\t\t\tinverted ? chart.chartWidth : chart.chartHeight\n\t\t\t\t);\n\t\t\t}\n\t\t\tseries.group.clip(clipRect);\n\t\t\tseries.markerGroup.clip(markerClipRect);\n\t\t\tseries.sharedClipKey = sharedClipKey;\n\n\t\t// Run the animation\n\t\t} else { \n\t\t\tclipRect = chart[sharedClipKey];\n\t\t\tif (clipRect) {\n\t\t\t\tclipRect.animate({\n\t\t\t\t\twidth: chart.plotSizeX\n\t\t\t\t}, animation);\n\t\t\t\tchart[sharedClipKey + 'm'].animate({\n\t\t\t\t\twidth: chart.plotSizeX + 99\n\t\t\t\t}, animation);\n\t\t\t}\n\n\t\t\t// Delete this function to allow it only once\n\t\t\tseries.animate = null;\n\t\t\t\n\t\t\t// Call the afterAnimate function on animation complete (but don't overwrite the animation.complete option\n\t\t\t// which should be available to the user).\n\t\t\tseries.animationTimeout = setTimeout(function () {\n\t\t\t\tseries.afterAnimate();\n\t\t\t}, animation.duration);\n\t\t}\n\t},\n\t\n\t/**\n\t * This runs after animation to land on the final plot clipping\n\t */\n\tafterAnimate: function () {\n\t\tvar chart = this.chart,\n\t\t\tsharedClipKey = this.sharedClipKey,\n\t\t\tgroup = this.group;\n\t\t\t\n\t\tif (group && this.options.clip !== false) {\n\t\t\tgroup.clip(chart.clipRect);\n\t\t\tthis.markerGroup.clip(); // no clip\n\t\t}\n\t\t\n\t\t// Remove the shared clipping rectancgle when all series are shown\t\t\n\t\tsetTimeout(function () {\n\t\t\tif (sharedClipKey && chart[sharedClipKey]) {\n\t\t\t\tchart[sharedClipKey] = chart[sharedClipKey].destroy();\n\t\t\t\tchart[sharedClipKey + 'm'] = chart[sharedClipKey + 'm'].destroy();\n\t\t\t}\n\t\t}, 100);\n\t},\n\n\t/**\n\t * Draw the markers\n\t */\n\tdrawPoints: function () {\n\t\tvar series = this,\n\t\t\tpointAttr,\n\t\t\tpoints = series.points,\n\t\t\tchart = series.chart,\n\t\t\tplotX,\n\t\t\tplotY,\n\t\t\ti,\n\t\t\tpoint,\n\t\t\tradius,\n\t\t\tsymbol,\n\t\t\tisImage,\n\t\t\tgraphic,\n\t\t\toptions = series.options,\n\t\t\tseriesMarkerOptions = options.marker,\n\t\t\tpointMarkerOptions,\n\t\t\tenabled,\n\t\t\tisInside,\n\t\t\tmarkerGroup = series.markerGroup;\n\n\t\tif (seriesMarkerOptions.enabled || series._hasPointMarkers) {\n\t\t\t\n\t\t\ti = points.length;\n\t\t\twhile (i--) {\n\t\t\t\tpoint = points[i];\n\t\t\t\tplotX = mathFloor(point.plotX); // #1843\n\t\t\t\tplotY = point.plotY;\n\t\t\t\tgraphic = point.graphic;\n\t\t\t\tpointMarkerOptions = point.marker || {};\n\t\t\t\tenabled = (seriesMarkerOptions.enabled && pointMarkerOptions.enabled === UNDEFINED) || pointMarkerOptions.enabled;\n\t\t\t\tisInside = chart.isInsidePlot(mathRound(plotX), plotY, chart.inverted); // #1858\n\t\t\t\t\n\t\t\t\t// only draw the point if y is defined\n\t\t\t\tif (enabled && plotY !== UNDEFINED && !isNaN(plotY) && point.y !== null) {\n\n\t\t\t\t\t// shortcuts\n\t\t\t\t\tpointAttr = point.pointAttr[point.selected ? SELECT_STATE : NORMAL_STATE];\n\t\t\t\t\tradius = pointAttr.r;\n\t\t\t\t\tsymbol = pick(pointMarkerOptions.symbol, series.symbol);\n\t\t\t\t\tisImage = symbol.indexOf('url') === 0;\n\n\t\t\t\t\tif (graphic) { // update\n\t\t\t\t\t\tgraphic\n\t\t\t\t\t\t\t.attr({ // Since the marker group isn't clipped, each individual marker must be toggled\n\t\t\t\t\t\t\t\tvisibility: isInside ? (hasSVG ? 'inherit' : VISIBLE) : HIDDEN\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.animate(extend({\n\t\t\t\t\t\t\t\tx: plotX - radius,\n\t\t\t\t\t\t\t\ty: plotY - radius\n\t\t\t\t\t\t\t}, graphic.symbolName ? { // don't apply to image symbols #507\n\t\t\t\t\t\t\t\twidth: 2 * radius,\n\t\t\t\t\t\t\t\theight: 2 * radius\n\t\t\t\t\t\t\t} : {}));\n\t\t\t\t\t} else if (isInside && (radius > 0 || isImage)) {\n\t\t\t\t\t\tpoint.graphic = graphic = chart.renderer.symbol(\n\t\t\t\t\t\t\tsymbol,\n\t\t\t\t\t\t\tplotX - radius,\n\t\t\t\t\t\t\tplotY - radius,\n\t\t\t\t\t\t\t2 * radius,\n\t\t\t\t\t\t\t2 * radius\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.attr(pointAttr)\n\t\t\t\t\t\t.add(markerGroup);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t} else if (graphic) {\n\t\t\t\t\tpoint.graphic = graphic.destroy(); // #1269\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t},\n\n\t/**\n\t * Convert state properties from API naming conventions to SVG attributes\n\t *\n\t * @param {Object} options API options object\n\t * @param {Object} base1 SVG attribute object to inherit from\n\t * @param {Object} base2 Second level SVG attribute object to inherit from\n\t */\n\tconvertAttribs: function (options, base1, base2, base3) {\n\t\tvar conversion = this.pointAttrToOptions,\n\t\t\tattr,\n\t\t\toption,\n\t\t\tobj = {};\n\n\t\toptions = options || {};\n\t\tbase1 = base1 || {};\n\t\tbase2 = base2 || {};\n\t\tbase3 = base3 || {};\n\n\t\tfor (attr in conversion) {\n\t\t\toption = conversion[attr];\n\t\t\tobj[attr] = pick(options[option], base1[attr], base2[attr], base3[attr]);\n\t\t}\n\t\treturn obj;\n\t},\n\n\t/**\n\t * Get the state attributes. Each series type has its own set of attributes\n\t * that are allowed to change on a point's state change. Series wide attributes are stored for\n\t * all series, and additionally point specific attributes are stored for all\n\t * points with individual marker options. If such options are not defined for the point,\n\t * a reference to the series wide attributes is stored in point.pointAttr.\n\t */\n\tgetAttribs: function () {\n\t\tvar series = this,\n\t\t\tseriesOptions = series.options,\n\t\t\tnormalOptions = defaultPlotOptions[series.type].marker ? seriesOptions.marker : seriesOptions,\n\t\t\tstateOptions = normalOptions.states,\n\t\t\tstateOptionsHover = stateOptions[HOVER_STATE],\n\t\t\tpointStateOptionsHover,\n\t\t\tseriesColor = series.color,\n\t\t\tnormalDefaults = {\n\t\t\t\tstroke: seriesColor,\n\t\t\t\tfill: seriesColor\n\t\t\t},\n\t\t\tpoints = series.points || [], // #927\n\t\t\ti,\n\t\t\tpoint,\n\t\t\tseriesPointAttr = [],\n\t\t\tpointAttr,\n\t\t\tpointAttrToOptions = series.pointAttrToOptions,\n\t\t\thasPointSpecificOptions,\n\t\t\tnegativeColor = seriesOptions.negativeColor,\n\t\t\tdefaultLineColor = normalOptions.lineColor,\n\t\t\tkey;\n\n\t\t// series type specific modifications\n\t\tif (seriesOptions.marker) { // line, spline, area, areaspline, scatter\n\n\t\t\t// if no hover radius is given, default to normal radius + 2\n\t\t\tstateOptionsHover.radius = stateOptionsHover.radius || normalOptions.radius + 2;\n\t\t\tstateOptionsHover.lineWidth = stateOptionsHover.lineWidth || normalOptions.lineWidth + 1;\n\t\t\t\n\t\t} else { // column, bar, pie\n\n\t\t\t// if no hover color is given, brighten the normal color\n\t\t\tstateOptionsHover.color = stateOptionsHover.color ||\n\t\t\t\tColor(stateOptionsHover.color || seriesColor)\n\t\t\t\t\t.brighten(stateOptionsHover.brightness).get();\n\t\t}\n\n\t\t// general point attributes for the series normal state\n\t\tseriesPointAttr[NORMAL_STATE] = series.convertAttribs(normalOptions, normalDefaults);\n\n\t\t// HOVER_STATE and SELECT_STATE states inherit from normal state except the default radius\n\t\teach([HOVER_STATE, SELECT_STATE], function (state) {\n\t\t\tseriesPointAttr[state] =\n\t\t\t\t\tseries.convertAttribs(stateOptions[state], seriesPointAttr[NORMAL_STATE]);\n\t\t});\n\n\t\t// set it\n\t\tseries.pointAttr = seriesPointAttr;\n\n\n\t\t// Generate the point-specific attribute collections if specific point\n\t\t// options are given. If not, create a referance to the series wide point\n\t\t// attributes\n\t\ti = points.length;\n\t\twhile (i--) {\n\t\t\tpoint = points[i];\n\t\t\tnormalOptions = (point.options && point.options.marker) || point.options;\n\t\t\tif (normalOptions && normalOptions.enabled === false) {\n\t\t\t\tnormalOptions.radius = 0;\n\t\t\t}\n\t\t\t\n\t\t\tif (point.negative && negativeColor) {\n\t\t\t\tpoint.color = point.fillColor = negativeColor;\n\t\t\t}\n\t\t\t\n\t\t\thasPointSpecificOptions = seriesOptions.colorByPoint || point.color; // #868\n\n\t\t\t// check if the point has specific visual options\n\t\t\tif (point.options) {\n\t\t\t\tfor (key in pointAttrToOptions) {\n\t\t\t\t\tif (defined(normalOptions[pointAttrToOptions[key]])) {\n\t\t\t\t\t\thasPointSpecificOptions = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// a specific marker config object is defined for the individual point:\n\t\t\t// create it's own attribute collection\n\t\t\tif (hasPointSpecificOptions) {\n\t\t\t\tnormalOptions = normalOptions || {};\n\t\t\t\tpointAttr = [];\n\t\t\t\tstateOptions = normalOptions.states || {}; // reassign for individual point\n\t\t\t\tpointStateOptionsHover = stateOptions[HOVER_STATE] = stateOptions[HOVER_STATE] || {};\n\n\t\t\t\t// Handle colors for column and pies\n\t\t\t\tif (!seriesOptions.marker) { // column, bar, point\n\t\t\t\t\t// if no hover color is given, brighten the normal color\n\t\t\t\t\tpointStateOptionsHover.color =\n\t\t\t\t\t\tColor(pointStateOptionsHover.color || point.color)\n\t\t\t\t\t\t\t.brighten(pointStateOptionsHover.brightness ||\n\t\t\t\t\t\t\t\tstateOptionsHover.brightness).get();\n\n\t\t\t\t}\n\n\t\t\t\t// normal point state inherits series wide normal state\n\t\t\t\tpointAttr[NORMAL_STATE] = series.convertAttribs(extend({\n\t\t\t\t\tcolor: point.color, // #868\n\t\t\t\t\tfillColor: point.color, // Individual point color or negative color markers (#2219)\n\t\t\t\t\tlineColor: defaultLineColor === null ? point.color : UNDEFINED // Bubbles take point color, line markers use white\n\t\t\t\t}, normalOptions), seriesPointAttr[NORMAL_STATE]);\n\n\t\t\t\t// inherit from point normal and series hover\n\t\t\t\tpointAttr[HOVER_STATE] = series.convertAttribs(\n\t\t\t\t\tstateOptions[HOVER_STATE],\n\t\t\t\t\tseriesPointAttr[HOVER_STATE],\n\t\t\t\t\tpointAttr[NORMAL_STATE]\n\t\t\t\t);\n\t\t\t\t\n\t\t\t\t// inherit from point normal and series hover\n\t\t\t\tpointAttr[SELECT_STATE] = series.convertAttribs(\n\t\t\t\t\tstateOptions[SELECT_STATE],\n\t\t\t\t\tseriesPointAttr[SELECT_STATE],\n\t\t\t\t\tpointAttr[NORMAL_STATE]\n\t\t\t\t);\n\n\n\t\t\t// no marker config object is created: copy a reference to the series-wide\n\t\t\t// attribute collection\n\t\t\t} else {\n\t\t\t\tpointAttr = seriesPointAttr;\n\t\t\t}\n\n\t\t\tpoint.pointAttr = pointAttr;\n\n\t\t}\n\n\t},\n\t/**\n\t * Update the series with a new set of options\n\t */\n\tupdate: function (newOptions, redraw) {\n\t\tvar chart = this.chart,\n\t\t\t// must use user options when changing type because this.options is merged\n\t\t\t// in with type specific plotOptions\n\t\t\toldOptions = this.userOptions,\n\t\t\toldType = this.type,\n\t\t\tproto = seriesTypes[oldType].prototype,\n\t\t\tn;\n\n\t\t// Do the merge, with some forced options\n\t\tnewOptions = merge(oldOptions, {\n\t\t\tanimation: false,\n\t\t\tindex: this.index,\n\t\t\tpointStart: this.xData[0] // when updating after addPoint\n\t\t}, { data: this.options.data }, newOptions);\n\n\t\t// Destroy the series and reinsert methods from the type prototype\n\t\tthis.remove(false);\n\t\tfor (n in proto) { // Overwrite series-type specific methods (#2270)\n\t\t\tif (proto.hasOwnProperty(n)) {\n\t\t\t\tthis[n] = UNDEFINED;\n\t\t\t}\n\t\t}\n\t\textend(this, seriesTypes[newOptions.type || oldType].prototype);\n\t\t\n\n\t\tthis.init(chart, newOptions);\n\t\tif (pick(redraw, true)) {\n\t\t\tchart.redraw(false);\n\t\t}\n\t},\n\n\t/**\n\t * Clear DOM objects and free up memory\n\t */\n\tdestroy: function () {\n\t\tvar series = this,\n\t\t\tchart = series.chart,\n\t\t\tissue134 = /AppleWebKit\\/533/.test(userAgent),\n\t\t\tdestroy,\n\t\t\ti,\n\t\t\tdata = series.data || [],\n\t\t\tpoint,\n\t\t\tprop,\n\t\t\taxis;\n\n\t\t// add event hook\n\t\tfireEvent(series, 'destroy');\n\n\t\t// remove all events\n\t\tremoveEvent(series);\n\t\t\n\t\t// erase from axes\n\t\teach(['xAxis', 'yAxis'], function (AXIS) {\n\t\t\taxis = series[AXIS];\n\t\t\tif (axis) {\n\t\t\t\terase(axis.series, series);\n\t\t\t\taxis.isDirty = axis.forceRedraw = true;\n\t\t\t\taxis.stacks = {}; // Rebuild stacks when updating (#2229)\n\t\t\t}\n\t\t});\n\n\t\t// remove legend items\n\t\tif (series.legendItem) {\n\t\t\tseries.chart.legend.destroyItem(series);\n\t\t}\n\n\t\t// destroy all points with their elements\n\t\ti = data.length;\n\t\twhile (i--) {\n\t\t\tpoint = data[i];\n\t\t\tif (point && point.destroy) {\n\t\t\t\tpoint.destroy();\n\t\t\t}\n\t\t}\n\t\tseries.points = null;\n\n\t\t// Clear the animation timeout if we are destroying the series during initial animation\n\t\tclearTimeout(series.animationTimeout);\n\n\t\t// destroy all SVGElements associated to the series\n\t\teach(['area', 'graph', 'dataLabelsGroup', 'group', 'markerGroup', 'tracker',\n\t\t\t\t'graphNeg', 'areaNeg', 'posClip', 'negClip'], function (prop) {\n\t\t\tif (series[prop]) {\n\n\t\t\t\t// issue 134 workaround\n\t\t\t\tdestroy = issue134 && prop === 'group' ?\n\t\t\t\t\t'hide' :\n\t\t\t\t\t'destroy';\n\n\t\t\t\tseries[prop][destroy]();\n\t\t\t}\n\t\t});\n\n\t\t// remove from hoverSeries\n\t\tif (chart.hoverSeries === series) {\n\t\t\tchart.hoverSeries = null;\n\t\t}\n\t\terase(chart.series, series);\n\n\t\t// clear all members\n\t\tfor (prop in series) {\n\t\t\tdelete series[prop];\n\t\t}\n\t},\n\n\t/**\n\t * Draw the data labels\n\t */\n\tdrawDataLabels: function () {\n\t\t\n\t\tvar series = this,\n\t\t\tseriesOptions = series.options,\n\t\t\toptions = seriesOptions.dataLabels,\n\t\t\tpoints = series.points,\n\t\t\tpointOptions,\n\t\t\tgeneralOptions,\n\t\t\tstr,\n\t\t\tdataLabelsGroup;\n\t\t\n\t\tif (options.enabled || series._hasPointLabels) {\n\t\t\t\t\t\t\n\t\t\t// Process default alignment of data labels for columns\n\t\t\tif (series.dlProcessOptions) {\n\t\t\t\tseries.dlProcessOptions(options);\n\t\t\t}\n\n\t\t\t// Create a separate group for the data labels to avoid rotation\n\t\t\tdataLabelsGroup = series.plotGroup(\n\t\t\t\t'dataLabelsGroup', \n\t\t\t\t'data-labels', \n\t\t\t\tseries.visible ? VISIBLE : HIDDEN, \n\t\t\t\toptions.zIndex || 6\n\t\t\t);\n\t\t\t\n\t\t\t// Make the labels for each point\n\t\t\tgeneralOptions = options;\n\t\t\teach(points, function (point) {\n\t\t\t\t\n\t\t\t\tvar enabled,\n\t\t\t\t\tdataLabel = point.dataLabel,\n\t\t\t\t\tlabelConfig,\n\t\t\t\t\tattr,\n\t\t\t\t\tname,\n\t\t\t\t\trotation,\n\t\t\t\t\tconnector = point.connector,\n\t\t\t\t\tisNew = true;\n\t\t\t\t\n\t\t\t\t// Determine if each data label is enabled\n\t\t\t\tpointOptions = point.options && point.options.dataLabels;\n\t\t\t\tenabled = pick(pointOptions && pointOptions.enabled, generalOptions.enabled); // #2282\n\t\t\t\t\n\t\t\t\t\n\t\t\t\t// If the point is outside the plot area, destroy it. #678, #820\n\t\t\t\tif (dataLabel && !enabled) {\n\t\t\t\t\tpoint.dataLabel = dataLabel.destroy();\n\t\t\t\t\n\t\t\t\t// Individual labels are disabled if the are explicitly disabled \n\t\t\t\t// in the point options, or if they fall outside the plot area.\n\t\t\t\t} else if (enabled) {\n\t\t\t\t\t\n\t\t\t\t\t// Create individual options structure that can be extended without \n\t\t\t\t\t// affecting others\n\t\t\t\t\toptions = merge(generalOptions, pointOptions);\n\n\t\t\t\t\trotation = options.rotation;\n\t\t\t\t\t\n\t\t\t\t\t// Get the string\n\t\t\t\t\tlabelConfig = point.getLabelConfig();\n\t\t\t\t\tstr = options.format ?\n\t\t\t\t\t\tformat(options.format, labelConfig) : \n\t\t\t\t\t\toptions.formatter.call(labelConfig, options);\n\t\t\t\t\t\n\t\t\t\t\t// Determine the color\n\t\t\t\t\toptions.style.color = pick(options.color, options.style.color, series.color, 'black');\n\t\n\t\t\t\t\t\n\t\t\t\t\t// update existing label\n\t\t\t\t\tif (dataLabel) {\n\t\t\t\t\t\t\n\t\t\t\t\t\tif (defined(str)) {\n\t\t\t\t\t\t\tdataLabel\n\t\t\t\t\t\t\t\t.attr({\n\t\t\t\t\t\t\t\t\ttext: str\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\tisNew = false;\n\t\t\t\t\t\t\n\t\t\t\t\t\t} else { // #1437 - the label is shown conditionally\n\t\t\t\t\t\t\tpoint.dataLabel = dataLabel = dataLabel.destroy();\n\t\t\t\t\t\t\tif (connector) {\n\t\t\t\t\t\t\t\tpoint.connector = connector.destroy();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t// create new label\n\t\t\t\t\t} else if (defined(str)) {\n\t\t\t\t\t\tattr = {\n\t\t\t\t\t\t\t//align: align,\n\t\t\t\t\t\t\tfill: options.backgroundColor,\n\t\t\t\t\t\t\tstroke: options.borderColor,\n\t\t\t\t\t\t\t'stroke-width': options.borderWidth,\n\t\t\t\t\t\t\tr: options.borderRadius || 0,\n\t\t\t\t\t\t\trotation: rotation,\n\t\t\t\t\t\t\tpadding: options.padding,\n\t\t\t\t\t\t\tzIndex: 1\n\t\t\t\t\t\t};\n\t\t\t\t\t\t// Remove unused attributes (#947)\n\t\t\t\t\t\tfor (name in attr) {\n\t\t\t\t\t\t\tif (attr[name] === UNDEFINED) {\n\t\t\t\t\t\t\t\tdelete attr[name];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t\tdataLabel = point.dataLabel = series.chart.renderer[rotation ? 'text' : 'label']( // labels don't support rotation\n\t\t\t\t\t\t\tstr,\n\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t-999,\n\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\toptions.useHTML\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.attr(attr)\n\t\t\t\t\t\t.css(options.style)\n\t\t\t\t\t\t.add(dataLabelsGroup)\n\t\t\t\t\t\t.shadow(options.shadow);\n\t\t\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tif (dataLabel) {\n\t\t\t\t\t\t// Now the data label is created and placed at 0,0, so we need to align it\n\t\t\t\t\t\tseries.alignDataLabel(point, dataLabel, options, null, isNew);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t},\n\t\n\t/**\n\t * Align each individual data label\n\t */\n\talignDataLabel: function (point, dataLabel, options, alignTo, isNew) {\n\t\tvar chart = this.chart,\n\t\t\tinverted = chart.inverted,\n\t\t\tplotX = pick(point.plotX, -999),\n\t\t\tplotY = pick(point.plotY, -999),\n\t\t\tbBox = dataLabel.getBBox(),\n\t\t\tvisible = this.visible && chart.isInsidePlot(point.plotX, point.plotY, inverted),\n\t\t\talignAttr; // the final position;\n\t\t\t\t\n\t\tif (visible) {\n\n\t\t\t// The alignment box is a singular point\n\t\t\talignTo = extend({\n\t\t\t\tx: inverted ? chart.plotWidth - plotY : plotX,\n\t\t\t\ty: mathRound(inverted ? chart.plotHeight - plotX : plotY),\n\t\t\t\twidth: 0,\n\t\t\t\theight: 0\n\t\t\t}, alignTo);\n\t\t\t\n\t\t\t// Add the text size for alignment calculation\n\t\t\textend(options, {\n\t\t\t\twidth: bBox.width,\n\t\t\t\theight: bBox.height\n\t\t\t});\n\n\t\t\t// Allow a hook for changing alignment in the last moment, then do the alignment\n\t\t\tif (options.rotation) { // Fancy box alignment isn't supported for rotated text\n\t\t\t\talignAttr = {\n\t\t\t\t\talign: options.align,\n\t\t\t\t\tx: alignTo.x + options.x + alignTo.width / 2,\n\t\t\t\t\ty: alignTo.y + options.y + alignTo.height / 2\n\t\t\t\t};\n\t\t\t\tdataLabel[isNew ? 'attr' : 'animate'](alignAttr);\n\t\t\t} else {\n\t\t\t\tdataLabel.align(options, null, alignTo);\n\t\t\t\talignAttr = dataLabel.alignAttr;\n\n\t\t\t\t// Handle justify or crop\n\t\t\t\tif (pick(options.overflow, 'justify') === 'justify') { // docs: overflow: justify, also crop only applies when not justify\n\t\t\t\t\tthis.justifyDataLabel(dataLabel, options, alignAttr, bBox, alignTo, isNew);\n\t\t\t\t\n\t\t\t\t} else if (pick(options.crop, true)) {\n\t\t\t\t\t// Now check that the data label is within the plot area\n\t\t\t\t\tvisible = chart.isInsidePlot(alignAttr.x, alignAttr.y) && chart.isInsidePlot(alignAttr.x + bBox.width, alignAttr.y + bBox.height);\n\t\t\t\t\n\t\t\t\t}\n\t\t\t}\t\t\n\t\t}\n\n\t\t// Show or hide based on the final aligned position\n\t\tif (!visible) {\n\t\t\tdataLabel.attr({ y: -999 });\n\t\t}\n\t\t\t\t\n\t},\n\t\n\t/**\n\t * If data labels fall partly outside the plot area, align them back in, in a way that\n\t * doesn't hide the point.\n\t */\n\tjustifyDataLabel: function (dataLabel, options, alignAttr, bBox, alignTo, isNew) {\n\t\tvar chart = this.chart,\n\t\t\talign = options.align,\n\t\t\tverticalAlign = options.verticalAlign,\n\t\t\toff,\n\t\t\tjustified;\n\n\t\t// Off left\n\t\toff = alignAttr.x;\n\t\tif (off < 0) {\n\t\t\tif (align === 'right') {\n\t\t\t\toptions.align = 'left';\n\t\t\t} else {\n\t\t\t\toptions.x = -off;\n\t\t\t}\n\t\t\tjustified = true;\n\t\t}\n\n\t\t// Off right\n\t\toff = alignAttr.x + bBox.width;\n\t\tif (off > chart.plotWidth) {\n\t\t\tif (align === 'left') {\n\t\t\t\toptions.align = 'right';\n\t\t\t} else {\n\t\t\t\toptions.x = chart.plotWidth - off;\n\t\t\t}\n\t\t\tjustified = true;\n\t\t}\n\n\t\t// Off top\n\t\toff = alignAttr.y;\n\t\tif (off < 0) {\n\t\t\tif (verticalAlign === 'bottom') {\n\t\t\t\toptions.verticalAlign = 'top';\n\t\t\t} else {\n\t\t\t\toptions.y = -off;\n\t\t\t}\n\t\t\tjustified = true;\n\t\t}\n\n\t\t// Off bottom\n\t\toff = alignAttr.y + bBox.height;\n\t\tif (off > chart.plotHeight) {\n\t\t\tif (verticalAlign === 'top') {\n\t\t\t\toptions.verticalAlign = 'bottom';\n\t\t\t} else {\n\t\t\t\toptions.y = chart.plotHeight - off;\n\t\t\t}\n\t\t\tjustified = true;\n\t\t}\n\t\t\n\t\tif (justified) {\n\t\t\tdataLabel.placed = !isNew;\n\t\t\tdataLabel.align(options, null, alignTo);\n\t\t}\n\t},\n\t\n\t/**\n\t * Return the graph path of a segment\n\t */\n\tgetSegmentPath: function (segment) {\t\t\n\t\tvar series = this,\n\t\t\tsegmentPath = [],\n\t\t\tstep = series.options.step;\n\t\t\t\n\t\t// build the segment line\n\t\teach(segment, function (point, i) {\n\t\t\t\n\t\t\tvar plotX = point.plotX,\n\t\t\t\tplotY = point.plotY,\n\t\t\t\tlastPoint;\n\n\t\t\tif (series.getPointSpline) { // generate the spline as defined in the SplineSeries object\n\t\t\t\tsegmentPath.push.apply(segmentPath, series.getPointSpline(segment, point, i));\n\n\t\t\t} else {\n\n\t\t\t\t// moveTo or lineTo\n\t\t\t\tsegmentPath.push(i ? L : M);\n\n\t\t\t\t// step line?\n\t\t\t\tif (step && i) {\n\t\t\t\t\tlastPoint = segment[i - 1];\n\t\t\t\t\tif (step === 'right') {\n\t\t\t\t\t\tsegmentPath.push(\n\t\t\t\t\t\t\tlastPoint.plotX,\n\t\t\t\t\t\t\tplotY\n\t\t\t\t\t\t);\n\t\t\t\t\t\t\n\t\t\t\t\t} else if (step === 'center') {\n\t\t\t\t\t\tsegmentPath.push(\n\t\t\t\t\t\t\t(lastPoint.plotX + plotX) / 2,\n\t\t\t\t\t\t\tlastPoint.plotY,\n\t\t\t\t\t\t\t(lastPoint.plotX + plotX) / 2,\n\t\t\t\t\t\t\tplotY\n\t\t\t\t\t\t);\n\t\t\t\t\t\t\n\t\t\t\t\t} else {\n\t\t\t\t\t\tsegmentPath.push(\n\t\t\t\t\t\t\tplotX,\n\t\t\t\t\t\t\tlastPoint.plotY\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// normal line to next point\n\t\t\t\tsegmentPath.push(\n\t\t\t\t\tpoint.plotX,\n\t\t\t\t\tpoint.plotY\n\t\t\t\t);\n\t\t\t}\n\t\t});\n\t\t\n\t\treturn segmentPath;\n\t},\n\n\t/**\n\t * Get the graph path\n\t */\n\tgetGraphPath: function () {\n\t\tvar series = this,\n\t\t\tgraphPath = [],\n\t\t\tsegmentPath,\n\t\t\tsinglePoints = []; // used in drawTracker\n\n\t\t// Divide into segments and build graph and area paths\n\t\teach(series.segments, function (segment) {\n\t\t\t\n\t\t\tsegmentPath = series.getSegmentPath(segment);\n\t\t\t\n\t\t\t// add the segment to the graph, or a single point for tracking\n\t\t\tif (segment.length > 1) {\n\t\t\t\tgraphPath = graphPath.concat(segmentPath);\n\t\t\t} else {\n\t\t\t\tsinglePoints.push(segment[0]);\n\t\t\t}\n\t\t});\n\n\t\t// Record it for use in drawGraph and drawTracker, and return graphPath\n\t\tseries.singlePoints = singlePoints;\n\t\tseries.graphPath = graphPath;\n\t\t\n\t\treturn graphPath;\n\t\t\n\t},\n\t\n\t/**\n\t * Draw the actual graph\n\t */\n\tdrawGraph: function () {\n\t\tvar series = this,\n\t\t\toptions = this.options,\n\t\t\tprops = [['graph', options.lineColor || this.color]],\n\t\t\tlineWidth = options.lineWidth,\n\t\t\tdashStyle =  options.dashStyle,\n\t\t\tgraphPath = this.getGraphPath(),\n\t\t\tnegativeColor = options.negativeColor;\n\t\t\t\n\t\tif (negativeColor) {\n\t\t\tprops.push(['graphNeg', negativeColor]);\n\t\t}\n\t\t\n\t\t// draw the graph\n\t\teach(props, function (prop, i) {\n\t\t\tvar graphKey = prop[0],\n\t\t\t\tgraph = series[graphKey],\n\t\t\t\tattribs;\n\t\t\t\n\t\t\tif (graph) {\n\t\t\t\tstop(graph); // cancel running animations, #459\n\t\t\t\tgraph.animate({ d: graphPath });\n\t\n\t\t\t} else if (lineWidth && graphPath.length) { // #1487\n\t\t\t\tattribs = {\n\t\t\t\t\tstroke: prop[1],\n\t\t\t\t\t'stroke-width': lineWidth,\n\t\t\t\t\tzIndex: 1 // #1069\n\t\t\t\t};\n\t\t\t\tif (dashStyle) {\n\t\t\t\t\tattribs.dashstyle = dashStyle;\n\t\t\t\t} else {\n\t\t\t\t\tattribs['stroke-linecap'] = attribs['stroke-linejoin'] = 'round';\n\t\t\t\t}\n\n\t\t\t\tseries[graphKey] = series.chart.renderer.path(graphPath)\n\t\t\t\t\t.attr(attribs)\n\t\t\t\t\t.add(series.group)\n\t\t\t\t\t.shadow(!i && options.shadow);\n\t\t\t}\n\t\t});\n\t},\n\t\n\t/**\n\t * Clip the graphs into the positive and negative coloured graphs\n\t */\n\tclipNeg: function () {\n\t\tvar options = this.options,\n\t\t\tchart = this.chart,\n\t\t\trenderer = chart.renderer,\n\t\t\tnegativeColor = options.negativeColor || options.negativeFillColor,\n\t\t\ttranslatedThreshold,\n\t\t\tposAttr,\n\t\t\tnegAttr,\n\t\t\tgraph = this.graph,\n\t\t\tarea = this.area,\n\t\t\tposClip = this.posClip,\n\t\t\tnegClip = this.negClip,\n\t\t\tchartWidth = chart.chartWidth,\n\t\t\tchartHeight = chart.chartHeight,\n\t\t\tchartSizeMax = mathMax(chartWidth, chartHeight),\n\t\t\tyAxis = this.yAxis,\n\t\t\tabove,\n\t\t\tbelow;\n\t\t\n\t\tif (negativeColor && (graph || area)) {\n\t\t\ttranslatedThreshold = mathRound(yAxis.toPixels(options.threshold || 0, true));\n\t\t\tabove = {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0,\n\t\t\t\twidth: chartSizeMax,\n\t\t\t\theight: translatedThreshold\n\t\t\t};\n\t\t\tbelow = {\n\t\t\t\tx: 0,\n\t\t\t\ty: translatedThreshold,\n\t\t\t\twidth: chartSizeMax,\n\t\t\t\theight: chartSizeMax\n\t\t\t};\n\t\t\t\n\t\t\tif (chart.inverted) {\n\n\t\t\t\tabove.height = below.y = chart.plotWidth - translatedThreshold;\n\t\t\t\tif (renderer.isVML) {\n\t\t\t\t\tabove = {\n\t\t\t\t\t\tx: chart.plotWidth - translatedThreshold - chart.plotLeft,\n\t\t\t\t\t\ty: 0,\n\t\t\t\t\t\twidth: chartWidth,\n\t\t\t\t\t\theight: chartHeight\n\t\t\t\t\t};\n\t\t\t\t\tbelow = {\n\t\t\t\t\t\tx: translatedThreshold + chart.plotLeft - chartWidth,\n\t\t\t\t\t\ty: 0,\n\t\t\t\t\t\twidth: chart.plotLeft + translatedThreshold,\n\t\t\t\t\t\theight: chartWidth\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tif (yAxis.reversed) {\n\t\t\t\tposAttr = below;\n\t\t\t\tnegAttr = above;\n\t\t\t} else {\n\t\t\t\tposAttr = above;\n\t\t\t\tnegAttr = below;\n\t\t\t}\n\t\t\n\t\t\tif (posClip) { // update\n\t\t\t\tposClip.animate(posAttr);\n\t\t\t\tnegClip.animate(negAttr);\n\t\t\t} else {\n\t\t\t\t\n\t\t\t\tthis.posClip = posClip = renderer.clipRect(posAttr);\n\t\t\t\tthis.negClip = negClip = renderer.clipRect(negAttr);\n\t\t\t\t\n\t\t\t\tif (graph && this.graphNeg) {\n\t\t\t\t\tgraph.clip(posClip);\n\t\t\t\t\tthis.graphNeg.clip(negClip);\t\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (area) {\n\t\t\t\t\tarea.clip(posClip);\n\t\t\t\t\tthis.areaNeg.clip(negClip);\n\t\t\t\t} \n\t\t\t} \n\t\t}\t\n\t},\n\n\t/**\n\t * Initialize and perform group inversion on series.group and series.markerGroup\n\t */\n\tinvertGroups: function () {\n\t\tvar series = this,\n\t\t\tchart = series.chart;\n\n\t\t// Pie, go away (#1736)\n\t\tif (!series.xAxis) {\n\t\t\treturn;\n\t\t}\n\t\t\n\t\t// A fixed size is needed for inversion to work\n\t\tfunction setInvert() {\t\t\t\n\t\t\tvar size = {\n\t\t\t\twidth: series.yAxis.len,\n\t\t\t\theight: series.xAxis.len\n\t\t\t};\n\t\t\t\n\t\t\teach(['group', 'markerGroup'], function (groupName) {\n\t\t\t\tif (series[groupName]) {\n\t\t\t\t\tseries[groupName].attr(size).invert();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\taddEvent(chart, 'resize', setInvert); // do it on resize\n\t\taddEvent(series, 'destroy', function () {\n\t\t\tremoveEvent(chart, 'resize', setInvert);\n\t\t});\n\n\t\t// Do it now\n\t\tsetInvert(); // do it now\n\t\t\n\t\t// On subsequent render and redraw, just do setInvert without setting up events again\n\t\tseries.invertGroups = setInvert;\n\t},\n\t\n\t/**\n\t * General abstraction for creating plot groups like series.group, series.dataLabelsGroup and \n\t * series.markerGroup. On subsequent calls, the group will only be adjusted to the updated plot size.\n\t */\n\tplotGroup: function (prop, name, visibility, zIndex, parent) {\n\t\tvar group = this[prop],\n\t\t\tisNew = !group;\n\t\t\n\t\t// Generate it on first call\n\t\tif (isNew) {\t\n\t\t\tthis[prop] = group = this.chart.renderer.g(name)\n\t\t\t\t.attr({\n\t\t\t\t\tvisibility: visibility,\n\t\t\t\t\tzIndex: zIndex || 0.1 // IE8 needs this\n\t\t\t\t})\n\t\t\t\t.add(parent);\n\t\t}\n\t\t// Place it on first and subsequent (redraw) calls\n\t\tgroup[isNew ? 'attr' : 'animate'](this.getPlotBox());\n\t\treturn group;\t\t\n\t},\n\n\t/**\n\t * Get the translation and scale for the plot area of this series\n\t */\n\tgetPlotBox: function () {\n\t\treturn {\n\t\t\ttranslateX: this.xAxis ? this.xAxis.left : this.chart.plotLeft, \n\t\t\ttranslateY: this.yAxis ? this.yAxis.top : this.chart.plotTop,\n\t\t\tscaleX: 1, // #1623\n\t\t\tscaleY: 1\n\t\t};\n\t},\n\t\n\t/**\n\t * Render the graph and markers\n\t */\n\trender: function () {\n\t\tvar series = this,\n\t\t\tchart = series.chart,\n\t\t\tgroup,\n\t\t\toptions = series.options,\n\t\t\tanimation = options.animation,\n\t\t\tdoAnimation = animation && !!series.animate && \n\t\t\t\tchart.renderer.isSVG, // this animation doesn't work in IE8 quirks when the group div is hidden,\n\t\t\t\t// and looks bad in other oldIE\n\t\t\tvisibility = series.visible ? VISIBLE : HIDDEN,\n\t\t\tzIndex = options.zIndex,\n\t\t\thasRendered = series.hasRendered,\n\t\t\tchartSeriesGroup = chart.seriesGroup;\n\t\t\n\t\t// the group\n\t\tgroup = series.plotGroup(\n\t\t\t'group', \n\t\t\t'series', \n\t\t\tvisibility, \n\t\t\tzIndex, \n\t\t\tchartSeriesGroup\n\t\t);\n\t\t\n\t\tseries.markerGroup = series.plotGroup(\n\t\t\t'markerGroup', \n\t\t\t'markers', \n\t\t\tvisibility, \n\t\t\tzIndex, \n\t\t\tchartSeriesGroup\n\t\t);\n\t\t\n\t\t// initiate the animation\n\t\tif (doAnimation) {\n\t\t\tseries.animate(true);\n\t\t}\n\n\t\t// cache attributes for shapes\n\t\tseries.getAttribs();\n\n\t\t// SVGRenderer needs to know this before drawing elements (#1089, #1795)\n\t\tgroup.inverted = series.isCartesian ? chart.inverted : false;\n\t\t\n\t\t// draw the graph if any\n\t\tif (series.drawGraph) {\n\t\t\tseries.drawGraph();\n\t\t\tseries.clipNeg();\n\t\t}\n\n\t\t// draw the data labels (inn pies they go before the points)\n\t\tseries.drawDataLabels();\n\t\t\n\t\t// draw the points\n\t\tseries.drawPoints();\n\n\n\t\t// draw the mouse tracking area\n\t\tif (series.options.enableMouseTracking !== false) {\n\t\t\tseries.drawTracker();\n\t\t}\n\t\t\n\t\t// Handle inverted series and tracker groups\n\t\tif (chart.inverted) {\n\t\t\tseries.invertGroups();\n\t\t}\n\t\t\n\t\t// Initial clipping, must be defined after inverting groups for VML\n\t\tif (options.clip !== false && !series.sharedClipKey && !hasRendered) {\n\t\t\tgroup.clip(chart.clipRect);\n\t\t}\n\n\t\t// Run the animation\n\t\tif (doAnimation) {\n\t\t\tseries.animate();\n\t\t} else if (!hasRendered) {\n\t\t\tseries.afterAnimate();\n\t\t}\n\n\t\tseries.isDirty = series.isDirtyData = false; // means data is in accordance with what you see\n\t\t// (See #322) series.isDirty = series.isDirtyData = false; // means data is in accordance with what you see\n\t\tseries.hasRendered = true;\n\t},\n\t\n\t/**\n\t * Redraw the series after an update in the axes.\n\t */\n\tredraw: function () {\n\t\tvar series = this,\n\t\t\tchart = series.chart,\n\t\t\twasDirtyData = series.isDirtyData, // cache it here as it is set to false in render, but used after\n\t\t\tgroup = series.group,\n\t\t\txAxis = series.xAxis,\n\t\t\tyAxis = series.yAxis;\n\n\t\t// reposition on resize\n\t\tif (group) {\n\t\t\tif (chart.inverted) {\n\t\t\t\tgroup.attr({\n\t\t\t\t\twidth: chart.plotWidth,\n\t\t\t\t\theight: chart.plotHeight\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tgroup.animate({\n\t\t\t\ttranslateX: pick(xAxis && xAxis.left, chart.plotLeft),\n\t\t\t\ttranslateY: pick(yAxis && yAxis.top, chart.plotTop)\n\t\t\t});\n\t\t}\n\n\t\tseries.translate();\n\t\tseries.setTooltipPoints(true);\n\n\t\tseries.render();\n\t\tif (wasDirtyData) {\n\t\t\tfireEvent(series, 'updatedData');\n\t\t}\n\t},\n\n\t/**\n\t * Set the state of the graph\n\t */\n\tsetState: function (state) {\n\t\tvar series = this,\n\t\t\toptions = series.options,\n\t\t\tgraph = series.graph,\n\t\t\tgraphNeg = series.graphNeg,\n\t\t\tstateOptions = options.states,\n\t\t\tlineWidth = options.lineWidth,\n\t\t\tattribs;\n\n\t\tstate = state || NORMAL_STATE;\n\n\t\tif (series.state !== state) {\n\t\t\tseries.state = state;\n\n\t\t\tif (stateOptions[state] && stateOptions[state].enabled === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif (state) {\n\t\t\t\tlineWidth = stateOptions[state].lineWidth || lineWidth + 1;\n\t\t\t}\n\n\t\t\tif (graph && !graph.dashstyle) { // hover is turned off for dashed lines in VML\n\t\t\t\tattribs = {\n\t\t\t\t\t'stroke-width': lineWidth\n\t\t\t\t};\n\t\t\t\t// use attr because animate will cause any other animation on the graph to stop\n\t\t\t\tgraph.attr(attribs);\n\t\t\t\tif (graphNeg) {\n\t\t\t\t\tgraphNeg.attr(attribs);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t/**\n\t * Set the visibility of the graph\n\t *\n\t * @param vis {Boolean} True to show the series, false to hide. If UNDEFINED,\n\t *        the visibility is toggled.\n\t */\n\tsetVisible: function (vis, redraw) {\n\t\tvar series = this,\n\t\t\tchart = series.chart,\n\t\t\tlegendItem = series.legendItem,\n\t\t\tshowOrHide,\n\t\t\tignoreHiddenSeries = chart.options.chart.ignoreHiddenSeries,\n\t\t\toldVisibility = series.visible;\n\n\t\t// if called without an argument, toggle visibility\n\t\tseries.visible = vis = series.userOptions.visible = vis === UNDEFINED ? !oldVisibility : vis;\n\t\tshowOrHide = vis ? 'show' : 'hide';\n\n\t\t// show or hide elements\n\t\teach(['group', 'dataLabelsGroup', 'markerGroup', 'tracker'], function (key) {\n\t\t\tif (series[key]) {\n\t\t\t\tseries[key][showOrHide]();\n\t\t\t}\n\t\t});\n\n\t\t\n\t\t// hide tooltip (#1361)\n\t\tif (chart.hoverSeries === series) {\n\t\t\tseries.onMouseOut();\n\t\t}\n\n\n\t\tif (legendItem) {\n\t\t\tchart.legend.colorizeItem(series, vis);\n\t\t}\n\n\n\t\t// rescale or adapt to resized chart\n\t\tseries.isDirty = true;\n\t\t// in a stack, all other series are affected\n\t\tif (series.options.stacking) {\n\t\t\teach(chart.series, function (otherSeries) {\n\t\t\t\tif (otherSeries.options.stacking && otherSeries.visible) {\n\t\t\t\t\totherSeries.isDirty = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\t// show or hide linked series\n\t\teach(series.linkedSeries, function (otherSeries) {\n\t\t\totherSeries.setVisible(vis, false);\n\t\t});\n\n\t\tif (ignoreHiddenSeries) {\n\t\t\tchart.isDirtyBox = true;\n\t\t}\n\t\tif (redraw !== false) {\n\t\t\tchart.redraw();\n\t\t}\n\n\t\tfireEvent(series, showOrHide);\n\t},\n\n\t/**\n\t * Show the graph\n\t */\n\tshow: function () {\n\t\tthis.setVisible(true);\n\t},\n\n\t/**\n\t * Hide the graph\n\t */\n\thide: function () {\n\t\tthis.setVisible(false);\n\t},\n\n\n\t/**\n\t * Set the selected state of the graph\n\t *\n\t * @param selected {Boolean} True to select the series, false to unselect. If\n\t *        UNDEFINED, the selection state is toggled.\n\t */\n\tselect: function (selected) {\n\t\tvar series = this;\n\t\t// if called without an argument, toggle\n\t\tseries.selected = selected = (selected === UNDEFINED) ? !series.selected : selected;\n\n\t\tif (series.checkbox) {\n\t\t\tseries.checkbox.checked = selected;\n\t\t}\n\n\t\tfireEvent(series, selected ? 'select' : 'unselect');\n\t},\n\n\t/**\n\t * Draw the tracker object that sits above all data labels and markers to\n\t * track mouse events on the graph or points. For the line type charts\n\t * the tracker uses the same graphPath, but with a greater stroke width\n\t * for better control.\n\t */\n\tdrawTracker: function () {\n\t\tvar series = this,\n\t\t\toptions = series.options,\n\t\t\ttrackByArea = options.trackByArea,\n\t\t\ttrackerPath = [].concat(trackByArea ? series.areaPath : series.graphPath),\n\t\t\ttrackerPathLength = trackerPath.length,\n\t\t\tchart = series.chart,\n\t\t\tpointer = chart.pointer,\n\t\t\trenderer = chart.renderer,\n\t\t\tsnap = chart.options.tooltip.snap,\n\t\t\ttracker = series.tracker,\n\t\t\tcursor = options.cursor,\n\t\t\tcss = cursor && { cursor: cursor },\n\t\t\tsinglePoints = series.singlePoints,\n\t\t\tsinglePoint,\n\t\t\ti,\n\t\t\tonMouseOver = function () {\n\t\t\t\tif (chart.hoverSeries !== series) {\n\t\t\t\t\tseries.onMouseOver();\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Extend end points. A better way would be to use round linecaps,\n\t\t// but those are not clickable in VML.\n\t\tif (trackerPathLength && !trackByArea) {\n\t\t\ti = trackerPathLength + 1;\n\t\t\twhile (i--) {\n\t\t\t\tif (trackerPath[i] === M) { // extend left side\n\t\t\t\t\ttrackerPath.splice(i + 1, 0, trackerPath[i + 1] - snap, trackerPath[i + 2], L);\n\t\t\t\t}\n\t\t\t\tif ((i && trackerPath[i] === M) || i === trackerPathLength) { // extend right side\n\t\t\t\t\ttrackerPath.splice(i, 0, L, trackerPath[i - 2] + snap, trackerPath[i - 1]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// handle single points\n\t\tfor (i = 0; i < singlePoints.length; i++) {\n\t\t\tsinglePoint = singlePoints[i];\n\t\t\ttrackerPath.push(M, singlePoint.plotX - snap, singlePoint.plotY,\n\t\t\t\tL, singlePoint.plotX + snap, singlePoint.plotY);\n\t\t}\n\t\t\n\t\t\n\n\t\t// draw the tracker\n\t\tif (tracker) {\n\t\t\ttracker.attr({ d: trackerPath });\n\n\t\t} else { // create\n\t\t\t\t\n\t\t\tseries.tracker = renderer.path(trackerPath)\n\t\t\t\t.attr({\n\t\t\t\t\t'stroke-linejoin': 'round', // #1225\n\t\t\t\t\tvisibility: series.visible ? VISIBLE : HIDDEN,\n\t\t\t\t\tstroke: TRACKER_FILL,\n\t\t\t\t\tfill: trackByArea ? TRACKER_FILL : NONE,\n\t\t\t\t\t'stroke-width' : options.lineWidth + (trackByArea ? 0 : 2 * snap),\n\t\t\t\t\tzIndex: 2\n\t\t\t\t})\n\t\t\t\t.add(series.group);\n\t\t\t\t\n\t\t\t// The tracker is added to the series group, which is clipped, but is covered \n\t\t\t// by the marker group. So the marker group also needs to capture events.\n\t\t\teach([series.tracker, series.markerGroup], function (tracker) {\n\t\t\t\ttracker.addClass(PREFIX + 'tracker')\n\t\t\t\t\t.on('mouseover', onMouseOver)\n\t\t\t\t\t.on('mouseout', function (e) { pointer.onTrackerMouseOut(e); })\n\t\t\t\t\t.css(css);\n\n\t\t\t\tif (hasTouch) {\n\t\t\t\t\ttracker.on('touchstart', onMouseOver);\n\t\t\t\t} \n\t\t\t});\n\t\t}\n\n\t}\n\n}; // end Series prototype\n\n\n/**\n * LineSeries object\n */\nvar LineSeries = extendClass(Series);\nseriesTypes.line = LineSeries;\n\n/**\n * Set the default options for area\n */\ndefaultPlotOptions.area = merge(defaultSeriesOptions, {\n\tthreshold: 0\n\t// trackByArea: false,\n\t// lineColor: null, // overrides color, but lets fillColor be unaltered\n\t// fillOpacity: 0.75,\n\t// fillColor: null\n});\n\n/**\n * AreaSeries object\n */\nvar AreaSeries = extendClass(Series, {\n\ttype: 'area',\n\t\n\t/**\n\t * For stacks, don't split segments on null values. Instead, draw null values with \n\t * no marker. Also insert dummy points for any X position that exists in other series\n\t * in the stack.\n\t */ \n\tgetSegments: function () {\n\t\tvar segments = [],\n\t\t\tsegment = [],\n\t\t\tkeys = [],\n\t\t\txAxis = this.xAxis,\n\t\t\tyAxis = this.yAxis,\n\t\t\tstack = yAxis.stacks[this.stackKey],\n\t\t\tpointMap = {},\n\t\t\tplotX,\n\t\t\tplotY,\n\t\t\tpoints = this.points,\n\t\t\tconnectNulls = this.options.connectNulls,\n\t\t\tval,\n\t\t\ti,\n\t\t\tx;\n\n\t\tif (this.options.stacking && !this.cropped) { // cropped causes artefacts in Stock, and perf issue\n\t\t\t// Create a map where we can quickly look up the points by their X value.\n\t\t\tfor (i = 0; i < points.length; i++) {\n\t\t\t\tpointMap[points[i].x] = points[i];\n\t\t\t}\n\n\t\t\t// Sort the keys (#1651)\n\t\t\tfor (x in stack) {\n\t\t\t\tkeys.push(+x);\n\t\t\t}\n\t\t\tkeys.sort(function (a, b) {\n\t\t\t\treturn a - b;\n\t\t\t});\n\n\t\t\teach(keys, function (x) {\n\t\t\t\tif (connectNulls && (!pointMap[x] || pointMap[x].y === null)) { // #1836\n\t\t\t\t\treturn;\n\n\t\t\t\t// The point exists, push it to the segment\n\t\t\t\t} else if (pointMap[x]) {\n\t\t\t\t\tsegment.push(pointMap[x]);\n\n\t\t\t\t// There is no point for this X value in this series, so we \n\t\t\t\t// insert a dummy point in order for the areas to be drawn\n\t\t\t\t// correctly.\n\t\t\t\t} else {\n\t\t\t\t\tplotX = xAxis.translate(x);\n\t\t\t\t\tval = stack[x].percent ? (stack[x].total ? stack[x].cum * 100 / stack[x].total : 0) : stack[x].cum; // #1991\n\t\t\t\t\tplotY = yAxis.toPixels(val, true);\n\t\t\t\t\tsegment.push({ \n\t\t\t\t\t\ty: null, \n\t\t\t\t\t\tplotX: plotX,\n\t\t\t\t\t\tclientX: plotX, \n\t\t\t\t\t\tplotY: plotY, \n\t\t\t\t\t\tyBottom: plotY,\n\t\t\t\t\t\tonMouseOver: noop\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (segment.length) {\n\t\t\t\tsegments.push(segment);\n\t\t\t}\n\n\t\t} else {\n\t\t\tSeries.prototype.getSegments.call(this);\n\t\t\tsegments = this.segments;\n\t\t}\n\n\t\tthis.segments = segments;\n\t},\n\t\n\t/**\n\t * Extend the base Series getSegmentPath method by adding the path for the area.\n\t * This path is pushed to the series.areaPath property.\n\t */\n\tgetSegmentPath: function (segment) {\n\t\t\n\t\tvar segmentPath = Series.prototype.getSegmentPath.call(this, segment), // call base method\n\t\t\tareaSegmentPath = [].concat(segmentPath), // work on a copy for the area path\n\t\t\ti,\n\t\t\toptions = this.options,\n\t\t\tsegLength = segmentPath.length,\n\t\t\ttranslatedThreshold = this.yAxis.getThreshold(options.threshold), // #2181\n\t\t\tyBottom;\n\t\t\n\t\tif (segLength === 3) { // for animation from 1 to two points\n\t\t\tareaSegmentPath.push(L, segmentPath[1], segmentPath[2]);\n\t\t}\n\t\tif (options.stacking && !this.closedStacks) {\n\t\t\t\n\t\t\t// Follow stack back. Todo: implement areaspline. A general solution could be to \n\t\t\t// reverse the entire graphPath of the previous series, though may be hard with\n\t\t\t// splines and with series with different extremes\n\t\t\tfor (i = segment.length - 1; i >= 0; i--) {\n\n\t\t\t\tyBottom = pick(segment[i].yBottom, translatedThreshold);\n\t\t\t\n\t\t\t\t// step line?\n\t\t\t\tif (i < segment.length - 1 && options.step) {\n\t\t\t\t\tareaSegmentPath.push(segment[i + 1].plotX, yBottom);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tareaSegmentPath.push(segment[i].plotX, yBottom);\n\t\t\t}\n\n\t\t} else { // follow zero line back\n\t\t\tthis.closeSegment(areaSegmentPath, segment, translatedThreshold);\n\t\t}\n\t\tthis.areaPath = this.areaPath.concat(areaSegmentPath);\n\t\treturn segmentPath;\n\t},\n\t\n\t/**\n\t * Extendable method to close the segment path of an area. This is overridden in polar \n\t * charts.\n\t */\n\tcloseSegment: function (path, segment, translatedThreshold) {\n\t\tpath.push(\n\t\t\tL,\n\t\t\tsegment[segment.length - 1].plotX,\n\t\t\ttranslatedThreshold,\n\t\t\tL,\n\t\t\tsegment[0].plotX,\n\t\t\ttranslatedThreshold\n\t\t);\n\t},\n\t\n\t/**\n\t * Draw the graph and the underlying area. This method calls the Series base\n\t * function and adds the area. The areaPath is calculated in the getSegmentPath\n\t * method called from Series.prototype.drawGraph.\n\t */\n\tdrawGraph: function () {\n\t\t\n\t\t// Define or reset areaPath\n\t\tthis.areaPath = [];\n\t\t\n\t\t// Call the base method\n\t\tSeries.prototype.drawGraph.apply(this);\n\t\t\n\t\t// Define local variables\n\t\tvar series = this,\n\t\t\tareaPath = this.areaPath,\n\t\t\toptions = this.options,\n\t\t\tnegativeColor = options.negativeColor,\n\t\t\tnegativeFillColor = options.negativeFillColor,\n\t\t\tprops = [['area', this.color, options.fillColor]]; // area name, main color, fill color\n\t\t\n\t\tif (negativeColor || negativeFillColor) {\n\t\t\tprops.push(['areaNeg', negativeColor, negativeFillColor]);\n\t\t}\n\t\t\n\t\teach(props, function (prop) {\n\t\t\tvar areaKey = prop[0],\n\t\t\t\tarea = series[areaKey];\n\t\t\t\t\n\t\t\t// Create or update the area\n\t\t\tif (area) { // update\n\t\t\t\tarea.animate({ d: areaPath });\n\t\n\t\t\t} else { // create\n\t\t\t\tseries[areaKey] = series.chart.renderer.path(areaPath)\n\t\t\t\t\t.attr({\n\t\t\t\t\t\tfill: pick(\n\t\t\t\t\t\t\tprop[2],\n\t\t\t\t\t\t\tColor(prop[1]).setOpacity(pick(options.fillOpacity, 0.75)).get()\n\t\t\t\t\t\t),\n\t\t\t\t\t\tzIndex: 0 // #1069\n\t\t\t\t\t}).add(series.group);\n\t\t\t}\n\t\t});\n\t},\n\t\n\t/**\n\t * Get the series' symbol in the legend\n\t * \n\t * @param {Object} legend The legend object\n\t * @param {Object} item The series (this) or point\n\t */\n\tdrawLegendSymbol: function (legend, item) {\n\t\t\n\t\titem.legendSymbol = this.chart.renderer.rect(\n\t\t\t0,\n\t\t\tlegend.baseline - 11,\n\t\t\tlegend.options.symbolWidth,\n\t\t\t12,\n\t\t\t2\n\t\t).attr({\n\t\t\tzIndex: 3\n\t\t}).add(item.legendGroup);\t\t\n\t\t\n\t}\n});\n\nseriesTypes.area = AreaSeries;/**\n * Set the default options for spline\n */\ndefaultPlotOptions.spline = merge(defaultSeriesOptions);\n\n/**\n * SplineSeries object\n */\nvar SplineSeries = extendClass(Series, {\n\ttype: 'spline',\n\n\t/**\n\t * Get the spline segment from a given point's previous neighbour to the given point\n\t */\n\tgetPointSpline: function (segment, point, i) {\n\t\tvar smoothing = 1.5, // 1 means control points midway between points, 2 means 1/3 from the point, 3 is 1/4 etc\n\t\t\tdenom = smoothing + 1,\n\t\t\tplotX = point.plotX,\n\t\t\tplotY = point.plotY,\n\t\t\tlastPoint = segment[i - 1],\n\t\t\tnextPoint = segment[i + 1],\n\t\t\tleftContX,\n\t\t\tleftContY,\n\t\t\trightContX,\n\t\t\trightContY,\n\t\t\tret;\n\n\t\t// find control points\n\t\tif (lastPoint && nextPoint) {\n\t\t\n\t\t\tvar lastX = lastPoint.plotX,\n\t\t\t\tlastY = lastPoint.plotY,\n\t\t\t\tnextX = nextPoint.plotX,\n\t\t\t\tnextY = nextPoint.plotY,\n\t\t\t\tcorrection;\n\n\t\t\tleftContX = (smoothing * plotX + lastX) / denom;\n\t\t\tleftContY = (smoothing * plotY + lastY) / denom;\n\t\t\trightContX = (smoothing * plotX + nextX) / denom;\n\t\t\trightContY = (smoothing * plotY + nextY) / denom;\n\n\t\t\t// have the two control points make a straight line through main point\n\t\t\tcorrection = ((rightContY - leftContY) * (rightContX - plotX)) /\n\t\t\t\t(rightContX - leftContX) + plotY - rightContY;\n\n\t\t\tleftContY += correction;\n\t\t\trightContY += correction;\n\n\t\t\t// to prevent false extremes, check that control points are between\n\t\t\t// neighbouring points' y values\n\t\t\tif (leftContY > lastY && leftContY > plotY) {\n\t\t\t\tleftContY = mathMax(lastY, plotY);\n\t\t\t\trightContY = 2 * plotY - leftContY; // mirror of left control point\n\t\t\t} else if (leftContY < lastY && leftContY < plotY) {\n\t\t\t\tleftContY = mathMin(lastY, plotY);\n\t\t\t\trightContY = 2 * plotY - leftContY;\n\t\t\t}\n\t\t\tif (rightContY > nextY && rightContY > plotY) {\n\t\t\t\trightContY = mathMax(nextY, plotY);\n\t\t\t\tleftContY = 2 * plotY - rightContY;\n\t\t\t} else if (rightContY < nextY && rightContY < plotY) {\n\t\t\t\trightContY = mathMin(nextY, plotY);\n\t\t\t\tleftContY = 2 * plotY - rightContY;\n\t\t\t}\n\n\t\t\t// record for drawing in next point\n\t\t\tpoint.rightContX = rightContX;\n\t\t\tpoint.rightContY = rightContY;\n\n\t\t}\n\t\t\n\t\t// Visualize control points for debugging\n\t\t/*\n\t\tif (leftContX) {\n\t\t\tthis.chart.renderer.circle(leftContX + this.chart.plotLeft, leftContY + this.chart.plotTop, 2)\n\t\t\t\t.attr({\n\t\t\t\t\tstroke: 'red',\n\t\t\t\t\t'stroke-width': 1,\n\t\t\t\t\tfill: 'none'\n\t\t\t\t})\n\t\t\t\t.add();\n\t\t\tthis.chart.renderer.path(['M', leftContX + this.chart.plotLeft, leftContY + this.chart.plotTop,\n\t\t\t\t'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop])\n\t\t\t\t.attr({\n\t\t\t\t\tstroke: 'red',\n\t\t\t\t\t'stroke-width': 1\n\t\t\t\t})\n\t\t\t\t.add();\n\t\t\tthis.chart.renderer.circle(rightContX + this.chart.plotLeft, rightContY + this.chart.plotTop, 2)\n\t\t\t\t.attr({\n\t\t\t\t\tstroke: 'green',\n\t\t\t\t\t'stroke-width': 1,\n\t\t\t\t\tfill: 'none'\n\t\t\t\t})\n\t\t\t\t.add();\n\t\t\tthis.chart.renderer.path(['M', rightContX + this.chart.plotLeft, rightContY + this.chart.plotTop,\n\t\t\t\t'L', plotX + this.chart.plotLeft, plotY + this.chart.plotTop])\n\t\t\t\t.attr({\n\t\t\t\t\tstroke: 'green',\n\t\t\t\t\t'stroke-width': 1\n\t\t\t\t})\n\t\t\t\t.add();\n\t\t}\n\t\t*/\n\n\t\t// moveTo or lineTo\n\t\tif (!i) {\n\t\t\tret = [M, plotX, plotY];\n\t\t} else { // curve from last point to this\n\t\t\tret = [\n\t\t\t\t'C',\n\t\t\t\tlastPoint.rightContX || lastPoint.plotX,\n\t\t\t\tlastPoint.rightContY || lastPoint.plotY,\n\t\t\t\tleftContX || plotX,\n\t\t\t\tleftContY || plotY,\n\t\t\t\tplotX,\n\t\t\t\tplotY\n\t\t\t];\n\t\t\tlastPoint.rightContX = lastPoint.rightContY = null; // reset for updating series later\n\t\t}\n\t\treturn ret;\n\t}\n});\nseriesTypes.spline = SplineSeries;\n\n/**\n * Set the default options for areaspline\n */\ndefaultPlotOptions.areaspline = merge(defaultPlotOptions.area);\n\n/**\n * AreaSplineSeries object\n */\nvar areaProto = AreaSeries.prototype,\n\tAreaSplineSeries = extendClass(SplineSeries, {\n\t\ttype: 'areaspline',\n\t\tclosedStacks: true, // instead of following the previous graph back, follow the threshold back\n\t\t\n\t\t// Mix in methods from the area series\n\t\tgetSegmentPath: areaProto.getSegmentPath,\n\t\tcloseSegment: areaProto.closeSegment,\n\t\tdrawGraph: areaProto.drawGraph,\n\t\tdrawLegendSymbol: areaProto.drawLegendSymbol\n\t});\nseriesTypes.areaspline = AreaSplineSeries;\n\n/**\n * Set the default options for column\n */\ndefaultPlotOptions.column = merge(defaultSeriesOptions, {\n\tborderColor: '#FFFFFF',\n\tborderWidth: 1,\n\tborderRadius: 0,\n\t//colorByPoint: undefined,\n\tgroupPadding: 0.2,\n\t//grouping: true,\n\tmarker: null, // point options are specified in the base options\n\tpointPadding: 0.1,\n\t//pointWidth: null,\n\tminPointLength: 0,\n\tcropThreshold: 50, // when there are more points, they will not animate out of the chart on xAxis.setExtremes\n\tpointRange: null, // null means auto, meaning 1 in a categorized axis and least distance between points if not categories\n\tstates: {\n\t\thover: {\n\t\t\tbrightness: 0.1,\n\t\t\tshadow: false\n\t\t},\n\t\tselect: {\n\t\t\tcolor: '#C0C0C0',\n\t\t\tborderColor: '#000000',\n\t\t\tshadow: false\n\t\t}\n\t},\n\tdataLabels: {\n\t\talign: null, // auto\n\t\tverticalAlign: null, // auto\n\t\ty: null\n\t},\n\tstickyTracking: false,\n\tthreshold: 0\n});\n\n/**\n * ColumnSeries object\n */\nvar ColumnSeries = extendClass(Series, {\n\ttype: 'column',\n\tpointAttrToOptions: { // mapping between SVG attributes and the corresponding options\n\t\tstroke: 'borderColor',\n\t\t'stroke-width': 'borderWidth',\n\t\tfill: 'color',\n\t\tr: 'borderRadius'\n\t},\n\tcropShoulder: 0,\n\ttrackerGroups: ['group', 'dataLabelsGroup'],\n\tnegStacks: true, // use separate negative stacks, unlike area stacks where a negative \n\t\t// point is substracted from previous (#1910)\n\t\n\t/**\n\t * Initialize the series\n\t */\n\tinit: function () {\n\t\tSeries.prototype.init.apply(this, arguments);\n\n\t\tvar series = this,\n\t\t\tchart = series.chart;\n\n\t\t// if the series is added dynamically, force redraw of other\n\t\t// series affected by a new column\n\t\tif (chart.hasRendered) {\n\t\t\teach(chart.series, function (otherSeries) {\n\t\t\t\tif (otherSeries.type === series.type) {\n\t\t\t\t\totherSeries.isDirty = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t},\n\n\t/**\n\t * Return the width and x offset of the columns adjusted for grouping, groupPadding, pointPadding,\n\t * pointWidth etc. \n\t */\n\tgetColumnMetrics: function () {\n\n\t\tvar series = this,\n\t\t\toptions = series.options,\n\t\t\txAxis = series.xAxis,\n\t\t\tyAxis = series.yAxis,\n\t\t\treversedXAxis = xAxis.reversed,\n\t\t\tstackKey,\n\t\t\tstackGroups = {},\n\t\t\tcolumnIndex,\n\t\t\tcolumnCount = 0;\n\n\t\t// Get the total number of column type series.\n\t\t// This is called on every series. Consider moving this logic to a\n\t\t// chart.orderStacks() function and call it on init, addSeries and removeSeries\n\t\tif (options.grouping === false) {\n\t\t\tcolumnCount = 1;\n\t\t} else {\n\t\t\teach(series.chart.series, function (otherSeries) {\n\t\t\t\tvar otherOptions = otherSeries.options,\n\t\t\t\t\totherYAxis = otherSeries.yAxis;\n\t\t\t\tif (otherSeries.type === series.type && otherSeries.visible &&\n\t\t\t\t\t\tyAxis.len === otherYAxis.len && yAxis.pos === otherYAxis.pos) {  // #642, #2086\n\t\t\t\t\tif (otherOptions.stacking) {\n\t\t\t\t\t\tstackKey = otherSeries.stackKey;\n\t\t\t\t\t\tif (stackGroups[stackKey] === UNDEFINED) {\n\t\t\t\t\t\t\tstackGroups[stackKey] = columnCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcolumnIndex = stackGroups[stackKey];\n\t\t\t\t\t} else if (otherOptions.grouping !== false) { // #1162\n\t\t\t\t\t\tcolumnIndex = columnCount++;\n\t\t\t\t\t}\n\t\t\t\t\totherSeries.columnIndex = columnIndex;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tvar categoryWidth = mathMin(\n\t\t\t\tmathAbs(xAxis.transA) * (xAxis.ordinalSlope || options.pointRange || xAxis.closestPointRange || 1), \n\t\t\t\txAxis.len // #1535\n\t\t\t),\n\t\t\tgroupPadding = categoryWidth * options.groupPadding,\n\t\t\tgroupWidth = categoryWidth - 2 * groupPadding,\n\t\t\tpointOffsetWidth = groupWidth / columnCount,\n\t\t\toptionPointWidth = options.pointWidth,\n\t\t\tpointPadding = defined(optionPointWidth) ? (pointOffsetWidth - optionPointWidth) / 2 :\n\t\t\t\tpointOffsetWidth * options.pointPadding,\n\t\t\tpointWidth = pick(optionPointWidth, pointOffsetWidth - 2 * pointPadding), // exact point width, used in polar charts\n\t\t\tcolIndex = (reversedXAxis ? \n\t\t\t\tcolumnCount - (series.columnIndex || 0) : // #1251\n\t\t\t\tseries.columnIndex) || 0,\n\t\t\tpointXOffset = pointPadding + (groupPadding + colIndex *\n\t\t\t\tpointOffsetWidth - (categoryWidth / 2)) *\n\t\t\t\t(reversedXAxis ? -1 : 1);\n\n\t\t// Save it for reading in linked series (Error bars particularly)\n\t\treturn (series.columnMetrics = { \n\t\t\twidth: pointWidth, \n\t\t\toffset: pointXOffset \n\t\t});\n\t\t\t\n\t},\n\n\t/**\n\t * Translate each point to the plot area coordinate system and find shape positions\n\t */\n\ttranslate: function () {\n\t\tvar series = this,\n\t\t\tchart = series.chart,\n\t\t\toptions = series.options,\n\t\t\tborderWidth = options.borderWidth,\n\t\t\tyAxis = series.yAxis,\n\t\t\tthreshold = options.threshold,\n\t\t\ttranslatedThreshold = series.translatedThreshold = yAxis.getThreshold(threshold),\n\t\t\tminPointLength = pick(options.minPointLength, 5),\n\t\t\tmetrics = series.getColumnMetrics(),\n\t\t\tpointWidth = metrics.width,\n\t\t\tseriesBarW = series.barW = mathCeil(mathMax(pointWidth, 1 + 2 * borderWidth)), // rounded and postprocessed for border width\n\t\t\tpointXOffset = series.pointXOffset = metrics.offset,\n\t\t\txCrisp = -(borderWidth % 2 ? 0.5 : 0),\n\t\t\tyCrisp = borderWidth % 2 ? 0.5 : 1;\n\n\t\tif (chart.renderer.isVML && chart.inverted) {\n\t\t\tyCrisp += 1;\n\t\t}\n\n\t\tSeries.prototype.translate.apply(series);\n\n\t\t// record the new values\n\t\teach(series.points, function (point) {\n\t\t\tvar yBottom = pick(point.yBottom, translatedThreshold),\n\t\t\t\tplotY = mathMin(mathMax(-999 - yBottom, point.plotY), yAxis.len + 999 + yBottom), // Don't draw too far outside plot area (#1303, #2241)\n\t\t\t\tbarX = point.plotX + pointXOffset,\n\t\t\t\tbarW = seriesBarW,\n\t\t\t\tbarY = mathMin(plotY, yBottom),\n\t\t\t\tright,\n\t\t\t\tbottom,\n\t\t\t\tfromTop,\n\t\t\t\tfromLeft,\n\t\t\t\tbarH = mathMax(plotY, yBottom) - barY;\n\n\t\t\t// Handle options.minPointLength\n\t\t\tif (mathAbs(barH) < minPointLength) {\n\t\t\t\tif (minPointLength) {\n\t\t\t\t\tbarH = minPointLength;\n\t\t\t\t\tbarY =\n\t\t\t\t\t\tmathRound(mathAbs(barY - translatedThreshold) > minPointLength ? // stacked\n\t\t\t\t\t\t\tyBottom - minPointLength : // keep position\n\t\t\t\t\t\t\ttranslatedThreshold - (yAxis.translate(point.y, 0, 1, 0, 1) <= translatedThreshold ? minPointLength : 0)); // use exact yAxis.translation (#1485)\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Cache for access in polar\n\t\t\tpoint.barX = barX;\n\t\t\tpoint.pointWidth = pointWidth;\n\n\n\t\t\t// Round off to obtain crisp edges\n\t\t\tfromLeft = mathAbs(barX) < 0.5;\n\t\t\tright = mathRound(barX + barW) + xCrisp;\n\t\t\tbarX = mathRound(barX) + xCrisp;\n\t\t\tbarW = right - barX;\n\n\t\t\tfromTop = mathAbs(barY) < 0.5;\n\t\t\tbottom = mathRound(barY + barH) + yCrisp;\n\t\t\tbarY = mathRound(barY) + yCrisp;\n\t\t\tbarH = bottom - barY;\n\n\t\t\t// Top and left edges are exceptions\n\t\t\tif (fromLeft) {\n\t\t\t\tbarX += 1;\n\t\t\t\tbarW -= 1;\n\t\t\t}\n\t\t\tif (fromTop) {\n\t\t\t\tbarY -= 1;\n\t\t\t\tbarH += 1;\n\t\t\t}\n\n\t\t\t// Register shape type and arguments to be used in drawPoints\n\t\t\tpoint.shapeType = 'rect';\n\t\t\tpoint.shapeArgs = {\n\t\t\t\tx: barX,\n\t\t\t\ty: barY,\n\t\t\t\twidth: barW,\n\t\t\t\theight: barH\n\t\t\t};\n\t\t});\n\n\t},\n\n\tgetSymbol: noop,\n\t\n\t/**\n\t * Use a solid rectangle like the area series types\n\t */\n\tdrawLegendSymbol: AreaSeries.prototype.drawLegendSymbol,\n\t\n\t\n\t/**\n\t * Columns have no graph\n\t */\n\tdrawGraph: noop,\n\n\t/**\n\t * Draw the columns. For bars, the series.group is rotated, so the same coordinates\n\t * apply for columns and bars. This method is inherited by scatter series.\n\t *\n\t */\n\tdrawPoints: function () {\n\t\tvar series = this,\n\t\t\toptions = series.options,\n\t\t\trenderer = series.chart.renderer,\n\t\t\tshapeArgs;\n\n\n\t\t// draw the columns\n\t\teach(series.points, function (point) {\n\t\t\tvar plotY = point.plotY,\n\t\t\t\tgraphic = point.graphic;\n\n\t\t\tif (plotY !== UNDEFINED && !isNaN(plotY) && point.y !== null) {\n\t\t\t\tshapeArgs = point.shapeArgs;\n\t\t\t\t\n\t\t\t\tif (graphic) { // update\n\t\t\t\t\tstop(graphic);\n\t\t\t\t\tgraphic.animate(merge(shapeArgs));\n\n\t\t\t\t} else {\n\t\t\t\t\tpoint.graphic = graphic = renderer[point.shapeType](shapeArgs)\n\t\t\t\t\t\t.attr(point.pointAttr[point.selected ? SELECT_STATE : NORMAL_STATE])\n\t\t\t\t\t\t.add(series.group)\n\t\t\t\t\t\t.shadow(options.shadow, null, options.stacking && !options.borderRadius);\n\t\t\t\t}\n\n\t\t\t} else if (graphic) {\n\t\t\t\tpoint.graphic = graphic.destroy(); // #1269\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n\t * Add tracking event listener to the series group, so the point graphics\n\t * themselves act as trackers\n\t */\n\tdrawTracker: function () {\n\t\tvar series = this,\n\t\t\tchart = series.chart,\n\t\t\tpointer = chart.pointer,\n\t\t\tcursor = series.options.cursor,\n\t\t\tcss = cursor && { cursor: cursor },\n\t\t\tonMouseOver = function (e) {\n\t\t\t\tvar target = e.target,\n\t\t\t\t\tpoint;\n\n\t\t\t\tif (chart.hoverSeries !== series) {\n\t\t\t\t\tseries.onMouseOver();\n\t\t\t\t}\n\t\t\t\twhile (target && !point) {\n\t\t\t\t\tpoint = target.point;\n\t\t\t\t\ttarget = target.parentNode;\n\t\t\t\t}\n\t\t\t\tif (point !== UNDEFINED && point !== chart.hoverPoint) { // undefined on graph in scatterchart\n\t\t\t\t\tpoint.onMouseOver(e);\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Add reference to the point\n\t\teach(series.points, function (point) {\n\t\t\tif (point.graphic) {\n\t\t\t\tpoint.graphic.element.point = point;\n\t\t\t}\n\t\t\tif (point.dataLabel) {\n\t\t\t\tpoint.dataLabel.element.point = point;\n\t\t\t}\n\t\t});\n\n\t\t// Add the event listeners, we need to do this only once\n\t\tif (!series._hasTracking) {\n\t\t\teach(series.trackerGroups, function (key) {\n\t\t\t\tif (series[key]) { // we don't always have dataLabelsGroup\n\t\t\t\t\tseries[key]\n\t\t\t\t\t\t.addClass(PREFIX + 'tracker')\n\t\t\t\t\t\t.on('mouseover', onMouseOver)\n\t\t\t\t\t\t.on('mouseout', function (e) { pointer.onTrackerMouseOut(e); })\n\t\t\t\t\t\t.css(css);\n\t\t\t\t\tif (hasTouch) {\n\t\t\t\t\t\tseries[key].on('touchstart', onMouseOver);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\tseries._hasTracking = true;\n\t\t}\n\t},\n\t\n\t/** \n\t * Override the basic data label alignment by adjusting for the position of the column\n\t */\n\talignDataLabel: function (point, dataLabel, options,  alignTo, isNew) {\n\t\tvar chart = this.chart,\n\t\t\tinverted = chart.inverted,\n\t\t\tdlBox = point.dlBox || point.shapeArgs, // data label box for alignment\n\t\t\tbelow = point.below || (point.plotY > pick(this.translatedThreshold, chart.plotSizeY)),\n\t\t\tinside = pick(options.inside, !!this.options.stacking); // draw it inside the box?\n\t\t\n\t\t// Align to the column itself, or the top of it\n\t\tif (dlBox) { // Area range uses this method but not alignTo\n\t\t\talignTo = merge(dlBox);\n\t\t\tif (inverted) {\n\t\t\t\talignTo = {\n\t\t\t\t\tx: chart.plotWidth - alignTo.y - alignTo.height,\n\t\t\t\t\ty: chart.plotHeight - alignTo.x - alignTo.width,\n\t\t\t\t\twidth: alignTo.height,\n\t\t\t\t\theight: alignTo.width\n\t\t\t\t};\n\t\t\t}\n\t\t\t\t\n\t\t\t// Compute the alignment box\n\t\t\tif (!inside) {\n\t\t\t\tif (inverted) {\n\t\t\t\t\talignTo.x += below ? 0 : alignTo.width;\n\t\t\t\t\talignTo.width = 0;\n\t\t\t\t} else {\n\t\t\t\t\talignTo.y += below ? alignTo.height : 0;\n\t\t\t\t\talignTo.height = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t// When alignment is undefined (typically columns and bars), display the individual \n\t\t// point below or above the point depending on the threshold\n\t\toptions.align = pick(\n\t\t\toptions.align, \n\t\t\t!inverted || inside ? 'center' : below ? 'right' : 'left'\n\t\t);\n\t\toptions.verticalAlign = pick(\n\t\t\toptions.verticalAlign, \n\t\t\tinverted || inside ? 'middle' : below ? 'top' : 'bottom'\n\t\t);\n\t\t\n\t\t// Call the parent method\n\t\tSeries.prototype.alignDataLabel.call(this, point, dataLabel, options, alignTo, isNew);\n\t},\n\n\n\t/**\n\t * Animate the column heights one by one from zero\n\t * @param {Boolean} init Whether to initialize the animation or run it\n\t */\n\tanimate: function (init) {\n\t\tvar series = this,\n\t\t\tyAxis = this.yAxis,\n\t\t\toptions = series.options,\n\t\t\tinverted = this.chart.inverted,\n\t\t\tattr = {},\n\t\t\ttranslatedThreshold;\n\n\t\tif (hasSVG) { // VML is too slow anyway\n\t\t\tif (init) {\n\t\t\t\tattr.scaleY = 0.001;\n\t\t\t\ttranslatedThreshold = mathMin(yAxis.pos + yAxis.len, mathMax(yAxis.pos, yAxis.toPixels(options.threshold)));\n\t\t\t\tif (inverted) {\n\t\t\t\t\tattr.translateX = translatedThreshold - yAxis.len;\n\t\t\t\t} else {\n\t\t\t\t\tattr.translateY = translatedThreshold;\n\t\t\t\t}\n\t\t\t\tseries.group.attr(attr);\n\n\t\t\t} else { // run the animation\n\t\t\t\t\n\t\t\t\tattr.scaleY = 1;\n\t\t\t\tattr[inverted ? 'translateX' : 'translateY'] = yAxis.pos;\n\t\t\t\tseries.group.animate(attr, series.options.animation);\n\n\t\t\t\t// delete this function to allow it only once\n\t\t\t\tseries.animate = null;\n\t\t\t}\n\t\t}\n\t},\n\t\n\t/**\n\t * Remove this series from the chart\n\t */\n\tremove: function () {\n\t\tvar series = this,\n\t\t\tchart = series.chart;\n\n\t\t// column and bar series affects other series of the same type\n\t\t// as they are either stacked or grouped\n\t\tif (chart.hasRendered) {\n\t\t\teach(chart.series, function (otherSeries) {\n\t\t\t\tif (otherSeries.type === series.type) {\n\t\t\t\t\totherSeries.isDirty = true;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\n\t\tSeries.prototype.remove.apply(series, arguments);\n\t}\n});\nseriesTypes.column = ColumnSeries;\n/**\n * Set the default options for bar\n */\ndefaultPlotOptions.bar = merge(defaultPlotOptions.column);\n/**\n * The Bar series class\n */\nvar BarSeries = extendClass(ColumnSeries, {\n\ttype: 'bar',\n\tinverted: true\n});\nseriesTypes.bar = BarSeries;\n\n/**\n * Set the default options for scatter\n */\ndefaultPlotOptions.scatter = merge(defaultSeriesOptions, {\n\tlineWidth: 0,\n\ttooltip: {\n\t\theaderFormat: '<span style=\"font-size: 10px; color:{series.color}\">{series.name}</span><br/>',\n\t\tpointFormat: 'x: <b>{point.x}</b><br/>y: <b>{point.y}</b><br/>',\n\t\tfollowPointer: true\n\t},\n\tstickyTracking: false\n});\n\n/**\n * The scatter series class\n */\nvar ScatterSeries = extendClass(Series, {\n\ttype: 'scatter',\n\tsorted: false,\n\trequireSorting: false,\n\tnoSharedTooltip: true,\n\ttrackerGroups: ['markerGroup'],\n\n\tdrawTracker: ColumnSeries.prototype.drawTracker,\n\t\n\tsetTooltipPoints: noop\n});\nseriesTypes.scatter = ScatterSeries;\n\n/**\n * Set the default options for pie\n */\ndefaultPlotOptions.pie = merge(defaultSeriesOptions, {\n\tborderColor: '#FFFFFF',\n\tborderWidth: 1,\n\tcenter: [null, null],\n\tclip: false,\n\tcolorByPoint: true, // always true for pies\n\tdataLabels: {\n\t\t// align: null,\n\t\t// connectorWidth: 1,\n\t\t// connectorColor: point.color,\n\t\t// connectorPadding: 5,\n\t\tdistance: 30,\n\t\tenabled: true,\n\t\tformatter: function () {\n\t\t\treturn this.point.name;\n\t\t}\n\t\t// softConnector: true,\n\t\t//y: 0\n\t},\n\tignoreHiddenPoint: true,\n\t//innerSize: 0,\n\tlegendType: 'point',\n\tmarker: null, // point options are specified in the base options\n\tsize: null,\n\tshowInLegend: false,\n\tslicedOffset: 10,\n\tstates: {\n\t\thover: {\n\t\t\tbrightness: 0.1,\n\t\t\tshadow: false\n\t\t}\n\t},\n\tstickyTracking: false,\n\ttooltip: {\n\t\tfollowPointer: true\n\t}\n});\n\n/**\n * Extended point object for pies\n */\nvar PiePoint = extendClass(Point, {\n\t/**\n\t * Initiate the pie slice\n\t */\n\tinit: function () {\n\n\t\tPoint.prototype.init.apply(this, arguments);\n\n\t\tvar point = this,\n\t\t\ttoggleSlice;\n\n\t\t// Disallow negative values (#1530)\n\t\tif (point.y < 0) {\n\t\t\tpoint.y = null;\n\t\t}\n\n\t\t//visible: options.visible !== false,\n\t\textend(point, {\n\t\t\tvisible: point.visible !== false,\n\t\t\tname: pick(point.name, 'Slice')\n\t\t});\n\n\t\t// add event listener for select\n\t\ttoggleSlice = function (e) {\n\t\t\tpoint.slice(e.type === 'select');\n\t\t};\n\t\taddEvent(point, 'select', toggleSlice);\n\t\taddEvent(point, 'unselect', toggleSlice);\n\n\t\treturn point;\n\t},\n\n\t/**\n\t * Toggle the visibility of the pie slice\n\t * @param {Boolean} vis Whether to show the slice or not. If undefined, the\n\t *    visibility is toggled\n\t */\n\tsetVisible: function (vis) {\n\t\tvar point = this,\n\t\t\tseries = point.series,\n\t\t\tchart = series.chart,\n\t\t\tmethod;\n\n\t\t// if called without an argument, toggle visibility\n\t\tpoint.visible = point.options.visible = vis = vis === UNDEFINED ? !point.visible : vis;\n\t\tseries.options.data[inArray(point, series.data)] = point.options; // update userOptions.data\n\t\t\n\t\tmethod = vis ? 'show' : 'hide';\n\n\t\t// Show and hide associated elements\n\t\teach(['graphic', 'dataLabel', 'connector', 'shadowGroup'], function (key) {\n\t\t\tif (point[key]) {\n\t\t\t\tpoint[key][method]();\n\t\t\t}\n\t\t});\n\n\t\tif (point.legendItem) {\n\t\t\tchart.legend.colorizeItem(point, vis);\n\t\t}\n\t\t\n\t\t// Handle ignore hidden slices\n\t\tif (!series.isDirty && series.options.ignoreHiddenPoint) {\n\t\t\tseries.isDirty = true;\n\t\t\tchart.redraw();\n\t\t}\n\t},\n\n\t/**\n\t * Set or toggle whether the slice is cut out from the pie\n\t * @param {Boolean} sliced When undefined, the slice state is toggled\n\t * @param {Boolean} redraw Whether to redraw the chart. True by default.\n\t */\n\tslice: function (sliced, redraw, animation) {\n\t\tvar point = this,\n\t\t\tseries = point.series,\n\t\t\tchart = series.chart,\n\t\t\ttranslation;\n\n\t\tsetAnimation(animation, chart);\n\n\t\t// redraw is true by default\n\t\tredraw = pick(redraw, true);\n\n\t\t// if called without an argument, toggle\n\t\tpoint.sliced = point.options.sliced = sliced = defined(sliced) ? sliced : !point.sliced;\n\t\tseries.options.data[inArray(point, series.data)] = point.options; // update userOptions.data\n\n\t\ttranslation = sliced ? point.slicedTranslation : {\n\t\t\ttranslateX: 0,\n\t\t\ttranslateY: 0\n\t\t};\n\n\t\tpoint.graphic.animate(translation);\n\t\t\n\t\tif (point.shadowGroup) {\n\t\t\tpoint.shadowGroup.animate(translation);\n\t\t}\n\n\t}\n});\n\n/**\n * The Pie series class\n */\nvar PieSeries = {\n\ttype: 'pie',\n\tisCartesian: false,\n\tpointClass: PiePoint,\n\trequireSorting: false,\n\tnoSharedTooltip: true,\n\ttrackerGroups: ['group', 'dataLabelsGroup'],\n\tpointAttrToOptions: { // mapping between SVG attributes and the corresponding options\n\t\tstroke: 'borderColor',\n\t\t'stroke-width': 'borderWidth',\n\t\tfill: 'color'\n\t},\n\n\t/**\n\t * Pies have one color each point\n\t */\n\tgetColor: noop,\n\n\t/**\n\t * Animate the pies in\n\t */\n\tanimate: function (init) {\n\t\tvar series = this,\n\t\t\tpoints = series.points,\n\t\t\tstartAngleRad = series.startAngleRad;\n\n\t\tif (!init) {\n\t\t\teach(points, function (point) {\n\t\t\t\tvar graphic = point.graphic,\n\t\t\t\t\targs = point.shapeArgs;\n\n\t\t\t\tif (graphic) {\n\t\t\t\t\t// start values\n\t\t\t\t\tgraphic.attr({\n\t\t\t\t\t\tr: series.center[3] / 2, // animate from inner radius (#779)\n\t\t\t\t\t\tstart: startAngleRad,\n\t\t\t\t\t\tend: startAngleRad\n\t\t\t\t\t});\n\n\t\t\t\t\t// animate\n\t\t\t\t\tgraphic.animate({\n\t\t\t\t\t\tr: args.r,\n\t\t\t\t\t\tstart: args.start,\n\t\t\t\t\t\tend: args.end\n\t\t\t\t\t}, series.options.animation);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// delete this function to allow it only once\n\t\t\tseries.animate = null;\n\t\t}\n\t},\n\n\t/**\n\t * Extend the basic setData method by running processData and generatePoints immediately,\n\t * in order to access the points from the legend.\n\t */\n\tsetData: function (data, redraw) {\n\t\tSeries.prototype.setData.call(this, data, false);\n\t\tthis.processData();\n\t\tthis.generatePoints();\n\t\tif (pick(redraw, true)) {\n\t\t\tthis.chart.redraw();\n\t\t} \n\t},\n\n\t/**\n\t * Extend the generatePoints method by adding total and percentage properties to each point\n\t */\n\tgeneratePoints: function () {\n\t\tvar i,\n\t\t\ttotal = 0,\n\t\t\tpoints,\n\t\t\tlen,\n\t\t\tpoint,\n\t\t\tignoreHiddenPoint = this.options.ignoreHiddenPoint;\n\n\t\tSeries.prototype.generatePoints.call(this);\n\n\t\t// Populate local vars\n\t\tpoints = this.points;\n\t\tlen = points.length;\n\t\t\n\t\t// Get the total sum\n\t\tfor (i = 0; i < len; i++) {\n\t\t\tpoint = points[i];\n\t\t\ttotal += (ignoreHiddenPoint && !point.visible) ? 0 : point.y;\n\t\t}\n\t\tthis.total = total;\n\n\t\t// Set each point's properties\n\t\tfor (i = 0; i < len; i++) {\n\t\t\tpoint = points[i];\n\t\t\tpoint.percentage = total > 0 ? (point.y / total) * 100 : 0;\n\t\t\tpoint.total = total;\n\t\t}\n\t\t\n\t},\n\t\n\t/**\n\t * Get the center of the pie based on the size and center options relative to the  \n\t * plot area. Borrowed by the polar and gauge series types.\n\t */\n\tgetCenter: function () {\n\t\t\n\t\tvar options = this.options,\n\t\t\tchart = this.chart,\n\t\t\tslicingRoom = 2 * (options.slicedOffset || 0),\n\t\t\thandleSlicingRoom,\n\t\t\tplotWidth = chart.plotWidth - 2 * slicingRoom,\n\t\t\tplotHeight = chart.plotHeight - 2 * slicingRoom,\n\t\t\tcenterOption = options.center,\n\t\t\tpositions = [pick(centerOption[0], '50%'), pick(centerOption[1], '50%'), options.size || '100%', options.innerSize || 0],\n\t\t\tsmallestSize = mathMin(plotWidth, plotHeight),\n\t\t\tisPercent;\n\t\t\n\t\treturn map(positions, function (length, i) {\n\t\t\tisPercent = /%$/.test(length);\n\t\t\thandleSlicingRoom = i < 2 || (i === 2 && isPercent);\n\t\t\treturn (isPercent ?\n\t\t\t\t// i == 0: centerX, relative to width\n\t\t\t\t// i == 1: centerY, relative to height\n\t\t\t\t// i == 2: size, relative to smallestSize\n\t\t\t\t// i == 4: innerSize, relative to smallestSize\n\t\t\t\t[plotWidth, plotHeight, smallestSize, smallestSize][i] *\n\t\t\t\t\tpInt(length) / 100 :\n\t\t\t\tlength) + (handleSlicingRoom ? slicingRoom : 0);\n\t\t});\n\t},\n\t\n\t/**\n\t * Do translation for pie slices\n\t */\n\ttranslate: function (positions) {\n\t\tthis.generatePoints();\n\t\t\n\t\tvar series = this,\n\t\t\tcumulative = 0,\n\t\t\tprecision = 1000, // issue #172\n\t\t\toptions = series.options,\n\t\t\tslicedOffset = options.slicedOffset,\n\t\t\tconnectorOffset = slicedOffset + options.borderWidth,\n\t\t\tstart,\n\t\t\tend,\n\t\t\tangle,\n\t\t\tstartAngle = options.startAngle || 0,\n\t\t\tstartAngleRad = series.startAngleRad = mathPI / 180 * (startAngle - 90),\n\t\t\tendAngleRad = series.endAngleRad = mathPI / 180 * ((options.endAngle || (startAngle + 360)) - 90), // docs\n\t\t\tcirc = endAngleRad - startAngleRad, //2 * mathPI,\n\t\t\tpoints = series.points,\n\t\t\tradiusX, // the x component of the radius vector for a given point\n\t\t\tradiusY,\n\t\t\tlabelDistance = options.dataLabels.distance,\n\t\t\tignoreHiddenPoint = options.ignoreHiddenPoint,\n\t\t\ti,\n\t\t\tlen = points.length,\n\t\t\tpoint;\n\n\t\t// Get positions - either an integer or a percentage string must be given.\n\t\t// If positions are passed as a parameter, we're in a recursive loop for adjusting\n\t\t// space for data labels.\n\t\tif (!positions) {\n\t\t\tseries.center = positions = series.getCenter();\n\t\t}\n\n\t\t// utility for getting the x value from a given y, used for anticollision logic in data labels\n\t\tseries.getX = function (y, left) {\n\n\t\t\tangle = math.asin((y - positions[1]) / (positions[2] / 2 + labelDistance));\n\n\t\t\treturn positions[0] +\n\t\t\t\t(left ? -1 : 1) *\n\t\t\t\t(mathCos(angle) * (positions[2] / 2 + labelDistance));\n\t\t};\n\n\t\t// Calculate the geometry for each point\n\t\tfor (i = 0; i < len; i++) {\n\t\t\t\n\t\t\tpoint = points[i];\n\t\t\t\n\t\t\t// set start and end angle\n\t\t\tstart = startAngleRad + (cumulative * circ);\n\t\t\tif (!ignoreHiddenPoint || point.visible) {\n\t\t\t\tcumulative += point.percentage / 100;\n\t\t\t}\n\t\t\tend = startAngleRad + (cumulative * circ);\n\n\t\t\t// set the shape\n\t\t\tpoint.shapeType = 'arc';\n\t\t\tpoint.shapeArgs = {\n\t\t\t\tx: positions[0],\n\t\t\t\ty: positions[1],\n\t\t\t\tr: positions[2] / 2,\n\t\t\t\tinnerR: positions[3] / 2,\n\t\t\t\tstart: mathRound(start * precision) / precision,\n\t\t\t\tend: mathRound(end * precision) / precision\n\t\t\t};\n\n\t\t\t// center for the sliced out slice\n\t\t\tangle = (end + start) / 2;\n\t\t\tif (angle > 0.75 * circ) {\n\t\t\t\tangle -= 2 * mathPI;\n\t\t\t}\n\t\t\tpoint.slicedTranslation = {\n\t\t\t\ttranslateX: mathRound(mathCos(angle) * slicedOffset),\n\t\t\t\ttranslateY: mathRound(mathSin(angle) * slicedOffset)\n\t\t\t};\n\n\t\t\t// set the anchor point for tooltips\n\t\t\tradiusX = mathCos(angle) * positions[2] / 2;\n\t\t\tradiusY = mathSin(angle) * positions[2] / 2;\n\t\t\tpoint.tooltipPos = [\n\t\t\t\tpositions[0] + radiusX * 0.7,\n\t\t\t\tpositions[1] + radiusY * 0.7\n\t\t\t];\n\t\t\t\n\t\t\tpoint.half = angle < -mathPI / 2 || angle > mathPI / 2 ? 1 : 0;\n\t\t\tpoint.angle = angle;\n\n\t\t\t// set the anchor point for data labels\n\t\t\tconnectorOffset = mathMin(connectorOffset, labelDistance / 2); // #1678\n\t\t\tpoint.labelPos = [\n\t\t\t\tpositions[0] + radiusX + mathCos(angle) * labelDistance, // first break of connector\n\t\t\t\tpositions[1] + radiusY + mathSin(angle) * labelDistance, // a/a\n\t\t\t\tpositions[0] + radiusX + mathCos(angle) * connectorOffset, // second break, right outside pie\n\t\t\t\tpositions[1] + radiusY + mathSin(angle) * connectorOffset, // a/a\n\t\t\t\tpositions[0] + radiusX, // landing point for connector\n\t\t\t\tpositions[1] + radiusY, // a/a\n\t\t\t\tlabelDistance < 0 ? // alignment\n\t\t\t\t\t'center' :\n\t\t\t\t\tpoint.half ? 'right' : 'left', // alignment\n\t\t\t\tangle // center angle\n\t\t\t];\n\n\t\t}\n\t},\n\n\tsetTooltipPoints: noop,\n\tdrawGraph: null,\n\n\t/**\n\t * Draw the data points\n\t */\n\tdrawPoints: function () {\n\t\tvar series = this,\n\t\t\tchart = series.chart,\n\t\t\trenderer = chart.renderer,\n\t\t\tgroupTranslation,\n\t\t\t//center,\n\t\t\tgraphic,\n\t\t\t//group,\n\t\t\tshadow = series.options.shadow,\n\t\t\tshadowGroup,\n\t\t\tshapeArgs;\n\n\t\tif (shadow && !series.shadowGroup) {\n\t\t\tseries.shadowGroup = renderer.g('shadow')\n\t\t\t\t.add(series.group);\n\t\t}\n\n\t\t// draw the slices\n\t\teach(series.points, function (point) {\n\t\t\tgraphic = point.graphic;\n\t\t\tshapeArgs = point.shapeArgs;\n\t\t\tshadowGroup = point.shadowGroup;\n\n\t\t\t// put the shadow behind all points\n\t\t\tif (shadow && !shadowGroup) {\n\t\t\t\tshadowGroup = point.shadowGroup = renderer.g('shadow')\n\t\t\t\t\t.add(series.shadowGroup);\n\t\t\t}\n\n\t\t\t// if the point is sliced, use special translation, else use plot area traslation\n\t\t\tgroupTranslation = point.sliced ? point.slicedTranslation : {\n\t\t\t\ttranslateX: 0,\n\t\t\t\ttranslateY: 0\n\t\t\t};\n\n\t\t\t//group.translate(groupTranslation[0], groupTranslation[1]);\n\t\t\tif (shadowGroup) {\n\t\t\t\tshadowGroup.attr(groupTranslation);\n\t\t\t}\n\n\t\t\t// draw the slice\n\t\t\tif (graphic) {\n\t\t\t\tgraphic.animate(extend(shapeArgs, groupTranslation));\n\t\t\t} else {\n\t\t\t\tpoint.graphic = graphic = renderer.arc(shapeArgs)\n\t\t\t\t\t.setRadialReference(series.center)\n\t\t\t\t\t.attr(\n\t\t\t\t\t\tpoint.pointAttr[point.selected ? SELECT_STATE : NORMAL_STATE]\n\t\t\t\t\t)\n\t\t\t\t\t.attr({ 'stroke-linejoin': 'round' })\n\t\t\t\t\t.attr(groupTranslation)\n\t\t\t\t\t.add(series.group)\n\t\t\t\t\t.shadow(shadow, shadowGroup);\t\n\t\t\t}\n\n\t\t\t// detect point specific visibility\n\t\t\tif (point.visible === false) {\n\t\t\t\tpoint.setVisible(false);\n\t\t\t}\n\n\t\t});\n\n\t},\n\n\t/**\n\t * Utility for sorting data labels\n\t */\n\tsortByAngle: function (points, sign) {\n\t\tpoints.sort(function (a, b) {\n\t\t\treturn a.angle !== undefined && (b.angle - a.angle) * sign;\n\t\t});\n\t},\n\n\t/**\n\t * Override the base drawDataLabels method by pie specific functionality\n\t */\n\tdrawDataLabels: function () {\n\t\tvar series = this,\n\t\t\tdata = series.data,\n\t\t\tpoint,\n\t\t\tchart = series.chart,\n\t\t\toptions = series.options.dataLabels,\n\t\t\tconnectorPadding = pick(options.connectorPadding, 10),\n\t\t\tconnectorWidth = pick(options.connectorWidth, 1),\n\t\t\tplotWidth = chart.plotWidth,\n\t\t\tplotHeight = chart.plotHeight,\n\t\t\tconnector,\n\t\t\tconnectorPath,\n\t\t\tsoftConnector = pick(options.softConnector, true),\n\t\t\tdistanceOption = options.distance,\n\t\t\tseriesCenter = series.center,\n\t\t\tradius = seriesCenter[2] / 2,\n\t\t\tcenterY = seriesCenter[1],\n\t\t\toutside = distanceOption > 0,\n\t\t\tdataLabel,\n\t\t\tdataLabelWidth,\n\t\t\tlabelPos,\n\t\t\tlabelHeight,\n\t\t\thalves = [// divide the points into right and left halves for anti collision\n\t\t\t\t[], // right\n\t\t\t\t[]  // left\n\t\t\t],\n\t\t\tx,\n\t\t\ty,\n\t\t\tvisibility,\n\t\t\trankArr,\n\t\t\ti,\n\t\t\tj,\n\t\t\toverflow = [0, 0, 0, 0], // top, right, bottom, left\n\t\t\tsort = function (a, b) {\n\t\t\t\treturn b.y - a.y;\n\t\t\t};\n\n\t\t// get out if not enabled\n\t\tif (!series.visible || (!options.enabled && !series._hasPointLabels)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// run parent method\n\t\tSeries.prototype.drawDataLabels.apply(series);\n\n\t\t// arrange points for detection collision\n\t\teach(data, function (point) {\n\t\t\tif (point.dataLabel) { // it may have been cancelled in the base method (#407)\n\t\t\t\thalves[point.half].push(point);\n\t\t\t}\n\t\t});\n\n\t\t// assume equal label heights\n\t\ti = 0;\n\t\twhile (!labelHeight && data[i]) { // #1569\n\t\t\tlabelHeight = data[i] && data[i].dataLabel && (data[i].dataLabel.getBBox().height || 21); // 21 is for #968\n\t\t\ti++;\n\t\t}\n\n\t\t/* Loop over the points in each half, starting from the top and bottom\n\t\t * of the pie to detect overlapping labels.\n\t\t */\n\t\ti = 2;\n\t\twhile (i--) {\n\n\t\t\tvar slots = [],\n\t\t\t\tslotsLength,\n\t\t\t\tusedSlots = [],\n\t\t\t\tpoints = halves[i],\n\t\t\t\tpos,\n\t\t\t\tlength = points.length,\n\t\t\t\tslotIndex;\n\t\t\t\t\n\t\t\t// Sort by angle\n\t\t\tseries.sortByAngle(points, i - 0.5);\n\n\t\t\t// Only do anti-collision when we are outside the pie and have connectors (#856)\n\t\t\tif (distanceOption > 0) {\n\t\t\t\t\n\t\t\t\t// build the slots\n\t\t\t\tfor (pos = centerY - radius - distanceOption; pos <= centerY + radius + distanceOption; pos += labelHeight) {\n\t\t\t\t\tslots.push(pos);\n\t\t\t\t\t\n\t\t\t\t\t// visualize the slot\n\t\t\t\t\t/*\n\t\t\t\t\tvar slotX = series.getX(pos, i) + chart.plotLeft - (i ? 100 : 0),\n\t\t\t\t\t\tslotY = pos + chart.plotTop;\n\t\t\t\t\tif (!isNaN(slotX)) {\n\t\t\t\t\t\tchart.renderer.rect(slotX, slotY - 7, 100, labelHeight, 1)\n\t\t\t\t\t\t\t.attr({\n\t\t\t\t\t\t\t\t'stroke-width': 1,\n\t\t\t\t\t\t\t\tstroke: 'silver'\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.add();\n\t\t\t\t\t\tchart.renderer.text('Slot '+ (slots.length - 1), slotX, slotY + 4)\n\t\t\t\t\t\t\t.attr({\n\t\t\t\t\t\t\t\tfill: 'silver'\n\t\t\t\t\t\t\t}).add();\n\t\t\t\t\t}\n\t\t\t\t\t*/\n\t\t\t\t}\n\t\t\t\tslotsLength = slots.length;\n\t\n\t\t\t\t// if there are more values than available slots, remove lowest values\n\t\t\t\tif (length > slotsLength) {\n\t\t\t\t\t// create an array for sorting and ranking the points within each quarter\n\t\t\t\t\trankArr = [].concat(points);\n\t\t\t\t\trankArr.sort(sort);\n\t\t\t\t\tj = length;\n\t\t\t\t\twhile (j--) {\n\t\t\t\t\t\trankArr[j].rank = j;\n\t\t\t\t\t}\n\t\t\t\t\tj = length;\n\t\t\t\t\twhile (j--) {\n\t\t\t\t\t\tif (points[j].rank >= slotsLength) {\n\t\t\t\t\t\t\tpoints.splice(j, 1);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tlength = points.length;\n\t\t\t\t}\n\t\n\t\t\t\t// The label goes to the nearest open slot, but not closer to the edge than\n\t\t\t\t// the label's index.\n\t\t\t\tfor (j = 0; j < length; j++) {\n\t\n\t\t\t\t\tpoint = points[j];\n\t\t\t\t\tlabelPos = point.labelPos;\n\t\n\t\t\t\t\tvar closest = 9999,\n\t\t\t\t\t\tdistance,\n\t\t\t\t\t\tslotI;\n\t\n\t\t\t\t\t// find the closest slot index\n\t\t\t\t\tfor (slotI = 0; slotI < slotsLength; slotI++) {\n\t\t\t\t\t\tdistance = mathAbs(slots[slotI] - labelPos[1]);\n\t\t\t\t\t\tif (distance < closest) {\n\t\t\t\t\t\t\tclosest = distance;\n\t\t\t\t\t\t\tslotIndex = slotI;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\n\t\t\t\t\t// if that slot index is closer to the edges of the slots, move it\n\t\t\t\t\t// to the closest appropriate slot\n\t\t\t\t\tif (slotIndex < j && slots[j] !== null) { // cluster at the top\n\t\t\t\t\t\tslotIndex = j;\n\t\t\t\t\t} else if (slotsLength  < length - j + slotIndex && slots[j] !== null) { // cluster at the bottom\n\t\t\t\t\t\tslotIndex = slotsLength - length + j;\n\t\t\t\t\t\twhile (slots[slotIndex] === null) { // make sure it is not taken\n\t\t\t\t\t\t\tslotIndex++;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Slot is taken, find next free slot below. In the next run, the next slice will find the\n\t\t\t\t\t\t// slot above these, because it is the closest one\n\t\t\t\t\t\twhile (slots[slotIndex] === null) { // make sure it is not taken\n\t\t\t\t\t\t\tslotIndex++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\n\t\t\t\t\tusedSlots.push({ i: slotIndex, y: slots[slotIndex] });\n\t\t\t\t\tslots[slotIndex] = null; // mark as taken\n\t\t\t\t}\n\t\t\t\t// sort them in order to fill in from the top\n\t\t\t\tusedSlots.sort(sort);\n\t\t\t}\n\n\t\t\t// now the used slots are sorted, fill them up sequentially\n\t\t\tfor (j = 0; j < length; j++) {\n\t\t\t\t\n\t\t\t\tvar slot, naturalY;\n\n\t\t\t\tpoint = points[j];\n\t\t\t\tlabelPos = point.labelPos;\n\t\t\t\tdataLabel = point.dataLabel;\n\t\t\t\tvisibility = point.visible === false ? HIDDEN : VISIBLE;\n\t\t\t\tnaturalY = labelPos[1];\n\t\t\t\t\n\t\t\t\tif (distanceOption > 0) {\n\t\t\t\t\tslot = usedSlots.pop();\n\t\t\t\t\tslotIndex = slot.i;\n\n\t\t\t\t\t// if the slot next to currrent slot is free, the y value is allowed\n\t\t\t\t\t// to fall back to the natural position\n\t\t\t\t\ty = slot.y;\n\t\t\t\t\tif ((naturalY > y && slots[slotIndex + 1] !== null) ||\n\t\t\t\t\t\t\t(naturalY < y &&  slots[slotIndex - 1] !== null)) {\n\t\t\t\t\t\ty = naturalY;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t} else {\n\t\t\t\t\ty = naturalY;\n\t\t\t\t}\n\n\t\t\t\t// get the x - use the natural x position for first and last slot, to prevent the top\n\t\t\t\t// and botton slice connectors from touching each other on either side\n\t\t\t\tx = options.justify ? \n\t\t\t\t\tseriesCenter[0] + (i ? -1 : 1) * (radius + distanceOption) :\n\t\t\t\t\tseries.getX(slotIndex === 0 || slotIndex === slots.length - 1 ? naturalY : y, i);\n\t\t\t\t\n\t\t\t\n\t\t\t\t// Record the placement and visibility\n\t\t\t\tdataLabel._attr = {\n\t\t\t\t\tvisibility: visibility,\n\t\t\t\t\talign: labelPos[6]\n\t\t\t\t};\n\t\t\t\tdataLabel._pos = {\n\t\t\t\t\tx: x + options.x +\n\t\t\t\t\t\t({ left: connectorPadding, right: -connectorPadding }[labelPos[6]] || 0),\n\t\t\t\t\ty: y + options.y - 10 // 10 is for the baseline (label vs text)\n\t\t\t\t};\n\t\t\t\tdataLabel.connX = x;\n\t\t\t\tdataLabel.connY = y;\n\t\t\t\t\n\t\t\t\t\t\t\n\t\t\t\t// Detect overflowing data labels\n\t\t\t\tif (this.options.size === null) {\n\t\t\t\t\tdataLabelWidth = dataLabel.width;\n\t\t\t\t\t// Overflow left\n\t\t\t\t\tif (x - dataLabelWidth < connectorPadding) {\n\t\t\t\t\t\toverflow[3] = mathMax(mathRound(dataLabelWidth - x + connectorPadding), overflow[3]);\n\t\t\t\t\t\t\n\t\t\t\t\t// Overflow right\n\t\t\t\t\t} else if (x + dataLabelWidth > plotWidth - connectorPadding) {\n\t\t\t\t\t\toverflow[1] = mathMax(mathRound(x + dataLabelWidth - plotWidth + connectorPadding), overflow[1]);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// Overflow top\n\t\t\t\t\tif (y - labelHeight / 2 < 0) {\n\t\t\t\t\t\toverflow[0] = mathMax(mathRound(-y + labelHeight / 2), overflow[0]);\n\t\t\t\t\t\t\n\t\t\t\t\t// Overflow left\n\t\t\t\t\t} else if (y + labelHeight / 2 > plotHeight) {\n\t\t\t\t\t\toverflow[2] = mathMax(mathRound(y + labelHeight / 2 - plotHeight), overflow[2]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} // for each point\n\t\t} // for each half\n\t\t\n\t\t// Do not apply the final placement and draw the connectors until we have verified\n\t\t// that labels are not spilling over. \n\t\tif (arrayMax(overflow) === 0 || this.verifyDataLabelOverflow(overflow)) {\n\t\t\t\n\t\t\t// Place the labels in the final position\n\t\t\tthis.placeDataLabels();\n\t\t\t\n\t\t\t// Draw the connectors\n\t\t\tif (outside && connectorWidth) {\n\t\t\t\teach(this.points, function (point) {\n\t\t\t\t\tconnector = point.connector;\n\t\t\t\t\tlabelPos = point.labelPos;\n\t\t\t\t\tdataLabel = point.dataLabel;\n\t\t\t\t\t\n\t\t\t\t\tif (dataLabel && dataLabel._pos) {\n\t\t\t\t\t\tvisibility = dataLabel._attr.visibility;\n\t\t\t\t\t\tx = dataLabel.connX;\n\t\t\t\t\t\ty = dataLabel.connY;\n\t\t\t\t\t\tconnectorPath = softConnector ? [\n\t\t\t\t\t\t\tM,\n\t\t\t\t\t\t\tx + (labelPos[6] === 'left' ? 5 : -5), y, // end of the string at the label\n\t\t\t\t\t\t\t'C',\n\t\t\t\t\t\t\tx, y, // first break, next to the label\n\t\t\t\t\t\t\t2 * labelPos[2] - labelPos[4], 2 * labelPos[3] - labelPos[5],\n\t\t\t\t\t\t\tlabelPos[2], labelPos[3], // second break\n\t\t\t\t\t\t\tL,\n\t\t\t\t\t\t\tlabelPos[4], labelPos[5] // base\n\t\t\t\t\t\t] : [\n\t\t\t\t\t\t\tM,\n\t\t\t\t\t\t\tx + (labelPos[6] === 'left' ? 5 : -5), y, // end of the string at the label\n\t\t\t\t\t\t\tL,\n\t\t\t\t\t\t\tlabelPos[2], labelPos[3], // second break\n\t\t\t\t\t\t\tL,\n\t\t\t\t\t\t\tlabelPos[4], labelPos[5] // base\n\t\t\t\t\t\t];\n\t\t\n\t\t\t\t\t\tif (connector) {\n\t\t\t\t\t\t\tconnector.animate({ d: connectorPath });\n\t\t\t\t\t\t\tconnector.attr('visibility', visibility);\n\t\t\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tpoint.connector = connector = series.chart.renderer.path(connectorPath).attr({\n\t\t\t\t\t\t\t\t'stroke-width': connectorWidth,\n\t\t\t\t\t\t\t\tstroke: options.connectorColor || point.color || '#606060',\n\t\t\t\t\t\t\t\tvisibility: visibility\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.add(series.group);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else if (connector) {\n\t\t\t\t\t\tpoint.connector = connector.destroy();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\t\t\t\n\t\t}\n\t},\n\t\n\t/**\n\t * Verify whether the data labels are allowed to draw, or we should run more translation and data\n\t * label positioning to keep them inside the plot area. Returns true when data labels are ready \n\t * to draw.\n\t */\n\tverifyDataLabelOverflow: function (overflow) {\n\t\t\n\t\tvar center = this.center,\n\t\t\toptions = this.options,\n\t\t\tcenterOption = options.center,\n\t\t\tminSize = options.minSize || 80,\n\t\t\tnewSize = minSize,\n\t\t\tret;\n\t\t\t\n\t\t// Handle horizontal size and center\n\t\tif (centerOption[0] !== null) { // Fixed center\n\t\t\tnewSize = mathMax(center[2] - mathMax(overflow[1], overflow[3]), minSize);\n\t\t\t\n\t\t} else { // Auto center\n\t\t\tnewSize = mathMax(\n\t\t\t\tcenter[2] - overflow[1] - overflow[3], // horizontal overflow\t\t\t\t\t\n\t\t\t\tminSize\n\t\t\t);\n\t\t\tcenter[0] += (overflow[3] - overflow[1]) / 2; // horizontal center\n\t\t}\n\t\t\n\t\t// Handle vertical size and center\n\t\tif (centerOption[1] !== null) { // Fixed center\n\t\t\tnewSize = mathMax(mathMin(newSize, center[2] - mathMax(overflow[0], overflow[2])), minSize);\n\t\t\t\n\t\t} else { // Auto center\n\t\t\tnewSize = mathMax(\n\t\t\t\tmathMin(\n\t\t\t\t\tnewSize,\t\t\n\t\t\t\t\tcenter[2] - overflow[0] - overflow[2] // vertical overflow\n\t\t\t\t),\n\t\t\t\tminSize\n\t\t\t);\n\t\t\tcenter[1] += (overflow[0] - overflow[2]) / 2; // vertical center\n\t\t}\n\t\t\n\t\t// If the size must be decreased, we need to run translate and drawDataLabels again\n\t\tif (newSize < center[2]) {\n\t\t\tcenter[2] = newSize;\n\t\t\tthis.translate(center);\n\t\t\teach(this.points, function (point) {\n\t\t\t\tif (point.dataLabel) {\n\t\t\t\t\tpoint.dataLabel._pos = null; // reset\n\t\t\t\t}\n\t\t\t});\n\t\t\tthis.drawDataLabels();\n\t\t\t\n\t\t// Else, return true to indicate that the pie and its labels is within the plot area\n\t\t} else {\n\t\t\tret = true;\n\t\t}\n\t\treturn ret;\n\t},\n\t\n\t/**\n\t * Perform the final placement of the data labels after we have verified that they\n\t * fall within the plot area.\n\t */\n\tplaceDataLabels: function () {\n\t\teach(this.points, function (point) {\n\t\t\tvar dataLabel = point.dataLabel,\n\t\t\t\t_pos;\n\t\t\t\n\t\t\tif (dataLabel) {\n\t\t\t\t_pos = dataLabel._pos;\n\t\t\t\tif (_pos) {\n\t\t\t\t\tdataLabel.attr(dataLabel._attr);\t\t\t\n\t\t\t\t\tdataLabel[dataLabel.moved ? 'animate' : 'attr'](_pos);\n\t\t\t\t\tdataLabel.moved = true;\n\t\t\t\t} else if (dataLabel) {\n\t\t\t\t\tdataLabel.attr({ y: -999 });\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\t\n\talignDataLabel: noop,\n\n\t/**\n\t * Draw point specific tracker objects. Inherit directly from column series.\n\t */\n\tdrawTracker: ColumnSeries.prototype.drawTracker,\n\n\t/**\n\t * Use a simple symbol from column prototype\n\t */\n\tdrawLegendSymbol: AreaSeries.prototype.drawLegendSymbol,\n\n\t/**\n\t * Pies don't have point marker symbols\n\t */\n\tgetSymbol: noop\n\n};\nPieSeries = extendClass(Series, PieSeries);\nseriesTypes.pie = PieSeries;\n\n\n// global variables\nextend(Highcharts, {\n\t\n\t// Constructors\n\tAxis: Axis,\n\tChart: Chart,\n\tColor: Color,\n\tLegend: Legend,\n\tPointer: Pointer,\n\tPoint: Point,\n\tTick: Tick,\n\tTooltip: Tooltip,\n\tRenderer: Renderer,\n\tSeries: Series,\n\tSVGElement: SVGElement,\n\tSVGRenderer: SVGRenderer,\n\t\n\t// Various\n\tarrayMin: arrayMin,\n\tarrayMax: arrayMax,\n\tcharts: charts,\n\tdateFormat: dateFormat,\n\tformat: format,\n\tpathAnim: pathAnim,\n\tgetOptions: getOptions,\n\thasBidiBug: hasBidiBug,\n\tisTouchDevice: isTouchDevice,\n\tnumberFormat: numberFormat,\n\tseriesTypes: seriesTypes,\n\tsetOptions: setOptions,\n\taddEvent: addEvent,\n\tremoveEvent: removeEvent,\n\tcreateElement: createElement,\n\tdiscardElement: discardElement,\n\tcss: css,\n\teach: each,\n\textend: extend,\n\tmap: map,\n\tmerge: merge,\n\tpick: pick,\n\tsplat: splat,\n\textendClass: extendClass,\n\tpInt: pInt,\n\twrap: wrap,\n\tsvg: hasSVG,\n\tcanvas: useCanVG,\n\tvml: !hasSVG && !useCanVG,\n\tproduct: PRODUCT,\n\tversion: VERSION\n});\n}());\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/annotations.js",
    "content": "(function(i,C){function m(a){return typeof a===\"number\"}function n(a){return a!==D&&a!==null}var D,p,r,s=i.Chart,t=i.extend,z=i.each;r=[\"path\",\"rect\",\"circle\"];p={top:0,left:0,center:0.5,middle:0.5,bottom:1,right:1};var u=C.inArray,A=i.merge,B=function(){this.init.apply(this,arguments)};B.prototype={init:function(a,d){var c=d.shape&&d.shape.type;this.chart=a;var b,f;f={xAxis:0,yAxis:0,title:{style:{},text:\"\",x:0,y:0},shape:{params:{stroke:\"#000000\",fill:\"transparent\",strokeWidth:2}}};b={circle:{params:{x:0,\ny:0}}};if(b[c])f.shape=A(f.shape,b[c]);this.options=A({},f,d)},render:function(a){var d=this.chart,c=this.chart.renderer,b=this.group,f=this.title,e=this.shape,h=this.options,i=h.title,l=h.shape;if(!b)b=this.group=c.g();if(!e&&l&&u(l.type,r)!==-1)e=this.shape=c[h.shape.type](l.params),e.add(b);if(!f&&i)f=this.title=c.label(i),f.add(b);b.add(d.annotations.group);this.linkObjects();a!==!1&&this.redraw()},redraw:function(){var a=this.options,d=this.chart,c=this.group,b=this.title,f=this.shape,e=this.linkedObject,\nh=d.xAxis[a.xAxis],v=d.yAxis[a.yAxis],l=a.width,w=a.height,x=p[a.anchorY],y=p[a.anchorX],j,o,g,q;if(e)j=e instanceof i.Point?\"point\":e instanceof i.Series?\"series\":null,j===\"point\"?(a.xValue=e.x,a.yValue=e.y,o=e.series):j===\"series\"&&(o=e),c.visibility!==o.group.visibility&&c.attr({visibility:o.group.visibility});e=n(a.xValue)?h.toPixels(a.xValue+h.minPointOffset)-h.minPixelPadding:a.x;j=n(a.yValue)?v.toPixels(a.yValue):a.y;if(!isNaN(e)&&!isNaN(j)&&m(e)&&m(j)){b&&(b.attr(a.title),b.css(a.title.style));\nif(f){b=t({},a.shape.params);if(a.units===\"values\"){for(g in b)u(g,[\"width\",\"x\"])>-1?b[g]=h.translate(b[g]):u(g,[\"height\",\"y\"])>-1&&(b[g]=v.translate(b[g]));b.width&&(b.width-=h.toPixels(0)-h.left);b.x&&(b.x+=h.minPixelPadding);if(a.shape.type===\"path\"){g=b.d;o=e;for(var r=j,s=g.length,k=0;k<s;)typeof g[k]===\"number\"&&typeof g[k+1]===\"number\"?(g[k]=h.toPixels(g[k])-o,g[k+1]=v.toPixels(g[k+1])-r,k+=2):k+=1}}a.shape.type===\"circle\"&&(b.x+=b.r,b.y+=b.r);f.attr(b)}c.bBox=null;if(!m(l))q=c.getBBox(),l=\nq.width;if(!m(w))q||(q=c.getBBox()),w=q.height;if(!m(y))y=p.center;if(!m(x))x=p.center;e-=l*y;j-=w*x;d.animation&&n(c.translateX)&&n(c.translateY)?c.animate({translateX:e,translateY:j}):c.translate(e,j)}},destroy:function(){var a=this,d=this.chart.annotations.allItems,c=d.indexOf(a);c>-1&&d.splice(c,1);z([\"title\",\"shape\",\"group\"],function(b){a[b]&&(a[b].destroy(),a[b]=null)});a.group=a.title=a.shape=a.chart=a.options=null},update:function(a,d){t(this.options,a);this.linkObjects();this.render(d)},\nlinkObjects:function(){var a=this.chart,d=this.linkedObject,c=d&&(d.id||d.options.id),b=this.options.linkedTo;if(n(b)){if(!n(d)||b!==c)this.linkedObject=a.get(b)}else this.linkedObject=null}};t(s.prototype,{annotations:{add:function(a,d){var c=this.allItems,b=this.chart,f,e;Object.prototype.toString.call(a)===\"[object Array]\"||(a=[a]);for(e=a.length;e--;)f=new B(b,a[e]),c.push(f),f.render(d)},redraw:function(){z(this.allItems,function(a){a.redraw()})}}});s.prototype.callbacks.push(function(a){var d=\na.options.annotations,c;c=a.renderer.g(\"annotations\");c.attr({zIndex:7});c.add();a.annotations.allItems=[];a.annotations.chart=a;a.annotations.group=c;Object.prototype.toString.call(d)===\"[object Array]\"&&d.length>0&&a.annotations.add(a.options.annotations);i.addEvent(a,\"redraw\",function(){a.annotations.redraw()})})})(Highcharts,HighchartsAdapter);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/annotations.src.js",
    "content": "(function (Highcharts, HighchartsAdapter) {\n\nvar UNDEFINED,\n\tALIGN_FACTOR,\n\tALLOWED_SHAPES,\n\tChart = Highcharts.Chart,\n\textend = Highcharts.extend,\n\teach = Highcharts.each;\n\nALLOWED_SHAPES = [\"path\", \"rect\", \"circle\"];\n\nALIGN_FACTOR = {\n\ttop: 0,\n\tleft: 0,\n\tcenter: 0.5,\n\tmiddle: 0.5,\n\tbottom: 1,\n\tright: 1\n};\n\n\n// Highcharts helper methods\nvar inArray = HighchartsAdapter.inArray,\n\tmerge = Highcharts.merge;\n\nfunction defaultOptions(shapeType) {\n\tvar shapeOptions,\n\t\toptions;\n\n\toptions = {\n\t\txAxis: 0,\n\t\tyAxis: 0,\n\t\ttitle: {\n\t\t\tstyle: {},\n\t\t\ttext: \"\",\n\t\t\tx: 0,\n\t\t\ty: 0\n\t\t},\n\t\tshape: {\n\t\t\tparams: {\n\t\t\t\tstroke: \"#000000\",\n\t\t\t\tfill: \"transparent\",\n\t\t\t\tstrokeWidth: 2\n\t\t\t}\n\t\t}\n\t};\n\n\tshapeOptions = {\n\t\tcircle: {\n\t\t\tparams: {\n\t\t\t\tx: 0,\n\t\t\t\ty: 0\n\t\t\t}\n\t\t}\n\t};\n\n\tif (shapeOptions[shapeType]) {\n\t\toptions.shape = merge(options.shape, shapeOptions[shapeType]);\n\t}\n\n\treturn options;\n}\n\nfunction isArray(obj) {\n\treturn Object.prototype.toString.call(obj) === '[object Array]';\n}\n\nfunction isNumber(n) {\n\treturn typeof n === 'number';\n}\n\nfunction defined(obj) {\n\treturn obj !== UNDEFINED && obj !== null;\n}\n\nfunction translatePath(d, xAxis, yAxis, xOffset, yOffset) {\n\tvar len = d.length,\n\t\ti = 0;\n\n\twhile (i < len) {\n\t\tif (typeof d[i] === 'number' && typeof d[i + 1] === 'number') {\n\t\t\td[i] = xAxis.toPixels(d[i]) - xOffset;\n\t\t\td[i + 1] = yAxis.toPixels(d[i + 1]) - yOffset;\n\t\t\ti += 2;\n\t\t} else {\n\t\t\ti += 1;\n\t\t}\n\t}\n\n\treturn d;\n}\n\n\n// Define annotation prototype\nvar Annotation = function () {\n\tthis.init.apply(this, arguments);\n};\nAnnotation.prototype = {\n\t/* \n\t * Initialize the annotation\n\t */\n\tinit: function (chart, options) {\n\t\tvar shapeType = options.shape && options.shape.type;\n\n\t\tthis.chart = chart;\n\t\tthis.options = merge({}, defaultOptions(shapeType), options);\n\t},\n\n\t/*\n\t * Render the annotation\n\t */\n\trender: function (redraw) {\n\t\tvar annotation = this,\n\t\t\tchart = this.chart,\n\t\t\trenderer = annotation.chart.renderer,\n\t\t\tgroup = annotation.group,\n\t\t\ttitle = annotation.title,\n\t\t\tshape = annotation.shape,\n\t\t\toptions = annotation.options,\n\t\t\ttitleOptions = options.title,\n\t\t\tshapeOptions = options.shape;\n\n\t\tif (!group) {\n\t\t\tgroup = annotation.group = renderer.g();\n\t\t}\n\n\n\t\tif (!shape && shapeOptions && inArray(shapeOptions.type, ALLOWED_SHAPES) !== -1) {\n\t\t\tshape = annotation.shape = renderer[options.shape.type](shapeOptions.params);\n\t\t\tshape.add(group);\n\t\t}\n\n\t\tif (!title && titleOptions) {\n\t\t\ttitle = annotation.title = renderer.label(titleOptions);\n\t\t\ttitle.add(group);\n\t\t}\n\n\t\tgroup.add(chart.annotations.group);\n\n\t\t// link annotations to point or series\n\t\tannotation.linkObjects();\n\n\t\tif (redraw !== false) {\n\t\t\tannotation.redraw();\n\t\t}\n\t},\n\n\t/*\n\t * Redraw the annotation title or shape after options update\n\t */\n\tredraw: function () {\n\t\tvar options = this.options,\n\t\t\tchart = this.chart,\n\t\t\tgroup = this.group,\n\t\t\ttitle = this.title,\n\t\t\tshape = this.shape,\n\t\t\tlinkedTo = this.linkedObject,\n\t\t\txAxis = chart.xAxis[options.xAxis],\n\t\t\tyAxis = chart.yAxis[options.yAxis],\n\t\t\twidth = options.width,\n\t\t\theight = options.height,\n\t\t\tanchorY = ALIGN_FACTOR[options.anchorY],\n\t\t\tanchorX = ALIGN_FACTOR[options.anchorX],\n\t\t\tresetBBox = false,\n\t\t\tshapeParams,\n\t\t\tlinkType,\n\t\t\tseries,\n\t\t\tparam,\n\t\t\tbbox,\n\t\t\tx,\n\t\t\ty;\n\n\t\tif (linkedTo) {\n\t\t\tlinkType = (linkedTo instanceof Highcharts.Point) ? 'point' :\n\t\t\t\t\t\t(linkedTo instanceof Highcharts.Series) ? 'series' : null;\n\n\t\t\tif (linkType === 'point') {\n\t\t\t\toptions.xValue = linkedTo.x;\n\t\t\t\toptions.yValue = linkedTo.y;\n\t\t\t\tseries = linkedTo.series;\n\t\t\t} else if (linkType === 'series') {\n\t\t\t\tseries = linkedTo;\n\t\t\t}\n\n\t\t\tif (group.visibility !== series.group.visibility) {\n\t\t\t\tgroup.attr({\n\t\t\t\t\tvisibility: series.group.visibility\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\n\t\t// Based on given options find annotation pixel position\n\t\tx = (defined(options.xValue) ? xAxis.toPixels(options.xValue + xAxis.minPointOffset) - xAxis.minPixelPadding : options.x);\n\t\ty = defined(options.yValue) ? yAxis.toPixels(options.yValue) : options.y;\n\n\t\tif (isNaN(x) || isNaN(y) || !isNumber(x) || !isNumber(y)) {\n\t\t\treturn;\n\t\t}\n\n\n\t\tif (title) {\n\t\t\ttitle.attr(options.title);\n\t\t\ttitle.css(options.title.style);\n\t\t\tresetBBox = true;\n\t\t}\n\n\t\tif (shape) {\n\t\t\tshapeParams = extend({}, options.shape.params);\n\n\t\t\tif (options.units === 'values') {\n\t\t\t\tfor (param in shapeParams) {\n\t\t\t\t\tif (inArray(param, ['width', 'x']) > -1) {\n\t\t\t\t\t\tshapeParams[param] = xAxis.translate(shapeParams[param]);\n\t\t\t\t\t} else if (inArray(param, ['height', 'y']) > -1) {\n\t\t\t\t\t\tshapeParams[param] = yAxis.translate(shapeParams[param]);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (shapeParams.width) {\n\t\t\t\t\tshapeParams.width -= xAxis.toPixels(0) - xAxis.left;\n\t\t\t\t}\n\n\t\t\t\tif (shapeParams.x) {\n\t\t\t\t\tshapeParams.x += xAxis.minPixelPadding;\n\t\t\t\t}\n\n\t\t\t\tif (options.shape.type === 'path') {\n\t\t\t\t\ttranslatePath(shapeParams.d, xAxis, yAxis, x, y);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// move the center of the circle to shape x/y\n\t\t\tif (options.shape.type === 'circle') {\n\t\t\t\tshapeParams.x += shapeParams.r;\n\t\t\t\tshapeParams.y += shapeParams.r;\n\t\t\t}\n\n\t\t\tresetBBox = true;\n\t\t\tshape.attr(shapeParams);\n\t\t}\n\n\t\tgroup.bBox = null;\n\n\t\t// If annotation width or height is not defined in options use bounding box size\n\t\tif (!isNumber(width)) {\n\t\t\tbbox = group.getBBox();\n\t\t\twidth = bbox.width;\n\t\t}\n\n\t\tif (!isNumber(height)) {\n\t\t\t// get bbox only if it wasn't set before\n\t\t\tif (!bbox) {\n\t\t\t\tbbox = group.getBBox();\n\t\t\t}\n\n\t\t\theight = bbox.height;\n\t\t}\n\n\t\t// Calculate anchor point\n\t\tif (!isNumber(anchorX)) {\n\t\t\tanchorX = ALIGN_FACTOR.center;\n\t\t}\n\n\t\tif (!isNumber(anchorY)) {\n\t\t\tanchorY = ALIGN_FACTOR.center;\n\t\t}\n\n\t\t// Translate group according to its dimension and anchor point\n\t\tx = x - width * anchorX;\n\t\ty = y - height * anchorY;\n\n\t\tif (chart.animation && defined(group.translateX) && defined(group.translateY)) {\n\t\t\tgroup.animate({\n\t\t\t\ttranslateX: x,\n\t\t\t\ttranslateY: y\n\t\t\t});\n\t\t} else {\n\t\t\tgroup.translate(x, y);\n\t\t}\n\t},\n\n\t/*\n\t * Destroy the annotation\n\t */\n\tdestroy: function () {\n\t\tvar annotation = this,\n\t\t\tchart = this.chart,\n\t\t\tallItems = chart.annotations.allItems,\n\t\t\tindex = allItems.indexOf(annotation);\n\n\t\tif (index > -1) {\n\t\t\tallItems.splice(index, 1);\n\t\t}\n\n\t\teach(['title', 'shape', 'group'], function (element) {\n\t\t\tif (annotation[element]) {\n\t\t\t\tannotation[element].destroy();\n\t\t\t\tannotation[element] = null;\n\t\t\t}\n\t\t});\n\n\t\tannotation.group = annotation.title = annotation.shape = annotation.chart = annotation.options = null;\n\t},\n\n\t/*\n\t * Update the annotation with a given options\n\t */\n\tupdate: function (options, redraw) {\n\t\textend(this.options, options);\n\n\t\t// update link to point or series\n\t\tthis.linkObjects();\n\n\t\tthis.render(redraw);\n\t},\n\n\tlinkObjects: function () {\n\t\tvar annotation = this,\n\t\t\tchart = annotation.chart,\n\t\t\tlinkedTo = annotation.linkedObject,\n\t\t\tlinkedId = linkedTo && (linkedTo.id || linkedTo.options.id),\n\t\t\toptions = annotation.options,\n\t\t\tid = options.linkedTo;\n\n\t\tif (!defined(id)) {\n\t\t\tannotation.linkedObject = null;\n\t\t} else if (!defined(linkedTo) || id !== linkedId) {\n\t\t\tannotation.linkedObject = chart.get(id);\n\t\t}\n\t}\n};\n\n\n// Add annotations methods to chart prototype\nextend(Chart.prototype, {\n\tannotations: {\n\t\t/*\n\t\t * Unified method for adding annotations to the chart\n\t\t */\n\t\tadd: function (options, redraw) {\n\t\t\tvar annotations = this.allItems,\n\t\t\t\tchart = this.chart,\n\t\t\t\titem,\n\t\t\t\tlen;\n\n\t\t\tif (!isArray(options)) {\n\t\t\t\toptions = [options];\n\t\t\t}\n\n\t\t\tlen = options.length;\n\n\t\t\twhile (len--) {\n\t\t\t\titem = new Annotation(chart, options[len]);\n\t\t\t\tannotations.push(item);\n\t\t\t\titem.render(redraw);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Redraw all annotations, method used in chart events\n\t\t */\n\t\tredraw: function () {\n\t\t\teach(this.allItems, function (annotation) {\n\t\t\t\tannotation.redraw();\n\t\t\t});\n\t\t}\n\t}\n});\n\n\n// Initialize on chart load\nChart.prototype.callbacks.push(function (chart) {\n\tvar options = chart.options.annotations,\n\t\tgroup;\n\n\tgroup = chart.renderer.g(\"annotations\");\n\tgroup.attr({\n\t\tzIndex: 7\n\t});\n\tgroup.add();\n\n\t// initialize empty array for annotations\n\tchart.annotations.allItems = [];\n\n\t// link chart object to annotations\n\tchart.annotations.chart = chart;\n\n\t// link annotations group element to the chart\n\tchart.annotations.group = group;\n\n\tif (isArray(options) && options.length > 0) {\n\t\tchart.annotations.add(chart.options.annotations);\n\t}\n\n\t// update annotations after chart redraw\n\tHighcharts.addEvent(chart, 'redraw', function () {\n\t\tchart.annotations.redraw();\n\t});\n});\n}(Highcharts, HighchartsAdapter));\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/canvas-tools.js",
    "content": "/*\n A class to parse color values\n @author Stoyan Stefanov <sstoo@gmail.com>\n @link   http://www.phpied.com/rgb-color-parser-in-javascript/\n Use it if you like it\n\n canvg.js - Javascript SVG parser and renderer on Canvas\n MIT Licensed \n Gabe Lerner (gabelerner@gmail.com)\n http://code.google.com/p/canvg/\n\n Requires: rgbcolor.js - http://www.phpied.com/rgb-color-parser-in-javascript/\n\n Highcharts JS v3.0.6 (2013-10-04)\n CanVGRenderer Extension module\n\n (c) 2011-2012 Torstein Hønsi, Erik Olsson\n\n License: www.highcharts.com/license\n*/\nfunction RGBColor(m){this.ok=!1;m.charAt(0)==\"#\"&&(m=m.substr(1,6));var m=m.replace(/ /g,\"\"),m=m.toLowerCase(),a={aliceblue:\"f0f8ff\",antiquewhite:\"faebd7\",aqua:\"00ffff\",aquamarine:\"7fffd4\",azure:\"f0ffff\",beige:\"f5f5dc\",bisque:\"ffe4c4\",black:\"000000\",blanchedalmond:\"ffebcd\",blue:\"0000ff\",blueviolet:\"8a2be2\",brown:\"a52a2a\",burlywood:\"deb887\",cadetblue:\"5f9ea0\",chartreuse:\"7fff00\",chocolate:\"d2691e\",coral:\"ff7f50\",cornflowerblue:\"6495ed\",cornsilk:\"fff8dc\",crimson:\"dc143c\",cyan:\"00ffff\",darkblue:\"00008b\",\ndarkcyan:\"008b8b\",darkgoldenrod:\"b8860b\",darkgray:\"a9a9a9\",darkgreen:\"006400\",darkkhaki:\"bdb76b\",darkmagenta:\"8b008b\",darkolivegreen:\"556b2f\",darkorange:\"ff8c00\",darkorchid:\"9932cc\",darkred:\"8b0000\",darksalmon:\"e9967a\",darkseagreen:\"8fbc8f\",darkslateblue:\"483d8b\",darkslategray:\"2f4f4f\",darkturquoise:\"00ced1\",darkviolet:\"9400d3\",deeppink:\"ff1493\",deepskyblue:\"00bfff\",dimgray:\"696969\",dodgerblue:\"1e90ff\",feldspar:\"d19275\",firebrick:\"b22222\",floralwhite:\"fffaf0\",forestgreen:\"228b22\",fuchsia:\"ff00ff\",\ngainsboro:\"dcdcdc\",ghostwhite:\"f8f8ff\",gold:\"ffd700\",goldenrod:\"daa520\",gray:\"808080\",green:\"008000\",greenyellow:\"adff2f\",honeydew:\"f0fff0\",hotpink:\"ff69b4\",indianred:\"cd5c5c\",indigo:\"4b0082\",ivory:\"fffff0\",khaki:\"f0e68c\",lavender:\"e6e6fa\",lavenderblush:\"fff0f5\",lawngreen:\"7cfc00\",lemonchiffon:\"fffacd\",lightblue:\"add8e6\",lightcoral:\"f08080\",lightcyan:\"e0ffff\",lightgoldenrodyellow:\"fafad2\",lightgrey:\"d3d3d3\",lightgreen:\"90ee90\",lightpink:\"ffb6c1\",lightsalmon:\"ffa07a\",lightseagreen:\"20b2aa\",lightskyblue:\"87cefa\",\nlightslateblue:\"8470ff\",lightslategray:\"778899\",lightsteelblue:\"b0c4de\",lightyellow:\"ffffe0\",lime:\"00ff00\",limegreen:\"32cd32\",linen:\"faf0e6\",magenta:\"ff00ff\",maroon:\"800000\",mediumaquamarine:\"66cdaa\",mediumblue:\"0000cd\",mediumorchid:\"ba55d3\",mediumpurple:\"9370d8\",mediumseagreen:\"3cb371\",mediumslateblue:\"7b68ee\",mediumspringgreen:\"00fa9a\",mediumturquoise:\"48d1cc\",mediumvioletred:\"c71585\",midnightblue:\"191970\",mintcream:\"f5fffa\",mistyrose:\"ffe4e1\",moccasin:\"ffe4b5\",navajowhite:\"ffdead\",navy:\"000080\",\noldlace:\"fdf5e6\",olive:\"808000\",olivedrab:\"6b8e23\",orange:\"ffa500\",orangered:\"ff4500\",orchid:\"da70d6\",palegoldenrod:\"eee8aa\",palegreen:\"98fb98\",paleturquoise:\"afeeee\",palevioletred:\"d87093\",papayawhip:\"ffefd5\",peachpuff:\"ffdab9\",peru:\"cd853f\",pink:\"ffc0cb\",plum:\"dda0dd\",powderblue:\"b0e0e6\",purple:\"800080\",red:\"ff0000\",rosybrown:\"bc8f8f\",royalblue:\"4169e1\",saddlebrown:\"8b4513\",salmon:\"fa8072\",sandybrown:\"f4a460\",seagreen:\"2e8b57\",seashell:\"fff5ee\",sienna:\"a0522d\",silver:\"c0c0c0\",skyblue:\"87ceeb\",slateblue:\"6a5acd\",\nslategray:\"708090\",snow:\"fffafa\",springgreen:\"00ff7f\",steelblue:\"4682b4\",tan:\"d2b48c\",teal:\"008080\",thistle:\"d8bfd8\",tomato:\"ff6347\",turquoise:\"40e0d0\",violet:\"ee82ee\",violetred:\"d02090\",wheat:\"f5deb3\",white:\"ffffff\",whitesmoke:\"f5f5f5\",yellow:\"ffff00\",yellowgreen:\"9acd32\"},c;for(c in a)m==c&&(m=a[c]);var d=[{re:/^rgb\\((\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})\\)$/,example:[\"rgb(123, 234, 45)\",\"rgb(255,234,245)\"],process:function(b){return[parseInt(b[1]),parseInt(b[2]),parseInt(b[3])]}},{re:/^(\\w{2})(\\w{2})(\\w{2})$/,\nexample:[\"#00ff00\",\"336699\"],process:function(b){return[parseInt(b[1],16),parseInt(b[2],16),parseInt(b[3],16)]}},{re:/^(\\w{1})(\\w{1})(\\w{1})$/,example:[\"#fb0\",\"f0f\"],process:function(b){return[parseInt(b[1]+b[1],16),parseInt(b[2]+b[2],16),parseInt(b[3]+b[3],16)]}}];for(c=0;c<d.length;c++){var b=d[c].process,k=d[c].re.exec(m);if(k)channels=b(k),this.r=channels[0],this.g=channels[1],this.b=channels[2],this.ok=!0}this.r=this.r<0||isNaN(this.r)?0:this.r>255?255:this.r;this.g=this.g<0||isNaN(this.g)?0:\nthis.g>255?255:this.g;this.b=this.b<0||isNaN(this.b)?0:this.b>255?255:this.b;this.toRGB=function(){return\"rgb(\"+this.r+\", \"+this.g+\", \"+this.b+\")\"};this.toHex=function(){var b=this.r.toString(16),a=this.g.toString(16),d=this.b.toString(16);b.length==1&&(b=\"0\"+b);a.length==1&&(a=\"0\"+a);d.length==1&&(d=\"0\"+d);return\"#\"+b+a+d};this.getHelpXML=function(){for(var b=[],k=0;k<d.length;k++)for(var c=d[k].example,j=0;j<c.length;j++)b[b.length]=c[j];for(var h in a)b[b.length]=h;c=document.createElement(\"ul\");\nc.setAttribute(\"id\",\"rgbcolor-examples\");for(k=0;k<b.length;k++)try{var l=document.createElement(\"li\"),o=new RGBColor(b[k]),n=document.createElement(\"div\");n.style.cssText=\"margin: 3px; border: 1px solid black; background:\"+o.toHex()+\"; color:\"+o.toHex();n.appendChild(document.createTextNode(\"test\"));var q=document.createTextNode(\" \"+b[k]+\" -> \"+o.toRGB()+\" -> \"+o.toHex());l.appendChild(n);l.appendChild(q);c.appendChild(l)}catch(p){}return c}}\nif(!window.console)window.console={},window.console.log=function(){},window.console.dir=function(){};if(!Array.prototype.indexOf)Array.prototype.indexOf=function(m){for(var a=0;a<this.length;a++)if(this[a]==m)return a;return-1};\n(function(){function m(){var a={FRAMERATE:30,MAX_VIRTUAL_PIXELS:3E4};a.init=function(c){a.Definitions={};a.Styles={};a.Animations=[];a.Images=[];a.ctx=c;a.ViewPort=new function(){this.viewPorts=[];this.Clear=function(){this.viewPorts=[]};this.SetCurrent=function(a,b){this.viewPorts.push({width:a,height:b})};this.RemoveCurrent=function(){this.viewPorts.pop()};this.Current=function(){return this.viewPorts[this.viewPorts.length-1]};this.width=function(){return this.Current().width};this.height=function(){return this.Current().height};\nthis.ComputeSize=function(a){return a!=null&&typeof a==\"number\"?a:a==\"x\"?this.width():a==\"y\"?this.height():Math.sqrt(Math.pow(this.width(),2)+Math.pow(this.height(),2))/Math.sqrt(2)}}};a.init();a.ImagesLoaded=function(){for(var c=0;c<a.Images.length;c++)if(!a.Images[c].loaded)return!1;return!0};a.trim=function(a){return a.replace(/^\\s+|\\s+$/g,\"\")};a.compressSpaces=function(a){return a.replace(/[\\s\\r\\t\\n]+/gm,\" \")};a.ajax=function(a){var d;return(d=window.XMLHttpRequest?new XMLHttpRequest:new ActiveXObject(\"Microsoft.XMLHTTP\"))?\n(d.open(\"GET\",a,!1),d.send(null),d.responseText):null};a.parseXml=function(a){if(window.DOMParser)return(new DOMParser).parseFromString(a,\"text/xml\");else{var a=a.replace(/<!DOCTYPE svg[^>]*>/,\"\"),d=new ActiveXObject(\"Microsoft.XMLDOM\");d.async=\"false\";d.loadXML(a);return d}};a.Property=function(c,d){this.name=c;this.value=d;this.hasValue=function(){return this.value!=null&&this.value!==\"\"};this.numValue=function(){if(!this.hasValue())return 0;var b=parseFloat(this.value);(this.value+\"\").match(/%$/)&&\n(b/=100);return b};this.valueOrDefault=function(b){return this.hasValue()?this.value:b};this.numValueOrDefault=function(b){return this.hasValue()?this.numValue():b};var b=this;this.Color={addOpacity:function(d){var c=b.value;if(d!=null&&d!=\"\"){var f=new RGBColor(b.value);f.ok&&(c=\"rgba(\"+f.r+\", \"+f.g+\", \"+f.b+\", \"+d+\")\")}return new a.Property(b.name,c)}};this.Definition={getDefinition:function(){var d=b.value.replace(/^(url\\()?#([^\\)]+)\\)?$/,\"$2\");return a.Definitions[d]},isUrl:function(){return b.value.indexOf(\"url(\")==\n0},getFillStyle:function(b){var d=this.getDefinition();return d!=null&&d.createGradient?d.createGradient(a.ctx,b):d!=null&&d.createPattern?d.createPattern(a.ctx,b):null}};this.Length={DPI:function(){return 96},EM:function(b){var d=12,c=new a.Property(\"fontSize\",a.Font.Parse(a.ctx.font).fontSize);c.hasValue()&&(d=c.Length.toPixels(b));return d},toPixels:function(d){if(!b.hasValue())return 0;var c=b.value+\"\";return c.match(/em$/)?b.numValue()*this.EM(d):c.match(/ex$/)?b.numValue()*this.EM(d)/2:c.match(/px$/)?\nb.numValue():c.match(/pt$/)?b.numValue()*1.25:c.match(/pc$/)?b.numValue()*15:c.match(/cm$/)?b.numValue()*this.DPI(d)/2.54:c.match(/mm$/)?b.numValue()*this.DPI(d)/25.4:c.match(/in$/)?b.numValue()*this.DPI(d):c.match(/%$/)?b.numValue()*a.ViewPort.ComputeSize(d):b.numValue()}};this.Time={toMilliseconds:function(){if(!b.hasValue())return 0;var a=b.value+\"\";if(a.match(/s$/))return b.numValue()*1E3;a.match(/ms$/);return b.numValue()}};this.Angle={toRadians:function(){if(!b.hasValue())return 0;var a=b.value+\n\"\";return a.match(/deg$/)?b.numValue()*(Math.PI/180):a.match(/grad$/)?b.numValue()*(Math.PI/200):a.match(/rad$/)?b.numValue():b.numValue()*(Math.PI/180)}}};a.Font=new function(){this.Styles=[\"normal\",\"italic\",\"oblique\",\"inherit\"];this.Variants=[\"normal\",\"small-caps\",\"inherit\"];this.Weights=\"normal,bold,bolder,lighter,100,200,300,400,500,600,700,800,900,inherit\".split(\",\");this.CreateFont=function(d,b,c,e,f,g){g=g!=null?this.Parse(g):this.CreateFont(\"\",\"\",\"\",\"\",\"\",a.ctx.font);return{fontFamily:f||\ng.fontFamily,fontSize:e||g.fontSize,fontStyle:d||g.fontStyle,fontWeight:c||g.fontWeight,fontVariant:b||g.fontVariant,toString:function(){return[this.fontStyle,this.fontVariant,this.fontWeight,this.fontSize,this.fontFamily].join(\" \")}}};var c=this;this.Parse=function(d){for(var b={},d=a.trim(a.compressSpaces(d||\"\")).split(\" \"),k=!1,e=!1,f=!1,g=!1,j=\"\",h=0;h<d.length;h++)if(!e&&c.Styles.indexOf(d[h])!=-1){if(d[h]!=\"inherit\")b.fontStyle=d[h];e=!0}else if(!g&&c.Variants.indexOf(d[h])!=-1){if(d[h]!=\"inherit\")b.fontVariant=\nd[h];e=g=!0}else if(!f&&c.Weights.indexOf(d[h])!=-1){if(d[h]!=\"inherit\")b.fontWeight=d[h];e=g=f=!0}else if(k)d[h]!=\"inherit\"&&(j+=d[h]);else{if(d[h]!=\"inherit\")b.fontSize=d[h].split(\"/\")[0];e=g=f=k=!0}if(j!=\"\")b.fontFamily=j;return b}};a.ToNumberArray=function(c){for(var c=a.trim(a.compressSpaces((c||\"\").replace(/,/g,\" \"))).split(\" \"),d=0;d<c.length;d++)c[d]=parseFloat(c[d]);return c};a.Point=function(a,d){this.x=a;this.y=d;this.angleTo=function(b){return Math.atan2(b.y-this.y,b.x-this.x)};this.applyTransform=\nfunction(b){var a=this.x*b[1]+this.y*b[3]+b[5];this.x=this.x*b[0]+this.y*b[2]+b[4];this.y=a}};a.CreatePoint=function(c){c=a.ToNumberArray(c);return new a.Point(c[0],c[1])};a.CreatePath=function(c){for(var c=a.ToNumberArray(c),d=[],b=0;b<c.length;b+=2)d.push(new a.Point(c[b],c[b+1]));return d};a.BoundingBox=function(a,d,b,k){this.y2=this.x2=this.y1=this.x1=Number.NaN;this.x=function(){return this.x1};this.y=function(){return this.y1};this.width=function(){return this.x2-this.x1};this.height=function(){return this.y2-\nthis.y1};this.addPoint=function(b,a){if(b!=null){if(isNaN(this.x1)||isNaN(this.x2))this.x2=this.x1=b;if(b<this.x1)this.x1=b;if(b>this.x2)this.x2=b}if(a!=null){if(isNaN(this.y1)||isNaN(this.y2))this.y2=this.y1=a;if(a<this.y1)this.y1=a;if(a>this.y2)this.y2=a}};this.addX=function(b){this.addPoint(b,null)};this.addY=function(b){this.addPoint(null,b)};this.addBoundingBox=function(b){this.addPoint(b.x1,b.y1);this.addPoint(b.x2,b.y2)};this.addQuadraticCurve=function(b,a,d,c,k,l){d=b+2/3*(d-b);c=a+2/3*(c-\na);this.addBezierCurve(b,a,d,d+1/3*(k-b),c,c+1/3*(l-a),k,l)};this.addBezierCurve=function(b,a,d,c,k,l,o,n){var q=[b,a],p=[d,c],t=[k,l],m=[o,n];this.addPoint(q[0],q[1]);this.addPoint(m[0],m[1]);for(i=0;i<=1;i++)b=function(b){return Math.pow(1-b,3)*q[i]+3*Math.pow(1-b,2)*b*p[i]+3*(1-b)*Math.pow(b,2)*t[i]+Math.pow(b,3)*m[i]},a=6*q[i]-12*p[i]+6*t[i],d=-3*q[i]+9*p[i]-9*t[i]+3*m[i],c=3*p[i]-3*q[i],d==0?a!=0&&(a=-c/a,0<a&&a<1&&(i==0&&this.addX(b(a)),i==1&&this.addY(b(a)))):(c=Math.pow(a,2)-4*c*d,c<0||(k=\n(-a+Math.sqrt(c))/(2*d),0<k&&k<1&&(i==0&&this.addX(b(k)),i==1&&this.addY(b(k))),a=(-a-Math.sqrt(c))/(2*d),0<a&&a<1&&(i==0&&this.addX(b(a)),i==1&&this.addY(b(a)))))};this.isPointInBox=function(b,a){return this.x1<=b&&b<=this.x2&&this.y1<=a&&a<=this.y2};this.addPoint(a,d);this.addPoint(b,k)};a.Transform=function(c){var d=this;this.Type={};this.Type.translate=function(b){this.p=a.CreatePoint(b);this.apply=function(b){b.translate(this.p.x||0,this.p.y||0)};this.applyToPoint=function(b){b.applyTransform([1,\n0,0,1,this.p.x||0,this.p.y||0])}};this.Type.rotate=function(b){b=a.ToNumberArray(b);this.angle=new a.Property(\"angle\",b[0]);this.cx=b[1]||0;this.cy=b[2]||0;this.apply=function(b){b.translate(this.cx,this.cy);b.rotate(this.angle.Angle.toRadians());b.translate(-this.cx,-this.cy)};this.applyToPoint=function(b){var a=this.angle.Angle.toRadians();b.applyTransform([1,0,0,1,this.p.x||0,this.p.y||0]);b.applyTransform([Math.cos(a),Math.sin(a),-Math.sin(a),Math.cos(a),0,0]);b.applyTransform([1,0,0,1,-this.p.x||\n0,-this.p.y||0])}};this.Type.scale=function(b){this.p=a.CreatePoint(b);this.apply=function(b){b.scale(this.p.x||1,this.p.y||this.p.x||1)};this.applyToPoint=function(b){b.applyTransform([this.p.x||0,0,0,this.p.y||0,0,0])}};this.Type.matrix=function(b){this.m=a.ToNumberArray(b);this.apply=function(b){b.transform(this.m[0],this.m[1],this.m[2],this.m[3],this.m[4],this.m[5])};this.applyToPoint=function(b){b.applyTransform(this.m)}};this.Type.SkewBase=function(b){this.base=d.Type.matrix;this.base(b);this.angle=\nnew a.Property(\"angle\",b)};this.Type.SkewBase.prototype=new this.Type.matrix;this.Type.skewX=function(b){this.base=d.Type.SkewBase;this.base(b);this.m=[1,0,Math.tan(this.angle.Angle.toRadians()),1,0,0]};this.Type.skewX.prototype=new this.Type.SkewBase;this.Type.skewY=function(b){this.base=d.Type.SkewBase;this.base(b);this.m=[1,Math.tan(this.angle.Angle.toRadians()),0,1,0,0]};this.Type.skewY.prototype=new this.Type.SkewBase;this.transforms=[];this.apply=function(b){for(var a=0;a<this.transforms.length;a++)this.transforms[a].apply(b)};\nthis.applyToPoint=function(b){for(var a=0;a<this.transforms.length;a++)this.transforms[a].applyToPoint(b)};for(var c=a.trim(a.compressSpaces(c)).split(/\\s(?=[a-z])/),b=0;b<c.length;b++){var k=c[b].split(\"(\")[0],e=c[b].split(\"(\")[1].replace(\")\",\"\");this.transforms.push(new this.Type[k](e))}};a.AspectRatio=function(c,d,b,k,e,f,g,j,h,l){var d=a.compressSpaces(d),d=d.replace(/^defer\\s/,\"\"),o=d.split(\" \")[0]||\"xMidYMid\",d=d.split(\" \")[1]||\"meet\",n=b/k,q=e/f,p=Math.min(n,q),m=Math.max(n,q);d==\"meet\"&&(k*=\np,f*=p);d==\"slice\"&&(k*=m,f*=m);h=new a.Property(\"refX\",h);l=new a.Property(\"refY\",l);h.hasValue()&&l.hasValue()?c.translate(-p*h.Length.toPixels(\"x\"),-p*l.Length.toPixels(\"y\")):(o.match(/^xMid/)&&(d==\"meet\"&&p==q||d==\"slice\"&&m==q)&&c.translate(b/2-k/2,0),o.match(/YMid$/)&&(d==\"meet\"&&p==n||d==\"slice\"&&m==n)&&c.translate(0,e/2-f/2),o.match(/^xMax/)&&(d==\"meet\"&&p==q||d==\"slice\"&&m==q)&&c.translate(b-k,0),o.match(/YMax$/)&&(d==\"meet\"&&p==n||d==\"slice\"&&m==n)&&c.translate(0,e-f));o==\"none\"?c.scale(n,\nq):d==\"meet\"?c.scale(p,p):d==\"slice\"&&c.scale(m,m);c.translate(g==null?0:-g,j==null?0:-j)};a.Element={};a.Element.ElementBase=function(c){this.attributes={};this.styles={};this.children=[];this.attribute=function(b,d){var c=this.attributes[b];if(c!=null)return c;c=new a.Property(b,\"\");d==!0&&(this.attributes[b]=c);return c};this.style=function(b,d){var c=this.styles[b];if(c!=null)return c;c=this.attribute(b);if(c!=null&&c.hasValue())return c;c=this.parent;if(c!=null&&(c=c.style(b),c!=null&&c.hasValue()))return c;\nc=new a.Property(b,\"\");d==!0&&(this.styles[b]=c);return c};this.render=function(b){if(this.style(\"display\").value!=\"none\"&&this.attribute(\"visibility\").value!=\"hidden\"){b.save();this.setContext(b);if(this.attribute(\"mask\").hasValue()){var a=this.attribute(\"mask\").Definition.getDefinition();a!=null&&a.apply(b,this)}else this.style(\"filter\").hasValue()?(a=this.style(\"filter\").Definition.getDefinition(),a!=null&&a.apply(b,this)):this.renderChildren(b);this.clearContext(b);b.restore()}};this.setContext=\nfunction(){};this.clearContext=function(){};this.renderChildren=function(b){for(var a=0;a<this.children.length;a++)this.children[a].render(b)};this.addChild=function(b,d){var c=b;d&&(c=a.CreateElement(b));c.parent=this;this.children.push(c)};if(c!=null&&c.nodeType==1){for(var d=0;d<c.childNodes.length;d++){var b=c.childNodes[d];b.nodeType==1&&this.addChild(b,!0)}for(d=0;d<c.attributes.length;d++)b=c.attributes[d],this.attributes[b.nodeName]=new a.Property(b.nodeName,b.nodeValue);b=a.Styles[c.nodeName];\nif(b!=null)for(var k in b)this.styles[k]=b[k];if(this.attribute(\"class\").hasValue())for(var d=a.compressSpaces(this.attribute(\"class\").value).split(\" \"),e=0;e<d.length;e++){b=a.Styles[\".\"+d[e]];if(b!=null)for(k in b)this.styles[k]=b[k];b=a.Styles[c.nodeName+\".\"+d[e]];if(b!=null)for(k in b)this.styles[k]=b[k]}if(this.attribute(\"style\").hasValue()){b=this.attribute(\"style\").value.split(\";\");for(d=0;d<b.length;d++)a.trim(b[d])!=\"\"&&(c=b[d].split(\":\"),k=a.trim(c[0]),c=a.trim(c[1]),this.styles[k]=new a.Property(k,\nc))}this.attribute(\"id\").hasValue()&&a.Definitions[this.attribute(\"id\").value]==null&&(a.Definitions[this.attribute(\"id\").value]=this)}};a.Element.RenderedElementBase=function(c){this.base=a.Element.ElementBase;this.base(c);this.setContext=function(d){if(this.style(\"fill\").Definition.isUrl()){var b=this.style(\"fill\").Definition.getFillStyle(this);if(b!=null)d.fillStyle=b}else if(this.style(\"fill\").hasValue())b=this.style(\"fill\"),this.style(\"fill-opacity\").hasValue()&&(b=b.Color.addOpacity(this.style(\"fill-opacity\").value)),\nd.fillStyle=b.value==\"none\"?\"rgba(0,0,0,0)\":b.value;if(this.style(\"stroke\").Definition.isUrl()){if(b=this.style(\"stroke\").Definition.getFillStyle(this),b!=null)d.strokeStyle=b}else if(this.style(\"stroke\").hasValue())b=this.style(\"stroke\"),this.style(\"stroke-opacity\").hasValue()&&(b=b.Color.addOpacity(this.style(\"stroke-opacity\").value)),d.strokeStyle=b.value==\"none\"?\"rgba(0,0,0,0)\":b.value;if(this.style(\"stroke-width\").hasValue())d.lineWidth=this.style(\"stroke-width\").Length.toPixels();if(this.style(\"stroke-linecap\").hasValue())d.lineCap=\nthis.style(\"stroke-linecap\").value;if(this.style(\"stroke-linejoin\").hasValue())d.lineJoin=this.style(\"stroke-linejoin\").value;if(this.style(\"stroke-miterlimit\").hasValue())d.miterLimit=this.style(\"stroke-miterlimit\").value;if(typeof d.font!=\"undefined\")d.font=a.Font.CreateFont(this.style(\"font-style\").value,this.style(\"font-variant\").value,this.style(\"font-weight\").value,this.style(\"font-size\").hasValue()?this.style(\"font-size\").Length.toPixels()+\"px\":\"\",this.style(\"font-family\").value).toString();\nthis.attribute(\"transform\").hasValue()&&(new a.Transform(this.attribute(\"transform\").value)).apply(d);this.attribute(\"clip-path\").hasValue()&&(b=this.attribute(\"clip-path\").Definition.getDefinition(),b!=null&&b.apply(d));if(this.style(\"opacity\").hasValue())d.globalAlpha=this.style(\"opacity\").numValue()}};a.Element.RenderedElementBase.prototype=new a.Element.ElementBase;a.Element.PathElementBase=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.path=function(d){d!=null&&d.beginPath();\nreturn new a.BoundingBox};this.renderChildren=function(d){this.path(d);a.Mouse.checkPath(this,d);d.fillStyle!=\"\"&&d.fill();d.strokeStyle!=\"\"&&d.stroke();var b=this.getMarkers();if(b!=null){if(this.style(\"marker-start\").Definition.isUrl()){var c=this.style(\"marker-start\").Definition.getDefinition();c.render(d,b[0][0],b[0][1])}if(this.style(\"marker-mid\").Definition.isUrl())for(var c=this.style(\"marker-mid\").Definition.getDefinition(),e=1;e<b.length-1;e++)c.render(d,b[e][0],b[e][1]);this.style(\"marker-end\").Definition.isUrl()&&\n(c=this.style(\"marker-end\").Definition.getDefinition(),c.render(d,b[b.length-1][0],b[b.length-1][1]))}};this.getBoundingBox=function(){return this.path()};this.getMarkers=function(){return null}};a.Element.PathElementBase.prototype=new a.Element.RenderedElementBase;a.Element.svg=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.baseClearContext=this.clearContext;this.clearContext=function(d){this.baseClearContext(d);a.ViewPort.RemoveCurrent()};this.baseSetContext=this.setContext;\nthis.setContext=function(d){d.strokeStyle=\"rgba(0,0,0,0)\";d.lineCap=\"butt\";d.lineJoin=\"miter\";d.miterLimit=4;this.baseSetContext(d);this.attribute(\"x\").hasValue()&&this.attribute(\"y\").hasValue()&&d.translate(this.attribute(\"x\").Length.toPixels(\"x\"),this.attribute(\"y\").Length.toPixels(\"y\"));var b=a.ViewPort.width(),c=a.ViewPort.height();if(typeof this.root==\"undefined\"&&this.attribute(\"width\").hasValue()&&this.attribute(\"height\").hasValue()){var b=this.attribute(\"width\").Length.toPixels(\"x\"),c=this.attribute(\"height\").Length.toPixels(\"y\"),\ne=0,f=0;this.attribute(\"refX\").hasValue()&&this.attribute(\"refY\").hasValue()&&(e=-this.attribute(\"refX\").Length.toPixels(\"x\"),f=-this.attribute(\"refY\").Length.toPixels(\"y\"));d.beginPath();d.moveTo(e,f);d.lineTo(b,f);d.lineTo(b,c);d.lineTo(e,c);d.closePath();d.clip()}a.ViewPort.SetCurrent(b,c);if(this.attribute(\"viewBox\").hasValue()){var e=a.ToNumberArray(this.attribute(\"viewBox\").value),f=e[0],g=e[1],b=e[2],c=e[3];a.AspectRatio(d,this.attribute(\"preserveAspectRatio\").value,a.ViewPort.width(),b,a.ViewPort.height(),\nc,f,g,this.attribute(\"refX\").value,this.attribute(\"refY\").value);a.ViewPort.RemoveCurrent();a.ViewPort.SetCurrent(e[2],e[3])}}};a.Element.svg.prototype=new a.Element.RenderedElementBase;a.Element.rect=function(c){this.base=a.Element.PathElementBase;this.base(c);this.path=function(d){var b=this.attribute(\"x\").Length.toPixels(\"x\"),c=this.attribute(\"y\").Length.toPixels(\"y\"),e=this.attribute(\"width\").Length.toPixels(\"x\"),f=this.attribute(\"height\").Length.toPixels(\"y\"),g=this.attribute(\"rx\").Length.toPixels(\"x\"),\nj=this.attribute(\"ry\").Length.toPixels(\"y\");this.attribute(\"rx\").hasValue()&&!this.attribute(\"ry\").hasValue()&&(j=g);this.attribute(\"ry\").hasValue()&&!this.attribute(\"rx\").hasValue()&&(g=j);d!=null&&(d.beginPath(),d.moveTo(b+g,c),d.lineTo(b+e-g,c),d.quadraticCurveTo(b+e,c,b+e,c+j),d.lineTo(b+e,c+f-j),d.quadraticCurveTo(b+e,c+f,b+e-g,c+f),d.lineTo(b+g,c+f),d.quadraticCurveTo(b,c+f,b,c+f-j),d.lineTo(b,c+j),d.quadraticCurveTo(b,c,b+g,c),d.closePath());return new a.BoundingBox(b,c,b+e,c+f)}};a.Element.rect.prototype=\nnew a.Element.PathElementBase;a.Element.circle=function(c){this.base=a.Element.PathElementBase;this.base(c);this.path=function(d){var b=this.attribute(\"cx\").Length.toPixels(\"x\"),c=this.attribute(\"cy\").Length.toPixels(\"y\"),e=this.attribute(\"r\").Length.toPixels();d!=null&&(d.beginPath(),d.arc(b,c,e,0,Math.PI*2,!0),d.closePath());return new a.BoundingBox(b-e,c-e,b+e,c+e)}};a.Element.circle.prototype=new a.Element.PathElementBase;a.Element.ellipse=function(c){this.base=a.Element.PathElementBase;this.base(c);\nthis.path=function(d){var b=4*((Math.sqrt(2)-1)/3),c=this.attribute(\"rx\").Length.toPixels(\"x\"),e=this.attribute(\"ry\").Length.toPixels(\"y\"),f=this.attribute(\"cx\").Length.toPixels(\"x\"),g=this.attribute(\"cy\").Length.toPixels(\"y\");d!=null&&(d.beginPath(),d.moveTo(f,g-e),d.bezierCurveTo(f+b*c,g-e,f+c,g-b*e,f+c,g),d.bezierCurveTo(f+c,g+b*e,f+b*c,g+e,f,g+e),d.bezierCurveTo(f-b*c,g+e,f-c,g+b*e,f-c,g),d.bezierCurveTo(f-c,g-b*e,f-b*c,g-e,f,g-e),d.closePath());return new a.BoundingBox(f-c,g-e,f+c,g+e)}};a.Element.ellipse.prototype=\nnew a.Element.PathElementBase;a.Element.line=function(c){this.base=a.Element.PathElementBase;this.base(c);this.getPoints=function(){return[new a.Point(this.attribute(\"x1\").Length.toPixels(\"x\"),this.attribute(\"y1\").Length.toPixels(\"y\")),new a.Point(this.attribute(\"x2\").Length.toPixels(\"x\"),this.attribute(\"y2\").Length.toPixels(\"y\"))]};this.path=function(d){var b=this.getPoints();d!=null&&(d.beginPath(),d.moveTo(b[0].x,b[0].y),d.lineTo(b[1].x,b[1].y));return new a.BoundingBox(b[0].x,b[0].y,b[1].x,b[1].y)};\nthis.getMarkers=function(){var a=this.getPoints(),b=a[0].angleTo(a[1]);return[[a[0],b],[a[1],b]]}};a.Element.line.prototype=new a.Element.PathElementBase;a.Element.polyline=function(c){this.base=a.Element.PathElementBase;this.base(c);this.points=a.CreatePath(this.attribute(\"points\").value);this.path=function(d){var b=new a.BoundingBox(this.points[0].x,this.points[0].y);d!=null&&(d.beginPath(),d.moveTo(this.points[0].x,this.points[0].y));for(var c=1;c<this.points.length;c++)b.addPoint(this.points[c].x,\nthis.points[c].y),d!=null&&d.lineTo(this.points[c].x,this.points[c].y);return b};this.getMarkers=function(){for(var a=[],b=0;b<this.points.length-1;b++)a.push([this.points[b],this.points[b].angleTo(this.points[b+1])]);a.push([this.points[this.points.length-1],a[a.length-1][1]]);return a}};a.Element.polyline.prototype=new a.Element.PathElementBase;a.Element.polygon=function(c){this.base=a.Element.polyline;this.base(c);this.basePath=this.path;this.path=function(a){var b=this.basePath(a);a!=null&&(a.lineTo(this.points[0].x,\nthis.points[0].y),a.closePath());return b}};a.Element.polygon.prototype=new a.Element.polyline;a.Element.path=function(c){this.base=a.Element.PathElementBase;this.base(c);c=this.attribute(\"d\").value;c=c.replace(/,/gm,\" \");c=c.replace(/([MmZzLlHhVvCcSsQqTtAa])([MmZzLlHhVvCcSsQqTtAa])/gm,\"$1 $2\");c=c.replace(/([MmZzLlHhVvCcSsQqTtAa])([MmZzLlHhVvCcSsQqTtAa])/gm,\"$1 $2\");c=c.replace(/([MmZzLlHhVvCcSsQqTtAa])([^\\s])/gm,\"$1 $2\");c=c.replace(/([^\\s])([MmZzLlHhVvCcSsQqTtAa])/gm,\"$1 $2\");c=c.replace(/([0-9])([+\\-])/gm,\n\"$1 $2\");c=c.replace(/(\\.[0-9]*)(\\.)/gm,\"$1 $2\");c=c.replace(/([Aa](\\s+[0-9]+){3})\\s+([01])\\s*([01])/gm,\"$1 $3 $4 \");c=a.compressSpaces(c);c=a.trim(c);this.PathParser=new function(d){this.tokens=d.split(\" \");this.reset=function(){this.i=-1;this.previousCommand=this.command=\"\";this.start=new a.Point(0,0);this.control=new a.Point(0,0);this.current=new a.Point(0,0);this.points=[];this.angles=[]};this.isEnd=function(){return this.i>=this.tokens.length-1};this.isCommandOrEnd=function(){return this.isEnd()?\n!0:this.tokens[this.i+1].match(/^[A-Za-z]$/)!=null};this.isRelativeCommand=function(){return this.command==this.command.toLowerCase()};this.getToken=function(){this.i+=1;return this.tokens[this.i]};this.getScalar=function(){return parseFloat(this.getToken())};this.nextCommand=function(){this.previousCommand=this.command;this.command=this.getToken()};this.getPoint=function(){return this.makeAbsolute(new a.Point(this.getScalar(),this.getScalar()))};this.getAsControlPoint=function(){var b=this.getPoint();\nreturn this.control=b};this.getAsCurrentPoint=function(){var b=this.getPoint();return this.current=b};this.getReflectedControlPoint=function(){return this.previousCommand.toLowerCase()!=\"c\"&&this.previousCommand.toLowerCase()!=\"s\"?this.current:new a.Point(2*this.current.x-this.control.x,2*this.current.y-this.control.y)};this.makeAbsolute=function(b){if(this.isRelativeCommand())b.x=this.current.x+b.x,b.y=this.current.y+b.y;return b};this.addMarker=function(b,a,d){d!=null&&this.angles.length>0&&this.angles[this.angles.length-\n1]==null&&(this.angles[this.angles.length-1]=this.points[this.points.length-1].angleTo(d));this.addMarkerAngle(b,a==null?null:a.angleTo(b))};this.addMarkerAngle=function(b,a){this.points.push(b);this.angles.push(a)};this.getMarkerPoints=function(){return this.points};this.getMarkerAngles=function(){for(var b=0;b<this.angles.length;b++)if(this.angles[b]==null)for(var a=b+1;a<this.angles.length;a++)if(this.angles[a]!=null){this.angles[b]=this.angles[a];break}return this.angles}}(c);this.path=function(d){var b=\nthis.PathParser;b.reset();var c=new a.BoundingBox;for(d!=null&&d.beginPath();!b.isEnd();)switch(b.nextCommand(),b.command.toUpperCase()){case \"M\":var e=b.getAsCurrentPoint();b.addMarker(e);c.addPoint(e.x,e.y);d!=null&&d.moveTo(e.x,e.y);for(b.start=b.current;!b.isCommandOrEnd();)e=b.getAsCurrentPoint(),b.addMarker(e,b.start),c.addPoint(e.x,e.y),d!=null&&d.lineTo(e.x,e.y);break;case \"L\":for(;!b.isCommandOrEnd();){var f=b.current,e=b.getAsCurrentPoint();b.addMarker(e,f);c.addPoint(e.x,e.y);d!=null&&\nd.lineTo(e.x,e.y)}break;case \"H\":for(;!b.isCommandOrEnd();)e=new a.Point((b.isRelativeCommand()?b.current.x:0)+b.getScalar(),b.current.y),b.addMarker(e,b.current),b.current=e,c.addPoint(b.current.x,b.current.y),d!=null&&d.lineTo(b.current.x,b.current.y);break;case \"V\":for(;!b.isCommandOrEnd();)e=new a.Point(b.current.x,(b.isRelativeCommand()?b.current.y:0)+b.getScalar()),b.addMarker(e,b.current),b.current=e,c.addPoint(b.current.x,b.current.y),d!=null&&d.lineTo(b.current.x,b.current.y);break;case \"C\":for(;!b.isCommandOrEnd();){var g=\nb.current,f=b.getPoint(),j=b.getAsControlPoint(),e=b.getAsCurrentPoint();b.addMarker(e,j,f);c.addBezierCurve(g.x,g.y,f.x,f.y,j.x,j.y,e.x,e.y);d!=null&&d.bezierCurveTo(f.x,f.y,j.x,j.y,e.x,e.y)}break;case \"S\":for(;!b.isCommandOrEnd();)g=b.current,f=b.getReflectedControlPoint(),j=b.getAsControlPoint(),e=b.getAsCurrentPoint(),b.addMarker(e,j,f),c.addBezierCurve(g.x,g.y,f.x,f.y,j.x,j.y,e.x,e.y),d!=null&&d.bezierCurveTo(f.x,f.y,j.x,j.y,e.x,e.y);break;case \"Q\":for(;!b.isCommandOrEnd();)g=b.current,j=b.getAsControlPoint(),\ne=b.getAsCurrentPoint(),b.addMarker(e,j,j),c.addQuadraticCurve(g.x,g.y,j.x,j.y,e.x,e.y),d!=null&&d.quadraticCurveTo(j.x,j.y,e.x,e.y);break;case \"T\":for(;!b.isCommandOrEnd();)g=b.current,j=b.getReflectedControlPoint(),b.control=j,e=b.getAsCurrentPoint(),b.addMarker(e,j,j),c.addQuadraticCurve(g.x,g.y,j.x,j.y,e.x,e.y),d!=null&&d.quadraticCurveTo(j.x,j.y,e.x,e.y);break;case \"A\":for(;!b.isCommandOrEnd();){var g=b.current,h=b.getScalar(),l=b.getScalar(),f=b.getScalar()*(Math.PI/180),o=b.getScalar(),j=b.getScalar(),\ne=b.getAsCurrentPoint(),n=new a.Point(Math.cos(f)*(g.x-e.x)/2+Math.sin(f)*(g.y-e.y)/2,-Math.sin(f)*(g.x-e.x)/2+Math.cos(f)*(g.y-e.y)/2),q=Math.pow(n.x,2)/Math.pow(h,2)+Math.pow(n.y,2)/Math.pow(l,2);q>1&&(h*=Math.sqrt(q),l*=Math.sqrt(q));o=(o==j?-1:1)*Math.sqrt((Math.pow(h,2)*Math.pow(l,2)-Math.pow(h,2)*Math.pow(n.y,2)-Math.pow(l,2)*Math.pow(n.x,2))/(Math.pow(h,2)*Math.pow(n.y,2)+Math.pow(l,2)*Math.pow(n.x,2)));isNaN(o)&&(o=0);var p=new a.Point(o*h*n.y/l,o*-l*n.x/h),g=new a.Point((g.x+e.x)/2+Math.cos(f)*\np.x-Math.sin(f)*p.y,(g.y+e.y)/2+Math.sin(f)*p.x+Math.cos(f)*p.y),m=function(b,a){return(b[0]*a[0]+b[1]*a[1])/(Math.sqrt(Math.pow(b[0],2)+Math.pow(b[1],2))*Math.sqrt(Math.pow(a[0],2)+Math.pow(a[1],2)))},s=function(b,a){return(b[0]*a[1]<b[1]*a[0]?-1:1)*Math.acos(m(b,a))},o=s([1,0],[(n.x-p.x)/h,(n.y-p.y)/l]),q=[(n.x-p.x)/h,(n.y-p.y)/l],p=[(-n.x-p.x)/h,(-n.y-p.y)/l],n=s(q,p);if(m(q,p)<=-1)n=Math.PI;m(q,p)>=1&&(n=0);j==0&&n>0&&(n-=2*Math.PI);j==1&&n<0&&(n+=2*Math.PI);q=new a.Point(g.x-h*Math.cos((o+n)/\n2),g.y-l*Math.sin((o+n)/2));b.addMarkerAngle(q,(o+n)/2+(j==0?1:-1)*Math.PI/2);b.addMarkerAngle(e,n+(j==0?1:-1)*Math.PI/2);c.addPoint(e.x,e.y);d!=null&&(m=h>l?h:l,e=h>l?1:h/l,h=h>l?l/h:1,d.translate(g.x,g.y),d.rotate(f),d.scale(e,h),d.arc(0,0,m,o,o+n,1-j),d.scale(1/e,1/h),d.rotate(-f),d.translate(-g.x,-g.y))}break;case \"Z\":d!=null&&d.closePath(),b.current=b.start}return c};this.getMarkers=function(){for(var a=this.PathParser.getMarkerPoints(),b=this.PathParser.getMarkerAngles(),c=[],e=0;e<a.length;e++)c.push([a[e],\nb[e]]);return c}};a.Element.path.prototype=new a.Element.PathElementBase;a.Element.pattern=function(c){this.base=a.Element.ElementBase;this.base(c);this.createPattern=function(d){var b=new a.Element.svg;b.attributes.viewBox=new a.Property(\"viewBox\",this.attribute(\"viewBox\").value);b.attributes.x=new a.Property(\"x\",this.attribute(\"x\").value);b.attributes.y=new a.Property(\"y\",this.attribute(\"y\").value);b.attributes.width=new a.Property(\"width\",this.attribute(\"width\").value);b.attributes.height=new a.Property(\"height\",\nthis.attribute(\"height\").value);b.children=this.children;var c=document.createElement(\"canvas\");c.width=this.attribute(\"width\").Length.toPixels(\"x\");c.height=this.attribute(\"height\").Length.toPixels(\"y\");b.render(c.getContext(\"2d\"));return d.createPattern(c,\"repeat\")}};a.Element.pattern.prototype=new a.Element.ElementBase;a.Element.marker=function(c){this.base=a.Element.ElementBase;this.base(c);this.baseRender=this.render;this.render=function(d,b,c){d.translate(b.x,b.y);this.attribute(\"orient\").valueOrDefault(\"auto\")==\n\"auto\"&&d.rotate(c);this.attribute(\"markerUnits\").valueOrDefault(\"strokeWidth\")==\"strokeWidth\"&&d.scale(d.lineWidth,d.lineWidth);d.save();var e=new a.Element.svg;e.attributes.viewBox=new a.Property(\"viewBox\",this.attribute(\"viewBox\").value);e.attributes.refX=new a.Property(\"refX\",this.attribute(\"refX\").value);e.attributes.refY=new a.Property(\"refY\",this.attribute(\"refY\").value);e.attributes.width=new a.Property(\"width\",this.attribute(\"markerWidth\").value);e.attributes.height=new a.Property(\"height\",\nthis.attribute(\"markerHeight\").value);e.attributes.fill=new a.Property(\"fill\",this.attribute(\"fill\").valueOrDefault(\"black\"));e.attributes.stroke=new a.Property(\"stroke\",this.attribute(\"stroke\").valueOrDefault(\"none\"));e.children=this.children;e.render(d);d.restore();this.attribute(\"markerUnits\").valueOrDefault(\"strokeWidth\")==\"strokeWidth\"&&d.scale(1/d.lineWidth,1/d.lineWidth);this.attribute(\"orient\").valueOrDefault(\"auto\")==\"auto\"&&d.rotate(-c);d.translate(-b.x,-b.y)}};a.Element.marker.prototype=\nnew a.Element.ElementBase;a.Element.defs=function(c){this.base=a.Element.ElementBase;this.base(c);this.render=function(){}};a.Element.defs.prototype=new a.Element.ElementBase;a.Element.GradientBase=function(c){this.base=a.Element.ElementBase;this.base(c);this.gradientUnits=this.attribute(\"gradientUnits\").valueOrDefault(\"objectBoundingBox\");this.stops=[];for(c=0;c<this.children.length;c++)this.stops.push(this.children[c]);this.getGradient=function(){};this.createGradient=function(d,b){var c=this;this.attribute(\"xlink:href\").hasValue()&&\n(c=this.attribute(\"xlink:href\").Definition.getDefinition());for(var e=this.getGradient(d,b),f=0;f<c.stops.length;f++)e.addColorStop(c.stops[f].offset,c.stops[f].color);if(this.attribute(\"gradientTransform\").hasValue()){c=a.ViewPort.viewPorts[0];f=new a.Element.rect;f.attributes.x=new a.Property(\"x\",-a.MAX_VIRTUAL_PIXELS/3);f.attributes.y=new a.Property(\"y\",-a.MAX_VIRTUAL_PIXELS/3);f.attributes.width=new a.Property(\"width\",a.MAX_VIRTUAL_PIXELS);f.attributes.height=new a.Property(\"height\",a.MAX_VIRTUAL_PIXELS);\nvar g=new a.Element.g;g.attributes.transform=new a.Property(\"transform\",this.attribute(\"gradientTransform\").value);g.children=[f];f=new a.Element.svg;f.attributes.x=new a.Property(\"x\",0);f.attributes.y=new a.Property(\"y\",0);f.attributes.width=new a.Property(\"width\",c.width);f.attributes.height=new a.Property(\"height\",c.height);f.children=[g];g=document.createElement(\"canvas\");g.width=c.width;g.height=c.height;c=g.getContext(\"2d\");c.fillStyle=e;f.render(c);return c.createPattern(g,\"no-repeat\")}return e}};\na.Element.GradientBase.prototype=new a.Element.ElementBase;a.Element.linearGradient=function(c){this.base=a.Element.GradientBase;this.base(c);this.getGradient=function(a,b){var c=b.getBoundingBox(),e=this.gradientUnits==\"objectBoundingBox\"?c.x()+c.width()*this.attribute(\"x1\").numValue():this.attribute(\"x1\").Length.toPixels(\"x\"),f=this.gradientUnits==\"objectBoundingBox\"?c.y()+c.height()*this.attribute(\"y1\").numValue():this.attribute(\"y1\").Length.toPixels(\"y\"),g=this.gradientUnits==\"objectBoundingBox\"?\nc.x()+c.width()*this.attribute(\"x2\").numValue():this.attribute(\"x2\").Length.toPixels(\"x\"),c=this.gradientUnits==\"objectBoundingBox\"?c.y()+c.height()*this.attribute(\"y2\").numValue():this.attribute(\"y2\").Length.toPixels(\"y\");return a.createLinearGradient(e,f,g,c)}};a.Element.linearGradient.prototype=new a.Element.GradientBase;a.Element.radialGradient=function(c){this.base=a.Element.GradientBase;this.base(c);this.getGradient=function(a,b){var c=b.getBoundingBox(),e=this.gradientUnits==\"objectBoundingBox\"?\nc.x()+c.width()*this.attribute(\"cx\").numValue():this.attribute(\"cx\").Length.toPixels(\"x\"),f=this.gradientUnits==\"objectBoundingBox\"?c.y()+c.height()*this.attribute(\"cy\").numValue():this.attribute(\"cy\").Length.toPixels(\"y\"),g=e,j=f;this.attribute(\"fx\").hasValue()&&(g=this.gradientUnits==\"objectBoundingBox\"?c.x()+c.width()*this.attribute(\"fx\").numValue():this.attribute(\"fx\").Length.toPixels(\"x\"));this.attribute(\"fy\").hasValue()&&(j=this.gradientUnits==\"objectBoundingBox\"?c.y()+c.height()*this.attribute(\"fy\").numValue():\nthis.attribute(\"fy\").Length.toPixels(\"y\"));c=this.gradientUnits==\"objectBoundingBox\"?(c.width()+c.height())/2*this.attribute(\"r\").numValue():this.attribute(\"r\").Length.toPixels();return a.createRadialGradient(g,j,0,e,f,c)}};a.Element.radialGradient.prototype=new a.Element.GradientBase;a.Element.stop=function(c){this.base=a.Element.ElementBase;this.base(c);this.offset=this.attribute(\"offset\").numValue();c=this.style(\"stop-color\");this.style(\"stop-opacity\").hasValue()&&(c=c.Color.addOpacity(this.style(\"stop-opacity\").value));\nthis.color=c.value};a.Element.stop.prototype=new a.Element.ElementBase;a.Element.AnimateBase=function(c){this.base=a.Element.ElementBase;this.base(c);a.Animations.push(this);this.duration=0;this.begin=this.attribute(\"begin\").Time.toMilliseconds();this.maxDuration=this.begin+this.attribute(\"dur\").Time.toMilliseconds();this.getProperty=function(){var a=this.attribute(\"attributeType\").value,b=this.attribute(\"attributeName\").value;return a==\"CSS\"?this.parent.style(b,!0):this.parent.attribute(b,!0)};this.initialValue=\nnull;this.removed=!1;this.calcValue=function(){return\"\"};this.update=function(a){if(this.initialValue==null)this.initialValue=this.getProperty().value;if(this.duration>this.maxDuration)if(this.attribute(\"repeatCount\").value==\"indefinite\")this.duration=0;else return this.attribute(\"fill\").valueOrDefault(\"remove\")==\"remove\"&&!this.removed?(this.removed=!0,this.getProperty().value=this.initialValue,!0):!1;this.duration+=a;a=!1;if(this.begin<this.duration)a=this.calcValue(),this.attribute(\"type\").hasValue()&&\n(a=this.attribute(\"type\").value+\"(\"+a+\")\"),this.getProperty().value=a,a=!0;return a};this.progress=function(){return(this.duration-this.begin)/(this.maxDuration-this.begin)}};a.Element.AnimateBase.prototype=new a.Element.ElementBase;a.Element.animate=function(c){this.base=a.Element.AnimateBase;this.base(c);this.calcValue=function(){var a=this.attribute(\"from\").numValue(),b=this.attribute(\"to\").numValue();return a+(b-a)*this.progress()}};a.Element.animate.prototype=new a.Element.AnimateBase;a.Element.animateColor=\nfunction(c){this.base=a.Element.AnimateBase;this.base(c);this.calcValue=function(){var a=new RGBColor(this.attribute(\"from\").value),b=new RGBColor(this.attribute(\"to\").value);if(a.ok&&b.ok){var c=a.r+(b.r-a.r)*this.progress(),e=a.g+(b.g-a.g)*this.progress(),a=a.b+(b.b-a.b)*this.progress();return\"rgb(\"+parseInt(c,10)+\",\"+parseInt(e,10)+\",\"+parseInt(a,10)+\")\"}return this.attribute(\"from\").value}};a.Element.animateColor.prototype=new a.Element.AnimateBase;a.Element.animateTransform=function(c){this.base=\na.Element.animate;this.base(c)};a.Element.animateTransform.prototype=new a.Element.animate;a.Element.font=function(c){this.base=a.Element.ElementBase;this.base(c);this.horizAdvX=this.attribute(\"horiz-adv-x\").numValue();this.isArabic=this.isRTL=!1;this.missingGlyph=this.fontFace=null;this.glyphs=[];for(c=0;c<this.children.length;c++){var d=this.children[c];if(d.type==\"font-face\")this.fontFace=d,d.style(\"font-family\").hasValue()&&(a.Definitions[d.style(\"font-family\").value]=this);else if(d.type==\"missing-glyph\")this.missingGlyph=\nd;else if(d.type==\"glyph\")d.arabicForm!=\"\"?(this.isArabic=this.isRTL=!0,typeof this.glyphs[d.unicode]==\"undefined\"&&(this.glyphs[d.unicode]=[]),this.glyphs[d.unicode][d.arabicForm]=d):this.glyphs[d.unicode]=d}};a.Element.font.prototype=new a.Element.ElementBase;a.Element.fontface=function(c){this.base=a.Element.ElementBase;this.base(c);this.ascent=this.attribute(\"ascent\").value;this.descent=this.attribute(\"descent\").value;this.unitsPerEm=this.attribute(\"units-per-em\").numValue()};a.Element.fontface.prototype=\nnew a.Element.ElementBase;a.Element.missingglyph=function(c){this.base=a.Element.path;this.base(c);this.horizAdvX=0};a.Element.missingglyph.prototype=new a.Element.path;a.Element.glyph=function(c){this.base=a.Element.path;this.base(c);this.horizAdvX=this.attribute(\"horiz-adv-x\").numValue();this.unicode=this.attribute(\"unicode\").value;this.arabicForm=this.attribute(\"arabic-form\").value};a.Element.glyph.prototype=new a.Element.path;a.Element.text=function(c){this.base=a.Element.RenderedElementBase;\nthis.base(c);if(c!=null){this.children=[];for(var d=0;d<c.childNodes.length;d++){var b=c.childNodes[d];b.nodeType==1?this.addChild(b,!0):b.nodeType==3&&this.addChild(new a.Element.tspan(b),!1)}}this.baseSetContext=this.setContext;this.setContext=function(b){this.baseSetContext(b);if(this.style(\"dominant-baseline\").hasValue())b.textBaseline=this.style(\"dominant-baseline\").value;if(this.style(\"alignment-baseline\").hasValue())b.textBaseline=this.style(\"alignment-baseline\").value};this.renderChildren=\nfunction(b){for(var a=this.style(\"text-anchor\").valueOrDefault(\"start\"),c=this.attribute(\"x\").Length.toPixels(\"x\"),d=this.attribute(\"y\").Length.toPixels(\"y\"),j=0;j<this.children.length;j++){var h=this.children[j];h.attribute(\"x\").hasValue()?h.x=h.attribute(\"x\").Length.toPixels(\"x\"):(h.attribute(\"dx\").hasValue()&&(c+=h.attribute(\"dx\").Length.toPixels(\"x\")),h.x=c);c=h.measureText(b);if(a!=\"start\"&&(j==0||h.attribute(\"x\").hasValue())){for(var l=c,o=j+1;o<this.children.length;o++){var n=this.children[o];\nif(n.attribute(\"x\").hasValue())break;l+=n.measureText(b)}h.x-=a==\"end\"?l:l/2}c=h.x+c;h.attribute(\"y\").hasValue()?h.y=h.attribute(\"y\").Length.toPixels(\"y\"):(h.attribute(\"dy\").hasValue()&&(d+=h.attribute(\"dy\").Length.toPixels(\"y\")),h.y=d);d=h.y;h.render(b)}}};a.Element.text.prototype=new a.Element.RenderedElementBase;a.Element.TextElementBase=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.getGlyph=function(a,b,c){var e=b[c],f=null;if(a.isArabic){var g=\"isolated\";if((c==0||b[c-\n1]==\" \")&&c<b.length-2&&b[c+1]!=\" \")g=\"terminal\";c>0&&b[c-1]!=\" \"&&c<b.length-2&&b[c+1]!=\" \"&&(g=\"medial\");if(c>0&&b[c-1]!=\" \"&&(c==b.length-1||b[c+1]==\" \"))g=\"initial\";typeof a.glyphs[e]!=\"undefined\"&&(f=a.glyphs[e][g],f==null&&a.glyphs[e].type==\"glyph\"&&(f=a.glyphs[e]))}else f=a.glyphs[e];if(f==null)f=a.missingGlyph;return f};this.renderChildren=function(c){var b=this.parent.style(\"font-family\").Definition.getDefinition();if(b!=null){var k=this.parent.style(\"font-size\").numValueOrDefault(a.Font.Parse(a.ctx.font).fontSize),\ne=this.parent.style(\"font-style\").valueOrDefault(a.Font.Parse(a.ctx.font).fontStyle),f=this.getText();b.isRTL&&(f=f.split(\"\").reverse().join(\"\"));for(var g=a.ToNumberArray(this.parent.attribute(\"dx\").value),j=0;j<f.length;j++){var h=this.getGlyph(b,f,j),l=k/b.fontFace.unitsPerEm;c.translate(this.x,this.y);c.scale(l,-l);var o=c.lineWidth;c.lineWidth=c.lineWidth*b.fontFace.unitsPerEm/k;e==\"italic\"&&c.transform(1,0,0.4,1,0,0);h.render(c);e==\"italic\"&&c.transform(1,0,-0.4,1,0,0);c.lineWidth=o;c.scale(1/\nl,-1/l);c.translate(-this.x,-this.y);this.x+=k*(h.horizAdvX||b.horizAdvX)/b.fontFace.unitsPerEm;typeof g[j]!=\"undefined\"&&!isNaN(g[j])&&(this.x+=g[j])}}else c.strokeStyle!=\"\"&&c.strokeText(a.compressSpaces(this.getText()),this.x,this.y),c.fillStyle!=\"\"&&c.fillText(a.compressSpaces(this.getText()),this.x,this.y)};this.getText=function(){};this.measureText=function(c){var b=this.parent.style(\"font-family\").Definition.getDefinition();if(b!=null){var c=this.parent.style(\"font-size\").numValueOrDefault(a.Font.Parse(a.ctx.font).fontSize),\nk=0,e=this.getText();b.isRTL&&(e=e.split(\"\").reverse().join(\"\"));for(var f=a.ToNumberArray(this.parent.attribute(\"dx\").value),g=0;g<e.length;g++){var j=this.getGlyph(b,e,g);k+=(j.horizAdvX||b.horizAdvX)*c/b.fontFace.unitsPerEm;typeof f[g]!=\"undefined\"&&!isNaN(f[g])&&(k+=f[g])}return k}b=a.compressSpaces(this.getText());if(!c.measureText)return b.length*10;c.save();this.setContext(c);b=c.measureText(b).width;c.restore();return b}};a.Element.TextElementBase.prototype=new a.Element.RenderedElementBase;\na.Element.tspan=function(c){this.base=a.Element.TextElementBase;this.base(c);this.text=c.nodeType==3?c.nodeValue:c.childNodes.length>0?c.childNodes[0].nodeValue:c.text;this.getText=function(){return this.text}};a.Element.tspan.prototype=new a.Element.TextElementBase;a.Element.tref=function(c){this.base=a.Element.TextElementBase;this.base(c);this.getText=function(){var a=this.attribute(\"xlink:href\").Definition.getDefinition();if(a!=null)return a.children[0].getText()}};a.Element.tref.prototype=new a.Element.TextElementBase;\na.Element.a=function(c){this.base=a.Element.TextElementBase;this.base(c);this.hasText=!0;for(var d=0;d<c.childNodes.length;d++)if(c.childNodes[d].nodeType!=3)this.hasText=!1;this.text=this.hasText?c.childNodes[0].nodeValue:\"\";this.getText=function(){return this.text};this.baseRenderChildren=this.renderChildren;this.renderChildren=function(b){if(this.hasText){this.baseRenderChildren(b);var c=new a.Property(\"fontSize\",a.Font.Parse(a.ctx.font).fontSize);a.Mouse.checkBoundingBox(this,new a.BoundingBox(this.x,\nthis.y-c.Length.toPixels(\"y\"),this.x+this.measureText(b),this.y))}else c=new a.Element.g,c.children=this.children,c.parent=this,c.render(b)};this.onclick=function(){window.open(this.attribute(\"xlink:href\").value)};this.onmousemove=function(){a.ctx.canvas.style.cursor=\"pointer\"}};a.Element.a.prototype=new a.Element.TextElementBase;a.Element.image=function(c){this.base=a.Element.RenderedElementBase;this.base(c);a.Images.push(this);this.img=document.createElement(\"img\");this.loaded=!1;var d=this;this.img.onload=\nfunction(){d.loaded=!0};this.img.src=this.attribute(\"xlink:href\").value;this.renderChildren=function(b){var c=this.attribute(\"x\").Length.toPixels(\"x\"),d=this.attribute(\"y\").Length.toPixels(\"y\"),f=this.attribute(\"width\").Length.toPixels(\"x\"),g=this.attribute(\"height\").Length.toPixels(\"y\");f==0||g==0||(b.save(),b.translate(c,d),a.AspectRatio(b,this.attribute(\"preserveAspectRatio\").value,f,this.img.width,g,this.img.height,0,0),b.drawImage(this.img,0,0),b.restore())}};a.Element.image.prototype=new a.Element.RenderedElementBase;\na.Element.g=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.getBoundingBox=function(){for(var c=new a.BoundingBox,b=0;b<this.children.length;b++)c.addBoundingBox(this.children[b].getBoundingBox());return c}};a.Element.g.prototype=new a.Element.RenderedElementBase;a.Element.symbol=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.baseSetContext=this.setContext;this.setContext=function(c){this.baseSetContext(c);if(this.attribute(\"viewBox\").hasValue()){var b=\na.ToNumberArray(this.attribute(\"viewBox\").value),k=b[0],e=b[1];width=b[2];height=b[3];a.AspectRatio(c,this.attribute(\"preserveAspectRatio\").value,this.attribute(\"width\").Length.toPixels(\"x\"),width,this.attribute(\"height\").Length.toPixels(\"y\"),height,k,e);a.ViewPort.SetCurrent(b[2],b[3])}}};a.Element.symbol.prototype=new a.Element.RenderedElementBase;a.Element.style=function(c){this.base=a.Element.ElementBase;this.base(c);for(var c=c.childNodes[0].nodeValue+(c.childNodes.length>1?c.childNodes[1].nodeValue:\n\"\"),c=c.replace(/(\\/\\*([^*]|[\\r\\n]|(\\*+([^*\\/]|[\\r\\n])))*\\*+\\/)|(^[\\s]*\\/\\/.*)/gm,\"\"),c=a.compressSpaces(c),c=c.split(\"}\"),d=0;d<c.length;d++)if(a.trim(c[d])!=\"\")for(var b=c[d].split(\"{\"),k=b[0].split(\",\"),b=b[1].split(\";\"),e=0;e<k.length;e++){var f=a.trim(k[e]);if(f!=\"\"){for(var g={},j=0;j<b.length;j++){var h=b[j].indexOf(\":\"),l=b[j].substr(0,h),h=b[j].substr(h+1,b[j].length-h);l!=null&&h!=null&&(g[a.trim(l)]=new a.Property(a.trim(l),a.trim(h)))}a.Styles[f]=g;if(f==\"@font-face\"){f=g[\"font-family\"].value.replace(/\"/g,\n\"\");g=g.src.value.split(\",\");for(j=0;j<g.length;j++)if(g[j].indexOf('format(\"svg\")')>0){l=g[j].indexOf(\"url\");h=g[j].indexOf(\")\",l);l=g[j].substr(l+5,h-l-6);l=a.parseXml(a.ajax(l)).getElementsByTagName(\"font\");for(h=0;h<l.length;h++){var o=a.CreateElement(l[h]);a.Definitions[f]=o}}}}}};a.Element.style.prototype=new a.Element.ElementBase;a.Element.use=function(c){this.base=a.Element.RenderedElementBase;this.base(c);this.baseSetContext=this.setContext;this.setContext=function(a){this.baseSetContext(a);\nthis.attribute(\"x\").hasValue()&&a.translate(this.attribute(\"x\").Length.toPixels(\"x\"),0);this.attribute(\"y\").hasValue()&&a.translate(0,this.attribute(\"y\").Length.toPixels(\"y\"))};this.getDefinition=function(){var a=this.attribute(\"xlink:href\").Definition.getDefinition();if(this.attribute(\"width\").hasValue())a.attribute(\"width\",!0).value=this.attribute(\"width\").value;if(this.attribute(\"height\").hasValue())a.attribute(\"height\",!0).value=this.attribute(\"height\").value;return a};this.path=function(a){var b=\nthis.getDefinition();b!=null&&b.path(a)};this.renderChildren=function(a){var b=this.getDefinition();b!=null&&b.render(a)}};a.Element.use.prototype=new a.Element.RenderedElementBase;a.Element.mask=function(c){this.base=a.Element.ElementBase;this.base(c);this.apply=function(a,b){var c=this.attribute(\"x\").Length.toPixels(\"x\"),e=this.attribute(\"y\").Length.toPixels(\"y\"),f=this.attribute(\"width\").Length.toPixels(\"x\"),g=this.attribute(\"height\").Length.toPixels(\"y\"),j=b.attribute(\"mask\").value;b.attribute(\"mask\").value=\n\"\";var h=document.createElement(\"canvas\");h.width=c+f;h.height=e+g;var l=h.getContext(\"2d\");this.renderChildren(l);var o=document.createElement(\"canvas\");o.width=c+f;o.height=e+g;var n=o.getContext(\"2d\");b.render(n);n.globalCompositeOperation=\"destination-in\";n.fillStyle=l.createPattern(h,\"no-repeat\");n.fillRect(0,0,c+f,e+g);a.fillStyle=n.createPattern(o,\"no-repeat\");a.fillRect(0,0,c+f,e+g);b.attribute(\"mask\").value=j};this.render=function(){}};a.Element.mask.prototype=new a.Element.ElementBase;a.Element.clipPath=\nfunction(c){this.base=a.Element.ElementBase;this.base(c);this.apply=function(a){for(var b=0;b<this.children.length;b++)this.children[b].path&&(this.children[b].path(a),a.clip())};this.render=function(){}};a.Element.clipPath.prototype=new a.Element.ElementBase;a.Element.filter=function(c){this.base=a.Element.ElementBase;this.base(c);this.apply=function(a,b){var c=b.getBoundingBox(),e=this.attribute(\"x\").Length.toPixels(\"x\"),f=this.attribute(\"y\").Length.toPixels(\"y\");if(e==0||f==0)e=c.x1,f=c.y1;var g=\nthis.attribute(\"width\").Length.toPixels(\"x\"),j=this.attribute(\"height\").Length.toPixels(\"y\");if(g==0||j==0)g=c.width(),j=c.height();c=b.style(\"filter\").value;b.style(\"filter\").value=\"\";var h=0.2*g,l=0.2*j,o=document.createElement(\"canvas\");o.width=g+2*h;o.height=j+2*l;var n=o.getContext(\"2d\");n.translate(-e+h,-f+l);b.render(n);for(var q=0;q<this.children.length;q++)this.children[q].apply(n,0,0,g+2*h,j+2*l);a.drawImage(o,0,0,g+2*h,j+2*l,e-h,f-l,g+2*h,j+2*l);b.style(\"filter\",!0).value=c};this.render=\nfunction(){}};a.Element.filter.prototype=new a.Element.ElementBase;a.Element.feGaussianBlur=function(c){function d(a,c,d,f,g){for(var j=0;j<g;j++)for(var h=0;h<f;h++)for(var l=a[j*f*4+h*4+3]/255,o=0;o<4;o++){for(var n=d[0]*(l==0?255:a[j*f*4+h*4+o])*(l==0||o==3?1:l),q=1;q<d.length;q++){var p=Math.max(h-q,0),m=a[j*f*4+p*4+3]/255,p=Math.min(h+q,f-1),p=a[j*f*4+p*4+3]/255,s=d[q],r;m==0?r=255:(r=Math.max(h-q,0),r=a[j*f*4+r*4+o]);m=r*(m==0||o==3?1:m);p==0?r=255:(r=Math.min(h+q,f-1),r=a[j*f*4+r*4+o]);n+=\ns*(m+r*(p==0||o==3?1:p))}c[h*g*4+j*4+o]=n}}this.base=a.Element.ElementBase;this.base(c);this.apply=function(a,c,e,f,g){var e=this.attribute(\"stdDeviation\").numValue(),c=a.getImageData(0,0,f,g),e=Math.max(e,0.01),j=Math.ceil(e*4)+1;mask=[];for(var h=0;h<j;h++)mask[h]=Math.exp(-0.5*(h/e)*(h/e));e=mask;j=0;for(h=1;h<e.length;h++)j+=Math.abs(e[h]);j=2*j+Math.abs(e[0]);for(h=0;h<e.length;h++)e[h]/=j;tmp=[];d(c.data,tmp,e,f,g);d(tmp,c.data,e,g,f);a.clearRect(0,0,f,g);a.putImageData(c,0,0)}};a.Element.filter.prototype=\nnew a.Element.feGaussianBlur;a.Element.title=function(){};a.Element.title.prototype=new a.Element.ElementBase;a.Element.desc=function(){};a.Element.desc.prototype=new a.Element.ElementBase;a.Element.MISSING=function(a){console.log(\"ERROR: Element '\"+a.nodeName+\"' not yet implemented.\")};a.Element.MISSING.prototype=new a.Element.ElementBase;a.CreateElement=function(c){var d=c.nodeName.replace(/^[^:]+:/,\"\"),d=d.replace(/\\-/g,\"\"),b=null,b=typeof a.Element[d]!=\"undefined\"?new a.Element[d](c):new a.Element.MISSING(c);\nb.type=c.nodeName;return b};a.load=function(c,d){a.loadXml(c,a.ajax(d))};a.loadXml=function(c,d){a.loadXmlDoc(c,a.parseXml(d))};a.loadXmlDoc=function(c,d){a.init(c);var b=function(a){for(var b=c.canvas;b;)a.x-=b.offsetLeft,a.y-=b.offsetTop,b=b.offsetParent;window.scrollX&&(a.x+=window.scrollX);window.scrollY&&(a.y+=window.scrollY);return a};if(a.opts.ignoreMouse!=!0)c.canvas.onclick=function(c){c=b(new a.Point(c!=null?c.clientX:event.clientX,c!=null?c.clientY:event.clientY));a.Mouse.onclick(c.x,c.y)},\nc.canvas.onmousemove=function(c){c=b(new a.Point(c!=null?c.clientX:event.clientX,c!=null?c.clientY:event.clientY));a.Mouse.onmousemove(c.x,c.y)};var k=a.CreateElement(d.documentElement),e=k.root=!0,f=function(){a.ViewPort.Clear();c.canvas.parentNode&&a.ViewPort.SetCurrent(c.canvas.parentNode.clientWidth,c.canvas.parentNode.clientHeight);if(a.opts.ignoreDimensions!=!0){if(k.style(\"width\").hasValue())c.canvas.width=k.style(\"width\").Length.toPixels(\"x\"),c.canvas.style.width=c.canvas.width+\"px\";if(k.style(\"height\").hasValue())c.canvas.height=\nk.style(\"height\").Length.toPixels(\"y\"),c.canvas.style.height=c.canvas.height+\"px\"}var b=c.canvas.clientWidth||c.canvas.width,d=c.canvas.clientHeight||c.canvas.height;a.ViewPort.SetCurrent(b,d);if(a.opts!=null&&a.opts.offsetX!=null)k.attribute(\"x\",!0).value=a.opts.offsetX;if(a.opts!=null&&a.opts.offsetY!=null)k.attribute(\"y\",!0).value=a.opts.offsetY;if(a.opts!=null&&a.opts.scaleWidth!=null&&a.opts.scaleHeight!=null){var f=1,g=1;k.attribute(\"width\").hasValue()&&(f=k.attribute(\"width\").Length.toPixels(\"x\")/\na.opts.scaleWidth);k.attribute(\"height\").hasValue()&&(g=k.attribute(\"height\").Length.toPixels(\"y\")/a.opts.scaleHeight);k.attribute(\"width\",!0).value=a.opts.scaleWidth;k.attribute(\"height\",!0).value=a.opts.scaleHeight;k.attribute(\"viewBox\",!0).value=\"0 0 \"+b*f+\" \"+d*g;k.attribute(\"preserveAspectRatio\",!0).value=\"none\"}a.opts.ignoreClear!=!0&&c.clearRect(0,0,b,d);k.render(c);e&&(e=!1,a.opts!=null&&typeof a.opts.renderCallback==\"function\"&&a.opts.renderCallback())},g=!0;a.ImagesLoaded()&&(g=!1,f());\na.intervalID=setInterval(function(){var b=!1;g&&a.ImagesLoaded()&&(g=!1,b=!0);a.opts.ignoreMouse!=!0&&(b|=a.Mouse.hasEvents());if(a.opts.ignoreAnimation!=!0)for(var c=0;c<a.Animations.length;c++)b|=a.Animations[c].update(1E3/a.FRAMERATE);a.opts!=null&&typeof a.opts.forceRedraw==\"function\"&&a.opts.forceRedraw()==!0&&(b=!0);b&&(f(),a.Mouse.runEvents())},1E3/a.FRAMERATE)};a.stop=function(){a.intervalID&&clearInterval(a.intervalID)};a.Mouse=new function(){this.events=[];this.hasEvents=function(){return this.events.length!=\n0};this.onclick=function(a,d){this.events.push({type:\"onclick\",x:a,y:d,run:function(a){if(a.onclick)a.onclick()}})};this.onmousemove=function(a,d){this.events.push({type:\"onmousemove\",x:a,y:d,run:function(a){if(a.onmousemove)a.onmousemove()}})};this.eventElements=[];this.checkPath=function(a,d){for(var b=0;b<this.events.length;b++){var k=this.events[b];d.isPointInPath&&d.isPointInPath(k.x,k.y)&&(this.eventElements[b]=a)}};this.checkBoundingBox=function(a,d){for(var b=0;b<this.events.length;b++){var k=\nthis.events[b];d.isPointInBox(k.x,k.y)&&(this.eventElements[b]=a)}};this.runEvents=function(){a.ctx.canvas.style.cursor=\"\";for(var c=0;c<this.events.length;c++)for(var d=this.events[c],b=this.eventElements[c];b;)d.run(b),b=b.parent;this.events=[];this.eventElements=[]}};return a}this.canvg=function(a,c,d){if(a==null&&c==null&&d==null)for(var c=document.getElementsByTagName(\"svg\"),b=0;b<c.length;b++){a=c[b];d=document.createElement(\"canvas\");d.width=a.clientWidth;d.height=a.clientHeight;a.parentNode.insertBefore(d,\na);a.parentNode.removeChild(a);var k=document.createElement(\"div\");k.appendChild(a);canvg(d,k.innerHTML)}else d=d||{},typeof a==\"string\"&&(a=document.getElementById(a)),a.svg==null?(b=m(),a.svg=b):(b=a.svg,b.stop()),b.opts=d,a=a.getContext(\"2d\"),typeof c.documentElement!=\"undefined\"?b.loadXmlDoc(a,c):c.substr(0,1)==\"<\"?b.loadXml(a,c):b.load(a,c)}})();\nif(CanvasRenderingContext2D)CanvasRenderingContext2D.prototype.drawSvg=function(m,a,c,d,b){canvg(this.canvas,m,{ignoreMouse:!0,ignoreAnimation:!0,ignoreDimensions:!0,ignoreClear:!0,offsetX:a,offsetY:c,scaleWidth:d,scaleHeight:b})};\n(function(m){var a=m.css,c=m.CanVGRenderer,d=m.SVGRenderer,b=m.extend,k=m.merge,e=m.addEvent,f=m.createElement,g=m.discardElement;b(c.prototype,d.prototype);b(c.prototype,{create:function(a,b,c,d){this.setContainer(b,c,d);this.configure(a)},setContainer:function(a,b,c){var d=a.style,e=a.parentNode,g=d.left,d=d.top,k=a.offsetWidth,m=a.offsetHeight,s={visibility:\"hidden\",position:\"absolute\"};this.init.apply(this,[a,b,c]);this.canvas=f(\"canvas\",{width:k,height:m},{position:\"relative\",left:g,top:d},a);\nthis.ttLine=f(\"div\",null,s,e);this.ttDiv=f(\"div\",null,s,e);this.ttTimer=void 0;this.hiddenSvg=a=f(\"div\",{width:k,height:m},{visibility:\"hidden\",left:g,top:d},e);a.appendChild(this.box)},configure:function(b){var c=this,d=b.options.tooltip,f=d.borderWidth,g=c.ttDiv,m=d.style,p=c.ttLine,t=parseInt(m.padding,10),m=k(m,{padding:t+\"px\",\"background-color\":d.backgroundColor,\"border-style\":\"solid\",\"border-width\":f+\"px\",\"border-radius\":d.borderRadius+\"px\"});d.shadow&&(m=k(m,{\"box-shadow\":\"1px 1px 3px gray\",\n\"-webkit-box-shadow\":\"1px 1px 3px gray\"}));a(g,m);a(p,{\"border-left\":\"1px solid darkgray\"});e(b,\"tooltipRefresh\",function(d){var e=b.container,f=e.offsetLeft,e=e.offsetTop,k;g.innerHTML=d.text;k=b.tooltip.getPosition(g.offsetWidth,g.offsetHeight,{plotX:d.x,plotY:d.y});a(g,{visibility:\"visible\",left:k.x+\"px\",top:k.y+\"px\",\"border-color\":d.borderColor});a(p,{visibility:\"visible\",left:f+d.x+\"px\",top:e+b.plotTop+\"px\",height:b.plotHeight+\"px\"});c.ttTimer!==void 0&&clearTimeout(c.ttTimer);c.ttTimer=setTimeout(function(){a(g,\n{visibility:\"hidden\"});a(p,{visibility:\"hidden\"})},3E3)})},destroy:function(){g(this.canvas);this.ttTimer!==void 0&&clearTimeout(this.ttTimer);g(this.ttLine);g(this.ttDiv);g(this.hiddenSvg);return d.prototype.destroy.apply(this)},color:function(a,b,c){a&&a.linearGradient&&(a=a.stops[a.stops.length-1][1]);return d.prototype.color.call(this,a,b,c)},draw:function(){window.canvg(this.canvas,this.hiddenSvg.innerHTML)}})})(Highcharts);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/canvas-tools.src.js",
    "content": "/**\n * @license A class to parse color values\n * @author Stoyan Stefanov <sstoo@gmail.com>\n * @link   http://www.phpied.com/rgb-color-parser-in-javascript/\n * Use it if you like it\n *\n */\nfunction RGBColor(color_string)\n{\n    this.ok = false;\n\n    // strip any leading #\n    if (color_string.charAt(0) == '#') { // remove # if any\n        color_string = color_string.substr(1,6);\n    }\n\n    color_string = color_string.replace(/ /g,'');\n    color_string = color_string.toLowerCase();\n\n    // before getting into regexps, try simple matches\n    // and overwrite the input\n    var simple_colors = {\n        aliceblue: 'f0f8ff',\n        antiquewhite: 'faebd7',\n        aqua: '00ffff',\n        aquamarine: '7fffd4',\n        azure: 'f0ffff',\n        beige: 'f5f5dc',\n        bisque: 'ffe4c4',\n        black: '000000',\n        blanchedalmond: 'ffebcd',\n        blue: '0000ff',\n        blueviolet: '8a2be2',\n        brown: 'a52a2a',\n        burlywood: 'deb887',\n        cadetblue: '5f9ea0',\n        chartreuse: '7fff00',\n        chocolate: 'd2691e',\n        coral: 'ff7f50',\n        cornflowerblue: '6495ed',\n        cornsilk: 'fff8dc',\n        crimson: 'dc143c',\n        cyan: '00ffff',\n        darkblue: '00008b',\n        darkcyan: '008b8b',\n        darkgoldenrod: 'b8860b',\n        darkgray: 'a9a9a9',\n        darkgreen: '006400',\n        darkkhaki: 'bdb76b',\n        darkmagenta: '8b008b',\n        darkolivegreen: '556b2f',\n        darkorange: 'ff8c00',\n        darkorchid: '9932cc',\n        darkred: '8b0000',\n        darksalmon: 'e9967a',\n        darkseagreen: '8fbc8f',\n        darkslateblue: '483d8b',\n        darkslategray: '2f4f4f',\n        darkturquoise: '00ced1',\n        darkviolet: '9400d3',\n        deeppink: 'ff1493',\n        deepskyblue: '00bfff',\n        dimgray: '696969',\n        dodgerblue: '1e90ff',\n        feldspar: 'd19275',\n        firebrick: 'b22222',\n        floralwhite: 'fffaf0',\n        forestgreen: '228b22',\n        fuchsia: 'ff00ff',\n        gainsboro: 'dcdcdc',\n        ghostwhite: 'f8f8ff',\n        gold: 'ffd700',\n        goldenrod: 'daa520',\n        gray: '808080',\n        green: '008000',\n        greenyellow: 'adff2f',\n        honeydew: 'f0fff0',\n        hotpink: 'ff69b4',\n        indianred : 'cd5c5c',\n        indigo : '4b0082',\n        ivory: 'fffff0',\n        khaki: 'f0e68c',\n        lavender: 'e6e6fa',\n        lavenderblush: 'fff0f5',\n        lawngreen: '7cfc00',\n        lemonchiffon: 'fffacd',\n        lightblue: 'add8e6',\n        lightcoral: 'f08080',\n        lightcyan: 'e0ffff',\n        lightgoldenrodyellow: 'fafad2',\n        lightgrey: 'd3d3d3',\n        lightgreen: '90ee90',\n        lightpink: 'ffb6c1',\n        lightsalmon: 'ffa07a',\n        lightseagreen: '20b2aa',\n        lightskyblue: '87cefa',\n        lightslateblue: '8470ff',\n        lightslategray: '778899',\n        lightsteelblue: 'b0c4de',\n        lightyellow: 'ffffe0',\n        lime: '00ff00',\n        limegreen: '32cd32',\n        linen: 'faf0e6',\n        magenta: 'ff00ff',\n        maroon: '800000',\n        mediumaquamarine: '66cdaa',\n        mediumblue: '0000cd',\n        mediumorchid: 'ba55d3',\n        mediumpurple: '9370d8',\n        mediumseagreen: '3cb371',\n        mediumslateblue: '7b68ee',\n        mediumspringgreen: '00fa9a',\n        mediumturquoise: '48d1cc',\n        mediumvioletred: 'c71585',\n        midnightblue: '191970',\n        mintcream: 'f5fffa',\n        mistyrose: 'ffe4e1',\n        moccasin: 'ffe4b5',\n        navajowhite: 'ffdead',\n        navy: '000080',\n        oldlace: 'fdf5e6',\n        olive: '808000',\n        olivedrab: '6b8e23',\n        orange: 'ffa500',\n        orangered: 'ff4500',\n        orchid: 'da70d6',\n        palegoldenrod: 'eee8aa',\n        palegreen: '98fb98',\n        paleturquoise: 'afeeee',\n        palevioletred: 'd87093',\n        papayawhip: 'ffefd5',\n        peachpuff: 'ffdab9',\n        peru: 'cd853f',\n        pink: 'ffc0cb',\n        plum: 'dda0dd',\n        powderblue: 'b0e0e6',\n        purple: '800080',\n        red: 'ff0000',\n        rosybrown: 'bc8f8f',\n        royalblue: '4169e1',\n        saddlebrown: '8b4513',\n        salmon: 'fa8072',\n        sandybrown: 'f4a460',\n        seagreen: '2e8b57',\n        seashell: 'fff5ee',\n        sienna: 'a0522d',\n        silver: 'c0c0c0',\n        skyblue: '87ceeb',\n        slateblue: '6a5acd',\n        slategray: '708090',\n        snow: 'fffafa',\n        springgreen: '00ff7f',\n        steelblue: '4682b4',\n        tan: 'd2b48c',\n        teal: '008080',\n        thistle: 'd8bfd8',\n        tomato: 'ff6347',\n        turquoise: '40e0d0',\n        violet: 'ee82ee',\n        violetred: 'd02090',\n        wheat: 'f5deb3',\n        white: 'ffffff',\n        whitesmoke: 'f5f5f5',\n        yellow: 'ffff00',\n        yellowgreen: '9acd32'\n    };\n    for (var key in simple_colors) {\n        if (color_string == key) {\n            color_string = simple_colors[key];\n        }\n    }\n    // emd of simple type-in colors\n\n    // array of color definition objects\n    var color_defs = [\n        {\n            re: /^rgb\\((\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})\\)$/,\n            example: ['rgb(123, 234, 45)', 'rgb(255,234,245)'],\n            process: function (bits){\n                return [\n                    parseInt(bits[1]),\n                    parseInt(bits[2]),\n                    parseInt(bits[3])\n                ];\n            }\n        },\n        {\n            re: /^(\\w{2})(\\w{2})(\\w{2})$/,\n            example: ['#00ff00', '336699'],\n            process: function (bits){\n                return [\n                    parseInt(bits[1], 16),\n                    parseInt(bits[2], 16),\n                    parseInt(bits[3], 16)\n                ];\n            }\n        },\n        {\n            re: /^(\\w{1})(\\w{1})(\\w{1})$/,\n            example: ['#fb0', 'f0f'],\n            process: function (bits){\n                return [\n                    parseInt(bits[1] + bits[1], 16),\n                    parseInt(bits[2] + bits[2], 16),\n                    parseInt(bits[3] + bits[3], 16)\n                ];\n            }\n        }\n    ];\n\n    // search through the definitions to find a match\n    for (var i = 0; i < color_defs.length; i++) {\n        var re = color_defs[i].re;\n        var processor = color_defs[i].process;\n        var bits = re.exec(color_string);\n        if (bits) {\n            channels = processor(bits);\n            this.r = channels[0];\n            this.g = channels[1];\n            this.b = channels[2];\n            this.ok = true;\n        }\n\n    }\n\n    // validate/cleanup values\n    this.r = (this.r < 0 || isNaN(this.r)) ? 0 : ((this.r > 255) ? 255 : this.r);\n    this.g = (this.g < 0 || isNaN(this.g)) ? 0 : ((this.g > 255) ? 255 : this.g);\n    this.b = (this.b < 0 || isNaN(this.b)) ? 0 : ((this.b > 255) ? 255 : this.b);\n\n    // some getters\n    this.toRGB = function () {\n        return 'rgb(' + this.r + ', ' + this.g + ', ' + this.b + ')';\n    }\n    this.toHex = function () {\n        var r = this.r.toString(16);\n        var g = this.g.toString(16);\n        var b = this.b.toString(16);\n        if (r.length == 1) r = '0' + r;\n        if (g.length == 1) g = '0' + g;\n        if (b.length == 1) b = '0' + b;\n        return '#' + r + g + b;\n    }\n\n    // help\n    this.getHelpXML = function () {\n\n        var examples = new Array();\n        // add regexps\n        for (var i = 0; i < color_defs.length; i++) {\n            var example = color_defs[i].example;\n            for (var j = 0; j < example.length; j++) {\n                examples[examples.length] = example[j];\n            }\n        }\n        // add type-in colors\n        for (var sc in simple_colors) {\n            examples[examples.length] = sc;\n        }\n\n        var xml = document.createElement('ul');\n        xml.setAttribute('id', 'rgbcolor-examples');\n        for (var i = 0; i < examples.length; i++) {\n            try {\n                var list_item = document.createElement('li');\n                var list_color = new RGBColor(examples[i]);\n                var example_div = document.createElement('div');\n                example_div.style.cssText =\n                        'margin: 3px; '\n                        + 'border: 1px solid black; '\n                        + 'background:' + list_color.toHex() + '; '\n                        + 'color:' + list_color.toHex()\n                ;\n                example_div.appendChild(document.createTextNode('test'));\n                var list_item_value = document.createTextNode(\n                    ' ' + examples[i] + ' -> ' + list_color.toRGB() + ' -> ' + list_color.toHex()\n                );\n                list_item.appendChild(example_div);\n                list_item.appendChild(list_item_value);\n                xml.appendChild(list_item);\n\n            } catch(e){}\n        }\n        return xml;\n\n    }\n\n}\n\n/**\n * @license canvg.js - Javascript SVG parser and renderer on Canvas\n * MIT Licensed \n * Gabe Lerner (gabelerner@gmail.com)\n * http://code.google.com/p/canvg/\n *\n * Requires: rgbcolor.js - http://www.phpied.com/rgb-color-parser-in-javascript/\n *\n */\nif(!window.console) {\n\twindow.console = {};\n\twindow.console.log = function(str) {};\n\twindow.console.dir = function(str) {};\n}\n\nif(!Array.prototype.indexOf){\n\tArray.prototype.indexOf = function(obj){\n\t\tfor(var i=0; i<this.length; i++){\n\t\t\tif(this[i]==obj){\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t}\n}\n\n(function(){\n\t// canvg(target, s)\n\t// empty parameters: replace all 'svg' elements on page with 'canvas' elements\n\t// target: canvas element or the id of a canvas element\n\t// s: svg string, url to svg file, or xml document\n\t// opts: optional hash of options\n\t//\t\t ignoreMouse: true => ignore mouse events\n\t//\t\t ignoreAnimation: true => ignore animations\n\t//\t\t ignoreDimensions: true => does not try to resize canvas\n\t//\t\t ignoreClear: true => does not clear canvas\n\t//\t\t offsetX: int => draws at a x offset\n\t//\t\t offsetY: int => draws at a y offset\n\t//\t\t scaleWidth: int => scales horizontally to width\n\t//\t\t scaleHeight: int => scales vertically to height\n\t//\t\t renderCallback: function => will call the function after the first render is completed\n\t//\t\t forceRedraw: function => will call the function on every frame, if it returns true, will redraw\n\tthis.canvg = function (target, s, opts) {\n\t\t// no parameters\n\t\tif (target == null && s == null && opts == null) {\n\t\t\tvar svgTags = document.getElementsByTagName('svg');\n\t\t\tfor (var i=0; i<svgTags.length; i++) {\n\t\t\t\tvar svgTag = svgTags[i];\n\t\t\t\tvar c = document.createElement('canvas');\n\t\t\t\tc.width = svgTag.clientWidth;\n\t\t\t\tc.height = svgTag.clientHeight;\n\t\t\t\tsvgTag.parentNode.insertBefore(c, svgTag);\n\t\t\t\tsvgTag.parentNode.removeChild(svgTag);\n\t\t\t\tvar div = document.createElement('div');\n\t\t\t\tdiv.appendChild(svgTag);\n\t\t\t\tcanvg(c, div.innerHTML);\n\t\t\t}\n\t\t\treturn;\n\t\t}\t\n\t\topts = opts || {};\n\t\n\t\tif (typeof target == 'string') {\n\t\t\ttarget = document.getElementById(target);\n\t\t}\n\t\t\n\t\t// reuse class per canvas\n\t\tvar svg;\n\t\tif (target.svg == null) {\n\t\t\tsvg = build();\n\t\t\ttarget.svg = svg;\n\t\t}\n\t\telse {\n\t\t\tsvg = target.svg;\n\t\t\tsvg.stop();\n\t\t}\n\t\tsvg.opts = opts;\n\t\t\n\t\tvar ctx = target.getContext('2d');\n\t\tif (typeof(s.documentElement) != 'undefined') {\n\t\t\t// load from xml doc\n\t\t\tsvg.loadXmlDoc(ctx, s);\n\t\t}\n\t\telse if (s.substr(0,1) == '<') {\n\t\t\t// load from xml string\n\t\t\tsvg.loadXml(ctx, s);\n\t\t}\n\t\telse {\n\t\t\t// load from url\n\t\t\tsvg.load(ctx, s);\n\t\t}\n\t}\n\n\tfunction build() {\n\t\tvar svg = { };\n\t\t\n\t\tsvg.FRAMERATE = 30;\n\t\tsvg.MAX_VIRTUAL_PIXELS = 30000;\n\t\t\n\t\t// globals\n\t\tsvg.init = function(ctx) {\n\t\t\tsvg.Definitions = {};\n\t\t\tsvg.Styles = {};\n\t\t\tsvg.Animations = [];\n\t\t\tsvg.Images = [];\n\t\t\tsvg.ctx = ctx;\n\t\t\tsvg.ViewPort = new (function () {\n\t\t\t\tthis.viewPorts = [];\n\t\t\t\tthis.Clear = function() { this.viewPorts = []; }\n\t\t\t\tthis.SetCurrent = function(width, height) { this.viewPorts.push({ width: width, height: height }); }\n\t\t\t\tthis.RemoveCurrent = function() { this.viewPorts.pop(); }\n\t\t\t\tthis.Current = function() { return this.viewPorts[this.viewPorts.length - 1]; }\n\t\t\t\tthis.width = function() { return this.Current().width; }\n\t\t\t\tthis.height = function() { return this.Current().height; }\n\t\t\t\tthis.ComputeSize = function(d) {\n\t\t\t\t\tif (d != null && typeof(d) == 'number') return d;\n\t\t\t\t\tif (d == 'x') return this.width();\n\t\t\t\t\tif (d == 'y') return this.height();\n\t\t\t\t\treturn Math.sqrt(Math.pow(this.width(), 2) + Math.pow(this.height(), 2)) / Math.sqrt(2);\t\t\t\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tsvg.init();\n\t\t\n\t\t// images loaded\n\t\tsvg.ImagesLoaded = function() { \n\t\t\tfor (var i=0; i<svg.Images.length; i++) {\n\t\t\t\tif (!svg.Images[i].loaded) return false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\n\t\t// trim\n\t\tsvg.trim = function(s) { return s.replace(/^\\s+|\\s+$/g, ''); }\n\t\t\n\t\t// compress spaces\n\t\tsvg.compressSpaces = function(s) { return s.replace(/[\\s\\r\\t\\n]+/gm,' '); }\n\t\t\n\t\t// ajax\n\t\tsvg.ajax = function(url) {\n\t\t\tvar AJAX;\n\t\t\tif(window.XMLHttpRequest){AJAX=new XMLHttpRequest();}\n\t\t\telse{AJAX=new ActiveXObject('Microsoft.XMLHTTP');}\n\t\t\tif(AJAX){\n\t\t\t   AJAX.open('GET',url,false);\n\t\t\t   AJAX.send(null);\n\t\t\t   return AJAX.responseText;\n\t\t\t}\n\t\t\treturn null;\n\t\t} \n\t\t\n\t\t// parse xml\n\t\tsvg.parseXml = function(xml) {\n\t\t\tif (window.DOMParser)\n\t\t\t{\n\t\t\t\tvar parser = new DOMParser();\n\t\t\t\treturn parser.parseFromString(xml, 'text/xml');\n\t\t\t}\n\t\t\telse \n\t\t\t{\n\t\t\t\txml = xml.replace(/<!DOCTYPE svg[^>]*>/, '');\n\t\t\t\tvar xmlDoc = new ActiveXObject('Microsoft.XMLDOM');\n\t\t\t\txmlDoc.async = 'false';\n\t\t\t\txmlDoc.loadXML(xml); \n\t\t\t\treturn xmlDoc;\n\t\t\t}\t\t\n\t\t}\n\t\t\n\t\tsvg.Property = function(name, value) {\n\t\t\tthis.name = name;\n\t\t\tthis.value = value;\n\t\t\t\n\t\t\tthis.hasValue = function() {\n\t\t\t\treturn (this.value != null && this.value !== '');\n\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\t// return the numerical value of the property\n\t\t\tthis.numValue = function() {\n\t\t\t\tif (!this.hasValue()) return 0;\n\t\t\t\t\n\t\t\t\tvar n = parseFloat(this.value);\n\t\t\t\tif ((this.value + '').match(/%$/)) {\n\t\t\t\t\tn = n / 100.0;\n\t\t\t\t}\n\t\t\t\treturn n;\n\t\t\t}\n\t\t\t\n\t\t\tthis.valueOrDefault = function(def) {\n\t\t\t\tif (this.hasValue()) return this.value;\n\t\t\t\treturn def;\n\t\t\t}\n\t\t\t\n\t\t\tthis.numValueOrDefault = function(def) {\n\t\t\t\tif (this.hasValue()) return this.numValue();\n\t\t\t\treturn def;\n\t\t\t}\n\t\t\t\n\t\t\t/* EXTENSIONS */\n\t\t\tvar that = this;\n\t\t\t\n\t\t\t// color extensions\n\t\t\tthis.Color = {\n\t\t\t\t// augment the current color value with the opacity\n\t\t\t\taddOpacity: function(opacity) {\n\t\t\t\t\tvar newValue = that.value;\n\t\t\t\t\tif (opacity != null && opacity != '') {\n\t\t\t\t\t\tvar color = new RGBColor(that.value);\n\t\t\t\t\t\tif (color.ok) {\n\t\t\t\t\t\t\tnewValue = 'rgba(' + color.r + ', ' + color.g + ', ' + color.b + ', ' + opacity + ')';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn new svg.Property(that.name, newValue);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// definition extensions\n\t\t\tthis.Definition = {\n\t\t\t\t// get the definition from the definitions table\n\t\t\t\tgetDefinition: function() {\n\t\t\t\t\tvar name = that.value.replace(/^(url\\()?#([^\\)]+)\\)?$/, '$2');\n\t\t\t\t\treturn svg.Definitions[name];\n\t\t\t\t},\n\t\t\t\t\n\t\t\t\tisUrl: function() {\n\t\t\t\t\treturn that.value.indexOf('url(') == 0\n\t\t\t\t},\n\t\t\t\t\n\t\t\t\tgetFillStyle: function(e) {\n\t\t\t\t\tvar def = this.getDefinition();\n\t\t\t\t\t\n\t\t\t\t\t// gradient\n\t\t\t\t\tif (def != null && def.createGradient) {\n\t\t\t\t\t\treturn def.createGradient(svg.ctx, e);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// pattern\n\t\t\t\t\tif (def != null && def.createPattern) {\n\t\t\t\t\t\treturn def.createPattern(svg.ctx, e);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// length extensions\n\t\t\tthis.Length = {\n\t\t\t\tDPI: function(viewPort) {\n\t\t\t\t\treturn 96.0; // TODO: compute?\n\t\t\t\t},\n\t\t\t\t\n\t\t\t\tEM: function(viewPort) {\n\t\t\t\t\tvar em = 12;\n\t\t\t\t\t\n\t\t\t\t\tvar fontSize = new svg.Property('fontSize', svg.Font.Parse(svg.ctx.font).fontSize);\n\t\t\t\t\tif (fontSize.hasValue()) em = fontSize.Length.toPixels(viewPort);\n\t\t\t\t\t\n\t\t\t\t\treturn em;\n\t\t\t\t},\n\t\t\t\n\t\t\t\t// get the length as pixels\n\t\t\t\ttoPixels: function(viewPort) {\n\t\t\t\t\tif (!that.hasValue()) return 0;\n\t\t\t\t\tvar s = that.value+'';\n\t\t\t\t\tif (s.match(/em$/)) return that.numValue() * this.EM(viewPort);\n\t\t\t\t\tif (s.match(/ex$/)) return that.numValue() * this.EM(viewPort) / 2.0;\n\t\t\t\t\tif (s.match(/px$/)) return that.numValue();\n\t\t\t\t\tif (s.match(/pt$/)) return that.numValue() * 1.25;\n\t\t\t\t\tif (s.match(/pc$/)) return that.numValue() * 15;\n\t\t\t\t\tif (s.match(/cm$/)) return that.numValue() * this.DPI(viewPort) / 2.54;\n\t\t\t\t\tif (s.match(/mm$/)) return that.numValue() * this.DPI(viewPort) / 25.4;\n\t\t\t\t\tif (s.match(/in$/)) return that.numValue() * this.DPI(viewPort);\n\t\t\t\t\tif (s.match(/%$/)) return that.numValue() * svg.ViewPort.ComputeSize(viewPort);\n\t\t\t\t\treturn that.numValue();\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// time extensions\n\t\t\tthis.Time = {\n\t\t\t\t// get the time as milliseconds\n\t\t\t\ttoMilliseconds: function() {\n\t\t\t\t\tif (!that.hasValue()) return 0;\n\t\t\t\t\tvar s = that.value+'';\n\t\t\t\t\tif (s.match(/s$/)) return that.numValue() * 1000;\n\t\t\t\t\tif (s.match(/ms$/)) return that.numValue();\n\t\t\t\t\treturn that.numValue();\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// angle extensions\n\t\t\tthis.Angle = {\n\t\t\t\t// get the angle as radians\n\t\t\t\ttoRadians: function() {\n\t\t\t\t\tif (!that.hasValue()) return 0;\n\t\t\t\t\tvar s = that.value+'';\n\t\t\t\t\tif (s.match(/deg$/)) return that.numValue() * (Math.PI / 180.0);\n\t\t\t\t\tif (s.match(/grad$/)) return that.numValue() * (Math.PI / 200.0);\n\t\t\t\t\tif (s.match(/rad$/)) return that.numValue();\n\t\t\t\t\treturn that.numValue() * (Math.PI / 180.0);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\t// fonts\n\t\tsvg.Font = new (function() {\n\t\t\tthis.Styles = ['normal','italic','oblique','inherit'];\n\t\t\tthis.Variants = ['normal','small-caps','inherit'];\n\t\t\tthis.Weights = ['normal','bold','bolder','lighter','100','200','300','400','500','600','700','800','900','inherit'];\n\t\t\t\n\t\t\tthis.CreateFont = function(fontStyle, fontVariant, fontWeight, fontSize, fontFamily, inherit) { \n\t\t\t\tvar f = inherit != null ? this.Parse(inherit) : this.CreateFont('', '', '', '', '', svg.ctx.font);\n\t\t\t\treturn { \n\t\t\t\t\tfontFamily: fontFamily || f.fontFamily, \n\t\t\t\t\tfontSize: fontSize || f.fontSize, \n\t\t\t\t\tfontStyle: fontStyle || f.fontStyle, \n\t\t\t\t\tfontWeight: fontWeight || f.fontWeight, \n\t\t\t\t\tfontVariant: fontVariant || f.fontVariant,\n\t\t\t\t\ttoString: function () { return [this.fontStyle, this.fontVariant, this.fontWeight, this.fontSize, this.fontFamily].join(' ') } \n\t\t\t\t} \n\t\t\t}\n\t\t\t\n\t\t\tvar that = this;\n\t\t\tthis.Parse = function(s) {\n\t\t\t\tvar f = {};\n\t\t\t\tvar d = svg.trim(svg.compressSpaces(s || '')).split(' ');\n\t\t\t\tvar set = { fontSize: false, fontStyle: false, fontWeight: false, fontVariant: false }\n\t\t\t\tvar ff = '';\n\t\t\t\tfor (var i=0; i<d.length; i++) {\n\t\t\t\t\tif (!set.fontStyle && that.Styles.indexOf(d[i]) != -1) { if (d[i] != 'inherit') f.fontStyle = d[i]; set.fontStyle = true; }\n\t\t\t\t\telse if (!set.fontVariant && that.Variants.indexOf(d[i]) != -1) { if (d[i] != 'inherit') f.fontVariant = d[i]; set.fontStyle = set.fontVariant = true;\t}\n\t\t\t\t\telse if (!set.fontWeight && that.Weights.indexOf(d[i]) != -1) {\tif (d[i] != 'inherit') f.fontWeight = d[i]; set.fontStyle = set.fontVariant = set.fontWeight = true; }\n\t\t\t\t\telse if (!set.fontSize) { if (d[i] != 'inherit') f.fontSize = d[i].split('/')[0]; set.fontStyle = set.fontVariant = set.fontWeight = set.fontSize = true; }\n\t\t\t\t\telse { if (d[i] != 'inherit') ff += d[i]; }\n\t\t\t\t} if (ff != '') f.fontFamily = ff;\n\t\t\t\treturn f;\n\t\t\t}\n\t\t});\n\t\t\n\t\t// points and paths\n\t\tsvg.ToNumberArray = function(s) {\n\t\t\tvar a = svg.trim(svg.compressSpaces((s || '').replace(/,/g, ' '))).split(' ');\n\t\t\tfor (var i=0; i<a.length; i++) {\n\t\t\t\ta[i] = parseFloat(a[i]);\n\t\t\t}\n\t\t\treturn a;\n\t\t}\t\t\n\t\tsvg.Point = function(x, y) {\n\t\t\tthis.x = x;\n\t\t\tthis.y = y;\n\t\t\t\n\t\t\tthis.angleTo = function(p) {\n\t\t\t\treturn Math.atan2(p.y - this.y, p.x - this.x);\n\t\t\t}\n\t\t\t\n\t\t\tthis.applyTransform = function(v) {\n\t\t\t\tvar xp = this.x * v[0] + this.y * v[2] + v[4];\n\t\t\t\tvar yp = this.x * v[1] + this.y * v[3] + v[5];\n\t\t\t\tthis.x = xp;\n\t\t\t\tthis.y = yp;\n\t\t\t}\n\t\t}\n\t\tsvg.CreatePoint = function(s) {\n\t\t\tvar a = svg.ToNumberArray(s);\n\t\t\treturn new svg.Point(a[0], a[1]);\n\t\t}\n\t\tsvg.CreatePath = function(s) {\n\t\t\tvar a = svg.ToNumberArray(s);\n\t\t\tvar path = [];\n\t\t\tfor (var i=0; i<a.length; i+=2) {\n\t\t\t\tpath.push(new svg.Point(a[i], a[i+1]));\n\t\t\t}\n\t\t\treturn path;\n\t\t}\n\t\t\n\t\t// bounding box\n\t\tsvg.BoundingBox = function(x1, y1, x2, y2) { // pass in initial points if you want\n\t\t\tthis.x1 = Number.NaN;\n\t\t\tthis.y1 = Number.NaN;\n\t\t\tthis.x2 = Number.NaN;\n\t\t\tthis.y2 = Number.NaN;\n\t\t\t\n\t\t\tthis.x = function() { return this.x1; }\n\t\t\tthis.y = function() { return this.y1; }\n\t\t\tthis.width = function() { return this.x2 - this.x1; }\n\t\t\tthis.height = function() { return this.y2 - this.y1; }\n\t\t\t\n\t\t\tthis.addPoint = function(x, y) {\t\n\t\t\t\tif (x != null) {\n\t\t\t\t\tif (isNaN(this.x1) || isNaN(this.x2)) {\n\t\t\t\t\t\tthis.x1 = x;\n\t\t\t\t\t\tthis.x2 = x;\n\t\t\t\t\t}\n\t\t\t\t\tif (x < this.x1) this.x1 = x;\n\t\t\t\t\tif (x > this.x2) this.x2 = x;\n\t\t\t\t}\n\t\t\t\n\t\t\t\tif (y != null) {\n\t\t\t\t\tif (isNaN(this.y1) || isNaN(this.y2)) {\n\t\t\t\t\t\tthis.y1 = y;\n\t\t\t\t\t\tthis.y2 = y;\n\t\t\t\t\t}\n\t\t\t\t\tif (y < this.y1) this.y1 = y;\n\t\t\t\t\tif (y > this.y2) this.y2 = y;\n\t\t\t\t}\n\t\t\t}\t\t\t\n\t\t\tthis.addX = function(x) { this.addPoint(x, null); }\n\t\t\tthis.addY = function(y) { this.addPoint(null, y); }\n\t\t\t\n\t\t\tthis.addBoundingBox = function(bb) {\n\t\t\t\tthis.addPoint(bb.x1, bb.y1);\n\t\t\t\tthis.addPoint(bb.x2, bb.y2);\n\t\t\t}\n\t\t\t\n\t\t\tthis.addQuadraticCurve = function(p0x, p0y, p1x, p1y, p2x, p2y) {\n\t\t\t\tvar cp1x = p0x + 2/3 * (p1x - p0x); // CP1 = QP0 + 2/3 *(QP1-QP0)\n\t\t\t\tvar cp1y = p0y + 2/3 * (p1y - p0y); // CP1 = QP0 + 2/3 *(QP1-QP0)\n\t\t\t\tvar cp2x = cp1x + 1/3 * (p2x - p0x); // CP2 = CP1 + 1/3 *(QP2-QP0)\n\t\t\t\tvar cp2y = cp1y + 1/3 * (p2y - p0y); // CP2 = CP1 + 1/3 *(QP2-QP0)\n\t\t\t\tthis.addBezierCurve(p0x, p0y, cp1x, cp2x, cp1y,\tcp2y, p2x, p2y);\n\t\t\t}\n\t\t\t\n\t\t\tthis.addBezierCurve = function(p0x, p0y, p1x, p1y, p2x, p2y, p3x, p3y) {\n\t\t\t\t// from http://blog.hackers-cafe.net/2009/06/how-to-calculate-bezier-curves-bounding.html\n\t\t\t\tvar p0 = [p0x, p0y], p1 = [p1x, p1y], p2 = [p2x, p2y], p3 = [p3x, p3y];\n\t\t\t\tthis.addPoint(p0[0], p0[1]);\n\t\t\t\tthis.addPoint(p3[0], p3[1]);\n\t\t\t\t\n\t\t\t\tfor (i=0; i<=1; i++) {\n\t\t\t\t\tvar f = function(t) { \n\t\t\t\t\t\treturn Math.pow(1-t, 3) * p0[i]\n\t\t\t\t\t\t+ 3 * Math.pow(1-t, 2) * t * p1[i]\n\t\t\t\t\t\t+ 3 * (1-t) * Math.pow(t, 2) * p2[i]\n\t\t\t\t\t\t+ Math.pow(t, 3) * p3[i];\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tvar b = 6 * p0[i] - 12 * p1[i] + 6 * p2[i];\n\t\t\t\t\tvar a = -3 * p0[i] + 9 * p1[i] - 9 * p2[i] + 3 * p3[i];\n\t\t\t\t\tvar c = 3 * p1[i] - 3 * p0[i];\n\t\t\t\t\t\n\t\t\t\t\tif (a == 0) {\n\t\t\t\t\t\tif (b == 0) continue;\n\t\t\t\t\t\tvar t = -c / b;\n\t\t\t\t\t\tif (0 < t && t < 1) {\n\t\t\t\t\t\t\tif (i == 0) this.addX(f(t));\n\t\t\t\t\t\t\tif (i == 1) this.addY(f(t));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tvar b2ac = Math.pow(b, 2) - 4 * c * a;\n\t\t\t\t\tif (b2ac < 0) continue;\n\t\t\t\t\tvar t1 = (-b + Math.sqrt(b2ac)) / (2 * a);\n\t\t\t\t\tif (0 < t1 && t1 < 1) {\n\t\t\t\t\t\tif (i == 0) this.addX(f(t1));\n\t\t\t\t\t\tif (i == 1) this.addY(f(t1));\n\t\t\t\t\t}\n\t\t\t\t\tvar t2 = (-b - Math.sqrt(b2ac)) / (2 * a);\n\t\t\t\t\tif (0 < t2 && t2 < 1) {\n\t\t\t\t\t\tif (i == 0) this.addX(f(t2));\n\t\t\t\t\t\tif (i == 1) this.addY(f(t2));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tthis.isPointInBox = function(x, y) {\n\t\t\t\treturn (this.x1 <= x && x <= this.x2 && this.y1 <= y && y <= this.y2);\n\t\t\t}\n\t\t\t\n\t\t\tthis.addPoint(x1, y1);\n\t\t\tthis.addPoint(x2, y2);\n\t\t}\n\t\t\n\t\t// transforms\n\t\tsvg.Transform = function(v) {\t\n\t\t\tvar that = this;\n\t\t\tthis.Type = {}\n\t\t\n\t\t\t// translate\n\t\t\tthis.Type.translate = function(s) {\n\t\t\t\tthis.p = svg.CreatePoint(s);\t\t\t\n\t\t\t\tthis.apply = function(ctx) {\n\t\t\t\t\tctx.translate(this.p.x || 0.0, this.p.y || 0.0);\n\t\t\t\t}\n\t\t\t\tthis.applyToPoint = function(p) {\n\t\t\t\t\tp.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// rotate\n\t\t\tthis.Type.rotate = function(s) {\n\t\t\t\tvar a = svg.ToNumberArray(s);\n\t\t\t\tthis.angle = new svg.Property('angle', a[0]);\n\t\t\t\tthis.cx = a[1] || 0;\n\t\t\t\tthis.cy = a[2] || 0;\n\t\t\t\tthis.apply = function(ctx) {\n\t\t\t\t\tctx.translate(this.cx, this.cy);\n\t\t\t\t\tctx.rotate(this.angle.Angle.toRadians());\n\t\t\t\t\tctx.translate(-this.cx, -this.cy);\n\t\t\t\t}\n\t\t\t\tthis.applyToPoint = function(p) {\n\t\t\t\t\tvar a = this.angle.Angle.toRadians();\n\t\t\t\t\tp.applyTransform([1, 0, 0, 1, this.p.x || 0.0, this.p.y || 0.0]);\n\t\t\t\t\tp.applyTransform([Math.cos(a), Math.sin(a), -Math.sin(a), Math.cos(a), 0, 0]);\n\t\t\t\t\tp.applyTransform([1, 0, 0, 1, -this.p.x || 0.0, -this.p.y || 0.0]);\n\t\t\t\t}\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\tthis.Type.scale = function(s) {\n\t\t\t\tthis.p = svg.CreatePoint(s);\n\t\t\t\tthis.apply = function(ctx) {\n\t\t\t\t\tctx.scale(this.p.x || 1.0, this.p.y || this.p.x || 1.0);\n\t\t\t\t}\n\t\t\t\tthis.applyToPoint = function(p) {\n\t\t\t\t\tp.applyTransform([this.p.x || 0.0, 0, 0, this.p.y || 0.0, 0, 0]);\n\t\t\t\t}\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\tthis.Type.matrix = function(s) {\n\t\t\t\tthis.m = svg.ToNumberArray(s);\n\t\t\t\tthis.apply = function(ctx) {\n\t\t\t\t\tctx.transform(this.m[0], this.m[1], this.m[2], this.m[3], this.m[4], this.m[5]);\n\t\t\t\t}\n\t\t\t\tthis.applyToPoint = function(p) {\n\t\t\t\t\tp.applyTransform(this.m);\n\t\t\t\t}\t\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\tthis.Type.SkewBase = function(s) {\n\t\t\t\tthis.base = that.Type.matrix;\n\t\t\t\tthis.base(s);\n\t\t\t\tthis.angle = new svg.Property('angle', s);\n\t\t\t}\n\t\t\tthis.Type.SkewBase.prototype = new this.Type.matrix;\n\t\t\t\n\t\t\tthis.Type.skewX = function(s) {\n\t\t\t\tthis.base = that.Type.SkewBase;\n\t\t\t\tthis.base(s);\n\t\t\t\tthis.m = [1, 0, Math.tan(this.angle.Angle.toRadians()), 1, 0, 0];\n\t\t\t}\n\t\t\tthis.Type.skewX.prototype = new this.Type.SkewBase;\n\t\t\t\n\t\t\tthis.Type.skewY = function(s) {\n\t\t\t\tthis.base = that.Type.SkewBase;\n\t\t\t\tthis.base(s);\n\t\t\t\tthis.m = [1, Math.tan(this.angle.Angle.toRadians()), 0, 1, 0, 0];\n\t\t\t}\n\t\t\tthis.Type.skewY.prototype = new this.Type.SkewBase;\n\t\t\n\t\t\tthis.transforms = [];\n\t\t\t\n\t\t\tthis.apply = function(ctx) {\n\t\t\t\tfor (var i=0; i<this.transforms.length; i++) {\n\t\t\t\t\tthis.transforms[i].apply(ctx);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tthis.applyToPoint = function(p) {\n\t\t\t\tfor (var i=0; i<this.transforms.length; i++) {\n\t\t\t\t\tthis.transforms[i].applyToPoint(p);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tvar data = svg.trim(svg.compressSpaces(v)).split(/\\s(?=[a-z])/);\n\t\t\tfor (var i=0; i<data.length; i++) {\n\t\t\t\tvar type = data[i].split('(')[0];\n\t\t\t\tvar s = data[i].split('(')[1].replace(')','');\n\t\t\t\tvar transform = new this.Type[type](s);\n\t\t\t\tthis.transforms.push(transform);\n\t\t\t}\n\t\t}\n\t\t\n\t\t// aspect ratio\n\t\tsvg.AspectRatio = function(ctx, aspectRatio, width, desiredWidth, height, desiredHeight, minX, minY, refX, refY) {\n\t\t\t// aspect ratio - http://www.w3.org/TR/SVG/coords.html#PreserveAspectRatioAttribute\n\t\t\taspectRatio = svg.compressSpaces(aspectRatio);\n\t\t\taspectRatio = aspectRatio.replace(/^defer\\s/,''); // ignore defer\n\t\t\tvar align = aspectRatio.split(' ')[0] || 'xMidYMid';\n\t\t\tvar meetOrSlice = aspectRatio.split(' ')[1] || 'meet';\t\t\t\t\t\n\t\n\t\t\t// calculate scale\n\t\t\tvar scaleX = width / desiredWidth;\n\t\t\tvar scaleY = height / desiredHeight;\n\t\t\tvar scaleMin = Math.min(scaleX, scaleY);\n\t\t\tvar scaleMax = Math.max(scaleX, scaleY);\n\t\t\tif (meetOrSlice == 'meet') { desiredWidth *= scaleMin; desiredHeight *= scaleMin; }\n\t\t\tif (meetOrSlice == 'slice') { desiredWidth *= scaleMax; desiredHeight *= scaleMax; }\t\n\t\t\t\n\t\t\trefX = new svg.Property('refX', refX);\n\t\t\trefY = new svg.Property('refY', refY);\n\t\t\tif (refX.hasValue() && refY.hasValue()) {\t\t\t\t\n\t\t\t\tctx.translate(-scaleMin * refX.Length.toPixels('x'), -scaleMin * refY.Length.toPixels('y'));\n\t\t\t} \n\t\t\telse {\t\t\t\t\t\n\t\t\t\t// align\n\t\t\t\tif (align.match(/^xMid/) && ((meetOrSlice == 'meet' && scaleMin == scaleY) || (meetOrSlice == 'slice' && scaleMax == scaleY))) ctx.translate(width / 2.0 - desiredWidth / 2.0, 0); \n\t\t\t\tif (align.match(/YMid$/) && ((meetOrSlice == 'meet' && scaleMin == scaleX) || (meetOrSlice == 'slice' && scaleMax == scaleX))) ctx.translate(0, height / 2.0 - desiredHeight / 2.0); \n\t\t\t\tif (align.match(/^xMax/) && ((meetOrSlice == 'meet' && scaleMin == scaleY) || (meetOrSlice == 'slice' && scaleMax == scaleY))) ctx.translate(width - desiredWidth, 0); \n\t\t\t\tif (align.match(/YMax$/) && ((meetOrSlice == 'meet' && scaleMin == scaleX) || (meetOrSlice == 'slice' && scaleMax == scaleX))) ctx.translate(0, height - desiredHeight); \n\t\t\t}\n\t\t\t\n\t\t\t// scale\n\t\t\tif (align == 'none') ctx.scale(scaleX, scaleY);\n\t\t\telse if (meetOrSlice == 'meet') ctx.scale(scaleMin, scaleMin); \n\t\t\telse if (meetOrSlice == 'slice') ctx.scale(scaleMax, scaleMax); \t\n\t\t\t\n\t\t\t// translate\n\t\t\tctx.translate(minX == null ? 0 : -minX, minY == null ? 0 : -minY);\t\t\t\n\t\t}\n\t\t\n\t\t// elements\n\t\tsvg.Element = {}\n\t\t\n\t\tsvg.Element.ElementBase = function(node) {\t\n\t\t\tthis.attributes = {};\n\t\t\tthis.styles = {};\n\t\t\tthis.children = [];\n\t\t\t\n\t\t\t// get or create attribute\n\t\t\tthis.attribute = function(name, createIfNotExists) {\n\t\t\t\tvar a = this.attributes[name];\n\t\t\t\tif (a != null) return a;\n\t\t\t\t\t\t\t\n\t\t\t\ta = new svg.Property(name, '');\n\t\t\t\tif (createIfNotExists == true) this.attributes[name] = a;\n\t\t\t\treturn a;\n\t\t\t}\n\t\t\t\n\t\t\t// get or create style, crawls up node tree\n\t\t\tthis.style = function(name, createIfNotExists) {\n\t\t\t\tvar s = this.styles[name];\n\t\t\t\tif (s != null) return s;\n\t\t\t\t\n\t\t\t\tvar a = this.attribute(name);\n\t\t\t\tif (a != null && a.hasValue()) {\n\t\t\t\t\treturn a;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tvar p = this.parent;\n\t\t\t\tif (p != null) {\n\t\t\t\t\tvar ps = p.style(name);\n\t\t\t\t\tif (ps != null && ps.hasValue()) {\n\t\t\t\t\t\treturn ps;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\ts = new svg.Property(name, '');\n\t\t\t\tif (createIfNotExists == true) this.styles[name] = s;\n\t\t\t\treturn s;\n\t\t\t}\n\t\t\t\n\t\t\t// base render\n\t\t\tthis.render = function(ctx) {\n\t\t\t\t// don't render display=none\n\t\t\t\tif (this.style('display').value == 'none') return;\n\t\t\t\t\n\t\t\t\t// don't render visibility=hidden\n\t\t\t\tif (this.attribute('visibility').value == 'hidden') return;\n\t\t\t\n\t\t\t\tctx.save();\n\t\t\t\t\tthis.setContext(ctx);\n\t\t\t\t\t\t// mask\n\t\t\t\t\t\tif (this.attribute('mask').hasValue()) {\n\t\t\t\t\t\t\tvar mask = this.attribute('mask').Definition.getDefinition();\n\t\t\t\t\t\t\tif (mask != null) mask.apply(ctx, this);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse if (this.style('filter').hasValue()) {\n\t\t\t\t\t\t\tvar filter = this.style('filter').Definition.getDefinition();\n\t\t\t\t\t\t\tif (filter != null) filter.apply(ctx, this);\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse this.renderChildren(ctx);\t\t\t\t\n\t\t\t\t\tthis.clearContext(ctx);\n\t\t\t\tctx.restore();\n\t\t\t}\n\t\t\t\n\t\t\t// base set context\n\t\t\tthis.setContext = function(ctx) {\n\t\t\t\t// OVERRIDE ME!\n\t\t\t}\n\t\t\t\n\t\t\t// base clear context\n\t\t\tthis.clearContext = function(ctx) {\n\t\t\t\t// OVERRIDE ME!\n\t\t\t}\t\t\t\n\t\t\t\n\t\t\t// base render children\n\t\t\tthis.renderChildren = function(ctx) {\n\t\t\t\tfor (var i=0; i<this.children.length; i++) {\n\t\t\t\t\tthis.children[i].render(ctx);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tthis.addChild = function(childNode, create) {\n\t\t\t\tvar child = childNode;\n\t\t\t\tif (create) child = svg.CreateElement(childNode);\n\t\t\t\tchild.parent = this;\n\t\t\t\tthis.children.push(child);\t\t\t\n\t\t\t}\n\t\t\t\t\n\t\t\tif (node != null && node.nodeType == 1) { //ELEMENT_NODE\n\t\t\t\t// add children\n\t\t\t\tfor (var i=0; i<node.childNodes.length; i++) {\n\t\t\t\t\tvar childNode = node.childNodes[i];\n\t\t\t\t\tif (childNode.nodeType == 1) this.addChild(childNode, true); //ELEMENT_NODE\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// add attributes\n\t\t\t\tfor (var i=0; i<node.attributes.length; i++) {\n\t\t\t\t\tvar attribute = node.attributes[i];\n\t\t\t\t\tthis.attributes[attribute.nodeName] = new svg.Property(attribute.nodeName, attribute.nodeValue);\n\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t// add tag styles\n\t\t\t\tvar styles = svg.Styles[node.nodeName];\n\t\t\t\tif (styles != null) {\n\t\t\t\t\tfor (var name in styles) {\n\t\t\t\t\t\tthis.styles[name] = styles[name];\n\t\t\t\t\t}\n\t\t\t\t}\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t// add class styles\n\t\t\t\tif (this.attribute('class').hasValue()) {\n\t\t\t\t\tvar classes = svg.compressSpaces(this.attribute('class').value).split(' ');\n\t\t\t\t\tfor (var j=0; j<classes.length; j++) {\n\t\t\t\t\t\tstyles = svg.Styles['.'+classes[j]];\n\t\t\t\t\t\tif (styles != null) {\n\t\t\t\t\t\t\tfor (var name in styles) {\n\t\t\t\t\t\t\t\tthis.styles[name] = styles[name];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tstyles = svg.Styles[node.nodeName+'.'+classes[j]];\n\t\t\t\t\t\tif (styles != null) {\n\t\t\t\t\t\t\tfor (var name in styles) {\n\t\t\t\t\t\t\t\tthis.styles[name] = styles[name];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// add inline styles\n\t\t\t\tif (this.attribute('style').hasValue()) {\n\t\t\t\t\tvar styles = this.attribute('style').value.split(';');\n\t\t\t\t\tfor (var i=0; i<styles.length; i++) {\n\t\t\t\t\t\tif (svg.trim(styles[i]) != '') {\n\t\t\t\t\t\t\tvar style = styles[i].split(':');\n\t\t\t\t\t\t\tvar name = svg.trim(style[0]);\n\t\t\t\t\t\t\tvar value = svg.trim(style[1]);\n\t\t\t\t\t\t\tthis.styles[name] = new svg.Property(name, value);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\t\n\n\t\t\t\t// add id\n\t\t\t\tif (this.attribute('id').hasValue()) {\n\t\t\t\t\tif (svg.Definitions[this.attribute('id').value] == null) {\n\t\t\t\t\t\tsvg.Definitions[this.attribute('id').value] = this;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t\n\t\tsvg.Element.RenderedElementBase = function(node) {\n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.setContext = function(ctx) {\n\t\t\t\t// fill\n\t\t\t\tif (this.style('fill').Definition.isUrl()) {\n\t\t\t\t\tvar fs = this.style('fill').Definition.getFillStyle(this);\n\t\t\t\t\tif (fs != null) ctx.fillStyle = fs;\n\t\t\t\t}\n\t\t\t\telse if (this.style('fill').hasValue()) {\n\t\t\t\t\tvar fillStyle = this.style('fill');\n\t\t\t\t\tif (this.style('fill-opacity').hasValue()) fillStyle = fillStyle.Color.addOpacity(this.style('fill-opacity').value);\n\t\t\t\t\tctx.fillStyle = (fillStyle.value == 'none' ? 'rgba(0,0,0,0)' : fillStyle.value);\n\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\n\t\t\t\t// stroke\n\t\t\t\tif (this.style('stroke').Definition.isUrl()) {\n\t\t\t\t\tvar fs = this.style('stroke').Definition.getFillStyle(this);\n\t\t\t\t\tif (fs != null) ctx.strokeStyle = fs;\n\t\t\t\t}\n\t\t\t\telse if (this.style('stroke').hasValue()) {\n\t\t\t\t\tvar strokeStyle = this.style('stroke');\n\t\t\t\t\tif (this.style('stroke-opacity').hasValue()) strokeStyle = strokeStyle.Color.addOpacity(this.style('stroke-opacity').value);\n\t\t\t\t\tctx.strokeStyle = (strokeStyle.value == 'none' ? 'rgba(0,0,0,0)' : strokeStyle.value);\n\t\t\t\t}\n\t\t\t\tif (this.style('stroke-width').hasValue()) ctx.lineWidth = this.style('stroke-width').Length.toPixels();\n\t\t\t\tif (this.style('stroke-linecap').hasValue()) ctx.lineCap = this.style('stroke-linecap').value;\n\t\t\t\tif (this.style('stroke-linejoin').hasValue()) ctx.lineJoin = this.style('stroke-linejoin').value;\n\t\t\t\tif (this.style('stroke-miterlimit').hasValue()) ctx.miterLimit = this.style('stroke-miterlimit').value;\n\n\t\t\t\t// font\n\t\t\t\tif (typeof(ctx.font) != 'undefined') {\n\t\t\t\t\tctx.font = svg.Font.CreateFont( \n\t\t\t\t\t\tthis.style('font-style').value, \n\t\t\t\t\t\tthis.style('font-variant').value, \n\t\t\t\t\t\tthis.style('font-weight').value, \n\t\t\t\t\t\tthis.style('font-size').hasValue() ? this.style('font-size').Length.toPixels() + 'px' : '', \n\t\t\t\t\t\tthis.style('font-family').value).toString();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// transform\n\t\t\t\tif (this.attribute('transform').hasValue()) { \n\t\t\t\t\tvar transform = new svg.Transform(this.attribute('transform').value);\n\t\t\t\t\ttransform.apply(ctx);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// clip\n\t\t\t\tif (this.attribute('clip-path').hasValue()) {\n\t\t\t\t\tvar clip = this.attribute('clip-path').Definition.getDefinition();\n\t\t\t\t\tif (clip != null) clip.apply(ctx);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// opacity\n\t\t\t\tif (this.style('opacity').hasValue()) {\n\t\t\t\t\tctx.globalAlpha = this.style('opacity').numValue();\n\t\t\t\t}\n\t\t\t}\t\t\n\t\t}\n\t\tsvg.Element.RenderedElementBase.prototype = new svg.Element.ElementBase;\n\t\t\n\t\tsvg.Element.PathElementBase = function(node) {\n\t\t\tthis.base = svg.Element.RenderedElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.path = function(ctx) {\n\t\t\t\tif (ctx != null) ctx.beginPath();\n\t\t\t\treturn new svg.BoundingBox();\n\t\t\t}\n\t\t\t\n\t\t\tthis.renderChildren = function(ctx) {\n\t\t\t\tthis.path(ctx);\n\t\t\t\tsvg.Mouse.checkPath(this, ctx);\n\t\t\t\tif (ctx.fillStyle != '') ctx.fill();\n\t\t\t\tif (ctx.strokeStyle != '') ctx.stroke();\n\t\t\t\t\n\t\t\t\tvar markers = this.getMarkers();\n\t\t\t\tif (markers != null) {\n\t\t\t\t\tif (this.style('marker-start').Definition.isUrl()) {\n\t\t\t\t\t\tvar marker = this.style('marker-start').Definition.getDefinition();\n\t\t\t\t\t\tmarker.render(ctx, markers[0][0], markers[0][1]);\n\t\t\t\t\t}\n\t\t\t\t\tif (this.style('marker-mid').Definition.isUrl()) {\n\t\t\t\t\t\tvar marker = this.style('marker-mid').Definition.getDefinition();\n\t\t\t\t\t\tfor (var i=1;i<markers.length-1;i++) {\n\t\t\t\t\t\t\tmarker.render(ctx, markers[i][0], markers[i][1]);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif (this.style('marker-end').Definition.isUrl()) {\n\t\t\t\t\t\tvar marker = this.style('marker-end').Definition.getDefinition();\n\t\t\t\t\t\tmarker.render(ctx, markers[markers.length-1][0], markers[markers.length-1][1]);\n\t\t\t\t\t}\n\t\t\t\t}\t\t\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\tthis.getBoundingBox = function() {\n\t\t\t\treturn this.path();\n\t\t\t}\n\t\t\t\n\t\t\tthis.getMarkers = function() {\n\t\t\t\treturn null;\n\t\t\t}\n\t\t}\n\t\tsvg.Element.PathElementBase.prototype = new svg.Element.RenderedElementBase;\n\t\t\n\t\t// svg element\n\t\tsvg.Element.svg = function(node) {\n\t\t\tthis.base = svg.Element.RenderedElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.baseClearContext = this.clearContext;\n\t\t\tthis.clearContext = function(ctx) {\n\t\t\t\tthis.baseClearContext(ctx);\n\t\t\t\tsvg.ViewPort.RemoveCurrent();\n\t\t\t}\n\t\t\t\n\t\t\tthis.baseSetContext = this.setContext;\n\t\t\tthis.setContext = function(ctx) {\n\t\t\t\t// initial values\n\t\t\t\tctx.strokeStyle = 'rgba(0,0,0,0)';\n\t\t\t\tctx.lineCap = 'butt';\n\t\t\t\tctx.lineJoin = 'miter';\n\t\t\t\tctx.miterLimit = 4;\t\t\t\n\t\t\t\n\t\t\t\tthis.baseSetContext(ctx);\n\t\t\t\t\n\t\t\t\t// create new view port\n\t\t\t\tif (this.attribute('x').hasValue() && this.attribute('y').hasValue()) {\n\t\t\t\t\tctx.translate(this.attribute('x').Length.toPixels('x'), this.attribute('y').Length.toPixels('y'));\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tvar width = svg.ViewPort.width();\n\t\t\t\tvar height = svg.ViewPort.height();\n\t\t\t\tif (typeof(this.root) == 'undefined' && this.attribute('width').hasValue() && this.attribute('height').hasValue()) {\n\t\t\t\t\twidth = this.attribute('width').Length.toPixels('x');\n\t\t\t\t\theight = this.attribute('height').Length.toPixels('y');\n\t\t\t\t\t\n\t\t\t\t\tvar x = 0;\n\t\t\t\t\tvar y = 0;\n\t\t\t\t\tif (this.attribute('refX').hasValue() && this.attribute('refY').hasValue()) {\n\t\t\t\t\t\tx = -this.attribute('refX').Length.toPixels('x');\n\t\t\t\t\t\ty = -this.attribute('refY').Length.toPixels('y');\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(x, y);\n\t\t\t\t\tctx.lineTo(width, y);\n\t\t\t\t\tctx.lineTo(width, height);\n\t\t\t\t\tctx.lineTo(x, height);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t\tctx.clip();\n\t\t\t\t}\n\t\t\t\tsvg.ViewPort.SetCurrent(width, height);\t\n\t\t\t\t\t\t\n\t\t\t\t// viewbox\n\t\t\t\tif (this.attribute('viewBox').hasValue()) {\t\t\t\t\n\t\t\t\t\tvar viewBox = svg.ToNumberArray(this.attribute('viewBox').value);\n\t\t\t\t\tvar minX = viewBox[0];\n\t\t\t\t\tvar minY = viewBox[1];\n\t\t\t\t\twidth = viewBox[2];\n\t\t\t\t\theight = viewBox[3];\n\t\t\t\t\t\n\t\t\t\t\tsvg.AspectRatio(ctx,\n\t\t\t\t\t\t\t\t\tthis.attribute('preserveAspectRatio').value, \n\t\t\t\t\t\t\t\t\tsvg.ViewPort.width(), \n\t\t\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\t\t\tsvg.ViewPort.height(),\n\t\t\t\t\t\t\t\t\theight,\n\t\t\t\t\t\t\t\t\tminX,\n\t\t\t\t\t\t\t\t\tminY,\n\t\t\t\t\t\t\t\t\tthis.attribute('refX').value,\n\t\t\t\t\t\t\t\t\tthis.attribute('refY').value);\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\tsvg.ViewPort.RemoveCurrent();\t\n\t\t\t\t\tsvg.ViewPort.SetCurrent(viewBox[2], viewBox[3]);\t\t\t\t\t\t\n\t\t\t\t}\t\t\t\t\n\t\t\t}\n\t\t}\n\t\tsvg.Element.svg.prototype = new svg.Element.RenderedElementBase;\n\n\t\t// rect element\n\t\tsvg.Element.rect = function(node) {\n\t\t\tthis.base = svg.Element.PathElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.path = function(ctx) {\n\t\t\t\tvar x = this.attribute('x').Length.toPixels('x');\n\t\t\t\tvar y = this.attribute('y').Length.toPixels('y');\n\t\t\t\tvar width = this.attribute('width').Length.toPixels('x');\n\t\t\t\tvar height = this.attribute('height').Length.toPixels('y');\n\t\t\t\tvar rx = this.attribute('rx').Length.toPixels('x');\n\t\t\t\tvar ry = this.attribute('ry').Length.toPixels('y');\n\t\t\t\tif (this.attribute('rx').hasValue() && !this.attribute('ry').hasValue()) ry = rx;\n\t\t\t\tif (this.attribute('ry').hasValue() && !this.attribute('rx').hasValue()) rx = ry;\n\t\t\t\t\n\t\t\t\tif (ctx != null) {\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(x + rx, y);\n\t\t\t\t\tctx.lineTo(x + width - rx, y);\n\t\t\t\t\tctx.quadraticCurveTo(x + width, y, x + width, y + ry)\n\t\t\t\t\tctx.lineTo(x + width, y + height - ry);\n\t\t\t\t\tctx.quadraticCurveTo(x + width, y + height, x + width - rx, y + height)\n\t\t\t\t\tctx.lineTo(x + rx, y + height);\n\t\t\t\t\tctx.quadraticCurveTo(x, y + height, x, y + height - ry)\n\t\t\t\t\tctx.lineTo(x, y + ry);\n\t\t\t\t\tctx.quadraticCurveTo(x, y, x + rx, y)\n\t\t\t\t\tctx.closePath();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn new svg.BoundingBox(x, y, x + width, y + height);\n\t\t\t}\n\t\t}\n\t\tsvg.Element.rect.prototype = new svg.Element.PathElementBase;\n\t\t\n\t\t// circle element\n\t\tsvg.Element.circle = function(node) {\n\t\t\tthis.base = svg.Element.PathElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.path = function(ctx) {\n\t\t\t\tvar cx = this.attribute('cx').Length.toPixels('x');\n\t\t\t\tvar cy = this.attribute('cy').Length.toPixels('y');\n\t\t\t\tvar r = this.attribute('r').Length.toPixels();\n\t\t\t\n\t\t\t\tif (ctx != null) {\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.arc(cx, cy, r, 0, Math.PI * 2, true); \n\t\t\t\t\tctx.closePath();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn new svg.BoundingBox(cx - r, cy - r, cx + r, cy + r);\n\t\t\t}\n\t\t}\n\t\tsvg.Element.circle.prototype = new svg.Element.PathElementBase;\t\n\n\t\t// ellipse element\n\t\tsvg.Element.ellipse = function(node) {\n\t\t\tthis.base = svg.Element.PathElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.path = function(ctx) {\n\t\t\t\tvar KAPPA = 4 * ((Math.sqrt(2) - 1) / 3);\n\t\t\t\tvar rx = this.attribute('rx').Length.toPixels('x');\n\t\t\t\tvar ry = this.attribute('ry').Length.toPixels('y');\n\t\t\t\tvar cx = this.attribute('cx').Length.toPixels('x');\n\t\t\t\tvar cy = this.attribute('cy').Length.toPixels('y');\n\t\t\t\t\n\t\t\t\tif (ctx != null) {\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(cx, cy - ry);\n\t\t\t\t\tctx.bezierCurveTo(cx + (KAPPA * rx), cy - ry,  cx + rx, cy - (KAPPA * ry), cx + rx, cy);\n\t\t\t\t\tctx.bezierCurveTo(cx + rx, cy + (KAPPA * ry), cx + (KAPPA * rx), cy + ry, cx, cy + ry);\n\t\t\t\t\tctx.bezierCurveTo(cx - (KAPPA * rx), cy + ry, cx - rx, cy + (KAPPA * ry), cx - rx, cy);\n\t\t\t\t\tctx.bezierCurveTo(cx - rx, cy - (KAPPA * ry), cx - (KAPPA * rx), cy - ry, cx, cy - ry);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn new svg.BoundingBox(cx - rx, cy - ry, cx + rx, cy + ry);\n\t\t\t}\n\t\t}\n\t\tsvg.Element.ellipse.prototype = new svg.Element.PathElementBase;\t\t\t\n\t\t\n\t\t// line element\n\t\tsvg.Element.line = function(node) {\n\t\t\tthis.base = svg.Element.PathElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.getPoints = function() {\n\t\t\t\treturn [\n\t\t\t\t\tnew svg.Point(this.attribute('x1').Length.toPixels('x'), this.attribute('y1').Length.toPixels('y')),\n\t\t\t\t\tnew svg.Point(this.attribute('x2').Length.toPixels('x'), this.attribute('y2').Length.toPixels('y'))];\n\t\t\t}\n\t\t\t\t\t\t\t\t\n\t\t\tthis.path = function(ctx) {\n\t\t\t\tvar points = this.getPoints();\n\t\t\t\t\n\t\t\t\tif (ctx != null) {\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(points[0].x, points[0].y);\n\t\t\t\t\tctx.lineTo(points[1].x, points[1].y);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn new svg.BoundingBox(points[0].x, points[0].y, points[1].x, points[1].y);\n\t\t\t}\n\t\t\t\n\t\t\tthis.getMarkers = function() {\n\t\t\t\tvar points = this.getPoints();\t\n\t\t\t\tvar a = points[0].angleTo(points[1]);\n\t\t\t\treturn [[points[0], a], [points[1], a]];\n\t\t\t}\n\t\t}\n\t\tsvg.Element.line.prototype = new svg.Element.PathElementBase;\t\t\n\t\t\t\t\n\t\t// polyline element\n\t\tsvg.Element.polyline = function(node) {\n\t\t\tthis.base = svg.Element.PathElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.points = svg.CreatePath(this.attribute('points').value);\n\t\t\tthis.path = function(ctx) {\n\t\t\t\tvar bb = new svg.BoundingBox(this.points[0].x, this.points[0].y);\n\t\t\t\tif (ctx != null) {\n\t\t\t\t\tctx.beginPath();\n\t\t\t\t\tctx.moveTo(this.points[0].x, this.points[0].y);\n\t\t\t\t}\n\t\t\t\tfor (var i=1; i<this.points.length; i++) {\n\t\t\t\t\tbb.addPoint(this.points[i].x, this.points[i].y);\n\t\t\t\t\tif (ctx != null) ctx.lineTo(this.points[i].x, this.points[i].y);\n\t\t\t\t}\n\t\t\t\treturn bb;\n\t\t\t}\n\t\t\t\n\t\t\tthis.getMarkers = function() {\n\t\t\t\tvar markers = [];\n\t\t\t\tfor (var i=0; i<this.points.length - 1; i++) {\n\t\t\t\t\tmarkers.push([this.points[i], this.points[i].angleTo(this.points[i+1])]);\n\t\t\t\t}\n\t\t\t\tmarkers.push([this.points[this.points.length-1], markers[markers.length-1][1]]);\n\t\t\t\treturn markers;\n\t\t\t}\t\t\t\n\t\t}\n\t\tsvg.Element.polyline.prototype = new svg.Element.PathElementBase;\t\t\t\t\n\t\t\t\t\n\t\t// polygon element\n\t\tsvg.Element.polygon = function(node) {\n\t\t\tthis.base = svg.Element.polyline;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.basePath = this.path;\n\t\t\tthis.path = function(ctx) {\n\t\t\t\tvar bb = this.basePath(ctx);\n\t\t\t\tif (ctx != null) {\n\t\t\t\t\tctx.lineTo(this.points[0].x, this.points[0].y);\n\t\t\t\t\tctx.closePath();\n\t\t\t\t}\n\t\t\t\treturn bb;\n\t\t\t}\n\t\t}\n\t\tsvg.Element.polygon.prototype = new svg.Element.polyline;\n\n\t\t// path element\n\t\tsvg.Element.path = function(node) {\n\t\t\tthis.base = svg.Element.PathElementBase;\n\t\t\tthis.base(node);\n\t\t\t\t\t\n\t\t\tvar d = this.attribute('d').value;\n\t\t\t// TODO: convert to real lexer based on http://www.w3.org/TR/SVG11/paths.html#PathDataBNF\n\t\t\td = d.replace(/,/gm,' '); // get rid of all commas\n\t\t\td = d.replace(/([MmZzLlHhVvCcSsQqTtAa])([MmZzLlHhVvCcSsQqTtAa])/gm,'$1 $2'); // separate commands from commands\n\t\t\td = d.replace(/([MmZzLlHhVvCcSsQqTtAa])([MmZzLlHhVvCcSsQqTtAa])/gm,'$1 $2'); // separate commands from commands\n\t\t\td = d.replace(/([MmZzLlHhVvCcSsQqTtAa])([^\\s])/gm,'$1 $2'); // separate commands from points\n\t\t\td = d.replace(/([^\\s])([MmZzLlHhVvCcSsQqTtAa])/gm,'$1 $2'); // separate commands from points\n\t\t\td = d.replace(/([0-9])([+\\-])/gm,'$1 $2'); // separate digits when no comma\n\t\t\td = d.replace(/(\\.[0-9]*)(\\.)/gm,'$1 $2'); // separate digits when no comma\n\t\t\td = d.replace(/([Aa](\\s+[0-9]+){3})\\s+([01])\\s*([01])/gm,'$1 $3 $4 '); // shorthand elliptical arc path syntax\n\t\t\td = svg.compressSpaces(d); // compress multiple spaces\n\t\t\td = svg.trim(d);\n\t\t\tthis.PathParser = new (function(d) {\n\t\t\t\tthis.tokens = d.split(' ');\n\t\t\t\t\n\t\t\t\tthis.reset = function() {\n\t\t\t\t\tthis.i = -1;\n\t\t\t\t\tthis.command = '';\n\t\t\t\t\tthis.previousCommand = '';\n\t\t\t\t\tthis.start = new svg.Point(0, 0);\n\t\t\t\t\tthis.control = new svg.Point(0, 0);\n\t\t\t\t\tthis.current = new svg.Point(0, 0);\n\t\t\t\t\tthis.points = [];\n\t\t\t\t\tthis.angles = [];\n\t\t\t\t}\n\t\t\t\t\t\t\t\t\n\t\t\t\tthis.isEnd = function() {\n\t\t\t\t\treturn this.i >= this.tokens.length - 1;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.isCommandOrEnd = function() {\n\t\t\t\t\tif (this.isEnd()) return true;\n\t\t\t\t\treturn this.tokens[this.i + 1].match(/^[A-Za-z]$/) != null;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.isRelativeCommand = function() {\n\t\t\t\t\treturn this.command == this.command.toLowerCase();\n\t\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\t\tthis.getToken = function() {\n\t\t\t\t\tthis.i = this.i + 1;\n\t\t\t\t\treturn this.tokens[this.i];\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.getScalar = function() {\n\t\t\t\t\treturn parseFloat(this.getToken());\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.nextCommand = function() {\n\t\t\t\t\tthis.previousCommand = this.command;\n\t\t\t\t\tthis.command = this.getToken();\n\t\t\t\t}\t\t\t\t\n\t\t\t\t\n\t\t\t\tthis.getPoint = function() {\n\t\t\t\t\tvar p = new svg.Point(this.getScalar(), this.getScalar());\n\t\t\t\t\treturn this.makeAbsolute(p);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.getAsControlPoint = function() {\n\t\t\t\t\tvar p = this.getPoint();\n\t\t\t\t\tthis.control = p;\n\t\t\t\t\treturn p;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.getAsCurrentPoint = function() {\n\t\t\t\t\tvar p = this.getPoint();\n\t\t\t\t\tthis.current = p;\n\t\t\t\t\treturn p;\t\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.getReflectedControlPoint = function() {\n\t\t\t\t\tif (this.previousCommand.toLowerCase() != 'c' && this.previousCommand.toLowerCase() != 's') {\n\t\t\t\t\t\treturn this.current;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// reflect point\n\t\t\t\t\tvar p = new svg.Point(2 * this.current.x - this.control.x, 2 * this.current.y - this.control.y);\t\t\t\t\t\n\t\t\t\t\treturn p;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.makeAbsolute = function(p) {\n\t\t\t\t\tif (this.isRelativeCommand()) {\n\t\t\t\t\t\tp.x = this.current.x + p.x;\n\t\t\t\t\t\tp.y = this.current.y + p.y;\n\t\t\t\t\t}\n\t\t\t\t\treturn p;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.addMarker = function(p, from, priorTo) {\n\t\t\t\t\t// if the last angle isn't filled in because we didn't have this point yet ...\n\t\t\t\t\tif (priorTo != null && this.angles.length > 0 && this.angles[this.angles.length-1] == null) {\n\t\t\t\t\t\tthis.angles[this.angles.length-1] = this.points[this.points.length-1].angleTo(priorTo);\n\t\t\t\t\t}\n\t\t\t\t\tthis.addMarkerAngle(p, from == null ? null : from.angleTo(p));\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tthis.addMarkerAngle = function(p, a) {\n\t\t\t\t\tthis.points.push(p);\n\t\t\t\t\tthis.angles.push(a);\n\t\t\t\t}\t\t\t\t\n\t\t\t\t\n\t\t\t\tthis.getMarkerPoints = function() { return this.points; }\n\t\t\t\tthis.getMarkerAngles = function() {\n\t\t\t\t\tfor (var i=0; i<this.angles.length; i++) {\n\t\t\t\t\t\tif (this.angles[i] == null) {\n\t\t\t\t\t\t\tfor (var j=i+1; j<this.angles.length; j++) {\n\t\t\t\t\t\t\t\tif (this.angles[j] != null) {\n\t\t\t\t\t\t\t\t\tthis.angles[i] = this.angles[j];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this.angles;\n\t\t\t\t}\n\t\t\t})(d);\n\n\t\t\tthis.path = function(ctx) {\n\t\t\t\tvar pp = this.PathParser;\n\t\t\t\tpp.reset();\n\n\t\t\t\tvar bb = new svg.BoundingBox();\n\t\t\t\tif (ctx != null) ctx.beginPath();\n\t\t\t\twhile (!pp.isEnd()) {\n\t\t\t\t\tpp.nextCommand();\n\t\t\t\t\tswitch (pp.command.toUpperCase()) {\n\t\t\t\t\tcase 'M':\n\t\t\t\t\t\tvar p = pp.getAsCurrentPoint();\n\t\t\t\t\t\tpp.addMarker(p);\n\t\t\t\t\t\tbb.addPoint(p.x, p.y);\n\t\t\t\t\t\tif (ctx != null) ctx.moveTo(p.x, p.y);\n\t\t\t\t\t\tpp.start = pp.current;\n\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n\t\t\t\t\t\t\tvar p = pp.getAsCurrentPoint();\n\t\t\t\t\t\t\tpp.addMarker(p, pp.start);\n\t\t\t\t\t\t\tbb.addPoint(p.x, p.y);\n\t\t\t\t\t\t\tif (ctx != null) ctx.lineTo(p.x, p.y);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'L':\n\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n\t\t\t\t\t\t\tvar c = pp.current;\n\t\t\t\t\t\t\tvar p = pp.getAsCurrentPoint();\n\t\t\t\t\t\t\tpp.addMarker(p, c);\n\t\t\t\t\t\t\tbb.addPoint(p.x, p.y);\n\t\t\t\t\t\t\tif (ctx != null) ctx.lineTo(p.x, p.y);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'H':\n\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n\t\t\t\t\t\t\tvar newP = new svg.Point((pp.isRelativeCommand() ? pp.current.x : 0) + pp.getScalar(), pp.current.y);\n\t\t\t\t\t\t\tpp.addMarker(newP, pp.current);\n\t\t\t\t\t\t\tpp.current = newP;\n\t\t\t\t\t\t\tbb.addPoint(pp.current.x, pp.current.y);\n\t\t\t\t\t\t\tif (ctx != null) ctx.lineTo(pp.current.x, pp.current.y);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'V':\n\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n\t\t\t\t\t\t\tvar newP = new svg.Point(pp.current.x, (pp.isRelativeCommand() ? pp.current.y : 0) + pp.getScalar());\n\t\t\t\t\t\t\tpp.addMarker(newP, pp.current);\n\t\t\t\t\t\t\tpp.current = newP;\n\t\t\t\t\t\t\tbb.addPoint(pp.current.x, pp.current.y);\n\t\t\t\t\t\t\tif (ctx != null) ctx.lineTo(pp.current.x, pp.current.y);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'C':\n\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n\t\t\t\t\t\t\tvar curr = pp.current;\n\t\t\t\t\t\t\tvar p1 = pp.getPoint();\n\t\t\t\t\t\t\tvar cntrl = pp.getAsControlPoint();\n\t\t\t\t\t\t\tvar cp = pp.getAsCurrentPoint();\n\t\t\t\t\t\t\tpp.addMarker(cp, cntrl, p1);\n\t\t\t\t\t\t\tbb.addBezierCurve(curr.x, curr.y, p1.x, p1.y, cntrl.x, cntrl.y, cp.x, cp.y);\n\t\t\t\t\t\t\tif (ctx != null) ctx.bezierCurveTo(p1.x, p1.y, cntrl.x, cntrl.y, cp.x, cp.y);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'S':\n\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n\t\t\t\t\t\t\tvar curr = pp.current;\n\t\t\t\t\t\t\tvar p1 = pp.getReflectedControlPoint();\n\t\t\t\t\t\t\tvar cntrl = pp.getAsControlPoint();\n\t\t\t\t\t\t\tvar cp = pp.getAsCurrentPoint();\n\t\t\t\t\t\t\tpp.addMarker(cp, cntrl, p1);\n\t\t\t\t\t\t\tbb.addBezierCurve(curr.x, curr.y, p1.x, p1.y, cntrl.x, cntrl.y, cp.x, cp.y);\n\t\t\t\t\t\t\tif (ctx != null) ctx.bezierCurveTo(p1.x, p1.y, cntrl.x, cntrl.y, cp.x, cp.y);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Q':\n\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n\t\t\t\t\t\t\tvar curr = pp.current;\n\t\t\t\t\t\t\tvar cntrl = pp.getAsControlPoint();\n\t\t\t\t\t\t\tvar cp = pp.getAsCurrentPoint();\n\t\t\t\t\t\t\tpp.addMarker(cp, cntrl, cntrl);\n\t\t\t\t\t\t\tbb.addQuadraticCurve(curr.x, curr.y, cntrl.x, cntrl.y, cp.x, cp.y);\n\t\t\t\t\t\t\tif (ctx != null) ctx.quadraticCurveTo(cntrl.x, cntrl.y, cp.x, cp.y);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'T':\n\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n\t\t\t\t\t\t\tvar curr = pp.current;\n\t\t\t\t\t\t\tvar cntrl = pp.getReflectedControlPoint();\n\t\t\t\t\t\t\tpp.control = cntrl;\n\t\t\t\t\t\t\tvar cp = pp.getAsCurrentPoint();\n\t\t\t\t\t\t\tpp.addMarker(cp, cntrl, cntrl);\n\t\t\t\t\t\t\tbb.addQuadraticCurve(curr.x, curr.y, cntrl.x, cntrl.y, cp.x, cp.y);\n\t\t\t\t\t\t\tif (ctx != null) ctx.quadraticCurveTo(cntrl.x, cntrl.y, cp.x, cp.y);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'A':\n\t\t\t\t\t\twhile (!pp.isCommandOrEnd()) {\n\t\t\t\t\t\t    var curr = pp.current;\n\t\t\t\t\t\t\tvar rx = pp.getScalar();\n\t\t\t\t\t\t\tvar ry = pp.getScalar();\n\t\t\t\t\t\t\tvar xAxisRotation = pp.getScalar() * (Math.PI / 180.0);\n\t\t\t\t\t\t\tvar largeArcFlag = pp.getScalar();\n\t\t\t\t\t\t\tvar sweepFlag = pp.getScalar();\n\t\t\t\t\t\t\tvar cp = pp.getAsCurrentPoint();\n\n\t\t\t\t\t\t\t// Conversion from endpoint to center parameterization\n\t\t\t\t\t\t\t// http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes\n\t\t\t\t\t\t\t// x1', y1'\n\t\t\t\t\t\t\tvar currp = new svg.Point(\n\t\t\t\t\t\t\t\tMath.cos(xAxisRotation) * (curr.x - cp.x) / 2.0 + Math.sin(xAxisRotation) * (curr.y - cp.y) / 2.0,\n\t\t\t\t\t\t\t\t-Math.sin(xAxisRotation) * (curr.x - cp.x) / 2.0 + Math.cos(xAxisRotation) * (curr.y - cp.y) / 2.0\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t// adjust radii\n\t\t\t\t\t\t\tvar l = Math.pow(currp.x,2)/Math.pow(rx,2)+Math.pow(currp.y,2)/Math.pow(ry,2);\n\t\t\t\t\t\t\tif (l > 1) {\n\t\t\t\t\t\t\t\trx *= Math.sqrt(l);\n\t\t\t\t\t\t\t\try *= Math.sqrt(l);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// cx', cy'\n\t\t\t\t\t\t\tvar s = (largeArcFlag == sweepFlag ? -1 : 1) * Math.sqrt(\n\t\t\t\t\t\t\t\t((Math.pow(rx,2)*Math.pow(ry,2))-(Math.pow(rx,2)*Math.pow(currp.y,2))-(Math.pow(ry,2)*Math.pow(currp.x,2))) /\n\t\t\t\t\t\t\t\t(Math.pow(rx,2)*Math.pow(currp.y,2)+Math.pow(ry,2)*Math.pow(currp.x,2))\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tif (isNaN(s)) s = 0;\n\t\t\t\t\t\t\tvar cpp = new svg.Point(s * rx * currp.y / ry, s * -ry * currp.x / rx);\n\t\t\t\t\t\t\t// cx, cy\n\t\t\t\t\t\t\tvar centp = new svg.Point(\n\t\t\t\t\t\t\t\t(curr.x + cp.x) / 2.0 + Math.cos(xAxisRotation) * cpp.x - Math.sin(xAxisRotation) * cpp.y,\n\t\t\t\t\t\t\t\t(curr.y + cp.y) / 2.0 + Math.sin(xAxisRotation) * cpp.x + Math.cos(xAxisRotation) * cpp.y\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t// vector magnitude\n\t\t\t\t\t\t\tvar m = function(v) { return Math.sqrt(Math.pow(v[0],2) + Math.pow(v[1],2)); }\n\t\t\t\t\t\t\t// ratio between two vectors\n\t\t\t\t\t\t\tvar r = function(u, v) { return (u[0]*v[0]+u[1]*v[1]) / (m(u)*m(v)) }\n\t\t\t\t\t\t\t// angle between two vectors\n\t\t\t\t\t\t\tvar a = function(u, v) { return (u[0]*v[1] < u[1]*v[0] ? -1 : 1) * Math.acos(r(u,v)); }\n\t\t\t\t\t\t\t// initial angle\n\t\t\t\t\t\t\tvar a1 = a([1,0], [(currp.x-cpp.x)/rx,(currp.y-cpp.y)/ry]);\n\t\t\t\t\t\t\t// angle delta\n\t\t\t\t\t\t\tvar u = [(currp.x-cpp.x)/rx,(currp.y-cpp.y)/ry];\n\t\t\t\t\t\t\tvar v = [(-currp.x-cpp.x)/rx,(-currp.y-cpp.y)/ry];\n\t\t\t\t\t\t\tvar ad = a(u, v);\n\t\t\t\t\t\t\tif (r(u,v) <= -1) ad = Math.PI;\n\t\t\t\t\t\t\tif (r(u,v) >= 1) ad = 0;\n\n\t\t\t\t\t\t\tif (sweepFlag == 0 && ad > 0) ad = ad - 2 * Math.PI;\n\t\t\t\t\t\t\tif (sweepFlag == 1 && ad < 0) ad = ad + 2 * Math.PI;\n\n\t\t\t\t\t\t\t// for markers\n\t\t\t\t\t\t\tvar halfWay = new svg.Point(\n\t\t\t\t\t\t\t\tcentp.x - rx * Math.cos((a1 + ad) / 2),\n\t\t\t\t\t\t\t\tcentp.y - ry * Math.sin((a1 + ad) / 2)\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\tpp.addMarkerAngle(halfWay, (a1 + ad) / 2 + (sweepFlag == 0 ? 1 : -1) * Math.PI / 2);\n\t\t\t\t\t\t\tpp.addMarkerAngle(cp, ad + (sweepFlag == 0 ? 1 : -1) * Math.PI / 2);\n\n\t\t\t\t\t\t\tbb.addPoint(cp.x, cp.y); // TODO: this is too naive, make it better\n\t\t\t\t\t\t\tif (ctx != null) {\n\t\t\t\t\t\t\t\tvar r = rx > ry ? rx : ry;\n\t\t\t\t\t\t\t\tvar sx = rx > ry ? 1 : rx / ry;\n\t\t\t\t\t\t\t\tvar sy = rx > ry ? ry / rx : 1;\n\n\t\t\t\t\t\t\t\tctx.translate(centp.x, centp.y);\n\t\t\t\t\t\t\t\tctx.rotate(xAxisRotation);\n\t\t\t\t\t\t\t\tctx.scale(sx, sy);\n\t\t\t\t\t\t\t\tctx.arc(0, 0, r, a1, a1 + ad, 1 - sweepFlag);\n\t\t\t\t\t\t\t\tctx.scale(1/sx, 1/sy);\n\t\t\t\t\t\t\t\tctx.rotate(-xAxisRotation);\n\t\t\t\t\t\t\t\tctx.translate(-centp.x, -centp.y);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Z':\n\t\t\t\t\t\tif (ctx != null) ctx.closePath();\n\t\t\t\t\t\tpp.current = pp.start;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn bb;\n\t\t\t}\n\n\t\t\tthis.getMarkers = function() {\n\t\t\t\tvar points = this.PathParser.getMarkerPoints();\n\t\t\t\tvar angles = this.PathParser.getMarkerAngles();\n\t\t\t\t\n\t\t\t\tvar markers = [];\n\t\t\t\tfor (var i=0; i<points.length; i++) {\n\t\t\t\t\tmarkers.push([points[i], angles[i]]);\n\t\t\t\t}\n\t\t\t\treturn markers;\n\t\t\t}\n\t\t}\n\t\tsvg.Element.path.prototype = new svg.Element.PathElementBase;\n\t\t\n\t\t// pattern element\n\t\tsvg.Element.pattern = function(node) {\n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.createPattern = function(ctx, element) {\n\t\t\t\t// render me using a temporary svg element\n\t\t\t\tvar tempSvg = new svg.Element.svg();\n\t\t\t\ttempSvg.attributes['viewBox'] = new svg.Property('viewBox', this.attribute('viewBox').value);\n\t\t\t\ttempSvg.attributes['x'] = new svg.Property('x', this.attribute('x').value);\n\t\t\t\ttempSvg.attributes['y'] = new svg.Property('y', this.attribute('y').value);\n\t\t\t\ttempSvg.attributes['width'] = new svg.Property('width', this.attribute('width').value);\n\t\t\t\ttempSvg.attributes['height'] = new svg.Property('height', this.attribute('height').value);\n\t\t\t\ttempSvg.children = this.children;\n\t\t\t\t\n\t\t\t\tvar c = document.createElement('canvas');\n\t\t\t\tc.width = this.attribute('width').Length.toPixels('x');\n\t\t\t\tc.height = this.attribute('height').Length.toPixels('y');\n\t\t\t\ttempSvg.render(c.getContext('2d'));\t\t\n\t\t\t\treturn ctx.createPattern(c, 'repeat');\n\t\t\t}\n\t\t}\n\t\tsvg.Element.pattern.prototype = new svg.Element.ElementBase;\n\t\t\n\t\t// marker element\n\t\tsvg.Element.marker = function(node) {\n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.baseRender = this.render;\n\t\t\tthis.render = function(ctx, point, angle) {\n\t\t\t\tctx.translate(point.x, point.y);\n\t\t\t\tif (this.attribute('orient').valueOrDefault('auto') == 'auto') ctx.rotate(angle);\n\t\t\t\tif (this.attribute('markerUnits').valueOrDefault('strokeWidth') == 'strokeWidth') ctx.scale(ctx.lineWidth, ctx.lineWidth);\n\t\t\t\tctx.save();\n\t\t\t\t\t\t\t\n\t\t\t\t// render me using a temporary svg element\n\t\t\t\tvar tempSvg = new svg.Element.svg();\n\t\t\t\ttempSvg.attributes['viewBox'] = new svg.Property('viewBox', this.attribute('viewBox').value);\n\t\t\t\ttempSvg.attributes['refX'] = new svg.Property('refX', this.attribute('refX').value);\n\t\t\t\ttempSvg.attributes['refY'] = new svg.Property('refY', this.attribute('refY').value);\n\t\t\t\ttempSvg.attributes['width'] = new svg.Property('width', this.attribute('markerWidth').value);\n\t\t\t\ttempSvg.attributes['height'] = new svg.Property('height', this.attribute('markerHeight').value);\n\t\t\t\ttempSvg.attributes['fill'] = new svg.Property('fill', this.attribute('fill').valueOrDefault('black'));\n\t\t\t\ttempSvg.attributes['stroke'] = new svg.Property('stroke', this.attribute('stroke').valueOrDefault('none'));\n\t\t\t\ttempSvg.children = this.children;\n\t\t\t\ttempSvg.render(ctx);\n\t\t\t\t\n\t\t\t\tctx.restore();\n\t\t\t\tif (this.attribute('markerUnits').valueOrDefault('strokeWidth') == 'strokeWidth') ctx.scale(1/ctx.lineWidth, 1/ctx.lineWidth);\n\t\t\t\tif (this.attribute('orient').valueOrDefault('auto') == 'auto') ctx.rotate(-angle);\n\t\t\t\tctx.translate(-point.x, -point.y);\n\t\t\t}\n\t\t}\n\t\tsvg.Element.marker.prototype = new svg.Element.ElementBase;\n\t\t\n\t\t// definitions element\n\t\tsvg.Element.defs = function(node) {\n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\t\n\t\t\t\n\t\t\tthis.render = function(ctx) {\n\t\t\t\t// NOOP\n\t\t\t}\n\t\t}\n\t\tsvg.Element.defs.prototype = new svg.Element.ElementBase;\n\t\t\n\t\t// base for gradients\n\t\tsvg.Element.GradientBase = function(node) {\n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.gradientUnits = this.attribute('gradientUnits').valueOrDefault('objectBoundingBox');\n\t\t\t\n\t\t\tthis.stops = [];\t\t\t\n\t\t\tfor (var i=0; i<this.children.length; i++) {\n\t\t\t\tvar child = this.children[i];\n\t\t\t\tthis.stops.push(child);\n\t\t\t}\t\n\t\t\t\n\t\t\tthis.getGradient = function() {\n\t\t\t\t// OVERRIDE ME!\n\t\t\t}\t\t\t\n\n\t\t\tthis.createGradient = function(ctx, element) {\n\t\t\t\tvar stopsContainer = this;\n\t\t\t\tif (this.attribute('xlink:href').hasValue()) {\n\t\t\t\t\tstopsContainer = this.attribute('xlink:href').Definition.getDefinition();\n\t\t\t\t}\n\t\t\t\n\t\t\t\tvar g = this.getGradient(ctx, element);\n\t\t\t\tfor (var i=0; i<stopsContainer.stops.length; i++) {\n\t\t\t\t\tg.addColorStop(stopsContainer.stops[i].offset, stopsContainer.stops[i].color);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tif (this.attribute('gradientTransform').hasValue()) {\n\t\t\t\t\t// render as transformed pattern on temporary canvas\n\t\t\t\t\tvar rootView = svg.ViewPort.viewPorts[0];\n\t\t\t\t\t\n\t\t\t\t\tvar rect = new svg.Element.rect();\n\t\t\t\t\trect.attributes['x'] = new svg.Property('x', -svg.MAX_VIRTUAL_PIXELS/3.0);\n\t\t\t\t\trect.attributes['y'] = new svg.Property('y', -svg.MAX_VIRTUAL_PIXELS/3.0);\n\t\t\t\t\trect.attributes['width'] = new svg.Property('width', svg.MAX_VIRTUAL_PIXELS);\n\t\t\t\t\trect.attributes['height'] = new svg.Property('height', svg.MAX_VIRTUAL_PIXELS);\n\t\t\t\t\t\n\t\t\t\t\tvar group = new svg.Element.g();\n\t\t\t\t\tgroup.attributes['transform'] = new svg.Property('transform', this.attribute('gradientTransform').value);\n\t\t\t\t\tgroup.children = [ rect ];\n\t\t\t\t\t\n\t\t\t\t\tvar tempSvg = new svg.Element.svg();\n\t\t\t\t\ttempSvg.attributes['x'] = new svg.Property('x', 0);\n\t\t\t\t\ttempSvg.attributes['y'] = new svg.Property('y', 0);\n\t\t\t\t\ttempSvg.attributes['width'] = new svg.Property('width', rootView.width);\n\t\t\t\t\ttempSvg.attributes['height'] = new svg.Property('height', rootView.height);\n\t\t\t\t\ttempSvg.children = [ group ];\n\t\t\t\t\t\n\t\t\t\t\tvar c = document.createElement('canvas');\n\t\t\t\t\tc.width = rootView.width;\n\t\t\t\t\tc.height = rootView.height;\n\t\t\t\t\tvar tempCtx = c.getContext('2d');\n\t\t\t\t\ttempCtx.fillStyle = g;\n\t\t\t\t\ttempSvg.render(tempCtx);\t\t\n\t\t\t\t\treturn tempCtx.createPattern(c, 'no-repeat');\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn g;\t\t\t\t\n\t\t\t}\n\t\t}\n\t\tsvg.Element.GradientBase.prototype = new svg.Element.ElementBase;\n\t\t\n\t\t// linear gradient element\n\t\tsvg.Element.linearGradient = function(node) {\n\t\t\tthis.base = svg.Element.GradientBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.getGradient = function(ctx, element) {\n\t\t\t\tvar bb = element.getBoundingBox();\n\t\t\t\t\n\t\t\t\tvar x1 = (this.gradientUnits == 'objectBoundingBox' \n\t\t\t\t\t? bb.x() + bb.width() * this.attribute('x1').numValue() \n\t\t\t\t\t: this.attribute('x1').Length.toPixels('x'));\n\t\t\t\tvar y1 = (this.gradientUnits == 'objectBoundingBox' \n\t\t\t\t\t? bb.y() + bb.height() * this.attribute('y1').numValue()\n\t\t\t\t\t: this.attribute('y1').Length.toPixels('y'));\n\t\t\t\tvar x2 = (this.gradientUnits == 'objectBoundingBox' \n\t\t\t\t\t? bb.x() + bb.width() * this.attribute('x2').numValue()\n\t\t\t\t\t: this.attribute('x2').Length.toPixels('x'));\n\t\t\t\tvar y2 = (this.gradientUnits == 'objectBoundingBox' \n\t\t\t\t\t? bb.y() + bb.height() * this.attribute('y2').numValue()\n\t\t\t\t\t: this.attribute('y2').Length.toPixels('y'));\n\n\t\t\t\treturn ctx.createLinearGradient(x1, y1, x2, y2);\n\t\t\t}\n\t\t}\n\t\tsvg.Element.linearGradient.prototype = new svg.Element.GradientBase;\n\t\t\n\t\t// radial gradient element\n\t\tsvg.Element.radialGradient = function(node) {\n\t\t\tthis.base = svg.Element.GradientBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.getGradient = function(ctx, element) {\n\t\t\t\tvar bb = element.getBoundingBox();\n\t\t\t\t\n\t\t\t\tvar cx = (this.gradientUnits == 'objectBoundingBox' \n\t\t\t\t\t? bb.x() + bb.width() * this.attribute('cx').numValue() \n\t\t\t\t\t: this.attribute('cx').Length.toPixels('x'));\n\t\t\t\tvar cy = (this.gradientUnits == 'objectBoundingBox' \n\t\t\t\t\t? bb.y() + bb.height() * this.attribute('cy').numValue() \n\t\t\t\t\t: this.attribute('cy').Length.toPixels('y'));\n\t\t\t\t\n\t\t\t\tvar fx = cx;\n\t\t\t\tvar fy = cy;\n\t\t\t\tif (this.attribute('fx').hasValue()) {\n\t\t\t\t\tfx = (this.gradientUnits == 'objectBoundingBox' \n\t\t\t\t\t? bb.x() + bb.width() * this.attribute('fx').numValue() \n\t\t\t\t\t: this.attribute('fx').Length.toPixels('x'));\n\t\t\t\t}\n\t\t\t\tif (this.attribute('fy').hasValue()) {\n\t\t\t\t\tfy = (this.gradientUnits == 'objectBoundingBox' \n\t\t\t\t\t? bb.y() + bb.height() * this.attribute('fy').numValue() \n\t\t\t\t\t: this.attribute('fy').Length.toPixels('y'));\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\tvar r = (this.gradientUnits == 'objectBoundingBox' \n\t\t\t\t\t? (bb.width() + bb.height()) / 2.0 * this.attribute('r').numValue()\n\t\t\t\t\t: this.attribute('r').Length.toPixels());\n\t\t\t\t\n\t\t\t\treturn ctx.createRadialGradient(fx, fy, 0, cx, cy, r);\n\t\t\t}\n\t\t}\n\t\tsvg.Element.radialGradient.prototype = new svg.Element.GradientBase;\n\t\t\n\t\t// gradient stop element\n\t\tsvg.Element.stop = function(node) {\n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.offset = this.attribute('offset').numValue();\n\t\t\t\n\t\t\tvar stopColor = this.style('stop-color');\n\t\t\tif (this.style('stop-opacity').hasValue()) stopColor = stopColor.Color.addOpacity(this.style('stop-opacity').value);\n\t\t\tthis.color = stopColor.value;\n\t\t}\n\t\tsvg.Element.stop.prototype = new svg.Element.ElementBase;\n\t\t\n\t\t// animation base element\n\t\tsvg.Element.AnimateBase = function(node) {\n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tsvg.Animations.push(this);\n\t\t\t\n\t\t\tthis.duration = 0.0;\n\t\t\tthis.begin = this.attribute('begin').Time.toMilliseconds();\n\t\t\tthis.maxDuration = this.begin + this.attribute('dur').Time.toMilliseconds();\n\t\t\t\n\t\t\tthis.getProperty = function() {\n\t\t\t\tvar attributeType = this.attribute('attributeType').value;\n\t\t\t\tvar attributeName = this.attribute('attributeName').value;\n\t\t\t\t\n\t\t\t\tif (attributeType == 'CSS') {\n\t\t\t\t\treturn this.parent.style(attributeName, true);\n\t\t\t\t}\n\t\t\t\treturn this.parent.attribute(attributeName, true);\t\t\t\n\t\t\t};\n\t\t\t\n\t\t\tthis.initialValue = null;\n\t\t\tthis.removed = false;\t\t\t\n\n\t\t\tthis.calcValue = function() {\n\t\t\t\t// OVERRIDE ME!\n\t\t\t\treturn '';\n\t\t\t}\n\t\t\t\n\t\t\tthis.update = function(delta) {\t\n\t\t\t\t// set initial value\n\t\t\t\tif (this.initialValue == null) {\n\t\t\t\t\tthis.initialValue = this.getProperty().value;\n\t\t\t\t}\n\t\t\t\n\t\t\t\t// if we're past the end time\n\t\t\t\tif (this.duration > this.maxDuration) {\n\t\t\t\t\t// loop for indefinitely repeating animations\n\t\t\t\t\tif (this.attribute('repeatCount').value == 'indefinite') {\n\t\t\t\t\t\tthis.duration = 0.0\n\t\t\t\t\t}\n\t\t\t\t\telse if (this.attribute('fill').valueOrDefault('remove') == 'remove' && !this.removed) {\n\t\t\t\t\t\tthis.removed = true;\n\t\t\t\t\t\tthis.getProperty().value = this.initialValue;\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\treturn false; // no updates made\n\t\t\t\t\t}\n\t\t\t\t}\t\t\t\n\t\t\t\tthis.duration = this.duration + delta;\n\t\t\t\n\t\t\t\t// if we're past the begin time\n\t\t\t\tvar updated = false;\n\t\t\t\tif (this.begin < this.duration) {\n\t\t\t\t\tvar newValue = this.calcValue(); // tween\n\t\t\t\t\t\n\t\t\t\t\tif (this.attribute('type').hasValue()) {\n\t\t\t\t\t\t// for transform, etc.\n\t\t\t\t\t\tvar type = this.attribute('type').value;\n\t\t\t\t\t\tnewValue = type + '(' + newValue + ')';\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tthis.getProperty().value = newValue;\n\t\t\t\t\tupdated = true;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\treturn updated;\n\t\t\t}\n\t\t\t\n\t\t\t// fraction of duration we've covered\n\t\t\tthis.progress = function() {\n\t\t\t\treturn ((this.duration - this.begin) / (this.maxDuration - this.begin));\n\t\t\t}\t\t\t\n\t\t}\n\t\tsvg.Element.AnimateBase.prototype = new svg.Element.ElementBase;\n\t\t\n\t\t// animate element\n\t\tsvg.Element.animate = function(node) {\n\t\t\tthis.base = svg.Element.AnimateBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.calcValue = function() {\n\t\t\t\tvar from = this.attribute('from').numValue();\n\t\t\t\tvar to = this.attribute('to').numValue();\n\t\t\t\t\n\t\t\t\t// tween value linearly\n\t\t\t\treturn from + (to - from) * this.progress(); \n\t\t\t};\n\t\t}\n\t\tsvg.Element.animate.prototype = new svg.Element.AnimateBase;\n\t\t\t\n\t\t// animate color element\n\t\tsvg.Element.animateColor = function(node) {\n\t\t\tthis.base = svg.Element.AnimateBase;\n\t\t\tthis.base(node);\n\n\t\t\tthis.calcValue = function() {\n\t\t\t\tvar from = new RGBColor(this.attribute('from').value);\n\t\t\t\tvar to = new RGBColor(this.attribute('to').value);\n\t\t\t\t\n\t\t\t\tif (from.ok && to.ok) {\n\t\t\t\t\t// tween color linearly\n\t\t\t\t\tvar r = from.r + (to.r - from.r) * this.progress();\n\t\t\t\t\tvar g = from.g + (to.g - from.g) * this.progress();\n\t\t\t\t\tvar b = from.b + (to.b - from.b) * this.progress();\n\t\t\t\t\treturn 'rgb('+parseInt(r,10)+','+parseInt(g,10)+','+parseInt(b,10)+')';\n\t\t\t\t}\n\t\t\t\treturn this.attribute('from').value;\n\t\t\t};\n\t\t}\n\t\tsvg.Element.animateColor.prototype = new svg.Element.AnimateBase;\n\t\t\n\t\t// animate transform element\n\t\tsvg.Element.animateTransform = function(node) {\n\t\t\tthis.base = svg.Element.animate;\n\t\t\tthis.base(node);\n\t\t}\n\t\tsvg.Element.animateTransform.prototype = new svg.Element.animate;\n\t\t\n\t\t// font element\n\t\tsvg.Element.font = function(node) {\n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\n\n\t\t\tthis.horizAdvX = this.attribute('horiz-adv-x').numValue();\t\t\t\n\t\t\t\n\t\t\tthis.isRTL = false;\n\t\t\tthis.isArabic = false;\n\t\t\tthis.fontFace = null;\n\t\t\tthis.missingGlyph = null;\n\t\t\tthis.glyphs = [];\t\t\t\n\t\t\tfor (var i=0; i<this.children.length; i++) {\n\t\t\t\tvar child = this.children[i];\n\t\t\t\tif (child.type == 'font-face') {\n\t\t\t\t\tthis.fontFace = child;\n\t\t\t\t\tif (child.style('font-family').hasValue()) {\n\t\t\t\t\t\tsvg.Definitions[child.style('font-family').value] = this;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse if (child.type == 'missing-glyph') this.missingGlyph = child;\n\t\t\t\telse if (child.type == 'glyph') {\n\t\t\t\t\tif (child.arabicForm != '') {\n\t\t\t\t\t\tthis.isRTL = true;\n\t\t\t\t\t\tthis.isArabic = true;\n\t\t\t\t\t\tif (typeof(this.glyphs[child.unicode]) == 'undefined') this.glyphs[child.unicode] = [];\n\t\t\t\t\t\tthis.glyphs[child.unicode][child.arabicForm] = child;\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tthis.glyphs[child.unicode] = child;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\t\n\t\t}\n\t\tsvg.Element.font.prototype = new svg.Element.ElementBase;\n\t\t\n\t\t// font-face element\n\t\tsvg.Element.fontface = function(node) {\n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\t\n\t\t\t\n\t\t\tthis.ascent = this.attribute('ascent').value;\n\t\t\tthis.descent = this.attribute('descent').value;\n\t\t\tthis.unitsPerEm = this.attribute('units-per-em').numValue();\t\t\t\t\n\t\t}\n\t\tsvg.Element.fontface.prototype = new svg.Element.ElementBase;\n\t\t\n\t\t// missing-glyph element\n\t\tsvg.Element.missingglyph = function(node) {\n\t\t\tthis.base = svg.Element.path;\n\t\t\tthis.base(node);\t\n\t\t\t\n\t\t\tthis.horizAdvX = 0;\n\t\t}\n\t\tsvg.Element.missingglyph.prototype = new svg.Element.path;\n\t\t\n\t\t// glyph element\n\t\tsvg.Element.glyph = function(node) {\n\t\t\tthis.base = svg.Element.path;\n\t\t\tthis.base(node);\t\n\t\t\t\n\t\t\tthis.horizAdvX = this.attribute('horiz-adv-x').numValue();\n\t\t\tthis.unicode = this.attribute('unicode').value;\n\t\t\tthis.arabicForm = this.attribute('arabic-form').value;\n\t\t}\n\t\tsvg.Element.glyph.prototype = new svg.Element.path;\n\t\t\n\t\t// text element\n\t\tsvg.Element.text = function(node) {\n\t\t\tthis.base = svg.Element.RenderedElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tif (node != null) {\n\t\t\t\t// add children\n\t\t\t\tthis.children = [];\n\t\t\t\tfor (var i=0; i<node.childNodes.length; i++) {\n\t\t\t\t\tvar childNode = node.childNodes[i];\n\t\t\t\t\tif (childNode.nodeType == 1) { // capture tspan and tref nodes\n\t\t\t\t\t\tthis.addChild(childNode, true);\n\t\t\t\t\t}\n\t\t\t\t\telse if (childNode.nodeType == 3) { // capture text\n\t\t\t\t\t\tthis.addChild(new svg.Element.tspan(childNode), false);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tthis.baseSetContext = this.setContext;\n\t\t\tthis.setContext = function(ctx) {\n\t\t\t\tthis.baseSetContext(ctx);\n\t\t\t\tif (this.style('dominant-baseline').hasValue()) ctx.textBaseline = this.style('dominant-baseline').value;\n\t\t\t\tif (this.style('alignment-baseline').hasValue()) ctx.textBaseline = this.style('alignment-baseline').value;\n\t\t\t}\n\t\t\t\n\t\t\tthis.renderChildren = function(ctx) {\n\t\t\t\tvar textAnchor = this.style('text-anchor').valueOrDefault('start');\n\t\t\t\tvar x = this.attribute('x').Length.toPixels('x');\n\t\t\t\tvar y = this.attribute('y').Length.toPixels('y');\n\t\t\t\tfor (var i=0; i<this.children.length; i++) {\n\t\t\t\t\tvar child = this.children[i];\n\t\t\t\t\n\t\t\t\t\tif (child.attribute('x').hasValue()) {\n\t\t\t\t\t\tchild.x = child.attribute('x').Length.toPixels('x');\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tif (child.attribute('dx').hasValue()) x += child.attribute('dx').Length.toPixels('x');\n\t\t\t\t\t\tchild.x = x;\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\tvar childLength = child.measureText(ctx);\n\t\t\t\t\tif (textAnchor != 'start' && (i==0 || child.attribute('x').hasValue())) { // new group?\n\t\t\t\t\t\t// loop through rest of children\n\t\t\t\t\t\tvar groupLength = childLength;\n\t\t\t\t\t\tfor (var j=i+1; j<this.children.length; j++) {\n\t\t\t\t\t\t\tvar childInGroup = this.children[j];\n\t\t\t\t\t\t\tif (childInGroup.attribute('x').hasValue()) break; // new group\n\t\t\t\t\t\t\tgroupLength += childInGroup.measureText(ctx);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tchild.x -= (textAnchor == 'end' ? groupLength : groupLength / 2.0);\n\t\t\t\t\t}\n\t\t\t\t\tx = child.x + childLength;\n\t\t\t\t\t\n\t\t\t\t\tif (child.attribute('y').hasValue()) {\n\t\t\t\t\t\tchild.y = child.attribute('y').Length.toPixels('y');\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\tif (child.attribute('dy').hasValue()) y += child.attribute('dy').Length.toPixels('y');\n\t\t\t\t\t\tchild.y = y;\n\t\t\t\t\t}\t\n\t\t\t\t\ty = child.y;\n\t\t\t\t\t\n\t\t\t\t\tchild.render(ctx);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tsvg.Element.text.prototype = new svg.Element.RenderedElementBase;\n\t\t\n\t\t// text base\n\t\tsvg.Element.TextElementBase = function(node) {\n\t\t\tthis.base = svg.Element.RenderedElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.getGlyph = function(font, text, i) {\n\t\t\t\tvar c = text[i];\n\t\t\t\tvar glyph = null;\n\t\t\t\tif (font.isArabic) {\n\t\t\t\t\tvar arabicForm = 'isolated';\n\t\t\t\t\tif ((i==0 || text[i-1]==' ') && i<text.length-2 && text[i+1]!=' ') arabicForm = 'terminal'; \n\t\t\t\t\tif (i>0 && text[i-1]!=' ' && i<text.length-2 && text[i+1]!=' ') arabicForm = 'medial';\n\t\t\t\t\tif (i>0 && text[i-1]!=' ' && (i == text.length-1 || text[i+1]==' ')) arabicForm = 'initial';\n\t\t\t\t\tif (typeof(font.glyphs[c]) != 'undefined') {\n\t\t\t\t\t\tglyph = font.glyphs[c][arabicForm];\n\t\t\t\t\t\tif (glyph == null && font.glyphs[c].type == 'glyph') glyph = font.glyphs[c];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\tglyph = font.glyphs[c];\n\t\t\t\t}\n\t\t\t\tif (glyph == null) glyph = font.missingGlyph;\n\t\t\t\treturn glyph;\n\t\t\t}\n\t\t\t\n\t\t\tthis.renderChildren = function(ctx) {\n\t\t\t\tvar customFont = this.parent.style('font-family').Definition.getDefinition();\n\t\t\t\tif (customFont != null) {\n\t\t\t\t\tvar fontSize = this.parent.style('font-size').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize);\n\t\t\t\t\tvar fontStyle = this.parent.style('font-style').valueOrDefault(svg.Font.Parse(svg.ctx.font).fontStyle);\n\t\t\t\t\tvar text = this.getText();\n\t\t\t\t\tif (customFont.isRTL) text = text.split(\"\").reverse().join(\"\");\n\t\t\t\t\t\n\t\t\t\t\tvar dx = svg.ToNumberArray(this.parent.attribute('dx').value);\n\t\t\t\t\tfor (var i=0; i<text.length; i++) {\n\t\t\t\t\t\tvar glyph = this.getGlyph(customFont, text, i);\n\t\t\t\t\t\tvar scale = fontSize / customFont.fontFace.unitsPerEm;\n\t\t\t\t\t\tctx.translate(this.x, this.y);\n\t\t\t\t\t\tctx.scale(scale, -scale);\n\t\t\t\t\t\tvar lw = ctx.lineWidth;\n\t\t\t\t\t\tctx.lineWidth = ctx.lineWidth * customFont.fontFace.unitsPerEm / fontSize;\n\t\t\t\t\t\tif (fontStyle == 'italic') ctx.transform(1, 0, .4, 1, 0, 0);\n\t\t\t\t\t\tglyph.render(ctx);\n\t\t\t\t\t\tif (fontStyle == 'italic') ctx.transform(1, 0, -.4, 1, 0, 0);\n\t\t\t\t\t\tctx.lineWidth = lw;\n\t\t\t\t\t\tctx.scale(1/scale, -1/scale);\n\t\t\t\t\t\tctx.translate(-this.x, -this.y);\t\n\t\t\t\t\t\t\n\t\t\t\t\t\tthis.x += fontSize * (glyph.horizAdvX || customFont.horizAdvX) / customFont.fontFace.unitsPerEm;\n\t\t\t\t\t\tif (typeof(dx[i]) != 'undefined' && !isNaN(dx[i])) {\n\t\t\t\t\t\t\tthis.x += dx[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t\n\t\t\t\tif (ctx.strokeStyle != '') ctx.strokeText(svg.compressSpaces(this.getText()), this.x, this.y);\n\t\t\t\tif (ctx.fillStyle != '') ctx.fillText(svg.compressSpaces(this.getText()), this.x, this.y);\n\t\t\t}\n\t\t\t\n\t\t\tthis.getText = function() {\n\t\t\t\t// OVERRIDE ME\n\t\t\t}\n\t\t\t\n\t\t\tthis.measureText = function(ctx) {\n\t\t\t\tvar customFont = this.parent.style('font-family').Definition.getDefinition();\n\t\t\t\tif (customFont != null) {\n\t\t\t\t\tvar fontSize = this.parent.style('font-size').numValueOrDefault(svg.Font.Parse(svg.ctx.font).fontSize);\n\t\t\t\t\tvar measure = 0;\n\t\t\t\t\tvar text = this.getText();\n\t\t\t\t\tif (customFont.isRTL) text = text.split(\"\").reverse().join(\"\");\n\t\t\t\t\tvar dx = svg.ToNumberArray(this.parent.attribute('dx').value);\n\t\t\t\t\tfor (var i=0; i<text.length; i++) {\n\t\t\t\t\t\tvar glyph = this.getGlyph(customFont, text, i);\n\t\t\t\t\t\tmeasure += (glyph.horizAdvX || customFont.horizAdvX) * fontSize / customFont.fontFace.unitsPerEm;\n\t\t\t\t\t\tif (typeof(dx[i]) != 'undefined' && !isNaN(dx[i])) {\n\t\t\t\t\t\t\tmeasure += dx[i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn measure;\n\t\t\t\t}\n\t\t\t\n\t\t\t\tvar textToMeasure = svg.compressSpaces(this.getText());\n\t\t\t\tif (!ctx.measureText) return textToMeasure.length * 10;\n\t\t\t\t\n\t\t\t\tctx.save();\n\t\t\t\tthis.setContext(ctx);\n\t\t\t\tvar width = ctx.measureText(textToMeasure).width;\n\t\t\t\tctx.restore();\n\t\t\t\treturn width;\n\t\t\t}\n\t\t}\n\t\tsvg.Element.TextElementBase.prototype = new svg.Element.RenderedElementBase;\n\t\t\n\t\t// tspan \n\t\tsvg.Element.tspan = function(node) {\n\t\t\tthis.base = svg.Element.TextElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.text = node.nodeType == 3 ? node.nodeValue : // text\n\t\t\t\t\t\tnode.childNodes.length > 0 ? node.childNodes[0].nodeValue : // element\n\t\t\t\t\t\tnode.text;\n\t\t\tthis.getText = function() {\n\t\t\t\treturn this.text;\n\t\t\t}\n\t\t}\n\t\tsvg.Element.tspan.prototype = new svg.Element.TextElementBase;\n\t\t\n\t\t// tref\n\t\tsvg.Element.tref = function(node) {\n\t\t\tthis.base = svg.Element.TextElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.getText = function() {\n\t\t\t\tvar element = this.attribute('xlink:href').Definition.getDefinition();\n\t\t\t\tif (element != null) return element.children[0].getText();\n\t\t\t}\n\t\t}\n\t\tsvg.Element.tref.prototype = new svg.Element.TextElementBase;\t\t\n\t\t\n\t\t// a element\n\t\tsvg.Element.a = function(node) {\n\t\t\tthis.base = svg.Element.TextElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.hasText = true;\n\t\t\tfor (var i=0; i<node.childNodes.length; i++) {\n\t\t\t\tif (node.childNodes[i].nodeType != 3) this.hasText = false;\n\t\t\t}\n\t\t\t\n\t\t\t// this might contain text\n\t\t\tthis.text = this.hasText ? node.childNodes[0].nodeValue : '';\n\t\t\tthis.getText = function() {\n\t\t\t\treturn this.text;\n\t\t\t}\t\t\n\n\t\t\tthis.baseRenderChildren = this.renderChildren;\n\t\t\tthis.renderChildren = function(ctx) {\n\t\t\t\tif (this.hasText) {\n\t\t\t\t\t// render as text element\n\t\t\t\t\tthis.baseRenderChildren(ctx);\n\t\t\t\t\tvar fontSize = new svg.Property('fontSize', svg.Font.Parse(svg.ctx.font).fontSize);\n\t\t\t\t\tsvg.Mouse.checkBoundingBox(this, new svg.BoundingBox(this.x, this.y - fontSize.Length.toPixels('y'), this.x + this.measureText(ctx), this.y));\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// render as temporary group\n\t\t\t\t\tvar g = new svg.Element.g();\n\t\t\t\t\tg.children = this.children;\n\t\t\t\t\tg.parent = this;\n\t\t\t\t\tg.render(ctx);\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tthis.onclick = function() {\n\t\t\t\twindow.open(this.attribute('xlink:href').value);\n\t\t\t}\n\t\t\t\n\t\t\tthis.onmousemove = function() {\n\t\t\t\tsvg.ctx.canvas.style.cursor = 'pointer';\n\t\t\t}\n\t\t}\n\t\tsvg.Element.a.prototype = new svg.Element.TextElementBase;\t\t\n\t\t\n\t\t// image element\n\t\tsvg.Element.image = function(node) {\n\t\t\tthis.base = svg.Element.RenderedElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tsvg.Images.push(this);\n\t\t\tthis.img = document.createElement('img');\n\t\t\tthis.loaded = false;\n\t\t\tvar that = this;\n\t\t\tthis.img.onload = function() { that.loaded = true; }\n\t\t\tthis.img.src = this.attribute('xlink:href').value;\n\t\t\t\n\t\t\tthis.renderChildren = function(ctx) {\n\t\t\t\tvar x = this.attribute('x').Length.toPixels('x');\n\t\t\t\tvar y = this.attribute('y').Length.toPixels('y');\n\t\t\t\t\n\t\t\t\tvar width = this.attribute('width').Length.toPixels('x');\n\t\t\t\tvar height = this.attribute('height').Length.toPixels('y');\t\t\t\n\t\t\t\tif (width == 0 || height == 0) return;\n\t\t\t\n\t\t\t\tctx.save();\n\t\t\t\tctx.translate(x, y);\n\t\t\t\tsvg.AspectRatio(ctx,\n\t\t\t\t\t\t\t\tthis.attribute('preserveAspectRatio').value,\n\t\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\t\tthis.img.width,\n\t\t\t\t\t\t\t\theight,\n\t\t\t\t\t\t\t\tthis.img.height,\n\t\t\t\t\t\t\t\t0,\n\t\t\t\t\t\t\t\t0);\t\n\t\t\t\tctx.drawImage(this.img, 0, 0);\t\t\t\n\t\t\t\tctx.restore();\n\t\t\t}\n\t\t}\n\t\tsvg.Element.image.prototype = new svg.Element.RenderedElementBase;\n\t\t\n\t\t// group element\n\t\tsvg.Element.g = function(node) {\n\t\t\tthis.base = svg.Element.RenderedElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.getBoundingBox = function() {\n\t\t\t\tvar bb = new svg.BoundingBox();\n\t\t\t\tfor (var i=0; i<this.children.length; i++) {\n\t\t\t\t\tbb.addBoundingBox(this.children[i].getBoundingBox());\n\t\t\t\t}\n\t\t\t\treturn bb;\n\t\t\t};\n\t\t}\n\t\tsvg.Element.g.prototype = new svg.Element.RenderedElementBase;\n\n\t\t// symbol element\n\t\tsvg.Element.symbol = function(node) {\n\t\t\tthis.base = svg.Element.RenderedElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.baseSetContext = this.setContext;\n\t\t\tthis.setContext = function(ctx) {\t\t\n\t\t\t\tthis.baseSetContext(ctx);\n\t\t\t\t\n\t\t\t\t// viewbox\n\t\t\t\tif (this.attribute('viewBox').hasValue()) {\t\t\t\t\n\t\t\t\t\tvar viewBox = svg.ToNumberArray(this.attribute('viewBox').value);\n\t\t\t\t\tvar minX = viewBox[0];\n\t\t\t\t\tvar minY = viewBox[1];\n\t\t\t\t\twidth = viewBox[2];\n\t\t\t\t\theight = viewBox[3];\n\t\t\t\t\t\n\t\t\t\t\tsvg.AspectRatio(ctx,\n\t\t\t\t\t\t\t\t\tthis.attribute('preserveAspectRatio').value, \n\t\t\t\t\t\t\t\t\tthis.attribute('width').Length.toPixels('x'),\n\t\t\t\t\t\t\t\t\twidth,\n\t\t\t\t\t\t\t\t\tthis.attribute('height').Length.toPixels('y'),\n\t\t\t\t\t\t\t\t\theight,\n\t\t\t\t\t\t\t\t\tminX,\n\t\t\t\t\t\t\t\t\tminY);\n\n\t\t\t\t\tsvg.ViewPort.SetCurrent(viewBox[2], viewBox[3]);\t\t\t\t\t\t\n\t\t\t\t}\n\t\t\t}\t\t\t\n\t\t}\n\t\tsvg.Element.symbol.prototype = new svg.Element.RenderedElementBase;\t\t\n\t\t\t\n\t\t// style element\n\t\tsvg.Element.style = function(node) { \n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\t// text, or spaces then CDATA\n\t\t\tvar css = node.childNodes[0].nodeValue + (node.childNodes.length > 1 ? node.childNodes[1].nodeValue : '');\n\t\t\tcss = css.replace(/(\\/\\*([^*]|[\\r\\n]|(\\*+([^*\\/]|[\\r\\n])))*\\*+\\/)|(^[\\s]*\\/\\/.*)/gm, ''); // remove comments\n\t\t\tcss = svg.compressSpaces(css); // replace whitespace\n\t\t\tvar cssDefs = css.split('}');\n\t\t\tfor (var i=0; i<cssDefs.length; i++) {\n\t\t\t\tif (svg.trim(cssDefs[i]) != '') {\n\t\t\t\t\tvar cssDef = cssDefs[i].split('{');\n\t\t\t\t\tvar cssClasses = cssDef[0].split(',');\n\t\t\t\t\tvar cssProps = cssDef[1].split(';');\n\t\t\t\t\tfor (var j=0; j<cssClasses.length; j++) {\n\t\t\t\t\t\tvar cssClass = svg.trim(cssClasses[j]);\n\t\t\t\t\t\tif (cssClass != '') {\n\t\t\t\t\t\t\tvar props = {};\n\t\t\t\t\t\t\tfor (var k=0; k<cssProps.length; k++) {\n\t\t\t\t\t\t\t\tvar prop = cssProps[k].indexOf(':');\n\t\t\t\t\t\t\t\tvar name = cssProps[k].substr(0, prop);\n\t\t\t\t\t\t\t\tvar value = cssProps[k].substr(prop + 1, cssProps[k].length - prop);\n\t\t\t\t\t\t\t\tif (name != null && value != null) {\n\t\t\t\t\t\t\t\t\tprops[svg.trim(name)] = new svg.Property(svg.trim(name), svg.trim(value));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tsvg.Styles[cssClass] = props;\n\t\t\t\t\t\t\tif (cssClass == '@font-face') {\n\t\t\t\t\t\t\t\tvar fontFamily = props['font-family'].value.replace(/\"/g,'');\n\t\t\t\t\t\t\t\tvar srcs = props['src'].value.split(',');\n\t\t\t\t\t\t\t\tfor (var s=0; s<srcs.length; s++) {\n\t\t\t\t\t\t\t\t\tif (srcs[s].indexOf('format(\"svg\")') > 0) {\n\t\t\t\t\t\t\t\t\t\tvar urlStart = srcs[s].indexOf('url');\n\t\t\t\t\t\t\t\t\t\tvar urlEnd = srcs[s].indexOf(')', urlStart);\n\t\t\t\t\t\t\t\t\t\tvar url = srcs[s].substr(urlStart + 5, urlEnd - urlStart - 6);\n\t\t\t\t\t\t\t\t\t\tvar doc = svg.parseXml(svg.ajax(url));\n\t\t\t\t\t\t\t\t\t\tvar fonts = doc.getElementsByTagName('font');\n\t\t\t\t\t\t\t\t\t\tfor (var f=0; f<fonts.length; f++) {\n\t\t\t\t\t\t\t\t\t\t\tvar font = svg.CreateElement(fonts[f]);\n\t\t\t\t\t\t\t\t\t\t\tsvg.Definitions[fontFamily] = font;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tsvg.Element.style.prototype = new svg.Element.ElementBase;\n\t\t\n\t\t// use element \n\t\tsvg.Element.use = function(node) {\n\t\t\tthis.base = svg.Element.RenderedElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.baseSetContext = this.setContext;\n\t\t\tthis.setContext = function(ctx) {\n\t\t\t\tthis.baseSetContext(ctx);\n\t\t\t\tif (this.attribute('x').hasValue()) ctx.translate(this.attribute('x').Length.toPixels('x'), 0);\n\t\t\t\tif (this.attribute('y').hasValue()) ctx.translate(0, this.attribute('y').Length.toPixels('y'));\n\t\t\t}\n\t\t\t\n\t\t\tthis.getDefinition = function() {\n\t\t\t\tvar element = this.attribute('xlink:href').Definition.getDefinition();\n\t\t\t\tif (this.attribute('width').hasValue()) element.attribute('width', true).value = this.attribute('width').value;\n\t\t\t\tif (this.attribute('height').hasValue()) element.attribute('height', true).value = this.attribute('height').value;\n\t\t\t\treturn element;\n\t\t\t}\n\t\t\t\n\t\t\tthis.path = function(ctx) {\n\t\t\t\tvar element = this.getDefinition();\n\t\t\t\tif (element != null) element.path(ctx);\n\t\t\t}\n\t\t\t\n\t\t\tthis.renderChildren = function(ctx) {\n\t\t\t\tvar element = this.getDefinition();\n\t\t\t\tif (element != null) element.render(ctx);\n\t\t\t}\n\t\t}\n\t\tsvg.Element.use.prototype = new svg.Element.RenderedElementBase;\n\t\t\n\t\t// mask element\n\t\tsvg.Element.mask = function(node) {\n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\n\t\t\t\t\t\t\n\t\t\tthis.apply = function(ctx, element) {\n\t\t\t\t// render as temp svg\t\n\t\t\t\tvar x = this.attribute('x').Length.toPixels('x');\n\t\t\t\tvar y = this.attribute('y').Length.toPixels('y');\n\t\t\t\tvar width = this.attribute('width').Length.toPixels('x');\n\t\t\t\tvar height = this.attribute('height').Length.toPixels('y');\n\t\t\t\t\n\t\t\t\t// temporarily remove mask to avoid recursion\n\t\t\t\tvar mask = element.attribute('mask').value;\n\t\t\t\telement.attribute('mask').value = '';\n\t\t\t\t\n\t\t\t\t\tvar cMask = document.createElement('canvas');\n\t\t\t\t\tcMask.width = x + width;\n\t\t\t\t\tcMask.height = y + height;\n\t\t\t\t\tvar maskCtx = cMask.getContext('2d');\n\t\t\t\t\tthis.renderChildren(maskCtx);\n\t\t\t\t\n\t\t\t\t\tvar c = document.createElement('canvas');\n\t\t\t\t\tc.width = x + width;\n\t\t\t\t\tc.height = y + height;\n\t\t\t\t\tvar tempCtx = c.getContext('2d');\n\t\t\t\t\telement.render(tempCtx);\n\t\t\t\t\ttempCtx.globalCompositeOperation = 'destination-in';\n\t\t\t\t\ttempCtx.fillStyle = maskCtx.createPattern(cMask, 'no-repeat');\n\t\t\t\t\ttempCtx.fillRect(0, 0, x + width, y + height);\n\t\t\t\t\t\n\t\t\t\t\tctx.fillStyle = tempCtx.createPattern(c, 'no-repeat');\n\t\t\t\t\tctx.fillRect(0, 0, x + width, y + height);\n\t\t\t\t\t\n\t\t\t\t// reassign mask\n\t\t\t\telement.attribute('mask').value = mask;\t\n\t\t\t}\n\t\t\t\n\t\t\tthis.render = function(ctx) {\n\t\t\t\t// NO RENDER\n\t\t\t}\n\t\t}\n\t\tsvg.Element.mask.prototype = new svg.Element.ElementBase;\n\t\t\n\t\t// clip element\n\t\tsvg.Element.clipPath = function(node) {\n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\n\t\t\t\n\t\t\tthis.apply = function(ctx) {\n\t\t\t\tfor (var i=0; i<this.children.length; i++) {\n\t\t\t\t\tif (this.children[i].path) {\n\t\t\t\t\t\tthis.children[i].path(ctx);\n\t\t\t\t\t\tctx.clip();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tthis.render = function(ctx) {\n\t\t\t\t// NO RENDER\n\t\t\t}\n\t\t}\n\t\tsvg.Element.clipPath.prototype = new svg.Element.ElementBase;\n\n\t\t// filters\n\t\tsvg.Element.filter = function(node) {\n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\n\t\t\t\t\t\t\n\t\t\tthis.apply = function(ctx, element) {\n\t\t\t\t// render as temp svg\t\n\t\t\t\tvar bb = element.getBoundingBox();\n\t\t\t\tvar x = this.attribute('x').Length.toPixels('x');\n\t\t\t\tvar y = this.attribute('y').Length.toPixels('y');\n\t\t\t\tif (x == 0 || y == 0) {\n\t\t\t\t\tx = bb.x1;\n\t\t\t\t\ty = bb.y1;\n\t\t\t\t}\n\t\t\t\tvar width = this.attribute('width').Length.toPixels('x');\n\t\t\t\tvar height = this.attribute('height').Length.toPixels('y');\n\t\t\t\tif (width == 0 || height == 0) {\n\t\t\t\t\twidth = bb.width();\n\t\t\t\t\theight = bb.height();\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// temporarily remove filter to avoid recursion\n\t\t\t\tvar filter = element.style('filter').value;\n\t\t\t\telement.style('filter').value = '';\n\t\t\t\t\n\t\t\t\t// max filter distance\n\t\t\t\tvar extraPercent = .20;\n\t\t\t\tvar px = extraPercent * width;\n\t\t\t\tvar py = extraPercent * height;\n\t\t\t\t\n\t\t\t\tvar c = document.createElement('canvas');\n\t\t\t\tc.width = width + 2*px;\n\t\t\t\tc.height = height + 2*py;\n\t\t\t\tvar tempCtx = c.getContext('2d');\n\t\t\t\ttempCtx.translate(-x + px, -y + py);\n\t\t\t\telement.render(tempCtx);\n\t\t\t\n\t\t\t\t// apply filters\n\t\t\t\tfor (var i=0; i<this.children.length; i++) {\n\t\t\t\t\tthis.children[i].apply(tempCtx, 0, 0, width + 2*px, height + 2*py);\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// render on me\n\t\t\t\tctx.drawImage(c, 0, 0, width + 2*px, height + 2*py, x - px, y - py, width + 2*px, height + 2*py);\n\t\t\t\t\n\t\t\t\t// reassign filter\n\t\t\t\telement.style('filter', true).value = filter;\t\n\t\t\t}\n\t\t\t\n\t\t\tthis.render = function(ctx) {\n\t\t\t\t// NO RENDER\n\t\t\t}\t\t\n\t\t}\n\t\tsvg.Element.filter.prototype = new svg.Element.ElementBase;\n\t\t\n\t\tsvg.Element.feGaussianBlur = function(node) {\n\t\t\tthis.base = svg.Element.ElementBase;\n\t\t\tthis.base(node);\t\n\t\t\t\n\t\t\tfunction make_fgauss(sigma) {\n\t\t\t\tsigma = Math.max(sigma, 0.01);\t\t\t      \n\t\t\t\tvar len = Math.ceil(sigma * 4.0) + 1;                     \n\t\t\t\tmask = [];                               \n\t\t\t\tfor (var i = 0; i < len; i++) {                             \n\t\t\t\t\tmask[i] = Math.exp(-0.5 * (i / sigma) * (i / sigma));                                           \n\t\t\t\t}                                                           \n\t\t\t\treturn mask; \n\t\t\t}\n\t\t\t\n\t\t\tfunction normalize(mask) {\n\t\t\t\tvar sum = 0;\n\t\t\t\tfor (var i = 1; i < mask.length; i++) {\n\t\t\t\t\tsum += Math.abs(mask[i]);\n\t\t\t\t}\n\t\t\t\tsum = 2 * sum + Math.abs(mask[0]);\n\t\t\t\tfor (var i = 0; i < mask.length; i++) {\n\t\t\t\t\tmask[i] /= sum;\n\t\t\t\t}\n\t\t\t\treturn mask;\n\t\t\t}\n\t\t\t\n\t\t\tfunction convolve_even(src, dst, mask, width, height) {\n\t\t\t  for (var y = 0; y < height; y++) {\n\t\t\t\tfor (var x = 0; x < width; x++) {\n\t\t\t\t  var a = imGet(src, x, y, width, height, 3)/255;\n\t\t\t\t  for (var rgba = 0; rgba < 4; rgba++) {\t\t\t\t\t  \n\t\t\t\t\t  var sum = mask[0] * (a==0?255:imGet(src, x, y, width, height, rgba)) * (a==0||rgba==3?1:a);\n\t\t\t\t\t  for (var i = 1; i < mask.length; i++) {\n\t\t\t\t\t\tvar a1 = imGet(src, Math.max(x-i,0), y, width, height, 3)/255;\n\t\t\t\t\t    var a2 = imGet(src, Math.min(x+i, width-1), y, width, height, 3)/255;\n\t\t\t\t\t\tsum += mask[i] * \n\t\t\t\t\t\t  ((a1==0?255:imGet(src, Math.max(x-i,0), y, width, height, rgba)) * (a1==0||rgba==3?1:a1) + \n\t\t\t\t\t\t   (a2==0?255:imGet(src, Math.min(x+i, width-1), y, width, height, rgba)) * (a2==0||rgba==3?1:a2));\n\t\t\t\t\t  }\n\t\t\t\t\t  imSet(dst, y, x, height, width, rgba, sum);\n\t\t\t\t  }\t\t\t  \n\t\t\t\t}\n\t\t\t  }\n\t\t\t}\t\t\n\n\t\t\tfunction imGet(img, x, y, width, height, rgba) {\n\t\t\t\treturn img[y*width*4 + x*4 + rgba];\n\t\t\t}\n\t\t\t\n\t\t\tfunction imSet(img, x, y, width, height, rgba, val) {\n\t\t\t\timg[y*width*4 + x*4 + rgba] = val;\n\t\t\t}\n\t\t\t\t\t\t\n\t\t\tfunction blur(ctx, width, height, sigma)\n\t\t\t{\n\t\t\t\tvar srcData = ctx.getImageData(0, 0, width, height);\n\t\t\t\tvar mask = make_fgauss(sigma);\n\t\t\t\tmask = normalize(mask);\n\t\t\t\ttmp = [];\n\t\t\t\tconvolve_even(srcData.data, tmp, mask, width, height);\n\t\t\t\tconvolve_even(tmp, srcData.data, mask, height, width);\n\t\t\t\tctx.clearRect(0, 0, width, height);\n\t\t\t\tctx.putImageData(srcData, 0, 0);\n\t\t\t}\t\t\t\n\t\t\n\t\t\tthis.apply = function(ctx, x, y, width, height) {\n\t\t\t\t// assuming x==0 && y==0 for now\n\t\t\t\tblur(ctx, width, height, this.attribute('stdDeviation').numValue());\n\t\t\t}\n\t\t}\n\t\tsvg.Element.filter.prototype = new svg.Element.feGaussianBlur;\n\t\t\n\t\t// title element, do nothing\n\t\tsvg.Element.title = function(node) {\n\t\t}\n\t\tsvg.Element.title.prototype = new svg.Element.ElementBase;\n\n\t\t// desc element, do nothing\n\t\tsvg.Element.desc = function(node) {\n\t\t}\n\t\tsvg.Element.desc.prototype = new svg.Element.ElementBase;\t\t\n\t\t\n\t\tsvg.Element.MISSING = function(node) {\n\t\t\tconsole.log('ERROR: Element \\'' + node.nodeName + '\\' not yet implemented.');\n\t\t}\n\t\tsvg.Element.MISSING.prototype = new svg.Element.ElementBase;\n\t\t\n\t\t// element factory\n\t\tsvg.CreateElement = function(node) {\t\n\t\t\tvar className = node.nodeName.replace(/^[^:]+:/,''); // remove namespace\n\t\t\tclassName = className.replace(/\\-/g,''); // remove dashes\n\t\t\tvar e = null;\n\t\t\tif (typeof(svg.Element[className]) != 'undefined') {\n\t\t\t\te = new svg.Element[className](node);\n\t\t\t}\n\t\t\telse {\n\t\t\t\te = new svg.Element.MISSING(node);\n\t\t\t}\n\n\t\t\te.type = node.nodeName;\n\t\t\treturn e;\n\t\t}\n\t\t\t\t\n\t\t// load from url\n\t\tsvg.load = function(ctx, url) {\n\t\t\tsvg.loadXml(ctx, svg.ajax(url));\n\t\t}\n\t\t\n\t\t// load from xml\n\t\tsvg.loadXml = function(ctx, xml) {\n\t\t\tsvg.loadXmlDoc(ctx, svg.parseXml(xml));\n\t\t}\n\t\t\n\t\tsvg.loadXmlDoc = function(ctx, dom) {\n\t\t\tsvg.init(ctx);\n\t\t\t\n\t\t\tvar mapXY = function(p) {\n\t\t\t\tvar e = ctx.canvas;\n\t\t\t\twhile (e) {\n\t\t\t\t\tp.x -= e.offsetLeft;\n\t\t\t\t\tp.y -= e.offsetTop;\n\t\t\t\t\te = e.offsetParent;\n\t\t\t\t}\n\t\t\t\tif (window.scrollX) p.x += window.scrollX;\n\t\t\t\tif (window.scrollY) p.y += window.scrollY;\n\t\t\t\treturn p;\n\t\t\t}\n\t\t\t\n\t\t\t// bind mouse\n\t\t\tif (svg.opts['ignoreMouse'] != true) {\n\t\t\t\tctx.canvas.onclick = function(e) {\n\t\t\t\t\tvar p = mapXY(new svg.Point(e != null ? e.clientX : event.clientX, e != null ? e.clientY : event.clientY));\n\t\t\t\t\tsvg.Mouse.onclick(p.x, p.y);\n\t\t\t\t};\n\t\t\t\tctx.canvas.onmousemove = function(e) {\n\t\t\t\t\tvar p = mapXY(new svg.Point(e != null ? e.clientX : event.clientX, e != null ? e.clientY : event.clientY));\n\t\t\t\t\tsvg.Mouse.onmousemove(p.x, p.y);\n\t\t\t\t};\n\t\t\t}\n\t\t\n\t\t\tvar e = svg.CreateElement(dom.documentElement);\n\t\t\te.root = true;\n\t\t\t\t\t\n\t\t\t// render loop\n\t\t\tvar isFirstRender = true;\n\t\t\tvar draw = function() {\n\t\t\t\tsvg.ViewPort.Clear();\n\t\t\t\tif (ctx.canvas.parentNode) svg.ViewPort.SetCurrent(ctx.canvas.parentNode.clientWidth, ctx.canvas.parentNode.clientHeight);\n\t\t\t\n\t\t\t\tif (svg.opts['ignoreDimensions'] != true) {\n\t\t\t\t\t// set canvas size\n\t\t\t\t\tif (e.style('width').hasValue()) {\n\t\t\t\t\t\tctx.canvas.width = e.style('width').Length.toPixels('x');\n\t\t\t\t\t\tctx.canvas.style.width = ctx.canvas.width + 'px';\n\t\t\t\t\t}\n\t\t\t\t\tif (e.style('height').hasValue()) {\n\t\t\t\t\t\tctx.canvas.height = e.style('height').Length.toPixels('y');\n\t\t\t\t\t\tctx.canvas.style.height = ctx.canvas.height + 'px';\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tvar cWidth = ctx.canvas.clientWidth || ctx.canvas.width;\n\t\t\t\tvar cHeight = ctx.canvas.clientHeight || ctx.canvas.height;\n\t\t\t\tsvg.ViewPort.SetCurrent(cWidth, cHeight);\t\t\n\t\t\t\t\n\t\t\t\tif (svg.opts != null && svg.opts['offsetX'] != null) e.attribute('x', true).value = svg.opts['offsetX'];\n\t\t\t\tif (svg.opts != null && svg.opts['offsetY'] != null) e.attribute('y', true).value = svg.opts['offsetY'];\n\t\t\t\tif (svg.opts != null && svg.opts['scaleWidth'] != null && svg.opts['scaleHeight'] != null) {\n\t\t\t\t\tvar xRatio = 1, yRatio = 1;\n\t\t\t\t\tif (e.attribute('width').hasValue()) xRatio = e.attribute('width').Length.toPixels('x') / svg.opts['scaleWidth'];\n\t\t\t\t\tif (e.attribute('height').hasValue()) yRatio = e.attribute('height').Length.toPixels('y') / svg.opts['scaleHeight'];\n\t\t\t\t\n\t\t\t\t\te.attribute('width', true).value = svg.opts['scaleWidth'];\n\t\t\t\t\te.attribute('height', true).value = svg.opts['scaleHeight'];\t\t\t\n\t\t\t\t\te.attribute('viewBox', true).value = '0 0 ' + (cWidth * xRatio) + ' ' + (cHeight * yRatio);\n\t\t\t\t\te.attribute('preserveAspectRatio', true).value = 'none';\n\t\t\t\t}\n\t\t\t\n\t\t\t\t// clear and render\n\t\t\t\tif (svg.opts['ignoreClear'] != true) {\n\t\t\t\t\tctx.clearRect(0, 0, cWidth, cHeight);\n\t\t\t\t}\n\t\t\t\te.render(ctx);\n\t\t\t\tif (isFirstRender) {\n\t\t\t\t\tisFirstRender = false;\n\t\t\t\t\tif (svg.opts != null && typeof(svg.opts['renderCallback']) == 'function') svg.opts['renderCallback']();\n\t\t\t\t}\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\tvar waitingForImages = true;\n\t\t\tif (svg.ImagesLoaded()) {\n\t\t\t\twaitingForImages = false;\n\t\t\t\tdraw();\n\t\t\t}\n\t\t\tsvg.intervalID = setInterval(function() { \n\t\t\t\tvar needUpdate = false;\n\t\t\t\t\n\t\t\t\tif (waitingForImages && svg.ImagesLoaded()) {\n\t\t\t\t\twaitingForImages = false;\n\t\t\t\t\tneedUpdate = true;\n\t\t\t\t}\n\t\t\t\n\t\t\t\t// need update from mouse events?\n\t\t\t\tif (svg.opts['ignoreMouse'] != true) {\n\t\t\t\t\tneedUpdate = needUpdate | svg.Mouse.hasEvents();\n\t\t\t\t}\n\t\t\t\n\t\t\t\t// need update from animations?\n\t\t\t\tif (svg.opts['ignoreAnimation'] != true) {\n\t\t\t\t\tfor (var i=0; i<svg.Animations.length; i++) {\n\t\t\t\t\t\tneedUpdate = needUpdate | svg.Animations[i].update(1000 / svg.FRAMERATE);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// need update from redraw?\n\t\t\t\tif (svg.opts != null && typeof(svg.opts['forceRedraw']) == 'function') {\n\t\t\t\t\tif (svg.opts['forceRedraw']() == true) needUpdate = true;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// render if needed\n\t\t\t\tif (needUpdate) {\n\t\t\t\t\tdraw();\t\t\t\t\n\t\t\t\t\tsvg.Mouse.runEvents(); // run and clear our events\n\t\t\t\t}\n\t\t\t}, 1000 / svg.FRAMERATE);\n\t\t}\n\t\t\n\t\tsvg.stop = function() {\n\t\t\tif (svg.intervalID) {\n\t\t\t\tclearInterval(svg.intervalID);\n\t\t\t}\n\t\t}\n\t\t\n\t\tsvg.Mouse = new (function() {\n\t\t\tthis.events = [];\n\t\t\tthis.hasEvents = function() { return this.events.length != 0; }\n\t\t\n\t\t\tthis.onclick = function(x, y) {\n\t\t\t\tthis.events.push({ type: 'onclick', x: x, y: y, \n\t\t\t\t\trun: function(e) { if (e.onclick) e.onclick(); }\n\t\t\t\t});\n\t\t\t}\n\t\t\t\n\t\t\tthis.onmousemove = function(x, y) {\n\t\t\t\tthis.events.push({ type: 'onmousemove', x: x, y: y,\n\t\t\t\t\trun: function(e) { if (e.onmousemove) e.onmousemove(); }\n\t\t\t\t});\n\t\t\t}\t\t\t\n\t\t\t\n\t\t\tthis.eventElements = [];\n\t\t\t\n\t\t\tthis.checkPath = function(element, ctx) {\n\t\t\t\tfor (var i=0; i<this.events.length; i++) {\n\t\t\t\t\tvar e = this.events[i];\n\t\t\t\t\tif (ctx.isPointInPath && ctx.isPointInPath(e.x, e.y)) this.eventElements[i] = element;\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\tthis.checkBoundingBox = function(element, bb) {\n\t\t\t\tfor (var i=0; i<this.events.length; i++) {\n\t\t\t\t\tvar e = this.events[i];\n\t\t\t\t\tif (bb.isPointInBox(e.x, e.y)) this.eventElements[i] = element;\n\t\t\t\t}\t\t\t\n\t\t\t}\n\t\t\t\n\t\t\tthis.runEvents = function() {\n\t\t\t\tsvg.ctx.canvas.style.cursor = '';\n\t\t\t\t\n\t\t\t\tfor (var i=0; i<this.events.length; i++) {\n\t\t\t\t\tvar e = this.events[i];\n\t\t\t\t\tvar element = this.eventElements[i];\n\t\t\t\t\twhile (element) {\n\t\t\t\t\t\te.run(element);\n\t\t\t\t\t\telement = element.parent;\n\t\t\t\t\t}\n\t\t\t\t}\t\t\n\t\t\t\n\t\t\t\t// done running, clear\n\t\t\t\tthis.events = []; \n\t\t\t\tthis.eventElements = [];\n\t\t\t}\n\t\t});\n\t\t\n\t\treturn svg;\n\t}\n})();\n\nif (CanvasRenderingContext2D) {\n\tCanvasRenderingContext2D.prototype.drawSvg = function(s, dx, dy, dw, dh) {\n\t\tcanvg(this.canvas, s, { \n\t\t\tignoreMouse: true, \n\t\t\tignoreAnimation: true, \n\t\t\tignoreDimensions: true, \n\t\t\tignoreClear: true, \n\t\t\toffsetX: dx, \n\t\t\toffsetY: dy, \n\t\t\tscaleWidth: dw, \n\t\t\tscaleHeight: dh\n\t\t});\n\t}\n}/**\n * @license Highcharts JS v3.0.6 (2013-10-04)\n * CanVGRenderer Extension module\n *\n * (c) 2011-2012 Torstein Hønsi, Erik Olsson\n *\n * License: www.highcharts.com/license\n */\n\n// JSLint options:\n/*global Highcharts */\n\n(function (Highcharts) { // encapsulate\n\tvar UNDEFINED,\n\t\tDIV = 'div',\n\t\tABSOLUTE = 'absolute',\n\t\tRELATIVE = 'relative',\n\t\tHIDDEN = 'hidden',\n\t\tVISIBLE = 'visible',\n\t\tPX = 'px',\n\t\tcss = Highcharts.css,\n\t\tCanVGRenderer = Highcharts.CanVGRenderer,\n\t\tSVGRenderer = Highcharts.SVGRenderer,\n\t\textend = Highcharts.extend,\n\t\tmerge = Highcharts.merge,\n\t\taddEvent = Highcharts.addEvent,\n\t\tcreateElement = Highcharts.createElement,\n\t\tdiscardElement = Highcharts.discardElement;\n\n\t// Extend CanVG renderer on demand, inherit from SVGRenderer\n\textend(CanVGRenderer.prototype, SVGRenderer.prototype);\n\n\t// Add additional functionality:\n\textend(CanVGRenderer.prototype, {\n\t\tcreate: function (chart, container, chartWidth, chartHeight) {\n\t\t\tthis.setContainer(container, chartWidth, chartHeight);\n\t\t\tthis.configure(chart);\n\t\t},\n\t\tsetContainer: function (container, chartWidth, chartHeight) {\n\t\t\tvar containerStyle = container.style,\n\t\t\t\tcontainerParent = container.parentNode,\n\t\t\t\tcontainerLeft = containerStyle.left,\n\t\t\t\tcontainerTop = containerStyle.top,\n\t\t\t\tcontainerOffsetWidth = container.offsetWidth,\n\t\t\t\tcontainerOffsetHeight = container.offsetHeight,\n\t\t\t\tcanvas,\n\t\t\t\tinitialHiddenStyle = { visibility: HIDDEN, position: ABSOLUTE };\n\n\t\t\tthis.init.apply(this, [container, chartWidth, chartHeight]);\n\n\t\t\t// add the canvas above it\n\t\t\tcanvas = createElement('canvas', {\n\t\t\t\twidth: containerOffsetWidth,\n\t\t\t\theight: containerOffsetHeight\n\t\t\t}, {\n\t\t\t\tposition: RELATIVE,\n\t\t\t\tleft: containerLeft,\n\t\t\t\ttop: containerTop\n\t\t\t}, container);\n\t\t\tthis.canvas = canvas;\n\n\t\t\t// Create the tooltip line and div, they are placed as siblings to\n\t\t\t// the container (and as direct childs to the div specified in the html page)\n\t\t\tthis.ttLine = createElement(DIV, null, initialHiddenStyle, containerParent);\n\t\t\tthis.ttDiv = createElement(DIV, null, initialHiddenStyle, containerParent);\n\t\t\tthis.ttTimer = UNDEFINED;\n\n\t\t\t// Move away the svg node to a new div inside the container's parent so we can hide it.\n\t\t\tvar hiddenSvg = createElement(DIV, {\n\t\t\t\twidth: containerOffsetWidth,\n\t\t\t\theight: containerOffsetHeight\n\t\t\t}, {\n\t\t\t\tvisibility: HIDDEN,\n\t\t\t\tleft: containerLeft,\n\t\t\t\ttop: containerTop\n\t\t\t}, containerParent);\n\t\t\tthis.hiddenSvg = hiddenSvg;\n\t\t\thiddenSvg.appendChild(this.box);\n\t\t},\n\n\t\t/**\n\t\t * Configures the renderer with the chart. Attach a listener to the event tooltipRefresh.\n\t\t **/\n\t\tconfigure: function (chart) {\n\t\t\tvar renderer = this,\n\t\t\t\toptions = chart.options.tooltip,\n\t\t\t\tborderWidth = options.borderWidth,\n\t\t\t\ttooltipDiv = renderer.ttDiv,\n\t\t\t\ttooltipDivStyle = options.style,\n\t\t\t\ttooltipLine = renderer.ttLine,\n\t\t\t\tpadding = parseInt(tooltipDivStyle.padding, 10);\n\n\t\t\t// Add border styling from options to the style\n\t\t\ttooltipDivStyle = merge(tooltipDivStyle, {\n\t\t\t\tpadding: padding + PX,\n\t\t\t\t'background-color': options.backgroundColor,\n\t\t\t\t'border-style': 'solid',\n\t\t\t\t'border-width': borderWidth + PX,\n\t\t\t\t'border-radius': options.borderRadius + PX\n\t\t\t});\n\n\t\t\t// Optionally add shadow\n\t\t\tif (options.shadow) {\n\t\t\t\ttooltipDivStyle = merge(tooltipDivStyle, {\n\t\t\t\t\t'box-shadow': '1px 1px 3px gray', // w3c\n\t\t\t\t\t'-webkit-box-shadow': '1px 1px 3px gray' // webkit\n\t\t\t\t});\n\t\t\t}\n\t\t\tcss(tooltipDiv, tooltipDivStyle);\n\n\t\t\t// Set simple style on the line\n\t\t\tcss(tooltipLine, {\n\t\t\t\t'border-left': '1px solid darkgray'\n\t\t\t});\n\n\t\t\t// This event is triggered when a new tooltip should be shown\n\t\t\taddEvent(chart, 'tooltipRefresh', function (args) {\n\t\t\t\tvar chartContainer = chart.container,\n\t\t\t\t\toffsetLeft = chartContainer.offsetLeft,\n\t\t\t\t\toffsetTop = chartContainer.offsetTop,\n\t\t\t\t\tposition;\n\n\t\t\t\t// Set the content of the tooltip\n\t\t\t\ttooltipDiv.innerHTML = args.text;\n\n\t\t\t\t// Compute the best position for the tooltip based on the divs size and container size.\n\t\t\t\tposition = chart.tooltip.getPosition(tooltipDiv.offsetWidth, tooltipDiv.offsetHeight, {plotX: args.x, plotY: args.y});\n\n\t\t\t\tcss(tooltipDiv, {\n\t\t\t\t\tvisibility: VISIBLE,\n\t\t\t\t\tleft: position.x + PX,\n\t\t\t\t\ttop: position.y + PX,\n\t\t\t\t\t'border-color': args.borderColor\n\t\t\t\t});\n\n\t\t\t\t// Position the tooltip line\n\t\t\t\tcss(tooltipLine, {\n\t\t\t\t\tvisibility: VISIBLE,\n\t\t\t\t\tleft: offsetLeft + args.x + PX,\n\t\t\t\t\ttop: offsetTop + chart.plotTop + PX,\n\t\t\t\t\theight: chart.plotHeight  + PX\n\t\t\t\t});\n\n\t\t\t\t// This timeout hides the tooltip after 3 seconds\n\t\t\t\t// First clear any existing timer\n\t\t\t\tif (renderer.ttTimer !== UNDEFINED) {\n\t\t\t\t\tclearTimeout(renderer.ttTimer);\n\t\t\t\t}\n\n\t\t\t\t// Start a new timer that hides tooltip and line\n\t\t\t\trenderer.ttTimer = setTimeout(function () {\n\t\t\t\t\tcss(tooltipDiv, { visibility: HIDDEN });\n\t\t\t\t\tcss(tooltipLine, { visibility: HIDDEN });\n\t\t\t\t}, 3000);\n\t\t\t});\n\t\t},\n\n\t\t/**\n\t\t * Extend SVGRenderer.destroy to also destroy the elements added by CanVGRenderer.\n\t\t */\n\t\tdestroy: function () {\n\t\t\tvar renderer = this;\n\n\t\t\t// Remove the canvas\n\t\t\tdiscardElement(renderer.canvas);\n\n\t\t\t// Kill the timer\n\t\t\tif (renderer.ttTimer !== UNDEFINED) {\n\t\t\t\tclearTimeout(renderer.ttTimer);\n\t\t\t}\n\n\t\t\t// Remove the divs for tooltip and line\n\t\t\tdiscardElement(renderer.ttLine);\n\t\t\tdiscardElement(renderer.ttDiv);\n\t\t\tdiscardElement(renderer.hiddenSvg);\n\n\t\t\t// Continue with base class\n\t\t\treturn SVGRenderer.prototype.destroy.apply(renderer);\n\t\t},\n\n\t\t/**\n\t\t * Take a color and return it if it's a string, do not make it a gradient even if it is a\n\t\t * gradient. Currently canvg cannot render gradients (turns out black),\n\t\t * see: http://code.google.com/p/canvg/issues/detail?id=104\n\t\t *\n\t\t * @param {Object} color The color or config object\n\t\t */\n\t\tcolor: function (color, elem, prop) {\n\t\t\tif (color && color.linearGradient) {\n\t\t\t\t// Pick the end color and forward to base implementation\n\t\t\t\tcolor = color.stops[color.stops.length - 1][1];\n\t\t\t}\n\t\t\treturn SVGRenderer.prototype.color.call(this, color, elem, prop);\n\t\t},\n\n\t\t/**\n\t\t * Draws the SVG on the canvas or adds a draw invokation to the deferred list.\n\t\t */\n\t\tdraw: function () {\n\t\t\tvar renderer = this;\n\t\t\twindow.canvg(renderer.canvas, renderer.hiddenSvg.innerHTML);\n\t\t}\n\t});\n}(Highcharts));\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/data.js",
    "content": "/*\n Data plugin for Highcharts\n\n (c) 2012-2013 Torstein Hønsi\n Last revision 2013-06-07\n\n License: www.highcharts.com/license\n*/\n(function(h){var k=h.each,m=function(b,a){this.init(b,a)};h.extend(m.prototype,{init:function(b,a){this.options=b;this.chartOptions=a;this.columns=b.columns||this.rowsToColumns(b.rows)||[];this.columns.length?this.dataFound():(this.parseCSV(),this.parseTable(),this.parseGoogleSpreadsheet())},getColumnDistribution:function(){var b=this.chartOptions,a=b&&b.chart&&b.chart.type,c=[];k(b&&b.series||[],function(b){c.push((h.seriesTypes[b.type||a||\"line\"].prototype.pointArrayMap||[0]).length)});this.valueCount=\n{global:(h.seriesTypes[a||\"line\"].prototype.pointArrayMap||[0]).length,individual:c}},dataFound:function(){this.parseTypes();this.findHeaderRow();this.parsed();this.complete()},parseCSV:function(){var b=this,a=this.options,c=a.csv,d=this.columns,f=a.startRow||0,i=a.endRow||Number.MAX_VALUE,j=a.startColumn||0,e=a.endColumn||Number.MAX_VALUE,g=0;c&&(c=c.replace(/\\r\\n/g,\"\\n\").replace(/\\r/g,\"\\n\").split(a.lineDelimiter||\"\\n\"),k(c,function(c,h){var n=b.trim(c),p=n.indexOf(\"#\")===0;h>=f&&h<=i&&!p&&n!==\"\"&&\n(n=c.split(a.itemDelimiter||\",\"),k(n,function(b,a){a>=j&&a<=e&&(d[a-j]||(d[a-j]=[]),d[a-j][g]=b)}),g+=1)}),this.dataFound())},parseTable:function(){var b=this.options,a=b.table,c=this.columns,d=b.startRow||0,f=b.endRow||Number.MAX_VALUE,i=b.startColumn||0,j=b.endColumn||Number.MAX_VALUE,e;a&&(typeof a===\"string\"&&(a=document.getElementById(a)),k(a.getElementsByTagName(\"tr\"),function(a,b){e=0;b>=d&&b<=f&&k(a.childNodes,function(a){if((a.tagName===\"TD\"||a.tagName===\"TH\")&&e>=i&&e<=j)c[e]||(c[e]=[]),\nc[e][b-d]=a.innerHTML,e+=1})}),this.dataFound())},parseGoogleSpreadsheet:function(){var b=this,a=this.options,c=a.googleSpreadsheetKey,d=this.columns,f=a.startRow||0,i=a.endRow||Number.MAX_VALUE,j=a.startColumn||0,e=a.endColumn||Number.MAX_VALUE,g,h;c&&jQuery.getJSON(\"https://spreadsheets.google.com/feeds/cells/\"+c+\"/\"+(a.googleSpreadsheetWorksheet||\"od6\")+\"/public/values?alt=json-in-script&callback=?\",function(a){var a=a.feed.entry,c,k=a.length,m=0,o=0,l;for(l=0;l<k;l++)c=a[l],m=Math.max(m,c.gs$cell.col),\no=Math.max(o,c.gs$cell.row);for(l=0;l<m;l++)if(l>=j&&l<=e)d[l-j]=[],d[l-j].length=Math.min(o,i-f);for(l=0;l<k;l++)if(c=a[l],g=c.gs$cell.row-1,h=c.gs$cell.col-1,h>=j&&h<=e&&g>=f&&g<=i)d[h-j][g-f]=c.content.$t;b.dataFound()})},findHeaderRow:function(){k(this.columns,function(){});this.headerRow=0},trim:function(b){return typeof b===\"string\"?b.replace(/^\\s+|\\s+$/g,\"\"):b},parseTypes:function(){for(var b=this.columns,a=b.length,c,d,f,i;a--;)for(c=b[a].length;c--;)d=b[a][c],f=parseFloat(d),i=this.trim(d),\ni==f?(b[a][c]=f,f>31536E6?b[a].isDatetime=!0:b[a].isNumeric=!0):(d=this.parseDate(d),a===0&&typeof d===\"number\"&&!isNaN(d)?(b[a][c]=d,b[a].isDatetime=!0):b[a][c]=i===\"\"?null:i)},dateFormats:{\"YYYY-mm-dd\":{regex:\"^([0-9]{4})-([0-9]{2})-([0-9]{2})$\",parser:function(b){return Date.UTC(+b[1],b[2]-1,+b[3])}}},parseDate:function(b){var a=this.options.parseDate,c,d,f;a&&(c=a(b));if(typeof b===\"string\")for(d in this.dateFormats)a=this.dateFormats[d],(f=b.match(a.regex))&&(c=a.parser(f));return c},rowsToColumns:function(b){var a,\nc,d,f,i;if(b){i=[];c=b.length;for(a=0;a<c;a++){f=b[a].length;for(d=0;d<f;d++)i[d]||(i[d]=[]),i[d][a]=b[a][d]}}return i},parsed:function(){this.options.parsed&&this.options.parsed.call(this,this.columns)},complete:function(){var b=this.columns,a,c,d=this.options,f,i,j,e,g,k;if(d.complete){this.getColumnDistribution();b.length>1&&(a=b.shift(),this.headerRow===0&&a.shift(),a.isDatetime?c=\"datetime\":a.isNumeric||(c=\"category\"));for(e=0;e<b.length;e++)if(this.headerRow===0)b[e].name=b[e].shift();i=[];\nfor(e=0,k=0;e<b.length;k++){f=h.pick(this.valueCount.individual[k],this.valueCount.global);j=[];for(g=0;g<b[e].length;g++)j[g]=[a[g],b[e][g]!==void 0?b[e][g]:null],f>1&&j[g].push(b[e+1][g]!==void 0?b[e+1][g]:null),f>2&&j[g].push(b[e+2][g]!==void 0?b[e+2][g]:null),f>3&&j[g].push(b[e+3][g]!==void 0?b[e+3][g]:null),f>4&&j[g].push(b[e+4][g]!==void 0?b[e+4][g]:null);i[k]={name:b[e].name,data:j};e+=f}d.complete({xAxis:{type:c},series:i})}}});h.Data=m;h.data=function(b,a){return new m(b,a)};h.wrap(h.Chart.prototype,\n\"init\",function(b,a,c){var d=this;a&&a.data?h.data(h.extend(a.data,{complete:function(f){a.series&&k(a.series,function(b,c){a.series[c]=h.merge(b,f.series[c])});a=h.merge(f,a);b.call(d,a,c)}}),a):b.call(d,a,c)})})(Highcharts);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/data.src.js",
    "content": "/**\n * @license Data plugin for Highcharts\n *\n * (c) 2012-2013 Torstein Hønsi\n * Last revision 2013-06-07\n *\n * License: www.highcharts.com/license\n */\n\n/*\n * The Highcharts Data plugin is a utility to ease parsing of input sources like\n * CSV, HTML tables or grid views into basic configuration options for use \n * directly in the Highcharts constructor.\n *\n * Demo: http://jsfiddle.net/highcharts/SnLFj/\n *\n * --- OPTIONS ---\n *\n * - columns : Array<Array<Mixed>>\n * A two-dimensional array representing the input data on tabular form. This input can\n * be used when the data is already parsed, for example from a grid view component.\n * Each cell can be a string or number. If not switchRowsAndColumns is set, the columns\n * are interpreted as series. See also the rows option.\n *\n * - complete : Function(chartOptions)\n * The callback that is evaluated when the data is finished loading, optionally from an \n * external source, and parsed. The first argument passed is a finished chart options\n * object, containing series and an xAxis with categories if applicable. Thise options\n * can be extended with additional options and passed directly to the chart constructor.\n *\n * - csv : String\n * A comma delimited string to be parsed. Related options are startRow, endRow, startColumn\n * and endColumn to delimit what part of the table is used. The lineDelimiter and \n * itemDelimiter options define the CSV delimiter formats.\n * \n * - endColumn : Integer\n * In tabular input data, the first row (indexed by 0) to use. Defaults to the last \n * column containing data.\n *\n * - endRow : Integer\n * In tabular input data, the last row (indexed by 0) to use. Defaults to the last row\n * containing data.\n *\n * - googleSpreadsheetKey : String \n * A Google Spreadsheet key. See https://developers.google.com/gdata/samples/spreadsheet_sample\n * for general information on GS.\n *\n * - googleSpreadsheetWorksheet : String \n * The Google Spreadsheet worksheet. The available id's can be read from \n * https://spreadsheets.google.com/feeds/worksheets/{key}/public/basic\n *\n * - itemDelimiter : String\n * Item or cell delimiter for parsing CSV. Defaults to \",\".\n *\n * - lineDelimiter : String\n * Line delimiter for parsing CSV. Defaults to \"\\n\".\n *\n * - parsed : Function\n * A callback function to access the parsed columns, the two-dimentional input data\n * array directly, before they are interpreted into series data and categories.\n *\n * - parseDate : Function\n * A callback function to parse string representations of dates into JavaScript timestamps.\n * Return an integer on success.\n *\n * - rows : Array<Array<Mixed>>\n * The same as the columns input option, but defining rows intead of columns.\n *\n * - startColumn : Integer\n * In tabular input data, the first column (indexed by 0) to use. \n *\n * - startRow : Integer\n * In tabular input data, the first row (indexed by 0) to use.\n *\n * - table : String|HTMLElement\n * A HTML table or the id of such to be parsed as input data. Related options ara startRow,\n * endRow, startColumn and endColumn to delimit what part of the table is used.\n */\n\n// JSLint options:\n/*global jQuery */\n\n(function (Highcharts) {\t\n\t\n\t// Utilities\n\tvar each = Highcharts.each;\n\t\n\t\n\t// The Data constructor\n\tvar Data = function (dataOptions, chartOptions) {\n\t\tthis.init(dataOptions, chartOptions);\n\t};\n\t\n\t// Set the prototype properties\n\tHighcharts.extend(Data.prototype, {\n\t\t\n\t/**\n\t * Initialize the Data object with the given options\n\t */\n\tinit: function (options, chartOptions) {\n\t\tthis.options = options;\n\t\tthis.chartOptions = chartOptions;\n\t\tthis.columns = options.columns || this.rowsToColumns(options.rows) || [];\n\n\t\t// No need to parse or interpret anything\n\t\tif (this.columns.length) {\n\t\t\tthis.dataFound();\n\n\t\t// Parse and interpret\n\t\t} else {\n\n\t\t\t// Parse a CSV string if options.csv is given\n\t\t\tthis.parseCSV();\n\t\t\t\n\t\t\t// Parse a HTML table if options.table is given\n\t\t\tthis.parseTable();\n\n\t\t\t// Parse a Google Spreadsheet \n\t\t\tthis.parseGoogleSpreadsheet();\t\n\t\t}\n\n\t},\n\n\t/**\n\t * Get the column distribution. For example, a line series takes a single column for \n\t * Y values. A range series takes two columns for low and high values respectively,\n\t * and an OHLC series takes four columns.\n\t */\n\tgetColumnDistribution: function () {\n\t\tvar chartOptions = this.chartOptions,\n\t\t\tgetValueCount = function (type) {\n\t\t\t\treturn (Highcharts.seriesTypes[type || 'line'].prototype.pointArrayMap || [0]).length;\n\t\t\t},\n\t\t\tglobalType = chartOptions && chartOptions.chart && chartOptions.chart.type,\n\t\t\tindividualCounts = [];\n\n\t\teach((chartOptions && chartOptions.series) || [], function (series) {\n\t\t\tindividualCounts.push(getValueCount(series.type || globalType));\n\t\t});\n\n\t\tthis.valueCount = {\n\t\t\tglobal: getValueCount(globalType),\n\t\t\tindividual: individualCounts\n\t\t};\n\t},\n\n\n\tdataFound: function () {\n\t\t// Interpret the values into right types\n\t\tthis.parseTypes();\n\t\t\n\t\t// Use first row for series names?\n\t\tthis.findHeaderRow();\n\t\t\n\t\t// Handle columns if a handleColumns callback is given\n\t\tthis.parsed();\n\t\t\n\t\t// Complete if a complete callback is given\n\t\tthis.complete();\n\t\t\n\t},\n\t\n\t/**\n\t * Parse a CSV input string\n\t */\n\tparseCSV: function () {\n\t\tvar self = this,\n\t\t\toptions = this.options,\n\t\t\tcsv = options.csv,\n\t\t\tcolumns = this.columns,\n\t\t\tstartRow = options.startRow || 0,\n\t\t\tendRow = options.endRow || Number.MAX_VALUE,\n\t\t\tstartColumn = options.startColumn || 0,\n\t\t\tendColumn = options.endColumn || Number.MAX_VALUE,\n\t\t\tlines,\n\t\t\tactiveRowNo = 0;\n\t\t\t\n\t\tif (csv) {\n\t\t\t\n\t\t\tlines = csv\n\t\t\t\t.replace(/\\r\\n/g, \"\\n\") // Unix\n\t\t\t\t.replace(/\\r/g, \"\\n\") // Mac\n\t\t\t\t.split(options.lineDelimiter || \"\\n\");\n\t\t\t\n\t\t\teach(lines, function (line, rowNo) {\n\t\t\t\tvar trimmed = self.trim(line),\n\t\t\t\t\tisComment = trimmed.indexOf('#') === 0,\n\t\t\t\t\tisBlank = trimmed === '',\n\t\t\t\t\titems;\n\t\t\t\t\n\t\t\t\tif (rowNo >= startRow && rowNo <= endRow && !isComment && !isBlank) {\n\t\t\t\t\titems = line.split(options.itemDelimiter || ',');\n\t\t\t\t\teach(items, function (item, colNo) {\n\t\t\t\t\t\tif (colNo >= startColumn && colNo <= endColumn) {\n\t\t\t\t\t\t\tif (!columns[colNo - startColumn]) {\n\t\t\t\t\t\t\t\tcolumns[colNo - startColumn] = [];\t\t\t\t\t\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tcolumns[colNo - startColumn][activeRowNo] = item;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tactiveRowNo += 1;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.dataFound();\n\t\t}\n\t},\n\t\n\t/**\n\t * Parse a HTML table\n\t */\n\tparseTable: function () {\n\t\tvar options = this.options,\n\t\t\ttable = options.table,\n\t\t\tcolumns = this.columns,\n\t\t\tstartRow = options.startRow || 0,\n\t\t\tendRow = options.endRow || Number.MAX_VALUE,\n\t\t\tstartColumn = options.startColumn || 0,\n\t\t\tendColumn = options.endColumn || Number.MAX_VALUE,\n\t\t\tcolNo;\n\t\t\t\n\t\tif (table) {\n\t\t\t\n\t\t\tif (typeof table === 'string') {\n\t\t\t\ttable = document.getElementById(table);\n\t\t\t}\n\t\t\t\n\t\t\teach(table.getElementsByTagName('tr'), function (tr, rowNo) {\n\t\t\t\tcolNo = 0; \n\t\t\t\tif (rowNo >= startRow && rowNo <= endRow) {\n\t\t\t\t\teach(tr.childNodes, function (item) {\n\t\t\t\t\t\tif ((item.tagName === 'TD' || item.tagName === 'TH') && colNo >= startColumn && colNo <= endColumn) {\n\t\t\t\t\t\t\tif (!columns[colNo]) {\n\t\t\t\t\t\t\t\tcolumns[colNo] = [];\t\t\t\t\t\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tcolumns[colNo][rowNo - startRow] = item.innerHTML;\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\tcolNo += 1;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tthis.dataFound(); // continue\n\t\t}\n\t},\n\n\t/**\n\t * TODO: \n\t * - switchRowsAndColumns\n\t */\n\tparseGoogleSpreadsheet: function () {\n\t\tvar self = this,\n\t\t\toptions = this.options,\n\t\t\tgoogleSpreadsheetKey = options.googleSpreadsheetKey,\n\t\t\tcolumns = this.columns,\n\t\t\tstartRow = options.startRow || 0,\n\t\t\tendRow = options.endRow || Number.MAX_VALUE,\n\t\t\tstartColumn = options.startColumn || 0,\n\t\t\tendColumn = options.endColumn || Number.MAX_VALUE,\n\t\t\tgr, // google row\n\t\t\tgc; // google column\n\n\t\tif (googleSpreadsheetKey) {\n\t\t\tjQuery.getJSON('https://spreadsheets.google.com/feeds/cells/' + \n\t\t\t\t  googleSpreadsheetKey + '/' + (options.googleSpreadsheetWorksheet || 'od6') +\n\t\t\t\t\t  '/public/values?alt=json-in-script&callback=?',\n\t\t\t\t\t  function (json) {\n\t\t\t\t\t\n\t\t\t\t// Prepare the data from the spreadsheat\n\t\t\t\tvar cells = json.feed.entry,\n\t\t\t\t\tcell,\n\t\t\t\t\tcellCount = cells.length,\n\t\t\t\t\tcolCount = 0,\n\t\t\t\t\trowCount = 0,\n\t\t\t\t\ti;\n\t\t\t\n\t\t\t\t// First, find the total number of columns and rows that \n\t\t\t\t// are actually filled with data\n\t\t\t\tfor (i = 0; i < cellCount; i++) {\n\t\t\t\t\tcell = cells[i];\n\t\t\t\t\tcolCount = Math.max(colCount, cell.gs$cell.col);\n\t\t\t\t\trowCount = Math.max(rowCount, cell.gs$cell.row);\t\t\t\n\t\t\t\t}\n\t\t\t\n\t\t\t\t// Set up arrays containing the column data\n\t\t\t\tfor (i = 0; i < colCount; i++) {\n\t\t\t\t\tif (i >= startColumn && i <= endColumn) {\n\t\t\t\t\t\t// Create new columns with the length of either end-start or rowCount\n\t\t\t\t\t\tcolumns[i - startColumn] = [];\n\n\t\t\t\t\t\t// Setting the length to avoid jslint warning\n\t\t\t\t\t\tcolumns[i - startColumn].length = Math.min(rowCount, endRow - startRow);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t// Loop over the cells and assign the value to the right\n\t\t\t\t// place in the column arrays\n\t\t\t\tfor (i = 0; i < cellCount; i++) {\n\t\t\t\t\tcell = cells[i];\n\t\t\t\t\tgr = cell.gs$cell.row - 1; // rows start at 1\n\t\t\t\t\tgc = cell.gs$cell.col - 1; // columns start at 1\n\n\t\t\t\t\t// If both row and col falls inside start and end\n\t\t\t\t\t// set the transposed cell value in the newly created columns\n\t\t\t\t\tif (gc >= startColumn && gc <= endColumn &&\n\t\t\t\t\t\tgr >= startRow && gr <= endRow) {\n\t\t\t\t\t\tcolumns[gc - startColumn][gr - startRow] = cell.content.$t;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tself.dataFound();\n\t\t\t});\n\t\t}\n\t},\n\t\n\t/**\n\t * Find the header row. For now, we just check whether the first row contains\n\t * numbers or strings. Later we could loop down and find the first row with \n\t * numbers.\n\t */\n\tfindHeaderRow: function () {\n\t\tvar headerRow = 0;\n\t\teach(this.columns, function (column) {\n\t\t\tif (typeof column[0] !== 'string') {\n\t\t\t\theaderRow = null;\n\t\t\t}\n\t\t});\n\t\tthis.headerRow = 0;\t\t\t\n\t},\n\t\n\t/**\n\t * Trim a string from whitespace\n\t */\n\ttrim: function (str) {\n\t\treturn typeof str === 'string' ? str.replace(/^\\s+|\\s+$/g, '') : str;\n\t},\n\t\n\t/**\n\t * Parse numeric cells in to number types and date types in to true dates.\n\t * @param {Object} columns\n\t */\n\tparseTypes: function () {\n\t\tvar columns = this.columns,\n\t\t\tcol = columns.length, \n\t\t\trow,\n\t\t\tval,\n\t\t\tfloatVal,\n\t\t\ttrimVal,\n\t\t\tdateVal;\n\t\t\t\n\t\twhile (col--) {\n\t\t\trow = columns[col].length;\n\t\t\twhile (row--) {\n\t\t\t\tval = columns[col][row];\n\t\t\t\tfloatVal = parseFloat(val);\n\t\t\t\ttrimVal = this.trim(val);\n\n\t\t\t\t/*jslint eqeq: true*/\n\t\t\t\tif (trimVal == floatVal) { // is numeric\n\t\t\t\t/*jslint eqeq: false*/\n\t\t\t\t\tcolumns[col][row] = floatVal;\n\t\t\t\t\t\n\t\t\t\t\t// If the number is greater than milliseconds in a year, assume datetime\n\t\t\t\t\tif (floatVal > 365 * 24 * 3600 * 1000) {\n\t\t\t\t\t\tcolumns[col].isDatetime = true;\n\t\t\t\t\t} else {\n\t\t\t\t\t\tcolumns[col].isNumeric = true;\n\t\t\t\t\t}\t\t\t\t\t\n\t\t\t\t\n\t\t\t\t} else { // string, continue to determine if it is a date string or really a string\n\t\t\t\t\tdateVal = this.parseDate(val);\n\t\t\t\t\t\n\t\t\t\t\tif (col === 0 && typeof dateVal === 'number' && !isNaN(dateVal)) { // is date\n\t\t\t\t\t\tcolumns[col][row] = dateVal;\n\t\t\t\t\t\tcolumns[col].isDatetime = true;\n\t\t\t\t\t\n\t\t\t\t\t} else { // string\n\t\t\t\t\t\tcolumns[col][row] = trimVal === '' ? null : trimVal;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t\n\t\t\t}\n\t\t}\n\t},\n\t//*\n\tdateFormats: {\n\t\t'YYYY-mm-dd': {\n\t\t\tregex: '^([0-9]{4})-([0-9]{2})-([0-9]{2})$',\n\t\t\tparser: function (match) {\n\t\t\t\treturn Date.UTC(+match[1], match[2] - 1, +match[3]);\n\t\t\t}\n\t\t}\n\t},\n\t// */\n\t/**\n\t * Parse a date and return it as a number. Overridable through options.parseDate.\n\t */\n\tparseDate: function (val) {\n\t\tvar parseDate = this.options.parseDate,\n\t\t\tret,\n\t\t\tkey,\n\t\t\tformat,\n\t\t\tmatch;\n\n\t\tif (parseDate) {\n\t\t\tret = parseDate(val);\n\t\t}\n\t\t\t\n\t\tif (typeof val === 'string') {\n\t\t\tfor (key in this.dateFormats) {\n\t\t\t\tformat = this.dateFormats[key];\n\t\t\t\tmatch = val.match(format.regex);\n\t\t\t\tif (match) {\n\t\t\t\t\tret = format.parser(match);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn ret;\n\t},\n\t\n\t/**\n\t * Reorganize rows into columns\n\t */\n\trowsToColumns: function (rows) {\n\t\tvar row,\n\t\t\trowsLength,\n\t\t\tcol,\n\t\t\tcolsLength,\n\t\t\tcolumns;\n\n\t\tif (rows) {\n\t\t\tcolumns = [];\n\t\t\trowsLength = rows.length;\n\t\t\tfor (row = 0; row < rowsLength; row++) {\n\t\t\t\tcolsLength = rows[row].length;\n\t\t\t\tfor (col = 0; col < colsLength; col++) {\n\t\t\t\t\tif (!columns[col]) {\n\t\t\t\t\t\tcolumns[col] = [];\n\t\t\t\t\t}\n\t\t\t\t\tcolumns[col][row] = rows[row][col];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn columns;\n\t},\n\t\n\t/**\n\t * A hook for working directly on the parsed columns\n\t */\n\tparsed: function () {\n\t\tif (this.options.parsed) {\n\t\t\tthis.options.parsed.call(this, this.columns);\n\t\t}\n\t},\n\t\n\t/**\n\t * If a complete callback function is provided in the options, interpret the \n\t * columns into a Highcharts options object.\n\t */\n\tcomplete: function () {\n\t\t\n\t\tvar columns = this.columns,\n\t\t\tfirstCol,\n\t\t\ttype,\n\t\t\toptions = this.options,\n\t\t\tvalueCount,\n\t\t\tseries,\n\t\t\tdata,\n\t\t\ti,\n\t\t\tj,\n\t\t\tseriesIndex;\n\t\t\t\n\t\t\n\t\tif (options.complete) {\n\n\t\t\tthis.getColumnDistribution();\n\t\t\t\n\t\t\t// Use first column for X data or categories?\n\t\t\tif (columns.length > 1) {\n\t\t\t\tfirstCol = columns.shift();\n\t\t\t\tif (this.headerRow === 0) {\n\t\t\t\t\tfirstCol.shift(); // remove the first cell\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t\n\t\t\t\tif (firstCol.isDatetime) {\n\t\t\t\t\ttype = 'datetime';\n\t\t\t\t} else if (!firstCol.isNumeric) {\n\t\t\t\t\ttype = 'category';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Get the names and shift the top row\n\t\t\tfor (i = 0; i < columns.length; i++) {\n\t\t\t\tif (this.headerRow === 0) {\n\t\t\t\t\tcolumns[i].name = columns[i].shift();\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// Use the next columns for series\n\t\t\tseries = [];\n\t\t\tfor (i = 0, seriesIndex = 0; i < columns.length; seriesIndex++) {\n\n\t\t\t\t// This series' value count\n\t\t\t\tvalueCount = Highcharts.pick(this.valueCount.individual[seriesIndex], this.valueCount.global);\n\t\t\t\t\n\t\t\t\t// Iterate down the cells of each column and add data to the series\n\t\t\t\tdata = [];\n\t\t\t\tfor (j = 0; j < columns[i].length; j++) {\n\t\t\t\t\tdata[j] = [\n\t\t\t\t\t\tfirstCol[j], \n\t\t\t\t\t\tcolumns[i][j] !== undefined ? columns[i][j] : null\n\t\t\t\t\t];\n\t\t\t\t\tif (valueCount > 1) {\n\t\t\t\t\t\tdata[j].push(columns[i + 1][j] !== undefined ? columns[i + 1][j] : null);\n\t\t\t\t\t}\n\t\t\t\t\tif (valueCount > 2) {\n\t\t\t\t\t\tdata[j].push(columns[i + 2][j] !== undefined ? columns[i + 2][j] : null);\n\t\t\t\t\t}\n\t\t\t\t\tif (valueCount > 3) {\n\t\t\t\t\t\tdata[j].push(columns[i + 3][j] !== undefined ? columns[i + 3][j] : null);\n\t\t\t\t\t}\n\t\t\t\t\tif (valueCount > 4) {\n\t\t\t\t\t\tdata[j].push(columns[i + 4][j] !== undefined ? columns[i + 4][j] : null);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Add the series\n\t\t\t\tseries[seriesIndex] = {\n\t\t\t\t\tname: columns[i].name,\n\t\t\t\t\tdata: data\n\t\t\t\t};\n\n\t\t\t\ti += valueCount;\n\t\t\t}\n\t\t\t\n\t\t\t// Do the callback\n\t\t\toptions.complete({\n\t\t\t\txAxis: {\n\t\t\t\t\ttype: type\n\t\t\t\t},\n\t\t\t\tseries: series\n\t\t\t});\n\t\t}\n\t}\n\t});\n\t\n\t// Register the Data prototype and data function on Highcharts\n\tHighcharts.Data = Data;\n\tHighcharts.data = function (options, chartOptions) {\n\t\treturn new Data(options, chartOptions);\n\t};\n\n\t// Extend Chart.init so that the Chart constructor accepts a new configuration\n\t// option group, data.\n\tHighcharts.wrap(Highcharts.Chart.prototype, 'init', function (proceed, userOptions, callback) {\n\t\tvar chart = this;\n\n\t\tif (userOptions && userOptions.data) {\n\t\t\tHighcharts.data(Highcharts.extend(userOptions.data, {\n\t\t\t\tcomplete: function (dataOptions) {\n\t\t\t\t\t\n\t\t\t\t\t// Merge series configs\n\t\t\t\t\tif (userOptions.series) {\n\t\t\t\t\t\teach(userOptions.series, function (series, i) {\n\t\t\t\t\t\t\tuserOptions.series[i] = Highcharts.merge(series, dataOptions.series[i]);\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t// Do the merge\n\t\t\t\t\tuserOptions = Highcharts.merge(dataOptions, userOptions);\n\n\t\t\t\t\tproceed.call(chart, userOptions, callback);\n\t\t\t\t}\n\t\t\t}), userOptions);\n\t\t} else {\n\t\t\tproceed.call(chart, userOptions, callback);\n\t\t}\n\t});\n\n}(Highcharts));\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/drilldown.js",
    "content": "(function(e){function q(b,a,c){return\"rgba(\"+[Math.round(b[0]+(a[0]-b[0])*c),Math.round(b[1]+(a[1]-b[1])*c),Math.round(b[2]+(a[2]-b[2])*c),b[3]+(a[3]-b[3])*c].join(\",\")+\")\"}var m=function(){},j=e.getOptions(),g=e.each,n=e.extend,o=e.wrap,h=e.Chart,i=e.seriesTypes,k=i.pie,l=i.column,r=HighchartsAdapter.fireEvent;n(j.lang,{drillUpText:\"◁ Back to {series.name}\"});j.drilldown={activeAxisLabelStyle:{cursor:\"pointer\",color:\"#039\",fontWeight:\"bold\",textDecoration:\"underline\"},activeDataLabelStyle:{cursor:\"pointer\",\ncolor:\"#039\",fontWeight:\"bold\",textDecoration:\"underline\"},animation:{duration:500},drillUpButton:{position:{align:\"right\",x:-10,y:10}}};e.SVGRenderer.prototype.Element.prototype.fadeIn=function(){this.attr({opacity:0.1,visibility:\"visible\"}).animate({opacity:1},{duration:250})};h.prototype.drilldownLevels=[];h.prototype.addSeriesAsDrilldown=function(b,a){var c=b.series,d=c.xAxis,f=c.yAxis,e;e=b.color||c.color;var g,a=n({color:e},a);g=HighchartsAdapter.inArray(this,c.points);this.drilldownLevels.push({seriesOptions:c.userOptions,\nshapeArgs:b.shapeArgs,bBox:b.graphic.getBBox(),color:e,newSeries:a,pointOptions:c.options.data[g],pointIndex:g,oldExtremes:{xMin:d&&d.userMin,xMax:d&&d.userMax,yMin:f&&f.userMin,yMax:f&&f.userMax}});e=this.addSeries(a,!1);if(d)d.oldPos=d.pos,d.userMin=d.userMax=null,f.userMin=f.userMax=null;if(c.type===e.type)e.animate=e.animateDrilldown||m,e.options.animation=!0;c.remove(!1);this.redraw();this.showDrillUpButton()};h.prototype.getDrilldownBackText=function(){return this.options.lang.drillUpText.replace(\"{series.name}\",\nthis.drilldownLevels[this.drilldownLevels.length-1].seriesOptions.name)};h.prototype.showDrillUpButton=function(){var b=this,a=this.getDrilldownBackText(),c=b.options.drilldown.drillUpButton;this.drillUpButton?this.drillUpButton.attr({text:a}).align():this.drillUpButton=this.renderer.button(a,null,null,function(){b.drillUp()}).attr(n({align:c.position.align,zIndex:9},c.theme)).add().align(c.position,!1,c.relativeTo||\"plotBox\")};h.prototype.drillUp=function(){var b=this.drilldownLevels.pop(),a=this.series[0],\nc=b.oldExtremes,d=this.addSeries(b.seriesOptions,!1);r(this,\"drillup\",{seriesOptions:b.seriesOptions});if(d.type===a.type)d.drilldownLevel=b,d.animate=d.animateDrillupTo||m,d.options.animation=!0,a.animateDrillupFrom&&a.animateDrillupFrom(b);a.remove(!1);d.xAxis&&(d.xAxis.setExtremes(c.xMin,c.xMax,!1),d.yAxis.setExtremes(c.yMin,c.yMax,!1));this.redraw();this.drilldownLevels.length===0?this.drillUpButton=this.drillUpButton.destroy():this.drillUpButton.attr({text:this.getDrilldownBackText()}).align()};\nk.prototype.animateDrilldown=function(b){var a=this.chart.drilldownLevels[this.chart.drilldownLevels.length-1],c=this.chart.options.drilldown.animation,d=a.shapeArgs,f=d.start,s=(d.end-f)/this.points.length,h=e.Color(a.color).rgba;b||g(this.points,function(a,b){var g=e.Color(a.color).rgba;a.graphic.attr(e.merge(d,{start:f+b*s,end:f+(b+1)*s})).animate(a.shapeArgs,e.merge(c,{step:function(a,d){d.prop===\"start\"&&this.attr({fill:q(h,g,d.pos)})}}))})};k.prototype.animateDrillupTo=l.prototype.animateDrillupTo=\nfunction(b){if(!b){var a=this,c=a.drilldownLevel;g(this.points,function(a){a.graphic.hide();a.dataLabel&&a.dataLabel.hide();a.connector&&a.connector.hide()});setTimeout(function(){g(a.points,function(a,b){var e=b===c.pointIndex?\"show\":\"fadeIn\";a.graphic[e]();if(a.dataLabel)a.dataLabel[e]();if(a.connector)a.connector[e]()})},Math.max(this.chart.options.drilldown.animation.duration-50,0));this.animate=m}};l.prototype.animateDrilldown=function(b){var a=this.chart.drilldownLevels[this.chart.drilldownLevels.length-\n1].shapeArgs,c=this.chart.options.drilldown.animation;b||(a.x+=this.xAxis.oldPos-this.xAxis.pos,g(this.points,function(b){b.graphic.attr(a).animate(b.shapeArgs,c)}))};l.prototype.animateDrillupFrom=k.prototype.animateDrillupFrom=function(b){var a=this.chart.options.drilldown.animation,c=this.group;delete this.group;g(this.points,function(d){var f=d.graphic,g=e.Color(d.color).rgba;delete d.graphic;f.animate(b.shapeArgs,e.merge(a,{step:function(a,c){c.prop===\"start\"&&this.attr({fill:q(g,e.Color(b.color).rgba,\nc.pos)})},complete:function(){f.destroy();c&&(c=c.destroy())}}))})};e.Point.prototype.doDrilldown=function(){for(var b=this.series.chart,a=b.options.drilldown,c=a.series.length,d;c--&&!d;)a.series[c].id===this.drilldown&&(d=a.series[c]);r(b,\"drilldown\",{point:this,seriesOptions:d});d&&b.addSeriesAsDrilldown(this,d)};o(e.Point.prototype,\"init\",function(b,a,c,d){var f=b.call(this,a,c,d),b=a.chart,a=(a=a.xAxis&&a.xAxis.ticks[d])&&a.label;if(f.drilldown){if(e.addEvent(f,\"click\",function(){f.doDrilldown()}),\na){if(!a._basicStyle)a._basicStyle=a.element.getAttribute(\"style\");a.addClass(\"highcharts-drilldown-axis-label\").css(b.options.drilldown.activeAxisLabelStyle).on(\"click\",function(){f.doDrilldown&&f.doDrilldown()})}}else a&&a._basicStyle&&a.element.setAttribute(\"style\",a._basicStyle);return f});o(e.Series.prototype,\"drawDataLabels\",function(b){var a=this.chart.options.drilldown.activeDataLabelStyle;b.call(this);g(this.points,function(b){if(b.drilldown&&b.dataLabel)b.dataLabel.attr({\"class\":\"highcharts-drilldown-data-label\"}).css(a).on(\"click\",\nfunction(){b.doDrilldown()})})});l.prototype.supportsDrilldown=!0;k.prototype.supportsDrilldown=!0;var p,j=function(b){b.call(this);g(this.points,function(a){a.drilldown&&a.graphic&&a.graphic.attr({\"class\":\"highcharts-drilldown-point\"}).css({cursor:\"pointer\"})})};for(p in i)i[p].prototype.supportsDrilldown&&o(i[p].prototype,\"drawTracker\",j)})(Highcharts);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/drilldown.src.js",
    "content": "/**\n * Highcharts Drilldown plugin\n * \n * Author: Torstein Honsi\n * Last revision: 2013-02-18\n * License: MIT License\n *\n * Demo: http://jsfiddle.net/highcharts/Vf3yT/\n */\n\n/*global HighchartsAdapter*/\n(function (H) {\n\n\t\"use strict\";\n\n\tvar noop = function () {},\n\t\tdefaultOptions = H.getOptions(),\n\t\teach = H.each,\n\t\textend = H.extend,\n\t\twrap = H.wrap,\n\t\tChart = H.Chart,\n\t\tseriesTypes = H.seriesTypes,\n\t\tPieSeries = seriesTypes.pie,\n\t\tColumnSeries = seriesTypes.column,\n\t\tfireEvent = HighchartsAdapter.fireEvent;\n\n\t// Utilities\n\tfunction tweenColors(startColor, endColor, pos) {\n\t\tvar rgba = [\n\t\t\t\tMath.round(startColor[0] + (endColor[0] - startColor[0]) * pos),\n\t\t\t\tMath.round(startColor[1] + (endColor[1] - startColor[1]) * pos),\n\t\t\t\tMath.round(startColor[2] + (endColor[2] - startColor[2]) * pos),\n\t\t\t\tstartColor[3] + (endColor[3] - startColor[3]) * pos\n\t\t\t];\n\t\treturn 'rgba(' + rgba.join(',') + ')';\n\t}\n\n\t// Add language\n\textend(defaultOptions.lang, {\n\t\tdrillUpText: '◁ Back to {series.name}'\n\t});\n\tdefaultOptions.drilldown = {\n\t\tactiveAxisLabelStyle: {\n\t\t\tcursor: 'pointer',\n\t\t\tcolor: '#039',\n\t\t\tfontWeight: 'bold',\n\t\t\ttextDecoration: 'underline'\t\t\t\n\t\t},\n\t\tactiveDataLabelStyle: {\n\t\t\tcursor: 'pointer',\n\t\t\tcolor: '#039',\n\t\t\tfontWeight: 'bold',\n\t\t\ttextDecoration: 'underline'\t\t\t\n\t\t},\n\t\tanimation: {\n\t\t\tduration: 500\n\t\t},\n\t\tdrillUpButton: {\n\t\t\tposition: { \n\t\t\t\talign: 'right',\n\t\t\t\tx: -10,\n\t\t\t\ty: 10\n\t\t\t}\n\t\t\t// relativeTo: 'plotBox'\n\t\t\t// theme\n\t\t}\n\t};\t\n\n\t/**\n\t * A general fadeIn method\n\t */\n\tH.SVGRenderer.prototype.Element.prototype.fadeIn = function () {\n\t\tthis\n\t\t.attr({\n\t\t\topacity: 0.1,\n\t\t\tvisibility: 'visible'\n\t\t})\n\t\t.animate({\n\t\t\topacity: 1\n\t\t}, {\n\t\t\tduration: 250\n\t\t});\n\t};\n\n\t// Extend the Chart prototype\n\tChart.prototype.drilldownLevels = [];\n\n\tChart.prototype.addSeriesAsDrilldown = function (point, ddOptions) {\n\t\tvar oldSeries = point.series,\n\t\t\txAxis = oldSeries.xAxis,\n\t\t\tyAxis = oldSeries.yAxis,\n\t\t\tnewSeries,\n\t\t\tcolor = point.color || oldSeries.color,\n\t\t\tpointIndex,\n\t\t\tlevel;\n\t\t\t\n\t\tddOptions = extend({\n\t\t\tcolor: color\n\t\t}, ddOptions);\n\t\tpointIndex = HighchartsAdapter.inArray(this, oldSeries.points);\n\t\tlevel = {\n\t\t\tseriesOptions: oldSeries.userOptions,\n\t\t\tshapeArgs: point.shapeArgs,\n\t\t\tbBox: point.graphic.getBBox(),\n\t\t\tcolor: color,\n\t\t\tnewSeries: ddOptions,\n\t\t\tpointOptions: oldSeries.options.data[pointIndex],\n\t\t\tpointIndex: pointIndex,\n\t\t\toldExtremes: {\n\t\t\t\txMin: xAxis && xAxis.userMin,\n\t\t\t\txMax: xAxis && xAxis.userMax,\n\t\t\t\tyMin: yAxis && yAxis.userMin,\n\t\t\t\tyMax: yAxis && yAxis.userMax\n\t\t\t}\n\t\t};\n\n\t\tthis.drilldownLevels.push(level);\n\n\t\tnewSeries = this.addSeries(ddOptions, false);\n\t\tif (xAxis) {\n\t\t\txAxis.oldPos = xAxis.pos;\n\t\t\txAxis.userMin = xAxis.userMax = null;\n\t\t\tyAxis.userMin = yAxis.userMax = null;\n\t\t}\n\n\t\t// Run fancy cross-animation on supported and equal types\n\t\tif (oldSeries.type === newSeries.type) {\n\t\t\tnewSeries.animate = newSeries.animateDrilldown || noop;\n\t\t\tnewSeries.options.animation = true;\n\t\t}\n\t\t\n\t\toldSeries.remove(false);\n\t\t\n\t\tthis.redraw();\n\t\tthis.showDrillUpButton();\n\t};\n\n\tChart.prototype.getDrilldownBackText = function () {\n\t\tvar lastLevel = this.drilldownLevels[this.drilldownLevels.length - 1];\n\n\t\treturn this.options.lang.drillUpText.replace('{series.name}', lastLevel.seriesOptions.name);\n\n\t};\n\n\tChart.prototype.showDrillUpButton = function () {\n\t\tvar chart = this,\n\t\t\tbackText = this.getDrilldownBackText(),\n\t\t\tbuttonOptions = chart.options.drilldown.drillUpButton;\n\t\t\t\n\n\t\tif (!this.drillUpButton) {\n\t\t\tthis.drillUpButton = this.renderer.button(\n\t\t\t\tbackText,\n\t\t\t\tnull,\n\t\t\t\tnull,\n\t\t\t\tfunction () {\n\t\t\t\t\tchart.drillUp(); \n\t\t\t\t}\n\t\t\t)\n\t\t\t.attr(extend({\n\t\t\t\talign: buttonOptions.position.align,\n\t\t\t\tzIndex: 9\n\t\t\t}, buttonOptions.theme))\n\t\t\t.add()\n\t\t\t.align(buttonOptions.position, false, buttonOptions.relativeTo || 'plotBox');\n\t\t} else {\n\t\t\tthis.drillUpButton.attr({\n\t\t\t\ttext: backText\n\t\t\t})\n\t\t\t.align();\n\t\t}\n\t};\n\n\tChart.prototype.drillUp = function () {\n\t\tvar chart = this,\n\t\t\tlevel = chart.drilldownLevels.pop(),\n\t\t\toldSeries = chart.series[0],\n\t\t\toldExtremes = level.oldExtremes,\n\t\t\tnewSeries = chart.addSeries(level.seriesOptions, false);\n\t\t\n\t\tfireEvent(chart, 'drillup', { seriesOptions: level.seriesOptions });\n\n\t\tif (newSeries.type === oldSeries.type) {\n\t\t\tnewSeries.drilldownLevel = level;\n\t\t\tnewSeries.animate = newSeries.animateDrillupTo || noop;\n\t\t\tnewSeries.options.animation = true;\n\n\t\t\tif (oldSeries.animateDrillupFrom) {\n\t\t\t\toldSeries.animateDrillupFrom(level);\n\t\t\t}\n\t\t}\n\n\t\toldSeries.remove(false);\n\n\t\t// Reset the zoom level of the upper series\n\t\tif (newSeries.xAxis) {\n\t\t\tnewSeries.xAxis.setExtremes(oldExtremes.xMin, oldExtremes.xMax, false);\n\t\t\tnewSeries.yAxis.setExtremes(oldExtremes.yMin, oldExtremes.yMax, false);\n\t\t}\n\n\n\t\tthis.redraw();\n\n\t\tif (this.drilldownLevels.length === 0) {\n\t\t\tthis.drillUpButton = this.drillUpButton.destroy();\n\t\t} else {\n\t\t\tthis.drillUpButton.attr({\n\t\t\t\ttext: this.getDrilldownBackText()\n\t\t\t})\n\t\t\t.align();\n\t\t}\n\t};\n\n\tPieSeries.prototype.animateDrilldown = function (init) {\n\t\tvar level = this.chart.drilldownLevels[this.chart.drilldownLevels.length - 1],\n\t\t\tanimationOptions = this.chart.options.drilldown.animation,\n\t\t\tanimateFrom = level.shapeArgs,\n\t\t\tstart = animateFrom.start,\n\t\t\tangle = animateFrom.end - start,\n\t\t\tstartAngle = angle / this.points.length,\n\t\t\tstartColor = H.Color(level.color).rgba;\n\n\t\tif (!init) {\n\t\t\teach(this.points, function (point, i) {\n\t\t\t\tvar endColor = H.Color(point.color).rgba;\n\n\t\t\t\t/*jslint unparam: true*/\n\t\t\t\tpoint.graphic\n\t\t\t\t\t.attr(H.merge(animateFrom, {\n\t\t\t\t\t\tstart: start + i * startAngle,\n\t\t\t\t\t\tend: start + (i + 1) * startAngle\n\t\t\t\t\t}))\n\t\t\t\t\t.animate(point.shapeArgs, H.merge(animationOptions, {\n\t\t\t\t\t\tstep: function (val, fx) {\n\t\t\t\t\t\t\tif (fx.prop === 'start') {\n\t\t\t\t\t\t\t\tthis.attr({\n\t\t\t\t\t\t\t\t\tfill: tweenColors(startColor, endColor, fx.pos)\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}));\n\t\t\t\t/*jslint unparam: false*/\n\t\t\t});\n\t\t}\n\t};\n\n\n\t/**\n\t * When drilling up, keep the upper series invisible until the lower series has\n\t * moved into place\n\t */\n\tPieSeries.prototype.animateDrillupTo = \n\t\t\tColumnSeries.prototype.animateDrillupTo = function (init) {\n\t\tif (!init) {\n\t\t\tvar newSeries = this,\n\t\t\t\tlevel = newSeries.drilldownLevel;\n\n\t\t\teach(this.points, function (point) {\n\t\t\t\tpoint.graphic.hide();\n\t\t\t\tif (point.dataLabel) {\n\t\t\t\t\tpoint.dataLabel.hide();\n\t\t\t\t}\n\t\t\t\tif (point.connector) {\n\t\t\t\t\tpoint.connector.hide();\n\t\t\t\t}\n\t\t\t});\n\n\n\t\t\t// Do dummy animation on first point to get to complete\n\t\t\tsetTimeout(function () {\n\t\t\t\teach(newSeries.points, function (point, i) {  \n\t\t\t\t\t// Fade in other points\t\t\t  \n\t\t\t\t\tvar verb = i === level.pointIndex ? 'show' : 'fadeIn';\n\t\t\t\t\tpoint.graphic[verb]();\n\t\t\t\t\tif (point.dataLabel) {\n\t\t\t\t\t\tpoint.dataLabel[verb]();\n\t\t\t\t\t}\n\t\t\t\t\tif (point.connector) {\n\t\t\t\t\t\tpoint.connector[verb]();\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}, Math.max(this.chart.options.drilldown.animation.duration - 50, 0));\n\n\t\t\t// Reset\n\t\t\tthis.animate = noop;\n\t\t}\n\n\t};\n\t\n\tColumnSeries.prototype.animateDrilldown = function (init) {\n\t\tvar animateFrom = this.chart.drilldownLevels[this.chart.drilldownLevels.length - 1].shapeArgs,\n\t\t\tanimationOptions = this.chart.options.drilldown.animation;\n\t\t\t\n\t\tif (!init) {\n\n\t\t\tanimateFrom.x += (this.xAxis.oldPos - this.xAxis.pos);\n\t\n\t\t\teach(this.points, function (point) {\n\t\t\t\tpoint.graphic\n\t\t\t\t\t.attr(animateFrom)\n\t\t\t\t\t.animate(point.shapeArgs, animationOptions);\n\t\t\t});\n\t\t}\n\t\t\n\t};\n\n\t/**\n\t * When drilling up, pull out the individual point graphics from the lower series\n\t * and animate them into the origin point in the upper series.\n\t */\n\tColumnSeries.prototype.animateDrillupFrom = \n\t\tPieSeries.prototype.animateDrillupFrom =\n\tfunction (level) {\n\t\tvar animationOptions = this.chart.options.drilldown.animation,\n\t\t\tgroup = this.group;\n\n\t\tdelete this.group;\n\t\teach(this.points, function (point) {\n\t\t\tvar graphic = point.graphic,\n\t\t\t\tstartColor = H.Color(point.color).rgba;\n\n\t\t\tdelete point.graphic;\n\n\t\t\t/*jslint unparam: true*/\n\t\t\tgraphic.animate(level.shapeArgs, H.merge(animationOptions, {\n\n\t\t\t\tstep: function (val, fx) {\n\t\t\t\t\tif (fx.prop === 'start') {\n\t\t\t\t\t\tthis.attr({\n\t\t\t\t\t\t\tfill: tweenColors(startColor, H.Color(level.color).rgba, fx.pos)\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tcomplete: function () {\n\t\t\t\t\tgraphic.destroy();\n\t\t\t\t\tif (group) {\n\t\t\t\t\t\tgroup = group.destroy();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}));\n\t\t\t/*jslint unparam: false*/\n\t\t});\n\t};\n\t\n\tH.Point.prototype.doDrilldown = function () {\n\t\tvar series = this.series,\n\t\t\tchart = series.chart,\n\t\t\tdrilldown = chart.options.drilldown,\n\t\t\ti = drilldown.series.length,\n\t\t\tseriesOptions;\n\t\t\n\t\twhile (i-- && !seriesOptions) {\n\t\t\tif (drilldown.series[i].id === this.drilldown) {\n\t\t\t\tseriesOptions = drilldown.series[i];\n\t\t\t}\n\t\t}\n\n\t\t// Fire the event. If seriesOptions is undefined, the implementer can check for \n\t\t// seriesOptions, and call addSeriesAsDrilldown async if necessary.\n\t\tfireEvent(chart, 'drilldown', { \n\t\t\tpoint: this,\n\t\t\tseriesOptions: seriesOptions\n\t\t});\n\t\t\n\t\tif (seriesOptions) {\n\t\t\tchart.addSeriesAsDrilldown(this, seriesOptions);\n\t\t}\n\n\t};\n\t\n\twrap(H.Point.prototype, 'init', function (proceed, series, options, x) {\n\t\tvar point = proceed.call(this, series, options, x),\n\t\t\tchart = series.chart,\n\t\t\ttick = series.xAxis && series.xAxis.ticks[x],\n\t\t\ttickLabel = tick && tick.label;\n\t\t\n\t\tif (point.drilldown) {\n\t\t\t\n\t\t\t// Add the click event to the point label\n\t\t\tH.addEvent(point, 'click', function () {\n\t\t\t\tpoint.doDrilldown();\n\t\t\t});\n\t\t\t\n\t\t\t// Make axis labels clickable\n\t\t\tif (tickLabel) {\n\t\t\t\tif (!tickLabel._basicStyle) {\n\t\t\t\t\ttickLabel._basicStyle = tickLabel.element.getAttribute('style');\n\t\t\t\t}\n\t\t\t\ttickLabel\n\t\t\t\t\t.addClass('highcharts-drilldown-axis-label')\n\t\t\t\t\t.css(chart.options.drilldown.activeAxisLabelStyle)\n\t\t\t\t\t.on('click', function () {\n\t\t\t\t\t\tif (point.doDrilldown) {\n\t\t\t\t\t\t\tpoint.doDrilldown();\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\t\n\t\t\t}\n\t\t} else if (tickLabel && tickLabel._basicStyle) {\n\t\t\ttickLabel.element.setAttribute('style', tickLabel._basicStyle);\n\t\t}\n\t\t\n\t\treturn point;\n\t});\n\n\twrap(H.Series.prototype, 'drawDataLabels', function (proceed) {\n\t\tvar css = this.chart.options.drilldown.activeDataLabelStyle;\n\n\t\tproceed.call(this);\n\n\t\teach(this.points, function (point) {\n\t\t\tif (point.drilldown && point.dataLabel) {\n\t\t\t\tpoint.dataLabel\n\t\t\t\t\t.attr({\n\t\t\t\t\t\t'class': 'highcharts-drilldown-data-label'\n\t\t\t\t\t})\n\t\t\t\t\t.css(css)\n\t\t\t\t\t.on('click', function () {\n\t\t\t\t\t\tpoint.doDrilldown();\n\t\t\t\t\t});\n\t\t\t}\n\t\t});\n\t});\n\n\t// Mark the trackers with a pointer \n\tColumnSeries.prototype.supportsDrilldown = true;\n\tPieSeries.prototype.supportsDrilldown = true;\n\tvar type, \n\t\tdrawTrackerWrapper = function (proceed) {\n\t\t\tproceed.call(this);\n\t\t\teach(this.points, function (point) {\n\t\t\t\tif (point.drilldown && point.graphic) {\n\t\t\t\t\tpoint.graphic\n\t\t\t\t\t\t.attr({\n\t\t\t\t\t\t\t'class': 'highcharts-drilldown-point'\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.css({ cursor: 'pointer' });\n\t\t\t\t}\n\t\t\t});\n\t\t};\n\tfor (type in seriesTypes) {\n\t\tif (seriesTypes[type].prototype.supportsDrilldown) {\n\t\t\twrap(seriesTypes[type].prototype, 'drawTracker', drawTrackerWrapper);\n\t\t}\n\t}\n\t\t\n}(Highcharts));\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/exporting.js",
    "content": "/*\n Highcharts JS v3.0.6 (2013-10-04)\n Exporting module\n\n (c) 2010-2013 Torstein Hønsi\n\n License: www.highcharts.com/license\n*/\n(function(f){var A=f.Chart,t=f.addEvent,C=f.removeEvent,k=f.createElement,n=f.discardElement,u=f.css,o=f.merge,r=f.each,p=f.extend,D=Math.max,j=document,B=window,E=f.isTouchDevice,F=f.Renderer.prototype.symbols,x=f.getOptions(),y;p(x.lang,{printChart:\"Print chart\",downloadPNG:\"Download PNG image\",downloadJPEG:\"Download JPEG image\",downloadPDF:\"Download PDF document\",downloadSVG:\"Download SVG vector image\",contextButtonTitle:\"Chart context menu\"});x.navigation={menuStyle:{border:\"1px solid #A0A0A0\",\nbackground:\"#FFFFFF\",padding:\"5px 0\"},menuItemStyle:{padding:\"0 10px\",background:\"none\",color:\"#303030\",fontSize:E?\"14px\":\"11px\"},menuItemHoverStyle:{background:\"#4572A5\",color:\"#FFFFFF\"},buttonOptions:{symbolFill:\"#E0E0E0\",symbolSize:14,symbolStroke:\"#666\",symbolStrokeWidth:3,symbolX:12.5,symbolY:10.5,align:\"right\",buttonSpacing:3,height:22,theme:{fill:\"white\",stroke:\"none\"},verticalAlign:\"top\",width:24}};x.exporting={type:\"image/png\",url:\"http://export.highcharts.com/\",buttons:{contextButton:{menuClassName:\"highcharts-contextmenu\",\nsymbol:\"menu\",_titleKey:\"contextButtonTitle\",menuItems:[{textKey:\"printChart\",onclick:function(){this.print()}},{separator:!0},{textKey:\"downloadPNG\",onclick:function(){this.exportChart()}},{textKey:\"downloadJPEG\",onclick:function(){this.exportChart({type:\"image/jpeg\"})}},{textKey:\"downloadPDF\",onclick:function(){this.exportChart({type:\"application/pdf\"})}},{textKey:\"downloadSVG\",onclick:function(){this.exportChart({type:\"image/svg+xml\"})}}]}}};f.post=function(c,a){var d,b;b=k(\"form\",{method:\"post\",\naction:c,enctype:\"multipart/form-data\"},{display:\"none\"},j.body);for(d in a)k(\"input\",{type:\"hidden\",name:d,value:a[d]},null,b);b.submit();n(b)};p(A.prototype,{getSVG:function(c){var a=this,d,b,z,h,g=o(a.options,c);if(!j.createElementNS)j.createElementNS=function(a,b){return j.createElement(b)};c=k(\"div\",null,{position:\"absolute\",top:\"-9999em\",width:a.chartWidth+\"px\",height:a.chartHeight+\"px\"},j.body);b=a.renderTo.style.width;h=a.renderTo.style.height;b=g.exporting.sourceWidth||g.chart.width||/px$/.test(b)&&\nparseInt(b,10)||600;h=g.exporting.sourceHeight||g.chart.height||/px$/.test(h)&&parseInt(h,10)||400;p(g.chart,{animation:!1,renderTo:c,forExport:!0,width:b,height:h});g.exporting.enabled=!1;g.series=[];r(a.series,function(a){z=o(a.options,{animation:!1,showCheckbox:!1,visible:a.visible});z.isInternal||g.series.push(z)});d=new f.Chart(g,a.callback);r([\"xAxis\",\"yAxis\"],function(b){r(a[b],function(a,c){var g=d[b][c],f=a.getExtremes(),h=f.userMin,f=f.userMax;g&&(h!==void 0||f!==void 0)&&g.setExtremes(h,\nf,!0,!1)})});b=d.container.innerHTML;g=null;d.destroy();n(c);b=b.replace(/zIndex=\"[^\"]+\"/g,\"\").replace(/isShadow=\"[^\"]+\"/g,\"\").replace(/symbolName=\"[^\"]+\"/g,\"\").replace(/jQuery[0-9]+=\"[^\"]+\"/g,\"\").replace(/url\\([^#]+#/g,\"url(#\").replace(/<svg /,'<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" ').replace(/ href=/g,\" xlink:href=\").replace(/\\n/,\" \").replace(/<\\/svg>.*?$/,\"</svg>\").replace(/&nbsp;/g,\" \").replace(/&shy;/g,\"­\").replace(/<IMG /g,\"<image \").replace(/height=([^\" ]+)/g,'height=\"$1\"').replace(/width=([^\" ]+)/g,\n'width=\"$1\"').replace(/hc-svg-href=\"([^\"]+)\">/g,'xlink:href=\"$1\"/>').replace(/id=([^\" >]+)/g,'id=\"$1\"').replace(/class=([^\" >]+)/g,'class=\"$1\"').replace(/ transform /g,\" \").replace(/:(path|rect)/g,\"$1\").replace(/style=\"([^\"]+)\"/g,function(a){return a.toLowerCase()});return b=b.replace(/(url\\(#highcharts-[0-9]+)&quot;/g,\"$1\").replace(/&quot;/g,\"'\")},exportChart:function(c,a){var c=c||{},d=this.options.exporting,d=this.getSVG(o({chart:{borderRadius:0}},d.chartOptions,a,{exporting:{sourceWidth:c.sourceWidth||\nd.sourceWidth,sourceHeight:c.sourceHeight||d.sourceHeight}})),c=o(this.options.exporting,c);f.post(c.url,{filename:c.filename||\"chart\",type:c.type,width:c.width||0,scale:c.scale||2,svg:d})},print:function(){var c=this,a=c.container,d=[],b=a.parentNode,f=j.body,h=f.childNodes;if(!c.isPrinting)c.isPrinting=!0,r(h,function(a,b){if(a.nodeType===1)d[b]=a.style.display,a.style.display=\"none\"}),f.appendChild(a),B.focus(),B.print(),setTimeout(function(){b.appendChild(a);r(h,function(a,b){if(a.nodeType===\n1)a.style.display=d[b]});c.isPrinting=!1},1E3)},contextMenu:function(c,a,d,b,f,h,g){var e=this,j=e.options.navigation,q=j.menuItemStyle,l=e.chartWidth,m=e.chartHeight,o=\"cache-\"+c,i=e[o],s=D(f,h),v,w,n;if(!i)e[o]=i=k(\"div\",{className:c},{position:\"absolute\",zIndex:1E3,padding:s+\"px\"},e.container),v=k(\"div\",null,p({MozBoxShadow:\"3px 3px 10px #888\",WebkitBoxShadow:\"3px 3px 10px #888\",boxShadow:\"3px 3px 10px #888\"},j.menuStyle),i),w=function(){u(i,{display:\"none\"});g&&g.setState(0);e.openMenu=!1},t(i,\n\"mouseleave\",function(){n=setTimeout(w,500)}),t(i,\"mouseenter\",function(){clearTimeout(n)}),t(document,\"mousedown\",function(a){e.pointer.inClass(a.target,c)||w()}),r(a,function(a){if(a){var b=a.separator?k(\"hr\",null,null,v):k(\"div\",{onmouseover:function(){u(this,j.menuItemHoverStyle)},onmouseout:function(){u(this,q)},onclick:function(){w();a.onclick.apply(e,arguments)},innerHTML:a.text||e.options.lang[a.textKey]},p({cursor:\"pointer\"},q),v);e.exportDivElements.push(b)}}),e.exportDivElements.push(v,\ni),e.exportMenuWidth=i.offsetWidth,e.exportMenuHeight=i.offsetHeight;a={display:\"block\"};d+e.exportMenuWidth>l?a.right=l-d-f-s+\"px\":a.left=d-s+\"px\";b+h+e.exportMenuHeight>m&&g.alignOptions.verticalAlign!==\"top\"?a.bottom=m-b-s+\"px\":a.top=b+h-s+\"px\";u(i,a);e.openMenu=!0},addButton:function(c){var a=this,d=a.renderer,b=o(a.options.navigation.buttonOptions,c),j=b.onclick,h=b.menuItems,g,e,k={stroke:b.symbolStroke,fill:b.symbolFill},q=b.symbolSize||12;if(!a.btnCount)a.btnCount=0;if(!a.exportDivElements)a.exportDivElements=\n[],a.exportSVGElements=[];if(b.enabled!==!1){var l=b.theme,m=l.states,n=m&&m.hover,m=m&&m.select,i;delete l.states;j?i=function(){j.apply(a,arguments)}:h&&(i=function(){a.contextMenu(e.menuClassName,h,e.translateX,e.translateY,e.width,e.height,e);e.setState(2)});b.text&&b.symbol?l.paddingLeft=f.pick(l.paddingLeft,25):b.text||p(l,{width:b.width,height:b.height,padding:0});e=d.button(b.text,0,0,i,l,n,m).attr({title:a.options.lang[b._titleKey],\"stroke-linecap\":\"round\"});e.menuClassName=c.menuClassName||\n\"highcharts-menu-\"+a.btnCount++;b.symbol&&(g=d.symbol(b.symbol,b.symbolX-q/2,b.symbolY-q/2,q,q).attr(p(k,{\"stroke-width\":b.symbolStrokeWidth||1,zIndex:1})).add(e));e.add().align(p(b,{width:e.width,x:f.pick(b.x,y)}),!0,\"spacingBox\");y+=(e.width+b.buttonSpacing)*(b.align===\"right\"?-1:1);a.exportSVGElements.push(e,g)}},destroyExport:function(c){var c=c.target,a,d;for(a=0;a<c.exportSVGElements.length;a++)if(d=c.exportSVGElements[a])d.onclick=d.ontouchstart=null,c.exportSVGElements[a]=d.destroy();for(a=\n0;a<c.exportDivElements.length;a++)d=c.exportDivElements[a],C(d,\"mouseleave\"),c.exportDivElements[a]=d.onmouseout=d.onmouseover=d.ontouchstart=d.onclick=null,n(d)}});F.menu=function(c,a,d,b){return[\"M\",c,a+2.5,\"L\",c+d,a+2.5,\"M\",c,a+b/2+0.5,\"L\",c+d,a+b/2+0.5,\"M\",c,a+b-1.5,\"L\",c+d,a+b-1.5]};A.prototype.callbacks.push(function(c){var a,d=c.options.exporting,b=d.buttons;y=0;if(d.enabled!==!1){for(a in b)c.addButton(b[a]);t(c,\"destroy\",c.destroyExport)}})})(Highcharts);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/exporting.src.js",
    "content": "/**\n * @license Highcharts JS v3.0.6 (2013-10-04)\n * Exporting module\n *\n * (c) 2010-2013 Torstein Hønsi\n *\n * License: www.highcharts.com/license\n */\n\n// JSLint options:\n/*global Highcharts, document, window, Math, setTimeout */\n\n(function (Highcharts) { // encapsulate\n\n// create shortcuts\nvar Chart = Highcharts.Chart,\n\taddEvent = Highcharts.addEvent,\n\tremoveEvent = Highcharts.removeEvent,\n\tcreateElement = Highcharts.createElement,\n\tdiscardElement = Highcharts.discardElement,\n\tcss = Highcharts.css,\n\tmerge = Highcharts.merge,\n\teach = Highcharts.each,\n\textend = Highcharts.extend,\n\tmath = Math,\n\tmathMax = math.max,\n\tdoc = document,\n\twin = window,\n\tisTouchDevice = Highcharts.isTouchDevice,\n\tM = 'M',\n\tL = 'L',\n\tDIV = 'div',\n\tHIDDEN = 'hidden',\n\tNONE = 'none',\n\tPREFIX = 'highcharts-',\n\tABSOLUTE = 'absolute',\n\tPX = 'px',\n\tUNDEFINED,\n\tsymbols = Highcharts.Renderer.prototype.symbols,\n\tdefaultOptions = Highcharts.getOptions(),\n\tbuttonOffset;\n\n\t// Add language\n\textend(defaultOptions.lang, {\n\t\tprintChart: 'Print chart',\n\t\tdownloadPNG: 'Download PNG image',\n\t\tdownloadJPEG: 'Download JPEG image',\n\t\tdownloadPDF: 'Download PDF document',\n\t\tdownloadSVG: 'Download SVG vector image',\n\t\tcontextButtonTitle: 'Chart context menu'\n\t});\n\n// Buttons and menus are collected in a separate config option set called 'navigation'.\n// This can be extended later to add control buttons like zoom and pan right click menus.\ndefaultOptions.navigation = {\n\tmenuStyle: {\n\t\tborder: '1px solid #A0A0A0',\n\t\tbackground: '#FFFFFF',\n\t\tpadding: '5px 0'\n\t},\n\tmenuItemStyle: {\n\t\tpadding: '0 10px',\n\t\tbackground: NONE,\n\t\tcolor: '#303030',\n\t\tfontSize: isTouchDevice ? '14px' : '11px'\n\t},\n\tmenuItemHoverStyle: {\n\t\tbackground: '#4572A5',\n\t\tcolor: '#FFFFFF'\n\t},\n\n\tbuttonOptions: {\n\t\tsymbolFill: '#E0E0E0',\n\t\tsymbolSize: 14,\n\t\tsymbolStroke: '#666',\n\t\tsymbolStrokeWidth: 3,\n\t\tsymbolX: 12.5,\n\t\tsymbolY: 10.5,\n\t\talign: 'right',\n\t\tbuttonSpacing: 3, \n\t\theight: 22,\n\t\t// text: null,\n\t\ttheme: {\n\t\t\tfill: 'white', // capture hover\n\t\t\tstroke: 'none'\n\t\t},\n\t\tverticalAlign: 'top',\n\t\twidth: 24\n\t}\n};\n\n\n\n// Add the export related options\ndefaultOptions.exporting = {\n\t//enabled: true,\n\t//filename: 'chart',\n\ttype: 'image/png',\n\turl: 'http://export.highcharts.com/',\n\t//width: undefined,\n\t//scale: 2\n\tbuttons: {\n\t\tcontextButton: {\n\t\t\tmenuClassName: PREFIX + 'contextmenu',\n\t\t\t//x: -10,\n\t\t\tsymbol: 'menu',\n\t\t\t_titleKey: 'contextButtonTitle',\n\t\t\tmenuItems: [{\n\t\t\t\ttextKey: 'printChart',\n\t\t\t\tonclick: function () {\n\t\t\t\t\tthis.print();\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\tseparator: true\n\t\t\t}, {\n\t\t\t\ttextKey: 'downloadPNG',\n\t\t\t\tonclick: function () {\n\t\t\t\t\tthis.exportChart();\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\ttextKey: 'downloadJPEG',\n\t\t\t\tonclick: function () {\n\t\t\t\t\tthis.exportChart({\n\t\t\t\t\t\ttype: 'image/jpeg'\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\ttextKey: 'downloadPDF',\n\t\t\t\tonclick: function () {\n\t\t\t\t\tthis.exportChart({\n\t\t\t\t\t\ttype: 'application/pdf'\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}, {\n\t\t\t\ttextKey: 'downloadSVG',\n\t\t\t\tonclick: function () {\n\t\t\t\t\tthis.exportChart({\n\t\t\t\t\t\ttype: 'image/svg+xml'\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Enable this block to add \"View SVG\" to the dropdown menu\n\t\t\t/*\n\t\t\t,{\n\n\t\t\t\ttext: 'View SVG',\n\t\t\t\tonclick: function () {\n\t\t\t\t\tvar svg = this.getSVG()\n\t\t\t\t\t\t.replace(/</g, '\\n&lt;')\n\t\t\t\t\t\t.replace(/>/g, '&gt;');\n\n\t\t\t\t\tdoc.body.innerHTML = '<pre>' + svg + '</pre>';\n\t\t\t\t}\n\t\t\t} // */\n\t\t\t]\n\t\t}\n\t}\n};\n\n// Add the Highcharts.post utility\nHighcharts.post = function (url, data) {\n\tvar name,\n\t\tform;\n\t\n\t// create the form\n\tform = createElement('form', {\n\t\tmethod: 'post',\n\t\taction: url,\n\t\tenctype: 'multipart/form-data'\n\t}, {\n\t\tdisplay: NONE\n\t}, doc.body);\n\n\t// add the data\n\tfor (name in data) {\n\t\tcreateElement('input', {\n\t\t\ttype: HIDDEN,\n\t\t\tname: name,\n\t\t\tvalue: data[name]\n\t\t}, null, form);\n\t}\n\n\t// submit\n\tform.submit();\n\n\t// clean up\n\tdiscardElement(form);\n};\n\nextend(Chart.prototype, {\n\n\t/**\n\t * Return an SVG representation of the chart\n\t *\n\t * @param additionalOptions {Object} Additional chart options for the generated SVG representation\n\t */\n\tgetSVG: function (additionalOptions) {\n\t\tvar chart = this,\n\t\t\tchartCopy,\n\t\t\tsandbox,\n\t\t\tsvg,\n\t\t\tseriesOptions,\n\t\t\tsourceWidth,\n\t\t\tsourceHeight,\n\t\t\tcssWidth,\n\t\t\tcssHeight,\n\t\t\toptions = merge(chart.options, additionalOptions); // copy the options and add extra options\n\n\t\t// IE compatibility hack for generating SVG content that it doesn't really understand\n\t\tif (!doc.createElementNS) {\n\t\t\t/*jslint unparam: true*//* allow unused parameter ns in function below */\n\t\t\tdoc.createElementNS = function (ns, tagName) {\n\t\t\t\treturn doc.createElement(tagName);\n\t\t\t};\n\t\t\t/*jslint unparam: false*/\n\t\t}\n\n\t\t// create a sandbox where a new chart will be generated\n\t\tsandbox = createElement(DIV, null, {\n\t\t\tposition: ABSOLUTE,\n\t\t\ttop: '-9999em',\n\t\t\twidth: chart.chartWidth + PX,\n\t\t\theight: chart.chartHeight + PX\n\t\t}, doc.body);\n\t\t\n\t\t// get the source size\n\t\tcssWidth = chart.renderTo.style.width;\n\t\tcssHeight = chart.renderTo.style.height;\n\t\tsourceWidth = options.exporting.sourceWidth ||\n\t\t\toptions.chart.width ||\n\t\t\t(/px$/.test(cssWidth) && parseInt(cssWidth, 10)) ||\n\t\t\t600;\n\t\tsourceHeight = options.exporting.sourceHeight ||\n\t\t\toptions.chart.height ||\n\t\t\t(/px$/.test(cssHeight) && parseInt(cssHeight, 10)) ||\n\t\t\t400;\n\n\t\t// override some options\n\t\textend(options.chart, {\n\t\t\tanimation: false,\n\t\t\trenderTo: sandbox,\n\t\t\tforExport: true,\n\t\t\twidth: sourceWidth,\n\t\t\theight: sourceHeight\n\t\t});\n\t\toptions.exporting.enabled = false; // hide buttons in print\n\t\t\n\t\t// prepare for replicating the chart\n\t\toptions.series = [];\n\t\teach(chart.series, function (serie) {\n\t\t\tseriesOptions = merge(serie.options, {\n\t\t\t\tanimation: false, // turn off animation\n\t\t\t\tshowCheckbox: false,\n\t\t\t\tvisible: serie.visible\n\t\t\t});\n\n\t\t\tif (!seriesOptions.isInternal) { // used for the navigator series that has its own option set\n\t\t\t\toptions.series.push(seriesOptions);\n\t\t\t}\n\t\t});\n\n\t\t// generate the chart copy\n\t\tchartCopy = new Highcharts.Chart(options, chart.callback);\n\n\t\t// reflect axis extremes in the export\n\t\teach(['xAxis', 'yAxis'], function (axisType) {\n\t\t\teach(chart[axisType], function (axis, i) {\n\t\t\t\tvar axisCopy = chartCopy[axisType][i],\n\t\t\t\t\textremes = axis.getExtremes(),\n\t\t\t\t\tuserMin = extremes.userMin,\n\t\t\t\t\tuserMax = extremes.userMax;\n\n\t\t\t\tif (axisCopy && (userMin !== UNDEFINED || userMax !== UNDEFINED)) {\n\t\t\t\t\taxisCopy.setExtremes(userMin, userMax, true, false);\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\n\t\t// get the SVG from the container's innerHTML\n\t\tsvg = chartCopy.container.innerHTML;\n\n\t\t// free up memory\n\t\toptions = null;\n\t\tchartCopy.destroy();\n\t\tdiscardElement(sandbox);\n\n\t\t// sanitize\n\t\tsvg = svg\n\t\t\t.replace(/zIndex=\"[^\"]+\"/g, '')\n\t\t\t.replace(/isShadow=\"[^\"]+\"/g, '')\n\t\t\t.replace(/symbolName=\"[^\"]+\"/g, '')\n\t\t\t.replace(/jQuery[0-9]+=\"[^\"]+\"/g, '')\n\t\t\t.replace(/url\\([^#]+#/g, 'url(#')\n\t\t\t.replace(/<svg /, '<svg xmlns:xlink=\"http://www.w3.org/1999/xlink\" ')\n\t\t\t.replace(/ href=/g, ' xlink:href=')\n\t\t\t.replace(/\\n/, ' ')\n\t\t\t.replace(/<\\/svg>.*?$/, '</svg>') // any HTML added to the container after the SVG (#894)\n\t\t\t/* This fails in IE < 8\n\t\t\t.replace(/([0-9]+)\\.([0-9]+)/g, function(s1, s2, s3) { // round off to save weight\n\t\t\t\treturn s2 +'.'+ s3[0];\n\t\t\t})*/\n\n\t\t\t// Replace HTML entities, issue #347\n\t\t\t.replace(/&nbsp;/g, '\\u00A0') // no-break space\n\t\t\t.replace(/&shy;/g,  '\\u00AD') // soft hyphen\n\n\t\t\t// IE specific\n\t\t\t.replace(/<IMG /g, '<image ')\n\t\t\t.replace(/height=([^\" ]+)/g, 'height=\"$1\"')\n\t\t\t.replace(/width=([^\" ]+)/g, 'width=\"$1\"')\n\t\t\t.replace(/hc-svg-href=\"([^\"]+)\">/g, 'xlink:href=\"$1\"/>')\n\t\t\t.replace(/id=([^\" >]+)/g, 'id=\"$1\"')\n\t\t\t.replace(/class=([^\" >]+)/g, 'class=\"$1\"')\n\t\t\t.replace(/ transform /g, ' ')\n\t\t\t.replace(/:(path|rect)/g, '$1')\n\t\t\t.replace(/style=\"([^\"]+)\"/g, function (s) {\n\t\t\t\treturn s.toLowerCase();\n\t\t\t});\n\n\t\t// IE9 beta bugs with innerHTML. Test again with final IE9.\n\t\tsvg = svg.replace(/(url\\(#highcharts-[0-9]+)&quot;/g, '$1')\n\t\t\t.replace(/&quot;/g, \"'\");\n\n\t\treturn svg;\n\t},\n\n\t/**\n\t * Submit the SVG representation of the chart to the server\n\t * @param {Object} options Exporting options. Possible members are url, type and width.\n\t * @param {Object} chartOptions Additional chart options for the SVG representation of the chart\n\t */\n\texportChart: function (options, chartOptions) {\n\t\toptions = options || {};\n\t\t\n\t\tvar chart = this,\n\t\t\tchartExportingOptions = chart.options.exporting,\n\t\t\tsvg = chart.getSVG(merge(\n\t\t\t\t{ chart: { borderRadius: 0 } },\n\t\t\t\tchartExportingOptions.chartOptions,\n\t\t\t\tchartOptions, \n\t\t\t\t{\n\t\t\t\t\texporting: {\n\t\t\t\t\t\tsourceWidth: options.sourceWidth || chartExportingOptions.sourceWidth,\n\t\t\t\t\t\tsourceHeight: options.sourceHeight || chartExportingOptions.sourceHeight\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t));\n\n\t\t// merge the options\n\t\toptions = merge(chart.options.exporting, options);\n\t\t\n\t\t// do the post\n\t\tHighcharts.post(options.url, {\n\t\t\tfilename: options.filename || 'chart',\n\t\t\ttype: options.type,\n\t\t\twidth: options.width || 0, // IE8 fails to post undefined correctly, so use 0\n\t\t\tscale: options.scale || 2,\n\t\t\tsvg: svg\n\t\t});\n\n\t},\n\t\n\t/**\n\t * Print the chart\n\t */\n\tprint: function () {\n\n\t\tvar chart = this,\n\t\t\tcontainer = chart.container,\n\t\t\torigDisplay = [],\n\t\t\torigParent = container.parentNode,\n\t\t\tbody = doc.body,\n\t\t\tchildNodes = body.childNodes;\n\n\t\tif (chart.isPrinting) { // block the button while in printing mode\n\t\t\treturn;\n\t\t}\n\n\t\tchart.isPrinting = true;\n\n\t\t// hide all body content\n\t\teach(childNodes, function (node, i) {\n\t\t\tif (node.nodeType === 1) {\n\t\t\t\torigDisplay[i] = node.style.display;\n\t\t\t\tnode.style.display = NONE;\n\t\t\t}\n\t\t});\n\n\t\t// pull out the chart\n\t\tbody.appendChild(container);\n\n\t\t// print\n\t\twin.focus(); // #1510\n\t\twin.print();\n\n\t\t// allow the browser to prepare before reverting\n\t\tsetTimeout(function () {\n\n\t\t\t// put the chart back in\n\t\t\torigParent.appendChild(container);\n\n\t\t\t// restore all body content\n\t\t\teach(childNodes, function (node, i) {\n\t\t\t\tif (node.nodeType === 1) {\n\t\t\t\t\tnode.style.display = origDisplay[i];\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tchart.isPrinting = false;\n\n\t\t}, 1000);\n\n\t},\n\n\t/**\n\t * Display a popup menu for choosing the export type\n\t *\n\t * @param {String} className An identifier for the menu\n\t * @param {Array} items A collection with text and onclicks for the items\n\t * @param {Number} x The x position of the opener button\n\t * @param {Number} y The y position of the opener button\n\t * @param {Number} width The width of the opener button\n\t * @param {Number} height The height of the opener button\n\t */\n\tcontextMenu: function (className, items, x, y, width, height, button) {\n\t\tvar chart = this,\n\t\t\tnavOptions = chart.options.navigation,\n\t\t\tmenuItemStyle = navOptions.menuItemStyle,\n\t\t\tchartWidth = chart.chartWidth,\n\t\t\tchartHeight = chart.chartHeight,\n\t\t\tcacheName = 'cache-' + className,\n\t\t\tmenu = chart[cacheName],\n\t\t\tmenuPadding = mathMax(width, height), // for mouse leave detection\n\t\t\tboxShadow = '3px 3px 10px #888',\n\t\t\tinnerMenu,\n\t\t\thide,\n\t\t\thideTimer,\n\t\t\tmenuStyle;\n\n\t\t// create the menu only the first time\n\t\tif (!menu) {\n\n\t\t\t// create a HTML element above the SVG\n\t\t\tchart[cacheName] = menu = createElement(DIV, {\n\t\t\t\tclassName: className\n\t\t\t}, {\n\t\t\t\tposition: ABSOLUTE,\n\t\t\t\tzIndex: 1000,\n\t\t\t\tpadding: menuPadding + PX\n\t\t\t}, chart.container);\n\n\t\t\tinnerMenu = createElement(DIV, null,\n\t\t\t\textend({\n\t\t\t\t\tMozBoxShadow: boxShadow,\n\t\t\t\t\tWebkitBoxShadow: boxShadow,\n\t\t\t\t\tboxShadow: boxShadow\n\t\t\t\t}, navOptions.menuStyle), menu);\n\n\t\t\t// hide on mouse out\n\t\t\thide = function () {\n\t\t\t\tcss(menu, { display: NONE });\n\t\t\t\tif (button) {\n\t\t\t\t\tbutton.setState(0);\n\t\t\t\t}\n\t\t\t\tchart.openMenu = false;\n\t\t\t};\n\n\t\t\t// Hide the menu some time after mouse leave (#1357)\n\t\t\taddEvent(menu, 'mouseleave', function () {\n\t\t\t\thideTimer = setTimeout(hide, 500);\n\t\t\t});\n\t\t\taddEvent(menu, 'mouseenter', function () {\n\t\t\t\tclearTimeout(hideTimer);\n\t\t\t});\n\t\t\t// Hide it on clicking or touching outside the menu (#2258)\n\t\t\taddEvent(document, 'mousedown', function (e) {\n\t\t\t\tif (!chart.pointer.inClass(e.target, className)) {\n\t\t\t\t\thide();\n\t\t\t\t}\n\t\t\t});\n\n\n\t\t\t// create the items\n\t\t\teach(items, function (item) {\n\t\t\t\tif (item) {\n\t\t\t\t\tvar element = item.separator ? \n\t\t\t\t\t\tcreateElement('hr', null, null, innerMenu) :\n\t\t\t\t\t\tcreateElement(DIV, {\n\t\t\t\t\t\t\tonmouseover: function () {\n\t\t\t\t\t\t\t\tcss(this, navOptions.menuItemHoverStyle);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tonmouseout: function () {\n\t\t\t\t\t\t\t\tcss(this, menuItemStyle);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tonclick: function () {\n\t\t\t\t\t\t\t\thide();\n\t\t\t\t\t\t\t\titem.onclick.apply(chart, arguments);\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tinnerHTML: item.text || chart.options.lang[item.textKey]\n\t\t\t\t\t\t}, extend({\n\t\t\t\t\t\t\tcursor: 'pointer'\n\t\t\t\t\t\t}, menuItemStyle), innerMenu);\n\n\n\t\t\t\t\t// Keep references to menu divs to be able to destroy them\n\t\t\t\t\tchart.exportDivElements.push(element);\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Keep references to menu and innerMenu div to be able to destroy them\n\t\t\tchart.exportDivElements.push(innerMenu, menu);\n\n\t\t\tchart.exportMenuWidth = menu.offsetWidth;\n\t\t\tchart.exportMenuHeight = menu.offsetHeight;\n\t\t}\n\n\t\tmenuStyle = { display: 'block' };\n\n\t\t// if outside right, right align it\n\t\tif (x + chart.exportMenuWidth > chartWidth) {\n\t\t\tmenuStyle.right = (chartWidth - x - width - menuPadding) + PX;\n\t\t} else {\n\t\t\tmenuStyle.left = (x - menuPadding) + PX;\n\t\t}\n\t\t// if outside bottom, bottom align it\n\t\tif (y + height + chart.exportMenuHeight > chartHeight && button.alignOptions.verticalAlign !== 'top') {\n\t\t\tmenuStyle.bottom = (chartHeight - y - menuPadding)  + PX;\n\t\t} else {\n\t\t\tmenuStyle.top = (y + height - menuPadding) + PX;\n\t\t}\n\n\t\tcss(menu, menuStyle);\n\t\tchart.openMenu = true;\n\t},\n\n\t/**\n\t * Add the export button to the chart\n\t */\n\taddButton: function (options) {\n\t\tvar chart = this,\n\t\t\trenderer = chart.renderer,\n\t\t\tbtnOptions = merge(chart.options.navigation.buttonOptions, options),\n\t\t\tonclick = btnOptions.onclick,\n\t\t\tmenuItems = btnOptions.menuItems,\n\t\t\tsymbol,\n\t\t\tbutton,\n\t\t\tsymbolAttr = {\n\t\t\t\tstroke: btnOptions.symbolStroke,\n\t\t\t\tfill: btnOptions.symbolFill\n\t\t\t},\n\t\t\tsymbolSize = btnOptions.symbolSize || 12;\n\t\tif (!chart.btnCount) {\n\t\t\tchart.btnCount = 0;\n\t\t}\n\n\t\t// Keeps references to the button elements\n\t\tif (!chart.exportDivElements) {\n\t\t\tchart.exportDivElements = [];\n\t\t\tchart.exportSVGElements = [];\n\t\t}\n\n\t\tif (btnOptions.enabled === false) {\n\t\t\treturn;\n\t\t}\n\n\n\t\tvar attr = btnOptions.theme,\n\t\t\tstates = attr.states,\n\t\t\thover = states && states.hover,\n\t\t\tselect = states && states.select,\n\t\t\tcallback;\n\n\t\tdelete attr.states;\n\n\t\tif (onclick) {\n\t\t\tcallback = function () {\n\t\t\t\tonclick.apply(chart, arguments);\n\t\t\t};\n\n\t\t} else if (menuItems) {\n\t\t\tcallback = function () {\n\t\t\t\tchart.contextMenu(\n\t\t\t\t\tbutton.menuClassName, \n\t\t\t\t\tmenuItems, \n\t\t\t\t\tbutton.translateX, \n\t\t\t\t\tbutton.translateY, \n\t\t\t\t\tbutton.width, \n\t\t\t\t\tbutton.height,\n\t\t\t\t\tbutton\n\t\t\t\t);\n\t\t\t\tbutton.setState(2);\n\t\t\t};\n\t\t}\n\n\n\t\tif (btnOptions.text && btnOptions.symbol) {\n\t\t\tattr.paddingLeft = Highcharts.pick(attr.paddingLeft, 25);\n\t\t\n\t\t} else if (!btnOptions.text) {\n\t\t\textend(attr, {\n\t\t\t\twidth: btnOptions.width,\n\t\t\t\theight: btnOptions.height,\n\t\t\t\tpadding: 0\n\t\t\t});\n\t\t}\n\n\t\tbutton = renderer.button(btnOptions.text, 0, 0, callback, attr, hover, select)\n\t\t\t.attr({\n\t\t\t\ttitle: chart.options.lang[btnOptions._titleKey],\n\t\t\t\t'stroke-linecap': 'round'\n\t\t\t});\n\t\tbutton.menuClassName = options.menuClassName || PREFIX + 'menu-' + chart.btnCount++;\n\n\t\tif (btnOptions.symbol) {\n\t\t\tsymbol = renderer.symbol(\n\t\t\t\t\tbtnOptions.symbol,\n\t\t\t\t\tbtnOptions.symbolX - (symbolSize / 2),\n\t\t\t\t\tbtnOptions.symbolY - (symbolSize / 2),\n\t\t\t\t\tsymbolSize,\t\t\t\t\n\t\t\t\t\tsymbolSize\n\t\t\t\t)\n\t\t\t\t.attr(extend(symbolAttr, {\n\t\t\t\t\t'stroke-width': btnOptions.symbolStrokeWidth || 1,\n\t\t\t\t\tzIndex: 1\n\t\t\t\t})).add(button);\n\t\t}\n\n\t\tbutton.add()\n\t\t\t.align(extend(btnOptions, {\n\t\t\t\twidth: button.width,\n\t\t\t\tx: Highcharts.pick(btnOptions.x, buttonOffset) // #1654\n\t\t\t}), true, 'spacingBox');\n\n\t\tbuttonOffset += (button.width + btnOptions.buttonSpacing) * (btnOptions.align === 'right' ? -1 : 1);\n\n\t\tchart.exportSVGElements.push(button, symbol);\n\n\t},\n\n\t/**\n\t * Destroy the buttons.\n\t */\n\tdestroyExport: function (e) {\n\t\tvar chart = e.target,\n\t\t\ti,\n\t\t\telem;\n\n\t\t// Destroy the extra buttons added\n\t\tfor (i = 0; i < chart.exportSVGElements.length; i++) {\n\t\t\telem = chart.exportSVGElements[i];\n\t\t\t\n\t\t\t// Destroy and null the svg/vml elements\n\t\t\tif (elem) { // #1822\n\t\t\t\telem.onclick = elem.ontouchstart = null;\n\t\t\t\tchart.exportSVGElements[i] = elem.destroy();\n\t\t\t}\n\t\t}\n\n\t\t// Destroy the divs for the menu\n\t\tfor (i = 0; i < chart.exportDivElements.length; i++) {\n\t\t\telem = chart.exportDivElements[i];\n\n\t\t\t// Remove the event handler\n\t\t\tremoveEvent(elem, 'mouseleave');\n\n\t\t\t// Remove inline events\n\t\t\tchart.exportDivElements[i] = elem.onmouseout = elem.onmouseover = elem.ontouchstart = elem.onclick = null;\n\n\t\t\t// Destroy the div by moving to garbage bin\n\t\t\tdiscardElement(elem);\n\t\t}\n\t}\n});\n\n\nsymbols.menu = function (x, y, width, height) {\n\tvar arr = [\n\t\tM, x, y + 2.5,\n\t\tL, x + width, y + 2.5,\n\t\tM, x, y + height / 2 + 0.5,\n\t\tL, x + width, y + height / 2 + 0.5,\n\t\tM, x, y + height - 1.5,\n\t\tL, x + width, y + height - 1.5\n\t];\n\treturn arr;\n};\n\n// Add the buttons on chart load\nChart.prototype.callbacks.push(function (chart) {\n\tvar n,\n\t\texportingOptions = chart.options.exporting,\n\t\tbuttons = exportingOptions.buttons;\n\n\tbuttonOffset = 0;\n\n\tif (exportingOptions.enabled !== false) {\n\n\t\tfor (n in buttons) {\n\t\t\tchart.addButton(buttons[n]);\n\t\t}\n\n\t\t// Destroy the export elements at chart destroy\n\t\taddEvent(chart, 'destroy', chart.destroyExport);\n\t}\n\n});\n\n\n}(Highcharts));\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/funnel.js",
    "content": "/*\n \n Highcharts funnel module, Beta\n\n (c) 2010-2012 Torstein Hønsi\n\n License: www.highcharts.com/license\n*/\n(function(d){var u=d.getOptions().plotOptions,p=d.seriesTypes,D=d.merge,z=function(){},A=d.each;u.funnel=D(u.pie,{center:[\"50%\",\"50%\"],width:\"90%\",neckWidth:\"30%\",height:\"100%\",neckHeight:\"25%\",dataLabels:{connectorWidth:1,connectorColor:\"#606060\"},size:!0,states:{select:{color:\"#C0C0C0\",borderColor:\"#000000\",shadow:!1}}});p.funnel=d.extendClass(p.pie,{type:\"funnel\",animate:z,translate:function(){var a=function(k,a){return/%$/.test(k)?a*parseInt(k,10)/100:parseInt(k,10)},g=0,e=this.chart,f=e.plotWidth,\ne=e.plotHeight,h=0,c=this.options,C=c.center,b=a(C[0],f),d=a(C[0],e),p=a(c.width,f),i,q,j=a(c.height,e),r=a(c.neckWidth,f),s=a(c.neckHeight,e),v=j-s,a=this.data,w,x,u=c.dataLabels.position===\"left\"?1:0,y,m,B,n,l,t,o;this.getWidthAt=q=function(k){return k>j-s||j===s?r:r+(p-r)*((j-s-k)/(j-s))};this.getX=function(k,a){return b+(a?-1:1)*(q(k)/2+c.dataLabels.distance)};this.center=[b,d,j];this.centerX=b;A(a,function(a){g+=a.y});A(a,function(a){o=null;x=g?a.y/g:0;m=d-j/2+h*j;l=m+x*j;i=q(m);y=b-i/2;B=y+\ni;i=q(l);n=b-i/2;t=n+i;m>v?(y=n=b-r/2,B=t=b+r/2):l>v&&(o=l,i=q(v),n=b-i/2,t=n+i,l=v);w=[\"M\",y,m,\"L\",B,m,t,l];o&&w.push(t,o,n,o);w.push(n,l,\"Z\");a.shapeType=\"path\";a.shapeArgs={d:w};a.percentage=x*100;a.plotX=b;a.plotY=(m+(o||l))/2;a.tooltipPos=[b,a.plotY];a.slice=z;a.half=u;h+=x});this.setTooltipPoints()},drawPoints:function(){var a=this,g=a.options,e=a.chart.renderer;A(a.data,function(f){var h=f.graphic,c=f.shapeArgs;h?h.animate(c):f.graphic=e.path(c).attr({fill:f.color,stroke:g.borderColor,\"stroke-width\":g.borderWidth}).add(a.group)})},\nsortByAngle:z,drawDataLabels:function(){var a=this.data,g=this.options.dataLabels.distance,e,f,h,c=a.length,d,b;for(this.center[2]-=2*g;c--;)h=a[c],f=(e=h.half)?1:-1,b=h.plotY,d=this.getX(b,e),h.labelPos=[0,b,d+(g-5)*f,b,d+g*f,b,e?\"right\":\"left\",0];p.pie.prototype.drawDataLabels.call(this)}})})(Highcharts);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/funnel.src.js",
    "content": "/**\n * @license \n * Highcharts funnel module, Beta\n *\n * (c) 2010-2012 Torstein Hønsi\n *\n * License: www.highcharts.com/license\n */\n\n/*global Highcharts */\n(function (Highcharts) {\n\t\n'use strict';\n\n// create shortcuts\nvar defaultOptions = Highcharts.getOptions(),\n\tdefaultPlotOptions = defaultOptions.plotOptions,\n\tseriesTypes = Highcharts.seriesTypes,\n\tmerge = Highcharts.merge,\n\tnoop = function () {},\n\teach = Highcharts.each;\n\n// set default options\ndefaultPlotOptions.funnel = merge(defaultPlotOptions.pie, {\n\tcenter: ['50%', '50%'],\n\twidth: '90%',\n\tneckWidth: '30%',\n\theight: '100%',\n\tneckHeight: '25%',\n\n\tdataLabels: {\n\t\t//position: 'right',\n\t\tconnectorWidth: 1,\n\t\tconnectorColor: '#606060'\n\t},\n\tsize: true, // to avoid adapting to data label size in Pie.drawDataLabels\n\tstates: {\n\t\tselect: {\n\t\t\tcolor: '#C0C0C0',\n\t\t\tborderColor: '#000000',\n\t\t\tshadow: false\n\t\t}\n\t}\t\n});\n\n\nseriesTypes.funnel = Highcharts.extendClass(seriesTypes.pie, {\n\t\n\ttype: 'funnel',\n\tanimate: noop,\n\n\t/**\n\t * Overrides the pie translate method\n\t */\n\ttranslate: function () {\n\t\t\n\t\tvar \n\t\t\t// Get positions - either an integer or a percentage string must be given\n\t\t\tgetLength = function (length, relativeTo) {\n\t\t\t\treturn (/%$/).test(length) ?\n\t\t\t\t\trelativeTo * parseInt(length, 10) / 100 :\n\t\t\t\t\tparseInt(length, 10);\n\t\t\t},\n\t\t\t\n\t\t\tsum = 0,\n\t\t\tseries = this,\n\t\t\tchart = series.chart,\n\t\t\tplotWidth = chart.plotWidth,\n\t\t\tplotHeight = chart.plotHeight,\n\t\t\tcumulative = 0, // start at top\n\t\t\toptions = series.options,\n\t\t\tcenter = options.center,\n\t\t\tcenterX = getLength(center[0], plotWidth),\n\t\t\tcenterY = getLength(center[0], plotHeight),\n\t\t\twidth = getLength(options.width, plotWidth),\n\t\t\ttempWidth,\n\t\t\tgetWidthAt,\n\t\t\theight = getLength(options.height, plotHeight),\n\t\t\tneckWidth = getLength(options.neckWidth, plotWidth),\n\t\t\tneckHeight = getLength(options.neckHeight, plotHeight),\n\t\t\tneckY = height - neckHeight,\n\t\t\tdata = series.data,\n\t\t\tpath,\n\t\t\tfraction,\n\t\t\thalf = options.dataLabels.position === 'left' ? 1 : 0,\n\n\t\t\tx1, \n\t\t\ty1, \n\t\t\tx2, \n\t\t\tx3, \n\t\t\ty3, \n\t\t\tx4, \n\t\t\ty5;\n\n\t\t// Return the width at a specific y coordinate\n\t\tseries.getWidthAt = getWidthAt = function (y) {\n\t\t\treturn y > height - neckHeight || height === neckHeight ?\n\t\t\t\tneckWidth :\n\t\t\t\tneckWidth + (width - neckWidth) * ((height - neckHeight - y) / (height - neckHeight));\n\t\t};\n\t\tseries.getX = function (y, half) {\n\t\t\treturn centerX + (half ? -1 : 1) * ((getWidthAt(y) / 2) + options.dataLabels.distance);\n\t\t};\n\n\t\t// Expose\n\t\tseries.center = [centerX, centerY, height];\n\t\tseries.centerX = centerX;\n\n\t\t/*\n\t\t * Individual point coordinate naming:\n\t\t *\n\t\t * x1,y1 _________________ x2,y1\n\t\t *  \\                         /\n\t\t *   \\                       /\n\t\t *    \\                     /\n\t\t *     \\                   /\n\t\t *      \\                 /\n\t\t *     x3,y3 _________ x4,y3\n\t\t *\n\t\t * Additional for the base of the neck:\n\t\t *\n\t\t *       |               |\n\t\t *       |               |\n\t\t *       |               |\n\t\t *     x3,y5 _________ x4,y5\n\t\t */\n\n\n\n\n\t\t// get the total sum\n\t\teach(data, function (point) {\n\t\t\tsum += point.y;\n\t\t});\n\n\t\teach(data, function (point) {\n\t\t\t// set start and end positions\n\t\t\ty5 = null;\n\t\t\tfraction = sum ? point.y / sum : 0;\n\t\t\ty1 = centerY - height / 2 + cumulative * height;\n\t\t\ty3 = y1 + fraction * height;\n\t\t\t//tempWidth = neckWidth + (width - neckWidth) * ((height - neckHeight - y1) / (height - neckHeight));\n\t\t\ttempWidth = getWidthAt(y1);\n\t\t\tx1 = centerX - tempWidth / 2;\n\t\t\tx2 = x1 + tempWidth;\n\t\t\ttempWidth = getWidthAt(y3);\n\t\t\tx3 = centerX - tempWidth / 2;\n\t\t\tx4 = x3 + tempWidth;\n\n\t\t\t// the entire point is within the neck\n\t\t\tif (y1 > neckY) {\n\t\t\t\tx1 = x3 = centerX - neckWidth / 2;\n\t\t\t\tx2 = x4 = centerX + neckWidth / 2;\n\t\t\t\n\t\t\t// the base of the neck\n\t\t\t} else if (y3 > neckY) {\n\t\t\t\ty5 = y3;\n\n\t\t\t\ttempWidth = getWidthAt(neckY);\n\t\t\t\tx3 = centerX - tempWidth / 2;\n\t\t\t\tx4 = x3 + tempWidth;\n\n\t\t\t\ty3 = neckY;\n\t\t\t}\n\n\t\t\t// save the path\n\t\t\tpath = [\n\t\t\t\t'M',\n\t\t\t\tx1, y1,\n\t\t\t\t'L',\n\t\t\t\tx2, y1,\n\t\t\t\tx4, y3\n\t\t\t];\n\t\t\tif (y5) {\n\t\t\t\tpath.push(x4, y5, x3, y5);\n\t\t\t}\n\t\t\tpath.push(x3, y3, 'Z');\n\n\t\t\t// prepare for using shared dr\n\t\t\tpoint.shapeType = 'path';\n\t\t\tpoint.shapeArgs = { d: path };\n\n\n\t\t\t// for tooltips and data labels\n\t\t\tpoint.percentage = fraction * 100;\n\t\t\tpoint.plotX = centerX;\n\t\t\tpoint.plotY = (y1 + (y5 || y3)) / 2;\n\n\t\t\t// Placement of tooltips and data labels\n\t\t\tpoint.tooltipPos = [\n\t\t\t\tcenterX,\n\t\t\t\tpoint.plotY\n\t\t\t];\n\n\t\t\t// Slice is a noop on funnel points\n\t\t\tpoint.slice = noop;\n\t\t\t\n\t\t\t// Mimicking pie data label placement logic\n\t\t\tpoint.half = half;\n\n\t\t\tcumulative += fraction;\n\t\t});\n\n\n\t\tseries.setTooltipPoints();\n\t},\n\t/**\n\t * Draw a single point (wedge)\n\t * @param {Object} point The point object\n\t * @param {Object} color The color of the point\n\t * @param {Number} brightness The brightness relative to the color\n\t */\n\tdrawPoints: function () {\n\t\tvar series = this,\n\t\t\toptions = series.options,\n\t\t\tchart = series.chart,\n\t\t\trenderer = chart.renderer;\n\n\t\teach(series.data, function (point) {\n\t\t\t\n\t\t\tvar graphic = point.graphic,\n\t\t\t\tshapeArgs = point.shapeArgs;\n\n\t\t\tif (!graphic) { // Create the shapes\n\t\t\t\tpoint.graphic = renderer.path(shapeArgs).\n\t\t\t\t\tattr({\n\t\t\t\t\t\tfill: point.color,\n\t\t\t\t\t\tstroke: options.borderColor,\n\t\t\t\t\t\t'stroke-width': options.borderWidth\n\t\t\t\t\t}).\n\t\t\t\t\tadd(series.group);\n\t\t\t\t\t\n\t\t\t} else { // Update the shapes\n\t\t\t\tgraphic.animate(shapeArgs);\n\t\t\t}\n\t\t});\n\t},\n\n\t/**\n\t * Funnel items don't have angles (#2289)\n\t */\n\tsortByAngle: noop,\n\t\n\t/**\n\t * Extend the pie data label method\n\t */\n\tdrawDataLabels: function () {\n\t\tvar data = this.data,\n\t\t\tlabelDistance = this.options.dataLabels.distance,\n\t\t\tleftSide,\n\t\t\tsign,\n\t\t\tpoint,\n\t\t\ti = data.length,\n\t\t\tx,\n\t\t\ty;\n\t\t\n\t\t// In the original pie label anticollision logic, the slots are distributed\n\t\t// from one labelDistance above to one labelDistance below the pie. In funnels\n\t\t// we don't want this.\n\t\tthis.center[2] -= 2 * labelDistance;\n\t\t\n\t\t// Set the label position array for each point.\n\t\twhile (i--) {\n\t\t\tpoint = data[i];\n\t\t\tleftSide = point.half;\n\t\t\tsign = leftSide ? 1 : -1;\n\t\t\ty = point.plotY;\n\t\t\tx = this.getX(y, leftSide);\n\t\t\t\t\n\t\t\t// set the anchor point for data labels\n\t\t\tpoint.labelPos = [\n\t\t\t\t0, // first break of connector\n\t\t\t\ty, // a/a\n\t\t\t\tx + (labelDistance - 5) * sign, // second break, right outside point shape\n\t\t\t\ty, // a/a\n\t\t\t\tx + labelDistance * sign, // landing point for connector\n\t\t\t\ty, // a/a\n\t\t\t\tleftSide ? 'right' : 'left', // alignment\n\t\t\t\t0 // center angle\n\t\t\t];\n\t\t}\n\t\t\n\t\tseriesTypes.pie.prototype.drawDataLabels.call(this);\n\t}\n\n});\n\n\n}(Highcharts));\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/heatmap.js",
    "content": "(function(b){var k=b.seriesTypes,l=b.each;k.heatmap=b.extendClass(k.map,{colorKey:\"z\",useMapGeometry:!1,pointArrayMap:[\"y\",\"z\"],translate:function(){var c=this,b=c.options,i=Number.MAX_VALUE,j=Number.MIN_VALUE;c.generatePoints();l(c.data,function(a){var e=a.x,f=a.y,d=a.z,g=(b.colsize||1)/2,h=(b.rowsize||1)/2;a.path=[\"M\",e-g,f-h,\"L\",e+g,f-h,\"L\",e+g,f+h,\"L\",e-g,f+h,\"Z\"];a.shapeType=\"path\";a.shapeArgs={d:c.translatePath(a.path)};typeof d===\"number\"&&(d>j?j=d:d<i&&(i=d))});c.translateColors(i,j)},getBox:function(){}})})(Highcharts);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/heatmap.src.js",
    "content": "(function (Highcharts) {\n\tvar seriesTypes = Highcharts.seriesTypes,\n\t\teach = Highcharts.each;\n\t\n\tseriesTypes.heatmap = Highcharts.extendClass(seriesTypes.map, {\n\t\tcolorKey: 'z',\n\t\tuseMapGeometry: false,\n\t\tpointArrayMap: ['y', 'z'],\n\t\ttranslate: function () {\n\t\t\tvar series = this,\n\t\t\t\toptions = series.options,\n\t\t\t\tdataMin = Number.MAX_VALUE,\n\t\t\t\tdataMax = Number.MIN_VALUE;\n\n\t\t\tseries.generatePoints();\n\t\n\t\t\teach(series.data, function (point) {\n\t\t\t\tvar x = point.x,\n\t\t\t\t\ty = point.y,\n\t\t\t\t\tvalue = point.z,\n\t\t\t\t\txPad = (options.colsize || 1) / 2,\n\t\t\t\t\tyPad = (options.rowsize || 1) / 2;\n\n\t\t\t\tpoint.path = [\n\t\t\t\t\t'M', x - xPad, y - yPad,\n\t\t\t\t\t'L', x + xPad, y - yPad,\n\t\t\t\t\t'L', x + xPad, y + yPad,\n\t\t\t\t\t'L', x - xPad, y + yPad,\n\t\t\t\t\t'Z'\n\t\t\t\t];\n\t\t\t\t\n\t\t\t\tpoint.shapeType = 'path';\n\t\t\t\tpoint.shapeArgs = {\n\t\t\t\t\td: series.translatePath(point.path)\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\tif (typeof value === 'number') {\n\t\t\t\t\tif (value > dataMax) {\n\t\t\t\t\t\tdataMax = value;\n\t\t\t\t\t} else if (value < dataMin) {\n\t\t\t\t\t\tdataMin = value;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\t\n\t\t\tseries.translateColors(dataMin, dataMax);\n\t\t},\n\t\t\n\t\tgetBox: function () {}\n\t\t\t\n\t});\n\t\n}(Highcharts));\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/map.js",
    "content": "/*\n Map plugin v0.1 for Highcharts\n\n (c) 2011-2013 Torstein Hønsi\n\n License: www.highcharts.com/license\n*/\n(function(g){function x(a,b,c){for(var d=4,e=[];d--;)e[d]=Math.round(b.rgba[d]+(a.rgba[d]-b.rgba[d])*(1-c));return\"rgba(\"+e.join(\",\")+\")\"}var r=g.Axis,y=g.Chart,s=g.Point,z=g.Pointer,l=g.each,v=g.extend,p=g.merge,n=g.pick,A=g.numberFormat,B=g.getOptions(),k=g.seriesTypes,q=B.plotOptions,t=g.wrap,u=g.Color,w=function(){};B.mapNavigation={buttonOptions:{align:\"right\",verticalAlign:\"bottom\",x:0,width:18,height:18,style:{fontSize:\"15px\",fontWeight:\"bold\",textAlign:\"center\"}},buttons:{zoomIn:{onclick:function(){this.mapZoom(0.5)},\ntext:\"+\",y:-32},zoomOut:{onclick:function(){this.mapZoom(2)},text:\"-\",y:0}}};g.splitPath=function(a){var b,a=a.replace(/([A-Za-z])/g,\" $1 \"),a=a.replace(/^\\s*/,\"\").replace(/\\s*$/,\"\"),a=a.split(/[ ,]+/);for(b=0;b<a.length;b++)/[a-zA-Z]/.test(a[b])||(a[b]=parseFloat(a[b]));return a};g.maps={};t(r.prototype,\"getSeriesExtremes\",function(a){var b=this.isXAxis,c,d,e=[];l(this.series,function(a,b){if(a.useMapGeometry)e[b]=a.xData,a.xData=[]});a.call(this);c=n(this.dataMin,Number.MAX_VALUE);d=n(this.dataMax,\nNumber.MIN_VALUE);l(this.series,function(a,i){if(a.useMapGeometry)c=Math.min(c,a[b?\"minX\":\"minY\"]),d=Math.max(d,a[b?\"maxX\":\"maxY\"]),a.xData=e[i]});this.dataMin=c;this.dataMax=d});t(r.prototype,\"setAxisTranslation\",function(a){var b=this.chart,c=b.plotWidth/b.plotHeight,d=this.isXAxis,e=b.xAxis[0];a.call(this);if(b.options.chart.type===\"map\"&&!d&&e.transA!==void 0)this.transA=e.transA=Math.min(this.transA,e.transA),a=(e.max-e.min)/(this.max-this.min),e=a>c?this:e,c=(e.max-e.min)*e.transA,e.minPixelPadding=\n(e.len-c)/2});t(y.prototype,\"render\",function(a){var b=this,c=b.options.mapNavigation;a.call(b);b.renderMapNavigation();c.zoomOnDoubleClick&&g.addEvent(b.container,\"dblclick\",function(a){b.pointer.onContainerDblClick(a)});c.zoomOnMouseWheel&&g.addEvent(b.container,document.onmousewheel===void 0?\"DOMMouseScroll\":\"mousewheel\",function(a){b.pointer.onContainerMouseWheel(a)})});v(z.prototype,{onContainerDblClick:function(a){var b=this.chart,a=this.normalize(a);b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-\nb.plotTop)&&b.mapZoom(0.5,b.xAxis[0].toValue(a.chartX),b.yAxis[0].toValue(a.chartY))},onContainerMouseWheel:function(a){var b=this.chart,c,a=this.normalize(a);c=a.detail||-(a.wheelDelta/120);b.isInsidePlot(a.chartX-b.plotLeft,a.chartY-b.plotTop)&&b.mapZoom(c>0?2:0.5,b.xAxis[0].toValue(a.chartX),b.yAxis[0].toValue(a.chartY))}});t(z.prototype,\"init\",function(a,b,c){a.call(this,b,c);if(c.mapNavigation.enableTouchZoom)this.pinchX=this.pinchHor=this.pinchY=this.pinchVert=!0});v(y.prototype,{renderMapNavigation:function(){var a=\nthis,b=this.options.mapNavigation,c=b.buttons,d,e,f,i=function(){this.handler.call(a)};if(b.enableButtons)for(d in c)if(c.hasOwnProperty(d))f=p(b.buttonOptions,c[d]),e=a.renderer.button(f.text,0,0,i).attr({width:f.width,height:f.height}).css(f.style).add(),e.handler=f.onclick,e.align(v(f,{width:e.width,height:e.height}),null,\"spacingBox\")},fitToBox:function(a,b){l([[\"x\",\"width\"],[\"y\",\"height\"]],function(c){var d=c[0],c=c[1];a[d]+a[c]>b[d]+b[c]&&(a[c]>b[c]?(a[c]=b[c],a[d]=b[d]):a[d]=b[d]+b[c]-a[c]);\na[c]>b[c]&&(a[c]=b[c]);a[d]<b[d]&&(a[d]=b[d])});return a},mapZoom:function(a,b,c){if(!this.isMapZooming){var d=this,e=d.xAxis[0],f=e.max-e.min,i=n(b,e.min+f/2),b=f*a,f=d.yAxis[0],h=f.max-f.min,c=n(c,f.min+h/2);a*=h;i-=b/2;h=c-a/2;c=n(d.options.chart.animation,!0);b=d.fitToBox({x:i,y:h,width:b,height:a},{x:e.dataMin,y:f.dataMin,width:e.dataMax-e.dataMin,height:f.dataMax-f.dataMin});e.setExtremes(b.x,b.x+b.width,!1);f.setExtremes(b.y,b.y+b.height,!1);if(e=c?c.duration||500:0)d.isMapZooming=!0,setTimeout(function(){d.isMapZooming=\n!1},e);d.redraw()}}});q.map=p(q.scatter,{animation:!1,nullColor:\"#F8F8F8\",borderColor:\"silver\",borderWidth:1,marker:null,stickyTracking:!1,dataLabels:{verticalAlign:\"middle\"},turboThreshold:0,tooltip:{followPointer:!0,pointFormat:\"{point.name}: {point.y}<br/>\"},states:{normal:{animation:!0}}});r=g.extendClass(s,{applyOptions:function(a,b){var c=s.prototype.applyOptions.call(this,a,b);if(c.path&&typeof c.path===\"string\")c.path=c.options.path=g.splitPath(c.path);return c},onMouseOver:function(){clearTimeout(this.colorInterval);\ns.prototype.onMouseOver.call(this)},onMouseOut:function(){var a=this,b=+new Date,c=u(a.options.color),d=u(a.pointAttr.hover.fill),e=a.series.options.states.normal.animation,f=e&&(e.duration||500);if(f&&c.rgba.length===4&&d.rgba.length===4)delete a.pointAttr[\"\"].fill,clearTimeout(a.colorInterval),a.colorInterval=setInterval(function(){var e=(new Date-b)/f,h=a.graphic;e>1&&(e=1);h&&h.attr(\"fill\",x(d,c,e));e>=1&&clearTimeout(a.colorInterval)},13);s.prototype.onMouseOut.call(a)}});k.map=g.extendClass(k.scatter,\n{type:\"map\",pointAttrToOptions:{stroke:\"borderColor\",\"stroke-width\":\"borderWidth\",fill:\"color\"},colorKey:\"y\",pointClass:r,trackerGroups:[\"group\",\"markerGroup\",\"dataLabelsGroup\"],getSymbol:w,supportsDrilldown:!0,getExtremesFromAll:!0,useMapGeometry:!0,init:function(a){var b=this,c=a.options.legend.valueDecimals,d=[],e,f,i,h,j,o,m;o=a.options.legend.layout===\"horizontal\";g.Series.prototype.init.apply(this,arguments);j=b.options.colorRange;if(h=b.options.valueRanges)l(h,function(a){f=a.from;i=a.to;e=\n\"\";f===void 0?e=\"< \":i===void 0&&(e=\"> \");f!==void 0&&(e+=A(f,c));f!==void 0&&i!==void 0&&(e+=\" - \");i!==void 0&&(e+=A(i,c));d.push(g.extend({chart:b.chart,name:e,options:{},drawLegendSymbol:k.area.prototype.drawLegendSymbol,visible:!0,setState:function(){},setVisible:function(){}},a))}),b.legendItems=d;else if(j)f=j.from,i=j.to,h=j.fromLabel,j=j.toLabel,m=o?[0,0,1,0]:[0,1,0,0],o||(o=h,h=j,j=o),o={linearGradient:{x1:m[0],y1:m[1],x2:m[2],y2:m[3]},stops:[[0,f],[1,i]]},d=[{chart:b.chart,options:{},fromLabel:h,\ntoLabel:j,color:o,drawLegendSymbol:this.drawLegendSymbolGradient,visible:!0,setState:function(){},setVisible:function(){}}],b.legendItems=d},drawLegendSymbol:k.area.prototype.drawLegendSymbol,drawLegendSymbolGradient:function(a,b){var c=a.options.symbolPadding,d=n(a.options.padding,8),e,f,i=this.chart.renderer.fontMetrics(a.options.itemStyle.fontSize).h,h=a.options.layout===\"horizontal\",j;j=n(a.options.rectangleLength,200);h?(e=-(c/2),f=0):(e=-j+a.baseline-c/2,f=d+i);b.fromText=this.chart.renderer.text(b.fromLabel,\nf,e).attr({zIndex:2}).add(b.legendGroup);f=b.fromText.getBBox();b.legendSymbol=this.chart.renderer.rect(h?f.x+f.width+c:f.x-i-c,f.y,h?j:i,h?i:j,2).attr({zIndex:1}).add(b.legendGroup);j=b.legendSymbol.getBBox();b.toText=this.chart.renderer.text(b.toLabel,j.x+j.width+c,h?e:j.y+j.height-c).attr({zIndex:2}).add(b.legendGroup);e=b.toText.getBBox();h?(a.offsetWidth=f.width+j.width+e.width+c*2+d,a.itemY=i+d):(a.offsetWidth=Math.max(f.width,e.width)+c+j.width+d,a.itemY=j.height+d,a.itemX=c)},getBox:function(a){var b=\nNumber.MIN_VALUE,c=Number.MAX_VALUE,d=Number.MIN_VALUE,e=Number.MAX_VALUE;l(a||this.options.data,function(a){for(var i=a.path,h=i.length,j=!1,g=Number.MIN_VALUE,m=Number.MAX_VALUE,k=Number.MIN_VALUE,l=Number.MAX_VALUE;h--;)typeof i[h]===\"number\"&&!isNaN(i[h])&&(j?(g=Math.max(g,i[h]),m=Math.min(m,i[h])):(k=Math.max(k,i[h]),l=Math.min(l,i[h])),j=!j);a._maxX=g;a._minX=m;a._maxY=k;a._minY=l;b=Math.max(b,g);c=Math.min(c,m);d=Math.max(d,k);e=Math.min(e,l)});this.minY=e;this.maxY=d;this.minX=c;this.maxX=\nb},translatePath:function(a){var b=!1,c=this.xAxis,d=this.yAxis,e,a=[].concat(a);for(e=a.length;e--;)typeof a[e]===\"number\"&&(a[e]=b?Math.round(c.translate(a[e])):Math.round(d.len-d.translate(a[e])),b=!b);return a},setData:function(){g.Series.prototype.setData.apply(this,arguments);this.getBox()},translate:function(){var a=this,b=Number.MAX_VALUE,c=Number.MIN_VALUE;a.generatePoints();l(a.data,function(d){d.shapeType=\"path\";d.shapeArgs={d:a.translatePath(d.path)};if(typeof d.y===\"number\")if(d.y>c)c=\nd.y;else if(d.y<b)b=d.y});a.translateColors(b,c)},translateColors:function(a,b){var c=this.options,d=c.valueRanges,e=c.colorRange,f=this.colorKey,i,h;e&&(i=u(e.from),h=u(e.to));l(this.data,function(g){var k=g[f],m,l,n;if(d)for(n=d.length;n--;){if(m=d[n],i=m.from,h=m.to,(i===void 0||k>=i)&&(h===void 0||k<=h)){l=m.color;break}}else e&&k!==void 0&&(m=1-(b-k)/(b-a),l=k===null?c.nullColor:x(i,h,m));if(l)g.color=null,g.options.color=l})},drawGraph:w,drawDataLabels:w,drawPoints:function(){var a=this.xAxis,\nb=this.yAxis,c=this.colorKey;l(this.data,function(a){a.plotY=1;if(a[c]===null)a[c]=0,a.isNull=!0});k.column.prototype.drawPoints.apply(this);l(this.data,function(d){var e=d.dataLabels,f=a.toPixels(d._minX,!0),g=a.toPixels(d._maxX,!0),h=b.toPixels(d._minY,!0),j=b.toPixels(d._maxY,!0);d.plotX=Math.round(f+(g-f)*n(e&&e.anchorX,0.5));d.plotY=Math.round(h+(j-h)*n(e&&e.anchorY,0.5));d.isNull&&(d[c]=null)});g.Series.prototype.drawDataLabels.call(this)},animateDrilldown:function(a){var b=this.chart.plotBox,\nc=this.chart.drilldownLevels[this.chart.drilldownLevels.length-1],d=c.bBox,e=this.chart.options.drilldown.animation;if(!a)a=Math.min(d.width/b.width,d.height/b.height),c.shapeArgs={scaleX:a,scaleY:a,translateX:d.x,translateY:d.y},l(this.points,function(a){a.graphic.attr(c.shapeArgs).animate({scaleX:1,scaleY:1,translateX:0,translateY:0},e)}),delete this.animate},animateDrillupFrom:function(a){k.column.prototype.animateDrillupFrom.call(this,a)},animateDrillupTo:function(a){k.column.prototype.animateDrillupTo.call(this,\na)}});q.mapline=p(q.map,{lineWidth:1,backgroundColor:\"none\"});k.mapline=g.extendClass(k.map,{type:\"mapline\",pointAttrToOptions:{stroke:\"color\",\"stroke-width\":\"lineWidth\",fill:\"backgroundColor\"},drawLegendSymbol:k.line.prototype.drawLegendSymbol});q.mappoint=p(q.scatter,{dataLabels:{enabled:!0,format:\"{point.name}\",color:\"black\",style:{textShadow:\"0 0 5px white\"}}});k.mappoint=g.extendClass(k.scatter,{type:\"mappoint\"});g.Map=function(a,b){var c={endOnTick:!1,gridLineWidth:0,labels:{enabled:!1},lineWidth:0,\nminPadding:0,maxPadding:0,startOnTick:!1,tickWidth:0,title:null},d;d=a.series;a.series=null;a=p({chart:{type:\"map\",panning:\"xy\"},xAxis:c,yAxis:p(c,{reversed:!0})},a,{chart:{inverted:!1}});a.series=d;return new g.Chart(a,b)}})(Highcharts);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/map.src.js",
    "content": "/**\n * @license Map plugin v0.1 for Highcharts\n *\n * (c) 2011-2013 Torstein Hønsi\n *\n * License: www.highcharts.com/license\n */\n\n/* \n * See www.highcharts.com/studies/world-map.htm for use case.\n *\n * To do:\n * - Optimize long variable names and alias adapter methods and Highcharts namespace variables\n * - Zoom and pan GUI\n */\n(function (Highcharts) {\n\tvar UNDEFINED,\n\t\tAxis = Highcharts.Axis,\n\t\tChart = Highcharts.Chart,\n\t\tPoint = Highcharts.Point,\n\t\tPointer = Highcharts.Pointer,\n\t\teach = Highcharts.each,\n\t\textend = Highcharts.extend,\n\t\tmerge = Highcharts.merge,\n\t\tpick = Highcharts.pick,\n\t\tnumberFormat = Highcharts.numberFormat,\n\t\tdefaultOptions = Highcharts.getOptions(),\n\t\tseriesTypes = Highcharts.seriesTypes,\n\t\tplotOptions = defaultOptions.plotOptions,\n\t\twrap = Highcharts.wrap,\n\t\tColor = Highcharts.Color,\n\t\tnoop = function () {};\n\n\t\n\n\t/*\n\t * Return an intermediate color between two colors, according to pos where 0\n\t * is the from color and 1 is the to color\n\t */\n\tfunction tweenColors(from, to, pos) {\n\t\tvar i = 4,\n\t\t\trgba = [];\n\n\t\twhile (i--) {\n\t\t\trgba[i] = Math.round(\n\t\t\t\tto.rgba[i] + (from.rgba[i] - to.rgba[i]) * (1 - pos)\n\t\t\t);\n\t\t}\n\t\treturn 'rgba(' + rgba.join(',') + ')';\n\t}\n\n\t// Set the default map navigation options\n\tdefaultOptions.mapNavigation = {\n\t\tbuttonOptions: {\n\t\t\talign: 'right',\n\t\t\tverticalAlign: 'bottom',\n\t\t\tx: 0,\n\t\t\twidth: 18,\n\t\t\theight: 18,\n\t\t\tstyle: {\n\t\t\t\tfontSize: '15px',\n\t\t\t\tfontWeight: 'bold',\n\t\t\t\ttextAlign: 'center'\n\t\t\t}\n\t\t},\n\t\tbuttons: {\n\t\t\tzoomIn: {\n\t\t\t\tonclick: function () {\n\t\t\t\t\tthis.mapZoom(0.5);\n\t\t\t\t},\n\t\t\t\ttext: '+',\n\t\t\t\ty: -32\n\t\t\t},\n\t\t\tzoomOut: {\n\t\t\t\tonclick: function () {\n\t\t\t\t\tthis.mapZoom(2);\n\t\t\t\t},\n\t\t\t\ttext: '-',\n\t\t\t\ty: 0\n\t\t\t}\n\t\t}\n\t\t// enableButtons: false,\n\t\t// enableTouchZoom: false,\n\t\t// zoomOnDoubleClick: false,\n\t\t// zoomOnMouseWheel: false\n\n\t};\n\t\n\t/**\n\t * Utility for reading SVG paths directly.\n\t */\n\tHighcharts.splitPath = function (path) {\n\t\tvar i;\n\n\t\t// Move letters apart\n\t\tpath = path.replace(/([A-Za-z])/g, ' $1 ');\n\t\t// Trim\n\t\tpath = path.replace(/^\\s*/, \"\").replace(/\\s*$/, \"\");\n\t\t\n\t\t// Split on spaces and commas\n\t\tpath = path.split(/[ ,]+/);\n\t\t\n\t\t// Parse numbers\n\t\tfor (i = 0; i < path.length; i++) {\n\t\t\tif (!/[a-zA-Z]/.test(path[i])) {\n\t\t\t\tpath[i] = parseFloat(path[i]);\n\t\t\t}\n\t\t}\n\t\treturn path;\n\t};\n\n\t// A placeholder for map definitions\n\tHighcharts.maps = {};\n\t\n\t/**\n\t * Override to use the extreme coordinates from the SVG shape, not the\n\t * data values\n\t */\n\twrap(Axis.prototype, 'getSeriesExtremes', function (proceed) {\n\t\tvar isXAxis = this.isXAxis,\n\t\t\tdataMin,\n\t\t\tdataMax,\n\t\t\txData = [];\n\n\t\t// Remove the xData array and cache it locally so that the proceed method doesn't use it\n\t\teach(this.series, function (series, i) {\n\t\t\tif (series.useMapGeometry) {\n\t\t\t\txData[i] = series.xData;\n\t\t\t\tseries.xData = [];\n\t\t\t}\n\t\t});\n\n\t\t// Call base to reach normal cartesian series (like mappoint)\n\t\tproceed.call(this);\n\n\t\t// Run extremes logic for map and mapline\n\t\tdataMin = pick(this.dataMin, Number.MAX_VALUE);\n\t\tdataMax = pick(this.dataMax, Number.MIN_VALUE);\n\t\teach(this.series, function (series, i) {\n\t\t\tif (series.useMapGeometry) {\n\t\t\t\tdataMin = Math.min(dataMin, series[isXAxis ? 'minX' : 'minY']);\n\t\t\t\tdataMax = Math.max(dataMax, series[isXAxis ? 'maxX' : 'maxY']);\n\t\t\t\tseries.xData = xData[i]; // Reset xData array\n\t\t\t}\n\t\t});\n\t\t\n\t\tthis.dataMin = dataMin;\n\t\tthis.dataMax = dataMax;\n\t});\n\t\n\t/**\n\t * Override axis translation to make sure the aspect ratio is always kept\n\t */\n\twrap(Axis.prototype, 'setAxisTranslation', function (proceed) {\n\t\tvar chart = this.chart,\n\t\t\tmapRatio,\n\t\t\tplotRatio = chart.plotWidth / chart.plotHeight,\n\t\t\tisXAxis = this.isXAxis,\n\t\t\tadjustedAxisLength,\n\t\t\txAxis = chart.xAxis[0],\n\t\t\tpadAxis;\n\t\t\n\t\t// Run the parent method\n\t\tproceed.call(this);\n\t\t\n\t\t// On Y axis, handle both\n\t\tif (chart.options.chart.type === 'map' && !isXAxis && xAxis.transA !== UNDEFINED) {\n\t\t\t\n\t\t\t// Use the same translation for both axes\n\t\t\tthis.transA = xAxis.transA = Math.min(this.transA, xAxis.transA);\n\t\t\t\n\t\t\tmapRatio = (xAxis.max - xAxis.min) / (this.max - this.min);\n\t\t\t\n\t\t\t// What axis to pad to put the map in the middle\n\t\t\tpadAxis = mapRatio > plotRatio ? this : xAxis;\n\t\t\t\n\t\t\t// Pad it\n\t\t\tadjustedAxisLength = (padAxis.max - padAxis.min) * padAxis.transA;\n\t\t\tpadAxis.minPixelPadding = (padAxis.len - adjustedAxisLength) / 2;\n\t\t}\n\t});\n\n\n\t//--- Start zooming and panning features\n\n\twrap(Chart.prototype, 'render', function (proceed) {\n\t\tvar chart = this,\n\t\t\tmapNavigation = chart.options.mapNavigation;\n\n\t\tproceed.call(chart);\n\n\t\t// Render the plus and minus buttons\n\t\tchart.renderMapNavigation();\n\n\t\t// Add the double click event\n\t\tif (mapNavigation.zoomOnDoubleClick) {\n\t\t\tHighcharts.addEvent(chart.container, 'dblclick', function (e) {\n\t\t\t\tchart.pointer.onContainerDblClick(e);\n\t\t\t});\n\t\t}\n\n\t\t// Add the mousewheel event\n\t\tif (mapNavigation.zoomOnMouseWheel) {\n\t\t\tHighcharts.addEvent(chart.container, document.onmousewheel === undefined ? 'DOMMouseScroll' : 'mousewheel', function (e) {\n\t\t\t\tchart.pointer.onContainerMouseWheel(e);\n\t\t\t});\n\t\t}\n\t});\n\n\t// Extend the Pointer\n\textend(Pointer.prototype, {\n\n\t\t/**\n\t\t * The event handler for the doubleclick event\n\t\t */\n\t\tonContainerDblClick: function (e) {\n\t\t\tvar chart = this.chart;\n\n\t\t\te = this.normalize(e);\n\n\t\t\tif (chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) {\n\t\t\t\tchart.mapZoom(\n\t\t\t\t\t0.5,\n\t\t\t\t\tchart.xAxis[0].toValue(e.chartX),\n\t\t\t\t\tchart.yAxis[0].toValue(e.chartY)\n\t\t\t\t);\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * The event handler for the mouse scroll event\n\t\t */\n\t\tonContainerMouseWheel: function (e) {\n\t\t\tvar chart = this.chart,\n\t\t\t\tdelta;\n\n\t\t\te = this.normalize(e);\n\n\t\t\t// Firefox uses e.detail, WebKit and IE uses wheelDelta\n\t\t\tdelta = e.detail || -(e.wheelDelta / 120);\n\t\t\tif (chart.isInsidePlot(e.chartX - chart.plotLeft, e.chartY - chart.plotTop)) {\n\t\t\t\tchart.mapZoom(\n\t\t\t\t\tdelta > 0 ? 2 : 0.5,\n\t\t\t\t\tchart.xAxis[0].toValue(e.chartX),\n\t\t\t\t\tchart.yAxis[0].toValue(e.chartY)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t});\n\t// Implement the pinchType option\n\twrap(Pointer.prototype, 'init', function (proceed, chart, options) {\n\n\t\tproceed.call(this, chart, options);\n\n\t\t// Pinch status\n\t\tif (options.mapNavigation.enableTouchZoom) {\n\t\t\tthis.pinchX = this.pinchHor = \n\t\t\t\tthis.pinchY = this.pinchVert = true;\n\t\t}\n\t});\n\n\t// Add events to the Chart object itself\n\textend(Chart.prototype, {\n\t\trenderMapNavigation: function () {\n\t\t\tvar chart = this,\n\t\t\t\toptions = this.options.mapNavigation,\n\t\t\t\tbuttons = options.buttons,\n\t\t\t\tn,\n\t\t\t\tbutton,\n\t\t\t\tbuttonOptions,\n\t\t\t\touterHandler = function () { \n\t\t\t\t\tthis.handler.call(chart); \n\t\t\t\t};\n\n\t\t\tif (options.enableButtons) {\n\t\t\t\tfor (n in buttons) {\n\t\t\t\t\tif (buttons.hasOwnProperty(n)) {\n\t\t\t\t\t\tbuttonOptions = merge(options.buttonOptions, buttons[n]);\n\n\t\t\t\t\t\tbutton = chart.renderer.button(buttonOptions.text, 0, 0, outerHandler)\n\t\t\t\t\t\t\t.attr({\n\t\t\t\t\t\t\t\twidth: buttonOptions.width,\n\t\t\t\t\t\t\t\theight: buttonOptions.height\n\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t.css(buttonOptions.style)\n\t\t\t\t\t\t\t.add();\n\t\t\t\t\t\tbutton.handler = buttonOptions.onclick;\n\t\t\t\t\t\tbutton.align(extend(buttonOptions, { width: button.width, height: button.height }), null, 'spacingBox');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Fit an inner box to an outer. If the inner box overflows left or right, align it to the sides of the\n\t\t * outer. If it overflows both sides, fit it within the outer. This is a pattern that occurs more places\n\t\t * in Highcharts, perhaps it should be elevated to a common utility function.\n\t\t */\n\t\tfitToBox: function (inner, outer) {\n\t\t\teach([['x', 'width'], ['y', 'height']], function (dim) {\n\t\t\t\tvar pos = dim[0],\n\t\t\t\t\tsize = dim[1];\n\t\t\t\tif (inner[pos] + inner[size] > outer[pos] + outer[size]) { // right overflow\n\t\t\t\t\tif (inner[size] > outer[size]) { // the general size is greater, fit fully to outer\n\t\t\t\t\t\tinner[size] = outer[size];\n\t\t\t\t\t\tinner[pos] = outer[pos];\n\t\t\t\t\t} else { // align right\n\t\t\t\t\t\tinner[pos] = outer[pos] + outer[size] - inner[size];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (inner[size] > outer[size]) {\n\t\t\t\t\tinner[size] = outer[size];\n\t\t\t\t}\n\t\t\t\tif (inner[pos] < outer[pos]) {\n\t\t\t\t\tinner[pos] = outer[pos];\n\t\t\t\t}\n\t\t\t\t\n\t\t\t});\n\n\t\t\treturn inner;\n\t\t},\n\n\t\t/**\n\t\t * Zoom the map in or out by a certain amount. Less than 1 zooms in, greater than 1 zooms out.\n\t\t */\n\t\tmapZoom: function (howMuch, centerXArg, centerYArg) {\n\n\t\t\tif (this.isMapZooming) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tvar chart = this,\n\t\t\t\txAxis = chart.xAxis[0],\n\t\t\t\txRange = xAxis.max - xAxis.min,\n\t\t\t\tcenterX = pick(centerXArg, xAxis.min + xRange / 2),\n\t\t\t\tnewXRange = xRange * howMuch,\n\t\t\t\tyAxis = chart.yAxis[0],\n\t\t\t\tyRange = yAxis.max - yAxis.min,\n\t\t\t\tcenterY = pick(centerYArg, yAxis.min + yRange / 2),\n\t\t\t\tnewYRange = yRange * howMuch,\n\t\t\t\tnewXMin = centerX - newXRange / 2,\n\t\t\t\tnewYMin = centerY - newYRange / 2,\n\t\t\t\tanimation = pick(chart.options.chart.animation, true),\n\t\t\t\tdelay,\n\t\t\t\tnewExt = chart.fitToBox({\n\t\t\t\t\tx: newXMin,\n\t\t\t\t\ty: newYMin,\n\t\t\t\t\twidth: newXRange,\n\t\t\t\t\theight: newYRange\n\t\t\t\t}, {\n\t\t\t\t\tx: xAxis.dataMin,\n\t\t\t\t\ty: yAxis.dataMin,\n\t\t\t\t\twidth: xAxis.dataMax - xAxis.dataMin,\n\t\t\t\t\theight: yAxis.dataMax - yAxis.dataMin\n\t\t\t\t});\n\n\t\t\txAxis.setExtremes(newExt.x, newExt.x + newExt.width, false);\n\t\t\tyAxis.setExtremes(newExt.y, newExt.y + newExt.height, false);\n\n\t\t\t// Prevent zooming until this one is finished animating\n\t\t\tdelay = animation ? animation.duration || 500 : 0;\n\t\t\tif (delay) {\n\t\t\t\tchart.isMapZooming = true;\n\t\t\t\tsetTimeout(function () {\n\t\t\t\t\tchart.isMapZooming = false;\n\t\t\t\t}, delay);\n\t\t\t}\n\n\t\t\tchart.redraw();\n\t\t}\n\t});\n\t\n\t/**\n\t * Extend the default options with map options\n\t */\n\tplotOptions.map = merge(plotOptions.scatter, {\n\t\tanimation: false, // makes the complex shapes slow\n\t\tnullColor: '#F8F8F8',\n\t\tborderColor: 'silver',\n\t\tborderWidth: 1,\n\t\tmarker: null,\n\t\tstickyTracking: false,\n\t\tdataLabels: {\n\t\t\tverticalAlign: 'middle'\n\t\t},\n\t\tturboThreshold: 0,\n\t\ttooltip: {\n\t\t\tfollowPointer: true,\n\t\t\tpointFormat: '{point.name}: {point.y}<br/>'\n\t\t},\n\t\tstates: {\n\t\t\tnormal: {\n\t\t\t\tanimation: true\n\t\t\t}\n\t\t}\n\t});\n\n\tvar MapAreaPoint = Highcharts.extendClass(Point, {\n\t\t/**\n\t\t * Extend the Point object to split paths\n\t\t */\n\t\tapplyOptions: function (options, x) {\n\n\t\t\tvar point = Point.prototype.applyOptions.call(this, options, x);\n\n\t\t\tif (point.path && typeof point.path === 'string') {\n\t\t\t\tpoint.path = point.options.path = Highcharts.splitPath(point.path);\n\t\t\t}\n\n\t\t\treturn point;\n\t\t},\n\t\t/**\n\t\t * Stop the fade-out \n\t\t */\n\t\tonMouseOver: function () {\n\t\t\tclearTimeout(this.colorInterval);\n\t\t\tPoint.prototype.onMouseOver.call(this);\n\t\t},\n\t\t/**\n\t\t * Custom animation for tweening out the colors. Animation reduces blinking when hovering\n\t\t * over islands and coast lines. We run a custom implementation of animation becuase we\n\t\t * need to be able to run this independently from other animations like zoom redraw. Also,\n\t\t * adding color animation to the adapters would introduce almost the same amount of code.\n\t\t */\n\t\tonMouseOut: function () {\n\t\t\tvar point = this,\n\t\t\t\tstart = +new Date(),\n\t\t\t\tnormalColor = Color(point.options.color),\n\t\t\t\thoverColor = Color(point.pointAttr.hover.fill),\n\t\t\t\tanimation = point.series.options.states.normal.animation,\n\t\t\t\tduration = animation && (animation.duration || 500);\n\n\t\t\tif (duration && normalColor.rgba.length === 4 && hoverColor.rgba.length === 4) {\n\t\t\t\tdelete point.pointAttr[''].fill; // avoid resetting it in Point.setState\n\n\t\t\t\tclearTimeout(point.colorInterval);\n\t\t\t\tpoint.colorInterval = setInterval(function () {\n\t\t\t\t\tvar pos = (new Date() - start) / duration,\n\t\t\t\t\t\tgraphic = point.graphic;\n\t\t\t\t\tif (pos > 1) {\n\t\t\t\t\t\tpos = 1;\n\t\t\t\t\t}\n\t\t\t\t\tif (graphic) {\n\t\t\t\t\t\tgraphic.attr('fill', tweenColors(hoverColor, normalColor, pos));\n\t\t\t\t\t}\n\t\t\t\t\tif (pos >= 1) {\n\t\t\t\t\t\tclearTimeout(point.colorInterval);\n\t\t\t\t\t}\n\t\t\t\t}, 13);\n\t\t\t}\n\t\t\tPoint.prototype.onMouseOut.call(point);\n\t\t}\n\t});\n\n\t/**\n\t * Add the series type\n\t */\n\tseriesTypes.map = Highcharts.extendClass(seriesTypes.scatter, {\n\t\ttype: 'map',\n\t\tpointAttrToOptions: { // mapping between SVG attributes and the corresponding options\n\t\t\tstroke: 'borderColor',\n\t\t\t'stroke-width': 'borderWidth',\n\t\t\tfill: 'color'\n\t\t},\n\t\tcolorKey: 'y',\n\t\tpointClass: MapAreaPoint,\n\t\ttrackerGroups: ['group', 'markerGroup', 'dataLabelsGroup'],\n\t\tgetSymbol: noop,\n\t\tsupportsDrilldown: true,\n\t\tgetExtremesFromAll: true,\n\t\tuseMapGeometry: true, // get axis extremes from paths, not values\n\t\tinit: function (chart) {\n\t\t\tvar series = this,\n\t\t\t\tvalueDecimals = chart.options.legend.valueDecimals,\n\t\t\t\tlegendItems = [],\n\t\t\t\tname,\n\t\t\t\tfrom,\n\t\t\t\tto,\n\t\t\t\tfromLabel,\n\t\t\t\ttoLabel,\n\t\t\t\tcolorRange,\n\t\t\t\tvalueRanges,\n\t\t\t\tgradientColor,\n\t\t\t\tgrad,\n\t\t\t\ttmpLabel,\n\t\t\t\thorizontal = chart.options.legend.layout === 'horizontal';\n\n\t\t\t\n\t\t\tHighcharts.Series.prototype.init.apply(this, arguments);\n\t\t\tcolorRange = series.options.colorRange;\n\t\t\tvalueRanges = series.options.valueRanges;\n\n\t\t\tif (valueRanges) {\n\t\t\t\teach(valueRanges, function (range) {\n\t\t\t\t\tfrom = range.from;\n\t\t\t\t\tto = range.to;\n\t\t\t\t\t\n\t\t\t\t\t// Assemble the default name. This can be overridden by legend.options.labelFormatter\n\t\t\t\t\tname = '';\n\t\t\t\t\tif (from === UNDEFINED) {\n\t\t\t\t\t\tname = '< ';\n\t\t\t\t\t} else if (to === UNDEFINED) {\n\t\t\t\t\t\tname = '> ';\n\t\t\t\t\t}\n\t\t\t\t\tif (from !== UNDEFINED) {\n\t\t\t\t\t\tname += numberFormat(from, valueDecimals);\n\t\t\t\t\t}\n\t\t\t\t\tif (from !== UNDEFINED && to !== UNDEFINED) {\n\t\t\t\t\t\tname += ' - ';\n\t\t\t\t\t}\n\t\t\t\t\tif (to !== UNDEFINED) {\n\t\t\t\t\t\tname += numberFormat(to, valueDecimals);\n\t\t\t\t\t}\n\t\t\t\t\t\n\t\t\t\t\t// Add a mock object to the legend items\n\t\t\t\t\tlegendItems.push(Highcharts.extend({\n\t\t\t\t\t\tchart: series.chart,\n\t\t\t\t\t\tname: name,\n\t\t\t\t\t\toptions: {},\n\t\t\t\t\t\tdrawLegendSymbol: seriesTypes.area.prototype.drawLegendSymbol,\n\t\t\t\t\t\tvisible: true,\n\t\t\t\t\t\tsetState: function () {},\n\t\t\t\t\t\tsetVisible: function () {}\n\t\t\t\t\t}, range));\n\t\t\t\t});\n\t\t\t\tseries.legendItems = legendItems;\n\n\t\t\t} else if (colorRange) {\n\n\t\t\t\tfrom = colorRange.from;\n\t\t\t\tto = colorRange.to;\n\t\t\t\tfromLabel = colorRange.fromLabel;\n\t\t\t\ttoLabel = colorRange.toLabel;\n\n\t\t\t\t// Flips linearGradient variables and label text.\n\t\t\t\tgrad = horizontal ? [0, 0, 1, 0] : [0, 1, 0, 0]; \n\t\t\t\tif (!horizontal) {\n\t\t\t\t\ttmpLabel = fromLabel;\n\t\t\t\t\tfromLabel = toLabel;\n\t\t\t\t\ttoLabel = tmpLabel;\n\t\t\t\t} \n\n\t\t\t\t// Creates color gradient.\n\t\t\t\tgradientColor = {\n\t\t\t\t\tlinearGradient: { x1: grad[0], y1: grad[1], x2: grad[2], y2: grad[3] },\n\t\t\t\t\tstops: \n\t\t\t\t\t[\n\t\t\t\t\t\t[0, from],\n\t\t\t\t\t\t[1, to]\n\t\t\t\t\t]\n\t\t\t\t};\n\n\t\t\t\t// Add a mock object to the legend items.\n\t\t\t\tlegendItems = [{\n\t\t\t\t\tchart: series.chart,\n\t\t\t\t\toptions: {},\n\t\t\t\t\tfromLabel: fromLabel,\n\t\t\t\t\ttoLabel: toLabel,\n\t\t\t\t\tcolor: gradientColor,\n\t\t\t\t\tdrawLegendSymbol: this.drawLegendSymbolGradient,\n\t\t\t\t\tvisible: true,\n\t\t\t\t\tsetState: function () {},\n\t\t\t\t\tsetVisible: function () {}\n\t\t\t\t}];\n\n\t\t\t\tseries.legendItems = legendItems;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * If neither valueRanges nor colorRanges are defined, use basic area symbol.\n\t\t */\n\t\tdrawLegendSymbol: seriesTypes.area.prototype.drawLegendSymbol,\n\n\t\t/**\n\t\t * Gets the series' symbol in the legend and extended legend with more information.\n\t\t * \n\t\t * @param {Object} legend The legend object\n\t\t * @param {Object} item The series (this) or point\n\t\t */\n\t\tdrawLegendSymbolGradient: function (legend, item) {\n\t\t\tvar spacing = legend.options.symbolPadding,\n\t\t\t\tpadding = pick(legend.options.padding, 8),\n\t\t\t\tpositionY,\n\t\t\t\tpositionX,\n\t\t\t\tgradientSize = this.chart.renderer.fontMetrics(legend.options.itemStyle.fontSize).h,\n\t\t\t\thorizontal = legend.options.layout === 'horizontal',\n\t\t\t\tbox1,\n\t\t\t\tbox2,\n\t\t\t\tbox3,\n\t\t\t\trectangleLength = pick(legend.options.rectangleLength, 200);\n\n\t\t\t// Set local variables based on option.\n\t\t\tif (horizontal) {\n\t\t\t\tpositionY = -(spacing / 2);\n\t\t\t\tpositionX = 0;\n\t\t\t} else {\n\t\t\t\tpositionY = -rectangleLength + legend.baseline - (spacing / 2);\n\t\t\t\tpositionX = padding + gradientSize;\n\t\t\t}\n\n\t\t\t// Creates the from text.\n\t\t\titem.fromText = this.chart.renderer.text(\n\t\t\t\t\titem.fromLabel,\t// Text.\n\t\t\t\t\tpositionX,\t\t// Lower left x.\n\t\t\t\t\tpositionY\t\t// Lower left y.\n\t\t\t\t).attr({\n\t\t\t\t\tzIndex: 2\n\t\t\t\t}).add(item.legendGroup);\n\t\t\tbox1 = item.fromText.getBBox();\n\n\t\t\t// Creates legend symbol.\n\t\t\t// Ternary changes variables based on option.\n\t\t\titem.legendSymbol = this.chart.renderer.rect(\n\t\t\t\thorizontal ? box1.x + box1.width + spacing : box1.x - gradientSize - spacing,\t\t// Upper left x.\n\t\t\t\tbox1.y,\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// Upper left y.\n\t\t\t\thorizontal ? rectangleLength : gradientSize,\t\t\t\t\t\t\t\t\t\t\t// Width.\n\t\t\t\thorizontal ? gradientSize : rectangleLength,\t\t\t\t\t\t\t\t\t\t// Height.\n\t\t\t\t2\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t// Corner radius.\n\t\t\t).attr({\n\t\t\t\tzIndex: 1\n\t\t\t}).add(item.legendGroup);\n\t\t\tbox2 = item.legendSymbol.getBBox();\n\n\t\t\t// Creates the to text.\n\t\t\t// Vertical coordinate changed based on option.\n\t\t\titem.toText = this.chart.renderer.text(\n\t\t\t\t\titem.toLabel,\n\t\t\t\t\tbox2.x + box2.width + spacing,\n\t\t\t\t\thorizontal ? positionY : box2.y + box2.height - spacing\n\t\t\t\t).attr({\n\t\t\t\t\tzIndex: 2\n\t\t\t\t}).add(item.legendGroup);\n\t\t\tbox3 = item.toText.getBBox();\n\n\t\t\t// Changes legend box settings based on option.\n\t\t\tif (horizontal) {\n\t\t\t\tlegend.offsetWidth = box1.width + box2.width + box3.width + (spacing * 2) + padding;\n\t\t\t\tlegend.itemY = gradientSize + padding;\n\t\t\t} else {\n\t\t\t\tlegend.offsetWidth = Math.max(box1.width, box3.width) + (spacing) + box2.width + padding;\n\t\t\t\tlegend.itemY = box2.height + padding;\n\t\t\t\tlegend.itemX = spacing;\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Get the bounding box of all paths in the map combined.\n\t\t */\n\t\tgetBox: function (paths) {\n\t\t\tvar maxX = Number.MIN_VALUE, \n\t\t\t\tminX =  Number.MAX_VALUE, \n\t\t\t\tmaxY = Number.MIN_VALUE, \n\t\t\t\tminY =  Number.MAX_VALUE;\n\t\t\t\n\t\t\t\n\t\t\t// Find the bounding box\n\t\t\teach(paths || this.options.data, function (point) {\n\t\t\t\tvar path = point.path,\n\t\t\t\t\ti = path.length,\n\t\t\t\t\teven = false, // while loop reads from the end\n\t\t\t\t\tpointMaxX = Number.MIN_VALUE, \n\t\t\t\t\tpointMinX =  Number.MAX_VALUE, \n\t\t\t\t\tpointMaxY = Number.MIN_VALUE, \n\t\t\t\t\tpointMinY =  Number.MAX_VALUE;\n\t\t\t\t\t\n\t\t\t\twhile (i--) {\n\t\t\t\t\tif (typeof path[i] === 'number' && !isNaN(path[i])) {\n\t\t\t\t\t\tif (even) { // even = x\n\t\t\t\t\t\t\tpointMaxX = Math.max(pointMaxX, path[i]);\n\t\t\t\t\t\t\tpointMinX = Math.min(pointMinX, path[i]);\n\t\t\t\t\t\t} else { // odd = Y\n\t\t\t\t\t\t\tpointMaxY = Math.max(pointMaxY, path[i]);\n\t\t\t\t\t\t\tpointMinY = Math.min(pointMinY, path[i]);\n\t\t\t\t\t\t}\n\t\t\t\t\t\teven = !even;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Cache point bounding box for use to position data labels\n\t\t\t\tpoint._maxX = pointMaxX;\n\t\t\t\tpoint._minX = pointMinX;\n\t\t\t\tpoint._maxY = pointMaxY;\n\t\t\t\tpoint._minY = pointMinY;\n\n\t\t\t\tmaxX = Math.max(maxX, pointMaxX);\n\t\t\t\tminX = Math.min(minX, pointMinX);\n\t\t\t\tmaxY = Math.max(maxY, pointMaxY);\n\t\t\t\tminY = Math.min(minY, pointMinY);\n\t\t\t});\n\t\t\tthis.minY = minY;\n\t\t\tthis.maxY = maxY;\n\t\t\tthis.minX = minX;\n\t\t\tthis.maxX = maxX;\n\t\t\t\n\t\t},\n\t\t\n\t\t\n\t\t\n\t\t/**\n\t\t * Translate the path so that it automatically fits into the plot area box\n\t\t * @param {Object} path\n\t\t */\n\t\ttranslatePath: function (path) {\n\t\t\t\n\t\t\tvar series = this,\n\t\t\t\teven = false, // while loop reads from the end\n\t\t\t\txAxis = series.xAxis,\n\t\t\t\tyAxis = series.yAxis,\n\t\t\t\ti;\n\t\t\t\t\n\t\t\t// Preserve the original\n\t\t\tpath = [].concat(path);\n\t\t\t\t\n\t\t\t// Do the translation\n\t\t\ti = path.length;\n\t\t\twhile (i--) {\n\t\t\t\tif (typeof path[i] === 'number') {\n\t\t\t\t\tif (even) { // even = x\n\t\t\t\t\t\tpath[i] = Math.round(xAxis.translate(path[i]));\n\t\t\t\t\t} else { // odd = Y\n\t\t\t\t\t\tpath[i] = Math.round(yAxis.len - yAxis.translate(path[i]));\n\t\t\t\t\t}\n\t\t\t\t\teven = !even;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn path;\n\t\t},\n\t\t\n\t\tsetData: function () {\n\t\t\tHighcharts.Series.prototype.setData.apply(this, arguments);\n\t\t\tthis.getBox();\n\t\t},\n\t\t\n\t\t/**\n\t\t * Add the path option for data points. Find the max value for color calculation.\n\t\t */\n\t\ttranslate: function () {\n\t\t\tvar series = this,\n\t\t\t\tdataMin = Number.MAX_VALUE,\n\t\t\t\tdataMax = Number.MIN_VALUE;\n\t\n\t\t\tseries.generatePoints();\n\t\n\t\t\teach(series.data, function (point) {\n\t\t\t\t\n\t\t\t\tpoint.shapeType = 'path';\n\t\t\t\tpoint.shapeArgs = {\n\t\t\t\t\td: series.translatePath(point.path)\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\t// TODO: do point colors in drawPoints instead of point.init\n\t\t\t\tif (typeof point.y === 'number') {\n\t\t\t\t\tif (point.y > dataMax) {\n\t\t\t\t\t\tdataMax = point.y;\n\t\t\t\t\t} else if (point.y < dataMin) {\n\t\t\t\t\t\tdataMin = point.y;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t});\n\t\t\t\n\t\t\tseries.translateColors(dataMin, dataMax);\n\t\t},\n\t\t\n\t\t/**\n\t\t * In choropleth maps, the color is a result of the value, so this needs translation too\n\t\t */\n\t\ttranslateColors: function (dataMin, dataMax) {\n\t\t\t\n\t\t\tvar seriesOptions = this.options,\n\t\t\t\tvalueRanges = seriesOptions.valueRanges,\n\t\t\t\tcolorRange = seriesOptions.colorRange,\n\t\t\t\tcolorKey = this.colorKey,\n\t\t\t\tfrom,\n\t\t\t\tto;\n\n\t\t\tif (colorRange) {\n\t\t\t\tfrom = Color(colorRange.from);\n\t\t\t\tto = Color(colorRange.to);\n\t\t\t}\n\t\t\t\n\t\t\teach(this.data, function (point) {\n\t\t\t\tvar value = point[colorKey],\n\t\t\t\t\trange,\n\t\t\t\t\tcolor,\n\t\t\t\t\ti,\n\t\t\t\t\tpos;\n\n\t\t\t\tif (valueRanges) {\n\t\t\t\t\ti = valueRanges.length;\n\t\t\t\t\twhile (i--) {\n\t\t\t\t\t\trange = valueRanges[i];\n\t\t\t\t\t\tfrom = range.from;\n\t\t\t\t\t\tto = range.to;\n\t\t\t\t\t\tif ((from === UNDEFINED || value >= from) && (to === UNDEFINED || value <= to)) {\n\t\t\t\t\t\t\tcolor = range.color;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\n\t\t\t\t\t}\n\t\t\t\t} else if (colorRange && value !== undefined) {\n\n\t\t\t\t\tpos = 1 - ((dataMax - value) / (dataMax - dataMin));\n\t\t\t\t\tcolor = value === null ? seriesOptions.nullColor : tweenColors(from, to, pos);\n\t\t\t\t}\n\n\t\t\t\tif (color) {\n\t\t\t\t\tpoint.color = null; // reset from previous drilldowns, use of the same data options\n\t\t\t\t\tpoint.options.color = color;\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\t\t\n\t\tdrawGraph: noop,\n\t\t\n\t\t/**\n\t\t * We need the points' bounding boxes in order to draw the data labels, so \n\t\t * we skip it now and call if from drawPoints instead.\n\t\t */\n\t\tdrawDataLabels: noop,\n\t\t\n\t\t/** \n\t\t * Use the drawPoints method of column, that is able to handle simple shapeArgs.\n\t\t * Extend it by assigning the tooltip position.\n\t\t */\n\t\tdrawPoints: function () {\n\t\t\tvar series = this,\n\t\t\t\txAxis = series.xAxis,\n\t\t\t\tyAxis = series.yAxis,\n\t\t\t\tcolorKey = series.colorKey;\n\t\t\t\n\t\t\t// Make points pass test in drawing\n\t\t\teach(series.data, function (point) {\n\t\t\t\tpoint.plotY = 1; // pass null test in column.drawPoints\n\t\t\t\tif (point[colorKey] === null) {\n\t\t\t\t\tpoint[colorKey] = 0;\n\t\t\t\t\tpoint.isNull = true;\n\t\t\t\t}\n\t\t\t});\n\t\t\t\n\t\t\t// Draw them\n\t\t\tseriesTypes.column.prototype.drawPoints.apply(series);\n\t\t\t\n\t\t\teach(series.data, function (point) {\n\n\t\t\t\tvar dataLabels = point.dataLabels,\n\t\t\t\t\tminX = xAxis.toPixels(point._minX, true),\n\t\t\t\t\tmaxX = xAxis.toPixels(point._maxX, true),\n\t\t\t\t\tminY = yAxis.toPixels(point._minY, true),\n\t\t\t\t\tmaxY = yAxis.toPixels(point._maxY, true);\n\n\t\t\t\tpoint.plotX = Math.round(minX + (maxX - minX) * pick(dataLabels && dataLabels.anchorX, 0.5));\n\t\t\t\tpoint.plotY = Math.round(minY + (maxY - minY) * pick(dataLabels && dataLabels.anchorY, 0.5)); \n\t\t\t\t\n\t\t\t\t\n\t\t\t\t// Reset escaped null points\n\t\t\t\tif (point.isNull) {\n\t\t\t\t\tpoint[colorKey] = null;\n\t\t\t\t}\n\t\t\t});\n\n\t\t\t// Now draw the data labels\n\t\t\tHighcharts.Series.prototype.drawDataLabels.call(series);\n\t\t\t\n\t\t},\n\n\t\t/**\n\t\t * Animate in the new series from the clicked point in the old series.\n\t\t * Depends on the drilldown.js module\n\t\t */\n\t\tanimateDrilldown: function (init) {\n\t\t\tvar toBox = this.chart.plotBox,\n\t\t\t\tlevel = this.chart.drilldownLevels[this.chart.drilldownLevels.length - 1],\n\t\t\t\tfromBox = level.bBox,\n\t\t\t\tanimationOptions = this.chart.options.drilldown.animation,\n\t\t\t\tscale;\n\t\t\t\t\n\t\t\tif (!init) {\n\n\t\t\t\tscale = Math.min(fromBox.width / toBox.width, fromBox.height / toBox.height);\n\t\t\t\tlevel.shapeArgs = {\n\t\t\t\t\tscaleX: scale,\n\t\t\t\t\tscaleY: scale,\n\t\t\t\t\ttranslateX: fromBox.x,\n\t\t\t\t\ttranslateY: fromBox.y\n\t\t\t\t};\n\t\t\t\t\n\t\t\t\t// TODO: Animate this.group instead\n\t\t\t\teach(this.points, function (point) {\n\n\t\t\t\t\tpoint.graphic\n\t\t\t\t\t\t.attr(level.shapeArgs)\n\t\t\t\t\t\t.animate({\n\t\t\t\t\t\t\tscaleX: 1,\n\t\t\t\t\t\t\tscaleY: 1,\n\t\t\t\t\t\t\ttranslateX: 0,\n\t\t\t\t\t\t\ttranslateY: 0\n\t\t\t\t\t\t}, animationOptions);\n\n\t\t\t\t});\n\n\t\t\t\tdelete this.animate;\n\t\t\t}\n\t\t\t\n\t\t},\n\n\t\t/**\n\t\t * When drilling up, pull out the individual point graphics from the lower series\n\t\t * and animate them into the origin point in the upper series.\n\t\t */\n\t\tanimateDrillupFrom: function (level) {\n\t\t\tseriesTypes.column.prototype.animateDrillupFrom.call(this, level);\n\t\t},\n\n\n\t\t/**\n\t\t * When drilling up, keep the upper series invisible until the lower series has\n\t\t * moved into place\n\t\t */\n\t\tanimateDrillupTo: function (init) {\n\t\t\tseriesTypes.column.prototype.animateDrillupTo.call(this, init);\n\t\t}\n\t});\n\n\n\t// The mapline series type\n\tplotOptions.mapline = merge(plotOptions.map, {\n\t\tlineWidth: 1,\n\t\tbackgroundColor: 'none'\n\t});\n\tseriesTypes.mapline = Highcharts.extendClass(seriesTypes.map, {\n\t\ttype: 'mapline',\n\t\tpointAttrToOptions: { // mapping between SVG attributes and the corresponding options\n\t\t\tstroke: 'color',\n\t\t\t'stroke-width': 'lineWidth',\n\t\t\tfill: 'backgroundColor'\n\t\t},\n\t\tdrawLegendSymbol: seriesTypes.line.prototype.drawLegendSymbol\n\t});\n\n\t// The mappoint series type\n\tplotOptions.mappoint = merge(plotOptions.scatter, {\n\t\tdataLabels: {\n\t\t\tenabled: true,\n\t\t\tformat: '{point.name}',\n\t\t\tcolor: 'black',\n\t\t\tstyle: {\n\t\t\t\ttextShadow: '0 0 5px white'\n\t\t\t}\n\t\t}\n\t});\n\tseriesTypes.mappoint = Highcharts.extendClass(seriesTypes.scatter, {\n\t\ttype: 'mappoint'\n\t});\n\t\n\n\t\n\t/**\n\t * A wrapper for Chart with all the default values for a Map\n\t */\n\tHighcharts.Map = function (options, callback) {\n\t\t\n\t\tvar hiddenAxis = {\n\t\t\t\tendOnTick: false,\n\t\t\t\tgridLineWidth: 0,\n\t\t\t\tlabels: {\n\t\t\t\t\tenabled: false\n\t\t\t\t},\n\t\t\t\tlineWidth: 0,\n\t\t\t\tminPadding: 0,\n\t\t\t\tmaxPadding: 0,\n\t\t\t\tstartOnTick: false,\n\t\t\t\ttickWidth: 0,\n\t\t\t\ttitle: null\n\t\t\t},\n\t\t\tseriesOptions;\n\t\t\n\t\t// Don't merge the data\n\t\tseriesOptions = options.series;\n\t\toptions.series = null;\n\t\t\n\t\toptions = merge({\n\t\t\tchart: {\n\t\t\t\ttype: 'map',\n\t\t\t\tpanning: 'xy'\n\t\t\t},\n\t\t\txAxis: hiddenAxis,\n\t\t\tyAxis: merge(hiddenAxis, { reversed: true })\t\n\t\t},\n\t\toptions, // user's options\n\t\n\t\t{ // forced options\n\t\t\tchart: {\n\t\t\t\tinverted: false\n\t\t\t}\n\t\t});\n\t\n\t\toptions.series = seriesOptions;\n\t\n\t\n\t\treturn new Highcharts.Chart(options, callback);\n\t};\n}(Highcharts));\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/no-data-to-display.js",
    "content": "/*\n Highcharts JS v3.0.6 (2013-10-04)\n Plugin for displaying a message when there is no data visible in chart.\n\n (c) 2010-2013 Highsoft AS\n Author: Øystein Moseng\n\n License: www.highcharts.com/license\n*/\n(function(c){function f(){return!!this.points.length}function g(){this.hasData()?this.hideNoData():this.showNoData()}var d=c.seriesTypes,e=c.Chart.prototype,h=c.getOptions(),i=c.extend;i(h.lang,{noData:\"No data to display\"});h.noData={position:{x:0,y:0,align:\"center\",verticalAlign:\"middle\"},attr:{},style:{fontWeight:\"bold\",fontSize:\"12px\",color:\"#60606a\"}};d.pie.prototype.hasData=f;if(d.gauge)d.gauge.prototype.hasData=f;if(d.waterfall)d.waterfall.prototype.hasData=f;c.Series.prototype.hasData=function(){return this.dataMax!==\nvoid 0&&this.dataMin!==void 0};e.showNoData=function(a){var b=this.options,a=a||b.lang.noData,b=b.noData;if(!this.noDataLabel)this.noDataLabel=this.renderer.label(a,0,0,null,null,null,null,null,\"no-data\").attr(b.attr).css(b.style).add(),this.noDataLabel.align(i(this.noDataLabel.getBBox(),b.position),!1,\"plotBox\")};e.hideNoData=function(){if(this.noDataLabel)this.noDataLabel=this.noDataLabel.destroy()};e.hasData=function(){for(var a=this.series,b=a.length;b--;)if(a[b].hasData()&&!a[b].options.isInternal)return!0;\nreturn!1};e.callbacks.push(function(a){c.addEvent(a,\"load\",g);c.addEvent(a,\"redraw\",g)})})(Highcharts);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/modules/no-data-to-display.src.js",
    "content": "/**\n * @license Highcharts JS v3.0.6 (2013-10-04)\n * Plugin for displaying a message when there is no data visible in chart.\n *\n * (c) 2010-2013 Highsoft AS\n * Author: Øystein Moseng\n *\n * License: www.highcharts.com/license\n */\n\n(function (H) { // docs\n\t\n\tvar seriesTypes = H.seriesTypes,\n\t\tchartPrototype = H.Chart.prototype,\n\t\tdefaultOptions = H.getOptions(),\n\t\textend = H.extend;\n\n\t// Add language option\n\textend(defaultOptions.lang, {\n\t\tnoData: 'No data to display'\n\t});\n\t\n\t// Add default display options for message\n\tdefaultOptions.noData = {\n\t\tposition: {\n\t\t\tx: 0,\n\t\t\ty: 0,\t\t\t\n\t\t\talign: 'center',\n\t\t\tverticalAlign: 'middle'\n\t\t},\n\t\tattr: {\t\t\t\t\t\t\n\t\t},\n\t\tstyle: {\t\n\t\t\tfontWeight: 'bold',\t\t\n\t\t\tfontSize: '12px',\n\t\t\tcolor: '#60606a'\t\t\n\t\t}\n\t};\n\n\t/**\n\t * Define hasData functions for series. These return true if there are data points on this series within the plot area\n\t */\t\n\tfunction hasDataPie() {\n\t\treturn !!this.points.length; /* != 0 */\n\t}\n\n\tseriesTypes.pie.prototype.hasData = hasDataPie;\n\n\tif (seriesTypes.gauge) {\n\t\tseriesTypes.gauge.prototype.hasData = hasDataPie;\n\t}\n\n\tif (seriesTypes.waterfall) {\n\t\tseriesTypes.waterfall.prototype.hasData = hasDataPie;\n\t}\n\n\tH.Series.prototype.hasData = function () {\n\t\treturn this.dataMax !== undefined && this.dataMin !== undefined;\n\t};\n\t\n\t/**\n\t * Display a no-data message.\n\t *\n\t * @param {String} str An optional message to show in place of the default one \n\t */\n\tchartPrototype.showNoData = function (str) {\n\t\tvar chart = this,\n\t\t\toptions = chart.options,\n\t\t\ttext = str || options.lang.noData,\n\t\t\tnoDataOptions = options.noData;\n\n\t\tif (!chart.noDataLabel) {\n\t\t\tchart.noDataLabel = chart.renderer.label(text, 0, 0, null, null, null, null, null, 'no-data')\n\t\t\t\t.attr(noDataOptions.attr)\n\t\t\t\t.css(noDataOptions.style)\n\t\t\t\t.add();\n\t\t\tchart.noDataLabel.align(extend(chart.noDataLabel.getBBox(), noDataOptions.position), false, 'plotBox');\n\t\t}\n\t};\n\n\t/**\n\t * Hide no-data message\t\n\t */\t\n\tchartPrototype.hideNoData = function () {\n\t\tvar chart = this;\n\t\tif (chart.noDataLabel) {\n\t\t\tchart.noDataLabel = chart.noDataLabel.destroy();\n\t\t}\n\t};\n\n\t/**\n\t * Returns true if there are data points within the plot area now\n\t */\t\n\tchartPrototype.hasData = function () {\n\t\tvar chart = this,\n\t\t\tseries = chart.series,\n\t\t\ti = series.length;\n\n\t\twhile (i--) {\n\t\t\tif (series[i].hasData() && !series[i].options.isInternal) { \n\t\t\t\treturn true;\n\t\t\t}\t\n\t\t}\n\n\t\treturn false;\n\t};\n\n\t/**\n\t * Show no-data message if there is no data in sight. Otherwise, hide it.\n\t */\n\tfunction handleNoData() {\n\t\tvar chart = this;\n\t\tif (chart.hasData()) {\n\t\t\tchart.hideNoData();\n\t\t} else {\n\t\t\tchart.showNoData();\n\t\t}\n\t}\n\n\t/**\n\t * Add event listener to handle automatic display of no-data message\n\t */\n\tchartPrototype.callbacks.push(function (chart) {\n\t\tH.addEvent(chart, 'load', handleNoData);\n\t\tH.addEvent(chart, 'redraw', handleNoData);\n\t});\n\n}(Highcharts));\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/themes/dark-blue.js",
    "content": "/**\n * Dark blue theme for Highcharts JS\n * @author Torstein Hønsi\n */\n\nHighcharts.theme = {\n\tcolors: [\"#DDDF0D\", \"#55BF3B\", \"#DF5353\", \"#7798BF\", \"#aaeeee\", \"#ff0066\", \"#eeaaee\",\n\t\t\"#55BF3B\", \"#DF5353\", \"#7798BF\", \"#aaeeee\"],\n\tchart: {\n\t\tbackgroundColor: {\n\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 },\n\t\t\tstops: [\n\t\t\t\t[0, 'rgb(48, 48, 96)'],\n\t\t\t\t[1, 'rgb(0, 0, 0)']\n\t\t\t]\n\t\t},\n\t\tborderColor: '#000000',\n\t\tborderWidth: 2,\n\t\tclassName: 'dark-container',\n\t\tplotBackgroundColor: 'rgba(255, 255, 255, .1)',\n\t\tplotBorderColor: '#CCCCCC',\n\t\tplotBorderWidth: 1\n\t},\n\ttitle: {\n\t\tstyle: {\n\t\t\tcolor: '#C0C0C0',\n\t\t\tfont: 'bold 16px \"Trebuchet MS\", Verdana, sans-serif'\n\t\t}\n\t},\n\tsubtitle: {\n\t\tstyle: {\n\t\t\tcolor: '#666666',\n\t\t\tfont: 'bold 12px \"Trebuchet MS\", Verdana, sans-serif'\n\t\t}\n\t},\n\txAxis: {\n\t\tgridLineColor: '#333333',\n\t\tgridLineWidth: 1,\n\t\tlabels: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#A0A0A0'\n\t\t\t}\n\t\t},\n\t\tlineColor: '#A0A0A0',\n\t\ttickColor: '#A0A0A0',\n\t\ttitle: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#CCC',\n\t\t\t\tfontWeight: 'bold',\n\t\t\t\tfontSize: '12px',\n\t\t\t\tfontFamily: 'Trebuchet MS, Verdana, sans-serif'\n\n\t\t\t}\n\t\t}\n\t},\n\tyAxis: {\n\t\tgridLineColor: '#333333',\n\t\tlabels: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#A0A0A0'\n\t\t\t}\n\t\t},\n\t\tlineColor: '#A0A0A0',\n\t\tminorTickInterval: null,\n\t\ttickColor: '#A0A0A0',\n\t\ttickWidth: 1,\n\t\ttitle: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#CCC',\n\t\t\t\tfontWeight: 'bold',\n\t\t\t\tfontSize: '12px',\n\t\t\t\tfontFamily: 'Trebuchet MS, Verdana, sans-serif'\n\t\t\t}\n\t\t}\n\t},\n\ttooltip: {\n\t\tbackgroundColor: 'rgba(0, 0, 0, 0.75)',\n\t\tstyle: {\n\t\t\tcolor: '#F0F0F0'\n\t\t}\n\t},\n\ttoolbar: {\n\t\titemStyle: {\n\t\t\tcolor: 'silver'\n\t\t}\n\t},\n\tplotOptions: {\n\t\tline: {\n\t\t\tdataLabels: {\n\t\t\t\tcolor: '#CCC'\n\t\t\t},\n\t\t\tmarker: {\n\t\t\t\tlineColor: '#333'\n\t\t\t}\n\t\t},\n\t\tspline: {\n\t\t\tmarker: {\n\t\t\t\tlineColor: '#333'\n\t\t\t}\n\t\t},\n\t\tscatter: {\n\t\t\tmarker: {\n\t\t\t\tlineColor: '#333'\n\t\t\t}\n\t\t},\n\t\tcandlestick: {\n\t\t\tlineColor: 'white'\n\t\t}\n\t},\n\tlegend: {\n\t\titemStyle: {\n\t\t\tfont: '9pt Trebuchet MS, Verdana, sans-serif',\n\t\t\tcolor: '#A0A0A0'\n\t\t},\n\t\titemHoverStyle: {\n\t\t\tcolor: '#FFF'\n\t\t},\n\t\titemHiddenStyle: {\n\t\t\tcolor: '#444'\n\t\t}\n\t},\n\tcredits: {\n\t\tstyle: {\n\t\t\tcolor: '#666'\n\t\t}\n\t},\n\tlabels: {\n\t\tstyle: {\n\t\t\tcolor: '#CCC'\n\t\t}\n\t},\n\n\tnavigation: {\n\t\tbuttonOptions: {\n\t\t\tsymbolStroke: '#DDDDDD',\n\t\t\thoverSymbolStroke: '#FFFFFF',\n\t\t\ttheme: {\n\t\t\t\tfill: {\n\t\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\t\tstops: [\n\t\t\t\t\t\t[0.4, '#606060'],\n\t\t\t\t\t\t[0.6, '#333333']\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\tstroke: '#000000'\n\t\t\t}\n\t\t}\n\t},\n\n\t// scroll charts\n\trangeSelector: {\n\t\tbuttonTheme: {\n\t\t\tfill: {\n\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\tstops: [\n\t\t\t\t\t[0.4, '#888'],\n\t\t\t\t\t[0.6, '#555']\n\t\t\t\t]\n\t\t\t},\n\t\t\tstroke: '#000000',\n\t\t\tstyle: {\n\t\t\t\tcolor: '#CCC',\n\t\t\t\tfontWeight: 'bold'\n\t\t\t},\n\t\t\tstates: {\n\t\t\t\thover: {\n\t\t\t\t\tfill: {\n\t\t\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\t\t\tstops: [\n\t\t\t\t\t\t\t[0.4, '#BBB'],\n\t\t\t\t\t\t\t[0.6, '#888']\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tstroke: '#000000',\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tcolor: 'white'\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tselect: {\n\t\t\t\t\tfill: {\n\t\t\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\t\t\tstops: [\n\t\t\t\t\t\t\t[0.1, '#000'],\n\t\t\t\t\t\t\t[0.3, '#333']\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tstroke: '#000000',\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tcolor: 'yellow'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tinputStyle: {\n\t\t\tbackgroundColor: '#333',\n\t\t\tcolor: 'silver'\n\t\t},\n\t\tlabelStyle: {\n\t\t\tcolor: 'silver'\n\t\t}\n\t},\n\n\tnavigator: {\n\t\thandles: {\n\t\t\tbackgroundColor: '#666',\n\t\t\tborderColor: '#AAA'\n\t\t},\n\t\toutlineColor: '#CCC',\n\t\tmaskFill: 'rgba(16, 16, 16, 0.5)',\n\t\tseries: {\n\t\t\tcolor: '#7798BF',\n\t\t\tlineColor: '#A6C7ED'\n\t\t}\n\t},\n\n\tscrollbar: {\n\t\tbarBackgroundColor: {\n\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\tstops: [\n\t\t\t\t\t[0.4, '#888'],\n\t\t\t\t\t[0.6, '#555']\n\t\t\t\t]\n\t\t\t},\n\t\tbarBorderColor: '#CCC',\n\t\tbuttonArrowColor: '#CCC',\n\t\tbuttonBackgroundColor: {\n\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\tstops: [\n\t\t\t\t\t[0.4, '#888'],\n\t\t\t\t\t[0.6, '#555']\n\t\t\t\t]\n\t\t\t},\n\t\tbuttonBorderColor: '#CCC',\n\t\trifleColor: '#FFF',\n\t\ttrackBackgroundColor: {\n\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\tstops: [\n\t\t\t\t[0, '#000'],\n\t\t\t\t[1, '#333']\n\t\t\t]\n\t\t},\n\t\ttrackBorderColor: '#666'\n\t},\n\n\t// special colors for some of the\n\tlegendBackgroundColor: 'rgba(0, 0, 0, 0.5)',\n\tlegendBackgroundColorSolid: 'rgb(35, 35, 70)',\n\tdataLabelsColor: '#444',\n\ttextColor: '#C0C0C0',\n\tmaskColor: 'rgba(255,255,255,0.3)'\n};\n\n// Apply the theme\nvar highchartsOptions = Highcharts.setOptions(Highcharts.theme);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/themes/dark-green.js",
    "content": "/**\n * Dark blue theme for Highcharts JS\n * @author Torstein Hønsi\n */\n\nHighcharts.theme = {\n\tcolors: [\"#DDDF0D\", \"#55BF3B\", \"#DF5353\", \"#7798BF\", \"#aaeeee\", \"#ff0066\", \"#eeaaee\",\n\t\t\"#55BF3B\", \"#DF5353\", \"#7798BF\", \"#aaeeee\"],\n\tchart: {\n\t\tbackgroundColor: {\n\t\t\tlinearGradient: [0, 0, 250, 500],\n\t\t\tstops: [\n\t\t\t\t[0, 'rgb(48, 96, 48)'],\n\t\t\t\t[1, 'rgb(0, 0, 0)']\n\t\t\t]\n\t\t},\n\t\tborderColor: '#000000',\n\t\tborderWidth: 2,\n\t\tclassName: 'dark-container',\n\t\tplotBackgroundColor: 'rgba(255, 255, 255, .1)',\n\t\tplotBorderColor: '#CCCCCC',\n\t\tplotBorderWidth: 1\n\t},\n\ttitle: {\n\t\tstyle: {\n\t\t\tcolor: '#C0C0C0',\n\t\t\tfont: 'bold 16px \"Trebuchet MS\", Verdana, sans-serif'\n\t\t}\n\t},\n\tsubtitle: {\n\t\tstyle: {\n\t\t\tcolor: '#666666',\n\t\t\tfont: 'bold 12px \"Trebuchet MS\", Verdana, sans-serif'\n\t\t}\n\t},\n\txAxis: {\n\t\tgridLineColor: '#333333',\n\t\tgridLineWidth: 1,\n\t\tlabels: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#A0A0A0'\n\t\t\t}\n\t\t},\n\t\tlineColor: '#A0A0A0',\n\t\ttickColor: '#A0A0A0',\n\t\ttitle: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#CCC',\n\t\t\t\tfontWeight: 'bold',\n\t\t\t\tfontSize: '12px',\n\t\t\t\tfontFamily: 'Trebuchet MS, Verdana, sans-serif'\n\n\t\t\t}\n\t\t}\n\t},\n\tyAxis: {\n\t\tgridLineColor: '#333333',\n\t\tlabels: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#A0A0A0'\n\t\t\t}\n\t\t},\n\t\tlineColor: '#A0A0A0',\n\t\tminorTickInterval: null,\n\t\ttickColor: '#A0A0A0',\n\t\ttickWidth: 1,\n\t\ttitle: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#CCC',\n\t\t\t\tfontWeight: 'bold',\n\t\t\t\tfontSize: '12px',\n\t\t\t\tfontFamily: 'Trebuchet MS, Verdana, sans-serif'\n\t\t\t}\n\t\t}\n\t},\n\ttooltip: {\n\t\tbackgroundColor: 'rgba(0, 0, 0, 0.75)',\n\t\tstyle: {\n\t\t\tcolor: '#F0F0F0'\n\t\t}\n\t},\n\ttoolbar: {\n\t\titemStyle: {\n\t\t\tcolor: 'silver'\n\t\t}\n\t},\n\tplotOptions: {\n\t\tline: {\n\t\t\tdataLabels: {\n\t\t\t\tcolor: '#CCC'\n\t\t\t},\n\t\t\tmarker: {\n\t\t\t\tlineColor: '#333'\n\t\t\t}\n\t\t},\n\t\tspline: {\n\t\t\tmarker: {\n\t\t\t\tlineColor: '#333'\n\t\t\t}\n\t\t},\n\t\tscatter: {\n\t\t\tmarker: {\n\t\t\t\tlineColor: '#333'\n\t\t\t}\n\t\t},\n\t\tcandlestick: {\n\t\t\tlineColor: 'white'\n\t\t}\n\t},\n\tlegend: {\n\t\titemStyle: {\n\t\t\tfont: '9pt Trebuchet MS, Verdana, sans-serif',\n\t\t\tcolor: '#A0A0A0'\n\t\t},\n\t\titemHoverStyle: {\n\t\t\tcolor: '#FFF'\n\t\t},\n\t\titemHiddenStyle: {\n\t\t\tcolor: '#444'\n\t\t}\n\t},\n\tcredits: {\n\t\tstyle: {\n\t\t\tcolor: '#666'\n\t\t}\n\t},\n\tlabels: {\n\t\tstyle: {\n\t\t\tcolor: '#CCC'\n\t\t}\n\t},\n\n\n\tnavigation: {\n\t\tbuttonOptions: {\n\t\t\tsymbolStroke: '#DDDDDD',\n\t\t\thoverSymbolStroke: '#FFFFFF',\n\t\t\ttheme: {\n\t\t\t\tfill: {\n\t\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\t\tstops: [\n\t\t\t\t\t\t[0.4, '#606060'],\n\t\t\t\t\t\t[0.6, '#333333']\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\tstroke: '#000000'\n\t\t\t}\n\t\t}\n\t},\n\n\t// scroll charts\n\trangeSelector: {\n\t\tbuttonTheme: {\n\t\t\tfill: {\n\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\tstops: [\n\t\t\t\t\t[0.4, '#888'],\n\t\t\t\t\t[0.6, '#555']\n\t\t\t\t]\n\t\t\t},\n\t\t\tstroke: '#000000',\n\t\t\tstyle: {\n\t\t\t\tcolor: '#CCC',\n\t\t\t\tfontWeight: 'bold'\n\t\t\t},\n\t\t\tstates: {\n\t\t\t\thover: {\n\t\t\t\t\tfill: {\n\t\t\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\t\t\tstops: [\n\t\t\t\t\t\t\t[0.4, '#BBB'],\n\t\t\t\t\t\t\t[0.6, '#888']\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tstroke: '#000000',\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tcolor: 'white'\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tselect: {\n\t\t\t\t\tfill: {\n\t\t\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\t\t\tstops: [\n\t\t\t\t\t\t\t[0.1, '#000'],\n\t\t\t\t\t\t\t[0.3, '#333']\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tstroke: '#000000',\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tcolor: 'yellow'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tinputStyle: {\n\t\t\tbackgroundColor: '#333',\n\t\t\tcolor: 'silver'\n\t\t},\n\t\tlabelStyle: {\n\t\t\tcolor: 'silver'\n\t\t}\n\t},\n\n\tnavigator: {\n\t\thandles: {\n\t\t\tbackgroundColor: '#666',\n\t\t\tborderColor: '#AAA'\n\t\t},\n\t\toutlineColor: '#CCC',\n\t\tmaskFill: 'rgba(16, 16, 16, 0.5)',\n\t\tseries: {\n\t\t\tcolor: '#7798BF',\n\t\t\tlineColor: '#A6C7ED'\n\t\t}\n\t},\n\n\tscrollbar: {\n\t\tbarBackgroundColor: {\n\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\tstops: [\n\t\t\t\t\t[0.4, '#888'],\n\t\t\t\t\t[0.6, '#555']\n\t\t\t\t]\n\t\t\t},\n\t\tbarBorderColor: '#CCC',\n\t\tbuttonArrowColor: '#CCC',\n\t\tbuttonBackgroundColor: {\n\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\tstops: [\n\t\t\t\t\t[0.4, '#888'],\n\t\t\t\t\t[0.6, '#555']\n\t\t\t\t]\n\t\t\t},\n\t\tbuttonBorderColor: '#CCC',\n\t\trifleColor: '#FFF',\n\t\ttrackBackgroundColor: {\n\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\tstops: [\n\t\t\t\t[0, '#000'],\n\t\t\t\t[1, '#333']\n\t\t\t]\n\t\t},\n\t\ttrackBorderColor: '#666'\n\t},\n\n\t// special colors for some of the\n\tlegendBackgroundColor: 'rgba(0, 0, 0, 0.5)',\n\tlegendBackgroundColorSolid: 'rgb(35, 35, 70)',\n\tdataLabelsColor: '#444',\n\ttextColor: '#C0C0C0',\n\tmaskColor: 'rgba(255,255,255,0.3)'\n};\n\n// Apply the theme\nvar highchartsOptions = Highcharts.setOptions(Highcharts.theme);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/themes/gray.js",
    "content": "/**\n * Gray theme for Highcharts JS\n * @author Torstein Hønsi\n */\n\nHighcharts.theme = {\n\tcolors: [\"#DDDF0D\", \"#7798BF\", \"#55BF3B\", \"#DF5353\", \"#aaeeee\", \"#ff0066\", \"#eeaaee\",\n\t\t\"#55BF3B\", \"#DF5353\", \"#7798BF\", \"#aaeeee\"],\n\tchart: {\n\t\tbackgroundColor: {\n\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\tstops: [\n\t\t\t\t[0, 'rgb(96, 96, 96)'],\n\t\t\t\t[1, 'rgb(16, 16, 16)']\n\t\t\t]\n\t\t},\n\t\tborderWidth: 0,\n\t\tborderRadius: 15,\n\t\tplotBackgroundColor: null,\n\t\tplotShadow: false,\n\t\tplotBorderWidth: 0\n\t},\n\ttitle: {\n\t\tstyle: {\n\t\t\tcolor: '#FFF',\n\t\t\tfont: '16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'\n\t\t}\n\t},\n\tsubtitle: {\n\t\tstyle: {\n\t\t\tcolor: '#DDD',\n\t\t\tfont: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'\n\t\t}\n\t},\n\txAxis: {\n\t\tgridLineWidth: 0,\n\t\tlineColor: '#999',\n\t\ttickColor: '#999',\n\t\tlabels: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#999',\n\t\t\t\tfontWeight: 'bold'\n\t\t\t}\n\t\t},\n\t\ttitle: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#AAA',\n\t\t\t\tfont: 'bold 12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'\n\t\t\t}\n\t\t}\n\t},\n\tyAxis: {\n\t\talternateGridColor: null,\n\t\tminorTickInterval: null,\n\t\tgridLineColor: 'rgba(255, 255, 255, .1)',\n\t\tminorGridLineColor: 'rgba(255,255,255,0.07)',\n\t\tlineWidth: 0,\n\t\ttickWidth: 0,\n\t\tlabels: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#999',\n\t\t\t\tfontWeight: 'bold'\n\t\t\t}\n\t\t},\n\t\ttitle: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#AAA',\n\t\t\t\tfont: 'bold 12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'\n\t\t\t}\n\t\t}\n\t},\n\tlegend: {\n\t\titemStyle: {\n\t\t\tcolor: '#CCC'\n\t\t},\n\t\titemHoverStyle: {\n\t\t\tcolor: '#FFF'\n\t\t},\n\t\titemHiddenStyle: {\n\t\t\tcolor: '#333'\n\t\t}\n\t},\n\tlabels: {\n\t\tstyle: {\n\t\t\tcolor: '#CCC'\n\t\t}\n\t},\n\ttooltip: {\n\t\tbackgroundColor: {\n\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\tstops: [\n\t\t\t\t[0, 'rgba(96, 96, 96, .8)'],\n\t\t\t\t[1, 'rgba(16, 16, 16, .8)']\n\t\t\t]\n\t\t},\n\t\tborderWidth: 0,\n\t\tstyle: {\n\t\t\tcolor: '#FFF'\n\t\t}\n\t},\n\n\n\tplotOptions: {\n\t\tseries: {\n\t\t\tshadow: true\n\t\t},\n\t\tline: {\n\t\t\tdataLabels: {\n\t\t\t\tcolor: '#CCC'\n\t\t\t},\n\t\t\tmarker: {\n\t\t\t\tlineColor: '#333'\n\t\t\t}\n\t\t},\n\t\tspline: {\n\t\t\tmarker: {\n\t\t\t\tlineColor: '#333'\n\t\t\t}\n\t\t},\n\t\tscatter: {\n\t\t\tmarker: {\n\t\t\t\tlineColor: '#333'\n\t\t\t}\n\t\t},\n\t\tcandlestick: {\n\t\t\tlineColor: 'white'\n\t\t}\n\t},\n\n\ttoolbar: {\n\t\titemStyle: {\n\t\t\tcolor: '#CCC'\n\t\t}\n\t},\n\n\tnavigation: {\n\t\tbuttonOptions: {\n\t\t\tsymbolStroke: '#DDDDDD',\n\t\t\thoverSymbolStroke: '#FFFFFF',\n\t\t\ttheme: {\n\t\t\t\tfill: {\n\t\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\t\tstops: [\n\t\t\t\t\t\t[0.4, '#606060'],\n\t\t\t\t\t\t[0.6, '#333333']\n\t\t\t\t\t]\n\t\t\t\t},\n\t\t\t\tstroke: '#000000'\n\t\t\t}\n\t\t}\n\t},\n\n\t// scroll charts\n\trangeSelector: {\n\t\tbuttonTheme: {\n\t\t\tfill: {\n\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\tstops: [\n\t\t\t\t\t[0.4, '#888'],\n\t\t\t\t\t[0.6, '#555']\n\t\t\t\t]\n\t\t\t},\n\t\t\tstroke: '#000000',\n\t\t\tstyle: {\n\t\t\t\tcolor: '#CCC',\n\t\t\t\tfontWeight: 'bold'\n\t\t\t},\n\t\t\tstates: {\n\t\t\t\thover: {\n\t\t\t\t\tfill: {\n\t\t\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\t\t\tstops: [\n\t\t\t\t\t\t\t[0.4, '#BBB'],\n\t\t\t\t\t\t\t[0.6, '#888']\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tstroke: '#000000',\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tcolor: 'white'\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t\tselect: {\n\t\t\t\t\tfill: {\n\t\t\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\t\t\tstops: [\n\t\t\t\t\t\t\t[0.1, '#000'],\n\t\t\t\t\t\t\t[0.3, '#333']\n\t\t\t\t\t\t]\n\t\t\t\t\t},\n\t\t\t\t\tstroke: '#000000',\n\t\t\t\t\tstyle: {\n\t\t\t\t\t\tcolor: 'yellow'\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\tinputStyle: {\n\t\t\tbackgroundColor: '#333',\n\t\t\tcolor: 'silver'\n\t\t},\n\t\tlabelStyle: {\n\t\t\tcolor: 'silver'\n\t\t}\n\t},\n\n\tnavigator: {\n\t\thandles: {\n\t\t\tbackgroundColor: '#666',\n\t\t\tborderColor: '#AAA'\n\t\t},\n\t\toutlineColor: '#CCC',\n\t\tmaskFill: 'rgba(16, 16, 16, 0.5)',\n\t\tseries: {\n\t\t\tcolor: '#7798BF',\n\t\t\tlineColor: '#A6C7ED'\n\t\t}\n\t},\n\n\tscrollbar: {\n\t\tbarBackgroundColor: {\n\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\tstops: [\n\t\t\t\t\t[0.4, '#888'],\n\t\t\t\t\t[0.6, '#555']\n\t\t\t\t]\n\t\t\t},\n\t\tbarBorderColor: '#CCC',\n\t\tbuttonArrowColor: '#CCC',\n\t\tbuttonBackgroundColor: {\n\t\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\t\tstops: [\n\t\t\t\t\t[0.4, '#888'],\n\t\t\t\t\t[0.6, '#555']\n\t\t\t\t]\n\t\t\t},\n\t\tbuttonBorderColor: '#CCC',\n\t\trifleColor: '#FFF',\n\t\ttrackBackgroundColor: {\n\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 0, y2: 1 },\n\t\t\tstops: [\n\t\t\t\t[0, '#000'],\n\t\t\t\t[1, '#333']\n\t\t\t]\n\t\t},\n\t\ttrackBorderColor: '#666'\n\t},\n\n\t// special colors for some of the demo examples\n\tlegendBackgroundColor: 'rgba(48, 48, 48, 0.8)',\n\tlegendBackgroundColorSolid: 'rgb(70, 70, 70)',\n\tdataLabelsColor: '#444',\n\ttextColor: '#E0E0E0',\n\tmaskColor: 'rgba(255,255,255,0.3)'\n};\n\n// Apply the theme\nvar highchartsOptions = Highcharts.setOptions(Highcharts.theme);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/themes/grid.js",
    "content": "/**\n * Grid theme for Highcharts JS\n * @author Torstein Hønsi\n */\n\nHighcharts.theme = {\n\tcolors: ['#058DC7', '#50B432', '#ED561B', '#DDDF00', '#24CBE5', '#64E572', '#FF9655', '#FFF263', '#6AF9C4'],\n\tchart: {\n\t\tbackgroundColor: {\n\t\t\tlinearGradient: { x1: 0, y1: 0, x2: 1, y2: 1 },\n\t\t\tstops: [\n\t\t\t\t[0, 'rgb(255, 255, 255)'],\n\t\t\t\t[1, 'rgb(240, 240, 255)']\n\t\t\t]\n\t\t},\n\t\tborderWidth: 2,\n\t\tplotBackgroundColor: 'rgba(255, 255, 255, .9)',\n\t\tplotShadow: true,\n\t\tplotBorderWidth: 1\n\t},\n\ttitle: {\n\t\tstyle: {\n\t\t\tcolor: '#000',\n\t\t\tfont: 'bold 16px \"Trebuchet MS\", Verdana, sans-serif'\n\t\t}\n\t},\n\tsubtitle: {\n\t\tstyle: {\n\t\t\tcolor: '#666666',\n\t\t\tfont: 'bold 12px \"Trebuchet MS\", Verdana, sans-serif'\n\t\t}\n\t},\n\txAxis: {\n\t\tgridLineWidth: 1,\n\t\tlineColor: '#000',\n\t\ttickColor: '#000',\n\t\tlabels: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#000',\n\t\t\t\tfont: '11px Trebuchet MS, Verdana, sans-serif'\n\t\t\t}\n\t\t},\n\t\ttitle: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#333',\n\t\t\t\tfontWeight: 'bold',\n\t\t\t\tfontSize: '12px',\n\t\t\t\tfontFamily: 'Trebuchet MS, Verdana, sans-serif'\n\n\t\t\t}\n\t\t}\n\t},\n\tyAxis: {\n\t\tminorTickInterval: 'auto',\n\t\tlineColor: '#000',\n\t\tlineWidth: 1,\n\t\ttickWidth: 1,\n\t\ttickColor: '#000',\n\t\tlabels: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#000',\n\t\t\t\tfont: '11px Trebuchet MS, Verdana, sans-serif'\n\t\t\t}\n\t\t},\n\t\ttitle: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#333',\n\t\t\t\tfontWeight: 'bold',\n\t\t\t\tfontSize: '12px',\n\t\t\t\tfontFamily: 'Trebuchet MS, Verdana, sans-serif'\n\t\t\t}\n\t\t}\n\t},\n\tlegend: {\n\t\titemStyle: {\n\t\t\tfont: '9pt Trebuchet MS, Verdana, sans-serif',\n\t\t\tcolor: 'black'\n\n\t\t},\n\t\titemHoverStyle: {\n\t\t\tcolor: '#039'\n\t\t},\n\t\titemHiddenStyle: {\n\t\t\tcolor: 'gray'\n\t\t}\n\t},\n\tlabels: {\n\t\tstyle: {\n\t\t\tcolor: '#99b'\n\t\t}\n\t},\n\n\tnavigation: {\n\t\tbuttonOptions: {\n\t\t\ttheme: {\n\t\t\t\tstroke: '#CCCCCC'\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Apply the theme\nvar highchartsOptions = Highcharts.setOptions(Highcharts.theme);\n"
  },
  {
    "path": "public/static/ueditor/third-party/highcharts/themes/skies.js",
    "content": "/**\n * Skies theme for Highcharts JS\n * @author Torstein Hønsi\n */\n\nHighcharts.theme = {\n\tcolors: [\"#514F78\", \"#42A07B\", \"#9B5E4A\", \"#72727F\", \"#1F949A\", \"#82914E\", \"#86777F\", \"#42A07B\"],\n\tchart: {\n\t\tclassName: 'skies',\n\t\tborderWidth: 0,\n\t\tplotShadow: true,\n\t\tplotBackgroundImage: 'http://www.highcharts.com/demo/gfx/skies.jpg',\n\t\tplotBackgroundColor: {\n\t\t\tlinearGradient: [0, 0, 250, 500],\n\t\t\tstops: [\n\t\t\t\t[0, 'rgba(255, 255, 255, 1)'],\n\t\t\t\t[1, 'rgba(255, 255, 255, 0)']\n\t\t\t]\n\t\t},\n\t\tplotBorderWidth: 1\n\t},\n\ttitle: {\n\t\tstyle: {\n\t\t\tcolor: '#3E576F',\n\t\t\tfont: '16px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'\n\t\t}\n\t},\n\tsubtitle: {\n\t\tstyle: {\n\t\t\tcolor: '#6D869F',\n\t\t\tfont: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'\n\t\t}\n\t},\n\txAxis: {\n\t\tgridLineWidth: 0,\n\t\tlineColor: '#C0D0E0',\n\t\ttickColor: '#C0D0E0',\n\t\tlabels: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#666',\n\t\t\t\tfontWeight: 'bold'\n\t\t\t}\n\t\t},\n\t\ttitle: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#666',\n\t\t\t\tfont: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'\n\t\t\t}\n\t\t}\n\t},\n\tyAxis: {\n\t\talternateGridColor: 'rgba(255, 255, 255, .5)',\n\t\tlineColor: '#C0D0E0',\n\t\ttickColor: '#C0D0E0',\n\t\ttickWidth: 1,\n\t\tlabels: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#666',\n\t\t\t\tfontWeight: 'bold'\n\t\t\t}\n\t\t},\n\t\ttitle: {\n\t\t\tstyle: {\n\t\t\t\tcolor: '#666',\n\t\t\t\tfont: '12px Lucida Grande, Lucida Sans Unicode, Verdana, Arial, Helvetica, sans-serif'\n\t\t\t}\n\t\t}\n\t},\n\tlegend: {\n\t\titemStyle: {\n\t\t\tfont: '9pt Trebuchet MS, Verdana, sans-serif',\n\t\t\tcolor: '#3E576F'\n\t\t},\n\t\titemHoverStyle: {\n\t\t\tcolor: 'black'\n\t\t},\n\t\titemHiddenStyle: {\n\t\t\tcolor: 'silver'\n\t\t}\n\t},\n\tlabels: {\n\t\tstyle: {\n\t\t\tcolor: '#3E576F'\n\t\t}\n\t}\n};\n\n// Apply the theme\nvar highchartsOptions = Highcharts.setOptions(Highcharts.theme);\n"
  },
  {
    "path": "public/static/ueditor/third-party/jquery-1.10.2.js",
    "content": "/*!\n * jQuery JavaScript Library v1.10.2\n * http://jquery.com/\n *\n * Includes Sizzle.js\n * http://sizzlejs.com/\n *\n * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2013-07-03T13:48Z\n */\n(function( window, undefined ) {\n\n// Can't do this because several apps including ASP.NET trace\n// the stack via arguments.caller.callee and Firefox dies if\n// you try to trace through \"use strict\" call chains. (#13335)\n// Support: Firefox 18+\n//\"use strict\";\nvar\n\t// The deferred used on DOM ready\n\treadyList,\n\n\t// A central reference to the root jQuery(document)\n\trootjQuery,\n\n\t// Support: IE<10\n\t// For `typeof xmlNode.method` instead of `xmlNode.method !== undefined`\n\tcore_strundefined = typeof undefined,\n\n\t// Use the correct document accordingly with window argument (sandbox)\n\tlocation = window.location,\n\tdocument = window.document,\n\tdocElem = document.documentElement,\n\n\t// Map over jQuery in case of overwrite\n\t_jQuery = window.jQuery,\n\n\t// Map over the $ in case of overwrite\n\t_$ = window.$,\n\n\t// [[Class]] -> type pairs\n\tclass2type = {},\n\n\t// List of deleted data cache ids, so we can reuse them\n\tcore_deletedIds = [],\n\n\tcore_version = \"1.10.2\",\n\n\t// Save a reference to some core methods\n\tcore_concat = core_deletedIds.concat,\n\tcore_push = core_deletedIds.push,\n\tcore_slice = core_deletedIds.slice,\n\tcore_indexOf = core_deletedIds.indexOf,\n\tcore_toString = class2type.toString,\n\tcore_hasOwn = class2type.hasOwnProperty,\n\tcore_trim = core_version.trim,\n\n\t// Define a local copy of jQuery\n\tjQuery = function( selector, context ) {\n\t\t// The jQuery object is actually just the init constructor 'enhanced'\n\t\treturn new jQuery.fn.init( selector, context, rootjQuery );\n\t},\n\n\t// Used for matching numbers\n\tcore_pnum = /[+-]?(?:\\d*\\.|)\\d+(?:[eE][+-]?\\d+|)/.source,\n\n\t// Used for splitting on whitespace\n\tcore_rnotwhite = /\\S+/g,\n\n\t// Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE)\n\trtrim = /^[\\s\\uFEFF\\xA0]+|[\\s\\uFEFF\\xA0]+$/g,\n\n\t// A simple way to check for HTML strings\n\t// Prioritize #id over <tag> to avoid XSS via location.hash (#9521)\n\t// Strict HTML recognition (#11290: must start with <)\n\trquickExpr = /^(?:\\s*(<[\\w\\W]+>)[^>]*|#([\\w-]*))$/,\n\n\t// Match a standalone tag\n\trsingleTag = /^<(\\w+)\\s*\\/?>(?:<\\/\\1>|)$/,\n\n\t// JSON RegExp\n\trvalidchars = /^[\\],:{}\\s]*$/,\n\trvalidbraces = /(?:^|:|,)(?:\\s*\\[)+/g,\n\trvalidescape = /\\\\(?:[\"\\\\\\/bfnrt]|u[\\da-fA-F]{4})/g,\n\trvalidtokens = /\"[^\"\\\\\\r\\n]*\"|true|false|null|-?(?:\\d+\\.|)\\d+(?:[eE][+-]?\\d+|)/g,\n\n\t// Matches dashed string for camelizing\n\trmsPrefix = /^-ms-/,\n\trdashAlpha = /-([\\da-z])/gi,\n\n\t// Used by jQuery.camelCase as callback to replace()\n\tfcamelCase = function( all, letter ) {\n\t\treturn letter.toUpperCase();\n\t},\n\n\t// The ready event handler\n\tcompleted = function( event ) {\n\n\t\t// readyState === \"complete\" is good enough for us to call the dom ready in oldIE\n\t\tif ( document.addEventListener || event.type === \"load\" || document.readyState === \"complete\" ) {\n\t\t\tdetach();\n\t\t\tjQuery.ready();\n\t\t}\n\t},\n\t// Clean-up method for dom ready events\n\tdetach = function() {\n\t\tif ( document.addEventListener ) {\n\t\t\tdocument.removeEventListener( \"DOMContentLoaded\", completed, false );\n\t\t\twindow.removeEventListener( \"load\", completed, false );\n\n\t\t} else {\n\t\t\tdocument.detachEvent( \"onreadystatechange\", completed );\n\t\t\twindow.detachEvent( \"onload\", completed );\n\t\t}\n\t};\n\njQuery.fn = jQuery.prototype = {\n\t// The current version of jQuery being used\n\tjquery: core_version,\n\n\tconstructor: jQuery,\n\tinit: function( selector, context, rootjQuery ) {\n\t\tvar match, elem;\n\n\t\t// HANDLE: $(\"\"), $(null), $(undefined), $(false)\n\t\tif ( !selector ) {\n\t\t\treturn this;\n\t\t}\n\n\t\t// Handle HTML strings\n\t\tif ( typeof selector === \"string\" ) {\n\t\t\tif ( selector.charAt(0) === \"<\" && selector.charAt( selector.length - 1 ) === \">\" && selector.length >= 3 ) {\n\t\t\t\t// Assume that strings that start and end with <> are HTML and skip the regex check\n\t\t\t\tmatch = [ null, selector, null ];\n\n\t\t\t} else {\n\t\t\t\tmatch = rquickExpr.exec( selector );\n\t\t\t}\n\n\t\t\t// Match html or make sure no context is specified for #id\n\t\t\tif ( match && (match[1] || !context) ) {\n\n\t\t\t\t// HANDLE: $(html) -> $(array)\n\t\t\t\tif ( match[1] ) {\n\t\t\t\t\tcontext = context instanceof jQuery ? context[0] : context;\n\n\t\t\t\t\t// scripts is true for back-compat\n\t\t\t\t\tjQuery.merge( this, jQuery.parseHTML(\n\t\t\t\t\t\tmatch[1],\n\t\t\t\t\t\tcontext && context.nodeType ? context.ownerDocument || context : document,\n\t\t\t\t\t\ttrue\n\t\t\t\t\t) );\n\n\t\t\t\t\t// HANDLE: $(html, props)\n\t\t\t\t\tif ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {\n\t\t\t\t\t\tfor ( match in context ) {\n\t\t\t\t\t\t\t// Properties of context are called as methods if possible\n\t\t\t\t\t\t\tif ( jQuery.isFunction( this[ match ] ) ) {\n\t\t\t\t\t\t\t\tthis[ match ]( context[ match ] );\n\n\t\t\t\t\t\t\t// ...and otherwise set as attributes\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tthis.attr( match, context[ match ] );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn this;\n\n\t\t\t\t// HANDLE: $(#id)\n\t\t\t\t} else {\n\t\t\t\t\telem = document.getElementById( match[2] );\n\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE and Opera return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id !== match[2] ) {\n\t\t\t\t\t\t\treturn rootjQuery.find( selector );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Otherwise, we inject the element directly into the jQuery object\n\t\t\t\t\t\tthis.length = 1;\n\t\t\t\t\t\tthis[0] = elem;\n\t\t\t\t\t}\n\n\t\t\t\t\tthis.context = document;\n\t\t\t\t\tthis.selector = selector;\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\n\t\t\t// HANDLE: $(expr, $(...))\n\t\t\t} else if ( !context || context.jquery ) {\n\t\t\t\treturn ( context || rootjQuery ).find( selector );\n\n\t\t\t// HANDLE: $(expr, context)\n\t\t\t// (which is just equivalent to: $(context).find(expr)\n\t\t\t} else {\n\t\t\t\treturn this.constructor( context ).find( selector );\n\t\t\t}\n\n\t\t// HANDLE: $(DOMElement)\n\t\t} else if ( selector.nodeType ) {\n\t\t\tthis.context = this[0] = selector;\n\t\t\tthis.length = 1;\n\t\t\treturn this;\n\n\t\t// HANDLE: $(function)\n\t\t// Shortcut for document ready\n\t\t} else if ( jQuery.isFunction( selector ) ) {\n\t\t\treturn rootjQuery.ready( selector );\n\t\t}\n\n\t\tif ( selector.selector !== undefined ) {\n\t\t\tthis.selector = selector.selector;\n\t\t\tthis.context = selector.context;\n\t\t}\n\n\t\treturn jQuery.makeArray( selector, this );\n\t},\n\n\t// Start with an empty selector\n\tselector: \"\",\n\n\t// The default length of a jQuery object is 0\n\tlength: 0,\n\n\ttoArray: function() {\n\t\treturn core_slice.call( this );\n\t},\n\n\t// Get the Nth element in the matched element set OR\n\t// Get the whole matched element set as a clean array\n\tget: function( num ) {\n\t\treturn num == null ?\n\n\t\t\t// Return a 'clean' array\n\t\t\tthis.toArray() :\n\n\t\t\t// Return just the object\n\t\t\t( num < 0 ? this[ this.length + num ] : this[ num ] );\n\t},\n\n\t// Take an array of elements and push it onto the stack\n\t// (returning the new matched element set)\n\tpushStack: function( elems ) {\n\n\t\t// Build a new jQuery matched element set\n\t\tvar ret = jQuery.merge( this.constructor(), elems );\n\n\t\t// Add the old object onto the stack (as a reference)\n\t\tret.prevObject = this;\n\t\tret.context = this.context;\n\n\t\t// Return the newly-formed element set\n\t\treturn ret;\n\t},\n\n\t// Execute a callback for every element in the matched set.\n\t// (You can seed the arguments with an array of args, but this is\n\t// only used internally.)\n\teach: function( callback, args ) {\n\t\treturn jQuery.each( this, callback, args );\n\t},\n\n\tready: function( fn ) {\n\t\t// Add the callback\n\t\tjQuery.ready.promise().done( fn );\n\n\t\treturn this;\n\t},\n\n\tslice: function() {\n\t\treturn this.pushStack( core_slice.apply( this, arguments ) );\n\t},\n\n\tfirst: function() {\n\t\treturn this.eq( 0 );\n\t},\n\n\tlast: function() {\n\t\treturn this.eq( -1 );\n\t},\n\n\teq: function( i ) {\n\t\tvar len = this.length,\n\t\t\tj = +i + ( i < 0 ? len : 0 );\n\t\treturn this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );\n\t},\n\n\tmap: function( callback ) {\n\t\treturn this.pushStack( jQuery.map(this, function( elem, i ) {\n\t\t\treturn callback.call( elem, i, elem );\n\t\t}));\n\t},\n\n\tend: function() {\n\t\treturn this.prevObject || this.constructor(null);\n\t},\n\n\t// For internal use only.\n\t// Behaves like an Array's method, not like a jQuery method.\n\tpush: core_push,\n\tsort: [].sort,\n\tsplice: [].splice\n};\n\n// Give the init function the jQuery prototype for later instantiation\njQuery.fn.init.prototype = jQuery.fn;\n\njQuery.extend = jQuery.fn.extend = function() {\n\tvar src, copyIsArray, copy, name, options, clone,\n\t\ttarget = arguments[0] || {},\n\t\ti = 1,\n\t\tlength = arguments.length,\n\t\tdeep = false;\n\n\t// Handle a deep copy situation\n\tif ( typeof target === \"boolean\" ) {\n\t\tdeep = target;\n\t\ttarget = arguments[1] || {};\n\t\t// skip the boolean and the target\n\t\ti = 2;\n\t}\n\n\t// Handle case when target is a string or something (possible in deep copy)\n\tif ( typeof target !== \"object\" && !jQuery.isFunction(target) ) {\n\t\ttarget = {};\n\t}\n\n\t// extend jQuery itself if only one argument is passed\n\tif ( length === i ) {\n\t\ttarget = this;\n\t\t--i;\n\t}\n\n\tfor ( ; i < length; i++ ) {\n\t\t// Only deal with non-null/undefined values\n\t\tif ( (options = arguments[ i ]) != null ) {\n\t\t\t// Extend the base object\n\t\t\tfor ( name in options ) {\n\t\t\t\tsrc = target[ name ];\n\t\t\t\tcopy = options[ name ];\n\n\t\t\t\t// Prevent never-ending loop\n\t\t\t\tif ( target === copy ) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Recurse if we're merging plain objects or arrays\n\t\t\t\tif ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {\n\t\t\t\t\tif ( copyIsArray ) {\n\t\t\t\t\t\tcopyIsArray = false;\n\t\t\t\t\t\tclone = src && jQuery.isArray(src) ? src : [];\n\n\t\t\t\t\t} else {\n\t\t\t\t\t\tclone = src && jQuery.isPlainObject(src) ? src : {};\n\t\t\t\t\t}\n\n\t\t\t\t\t// Never move original objects, clone them\n\t\t\t\t\ttarget[ name ] = jQuery.extend( deep, clone, copy );\n\n\t\t\t\t// Don't bring in undefined values\n\t\t\t\t} else if ( copy !== undefined ) {\n\t\t\t\t\ttarget[ name ] = copy;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Return the modified object\n\treturn target;\n};\n\njQuery.extend({\n\t// Unique for each copy of jQuery on the page\n\t// Non-digits removed to match rinlinejQuery\n\texpando: \"jQuery\" + ( core_version + Math.random() ).replace( /\\D/g, \"\" ),\n\n\tnoConflict: function( deep ) {\n\t\tif ( window.$ === jQuery ) {\n\t\t\twindow.$ = _$;\n\t\t}\n\n\t\tif ( deep && window.jQuery === jQuery ) {\n\t\t\twindow.jQuery = _jQuery;\n\t\t}\n\n\t\treturn jQuery;\n\t},\n\n\t// Is the DOM ready to be used? Set to true once it occurs.\n\tisReady: false,\n\n\t// A counter to track how many items to wait for before\n\t// the ready event fires. See #6781\n\treadyWait: 1,\n\n\t// Hold (or release) the ready event\n\tholdReady: function( hold ) {\n\t\tif ( hold ) {\n\t\t\tjQuery.readyWait++;\n\t\t} else {\n\t\t\tjQuery.ready( true );\n\t\t}\n\t},\n\n\t// Handle when the DOM is ready\n\tready: function( wait ) {\n\n\t\t// Abort if there are pending holds or we're already ready\n\t\tif ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).\n\t\tif ( !document.body ) {\n\t\t\treturn setTimeout( jQuery.ready );\n\t\t}\n\n\t\t// Remember that the DOM is ready\n\t\tjQuery.isReady = true;\n\n\t\t// If a normal DOM Ready event fired, decrement, and wait if need be\n\t\tif ( wait !== true && --jQuery.readyWait > 0 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If there are functions bound, to execute\n\t\treadyList.resolveWith( document, [ jQuery ] );\n\n\t\t// Trigger any bound ready events\n\t\tif ( jQuery.fn.trigger ) {\n\t\t\tjQuery( document ).trigger(\"ready\").off(\"ready\");\n\t\t}\n\t},\n\n\t// See test/unit/core.js for details concerning isFunction.\n\t// Since version 1.3, DOM methods and functions like alert\n\t// aren't supported. They return false on IE (#2968).\n\tisFunction: function( obj ) {\n\t\treturn jQuery.type(obj) === \"function\";\n\t},\n\n\tisArray: Array.isArray || function( obj ) {\n\t\treturn jQuery.type(obj) === \"array\";\n\t},\n\n\tisWindow: function( obj ) {\n\t\t/* jshint eqeqeq: false */\n\t\treturn obj != null && obj == obj.window;\n\t},\n\n\tisNumeric: function( obj ) {\n\t\treturn !isNaN( parseFloat(obj) ) && isFinite( obj );\n\t},\n\n\ttype: function( obj ) {\n\t\tif ( obj == null ) {\n\t\t\treturn String( obj );\n\t\t}\n\t\treturn typeof obj === \"object\" || typeof obj === \"function\" ?\n\t\t\tclass2type[ core_toString.call(obj) ] || \"object\" :\n\t\t\ttypeof obj;\n\t},\n\n\tisPlainObject: function( obj ) {\n\t\tvar key;\n\n\t\t// Must be an Object.\n\t\t// Because of IE, we also have to check the presence of the constructor property.\n\t\t// Make sure that DOM nodes and window objects don't pass through, as well\n\t\tif ( !obj || jQuery.type(obj) !== \"object\" || obj.nodeType || jQuery.isWindow( obj ) ) {\n\t\t\treturn false;\n\t\t}\n\n\t\ttry {\n\t\t\t// Not own constructor property must be Object\n\t\t\tif ( obj.constructor &&\n\t\t\t\t!core_hasOwn.call(obj, \"constructor\") &&\n\t\t\t\t!core_hasOwn.call(obj.constructor.prototype, \"isPrototypeOf\") ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} catch ( e ) {\n\t\t\t// IE8,9 Will throw exceptions on certain host objects #9897\n\t\t\treturn false;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Handle iteration over inherited properties before own properties.\n\t\tif ( jQuery.support.ownLast ) {\n\t\t\tfor ( key in obj ) {\n\t\t\t\treturn core_hasOwn.call( obj, key );\n\t\t\t}\n\t\t}\n\n\t\t// Own properties are enumerated firstly, so to speed up,\n\t\t// if last one is own, then all properties are own.\n\t\tfor ( key in obj ) {}\n\n\t\treturn key === undefined || core_hasOwn.call( obj, key );\n\t},\n\n\tisEmptyObject: function( obj ) {\n\t\tvar name;\n\t\tfor ( name in obj ) {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t},\n\n\terror: function( msg ) {\n\t\tthrow new Error( msg );\n\t},\n\n\t// data: string of html\n\t// context (optional): If specified, the fragment will be created in this context, defaults to document\n\t// keepScripts (optional): If true, will include scripts passed in the html string\n\tparseHTML: function( data, context, keepScripts ) {\n\t\tif ( !data || typeof data !== \"string\" ) {\n\t\t\treturn null;\n\t\t}\n\t\tif ( typeof context === \"boolean\" ) {\n\t\t\tkeepScripts = context;\n\t\t\tcontext = false;\n\t\t}\n\t\tcontext = context || document;\n\n\t\tvar parsed = rsingleTag.exec( data ),\n\t\t\tscripts = !keepScripts && [];\n\n\t\t// Single tag\n\t\tif ( parsed ) {\n\t\t\treturn [ context.createElement( parsed[1] ) ];\n\t\t}\n\n\t\tparsed = jQuery.buildFragment( [ data ], context, scripts );\n\t\tif ( scripts ) {\n\t\t\tjQuery( scripts ).remove();\n\t\t}\n\t\treturn jQuery.merge( [], parsed.childNodes );\n\t},\n\n\tparseJSON: function( data ) {\n\t\t// Attempt to parse using the native JSON parser first\n\t\tif ( window.JSON && window.JSON.parse ) {\n\t\t\treturn window.JSON.parse( data );\n\t\t}\n\n\t\tif ( data === null ) {\n\t\t\treturn data;\n\t\t}\n\n\t\tif ( typeof data === \"string\" ) {\n\n\t\t\t// Make sure leading/trailing whitespace is removed (IE can't handle it)\n\t\t\tdata = jQuery.trim( data );\n\n\t\t\tif ( data ) {\n\t\t\t\t// Make sure the incoming data is actual JSON\n\t\t\t\t// Logic borrowed from http://json.org/json2.js\n\t\t\t\tif ( rvalidchars.test( data.replace( rvalidescape, \"@\" )\n\t\t\t\t\t.replace( rvalidtokens, \"]\" )\n\t\t\t\t\t.replace( rvalidbraces, \"\")) ) {\n\n\t\t\t\t\treturn ( new Function( \"return \" + data ) )();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tjQuery.error( \"Invalid JSON: \" + data );\n\t},\n\n\t// Cross-browser xml parsing\n\tparseXML: function( data ) {\n\t\tvar xml, tmp;\n\t\tif ( !data || typeof data !== \"string\" ) {\n\t\t\treturn null;\n\t\t}\n\t\ttry {\n\t\t\tif ( window.DOMParser ) { // Standard\n\t\t\t\ttmp = new DOMParser();\n\t\t\t\txml = tmp.parseFromString( data , \"text/xml\" );\n\t\t\t} else { // IE\n\t\t\t\txml = new ActiveXObject( \"Microsoft.XMLDOM\" );\n\t\t\t\txml.async = \"false\";\n\t\t\t\txml.loadXML( data );\n\t\t\t}\n\t\t} catch( e ) {\n\t\t\txml = undefined;\n\t\t}\n\t\tif ( !xml || !xml.documentElement || xml.getElementsByTagName( \"parsererror\" ).length ) {\n\t\t\tjQuery.error( \"Invalid XML: \" + data );\n\t\t}\n\t\treturn xml;\n\t},\n\n\tnoop: function() {},\n\n\t// Evaluates a script in a global context\n\t// Workarounds based on findings by Jim Driscoll\n\t// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context\n\tglobalEval: function( data ) {\n\t\tif ( data && jQuery.trim( data ) ) {\n\t\t\t// We use execScript on Internet Explorer\n\t\t\t// We use an anonymous function so that context is window\n\t\t\t// rather than jQuery in Firefox\n\t\t\t( window.execScript || function( data ) {\n\t\t\t\twindow[ \"eval\" ].call( window, data );\n\t\t\t} )( data );\n\t\t}\n\t},\n\n\t// Convert dashed to camelCase; used by the css and data modules\n\t// Microsoft forgot to hump their vendor prefix (#9572)\n\tcamelCase: function( string ) {\n\t\treturn string.replace( rmsPrefix, \"ms-\" ).replace( rdashAlpha, fcamelCase );\n\t},\n\n\tnodeName: function( elem, name ) {\n\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();\n\t},\n\n\t// args is for internal usage only\n\teach: function( obj, callback, args ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = obj.length,\n\t\t\tisArray = isArraylike( obj );\n\n\t\tif ( args ) {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.apply( obj[ i ], args );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// A special, fast, case for the most common use of each\n\t\t} else {\n\t\t\tif ( isArray ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( i in obj ) {\n\t\t\t\t\tvalue = callback.call( obj[ i ], i, obj[ i ] );\n\n\t\t\t\t\tif ( value === false ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn obj;\n\t},\n\n\t// Use native String.trim function wherever possible\n\ttrim: core_trim && !core_trim.call(\"\\uFEFF\\xA0\") ?\n\t\tfunction( text ) {\n\t\t\treturn text == null ?\n\t\t\t\t\"\" :\n\t\t\t\tcore_trim.call( text );\n\t\t} :\n\n\t\t// Otherwise use our own trimming functionality\n\t\tfunction( text ) {\n\t\t\treturn text == null ?\n\t\t\t\t\"\" :\n\t\t\t\t( text + \"\" ).replace( rtrim, \"\" );\n\t\t},\n\n\t// results is for internal usage only\n\tmakeArray: function( arr, results ) {\n\t\tvar ret = results || [];\n\n\t\tif ( arr != null ) {\n\t\t\tif ( isArraylike( Object(arr) ) ) {\n\t\t\t\tjQuery.merge( ret,\n\t\t\t\t\ttypeof arr === \"string\" ?\n\t\t\t\t\t[ arr ] : arr\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tcore_push.call( ret, arr );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\tinArray: function( elem, arr, i ) {\n\t\tvar len;\n\n\t\tif ( arr ) {\n\t\t\tif ( core_indexOf ) {\n\t\t\t\treturn core_indexOf.call( arr, elem, i );\n\t\t\t}\n\n\t\t\tlen = arr.length;\n\t\t\ti = i ? i < 0 ? Math.max( 0, len + i ) : i : 0;\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t// Skip accessing in sparse arrays\n\t\t\t\tif ( i in arr && arr[ i ] === elem ) {\n\t\t\t\t\treturn i;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn -1;\n\t},\n\n\tmerge: function( first, second ) {\n\t\tvar l = second.length,\n\t\t\ti = first.length,\n\t\t\tj = 0;\n\n\t\tif ( typeof l === \"number\" ) {\n\t\t\tfor ( ; j < l; j++ ) {\n\t\t\t\tfirst[ i++ ] = second[ j ];\n\t\t\t}\n\t\t} else {\n\t\t\twhile ( second[j] !== undefined ) {\n\t\t\t\tfirst[ i++ ] = second[ j++ ];\n\t\t\t}\n\t\t}\n\n\t\tfirst.length = i;\n\n\t\treturn first;\n\t},\n\n\tgrep: function( elems, callback, inv ) {\n\t\tvar retVal,\n\t\t\tret = [],\n\t\t\ti = 0,\n\t\t\tlength = elems.length;\n\t\tinv = !!inv;\n\n\t\t// Go through the array, only saving the items\n\t\t// that pass the validator function\n\t\tfor ( ; i < length; i++ ) {\n\t\t\tretVal = !!callback( elems[ i ], i );\n\t\t\tif ( inv !== retVal ) {\n\t\t\t\tret.push( elems[ i ] );\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t},\n\n\t// arg is for internal usage only\n\tmap: function( elems, callback, arg ) {\n\t\tvar value,\n\t\t\ti = 0,\n\t\t\tlength = elems.length,\n\t\t\tisArray = isArraylike( elems ),\n\t\t\tret = [];\n\n\t\t// Go through the array, translating each of the items to their\n\t\tif ( isArray ) {\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret[ ret.length ] = value;\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Go through every key on the object,\n\t\t} else {\n\t\t\tfor ( i in elems ) {\n\t\t\t\tvalue = callback( elems[ i ], i, arg );\n\n\t\t\t\tif ( value != null ) {\n\t\t\t\t\tret[ ret.length ] = value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Flatten any nested arrays\n\t\treturn core_concat.apply( [], ret );\n\t},\n\n\t// A global GUID counter for objects\n\tguid: 1,\n\n\t// Bind a function to a context, optionally partially applying any\n\t// arguments.\n\tproxy: function( fn, context ) {\n\t\tvar args, proxy, tmp;\n\n\t\tif ( typeof context === \"string\" ) {\n\t\t\ttmp = fn[ context ];\n\t\t\tcontext = fn;\n\t\t\tfn = tmp;\n\t\t}\n\n\t\t// Quick check to determine if target is callable, in the spec\n\t\t// this throws a TypeError, but we will just return undefined.\n\t\tif ( !jQuery.isFunction( fn ) ) {\n\t\t\treturn undefined;\n\t\t}\n\n\t\t// Simulated bind\n\t\targs = core_slice.call( arguments, 2 );\n\t\tproxy = function() {\n\t\t\treturn fn.apply( context || this, args.concat( core_slice.call( arguments ) ) );\n\t\t};\n\n\t\t// Set the guid of unique handler to the same of original handler, so it can be removed\n\t\tproxy.guid = fn.guid = fn.guid || jQuery.guid++;\n\n\t\treturn proxy;\n\t},\n\n\t// Multifunctional method to get and set values of a collection\n\t// The value/s can optionally be executed if it's a function\n\taccess: function( elems, fn, key, value, chainable, emptyGet, raw ) {\n\t\tvar i = 0,\n\t\t\tlength = elems.length,\n\t\t\tbulk = key == null;\n\n\t\t// Sets many values\n\t\tif ( jQuery.type( key ) === \"object\" ) {\n\t\t\tchainable = true;\n\t\t\tfor ( i in key ) {\n\t\t\t\tjQuery.access( elems, fn, i, key[i], true, emptyGet, raw );\n\t\t\t}\n\n\t\t// Sets one value\n\t\t} else if ( value !== undefined ) {\n\t\t\tchainable = true;\n\n\t\t\tif ( !jQuery.isFunction( value ) ) {\n\t\t\t\traw = true;\n\t\t\t}\n\n\t\t\tif ( bulk ) {\n\t\t\t\t// Bulk operations run against the entire set\n\t\t\t\tif ( raw ) {\n\t\t\t\t\tfn.call( elems, value );\n\t\t\t\t\tfn = null;\n\n\t\t\t\t// ...except when executing function values\n\t\t\t\t} else {\n\t\t\t\t\tbulk = fn;\n\t\t\t\t\tfn = function( elem, key, value ) {\n\t\t\t\t\t\treturn bulk.call( jQuery( elem ), value );\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( fn ) {\n\t\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\t\tfn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn chainable ?\n\t\t\telems :\n\n\t\t\t// Gets\n\t\t\tbulk ?\n\t\t\t\tfn.call( elems ) :\n\t\t\t\tlength ? fn( elems[0], key ) : emptyGet;\n\t},\n\n\tnow: function() {\n\t\treturn ( new Date() ).getTime();\n\t},\n\n\t// A method for quickly swapping in/out CSS properties to get correct calculations.\n\t// Note: this method belongs to the css module but it's needed here for the support module.\n\t// If support gets modularized, this method should be moved back to the css module.\n\tswap: function( elem, options, callback, args ) {\n\t\tvar ret, name,\n\t\t\told = {};\n\n\t\t// Remember the old values, and insert the new ones\n\t\tfor ( name in options ) {\n\t\t\told[ name ] = elem.style[ name ];\n\t\t\telem.style[ name ] = options[ name ];\n\t\t}\n\n\t\tret = callback.apply( elem, args || [] );\n\n\t\t// Revert the old values\n\t\tfor ( name in options ) {\n\t\t\telem.style[ name ] = old[ name ];\n\t\t}\n\n\t\treturn ret;\n\t}\n});\n\njQuery.ready.promise = function( obj ) {\n\tif ( !readyList ) {\n\n\t\treadyList = jQuery.Deferred();\n\n\t\t// Catch cases where $(document).ready() is called after the browser event has already occurred.\n\t\t// we once tried to use readyState \"interactive\" here, but it caused issues like the one\n\t\t// discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15\n\t\tif ( document.readyState === \"complete\" ) {\n\t\t\t// Handle it asynchronously to allow scripts the opportunity to delay ready\n\t\t\tsetTimeout( jQuery.ready );\n\n\t\t// Standards-based browsers support DOMContentLoaded\n\t\t} else if ( document.addEventListener ) {\n\t\t\t// Use the handy event callback\n\t\t\tdocument.addEventListener( \"DOMContentLoaded\", completed, false );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.addEventListener( \"load\", completed, false );\n\n\t\t// If IE event model is used\n\t\t} else {\n\t\t\t// Ensure firing before onload, maybe late but safe also for iframes\n\t\t\tdocument.attachEvent( \"onreadystatechange\", completed );\n\n\t\t\t// A fallback to window.onload, that will always work\n\t\t\twindow.attachEvent( \"onload\", completed );\n\n\t\t\t// If IE and not a frame\n\t\t\t// continually check to see if the document is ready\n\t\t\tvar top = false;\n\n\t\t\ttry {\n\t\t\t\ttop = window.frameElement == null && document.documentElement;\n\t\t\t} catch(e) {}\n\n\t\t\tif ( top && top.doScroll ) {\n\t\t\t\t(function doScrollCheck() {\n\t\t\t\t\tif ( !jQuery.isReady ) {\n\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t// Use the trick by Diego Perini\n\t\t\t\t\t\t\t// http://javascript.nwbox.com/IEContentLoaded/\n\t\t\t\t\t\t\ttop.doScroll(\"left\");\n\t\t\t\t\t\t} catch(e) {\n\t\t\t\t\t\t\treturn setTimeout( doScrollCheck, 50 );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// detach all dom ready events\n\t\t\t\t\t\tdetach();\n\n\t\t\t\t\t\t// and execute any waiting functions\n\t\t\t\t\t\tjQuery.ready();\n\t\t\t\t\t}\n\t\t\t\t})();\n\t\t\t}\n\t\t}\n\t}\n\treturn readyList.promise( obj );\n};\n\n// Populate the class2type map\njQuery.each(\"Boolean Number String Function Array Date RegExp Object Error\".split(\" \"), function(i, name) {\n\tclass2type[ \"[object \" + name + \"]\" ] = name.toLowerCase();\n});\n\nfunction isArraylike( obj ) {\n\tvar length = obj.length,\n\t\ttype = jQuery.type( obj );\n\n\tif ( jQuery.isWindow( obj ) ) {\n\t\treturn false;\n\t}\n\n\tif ( obj.nodeType === 1 && length ) {\n\t\treturn true;\n\t}\n\n\treturn type === \"array\" || type !== \"function\" &&\n\t\t( length === 0 ||\n\t\ttypeof length === \"number\" && length > 0 && ( length - 1 ) in obj );\n}\n\n// All jQuery objects should point back to these\nrootjQuery = jQuery(document);\n/*!\n * Sizzle CSS Selector Engine v1.10.2\n * http://sizzlejs.com/\n *\n * Copyright 2013 jQuery Foundation, Inc. and other contributors\n * Released under the MIT license\n * http://jquery.org/license\n *\n * Date: 2013-07-03\n */\n(function( window, undefined ) {\n\nvar i,\n\tsupport,\n\tcachedruns,\n\tExpr,\n\tgetText,\n\tisXML,\n\tcompile,\n\toutermostContext,\n\tsortInput,\n\n\t// Local document vars\n\tsetDocument,\n\tdocument,\n\tdocElem,\n\tdocumentIsHTML,\n\trbuggyQSA,\n\trbuggyMatches,\n\tmatches,\n\tcontains,\n\n\t// Instance-specific data\n\texpando = \"sizzle\" + -(new Date()),\n\tpreferredDoc = window.document,\n\tdirruns = 0,\n\tdone = 0,\n\tclassCache = createCache(),\n\ttokenCache = createCache(),\n\tcompilerCache = createCache(),\n\thasDuplicate = false,\n\tsortOrder = function( a, b ) {\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\t\treturn 0;\n\t},\n\n\t// General-purpose constants\n\tstrundefined = typeof undefined,\n\tMAX_NEGATIVE = 1 << 31,\n\n\t// Instance methods\n\thasOwn = ({}).hasOwnProperty,\n\tarr = [],\n\tpop = arr.pop,\n\tpush_native = arr.push,\n\tpush = arr.push,\n\tslice = arr.slice,\n\t// Use a stripped-down indexOf if we can't use a native one\n\tindexOf = arr.indexOf || function( elem ) {\n\t\tvar i = 0,\n\t\t\tlen = this.length;\n\t\tfor ( ; i < len; i++ ) {\n\t\t\tif ( this[i] === elem ) {\n\t\t\t\treturn i;\n\t\t\t}\n\t\t}\n\t\treturn -1;\n\t},\n\n\tbooleans = \"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped\",\n\n\t// Regular expressions\n\n\t// Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace\n\twhitespace = \"[\\\\x20\\\\t\\\\r\\\\n\\\\f]\",\n\t// http://www.w3.org/TR/css3-syntax/#characters\n\tcharacterEncoding = \"(?:\\\\\\\\.|[\\\\w-]|[^\\\\x00-\\\\xa0])+\",\n\n\t// Loosely modeled on CSS identifier characters\n\t// An unquoted value should be a CSS identifier http://www.w3.org/TR/css3-selectors/#attribute-selectors\n\t// Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier\n\tidentifier = characterEncoding.replace( \"w\", \"w#\" ),\n\n\t// Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors\n\tattributes = \"\\\\[\" + whitespace + \"*(\" + characterEncoding + \")\" + whitespace +\n\t\t\"*(?:([*^$|!~]?=)\" + whitespace + \"*(?:(['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|(\" + identifier + \")|)|)\" + whitespace + \"*\\\\]\",\n\n\t// Prefer arguments quoted,\n\t//   then not containing pseudos/brackets,\n\t//   then attribute selectors/non-parenthetical expressions,\n\t//   then anything else\n\t// These preferences are here to reduce the number of selectors\n\t//   needing tokenize in the PSEUDO preFilter\n\tpseudos = \":(\" + characterEncoding + \")(?:\\\\(((['\\\"])((?:\\\\\\\\.|[^\\\\\\\\])*?)\\\\3|((?:\\\\\\\\.|[^\\\\\\\\()[\\\\]]|\" + attributes.replace( 3, 8 ) + \")*)|.*)\\\\)|)\",\n\n\t// Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter\n\trtrim = new RegExp( \"^\" + whitespace + \"+|((?:^|[^\\\\\\\\])(?:\\\\\\\\.)*)\" + whitespace + \"+$\", \"g\" ),\n\n\trcomma = new RegExp( \"^\" + whitespace + \"*,\" + whitespace + \"*\" ),\n\trcombinators = new RegExp( \"^\" + whitespace + \"*([>+~]|\" + whitespace + \")\" + whitespace + \"*\" ),\n\n\trsibling = new RegExp( whitespace + \"*[+~]\" ),\n\trattributeQuotes = new RegExp( \"=\" + whitespace + \"*([^\\\\]'\\\"]*)\" + whitespace + \"*\\\\]\", \"g\" ),\n\n\trpseudo = new RegExp( pseudos ),\n\tridentifier = new RegExp( \"^\" + identifier + \"$\" ),\n\n\tmatchExpr = {\n\t\t\"ID\": new RegExp( \"^#(\" + characterEncoding + \")\" ),\n\t\t\"CLASS\": new RegExp( \"^\\\\.(\" + characterEncoding + \")\" ),\n\t\t\"TAG\": new RegExp( \"^(\" + characterEncoding.replace( \"w\", \"w*\" ) + \")\" ),\n\t\t\"ATTR\": new RegExp( \"^\" + attributes ),\n\t\t\"PSEUDO\": new RegExp( \"^\" + pseudos ),\n\t\t\"CHILD\": new RegExp( \"^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\\\(\" + whitespace +\n\t\t\t\"*(even|odd|(([+-]|)(\\\\d*)n|)\" + whitespace + \"*(?:([+-]|)\" + whitespace +\n\t\t\t\"*(\\\\d+)|))\" + whitespace + \"*\\\\)|)\", \"i\" ),\n\t\t\"bool\": new RegExp( \"^(?:\" + booleans + \")$\", \"i\" ),\n\t\t// For use in libraries implementing .is()\n\t\t// We use this for POS matching in `select`\n\t\t\"needsContext\": new RegExp( \"^\" + whitespace + \"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\\\(\" +\n\t\t\twhitespace + \"*((?:-\\\\d)?\\\\d*)\" + whitespace + \"*\\\\)|)(?=[^-]|$)\", \"i\" )\n\t},\n\n\trnative = /^[^{]+\\{\\s*\\[native \\w/,\n\n\t// Easily-parseable/retrievable ID or TAG or CLASS selectors\n\trquickExpr = /^(?:#([\\w-]+)|(\\w+)|\\.([\\w-]+))$/,\n\n\trinputs = /^(?:input|select|textarea|button)$/i,\n\trheader = /^h\\d$/i,\n\n\trescape = /'|\\\\/g,\n\n\t// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters\n\trunescape = new RegExp( \"\\\\\\\\([\\\\da-f]{1,6}\" + whitespace + \"?|(\" + whitespace + \")|.)\", \"ig\" ),\n\tfunescape = function( _, escaped, escapedWhitespace ) {\n\t\tvar high = \"0x\" + escaped - 0x10000;\n\t\t// NaN means non-codepoint\n\t\t// Support: Firefox\n\t\t// Workaround erroneous numeric interpretation of +\"0x\"\n\t\treturn high !== high || escapedWhitespace ?\n\t\t\tescaped :\n\t\t\t// BMP codepoint\n\t\t\thigh < 0 ?\n\t\t\t\tString.fromCharCode( high + 0x10000 ) :\n\t\t\t\t// Supplemental Plane codepoint (surrogate pair)\n\t\t\t\tString.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );\n\t};\n\n// Optimize for push.apply( _, NodeList )\ntry {\n\tpush.apply(\n\t\t(arr = slice.call( preferredDoc.childNodes )),\n\t\tpreferredDoc.childNodes\n\t);\n\t// Support: Android<4.0\n\t// Detect silently failing push.apply\n\tarr[ preferredDoc.childNodes.length ].nodeType;\n} catch ( e ) {\n\tpush = { apply: arr.length ?\n\n\t\t// Leverage slice if possible\n\t\tfunction( target, els ) {\n\t\t\tpush_native.apply( target, slice.call(els) );\n\t\t} :\n\n\t\t// Support: IE<9\n\t\t// Otherwise append directly\n\t\tfunction( target, els ) {\n\t\t\tvar j = target.length,\n\t\t\t\ti = 0;\n\t\t\t// Can't trust NodeList.length\n\t\t\twhile ( (target[j++] = els[i++]) ) {}\n\t\t\ttarget.length = j - 1;\n\t\t}\n\t};\n}\n\nfunction Sizzle( selector, context, results, seed ) {\n\tvar match, elem, m, nodeType,\n\t\t// QSA vars\n\t\ti, groups, old, nid, newContext, newSelector;\n\n\tif ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\n\tcontext = context || document;\n\tresults = results || [];\n\n\tif ( !selector || typeof selector !== \"string\" ) {\n\t\treturn results;\n\t}\n\n\tif ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {\n\t\treturn [];\n\t}\n\n\tif ( documentIsHTML && !seed ) {\n\n\t\t// Shortcuts\n\t\tif ( (match = rquickExpr.exec( selector )) ) {\n\t\t\t// Speed-up: Sizzle(\"#ID\")\n\t\t\tif ( (m = match[1]) ) {\n\t\t\t\tif ( nodeType === 9 ) {\n\t\t\t\t\telem = context.getElementById( m );\n\t\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\t\tif ( elem && elem.parentNode ) {\n\t\t\t\t\t\t// Handle the case where IE, Opera, and Webkit return items\n\t\t\t\t\t\t// by name instead of ID\n\t\t\t\t\t\tif ( elem.id === m ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Context is not a document\n\t\t\t\t\tif ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) &&\n\t\t\t\t\t\tcontains( context, elem ) && elem.id === m ) {\n\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\treturn results;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Speed-up: Sizzle(\"TAG\")\n\t\t\t} else if ( match[2] ) {\n\t\t\t\tpush.apply( results, context.getElementsByTagName( selector ) );\n\t\t\t\treturn results;\n\n\t\t\t// Speed-up: Sizzle(\".CLASS\")\n\t\t\t} else if ( (m = match[3]) && support.getElementsByClassName && context.getElementsByClassName ) {\n\t\t\t\tpush.apply( results, context.getElementsByClassName( m ) );\n\t\t\t\treturn results;\n\t\t\t}\n\t\t}\n\n\t\t// QSA path\n\t\tif ( support.qsa && (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {\n\t\t\tnid = old = expando;\n\t\t\tnewContext = context;\n\t\t\tnewSelector = nodeType === 9 && selector;\n\n\t\t\t// qSA works strangely on Element-rooted queries\n\t\t\t// We can work around this by specifying an extra ID on the root\n\t\t\t// and working up from there (Thanks to Andrew Dupont for the technique)\n\t\t\t// IE 8 doesn't work on object elements\n\t\t\tif ( nodeType === 1 && context.nodeName.toLowerCase() !== \"object\" ) {\n\t\t\t\tgroups = tokenize( selector );\n\n\t\t\t\tif ( (old = context.getAttribute(\"id\")) ) {\n\t\t\t\t\tnid = old.replace( rescape, \"\\\\$&\" );\n\t\t\t\t} else {\n\t\t\t\t\tcontext.setAttribute( \"id\", nid );\n\t\t\t\t}\n\t\t\t\tnid = \"[id='\" + nid + \"'] \";\n\n\t\t\t\ti = groups.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tgroups[i] = nid + toSelector( groups[i] );\n\t\t\t\t}\n\t\t\t\tnewContext = rsibling.test( selector ) && context.parentNode || context;\n\t\t\t\tnewSelector = groups.join(\",\");\n\t\t\t}\n\n\t\t\tif ( newSelector ) {\n\t\t\t\ttry {\n\t\t\t\t\tpush.apply( results,\n\t\t\t\t\t\tnewContext.querySelectorAll( newSelector )\n\t\t\t\t\t);\n\t\t\t\t\treturn results;\n\t\t\t\t} catch(qsaError) {\n\t\t\t\t} finally {\n\t\t\t\t\tif ( !old ) {\n\t\t\t\t\t\tcontext.removeAttribute(\"id\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// All others\n\treturn select( selector.replace( rtrim, \"$1\" ), context, results, seed );\n}\n\n/**\n * Create key-value caches of limited size\n * @returns {Function(string, Object)} Returns the Object data after storing it on itself with\n *\tproperty name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)\n *\tdeleting the oldest entry\n */\nfunction createCache() {\n\tvar keys = [];\n\n\tfunction cache( key, value ) {\n\t\t// Use (key + \" \") to avoid collision with native prototype properties (see Issue #157)\n\t\tif ( keys.push( key += \" \" ) > Expr.cacheLength ) {\n\t\t\t// Only keep the most recent entries\n\t\t\tdelete cache[ keys.shift() ];\n\t\t}\n\t\treturn (cache[ key ] = value);\n\t}\n\treturn cache;\n}\n\n/**\n * Mark a function for special use by Sizzle\n * @param {Function} fn The function to mark\n */\nfunction markFunction( fn ) {\n\tfn[ expando ] = true;\n\treturn fn;\n}\n\n/**\n * Support testing using an element\n * @param {Function} fn Passed the created div and expects a boolean result\n */\nfunction assert( fn ) {\n\tvar div = document.createElement(\"div\");\n\n\ttry {\n\t\treturn !!fn( div );\n\t} catch (e) {\n\t\treturn false;\n\t} finally {\n\t\t// Remove from its parent by default\n\t\tif ( div.parentNode ) {\n\t\t\tdiv.parentNode.removeChild( div );\n\t\t}\n\t\t// release memory in IE\n\t\tdiv = null;\n\t}\n}\n\n/**\n * Adds the same handler for all of the specified attrs\n * @param {String} attrs Pipe-separated list of attributes\n * @param {Function} handler The method that will be applied\n */\nfunction addHandle( attrs, handler ) {\n\tvar arr = attrs.split(\"|\"),\n\t\ti = attrs.length;\n\n\twhile ( i-- ) {\n\t\tExpr.attrHandle[ arr[i] ] = handler;\n\t}\n}\n\n/**\n * Checks document order of two siblings\n * @param {Element} a\n * @param {Element} b\n * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b\n */\nfunction siblingCheck( a, b ) {\n\tvar cur = b && a,\n\t\tdiff = cur && a.nodeType === 1 && b.nodeType === 1 &&\n\t\t\t( ~b.sourceIndex || MAX_NEGATIVE ) -\n\t\t\t( ~a.sourceIndex || MAX_NEGATIVE );\n\n\t// Use IE sourceIndex if available on both nodes\n\tif ( diff ) {\n\t\treturn diff;\n\t}\n\n\t// Check if b follows a\n\tif ( cur ) {\n\t\twhile ( (cur = cur.nextSibling) ) {\n\t\t\tif ( cur === b ) {\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn a ? 1 : -1;\n}\n\n/**\n * Returns a function to use in pseudos for input types\n * @param {String} type\n */\nfunction createInputPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn name === \"input\" && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for buttons\n * @param {String} type\n */\nfunction createButtonPseudo( type ) {\n\treturn function( elem ) {\n\t\tvar name = elem.nodeName.toLowerCase();\n\t\treturn (name === \"input\" || name === \"button\") && elem.type === type;\n\t};\n}\n\n/**\n * Returns a function to use in pseudos for positionals\n * @param {Function} fn\n */\nfunction createPositionalPseudo( fn ) {\n\treturn markFunction(function( argument ) {\n\t\targument = +argument;\n\t\treturn markFunction(function( seed, matches ) {\n\t\t\tvar j,\n\t\t\t\tmatchIndexes = fn( [], seed.length, argument ),\n\t\t\t\ti = matchIndexes.length;\n\n\t\t\t// Match elements found at the specified indexes\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( seed[ (j = matchIndexes[i]) ] ) {\n\t\t\t\t\tseed[j] = !(matches[j] = seed[j]);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t});\n}\n\n/**\n * Detect xml\n * @param {Element|Object} elem An element or a document\n */\nisXML = Sizzle.isXML = function( elem ) {\n\t// documentElement is verified for cases where it doesn't yet exist\n\t// (such as loading iframes in IE - #4833)\n\tvar documentElement = elem && (elem.ownerDocument || elem).documentElement;\n\treturn documentElement ? documentElement.nodeName !== \"HTML\" : false;\n};\n\n// Expose support vars for convenience\nsupport = Sizzle.support = {};\n\n/**\n * Sets document-related variables once based on the current document\n * @param {Element|Object} [doc] An element or document object to use to set the document\n * @returns {Object} Returns the current document\n */\nsetDocument = Sizzle.setDocument = function( node ) {\n\tvar doc = node ? node.ownerDocument || node : preferredDoc,\n\t\tparent = doc.defaultView;\n\n\t// If no document and documentElement is available, return\n\tif ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {\n\t\treturn document;\n\t}\n\n\t// Set our document\n\tdocument = doc;\n\tdocElem = doc.documentElement;\n\n\t// Support tests\n\tdocumentIsHTML = !isXML( doc );\n\n\t// Support: IE>8\n\t// If iframe document is assigned to \"document\" variable and if iframe has been reloaded,\n\t// IE will throw \"permission denied\" error when accessing \"document\" variable, see jQuery #13936\n\t// IE6-8 do not support the defaultView property so parent will be undefined\n\tif ( parent && parent.attachEvent && parent !== parent.top ) {\n\t\tparent.attachEvent( \"onbeforeunload\", function() {\n\t\t\tsetDocument();\n\t\t});\n\t}\n\n\t/* Attributes\n\t---------------------------------------------------------------------- */\n\n\t// Support: IE<8\n\t// Verify that getAttribute really returns attributes and not properties (excepting IE8 booleans)\n\tsupport.attributes = assert(function( div ) {\n\t\tdiv.className = \"i\";\n\t\treturn !div.getAttribute(\"className\");\n\t});\n\n\t/* getElement(s)By*\n\t---------------------------------------------------------------------- */\n\n\t// Check if getElementsByTagName(\"*\") returns only elements\n\tsupport.getElementsByTagName = assert(function( div ) {\n\t\tdiv.appendChild( doc.createComment(\"\") );\n\t\treturn !div.getElementsByTagName(\"*\").length;\n\t});\n\n\t// Check if getElementsByClassName can be trusted\n\tsupport.getElementsByClassName = assert(function( div ) {\n\t\tdiv.innerHTML = \"<div class='a'></div><div class='a i'></div>\";\n\n\t\t// Support: Safari<4\n\t\t// Catch class over-caching\n\t\tdiv.firstChild.className = \"i\";\n\t\t// Support: Opera<10\n\t\t// Catch gEBCN failure to find non-leading classes\n\t\treturn div.getElementsByClassName(\"i\").length === 2;\n\t});\n\n\t// Support: IE<10\n\t// Check if getElementById returns elements by name\n\t// The broken getElementById methods don't pick up programatically-set names,\n\t// so use a roundabout getElementsByName test\n\tsupport.getById = assert(function( div ) {\n\t\tdocElem.appendChild( div ).id = expando;\n\t\treturn !doc.getElementsByName || !doc.getElementsByName( expando ).length;\n\t});\n\n\t// ID find and filter\n\tif ( support.getById ) {\n\t\tExpr.find[\"ID\"] = function( id, context ) {\n\t\t\tif ( typeof context.getElementById !== strundefined && documentIsHTML ) {\n\t\t\t\tvar m = context.getElementById( id );\n\t\t\t\t// Check parentNode to catch when Blackberry 4.6 returns\n\t\t\t\t// nodes that are no longer in the document #6963\n\t\t\t\treturn m && m.parentNode ? [m] : [];\n\t\t\t}\n\t\t};\n\t\tExpr.filter[\"ID\"] = function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\treturn elem.getAttribute(\"id\") === attrId;\n\t\t\t};\n\t\t};\n\t} else {\n\t\t// Support: IE6/7\n\t\t// getElementById is not reliable as a find shortcut\n\t\tdelete Expr.find[\"ID\"];\n\n\t\tExpr.filter[\"ID\"] =  function( id ) {\n\t\t\tvar attrId = id.replace( runescape, funescape );\n\t\t\treturn function( elem ) {\n\t\t\t\tvar node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode(\"id\");\n\t\t\t\treturn node && node.value === attrId;\n\t\t\t};\n\t\t};\n\t}\n\n\t// Tag\n\tExpr.find[\"TAG\"] = support.getElementsByTagName ?\n\t\tfunction( tag, context ) {\n\t\t\tif ( typeof context.getElementsByTagName !== strundefined ) {\n\t\t\t\treturn context.getElementsByTagName( tag );\n\t\t\t}\n\t\t} :\n\t\tfunction( tag, context ) {\n\t\t\tvar elem,\n\t\t\t\ttmp = [],\n\t\t\t\ti = 0,\n\t\t\t\tresults = context.getElementsByTagName( tag );\n\n\t\t\t// Filter out possible comments\n\t\t\tif ( tag === \"*\" ) {\n\t\t\t\twhile ( (elem = results[i++]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\ttmp.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn tmp;\n\t\t\t}\n\t\t\treturn results;\n\t\t};\n\n\t// Class\n\tExpr.find[\"CLASS\"] = support.getElementsByClassName && function( className, context ) {\n\t\tif ( typeof context.getElementsByClassName !== strundefined && documentIsHTML ) {\n\t\t\treturn context.getElementsByClassName( className );\n\t\t}\n\t};\n\n\t/* QSA/matchesSelector\n\t---------------------------------------------------------------------- */\n\n\t// QSA and matchesSelector support\n\n\t// matchesSelector(:active) reports false when true (IE9/Opera 11.5)\n\trbuggyMatches = [];\n\n\t// qSa(:focus) reports false when true (Chrome 21)\n\t// We allow this because of a bug in IE8/9 that throws an error\n\t// whenever `document.activeElement` is accessed on an iframe\n\t// So, we allow :focus to pass through QSA all the time to avoid the IE error\n\t// See http://bugs.jquery.com/ticket/13378\n\trbuggyQSA = [];\n\n\tif ( (support.qsa = rnative.test( doc.querySelectorAll )) ) {\n\t\t// Build QSA regex\n\t\t// Regex strategy adopted from Diego Perini\n\t\tassert(function( div ) {\n\t\t\t// Select is set to empty string on purpose\n\t\t\t// This is to test IE's treatment of not explicitly\n\t\t\t// setting a boolean content attribute,\n\t\t\t// since its presence should be enough\n\t\t\t// http://bugs.jquery.com/ticket/12359\n\t\t\tdiv.innerHTML = \"<select><option selected=''></option></select>\";\n\n\t\t\t// Support: IE8\n\t\t\t// Boolean attributes and \"value\" are not treated correctly\n\t\t\tif ( !div.querySelectorAll(\"[selected]\").length ) {\n\t\t\t\trbuggyQSA.push( \"\\\\[\" + whitespace + \"*(?:value|\" + booleans + \")\" );\n\t\t\t}\n\n\t\t\t// Webkit/Opera - :checked should return selected option elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":checked\").length ) {\n\t\t\t\trbuggyQSA.push(\":checked\");\n\t\t\t}\n\t\t});\n\n\t\tassert(function( div ) {\n\n\t\t\t// Support: Opera 10-12/IE8\n\t\t\t// ^= $= *= and empty values\n\t\t\t// Should not select anything\n\t\t\t// Support: Windows 8 Native Apps\n\t\t\t// The type attribute is restricted during .innerHTML assignment\n\t\t\tvar input = doc.createElement(\"input\");\n\t\t\tinput.setAttribute( \"type\", \"hidden\" );\n\t\t\tdiv.appendChild( input ).setAttribute( \"t\", \"\" );\n\n\t\t\tif ( div.querySelectorAll(\"[t^='']\").length ) {\n\t\t\t\trbuggyQSA.push( \"[*^$]=\" + whitespace + \"*(?:''|\\\"\\\")\" );\n\t\t\t}\n\n\t\t\t// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)\n\t\t\t// IE8 throws error here and will not see later tests\n\t\t\tif ( !div.querySelectorAll(\":enabled\").length ) {\n\t\t\t\trbuggyQSA.push( \":enabled\", \":disabled\" );\n\t\t\t}\n\n\t\t\t// Opera 10-11 does not throw on post-comma invalid pseudos\n\t\t\tdiv.querySelectorAll(\"*,:x\");\n\t\t\trbuggyQSA.push(\",.*:\");\n\t\t});\n\t}\n\n\tif ( (support.matchesSelector = rnative.test( (matches = docElem.webkitMatchesSelector ||\n\t\tdocElem.mozMatchesSelector ||\n\t\tdocElem.oMatchesSelector ||\n\t\tdocElem.msMatchesSelector) )) ) {\n\n\t\tassert(function( div ) {\n\t\t\t// Check to see if it's possible to do matchesSelector\n\t\t\t// on a disconnected node (IE 9)\n\t\t\tsupport.disconnectedMatch = matches.call( div, \"div\" );\n\n\t\t\t// This should fail with an exception\n\t\t\t// Gecko does not error, returns false instead\n\t\t\tmatches.call( div, \"[s!='']:x\" );\n\t\t\trbuggyMatches.push( \"!=\", pseudos );\n\t\t});\n\t}\n\n\trbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join(\"|\") );\n\trbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join(\"|\") );\n\n\t/* Contains\n\t---------------------------------------------------------------------- */\n\n\t// Element contains another\n\t// Purposefully does not implement inclusive descendent\n\t// As in, an element does not contain itself\n\tcontains = rnative.test( docElem.contains ) || docElem.compareDocumentPosition ?\n\t\tfunction( a, b ) {\n\t\t\tvar adown = a.nodeType === 9 ? a.documentElement : a,\n\t\t\t\tbup = b && b.parentNode;\n\t\t\treturn a === bup || !!( bup && bup.nodeType === 1 && (\n\t\t\t\tadown.contains ?\n\t\t\t\t\tadown.contains( bup ) :\n\t\t\t\t\ta.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16\n\t\t\t));\n\t\t} :\n\t\tfunction( a, b ) {\n\t\t\tif ( b ) {\n\t\t\t\twhile ( (b = b.parentNode) ) {\n\t\t\t\t\tif ( b === a ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn false;\n\t\t};\n\n\t/* Sorting\n\t---------------------------------------------------------------------- */\n\n\t// Document order sorting\n\tsortOrder = docElem.compareDocumentPosition ?\n\tfunction( a, b ) {\n\n\t\t// Flag for duplicate removal\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\t\t}\n\n\t\tvar compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b );\n\n\t\tif ( compare ) {\n\t\t\t// Disconnected nodes\n\t\t\tif ( compare & 1 ||\n\t\t\t\t(!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {\n\n\t\t\t\t// Choose the first element that is related to our preferred document\n\t\t\t\tif ( a === doc || contains(preferredDoc, a) ) {\n\t\t\t\t\treturn -1;\n\t\t\t\t}\n\t\t\t\tif ( b === doc || contains(preferredDoc, b) ) {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\n\t\t\t\t// Maintain original order\n\t\t\t\treturn sortInput ?\n\t\t\t\t\t( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :\n\t\t\t\t\t0;\n\t\t\t}\n\n\t\t\treturn compare & 4 ? -1 : 1;\n\t\t}\n\n\t\t// Not directly comparable, sort on existence of method\n\t\treturn a.compareDocumentPosition ? -1 : 1;\n\t} :\n\tfunction( a, b ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\taup = a.parentNode,\n\t\t\tbup = b.parentNode,\n\t\t\tap = [ a ],\n\t\t\tbp = [ b ];\n\n\t\t// Exit early if the nodes are identical\n\t\tif ( a === b ) {\n\t\t\thasDuplicate = true;\n\t\t\treturn 0;\n\n\t\t// Parentless nodes are either documents or disconnected\n\t\t} else if ( !aup || !bup ) {\n\t\t\treturn a === doc ? -1 :\n\t\t\t\tb === doc ? 1 :\n\t\t\t\taup ? -1 :\n\t\t\t\tbup ? 1 :\n\t\t\t\tsortInput ?\n\t\t\t\t( indexOf.call( sortInput, a ) - indexOf.call( sortInput, b ) ) :\n\t\t\t\t0;\n\n\t\t// If the nodes are siblings, we can do a quick check\n\t\t} else if ( aup === bup ) {\n\t\t\treturn siblingCheck( a, b );\n\t\t}\n\n\t\t// Otherwise we need full lists of their ancestors for comparison\n\t\tcur = a;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tap.unshift( cur );\n\t\t}\n\t\tcur = b;\n\t\twhile ( (cur = cur.parentNode) ) {\n\t\t\tbp.unshift( cur );\n\t\t}\n\n\t\t// Walk down the tree looking for a discrepancy\n\t\twhile ( ap[i] === bp[i] ) {\n\t\t\ti++;\n\t\t}\n\n\t\treturn i ?\n\t\t\t// Do a sibling check if the nodes have a common ancestor\n\t\t\tsiblingCheck( ap[i], bp[i] ) :\n\n\t\t\t// Otherwise nodes in our document sort first\n\t\t\tap[i] === preferredDoc ? -1 :\n\t\t\tbp[i] === preferredDoc ? 1 :\n\t\t\t0;\n\t};\n\n\treturn doc;\n};\n\nSizzle.matches = function( expr, elements ) {\n\treturn Sizzle( expr, null, null, elements );\n};\n\nSizzle.matchesSelector = function( elem, expr ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\t// Make sure that attribute selectors are quoted\n\texpr = expr.replace( rattributeQuotes, \"='$1']\" );\n\n\tif ( support.matchesSelector && documentIsHTML &&\n\t\t( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&\n\t\t( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {\n\n\t\ttry {\n\t\t\tvar ret = matches.call( elem, expr );\n\n\t\t\t// IE 9's matchesSelector returns false on disconnected nodes\n\t\t\tif ( ret || support.disconnectedMatch ||\n\t\t\t\t\t// As well, disconnected nodes are said to be in a document\n\t\t\t\t\t// fragment in IE 9\n\t\t\t\t\telem.document && elem.document.nodeType !== 11 ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\t\t} catch(e) {}\n\t}\n\n\treturn Sizzle( expr, document, null, [elem] ).length > 0;\n};\n\nSizzle.contains = function( context, elem ) {\n\t// Set document vars if needed\n\tif ( ( context.ownerDocument || context ) !== document ) {\n\t\tsetDocument( context );\n\t}\n\treturn contains( context, elem );\n};\n\nSizzle.attr = function( elem, name ) {\n\t// Set document vars if needed\n\tif ( ( elem.ownerDocument || elem ) !== document ) {\n\t\tsetDocument( elem );\n\t}\n\n\tvar fn = Expr.attrHandle[ name.toLowerCase() ],\n\t\t// Don't get fooled by Object.prototype properties (jQuery #13807)\n\t\tval = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?\n\t\t\tfn( elem, name, !documentIsHTML ) :\n\t\t\tundefined;\n\n\treturn val === undefined ?\n\t\tsupport.attributes || !documentIsHTML ?\n\t\t\telem.getAttribute( name ) :\n\t\t\t(val = elem.getAttributeNode(name)) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\tnull :\n\t\tval;\n};\n\nSizzle.error = function( msg ) {\n\tthrow new Error( \"Syntax error, unrecognized expression: \" + msg );\n};\n\n/**\n * Document sorting and removing duplicates\n * @param {ArrayLike} results\n */\nSizzle.uniqueSort = function( results ) {\n\tvar elem,\n\t\tduplicates = [],\n\t\tj = 0,\n\t\ti = 0;\n\n\t// Unless we *know* we can detect duplicates, assume their presence\n\thasDuplicate = !support.detectDuplicates;\n\tsortInput = !support.sortStable && results.slice( 0 );\n\tresults.sort( sortOrder );\n\n\tif ( hasDuplicate ) {\n\t\twhile ( (elem = results[i++]) ) {\n\t\t\tif ( elem === results[ i ] ) {\n\t\t\t\tj = duplicates.push( i );\n\t\t\t}\n\t\t}\n\t\twhile ( j-- ) {\n\t\t\tresults.splice( duplicates[ j ], 1 );\n\t\t}\n\t}\n\n\treturn results;\n};\n\n/**\n * Utility function for retrieving the text value of an array of DOM nodes\n * @param {Array|Element} elem\n */\ngetText = Sizzle.getText = function( elem ) {\n\tvar node,\n\t\tret = \"\",\n\t\ti = 0,\n\t\tnodeType = elem.nodeType;\n\n\tif ( !nodeType ) {\n\t\t// If no nodeType, this is expected to be an array\n\t\tfor ( ; (node = elem[i]); i++ ) {\n\t\t\t// Do not traverse comment nodes\n\t\t\tret += getText( node );\n\t\t}\n\t} else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {\n\t\t// Use textContent for elements\n\t\t// innerText usage removed for consistency of new lines (see #11153)\n\t\tif ( typeof elem.textContent === \"string\" ) {\n\t\t\treturn elem.textContent;\n\t\t} else {\n\t\t\t// Traverse its children\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tret += getText( elem );\n\t\t\t}\n\t\t}\n\t} else if ( nodeType === 3 || nodeType === 4 ) {\n\t\treturn elem.nodeValue;\n\t}\n\t// Do not include comment or processing instruction nodes\n\n\treturn ret;\n};\n\nExpr = Sizzle.selectors = {\n\n\t// Can be adjusted by the user\n\tcacheLength: 50,\n\n\tcreatePseudo: markFunction,\n\n\tmatch: matchExpr,\n\n\tattrHandle: {},\n\n\tfind: {},\n\n\trelative: {\n\t\t\">\": { dir: \"parentNode\", first: true },\n\t\t\" \": { dir: \"parentNode\" },\n\t\t\"+\": { dir: \"previousSibling\", first: true },\n\t\t\"~\": { dir: \"previousSibling\" }\n\t},\n\n\tpreFilter: {\n\t\t\"ATTR\": function( match ) {\n\t\t\tmatch[1] = match[1].replace( runescape, funescape );\n\n\t\t\t// Move the given value to match[3] whether quoted or unquoted\n\t\t\tmatch[3] = ( match[4] || match[5] || \"\" ).replace( runescape, funescape );\n\n\t\t\tif ( match[2] === \"~=\" ) {\n\t\t\t\tmatch[3] = \" \" + match[3] + \" \";\n\t\t\t}\n\n\t\t\treturn match.slice( 0, 4 );\n\t\t},\n\n\t\t\"CHILD\": function( match ) {\n\t\t\t/* matches from matchExpr[\"CHILD\"]\n\t\t\t\t1 type (only|nth|...)\n\t\t\t\t2 what (child|of-type)\n\t\t\t\t3 argument (even|odd|\\d*|\\d*n([+-]\\d+)?|...)\n\t\t\t\t4 xn-component of xn+y argument ([+-]?\\d*n|)\n\t\t\t\t5 sign of xn-component\n\t\t\t\t6 x of xn-component\n\t\t\t\t7 sign of y-component\n\t\t\t\t8 y of y-component\n\t\t\t*/\n\t\t\tmatch[1] = match[1].toLowerCase();\n\n\t\t\tif ( match[1].slice( 0, 3 ) === \"nth\" ) {\n\t\t\t\t// nth-* requires argument\n\t\t\t\tif ( !match[3] ) {\n\t\t\t\t\tSizzle.error( match[0] );\n\t\t\t\t}\n\n\t\t\t\t// numeric x and y parameters for Expr.filter.CHILD\n\t\t\t\t// remember that false/true cast respectively to 0/1\n\t\t\t\tmatch[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === \"even\" || match[3] === \"odd\" ) );\n\t\t\t\tmatch[5] = +( ( match[7] + match[8] ) || match[3] === \"odd\" );\n\n\t\t\t// other types prohibit arguments\n\t\t\t} else if ( match[3] ) {\n\t\t\t\tSizzle.error( match[0] );\n\t\t\t}\n\n\t\t\treturn match;\n\t\t},\n\n\t\t\"PSEUDO\": function( match ) {\n\t\t\tvar excess,\n\t\t\t\tunquoted = !match[5] && match[2];\n\n\t\t\tif ( matchExpr[\"CHILD\"].test( match[0] ) ) {\n\t\t\t\treturn null;\n\t\t\t}\n\n\t\t\t// Accept quoted arguments as-is\n\t\t\tif ( match[3] && match[4] !== undefined ) {\n\t\t\t\tmatch[2] = match[4];\n\n\t\t\t// Strip excess characters from unquoted arguments\n\t\t\t} else if ( unquoted && rpseudo.test( unquoted ) &&\n\t\t\t\t// Get excess from tokenize (recursively)\n\t\t\t\t(excess = tokenize( unquoted, true )) &&\n\t\t\t\t// advance to the next closing parenthesis\n\t\t\t\t(excess = unquoted.indexOf( \")\", unquoted.length - excess ) - unquoted.length) ) {\n\n\t\t\t\t// excess is a negative index\n\t\t\t\tmatch[0] = match[0].slice( 0, excess );\n\t\t\t\tmatch[2] = unquoted.slice( 0, excess );\n\t\t\t}\n\n\t\t\t// Return only captures needed by the pseudo filter method (type and argument)\n\t\t\treturn match.slice( 0, 3 );\n\t\t}\n\t},\n\n\tfilter: {\n\n\t\t\"TAG\": function( nodeNameSelector ) {\n\t\t\tvar nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn nodeNameSelector === \"*\" ?\n\t\t\t\tfunction() { return true; } :\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn elem.nodeName && elem.nodeName.toLowerCase() === nodeName;\n\t\t\t\t};\n\t\t},\n\n\t\t\"CLASS\": function( className ) {\n\t\t\tvar pattern = classCache[ className + \" \" ];\n\n\t\t\treturn pattern ||\n\t\t\t\t(pattern = new RegExp( \"(^|\" + whitespace + \")\" + className + \"(\" + whitespace + \"|$)\" )) &&\n\t\t\t\tclassCache( className, function( elem ) {\n\t\t\t\t\treturn pattern.test( typeof elem.className === \"string\" && elem.className || typeof elem.getAttribute !== strundefined && elem.getAttribute(\"class\") || \"\" );\n\t\t\t\t});\n\t\t},\n\n\t\t\"ATTR\": function( name, operator, check ) {\n\t\t\treturn function( elem ) {\n\t\t\t\tvar result = Sizzle.attr( elem, name );\n\n\t\t\t\tif ( result == null ) {\n\t\t\t\t\treturn operator === \"!=\";\n\t\t\t\t}\n\t\t\t\tif ( !operator ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\n\t\t\t\tresult += \"\";\n\n\t\t\t\treturn operator === \"=\" ? result === check :\n\t\t\t\t\toperator === \"!=\" ? result !== check :\n\t\t\t\t\toperator === \"^=\" ? check && result.indexOf( check ) === 0 :\n\t\t\t\t\toperator === \"*=\" ? check && result.indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"$=\" ? check && result.slice( -check.length ) === check :\n\t\t\t\t\toperator === \"~=\" ? ( \" \" + result + \" \" ).indexOf( check ) > -1 :\n\t\t\t\t\toperator === \"|=\" ? result === check || result.slice( 0, check.length + 1 ) === check + \"-\" :\n\t\t\t\t\tfalse;\n\t\t\t};\n\t\t},\n\n\t\t\"CHILD\": function( type, what, argument, first, last ) {\n\t\t\tvar simple = type.slice( 0, 3 ) !== \"nth\",\n\t\t\t\tforward = type.slice( -4 ) !== \"last\",\n\t\t\t\tofType = what === \"of-type\";\n\n\t\t\treturn first === 1 && last === 0 ?\n\n\t\t\t\t// Shortcut for :nth-*(n)\n\t\t\t\tfunction( elem ) {\n\t\t\t\t\treturn !!elem.parentNode;\n\t\t\t\t} :\n\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tvar cache, outerCache, node, diff, nodeIndex, start,\n\t\t\t\t\t\tdir = simple !== forward ? \"nextSibling\" : \"previousSibling\",\n\t\t\t\t\t\tparent = elem.parentNode,\n\t\t\t\t\t\tname = ofType && elem.nodeName.toLowerCase(),\n\t\t\t\t\t\tuseCache = !xml && !ofType;\n\n\t\t\t\t\tif ( parent ) {\n\n\t\t\t\t\t\t// :(first|last|only)-(child|of-type)\n\t\t\t\t\t\tif ( simple ) {\n\t\t\t\t\t\t\twhile ( dir ) {\n\t\t\t\t\t\t\t\tnode = elem;\n\t\t\t\t\t\t\t\twhile ( (node = node[ dir ]) ) {\n\t\t\t\t\t\t\t\t\tif ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {\n\t\t\t\t\t\t\t\t\t\treturn false;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t// Reverse direction for :only-* (if we haven't yet done so)\n\t\t\t\t\t\t\t\tstart = dir = type === \"only\" && !start && \"nextSibling\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tstart = [ forward ? parent.firstChild : parent.lastChild ];\n\n\t\t\t\t\t\t// non-xml :nth-child(...) stores cache data on `parent`\n\t\t\t\t\t\tif ( forward && useCache ) {\n\t\t\t\t\t\t\t// Seek `elem` from a previously-cached index\n\t\t\t\t\t\t\touterCache = parent[ expando ] || (parent[ expando ] = {});\n\t\t\t\t\t\t\tcache = outerCache[ type ] || [];\n\t\t\t\t\t\t\tnodeIndex = cache[0] === dirruns && cache[1];\n\t\t\t\t\t\t\tdiff = cache[0] === dirruns && cache[2];\n\t\t\t\t\t\t\tnode = nodeIndex && parent.childNodes[ nodeIndex ];\n\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\n\t\t\t\t\t\t\t\t// Fallback to seeking `elem` from the start\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\t// When found, cache indexes on `parent` and break\n\t\t\t\t\t\t\t\tif ( node.nodeType === 1 && ++diff && node === elem ) {\n\t\t\t\t\t\t\t\t\touterCache[ type ] = [ dirruns, nodeIndex, diff ];\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Use previously-cached element index if available\n\t\t\t\t\t\t} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {\n\t\t\t\t\t\t\tdiff = cache[1];\n\n\t\t\t\t\t\t// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Use the same loop as above to seek `elem` from the start\n\t\t\t\t\t\t\twhile ( (node = ++nodeIndex && node && node[ dir ] ||\n\t\t\t\t\t\t\t\t(diff = nodeIndex = 0) || start.pop()) ) {\n\n\t\t\t\t\t\t\t\tif ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {\n\t\t\t\t\t\t\t\t\t// Cache the index of each encountered element\n\t\t\t\t\t\t\t\t\tif ( useCache ) {\n\t\t\t\t\t\t\t\t\t\t(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ( node === elem ) {\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Incorporate the offset, then check against cycle size\n\t\t\t\t\t\tdiff -= last;\n\t\t\t\t\t\treturn diff === first || ( diff % first === 0 && diff / first >= 0 );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t},\n\n\t\t\"PSEUDO\": function( pseudo, argument ) {\n\t\t\t// pseudo-class names are case-insensitive\n\t\t\t// http://www.w3.org/TR/selectors/#pseudo-classes\n\t\t\t// Prioritize by case sensitivity in case custom pseudos are added with uppercase letters\n\t\t\t// Remember that setFilters inherits from pseudos\n\t\t\tvar args,\n\t\t\t\tfn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||\n\t\t\t\t\tSizzle.error( \"unsupported pseudo: \" + pseudo );\n\n\t\t\t// The user may use createPseudo to indicate that\n\t\t\t// arguments are needed to create the filter function\n\t\t\t// just as Sizzle does\n\t\t\tif ( fn[ expando ] ) {\n\t\t\t\treturn fn( argument );\n\t\t\t}\n\n\t\t\t// But maintain support for old signatures\n\t\t\tif ( fn.length > 1 ) {\n\t\t\t\targs = [ pseudo, pseudo, \"\", argument ];\n\t\t\t\treturn Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?\n\t\t\t\t\tmarkFunction(function( seed, matches ) {\n\t\t\t\t\t\tvar idx,\n\t\t\t\t\t\t\tmatched = fn( seed, argument ),\n\t\t\t\t\t\t\ti = matched.length;\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tidx = indexOf.call( seed, matched[i] );\n\t\t\t\t\t\t\tseed[ idx ] = !( matches[ idx ] = matched[i] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}) :\n\t\t\t\t\tfunction( elem ) {\n\t\t\t\t\t\treturn fn( elem, 0, args );\n\t\t\t\t\t};\n\t\t\t}\n\n\t\t\treturn fn;\n\t\t}\n\t},\n\n\tpseudos: {\n\t\t// Potentially complex pseudos\n\t\t\"not\": markFunction(function( selector ) {\n\t\t\t// Trim the selector passed to compile\n\t\t\t// to avoid treating leading and trailing\n\t\t\t// spaces as combinators\n\t\t\tvar input = [],\n\t\t\t\tresults = [],\n\t\t\t\tmatcher = compile( selector.replace( rtrim, \"$1\" ) );\n\n\t\t\treturn matcher[ expando ] ?\n\t\t\t\tmarkFunction(function( seed, matches, context, xml ) {\n\t\t\t\t\tvar elem,\n\t\t\t\t\t\tunmatched = matcher( seed, null, xml, [] ),\n\t\t\t\t\t\ti = seed.length;\n\n\t\t\t\t\t// Match elements unmatched by `matcher`\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = unmatched[i]) ) {\n\t\t\t\t\t\t\tseed[i] = !(matches[i] = elem);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}) :\n\t\t\t\tfunction( elem, context, xml ) {\n\t\t\t\t\tinput[0] = elem;\n\t\t\t\t\tmatcher( input, null, xml, results );\n\t\t\t\t\treturn !results.pop();\n\t\t\t\t};\n\t\t}),\n\n\t\t\"has\": markFunction(function( selector ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn Sizzle( selector, elem ).length > 0;\n\t\t\t};\n\t\t}),\n\n\t\t\"contains\": markFunction(function( text ) {\n\t\t\treturn function( elem ) {\n\t\t\t\treturn ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1;\n\t\t\t};\n\t\t}),\n\n\t\t// \"Whether an element is represented by a :lang() selector\n\t\t// is based solely on the element's language value\n\t\t// being equal to the identifier C,\n\t\t// or beginning with the identifier C immediately followed by \"-\".\n\t\t// The matching of C against the element's language value is performed case-insensitively.\n\t\t// The identifier C does not have to be a valid language name.\"\n\t\t// http://www.w3.org/TR/selectors/#lang-pseudo\n\t\t\"lang\": markFunction( function( lang ) {\n\t\t\t// lang value must be a valid identifier\n\t\t\tif ( !ridentifier.test(lang || \"\") ) {\n\t\t\t\tSizzle.error( \"unsupported lang: \" + lang );\n\t\t\t}\n\t\t\tlang = lang.replace( runescape, funescape ).toLowerCase();\n\t\t\treturn function( elem ) {\n\t\t\t\tvar elemLang;\n\t\t\t\tdo {\n\t\t\t\t\tif ( (elemLang = documentIsHTML ?\n\t\t\t\t\t\telem.lang :\n\t\t\t\t\t\telem.getAttribute(\"xml:lang\") || elem.getAttribute(\"lang\")) ) {\n\n\t\t\t\t\t\telemLang = elemLang.toLowerCase();\n\t\t\t\t\t\treturn elemLang === lang || elemLang.indexOf( lang + \"-\" ) === 0;\n\t\t\t\t\t}\n\t\t\t\t} while ( (elem = elem.parentNode) && elem.nodeType === 1 );\n\t\t\t\treturn false;\n\t\t\t};\n\t\t}),\n\n\t\t// Miscellaneous\n\t\t\"target\": function( elem ) {\n\t\t\tvar hash = window.location && window.location.hash;\n\t\t\treturn hash && hash.slice( 1 ) === elem.id;\n\t\t},\n\n\t\t\"root\": function( elem ) {\n\t\t\treturn elem === docElem;\n\t\t},\n\n\t\t\"focus\": function( elem ) {\n\t\t\treturn elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);\n\t\t},\n\n\t\t// Boolean properties\n\t\t\"enabled\": function( elem ) {\n\t\t\treturn elem.disabled === false;\n\t\t},\n\n\t\t\"disabled\": function( elem ) {\n\t\t\treturn elem.disabled === true;\n\t\t},\n\n\t\t\"checked\": function( elem ) {\n\t\t\t// In CSS3, :checked should return both checked and selected elements\n\t\t\t// http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked\n\t\t\tvar nodeName = elem.nodeName.toLowerCase();\n\t\t\treturn (nodeName === \"input\" && !!elem.checked) || (nodeName === \"option\" && !!elem.selected);\n\t\t},\n\n\t\t\"selected\": function( elem ) {\n\t\t\t// Accessing this property makes selected-by-default\n\t\t\t// options in Safari work properly\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\telem.parentNode.selectedIndex;\n\t\t\t}\n\n\t\t\treturn elem.selected === true;\n\t\t},\n\n\t\t// Contents\n\t\t\"empty\": function( elem ) {\n\t\t\t// http://www.w3.org/TR/selectors/#empty-pseudo\n\t\t\t// :empty is only affected by element nodes and content nodes(including text(3), cdata(4)),\n\t\t\t//   not comment, processing instructions, or others\n\t\t\t// Thanks to Diego Perini for the nodeName shortcut\n\t\t\t//   Greater than \"@\" means alpha characters (specifically not starting with \"#\" or \"?\")\n\t\t\tfor ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {\n\t\t\t\tif ( elem.nodeName > \"@\" || elem.nodeType === 3 || elem.nodeType === 4 ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t},\n\n\t\t\"parent\": function( elem ) {\n\t\t\treturn !Expr.pseudos[\"empty\"]( elem );\n\t\t},\n\n\t\t// Element/input types\n\t\t\"header\": function( elem ) {\n\t\t\treturn rheader.test( elem.nodeName );\n\t\t},\n\n\t\t\"input\": function( elem ) {\n\t\t\treturn rinputs.test( elem.nodeName );\n\t\t},\n\n\t\t\"button\": function( elem ) {\n\t\t\tvar name = elem.nodeName.toLowerCase();\n\t\t\treturn name === \"input\" && elem.type === \"button\" || name === \"button\";\n\t\t},\n\n\t\t\"text\": function( elem ) {\n\t\t\tvar attr;\n\t\t\t// IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc)\n\t\t\t// use getAttribute instead to test this case\n\t\t\treturn elem.nodeName.toLowerCase() === \"input\" &&\n\t\t\t\telem.type === \"text\" &&\n\t\t\t\t( (attr = elem.getAttribute(\"type\")) == null || attr.toLowerCase() === elem.type );\n\t\t},\n\n\t\t// Position-in-collection\n\t\t\"first\": createPositionalPseudo(function() {\n\t\t\treturn [ 0 ];\n\t\t}),\n\n\t\t\"last\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\treturn [ length - 1 ];\n\t\t}),\n\n\t\t\"eq\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\treturn [ argument < 0 ? argument + length : argument ];\n\t\t}),\n\n\t\t\"even\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 0;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"odd\": createPositionalPseudo(function( matchIndexes, length ) {\n\t\t\tvar i = 1;\n\t\t\tfor ( ; i < length; i += 2 ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"lt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; --i >= 0; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t}),\n\n\t\t\"gt\": createPositionalPseudo(function( matchIndexes, length, argument ) {\n\t\t\tvar i = argument < 0 ? argument + length : argument;\n\t\t\tfor ( ; ++i < length; ) {\n\t\t\t\tmatchIndexes.push( i );\n\t\t\t}\n\t\t\treturn matchIndexes;\n\t\t})\n\t}\n};\n\nExpr.pseudos[\"nth\"] = Expr.pseudos[\"eq\"];\n\n// Add button/input type pseudos\nfor ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {\n\tExpr.pseudos[ i ] = createInputPseudo( i );\n}\nfor ( i in { submit: true, reset: true } ) {\n\tExpr.pseudos[ i ] = createButtonPseudo( i );\n}\n\n// Easy API for creating new setFilters\nfunction setFilters() {}\nsetFilters.prototype = Expr.filters = Expr.pseudos;\nExpr.setFilters = new setFilters();\n\nfunction tokenize( selector, parseOnly ) {\n\tvar matched, match, tokens, type,\n\t\tsoFar, groups, preFilters,\n\t\tcached = tokenCache[ selector + \" \" ];\n\n\tif ( cached ) {\n\t\treturn parseOnly ? 0 : cached.slice( 0 );\n\t}\n\n\tsoFar = selector;\n\tgroups = [];\n\tpreFilters = Expr.preFilter;\n\n\twhile ( soFar ) {\n\n\t\t// Comma and first run\n\t\tif ( !matched || (match = rcomma.exec( soFar )) ) {\n\t\t\tif ( match ) {\n\t\t\t\t// Don't consume trailing commas as valid\n\t\t\t\tsoFar = soFar.slice( match[0].length ) || soFar;\n\t\t\t}\n\t\t\tgroups.push( tokens = [] );\n\t\t}\n\n\t\tmatched = false;\n\n\t\t// Combinators\n\t\tif ( (match = rcombinators.exec( soFar )) ) {\n\t\t\tmatched = match.shift();\n\t\t\ttokens.push({\n\t\t\t\tvalue: matched,\n\t\t\t\t// Cast descendant combinators to space\n\t\t\t\ttype: match[0].replace( rtrim, \" \" )\n\t\t\t});\n\t\t\tsoFar = soFar.slice( matched.length );\n\t\t}\n\n\t\t// Filters\n\t\tfor ( type in Expr.filter ) {\n\t\t\tif ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||\n\t\t\t\t(match = preFilters[ type ]( match ))) ) {\n\t\t\t\tmatched = match.shift();\n\t\t\t\ttokens.push({\n\t\t\t\t\tvalue: matched,\n\t\t\t\t\ttype: type,\n\t\t\t\t\tmatches: match\n\t\t\t\t});\n\t\t\t\tsoFar = soFar.slice( matched.length );\n\t\t\t}\n\t\t}\n\n\t\tif ( !matched ) {\n\t\t\tbreak;\n\t\t}\n\t}\n\n\t// Return the length of the invalid excess\n\t// if we're just parsing\n\t// Otherwise, throw an error or return tokens\n\treturn parseOnly ?\n\t\tsoFar.length :\n\t\tsoFar ?\n\t\t\tSizzle.error( selector ) :\n\t\t\t// Cache the tokens\n\t\t\ttokenCache( selector, groups ).slice( 0 );\n}\n\nfunction toSelector( tokens ) {\n\tvar i = 0,\n\t\tlen = tokens.length,\n\t\tselector = \"\";\n\tfor ( ; i < len; i++ ) {\n\t\tselector += tokens[i].value;\n\t}\n\treturn selector;\n}\n\nfunction addCombinator( matcher, combinator, base ) {\n\tvar dir = combinator.dir,\n\t\tcheckNonElements = base && dir === \"parentNode\",\n\t\tdoneName = done++;\n\n\treturn combinator.first ?\n\t\t// Check against closest ancestor/preceding element\n\t\tfunction( elem, context, xml ) {\n\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\treturn matcher( elem, context, xml );\n\t\t\t\t}\n\t\t\t}\n\t\t} :\n\n\t\t// Check against all ancestor/preceding elements\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar data, cache, outerCache,\n\t\t\t\tdirkey = dirruns + \" \" + doneName;\n\n\t\t\t// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching\n\t\t\tif ( xml ) {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\twhile ( (elem = elem[ dir ]) ) {\n\t\t\t\t\tif ( elem.nodeType === 1 || checkNonElements ) {\n\t\t\t\t\t\touterCache = elem[ expando ] || (elem[ expando ] = {});\n\t\t\t\t\t\tif ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {\n\t\t\t\t\t\t\tif ( (data = cache[1]) === true || data === cachedruns ) {\n\t\t\t\t\t\t\t\treturn data === true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tcache = outerCache[ dir ] = [ dirkey ];\n\t\t\t\t\t\t\tcache[1] = matcher( elem, context, xml ) || cachedruns;\n\t\t\t\t\t\t\tif ( cache[1] === true ) {\n\t\t\t\t\t\t\t\treturn true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t};\n}\n\nfunction elementMatcher( matchers ) {\n\treturn matchers.length > 1 ?\n\t\tfunction( elem, context, xml ) {\n\t\t\tvar i = matchers.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( !matchers[i]( elem, context, xml ) ) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn true;\n\t\t} :\n\t\tmatchers[0];\n}\n\nfunction condense( unmatched, map, filter, context, xml ) {\n\tvar elem,\n\t\tnewUnmatched = [],\n\t\ti = 0,\n\t\tlen = unmatched.length,\n\t\tmapped = map != null;\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (elem = unmatched[i]) ) {\n\t\t\tif ( !filter || filter( elem, context, xml ) ) {\n\t\t\t\tnewUnmatched.push( elem );\n\t\t\t\tif ( mapped ) {\n\t\t\t\t\tmap.push( i );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn newUnmatched;\n}\n\nfunction setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {\n\tif ( postFilter && !postFilter[ expando ] ) {\n\t\tpostFilter = setMatcher( postFilter );\n\t}\n\tif ( postFinder && !postFinder[ expando ] ) {\n\t\tpostFinder = setMatcher( postFinder, postSelector );\n\t}\n\treturn markFunction(function( seed, results, context, xml ) {\n\t\tvar temp, i, elem,\n\t\t\tpreMap = [],\n\t\t\tpostMap = [],\n\t\t\tpreexisting = results.length,\n\n\t\t\t// Get initial elements from seed or context\n\t\t\telems = seed || multipleContexts( selector || \"*\", context.nodeType ? [ context ] : context, [] ),\n\n\t\t\t// Prefilter to get matcher input, preserving a map for seed-results synchronization\n\t\t\tmatcherIn = preFilter && ( seed || !selector ) ?\n\t\t\t\tcondense( elems, preMap, preFilter, context, xml ) :\n\t\t\t\telems,\n\n\t\t\tmatcherOut = matcher ?\n\t\t\t\t// If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results,\n\t\t\t\tpostFinder || ( seed ? preFilter : preexisting || postFilter ) ?\n\n\t\t\t\t\t// ...intermediate processing is necessary\n\t\t\t\t\t[] :\n\n\t\t\t\t\t// ...otherwise use results directly\n\t\t\t\t\tresults :\n\t\t\t\tmatcherIn;\n\n\t\t// Find primary matches\n\t\tif ( matcher ) {\n\t\t\tmatcher( matcherIn, matcherOut, context, xml );\n\t\t}\n\n\t\t// Apply postFilter\n\t\tif ( postFilter ) {\n\t\t\ttemp = condense( matcherOut, postMap );\n\t\t\tpostFilter( temp, [], context, xml );\n\n\t\t\t// Un-match failing elements by moving them back to matcherIn\n\t\t\ti = temp.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tif ( (elem = temp[i]) ) {\n\t\t\t\t\tmatcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ( seed ) {\n\t\t\tif ( postFinder || preFilter ) {\n\t\t\t\tif ( postFinder ) {\n\t\t\t\t\t// Get the final matcherOut by condensing this intermediate into postFinder contexts\n\t\t\t\t\ttemp = [];\n\t\t\t\t\ti = matcherOut.length;\n\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\tif ( (elem = matcherOut[i]) ) {\n\t\t\t\t\t\t\t// Restore matcherIn since elem is not yet a final match\n\t\t\t\t\t\t\ttemp.push( (matcherIn[i] = elem) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tpostFinder( null, (matcherOut = []), temp, xml );\n\t\t\t\t}\n\n\t\t\t\t// Move matched elements from seed to results to keep them synchronized\n\t\t\t\ti = matcherOut.length;\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\tif ( (elem = matcherOut[i]) &&\n\t\t\t\t\t\t(temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) {\n\n\t\t\t\t\t\tseed[temp] = !(results[temp] = elem);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t// Add elements to results, through postFinder if defined\n\t\t} else {\n\t\t\tmatcherOut = condense(\n\t\t\t\tmatcherOut === results ?\n\t\t\t\t\tmatcherOut.splice( preexisting, matcherOut.length ) :\n\t\t\t\t\tmatcherOut\n\t\t\t);\n\t\t\tif ( postFinder ) {\n\t\t\t\tpostFinder( null, results, matcherOut, xml );\n\t\t\t} else {\n\t\t\t\tpush.apply( results, matcherOut );\n\t\t\t}\n\t\t}\n\t});\n}\n\nfunction matcherFromTokens( tokens ) {\n\tvar checkContext, matcher, j,\n\t\tlen = tokens.length,\n\t\tleadingRelative = Expr.relative[ tokens[0].type ],\n\t\timplicitRelative = leadingRelative || Expr.relative[\" \"],\n\t\ti = leadingRelative ? 1 : 0,\n\n\t\t// The foundational matcher ensures that elements are reachable from top-level context(s)\n\t\tmatchContext = addCombinator( function( elem ) {\n\t\t\treturn elem === checkContext;\n\t\t}, implicitRelative, true ),\n\t\tmatchAnyContext = addCombinator( function( elem ) {\n\t\t\treturn indexOf.call( checkContext, elem ) > -1;\n\t\t}, implicitRelative, true ),\n\t\tmatchers = [ function( elem, context, xml ) {\n\t\t\treturn ( !leadingRelative && ( xml || context !== outermostContext ) ) || (\n\t\t\t\t(checkContext = context).nodeType ?\n\t\t\t\t\tmatchContext( elem, context, xml ) :\n\t\t\t\t\tmatchAnyContext( elem, context, xml ) );\n\t\t} ];\n\n\tfor ( ; i < len; i++ ) {\n\t\tif ( (matcher = Expr.relative[ tokens[i].type ]) ) {\n\t\t\tmatchers = [ addCombinator(elementMatcher( matchers ), matcher) ];\n\t\t} else {\n\t\t\tmatcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );\n\n\t\t\t// Return special upon seeing a positional matcher\n\t\t\tif ( matcher[ expando ] ) {\n\t\t\t\t// Find the next relative operator (if any) for proper handling\n\t\t\t\tj = ++i;\n\t\t\t\tfor ( ; j < len; j++ ) {\n\t\t\t\t\tif ( Expr.relative[ tokens[j].type ] ) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn setMatcher(\n\t\t\t\t\ti > 1 && elementMatcher( matchers ),\n\t\t\t\t\ti > 1 && toSelector(\n\t\t\t\t\t\t// If the preceding token was a descendant combinator, insert an implicit any-element `*`\n\t\t\t\t\t\ttokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type === \" \" ? \"*\" : \"\" })\n\t\t\t\t\t).replace( rtrim, \"$1\" ),\n\t\t\t\t\tmatcher,\n\t\t\t\t\ti < j && matcherFromTokens( tokens.slice( i, j ) ),\n\t\t\t\t\tj < len && matcherFromTokens( (tokens = tokens.slice( j )) ),\n\t\t\t\t\tj < len && toSelector( tokens )\n\t\t\t\t);\n\t\t\t}\n\t\t\tmatchers.push( matcher );\n\t\t}\n\t}\n\n\treturn elementMatcher( matchers );\n}\n\nfunction matcherFromGroupMatchers( elementMatchers, setMatchers ) {\n\t// A counter to specify which element is currently being matched\n\tvar matcherCachedRuns = 0,\n\t\tbySet = setMatchers.length > 0,\n\t\tbyElement = elementMatchers.length > 0,\n\t\tsuperMatcher = function( seed, context, xml, results, expandContext ) {\n\t\t\tvar elem, j, matcher,\n\t\t\t\tsetMatched = [],\n\t\t\t\tmatchedCount = 0,\n\t\t\t\ti = \"0\",\n\t\t\t\tunmatched = seed && [],\n\t\t\t\toutermost = expandContext != null,\n\t\t\t\tcontextBackup = outermostContext,\n\t\t\t\t// We must always have either seed elements or context\n\t\t\t\telems = seed || byElement && Expr.find[\"TAG\"]( \"*\", expandContext && context.parentNode || context ),\n\t\t\t\t// Use integer dirruns iff this is the outermost matcher\n\t\t\t\tdirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);\n\n\t\t\tif ( outermost ) {\n\t\t\t\toutermostContext = context !== document && context;\n\t\t\t\tcachedruns = matcherCachedRuns;\n\t\t\t}\n\n\t\t\t// Add elements passing elementMatchers directly to results\n\t\t\t// Keep `i` a string if there are no elements so `matchedCount` will be \"00\" below\n\t\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\t\t\tif ( byElement && elem ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (matcher = elementMatchers[j++]) ) {\n\t\t\t\t\t\tif ( matcher( elem, context, xml ) ) {\n\t\t\t\t\t\t\tresults.push( elem );\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( outermost ) {\n\t\t\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\t\t\tcachedruns = ++matcherCachedRuns;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Track unmatched elements for set filters\n\t\t\t\tif ( bySet ) {\n\t\t\t\t\t// They will have gone through all possible matchers\n\t\t\t\t\tif ( (elem = !matcher && elem) ) {\n\t\t\t\t\t\tmatchedCount--;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Lengthen the array for every element, matched or not\n\t\t\t\t\tif ( seed ) {\n\t\t\t\t\t\tunmatched.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Apply set filters to unmatched elements\n\t\t\tmatchedCount += i;\n\t\t\tif ( bySet && i !== matchedCount ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (matcher = setMatchers[j++]) ) {\n\t\t\t\t\tmatcher( unmatched, setMatched, context, xml );\n\t\t\t\t}\n\n\t\t\t\tif ( seed ) {\n\t\t\t\t\t// Reintegrate element matches to eliminate the need for sorting\n\t\t\t\t\tif ( matchedCount > 0 ) {\n\t\t\t\t\t\twhile ( i-- ) {\n\t\t\t\t\t\t\tif ( !(unmatched[i] || setMatched[i]) ) {\n\t\t\t\t\t\t\t\tsetMatched[i] = pop.call( results );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Discard index placeholder values to get only actual matches\n\t\t\t\t\tsetMatched = condense( setMatched );\n\t\t\t\t}\n\n\t\t\t\t// Add matches to results\n\t\t\t\tpush.apply( results, setMatched );\n\n\t\t\t\t// Seedless set matches succeeding multiple successful matchers stipulate sorting\n\t\t\t\tif ( outermost && !seed && setMatched.length > 0 &&\n\t\t\t\t\t( matchedCount + setMatchers.length ) > 1 ) {\n\n\t\t\t\t\tSizzle.uniqueSort( results );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Override manipulation of globals by nested matchers\n\t\t\tif ( outermost ) {\n\t\t\t\tdirruns = dirrunsUnique;\n\t\t\t\toutermostContext = contextBackup;\n\t\t\t}\n\n\t\t\treturn unmatched;\n\t\t};\n\n\treturn bySet ?\n\t\tmarkFunction( superMatcher ) :\n\t\tsuperMatcher;\n}\n\ncompile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {\n\tvar i,\n\t\tsetMatchers = [],\n\t\telementMatchers = [],\n\t\tcached = compilerCache[ selector + \" \" ];\n\n\tif ( !cached ) {\n\t\t// Generate a function of recursive functions that can be used to check each element\n\t\tif ( !group ) {\n\t\t\tgroup = tokenize( selector );\n\t\t}\n\t\ti = group.length;\n\t\twhile ( i-- ) {\n\t\t\tcached = matcherFromTokens( group[i] );\n\t\t\tif ( cached[ expando ] ) {\n\t\t\t\tsetMatchers.push( cached );\n\t\t\t} else {\n\t\t\t\telementMatchers.push( cached );\n\t\t\t}\n\t\t}\n\n\t\t// Cache the compiled function\n\t\tcached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );\n\t}\n\treturn cached;\n};\n\nfunction multipleContexts( selector, contexts, results ) {\n\tvar i = 0,\n\t\tlen = contexts.length;\n\tfor ( ; i < len; i++ ) {\n\t\tSizzle( selector, contexts[i], results );\n\t}\n\treturn results;\n}\n\nfunction select( selector, context, results, seed ) {\n\tvar i, tokens, token, type, find,\n\t\tmatch = tokenize( selector );\n\n\tif ( !seed ) {\n\t\t// Try to minimize operations if there is only one group\n\t\tif ( match.length === 1 ) {\n\n\t\t\t// Take a shortcut and set the context if the root selector is an ID\n\t\t\ttokens = match[0] = match[0].slice( 0 );\n\t\t\tif ( tokens.length > 2 && (token = tokens[0]).type === \"ID\" &&\n\t\t\t\t\tsupport.getById && context.nodeType === 9 && documentIsHTML &&\n\t\t\t\t\tExpr.relative[ tokens[1].type ] ) {\n\n\t\t\t\tcontext = ( Expr.find[\"ID\"]( token.matches[0].replace(runescape, funescape), context ) || [] )[0];\n\t\t\t\tif ( !context ) {\n\t\t\t\t\treturn results;\n\t\t\t\t}\n\t\t\t\tselector = selector.slice( tokens.shift().value.length );\n\t\t\t}\n\n\t\t\t// Fetch a seed set for right-to-left matching\n\t\t\ti = matchExpr[\"needsContext\"].test( selector ) ? 0 : tokens.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\ttoken = tokens[i];\n\n\t\t\t\t// Abort if we hit a combinator\n\t\t\t\tif ( Expr.relative[ (type = token.type) ] ) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif ( (find = Expr.find[ type ]) ) {\n\t\t\t\t\t// Search, expanding context for leading sibling combinators\n\t\t\t\t\tif ( (seed = find(\n\t\t\t\t\t\ttoken.matches[0].replace( runescape, funescape ),\n\t\t\t\t\t\trsibling.test( tokens[0].type ) && context.parentNode || context\n\t\t\t\t\t)) ) {\n\n\t\t\t\t\t\t// If seed is empty or no tokens remain, we can return early\n\t\t\t\t\t\ttokens.splice( i, 1 );\n\t\t\t\t\t\tselector = seed.length && toSelector( tokens );\n\t\t\t\t\t\tif ( !selector ) {\n\t\t\t\t\t\t\tpush.apply( results, seed );\n\t\t\t\t\t\t\treturn results;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Compile and execute a filtering function\n\t// Provide `match` to avoid retokenization if we modified the selector above\n\tcompile( selector, match )(\n\t\tseed,\n\t\tcontext,\n\t\t!documentIsHTML,\n\t\tresults,\n\t\trsibling.test( selector )\n\t);\n\treturn results;\n}\n\n// One-time assignments\n\n// Sort stability\nsupport.sortStable = expando.split(\"\").sort( sortOrder ).join(\"\") === expando;\n\n// Support: Chrome<14\n// Always assume duplicates if they aren't passed to the comparison function\nsupport.detectDuplicates = hasDuplicate;\n\n// Initialize against the default document\nsetDocument();\n\n// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)\n// Detached nodes confoundingly follow *each other*\nsupport.sortDetached = assert(function( div1 ) {\n\t// Should return 1, but returns 4 (following)\n\treturn div1.compareDocumentPosition( document.createElement(\"div\") ) & 1;\n});\n\n// Support: IE<8\n// Prevent attribute/property \"interpolation\"\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !assert(function( div ) {\n\tdiv.innerHTML = \"<a href='#'></a>\";\n\treturn div.firstChild.getAttribute(\"href\") === \"#\" ;\n}) ) {\n\taddHandle( \"type|href|height|width\", function( elem, name, isXML ) {\n\t\tif ( !isXML ) {\n\t\t\treturn elem.getAttribute( name, name.toLowerCase() === \"type\" ? 1 : 2 );\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use defaultValue in place of getAttribute(\"value\")\nif ( !support.attributes || !assert(function( div ) {\n\tdiv.innerHTML = \"<input/>\";\n\tdiv.firstChild.setAttribute( \"value\", \"\" );\n\treturn div.firstChild.getAttribute( \"value\" ) === \"\";\n}) ) {\n\taddHandle( \"value\", function( elem, name, isXML ) {\n\t\tif ( !isXML && elem.nodeName.toLowerCase() === \"input\" ) {\n\t\t\treturn elem.defaultValue;\n\t\t}\n\t});\n}\n\n// Support: IE<9\n// Use getAttributeNode to fetch booleans when getAttribute lies\nif ( !assert(function( div ) {\n\treturn div.getAttribute(\"disabled\") == null;\n}) ) {\n\taddHandle( booleans, function( elem, name, isXML ) {\n\t\tvar val;\n\t\tif ( !isXML ) {\n\t\t\treturn (val = elem.getAttributeNode( name )) && val.specified ?\n\t\t\t\tval.value :\n\t\t\t\telem[ name ] === true ? name.toLowerCase() : null;\n\t\t}\n\t});\n}\n\njQuery.find = Sizzle;\njQuery.expr = Sizzle.selectors;\njQuery.expr[\":\"] = jQuery.expr.pseudos;\njQuery.unique = Sizzle.uniqueSort;\njQuery.text = Sizzle.getText;\njQuery.isXMLDoc = Sizzle.isXML;\njQuery.contains = Sizzle.contains;\n\n\n})( window );\n// String to Object options format cache\nvar optionsCache = {};\n\n// Convert String-formatted options into Object-formatted ones and store in cache\nfunction createOptions( options ) {\n\tvar object = optionsCache[ options ] = {};\n\tjQuery.each( options.match( core_rnotwhite ) || [], function( _, flag ) {\n\t\tobject[ flag ] = true;\n\t});\n\treturn object;\n}\n\n/*\n * Create a callback list using the following parameters:\n *\n *\toptions: an optional list of space-separated options that will change how\n *\t\t\tthe callback list behaves or a more traditional option object\n *\n * By default a callback list will act like an event callback list and can be\n * \"fired\" multiple times.\n *\n * Possible options:\n *\n *\tonce:\t\t\twill ensure the callback list can only be fired once (like a Deferred)\n *\n *\tmemory:\t\t\twill keep track of previous values and will call any callback added\n *\t\t\t\t\tafter the list has been fired right away with the latest \"memorized\"\n *\t\t\t\t\tvalues (like a Deferred)\n *\n *\tunique:\t\t\twill ensure a callback can only be added once (no duplicate in the list)\n *\n *\tstopOnFalse:\tinterrupt callings when a callback returns false\n *\n */\njQuery.Callbacks = function( options ) {\n\n\t// Convert options from String-formatted to Object-formatted if needed\n\t// (we check in cache first)\n\toptions = typeof options === \"string\" ?\n\t\t( optionsCache[ options ] || createOptions( options ) ) :\n\t\tjQuery.extend( {}, options );\n\n\tvar // Flag to know if list is currently firing\n\t\tfiring,\n\t\t// Last fire value (for non-forgettable lists)\n\t\tmemory,\n\t\t// Flag to know if list was already fired\n\t\tfired,\n\t\t// End of the loop when firing\n\t\tfiringLength,\n\t\t// Index of currently firing callback (modified by remove if needed)\n\t\tfiringIndex,\n\t\t// First callback to fire (used internally by add and fireWith)\n\t\tfiringStart,\n\t\t// Actual callback list\n\t\tlist = [],\n\t\t// Stack of fire calls for repeatable lists\n\t\tstack = !options.once && [],\n\t\t// Fire callbacks\n\t\tfire = function( data ) {\n\t\t\tmemory = options.memory && data;\n\t\t\tfired = true;\n\t\t\tfiringIndex = firingStart || 0;\n\t\t\tfiringStart = 0;\n\t\t\tfiringLength = list.length;\n\t\t\tfiring = true;\n\t\t\tfor ( ; list && firingIndex < firingLength; firingIndex++ ) {\n\t\t\t\tif ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) {\n\t\t\t\t\tmemory = false; // To prevent further calls using add\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tfiring = false;\n\t\t\tif ( list ) {\n\t\t\t\tif ( stack ) {\n\t\t\t\t\tif ( stack.length ) {\n\t\t\t\t\t\tfire( stack.shift() );\n\t\t\t\t\t}\n\t\t\t\t} else if ( memory ) {\n\t\t\t\t\tlist = [];\n\t\t\t\t} else {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\t// Actual Callbacks object\n\t\tself = {\n\t\t\t// Add a callback or a collection of callbacks to the list\n\t\t\tadd: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\t// First, we save the current length\n\t\t\t\t\tvar start = list.length;\n\t\t\t\t\t(function add( args ) {\n\t\t\t\t\t\tjQuery.each( args, function( _, arg ) {\n\t\t\t\t\t\t\tvar type = jQuery.type( arg );\n\t\t\t\t\t\t\tif ( type === \"function\" ) {\n\t\t\t\t\t\t\t\tif ( !options.unique || !self.has( arg ) ) {\n\t\t\t\t\t\t\t\t\tlist.push( arg );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else if ( arg && arg.length && type !== \"string\" ) {\n\t\t\t\t\t\t\t\t// Inspect recursively\n\t\t\t\t\t\t\t\tadd( arg );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t});\n\t\t\t\t\t})( arguments );\n\t\t\t\t\t// Do we need to add the callbacks to the\n\t\t\t\t\t// current firing batch?\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tfiringLength = list.length;\n\t\t\t\t\t// With memory, if we're not firing then\n\t\t\t\t\t// we should call right away\n\t\t\t\t\t} else if ( memory ) {\n\t\t\t\t\t\tfiringStart = start;\n\t\t\t\t\t\tfire( memory );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Remove a callback from the list\n\t\t\tremove: function() {\n\t\t\t\tif ( list ) {\n\t\t\t\t\tjQuery.each( arguments, function( _, arg ) {\n\t\t\t\t\t\tvar index;\n\t\t\t\t\t\twhile( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {\n\t\t\t\t\t\t\tlist.splice( index, 1 );\n\t\t\t\t\t\t\t// Handle firing indexes\n\t\t\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\t\t\tif ( index <= firingLength ) {\n\t\t\t\t\t\t\t\t\tfiringLength--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ( index <= firingIndex ) {\n\t\t\t\t\t\t\t\t\tfiringIndex--;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Check if a given callback is in the list.\n\t\t\t// If no argument is given, return whether or not list has callbacks attached.\n\t\t\thas: function( fn ) {\n\t\t\t\treturn fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );\n\t\t\t},\n\t\t\t// Remove all callbacks from the list\n\t\t\tempty: function() {\n\t\t\t\tlist = [];\n\t\t\t\tfiringLength = 0;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Have the list do nothing anymore\n\t\t\tdisable: function() {\n\t\t\t\tlist = stack = memory = undefined;\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it disabled?\n\t\t\tdisabled: function() {\n\t\t\t\treturn !list;\n\t\t\t},\n\t\t\t// Lock the list in its current state\n\t\t\tlock: function() {\n\t\t\t\tstack = undefined;\n\t\t\t\tif ( !memory ) {\n\t\t\t\t\tself.disable();\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Is it locked?\n\t\t\tlocked: function() {\n\t\t\t\treturn !stack;\n\t\t\t},\n\t\t\t// Call all callbacks with the given context and arguments\n\t\t\tfireWith: function( context, args ) {\n\t\t\t\tif ( list && ( !fired || stack ) ) {\n\t\t\t\t\targs = args || [];\n\t\t\t\t\targs = [ context, args.slice ? args.slice() : args ];\n\t\t\t\t\tif ( firing ) {\n\t\t\t\t\t\tstack.push( args );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfire( args );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// Call all the callbacks with the given arguments\n\t\t\tfire: function() {\n\t\t\t\tself.fireWith( this, arguments );\n\t\t\t\treturn this;\n\t\t\t},\n\t\t\t// To know if the callbacks have already been called at least once\n\t\t\tfired: function() {\n\t\t\t\treturn !!fired;\n\t\t\t}\n\t\t};\n\n\treturn self;\n};\njQuery.extend({\n\n\tDeferred: function( func ) {\n\t\tvar tuples = [\n\t\t\t\t// action, add listener, listener list, final state\n\t\t\t\t[ \"resolve\", \"done\", jQuery.Callbacks(\"once memory\"), \"resolved\" ],\n\t\t\t\t[ \"reject\", \"fail\", jQuery.Callbacks(\"once memory\"), \"rejected\" ],\n\t\t\t\t[ \"notify\", \"progress\", jQuery.Callbacks(\"memory\") ]\n\t\t\t],\n\t\t\tstate = \"pending\",\n\t\t\tpromise = {\n\t\t\t\tstate: function() {\n\t\t\t\t\treturn state;\n\t\t\t\t},\n\t\t\t\talways: function() {\n\t\t\t\t\tdeferred.done( arguments ).fail( arguments );\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\t\t\t\tthen: function( /* fnDone, fnFail, fnProgress */ ) {\n\t\t\t\t\tvar fns = arguments;\n\t\t\t\t\treturn jQuery.Deferred(function( newDefer ) {\n\t\t\t\t\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\t\t\t\t\tvar action = tuple[ 0 ],\n\t\t\t\t\t\t\t\tfn = jQuery.isFunction( fns[ i ] ) && fns[ i ];\n\t\t\t\t\t\t\t// deferred[ done | fail | progress ] for forwarding actions to newDefer\n\t\t\t\t\t\t\tdeferred[ tuple[1] ](function() {\n\t\t\t\t\t\t\t\tvar returned = fn && fn.apply( this, arguments );\n\t\t\t\t\t\t\t\tif ( returned && jQuery.isFunction( returned.promise ) ) {\n\t\t\t\t\t\t\t\t\treturned.promise()\n\t\t\t\t\t\t\t\t\t\t.done( newDefer.resolve )\n\t\t\t\t\t\t\t\t\t\t.fail( newDefer.reject )\n\t\t\t\t\t\t\t\t\t\t.progress( newDefer.notify );\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tnewDefer[ action + \"With\" ]( this === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t});\n\t\t\t\t\t\tfns = null;\n\t\t\t\t\t}).promise();\n\t\t\t\t},\n\t\t\t\t// Get a promise for this deferred\n\t\t\t\t// If obj is provided, the promise aspect is added to the object\n\t\t\t\tpromise: function( obj ) {\n\t\t\t\t\treturn obj != null ? jQuery.extend( obj, promise ) : promise;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdeferred = {};\n\n\t\t// Keep pipe for back-compat\n\t\tpromise.pipe = promise.then;\n\n\t\t// Add list-specific methods\n\t\tjQuery.each( tuples, function( i, tuple ) {\n\t\t\tvar list = tuple[ 2 ],\n\t\t\t\tstateString = tuple[ 3 ];\n\n\t\t\t// promise[ done | fail | progress ] = list.add\n\t\t\tpromise[ tuple[1] ] = list.add;\n\n\t\t\t// Handle state\n\t\t\tif ( stateString ) {\n\t\t\t\tlist.add(function() {\n\t\t\t\t\t// state = [ resolved | rejected ]\n\t\t\t\t\tstate = stateString;\n\n\t\t\t\t// [ reject_list | resolve_list ].disable; progress_list.lock\n\t\t\t\t}, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock );\n\t\t\t}\n\n\t\t\t// deferred[ resolve | reject | notify ]\n\t\t\tdeferred[ tuple[0] ] = function() {\n\t\t\t\tdeferred[ tuple[0] + \"With\" ]( this === deferred ? promise : this, arguments );\n\t\t\t\treturn this;\n\t\t\t};\n\t\t\tdeferred[ tuple[0] + \"With\" ] = list.fireWith;\n\t\t});\n\n\t\t// Make the deferred a promise\n\t\tpromise.promise( deferred );\n\n\t\t// Call given func if any\n\t\tif ( func ) {\n\t\t\tfunc.call( deferred, deferred );\n\t\t}\n\n\t\t// All done!\n\t\treturn deferred;\n\t},\n\n\t// Deferred helper\n\twhen: function( subordinate /* , ..., subordinateN */ ) {\n\t\tvar i = 0,\n\t\t\tresolveValues = core_slice.call( arguments ),\n\t\t\tlength = resolveValues.length,\n\n\t\t\t// the count of uncompleted subordinates\n\t\t\tremaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0,\n\n\t\t\t// the master Deferred. If resolveValues consist of only a single Deferred, just use that.\n\t\t\tdeferred = remaining === 1 ? subordinate : jQuery.Deferred(),\n\n\t\t\t// Update function for both resolve and progress values\n\t\t\tupdateFunc = function( i, contexts, values ) {\n\t\t\t\treturn function( value ) {\n\t\t\t\t\tcontexts[ i ] = this;\n\t\t\t\t\tvalues[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value;\n\t\t\t\t\tif( values === progressValues ) {\n\t\t\t\t\t\tdeferred.notifyWith( contexts, values );\n\t\t\t\t\t} else if ( !( --remaining ) ) {\n\t\t\t\t\t\tdeferred.resolveWith( contexts, values );\n\t\t\t\t\t}\n\t\t\t\t};\n\t\t\t},\n\n\t\t\tprogressValues, progressContexts, resolveContexts;\n\n\t\t// add listeners to Deferred subordinates; treat others as resolved\n\t\tif ( length > 1 ) {\n\t\t\tprogressValues = new Array( length );\n\t\t\tprogressContexts = new Array( length );\n\t\t\tresolveContexts = new Array( length );\n\t\t\tfor ( ; i < length; i++ ) {\n\t\t\t\tif ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) {\n\t\t\t\t\tresolveValues[ i ].promise()\n\t\t\t\t\t\t.done( updateFunc( i, resolveContexts, resolveValues ) )\n\t\t\t\t\t\t.fail( deferred.reject )\n\t\t\t\t\t\t.progress( updateFunc( i, progressContexts, progressValues ) );\n\t\t\t\t} else {\n\t\t\t\t\t--remaining;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// if we're not waiting on anything, resolve the master\n\t\tif ( !remaining ) {\n\t\t\tdeferred.resolveWith( resolveContexts, resolveValues );\n\t\t}\n\n\t\treturn deferred.promise();\n\t}\n});\njQuery.support = (function( support ) {\n\n\tvar all, a, input, select, fragment, opt, eventName, isSupported, i,\n\t\tdiv = document.createElement(\"div\");\n\n\t// Setup\n\tdiv.setAttribute( \"className\", \"t\" );\n\tdiv.innerHTML = \"  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>\";\n\n\t// Finish early in limited (non-browser) environments\n\tall = div.getElementsByTagName(\"*\") || [];\n\ta = div.getElementsByTagName(\"a\")[ 0 ];\n\tif ( !a || !a.style || !all.length ) {\n\t\treturn support;\n\t}\n\n\t// First batch of tests\n\tselect = document.createElement(\"select\");\n\topt = select.appendChild( document.createElement(\"option\") );\n\tinput = div.getElementsByTagName(\"input\")[ 0 ];\n\n\ta.style.cssText = \"top:1px;float:left;opacity:.5\";\n\n\t// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)\n\tsupport.getSetAttribute = div.className !== \"t\";\n\n\t// IE strips leading whitespace when .innerHTML is used\n\tsupport.leadingWhitespace = div.firstChild.nodeType === 3;\n\n\t// Make sure that tbody elements aren't automatically inserted\n\t// IE will insert them into empty tables\n\tsupport.tbody = !div.getElementsByTagName(\"tbody\").length;\n\n\t// Make sure that link elements get serialized correctly by innerHTML\n\t// This requires a wrapper element in IE\n\tsupport.htmlSerialize = !!div.getElementsByTagName(\"link\").length;\n\n\t// Get the style information from getAttribute\n\t// (IE uses .cssText instead)\n\tsupport.style = /top/.test( a.getAttribute(\"style\") );\n\n\t// Make sure that URLs aren't manipulated\n\t// (IE normalizes it by default)\n\tsupport.hrefNormalized = a.getAttribute(\"href\") === \"/a\";\n\n\t// Make sure that element opacity exists\n\t// (IE uses filter instead)\n\t// Use a regex to work around a WebKit issue. See #5145\n\tsupport.opacity = /^0.5/.test( a.style.opacity );\n\n\t// Verify style float existence\n\t// (IE uses styleFloat instead of cssFloat)\n\tsupport.cssFloat = !!a.style.cssFloat;\n\n\t// Check the default checkbox/radio value (\"\" on WebKit; \"on\" elsewhere)\n\tsupport.checkOn = !!input.value;\n\n\t// Make sure that a selected-by-default option has a working selected property.\n\t// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)\n\tsupport.optSelected = opt.selected;\n\n\t// Tests for enctype support on a form (#6743)\n\tsupport.enctype = !!document.createElement(\"form\").enctype;\n\n\t// Makes sure cloning an html5 element does not cause problems\n\t// Where outerHTML is undefined, this still works\n\tsupport.html5Clone = document.createElement(\"nav\").cloneNode( true ).outerHTML !== \"<:nav></:nav>\";\n\n\t// Will be defined later\n\tsupport.inlineBlockNeedsLayout = false;\n\tsupport.shrinkWrapBlocks = false;\n\tsupport.pixelPosition = false;\n\tsupport.deleteExpando = true;\n\tsupport.noCloneEvent = true;\n\tsupport.reliableMarginRight = true;\n\tsupport.boxSizingReliable = true;\n\n\t// Make sure checked status is properly cloned\n\tinput.checked = true;\n\tsupport.noCloneChecked = input.cloneNode( true ).checked;\n\n\t// Make sure that the options inside disabled selects aren't marked as disabled\n\t// (WebKit marks them as disabled)\n\tselect.disabled = true;\n\tsupport.optDisabled = !opt.disabled;\n\n\t// Support: IE<9\n\ttry {\n\t\tdelete div.test;\n\t} catch( e ) {\n\t\tsupport.deleteExpando = false;\n\t}\n\n\t// Check if we can trust getAttribute(\"value\")\n\tinput = document.createElement(\"input\");\n\tinput.setAttribute( \"value\", \"\" );\n\tsupport.input = input.getAttribute( \"value\" ) === \"\";\n\n\t// Check if an input maintains its value after becoming a radio\n\tinput.value = \"t\";\n\tinput.setAttribute( \"type\", \"radio\" );\n\tsupport.radioValue = input.value === \"t\";\n\n\t// #11217 - WebKit loses check when the name is after the checked attribute\n\tinput.setAttribute( \"checked\", \"t\" );\n\tinput.setAttribute( \"name\", \"t\" );\n\n\tfragment = document.createDocumentFragment();\n\tfragment.appendChild( input );\n\n\t// Check if a disconnected checkbox will retain its checked\n\t// value of true after appended to the DOM (IE6/7)\n\tsupport.appendChecked = input.checked;\n\n\t// WebKit doesn't clone checked state correctly in fragments\n\tsupport.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;\n\n\t// Support: IE<9\n\t// Opera does not clone events (and typeof div.attachEvent === undefined).\n\t// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()\n\tif ( div.attachEvent ) {\n\t\tdiv.attachEvent( \"onclick\", function() {\n\t\t\tsupport.noCloneEvent = false;\n\t\t});\n\n\t\tdiv.cloneNode( true ).click();\n\t}\n\n\t// Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event)\n\t// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)\n\tfor ( i in { submit: true, change: true, focusin: true }) {\n\t\tdiv.setAttribute( eventName = \"on\" + i, \"t\" );\n\n\t\tsupport[ i + \"Bubbles\" ] = eventName in window || div.attributes[ eventName ].expando === false;\n\t}\n\n\tdiv.style.backgroundClip = \"content-box\";\n\tdiv.cloneNode( true ).style.backgroundClip = \"\";\n\tsupport.clearCloneStyle = div.style.backgroundClip === \"content-box\";\n\n\t// Support: IE<9\n\t// Iteration over object's inherited properties before its own.\n\tfor ( i in jQuery( support ) ) {\n\t\tbreak;\n\t}\n\tsupport.ownLast = i !== \"0\";\n\n\t// Run tests that need a body at doc ready\n\tjQuery(function() {\n\t\tvar container, marginDiv, tds,\n\t\t\tdivReset = \"padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;\",\n\t\t\tbody = document.getElementsByTagName(\"body\")[0];\n\n\t\tif ( !body ) {\n\t\t\t// Return for frameset docs that don't have a body\n\t\t\treturn;\n\t\t}\n\n\t\tcontainer = document.createElement(\"div\");\n\t\tcontainer.style.cssText = \"border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px\";\n\n\t\tbody.appendChild( container ).appendChild( div );\n\n\t\t// Support: IE8\n\t\t// Check if table cells still have offsetWidth/Height when they are set\n\t\t// to display:none and there are still other visible table cells in a\n\t\t// table row; if so, offsetWidth/Height are not reliable for use when\n\t\t// determining if an element has been hidden directly using\n\t\t// display:none (it is still safe to use offsets if a parent element is\n\t\t// hidden; don safety goggles and see bug #4512 for more information).\n\t\tdiv.innerHTML = \"<table><tr><td></td><td>t</td></tr></table>\";\n\t\ttds = div.getElementsByTagName(\"td\");\n\t\ttds[ 0 ].style.cssText = \"padding:0;margin:0;border:0;display:none\";\n\t\tisSupported = ( tds[ 0 ].offsetHeight === 0 );\n\n\t\ttds[ 0 ].style.display = \"\";\n\t\ttds[ 1 ].style.display = \"none\";\n\n\t\t// Support: IE8\n\t\t// Check if empty table cells still have offsetWidth/Height\n\t\tsupport.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );\n\n\t\t// Check box-sizing and margin behavior.\n\t\tdiv.innerHTML = \"\";\n\t\tdiv.style.cssText = \"box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;\";\n\n\t\t// Workaround failing boxSizing test due to offsetWidth returning wrong value\n\t\t// with some non-1 values of body zoom, ticket #13543\n\t\tjQuery.swap( body, body.style.zoom != null ? { zoom: 1 } : {}, function() {\n\t\t\tsupport.boxSizing = div.offsetWidth === 4;\n\t\t});\n\n\t\t// Use window.getComputedStyle because jsdom on node.js will break without it.\n\t\tif ( window.getComputedStyle ) {\n\t\t\tsupport.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== \"1%\";\n\t\t\tsupport.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: \"4px\" } ).width === \"4px\";\n\n\t\t\t// Check if div with explicit width and no margin-right incorrectly\n\t\t\t// gets computed margin-right based on width of container. (#3333)\n\t\t\t// Fails in WebKit before Feb 2011 nightlies\n\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\tmarginDiv = div.appendChild( document.createElement(\"div\") );\n\t\t\tmarginDiv.style.cssText = div.style.cssText = divReset;\n\t\t\tmarginDiv.style.marginRight = marginDiv.style.width = \"0\";\n\t\t\tdiv.style.width = \"1px\";\n\n\t\t\tsupport.reliableMarginRight =\n\t\t\t\t!parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );\n\t\t}\n\n\t\tif ( typeof div.style.zoom !== core_strundefined ) {\n\t\t\t// Support: IE<8\n\t\t\t// Check if natively block-level elements act like inline-block\n\t\t\t// elements when setting their display to 'inline' and giving\n\t\t\t// them layout\n\t\t\tdiv.innerHTML = \"\";\n\t\t\tdiv.style.cssText = divReset + \"width:1px;padding:1px;display:inline;zoom:1\";\n\t\t\tsupport.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );\n\n\t\t\t// Support: IE6\n\t\t\t// Check if elements with layout shrink-wrap their children\n\t\t\tdiv.style.display = \"block\";\n\t\t\tdiv.innerHTML = \"<div></div>\";\n\t\t\tdiv.firstChild.style.width = \"5px\";\n\t\t\tsupport.shrinkWrapBlocks = ( div.offsetWidth !== 3 );\n\n\t\t\tif ( support.inlineBlockNeedsLayout ) {\n\t\t\t\t// Prevent IE 6 from affecting layout for positioned elements #11048\n\t\t\t\t// Prevent IE from shrinking the body in IE 7 mode #12869\n\t\t\t\t// Support: IE<8\n\t\t\t\tbody.style.zoom = 1;\n\t\t\t}\n\t\t}\n\n\t\tbody.removeChild( container );\n\n\t\t// Null elements to avoid leaks in IE\n\t\tcontainer = div = tds = marginDiv = null;\n\t});\n\n\t// Null elements to avoid leaks in IE\n\tall = select = fragment = opt = a = input = null;\n\n\treturn support;\n})({});\n\nvar rbrace = /(?:\\{[\\s\\S]*\\}|\\[[\\s\\S]*\\])$/,\n\trmultiDash = /([A-Z])/g;\n\nfunction internalData( elem, name, data, pvt /* Internal Use Only */ ){\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar ret, thisCache,\n\t\tinternalKey = jQuery.expando,\n\n\t\t// We have to handle DOM nodes and JS objects differently because IE6-7\n\t\t// can't GC object references properly across the DOM-JS boundary\n\t\tisNode = elem.nodeType,\n\n\t\t// Only DOM nodes need the global jQuery cache; JS object data is\n\t\t// attached directly to the object so GC can occur automatically\n\t\tcache = isNode ? jQuery.cache : elem,\n\n\t\t// Only defining an ID for JS objects if its cache already exists allows\n\t\t// the code to shortcut on the same path as a DOM node with no cache\n\t\tid = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey;\n\n\t// Avoid doing any more work than we need to when trying to get data on an\n\t// object that has no data at all\n\tif ( (!id || !cache[id] || (!pvt && !cache[id].data)) && data === undefined && typeof name === \"string\" ) {\n\t\treturn;\n\t}\n\n\tif ( !id ) {\n\t\t// Only DOM nodes need a new unique ID for each element since their data\n\t\t// ends up in the global cache\n\t\tif ( isNode ) {\n\t\t\tid = elem[ internalKey ] = core_deletedIds.pop() || jQuery.guid++;\n\t\t} else {\n\t\t\tid = internalKey;\n\t\t}\n\t}\n\n\tif ( !cache[ id ] ) {\n\t\t// Avoid exposing jQuery metadata on plain JS objects when the object\n\t\t// is serialized using JSON.stringify\n\t\tcache[ id ] = isNode ? {} : { toJSON: jQuery.noop };\n\t}\n\n\t// An object can be passed to jQuery.data instead of a key/value pair; this gets\n\t// shallow copied over onto the existing cache\n\tif ( typeof name === \"object\" || typeof name === \"function\" ) {\n\t\tif ( pvt ) {\n\t\t\tcache[ id ] = jQuery.extend( cache[ id ], name );\n\t\t} else {\n\t\t\tcache[ id ].data = jQuery.extend( cache[ id ].data, name );\n\t\t}\n\t}\n\n\tthisCache = cache[ id ];\n\n\t// jQuery data() is stored in a separate object inside the object's internal data\n\t// cache in order to avoid key collisions between internal data and user-defined\n\t// data.\n\tif ( !pvt ) {\n\t\tif ( !thisCache.data ) {\n\t\t\tthisCache.data = {};\n\t\t}\n\n\t\tthisCache = thisCache.data;\n\t}\n\n\tif ( data !== undefined ) {\n\t\tthisCache[ jQuery.camelCase( name ) ] = data;\n\t}\n\n\t// Check for both converted-to-camel and non-converted data property names\n\t// If a data property was specified\n\tif ( typeof name === \"string\" ) {\n\n\t\t// First Try to find as-is property data\n\t\tret = thisCache[ name ];\n\n\t\t// Test for null|undefined property data\n\t\tif ( ret == null ) {\n\n\t\t\t// Try to find the camelCased property\n\t\t\tret = thisCache[ jQuery.camelCase( name ) ];\n\t\t}\n\t} else {\n\t\tret = thisCache;\n\t}\n\n\treturn ret;\n}\n\nfunction internalRemoveData( elem, name, pvt ) {\n\tif ( !jQuery.acceptData( elem ) ) {\n\t\treturn;\n\t}\n\n\tvar thisCache, i,\n\t\tisNode = elem.nodeType,\n\n\t\t// See jQuery.data for more information\n\t\tcache = isNode ? jQuery.cache : elem,\n\t\tid = isNode ? elem[ jQuery.expando ] : jQuery.expando;\n\n\t// If there is already no cache entry for this object, there is no\n\t// purpose in continuing\n\tif ( !cache[ id ] ) {\n\t\treturn;\n\t}\n\n\tif ( name ) {\n\n\t\tthisCache = pvt ? cache[ id ] : cache[ id ].data;\n\n\t\tif ( thisCache ) {\n\n\t\t\t// Support array or space separated string names for data keys\n\t\t\tif ( !jQuery.isArray( name ) ) {\n\n\t\t\t\t// try the string as a key before any manipulation\n\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\tname = [ name ];\n\t\t\t\t} else {\n\n\t\t\t\t\t// split the camel cased version by spaces unless a key with the spaces exists\n\t\t\t\t\tname = jQuery.camelCase( name );\n\t\t\t\t\tif ( name in thisCache ) {\n\t\t\t\t\t\tname = [ name ];\n\t\t\t\t\t} else {\n\t\t\t\t\t\tname = name.split(\" \");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// If \"name\" is an array of keys...\n\t\t\t\t// When data is initially created, via (\"key\", \"val\") signature,\n\t\t\t\t// keys will be converted to camelCase.\n\t\t\t\t// Since there is no way to tell _how_ a key was added, remove\n\t\t\t\t// both plain key and camelCase key. #12786\n\t\t\t\t// This will only penalize the array argument path.\n\t\t\t\tname = name.concat( jQuery.map( name, jQuery.camelCase ) );\n\t\t\t}\n\n\t\t\ti = name.length;\n\t\t\twhile ( i-- ) {\n\t\t\t\tdelete thisCache[ name[i] ];\n\t\t\t}\n\n\t\t\t// If there is no data left in the cache, we want to continue\n\t\t\t// and let the cache object itself get destroyed\n\t\t\tif ( pvt ? !isEmptyDataObject(thisCache) : !jQuery.isEmptyObject(thisCache) ) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\t// See jQuery.data for more information\n\tif ( !pvt ) {\n\t\tdelete cache[ id ].data;\n\n\t\t// Don't destroy the parent cache unless the internal data object\n\t\t// had been the only thing left in it\n\t\tif ( !isEmptyDataObject( cache[ id ] ) ) {\n\t\t\treturn;\n\t\t}\n\t}\n\n\t// Destroy the cache\n\tif ( isNode ) {\n\t\tjQuery.cleanData( [ elem ], true );\n\n\t// Use delete when supported for expandos or `cache` is not a window per isWindow (#10080)\n\t/* jshint eqeqeq: false */\n\t} else if ( jQuery.support.deleteExpando || cache != cache.window ) {\n\t\t/* jshint eqeqeq: true */\n\t\tdelete cache[ id ];\n\n\t// When all else fails, null\n\t} else {\n\t\tcache[ id ] = null;\n\t}\n}\n\njQuery.extend({\n\tcache: {},\n\n\t// The following elements throw uncatchable exceptions if you\n\t// attempt to add expando properties to them.\n\tnoData: {\n\t\t\"applet\": true,\n\t\t\"embed\": true,\n\t\t// Ban all objects except for Flash (which handle expandos)\n\t\t\"object\": \"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\"\n\t},\n\n\thasData: function( elem ) {\n\t\telem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ];\n\t\treturn !!elem && !isEmptyDataObject( elem );\n\t},\n\n\tdata: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data );\n\t},\n\n\tremoveData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name );\n\t},\n\n\t// For internal use only.\n\t_data: function( elem, name, data ) {\n\t\treturn internalData( elem, name, data, true );\n\t},\n\n\t_removeData: function( elem, name ) {\n\t\treturn internalRemoveData( elem, name, true );\n\t},\n\n\t// A method for determining if a DOM node can handle the data expando\n\tacceptData: function( elem ) {\n\t\t// Do not set data on non-element because it will not be cleared (#8335).\n\t\tif ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {\n\t\t\treturn false;\n\t\t}\n\n\t\tvar noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ];\n\n\t\t// nodes accept data unless otherwise specified; rejection can be conditional\n\t\treturn !noData || noData !== true && elem.getAttribute(\"classid\") === noData;\n\t}\n});\n\njQuery.fn.extend({\n\tdata: function( key, value ) {\n\t\tvar attrs, name,\n\t\t\tdata = null,\n\t\t\ti = 0,\n\t\t\telem = this[0];\n\n\t\t// Special expections of .data basically thwart jQuery.access,\n\t\t// so implement the relevant behavior ourselves\n\n\t\t// Gets all values\n\t\tif ( key === undefined ) {\n\t\t\tif ( this.length ) {\n\t\t\t\tdata = jQuery.data( elem );\n\n\t\t\t\tif ( elem.nodeType === 1 && !jQuery._data( elem, \"parsedAttrs\" ) ) {\n\t\t\t\t\tattrs = elem.attributes;\n\t\t\t\t\tfor ( ; i < attrs.length; i++ ) {\n\t\t\t\t\t\tname = attrs[i].name;\n\n\t\t\t\t\t\tif ( name.indexOf(\"data-\") === 0 ) {\n\t\t\t\t\t\t\tname = jQuery.camelCase( name.slice(5) );\n\n\t\t\t\t\t\t\tdataAttr( elem, name, data[ name ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tjQuery._data( elem, \"parsedAttrs\", true );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\treturn data;\n\t\t}\n\n\t\t// Sets multiple values\n\t\tif ( typeof key === \"object\" ) {\n\t\t\treturn this.each(function() {\n\t\t\t\tjQuery.data( this, key );\n\t\t\t});\n\t\t}\n\n\t\treturn arguments.length > 1 ?\n\n\t\t\t// Sets one value\n\t\t\tthis.each(function() {\n\t\t\t\tjQuery.data( this, key, value );\n\t\t\t}) :\n\n\t\t\t// Gets one value\n\t\t\t// Try to fetch any internally stored data first\n\t\t\telem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;\n\t},\n\n\tremoveData: function( key ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeData( this, key );\n\t\t});\n\t}\n});\n\nfunction dataAttr( elem, key, data ) {\n\t// If nothing was found internally, try to fetch any\n\t// data from the HTML5 data-* attribute\n\tif ( data === undefined && elem.nodeType === 1 ) {\n\n\t\tvar name = \"data-\" + key.replace( rmultiDash, \"-$1\" ).toLowerCase();\n\n\t\tdata = elem.getAttribute( name );\n\n\t\tif ( typeof data === \"string\" ) {\n\t\t\ttry {\n\t\t\t\tdata = data === \"true\" ? true :\n\t\t\t\t\tdata === \"false\" ? false :\n\t\t\t\t\tdata === \"null\" ? null :\n\t\t\t\t\t// Only convert to a number if it doesn't change the string\n\t\t\t\t\t+data + \"\" === data ? +data :\n\t\t\t\t\trbrace.test( data ) ? jQuery.parseJSON( data ) :\n\t\t\t\t\t\tdata;\n\t\t\t} catch( e ) {}\n\n\t\t\t// Make sure we set the data so it isn't changed later\n\t\t\tjQuery.data( elem, key, data );\n\n\t\t} else {\n\t\t\tdata = undefined;\n\t\t}\n\t}\n\n\treturn data;\n}\n\n// checks a cache object for emptiness\nfunction isEmptyDataObject( obj ) {\n\tvar name;\n\tfor ( name in obj ) {\n\n\t\t// if the public data object is empty, the private is still empty\n\t\tif ( name === \"data\" && jQuery.isEmptyObject( obj[name] ) ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( name !== \"toJSON\" ) {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\treturn true;\n}\njQuery.extend({\n\tqueue: function( elem, type, data ) {\n\t\tvar queue;\n\n\t\tif ( elem ) {\n\t\t\ttype = ( type || \"fx\" ) + \"queue\";\n\t\t\tqueue = jQuery._data( elem, type );\n\n\t\t\t// Speed up dequeue by getting out quickly if this is just a lookup\n\t\t\tif ( data ) {\n\t\t\t\tif ( !queue || jQuery.isArray(data) ) {\n\t\t\t\t\tqueue = jQuery._data( elem, type, jQuery.makeArray(data) );\n\t\t\t\t} else {\n\t\t\t\t\tqueue.push( data );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn queue || [];\n\t\t}\n\t},\n\n\tdequeue: function( elem, type ) {\n\t\ttype = type || \"fx\";\n\n\t\tvar queue = jQuery.queue( elem, type ),\n\t\t\tstartLength = queue.length,\n\t\t\tfn = queue.shift(),\n\t\t\thooks = jQuery._queueHooks( elem, type ),\n\t\t\tnext = function() {\n\t\t\t\tjQuery.dequeue( elem, type );\n\t\t\t};\n\n\t\t// If the fx queue is dequeued, always remove the progress sentinel\n\t\tif ( fn === \"inprogress\" ) {\n\t\t\tfn = queue.shift();\n\t\t\tstartLength--;\n\t\t}\n\n\t\tif ( fn ) {\n\n\t\t\t// Add a progress sentinel to prevent the fx queue from being\n\t\t\t// automatically dequeued\n\t\t\tif ( type === \"fx\" ) {\n\t\t\t\tqueue.unshift( \"inprogress\" );\n\t\t\t}\n\n\t\t\t// clear up the last queue stop function\n\t\t\tdelete hooks.stop;\n\t\t\tfn.call( elem, next, hooks );\n\t\t}\n\n\t\tif ( !startLength && hooks ) {\n\t\t\thooks.empty.fire();\n\t\t}\n\t},\n\n\t// not intended for public consumption - generates a queueHooks object, or returns the current one\n\t_queueHooks: function( elem, type ) {\n\t\tvar key = type + \"queueHooks\";\n\t\treturn jQuery._data( elem, key ) || jQuery._data( elem, key, {\n\t\t\tempty: jQuery.Callbacks(\"once memory\").add(function() {\n\t\t\t\tjQuery._removeData( elem, type + \"queue\" );\n\t\t\t\tjQuery._removeData( elem, key );\n\t\t\t})\n\t\t});\n\t}\n});\n\njQuery.fn.extend({\n\tqueue: function( type, data ) {\n\t\tvar setter = 2;\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tdata = type;\n\t\t\ttype = \"fx\";\n\t\t\tsetter--;\n\t\t}\n\n\t\tif ( arguments.length < setter ) {\n\t\t\treturn jQuery.queue( this[0], type );\n\t\t}\n\n\t\treturn data === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function() {\n\t\t\t\tvar queue = jQuery.queue( this, type, data );\n\n\t\t\t\t// ensure a hooks for this queue\n\t\t\t\tjQuery._queueHooks( this, type );\n\n\t\t\t\tif ( type === \"fx\" && queue[0] !== \"inprogress\" ) {\n\t\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t\t}\n\t\t\t});\n\t},\n\tdequeue: function( type ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.dequeue( this, type );\n\t\t});\n\t},\n\t// Based off of the plugin by Clint Helfers, with permission.\n\t// http://blindsignals.com/index.php/2009/07/jquery-delay/\n\tdelay: function( time, type ) {\n\t\ttime = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;\n\t\ttype = type || \"fx\";\n\n\t\treturn this.queue( type, function( next, hooks ) {\n\t\t\tvar timeout = setTimeout( next, time );\n\t\t\thooks.stop = function() {\n\t\t\t\tclearTimeout( timeout );\n\t\t\t};\n\t\t});\n\t},\n\tclearQueue: function( type ) {\n\t\treturn this.queue( type || \"fx\", [] );\n\t},\n\t// Get a promise resolved when queues of a certain type\n\t// are emptied (fx is the type by default)\n\tpromise: function( type, obj ) {\n\t\tvar tmp,\n\t\t\tcount = 1,\n\t\t\tdefer = jQuery.Deferred(),\n\t\t\telements = this,\n\t\t\ti = this.length,\n\t\t\tresolve = function() {\n\t\t\t\tif ( !( --count ) ) {\n\t\t\t\t\tdefer.resolveWith( elements, [ elements ] );\n\t\t\t\t}\n\t\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tobj = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\ttype = type || \"fx\";\n\n\t\twhile( i-- ) {\n\t\t\ttmp = jQuery._data( elements[ i ], type + \"queueHooks\" );\n\t\t\tif ( tmp && tmp.empty ) {\n\t\t\t\tcount++;\n\t\t\t\ttmp.empty.add( resolve );\n\t\t\t}\n\t\t}\n\t\tresolve();\n\t\treturn defer.promise( obj );\n\t}\n});\nvar nodeHook, boolHook,\n\trclass = /[\\t\\r\\n\\f]/g,\n\trreturn = /\\r/g,\n\trfocusable = /^(?:input|select|textarea|button|object)$/i,\n\trclickable = /^(?:a|area)$/i,\n\truseDefault = /^(?:checked|selected)$/i,\n\tgetSetAttribute = jQuery.support.getSetAttribute,\n\tgetSetInput = jQuery.support.input;\n\njQuery.fn.extend({\n\tattr: function( name, value ) {\n\t\treturn jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 );\n\t},\n\n\tremoveAttr: function( name ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.removeAttr( this, name );\n\t\t});\n\t},\n\n\tprop: function( name, value ) {\n\t\treturn jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 );\n\t},\n\n\tremoveProp: function( name ) {\n\t\tname = jQuery.propFix[ name ] || name;\n\t\treturn this.each(function() {\n\t\t\t// try/catch handles cases where IE balks (such as removing a property on window)\n\t\t\ttry {\n\t\t\t\tthis[ name ] = undefined;\n\t\t\t\tdelete this[ name ];\n\t\t\t} catch( e ) {}\n\t\t});\n\t},\n\n\taddClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).addClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\n\t\tif ( proceed ) {\n\t\t\t// The disjunction here is for better compressibility (see removeClass)\n\t\t\tclasses = ( value || \"\" ).match( core_rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\" \"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\tif ( cur.indexOf( \" \" + clazz + \" \" ) < 0 ) {\n\t\t\t\t\t\t\tcur += clazz + \" \";\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telem.className = jQuery.trim( cur );\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tremoveClass: function( value ) {\n\t\tvar classes, elem, cur, clazz, j,\n\t\t\ti = 0,\n\t\t\tlen = this.length,\n\t\t\tproceed = arguments.length === 0 || typeof value === \"string\" && value;\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( j ) {\n\t\t\t\tjQuery( this ).removeClass( value.call( this, j, this.className ) );\n\t\t\t});\n\t\t}\n\t\tif ( proceed ) {\n\t\t\tclasses = ( value || \"\" ).match( core_rnotwhite ) || [];\n\n\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\telem = this[ i ];\n\t\t\t\t// This expression is here for better compressibility (see addClass)\n\t\t\t\tcur = elem.nodeType === 1 && ( elem.className ?\n\t\t\t\t\t( \" \" + elem.className + \" \" ).replace( rclass, \" \" ) :\n\t\t\t\t\t\"\"\n\t\t\t\t);\n\n\t\t\t\tif ( cur ) {\n\t\t\t\t\tj = 0;\n\t\t\t\t\twhile ( (clazz = classes[j++]) ) {\n\t\t\t\t\t\t// Remove *all* instances\n\t\t\t\t\t\twhile ( cur.indexOf( \" \" + clazz + \" \" ) >= 0 ) {\n\t\t\t\t\t\t\tcur = cur.replace( \" \" + clazz + \" \", \" \" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\telem.className = value ? jQuery.trim( cur ) : \"\";\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\ttoggleClass: function( value, stateVal ) {\n\t\tvar type = typeof value;\n\n\t\tif ( typeof stateVal === \"boolean\" && type === \"string\" ) {\n\t\t\treturn stateVal ? this.addClass( value ) : this.removeClass( value );\n\t\t}\n\n\t\tif ( jQuery.isFunction( value ) ) {\n\t\t\treturn this.each(function( i ) {\n\t\t\t\tjQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( type === \"string\" ) {\n\t\t\t\t// toggle individual class names\n\t\t\t\tvar className,\n\t\t\t\t\ti = 0,\n\t\t\t\t\tself = jQuery( this ),\n\t\t\t\t\tclassNames = value.match( core_rnotwhite ) || [];\n\n\t\t\t\twhile ( (className = classNames[ i++ ]) ) {\n\t\t\t\t\t// check each className given, space separated list\n\t\t\t\t\tif ( self.hasClass( className ) ) {\n\t\t\t\t\t\tself.removeClass( className );\n\t\t\t\t\t} else {\n\t\t\t\t\t\tself.addClass( className );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t// Toggle whole class name\n\t\t\t} else if ( type === core_strundefined || type === \"boolean\" ) {\n\t\t\t\tif ( this.className ) {\n\t\t\t\t\t// store className if set\n\t\t\t\t\tjQuery._data( this, \"__className__\", this.className );\n\t\t\t\t}\n\n\t\t\t\t// If the element has a class name or if we're passed \"false\",\n\t\t\t\t// then remove the whole classname (if there was one, the above saved it).\n\t\t\t\t// Otherwise bring back whatever was previously saved (if anything),\n\t\t\t\t// falling back to the empty string if nothing was stored.\n\t\t\t\tthis.className = this.className || value === false ? \"\" : jQuery._data( this, \"__className__\" ) || \"\";\n\t\t\t}\n\t\t});\n\t},\n\n\thasClass: function( selector ) {\n\t\tvar className = \" \" + selector + \" \",\n\t\t\ti = 0,\n\t\t\tl = this.length;\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tif ( this[i].nodeType === 1 && (\" \" + this[i].className + \" \").replace(rclass, \" \").indexOf( className ) >= 0 ) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t},\n\n\tval: function( value ) {\n\t\tvar ret, hooks, isFunction,\n\t\t\telem = this[0];\n\n\t\tif ( !arguments.length ) {\n\t\t\tif ( elem ) {\n\t\t\t\thooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ];\n\n\t\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, \"value\" )) !== undefined ) {\n\t\t\t\t\treturn ret;\n\t\t\t\t}\n\n\t\t\t\tret = elem.value;\n\n\t\t\t\treturn typeof ret === \"string\" ?\n\t\t\t\t\t// handle most common string cases\n\t\t\t\t\tret.replace(rreturn, \"\") :\n\t\t\t\t\t// handle cases where value is null/undef or number\n\t\t\t\t\tret == null ? \"\" : ret;\n\t\t\t}\n\n\t\t\treturn;\n\t\t}\n\n\t\tisFunction = jQuery.isFunction( value );\n\n\t\treturn this.each(function( i ) {\n\t\t\tvar val;\n\n\t\t\tif ( this.nodeType !== 1 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tif ( isFunction ) {\n\t\t\t\tval = value.call( this, i, jQuery( this ).val() );\n\t\t\t} else {\n\t\t\t\tval = value;\n\t\t\t}\n\n\t\t\t// Treat null/undefined as \"\"; convert numbers to string\n\t\t\tif ( val == null ) {\n\t\t\t\tval = \"\";\n\t\t\t} else if ( typeof val === \"number\" ) {\n\t\t\t\tval += \"\";\n\t\t\t} else if ( jQuery.isArray( val ) ) {\n\t\t\t\tval = jQuery.map(val, function ( value ) {\n\t\t\t\t\treturn value == null ? \"\" : value + \"\";\n\t\t\t\t});\n\t\t\t}\n\n\t\t\thooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ];\n\n\t\t\t// If set returns undefined, fall back to normal setting\n\t\t\tif ( !hooks || !(\"set\" in hooks) || hooks.set( this, val, \"value\" ) === undefined ) {\n\t\t\t\tthis.value = val;\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\tvalHooks: {\n\t\toption: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// Use proper attribute retrieval(#6932, #12072)\n\t\t\t\tvar val = jQuery.find.attr( elem, \"value\" );\n\t\t\t\treturn val != null ?\n\t\t\t\t\tval :\n\t\t\t\t\telem.text;\n\t\t\t}\n\t\t},\n\t\tselect: {\n\t\t\tget: function( elem ) {\n\t\t\t\tvar value, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tindex = elem.selectedIndex,\n\t\t\t\t\tone = elem.type === \"select-one\" || index < 0,\n\t\t\t\t\tvalues = one ? null : [],\n\t\t\t\t\tmax = one ? index + 1 : options.length,\n\t\t\t\t\ti = index < 0 ?\n\t\t\t\t\t\tmax :\n\t\t\t\t\t\tone ? index : 0;\n\n\t\t\t\t// Loop through all the selected options\n\t\t\t\tfor ( ; i < max; i++ ) {\n\t\t\t\t\toption = options[ i ];\n\n\t\t\t\t\t// oldIE doesn't update selected after form reset (#2551)\n\t\t\t\t\tif ( ( option.selected || i === index ) &&\n\t\t\t\t\t\t\t// Don't return options that are disabled or in a disabled optgroup\n\t\t\t\t\t\t\t( jQuery.support.optDisabled ? !option.disabled : option.getAttribute(\"disabled\") === null ) &&\n\t\t\t\t\t\t\t( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, \"optgroup\" ) ) ) {\n\n\t\t\t\t\t\t// Get the specific value for the option\n\t\t\t\t\t\tvalue = jQuery( option ).val();\n\n\t\t\t\t\t\t// We don't need an array for one selects\n\t\t\t\t\t\tif ( one ) {\n\t\t\t\t\t\t\treturn value;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Multi-Selects return an array\n\t\t\t\t\t\tvalues.push( value );\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treturn values;\n\t\t\t},\n\n\t\t\tset: function( elem, value ) {\n\t\t\t\tvar optionSet, option,\n\t\t\t\t\toptions = elem.options,\n\t\t\t\t\tvalues = jQuery.makeArray( value ),\n\t\t\t\t\ti = options.length;\n\n\t\t\t\twhile ( i-- ) {\n\t\t\t\t\toption = options[ i ];\n\t\t\t\t\tif ( (option.selected = jQuery.inArray( jQuery(option).val(), values ) >= 0) ) {\n\t\t\t\t\t\toptionSet = true;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// force browsers to behave consistently when non-matching value is set\n\t\t\t\tif ( !optionSet ) {\n\t\t\t\t\telem.selectedIndex = -1;\n\t\t\t\t}\n\t\t\t\treturn values;\n\t\t\t}\n\t\t}\n\t},\n\n\tattr: function( elem, name, value ) {\n\t\tvar hooks, ret,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set attributes on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Fallback to prop when attributes are not supported\n\t\tif ( typeof elem.getAttribute === core_strundefined ) {\n\t\t\treturn jQuery.prop( elem, name, value );\n\t\t}\n\n\t\t// All attributes are lowercase\n\t\t// Grab necessary hook if one is defined\n\t\tif ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {\n\t\t\tname = name.toLowerCase();\n\t\t\thooks = jQuery.attrHooks[ name ] ||\n\t\t\t\t( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\n\t\t\tif ( value === null ) {\n\t\t\t\tjQuery.removeAttr( elem, name );\n\n\t\t\t} else if ( hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {\n\t\t\t\treturn ret;\n\n\t\t\t} else {\n\t\t\t\telem.setAttribute( name, value + \"\" );\n\t\t\t\treturn value;\n\t\t\t}\n\n\t\t} else if ( hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ) {\n\t\t\treturn ret;\n\n\t\t} else {\n\t\t\tret = jQuery.find.attr( elem, name );\n\n\t\t\t// Non-existent attributes return null, we normalize to undefined\n\t\t\treturn ret == null ?\n\t\t\t\tundefined :\n\t\t\t\tret;\n\t\t}\n\t},\n\n\tremoveAttr: function( elem, value ) {\n\t\tvar name, propName,\n\t\t\ti = 0,\n\t\t\tattrNames = value && value.match( core_rnotwhite );\n\n\t\tif ( attrNames && elem.nodeType === 1 ) {\n\t\t\twhile ( (name = attrNames[i++]) ) {\n\t\t\t\tpropName = jQuery.propFix[ name ] || name;\n\n\t\t\t\t// Boolean attributes get special treatment (#10870)\n\t\t\t\tif ( jQuery.expr.match.bool.test( name ) ) {\n\t\t\t\t\t// Set corresponding property to false\n\t\t\t\t\tif ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t// Also clear defaultChecked/defaultSelected (if appropriate)\n\t\t\t\t\t} else {\n\t\t\t\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] =\n\t\t\t\t\t\t\telem[ propName ] = false;\n\t\t\t\t\t}\n\n\t\t\t\t// See #9699 for explanation of this approach (setting first, then removal)\n\t\t\t\t} else {\n\t\t\t\t\tjQuery.attr( elem, name, \"\" );\n\t\t\t\t}\n\n\t\t\t\telem.removeAttribute( getSetAttribute ? name : propName );\n\t\t\t}\n\t\t}\n\t},\n\n\tattrHooks: {\n\t\ttype: {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( !jQuery.support.radioValue && value === \"radio\" && jQuery.nodeName(elem, \"input\") ) {\n\t\t\t\t\t// Setting the type on a radio button after the value resets the value in IE6-9\n\t\t\t\t\t// Reset value to default in case type is set after value during creation\n\t\t\t\t\tvar val = elem.value;\n\t\t\t\t\telem.setAttribute( \"type\", value );\n\t\t\t\t\tif ( val ) {\n\t\t\t\t\t\telem.value = val;\n\t\t\t\t\t}\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tpropFix: {\n\t\t\"for\": \"htmlFor\",\n\t\t\"class\": \"className\"\n\t},\n\n\tprop: function( elem, name, value ) {\n\t\tvar ret, hooks, notxml,\n\t\t\tnType = elem.nodeType;\n\n\t\t// don't get/set properties on text, comment and attribute nodes\n\t\tif ( !elem || nType === 3 || nType === 8 || nType === 2 ) {\n\t\t\treturn;\n\t\t}\n\n\t\tnotxml = nType !== 1 || !jQuery.isXMLDoc( elem );\n\n\t\tif ( notxml ) {\n\t\t\t// Fix name and attach hooks\n\t\t\tname = jQuery.propFix[ name ] || name;\n\t\t\thooks = jQuery.propHooks[ name ];\n\t\t}\n\n\t\tif ( value !== undefined ) {\n\t\t\treturn hooks && \"set\" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ?\n\t\t\t\tret :\n\t\t\t\t( elem[ name ] = value );\n\n\t\t} else {\n\t\t\treturn hooks && \"get\" in hooks && (ret = hooks.get( elem, name )) !== null ?\n\t\t\t\tret :\n\t\t\t\telem[ name ];\n\t\t}\n\t},\n\n\tpropHooks: {\n\t\ttabIndex: {\n\t\t\tget: function( elem ) {\n\t\t\t\t// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set\n\t\t\t\t// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/\n\t\t\t\t// Use proper attribute retrieval(#12072)\n\t\t\t\tvar tabindex = jQuery.find.attr( elem, \"tabindex\" );\n\n\t\t\t\treturn tabindex ?\n\t\t\t\t\tparseInt( tabindex, 10 ) :\n\t\t\t\t\trfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?\n\t\t\t\t\t\t0 :\n\t\t\t\t\t\t-1;\n\t\t\t}\n\t\t}\n\t}\n});\n\n// Hooks for boolean attributes\nboolHook = {\n\tset: function( elem, value, name ) {\n\t\tif ( value === false ) {\n\t\t\t// Remove boolean attributes when set to false\n\t\t\tjQuery.removeAttr( elem, name );\n\t\t} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {\n\t\t\t// IE<8 needs the *property* name\n\t\t\telem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );\n\n\t\t// Use defaultChecked and defaultSelected for oldIE\n\t\t} else {\n\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] = elem[ name ] = true;\n\t\t}\n\n\t\treturn name;\n\t}\n};\njQuery.each( jQuery.expr.match.bool.source.match( /\\w+/g ), function( i, name ) {\n\tvar getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;\n\n\tjQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar fn = jQuery.expr.attrHandle[ name ],\n\t\t\t\tret = isXML ?\n\t\t\t\t\tundefined :\n\t\t\t\t\t/* jshint eqeqeq: false */\n\t\t\t\t\t(jQuery.expr.attrHandle[ name ] = undefined) !=\n\t\t\t\t\t\tgetter( elem, name, isXML ) ?\n\n\t\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\t\tnull;\n\t\t\tjQuery.expr.attrHandle[ name ] = fn;\n\t\t\treturn ret;\n\t\t} :\n\t\tfunction( elem, name, isXML ) {\n\t\t\treturn isXML ?\n\t\t\t\tundefined :\n\t\t\t\telem[ jQuery.camelCase( \"default-\" + name ) ] ?\n\t\t\t\t\tname.toLowerCase() :\n\t\t\t\t\tnull;\n\t\t};\n});\n\n// fix oldIE attroperties\nif ( !getSetInput || !getSetAttribute ) {\n\tjQuery.attrHooks.value = {\n\t\tset: function( elem, value, name ) {\n\t\t\tif ( jQuery.nodeName( elem, \"input\" ) ) {\n\t\t\t\t// Does not return so that setAttribute is also used\n\t\t\t\telem.defaultValue = value;\n\t\t\t} else {\n\t\t\t\t// Use nodeHook if defined (#1954); otherwise setAttribute is fine\n\t\t\t\treturn nodeHook && nodeHook.set( elem, value, name );\n\t\t\t}\n\t\t}\n\t};\n}\n\n// IE6/7 do not support getting/setting some attributes with get/setAttribute\nif ( !getSetAttribute ) {\n\n\t// Use this for any attribute in IE6/7\n\t// This fixes almost every IE6/7 issue\n\tnodeHook = {\n\t\tset: function( elem, value, name ) {\n\t\t\t// Set the existing or create a new attribute node\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\tif ( !ret ) {\n\t\t\t\telem.setAttributeNode(\n\t\t\t\t\t(ret = elem.ownerDocument.createAttribute( name ))\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tret.value = value += \"\";\n\n\t\t\t// Break association with cloned elements by also using setAttribute (#9646)\n\t\t\treturn name === \"value\" || value === elem.getAttribute( name ) ?\n\t\t\t\tvalue :\n\t\t\t\tundefined;\n\t\t}\n\t};\n\tjQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords =\n\t\t// Some attributes are constructed with empty-string values when not defined\n\t\tfunction( elem, name, isXML ) {\n\t\t\tvar ret;\n\t\t\treturn isXML ?\n\t\t\t\tundefined :\n\t\t\t\t(ret = elem.getAttributeNode( name )) && ret.value !== \"\" ?\n\t\t\t\t\tret.value :\n\t\t\t\t\tnull;\n\t\t};\n\tjQuery.valHooks.button = {\n\t\tget: function( elem, name ) {\n\t\t\tvar ret = elem.getAttributeNode( name );\n\t\t\treturn ret && ret.specified ?\n\t\t\t\tret.value :\n\t\t\t\tundefined;\n\t\t},\n\t\tset: nodeHook.set\n\t};\n\n\t// Set contenteditable to false on removals(#10429)\n\t// Setting to empty string throws an error as an invalid value\n\tjQuery.attrHooks.contenteditable = {\n\t\tset: function( elem, value, name ) {\n\t\t\tnodeHook.set( elem, value === \"\" ? false : value, name );\n\t\t}\n\t};\n\n\t// Set width and height to auto instead of 0 on empty string( Bug #8150 )\n\t// This is for removals\n\tjQuery.each([ \"width\", \"height\" ], function( i, name ) {\n\t\tjQuery.attrHooks[ name ] = {\n\t\t\tset: function( elem, value ) {\n\t\t\t\tif ( value === \"\" ) {\n\t\t\t\t\telem.setAttribute( name, \"auto\" );\n\t\t\t\t\treturn value;\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\n\n// Some attributes require a special call on IE\n// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx\nif ( !jQuery.support.hrefNormalized ) {\n\t// href/src property should get the full normalized URL (#10299/#12915)\n\tjQuery.each([ \"href\", \"src\" ], function( i, name ) {\n\t\tjQuery.propHooks[ name ] = {\n\t\t\tget: function( elem ) {\n\t\t\t\treturn elem.getAttribute( name, 4 );\n\t\t\t}\n\t\t};\n\t});\n}\n\nif ( !jQuery.support.style ) {\n\tjQuery.attrHooks.style = {\n\t\tget: function( elem ) {\n\t\t\t// Return undefined in the case of empty string\n\t\t\t// Note: IE uppercases css property names, but if we were to .toLowerCase()\n\t\t\t// .cssText, that would destroy case senstitivity in URL's, like in \"background\"\n\t\t\treturn elem.style.cssText || undefined;\n\t\t},\n\t\tset: function( elem, value ) {\n\t\t\treturn ( elem.style.cssText = value + \"\" );\n\t\t}\n\t};\n}\n\n// Safari mis-reports the default selected property of an option\n// Accessing the parent's selectedIndex property fixes it\nif ( !jQuery.support.optSelected ) {\n\tjQuery.propHooks.selected = {\n\t\tget: function( elem ) {\n\t\t\tvar parent = elem.parentNode;\n\n\t\t\tif ( parent ) {\n\t\t\t\tparent.selectedIndex;\n\n\t\t\t\t// Make sure that it also works with optgroups, see #5701\n\t\t\t\tif ( parent.parentNode ) {\n\t\t\t\t\tparent.parentNode.selectedIndex;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn null;\n\t\t}\n\t};\n}\n\njQuery.each([\n\t\"tabIndex\",\n\t\"readOnly\",\n\t\"maxLength\",\n\t\"cellSpacing\",\n\t\"cellPadding\",\n\t\"rowSpan\",\n\t\"colSpan\",\n\t\"useMap\",\n\t\"frameBorder\",\n\t\"contentEditable\"\n], function() {\n\tjQuery.propFix[ this.toLowerCase() ] = this;\n});\n\n// IE6/7 call enctype encoding\nif ( !jQuery.support.enctype ) {\n\tjQuery.propFix.enctype = \"encoding\";\n}\n\n// Radios and checkboxes getter/setter\njQuery.each([ \"radio\", \"checkbox\" ], function() {\n\tjQuery.valHooks[ this ] = {\n\t\tset: function( elem, value ) {\n\t\t\tif ( jQuery.isArray( value ) ) {\n\t\t\t\treturn ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );\n\t\t\t}\n\t\t}\n\t};\n\tif ( !jQuery.support.checkOn ) {\n\t\tjQuery.valHooks[ this ].get = function( elem ) {\n\t\t\t// Support: Webkit\n\t\t\t// \"\" is returned instead of \"on\" if a value isn't specified\n\t\t\treturn elem.getAttribute(\"value\") === null ? \"on\" : elem.value;\n\t\t};\n\t}\n});\nvar rformElems = /^(?:input|select|textarea)$/i,\n\trkeyEvent = /^key/,\n\trmouseEvent = /^(?:mouse|contextmenu)|click/,\n\trfocusMorph = /^(?:focusinfocus|focusoutblur)$/,\n\trtypenamespace = /^([^.]*)(?:\\.(.+)|)$/;\n\nfunction returnTrue() {\n\treturn true;\n}\n\nfunction returnFalse() {\n\treturn false;\n}\n\nfunction safeActiveElement() {\n\ttry {\n\t\treturn document.activeElement;\n\t} catch ( err ) { }\n}\n\n/*\n * Helper functions for managing events -- not part of the public interface.\n * Props to Dean Edwards' addEvent library for many of the ideas.\n */\njQuery.event = {\n\n\tglobal: {},\n\n\tadd: function( elem, types, handler, data, selector ) {\n\t\tvar tmp, events, t, handleObjIn,\n\t\t\tspecial, eventHandle, handleObj,\n\t\t\thandlers, type, namespaces, origType,\n\t\t\telemData = jQuery._data( elem );\n\n\t\t// Don't attach events to noData or text/comment nodes (but allow plain objects)\n\t\tif ( !elemData ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Caller can pass in an object of custom data in lieu of the handler\n\t\tif ( handler.handler ) {\n\t\t\thandleObjIn = handler;\n\t\t\thandler = handleObjIn.handler;\n\t\t\tselector = handleObjIn.selector;\n\t\t}\n\n\t\t// Make sure that the handler has a unique ID, used to find/remove it later\n\t\tif ( !handler.guid ) {\n\t\t\thandler.guid = jQuery.guid++;\n\t\t}\n\n\t\t// Init the element's event structure and main handler, if this is the first\n\t\tif ( !(events = elemData.events) ) {\n\t\t\tevents = elemData.events = {};\n\t\t}\n\t\tif ( !(eventHandle = elemData.handle) ) {\n\t\t\teventHandle = elemData.handle = function( e ) {\n\t\t\t\t// Discard the second event of a jQuery.event.trigger() and\n\t\t\t\t// when an event is called after a page has unloaded\n\t\t\t\treturn typeof jQuery !== core_strundefined && (!e || jQuery.event.triggered !== e.type) ?\n\t\t\t\t\tjQuery.event.dispatch.apply( eventHandle.elem, arguments ) :\n\t\t\t\t\tundefined;\n\t\t\t};\n\t\t\t// Add elem as a property of the handle fn to prevent a memory leak with IE non-native events\n\t\t\teventHandle.elem = elem;\n\t\t}\n\n\t\t// Handle multiple events separated by a space\n\t\ttypes = ( types || \"\" ).match( core_rnotwhite ) || [\"\"];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// There *must* be a type, no attaching namespace-only handlers\n\t\t\tif ( !type ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// If event changes its type, use the special event handlers for the changed type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// If selector defined, determine special event api type, otherwise given type\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\n\t\t\t// Update special based on newly reset type\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\n\t\t\t// handleObj is passed to all event handlers\n\t\t\thandleObj = jQuery.extend({\n\t\t\t\ttype: type,\n\t\t\t\torigType: origType,\n\t\t\t\tdata: data,\n\t\t\t\thandler: handler,\n\t\t\t\tguid: handler.guid,\n\t\t\t\tselector: selector,\n\t\t\t\tneedsContext: selector && jQuery.expr.match.needsContext.test( selector ),\n\t\t\t\tnamespace: namespaces.join(\".\")\n\t\t\t}, handleObjIn );\n\n\t\t\t// Init the event handler queue if we're the first\n\t\t\tif ( !(handlers = events[ type ]) ) {\n\t\t\t\thandlers = events[ type ] = [];\n\t\t\t\thandlers.delegateCount = 0;\n\n\t\t\t\t// Only use addEventListener/attachEvent if the special events handler returns false\n\t\t\t\tif ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {\n\t\t\t\t\t// Bind the global event handler to the element\n\t\t\t\t\tif ( elem.addEventListener ) {\n\t\t\t\t\t\telem.addEventListener( type, eventHandle, false );\n\n\t\t\t\t\t} else if ( elem.attachEvent ) {\n\t\t\t\t\t\telem.attachEvent( \"on\" + type, eventHandle );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ( special.add ) {\n\t\t\t\tspecial.add.call( elem, handleObj );\n\n\t\t\t\tif ( !handleObj.handler.guid ) {\n\t\t\t\t\thandleObj.handler.guid = handler.guid;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add to the element's handler list, delegates in front\n\t\t\tif ( selector ) {\n\t\t\t\thandlers.splice( handlers.delegateCount++, 0, handleObj );\n\t\t\t} else {\n\t\t\t\thandlers.push( handleObj );\n\t\t\t}\n\n\t\t\t// Keep track of which events have ever been used, for event optimization\n\t\t\tjQuery.event.global[ type ] = true;\n\t\t}\n\n\t\t// Nullify elem to prevent memory leaks in IE\n\t\telem = null;\n\t},\n\n\t// Detach an event or set of events from an element\n\tremove: function( elem, types, handler, selector, mappedTypes ) {\n\t\tvar j, handleObj, tmp,\n\t\t\torigCount, t, events,\n\t\t\tspecial, handlers, type,\n\t\t\tnamespaces, origType,\n\t\t\telemData = jQuery.hasData( elem ) && jQuery._data( elem );\n\n\t\tif ( !elemData || !(events = elemData.events) ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Once for each type.namespace in types; type may be omitted\n\t\ttypes = ( types || \"\" ).match( core_rnotwhite ) || [\"\"];\n\t\tt = types.length;\n\t\twhile ( t-- ) {\n\t\t\ttmp = rtypenamespace.exec( types[t] ) || [];\n\t\t\ttype = origType = tmp[1];\n\t\t\tnamespaces = ( tmp[2] || \"\" ).split( \".\" ).sort();\n\n\t\t\t// Unbind all events (on this namespace, if provided) for the element\n\t\t\tif ( !type ) {\n\t\t\t\tfor ( type in events ) {\n\t\t\t\t\tjQuery.event.remove( elem, type + types[ t ], handler, selector, true );\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tspecial = jQuery.event.special[ type ] || {};\n\t\t\ttype = ( selector ? special.delegateType : special.bindType ) || type;\n\t\t\thandlers = events[ type ] || [];\n\t\t\ttmp = tmp[2] && new RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" );\n\n\t\t\t// Remove matching events\n\t\t\torigCount = j = handlers.length;\n\t\t\twhile ( j-- ) {\n\t\t\t\thandleObj = handlers[ j ];\n\n\t\t\t\tif ( ( mappedTypes || origType === handleObj.origType ) &&\n\t\t\t\t\t( !handler || handler.guid === handleObj.guid ) &&\n\t\t\t\t\t( !tmp || tmp.test( handleObj.namespace ) ) &&\n\t\t\t\t\t( !selector || selector === handleObj.selector || selector === \"**\" && handleObj.selector ) ) {\n\t\t\t\t\thandlers.splice( j, 1 );\n\n\t\t\t\t\tif ( handleObj.selector ) {\n\t\t\t\t\t\thandlers.delegateCount--;\n\t\t\t\t\t}\n\t\t\t\t\tif ( special.remove ) {\n\t\t\t\t\t\tspecial.remove.call( elem, handleObj );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Remove generic event handler if we removed something and no more handlers exist\n\t\t\t// (avoids potential for endless recursion during removal of special event handlers)\n\t\t\tif ( origCount && !handlers.length ) {\n\t\t\t\tif ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {\n\t\t\t\t\tjQuery.removeEvent( elem, type, elemData.handle );\n\t\t\t\t}\n\n\t\t\t\tdelete events[ type ];\n\t\t\t}\n\t\t}\n\n\t\t// Remove the expando if it's no longer used\n\t\tif ( jQuery.isEmptyObject( events ) ) {\n\t\t\tdelete elemData.handle;\n\n\t\t\t// removeData also checks for emptiness and clears the expando if empty\n\t\t\t// so use it instead of delete\n\t\t\tjQuery._removeData( elem, \"events\" );\n\t\t}\n\t},\n\n\ttrigger: function( event, data, elem, onlyHandlers ) {\n\t\tvar handle, ontype, cur,\n\t\t\tbubbleType, special, tmp, i,\n\t\t\teventPath = [ elem || document ],\n\t\t\ttype = core_hasOwn.call( event, \"type\" ) ? event.type : event,\n\t\t\tnamespaces = core_hasOwn.call( event, \"namespace\" ) ? event.namespace.split(\".\") : [];\n\n\t\tcur = tmp = elem = elem || document;\n\n\t\t// Don't do events on text and comment nodes\n\t\tif ( elem.nodeType === 3 || elem.nodeType === 8 ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// focus/blur morphs to focusin/out; ensure we're not firing them right now\n\t\tif ( rfocusMorph.test( type + jQuery.event.triggered ) ) {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( type.indexOf(\".\") >= 0 ) {\n\t\t\t// Namespaced trigger; create a regexp to match event type in handle()\n\t\t\tnamespaces = type.split(\".\");\n\t\t\ttype = namespaces.shift();\n\t\t\tnamespaces.sort();\n\t\t}\n\t\tontype = type.indexOf(\":\") < 0 && \"on\" + type;\n\n\t\t// Caller can pass in a jQuery.Event object, Object, or just an event type string\n\t\tevent = event[ jQuery.expando ] ?\n\t\t\tevent :\n\t\t\tnew jQuery.Event( type, typeof event === \"object\" && event );\n\n\t\t// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)\n\t\tevent.isTrigger = onlyHandlers ? 2 : 3;\n\t\tevent.namespace = namespaces.join(\".\");\n\t\tevent.namespace_re = event.namespace ?\n\t\t\tnew RegExp( \"(^|\\\\.)\" + namespaces.join(\"\\\\.(?:.*\\\\.|)\") + \"(\\\\.|$)\" ) :\n\t\t\tnull;\n\n\t\t// Clean up the event in case it is being reused\n\t\tevent.result = undefined;\n\t\tif ( !event.target ) {\n\t\t\tevent.target = elem;\n\t\t}\n\n\t\t// Clone any incoming data and prepend the event, creating the handler arg list\n\t\tdata = data == null ?\n\t\t\t[ event ] :\n\t\t\tjQuery.makeArray( data, [ event ] );\n\n\t\t// Allow special events to draw outside the lines\n\t\tspecial = jQuery.event.special[ type ] || {};\n\t\tif ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine event propagation path in advance, per W3C events spec (#9951)\n\t\t// Bubble up to document, then to window; watch for a global ownerDocument var (#9724)\n\t\tif ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {\n\n\t\t\tbubbleType = special.delegateType || type;\n\t\t\tif ( !rfocusMorph.test( bubbleType + type ) ) {\n\t\t\t\tcur = cur.parentNode;\n\t\t\t}\n\t\t\tfor ( ; cur; cur = cur.parentNode ) {\n\t\t\t\teventPath.push( cur );\n\t\t\t\ttmp = cur;\n\t\t\t}\n\n\t\t\t// Only add window if we got to document (e.g., not plain obj or detached DOM)\n\t\t\tif ( tmp === (elem.ownerDocument || document) ) {\n\t\t\t\teventPath.push( tmp.defaultView || tmp.parentWindow || window );\n\t\t\t}\n\t\t}\n\n\t\t// Fire handlers on the event path\n\t\ti = 0;\n\t\twhile ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {\n\n\t\t\tevent.type = i > 1 ?\n\t\t\t\tbubbleType :\n\t\t\t\tspecial.bindType || type;\n\n\t\t\t// jQuery handler\n\t\t\thandle = ( jQuery._data( cur, \"events\" ) || {} )[ event.type ] && jQuery._data( cur, \"handle\" );\n\t\t\tif ( handle ) {\n\t\t\t\thandle.apply( cur, data );\n\t\t\t}\n\n\t\t\t// Native handler\n\t\t\thandle = ontype && cur[ ontype ];\n\t\t\tif ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {\n\t\t\t\tevent.preventDefault();\n\t\t\t}\n\t\t}\n\t\tevent.type = type;\n\n\t\t// If nobody prevented the default action, do it now\n\t\tif ( !onlyHandlers && !event.isDefaultPrevented() ) {\n\n\t\t\tif ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&\n\t\t\t\tjQuery.acceptData( elem ) ) {\n\n\t\t\t\t// Call a native DOM method on the target with the same name name as the event.\n\t\t\t\t// Can't use an .isFunction() check here because IE6/7 fails that test.\n\t\t\t\t// Don't do default actions on window, that's where global variables be (#6170)\n\t\t\t\tif ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {\n\n\t\t\t\t\t// Don't re-trigger an onFOO event when we call its FOO() method\n\t\t\t\t\ttmp = elem[ ontype ];\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = null;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prevent re-triggering of the same event, since we already bubbled it above\n\t\t\t\t\tjQuery.event.triggered = type;\n\t\t\t\t\ttry {\n\t\t\t\t\t\telem[ type ]();\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// IE<9 dies on focus/blur to hidden element (#1486,#12518)\n\t\t\t\t\t\t// only reproducible on winXP IE8 native, not IE9 in IE8 mode\n\t\t\t\t\t}\n\t\t\t\t\tjQuery.event.triggered = undefined;\n\n\t\t\t\t\tif ( tmp ) {\n\t\t\t\t\t\telem[ ontype ] = tmp;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\tdispatch: function( event ) {\n\n\t\t// Make a writable jQuery.Event from the native event object\n\t\tevent = jQuery.event.fix( event );\n\n\t\tvar i, ret, handleObj, matched, j,\n\t\t\thandlerQueue = [],\n\t\t\targs = core_slice.call( arguments ),\n\t\t\thandlers = ( jQuery._data( this, \"events\" ) || {} )[ event.type ] || [],\n\t\t\tspecial = jQuery.event.special[ event.type ] || {};\n\n\t\t// Use the fix-ed jQuery.Event rather than the (read-only) native event\n\t\targs[0] = event;\n\t\tevent.delegateTarget = this;\n\n\t\t// Call the preDispatch hook for the mapped type, and let it bail if desired\n\t\tif ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Determine handlers\n\t\thandlerQueue = jQuery.event.handlers.call( this, event, handlers );\n\n\t\t// Run delegates first; they may want to stop propagation beneath us\n\t\ti = 0;\n\t\twhile ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {\n\t\t\tevent.currentTarget = matched.elem;\n\n\t\t\tj = 0;\n\t\t\twhile ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {\n\n\t\t\t\t// Triggered event must either 1) have no namespace, or\n\t\t\t\t// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).\n\t\t\t\tif ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {\n\n\t\t\t\t\tevent.handleObj = handleObj;\n\t\t\t\t\tevent.data = handleObj.data;\n\n\t\t\t\t\tret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )\n\t\t\t\t\t\t\t.apply( matched.elem, args );\n\n\t\t\t\t\tif ( ret !== undefined ) {\n\t\t\t\t\t\tif ( (event.result = ret) === false ) {\n\t\t\t\t\t\t\tevent.preventDefault();\n\t\t\t\t\t\t\tevent.stopPropagation();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Call the postDispatch hook for the mapped type\n\t\tif ( special.postDispatch ) {\n\t\t\tspecial.postDispatch.call( this, event );\n\t\t}\n\n\t\treturn event.result;\n\t},\n\n\thandlers: function( event, handlers ) {\n\t\tvar sel, handleObj, matches, i,\n\t\t\thandlerQueue = [],\n\t\t\tdelegateCount = handlers.delegateCount,\n\t\t\tcur = event.target;\n\n\t\t// Find delegate handlers\n\t\t// Black-hole SVG <use> instance trees (#13180)\n\t\t// Avoid non-left-click bubbling in Firefox (#3861)\n\t\tif ( delegateCount && cur.nodeType && (!event.button || event.type !== \"click\") ) {\n\n\t\t\t/* jshint eqeqeq: false */\n\t\t\tfor ( ; cur != this; cur = cur.parentNode || this ) {\n\t\t\t\t/* jshint eqeqeq: true */\n\n\t\t\t\t// Don't check non-elements (#13208)\n\t\t\t\t// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)\n\t\t\t\tif ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== \"click\") ) {\n\t\t\t\t\tmatches = [];\n\t\t\t\t\tfor ( i = 0; i < delegateCount; i++ ) {\n\t\t\t\t\t\thandleObj = handlers[ i ];\n\n\t\t\t\t\t\t// Don't conflict with Object.prototype properties (#13203)\n\t\t\t\t\t\tsel = handleObj.selector + \" \";\n\n\t\t\t\t\t\tif ( matches[ sel ] === undefined ) {\n\t\t\t\t\t\t\tmatches[ sel ] = handleObj.needsContext ?\n\t\t\t\t\t\t\t\tjQuery( sel, this ).index( cur ) >= 0 :\n\t\t\t\t\t\t\t\tjQuery.find( sel, this, null, [ cur ] ).length;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ( matches[ sel ] ) {\n\t\t\t\t\t\t\tmatches.push( handleObj );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ( matches.length ) {\n\t\t\t\t\t\thandlerQueue.push({ elem: cur, handlers: matches });\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Add the remaining (directly-bound) handlers\n\t\tif ( delegateCount < handlers.length ) {\n\t\t\thandlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });\n\t\t}\n\n\t\treturn handlerQueue;\n\t},\n\n\tfix: function( event ) {\n\t\tif ( event[ jQuery.expando ] ) {\n\t\t\treturn event;\n\t\t}\n\n\t\t// Create a writable copy of the event object and normalize some properties\n\t\tvar i, prop, copy,\n\t\t\ttype = event.type,\n\t\t\toriginalEvent = event,\n\t\t\tfixHook = this.fixHooks[ type ];\n\n\t\tif ( !fixHook ) {\n\t\t\tthis.fixHooks[ type ] = fixHook =\n\t\t\t\trmouseEvent.test( type ) ? this.mouseHooks :\n\t\t\t\trkeyEvent.test( type ) ? this.keyHooks :\n\t\t\t\t{};\n\t\t}\n\t\tcopy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;\n\n\t\tevent = new jQuery.Event( originalEvent );\n\n\t\ti = copy.length;\n\t\twhile ( i-- ) {\n\t\t\tprop = copy[ i ];\n\t\t\tevent[ prop ] = originalEvent[ prop ];\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// Fix target property (#1925)\n\t\tif ( !event.target ) {\n\t\t\tevent.target = originalEvent.srcElement || document;\n\t\t}\n\n\t\t// Support: Chrome 23+, Safari?\n\t\t// Target should not be a text node (#504, #13143)\n\t\tif ( event.target.nodeType === 3 ) {\n\t\t\tevent.target = event.target.parentNode;\n\t\t}\n\n\t\t// Support: IE<9\n\t\t// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)\n\t\tevent.metaKey = !!event.metaKey;\n\n\t\treturn fixHook.filter ? fixHook.filter( event, originalEvent ) : event;\n\t},\n\n\t// Includes some event props shared by KeyEvent and MouseEvent\n\tprops: \"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which\".split(\" \"),\n\n\tfixHooks: {},\n\n\tkeyHooks: {\n\t\tprops: \"char charCode key keyCode\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\n\t\t\t// Add which for key events\n\t\t\tif ( event.which == null ) {\n\t\t\t\tevent.which = original.charCode != null ? original.charCode : original.keyCode;\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tmouseHooks: {\n\t\tprops: \"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement\".split(\" \"),\n\t\tfilter: function( event, original ) {\n\t\t\tvar body, eventDoc, doc,\n\t\t\t\tbutton = original.button,\n\t\t\t\tfromElement = original.fromElement;\n\n\t\t\t// Calculate pageX/Y if missing and clientX/Y available\n\t\t\tif ( event.pageX == null && original.clientX != null ) {\n\t\t\t\teventDoc = event.target.ownerDocument || document;\n\t\t\t\tdoc = eventDoc.documentElement;\n\t\t\t\tbody = eventDoc.body;\n\n\t\t\t\tevent.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 );\n\t\t\t\tevent.pageY = original.clientY + ( doc && doc.scrollTop  || body && body.scrollTop  || 0 ) - ( doc && doc.clientTop  || body && body.clientTop  || 0 );\n\t\t\t}\n\n\t\t\t// Add relatedTarget, if necessary\n\t\t\tif ( !event.relatedTarget && fromElement ) {\n\t\t\t\tevent.relatedTarget = fromElement === event.target ? original.toElement : fromElement;\n\t\t\t}\n\n\t\t\t// Add which for click: 1 === left; 2 === middle; 3 === right\n\t\t\t// Note: button is not normalized, so don't use it\n\t\t\tif ( !event.which && button !== undefined ) {\n\t\t\t\tevent.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );\n\t\t\t}\n\n\t\t\treturn event;\n\t\t}\n\t},\n\n\tspecial: {\n\t\tload: {\n\t\t\t// Prevent triggered image.load events from bubbling to window.load\n\t\t\tnoBubble: true\n\t\t},\n\t\tfocus: {\n\t\t\t// Fire native event if possible so blur/focus sequence is correct\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this !== safeActiveElement() && this.focus ) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tthis.focus();\n\t\t\t\t\t\treturn false;\n\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t// Support: IE<9\n\t\t\t\t\t\t// If we error on focus to hidden element (#1486, #12518),\n\t\t\t\t\t\t// let .trigger() run the handlers\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusin\"\n\t\t},\n\t\tblur: {\n\t\t\ttrigger: function() {\n\t\t\t\tif ( this === safeActiveElement() && this.blur ) {\n\t\t\t\t\tthis.blur();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\t\t\tdelegateType: \"focusout\"\n\t\t},\n\t\tclick: {\n\t\t\t// For checkbox, fire native event so checked state will be right\n\t\t\ttrigger: function() {\n\t\t\t\tif ( jQuery.nodeName( this, \"input\" ) && this.type === \"checkbox\" && this.click ) {\n\t\t\t\t\tthis.click();\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t},\n\n\t\t\t// For cross-browser consistency, don't fire native .click() on links\n\t\t\t_default: function( event ) {\n\t\t\t\treturn jQuery.nodeName( event.target, \"a\" );\n\t\t\t}\n\t\t},\n\n\t\tbeforeunload: {\n\t\t\tpostDispatch: function( event ) {\n\n\t\t\t\t// Even when returnValue equals to undefined Firefox will still show alert\n\t\t\t\tif ( event.result !== undefined ) {\n\t\t\t\t\tevent.originalEvent.returnValue = event.result;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\tsimulate: function( type, elem, event, bubble ) {\n\t\t// Piggyback on a donor event to simulate a different one.\n\t\t// Fake originalEvent to avoid donor's stopPropagation, but if the\n\t\t// simulated event prevents default then we do the same on the donor.\n\t\tvar e = jQuery.extend(\n\t\t\tnew jQuery.Event(),\n\t\t\tevent,\n\t\t\t{\n\t\t\t\ttype: type,\n\t\t\t\tisSimulated: true,\n\t\t\t\toriginalEvent: {}\n\t\t\t}\n\t\t);\n\t\tif ( bubble ) {\n\t\t\tjQuery.event.trigger( e, null, elem );\n\t\t} else {\n\t\t\tjQuery.event.dispatch.call( elem, e );\n\t\t}\n\t\tif ( e.isDefaultPrevented() ) {\n\t\t\tevent.preventDefault();\n\t\t}\n\t}\n};\n\njQuery.removeEvent = document.removeEventListener ?\n\tfunction( elem, type, handle ) {\n\t\tif ( elem.removeEventListener ) {\n\t\t\telem.removeEventListener( type, handle, false );\n\t\t}\n\t} :\n\tfunction( elem, type, handle ) {\n\t\tvar name = \"on\" + type;\n\n\t\tif ( elem.detachEvent ) {\n\n\t\t\t// #8545, #7054, preventing memory leaks for custom events in IE6-8\n\t\t\t// detachEvent needed property on element, by name of that event, to properly expose it to GC\n\t\t\tif ( typeof elem[ name ] === core_strundefined ) {\n\t\t\t\telem[ name ] = null;\n\t\t\t}\n\n\t\t\telem.detachEvent( name, handle );\n\t\t}\n\t};\n\njQuery.Event = function( src, props ) {\n\t// Allow instantiation without the 'new' keyword\n\tif ( !(this instanceof jQuery.Event) ) {\n\t\treturn new jQuery.Event( src, props );\n\t}\n\n\t// Event object\n\tif ( src && src.type ) {\n\t\tthis.originalEvent = src;\n\t\tthis.type = src.type;\n\n\t\t// Events bubbling up the document may have been marked as prevented\n\t\t// by a handler lower down the tree; reflect the correct value.\n\t\tthis.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||\n\t\t\tsrc.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;\n\n\t// Event type\n\t} else {\n\t\tthis.type = src;\n\t}\n\n\t// Put explicitly provided properties onto the event object\n\tif ( props ) {\n\t\tjQuery.extend( this, props );\n\t}\n\n\t// Create a timestamp if incoming event doesn't have one\n\tthis.timeStamp = src && src.timeStamp || jQuery.now();\n\n\t// Mark it as fixed\n\tthis[ jQuery.expando ] = true;\n};\n\n// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding\n// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html\njQuery.Event.prototype = {\n\tisDefaultPrevented: returnFalse,\n\tisPropagationStopped: returnFalse,\n\tisImmediatePropagationStopped: returnFalse,\n\n\tpreventDefault: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isDefaultPrevented = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// If preventDefault exists, run it on the original event\n\t\tif ( e.preventDefault ) {\n\t\t\te.preventDefault();\n\n\t\t// Support: IE\n\t\t// Otherwise set the returnValue property of the original event to false\n\t\t} else {\n\t\t\te.returnValue = false;\n\t\t}\n\t},\n\tstopPropagation: function() {\n\t\tvar e = this.originalEvent;\n\n\t\tthis.isPropagationStopped = returnTrue;\n\t\tif ( !e ) {\n\t\t\treturn;\n\t\t}\n\t\t// If stopPropagation exists, run it on the original event\n\t\tif ( e.stopPropagation ) {\n\t\t\te.stopPropagation();\n\t\t}\n\n\t\t// Support: IE\n\t\t// Set the cancelBubble property of the original event to true\n\t\te.cancelBubble = true;\n\t},\n\tstopImmediatePropagation: function() {\n\t\tthis.isImmediatePropagationStopped = returnTrue;\n\t\tthis.stopPropagation();\n\t}\n};\n\n// Create mouseenter/leave events using mouseover/out and event-time checks\njQuery.each({\n\tmouseenter: \"mouseover\",\n\tmouseleave: \"mouseout\"\n}, function( orig, fix ) {\n\tjQuery.event.special[ orig ] = {\n\t\tdelegateType: fix,\n\t\tbindType: fix,\n\n\t\thandle: function( event ) {\n\t\t\tvar ret,\n\t\t\t\ttarget = this,\n\t\t\t\trelated = event.relatedTarget,\n\t\t\t\thandleObj = event.handleObj;\n\n\t\t\t// For mousenter/leave call the handler if related is outside the target.\n\t\t\t// NB: No relatedTarget if the mouse left/entered the browser window\n\t\t\tif ( !related || (related !== target && !jQuery.contains( target, related )) ) {\n\t\t\t\tevent.type = handleObj.origType;\n\t\t\t\tret = handleObj.handler.apply( this, arguments );\n\t\t\t\tevent.type = fix;\n\t\t\t}\n\t\t\treturn ret;\n\t\t}\n\t};\n});\n\n// IE submit delegation\nif ( !jQuery.support.submitBubbles ) {\n\n\tjQuery.event.special.submit = {\n\t\tsetup: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Lazy-add a submit handler when a descendant form may potentially be submitted\n\t\t\tjQuery.event.add( this, \"click._submit keypress._submit\", function( e ) {\n\t\t\t\t// Node name check avoids a VML-related crash in IE (#9807)\n\t\t\t\tvar elem = e.target,\n\t\t\t\t\tform = jQuery.nodeName( elem, \"input\" ) || jQuery.nodeName( elem, \"button\" ) ? elem.form : undefined;\n\t\t\t\tif ( form && !jQuery._data( form, \"submitBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( form, \"submit._submit\", function( event ) {\n\t\t\t\t\t\tevent._submit_bubble = true;\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( form, \"submitBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t\t// return undefined since we don't need an event listener\n\t\t},\n\n\t\tpostDispatch: function( event ) {\n\t\t\t// If form was submitted by the user, bubble the event up the tree\n\t\t\tif ( event._submit_bubble ) {\n\t\t\t\tdelete event._submit_bubble;\n\t\t\t\tif ( this.parentNode && !event.isTrigger ) {\n\t\t\t\t\tjQuery.event.simulate( \"submit\", this.parentNode, event, true );\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\t// Only need this for delegated form submit events\n\t\t\tif ( jQuery.nodeName( this, \"form\" ) ) {\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\t// Remove delegated handlers; cleanData eventually reaps submit handlers attached above\n\t\t\tjQuery.event.remove( this, \"._submit\" );\n\t\t}\n\t};\n}\n\n// IE change delegation and checkbox/radio fix\nif ( !jQuery.support.changeBubbles ) {\n\n\tjQuery.event.special.change = {\n\n\t\tsetup: function() {\n\n\t\t\tif ( rformElems.test( this.nodeName ) ) {\n\t\t\t\t// IE doesn't fire change on a check/radio until blur; trigger it on click\n\t\t\t\t// after a propertychange. Eat the blur-change in special.change.handle.\n\t\t\t\t// This still fires onchange a second time for check/radio after blur.\n\t\t\t\tif ( this.type === \"checkbox\" || this.type === \"radio\" ) {\n\t\t\t\t\tjQuery.event.add( this, \"propertychange._change\", function( event ) {\n\t\t\t\t\t\tif ( event.originalEvent.propertyName === \"checked\" ) {\n\t\t\t\t\t\t\tthis._just_changed = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery.event.add( this, \"click._change\", function( event ) {\n\t\t\t\t\t\tif ( this._just_changed && !event.isTrigger ) {\n\t\t\t\t\t\t\tthis._just_changed = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Allow triggered, simulated change events (#11500)\n\t\t\t\t\t\tjQuery.event.simulate( \"change\", this, event, true );\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t// Delegated event; lazy-add a change handler on descendant inputs\n\t\t\tjQuery.event.add( this, \"beforeactivate._change\", function( e ) {\n\t\t\t\tvar elem = e.target;\n\n\t\t\t\tif ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, \"changeBubbles\" ) ) {\n\t\t\t\t\tjQuery.event.add( elem, \"change._change\", function( event ) {\n\t\t\t\t\t\tif ( this.parentNode && !event.isSimulated && !event.isTrigger ) {\n\t\t\t\t\t\t\tjQuery.event.simulate( \"change\", this.parentNode, event, true );\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t\tjQuery._data( elem, \"changeBubbles\", true );\n\t\t\t\t}\n\t\t\t});\n\t\t},\n\n\t\thandle: function( event ) {\n\t\t\tvar elem = event.target;\n\n\t\t\t// Swallow native change events from checkbox/radio, we already triggered them above\n\t\t\tif ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== \"radio\" && elem.type !== \"checkbox\") ) {\n\t\t\t\treturn event.handleObj.handler.apply( this, arguments );\n\t\t\t}\n\t\t},\n\n\t\tteardown: function() {\n\t\t\tjQuery.event.remove( this, \"._change\" );\n\n\t\t\treturn !rformElems.test( this.nodeName );\n\t\t}\n\t};\n}\n\n// Create \"bubbling\" focus and blur events\nif ( !jQuery.support.focusinBubbles ) {\n\tjQuery.each({ focus: \"focusin\", blur: \"focusout\" }, function( orig, fix ) {\n\n\t\t// Attach a single capturing handler while someone wants focusin/focusout\n\t\tvar attaches = 0,\n\t\t\thandler = function( event ) {\n\t\t\t\tjQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true );\n\t\t\t};\n\n\t\tjQuery.event.special[ fix ] = {\n\t\t\tsetup: function() {\n\t\t\t\tif ( attaches++ === 0 ) {\n\t\t\t\t\tdocument.addEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t},\n\t\t\tteardown: function() {\n\t\t\t\tif ( --attaches === 0 ) {\n\t\t\t\t\tdocument.removeEventListener( orig, handler, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t});\n}\n\njQuery.fn.extend({\n\n\ton: function( types, selector, data, fn, /*INTERNAL*/ one ) {\n\t\tvar type, origFn;\n\n\t\t// Types can be a map of types/handlers\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-Object, selector, data )\n\t\t\tif ( typeof selector !== \"string\" ) {\n\t\t\t\t// ( types-Object, data )\n\t\t\t\tdata = data || selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.on( type, selector, data, types[ type ], one );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( data == null && fn == null ) {\n\t\t\t// ( types, fn )\n\t\t\tfn = selector;\n\t\t\tdata = selector = undefined;\n\t\t} else if ( fn == null ) {\n\t\t\tif ( typeof selector === \"string\" ) {\n\t\t\t\t// ( types, selector, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = undefined;\n\t\t\t} else {\n\t\t\t\t// ( types, data, fn )\n\t\t\t\tfn = data;\n\t\t\t\tdata = selector;\n\t\t\t\tselector = undefined;\n\t\t\t}\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t} else if ( !fn ) {\n\t\t\treturn this;\n\t\t}\n\n\t\tif ( one === 1 ) {\n\t\t\torigFn = fn;\n\t\t\tfn = function( event ) {\n\t\t\t\t// Can use an empty set, since event contains the info\n\t\t\t\tjQuery().off( event );\n\t\t\t\treturn origFn.apply( this, arguments );\n\t\t\t};\n\t\t\t// Use same guid so caller can remove using origFn\n\t\t\tfn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );\n\t\t}\n\t\treturn this.each( function() {\n\t\t\tjQuery.event.add( this, types, fn, data, selector );\n\t\t});\n\t},\n\tone: function( types, selector, data, fn ) {\n\t\treturn this.on( types, selector, data, fn, 1 );\n\t},\n\toff: function( types, selector, fn ) {\n\t\tvar handleObj, type;\n\t\tif ( types && types.preventDefault && types.handleObj ) {\n\t\t\t// ( event )  dispatched jQuery.Event\n\t\t\thandleObj = types.handleObj;\n\t\t\tjQuery( types.delegateTarget ).off(\n\t\t\t\thandleObj.namespace ? handleObj.origType + \".\" + handleObj.namespace : handleObj.origType,\n\t\t\t\thandleObj.selector,\n\t\t\t\thandleObj.handler\n\t\t\t);\n\t\t\treturn this;\n\t\t}\n\t\tif ( typeof types === \"object\" ) {\n\t\t\t// ( types-object [, selector] )\n\t\t\tfor ( type in types ) {\n\t\t\t\tthis.off( type, selector, types[ type ] );\n\t\t\t}\n\t\t\treturn this;\n\t\t}\n\t\tif ( selector === false || typeof selector === \"function\" ) {\n\t\t\t// ( types [, fn] )\n\t\t\tfn = selector;\n\t\t\tselector = undefined;\n\t\t}\n\t\tif ( fn === false ) {\n\t\t\tfn = returnFalse;\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.remove( this, types, fn, selector );\n\t\t});\n\t},\n\n\ttrigger: function( type, data ) {\n\t\treturn this.each(function() {\n\t\t\tjQuery.event.trigger( type, data, this );\n\t\t});\n\t},\n\ttriggerHandler: function( type, data ) {\n\t\tvar elem = this[0];\n\t\tif ( elem ) {\n\t\t\treturn jQuery.event.trigger( type, data, elem, true );\n\t\t}\n\t}\n});\nvar isSimple = /^.[^:#\\[\\.,]*$/,\n\trparentsprev = /^(?:parents|prev(?:Until|All))/,\n\trneedsContext = jQuery.expr.match.needsContext,\n\t// methods guaranteed to produce a unique set when starting from a unique set\n\tguaranteedUnique = {\n\t\tchildren: true,\n\t\tcontents: true,\n\t\tnext: true,\n\t\tprev: true\n\t};\n\njQuery.fn.extend({\n\tfind: function( selector ) {\n\t\tvar i,\n\t\t\tret = [],\n\t\t\tself = this,\n\t\t\tlen = self.length;\n\n\t\tif ( typeof selector !== \"string\" ) {\n\t\t\treturn this.pushStack( jQuery( selector ).filter(function() {\n\t\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\t\tif ( jQuery.contains( self[ i ], this ) ) {\n\t\t\t\t\t\treturn true;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}) );\n\t\t}\n\n\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\tjQuery.find( selector, self[ i ], ret );\n\t\t}\n\n\t\t// Needed because $( selector, context ) becomes $( context ).find( selector )\n\t\tret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );\n\t\tret.selector = this.selector ? this.selector + \" \" + selector : selector;\n\t\treturn ret;\n\t},\n\n\thas: function( target ) {\n\t\tvar i,\n\t\t\ttargets = jQuery( target, this ),\n\t\t\tlen = targets.length;\n\n\t\treturn this.filter(function() {\n\t\t\tfor ( i = 0; i < len; i++ ) {\n\t\t\t\tif ( jQuery.contains( this, targets[i] ) ) {\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\t},\n\n\tnot: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], true) );\n\t},\n\n\tfilter: function( selector ) {\n\t\treturn this.pushStack( winnow(this, selector || [], false) );\n\t},\n\n\tis: function( selector ) {\n\t\treturn !!winnow(\n\t\t\tthis,\n\n\t\t\t// If this is a positional/relative selector, check membership in the returned set\n\t\t\t// so $(\"p:first\").is(\"p:last\") won't return true for a doc with two \"p\".\n\t\t\ttypeof selector === \"string\" && rneedsContext.test( selector ) ?\n\t\t\t\tjQuery( selector ) :\n\t\t\t\tselector || [],\n\t\t\tfalse\n\t\t).length;\n\t},\n\n\tclosest: function( selectors, context ) {\n\t\tvar cur,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tret = [],\n\t\t\tpos = rneedsContext.test( selectors ) || typeof selectors !== \"string\" ?\n\t\t\t\tjQuery( selectors, context || this.context ) :\n\t\t\t\t0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\tfor ( cur = this[i]; cur && cur !== context; cur = cur.parentNode ) {\n\t\t\t\t// Always skip document fragments\n\t\t\t\tif ( cur.nodeType < 11 && (pos ?\n\t\t\t\t\tpos.index(cur) > -1 :\n\n\t\t\t\t\t// Don't pass non-elements to Sizzle\n\t\t\t\t\tcur.nodeType === 1 &&\n\t\t\t\t\t\tjQuery.find.matchesSelector(cur, selectors)) ) {\n\n\t\t\t\t\tcur = ret.push( cur );\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );\n\t},\n\n\t// Determine the position of an element within\n\t// the matched set of elements\n\tindex: function( elem ) {\n\n\t\t// No argument, return index in parent\n\t\tif ( !elem ) {\n\t\t\treturn ( this[0] && this[0].parentNode ) ? this.first().prevAll().length : -1;\n\t\t}\n\n\t\t// index in selector\n\t\tif ( typeof elem === \"string\" ) {\n\t\t\treturn jQuery.inArray( this[0], jQuery( elem ) );\n\t\t}\n\n\t\t// Locate the position of the desired element\n\t\treturn jQuery.inArray(\n\t\t\t// If it receives a jQuery object, the first element is used\n\t\t\telem.jquery ? elem[0] : elem, this );\n\t},\n\n\tadd: function( selector, context ) {\n\t\tvar set = typeof selector === \"string\" ?\n\t\t\t\tjQuery( selector, context ) :\n\t\t\t\tjQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ),\n\t\t\tall = jQuery.merge( this.get(), set );\n\n\t\treturn this.pushStack( jQuery.unique(all) );\n\t},\n\n\taddBack: function( selector ) {\n\t\treturn this.add( selector == null ?\n\t\t\tthis.prevObject : this.prevObject.filter(selector)\n\t\t);\n\t}\n});\n\nfunction sibling( cur, dir ) {\n\tdo {\n\t\tcur = cur[ dir ];\n\t} while ( cur && cur.nodeType !== 1 );\n\n\treturn cur;\n}\n\njQuery.each({\n\tparent: function( elem ) {\n\t\tvar parent = elem.parentNode;\n\t\treturn parent && parent.nodeType !== 11 ? parent : null;\n\t},\n\tparents: function( elem ) {\n\t\treturn jQuery.dir( elem, \"parentNode\" );\n\t},\n\tparentsUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"parentNode\", until );\n\t},\n\tnext: function( elem ) {\n\t\treturn sibling( elem, \"nextSibling\" );\n\t},\n\tprev: function( elem ) {\n\t\treturn sibling( elem, \"previousSibling\" );\n\t},\n\tnextAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\" );\n\t},\n\tprevAll: function( elem ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\" );\n\t},\n\tnextUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"nextSibling\", until );\n\t},\n\tprevUntil: function( elem, i, until ) {\n\t\treturn jQuery.dir( elem, \"previousSibling\", until );\n\t},\n\tsiblings: function( elem ) {\n\t\treturn jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem );\n\t},\n\tchildren: function( elem ) {\n\t\treturn jQuery.sibling( elem.firstChild );\n\t},\n\tcontents: function( elem ) {\n\t\treturn jQuery.nodeName( elem, \"iframe\" ) ?\n\t\t\telem.contentDocument || elem.contentWindow.document :\n\t\t\tjQuery.merge( [], elem.childNodes );\n\t}\n}, function( name, fn ) {\n\tjQuery.fn[ name ] = function( until, selector ) {\n\t\tvar ret = jQuery.map( this, fn, until );\n\n\t\tif ( name.slice( -5 ) !== \"Until\" ) {\n\t\t\tselector = until;\n\t\t}\n\n\t\tif ( selector && typeof selector === \"string\" ) {\n\t\t\tret = jQuery.filter( selector, ret );\n\t\t}\n\n\t\tif ( this.length > 1 ) {\n\t\t\t// Remove duplicates\n\t\t\tif ( !guaranteedUnique[ name ] ) {\n\t\t\t\tret = jQuery.unique( ret );\n\t\t\t}\n\n\t\t\t// Reverse order for parents* and prev-derivatives\n\t\t\tif ( rparentsprev.test( name ) ) {\n\t\t\t\tret = ret.reverse();\n\t\t\t}\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\njQuery.extend({\n\tfilter: function( expr, elems, not ) {\n\t\tvar elem = elems[ 0 ];\n\n\t\tif ( not ) {\n\t\t\texpr = \":not(\" + expr + \")\";\n\t\t}\n\n\t\treturn elems.length === 1 && elem.nodeType === 1 ?\n\t\t\tjQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [] :\n\t\t\tjQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {\n\t\t\t\treturn elem.nodeType === 1;\n\t\t\t}));\n\t},\n\n\tdir: function( elem, dir, until ) {\n\t\tvar matched = [],\n\t\t\tcur = elem[ dir ];\n\n\t\twhile ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) {\n\t\t\tif ( cur.nodeType === 1 ) {\n\t\t\t\tmatched.push( cur );\n\t\t\t}\n\t\t\tcur = cur[dir];\n\t\t}\n\t\treturn matched;\n\t},\n\n\tsibling: function( n, elem ) {\n\t\tvar r = [];\n\n\t\tfor ( ; n; n = n.nextSibling ) {\n\t\t\tif ( n.nodeType === 1 && n !== elem ) {\n\t\t\t\tr.push( n );\n\t\t\t}\n\t\t}\n\n\t\treturn r;\n\t}\n});\n\n// Implement the identical functionality for filter and not\nfunction winnow( elements, qualifier, not ) {\n\tif ( jQuery.isFunction( qualifier ) ) {\n\t\treturn jQuery.grep( elements, function( elem, i ) {\n\t\t\t/* jshint -W018 */\n\t\t\treturn !!qualifier.call( elem, i, elem ) !== not;\n\t\t});\n\n\t}\n\n\tif ( qualifier.nodeType ) {\n\t\treturn jQuery.grep( elements, function( elem ) {\n\t\t\treturn ( elem === qualifier ) !== not;\n\t\t});\n\n\t}\n\n\tif ( typeof qualifier === \"string\" ) {\n\t\tif ( isSimple.test( qualifier ) ) {\n\t\t\treturn jQuery.filter( qualifier, elements, not );\n\t\t}\n\n\t\tqualifier = jQuery.filter( qualifier, elements );\n\t}\n\n\treturn jQuery.grep( elements, function( elem ) {\n\t\treturn ( jQuery.inArray( elem, qualifier ) >= 0 ) !== not;\n\t});\n}\nfunction createSafeFragment( document ) {\n\tvar list = nodeNames.split( \"|\" ),\n\t\tsafeFrag = document.createDocumentFragment();\n\n\tif ( safeFrag.createElement ) {\n\t\twhile ( list.length ) {\n\t\t\tsafeFrag.createElement(\n\t\t\t\tlist.pop()\n\t\t\t);\n\t\t}\n\t}\n\treturn safeFrag;\n}\n\nvar nodeNames = \"abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|\" +\n\t\t\"header|hgroup|mark|meter|nav|output|progress|section|summary|time|video\",\n\trinlinejQuery = / jQuery\\d+=\"(?:null|\\d+)\"/g,\n\trnoshimcache = new RegExp(\"<(?:\" + nodeNames + \")[\\\\s/>]\", \"i\"),\n\trleadingWhitespace = /^\\s+/,\n\trxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\\w:]+)[^>]*)\\/>/gi,\n\trtagName = /<([\\w:]+)/,\n\trtbody = /<tbody/i,\n\trhtml = /<|&#?\\w+;/,\n\trnoInnerhtml = /<(?:script|style|link)/i,\n\tmanipulation_rcheckableType = /^(?:checkbox|radio)$/i,\n\t// checked=\"checked\" or checked\n\trchecked = /checked\\s*(?:[^=]|=\\s*.checked.)/i,\n\trscriptType = /^$|\\/(?:java|ecma)script/i,\n\trscriptTypeMasked = /^true\\/(.*)/,\n\trcleanScript = /^\\s*<!(?:\\[CDATA\\[|--)|(?:\\]\\]|--)>\\s*$/g,\n\n\t// We have to close these tags to support XHTML (#13200)\n\twrapMap = {\n\t\toption: [ 1, \"<select multiple='multiple'>\", \"</select>\" ],\n\t\tlegend: [ 1, \"<fieldset>\", \"</fieldset>\" ],\n\t\tarea: [ 1, \"<map>\", \"</map>\" ],\n\t\tparam: [ 1, \"<object>\", \"</object>\" ],\n\t\tthead: [ 1, \"<table>\", \"</table>\" ],\n\t\ttr: [ 2, \"<table><tbody>\", \"</tbody></table>\" ],\n\t\tcol: [ 2, \"<table><tbody></tbody><colgroup>\", \"</colgroup></table>\" ],\n\t\ttd: [ 3, \"<table><tbody><tr>\", \"</tr></tbody></table>\" ],\n\n\t\t// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,\n\t\t// unless wrapped in a div with non-breaking characters in front of it.\n\t\t_default: jQuery.support.htmlSerialize ? [ 0, \"\", \"\" ] : [ 1, \"X<div>\", \"</div>\"  ]\n\t},\n\tsafeFragment = createSafeFragment( document ),\n\tfragmentDiv = safeFragment.appendChild( document.createElement(\"div\") );\n\nwrapMap.optgroup = wrapMap.option;\nwrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;\nwrapMap.th = wrapMap.td;\n\njQuery.fn.extend({\n\ttext: function( value ) {\n\t\treturn jQuery.access( this, function( value ) {\n\t\t\treturn value === undefined ?\n\t\t\t\tjQuery.text( this ) :\n\t\t\t\tthis.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );\n\t\t}, null, value, arguments.length );\n\t},\n\n\tappend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.appendChild( elem );\n\t\t\t}\n\t\t});\n\t},\n\n\tprepend: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {\n\t\t\t\tvar target = manipulationTarget( this, elem );\n\t\t\t\ttarget.insertBefore( elem, target.firstChild );\n\t\t\t}\n\t\t});\n\t},\n\n\tbefore: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this );\n\t\t\t}\n\t\t});\n\t},\n\n\tafter: function() {\n\t\treturn this.domManip( arguments, function( elem ) {\n\t\t\tif ( this.parentNode ) {\n\t\t\t\tthis.parentNode.insertBefore( elem, this.nextSibling );\n\t\t\t}\n\t\t});\n\t},\n\n\t// keepData is for internal use only--do not document\n\tremove: function( selector, keepData ) {\n\t\tvar elem,\n\t\t\telems = selector ? jQuery.filter( selector, this ) : this,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( !keepData && elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem ) );\n\t\t\t}\n\n\t\t\tif ( elem.parentNode ) {\n\t\t\t\tif ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\t\tsetGlobalEval( getAll( elem, \"script\" ) );\n\t\t\t\t}\n\t\t\t\telem.parentNode.removeChild( elem );\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tempty: function() {\n\t\tvar elem,\n\t\t\ti = 0;\n\n\t\tfor ( ; (elem = this[i]) != null; i++ ) {\n\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t}\n\n\t\t\t// Remove any remaining nodes\n\t\t\twhile ( elem.firstChild ) {\n\t\t\t\telem.removeChild( elem.firstChild );\n\t\t\t}\n\n\t\t\t// If this is a select, ensure that it displays empty (#12336)\n\t\t\t// Support: IE<9\n\t\t\tif ( elem.options && jQuery.nodeName( elem, \"select\" ) ) {\n\t\t\t\telem.options.length = 0;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t},\n\n\tclone: function( dataAndEvents, deepDataAndEvents ) {\n\t\tdataAndEvents = dataAndEvents == null ? false : dataAndEvents;\n\t\tdeepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;\n\n\t\treturn this.map( function () {\n\t\t\treturn jQuery.clone( this, dataAndEvents, deepDataAndEvents );\n\t\t});\n\t},\n\n\thtml: function( value ) {\n\t\treturn jQuery.access( this, function( value ) {\n\t\t\tvar elem = this[0] || {},\n\t\t\t\ti = 0,\n\t\t\t\tl = this.length;\n\n\t\t\tif ( value === undefined ) {\n\t\t\t\treturn elem.nodeType === 1 ?\n\t\t\t\t\telem.innerHTML.replace( rinlinejQuery, \"\" ) :\n\t\t\t\t\tundefined;\n\t\t\t}\n\n\t\t\t// See if we can take a shortcut and just use innerHTML\n\t\t\tif ( typeof value === \"string\" && !rnoInnerhtml.test( value ) &&\n\t\t\t\t( jQuery.support.htmlSerialize || !rnoshimcache.test( value )  ) &&\n\t\t\t\t( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) &&\n\t\t\t\t!wrapMap[ ( rtagName.exec( value ) || [\"\", \"\"] )[1].toLowerCase() ] ) {\n\n\t\t\t\tvalue = value.replace( rxhtmlTag, \"<$1></$2>\" );\n\n\t\t\t\ttry {\n\t\t\t\t\tfor (; i < l; i++ ) {\n\t\t\t\t\t\t// Remove element nodes and prevent memory leaks\n\t\t\t\t\t\telem = this[i] || {};\n\t\t\t\t\t\tif ( elem.nodeType === 1 ) {\n\t\t\t\t\t\t\tjQuery.cleanData( getAll( elem, false ) );\n\t\t\t\t\t\t\telem.innerHTML = value;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\telem = 0;\n\n\t\t\t\t// If using innerHTML throws an exception, use the fallback method\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t\tif ( elem ) {\n\t\t\t\tthis.empty().append( value );\n\t\t\t}\n\t\t}, null, value, arguments.length );\n\t},\n\n\treplaceWith: function() {\n\t\tvar\n\t\t\t// Snapshot the DOM in case .domManip sweeps something relevant into its fragment\n\t\t\targs = jQuery.map( this, function( elem ) {\n\t\t\t\treturn [ elem.nextSibling, elem.parentNode ];\n\t\t\t}),\n\t\t\ti = 0;\n\n\t\t// Make the changes, replacing each context element with the new content\n\t\tthis.domManip( arguments, function( elem ) {\n\t\t\tvar next = args[ i++ ],\n\t\t\t\tparent = args[ i++ ];\n\n\t\t\tif ( parent ) {\n\t\t\t\t// Don't use the snapshot next if it has moved (#13810)\n\t\t\t\tif ( next && next.parentNode !== parent ) {\n\t\t\t\t\tnext = this.nextSibling;\n\t\t\t\t}\n\t\t\t\tjQuery( this ).remove();\n\t\t\t\tparent.insertBefore( elem, next );\n\t\t\t}\n\t\t// Allow new content to include elements from the context set\n\t\t}, true );\n\n\t\t// Force removal if there was no new content (e.g., from empty arguments)\n\t\treturn i ? this : this.remove();\n\t},\n\n\tdetach: function( selector ) {\n\t\treturn this.remove( selector, true );\n\t},\n\n\tdomManip: function( args, callback, allowIntersection ) {\n\n\t\t// Flatten any nested arrays\n\t\targs = core_concat.apply( [], args );\n\n\t\tvar first, node, hasScripts,\n\t\t\tscripts, doc, fragment,\n\t\t\ti = 0,\n\t\t\tl = this.length,\n\t\t\tset = this,\n\t\t\tiNoClone = l - 1,\n\t\t\tvalue = args[0],\n\t\t\tisFunction = jQuery.isFunction( value );\n\n\t\t// We can't cloneNode fragments that contain checked, in WebKit\n\t\tif ( isFunction || !( l <= 1 || typeof value !== \"string\" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {\n\t\t\treturn this.each(function( index ) {\n\t\t\t\tvar self = set.eq( index );\n\t\t\t\tif ( isFunction ) {\n\t\t\t\t\targs[0] = value.call( this, index, self.html() );\n\t\t\t\t}\n\t\t\t\tself.domManip( args, callback, allowIntersection );\n\t\t\t});\n\t\t}\n\n\t\tif ( l ) {\n\t\t\tfragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, !allowIntersection && this );\n\t\t\tfirst = fragment.firstChild;\n\n\t\t\tif ( fragment.childNodes.length === 1 ) {\n\t\t\t\tfragment = first;\n\t\t\t}\n\n\t\t\tif ( first ) {\n\t\t\t\tscripts = jQuery.map( getAll( fragment, \"script\" ), disableScript );\n\t\t\t\thasScripts = scripts.length;\n\n\t\t\t\t// Use the original fragment for the last item instead of the first because it can end up\n\t\t\t\t// being emptied incorrectly in certain situations (#8070).\n\t\t\t\tfor ( ; i < l; i++ ) {\n\t\t\t\t\tnode = fragment;\n\n\t\t\t\t\tif ( i !== iNoClone ) {\n\t\t\t\t\t\tnode = jQuery.clone( node, true, true );\n\n\t\t\t\t\t\t// Keep references to cloned scripts for later restoration\n\t\t\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\t\t\tjQuery.merge( scripts, getAll( node, \"script\" ) );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tcallback.call( this[i], node, i );\n\t\t\t\t}\n\n\t\t\t\tif ( hasScripts ) {\n\t\t\t\t\tdoc = scripts[ scripts.length - 1 ].ownerDocument;\n\n\t\t\t\t\t// Reenable scripts\n\t\t\t\t\tjQuery.map( scripts, restoreScript );\n\n\t\t\t\t\t// Evaluate executable scripts on first document insertion\n\t\t\t\t\tfor ( i = 0; i < hasScripts; i++ ) {\n\t\t\t\t\t\tnode = scripts[ i ];\n\t\t\t\t\t\tif ( rscriptType.test( node.type || \"\" ) &&\n\t\t\t\t\t\t\t!jQuery._data( node, \"globalEval\" ) && jQuery.contains( doc, node ) ) {\n\n\t\t\t\t\t\t\tif ( node.src ) {\n\t\t\t\t\t\t\t\t// Hope ajax is available...\n\t\t\t\t\t\t\t\tjQuery._evalUrl( node.src );\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.globalEval( ( node.text || node.textContent || node.innerHTML || \"\" ).replace( rcleanScript, \"\" ) );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Fix #11809: Avoid leaking memory\n\t\t\t\tfragment = first = null;\n\t\t\t}\n\t\t}\n\n\t\treturn this;\n\t}\n});\n\n// Support: IE<8\n// Manipulating tables requires a tbody\nfunction manipulationTarget( elem, content ) {\n\treturn jQuery.nodeName( elem, \"table\" ) &&\n\t\tjQuery.nodeName( content.nodeType === 1 ? content : content.firstChild, \"tr\" ) ?\n\n\t\telem.getElementsByTagName(\"tbody\")[0] ||\n\t\t\telem.appendChild( elem.ownerDocument.createElement(\"tbody\") ) :\n\t\telem;\n}\n\n// Replace/restore the type attribute of script elements for safe DOM manipulation\nfunction disableScript( elem ) {\n\telem.type = (jQuery.find.attr( elem, \"type\" ) !== null) + \"/\" + elem.type;\n\treturn elem;\n}\nfunction restoreScript( elem ) {\n\tvar match = rscriptTypeMasked.exec( elem.type );\n\tif ( match ) {\n\t\telem.type = match[1];\n\t} else {\n\t\telem.removeAttribute(\"type\");\n\t}\n\treturn elem;\n}\n\n// Mark scripts as having already been evaluated\nfunction setGlobalEval( elems, refElements ) {\n\tvar elem,\n\t\ti = 0;\n\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\t\tjQuery._data( elem, \"globalEval\", !refElements || jQuery._data( refElements[i], \"globalEval\" ) );\n\t}\n}\n\nfunction cloneCopyEvent( src, dest ) {\n\n\tif ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) {\n\t\treturn;\n\t}\n\n\tvar type, i, l,\n\t\toldData = jQuery._data( src ),\n\t\tcurData = jQuery._data( dest, oldData ),\n\t\tevents = oldData.events;\n\n\tif ( events ) {\n\t\tdelete curData.handle;\n\t\tcurData.events = {};\n\n\t\tfor ( type in events ) {\n\t\t\tfor ( i = 0, l = events[ type ].length; i < l; i++ ) {\n\t\t\t\tjQuery.event.add( dest, type, events[ type ][ i ] );\n\t\t\t}\n\t\t}\n\t}\n\n\t// make the cloned public data object a copy from the original\n\tif ( curData.data ) {\n\t\tcurData.data = jQuery.extend( {}, curData.data );\n\t}\n}\n\nfunction fixCloneNodeIssues( src, dest ) {\n\tvar nodeName, e, data;\n\n\t// We do not need to do anything for non-Elements\n\tif ( dest.nodeType !== 1 ) {\n\t\treturn;\n\t}\n\n\tnodeName = dest.nodeName.toLowerCase();\n\n\t// IE6-8 copies events bound via attachEvent when using cloneNode.\n\tif ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) {\n\t\tdata = jQuery._data( dest );\n\n\t\tfor ( e in data.events ) {\n\t\t\tjQuery.removeEvent( dest, e, data.handle );\n\t\t}\n\n\t\t// Event data gets referenced instead of copied if the expando gets copied too\n\t\tdest.removeAttribute( jQuery.expando );\n\t}\n\n\t// IE blanks contents when cloning scripts, and tries to evaluate newly-set text\n\tif ( nodeName === \"script\" && dest.text !== src.text ) {\n\t\tdisableScript( dest ).text = src.text;\n\t\trestoreScript( dest );\n\n\t// IE6-10 improperly clones children of object elements using classid.\n\t// IE10 throws NoModificationAllowedError if parent is null, #12132.\n\t} else if ( nodeName === \"object\" ) {\n\t\tif ( dest.parentNode ) {\n\t\t\tdest.outerHTML = src.outerHTML;\n\t\t}\n\n\t\t// This path appears unavoidable for IE9. When cloning an object\n\t\t// element in IE9, the outerHTML strategy above is not sufficient.\n\t\t// If the src has innerHTML and the destination does not,\n\t\t// copy the src.innerHTML into the dest.innerHTML. #10324\n\t\tif ( jQuery.support.html5Clone && ( src.innerHTML && !jQuery.trim(dest.innerHTML) ) ) {\n\t\t\tdest.innerHTML = src.innerHTML;\n\t\t}\n\n\t} else if ( nodeName === \"input\" && manipulation_rcheckableType.test( src.type ) ) {\n\t\t// IE6-8 fails to persist the checked state of a cloned checkbox\n\t\t// or radio button. Worse, IE6-7 fail to give the cloned element\n\t\t// a checked appearance if the defaultChecked value isn't also set\n\n\t\tdest.defaultChecked = dest.checked = src.checked;\n\n\t\t// IE6-7 get confused and end up setting the value of a cloned\n\t\t// checkbox/radio button to an empty string instead of \"on\"\n\t\tif ( dest.value !== src.value ) {\n\t\t\tdest.value = src.value;\n\t\t}\n\n\t// IE6-8 fails to return the selected option to the default selected\n\t// state when cloning options\n\t} else if ( nodeName === \"option\" ) {\n\t\tdest.defaultSelected = dest.selected = src.defaultSelected;\n\n\t// IE6-8 fails to set the defaultValue to the correct value when\n\t// cloning other types of input fields\n\t} else if ( nodeName === \"input\" || nodeName === \"textarea\" ) {\n\t\tdest.defaultValue = src.defaultValue;\n\t}\n}\n\njQuery.each({\n\tappendTo: \"append\",\n\tprependTo: \"prepend\",\n\tinsertBefore: \"before\",\n\tinsertAfter: \"after\",\n\treplaceAll: \"replaceWith\"\n}, function( name, original ) {\n\tjQuery.fn[ name ] = function( selector ) {\n\t\tvar elems,\n\t\t\ti = 0,\n\t\t\tret = [],\n\t\t\tinsert = jQuery( selector ),\n\t\t\tlast = insert.length - 1;\n\n\t\tfor ( ; i <= last; i++ ) {\n\t\t\telems = i === last ? this : this.clone(true);\n\t\t\tjQuery( insert[i] )[ original ]( elems );\n\n\t\t\t// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()\n\t\t\tcore_push.apply( ret, elems.get() );\n\t\t}\n\n\t\treturn this.pushStack( ret );\n\t};\n});\n\nfunction getAll( context, tag ) {\n\tvar elems, elem,\n\t\ti = 0,\n\t\tfound = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || \"*\" ) :\n\t\t\ttypeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || \"*\" ) :\n\t\t\tundefined;\n\n\tif ( !found ) {\n\t\tfor ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {\n\t\t\tif ( !tag || jQuery.nodeName( elem, tag ) ) {\n\t\t\t\tfound.push( elem );\n\t\t\t} else {\n\t\t\t\tjQuery.merge( found, getAll( elem, tag ) );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn tag === undefined || tag && jQuery.nodeName( context, tag ) ?\n\t\tjQuery.merge( [ context ], found ) :\n\t\tfound;\n}\n\n// Used in buildFragment, fixes the defaultChecked property\nfunction fixDefaultChecked( elem ) {\n\tif ( manipulation_rcheckableType.test( elem.type ) ) {\n\t\telem.defaultChecked = elem.checked;\n\t}\n}\n\njQuery.extend({\n\tclone: function( elem, dataAndEvents, deepDataAndEvents ) {\n\t\tvar destElements, node, clone, i, srcElements,\n\t\t\tinPage = jQuery.contains( elem.ownerDocument, elem );\n\n\t\tif ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( \"<\" + elem.nodeName + \">\" ) ) {\n\t\t\tclone = elem.cloneNode( true );\n\n\t\t// IE<=8 does not properly clone detached, unknown element nodes\n\t\t} else {\n\t\t\tfragmentDiv.innerHTML = elem.outerHTML;\n\t\t\tfragmentDiv.removeChild( clone = fragmentDiv.firstChild );\n\t\t}\n\n\t\tif ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) &&\n\t\t\t\t(elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) {\n\n\t\t\t// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2\n\t\t\tdestElements = getAll( clone );\n\t\t\tsrcElements = getAll( elem );\n\n\t\t\t// Fix all IE cloning issues\n\t\t\tfor ( i = 0; (node = srcElements[i]) != null; ++i ) {\n\t\t\t\t// Ensure that the destination node is not null; Fixes #9587\n\t\t\t\tif ( destElements[i] ) {\n\t\t\t\t\tfixCloneNodeIssues( node, destElements[i] );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Copy the events from the original to the clone\n\t\tif ( dataAndEvents ) {\n\t\t\tif ( deepDataAndEvents ) {\n\t\t\t\tsrcElements = srcElements || getAll( elem );\n\t\t\t\tdestElements = destElements || getAll( clone );\n\n\t\t\t\tfor ( i = 0; (node = srcElements[i]) != null; i++ ) {\n\t\t\t\t\tcloneCopyEvent( node, destElements[i] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tcloneCopyEvent( elem, clone );\n\t\t\t}\n\t\t}\n\n\t\t// Preserve script evaluation history\n\t\tdestElements = getAll( clone, \"script\" );\n\t\tif ( destElements.length > 0 ) {\n\t\t\tsetGlobalEval( destElements, !inPage && getAll( elem, \"script\" ) );\n\t\t}\n\n\t\tdestElements = srcElements = node = null;\n\n\t\t// Return the cloned set\n\t\treturn clone;\n\t},\n\n\tbuildFragment: function( elems, context, scripts, selection ) {\n\t\tvar j, elem, contains,\n\t\t\ttmp, tag, tbody, wrap,\n\t\t\tl = elems.length,\n\n\t\t\t// Ensure a safe fragment\n\t\t\tsafe = createSafeFragment( context ),\n\n\t\t\tnodes = [],\n\t\t\ti = 0;\n\n\t\tfor ( ; i < l; i++ ) {\n\t\t\telem = elems[ i ];\n\n\t\t\tif ( elem || elem === 0 ) {\n\n\t\t\t\t// Add nodes directly\n\t\t\t\tif ( jQuery.type( elem ) === \"object\" ) {\n\t\t\t\t\tjQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );\n\n\t\t\t\t// Convert non-html into a text node\n\t\t\t\t} else if ( !rhtml.test( elem ) ) {\n\t\t\t\t\tnodes.push( context.createTextNode( elem ) );\n\n\t\t\t\t// Convert html into DOM nodes\n\t\t\t\t} else {\n\t\t\t\t\ttmp = tmp || safe.appendChild( context.createElement(\"div\") );\n\n\t\t\t\t\t// Deserialize a standard representation\n\t\t\t\t\ttag = ( rtagName.exec( elem ) || [\"\", \"\"] )[1].toLowerCase();\n\t\t\t\t\twrap = wrapMap[ tag ] || wrapMap._default;\n\n\t\t\t\t\ttmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, \"<$1></$2>\" ) + wrap[2];\n\n\t\t\t\t\t// Descend through wrappers to the right content\n\t\t\t\t\tj = wrap[0];\n\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\ttmp = tmp.lastChild;\n\t\t\t\t\t}\n\n\t\t\t\t\t// Manually add leading whitespace removed by IE\n\t\t\t\t\tif ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {\n\t\t\t\t\t\tnodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove IE's autoinserted <tbody> from table fragments\n\t\t\t\t\tif ( !jQuery.support.tbody ) {\n\n\t\t\t\t\t\t// String was a <table>, *may* have spurious <tbody>\n\t\t\t\t\t\telem = tag === \"table\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\ttmp.firstChild :\n\n\t\t\t\t\t\t\t// String was a bare <thead> or <tfoot>\n\t\t\t\t\t\t\twrap[1] === \"<table>\" && !rtbody.test( elem ) ?\n\t\t\t\t\t\t\t\ttmp :\n\t\t\t\t\t\t\t\t0;\n\n\t\t\t\t\t\tj = elem && elem.childNodes.length;\n\t\t\t\t\t\twhile ( j-- ) {\n\t\t\t\t\t\t\tif ( jQuery.nodeName( (tbody = elem.childNodes[j]), \"tbody\" ) && !tbody.childNodes.length ) {\n\t\t\t\t\t\t\t\telem.removeChild( tbody );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tjQuery.merge( nodes, tmp.childNodes );\n\n\t\t\t\t\t// Fix #12392 for WebKit and IE > 9\n\t\t\t\t\ttmp.textContent = \"\";\n\n\t\t\t\t\t// Fix #12392 for oldIE\n\t\t\t\t\twhile ( tmp.firstChild ) {\n\t\t\t\t\t\ttmp.removeChild( tmp.firstChild );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remember the top-level container for proper cleanup\n\t\t\t\t\ttmp = safe.lastChild;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Fix #11356: Clear elements from fragment\n\t\tif ( tmp ) {\n\t\t\tsafe.removeChild( tmp );\n\t\t}\n\n\t\t// Reset defaultChecked for any radios and checkboxes\n\t\t// about to be appended to the DOM in IE 6/7 (#8060)\n\t\tif ( !jQuery.support.appendChecked ) {\n\t\t\tjQuery.grep( getAll( nodes, \"input\" ), fixDefaultChecked );\n\t\t}\n\n\t\ti = 0;\n\t\twhile ( (elem = nodes[ i++ ]) ) {\n\n\t\t\t// #4087 - If origin and destination elements are the same, and this is\n\t\t\t// that element, do not do anything\n\t\t\tif ( selection && jQuery.inArray( elem, selection ) !== -1 ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tcontains = jQuery.contains( elem.ownerDocument, elem );\n\n\t\t\t// Append to fragment\n\t\t\ttmp = getAll( safe.appendChild( elem ), \"script\" );\n\n\t\t\t// Preserve script evaluation history\n\t\t\tif ( contains ) {\n\t\t\t\tsetGlobalEval( tmp );\n\t\t\t}\n\n\t\t\t// Capture executables\n\t\t\tif ( scripts ) {\n\t\t\t\tj = 0;\n\t\t\t\twhile ( (elem = tmp[ j++ ]) ) {\n\t\t\t\t\tif ( rscriptType.test( elem.type || \"\" ) ) {\n\t\t\t\t\t\tscripts.push( elem );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\ttmp = null;\n\n\t\treturn safe;\n\t},\n\n\tcleanData: function( elems, /* internal */ acceptData ) {\n\t\tvar elem, type, id, data,\n\t\t\ti = 0,\n\t\t\tinternalKey = jQuery.expando,\n\t\t\tcache = jQuery.cache,\n\t\t\tdeleteExpando = jQuery.support.deleteExpando,\n\t\t\tspecial = jQuery.event.special;\n\n\t\tfor ( ; (elem = elems[i]) != null; i++ ) {\n\n\t\t\tif ( acceptData || jQuery.acceptData( elem ) ) {\n\n\t\t\t\tid = elem[ internalKey ];\n\t\t\t\tdata = id && cache[ id ];\n\n\t\t\t\tif ( data ) {\n\t\t\t\t\tif ( data.events ) {\n\t\t\t\t\t\tfor ( type in data.events ) {\n\t\t\t\t\t\t\tif ( special[ type ] ) {\n\t\t\t\t\t\t\t\tjQuery.event.remove( elem, type );\n\n\t\t\t\t\t\t\t// This is a shortcut to avoid jQuery.event.remove's overhead\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\tjQuery.removeEvent( elem, type, data.handle );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Remove cache only if it was not already removed by jQuery.event.remove\n\t\t\t\t\tif ( cache[ id ] ) {\n\n\t\t\t\t\t\tdelete cache[ id ];\n\n\t\t\t\t\t\t// IE does not allow us to delete expando properties from nodes,\n\t\t\t\t\t\t// nor does it have a removeAttribute function on Document nodes;\n\t\t\t\t\t\t// we must handle all of these cases\n\t\t\t\t\t\tif ( deleteExpando ) {\n\t\t\t\t\t\t\tdelete elem[ internalKey ];\n\n\t\t\t\t\t\t} else if ( typeof elem.removeAttribute !== core_strundefined ) {\n\t\t\t\t\t\t\telem.removeAttribute( internalKey );\n\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\telem[ internalKey ] = null;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tcore_deletedIds.push( id );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t_evalUrl: function( url ) {\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: \"GET\",\n\t\t\tdataType: \"script\",\n\t\t\tasync: false,\n\t\t\tglobal: false,\n\t\t\t\"throws\": true\n\t\t});\n\t}\n});\njQuery.fn.extend({\n\twrapAll: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapAll( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\tif ( this[0] ) {\n\t\t\t// The elements to wrap the target around\n\t\t\tvar wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true);\n\n\t\t\tif ( this[0].parentNode ) {\n\t\t\t\twrap.insertBefore( this[0] );\n\t\t\t}\n\n\t\t\twrap.map(function() {\n\t\t\t\tvar elem = this;\n\n\t\t\t\twhile ( elem.firstChild && elem.firstChild.nodeType === 1 ) {\n\t\t\t\t\telem = elem.firstChild;\n\t\t\t\t}\n\n\t\t\t\treturn elem;\n\t\t\t}).append( this );\n\t\t}\n\n\t\treturn this;\n\t},\n\n\twrapInner: function( html ) {\n\t\tif ( jQuery.isFunction( html ) ) {\n\t\t\treturn this.each(function(i) {\n\t\t\t\tjQuery(this).wrapInner( html.call(this, i) );\n\t\t\t});\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar self = jQuery( this ),\n\t\t\t\tcontents = self.contents();\n\n\t\t\tif ( contents.length ) {\n\t\t\t\tcontents.wrapAll( html );\n\n\t\t\t} else {\n\t\t\t\tself.append( html );\n\t\t\t}\n\t\t});\n\t},\n\n\twrap: function( html ) {\n\t\tvar isFunction = jQuery.isFunction( html );\n\n\t\treturn this.each(function(i) {\n\t\t\tjQuery( this ).wrapAll( isFunction ? html.call(this, i) : html );\n\t\t});\n\t},\n\n\tunwrap: function() {\n\t\treturn this.parent().each(function() {\n\t\t\tif ( !jQuery.nodeName( this, \"body\" ) ) {\n\t\t\t\tjQuery( this ).replaceWith( this.childNodes );\n\t\t\t}\n\t\t}).end();\n\t}\n});\nvar iframe, getStyles, curCSS,\n\tralpha = /alpha\\([^)]*\\)/i,\n\tropacity = /opacity\\s*=\\s*([^)]*)/,\n\trposition = /^(top|right|bottom|left)$/,\n\t// swappable if display is none or starts with table except \"table\", \"table-cell\", or \"table-caption\"\n\t// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display\n\trdisplayswap = /^(none|table(?!-c[ea]).+)/,\n\trmargin = /^margin/,\n\trnumsplit = new RegExp( \"^(\" + core_pnum + \")(.*)$\", \"i\" ),\n\trnumnonpx = new RegExp( \"^(\" + core_pnum + \")(?!px)[a-z%]+$\", \"i\" ),\n\trrelNum = new RegExp( \"^([+-])=(\" + core_pnum + \")\", \"i\" ),\n\telemdisplay = { BODY: \"block\" },\n\n\tcssShow = { position: \"absolute\", visibility: \"hidden\", display: \"block\" },\n\tcssNormalTransform = {\n\t\tletterSpacing: 0,\n\t\tfontWeight: 400\n\t},\n\n\tcssExpand = [ \"Top\", \"Right\", \"Bottom\", \"Left\" ],\n\tcssPrefixes = [ \"Webkit\", \"O\", \"Moz\", \"ms\" ];\n\n// return a css property mapped to a potentially vendor prefixed property\nfunction vendorPropName( style, name ) {\n\n\t// shortcut for names that are not vendor prefixed\n\tif ( name in style ) {\n\t\treturn name;\n\t}\n\n\t// check for vendor prefixed names\n\tvar capName = name.charAt(0).toUpperCase() + name.slice(1),\n\t\torigName = name,\n\t\ti = cssPrefixes.length;\n\n\twhile ( i-- ) {\n\t\tname = cssPrefixes[ i ] + capName;\n\t\tif ( name in style ) {\n\t\t\treturn name;\n\t\t}\n\t}\n\n\treturn origName;\n}\n\nfunction isHidden( elem, el ) {\n\t// isHidden might be called from jQuery#filter function;\n\t// in that case, element will be second argument\n\telem = el || elem;\n\treturn jQuery.css( elem, \"display\" ) === \"none\" || !jQuery.contains( elem.ownerDocument, elem );\n}\n\nfunction showHide( elements, show ) {\n\tvar display, elem, hidden,\n\t\tvalues = [],\n\t\tindex = 0,\n\t\tlength = elements.length;\n\n\tfor ( ; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\n\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\" );\n\t\tdisplay = elem.style.display;\n\t\tif ( show ) {\n\t\t\t// Reset the inline display of this element to learn if it is\n\t\t\t// being hidden by cascaded rules or not\n\t\t\tif ( !values[ index ] && display === \"none\" ) {\n\t\t\t\telem.style.display = \"\";\n\t\t\t}\n\n\t\t\t// Set elements which have been overridden with display: none\n\t\t\t// in a stylesheet to whatever the default browser style is\n\t\t\t// for such an element\n\t\t\tif ( elem.style.display === \"\" && isHidden( elem ) ) {\n\t\t\t\tvalues[ index ] = jQuery._data( elem, \"olddisplay\", css_defaultDisplay(elem.nodeName) );\n\t\t\t}\n\t\t} else {\n\n\t\t\tif ( !values[ index ] ) {\n\t\t\t\thidden = isHidden( elem );\n\n\t\t\t\tif ( display && display !== \"none\" || !hidden ) {\n\t\t\t\t\tjQuery._data( elem, \"olddisplay\", hidden ? display : jQuery.css( elem, \"display\" ) );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t// Set the display of most of the elements in a second loop\n\t// to avoid the constant reflow\n\tfor ( index = 0; index < length; index++ ) {\n\t\telem = elements[ index ];\n\t\tif ( !elem.style ) {\n\t\t\tcontinue;\n\t\t}\n\t\tif ( !show || elem.style.display === \"none\" || elem.style.display === \"\" ) {\n\t\t\telem.style.display = show ? values[ index ] || \"\" : \"none\";\n\t\t}\n\t}\n\n\treturn elements;\n}\n\njQuery.fn.extend({\n\tcss: function( name, value ) {\n\t\treturn jQuery.access( this, function( elem, name, value ) {\n\t\t\tvar len, styles,\n\t\t\t\tmap = {},\n\t\t\t\ti = 0;\n\n\t\t\tif ( jQuery.isArray( name ) ) {\n\t\t\t\tstyles = getStyles( elem );\n\t\t\t\tlen = name.length;\n\n\t\t\t\tfor ( ; i < len; i++ ) {\n\t\t\t\t\tmap[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );\n\t\t\t\t}\n\n\t\t\t\treturn map;\n\t\t\t}\n\n\t\t\treturn value !== undefined ?\n\t\t\t\tjQuery.style( elem, name, value ) :\n\t\t\t\tjQuery.css( elem, name );\n\t\t}, name, value, arguments.length > 1 );\n\t},\n\tshow: function() {\n\t\treturn showHide( this, true );\n\t},\n\thide: function() {\n\t\treturn showHide( this );\n\t},\n\ttoggle: function( state ) {\n\t\tif ( typeof state === \"boolean\" ) {\n\t\t\treturn state ? this.show() : this.hide();\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tif ( isHidden( this ) ) {\n\t\t\t\tjQuery( this ).show();\n\t\t\t} else {\n\t\t\t\tjQuery( this ).hide();\n\t\t\t}\n\t\t});\n\t}\n});\n\njQuery.extend({\n\t// Add in style property hooks for overriding the default\n\t// behavior of getting and setting a style property\n\tcssHooks: {\n\t\topacity: {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// We should always get a number back from opacity\n\t\t\t\t\tvar ret = curCSS( elem, \"opacity\" );\n\t\t\t\t\treturn ret === \"\" ? \"1\" : ret;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t},\n\n\t// Don't automatically add \"px\" to these possibly-unitless properties\n\tcssNumber: {\n\t\t\"columnCount\": true,\n\t\t\"fillOpacity\": true,\n\t\t\"fontWeight\": true,\n\t\t\"lineHeight\": true,\n\t\t\"opacity\": true,\n\t\t\"order\": true,\n\t\t\"orphans\": true,\n\t\t\"widows\": true,\n\t\t\"zIndex\": true,\n\t\t\"zoom\": true\n\t},\n\n\t// Add in properties whose names you wish to fix before\n\t// setting or getting the value\n\tcssProps: {\n\t\t// normalize float css property\n\t\t\"float\": jQuery.support.cssFloat ? \"cssFloat\" : \"styleFloat\"\n\t},\n\n\t// Get and set the style property on a DOM Node\n\tstyle: function( elem, name, value, extra ) {\n\t\t// Don't set styles on text and comment nodes\n\t\tif ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Make sure that we're working with the right name\n\t\tvar ret, type, hooks,\n\t\t\torigName = jQuery.camelCase( name ),\n\t\t\tstyle = elem.style;\n\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// Check if we're setting a value\n\t\tif ( value !== undefined ) {\n\t\t\ttype = typeof value;\n\n\t\t\t// convert relative number strings (+= or -=) to relative numbers. #7345\n\t\t\tif ( type === \"string\" && (ret = rrelNum.exec( value )) ) {\n\t\t\t\tvalue = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) );\n\t\t\t\t// Fixes bug #9237\n\t\t\t\ttype = \"number\";\n\t\t\t}\n\n\t\t\t// Make sure that NaN and null values aren't set. See: #7116\n\t\t\tif ( value == null || type === \"number\" && isNaN( value ) ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// If a number was passed in, add 'px' to the (except for certain CSS properties)\n\t\t\tif ( type === \"number\" && !jQuery.cssNumber[ origName ] ) {\n\t\t\t\tvalue += \"px\";\n\t\t\t}\n\n\t\t\t// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,\n\t\t\t// but it would mean to define eight (for every problematic property) identical functions\n\t\t\tif ( !jQuery.support.clearCloneStyle && value === \"\" && name.indexOf(\"background\") === 0 ) {\n\t\t\t\tstyle[ name ] = \"inherit\";\n\t\t\t}\n\n\t\t\t// If a hook was provided, use that value, otherwise just set the specified value\n\t\t\tif ( !hooks || !(\"set\" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) {\n\n\t\t\t\t// Wrapped to prevent IE from throwing errors when 'invalid' values are provided\n\t\t\t\t// Fixes bug #5509\n\t\t\t\ttry {\n\t\t\t\t\tstyle[ name ] = value;\n\t\t\t\t} catch(e) {}\n\t\t\t}\n\n\t\t} else {\n\t\t\t// If a hook was provided get the non-computed value from there\n\t\t\tif ( hooks && \"get\" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) {\n\t\t\t\treturn ret;\n\t\t\t}\n\n\t\t\t// Otherwise just get the value from the style object\n\t\t\treturn style[ name ];\n\t\t}\n\t},\n\n\tcss: function( elem, name, extra, styles ) {\n\t\tvar num, val, hooks,\n\t\t\torigName = jQuery.camelCase( name );\n\n\t\t// Make sure that we're working with the right name\n\t\tname = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) );\n\n\t\t// gets hook for the prefixed version\n\t\t// followed by the unprefixed version\n\t\thooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];\n\n\t\t// If a hook was provided get the computed value from there\n\t\tif ( hooks && \"get\" in hooks ) {\n\t\t\tval = hooks.get( elem, true, extra );\n\t\t}\n\n\t\t// Otherwise, if a way to get the computed value exists, use that\n\t\tif ( val === undefined ) {\n\t\t\tval = curCSS( elem, name, styles );\n\t\t}\n\n\t\t//convert \"normal\" to computed value\n\t\tif ( val === \"normal\" && name in cssNormalTransform ) {\n\t\t\tval = cssNormalTransform[ name ];\n\t\t}\n\n\t\t// Return, converting to number if forced or a qualifier was provided and val looks numeric\n\t\tif ( extra === \"\" || extra ) {\n\t\t\tnum = parseFloat( val );\n\t\t\treturn extra === true || jQuery.isNumeric( num ) ? num || 0 : val;\n\t\t}\n\t\treturn val;\n\t}\n});\n\n// NOTE: we've included the \"window\" in window.getComputedStyle\n// because jsdom on node.js will break without it.\nif ( window.getComputedStyle ) {\n\tgetStyles = function( elem ) {\n\t\treturn window.getComputedStyle( elem, null );\n\t};\n\n\tcurCSS = function( elem, name, _computed ) {\n\t\tvar width, minWidth, maxWidth,\n\t\t\tcomputed = _computed || getStyles( elem ),\n\n\t\t\t// getPropertyValue is only needed for .css('filter') in IE9, see #12537\n\t\t\tret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,\n\t\t\tstyle = elem.style;\n\n\t\tif ( computed ) {\n\n\t\t\tif ( ret === \"\" && !jQuery.contains( elem.ownerDocument, elem ) ) {\n\t\t\t\tret = jQuery.style( elem, name );\n\t\t\t}\n\n\t\t\t// A tribute to the \"awesome hack by Dean Edwards\"\n\t\t\t// Chrome < 17 and Safari 5.0 uses \"computed value\" instead of \"used value\" for margin-right\n\t\t\t// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels\n\t\t\t// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values\n\t\t\tif ( rnumnonpx.test( ret ) && rmargin.test( name ) ) {\n\n\t\t\t\t// Remember the original values\n\t\t\t\twidth = style.width;\n\t\t\t\tminWidth = style.minWidth;\n\t\t\t\tmaxWidth = style.maxWidth;\n\n\t\t\t\t// Put in the new values to get a computed value out\n\t\t\t\tstyle.minWidth = style.maxWidth = style.width = ret;\n\t\t\t\tret = computed.width;\n\n\t\t\t\t// Revert the changed values\n\t\t\t\tstyle.width = width;\n\t\t\t\tstyle.minWidth = minWidth;\n\t\t\t\tstyle.maxWidth = maxWidth;\n\t\t\t}\n\t\t}\n\n\t\treturn ret;\n\t};\n} else if ( document.documentElement.currentStyle ) {\n\tgetStyles = function( elem ) {\n\t\treturn elem.currentStyle;\n\t};\n\n\tcurCSS = function( elem, name, _computed ) {\n\t\tvar left, rs, rsLeft,\n\t\t\tcomputed = _computed || getStyles( elem ),\n\t\t\tret = computed ? computed[ name ] : undefined,\n\t\t\tstyle = elem.style;\n\n\t\t// Avoid setting ret to empty string here\n\t\t// so we don't default to auto\n\t\tif ( ret == null && style && style[ name ] ) {\n\t\t\tret = style[ name ];\n\t\t}\n\n\t\t// From the awesome hack by Dean Edwards\n\t\t// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291\n\n\t\t// If we're not dealing with a regular pixel number\n\t\t// but a number that has a weird ending, we need to convert it to pixels\n\t\t// but not position css attributes, as those are proportional to the parent element instead\n\t\t// and we can't measure the parent instead because it might trigger a \"stacking dolls\" problem\n\t\tif ( rnumnonpx.test( ret ) && !rposition.test( name ) ) {\n\n\t\t\t// Remember the original values\n\t\t\tleft = style.left;\n\t\t\trs = elem.runtimeStyle;\n\t\t\trsLeft = rs && rs.left;\n\n\t\t\t// Put in the new values to get a computed value out\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = elem.currentStyle.left;\n\t\t\t}\n\t\t\tstyle.left = name === \"fontSize\" ? \"1em\" : ret;\n\t\t\tret = style.pixelLeft + \"px\";\n\n\t\t\t// Revert the changed values\n\t\t\tstyle.left = left;\n\t\t\tif ( rsLeft ) {\n\t\t\t\trs.left = rsLeft;\n\t\t\t}\n\t\t}\n\n\t\treturn ret === \"\" ? \"auto\" : ret;\n\t};\n}\n\nfunction setPositiveNumber( elem, value, subtract ) {\n\tvar matches = rnumsplit.exec( value );\n\treturn matches ?\n\t\t// Guard against undefined \"subtract\", e.g., when used as in cssHooks\n\t\tMath.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || \"px\" ) :\n\t\tvalue;\n}\n\nfunction augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {\n\tvar i = extra === ( isBorderBox ? \"border\" : \"content\" ) ?\n\t\t// If we already have the right measurement, avoid augmentation\n\t\t4 :\n\t\t// Otherwise initialize for horizontal or vertical properties\n\t\tname === \"width\" ? 1 : 0,\n\n\t\tval = 0;\n\n\tfor ( ; i < 4; i += 2 ) {\n\t\t// both box models exclude margin, so add it if we want it\n\t\tif ( extra === \"margin\" ) {\n\t\t\tval += jQuery.css( elem, extra + cssExpand[ i ], true, styles );\n\t\t}\n\n\t\tif ( isBorderBox ) {\n\t\t\t// border-box includes padding, so remove it if we want content\n\t\t\tif ( extra === \"content\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\t\t\t}\n\n\t\t\t// at this point, extra isn't border nor margin, so remove border\n\t\t\tif ( extra !== \"margin\" ) {\n\t\t\t\tval -= jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t} else {\n\t\t\t// at this point, extra isn't content, so add padding\n\t\t\tval += jQuery.css( elem, \"padding\" + cssExpand[ i ], true, styles );\n\n\t\t\t// at this point, extra isn't content nor padding, so add border\n\t\t\tif ( extra !== \"padding\" ) {\n\t\t\t\tval += jQuery.css( elem, \"border\" + cssExpand[ i ] + \"Width\", true, styles );\n\t\t\t}\n\t\t}\n\t}\n\n\treturn val;\n}\n\nfunction getWidthOrHeight( elem, name, extra ) {\n\n\t// Start with offset property, which is equivalent to the border-box value\n\tvar valueIsBorderBox = true,\n\t\tval = name === \"width\" ? elem.offsetWidth : elem.offsetHeight,\n\t\tstyles = getStyles( elem ),\n\t\tisBorderBox = jQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\";\n\n\t// some non-html elements return undefined for offsetWidth, so check for null/undefined\n\t// svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285\n\t// MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668\n\tif ( val <= 0 || val == null ) {\n\t\t// Fall back to computed then uncomputed css if necessary\n\t\tval = curCSS( elem, name, styles );\n\t\tif ( val < 0 || val == null ) {\n\t\t\tval = elem.style[ name ];\n\t\t}\n\n\t\t// Computed unit is not pixels. Stop here and return.\n\t\tif ( rnumnonpx.test(val) ) {\n\t\t\treturn val;\n\t\t}\n\n\t\t// we need the check for style in case a browser which returns unreliable values\n\t\t// for getComputedStyle silently falls back to the reliable elem.style\n\t\tvalueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] );\n\n\t\t// Normalize \"\", auto, and prepare for extra\n\t\tval = parseFloat( val ) || 0;\n\t}\n\n\t// use the active box-sizing model to add/subtract irrelevant styles\n\treturn ( val +\n\t\taugmentWidthOrHeight(\n\t\t\telem,\n\t\t\tname,\n\t\t\textra || ( isBorderBox ? \"border\" : \"content\" ),\n\t\t\tvalueIsBorderBox,\n\t\t\tstyles\n\t\t)\n\t) + \"px\";\n}\n\n// Try to determine the default display value of an element\nfunction css_defaultDisplay( nodeName ) {\n\tvar doc = document,\n\t\tdisplay = elemdisplay[ nodeName ];\n\n\tif ( !display ) {\n\t\tdisplay = actualDisplay( nodeName, doc );\n\n\t\t// If the simple way fails, read from inside an iframe\n\t\tif ( display === \"none\" || !display ) {\n\t\t\t// Use the already-created iframe if possible\n\t\t\tiframe = ( iframe ||\n\t\t\t\tjQuery(\"<iframe frameborder='0' width='0' height='0'/>\")\n\t\t\t\t.css( \"cssText\", \"display:block !important\" )\n\t\t\t).appendTo( doc.documentElement );\n\n\t\t\t// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse\n\t\t\tdoc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;\n\t\t\tdoc.write(\"<!doctype html><html><body>\");\n\t\t\tdoc.close();\n\n\t\t\tdisplay = actualDisplay( nodeName, doc );\n\t\t\tiframe.detach();\n\t\t}\n\n\t\t// Store the correct default display\n\t\telemdisplay[ nodeName ] = display;\n\t}\n\n\treturn display;\n}\n\n// Called ONLY from within css_defaultDisplay\nfunction actualDisplay( name, doc ) {\n\tvar elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),\n\t\tdisplay = jQuery.css( elem[0], \"display\" );\n\telem.remove();\n\treturn display;\n}\n\njQuery.each([ \"height\", \"width\" ], function( i, name ) {\n\tjQuery.cssHooks[ name ] = {\n\t\tget: function( elem, computed, extra ) {\n\t\t\tif ( computed ) {\n\t\t\t\t// certain elements can have dimension info if we invisibly show them\n\t\t\t\t// however, it must have a current display style that would benefit from this\n\t\t\t\treturn elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, \"display\" ) ) ?\n\t\t\t\t\tjQuery.swap( elem, cssShow, function() {\n\t\t\t\t\t\treturn getWidthOrHeight( elem, name, extra );\n\t\t\t\t\t}) :\n\t\t\t\t\tgetWidthOrHeight( elem, name, extra );\n\t\t\t}\n\t\t},\n\n\t\tset: function( elem, value, extra ) {\n\t\t\tvar styles = extra && getStyles( elem );\n\t\t\treturn setPositiveNumber( elem, value, extra ?\n\t\t\t\taugmentWidthOrHeight(\n\t\t\t\t\telem,\n\t\t\t\t\tname,\n\t\t\t\t\textra,\n\t\t\t\t\tjQuery.support.boxSizing && jQuery.css( elem, \"boxSizing\", false, styles ) === \"border-box\",\n\t\t\t\t\tstyles\n\t\t\t\t) : 0\n\t\t\t);\n\t\t}\n\t};\n});\n\nif ( !jQuery.support.opacity ) {\n\tjQuery.cssHooks.opacity = {\n\t\tget: function( elem, computed ) {\n\t\t\t// IE uses filters for opacity\n\t\t\treturn ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || \"\" ) ?\n\t\t\t\t( 0.01 * parseFloat( RegExp.$1 ) ) + \"\" :\n\t\t\t\tcomputed ? \"1\" : \"\";\n\t\t},\n\n\t\tset: function( elem, value ) {\n\t\t\tvar style = elem.style,\n\t\t\t\tcurrentStyle = elem.currentStyle,\n\t\t\t\topacity = jQuery.isNumeric( value ) ? \"alpha(opacity=\" + value * 100 + \")\" : \"\",\n\t\t\t\tfilter = currentStyle && currentStyle.filter || style.filter || \"\";\n\n\t\t\t// IE has trouble with opacity if it does not have layout\n\t\t\t// Force it by setting the zoom level\n\t\t\tstyle.zoom = 1;\n\n\t\t\t// if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652\n\t\t\t// if value === \"\", then remove inline opacity #12685\n\t\t\tif ( ( value >= 1 || value === \"\" ) &&\n\t\t\t\t\tjQuery.trim( filter.replace( ralpha, \"\" ) ) === \"\" &&\n\t\t\t\t\tstyle.removeAttribute ) {\n\n\t\t\t\t// Setting style.filter to null, \"\" & \" \" still leave \"filter:\" in the cssText\n\t\t\t\t// if \"filter:\" is present at all, clearType is disabled, we want to avoid this\n\t\t\t\t// style.removeAttribute is IE Only, but so apparently is this code path...\n\t\t\t\tstyle.removeAttribute( \"filter\" );\n\n\t\t\t\t// if there is no filter style applied in a css rule or unset inline opacity, we are done\n\t\t\t\tif ( value === \"\" || currentStyle && !currentStyle.filter ) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// otherwise, set new filter values\n\t\t\tstyle.filter = ralpha.test( filter ) ?\n\t\t\t\tfilter.replace( ralpha, opacity ) :\n\t\t\t\tfilter + \" \" + opacity;\n\t\t}\n\t};\n}\n\n// These hooks cannot be added until DOM ready because the support test\n// for it is not run until after DOM ready\njQuery(function() {\n\tif ( !jQuery.support.reliableMarginRight ) {\n\t\tjQuery.cssHooks.marginRight = {\n\t\t\tget: function( elem, computed ) {\n\t\t\t\tif ( computed ) {\n\t\t\t\t\t// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right\n\t\t\t\t\t// Work around by temporarily setting element display to inline-block\n\t\t\t\t\treturn jQuery.swap( elem, { \"display\": \"inline-block\" },\n\t\t\t\t\t\tcurCSS, [ elem, \"marginRight\" ] );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n\n\t// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084\n\t// getComputedStyle returns percent when specified for top/left/bottom/right\n\t// rather than make the css module depend on the offset module, we just check for it here\n\tif ( !jQuery.support.pixelPosition && jQuery.fn.position ) {\n\t\tjQuery.each( [ \"top\", \"left\" ], function( i, prop ) {\n\t\t\tjQuery.cssHooks[ prop ] = {\n\t\t\t\tget: function( elem, computed ) {\n\t\t\t\t\tif ( computed ) {\n\t\t\t\t\t\tcomputed = curCSS( elem, prop );\n\t\t\t\t\t\t// if curCSS returns percentage, fallback to offset\n\t\t\t\t\t\treturn rnumnonpx.test( computed ) ?\n\t\t\t\t\t\t\tjQuery( elem ).position()[ prop ] + \"px\" :\n\t\t\t\t\t\t\tcomputed;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t});\n\t}\n\n});\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.hidden = function( elem ) {\n\t\t// Support: Opera <= 12.12\n\t\t// Opera reports offsetWidths and offsetHeights less than zero on some elements\n\t\treturn elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||\n\t\t\t(!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( elem, \"display\" )) === \"none\");\n\t};\n\n\tjQuery.expr.filters.visible = function( elem ) {\n\t\treturn !jQuery.expr.filters.hidden( elem );\n\t};\n}\n\n// These hooks are used by animate to expand properties\njQuery.each({\n\tmargin: \"\",\n\tpadding: \"\",\n\tborder: \"Width\"\n}, function( prefix, suffix ) {\n\tjQuery.cssHooks[ prefix + suffix ] = {\n\t\texpand: function( value ) {\n\t\t\tvar i = 0,\n\t\t\t\texpanded = {},\n\n\t\t\t\t// assumes a single number if not a string\n\t\t\t\tparts = typeof value === \"string\" ? value.split(\" \") : [ value ];\n\n\t\t\tfor ( ; i < 4; i++ ) {\n\t\t\t\texpanded[ prefix + cssExpand[ i ] + suffix ] =\n\t\t\t\t\tparts[ i ] || parts[ i - 2 ] || parts[ 0 ];\n\t\t\t}\n\n\t\t\treturn expanded;\n\t\t}\n\t};\n\n\tif ( !rmargin.test( prefix ) ) {\n\t\tjQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;\n\t}\n});\nvar r20 = /%20/g,\n\trbracket = /\\[\\]$/,\n\trCRLF = /\\r?\\n/g,\n\trsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,\n\trsubmittable = /^(?:input|select|textarea|keygen)/i;\n\njQuery.fn.extend({\n\tserialize: function() {\n\t\treturn jQuery.param( this.serializeArray() );\n\t},\n\tserializeArray: function() {\n\t\treturn this.map(function(){\n\t\t\t// Can add propHook for \"elements\" to filter or add form elements\n\t\t\tvar elements = jQuery.prop( this, \"elements\" );\n\t\t\treturn elements ? jQuery.makeArray( elements ) : this;\n\t\t})\n\t\t.filter(function(){\n\t\t\tvar type = this.type;\n\t\t\t// Use .is(\":disabled\") so that fieldset[disabled] works\n\t\t\treturn this.name && !jQuery( this ).is( \":disabled\" ) &&\n\t\t\t\trsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&\n\t\t\t\t( this.checked || !manipulation_rcheckableType.test( type ) );\n\t\t})\n\t\t.map(function( i, elem ){\n\t\t\tvar val = jQuery( this ).val();\n\n\t\t\treturn val == null ?\n\t\t\t\tnull :\n\t\t\t\tjQuery.isArray( val ) ?\n\t\t\t\t\tjQuery.map( val, function( val ){\n\t\t\t\t\t\treturn { name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t\t\t\t}) :\n\t\t\t\t\t{ name: elem.name, value: val.replace( rCRLF, \"\\r\\n\" ) };\n\t\t}).get();\n\t}\n});\n\n//Serialize an array of form elements or a set of\n//key/values into a query string\njQuery.param = function( a, traditional ) {\n\tvar prefix,\n\t\ts = [],\n\t\tadd = function( key, value ) {\n\t\t\t// If value is a function, invoke it and return its value\n\t\t\tvalue = jQuery.isFunction( value ) ? value() : ( value == null ? \"\" : value );\n\t\t\ts[ s.length ] = encodeURIComponent( key ) + \"=\" + encodeURIComponent( value );\n\t\t};\n\n\t// Set traditional to true for jQuery <= 1.3.2 behavior.\n\tif ( traditional === undefined ) {\n\t\ttraditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional;\n\t}\n\n\t// If an array was passed in, assume that it is an array of form elements.\n\tif ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {\n\t\t// Serialize the form elements\n\t\tjQuery.each( a, function() {\n\t\t\tadd( this.name, this.value );\n\t\t});\n\n\t} else {\n\t\t// If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t\t// did it), otherwise encode params recursively.\n\t\tfor ( prefix in a ) {\n\t\t\tbuildParams( prefix, a[ prefix ], traditional, add );\n\t\t}\n\t}\n\n\t// Return the resulting serialization\n\treturn s.join( \"&\" ).replace( r20, \"+\" );\n};\n\nfunction buildParams( prefix, obj, traditional, add ) {\n\tvar name;\n\n\tif ( jQuery.isArray( obj ) ) {\n\t\t// Serialize array item.\n\t\tjQuery.each( obj, function( i, v ) {\n\t\t\tif ( traditional || rbracket.test( prefix ) ) {\n\t\t\t\t// Treat each array item as a scalar.\n\t\t\t\tadd( prefix, v );\n\n\t\t\t} else {\n\t\t\t\t// Item is non-scalar (array or object), encode its numeric index.\n\t\t\t\tbuildParams( prefix + \"[\" + ( typeof v === \"object\" ? i : \"\" ) + \"]\", v, traditional, add );\n\t\t\t}\n\t\t});\n\n\t} else if ( !traditional && jQuery.type( obj ) === \"object\" ) {\n\t\t// Serialize object item.\n\t\tfor ( name in obj ) {\n\t\t\tbuildParams( prefix + \"[\" + name + \"]\", obj[ name ], traditional, add );\n\t\t}\n\n\t} else {\n\t\t// Serialize scalar item.\n\t\tadd( prefix, obj );\n\t}\n}\njQuery.each( (\"blur focus focusin focusout load resize scroll unload click dblclick \" +\n\t\"mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave \" +\n\t\"change select submit keydown keypress keyup error contextmenu\").split(\" \"), function( i, name ) {\n\n\t// Handle event binding\n\tjQuery.fn[ name ] = function( data, fn ) {\n\t\treturn arguments.length > 0 ?\n\t\t\tthis.on( name, null, data, fn ) :\n\t\t\tthis.trigger( name );\n\t};\n});\n\njQuery.fn.extend({\n\thover: function( fnOver, fnOut ) {\n\t\treturn this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );\n\t},\n\n\tbind: function( types, data, fn ) {\n\t\treturn this.on( types, null, data, fn );\n\t},\n\tunbind: function( types, fn ) {\n\t\treturn this.off( types, null, fn );\n\t},\n\n\tdelegate: function( selector, types, data, fn ) {\n\t\treturn this.on( types, selector, data, fn );\n\t},\n\tundelegate: function( selector, types, fn ) {\n\t\t// ( namespace ) or ( selector, types [, fn] )\n\t\treturn arguments.length === 1 ? this.off( selector, \"**\" ) : this.off( types, selector || \"**\", fn );\n\t}\n});\nvar\n\t// Document location\n\tajaxLocParts,\n\tajaxLocation,\n\tajax_nonce = jQuery.now(),\n\n\tajax_rquery = /\\?/,\n\trhash = /#.*$/,\n\trts = /([?&])_=[^&]*/,\n\trheaders = /^(.*?):[ \\t]*([^\\r\\n]*)\\r?$/mg, // IE leaves an \\r character at EOL\n\t// #7653, #8125, #8152: local protocol detection\n\trlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,\n\trnoContent = /^(?:GET|HEAD)$/,\n\trprotocol = /^\\/\\//,\n\trurl = /^([\\w.+-]+:)(?:\\/\\/([^\\/?#:]*)(?::(\\d+)|)|)/,\n\n\t// Keep a copy of the old load method\n\t_load = jQuery.fn.load,\n\n\t/* Prefilters\n\t * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)\n\t * 2) These are called:\n\t *    - BEFORE asking for a transport\n\t *    - AFTER param serialization (s.data is a string if s.processData is true)\n\t * 3) key is the dataType\n\t * 4) the catchall symbol \"*\" can be used\n\t * 5) execution will start with transport dataType and THEN continue down to \"*\" if needed\n\t */\n\tprefilters = {},\n\n\t/* Transports bindings\n\t * 1) key is the dataType\n\t * 2) the catchall symbol \"*\" can be used\n\t * 3) selection will start with transport dataType and THEN go to \"*\" if needed\n\t */\n\ttransports = {},\n\n\t// Avoid comment-prolog char sequence (#10098); must appease lint and evade compression\n\tallTypes = \"*/\".concat(\"*\");\n\n// #8138, IE may throw an exception when accessing\n// a field from window.location if document.domain has been set\ntry {\n\tajaxLocation = location.href;\n} catch( e ) {\n\t// Use the href attribute of an A element\n\t// since IE will modify it given document.location\n\tajaxLocation = document.createElement( \"a\" );\n\tajaxLocation.href = \"\";\n\tajaxLocation = ajaxLocation.href;\n}\n\n// Segment location into parts\najaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || [];\n\n// Base \"constructor\" for jQuery.ajaxPrefilter and jQuery.ajaxTransport\nfunction addToPrefiltersOrTransports( structure ) {\n\n\t// dataTypeExpression is optional and defaults to \"*\"\n\treturn function( dataTypeExpression, func ) {\n\n\t\tif ( typeof dataTypeExpression !== \"string\" ) {\n\t\t\tfunc = dataTypeExpression;\n\t\t\tdataTypeExpression = \"*\";\n\t\t}\n\n\t\tvar dataType,\n\t\t\ti = 0,\n\t\t\tdataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];\n\n\t\tif ( jQuery.isFunction( func ) ) {\n\t\t\t// For each dataType in the dataTypeExpression\n\t\t\twhile ( (dataType = dataTypes[i++]) ) {\n\t\t\t\t// Prepend if requested\n\t\t\t\tif ( dataType[0] === \"+\" ) {\n\t\t\t\t\tdataType = dataType.slice( 1 ) || \"*\";\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).unshift( func );\n\n\t\t\t\t// Otherwise append\n\t\t\t\t} else {\n\t\t\t\t\t(structure[ dataType ] = structure[ dataType ] || []).push( func );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t};\n}\n\n// Base inspection function for prefilters and transports\nfunction inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {\n\n\tvar inspected = {},\n\t\tseekingTransport = ( structure === transports );\n\n\tfunction inspect( dataType ) {\n\t\tvar selected;\n\t\tinspected[ dataType ] = true;\n\t\tjQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {\n\t\t\tvar dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );\n\t\t\tif( typeof dataTypeOrTransport === \"string\" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {\n\t\t\t\toptions.dataTypes.unshift( dataTypeOrTransport );\n\t\t\t\tinspect( dataTypeOrTransport );\n\t\t\t\treturn false;\n\t\t\t} else if ( seekingTransport ) {\n\t\t\t\treturn !( selected = dataTypeOrTransport );\n\t\t\t}\n\t\t});\n\t\treturn selected;\n\t}\n\n\treturn inspect( options.dataTypes[ 0 ] ) || !inspected[ \"*\" ] && inspect( \"*\" );\n}\n\n// A special extend for ajax options\n// that takes \"flat\" options (not to be deep extended)\n// Fixes #9887\nfunction ajaxExtend( target, src ) {\n\tvar deep, key,\n\t\tflatOptions = jQuery.ajaxSettings.flatOptions || {};\n\n\tfor ( key in src ) {\n\t\tif ( src[ key ] !== undefined ) {\n\t\t\t( flatOptions[ key ] ? target : ( deep || (deep = {}) ) )[ key ] = src[ key ];\n\t\t}\n\t}\n\tif ( deep ) {\n\t\tjQuery.extend( true, target, deep );\n\t}\n\n\treturn target;\n}\n\njQuery.fn.load = function( url, params, callback ) {\n\tif ( typeof url !== \"string\" && _load ) {\n\t\treturn _load.apply( this, arguments );\n\t}\n\n\tvar selector, response, type,\n\t\tself = this,\n\t\toff = url.indexOf(\" \");\n\n\tif ( off >= 0 ) {\n\t\tselector = url.slice( off, url.length );\n\t\turl = url.slice( 0, off );\n\t}\n\n\t// If it's a function\n\tif ( jQuery.isFunction( params ) ) {\n\n\t\t// We assume that it's the callback\n\t\tcallback = params;\n\t\tparams = undefined;\n\n\t// Otherwise, build a param string\n\t} else if ( params && typeof params === \"object\" ) {\n\t\ttype = \"POST\";\n\t}\n\n\t// If we have elements to modify, make the request\n\tif ( self.length > 0 ) {\n\t\tjQuery.ajax({\n\t\t\turl: url,\n\n\t\t\t// if \"type\" variable is undefined, then \"GET\" method will be used\n\t\t\ttype: type,\n\t\t\tdataType: \"html\",\n\t\t\tdata: params\n\t\t}).done(function( responseText ) {\n\n\t\t\t// Save response for use in complete callback\n\t\t\tresponse = arguments;\n\n\t\t\tself.html( selector ?\n\n\t\t\t\t// If a selector was specified, locate the right elements in a dummy div\n\t\t\t\t// Exclude scripts to avoid IE 'Permission Denied' errors\n\t\t\t\tjQuery(\"<div>\").append( jQuery.parseHTML( responseText ) ).find( selector ) :\n\n\t\t\t\t// Otherwise use the full result\n\t\t\t\tresponseText );\n\n\t\t}).complete( callback && function( jqXHR, status ) {\n\t\t\tself.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );\n\t\t});\n\t}\n\n\treturn this;\n};\n\n// Attach a bunch of functions for handling common AJAX events\njQuery.each( [ \"ajaxStart\", \"ajaxStop\", \"ajaxComplete\", \"ajaxError\", \"ajaxSuccess\", \"ajaxSend\" ], function( i, type ){\n\tjQuery.fn[ type ] = function( fn ){\n\t\treturn this.on( type, fn );\n\t};\n});\n\njQuery.extend({\n\n\t// Counter for holding the number of active queries\n\tactive: 0,\n\n\t// Last-Modified header cache for next request\n\tlastModified: {},\n\tetag: {},\n\n\tajaxSettings: {\n\t\turl: ajaxLocation,\n\t\ttype: \"GET\",\n\t\tisLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),\n\t\tglobal: true,\n\t\tprocessData: true,\n\t\tasync: true,\n\t\tcontentType: \"application/x-www-form-urlencoded; charset=UTF-8\",\n\t\t/*\n\t\ttimeout: 0,\n\t\tdata: null,\n\t\tdataType: null,\n\t\tusername: null,\n\t\tpassword: null,\n\t\tcache: null,\n\t\tthrows: false,\n\t\ttraditional: false,\n\t\theaders: {},\n\t\t*/\n\n\t\taccepts: {\n\t\t\t\"*\": allTypes,\n\t\t\ttext: \"text/plain\",\n\t\t\thtml: \"text/html\",\n\t\t\txml: \"application/xml, text/xml\",\n\t\t\tjson: \"application/json, text/javascript\"\n\t\t},\n\n\t\tcontents: {\n\t\t\txml: /xml/,\n\t\t\thtml: /html/,\n\t\t\tjson: /json/\n\t\t},\n\n\t\tresponseFields: {\n\t\t\txml: \"responseXML\",\n\t\t\ttext: \"responseText\",\n\t\t\tjson: \"responseJSON\"\n\t\t},\n\n\t\t// Data converters\n\t\t// Keys separate source (or catchall \"*\") and destination types with a single space\n\t\tconverters: {\n\n\t\t\t// Convert anything to text\n\t\t\t\"* text\": String,\n\n\t\t\t// Text to html (true = no transformation)\n\t\t\t\"text html\": true,\n\n\t\t\t// Evaluate text as a json expression\n\t\t\t\"text json\": jQuery.parseJSON,\n\n\t\t\t// Parse text as xml\n\t\t\t\"text xml\": jQuery.parseXML\n\t\t},\n\n\t\t// For options that shouldn't be deep extended:\n\t\t// you can add your own custom options here if\n\t\t// and when you create one that shouldn't be\n\t\t// deep extended (see ajaxExtend)\n\t\tflatOptions: {\n\t\t\turl: true,\n\t\t\tcontext: true\n\t\t}\n\t},\n\n\t// Creates a full fledged settings object into target\n\t// with both ajaxSettings and settings fields.\n\t// If target is omitted, writes into ajaxSettings.\n\tajaxSetup: function( target, settings ) {\n\t\treturn settings ?\n\n\t\t\t// Building a settings object\n\t\t\tajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :\n\n\t\t\t// Extending ajaxSettings\n\t\t\tajaxExtend( jQuery.ajaxSettings, target );\n\t},\n\n\tajaxPrefilter: addToPrefiltersOrTransports( prefilters ),\n\tajaxTransport: addToPrefiltersOrTransports( transports ),\n\n\t// Main method\n\tajax: function( url, options ) {\n\n\t\t// If url is an object, simulate pre-1.5 signature\n\t\tif ( typeof url === \"object\" ) {\n\t\t\toptions = url;\n\t\t\turl = undefined;\n\t\t}\n\n\t\t// Force options to be an object\n\t\toptions = options || {};\n\n\t\tvar // Cross-domain detection vars\n\t\t\tparts,\n\t\t\t// Loop variable\n\t\t\ti,\n\t\t\t// URL without anti-cache param\n\t\t\tcacheURL,\n\t\t\t// Response headers as string\n\t\t\tresponseHeadersString,\n\t\t\t// timeout handle\n\t\t\ttimeoutTimer,\n\n\t\t\t// To know if global events are to be dispatched\n\t\t\tfireGlobals,\n\n\t\t\ttransport,\n\t\t\t// Response headers\n\t\t\tresponseHeaders,\n\t\t\t// Create the final options object\n\t\t\ts = jQuery.ajaxSetup( {}, options ),\n\t\t\t// Callbacks context\n\t\t\tcallbackContext = s.context || s,\n\t\t\t// Context for global events is callbackContext if it is a DOM node or jQuery collection\n\t\t\tglobalEventContext = s.context && ( callbackContext.nodeType || callbackContext.jquery ) ?\n\t\t\t\tjQuery( callbackContext ) :\n\t\t\t\tjQuery.event,\n\t\t\t// Deferreds\n\t\t\tdeferred = jQuery.Deferred(),\n\t\t\tcompleteDeferred = jQuery.Callbacks(\"once memory\"),\n\t\t\t// Status-dependent callbacks\n\t\t\tstatusCode = s.statusCode || {},\n\t\t\t// Headers (they are sent all at once)\n\t\t\trequestHeaders = {},\n\t\t\trequestHeadersNames = {},\n\t\t\t// The jqXHR state\n\t\t\tstate = 0,\n\t\t\t// Default abort message\n\t\t\tstrAbort = \"canceled\",\n\t\t\t// Fake xhr\n\t\t\tjqXHR = {\n\t\t\t\treadyState: 0,\n\n\t\t\t\t// Builds headers hashtable if needed\n\t\t\t\tgetResponseHeader: function( key ) {\n\t\t\t\t\tvar match;\n\t\t\t\t\tif ( state === 2 ) {\n\t\t\t\t\t\tif ( !responseHeaders ) {\n\t\t\t\t\t\t\tresponseHeaders = {};\n\t\t\t\t\t\t\twhile ( (match = rheaders.exec( responseHeadersString )) ) {\n\t\t\t\t\t\t\t\tresponseHeaders[ match[1].toLowerCase() ] = match[ 2 ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tmatch = responseHeaders[ key.toLowerCase() ];\n\t\t\t\t\t}\n\t\t\t\t\treturn match == null ? null : match;\n\t\t\t\t},\n\n\t\t\t\t// Raw string\n\t\t\t\tgetAllResponseHeaders: function() {\n\t\t\t\t\treturn state === 2 ? responseHeadersString : null;\n\t\t\t\t},\n\n\t\t\t\t// Caches the header\n\t\t\t\tsetRequestHeader: function( name, value ) {\n\t\t\t\t\tvar lname = name.toLowerCase();\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\tname = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;\n\t\t\t\t\t\trequestHeaders[ name ] = value;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Overrides response content-type header\n\t\t\t\toverrideMimeType: function( type ) {\n\t\t\t\t\tif ( !state ) {\n\t\t\t\t\t\ts.mimeType = type;\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Status-dependent callbacks\n\t\t\t\tstatusCode: function( map ) {\n\t\t\t\t\tvar code;\n\t\t\t\t\tif ( map ) {\n\t\t\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\t\t\tfor ( code in map ) {\n\t\t\t\t\t\t\t\t// Lazy-add the new callback in a way that preserves old ones\n\t\t\t\t\t\t\t\tstatusCode[ code ] = [ statusCode[ code ], map[ code ] ];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Execute the appropriate callbacks\n\t\t\t\t\t\t\tjqXHR.always( map[ jqXHR.status ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn this;\n\t\t\t\t},\n\n\t\t\t\t// Cancel the request\n\t\t\t\tabort: function( statusText ) {\n\t\t\t\t\tvar finalText = statusText || strAbort;\n\t\t\t\t\tif ( transport ) {\n\t\t\t\t\t\ttransport.abort( finalText );\n\t\t\t\t\t}\n\t\t\t\t\tdone( 0, finalText );\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t};\n\n\t\t// Attach deferreds\n\t\tdeferred.promise( jqXHR ).complete = completeDeferred.add;\n\t\tjqXHR.success = jqXHR.done;\n\t\tjqXHR.error = jqXHR.fail;\n\n\t\t// Remove hash character (#7531: and string promotion)\n\t\t// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)\n\t\t// Handle falsy url in the settings object (#10093: consistency with old signature)\n\t\t// We also use the url parameter if available\n\t\ts.url = ( ( url || s.url || ajaxLocation ) + \"\" ).replace( rhash, \"\" ).replace( rprotocol, ajaxLocParts[ 1 ] + \"//\" );\n\n\t\t// Alias method option to type as per ticket #12004\n\t\ts.type = options.method || options.type || s.method || s.type;\n\n\t\t// Extract dataTypes list\n\t\ts.dataTypes = jQuery.trim( s.dataType || \"*\" ).toLowerCase().match( core_rnotwhite ) || [\"\"];\n\n\t\t// A cross-domain request is in order when we have a protocol:host:port mismatch\n\t\tif ( s.crossDomain == null ) {\n\t\t\tparts = rurl.exec( s.url.toLowerCase() );\n\t\t\ts.crossDomain = !!( parts &&\n\t\t\t\t( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] ||\n\t\t\t\t\t( parts[ 3 ] || ( parts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) !==\n\t\t\t\t\t\t( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === \"http:\" ? \"80\" : \"443\" ) ) )\n\t\t\t);\n\t\t}\n\n\t\t// Convert data if not already a string\n\t\tif ( s.data && s.processData && typeof s.data !== \"string\" ) {\n\t\t\ts.data = jQuery.param( s.data, s.traditional );\n\t\t}\n\n\t\t// Apply prefilters\n\t\tinspectPrefiltersOrTransports( prefilters, s, options, jqXHR );\n\n\t\t// If request was aborted inside a prefilter, stop there\n\t\tif ( state === 2 ) {\n\t\t\treturn jqXHR;\n\t\t}\n\n\t\t// We can fire global events as of now if asked to\n\t\tfireGlobals = s.global;\n\n\t\t// Watch for a new set of requests\n\t\tif ( fireGlobals && jQuery.active++ === 0 ) {\n\t\t\tjQuery.event.trigger(\"ajaxStart\");\n\t\t}\n\n\t\t// Uppercase the type\n\t\ts.type = s.type.toUpperCase();\n\n\t\t// Determine if request has content\n\t\ts.hasContent = !rnoContent.test( s.type );\n\n\t\t// Save the URL in case we're toying with the If-Modified-Since\n\t\t// and/or If-None-Match header later on\n\t\tcacheURL = s.url;\n\n\t\t// More options handling for requests with no content\n\t\tif ( !s.hasContent ) {\n\n\t\t\t// If data is available, append data to url\n\t\t\tif ( s.data ) {\n\t\t\t\tcacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? \"&\" : \"?\" ) + s.data );\n\t\t\t\t// #9682: remove data so that it's not used in an eventual retry\n\t\t\t\tdelete s.data;\n\t\t\t}\n\n\t\t\t// Add anti-cache in url if needed\n\t\t\tif ( s.cache === false ) {\n\t\t\t\ts.url = rts.test( cacheURL ) ?\n\n\t\t\t\t\t// If there is already a '_' parameter, set its value\n\t\t\t\t\tcacheURL.replace( rts, \"$1_=\" + ajax_nonce++ ) :\n\n\t\t\t\t\t// Otherwise add one to the end\n\t\t\t\t\tcacheURL + ( ajax_rquery.test( cacheURL ) ? \"&\" : \"?\" ) + \"_=\" + ajax_nonce++;\n\t\t\t}\n\t\t}\n\n\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\tif ( s.ifModified ) {\n\t\t\tif ( jQuery.lastModified[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-Modified-Since\", jQuery.lastModified[ cacheURL ] );\n\t\t\t}\n\t\t\tif ( jQuery.etag[ cacheURL ] ) {\n\t\t\t\tjqXHR.setRequestHeader( \"If-None-Match\", jQuery.etag[ cacheURL ] );\n\t\t\t}\n\t\t}\n\n\t\t// Set the correct header, if data is being sent\n\t\tif ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {\n\t\t\tjqXHR.setRequestHeader( \"Content-Type\", s.contentType );\n\t\t}\n\n\t\t// Set the Accepts header for the server, depending on the dataType\n\t\tjqXHR.setRequestHeader(\n\t\t\t\"Accept\",\n\t\t\ts.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ?\n\t\t\t\ts.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== \"*\" ? \", \" + allTypes + \"; q=0.01\" : \"\" ) :\n\t\t\t\ts.accepts[ \"*\" ]\n\t\t);\n\n\t\t// Check for headers option\n\t\tfor ( i in s.headers ) {\n\t\t\tjqXHR.setRequestHeader( i, s.headers[ i ] );\n\t\t}\n\n\t\t// Allow custom headers/mimetypes and early abort\n\t\tif ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) {\n\t\t\t// Abort if not done already and return\n\t\t\treturn jqXHR.abort();\n\t\t}\n\n\t\t// aborting is no longer a cancellation\n\t\tstrAbort = \"abort\";\n\n\t\t// Install callbacks on deferreds\n\t\tfor ( i in { success: 1, error: 1, complete: 1 } ) {\n\t\t\tjqXHR[ i ]( s[ i ] );\n\t\t}\n\n\t\t// Get transport\n\t\ttransport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );\n\n\t\t// If no transport, we auto-abort\n\t\tif ( !transport ) {\n\t\t\tdone( -1, \"No Transport\" );\n\t\t} else {\n\t\t\tjqXHR.readyState = 1;\n\n\t\t\t// Send global event\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxSend\", [ jqXHR, s ] );\n\t\t\t}\n\t\t\t// Timeout\n\t\t\tif ( s.async && s.timeout > 0 ) {\n\t\t\t\ttimeoutTimer = setTimeout(function() {\n\t\t\t\t\tjqXHR.abort(\"timeout\");\n\t\t\t\t}, s.timeout );\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tstate = 1;\n\t\t\t\ttransport.send( requestHeaders, done );\n\t\t\t} catch ( e ) {\n\t\t\t\t// Propagate exception as error if not done\n\t\t\t\tif ( state < 2 ) {\n\t\t\t\t\tdone( -1, e );\n\t\t\t\t// Simply rethrow otherwise\n\t\t\t\t} else {\n\t\t\t\t\tthrow e;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Callback for when everything is done\n\t\tfunction done( status, nativeStatusText, responses, headers ) {\n\t\t\tvar isSuccess, success, error, response, modified,\n\t\t\t\tstatusText = nativeStatusText;\n\n\t\t\t// Called once\n\t\t\tif ( state === 2 ) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\t// State is \"done\" now\n\t\t\tstate = 2;\n\n\t\t\t// Clear timeout if it exists\n\t\t\tif ( timeoutTimer ) {\n\t\t\t\tclearTimeout( timeoutTimer );\n\t\t\t}\n\n\t\t\t// Dereference transport for early garbage collection\n\t\t\t// (no matter how long the jqXHR object will be used)\n\t\t\ttransport = undefined;\n\n\t\t\t// Cache response headers\n\t\t\tresponseHeadersString = headers || \"\";\n\n\t\t\t// Set readyState\n\t\t\tjqXHR.readyState = status > 0 ? 4 : 0;\n\n\t\t\t// Determine if successful\n\t\t\tisSuccess = status >= 200 && status < 300 || status === 304;\n\n\t\t\t// Get response data\n\t\t\tif ( responses ) {\n\t\t\t\tresponse = ajaxHandleResponses( s, jqXHR, responses );\n\t\t\t}\n\n\t\t\t// Convert no matter what (that way responseXXX fields are always set)\n\t\t\tresponse = ajaxConvert( s, response, jqXHR, isSuccess );\n\n\t\t\t// If successful, handle type chaining\n\t\t\tif ( isSuccess ) {\n\n\t\t\t\t// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.\n\t\t\t\tif ( s.ifModified ) {\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"Last-Modified\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.lastModified[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t\tmodified = jqXHR.getResponseHeader(\"etag\");\n\t\t\t\t\tif ( modified ) {\n\t\t\t\t\t\tjQuery.etag[ cacheURL ] = modified;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// if no content\n\t\t\t\tif ( status === 204 || s.type === \"HEAD\" ) {\n\t\t\t\t\tstatusText = \"nocontent\";\n\n\t\t\t\t// if not modified\n\t\t\t\t} else if ( status === 304 ) {\n\t\t\t\t\tstatusText = \"notmodified\";\n\n\t\t\t\t// If we have data, let's convert it\n\t\t\t\t} else {\n\t\t\t\t\tstatusText = response.state;\n\t\t\t\t\tsuccess = response.data;\n\t\t\t\t\terror = response.error;\n\t\t\t\t\tisSuccess = !error;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We extract error from statusText\n\t\t\t\t// then normalize statusText and status for non-aborts\n\t\t\t\terror = statusText;\n\t\t\t\tif ( status || !statusText ) {\n\t\t\t\t\tstatusText = \"error\";\n\t\t\t\t\tif ( status < 0 ) {\n\t\t\t\t\t\tstatus = 0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Set data for the fake xhr object\n\t\t\tjqXHR.status = status;\n\t\t\tjqXHR.statusText = ( nativeStatusText || statusText ) + \"\";\n\n\t\t\t// Success/Error\n\t\t\tif ( isSuccess ) {\n\t\t\t\tdeferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );\n\t\t\t} else {\n\t\t\t\tdeferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );\n\t\t\t}\n\n\t\t\t// Status-dependent callbacks\n\t\t\tjqXHR.statusCode( statusCode );\n\t\t\tstatusCode = undefined;\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( isSuccess ? \"ajaxSuccess\" : \"ajaxError\",\n\t\t\t\t\t[ jqXHR, s, isSuccess ? success : error ] );\n\t\t\t}\n\n\t\t\t// Complete\n\t\t\tcompleteDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );\n\n\t\t\tif ( fireGlobals ) {\n\t\t\t\tglobalEventContext.trigger( \"ajaxComplete\", [ jqXHR, s ] );\n\t\t\t\t// Handle the global AJAX counter\n\t\t\t\tif ( !( --jQuery.active ) ) {\n\t\t\t\t\tjQuery.event.trigger(\"ajaxStop\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn jqXHR;\n\t},\n\n\tgetJSON: function( url, data, callback ) {\n\t\treturn jQuery.get( url, data, callback, \"json\" );\n\t},\n\n\tgetScript: function( url, callback ) {\n\t\treturn jQuery.get( url, undefined, callback, \"script\" );\n\t}\n});\n\njQuery.each( [ \"get\", \"post\" ], function( i, method ) {\n\tjQuery[ method ] = function( url, data, callback, type ) {\n\t\t// shift arguments if data argument was omitted\n\t\tif ( jQuery.isFunction( data ) ) {\n\t\t\ttype = type || callback;\n\t\t\tcallback = data;\n\t\t\tdata = undefined;\n\t\t}\n\n\t\treturn jQuery.ajax({\n\t\t\turl: url,\n\t\t\ttype: method,\n\t\t\tdataType: type,\n\t\t\tdata: data,\n\t\t\tsuccess: callback\n\t\t});\n\t};\n});\n\n/* Handles responses to an ajax request:\n * - finds the right dataType (mediates between content-type and expected dataType)\n * - returns the corresponding response\n */\nfunction ajaxHandleResponses( s, jqXHR, responses ) {\n\tvar firstDataType, ct, finalDataType, type,\n\t\tcontents = s.contents,\n\t\tdataTypes = s.dataTypes;\n\n\t// Remove auto dataType and get content-type in the process\n\twhile( dataTypes[ 0 ] === \"*\" ) {\n\t\tdataTypes.shift();\n\t\tif ( ct === undefined ) {\n\t\t\tct = s.mimeType || jqXHR.getResponseHeader(\"Content-Type\");\n\t\t}\n\t}\n\n\t// Check if we're dealing with a known content-type\n\tif ( ct ) {\n\t\tfor ( type in contents ) {\n\t\t\tif ( contents[ type ] && contents[ type ].test( ct ) ) {\n\t\t\t\tdataTypes.unshift( type );\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t// Check to see if we have a response for the expected dataType\n\tif ( dataTypes[ 0 ] in responses ) {\n\t\tfinalDataType = dataTypes[ 0 ];\n\t} else {\n\t\t// Try convertible dataTypes\n\t\tfor ( type in responses ) {\n\t\t\tif ( !dataTypes[ 0 ] || s.converters[ type + \" \" + dataTypes[0] ] ) {\n\t\t\t\tfinalDataType = type;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif ( !firstDataType ) {\n\t\t\t\tfirstDataType = type;\n\t\t\t}\n\t\t}\n\t\t// Or just use first one\n\t\tfinalDataType = finalDataType || firstDataType;\n\t}\n\n\t// If we found a dataType\n\t// We add the dataType to the list if needed\n\t// and return the corresponding response\n\tif ( finalDataType ) {\n\t\tif ( finalDataType !== dataTypes[ 0 ] ) {\n\t\t\tdataTypes.unshift( finalDataType );\n\t\t}\n\t\treturn responses[ finalDataType ];\n\t}\n}\n\n/* Chain conversions given the request and the original response\n * Also sets the responseXXX fields on the jqXHR instance\n */\nfunction ajaxConvert( s, response, jqXHR, isSuccess ) {\n\tvar conv2, current, conv, tmp, prev,\n\t\tconverters = {},\n\t\t// Work with a copy of dataTypes in case we need to modify it for conversion\n\t\tdataTypes = s.dataTypes.slice();\n\n\t// Create converters map with lowercased keys\n\tif ( dataTypes[ 1 ] ) {\n\t\tfor ( conv in s.converters ) {\n\t\t\tconverters[ conv.toLowerCase() ] = s.converters[ conv ];\n\t\t}\n\t}\n\n\tcurrent = dataTypes.shift();\n\n\t// Convert to each sequential dataType\n\twhile ( current ) {\n\n\t\tif ( s.responseFields[ current ] ) {\n\t\t\tjqXHR[ s.responseFields[ current ] ] = response;\n\t\t}\n\n\t\t// Apply the dataFilter if provided\n\t\tif ( !prev && isSuccess && s.dataFilter ) {\n\t\t\tresponse = s.dataFilter( response, s.dataType );\n\t\t}\n\n\t\tprev = current;\n\t\tcurrent = dataTypes.shift();\n\n\t\tif ( current ) {\n\n\t\t\t// There's only work to do if current dataType is non-auto\n\t\t\tif ( current === \"*\" ) {\n\n\t\t\t\tcurrent = prev;\n\n\t\t\t// Convert response if prev dataType is non-auto and differs from current\n\t\t\t} else if ( prev !== \"*\" && prev !== current ) {\n\n\t\t\t\t// Seek a direct converter\n\t\t\t\tconv = converters[ prev + \" \" + current ] || converters[ \"* \" + current ];\n\n\t\t\t\t// If none found, seek a pair\n\t\t\t\tif ( !conv ) {\n\t\t\t\t\tfor ( conv2 in converters ) {\n\n\t\t\t\t\t\t// If conv2 outputs current\n\t\t\t\t\t\ttmp = conv2.split( \" \" );\n\t\t\t\t\t\tif ( tmp[ 1 ] === current ) {\n\n\t\t\t\t\t\t\t// If prev can be converted to accepted input\n\t\t\t\t\t\t\tconv = converters[ prev + \" \" + tmp[ 0 ] ] ||\n\t\t\t\t\t\t\t\tconverters[ \"* \" + tmp[ 0 ] ];\n\t\t\t\t\t\t\tif ( conv ) {\n\t\t\t\t\t\t\t\t// Condense equivalence converters\n\t\t\t\t\t\t\t\tif ( conv === true ) {\n\t\t\t\t\t\t\t\t\tconv = converters[ conv2 ];\n\n\t\t\t\t\t\t\t\t// Otherwise, insert the intermediate dataType\n\t\t\t\t\t\t\t\t} else if ( converters[ conv2 ] !== true ) {\n\t\t\t\t\t\t\t\t\tcurrent = tmp[ 0 ];\n\t\t\t\t\t\t\t\t\tdataTypes.unshift( tmp[ 1 ] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Apply converter (if not an equivalence)\n\t\t\t\tif ( conv !== true ) {\n\n\t\t\t\t\t// Unless errors are allowed to bubble, catch and return them\n\t\t\t\t\tif ( conv && s[ \"throws\" ] ) {\n\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t} else {\n\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\tresponse = conv( response );\n\t\t\t\t\t\t} catch ( e ) {\n\t\t\t\t\t\t\treturn { state: \"parsererror\", error: conv ? e : \"No conversion from \" + prev + \" to \" + current };\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\treturn { state: \"success\", data: response };\n}\n// Install script dataType\njQuery.ajaxSetup({\n\taccepts: {\n\t\tscript: \"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript\"\n\t},\n\tcontents: {\n\t\tscript: /(?:java|ecma)script/\n\t},\n\tconverters: {\n\t\t\"text script\": function( text ) {\n\t\t\tjQuery.globalEval( text );\n\t\t\treturn text;\n\t\t}\n\t}\n});\n\n// Handle cache's special case and global\njQuery.ajaxPrefilter( \"script\", function( s ) {\n\tif ( s.cache === undefined ) {\n\t\ts.cache = false;\n\t}\n\tif ( s.crossDomain ) {\n\t\ts.type = \"GET\";\n\t\ts.global = false;\n\t}\n});\n\n// Bind script tag hack transport\njQuery.ajaxTransport( \"script\", function(s) {\n\n\t// This transport only deals with cross domain requests\n\tif ( s.crossDomain ) {\n\n\t\tvar script,\n\t\t\thead = document.head || jQuery(\"head\")[0] || document.documentElement;\n\n\t\treturn {\n\n\t\t\tsend: function( _, callback ) {\n\n\t\t\t\tscript = document.createElement(\"script\");\n\n\t\t\t\tscript.async = true;\n\n\t\t\t\tif ( s.scriptCharset ) {\n\t\t\t\t\tscript.charset = s.scriptCharset;\n\t\t\t\t}\n\n\t\t\t\tscript.src = s.url;\n\n\t\t\t\t// Attach handlers for all browsers\n\t\t\t\tscript.onload = script.onreadystatechange = function( _, isAbort ) {\n\n\t\t\t\t\tif ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {\n\n\t\t\t\t\t\t// Handle memory leak in IE\n\t\t\t\t\t\tscript.onload = script.onreadystatechange = null;\n\n\t\t\t\t\t\t// Remove the script\n\t\t\t\t\t\tif ( script.parentNode ) {\n\t\t\t\t\t\t\tscript.parentNode.removeChild( script );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Dereference the script\n\t\t\t\t\t\tscript = null;\n\n\t\t\t\t\t\t// Callback if not abort\n\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\tcallback( 200, \"success\" );\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t};\n\n\t\t\t\t// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending\n\t\t\t\t// Use native DOM manipulation to avoid our domManip AJAX trickery\n\t\t\t\thead.insertBefore( script, head.firstChild );\n\t\t\t},\n\n\t\t\tabort: function() {\n\t\t\t\tif ( script ) {\n\t\t\t\t\tscript.onload( undefined, true );\n\t\t\t\t}\n\t\t\t}\n\t\t};\n\t}\n});\nvar oldCallbacks = [],\n\trjsonp = /(=)\\?(?=&|$)|\\?\\?/;\n\n// Default jsonp settings\njQuery.ajaxSetup({\n\tjsonp: \"callback\",\n\tjsonpCallback: function() {\n\t\tvar callback = oldCallbacks.pop() || ( jQuery.expando + \"_\" + ( ajax_nonce++ ) );\n\t\tthis[ callback ] = true;\n\t\treturn callback;\n\t}\n});\n\n// Detect, normalize options and install callbacks for jsonp requests\njQuery.ajaxPrefilter( \"json jsonp\", function( s, originalSettings, jqXHR ) {\n\n\tvar callbackName, overwritten, responseContainer,\n\t\tjsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?\n\t\t\t\"url\" :\n\t\t\ttypeof s.data === \"string\" && !( s.contentType || \"\" ).indexOf(\"application/x-www-form-urlencoded\") && rjsonp.test( s.data ) && \"data\"\n\t\t);\n\n\t// Handle iff the expected data type is \"jsonp\" or we have a parameter to set\n\tif ( jsonProp || s.dataTypes[ 0 ] === \"jsonp\" ) {\n\n\t\t// Get callback name, remembering preexisting value associated with it\n\t\tcallbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?\n\t\t\ts.jsonpCallback() :\n\t\t\ts.jsonpCallback;\n\n\t\t// Insert callback into url or form data\n\t\tif ( jsonProp ) {\n\t\t\ts[ jsonProp ] = s[ jsonProp ].replace( rjsonp, \"$1\" + callbackName );\n\t\t} else if ( s.jsonp !== false ) {\n\t\t\ts.url += ( ajax_rquery.test( s.url ) ? \"&\" : \"?\" ) + s.jsonp + \"=\" + callbackName;\n\t\t}\n\n\t\t// Use data converter to retrieve json after script execution\n\t\ts.converters[\"script json\"] = function() {\n\t\t\tif ( !responseContainer ) {\n\t\t\t\tjQuery.error( callbackName + \" was not called\" );\n\t\t\t}\n\t\t\treturn responseContainer[ 0 ];\n\t\t};\n\n\t\t// force json dataType\n\t\ts.dataTypes[ 0 ] = \"json\";\n\n\t\t// Install callback\n\t\toverwritten = window[ callbackName ];\n\t\twindow[ callbackName ] = function() {\n\t\t\tresponseContainer = arguments;\n\t\t};\n\n\t\t// Clean-up function (fires after converters)\n\t\tjqXHR.always(function() {\n\t\t\t// Restore preexisting value\n\t\t\twindow[ callbackName ] = overwritten;\n\n\t\t\t// Save back as free\n\t\t\tif ( s[ callbackName ] ) {\n\t\t\t\t// make sure that re-using the options doesn't screw things around\n\t\t\t\ts.jsonpCallback = originalSettings.jsonpCallback;\n\n\t\t\t\t// save the callback name for future use\n\t\t\t\toldCallbacks.push( callbackName );\n\t\t\t}\n\n\t\t\t// Call if it was a function and we have a response\n\t\t\tif ( responseContainer && jQuery.isFunction( overwritten ) ) {\n\t\t\t\toverwritten( responseContainer[ 0 ] );\n\t\t\t}\n\n\t\t\tresponseContainer = overwritten = undefined;\n\t\t});\n\n\t\t// Delegate to script\n\t\treturn \"script\";\n\t}\n});\nvar xhrCallbacks, xhrSupported,\n\txhrId = 0,\n\t// #5280: Internet Explorer will keep connections alive if we don't abort on unload\n\txhrOnUnloadAbort = window.ActiveXObject && function() {\n\t\t// Abort all pending requests\n\t\tvar key;\n\t\tfor ( key in xhrCallbacks ) {\n\t\t\txhrCallbacks[ key ]( undefined, true );\n\t\t}\n\t};\n\n// Functions to create xhrs\nfunction createStandardXHR() {\n\ttry {\n\t\treturn new window.XMLHttpRequest();\n\t} catch( e ) {}\n}\n\nfunction createActiveXHR() {\n\ttry {\n\t\treturn new window.ActiveXObject(\"Microsoft.XMLHTTP\");\n\t} catch( e ) {}\n}\n\n// Create the request object\n// (This is still attached to ajaxSettings for backward compatibility)\njQuery.ajaxSettings.xhr = window.ActiveXObject ?\n\t/* Microsoft failed to properly\n\t * implement the XMLHttpRequest in IE7 (can't request local files),\n\t * so we use the ActiveXObject when it is available\n\t * Additionally XMLHttpRequest can be disabled in IE7/IE8 so\n\t * we need a fallback.\n\t */\n\tfunction() {\n\t\treturn !this.isLocal && createStandardXHR() || createActiveXHR();\n\t} :\n\t// For all other browsers, use the standard XMLHttpRequest object\n\tcreateStandardXHR;\n\n// Determine support properties\nxhrSupported = jQuery.ajaxSettings.xhr();\njQuery.support.cors = !!xhrSupported && ( \"withCredentials\" in xhrSupported );\nxhrSupported = jQuery.support.ajax = !!xhrSupported;\n\n// Create transport if the browser can provide an xhr\nif ( xhrSupported ) {\n\n\tjQuery.ajaxTransport(function( s ) {\n\t\t// Cross domain only allowed if supported through XMLHttpRequest\n\t\tif ( !s.crossDomain || jQuery.support.cors ) {\n\n\t\t\tvar callback;\n\n\t\t\treturn {\n\t\t\t\tsend: function( headers, complete ) {\n\n\t\t\t\t\t// Get a new xhr\n\t\t\t\t\tvar handle, i,\n\t\t\t\t\t\txhr = s.xhr();\n\n\t\t\t\t\t// Open the socket\n\t\t\t\t\t// Passing null username, generates a login popup on Opera (#2865)\n\t\t\t\t\tif ( s.username ) {\n\t\t\t\t\t\txhr.open( s.type, s.url, s.async, s.username, s.password );\n\t\t\t\t\t} else {\n\t\t\t\t\t\txhr.open( s.type, s.url, s.async );\n\t\t\t\t\t}\n\n\t\t\t\t\t// Apply custom fields if provided\n\t\t\t\t\tif ( s.xhrFields ) {\n\t\t\t\t\t\tfor ( i in s.xhrFields ) {\n\t\t\t\t\t\t\txhr[ i ] = s.xhrFields[ i ];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Override mime type if needed\n\t\t\t\t\tif ( s.mimeType && xhr.overrideMimeType ) {\n\t\t\t\t\t\txhr.overrideMimeType( s.mimeType );\n\t\t\t\t\t}\n\n\t\t\t\t\t// X-Requested-With header\n\t\t\t\t\t// For cross-domain requests, seeing as conditions for a preflight are\n\t\t\t\t\t// akin to a jigsaw puzzle, we simply never set it to be sure.\n\t\t\t\t\t// (it can always be set on a per-request basis or even using ajaxSetup)\n\t\t\t\t\t// For same-domain requests, won't change header if already provided.\n\t\t\t\t\tif ( !s.crossDomain && !headers[\"X-Requested-With\"] ) {\n\t\t\t\t\t\theaders[\"X-Requested-With\"] = \"XMLHttpRequest\";\n\t\t\t\t\t}\n\n\t\t\t\t\t// Need an extra try/catch for cross domain requests in Firefox 3\n\t\t\t\t\ttry {\n\t\t\t\t\t\tfor ( i in headers ) {\n\t\t\t\t\t\t\txhr.setRequestHeader( i, headers[ i ] );\n\t\t\t\t\t\t}\n\t\t\t\t\t} catch( err ) {}\n\n\t\t\t\t\t// Do send the request\n\t\t\t\t\t// This may raise an exception which is actually\n\t\t\t\t\t// handled in jQuery.ajax (so no try/catch here)\n\t\t\t\t\txhr.send( ( s.hasContent && s.data ) || null );\n\n\t\t\t\t\t// Listener\n\t\t\t\t\tcallback = function( _, isAbort ) {\n\t\t\t\t\t\tvar status, responseHeaders, statusText, responses;\n\n\t\t\t\t\t\t// Firefox throws exceptions when accessing properties\n\t\t\t\t\t\t// of an xhr when a network error occurred\n\t\t\t\t\t\t// http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE)\n\t\t\t\t\t\ttry {\n\n\t\t\t\t\t\t\t// Was never called and is aborted or complete\n\t\t\t\t\t\t\tif ( callback && ( isAbort || xhr.readyState === 4 ) ) {\n\n\t\t\t\t\t\t\t\t// Only called once\n\t\t\t\t\t\t\t\tcallback = undefined;\n\n\t\t\t\t\t\t\t\t// Do not keep as active anymore\n\t\t\t\t\t\t\t\tif ( handle ) {\n\t\t\t\t\t\t\t\t\txhr.onreadystatechange = jQuery.noop;\n\t\t\t\t\t\t\t\t\tif ( xhrOnUnloadAbort ) {\n\t\t\t\t\t\t\t\t\t\tdelete xhrCallbacks[ handle ];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// If it's an abort\n\t\t\t\t\t\t\t\tif ( isAbort ) {\n\t\t\t\t\t\t\t\t\t// Abort it manually if needed\n\t\t\t\t\t\t\t\t\tif ( xhr.readyState !== 4 ) {\n\t\t\t\t\t\t\t\t\t\txhr.abort();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\tresponses = {};\n\t\t\t\t\t\t\t\t\tstatus = xhr.status;\n\t\t\t\t\t\t\t\t\tresponseHeaders = xhr.getAllResponseHeaders();\n\n\t\t\t\t\t\t\t\t\t// When requesting binary data, IE6-9 will throw an exception\n\t\t\t\t\t\t\t\t\t// on any attempt to access responseText (#11426)\n\t\t\t\t\t\t\t\t\tif ( typeof xhr.responseText === \"string\" ) {\n\t\t\t\t\t\t\t\t\t\tresponses.text = xhr.responseText;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Firefox throws an exception when accessing\n\t\t\t\t\t\t\t\t\t// statusText for faulty cross-domain requests\n\t\t\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t\t\tstatusText = xhr.statusText;\n\t\t\t\t\t\t\t\t\t} catch( e ) {\n\t\t\t\t\t\t\t\t\t\t// We normalize with Webkit giving an empty statusText\n\t\t\t\t\t\t\t\t\t\tstatusText = \"\";\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Filter status for non standard behaviors\n\n\t\t\t\t\t\t\t\t\t// If the request is local and we have data: assume a success\n\t\t\t\t\t\t\t\t\t// (success with no data won't get notified, that's the best we\n\t\t\t\t\t\t\t\t\t// can do given current implementations)\n\t\t\t\t\t\t\t\t\tif ( !status && s.isLocal && !s.crossDomain ) {\n\t\t\t\t\t\t\t\t\t\tstatus = responses.text ? 200 : 404;\n\t\t\t\t\t\t\t\t\t// IE - #1450: sometimes returns 1223 when it should be 204\n\t\t\t\t\t\t\t\t\t} else if ( status === 1223 ) {\n\t\t\t\t\t\t\t\t\t\tstatus = 204;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} catch( firefoxAccessException ) {\n\t\t\t\t\t\t\tif ( !isAbort ) {\n\t\t\t\t\t\t\t\tcomplete( -1, firefoxAccessException );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Call complete if needed\n\t\t\t\t\t\tif ( responses ) {\n\t\t\t\t\t\t\tcomplete( status, statusText, responses, responseHeaders );\n\t\t\t\t\t\t}\n\t\t\t\t\t};\n\n\t\t\t\t\tif ( !s.async ) {\n\t\t\t\t\t\t// if we're in sync mode we fire the callback\n\t\t\t\t\t\tcallback();\n\t\t\t\t\t} else if ( xhr.readyState === 4 ) {\n\t\t\t\t\t\t// (IE6 & IE7) if it's in cache and has been\n\t\t\t\t\t\t// retrieved directly we need to fire the callback\n\t\t\t\t\t\tsetTimeout( callback );\n\t\t\t\t\t} else {\n\t\t\t\t\t\thandle = ++xhrId;\n\t\t\t\t\t\tif ( xhrOnUnloadAbort ) {\n\t\t\t\t\t\t\t// Create the active xhrs callbacks list if needed\n\t\t\t\t\t\t\t// and attach the unload handler\n\t\t\t\t\t\t\tif ( !xhrCallbacks ) {\n\t\t\t\t\t\t\t\txhrCallbacks = {};\n\t\t\t\t\t\t\t\tjQuery( window ).unload( xhrOnUnloadAbort );\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t// Add to list of active xhrs callbacks\n\t\t\t\t\t\t\txhrCallbacks[ handle ] = callback;\n\t\t\t\t\t\t}\n\t\t\t\t\t\txhr.onreadystatechange = callback;\n\t\t\t\t\t}\n\t\t\t\t},\n\n\t\t\t\tabort: function() {\n\t\t\t\t\tif ( callback ) {\n\t\t\t\t\t\tcallback( undefined, true );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t});\n}\nvar fxNow, timerId,\n\trfxtypes = /^(?:toggle|show|hide)$/,\n\trfxnum = new RegExp( \"^(?:([+-])=|)(\" + core_pnum + \")([a-z%]*)$\", \"i\" ),\n\trrun = /queueHooks$/,\n\tanimationPrefilters = [ defaultPrefilter ],\n\ttweeners = {\n\t\t\"*\": [function( prop, value ) {\n\t\t\tvar tween = this.createTween( prop, value ),\n\t\t\t\ttarget = tween.cur(),\n\t\t\t\tparts = rfxnum.exec( value ),\n\t\t\t\tunit = parts && parts[ 3 ] || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" ),\n\n\t\t\t\t// Starting value computation is required for potential unit mismatches\n\t\t\t\tstart = ( jQuery.cssNumber[ prop ] || unit !== \"px\" && +target ) &&\n\t\t\t\t\trfxnum.exec( jQuery.css( tween.elem, prop ) ),\n\t\t\t\tscale = 1,\n\t\t\t\tmaxIterations = 20;\n\n\t\t\tif ( start && start[ 3 ] !== unit ) {\n\t\t\t\t// Trust units reported by jQuery.css\n\t\t\t\tunit = unit || start[ 3 ];\n\n\t\t\t\t// Make sure we update the tween properties later on\n\t\t\t\tparts = parts || [];\n\n\t\t\t\t// Iteratively approximate from a nonzero starting point\n\t\t\t\tstart = +target || 1;\n\n\t\t\t\tdo {\n\t\t\t\t\t// If previous iteration zeroed out, double until we get *something*\n\t\t\t\t\t// Use a string for doubling factor so we don't accidentally see scale as unchanged below\n\t\t\t\t\tscale = scale || \".5\";\n\n\t\t\t\t\t// Adjust and apply\n\t\t\t\t\tstart = start / scale;\n\t\t\t\t\tjQuery.style( tween.elem, prop, start + unit );\n\n\t\t\t\t// Update scale, tolerating zero or NaN from tween.cur()\n\t\t\t\t// And breaking the loop if scale is unchanged or perfect, or if we've just had enough\n\t\t\t\t} while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations );\n\t\t\t}\n\n\t\t\t// Update tween properties\n\t\t\tif ( parts ) {\n\t\t\t\tstart = tween.start = +start || +target || 0;\n\t\t\t\ttween.unit = unit;\n\t\t\t\t// If a +=/-= token was provided, we're doing a relative animation\n\t\t\t\ttween.end = parts[ 1 ] ?\n\t\t\t\t\tstart + ( parts[ 1 ] + 1 ) * parts[ 2 ] :\n\t\t\t\t\t+parts[ 2 ];\n\t\t\t}\n\n\t\t\treturn tween;\n\t\t}]\n\t};\n\n// Animations created synchronously will run synchronously\nfunction createFxNow() {\n\tsetTimeout(function() {\n\t\tfxNow = undefined;\n\t});\n\treturn ( fxNow = jQuery.now() );\n}\n\nfunction createTween( value, prop, animation ) {\n\tvar tween,\n\t\tcollection = ( tweeners[ prop ] || [] ).concat( tweeners[ \"*\" ] ),\n\t\tindex = 0,\n\t\tlength = collection.length;\n\tfor ( ; index < length; index++ ) {\n\t\tif ( (tween = collection[ index ].call( animation, prop, value )) ) {\n\n\t\t\t// we're done with this property\n\t\t\treturn tween;\n\t\t}\n\t}\n}\n\nfunction Animation( elem, properties, options ) {\n\tvar result,\n\t\tstopped,\n\t\tindex = 0,\n\t\tlength = animationPrefilters.length,\n\t\tdeferred = jQuery.Deferred().always( function() {\n\t\t\t// don't match elem in the :animated selector\n\t\t\tdelete tick.elem;\n\t\t}),\n\t\ttick = function() {\n\t\t\tif ( stopped ) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tvar currentTime = fxNow || createFxNow(),\n\t\t\t\tremaining = Math.max( 0, animation.startTime + animation.duration - currentTime ),\n\t\t\t\t// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497)\n\t\t\t\ttemp = remaining / animation.duration || 0,\n\t\t\t\tpercent = 1 - temp,\n\t\t\t\tindex = 0,\n\t\t\t\tlength = animation.tweens.length;\n\n\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\tanimation.tweens[ index ].run( percent );\n\t\t\t}\n\n\t\t\tdeferred.notifyWith( elem, [ animation, percent, remaining ]);\n\n\t\t\tif ( percent < 1 && length ) {\n\t\t\t\treturn remaining;\n\t\t\t} else {\n\t\t\t\tdeferred.resolveWith( elem, [ animation ] );\n\t\t\t\treturn false;\n\t\t\t}\n\t\t},\n\t\tanimation = deferred.promise({\n\t\t\telem: elem,\n\t\t\tprops: jQuery.extend( {}, properties ),\n\t\t\topts: jQuery.extend( true, { specialEasing: {} }, options ),\n\t\t\toriginalProperties: properties,\n\t\t\toriginalOptions: options,\n\t\t\tstartTime: fxNow || createFxNow(),\n\t\t\tduration: options.duration,\n\t\t\ttweens: [],\n\t\t\tcreateTween: function( prop, end ) {\n\t\t\t\tvar tween = jQuery.Tween( elem, animation.opts, prop, end,\n\t\t\t\t\t\tanimation.opts.specialEasing[ prop ] || animation.opts.easing );\n\t\t\t\tanimation.tweens.push( tween );\n\t\t\t\treturn tween;\n\t\t\t},\n\t\t\tstop: function( gotoEnd ) {\n\t\t\t\tvar index = 0,\n\t\t\t\t\t// if we are going to the end, we want to run all the tweens\n\t\t\t\t\t// otherwise we skip this part\n\t\t\t\t\tlength = gotoEnd ? animation.tweens.length : 0;\n\t\t\t\tif ( stopped ) {\n\t\t\t\t\treturn this;\n\t\t\t\t}\n\t\t\t\tstopped = true;\n\t\t\t\tfor ( ; index < length ; index++ ) {\n\t\t\t\t\tanimation.tweens[ index ].run( 1 );\n\t\t\t\t}\n\n\t\t\t\t// resolve when we played the last frame\n\t\t\t\t// otherwise, reject\n\t\t\t\tif ( gotoEnd ) {\n\t\t\t\t\tdeferred.resolveWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t} else {\n\t\t\t\t\tdeferred.rejectWith( elem, [ animation, gotoEnd ] );\n\t\t\t\t}\n\t\t\t\treturn this;\n\t\t\t}\n\t\t}),\n\t\tprops = animation.props;\n\n\tpropFilter( props, animation.opts.specialEasing );\n\n\tfor ( ; index < length ; index++ ) {\n\t\tresult = animationPrefilters[ index ].call( animation, elem, props, animation.opts );\n\t\tif ( result ) {\n\t\t\treturn result;\n\t\t}\n\t}\n\n\tjQuery.map( props, createTween, animation );\n\n\tif ( jQuery.isFunction( animation.opts.start ) ) {\n\t\tanimation.opts.start.call( elem, animation );\n\t}\n\n\tjQuery.fx.timer(\n\t\tjQuery.extend( tick, {\n\t\t\telem: elem,\n\t\t\tanim: animation,\n\t\t\tqueue: animation.opts.queue\n\t\t})\n\t);\n\n\t// attach callbacks from options\n\treturn animation.progress( animation.opts.progress )\n\t\t.done( animation.opts.done, animation.opts.complete )\n\t\t.fail( animation.opts.fail )\n\t\t.always( animation.opts.always );\n}\n\nfunction propFilter( props, specialEasing ) {\n\tvar index, name, easing, value, hooks;\n\n\t// camelCase, specialEasing and expand cssHook pass\n\tfor ( index in props ) {\n\t\tname = jQuery.camelCase( index );\n\t\teasing = specialEasing[ name ];\n\t\tvalue = props[ index ];\n\t\tif ( jQuery.isArray( value ) ) {\n\t\t\teasing = value[ 1 ];\n\t\t\tvalue = props[ index ] = value[ 0 ];\n\t\t}\n\n\t\tif ( index !== name ) {\n\t\t\tprops[ name ] = value;\n\t\t\tdelete props[ index ];\n\t\t}\n\n\t\thooks = jQuery.cssHooks[ name ];\n\t\tif ( hooks && \"expand\" in hooks ) {\n\t\t\tvalue = hooks.expand( value );\n\t\t\tdelete props[ name ];\n\n\t\t\t// not quite $.extend, this wont overwrite keys already present.\n\t\t\t// also - reusing 'index' from above because we have the correct \"name\"\n\t\t\tfor ( index in value ) {\n\t\t\t\tif ( !( index in props ) ) {\n\t\t\t\t\tprops[ index ] = value[ index ];\n\t\t\t\t\tspecialEasing[ index ] = easing;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tspecialEasing[ name ] = easing;\n\t\t}\n\t}\n}\n\njQuery.Animation = jQuery.extend( Animation, {\n\n\ttweener: function( props, callback ) {\n\t\tif ( jQuery.isFunction( props ) ) {\n\t\t\tcallback = props;\n\t\t\tprops = [ \"*\" ];\n\t\t} else {\n\t\t\tprops = props.split(\" \");\n\t\t}\n\n\t\tvar prop,\n\t\t\tindex = 0,\n\t\t\tlength = props.length;\n\n\t\tfor ( ; index < length ; index++ ) {\n\t\t\tprop = props[ index ];\n\t\t\ttweeners[ prop ] = tweeners[ prop ] || [];\n\t\t\ttweeners[ prop ].unshift( callback );\n\t\t}\n\t},\n\n\tprefilter: function( callback, prepend ) {\n\t\tif ( prepend ) {\n\t\t\tanimationPrefilters.unshift( callback );\n\t\t} else {\n\t\t\tanimationPrefilters.push( callback );\n\t\t}\n\t}\n});\n\nfunction defaultPrefilter( elem, props, opts ) {\n\t/* jshint validthis: true */\n\tvar prop, value, toggle, tween, hooks, oldfire,\n\t\tanim = this,\n\t\torig = {},\n\t\tstyle = elem.style,\n\t\thidden = elem.nodeType && isHidden( elem ),\n\t\tdataShow = jQuery._data( elem, \"fxshow\" );\n\n\t// handle queue: false promises\n\tif ( !opts.queue ) {\n\t\thooks = jQuery._queueHooks( elem, \"fx\" );\n\t\tif ( hooks.unqueued == null ) {\n\t\t\thooks.unqueued = 0;\n\t\t\toldfire = hooks.empty.fire;\n\t\t\thooks.empty.fire = function() {\n\t\t\t\tif ( !hooks.unqueued ) {\n\t\t\t\t\toldfire();\n\t\t\t\t}\n\t\t\t};\n\t\t}\n\t\thooks.unqueued++;\n\n\t\tanim.always(function() {\n\t\t\t// doing this makes sure that the complete handler will be called\n\t\t\t// before this completes\n\t\t\tanim.always(function() {\n\t\t\t\thooks.unqueued--;\n\t\t\t\tif ( !jQuery.queue( elem, \"fx\" ).length ) {\n\t\t\t\t\thooks.empty.fire();\n\t\t\t\t}\n\t\t\t});\n\t\t});\n\t}\n\n\t// height/width overflow pass\n\tif ( elem.nodeType === 1 && ( \"height\" in props || \"width\" in props ) ) {\n\t\t// Make sure that nothing sneaks out\n\t\t// Record all 3 overflow attributes because IE does not\n\t\t// change the overflow attribute when overflowX and\n\t\t// overflowY are set to the same value\n\t\topts.overflow = [ style.overflow, style.overflowX, style.overflowY ];\n\n\t\t// Set display property to inline-block for height/width\n\t\t// animations on inline elements that are having width/height animated\n\t\tif ( jQuery.css( elem, \"display\" ) === \"inline\" &&\n\t\t\t\tjQuery.css( elem, \"float\" ) === \"none\" ) {\n\n\t\t\t// inline-level elements accept inline-block;\n\t\t\t// block-level elements need to be inline with layout\n\t\t\tif ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === \"inline\" ) {\n\t\t\t\tstyle.display = \"inline-block\";\n\n\t\t\t} else {\n\t\t\t\tstyle.zoom = 1;\n\t\t\t}\n\t\t}\n\t}\n\n\tif ( opts.overflow ) {\n\t\tstyle.overflow = \"hidden\";\n\t\tif ( !jQuery.support.shrinkWrapBlocks ) {\n\t\t\tanim.always(function() {\n\t\t\t\tstyle.overflow = opts.overflow[ 0 ];\n\t\t\t\tstyle.overflowX = opts.overflow[ 1 ];\n\t\t\t\tstyle.overflowY = opts.overflow[ 2 ];\n\t\t\t});\n\t\t}\n\t}\n\n\n\t// show/hide pass\n\tfor ( prop in props ) {\n\t\tvalue = props[ prop ];\n\t\tif ( rfxtypes.exec( value ) ) {\n\t\t\tdelete props[ prop ];\n\t\t\ttoggle = toggle || value === \"toggle\";\n\t\t\tif ( value === ( hidden ? \"hide\" : \"show\" ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\torig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );\n\t\t}\n\t}\n\n\tif ( !jQuery.isEmptyObject( orig ) ) {\n\t\tif ( dataShow ) {\n\t\t\tif ( \"hidden\" in dataShow ) {\n\t\t\t\thidden = dataShow.hidden;\n\t\t\t}\n\t\t} else {\n\t\t\tdataShow = jQuery._data( elem, \"fxshow\", {} );\n\t\t}\n\n\t\t// store state if its toggle - enables .stop().toggle() to \"reverse\"\n\t\tif ( toggle ) {\n\t\t\tdataShow.hidden = !hidden;\n\t\t}\n\t\tif ( hidden ) {\n\t\t\tjQuery( elem ).show();\n\t\t} else {\n\t\t\tanim.done(function() {\n\t\t\t\tjQuery( elem ).hide();\n\t\t\t});\n\t\t}\n\t\tanim.done(function() {\n\t\t\tvar prop;\n\t\t\tjQuery._removeData( elem, \"fxshow\" );\n\t\t\tfor ( prop in orig ) {\n\t\t\t\tjQuery.style( elem, prop, orig[ prop ] );\n\t\t\t}\n\t\t});\n\t\tfor ( prop in orig ) {\n\t\t\ttween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );\n\n\t\t\tif ( !( prop in dataShow ) ) {\n\t\t\t\tdataShow[ prop ] = tween.start;\n\t\t\t\tif ( hidden ) {\n\t\t\t\t\ttween.end = tween.start;\n\t\t\t\t\ttween.start = prop === \"width\" || prop === \"height\" ? 1 : 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction Tween( elem, options, prop, end, easing ) {\n\treturn new Tween.prototype.init( elem, options, prop, end, easing );\n}\njQuery.Tween = Tween;\n\nTween.prototype = {\n\tconstructor: Tween,\n\tinit: function( elem, options, prop, end, easing, unit ) {\n\t\tthis.elem = elem;\n\t\tthis.prop = prop;\n\t\tthis.easing = easing || \"swing\";\n\t\tthis.options = options;\n\t\tthis.start = this.now = this.cur();\n\t\tthis.end = end;\n\t\tthis.unit = unit || ( jQuery.cssNumber[ prop ] ? \"\" : \"px\" );\n\t},\n\tcur: function() {\n\t\tvar hooks = Tween.propHooks[ this.prop ];\n\n\t\treturn hooks && hooks.get ?\n\t\t\thooks.get( this ) :\n\t\t\tTween.propHooks._default.get( this );\n\t},\n\trun: function( percent ) {\n\t\tvar eased,\n\t\t\thooks = Tween.propHooks[ this.prop ];\n\n\t\tif ( this.options.duration ) {\n\t\t\tthis.pos = eased = jQuery.easing[ this.easing ](\n\t\t\t\tpercent, this.options.duration * percent, 0, 1, this.options.duration\n\t\t\t);\n\t\t} else {\n\t\t\tthis.pos = eased = percent;\n\t\t}\n\t\tthis.now = ( this.end - this.start ) * eased + this.start;\n\n\t\tif ( this.options.step ) {\n\t\t\tthis.options.step.call( this.elem, this.now, this );\n\t\t}\n\n\t\tif ( hooks && hooks.set ) {\n\t\t\thooks.set( this );\n\t\t} else {\n\t\t\tTween.propHooks._default.set( this );\n\t\t}\n\t\treturn this;\n\t}\n};\n\nTween.prototype.init.prototype = Tween.prototype;\n\nTween.propHooks = {\n\t_default: {\n\t\tget: function( tween ) {\n\t\t\tvar result;\n\n\t\t\tif ( tween.elem[ tween.prop ] != null &&\n\t\t\t\t(!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) {\n\t\t\t\treturn tween.elem[ tween.prop ];\n\t\t\t}\n\n\t\t\t// passing an empty string as a 3rd parameter to .css will automatically\n\t\t\t// attempt a parseFloat and fallback to a string if the parse fails\n\t\t\t// so, simple values such as \"10px\" are parsed to Float.\n\t\t\t// complex values such as \"rotate(1rad)\" are returned as is.\n\t\t\tresult = jQuery.css( tween.elem, tween.prop, \"\" );\n\t\t\t// Empty strings, null, undefined and \"auto\" are converted to 0.\n\t\t\treturn !result || result === \"auto\" ? 0 : result;\n\t\t},\n\t\tset: function( tween ) {\n\t\t\t// use step hook for back compat - use cssHook if its there - use .style if its\n\t\t\t// available and use plain properties where available\n\t\t\tif ( jQuery.fx.step[ tween.prop ] ) {\n\t\t\t\tjQuery.fx.step[ tween.prop ]( tween );\n\t\t\t} else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) {\n\t\t\t\tjQuery.style( tween.elem, tween.prop, tween.now + tween.unit );\n\t\t\t} else {\n\t\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t\t}\n\t\t}\n\t}\n};\n\n// Support: IE <=9\n// Panic based approach to setting things on disconnected nodes\n\nTween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {\n\tset: function( tween ) {\n\t\tif ( tween.elem.nodeType && tween.elem.parentNode ) {\n\t\t\ttween.elem[ tween.prop ] = tween.now;\n\t\t}\n\t}\n};\n\njQuery.each([ \"toggle\", \"show\", \"hide\" ], function( i, name ) {\n\tvar cssFn = jQuery.fn[ name ];\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn speed == null || typeof speed === \"boolean\" ?\n\t\t\tcssFn.apply( this, arguments ) :\n\t\t\tthis.animate( genFx( name, true ), speed, easing, callback );\n\t};\n});\n\njQuery.fn.extend({\n\tfadeTo: function( speed, to, easing, callback ) {\n\n\t\t// show any hidden elements after setting opacity to 0\n\t\treturn this.filter( isHidden ).css( \"opacity\", 0 ).show()\n\n\t\t\t// animate to the value specified\n\t\t\t.end().animate({ opacity: to }, speed, easing, callback );\n\t},\n\tanimate: function( prop, speed, easing, callback ) {\n\t\tvar empty = jQuery.isEmptyObject( prop ),\n\t\t\toptall = jQuery.speed( speed, easing, callback ),\n\t\t\tdoAnimation = function() {\n\t\t\t\t// Operate on a copy of prop so per-property easing won't be lost\n\t\t\t\tvar anim = Animation( this, jQuery.extend( {}, prop ), optall );\n\n\t\t\t\t// Empty animations, or finishing resolves immediately\n\t\t\t\tif ( empty || jQuery._data( this, \"finish\" ) ) {\n\t\t\t\t\tanim.stop( true );\n\t\t\t\t}\n\t\t\t};\n\t\t\tdoAnimation.finish = doAnimation;\n\n\t\treturn empty || optall.queue === false ?\n\t\t\tthis.each( doAnimation ) :\n\t\t\tthis.queue( optall.queue, doAnimation );\n\t},\n\tstop: function( type, clearQueue, gotoEnd ) {\n\t\tvar stopQueue = function( hooks ) {\n\t\t\tvar stop = hooks.stop;\n\t\t\tdelete hooks.stop;\n\t\t\tstop( gotoEnd );\n\t\t};\n\n\t\tif ( typeof type !== \"string\" ) {\n\t\t\tgotoEnd = clearQueue;\n\t\t\tclearQueue = type;\n\t\t\ttype = undefined;\n\t\t}\n\t\tif ( clearQueue && type !== false ) {\n\t\t\tthis.queue( type || \"fx\", [] );\n\t\t}\n\n\t\treturn this.each(function() {\n\t\t\tvar dequeue = true,\n\t\t\t\tindex = type != null && type + \"queueHooks\",\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tdata = jQuery._data( this );\n\n\t\t\tif ( index ) {\n\t\t\t\tif ( data[ index ] && data[ index ].stop ) {\n\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tfor ( index in data ) {\n\t\t\t\t\tif ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {\n\t\t\t\t\t\tstopQueue( data[ index ] );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) {\n\t\t\t\t\ttimers[ index ].anim.stop( gotoEnd );\n\t\t\t\t\tdequeue = false;\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// start the next in the queue if the last step wasn't forced\n\t\t\t// timers currently will call their complete callbacks, which will dequeue\n\t\t\t// but only if they were gotoEnd\n\t\t\tif ( dequeue || !gotoEnd ) {\n\t\t\t\tjQuery.dequeue( this, type );\n\t\t\t}\n\t\t});\n\t},\n\tfinish: function( type ) {\n\t\tif ( type !== false ) {\n\t\t\ttype = type || \"fx\";\n\t\t}\n\t\treturn this.each(function() {\n\t\t\tvar index,\n\t\t\t\tdata = jQuery._data( this ),\n\t\t\t\tqueue = data[ type + \"queue\" ],\n\t\t\t\thooks = data[ type + \"queueHooks\" ],\n\t\t\t\ttimers = jQuery.timers,\n\t\t\t\tlength = queue ? queue.length : 0;\n\n\t\t\t// enable finishing flag on private data\n\t\t\tdata.finish = true;\n\n\t\t\t// empty the queue first\n\t\t\tjQuery.queue( this, type, [] );\n\n\t\t\tif ( hooks && hooks.stop ) {\n\t\t\t\thooks.stop.call( this, true );\n\t\t\t}\n\n\t\t\t// look for any active animations, and finish them\n\t\t\tfor ( index = timers.length; index--; ) {\n\t\t\t\tif ( timers[ index ].elem === this && timers[ index ].queue === type ) {\n\t\t\t\t\ttimers[ index ].anim.stop( true );\n\t\t\t\t\ttimers.splice( index, 1 );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// look for any animations in the old queue and finish them\n\t\t\tfor ( index = 0; index < length; index++ ) {\n\t\t\t\tif ( queue[ index ] && queue[ index ].finish ) {\n\t\t\t\t\tqueue[ index ].finish.call( this );\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// turn off finishing flag\n\t\t\tdelete data.finish;\n\t\t});\n\t}\n});\n\n// Generate parameters to create a standard animation\nfunction genFx( type, includeWidth ) {\n\tvar which,\n\t\tattrs = { height: type },\n\t\ti = 0;\n\n\t// if we include width, step value is 1 to do all cssExpand values,\n\t// if we don't include width, step value is 2 to skip over Left and Right\n\tincludeWidth = includeWidth? 1 : 0;\n\tfor( ; i < 4 ; i += 2 - includeWidth ) {\n\t\twhich = cssExpand[ i ];\n\t\tattrs[ \"margin\" + which ] = attrs[ \"padding\" + which ] = type;\n\t}\n\n\tif ( includeWidth ) {\n\t\tattrs.opacity = attrs.width = type;\n\t}\n\n\treturn attrs;\n}\n\n// Generate shortcuts for custom animations\njQuery.each({\n\tslideDown: genFx(\"show\"),\n\tslideUp: genFx(\"hide\"),\n\tslideToggle: genFx(\"toggle\"),\n\tfadeIn: { opacity: \"show\" },\n\tfadeOut: { opacity: \"hide\" },\n\tfadeToggle: { opacity: \"toggle\" }\n}, function( name, props ) {\n\tjQuery.fn[ name ] = function( speed, easing, callback ) {\n\t\treturn this.animate( props, speed, easing, callback );\n\t};\n});\n\njQuery.speed = function( speed, easing, fn ) {\n\tvar opt = speed && typeof speed === \"object\" ? jQuery.extend( {}, speed ) : {\n\t\tcomplete: fn || !fn && easing ||\n\t\t\tjQuery.isFunction( speed ) && speed,\n\t\tduration: speed,\n\t\teasing: fn && easing || easing && !jQuery.isFunction( easing ) && easing\n\t};\n\n\topt.duration = jQuery.fx.off ? 0 : typeof opt.duration === \"number\" ? opt.duration :\n\t\topt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default;\n\n\t// normalize opt.queue - true/undefined/null -> \"fx\"\n\tif ( opt.queue == null || opt.queue === true ) {\n\t\topt.queue = \"fx\";\n\t}\n\n\t// Queueing\n\topt.old = opt.complete;\n\n\topt.complete = function() {\n\t\tif ( jQuery.isFunction( opt.old ) ) {\n\t\t\topt.old.call( this );\n\t\t}\n\n\t\tif ( opt.queue ) {\n\t\t\tjQuery.dequeue( this, opt.queue );\n\t\t}\n\t};\n\n\treturn opt;\n};\n\njQuery.easing = {\n\tlinear: function( p ) {\n\t\treturn p;\n\t},\n\tswing: function( p ) {\n\t\treturn 0.5 - Math.cos( p*Math.PI ) / 2;\n\t}\n};\n\njQuery.timers = [];\njQuery.fx = Tween.prototype.init;\njQuery.fx.tick = function() {\n\tvar timer,\n\t\ttimers = jQuery.timers,\n\t\ti = 0;\n\n\tfxNow = jQuery.now();\n\n\tfor ( ; i < timers.length; i++ ) {\n\t\ttimer = timers[ i ];\n\t\t// Checks the timer has not already been removed\n\t\tif ( !timer() && timers[ i ] === timer ) {\n\t\t\ttimers.splice( i--, 1 );\n\t\t}\n\t}\n\n\tif ( !timers.length ) {\n\t\tjQuery.fx.stop();\n\t}\n\tfxNow = undefined;\n};\n\njQuery.fx.timer = function( timer ) {\n\tif ( timer() && jQuery.timers.push( timer ) ) {\n\t\tjQuery.fx.start();\n\t}\n};\n\njQuery.fx.interval = 13;\n\njQuery.fx.start = function() {\n\tif ( !timerId ) {\n\t\ttimerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );\n\t}\n};\n\njQuery.fx.stop = function() {\n\tclearInterval( timerId );\n\ttimerId = null;\n};\n\njQuery.fx.speeds = {\n\tslow: 600,\n\tfast: 200,\n\t// Default speed\n\t_default: 400\n};\n\n// Back Compat <1.8 extension point\njQuery.fx.step = {};\n\nif ( jQuery.expr && jQuery.expr.filters ) {\n\tjQuery.expr.filters.animated = function( elem ) {\n\t\treturn jQuery.grep(jQuery.timers, function( fn ) {\n\t\t\treturn elem === fn.elem;\n\t\t}).length;\n\t};\n}\njQuery.fn.offset = function( options ) {\n\tif ( arguments.length ) {\n\t\treturn options === undefined ?\n\t\t\tthis :\n\t\t\tthis.each(function( i ) {\n\t\t\t\tjQuery.offset.setOffset( this, options, i );\n\t\t\t});\n\t}\n\n\tvar docElem, win,\n\t\tbox = { top: 0, left: 0 },\n\t\telem = this[ 0 ],\n\t\tdoc = elem && elem.ownerDocument;\n\n\tif ( !doc ) {\n\t\treturn;\n\t}\n\n\tdocElem = doc.documentElement;\n\n\t// Make sure it's not a disconnected DOM node\n\tif ( !jQuery.contains( docElem, elem ) ) {\n\t\treturn box;\n\t}\n\n\t// If we don't have gBCR, just use 0,0 rather than error\n\t// BlackBerry 5, iOS 3 (original iPhone)\n\tif ( typeof elem.getBoundingClientRect !== core_strundefined ) {\n\t\tbox = elem.getBoundingClientRect();\n\t}\n\twin = getWindow( doc );\n\treturn {\n\t\ttop: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),\n\t\tleft: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )\n\t};\n};\n\njQuery.offset = {\n\n\tsetOffset: function( elem, options, i ) {\n\t\tvar position = jQuery.css( elem, \"position\" );\n\n\t\t// set position first, in-case top/left are set even on static elem\n\t\tif ( position === \"static\" ) {\n\t\t\telem.style.position = \"relative\";\n\t\t}\n\n\t\tvar curElem = jQuery( elem ),\n\t\t\tcurOffset = curElem.offset(),\n\t\t\tcurCSSTop = jQuery.css( elem, \"top\" ),\n\t\t\tcurCSSLeft = jQuery.css( elem, \"left\" ),\n\t\t\tcalculatePosition = ( position === \"absolute\" || position === \"fixed\" ) && jQuery.inArray(\"auto\", [curCSSTop, curCSSLeft]) > -1,\n\t\t\tprops = {}, curPosition = {}, curTop, curLeft;\n\n\t\t// need to be able to calculate position if either top or left is auto and position is either absolute or fixed\n\t\tif ( calculatePosition ) {\n\t\t\tcurPosition = curElem.position();\n\t\t\tcurTop = curPosition.top;\n\t\t\tcurLeft = curPosition.left;\n\t\t} else {\n\t\t\tcurTop = parseFloat( curCSSTop ) || 0;\n\t\t\tcurLeft = parseFloat( curCSSLeft ) || 0;\n\t\t}\n\n\t\tif ( jQuery.isFunction( options ) ) {\n\t\t\toptions = options.call( elem, i, curOffset );\n\t\t}\n\n\t\tif ( options.top != null ) {\n\t\t\tprops.top = ( options.top - curOffset.top ) + curTop;\n\t\t}\n\t\tif ( options.left != null ) {\n\t\t\tprops.left = ( options.left - curOffset.left ) + curLeft;\n\t\t}\n\n\t\tif ( \"using\" in options ) {\n\t\t\toptions.using.call( elem, props );\n\t\t} else {\n\t\t\tcurElem.css( props );\n\t\t}\n\t}\n};\n\n\njQuery.fn.extend({\n\n\tposition: function() {\n\t\tif ( !this[ 0 ] ) {\n\t\t\treturn;\n\t\t}\n\n\t\tvar offsetParent, offset,\n\t\t\tparentOffset = { top: 0, left: 0 },\n\t\t\telem = this[ 0 ];\n\n\t\t// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent\n\t\tif ( jQuery.css( elem, \"position\" ) === \"fixed\" ) {\n\t\t\t// we assume that getBoundingClientRect is available when computed position is fixed\n\t\t\toffset = elem.getBoundingClientRect();\n\t\t} else {\n\t\t\t// Get *real* offsetParent\n\t\t\toffsetParent = this.offsetParent();\n\n\t\t\t// Get correct offsets\n\t\t\toffset = this.offset();\n\t\t\tif ( !jQuery.nodeName( offsetParent[ 0 ], \"html\" ) ) {\n\t\t\t\tparentOffset = offsetParent.offset();\n\t\t\t}\n\n\t\t\t// Add offsetParent borders\n\t\t\tparentOffset.top  += jQuery.css( offsetParent[ 0 ], \"borderTopWidth\", true );\n\t\t\tparentOffset.left += jQuery.css( offsetParent[ 0 ], \"borderLeftWidth\", true );\n\t\t}\n\n\t\t// Subtract parent offsets and element margins\n\t\t// note: when an element has margin: auto the offsetLeft and marginLeft\n\t\t// are the same in Safari causing offset.left to incorrectly be 0\n\t\treturn {\n\t\t\ttop:  offset.top  - parentOffset.top - jQuery.css( elem, \"marginTop\", true ),\n\t\t\tleft: offset.left - parentOffset.left - jQuery.css( elem, \"marginLeft\", true)\n\t\t};\n\t},\n\n\toffsetParent: function() {\n\t\treturn this.map(function() {\n\t\t\tvar offsetParent = this.offsetParent || docElem;\n\t\t\twhile ( offsetParent && ( !jQuery.nodeName( offsetParent, \"html\" ) && jQuery.css( offsetParent, \"position\") === \"static\" ) ) {\n\t\t\t\toffsetParent = offsetParent.offsetParent;\n\t\t\t}\n\t\t\treturn offsetParent || docElem;\n\t\t});\n\t}\n});\n\n\n// Create scrollLeft and scrollTop methods\njQuery.each( {scrollLeft: \"pageXOffset\", scrollTop: \"pageYOffset\"}, function( method, prop ) {\n\tvar top = /Y/.test( prop );\n\n\tjQuery.fn[ method ] = function( val ) {\n\t\treturn jQuery.access( this, function( elem, method, val ) {\n\t\t\tvar win = getWindow( elem );\n\n\t\t\tif ( val === undefined ) {\n\t\t\t\treturn win ? (prop in win) ? win[ prop ] :\n\t\t\t\t\twin.document.documentElement[ method ] :\n\t\t\t\t\telem[ method ];\n\t\t\t}\n\n\t\t\tif ( win ) {\n\t\t\t\twin.scrollTo(\n\t\t\t\t\t!top ? val : jQuery( win ).scrollLeft(),\n\t\t\t\t\ttop ? val : jQuery( win ).scrollTop()\n\t\t\t\t);\n\n\t\t\t} else {\n\t\t\t\telem[ method ] = val;\n\t\t\t}\n\t\t}, method, val, arguments.length, null );\n\t};\n});\n\nfunction getWindow( elem ) {\n\treturn jQuery.isWindow( elem ) ?\n\t\telem :\n\t\telem.nodeType === 9 ?\n\t\t\telem.defaultView || elem.parentWindow :\n\t\t\tfalse;\n}\n// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods\njQuery.each( { Height: \"height\", Width: \"width\" }, function( name, type ) {\n\tjQuery.each( { padding: \"inner\" + name, content: type, \"\": \"outer\" + name }, function( defaultExtra, funcName ) {\n\t\t// margin is only for outerHeight, outerWidth\n\t\tjQuery.fn[ funcName ] = function( margin, value ) {\n\t\t\tvar chainable = arguments.length && ( defaultExtra || typeof margin !== \"boolean\" ),\n\t\t\t\textra = defaultExtra || ( margin === true || value === true ? \"margin\" : \"border\" );\n\n\t\t\treturn jQuery.access( this, function( elem, type, value ) {\n\t\t\t\tvar doc;\n\n\t\t\t\tif ( jQuery.isWindow( elem ) ) {\n\t\t\t\t\t// As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there\n\t\t\t\t\t// isn't a whole lot we can do. See pull request at this URL for discussion:\n\t\t\t\t\t// https://github.com/jquery/jquery/pull/764\n\t\t\t\t\treturn elem.document.documentElement[ \"client\" + name ];\n\t\t\t\t}\n\n\t\t\t\t// Get document width or height\n\t\t\t\tif ( elem.nodeType === 9 ) {\n\t\t\t\t\tdoc = elem.documentElement;\n\n\t\t\t\t\t// Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest\n\t\t\t\t\t// unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it.\n\t\t\t\t\treturn Math.max(\n\t\t\t\t\t\telem.body[ \"scroll\" + name ], doc[ \"scroll\" + name ],\n\t\t\t\t\t\telem.body[ \"offset\" + name ], doc[ \"offset\" + name ],\n\t\t\t\t\t\tdoc[ \"client\" + name ]\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\treturn value === undefined ?\n\t\t\t\t\t// Get width or height on the element, requesting but not forcing parseFloat\n\t\t\t\t\tjQuery.css( elem, type, extra ) :\n\n\t\t\t\t\t// Set width or height on the element\n\t\t\t\t\tjQuery.style( elem, type, value, extra );\n\t\t\t}, type, chainable ? margin : undefined, chainable, null );\n\t\t};\n\t});\n});\n// Limit scope pollution from any deprecated API\n// (function() {\n\n// The number of elements contained in the matched element set\njQuery.fn.size = function() {\n\treturn this.length;\n};\n\njQuery.fn.andSelf = jQuery.fn.addBack;\n\n// })();\nif ( typeof module === \"object\" && module && typeof module.exports === \"object\" ) {\n\t// Expose jQuery as module.exports in loaders that implement the Node\n\t// module pattern (including browserify). Do not create the global, since\n\t// the user will be storing it themselves locally, and globals are frowned\n\t// upon in the Node module world.\n\tmodule.exports = jQuery;\n} else {\n\t// Otherwise expose jQuery to the global object as usual\n\twindow.jQuery = window.$ = jQuery;\n\n\t// Register as a named AMD module, since jQuery can be concatenated with other\n\t// files that may use define, but not via a proper concatenation script that\n\t// understands anonymous AMD modules. A named AMD is safest and most robust\n\t// way to register. Lowercase jquery is used because AMD module names are\n\t// derived from file names, and jQuery is normally delivered in a lowercase\n\t// file name. Do this after creating the global so that if an AMD module wants\n\t// to call noConflict to hide this version of jQuery, it will work.\n\tif ( typeof define === \"function\" && define.amd ) {\n\t\tdefine( \"jquery\", [], function () { return jQuery; } );\n\t}\n}\n\n})( window );\n"
  },
  {
    "path": "public/static/ueditor/third-party/video-js/video-js.css",
    "content": "/*!\nVideo.js Default Styles (http://videojs.com)\nVersion 4.3.0\nCreate your own skin at http://designer.videojs.com\n*/\n/* SKIN\n================================================================================\nThe main class name for all skin-specific styles. To make your own skin,\nreplace all occurances of 'vjs-default-skin' with a new name. Then add your new\nskin name to your video tag instead of the default skin.\ne.g. <video class=\"video-js my-skin-name\">\n*/\n.vjs-default-skin {\n  color: #cccccc;\n}\n/* Custom Icon Font\n--------------------------------------------------------------------------------\nThe control icons are from a custom font. Each icon corresponds to a character\n(e.g. \"\\e001\"). Font icons allow for easy scaling and coloring of icons.\n*/\n@font-face {\n  font-family: 'VideoJS';\n  src: url('font/vjs.eot');\n  src: url('font/vjs.eot?#iefix') format('embedded-opentype'), url('font/vjs.woff') format('woff'), url('font/vjs.ttf') format('truetype');\n  font-weight: normal;\n  font-style: normal;\n}\n/* Base UI Component Classes\n--------------------------------------------------------------------------------\n*/\n/* Slider - used for Volume bar and Seek bar */\n.vjs-default-skin .vjs-slider {\n  /* Replace browser focus hightlight with handle highlight */\n  outline: 0;\n  position: relative;\n  cursor: pointer;\n  padding: 0;\n  /* background-color-with-alpha */\n  background-color: #333333;\n  background-color: rgba(51, 51, 51, 0.9);\n}\n.vjs-default-skin .vjs-slider:focus {\n  /* box-shadow */\n  -webkit-box-shadow: 0 0 2em #ffffff;\n  -moz-box-shadow: 0 0 2em #ffffff;\n  box-shadow: 0 0 2em #ffffff;\n}\n.vjs-default-skin .vjs-slider-handle {\n  position: absolute;\n  /* Needed for IE6 */\n  left: 0;\n  top: 0;\n}\n.vjs-default-skin .vjs-slider-handle:before {\n  content: \"\\e009\";\n  font-family: VideoJS;\n  font-size: 1em;\n  line-height: 1;\n  text-align: center;\n  text-shadow: 0em 0em 1em #fff;\n  position: absolute;\n  top: 0;\n  left: 0;\n  /* Rotate the square icon to make a diamond */\n  /* transform */\n  -webkit-transform: rotate(-45deg);\n  -moz-transform: rotate(-45deg);\n  -ms-transform: rotate(-45deg);\n  -o-transform: rotate(-45deg);\n  transform: rotate(-45deg);\n}\n/* Control Bar\n--------------------------------------------------------------------------------\nThe default control bar that is a container for most of the controls.\n*/\n.vjs-default-skin .vjs-control-bar {\n  /* Start hidden */\n  display: none;\n  position: absolute;\n  /* Place control bar at the bottom of the player box/video.\n     If you want more margin below the control bar, add more height. */\n  bottom: 0;\n  /* Use left/right to stretch to 100% width of player div */\n  left: 0;\n  right: 0;\n  /* Height includes any margin you want above or below control items */\n  height: 3.0em;\n  /* background-color-with-alpha */\n  background-color: #07141e;\n  background-color: rgba(7, 20, 30, 0.7);\n}\n/* Show the control bar only once the video has started playing */\n.vjs-default-skin.vjs-has-started .vjs-control-bar {\n  display: block;\n  /* Visibility needed to make sure things hide in older browsers too. */\n\n  visibility: visible;\n  opacity: 1;\n  /* transition */\n  -webkit-transition: visibility 0.1s, opacity 0.1s;\n  -moz-transition: visibility 0.1s, opacity 0.1s;\n  -o-transition: visibility 0.1s, opacity 0.1s;\n  transition: visibility 0.1s, opacity 0.1s;\n}\n/* Hide the control bar when the video is playing and the user is inactive  */\n.vjs-default-skin.vjs-has-started.vjs-user-inactive.vjs-playing .vjs-control-bar {\n  display: block;\n  visibility: hidden;\n  opacity: 0;\n  /* transition */\n  -webkit-transition: visibility 1s, opacity 1s;\n  -moz-transition: visibility 1s, opacity 1s;\n  -o-transition: visibility 1s, opacity 1s;\n  transition: visibility 1s, opacity 1s;\n}\n.vjs-default-skin.vjs-controls-disabled .vjs-control-bar {\n  display: none;\n}\n.vjs-default-skin.vjs-using-native-controls .vjs-control-bar {\n  display: none;\n}\n/* IE8 is flakey with fonts, and you have to change the actual content to force\nfonts to show/hide properly.\n  - \"\\9\" IE8 hack didn't work for this\n  - Found in XP IE8 from http://modern.ie. Does not show up in \"IE8 mode\" in IE9\n*/\n@media \\0screen {\n  .vjs-default-skin.vjs-user-inactive.vjs-playing .vjs-control-bar :before {\n    content: \"\";\n  }\n}\n/* General styles for individual controls. */\n.vjs-default-skin .vjs-control {\n  outline: none;\n  position: relative;\n  float: left;\n  text-align: center;\n  margin: 0;\n  padding: 0;\n  height: 3.0em;\n  width: 4em;\n}\n/* FontAwsome button icons */\n.vjs-default-skin .vjs-control:before {\n  font-family: VideoJS;\n  font-size: 1.5em;\n  line-height: 2;\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n  text-align: center;\n  text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.5);\n}\n/* Replacement for focus outline */\n.vjs-default-skin .vjs-control:focus:before,\n.vjs-default-skin .vjs-control:hover:before {\n  text-shadow: 0em 0em 1em #ffffff;\n}\n.vjs-default-skin .vjs-control:focus {\n  /*  outline: 0; */\n  /* keyboard-only users cannot see the focus on several of the UI elements when\n  this is set to 0 */\n\n}\n/* Hide control text visually, but have it available for screenreaders */\n.vjs-default-skin .vjs-control-text {\n  /* hide-visually */\n  border: 0;\n  clip: rect(0 0 0 0);\n  height: 1px;\n  margin: -1px;\n  overflow: hidden;\n  padding: 0;\n  position: absolute;\n  width: 1px;\n}\n/* Play/Pause\n--------------------------------------------------------------------------------\n*/\n.vjs-default-skin .vjs-play-control {\n  width: 5em;\n  cursor: pointer;\n}\n.vjs-default-skin .vjs-play-control:before {\n  content: \"\\e001\";\n}\n.vjs-default-skin.vjs-playing .vjs-play-control:before {\n  content: \"\\e002\";\n}\n/* Volume/Mute\n-------------------------------------------------------------------------------- */\n.vjs-default-skin .vjs-mute-control,\n.vjs-default-skin .vjs-volume-menu-button {\n  cursor: pointer;\n  float: right;\n}\n.vjs-default-skin .vjs-mute-control:before,\n.vjs-default-skin .vjs-volume-menu-button:before {\n  content: \"\\e006\";\n}\n.vjs-default-skin .vjs-mute-control.vjs-vol-0:before,\n.vjs-default-skin .vjs-volume-menu-button.vjs-vol-0:before {\n  content: \"\\e003\";\n}\n.vjs-default-skin .vjs-mute-control.vjs-vol-1:before,\n.vjs-default-skin .vjs-volume-menu-button.vjs-vol-1:before {\n  content: \"\\e004\";\n}\n.vjs-default-skin .vjs-mute-control.vjs-vol-2:before,\n.vjs-default-skin .vjs-volume-menu-button.vjs-vol-2:before {\n  content: \"\\e005\";\n}\n.vjs-default-skin .vjs-volume-control {\n  width: 5em;\n  float: right;\n}\n.vjs-default-skin .vjs-volume-bar {\n  width: 5em;\n  height: 0.6em;\n  margin: 1.1em auto 0;\n}\n.vjs-default-skin .vjs-volume-menu-button .vjs-menu-content {\n  height: 2.9em;\n}\n.vjs-default-skin .vjs-volume-level {\n  position: absolute;\n  top: 0;\n  left: 0;\n  height: 0.5em;\n  background: #66a8cc url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC) -50% 0 repeat;\n}\n.vjs-default-skin .vjs-volume-bar .vjs-volume-handle {\n  width: 0.5em;\n  height: 0.5em;\n}\n.vjs-default-skin .vjs-volume-handle:before {\n  font-size: 0.9em;\n  top: -0.2em;\n  left: -0.2em;\n  width: 1em;\n  height: 1em;\n}\n.vjs-default-skin .vjs-volume-menu-button .vjs-menu .vjs-menu-content {\n  width: 6em;\n  left: -4em;\n}\n/* Progress\n--------------------------------------------------------------------------------\n*/\n.vjs-default-skin .vjs-progress-control {\n  position: absolute;\n  left: 0;\n  right: 0;\n  width: auto;\n  font-size: 0.3em;\n  height: 1em;\n  /* Set above the rest of the controls. */\n  top: -1em;\n  /* Shrink the bar slower than it grows. */\n  /* transition */\n  -webkit-transition: all 0.4s;\n  -moz-transition: all 0.4s;\n  -o-transition: all 0.4s;\n  transition: all 0.4s;\n}\n/* On hover, make the progress bar grow to something that's more clickable.\n    This simply changes the overall font for the progress bar, and this\n    updates both the em-based widths and heights, as wells as the icon font */\n.vjs-default-skin:hover .vjs-progress-control {\n  font-size: .9em;\n  /* Even though we're not changing the top/height, we need to include them in\n      the transition so they're handled correctly. */\n\n  /* transition */\n  -webkit-transition: all 0.2s;\n  -moz-transition: all 0.2s;\n  -o-transition: all 0.2s;\n  transition: all 0.2s;\n}\n/* Box containing play and load progresses. Also acts as seek scrubber. */\n.vjs-default-skin .vjs-progress-holder {\n  height: 100%;\n}\n/* Progress Bars */\n.vjs-default-skin .vjs-progress-holder .vjs-play-progress,\n.vjs-default-skin .vjs-progress-holder .vjs-load-progress {\n  position: absolute;\n  display: block;\n  height: 100%;\n  margin: 0;\n  padding: 0;\n  /* Needed for IE6 */\n  left: 0;\n  top: 0;\n}\n.vjs-default-skin .vjs-play-progress {\n  /*\n    Using a data URI to create the white diagonal lines with a transparent\n      background. Surprisingly works in IE8.\n      Created using http://www.patternify.com\n    Changing the first color value will change the bar color.\n    Also using a paralax effect to make the lines move backwards.\n      The -50% left position makes that happen.\n  */\n\n  background: #66a8cc url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAAGCAYAAADgzO9IAAAAP0lEQVQIHWWMAQoAIAgDR/QJ/Ub//04+w7ZICBwcOg5FZi5iBB82AGzixEglJrd4TVK5XUJpskSTEvpdFzX9AB2pGziSQcvAAAAAAElFTkSuQmCC) -50% 0 repeat;\n}\n.vjs-default-skin .vjs-load-progress {\n  background: #646464 /* IE8- Fallback */;\n  background: rgba(255, 255, 255, 0.4);\n}\n.vjs-default-skin .vjs-seek-handle {\n  width: 1.5em;\n  height: 100%;\n}\n.vjs-default-skin .vjs-seek-handle:before {\n  padding-top: 0.1em /* Minor adjustment */;\n}\n/* Time Display\n--------------------------------------------------------------------------------\n*/\n.vjs-default-skin .vjs-time-controls {\n  font-size: 1em;\n  /* Align vertically by making the line height the same as the control bar */\n  line-height: 3em;\n}\n.vjs-default-skin .vjs-current-time {\n  float: left;\n}\n.vjs-default-skin .vjs-duration {\n  float: left;\n}\n/* Remaining time is in the HTML, but not included in default design */\n.vjs-default-skin .vjs-remaining-time {\n  display: none;\n  float: left;\n}\n.vjs-time-divider {\n  float: left;\n  line-height: 3em;\n}\n/* Fullscreen\n--------------------------------------------------------------------------------\n*/\n.vjs-default-skin .vjs-fullscreen-control {\n  width: 3.8em;\n  cursor: pointer;\n  float: right;\n}\n.vjs-default-skin .vjs-fullscreen-control:before {\n  content: \"\\e000\";\n}\n/* Switch to the exit icon when the player is in fullscreen */\n.vjs-default-skin.vjs-fullscreen .vjs-fullscreen-control:before {\n  content: \"\\e00b\";\n}\n/* Big Play Button (play button at start)\n--------------------------------------------------------------------------------\nPositioning of the play button in the center or other corners can be done more\neasily in the skin designer. http://designer.videojs.com/\n*/\n.vjs-default-skin .vjs-big-play-button {\n  left: 0.5em;\n  top: 0.5em;\n  font-size: 3em;\n  display: block;\n  z-index: 2;\n  position: absolute;\n  width: 4em;\n  height: 2.6em;\n  text-align: center;\n  vertical-align: middle;\n  cursor: pointer;\n  opacity: 1;\n  /* Need a slightly gray bg so it can be seen on black backgrounds */\n  /* background-color-with-alpha */\n  background-color: #07141e;\n  background-color: rgba(7, 20, 30, 0.7);\n  border: 0.1em solid #3b4249;\n  /* border-radius */\n  -webkit-border-radius: 0.8em;\n  -moz-border-radius: 0.8em;\n  border-radius: 0.8em;\n  /* box-shadow */\n  -webkit-box-shadow: 0px 0px 1em rgba(255, 255, 255, 0.25);\n  -moz-box-shadow: 0px 0px 1em rgba(255, 255, 255, 0.25);\n  box-shadow: 0px 0px 1em rgba(255, 255, 255, 0.25);\n  /* transition */\n  -webkit-transition: all 0.4s;\n  -moz-transition: all 0.4s;\n  -o-transition: all 0.4s;\n  transition: all 0.4s;\n}\n/* Optionally center */\n.vjs-default-skin.vjs-big-play-centered .vjs-big-play-button {\n  /* Center it horizontally */\n  left: 50%;\n  margin-left: -2.1em;\n  /* Center it vertically */\n  top: 50%;\n  margin-top: -1.4000000000000001em;\n}\n/* Hide if controls are disabled */\n.vjs-default-skin.vjs-controls-disabled .vjs-big-play-button {\n  display: none;\n}\n/* Hide when video starts playing */\n.vjs-default-skin.vjs-has-started .vjs-big-play-button {\n  display: none;\n}\n/* Hide on mobile devices. Remove when we stop using native controls\n    by default on mobile  */\n.vjs-default-skin.vjs-using-native-controls .vjs-big-play-button {\n  display: none;\n}\n.vjs-default-skin:hover .vjs-big-play-button,\n.vjs-default-skin .vjs-big-play-button:focus {\n  outline: 0;\n  border-color: #fff;\n  /* IE8 needs a non-glow hover state */\n  background-color: #505050;\n  background-color: rgba(50, 50, 50, 0.75);\n  /* box-shadow */\n  -webkit-box-shadow: 0 0 3em #ffffff;\n  -moz-box-shadow: 0 0 3em #ffffff;\n  box-shadow: 0 0 3em #ffffff;\n  /* transition */\n  -webkit-transition: all 0s;\n  -moz-transition: all 0s;\n  -o-transition: all 0s;\n  transition: all 0s;\n}\n.vjs-default-skin .vjs-big-play-button:before {\n  content: \"\\e001\";\n  font-family: VideoJS;\n  /* In order to center the play icon vertically we need to set the line height\n     to the same as the button height */\n\n  line-height: 2.6em;\n  text-shadow: 0.05em 0.05em 0.1em #000;\n  text-align: center /* Needed for IE8 */;\n  position: absolute;\n  left: 0;\n  width: 100%;\n  height: 100%;\n}\n/* Loading Spinner\n--------------------------------------------------------------------------------\n*/\n.vjs-loading-spinner {\n  display: none;\n  position: absolute;\n  top: 50%;\n  left: 50%;\n  font-size: 4em;\n  line-height: 1;\n  width: 1em;\n  height: 1em;\n  margin-left: -0.5em;\n  margin-top: -0.5em;\n  opacity: 0.75;\n  /* animation */\n  -webkit-animation: spin 1.5s infinite linear;\n  -moz-animation: spin 1.5s infinite linear;\n  -o-animation: spin 1.5s infinite linear;\n  animation: spin 1.5s infinite linear;\n}\n.vjs-default-skin .vjs-loading-spinner:before {\n  content: \"\\e01e\";\n  font-family: VideoJS;\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 1em;\n  height: 1em;\n  text-align: center;\n  text-shadow: 0em 0em 0.1em #000;\n}\n@-moz-keyframes spin {\n  0% {\n    -moz-transform: rotate(0deg);\n  }\n  100% {\n    -moz-transform: rotate(359deg);\n  }\n}\n@-webkit-keyframes spin {\n  0% {\n    -webkit-transform: rotate(0deg);\n  }\n  100% {\n    -webkit-transform: rotate(359deg);\n  }\n}\n@-o-keyframes spin {\n  0% {\n    -o-transform: rotate(0deg);\n  }\n  100% {\n    -o-transform: rotate(359deg);\n  }\n}\n@keyframes spin {\n  0% {\n    transform: rotate(0deg);\n  }\n  100% {\n    transform: rotate(359deg);\n  }\n}\n/* Menu Buttons (Captions/Subtitles/etc.)\n--------------------------------------------------------------------------------\n*/\n.vjs-default-skin .vjs-menu-button {\n  float: right;\n  cursor: pointer;\n}\n.vjs-default-skin .vjs-menu {\n  display: none;\n  position: absolute;\n  bottom: 0;\n  left: 0em;\n  /* (Width of vjs-menu - width of button) / 2 */\n\n  width: 0em;\n  height: 0em;\n  margin-bottom: 3em;\n  border-left: 2em solid transparent;\n  border-right: 2em solid transparent;\n  border-top: 1.55em solid #000000;\n  /* Same width top as ul bottom */\n\n  border-top-color: rgba(7, 40, 50, 0.5);\n  /* Same as ul background */\n\n}\n/* Button Pop-up Menu */\n.vjs-default-skin .vjs-menu-button .vjs-menu .vjs-menu-content {\n  display: block;\n  padding: 0;\n  margin: 0;\n  position: absolute;\n  width: 10em;\n  bottom: 1.5em;\n  /* Same bottom as vjs-menu border-top */\n\n  max-height: 15em;\n  overflow: auto;\n  left: -5em;\n  /* Width of menu - width of button / 2 */\n\n  /* background-color-with-alpha */\n  background-color: #07141e;\n  background-color: rgba(7, 20, 30, 0.7);\n  /* box-shadow */\n  -webkit-box-shadow: -0.2em -0.2em 0.3em rgba(255, 255, 255, 0.2);\n  -moz-box-shadow: -0.2em -0.2em 0.3em rgba(255, 255, 255, 0.2);\n  box-shadow: -0.2em -0.2em 0.3em rgba(255, 255, 255, 0.2);\n}\n.vjs-default-skin .vjs-menu-button:hover .vjs-menu {\n  display: block;\n}\n.vjs-default-skin .vjs-menu-button ul li {\n  list-style: none;\n  margin: 0;\n  padding: 0.3em 0 0.3em 0;\n  line-height: 1.4em;\n  font-size: 1.2em;\n  text-align: center;\n  text-transform: lowercase;\n}\n.vjs-default-skin .vjs-menu-button ul li.vjs-selected {\n  background-color: #000;\n}\n.vjs-default-skin .vjs-menu-button ul li:focus,\n.vjs-default-skin .vjs-menu-button ul li:hover,\n.vjs-default-skin .vjs-menu-button ul li.vjs-selected:focus,\n.vjs-default-skin .vjs-menu-button ul li.vjs-selected:hover {\n  outline: 0;\n  color: #111;\n  /* background-color-with-alpha */\n  background-color: #ffffff;\n  background-color: rgba(255, 255, 255, 0.75);\n  /* box-shadow */\n  -webkit-box-shadow: 0 0 1em #ffffff;\n  -moz-box-shadow: 0 0 1em #ffffff;\n  box-shadow: 0 0 1em #ffffff;\n}\n.vjs-default-skin .vjs-menu-button ul li.vjs-menu-title {\n  text-align: center;\n  text-transform: uppercase;\n  font-size: 1em;\n  line-height: 2em;\n  padding: 0;\n  margin: 0 0 0.3em 0;\n  font-weight: bold;\n  cursor: default;\n}\n/* Subtitles Button */\n.vjs-default-skin .vjs-subtitles-button:before {\n  content: \"\\e00c\";\n}\n/* Captions Button */\n.vjs-default-skin .vjs-captions-button:before {\n  content: \"\\e008\";\n}\n/* Replacement for focus outline */\n.vjs-default-skin .vjs-captions-button:focus .vjs-control-content:before,\n.vjs-default-skin .vjs-captions-button:hover .vjs-control-content:before {\n  /* box-shadow */\n  -webkit-box-shadow: 0 0 1em #ffffff;\n  -moz-box-shadow: 0 0 1em #ffffff;\n  box-shadow: 0 0 1em #ffffff;\n}\n/*\nREQUIRED STYLES (be careful overriding)\n================================================================================\nWhen loading the player, the video tag is replaced with a DIV,\nthat will hold the video tag or object tag for other playback methods.\nThe div contains the video playback element (Flash or HTML5) and controls,\nand sets the width and height of the video.\n\n** If you want to add some kind of border/padding (e.g. a frame), or special\npositioning, use another containing element. Otherwise you risk messing up\ncontrol positioning and full window mode. **\n*/\n.video-js {\n  background-color: #000;\n  position: relative;\n  padding: 0;\n  /* Start with 10px for base font size so other dimensions can be em based and\n     easily calculable. */\n\n  font-size: 10px;\n  /* Allow poster to be vertially aligned. */\n\n  vertical-align: middle;\n  /*  display: table-cell; */\n  /*This works in Safari but not Firefox.*/\n\n  /* Provide some basic defaults for fonts */\n\n  font-weight: normal;\n  font-style: normal;\n  /* Avoiding helvetica: issue #376 */\n\n  font-family: Arial, sans-serif;\n  /* Turn off user selection (text highlighting) by default.\n     The majority of player components will not be text blocks.\n     Text areas will need to turn user selection back on. */\n\n  /* user-select */\n  -webkit-user-select: none;\n  -moz-user-select: none;\n  -ms-user-select: none;\n  user-select: none;\n}\n/* Playback technology elements expand to the width/height of the containing div\n    <video> or <object> */\n.video-js .vjs-tech {\n  position: absolute;\n  top: 0;\n  left: 0;\n  width: 100%;\n  height: 100%;\n}\n/* Fix for Firefox 9 fullscreen (only if it is enabled). Not needed when\n   checking fullScreenEnabled. */\n.video-js:-moz-full-screen {\n  position: absolute;\n}\n/* Fullscreen Styles */\nbody.vjs-full-window {\n  padding: 0;\n  margin: 0;\n  height: 100%;\n  /* Fix for IE6 full-window. http://www.cssplay.co.uk/layouts/fixed.html */\n  overflow-y: auto;\n}\n.video-js.vjs-fullscreen {\n  position: fixed;\n  overflow: hidden;\n  z-index: 1000;\n  left: 0;\n  top: 0;\n  bottom: 0;\n  right: 0;\n  width: 100% !important;\n  height: 100% !important;\n  /* IE6 full-window (underscore hack) */\n  _position: absolute;\n}\n.video-js:-webkit-full-screen {\n  width: 100% !important;\n  height: 100% !important;\n}\n.video-js.vjs-fullscreen.vjs-user-inactive {\n  cursor: none;\n}\n/* Poster Styles */\n.vjs-poster {\n  background-repeat: no-repeat;\n  background-position: 50% 50%;\n  background-size: contain;\n  cursor: pointer;\n  height: 100%;\n  margin: 0;\n  padding: 0;\n  position: relative;\n  width: 100%;\n}\n.vjs-poster img {\n  display: block;\n  margin: 0 auto;\n  max-height: 100%;\n  padding: 0;\n  width: 100%;\n}\n/* Hide the poster when native controls are used otherwise it covers them */\n.video-js.vjs-using-native-controls .vjs-poster {\n  display: none;\n}\n/* Text Track Styles */\n/* Overall track holder for both captions and subtitles */\n.video-js .vjs-text-track-display {\n  text-align: center;\n  position: absolute;\n  bottom: 4em;\n  /* Leave padding on left and right */\n  left: 1em;\n  right: 1em;\n}\n/* Individual tracks */\n.video-js .vjs-text-track {\n  display: none;\n  font-size: 1.4em;\n  text-align: center;\n  margin-bottom: 0.1em;\n  /* Transparent black background, or fallback to all black (oldIE) */\n  /* background-color-with-alpha */\n  background-color: #000000;\n  background-color: rgba(0, 0, 0, 0.5);\n}\n.video-js .vjs-subtitles {\n  color: #ffffff /* Subtitles are white */;\n}\n.video-js .vjs-captions {\n  color: #ffcc66 /* Captions are yellow */;\n}\n.vjs-tt-cue {\n  display: block;\n}\n/* Hide disabled or unsupported controls */\n.vjs-default-skin .vjs-hidden {\n  display: none;\n}\n.vjs-lock-showing {\n  display: block !important;\n  opacity: 1;\n  visibility: visible;\n}\n/* -----------------------------------------------------------------------------\nThe original source of this file lives at\nhttps://github.com/videojs/video.js/blob/master/src/css/video-js.less */\n"
  },
  {
    "path": "public/static/ueditor/third-party/video-js/video.dev.js",
    "content": "/**\n * @fileoverview Main function src.\n */\n\n// HTML5 Shiv. Must be in <head> to support older browsers.\ndocument.createElement('video');\ndocument.createElement('audio');\ndocument.createElement('track');\n\n/**\n * Doubles as the main function for users to create a player instance and also\n * the main library object.\n *\n * **ALIASES** videojs, _V_ (deprecated)\n *\n * The `vjs` function can be used to initialize or retrieve a player.\n *\n *     var myPlayer = vjs('my_video_id');\n *\n * @param  {String|Element} id      Video element or video element ID\n * @param  {Object=} options        Optional options object for config/settings\n * @param  {Function=} ready        Optional ready callback\n * @return {vjs.Player}             A player instance\n * @namespace\n */\nvar vjs = function(id, options, ready){\n  var tag; // Element of ID\n\n  // Allow for element or ID to be passed in\n  // String ID\n  if (typeof id === 'string') {\n\n    // Adjust for jQuery ID syntax\n    if (id.indexOf('#') === 0) {\n      id = id.slice(1);\n    }\n\n    // If a player instance has already been created for this ID return it.\n    if (vjs.players[id]) {\n      return vjs.players[id];\n\n    // Otherwise get element for ID\n    } else {\n      tag = vjs.el(id);\n    }\n\n  // ID is a media element\n  } else {\n    tag = id;\n  }\n\n  // Check for a useable element\n  if (!tag || !tag.nodeName) { // re: nodeName, could be a box div also\n    throw new TypeError('The element or ID supplied is not valid. (videojs)'); // Returns\n  }\n\n  // Element may have a player attr referring to an already created player instance.\n  // If not, set up a new player and return the instance.\n  return tag['player'] || new vjs.Player(tag, options, ready);\n};\n\n// Extended name, also available externally, window.videojs\nvar videojs = vjs;\nwindow.videojs = window.vjs = vjs;\n\n// CDN Version. Used to target right flash swf.\nvjs.CDN_VERSION = '4.3';\nvjs.ACCESS_PROTOCOL = ('https:' == document.location.protocol ? 'https://' : 'http://');\n\n/**\n * Global Player instance options, surfaced from vjs.Player.prototype.options_\n * vjs.options = vjs.Player.prototype.options_\n * All options should use string keys so they avoid\n * renaming by closure compiler\n * @type {Object}\n */\nvjs.options = {\n  // Default order of fallback technology\n  'techOrder': ['html5','flash'],\n  // techOrder: ['flash','html5'],\n\n  'html5': {},\n  'flash': {},\n\n  // Default of web browser is 300x150. Should rely on source width/height.\n  'width': 300,\n  'height': 150,\n  // defaultVolume: 0.85,\n  'defaultVolume': 0.00, // The freakin seaguls are driving me crazy!\n\n  // Included control sets\n  'children': {\n    'mediaLoader': {},\n    'posterImage': {},\n    'textTrackDisplay': {},\n    'loadingSpinner': {},\n    'bigPlayButton': {},\n    'controlBar': {}\n  },\n\n  // Default message to show when a video cannot be played.\n  'notSupportedMessage': 'Sorry, no compatible source and playback ' +\n      'technology were found for this video. Try using another browser ' +\n      'like <a href=\"http://bit.ly/ccMUEC\">Chrome</a> or download the ' +\n      'latest <a href=\"http://adobe.ly/mwfN1\">Adobe Flash Player</a>.'\n};\n\n// Set CDN Version of swf\n// The added (+) blocks the replace from changing this 4.3 string\nif (vjs.CDN_VERSION !== 'GENERATED'+'_CDN_VSN') {\n  videojs.options['flash']['swf'] = vjs.ACCESS_PROTOCOL + 'vjs.zencdn.net/'+vjs.CDN_VERSION+'/video-js.swf';\n}\n\n/**\n * Global player list\n * @type {Object}\n */\nvjs.players = {};\n/**\n * Core Object/Class for objects that use inheritance + contstructors\n *\n * To create a class that can be subclassed itself, extend the CoreObject class.\n *\n *     var Animal = CoreObject.extend();\n *     var Horse = Animal.extend();\n *\n * The constructor can be defined through the init property of an object argument.\n *\n *     var Animal = CoreObject.extend({\n *       init: function(name, sound){\n *         this.name = name;\n *       }\n *     });\n *\n * Other methods and properties can be added the same way, or directly to the\n * prototype.\n *\n *    var Animal = CoreObject.extend({\n *       init: function(name){\n *         this.name = name;\n *       },\n *       getName: function(){\n *         return this.name;\n *       },\n *       sound: '...'\n *    });\n *\n *    Animal.prototype.makeSound = function(){\n *      alert(this.sound);\n *    };\n *\n * To create an instance of a class, use the create method.\n *\n *    var fluffy = Animal.create('Fluffy');\n *    fluffy.getName(); // -> Fluffy\n *\n * Methods and properties can be overridden in subclasses.\n *\n *     var Horse = Animal.extend({\n *       sound: 'Neighhhhh!'\n *     });\n *\n *     var horsey = Horse.create('Horsey');\n *     horsey.getName(); // -> Horsey\n *     horsey.makeSound(); // -> Alert: Neighhhhh!\n *\n * @class\n * @constructor\n */\nvjs.CoreObject = vjs['CoreObject'] = function(){};\n// Manually exporting vjs['CoreObject'] here for Closure Compiler\n// because of the use of the extend/create class methods\n// If we didn't do this, those functions would get flattend to something like\n// `a = ...` and `this.prototype` would refer to the global object instead of\n// CoreObject\n\n/**\n * Create a new object that inherits from this Object\n *\n *     var Animal = CoreObject.extend();\n *     var Horse = Animal.extend();\n *\n * @param {Object} props Functions and properties to be applied to the\n *                       new object's prototype\n * @return {vjs.CoreObject} An object that inherits from CoreObject\n * @this {*}\n */\nvjs.CoreObject.extend = function(props){\n  var init, subObj;\n\n  props = props || {};\n  // Set up the constructor using the supplied init method\n  // or using the init of the parent object\n  // Make sure to check the unobfuscated version for external libs\n  init = props['init'] || props.init || this.prototype['init'] || this.prototype.init || function(){};\n  // In Resig's simple class inheritance (previously used) the constructor\n  //  is a function that calls `this.init.apply(arguments)`\n  // However that would prevent us from using `ParentObject.call(this);`\n  //  in a Child constuctor because the `this` in `this.init`\n  //  would still refer to the Child and cause an inifinite loop.\n  // We would instead have to do\n  //    `ParentObject.prototype.init.apply(this, argumnents);`\n  //  Bleh. We're not creating a _super() function, so it's good to keep\n  //  the parent constructor reference simple.\n  subObj = function(){\n    init.apply(this, arguments);\n  };\n\n  // Inherit from this object's prototype\n  subObj.prototype = vjs.obj.create(this.prototype);\n  // Reset the constructor property for subObj otherwise\n  // instances of subObj would have the constructor of the parent Object\n  subObj.prototype.constructor = subObj;\n\n  // Make the class extendable\n  subObj.extend = vjs.CoreObject.extend;\n  // Make a function for creating instances\n  subObj.create = vjs.CoreObject.create;\n\n  // Extend subObj's prototype with functions and other properties from props\n  for (var name in props) {\n    if (props.hasOwnProperty(name)) {\n      subObj.prototype[name] = props[name];\n    }\n  }\n\n  return subObj;\n};\n\n/**\n * Create a new instace of this Object class\n *\n *     var myAnimal = Animal.create();\n *\n * @return {vjs.CoreObject} An instance of a CoreObject subclass\n * @this {*}\n */\nvjs.CoreObject.create = function(){\n  // Create a new object that inherits from this object's prototype\n  var inst = vjs.obj.create(this.prototype);\n\n  // Apply this constructor function to the new object\n  this.apply(inst, arguments);\n\n  // Return the new object\n  return inst;\n};\n/**\n * @fileoverview Event System (John Resig - Secrets of a JS Ninja http://jsninja.com/)\n * (Original book version wasn't completely usable, so fixed some things and made Closure Compiler compatible)\n * This should work very similarly to jQuery's events, however it's based off the book version which isn't as\n * robust as jquery's, so there's probably some differences.\n */\n\n/**\n * Add an event listener to element\n * It stores the handler function in a separate cache object\n * and adds a generic handler to the element's event,\n * along with a unique id (guid) to the element.\n * @param  {Element|Object}   elem Element or object to bind listeners to\n * @param  {String}   type Type of event to bind to.\n * @param  {Function} fn   Event listener.\n * @private\n */\nvjs.on = function(elem, type, fn){\n  var data = vjs.getData(elem);\n\n  // We need a place to store all our handler data\n  if (!data.handlers) data.handlers = {};\n\n  if (!data.handlers[type]) data.handlers[type] = [];\n\n  if (!fn.guid) fn.guid = vjs.guid++;\n\n  data.handlers[type].push(fn);\n\n  if (!data.dispatcher) {\n    data.disabled = false;\n\n    data.dispatcher = function (event){\n\n      if (data.disabled) return;\n      event = vjs.fixEvent(event);\n\n      var handlers = data.handlers[event.type];\n\n      if (handlers) {\n        // Copy handlers so if handlers are added/removed during the process it doesn't throw everything off.\n        var handlersCopy = handlers.slice(0);\n\n        for (var m = 0, n = handlersCopy.length; m < n; m++) {\n          if (event.isImmediatePropagationStopped()) {\n            break;\n          } else {\n            handlersCopy[m].call(elem, event);\n          }\n        }\n      }\n    };\n  }\n\n  if (data.handlers[type].length == 1) {\n    if (document.addEventListener) {\n      elem.addEventListener(type, data.dispatcher, false);\n    } else if (document.attachEvent) {\n      elem.attachEvent('on' + type, data.dispatcher);\n    }\n  }\n};\n\n/**\n * Removes event listeners from an element\n * @param  {Element|Object}   elem Object to remove listeners from\n * @param  {String=}   type Type of listener to remove. Don't include to remove all events from element.\n * @param  {Function} fn   Specific listener to remove. Don't incldue to remove listeners for an event type.\n * @private\n */\nvjs.off = function(elem, type, fn) {\n  // Don't want to add a cache object through getData if not needed\n  if (!vjs.hasData(elem)) return;\n\n  var data = vjs.getData(elem);\n\n  // If no events exist, nothing to unbind\n  if (!data.handlers) { return; }\n\n  // Utility function\n  var removeType = function(t){\n     data.handlers[t] = [];\n     vjs.cleanUpEvents(elem,t);\n  };\n\n  // Are we removing all bound events?\n  if (!type) {\n    for (var t in data.handlers) removeType(t);\n    return;\n  }\n\n  var handlers = data.handlers[type];\n\n  // If no handlers exist, nothing to unbind\n  if (!handlers) return;\n\n  // If no listener was provided, remove all listeners for type\n  if (!fn) {\n    removeType(type);\n    return;\n  }\n\n  // We're only removing a single handler\n  if (fn.guid) {\n    for (var n = 0; n < handlers.length; n++) {\n      if (handlers[n].guid === fn.guid) {\n        handlers.splice(n--, 1);\n      }\n    }\n  }\n\n  vjs.cleanUpEvents(elem, type);\n};\n\n/**\n * Clean up the listener cache and dispatchers\n * @param  {Element|Object} elem Element to clean up\n * @param  {String} type Type of event to clean up\n * @private\n */\nvjs.cleanUpEvents = function(elem, type) {\n  var data = vjs.getData(elem);\n\n  // Remove the events of a particular type if there are none left\n  if (data.handlers[type].length === 0) {\n    delete data.handlers[type];\n    // data.handlers[type] = null;\n    // Setting to null was causing an error with data.handlers\n\n    // Remove the meta-handler from the element\n    if (document.removeEventListener) {\n      elem.removeEventListener(type, data.dispatcher, false);\n    } else if (document.detachEvent) {\n      elem.detachEvent('on' + type, data.dispatcher);\n    }\n  }\n\n  // Remove the events object if there are no types left\n  if (vjs.isEmpty(data.handlers)) {\n    delete data.handlers;\n    delete data.dispatcher;\n    delete data.disabled;\n\n    // data.handlers = null;\n    // data.dispatcher = null;\n    // data.disabled = null;\n  }\n\n  // Finally remove the expando if there is no data left\n  if (vjs.isEmpty(data)) {\n    vjs.removeData(elem);\n  }\n};\n\n/**\n * Fix a native event to have standard property values\n * @param  {Object} event Event object to fix\n * @return {Object}\n * @private\n */\nvjs.fixEvent = function(event) {\n\n  function returnTrue() { return true; }\n  function returnFalse() { return false; }\n\n  // Test if fixing up is needed\n  // Used to check if !event.stopPropagation instead of isPropagationStopped\n  // But native events return true for stopPropagation, but don't have\n  // other expected methods like isPropagationStopped. Seems to be a problem\n  // with the Javascript Ninja code. So we're just overriding all events now.\n  if (!event || !event.isPropagationStopped) {\n    var old = event || window.event;\n\n    event = {};\n    // Clone the old object so that we can modify the values event = {};\n    // IE8 Doesn't like when you mess with native event properties\n    // Firefox returns false for event.hasOwnProperty('type') and other props\n    //  which makes copying more difficult.\n    // TODO: Probably best to create a whitelist of event props\n    for (var key in old) {\n      // Safari 6.0.3 warns you if you try to copy deprecated layerX/Y\n      if (key !== 'layerX' && key !== 'layerY') {\n        event[key] = old[key];\n      }\n    }\n\n    // The event occurred on this element\n    if (!event.target) {\n      event.target = event.srcElement || document;\n    }\n\n    // Handle which other element the event is related to\n    event.relatedTarget = event.fromElement === event.target ?\n      event.toElement :\n      event.fromElement;\n\n    // Stop the default browser action\n    event.preventDefault = function () {\n      if (old.preventDefault) {\n        old.preventDefault();\n      }\n      event.returnValue = false;\n      event.isDefaultPrevented = returnTrue;\n    };\n\n    event.isDefaultPrevented = returnFalse;\n\n    // Stop the event from bubbling\n    event.stopPropagation = function () {\n      if (old.stopPropagation) {\n        old.stopPropagation();\n      }\n      event.cancelBubble = true;\n      event.isPropagationStopped = returnTrue;\n    };\n\n    event.isPropagationStopped = returnFalse;\n\n    // Stop the event from bubbling and executing other handlers\n    event.stopImmediatePropagation = function () {\n      if (old.stopImmediatePropagation) {\n        old.stopImmediatePropagation();\n      }\n      event.isImmediatePropagationStopped = returnTrue;\n      event.stopPropagation();\n    };\n\n    event.isImmediatePropagationStopped = returnFalse;\n\n    // Handle mouse position\n    if (event.clientX != null) {\n      var doc = document.documentElement, body = document.body;\n\n      event.pageX = event.clientX +\n        (doc && doc.scrollLeft || body && body.scrollLeft || 0) -\n        (doc && doc.clientLeft || body && body.clientLeft || 0);\n      event.pageY = event.clientY +\n        (doc && doc.scrollTop || body && body.scrollTop || 0) -\n        (doc && doc.clientTop || body && body.clientTop || 0);\n    }\n\n    // Handle key presses\n    event.which = event.charCode || event.keyCode;\n\n    // Fix button for mouse clicks:\n    // 0 == left; 1 == middle; 2 == right\n    if (event.button != null) {\n      event.button = (event.button & 1 ? 0 :\n        (event.button & 4 ? 1 :\n          (event.button & 2 ? 2 : 0)));\n    }\n  }\n\n  // Returns fixed-up instance\n  return event;\n};\n\n/**\n * Trigger an event for an element\n * @param  {Element|Object} elem  Element to trigger an event on\n * @param  {String} event Type of event to trigger\n * @private\n */\nvjs.trigger = function(elem, event) {\n  // Fetches element data and a reference to the parent (for bubbling).\n  // Don't want to add a data object to cache for every parent,\n  // so checking hasData first.\n  var elemData = (vjs.hasData(elem)) ? vjs.getData(elem) : {};\n  var parent = elem.parentNode || elem.ownerDocument;\n      // type = event.type || event,\n      // handler;\n\n  // If an event name was passed as a string, creates an event out of it\n  if (typeof event === 'string') {\n    event = { type:event, target:elem };\n  }\n  // Normalizes the event properties.\n  event = vjs.fixEvent(event);\n\n  // If the passed element has a dispatcher, executes the established handlers.\n  if (elemData.dispatcher) {\n    elemData.dispatcher.call(elem, event);\n  }\n\n  // Unless explicitly stopped or the event does not bubble (e.g. media events)\n    // recursively calls this function to bubble the event up the DOM.\n    if (parent && !event.isPropagationStopped() && event.bubbles !== false) {\n    vjs.trigger(parent, event);\n\n  // If at the top of the DOM, triggers the default action unless disabled.\n  } else if (!parent && !event.isDefaultPrevented()) {\n    var targetData = vjs.getData(event.target);\n\n    // Checks if the target has a default action for this event.\n    if (event.target[event.type]) {\n      // Temporarily disables event dispatching on the target as we have already executed the handler.\n      targetData.disabled = true;\n      // Executes the default action.\n      if (typeof event.target[event.type] === 'function') {\n        event.target[event.type]();\n      }\n      // Re-enables event dispatching.\n      targetData.disabled = false;\n    }\n  }\n\n  // Inform the triggerer if the default was prevented by returning false\n  return !event.isDefaultPrevented();\n  /* Original version of js ninja events wasn't complete.\n   * We've since updated to the latest version, but keeping this around\n   * for now just in case.\n   */\n  // // Added in attion to book. Book code was broke.\n  // event = typeof event === 'object' ?\n  //   event[vjs.expando] ?\n  //     event :\n  //     new vjs.Event(type, event) :\n  //   new vjs.Event(type);\n\n  // event.type = type;\n  // if (handler) {\n  //   handler.call(elem, event);\n  // }\n\n  // // Clean up the event in case it is being reused\n  // event.result = undefined;\n  // event.target = elem;\n};\n\n/**\n * Trigger a listener only once for an event\n * @param  {Element|Object}   elem Element or object to\n * @param  {String}   type\n * @param  {Function} fn\n * @private\n */\nvjs.one = function(elem, type, fn) {\n  var func = function(){\n    vjs.off(elem, type, func);\n    fn.apply(this, arguments);\n  };\n  func.guid = fn.guid = fn.guid || vjs.guid++;\n  vjs.on(elem, type, func);\n};\nvar hasOwnProp = Object.prototype.hasOwnProperty;\n\n/**\n * Creates an element and applies properties.\n * @param  {String=} tagName    Name of tag to be created.\n * @param  {Object=} properties Element properties to be applied.\n * @return {Element}\n * @private\n */\nvjs.createEl = function(tagName, properties){\n  var el, propName;\n\n  el = document.createElement(tagName || 'div');\n\n  for (propName in properties){\n    if (hasOwnProp.call(properties, propName)) {\n      //el[propName] = properties[propName];\n      // Not remembering why we were checking for dash\n      // but using setAttribute means you have to use getAttribute\n\n      // The check for dash checks for the aria-* attributes, like aria-label, aria-valuemin.\n      // The additional check for \"role\" is because the default method for adding attributes does not\n      // add the attribute \"role\". My guess is because it's not a valid attribute in some namespaces, although\n      // browsers handle the attribute just fine. The W3C allows for aria-* attributes to be used in pre-HTML5 docs.\n      // http://www.w3.org/TR/wai-aria-primer/#ariahtml. Using setAttribute gets around this problem.\n\n       if (propName.indexOf('aria-') !== -1 || propName=='role') {\n         el.setAttribute(propName, properties[propName]);\n       } else {\n         el[propName] = properties[propName];\n       }\n    }\n  }\n  return el;\n};\n\n/**\n * Uppercase the first letter of a string\n * @param  {String} string String to be uppercased\n * @return {String}\n * @private\n */\nvjs.capitalize = function(string){\n  return string.charAt(0).toUpperCase() + string.slice(1);\n};\n\n/**\n * Object functions container\n * @type {Object}\n * @private\n */\nvjs.obj = {};\n\n/**\n * Object.create shim for prototypal inheritance\n *\n * https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/Object/create\n *\n * @function\n * @param  {Object}   obj Object to use as prototype\n * @private\n */\n vjs.obj.create = Object.create || function(obj){\n  //Create a new function called 'F' which is just an empty object.\n  function F() {}\n\n  //the prototype of the 'F' function should point to the\n  //parameter of the anonymous function.\n  F.prototype = obj;\n\n  //create a new constructor function based off of the 'F' function.\n  return new F();\n};\n\n/**\n * Loop through each property in an object and call a function\n * whose arguments are (key,value)\n * @param  {Object}   obj Object of properties\n * @param  {Function} fn  Function to be called on each property.\n * @this {*}\n * @private\n */\nvjs.obj.each = function(obj, fn, context){\n  for (var key in obj) {\n    if (hasOwnProp.call(obj, key)) {\n      fn.call(context || this, key, obj[key]);\n    }\n  }\n};\n\n/**\n * Merge two objects together and return the original.\n * @param  {Object} obj1\n * @param  {Object} obj2\n * @return {Object}\n * @private\n */\nvjs.obj.merge = function(obj1, obj2){\n  if (!obj2) { return obj1; }\n  for (var key in obj2){\n    if (hasOwnProp.call(obj2, key)) {\n      obj1[key] = obj2[key];\n    }\n  }\n  return obj1;\n};\n\n/**\n * Merge two objects, and merge any properties that are objects\n * instead of just overwriting one. Uses to merge options hashes\n * where deeper default settings are important.\n * @param  {Object} obj1 Object to override\n * @param  {Object} obj2 Overriding object\n * @return {Object}      New object. Obj1 and Obj2 will be untouched.\n * @private\n */\nvjs.obj.deepMerge = function(obj1, obj2){\n  var key, val1, val2;\n\n  // make a copy of obj1 so we're not ovewriting original values.\n  // like prototype.options_ and all sub options objects\n  obj1 = vjs.obj.copy(obj1);\n\n  for (key in obj2){\n    if (hasOwnProp.call(obj2, key)) {\n      val1 = obj1[key];\n      val2 = obj2[key];\n\n      // Check if both properties are pure objects and do a deep merge if so\n      if (vjs.obj.isPlain(val1) && vjs.obj.isPlain(val2)) {\n        obj1[key] = vjs.obj.deepMerge(val1, val2);\n      } else {\n        obj1[key] = obj2[key];\n      }\n    }\n  }\n  return obj1;\n};\n\n/**\n * Make a copy of the supplied object\n * @param  {Object} obj Object to copy\n * @return {Object}     Copy of object\n * @private\n */\nvjs.obj.copy = function(obj){\n  return vjs.obj.merge({}, obj);\n};\n\n/**\n * Check if an object is plain, and not a dom node or any object sub-instance\n * @param  {Object} obj Object to check\n * @return {Boolean}     True if plain, false otherwise\n * @private\n */\nvjs.obj.isPlain = function(obj){\n  return !!obj\n    && typeof obj === 'object'\n    && obj.toString() === '[object Object]'\n    && obj.constructor === Object;\n};\n\n/**\n * Bind (a.k.a proxy or Context). A simple method for changing the context of a function\n   It also stores a unique id on the function so it can be easily removed from events\n * @param  {*}   context The object to bind as scope\n * @param  {Function} fn      The function to be bound to a scope\n * @param  {Number=}   uid     An optional unique ID for the function to be set\n * @return {Function}\n * @private\n */\nvjs.bind = function(context, fn, uid) {\n  // Make sure the function has a unique ID\n  if (!fn.guid) { fn.guid = vjs.guid++; }\n\n  // Create the new function that changes the context\n  var ret = function() {\n    return fn.apply(context, arguments);\n  };\n\n  // Allow for the ability to individualize this function\n  // Needed in the case where multiple objects might share the same prototype\n  // IF both items add an event listener with the same function, then you try to remove just one\n  // it will remove both because they both have the same guid.\n  // when using this, you need to use the bind method when you remove the listener as well.\n  // currently used in text tracks\n  ret.guid = (uid) ? uid + '_' + fn.guid : fn.guid;\n\n  return ret;\n};\n\n/**\n * Element Data Store. Allows for binding data to an element without putting it directly on the element.\n * Ex. Event listneres are stored here.\n * (also from jsninja.com, slightly modified and updated for closure compiler)\n * @type {Object}\n * @private\n */\nvjs.cache = {};\n\n/**\n * Unique ID for an element or function\n * @type {Number}\n * @private\n */\nvjs.guid = 1;\n\n/**\n * Unique attribute name to store an element's guid in\n * @type {String}\n * @constant\n * @private\n */\nvjs.expando = 'vdata' + (new Date()).getTime();\n\n/**\n * Returns the cache object where data for an element is stored\n * @param  {Element} el Element to store data for.\n * @return {Object}\n * @private\n */\nvjs.getData = function(el){\n  var id = el[vjs.expando];\n  if (!id) {\n    id = el[vjs.expando] = vjs.guid++;\n    vjs.cache[id] = {};\n  }\n  return vjs.cache[id];\n};\n\n/**\n * Returns the cache object where data for an element is stored\n * @param  {Element} el Element to store data for.\n * @return {Object}\n * @private\n */\nvjs.hasData = function(el){\n  var id = el[vjs.expando];\n  return !(!id || vjs.isEmpty(vjs.cache[id]));\n};\n\n/**\n * Delete data for the element from the cache and the guid attr from getElementById\n * @param  {Element} el Remove data for an element\n * @private\n */\nvjs.removeData = function(el){\n  var id = el[vjs.expando];\n  if (!id) { return; }\n  // Remove all stored data\n  // Changed to = null\n  // http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/\n  // vjs.cache[id] = null;\n  delete vjs.cache[id];\n\n  // Remove the expando property from the DOM node\n  try {\n    delete el[vjs.expando];\n  } catch(e) {\n    if (el.removeAttribute) {\n      el.removeAttribute(vjs.expando);\n    } else {\n      // IE doesn't appear to support removeAttribute on the document element\n      el[vjs.expando] = null;\n    }\n  }\n};\n\n/**\n * Check if an object is empty\n * @param  {Object}  obj The object to check for emptiness\n * @return {Boolean}\n * @private\n */\nvjs.isEmpty = function(obj) {\n  for (var prop in obj) {\n    // Inlude null properties as empty.\n    if (obj[prop] !== null) {\n      return false;\n    }\n  }\n  return true;\n};\n\n/**\n * Add a CSS class name to an element\n * @param {Element} element    Element to add class name to\n * @param {String} classToAdd Classname to add\n * @private\n */\nvjs.addClass = function(element, classToAdd){\n  if ((' '+element.className+' ').indexOf(' '+classToAdd+' ') == -1) {\n    element.className = element.className === '' ? classToAdd : element.className + ' ' + classToAdd;\n  }\n};\n\n/**\n * Remove a CSS class name from an element\n * @param {Element} element    Element to remove from class name\n * @param {String} classToAdd Classname to remove\n * @private\n */\nvjs.removeClass = function(element, classToRemove){\n  var classNames, i;\n\n  if (element.className.indexOf(classToRemove) == -1) { return; }\n\n  classNames = element.className.split(' ');\n\n  // no arr.indexOf in ie8, and we don't want to add a big shim\n  for (i = classNames.length - 1; i >= 0; i--) {\n    if (classNames[i] === classToRemove) {\n      classNames.splice(i,1);\n    }\n  }\n\n  element.className = classNames.join(' ');\n};\n\n/**\n * Element for testing browser HTML5 video capabilities\n * @type {Element}\n * @constant\n * @private\n */\nvjs.TEST_VID = vjs.createEl('video');\n\n/**\n * Useragent for browser testing.\n * @type {String}\n * @constant\n * @private\n */\nvjs.USER_AGENT = navigator.userAgent;\n\n/**\n * Device is an iPhone\n * @type {Boolean}\n * @constant\n * @private\n */\nvjs.IS_IPHONE = (/iPhone/i).test(vjs.USER_AGENT);\nvjs.IS_IPAD = (/iPad/i).test(vjs.USER_AGENT);\nvjs.IS_IPOD = (/iPod/i).test(vjs.USER_AGENT);\nvjs.IS_IOS = vjs.IS_IPHONE || vjs.IS_IPAD || vjs.IS_IPOD;\n\nvjs.IOS_VERSION = (function(){\n  var match = vjs.USER_AGENT.match(/OS (\\d+)_/i);\n  if (match && match[1]) { return match[1]; }\n})();\n\nvjs.IS_ANDROID = (/Android/i).test(vjs.USER_AGENT);\nvjs.ANDROID_VERSION = (function() {\n  // This matches Android Major.Minor.Patch versions\n  // ANDROID_VERSION is Major.Minor as a Number, if Minor isn't available, then only Major is returned\n  var match = vjs.USER_AGENT.match(/Android (\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))*/i),\n    major,\n    minor;\n\n  if (!match) {\n    return null;\n  }\n\n  major = match[1] && parseFloat(match[1]);\n  minor = match[2] && parseFloat(match[2]);\n\n  if (major && minor) {\n    return parseFloat(match[1] + '.' + match[2]);\n  } else if (major) {\n    return major;\n  } else {\n    return null;\n  }\n})();\n// Old Android is defined as Version older than 2.3, and requiring a webkit version of the android browser\nvjs.IS_OLD_ANDROID = vjs.IS_ANDROID && (/webkit/i).test(vjs.USER_AGENT) && vjs.ANDROID_VERSION < 2.3;\n\nvjs.IS_FIREFOX = (/Firefox/i).test(vjs.USER_AGENT);\nvjs.IS_CHROME = (/Chrome/i).test(vjs.USER_AGENT);\n\nvjs.TOUCH_ENABLED = !!(('ontouchstart' in window) || window.DocumentTouch && document instanceof window.DocumentTouch);\n\n/**\n * Get an element's attribute values, as defined on the HTML tag\n * Attributs are not the same as properties. They're defined on the tag\n * or with setAttribute (which shouldn't be used with HTML)\n * This will return true or false for boolean attributes.\n * @param  {Element} tag Element from which to get tag attributes\n * @return {Object}\n * @private\n */\nvjs.getAttributeValues = function(tag){\n  var obj, knownBooleans, attrs, attrName, attrVal;\n\n  obj = {};\n\n  // known boolean attributes\n  // we can check for matching boolean properties, but older browsers\n  // won't know about HTML5 boolean attributes that we still read from\n  knownBooleans = ','+'autoplay,controls,loop,muted,default'+',';\n\n  if (tag && tag.attributes && tag.attributes.length > 0) {\n    attrs = tag.attributes;\n\n    for (var i = attrs.length - 1; i >= 0; i--) {\n      attrName = attrs[i].name;\n      attrVal = attrs[i].value;\n\n      // check for known booleans\n      // the matching element property will return a value for typeof\n      if (typeof tag[attrName] === 'boolean' || knownBooleans.indexOf(','+attrName+',') !== -1) {\n        // the value of an included boolean attribute is typically an empty\n        // string ('') which would equal false if we just check for a false value.\n        // we also don't want support bad code like autoplay='false'\n        attrVal = (attrVal !== null) ? true : false;\n      }\n\n      obj[attrName] = attrVal;\n    }\n  }\n\n  return obj;\n};\n\n/**\n * Get the computed style value for an element\n * From http://robertnyman.com/2006/04/24/get-the-rendered-style-of-an-element/\n * @param  {Element} el        Element to get style value for\n * @param  {String} strCssRule Style name\n * @return {String}            Style value\n * @private\n */\nvjs.getComputedDimension = function(el, strCssRule){\n  var strValue = '';\n  if(document.defaultView && document.defaultView.getComputedStyle){\n    strValue = document.defaultView.getComputedStyle(el, '').getPropertyValue(strCssRule);\n\n  } else if(el.currentStyle){\n    // IE8 Width/Height support\n    strValue = el['client'+strCssRule.substr(0,1).toUpperCase() + strCssRule.substr(1)] + 'px';\n  }\n  return strValue;\n};\n\n/**\n * Insert an element as the first child node of another\n * @param  {Element} child   Element to insert\n * @param  {[type]} parent Element to insert child into\n * @private\n */\nvjs.insertFirst = function(child, parent){\n  if (parent.firstChild) {\n    parent.insertBefore(child, parent.firstChild);\n  } else {\n    parent.appendChild(child);\n  }\n};\n\n/**\n * Object to hold browser support information\n * @type {Object}\n * @private\n */\nvjs.support = {};\n\n/**\n * Shorthand for document.getElementById()\n * Also allows for CSS (jQuery) ID syntax. But nothing other than IDs.\n * @param  {String} id  Element ID\n * @return {Element}    Element with supplied ID\n * @private\n */\nvjs.el = function(id){\n  if (id.indexOf('#') === 0) {\n    id = id.slice(1);\n  }\n\n  return document.getElementById(id);\n};\n\n/**\n * Format seconds as a time string, H:MM:SS or M:SS\n * Supplying a guide (in seconds) will force a number of leading zeros\n * to cover the length of the guide\n * @param  {Number} seconds Number of seconds to be turned into a string\n * @param  {Number} guide   Number (in seconds) to model the string after\n * @return {String}         Time formatted as H:MM:SS or M:SS\n * @private\n */\nvjs.formatTime = function(seconds, guide) {\n  // Default to using seconds as guide\n  guide = guide || seconds;\n  var s = Math.floor(seconds % 60),\n      m = Math.floor(seconds / 60 % 60),\n      h = Math.floor(seconds / 3600),\n      gm = Math.floor(guide / 60 % 60),\n      gh = Math.floor(guide / 3600);\n\n  // handle invalid times\n  if (isNaN(seconds) || seconds === Infinity) {\n    // '-' is false for all relational operators (e.g. <, >=) so this setting\n    // will add the minimum number of fields specified by the guide\n    h = m = s = '-';\n  }\n\n  // Check if we need to show hours\n  h = (h > 0 || gh > 0) ? h + ':' : '';\n\n  // If hours are showing, we may need to add a leading zero.\n  // Always show at least one digit of minutes.\n  m = (((h || gm >= 10) && m < 10) ? '0' + m : m) + ':';\n\n  // Check if leading zero is need for seconds\n  s = (s < 10) ? '0' + s : s;\n\n  return h + m + s;\n};\n\n// Attempt to block the ability to select text while dragging controls\nvjs.blockTextSelection = function(){\n  document.body.focus();\n  document.onselectstart = function () { return false; };\n};\n// Turn off text selection blocking\nvjs.unblockTextSelection = function(){ document.onselectstart = function () { return true; }; };\n\n/**\n * Trim whitespace from the ends of a string.\n * @param  {String} string String to trim\n * @return {String}        Trimmed string\n * @private\n */\nvjs.trim = function(str){\n  return (str+'').replace(/^\\s+|\\s+$/g, '');\n};\n\n/**\n * Should round off a number to a decimal place\n * @param  {Number} num Number to round\n * @param  {Number} dec Number of decimal places to round to\n * @return {Number}     Rounded number\n * @private\n */\nvjs.round = function(num, dec) {\n  if (!dec) { dec = 0; }\n  return Math.round(num*Math.pow(10,dec))/Math.pow(10,dec);\n};\n\n/**\n * Should create a fake TimeRange object\n * Mimics an HTML5 time range instance, which has functions that\n * return the start and end times for a range\n * TimeRanges are returned by the buffered() method\n * @param  {Number} start Start time in seconds\n * @param  {Number} end   End time in seconds\n * @return {Object}       Fake TimeRange object\n * @private\n */\nvjs.createTimeRange = function(start, end){\n  return {\n    length: 1,\n    start: function() { return start; },\n    end: function() { return end; }\n  };\n};\n\n/**\n * Simple http request for retrieving external files (e.g. text tracks)\n * @param  {String} url           URL of resource\n * @param  {Function=} onSuccess  Success callback\n * @param  {Function=} onError    Error callback\n * @private\n */\nvjs.get = function(url, onSuccess, onError){\n  var local, request;\n\n  if (typeof XMLHttpRequest === 'undefined') {\n    window.XMLHttpRequest = function () {\n      try { return new window.ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch (e) {}\n      try { return new window.ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch (f) {}\n      try { return new window.ActiveXObject('Msxml2.XMLHTTP'); } catch (g) {}\n      throw new Error('This browser does not support XMLHttpRequest.');\n    };\n  }\n\n  request = new XMLHttpRequest();\n  try {\n    request.open('GET', url);\n  } catch(e) {\n    onError(e);\n  }\n\n  local = (url.indexOf('file:') === 0 || (window.location.href.indexOf('file:') === 0 && url.indexOf('http') === -1));\n\n  request.onreadystatechange = function() {\n    if (request.readyState === 4) {\n      if (request.status === 200 || local && request.status === 0) {\n        onSuccess(request.responseText);\n      } else {\n        if (onError) {\n          onError();\n        }\n      }\n    }\n  };\n\n  try {\n    request.send();\n  } catch(e) {\n    if (onError) {\n      onError(e);\n    }\n  }\n};\n\n/**\n * Add to local storage (may removeable)\n * @private\n */\nvjs.setLocalStorage = function(key, value){\n  try {\n    // IE was throwing errors referencing the var anywhere without this\n    var localStorage = window.localStorage || false;\n    if (!localStorage) { return; }\n    localStorage[key] = value;\n  } catch(e) {\n    if (e.code == 22 || e.code == 1014) { // Webkit == 22 / Firefox == 1014\n      vjs.log('LocalStorage Full (VideoJS)', e);\n    } else {\n      if (e.code == 18) {\n        vjs.log('LocalStorage not allowed (VideoJS)', e);\n      } else {\n        vjs.log('LocalStorage Error (VideoJS)', e);\n      }\n    }\n  }\n};\n\n/**\n * Get abosolute version of relative URL. Used to tell flash correct URL.\n * http://stackoverflow.com/questions/470832/getting-an-absolute-url-from-a-relative-one-ie6-issue\n * @param  {String} url URL to make absolute\n * @return {String}     Absolute URL\n * @private\n */\nvjs.getAbsoluteURL = function(url){\n\n  // Check if absolute URL\n  if (!url.match(/^https?:\\/\\//)) {\n    // Convert to absolute URL. Flash hosted off-site needs an absolute URL.\n    url = vjs.createEl('div', {\n      innerHTML: '<a href=\"'+url+'\">x</a>'\n    }).firstChild.href;\n  }\n\n  return url;\n};\n\n// usage: log('inside coolFunc',this,arguments);\n// http://paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/\nvjs.log = function(){\n  vjs.log.history = vjs.log.history || [];   // store logs to an array for reference\n  vjs.log.history.push(arguments);\n  if(window.console){\n    window.console.log(Array.prototype.slice.call(arguments));\n  }\n};\n\n// Offset Left\n// getBoundingClientRect technique from John Resig http://ejohn.org/blog/getboundingclientrect-is-awesome/\nvjs.findPosition = function(el) {\n    var box, docEl, body, clientLeft, scrollLeft, left, clientTop, scrollTop, top;\n\n    if (el.getBoundingClientRect && el.parentNode) {\n      box = el.getBoundingClientRect();\n    }\n\n    if (!box) {\n      return {\n        left: 0,\n        top: 0\n      };\n    }\n\n    docEl = document.documentElement;\n    body = document.body;\n\n    clientLeft = docEl.clientLeft || body.clientLeft || 0;\n    scrollLeft = window.pageXOffset || body.scrollLeft;\n    left = box.left + scrollLeft - clientLeft;\n\n    clientTop = docEl.clientTop || body.clientTop || 0;\n    scrollTop = window.pageYOffset || body.scrollTop;\n    top = box.top + scrollTop - clientTop;\n\n    return {\n      left: left,\n      top: top\n    };\n};\n/**\n * @fileoverview Player Component - Base class for all UI objects\n *\n */\n\n/**\n * Base UI Component class\n *\n * Components are embeddable UI objects that are represented by both a\n * javascript object and an element in the DOM. They can be children of other\n * components, and can have many children themselves.\n *\n *     // adding a button to the player\n *     var button = player.addChild('button');\n *     button.el(); // -> button element\n *\n *     <div class=\"video-js\">\n *       <div class=\"vjs-button\">Button</div>\n *     </div>\n *\n * Components are also event emitters.\n *\n *     button.on('click', function(){\n *       console.log('Button Clicked!');\n *     });\n *\n *     button.trigger('customevent');\n *\n * @param {Object} player  Main Player\n * @param {Object=} options\n * @class\n * @constructor\n * @extends vjs.CoreObject\n */\nvjs.Component = vjs.CoreObject.extend({\n  /**\n   * the constructor funciton for the class\n   *\n   * @constructor\n   */\n  init: function(player, options, ready){\n    this.player_ = player;\n\n    // Make a copy of prototype.options_ to protect against overriding global defaults\n    this.options_ = vjs.obj.copy(this.options_);\n\n    // Updated options with supplied options\n    options = this.options(options);\n\n    // Get ID from options, element, or create using player ID and unique ID\n    this.id_ = options['id'] || ((options['el'] && options['el']['id']) ? options['el']['id'] : player.id() + '_component_' + vjs.guid++ );\n\n    this.name_ = options['name'] || null;\n\n    // Create element if one wasn't provided in options\n    this.el_ = options['el'] || this.createEl();\n\n    this.children_ = [];\n    this.childIndex_ = {};\n    this.childNameIndex_ = {};\n\n    // Add any child components in options\n    this.initChildren();\n\n    this.ready(ready);\n    // Don't want to trigger ready here or it will before init is actually\n    // finished for all children that run this constructor\n  }\n});\n\n/**\n * Dispose of the component and all child components\n */\nvjs.Component.prototype.dispose = function(){\n  this.trigger('dispose');\n\n  // Dispose all children.\n  if (this.children_) {\n    for (var i = this.children_.length - 1; i >= 0; i--) {\n      if (this.children_[i].dispose) {\n        this.children_[i].dispose();\n      }\n    }\n  }\n\n  // Delete child references\n  this.children_ = null;\n  this.childIndex_ = null;\n  this.childNameIndex_ = null;\n\n  // Remove all event listeners.\n  this.off();\n\n  // Remove element from DOM\n  if (this.el_.parentNode) {\n    this.el_.parentNode.removeChild(this.el_);\n  }\n\n  vjs.removeData(this.el_);\n  this.el_ = null;\n};\n\n/**\n * Reference to main player instance\n *\n * @type {vjs.Player}\n * @private\n */\nvjs.Component.prototype.player_ = true;\n\n/**\n * Return the component's player\n *\n * @return {vjs.Player}\n */\nvjs.Component.prototype.player = function(){\n  return this.player_;\n};\n\n/**\n * The component's options object\n *\n * @type {Object}\n * @private\n */\nvjs.Component.prototype.options_;\n\n/**\n * Deep merge of options objects\n *\n * Whenever a property is an object on both options objects\n * the two properties will be merged using vjs.obj.deepMerge.\n *\n * This is used for merging options for child components. We\n * want it to be easy to override individual options on a child\n * component without having to rewrite all the other default options.\n *\n *     Parent.prototype.options_ = {\n *       children: {\n *         'childOne': { 'foo': 'bar', 'asdf': 'fdsa' },\n *         'childTwo': {},\n *         'childThree': {}\n *       }\n *     }\n *     newOptions = {\n *       children: {\n *         'childOne': { 'foo': 'baz', 'abc': '123' }\n *         'childTwo': null,\n *         'childFour': {}\n *       }\n *     }\n *\n *     this.options(newOptions);\n *\n * RESULT\n *\n *     {\n *       children: {\n *         'childOne': { 'foo': 'baz', 'asdf': 'fdsa', 'abc': '123' },\n *         'childTwo': null, // Disabled. Won't be initialized.\n *         'childThree': {},\n *         'childFour': {}\n *       }\n *     }\n *\n * @param  {Object} obj Object whose values will be overwritten\n * @return {Object}     NEW merged object. Does not return obj1.\n */\nvjs.Component.prototype.options = function(obj){\n  if (obj === undefined) return this.options_;\n\n  return this.options_ = vjs.obj.deepMerge(this.options_, obj);\n};\n\n/**\n * The DOM element for the component\n *\n * @type {Element}\n * @private\n */\nvjs.Component.prototype.el_;\n\n/**\n * Create the component's DOM element\n *\n * @param  {String=} tagName  Element's node type. e.g. 'div'\n * @param  {Object=} attributes An object of element attributes that should be set on the element\n * @return {Element}\n */\nvjs.Component.prototype.createEl = function(tagName, attributes){\n  return vjs.createEl(tagName, attributes);\n};\n\n/**\n * Get the component's DOM element\n *\n *     var domEl = myComponent.el();\n *\n * @return {Element}\n */\nvjs.Component.prototype.el = function(){\n  return this.el_;\n};\n\n/**\n * An optional element where, if defined, children will be inserted instead of\n * directly in `el_`\n *\n * @type {Element}\n * @private\n */\nvjs.Component.prototype.contentEl_;\n\n/**\n * Return the component's DOM element for embedding content.\n * Will either be el_ or a new element defined in createEl.\n *\n * @return {Element}\n */\nvjs.Component.prototype.contentEl = function(){\n  return this.contentEl_ || this.el_;\n};\n\n/**\n * The ID for the component\n *\n * @type {String}\n * @private\n */\nvjs.Component.prototype.id_;\n\n/**\n * Get the component's ID\n *\n *     var id = myComponent.id();\n *\n * @return {String}\n */\nvjs.Component.prototype.id = function(){\n  return this.id_;\n};\n\n/**\n * The name for the component. Often used to reference the component.\n *\n * @type {String}\n * @private\n */\nvjs.Component.prototype.name_;\n\n/**\n * Get the component's name. The name is often used to reference the component.\n *\n *     var name = myComponent.name();\n *\n * @return {String}\n */\nvjs.Component.prototype.name = function(){\n  return this.name_;\n};\n\n/**\n * Array of child components\n *\n * @type {Array}\n * @private\n */\nvjs.Component.prototype.children_;\n\n/**\n * Get an array of all child components\n *\n *     var kids = myComponent.children();\n *\n * @return {Array} The children\n */\nvjs.Component.prototype.children = function(){\n  return this.children_;\n};\n\n/**\n * Object of child components by ID\n *\n * @type {Object}\n * @private\n */\nvjs.Component.prototype.childIndex_;\n\n/**\n * Returns a child component with the provided ID\n *\n * @return {vjs.Component}\n */\nvjs.Component.prototype.getChildById = function(id){\n  return this.childIndex_[id];\n};\n\n/**\n * Object of child components by name\n *\n * @type {Object}\n * @private\n */\nvjs.Component.prototype.childNameIndex_;\n\n/**\n * Returns a child component with the provided ID\n *\n * @return {vjs.Component}\n */\nvjs.Component.prototype.getChild = function(name){\n  return this.childNameIndex_[name];\n};\n\n/**\n * Adds a child component inside this component\n *\n *     myComponent.el();\n *     // -> <div class='my-component'></div>\n *     myComonent.children();\n *     // [empty array]\n *\n *     var myButton = myComponent.addChild('MyButton');\n *     // -> <div class='my-component'><div class=\"my-button\">myButton<div></div>\n *     // -> myButton === myComonent.children()[0];\n *\n * Pass in options for child constructors and options for children of the child\n *\n *    var myButton = myComponent.addChild('MyButton', {\n *      text: 'Press Me',\n *      children: {\n *        buttonChildExample: {\n *          buttonChildOption: true\n *        }\n *      }\n *    });\n *\n * @param {String|vjs.Component} child The class name or instance of a child to add\n * @param {Object=} options Options, including options to be passed to children of the child.\n * @return {vjs.Component} The child component (created by this process if a string was used)\n * @suppress {accessControls|checkRegExp|checkTypes|checkVars|const|constantProperty|deprecated|duplicate|es5Strict|fileoverviewTags|globalThis|invalidCasts|missingProperties|nonStandardJsDocs|strictModuleDepCheck|undefinedNames|undefinedVars|unknownDefines|uselessCode|visibility}\n */\nvjs.Component.prototype.addChild = function(child, options){\n  var component, componentClass, componentName, componentId;\n\n  // If string, create new component with options\n  if (typeof child === 'string') {\n\n    componentName = child;\n\n    // Make sure options is at least an empty object to protect against errors\n    options = options || {};\n\n    // Assume name of set is a lowercased name of the UI Class (PlayButton, etc.)\n    componentClass = options['componentClass'] || vjs.capitalize(componentName);\n\n    // Set name through options\n    options['name'] = componentName;\n\n    // Create a new object & element for this controls set\n    // If there's no .player_, this is a player\n    // Closure Compiler throws an 'incomplete alias' warning if we use the vjs variable directly.\n    // Every class should be exported, so this should never be a problem here.\n    component = new window['videojs'][componentClass](this.player_ || this, options);\n\n  // child is a component instance\n  } else {\n    component = child;\n  }\n\n  this.children_.push(component);\n\n  if (typeof component.id === 'function') {\n    this.childIndex_[component.id()] = component;\n  }\n\n  // If a name wasn't used to create the component, check if we can use the\n  // name function of the component\n  componentName = componentName || (component.name && component.name());\n\n  if (componentName) {\n    this.childNameIndex_[componentName] = component;\n  }\n\n  // Add the UI object's element to the container div (box)\n  // Having an element is not required\n  if (typeof component['el'] === 'function' && component['el']()) {\n    this.contentEl().appendChild(component['el']());\n  }\n\n  // Return so it can stored on parent object if desired.\n  return component;\n};\n\n/**\n * Remove a child component from this component's list of children, and the\n * child component's element from this component's element\n *\n * @param  {vjs.Component} component Component to remove\n */\nvjs.Component.prototype.removeChild = function(component){\n  if (typeof component === 'string') {\n    component = this.getChild(component);\n  }\n\n  if (!component || !this.children_) return;\n\n  var childFound = false;\n  for (var i = this.children_.length - 1; i >= 0; i--) {\n    if (this.children_[i] === component) {\n      childFound = true;\n      this.children_.splice(i,1);\n      break;\n    }\n  }\n\n  if (!childFound) return;\n\n  this.childIndex_[component.id] = null;\n  this.childNameIndex_[component.name] = null;\n\n  var compEl = component.el();\n  if (compEl && compEl.parentNode === this.contentEl()) {\n    this.contentEl().removeChild(component.el());\n  }\n};\n\n/**\n * Add and initialize default child components from options\n *\n *     // when an instance of MyComponent is created, all children in options\n *     // will be added to the instance by their name strings and options\n *     MyComponent.prototype.options_.children = {\n *       myChildComponent: {\n *         myChildOption: true\n *       }\n *     }\n */\nvjs.Component.prototype.initChildren = function(){\n  var options = this.options_;\n\n  if (options && options['children']) {\n    var self = this;\n\n    // Loop through components and add them to the player\n    vjs.obj.each(options['children'], function(name, opts){\n      // Allow for disabling default components\n      // e.g. vjs.options['children']['posterImage'] = false\n      if (opts === false) return;\n\n      // Allow waiting to add components until a specific event is called\n      var tempAdd = function(){\n        // Set property name on player. Could cause conflicts with other prop names, but it's worth making refs easy.\n        self[name] = self.addChild(name, opts);\n      };\n\n      if (opts['loadEvent']) {\n        // this.one(opts.loadEvent, tempAdd)\n      } else {\n        tempAdd();\n      }\n    });\n  }\n};\n\n/**\n * Allows sub components to stack CSS class names\n *\n * @return {String} The constructed class name\n */\nvjs.Component.prototype.buildCSSClass = function(){\n    // Child classes can include a function that does:\n    // return 'CLASS NAME' + this._super();\n    return '';\n};\n\n/* Events\n============================================================================= */\n\n/**\n * Add an event listener to this component's element\n *\n *     var myFunc = function(){\n *       var myPlayer = this;\n *       // Do something when the event is fired\n *     };\n *\n *     myPlayer.on(\"eventName\", myFunc);\n *\n * The context will be the component.\n *\n * @param  {String}   type The event type e.g. 'click'\n * @param  {Function} fn   The event listener\n * @return {vjs.Component} self\n */\nvjs.Component.prototype.on = function(type, fn){\n  vjs.on(this.el_, type, vjs.bind(this, fn));\n  return this;\n};\n\n/**\n * Remove an event listener from the component's element\n *\n *     myComponent.off(\"eventName\", myFunc);\n *\n * @param  {String=}   type Event type. Without type it will remove all listeners.\n * @param  {Function=} fn   Event listener. Without fn it will remove all listeners for a type.\n * @return {vjs.Component}\n */\nvjs.Component.prototype.off = function(type, fn){\n  vjs.off(this.el_, type, fn);\n  return this;\n};\n\n/**\n * Add an event listener to be triggered only once and then removed\n *\n * @param  {String}   type Event type\n * @param  {Function} fn   Event listener\n * @return {vjs.Component}\n */\nvjs.Component.prototype.one = function(type, fn) {\n  vjs.one(this.el_, type, vjs.bind(this, fn));\n  return this;\n};\n\n/**\n * Trigger an event on an element\n *\n *     myComponent.trigger('eventName');\n *\n * @param  {String}       type  The event type to trigger, e.g. 'click'\n * @param  {Event|Object} event The event object to be passed to the listener\n * @return {vjs.Component}      self\n */\nvjs.Component.prototype.trigger = function(type, event){\n  vjs.trigger(this.el_, type, event);\n  return this;\n};\n\n/* Ready\n================================================================================ */\n/**\n * Is the component loaded\n * This can mean different things depending on the component.\n *\n * @private\n * @type {Boolean}\n */\nvjs.Component.prototype.isReady_;\n\n/**\n * Trigger ready as soon as initialization is finished\n *\n * Allows for delaying ready. Override on a sub class prototype.\n * If you set this.isReadyOnInitFinish_ it will affect all components.\n * Specially used when waiting for the Flash player to asynchrnously load.\n *\n * @type {Boolean}\n * @private\n */\nvjs.Component.prototype.isReadyOnInitFinish_ = true;\n\n/**\n * List of ready listeners\n *\n * @type {Array}\n * @private\n */\nvjs.Component.prototype.readyQueue_;\n\n/**\n * Bind a listener to the component's ready state\n *\n * Different from event listeners in that if the ready event has already happend\n * it will trigger the function immediately.\n *\n * @param  {Function} fn Ready listener\n * @return {vjs.Component}\n */\nvjs.Component.prototype.ready = function(fn){\n  if (fn) {\n    if (this.isReady_) {\n      fn.call(this);\n    } else {\n      if (this.readyQueue_ === undefined) {\n        this.readyQueue_ = [];\n      }\n      this.readyQueue_.push(fn);\n    }\n  }\n  return this;\n};\n\n/**\n * Trigger the ready listeners\n *\n * @return {vjs.Component}\n */\nvjs.Component.prototype.triggerReady = function(){\n  this.isReady_ = true;\n\n  var readyQueue = this.readyQueue_;\n\n  if (readyQueue && readyQueue.length > 0) {\n\n    for (var i = 0, j = readyQueue.length; i < j; i++) {\n      readyQueue[i].call(this);\n    }\n\n    // Reset Ready Queue\n    this.readyQueue_ = [];\n\n    // Allow for using event listeners also, in case you want to do something everytime a source is ready.\n    this.trigger('ready');\n  }\n};\n\n/* Display\n============================================================================= */\n\n/**\n * Add a CSS class name to the component's element\n *\n * @param {String} classToAdd Classname to add\n * @return {vjs.Component}\n */\nvjs.Component.prototype.addClass = function(classToAdd){\n  vjs.addClass(this.el_, classToAdd);\n  return this;\n};\n\n/**\n * Remove a CSS class name from the component's element\n *\n * @param {String} classToRemove Classname to remove\n * @return {vjs.Component}\n */\nvjs.Component.prototype.removeClass = function(classToRemove){\n  vjs.removeClass(this.el_, classToRemove);\n  return this;\n};\n\n/**\n * Show the component element if hidden\n *\n * @return {vjs.Component}\n */\nvjs.Component.prototype.show = function(){\n  this.el_.style.display = 'block';\n  return this;\n};\n\n/**\n * Hide the component element if hidden\n *\n * @return {vjs.Component}\n */\nvjs.Component.prototype.hide = function(){\n  this.el_.style.display = 'none';\n  return this;\n};\n\n/**\n * Lock an item in its visible state\n * To be used with fadeIn/fadeOut.\n *\n * @return {vjs.Component}\n * @private\n */\nvjs.Component.prototype.lockShowing = function(){\n  this.addClass('vjs-lock-showing');\n  return this;\n};\n\n/**\n * Unlock an item to be hidden\n * To be used with fadeIn/fadeOut.\n *\n * @return {vjs.Component}\n * @private\n */\nvjs.Component.prototype.unlockShowing = function(){\n  this.removeClass('vjs-lock-showing');\n  return this;\n};\n\n/**\n * Disable component by making it unshowable\n */\nvjs.Component.prototype.disable = function(){\n  this.hide();\n  this.show = function(){};\n};\n\n/**\n * Set or get the width of the component (CSS values)\n *\n * Video tag width/height only work in pixels. No percents.\n * But allowing limited percents use. e.g. width() will return number+%, not computed width\n *\n * @param  {Number|String=} num   Optional width number\n * @param  {Boolean} skipListeners Skip the 'resize' event trigger\n * @return {vjs.Component} Returns 'this' if width was set\n * @return {Number|String} Returns the width if nothing was set\n */\nvjs.Component.prototype.width = function(num, skipListeners){\n  return this.dimension('width', num, skipListeners);\n};\n\n/**\n * Get or set the height of the component (CSS values)\n *\n * @param  {Number|String=} num     New component height\n * @param  {Boolean=} skipListeners Skip the resize event trigger\n * @return {vjs.Component} The component if the height was set\n * @return {Number|String} The height if it wasn't set\n */\nvjs.Component.prototype.height = function(num, skipListeners){\n  return this.dimension('height', num, skipListeners);\n};\n\n/**\n * Set both width and height at the same time\n *\n * @param  {Number|String} width\n * @param  {Number|String} height\n * @return {vjs.Component} The component\n */\nvjs.Component.prototype.dimensions = function(width, height){\n  // Skip resize listeners on width for optimization\n  return this.width(width, true).height(height);\n};\n\n/**\n * Get or set width or height\n *\n * This is the shared code for the width() and height() methods.\n * All for an integer, integer + 'px' or integer + '%';\n *\n * Known issue: Hidden elements officially have a width of 0. We're defaulting\n * to the style.width value and falling back to computedStyle which has the\n * hidden element issue. Info, but probably not an efficient fix:\n * http://www.foliotek.com/devblog/getting-the-width-of-a-hidden-element-with-jquery-using-width/\n *\n * @param  {String} widthOrHeight  'width' or 'height'\n * @param  {Number|String=} num     New dimension\n * @param  {Boolean=} skipListeners Skip resize event trigger\n * @return {vjs.Component} The component if a dimension was set\n * @return {Number|String} The dimension if nothing was set\n * @private\n */\nvjs.Component.prototype.dimension = function(widthOrHeight, num, skipListeners){\n  if (num !== undefined) {\n\n    // Check if using css width/height (% or px) and adjust\n    if ((''+num).indexOf('%') !== -1 || (''+num).indexOf('px') !== -1) {\n      this.el_.style[widthOrHeight] = num;\n    } else if (num === 'auto') {\n      this.el_.style[widthOrHeight] = '';\n    } else {\n      this.el_.style[widthOrHeight] = num+'px';\n    }\n\n    // skipListeners allows us to avoid triggering the resize event when setting both width and height\n    if (!skipListeners) { this.trigger('resize'); }\n\n    // Return component\n    return this;\n  }\n\n  // Not setting a value, so getting it\n  // Make sure element exists\n  if (!this.el_) return 0;\n\n  // Get dimension value from style\n  var val = this.el_.style[widthOrHeight];\n  var pxIndex = val.indexOf('px');\n  if (pxIndex !== -1) {\n    // Return the pixel value with no 'px'\n    return parseInt(val.slice(0,pxIndex), 10);\n\n  // No px so using % or no style was set, so falling back to offsetWidth/height\n  // If component has display:none, offset will return 0\n  // TODO: handle display:none and no dimension style using px\n  } else {\n\n    return parseInt(this.el_['offset'+vjs.capitalize(widthOrHeight)], 10);\n\n    // ComputedStyle version.\n    // Only difference is if the element is hidden it will return\n    // the percent value (e.g. '100%'')\n    // instead of zero like offsetWidth returns.\n    // var val = vjs.getComputedStyleValue(this.el_, widthOrHeight);\n    // var pxIndex = val.indexOf('px');\n\n    // if (pxIndex !== -1) {\n    //   return val.slice(0, pxIndex);\n    // } else {\n    //   return val;\n    // }\n  }\n};\n\n/**\n * Fired when the width and/or height of the component changes\n * @event resize\n */\nvjs.Component.prototype.onResize;\n\n/**\n * Emit 'tap' events when touch events are supported\n *\n * This is used to support toggling the controls through a tap on the video.\n *\n * We're requireing them to be enabled because otherwise every component would\n * have this extra overhead unnecessarily, on mobile devices where extra\n * overhead is especially bad.\n * @private\n */\nvjs.Component.prototype.emitTapEvents = function(){\n  var touchStart, touchTime, couldBeTap, noTap;\n\n  // Track the start time so we can determine how long the touch lasted\n  touchStart = 0;\n\n  this.on('touchstart', function(event) {\n    // Record start time so we can detect a tap vs. \"touch and hold\"\n    touchStart = new Date().getTime();\n    // Reset couldBeTap tracking\n    couldBeTap = true;\n  });\n\n  noTap = function(){\n    couldBeTap = false;\n  };\n  // TODO: Listen to the original target. http://youtu.be/DujfpXOKUp8?t=13m8s\n  this.on('touchmove', noTap);\n  this.on('touchleave', noTap);\n  this.on('touchcancel', noTap);\n\n  // When the touch ends, measure how long it took and trigger the appropriate\n  // event\n  this.on('touchend', function() {\n    // Proceed only if the touchmove/leave/cancel event didn't happen\n    if (couldBeTap === true) {\n      // Measure how long the touch lasted\n      touchTime = new Date().getTime() - touchStart;\n      // The touch needs to be quick in order to consider it a tap\n      if (touchTime < 250) {\n        this.trigger('tap');\n        // It may be good to copy the touchend event object and change the\n        // type to tap, if the other event properties aren't exact after\n        // vjs.fixEvent runs (e.g. event.target)\n      }\n    }\n  });\n};\n/* Button - Base class for all buttons\n================================================================================ */\n/**\n * Base class for all buttons\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @class\n * @constructor\n */\nvjs.Button = vjs.Component.extend({\n  /**\n   * @constructor\n   * @inheritDoc\n   */\n  init: function(player, options){\n    vjs.Component.call(this, player, options);\n\n    var touchstart = false;\n    this.on('touchstart', function(event) {\n      // Stop click and other mouse events from triggering also\n      event.preventDefault();\n      touchstart = true;\n    });\n    this.on('touchmove', function() {\n      touchstart = false;\n    });\n    var self = this;\n    this.on('touchend', function(event) {\n      if (touchstart) {\n        self.onClick(event);\n      }\n      event.preventDefault();\n    });\n\n    this.on('click', this.onClick);\n    this.on('focus', this.onFocus);\n    this.on('blur', this.onBlur);\n  }\n});\n\nvjs.Button.prototype.createEl = function(type, props){\n  // Add standard Aria and Tabindex info\n  props = vjs.obj.merge({\n    className: this.buildCSSClass(),\n    innerHTML: '<div class=\"vjs-control-content\"><span class=\"vjs-control-text\">' + (this.buttonText || 'Need Text') + '</span></div>',\n    role: 'button',\n    'aria-live': 'polite', // let the screen reader user know that the text of the button may change\n    tabIndex: 0\n  }, props);\n\n  return vjs.Component.prototype.createEl.call(this, type, props);\n};\n\nvjs.Button.prototype.buildCSSClass = function(){\n  // TODO: Change vjs-control to vjs-button?\n  return 'vjs-control ' + vjs.Component.prototype.buildCSSClass.call(this);\n};\n\n  // Click - Override with specific functionality for button\nvjs.Button.prototype.onClick = function(){};\n\n  // Focus - Add keyboard functionality to element\nvjs.Button.prototype.onFocus = function(){\n  vjs.on(document, 'keyup', vjs.bind(this, this.onKeyPress));\n};\n\n  // KeyPress (document level) - Trigger click when keys are pressed\nvjs.Button.prototype.onKeyPress = function(event){\n  // Check for space bar (32) or enter (13) keys\n  if (event.which == 32 || event.which == 13) {\n    event.preventDefault();\n    this.onClick();\n  }\n};\n\n// Blur - Remove keyboard triggers\nvjs.Button.prototype.onBlur = function(){\n  vjs.off(document, 'keyup', vjs.bind(this, this.onKeyPress));\n};\n/* Slider\n================================================================================ */\n/**\n * The base functionality for sliders like the volume bar and seek bar\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.Slider = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Component.call(this, player, options);\n\n    // Set property names to bar and handle to match with the child Slider class is looking for\n    this.bar = this.getChild(this.options_['barName']);\n    this.handle = this.getChild(this.options_['handleName']);\n\n    player.on(this.playerEvent, vjs.bind(this, this.update));\n\n    this.on('mousedown', this.onMouseDown);\n    this.on('touchstart', this.onMouseDown);\n    this.on('focus', this.onFocus);\n    this.on('blur', this.onBlur);\n    this.on('click', this.onClick);\n\n    this.player_.on('controlsvisible', vjs.bind(this, this.update));\n\n    // This is actually to fix the volume handle position. http://twitter.com/#!/gerritvanaaken/status/159046254519787520\n    // this.player_.one('timeupdate', vjs.bind(this, this.update));\n\n    player.ready(vjs.bind(this, this.update));\n\n    this.boundEvents = {};\n  }\n});\n\nvjs.Slider.prototype.createEl = function(type, props) {\n  props = props || {};\n  // Add the slider element class to all sub classes\n  props.className = props.className + ' vjs-slider';\n  props = vjs.obj.merge({\n    role: 'slider',\n    'aria-valuenow': 0,\n    'aria-valuemin': 0,\n    'aria-valuemax': 100,\n    tabIndex: 0\n  }, props);\n\n  return vjs.Component.prototype.createEl.call(this, type, props);\n};\n\nvjs.Slider.prototype.onMouseDown = function(event){\n  event.preventDefault();\n  vjs.blockTextSelection();\n\n  this.boundEvents.move = vjs.bind(this, this.onMouseMove);\n  this.boundEvents.end = vjs.bind(this, this.onMouseUp);\n\n  vjs.on(document, 'mousemove', this.boundEvents.move);\n  vjs.on(document, 'mouseup', this.boundEvents.end);\n  vjs.on(document, 'touchmove', this.boundEvents.move);\n  vjs.on(document, 'touchend', this.boundEvents.end);\n\n  this.onMouseMove(event);\n};\n\nvjs.Slider.prototype.onMouseUp = function() {\n  vjs.unblockTextSelection();\n  vjs.off(document, 'mousemove', this.boundEvents.move, false);\n  vjs.off(document, 'mouseup', this.boundEvents.end, false);\n  vjs.off(document, 'touchmove', this.boundEvents.move, false);\n  vjs.off(document, 'touchend', this.boundEvents.end, false);\n\n  this.update();\n};\n\nvjs.Slider.prototype.update = function(){\n  // In VolumeBar init we have a setTimeout for update that pops and update to the end of the\n  // execution stack. The player is destroyed before then update will cause an error\n  if (!this.el_) return;\n\n  // If scrubbing, we could use a cached value to make the handle keep up with the user's mouse.\n  // On HTML5 browsers scrubbing is really smooth, but some flash players are slow, so we might want to utilize this later.\n  // var progress =  (this.player_.scrubbing) ? this.player_.getCache().currentTime / this.player_.duration() : this.player_.currentTime() / this.player_.duration();\n\n  var barProgress,\n      progress = this.getPercent(),\n      handle = this.handle,\n      bar = this.bar;\n\n  // Protect against no duration and other division issues\n  if (isNaN(progress)) { progress = 0; }\n\n  barProgress = progress;\n\n  // If there is a handle, we need to account for the handle in our calculation for progress bar\n  // so that it doesn't fall short of or extend past the handle.\n  if (handle) {\n\n    var box = this.el_,\n        boxWidth = box.offsetWidth,\n\n        handleWidth = handle.el().offsetWidth,\n\n        // The width of the handle in percent of the containing box\n        // In IE, widths may not be ready yet causing NaN\n        handlePercent = (handleWidth) ? handleWidth / boxWidth : 0,\n\n        // Get the adjusted size of the box, considering that the handle's center never touches the left or right side.\n        // There is a margin of half the handle's width on both sides.\n        boxAdjustedPercent = 1 - handlePercent,\n\n        // Adjust the progress that we'll use to set widths to the new adjusted box width\n        adjustedProgress = progress * boxAdjustedPercent;\n\n    // The bar does reach the left side, so we need to account for this in the bar's width\n    barProgress = adjustedProgress + (handlePercent / 2);\n\n    // Move the handle from the left based on the adjected progress\n    handle.el().style.left = vjs.round(adjustedProgress * 100, 2) + '%';\n  }\n\n  // Set the new bar width\n  bar.el().style.width = vjs.round(barProgress * 100, 2) + '%';\n};\n\nvjs.Slider.prototype.calculateDistance = function(event){\n  var el, box, boxX, boxY, boxW, boxH, handle, pageX, pageY;\n\n  el = this.el_;\n  box = vjs.findPosition(el);\n  boxW = boxH = el.offsetWidth;\n  handle = this.handle;\n\n  if (this.options_.vertical) {\n    boxY = box.top;\n\n    if (event.changedTouches) {\n      pageY = event.changedTouches[0].pageY;\n    } else {\n      pageY = event.pageY;\n    }\n\n    if (handle) {\n      var handleH = handle.el().offsetHeight;\n      // Adjusted X and Width, so handle doesn't go outside the bar\n      boxY = boxY + (handleH / 2);\n      boxH = boxH - handleH;\n    }\n\n    // Percent that the click is through the adjusted area\n    return Math.max(0, Math.min(1, ((boxY - pageY) + boxH) / boxH));\n\n  } else {\n    boxX = box.left;\n\n    if (event.changedTouches) {\n      pageX = event.changedTouches[0].pageX;\n    } else {\n      pageX = event.pageX;\n    }\n\n    if (handle) {\n      var handleW = handle.el().offsetWidth;\n\n      // Adjusted X and Width, so handle doesn't go outside the bar\n      boxX = boxX + (handleW / 2);\n      boxW = boxW - handleW;\n    }\n\n    // Percent that the click is through the adjusted area\n    return Math.max(0, Math.min(1, (pageX - boxX) / boxW));\n  }\n};\n\nvjs.Slider.prototype.onFocus = function(){\n  vjs.on(document, 'keyup', vjs.bind(this, this.onKeyPress));\n};\n\nvjs.Slider.prototype.onKeyPress = function(event){\n  if (event.which == 37) { // Left Arrow\n    event.preventDefault();\n    this.stepBack();\n  } else if (event.which == 39) { // Right Arrow\n    event.preventDefault();\n    this.stepForward();\n  }\n};\n\nvjs.Slider.prototype.onBlur = function(){\n  vjs.off(document, 'keyup', vjs.bind(this, this.onKeyPress));\n};\n\n/**\n * Listener for click events on slider, used to prevent clicks\n *   from bubbling up to parent elements like button menus.\n * @param  {Object} event Event object\n */\nvjs.Slider.prototype.onClick = function(event){\n  event.stopImmediatePropagation();\n  event.preventDefault();\n};\n\n/**\n * SeekBar Behavior includes play progress bar, and seek handle\n * Needed so it can determine seek position based on handle position/size\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.SliderHandle = vjs.Component.extend();\n\n/**\n * Default value of the slider\n *\n * @type {Number}\n * @private\n */\nvjs.SliderHandle.prototype.defaultValue = 0;\n\n/** @inheritDoc */\nvjs.SliderHandle.prototype.createEl = function(type, props) {\n  props = props || {};\n  // Add the slider element class to all sub classes\n  props.className = props.className + ' vjs-slider-handle';\n  props = vjs.obj.merge({\n    innerHTML: '<span class=\"vjs-control-text\">'+this.defaultValue+'</span>'\n  }, props);\n\n  return vjs.Component.prototype.createEl.call(this, 'div', props);\n};\n/* Menu\n================================================================================ */\n/**\n * The Menu component is used to build pop up menus, including subtitle and\n * captions selection menus.\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @class\n * @constructor\n */\nvjs.Menu = vjs.Component.extend();\n\n/**\n * Add a menu item to the menu\n * @param {Object|String} component Component or component type to add\n */\nvjs.Menu.prototype.addItem = function(component){\n  this.addChild(component);\n  component.on('click', vjs.bind(this, function(){\n    this.unlockShowing();\n  }));\n};\n\n/** @inheritDoc */\nvjs.Menu.prototype.createEl = function(){\n  var contentElType = this.options().contentElType || 'ul';\n  this.contentEl_ = vjs.createEl(contentElType, {\n    className: 'vjs-menu-content'\n  });\n  var el = vjs.Component.prototype.createEl.call(this, 'div', {\n    append: this.contentEl_,\n    className: 'vjs-menu'\n  });\n  el.appendChild(this.contentEl_);\n\n  // Prevent clicks from bubbling up. Needed for Menu Buttons,\n  // where a click on the parent is significant\n  vjs.on(el, 'click', function(event){\n    event.preventDefault();\n    event.stopImmediatePropagation();\n  });\n\n  return el;\n};\n\n/**\n * The component for a menu item. `<li>`\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @class\n * @constructor\n */\nvjs.MenuItem = vjs.Button.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Button.call(this, player, options);\n    this.selected(options['selected']);\n  }\n});\n\n/** @inheritDoc */\nvjs.MenuItem.prototype.createEl = function(type, props){\n  return vjs.Button.prototype.createEl.call(this, 'li', vjs.obj.merge({\n    className: 'vjs-menu-item',\n    innerHTML: this.options_['label']\n  }, props));\n};\n\n/**\n * Handle a click on the menu item, and set it to selected\n */\nvjs.MenuItem.prototype.onClick = function(){\n  this.selected(true);\n};\n\n/**\n * Set this menu item as selected or not\n * @param  {Boolean} selected\n */\nvjs.MenuItem.prototype.selected = function(selected){\n  if (selected) {\n    this.addClass('vjs-selected');\n    this.el_.setAttribute('aria-selected',true);\n  } else {\n    this.removeClass('vjs-selected');\n    this.el_.setAttribute('aria-selected',false);\n  }\n};\n\n\n/**\n * A button class with a popup menu\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.MenuButton = vjs.Button.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Button.call(this, player, options);\n\n    this.menu = this.createMenu();\n\n    // Add list to element\n    this.addChild(this.menu);\n\n    // Automatically hide empty menu buttons\n    if (this.items && this.items.length === 0) {\n      this.hide();\n    }\n\n    this.on('keyup', this.onKeyPress);\n    this.el_.setAttribute('aria-haspopup', true);\n    this.el_.setAttribute('role', 'button');\n  }\n});\n\n/**\n * Track the state of the menu button\n * @type {Boolean}\n * @private\n */\nvjs.MenuButton.prototype.buttonPressed_ = false;\n\nvjs.MenuButton.prototype.createMenu = function(){\n  var menu = new vjs.Menu(this.player_);\n\n  // Add a title list item to the top\n  if (this.options().title) {\n    menu.el().appendChild(vjs.createEl('li', {\n      className: 'vjs-menu-title',\n      innerHTML: vjs.capitalize(this.kind_),\n      tabindex: -1\n    }));\n  }\n\n  this.items = this['createItems']();\n\n  if (this.items) {\n    // Add menu items to the menu\n    for (var i = 0; i < this.items.length; i++) {\n      menu.addItem(this.items[i]);\n    }\n  }\n\n  return menu;\n};\n\n/**\n * Create the list of menu items. Specific to each subclass.\n */\nvjs.MenuButton.prototype.createItems = function(){};\n\n/** @inheritDoc */\nvjs.MenuButton.prototype.buildCSSClass = function(){\n  return this.className + ' vjs-menu-button ' + vjs.Button.prototype.buildCSSClass.call(this);\n};\n\n// Focus - Add keyboard functionality to element\n// This function is not needed anymore. Instead, the keyboard functionality is handled by\n// treating the button as triggering a submenu. When the button is pressed, the submenu\n// appears. Pressing the button again makes the submenu disappear.\nvjs.MenuButton.prototype.onFocus = function(){};\n// Can't turn off list display that we turned on with focus, because list would go away.\nvjs.MenuButton.prototype.onBlur = function(){};\n\nvjs.MenuButton.prototype.onClick = function(){\n  // When you click the button it adds focus, which will show the menu indefinitely.\n  // So we'll remove focus when the mouse leaves the button.\n  // Focus is needed for tab navigation.\n  this.one('mouseout', vjs.bind(this, function(){\n    this.menu.unlockShowing();\n    this.el_.blur();\n  }));\n  if (this.buttonPressed_){\n    this.unpressButton();\n  } else {\n    this.pressButton();\n  }\n};\n\nvjs.MenuButton.prototype.onKeyPress = function(event){\n  event.preventDefault();\n\n  // Check for space bar (32) or enter (13) keys\n  if (event.which == 32 || event.which == 13) {\n    if (this.buttonPressed_){\n      this.unpressButton();\n    } else {\n      this.pressButton();\n    }\n  // Check for escape (27) key\n  } else if (event.which == 27){\n    if (this.buttonPressed_){\n      this.unpressButton();\n    }\n  }\n};\n\nvjs.MenuButton.prototype.pressButton = function(){\n  this.buttonPressed_ = true;\n  this.menu.lockShowing();\n  this.el_.setAttribute('aria-pressed', true);\n  if (this.items && this.items.length > 0) {\n    this.items[0].el().focus(); // set the focus to the title of the submenu\n  }\n};\n\nvjs.MenuButton.prototype.unpressButton = function(){\n  this.buttonPressed_ = false;\n  this.menu.unlockShowing();\n  this.el_.setAttribute('aria-pressed', false);\n};\n\n/**\n * An instance of the `vjs.Player` class is created when any of the Video.js setup methods are used to initialize a video.\n *\n * ```js\n * var myPlayer = videojs('example_video_1');\n * ```\n *\n * In the follwing example, the `data-setup` attribute tells the Video.js library to create a player instance when the library is ready.\n *\n * ```html\n * <video id=\"example_video_1\" data-setup='{}' controls>\n *   <source src=\"my-source.mp4\" type=\"video/mp4\">\n * </video>\n * ```\n *\n * After an instance has been created it can be accessed globally using `Video('example_video_1')`.\n *\n * @class\n * @extends vjs.Component\n */\nvjs.Player = vjs.Component.extend({\n\n  /**\n   * player's constructor function\n   *\n   * @constructs\n   * @method init\n   * @param {Element} tag        The original video tag used for configuring options\n   * @param {Object=} options    Player options\n   * @param {Function=} ready    Ready callback function\n   */\n  init: function(tag, options, ready){\n    this.tag = tag; // Store the original tag used to set options\n\n    // Set Options\n    // The options argument overrides options set in the video tag\n    // which overrides globally set options.\n    // This latter part coincides with the load order\n    // (tag must exist before Player)\n    options = vjs.obj.merge(this.getTagSettings(tag), options);\n\n    // Cache for video property values.\n    this.cache_ = {};\n\n    // Set poster\n    this.poster_ = options['poster'];\n    // Set controls\n    this.controls_ = options['controls'];\n    // Original tag settings stored in options\n    // now remove immediately so native controls don't flash.\n    // May be turned back on by HTML5 tech if nativeControlsForTouch is true\n    tag.controls = false;\n\n    // Run base component initializing with new options.\n    // Builds the element through createEl()\n    // Inits and embeds any child components in opts\n    vjs.Component.call(this, this, options, ready);\n\n    // Update controls className. Can't do this when the controls are initially\n    // set because the element doesn't exist yet.\n    if (this.controls()) {\n      this.addClass('vjs-controls-enabled');\n    } else {\n      this.addClass('vjs-controls-disabled');\n    }\n\n    // TODO: Make this smarter. Toggle user state between touching/mousing\n    // using events, since devices can have both touch and mouse events.\n    // if (vjs.TOUCH_ENABLED) {\n    //   this.addClass('vjs-touch-enabled');\n    // }\n\n    // Firstplay event implimentation. Not sold on the event yet.\n    // Could probably just check currentTime==0?\n    this.one('play', function(e){\n      var fpEvent = { type: 'firstplay', target: this.el_ };\n      // Using vjs.trigger so we can check if default was prevented\n      var keepGoing = vjs.trigger(this.el_, fpEvent);\n\n      if (!keepGoing) {\n        e.preventDefault();\n        e.stopPropagation();\n        e.stopImmediatePropagation();\n      }\n    });\n\n    this.on('ended', this.onEnded);\n    this.on('play', this.onPlay);\n    this.on('firstplay', this.onFirstPlay);\n    this.on('pause', this.onPause);\n    this.on('progress', this.onProgress);\n    this.on('durationchange', this.onDurationChange);\n    this.on('error', this.onError);\n    this.on('fullscreenchange', this.onFullscreenChange);\n\n    // Make player easily findable by ID\n    vjs.players[this.id_] = this;\n\n    if (options['plugins']) {\n      vjs.obj.each(options['plugins'], function(key, val){\n        this[key](val);\n      }, this);\n    }\n\n    this.listenForUserActivity();\n  }\n});\n\n/**\n * Player instance options, surfaced using vjs.options\n * vjs.options = vjs.Player.prototype.options_\n * Make changes in vjs.options, not here.\n * All options should use string keys so they avoid\n * renaming by closure compiler\n * @type {Object}\n * @private\n */\nvjs.Player.prototype.options_ = vjs.options;\n\n/**\n * Destroys the video player and does any necessary cleanup\n *\n *     myPlayer.dispose();\n *\n * This is especially helpful if you are dynamically adding and removing videos\n * to/from the DOM.\n */\nvjs.Player.prototype.dispose = function(){\n  this.trigger('dispose');\n  // prevent dispose from being called twice\n  this.off('dispose');\n\n  // Kill reference to this player\n  vjs.players[this.id_] = null;\n  if (this.tag && this.tag['player']) { this.tag['player'] = null; }\n  if (this.el_ && this.el_['player']) { this.el_['player'] = null; }\n\n  // Ensure that tracking progress and time progress will stop and plater deleted\n  this.stopTrackingProgress();\n  this.stopTrackingCurrentTime();\n\n  if (this.tech) { this.tech.dispose(); }\n\n  // Component dispose\n  vjs.Component.prototype.dispose.call(this);\n};\n\nvjs.Player.prototype.getTagSettings = function(tag){\n  var options = {\n    'sources': [],\n    'tracks': []\n  };\n\n  vjs.obj.merge(options, vjs.getAttributeValues(tag));\n\n  // Get tag children settings\n  if (tag.hasChildNodes()) {\n    var children, child, childName, i, j;\n\n    children = tag.childNodes;\n\n    for (i=0,j=children.length; i<j; i++) {\n      child = children[i];\n      // Change case needed: http://ejohn.org/blog/nodename-case-sensitivity/\n      childName = child.nodeName.toLowerCase();\n      if (childName === 'source') {\n        options['sources'].push(vjs.getAttributeValues(child));\n      } else if (childName === 'track') {\n        options['tracks'].push(vjs.getAttributeValues(child));\n      }\n    }\n  }\n\n  return options;\n};\n\nvjs.Player.prototype.createEl = function(){\n  var el = this.el_ = vjs.Component.prototype.createEl.call(this, 'div');\n  var tag = this.tag;\n\n  // Remove width/height attrs from tag so CSS can make it 100% width/height\n  tag.removeAttribute('width');\n  tag.removeAttribute('height');\n  // Empty video tag tracks so the built-in player doesn't use them also.\n  // This may not be fast enough to stop HTML5 browsers from reading the tags\n  // so we'll need to turn off any default tracks if we're manually doing\n  // captions and subtitles. videoElement.textTracks\n  if (tag.hasChildNodes()) {\n    var nodes, nodesLength, i, node, nodeName, removeNodes;\n\n    nodes = tag.childNodes;\n    nodesLength = nodes.length;\n    removeNodes = [];\n\n    while (nodesLength--) {\n      node = nodes[nodesLength];\n      nodeName = node.nodeName.toLowerCase();\n      if (nodeName === 'track') {\n        removeNodes.push(node);\n      }\n    }\n\n    for (i=0; i<removeNodes.length; i++) {\n      tag.removeChild(removeNodes[i]);\n    }\n  }\n\n  // Make sure tag ID exists\n  tag.id = tag.id || 'vjs_video_' + vjs.guid++;\n\n  // Give video tag ID and class to player div\n  // ID will now reference player box, not the video tag\n  el.id = tag.id;\n  el.className = tag.className;\n\n  // Update tag id/class for use as HTML5 playback tech\n  // Might think we should do this after embedding in container so .vjs-tech class\n  // doesn't flash 100% width/height, but class only applies with .video-js parent\n  tag.id += '_html5_api';\n  tag.className = 'vjs-tech';\n\n  // Make player findable on elements\n  tag['player'] = el['player'] = this;\n  // Default state of video is paused\n  this.addClass('vjs-paused');\n\n  // Make box use width/height of tag, or rely on default implementation\n  // Enforce with CSS since width/height attrs don't work on divs\n  this.width(this.options_['width'], true); // (true) Skip resize listener on load\n  this.height(this.options_['height'], true);\n\n  // Wrap video tag in div (el/box) container\n  if (tag.parentNode) {\n    tag.parentNode.insertBefore(el, tag);\n  }\n  vjs.insertFirst(tag, el); // Breaks iPhone, fixed in HTML5 setup.\n\n  return el;\n};\n\n// /* Media Technology (tech)\n// ================================================================================ */\n// Load/Create an instance of playback technlogy including element and API methods\n// And append playback element in player div.\nvjs.Player.prototype.loadTech = function(techName, source){\n\n  // Pause and remove current playback technology\n  if (this.tech) {\n    this.unloadTech();\n\n  // if this is the first time loading, HTML5 tag will exist but won't be initialized\n  // so we need to remove it if we're not loading HTML5\n  } else if (techName !== 'Html5' && this.tag) {\n    vjs.Html5.disposeMediaElement(this.tag);\n    this.tag = null;\n  }\n\n  this.techName = techName;\n\n  // Turn off API access because we're loading a new tech that might load asynchronously\n  this.isReady_ = false;\n\n  var techReady = function(){\n    this.player_.triggerReady();\n\n    // Manually track progress in cases where the browser/flash player doesn't report it.\n    if (!this.features['progressEvents']) {\n      this.player_.manualProgressOn();\n    }\n\n    // Manually track timeudpates in cases where the browser/flash player doesn't report it.\n    if (!this.features['timeupdateEvents']) {\n      this.player_.manualTimeUpdatesOn();\n    }\n  };\n\n  // Grab tech-specific options from player options and add source and parent element to use.\n  var techOptions = vjs.obj.merge({ 'source': source, 'parentEl': this.el_ }, this.options_[techName.toLowerCase()]);\n\n  if (source) {\n    if (source.src == this.cache_.src && this.cache_.currentTime > 0) {\n      techOptions['startTime'] = this.cache_.currentTime;\n    }\n\n    this.cache_.src = source.src;\n  }\n\n  // Initialize tech instance\n  this.tech = new window['videojs'][techName](this, techOptions);\n\n  this.tech.ready(techReady);\n};\n\nvjs.Player.prototype.unloadTech = function(){\n  this.isReady_ = false;\n  this.tech.dispose();\n\n  // Turn off any manual progress or timeupdate tracking\n  if (this.manualProgress) { this.manualProgressOff(); }\n\n  if (this.manualTimeUpdates) { this.manualTimeUpdatesOff(); }\n\n  this.tech = false;\n};\n\n// There's many issues around changing the size of a Flash (or other plugin) object.\n// First is a plugin reload issue in Firefox that has been around for 11 years: https://bugzilla.mozilla.org/show_bug.cgi?id=90268\n// Then with the new fullscreen API, Mozilla and webkit browsers will reload the flash object after going to fullscreen.\n// To get around this, we're unloading the tech, caching source and currentTime values, and reloading the tech once the plugin is resized.\n// reloadTech: function(betweenFn){\n//   vjs.log('unloadingTech')\n//   this.unloadTech();\n//   vjs.log('unloadedTech')\n//   if (betweenFn) { betweenFn.call(); }\n//   vjs.log('LoadingTech')\n//   this.loadTech(this.techName, { src: this.cache_.src })\n//   vjs.log('loadedTech')\n// },\n\n/* Fallbacks for unsupported event types\n================================================================================ */\n// Manually trigger progress events based on changes to the buffered amount\n// Many flash players and older HTML5 browsers don't send progress or progress-like events\nvjs.Player.prototype.manualProgressOn = function(){\n  this.manualProgress = true;\n\n  // Trigger progress watching when a source begins loading\n  this.trackProgress();\n\n  // Watch for a native progress event call on the tech element\n  // In HTML5, some older versions don't support the progress event\n  // So we're assuming they don't, and turning off manual progress if they do.\n  // As opposed to doing user agent detection\n  this.tech.one('progress', function(){\n\n    // Update known progress support for this playback technology\n    this.features['progressEvents'] = true;\n\n    // Turn off manual progress tracking\n    this.player_.manualProgressOff();\n  });\n};\n\nvjs.Player.prototype.manualProgressOff = function(){\n  this.manualProgress = false;\n  this.stopTrackingProgress();\n};\n\nvjs.Player.prototype.trackProgress = function(){\n\n  this.progressInterval = setInterval(vjs.bind(this, function(){\n    // Don't trigger unless buffered amount is greater than last time\n    // log(this.cache_.bufferEnd, this.buffered().end(0), this.duration())\n    /* TODO: update for multiple buffered regions */\n    if (this.cache_.bufferEnd < this.buffered().end(0)) {\n      this.trigger('progress');\n    } else if (this.bufferedPercent() == 1) {\n      this.stopTrackingProgress();\n      this.trigger('progress'); // Last update\n    }\n  }), 500);\n};\nvjs.Player.prototype.stopTrackingProgress = function(){ clearInterval(this.progressInterval); };\n\n/*! Time Tracking -------------------------------------------------------------- */\nvjs.Player.prototype.manualTimeUpdatesOn = function(){\n  this.manualTimeUpdates = true;\n\n  this.on('play', this.trackCurrentTime);\n  this.on('pause', this.stopTrackingCurrentTime);\n  // timeupdate is also called by .currentTime whenever current time is set\n\n  // Watch for native timeupdate event\n  this.tech.one('timeupdate', function(){\n    // Update known progress support for this playback technology\n    this.features['timeupdateEvents'] = true;\n    // Turn off manual progress tracking\n    this.player_.manualTimeUpdatesOff();\n  });\n};\n\nvjs.Player.prototype.manualTimeUpdatesOff = function(){\n  this.manualTimeUpdates = false;\n  this.stopTrackingCurrentTime();\n  this.off('play', this.trackCurrentTime);\n  this.off('pause', this.stopTrackingCurrentTime);\n};\n\nvjs.Player.prototype.trackCurrentTime = function(){\n  if (this.currentTimeInterval) { this.stopTrackingCurrentTime(); }\n  this.currentTimeInterval = setInterval(vjs.bind(this, function(){\n    this.trigger('timeupdate');\n  }), 250); // 42 = 24 fps // 250 is what Webkit uses // FF uses 15\n};\n\n// Turn off play progress tracking (when paused or dragging)\nvjs.Player.prototype.stopTrackingCurrentTime = function(){ clearInterval(this.currentTimeInterval); };\n\n// /* Player event handlers (how the player reacts to certain events)\n// ================================================================================ */\n\n/**\n * Fired when the user agent begins looking for media data\n * @event loadstart\n */\nvjs.Player.prototype.onLoadStart;\n\n/**\n * Fired when the player has initial duration and dimension information\n * @event loadedmetadata\n */\nvjs.Player.prototype.onLoadedMetaData;\n\n/**\n * Fired when the player has downloaded data at the current playback position\n * @event loadeddata\n */\nvjs.Player.prototype.onLoadedData;\n\n/**\n * Fired when the player has finished downloading the source data\n * @event loadedalldata\n */\nvjs.Player.prototype.onLoadedAllData;\n\n/**\n * Fired whenever the media begins or resumes playback\n * @event play\n */\nvjs.Player.prototype.onPlay = function(){\n  vjs.removeClass(this.el_, 'vjs-paused');\n  vjs.addClass(this.el_, 'vjs-playing');\n};\n\n/**\n * Fired the first time a video is played\n *\n * Not part of the HLS spec, and we're not sure if this is the best\n * implementation yet, so use sparingly. If you don't have a reason to\n * prevent playback, use `myPlayer.one('play');` instead.\n *\n * @event firstplay\n */\nvjs.Player.prototype.onFirstPlay = function(){\n    //If the first starttime attribute is specified\n    //then we will start at the given offset in seconds\n    if(this.options_['starttime']){\n      this.currentTime(this.options_['starttime']);\n    }\n\n    this.addClass('vjs-has-started');\n};\n\n/**\n * Fired whenever the media has been paused\n * @event pause\n */\nvjs.Player.prototype.onPause = function(){\n  vjs.removeClass(this.el_, 'vjs-playing');\n  vjs.addClass(this.el_, 'vjs-paused');\n};\n\n/**\n * Fired when the current playback position has changed\n *\n * During playback this is fired every 15-250 milliseconds, depnding on the\n * playback technology in use.\n * @event timeupdate\n */\nvjs.Player.prototype.onTimeUpdate;\n\n/**\n * Fired while the user agent is downloading media data\n * @event progress\n */\nvjs.Player.prototype.onProgress = function(){\n  // Add custom event for when source is finished downloading.\n  if (this.bufferedPercent() == 1) {\n    this.trigger('loadedalldata');\n  }\n};\n\n/**\n * Fired when the end of the media resource is reached (currentTime == duration)\n * @event ended\n */\nvjs.Player.prototype.onEnded = function(){\n  if (this.options_['loop']) {\n    this.currentTime(0);\n    this.play();\n  }\n};\n\n/**\n * Fired when the duration of the media resource is first known or changed\n * @event durationchange\n */\nvjs.Player.prototype.onDurationChange = function(){\n  // Allows for cacheing value instead of asking player each time.\n  this.duration(this.techGet('duration'));\n};\n\n/**\n * Fired when the volume changes\n * @event volumechange\n */\nvjs.Player.prototype.onVolumeChange;\n\n/**\n * Fired when the player switches in or out of fullscreen mode\n * @event fullscreenchange\n */\nvjs.Player.prototype.onFullscreenChange = function() {\n  if (this.isFullScreen) {\n    this.addClass('vjs-fullscreen');\n  } else {\n    this.removeClass('vjs-fullscreen');\n  }\n};\n\n/**\n * Fired when there is an error in playback\n * @event error\n */\nvjs.Player.prototype.onError = function(e) {\n  vjs.log('Video Error', e);\n};\n\n// /* Player API\n// ================================================================================ */\n\n/**\n * Object for cached values.\n * @private\n */\nvjs.Player.prototype.cache_;\n\nvjs.Player.prototype.getCache = function(){\n  return this.cache_;\n};\n\n// Pass values to the playback tech\nvjs.Player.prototype.techCall = function(method, arg){\n  // If it's not ready yet, call method when it is\n  if (this.tech && !this.tech.isReady_) {\n    this.tech.ready(function(){\n      this[method](arg);\n    });\n\n  // Otherwise call method now\n  } else {\n    try {\n      this.tech[method](arg);\n    } catch(e) {\n      vjs.log(e);\n      throw e;\n    }\n  }\n};\n\n// Get calls can't wait for the tech, and sometimes don't need to.\nvjs.Player.prototype.techGet = function(method){\n\n  if (this.tech && this.tech.isReady_) {\n\n    // Flash likes to die and reload when you hide or reposition it.\n    // In these cases the object methods go away and we get errors.\n    // When that happens we'll catch the errors and inform tech that it's not ready any more.\n    try {\n      return this.tech[method]();\n    } catch(e) {\n      // When building additional tech libs, an expected method may not be defined yet\n      if (this.tech[method] === undefined) {\n        vjs.log('Video.js: ' + method + ' method not defined for '+this.techName+' playback technology.', e);\n      } else {\n        // When a method isn't available on the object it throws a TypeError\n        if (e.name == 'TypeError') {\n          vjs.log('Video.js: ' + method + ' unavailable on '+this.techName+' playback technology element.', e);\n          this.tech.isReady_ = false;\n        } else {\n          vjs.log(e);\n        }\n      }\n      throw e;\n    }\n  }\n\n  return;\n};\n\n/**\n * start media playback\n *\n *     myPlayer.play();\n *\n * @return {vjs.Player} self\n */\nvjs.Player.prototype.play = function(){\n  this.techCall('play');\n  return this;\n};\n\n/**\n * Pause the video playback\n *\n *     myPlayer.pause();\n *\n * @return {vjs.Player} self\n */\nvjs.Player.prototype.pause = function(){\n  this.techCall('pause');\n  return this;\n};\n\n/**\n * Check if the player is paused\n *\n *     var isPaused = myPlayer.paused();\n *     var isPlaying = !myPlayer.paused();\n *\n * @return {Boolean} false if the media is currently playing, or true otherwise\n */\nvjs.Player.prototype.paused = function(){\n  // The initial state of paused should be true (in Safari it's actually false)\n  return (this.techGet('paused') === false) ? false : true;\n};\n\n/**\n * Get or set the current time (in seconds)\n *\n *     // get\n *     var whereYouAt = myPlayer.currentTime();\n *\n *     // set\n *     myPlayer.currentTime(120); // 2 minutes into the video\n *\n * @param  {Number|String=} seconds The time to seek to\n * @return {Number}        The time in seconds, when not setting\n * @return {vjs.Player}    self, when the current time is set\n */\nvjs.Player.prototype.currentTime = function(seconds){\n  if (seconds !== undefined) {\n\n    // cache the last set value for smoother scrubbing\n    this.cache_.lastSetCurrentTime = seconds;\n\n    this.techCall('setCurrentTime', seconds);\n\n    // improve the accuracy of manual timeupdates\n    if (this.manualTimeUpdates) { this.trigger('timeupdate'); }\n\n    return this;\n  }\n\n  // cache last currentTime and return\n  // default to 0 seconds\n  return this.cache_.currentTime = (this.techGet('currentTime') || 0);\n};\n\n/**\n * Get the length in time of the video in seconds\n *\n *     var lengthOfVideo = myPlayer.duration();\n *\n * **NOTE**: The video must have started loading before the duration can be\n * known, and in the case of Flash, may not be known until the video starts\n * playing.\n *\n * @return {Number} The duration of the video in seconds\n */\nvjs.Player.prototype.duration = function(seconds){\n  if (seconds !== undefined) {\n\n    // cache the last set value for optimiized scrubbing (esp. Flash)\n    this.cache_.duration = parseFloat(seconds);\n\n    return this;\n  }\n\n  if (this.cache_.duration === undefined) {\n    this.onDurationChange();\n  }\n\n  return this.cache_.duration;\n};\n\n// Calculates how much time is left. Not in spec, but useful.\nvjs.Player.prototype.remainingTime = function(){\n  return this.duration() - this.currentTime();\n};\n\n// http://dev.w3.org/html5/spec/video.html#dom-media-buffered\n// Buffered returns a timerange object.\n// Kind of like an array of portions of the video that have been downloaded.\n// So far no browsers return more than one range (portion)\n\n/**\n * Get a TimeRange object with the times of the video that have been downloaded\n *\n * If you just want the percent of the video that's been downloaded,\n * use bufferedPercent.\n *\n *     // Number of different ranges of time have been buffered. Usually 1.\n *     numberOfRanges = bufferedTimeRange.length,\n *\n *     // Time in seconds when the first range starts. Usually 0.\n *     firstRangeStart = bufferedTimeRange.start(0),\n *\n *     // Time in seconds when the first range ends\n *     firstRangeEnd = bufferedTimeRange.end(0),\n *\n *     // Length in seconds of the first time range\n *     firstRangeLength = firstRangeEnd - firstRangeStart;\n *\n * @return {Object} A mock TimeRange object (following HTML spec)\n */\nvjs.Player.prototype.buffered = function(){\n  var buffered = this.techGet('buffered'),\n      start = 0,\n      buflast = buffered.length - 1,\n      // Default end to 0 and store in values\n      end = this.cache_.bufferEnd = this.cache_.bufferEnd || 0;\n\n  if (buffered && buflast >= 0 && buffered.end(buflast) !== end) {\n    end = buffered.end(buflast);\n    // Storing values allows them be overridden by setBufferedFromProgress\n    this.cache_.bufferEnd = end;\n  }\n\n  return vjs.createTimeRange(start, end);\n};\n\n/**\n * Get the percent (as a decimal) of the video that's been downloaded\n *\n *     var howMuchIsDownloaded = myPlayer.bufferedPercent();\n *\n * 0 means none, 1 means all.\n * (This method isn't in the HTML5 spec, but it's very convenient)\n *\n * @return {Number} A decimal between 0 and 1 representing the percent\n */\nvjs.Player.prototype.bufferedPercent = function(){\n  return (this.duration()) ? this.buffered().end(0) / this.duration() : 0;\n};\n\n/**\n * Get or set the current volume of the media\n *\n *     // get\n *     var howLoudIsIt = myPlayer.volume();\n *\n *     // set\n *     myPlayer.volume(0.5); // Set volume to half\n *\n * 0 is off (muted), 1.0 is all the way up, 0.5 is half way.\n *\n * @param  {Number} percentAsDecimal The new volume as a decimal percent\n * @return {Number}                  The current volume, when getting\n * @return {vjs.Player}              self, when setting\n */\nvjs.Player.prototype.volume = function(percentAsDecimal){\n  var vol;\n\n  if (percentAsDecimal !== undefined) {\n    vol = Math.max(0, Math.min(1, parseFloat(percentAsDecimal))); // Force value to between 0 and 1\n    this.cache_.volume = vol;\n    this.techCall('setVolume', vol);\n    vjs.setLocalStorage('volume', vol);\n    return this;\n  }\n\n  // Default to 1 when returning current volume.\n  vol = parseFloat(this.techGet('volume'));\n  return (isNaN(vol)) ? 1 : vol;\n};\n\n\n/**\n * Get the current muted state, or turn mute on or off\n *\n *     // get\n *     var isVolumeMuted = myPlayer.muted();\n *\n *     // set\n *     myPlayer.muted(true); // mute the volume\n *\n * @param  {Boolean=} muted True to mute, false to unmute\n * @return {Boolean} True if mute is on, false if not, when getting\n * @return {vjs.Player} self, when setting mute\n */\nvjs.Player.prototype.muted = function(muted){\n  if (muted !== undefined) {\n    this.techCall('setMuted', muted);\n    return this;\n  }\n  return this.techGet('muted') || false; // Default to false\n};\n\n// Check if current tech can support native fullscreen (e.g. with built in controls lik iOS, so not our flash swf)\nvjs.Player.prototype.supportsFullScreen = function(){ return this.techGet('supportsFullScreen') || false; };\n\n/**\n * Increase the size of the video to full screen\n *\n *     myPlayer.requestFullScreen();\n *\n * In some browsers, full screen is not supported natively, so it enters\n * \"full window mode\", where the video fills the browser window.\n * In browsers and devices that support native full screen, sometimes the\n * browser's default controls will be shown, and not the Video.js custom skin.\n * This includes most mobile devices (iOS, Android) and older versions of\n * Safari.\n *\n * @return {vjs.Player} self\n */\nvjs.Player.prototype.requestFullScreen = function(){\n  var requestFullScreen = vjs.support.requestFullScreen;\n  this.isFullScreen = true;\n\n  if (requestFullScreen) {\n    // the browser supports going fullscreen at the element level so we can\n    // take the controls fullscreen as well as the video\n\n    // Trigger fullscreenchange event after change\n    // We have to specifically add this each time, and remove\n    // when cancelling fullscreen. Otherwise if there's multiple\n    // players on a page, they would all be reacting to the same fullscreen\n    // events\n    vjs.on(document, requestFullScreen.eventName, vjs.bind(this, function(e){\n      this.isFullScreen = document[requestFullScreen.isFullScreen];\n\n      // If cancelling fullscreen, remove event listener.\n      if (this.isFullScreen === false) {\n        vjs.off(document, requestFullScreen.eventName, arguments.callee);\n      }\n\n      this.trigger('fullscreenchange');\n    }));\n\n    this.el_[requestFullScreen.requestFn]();\n\n  } else if (this.tech.supportsFullScreen()) {\n    // we can't take the video.js controls fullscreen but we can go fullscreen\n    // with native controls\n    this.techCall('enterFullScreen');\n  } else {\n    // fullscreen isn't supported so we'll just stretch the video element to\n    // fill the viewport\n    this.enterFullWindow();\n    this.trigger('fullscreenchange');\n  }\n\n  return this;\n};\n\n/**\n * Return the video to its normal size after having been in full screen mode\n *\n *     myPlayer.cancelFullScreen();\n *\n * @return {vjs.Player} self\n */\nvjs.Player.prototype.cancelFullScreen = function(){\n  var requestFullScreen = vjs.support.requestFullScreen;\n  this.isFullScreen = false;\n\n  // Check for browser element fullscreen support\n  if (requestFullScreen) {\n    document[requestFullScreen.cancelFn]();\n  } else if (this.tech.supportsFullScreen()) {\n   this.techCall('exitFullScreen');\n  } else {\n   this.exitFullWindow();\n   this.trigger('fullscreenchange');\n  }\n\n  return this;\n};\n\n// When fullscreen isn't supported we can stretch the video container to as wide as the browser will let us.\nvjs.Player.prototype.enterFullWindow = function(){\n  this.isFullWindow = true;\n\n  // Storing original doc overflow value to return to when fullscreen is off\n  this.docOrigOverflow = document.documentElement.style.overflow;\n\n  // Add listener for esc key to exit fullscreen\n  vjs.on(document, 'keydown', vjs.bind(this, this.fullWindowOnEscKey));\n\n  // Hide any scroll bars\n  document.documentElement.style.overflow = 'hidden';\n\n  // Apply fullscreen styles\n  vjs.addClass(document.body, 'vjs-full-window');\n\n  this.trigger('enterFullWindow');\n};\nvjs.Player.prototype.fullWindowOnEscKey = function(event){\n  if (event.keyCode === 27) {\n    if (this.isFullScreen === true) {\n      this.cancelFullScreen();\n    } else {\n      this.exitFullWindow();\n    }\n  }\n};\n\nvjs.Player.prototype.exitFullWindow = function(){\n  this.isFullWindow = false;\n  vjs.off(document, 'keydown', this.fullWindowOnEscKey);\n\n  // Unhide scroll bars.\n  document.documentElement.style.overflow = this.docOrigOverflow;\n\n  // Remove fullscreen styles\n  vjs.removeClass(document.body, 'vjs-full-window');\n\n  // Resize the box, controller, and poster to original sizes\n  // this.positionAll();\n  this.trigger('exitFullWindow');\n};\n\nvjs.Player.prototype.selectSource = function(sources){\n\n  // Loop through each playback technology in the options order\n  for (var i=0,j=this.options_['techOrder'];i<j.length;i++) {\n    var techName = vjs.capitalize(j[i]),\n        tech = window['videojs'][techName];\n\n    // Check if the browser supports this technology\n    if (tech.isSupported()) {\n      // Loop through each source object\n      for (var a=0,b=sources;a<b.length;a++) {\n        var source = b[a];\n\n        // Check if source can be played with this technology\n        if (tech['canPlaySource'](source)) {\n          return { source: source, tech: techName };\n        }\n      }\n    }\n  }\n\n  return false;\n};\n\n/**\n * The source function updates the video source\n *\n * There are three types of variables you can pass as the argument.\n *\n * **URL String**: A URL to the the video file. Use this method if you are sure\n * the current playback technology (HTML5/Flash) can support the source you\n * provide. Currently only MP4 files can be used in both HTML5 and Flash.\n *\n *     myPlayer.src(\"http://www.example.com/path/to/video.mp4\");\n *\n * **Source Object (or element):** A javascript object containing information\n * about the source file. Use this method if you want the player to determine if\n * it can support the file using the type information.\n *\n *     myPlayer.src({ type: \"video/mp4\", src: \"http://www.example.com/path/to/video.mp4\" });\n *\n * **Array of Source Objects:** To provide multiple versions of the source so\n * that it can be played using HTML5 across browsers you can use an array of\n * source objects. Video.js will detect which version is supported and load that\n * file.\n *\n *     myPlayer.src([\n *       { type: \"video/mp4\", src: \"http://www.example.com/path/to/video.mp4\" },\n *       { type: \"video/webm\", src: \"http://www.example.com/path/to/video.webm\" },\n *       { type: \"video/ogg\", src: \"http://www.example.com/path/to/video.ogv\" }\n *     ]);\n *\n * @param  {String|Object|Array=} source The source URL, object, or array of sources\n * @return {vjs.Player} self\n */\nvjs.Player.prototype.src = function(source){\n  // Case: Array of source objects to choose from and pick the best to play\n  if (source instanceof Array) {\n\n    var sourceTech = this.selectSource(source),\n        techName;\n\n    if (sourceTech) {\n        source = sourceTech.source;\n        techName = sourceTech.tech;\n\n      // If this technology is already loaded, set source\n      if (techName == this.techName) {\n        this.src(source); // Passing the source object\n      // Otherwise load this technology with chosen source\n      } else {\n        this.loadTech(techName, source);\n      }\n    } else {\n      this.el_.appendChild(vjs.createEl('p', {\n        innerHTML: this.options()['notSupportedMessage']\n      }));\n    }\n\n  // Case: Source object { src: '', type: '' ... }\n  } else if (source instanceof Object) {\n\n    if (window['videojs'][this.techName]['canPlaySource'](source)) {\n      this.src(source.src);\n    } else {\n      // Send through tech loop to check for a compatible technology.\n      this.src([source]);\n    }\n\n  // Case: URL String (http://myvideo...)\n  } else {\n    // Cache for getting last set source\n    this.cache_.src = source;\n\n    if (!this.isReady_) {\n      this.ready(function(){\n        this.src(source);\n      });\n    } else {\n      this.techCall('src', source);\n      if (this.options_['preload'] == 'auto') {\n        this.load();\n      }\n      if (this.options_['autoplay']) {\n        this.play();\n      }\n    }\n  }\n  return this;\n};\n\n// Begin loading the src data\n// http://dev.w3.org/html5/spec/video.html#dom-media-load\nvjs.Player.prototype.load = function(){\n  this.techCall('load');\n  return this;\n};\n\n// http://dev.w3.org/html5/spec/video.html#dom-media-currentsrc\nvjs.Player.prototype.currentSrc = function(){\n  return this.techGet('currentSrc') || this.cache_.src || '';\n};\n\n// Attributes/Options\nvjs.Player.prototype.preload = function(value){\n  if (value !== undefined) {\n    this.techCall('setPreload', value);\n    this.options_['preload'] = value;\n    return this;\n  }\n  return this.techGet('preload');\n};\nvjs.Player.prototype.autoplay = function(value){\n  if (value !== undefined) {\n    this.techCall('setAutoplay', value);\n    this.options_['autoplay'] = value;\n    return this;\n  }\n  return this.techGet('autoplay', value);\n};\nvjs.Player.prototype.loop = function(value){\n  if (value !== undefined) {\n    this.techCall('setLoop', value);\n    this.options_['loop'] = value;\n    return this;\n  }\n  return this.techGet('loop');\n};\n\n/**\n * the url of the poster image source\n * @type {String}\n * @private\n */\nvjs.Player.prototype.poster_;\n\n/**\n * get or set the poster image source url\n *\n * ##### EXAMPLE:\n *\n *     // getting\n *     var currentPoster = myPlayer.poster();\n *\n *     // setting\n *     myPlayer.poster('http://example.com/myImage.jpg');\n *\n * @param  {String=} [src] Poster image source URL\n * @return {String} poster URL when getting\n * @return {vjs.Player} self when setting\n */\nvjs.Player.prototype.poster = function(src){\n  if (src !== undefined) {\n    this.poster_ = src;\n    return this;\n  }\n  return this.poster_;\n};\n\n/**\n * Whether or not the controls are showing\n * @type {Boolean}\n * @private\n */\nvjs.Player.prototype.controls_;\n\n/**\n * Get or set whether or not the controls are showing.\n * @param  {Boolean} controls Set controls to showing or not\n * @return {Boolean}    Controls are showing\n */\nvjs.Player.prototype.controls = function(bool){\n  if (bool !== undefined) {\n    bool = !!bool; // force boolean\n    // Don't trigger a change event unless it actually changed\n    if (this.controls_ !== bool) {\n      this.controls_ = bool;\n      if (bool) {\n        this.removeClass('vjs-controls-disabled');\n        this.addClass('vjs-controls-enabled');\n        this.trigger('controlsenabled');\n      } else {\n        this.removeClass('vjs-controls-enabled');\n        this.addClass('vjs-controls-disabled');\n        this.trigger('controlsdisabled');\n      }\n    }\n    return this;\n  }\n  return this.controls_;\n};\n\nvjs.Player.prototype.usingNativeControls_;\n\n/**\n * Toggle native controls on/off. Native controls are the controls built into\n * devices (e.g. default iPhone controls), Flash, or other techs\n * (e.g. Vimeo Controls)\n *\n * **This should only be set by the current tech, because only the tech knows\n * if it can support native controls**\n *\n * @param  {Boolean} bool    True signals that native controls are on\n * @return {vjs.Player}      Returns the player\n * @private\n */\nvjs.Player.prototype.usingNativeControls = function(bool){\n  if (bool !== undefined) {\n    bool = !!bool; // force boolean\n    // Don't trigger a change event unless it actually changed\n    if (this.usingNativeControls_ !== bool) {\n      this.usingNativeControls_ = bool;\n      if (bool) {\n        this.addClass('vjs-using-native-controls');\n\n        /**\n         * player is using the native device controls\n         *\n         * @event usingnativecontrols\n         * @memberof vjs.Player\n         * @instance\n         * @private\n         */\n        this.trigger('usingnativecontrols');\n      } else {\n        this.removeClass('vjs-using-native-controls');\n\n        /**\n         * player is using the custom HTML controls\n         *\n         * @event usingcustomcontrols\n         * @memberof vjs.Player\n         * @instance\n         * @private\n         */\n        this.trigger('usingcustomcontrols');\n      }\n    }\n    return this;\n  }\n  return this.usingNativeControls_;\n};\n\nvjs.Player.prototype.error = function(){ return this.techGet('error'); };\nvjs.Player.prototype.ended = function(){ return this.techGet('ended'); };\nvjs.Player.prototype.seeking = function(){ return this.techGet('seeking'); };\n\n// When the player is first initialized, trigger activity so components\n// like the control bar show themselves if needed\nvjs.Player.prototype.userActivity_ = true;\nvjs.Player.prototype.reportUserActivity = function(event){\n  this.userActivity_ = true;\n};\n\nvjs.Player.prototype.userActive_ = true;\nvjs.Player.prototype.userActive = function(bool){\n  if (bool !== undefined) {\n    bool = !!bool;\n    if (bool !== this.userActive_) {\n      this.userActive_ = bool;\n      if (bool) {\n        // If the user was inactive and is now active we want to reset the\n        // inactivity timer\n        this.userActivity_ = true;\n        this.removeClass('vjs-user-inactive');\n        this.addClass('vjs-user-active');\n        this.trigger('useractive');\n      } else {\n        // We're switching the state to inactive manually, so erase any other\n        // activity\n        this.userActivity_ = false;\n\n        // Chrome/Safari/IE have bugs where when you change the cursor it can\n        // trigger a mousemove event. This causes an issue when you're hiding\n        // the cursor when the user is inactive, and a mousemove signals user\n        // activity. Making it impossible to go into inactive mode. Specifically\n        // this happens in fullscreen when we really need to hide the cursor.\n        //\n        // When this gets resolved in ALL browsers it can be removed\n        // https://code.google.com/p/chromium/issues/detail?id=103041\n        this.tech.one('mousemove', function(e){\n          e.stopPropagation();\n          e.preventDefault();\n        });\n        this.removeClass('vjs-user-active');\n        this.addClass('vjs-user-inactive');\n        this.trigger('userinactive');\n      }\n    }\n    return this;\n  }\n  return this.userActive_;\n};\n\nvjs.Player.prototype.listenForUserActivity = function(){\n  var onMouseActivity, onMouseDown, mouseInProgress, onMouseUp,\n      activityCheck, inactivityTimeout;\n\n  onMouseActivity = this.reportUserActivity;\n\n  onMouseDown = function() {\n    onMouseActivity();\n    // For as long as the they are touching the device or have their mouse down,\n    // we consider them active even if they're not moving their finger or mouse.\n    // So we want to continue to update that they are active\n    clearInterval(mouseInProgress);\n    // Setting userActivity=true now and setting the interval to the same time\n    // as the activityCheck interval (250) should ensure we never miss the\n    // next activityCheck\n    mouseInProgress = setInterval(vjs.bind(this, onMouseActivity), 250);\n  };\n\n  onMouseUp = function(event) {\n    onMouseActivity();\n    // Stop the interval that maintains activity if the mouse/touch is down\n    clearInterval(mouseInProgress);\n  };\n\n  // Any mouse movement will be considered user activity\n  this.on('mousedown', onMouseDown);\n  this.on('mousemove', onMouseActivity);\n  this.on('mouseup', onMouseUp);\n\n  // Listen for keyboard navigation\n  // Shouldn't need to use inProgress interval because of key repeat\n  this.on('keydown', onMouseActivity);\n  this.on('keyup', onMouseActivity);\n\n  // Consider any touch events that bubble up to be activity\n  // Certain touches on the tech will be blocked from bubbling because they\n  // toggle controls\n  this.on('touchstart', onMouseDown);\n  this.on('touchmove', onMouseActivity);\n  this.on('touchend', onMouseUp);\n  this.on('touchcancel', onMouseUp);\n\n  // Run an interval every 250 milliseconds instead of stuffing everything into\n  // the mousemove/touchmove function itself, to prevent performance degradation.\n  // `this.reportUserActivity` simply sets this.userActivity_ to true, which\n  // then gets picked up by this loop\n  // http://ejohn.org/blog/learning-from-twitter/\n  activityCheck = setInterval(vjs.bind(this, function() {\n    // Check to see if mouse/touch activity has happened\n    if (this.userActivity_) {\n      // Reset the activity tracker\n      this.userActivity_ = false;\n\n      // If the user state was inactive, set the state to active\n      this.userActive(true);\n\n      // Clear any existing inactivity timeout to start the timer over\n      clearTimeout(inactivityTimeout);\n\n      // In X seconds, if no more activity has occurred the user will be\n      // considered inactive\n      inactivityTimeout = setTimeout(vjs.bind(this, function() {\n        // Protect against the case where the inactivityTimeout can trigger just\n        // before the next user activity is picked up by the activityCheck loop\n        // causing a flicker\n        if (!this.userActivity_) {\n          this.userActive(false);\n        }\n      }), 2000);\n    }\n  }), 250);\n\n  // Clean up the intervals when we kill the player\n  this.on('dispose', function(){\n    clearInterval(activityCheck);\n    clearTimeout(inactivityTimeout);\n  });\n};\n\n// Methods to add support for\n// networkState: function(){ return this.techCall('networkState'); },\n// readyState: function(){ return this.techCall('readyState'); },\n// seeking: function(){ return this.techCall('seeking'); },\n// initialTime: function(){ return this.techCall('initialTime'); },\n// startOffsetTime: function(){ return this.techCall('startOffsetTime'); },\n// played: function(){ return this.techCall('played'); },\n// seekable: function(){ return this.techCall('seekable'); },\n// videoTracks: function(){ return this.techCall('videoTracks'); },\n// audioTracks: function(){ return this.techCall('audioTracks'); },\n// videoWidth: function(){ return this.techCall('videoWidth'); },\n// videoHeight: function(){ return this.techCall('videoHeight'); },\n// defaultPlaybackRate: function(){ return this.techCall('defaultPlaybackRate'); },\n// playbackRate: function(){ return this.techCall('playbackRate'); },\n// mediaGroup: function(){ return this.techCall('mediaGroup'); },\n// controller: function(){ return this.techCall('controller'); },\n// defaultMuted: function(){ return this.techCall('defaultMuted'); }\n\n// TODO\n// currentSrcList: the array of sources including other formats and bitrates\n// playList: array of source lists in order of playback\n\n// RequestFullscreen API\n(function(){\n  var prefix, requestFS, div;\n\n  div = document.createElement('div');\n\n  requestFS = {};\n\n  // Current W3C Spec\n  // http://dvcs.w3.org/hg/fullscreen/raw-file/tip/Overview.html#api\n  // Mozilla Draft: https://wiki.mozilla.org/Gecko:FullScreenAPI#fullscreenchange_event\n  // New: https://dvcs.w3.org/hg/fullscreen/raw-file/529a67b8d9f3/Overview.html\n  if (div.cancelFullscreen !== undefined) {\n    requestFS.requestFn = 'requestFullscreen';\n    requestFS.cancelFn = 'exitFullscreen';\n    requestFS.eventName = 'fullscreenchange';\n    requestFS.isFullScreen = 'fullScreen';\n\n  // Webkit (Chrome/Safari) and Mozilla (Firefox) have working implementations\n  // that use prefixes and vary slightly from the new W3C spec. Specifically,\n  // using 'exit' instead of 'cancel', and lowercasing the 'S' in Fullscreen.\n  // Other browsers don't have any hints of which version they might follow yet,\n  // so not going to try to predict by looping through all prefixes.\n  } else {\n\n    if (document.mozCancelFullScreen) {\n      prefix = 'moz';\n      requestFS.isFullScreen = prefix + 'FullScreen';\n    } else {\n      prefix = 'webkit';\n      requestFS.isFullScreen = prefix + 'IsFullScreen';\n    }\n\n    if (div[prefix + 'RequestFullScreen']) {\n      requestFS.requestFn = prefix + 'RequestFullScreen';\n      requestFS.cancelFn = prefix + 'CancelFullScreen';\n    }\n    requestFS.eventName = prefix + 'fullscreenchange';\n  }\n\n  if (document[requestFS.cancelFn]) {\n    vjs.support.requestFullScreen = requestFS;\n  }\n\n})();\n\n\n/**\n * Container of main controls\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @class\n * @constructor\n * @extends vjs.Component\n */\nvjs.ControlBar = vjs.Component.extend();\n\nvjs.ControlBar.prototype.options_ = {\n  loadEvent: 'play',\n  children: {\n    'playToggle': {},\n    'currentTimeDisplay': {},\n    'timeDivider': {},\n    'durationDisplay': {},\n    'remainingTimeDisplay': {},\n    'progressControl': {},\n    'fullscreenToggle': {},\n    'volumeControl': {},\n    'muteToggle': {}\n    // 'volumeMenuButton': {}\n  }\n};\n\nvjs.ControlBar.prototype.createEl = function(){\n  return vjs.createEl('div', {\n    className: 'vjs-control-bar'\n  });\n};\n/**\n * Button to toggle between play and pause\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @class\n * @constructor\n */\nvjs.PlayToggle = vjs.Button.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Button.call(this, player, options);\n\n    player.on('play', vjs.bind(this, this.onPlay));\n    player.on('pause', vjs.bind(this, this.onPause));\n  }\n});\n\nvjs.PlayToggle.prototype.buttonText = 'Play';\n\nvjs.PlayToggle.prototype.buildCSSClass = function(){\n  return 'vjs-play-control ' + vjs.Button.prototype.buildCSSClass.call(this);\n};\n\n// OnClick - Toggle between play and pause\nvjs.PlayToggle.prototype.onClick = function(){\n  if (this.player_.paused()) {\n    this.player_.play();\n  } else {\n    this.player_.pause();\n  }\n};\n\n  // OnPlay - Add the vjs-playing class to the element so it can change appearance\nvjs.PlayToggle.prototype.onPlay = function(){\n  vjs.removeClass(this.el_, 'vjs-paused');\n  vjs.addClass(this.el_, 'vjs-playing');\n  this.el_.children[0].children[0].innerHTML = 'Pause'; // change the button text to \"Pause\"\n};\n\n  // OnPause - Add the vjs-paused class to the element so it can change appearance\nvjs.PlayToggle.prototype.onPause = function(){\n  vjs.removeClass(this.el_, 'vjs-playing');\n  vjs.addClass(this.el_, 'vjs-paused');\n  this.el_.children[0].children[0].innerHTML = 'Play'; // change the button text to \"Play\"\n};\n/**\n * Displays the current time\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.CurrentTimeDisplay = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Component.call(this, player, options);\n\n    player.on('timeupdate', vjs.bind(this, this.updateContent));\n  }\n});\n\nvjs.CurrentTimeDisplay.prototype.createEl = function(){\n  var el = vjs.Component.prototype.createEl.call(this, 'div', {\n    className: 'vjs-current-time vjs-time-controls vjs-control'\n  });\n\n  this.content = vjs.createEl('div', {\n    className: 'vjs-current-time-display',\n    innerHTML: '<span class=\"vjs-control-text\">Current Time </span>' + '0:00', // label the current time for screen reader users\n    'aria-live': 'off' // tell screen readers not to automatically read the time as it changes\n  });\n\n  el.appendChild(vjs.createEl('div').appendChild(this.content));\n  return el;\n};\n\nvjs.CurrentTimeDisplay.prototype.updateContent = function(){\n  // Allows for smooth scrubbing, when player can't keep up.\n  var time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime();\n  this.content.innerHTML = '<span class=\"vjs-control-text\">Current Time </span>' + vjs.formatTime(time, this.player_.duration());\n};\n\n/**\n * Displays the duration\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.DurationDisplay = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Component.call(this, player, options);\n\n    player.on('timeupdate', vjs.bind(this, this.updateContent)); // this might need to be changes to 'durationchange' instead of 'timeupdate' eventually, however the durationchange event fires before this.player_.duration() is set, so the value cannot be written out using this method. Once the order of durationchange and this.player_.duration() being set is figured out, this can be updated.\n  }\n});\n\nvjs.DurationDisplay.prototype.createEl = function(){\n  var el = vjs.Component.prototype.createEl.call(this, 'div', {\n    className: 'vjs-duration vjs-time-controls vjs-control'\n  });\n\n  this.content = vjs.createEl('div', {\n    className: 'vjs-duration-display',\n    innerHTML: '<span class=\"vjs-control-text\">Duration Time </span>' + '0:00', // label the duration time for screen reader users\n    'aria-live': 'off' // tell screen readers not to automatically read the time as it changes\n  });\n\n  el.appendChild(vjs.createEl('div').appendChild(this.content));\n  return el;\n};\n\nvjs.DurationDisplay.prototype.updateContent = function(){\n  var duration = this.player_.duration();\n  if (duration) {\n      this.content.innerHTML = '<span class=\"vjs-control-text\">Duration Time </span>' + vjs.formatTime(duration); // label the duration time for screen reader users\n  }\n};\n\n/**\n * The separator between the current time and duration\n *\n * Can be hidden if it's not needed in the design.\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.TimeDivider = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Component.call(this, player, options);\n  }\n});\n\nvjs.TimeDivider.prototype.createEl = function(){\n  return vjs.Component.prototype.createEl.call(this, 'div', {\n    className: 'vjs-time-divider',\n    innerHTML: '<div><span>/</span></div>'\n  });\n};\n\n/**\n * Displays the time left in the video\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.RemainingTimeDisplay = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Component.call(this, player, options);\n\n    player.on('timeupdate', vjs.bind(this, this.updateContent));\n  }\n});\n\nvjs.RemainingTimeDisplay.prototype.createEl = function(){\n  var el = vjs.Component.prototype.createEl.call(this, 'div', {\n    className: 'vjs-remaining-time vjs-time-controls vjs-control'\n  });\n\n  this.content = vjs.createEl('div', {\n    className: 'vjs-remaining-time-display',\n    innerHTML: '<span class=\"vjs-control-text\">Remaining Time </span>' + '-0:00', // label the remaining time for screen reader users\n    'aria-live': 'off' // tell screen readers not to automatically read the time as it changes\n  });\n\n  el.appendChild(vjs.createEl('div').appendChild(this.content));\n  return el;\n};\n\nvjs.RemainingTimeDisplay.prototype.updateContent = function(){\n  if (this.player_.duration()) {\n    this.content.innerHTML = '<span class=\"vjs-control-text\">Remaining Time </span>' + '-'+ vjs.formatTime(this.player_.remainingTime());\n  }\n\n  // Allows for smooth scrubbing, when player can't keep up.\n  // var time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime();\n  // this.content.innerHTML = vjs.formatTime(time, this.player_.duration());\n};\n/**\n * Toggle fullscreen video\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @class\n * @extends vjs.Button\n */\nvjs.FullscreenToggle = vjs.Button.extend({\n  /**\n   * @constructor\n   * @memberof vjs.FullscreenToggle\n   * @instance\n   */\n  init: function(player, options){\n    vjs.Button.call(this, player, options);\n  }\n});\n\nvjs.FullscreenToggle.prototype.buttonText = 'Fullscreen';\n\nvjs.FullscreenToggle.prototype.buildCSSClass = function(){\n  return 'vjs-fullscreen-control ' + vjs.Button.prototype.buildCSSClass.call(this);\n};\n\nvjs.FullscreenToggle.prototype.onClick = function(){\n  if (!this.player_.isFullScreen) {\n    this.player_.requestFullScreen();\n    this.el_.children[0].children[0].innerHTML = 'Non-Fullscreen'; // change the button text to \"Non-Fullscreen\"\n  } else {\n    this.player_.cancelFullScreen();\n    this.el_.children[0].children[0].innerHTML = 'Fullscreen'; // change the button to \"Fullscreen\"\n  }\n};\n/**\n * The Progress Control component contains the seek bar, load progress,\n * and play progress\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.ProgressControl = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Component.call(this, player, options);\n  }\n});\n\nvjs.ProgressControl.prototype.options_ = {\n  children: {\n    'seekBar': {}\n  }\n};\n\nvjs.ProgressControl.prototype.createEl = function(){\n  return vjs.Component.prototype.createEl.call(this, 'div', {\n    className: 'vjs-progress-control vjs-control'\n  });\n};\n\n/**\n * Seek Bar and holder for the progress bars\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.SeekBar = vjs.Slider.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Slider.call(this, player, options);\n    player.on('timeupdate', vjs.bind(this, this.updateARIAAttributes));\n    player.ready(vjs.bind(this, this.updateARIAAttributes));\n  }\n});\n\nvjs.SeekBar.prototype.options_ = {\n  children: {\n    'loadProgressBar': {},\n    'playProgressBar': {},\n    'seekHandle': {}\n  },\n  'barName': 'playProgressBar',\n  'handleName': 'seekHandle'\n};\n\nvjs.SeekBar.prototype.playerEvent = 'timeupdate';\n\nvjs.SeekBar.prototype.createEl = function(){\n  return vjs.Slider.prototype.createEl.call(this, 'div', {\n    className: 'vjs-progress-holder',\n    'aria-label': 'video progress bar'\n  });\n};\n\nvjs.SeekBar.prototype.updateARIAAttributes = function(){\n    // Allows for smooth scrubbing, when player can't keep up.\n    var time = (this.player_.scrubbing) ? this.player_.getCache().currentTime : this.player_.currentTime();\n    this.el_.setAttribute('aria-valuenow',vjs.round(this.getPercent()*100, 2)); // machine readable value of progress bar (percentage complete)\n    this.el_.setAttribute('aria-valuetext',vjs.formatTime(time, this.player_.duration())); // human readable value of progress bar (time complete)\n};\n\nvjs.SeekBar.prototype.getPercent = function(){\n  var currentTime;\n  // Flash RTMP provider will not report the correct time\n  // immediately after a seek. This isn't noticeable if you're\n  // seeking while the video is playing, but it is if you seek\n  // while the video is paused.\n  if (this.player_.techName === 'Flash' && this.player_.seeking()) {\n    var cache = this.player_.getCache();\n    if (cache.lastSetCurrentTime) {\n      currentTime = cache.lastSetCurrentTime;\n    }\n    else {\n      currentTime = this.player_.currentTime();\n    }\n  }\n  else {\n    currentTime = this.player_.currentTime();\n  }\n\n  return currentTime / this.player_.duration();\n};\n\nvjs.SeekBar.prototype.onMouseDown = function(event){\n  vjs.Slider.prototype.onMouseDown.call(this, event);\n\n  this.player_.scrubbing = true;\n\n  this.videoWasPlaying = !this.player_.paused();\n  this.player_.pause();\n};\n\nvjs.SeekBar.prototype.onMouseMove = function(event){\n  var newTime = this.calculateDistance(event) * this.player_.duration();\n\n  // Don't let video end while scrubbing.\n  if (newTime == this.player_.duration()) { newTime = newTime - 0.1; }\n\n  // Set new time (tell player to seek to new time)\n  this.player_.currentTime(newTime);\n};\n\nvjs.SeekBar.prototype.onMouseUp = function(event){\n    debugger\n  vjs.Slider.prototype.onMouseUp.call(this, event);\n\n  this.player_.scrubbing = false;\n  if (this.videoWasPlaying) {\n      debugger\n    this.player_.play();\n  }\n};\n\nvjs.SeekBar.prototype.stepForward = function(){\n  this.player_.currentTime(this.player_.currentTime() + 5); // more quickly fast forward for keyboard-only users\n};\n\nvjs.SeekBar.prototype.stepBack = function(){\n  this.player_.currentTime(this.player_.currentTime() - 5); // more quickly rewind for keyboard-only users\n};\n\n\n/**\n * Shows load progress\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.LoadProgressBar = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Component.call(this, player, options);\n    player.on('progress', vjs.bind(this, this.update));\n  }\n});\n\nvjs.LoadProgressBar.prototype.createEl = function(){\n  return vjs.Component.prototype.createEl.call(this, 'div', {\n    className: 'vjs-load-progress',\n    innerHTML: '<span class=\"vjs-control-text\">Loaded: 0%</span>'\n  });\n};\n\nvjs.LoadProgressBar.prototype.update = function(){\n  if (this.el_.style) { this.el_.style.width = vjs.round(this.player_.bufferedPercent() * 100, 2) + '%'; }\n};\n\n\n/**\n * Shows play progress\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.PlayProgressBar = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Component.call(this, player, options);\n  }\n});\n\nvjs.PlayProgressBar.prototype.createEl = function(){\n  return vjs.Component.prototype.createEl.call(this, 'div', {\n    className: 'vjs-play-progress',\n    innerHTML: '<span class=\"vjs-control-text\">Progress: 0%</span>'\n  });\n};\n\n/**\n * The Seek Handle shows the current position of the playhead during playback,\n * and can be dragged to adjust the playhead.\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.SeekHandle = vjs.SliderHandle.extend();\n\n/**\n * The default value for the handle content, which may be read by screen readers\n *\n * @type {String}\n * @private\n */\nvjs.SeekHandle.prototype.defaultValue = '00:00';\n\n/** @inheritDoc */\nvjs.SeekHandle.prototype.createEl = function(){\n  return vjs.SliderHandle.prototype.createEl.call(this, 'div', {\n    className: 'vjs-seek-handle'\n  });\n};\n/**\n * The component for controlling the volume level\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.VolumeControl = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Component.call(this, player, options);\n\n    // hide volume controls when they're not supported by the current tech\n    if (player.tech && player.tech.features && player.tech.features['volumeControl'] === false) {\n      this.addClass('vjs-hidden');\n    }\n    player.on('loadstart', vjs.bind(this, function(){\n      if (player.tech.features && player.tech.features['volumeControl'] === false) {\n        this.addClass('vjs-hidden');\n      } else {\n        this.removeClass('vjs-hidden');\n      }\n    }));\n  }\n});\n\nvjs.VolumeControl.prototype.options_ = {\n  children: {\n    'volumeBar': {}\n  }\n};\n\nvjs.VolumeControl.prototype.createEl = function(){\n  return vjs.Component.prototype.createEl.call(this, 'div', {\n    className: 'vjs-volume-control vjs-control'\n  });\n};\n\n/**\n * The bar that contains the volume level and can be clicked on to adjust the level\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.VolumeBar = vjs.Slider.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Slider.call(this, player, options);\n    player.on('volumechange', vjs.bind(this, this.updateARIAAttributes));\n    player.ready(vjs.bind(this, this.updateARIAAttributes));\n    setTimeout(vjs.bind(this, this.update), 0); // update when elements is in DOM\n  }\n});\n\nvjs.VolumeBar.prototype.updateARIAAttributes = function(){\n  // Current value of volume bar as a percentage\n  this.el_.setAttribute('aria-valuenow',vjs.round(this.player_.volume()*100, 2));\n  this.el_.setAttribute('aria-valuetext',vjs.round(this.player_.volume()*100, 2)+'%');\n};\n\nvjs.VolumeBar.prototype.options_ = {\n  children: {\n    'volumeLevel': {},\n    'volumeHandle': {}\n  },\n  'barName': 'volumeLevel',\n  'handleName': 'volumeHandle'\n};\n\nvjs.VolumeBar.prototype.playerEvent = 'volumechange';\n\nvjs.VolumeBar.prototype.createEl = function(){\n  return vjs.Slider.prototype.createEl.call(this, 'div', {\n    className: 'vjs-volume-bar',\n    'aria-label': 'volume level'\n  });\n};\n\nvjs.VolumeBar.prototype.onMouseMove = function(event) {\n  if (this.player_.muted()) {\n    this.player_.muted(false);\n  }\n\n  this.player_.volume(this.calculateDistance(event));\n};\n\nvjs.VolumeBar.prototype.getPercent = function(){\n  if (this.player_.muted()) {\n    return 0;\n  } else {\n    return this.player_.volume();\n  }\n};\n\nvjs.VolumeBar.prototype.stepForward = function(){\n  this.player_.volume(this.player_.volume() + 0.1);\n};\n\nvjs.VolumeBar.prototype.stepBack = function(){\n  this.player_.volume(this.player_.volume() - 0.1);\n};\n\n/**\n * Shows volume level\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.VolumeLevel = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Component.call(this, player, options);\n  }\n});\n\nvjs.VolumeLevel.prototype.createEl = function(){\n  return vjs.Component.prototype.createEl.call(this, 'div', {\n    className: 'vjs-volume-level',\n    innerHTML: '<span class=\"vjs-control-text\"></span>'\n  });\n};\n\n/**\n * The volume handle can be dragged to adjust the volume level\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\n vjs.VolumeHandle = vjs.SliderHandle.extend();\n\n vjs.VolumeHandle.prototype.defaultValue = '00:00';\n\n /** @inheritDoc */\n vjs.VolumeHandle.prototype.createEl = function(){\n   return vjs.SliderHandle.prototype.createEl.call(this, 'div', {\n     className: 'vjs-volume-handle'\n   });\n };\n/**\n * A button component for muting the audio\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.MuteToggle = vjs.Button.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Button.call(this, player, options);\n\n    player.on('volumechange', vjs.bind(this, this.update));\n\n    // hide mute toggle if the current tech doesn't support volume control\n    if (player.tech && player.tech.features && player.tech.features['volumeControl'] === false) {\n      this.addClass('vjs-hidden');\n    }\n    player.on('loadstart', vjs.bind(this, function(){\n      if (player.tech.features && player.tech.features['volumeControl'] === false) {\n        this.addClass('vjs-hidden');\n      } else {\n        this.removeClass('vjs-hidden');\n      }\n    }));\n  }\n});\n\nvjs.MuteToggle.prototype.createEl = function(){\n  return vjs.Button.prototype.createEl.call(this, 'div', {\n    className: 'vjs-mute-control vjs-control',\n    innerHTML: '<div><span class=\"vjs-control-text\">Mute</span></div>'\n  });\n};\n\nvjs.MuteToggle.prototype.onClick = function(){\n  this.player_.muted( this.player_.muted() ? false : true );\n};\n\nvjs.MuteToggle.prototype.update = function(){\n  var vol = this.player_.volume(),\n      level = 3;\n\n  if (vol === 0 || this.player_.muted()) {\n    level = 0;\n  } else if (vol < 0.33) {\n    level = 1;\n  } else if (vol < 0.67) {\n    level = 2;\n  }\n\n  // Don't rewrite the button text if the actual text doesn't change.\n  // This causes unnecessary and confusing information for screen reader users.\n  // This check is needed because this function gets called every time the volume level is changed.\n  if(this.player_.muted()){\n      if(this.el_.children[0].children[0].innerHTML!='Unmute'){\n          this.el_.children[0].children[0].innerHTML = 'Unmute'; // change the button text to \"Unmute\"\n      }\n  } else {\n      if(this.el_.children[0].children[0].innerHTML!='Mute'){\n          this.el_.children[0].children[0].innerHTML = 'Mute'; // change the button text to \"Mute\"\n      }\n  }\n\n  /* TODO improve muted icon classes */\n  for (var i = 0; i < 4; i++) {\n    vjs.removeClass(this.el_, 'vjs-vol-'+i);\n  }\n  vjs.addClass(this.el_, 'vjs-vol-'+level);\n};\n/**\n * Menu button with a popup for showing the volume slider.\n * @constructor\n */\nvjs.VolumeMenuButton = vjs.MenuButton.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.MenuButton.call(this, player, options);\n\n    // Same listeners as MuteToggle\n    player.on('volumechange', vjs.bind(this, this.update));\n\n    // hide mute toggle if the current tech doesn't support volume control\n    if (player.tech && player.tech.features && player.tech.features.volumeControl === false) {\n      this.addClass('vjs-hidden');\n    }\n    player.on('loadstart', vjs.bind(this, function(){\n      if (player.tech.features && player.tech.features.volumeControl === false) {\n        this.addClass('vjs-hidden');\n      } else {\n        this.removeClass('vjs-hidden');\n      }\n    }));\n    this.addClass('vjs-menu-button');\n  }\n});\n\nvjs.VolumeMenuButton.prototype.createMenu = function(){\n  var menu = new vjs.Menu(this.player_, {\n    contentElType: 'div'\n  });\n  var vc = new vjs.VolumeBar(this.player_, vjs.obj.merge({vertical: true}, this.options_.volumeBar));\n  menu.addChild(vc);\n  return menu;\n};\n\nvjs.VolumeMenuButton.prototype.onClick = function(){\n  vjs.MuteToggle.prototype.onClick.call(this);\n  vjs.MenuButton.prototype.onClick.call(this);\n};\n\nvjs.VolumeMenuButton.prototype.createEl = function(){\n  return vjs.Button.prototype.createEl.call(this, 'div', {\n    className: 'vjs-volume-menu-button vjs-menu-button vjs-control',\n    innerHTML: '<div><span class=\"vjs-control-text\">Mute</span></div>'\n  });\n};\nvjs.VolumeMenuButton.prototype.update = vjs.MuteToggle.prototype.update;\n/* Poster Image\n================================================================================ */\n/**\n * The component that handles showing the poster image.\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.PosterImage = vjs.Button.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Button.call(this, player, options);\n\n    if (!player.poster() || !player.controls()) {\n      this.hide();\n    }\n\n    player.on('play', vjs.bind(this, this.hide));\n  }\n});\n\nvjs.PosterImage.prototype.createEl = function(){\n  var el = vjs.createEl('div', {\n        className: 'vjs-poster',\n\n        // Don't want poster to be tabbable.\n        tabIndex: -1\n      }),\n      poster = this.player_.poster();\n\n  if (poster) {\n    if ('backgroundSize' in el.style) {\n      el.style.backgroundImage = 'url(\"' + poster + '\")';\n    } else {\n      el.appendChild(vjs.createEl('img', { src: poster }));\n    }\n  }\n\n  return el;\n};\n\nvjs.PosterImage.prototype.onClick = function(){\n  // Only accept clicks when controls are enabled\n  if (this.player().controls()) {\n    this.player_.play();\n  }\n};\n/* Loading Spinner\n================================================================================ */\n/**\n * Loading spinner for waiting events\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @class\n * @constructor\n */\nvjs.LoadingSpinner = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Component.call(this, player, options);\n\n    player.on('canplay', vjs.bind(this, this.hide));\n    player.on('canplaythrough', vjs.bind(this, this.hide));\n    player.on('playing', vjs.bind(this, this.hide));\n    player.on('seeked', vjs.bind(this, this.hide));\n\n    player.on('seeking', vjs.bind(this, this.show));\n\n    // in some browsers seeking does not trigger the 'playing' event,\n    // so we also need to trap 'seeked' if we are going to set a\n    // 'seeking' event\n    player.on('seeked', vjs.bind(this, this.hide));\n\n    player.on('error', vjs.bind(this, this.show));\n\n    // Not showing spinner on stalled any more. Browsers may stall and then not trigger any events that would remove the spinner.\n    // Checked in Chrome 16 and Safari 5.1.2. http://help.videojs.com/discussions/problems/883-why-is-the-download-progress-showing\n    // player.on('stalled', vjs.bind(this, this.show));\n\n    player.on('waiting', vjs.bind(this, this.show));\n  }\n});\n\nvjs.LoadingSpinner.prototype.createEl = function(){\n  return vjs.Component.prototype.createEl.call(this, 'div', {\n    className: 'vjs-loading-spinner'\n  });\n};\n/* Big Play Button\n================================================================================ */\n/**\n * Initial play button. Shows before the video has played. The hiding of the\n * big play button is done via CSS and player states.\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @class\n * @constructor\n */\nvjs.BigPlayButton = vjs.Button.extend();\n\nvjs.BigPlayButton.prototype.createEl = function(){\n  return vjs.Button.prototype.createEl.call(this, 'div', {\n    className: 'vjs-big-play-button',\n    innerHTML: '<span aria-hidden=\"true\"></span>',\n    'aria-label': 'play video'\n  });\n};\n\nvjs.BigPlayButton.prototype.onClick = function(){\n  this.player_.play();\n};\n/**\n * @fileoverview Media Technology Controller - Base class for media playback\n * technology controllers like Flash and HTML5\n */\n\n/**\n * Base class for media (HTML5 Video, Flash) controllers\n * @param {vjs.Player|Object} player  Central player instance\n * @param {Object=} options Options object\n * @constructor\n */\nvjs.MediaTechController = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options, ready){\n    vjs.Component.call(this, player, options, ready);\n\n    this.initControlsListeners();\n  }\n});\n\n/**\n * Set up click and touch listeners for the playback element\n * On desktops, a click on the video itself will toggle playback,\n * on a mobile device a click on the video toggles controls.\n * (toggling controls is done by toggling the user state between active and\n * inactive)\n *\n * A tap can signal that a user has become active, or has become inactive\n * e.g. a quick tap on an iPhone movie should reveal the controls. Another\n * quick tap should hide them again (signaling the user is in an inactive\n * viewing state)\n *\n * In addition to this, we still want the user to be considered inactive after\n * a few seconds of inactivity.\n *\n * Note: the only part of iOS interaction we can't mimic with this setup\n * is a touch and hold on the video element counting as activity in order to\n * keep the controls showing, but that shouldn't be an issue. A touch and hold on\n * any controls will still keep the user active\n */\nvjs.MediaTechController.prototype.initControlsListeners = function(){\n  var player, tech, activateControls, deactivateControls;\n\n  tech = this;\n  player = this.player();\n\n  var activateControls = function(){\n    if (player.controls() && !player.usingNativeControls()) {\n      tech.addControlsListeners();\n    }\n  };\n\n  deactivateControls = vjs.bind(tech, tech.removeControlsListeners);\n\n  // Set up event listeners once the tech is ready and has an element to apply\n  // listeners to\n  this.ready(activateControls);\n  player.on('controlsenabled', activateControls);\n  player.on('controlsdisabled', deactivateControls);\n};\n\nvjs.MediaTechController.prototype.addControlsListeners = function(){\n  var preventBubble, userWasActive;\n\n  // Some browsers (Chrome & IE) don't trigger a click on a flash swf, but do\n  // trigger mousedown/up.\n  // http://stackoverflow.com/questions/1444562/javascript-onclick-event-over-flash-object\n  // Any touch events are set to block the mousedown event from happening\n  this.on('mousedown', this.onClick);\n\n  // We need to block touch events on the video element from bubbling up,\n  // otherwise they'll signal activity prematurely. The specific use case is\n  // when the video is playing and the controls have faded out. In this case\n  // only a tap (fast touch) should toggle the user active state and turn the\n  // controls back on. A touch and move or touch and hold should not trigger\n  // the controls (per iOS as an example at least)\n  //\n  // We always want to stop propagation on touchstart because touchstart\n  // at the player level starts the touchInProgress interval. We can still\n  // report activity on the other events, but won't let them bubble for\n  // consistency. We don't want to bubble a touchend without a touchstart.\n  this.on('touchstart', function(event) {\n    // Stop the mouse events from also happening\n    event.preventDefault();\n    event.stopPropagation();\n    // Record if the user was active now so we don't have to keep polling it\n    userWasActive = this.player_.userActive();\n  });\n\n  preventBubble = function(event){\n    event.stopPropagation();\n    if (userWasActive) {\n      this.player_.reportUserActivity();\n    }\n  };\n\n  // Treat all touch events the same for consistency\n  this.on('touchmove', preventBubble);\n  this.on('touchleave', preventBubble);\n  this.on('touchcancel', preventBubble);\n  this.on('touchend', preventBubble);\n\n  // Turn on component tap events\n  this.emitTapEvents();\n\n  // The tap listener needs to come after the touchend listener because the tap\n  // listener cancels out any reportedUserActivity when setting userActive(false)\n  this.on('tap', this.onTap);\n};\n\n/**\n * Remove the listeners used for click and tap controls. This is needed for\n * toggling to controls disabled, where a tap/touch should do nothing.\n */\nvjs.MediaTechController.prototype.removeControlsListeners = function(){\n  // We don't want to just use `this.off()` because there might be other needed\n  // listeners added by techs that extend this.\n  this.off('tap');\n  this.off('touchstart');\n  this.off('touchmove');\n  this.off('touchleave');\n  this.off('touchcancel');\n  this.off('touchend');\n  this.off('click');\n  this.off('mousedown');\n};\n\n/**\n * Handle a click on the media element. By default will play/pause the media.\n */\nvjs.MediaTechController.prototype.onClick = function(event){\n  // We're using mousedown to detect clicks thanks to Flash, but mousedown\n  // will also be triggered with right-clicks, so we need to prevent that\n  if (event.button !== 0) return;\n\n  // When controls are disabled a click should not toggle playback because\n  // the click is considered a control\n  if (this.player().controls()) {\n    if (this.player().paused()) {\n      this.player().play();\n    } else {\n      this.player().pause();\n    }\n  }\n};\n\n/**\n * Handle a tap on the media element. By default it will toggle the user\n * activity state, which hides and shows the controls.\n */\n\nvjs.MediaTechController.prototype.onTap = function(){\n  this.player().userActive(!this.player().userActive());\n};\n\nvjs.MediaTechController.prototype.features = {\n  'volumeControl': true,\n\n  // Resizing plugins using request fullscreen reloads the plugin\n  'fullscreenResize': false,\n\n  // Optional events that we can manually mimic with timers\n  // currently not triggered by video-js-swf\n  'progressEvents': false,\n  'timeupdateEvents': false\n};\n\nvjs.media = {};\n\n/**\n * List of default API methods for any MediaTechController\n * @type {String}\n */\nvjs.media.ApiMethods = 'play,pause,paused,currentTime,setCurrentTime,duration,buffered,volume,setVolume,muted,setMuted,width,height,supportsFullScreen,enterFullScreen,src,load,currentSrc,preload,setPreload,autoplay,setAutoplay,loop,setLoop,error,networkState,readyState,seeking,initialTime,startOffsetTime,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks,defaultPlaybackRate,playbackRate,mediaGroup,controller,controls,defaultMuted'.split(',');\n// Create placeholder methods for each that warn when a method isn't supported by the current playback technology\n\nfunction createMethod(methodName){\n  return function(){\n    throw new Error('The \"'+methodName+'\" method is not available on the playback technology\\'s API');\n  };\n}\n\nfor (var i = vjs.media.ApiMethods.length - 1; i >= 0; i--) {\n  var methodName = vjs.media.ApiMethods[i];\n  vjs.MediaTechController.prototype[vjs.media.ApiMethods[i]] = createMethod(methodName);\n}\n/**\n * @fileoverview HTML5 Media Controller - Wrapper for HTML5 Media API\n */\n\n/**\n * HTML5 Media Controller - Wrapper for HTML5 Media API\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @param {Function=} ready\n * @constructor\n */\nvjs.Html5 = vjs.MediaTechController.extend({\n  /** @constructor */\n  init: function(player, options, ready){\n    // volume cannot be changed from 1 on iOS\n    this.features['volumeControl'] = vjs.Html5.canControlVolume();\n\n    // In iOS, if you move a video element in the DOM, it breaks video playback.\n    this.features['movingMediaElementInDOM'] = !vjs.IS_IOS;\n\n    // HTML video is able to automatically resize when going to fullscreen\n    this.features['fullscreenResize'] = true;\n\n    vjs.MediaTechController.call(this, player, options, ready);\n\n    var source = options['source'];\n\n    // If the element source is already set, we may have missed the loadstart event, and want to trigger it.\n    // We don't want to set the source again and interrupt playback.\n    if (source && this.el_.currentSrc === source.src && this.el_.networkState > 0) {\n      player.trigger('loadstart');\n\n    // Otherwise set the source if one was provided.\n    } else if (source) {\n      this.el_.src = source.src;\n    }\n\n    // Determine if native controls should be used\n    // Our goal should be to get the custom controls on mobile solid everywhere\n    // so we can remove this all together. Right now this will block custom\n    // controls on touch enabled laptops like the Chrome Pixel\n    if (vjs.TOUCH_ENABLED && player.options()['nativeControlsForTouch'] !== false) {\n      this.useNativeControls();\n    }\n\n    // Chrome and Safari both have issues with autoplay.\n    // In Safari (5.1.1), when we move the video element into the container div, autoplay doesn't work.\n    // In Chrome (15), if you have autoplay + a poster + no controls, the video gets hidden (but audio plays)\n    // This fixes both issues. Need to wait for API, so it updates displays correctly\n    player.ready(function(){\n      if (this.tag && this.options_['autoplay'] && this.paused()) {\n        delete this.tag['poster']; // Chrome Fix. Fixed in Chrome v16.\n        this.play();\n      }\n    });\n\n    this.setupTriggers();\n    this.triggerReady();\n  }\n});\n\nvjs.Html5.prototype.dispose = function(){\n  vjs.MediaTechController.prototype.dispose.call(this);\n};\n\nvjs.Html5.prototype.createEl = function(){\n  var player = this.player_,\n      // If possible, reuse original tag for HTML5 playback technology element\n      el = player.tag,\n      newEl,\n      clone;\n\n  // Check if this browser supports moving the element into the box.\n  // On the iPhone video will break if you move the element,\n  // So we have to create a brand new element.\n  if (!el || this.features['movingMediaElementInDOM'] === false) {\n\n    // If the original tag is still there, clone and remove it.\n    if (el) {\n      clone = el.cloneNode(false);\n      vjs.Html5.disposeMediaElement(el);\n      el = clone;\n      player.tag = null;\n    } else {\n      el = vjs.createEl('video', {\n        id:player.id() + '_html5_api',\n        className:'vjs-tech'\n      });\n    }\n    // associate the player with the new tag\n    el['player'] = player;\n\n    vjs.insertFirst(el, player.el());\n  }\n\n  // Update specific tag settings, in case they were overridden\n  var attrs = ['autoplay','preload','loop','muted'];\n  for (var i = attrs.length - 1; i >= 0; i--) {\n    var attr = attrs[i];\n    if (player.options_[attr] !== null) {\n      el[attr] = player.options_[attr];\n    }\n  }\n\n  return el;\n  // jenniisawesome = true;\n};\n\n// Make video events trigger player events\n// May seem verbose here, but makes other APIs possible.\nvjs.Html5.prototype.setupTriggers = function(){\n  for (var i = vjs.Html5.Events.length - 1; i >= 0; i--) {\n    vjs.on(this.el_, vjs.Html5.Events[i], vjs.bind(this.player_, this.eventHandler));\n  }\n};\n// Triggers removed using this.off when disposed\n\nvjs.Html5.prototype.eventHandler = function(e){\n  this.trigger(e);\n\n  // No need for media events to bubble up.\n  e.stopPropagation();\n};\n\nvjs.Html5.prototype.useNativeControls = function(){\n  var tech, player, controlsOn, controlsOff, cleanUp;\n\n  tech = this;\n  player = this.player();\n\n  // If the player controls are enabled turn on the native controls\n  tech.setControls(player.controls());\n\n  // Update the native controls when player controls state is updated\n  controlsOn = function(){\n    tech.setControls(true);\n  };\n  controlsOff = function(){\n    tech.setControls(false);\n  };\n  player.on('controlsenabled', controlsOn);\n  player.on('controlsdisabled', controlsOff);\n\n  // Clean up when not using native controls anymore\n  cleanUp = function(){\n    player.off('controlsenabled', controlsOn);\n    player.off('controlsdisabled', controlsOff);\n  };\n  tech.on('dispose', cleanUp);\n  player.on('usingcustomcontrols', cleanUp);\n\n  // Update the state of the player to using native controls\n  player.usingNativeControls(true);\n};\n\n\nvjs.Html5.prototype.play = function(){ this.el_.play(); };\nvjs.Html5.prototype.pause = function(){ this.el_.pause(); };\nvjs.Html5.prototype.paused = function(){ return this.el_.paused; };\n\nvjs.Html5.prototype.currentTime = function(){ return this.el_.currentTime; };\nvjs.Html5.prototype.setCurrentTime = function(seconds){\n  try {\n    this.el_.currentTime = seconds;\n  } catch(e) {\n    vjs.log(e, 'Video is not ready. (Video.js)');\n    // this.warning(VideoJS.warnings.videoNotReady);\n  }\n};\n\nvjs.Html5.prototype.duration = function(){ return this.el_.duration || 0; };\nvjs.Html5.prototype.buffered = function(){ return this.el_.buffered; };\n\nvjs.Html5.prototype.volume = function(){ return this.el_.volume; };\nvjs.Html5.prototype.setVolume = function(percentAsDecimal){ this.el_.volume = percentAsDecimal; };\nvjs.Html5.prototype.muted = function(){ return this.el_.muted; };\nvjs.Html5.prototype.setMuted = function(muted){ this.el_.muted = muted; };\n\nvjs.Html5.prototype.width = function(){ return this.el_.offsetWidth; };\nvjs.Html5.prototype.height = function(){ return this.el_.offsetHeight; };\n\nvjs.Html5.prototype.supportsFullScreen = function(){\n  if (typeof this.el_.webkitEnterFullScreen == 'function') {\n\n    // Seems to be broken in Chromium/Chrome && Safari in Leopard\n    if (/Android/.test(vjs.USER_AGENT) || !/Chrome|Mac OS X 10.5/.test(vjs.USER_AGENT)) {\n      return true;\n    }\n  }\n  return false;\n};\n\nvjs.Html5.prototype.enterFullScreen = function(){\n  var video = this.el_;\n  if (video.paused && video.networkState <= video.HAVE_METADATA) {\n    // attempt to prime the video element for programmatic access\n    // this isn't necessary on the desktop but shouldn't hurt\n    this.el_.play();\n\n    // playing and pausing synchronously during the transition to fullscreen\n    // can get iOS ~6.1 devices into a play/pause loop\n    setTimeout(function(){\n      video.pause();\n      video.webkitEnterFullScreen();\n    }, 0);\n  } else {\n    video.webkitEnterFullScreen();\n  }\n};\nvjs.Html5.prototype.exitFullScreen = function(){\n  this.el_.webkitExitFullScreen();\n};\nvjs.Html5.prototype.src = function(src){ this.el_.src = src; };\nvjs.Html5.prototype.load = function(){ this.el_.load(); };\nvjs.Html5.prototype.currentSrc = function(){ return this.el_.currentSrc; };\n\nvjs.Html5.prototype.preload = function(){ return this.el_.preload; };\nvjs.Html5.prototype.setPreload = function(val){ this.el_.preload = val; };\n\nvjs.Html5.prototype.autoplay = function(){ return this.el_.autoplay; };\nvjs.Html5.prototype.setAutoplay = function(val){ this.el_.autoplay = val; };\n\nvjs.Html5.prototype.controls = function(){ return this.el_.controls; }\nvjs.Html5.prototype.setControls = function(val){ this.el_.controls = !!val; }\n\nvjs.Html5.prototype.loop = function(){ return this.el_.loop; };\nvjs.Html5.prototype.setLoop = function(val){ this.el_.loop = val; };\n\nvjs.Html5.prototype.error = function(){ return this.el_.error; };\nvjs.Html5.prototype.seeking = function(){ return this.el_.seeking; };\nvjs.Html5.prototype.ended = function(){ return this.el_.ended; };\nvjs.Html5.prototype.defaultMuted = function(){ return this.el_.defaultMuted; };\n\n/* HTML5 Support Testing ---------------------------------------------------- */\n\nvjs.Html5.isSupported = function(){\n  return !!vjs.TEST_VID.canPlayType;\n};\n\nvjs.Html5.canPlaySource = function(srcObj){\n  // IE9 on Windows 7 without MediaPlayer throws an error here\n  // https://github.com/videojs/video.js/issues/519\n  try {\n    return !!vjs.TEST_VID.canPlayType(srcObj.type);\n  } catch(e) {\n    return '';\n  }\n  // TODO: Check Type\n  // If no Type, check ext\n  // Check Media Type\n};\n\nvjs.Html5.canControlVolume = function(){\n  var volume =  vjs.TEST_VID.volume;\n  vjs.TEST_VID.volume = (volume / 2) + 0.1;\n  return volume !== vjs.TEST_VID.volume;\n};\n\n// List of all HTML5 events (various uses).\nvjs.Html5.Events = 'loadstart,suspend,abort,error,emptied,stalled,loadedmetadata,loadeddata,canplay,canplaythrough,playing,waiting,seeking,seeked,ended,durationchange,timeupdate,progress,play,pause,ratechange,volumechange'.split(',');\n\nvjs.Html5.disposeMediaElement = function(el){\n  if (!el) { return; }\n\n  el['player'] = null;\n\n  if (el.parentNode) {\n    el.parentNode.removeChild(el);\n  }\n\n  // remove any child track or source nodes to prevent their loading\n  while(el.hasChildNodes()) {\n    el.removeChild(el.firstChild);\n  }\n\n  // remove any src reference. not setting `src=''` because that causes a warning\n  // in firefox\n  el.removeAttribute('src');\n\n  // force the media element to update its loading state by calling load()\n  if (typeof el.load === 'function') {\n    el.load();\n  }\n};\n\n// HTML5 Feature detection and Device Fixes --------------------------------- //\n\n  // Override Android 2.2 and less canPlayType method which is broken\nif (vjs.IS_OLD_ANDROID) {\n  document.createElement('video').constructor.prototype.canPlayType = function(type){\n    return (type && type.toLowerCase().indexOf('video/mp4') != -1) ? 'maybe' : '';\n  };\n}\n/**\n * @fileoverview VideoJS-SWF - Custom Flash Player with HTML5-ish API\n * https://github.com/zencoder/video-js-swf\n * Not using setupTriggers. Using global onEvent func to distribute events\n */\n\n/**\n * Flash Media Controller - Wrapper for fallback SWF API\n *\n * @param {vjs.Player} player\n * @param {Object=} options\n * @param {Function=} ready\n * @constructor\n */\nvjs.Flash = vjs.MediaTechController.extend({\n  /** @constructor */\n  init: function(player, options, ready){\n    vjs.MediaTechController.call(this, player, options, ready);\n\n    var source = options['source'],\n\n        // Which element to embed in\n        parentEl = options['parentEl'],\n\n        // Create a temporary element to be replaced by swf object\n        placeHolder = this.el_ = vjs.createEl('div', { id: player.id() + '_temp_flash' }),\n\n        // Generate ID for swf object\n        objId = player.id()+'_flash_api',\n\n        // Store player options in local var for optimization\n        // TODO: switch to using player methods instead of options\n        // e.g. player.autoplay();\n        playerOptions = player.options_,\n\n        // Merge default flashvars with ones passed in to init\n        flashVars = vjs.obj.merge({\n\n          // SWF Callback Functions\n          'readyFunction': 'videojs.Flash.onReady',\n          'eventProxyFunction': 'videojs.Flash.onEvent',\n          'errorEventProxyFunction': 'videojs.Flash.onError',\n\n          // Player Settings\n          'autoplay': playerOptions.autoplay,\n          'preload': playerOptions.preload,\n          'loop': playerOptions.loop,\n          'muted': playerOptions.muted\n\n        }, options['flashVars']),\n\n        // Merge default parames with ones passed in\n        params = vjs.obj.merge({\n          'wmode': 'opaque', // Opaque is needed to overlay controls, but can affect playback performance\n          'bgcolor': '#000000' // Using bgcolor prevents a white flash when the object is loading\n        }, options['params']),\n\n        // Merge default attributes with ones passed in\n        attributes = vjs.obj.merge({\n          'id': objId,\n          'name': objId, // Both ID and Name needed or swf to identifty itself\n          'class': 'vjs-tech'\n        }, options['attributes'])\n    ;\n\n    // If source was supplied pass as a flash var.\n    if (source) {\n      if (source.type && vjs.Flash.isStreamingType(source.type)) {\n        var parts = vjs.Flash.streamToParts(source.src);\n        flashVars['rtmpConnection'] = encodeURIComponent(parts.connection);\n        flashVars['rtmpStream'] = encodeURIComponent(parts.stream);\n      }\n      else {\n        flashVars['src'] = encodeURIComponent(vjs.getAbsoluteURL(source.src));\n      }\n    }\n\n    // Add placeholder to player div\n    vjs.insertFirst(placeHolder, parentEl);\n\n    // Having issues with Flash reloading on certain page actions (hide/resize/fullscreen) in certain browsers\n    // This allows resetting the playhead when we catch the reload\n    if (options['startTime']) {\n      this.ready(function(){\n        this.load();\n        this.play();\n        this.currentTime(options['startTime']);\n      });\n    }\n\n    // Flash iFrame Mode\n    // In web browsers there are multiple instances where changing the parent element or visibility of a plugin causes the plugin to reload.\n    // - Firefox just about always. https://bugzilla.mozilla.org/show_bug.cgi?id=90268 (might be fixed by version 13)\n    // - Webkit when hiding the plugin\n    // - Webkit and Firefox when using requestFullScreen on a parent element\n    // Loading the flash plugin into a dynamically generated iFrame gets around most of these issues.\n    // Issues that remain include hiding the element and requestFullScreen in Firefox specifically\n\n    // There's on particularly annoying issue with this method which is that Firefox throws a security error on an offsite Flash object loaded into a dynamically created iFrame.\n    // Even though the iframe was inserted into a page on the web, Firefox + Flash considers it a local app trying to access an internet file.\n    // I tried mulitple ways of setting the iframe src attribute but couldn't find a src that worked well. Tried a real/fake source, in/out of domain.\n    // Also tried a method from stackoverflow that caused a security error in all browsers. http://stackoverflow.com/questions/2486901/how-to-set-document-domain-for-a-dynamically-generated-iframe\n    // In the end the solution I found to work was setting the iframe window.location.href right before doing a document.write of the Flash object.\n    // The only downside of this it seems to trigger another http request to the original page (no matter what's put in the href). Not sure why that is.\n\n    // NOTE (2012-01-29): Cannot get Firefox to load the remote hosted SWF into a dynamically created iFrame\n    // Firefox 9 throws a security error, unleess you call location.href right before doc.write.\n    //    Not sure why that even works, but it causes the browser to look like it's continuously trying to load the page.\n    // Firefox 3.6 keeps calling the iframe onload function anytime I write to it, causing an endless loop.\n\n    if (options['iFrameMode'] === true && !vjs.IS_FIREFOX) {\n\n      // Create iFrame with vjs-tech class so it's 100% width/height\n      var iFrm = vjs.createEl('iframe', {\n        'id': objId + '_iframe',\n        'name': objId + '_iframe',\n        'className': 'vjs-tech',\n        'scrolling': 'no',\n        'marginWidth': 0,\n        'marginHeight': 0,\n        'frameBorder': 0\n      });\n\n      // Update ready function names in flash vars for iframe window\n      flashVars['readyFunction'] = 'ready';\n      flashVars['eventProxyFunction'] = 'events';\n      flashVars['errorEventProxyFunction'] = 'errors';\n\n      // Tried multiple methods to get this to work in all browsers\n\n      // Tried embedding the flash object in the page first, and then adding a place holder to the iframe, then replacing the placeholder with the page object.\n      // The goal here was to try to load the swf URL in the parent page first and hope that got around the firefox security error\n      // var newObj = vjs.Flash.embed(options['swf'], placeHolder, flashVars, params, attributes);\n      // (in onload)\n      //  var temp = vjs.createEl('a', { id:'asdf', innerHTML: 'asdf' } );\n      //  iDoc.body.appendChild(temp);\n\n      // Tried embedding the flash object through javascript in the iframe source.\n      // This works in webkit but still triggers the firefox security error\n      // iFrm.src = 'javascript: document.write('\"+vjs.Flash.getEmbedCode(options['swf'], flashVars, params, attributes)+\"');\";\n\n      // Tried an actual local iframe just to make sure that works, but it kills the easiness of the CDN version if you require the user to host an iframe\n      // We should add an option to host the iframe locally though, because it could help a lot of issues.\n      // iFrm.src = \"iframe.html\";\n\n      // Wait until iFrame has loaded to write into it.\n      vjs.on(iFrm, 'load', vjs.bind(this, function(){\n\n        var iDoc,\n            iWin = iFrm.contentWindow;\n\n        // The one working method I found was to use the iframe's document.write() to create the swf object\n        // This got around the security issue in all browsers except firefox.\n        // I did find a hack where if I call the iframe's window.location.href='', it would get around the security error\n        // However, the main page would look like it was loading indefinitely (URL bar loading spinner would never stop)\n        // Plus Firefox 3.6 didn't work no matter what I tried.\n        // if (vjs.USER_AGENT.match('Firefox')) {\n        //   iWin.location.href = '';\n        // }\n\n        // Get the iFrame's document depending on what the browser supports\n        iDoc = iFrm.contentDocument ? iFrm.contentDocument : iFrm.contentWindow.document;\n\n        // Tried ensuring both document domains were the same, but they already were, so that wasn't the issue.\n        // Even tried adding /. that was mentioned in a browser security writeup\n        // document.domain = document.domain+'/.';\n        // iDoc.domain = document.domain+'/.';\n\n        // Tried adding the object to the iframe doc's innerHTML. Security error in all browsers.\n        // iDoc.body.innerHTML = swfObjectHTML;\n\n        // Tried appending the object to the iframe doc's body. Security error in all browsers.\n        // iDoc.body.appendChild(swfObject);\n\n        // Using document.write actually got around the security error that browsers were throwing.\n        // Again, it's a dynamically generated (same domain) iframe, loading an external Flash swf.\n        // Not sure why that's a security issue, but apparently it is.\n        iDoc.write(vjs.Flash.getEmbedCode(options['swf'], flashVars, params, attributes));\n\n        // Setting variables on the window needs to come after the doc write because otherwise they can get reset in some browsers\n        // So far no issues with swf ready event being called before it's set on the window.\n        iWin['player'] = this.player_;\n\n        // Create swf ready function for iFrame window\n        iWin['ready'] = vjs.bind(this.player_, function(currSwf){\n          var el = iDoc.getElementById(currSwf),\n              player = this,\n              tech = player.tech;\n\n          // Update reference to playback technology element\n          tech.el_ = el;\n\n          // Make sure swf is actually ready. Sometimes the API isn't actually yet.\n          vjs.Flash.checkReady(tech);\n        });\n\n        // Create event listener for all swf events\n        iWin['events'] = vjs.bind(this.player_, function(swfID, eventName){\n          var player = this;\n          if (player && player.techName === 'flash') {\n            player.trigger(eventName);\n          }\n        });\n\n        // Create error listener for all swf errors\n        iWin['errors'] = vjs.bind(this.player_, function(swfID, eventName){\n          vjs.log('Flash Error', eventName);\n        });\n\n      }));\n\n      // Replace placeholder with iFrame (it will load now)\n      placeHolder.parentNode.replaceChild(iFrm, placeHolder);\n\n    // If not using iFrame mode, embed as normal object\n    } else {\n      vjs.Flash.embed(options['swf'], placeHolder, flashVars, params, attributes);\n    }\n  }\n});\n\nvjs.Flash.prototype.dispose = function(){\n  vjs.MediaTechController.prototype.dispose.call(this);\n};\n\nvjs.Flash.prototype.play = function(){\n  this.el_.vjs_play();\n};\n\nvjs.Flash.prototype.pause = function(){\n  this.el_.vjs_pause();\n};\n\nvjs.Flash.prototype.src = function(src){\n  if (vjs.Flash.isStreamingSrc(src)) {\n    src = vjs.Flash.streamToParts(src);\n    this.setRtmpConnection(src.connection);\n    this.setRtmpStream(src.stream);\n  }\n  else {\n    // Make sure source URL is abosolute.\n    src = vjs.getAbsoluteURL(src);\n    this.el_.vjs_src(src);\n  }\n\n  // Currently the SWF doesn't autoplay if you load a source later.\n  // e.g. Load player w/ no source, wait 2s, set src.\n  if (this.player_.autoplay()) {\n    var tech = this;\n    setTimeout(function(){ tech.play(); }, 0);\n  }\n};\n\nvjs.Flash.prototype.currentSrc = function(){\n  var src = this.el_.vjs_getProperty('currentSrc');\n  // no src, check and see if RTMP\n  if (src == null) {\n    var connection = this.rtmpConnection(),\n        stream = this.rtmpStream();\n\n    if (connection && stream) {\n      src = vjs.Flash.streamFromParts(connection, stream);\n    }\n  }\n  return src;\n};\n\nvjs.Flash.prototype.load = function(){\n  this.el_.vjs_load();\n};\n\nvjs.Flash.prototype.poster = function(){\n  this.el_.vjs_getProperty('poster');\n};\n\nvjs.Flash.prototype.buffered = function(){\n  return vjs.createTimeRange(0, this.el_.vjs_getProperty('buffered'));\n};\n\nvjs.Flash.prototype.supportsFullScreen = function(){\n  return false; // Flash does not allow fullscreen through javascript\n};\n\nvjs.Flash.prototype.enterFullScreen = function(){\n  return false;\n};\n\n\n// Create setters and getters for attributes\nvar api = vjs.Flash.prototype,\n    readWrite = 'rtmpConnection,rtmpStream,preload,currentTime,defaultPlaybackRate,playbackRate,autoplay,loop,mediaGroup,controller,controls,volume,muted,defaultMuted'.split(','),\n    readOnly = 'error,currentSrc,networkState,readyState,seeking,initialTime,duration,startOffsetTime,paused,played,seekable,ended,videoTracks,audioTracks,videoWidth,videoHeight,textTracks'.split(',');\n    // Overridden: buffered\n\n/**\n * @this {*}\n * @private\n */\nvar createSetter = function(attr){\n  var attrUpper = attr.charAt(0).toUpperCase() + attr.slice(1);\n  api['set'+attrUpper] = function(val){ return this.el_.vjs_setProperty(attr, val); };\n};\n\n/**\n * @this {*}\n * @private\n */\nvar createGetter = function(attr){\n  api[attr] = function(){ return this.el_.vjs_getProperty(attr); };\n};\n\n(function(){\n  var i;\n  // Create getter and setters for all read/write attributes\n  for (i = 0; i < readWrite.length; i++) {\n    createGetter(readWrite[i]);\n    createSetter(readWrite[i]);\n  }\n\n  // Create getters for read-only attributes\n  for (i = 0; i < readOnly.length; i++) {\n    createGetter(readOnly[i]);\n  }\n})();\n\n/* Flash Support Testing -------------------------------------------------------- */\n\nvjs.Flash.isSupported = function(){\n  return vjs.Flash.version()[0] >= 10;\n  // return swfobject.hasFlashPlayerVersion('10');\n};\n\nvjs.Flash.canPlaySource = function(srcObj){\n  var type;\n\n  if (!srcObj.type) {\n    return '';\n  }\n\n  type = srcObj.type.replace(/;.*/,'').toLowerCase();\n  if (type in vjs.Flash.formats || type in vjs.Flash.streamingFormats) {\n    return 'maybe';\n  }\n};\n\nvjs.Flash.formats = {\n  'video/flv': 'FLV',\n  'video/x-flv': 'FLV',\n  'video/mp4': 'MP4',\n  'video/m4v': 'MP4'\n};\n\nvjs.Flash.streamingFormats = {\n  'rtmp/mp4': 'MP4',\n  'rtmp/flv': 'FLV'\n};\n\nvjs.Flash['onReady'] = function(currSwf){\n  var el = vjs.el(currSwf);\n\n  // Get player from box\n  // On firefox reloads, el might already have a player\n  var player = el['player'] || el.parentNode['player'],\n      tech = player.tech;\n\n  // Reference player on tech element\n  el['player'] = player;\n\n  // Update reference to playback technology element\n  tech.el_ = el;\n\n  vjs.Flash.checkReady(tech);\n};\n\n// The SWF isn't alwasy ready when it says it is. Sometimes the API functions still need to be added to the object.\n// If it's not ready, we set a timeout to check again shortly.\nvjs.Flash.checkReady = function(tech){\n\n  // Check if API property exists\n  if (tech.el().vjs_getProperty) {\n\n    // If so, tell tech it's ready\n    tech.triggerReady();\n\n  // Otherwise wait longer.\n  } else {\n\n    setTimeout(function(){\n      vjs.Flash.checkReady(tech);\n    }, 50);\n\n  }\n};\n\n// Trigger events from the swf on the player\nvjs.Flash['onEvent'] = function(swfID, eventName){\n  var player = vjs.el(swfID)['player'];\n  player.trigger(eventName);\n};\n\n// Log errors from the swf\nvjs.Flash['onError'] = function(swfID, err){\n  var player = vjs.el(swfID)['player'];\n  player.trigger('error');\n  vjs.log('Flash Error', err, swfID);\n};\n\n// Flash Version Check\nvjs.Flash.version = function(){\n  var version = '0,0,0';\n\n  // IE\n  try {\n    version = new window.ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version').replace(/\\D+/g, ',').match(/^,?(.+),?$/)[1];\n\n  // other browsers\n  } catch(e) {\n    try {\n      if (navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin){\n        version = (navigator.plugins['Shockwave Flash 2.0'] || navigator.plugins['Shockwave Flash']).description.replace(/\\D+/g, ',').match(/^,?(.+),?$/)[1];\n      }\n    } catch(err) {}\n  }\n  return version.split(',');\n};\n\n// Flash embedding method. Only used in non-iframe mode\nvjs.Flash.embed = function(swf, placeHolder, flashVars, params, attributes){\n  var code = vjs.Flash.getEmbedCode(swf, flashVars, params, attributes),\n\n      // Get element by embedding code and retrieving created element\n      obj = vjs.createEl('div', { innerHTML: code }).childNodes[0],\n\n      par = placeHolder.parentNode\n  ;\n\n  placeHolder.parentNode.replaceChild(obj, placeHolder);\n\n  // IE6 seems to have an issue where it won't initialize the swf object after injecting it.\n  // This is a dumb fix\n  var newObj = par.childNodes[0];\n  setTimeout(function(){\n    newObj.style.display = 'block';\n  }, 1000);\n\n  return obj;\n\n};\n\nvjs.Flash.getEmbedCode = function(swf, flashVars, params, attributes){\n\n  var objTag = '<object type=\"application/x-shockwave-flash\"',\n      flashVarsString = '',\n      paramsString = '',\n      attrsString = '';\n\n  // Convert flash vars to string\n  if (flashVars) {\n    vjs.obj.each(flashVars, function(key, val){\n      flashVarsString += (key + '=' + val + '&amp;');\n    });\n  }\n\n  // Add swf, flashVars, and other default params\n  params = vjs.obj.merge({\n    'movie': swf,\n    'flashvars': flashVarsString,\n    'allowScriptAccess': 'always', // Required to talk to swf\n    'allowNetworking': 'all' // All should be default, but having security issues.\n  }, params);\n\n  // Create param tags string\n  vjs.obj.each(params, function(key, val){\n    paramsString += '<param name=\"'+key+'\" value=\"'+val+'\" />';\n  });\n\n  attributes = vjs.obj.merge({\n    // Add swf to attributes (need both for IE and Others to work)\n    'data': swf,\n\n    // Default to 100% width/height\n    'width': '100%',\n    'height': '100%'\n\n  }, attributes);\n\n  // Create Attributes string\n  vjs.obj.each(attributes, function(key, val){\n    attrsString += (key + '=\"' + val + '\" ');\n  });\n\n  return objTag + attrsString + '>' + paramsString + '</object>';\n};\n\nvjs.Flash.streamFromParts = function(connection, stream) {\n  return connection + '&' + stream;\n};\n\nvjs.Flash.streamToParts = function(src) {\n  var parts = {\n    connection: '',\n    stream: ''\n  };\n\n  if (! src) {\n    return parts;\n  }\n\n  // Look for the normal URL separator we expect, '&'.\n  // If found, we split the URL into two pieces around the\n  // first '&'.\n  var connEnd = src.indexOf('&');\n  var streamBegin;\n  if (connEnd !== -1) {\n    streamBegin = connEnd + 1;\n  }\n  else {\n    // If there's not a '&', we use the last '/' as the delimiter.\n    connEnd = streamBegin = src.lastIndexOf('/') + 1;\n    if (connEnd === 0) {\n      // really, there's not a '/'?\n      connEnd = streamBegin = src.length;\n    }\n  }\n  parts.connection = src.substring(0, connEnd);\n  parts.stream = src.substring(streamBegin, src.length);\n\n  return parts;\n};\n\nvjs.Flash.isStreamingType = function(srcType) {\n  return srcType in vjs.Flash.streamingFormats;\n};\n\n// RTMP has four variations, any string starting\n// with one of these protocols should be valid\nvjs.Flash.RTMP_RE = /^rtmp[set]?:\\/\\//i;\n\nvjs.Flash.isStreamingSrc = function(src) {\n  return vjs.Flash.RTMP_RE.test(src);\n};\n/**\n * The Media Loader is the component that decides which playback technology to load\n * when the player is initialized.\n *\n * @constructor\n */\nvjs.MediaLoader = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options, ready){\n    vjs.Component.call(this, player, options, ready);\n\n    // If there are no sources when the player is initialized,\n    // load the first supported playback technology.\n    if (!player.options_['sources'] || player.options_['sources'].length === 0) {\n      for (var i=0,j=player.options_['techOrder']; i<j.length; i++) {\n        var techName = vjs.capitalize(j[i]),\n            tech = window['videojs'][techName];\n\n        // Check if the browser supports this technology\n        if (tech && tech.isSupported()) {\n          player.loadTech(techName);\n          break;\n        }\n      }\n    } else {\n      // // Loop through playback technologies (HTML5, Flash) and check for support.\n      // // Then load the best source.\n      // // A few assumptions here:\n      // //   All playback technologies respect preload false.\n      player.src(player.options_['sources']);\n    }\n  }\n});\n/**\n * @fileoverview Text Tracks\n * Text tracks are tracks of timed text events.\n * Captions - text displayed over the video for the hearing impared\n * Subtitles - text displayed over the video for those who don't understand langauge in the video\n * Chapters - text displayed in a menu allowing the user to jump to particular points (chapters) in the video\n * Descriptions (not supported yet) - audio descriptions that are read back to the user by a screen reading device\n */\n\n// Player Additions - Functions add to the player object for easier access to tracks\n\n/**\n * List of associated text tracks\n * @type {Array}\n * @private\n */\nvjs.Player.prototype.textTracks_;\n\n/**\n * Get an array of associated text tracks. captions, subtitles, chapters, descriptions\n * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-texttracks\n * @return {Array}           Array of track objects\n * @private\n */\nvjs.Player.prototype.textTracks = function(){\n  this.textTracks_ = this.textTracks_ || [];\n  return this.textTracks_;\n};\n\n/**\n * Add a text track\n * In addition to the W3C settings we allow adding additional info through options.\n * http://www.w3.org/html/wg/drafts/html/master/embedded-content-0.html#dom-media-addtexttrack\n * @param {String}  kind        Captions, subtitles, chapters, descriptions, or metadata\n * @param {String=} label       Optional label\n * @param {String=} language    Optional language\n * @param {Object=} options     Additional track options, like src\n * @private\n */\nvjs.Player.prototype.addTextTrack = function(kind, label, language, options){\n  var tracks = this.textTracks_ = this.textTracks_ || [];\n  options = options || {};\n\n  options['kind'] = kind;\n  options['label'] = label;\n  options['language'] = language;\n\n  // HTML5 Spec says default to subtitles.\n  // Uppercase first letter to match class names\n  var Kind = vjs.capitalize(kind || 'subtitles');\n\n  // Create correct texttrack class. CaptionsTrack, etc.\n  var track = new window['videojs'][Kind + 'Track'](this, options);\n\n  tracks.push(track);\n\n  // If track.dflt() is set, start showing immediately\n  // TODO: Add a process to deterime the best track to show for the specific kind\n  // Incase there are mulitple defaulted tracks of the same kind\n  // Or the user has a set preference of a specific language that should override the default\n  // if (track.dflt()) {\n  //   this.ready(vjs.bind(track, track.show));\n  // }\n\n  return track;\n};\n\n/**\n * Add an array of text tracks. captions, subtitles, chapters, descriptions\n * Track objects will be stored in the player.textTracks() array\n * @param {Array} trackList Array of track elements or objects (fake track elements)\n * @private\n */\nvjs.Player.prototype.addTextTracks = function(trackList){\n  var trackObj;\n\n  for (var i = 0; i < trackList.length; i++) {\n    trackObj = trackList[i];\n    this.addTextTrack(trackObj['kind'], trackObj['label'], trackObj['language'], trackObj);\n  }\n\n  return this;\n};\n\n// Show a text track\n// disableSameKind: disable all other tracks of the same kind. Value should be a track kind (captions, etc.)\nvjs.Player.prototype.showTextTrack = function(id, disableSameKind){\n  var tracks = this.textTracks_,\n      i = 0,\n      j = tracks.length,\n      track, showTrack, kind;\n\n  // Find Track with same ID\n  for (;i<j;i++) {\n    track = tracks[i];\n    if (track.id() === id) {\n      track.show();\n      showTrack = track;\n\n    // Disable tracks of the same kind\n    } else if (disableSameKind && track.kind() == disableSameKind && track.mode() > 0) {\n      track.disable();\n    }\n  }\n\n  // Get track kind from shown track or disableSameKind\n  kind = (showTrack) ? showTrack.kind() : ((disableSameKind) ? disableSameKind : false);\n\n  // Trigger trackchange event, captionstrackchange, subtitlestrackchange, etc.\n  if (kind) {\n    this.trigger(kind+'trackchange');\n  }\n\n  return this;\n};\n\n/**\n * The base class for all text tracks\n *\n * Handles the parsing, hiding, and showing of text track cues\n *\n * @param {vjs.Player|Object} player\n * @param {Object=} options\n * @constructor\n */\nvjs.TextTrack = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.Component.call(this, player, options);\n\n    // Apply track info to track object\n    // Options will often be a track element\n\n    // Build ID if one doesn't exist\n    this.id_ = options['id'] || ('vjs_' + options['kind'] + '_' + options['language'] + '_' + vjs.guid++);\n    this.src_ = options['src'];\n    // 'default' is a reserved keyword in js so we use an abbreviated version\n    this.dflt_ = options['default'] || options['dflt'];\n    this.title_ = options['title'];\n    this.language_ = options['srclang'];\n    this.label_ = options['label'];\n    this.cues_ = [];\n    this.activeCues_ = [];\n    this.readyState_ = 0;\n    this.mode_ = 0;\n\n    this.player_.on('fullscreenchange', vjs.bind(this, this.adjustFontSize));\n  }\n});\n\n/**\n * Track kind value. Captions, subtitles, etc.\n * @private\n */\nvjs.TextTrack.prototype.kind_;\n\n/**\n * Get the track kind value\n * @return {String}\n */\nvjs.TextTrack.prototype.kind = function(){\n  return this.kind_;\n};\n\n/**\n * Track src value\n * @private\n */\nvjs.TextTrack.prototype.src_;\n\n/**\n * Get the track src value\n * @return {String}\n */\nvjs.TextTrack.prototype.src = function(){\n  return this.src_;\n};\n\n/**\n * Track default value\n * If default is used, subtitles/captions to start showing\n * @private\n */\nvjs.TextTrack.prototype.dflt_;\n\n/**\n * Get the track default value. ('default' is a reserved keyword)\n * @return {Boolean}\n */\nvjs.TextTrack.prototype.dflt = function(){\n  return this.dflt_;\n};\n\n/**\n * Track title value\n * @private\n */\nvjs.TextTrack.prototype.title_;\n\n/**\n * Get the track title value\n * @return {String}\n */\nvjs.TextTrack.prototype.title = function(){\n  return this.title_;\n};\n\n/**\n * Language - two letter string to represent track language, e.g. 'en' for English\n * Spec def: readonly attribute DOMString language;\n * @private\n */\nvjs.TextTrack.prototype.language_;\n\n/**\n * Get the track language value\n * @return {String}\n */\nvjs.TextTrack.prototype.language = function(){\n  return this.language_;\n};\n\n/**\n * Track label e.g. 'English'\n * Spec def: readonly attribute DOMString label;\n * @private\n */\nvjs.TextTrack.prototype.label_;\n\n/**\n * Get the track label value\n * @return {String}\n */\nvjs.TextTrack.prototype.label = function(){\n  return this.label_;\n};\n\n/**\n * All cues of the track. Cues have a startTime, endTime, text, and other properties.\n * Spec def: readonly attribute TextTrackCueList cues;\n * @private\n */\nvjs.TextTrack.prototype.cues_;\n\n/**\n * Get the track cues\n * @return {Array}\n */\nvjs.TextTrack.prototype.cues = function(){\n  return this.cues_;\n};\n\n/**\n * ActiveCues is all cues that are currently showing\n * Spec def: readonly attribute TextTrackCueList activeCues;\n * @private\n */\nvjs.TextTrack.prototype.activeCues_;\n\n/**\n * Get the track active cues\n * @return {Array}\n */\nvjs.TextTrack.prototype.activeCues = function(){\n  return this.activeCues_;\n};\n\n/**\n * ReadyState describes if the text file has been loaded\n * const unsigned short NONE = 0;\n * const unsigned short LOADING = 1;\n * const unsigned short LOADED = 2;\n * const unsigned short ERROR = 3;\n * readonly attribute unsigned short readyState;\n * @private\n */\nvjs.TextTrack.prototype.readyState_;\n\n/**\n * Get the track readyState\n * @return {Number}\n */\nvjs.TextTrack.prototype.readyState = function(){\n  return this.readyState_;\n};\n\n/**\n * Mode describes if the track is showing, hidden, or disabled\n * const unsigned short OFF = 0;\n * const unsigned short HIDDEN = 1; (still triggering cuechange events, but not visible)\n * const unsigned short SHOWING = 2;\n * attribute unsigned short mode;\n * @private\n */\nvjs.TextTrack.prototype.mode_;\n\n/**\n * Get the track mode\n * @return {Number}\n */\nvjs.TextTrack.prototype.mode = function(){\n  return this.mode_;\n};\n\n/**\n * Change the font size of the text track to make it larger when playing in fullscreen mode\n * and restore it to its normal size when not in fullscreen mode.\n */\nvjs.TextTrack.prototype.adjustFontSize = function(){\n    if (this.player_.isFullScreen) {\n        // Scale the font by the same factor as increasing the video width to the full screen window width.\n        // Additionally, multiply that factor by 1.4, which is the default font size for\n        // the caption track (from the CSS)\n        this.el_.style.fontSize = screen.width / this.player_.width() * 1.4 * 100 + '%';\n    } else {\n        // Change the font size of the text track back to its original non-fullscreen size\n        this.el_.style.fontSize = '';\n    }\n};\n\n/**\n * Create basic div to hold cue text\n * @return {Element}\n */\nvjs.TextTrack.prototype.createEl = function(){\n  return vjs.Component.prototype.createEl.call(this, 'div', {\n    className: 'vjs-' + this.kind_ + ' vjs-text-track'\n  });\n};\n\n/**\n * Show: Mode Showing (2)\n * Indicates that the text track is active. If no attempt has yet been made to obtain the track's cues, the user agent will perform such an attempt momentarily.\n * The user agent is maintaining a list of which cues are active, and events are being fired accordingly.\n * In addition, for text tracks whose kind is subtitles or captions, the cues are being displayed over the video as appropriate;\n * for text tracks whose kind is descriptions, the user agent is making the cues available to the user in a non-visual fashion;\n * and for text tracks whose kind is chapters, the user agent is making available to the user a mechanism by which the user can navigate to any point in the media resource by selecting a cue.\n * The showing by default state is used in conjunction with the default attribute on track elements to indicate that the text track was enabled due to that attribute.\n * This allows the user agent to override the state if a later track is discovered that is more appropriate per the user's preferences.\n */\nvjs.TextTrack.prototype.show = function(){\n  this.activate();\n\n  this.mode_ = 2;\n\n  // Show element.\n  vjs.Component.prototype.show.call(this);\n};\n\n/**\n * Hide: Mode Hidden (1)\n * Indicates that the text track is active, but that the user agent is not actively displaying the cues.\n * If no attempt has yet been made to obtain the track's cues, the user agent will perform such an attempt momentarily.\n * The user agent is maintaining a list of which cues are active, and events are being fired accordingly.\n */\nvjs.TextTrack.prototype.hide = function(){\n  // When hidden, cues are still triggered. Disable to stop triggering.\n  this.activate();\n\n  this.mode_ = 1;\n\n  // Hide element.\n  vjs.Component.prototype.hide.call(this);\n};\n\n/**\n * Disable: Mode Off/Disable (0)\n * Indicates that the text track is not active. Other than for the purposes of exposing the track in the DOM, the user agent is ignoring the text track.\n * No cues are active, no events are fired, and the user agent will not attempt to obtain the track's cues.\n */\nvjs.TextTrack.prototype.disable = function(){\n  // If showing, hide.\n  if (this.mode_ == 2) { this.hide(); }\n\n  // Stop triggering cues\n  this.deactivate();\n\n  // Switch Mode to Off\n  this.mode_ = 0;\n};\n\n/**\n * Turn on cue tracking. Tracks that are showing OR hidden are active.\n */\nvjs.TextTrack.prototype.activate = function(){\n  // Load text file if it hasn't been yet.\n  if (this.readyState_ === 0) { this.load(); }\n\n  // Only activate if not already active.\n  if (this.mode_ === 0) {\n    // Update current cue on timeupdate\n    // Using unique ID for bind function so other tracks don't remove listener\n    this.player_.on('timeupdate', vjs.bind(this, this.update, this.id_));\n\n    // Reset cue time on media end\n    this.player_.on('ended', vjs.bind(this, this.reset, this.id_));\n\n    // Add to display\n    if (this.kind_ === 'captions' || this.kind_ === 'subtitles') {\n      this.player_.getChild('textTrackDisplay').addChild(this);\n    }\n  }\n};\n\n/**\n * Turn off cue tracking.\n */\nvjs.TextTrack.prototype.deactivate = function(){\n  // Using unique ID for bind function so other tracks don't remove listener\n  this.player_.off('timeupdate', vjs.bind(this, this.update, this.id_));\n  this.player_.off('ended', vjs.bind(this, this.reset, this.id_));\n  this.reset(); // Reset\n\n  // Remove from display\n  this.player_.getChild('textTrackDisplay').removeChild(this);\n};\n\n// A readiness state\n// One of the following:\n//\n// Not loaded\n// Indicates that the text track is known to exist (e.g. it has been declared with a track element), but its cues have not been obtained.\n//\n// Loading\n// Indicates that the text track is loading and there have been no fatal errors encountered so far. Further cues might still be added to the track.\n//\n// Loaded\n// Indicates that the text track has been loaded with no fatal errors. No new cues will be added to the track except if the text track corresponds to a MutableTextTrack object.\n//\n// Failed to load\n// Indicates that the text track was enabled, but when the user agent attempted to obtain it, this failed in some way (e.g. URL could not be resolved, network error, unknown text track format). Some or all of the cues are likely missing and will not be obtained.\nvjs.TextTrack.prototype.load = function(){\n\n  // Only load if not loaded yet.\n  if (this.readyState_ === 0) {\n    this.readyState_ = 1;\n    vjs.get(this.src_, vjs.bind(this, this.parseCues), vjs.bind(this, this.onError));\n  }\n\n};\n\nvjs.TextTrack.prototype.onError = function(err){\n  this.error = err;\n  this.readyState_ = 3;\n  this.trigger('error');\n};\n\n// Parse the WebVTT text format for cue times.\n// TODO: Separate parser into own class so alternative timed text formats can be used. (TTML, DFXP)\nvjs.TextTrack.prototype.parseCues = function(srcContent) {\n  var cue, time, text,\n      lines = srcContent.split('\\n'),\n      line = '', id;\n\n  for (var i=1, j=lines.length; i<j; i++) {\n    // Line 0 should be 'WEBVTT', so skipping i=0\n\n    line = vjs.trim(lines[i]); // Trim whitespace and linebreaks\n\n    if (line) { // Loop until a line with content\n\n      // First line could be an optional cue ID\n      // Check if line has the time separator\n      if (line.indexOf('-->') == -1) {\n        id = line;\n        // Advance to next line for timing.\n        line = vjs.trim(lines[++i]);\n      } else {\n        id = this.cues_.length;\n      }\n\n      // First line - Number\n      cue = {\n        id: id, // Cue Number\n        index: this.cues_.length // Position in Array\n      };\n\n      // Timing line\n      time = line.split(' --> ');\n      cue.startTime = this.parseCueTime(time[0]);\n      cue.endTime = this.parseCueTime(time[1]);\n\n      // Additional lines - Cue Text\n      text = [];\n\n      // Loop until a blank line or end of lines\n      // Assumeing trim('') returns false for blank lines\n      while (lines[++i] && (line = vjs.trim(lines[i]))) {\n        text.push(line);\n      }\n\n      cue.text = text.join('<br/>');\n\n      // Add this cue\n      this.cues_.push(cue);\n    }\n  }\n\n  this.readyState_ = 2;\n  this.trigger('loaded');\n};\n\n\nvjs.TextTrack.prototype.parseCueTime = function(timeText) {\n  var parts = timeText.split(':'),\n      time = 0,\n      hours, minutes, other, seconds, ms;\n\n  // Check if optional hours place is included\n  // 00:00:00.000 vs. 00:00.000\n  if (parts.length == 3) {\n    hours = parts[0];\n    minutes = parts[1];\n    other = parts[2];\n  } else {\n    hours = 0;\n    minutes = parts[0];\n    other = parts[1];\n  }\n\n  // Break other (seconds, milliseconds, and flags) by spaces\n  // TODO: Make additional cue layout settings work with flags\n  other = other.split(/\\s+/);\n  // Remove seconds. Seconds is the first part before any spaces.\n  seconds = other.splice(0,1)[0];\n  // Could use either . or , for decimal\n  seconds = seconds.split(/\\.|,/);\n  // Get milliseconds\n  ms = parseFloat(seconds[1]);\n  seconds = seconds[0];\n\n  // hours => seconds\n  time += parseFloat(hours) * 3600;\n  // minutes => seconds\n  time += parseFloat(minutes) * 60;\n  // Add seconds\n  time += parseFloat(seconds);\n  // Add milliseconds\n  if (ms) { time += ms/1000; }\n\n  return time;\n};\n\n// Update active cues whenever timeupdate events are triggered on the player.\nvjs.TextTrack.prototype.update = function(){\n  if (this.cues_.length > 0) {\n\n    // Get curent player time\n    var time = this.player_.currentTime();\n\n    // Check if the new time is outside the time box created by the the last update.\n    if (this.prevChange === undefined || time < this.prevChange || this.nextChange <= time) {\n      var cues = this.cues_,\n\n          // Create a new time box for this state.\n          newNextChange = this.player_.duration(), // Start at beginning of the timeline\n          newPrevChange = 0, // Start at end\n\n          reverse = false, // Set the direction of the loop through the cues. Optimized the cue check.\n          newCues = [], // Store new active cues.\n\n          // Store where in the loop the current active cues are, to provide a smart starting point for the next loop.\n          firstActiveIndex, lastActiveIndex,\n          cue, i; // Loop vars\n\n      // Check if time is going forwards or backwards (scrubbing/rewinding)\n      // If we know the direction we can optimize the starting position and direction of the loop through the cues array.\n      if (time >= this.nextChange || this.nextChange === undefined) { // NextChange should happen\n        // Forwards, so start at the index of the first active cue and loop forward\n        i = (this.firstActiveIndex !== undefined) ? this.firstActiveIndex : 0;\n      } else {\n        // Backwards, so start at the index of the last active cue and loop backward\n        reverse = true;\n        i = (this.lastActiveIndex !== undefined) ? this.lastActiveIndex : cues.length - 1;\n      }\n\n      while (true) { // Loop until broken\n        cue = cues[i];\n\n        // Cue ended at this point\n        if (cue.endTime <= time) {\n          newPrevChange = Math.max(newPrevChange, cue.endTime);\n\n          if (cue.active) {\n            cue.active = false;\n          }\n\n          // No earlier cues should have an active start time.\n          // Nevermind. Assume first cue could have a duration the same as the video.\n          // In that case we need to loop all the way back to the beginning.\n          // if (reverse && cue.startTime) { break; }\n\n        // Cue hasn't started\n        } else if (time < cue.startTime) {\n          newNextChange = Math.min(newNextChange, cue.startTime);\n\n          if (cue.active) {\n            cue.active = false;\n          }\n\n          // No later cues should have an active start time.\n          if (!reverse) { break; }\n\n        // Cue is current\n        } else {\n\n          if (reverse) {\n            // Add cue to front of array to keep in time order\n            newCues.splice(0,0,cue);\n\n            // If in reverse, the first current cue is our lastActiveCue\n            if (lastActiveIndex === undefined) { lastActiveIndex = i; }\n            firstActiveIndex = i;\n          } else {\n            // Add cue to end of array\n            newCues.push(cue);\n\n            // If forward, the first current cue is our firstActiveIndex\n            if (firstActiveIndex === undefined) { firstActiveIndex = i; }\n            lastActiveIndex = i;\n          }\n\n          newNextChange = Math.min(newNextChange, cue.endTime);\n          newPrevChange = Math.max(newPrevChange, cue.startTime);\n\n          cue.active = true;\n        }\n\n        if (reverse) {\n          // Reverse down the array of cues, break if at first\n          if (i === 0) { break; } else { i--; }\n        } else {\n          // Walk up the array fo cues, break if at last\n          if (i === cues.length - 1) { break; } else { i++; }\n        }\n\n      }\n\n      this.activeCues_ = newCues;\n      this.nextChange = newNextChange;\n      this.prevChange = newPrevChange;\n      this.firstActiveIndex = firstActiveIndex;\n      this.lastActiveIndex = lastActiveIndex;\n\n      this.updateDisplay();\n\n      this.trigger('cuechange');\n    }\n  }\n};\n\n// Add cue HTML to display\nvjs.TextTrack.prototype.updateDisplay = function(){\n  var cues = this.activeCues_,\n      html = '',\n      i=0,j=cues.length;\n\n  for (;i<j;i++) {\n    html += '<span class=\"vjs-tt-cue\">'+cues[i].text+'</span>';\n  }\n\n  this.el_.innerHTML = html;\n};\n\n// Set all loop helper values back\nvjs.TextTrack.prototype.reset = function(){\n  this.nextChange = 0;\n  this.prevChange = this.player_.duration();\n  this.firstActiveIndex = 0;\n  this.lastActiveIndex = 0;\n};\n\n// Create specific track types\n/**\n * The track component for managing the hiding and showing of captions\n *\n * @constructor\n */\nvjs.CaptionsTrack = vjs.TextTrack.extend();\nvjs.CaptionsTrack.prototype.kind_ = 'captions';\n// Exporting here because Track creation requires the track kind\n// to be available on global object. e.g. new window['videojs'][Kind + 'Track']\n\n/**\n * The track component for managing the hiding and showing of subtitles\n *\n * @constructor\n */\nvjs.SubtitlesTrack = vjs.TextTrack.extend();\nvjs.SubtitlesTrack.prototype.kind_ = 'subtitles';\n\n/**\n * The track component for managing the hiding and showing of chapters\n *\n * @constructor\n */\nvjs.ChaptersTrack = vjs.TextTrack.extend();\nvjs.ChaptersTrack.prototype.kind_ = 'chapters';\n\n\n/* Text Track Display\n============================================================================= */\n// Global container for both subtitle and captions text. Simple div container.\n\n/**\n * The component for displaying text track cues\n *\n * @constructor\n */\nvjs.TextTrackDisplay = vjs.Component.extend({\n  /** @constructor */\n  init: function(player, options, ready){\n    vjs.Component.call(this, player, options, ready);\n\n    // This used to be called during player init, but was causing an error\n    // if a track should show by default and the display hadn't loaded yet.\n    // Should probably be moved to an external track loader when we support\n    // tracks that don't need a display.\n    if (player.options_['tracks'] && player.options_['tracks'].length > 0) {\n      this.player_.addTextTracks(player.options_['tracks']);\n    }\n  }\n});\n\nvjs.TextTrackDisplay.prototype.createEl = function(){\n  return vjs.Component.prototype.createEl.call(this, 'div', {\n    className: 'vjs-text-track-display'\n  });\n};\n\n\n/**\n * The specific menu item type for selecting a language within a text track kind\n *\n * @constructor\n */\nvjs.TextTrackMenuItem = vjs.MenuItem.extend({\n  /** @constructor */\n  init: function(player, options){\n    var track = this.track = options['track'];\n\n    // Modify options for parent MenuItem class's init.\n    options['label'] = track.label();\n    options['selected'] = track.dflt();\n    vjs.MenuItem.call(this, player, options);\n\n    this.player_.on(track.kind() + 'trackchange', vjs.bind(this, this.update));\n  }\n});\n\nvjs.TextTrackMenuItem.prototype.onClick = function(){\n  vjs.MenuItem.prototype.onClick.call(this);\n  this.player_.showTextTrack(this.track.id_, this.track.kind());\n};\n\nvjs.TextTrackMenuItem.prototype.update = function(){\n  this.selected(this.track.mode() == 2);\n};\n\n/**\n * A special menu item for turning of a specific type of text track\n *\n * @constructor\n */\nvjs.OffTextTrackMenuItem = vjs.TextTrackMenuItem.extend({\n  /** @constructor */\n  init: function(player, options){\n    // Create pseudo track info\n    // Requires options['kind']\n    options['track'] = {\n      kind: function() { return options['kind']; },\n      player: player,\n      label: function(){ return options['kind'] + ' off'; },\n      dflt: function(){ return false; },\n      mode: function(){ return false; }\n    };\n    vjs.TextTrackMenuItem.call(this, player, options);\n    this.selected(true);\n  }\n});\n\nvjs.OffTextTrackMenuItem.prototype.onClick = function(){\n  vjs.TextTrackMenuItem.prototype.onClick.call(this);\n  this.player_.showTextTrack(this.track.id_, this.track.kind());\n};\n\nvjs.OffTextTrackMenuItem.prototype.update = function(){\n  var tracks = this.player_.textTracks(),\n      i=0, j=tracks.length, track,\n      off = true;\n\n  for (;i<j;i++) {\n    track = tracks[i];\n    if (track.kind() == this.track.kind() && track.mode() == 2) {\n      off = false;\n    }\n  }\n\n  this.selected(off);\n};\n\n/**\n * The base class for buttons that toggle specific text track types (e.g. subtitles)\n *\n * @constructor\n */\nvjs.TextTrackButton = vjs.MenuButton.extend({\n  /** @constructor */\n  init: function(player, options){\n    vjs.MenuButton.call(this, player, options);\n\n    if (this.items.length <= 1) {\n      this.hide();\n    }\n  }\n});\n\n// vjs.TextTrackButton.prototype.buttonPressed = false;\n\n// vjs.TextTrackButton.prototype.createMenu = function(){\n//   var menu = new vjs.Menu(this.player_);\n\n//   // Add a title list item to the top\n//   // menu.el().appendChild(vjs.createEl('li', {\n//   //   className: 'vjs-menu-title',\n//   //   innerHTML: vjs.capitalize(this.kind_),\n//   //   tabindex: -1\n//   // }));\n\n//   this.items = this.createItems();\n\n//   // Add menu items to the menu\n//   for (var i = 0; i < this.items.length; i++) {\n//     menu.addItem(this.items[i]);\n//   }\n\n//   // Add list to element\n//   this.addChild(menu);\n\n//   return menu;\n// };\n\n// Create a menu item for each text track\nvjs.TextTrackButton.prototype.createItems = function(){\n  var items = [], track;\n\n  // Add an OFF menu item to turn all tracks off\n  items.push(new vjs.OffTextTrackMenuItem(this.player_, { 'kind': this.kind_ }));\n\n  for (var i = 0; i < this.player_.textTracks().length; i++) {\n    track = this.player_.textTracks()[i];\n    if (track.kind() === this.kind_) {\n      items.push(new vjs.TextTrackMenuItem(this.player_, {\n        'track': track\n      }));\n    }\n  }\n\n  return items;\n};\n\n/**\n * The button component for toggling and selecting captions\n *\n * @constructor\n */\nvjs.CaptionsButton = vjs.TextTrackButton.extend({\n  /** @constructor */\n  init: function(player, options, ready){\n    vjs.TextTrackButton.call(this, player, options, ready);\n    this.el_.setAttribute('aria-label','Captions Menu');\n  }\n});\nvjs.CaptionsButton.prototype.kind_ = 'captions';\nvjs.CaptionsButton.prototype.buttonText = 'Captions';\nvjs.CaptionsButton.prototype.className = 'vjs-captions-button';\n\n/**\n * The button component for toggling and selecting subtitles\n *\n * @constructor\n */\nvjs.SubtitlesButton = vjs.TextTrackButton.extend({\n  /** @constructor */\n  init: function(player, options, ready){\n    vjs.TextTrackButton.call(this, player, options, ready);\n    this.el_.setAttribute('aria-label','Subtitles Menu');\n  }\n});\nvjs.SubtitlesButton.prototype.kind_ = 'subtitles';\nvjs.SubtitlesButton.prototype.buttonText = 'Subtitles';\nvjs.SubtitlesButton.prototype.className = 'vjs-subtitles-button';\n\n// Chapters act much differently than other text tracks\n// Cues are navigation vs. other tracks of alternative languages\n/**\n * The button component for toggling and selecting chapters\n *\n * @constructor\n */\nvjs.ChaptersButton = vjs.TextTrackButton.extend({\n  /** @constructor */\n  init: function(player, options, ready){\n    vjs.TextTrackButton.call(this, player, options, ready);\n    this.el_.setAttribute('aria-label','Chapters Menu');\n  }\n});\nvjs.ChaptersButton.prototype.kind_ = 'chapters';\nvjs.ChaptersButton.prototype.buttonText = 'Chapters';\nvjs.ChaptersButton.prototype.className = 'vjs-chapters-button';\n\n// Create a menu item for each text track\nvjs.ChaptersButton.prototype.createItems = function(){\n  var items = [], track;\n\n  for (var i = 0; i < this.player_.textTracks().length; i++) {\n    track = this.player_.textTracks()[i];\n    if (track.kind() === this.kind_) {\n      items.push(new vjs.TextTrackMenuItem(this.player_, {\n        'track': track\n      }));\n    }\n  }\n\n  return items;\n};\n\nvjs.ChaptersButton.prototype.createMenu = function(){\n  var tracks = this.player_.textTracks(),\n      i = 0,\n      j = tracks.length,\n      track, chaptersTrack,\n      items = this.items = [];\n\n  for (;i<j;i++) {\n    track = tracks[i];\n    if (track.kind() == this.kind_ && track.dflt()) {\n      if (track.readyState() < 2) {\n        this.chaptersTrack = track;\n        track.on('loaded', vjs.bind(this, this.createMenu));\n        return;\n      } else {\n        chaptersTrack = track;\n        break;\n      }\n    }\n  }\n\n  var menu = this.menu = new vjs.Menu(this.player_);\n\n  menu.el_.appendChild(vjs.createEl('li', {\n    className: 'vjs-menu-title',\n    innerHTML: vjs.capitalize(this.kind_),\n    tabindex: -1\n  }));\n\n  if (chaptersTrack) {\n    var cues = chaptersTrack.cues_, cue, mi;\n    i = 0;\n    j = cues.length;\n\n    for (;i<j;i++) {\n      cue = cues[i];\n\n      mi = new vjs.ChaptersTrackMenuItem(this.player_, {\n        'track': chaptersTrack,\n        'cue': cue\n      });\n\n      items.push(mi);\n\n      menu.addChild(mi);\n    }\n  }\n\n  if (this.items.length > 0) {\n    this.show();\n  }\n\n  return menu;\n};\n\n\n/**\n * @constructor\n */\nvjs.ChaptersTrackMenuItem = vjs.MenuItem.extend({\n  /** @constructor */\n  init: function(player, options){\n    var track = this.track = options['track'],\n        cue = this.cue = options['cue'],\n        currentTime = player.currentTime();\n\n    // Modify options for parent MenuItem class's init.\n    options['label'] = cue.text;\n    options['selected'] = (cue.startTime <= currentTime && currentTime < cue.endTime);\n    vjs.MenuItem.call(this, player, options);\n\n    track.on('cuechange', vjs.bind(this, this.update));\n  }\n});\n\nvjs.ChaptersTrackMenuItem.prototype.onClick = function(){\n  vjs.MenuItem.prototype.onClick.call(this);\n  this.player_.currentTime(this.cue.startTime);\n  this.update(this.cue.startTime);\n};\n\nvjs.ChaptersTrackMenuItem.prototype.update = function(){\n  var cue = this.cue,\n      currentTime = this.player_.currentTime();\n\n  // vjs.log(currentTime, cue.startTime);\n  this.selected(cue.startTime <= currentTime && currentTime < cue.endTime);\n};\n\n// Add Buttons to controlBar\nvjs.obj.merge(vjs.ControlBar.prototype.options_['children'], {\n  'subtitlesButton': {},\n  'captionsButton': {},\n  'chaptersButton': {}\n});\n\n// vjs.Cue = vjs.Component.extend({\n//   /** @constructor */\n//   init: function(player, options){\n//     vjs.Component.call(this, player, options);\n//   }\n// });\n/**\n * @fileoverview Add JSON support\n * @suppress {undefinedVars}\n * (Compiler doesn't like JSON not being declared)\n */\n\n/**\n * Javascript JSON implementation\n * (Parse Method Only)\n * https://github.com/douglascrockford/JSON-js/blob/master/json2.js\n * Only using for parse method when parsing data-setup attribute JSON.\n * @suppress {undefinedVars}\n * @namespace\n * @private\n */\nvjs.JSON;\n\nif (typeof window.JSON !== 'undefined' && window.JSON.parse === 'function') {\n  vjs.JSON = window.JSON;\n\n} else {\n  vjs.JSON = {};\n\n  var cx = /[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g;\n\n  /**\n   * parse the json\n   *\n   * @memberof vjs.JSON\n   * @return {Object|Array} The parsed JSON\n   */\n  vjs.JSON.parse = function (text, reviver) {\n      var j;\n\n      function walk(holder, key) {\n          var k, v, value = holder[key];\n          if (value && typeof value === 'object') {\n              for (k in value) {\n                  if (Object.prototype.hasOwnProperty.call(value, k)) {\n                      v = walk(value, k);\n                      if (v !== undefined) {\n                          value[k] = v;\n                      } else {\n                          delete value[k];\n                      }\n                  }\n              }\n          }\n          return reviver.call(holder, key, value);\n      }\n      text = String(text);\n      cx.lastIndex = 0;\n      if (cx.test(text)) {\n          text = text.replace(cx, function (a) {\n              return '\\\\u' +\n                  ('0000' + a.charCodeAt(0).toString(16)).slice(-4);\n          });\n      }\n\n      if (/^[\\],:{}\\s]*$/\n              .test(text.replace(/\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@')\n                  .replace(/\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g, ']')\n                  .replace(/(?:^|:|,)(?:\\s*\\[)+/g, ''))) {\n\n          j = eval('(' + text + ')');\n\n          return typeof reviver === 'function' ?\n              walk({'': j}, '') : j;\n      }\n\n      throw new SyntaxError('JSON.parse(): invalid or malformed JSON data');\n  };\n}\n/**\n * @fileoverview Functions for automatically setting up a player\n * based on the data-setup attribute of the video tag\n */\n\n// Automatically set up any tags that have a data-setup attribute\nvjs.autoSetup = function(){\n  var options, vid, player,\n      vids = document.getElementsByTagName('video');\n\n  // Check if any media elements exist\n  if (vids && vids.length > 0) {\n\n    for (var i=0,j=vids.length; i<j; i++) {\n      vid = vids[i];\n\n      // Check if element exists, has getAttribute func.\n      // IE seems to consider typeof el.getAttribute == 'object' instead of 'function' like expected, at least when loading the player immediately.\n      if (vid && vid.getAttribute) {\n\n        // Make sure this player hasn't already been set up.\n        if (vid['player'] === undefined) {\n          options = vid.getAttribute('data-setup');\n\n          // Check if data-setup attr exists.\n          // We only auto-setup if they've added the data-setup attr.\n          if (options !== null) {\n\n            // Parse options JSON\n            // If empty string, make it a parsable json object.\n            options = vjs.JSON.parse(options || '{}');\n\n            // Create new video.js instance.\n            player = videojs(vid, options);\n          }\n        }\n\n      // If getAttribute isn't defined, we need to wait for the DOM.\n      } else {\n        vjs.autoSetupTimeout(1);\n        break;\n      }\n    }\n\n  // No videos were found, so keep looping unless page is finisehd loading.\n  } else if (!vjs.windowLoaded) {\n    vjs.autoSetupTimeout(1);\n  }\n};\n\n// Pause to let the DOM keep processing\nvjs.autoSetupTimeout = function(wait){\n  setTimeout(vjs.autoSetup, wait);\n};\n\nif (document.readyState === 'complete') {\n  vjs.windowLoaded = true;\n} else {\n  vjs.one(window, 'load', function(){\n    vjs.windowLoaded = true;\n  });\n}\n\n// Run Auto-load players\n// You have to wait at least once in case this script is loaded after your video in the DOM (weird behavior only with minified version)\nvjs.autoSetupTimeout(1);\n/**\n * the method for registering a video.js plugin\n *\n * @param  {String} name The name of the plugin\n * @param  {Function} init The function that is run when the player inits\n */\nvjs.plugin = function(name, init){\n  vjs.Player.prototype[name] = init;\n};\n"
  },
  {
    "path": "public/static/ueditor/third-party/video-js/video.js",
    "content": "/*! Video.js v4.3.0 Copyright 2013 Brightcove, Inc. https://github.com/videojs/video.js/blob/master/LICENSE */ (function() {var b=void 0,f=!0,h=null,l=!1;function m(){return function(){}}function p(a){return function(){return this[a]}}function s(a){return function(){return a}}var t;document.createElement(\"video\");document.createElement(\"audio\");document.createElement(\"track\");function u(a,c,d){if(\"string\"===typeof a){0===a.indexOf(\"#\")&&(a=a.slice(1));if(u.xa[a])return u.xa[a];a=u.w(a)}if(!a||!a.nodeName)throw new TypeError(\"The element or ID supplied is not valid. (videojs)\");return a.player||new u.s(a,c,d)}var v=u;\nwindow.Td=window.Ud=u;u.Tb=\"4.3\";u.Fc=\"https:\"==document.location.protocol?\"https://\":\"http://\";u.options={techOrder:[\"html5\",\"flash\"],html5:{},flash:{},width:300,height:150,defaultVolume:0,children:{mediaLoader:{},posterImage:{},textTrackDisplay:{},loadingSpinner:{},bigPlayButton:{},controlBar:{}},notSupportedMessage:'Sorry, no compatible source and playback technology were found for this video. Try using another browser like <a href=\"http://bit.ly/ccMUEC\">Chrome</a> or download the latest <a href=\"http://adobe.ly/mwfN1\">Adobe Flash Player</a>.'};\n\"GENERATED_CDN_VSN\"!==u.Tb&&(v.options.flash.swf=u.Fc+\"vjs.zencdn.net/\"+u.Tb+\"/video-js.swf\");u.xa={};u.la=u.CoreObject=m();u.la.extend=function(a){var c,d;a=a||{};c=a.init||a.i||this.prototype.init||this.prototype.i||m();d=function(){c.apply(this,arguments)};d.prototype=u.k.create(this.prototype);d.prototype.constructor=d;d.extend=u.la.extend;d.create=u.la.create;for(var e in a)a.hasOwnProperty(e)&&(d.prototype[e]=a[e]);return d};\nu.la.create=function(){var a=u.k.create(this.prototype);this.apply(a,arguments);return a};u.d=function(a,c,d){var e=u.getData(a);e.z||(e.z={});e.z[c]||(e.z[c]=[]);d.t||(d.t=u.t++);e.z[c].push(d);e.W||(e.disabled=l,e.W=function(c){if(!e.disabled){c=u.kc(c);var d=e.z[c.type];if(d)for(var d=d.slice(0),k=0,q=d.length;k<q&&!c.pc();k++)d[k].call(a,c)}});1==e.z[c].length&&(document.addEventListener?a.addEventListener(c,e.W,l):document.attachEvent&&a.attachEvent(\"on\"+c,e.W))};\nu.o=function(a,c,d){if(u.oc(a)){var e=u.getData(a);if(e.z)if(c){var g=e.z[c];if(g){if(d){if(d.t)for(e=0;e<g.length;e++)g[e].t===d.t&&g.splice(e--,1)}else e.z[c]=[];u.gc(a,c)}}else for(g in e.z)c=g,e.z[c]=[],u.gc(a,c)}};u.gc=function(a,c){var d=u.getData(a);0===d.z[c].length&&(delete d.z[c],document.removeEventListener?a.removeEventListener(c,d.W,l):document.detachEvent&&a.detachEvent(\"on\"+c,d.W));u.Bb(d.z)&&(delete d.z,delete d.W,delete d.disabled);u.Bb(d)&&u.vc(a)};\nu.kc=function(a){function c(){return f}function d(){return l}if(!a||!a.Cb){var e=a||window.event;a={};for(var g in e)\"layerX\"!==g&&\"layerY\"!==g&&(a[g]=e[g]);a.target||(a.target=a.srcElement||document);a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement;a.preventDefault=function(){e.preventDefault&&e.preventDefault();a.returnValue=l;a.Ab=c};a.Ab=d;a.stopPropagation=function(){e.stopPropagation&&e.stopPropagation();a.cancelBubble=f;a.Cb=c};a.Cb=d;a.stopImmediatePropagation=function(){e.stopImmediatePropagation&&\ne.stopImmediatePropagation();a.pc=c;a.stopPropagation()};a.pc=d;if(a.clientX!=h){g=document.documentElement;var j=document.body;a.pageX=a.clientX+(g&&g.scrollLeft||j&&j.scrollLeft||0)-(g&&g.clientLeft||j&&j.clientLeft||0);a.pageY=a.clientY+(g&&g.scrollTop||j&&j.scrollTop||0)-(g&&g.clientTop||j&&j.clientTop||0)}a.which=a.charCode||a.keyCode;a.button!=h&&(a.button=a.button&1?0:a.button&4?1:a.button&2?2:0)}return a};\nu.j=function(a,c){var d=u.oc(a)?u.getData(a):{},e=a.parentNode||a.ownerDocument;\"string\"===typeof c&&(c={type:c,target:a});c=u.kc(c);d.W&&d.W.call(a,c);if(e&&!c.Cb()&&c.bubbles!==l)u.j(e,c);else if(!e&&!c.Ab()&&(d=u.getData(c.target),c.target[c.type])){d.disabled=f;if(\"function\"===typeof c.target[c.type])c.target[c.type]();d.disabled=l}return!c.Ab()};u.U=function(a,c,d){function e(){u.o(a,c,e);d.apply(this,arguments)}e.t=d.t=d.t||u.t++;u.d(a,c,e)};var w=Object.prototype.hasOwnProperty;\nu.e=function(a,c){var d,e;d=document.createElement(a||\"div\");for(e in c)w.call(c,e)&&(-1!==e.indexOf(\"aria-\")||\"role\"==e?d.setAttribute(e,c[e]):d[e]=c[e]);return d};u.$=function(a){return a.charAt(0).toUpperCase()+a.slice(1)};u.k={};u.k.create=Object.create||function(a){function c(){}c.prototype=a;return new c};u.k.ua=function(a,c,d){for(var e in a)w.call(a,e)&&c.call(d||this,e,a[e])};u.k.B=function(a,c){if(!c)return a;for(var d in c)w.call(c,d)&&(a[d]=c[d]);return a};\nu.k.ic=function(a,c){var d,e,g;a=u.k.copy(a);for(d in c)w.call(c,d)&&(e=a[d],g=c[d],a[d]=u.k.qc(e)&&u.k.qc(g)?u.k.ic(e,g):c[d]);return a};u.k.copy=function(a){return u.k.B({},a)};u.k.qc=function(a){return!!a&&\"object\"===typeof a&&\"[object Object]\"===a.toString()&&a.constructor===Object};u.bind=function(a,c,d){function e(){return c.apply(a,arguments)}c.t||(c.t=u.t++);e.t=d?d+\"_\"+c.t:c.t;return e};u.ra={};u.t=1;u.expando=\"vdata\"+(new Date).getTime();\nu.getData=function(a){var c=a[u.expando];c||(c=a[u.expando]=u.t++,u.ra[c]={});return u.ra[c]};u.oc=function(a){a=a[u.expando];return!(!a||u.Bb(u.ra[a]))};u.vc=function(a){var c=a[u.expando];if(c){delete u.ra[c];try{delete a[u.expando]}catch(d){a.removeAttribute?a.removeAttribute(u.expando):a[u.expando]=h}}};u.Bb=function(a){for(var c in a)if(a[c]!==h)return l;return f};u.n=function(a,c){-1==(\" \"+a.className+\" \").indexOf(\" \"+c+\" \")&&(a.className=\"\"===a.className?c:a.className+\" \"+c)};\nu.u=function(a,c){var d,e;if(-1!=a.className.indexOf(c)){d=a.className.split(\" \");for(e=d.length-1;0<=e;e--)d[e]===c&&d.splice(e,1);a.className=d.join(\" \")}};u.na=u.e(\"video\");u.F=navigator.userAgent;u.Mc=/iPhone/i.test(u.F);u.Lc=/iPad/i.test(u.F);u.Nc=/iPod/i.test(u.F);u.Kc=u.Mc||u.Lc||u.Nc;var aa=u,x;var y=u.F.match(/OS (\\d+)_/i);x=y&&y[1]?y[1]:b;aa.Fd=x;u.Ic=/Android/i.test(u.F);var ba=u,z;var A=u.F.match(/Android (\\d+)(?:\\.(\\d+))?(?:\\.(\\d+))*/i),B,C;\nA?(B=A[1]&&parseFloat(A[1]),C=A[2]&&parseFloat(A[2]),z=B&&C?parseFloat(A[1]+\".\"+A[2]):B?B:h):z=h;ba.Gc=z;u.Oc=u.Ic&&/webkit/i.test(u.F)&&2.3>u.Gc;u.Jc=/Firefox/i.test(u.F);u.Gd=/Chrome/i.test(u.F);u.ac=!!(\"ontouchstart\"in window||window.Hc&&document instanceof window.Hc);\nu.xb=function(a){var c,d,e,g;c={};if(a&&a.attributes&&0<a.attributes.length){d=a.attributes;for(var j=d.length-1;0<=j;j--){e=d[j].name;g=d[j].value;if(\"boolean\"===typeof a[e]||-1!==\",autoplay,controls,loop,muted,default,\".indexOf(\",\"+e+\",\"))g=g!==h?f:l;c[e]=g}}return c};\nu.Kd=function(a,c){var d=\"\";document.defaultView&&document.defaultView.getComputedStyle?d=document.defaultView.getComputedStyle(a,\"\").getPropertyValue(c):a.currentStyle&&(d=a[\"client\"+c.substr(0,1).toUpperCase()+c.substr(1)]+\"px\");return d};u.zb=function(a,c){c.firstChild?c.insertBefore(a,c.firstChild):c.appendChild(a)};u.Pb={};u.w=function(a){0===a.indexOf(\"#\")&&(a=a.slice(1));return document.getElementById(a)};\nu.La=function(a,c){c=c||a;var d=Math.floor(a%60),e=Math.floor(a/60%60),g=Math.floor(a/3600),j=Math.floor(c/60%60),k=Math.floor(c/3600);if(isNaN(a)||Infinity===a)g=e=d=\"-\";g=0<g||0<k?g+\":\":\"\";return g+(((g||10<=j)&&10>e?\"0\"+e:e)+\":\")+(10>d?\"0\"+d:d)};u.Tc=function(){document.body.focus();document.onselectstart=s(l)};u.Bd=function(){document.onselectstart=s(f)};u.trim=function(a){return(a+\"\").replace(/^\\s+|\\s+$/g,\"\")};u.round=function(a,c){c||(c=0);return Math.round(a*Math.pow(10,c))/Math.pow(10,c)};\nu.tb=function(a,c){return{length:1,start:function(){return a},end:function(){return c}}};\nu.get=function(a,c,d){var e,g;\"undefined\"===typeof XMLHttpRequest&&(window.XMLHttpRequest=function(){try{return new window.ActiveXObject(\"Msxml2.XMLHTTP.6.0\")}catch(a){}try{return new window.ActiveXObject(\"Msxml2.XMLHTTP.3.0\")}catch(c){}try{return new window.ActiveXObject(\"Msxml2.XMLHTTP\")}catch(d){}throw Error(\"This browser does not support XMLHttpRequest.\");});g=new XMLHttpRequest;try{g.open(\"GET\",a)}catch(j){d(j)}e=0===a.indexOf(\"file:\")||0===window.location.href.indexOf(\"file:\")&&-1===a.indexOf(\"http\");\ng.onreadystatechange=function(){4===g.readyState&&(200===g.status||e&&0===g.status?c(g.responseText):d&&d())};try{g.send()}catch(k){d&&d(k)}};u.td=function(a){try{var c=window.localStorage||l;c&&(c.volume=a)}catch(d){22==d.code||1014==d.code?u.log(\"LocalStorage Full (VideoJS)\",d):18==d.code?u.log(\"LocalStorage not allowed (VideoJS)\",d):u.log(\"LocalStorage Error (VideoJS)\",d)}};u.mc=function(a){a.match(/^https?:\\/\\//)||(a=u.e(\"div\",{innerHTML:'<a href=\"'+a+'\">x</a>'}).firstChild.href);return a};\nu.log=function(){u.log.history=u.log.history||[];u.log.history.push(arguments);window.console&&window.console.log(Array.prototype.slice.call(arguments))};u.ad=function(a){var c,d;a.getBoundingClientRect&&a.parentNode&&(c=a.getBoundingClientRect());if(!c)return{left:0,top:0};a=document.documentElement;d=document.body;return{left:c.left+(window.pageXOffset||d.scrollLeft)-(a.clientLeft||d.clientLeft||0),top:c.top+(window.pageYOffset||d.scrollTop)-(a.clientTop||d.clientTop||0)}};\nu.c=u.la.extend({i:function(a,c,d){this.b=a;this.g=u.k.copy(this.g);c=this.options(c);this.Q=c.id||(c.el&&c.el.id?c.el.id:a.id()+\"_component_\"+u.t++);this.gd=c.name||h;this.a=c.el||this.e();this.G=[];this.qb={};this.V={};if((a=this.g)&&a.children){var e=this;u.k.ua(a.children,function(a,c){c!==l&&!c.loadEvent&&(e[a]=e.Z(a,c))})}this.L(d)}});t=u.c.prototype;\nt.D=function(){this.j(\"dispose\");if(this.G)for(var a=this.G.length-1;0<=a;a--)this.G[a].D&&this.G[a].D();this.V=this.qb=this.G=h;this.o();this.a.parentNode&&this.a.parentNode.removeChild(this.a);u.vc(this.a);this.a=h};t.b=f;t.K=p(\"b\");t.options=function(a){return a===b?this.g:this.g=u.k.ic(this.g,a)};t.e=function(a,c){return u.e(a,c)};t.w=p(\"a\");t.id=p(\"Q\");t.name=p(\"gd\");t.children=p(\"G\");\nt.Z=function(a,c){var d,e;\"string\"===typeof a?(e=a,c=c||{},d=c.componentClass||u.$(e),c.name=e,d=new window.videojs[d](this.b||this,c)):d=a;this.G.push(d);\"function\"===typeof d.id&&(this.qb[d.id()]=d);(e=e||d.name&&d.name())&&(this.V[e]=d);\"function\"===typeof d.el&&d.el()&&(this.sa||this.a).appendChild(d.el());return d};\nt.removeChild=function(a){\"string\"===typeof a&&(a=this.V[a]);if(a&&this.G){for(var c=l,d=this.G.length-1;0<=d;d--)if(this.G[d]===a){c=f;this.G.splice(d,1);break}c&&(this.qb[a.id]=h,this.V[a.name]=h,(c=a.w())&&c.parentNode===(this.sa||this.a)&&(this.sa||this.a).removeChild(a.w()))}};t.T=s(\"\");t.d=function(a,c){u.d(this.a,a,u.bind(this,c));return this};t.o=function(a,c){u.o(this.a,a,c);return this};t.U=function(a,c){u.U(this.a,a,u.bind(this,c));return this};t.j=function(a,c){u.j(this.a,a,c);return this};\nt.L=function(a){a&&(this.aa?a.call(this):(this.Sa===b&&(this.Sa=[]),this.Sa.push(a)));return this};t.Ua=function(){this.aa=f;var a=this.Sa;if(a&&0<a.length){for(var c=0,d=a.length;c<d;c++)a[c].call(this);this.Sa=[];this.j(\"ready\")}};t.n=function(a){u.n(this.a,a);return this};t.u=function(a){u.u(this.a,a);return this};t.show=function(){this.a.style.display=\"block\";return this};t.C=function(){this.a.style.display=\"none\";return this};function D(a){a.u(\"vjs-lock-showing\")}\nt.disable=function(){this.C();this.show=m()};t.width=function(a,c){return E(this,\"width\",a,c)};t.height=function(a,c){return E(this,\"height\",a,c)};t.Xc=function(a,c){return this.width(a,f).height(c)};function E(a,c,d,e){if(d!==b)return a.a.style[c]=-1!==(\"\"+d).indexOf(\"%\")||-1!==(\"\"+d).indexOf(\"px\")?d:\"auto\"===d?\"\":d+\"px\",e||a.j(\"resize\"),a;if(!a.a)return 0;d=a.a.style[c];e=d.indexOf(\"px\");return-1!==e?parseInt(d.slice(0,e),10):parseInt(a.a[\"offset\"+u.$(c)],10)}\nu.q=u.c.extend({i:function(a,c){u.c.call(this,a,c);var d=l;this.d(\"touchstart\",function(a){a.preventDefault();d=f});this.d(\"touchmove\",function(){d=l});var e=this;this.d(\"touchend\",function(a){d&&e.p(a);a.preventDefault()});this.d(\"click\",this.p);this.d(\"focus\",this.Oa);this.d(\"blur\",this.Na)}});t=u.q.prototype;\nt.e=function(a,c){c=u.k.B({className:this.T(),innerHTML:'<div class=\"vjs-control-content\"><span class=\"vjs-control-text\">'+(this.qa||\"Need Text\")+\"</span></div>\",qd:\"button\",\"aria-live\":\"polite\",tabIndex:0},c);return u.c.prototype.e.call(this,a,c)};t.T=function(){return\"vjs-control \"+u.c.prototype.T.call(this)};t.p=m();t.Oa=function(){u.d(document,\"keyup\",u.bind(this,this.ba))};t.ba=function(a){if(32==a.which||13==a.which)a.preventDefault(),this.p()};\nt.Na=function(){u.o(document,\"keyup\",u.bind(this,this.ba))};u.O=u.c.extend({i:function(a,c){u.c.call(this,a,c);this.Sc=this.V[this.g.barName];this.handle=this.V[this.g.handleName];a.d(this.tc,u.bind(this,this.update));this.d(\"mousedown\",this.Pa);this.d(\"touchstart\",this.Pa);this.d(\"focus\",this.Oa);this.d(\"blur\",this.Na);this.d(\"click\",this.p);this.b.d(\"controlsvisible\",u.bind(this,this.update));a.L(u.bind(this,this.update));this.P={}}});t=u.O.prototype;\nt.e=function(a,c){c=c||{};c.className+=\" vjs-slider\";c=u.k.B({qd:\"slider\",\"aria-valuenow\":0,\"aria-valuemin\":0,\"aria-valuemax\":100,tabIndex:0},c);return u.c.prototype.e.call(this,a,c)};t.Pa=function(a){a.preventDefault();u.Tc();this.P.move=u.bind(this,this.Hb);this.P.end=u.bind(this,this.Ib);u.d(document,\"mousemove\",this.P.move);u.d(document,\"mouseup\",this.P.end);u.d(document,\"touchmove\",this.P.move);u.d(document,\"touchend\",this.P.end);this.Hb(a)};\nt.Ib=function(){u.Bd();u.o(document,\"mousemove\",this.P.move,l);u.o(document,\"mouseup\",this.P.end,l);u.o(document,\"touchmove\",this.P.move,l);u.o(document,\"touchend\",this.P.end,l);this.update()};t.update=function(){if(this.a){var a,c=this.yb(),d=this.handle,e=this.Sc;isNaN(c)&&(c=0);a=c;if(d){a=this.a.offsetWidth;var g=d.w().offsetWidth;a=g?g/a:0;c*=1-a;a=c+a/2;d.w().style.left=u.round(100*c,2)+\"%\"}e.w().style.width=u.round(100*a,2)+\"%\"}};\nfunction F(a,c){var d,e,g,j;d=a.a;e=u.ad(d);j=g=d.offsetWidth;d=a.handle;if(a.g.Cd)return j=e.top,e=c.changedTouches?c.changedTouches[0].pageY:c.pageY,d&&(d=d.w().offsetHeight,j+=d/2,g-=d),Math.max(0,Math.min(1,(j-e+g)/g));g=e.left;e=c.changedTouches?c.changedTouches[0].pageX:c.pageX;d&&(d=d.w().offsetWidth,g+=d/2,j-=d);return Math.max(0,Math.min(1,(e-g)/j))}t.Oa=function(){u.d(document,\"keyup\",u.bind(this,this.ba))};\nt.ba=function(a){37==a.which?(a.preventDefault(),this.yc()):39==a.which&&(a.preventDefault(),this.zc())};t.Na=function(){u.o(document,\"keyup\",u.bind(this,this.ba))};t.p=function(a){a.stopImmediatePropagation();a.preventDefault()};u.ea=u.c.extend();u.ea.prototype.defaultValue=0;u.ea.prototype.e=function(a,c){c=c||{};c.className+=\" vjs-slider-handle\";c=u.k.B({innerHTML:'<span class=\"vjs-control-text\">'+this.defaultValue+\"</span>\"},c);return u.c.prototype.e.call(this,\"div\",c)};u.ma=u.c.extend();\nfunction ca(a,c){a.Z(c);c.d(\"click\",u.bind(a,function(){D(this)}))}u.ma.prototype.e=function(){var a=this.options().Vc||\"ul\";this.sa=u.e(a,{className:\"vjs-menu-content\"});a=u.c.prototype.e.call(this,\"div\",{append:this.sa,className:\"vjs-menu\"});a.appendChild(this.sa);u.d(a,\"click\",function(a){a.preventDefault();a.stopImmediatePropagation()});return a};u.N=u.q.extend({i:function(a,c){u.q.call(this,a,c);this.selected(c.selected)}});\nu.N.prototype.e=function(a,c){return u.q.prototype.e.call(this,\"li\",u.k.B({className:\"vjs-menu-item\",innerHTML:this.g.label},c))};u.N.prototype.p=function(){this.selected(f)};u.N.prototype.selected=function(a){a?(this.n(\"vjs-selected\"),this.a.setAttribute(\"aria-selected\",f)):(this.u(\"vjs-selected\"),this.a.setAttribute(\"aria-selected\",l))};\nu.R=u.q.extend({i:function(a,c){u.q.call(this,a,c);this.wa=this.Ka();this.Z(this.wa);this.I&&0===this.I.length&&this.C();this.d(\"keyup\",this.ba);this.a.setAttribute(\"aria-haspopup\",f);this.a.setAttribute(\"role\",\"button\")}});t=u.R.prototype;t.pa=l;t.Ka=function(){var a=new u.ma(this.b);this.options().title&&a.w().appendChild(u.e(\"li\",{className:\"vjs-menu-title\",innerHTML:u.$(this.A),zd:-1}));if(this.I=this.createItems())for(var c=0;c<this.I.length;c++)ca(a,this.I[c]);return a};t.ta=m();\nt.T=function(){return this.className+\" vjs-menu-button \"+u.q.prototype.T.call(this)};t.Oa=m();t.Na=m();t.p=function(){this.U(\"mouseout\",u.bind(this,function(){D(this.wa);this.a.blur()}));this.pa?G(this):H(this)};t.ba=function(a){a.preventDefault();32==a.which||13==a.which?this.pa?G(this):H(this):27==a.which&&this.pa&&G(this)};function H(a){a.pa=f;a.wa.n(\"vjs-lock-showing\");a.a.setAttribute(\"aria-pressed\",f);a.I&&0<a.I.length&&a.I[0].w().focus()}\nfunction G(a){a.pa=l;D(a.wa);a.a.setAttribute(\"aria-pressed\",l)}\nu.s=u.c.extend({i:function(a,c,d){this.M=a;c=u.k.B(da(a),c);this.v={};this.uc=c.poster;this.sb=c.controls;a.controls=l;u.c.call(this,this,c,d);this.controls()?this.n(\"vjs-controls-enabled\"):this.n(\"vjs-controls-disabled\");this.U(\"play\",function(a){u.j(this.a,{type:\"firstplay\",target:this.a})||(a.preventDefault(),a.stopPropagation(),a.stopImmediatePropagation())});this.d(\"ended\",this.hd);this.d(\"play\",this.Kb);this.d(\"firstplay\",this.jd);this.d(\"pause\",this.Jb);this.d(\"progress\",this.ld);this.d(\"durationchange\",\nthis.sc);this.d(\"error\",this.Gb);this.d(\"fullscreenchange\",this.kd);u.xa[this.Q]=this;c.plugins&&u.k.ua(c.plugins,function(a,c){this[a](c)},this);var e,g,j,k;e=this.Mb;a=function(){e();clearInterval(g);g=setInterval(u.bind(this,e),250)};c=function(){e();clearInterval(g)};this.d(\"mousedown\",a);this.d(\"mousemove\",e);this.d(\"mouseup\",c);this.d(\"keydown\",e);this.d(\"keyup\",e);this.d(\"touchstart\",a);this.d(\"touchmove\",e);this.d(\"touchend\",c);this.d(\"touchcancel\",c);j=setInterval(u.bind(this,function(){this.ka&&\n(this.ka=l,this.ja(f),clearTimeout(k),k=setTimeout(u.bind(this,function(){this.ka||this.ja(l)}),2E3))}),250);this.d(\"dispose\",function(){clearInterval(j);clearTimeout(k)})}});t=u.s.prototype;t.g=u.options;t.D=function(){this.j(\"dispose\");this.o(\"dispose\");u.xa[this.Q]=h;this.M&&this.M.player&&(this.M.player=h);this.a&&this.a.player&&(this.a.player=h);clearInterval(this.Ra);this.za();this.h&&this.h.D();u.c.prototype.D.call(this)};\nfunction da(a){var c={sources:[],tracks:[]};u.k.B(c,u.xb(a));if(a.hasChildNodes()){var d,e,g,j;a=a.childNodes;g=0;for(j=a.length;g<j;g++)d=a[g],e=d.nodeName.toLowerCase(),\"source\"===e?c.sources.push(u.xb(d)):\"track\"===e&&c.tracks.push(u.xb(d))}return c}\nt.e=function(){var a=this.a=u.c.prototype.e.call(this,\"div\"),c=this.M;c.removeAttribute(\"width\");c.removeAttribute(\"height\");if(c.hasChildNodes()){var d,e,g,j,k;d=c.childNodes;e=d.length;for(k=[];e--;)g=d[e],j=g.nodeName.toLowerCase(),\"track\"===j&&k.push(g);for(d=0;d<k.length;d++)c.removeChild(k[d])}c.id=c.id||\"vjs_video_\"+u.t++;a.id=c.id;a.className=c.className;c.id+=\"_html5_api\";c.className=\"vjs-tech\";c.player=a.player=this;this.n(\"vjs-paused\");this.width(this.g.width,f);this.height(this.g.height,\nf);c.parentNode&&c.parentNode.insertBefore(a,c);u.zb(c,a);return a};\nfunction I(a,c,d){a.h?(a.aa=l,a.h.D(),a.Eb&&(a.Eb=l,clearInterval(a.Ra)),a.Fb&&J(a),a.h=l):\"Html5\"!==c&&a.M&&(u.l.jc(a.M),a.M=h);a.ia=c;a.aa=l;var e=u.k.B({source:d,parentEl:a.a},a.g[c.toLowerCase()]);d&&(d.src==a.v.src&&0<a.v.currentTime&&(e.startTime=a.v.currentTime),a.v.src=d.src);a.h=new window.videojs[c](a,e);a.h.L(function(){this.b.Ua();if(!this.m.progressEvents){var a=this.b;a.Eb=f;a.Ra=setInterval(u.bind(a,function(){this.v.lb<this.buffered().end(0)?this.j(\"progress\"):1==this.Ja()&&(clearInterval(this.Ra),\nthis.j(\"progress\"))}),500);a.h.U(\"progress\",function(){this.m.progressEvents=f;var a=this.b;a.Eb=l;clearInterval(a.Ra)})}this.m.timeupdateEvents||(a=this.b,a.Fb=f,a.d(\"play\",a.Cc),a.d(\"pause\",a.za),a.h.U(\"timeupdate\",function(){this.m.timeupdateEvents=f;J(this.b)}))})}function J(a){a.Fb=l;a.za();a.o(\"play\",a.Cc);a.o(\"pause\",a.za)}t.Cc=function(){this.hc&&this.za();this.hc=setInterval(u.bind(this,function(){this.j(\"timeupdate\")}),250)};t.za=function(){clearInterval(this.hc)};\nt.Kb=function(){u.u(this.a,\"vjs-paused\");u.n(this.a,\"vjs-playing\")};t.jd=function(){this.g.starttime&&this.currentTime(this.g.starttime);this.n(\"vjs-has-started\")};t.Jb=function(){u.u(this.a,\"vjs-playing\");u.n(this.a,\"vjs-paused\")};t.ld=function(){1==this.Ja()&&this.j(\"loadedalldata\")};t.hd=function(){this.g.loop&&(this.currentTime(0),this.play())};t.sc=function(){this.duration(K(this,\"duration\"))};t.kd=function(){this.H?this.n(\"vjs-fullscreen\"):this.u(\"vjs-fullscreen\")};\nt.Gb=function(a){u.log(\"Video Error\",a)};function L(a,c,d){if(a.h&&!a.h.aa)a.h.L(function(){this[c](d)});else try{a.h[c](d)}catch(e){throw u.log(e),e;}}function K(a,c){if(a.h&&a.h.aa)try{return a.h[c]()}catch(d){throw a.h[c]===b?u.log(\"Video.js: \"+c+\" method not defined for \"+a.ia+\" playback technology.\",d):\"TypeError\"==d.name?(u.log(\"Video.js: \"+c+\" unavailable on \"+a.ia+\" playback technology element.\",d),a.h.aa=l):u.log(d),d;}}t.play=function(){L(this,\"play\");return this};\nt.pause=function(){L(this,\"pause\");return this};t.paused=function(){return K(this,\"paused\")===l?l:f};t.currentTime=function(a){return a!==b?(this.v.rc=a,L(this,\"setCurrentTime\",a),this.Fb&&this.j(\"timeupdate\"),this):this.v.currentTime=K(this,\"currentTime\")||0};t.duration=function(a){if(a!==b)return this.v.duration=parseFloat(a),this;this.v.duration===b&&this.sc();return this.v.duration};\nt.buffered=function(){var a=K(this,\"buffered\"),c=a.length-1,d=this.v.lb=this.v.lb||0;a&&(0<=c&&a.end(c)!==d)&&(d=a.end(c),this.v.lb=d);return u.tb(0,d)};t.Ja=function(){return this.duration()?this.buffered().end(0)/this.duration():0};t.volume=function(a){if(a!==b)return a=Math.max(0,Math.min(1,parseFloat(a))),this.v.volume=a,L(this,\"setVolume\",a),u.td(a),this;a=parseFloat(K(this,\"volume\"));return isNaN(a)?1:a};t.muted=function(a){return a!==b?(L(this,\"setMuted\",a),this):K(this,\"muted\")||l};\nt.Ta=function(){return K(this,\"supportsFullScreen\")||l};\nt.ya=function(){var a=u.Pb.ya;this.H=f;a?(u.d(document,a.vb,u.bind(this,function(c){this.H=document[a.H];this.H===l&&u.o(document,a.vb,arguments.callee);this.j(\"fullscreenchange\")})),this.a[a.wc]()):this.h.Ta()?L(this,\"enterFullScreen\"):(this.cd=f,this.Yc=document.documentElement.style.overflow,u.d(document,\"keydown\",u.bind(this,this.lc)),document.documentElement.style.overflow=\"hidden\",u.n(document.body,\"vjs-full-window\"),this.j(\"enterFullWindow\"),this.j(\"fullscreenchange\"));return this};\nt.ob=function(){var a=u.Pb.ya;this.H=l;if(a)document[a.nb]();else this.h.Ta()?L(this,\"exitFullScreen\"):(M(this),this.j(\"fullscreenchange\"));return this};t.lc=function(a){27===a.keyCode&&(this.H===f?this.ob():M(this))};function M(a){a.cd=l;u.o(document,\"keydown\",a.lc);document.documentElement.style.overflow=a.Yc;u.u(document.body,\"vjs-full-window\");a.j(\"exitFullWindow\")}\nt.src=function(a){if(a instanceof Array){var c;a:{c=a;for(var d=0,e=this.g.techOrder;d<e.length;d++){var g=u.$(e[d]),j=window.videojs[g];if(j.isSupported())for(var k=0,q=c;k<q.length;k++){var n=q[k];if(j.canPlaySource(n)){c={source:n,h:g};break a}}}c=l}c?(a=c.source,c=c.h,c==this.ia?this.src(a):I(this,c,a)):this.a.appendChild(u.e(\"p\",{innerHTML:this.options().notSupportedMessage}))}else a instanceof Object?window.videojs[this.ia].canPlaySource(a)?this.src(a.src):this.src([a]):(this.v.src=a,this.aa?\n(L(this,\"src\",a),\"auto\"==this.g.preload&&this.load(),this.g.autoplay&&this.play()):this.L(function(){this.src(a)}));return this};t.load=function(){L(this,\"load\");return this};t.currentSrc=function(){return K(this,\"currentSrc\")||this.v.src||\"\"};t.Qa=function(a){return a!==b?(L(this,\"setPreload\",a),this.g.preload=a,this):K(this,\"preload\")};t.autoplay=function(a){return a!==b?(L(this,\"setAutoplay\",a),this.g.autoplay=a,this):K(this,\"autoplay\")};\nt.loop=function(a){return a!==b?(L(this,\"setLoop\",a),this.g.loop=a,this):K(this,\"loop\")};t.poster=function(a){return a!==b?(this.uc=a,this):this.uc};t.controls=function(a){return a!==b?(a=!!a,this.sb!==a&&((this.sb=a)?(this.u(\"vjs-controls-disabled\"),this.n(\"vjs-controls-enabled\"),this.j(\"controlsenabled\")):(this.u(\"vjs-controls-enabled\"),this.n(\"vjs-controls-disabled\"),this.j(\"controlsdisabled\"))),this):this.sb};u.s.prototype.Sb;t=u.s.prototype;\nt.Rb=function(a){return a!==b?(a=!!a,this.Sb!==a&&((this.Sb=a)?(this.n(\"vjs-using-native-controls\"),this.j(\"usingnativecontrols\")):(this.u(\"vjs-using-native-controls\"),this.j(\"usingcustomcontrols\"))),this):this.Sb};t.error=function(){return K(this,\"error\")};t.seeking=function(){return K(this,\"seeking\")};t.ka=f;t.Mb=function(){this.ka=f};t.Qb=f;\nt.ja=function(a){return a!==b?(a=!!a,a!==this.Qb&&((this.Qb=a)?(this.ka=f,this.u(\"vjs-user-inactive\"),this.n(\"vjs-user-active\"),this.j(\"useractive\")):(this.ka=l,this.h.U(\"mousemove\",function(a){a.stopPropagation();a.preventDefault()}),this.u(\"vjs-user-active\"),this.n(\"vjs-user-inactive\"),this.j(\"userinactive\"))),this):this.Qb};var N,O,P;P=document.createElement(\"div\");O={};\nP.Hd!==b?(O.wc=\"requestFullscreen\",O.nb=\"exitFullscreen\",O.vb=\"fullscreenchange\",O.H=\"fullScreen\"):(document.mozCancelFullScreen?(N=\"moz\",O.H=N+\"FullScreen\"):(N=\"webkit\",O.H=N+\"IsFullScreen\"),P[N+\"RequestFullScreen\"]&&(O.wc=N+\"RequestFullScreen\",O.nb=N+\"CancelFullScreen\"),O.vb=N+\"fullscreenchange\");document[O.nb]&&(u.Pb.ya=O);u.Fa=u.c.extend();\nu.Fa.prototype.g={Md:\"play\",children:{playToggle:{},currentTimeDisplay:{},timeDivider:{},durationDisplay:{},remainingTimeDisplay:{},progressControl:{},fullscreenToggle:{},volumeControl:{},muteToggle:{}}};u.Fa.prototype.e=function(){return u.e(\"div\",{className:\"vjs-control-bar\"})};u.Yb=u.q.extend({i:function(a,c){u.q.call(this,a,c);a.d(\"play\",u.bind(this,this.Kb));a.d(\"pause\",u.bind(this,this.Jb))}});t=u.Yb.prototype;t.qa=\"Play\";t.T=function(){return\"vjs-play-control \"+u.q.prototype.T.call(this)};\nt.p=function(){this.b.paused()?this.b.play():this.b.pause()};t.Kb=function(){u.u(this.a,\"vjs-paused\");u.n(this.a,\"vjs-playing\");this.a.children[0].children[0].innerHTML=\"Pause\"};t.Jb=function(){u.u(this.a,\"vjs-playing\");u.n(this.a,\"vjs-paused\");this.a.children[0].children[0].innerHTML=\"Play\"};u.Ya=u.c.extend({i:function(a,c){u.c.call(this,a,c);a.d(\"timeupdate\",u.bind(this,this.Ca))}});\nu.Ya.prototype.e=function(){var a=u.c.prototype.e.call(this,\"div\",{className:\"vjs-current-time vjs-time-controls vjs-control\"});this.content=u.e(\"div\",{className:\"vjs-current-time-display\",innerHTML:'<span class=\"vjs-control-text\">Current Time </span>0:00',\"aria-live\":\"off\"});a.appendChild(u.e(\"div\").appendChild(this.content));return a};\nu.Ya.prototype.Ca=function(){var a=this.b.Nb?this.b.v.currentTime:this.b.currentTime();this.content.innerHTML='<span class=\"vjs-control-text\">Current Time </span>'+u.La(a,this.b.duration())};u.Za=u.c.extend({i:function(a,c){u.c.call(this,a,c);a.d(\"timeupdate\",u.bind(this,this.Ca))}});\nu.Za.prototype.e=function(){var a=u.c.prototype.e.call(this,\"div\",{className:\"vjs-duration vjs-time-controls vjs-control\"});this.content=u.e(\"div\",{className:\"vjs-duration-display\",innerHTML:'<span class=\"vjs-control-text\">Duration Time </span>0:00',\"aria-live\":\"off\"});a.appendChild(u.e(\"div\").appendChild(this.content));return a};u.Za.prototype.Ca=function(){var a=this.b.duration();a&&(this.content.innerHTML='<span class=\"vjs-control-text\">Duration Time </span>'+u.La(a))};\nu.cc=u.c.extend({i:function(a,c){u.c.call(this,a,c)}});u.cc.prototype.e=function(){return u.c.prototype.e.call(this,\"div\",{className:\"vjs-time-divider\",innerHTML:\"<div><span>/</span></div>\"})};u.fb=u.c.extend({i:function(a,c){u.c.call(this,a,c);a.d(\"timeupdate\",u.bind(this,this.Ca))}});\nu.fb.prototype.e=function(){var a=u.c.prototype.e.call(this,\"div\",{className:\"vjs-remaining-time vjs-time-controls vjs-control\"});this.content=u.e(\"div\",{className:\"vjs-remaining-time-display\",innerHTML:'<span class=\"vjs-control-text\">Remaining Time </span>-0:00',\"aria-live\":\"off\"});a.appendChild(u.e(\"div\").appendChild(this.content));return a};u.fb.prototype.Ca=function(){this.b.duration()&&(this.content.innerHTML='<span class=\"vjs-control-text\">Remaining Time </span>-'+u.La(this.b.duration()-this.b.currentTime()))};\nu.Ga=u.q.extend({i:function(a,c){u.q.call(this,a,c)}});u.Ga.prototype.qa=\"Fullscreen\";u.Ga.prototype.T=function(){return\"vjs-fullscreen-control \"+u.q.prototype.T.call(this)};u.Ga.prototype.p=function(){this.b.H?(this.b.ob(),this.a.children[0].children[0].innerHTML=\"Fullscreen\"):(this.b.ya(),this.a.children[0].children[0].innerHTML=\"Non-Fullscreen\")};u.eb=u.c.extend({i:function(a,c){u.c.call(this,a,c)}});u.eb.prototype.g={children:{seekBar:{}}};\nu.eb.prototype.e=function(){return u.c.prototype.e.call(this,\"div\",{className:\"vjs-progress-control vjs-control\"})};u.Zb=u.O.extend({i:function(a,c){u.O.call(this,a,c);a.d(\"timeupdate\",u.bind(this,this.Ba));a.L(u.bind(this,this.Ba))}});t=u.Zb.prototype;t.g={children:{loadProgressBar:{},playProgressBar:{},seekHandle:{}},barName:\"playProgressBar\",handleName:\"seekHandle\"};t.tc=\"timeupdate\";t.e=function(){return u.O.prototype.e.call(this,\"div\",{className:\"vjs-progress-holder\",\"aria-label\":\"video progress bar\"})};\nt.Ba=function(){var a=this.b.Nb?this.b.v.currentTime:this.b.currentTime();this.a.setAttribute(\"aria-valuenow\",u.round(100*this.yb(),2));this.a.setAttribute(\"aria-valuetext\",u.La(a,this.b.duration()))};t.yb=function(){var a;\"Flash\"===this.b.ia&&this.b.seeking()?(a=this.b.v,a=a.rc?a.rc:this.b.currentTime()):a=this.b.currentTime();return a/this.b.duration()};t.Pa=function(a){u.O.prototype.Pa.call(this,a);this.b.Nb=f;this.Dd=!this.b.paused();this.b.pause()};\nt.Hb=function(a){a=F(this,a)*this.b.duration();a==this.b.duration()&&(a-=0.1);this.b.currentTime(a)};t.Ib=function(a){u.O.prototype.Ib.call(this,a);this.b.Nb=l;this.Dd&&this.b.play()};t.zc=function(){this.b.currentTime(this.b.currentTime()+5)};t.yc=function(){this.b.currentTime(this.b.currentTime()-5)};u.ab=u.c.extend({i:function(a,c){u.c.call(this,a,c);a.d(\"progress\",u.bind(this,this.update))}});u.ab.prototype.e=function(){return u.c.prototype.e.call(this,\"div\",{className:\"vjs-load-progress\",innerHTML:'<span class=\"vjs-control-text\">Loaded: 0%</span>'})};\nu.ab.prototype.update=function(){this.a.style&&(this.a.style.width=u.round(100*this.b.Ja(),2)+\"%\")};u.Xb=u.c.extend({i:function(a,c){u.c.call(this,a,c)}});u.Xb.prototype.e=function(){return u.c.prototype.e.call(this,\"div\",{className:\"vjs-play-progress\",innerHTML:'<span class=\"vjs-control-text\">Progress: 0%</span>'})};u.gb=u.ea.extend();u.gb.prototype.defaultValue=\"00:00\";u.gb.prototype.e=function(){return u.ea.prototype.e.call(this,\"div\",{className:\"vjs-seek-handle\"})};\nu.ib=u.c.extend({i:function(a,c){u.c.call(this,a,c);a.h&&(a.h.m&&a.h.m.volumeControl===l)&&this.n(\"vjs-hidden\");a.d(\"loadstart\",u.bind(this,function(){a.h.m&&a.h.m.volumeControl===l?this.n(\"vjs-hidden\"):this.u(\"vjs-hidden\")}))}});u.ib.prototype.g={children:{volumeBar:{}}};u.ib.prototype.e=function(){return u.c.prototype.e.call(this,\"div\",{className:\"vjs-volume-control vjs-control\"})};\nu.hb=u.O.extend({i:function(a,c){u.O.call(this,a,c);a.d(\"volumechange\",u.bind(this,this.Ba));a.L(u.bind(this,this.Ba));setTimeout(u.bind(this,this.update),0)}});t=u.hb.prototype;t.Ba=function(){this.a.setAttribute(\"aria-valuenow\",u.round(100*this.b.volume(),2));this.a.setAttribute(\"aria-valuetext\",u.round(100*this.b.volume(),2)+\"%\")};t.g={children:{volumeLevel:{},volumeHandle:{}},barName:\"volumeLevel\",handleName:\"volumeHandle\"};t.tc=\"volumechange\";\nt.e=function(){return u.O.prototype.e.call(this,\"div\",{className:\"vjs-volume-bar\",\"aria-label\":\"volume level\"})};t.Hb=function(a){this.b.muted()&&this.b.muted(l);this.b.volume(F(this,a))};t.yb=function(){return this.b.muted()?0:this.b.volume()};t.zc=function(){this.b.volume(this.b.volume()+0.1)};t.yc=function(){this.b.volume(this.b.volume()-0.1)};u.dc=u.c.extend({i:function(a,c){u.c.call(this,a,c)}});\nu.dc.prototype.e=function(){return u.c.prototype.e.call(this,\"div\",{className:\"vjs-volume-level\",innerHTML:'<span class=\"vjs-control-text\"></span>'})};u.jb=u.ea.extend();u.jb.prototype.defaultValue=\"00:00\";u.jb.prototype.e=function(){return u.ea.prototype.e.call(this,\"div\",{className:\"vjs-volume-handle\"})};\nu.da=u.q.extend({i:function(a,c){u.q.call(this,a,c);a.d(\"volumechange\",u.bind(this,this.update));a.h&&(a.h.m&&a.h.m.volumeControl===l)&&this.n(\"vjs-hidden\");a.d(\"loadstart\",u.bind(this,function(){a.h.m&&a.h.m.volumeControl===l?this.n(\"vjs-hidden\"):this.u(\"vjs-hidden\")}))}});u.da.prototype.e=function(){return u.q.prototype.e.call(this,\"div\",{className:\"vjs-mute-control vjs-control\",innerHTML:'<div><span class=\"vjs-control-text\">Mute</span></div>'})};\nu.da.prototype.p=function(){this.b.muted(this.b.muted()?l:f)};u.da.prototype.update=function(){var a=this.b.volume(),c=3;0===a||this.b.muted()?c=0:0.33>a?c=1:0.67>a&&(c=2);this.b.muted()?\"Unmute\"!=this.a.children[0].children[0].innerHTML&&(this.a.children[0].children[0].innerHTML=\"Unmute\"):\"Mute\"!=this.a.children[0].children[0].innerHTML&&(this.a.children[0].children[0].innerHTML=\"Mute\");for(a=0;4>a;a++)u.u(this.a,\"vjs-vol-\"+a);u.n(this.a,\"vjs-vol-\"+c)};\nu.oa=u.R.extend({i:function(a,c){u.R.call(this,a,c);a.d(\"volumechange\",u.bind(this,this.update));a.h&&(a.h.m&&a.h.m.Dc===l)&&this.n(\"vjs-hidden\");a.d(\"loadstart\",u.bind(this,function(){a.h.m&&a.h.m.Dc===l?this.n(\"vjs-hidden\"):this.u(\"vjs-hidden\")}));this.n(\"vjs-menu-button\")}});u.oa.prototype.Ka=function(){var a=new u.ma(this.b,{Vc:\"div\"}),c=new u.hb(this.b,u.k.B({Cd:f},this.g.Vd));a.Z(c);return a};u.oa.prototype.p=function(){u.da.prototype.p.call(this);u.R.prototype.p.call(this)};\nu.oa.prototype.e=function(){return u.q.prototype.e.call(this,\"div\",{className:\"vjs-volume-menu-button vjs-menu-button vjs-control\",innerHTML:'<div><span class=\"vjs-control-text\">Mute</span></div>'})};u.oa.prototype.update=u.da.prototype.update;u.cb=u.q.extend({i:function(a,c){u.q.call(this,a,c);(!a.poster()||!a.controls())&&this.C();a.d(\"play\",u.bind(this,this.C))}});\nu.cb.prototype.e=function(){var a=u.e(\"div\",{className:\"vjs-poster\",tabIndex:-1}),c=this.b.poster();c&&(\"backgroundSize\"in a.style?a.style.backgroundImage='url(\"'+c+'\")':a.appendChild(u.e(\"img\",{src:c})));return a};u.cb.prototype.p=function(){this.K().controls()&&this.b.play()};\nu.Wb=u.c.extend({i:function(a,c){u.c.call(this,a,c);a.d(\"canplay\",u.bind(this,this.C));a.d(\"canplaythrough\",u.bind(this,this.C));a.d(\"playing\",u.bind(this,this.C));a.d(\"seeked\",u.bind(this,this.C));a.d(\"seeking\",u.bind(this,this.show));a.d(\"seeked\",u.bind(this,this.C));a.d(\"error\",u.bind(this,this.show));a.d(\"waiting\",u.bind(this,this.show))}});u.Wb.prototype.e=function(){return u.c.prototype.e.call(this,\"div\",{className:\"vjs-loading-spinner\"})};u.Wa=u.q.extend();\nu.Wa.prototype.e=function(){return u.q.prototype.e.call(this,\"div\",{className:\"vjs-big-play-button\",innerHTML:'<span aria-hidden=\"true\"></span>',\"aria-label\":\"play video\"})};u.Wa.prototype.p=function(){this.b.play()};\nu.r=u.c.extend({i:function(a,c,d){u.c.call(this,a,c,d);var e,g;g=this;e=this.K();a=function(){if(e.controls()&&!e.Rb()){var a,c;g.d(\"mousedown\",g.p);g.d(\"touchstart\",function(a){a.preventDefault();a.stopPropagation();c=this.b.ja()});a=function(a){a.stopPropagation();c&&this.b.Mb()};g.d(\"touchmove\",a);g.d(\"touchleave\",a);g.d(\"touchcancel\",a);g.d(\"touchend\",a);var d,n,r;d=0;g.d(\"touchstart\",function(){d=(new Date).getTime();r=f});a=function(){r=l};g.d(\"touchmove\",a);g.d(\"touchleave\",a);g.d(\"touchcancel\",\na);g.d(\"touchend\",function(){r===f&&(n=(new Date).getTime()-d,250>n&&this.j(\"tap\"))});g.d(\"tap\",g.md)}};c=u.bind(g,g.pd);this.L(a);e.d(\"controlsenabled\",a);e.d(\"controlsdisabled\",c)}});u.r.prototype.pd=function(){this.o(\"tap\");this.o(\"touchstart\");this.o(\"touchmove\");this.o(\"touchleave\");this.o(\"touchcancel\");this.o(\"touchend\");this.o(\"click\");this.o(\"mousedown\")};u.r.prototype.p=function(a){0===a.button&&this.K().controls()&&(this.K().paused()?this.K().play():this.K().pause())};\nu.r.prototype.md=function(){this.K().ja(!this.K().ja())};u.r.prototype.m={volumeControl:f,fullscreenResize:l,progressEvents:l,timeupdateEvents:l};u.media={};u.media.Va=\"play pause paused currentTime setCurrentTime duration buffered volume setVolume muted setMuted width height supportsFullScreen enterFullScreen src load currentSrc preload setPreload autoplay setAutoplay loop setLoop error networkState readyState seeking initialTime startOffsetTime played seekable ended videoTracks audioTracks videoWidth videoHeight textTracks defaultPlaybackRate playbackRate mediaGroup controller controls defaultMuted\".split(\" \");\nfunction ea(){var a=u.media.Va[i];return function(){throw Error('The \"'+a+\"\\\" method is not available on the playback technology's API\");}}for(var i=u.media.Va.length-1;0<=i;i--)u.r.prototype[u.media.Va[i]]=ea();\nu.l=u.r.extend({i:function(a,c,d){this.m.volumeControl=u.l.Uc();this.m.movingMediaElementInDOM=!u.Kc;this.m.fullscreenResize=f;u.r.call(this,a,c,d);(c=c.source)&&this.a.currentSrc===c.src&&0<this.a.networkState?a.j(\"loadstart\"):c&&(this.a.src=c.src);if(u.ac&&a.options().nativeControlsForTouch!==l){var e,g,j,k;e=this;g=this.K();c=g.controls();e.a.controls=!!c;j=function(){e.a.controls=f};k=function(){e.a.controls=l};g.d(\"controlsenabled\",j);g.d(\"controlsdisabled\",k);c=function(){g.o(\"controlsenabled\",\nj);g.o(\"controlsdisabled\",k)};e.d(\"dispose\",c);g.d(\"usingcustomcontrols\",c);g.Rb(f)}a.L(function(){this.M&&(this.g.autoplay&&this.paused())&&(delete this.M.poster,this.play())});for(a=u.l.$a.length-1;0<=a;a--)u.d(this.a,u.l.$a[a],u.bind(this.b,this.$c));this.Ua()}});t=u.l.prototype;t.D=function(){u.r.prototype.D.call(this)};\nt.e=function(){var a=this.b,c=a.M,d;if(!c||this.m.movingMediaElementInDOM===l)c?(d=c.cloneNode(l),u.l.jc(c),c=d,a.M=h):c=u.e(\"video\",{id:a.id()+\"_html5_api\",className:\"vjs-tech\"}),c.player=a,u.zb(c,a.w());d=[\"autoplay\",\"preload\",\"loop\",\"muted\"];for(var e=d.length-1;0<=e;e--){var g=d[e];a.g[g]!==h&&(c[g]=a.g[g])}return c};t.$c=function(a){this.j(a);a.stopPropagation()};t.play=function(){this.a.play()};t.pause=function(){this.a.pause()};t.paused=function(){return this.a.paused};t.currentTime=function(){return this.a.currentTime};\nt.sd=function(a){try{this.a.currentTime=a}catch(c){u.log(c,\"Video is not ready. (Video.js)\")}};t.duration=function(){return this.a.duration||0};t.buffered=function(){return this.a.buffered};t.volume=function(){return this.a.volume};t.xd=function(a){this.a.volume=a};t.muted=function(){return this.a.muted};t.vd=function(a){this.a.muted=a};t.width=function(){return this.a.offsetWidth};t.height=function(){return this.a.offsetHeight};\nt.Ta=function(){return\"function\"==typeof this.a.webkitEnterFullScreen&&(/Android/.test(u.F)||!/Chrome|Mac OS X 10.5/.test(u.F))?f:l};t.src=function(a){this.a.src=a};t.load=function(){this.a.load()};t.currentSrc=function(){return this.a.currentSrc};t.Qa=function(){return this.a.Qa};t.wd=function(a){this.a.Qa=a};t.autoplay=function(){return this.a.autoplay};t.rd=function(a){this.a.autoplay=a};t.controls=function(){return this.a.controls};t.loop=function(){return this.a.loop};\nt.ud=function(a){this.a.loop=a};t.error=function(){return this.a.error};t.seeking=function(){return this.a.seeking};u.l.isSupported=function(){return!!u.na.canPlayType};u.l.mb=function(a){try{return!!u.na.canPlayType(a.type)}catch(c){return\"\"}};u.l.Uc=function(){var a=u.na.volume;u.na.volume=a/2+0.1;return a!==u.na.volume};u.l.$a=\"loadstart suspend abort error emptied stalled loadedmetadata loadeddata canplay canplaythrough playing waiting seeking seeked ended durationchange timeupdate progress play pause ratechange volumechange\".split(\" \");\nu.l.jc=function(a){if(a){a.player=h;for(a.parentNode&&a.parentNode.removeChild(a);a.hasChildNodes();)a.removeChild(a.firstChild);a.removeAttribute(\"src\");\"function\"===typeof a.load&&a.load()}};u.Oc&&(document.createElement(\"video\").constructor.prototype.canPlayType=function(a){return a&&-1!=a.toLowerCase().indexOf(\"video/mp4\")?\"maybe\":\"\"});\nu.f=u.r.extend({i:function(a,c,d){u.r.call(this,a,c,d);var e=c.source;d=c.parentEl;var g=this.a=u.e(\"div\",{id:a.id()+\"_temp_flash\"}),j=a.id()+\"_flash_api\";a=a.g;var k=u.k.B({readyFunction:\"videojs.Flash.onReady\",eventProxyFunction:\"videojs.Flash.onEvent\",errorEventProxyFunction:\"videojs.Flash.onError\",autoplay:a.autoplay,preload:a.Qa,loop:a.loop,muted:a.muted},c.flashVars),q=u.k.B({wmode:\"opaque\",bgcolor:\"#000000\"},c.params),n=u.k.B({id:j,name:j,\"class\":\"vjs-tech\"},c.attributes);e&&(e.type&&u.f.ed(e.type)?\n(a=u.f.Ac(e.src),k.rtmpConnection=encodeURIComponent(a.rb),k.rtmpStream=encodeURIComponent(a.Ob)):k.src=encodeURIComponent(u.mc(e.src)));u.zb(g,d);c.startTime&&this.L(function(){this.load();this.play();this.currentTime(c.startTime)});if(c.iFrameMode===f&&!u.Jc){var r=u.e(\"iframe\",{id:j+\"_iframe\",name:j+\"_iframe\",className:\"vjs-tech\",scrolling:\"no\",marginWidth:0,marginHeight:0,frameBorder:0});k.readyFunction=\"ready\";k.eventProxyFunction=\"events\";k.errorEventProxyFunction=\"errors\";u.d(r,\"load\",u.bind(this,\nfunction(){var a,d=r.contentWindow;a=r.contentDocument?r.contentDocument:r.contentWindow.document;a.write(u.f.nc(c.swf,k,q,n));d.player=this.b;d.ready=u.bind(this.b,function(c){var d=this.h;d.a=a.getElementById(c);u.f.pb(d)});d.events=u.bind(this.b,function(a,c){this&&\"flash\"===this.ia&&this.j(c)});d.errors=u.bind(this.b,function(a,c){u.log(\"Flash Error\",c)})}));g.parentNode.replaceChild(r,g)}else u.f.Zc(c.swf,g,k,q,n)}});t=u.f.prototype;t.D=function(){u.r.prototype.D.call(this)};t.play=function(){this.a.vjs_play()};\nt.pause=function(){this.a.vjs_pause()};t.src=function(a){u.f.dd(a)?(a=u.f.Ac(a),this.Qd(a.rb),this.Rd(a.Ob)):(a=u.mc(a),this.a.vjs_src(a));if(this.b.autoplay()){var c=this;setTimeout(function(){c.play()},0)}};t.currentSrc=function(){var a=this.a.vjs_getProperty(\"currentSrc\");if(a==h){var c=this.Od(),d=this.Pd();c&&d&&(a=u.f.yd(c,d))}return a};t.load=function(){this.a.vjs_load()};t.poster=function(){this.a.vjs_getProperty(\"poster\")};t.buffered=function(){return u.tb(0,this.a.vjs_getProperty(\"buffered\"))};\nt.Ta=s(l);var Q=u.f.prototype,R=\"rtmpConnection rtmpStream preload currentTime defaultPlaybackRate playbackRate autoplay loop mediaGroup controller controls volume muted defaultMuted\".split(\" \"),S=\"error currentSrc networkState readyState seeking initialTime duration startOffsetTime paused played seekable ended videoTracks audioTracks videoWidth videoHeight textTracks\".split(\" \");\nfunction fa(){var a=R[T],c=a.charAt(0).toUpperCase()+a.slice(1);Q[\"set\"+c]=function(c){return this.a.vjs_setProperty(a,c)}}function U(a){Q[a]=function(){return this.a.vjs_getProperty(a)}}var T;for(T=0;T<R.length;T++)U(R[T]),fa();for(T=0;T<S.length;T++)U(S[T]);u.f.isSupported=function(){return 10<=u.f.version()[0]};u.f.mb=function(a){if(!a.type)return\"\";a=a.type.replace(/;.*/,\"\").toLowerCase();if(a in u.f.bd||a in u.f.Bc)return\"maybe\"};\nu.f.bd={\"video/flv\":\"FLV\",\"video/x-flv\":\"FLV\",\"video/mp4\":\"MP4\",\"video/m4v\":\"MP4\"};u.f.Bc={\"rtmp/mp4\":\"MP4\",\"rtmp/flv\":\"FLV\"};u.f.onReady=function(a){a=u.w(a);var c=a.player||a.parentNode.player,d=c.h;a.player=c;d.a=a;u.f.pb(d)};u.f.pb=function(a){a.w().vjs_getProperty?a.Ua():setTimeout(function(){u.f.pb(a)},50)};u.f.onEvent=function(a,c){u.w(a).player.j(c)};u.f.onError=function(a,c){u.w(a).player.j(\"error\");u.log(\"Flash Error\",c,a)};\nu.f.version=function(){var a=\"0,0,0\";try{a=(new window.ActiveXObject(\"ShockwaveFlash.ShockwaveFlash\")).GetVariable(\"$version\").replace(/\\D+/g,\",\").match(/^,?(.+),?$/)[1]}catch(c){try{navigator.mimeTypes[\"application/x-shockwave-flash\"].enabledPlugin&&(a=(navigator.plugins[\"Shockwave Flash 2.0\"]||navigator.plugins[\"Shockwave Flash\"]).description.replace(/\\D+/g,\",\").match(/^,?(.+),?$/)[1])}catch(d){}}return a.split(\",\")};\nu.f.Zc=function(a,c,d,e,g){a=u.f.nc(a,d,e,g);a=u.e(\"div\",{innerHTML:a}).childNodes[0];d=c.parentNode;c.parentNode.replaceChild(a,c);var j=d.childNodes[0];setTimeout(function(){j.style.display=\"block\"},1E3)};\nu.f.nc=function(a,c,d,e){var g=\"\",j=\"\",k=\"\";c&&u.k.ua(c,function(a,c){g+=a+\"=\"+c+\"&amp;\"});d=u.k.B({movie:a,flashvars:g,allowScriptAccess:\"always\",allowNetworking:\"all\"},d);u.k.ua(d,function(a,c){j+='<param name=\"'+a+'\" value=\"'+c+'\" />'});e=u.k.B({data:a,width:\"100%\",height:\"100%\"},e);u.k.ua(e,function(a,c){k+=a+'=\"'+c+'\" '});return'<object type=\"application/x-shockwave-flash\"'+k+\">\"+j+\"</object>\"};u.f.yd=function(a,c){return a+\"&\"+c};\nu.f.Ac=function(a){var c={rb:\"\",Ob:\"\"};if(!a)return c;var d=a.indexOf(\"&\"),e;-1!==d?e=d+1:(d=e=a.lastIndexOf(\"/\")+1,0===d&&(d=e=a.length));c.rb=a.substring(0,d);c.Ob=a.substring(e,a.length);return c};u.f.ed=function(a){return a in u.f.Bc};u.f.Qc=/^rtmp[set]?:\\/\\//i;u.f.dd=function(a){return u.f.Qc.test(a)};\nu.Pc=u.c.extend({i:function(a,c,d){u.c.call(this,a,c,d);if(!a.g.sources||0===a.g.sources.length){c=0;for(d=a.g.techOrder;c<d.length;c++){var e=u.$(d[c]),g=window.videojs[e];if(g&&g.isSupported()){I(a,e);break}}}else a.src(a.g.sources)}});function V(a){a.Aa=a.Aa||[];return a.Aa}function W(a,c,d){for(var e=a.Aa,g=0,j=e.length,k,q;g<j;g++)k=e[g],k.id()===c?(k.show(),q=k):d&&(k.J()==d&&0<k.mode())&&k.disable();(c=q?q.J():d?d:l)&&a.j(c+\"trackchange\")}\nu.X=u.c.extend({i:function(a,c){u.c.call(this,a,c);this.Q=c.id||\"vjs_\"+c.kind+\"_\"+c.language+\"_\"+u.t++;this.xc=c.src;this.Wc=c[\"default\"]||c.dflt;this.Ad=c.title;this.Ld=c.srclang;this.fd=c.label;this.fa=[];this.ec=[];this.ga=this.ha=0;this.b.d(\"fullscreenchange\",u.bind(this,this.Rc))}});t=u.X.prototype;t.J=p(\"A\");t.src=p(\"xc\");t.ub=p(\"Wc\");t.title=p(\"Ad\");t.label=p(\"fd\");t.readyState=p(\"ha\");t.mode=p(\"ga\");t.Rc=function(){this.a.style.fontSize=this.b.H?140*(screen.width/this.b.width())+\"%\":\"\"};\nt.e=function(){return u.c.prototype.e.call(this,\"div\",{className:\"vjs-\"+this.A+\" vjs-text-track\"})};t.show=function(){X(this);this.ga=2;u.c.prototype.show.call(this)};t.C=function(){X(this);this.ga=1;u.c.prototype.C.call(this)};t.disable=function(){2==this.ga&&this.C();this.b.o(\"timeupdate\",u.bind(this,this.update,this.Q));this.b.o(\"ended\",u.bind(this,this.reset,this.Q));this.reset();this.b.V.textTrackDisplay.removeChild(this);this.ga=0};\nfunction X(a){0===a.ha&&a.load();0===a.ga&&(a.b.d(\"timeupdate\",u.bind(a,a.update,a.Q)),a.b.d(\"ended\",u.bind(a,a.reset,a.Q)),(\"captions\"===a.A||\"subtitles\"===a.A)&&a.b.V.textTrackDisplay.Z(a))}t.load=function(){0===this.ha&&(this.ha=1,u.get(this.xc,u.bind(this,this.nd),u.bind(this,this.Gb)))};t.Gb=function(a){this.error=a;this.ha=3;this.j(\"error\")};\nt.nd=function(a){var c,d;a=a.split(\"\\n\");for(var e=\"\",g=1,j=a.length;g<j;g++)if(e=u.trim(a[g])){-1==e.indexOf(\"--\\x3e\")?(c=e,e=u.trim(a[++g])):c=this.fa.length;c={id:c,index:this.fa.length};d=e.split(\" --\\x3e \");c.startTime=Y(d[0]);c.va=Y(d[1]);for(d=[];a[++g]&&(e=u.trim(a[g]));)d.push(e);c.text=d.join(\"<br/>\");this.fa.push(c)}this.ha=2;this.j(\"loaded\")};\nfunction Y(a){var c=a.split(\":\");a=0;var d,e,g;3==c.length?(d=c[0],e=c[1],c=c[2]):(d=0,e=c[0],c=c[1]);c=c.split(/\\s+/);c=c.splice(0,1)[0];c=c.split(/\\.|,/);g=parseFloat(c[1]);c=c[0];a+=3600*parseFloat(d);a+=60*parseFloat(e);a+=parseFloat(c);g&&(a+=g/1E3);return a}\nt.update=function(){if(0<this.fa.length){var a=this.b.currentTime();if(this.Lb===b||a<this.Lb||this.Ma<=a){var c=this.fa,d=this.b.duration(),e=0,g=l,j=[],k,q,n,r;a>=this.Ma||this.Ma===b?r=this.wb!==b?this.wb:0:(g=f,r=this.Db!==b?this.Db:c.length-1);for(;;){n=c[r];if(n.va<=a)e=Math.max(e,n.va),n.Ia&&(n.Ia=l);else if(a<n.startTime){if(d=Math.min(d,n.startTime),n.Ia&&(n.Ia=l),!g)break}else g?(j.splice(0,0,n),q===b&&(q=r),k=r):(j.push(n),k===b&&(k=r),q=r),d=Math.min(d,n.va),e=Math.max(e,n.startTime),\nn.Ia=f;if(g)if(0===r)break;else r--;else if(r===c.length-1)break;else r++}this.ec=j;this.Ma=d;this.Lb=e;this.wb=k;this.Db=q;a=this.ec;c=\"\";d=0;for(e=a.length;d<e;d++)c+='<span class=\"vjs-tt-cue\">'+a[d].text+\"</span>\";this.a.innerHTML=c;this.j(\"cuechange\")}}};t.reset=function(){this.Ma=0;this.Lb=this.b.duration();this.Db=this.wb=0};u.Ub=u.X.extend();u.Ub.prototype.A=\"captions\";u.$b=u.X.extend();u.$b.prototype.A=\"subtitles\";u.Vb=u.X.extend();u.Vb.prototype.A=\"chapters\";\nu.bc=u.c.extend({i:function(a,c,d){u.c.call(this,a,c,d);if(a.g.tracks&&0<a.g.tracks.length){c=this.b;a=a.g.tracks;var e;for(d=0;d<a.length;d++){e=a[d];var g=c,j=e.kind,k=e.label,q=e.language,n=e;e=g.Aa=g.Aa||[];n=n||{};n.kind=j;n.label=k;n.language=q;j=u.$(j||\"subtitles\");g=new window.videojs[j+\"Track\"](g,n);e.push(g)}}}});u.bc.prototype.e=function(){return u.c.prototype.e.call(this,\"div\",{className:\"vjs-text-track-display\"})};\nu.Y=u.N.extend({i:function(a,c){var d=this.ca=c.track;c.label=d.label();c.selected=d.ub();u.N.call(this,a,c);this.b.d(d.J()+\"trackchange\",u.bind(this,this.update))}});u.Y.prototype.p=function(){u.N.prototype.p.call(this);W(this.b,this.ca.Q,this.ca.J())};u.Y.prototype.update=function(){this.selected(2==this.ca.mode())};u.bb=u.Y.extend({i:function(a,c){c.track={J:function(){return c.kind},K:a,label:function(){return c.kind+\" off\"},ub:s(l),mode:s(l)};u.Y.call(this,a,c);this.selected(f)}});\nu.bb.prototype.p=function(){u.Y.prototype.p.call(this);W(this.b,this.ca.Q,this.ca.J())};u.bb.prototype.update=function(){for(var a=V(this.b),c=0,d=a.length,e,g=f;c<d;c++)e=a[c],e.J()==this.ca.J()&&2==e.mode()&&(g=l);this.selected(g)};u.S=u.R.extend({i:function(a,c){u.R.call(this,a,c);1>=this.I.length&&this.C()}});u.S.prototype.ta=function(){var a=[],c;a.push(new u.bb(this.b,{kind:this.A}));for(var d=0;d<V(this.b).length;d++)c=V(this.b)[d],c.J()===this.A&&a.push(new u.Y(this.b,{track:c}));return a};\nu.Da=u.S.extend({i:function(a,c,d){u.S.call(this,a,c,d);this.a.setAttribute(\"aria-label\",\"Captions Menu\")}});u.Da.prototype.A=\"captions\";u.Da.prototype.qa=\"Captions\";u.Da.prototype.className=\"vjs-captions-button\";u.Ha=u.S.extend({i:function(a,c,d){u.S.call(this,a,c,d);this.a.setAttribute(\"aria-label\",\"Subtitles Menu\")}});u.Ha.prototype.A=\"subtitles\";u.Ha.prototype.qa=\"Subtitles\";u.Ha.prototype.className=\"vjs-subtitles-button\";\nu.Ea=u.S.extend({i:function(a,c,d){u.S.call(this,a,c,d);this.a.setAttribute(\"aria-label\",\"Chapters Menu\")}});t=u.Ea.prototype;t.A=\"chapters\";t.qa=\"Chapters\";t.className=\"vjs-chapters-button\";t.ta=function(){for(var a=[],c,d=0;d<V(this.b).length;d++)c=V(this.b)[d],c.J()===this.A&&a.push(new u.Y(this.b,{track:c}));return a};\nt.Ka=function(){for(var a=V(this.b),c=0,d=a.length,e,g,j=this.I=[];c<d;c++)if(e=a[c],e.J()==this.A&&e.ub()){if(2>e.readyState()){this.Id=e;e.d(\"loaded\",u.bind(this,this.Ka));return}g=e;break}a=this.wa=new u.ma(this.b);a.a.appendChild(u.e(\"li\",{className:\"vjs-menu-title\",innerHTML:u.$(this.A),zd:-1}));if(g){e=g.fa;for(var k,c=0,d=e.length;c<d;c++)k=e[c],k=new u.Xa(this.b,{track:g,cue:k}),j.push(k),a.Z(k)}0<this.I.length&&this.show();return a};\nu.Xa=u.N.extend({i:function(a,c){var d=this.ca=c.track,e=this.cue=c.cue,g=a.currentTime();c.label=e.text;c.selected=e.startTime<=g&&g<e.va;u.N.call(this,a,c);d.d(\"cuechange\",u.bind(this,this.update))}});u.Xa.prototype.p=function(){u.N.prototype.p.call(this);this.b.currentTime(this.cue.startTime);this.update(this.cue.startTime)};u.Xa.prototype.update=function(){var a=this.cue,c=this.b.currentTime();this.selected(a.startTime<=c&&c<a.va)};\nu.k.B(u.Fa.prototype.g.children,{subtitlesButton:{},captionsButton:{},chaptersButton:{}});\nif(\"undefined\"!==typeof window.JSON&&\"function\"===window.JSON.parse)u.JSON=window.JSON;else{u.JSON={};var Z=/[\\u0000\\u00ad\\u0600-\\u0604\\u070f\\u17b4\\u17b5\\u200c-\\u200f\\u2028-\\u202f\\u2060-\\u206f\\ufeff\\ufff0-\\uffff]/g;u.JSON.parse=function(a,c){function d(a,e){var k,q,n=a[e];if(n&&\"object\"===typeof n)for(k in n)Object.prototype.hasOwnProperty.call(n,k)&&(q=d(n,k),q!==b?n[k]=q:delete n[k]);return c.call(a,e,n)}var e;a=String(a);Z.lastIndex=0;Z.test(a)&&(a=a.replace(Z,function(a){return\"\\\\u\"+(\"0000\"+a.charCodeAt(0).toString(16)).slice(-4)}));\nif(/^[\\],:{}\\s]*$/.test(a.replace(/\\\\(?:[\"\\\\\\/bfnrt]|u[0-9a-fA-F]{4})/g,\"@\").replace(/\"[^\"\\\\\\n\\r]*\"|true|false|null|-?\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d+)?/g,\"]\").replace(/(?:^|:|,)(?:\\s*\\[)+/g,\"\")))return e=eval(\"(\"+a+\")\"),\"function\"===typeof c?d({\"\":e},\"\"):e;throw new SyntaxError(\"JSON.parse(): invalid or malformed JSON data\");}}\nu.fc=function(){var a,c,d=document.getElementsByTagName(\"video\");if(d&&0<d.length)for(var e=0,g=d.length;e<g;e++)if((c=d[e])&&c.getAttribute)c.player===b&&(a=c.getAttribute(\"data-setup\"),a!==h&&(a=u.JSON.parse(a||\"{}\"),v(c,a)));else{u.kb();break}else u.Ec||u.kb()};u.kb=function(){setTimeout(u.fc,1)};\"complete\"===document.readyState?u.Ec=f:u.U(window,\"load\",function(){u.Ec=f});u.kb();u.od=function(a,c){u.s.prototype[a]=c};var ga=this;ga.Ed=f;function $(a,c){var d=a.split(\".\"),e=ga;!(d[0]in e)&&e.execScript&&e.execScript(\"var \"+d[0]);for(var g;d.length&&(g=d.shift());)!d.length&&c!==b?e[g]=c:e=e[g]?e[g]:e[g]={}};$(\"videojs\",u);$(\"_V_\",u);$(\"videojs.options\",u.options);$(\"videojs.players\",u.xa);$(\"videojs.TOUCH_ENABLED\",u.ac);$(\"videojs.cache\",u.ra);$(\"videojs.Component\",u.c);u.c.prototype.player=u.c.prototype.K;u.c.prototype.dispose=u.c.prototype.D;u.c.prototype.createEl=u.c.prototype.e;u.c.prototype.el=u.c.prototype.w;u.c.prototype.addChild=u.c.prototype.Z;u.c.prototype.children=u.c.prototype.children;u.c.prototype.on=u.c.prototype.d;u.c.prototype.off=u.c.prototype.o;u.c.prototype.one=u.c.prototype.U;\nu.c.prototype.trigger=u.c.prototype.j;u.c.prototype.triggerReady=u.c.prototype.Ua;u.c.prototype.show=u.c.prototype.show;u.c.prototype.hide=u.c.prototype.C;u.c.prototype.width=u.c.prototype.width;u.c.prototype.height=u.c.prototype.height;u.c.prototype.dimensions=u.c.prototype.Xc;u.c.prototype.ready=u.c.prototype.L;u.c.prototype.addClass=u.c.prototype.n;u.c.prototype.removeClass=u.c.prototype.u;$(\"videojs.Player\",u.s);u.s.prototype.dispose=u.s.prototype.D;u.s.prototype.requestFullScreen=u.s.prototype.ya;\nu.s.prototype.cancelFullScreen=u.s.prototype.ob;u.s.prototype.bufferedPercent=u.s.prototype.Ja;u.s.prototype.usingNativeControls=u.s.prototype.Rb;u.s.prototype.reportUserActivity=u.s.prototype.Mb;u.s.prototype.userActive=u.s.prototype.ja;$(\"videojs.MediaLoader\",u.Pc);$(\"videojs.TextTrackDisplay\",u.bc);$(\"videojs.ControlBar\",u.Fa);$(\"videojs.Button\",u.q);$(\"videojs.PlayToggle\",u.Yb);$(\"videojs.FullscreenToggle\",u.Ga);$(\"videojs.BigPlayButton\",u.Wa);$(\"videojs.LoadingSpinner\",u.Wb);\n$(\"videojs.CurrentTimeDisplay\",u.Ya);$(\"videojs.DurationDisplay\",u.Za);$(\"videojs.TimeDivider\",u.cc);$(\"videojs.RemainingTimeDisplay\",u.fb);$(\"videojs.Slider\",u.O);$(\"videojs.ProgressControl\",u.eb);$(\"videojs.SeekBar\",u.Zb);$(\"videojs.LoadProgressBar\",u.ab);$(\"videojs.PlayProgressBar\",u.Xb);$(\"videojs.SeekHandle\",u.gb);$(\"videojs.VolumeControl\",u.ib);$(\"videojs.VolumeBar\",u.hb);$(\"videojs.VolumeLevel\",u.dc);$(\"videojs.VolumeMenuButton\",u.oa);$(\"videojs.VolumeHandle\",u.jb);$(\"videojs.MuteToggle\",u.da);\n$(\"videojs.PosterImage\",u.cb);$(\"videojs.Menu\",u.ma);$(\"videojs.MenuItem\",u.N);$(\"videojs.MenuButton\",u.R);u.R.prototype.createItems=u.R.prototype.ta;u.S.prototype.createItems=u.S.prototype.ta;u.Ea.prototype.createItems=u.Ea.prototype.ta;$(\"videojs.SubtitlesButton\",u.Ha);$(\"videojs.CaptionsButton\",u.Da);$(\"videojs.ChaptersButton\",u.Ea);$(\"videojs.MediaTechController\",u.r);u.r.prototype.features=u.r.prototype.m;u.r.prototype.m.volumeControl=u.r.prototype.m.Dc;u.r.prototype.m.fullscreenResize=u.r.prototype.m.Jd;\nu.r.prototype.m.progressEvents=u.r.prototype.m.Nd;u.r.prototype.m.timeupdateEvents=u.r.prototype.m.Sd;$(\"videojs.Html5\",u.l);u.l.Events=u.l.$a;u.l.isSupported=u.l.isSupported;u.l.canPlaySource=u.l.mb;u.l.prototype.setCurrentTime=u.l.prototype.sd;u.l.prototype.setVolume=u.l.prototype.xd;u.l.prototype.setMuted=u.l.prototype.vd;u.l.prototype.setPreload=u.l.prototype.wd;u.l.prototype.setAutoplay=u.l.prototype.rd;u.l.prototype.setLoop=u.l.prototype.ud;$(\"videojs.Flash\",u.f);u.f.isSupported=u.f.isSupported;\nu.f.canPlaySource=u.f.mb;u.f.onReady=u.f.onReady;$(\"videojs.TextTrack\",u.X);u.X.prototype.label=u.X.prototype.label;$(\"videojs.CaptionsTrack\",u.Ub);$(\"videojs.SubtitlesTrack\",u.$b);$(\"videojs.ChaptersTrack\",u.Vb);$(\"videojs.autoSetup\",u.fc);$(\"videojs.plugin\",u.od);$(\"videojs.createTimeRange\",u.tb);})();\n"
  },
  {
    "path": "public/static/ueditor/third-party/webuploader/webuploader.css",
    "content": ".webuploader-container {\n\tposition: relative;\n}\n.webuploader-element-invisible {\n\tposition: absolute !important;\n\tclip: rect(1px 1px 1px 1px); /* IE6, IE7 */\n    clip: rect(1px,1px,1px,1px);\n}\n.webuploader-pick {\n\tposition: relative;\n\tdisplay: inline-block;\n\tcursor: pointer;\n\tbackground: #00b7ee;\n\tpadding: 10px 15px;\n\tcolor: #fff;\n\ttext-align: center;\n\tborder-radius: 3px;\n\toverflow: hidden;\n}\n.webuploader-pick-hover {\n\tbackground: #00a2d4;\n}\n\n.webuploader-pick-disable {\n\topacity: 0.6;\n\tpointer-events:none;\n}\n\n"
  },
  {
    "path": "public/static/ueditor/third-party/webuploader/webuploader.custom.js",
    "content": "/*! WebUploader 0.1.2 */\n\n\n/**\n * @fileOverview 让内部各个部件的代码可以用[amd](https://github.com/amdjs/amdjs-api/wiki/AMD)模块定义方式组织起来。\n *\n * AMD API 内部的简单不完全实现，请忽略。只有当WebUploader被合并成一个文件的时候才会引入。\n */\n(function( root, factory ) {\n    var modules = {},\n\n        // 内部require, 简单不完全实现。\n        // https://github.com/amdjs/amdjs-api/wiki/require\n        _require = function( deps, callback ) {\n            var args, len, i;\n\n            // 如果deps不是数组，则直接返回指定module\n            if ( typeof deps === 'string' ) {\n                return getModule( deps );\n            } else {\n                args = [];\n                for( len = deps.length, i = 0; i < len; i++ ) {\n                    args.push( getModule( deps[ i ] ) );\n                }\n\n                return callback.apply( null, args );\n            }\n        },\n\n        // 内部define，暂时不支持不指定id.\n        _define = function( id, deps, factory ) {\n            if ( arguments.length === 2 ) {\n                factory = deps;\n                deps = null;\n            }\n\n            _require( deps || [], function() {\n                setModule( id, factory, arguments );\n            });\n        },\n\n        // 设置module, 兼容CommonJs写法。\n        setModule = function( id, factory, args ) {\n            var module = {\n                    exports: factory\n                },\n                returned;\n\n            if ( typeof factory === 'function' ) {\n                args.length || (args = [ _require, module.exports, module ]);\n                returned = factory.apply( null, args );\n                returned !== undefined && (module.exports = returned);\n            }\n\n            modules[ id ] = module.exports;\n        },\n\n        // 根据id获取module\n        getModule = function( id ) {\n            var module = modules[ id ] || root[ id ];\n\n            if ( !module ) {\n                throw new Error( '`' + id + '` is undefined' );\n            }\n\n            return module;\n        },\n\n        // 将所有modules，将路径ids装换成对象。\n        exportsTo = function( obj ) {\n            var key, host, parts, part, last, ucFirst;\n\n            // make the first character upper case.\n            ucFirst = function( str ) {\n                return str && (str.charAt( 0 ).toUpperCase() + str.substr( 1 ));\n            };\n\n            for ( key in modules ) {\n                host = obj;\n\n                if ( !modules.hasOwnProperty( key ) ) {\n                    continue;\n                }\n\n                parts = key.split('/');\n                last = ucFirst( parts.pop() );\n\n                while( (part = ucFirst( parts.shift() )) ) {\n                    host[ part ] = host[ part ] || {};\n                    host = host[ part ];\n                }\n\n                host[ last ] = modules[ key ];\n            }\n        },\n\n        exports = factory( root, _define, _require ),\n        origin;\n\n    // exports every module.\n    exportsTo( exports );\n\n    if ( typeof module === 'object' && typeof module.exports === 'object' ) {\n\n        // For CommonJS and CommonJS-like environments where a proper window is present,\n        module.exports = exports;\n    } else if ( typeof define === 'function' && define.amd ) {\n\n        // Allow using this built library as an AMD module\n        // in another project. That other project will only\n        // see this AMD call, not the internal modules in\n        // the closure below.\n        define([], exports );\n    } else {\n\n        // Browser globals case. Just assign the\n        // result to a property on the global.\n        origin = root.WebUploader;\n        root.WebUploader = exports;\n        root.WebUploader.noConflict = function() {\n            root.WebUploader = origin;\n        };\n    }\n})( this, function( window, define, require ) {\n\n\n    /**\n     * @fileOverview jQuery or Zepto\n     */\n    define('dollar-third',[],function() {\n        return window.jQuery || window.Zepto;\n    });\n    /**\n     * @fileOverview Dom 操作相关\n     */\n    define('dollar',[\n        'dollar-third'\n    ], function( _ ) {\n        return _;\n    });\n    /**\n     * @fileOverview 使用jQuery的Promise\n     */\n    define('promise-third',[\n        'dollar'\n    ], function( $ ) {\n        return {\n            Deferred: $.Deferred,\n            when: $.when,\n    \n            isPromise: function( anything ) {\n                return anything && typeof anything.then === 'function';\n            }\n        };\n    });\n    /**\n     * @fileOverview Promise/A+\n     */\n    define('promise',[\n        'promise-third'\n    ], function( _ ) {\n        return _;\n    });\n    /**\n     * @fileOverview 基础类方法。\n     */\n    \n    /**\n     * Web Uploader内部类的详细说明，以下提及的功能类，都可以在`WebUploader`这个变量中访问到。\n     *\n     * As you know, Web Uploader的每个文件都是用过[AMD](https://github.com/amdjs/amdjs-api/wiki/AMD)规范中的`define`组织起来的, 每个Module都会有个module id.\n     * 默认module id该文件的路径，而此路径将会转化成名字空间存放在WebUploader中。如：\n     *\n     * * module `base`：WebUploader.Base\n     * * module `file`: WebUploader.File\n     * * module `lib/dnd`: WebUploader.Lib.Dnd\n     * * module `runtime/html5/dnd`: WebUploader.Runtime.Html5.Dnd\n     *\n     *\n     * 以下文档将可能省略`WebUploader`前缀。\n     * @module WebUploader\n     * @title WebUploader API文档\n     */\n    define('base',[\n        'dollar',\n        'promise'\n    ], function( $, promise ) {\n    \n        var noop = function() {},\n            call = Function.call;\n    \n        // http://jsperf.com/uncurrythis\n        // 反科里化\n        function uncurryThis( fn ) {\n            return function() {\n                return call.apply( fn, arguments );\n            };\n        }\n    \n        function bindFn( fn, context ) {\n            return function() {\n                return fn.apply( context, arguments );\n            };\n        }\n    \n        function createObject( proto ) {\n            var f;\n    \n            if ( Object.create ) {\n                return Object.create( proto );\n            } else {\n                f = function() {};\n                f.prototype = proto;\n                return new f();\n            }\n        }\n    \n    \n        /**\n         * 基础类，提供一些简单常用的方法。\n         * @class Base\n         */\n        return {\n    \n            /**\n             * @property {String} version 当前版本号。\n             */\n            version: '0.1.2',\n    \n            /**\n             * @property {jQuery|Zepto} $ 引用依赖的jQuery或者Zepto对象。\n             */\n            $: $,\n    \n            Deferred: promise.Deferred,\n    \n            isPromise: promise.isPromise,\n    \n            when: promise.when,\n    \n            /**\n             * @description  简单的浏览器检查结果。\n             *\n             * * `webkit`  webkit版本号，如果浏览器为非webkit内核，此属性为`undefined`。\n             * * `chrome`  chrome浏览器版本号，如果浏览器为chrome，此属性为`undefined`。\n             * * `ie`  ie浏览器版本号，如果浏览器为非ie，此属性为`undefined`。**暂不支持ie10+**\n             * * `firefox`  firefox浏览器版本号，如果浏览器为非firefox，此属性为`undefined`。\n             * * `safari`  safari浏览器版本号，如果浏览器为非safari，此属性为`undefined`。\n             * * `opera`  opera浏览器版本号，如果浏览器为非opera，此属性为`undefined`。\n             *\n             * @property {Object} [browser]\n             */\n            browser: (function( ua ) {\n                var ret = {},\n                    webkit = ua.match( /WebKit\\/([\\d.]+)/ ),\n                    chrome = ua.match( /Chrome\\/([\\d.]+)/ ) ||\n                        ua.match( /CriOS\\/([\\d.]+)/ ),\n    \n                    ie = ua.match( /MSIE\\s([\\d\\.]+)/ ) ||\n                        ua.match(/(?:trident)(?:.*rv:([\\w.]+))?/i),\n                    firefox = ua.match( /Firefox\\/([\\d.]+)/ ),\n                    safari = ua.match( /Safari\\/([\\d.]+)/ ),\n                    opera = ua.match( /OPR\\/([\\d.]+)/ );\n    \n                webkit && (ret.webkit = parseFloat( webkit[ 1 ] ));\n                chrome && (ret.chrome = parseFloat( chrome[ 1 ] ));\n                ie && (ret.ie = parseFloat( ie[ 1 ] ));\n                firefox && (ret.firefox = parseFloat( firefox[ 1 ] ));\n                safari && (ret.safari = parseFloat( safari[ 1 ] ));\n                opera && (ret.opera = parseFloat( opera[ 1 ] ));\n    \n                return ret;\n            })( navigator.userAgent ),\n    \n            /**\n             * @description  操作系统检查结果。\n             *\n             * * `android`  如果在android浏览器环境下，此值为对应的android版本号，否则为`undefined`。\n             * * `ios` 如果在ios浏览器环境下，此值为对应的ios版本号，否则为`undefined`。\n             * @property {Object} [os]\n             */\n            os: (function( ua ) {\n                var ret = {},\n    \n                    // osx = !!ua.match( /\\(Macintosh\\; Intel / ),\n                    android = ua.match( /(?:Android);?[\\s\\/]+([\\d.]+)?/ ),\n                    ios = ua.match( /(?:iPad|iPod|iPhone).*OS\\s([\\d_]+)/ );\n    \n                // osx && (ret.osx = true);\n                android && (ret.android = parseFloat( android[ 1 ] ));\n                ios && (ret.ios = parseFloat( ios[ 1 ].replace( /_/g, '.' ) ));\n    \n                return ret;\n            })( navigator.userAgent ),\n    \n            /**\n             * 实现类与类之间的继承。\n             * @method inherits\n             * @grammar Base.inherits( super ) => child\n             * @grammar Base.inherits( super, protos ) => child\n             * @grammar Base.inherits( super, protos, statics ) => child\n             * @param  {Class} super 父类\n             * @param  {Object | Function} [protos] 子类或者对象。如果对象中包含constructor，子类将是用此属性值。\n             * @param  {Function} [protos.constructor] 子类构造器，不指定的话将创建个临时的直接执行父类构造器的方法。\n             * @param  {Object} [statics] 静态属性或方法。\n             * @return {Class} 返回子类。\n             * @example\n             * function Person() {\n             *     console.log( 'Super' );\n             * }\n             * Person.prototype.hello = function() {\n             *     console.log( 'hello' );\n             * };\n             *\n             * var Manager = Base.inherits( Person, {\n             *     world: function() {\n             *         console.log( 'World' );\n             *     }\n             * });\n             *\n             * // 因为没有指定构造器，父类的构造器将会执行。\n             * var instance = new Manager();    // => Super\n             *\n             * // 继承子父类的方法\n             * instance.hello();    // => hello\n             * instance.world();    // => World\n             *\n             * // 子类的__super__属性指向父类\n             * console.log( Manager.__super__ === Person );    // => true\n             */\n            inherits: function( Super, protos, staticProtos ) {\n                var child;\n    \n                if ( typeof protos === 'function' ) {\n                    child = protos;\n                    protos = null;\n                } else if ( protos && protos.hasOwnProperty('constructor') ) {\n                    child = protos.constructor;\n                } else {\n                    child = function() {\n                        return Super.apply( this, arguments );\n                    };\n                }\n    \n                // 复制静态方法\n                $.extend( true, child, Super, staticProtos || {} );\n    \n                /* jshint camelcase: false */\n    \n                // 让子类的__super__属性指向父类。\n                child.__super__ = Super.prototype;\n    \n                // 构建原型，添加原型方法或属性。\n                // 暂时用Object.create实现。\n                child.prototype = createObject( Super.prototype );\n                protos && $.extend( true, child.prototype, protos );\n    \n                return child;\n            },\n    \n            /**\n             * 一个不做任何事情的方法。可以用来赋值给默认的callback.\n             * @method noop\n             */\n            noop: noop,\n    \n            /**\n             * 返回一个新的方法，此方法将已指定的`context`来执行。\n             * @grammar Base.bindFn( fn, context ) => Function\n             * @method bindFn\n             * @example\n             * var doSomething = function() {\n             *         console.log( this.name );\n             *     },\n             *     obj = {\n             *         name: 'Object Name'\n             *     },\n             *     aliasFn = Base.bind( doSomething, obj );\n             *\n             *  aliasFn();    // => Object Name\n             *\n             */\n            bindFn: bindFn,\n    \n            /**\n             * 引用Console.log如果存在的话，否则引用一个[空函数loop](#WebUploader:Base.log)。\n             * @grammar Base.log( args... ) => undefined\n             * @method log\n             */\n            log: (function() {\n                if ( window.console ) {\n                    return bindFn( console.log, console );\n                }\n                return noop;\n            })(),\n    \n            nextTick: (function() {\n    \n                return function( cb ) {\n                    setTimeout( cb, 1 );\n                };\n    \n                // @bug 当浏览器不在当前窗口时就停了。\n                // var next = window.requestAnimationFrame ||\n                //     window.webkitRequestAnimationFrame ||\n                //     window.mozRequestAnimationFrame ||\n                //     function( cb ) {\n                //         window.setTimeout( cb, 1000 / 60 );\n                //     };\n    \n                // // fix: Uncaught TypeError: Illegal invocation\n                // return bindFn( next, window );\n            })(),\n    \n            /**\n             * 被[uncurrythis](http://www.2ality.com/2011/11/uncurrying-this.html)的数组slice方法。\n             * 将用来将非数组对象转化成数组对象。\n             * @grammar Base.slice( target, start[, end] ) => Array\n             * @method slice\n             * @example\n             * function doSomthing() {\n             *     var args = Base.slice( arguments, 1 );\n             *     console.log( args );\n             * }\n             *\n             * doSomthing( 'ignored', 'arg2', 'arg3' );    // => Array [\"arg2\", \"arg3\"]\n             */\n            slice: uncurryThis( [].slice ),\n    \n            /**\n             * 生成唯一的ID\n             * @method guid\n             * @grammar Base.guid() => String\n             * @grammar Base.guid( prefx ) => String\n             */\n            guid: (function() {\n                var counter = 0;\n    \n                return function( prefix ) {\n                    var guid = (+new Date()).toString( 32 ),\n                        i = 0;\n    \n                    for ( ; i < 5; i++ ) {\n                        guid += Math.floor( Math.random() * 65535 ).toString( 32 );\n                    }\n    \n                    return (prefix || 'wu_') + guid + (counter++).toString( 32 );\n                };\n            })(),\n    \n            /**\n             * 格式化文件大小, 输出成带单位的字符串\n             * @method formatSize\n             * @grammar Base.formatSize( size ) => String\n             * @grammar Base.formatSize( size, pointLength ) => String\n             * @grammar Base.formatSize( size, pointLength, units ) => String\n             * @param {Number} size 文件大小\n             * @param {Number} [pointLength=2] 精确到的小数点数。\n             * @param {Array} [units=[ 'B', 'K', 'M', 'G', 'TB' ]] 单位数组。从字节，到千字节，一直往上指定。如果单位数组里面只指定了到了K(千字节)，同时文件大小大于M, 此方法的输出将还是显示成多少K.\n             * @example\n             * console.log( Base.formatSize( 100 ) );    // => 100B\n             * console.log( Base.formatSize( 1024 ) );    // => 1.00K\n             * console.log( Base.formatSize( 1024, 0 ) );    // => 1K\n             * console.log( Base.formatSize( 1024 * 1024 ) );    // => 1.00M\n             * console.log( Base.formatSize( 1024 * 1024 * 1024 ) );    // => 1.00G\n             * console.log( Base.formatSize( 1024 * 1024 * 1024, 0, ['B', 'KB', 'MB'] ) );    // => 1024MB\n             */\n            formatSize: function( size, pointLength, units ) {\n                var unit;\n    \n                units = units || [ 'B', 'K', 'M', 'G', 'TB' ];\n    \n                while ( (unit = units.shift()) && size > 1024 ) {\n                    size = size / 1024;\n                }\n    \n                return (unit === 'B' ? size : size.toFixed( pointLength || 2 )) +\n                        unit;\n            }\n        };\n    });\n    /**\n     * 事件处理类，可以独立使用，也可以扩展给对象使用。\n     * @fileOverview Mediator\n     */\n    define('mediator',[\n        'base'\n    ], function( Base ) {\n        var $ = Base.$,\n            slice = [].slice,\n            separator = /\\s+/,\n            protos;\n    \n        // 根据条件过滤出事件handlers.\n        function findHandlers( arr, name, callback, context ) {\n            return $.grep( arr, function( handler ) {\n                return handler &&\n                        (!name || handler.e === name) &&\n                        (!callback || handler.cb === callback ||\n                        handler.cb._cb === callback) &&\n                        (!context || handler.ctx === context);\n            });\n        }\n    \n        function eachEvent( events, callback, iterator ) {\n            // 不支持对象，只支持多个event用空格隔开\n            $.each( (events || '').split( separator ), function( _, key ) {\n                iterator( key, callback );\n            });\n        }\n    \n        function triggerHanders( events, args ) {\n            var stoped = false,\n                i = -1,\n                len = events.length,\n                handler;\n    \n            while ( ++i < len ) {\n                handler = events[ i ];\n    \n                if ( handler.cb.apply( handler.ctx2, args ) === false ) {\n                    stoped = true;\n                    break;\n                }\n            }\n    \n            return !stoped;\n        }\n    \n        protos = {\n    \n            /**\n             * 绑定事件。\n             *\n             * `callback`方法在执行时，arguments将会来源于trigger的时候携带的参数。如\n             * ```javascript\n             * var obj = {};\n             *\n             * // 使得obj有事件行为\n             * Mediator.installTo( obj );\n             *\n             * obj.on( 'testa', function( arg1, arg2 ) {\n             *     console.log( arg1, arg2 ); // => 'arg1', 'arg2'\n             * });\n             *\n             * obj.trigger( 'testa', 'arg1', 'arg2' );\n             * ```\n             *\n             * 如果`callback`中，某一个方法`return false`了，则后续的其他`callback`都不会被执行到。\n             * 切会影响到`trigger`方法的返回值，为`false`。\n             *\n             * `on`还可以用来添加一个特殊事件`all`, 这样所有的事件触发都会响应到。同时此类`callback`中的arguments有一个不同处，\n             * 就是第一个参数为`type`，记录当前是什么事件在触发。此类`callback`的优先级比脚低，会再正常`callback`执行完后触发。\n             * ```javascript\n             * obj.on( 'all', function( type, arg1, arg2 ) {\n             *     console.log( type, arg1, arg2 ); // => 'testa', 'arg1', 'arg2'\n             * });\n             * ```\n             *\n             * @method on\n             * @grammar on( name, callback[, context] ) => self\n             * @param  {String}   name     事件名，支持多个事件用空格隔开\n             * @param  {Function} callback 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             * @class Mediator\n             */\n            on: function( name, callback, context ) {\n                var me = this,\n                    set;\n    \n                if ( !callback ) {\n                    return this;\n                }\n    \n                set = this._events || (this._events = []);\n    \n                eachEvent( name, callback, function( name, callback ) {\n                    var handler = { e: name };\n    \n                    handler.cb = callback;\n                    handler.ctx = context;\n                    handler.ctx2 = context || me;\n                    handler.id = set.length;\n    \n                    set.push( handler );\n                });\n    \n                return this;\n            },\n    \n            /**\n             * 绑定事件，且当handler执行完后，自动解除绑定。\n             * @method once\n             * @grammar once( name, callback[, context] ) => self\n             * @param  {String}   name     事件名\n             * @param  {Function} callback 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             */\n            once: function( name, callback, context ) {\n                var me = this;\n    \n                if ( !callback ) {\n                    return me;\n                }\n    \n                eachEvent( name, callback, function( name, callback ) {\n                    var once = function() {\n                            me.off( name, once );\n                            return callback.apply( context || me, arguments );\n                        };\n    \n                    once._cb = callback;\n                    me.on( name, once, context );\n                });\n    \n                return me;\n            },\n    \n            /**\n             * 解除事件绑定\n             * @method off\n             * @grammar off( [name[, callback[, context] ] ] ) => self\n             * @param  {String}   [name]     事件名\n             * @param  {Function} [callback] 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             */\n            off: function( name, cb, ctx ) {\n                var events = this._events;\n    \n                if ( !events ) {\n                    return this;\n                }\n    \n                if ( !name && !cb && !ctx ) {\n                    this._events = [];\n                    return this;\n                }\n    \n                eachEvent( name, cb, function( name, cb ) {\n                    $.each( findHandlers( events, name, cb, ctx ), function() {\n                        delete events[ this.id ];\n                    });\n                });\n    \n                return this;\n            },\n    \n            /**\n             * 触发事件\n             * @method trigger\n             * @grammar trigger( name[, args...] ) => self\n             * @param  {String}   type     事件名\n             * @param  {*} [...] 任意参数\n             * @return {Boolean} 如果handler中return false了，则返回false, 否则返回true\n             */\n            trigger: function( type ) {\n                var args, events, allEvents;\n    \n                if ( !this._events || !type ) {\n                    return this;\n                }\n    \n                args = slice.call( arguments, 1 );\n                events = findHandlers( this._events, type );\n                allEvents = findHandlers( this._events, 'all' );\n    \n                return triggerHanders( events, args ) &&\n                        triggerHanders( allEvents, arguments );\n            }\n        };\n    \n        /**\n         * 中介者，它本身是个单例，但可以通过[installTo](#WebUploader:Mediator:installTo)方法，使任何对象具备事件行为。\n         * 主要目的是负责模块与模块之间的合作，降低耦合度。\n         *\n         * @class Mediator\n         */\n        return $.extend({\n    \n            /**\n             * 可以通过这个接口，使任何对象具备事件功能。\n             * @method installTo\n             * @param  {Object} obj 需要具备事件行为的对象。\n             * @return {Object} 返回obj.\n             */\n            installTo: function( obj ) {\n                return $.extend( obj, protos );\n            }\n    \n        }, protos );\n    });\n    /**\n     * @fileOverview Uploader上传类\n     */\n    define('uploader',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$;\n    \n        /**\n         * 上传入口类。\n         * @class Uploader\n         * @constructor\n         * @grammar new Uploader( opts ) => Uploader\n         * @example\n         * var uploader = WebUploader.Uploader({\n         *     swf: 'path_of_swf/Uploader.swf',\n         *\n         *     // 开起分片上传。\n         *     chunked: true\n         * });\n         */\n        function Uploader( opts ) {\n            this.options = $.extend( true, {}, Uploader.options, opts );\n            this._init( this.options );\n        }\n    \n        // default Options\n        // widgets中有相应扩展\n        Uploader.options = {};\n        Mediator.installTo( Uploader.prototype );\n    \n        // 批量添加纯命令式方法。\n        $.each({\n            upload: 'start-upload',\n            stop: 'stop-upload',\n            getFile: 'get-file',\n            getFiles: 'get-files',\n            addFile: 'add-file',\n            addFiles: 'add-file',\n            sort: 'sort-files',\n            removeFile: 'remove-file',\n            skipFile: 'skip-file',\n            retry: 'retry',\n            isInProgress: 'is-in-progress',\n            makeThumb: 'make-thumb',\n            getDimension: 'get-dimension',\n            addButton: 'add-btn',\n            getRuntimeType: 'get-runtime-type',\n            refresh: 'refresh',\n            disable: 'disable',\n            enable: 'enable',\n            reset: 'reset'\n        }, function( fn, command ) {\n            Uploader.prototype[ fn ] = function() {\n                return this.request( command, arguments );\n            };\n        });\n    \n        $.extend( Uploader.prototype, {\n            state: 'pending',\n    \n            _init: function( opts ) {\n                var me = this;\n    \n                me.request( 'init', opts, function() {\n                    me.state = 'ready';\n                    me.trigger('ready');\n                });\n            },\n    \n            /**\n             * 获取或者设置Uploader配置项。\n             * @method option\n             * @grammar option( key ) => *\n             * @grammar option( key, val ) => self\n             * @example\n             *\n             * // 初始状态图片上传前不会压缩\n             * var uploader = new WebUploader.Uploader({\n             *     resize: null;\n             * });\n             *\n             * // 修改后图片上传前，尝试将图片压缩到1600 * 1600\n             * uploader.options( 'resize', {\n             *     width: 1600,\n             *     height: 1600\n             * });\n             */\n            option: function( key, val ) {\n                var opts = this.options;\n    \n                // setter\n                if ( arguments.length > 1 ) {\n    \n                    if ( $.isPlainObject( val ) &&\n                            $.isPlainObject( opts[ key ] ) ) {\n                        $.extend( opts[ key ], val );\n                    } else {\n                        opts[ key ] = val;\n                    }\n    \n                } else {    // getter\n                    return key ? opts[ key ] : opts;\n                }\n            },\n    \n            /**\n             * 获取文件统计信息。返回一个包含一下信息的对象。\n             * * `successNum` 上传成功的文件数\n             * * `uploadFailNum` 上传失败的文件数\n             * * `cancelNum` 被删除的文件数\n             * * `invalidNum` 无效的文件数\n             * * `queueNum` 还在队列中的文件数\n             * @method getStats\n             * @grammar getStats() => Object\n             */\n            getStats: function() {\n                // return this._mgr.getStats.apply( this._mgr, arguments );\n                var stats = this.request('get-stats');\n    \n                return {\n                    successNum: stats.numOfSuccess,\n    \n                    // who care?\n                    // queueFailNum: 0,\n                    cancelNum: stats.numOfCancel,\n                    invalidNum: stats.numOfInvalid,\n                    uploadFailNum: stats.numOfUploadFailed,\n                    queueNum: stats.numOfQueue\n                };\n            },\n    \n            // 需要重写此方法来来支持opts.onEvent和instance.onEvent的处理器\n            trigger: function( type/*, args...*/ ) {\n                var args = [].slice.call( arguments, 1 ),\n                    opts = this.options,\n                    name = 'on' + type.substring( 0, 1 ).toUpperCase() +\n                        type.substring( 1 );\n    \n                if (\n                        // 调用通过on方法注册的handler.\n                        Mediator.trigger.apply( this, arguments ) === false ||\n    \n                        // 调用opts.onEvent\n                        $.isFunction( opts[ name ] ) &&\n                        opts[ name ].apply( this, args ) === false ||\n    \n                        // 调用this.onEvent\n                        $.isFunction( this[ name ] ) &&\n                        this[ name ].apply( this, args ) === false ||\n    \n                        // 广播所有uploader的事件。\n                        Mediator.trigger.apply( Mediator,\n                        [ this, type ].concat( args ) ) === false ) {\n    \n                    return false;\n                }\n    \n                return true;\n            },\n    \n            // widgets/widget.js将补充此方法的详细文档。\n            request: Base.noop\n        });\n    \n        /**\n         * 创建Uploader实例，等同于new Uploader( opts );\n         * @method create\n         * @class Base\n         * @static\n         * @grammar Base.create( opts ) => Uploader\n         */\n        Base.create = Uploader.create = function( opts ) {\n            return new Uploader( opts );\n        };\n    \n        // 暴露Uploader，可以通过它来扩展业务逻辑。\n        Base.Uploader = Uploader;\n    \n        return Uploader;\n    });\n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/runtime',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$,\n            factories = {},\n    \n            // 获取对象的第一个key\n            getFirstKey = function( obj ) {\n                for ( var key in obj ) {\n                    if ( obj.hasOwnProperty( key ) ) {\n                        return key;\n                    }\n                }\n                return null;\n            };\n    \n        // 接口类。\n        function Runtime( options ) {\n            this.options = $.extend({\n                container: document.body\n            }, options );\n            this.uid = Base.guid('rt_');\n        }\n    \n        $.extend( Runtime.prototype, {\n    \n            getContainer: function() {\n                var opts = this.options,\n                    parent, container;\n    \n                if ( this._container ) {\n                    return this._container;\n                }\n    \n                parent = $( opts.container || document.body );\n                container = $( document.createElement('div') );\n    \n                container.attr( 'id', 'rt_' + this.uid );\n                container.css({\n                    position: 'absolute',\n                    top: '0px',\n                    left: '0px',\n                    width: '1px',\n                    height: '1px',\n                    overflow: 'hidden'\n                });\n    \n                parent.append( container );\n                parent.addClass('webuploader-container');\n                this._container = container;\n                return container;\n            },\n    \n            init: Base.noop,\n            exec: Base.noop,\n    \n            destroy: function() {\n                if ( this._container ) {\n                    this._container.parentNode.removeChild( this.__container );\n                }\n    \n                this.off();\n            }\n        });\n    \n        Runtime.orders = 'html5,flash';\n    \n    \n        /**\n         * 添加Runtime实现。\n         * @param {String} type    类型\n         * @param {Runtime} factory 具体Runtime实现。\n         */\n        Runtime.addRuntime = function( type, factory ) {\n            factories[ type ] = factory;\n        };\n    \n        Runtime.hasRuntime = function( type ) {\n            return !!(type ? factories[ type ] : getFirstKey( factories ));\n        };\n    \n        Runtime.create = function( opts, orders ) {\n            var type, runtime;\n    \n            orders = orders || Runtime.orders;\n            $.each( orders.split( /\\s*,\\s*/g ), function() {\n                if ( factories[ this ] ) {\n                    type = this;\n                    return false;\n                }\n            });\n    \n            type = type || getFirstKey( factories );\n    \n            if ( !type ) {\n                throw new Error('Runtime Error');\n            }\n    \n            runtime = new factories[ type ]( opts );\n            return runtime;\n        };\n    \n        Mediator.installTo( Runtime.prototype );\n        return Runtime;\n    });\n    \n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/client',[\n        'base',\n        'mediator',\n        'runtime/runtime'\n    ], function( Base, Mediator, Runtime ) {\n    \n        var cache;\n    \n        cache = (function() {\n            var obj = {};\n    \n            return {\n                add: function( runtime ) {\n                    obj[ runtime.uid ] = runtime;\n                },\n    \n                get: function( ruid, standalone ) {\n                    var i;\n    \n                    if ( ruid ) {\n                        return obj[ ruid ];\n                    }\n    \n                    for ( i in obj ) {\n                        // 有些类型不能重用，比如filepicker.\n                        if ( standalone && obj[ i ].__standalone ) {\n                            continue;\n                        }\n    \n                        return obj[ i ];\n                    }\n    \n                    return null;\n                },\n    \n                remove: function( runtime ) {\n                    delete obj[ runtime.uid ];\n                }\n            };\n        })();\n    \n        function RuntimeClient( component, standalone ) {\n            var deferred = Base.Deferred(),\n                runtime;\n    \n            this.uid = Base.guid('client_');\n    \n            // 允许runtime没有初始化之前，注册一些方法在初始化后执行。\n            this.runtimeReady = function( cb ) {\n                return deferred.done( cb );\n            };\n    \n            this.connectRuntime = function( opts, cb ) {\n    \n                // already connected.\n                if ( runtime ) {\n                    throw new Error('already connected!');\n                }\n    \n                deferred.done( cb );\n    \n                if ( typeof opts === 'string' && cache.get( opts ) ) {\n                    runtime = cache.get( opts );\n                }\n    \n                // 像filePicker只能独立存在，不能公用。\n                runtime = runtime || cache.get( null, standalone );\n    \n                // 需要创建\n                if ( !runtime ) {\n                    runtime = Runtime.create( opts, opts.runtimeOrder );\n                    runtime.__promise = deferred.promise();\n                    runtime.once( 'ready', deferred.resolve );\n                    runtime.init();\n                    cache.add( runtime );\n                    runtime.__client = 1;\n                } else {\n                    // 来自cache\n                    Base.$.extend( runtime.options, opts );\n                    runtime.__promise.then( deferred.resolve );\n                    runtime.__client++;\n                }\n    \n                standalone && (runtime.__standalone = standalone);\n                return runtime;\n            };\n    \n            this.getRuntime = function() {\n                return runtime;\n            };\n    \n            this.disconnectRuntime = function() {\n                if ( !runtime ) {\n                    return;\n                }\n    \n                runtime.__client--;\n    \n                if ( runtime.__client <= 0 ) {\n                    cache.remove( runtime );\n                    delete runtime.__promise;\n                    runtime.destroy();\n                }\n    \n                runtime = null;\n            };\n    \n            this.exec = function() {\n                if ( !runtime ) {\n                    return;\n                }\n    \n                var args = Base.slice( arguments );\n                component && args.unshift( component );\n    \n                return runtime.exec.apply( this, args );\n            };\n    \n            this.getRuid = function() {\n                return runtime && runtime.uid;\n            };\n    \n            this.destroy = (function( destroy ) {\n                return function() {\n                    destroy && destroy.apply( this, arguments );\n                    this.trigger('destroy');\n                    this.off();\n                    this.exec('destroy');\n                    this.disconnectRuntime();\n                };\n            })( this.destroy );\n        }\n    \n        Mediator.installTo( RuntimeClient.prototype );\n        return RuntimeClient;\n    });\n    /**\n     * @fileOverview Blob\n     */\n    define('lib/blob',[\n        'base',\n        'runtime/client'\n    ], function( Base, RuntimeClient ) {\n    \n        function Blob( ruid, source ) {\n            var me = this;\n    \n            me.source = source;\n            me.ruid = ruid;\n    \n            RuntimeClient.call( me, 'Blob' );\n    \n            this.uid = source.uid || this.uid;\n            this.type = source.type || '';\n            this.size = source.size || 0;\n    \n            if ( ruid ) {\n                me.connectRuntime( ruid );\n            }\n        }\n    \n        Base.inherits( RuntimeClient, {\n            constructor: Blob,\n    \n            slice: function( start, end ) {\n                return this.exec( 'slice', start, end );\n            },\n    \n            getSource: function() {\n                return this.source;\n            }\n        });\n    \n        return Blob;\n    });\n    /**\n     * 为了统一化Flash的File和HTML5的File而存在。\n     * 以至于要调用Flash里面的File，也可以像调用HTML5版本的File一下。\n     * @fileOverview File\n     */\n    define('lib/file',[\n        'base',\n        'lib/blob'\n    ], function( Base, Blob ) {\n    \n        var uid = 1,\n            rExt = /\\.([^.]+)$/;\n    \n        function File( ruid, file ) {\n            var ext;\n    \n            Blob.apply( this, arguments );\n            this.name = file.name || ('untitled' + uid++);\n            ext = rExt.exec( file.name ) ? RegExp.$1.toLowerCase() : '';\n    \n            // todo 支持其他类型文件的转换。\n    \n            // 如果有mimetype, 但是文件名里面没有找出后缀规律\n            if ( !ext && this.type ) {\n                ext = /\\/(jpg|jpeg|png|gif|bmp)$/i.exec( this.type ) ?\n                        RegExp.$1.toLowerCase() : '';\n                this.name += '.' + ext;\n            }\n    \n            // 如果没有指定mimetype, 但是知道文件后缀。\n            if ( !this.type &&  ~'jpg,jpeg,png,gif,bmp'.indexOf( ext ) ) {\n                this.type = 'image/' + (ext === 'jpg' ? 'jpeg' : ext);\n            }\n    \n            this.ext = ext;\n            this.lastModifiedDate = file.lastModifiedDate ||\n                    (new Date()).toLocaleString();\n        }\n    \n        return Base.inherits( Blob, File );\n    });\n    \n    /**\n     * @fileOverview 错误信息\n     */\n    define('lib/filepicker',[\n        'base',\n        'runtime/client',\n        'lib/file'\n    ], function( Base, RuntimeClent, File ) {\n    \n        var $ = Base.$;\n    \n        function FilePicker( opts ) {\n            opts = this.options = $.extend({}, FilePicker.options, opts );\n    \n            opts.container = $( opts.id );\n    \n            if ( !opts.container.length ) {\n                throw new Error('按钮指定错误');\n            }\n    \n            opts.innerHTML = opts.innerHTML || opts.label ||\n                    opts.container.html() || '';\n    \n            opts.button = $( opts.button || document.createElement('div') );\n            opts.button.html( opts.innerHTML );\n            opts.container.html( opts.button );\n    \n            RuntimeClent.call( this, 'FilePicker', true );\n        }\n    \n        FilePicker.options = {\n            button: null,\n            container: null,\n            label: null,\n            innerHTML: null,\n            multiple: true,\n            accept: null,\n            name: 'file'\n        };\n    \n        Base.inherits( RuntimeClent, {\n            constructor: FilePicker,\n    \n            init: function() {\n                var me = this,\n                    opts = me.options,\n                    button = opts.button;\n    \n                button.addClass('webuploader-pick');\n    \n                me.on( 'all', function( type ) {\n                    var files;\n    \n                    switch ( type ) {\n                        case 'mouseenter':\n                            button.addClass('webuploader-pick-hover');\n                            break;\n    \n                        case 'mouseleave':\n                            button.removeClass('webuploader-pick-hover');\n                            break;\n    \n                        case 'change':\n                            files = me.exec('getFiles');\n                            me.trigger( 'select', $.map( files, function( file ) {\n                                file = new File( me.getRuid(), file );\n    \n                                // 记录来源。\n                                file._refer = opts.container;\n                                return file;\n                            }), opts.container );\n                            break;\n                    }\n                });\n    \n                me.connectRuntime( opts, function() {\n                    me.refresh();\n                    me.exec( 'init', opts );\n                    me.trigger('ready');\n                });\n    \n                $( window ).on( 'resize', function() {\n                    me.refresh();\n                });\n            },\n    \n            refresh: function() {\n                var shimContainer = this.getRuntime().getContainer(),\n                    button = this.options.button,\n                    width = button.outerWidth ?\n                            button.outerWidth() : button.width(),\n    \n                    height = button.outerHeight ?\n                            button.outerHeight() : button.height(),\n    \n                    pos = button.offset();\n    \n                width && height && shimContainer.css({\n                    bottom: 'auto',\n                    right: 'auto',\n                    width: width + 'px',\n                    height: height + 'px'\n                }).offset( pos );\n            },\n    \n            enable: function() {\n                var btn = this.options.button;\n    \n                btn.removeClass('webuploader-pick-disable');\n                this.refresh();\n            },\n    \n            disable: function() {\n                var btn = this.options.button;\n    \n                this.getRuntime().getContainer().css({\n                    top: '-99999px'\n                });\n    \n                btn.addClass('webuploader-pick-disable');\n            },\n    \n            destroy: function() {\n                if ( this.runtime ) {\n                    this.exec('destroy');\n                    this.disconnectRuntime();\n                }\n            }\n        });\n    \n        return FilePicker;\n    });\n    \n    /**\n     * @fileOverview 组件基类。\n     */\n    define('widgets/widget',[\n        'base',\n        'uploader'\n    ], function( Base, Uploader ) {\n    \n        var $ = Base.$,\n            _init = Uploader.prototype._init,\n            IGNORE = {},\n            widgetClass = [];\n    \n        function isArrayLike( obj ) {\n            if ( !obj ) {\n                return false;\n            }\n    \n            var length = obj.length,\n                type = $.type( obj );\n    \n            if ( obj.nodeType === 1 && length ) {\n                return true;\n            }\n    \n            return type === 'array' || type !== 'function' && type !== 'string' &&\n                    (length === 0 || typeof length === 'number' && length > 0 &&\n                    (length - 1) in obj);\n        }\n    \n        function Widget( uploader ) {\n            this.owner = uploader;\n            this.options = uploader.options;\n        }\n    \n        $.extend( Widget.prototype, {\n    \n            init: Base.noop,\n    \n            // 类Backbone的事件监听声明，监听uploader实例上的事件\n            // widget直接无法监听事件，事件只能通过uploader来传递\n            invoke: function( apiName, args ) {\n    \n                /*\n                    {\n                        'make-thumb': 'makeThumb'\n                    }\n                 */\n                var map = this.responseMap;\n    \n                // 如果无API响应声明则忽略\n                if ( !map || !(apiName in map) || !(map[ apiName ] in this) ||\n                        !$.isFunction( this[ map[ apiName ] ] ) ) {\n    \n                    return IGNORE;\n                }\n    \n                return this[ map[ apiName ] ].apply( this, args );\n    \n            },\n    \n            /**\n             * 发送命令。当传入`callback`或者`handler`中返回`promise`时。返回一个当所有`handler`中的promise都完成后完成的新`promise`。\n             * @method request\n             * @grammar request( command, args ) => * | Promise\n             * @grammar request( command, args, callback ) => Promise\n             * @for  Uploader\n             */\n            request: function() {\n                return this.owner.request.apply( this.owner, arguments );\n            }\n        });\n    \n        // 扩展Uploader.\n        $.extend( Uploader.prototype, {\n    \n            // 覆写_init用来初始化widgets\n            _init: function() {\n                var me = this,\n                    widgets = me._widgets = [];\n    \n                $.each( widgetClass, function( _, klass ) {\n                    widgets.push( new klass( me ) );\n                });\n    \n                return _init.apply( me, arguments );\n            },\n    \n            request: function( apiName, args, callback ) {\n                var i = 0,\n                    widgets = this._widgets,\n                    len = widgets.length,\n                    rlts = [],\n                    dfds = [],\n                    widget, rlt, promise, key;\n    \n                args = isArrayLike( args ) ? args : [ args ];\n    \n                for ( ; i < len; i++ ) {\n                    widget = widgets[ i ];\n                    rlt = widget.invoke( apiName, args );\n    \n                    if ( rlt !== IGNORE ) {\n    \n                        // Deferred对象\n                        if ( Base.isPromise( rlt ) ) {\n                            dfds.push( rlt );\n                        } else {\n                            rlts.push( rlt );\n                        }\n                    }\n                }\n    \n                // 如果有callback，则用异步方式。\n                if ( callback || dfds.length ) {\n                    promise = Base.when.apply( Base, dfds );\n                    key = promise.pipe ? 'pipe' : 'then';\n    \n                    // 很重要不能删除。删除了会死循环。\n                    // 保证执行顺序。让callback总是在下一个tick中执行。\n                    return promise[ key ](function() {\n                                var deferred = Base.Deferred(),\n                                    args = arguments;\n    \n                                setTimeout(function() {\n                                    deferred.resolve.apply( deferred, args );\n                                }, 1 );\n    \n                                return deferred.promise();\n                            })[ key ]( callback || Base.noop );\n                } else {\n                    return rlts[ 0 ];\n                }\n            }\n        });\n    \n        /**\n         * 添加组件\n         * @param  {object} widgetProto 组件原型，构造函数通过constructor属性定义\n         * @param  {object} responseMap API名称与函数实现的映射\n         * @example\n         *     Uploader.register( {\n         *         init: function( options ) {},\n         *         makeThumb: function() {}\n         *     }, {\n         *         'make-thumb': 'makeThumb'\n         *     } );\n         */\n        Uploader.register = Widget.register = function( responseMap, widgetProto ) {\n            var map = { init: 'init' },\n                klass;\n    \n            if ( arguments.length === 1 ) {\n                widgetProto = responseMap;\n                widgetProto.responseMap = map;\n            } else {\n                widgetProto.responseMap = $.extend( map, responseMap );\n            }\n    \n            klass = Base.inherits( Widget, widgetProto );\n            widgetClass.push( klass );\n    \n            return klass;\n        };\n    \n        return Widget;\n    });\n    /**\n     * @fileOverview 文件选择相关\n     */\n    define('widgets/filepicker',[\n        'base',\n        'uploader',\n        'lib/filepicker',\n        'widgets/widget'\n    ], function( Base, Uploader, FilePicker ) {\n        var $ = Base.$;\n    \n        $.extend( Uploader.options, {\n    \n            /**\n             * @property {Selector | Object} [pick=undefined]\n             * @namespace options\n             * @for Uploader\n             * @description 指定选择文件的按钮容器，不指定则不创建按钮。\n             *\n             * * `id` {Seletor} 指定选择文件的按钮容器，不指定则不创建按钮。\n             * * `label` {String} 请采用 `innerHTML` 代替\n             * * `innerHTML` {String} 指定按钮文字。不指定时优先从指定的容器中看是否自带文字。\n             * * `multiple` {Boolean} 是否开起同时选择多个文件能力。\n             */\n            pick: null,\n    \n            /**\n             * @property {Arroy} [accept=null]\n             * @namespace options\n             * @for Uploader\n             * @description 指定接受哪些类型的文件。 由于目前还有ext转mimeType表，所以这里需要分开指定。\n             *\n             * * `title` {String} 文字描述\n             * * `extensions` {String} 允许的文件后缀，不带点，多个用逗号分割。\n             * * `mimeTypes` {String} 多个用逗号分割。\n             *\n             * 如：\n             *\n             * ```\n             * {\n             *     title: 'Images',\n             *     extensions: 'gif,jpg,jpeg,bmp,png',\n             *     mimeTypes: 'image/*'\n             * }\n             * ```\n             */\n            accept: null/*{\n                title: 'Images',\n                extensions: 'gif,jpg,jpeg,bmp,png',\n                mimeTypes: 'image/*'\n            }*/\n        });\n    \n        return Uploader.register({\n            'add-btn': 'addButton',\n            refresh: 'refresh',\n            disable: 'disable',\n            enable: 'enable'\n        }, {\n    \n            init: function( opts ) {\n                this.pickers = [];\n                return opts.pick && this.addButton( opts.pick );\n            },\n    \n            refresh: function() {\n                $.each( this.pickers, function() {\n                    this.refresh();\n                });\n            },\n    \n            /**\n             * @method addButton\n             * @for Uploader\n             * @grammar addButton( pick ) => Promise\n             * @description\n             * 添加文件选择按钮，如果一个按钮不够，需要调用此方法来添加。参数跟[options.pick](#WebUploader:Uploader:options)一致。\n             * @example\n             * uploader.addButton({\n             *     id: '#btnContainer',\n             *     innerHTML: '选择文件'\n             * });\n             */\n            addButton: function( pick ) {\n                var me = this,\n                    opts = me.options,\n                    accept = opts.accept,\n                    options, picker, deferred;\n    \n                if ( !pick ) {\n                    return;\n                }\n    \n                deferred = Base.Deferred();\n                $.isPlainObject( pick ) || (pick = {\n                    id: pick\n                });\n    \n                options = $.extend({}, pick, {\n                    accept: $.isPlainObject( accept ) ? [ accept ] : accept,\n                    swf: opts.swf,\n                    runtimeOrder: opts.runtimeOrder\n                });\n    \n                picker = new FilePicker( options );\n    \n                picker.once( 'ready', deferred.resolve );\n                picker.on( 'select', function( files ) {\n                    me.owner.request( 'add-file', [ files ]);\n                });\n                picker.init();\n    \n                this.pickers.push( picker );\n    \n                return deferred.promise();\n            },\n    \n            disable: function() {\n                $.each( this.pickers, function() {\n                    this.disable();\n                });\n            },\n    \n            enable: function() {\n                $.each( this.pickers, function() {\n                    this.enable();\n                });\n            }\n        });\n    });\n    /**\n     * @fileOverview Image\n     */\n    define('lib/image',[\n        'base',\n        'runtime/client',\n        'lib/blob'\n    ], function( Base, RuntimeClient, Blob ) {\n        var $ = Base.$;\n    \n        // 构造器。\n        function Image( opts ) {\n            this.options = $.extend({}, Image.options, opts );\n            RuntimeClient.call( this, 'Image' );\n    \n            this.on( 'load', function() {\n                this._info = this.exec('info');\n                this._meta = this.exec('meta');\n            });\n        }\n    \n        // 默认选项。\n        Image.options = {\n    \n            // 默认的图片处理质量\n            quality: 90,\n    \n            // 是否裁剪\n            crop: false,\n    \n            // 是否保留头部信息\n            preserveHeaders: true,\n    \n            // 是否允许放大。\n            allowMagnify: true\n        };\n    \n        // 继承RuntimeClient.\n        Base.inherits( RuntimeClient, {\n            constructor: Image,\n    \n            info: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._info = val;\n                    return this;\n                }\n    \n                // getter\n                return this._info;\n            },\n    \n            meta: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._meta = val;\n                    return this;\n                }\n    \n                // getter\n                return this._meta;\n            },\n    \n            loadFromBlob: function( blob ) {\n                var me = this,\n                    ruid = blob.getRuid();\n    \n                this.connectRuntime( ruid, function() {\n                    me.exec( 'init', me.options );\n                    me.exec( 'loadFromBlob', blob );\n                });\n            },\n    \n            resize: function() {\n                var args = Base.slice( arguments );\n                return this.exec.apply( this, [ 'resize' ].concat( args ) );\n            },\n    \n            getAsDataUrl: function( type ) {\n                return this.exec( 'getAsDataUrl', type );\n            },\n    \n            getAsBlob: function( type ) {\n                var blob = this.exec( 'getAsBlob', type );\n    \n                return new Blob( this.getRuid(), blob );\n            }\n        });\n    \n        return Image;\n    });\n    /**\n     * @fileOverview 图片操作, 负责预览图片和上传前压缩图片\n     */\n    define('widgets/image',[\n        'base',\n        'uploader',\n        'lib/image',\n        'widgets/widget'\n    ], function( Base, Uploader, Image ) {\n    \n        var $ = Base.$,\n            throttle;\n    \n        // 根据要处理的文件大小来节流，一次不能处理太多，会卡。\n        throttle = (function( max ) {\n            var occupied = 0,\n                waiting = [],\n                tick = function() {\n                    var item;\n    \n                    while ( waiting.length && occupied < max ) {\n                        item = waiting.shift();\n                        occupied += item[ 0 ];\n                        item[ 1 ]();\n                    }\n                };\n    \n            return function( emiter, size, cb ) {\n                waiting.push([ size, cb ]);\n                emiter.once( 'destroy', function() {\n                    occupied -= size;\n                    setTimeout( tick, 1 );\n                });\n                setTimeout( tick, 1 );\n            };\n        })( 5 * 1024 * 1024 );\n    \n        $.extend( Uploader.options, {\n    \n            /**\n             * @property {Object} [thumb]\n             * @namespace options\n             * @for Uploader\n             * @description 配置生成缩略图的选项。\n             *\n             * 默认为：\n             *\n             * ```javascript\n             * {\n             *     width: 110,\n             *     height: 110,\n             *\n             *     // 图片质量，只有type为`image/jpeg`的时候才有效。\n             *     quality: 70,\n             *\n             *     // 是否允许放大，如果想要生成小图的时候不失真，此选项应该设置为false.\n             *     allowMagnify: true,\n             *\n             *     // 是否允许裁剪。\n             *     crop: true,\n             *\n             *     // 是否保留头部meta信息。\n             *     preserveHeaders: false,\n             *\n             *     // 为空的话则保留原有图片格式。\n             *     // 否则强制转换成指定的类型。\n             *     type: 'image/jpeg'\n             * }\n             * ```\n             */\n            thumb: {\n                width: 110,\n                height: 110,\n                quality: 70,\n                allowMagnify: true,\n                crop: true,\n                preserveHeaders: false,\n    \n                // 为空的话则保留原有图片格式。\n                // 否则强制转换成指定的类型。\n                // IE 8下面 base64 大小不能超过 32K 否则预览失败，而非 jpeg 编码的图片很可\n                // 能会超过 32k, 所以这里设置成预览的时候都是 image/jpeg\n                type: 'image/jpeg'\n            },\n    \n            /**\n             * @property {Object} [compress]\n             * @namespace options\n             * @for Uploader\n             * @description 配置压缩的图片的选项。如果此选项为`false`, 则图片在上传前不进行压缩。\n             *\n             * 默认为：\n             *\n             * ```javascript\n             * {\n             *     width: 1600,\n             *     height: 1600,\n             *\n             *     // 图片质量，只有type为`image/jpeg`的时候才有效。\n             *     quality: 90,\n             *\n             *     // 是否允许放大，如果想要生成小图的时候不失真，此选项应该设置为false.\n             *     allowMagnify: false,\n             *\n             *     // 是否允许裁剪。\n             *     crop: false,\n             *\n             *     // 是否保留头部meta信息。\n             *     preserveHeaders: true\n             * }\n             * ```\n             */\n            compress: {\n                width: 1600,\n                height: 1600,\n                quality: 90,\n                allowMagnify: false,\n                crop: false,\n                preserveHeaders: true\n            }\n        });\n    \n        return Uploader.register({\n            'make-thumb': 'makeThumb',\n            'before-send-file': 'compressImage'\n        }, {\n    \n    \n            /**\n             * 生成缩略图，此过程为异步，所以需要传入`callback`。\n             * 通常情况在图片加入队里后调用此方法来生成预览图以增强交互效果。\n             *\n             * `callback`中可以接收到两个参数。\n             * * 第一个为error，如果生成缩略图有错误，此error将为真。\n             * * 第二个为ret, 缩略图的Data URL值。\n             *\n             * **注意**\n             * Date URL在IE6/7中不支持，所以不用调用此方法了，直接显示一张暂不支持预览图片好了。\n             *\n             *\n             * @method makeThumb\n             * @grammar makeThumb( file, callback ) => undefined\n             * @grammar makeThumb( file, callback, width, height ) => undefined\n             * @for Uploader\n             * @example\n             *\n             * uploader.on( 'fileQueued', function( file ) {\n             *     var $li = ...;\n             *\n             *     uploader.makeThumb( file, function( error, ret ) {\n             *         if ( error ) {\n             *             $li.text('预览错误');\n             *         } else {\n             *             $li.append('<img alt=\"\" src=\"' + ret + '\" />');\n             *         }\n             *     });\n             *\n             * });\n             */\n            makeThumb: function( file, cb, width, height ) {\n                var opts, image;\n    \n                file = this.request( 'get-file', file );\n    \n                // 只预览图片格式。\n                if ( !file.type.match( /^image/ ) ) {\n                    cb( true );\n                    return;\n                }\n    \n                opts = $.extend({}, this.options.thumb );\n    \n                // 如果传入的是object.\n                if ( $.isPlainObject( width ) ) {\n                    opts = $.extend( opts, width );\n                    width = null;\n                }\n    \n                width = width || opts.width;\n                height = height || opts.height;\n    \n                image = new Image( opts );\n    \n                image.once( 'load', function() {\n                    file._info = file._info || image.info();\n                    file._meta = file._meta || image.meta();\n                    image.resize( width, height );\n                });\n    \n                image.once( 'complete', function() {\n                    cb( false, image.getAsDataUrl( opts.type ) );\n                    image.destroy();\n                });\n    \n                image.once( 'error', function() {\n                    cb( true );\n                    image.destroy();\n                });\n    \n                throttle( image, file.source.size, function() {\n                    file._info && image.info( file._info );\n                    file._meta && image.meta( file._meta );\n                    image.loadFromBlob( file.source );\n                });\n            },\n    \n            compressImage: function( file ) {\n                var opts = this.options.compress || this.options.resize,\n                    compressSize = opts && opts.compressSize || 300 * 1024,\n                    image, deferred;\n    \n                file = this.request( 'get-file', file );\n    \n                // 只预览图片格式。\n                if ( !opts || !~'image/jpeg,image/jpg'.indexOf( file.type ) ||\n                        file.size < compressSize ||\n                        file._compressed ) {\n                    return;\n                }\n    \n                opts = $.extend({}, opts );\n                deferred = Base.Deferred();\n    \n                image = new Image( opts );\n    \n                deferred.always(function() {\n                    image.destroy();\n                    image = null;\n                });\n                image.once( 'error', deferred.reject );\n                image.once( 'load', function() {\n                    file._info = file._info || image.info();\n                    file._meta = file._meta || image.meta();\n                    image.resize( opts.width, opts.height );\n                });\n    \n                image.once( 'complete', function() {\n                    var blob, size;\n    \n                    // 移动端 UC / qq 浏览器的无图模式下\n                    // ctx.getImageData 处理大图的时候会报 Exception\n                    // INDEX_SIZE_ERR: DOM Exception 1\n                    try {\n                        blob = image.getAsBlob( opts.type );\n    \n                        size = file.size;\n    \n                        // 如果压缩后，比原来还大则不用压缩后的。\n                        if ( blob.size < size ) {\n                            // file.source.destroy && file.source.destroy();\n                            file.source = blob;\n                            file.size = blob.size;\n    \n                            file.trigger( 'resize', blob.size, size );\n                        }\n    \n                        // 标记，避免重复压缩。\n                        file._compressed = true;\n                        deferred.resolve();\n                    } catch ( e ) {\n                        // 出错了直接继续，让其上传原始图片\n                        deferred.resolve();\n                    }\n                });\n    \n                file._info && image.info( file._info );\n                file._meta && image.meta( file._meta );\n    \n                image.loadFromBlob( file.source );\n                return deferred.promise();\n            }\n        });\n    });\n    /**\n     * @fileOverview 文件属性封装\n     */\n    define('file',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$,\n            idPrefix = 'WU_FILE_',\n            idSuffix = 0,\n            rExt = /\\.([^.]+)$/,\n            statusMap = {};\n    \n        function gid() {\n            return idPrefix + idSuffix++;\n        }\n    \n        /**\n         * 文件类\n         * @class File\n         * @constructor 构造函数\n         * @grammar new File( source ) => File\n         * @param {Lib.File} source [lib.File](#Lib.File)实例, 此source对象是带有Runtime信息的。\n         */\n        function WUFile( source ) {\n    \n            /**\n             * 文件名，包括扩展名（后缀）\n             * @property name\n             * @type {string}\n             */\n            this.name = source.name || 'Untitled';\n    \n            /**\n             * 文件体积（字节）\n             * @property size\n             * @type {uint}\n             * @default 0\n             */\n            this.size = source.size || 0;\n    \n            /**\n             * 文件MIMETYPE类型，与文件类型的对应关系请参考[http://t.cn/z8ZnFny](http://t.cn/z8ZnFny)\n             * @property type\n             * @type {string}\n             * @default 'application'\n             */\n            this.type = source.type || 'application';\n    \n            /**\n             * 文件最后修改日期\n             * @property lastModifiedDate\n             * @type {int}\n             * @default 当前时间戳\n             */\n            this.lastModifiedDate = source.lastModifiedDate || (new Date() * 1);\n    \n            /**\n             * 文件ID，每个对象具有唯一ID，与文件名无关\n             * @property id\n             * @type {string}\n             */\n            this.id = gid();\n    \n            /**\n             * 文件扩展名，通过文件名获取，例如test.png的扩展名为png\n             * @property ext\n             * @type {string}\n             */\n            this.ext = rExt.exec( this.name ) ? RegExp.$1 : '';\n    \n    \n            /**\n             * 状态文字说明。在不同的status语境下有不同的用途。\n             * @property statusText\n             * @type {string}\n             */\n            this.statusText = '';\n    \n            // 存储文件状态，防止通过属性直接修改\n            statusMap[ this.id ] = WUFile.Status.INITED;\n    \n            this.source = source;\n            this.loaded = 0;\n    \n            this.on( 'error', function( msg ) {\n                this.setStatus( WUFile.Status.ERROR, msg );\n            });\n        }\n    \n        $.extend( WUFile.prototype, {\n    \n            /**\n             * 设置状态，状态变化时会触发`change`事件。\n             * @method setStatus\n             * @grammar setStatus( status[, statusText] );\n             * @param {File.Status|String} status [文件状态值](#WebUploader:File:File.Status)\n             * @param {String} [statusText=''] 状态说明，常在error时使用，用http, abort,server等来标记是由于什么原因导致文件错误。\n             */\n            setStatus: function( status, text ) {\n    \n                var prevStatus = statusMap[ this.id ];\n    \n                typeof text !== 'undefined' && (this.statusText = text);\n    \n                if ( status !== prevStatus ) {\n                    statusMap[ this.id ] = status;\n                    /**\n                     * 文件状态变化\n                     * @event statuschange\n                     */\n                    this.trigger( 'statuschange', status, prevStatus );\n                }\n    \n            },\n    \n            /**\n             * 获取文件状态\n             * @return {File.Status}\n             * @example\n                     文件状态具体包括以下几种类型：\n                     {\n                         // 初始化\n                        INITED:     0,\n                        // 已入队列\n                        QUEUED:     1,\n                        // 正在上传\n                        PROGRESS:     2,\n                        // 上传出错\n                        ERROR:         3,\n                        // 上传成功\n                        COMPLETE:     4,\n                        // 上传取消\n                        CANCELLED:     5\n                    }\n             */\n            getStatus: function() {\n                return statusMap[ this.id ];\n            },\n    \n            /**\n             * 获取文件原始信息。\n             * @return {*}\n             */\n            getSource: function() {\n                return this.source;\n            },\n    \n            destory: function() {\n                delete statusMap[ this.id ];\n            }\n        });\n    \n        Mediator.installTo( WUFile.prototype );\n    \n        /**\n         * 文件状态值，具体包括以下几种类型：\n         * * `inited` 初始状态\n         * * `queued` 已经进入队列, 等待上传\n         * * `progress` 上传中\n         * * `complete` 上传完成。\n         * * `error` 上传出错，可重试\n         * * `interrupt` 上传中断，可续传。\n         * * `invalid` 文件不合格，不能重试上传。会自动从队列中移除。\n         * * `cancelled` 文件被移除。\n         * @property {Object} Status\n         * @namespace File\n         * @class File\n         * @static\n         */\n        WUFile.Status = {\n            INITED:     'inited',    // 初始状态\n            QUEUED:     'queued',    // 已经进入队列, 等待上传\n            PROGRESS:   'progress',    // 上传中\n            ERROR:      'error',    // 上传出错，可重试\n            COMPLETE:   'complete',    // 上传完成。\n            CANCELLED:  'cancelled',    // 上传取消。\n            INTERRUPT:  'interrupt',    // 上传中断，可续传。\n            INVALID:    'invalid'    // 文件不合格，不能重试上传。\n        };\n    \n        return WUFile;\n    });\n    \n    /**\n     * @fileOverview 文件队列\n     */\n    define('queue',[\n        'base',\n        'mediator',\n        'file'\n    ], function( Base, Mediator, WUFile ) {\n    \n        var $ = Base.$,\n            STATUS = WUFile.Status;\n    \n        /**\n         * 文件队列, 用来存储各个状态中的文件。\n         * @class Queue\n         * @extends Mediator\n         */\n        function Queue() {\n    \n            /**\n             * 统计文件数。\n             * * `numOfQueue` 队列中的文件数。\n             * * `numOfSuccess` 上传成功的文件数\n             * * `numOfCancel` 被移除的文件数\n             * * `numOfProgress` 正在上传中的文件数\n             * * `numOfUploadFailed` 上传错误的文件数。\n             * * `numOfInvalid` 无效的文件数。\n             * @property {Object} stats\n             */\n            this.stats = {\n                numOfQueue: 0,\n                numOfSuccess: 0,\n                numOfCancel: 0,\n                numOfProgress: 0,\n                numOfUploadFailed: 0,\n                numOfInvalid: 0\n            };\n    \n            // 上传队列，仅包括等待上传的文件\n            this._queue = [];\n    \n            // 存储所有文件\n            this._map = {};\n        }\n    \n        $.extend( Queue.prototype, {\n    \n            /**\n             * 将新文件加入对队列尾部\n             *\n             * @method append\n             * @param  {File} file   文件对象\n             */\n            append: function( file ) {\n                this._queue.push( file );\n                this._fileAdded( file );\n                return this;\n            },\n    \n            /**\n             * 将新文件加入对队列头部\n             *\n             * @method prepend\n             * @param  {File} file   文件对象\n             */\n            prepend: function( file ) {\n                this._queue.unshift( file );\n                this._fileAdded( file );\n                return this;\n            },\n    \n            /**\n             * 获取文件对象\n             *\n             * @method getFile\n             * @param  {String} fileId   文件ID\n             * @return {File}\n             */\n            getFile: function( fileId ) {\n                if ( typeof fileId !== 'string' ) {\n                    return fileId;\n                }\n                return this._map[ fileId ];\n            },\n    \n            /**\n             * 从队列中取出一个指定状态的文件。\n             * @grammar fetch( status ) => File\n             * @method fetch\n             * @param {String} status [文件状态值](#WebUploader:File:File.Status)\n             * @return {File} [File](#WebUploader:File)\n             */\n            fetch: function( status ) {\n                var len = this._queue.length,\n                    i, file;\n    \n                status = status || STATUS.QUEUED;\n    \n                for ( i = 0; i < len; i++ ) {\n                    file = this._queue[ i ];\n    \n                    if ( status === file.getStatus() ) {\n                        return file;\n                    }\n                }\n    \n                return null;\n            },\n    \n            /**\n             * 对队列进行排序，能够控制文件上传顺序。\n             * @grammar sort( fn ) => undefined\n             * @method sort\n             * @param {Function} fn 排序方法\n             */\n            sort: function( fn ) {\n                if ( typeof fn === 'function' ) {\n                    this._queue.sort( fn );\n                }\n            },\n    \n            /**\n             * 获取指定类型的文件列表, 列表中每一个成员为[File](#WebUploader:File)对象。\n             * @grammar getFiles( [status1[, status2 ...]] ) => Array\n             * @method getFiles\n             * @param {String} [status] [文件状态值](#WebUploader:File:File.Status)\n             */\n            getFiles: function() {\n                var sts = [].slice.call( arguments, 0 ),\n                    ret = [],\n                    i = 0,\n                    len = this._queue.length,\n                    file;\n    \n                for ( ; i < len; i++ ) {\n                    file = this._queue[ i ];\n    \n                    if ( sts.length && !~$.inArray( file.getStatus(), sts ) ) {\n                        continue;\n                    }\n    \n                    ret.push( file );\n                }\n    \n                return ret;\n            },\n    \n            _fileAdded: function( file ) {\n                var me = this,\n                    existing = this._map[ file.id ];\n    \n                if ( !existing ) {\n                    this._map[ file.id ] = file;\n    \n                    file.on( 'statuschange', function( cur, pre ) {\n                        me._onFileStatusChange( cur, pre );\n                    });\n                }\n    \n                file.setStatus( STATUS.QUEUED );\n            },\n    \n            _onFileStatusChange: function( curStatus, preStatus ) {\n                var stats = this.stats;\n    \n                switch ( preStatus ) {\n                    case STATUS.PROGRESS:\n                        stats.numOfProgress--;\n                        break;\n    \n                    case STATUS.QUEUED:\n                        stats.numOfQueue --;\n                        break;\n    \n                    case STATUS.ERROR:\n                        stats.numOfUploadFailed--;\n                        break;\n    \n                    case STATUS.INVALID:\n                        stats.numOfInvalid--;\n                        break;\n                }\n    \n                switch ( curStatus ) {\n                    case STATUS.QUEUED:\n                        stats.numOfQueue++;\n                        break;\n    \n                    case STATUS.PROGRESS:\n                        stats.numOfProgress++;\n                        break;\n    \n                    case STATUS.ERROR:\n                        stats.numOfUploadFailed++;\n                        break;\n    \n                    case STATUS.COMPLETE:\n                        stats.numOfSuccess++;\n                        break;\n    \n                    case STATUS.CANCELLED:\n                        stats.numOfCancel++;\n                        break;\n    \n                    case STATUS.INVALID:\n                        stats.numOfInvalid++;\n                        break;\n                }\n            }\n    \n        });\n    \n        Mediator.installTo( Queue.prototype );\n    \n        return Queue;\n    });\n    /**\n     * @fileOverview 队列\n     */\n    define('widgets/queue',[\n        'base',\n        'uploader',\n        'queue',\n        'file',\n        'lib/file',\n        'runtime/client',\n        'widgets/widget'\n    ], function( Base, Uploader, Queue, WUFile, File, RuntimeClient ) {\n    \n        var $ = Base.$,\n            rExt = /\\.\\w+$/,\n            Status = WUFile.Status;\n    \n        return Uploader.register({\n            'sort-files': 'sortFiles',\n            'add-file': 'addFiles',\n            'get-file': 'getFile',\n            'fetch-file': 'fetchFile',\n            'get-stats': 'getStats',\n            'get-files': 'getFiles',\n            'remove-file': 'removeFile',\n            'retry': 'retry',\n            'reset': 'reset',\n            'accept-file': 'acceptFile'\n        }, {\n    \n            init: function( opts ) {\n                var me = this,\n                    deferred, len, i, item, arr, accept, runtime;\n    \n                if ( $.isPlainObject( opts.accept ) ) {\n                    opts.accept = [ opts.accept ];\n                }\n    \n                // accept中的中生成匹配正则。\n                if ( opts.accept ) {\n                    arr = [];\n    \n                    for ( i = 0, len = opts.accept.length; i < len; i++ ) {\n                        item = opts.accept[ i ].extensions;\n                        item && arr.push( item );\n                    }\n    \n                    if ( arr.length ) {\n                        accept = '\\\\.' + arr.join(',')\n                                .replace( /,/g, '$|\\\\.' )\n                                .replace( /\\*/g, '.*' ) + '$';\n                    }\n    \n                    me.accept = new RegExp( accept, 'i' );\n                }\n    \n                me.queue = new Queue();\n                me.stats = me.queue.stats;\n    \n                // 如果当前不是html5运行时，那就算了。\n                // 不执行后续操作\n                if ( this.request('predict-runtime-type') !== 'html5' ) {\n                    return;\n                }\n    \n                // 创建一个 html5 运行时的 placeholder\n                // 以至于外部添加原生 File 对象的时候能正确包裹一下供 webuploader 使用。\n                deferred = Base.Deferred();\n                runtime = new RuntimeClient('Placeholder');\n                runtime.connectRuntime({\n                    runtimeOrder: 'html5'\n                }, function() {\n                    me._ruid = runtime.getRuid();\n                    deferred.resolve();\n                });\n                return deferred.promise();\n            },\n    \n    \n            // 为了支持外部直接添加一个原生File对象。\n            _wrapFile: function( file ) {\n                if ( !(file instanceof WUFile) ) {\n    \n                    if ( !(file instanceof File) ) {\n                        if ( !this._ruid ) {\n                            throw new Error('Can\\'t add external files.');\n                        }\n                        file = new File( this._ruid, file );\n                    }\n    \n                    file = new WUFile( file );\n                }\n    \n                return file;\n            },\n    \n            // 判断文件是否可以被加入队列\n            acceptFile: function( file ) {\n                var invalid = !file || file.size < 6 || this.accept &&\n    \n                        // 如果名字中有后缀，才做后缀白名单处理。\n                        rExt.exec( file.name ) && !this.accept.test( file.name );\n    \n                return !invalid;\n            },\n    \n    \n            /**\n             * @event beforeFileQueued\n             * @param {File} file File对象\n             * @description 当文件被加入队列之前触发，此事件的handler返回值为`false`，则此文件不会被添加进入队列。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event fileQueued\n             * @param {File} file File对象\n             * @description 当文件被加入队列以后触发。\n             * @for  Uploader\n             */\n    \n            _addFile: function( file ) {\n                var me = this;\n    \n                file = me._wrapFile( file );\n    \n                // 不过类型判断允许不允许，先派送 `beforeFileQueued`\n                if ( !me.owner.trigger( 'beforeFileQueued', file ) ) {\n                    return;\n                }\n    \n                // 类型不匹配，则派送错误事件，并返回。\n                if ( !me.acceptFile( file ) ) {\n                    me.owner.trigger( 'error', 'Q_TYPE_DENIED', file );\n                    return;\n                }\n    \n                me.queue.append( file );\n                me.owner.trigger( 'fileQueued', file );\n                return file;\n            },\n    \n            getFile: function( fileId ) {\n                return this.queue.getFile( fileId );\n            },\n    \n            /**\n             * @event filesQueued\n             * @param {File} files 数组，内容为原始File(lib/File）对象。\n             * @description 当一批文件添加进队列以后触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @method addFiles\n             * @grammar addFiles( file ) => undefined\n             * @grammar addFiles( [file1, file2 ...] ) => undefined\n             * @param {Array of File or File} [files] Files 对象 数组\n             * @description 添加文件到队列\n             * @for  Uploader\n             */\n            addFiles: function( files ) {\n                var me = this;\n    \n                if ( !files.length ) {\n                    files = [ files ];\n                }\n    \n                files = $.map( files, function( file ) {\n                    return me._addFile( file );\n                });\n    \n                me.owner.trigger( 'filesQueued', files );\n    \n                if ( me.options.auto ) {\n                    me.request('start-upload');\n                }\n            },\n    \n            getStats: function() {\n                return this.stats;\n            },\n    \n            /**\n             * @event fileDequeued\n             * @param {File} file File对象\n             * @description 当文件被移除队列后触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @method removeFile\n             * @grammar removeFile( file ) => undefined\n             * @grammar removeFile( id ) => undefined\n             * @param {File|id} file File对象或这File对象的id\n             * @description 移除某一文件。\n             * @for  Uploader\n             * @example\n             *\n             * $li.on('click', '.remove-this', function() {\n             *     uploader.removeFile( file );\n             * })\n             */\n            removeFile: function( file ) {\n                var me = this;\n    \n                file = file.id ? file : me.queue.getFile( file );\n    \n                file.setStatus( Status.CANCELLED );\n                me.owner.trigger( 'fileDequeued', file );\n            },\n    \n            /**\n             * @method getFiles\n             * @grammar getFiles() => Array\n             * @grammar getFiles( status1, status2, status... ) => Array\n             * @description 返回指定状态的文件集合，不传参数将返回所有状态的文件。\n             * @for  Uploader\n             * @example\n             * console.log( uploader.getFiles() );    // => all files\n             * console.log( uploader.getFiles('error') )    // => all error files.\n             */\n            getFiles: function() {\n                return this.queue.getFiles.apply( this.queue, arguments );\n            },\n    \n            fetchFile: function() {\n                return this.queue.fetch.apply( this.queue, arguments );\n            },\n    \n            /**\n             * @method retry\n             * @grammar retry() => undefined\n             * @grammar retry( file ) => undefined\n             * @description 重试上传，重试指定文件，或者从出错的文件开始重新上传。\n             * @for  Uploader\n             * @example\n             * function retry() {\n             *     uploader.retry();\n             * }\n             */\n            retry: function( file, noForceStart ) {\n                var me = this,\n                    files, i, len;\n    \n                if ( file ) {\n                    file = file.id ? file : me.queue.getFile( file );\n                    file.setStatus( Status.QUEUED );\n                    noForceStart || me.request('start-upload');\n                    return;\n                }\n    \n                files = me.queue.getFiles( Status.ERROR );\n                i = 0;\n                len = files.length;\n    \n                for ( ; i < len; i++ ) {\n                    file = files[ i ];\n                    file.setStatus( Status.QUEUED );\n                }\n    \n                me.request('start-upload');\n            },\n    \n            /**\n             * @method sort\n             * @grammar sort( fn ) => undefined\n             * @description 排序队列中的文件，在上传之前调整可以控制上传顺序。\n             * @for  Uploader\n             */\n            sortFiles: function() {\n                return this.queue.sort.apply( this.queue, arguments );\n            },\n    \n            /**\n             * @method reset\n             * @grammar reset() => undefined\n             * @description 重置uploader。目前只重置了队列。\n             * @for  Uploader\n             * @example\n             * uploader.reset();\n             */\n            reset: function() {\n                this.queue = new Queue();\n                this.stats = this.queue.stats;\n            }\n        });\n    \n    });\n    /**\n     * @fileOverview 添加获取Runtime相关信息的方法。\n     */\n    define('widgets/runtime',[\n        'uploader',\n        'runtime/runtime',\n        'widgets/widget'\n    ], function( Uploader, Runtime ) {\n    \n        Uploader.support = function() {\n            return Runtime.hasRuntime.apply( Runtime, arguments );\n        };\n    \n        return Uploader.register({\n            'predict-runtime-type': 'predictRuntmeType'\n        }, {\n    \n            init: function() {\n                if ( !this.predictRuntmeType() ) {\n                    throw Error('Runtime Error');\n                }\n            },\n    \n            /**\n             * 预测Uploader将采用哪个`Runtime`\n             * @grammar predictRuntmeType() => String\n             * @method predictRuntmeType\n             * @for  Uploader\n             */\n            predictRuntmeType: function() {\n                var orders = this.options.runtimeOrder || Runtime.orders,\n                    type = this.type,\n                    i, len;\n    \n                if ( !type ) {\n                    orders = orders.split( /\\s*,\\s*/g );\n    \n                    for ( i = 0, len = orders.length; i < len; i++ ) {\n                        if ( Runtime.hasRuntime( orders[ i ] ) ) {\n                            this.type = type = orders[ i ];\n                            break;\n                        }\n                    }\n                }\n    \n                return type;\n            }\n        });\n    });\n    /**\n     * @fileOverview Transport\n     */\n    define('lib/transport',[\n        'base',\n        'runtime/client',\n        'mediator'\n    ], function( Base, RuntimeClient, Mediator ) {\n    \n        var $ = Base.$;\n    \n        function Transport( opts ) {\n            var me = this;\n    \n            opts = me.options = $.extend( true, {}, Transport.options, opts || {} );\n            RuntimeClient.call( this, 'Transport' );\n    \n            this._blob = null;\n            this._formData = opts.formData || {};\n            this._headers = opts.headers || {};\n    \n            this.on( 'progress', this._timeout );\n            this.on( 'load error', function() {\n                me.trigger( 'progress', 1 );\n                clearTimeout( me._timer );\n            });\n        }\n    \n        Transport.options = {\n            server: '',\n            method: 'POST',\n    \n            // 跨域时，是否允许携带cookie, 只有html5 runtime才有效\n            withCredentials: false,\n            fileVal: 'file',\n            timeout: 2 * 60 * 1000,    // 2分钟\n            formData: {},\n            headers: {},\n            sendAsBinary: false\n        };\n    \n        $.extend( Transport.prototype, {\n    \n            // 添加Blob, 只能添加一次，最后一次有效。\n            appendBlob: function( key, blob, filename ) {\n                var me = this,\n                    opts = me.options;\n    \n                if ( me.getRuid() ) {\n                    me.disconnectRuntime();\n                }\n    \n                // 连接到blob归属的同一个runtime.\n                me.connectRuntime( blob.ruid, function() {\n                    me.exec('init');\n                });\n    \n                me._blob = blob;\n                opts.fileVal = key || opts.fileVal;\n                opts.filename = filename || opts.filename;\n            },\n    \n            // 添加其他字段\n            append: function( key, value ) {\n                if ( typeof key === 'object' ) {\n                    $.extend( this._formData, key );\n                } else {\n                    this._formData[ key ] = value;\n                }\n            },\n    \n            setRequestHeader: function( key, value ) {\n                if ( typeof key === 'object' ) {\n                    $.extend( this._headers, key );\n                } else {\n                    this._headers[ key ] = value;\n                }\n            },\n    \n            send: function( method ) {\n                this.exec( 'send', method );\n                this._timeout();\n            },\n    \n            abort: function() {\n                clearTimeout( this._timer );\n                return this.exec('abort');\n            },\n    \n            destroy: function() {\n                this.trigger('destroy');\n                this.off();\n                this.exec('destroy');\n                this.disconnectRuntime();\n            },\n    \n            getResponse: function() {\n                return this.exec('getResponse');\n            },\n    \n            getResponseAsJson: function() {\n                return this.exec('getResponseAsJson');\n            },\n    \n            getStatus: function() {\n                return this.exec('getStatus');\n            },\n    \n            _timeout: function() {\n                var me = this,\n                    duration = me.options.timeout;\n    \n                if ( !duration ) {\n                    return;\n                }\n    \n                clearTimeout( me._timer );\n                me._timer = setTimeout(function() {\n                    me.abort();\n                    me.trigger( 'error', 'timeout' );\n                }, duration );\n            }\n    \n        });\n    \n        // 让Transport具备事件功能。\n        Mediator.installTo( Transport.prototype );\n    \n        return Transport;\n    });\n    /**\n     * @fileOverview 负责文件上传相关。\n     */\n    define('widgets/upload',[\n        'base',\n        'uploader',\n        'file',\n        'lib/transport',\n        'widgets/widget'\n    ], function( Base, Uploader, WUFile, Transport ) {\n    \n        var $ = Base.$,\n            isPromise = Base.isPromise,\n            Status = WUFile.Status;\n    \n        // 添加默认配置项\n        $.extend( Uploader.options, {\n    \n    \n            /**\n             * @property {Boolean} [prepareNextFile=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否允许在文件传输时提前把下一个文件准备好。\n             * 对于一个文件的准备工作比较耗时，比如图片压缩，md5序列化。\n             * 如果能提前在当前文件传输期处理，可以节省总体耗时。\n             */\n            prepareNextFile: false,\n    \n            /**\n             * @property {Boolean} [chunked=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否要分片处理大文件上传。\n             */\n            chunked: false,\n    \n            /**\n             * @property {Boolean} [chunkSize=5242880]\n             * @namespace options\n             * @for Uploader\n             * @description 如果要分片，分多大一片？ 默认大小为5M.\n             */\n            chunkSize: 5 * 1024 * 1024,\n    \n            /**\n             * @property {Boolean} [chunkRetry=2]\n             * @namespace options\n             * @for Uploader\n             * @description 如果某个分片由于网络问题出错，允许自动重传多少次？\n             */\n            chunkRetry: 2,\n    \n            /**\n             * @property {Boolean} [threads=3]\n             * @namespace options\n             * @for Uploader\n             * @description 上传并发数。允许同时最大上传进程数。\n             */\n            threads: 3,\n    \n    \n            /**\n             * @property {Object} [formData]\n             * @namespace options\n             * @for Uploader\n             * @description 文件上传请求的参数表，每次发送都会发送此对象中的参数。\n             */\n            formData: null\n    \n            /**\n             * @property {Object} [fileVal='file']\n             * @namespace options\n             * @for Uploader\n             * @description 设置文件上传域的name。\n             */\n    \n            /**\n             * @property {Object} [method='POST']\n             * @namespace options\n             * @for Uploader\n             * @description 文件上传方式，`POST`或者`GET`。\n             */\n    \n            /**\n             * @property {Object} [sendAsBinary=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否已二进制的流的方式发送文件，这样整个上传内容`php://input`都为文件内容，\n             * 其他参数在$_GET数组中。\n             */\n        });\n    \n        // 负责将文件切片。\n        function CuteFile( file, chunkSize ) {\n            var pending = [],\n                blob = file.source,\n                total = blob.size,\n                chunks = chunkSize ? Math.ceil( total / chunkSize ) : 1,\n                start = 0,\n                index = 0,\n                len;\n    \n            while ( index < chunks ) {\n                len = Math.min( chunkSize, total - start );\n    \n                pending.push({\n                    file: file,\n                    start: start,\n                    end: chunkSize ? (start + len) : total,\n                    total: total,\n                    chunks: chunks,\n                    chunk: index++\n                });\n                start += len;\n            }\n    \n            file.blocks = pending.concat();\n            file.remaning = pending.length;\n    \n            return {\n                file: file,\n    \n                has: function() {\n                    return !!pending.length;\n                },\n    \n                fetch: function() {\n                    return pending.shift();\n                }\n            };\n        }\n    \n        Uploader.register({\n            'start-upload': 'start',\n            'stop-upload': 'stop',\n            'skip-file': 'skipFile',\n            'is-in-progress': 'isInProgress'\n        }, {\n    \n            init: function() {\n                var owner = this.owner;\n    \n                this.runing = false;\n    \n                // 记录当前正在传的数据，跟threads相关\n                this.pool = [];\n    \n                // 缓存即将上传的文件。\n                this.pending = [];\n    \n                // 跟踪还有多少分片没有完成上传。\n                this.remaning = 0;\n                this.__tick = Base.bindFn( this._tick, this );\n    \n                owner.on( 'uploadComplete', function( file ) {\n                    // 把其他块取消了。\n                    file.blocks && $.each( file.blocks, function( _, v ) {\n                        v.transport && (v.transport.abort(), v.transport.destroy());\n                        delete v.transport;\n                    });\n    \n                    delete file.blocks;\n                    delete file.remaning;\n                });\n            },\n    \n            /**\n             * @event startUpload\n             * @description 当开始上传流程时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * 开始上传。此方法可以从初始状态调用开始上传流程，也可以从暂停状态调用，继续上传流程。\n             * @grammar upload() => undefined\n             * @method upload\n             * @for  Uploader\n             */\n            start: function() {\n                var me = this;\n    \n                // 移出invalid的文件\n                $.each( me.request( 'get-files', Status.INVALID ), function() {\n                    me.request( 'remove-file', this );\n                });\n    \n                if ( me.runing ) {\n                    return;\n                }\n    \n                me.runing = true;\n    \n                // 如果有暂停的，则续传\n                $.each( me.pool, function( _, v ) {\n                    var file = v.file;\n    \n                    if ( file.getStatus() === Status.INTERRUPT ) {\n                        file.setStatus( Status.PROGRESS );\n                        me._trigged = false;\n                        v.transport && v.transport.send();\n                    }\n                });\n    \n                me._trigged = false;\n                me.owner.trigger('startUpload');\n                Base.nextTick( me.__tick );\n            },\n    \n            /**\n             * @event stopUpload\n             * @description 当开始上传流程暂停时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * 暂停上传。第一个参数为是否中断上传当前正在上传的文件。\n             * @grammar stop() => undefined\n             * @grammar stop( true ) => undefined\n             * @method stop\n             * @for  Uploader\n             */\n            stop: function( interrupt ) {\n                var me = this;\n    \n                if ( me.runing === false ) {\n                    return;\n                }\n    \n                me.runing = false;\n    \n                interrupt && $.each( me.pool, function( _, v ) {\n                    v.transport && v.transport.abort();\n                    v.file.setStatus( Status.INTERRUPT );\n                });\n    \n                me.owner.trigger('stopUpload');\n            },\n    \n            /**\n             * 判断`Uplaode`r是否正在上传中。\n             * @grammar isInProgress() => Boolean\n             * @method isInProgress\n             * @for  Uploader\n             */\n            isInProgress: function() {\n                return !!this.runing;\n            },\n    \n            getStats: function() {\n                return this.request('get-stats');\n            },\n    \n            /**\n             * 掉过一个文件上传，直接标记指定文件为已上传状态。\n             * @grammar skipFile( file ) => undefined\n             * @method skipFile\n             * @for  Uploader\n             */\n            skipFile: function( file, status ) {\n                file = this.request( 'get-file', file );\n    \n                file.setStatus( status || Status.COMPLETE );\n                file.skipped = true;\n    \n                // 如果正在上传。\n                file.blocks && $.each( file.blocks, function( _, v ) {\n                    var _tr = v.transport;\n    \n                    if ( _tr ) {\n                        _tr.abort();\n                        _tr.destroy();\n                        delete v.transport;\n                    }\n                });\n    \n                this.owner.trigger( 'uploadSkip', file );\n            },\n    \n            /**\n             * @event uploadFinished\n             * @description 当所有文件上传结束时触发。\n             * @for  Uploader\n             */\n            _tick: function() {\n                var me = this,\n                    opts = me.options,\n                    fn, val;\n    \n                // 上一个promise还没有结束，则等待完成后再执行。\n                if ( me._promise ) {\n                    return me._promise.always( me.__tick );\n                }\n    \n                // 还有位置，且还有文件要处理的话。\n                if ( me.pool.length < opts.threads && (val = me._nextBlock()) ) {\n                    me._trigged = false;\n    \n                    fn = function( val ) {\n                        me._promise = null;\n    \n                        // 有可能是reject过来的，所以要检测val的类型。\n                        val && val.file && me._startSend( val );\n                        Base.nextTick( me.__tick );\n                    };\n    \n                    me._promise = isPromise( val ) ? val.always( fn ) : fn( val );\n    \n                // 没有要上传的了，且没有正在传输的了。\n                } else if ( !me.remaning && !me.getStats().numOfQueue ) {\n                    me.runing = false;\n    \n                    me._trigged || Base.nextTick(function() {\n                        me.owner.trigger('uploadFinished');\n                    });\n                    me._trigged = true;\n                }\n            },\n    \n            _nextBlock: function() {\n                var me = this,\n                    act = me._act,\n                    opts = me.options,\n                    next, done;\n    \n                // 如果当前文件还有没有需要传输的，则直接返回剩下的。\n                if ( act && act.has() &&\n                        act.file.getStatus() === Status.PROGRESS ) {\n    \n                    // 是否提前准备下一个文件\n                    if ( opts.prepareNextFile && !me.pending.length ) {\n                        me._prepareNextFile();\n                    }\n    \n                    return act.fetch();\n    \n                // 否则，如果正在运行，则准备下一个文件，并等待完成后返回下个分片。\n                } else if ( me.runing ) {\n    \n                    // 如果缓存中有，则直接在缓存中取，没有则去queue中取。\n                    if ( !me.pending.length && me.getStats().numOfQueue ) {\n                        me._prepareNextFile();\n                    }\n    \n                    next = me.pending.shift();\n                    done = function( file ) {\n                        if ( !file ) {\n                            return null;\n                        }\n    \n                        act = CuteFile( file, opts.chunked ? opts.chunkSize : 0 );\n                        me._act = act;\n                        return act.fetch();\n                    };\n    \n                    // 文件可能还在prepare中，也有可能已经完全准备好了。\n                    return isPromise( next ) ?\n                            next[ next.pipe ? 'pipe' : 'then']( done ) :\n                            done( next );\n                }\n            },\n    \n    \n            /**\n             * @event uploadStart\n             * @param {File} file File对象\n             * @description 某个文件开始上传前触发，一个文件只会触发一次。\n             * @for  Uploader\n             */\n            _prepareNextFile: function() {\n                var me = this,\n                    file = me.request('fetch-file'),\n                    pending = me.pending,\n                    promise;\n    \n                if ( file ) {\n                    promise = me.request( 'before-send-file', file, function() {\n    \n                        // 有可能文件被skip掉了。文件被skip掉后，状态坑定不是Queued.\n                        if ( file.getStatus() === Status.QUEUED ) {\n                            me.owner.trigger( 'uploadStart', file );\n                            file.setStatus( Status.PROGRESS );\n                            return file;\n                        }\n    \n                        return me._finishFile( file );\n                    });\n    \n                    // 如果还在pending中，则替换成文件本身。\n                    promise.done(function() {\n                        var idx = $.inArray( promise, pending );\n    \n                        ~idx && pending.splice( idx, 1, file );\n                    });\n    \n                    // befeore-send-file的钩子就有错误发生。\n                    promise.fail(function( reason ) {\n                        file.setStatus( Status.ERROR, reason );\n                        me.owner.trigger( 'uploadError', file, reason );\n                        me.owner.trigger( 'uploadComplete', file );\n                    });\n    \n                    pending.push( promise );\n                }\n            },\n    \n            // 让出位置了，可以让其他分片开始上传\n            _popBlock: function( block ) {\n                var idx = $.inArray( block, this.pool );\n    \n                this.pool.splice( idx, 1 );\n                block.file.remaning--;\n                this.remaning--;\n            },\n    \n            // 开始上传，可以被掉过。如果promise被reject了，则表示跳过此分片。\n            _startSend: function( block ) {\n                var me = this,\n                    file = block.file,\n                    promise;\n    \n                me.pool.push( block );\n                me.remaning++;\n    \n                // 如果没有分片，则直接使用原始的。\n                // 不会丢失content-type信息。\n                block.blob = block.chunks === 1 ? file.source :\n                        file.source.slice( block.start, block.end );\n    \n                // hook, 每个分片发送之前可能要做些异步的事情。\n                promise = me.request( 'before-send', block, function() {\n    \n                    // 有可能文件已经上传出错了，所以不需要再传输了。\n                    if ( file.getStatus() === Status.PROGRESS ) {\n                        me._doSend( block );\n                    } else {\n                        me._popBlock( block );\n                        Base.nextTick( me.__tick );\n                    }\n                });\n    \n                // 如果为fail了，则跳过此分片。\n                promise.fail(function() {\n                    if ( file.remaning === 1 ) {\n                        me._finishFile( file ).always(function() {\n                            block.percentage = 1;\n                            me._popBlock( block );\n                            me.owner.trigger( 'uploadComplete', file );\n                            Base.nextTick( me.__tick );\n                        });\n                    } else {\n                        block.percentage = 1;\n                        me._popBlock( block );\n                        Base.nextTick( me.__tick );\n                    }\n                });\n            },\n    \n    \n            /**\n             * @event uploadBeforeSend\n             * @param {Object} object\n             * @param {Object} data 默认的上传参数，可以扩展此对象来控制上传参数。\n             * @description 当某个文件的分块在发送前触发，主要用来询问是否要添加附带参数，大文件在开起分片上传的前提下此事件可能会触发多次。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadAccept\n             * @param {Object} object\n             * @param {Object} ret 服务端的返回数据，json格式，如果服务端不是json格式，从ret._raw中取数据，自行解析。\n             * @description 当某个文件上传到服务端响应后，会派送此事件来询问服务端响应是否有效。如果此事件handler返回值为`false`, 则此文件将派送`server`类型的`uploadError`事件。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadProgress\n             * @param {File} file File对象\n             * @param {Number} percentage 上传进度\n             * @description 上传过程中触发，携带上传进度。\n             * @for  Uploader\n             */\n    \n    \n            /**\n             * @event uploadError\n             * @param {File} file File对象\n             * @param {String} reason 出错的code\n             * @description 当文件上传出错时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadSuccess\n             * @param {File} file File对象\n             * @param {Object} response 服务端返回的数据\n             * @description 当文件上传成功时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadComplete\n             * @param {File} [file] File对象\n             * @description 不管成功或者失败，文件上传完成时触发。\n             * @for  Uploader\n             */\n    \n            // 做上传操作。\n            _doSend: function( block ) {\n                var me = this,\n                    owner = me.owner,\n                    opts = me.options,\n                    file = block.file,\n                    tr = new Transport( opts ),\n                    data = $.extend({}, opts.formData ),\n                    headers = $.extend({}, opts.headers ),\n                    requestAccept, ret;\n    \n                block.transport = tr;\n    \n                tr.on( 'destroy', function() {\n                    delete block.transport;\n                    me._popBlock( block );\n                    Base.nextTick( me.__tick );\n                });\n    \n                // 广播上传进度。以文件为单位。\n                tr.on( 'progress', function( percentage ) {\n                    var totalPercent = 0,\n                        uploaded = 0;\n    \n                    // 可能没有abort掉，progress还是执行进来了。\n                    // if ( !file.blocks ) {\n                    //     return;\n                    // }\n    \n                    totalPercent = block.percentage = percentage;\n    \n                    if ( block.chunks > 1 ) {    // 计算文件的整体速度。\n                        $.each( file.blocks, function( _, v ) {\n                            uploaded += (v.percentage || 0) * (v.end - v.start);\n                        });\n    \n                        totalPercent = uploaded / file.size;\n                    }\n    \n                    owner.trigger( 'uploadProgress', file, totalPercent || 0 );\n                });\n    \n                // 用来询问，是否返回的结果是有错误的。\n                requestAccept = function( reject ) {\n                    var fn;\n    \n                    ret = tr.getResponseAsJson() || {};\n                    ret._raw = tr.getResponse();\n                    fn = function( value ) {\n                        reject = value;\n                    };\n    \n                    // 服务端响应了，不代表成功了，询问是否响应正确。\n                    if ( !owner.trigger( 'uploadAccept', block, ret, fn ) ) {\n                        reject = reject || 'server';\n                    }\n    \n                    return reject;\n                };\n    \n                // 尝试重试，然后广播文件上传出错。\n                tr.on( 'error', function( type, flag ) {\n                    block.retried = block.retried || 0;\n    \n                    // 自动重试\n                    if ( block.chunks > 1 && ~'http,abort'.indexOf( type ) &&\n                            block.retried < opts.chunkRetry ) {\n    \n                        block.retried++;\n                        tr.send();\n    \n                    } else {\n    \n                        // http status 500 ~ 600\n                        if ( !flag && type === 'server' ) {\n                            type = requestAccept( type );\n                        }\n    \n                        file.setStatus( Status.ERROR, type );\n                        owner.trigger( 'uploadError', file, type );\n                        owner.trigger( 'uploadComplete', file );\n                    }\n                });\n    \n                // 上传成功\n                tr.on( 'load', function() {\n                    var reason;\n    \n                    // 如果非预期，转向上传出错。\n                    if ( (reason = requestAccept()) ) {\n                        tr.trigger( 'error', reason, true );\n                        return;\n                    }\n    \n                    // 全部上传完成。\n                    if ( file.remaning === 1 ) {\n                        me._finishFile( file, ret );\n                    } else {\n                        tr.destroy();\n                    }\n                });\n    \n                // 配置默认的上传字段。\n                data = $.extend( data, {\n                    id: file.id,\n                    name: file.name,\n                    type: file.type,\n                    lastModifiedDate: file.lastModifiedDate,\n                    size: file.size\n                });\n    \n                block.chunks > 1 && $.extend( data, {\n                    chunks: block.chunks,\n                    chunk: block.chunk\n                });\n    \n                // 在发送之间可以添加字段什么的。。。\n                // 如果默认的字段不够使用，可以通过监听此事件来扩展\n                owner.trigger( 'uploadBeforeSend', block, data, headers );\n    \n                // 开始发送。\n                tr.appendBlob( opts.fileVal, block.blob, file.name );\n                tr.append( data );\n                tr.setRequestHeader( headers );\n                tr.send();\n            },\n    \n            // 完成上传。\n            _finishFile: function( file, ret, hds ) {\n                var owner = this.owner;\n    \n                return owner\n                        .request( 'after-send-file', arguments, function() {\n                            file.setStatus( Status.COMPLETE );\n                            owner.trigger( 'uploadSuccess', file, ret, hds );\n                        })\n                        .fail(function( reason ) {\n    \n                            // 如果外部已经标记为invalid什么的，不再改状态。\n                            if ( file.getStatus() === Status.PROGRESS ) {\n                                file.setStatus( Status.ERROR, reason );\n                            }\n    \n                            owner.trigger( 'uploadError', file, reason );\n                        })\n                        .always(function() {\n                            owner.trigger( 'uploadComplete', file );\n                        });\n            }\n    \n        });\n    });\n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/compbase',[],function() {\n    \n        function CompBase( owner, runtime ) {\n    \n            this.owner = owner;\n            this.options = owner.options;\n    \n            this.getRuntime = function() {\n                return runtime;\n            };\n    \n            this.getRuid = function() {\n                return runtime.uid;\n            };\n    \n            this.trigger = function() {\n                return owner.trigger.apply( owner, arguments );\n            };\n        }\n    \n        return CompBase;\n    });\n    /**\n     * @fileOverview Html5Runtime\n     */\n    define('runtime/html5/runtime',[\n        'base',\n        'runtime/runtime',\n        'runtime/compbase'\n    ], function( Base, Runtime, CompBase ) {\n    \n        var type = 'html5',\n            components = {};\n    \n        function Html5Runtime() {\n            var pool = {},\n                me = this,\n                destory = this.destory;\n    \n            Runtime.apply( me, arguments );\n            me.type = type;\n    \n    \n            // 这个方法的调用者，实际上是RuntimeClient\n            me.exec = function( comp, fn/*, args...*/) {\n                var client = this,\n                    uid = client.uid,\n                    args = Base.slice( arguments, 2 ),\n                    instance;\n    \n                if ( components[ comp ] ) {\n                    instance = pool[ uid ] = pool[ uid ] ||\n                            new components[ comp ]( client, me );\n    \n                    if ( instance[ fn ] ) {\n                        return instance[ fn ].apply( instance, args );\n                    }\n                }\n            };\n    \n            me.destory = function() {\n                // @todo 删除池子中的所有实例\n                return destory && destory.apply( this, arguments );\n            };\n        }\n    \n        Base.inherits( Runtime, {\n            constructor: Html5Runtime,\n    \n            // 不需要连接其他程序，直接执行callback\n            init: function() {\n                var me = this;\n                setTimeout(function() {\n                    me.trigger('ready');\n                }, 1 );\n            }\n    \n        });\n    \n        // 注册Components\n        Html5Runtime.register = function( name, component ) {\n            var klass = components[ name ] = Base.inherits( CompBase, component );\n            return klass;\n        };\n    \n        // 注册html5运行时。\n        // 只有在支持的前提下注册。\n        if ( window.Blob && window.FileReader && window.DataView ) {\n            Runtime.addRuntime( type, Html5Runtime );\n        }\n    \n        return Html5Runtime;\n    });\n    /**\n     * @fileOverview Blob Html实现\n     */\n    define('runtime/html5/blob',[\n        'runtime/html5/runtime',\n        'lib/blob'\n    ], function( Html5Runtime, Blob ) {\n    \n        return Html5Runtime.register( 'Blob', {\n            slice: function( start, end ) {\n                var blob = this.owner.source,\n                    slice = blob.slice || blob.webkitSlice || blob.mozSlice;\n    \n                blob = slice.call( blob, start, end );\n    \n                return new Blob( this.getRuid(), blob );\n            }\n        });\n    });\n    /**\n     * @fileOverview FilePicker\n     */\n    define('runtime/html5/filepicker',[\n        'base',\n        'runtime/html5/runtime'\n    ], function( Base, Html5Runtime ) {\n    \n        var $ = Base.$;\n    \n        return Html5Runtime.register( 'FilePicker', {\n            init: function() {\n                var container = this.getRuntime().getContainer(),\n                    me = this,\n                    owner = me.owner,\n                    opts = me.options,\n                    lable = $( document.createElement('label') ),\n                    input = $( document.createElement('input') ),\n                    arr, i, len, mouseHandler;\n    \n                input.attr( 'type', 'file' );\n                input.attr( 'name', opts.name );\n                input.addClass('webuploader-element-invisible');\n    \n                lable.on( 'click', function() {\n                    input.trigger('click');\n                });\n    \n                lable.css({\n                    opacity: 0,\n                    width: '100%',\n                    height: '100%',\n                    display: 'block',\n                    cursor: 'pointer',\n                    background: '#ffffff'\n                });\n    \n                if ( opts.multiple ) {\n                    input.attr( 'multiple', 'multiple' );\n                }\n    \n                // @todo Firefox不支持单独指定后缀\n                if ( opts.accept && opts.accept.length > 0 ) {\n                    arr = [];\n    \n                    for ( i = 0, len = opts.accept.length; i < len; i++ ) {\n                        arr.push( opts.accept[ i ].mimeTypes );\n                    }\n    \n                    input.attr( 'accept', arr.join(',') );\n                }\n    \n                container.append( input );\n                container.append( lable );\n    \n                mouseHandler = function( e ) {\n                    owner.trigger( e.type );\n                };\n    \n                input.on( 'change', function( e ) {\n                    var fn = arguments.callee,\n                        clone;\n    \n                    me.files = e.target.files;\n    \n                    // reset input\n                    clone = this.cloneNode( true );\n                    this.parentNode.replaceChild( clone, this );\n    \n                    input.off();\n                    input = $( clone ).on( 'change', fn )\n                            .on( 'mouseenter mouseleave', mouseHandler );\n    \n                    owner.trigger('change');\n                });\n    \n                lable.on( 'mouseenter mouseleave', mouseHandler );\n    \n            },\n    \n    \n            getFiles: function() {\n                return this.files;\n            },\n    \n            destroy: function() {\n                // todo\n            }\n        });\n    });\n    /**\n     * Terms:\n     *\n     * Uint8Array, FileReader, BlobBuilder, atob, ArrayBuffer\n     * @fileOverview Image控件\n     */\n    define('runtime/html5/util',[\n        'base'\n    ], function( Base ) {\n    \n        var urlAPI = window.createObjectURL && window ||\n                window.URL && URL.revokeObjectURL && URL ||\n                window.webkitURL,\n            createObjectURL = Base.noop,\n            revokeObjectURL = createObjectURL;\n    \n        if ( urlAPI ) {\n    \n            // 更安全的方式调用，比如android里面就能把context改成其他的对象。\n            createObjectURL = function() {\n                return urlAPI.createObjectURL.apply( urlAPI, arguments );\n            };\n    \n            revokeObjectURL = function() {\n                return urlAPI.revokeObjectURL.apply( urlAPI, arguments );\n            };\n        }\n    \n        return {\n            createObjectURL: createObjectURL,\n            revokeObjectURL: revokeObjectURL,\n    \n            dataURL2Blob: function( dataURI ) {\n                var byteStr, intArray, ab, i, mimetype, parts;\n    \n                parts = dataURI.split(',');\n    \n                if ( ~parts[ 0 ].indexOf('base64') ) {\n                    byteStr = atob( parts[ 1 ] );\n                } else {\n                    byteStr = decodeURIComponent( parts[ 1 ] );\n                }\n    \n                ab = new ArrayBuffer( byteStr.length );\n                intArray = new Uint8Array( ab );\n    \n                for ( i = 0; i < byteStr.length; i++ ) {\n                    intArray[ i ] = byteStr.charCodeAt( i );\n                }\n    \n                mimetype = parts[ 0 ].split(':')[ 1 ].split(';')[ 0 ];\n    \n                return this.arrayBufferToBlob( ab, mimetype );\n            },\n    \n            dataURL2ArrayBuffer: function( dataURI ) {\n                var byteStr, intArray, i, parts;\n    \n                parts = dataURI.split(',');\n    \n                if ( ~parts[ 0 ].indexOf('base64') ) {\n                    byteStr = atob( parts[ 1 ] );\n                } else {\n                    byteStr = decodeURIComponent( parts[ 1 ] );\n                }\n    \n                intArray = new Uint8Array( byteStr.length );\n    \n                for ( i = 0; i < byteStr.length; i++ ) {\n                    intArray[ i ] = byteStr.charCodeAt( i );\n                }\n    \n                return intArray.buffer;\n            },\n    \n            arrayBufferToBlob: function( buffer, type ) {\n                var builder = window.BlobBuilder || window.WebKitBlobBuilder,\n                    bb;\n    \n                // android不支持直接new Blob, 只能借助blobbuilder.\n                if ( builder ) {\n                    bb = new builder();\n                    bb.append( buffer );\n                    return bb.getBlob( type );\n                }\n    \n                return new Blob([ buffer ], type ? { type: type } : {} );\n            },\n    \n            // 抽出来主要是为了解决android下面canvas.toDataUrl不支持jpeg.\n            // 你得到的结果是png.\n            canvasToDataUrl: function( canvas, type, quality ) {\n                return canvas.toDataURL( type, quality / 100 );\n            },\n    \n            // imagemeat会复写这个方法，如果用户选择加载那个文件了的话。\n            parseMeta: function( blob, callback ) {\n                callback( false, {});\n            },\n    \n            // imagemeat会复写这个方法，如果用户选择加载那个文件了的话。\n            updateImageHead: function( data ) {\n                return data;\n            }\n        };\n    });\n    /**\n     * Terms:\n     *\n     * Uint8Array, FileReader, BlobBuilder, atob, ArrayBuffer\n     * @fileOverview Image控件\n     */\n    define('runtime/html5/imagemeta',[\n        'runtime/html5/util'\n    ], function( Util ) {\n    \n        var api;\n    \n        api = {\n            parsers: {\n                0xffe1: []\n            },\n    \n            maxMetaDataSize: 262144,\n    \n            parse: function( blob, cb ) {\n                var me = this,\n                    fr = new FileReader();\n    \n                fr.onload = function() {\n                    cb( false, me._parse( this.result ) );\n                    fr = fr.onload = fr.onerror = null;\n                };\n    \n                fr.onerror = function( e ) {\n                    cb( e.message );\n                    fr = fr.onload = fr.onerror = null;\n                };\n    \n                blob = blob.slice( 0, me.maxMetaDataSize );\n                fr.readAsArrayBuffer( blob.getSource() );\n            },\n    \n            _parse: function( buffer, noParse ) {\n                if ( buffer.byteLength < 6 ) {\n                    return;\n                }\n    \n                var dataview = new DataView( buffer ),\n                    offset = 2,\n                    maxOffset = dataview.byteLength - 4,\n                    headLength = offset,\n                    ret = {},\n                    markerBytes, markerLength, parsers, i;\n    \n                if ( dataview.getUint16( 0 ) === 0xffd8 ) {\n    \n                    while ( offset < maxOffset ) {\n                        markerBytes = dataview.getUint16( offset );\n    \n                        if ( markerBytes >= 0xffe0 && markerBytes <= 0xffef ||\n                                markerBytes === 0xfffe ) {\n    \n                            markerLength = dataview.getUint16( offset + 2 ) + 2;\n    \n                            if ( offset + markerLength > dataview.byteLength ) {\n                                break;\n                            }\n    \n                            parsers = api.parsers[ markerBytes ];\n    \n                            if ( !noParse && parsers ) {\n                                for ( i = 0; i < parsers.length; i += 1 ) {\n                                    parsers[ i ].call( api, dataview, offset,\n                                            markerLength, ret );\n                                }\n                            }\n    \n                            offset += markerLength;\n                            headLength = offset;\n                        } else {\n                            break;\n                        }\n                    }\n    \n                    if ( headLength > 6 ) {\n                        if ( buffer.slice ) {\n                            ret.imageHead = buffer.slice( 2, headLength );\n                        } else {\n                            // Workaround for IE10, which does not yet\n                            // support ArrayBuffer.slice:\n                            ret.imageHead = new Uint8Array( buffer )\n                                    .subarray( 2, headLength );\n                        }\n                    }\n                }\n    \n                return ret;\n            },\n    \n            updateImageHead: function( buffer, head ) {\n                var data = this._parse( buffer, true ),\n                    buf1, buf2, bodyoffset;\n    \n    \n                bodyoffset = 2;\n                if ( data.imageHead ) {\n                    bodyoffset = 2 + data.imageHead.byteLength;\n                }\n    \n                if ( buffer.slice ) {\n                    buf2 = buffer.slice( bodyoffset );\n                } else {\n                    buf2 = new Uint8Array( buffer ).subarray( bodyoffset );\n                }\n    \n                buf1 = new Uint8Array( head.byteLength + 2 + buf2.byteLength );\n    \n                buf1[ 0 ] = 0xFF;\n                buf1[ 1 ] = 0xD8;\n                buf1.set( new Uint8Array( head ), 2 );\n                buf1.set( new Uint8Array( buf2 ), head.byteLength + 2 );\n    \n                return buf1.buffer;\n            }\n        };\n    \n        Util.parseMeta = function() {\n            return api.parse.apply( api, arguments );\n        };\n    \n        Util.updateImageHead = function() {\n            return api.updateImageHead.apply( api, arguments );\n        };\n    \n        return api;\n    });\n    /**\n     * 代码来自于：https://github.com/blueimp/JavaScript-Load-Image\n     * 暂时项目中只用了orientation.\n     *\n     * 去除了 Exif Sub IFD Pointer, GPS Info IFD Pointer, Exif Thumbnail.\n     * @fileOverview EXIF解析\n     */\n    \n    // Sample\n    // ====================================\n    // Make : Apple\n    // Model : iPhone 4S\n    // Orientation : 1\n    // XResolution : 72 [72/1]\n    // YResolution : 72 [72/1]\n    // ResolutionUnit : 2\n    // Software : QuickTime 7.7.1\n    // DateTime : 2013:09:01 22:53:55\n    // ExifIFDPointer : 190\n    // ExposureTime : 0.058823529411764705 [1/17]\n    // FNumber : 2.4 [12/5]\n    // ExposureProgram : Normal program\n    // ISOSpeedRatings : 800\n    // ExifVersion : 0220\n    // DateTimeOriginal : 2013:09:01 22:52:51\n    // DateTimeDigitized : 2013:09:01 22:52:51\n    // ComponentsConfiguration : YCbCr\n    // ShutterSpeedValue : 4.058893515764426\n    // ApertureValue : 2.5260688216892597 [4845/1918]\n    // BrightnessValue : -0.3126686601998395\n    // MeteringMode : Pattern\n    // Flash : Flash did not fire, compulsory flash mode\n    // FocalLength : 4.28 [107/25]\n    // SubjectArea : [4 values]\n    // FlashpixVersion : 0100\n    // ColorSpace : 1\n    // PixelXDimension : 2448\n    // PixelYDimension : 3264\n    // SensingMethod : One-chip color area sensor\n    // ExposureMode : 0\n    // WhiteBalance : Auto white balance\n    // FocalLengthIn35mmFilm : 35\n    // SceneCaptureType : Standard\n    define('runtime/html5/imagemeta/exif',[\n        'base',\n        'runtime/html5/imagemeta'\n    ], function( Base, ImageMeta ) {\n    \n        var EXIF = {};\n    \n        EXIF.ExifMap = function() {\n            return this;\n        };\n    \n        EXIF.ExifMap.prototype.map = {\n            'Orientation': 0x0112\n        };\n    \n        EXIF.ExifMap.prototype.get = function( id ) {\n            return this[ id ] || this[ this.map[ id ] ];\n        };\n    \n        EXIF.exifTagTypes = {\n            // byte, 8-bit unsigned int:\n            1: {\n                getValue: function( dataView, dataOffset ) {\n                    return dataView.getUint8( dataOffset );\n                },\n                size: 1\n            },\n    \n            // ascii, 8-bit byte:\n            2: {\n                getValue: function( dataView, dataOffset ) {\n                    return String.fromCharCode( dataView.getUint8( dataOffset ) );\n                },\n                size: 1,\n                ascii: true\n            },\n    \n            // short, 16 bit int:\n            3: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getUint16( dataOffset, littleEndian );\n                },\n                size: 2\n            },\n    \n            // long, 32 bit int:\n            4: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getUint32( dataOffset, littleEndian );\n                },\n                size: 4\n            },\n    \n            // rational = two long values,\n            // first is numerator, second is denominator:\n            5: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getUint32( dataOffset, littleEndian ) /\n                        dataView.getUint32( dataOffset + 4, littleEndian );\n                },\n                size: 8\n            },\n    \n            // slong, 32 bit signed int:\n            9: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getInt32( dataOffset, littleEndian );\n                },\n                size: 4\n            },\n    \n            // srational, two slongs, first is numerator, second is denominator:\n            10: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getInt32( dataOffset, littleEndian ) /\n                        dataView.getInt32( dataOffset + 4, littleEndian );\n                },\n                size: 8\n            }\n        };\n    \n        // undefined, 8-bit byte, value depending on field:\n        EXIF.exifTagTypes[ 7 ] = EXIF.exifTagTypes[ 1 ];\n    \n        EXIF.getExifValue = function( dataView, tiffOffset, offset, type, length,\n                littleEndian ) {\n    \n            var tagType = EXIF.exifTagTypes[ type ],\n                tagSize, dataOffset, values, i, str, c;\n    \n            if ( !tagType ) {\n                Base.log('Invalid Exif data: Invalid tag type.');\n                return;\n            }\n    \n            tagSize = tagType.size * length;\n    \n            // Determine if the value is contained in the dataOffset bytes,\n            // or if the value at the dataOffset is a pointer to the actual data:\n            dataOffset = tagSize > 4 ? tiffOffset + dataView.getUint32( offset + 8,\n                    littleEndian ) : (offset + 8);\n    \n            if ( dataOffset + tagSize > dataView.byteLength ) {\n                Base.log('Invalid Exif data: Invalid data offset.');\n                return;\n            }\n    \n            if ( length === 1 ) {\n                return tagType.getValue( dataView, dataOffset, littleEndian );\n            }\n    \n            values = [];\n    \n            for ( i = 0; i < length; i += 1 ) {\n                values[ i ] = tagType.getValue( dataView,\n                        dataOffset + i * tagType.size, littleEndian );\n            }\n    \n            if ( tagType.ascii ) {\n                str = '';\n    \n                // Concatenate the chars:\n                for ( i = 0; i < values.length; i += 1 ) {\n                    c = values[ i ];\n    \n                    // Ignore the terminating NULL byte(s):\n                    if ( c === '\\u0000' ) {\n                        break;\n                    }\n                    str += c;\n                }\n    \n                return str;\n            }\n            return values;\n        };\n    \n        EXIF.parseExifTag = function( dataView, tiffOffset, offset, littleEndian,\n                data ) {\n    \n            var tag = dataView.getUint16( offset, littleEndian );\n            data.exif[ tag ] = EXIF.getExifValue( dataView, tiffOffset, offset,\n                    dataView.getUint16( offset + 2, littleEndian ),    // tag type\n                    dataView.getUint32( offset + 4, littleEndian ),    // tag length\n                    littleEndian );\n        };\n    \n        EXIF.parseExifTags = function( dataView, tiffOffset, dirOffset,\n                littleEndian, data ) {\n    \n            var tagsNumber, dirEndOffset, i;\n    \n            if ( dirOffset + 6 > dataView.byteLength ) {\n                Base.log('Invalid Exif data: Invalid directory offset.');\n                return;\n            }\n    \n            tagsNumber = dataView.getUint16( dirOffset, littleEndian );\n            dirEndOffset = dirOffset + 2 + 12 * tagsNumber;\n    \n            if ( dirEndOffset + 4 > dataView.byteLength ) {\n                Base.log('Invalid Exif data: Invalid directory size.');\n                return;\n            }\n    \n            for ( i = 0; i < tagsNumber; i += 1 ) {\n                this.parseExifTag( dataView, tiffOffset,\n                        dirOffset + 2 + 12 * i,    // tag offset\n                        littleEndian, data );\n            }\n    \n            // Return the offset to the next directory:\n            return dataView.getUint32( dirEndOffset, littleEndian );\n        };\n    \n        // EXIF.getExifThumbnail = function(dataView, offset, length) {\n        //     var hexData,\n        //         i,\n        //         b;\n        //     if (!length || offset + length > dataView.byteLength) {\n        //         Base.log('Invalid Exif data: Invalid thumbnail data.');\n        //         return;\n        //     }\n        //     hexData = [];\n        //     for (i = 0; i < length; i += 1) {\n        //         b = dataView.getUint8(offset + i);\n        //         hexData.push((b < 16 ? '0' : '') + b.toString(16));\n        //     }\n        //     return 'data:image/jpeg,%' + hexData.join('%');\n        // };\n    \n        EXIF.parseExifData = function( dataView, offset, length, data ) {\n    \n            var tiffOffset = offset + 10,\n                littleEndian, dirOffset;\n    \n            // Check for the ASCII code for \"Exif\" (0x45786966):\n            if ( dataView.getUint32( offset + 4 ) !== 0x45786966 ) {\n                // No Exif data, might be XMP data instead\n                return;\n            }\n            if ( tiffOffset + 8 > dataView.byteLength ) {\n                Base.log('Invalid Exif data: Invalid segment size.');\n                return;\n            }\n    \n            // Check for the two null bytes:\n            if ( dataView.getUint16( offset + 8 ) !== 0x0000 ) {\n                Base.log('Invalid Exif data: Missing byte alignment offset.');\n                return;\n            }\n    \n            // Check the byte alignment:\n            switch ( dataView.getUint16( tiffOffset ) ) {\n                case 0x4949:\n                    littleEndian = true;\n                    break;\n    \n                case 0x4D4D:\n                    littleEndian = false;\n                    break;\n    \n                default:\n                    Base.log('Invalid Exif data: Invalid byte alignment marker.');\n                    return;\n            }\n    \n            // Check for the TIFF tag marker (0x002A):\n            if ( dataView.getUint16( tiffOffset + 2, littleEndian ) !== 0x002A ) {\n                Base.log('Invalid Exif data: Missing TIFF marker.');\n                return;\n            }\n    \n            // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:\n            dirOffset = dataView.getUint32( tiffOffset + 4, littleEndian );\n            // Create the exif object to store the tags:\n            data.exif = new EXIF.ExifMap();\n            // Parse the tags of the main image directory and retrieve the\n            // offset to the next directory, usually the thumbnail directory:\n            dirOffset = EXIF.parseExifTags( dataView, tiffOffset,\n                    tiffOffset + dirOffset, littleEndian, data );\n    \n            // 尝试读取缩略图\n            // if ( dirOffset ) {\n            //     thumbnailData = {exif: {}};\n            //     dirOffset = EXIF.parseExifTags(\n            //         dataView,\n            //         tiffOffset,\n            //         tiffOffset + dirOffset,\n            //         littleEndian,\n            //         thumbnailData\n            //     );\n    \n            //     // Check for JPEG Thumbnail offset:\n            //     if (thumbnailData.exif[0x0201]) {\n            //         data.exif.Thumbnail = EXIF.getExifThumbnail(\n            //             dataView,\n            //             tiffOffset + thumbnailData.exif[0x0201],\n            //             thumbnailData.exif[0x0202] // Thumbnail data length\n            //         );\n            //     }\n            // }\n        };\n    \n        ImageMeta.parsers[ 0xffe1 ].push( EXIF.parseExifData );\n        return EXIF;\n    });\n    /**\n     * @fileOverview Image\n     */\n    define('runtime/html5/image',[\n        'base',\n        'runtime/html5/runtime',\n        'runtime/html5/util'\n    ], function( Base, Html5Runtime, Util ) {\n    \n        var BLANK = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D';\n    \n        return Html5Runtime.register( 'Image', {\n    \n            // flag: 标记是否被修改过。\n            modified: false,\n    \n            init: function() {\n                var me = this,\n                    img = new Image();\n    \n                img.onload = function() {\n    \n                    me._info = {\n                        type: me.type,\n                        width: this.width,\n                        height: this.height\n                    };\n    \n                    // 读取meta信息。\n                    if ( !me._metas && 'image/jpeg' === me.type ) {\n                        Util.parseMeta( me._blob, function( error, ret ) {\n                            me._metas = ret;\n                            me.owner.trigger('load');\n                        });\n                    } else {\n                        me.owner.trigger('load');\n                    }\n                };\n    \n                img.onerror = function() {\n                    me.owner.trigger('error');\n                };\n    \n                me._img = img;\n            },\n    \n            loadFromBlob: function( blob ) {\n                var me = this,\n                    img = me._img;\n    \n                me._blob = blob;\n                me.type = blob.type;\n                img.src = Util.createObjectURL( blob.getSource() );\n                me.owner.once( 'load', function() {\n                    Util.revokeObjectURL( img.src );\n                });\n            },\n    \n            resize: function( width, height ) {\n                var canvas = this._canvas ||\n                        (this._canvas = document.createElement('canvas'));\n    \n                this._resize( this._img, canvas, width, height );\n                this._blob = null;    // 没用了，可以删掉了。\n                this.modified = true;\n                this.owner.trigger('complete');\n            },\n    \n            getAsBlob: function( type ) {\n                var blob = this._blob,\n                    opts = this.options,\n                    canvas;\n    \n                type = type || this.type;\n    \n                // blob需要重新生成。\n                if ( this.modified || this.type !== type ) {\n                    canvas = this._canvas;\n    \n                    if ( type === 'image/jpeg' ) {\n    \n                        blob = Util.canvasToDataUrl( canvas, 'image/jpeg',\n                                opts.quality );\n    \n                        if ( opts.preserveHeaders && this._metas &&\n                                this._metas.imageHead ) {\n    \n                            blob = Util.dataURL2ArrayBuffer( blob );\n                            blob = Util.updateImageHead( blob,\n                                    this._metas.imageHead );\n                            blob = Util.arrayBufferToBlob( blob, type );\n                            return blob;\n                        }\n                    } else {\n                        blob = Util.canvasToDataUrl( canvas, type );\n                    }\n    \n                    blob = Util.dataURL2Blob( blob );\n                }\n    \n                return blob;\n            },\n    \n            getAsDataUrl: function( type ) {\n                var opts = this.options;\n    \n                type = type || this.type;\n    \n                if ( type === 'image/jpeg' ) {\n                    return Util.canvasToDataUrl( this._canvas, type, opts.quality );\n                } else {\n                    return this._canvas.toDataURL( type );\n                }\n            },\n    \n            getOrientation: function() {\n                return this._metas && this._metas.exif &&\n                        this._metas.exif.get('Orientation') || 1;\n            },\n    \n            info: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._info = val;\n                    return this;\n                }\n    \n                // getter\n                return this._info;\n            },\n    \n            meta: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._meta = val;\n                    return this;\n                }\n    \n                // getter\n                return this._meta;\n            },\n    \n            destroy: function() {\n                var canvas = this._canvas;\n                this._img.onload = null;\n    \n                if ( canvas ) {\n                    canvas.getContext('2d')\n                            .clearRect( 0, 0, canvas.width, canvas.height );\n                    canvas.width = canvas.height = 0;\n                    this._canvas = null;\n                }\n    \n                // 释放内存。非常重要，否则释放不了image的内存。\n                this._img.src = BLANK;\n                this._img = this._blob = null;\n            },\n    \n            _resize: function( img, cvs, width, height ) {\n                var opts = this.options,\n                    naturalWidth = img.width,\n                    naturalHeight = img.height,\n                    orientation = this.getOrientation(),\n                    scale, w, h, x, y;\n    \n                // values that require 90 degree rotation\n                if ( ~[ 5, 6, 7, 8 ].indexOf( orientation ) ) {\n    \n                    // 交换width, height的值。\n                    width ^= height;\n                    height ^= width;\n                    width ^= height;\n                }\n    \n                scale = Math[ opts.crop ? 'max' : 'min' ]( width / naturalWidth,\n                        height / naturalHeight );\n    \n                // 不允许放大。\n                opts.allowMagnify || (scale = Math.min( 1, scale ));\n    \n                w = naturalWidth * scale;\n                h = naturalHeight * scale;\n    \n                if ( opts.crop ) {\n                    cvs.width = width;\n                    cvs.height = height;\n                } else {\n                    cvs.width = w;\n                    cvs.height = h;\n                }\n    \n                x = (cvs.width - w) / 2;\n                y = (cvs.height - h) / 2;\n    \n                opts.preserveHeaders || this._rotate2Orientaion( cvs, orientation );\n    \n                this._renderImageToCanvas( cvs, img, x, y, w, h );\n            },\n    \n            _rotate2Orientaion: function( canvas, orientation ) {\n                var width = canvas.width,\n                    height = canvas.height,\n                    ctx = canvas.getContext('2d');\n    \n                switch ( orientation ) {\n                    case 5:\n                    case 6:\n                    case 7:\n                    case 8:\n                        canvas.width = height;\n                        canvas.height = width;\n                        break;\n                }\n    \n                switch ( orientation ) {\n                    case 2:    // horizontal flip\n                        ctx.translate( width, 0 );\n                        ctx.scale( -1, 1 );\n                        break;\n    \n                    case 3:    // 180 rotate left\n                        ctx.translate( width, height );\n                        ctx.rotate( Math.PI );\n                        break;\n    \n                    case 4:    // vertical flip\n                        ctx.translate( 0, height );\n                        ctx.scale( 1, -1 );\n                        break;\n    \n                    case 5:    // vertical flip + 90 rotate right\n                        ctx.rotate( 0.5 * Math.PI );\n                        ctx.scale( 1, -1 );\n                        break;\n    \n                    case 6:    // 90 rotate right\n                        ctx.rotate( 0.5 * Math.PI );\n                        ctx.translate( 0, -height );\n                        break;\n    \n                    case 7:    // horizontal flip + 90 rotate right\n                        ctx.rotate( 0.5 * Math.PI );\n                        ctx.translate( width, -height );\n                        ctx.scale( -1, 1 );\n                        break;\n    \n                    case 8:    // 90 rotate left\n                        ctx.rotate( -0.5 * Math.PI );\n                        ctx.translate( -width, 0 );\n                        break;\n                }\n            },\n    \n            // https://github.com/stomita/ios-imagefile-megapixel/\n            // blob/master/src/megapix-image.js\n            _renderImageToCanvas: (function() {\n    \n                // 如果不是ios, 不需要这么复杂！\n                if ( !Base.os.ios ) {\n                    return function( canvas, img, x, y, w, h ) {\n                        canvas.getContext('2d').drawImage( img, x, y, w, h );\n                    };\n                }\n    \n                /**\n                 * Detecting vertical squash in loaded image.\n                 * Fixes a bug which squash image vertically while drawing into\n                 * canvas for some images.\n                 */\n                function detectVerticalSquash( img, iw, ih ) {\n                    var canvas = document.createElement('canvas'),\n                        ctx = canvas.getContext('2d'),\n                        sy = 0,\n                        ey = ih,\n                        py = ih,\n                        data, alpha, ratio;\n    \n    \n                    canvas.width = 1;\n                    canvas.height = ih;\n                    ctx.drawImage( img, 0, 0 );\n                    data = ctx.getImageData( 0, 0, 1, ih ).data;\n    \n                    // search image edge pixel position in case\n                    // it is squashed vertically.\n                    while ( py > sy ) {\n                        alpha = data[ (py - 1) * 4 + 3 ];\n    \n                        if ( alpha === 0 ) {\n                            ey = py;\n                        } else {\n                            sy = py;\n                        }\n    \n                        py = (ey + sy) >> 1;\n                    }\n    \n                    ratio = (py / ih);\n                    return (ratio === 0) ? 1 : ratio;\n                }\n    \n                // fix ie7 bug\n                // http://stackoverflow.com/questions/11929099/\n                // html5-canvas-drawimage-ratio-bug-ios\n                if ( Base.os.ios >= 7 ) {\n                    return function( canvas, img, x, y, w, h ) {\n                        var iw = img.naturalWidth,\n                            ih = img.naturalHeight,\n                            vertSquashRatio = detectVerticalSquash( img, iw, ih );\n    \n                        return canvas.getContext('2d').drawImage( img, 0, 0,\n                            iw * vertSquashRatio, ih * vertSquashRatio,\n                            x, y, w, h );\n                    };\n                }\n    \n                /**\n                 * Detect subsampling in loaded image.\n                 * In iOS, larger images than 2M pixels may be\n                 * subsampled in rendering.\n                 */\n                function detectSubsampling( img ) {\n                    var iw = img.naturalWidth,\n                        ih = img.naturalHeight,\n                        canvas, ctx;\n    \n                    // subsampling may happen overmegapixel image\n                    if ( iw * ih > 1024 * 1024 ) {\n                        canvas = document.createElement('canvas');\n                        canvas.width = canvas.height = 1;\n                        ctx = canvas.getContext('2d');\n                        ctx.drawImage( img, -iw + 1, 0 );\n    \n                        // subsampled image becomes half smaller in rendering size.\n                        // check alpha channel value to confirm image is covering\n                        // edge pixel or not. if alpha value is 0\n                        // image is not covering, hence subsampled.\n                        return ctx.getImageData( 0, 0, 1, 1 ).data[ 3 ] === 0;\n                    } else {\n                        return false;\n                    }\n                }\n    \n    \n                return function( canvas, img, x, y, width, height ) {\n                    var iw = img.naturalWidth,\n                        ih = img.naturalHeight,\n                        ctx = canvas.getContext('2d'),\n                        subsampled = detectSubsampling( img ),\n                        doSquash = this.type === 'image/jpeg',\n                        d = 1024,\n                        sy = 0,\n                        dy = 0,\n                        tmpCanvas, tmpCtx, vertSquashRatio, dw, dh, sx, dx;\n    \n                    if ( subsampled ) {\n                        iw /= 2;\n                        ih /= 2;\n                    }\n    \n                    ctx.save();\n                    tmpCanvas = document.createElement('canvas');\n                    tmpCanvas.width = tmpCanvas.height = d;\n    \n                    tmpCtx = tmpCanvas.getContext('2d');\n                    vertSquashRatio = doSquash ?\n                            detectVerticalSquash( img, iw, ih ) : 1;\n    \n                    dw = Math.ceil( d * width / iw );\n                    dh = Math.ceil( d * height / ih / vertSquashRatio );\n    \n                    while ( sy < ih ) {\n                        sx = 0;\n                        dx = 0;\n                        while ( sx < iw ) {\n                            tmpCtx.clearRect( 0, 0, d, d );\n                            tmpCtx.drawImage( img, -sx, -sy );\n                            ctx.drawImage( tmpCanvas, 0, 0, d, d,\n                                    x + dx, y + dy, dw, dh );\n                            sx += d;\n                            dx += dw;\n                        }\n                        sy += d;\n                        dy += dh;\n                    }\n                    ctx.restore();\n                    tmpCanvas = tmpCtx = null;\n                };\n            })()\n        });\n    });\n    /**\n     * 这个方式性能不行，但是可以解决android里面的toDataUrl的bug\n     * android里面toDataUrl('image/jpege')得到的结果却是png.\n     *\n     * 所以这里没辙，只能借助这个工具\n     * @fileOverview jpeg encoder\n     */\n    define('runtime/html5/jpegencoder',[], function( require, exports, module ) {\n    \n        /*\n          Copyright (c) 2008, Adobe Systems Incorporated\n          All rights reserved.\n    \n          Redistribution and use in source and binary forms, with or without\n          modification, are permitted provided that the following conditions are\n          met:\n    \n          * Redistributions of source code must retain the above copyright notice,\n            this list of conditions and the following disclaimer.\n    \n          * Redistributions in binary form must reproduce the above copyright\n            notice, this list of conditions and the following disclaimer in the\n            documentation and/or other materials provided with the distribution.\n    \n          * Neither the name of Adobe Systems Incorporated nor the names of its\n            contributors may be used to endorse or promote products derived from\n            this software without specific prior written permission.\n    \n          THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\n          IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n          THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n          PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n          CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n          EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n          PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n          PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n          LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n          NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n          SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n        */\n        /*\n        JPEG encoder ported to JavaScript and optimized by Andreas Ritter, www.bytestrom.eu, 11/2009\n    \n        Basic GUI blocking jpeg encoder\n        */\n    \n        function JPEGEncoder(quality) {\n          var self = this;\n            var fround = Math.round;\n            var ffloor = Math.floor;\n            var YTable = new Array(64);\n            var UVTable = new Array(64);\n            var fdtbl_Y = new Array(64);\n            var fdtbl_UV = new Array(64);\n            var YDC_HT;\n            var UVDC_HT;\n            var YAC_HT;\n            var UVAC_HT;\n    \n            var bitcode = new Array(65535);\n            var category = new Array(65535);\n            var outputfDCTQuant = new Array(64);\n            var DU = new Array(64);\n            var byteout = [];\n            var bytenew = 0;\n            var bytepos = 7;\n    \n            var YDU = new Array(64);\n            var UDU = new Array(64);\n            var VDU = new Array(64);\n            var clt = new Array(256);\n            var RGB_YUV_TABLE = new Array(2048);\n            var currentQuality;\n    \n            var ZigZag = [\n                     0, 1, 5, 6,14,15,27,28,\n                     2, 4, 7,13,16,26,29,42,\n                     3, 8,12,17,25,30,41,43,\n                     9,11,18,24,31,40,44,53,\n                    10,19,23,32,39,45,52,54,\n                    20,22,33,38,46,51,55,60,\n                    21,34,37,47,50,56,59,61,\n                    35,36,48,49,57,58,62,63\n                ];\n    \n            var std_dc_luminance_nrcodes = [0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0];\n            var std_dc_luminance_values = [0,1,2,3,4,5,6,7,8,9,10,11];\n            var std_ac_luminance_nrcodes = [0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d];\n            var std_ac_luminance_values = [\n                    0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,\n                    0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,\n                    0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,\n                    0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,\n                    0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,\n                    0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,\n                    0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,\n                    0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,\n                    0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,\n                    0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,\n                    0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,\n                    0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,\n                    0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,\n                    0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,\n                    0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,\n                    0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,\n                    0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,\n                    0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,\n                    0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,\n                    0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,\n                    0xf9,0xfa\n                ];\n    \n            var std_dc_chrominance_nrcodes = [0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0];\n            var std_dc_chrominance_values = [0,1,2,3,4,5,6,7,8,9,10,11];\n            var std_ac_chrominance_nrcodes = [0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77];\n            var std_ac_chrominance_values = [\n                    0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,\n                    0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,\n                    0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,\n                    0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,\n                    0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,\n                    0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,\n                    0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,\n                    0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,\n                    0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,\n                    0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,\n                    0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,\n                    0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,\n                    0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,\n                    0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,\n                    0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,\n                    0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,\n                    0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,\n                    0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,\n                    0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,\n                    0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,\n                    0xf9,0xfa\n                ];\n    \n            function initQuantTables(sf){\n                    var YQT = [\n                        16, 11, 10, 16, 24, 40, 51, 61,\n                        12, 12, 14, 19, 26, 58, 60, 55,\n                        14, 13, 16, 24, 40, 57, 69, 56,\n                        14, 17, 22, 29, 51, 87, 80, 62,\n                        18, 22, 37, 56, 68,109,103, 77,\n                        24, 35, 55, 64, 81,104,113, 92,\n                        49, 64, 78, 87,103,121,120,101,\n                        72, 92, 95, 98,112,100,103, 99\n                    ];\n    \n                    for (var i = 0; i < 64; i++) {\n                        var t = ffloor((YQT[i]*sf+50)/100);\n                        if (t < 1) {\n                            t = 1;\n                        } else if (t > 255) {\n                            t = 255;\n                        }\n                        YTable[ZigZag[i]] = t;\n                    }\n                    var UVQT = [\n                        17, 18, 24, 47, 99, 99, 99, 99,\n                        18, 21, 26, 66, 99, 99, 99, 99,\n                        24, 26, 56, 99, 99, 99, 99, 99,\n                        47, 66, 99, 99, 99, 99, 99, 99,\n                        99, 99, 99, 99, 99, 99, 99, 99,\n                        99, 99, 99, 99, 99, 99, 99, 99,\n                        99, 99, 99, 99, 99, 99, 99, 99,\n                        99, 99, 99, 99, 99, 99, 99, 99\n                    ];\n                    for (var j = 0; j < 64; j++) {\n                        var u = ffloor((UVQT[j]*sf+50)/100);\n                        if (u < 1) {\n                            u = 1;\n                        } else if (u > 255) {\n                            u = 255;\n                        }\n                        UVTable[ZigZag[j]] = u;\n                    }\n                    var aasf = [\n                        1.0, 1.387039845, 1.306562965, 1.175875602,\n                        1.0, 0.785694958, 0.541196100, 0.275899379\n                    ];\n                    var k = 0;\n                    for (var row = 0; row < 8; row++)\n                    {\n                        for (var col = 0; col < 8; col++)\n                        {\n                            fdtbl_Y[k]  = (1.0 / (YTable [ZigZag[k]] * aasf[row] * aasf[col] * 8.0));\n                            fdtbl_UV[k] = (1.0 / (UVTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0));\n                            k++;\n                        }\n                    }\n                }\n    \n                function computeHuffmanTbl(nrcodes, std_table){\n                    var codevalue = 0;\n                    var pos_in_table = 0;\n                    var HT = new Array();\n                    for (var k = 1; k <= 16; k++) {\n                        for (var j = 1; j <= nrcodes[k]; j++) {\n                            HT[std_table[pos_in_table]] = [];\n                            HT[std_table[pos_in_table]][0] = codevalue;\n                            HT[std_table[pos_in_table]][1] = k;\n                            pos_in_table++;\n                            codevalue++;\n                        }\n                        codevalue*=2;\n                    }\n                    return HT;\n                }\n    \n                function initHuffmanTbl()\n                {\n                    YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values);\n                    UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values);\n                    YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values);\n                    UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values);\n                }\n    \n                function initCategoryNumber()\n                {\n                    var nrlower = 1;\n                    var nrupper = 2;\n                    for (var cat = 1; cat <= 15; cat++) {\n                        //Positive numbers\n                        for (var nr = nrlower; nr<nrupper; nr++) {\n                            category[32767+nr] = cat;\n                            bitcode[32767+nr] = [];\n                            bitcode[32767+nr][1] = cat;\n                            bitcode[32767+nr][0] = nr;\n                        }\n                        //Negative numbers\n                        for (var nrneg =-(nrupper-1); nrneg<=-nrlower; nrneg++) {\n                            category[32767+nrneg] = cat;\n                            bitcode[32767+nrneg] = [];\n                            bitcode[32767+nrneg][1] = cat;\n                            bitcode[32767+nrneg][0] = nrupper-1+nrneg;\n                        }\n                        nrlower <<= 1;\n                        nrupper <<= 1;\n                    }\n                }\n    \n                function initRGBYUVTable() {\n                    for(var i = 0; i < 256;i++) {\n                        RGB_YUV_TABLE[i]            =  19595 * i;\n                        RGB_YUV_TABLE[(i+ 256)>>0]  =  38470 * i;\n                        RGB_YUV_TABLE[(i+ 512)>>0]  =   7471 * i + 0x8000;\n                        RGB_YUV_TABLE[(i+ 768)>>0]  = -11059 * i;\n                        RGB_YUV_TABLE[(i+1024)>>0]  = -21709 * i;\n                        RGB_YUV_TABLE[(i+1280)>>0]  =  32768 * i + 0x807FFF;\n                        RGB_YUV_TABLE[(i+1536)>>0]  = -27439 * i;\n                        RGB_YUV_TABLE[(i+1792)>>0]  = - 5329 * i;\n                    }\n                }\n    \n                // IO functions\n                function writeBits(bs)\n                {\n                    var value = bs[0];\n                    var posval = bs[1]-1;\n                    while ( posval >= 0 ) {\n                        if (value & (1 << posval) ) {\n                            bytenew |= (1 << bytepos);\n                        }\n                        posval--;\n                        bytepos--;\n                        if (bytepos < 0) {\n                            if (bytenew == 0xFF) {\n                                writeByte(0xFF);\n                                writeByte(0);\n                            }\n                            else {\n                                writeByte(bytenew);\n                            }\n                            bytepos=7;\n                            bytenew=0;\n                        }\n                    }\n                }\n    \n                function writeByte(value)\n                {\n                    byteout.push(clt[value]); // write char directly instead of converting later\n                }\n    \n                function writeWord(value)\n                {\n                    writeByte((value>>8)&0xFF);\n                    writeByte((value   )&0xFF);\n                }\n    \n                // DCT & quantization core\n                function fDCTQuant(data, fdtbl)\n                {\n                    var d0, d1, d2, d3, d4, d5, d6, d7;\n                    /* Pass 1: process rows. */\n                    var dataOff=0;\n                    var i;\n                    var I8 = 8;\n                    var I64 = 64;\n                    for (i=0; i<I8; ++i)\n                    {\n                        d0 = data[dataOff];\n                        d1 = data[dataOff+1];\n                        d2 = data[dataOff+2];\n                        d3 = data[dataOff+3];\n                        d4 = data[dataOff+4];\n                        d5 = data[dataOff+5];\n                        d6 = data[dataOff+6];\n                        d7 = data[dataOff+7];\n    \n                        var tmp0 = d0 + d7;\n                        var tmp7 = d0 - d7;\n                        var tmp1 = d1 + d6;\n                        var tmp6 = d1 - d6;\n                        var tmp2 = d2 + d5;\n                        var tmp5 = d2 - d5;\n                        var tmp3 = d3 + d4;\n                        var tmp4 = d3 - d4;\n    \n                        /* Even part */\n                        var tmp10 = tmp0 + tmp3;    /* phase 2 */\n                        var tmp13 = tmp0 - tmp3;\n                        var tmp11 = tmp1 + tmp2;\n                        var tmp12 = tmp1 - tmp2;\n    \n                        data[dataOff] = tmp10 + tmp11; /* phase 3 */\n                        data[dataOff+4] = tmp10 - tmp11;\n    \n                        var z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */\n                        data[dataOff+2] = tmp13 + z1; /* phase 5 */\n                        data[dataOff+6] = tmp13 - z1;\n    \n                        /* Odd part */\n                        tmp10 = tmp4 + tmp5; /* phase 2 */\n                        tmp11 = tmp5 + tmp6;\n                        tmp12 = tmp6 + tmp7;\n    \n                        /* The rotator is modified from fig 4-8 to avoid extra negations. */\n                        var z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */\n                        var z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */\n                        var z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */\n                        var z3 = tmp11 * 0.707106781; /* c4 */\n    \n                        var z11 = tmp7 + z3;    /* phase 5 */\n                        var z13 = tmp7 - z3;\n    \n                        data[dataOff+5] = z13 + z2; /* phase 6 */\n                        data[dataOff+3] = z13 - z2;\n                        data[dataOff+1] = z11 + z4;\n                        data[dataOff+7] = z11 - z4;\n    \n                        dataOff += 8; /* advance pointer to next row */\n                    }\n    \n                    /* Pass 2: process columns. */\n                    dataOff = 0;\n                    for (i=0; i<I8; ++i)\n                    {\n                        d0 = data[dataOff];\n                        d1 = data[dataOff + 8];\n                        d2 = data[dataOff + 16];\n                        d3 = data[dataOff + 24];\n                        d4 = data[dataOff + 32];\n                        d5 = data[dataOff + 40];\n                        d6 = data[dataOff + 48];\n                        d7 = data[dataOff + 56];\n    \n                        var tmp0p2 = d0 + d7;\n                        var tmp7p2 = d0 - d7;\n                        var tmp1p2 = d1 + d6;\n                        var tmp6p2 = d1 - d6;\n                        var tmp2p2 = d2 + d5;\n                        var tmp5p2 = d2 - d5;\n                        var tmp3p2 = d3 + d4;\n                        var tmp4p2 = d3 - d4;\n    \n                        /* Even part */\n                        var tmp10p2 = tmp0p2 + tmp3p2;  /* phase 2 */\n                        var tmp13p2 = tmp0p2 - tmp3p2;\n                        var tmp11p2 = tmp1p2 + tmp2p2;\n                        var tmp12p2 = tmp1p2 - tmp2p2;\n    \n                        data[dataOff] = tmp10p2 + tmp11p2; /* phase 3 */\n                        data[dataOff+32] = tmp10p2 - tmp11p2;\n    \n                        var z1p2 = (tmp12p2 + tmp13p2) * 0.707106781; /* c4 */\n                        data[dataOff+16] = tmp13p2 + z1p2; /* phase 5 */\n                        data[dataOff+48] = tmp13p2 - z1p2;\n    \n                        /* Odd part */\n                        tmp10p2 = tmp4p2 + tmp5p2; /* phase 2 */\n                        tmp11p2 = tmp5p2 + tmp6p2;\n                        tmp12p2 = tmp6p2 + tmp7p2;\n    \n                        /* The rotator is modified from fig 4-8 to avoid extra negations. */\n                        var z5p2 = (tmp10p2 - tmp12p2) * 0.382683433; /* c6 */\n                        var z2p2 = 0.541196100 * tmp10p2 + z5p2; /* c2-c6 */\n                        var z4p2 = 1.306562965 * tmp12p2 + z5p2; /* c2+c6 */\n                        var z3p2 = tmp11p2 * 0.707106781; /* c4 */\n    \n                        var z11p2 = tmp7p2 + z3p2;  /* phase 5 */\n                        var z13p2 = tmp7p2 - z3p2;\n    \n                        data[dataOff+40] = z13p2 + z2p2; /* phase 6 */\n                        data[dataOff+24] = z13p2 - z2p2;\n                        data[dataOff+ 8] = z11p2 + z4p2;\n                        data[dataOff+56] = z11p2 - z4p2;\n    \n                        dataOff++; /* advance pointer to next column */\n                    }\n    \n                    // Quantize/descale the coefficients\n                    var fDCTQuant;\n                    for (i=0; i<I64; ++i)\n                    {\n                        // Apply the quantization and scaling factor & Round to nearest integer\n                        fDCTQuant = data[i]*fdtbl[i];\n                        outputfDCTQuant[i] = (fDCTQuant > 0.0) ? ((fDCTQuant + 0.5)|0) : ((fDCTQuant - 0.5)|0);\n                        //outputfDCTQuant[i] = fround(fDCTQuant);\n    \n                    }\n                    return outputfDCTQuant;\n                }\n    \n                function writeAPP0()\n                {\n                    writeWord(0xFFE0); // marker\n                    writeWord(16); // length\n                    writeByte(0x4A); // J\n                    writeByte(0x46); // F\n                    writeByte(0x49); // I\n                    writeByte(0x46); // F\n                    writeByte(0); // = \"JFIF\",'\\0'\n                    writeByte(1); // versionhi\n                    writeByte(1); // versionlo\n                    writeByte(0); // xyunits\n                    writeWord(1); // xdensity\n                    writeWord(1); // ydensity\n                    writeByte(0); // thumbnwidth\n                    writeByte(0); // thumbnheight\n                }\n    \n                function writeSOF0(width, height)\n                {\n                    writeWord(0xFFC0); // marker\n                    writeWord(17);   // length, truecolor YUV JPG\n                    writeByte(8);    // precision\n                    writeWord(height);\n                    writeWord(width);\n                    writeByte(3);    // nrofcomponents\n                    writeByte(1);    // IdY\n                    writeByte(0x11); // HVY\n                    writeByte(0);    // QTY\n                    writeByte(2);    // IdU\n                    writeByte(0x11); // HVU\n                    writeByte(1);    // QTU\n                    writeByte(3);    // IdV\n                    writeByte(0x11); // HVV\n                    writeByte(1);    // QTV\n                }\n    \n                function writeDQT()\n                {\n                    writeWord(0xFFDB); // marker\n                    writeWord(132);    // length\n                    writeByte(0);\n                    for (var i=0; i<64; i++) {\n                        writeByte(YTable[i]);\n                    }\n                    writeByte(1);\n                    for (var j=0; j<64; j++) {\n                        writeByte(UVTable[j]);\n                    }\n                }\n    \n                function writeDHT()\n                {\n                    writeWord(0xFFC4); // marker\n                    writeWord(0x01A2); // length\n    \n                    writeByte(0); // HTYDCinfo\n                    for (var i=0; i<16; i++) {\n                        writeByte(std_dc_luminance_nrcodes[i+1]);\n                    }\n                    for (var j=0; j<=11; j++) {\n                        writeByte(std_dc_luminance_values[j]);\n                    }\n    \n                    writeByte(0x10); // HTYACinfo\n                    for (var k=0; k<16; k++) {\n                        writeByte(std_ac_luminance_nrcodes[k+1]);\n                    }\n                    for (var l=0; l<=161; l++) {\n                        writeByte(std_ac_luminance_values[l]);\n                    }\n    \n                    writeByte(1); // HTUDCinfo\n                    for (var m=0; m<16; m++) {\n                        writeByte(std_dc_chrominance_nrcodes[m+1]);\n                    }\n                    for (var n=0; n<=11; n++) {\n                        writeByte(std_dc_chrominance_values[n]);\n                    }\n    \n                    writeByte(0x11); // HTUACinfo\n                    for (var o=0; o<16; o++) {\n                        writeByte(std_ac_chrominance_nrcodes[o+1]);\n                    }\n                    for (var p=0; p<=161; p++) {\n                        writeByte(std_ac_chrominance_values[p]);\n                    }\n                }\n    \n                function writeSOS()\n                {\n                    writeWord(0xFFDA); // marker\n                    writeWord(12); // length\n                    writeByte(3); // nrofcomponents\n                    writeByte(1); // IdY\n                    writeByte(0); // HTY\n                    writeByte(2); // IdU\n                    writeByte(0x11); // HTU\n                    writeByte(3); // IdV\n                    writeByte(0x11); // HTV\n                    writeByte(0); // Ss\n                    writeByte(0x3f); // Se\n                    writeByte(0); // Bf\n                }\n    \n                function processDU(CDU, fdtbl, DC, HTDC, HTAC){\n                    var EOB = HTAC[0x00];\n                    var M16zeroes = HTAC[0xF0];\n                    var pos;\n                    var I16 = 16;\n                    var I63 = 63;\n                    var I64 = 64;\n                    var DU_DCT = fDCTQuant(CDU, fdtbl);\n                    //ZigZag reorder\n                    for (var j=0;j<I64;++j) {\n                        DU[ZigZag[j]]=DU_DCT[j];\n                    }\n                    var Diff = DU[0] - DC; DC = DU[0];\n                    //Encode DC\n                    if (Diff==0) {\n                        writeBits(HTDC[0]); // Diff might be 0\n                    } else {\n                        pos = 32767+Diff;\n                        writeBits(HTDC[category[pos]]);\n                        writeBits(bitcode[pos]);\n                    }\n                    //Encode ACs\n                    var end0pos = 63; // was const... which is crazy\n                    for (; (end0pos>0)&&(DU[end0pos]==0); end0pos--) {};\n                    //end0pos = first element in reverse order !=0\n                    if ( end0pos == 0) {\n                        writeBits(EOB);\n                        return DC;\n                    }\n                    var i = 1;\n                    var lng;\n                    while ( i <= end0pos ) {\n                        var startpos = i;\n                        for (; (DU[i]==0) && (i<=end0pos); ++i) {}\n                        var nrzeroes = i-startpos;\n                        if ( nrzeroes >= I16 ) {\n                            lng = nrzeroes>>4;\n                            for (var nrmarker=1; nrmarker <= lng; ++nrmarker)\n                                writeBits(M16zeroes);\n                            nrzeroes = nrzeroes&0xF;\n                        }\n                        pos = 32767+DU[i];\n                        writeBits(HTAC[(nrzeroes<<4)+category[pos]]);\n                        writeBits(bitcode[pos]);\n                        i++;\n                    }\n                    if ( end0pos != I63 ) {\n                        writeBits(EOB);\n                    }\n                    return DC;\n                }\n    \n                function initCharLookupTable(){\n                    var sfcc = String.fromCharCode;\n                    for(var i=0; i < 256; i++){ ///// ACHTUNG // 255\n                        clt[i] = sfcc(i);\n                    }\n                }\n    \n                this.encode = function(image,quality) // image data object\n                {\n                    // var time_start = new Date().getTime();\n    \n                    if(quality) setQuality(quality);\n    \n                    // Initialize bit writer\n                    byteout = new Array();\n                    bytenew=0;\n                    bytepos=7;\n    \n                    // Add JPEG headers\n                    writeWord(0xFFD8); // SOI\n                    writeAPP0();\n                    writeDQT();\n                    writeSOF0(image.width,image.height);\n                    writeDHT();\n                    writeSOS();\n    \n    \n                    // Encode 8x8 macroblocks\n                    var DCY=0;\n                    var DCU=0;\n                    var DCV=0;\n    \n                    bytenew=0;\n                    bytepos=7;\n    \n    \n                    this.encode.displayName = \"_encode_\";\n    \n                    var imageData = image.data;\n                    var width = image.width;\n                    var height = image.height;\n    \n                    var quadWidth = width*4;\n                    var tripleWidth = width*3;\n    \n                    var x, y = 0;\n                    var r, g, b;\n                    var start,p, col,row,pos;\n                    while(y < height){\n                        x = 0;\n                        while(x < quadWidth){\n                        start = quadWidth * y + x;\n                        p = start;\n                        col = -1;\n                        row = 0;\n    \n                        for(pos=0; pos < 64; pos++){\n                            row = pos >> 3;// /8\n                            col = ( pos & 7 ) * 4; // %8\n                            p = start + ( row * quadWidth ) + col;\n    \n                            if(y+row >= height){ // padding bottom\n                                p-= (quadWidth*(y+1+row-height));\n                            }\n    \n                            if(x+col >= quadWidth){ // padding right\n                                p-= ((x+col) - quadWidth +4)\n                            }\n    \n                            r = imageData[ p++ ];\n                            g = imageData[ p++ ];\n                            b = imageData[ p++ ];\n    \n    \n                            /* // calculate YUV values dynamically\n                            YDU[pos]=((( 0.29900)*r+( 0.58700)*g+( 0.11400)*b))-128; //-0x80\n                            UDU[pos]=(((-0.16874)*r+(-0.33126)*g+( 0.50000)*b));\n                            VDU[pos]=((( 0.50000)*r+(-0.41869)*g+(-0.08131)*b));\n                            */\n    \n                            // use lookup table (slightly faster)\n                            YDU[pos] = ((RGB_YUV_TABLE[r]             + RGB_YUV_TABLE[(g +  256)>>0] + RGB_YUV_TABLE[(b +  512)>>0]) >> 16)-128;\n                            UDU[pos] = ((RGB_YUV_TABLE[(r +  768)>>0] + RGB_YUV_TABLE[(g + 1024)>>0] + RGB_YUV_TABLE[(b + 1280)>>0]) >> 16)-128;\n                            VDU[pos] = ((RGB_YUV_TABLE[(r + 1280)>>0] + RGB_YUV_TABLE[(g + 1536)>>0] + RGB_YUV_TABLE[(b + 1792)>>0]) >> 16)-128;\n    \n                        }\n    \n                        DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);\n                        DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);\n                        DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);\n                        x+=32;\n                        }\n                        y+=8;\n                    }\n    \n    \n                    ////////////////////////////////////////////////////////////////\n    \n                    // Do the bit alignment of the EOI marker\n                    if ( bytepos >= 0 ) {\n                        var fillbits = [];\n                        fillbits[1] = bytepos+1;\n                        fillbits[0] = (1<<(bytepos+1))-1;\n                        writeBits(fillbits);\n                    }\n    \n                    writeWord(0xFFD9); //EOI\n    \n                    var jpegDataUri = 'data:image/jpeg;base64,' + btoa(byteout.join(''));\n    \n                    byteout = [];\n    \n                    // benchmarking\n                    // var duration = new Date().getTime() - time_start;\n                    // console.log('Encoding time: '+ currentQuality + 'ms');\n                    //\n    \n                    return jpegDataUri\n            }\n    \n            function setQuality(quality){\n                if (quality <= 0) {\n                    quality = 1;\n                }\n                if (quality > 100) {\n                    quality = 100;\n                }\n    \n                if(currentQuality == quality) return // don't recalc if unchanged\n    \n                var sf = 0;\n                if (quality < 50) {\n                    sf = Math.floor(5000 / quality);\n                } else {\n                    sf = Math.floor(200 - quality*2);\n                }\n    \n                initQuantTables(sf);\n                currentQuality = quality;\n                // console.log('Quality set to: '+quality +'%');\n            }\n    \n            function init(){\n                // var time_start = new Date().getTime();\n                if(!quality) quality = 50;\n                // Create tables\n                initCharLookupTable()\n                initHuffmanTbl();\n                initCategoryNumber();\n                initRGBYUVTable();\n    \n                setQuality(quality);\n                // var duration = new Date().getTime() - time_start;\n                // console.log('Initialization '+ duration + 'ms');\n            }\n    \n            init();\n    \n        };\n    \n        JPEGEncoder.encode = function( data, quality ) {\n            var encoder = new JPEGEncoder( quality );\n    \n            return encoder.encode( data );\n        }\n    \n        return JPEGEncoder;\n    });\n    /**\n     * @fileOverview Fix android canvas.toDataUrl bug.\n     */\n    define('runtime/html5/androidpatch',[\n        'runtime/html5/util',\n        'runtime/html5/jpegencoder',\n        'base'\n    ], function( Util, encoder, Base ) {\n        var origin = Util.canvasToDataUrl,\n            supportJpeg;\n    \n        Util.canvasToDataUrl = function( canvas, type, quality ) {\n            var ctx, w, h, fragement, parts;\n    \n            // 非android手机直接跳过。\n            if ( !Base.os.android ) {\n                return origin.apply( null, arguments );\n            }\n    \n            // 检测是否canvas支持jpeg导出，根据数据格式来判断。\n            // JPEG 前两位分别是：255, 216\n            if ( type === 'image/jpeg' && typeof supportJpeg === 'undefined' ) {\n                fragement = origin.apply( null, arguments );\n    \n                parts = fragement.split(',');\n    \n                if ( ~parts[ 0 ].indexOf('base64') ) {\n                    fragement = atob( parts[ 1 ] );\n                } else {\n                    fragement = decodeURIComponent( parts[ 1 ] );\n                }\n    \n                fragement = fragement.substring( 0, 2 );\n    \n                supportJpeg = fragement.charCodeAt( 0 ) === 255 &&\n                        fragement.charCodeAt( 1 ) === 216;\n            }\n    \n            // 只有在android环境下才修复\n            if ( type === 'image/jpeg' && !supportJpeg ) {\n                w = canvas.width;\n                h = canvas.height;\n                ctx = canvas.getContext('2d');\n    \n                return encoder.encode( ctx.getImageData( 0, 0, w, h ), quality );\n            }\n    \n            return origin.apply( null, arguments );\n        };\n    });\n    /**\n     * @fileOverview Transport\n     * @todo 支持chunked传输，优势：\n     * 可以将大文件分成小块，挨个传输，可以提高大文件成功率，当失败的时候，也只需要重传那小部分，\n     * 而不需要重头再传一次。另外断点续传也需要用chunked方式。\n     */\n    define('runtime/html5/transport',[\n        'base',\n        'runtime/html5/runtime'\n    ], function( Base, Html5Runtime ) {\n    \n        var noop = Base.noop,\n            $ = Base.$;\n    \n        return Html5Runtime.register( 'Transport', {\n            init: function() {\n                this._status = 0;\n                this._response = null;\n            },\n    \n            send: function() {\n                var owner = this.owner,\n                    opts = this.options,\n                    xhr = this._initAjax(),\n                    blob = owner._blob,\n                    server = opts.server,\n                    formData, binary, fr;\n    \n                if ( opts.sendAsBinary ) {\n                    server += (/\\?/.test( server ) ? '&' : '?') +\n                            $.param( owner._formData );\n    \n                    binary = blob.getSource();\n                } else {\n                    formData = new FormData();\n                    $.each( owner._formData, function( k, v ) {\n                        formData.append( k, v );\n                    });\n    \n                    formData.append( opts.fileVal, blob.getSource(),\n                            opts.filename || owner._formData.name || '' );\n                }\n    \n                if ( opts.withCredentials && 'withCredentials' in xhr ) {\n                    xhr.open( opts.method, server, true );\n                    xhr.withCredentials = true;\n                } else {\n                    xhr.open( opts.method, server );\n                }\n    \n                this._setRequestHeader( xhr, opts.headers );\n    \n                if ( binary ) {\n                    xhr.overrideMimeType('application/octet-stream');\n    \n                    // android直接发送blob会导致服务端接收到的是空文件。\n                    // bug详情。\n                    // https://code.google.com/p/android/issues/detail?id=39882\n                    // 所以先用fileReader读取出来再通过arraybuffer的方式发送。\n                    if ( Base.os.android ) {\n                        fr = new FileReader();\n    \n                        fr.onload = function() {\n                            xhr.send( this.result );\n                            fr = fr.onload = null;\n                        };\n    \n                        fr.readAsArrayBuffer( binary );\n                    } else {\n                        xhr.send( binary );\n                    }\n                } else {\n                    xhr.send( formData );\n                }\n            },\n    \n            getResponse: function() {\n                return this._response;\n            },\n    \n            getResponseAsJson: function() {\n                return this._parseJson( this._response );\n            },\n    \n            getStatus: function() {\n                return this._status;\n            },\n    \n            abort: function() {\n                var xhr = this._xhr;\n    \n                if ( xhr ) {\n                    xhr.upload.onprogress = noop;\n                    xhr.onreadystatechange = noop;\n                    xhr.abort();\n    \n                    this._xhr = xhr = null;\n                }\n            },\n    \n            destroy: function() {\n                this.abort();\n            },\n    \n            _initAjax: function() {\n                var me = this,\n                    xhr = new XMLHttpRequest(),\n                    opts = this.options;\n    \n                if ( opts.withCredentials && !('withCredentials' in xhr) &&\n                        typeof XDomainRequest !== 'undefined' ) {\n                    xhr = new XDomainRequest();\n                }\n    \n                xhr.upload.onprogress = function( e ) {\n                    var percentage = 0;\n    \n                    if ( e.lengthComputable ) {\n                        percentage = e.loaded / e.total;\n                    }\n    \n                    return me.trigger( 'progress', percentage );\n                };\n    \n                xhr.onreadystatechange = function() {\n    \n                    if ( xhr.readyState !== 4 ) {\n                        return;\n                    }\n    \n                    xhr.upload.onprogress = noop;\n                    xhr.onreadystatechange = noop;\n                    me._xhr = null;\n                    me._status = xhr.status;\n    \n                    if ( xhr.status >= 200 && xhr.status < 300 ) {\n                        me._response = xhr.responseText;\n                        return me.trigger('load');\n                    } else if ( xhr.status >= 500 && xhr.status < 600 ) {\n                        me._response = xhr.responseText;\n                        return me.trigger( 'error', 'server' );\n                    }\n    \n    \n                    return me.trigger( 'error', me._status ? 'http' : 'abort' );\n                };\n    \n                me._xhr = xhr;\n                return xhr;\n            },\n    \n            _setRequestHeader: function( xhr, headers ) {\n                $.each( headers, function( key, val ) {\n                    xhr.setRequestHeader( key, val );\n                });\n            },\n    \n            _parseJson: function( str ) {\n                var json;\n    \n                try {\n                    json = JSON.parse( str );\n                } catch ( ex ) {\n                    json = {};\n                }\n    \n                return json;\n            }\n        });\n    });\n    define('webuploader',[\n        'base',\n        'widgets/filepicker',\n        'widgets/image',\n        'widgets/queue',\n        'widgets/runtime',\n        'widgets/upload',\n        'runtime/html5/blob',\n        'runtime/html5/filepicker',\n        'runtime/html5/imagemeta/exif',\n        'runtime/html5/image',\n        'runtime/html5/androidpatch',\n        'runtime/html5/transport'\n    ], function( Base ) {\n        return Base;\n    });\n    return require('webuploader');\n});\n"
  },
  {
    "path": "public/static/ueditor/third-party/webuploader/webuploader.flashonly.js",
    "content": "/*! WebUploader 0.1.2 */\n\n\n/**\n * @fileOverview 让内部各个部件的代码可以用[amd](https://github.com/amdjs/amdjs-api/wiki/AMD)模块定义方式组织起来。\n *\n * AMD API 内部的简单不完全实现，请忽略。只有当WebUploader被合并成一个文件的时候才会引入。\n */\n(function( root, factory ) {\n    var modules = {},\n\n        // 内部require, 简单不完全实现。\n        // https://github.com/amdjs/amdjs-api/wiki/require\n        _require = function( deps, callback ) {\n            var args, len, i;\n\n            // 如果deps不是数组，则直接返回指定module\n            if ( typeof deps === 'string' ) {\n                return getModule( deps );\n            } else {\n                args = [];\n                for( len = deps.length, i = 0; i < len; i++ ) {\n                    args.push( getModule( deps[ i ] ) );\n                }\n\n                return callback.apply( null, args );\n            }\n        },\n\n        // 内部define，暂时不支持不指定id.\n        _define = function( id, deps, factory ) {\n            if ( arguments.length === 2 ) {\n                factory = deps;\n                deps = null;\n            }\n\n            _require( deps || [], function() {\n                setModule( id, factory, arguments );\n            });\n        },\n\n        // 设置module, 兼容CommonJs写法。\n        setModule = function( id, factory, args ) {\n            var module = {\n                    exports: factory\n                },\n                returned;\n\n            if ( typeof factory === 'function' ) {\n                args.length || (args = [ _require, module.exports, module ]);\n                returned = factory.apply( null, args );\n                returned !== undefined && (module.exports = returned);\n            }\n\n            modules[ id ] = module.exports;\n        },\n\n        // 根据id获取module\n        getModule = function( id ) {\n            var module = modules[ id ] || root[ id ];\n\n            if ( !module ) {\n                throw new Error( '`' + id + '` is undefined' );\n            }\n\n            return module;\n        },\n\n        // 将所有modules，将路径ids装换成对象。\n        exportsTo = function( obj ) {\n            var key, host, parts, part, last, ucFirst;\n\n            // make the first character upper case.\n            ucFirst = function( str ) {\n                return str && (str.charAt( 0 ).toUpperCase() + str.substr( 1 ));\n            };\n\n            for ( key in modules ) {\n                host = obj;\n\n                if ( !modules.hasOwnProperty( key ) ) {\n                    continue;\n                }\n\n                parts = key.split('/');\n                last = ucFirst( parts.pop() );\n\n                while( (part = ucFirst( parts.shift() )) ) {\n                    host[ part ] = host[ part ] || {};\n                    host = host[ part ];\n                }\n\n                host[ last ] = modules[ key ];\n            }\n        },\n\n        exports = factory( root, _define, _require ),\n        origin;\n\n    // exports every module.\n    exportsTo( exports );\n\n    if ( typeof module === 'object' && typeof module.exports === 'object' ) {\n\n        // For CommonJS and CommonJS-like environments where a proper window is present,\n        module.exports = exports;\n    } else if ( typeof define === 'function' && define.amd ) {\n\n        // Allow using this built library as an AMD module\n        // in another project. That other project will only\n        // see this AMD call, not the internal modules in\n        // the closure below.\n        define([], exports );\n    } else {\n\n        // Browser globals case. Just assign the\n        // result to a property on the global.\n        origin = root.WebUploader;\n        root.WebUploader = exports;\n        root.WebUploader.noConflict = function() {\n            root.WebUploader = origin;\n        };\n    }\n})( this, function( window, define, require ) {\n\n\n    /**\n     * @fileOverview jQuery or Zepto\n     */\n    define('dollar-third',[],function() {\n        return window.jQuery || window.Zepto;\n    });\n    /**\n     * @fileOverview Dom 操作相关\n     */\n    define('dollar',[\n        'dollar-third'\n    ], function( _ ) {\n        return _;\n    });\n    /**\n     * @fileOverview 使用jQuery的Promise\n     */\n    define('promise-third',[\n        'dollar'\n    ], function( $ ) {\n        return {\n            Deferred: $.Deferred,\n            when: $.when,\n    \n            isPromise: function( anything ) {\n                return anything && typeof anything.then === 'function';\n            }\n        };\n    });\n    /**\n     * @fileOverview Promise/A+\n     */\n    define('promise',[\n        'promise-third'\n    ], function( _ ) {\n        return _;\n    });\n    /**\n     * @fileOverview 基础类方法。\n     */\n    \n    /**\n     * Web Uploader内部类的详细说明，以下提及的功能类，都可以在`WebUploader`这个变量中访问到。\n     *\n     * As you know, Web Uploader的每个文件都是用过[AMD](https://github.com/amdjs/amdjs-api/wiki/AMD)规范中的`define`组织起来的, 每个Module都会有个module id.\n     * 默认module id该文件的路径，而此路径将会转化成名字空间存放在WebUploader中。如：\n     *\n     * * module `base`：WebUploader.Base\n     * * module `file`: WebUploader.File\n     * * module `lib/dnd`: WebUploader.Lib.Dnd\n     * * module `runtime/html5/dnd`: WebUploader.Runtime.Html5.Dnd\n     *\n     *\n     * 以下文档将可能省略`WebUploader`前缀。\n     * @module WebUploader\n     * @title WebUploader API文档\n     */\n    define('base',[\n        'dollar',\n        'promise'\n    ], function( $, promise ) {\n    \n        var noop = function() {},\n            call = Function.call;\n    \n        // http://jsperf.com/uncurrythis\n        // 反科里化\n        function uncurryThis( fn ) {\n            return function() {\n                return call.apply( fn, arguments );\n            };\n        }\n    \n        function bindFn( fn, context ) {\n            return function() {\n                return fn.apply( context, arguments );\n            };\n        }\n    \n        function createObject( proto ) {\n            var f;\n    \n            if ( Object.create ) {\n                return Object.create( proto );\n            } else {\n                f = function() {};\n                f.prototype = proto;\n                return new f();\n            }\n        }\n    \n    \n        /**\n         * 基础类，提供一些简单常用的方法。\n         * @class Base\n         */\n        return {\n    \n            /**\n             * @property {String} version 当前版本号。\n             */\n            version: '0.1.2',\n    \n            /**\n             * @property {jQuery|Zepto} $ 引用依赖的jQuery或者Zepto对象。\n             */\n            $: $,\n    \n            Deferred: promise.Deferred,\n    \n            isPromise: promise.isPromise,\n    \n            when: promise.when,\n    \n            /**\n             * @description  简单的浏览器检查结果。\n             *\n             * * `webkit`  webkit版本号，如果浏览器为非webkit内核，此属性为`undefined`。\n             * * `chrome`  chrome浏览器版本号，如果浏览器为chrome，此属性为`undefined`。\n             * * `ie`  ie浏览器版本号，如果浏览器为非ie，此属性为`undefined`。**暂不支持ie10+**\n             * * `firefox`  firefox浏览器版本号，如果浏览器为非firefox，此属性为`undefined`。\n             * * `safari`  safari浏览器版本号，如果浏览器为非safari，此属性为`undefined`。\n             * * `opera`  opera浏览器版本号，如果浏览器为非opera，此属性为`undefined`。\n             *\n             * @property {Object} [browser]\n             */\n            browser: (function( ua ) {\n                var ret = {},\n                    webkit = ua.match( /WebKit\\/([\\d.]+)/ ),\n                    chrome = ua.match( /Chrome\\/([\\d.]+)/ ) ||\n                        ua.match( /CriOS\\/([\\d.]+)/ ),\n    \n                    ie = ua.match( /MSIE\\s([\\d\\.]+)/ ) ||\n                        ua.match(/(?:trident)(?:.*rv:([\\w.]+))?/i),\n                    firefox = ua.match( /Firefox\\/([\\d.]+)/ ),\n                    safari = ua.match( /Safari\\/([\\d.]+)/ ),\n                    opera = ua.match( /OPR\\/([\\d.]+)/ );\n    \n                webkit && (ret.webkit = parseFloat( webkit[ 1 ] ));\n                chrome && (ret.chrome = parseFloat( chrome[ 1 ] ));\n                ie && (ret.ie = parseFloat( ie[ 1 ] ));\n                firefox && (ret.firefox = parseFloat( firefox[ 1 ] ));\n                safari && (ret.safari = parseFloat( safari[ 1 ] ));\n                opera && (ret.opera = parseFloat( opera[ 1 ] ));\n    \n                return ret;\n            })( navigator.userAgent ),\n    \n            /**\n             * @description  操作系统检查结果。\n             *\n             * * `android`  如果在android浏览器环境下，此值为对应的android版本号，否则为`undefined`。\n             * * `ios` 如果在ios浏览器环境下，此值为对应的ios版本号，否则为`undefined`。\n             * @property {Object} [os]\n             */\n            os: (function( ua ) {\n                var ret = {},\n    \n                    // osx = !!ua.match( /\\(Macintosh\\; Intel / ),\n                    android = ua.match( /(?:Android);?[\\s\\/]+([\\d.]+)?/ ),\n                    ios = ua.match( /(?:iPad|iPod|iPhone).*OS\\s([\\d_]+)/ );\n    \n                // osx && (ret.osx = true);\n                android && (ret.android = parseFloat( android[ 1 ] ));\n                ios && (ret.ios = parseFloat( ios[ 1 ].replace( /_/g, '.' ) ));\n    \n                return ret;\n            })( navigator.userAgent ),\n    \n            /**\n             * 实现类与类之间的继承。\n             * @method inherits\n             * @grammar Base.inherits( super ) => child\n             * @grammar Base.inherits( super, protos ) => child\n             * @grammar Base.inherits( super, protos, statics ) => child\n             * @param  {Class} super 父类\n             * @param  {Object | Function} [protos] 子类或者对象。如果对象中包含constructor，子类将是用此属性值。\n             * @param  {Function} [protos.constructor] 子类构造器，不指定的话将创建个临时的直接执行父类构造器的方法。\n             * @param  {Object} [statics] 静态属性或方法。\n             * @return {Class} 返回子类。\n             * @example\n             * function Person() {\n             *     console.log( 'Super' );\n             * }\n             * Person.prototype.hello = function() {\n             *     console.log( 'hello' );\n             * };\n             *\n             * var Manager = Base.inherits( Person, {\n             *     world: function() {\n             *         console.log( 'World' );\n             *     }\n             * });\n             *\n             * // 因为没有指定构造器，父类的构造器将会执行。\n             * var instance = new Manager();    // => Super\n             *\n             * // 继承子父类的方法\n             * instance.hello();    // => hello\n             * instance.world();    // => World\n             *\n             * // 子类的__super__属性指向父类\n             * console.log( Manager.__super__ === Person );    // => true\n             */\n            inherits: function( Super, protos, staticProtos ) {\n                var child;\n    \n                if ( typeof protos === 'function' ) {\n                    child = protos;\n                    protos = null;\n                } else if ( protos && protos.hasOwnProperty('constructor') ) {\n                    child = protos.constructor;\n                } else {\n                    child = function() {\n                        return Super.apply( this, arguments );\n                    };\n                }\n    \n                // 复制静态方法\n                $.extend( true, child, Super, staticProtos || {} );\n    \n                /* jshint camelcase: false */\n    \n                // 让子类的__super__属性指向父类。\n                child.__super__ = Super.prototype;\n    \n                // 构建原型，添加原型方法或属性。\n                // 暂时用Object.create实现。\n                child.prototype = createObject( Super.prototype );\n                protos && $.extend( true, child.prototype, protos );\n    \n                return child;\n            },\n    \n            /**\n             * 一个不做任何事情的方法。可以用来赋值给默认的callback.\n             * @method noop\n             */\n            noop: noop,\n    \n            /**\n             * 返回一个新的方法，此方法将已指定的`context`来执行。\n             * @grammar Base.bindFn( fn, context ) => Function\n             * @method bindFn\n             * @example\n             * var doSomething = function() {\n             *         console.log( this.name );\n             *     },\n             *     obj = {\n             *         name: 'Object Name'\n             *     },\n             *     aliasFn = Base.bind( doSomething, obj );\n             *\n             *  aliasFn();    // => Object Name\n             *\n             */\n            bindFn: bindFn,\n    \n            /**\n             * 引用Console.log如果存在的话，否则引用一个[空函数loop](#WebUploader:Base.log)。\n             * @grammar Base.log( args... ) => undefined\n             * @method log\n             */\n            log: (function() {\n                if ( window.console ) {\n                    return bindFn( console.log, console );\n                }\n                return noop;\n            })(),\n    \n            nextTick: (function() {\n    \n                return function( cb ) {\n                    setTimeout( cb, 1 );\n                };\n    \n                // @bug 当浏览器不在当前窗口时就停了。\n                // var next = window.requestAnimationFrame ||\n                //     window.webkitRequestAnimationFrame ||\n                //     window.mozRequestAnimationFrame ||\n                //     function( cb ) {\n                //         window.setTimeout( cb, 1000 / 60 );\n                //     };\n    \n                // // fix: Uncaught TypeError: Illegal invocation\n                // return bindFn( next, window );\n            })(),\n    \n            /**\n             * 被[uncurrythis](http://www.2ality.com/2011/11/uncurrying-this.html)的数组slice方法。\n             * 将用来将非数组对象转化成数组对象。\n             * @grammar Base.slice( target, start[, end] ) => Array\n             * @method slice\n             * @example\n             * function doSomthing() {\n             *     var args = Base.slice( arguments, 1 );\n             *     console.log( args );\n             * }\n             *\n             * doSomthing( 'ignored', 'arg2', 'arg3' );    // => Array [\"arg2\", \"arg3\"]\n             */\n            slice: uncurryThis( [].slice ),\n    \n            /**\n             * 生成唯一的ID\n             * @method guid\n             * @grammar Base.guid() => String\n             * @grammar Base.guid( prefx ) => String\n             */\n            guid: (function() {\n                var counter = 0;\n    \n                return function( prefix ) {\n                    var guid = (+new Date()).toString( 32 ),\n                        i = 0;\n    \n                    for ( ; i < 5; i++ ) {\n                        guid += Math.floor( Math.random() * 65535 ).toString( 32 );\n                    }\n    \n                    return (prefix || 'wu_') + guid + (counter++).toString( 32 );\n                };\n            })(),\n    \n            /**\n             * 格式化文件大小, 输出成带单位的字符串\n             * @method formatSize\n             * @grammar Base.formatSize( size ) => String\n             * @grammar Base.formatSize( size, pointLength ) => String\n             * @grammar Base.formatSize( size, pointLength, units ) => String\n             * @param {Number} size 文件大小\n             * @param {Number} [pointLength=2] 精确到的小数点数。\n             * @param {Array} [units=[ 'B', 'K', 'M', 'G', 'TB' ]] 单位数组。从字节，到千字节，一直往上指定。如果单位数组里面只指定了到了K(千字节)，同时文件大小大于M, 此方法的输出将还是显示成多少K.\n             * @example\n             * console.log( Base.formatSize( 100 ) );    // => 100B\n             * console.log( Base.formatSize( 1024 ) );    // => 1.00K\n             * console.log( Base.formatSize( 1024, 0 ) );    // => 1K\n             * console.log( Base.formatSize( 1024 * 1024 ) );    // => 1.00M\n             * console.log( Base.formatSize( 1024 * 1024 * 1024 ) );    // => 1.00G\n             * console.log( Base.formatSize( 1024 * 1024 * 1024, 0, ['B', 'KB', 'MB'] ) );    // => 1024MB\n             */\n            formatSize: function( size, pointLength, units ) {\n                var unit;\n    \n                units = units || [ 'B', 'K', 'M', 'G', 'TB' ];\n    \n                while ( (unit = units.shift()) && size > 1024 ) {\n                    size = size / 1024;\n                }\n    \n                return (unit === 'B' ? size : size.toFixed( pointLength || 2 )) +\n                        unit;\n            }\n        };\n    });\n    /**\n     * 事件处理类，可以独立使用，也可以扩展给对象使用。\n     * @fileOverview Mediator\n     */\n    define('mediator',[\n        'base'\n    ], function( Base ) {\n        var $ = Base.$,\n            slice = [].slice,\n            separator = /\\s+/,\n            protos;\n    \n        // 根据条件过滤出事件handlers.\n        function findHandlers( arr, name, callback, context ) {\n            return $.grep( arr, function( handler ) {\n                return handler &&\n                        (!name || handler.e === name) &&\n                        (!callback || handler.cb === callback ||\n                        handler.cb._cb === callback) &&\n                        (!context || handler.ctx === context);\n            });\n        }\n    \n        function eachEvent( events, callback, iterator ) {\n            // 不支持对象，只支持多个event用空格隔开\n            $.each( (events || '').split( separator ), function( _, key ) {\n                iterator( key, callback );\n            });\n        }\n    \n        function triggerHanders( events, args ) {\n            var stoped = false,\n                i = -1,\n                len = events.length,\n                handler;\n    \n            while ( ++i < len ) {\n                handler = events[ i ];\n    \n                if ( handler.cb.apply( handler.ctx2, args ) === false ) {\n                    stoped = true;\n                    break;\n                }\n            }\n    \n            return !stoped;\n        }\n    \n        protos = {\n    \n            /**\n             * 绑定事件。\n             *\n             * `callback`方法在执行时，arguments将会来源于trigger的时候携带的参数。如\n             * ```javascript\n             * var obj = {};\n             *\n             * // 使得obj有事件行为\n             * Mediator.installTo( obj );\n             *\n             * obj.on( 'testa', function( arg1, arg2 ) {\n             *     console.log( arg1, arg2 ); // => 'arg1', 'arg2'\n             * });\n             *\n             * obj.trigger( 'testa', 'arg1', 'arg2' );\n             * ```\n             *\n             * 如果`callback`中，某一个方法`return false`了，则后续的其他`callback`都不会被执行到。\n             * 切会影响到`trigger`方法的返回值，为`false`。\n             *\n             * `on`还可以用来添加一个特殊事件`all`, 这样所有的事件触发都会响应到。同时此类`callback`中的arguments有一个不同处，\n             * 就是第一个参数为`type`，记录当前是什么事件在触发。此类`callback`的优先级比脚低，会再正常`callback`执行完后触发。\n             * ```javascript\n             * obj.on( 'all', function( type, arg1, arg2 ) {\n             *     console.log( type, arg1, arg2 ); // => 'testa', 'arg1', 'arg2'\n             * });\n             * ```\n             *\n             * @method on\n             * @grammar on( name, callback[, context] ) => self\n             * @param  {String}   name     事件名，支持多个事件用空格隔开\n             * @param  {Function} callback 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             * @class Mediator\n             */\n            on: function( name, callback, context ) {\n                var me = this,\n                    set;\n    \n                if ( !callback ) {\n                    return this;\n                }\n    \n                set = this._events || (this._events = []);\n    \n                eachEvent( name, callback, function( name, callback ) {\n                    var handler = { e: name };\n    \n                    handler.cb = callback;\n                    handler.ctx = context;\n                    handler.ctx2 = context || me;\n                    handler.id = set.length;\n    \n                    set.push( handler );\n                });\n    \n                return this;\n            },\n    \n            /**\n             * 绑定事件，且当handler执行完后，自动解除绑定。\n             * @method once\n             * @grammar once( name, callback[, context] ) => self\n             * @param  {String}   name     事件名\n             * @param  {Function} callback 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             */\n            once: function( name, callback, context ) {\n                var me = this;\n    \n                if ( !callback ) {\n                    return me;\n                }\n    \n                eachEvent( name, callback, function( name, callback ) {\n                    var once = function() {\n                            me.off( name, once );\n                            return callback.apply( context || me, arguments );\n                        };\n    \n                    once._cb = callback;\n                    me.on( name, once, context );\n                });\n    \n                return me;\n            },\n    \n            /**\n             * 解除事件绑定\n             * @method off\n             * @grammar off( [name[, callback[, context] ] ] ) => self\n             * @param  {String}   [name]     事件名\n             * @param  {Function} [callback] 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             */\n            off: function( name, cb, ctx ) {\n                var events = this._events;\n    \n                if ( !events ) {\n                    return this;\n                }\n    \n                if ( !name && !cb && !ctx ) {\n                    this._events = [];\n                    return this;\n                }\n    \n                eachEvent( name, cb, function( name, cb ) {\n                    $.each( findHandlers( events, name, cb, ctx ), function() {\n                        delete events[ this.id ];\n                    });\n                });\n    \n                return this;\n            },\n    \n            /**\n             * 触发事件\n             * @method trigger\n             * @grammar trigger( name[, args...] ) => self\n             * @param  {String}   type     事件名\n             * @param  {*} [...] 任意参数\n             * @return {Boolean} 如果handler中return false了，则返回false, 否则返回true\n             */\n            trigger: function( type ) {\n                var args, events, allEvents;\n    \n                if ( !this._events || !type ) {\n                    return this;\n                }\n    \n                args = slice.call( arguments, 1 );\n                events = findHandlers( this._events, type );\n                allEvents = findHandlers( this._events, 'all' );\n    \n                return triggerHanders( events, args ) &&\n                        triggerHanders( allEvents, arguments );\n            }\n        };\n    \n        /**\n         * 中介者，它本身是个单例，但可以通过[installTo](#WebUploader:Mediator:installTo)方法，使任何对象具备事件行为。\n         * 主要目的是负责模块与模块之间的合作，降低耦合度。\n         *\n         * @class Mediator\n         */\n        return $.extend({\n    \n            /**\n             * 可以通过这个接口，使任何对象具备事件功能。\n             * @method installTo\n             * @param  {Object} obj 需要具备事件行为的对象。\n             * @return {Object} 返回obj.\n             */\n            installTo: function( obj ) {\n                return $.extend( obj, protos );\n            }\n    \n        }, protos );\n    });\n    /**\n     * @fileOverview Uploader上传类\n     */\n    define('uploader',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$;\n    \n        /**\n         * 上传入口类。\n         * @class Uploader\n         * @constructor\n         * @grammar new Uploader( opts ) => Uploader\n         * @example\n         * var uploader = WebUploader.Uploader({\n         *     swf: 'path_of_swf/Uploader.swf',\n         *\n         *     // 开起分片上传。\n         *     chunked: true\n         * });\n         */\n        function Uploader( opts ) {\n            this.options = $.extend( true, {}, Uploader.options, opts );\n            this._init( this.options );\n        }\n    \n        // default Options\n        // widgets中有相应扩展\n        Uploader.options = {};\n        Mediator.installTo( Uploader.prototype );\n    \n        // 批量添加纯命令式方法。\n        $.each({\n            upload: 'start-upload',\n            stop: 'stop-upload',\n            getFile: 'get-file',\n            getFiles: 'get-files',\n            addFile: 'add-file',\n            addFiles: 'add-file',\n            sort: 'sort-files',\n            removeFile: 'remove-file',\n            skipFile: 'skip-file',\n            retry: 'retry',\n            isInProgress: 'is-in-progress',\n            makeThumb: 'make-thumb',\n            getDimension: 'get-dimension',\n            addButton: 'add-btn',\n            getRuntimeType: 'get-runtime-type',\n            refresh: 'refresh',\n            disable: 'disable',\n            enable: 'enable',\n            reset: 'reset'\n        }, function( fn, command ) {\n            Uploader.prototype[ fn ] = function() {\n                return this.request( command, arguments );\n            };\n        });\n    \n        $.extend( Uploader.prototype, {\n            state: 'pending',\n    \n            _init: function( opts ) {\n                var me = this;\n    \n                me.request( 'init', opts, function() {\n                    me.state = 'ready';\n                    me.trigger('ready');\n                });\n            },\n    \n            /**\n             * 获取或者设置Uploader配置项。\n             * @method option\n             * @grammar option( key ) => *\n             * @grammar option( key, val ) => self\n             * @example\n             *\n             * // 初始状态图片上传前不会压缩\n             * var uploader = new WebUploader.Uploader({\n             *     resize: null;\n             * });\n             *\n             * // 修改后图片上传前，尝试将图片压缩到1600 * 1600\n             * uploader.options( 'resize', {\n             *     width: 1600,\n             *     height: 1600\n             * });\n             */\n            option: function( key, val ) {\n                var opts = this.options;\n    \n                // setter\n                if ( arguments.length > 1 ) {\n    \n                    if ( $.isPlainObject( val ) &&\n                            $.isPlainObject( opts[ key ] ) ) {\n                        $.extend( opts[ key ], val );\n                    } else {\n                        opts[ key ] = val;\n                    }\n    \n                } else {    // getter\n                    return key ? opts[ key ] : opts;\n                }\n            },\n    \n            /**\n             * 获取文件统计信息。返回一个包含一下信息的对象。\n             * * `successNum` 上传成功的文件数\n             * * `uploadFailNum` 上传失败的文件数\n             * * `cancelNum` 被删除的文件数\n             * * `invalidNum` 无效的文件数\n             * * `queueNum` 还在队列中的文件数\n             * @method getStats\n             * @grammar getStats() => Object\n             */\n            getStats: function() {\n                // return this._mgr.getStats.apply( this._mgr, arguments );\n                var stats = this.request('get-stats');\n    \n                return {\n                    successNum: stats.numOfSuccess,\n    \n                    // who care?\n                    // queueFailNum: 0,\n                    cancelNum: stats.numOfCancel,\n                    invalidNum: stats.numOfInvalid,\n                    uploadFailNum: stats.numOfUploadFailed,\n                    queueNum: stats.numOfQueue\n                };\n            },\n    \n            // 需要重写此方法来来支持opts.onEvent和instance.onEvent的处理器\n            trigger: function( type/*, args...*/ ) {\n                var args = [].slice.call( arguments, 1 ),\n                    opts = this.options,\n                    name = 'on' + type.substring( 0, 1 ).toUpperCase() +\n                        type.substring( 1 );\n    \n                if (\n                        // 调用通过on方法注册的handler.\n                        Mediator.trigger.apply( this, arguments ) === false ||\n    \n                        // 调用opts.onEvent\n                        $.isFunction( opts[ name ] ) &&\n                        opts[ name ].apply( this, args ) === false ||\n    \n                        // 调用this.onEvent\n                        $.isFunction( this[ name ] ) &&\n                        this[ name ].apply( this, args ) === false ||\n    \n                        // 广播所有uploader的事件。\n                        Mediator.trigger.apply( Mediator,\n                        [ this, type ].concat( args ) ) === false ) {\n    \n                    return false;\n                }\n    \n                return true;\n            },\n    \n            // widgets/widget.js将补充此方法的详细文档。\n            request: Base.noop\n        });\n    \n        /**\n         * 创建Uploader实例，等同于new Uploader( opts );\n         * @method create\n         * @class Base\n         * @static\n         * @grammar Base.create( opts ) => Uploader\n         */\n        Base.create = Uploader.create = function( opts ) {\n            return new Uploader( opts );\n        };\n    \n        // 暴露Uploader，可以通过它来扩展业务逻辑。\n        Base.Uploader = Uploader;\n    \n        return Uploader;\n    });\n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/runtime',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$,\n            factories = {},\n    \n            // 获取对象的第一个key\n            getFirstKey = function( obj ) {\n                for ( var key in obj ) {\n                    if ( obj.hasOwnProperty( key ) ) {\n                        return key;\n                    }\n                }\n                return null;\n            };\n    \n        // 接口类。\n        function Runtime( options ) {\n            this.options = $.extend({\n                container: document.body\n            }, options );\n            this.uid = Base.guid('rt_');\n        }\n    \n        $.extend( Runtime.prototype, {\n    \n            getContainer: function() {\n                var opts = this.options,\n                    parent, container;\n    \n                if ( this._container ) {\n                    return this._container;\n                }\n    \n                parent = $( opts.container || document.body );\n                container = $( document.createElement('div') );\n    \n                container.attr( 'id', 'rt_' + this.uid );\n                container.css({\n                    position: 'absolute',\n                    top: '0px',\n                    left: '0px',\n                    width: '1px',\n                    height: '1px',\n                    overflow: 'hidden'\n                });\n    \n                parent.append( container );\n                parent.addClass('webuploader-container');\n                this._container = container;\n                return container;\n            },\n    \n            init: Base.noop,\n            exec: Base.noop,\n    \n            destroy: function() {\n                if ( this._container ) {\n                    this._container.parentNode.removeChild( this.__container );\n                }\n    \n                this.off();\n            }\n        });\n    \n        Runtime.orders = 'html5,flash';\n    \n    \n        /**\n         * 添加Runtime实现。\n         * @param {String} type    类型\n         * @param {Runtime} factory 具体Runtime实现。\n         */\n        Runtime.addRuntime = function( type, factory ) {\n            factories[ type ] = factory;\n        };\n    \n        Runtime.hasRuntime = function( type ) {\n            return !!(type ? factories[ type ] : getFirstKey( factories ));\n        };\n    \n        Runtime.create = function( opts, orders ) {\n            var type, runtime;\n    \n            orders = orders || Runtime.orders;\n            $.each( orders.split( /\\s*,\\s*/g ), function() {\n                if ( factories[ this ] ) {\n                    type = this;\n                    return false;\n                }\n            });\n    \n            type = type || getFirstKey( factories );\n    \n            if ( !type ) {\n                throw new Error('Runtime Error');\n            }\n    \n            runtime = new factories[ type ]( opts );\n            return runtime;\n        };\n    \n        Mediator.installTo( Runtime.prototype );\n        return Runtime;\n    });\n    \n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/client',[\n        'base',\n        'mediator',\n        'runtime/runtime'\n    ], function( Base, Mediator, Runtime ) {\n    \n        var cache;\n    \n        cache = (function() {\n            var obj = {};\n    \n            return {\n                add: function( runtime ) {\n                    obj[ runtime.uid ] = runtime;\n                },\n    \n                get: function( ruid, standalone ) {\n                    var i;\n    \n                    if ( ruid ) {\n                        return obj[ ruid ];\n                    }\n    \n                    for ( i in obj ) {\n                        // 有些类型不能重用，比如filepicker.\n                        if ( standalone && obj[ i ].__standalone ) {\n                            continue;\n                        }\n    \n                        return obj[ i ];\n                    }\n    \n                    return null;\n                },\n    \n                remove: function( runtime ) {\n                    delete obj[ runtime.uid ];\n                }\n            };\n        })();\n    \n        function RuntimeClient( component, standalone ) {\n            var deferred = Base.Deferred(),\n                runtime;\n    \n            this.uid = Base.guid('client_');\n    \n            // 允许runtime没有初始化之前，注册一些方法在初始化后执行。\n            this.runtimeReady = function( cb ) {\n                return deferred.done( cb );\n            };\n    \n            this.connectRuntime = function( opts, cb ) {\n    \n                // already connected.\n                if ( runtime ) {\n                    throw new Error('already connected!');\n                }\n    \n                deferred.done( cb );\n    \n                if ( typeof opts === 'string' && cache.get( opts ) ) {\n                    runtime = cache.get( opts );\n                }\n    \n                // 像filePicker只能独立存在，不能公用。\n                runtime = runtime || cache.get( null, standalone );\n    \n                // 需要创建\n                if ( !runtime ) {\n                    runtime = Runtime.create( opts, opts.runtimeOrder );\n                    runtime.__promise = deferred.promise();\n                    runtime.once( 'ready', deferred.resolve );\n                    runtime.init();\n                    cache.add( runtime );\n                    runtime.__client = 1;\n                } else {\n                    // 来自cache\n                    Base.$.extend( runtime.options, opts );\n                    runtime.__promise.then( deferred.resolve );\n                    runtime.__client++;\n                }\n    \n                standalone && (runtime.__standalone = standalone);\n                return runtime;\n            };\n    \n            this.getRuntime = function() {\n                return runtime;\n            };\n    \n            this.disconnectRuntime = function() {\n                if ( !runtime ) {\n                    return;\n                }\n    \n                runtime.__client--;\n    \n                if ( runtime.__client <= 0 ) {\n                    cache.remove( runtime );\n                    delete runtime.__promise;\n                    runtime.destroy();\n                }\n    \n                runtime = null;\n            };\n    \n            this.exec = function() {\n                if ( !runtime ) {\n                    return;\n                }\n    \n                var args = Base.slice( arguments );\n                component && args.unshift( component );\n    \n                return runtime.exec.apply( this, args );\n            };\n    \n            this.getRuid = function() {\n                return runtime && runtime.uid;\n            };\n    \n            this.destroy = (function( destroy ) {\n                return function() {\n                    destroy && destroy.apply( this, arguments );\n                    this.trigger('destroy');\n                    this.off();\n                    this.exec('destroy');\n                    this.disconnectRuntime();\n                };\n            })( this.destroy );\n        }\n    \n        Mediator.installTo( RuntimeClient.prototype );\n        return RuntimeClient;\n    });\n    /**\n     * @fileOverview Blob\n     */\n    define('lib/blob',[\n        'base',\n        'runtime/client'\n    ], function( Base, RuntimeClient ) {\n    \n        function Blob( ruid, source ) {\n            var me = this;\n    \n            me.source = source;\n            me.ruid = ruid;\n    \n            RuntimeClient.call( me, 'Blob' );\n    \n            this.uid = source.uid || this.uid;\n            this.type = source.type || '';\n            this.size = source.size || 0;\n    \n            if ( ruid ) {\n                me.connectRuntime( ruid );\n            }\n        }\n    \n        Base.inherits( RuntimeClient, {\n            constructor: Blob,\n    \n            slice: function( start, end ) {\n                return this.exec( 'slice', start, end );\n            },\n    \n            getSource: function() {\n                return this.source;\n            }\n        });\n    \n        return Blob;\n    });\n    /**\n     * 为了统一化Flash的File和HTML5的File而存在。\n     * 以至于要调用Flash里面的File，也可以像调用HTML5版本的File一下。\n     * @fileOverview File\n     */\n    define('lib/file',[\n        'base',\n        'lib/blob'\n    ], function( Base, Blob ) {\n    \n        var uid = 1,\n            rExt = /\\.([^.]+)$/;\n    \n        function File( ruid, file ) {\n            var ext;\n    \n            Blob.apply( this, arguments );\n            this.name = file.name || ('untitled' + uid++);\n            ext = rExt.exec( file.name ) ? RegExp.$1.toLowerCase() : '';\n    \n            // todo 支持其他类型文件的转换。\n    \n            // 如果有mimetype, 但是文件名里面没有找出后缀规律\n            if ( !ext && this.type ) {\n                ext = /\\/(jpg|jpeg|png|gif|bmp)$/i.exec( this.type ) ?\n                        RegExp.$1.toLowerCase() : '';\n                this.name += '.' + ext;\n            }\n    \n            // 如果没有指定mimetype, 但是知道文件后缀。\n            if ( !this.type &&  ~'jpg,jpeg,png,gif,bmp'.indexOf( ext ) ) {\n                this.type = 'image/' + (ext === 'jpg' ? 'jpeg' : ext);\n            }\n    \n            this.ext = ext;\n            this.lastModifiedDate = file.lastModifiedDate ||\n                    (new Date()).toLocaleString();\n        }\n    \n        return Base.inherits( Blob, File );\n    });\n    \n    /**\n     * @fileOverview 错误信息\n     */\n    define('lib/filepicker',[\n        'base',\n        'runtime/client',\n        'lib/file'\n    ], function( Base, RuntimeClent, File ) {\n    \n        var $ = Base.$;\n    \n        function FilePicker( opts ) {\n            opts = this.options = $.extend({}, FilePicker.options, opts );\n    \n            opts.container = $( opts.id );\n    \n            if ( !opts.container.length ) {\n                throw new Error('按钮指定错误');\n            }\n    \n            opts.innerHTML = opts.innerHTML || opts.label ||\n                    opts.container.html() || '';\n    \n            opts.button = $( opts.button || document.createElement('div') );\n            opts.button.html( opts.innerHTML );\n            opts.container.html( opts.button );\n    \n            RuntimeClent.call( this, 'FilePicker', true );\n        }\n    \n        FilePicker.options = {\n            button: null,\n            container: null,\n            label: null,\n            innerHTML: null,\n            multiple: true,\n            accept: null,\n            name: 'file'\n        };\n    \n        Base.inherits( RuntimeClent, {\n            constructor: FilePicker,\n    \n            init: function() {\n                var me = this,\n                    opts = me.options,\n                    button = opts.button;\n    \n                button.addClass('webuploader-pick');\n    \n                me.on( 'all', function( type ) {\n                    var files;\n    \n                    switch ( type ) {\n                        case 'mouseenter':\n                            button.addClass('webuploader-pick-hover');\n                            break;\n    \n                        case 'mouseleave':\n                            button.removeClass('webuploader-pick-hover');\n                            break;\n    \n                        case 'change':\n                            files = me.exec('getFiles');\n                            me.trigger( 'select', $.map( files, function( file ) {\n                                file = new File( me.getRuid(), file );\n    \n                                // 记录来源。\n                                file._refer = opts.container;\n                                return file;\n                            }), opts.container );\n                            break;\n                    }\n                });\n    \n                me.connectRuntime( opts, function() {\n                    me.refresh();\n                    me.exec( 'init', opts );\n                    me.trigger('ready');\n                });\n    \n                $( window ).on( 'resize', function() {\n                    me.refresh();\n                });\n            },\n    \n            refresh: function() {\n                var shimContainer = this.getRuntime().getContainer(),\n                    button = this.options.button,\n                    width = button.outerWidth ?\n                            button.outerWidth() : button.width(),\n    \n                    height = button.outerHeight ?\n                            button.outerHeight() : button.height(),\n    \n                    pos = button.offset();\n    \n                width && height && shimContainer.css({\n                    bottom: 'auto',\n                    right: 'auto',\n                    width: width + 'px',\n                    height: height + 'px'\n                }).offset( pos );\n            },\n    \n            enable: function() {\n                var btn = this.options.button;\n    \n                btn.removeClass('webuploader-pick-disable');\n                this.refresh();\n            },\n    \n            disable: function() {\n                var btn = this.options.button;\n    \n                this.getRuntime().getContainer().css({\n                    top: '-99999px'\n                });\n    \n                btn.addClass('webuploader-pick-disable');\n            },\n    \n            destroy: function() {\n                if ( this.runtime ) {\n                    this.exec('destroy');\n                    this.disconnectRuntime();\n                }\n            }\n        });\n    \n        return FilePicker;\n    });\n    \n    /**\n     * @fileOverview 组件基类。\n     */\n    define('widgets/widget',[\n        'base',\n        'uploader'\n    ], function( Base, Uploader ) {\n    \n        var $ = Base.$,\n            _init = Uploader.prototype._init,\n            IGNORE = {},\n            widgetClass = [];\n    \n        function isArrayLike( obj ) {\n            if ( !obj ) {\n                return false;\n            }\n    \n            var length = obj.length,\n                type = $.type( obj );\n    \n            if ( obj.nodeType === 1 && length ) {\n                return true;\n            }\n    \n            return type === 'array' || type !== 'function' && type !== 'string' &&\n                    (length === 0 || typeof length === 'number' && length > 0 &&\n                    (length - 1) in obj);\n        }\n    \n        function Widget( uploader ) {\n            this.owner = uploader;\n            this.options = uploader.options;\n        }\n    \n        $.extend( Widget.prototype, {\n    \n            init: Base.noop,\n    \n            // 类Backbone的事件监听声明，监听uploader实例上的事件\n            // widget直接无法监听事件，事件只能通过uploader来传递\n            invoke: function( apiName, args ) {\n    \n                /*\n                    {\n                        'make-thumb': 'makeThumb'\n                    }\n                 */\n                var map = this.responseMap;\n    \n                // 如果无API响应声明则忽略\n                if ( !map || !(apiName in map) || !(map[ apiName ] in this) ||\n                        !$.isFunction( this[ map[ apiName ] ] ) ) {\n    \n                    return IGNORE;\n                }\n    \n                return this[ map[ apiName ] ].apply( this, args );\n    \n            },\n    \n            /**\n             * 发送命令。当传入`callback`或者`handler`中返回`promise`时。返回一个当所有`handler`中的promise都完成后完成的新`promise`。\n             * @method request\n             * @grammar request( command, args ) => * | Promise\n             * @grammar request( command, args, callback ) => Promise\n             * @for  Uploader\n             */\n            request: function() {\n                return this.owner.request.apply( this.owner, arguments );\n            }\n        });\n    \n        // 扩展Uploader.\n        $.extend( Uploader.prototype, {\n    \n            // 覆写_init用来初始化widgets\n            _init: function() {\n                var me = this,\n                    widgets = me._widgets = [];\n    \n                $.each( widgetClass, function( _, klass ) {\n                    widgets.push( new klass( me ) );\n                });\n    \n                return _init.apply( me, arguments );\n            },\n    \n            request: function( apiName, args, callback ) {\n                var i = 0,\n                    widgets = this._widgets,\n                    len = widgets.length,\n                    rlts = [],\n                    dfds = [],\n                    widget, rlt, promise, key;\n    \n                args = isArrayLike( args ) ? args : [ args ];\n    \n                for ( ; i < len; i++ ) {\n                    widget = widgets[ i ];\n                    rlt = widget.invoke( apiName, args );\n    \n                    if ( rlt !== IGNORE ) {\n    \n                        // Deferred对象\n                        if ( Base.isPromise( rlt ) ) {\n                            dfds.push( rlt );\n                        } else {\n                            rlts.push( rlt );\n                        }\n                    }\n                }\n    \n                // 如果有callback，则用异步方式。\n                if ( callback || dfds.length ) {\n                    promise = Base.when.apply( Base, dfds );\n                    key = promise.pipe ? 'pipe' : 'then';\n    \n                    // 很重要不能删除。删除了会死循环。\n                    // 保证执行顺序。让callback总是在下一个tick中执行。\n                    return promise[ key ](function() {\n                                var deferred = Base.Deferred(),\n                                    args = arguments;\n    \n                                setTimeout(function() {\n                                    deferred.resolve.apply( deferred, args );\n                                }, 1 );\n    \n                                return deferred.promise();\n                            })[ key ]( callback || Base.noop );\n                } else {\n                    return rlts[ 0 ];\n                }\n            }\n        });\n    \n        /**\n         * 添加组件\n         * @param  {object} widgetProto 组件原型，构造函数通过constructor属性定义\n         * @param  {object} responseMap API名称与函数实现的映射\n         * @example\n         *     Uploader.register( {\n         *         init: function( options ) {},\n         *         makeThumb: function() {}\n         *     }, {\n         *         'make-thumb': 'makeThumb'\n         *     } );\n         */\n        Uploader.register = Widget.register = function( responseMap, widgetProto ) {\n            var map = { init: 'init' },\n                klass;\n    \n            if ( arguments.length === 1 ) {\n                widgetProto = responseMap;\n                widgetProto.responseMap = map;\n            } else {\n                widgetProto.responseMap = $.extend( map, responseMap );\n            }\n    \n            klass = Base.inherits( Widget, widgetProto );\n            widgetClass.push( klass );\n    \n            return klass;\n        };\n    \n        return Widget;\n    });\n    /**\n     * @fileOverview 文件选择相关\n     */\n    define('widgets/filepicker',[\n        'base',\n        'uploader',\n        'lib/filepicker',\n        'widgets/widget'\n    ], function( Base, Uploader, FilePicker ) {\n        var $ = Base.$;\n    \n        $.extend( Uploader.options, {\n    \n            /**\n             * @property {Selector | Object} [pick=undefined]\n             * @namespace options\n             * @for Uploader\n             * @description 指定选择文件的按钮容器，不指定则不创建按钮。\n             *\n             * * `id` {Seletor} 指定选择文件的按钮容器，不指定则不创建按钮。\n             * * `label` {String} 请采用 `innerHTML` 代替\n             * * `innerHTML` {String} 指定按钮文字。不指定时优先从指定的容器中看是否自带文字。\n             * * `multiple` {Boolean} 是否开起同时选择多个文件能力。\n             */\n            pick: null,\n    \n            /**\n             * @property {Arroy} [accept=null]\n             * @namespace options\n             * @for Uploader\n             * @description 指定接受哪些类型的文件。 由于目前还有ext转mimeType表，所以这里需要分开指定。\n             *\n             * * `title` {String} 文字描述\n             * * `extensions` {String} 允许的文件后缀，不带点，多个用逗号分割。\n             * * `mimeTypes` {String} 多个用逗号分割。\n             *\n             * 如：\n             *\n             * ```\n             * {\n             *     title: 'Images',\n             *     extensions: 'gif,jpg,jpeg,bmp,png',\n             *     mimeTypes: 'image/*'\n             * }\n             * ```\n             */\n            accept: null/*{\n                title: 'Images',\n                extensions: 'gif,jpg,jpeg,bmp,png',\n                mimeTypes: 'image/*'\n            }*/\n        });\n    \n        return Uploader.register({\n            'add-btn': 'addButton',\n            refresh: 'refresh',\n            disable: 'disable',\n            enable: 'enable'\n        }, {\n    \n            init: function( opts ) {\n                this.pickers = [];\n                return opts.pick && this.addButton( opts.pick );\n            },\n    \n            refresh: function() {\n                $.each( this.pickers, function() {\n                    this.refresh();\n                });\n            },\n    \n            /**\n             * @method addButton\n             * @for Uploader\n             * @grammar addButton( pick ) => Promise\n             * @description\n             * 添加文件选择按钮，如果一个按钮不够，需要调用此方法来添加。参数跟[options.pick](#WebUploader:Uploader:options)一致。\n             * @example\n             * uploader.addButton({\n             *     id: '#btnContainer',\n             *     innerHTML: '选择文件'\n             * });\n             */\n            addButton: function( pick ) {\n                var me = this,\n                    opts = me.options,\n                    accept = opts.accept,\n                    options, picker, deferred;\n    \n                if ( !pick ) {\n                    return;\n                }\n    \n                deferred = Base.Deferred();\n                $.isPlainObject( pick ) || (pick = {\n                    id: pick\n                });\n    \n                options = $.extend({}, pick, {\n                    accept: $.isPlainObject( accept ) ? [ accept ] : accept,\n                    swf: opts.swf,\n                    runtimeOrder: opts.runtimeOrder\n                });\n    \n                picker = new FilePicker( options );\n    \n                picker.once( 'ready', deferred.resolve );\n                picker.on( 'select', function( files ) {\n                    me.owner.request( 'add-file', [ files ]);\n                });\n                picker.init();\n    \n                this.pickers.push( picker );\n    \n                return deferred.promise();\n            },\n    \n            disable: function() {\n                $.each( this.pickers, function() {\n                    this.disable();\n                });\n            },\n    \n            enable: function() {\n                $.each( this.pickers, function() {\n                    this.enable();\n                });\n            }\n        });\n    });\n    /**\n     * @fileOverview Image\n     */\n    define('lib/image',[\n        'base',\n        'runtime/client',\n        'lib/blob'\n    ], function( Base, RuntimeClient, Blob ) {\n        var $ = Base.$;\n    \n        // 构造器。\n        function Image( opts ) {\n            this.options = $.extend({}, Image.options, opts );\n            RuntimeClient.call( this, 'Image' );\n    \n            this.on( 'load', function() {\n                this._info = this.exec('info');\n                this._meta = this.exec('meta');\n            });\n        }\n    \n        // 默认选项。\n        Image.options = {\n    \n            // 默认的图片处理质量\n            quality: 90,\n    \n            // 是否裁剪\n            crop: false,\n    \n            // 是否保留头部信息\n            preserveHeaders: true,\n    \n            // 是否允许放大。\n            allowMagnify: true\n        };\n    \n        // 继承RuntimeClient.\n        Base.inherits( RuntimeClient, {\n            constructor: Image,\n    \n            info: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._info = val;\n                    return this;\n                }\n    \n                // getter\n                return this._info;\n            },\n    \n            meta: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._meta = val;\n                    return this;\n                }\n    \n                // getter\n                return this._meta;\n            },\n    \n            loadFromBlob: function( blob ) {\n                var me = this,\n                    ruid = blob.getRuid();\n    \n                this.connectRuntime( ruid, function() {\n                    me.exec( 'init', me.options );\n                    me.exec( 'loadFromBlob', blob );\n                });\n            },\n    \n            resize: function() {\n                var args = Base.slice( arguments );\n                return this.exec.apply( this, [ 'resize' ].concat( args ) );\n            },\n    \n            getAsDataUrl: function( type ) {\n                return this.exec( 'getAsDataUrl', type );\n            },\n    \n            getAsBlob: function( type ) {\n                var blob = this.exec( 'getAsBlob', type );\n    \n                return new Blob( this.getRuid(), blob );\n            }\n        });\n    \n        return Image;\n    });\n    /**\n     * @fileOverview 图片操作, 负责预览图片和上传前压缩图片\n     */\n    define('widgets/image',[\n        'base',\n        'uploader',\n        'lib/image',\n        'widgets/widget'\n    ], function( Base, Uploader, Image ) {\n    \n        var $ = Base.$,\n            throttle;\n    \n        // 根据要处理的文件大小来节流，一次不能处理太多，会卡。\n        throttle = (function( max ) {\n            var occupied = 0,\n                waiting = [],\n                tick = function() {\n                    var item;\n    \n                    while ( waiting.length && occupied < max ) {\n                        item = waiting.shift();\n                        occupied += item[ 0 ];\n                        item[ 1 ]();\n                    }\n                };\n    \n            return function( emiter, size, cb ) {\n                waiting.push([ size, cb ]);\n                emiter.once( 'destroy', function() {\n                    occupied -= size;\n                    setTimeout( tick, 1 );\n                });\n                setTimeout( tick, 1 );\n            };\n        })( 5 * 1024 * 1024 );\n    \n        $.extend( Uploader.options, {\n    \n            /**\n             * @property {Object} [thumb]\n             * @namespace options\n             * @for Uploader\n             * @description 配置生成缩略图的选项。\n             *\n             * 默认为：\n             *\n             * ```javascript\n             * {\n             *     width: 110,\n             *     height: 110,\n             *\n             *     // 图片质量，只有type为`image/jpeg`的时候才有效。\n             *     quality: 70,\n             *\n             *     // 是否允许放大，如果想要生成小图的时候不失真，此选项应该设置为false.\n             *     allowMagnify: true,\n             *\n             *     // 是否允许裁剪。\n             *     crop: true,\n             *\n             *     // 是否保留头部meta信息。\n             *     preserveHeaders: false,\n             *\n             *     // 为空的话则保留原有图片格式。\n             *     // 否则强制转换成指定的类型。\n             *     type: 'image/jpeg'\n             * }\n             * ```\n             */\n            thumb: {\n                width: 110,\n                height: 110,\n                quality: 70,\n                allowMagnify: true,\n                crop: true,\n                preserveHeaders: false,\n    \n                // 为空的话则保留原有图片格式。\n                // 否则强制转换成指定的类型。\n                // IE 8下面 base64 大小不能超过 32K 否则预览失败，而非 jpeg 编码的图片很可\n                // 能会超过 32k, 所以这里设置成预览的时候都是 image/jpeg\n                type: 'image/jpeg'\n            },\n    \n            /**\n             * @property {Object} [compress]\n             * @namespace options\n             * @for Uploader\n             * @description 配置压缩的图片的选项。如果此选项为`false`, 则图片在上传前不进行压缩。\n             *\n             * 默认为：\n             *\n             * ```javascript\n             * {\n             *     width: 1600,\n             *     height: 1600,\n             *\n             *     // 图片质量，只有type为`image/jpeg`的时候才有效。\n             *     quality: 90,\n             *\n             *     // 是否允许放大，如果想要生成小图的时候不失真，此选项应该设置为false.\n             *     allowMagnify: false,\n             *\n             *     // 是否允许裁剪。\n             *     crop: false,\n             *\n             *     // 是否保留头部meta信息。\n             *     preserveHeaders: true\n             * }\n             * ```\n             */\n            compress: {\n                width: 1600,\n                height: 1600,\n                quality: 90,\n                allowMagnify: false,\n                crop: false,\n                preserveHeaders: true\n            }\n        });\n    \n        return Uploader.register({\n            'make-thumb': 'makeThumb',\n            'before-send-file': 'compressImage'\n        }, {\n    \n    \n            /**\n             * 生成缩略图，此过程为异步，所以需要传入`callback`。\n             * 通常情况在图片加入队里后调用此方法来生成预览图以增强交互效果。\n             *\n             * `callback`中可以接收到两个参数。\n             * * 第一个为error，如果生成缩略图有错误，此error将为真。\n             * * 第二个为ret, 缩略图的Data URL值。\n             *\n             * **注意**\n             * Date URL在IE6/7中不支持，所以不用调用此方法了，直接显示一张暂不支持预览图片好了。\n             *\n             *\n             * @method makeThumb\n             * @grammar makeThumb( file, callback ) => undefined\n             * @grammar makeThumb( file, callback, width, height ) => undefined\n             * @for Uploader\n             * @example\n             *\n             * uploader.on( 'fileQueued', function( file ) {\n             *     var $li = ...;\n             *\n             *     uploader.makeThumb( file, function( error, ret ) {\n             *         if ( error ) {\n             *             $li.text('预览错误');\n             *         } else {\n             *             $li.append('<img alt=\"\" src=\"' + ret + '\" />');\n             *         }\n             *     });\n             *\n             * });\n             */\n            makeThumb: function( file, cb, width, height ) {\n                var opts, image;\n    \n                file = this.request( 'get-file', file );\n    \n                // 只预览图片格式。\n                if ( !file.type.match( /^image/ ) ) {\n                    cb( true );\n                    return;\n                }\n    \n                opts = $.extend({}, this.options.thumb );\n    \n                // 如果传入的是object.\n                if ( $.isPlainObject( width ) ) {\n                    opts = $.extend( opts, width );\n                    width = null;\n                }\n    \n                width = width || opts.width;\n                height = height || opts.height;\n    \n                image = new Image( opts );\n    \n                image.once( 'load', function() {\n                    file._info = file._info || image.info();\n                    file._meta = file._meta || image.meta();\n                    image.resize( width, height );\n                });\n    \n                image.once( 'complete', function() {\n                    cb( false, image.getAsDataUrl( opts.type ) );\n                    image.destroy();\n                });\n    \n                image.once( 'error', function() {\n                    cb( true );\n                    image.destroy();\n                });\n    \n                throttle( image, file.source.size, function() {\n                    file._info && image.info( file._info );\n                    file._meta && image.meta( file._meta );\n                    image.loadFromBlob( file.source );\n                });\n            },\n    \n            compressImage: function( file ) {\n                var opts = this.options.compress || this.options.resize,\n                    compressSize = opts && opts.compressSize || 300 * 1024,\n                    image, deferred;\n    \n                file = this.request( 'get-file', file );\n    \n                // 只预览图片格式。\n                if ( !opts || !~'image/jpeg,image/jpg'.indexOf( file.type ) ||\n                        file.size < compressSize ||\n                        file._compressed ) {\n                    return;\n                }\n    \n                opts = $.extend({}, opts );\n                deferred = Base.Deferred();\n    \n                image = new Image( opts );\n    \n                deferred.always(function() {\n                    image.destroy();\n                    image = null;\n                });\n                image.once( 'error', deferred.reject );\n                image.once( 'load', function() {\n                    file._info = file._info || image.info();\n                    file._meta = file._meta || image.meta();\n                    image.resize( opts.width, opts.height );\n                });\n    \n                image.once( 'complete', function() {\n                    var blob, size;\n    \n                    // 移动端 UC / qq 浏览器的无图模式下\n                    // ctx.getImageData 处理大图的时候会报 Exception\n                    // INDEX_SIZE_ERR: DOM Exception 1\n                    try {\n                        blob = image.getAsBlob( opts.type );\n    \n                        size = file.size;\n    \n                        // 如果压缩后，比原来还大则不用压缩后的。\n                        if ( blob.size < size ) {\n                            // file.source.destroy && file.source.destroy();\n                            file.source = blob;\n                            file.size = blob.size;\n    \n                            file.trigger( 'resize', blob.size, size );\n                        }\n    \n                        // 标记，避免重复压缩。\n                        file._compressed = true;\n                        deferred.resolve();\n                    } catch ( e ) {\n                        // 出错了直接继续，让其上传原始图片\n                        deferred.resolve();\n                    }\n                });\n    \n                file._info && image.info( file._info );\n                file._meta && image.meta( file._meta );\n    \n                image.loadFromBlob( file.source );\n                return deferred.promise();\n            }\n        });\n    });\n    /**\n     * @fileOverview 文件属性封装\n     */\n    define('file',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$,\n            idPrefix = 'WU_FILE_',\n            idSuffix = 0,\n            rExt = /\\.([^.]+)$/,\n            statusMap = {};\n    \n        function gid() {\n            return idPrefix + idSuffix++;\n        }\n    \n        /**\n         * 文件类\n         * @class File\n         * @constructor 构造函数\n         * @grammar new File( source ) => File\n         * @param {Lib.File} source [lib.File](#Lib.File)实例, 此source对象是带有Runtime信息的。\n         */\n        function WUFile( source ) {\n    \n            /**\n             * 文件名，包括扩展名（后缀）\n             * @property name\n             * @type {string}\n             */\n            this.name = source.name || 'Untitled';\n    \n            /**\n             * 文件体积（字节）\n             * @property size\n             * @type {uint}\n             * @default 0\n             */\n            this.size = source.size || 0;\n    \n            /**\n             * 文件MIMETYPE类型，与文件类型的对应关系请参考[http://t.cn/z8ZnFny](http://t.cn/z8ZnFny)\n             * @property type\n             * @type {string}\n             * @default 'application'\n             */\n            this.type = source.type || 'application';\n    \n            /**\n             * 文件最后修改日期\n             * @property lastModifiedDate\n             * @type {int}\n             * @default 当前时间戳\n             */\n            this.lastModifiedDate = source.lastModifiedDate || (new Date() * 1);\n    \n            /**\n             * 文件ID，每个对象具有唯一ID，与文件名无关\n             * @property id\n             * @type {string}\n             */\n            this.id = gid();\n    \n            /**\n             * 文件扩展名，通过文件名获取，例如test.png的扩展名为png\n             * @property ext\n             * @type {string}\n             */\n            this.ext = rExt.exec( this.name ) ? RegExp.$1 : '';\n    \n    \n            /**\n             * 状态文字说明。在不同的status语境下有不同的用途。\n             * @property statusText\n             * @type {string}\n             */\n            this.statusText = '';\n    \n            // 存储文件状态，防止通过属性直接修改\n            statusMap[ this.id ] = WUFile.Status.INITED;\n    \n            this.source = source;\n            this.loaded = 0;\n    \n            this.on( 'error', function( msg ) {\n                this.setStatus( WUFile.Status.ERROR, msg );\n            });\n        }\n    \n        $.extend( WUFile.prototype, {\n    \n            /**\n             * 设置状态，状态变化时会触发`change`事件。\n             * @method setStatus\n             * @grammar setStatus( status[, statusText] );\n             * @param {File.Status|String} status [文件状态值](#WebUploader:File:File.Status)\n             * @param {String} [statusText=''] 状态说明，常在error时使用，用http, abort,server等来标记是由于什么原因导致文件错误。\n             */\n            setStatus: function( status, text ) {\n    \n                var prevStatus = statusMap[ this.id ];\n    \n                typeof text !== 'undefined' && (this.statusText = text);\n    \n                if ( status !== prevStatus ) {\n                    statusMap[ this.id ] = status;\n                    /**\n                     * 文件状态变化\n                     * @event statuschange\n                     */\n                    this.trigger( 'statuschange', status, prevStatus );\n                }\n    \n            },\n    \n            /**\n             * 获取文件状态\n             * @return {File.Status}\n             * @example\n                     文件状态具体包括以下几种类型：\n                     {\n                         // 初始化\n                        INITED:     0,\n                        // 已入队列\n                        QUEUED:     1,\n                        // 正在上传\n                        PROGRESS:     2,\n                        // 上传出错\n                        ERROR:         3,\n                        // 上传成功\n                        COMPLETE:     4,\n                        // 上传取消\n                        CANCELLED:     5\n                    }\n             */\n            getStatus: function() {\n                return statusMap[ this.id ];\n            },\n    \n            /**\n             * 获取文件原始信息。\n             * @return {*}\n             */\n            getSource: function() {\n                return this.source;\n            },\n    \n            destory: function() {\n                delete statusMap[ this.id ];\n            }\n        });\n    \n        Mediator.installTo( WUFile.prototype );\n    \n        /**\n         * 文件状态值，具体包括以下几种类型：\n         * * `inited` 初始状态\n         * * `queued` 已经进入队列, 等待上传\n         * * `progress` 上传中\n         * * `complete` 上传完成。\n         * * `error` 上传出错，可重试\n         * * `interrupt` 上传中断，可续传。\n         * * `invalid` 文件不合格，不能重试上传。会自动从队列中移除。\n         * * `cancelled` 文件被移除。\n         * @property {Object} Status\n         * @namespace File\n         * @class File\n         * @static\n         */\n        WUFile.Status = {\n            INITED:     'inited',    // 初始状态\n            QUEUED:     'queued',    // 已经进入队列, 等待上传\n            PROGRESS:   'progress',    // 上传中\n            ERROR:      'error',    // 上传出错，可重试\n            COMPLETE:   'complete',    // 上传完成。\n            CANCELLED:  'cancelled',    // 上传取消。\n            INTERRUPT:  'interrupt',    // 上传中断，可续传。\n            INVALID:    'invalid'    // 文件不合格，不能重试上传。\n        };\n    \n        return WUFile;\n    });\n    \n    /**\n     * @fileOverview 文件队列\n     */\n    define('queue',[\n        'base',\n        'mediator',\n        'file'\n    ], function( Base, Mediator, WUFile ) {\n    \n        var $ = Base.$,\n            STATUS = WUFile.Status;\n    \n        /**\n         * 文件队列, 用来存储各个状态中的文件。\n         * @class Queue\n         * @extends Mediator\n         */\n        function Queue() {\n    \n            /**\n             * 统计文件数。\n             * * `numOfQueue` 队列中的文件数。\n             * * `numOfSuccess` 上传成功的文件数\n             * * `numOfCancel` 被移除的文件数\n             * * `numOfProgress` 正在上传中的文件数\n             * * `numOfUploadFailed` 上传错误的文件数。\n             * * `numOfInvalid` 无效的文件数。\n             * @property {Object} stats\n             */\n            this.stats = {\n                numOfQueue: 0,\n                numOfSuccess: 0,\n                numOfCancel: 0,\n                numOfProgress: 0,\n                numOfUploadFailed: 0,\n                numOfInvalid: 0\n            };\n    \n            // 上传队列，仅包括等待上传的文件\n            this._queue = [];\n    \n            // 存储所有文件\n            this._map = {};\n        }\n    \n        $.extend( Queue.prototype, {\n    \n            /**\n             * 将新文件加入对队列尾部\n             *\n             * @method append\n             * @param  {File} file   文件对象\n             */\n            append: function( file ) {\n                this._queue.push( file );\n                this._fileAdded( file );\n                return this;\n            },\n    \n            /**\n             * 将新文件加入对队列头部\n             *\n             * @method prepend\n             * @param  {File} file   文件对象\n             */\n            prepend: function( file ) {\n                this._queue.unshift( file );\n                this._fileAdded( file );\n                return this;\n            },\n    \n            /**\n             * 获取文件对象\n             *\n             * @method getFile\n             * @param  {String} fileId   文件ID\n             * @return {File}\n             */\n            getFile: function( fileId ) {\n                if ( typeof fileId !== 'string' ) {\n                    return fileId;\n                }\n                return this._map[ fileId ];\n            },\n    \n            /**\n             * 从队列中取出一个指定状态的文件。\n             * @grammar fetch( status ) => File\n             * @method fetch\n             * @param {String} status [文件状态值](#WebUploader:File:File.Status)\n             * @return {File} [File](#WebUploader:File)\n             */\n            fetch: function( status ) {\n                var len = this._queue.length,\n                    i, file;\n    \n                status = status || STATUS.QUEUED;\n    \n                for ( i = 0; i < len; i++ ) {\n                    file = this._queue[ i ];\n    \n                    if ( status === file.getStatus() ) {\n                        return file;\n                    }\n                }\n    \n                return null;\n            },\n    \n            /**\n             * 对队列进行排序，能够控制文件上传顺序。\n             * @grammar sort( fn ) => undefined\n             * @method sort\n             * @param {Function} fn 排序方法\n             */\n            sort: function( fn ) {\n                if ( typeof fn === 'function' ) {\n                    this._queue.sort( fn );\n                }\n            },\n    \n            /**\n             * 获取指定类型的文件列表, 列表中每一个成员为[File](#WebUploader:File)对象。\n             * @grammar getFiles( [status1[, status2 ...]] ) => Array\n             * @method getFiles\n             * @param {String} [status] [文件状态值](#WebUploader:File:File.Status)\n             */\n            getFiles: function() {\n                var sts = [].slice.call( arguments, 0 ),\n                    ret = [],\n                    i = 0,\n                    len = this._queue.length,\n                    file;\n    \n                for ( ; i < len; i++ ) {\n                    file = this._queue[ i ];\n    \n                    if ( sts.length && !~$.inArray( file.getStatus(), sts ) ) {\n                        continue;\n                    }\n    \n                    ret.push( file );\n                }\n    \n                return ret;\n            },\n    \n            _fileAdded: function( file ) {\n                var me = this,\n                    existing = this._map[ file.id ];\n    \n                if ( !existing ) {\n                    this._map[ file.id ] = file;\n    \n                    file.on( 'statuschange', function( cur, pre ) {\n                        me._onFileStatusChange( cur, pre );\n                    });\n                }\n    \n                file.setStatus( STATUS.QUEUED );\n            },\n    \n            _onFileStatusChange: function( curStatus, preStatus ) {\n                var stats = this.stats;\n    \n                switch ( preStatus ) {\n                    case STATUS.PROGRESS:\n                        stats.numOfProgress--;\n                        break;\n    \n                    case STATUS.QUEUED:\n                        stats.numOfQueue --;\n                        break;\n    \n                    case STATUS.ERROR:\n                        stats.numOfUploadFailed--;\n                        break;\n    \n                    case STATUS.INVALID:\n                        stats.numOfInvalid--;\n                        break;\n                }\n    \n                switch ( curStatus ) {\n                    case STATUS.QUEUED:\n                        stats.numOfQueue++;\n                        break;\n    \n                    case STATUS.PROGRESS:\n                        stats.numOfProgress++;\n                        break;\n    \n                    case STATUS.ERROR:\n                        stats.numOfUploadFailed++;\n                        break;\n    \n                    case STATUS.COMPLETE:\n                        stats.numOfSuccess++;\n                        break;\n    \n                    case STATUS.CANCELLED:\n                        stats.numOfCancel++;\n                        break;\n    \n                    case STATUS.INVALID:\n                        stats.numOfInvalid++;\n                        break;\n                }\n            }\n    \n        });\n    \n        Mediator.installTo( Queue.prototype );\n    \n        return Queue;\n    });\n    /**\n     * @fileOverview 队列\n     */\n    define('widgets/queue',[\n        'base',\n        'uploader',\n        'queue',\n        'file',\n        'lib/file',\n        'runtime/client',\n        'widgets/widget'\n    ], function( Base, Uploader, Queue, WUFile, File, RuntimeClient ) {\n    \n        var $ = Base.$,\n            rExt = /\\.\\w+$/,\n            Status = WUFile.Status;\n    \n        return Uploader.register({\n            'sort-files': 'sortFiles',\n            'add-file': 'addFiles',\n            'get-file': 'getFile',\n            'fetch-file': 'fetchFile',\n            'get-stats': 'getStats',\n            'get-files': 'getFiles',\n            'remove-file': 'removeFile',\n            'retry': 'retry',\n            'reset': 'reset',\n            'accept-file': 'acceptFile'\n        }, {\n    \n            init: function( opts ) {\n                var me = this,\n                    deferred, len, i, item, arr, accept, runtime;\n    \n                if ( $.isPlainObject( opts.accept ) ) {\n                    opts.accept = [ opts.accept ];\n                }\n    \n                // accept中的中生成匹配正则。\n                if ( opts.accept ) {\n                    arr = [];\n    \n                    for ( i = 0, len = opts.accept.length; i < len; i++ ) {\n                        item = opts.accept[ i ].extensions;\n                        item && arr.push( item );\n                    }\n    \n                    if ( arr.length ) {\n                        accept = '\\\\.' + arr.join(',')\n                                .replace( /,/g, '$|\\\\.' )\n                                .replace( /\\*/g, '.*' ) + '$';\n                    }\n    \n                    me.accept = new RegExp( accept, 'i' );\n                }\n    \n                me.queue = new Queue();\n                me.stats = me.queue.stats;\n    \n                // 如果当前不是html5运行时，那就算了。\n                // 不执行后续操作\n                if ( this.request('predict-runtime-type') !== 'html5' ) {\n                    return;\n                }\n    \n                // 创建一个 html5 运行时的 placeholder\n                // 以至于外部添加原生 File 对象的时候能正确包裹一下供 webuploader 使用。\n                deferred = Base.Deferred();\n                runtime = new RuntimeClient('Placeholder');\n                runtime.connectRuntime({\n                    runtimeOrder: 'html5'\n                }, function() {\n                    me._ruid = runtime.getRuid();\n                    deferred.resolve();\n                });\n                return deferred.promise();\n            },\n    \n    \n            // 为了支持外部直接添加一个原生File对象。\n            _wrapFile: function( file ) {\n                if ( !(file instanceof WUFile) ) {\n    \n                    if ( !(file instanceof File) ) {\n                        if ( !this._ruid ) {\n                            throw new Error('Can\\'t add external files.');\n                        }\n                        file = new File( this._ruid, file );\n                    }\n    \n                    file = new WUFile( file );\n                }\n    \n                return file;\n            },\n    \n            // 判断文件是否可以被加入队列\n            acceptFile: function( file ) {\n                var invalid = !file || file.size < 6 || this.accept &&\n    \n                        // 如果名字中有后缀，才做后缀白名单处理。\n                        rExt.exec( file.name ) && !this.accept.test( file.name );\n    \n                return !invalid;\n            },\n    \n    \n            /**\n             * @event beforeFileQueued\n             * @param {File} file File对象\n             * @description 当文件被加入队列之前触发，此事件的handler返回值为`false`，则此文件不会被添加进入队列。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event fileQueued\n             * @param {File} file File对象\n             * @description 当文件被加入队列以后触发。\n             * @for  Uploader\n             */\n    \n            _addFile: function( file ) {\n                var me = this;\n    \n                file = me._wrapFile( file );\n    \n                // 不过类型判断允许不允许，先派送 `beforeFileQueued`\n                if ( !me.owner.trigger( 'beforeFileQueued', file ) ) {\n                    return;\n                }\n    \n                // 类型不匹配，则派送错误事件，并返回。\n                if ( !me.acceptFile( file ) ) {\n                    me.owner.trigger( 'error', 'Q_TYPE_DENIED', file );\n                    return;\n                }\n    \n                me.queue.append( file );\n                me.owner.trigger( 'fileQueued', file );\n                return file;\n            },\n    \n            getFile: function( fileId ) {\n                return this.queue.getFile( fileId );\n            },\n    \n            /**\n             * @event filesQueued\n             * @param {File} files 数组，内容为原始File(lib/File）对象。\n             * @description 当一批文件添加进队列以后触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @method addFiles\n             * @grammar addFiles( file ) => undefined\n             * @grammar addFiles( [file1, file2 ...] ) => undefined\n             * @param {Array of File or File} [files] Files 对象 数组\n             * @description 添加文件到队列\n             * @for  Uploader\n             */\n            addFiles: function( files ) {\n                var me = this;\n    \n                if ( !files.length ) {\n                    files = [ files ];\n                }\n    \n                files = $.map( files, function( file ) {\n                    return me._addFile( file );\n                });\n    \n                me.owner.trigger( 'filesQueued', files );\n    \n                if ( me.options.auto ) {\n                    me.request('start-upload');\n                }\n            },\n    \n            getStats: function() {\n                return this.stats;\n            },\n    \n            /**\n             * @event fileDequeued\n             * @param {File} file File对象\n             * @description 当文件被移除队列后触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @method removeFile\n             * @grammar removeFile( file ) => undefined\n             * @grammar removeFile( id ) => undefined\n             * @param {File|id} file File对象或这File对象的id\n             * @description 移除某一文件。\n             * @for  Uploader\n             * @example\n             *\n             * $li.on('click', '.remove-this', function() {\n             *     uploader.removeFile( file );\n             * })\n             */\n            removeFile: function( file ) {\n                var me = this;\n    \n                file = file.id ? file : me.queue.getFile( file );\n    \n                file.setStatus( Status.CANCELLED );\n                me.owner.trigger( 'fileDequeued', file );\n            },\n    \n            /**\n             * @method getFiles\n             * @grammar getFiles() => Array\n             * @grammar getFiles( status1, status2, status... ) => Array\n             * @description 返回指定状态的文件集合，不传参数将返回所有状态的文件。\n             * @for  Uploader\n             * @example\n             * console.log( uploader.getFiles() );    // => all files\n             * console.log( uploader.getFiles('error') )    // => all error files.\n             */\n            getFiles: function() {\n                return this.queue.getFiles.apply( this.queue, arguments );\n            },\n    \n            fetchFile: function() {\n                return this.queue.fetch.apply( this.queue, arguments );\n            },\n    \n            /**\n             * @method retry\n             * @grammar retry() => undefined\n             * @grammar retry( file ) => undefined\n             * @description 重试上传，重试指定文件，或者从出错的文件开始重新上传。\n             * @for  Uploader\n             * @example\n             * function retry() {\n             *     uploader.retry();\n             * }\n             */\n            retry: function( file, noForceStart ) {\n                var me = this,\n                    files, i, len;\n    \n                if ( file ) {\n                    file = file.id ? file : me.queue.getFile( file );\n                    file.setStatus( Status.QUEUED );\n                    noForceStart || me.request('start-upload');\n                    return;\n                }\n    \n                files = me.queue.getFiles( Status.ERROR );\n                i = 0;\n                len = files.length;\n    \n                for ( ; i < len; i++ ) {\n                    file = files[ i ];\n                    file.setStatus( Status.QUEUED );\n                }\n    \n                me.request('start-upload');\n            },\n    \n            /**\n             * @method sort\n             * @grammar sort( fn ) => undefined\n             * @description 排序队列中的文件，在上传之前调整可以控制上传顺序。\n             * @for  Uploader\n             */\n            sortFiles: function() {\n                return this.queue.sort.apply( this.queue, arguments );\n            },\n    \n            /**\n             * @method reset\n             * @grammar reset() => undefined\n             * @description 重置uploader。目前只重置了队列。\n             * @for  Uploader\n             * @example\n             * uploader.reset();\n             */\n            reset: function() {\n                this.queue = new Queue();\n                this.stats = this.queue.stats;\n            }\n        });\n    \n    });\n    /**\n     * @fileOverview 添加获取Runtime相关信息的方法。\n     */\n    define('widgets/runtime',[\n        'uploader',\n        'runtime/runtime',\n        'widgets/widget'\n    ], function( Uploader, Runtime ) {\n    \n        Uploader.support = function() {\n            return Runtime.hasRuntime.apply( Runtime, arguments );\n        };\n    \n        return Uploader.register({\n            'predict-runtime-type': 'predictRuntmeType'\n        }, {\n    \n            init: function() {\n                if ( !this.predictRuntmeType() ) {\n                    throw Error('Runtime Error');\n                }\n            },\n    \n            /**\n             * 预测Uploader将采用哪个`Runtime`\n             * @grammar predictRuntmeType() => String\n             * @method predictRuntmeType\n             * @for  Uploader\n             */\n            predictRuntmeType: function() {\n                var orders = this.options.runtimeOrder || Runtime.orders,\n                    type = this.type,\n                    i, len;\n    \n                if ( !type ) {\n                    orders = orders.split( /\\s*,\\s*/g );\n    \n                    for ( i = 0, len = orders.length; i < len; i++ ) {\n                        if ( Runtime.hasRuntime( orders[ i ] ) ) {\n                            this.type = type = orders[ i ];\n                            break;\n                        }\n                    }\n                }\n    \n                return type;\n            }\n        });\n    });\n    /**\n     * @fileOverview Transport\n     */\n    define('lib/transport',[\n        'base',\n        'runtime/client',\n        'mediator'\n    ], function( Base, RuntimeClient, Mediator ) {\n    \n        var $ = Base.$;\n    \n        function Transport( opts ) {\n            var me = this;\n    \n            opts = me.options = $.extend( true, {}, Transport.options, opts || {} );\n            RuntimeClient.call( this, 'Transport' );\n    \n            this._blob = null;\n            this._formData = opts.formData || {};\n            this._headers = opts.headers || {};\n    \n            this.on( 'progress', this._timeout );\n            this.on( 'load error', function() {\n                me.trigger( 'progress', 1 );\n                clearTimeout( me._timer );\n            });\n        }\n    \n        Transport.options = {\n            server: '',\n            method: 'POST',\n    \n            // 跨域时，是否允许携带cookie, 只有html5 runtime才有效\n            withCredentials: false,\n            fileVal: 'file',\n            timeout: 2 * 60 * 1000,    // 2分钟\n            formData: {},\n            headers: {},\n            sendAsBinary: false\n        };\n    \n        $.extend( Transport.prototype, {\n    \n            // 添加Blob, 只能添加一次，最后一次有效。\n            appendBlob: function( key, blob, filename ) {\n                var me = this,\n                    opts = me.options;\n    \n                if ( me.getRuid() ) {\n                    me.disconnectRuntime();\n                }\n    \n                // 连接到blob归属的同一个runtime.\n                me.connectRuntime( blob.ruid, function() {\n                    me.exec('init');\n                });\n    \n                me._blob = blob;\n                opts.fileVal = key || opts.fileVal;\n                opts.filename = filename || opts.filename;\n            },\n    \n            // 添加其他字段\n            append: function( key, value ) {\n                if ( typeof key === 'object' ) {\n                    $.extend( this._formData, key );\n                } else {\n                    this._formData[ key ] = value;\n                }\n            },\n    \n            setRequestHeader: function( key, value ) {\n                if ( typeof key === 'object' ) {\n                    $.extend( this._headers, key );\n                } else {\n                    this._headers[ key ] = value;\n                }\n            },\n    \n            send: function( method ) {\n                this.exec( 'send', method );\n                this._timeout();\n            },\n    \n            abort: function() {\n                clearTimeout( this._timer );\n                return this.exec('abort');\n            },\n    \n            destroy: function() {\n                this.trigger('destroy');\n                this.off();\n                this.exec('destroy');\n                this.disconnectRuntime();\n            },\n    \n            getResponse: function() {\n                return this.exec('getResponse');\n            },\n    \n            getResponseAsJson: function() {\n                return this.exec('getResponseAsJson');\n            },\n    \n            getStatus: function() {\n                return this.exec('getStatus');\n            },\n    \n            _timeout: function() {\n                var me = this,\n                    duration = me.options.timeout;\n    \n                if ( !duration ) {\n                    return;\n                }\n    \n                clearTimeout( me._timer );\n                me._timer = setTimeout(function() {\n                    me.abort();\n                    me.trigger( 'error', 'timeout' );\n                }, duration );\n            }\n    \n        });\n    \n        // 让Transport具备事件功能。\n        Mediator.installTo( Transport.prototype );\n    \n        return Transport;\n    });\n    /**\n     * @fileOverview 负责文件上传相关。\n     */\n    define('widgets/upload',[\n        'base',\n        'uploader',\n        'file',\n        'lib/transport',\n        'widgets/widget'\n    ], function( Base, Uploader, WUFile, Transport ) {\n    \n        var $ = Base.$,\n            isPromise = Base.isPromise,\n            Status = WUFile.Status;\n    \n        // 添加默认配置项\n        $.extend( Uploader.options, {\n    \n    \n            /**\n             * @property {Boolean} [prepareNextFile=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否允许在文件传输时提前把下一个文件准备好。\n             * 对于一个文件的准备工作比较耗时，比如图片压缩，md5序列化。\n             * 如果能提前在当前文件传输期处理，可以节省总体耗时。\n             */\n            prepareNextFile: false,\n    \n            /**\n             * @property {Boolean} [chunked=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否要分片处理大文件上传。\n             */\n            chunked: false,\n    \n            /**\n             * @property {Boolean} [chunkSize=5242880]\n             * @namespace options\n             * @for Uploader\n             * @description 如果要分片，分多大一片？ 默认大小为5M.\n             */\n            chunkSize: 5 * 1024 * 1024,\n    \n            /**\n             * @property {Boolean} [chunkRetry=2]\n             * @namespace options\n             * @for Uploader\n             * @description 如果某个分片由于网络问题出错，允许自动重传多少次？\n             */\n            chunkRetry: 2,\n    \n            /**\n             * @property {Boolean} [threads=3]\n             * @namespace options\n             * @for Uploader\n             * @description 上传并发数。允许同时最大上传进程数。\n             */\n            threads: 3,\n    \n    \n            /**\n             * @property {Object} [formData]\n             * @namespace options\n             * @for Uploader\n             * @description 文件上传请求的参数表，每次发送都会发送此对象中的参数。\n             */\n            formData: null\n    \n            /**\n             * @property {Object} [fileVal='file']\n             * @namespace options\n             * @for Uploader\n             * @description 设置文件上传域的name。\n             */\n    \n            /**\n             * @property {Object} [method='POST']\n             * @namespace options\n             * @for Uploader\n             * @description 文件上传方式，`POST`或者`GET`。\n             */\n    \n            /**\n             * @property {Object} [sendAsBinary=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否已二进制的流的方式发送文件，这样整个上传内容`php://input`都为文件内容，\n             * 其他参数在$_GET数组中。\n             */\n        });\n    \n        // 负责将文件切片。\n        function CuteFile( file, chunkSize ) {\n            var pending = [],\n                blob = file.source,\n                total = blob.size,\n                chunks = chunkSize ? Math.ceil( total / chunkSize ) : 1,\n                start = 0,\n                index = 0,\n                len;\n    \n            while ( index < chunks ) {\n                len = Math.min( chunkSize, total - start );\n    \n                pending.push({\n                    file: file,\n                    start: start,\n                    end: chunkSize ? (start + len) : total,\n                    total: total,\n                    chunks: chunks,\n                    chunk: index++\n                });\n                start += len;\n            }\n    \n            file.blocks = pending.concat();\n            file.remaning = pending.length;\n    \n            return {\n                file: file,\n    \n                has: function() {\n                    return !!pending.length;\n                },\n    \n                fetch: function() {\n                    return pending.shift();\n                }\n            };\n        }\n    \n        Uploader.register({\n            'start-upload': 'start',\n            'stop-upload': 'stop',\n            'skip-file': 'skipFile',\n            'is-in-progress': 'isInProgress'\n        }, {\n    \n            init: function() {\n                var owner = this.owner;\n    \n                this.runing = false;\n    \n                // 记录当前正在传的数据，跟threads相关\n                this.pool = [];\n    \n                // 缓存即将上传的文件。\n                this.pending = [];\n    \n                // 跟踪还有多少分片没有完成上传。\n                this.remaning = 0;\n                this.__tick = Base.bindFn( this._tick, this );\n    \n                owner.on( 'uploadComplete', function( file ) {\n                    // 把其他块取消了。\n                    file.blocks && $.each( file.blocks, function( _, v ) {\n                        v.transport && (v.transport.abort(), v.transport.destroy());\n                        delete v.transport;\n                    });\n    \n                    delete file.blocks;\n                    delete file.remaning;\n                });\n            },\n    \n            /**\n             * @event startUpload\n             * @description 当开始上传流程时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * 开始上传。此方法可以从初始状态调用开始上传流程，也可以从暂停状态调用，继续上传流程。\n             * @grammar upload() => undefined\n             * @method upload\n             * @for  Uploader\n             */\n            start: function() {\n                var me = this;\n    \n                // 移出invalid的文件\n                $.each( me.request( 'get-files', Status.INVALID ), function() {\n                    me.request( 'remove-file', this );\n                });\n    \n                if ( me.runing ) {\n                    return;\n                }\n    \n                me.runing = true;\n    \n                // 如果有暂停的，则续传\n                $.each( me.pool, function( _, v ) {\n                    var file = v.file;\n    \n                    if ( file.getStatus() === Status.INTERRUPT ) {\n                        file.setStatus( Status.PROGRESS );\n                        me._trigged = false;\n                        v.transport && v.transport.send();\n                    }\n                });\n    \n                me._trigged = false;\n                me.owner.trigger('startUpload');\n                Base.nextTick( me.__tick );\n            },\n    \n            /**\n             * @event stopUpload\n             * @description 当开始上传流程暂停时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * 暂停上传。第一个参数为是否中断上传当前正在上传的文件。\n             * @grammar stop() => undefined\n             * @grammar stop( true ) => undefined\n             * @method stop\n             * @for  Uploader\n             */\n            stop: function( interrupt ) {\n                var me = this;\n    \n                if ( me.runing === false ) {\n                    return;\n                }\n    \n                me.runing = false;\n    \n                interrupt && $.each( me.pool, function( _, v ) {\n                    v.transport && v.transport.abort();\n                    v.file.setStatus( Status.INTERRUPT );\n                });\n    \n                me.owner.trigger('stopUpload');\n            },\n    \n            /**\n             * 判断`Uplaode`r是否正在上传中。\n             * @grammar isInProgress() => Boolean\n             * @method isInProgress\n             * @for  Uploader\n             */\n            isInProgress: function() {\n                return !!this.runing;\n            },\n    \n            getStats: function() {\n                return this.request('get-stats');\n            },\n    \n            /**\n             * 掉过一个文件上传，直接标记指定文件为已上传状态。\n             * @grammar skipFile( file ) => undefined\n             * @method skipFile\n             * @for  Uploader\n             */\n            skipFile: function( file, status ) {\n                file = this.request( 'get-file', file );\n    \n                file.setStatus( status || Status.COMPLETE );\n                file.skipped = true;\n    \n                // 如果正在上传。\n                file.blocks && $.each( file.blocks, function( _, v ) {\n                    var _tr = v.transport;\n    \n                    if ( _tr ) {\n                        _tr.abort();\n                        _tr.destroy();\n                        delete v.transport;\n                    }\n                });\n    \n                this.owner.trigger( 'uploadSkip', file );\n            },\n    \n            /**\n             * @event uploadFinished\n             * @description 当所有文件上传结束时触发。\n             * @for  Uploader\n             */\n            _tick: function() {\n                var me = this,\n                    opts = me.options,\n                    fn, val;\n    \n                // 上一个promise还没有结束，则等待完成后再执行。\n                if ( me._promise ) {\n                    return me._promise.always( me.__tick );\n                }\n    \n                // 还有位置，且还有文件要处理的话。\n                if ( me.pool.length < opts.threads && (val = me._nextBlock()) ) {\n                    me._trigged = false;\n    \n                    fn = function( val ) {\n                        me._promise = null;\n    \n                        // 有可能是reject过来的，所以要检测val的类型。\n                        val && val.file && me._startSend( val );\n                        Base.nextTick( me.__tick );\n                    };\n    \n                    me._promise = isPromise( val ) ? val.always( fn ) : fn( val );\n    \n                // 没有要上传的了，且没有正在传输的了。\n                } else if ( !me.remaning && !me.getStats().numOfQueue ) {\n                    me.runing = false;\n    \n                    me._trigged || Base.nextTick(function() {\n                        me.owner.trigger('uploadFinished');\n                    });\n                    me._trigged = true;\n                }\n            },\n    \n            _nextBlock: function() {\n                var me = this,\n                    act = me._act,\n                    opts = me.options,\n                    next, done;\n    \n                // 如果当前文件还有没有需要传输的，则直接返回剩下的。\n                if ( act && act.has() &&\n                        act.file.getStatus() === Status.PROGRESS ) {\n    \n                    // 是否提前准备下一个文件\n                    if ( opts.prepareNextFile && !me.pending.length ) {\n                        me._prepareNextFile();\n                    }\n    \n                    return act.fetch();\n    \n                // 否则，如果正在运行，则准备下一个文件，并等待完成后返回下个分片。\n                } else if ( me.runing ) {\n    \n                    // 如果缓存中有，则直接在缓存中取，没有则去queue中取。\n                    if ( !me.pending.length && me.getStats().numOfQueue ) {\n                        me._prepareNextFile();\n                    }\n    \n                    next = me.pending.shift();\n                    done = function( file ) {\n                        if ( !file ) {\n                            return null;\n                        }\n    \n                        act = CuteFile( file, opts.chunked ? opts.chunkSize : 0 );\n                        me._act = act;\n                        return act.fetch();\n                    };\n    \n                    // 文件可能还在prepare中，也有可能已经完全准备好了。\n                    return isPromise( next ) ?\n                            next[ next.pipe ? 'pipe' : 'then']( done ) :\n                            done( next );\n                }\n            },\n    \n    \n            /**\n             * @event uploadStart\n             * @param {File} file File对象\n             * @description 某个文件开始上传前触发，一个文件只会触发一次。\n             * @for  Uploader\n             */\n            _prepareNextFile: function() {\n                var me = this,\n                    file = me.request('fetch-file'),\n                    pending = me.pending,\n                    promise;\n    \n                if ( file ) {\n                    promise = me.request( 'before-send-file', file, function() {\n    \n                        // 有可能文件被skip掉了。文件被skip掉后，状态坑定不是Queued.\n                        if ( file.getStatus() === Status.QUEUED ) {\n                            me.owner.trigger( 'uploadStart', file );\n                            file.setStatus( Status.PROGRESS );\n                            return file;\n                        }\n    \n                        return me._finishFile( file );\n                    });\n    \n                    // 如果还在pending中，则替换成文件本身。\n                    promise.done(function() {\n                        var idx = $.inArray( promise, pending );\n    \n                        ~idx && pending.splice( idx, 1, file );\n                    });\n    \n                    // befeore-send-file的钩子就有错误发生。\n                    promise.fail(function( reason ) {\n                        file.setStatus( Status.ERROR, reason );\n                        me.owner.trigger( 'uploadError', file, reason );\n                        me.owner.trigger( 'uploadComplete', file );\n                    });\n    \n                    pending.push( promise );\n                }\n            },\n    \n            // 让出位置了，可以让其他分片开始上传\n            _popBlock: function( block ) {\n                var idx = $.inArray( block, this.pool );\n    \n                this.pool.splice( idx, 1 );\n                block.file.remaning--;\n                this.remaning--;\n            },\n    \n            // 开始上传，可以被掉过。如果promise被reject了，则表示跳过此分片。\n            _startSend: function( block ) {\n                var me = this,\n                    file = block.file,\n                    promise;\n    \n                me.pool.push( block );\n                me.remaning++;\n    \n                // 如果没有分片，则直接使用原始的。\n                // 不会丢失content-type信息。\n                block.blob = block.chunks === 1 ? file.source :\n                        file.source.slice( block.start, block.end );\n    \n                // hook, 每个分片发送之前可能要做些异步的事情。\n                promise = me.request( 'before-send', block, function() {\n    \n                    // 有可能文件已经上传出错了，所以不需要再传输了。\n                    if ( file.getStatus() === Status.PROGRESS ) {\n                        me._doSend( block );\n                    } else {\n                        me._popBlock( block );\n                        Base.nextTick( me.__tick );\n                    }\n                });\n    \n                // 如果为fail了，则跳过此分片。\n                promise.fail(function() {\n                    if ( file.remaning === 1 ) {\n                        me._finishFile( file ).always(function() {\n                            block.percentage = 1;\n                            me._popBlock( block );\n                            me.owner.trigger( 'uploadComplete', file );\n                            Base.nextTick( me.__tick );\n                        });\n                    } else {\n                        block.percentage = 1;\n                        me._popBlock( block );\n                        Base.nextTick( me.__tick );\n                    }\n                });\n            },\n    \n    \n            /**\n             * @event uploadBeforeSend\n             * @param {Object} object\n             * @param {Object} data 默认的上传参数，可以扩展此对象来控制上传参数。\n             * @description 当某个文件的分块在发送前触发，主要用来询问是否要添加附带参数，大文件在开起分片上传的前提下此事件可能会触发多次。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadAccept\n             * @param {Object} object\n             * @param {Object} ret 服务端的返回数据，json格式，如果服务端不是json格式，从ret._raw中取数据，自行解析。\n             * @description 当某个文件上传到服务端响应后，会派送此事件来询问服务端响应是否有效。如果此事件handler返回值为`false`, 则此文件将派送`server`类型的`uploadError`事件。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadProgress\n             * @param {File} file File对象\n             * @param {Number} percentage 上传进度\n             * @description 上传过程中触发，携带上传进度。\n             * @for  Uploader\n             */\n    \n    \n            /**\n             * @event uploadError\n             * @param {File} file File对象\n             * @param {String} reason 出错的code\n             * @description 当文件上传出错时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadSuccess\n             * @param {File} file File对象\n             * @param {Object} response 服务端返回的数据\n             * @description 当文件上传成功时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadComplete\n             * @param {File} [file] File对象\n             * @description 不管成功或者失败，文件上传完成时触发。\n             * @for  Uploader\n             */\n    \n            // 做上传操作。\n            _doSend: function( block ) {\n                var me = this,\n                    owner = me.owner,\n                    opts = me.options,\n                    file = block.file,\n                    tr = new Transport( opts ),\n                    data = $.extend({}, opts.formData ),\n                    headers = $.extend({}, opts.headers ),\n                    requestAccept, ret;\n    \n                block.transport = tr;\n    \n                tr.on( 'destroy', function() {\n                    delete block.transport;\n                    me._popBlock( block );\n                    Base.nextTick( me.__tick );\n                });\n    \n                // 广播上传进度。以文件为单位。\n                tr.on( 'progress', function( percentage ) {\n                    var totalPercent = 0,\n                        uploaded = 0;\n    \n                    // 可能没有abort掉，progress还是执行进来了。\n                    // if ( !file.blocks ) {\n                    //     return;\n                    // }\n    \n                    totalPercent = block.percentage = percentage;\n    \n                    if ( block.chunks > 1 ) {    // 计算文件的整体速度。\n                        $.each( file.blocks, function( _, v ) {\n                            uploaded += (v.percentage || 0) * (v.end - v.start);\n                        });\n    \n                        totalPercent = uploaded / file.size;\n                    }\n    \n                    owner.trigger( 'uploadProgress', file, totalPercent || 0 );\n                });\n    \n                // 用来询问，是否返回的结果是有错误的。\n                requestAccept = function( reject ) {\n                    var fn;\n    \n                    ret = tr.getResponseAsJson() || {};\n                    ret._raw = tr.getResponse();\n                    fn = function( value ) {\n                        reject = value;\n                    };\n    \n                    // 服务端响应了，不代表成功了，询问是否响应正确。\n                    if ( !owner.trigger( 'uploadAccept', block, ret, fn ) ) {\n                        reject = reject || 'server';\n                    }\n    \n                    return reject;\n                };\n    \n                // 尝试重试，然后广播文件上传出错。\n                tr.on( 'error', function( type, flag ) {\n                    block.retried = block.retried || 0;\n    \n                    // 自动重试\n                    if ( block.chunks > 1 && ~'http,abort'.indexOf( type ) &&\n                            block.retried < opts.chunkRetry ) {\n    \n                        block.retried++;\n                        tr.send();\n    \n                    } else {\n    \n                        // http status 500 ~ 600\n                        if ( !flag && type === 'server' ) {\n                            type = requestAccept( type );\n                        }\n    \n                        file.setStatus( Status.ERROR, type );\n                        owner.trigger( 'uploadError', file, type );\n                        owner.trigger( 'uploadComplete', file );\n                    }\n                });\n    \n                // 上传成功\n                tr.on( 'load', function() {\n                    var reason;\n    \n                    // 如果非预期，转向上传出错。\n                    if ( (reason = requestAccept()) ) {\n                        tr.trigger( 'error', reason, true );\n                        return;\n                    }\n    \n                    // 全部上传完成。\n                    if ( file.remaning === 1 ) {\n                        me._finishFile( file, ret );\n                    } else {\n                        tr.destroy();\n                    }\n                });\n    \n                // 配置默认的上传字段。\n                data = $.extend( data, {\n                    id: file.id,\n                    name: file.name,\n                    type: file.type,\n                    lastModifiedDate: file.lastModifiedDate,\n                    size: file.size\n                });\n    \n                block.chunks > 1 && $.extend( data, {\n                    chunks: block.chunks,\n                    chunk: block.chunk\n                });\n    \n                // 在发送之间可以添加字段什么的。。。\n                // 如果默认的字段不够使用，可以通过监听此事件来扩展\n                owner.trigger( 'uploadBeforeSend', block, data, headers );\n    \n                // 开始发送。\n                tr.appendBlob( opts.fileVal, block.blob, file.name );\n                tr.append( data );\n                tr.setRequestHeader( headers );\n                tr.send();\n            },\n    \n            // 完成上传。\n            _finishFile: function( file, ret, hds ) {\n                var owner = this.owner;\n    \n                return owner\n                        .request( 'after-send-file', arguments, function() {\n                            file.setStatus( Status.COMPLETE );\n                            owner.trigger( 'uploadSuccess', file, ret, hds );\n                        })\n                        .fail(function( reason ) {\n    \n                            // 如果外部已经标记为invalid什么的，不再改状态。\n                            if ( file.getStatus() === Status.PROGRESS ) {\n                                file.setStatus( Status.ERROR, reason );\n                            }\n    \n                            owner.trigger( 'uploadError', file, reason );\n                        })\n                        .always(function() {\n                            owner.trigger( 'uploadComplete', file );\n                        });\n            }\n    \n        });\n    });\n    /**\n     * @fileOverview 各种验证，包括文件总大小是否超出、单文件是否超出和文件是否重复。\n     */\n    \n    define('widgets/validator',[\n        'base',\n        'uploader',\n        'file',\n        'widgets/widget'\n    ], function( Base, Uploader, WUFile ) {\n    \n        var $ = Base.$,\n            validators = {},\n            api;\n    \n        /**\n         * @event error\n         * @param {String} type 错误类型。\n         * @description 当validate不通过时，会以派送错误事件的形式通知调用者。通过`upload.on('error', handler)`可以捕获到此类错误，目前有以下错误会在特定的情况下派送错来。\n         *\n         * * `Q_EXCEED_NUM_LIMIT` 在设置了`fileNumLimit`且尝试给`uploader`添加的文件数量超出这个值时派送。\n         * * `Q_EXCEED_SIZE_LIMIT` 在设置了`Q_EXCEED_SIZE_LIMIT`且尝试给`uploader`添加的文件总大小超出这个值时派送。\n         * @for  Uploader\n         */\n    \n        // 暴露给外面的api\n        api = {\n    \n            // 添加验证器\n            addValidator: function( type, cb ) {\n                validators[ type ] = cb;\n            },\n    \n            // 移除验证器\n            removeValidator: function( type ) {\n                delete validators[ type ];\n            }\n        };\n    \n        // 在Uploader初始化的时候启动Validators的初始化\n        Uploader.register({\n            init: function() {\n                var me = this;\n                $.each( validators, function() {\n                    this.call( me.owner );\n                });\n            }\n        });\n    \n        /**\n         * @property {int} [fileNumLimit=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 验证文件总数量, 超出则不允许加入队列。\n         */\n        api.addValidator( 'fileNumLimit', function() {\n            var uploader = this,\n                opts = uploader.options,\n                count = 0,\n                max = opts.fileNumLimit >> 0,\n                flag = true;\n    \n            if ( !max ) {\n                return;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n    \n                if ( count >= max && flag ) {\n                    flag = false;\n                    this.trigger( 'error', 'Q_EXCEED_NUM_LIMIT', max, file );\n                    setTimeout(function() {\n                        flag = true;\n                    }, 1 );\n                }\n    \n                return count >= max ? false : true;\n            });\n    \n            uploader.on( 'fileQueued', function() {\n                count++;\n            });\n    \n            uploader.on( 'fileDequeued', function() {\n                count--;\n            });\n    \n            uploader.on( 'uploadFinished', function() {\n                count = 0;\n            });\n        });\n    \n    \n        /**\n         * @property {int} [fileSizeLimit=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 验证文件总大小是否超出限制, 超出则不允许加入队列。\n         */\n        api.addValidator( 'fileSizeLimit', function() {\n            var uploader = this,\n                opts = uploader.options,\n                count = 0,\n                max = opts.fileSizeLimit >> 0,\n                flag = true;\n    \n            if ( !max ) {\n                return;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n                var invalid = count + file.size > max;\n    \n                if ( invalid && flag ) {\n                    flag = false;\n                    this.trigger( 'error', 'Q_EXCEED_SIZE_LIMIT', max, file );\n                    setTimeout(function() {\n                        flag = true;\n                    }, 1 );\n                }\n    \n                return invalid ? false : true;\n            });\n    \n            uploader.on( 'fileQueued', function( file ) {\n                count += file.size;\n            });\n    \n            uploader.on( 'fileDequeued', function( file ) {\n                count -= file.size;\n            });\n    \n            uploader.on( 'uploadFinished', function() {\n                count = 0;\n            });\n        });\n    \n        /**\n         * @property {int} [fileSingleSizeLimit=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 验证单个文件大小是否超出限制, 超出则不允许加入队列。\n         */\n        api.addValidator( 'fileSingleSizeLimit', function() {\n            var uploader = this,\n                opts = uploader.options,\n                max = opts.fileSingleSizeLimit;\n    \n            if ( !max ) {\n                return;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n    \n                if ( file.size > max ) {\n                    file.setStatus( WUFile.Status.INVALID, 'exceed_size' );\n                    this.trigger( 'error', 'F_EXCEED_SIZE', file );\n                    return false;\n                }\n    \n            });\n    \n        });\n    \n        /**\n         * @property {int} [duplicate=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 去重， 根据文件名字、文件大小和最后修改时间来生成hash Key.\n         */\n        api.addValidator( 'duplicate', function() {\n            var uploader = this,\n                opts = uploader.options,\n                mapping = {};\n    \n            if ( opts.duplicate ) {\n                return;\n            }\n    \n            function hashString( str ) {\n                var hash = 0,\n                    i = 0,\n                    len = str.length,\n                    _char;\n    \n                for ( ; i < len; i++ ) {\n                    _char = str.charCodeAt( i );\n                    hash = _char + (hash << 6) + (hash << 16) - hash;\n                }\n    \n                return hash;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n                var hash = file.__hash || (file.__hash = hashString( file.name +\n                        file.size + file.lastModifiedDate ));\n    \n                // 已经重复了\n                if ( mapping[ hash ] ) {\n                    this.trigger( 'error', 'F_DUPLICATE', file );\n                    return false;\n                }\n            });\n    \n            uploader.on( 'fileQueued', function( file ) {\n                var hash = file.__hash;\n    \n                hash && (mapping[ hash ] = true);\n            });\n    \n            uploader.on( 'fileDequeued', function( file ) {\n                var hash = file.__hash;\n    \n                hash && (delete mapping[ hash ]);\n            });\n        });\n    \n        return api;\n    });\n    \n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/compbase',[],function() {\n    \n        function CompBase( owner, runtime ) {\n    \n            this.owner = owner;\n            this.options = owner.options;\n    \n            this.getRuntime = function() {\n                return runtime;\n            };\n    \n            this.getRuid = function() {\n                return runtime.uid;\n            };\n    \n            this.trigger = function() {\n                return owner.trigger.apply( owner, arguments );\n            };\n        }\n    \n        return CompBase;\n    });\n    /**\n     * @fileOverview FlashRuntime\n     */\n    define('runtime/flash/runtime',[\n        'base',\n        'runtime/runtime',\n        'runtime/compbase'\n    ], function( Base, Runtime, CompBase ) {\n    \n        var $ = Base.$,\n            type = 'flash',\n            components = {};\n    \n    \n        function getFlashVersion() {\n            var version;\n    \n            try {\n                version = navigator.plugins[ 'Shockwave Flash' ];\n                version = version.description;\n            } catch ( ex ) {\n                try {\n                    version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash')\n                            .GetVariable('$version');\n                } catch ( ex2 ) {\n                    version = '0.0';\n                }\n            }\n            version = version.match( /\\d+/g );\n            return parseFloat( version[ 0 ] + '.' + version[ 1 ], 10 );\n        }\n    \n        function FlashRuntime() {\n            var pool = {},\n                clients = {},\n                destory = this.destory,\n                me = this,\n                jsreciver = Base.guid('webuploader_');\n    \n            Runtime.apply( me, arguments );\n            me.type = type;\n    \n    \n            // 这个方法的调用者，实际上是RuntimeClient\n            me.exec = function( comp, fn/*, args...*/ ) {\n                var client = this,\n                    uid = client.uid,\n                    args = Base.slice( arguments, 2 ),\n                    instance;\n    \n                clients[ uid ] = client;\n    \n                if ( components[ comp ] ) {\n                    if ( !pool[ uid ] ) {\n                        pool[ uid ] = new components[ comp ]( client, me );\n                    }\n    \n                    instance = pool[ uid ];\n    \n                    if ( instance[ fn ] ) {\n                        return instance[ fn ].apply( instance, args );\n                    }\n                }\n    \n                return me.flashExec.apply( client, arguments );\n            };\n    \n            function handler( evt, obj ) {\n                var type = evt.type || evt,\n                    parts, uid;\n    \n                parts = type.split('::');\n                uid = parts[ 0 ];\n                type = parts[ 1 ];\n    \n                // console.log.apply( console, arguments );\n    \n                if ( type === 'Ready' && uid === me.uid ) {\n                    me.trigger('ready');\n                } else if ( clients[ uid ] ) {\n                    clients[ uid ].trigger( type.toLowerCase(), evt, obj );\n                }\n    \n                // Base.log( evt, obj );\n            }\n    \n            // flash的接受器。\n            window[ jsreciver ] = function() {\n                var args = arguments;\n    \n                // 为了能捕获得到。\n                setTimeout(function() {\n                    handler.apply( null, args );\n                }, 1 );\n            };\n    \n            this.jsreciver = jsreciver;\n    \n            this.destory = function() {\n                // @todo 删除池子中的所有实例\n                return destory && destory.apply( this, arguments );\n            };\n    \n            this.flashExec = function( comp, fn ) {\n                var flash = me.getFlash(),\n                    args = Base.slice( arguments, 2 );\n    \n                return flash.exec( this.uid, comp, fn, args );\n            };\n    \n            // @todo\n        }\n    \n        Base.inherits( Runtime, {\n            constructor: FlashRuntime,\n    \n            init: function() {\n                var container = this.getContainer(),\n                    opts = this.options,\n                    html;\n    \n                // if not the minimal height, shims are not initialized\n                // in older browsers (e.g FF3.6, IE6,7,8, Safari 4.0,5.0, etc)\n                container.css({\n                    position: 'absolute',\n                    top: '-8px',\n                    left: '-8px',\n                    width: '9px',\n                    height: '9px',\n                    overflow: 'hidden'\n                });\n    \n                // insert flash object\n                html = '<object id=\"' + this.uid + '\" type=\"application/' +\n                        'x-shockwave-flash\" data=\"' +  opts.swf + '\" ';\n    \n                if ( Base.browser.ie ) {\n                    html += 'classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" ';\n                }\n    \n                html += 'width=\"100%\" height=\"100%\" style=\"outline:0\">'  +\n                    '<param name=\"movie\" value=\"' + opts.swf + '\" />' +\n                    '<param name=\"flashvars\" value=\"uid=' + this.uid +\n                    '&jsreciver=' + this.jsreciver + '\" />' +\n                    '<param name=\"wmode\" value=\"transparent\" />' +\n                    '<param name=\"allowscriptaccess\" value=\"always\" />' +\n                '</object>';\n    \n                container.html( html );\n            },\n    \n            getFlash: function() {\n                if ( this._flash ) {\n                    return this._flash;\n                }\n    \n                this._flash = $( '#' + this.uid ).get( 0 );\n                return this._flash;\n            }\n    \n        });\n    \n        FlashRuntime.register = function( name, component ) {\n            component = components[ name ] = Base.inherits( CompBase, $.extend({\n    \n                // @todo fix this later\n                flashExec: function() {\n                    var owner = this.owner,\n                        runtime = this.getRuntime();\n    \n                    return runtime.flashExec.apply( owner, arguments );\n                }\n            }, component ) );\n    \n            return component;\n        };\n    \n        if ( getFlashVersion() >= 11.4 ) {\n            Runtime.addRuntime( type, FlashRuntime );\n        }\n    \n        return FlashRuntime;\n    });\n    /**\n     * @fileOverview FilePicker\n     */\n    define('runtime/flash/filepicker',[\n        'base',\n        'runtime/flash/runtime'\n    ], function( Base, FlashRuntime ) {\n        var $ = Base.$;\n    \n        return FlashRuntime.register( 'FilePicker', {\n            init: function( opts ) {\n                var copy = $.extend({}, opts ),\n                    len, i;\n    \n                // 修复Flash再没有设置title的情况下无法弹出flash文件选择框的bug.\n                len = copy.accept && copy.accept.length;\n                for (  i = 0; i < len; i++ ) {\n                    if ( !copy.accept[ i ].title ) {\n                        copy.accept[ i ].title = 'Files';\n                    }\n                }\n    \n                delete copy.button;\n                delete copy.container;\n    \n                this.flashExec( 'FilePicker', 'init', copy );\n            },\n    \n            destroy: function() {\n                // todo\n            }\n        });\n    });\n    /**\n     * @fileOverview 图片压缩\n     */\n    define('runtime/flash/image',[\n        'runtime/flash/runtime'\n    ], function( FlashRuntime ) {\n    \n        return FlashRuntime.register( 'Image', {\n            // init: function( options ) {\n            //     var owner = this.owner;\n    \n            //     this.flashExec( 'Image', 'init', options );\n            //     owner.on( 'load', function() {\n            //         debugger;\n            //     });\n            // },\n    \n            loadFromBlob: function( blob ) {\n                var owner = this.owner;\n    \n                owner.info() && this.flashExec( 'Image', 'info', owner.info() );\n                owner.meta() && this.flashExec( 'Image', 'meta', owner.meta() );\n    \n                this.flashExec( 'Image', 'loadFromBlob', blob.uid );\n            }\n        });\n    });\n    /**\n     * @fileOverview  Transport flash实现\n     */\n    define('runtime/flash/transport',[\n        'base',\n        'runtime/flash/runtime',\n        'runtime/client'\n    ], function( Base, FlashRuntime, RuntimeClient ) {\n        var $ = Base.$;\n    \n        return FlashRuntime.register( 'Transport', {\n            init: function() {\n                this._status = 0;\n                this._response = null;\n                this._responseJson = null;\n            },\n    \n            send: function() {\n                var owner = this.owner,\n                    opts = this.options,\n                    xhr = this._initAjax(),\n                    blob = owner._blob,\n                    server = opts.server,\n                    binary;\n    \n                xhr.connectRuntime( blob.ruid );\n    \n                if ( opts.sendAsBinary ) {\n                    server += (/\\?/.test( server ) ? '&' : '?') +\n                            $.param( owner._formData );\n    \n                    binary = blob.uid;\n                } else {\n                    $.each( owner._formData, function( k, v ) {\n                        xhr.exec( 'append', k, v );\n                    });\n    \n                    xhr.exec( 'appendBlob', opts.fileVal, blob.uid,\n                            opts.filename || owner._formData.name || '' );\n                }\n    \n                this._setRequestHeader( xhr, opts.headers );\n                xhr.exec( 'send', {\n                    method: opts.method,\n                    url: server\n                }, binary );\n            },\n    \n            getStatus: function() {\n                return this._status;\n            },\n    \n            getResponse: function() {\n                return this._response;\n            },\n    \n            getResponseAsJson: function() {\n                return this._responseJson;\n            },\n    \n            abort: function() {\n                var xhr = this._xhr;\n    \n                if ( xhr ) {\n                    xhr.exec('abort');\n                    xhr.destroy();\n                    this._xhr = xhr = null;\n                }\n            },\n    \n            destroy: function() {\n                this.abort();\n            },\n    \n            _initAjax: function() {\n                var me = this,\n                    xhr = new RuntimeClient('XMLHttpRequest');\n    \n                xhr.on( 'uploadprogress progress', function( e ) {\n                    return me.trigger( 'progress', e.loaded / e.total );\n                });\n    \n                xhr.on( 'load', function() {\n                    var status = xhr.exec('getStatus'),\n                        err = '';\n    \n                    xhr.off();\n                    me._xhr = null;\n    \n                    if ( status >= 200 && status < 300 ) {\n                        me._response = xhr.exec('getResponse');\n                        me._responseJson = xhr.exec('getResponseAsJson');\n                    } else if ( status >= 500 && status < 600 ) {\n                        me._response = xhr.exec('getResponse');\n                        me._responseJson = xhr.exec('getResponseAsJson');\n                        err = 'server';\n                    } else {\n                        err = 'http';\n                    }\n    \n                    xhr.destroy();\n                    xhr = null;\n    \n                    return err ? me.trigger( 'error', err ) : me.trigger('load');\n                });\n    \n                xhr.on( 'error', function() {\n                    xhr.off();\n                    me._xhr = null;\n                    me.trigger( 'error', 'http' );\n                });\n    \n                me._xhr = xhr;\n                return xhr;\n            },\n    \n            _setRequestHeader: function( xhr, headers ) {\n                $.each( headers, function( key, val ) {\n                    xhr.exec( 'setRequestHeader', key, val );\n                });\n            }\n        });\n    });\n    /**\n     * @fileOverview 只有flash实现的文件版本。\n     */\n    define('preset/flashonly',[\n        'base',\n    \n        // widgets\n        'widgets/filepicker',\n        'widgets/image',\n        'widgets/queue',\n        'widgets/runtime',\n        'widgets/upload',\n        'widgets/validator',\n    \n        // runtimes\n    \n        // flash\n        'runtime/flash/filepicker',\n        'runtime/flash/image',\n        'runtime/flash/transport'\n    ], function( Base ) {\n        return Base;\n    });\n    define('webuploader',[\n        'preset/flashonly'\n    ], function( preset ) {\n        return preset;\n    });\n    return require('webuploader');\n});\n"
  },
  {
    "path": "public/static/ueditor/third-party/webuploader/webuploader.html5only.js",
    "content": "/*! WebUploader 0.1.2 */\n\n\n/**\n * @fileOverview 让内部各个部件的代码可以用[amd](https://github.com/amdjs/amdjs-api/wiki/AMD)模块定义方式组织起来。\n *\n * AMD API 内部的简单不完全实现，请忽略。只有当WebUploader被合并成一个文件的时候才会引入。\n */\n(function( root, factory ) {\n    var modules = {},\n\n        // 内部require, 简单不完全实现。\n        // https://github.com/amdjs/amdjs-api/wiki/require\n        _require = function( deps, callback ) {\n            var args, len, i;\n\n            // 如果deps不是数组，则直接返回指定module\n            if ( typeof deps === 'string' ) {\n                return getModule( deps );\n            } else {\n                args = [];\n                for( len = deps.length, i = 0; i < len; i++ ) {\n                    args.push( getModule( deps[ i ] ) );\n                }\n\n                return callback.apply( null, args );\n            }\n        },\n\n        // 内部define，暂时不支持不指定id.\n        _define = function( id, deps, factory ) {\n            if ( arguments.length === 2 ) {\n                factory = deps;\n                deps = null;\n            }\n\n            _require( deps || [], function() {\n                setModule( id, factory, arguments );\n            });\n        },\n\n        // 设置module, 兼容CommonJs写法。\n        setModule = function( id, factory, args ) {\n            var module = {\n                    exports: factory\n                },\n                returned;\n\n            if ( typeof factory === 'function' ) {\n                args.length || (args = [ _require, module.exports, module ]);\n                returned = factory.apply( null, args );\n                returned !== undefined && (module.exports = returned);\n            }\n\n            modules[ id ] = module.exports;\n        },\n\n        // 根据id获取module\n        getModule = function( id ) {\n            var module = modules[ id ] || root[ id ];\n\n            if ( !module ) {\n                throw new Error( '`' + id + '` is undefined' );\n            }\n\n            return module;\n        },\n\n        // 将所有modules，将路径ids装换成对象。\n        exportsTo = function( obj ) {\n            var key, host, parts, part, last, ucFirst;\n\n            // make the first character upper case.\n            ucFirst = function( str ) {\n                return str && (str.charAt( 0 ).toUpperCase() + str.substr( 1 ));\n            };\n\n            for ( key in modules ) {\n                host = obj;\n\n                if ( !modules.hasOwnProperty( key ) ) {\n                    continue;\n                }\n\n                parts = key.split('/');\n                last = ucFirst( parts.pop() );\n\n                while( (part = ucFirst( parts.shift() )) ) {\n                    host[ part ] = host[ part ] || {};\n                    host = host[ part ];\n                }\n\n                host[ last ] = modules[ key ];\n            }\n        },\n\n        exports = factory( root, _define, _require ),\n        origin;\n\n    // exports every module.\n    exportsTo( exports );\n\n    if ( typeof module === 'object' && typeof module.exports === 'object' ) {\n\n        // For CommonJS and CommonJS-like environments where a proper window is present,\n        module.exports = exports;\n    } else if ( typeof define === 'function' && define.amd ) {\n\n        // Allow using this built library as an AMD module\n        // in another project. That other project will only\n        // see this AMD call, not the internal modules in\n        // the closure below.\n        define([], exports );\n    } else {\n\n        // Browser globals case. Just assign the\n        // result to a property on the global.\n        origin = root.WebUploader;\n        root.WebUploader = exports;\n        root.WebUploader.noConflict = function() {\n            root.WebUploader = origin;\n        };\n    }\n})( this, function( window, define, require ) {\n\n\n    /**\n     * @fileOverview jQuery or Zepto\n     */\n    define('dollar-third',[],function() {\n        return window.jQuery || window.Zepto;\n    });\n    /**\n     * @fileOverview Dom 操作相关\n     */\n    define('dollar',[\n        'dollar-third'\n    ], function( _ ) {\n        return _;\n    });\n    /**\n     * @fileOverview 使用jQuery的Promise\n     */\n    define('promise-third',[\n        'dollar'\n    ], function( $ ) {\n        return {\n            Deferred: $.Deferred,\n            when: $.when,\n    \n            isPromise: function( anything ) {\n                return anything && typeof anything.then === 'function';\n            }\n        };\n    });\n    /**\n     * @fileOverview Promise/A+\n     */\n    define('promise',[\n        'promise-third'\n    ], function( _ ) {\n        return _;\n    });\n    /**\n     * @fileOverview 基础类方法。\n     */\n    \n    /**\n     * Web Uploader内部类的详细说明，以下提及的功能类，都可以在`WebUploader`这个变量中访问到。\n     *\n     * As you know, Web Uploader的每个文件都是用过[AMD](https://github.com/amdjs/amdjs-api/wiki/AMD)规范中的`define`组织起来的, 每个Module都会有个module id.\n     * 默认module id该文件的路径，而此路径将会转化成名字空间存放在WebUploader中。如：\n     *\n     * * module `base`：WebUploader.Base\n     * * module `file`: WebUploader.File\n     * * module `lib/dnd`: WebUploader.Lib.Dnd\n     * * module `runtime/html5/dnd`: WebUploader.Runtime.Html5.Dnd\n     *\n     *\n     * 以下文档将可能省略`WebUploader`前缀。\n     * @module WebUploader\n     * @title WebUploader API文档\n     */\n    define('base',[\n        'dollar',\n        'promise'\n    ], function( $, promise ) {\n    \n        var noop = function() {},\n            call = Function.call;\n    \n        // http://jsperf.com/uncurrythis\n        // 反科里化\n        function uncurryThis( fn ) {\n            return function() {\n                return call.apply( fn, arguments );\n            };\n        }\n    \n        function bindFn( fn, context ) {\n            return function() {\n                return fn.apply( context, arguments );\n            };\n        }\n    \n        function createObject( proto ) {\n            var f;\n    \n            if ( Object.create ) {\n                return Object.create( proto );\n            } else {\n                f = function() {};\n                f.prototype = proto;\n                return new f();\n            }\n        }\n    \n    \n        /**\n         * 基础类，提供一些简单常用的方法。\n         * @class Base\n         */\n        return {\n    \n            /**\n             * @property {String} version 当前版本号。\n             */\n            version: '0.1.2',\n    \n            /**\n             * @property {jQuery|Zepto} $ 引用依赖的jQuery或者Zepto对象。\n             */\n            $: $,\n    \n            Deferred: promise.Deferred,\n    \n            isPromise: promise.isPromise,\n    \n            when: promise.when,\n    \n            /**\n             * @description  简单的浏览器检查结果。\n             *\n             * * `webkit`  webkit版本号，如果浏览器为非webkit内核，此属性为`undefined`。\n             * * `chrome`  chrome浏览器版本号，如果浏览器为chrome，此属性为`undefined`。\n             * * `ie`  ie浏览器版本号，如果浏览器为非ie，此属性为`undefined`。**暂不支持ie10+**\n             * * `firefox`  firefox浏览器版本号，如果浏览器为非firefox，此属性为`undefined`。\n             * * `safari`  safari浏览器版本号，如果浏览器为非safari，此属性为`undefined`。\n             * * `opera`  opera浏览器版本号，如果浏览器为非opera，此属性为`undefined`。\n             *\n             * @property {Object} [browser]\n             */\n            browser: (function( ua ) {\n                var ret = {},\n                    webkit = ua.match( /WebKit\\/([\\d.]+)/ ),\n                    chrome = ua.match( /Chrome\\/([\\d.]+)/ ) ||\n                        ua.match( /CriOS\\/([\\d.]+)/ ),\n    \n                    ie = ua.match( /MSIE\\s([\\d\\.]+)/ ) ||\n                        ua.match(/(?:trident)(?:.*rv:([\\w.]+))?/i),\n                    firefox = ua.match( /Firefox\\/([\\d.]+)/ ),\n                    safari = ua.match( /Safari\\/([\\d.]+)/ ),\n                    opera = ua.match( /OPR\\/([\\d.]+)/ );\n    \n                webkit && (ret.webkit = parseFloat( webkit[ 1 ] ));\n                chrome && (ret.chrome = parseFloat( chrome[ 1 ] ));\n                ie && (ret.ie = parseFloat( ie[ 1 ] ));\n                firefox && (ret.firefox = parseFloat( firefox[ 1 ] ));\n                safari && (ret.safari = parseFloat( safari[ 1 ] ));\n                opera && (ret.opera = parseFloat( opera[ 1 ] ));\n    \n                return ret;\n            })( navigator.userAgent ),\n    \n            /**\n             * @description  操作系统检查结果。\n             *\n             * * `android`  如果在android浏览器环境下，此值为对应的android版本号，否则为`undefined`。\n             * * `ios` 如果在ios浏览器环境下，此值为对应的ios版本号，否则为`undefined`。\n             * @property {Object} [os]\n             */\n            os: (function( ua ) {\n                var ret = {},\n    \n                    // osx = !!ua.match( /\\(Macintosh\\; Intel / ),\n                    android = ua.match( /(?:Android);?[\\s\\/]+([\\d.]+)?/ ),\n                    ios = ua.match( /(?:iPad|iPod|iPhone).*OS\\s([\\d_]+)/ );\n    \n                // osx && (ret.osx = true);\n                android && (ret.android = parseFloat( android[ 1 ] ));\n                ios && (ret.ios = parseFloat( ios[ 1 ].replace( /_/g, '.' ) ));\n    \n                return ret;\n            })( navigator.userAgent ),\n    \n            /**\n             * 实现类与类之间的继承。\n             * @method inherits\n             * @grammar Base.inherits( super ) => child\n             * @grammar Base.inherits( super, protos ) => child\n             * @grammar Base.inherits( super, protos, statics ) => child\n             * @param  {Class} super 父类\n             * @param  {Object | Function} [protos] 子类或者对象。如果对象中包含constructor，子类将是用此属性值。\n             * @param  {Function} [protos.constructor] 子类构造器，不指定的话将创建个临时的直接执行父类构造器的方法。\n             * @param  {Object} [statics] 静态属性或方法。\n             * @return {Class} 返回子类。\n             * @example\n             * function Person() {\n             *     console.log( 'Super' );\n             * }\n             * Person.prototype.hello = function() {\n             *     console.log( 'hello' );\n             * };\n             *\n             * var Manager = Base.inherits( Person, {\n             *     world: function() {\n             *         console.log( 'World' );\n             *     }\n             * });\n             *\n             * // 因为没有指定构造器，父类的构造器将会执行。\n             * var instance = new Manager();    // => Super\n             *\n             * // 继承子父类的方法\n             * instance.hello();    // => hello\n             * instance.world();    // => World\n             *\n             * // 子类的__super__属性指向父类\n             * console.log( Manager.__super__ === Person );    // => true\n             */\n            inherits: function( Super, protos, staticProtos ) {\n                var child;\n    \n                if ( typeof protos === 'function' ) {\n                    child = protos;\n                    protos = null;\n                } else if ( protos && protos.hasOwnProperty('constructor') ) {\n                    child = protos.constructor;\n                } else {\n                    child = function() {\n                        return Super.apply( this, arguments );\n                    };\n                }\n    \n                // 复制静态方法\n                $.extend( true, child, Super, staticProtos || {} );\n    \n                /* jshint camelcase: false */\n    \n                // 让子类的__super__属性指向父类。\n                child.__super__ = Super.prototype;\n    \n                // 构建原型，添加原型方法或属性。\n                // 暂时用Object.create实现。\n                child.prototype = createObject( Super.prototype );\n                protos && $.extend( true, child.prototype, protos );\n    \n                return child;\n            },\n    \n            /**\n             * 一个不做任何事情的方法。可以用来赋值给默认的callback.\n             * @method noop\n             */\n            noop: noop,\n    \n            /**\n             * 返回一个新的方法，此方法将已指定的`context`来执行。\n             * @grammar Base.bindFn( fn, context ) => Function\n             * @method bindFn\n             * @example\n             * var doSomething = function() {\n             *         console.log( this.name );\n             *     },\n             *     obj = {\n             *         name: 'Object Name'\n             *     },\n             *     aliasFn = Base.bind( doSomething, obj );\n             *\n             *  aliasFn();    // => Object Name\n             *\n             */\n            bindFn: bindFn,\n    \n            /**\n             * 引用Console.log如果存在的话，否则引用一个[空函数loop](#WebUploader:Base.log)。\n             * @grammar Base.log( args... ) => undefined\n             * @method log\n             */\n            log: (function() {\n                if ( window.console ) {\n                    return bindFn( console.log, console );\n                }\n                return noop;\n            })(),\n    \n            nextTick: (function() {\n    \n                return function( cb ) {\n                    setTimeout( cb, 1 );\n                };\n    \n                // @bug 当浏览器不在当前窗口时就停了。\n                // var next = window.requestAnimationFrame ||\n                //     window.webkitRequestAnimationFrame ||\n                //     window.mozRequestAnimationFrame ||\n                //     function( cb ) {\n                //         window.setTimeout( cb, 1000 / 60 );\n                //     };\n    \n                // // fix: Uncaught TypeError: Illegal invocation\n                // return bindFn( next, window );\n            })(),\n    \n            /**\n             * 被[uncurrythis](http://www.2ality.com/2011/11/uncurrying-this.html)的数组slice方法。\n             * 将用来将非数组对象转化成数组对象。\n             * @grammar Base.slice( target, start[, end] ) => Array\n             * @method slice\n             * @example\n             * function doSomthing() {\n             *     var args = Base.slice( arguments, 1 );\n             *     console.log( args );\n             * }\n             *\n             * doSomthing( 'ignored', 'arg2', 'arg3' );    // => Array [\"arg2\", \"arg3\"]\n             */\n            slice: uncurryThis( [].slice ),\n    \n            /**\n             * 生成唯一的ID\n             * @method guid\n             * @grammar Base.guid() => String\n             * @grammar Base.guid( prefx ) => String\n             */\n            guid: (function() {\n                var counter = 0;\n    \n                return function( prefix ) {\n                    var guid = (+new Date()).toString( 32 ),\n                        i = 0;\n    \n                    for ( ; i < 5; i++ ) {\n                        guid += Math.floor( Math.random() * 65535 ).toString( 32 );\n                    }\n    \n                    return (prefix || 'wu_') + guid + (counter++).toString( 32 );\n                };\n            })(),\n    \n            /**\n             * 格式化文件大小, 输出成带单位的字符串\n             * @method formatSize\n             * @grammar Base.formatSize( size ) => String\n             * @grammar Base.formatSize( size, pointLength ) => String\n             * @grammar Base.formatSize( size, pointLength, units ) => String\n             * @param {Number} size 文件大小\n             * @param {Number} [pointLength=2] 精确到的小数点数。\n             * @param {Array} [units=[ 'B', 'K', 'M', 'G', 'TB' ]] 单位数组。从字节，到千字节，一直往上指定。如果单位数组里面只指定了到了K(千字节)，同时文件大小大于M, 此方法的输出将还是显示成多少K.\n             * @example\n             * console.log( Base.formatSize( 100 ) );    // => 100B\n             * console.log( Base.formatSize( 1024 ) );    // => 1.00K\n             * console.log( Base.formatSize( 1024, 0 ) );    // => 1K\n             * console.log( Base.formatSize( 1024 * 1024 ) );    // => 1.00M\n             * console.log( Base.formatSize( 1024 * 1024 * 1024 ) );    // => 1.00G\n             * console.log( Base.formatSize( 1024 * 1024 * 1024, 0, ['B', 'KB', 'MB'] ) );    // => 1024MB\n             */\n            formatSize: function( size, pointLength, units ) {\n                var unit;\n    \n                units = units || [ 'B', 'K', 'M', 'G', 'TB' ];\n    \n                while ( (unit = units.shift()) && size > 1024 ) {\n                    size = size / 1024;\n                }\n    \n                return (unit === 'B' ? size : size.toFixed( pointLength || 2 )) +\n                        unit;\n            }\n        };\n    });\n    /**\n     * 事件处理类，可以独立使用，也可以扩展给对象使用。\n     * @fileOverview Mediator\n     */\n    define('mediator',[\n        'base'\n    ], function( Base ) {\n        var $ = Base.$,\n            slice = [].slice,\n            separator = /\\s+/,\n            protos;\n    \n        // 根据条件过滤出事件handlers.\n        function findHandlers( arr, name, callback, context ) {\n            return $.grep( arr, function( handler ) {\n                return handler &&\n                        (!name || handler.e === name) &&\n                        (!callback || handler.cb === callback ||\n                        handler.cb._cb === callback) &&\n                        (!context || handler.ctx === context);\n            });\n        }\n    \n        function eachEvent( events, callback, iterator ) {\n            // 不支持对象，只支持多个event用空格隔开\n            $.each( (events || '').split( separator ), function( _, key ) {\n                iterator( key, callback );\n            });\n        }\n    \n        function triggerHanders( events, args ) {\n            var stoped = false,\n                i = -1,\n                len = events.length,\n                handler;\n    \n            while ( ++i < len ) {\n                handler = events[ i ];\n    \n                if ( handler.cb.apply( handler.ctx2, args ) === false ) {\n                    stoped = true;\n                    break;\n                }\n            }\n    \n            return !stoped;\n        }\n    \n        protos = {\n    \n            /**\n             * 绑定事件。\n             *\n             * `callback`方法在执行时，arguments将会来源于trigger的时候携带的参数。如\n             * ```javascript\n             * var obj = {};\n             *\n             * // 使得obj有事件行为\n             * Mediator.installTo( obj );\n             *\n             * obj.on( 'testa', function( arg1, arg2 ) {\n             *     console.log( arg1, arg2 ); // => 'arg1', 'arg2'\n             * });\n             *\n             * obj.trigger( 'testa', 'arg1', 'arg2' );\n             * ```\n             *\n             * 如果`callback`中，某一个方法`return false`了，则后续的其他`callback`都不会被执行到。\n             * 切会影响到`trigger`方法的返回值，为`false`。\n             *\n             * `on`还可以用来添加一个特殊事件`all`, 这样所有的事件触发都会响应到。同时此类`callback`中的arguments有一个不同处，\n             * 就是第一个参数为`type`，记录当前是什么事件在触发。此类`callback`的优先级比脚低，会再正常`callback`执行完后触发。\n             * ```javascript\n             * obj.on( 'all', function( type, arg1, arg2 ) {\n             *     console.log( type, arg1, arg2 ); // => 'testa', 'arg1', 'arg2'\n             * });\n             * ```\n             *\n             * @method on\n             * @grammar on( name, callback[, context] ) => self\n             * @param  {String}   name     事件名，支持多个事件用空格隔开\n             * @param  {Function} callback 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             * @class Mediator\n             */\n            on: function( name, callback, context ) {\n                var me = this,\n                    set;\n    \n                if ( !callback ) {\n                    return this;\n                }\n    \n                set = this._events || (this._events = []);\n    \n                eachEvent( name, callback, function( name, callback ) {\n                    var handler = { e: name };\n    \n                    handler.cb = callback;\n                    handler.ctx = context;\n                    handler.ctx2 = context || me;\n                    handler.id = set.length;\n    \n                    set.push( handler );\n                });\n    \n                return this;\n            },\n    \n            /**\n             * 绑定事件，且当handler执行完后，自动解除绑定。\n             * @method once\n             * @grammar once( name, callback[, context] ) => self\n             * @param  {String}   name     事件名\n             * @param  {Function} callback 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             */\n            once: function( name, callback, context ) {\n                var me = this;\n    \n                if ( !callback ) {\n                    return me;\n                }\n    \n                eachEvent( name, callback, function( name, callback ) {\n                    var once = function() {\n                            me.off( name, once );\n                            return callback.apply( context || me, arguments );\n                        };\n    \n                    once._cb = callback;\n                    me.on( name, once, context );\n                });\n    \n                return me;\n            },\n    \n            /**\n             * 解除事件绑定\n             * @method off\n             * @grammar off( [name[, callback[, context] ] ] ) => self\n             * @param  {String}   [name]     事件名\n             * @param  {Function} [callback] 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             */\n            off: function( name, cb, ctx ) {\n                var events = this._events;\n    \n                if ( !events ) {\n                    return this;\n                }\n    \n                if ( !name && !cb && !ctx ) {\n                    this._events = [];\n                    return this;\n                }\n    \n                eachEvent( name, cb, function( name, cb ) {\n                    $.each( findHandlers( events, name, cb, ctx ), function() {\n                        delete events[ this.id ];\n                    });\n                });\n    \n                return this;\n            },\n    \n            /**\n             * 触发事件\n             * @method trigger\n             * @grammar trigger( name[, args...] ) => self\n             * @param  {String}   type     事件名\n             * @param  {*} [...] 任意参数\n             * @return {Boolean} 如果handler中return false了，则返回false, 否则返回true\n             */\n            trigger: function( type ) {\n                var args, events, allEvents;\n    \n                if ( !this._events || !type ) {\n                    return this;\n                }\n    \n                args = slice.call( arguments, 1 );\n                events = findHandlers( this._events, type );\n                allEvents = findHandlers( this._events, 'all' );\n    \n                return triggerHanders( events, args ) &&\n                        triggerHanders( allEvents, arguments );\n            }\n        };\n    \n        /**\n         * 中介者，它本身是个单例，但可以通过[installTo](#WebUploader:Mediator:installTo)方法，使任何对象具备事件行为。\n         * 主要目的是负责模块与模块之间的合作，降低耦合度。\n         *\n         * @class Mediator\n         */\n        return $.extend({\n    \n            /**\n             * 可以通过这个接口，使任何对象具备事件功能。\n             * @method installTo\n             * @param  {Object} obj 需要具备事件行为的对象。\n             * @return {Object} 返回obj.\n             */\n            installTo: function( obj ) {\n                return $.extend( obj, protos );\n            }\n    \n        }, protos );\n    });\n    /**\n     * @fileOverview Uploader上传类\n     */\n    define('uploader',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$;\n    \n        /**\n         * 上传入口类。\n         * @class Uploader\n         * @constructor\n         * @grammar new Uploader( opts ) => Uploader\n         * @example\n         * var uploader = WebUploader.Uploader({\n         *     swf: 'path_of_swf/Uploader.swf',\n         *\n         *     // 开起分片上传。\n         *     chunked: true\n         * });\n         */\n        function Uploader( opts ) {\n            this.options = $.extend( true, {}, Uploader.options, opts );\n            this._init( this.options );\n        }\n    \n        // default Options\n        // widgets中有相应扩展\n        Uploader.options = {};\n        Mediator.installTo( Uploader.prototype );\n    \n        // 批量添加纯命令式方法。\n        $.each({\n            upload: 'start-upload',\n            stop: 'stop-upload',\n            getFile: 'get-file',\n            getFiles: 'get-files',\n            addFile: 'add-file',\n            addFiles: 'add-file',\n            sort: 'sort-files',\n            removeFile: 'remove-file',\n            skipFile: 'skip-file',\n            retry: 'retry',\n            isInProgress: 'is-in-progress',\n            makeThumb: 'make-thumb',\n            getDimension: 'get-dimension',\n            addButton: 'add-btn',\n            getRuntimeType: 'get-runtime-type',\n            refresh: 'refresh',\n            disable: 'disable',\n            enable: 'enable',\n            reset: 'reset'\n        }, function( fn, command ) {\n            Uploader.prototype[ fn ] = function() {\n                return this.request( command, arguments );\n            };\n        });\n    \n        $.extend( Uploader.prototype, {\n            state: 'pending',\n    \n            _init: function( opts ) {\n                var me = this;\n    \n                me.request( 'init', opts, function() {\n                    me.state = 'ready';\n                    me.trigger('ready');\n                });\n            },\n    \n            /**\n             * 获取或者设置Uploader配置项。\n             * @method option\n             * @grammar option( key ) => *\n             * @grammar option( key, val ) => self\n             * @example\n             *\n             * // 初始状态图片上传前不会压缩\n             * var uploader = new WebUploader.Uploader({\n             *     resize: null;\n             * });\n             *\n             * // 修改后图片上传前，尝试将图片压缩到1600 * 1600\n             * uploader.options( 'resize', {\n             *     width: 1600,\n             *     height: 1600\n             * });\n             */\n            option: function( key, val ) {\n                var opts = this.options;\n    \n                // setter\n                if ( arguments.length > 1 ) {\n    \n                    if ( $.isPlainObject( val ) &&\n                            $.isPlainObject( opts[ key ] ) ) {\n                        $.extend( opts[ key ], val );\n                    } else {\n                        opts[ key ] = val;\n                    }\n    \n                } else {    // getter\n                    return key ? opts[ key ] : opts;\n                }\n            },\n    \n            /**\n             * 获取文件统计信息。返回一个包含一下信息的对象。\n             * * `successNum` 上传成功的文件数\n             * * `uploadFailNum` 上传失败的文件数\n             * * `cancelNum` 被删除的文件数\n             * * `invalidNum` 无效的文件数\n             * * `queueNum` 还在队列中的文件数\n             * @method getStats\n             * @grammar getStats() => Object\n             */\n            getStats: function() {\n                // return this._mgr.getStats.apply( this._mgr, arguments );\n                var stats = this.request('get-stats');\n    \n                return {\n                    successNum: stats.numOfSuccess,\n    \n                    // who care?\n                    // queueFailNum: 0,\n                    cancelNum: stats.numOfCancel,\n                    invalidNum: stats.numOfInvalid,\n                    uploadFailNum: stats.numOfUploadFailed,\n                    queueNum: stats.numOfQueue\n                };\n            },\n    \n            // 需要重写此方法来来支持opts.onEvent和instance.onEvent的处理器\n            trigger: function( type/*, args...*/ ) {\n                var args = [].slice.call( arguments, 1 ),\n                    opts = this.options,\n                    name = 'on' + type.substring( 0, 1 ).toUpperCase() +\n                        type.substring( 1 );\n    \n                if (\n                        // 调用通过on方法注册的handler.\n                        Mediator.trigger.apply( this, arguments ) === false ||\n    \n                        // 调用opts.onEvent\n                        $.isFunction( opts[ name ] ) &&\n                        opts[ name ].apply( this, args ) === false ||\n    \n                        // 调用this.onEvent\n                        $.isFunction( this[ name ] ) &&\n                        this[ name ].apply( this, args ) === false ||\n    \n                        // 广播所有uploader的事件。\n                        Mediator.trigger.apply( Mediator,\n                        [ this, type ].concat( args ) ) === false ) {\n    \n                    return false;\n                }\n    \n                return true;\n            },\n    \n            // widgets/widget.js将补充此方法的详细文档。\n            request: Base.noop\n        });\n    \n        /**\n         * 创建Uploader实例，等同于new Uploader( opts );\n         * @method create\n         * @class Base\n         * @static\n         * @grammar Base.create( opts ) => Uploader\n         */\n        Base.create = Uploader.create = function( opts ) {\n            return new Uploader( opts );\n        };\n    \n        // 暴露Uploader，可以通过它来扩展业务逻辑。\n        Base.Uploader = Uploader;\n    \n        return Uploader;\n    });\n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/runtime',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$,\n            factories = {},\n    \n            // 获取对象的第一个key\n            getFirstKey = function( obj ) {\n                for ( var key in obj ) {\n                    if ( obj.hasOwnProperty( key ) ) {\n                        return key;\n                    }\n                }\n                return null;\n            };\n    \n        // 接口类。\n        function Runtime( options ) {\n            this.options = $.extend({\n                container: document.body\n            }, options );\n            this.uid = Base.guid('rt_');\n        }\n    \n        $.extend( Runtime.prototype, {\n    \n            getContainer: function() {\n                var opts = this.options,\n                    parent, container;\n    \n                if ( this._container ) {\n                    return this._container;\n                }\n    \n                parent = $( opts.container || document.body );\n                container = $( document.createElement('div') );\n    \n                container.attr( 'id', 'rt_' + this.uid );\n                container.css({\n                    position: 'absolute',\n                    top: '0px',\n                    left: '0px',\n                    width: '1px',\n                    height: '1px',\n                    overflow: 'hidden'\n                });\n    \n                parent.append( container );\n                parent.addClass('webuploader-container');\n                this._container = container;\n                return container;\n            },\n    \n            init: Base.noop,\n            exec: Base.noop,\n    \n            destroy: function() {\n                if ( this._container ) {\n                    this._container.parentNode.removeChild( this.__container );\n                }\n    \n                this.off();\n            }\n        });\n    \n        Runtime.orders = 'html5,flash';\n    \n    \n        /**\n         * 添加Runtime实现。\n         * @param {String} type    类型\n         * @param {Runtime} factory 具体Runtime实现。\n         */\n        Runtime.addRuntime = function( type, factory ) {\n            factories[ type ] = factory;\n        };\n    \n        Runtime.hasRuntime = function( type ) {\n            return !!(type ? factories[ type ] : getFirstKey( factories ));\n        };\n    \n        Runtime.create = function( opts, orders ) {\n            var type, runtime;\n    \n            orders = orders || Runtime.orders;\n            $.each( orders.split( /\\s*,\\s*/g ), function() {\n                if ( factories[ this ] ) {\n                    type = this;\n                    return false;\n                }\n            });\n    \n            type = type || getFirstKey( factories );\n    \n            if ( !type ) {\n                throw new Error('Runtime Error');\n            }\n    \n            runtime = new factories[ type ]( opts );\n            return runtime;\n        };\n    \n        Mediator.installTo( Runtime.prototype );\n        return Runtime;\n    });\n    \n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/client',[\n        'base',\n        'mediator',\n        'runtime/runtime'\n    ], function( Base, Mediator, Runtime ) {\n    \n        var cache;\n    \n        cache = (function() {\n            var obj = {};\n    \n            return {\n                add: function( runtime ) {\n                    obj[ runtime.uid ] = runtime;\n                },\n    \n                get: function( ruid, standalone ) {\n                    var i;\n    \n                    if ( ruid ) {\n                        return obj[ ruid ];\n                    }\n    \n                    for ( i in obj ) {\n                        // 有些类型不能重用，比如filepicker.\n                        if ( standalone && obj[ i ].__standalone ) {\n                            continue;\n                        }\n    \n                        return obj[ i ];\n                    }\n    \n                    return null;\n                },\n    \n                remove: function( runtime ) {\n                    delete obj[ runtime.uid ];\n                }\n            };\n        })();\n    \n        function RuntimeClient( component, standalone ) {\n            var deferred = Base.Deferred(),\n                runtime;\n    \n            this.uid = Base.guid('client_');\n    \n            // 允许runtime没有初始化之前，注册一些方法在初始化后执行。\n            this.runtimeReady = function( cb ) {\n                return deferred.done( cb );\n            };\n    \n            this.connectRuntime = function( opts, cb ) {\n    \n                // already connected.\n                if ( runtime ) {\n                    throw new Error('already connected!');\n                }\n    \n                deferred.done( cb );\n    \n                if ( typeof opts === 'string' && cache.get( opts ) ) {\n                    runtime = cache.get( opts );\n                }\n    \n                // 像filePicker只能独立存在，不能公用。\n                runtime = runtime || cache.get( null, standalone );\n    \n                // 需要创建\n                if ( !runtime ) {\n                    runtime = Runtime.create( opts, opts.runtimeOrder );\n                    runtime.__promise = deferred.promise();\n                    runtime.once( 'ready', deferred.resolve );\n                    runtime.init();\n                    cache.add( runtime );\n                    runtime.__client = 1;\n                } else {\n                    // 来自cache\n                    Base.$.extend( runtime.options, opts );\n                    runtime.__promise.then( deferred.resolve );\n                    runtime.__client++;\n                }\n    \n                standalone && (runtime.__standalone = standalone);\n                return runtime;\n            };\n    \n            this.getRuntime = function() {\n                return runtime;\n            };\n    \n            this.disconnectRuntime = function() {\n                if ( !runtime ) {\n                    return;\n                }\n    \n                runtime.__client--;\n    \n                if ( runtime.__client <= 0 ) {\n                    cache.remove( runtime );\n                    delete runtime.__promise;\n                    runtime.destroy();\n                }\n    \n                runtime = null;\n            };\n    \n            this.exec = function() {\n                if ( !runtime ) {\n                    return;\n                }\n    \n                var args = Base.slice( arguments );\n                component && args.unshift( component );\n    \n                return runtime.exec.apply( this, args );\n            };\n    \n            this.getRuid = function() {\n                return runtime && runtime.uid;\n            };\n    \n            this.destroy = (function( destroy ) {\n                return function() {\n                    destroy && destroy.apply( this, arguments );\n                    this.trigger('destroy');\n                    this.off();\n                    this.exec('destroy');\n                    this.disconnectRuntime();\n                };\n            })( this.destroy );\n        }\n    \n        Mediator.installTo( RuntimeClient.prototype );\n        return RuntimeClient;\n    });\n    /**\n     * @fileOverview 错误信息\n     */\n    define('lib/dnd',[\n        'base',\n        'mediator',\n        'runtime/client'\n    ], function( Base, Mediator, RuntimeClent ) {\n    \n        var $ = Base.$;\n    \n        function DragAndDrop( opts ) {\n            opts = this.options = $.extend({}, DragAndDrop.options, opts );\n    \n            opts.container = $( opts.container );\n    \n            if ( !opts.container.length ) {\n                return;\n            }\n    \n            RuntimeClent.call( this, 'DragAndDrop' );\n        }\n    \n        DragAndDrop.options = {\n            accept: null,\n            disableGlobalDnd: false\n        };\n    \n        Base.inherits( RuntimeClent, {\n            constructor: DragAndDrop,\n    \n            init: function() {\n                var me = this;\n    \n                me.connectRuntime( me.options, function() {\n                    me.exec('init');\n                    me.trigger('ready');\n                });\n            },\n    \n            destroy: function() {\n                this.disconnectRuntime();\n            }\n        });\n    \n        Mediator.installTo( DragAndDrop.prototype );\n    \n        return DragAndDrop;\n    });\n    /**\n     * @fileOverview 组件基类。\n     */\n    define('widgets/widget',[\n        'base',\n        'uploader'\n    ], function( Base, Uploader ) {\n    \n        var $ = Base.$,\n            _init = Uploader.prototype._init,\n            IGNORE = {},\n            widgetClass = [];\n    \n        function isArrayLike( obj ) {\n            if ( !obj ) {\n                return false;\n            }\n    \n            var length = obj.length,\n                type = $.type( obj );\n    \n            if ( obj.nodeType === 1 && length ) {\n                return true;\n            }\n    \n            return type === 'array' || type !== 'function' && type !== 'string' &&\n                    (length === 0 || typeof length === 'number' && length > 0 &&\n                    (length - 1) in obj);\n        }\n    \n        function Widget( uploader ) {\n            this.owner = uploader;\n            this.options = uploader.options;\n        }\n    \n        $.extend( Widget.prototype, {\n    \n            init: Base.noop,\n    \n            // 类Backbone的事件监听声明，监听uploader实例上的事件\n            // widget直接无法监听事件，事件只能通过uploader来传递\n            invoke: function( apiName, args ) {\n    \n                /*\n                    {\n                        'make-thumb': 'makeThumb'\n                    }\n                 */\n                var map = this.responseMap;\n    \n                // 如果无API响应声明则忽略\n                if ( !map || !(apiName in map) || !(map[ apiName ] in this) ||\n                        !$.isFunction( this[ map[ apiName ] ] ) ) {\n    \n                    return IGNORE;\n                }\n    \n                return this[ map[ apiName ] ].apply( this, args );\n    \n            },\n    \n            /**\n             * 发送命令。当传入`callback`或者`handler`中返回`promise`时。返回一个当所有`handler`中的promise都完成后完成的新`promise`。\n             * @method request\n             * @grammar request( command, args ) => * | Promise\n             * @grammar request( command, args, callback ) => Promise\n             * @for  Uploader\n             */\n            request: function() {\n                return this.owner.request.apply( this.owner, arguments );\n            }\n        });\n    \n        // 扩展Uploader.\n        $.extend( Uploader.prototype, {\n    \n            // 覆写_init用来初始化widgets\n            _init: function() {\n                var me = this,\n                    widgets = me._widgets = [];\n    \n                $.each( widgetClass, function( _, klass ) {\n                    widgets.push( new klass( me ) );\n                });\n    \n                return _init.apply( me, arguments );\n            },\n    \n            request: function( apiName, args, callback ) {\n                var i = 0,\n                    widgets = this._widgets,\n                    len = widgets.length,\n                    rlts = [],\n                    dfds = [],\n                    widget, rlt, promise, key;\n    \n                args = isArrayLike( args ) ? args : [ args ];\n    \n                for ( ; i < len; i++ ) {\n                    widget = widgets[ i ];\n                    rlt = widget.invoke( apiName, args );\n    \n                    if ( rlt !== IGNORE ) {\n    \n                        // Deferred对象\n                        if ( Base.isPromise( rlt ) ) {\n                            dfds.push( rlt );\n                        } else {\n                            rlts.push( rlt );\n                        }\n                    }\n                }\n    \n                // 如果有callback，则用异步方式。\n                if ( callback || dfds.length ) {\n                    promise = Base.when.apply( Base, dfds );\n                    key = promise.pipe ? 'pipe' : 'then';\n    \n                    // 很重要不能删除。删除了会死循环。\n                    // 保证执行顺序。让callback总是在下一个tick中执行。\n                    return promise[ key ](function() {\n                                var deferred = Base.Deferred(),\n                                    args = arguments;\n    \n                                setTimeout(function() {\n                                    deferred.resolve.apply( deferred, args );\n                                }, 1 );\n    \n                                return deferred.promise();\n                            })[ key ]( callback || Base.noop );\n                } else {\n                    return rlts[ 0 ];\n                }\n            }\n        });\n    \n        /**\n         * 添加组件\n         * @param  {object} widgetProto 组件原型，构造函数通过constructor属性定义\n         * @param  {object} responseMap API名称与函数实现的映射\n         * @example\n         *     Uploader.register( {\n         *         init: function( options ) {},\n         *         makeThumb: function() {}\n         *     }, {\n         *         'make-thumb': 'makeThumb'\n         *     } );\n         */\n        Uploader.register = Widget.register = function( responseMap, widgetProto ) {\n            var map = { init: 'init' },\n                klass;\n    \n            if ( arguments.length === 1 ) {\n                widgetProto = responseMap;\n                widgetProto.responseMap = map;\n            } else {\n                widgetProto.responseMap = $.extend( map, responseMap );\n            }\n    \n            klass = Base.inherits( Widget, widgetProto );\n            widgetClass.push( klass );\n    \n            return klass;\n        };\n    \n        return Widget;\n    });\n    /**\n     * @fileOverview DragAndDrop Widget。\n     */\n    define('widgets/filednd',[\n        'base',\n        'uploader',\n        'lib/dnd',\n        'widgets/widget'\n    ], function( Base, Uploader, Dnd ) {\n        var $ = Base.$;\n    \n        Uploader.options.dnd = '';\n    \n        /**\n         * @property {Selector} [dnd=undefined]  指定Drag And Drop拖拽的容器，如果不指定，则不启动。\n         * @namespace options\n         * @for Uploader\n         */\n    \n        /**\n         * @event dndAccept\n         * @param {DataTransferItemList} items DataTransferItem\n         * @description 阻止此事件可以拒绝某些类型的文件拖入进来。目前只有 chrome 提供这样的 API，且只能通过 mime-type 验证。\n         * @for  Uploader\n         */\n        return Uploader.register({\n            init: function( opts ) {\n    \n                if ( !opts.dnd ||\n                        this.request('predict-runtime-type') !== 'html5' ) {\n                    return;\n                }\n    \n                var me = this,\n                    deferred = Base.Deferred(),\n                    options = $.extend({}, {\n                        disableGlobalDnd: opts.disableGlobalDnd,\n                        container: opts.dnd,\n                        accept: opts.accept\n                    }),\n                    dnd;\n    \n                dnd = new Dnd( options );\n    \n                dnd.once( 'ready', deferred.resolve );\n                dnd.on( 'drop', function( files ) {\n                    me.request( 'add-file', [ files ]);\n                });\n    \n                // 检测文件是否全部允许添加。\n                dnd.on( 'accept', function( items ) {\n                    return me.owner.trigger( 'dndAccept', items );\n                });\n    \n                dnd.init();\n    \n                return deferred.promise();\n            }\n        });\n    });\n    \n    /**\n     * @fileOverview 错误信息\n     */\n    define('lib/filepaste',[\n        'base',\n        'mediator',\n        'runtime/client'\n    ], function( Base, Mediator, RuntimeClent ) {\n    \n        var $ = Base.$;\n    \n        function FilePaste( opts ) {\n            opts = this.options = $.extend({}, opts );\n            opts.container = $( opts.container || document.body );\n            RuntimeClent.call( this, 'FilePaste' );\n        }\n    \n        Base.inherits( RuntimeClent, {\n            constructor: FilePaste,\n    \n            init: function() {\n                var me = this;\n    \n                me.connectRuntime( me.options, function() {\n                    me.exec('init');\n                    me.trigger('ready');\n                });\n            },\n    \n            destroy: function() {\n                this.exec('destroy');\n                this.disconnectRuntime();\n                this.off();\n            }\n        });\n    \n        Mediator.installTo( FilePaste.prototype );\n    \n        return FilePaste;\n    });\n    /**\n     * @fileOverview 组件基类。\n     */\n    define('widgets/filepaste',[\n        'base',\n        'uploader',\n        'lib/filepaste',\n        'widgets/widget'\n    ], function( Base, Uploader, FilePaste ) {\n        var $ = Base.$;\n    \n        /**\n         * @property {Selector} [paste=undefined]  指定监听paste事件的容器，如果不指定，不启用此功能。此功能为通过粘贴来添加截屏的图片。建议设置为`document.body`.\n         * @namespace options\n         * @for Uploader\n         */\n        return Uploader.register({\n            init: function( opts ) {\n    \n                if ( !opts.paste ||\n                        this.request('predict-runtime-type') !== 'html5' ) {\n                    return;\n                }\n    \n                var me = this,\n                    deferred = Base.Deferred(),\n                    options = $.extend({}, {\n                        container: opts.paste,\n                        accept: opts.accept\n                    }),\n                    paste;\n    \n                paste = new FilePaste( options );\n    \n                paste.once( 'ready', deferred.resolve );\n                paste.on( 'paste', function( files ) {\n                    me.owner.request( 'add-file', [ files ]);\n                });\n                paste.init();\n    \n                return deferred.promise();\n            }\n        });\n    });\n    /**\n     * @fileOverview Blob\n     */\n    define('lib/blob',[\n        'base',\n        'runtime/client'\n    ], function( Base, RuntimeClient ) {\n    \n        function Blob( ruid, source ) {\n            var me = this;\n    \n            me.source = source;\n            me.ruid = ruid;\n    \n            RuntimeClient.call( me, 'Blob' );\n    \n            this.uid = source.uid || this.uid;\n            this.type = source.type || '';\n            this.size = source.size || 0;\n    \n            if ( ruid ) {\n                me.connectRuntime( ruid );\n            }\n        }\n    \n        Base.inherits( RuntimeClient, {\n            constructor: Blob,\n    \n            slice: function( start, end ) {\n                return this.exec( 'slice', start, end );\n            },\n    \n            getSource: function() {\n                return this.source;\n            }\n        });\n    \n        return Blob;\n    });\n    /**\n     * 为了统一化Flash的File和HTML5的File而存在。\n     * 以至于要调用Flash里面的File，也可以像调用HTML5版本的File一下。\n     * @fileOverview File\n     */\n    define('lib/file',[\n        'base',\n        'lib/blob'\n    ], function( Base, Blob ) {\n    \n        var uid = 1,\n            rExt = /\\.([^.]+)$/;\n    \n        function File( ruid, file ) {\n            var ext;\n    \n            Blob.apply( this, arguments );\n            this.name = file.name || ('untitled' + uid++);\n            ext = rExt.exec( file.name ) ? RegExp.$1.toLowerCase() : '';\n    \n            // todo 支持其他类型文件的转换。\n    \n            // 如果有mimetype, 但是文件名里面没有找出后缀规律\n            if ( !ext && this.type ) {\n                ext = /\\/(jpg|jpeg|png|gif|bmp)$/i.exec( this.type ) ?\n                        RegExp.$1.toLowerCase() : '';\n                this.name += '.' + ext;\n            }\n    \n            // 如果没有指定mimetype, 但是知道文件后缀。\n            if ( !this.type &&  ~'jpg,jpeg,png,gif,bmp'.indexOf( ext ) ) {\n                this.type = 'image/' + (ext === 'jpg' ? 'jpeg' : ext);\n            }\n    \n            this.ext = ext;\n            this.lastModifiedDate = file.lastModifiedDate ||\n                    (new Date()).toLocaleString();\n        }\n    \n        return Base.inherits( Blob, File );\n    });\n    \n    /**\n     * @fileOverview 错误信息\n     */\n    define('lib/filepicker',[\n        'base',\n        'runtime/client',\n        'lib/file'\n    ], function( Base, RuntimeClent, File ) {\n    \n        var $ = Base.$;\n    \n        function FilePicker( opts ) {\n            opts = this.options = $.extend({}, FilePicker.options, opts );\n    \n            opts.container = $( opts.id );\n    \n            if ( !opts.container.length ) {\n                throw new Error('按钮指定错误');\n            }\n    \n            opts.innerHTML = opts.innerHTML || opts.label ||\n                    opts.container.html() || '';\n    \n            opts.button = $( opts.button || document.createElement('div') );\n            opts.button.html( opts.innerHTML );\n            opts.container.html( opts.button );\n    \n            RuntimeClent.call( this, 'FilePicker', true );\n        }\n    \n        FilePicker.options = {\n            button: null,\n            container: null,\n            label: null,\n            innerHTML: null,\n            multiple: true,\n            accept: null,\n            name: 'file'\n        };\n    \n        Base.inherits( RuntimeClent, {\n            constructor: FilePicker,\n    \n            init: function() {\n                var me = this,\n                    opts = me.options,\n                    button = opts.button;\n    \n                button.addClass('webuploader-pick');\n    \n                me.on( 'all', function( type ) {\n                    var files;\n    \n                    switch ( type ) {\n                        case 'mouseenter':\n                            button.addClass('webuploader-pick-hover');\n                            break;\n    \n                        case 'mouseleave':\n                            button.removeClass('webuploader-pick-hover');\n                            break;\n    \n                        case 'change':\n                            files = me.exec('getFiles');\n                            me.trigger( 'select', $.map( files, function( file ) {\n                                file = new File( me.getRuid(), file );\n    \n                                // 记录来源。\n                                file._refer = opts.container;\n                                return file;\n                            }), opts.container );\n                            break;\n                    }\n                });\n    \n                me.connectRuntime( opts, function() {\n                    me.refresh();\n                    me.exec( 'init', opts );\n                    me.trigger('ready');\n                });\n    \n                $( window ).on( 'resize', function() {\n                    me.refresh();\n                });\n            },\n    \n            refresh: function() {\n                var shimContainer = this.getRuntime().getContainer(),\n                    button = this.options.button,\n                    width = button.outerWidth ?\n                            button.outerWidth() : button.width(),\n    \n                    height = button.outerHeight ?\n                            button.outerHeight() : button.height(),\n    \n                    pos = button.offset();\n    \n                width && height && shimContainer.css({\n                    bottom: 'auto',\n                    right: 'auto',\n                    width: width + 'px',\n                    height: height + 'px'\n                }).offset( pos );\n            },\n    \n            enable: function() {\n                var btn = this.options.button;\n    \n                btn.removeClass('webuploader-pick-disable');\n                this.refresh();\n            },\n    \n            disable: function() {\n                var btn = this.options.button;\n    \n                this.getRuntime().getContainer().css({\n                    top: '-99999px'\n                });\n    \n                btn.addClass('webuploader-pick-disable');\n            },\n    \n            destroy: function() {\n                if ( this.runtime ) {\n                    this.exec('destroy');\n                    this.disconnectRuntime();\n                }\n            }\n        });\n    \n        return FilePicker;\n    });\n    \n    /**\n     * @fileOverview 文件选择相关\n     */\n    define('widgets/filepicker',[\n        'base',\n        'uploader',\n        'lib/filepicker',\n        'widgets/widget'\n    ], function( Base, Uploader, FilePicker ) {\n        var $ = Base.$;\n    \n        $.extend( Uploader.options, {\n    \n            /**\n             * @property {Selector | Object} [pick=undefined]\n             * @namespace options\n             * @for Uploader\n             * @description 指定选择文件的按钮容器，不指定则不创建按钮。\n             *\n             * * `id` {Seletor} 指定选择文件的按钮容器，不指定则不创建按钮。\n             * * `label` {String} 请采用 `innerHTML` 代替\n             * * `innerHTML` {String} 指定按钮文字。不指定时优先从指定的容器中看是否自带文字。\n             * * `multiple` {Boolean} 是否开起同时选择多个文件能力。\n             */\n            pick: null,\n    \n            /**\n             * @property {Arroy} [accept=null]\n             * @namespace options\n             * @for Uploader\n             * @description 指定接受哪些类型的文件。 由于目前还有ext转mimeType表，所以这里需要分开指定。\n             *\n             * * `title` {String} 文字描述\n             * * `extensions` {String} 允许的文件后缀，不带点，多个用逗号分割。\n             * * `mimeTypes` {String} 多个用逗号分割。\n             *\n             * 如：\n             *\n             * ```\n             * {\n             *     title: 'Images',\n             *     extensions: 'gif,jpg,jpeg,bmp,png',\n             *     mimeTypes: 'image/*'\n             * }\n             * ```\n             */\n            accept: null/*{\n                title: 'Images',\n                extensions: 'gif,jpg,jpeg,bmp,png',\n                mimeTypes: 'image/*'\n            }*/\n        });\n    \n        return Uploader.register({\n            'add-btn': 'addButton',\n            refresh: 'refresh',\n            disable: 'disable',\n            enable: 'enable'\n        }, {\n    \n            init: function( opts ) {\n                this.pickers = [];\n                return opts.pick && this.addButton( opts.pick );\n            },\n    \n            refresh: function() {\n                $.each( this.pickers, function() {\n                    this.refresh();\n                });\n            },\n    \n            /**\n             * @method addButton\n             * @for Uploader\n             * @grammar addButton( pick ) => Promise\n             * @description\n             * 添加文件选择按钮，如果一个按钮不够，需要调用此方法来添加。参数跟[options.pick](#WebUploader:Uploader:options)一致。\n             * @example\n             * uploader.addButton({\n             *     id: '#btnContainer',\n             *     innerHTML: '选择文件'\n             * });\n             */\n            addButton: function( pick ) {\n                var me = this,\n                    opts = me.options,\n                    accept = opts.accept,\n                    options, picker, deferred;\n    \n                if ( !pick ) {\n                    return;\n                }\n    \n                deferred = Base.Deferred();\n                $.isPlainObject( pick ) || (pick = {\n                    id: pick\n                });\n    \n                options = $.extend({}, pick, {\n                    accept: $.isPlainObject( accept ) ? [ accept ] : accept,\n                    swf: opts.swf,\n                    runtimeOrder: opts.runtimeOrder\n                });\n    \n                picker = new FilePicker( options );\n    \n                picker.once( 'ready', deferred.resolve );\n                picker.on( 'select', function( files ) {\n                    me.owner.request( 'add-file', [ files ]);\n                });\n                picker.init();\n    \n                this.pickers.push( picker );\n    \n                return deferred.promise();\n            },\n    \n            disable: function() {\n                $.each( this.pickers, function() {\n                    this.disable();\n                });\n            },\n    \n            enable: function() {\n                $.each( this.pickers, function() {\n                    this.enable();\n                });\n            }\n        });\n    });\n    /**\n     * @fileOverview Image\n     */\n    define('lib/image',[\n        'base',\n        'runtime/client',\n        'lib/blob'\n    ], function( Base, RuntimeClient, Blob ) {\n        var $ = Base.$;\n    \n        // 构造器。\n        function Image( opts ) {\n            this.options = $.extend({}, Image.options, opts );\n            RuntimeClient.call( this, 'Image' );\n    \n            this.on( 'load', function() {\n                this._info = this.exec('info');\n                this._meta = this.exec('meta');\n            });\n        }\n    \n        // 默认选项。\n        Image.options = {\n    \n            // 默认的图片处理质量\n            quality: 90,\n    \n            // 是否裁剪\n            crop: false,\n    \n            // 是否保留头部信息\n            preserveHeaders: true,\n    \n            // 是否允许放大。\n            allowMagnify: true\n        };\n    \n        // 继承RuntimeClient.\n        Base.inherits( RuntimeClient, {\n            constructor: Image,\n    \n            info: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._info = val;\n                    return this;\n                }\n    \n                // getter\n                return this._info;\n            },\n    \n            meta: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._meta = val;\n                    return this;\n                }\n    \n                // getter\n                return this._meta;\n            },\n    \n            loadFromBlob: function( blob ) {\n                var me = this,\n                    ruid = blob.getRuid();\n    \n                this.connectRuntime( ruid, function() {\n                    me.exec( 'init', me.options );\n                    me.exec( 'loadFromBlob', blob );\n                });\n            },\n    \n            resize: function() {\n                var args = Base.slice( arguments );\n                return this.exec.apply( this, [ 'resize' ].concat( args ) );\n            },\n    \n            getAsDataUrl: function( type ) {\n                return this.exec( 'getAsDataUrl', type );\n            },\n    \n            getAsBlob: function( type ) {\n                var blob = this.exec( 'getAsBlob', type );\n    \n                return new Blob( this.getRuid(), blob );\n            }\n        });\n    \n        return Image;\n    });\n    /**\n     * @fileOverview 图片操作, 负责预览图片和上传前压缩图片\n     */\n    define('widgets/image',[\n        'base',\n        'uploader',\n        'lib/image',\n        'widgets/widget'\n    ], function( Base, Uploader, Image ) {\n    \n        var $ = Base.$,\n            throttle;\n    \n        // 根据要处理的文件大小来节流，一次不能处理太多，会卡。\n        throttle = (function( max ) {\n            var occupied = 0,\n                waiting = [],\n                tick = function() {\n                    var item;\n    \n                    while ( waiting.length && occupied < max ) {\n                        item = waiting.shift();\n                        occupied += item[ 0 ];\n                        item[ 1 ]();\n                    }\n                };\n    \n            return function( emiter, size, cb ) {\n                waiting.push([ size, cb ]);\n                emiter.once( 'destroy', function() {\n                    occupied -= size;\n                    setTimeout( tick, 1 );\n                });\n                setTimeout( tick, 1 );\n            };\n        })( 5 * 1024 * 1024 );\n    \n        $.extend( Uploader.options, {\n    \n            /**\n             * @property {Object} [thumb]\n             * @namespace options\n             * @for Uploader\n             * @description 配置生成缩略图的选项。\n             *\n             * 默认为：\n             *\n             * ```javascript\n             * {\n             *     width: 110,\n             *     height: 110,\n             *\n             *     // 图片质量，只有type为`image/jpeg`的时候才有效。\n             *     quality: 70,\n             *\n             *     // 是否允许放大，如果想要生成小图的时候不失真，此选项应该设置为false.\n             *     allowMagnify: true,\n             *\n             *     // 是否允许裁剪。\n             *     crop: true,\n             *\n             *     // 是否保留头部meta信息。\n             *     preserveHeaders: false,\n             *\n             *     // 为空的话则保留原有图片格式。\n             *     // 否则强制转换成指定的类型。\n             *     type: 'image/jpeg'\n             * }\n             * ```\n             */\n            thumb: {\n                width: 110,\n                height: 110,\n                quality: 70,\n                allowMagnify: true,\n                crop: true,\n                preserveHeaders: false,\n    \n                // 为空的话则保留原有图片格式。\n                // 否则强制转换成指定的类型。\n                // IE 8下面 base64 大小不能超过 32K 否则预览失败，而非 jpeg 编码的图片很可\n                // 能会超过 32k, 所以这里设置成预览的时候都是 image/jpeg\n                type: 'image/jpeg'\n            },\n    \n            /**\n             * @property {Object} [compress]\n             * @namespace options\n             * @for Uploader\n             * @description 配置压缩的图片的选项。如果此选项为`false`, 则图片在上传前不进行压缩。\n             *\n             * 默认为：\n             *\n             * ```javascript\n             * {\n             *     width: 1600,\n             *     height: 1600,\n             *\n             *     // 图片质量，只有type为`image/jpeg`的时候才有效。\n             *     quality: 90,\n             *\n             *     // 是否允许放大，如果想要生成小图的时候不失真，此选项应该设置为false.\n             *     allowMagnify: false,\n             *\n             *     // 是否允许裁剪。\n             *     crop: false,\n             *\n             *     // 是否保留头部meta信息。\n             *     preserveHeaders: true\n             * }\n             * ```\n             */\n            compress: {\n                width: 1600,\n                height: 1600,\n                quality: 90,\n                allowMagnify: false,\n                crop: false,\n                preserveHeaders: true\n            }\n        });\n    \n        return Uploader.register({\n            'make-thumb': 'makeThumb',\n            'before-send-file': 'compressImage'\n        }, {\n    \n    \n            /**\n             * 生成缩略图，此过程为异步，所以需要传入`callback`。\n             * 通常情况在图片加入队里后调用此方法来生成预览图以增强交互效果。\n             *\n             * `callback`中可以接收到两个参数。\n             * * 第一个为error，如果生成缩略图有错误，此error将为真。\n             * * 第二个为ret, 缩略图的Data URL值。\n             *\n             * **注意**\n             * Date URL在IE6/7中不支持，所以不用调用此方法了，直接显示一张暂不支持预览图片好了。\n             *\n             *\n             * @method makeThumb\n             * @grammar makeThumb( file, callback ) => undefined\n             * @grammar makeThumb( file, callback, width, height ) => undefined\n             * @for Uploader\n             * @example\n             *\n             * uploader.on( 'fileQueued', function( file ) {\n             *     var $li = ...;\n             *\n             *     uploader.makeThumb( file, function( error, ret ) {\n             *         if ( error ) {\n             *             $li.text('预览错误');\n             *         } else {\n             *             $li.append('<img alt=\"\" src=\"' + ret + '\" />');\n             *         }\n             *     });\n             *\n             * });\n             */\n            makeThumb: function( file, cb, width, height ) {\n                var opts, image;\n    \n                file = this.request( 'get-file', file );\n    \n                // 只预览图片格式。\n                if ( !file.type.match( /^image/ ) ) {\n                    cb( true );\n                    return;\n                }\n    \n                opts = $.extend({}, this.options.thumb );\n    \n                // 如果传入的是object.\n                if ( $.isPlainObject( width ) ) {\n                    opts = $.extend( opts, width );\n                    width = null;\n                }\n    \n                width = width || opts.width;\n                height = height || opts.height;\n    \n                image = new Image( opts );\n    \n                image.once( 'load', function() {\n                    file._info = file._info || image.info();\n                    file._meta = file._meta || image.meta();\n                    image.resize( width, height );\n                });\n    \n                image.once( 'complete', function() {\n                    cb( false, image.getAsDataUrl( opts.type ) );\n                    image.destroy();\n                });\n    \n                image.once( 'error', function() {\n                    cb( true );\n                    image.destroy();\n                });\n    \n                throttle( image, file.source.size, function() {\n                    file._info && image.info( file._info );\n                    file._meta && image.meta( file._meta );\n                    image.loadFromBlob( file.source );\n                });\n            },\n    \n            compressImage: function( file ) {\n                var opts = this.options.compress || this.options.resize,\n                    compressSize = opts && opts.compressSize || 300 * 1024,\n                    image, deferred;\n    \n                file = this.request( 'get-file', file );\n    \n                // 只预览图片格式。\n                if ( !opts || !~'image/jpeg,image/jpg'.indexOf( file.type ) ||\n                        file.size < compressSize ||\n                        file._compressed ) {\n                    return;\n                }\n    \n                opts = $.extend({}, opts );\n                deferred = Base.Deferred();\n    \n                image = new Image( opts );\n    \n                deferred.always(function() {\n                    image.destroy();\n                    image = null;\n                });\n                image.once( 'error', deferred.reject );\n                image.once( 'load', function() {\n                    file._info = file._info || image.info();\n                    file._meta = file._meta || image.meta();\n                    image.resize( opts.width, opts.height );\n                });\n    \n                image.once( 'complete', function() {\n                    var blob, size;\n    \n                    // 移动端 UC / qq 浏览器的无图模式下\n                    // ctx.getImageData 处理大图的时候会报 Exception\n                    // INDEX_SIZE_ERR: DOM Exception 1\n                    try {\n                        blob = image.getAsBlob( opts.type );\n    \n                        size = file.size;\n    \n                        // 如果压缩后，比原来还大则不用压缩后的。\n                        if ( blob.size < size ) {\n                            // file.source.destroy && file.source.destroy();\n                            file.source = blob;\n                            file.size = blob.size;\n    \n                            file.trigger( 'resize', blob.size, size );\n                        }\n    \n                        // 标记，避免重复压缩。\n                        file._compressed = true;\n                        deferred.resolve();\n                    } catch ( e ) {\n                        // 出错了直接继续，让其上传原始图片\n                        deferred.resolve();\n                    }\n                });\n    \n                file._info && image.info( file._info );\n                file._meta && image.meta( file._meta );\n    \n                image.loadFromBlob( file.source );\n                return deferred.promise();\n            }\n        });\n    });\n    /**\n     * @fileOverview 文件属性封装\n     */\n    define('file',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$,\n            idPrefix = 'WU_FILE_',\n            idSuffix = 0,\n            rExt = /\\.([^.]+)$/,\n            statusMap = {};\n    \n        function gid() {\n            return idPrefix + idSuffix++;\n        }\n    \n        /**\n         * 文件类\n         * @class File\n         * @constructor 构造函数\n         * @grammar new File( source ) => File\n         * @param {Lib.File} source [lib.File](#Lib.File)实例, 此source对象是带有Runtime信息的。\n         */\n        function WUFile( source ) {\n    \n            /**\n             * 文件名，包括扩展名（后缀）\n             * @property name\n             * @type {string}\n             */\n            this.name = source.name || 'Untitled';\n    \n            /**\n             * 文件体积（字节）\n             * @property size\n             * @type {uint}\n             * @default 0\n             */\n            this.size = source.size || 0;\n    \n            /**\n             * 文件MIMETYPE类型，与文件类型的对应关系请参考[http://t.cn/z8ZnFny](http://t.cn/z8ZnFny)\n             * @property type\n             * @type {string}\n             * @default 'application'\n             */\n            this.type = source.type || 'application';\n    \n            /**\n             * 文件最后修改日期\n             * @property lastModifiedDate\n             * @type {int}\n             * @default 当前时间戳\n             */\n            this.lastModifiedDate = source.lastModifiedDate || (new Date() * 1);\n    \n            /**\n             * 文件ID，每个对象具有唯一ID，与文件名无关\n             * @property id\n             * @type {string}\n             */\n            this.id = gid();\n    \n            /**\n             * 文件扩展名，通过文件名获取，例如test.png的扩展名为png\n             * @property ext\n             * @type {string}\n             */\n            this.ext = rExt.exec( this.name ) ? RegExp.$1 : '';\n    \n    \n            /**\n             * 状态文字说明。在不同的status语境下有不同的用途。\n             * @property statusText\n             * @type {string}\n             */\n            this.statusText = '';\n    \n            // 存储文件状态，防止通过属性直接修改\n            statusMap[ this.id ] = WUFile.Status.INITED;\n    \n            this.source = source;\n            this.loaded = 0;\n    \n            this.on( 'error', function( msg ) {\n                this.setStatus( WUFile.Status.ERROR, msg );\n            });\n        }\n    \n        $.extend( WUFile.prototype, {\n    \n            /**\n             * 设置状态，状态变化时会触发`change`事件。\n             * @method setStatus\n             * @grammar setStatus( status[, statusText] );\n             * @param {File.Status|String} status [文件状态值](#WebUploader:File:File.Status)\n             * @param {String} [statusText=''] 状态说明，常在error时使用，用http, abort,server等来标记是由于什么原因导致文件错误。\n             */\n            setStatus: function( status, text ) {\n    \n                var prevStatus = statusMap[ this.id ];\n    \n                typeof text !== 'undefined' && (this.statusText = text);\n    \n                if ( status !== prevStatus ) {\n                    statusMap[ this.id ] = status;\n                    /**\n                     * 文件状态变化\n                     * @event statuschange\n                     */\n                    this.trigger( 'statuschange', status, prevStatus );\n                }\n    \n            },\n    \n            /**\n             * 获取文件状态\n             * @return {File.Status}\n             * @example\n                     文件状态具体包括以下几种类型：\n                     {\n                         // 初始化\n                        INITED:     0,\n                        // 已入队列\n                        QUEUED:     1,\n                        // 正在上传\n                        PROGRESS:     2,\n                        // 上传出错\n                        ERROR:         3,\n                        // 上传成功\n                        COMPLETE:     4,\n                        // 上传取消\n                        CANCELLED:     5\n                    }\n             */\n            getStatus: function() {\n                return statusMap[ this.id ];\n            },\n    \n            /**\n             * 获取文件原始信息。\n             * @return {*}\n             */\n            getSource: function() {\n                return this.source;\n            },\n    \n            destory: function() {\n                delete statusMap[ this.id ];\n            }\n        });\n    \n        Mediator.installTo( WUFile.prototype );\n    \n        /**\n         * 文件状态值，具体包括以下几种类型：\n         * * `inited` 初始状态\n         * * `queued` 已经进入队列, 等待上传\n         * * `progress` 上传中\n         * * `complete` 上传完成。\n         * * `error` 上传出错，可重试\n         * * `interrupt` 上传中断，可续传。\n         * * `invalid` 文件不合格，不能重试上传。会自动从队列中移除。\n         * * `cancelled` 文件被移除。\n         * @property {Object} Status\n         * @namespace File\n         * @class File\n         * @static\n         */\n        WUFile.Status = {\n            INITED:     'inited',    // 初始状态\n            QUEUED:     'queued',    // 已经进入队列, 等待上传\n            PROGRESS:   'progress',    // 上传中\n            ERROR:      'error',    // 上传出错，可重试\n            COMPLETE:   'complete',    // 上传完成。\n            CANCELLED:  'cancelled',    // 上传取消。\n            INTERRUPT:  'interrupt',    // 上传中断，可续传。\n            INVALID:    'invalid'    // 文件不合格，不能重试上传。\n        };\n    \n        return WUFile;\n    });\n    \n    /**\n     * @fileOverview 文件队列\n     */\n    define('queue',[\n        'base',\n        'mediator',\n        'file'\n    ], function( Base, Mediator, WUFile ) {\n    \n        var $ = Base.$,\n            STATUS = WUFile.Status;\n    \n        /**\n         * 文件队列, 用来存储各个状态中的文件。\n         * @class Queue\n         * @extends Mediator\n         */\n        function Queue() {\n    \n            /**\n             * 统计文件数。\n             * * `numOfQueue` 队列中的文件数。\n             * * `numOfSuccess` 上传成功的文件数\n             * * `numOfCancel` 被移除的文件数\n             * * `numOfProgress` 正在上传中的文件数\n             * * `numOfUploadFailed` 上传错误的文件数。\n             * * `numOfInvalid` 无效的文件数。\n             * @property {Object} stats\n             */\n            this.stats = {\n                numOfQueue: 0,\n                numOfSuccess: 0,\n                numOfCancel: 0,\n                numOfProgress: 0,\n                numOfUploadFailed: 0,\n                numOfInvalid: 0\n            };\n    \n            // 上传队列，仅包括等待上传的文件\n            this._queue = [];\n    \n            // 存储所有文件\n            this._map = {};\n        }\n    \n        $.extend( Queue.prototype, {\n    \n            /**\n             * 将新文件加入对队列尾部\n             *\n             * @method append\n             * @param  {File} file   文件对象\n             */\n            append: function( file ) {\n                this._queue.push( file );\n                this._fileAdded( file );\n                return this;\n            },\n    \n            /**\n             * 将新文件加入对队列头部\n             *\n             * @method prepend\n             * @param  {File} file   文件对象\n             */\n            prepend: function( file ) {\n                this._queue.unshift( file );\n                this._fileAdded( file );\n                return this;\n            },\n    \n            /**\n             * 获取文件对象\n             *\n             * @method getFile\n             * @param  {String} fileId   文件ID\n             * @return {File}\n             */\n            getFile: function( fileId ) {\n                if ( typeof fileId !== 'string' ) {\n                    return fileId;\n                }\n                return this._map[ fileId ];\n            },\n    \n            /**\n             * 从队列中取出一个指定状态的文件。\n             * @grammar fetch( status ) => File\n             * @method fetch\n             * @param {String} status [文件状态值](#WebUploader:File:File.Status)\n             * @return {File} [File](#WebUploader:File)\n             */\n            fetch: function( status ) {\n                var len = this._queue.length,\n                    i, file;\n    \n                status = status || STATUS.QUEUED;\n    \n                for ( i = 0; i < len; i++ ) {\n                    file = this._queue[ i ];\n    \n                    if ( status === file.getStatus() ) {\n                        return file;\n                    }\n                }\n    \n                return null;\n            },\n    \n            /**\n             * 对队列进行排序，能够控制文件上传顺序。\n             * @grammar sort( fn ) => undefined\n             * @method sort\n             * @param {Function} fn 排序方法\n             */\n            sort: function( fn ) {\n                if ( typeof fn === 'function' ) {\n                    this._queue.sort( fn );\n                }\n            },\n    \n            /**\n             * 获取指定类型的文件列表, 列表中每一个成员为[File](#WebUploader:File)对象。\n             * @grammar getFiles( [status1[, status2 ...]] ) => Array\n             * @method getFiles\n             * @param {String} [status] [文件状态值](#WebUploader:File:File.Status)\n             */\n            getFiles: function() {\n                var sts = [].slice.call( arguments, 0 ),\n                    ret = [],\n                    i = 0,\n                    len = this._queue.length,\n                    file;\n    \n                for ( ; i < len; i++ ) {\n                    file = this._queue[ i ];\n    \n                    if ( sts.length && !~$.inArray( file.getStatus(), sts ) ) {\n                        continue;\n                    }\n    \n                    ret.push( file );\n                }\n    \n                return ret;\n            },\n    \n            _fileAdded: function( file ) {\n                var me = this,\n                    existing = this._map[ file.id ];\n    \n                if ( !existing ) {\n                    this._map[ file.id ] = file;\n    \n                    file.on( 'statuschange', function( cur, pre ) {\n                        me._onFileStatusChange( cur, pre );\n                    });\n                }\n    \n                file.setStatus( STATUS.QUEUED );\n            },\n    \n            _onFileStatusChange: function( curStatus, preStatus ) {\n                var stats = this.stats;\n    \n                switch ( preStatus ) {\n                    case STATUS.PROGRESS:\n                        stats.numOfProgress--;\n                        break;\n    \n                    case STATUS.QUEUED:\n                        stats.numOfQueue --;\n                        break;\n    \n                    case STATUS.ERROR:\n                        stats.numOfUploadFailed--;\n                        break;\n    \n                    case STATUS.INVALID:\n                        stats.numOfInvalid--;\n                        break;\n                }\n    \n                switch ( curStatus ) {\n                    case STATUS.QUEUED:\n                        stats.numOfQueue++;\n                        break;\n    \n                    case STATUS.PROGRESS:\n                        stats.numOfProgress++;\n                        break;\n    \n                    case STATUS.ERROR:\n                        stats.numOfUploadFailed++;\n                        break;\n    \n                    case STATUS.COMPLETE:\n                        stats.numOfSuccess++;\n                        break;\n    \n                    case STATUS.CANCELLED:\n                        stats.numOfCancel++;\n                        break;\n    \n                    case STATUS.INVALID:\n                        stats.numOfInvalid++;\n                        break;\n                }\n            }\n    \n        });\n    \n        Mediator.installTo( Queue.prototype );\n    \n        return Queue;\n    });\n    /**\n     * @fileOverview 队列\n     */\n    define('widgets/queue',[\n        'base',\n        'uploader',\n        'queue',\n        'file',\n        'lib/file',\n        'runtime/client',\n        'widgets/widget'\n    ], function( Base, Uploader, Queue, WUFile, File, RuntimeClient ) {\n    \n        var $ = Base.$,\n            rExt = /\\.\\w+$/,\n            Status = WUFile.Status;\n    \n        return Uploader.register({\n            'sort-files': 'sortFiles',\n            'add-file': 'addFiles',\n            'get-file': 'getFile',\n            'fetch-file': 'fetchFile',\n            'get-stats': 'getStats',\n            'get-files': 'getFiles',\n            'remove-file': 'removeFile',\n            'retry': 'retry',\n            'reset': 'reset',\n            'accept-file': 'acceptFile'\n        }, {\n    \n            init: function( opts ) {\n                var me = this,\n                    deferred, len, i, item, arr, accept, runtime;\n    \n                if ( $.isPlainObject( opts.accept ) ) {\n                    opts.accept = [ opts.accept ];\n                }\n    \n                // accept中的中生成匹配正则。\n                if ( opts.accept ) {\n                    arr = [];\n    \n                    for ( i = 0, len = opts.accept.length; i < len; i++ ) {\n                        item = opts.accept[ i ].extensions;\n                        item && arr.push( item );\n                    }\n    \n                    if ( arr.length ) {\n                        accept = '\\\\.' + arr.join(',')\n                                .replace( /,/g, '$|\\\\.' )\n                                .replace( /\\*/g, '.*' ) + '$';\n                    }\n    \n                    me.accept = new RegExp( accept, 'i' );\n                }\n    \n                me.queue = new Queue();\n                me.stats = me.queue.stats;\n    \n                // 如果当前不是html5运行时，那就算了。\n                // 不执行后续操作\n                if ( this.request('predict-runtime-type') !== 'html5' ) {\n                    return;\n                }\n    \n                // 创建一个 html5 运行时的 placeholder\n                // 以至于外部添加原生 File 对象的时候能正确包裹一下供 webuploader 使用。\n                deferred = Base.Deferred();\n                runtime = new RuntimeClient('Placeholder');\n                runtime.connectRuntime({\n                    runtimeOrder: 'html5'\n                }, function() {\n                    me._ruid = runtime.getRuid();\n                    deferred.resolve();\n                });\n                return deferred.promise();\n            },\n    \n    \n            // 为了支持外部直接添加一个原生File对象。\n            _wrapFile: function( file ) {\n                if ( !(file instanceof WUFile) ) {\n    \n                    if ( !(file instanceof File) ) {\n                        if ( !this._ruid ) {\n                            throw new Error('Can\\'t add external files.');\n                        }\n                        file = new File( this._ruid, file );\n                    }\n    \n                    file = new WUFile( file );\n                }\n    \n                return file;\n            },\n    \n            // 判断文件是否可以被加入队列\n            acceptFile: function( file ) {\n                var invalid = !file || file.size < 6 || this.accept &&\n    \n                        // 如果名字中有后缀，才做后缀白名单处理。\n                        rExt.exec( file.name ) && !this.accept.test( file.name );\n    \n                return !invalid;\n            },\n    \n    \n            /**\n             * @event beforeFileQueued\n             * @param {File} file File对象\n             * @description 当文件被加入队列之前触发，此事件的handler返回值为`false`，则此文件不会被添加进入队列。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event fileQueued\n             * @param {File} file File对象\n             * @description 当文件被加入队列以后触发。\n             * @for  Uploader\n             */\n    \n            _addFile: function( file ) {\n                var me = this;\n    \n                file = me._wrapFile( file );\n    \n                // 不过类型判断允许不允许，先派送 `beforeFileQueued`\n                if ( !me.owner.trigger( 'beforeFileQueued', file ) ) {\n                    return;\n                }\n    \n                // 类型不匹配，则派送错误事件，并返回。\n                if ( !me.acceptFile( file ) ) {\n                    me.owner.trigger( 'error', 'Q_TYPE_DENIED', file );\n                    return;\n                }\n    \n                me.queue.append( file );\n                me.owner.trigger( 'fileQueued', file );\n                return file;\n            },\n    \n            getFile: function( fileId ) {\n                return this.queue.getFile( fileId );\n            },\n    \n            /**\n             * @event filesQueued\n             * @param {File} files 数组，内容为原始File(lib/File）对象。\n             * @description 当一批文件添加进队列以后触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @method addFiles\n             * @grammar addFiles( file ) => undefined\n             * @grammar addFiles( [file1, file2 ...] ) => undefined\n             * @param {Array of File or File} [files] Files 对象 数组\n             * @description 添加文件到队列\n             * @for  Uploader\n             */\n            addFiles: function( files ) {\n                var me = this;\n    \n                if ( !files.length ) {\n                    files = [ files ];\n                }\n    \n                files = $.map( files, function( file ) {\n                    return me._addFile( file );\n                });\n    \n                me.owner.trigger( 'filesQueued', files );\n    \n                if ( me.options.auto ) {\n                    me.request('start-upload');\n                }\n            },\n    \n            getStats: function() {\n                return this.stats;\n            },\n    \n            /**\n             * @event fileDequeued\n             * @param {File} file File对象\n             * @description 当文件被移除队列后触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @method removeFile\n             * @grammar removeFile( file ) => undefined\n             * @grammar removeFile( id ) => undefined\n             * @param {File|id} file File对象或这File对象的id\n             * @description 移除某一文件。\n             * @for  Uploader\n             * @example\n             *\n             * $li.on('click', '.remove-this', function() {\n             *     uploader.removeFile( file );\n             * })\n             */\n            removeFile: function( file ) {\n                var me = this;\n    \n                file = file.id ? file : me.queue.getFile( file );\n    \n                file.setStatus( Status.CANCELLED );\n                me.owner.trigger( 'fileDequeued', file );\n            },\n    \n            /**\n             * @method getFiles\n             * @grammar getFiles() => Array\n             * @grammar getFiles( status1, status2, status... ) => Array\n             * @description 返回指定状态的文件集合，不传参数将返回所有状态的文件。\n             * @for  Uploader\n             * @example\n             * console.log( uploader.getFiles() );    // => all files\n             * console.log( uploader.getFiles('error') )    // => all error files.\n             */\n            getFiles: function() {\n                return this.queue.getFiles.apply( this.queue, arguments );\n            },\n    \n            fetchFile: function() {\n                return this.queue.fetch.apply( this.queue, arguments );\n            },\n    \n            /**\n             * @method retry\n             * @grammar retry() => undefined\n             * @grammar retry( file ) => undefined\n             * @description 重试上传，重试指定文件，或者从出错的文件开始重新上传。\n             * @for  Uploader\n             * @example\n             * function retry() {\n             *     uploader.retry();\n             * }\n             */\n            retry: function( file, noForceStart ) {\n                var me = this,\n                    files, i, len;\n    \n                if ( file ) {\n                    file = file.id ? file : me.queue.getFile( file );\n                    file.setStatus( Status.QUEUED );\n                    noForceStart || me.request('start-upload');\n                    return;\n                }\n    \n                files = me.queue.getFiles( Status.ERROR );\n                i = 0;\n                len = files.length;\n    \n                for ( ; i < len; i++ ) {\n                    file = files[ i ];\n                    file.setStatus( Status.QUEUED );\n                }\n    \n                me.request('start-upload');\n            },\n    \n            /**\n             * @method sort\n             * @grammar sort( fn ) => undefined\n             * @description 排序队列中的文件，在上传之前调整可以控制上传顺序。\n             * @for  Uploader\n             */\n            sortFiles: function() {\n                return this.queue.sort.apply( this.queue, arguments );\n            },\n    \n            /**\n             * @method reset\n             * @grammar reset() => undefined\n             * @description 重置uploader。目前只重置了队列。\n             * @for  Uploader\n             * @example\n             * uploader.reset();\n             */\n            reset: function() {\n                this.queue = new Queue();\n                this.stats = this.queue.stats;\n            }\n        });\n    \n    });\n    /**\n     * @fileOverview 添加获取Runtime相关信息的方法。\n     */\n    define('widgets/runtime',[\n        'uploader',\n        'runtime/runtime',\n        'widgets/widget'\n    ], function( Uploader, Runtime ) {\n    \n        Uploader.support = function() {\n            return Runtime.hasRuntime.apply( Runtime, arguments );\n        };\n    \n        return Uploader.register({\n            'predict-runtime-type': 'predictRuntmeType'\n        }, {\n    \n            init: function() {\n                if ( !this.predictRuntmeType() ) {\n                    throw Error('Runtime Error');\n                }\n            },\n    \n            /**\n             * 预测Uploader将采用哪个`Runtime`\n             * @grammar predictRuntmeType() => String\n             * @method predictRuntmeType\n             * @for  Uploader\n             */\n            predictRuntmeType: function() {\n                var orders = this.options.runtimeOrder || Runtime.orders,\n                    type = this.type,\n                    i, len;\n    \n                if ( !type ) {\n                    orders = orders.split( /\\s*,\\s*/g );\n    \n                    for ( i = 0, len = orders.length; i < len; i++ ) {\n                        if ( Runtime.hasRuntime( orders[ i ] ) ) {\n                            this.type = type = orders[ i ];\n                            break;\n                        }\n                    }\n                }\n    \n                return type;\n            }\n        });\n    });\n    /**\n     * @fileOverview Transport\n     */\n    define('lib/transport',[\n        'base',\n        'runtime/client',\n        'mediator'\n    ], function( Base, RuntimeClient, Mediator ) {\n    \n        var $ = Base.$;\n    \n        function Transport( opts ) {\n            var me = this;\n    \n            opts = me.options = $.extend( true, {}, Transport.options, opts || {} );\n            RuntimeClient.call( this, 'Transport' );\n    \n            this._blob = null;\n            this._formData = opts.formData || {};\n            this._headers = opts.headers || {};\n    \n            this.on( 'progress', this._timeout );\n            this.on( 'load error', function() {\n                me.trigger( 'progress', 1 );\n                clearTimeout( me._timer );\n            });\n        }\n    \n        Transport.options = {\n            server: '',\n            method: 'POST',\n    \n            // 跨域时，是否允许携带cookie, 只有html5 runtime才有效\n            withCredentials: false,\n            fileVal: 'file',\n            timeout: 2 * 60 * 1000,    // 2分钟\n            formData: {},\n            headers: {},\n            sendAsBinary: false\n        };\n    \n        $.extend( Transport.prototype, {\n    \n            // 添加Blob, 只能添加一次，最后一次有效。\n            appendBlob: function( key, blob, filename ) {\n                var me = this,\n                    opts = me.options;\n    \n                if ( me.getRuid() ) {\n                    me.disconnectRuntime();\n                }\n    \n                // 连接到blob归属的同一个runtime.\n                me.connectRuntime( blob.ruid, function() {\n                    me.exec('init');\n                });\n    \n                me._blob = blob;\n                opts.fileVal = key || opts.fileVal;\n                opts.filename = filename || opts.filename;\n            },\n    \n            // 添加其他字段\n            append: function( key, value ) {\n                if ( typeof key === 'object' ) {\n                    $.extend( this._formData, key );\n                } else {\n                    this._formData[ key ] = value;\n                }\n            },\n    \n            setRequestHeader: function( key, value ) {\n                if ( typeof key === 'object' ) {\n                    $.extend( this._headers, key );\n                } else {\n                    this._headers[ key ] = value;\n                }\n            },\n    \n            send: function( method ) {\n                this.exec( 'send', method );\n                this._timeout();\n            },\n    \n            abort: function() {\n                clearTimeout( this._timer );\n                return this.exec('abort');\n            },\n    \n            destroy: function() {\n                this.trigger('destroy');\n                this.off();\n                this.exec('destroy');\n                this.disconnectRuntime();\n            },\n    \n            getResponse: function() {\n                return this.exec('getResponse');\n            },\n    \n            getResponseAsJson: function() {\n                return this.exec('getResponseAsJson');\n            },\n    \n            getStatus: function() {\n                return this.exec('getStatus');\n            },\n    \n            _timeout: function() {\n                var me = this,\n                    duration = me.options.timeout;\n    \n                if ( !duration ) {\n                    return;\n                }\n    \n                clearTimeout( me._timer );\n                me._timer = setTimeout(function() {\n                    me.abort();\n                    me.trigger( 'error', 'timeout' );\n                }, duration );\n            }\n    \n        });\n    \n        // 让Transport具备事件功能。\n        Mediator.installTo( Transport.prototype );\n    \n        return Transport;\n    });\n    /**\n     * @fileOverview 负责文件上传相关。\n     */\n    define('widgets/upload',[\n        'base',\n        'uploader',\n        'file',\n        'lib/transport',\n        'widgets/widget'\n    ], function( Base, Uploader, WUFile, Transport ) {\n    \n        var $ = Base.$,\n            isPromise = Base.isPromise,\n            Status = WUFile.Status;\n    \n        // 添加默认配置项\n        $.extend( Uploader.options, {\n    \n    \n            /**\n             * @property {Boolean} [prepareNextFile=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否允许在文件传输时提前把下一个文件准备好。\n             * 对于一个文件的准备工作比较耗时，比如图片压缩，md5序列化。\n             * 如果能提前在当前文件传输期处理，可以节省总体耗时。\n             */\n            prepareNextFile: false,\n    \n            /**\n             * @property {Boolean} [chunked=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否要分片处理大文件上传。\n             */\n            chunked: false,\n    \n            /**\n             * @property {Boolean} [chunkSize=5242880]\n             * @namespace options\n             * @for Uploader\n             * @description 如果要分片，分多大一片？ 默认大小为5M.\n             */\n            chunkSize: 5 * 1024 * 1024,\n    \n            /**\n             * @property {Boolean} [chunkRetry=2]\n             * @namespace options\n             * @for Uploader\n             * @description 如果某个分片由于网络问题出错，允许自动重传多少次？\n             */\n            chunkRetry: 2,\n    \n            /**\n             * @property {Boolean} [threads=3]\n             * @namespace options\n             * @for Uploader\n             * @description 上传并发数。允许同时最大上传进程数。\n             */\n            threads: 3,\n    \n    \n            /**\n             * @property {Object} [formData]\n             * @namespace options\n             * @for Uploader\n             * @description 文件上传请求的参数表，每次发送都会发送此对象中的参数。\n             */\n            formData: null\n    \n            /**\n             * @property {Object} [fileVal='file']\n             * @namespace options\n             * @for Uploader\n             * @description 设置文件上传域的name。\n             */\n    \n            /**\n             * @property {Object} [method='POST']\n             * @namespace options\n             * @for Uploader\n             * @description 文件上传方式，`POST`或者`GET`。\n             */\n    \n            /**\n             * @property {Object} [sendAsBinary=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否已二进制的流的方式发送文件，这样整个上传内容`php://input`都为文件内容，\n             * 其他参数在$_GET数组中。\n             */\n        });\n    \n        // 负责将文件切片。\n        function CuteFile( file, chunkSize ) {\n            var pending = [],\n                blob = file.source,\n                total = blob.size,\n                chunks = chunkSize ? Math.ceil( total / chunkSize ) : 1,\n                start = 0,\n                index = 0,\n                len;\n    \n            while ( index < chunks ) {\n                len = Math.min( chunkSize, total - start );\n    \n                pending.push({\n                    file: file,\n                    start: start,\n                    end: chunkSize ? (start + len) : total,\n                    total: total,\n                    chunks: chunks,\n                    chunk: index++\n                });\n                start += len;\n            }\n    \n            file.blocks = pending.concat();\n            file.remaning = pending.length;\n    \n            return {\n                file: file,\n    \n                has: function() {\n                    return !!pending.length;\n                },\n    \n                fetch: function() {\n                    return pending.shift();\n                }\n            };\n        }\n    \n        Uploader.register({\n            'start-upload': 'start',\n            'stop-upload': 'stop',\n            'skip-file': 'skipFile',\n            'is-in-progress': 'isInProgress'\n        }, {\n    \n            init: function() {\n                var owner = this.owner;\n    \n                this.runing = false;\n    \n                // 记录当前正在传的数据，跟threads相关\n                this.pool = [];\n    \n                // 缓存即将上传的文件。\n                this.pending = [];\n    \n                // 跟踪还有多少分片没有完成上传。\n                this.remaning = 0;\n                this.__tick = Base.bindFn( this._tick, this );\n    \n                owner.on( 'uploadComplete', function( file ) {\n                    // 把其他块取消了。\n                    file.blocks && $.each( file.blocks, function( _, v ) {\n                        v.transport && (v.transport.abort(), v.transport.destroy());\n                        delete v.transport;\n                    });\n    \n                    delete file.blocks;\n                    delete file.remaning;\n                });\n            },\n    \n            /**\n             * @event startUpload\n             * @description 当开始上传流程时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * 开始上传。此方法可以从初始状态调用开始上传流程，也可以从暂停状态调用，继续上传流程。\n             * @grammar upload() => undefined\n             * @method upload\n             * @for  Uploader\n             */\n            start: function() {\n                var me = this;\n    \n                // 移出invalid的文件\n                $.each( me.request( 'get-files', Status.INVALID ), function() {\n                    me.request( 'remove-file', this );\n                });\n    \n                if ( me.runing ) {\n                    return;\n                }\n    \n                me.runing = true;\n    \n                // 如果有暂停的，则续传\n                $.each( me.pool, function( _, v ) {\n                    var file = v.file;\n    \n                    if ( file.getStatus() === Status.INTERRUPT ) {\n                        file.setStatus( Status.PROGRESS );\n                        me._trigged = false;\n                        v.transport && v.transport.send();\n                    }\n                });\n    \n                me._trigged = false;\n                me.owner.trigger('startUpload');\n                Base.nextTick( me.__tick );\n            },\n    \n            /**\n             * @event stopUpload\n             * @description 当开始上传流程暂停时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * 暂停上传。第一个参数为是否中断上传当前正在上传的文件。\n             * @grammar stop() => undefined\n             * @grammar stop( true ) => undefined\n             * @method stop\n             * @for  Uploader\n             */\n            stop: function( interrupt ) {\n                var me = this;\n    \n                if ( me.runing === false ) {\n                    return;\n                }\n    \n                me.runing = false;\n    \n                interrupt && $.each( me.pool, function( _, v ) {\n                    v.transport && v.transport.abort();\n                    v.file.setStatus( Status.INTERRUPT );\n                });\n    \n                me.owner.trigger('stopUpload');\n            },\n    \n            /**\n             * 判断`Uplaode`r是否正在上传中。\n             * @grammar isInProgress() => Boolean\n             * @method isInProgress\n             * @for  Uploader\n             */\n            isInProgress: function() {\n                return !!this.runing;\n            },\n    \n            getStats: function() {\n                return this.request('get-stats');\n            },\n    \n            /**\n             * 掉过一个文件上传，直接标记指定文件为已上传状态。\n             * @grammar skipFile( file ) => undefined\n             * @method skipFile\n             * @for  Uploader\n             */\n            skipFile: function( file, status ) {\n                file = this.request( 'get-file', file );\n    \n                file.setStatus( status || Status.COMPLETE );\n                file.skipped = true;\n    \n                // 如果正在上传。\n                file.blocks && $.each( file.blocks, function( _, v ) {\n                    var _tr = v.transport;\n    \n                    if ( _tr ) {\n                        _tr.abort();\n                        _tr.destroy();\n                        delete v.transport;\n                    }\n                });\n    \n                this.owner.trigger( 'uploadSkip', file );\n            },\n    \n            /**\n             * @event uploadFinished\n             * @description 当所有文件上传结束时触发。\n             * @for  Uploader\n             */\n            _tick: function() {\n                var me = this,\n                    opts = me.options,\n                    fn, val;\n    \n                // 上一个promise还没有结束，则等待完成后再执行。\n                if ( me._promise ) {\n                    return me._promise.always( me.__tick );\n                }\n    \n                // 还有位置，且还有文件要处理的话。\n                if ( me.pool.length < opts.threads && (val = me._nextBlock()) ) {\n                    me._trigged = false;\n    \n                    fn = function( val ) {\n                        me._promise = null;\n    \n                        // 有可能是reject过来的，所以要检测val的类型。\n                        val && val.file && me._startSend( val );\n                        Base.nextTick( me.__tick );\n                    };\n    \n                    me._promise = isPromise( val ) ? val.always( fn ) : fn( val );\n    \n                // 没有要上传的了，且没有正在传输的了。\n                } else if ( !me.remaning && !me.getStats().numOfQueue ) {\n                    me.runing = false;\n    \n                    me._trigged || Base.nextTick(function() {\n                        me.owner.trigger('uploadFinished');\n                    });\n                    me._trigged = true;\n                }\n            },\n    \n            _nextBlock: function() {\n                var me = this,\n                    act = me._act,\n                    opts = me.options,\n                    next, done;\n    \n                // 如果当前文件还有没有需要传输的，则直接返回剩下的。\n                if ( act && act.has() &&\n                        act.file.getStatus() === Status.PROGRESS ) {\n    \n                    // 是否提前准备下一个文件\n                    if ( opts.prepareNextFile && !me.pending.length ) {\n                        me._prepareNextFile();\n                    }\n    \n                    return act.fetch();\n    \n                // 否则，如果正在运行，则准备下一个文件，并等待完成后返回下个分片。\n                } else if ( me.runing ) {\n    \n                    // 如果缓存中有，则直接在缓存中取，没有则去queue中取。\n                    if ( !me.pending.length && me.getStats().numOfQueue ) {\n                        me._prepareNextFile();\n                    }\n    \n                    next = me.pending.shift();\n                    done = function( file ) {\n                        if ( !file ) {\n                            return null;\n                        }\n    \n                        act = CuteFile( file, opts.chunked ? opts.chunkSize : 0 );\n                        me._act = act;\n                        return act.fetch();\n                    };\n    \n                    // 文件可能还在prepare中，也有可能已经完全准备好了。\n                    return isPromise( next ) ?\n                            next[ next.pipe ? 'pipe' : 'then']( done ) :\n                            done( next );\n                }\n            },\n    \n    \n            /**\n             * @event uploadStart\n             * @param {File} file File对象\n             * @description 某个文件开始上传前触发，一个文件只会触发一次。\n             * @for  Uploader\n             */\n            _prepareNextFile: function() {\n                var me = this,\n                    file = me.request('fetch-file'),\n                    pending = me.pending,\n                    promise;\n    \n                if ( file ) {\n                    promise = me.request( 'before-send-file', file, function() {\n    \n                        // 有可能文件被skip掉了。文件被skip掉后，状态坑定不是Queued.\n                        if ( file.getStatus() === Status.QUEUED ) {\n                            me.owner.trigger( 'uploadStart', file );\n                            file.setStatus( Status.PROGRESS );\n                            return file;\n                        }\n    \n                        return me._finishFile( file );\n                    });\n    \n                    // 如果还在pending中，则替换成文件本身。\n                    promise.done(function() {\n                        var idx = $.inArray( promise, pending );\n    \n                        ~idx && pending.splice( idx, 1, file );\n                    });\n    \n                    // befeore-send-file的钩子就有错误发生。\n                    promise.fail(function( reason ) {\n                        file.setStatus( Status.ERROR, reason );\n                        me.owner.trigger( 'uploadError', file, reason );\n                        me.owner.trigger( 'uploadComplete', file );\n                    });\n    \n                    pending.push( promise );\n                }\n            },\n    \n            // 让出位置了，可以让其他分片开始上传\n            _popBlock: function( block ) {\n                var idx = $.inArray( block, this.pool );\n    \n                this.pool.splice( idx, 1 );\n                block.file.remaning--;\n                this.remaning--;\n            },\n    \n            // 开始上传，可以被掉过。如果promise被reject了，则表示跳过此分片。\n            _startSend: function( block ) {\n                var me = this,\n                    file = block.file,\n                    promise;\n    \n                me.pool.push( block );\n                me.remaning++;\n    \n                // 如果没有分片，则直接使用原始的。\n                // 不会丢失content-type信息。\n                block.blob = block.chunks === 1 ? file.source :\n                        file.source.slice( block.start, block.end );\n    \n                // hook, 每个分片发送之前可能要做些异步的事情。\n                promise = me.request( 'before-send', block, function() {\n    \n                    // 有可能文件已经上传出错了，所以不需要再传输了。\n                    if ( file.getStatus() === Status.PROGRESS ) {\n                        me._doSend( block );\n                    } else {\n                        me._popBlock( block );\n                        Base.nextTick( me.__tick );\n                    }\n                });\n    \n                // 如果为fail了，则跳过此分片。\n                promise.fail(function() {\n                    if ( file.remaning === 1 ) {\n                        me._finishFile( file ).always(function() {\n                            block.percentage = 1;\n                            me._popBlock( block );\n                            me.owner.trigger( 'uploadComplete', file );\n                            Base.nextTick( me.__tick );\n                        });\n                    } else {\n                        block.percentage = 1;\n                        me._popBlock( block );\n                        Base.nextTick( me.__tick );\n                    }\n                });\n            },\n    \n    \n            /**\n             * @event uploadBeforeSend\n             * @param {Object} object\n             * @param {Object} data 默认的上传参数，可以扩展此对象来控制上传参数。\n             * @description 当某个文件的分块在发送前触发，主要用来询问是否要添加附带参数，大文件在开起分片上传的前提下此事件可能会触发多次。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadAccept\n             * @param {Object} object\n             * @param {Object} ret 服务端的返回数据，json格式，如果服务端不是json格式，从ret._raw中取数据，自行解析。\n             * @description 当某个文件上传到服务端响应后，会派送此事件来询问服务端响应是否有效。如果此事件handler返回值为`false`, 则此文件将派送`server`类型的`uploadError`事件。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadProgress\n             * @param {File} file File对象\n             * @param {Number} percentage 上传进度\n             * @description 上传过程中触发，携带上传进度。\n             * @for  Uploader\n             */\n    \n    \n            /**\n             * @event uploadError\n             * @param {File} file File对象\n             * @param {String} reason 出错的code\n             * @description 当文件上传出错时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadSuccess\n             * @param {File} file File对象\n             * @param {Object} response 服务端返回的数据\n             * @description 当文件上传成功时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadComplete\n             * @param {File} [file] File对象\n             * @description 不管成功或者失败，文件上传完成时触发。\n             * @for  Uploader\n             */\n    \n            // 做上传操作。\n            _doSend: function( block ) {\n                var me = this,\n                    owner = me.owner,\n                    opts = me.options,\n                    file = block.file,\n                    tr = new Transport( opts ),\n                    data = $.extend({}, opts.formData ),\n                    headers = $.extend({}, opts.headers ),\n                    requestAccept, ret;\n    \n                block.transport = tr;\n    \n                tr.on( 'destroy', function() {\n                    delete block.transport;\n                    me._popBlock( block );\n                    Base.nextTick( me.__tick );\n                });\n    \n                // 广播上传进度。以文件为单位。\n                tr.on( 'progress', function( percentage ) {\n                    var totalPercent = 0,\n                        uploaded = 0;\n    \n                    // 可能没有abort掉，progress还是执行进来了。\n                    // if ( !file.blocks ) {\n                    //     return;\n                    // }\n    \n                    totalPercent = block.percentage = percentage;\n    \n                    if ( block.chunks > 1 ) {    // 计算文件的整体速度。\n                        $.each( file.blocks, function( _, v ) {\n                            uploaded += (v.percentage || 0) * (v.end - v.start);\n                        });\n    \n                        totalPercent = uploaded / file.size;\n                    }\n    \n                    owner.trigger( 'uploadProgress', file, totalPercent || 0 );\n                });\n    \n                // 用来询问，是否返回的结果是有错误的。\n                requestAccept = function( reject ) {\n                    var fn;\n    \n                    ret = tr.getResponseAsJson() || {};\n                    ret._raw = tr.getResponse();\n                    fn = function( value ) {\n                        reject = value;\n                    };\n    \n                    // 服务端响应了，不代表成功了，询问是否响应正确。\n                    if ( !owner.trigger( 'uploadAccept', block, ret, fn ) ) {\n                        reject = reject || 'server';\n                    }\n    \n                    return reject;\n                };\n    \n                // 尝试重试，然后广播文件上传出错。\n                tr.on( 'error', function( type, flag ) {\n                    block.retried = block.retried || 0;\n    \n                    // 自动重试\n                    if ( block.chunks > 1 && ~'http,abort'.indexOf( type ) &&\n                            block.retried < opts.chunkRetry ) {\n    \n                        block.retried++;\n                        tr.send();\n    \n                    } else {\n    \n                        // http status 500 ~ 600\n                        if ( !flag && type === 'server' ) {\n                            type = requestAccept( type );\n                        }\n    \n                        file.setStatus( Status.ERROR, type );\n                        owner.trigger( 'uploadError', file, type );\n                        owner.trigger( 'uploadComplete', file );\n                    }\n                });\n    \n                // 上传成功\n                tr.on( 'load', function() {\n                    var reason;\n    \n                    // 如果非预期，转向上传出错。\n                    if ( (reason = requestAccept()) ) {\n                        tr.trigger( 'error', reason, true );\n                        return;\n                    }\n    \n                    // 全部上传完成。\n                    if ( file.remaning === 1 ) {\n                        me._finishFile( file, ret );\n                    } else {\n                        tr.destroy();\n                    }\n                });\n    \n                // 配置默认的上传字段。\n                data = $.extend( data, {\n                    id: file.id,\n                    name: file.name,\n                    type: file.type,\n                    lastModifiedDate: file.lastModifiedDate,\n                    size: file.size\n                });\n    \n                block.chunks > 1 && $.extend( data, {\n                    chunks: block.chunks,\n                    chunk: block.chunk\n                });\n    \n                // 在发送之间可以添加字段什么的。。。\n                // 如果默认的字段不够使用，可以通过监听此事件来扩展\n                owner.trigger( 'uploadBeforeSend', block, data, headers );\n    \n                // 开始发送。\n                tr.appendBlob( opts.fileVal, block.blob, file.name );\n                tr.append( data );\n                tr.setRequestHeader( headers );\n                tr.send();\n            },\n    \n            // 完成上传。\n            _finishFile: function( file, ret, hds ) {\n                var owner = this.owner;\n    \n                return owner\n                        .request( 'after-send-file', arguments, function() {\n                            file.setStatus( Status.COMPLETE );\n                            owner.trigger( 'uploadSuccess', file, ret, hds );\n                        })\n                        .fail(function( reason ) {\n    \n                            // 如果外部已经标记为invalid什么的，不再改状态。\n                            if ( file.getStatus() === Status.PROGRESS ) {\n                                file.setStatus( Status.ERROR, reason );\n                            }\n    \n                            owner.trigger( 'uploadError', file, reason );\n                        })\n                        .always(function() {\n                            owner.trigger( 'uploadComplete', file );\n                        });\n            }\n    \n        });\n    });\n    /**\n     * @fileOverview 各种验证，包括文件总大小是否超出、单文件是否超出和文件是否重复。\n     */\n    \n    define('widgets/validator',[\n        'base',\n        'uploader',\n        'file',\n        'widgets/widget'\n    ], function( Base, Uploader, WUFile ) {\n    \n        var $ = Base.$,\n            validators = {},\n            api;\n    \n        /**\n         * @event error\n         * @param {String} type 错误类型。\n         * @description 当validate不通过时，会以派送错误事件的形式通知调用者。通过`upload.on('error', handler)`可以捕获到此类错误，目前有以下错误会在特定的情况下派送错来。\n         *\n         * * `Q_EXCEED_NUM_LIMIT` 在设置了`fileNumLimit`且尝试给`uploader`添加的文件数量超出这个值时派送。\n         * * `Q_EXCEED_SIZE_LIMIT` 在设置了`Q_EXCEED_SIZE_LIMIT`且尝试给`uploader`添加的文件总大小超出这个值时派送。\n         * @for  Uploader\n         */\n    \n        // 暴露给外面的api\n        api = {\n    \n            // 添加验证器\n            addValidator: function( type, cb ) {\n                validators[ type ] = cb;\n            },\n    \n            // 移除验证器\n            removeValidator: function( type ) {\n                delete validators[ type ];\n            }\n        };\n    \n        // 在Uploader初始化的时候启动Validators的初始化\n        Uploader.register({\n            init: function() {\n                var me = this;\n                $.each( validators, function() {\n                    this.call( me.owner );\n                });\n            }\n        });\n    \n        /**\n         * @property {int} [fileNumLimit=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 验证文件总数量, 超出则不允许加入队列。\n         */\n        api.addValidator( 'fileNumLimit', function() {\n            var uploader = this,\n                opts = uploader.options,\n                count = 0,\n                max = opts.fileNumLimit >> 0,\n                flag = true;\n    \n            if ( !max ) {\n                return;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n    \n                if ( count >= max && flag ) {\n                    flag = false;\n                    this.trigger( 'error', 'Q_EXCEED_NUM_LIMIT', max, file );\n                    setTimeout(function() {\n                        flag = true;\n                    }, 1 );\n                }\n    \n                return count >= max ? false : true;\n            });\n    \n            uploader.on( 'fileQueued', function() {\n                count++;\n            });\n    \n            uploader.on( 'fileDequeued', function() {\n                count--;\n            });\n    \n            uploader.on( 'uploadFinished', function() {\n                count = 0;\n            });\n        });\n    \n    \n        /**\n         * @property {int} [fileSizeLimit=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 验证文件总大小是否超出限制, 超出则不允许加入队列。\n         */\n        api.addValidator( 'fileSizeLimit', function() {\n            var uploader = this,\n                opts = uploader.options,\n                count = 0,\n                max = opts.fileSizeLimit >> 0,\n                flag = true;\n    \n            if ( !max ) {\n                return;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n                var invalid = count + file.size > max;\n    \n                if ( invalid && flag ) {\n                    flag = false;\n                    this.trigger( 'error', 'Q_EXCEED_SIZE_LIMIT', max, file );\n                    setTimeout(function() {\n                        flag = true;\n                    }, 1 );\n                }\n    \n                return invalid ? false : true;\n            });\n    \n            uploader.on( 'fileQueued', function( file ) {\n                count += file.size;\n            });\n    \n            uploader.on( 'fileDequeued', function( file ) {\n                count -= file.size;\n            });\n    \n            uploader.on( 'uploadFinished', function() {\n                count = 0;\n            });\n        });\n    \n        /**\n         * @property {int} [fileSingleSizeLimit=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 验证单个文件大小是否超出限制, 超出则不允许加入队列。\n         */\n        api.addValidator( 'fileSingleSizeLimit', function() {\n            var uploader = this,\n                opts = uploader.options,\n                max = opts.fileSingleSizeLimit;\n    \n            if ( !max ) {\n                return;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n    \n                if ( file.size > max ) {\n                    file.setStatus( WUFile.Status.INVALID, 'exceed_size' );\n                    this.trigger( 'error', 'F_EXCEED_SIZE', file );\n                    return false;\n                }\n    \n            });\n    \n        });\n    \n        /**\n         * @property {int} [duplicate=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 去重， 根据文件名字、文件大小和最后修改时间来生成hash Key.\n         */\n        api.addValidator( 'duplicate', function() {\n            var uploader = this,\n                opts = uploader.options,\n                mapping = {};\n    \n            if ( opts.duplicate ) {\n                return;\n            }\n    \n            function hashString( str ) {\n                var hash = 0,\n                    i = 0,\n                    len = str.length,\n                    _char;\n    \n                for ( ; i < len; i++ ) {\n                    _char = str.charCodeAt( i );\n                    hash = _char + (hash << 6) + (hash << 16) - hash;\n                }\n    \n                return hash;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n                var hash = file.__hash || (file.__hash = hashString( file.name +\n                        file.size + file.lastModifiedDate ));\n    \n                // 已经重复了\n                if ( mapping[ hash ] ) {\n                    this.trigger( 'error', 'F_DUPLICATE', file );\n                    return false;\n                }\n            });\n    \n            uploader.on( 'fileQueued', function( file ) {\n                var hash = file.__hash;\n    \n                hash && (mapping[ hash ] = true);\n            });\n    \n            uploader.on( 'fileDequeued', function( file ) {\n                var hash = file.__hash;\n    \n                hash && (delete mapping[ hash ]);\n            });\n        });\n    \n        return api;\n    });\n    \n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/compbase',[],function() {\n    \n        function CompBase( owner, runtime ) {\n    \n            this.owner = owner;\n            this.options = owner.options;\n    \n            this.getRuntime = function() {\n                return runtime;\n            };\n    \n            this.getRuid = function() {\n                return runtime.uid;\n            };\n    \n            this.trigger = function() {\n                return owner.trigger.apply( owner, arguments );\n            };\n        }\n    \n        return CompBase;\n    });\n    /**\n     * @fileOverview Html5Runtime\n     */\n    define('runtime/html5/runtime',[\n        'base',\n        'runtime/runtime',\n        'runtime/compbase'\n    ], function( Base, Runtime, CompBase ) {\n    \n        var type = 'html5',\n            components = {};\n    \n        function Html5Runtime() {\n            var pool = {},\n                me = this,\n                destory = this.destory;\n    \n            Runtime.apply( me, arguments );\n            me.type = type;\n    \n    \n            // 这个方法的调用者，实际上是RuntimeClient\n            me.exec = function( comp, fn/*, args...*/) {\n                var client = this,\n                    uid = client.uid,\n                    args = Base.slice( arguments, 2 ),\n                    instance;\n    \n                if ( components[ comp ] ) {\n                    instance = pool[ uid ] = pool[ uid ] ||\n                            new components[ comp ]( client, me );\n    \n                    if ( instance[ fn ] ) {\n                        return instance[ fn ].apply( instance, args );\n                    }\n                }\n            };\n    \n            me.destory = function() {\n                // @todo 删除池子中的所有实例\n                return destory && destory.apply( this, arguments );\n            };\n        }\n    \n        Base.inherits( Runtime, {\n            constructor: Html5Runtime,\n    \n            // 不需要连接其他程序，直接执行callback\n            init: function() {\n                var me = this;\n                setTimeout(function() {\n                    me.trigger('ready');\n                }, 1 );\n            }\n    \n        });\n    \n        // 注册Components\n        Html5Runtime.register = function( name, component ) {\n            var klass = components[ name ] = Base.inherits( CompBase, component );\n            return klass;\n        };\n    \n        // 注册html5运行时。\n        // 只有在支持的前提下注册。\n        if ( window.Blob && window.FileReader && window.DataView ) {\n            Runtime.addRuntime( type, Html5Runtime );\n        }\n    \n        return Html5Runtime;\n    });\n    /**\n     * @fileOverview Blob Html实现\n     */\n    define('runtime/html5/blob',[\n        'runtime/html5/runtime',\n        'lib/blob'\n    ], function( Html5Runtime, Blob ) {\n    \n        return Html5Runtime.register( 'Blob', {\n            slice: function( start, end ) {\n                var blob = this.owner.source,\n                    slice = blob.slice || blob.webkitSlice || blob.mozSlice;\n    \n                blob = slice.call( blob, start, end );\n    \n                return new Blob( this.getRuid(), blob );\n            }\n        });\n    });\n    /**\n     * @fileOverview FilePaste\n     */\n    define('runtime/html5/dnd',[\n        'base',\n        'runtime/html5/runtime',\n        'lib/file'\n    ], function( Base, Html5Runtime, File ) {\n    \n        var $ = Base.$,\n            prefix = 'webuploader-dnd-';\n    \n        return Html5Runtime.register( 'DragAndDrop', {\n            init: function() {\n                var elem = this.elem = this.options.container;\n    \n                this.dragEnterHandler = Base.bindFn( this._dragEnterHandler, this );\n                this.dragOverHandler = Base.bindFn( this._dragOverHandler, this );\n                this.dragLeaveHandler = Base.bindFn( this._dragLeaveHandler, this );\n                this.dropHandler = Base.bindFn( this._dropHandler, this );\n                this.dndOver = false;\n    \n                elem.on( 'dragenter', this.dragEnterHandler );\n                elem.on( 'dragover', this.dragOverHandler );\n                elem.on( 'dragleave', this.dragLeaveHandler );\n                elem.on( 'drop', this.dropHandler );\n    \n                if ( this.options.disableGlobalDnd ) {\n                    $( document ).on( 'dragover', this.dragOverHandler );\n                    $( document ).on( 'drop', this.dropHandler );\n                }\n            },\n    \n            _dragEnterHandler: function( e ) {\n                var me = this,\n                    denied = me._denied || false,\n                    items;\n    \n                e = e.originalEvent || e;\n    \n                if ( !me.dndOver ) {\n                    me.dndOver = true;\n    \n                    // 注意只有 chrome 支持。\n                    items = e.dataTransfer.items;\n    \n                    if ( items && items.length ) {\n                        me._denied = denied = !me.trigger( 'accept', items );\n                    }\n    \n                    me.elem.addClass( prefix + 'over' );\n                    me.elem[ denied ? 'addClass' :\n                            'removeClass' ]( prefix + 'denied' );\n                }\n    \n    \n                e.dataTransfer.dropEffect = denied ? 'none' : 'copy';\n    \n                return false;\n            },\n    \n            _dragOverHandler: function( e ) {\n                // 只处理框内的。\n                var parentElem = this.elem.parent().get( 0 );\n                if ( parentElem && !$.contains( parentElem, e.currentTarget ) ) {\n                    return false;\n                }\n    \n                clearTimeout( this._leaveTimer );\n                this._dragEnterHandler.call( this, e );\n    \n                return false;\n            },\n    \n            _dragLeaveHandler: function() {\n                var me = this,\n                    handler;\n    \n                handler = function() {\n                    me.dndOver = false;\n                    me.elem.removeClass( prefix + 'over ' + prefix + 'denied' );\n                };\n    \n                clearTimeout( me._leaveTimer );\n                me._leaveTimer = setTimeout( handler, 100 );\n                return false;\n            },\n    \n            _dropHandler: function( e ) {\n                var me = this,\n                    ruid = me.getRuid(),\n                    parentElem = me.elem.parent().get( 0 );\n    \n                // 只处理框内的。\n                if ( parentElem && !$.contains( parentElem, e.currentTarget ) ) {\n                    return false;\n                }\n    \n                me._getTansferFiles( e, function( results ) {\n                    me.trigger( 'drop', $.map( results, function( file ) {\n                        return new File( ruid, file );\n                    }) );\n                });\n    \n                me.dndOver = false;\n                me.elem.removeClass( prefix + 'over' );\n                return false;\n            },\n    \n            // 如果传入 callback 则去查看文件夹，否则只管当前文件夹。\n            _getTansferFiles: function( e, callback ) {\n                var results  = [],\n                    promises = [],\n                    items, files, dataTransfer, file, item, i, len, canAccessFolder;\n    \n                e = e.originalEvent || e;\n    \n                dataTransfer = e.dataTransfer;\n                items = dataTransfer.items;\n                files = dataTransfer.files;\n    \n                canAccessFolder = !!(items && items[ 0 ].webkitGetAsEntry);\n    \n                for ( i = 0, len = files.length; i < len; i++ ) {\n                    file = files[ i ];\n                    item = items && items[ i ];\n    \n                    if ( canAccessFolder && item.webkitGetAsEntry().isDirectory ) {\n    \n                        promises.push( this._traverseDirectoryTree(\n                                item.webkitGetAsEntry(), results ) );\n                    } else {\n                        results.push( file );\n                    }\n                }\n    \n                Base.when.apply( Base, promises ).done(function() {\n    \n                    if ( !results.length ) {\n                        return;\n                    }\n    \n                    callback( results );\n                });\n            },\n    \n            _traverseDirectoryTree: function( entry, results ) {\n                var deferred = Base.Deferred(),\n                    me = this;\n    \n                if ( entry.isFile ) {\n                    entry.file(function( file ) {\n                        results.push( file );\n                        deferred.resolve();\n                    });\n                } else if ( entry.isDirectory ) {\n                    entry.createReader().readEntries(function( entries ) {\n                        var len = entries.length,\n                            promises = [],\n                            arr = [],    // 为了保证顺序。\n                            i;\n    \n                        for ( i = 0; i < len; i++ ) {\n                            promises.push( me._traverseDirectoryTree(\n                                    entries[ i ], arr ) );\n                        }\n    \n                        Base.when.apply( Base, promises ).then(function() {\n                            results.push.apply( results, arr );\n                            deferred.resolve();\n                        }, deferred.reject );\n                    });\n                }\n    \n                return deferred.promise();\n            },\n    \n            destroy: function() {\n                var elem = this.elem;\n    \n                elem.off( 'dragenter', this.dragEnterHandler );\n                elem.off( 'dragover', this.dragEnterHandler );\n                elem.off( 'dragleave', this.dragLeaveHandler );\n                elem.off( 'drop', this.dropHandler );\n    \n                if ( this.options.disableGlobalDnd ) {\n                    $( document ).off( 'dragover', this.dragOverHandler );\n                    $( document ).off( 'drop', this.dropHandler );\n                }\n            }\n        });\n    });\n    \n    /**\n     * @fileOverview FilePaste\n     */\n    define('runtime/html5/filepaste',[\n        'base',\n        'runtime/html5/runtime',\n        'lib/file'\n    ], function( Base, Html5Runtime, File ) {\n    \n        return Html5Runtime.register( 'FilePaste', {\n            init: function() {\n                var opts = this.options,\n                    elem = this.elem = opts.container,\n                    accept = '.*',\n                    arr, i, len, item;\n    \n                // accetp的mimeTypes中生成匹配正则。\n                if ( opts.accept ) {\n                    arr = [];\n    \n                    for ( i = 0, len = opts.accept.length; i < len; i++ ) {\n                        item = opts.accept[ i ].mimeTypes;\n                        item && arr.push( item );\n                    }\n    \n                    if ( arr.length ) {\n                        accept = arr.join(',');\n                        accept = accept.replace( /,/g, '|' ).replace( /\\*/g, '.*' );\n                    }\n                }\n                this.accept = accept = new RegExp( accept, 'i' );\n                this.hander = Base.bindFn( this._pasteHander, this );\n                elem.on( 'paste', this.hander );\n            },\n    \n            _pasteHander: function( e ) {\n                var allowed = [],\n                    ruid = this.getRuid(),\n                    items, item, blob, i, len;\n    \n                e = e.originalEvent || e;\n                items = e.clipboardData.items;\n    \n                for ( i = 0, len = items.length; i < len; i++ ) {\n                    item = items[ i ];\n    \n                    if ( item.kind !== 'file' || !(blob = item.getAsFile()) ) {\n                        continue;\n                    }\n    \n                    allowed.push( new File( ruid, blob ) );\n                }\n    \n                if ( allowed.length ) {\n                    // 不阻止非文件粘贴（文字粘贴）的事件冒泡\n                    e.preventDefault();\n                    e.stopPropagation();\n                    this.trigger( 'paste', allowed );\n                }\n            },\n    \n            destroy: function() {\n                this.elem.off( 'paste', this.hander );\n            }\n        });\n    });\n    \n    /**\n     * @fileOverview FilePicker\n     */\n    define('runtime/html5/filepicker',[\n        'base',\n        'runtime/html5/runtime'\n    ], function( Base, Html5Runtime ) {\n    \n        var $ = Base.$;\n    \n        return Html5Runtime.register( 'FilePicker', {\n            init: function() {\n                var container = this.getRuntime().getContainer(),\n                    me = this,\n                    owner = me.owner,\n                    opts = me.options,\n                    lable = $( document.createElement('label') ),\n                    input = $( document.createElement('input') ),\n                    arr, i, len, mouseHandler;\n    \n                input.attr( 'type', 'file' );\n                input.attr( 'name', opts.name );\n                input.addClass('webuploader-element-invisible');\n    \n                lable.on( 'click', function() {\n                    input.trigger('click');\n                });\n    \n                lable.css({\n                    opacity: 0,\n                    width: '100%',\n                    height: '100%',\n                    display: 'block',\n                    cursor: 'pointer',\n                    background: '#ffffff'\n                });\n    \n                if ( opts.multiple ) {\n                    input.attr( 'multiple', 'multiple' );\n                }\n    \n                // @todo Firefox不支持单独指定后缀\n                if ( opts.accept && opts.accept.length > 0 ) {\n                    arr = [];\n    \n                    for ( i = 0, len = opts.accept.length; i < len; i++ ) {\n                        arr.push( opts.accept[ i ].mimeTypes );\n                    }\n    \n                    input.attr( 'accept', arr.join(',') );\n                }\n    \n                container.append( input );\n                container.append( lable );\n    \n                mouseHandler = function( e ) {\n                    owner.trigger( e.type );\n                };\n    \n                input.on( 'change', function( e ) {\n                    var fn = arguments.callee,\n                        clone;\n    \n                    me.files = e.target.files;\n    \n                    // reset input\n                    clone = this.cloneNode( true );\n                    this.parentNode.replaceChild( clone, this );\n    \n                    input.off();\n                    input = $( clone ).on( 'change', fn )\n                            .on( 'mouseenter mouseleave', mouseHandler );\n    \n                    owner.trigger('change');\n                });\n    \n                lable.on( 'mouseenter mouseleave', mouseHandler );\n    \n            },\n    \n    \n            getFiles: function() {\n                return this.files;\n            },\n    \n            destroy: function() {\n                // todo\n            }\n        });\n    });\n    /**\n     * Terms:\n     *\n     * Uint8Array, FileReader, BlobBuilder, atob, ArrayBuffer\n     * @fileOverview Image控件\n     */\n    define('runtime/html5/util',[\n        'base'\n    ], function( Base ) {\n    \n        var urlAPI = window.createObjectURL && window ||\n                window.URL && URL.revokeObjectURL && URL ||\n                window.webkitURL,\n            createObjectURL = Base.noop,\n            revokeObjectURL = createObjectURL;\n    \n        if ( urlAPI ) {\n    \n            // 更安全的方式调用，比如android里面就能把context改成其他的对象。\n            createObjectURL = function() {\n                return urlAPI.createObjectURL.apply( urlAPI, arguments );\n            };\n    \n            revokeObjectURL = function() {\n                return urlAPI.revokeObjectURL.apply( urlAPI, arguments );\n            };\n        }\n    \n        return {\n            createObjectURL: createObjectURL,\n            revokeObjectURL: revokeObjectURL,\n    \n            dataURL2Blob: function( dataURI ) {\n                var byteStr, intArray, ab, i, mimetype, parts;\n    \n                parts = dataURI.split(',');\n    \n                if ( ~parts[ 0 ].indexOf('base64') ) {\n                    byteStr = atob( parts[ 1 ] );\n                } else {\n                    byteStr = decodeURIComponent( parts[ 1 ] );\n                }\n    \n                ab = new ArrayBuffer( byteStr.length );\n                intArray = new Uint8Array( ab );\n    \n                for ( i = 0; i < byteStr.length; i++ ) {\n                    intArray[ i ] = byteStr.charCodeAt( i );\n                }\n    \n                mimetype = parts[ 0 ].split(':')[ 1 ].split(';')[ 0 ];\n    \n                return this.arrayBufferToBlob( ab, mimetype );\n            },\n    \n            dataURL2ArrayBuffer: function( dataURI ) {\n                var byteStr, intArray, i, parts;\n    \n                parts = dataURI.split(',');\n    \n                if ( ~parts[ 0 ].indexOf('base64') ) {\n                    byteStr = atob( parts[ 1 ] );\n                } else {\n                    byteStr = decodeURIComponent( parts[ 1 ] );\n                }\n    \n                intArray = new Uint8Array( byteStr.length );\n    \n                for ( i = 0; i < byteStr.length; i++ ) {\n                    intArray[ i ] = byteStr.charCodeAt( i );\n                }\n    \n                return intArray.buffer;\n            },\n    \n            arrayBufferToBlob: function( buffer, type ) {\n                var builder = window.BlobBuilder || window.WebKitBlobBuilder,\n                    bb;\n    \n                // android不支持直接new Blob, 只能借助blobbuilder.\n                if ( builder ) {\n                    bb = new builder();\n                    bb.append( buffer );\n                    return bb.getBlob( type );\n                }\n    \n                return new Blob([ buffer ], type ? { type: type } : {} );\n            },\n    \n            // 抽出来主要是为了解决android下面canvas.toDataUrl不支持jpeg.\n            // 你得到的结果是png.\n            canvasToDataUrl: function( canvas, type, quality ) {\n                return canvas.toDataURL( type, quality / 100 );\n            },\n    \n            // imagemeat会复写这个方法，如果用户选择加载那个文件了的话。\n            parseMeta: function( blob, callback ) {\n                callback( false, {});\n            },\n    \n            // imagemeat会复写这个方法，如果用户选择加载那个文件了的话。\n            updateImageHead: function( data ) {\n                return data;\n            }\n        };\n    });\n    /**\n     * Terms:\n     *\n     * Uint8Array, FileReader, BlobBuilder, atob, ArrayBuffer\n     * @fileOverview Image控件\n     */\n    define('runtime/html5/imagemeta',[\n        'runtime/html5/util'\n    ], function( Util ) {\n    \n        var api;\n    \n        api = {\n            parsers: {\n                0xffe1: []\n            },\n    \n            maxMetaDataSize: 262144,\n    \n            parse: function( blob, cb ) {\n                var me = this,\n                    fr = new FileReader();\n    \n                fr.onload = function() {\n                    cb( false, me._parse( this.result ) );\n                    fr = fr.onload = fr.onerror = null;\n                };\n    \n                fr.onerror = function( e ) {\n                    cb( e.message );\n                    fr = fr.onload = fr.onerror = null;\n                };\n    \n                blob = blob.slice( 0, me.maxMetaDataSize );\n                fr.readAsArrayBuffer( blob.getSource() );\n            },\n    \n            _parse: function( buffer, noParse ) {\n                if ( buffer.byteLength < 6 ) {\n                    return;\n                }\n    \n                var dataview = new DataView( buffer ),\n                    offset = 2,\n                    maxOffset = dataview.byteLength - 4,\n                    headLength = offset,\n                    ret = {},\n                    markerBytes, markerLength, parsers, i;\n    \n                if ( dataview.getUint16( 0 ) === 0xffd8 ) {\n    \n                    while ( offset < maxOffset ) {\n                        markerBytes = dataview.getUint16( offset );\n    \n                        if ( markerBytes >= 0xffe0 && markerBytes <= 0xffef ||\n                                markerBytes === 0xfffe ) {\n    \n                            markerLength = dataview.getUint16( offset + 2 ) + 2;\n    \n                            if ( offset + markerLength > dataview.byteLength ) {\n                                break;\n                            }\n    \n                            parsers = api.parsers[ markerBytes ];\n    \n                            if ( !noParse && parsers ) {\n                                for ( i = 0; i < parsers.length; i += 1 ) {\n                                    parsers[ i ].call( api, dataview, offset,\n                                            markerLength, ret );\n                                }\n                            }\n    \n                            offset += markerLength;\n                            headLength = offset;\n                        } else {\n                            break;\n                        }\n                    }\n    \n                    if ( headLength > 6 ) {\n                        if ( buffer.slice ) {\n                            ret.imageHead = buffer.slice( 2, headLength );\n                        } else {\n                            // Workaround for IE10, which does not yet\n                            // support ArrayBuffer.slice:\n                            ret.imageHead = new Uint8Array( buffer )\n                                    .subarray( 2, headLength );\n                        }\n                    }\n                }\n    \n                return ret;\n            },\n    \n            updateImageHead: function( buffer, head ) {\n                var data = this._parse( buffer, true ),\n                    buf1, buf2, bodyoffset;\n    \n    \n                bodyoffset = 2;\n                if ( data.imageHead ) {\n                    bodyoffset = 2 + data.imageHead.byteLength;\n                }\n    \n                if ( buffer.slice ) {\n                    buf2 = buffer.slice( bodyoffset );\n                } else {\n                    buf2 = new Uint8Array( buffer ).subarray( bodyoffset );\n                }\n    \n                buf1 = new Uint8Array( head.byteLength + 2 + buf2.byteLength );\n    \n                buf1[ 0 ] = 0xFF;\n                buf1[ 1 ] = 0xD8;\n                buf1.set( new Uint8Array( head ), 2 );\n                buf1.set( new Uint8Array( buf2 ), head.byteLength + 2 );\n    \n                return buf1.buffer;\n            }\n        };\n    \n        Util.parseMeta = function() {\n            return api.parse.apply( api, arguments );\n        };\n    \n        Util.updateImageHead = function() {\n            return api.updateImageHead.apply( api, arguments );\n        };\n    \n        return api;\n    });\n    /**\n     * 代码来自于：https://github.com/blueimp/JavaScript-Load-Image\n     * 暂时项目中只用了orientation.\n     *\n     * 去除了 Exif Sub IFD Pointer, GPS Info IFD Pointer, Exif Thumbnail.\n     * @fileOverview EXIF解析\n     */\n    \n    // Sample\n    // ====================================\n    // Make : Apple\n    // Model : iPhone 4S\n    // Orientation : 1\n    // XResolution : 72 [72/1]\n    // YResolution : 72 [72/1]\n    // ResolutionUnit : 2\n    // Software : QuickTime 7.7.1\n    // DateTime : 2013:09:01 22:53:55\n    // ExifIFDPointer : 190\n    // ExposureTime : 0.058823529411764705 [1/17]\n    // FNumber : 2.4 [12/5]\n    // ExposureProgram : Normal program\n    // ISOSpeedRatings : 800\n    // ExifVersion : 0220\n    // DateTimeOriginal : 2013:09:01 22:52:51\n    // DateTimeDigitized : 2013:09:01 22:52:51\n    // ComponentsConfiguration : YCbCr\n    // ShutterSpeedValue : 4.058893515764426\n    // ApertureValue : 2.5260688216892597 [4845/1918]\n    // BrightnessValue : -0.3126686601998395\n    // MeteringMode : Pattern\n    // Flash : Flash did not fire, compulsory flash mode\n    // FocalLength : 4.28 [107/25]\n    // SubjectArea : [4 values]\n    // FlashpixVersion : 0100\n    // ColorSpace : 1\n    // PixelXDimension : 2448\n    // PixelYDimension : 3264\n    // SensingMethod : One-chip color area sensor\n    // ExposureMode : 0\n    // WhiteBalance : Auto white balance\n    // FocalLengthIn35mmFilm : 35\n    // SceneCaptureType : Standard\n    define('runtime/html5/imagemeta/exif',[\n        'base',\n        'runtime/html5/imagemeta'\n    ], function( Base, ImageMeta ) {\n    \n        var EXIF = {};\n    \n        EXIF.ExifMap = function() {\n            return this;\n        };\n    \n        EXIF.ExifMap.prototype.map = {\n            'Orientation': 0x0112\n        };\n    \n        EXIF.ExifMap.prototype.get = function( id ) {\n            return this[ id ] || this[ this.map[ id ] ];\n        };\n    \n        EXIF.exifTagTypes = {\n            // byte, 8-bit unsigned int:\n            1: {\n                getValue: function( dataView, dataOffset ) {\n                    return dataView.getUint8( dataOffset );\n                },\n                size: 1\n            },\n    \n            // ascii, 8-bit byte:\n            2: {\n                getValue: function( dataView, dataOffset ) {\n                    return String.fromCharCode( dataView.getUint8( dataOffset ) );\n                },\n                size: 1,\n                ascii: true\n            },\n    \n            // short, 16 bit int:\n            3: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getUint16( dataOffset, littleEndian );\n                },\n                size: 2\n            },\n    \n            // long, 32 bit int:\n            4: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getUint32( dataOffset, littleEndian );\n                },\n                size: 4\n            },\n    \n            // rational = two long values,\n            // first is numerator, second is denominator:\n            5: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getUint32( dataOffset, littleEndian ) /\n                        dataView.getUint32( dataOffset + 4, littleEndian );\n                },\n                size: 8\n            },\n    \n            // slong, 32 bit signed int:\n            9: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getInt32( dataOffset, littleEndian );\n                },\n                size: 4\n            },\n    \n            // srational, two slongs, first is numerator, second is denominator:\n            10: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getInt32( dataOffset, littleEndian ) /\n                        dataView.getInt32( dataOffset + 4, littleEndian );\n                },\n                size: 8\n            }\n        };\n    \n        // undefined, 8-bit byte, value depending on field:\n        EXIF.exifTagTypes[ 7 ] = EXIF.exifTagTypes[ 1 ];\n    \n        EXIF.getExifValue = function( dataView, tiffOffset, offset, type, length,\n                littleEndian ) {\n    \n            var tagType = EXIF.exifTagTypes[ type ],\n                tagSize, dataOffset, values, i, str, c;\n    \n            if ( !tagType ) {\n                Base.log('Invalid Exif data: Invalid tag type.');\n                return;\n            }\n    \n            tagSize = tagType.size * length;\n    \n            // Determine if the value is contained in the dataOffset bytes,\n            // or if the value at the dataOffset is a pointer to the actual data:\n            dataOffset = tagSize > 4 ? tiffOffset + dataView.getUint32( offset + 8,\n                    littleEndian ) : (offset + 8);\n    \n            if ( dataOffset + tagSize > dataView.byteLength ) {\n                Base.log('Invalid Exif data: Invalid data offset.');\n                return;\n            }\n    \n            if ( length === 1 ) {\n                return tagType.getValue( dataView, dataOffset, littleEndian );\n            }\n    \n            values = [];\n    \n            for ( i = 0; i < length; i += 1 ) {\n                values[ i ] = tagType.getValue( dataView,\n                        dataOffset + i * tagType.size, littleEndian );\n            }\n    \n            if ( tagType.ascii ) {\n                str = '';\n    \n                // Concatenate the chars:\n                for ( i = 0; i < values.length; i += 1 ) {\n                    c = values[ i ];\n    \n                    // Ignore the terminating NULL byte(s):\n                    if ( c === '\\u0000' ) {\n                        break;\n                    }\n                    str += c;\n                }\n    \n                return str;\n            }\n            return values;\n        };\n    \n        EXIF.parseExifTag = function( dataView, tiffOffset, offset, littleEndian,\n                data ) {\n    \n            var tag = dataView.getUint16( offset, littleEndian );\n            data.exif[ tag ] = EXIF.getExifValue( dataView, tiffOffset, offset,\n                    dataView.getUint16( offset + 2, littleEndian ),    // tag type\n                    dataView.getUint32( offset + 4, littleEndian ),    // tag length\n                    littleEndian );\n        };\n    \n        EXIF.parseExifTags = function( dataView, tiffOffset, dirOffset,\n                littleEndian, data ) {\n    \n            var tagsNumber, dirEndOffset, i;\n    \n            if ( dirOffset + 6 > dataView.byteLength ) {\n                Base.log('Invalid Exif data: Invalid directory offset.');\n                return;\n            }\n    \n            tagsNumber = dataView.getUint16( dirOffset, littleEndian );\n            dirEndOffset = dirOffset + 2 + 12 * tagsNumber;\n    \n            if ( dirEndOffset + 4 > dataView.byteLength ) {\n                Base.log('Invalid Exif data: Invalid directory size.');\n                return;\n            }\n    \n            for ( i = 0; i < tagsNumber; i += 1 ) {\n                this.parseExifTag( dataView, tiffOffset,\n                        dirOffset + 2 + 12 * i,    // tag offset\n                        littleEndian, data );\n            }\n    \n            // Return the offset to the next directory:\n            return dataView.getUint32( dirEndOffset, littleEndian );\n        };\n    \n        // EXIF.getExifThumbnail = function(dataView, offset, length) {\n        //     var hexData,\n        //         i,\n        //         b;\n        //     if (!length || offset + length > dataView.byteLength) {\n        //         Base.log('Invalid Exif data: Invalid thumbnail data.');\n        //         return;\n        //     }\n        //     hexData = [];\n        //     for (i = 0; i < length; i += 1) {\n        //         b = dataView.getUint8(offset + i);\n        //         hexData.push((b < 16 ? '0' : '') + b.toString(16));\n        //     }\n        //     return 'data:image/jpeg,%' + hexData.join('%');\n        // };\n    \n        EXIF.parseExifData = function( dataView, offset, length, data ) {\n    \n            var tiffOffset = offset + 10,\n                littleEndian, dirOffset;\n    \n            // Check for the ASCII code for \"Exif\" (0x45786966):\n            if ( dataView.getUint32( offset + 4 ) !== 0x45786966 ) {\n                // No Exif data, might be XMP data instead\n                return;\n            }\n            if ( tiffOffset + 8 > dataView.byteLength ) {\n                Base.log('Invalid Exif data: Invalid segment size.');\n                return;\n            }\n    \n            // Check for the two null bytes:\n            if ( dataView.getUint16( offset + 8 ) !== 0x0000 ) {\n                Base.log('Invalid Exif data: Missing byte alignment offset.');\n                return;\n            }\n    \n            // Check the byte alignment:\n            switch ( dataView.getUint16( tiffOffset ) ) {\n                case 0x4949:\n                    littleEndian = true;\n                    break;\n    \n                case 0x4D4D:\n                    littleEndian = false;\n                    break;\n    \n                default:\n                    Base.log('Invalid Exif data: Invalid byte alignment marker.');\n                    return;\n            }\n    \n            // Check for the TIFF tag marker (0x002A):\n            if ( dataView.getUint16( tiffOffset + 2, littleEndian ) !== 0x002A ) {\n                Base.log('Invalid Exif data: Missing TIFF marker.');\n                return;\n            }\n    \n            // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:\n            dirOffset = dataView.getUint32( tiffOffset + 4, littleEndian );\n            // Create the exif object to store the tags:\n            data.exif = new EXIF.ExifMap();\n            // Parse the tags of the main image directory and retrieve the\n            // offset to the next directory, usually the thumbnail directory:\n            dirOffset = EXIF.parseExifTags( dataView, tiffOffset,\n                    tiffOffset + dirOffset, littleEndian, data );\n    \n            // 尝试读取缩略图\n            // if ( dirOffset ) {\n            //     thumbnailData = {exif: {}};\n            //     dirOffset = EXIF.parseExifTags(\n            //         dataView,\n            //         tiffOffset,\n            //         tiffOffset + dirOffset,\n            //         littleEndian,\n            //         thumbnailData\n            //     );\n    \n            //     // Check for JPEG Thumbnail offset:\n            //     if (thumbnailData.exif[0x0201]) {\n            //         data.exif.Thumbnail = EXIF.getExifThumbnail(\n            //             dataView,\n            //             tiffOffset + thumbnailData.exif[0x0201],\n            //             thumbnailData.exif[0x0202] // Thumbnail data length\n            //         );\n            //     }\n            // }\n        };\n    \n        ImageMeta.parsers[ 0xffe1 ].push( EXIF.parseExifData );\n        return EXIF;\n    });\n    /**\n     * @fileOverview Image\n     */\n    define('runtime/html5/image',[\n        'base',\n        'runtime/html5/runtime',\n        'runtime/html5/util'\n    ], function( Base, Html5Runtime, Util ) {\n    \n        var BLANK = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D';\n    \n        return Html5Runtime.register( 'Image', {\n    \n            // flag: 标记是否被修改过。\n            modified: false,\n    \n            init: function() {\n                var me = this,\n                    img = new Image();\n    \n                img.onload = function() {\n    \n                    me._info = {\n                        type: me.type,\n                        width: this.width,\n                        height: this.height\n                    };\n    \n                    // 读取meta信息。\n                    if ( !me._metas && 'image/jpeg' === me.type ) {\n                        Util.parseMeta( me._blob, function( error, ret ) {\n                            me._metas = ret;\n                            me.owner.trigger('load');\n                        });\n                    } else {\n                        me.owner.trigger('load');\n                    }\n                };\n    \n                img.onerror = function() {\n                    me.owner.trigger('error');\n                };\n    \n                me._img = img;\n            },\n    \n            loadFromBlob: function( blob ) {\n                var me = this,\n                    img = me._img;\n    \n                me._blob = blob;\n                me.type = blob.type;\n                img.src = Util.createObjectURL( blob.getSource() );\n                me.owner.once( 'load', function() {\n                    Util.revokeObjectURL( img.src );\n                });\n            },\n    \n            resize: function( width, height ) {\n                var canvas = this._canvas ||\n                        (this._canvas = document.createElement('canvas'));\n    \n                this._resize( this._img, canvas, width, height );\n                this._blob = null;    // 没用了，可以删掉了。\n                this.modified = true;\n                this.owner.trigger('complete');\n            },\n    \n            getAsBlob: function( type ) {\n                var blob = this._blob,\n                    opts = this.options,\n                    canvas;\n    \n                type = type || this.type;\n    \n                // blob需要重新生成。\n                if ( this.modified || this.type !== type ) {\n                    canvas = this._canvas;\n    \n                    if ( type === 'image/jpeg' ) {\n    \n                        blob = Util.canvasToDataUrl( canvas, 'image/jpeg',\n                                opts.quality );\n    \n                        if ( opts.preserveHeaders && this._metas &&\n                                this._metas.imageHead ) {\n    \n                            blob = Util.dataURL2ArrayBuffer( blob );\n                            blob = Util.updateImageHead( blob,\n                                    this._metas.imageHead );\n                            blob = Util.arrayBufferToBlob( blob, type );\n                            return blob;\n                        }\n                    } else {\n                        blob = Util.canvasToDataUrl( canvas, type );\n                    }\n    \n                    blob = Util.dataURL2Blob( blob );\n                }\n    \n                return blob;\n            },\n    \n            getAsDataUrl: function( type ) {\n                var opts = this.options;\n    \n                type = type || this.type;\n    \n                if ( type === 'image/jpeg' ) {\n                    return Util.canvasToDataUrl( this._canvas, type, opts.quality );\n                } else {\n                    return this._canvas.toDataURL( type );\n                }\n            },\n    \n            getOrientation: function() {\n                return this._metas && this._metas.exif &&\n                        this._metas.exif.get('Orientation') || 1;\n            },\n    \n            info: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._info = val;\n                    return this;\n                }\n    \n                // getter\n                return this._info;\n            },\n    \n            meta: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._meta = val;\n                    return this;\n                }\n    \n                // getter\n                return this._meta;\n            },\n    \n            destroy: function() {\n                var canvas = this._canvas;\n                this._img.onload = null;\n    \n                if ( canvas ) {\n                    canvas.getContext('2d')\n                            .clearRect( 0, 0, canvas.width, canvas.height );\n                    canvas.width = canvas.height = 0;\n                    this._canvas = null;\n                }\n    \n                // 释放内存。非常重要，否则释放不了image的内存。\n                this._img.src = BLANK;\n                this._img = this._blob = null;\n            },\n    \n            _resize: function( img, cvs, width, height ) {\n                var opts = this.options,\n                    naturalWidth = img.width,\n                    naturalHeight = img.height,\n                    orientation = this.getOrientation(),\n                    scale, w, h, x, y;\n    \n                // values that require 90 degree rotation\n                if ( ~[ 5, 6, 7, 8 ].indexOf( orientation ) ) {\n    \n                    // 交换width, height的值。\n                    width ^= height;\n                    height ^= width;\n                    width ^= height;\n                }\n    \n                scale = Math[ opts.crop ? 'max' : 'min' ]( width / naturalWidth,\n                        height / naturalHeight );\n    \n                // 不允许放大。\n                opts.allowMagnify || (scale = Math.min( 1, scale ));\n    \n                w = naturalWidth * scale;\n                h = naturalHeight * scale;\n    \n                if ( opts.crop ) {\n                    cvs.width = width;\n                    cvs.height = height;\n                } else {\n                    cvs.width = w;\n                    cvs.height = h;\n                }\n    \n                x = (cvs.width - w) / 2;\n                y = (cvs.height - h) / 2;\n    \n                opts.preserveHeaders || this._rotate2Orientaion( cvs, orientation );\n    \n                this._renderImageToCanvas( cvs, img, x, y, w, h );\n            },\n    \n            _rotate2Orientaion: function( canvas, orientation ) {\n                var width = canvas.width,\n                    height = canvas.height,\n                    ctx = canvas.getContext('2d');\n    \n                switch ( orientation ) {\n                    case 5:\n                    case 6:\n                    case 7:\n                    case 8:\n                        canvas.width = height;\n                        canvas.height = width;\n                        break;\n                }\n    \n                switch ( orientation ) {\n                    case 2:    // horizontal flip\n                        ctx.translate( width, 0 );\n                        ctx.scale( -1, 1 );\n                        break;\n    \n                    case 3:    // 180 rotate left\n                        ctx.translate( width, height );\n                        ctx.rotate( Math.PI );\n                        break;\n    \n                    case 4:    // vertical flip\n                        ctx.translate( 0, height );\n                        ctx.scale( 1, -1 );\n                        break;\n    \n                    case 5:    // vertical flip + 90 rotate right\n                        ctx.rotate( 0.5 * Math.PI );\n                        ctx.scale( 1, -1 );\n                        break;\n    \n                    case 6:    // 90 rotate right\n                        ctx.rotate( 0.5 * Math.PI );\n                        ctx.translate( 0, -height );\n                        break;\n    \n                    case 7:    // horizontal flip + 90 rotate right\n                        ctx.rotate( 0.5 * Math.PI );\n                        ctx.translate( width, -height );\n                        ctx.scale( -1, 1 );\n                        break;\n    \n                    case 8:    // 90 rotate left\n                        ctx.rotate( -0.5 * Math.PI );\n                        ctx.translate( -width, 0 );\n                        break;\n                }\n            },\n    \n            // https://github.com/stomita/ios-imagefile-megapixel/\n            // blob/master/src/megapix-image.js\n            _renderImageToCanvas: (function() {\n    \n                // 如果不是ios, 不需要这么复杂！\n                if ( !Base.os.ios ) {\n                    return function( canvas, img, x, y, w, h ) {\n                        canvas.getContext('2d').drawImage( img, x, y, w, h );\n                    };\n                }\n    \n                /**\n                 * Detecting vertical squash in loaded image.\n                 * Fixes a bug which squash image vertically while drawing into\n                 * canvas for some images.\n                 */\n                function detectVerticalSquash( img, iw, ih ) {\n                    var canvas = document.createElement('canvas'),\n                        ctx = canvas.getContext('2d'),\n                        sy = 0,\n                        ey = ih,\n                        py = ih,\n                        data, alpha, ratio;\n    \n    \n                    canvas.width = 1;\n                    canvas.height = ih;\n                    ctx.drawImage( img, 0, 0 );\n                    data = ctx.getImageData( 0, 0, 1, ih ).data;\n    \n                    // search image edge pixel position in case\n                    // it is squashed vertically.\n                    while ( py > sy ) {\n                        alpha = data[ (py - 1) * 4 + 3 ];\n    \n                        if ( alpha === 0 ) {\n                            ey = py;\n                        } else {\n                            sy = py;\n                        }\n    \n                        py = (ey + sy) >> 1;\n                    }\n    \n                    ratio = (py / ih);\n                    return (ratio === 0) ? 1 : ratio;\n                }\n    \n                // fix ie7 bug\n                // http://stackoverflow.com/questions/11929099/\n                // html5-canvas-drawimage-ratio-bug-ios\n                if ( Base.os.ios >= 7 ) {\n                    return function( canvas, img, x, y, w, h ) {\n                        var iw = img.naturalWidth,\n                            ih = img.naturalHeight,\n                            vertSquashRatio = detectVerticalSquash( img, iw, ih );\n    \n                        return canvas.getContext('2d').drawImage( img, 0, 0,\n                            iw * vertSquashRatio, ih * vertSquashRatio,\n                            x, y, w, h );\n                    };\n                }\n    \n                /**\n                 * Detect subsampling in loaded image.\n                 * In iOS, larger images than 2M pixels may be\n                 * subsampled in rendering.\n                 */\n                function detectSubsampling( img ) {\n                    var iw = img.naturalWidth,\n                        ih = img.naturalHeight,\n                        canvas, ctx;\n    \n                    // subsampling may happen overmegapixel image\n                    if ( iw * ih > 1024 * 1024 ) {\n                        canvas = document.createElement('canvas');\n                        canvas.width = canvas.height = 1;\n                        ctx = canvas.getContext('2d');\n                        ctx.drawImage( img, -iw + 1, 0 );\n    \n                        // subsampled image becomes half smaller in rendering size.\n                        // check alpha channel value to confirm image is covering\n                        // edge pixel or not. if alpha value is 0\n                        // image is not covering, hence subsampled.\n                        return ctx.getImageData( 0, 0, 1, 1 ).data[ 3 ] === 0;\n                    } else {\n                        return false;\n                    }\n                }\n    \n    \n                return function( canvas, img, x, y, width, height ) {\n                    var iw = img.naturalWidth,\n                        ih = img.naturalHeight,\n                        ctx = canvas.getContext('2d'),\n                        subsampled = detectSubsampling( img ),\n                        doSquash = this.type === 'image/jpeg',\n                        d = 1024,\n                        sy = 0,\n                        dy = 0,\n                        tmpCanvas, tmpCtx, vertSquashRatio, dw, dh, sx, dx;\n    \n                    if ( subsampled ) {\n                        iw /= 2;\n                        ih /= 2;\n                    }\n    \n                    ctx.save();\n                    tmpCanvas = document.createElement('canvas');\n                    tmpCanvas.width = tmpCanvas.height = d;\n    \n                    tmpCtx = tmpCanvas.getContext('2d');\n                    vertSquashRatio = doSquash ?\n                            detectVerticalSquash( img, iw, ih ) : 1;\n    \n                    dw = Math.ceil( d * width / iw );\n                    dh = Math.ceil( d * height / ih / vertSquashRatio );\n    \n                    while ( sy < ih ) {\n                        sx = 0;\n                        dx = 0;\n                        while ( sx < iw ) {\n                            tmpCtx.clearRect( 0, 0, d, d );\n                            tmpCtx.drawImage( img, -sx, -sy );\n                            ctx.drawImage( tmpCanvas, 0, 0, d, d,\n                                    x + dx, y + dy, dw, dh );\n                            sx += d;\n                            dx += dw;\n                        }\n                        sy += d;\n                        dy += dh;\n                    }\n                    ctx.restore();\n                    tmpCanvas = tmpCtx = null;\n                };\n            })()\n        });\n    });\n    /**\n     * @fileOverview Transport\n     * @todo 支持chunked传输，优势：\n     * 可以将大文件分成小块，挨个传输，可以提高大文件成功率，当失败的时候，也只需要重传那小部分，\n     * 而不需要重头再传一次。另外断点续传也需要用chunked方式。\n     */\n    define('runtime/html5/transport',[\n        'base',\n        'runtime/html5/runtime'\n    ], function( Base, Html5Runtime ) {\n    \n        var noop = Base.noop,\n            $ = Base.$;\n    \n        return Html5Runtime.register( 'Transport', {\n            init: function() {\n                this._status = 0;\n                this._response = null;\n            },\n    \n            send: function() {\n                var owner = this.owner,\n                    opts = this.options,\n                    xhr = this._initAjax(),\n                    blob = owner._blob,\n                    server = opts.server,\n                    formData, binary, fr;\n    \n                if ( opts.sendAsBinary ) {\n                    server += (/\\?/.test( server ) ? '&' : '?') +\n                            $.param( owner._formData );\n    \n                    binary = blob.getSource();\n                } else {\n                    formData = new FormData();\n                    $.each( owner._formData, function( k, v ) {\n                        formData.append( k, v );\n                    });\n    \n                    formData.append( opts.fileVal, blob.getSource(),\n                            opts.filename || owner._formData.name || '' );\n                }\n    \n                if ( opts.withCredentials && 'withCredentials' in xhr ) {\n                    xhr.open( opts.method, server, true );\n                    xhr.withCredentials = true;\n                } else {\n                    xhr.open( opts.method, server );\n                }\n    \n                this._setRequestHeader( xhr, opts.headers );\n    \n                if ( binary ) {\n                    xhr.overrideMimeType('application/octet-stream');\n    \n                    // android直接发送blob会导致服务端接收到的是空文件。\n                    // bug详情。\n                    // https://code.google.com/p/android/issues/detail?id=39882\n                    // 所以先用fileReader读取出来再通过arraybuffer的方式发送。\n                    if ( Base.os.android ) {\n                        fr = new FileReader();\n    \n                        fr.onload = function() {\n                            xhr.send( this.result );\n                            fr = fr.onload = null;\n                        };\n    \n                        fr.readAsArrayBuffer( binary );\n                    } else {\n                        xhr.send( binary );\n                    }\n                } else {\n                    xhr.send( formData );\n                }\n            },\n    \n            getResponse: function() {\n                return this._response;\n            },\n    \n            getResponseAsJson: function() {\n                return this._parseJson( this._response );\n            },\n    \n            getStatus: function() {\n                return this._status;\n            },\n    \n            abort: function() {\n                var xhr = this._xhr;\n    \n                if ( xhr ) {\n                    xhr.upload.onprogress = noop;\n                    xhr.onreadystatechange = noop;\n                    xhr.abort();\n    \n                    this._xhr = xhr = null;\n                }\n            },\n    \n            destroy: function() {\n                this.abort();\n            },\n    \n            _initAjax: function() {\n                var me = this,\n                    xhr = new XMLHttpRequest(),\n                    opts = this.options;\n    \n                if ( opts.withCredentials && !('withCredentials' in xhr) &&\n                        typeof XDomainRequest !== 'undefined' ) {\n                    xhr = new XDomainRequest();\n                }\n    \n                xhr.upload.onprogress = function( e ) {\n                    var percentage = 0;\n    \n                    if ( e.lengthComputable ) {\n                        percentage = e.loaded / e.total;\n                    }\n    \n                    return me.trigger( 'progress', percentage );\n                };\n    \n                xhr.onreadystatechange = function() {\n    \n                    if ( xhr.readyState !== 4 ) {\n                        return;\n                    }\n    \n                    xhr.upload.onprogress = noop;\n                    xhr.onreadystatechange = noop;\n                    me._xhr = null;\n                    me._status = xhr.status;\n    \n                    if ( xhr.status >= 200 && xhr.status < 300 ) {\n                        me._response = xhr.responseText;\n                        return me.trigger('load');\n                    } else if ( xhr.status >= 500 && xhr.status < 600 ) {\n                        me._response = xhr.responseText;\n                        return me.trigger( 'error', 'server' );\n                    }\n    \n    \n                    return me.trigger( 'error', me._status ? 'http' : 'abort' );\n                };\n    \n                me._xhr = xhr;\n                return xhr;\n            },\n    \n            _setRequestHeader: function( xhr, headers ) {\n                $.each( headers, function( key, val ) {\n                    xhr.setRequestHeader( key, val );\n                });\n            },\n    \n            _parseJson: function( str ) {\n                var json;\n    \n                try {\n                    json = JSON.parse( str );\n                } catch ( ex ) {\n                    json = {};\n                }\n    \n                return json;\n            }\n        });\n    });\n    /**\n     * @fileOverview 只有html5实现的文件版本。\n     */\n    define('preset/html5only',[\n        'base',\n    \n        // widgets\n        'widgets/filednd',\n        'widgets/filepaste',\n        'widgets/filepicker',\n        'widgets/image',\n        'widgets/queue',\n        'widgets/runtime',\n        'widgets/upload',\n        'widgets/validator',\n    \n        // runtimes\n        // html5\n        'runtime/html5/blob',\n        'runtime/html5/dnd',\n        'runtime/html5/filepaste',\n        'runtime/html5/filepicker',\n        'runtime/html5/imagemeta/exif',\n        'runtime/html5/image',\n        'runtime/html5/transport'\n    ], function( Base ) {\n        return Base;\n    });\n    define('webuploader',[\n        'preset/html5only'\n    ], function( preset ) {\n        return preset;\n    });\n    return require('webuploader');\n});\n"
  },
  {
    "path": "public/static/ueditor/third-party/webuploader/webuploader.js",
    "content": "/*! WebUploader 0.1.2 */\n\n\n/**\n * @fileOverview 让内部各个部件的代码可以用[amd](https://github.com/amdjs/amdjs-api/wiki/AMD)模块定义方式组织起来。\n *\n * AMD API 内部的简单不完全实现，请忽略。只有当WebUploader被合并成一个文件的时候才会引入。\n */\n(function( root, factory ) {\n    var modules = {},\n\n        // 内部require, 简单不完全实现。\n        // https://github.com/amdjs/amdjs-api/wiki/require\n        _require = function( deps, callback ) {\n            var args, len, i;\n\n            // 如果deps不是数组，则直接返回指定module\n            if ( typeof deps === 'string' ) {\n                return getModule( deps );\n            } else {\n                args = [];\n                for( len = deps.length, i = 0; i < len; i++ ) {\n                    args.push( getModule( deps[ i ] ) );\n                }\n\n                return callback.apply( null, args );\n            }\n        },\n\n        // 内部define，暂时不支持不指定id.\n        _define = function( id, deps, factory ) {\n            if ( arguments.length === 2 ) {\n                factory = deps;\n                deps = null;\n            }\n\n            _require( deps || [], function() {\n                setModule( id, factory, arguments );\n            });\n        },\n\n        // 设置module, 兼容CommonJs写法。\n        setModule = function( id, factory, args ) {\n            var module = {\n                    exports: factory\n                },\n                returned;\n\n            if ( typeof factory === 'function' ) {\n                args.length || (args = [ _require, module.exports, module ]);\n                returned = factory.apply( null, args );\n                returned !== undefined && (module.exports = returned);\n            }\n\n            modules[ id ] = module.exports;\n        },\n\n        // 根据id获取module\n        getModule = function( id ) {\n            var module = modules[ id ] || root[ id ];\n\n            if ( !module ) {\n                throw new Error( '`' + id + '` is undefined' );\n            }\n\n            return module;\n        },\n\n        // 将所有modules，将路径ids装换成对象。\n        exportsTo = function( obj ) {\n            var key, host, parts, part, last, ucFirst;\n\n            // make the first character upper case.\n            ucFirst = function( str ) {\n                return str && (str.charAt( 0 ).toUpperCase() + str.substr( 1 ));\n            };\n\n            for ( key in modules ) {\n                host = obj;\n\n                if ( !modules.hasOwnProperty( key ) ) {\n                    continue;\n                }\n\n                parts = key.split('/');\n                last = ucFirst( parts.pop() );\n\n                while( (part = ucFirst( parts.shift() )) ) {\n                    host[ part ] = host[ part ] || {};\n                    host = host[ part ];\n                }\n\n                host[ last ] = modules[ key ];\n            }\n        },\n\n        exports = factory( root, _define, _require ),\n        origin;\n\n    // exports every module.\n    exportsTo( exports );\n\n    if ( typeof module === 'object' && typeof module.exports === 'object' ) {\n\n        // For CommonJS and CommonJS-like environments where a proper window is present,\n        module.exports = exports;\n    } else if ( typeof define === 'function' && define.amd ) {\n\n        // Allow using this built library as an AMD module\n        // in another project. That other project will only\n        // see this AMD call, not the internal modules in\n        // the closure below.\n        define([], exports );\n    } else {\n\n        // Browser globals case. Just assign the\n        // result to a property on the global.\n        origin = root.WebUploader;\n        root.WebUploader = exports;\n        root.WebUploader.noConflict = function() {\n            root.WebUploader = origin;\n        };\n    }\n})( this, function( window, define, require ) {\n\n\n    /**\n     * @fileOverview jQuery or Zepto\n     */\n    define('dollar-third',[],function() {\n        return window.jQuery || window.Zepto;\n    });\n    /**\n     * @fileOverview Dom 操作相关\n     */\n    define('dollar',[\n        'dollar-third'\n    ], function( _ ) {\n        return _;\n    });\n    /**\n     * @fileOverview 使用jQuery的Promise\n     */\n    define('promise-third',[\n        'dollar'\n    ], function( $ ) {\n        return {\n            Deferred: $.Deferred,\n            when: $.when,\n    \n            isPromise: function( anything ) {\n                return anything && typeof anything.then === 'function';\n            }\n        };\n    });\n    /**\n     * @fileOverview Promise/A+\n     */\n    define('promise',[\n        'promise-third'\n    ], function( _ ) {\n        return _;\n    });\n    /**\n     * @fileOverview 基础类方法。\n     */\n    \n    /**\n     * Web Uploader内部类的详细说明，以下提及的功能类，都可以在`WebUploader`这个变量中访问到。\n     *\n     * As you know, Web Uploader的每个文件都是用过[AMD](https://github.com/amdjs/amdjs-api/wiki/AMD)规范中的`define`组织起来的, 每个Module都会有个module id.\n     * 默认module id该文件的路径，而此路径将会转化成名字空间存放在WebUploader中。如：\n     *\n     * * module `base`：WebUploader.Base\n     * * module `file`: WebUploader.File\n     * * module `lib/dnd`: WebUploader.Lib.Dnd\n     * * module `runtime/html5/dnd`: WebUploader.Runtime.Html5.Dnd\n     *\n     *\n     * 以下文档将可能省略`WebUploader`前缀。\n     * @module WebUploader\n     * @title WebUploader API文档\n     */\n    define('base',[\n        'dollar',\n        'promise'\n    ], function( $, promise ) {\n    \n        var noop = function() {},\n            call = Function.call;\n    \n        // http://jsperf.com/uncurrythis\n        // 反科里化\n        function uncurryThis( fn ) {\n            return function() {\n                return call.apply( fn, arguments );\n            };\n        }\n    \n        function bindFn( fn, context ) {\n            return function() {\n                return fn.apply( context, arguments );\n            };\n        }\n    \n        function createObject( proto ) {\n            var f;\n    \n            if ( Object.create ) {\n                return Object.create( proto );\n            } else {\n                f = function() {};\n                f.prototype = proto;\n                return new f();\n            }\n        }\n    \n    \n        /**\n         * 基础类，提供一些简单常用的方法。\n         * @class Base\n         */\n        return {\n    \n            /**\n             * @property {String} version 当前版本号。\n             */\n            version: '0.1.2',\n    \n            /**\n             * @property {jQuery|Zepto} $ 引用依赖的jQuery或者Zepto对象。\n             */\n            $: $,\n    \n            Deferred: promise.Deferred,\n    \n            isPromise: promise.isPromise,\n    \n            when: promise.when,\n    \n            /**\n             * @description  简单的浏览器检查结果。\n             *\n             * * `webkit`  webkit版本号，如果浏览器为非webkit内核，此属性为`undefined`。\n             * * `chrome`  chrome浏览器版本号，如果浏览器为chrome，此属性为`undefined`。\n             * * `ie`  ie浏览器版本号，如果浏览器为非ie，此属性为`undefined`。**暂不支持ie10+**\n             * * `firefox`  firefox浏览器版本号，如果浏览器为非firefox，此属性为`undefined`。\n             * * `safari`  safari浏览器版本号，如果浏览器为非safari，此属性为`undefined`。\n             * * `opera`  opera浏览器版本号，如果浏览器为非opera，此属性为`undefined`。\n             *\n             * @property {Object} [browser]\n             */\n            browser: (function( ua ) {\n                var ret = {},\n                    webkit = ua.match( /WebKit\\/([\\d.]+)/ ),\n                    chrome = ua.match( /Chrome\\/([\\d.]+)/ ) ||\n                        ua.match( /CriOS\\/([\\d.]+)/ ),\n    \n                    ie = ua.match( /MSIE\\s([\\d\\.]+)/ ) ||\n                        ua.match(/(?:trident)(?:.*rv:([\\w.]+))?/i),\n                    firefox = ua.match( /Firefox\\/([\\d.]+)/ ),\n                    safari = ua.match( /Safari\\/([\\d.]+)/ ),\n                    opera = ua.match( /OPR\\/([\\d.]+)/ );\n    \n                webkit && (ret.webkit = parseFloat( webkit[ 1 ] ));\n                chrome && (ret.chrome = parseFloat( chrome[ 1 ] ));\n                ie && (ret.ie = parseFloat( ie[ 1 ] ));\n                firefox && (ret.firefox = parseFloat( firefox[ 1 ] ));\n                safari && (ret.safari = parseFloat( safari[ 1 ] ));\n                opera && (ret.opera = parseFloat( opera[ 1 ] ));\n    \n                return ret;\n            })( navigator.userAgent ),\n    \n            /**\n             * @description  操作系统检查结果。\n             *\n             * * `android`  如果在android浏览器环境下，此值为对应的android版本号，否则为`undefined`。\n             * * `ios` 如果在ios浏览器环境下，此值为对应的ios版本号，否则为`undefined`。\n             * @property {Object} [os]\n             */\n            os: (function( ua ) {\n                var ret = {},\n    \n                    // osx = !!ua.match( /\\(Macintosh\\; Intel / ),\n                    android = ua.match( /(?:Android);?[\\s\\/]+([\\d.]+)?/ ),\n                    ios = ua.match( /(?:iPad|iPod|iPhone).*OS\\s([\\d_]+)/ );\n    \n                // osx && (ret.osx = true);\n                android && (ret.android = parseFloat( android[ 1 ] ));\n                ios && (ret.ios = parseFloat( ios[ 1 ].replace( /_/g, '.' ) ));\n    \n                return ret;\n            })( navigator.userAgent ),\n    \n            /**\n             * 实现类与类之间的继承。\n             * @method inherits\n             * @grammar Base.inherits( super ) => child\n             * @grammar Base.inherits( super, protos ) => child\n             * @grammar Base.inherits( super, protos, statics ) => child\n             * @param  {Class} super 父类\n             * @param  {Object | Function} [protos] 子类或者对象。如果对象中包含constructor，子类将是用此属性值。\n             * @param  {Function} [protos.constructor] 子类构造器，不指定的话将创建个临时的直接执行父类构造器的方法。\n             * @param  {Object} [statics] 静态属性或方法。\n             * @return {Class} 返回子类。\n             * @example\n             * function Person() {\n             *     console.log( 'Super' );\n             * }\n             * Person.prototype.hello = function() {\n             *     console.log( 'hello' );\n             * };\n             *\n             * var Manager = Base.inherits( Person, {\n             *     world: function() {\n             *         console.log( 'World' );\n             *     }\n             * });\n             *\n             * // 因为没有指定构造器，父类的构造器将会执行。\n             * var instance = new Manager();    // => Super\n             *\n             * // 继承子父类的方法\n             * instance.hello();    // => hello\n             * instance.world();    // => World\n             *\n             * // 子类的__super__属性指向父类\n             * console.log( Manager.__super__ === Person );    // => true\n             */\n            inherits: function( Super, protos, staticProtos ) {\n                var child;\n    \n                if ( typeof protos === 'function' ) {\n                    child = protos;\n                    protos = null;\n                } else if ( protos && protos.hasOwnProperty('constructor') ) {\n                    child = protos.constructor;\n                } else {\n                    child = function() {\n                        return Super.apply( this, arguments );\n                    };\n                }\n    \n                // 复制静态方法\n                $.extend( true, child, Super, staticProtos || {} );\n    \n                /* jshint camelcase: false */\n    \n                // 让子类的__super__属性指向父类。\n                child.__super__ = Super.prototype;\n    \n                // 构建原型，添加原型方法或属性。\n                // 暂时用Object.create实现。\n                child.prototype = createObject( Super.prototype );\n                protos && $.extend( true, child.prototype, protos );\n    \n                return child;\n            },\n    \n            /**\n             * 一个不做任何事情的方法。可以用来赋值给默认的callback.\n             * @method noop\n             */\n            noop: noop,\n    \n            /**\n             * 返回一个新的方法，此方法将已指定的`context`来执行。\n             * @grammar Base.bindFn( fn, context ) => Function\n             * @method bindFn\n             * @example\n             * var doSomething = function() {\n             *         console.log( this.name );\n             *     },\n             *     obj = {\n             *         name: 'Object Name'\n             *     },\n             *     aliasFn = Base.bind( doSomething, obj );\n             *\n             *  aliasFn();    // => Object Name\n             *\n             */\n            bindFn: bindFn,\n    \n            /**\n             * 引用Console.log如果存在的话，否则引用一个[空函数loop](#WebUploader:Base.log)。\n             * @grammar Base.log( args... ) => undefined\n             * @method log\n             */\n            log: (function() {\n                if ( window.console ) {\n                    return bindFn( console.log, console );\n                }\n                return noop;\n            })(),\n    \n            nextTick: (function() {\n    \n                return function( cb ) {\n                    setTimeout( cb, 1 );\n                };\n    \n                // @bug 当浏览器不在当前窗口时就停了。\n                // var next = window.requestAnimationFrame ||\n                //     window.webkitRequestAnimationFrame ||\n                //     window.mozRequestAnimationFrame ||\n                //     function( cb ) {\n                //         window.setTimeout( cb, 1000 / 60 );\n                //     };\n    \n                // // fix: Uncaught TypeError: Illegal invocation\n                // return bindFn( next, window );\n            })(),\n    \n            /**\n             * 被[uncurrythis](http://www.2ality.com/2011/11/uncurrying-this.html)的数组slice方法。\n             * 将用来将非数组对象转化成数组对象。\n             * @grammar Base.slice( target, start[, end] ) => Array\n             * @method slice\n             * @example\n             * function doSomthing() {\n             *     var args = Base.slice( arguments, 1 );\n             *     console.log( args );\n             * }\n             *\n             * doSomthing( 'ignored', 'arg2', 'arg3' );    // => Array [\"arg2\", \"arg3\"]\n             */\n            slice: uncurryThis( [].slice ),\n    \n            /**\n             * 生成唯一的ID\n             * @method guid\n             * @grammar Base.guid() => String\n             * @grammar Base.guid( prefx ) => String\n             */\n            guid: (function() {\n                var counter = 0;\n    \n                return function( prefix ) {\n                    var guid = (+new Date()).toString( 32 ),\n                        i = 0;\n    \n                    for ( ; i < 5; i++ ) {\n                        guid += Math.floor( Math.random() * 65535 ).toString( 32 );\n                    }\n    \n                    return (prefix || 'wu_') + guid + (counter++).toString( 32 );\n                };\n            })(),\n    \n            /**\n             * 格式化文件大小, 输出成带单位的字符串\n             * @method formatSize\n             * @grammar Base.formatSize( size ) => String\n             * @grammar Base.formatSize( size, pointLength ) => String\n             * @grammar Base.formatSize( size, pointLength, units ) => String\n             * @param {Number} size 文件大小\n             * @param {Number} [pointLength=2] 精确到的小数点数。\n             * @param {Array} [units=[ 'B', 'K', 'M', 'G', 'TB' ]] 单位数组。从字节，到千字节，一直往上指定。如果单位数组里面只指定了到了K(千字节)，同时文件大小大于M, 此方法的输出将还是显示成多少K.\n             * @example\n             * console.log( Base.formatSize( 100 ) );    // => 100B\n             * console.log( Base.formatSize( 1024 ) );    // => 1.00K\n             * console.log( Base.formatSize( 1024, 0 ) );    // => 1K\n             * console.log( Base.formatSize( 1024 * 1024 ) );    // => 1.00M\n             * console.log( Base.formatSize( 1024 * 1024 * 1024 ) );    // => 1.00G\n             * console.log( Base.formatSize( 1024 * 1024 * 1024, 0, ['B', 'KB', 'MB'] ) );    // => 1024MB\n             */\n            formatSize: function( size, pointLength, units ) {\n                var unit;\n    \n                units = units || [ 'B', 'K', 'M', 'G', 'TB' ];\n    \n                while ( (unit = units.shift()) && size > 1024 ) {\n                    size = size / 1024;\n                }\n    \n                return (unit === 'B' ? size : size.toFixed( pointLength || 2 )) +\n                        unit;\n            }\n        };\n    });\n    /**\n     * 事件处理类，可以独立使用，也可以扩展给对象使用。\n     * @fileOverview Mediator\n     */\n    define('mediator',[\n        'base'\n    ], function( Base ) {\n        var $ = Base.$,\n            slice = [].slice,\n            separator = /\\s+/,\n            protos;\n    \n        // 根据条件过滤出事件handlers.\n        function findHandlers( arr, name, callback, context ) {\n            return $.grep( arr, function( handler ) {\n                return handler &&\n                        (!name || handler.e === name) &&\n                        (!callback || handler.cb === callback ||\n                        handler.cb._cb === callback) &&\n                        (!context || handler.ctx === context);\n            });\n        }\n    \n        function eachEvent( events, callback, iterator ) {\n            // 不支持对象，只支持多个event用空格隔开\n            $.each( (events || '').split( separator ), function( _, key ) {\n                iterator( key, callback );\n            });\n        }\n    \n        function triggerHanders( events, args ) {\n            var stoped = false,\n                i = -1,\n                len = events.length,\n                handler;\n    \n            while ( ++i < len ) {\n                handler = events[ i ];\n    \n                if ( handler.cb.apply( handler.ctx2, args ) === false ) {\n                    stoped = true;\n                    break;\n                }\n            }\n    \n            return !stoped;\n        }\n    \n        protos = {\n    \n            /**\n             * 绑定事件。\n             *\n             * `callback`方法在执行时，arguments将会来源于trigger的时候携带的参数。如\n             * ```javascript\n             * var obj = {};\n             *\n             * // 使得obj有事件行为\n             * Mediator.installTo( obj );\n             *\n             * obj.on( 'testa', function( arg1, arg2 ) {\n             *     console.log( arg1, arg2 ); // => 'arg1', 'arg2'\n             * });\n             *\n             * obj.trigger( 'testa', 'arg1', 'arg2' );\n             * ```\n             *\n             * 如果`callback`中，某一个方法`return false`了，则后续的其他`callback`都不会被执行到。\n             * 切会影响到`trigger`方法的返回值，为`false`。\n             *\n             * `on`还可以用来添加一个特殊事件`all`, 这样所有的事件触发都会响应到。同时此类`callback`中的arguments有一个不同处，\n             * 就是第一个参数为`type`，记录当前是什么事件在触发。此类`callback`的优先级比脚低，会再正常`callback`执行完后触发。\n             * ```javascript\n             * obj.on( 'all', function( type, arg1, arg2 ) {\n             *     console.log( type, arg1, arg2 ); // => 'testa', 'arg1', 'arg2'\n             * });\n             * ```\n             *\n             * @method on\n             * @grammar on( name, callback[, context] ) => self\n             * @param  {String}   name     事件名，支持多个事件用空格隔开\n             * @param  {Function} callback 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             * @class Mediator\n             */\n            on: function( name, callback, context ) {\n                var me = this,\n                    set;\n    \n                if ( !callback ) {\n                    return this;\n                }\n    \n                set = this._events || (this._events = []);\n    \n                eachEvent( name, callback, function( name, callback ) {\n                    var handler = { e: name };\n    \n                    handler.cb = callback;\n                    handler.ctx = context;\n                    handler.ctx2 = context || me;\n                    handler.id = set.length;\n    \n                    set.push( handler );\n                });\n    \n                return this;\n            },\n    \n            /**\n             * 绑定事件，且当handler执行完后，自动解除绑定。\n             * @method once\n             * @grammar once( name, callback[, context] ) => self\n             * @param  {String}   name     事件名\n             * @param  {Function} callback 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             */\n            once: function( name, callback, context ) {\n                var me = this;\n    \n                if ( !callback ) {\n                    return me;\n                }\n    \n                eachEvent( name, callback, function( name, callback ) {\n                    var once = function() {\n                            me.off( name, once );\n                            return callback.apply( context || me, arguments );\n                        };\n    \n                    once._cb = callback;\n                    me.on( name, once, context );\n                });\n    \n                return me;\n            },\n    \n            /**\n             * 解除事件绑定\n             * @method off\n             * @grammar off( [name[, callback[, context] ] ] ) => self\n             * @param  {String}   [name]     事件名\n             * @param  {Function} [callback] 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             */\n            off: function( name, cb, ctx ) {\n                var events = this._events;\n    \n                if ( !events ) {\n                    return this;\n                }\n    \n                if ( !name && !cb && !ctx ) {\n                    this._events = [];\n                    return this;\n                }\n    \n                eachEvent( name, cb, function( name, cb ) {\n                    $.each( findHandlers( events, name, cb, ctx ), function() {\n                        delete events[ this.id ];\n                    });\n                });\n    \n                return this;\n            },\n    \n            /**\n             * 触发事件\n             * @method trigger\n             * @grammar trigger( name[, args...] ) => self\n             * @param  {String}   type     事件名\n             * @param  {*} [...] 任意参数\n             * @return {Boolean} 如果handler中return false了，则返回false, 否则返回true\n             */\n            trigger: function( type ) {\n                var args, events, allEvents;\n    \n                if ( !this._events || !type ) {\n                    return this;\n                }\n    \n                args = slice.call( arguments, 1 );\n                events = findHandlers( this._events, type );\n                allEvents = findHandlers( this._events, 'all' );\n    \n                return triggerHanders( events, args ) &&\n                        triggerHanders( allEvents, arguments );\n            }\n        };\n    \n        /**\n         * 中介者，它本身是个单例，但可以通过[installTo](#WebUploader:Mediator:installTo)方法，使任何对象具备事件行为。\n         * 主要目的是负责模块与模块之间的合作，降低耦合度。\n         *\n         * @class Mediator\n         */\n        return $.extend({\n    \n            /**\n             * 可以通过这个接口，使任何对象具备事件功能。\n             * @method installTo\n             * @param  {Object} obj 需要具备事件行为的对象。\n             * @return {Object} 返回obj.\n             */\n            installTo: function( obj ) {\n                return $.extend( obj, protos );\n            }\n    \n        }, protos );\n    });\n    /**\n     * @fileOverview Uploader上传类\n     */\n    define('uploader',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$;\n    \n        /**\n         * 上传入口类。\n         * @class Uploader\n         * @constructor\n         * @grammar new Uploader( opts ) => Uploader\n         * @example\n         * var uploader = WebUploader.Uploader({\n         *     swf: 'path_of_swf/Uploader.swf',\n         *\n         *     // 开起分片上传。\n         *     chunked: true\n         * });\n         */\n        function Uploader( opts ) {\n            this.options = $.extend( true, {}, Uploader.options, opts );\n            this._init( this.options );\n        }\n    \n        // default Options\n        // widgets中有相应扩展\n        Uploader.options = {};\n        Mediator.installTo( Uploader.prototype );\n    \n        // 批量添加纯命令式方法。\n        $.each({\n            upload: 'start-upload',\n            stop: 'stop-upload',\n            getFile: 'get-file',\n            getFiles: 'get-files',\n            addFile: 'add-file',\n            addFiles: 'add-file',\n            sort: 'sort-files',\n            removeFile: 'remove-file',\n            skipFile: 'skip-file',\n            retry: 'retry',\n            isInProgress: 'is-in-progress',\n            makeThumb: 'make-thumb',\n            getDimension: 'get-dimension',\n            addButton: 'add-btn',\n            getRuntimeType: 'get-runtime-type',\n            refresh: 'refresh',\n            disable: 'disable',\n            enable: 'enable',\n            reset: 'reset'\n        }, function( fn, command ) {\n            Uploader.prototype[ fn ] = function() {\n                return this.request( command, arguments );\n            };\n        });\n    \n        $.extend( Uploader.prototype, {\n            state: 'pending',\n    \n            _init: function( opts ) {\n                var me = this;\n    \n                me.request( 'init', opts, function() {\n                    me.state = 'ready';\n                    me.trigger('ready');\n                });\n            },\n    \n            /**\n             * 获取或者设置Uploader配置项。\n             * @method option\n             * @grammar option( key ) => *\n             * @grammar option( key, val ) => self\n             * @example\n             *\n             * // 初始状态图片上传前不会压缩\n             * var uploader = new WebUploader.Uploader({\n             *     resize: null;\n             * });\n             *\n             * // 修改后图片上传前，尝试将图片压缩到1600 * 1600\n             * uploader.options( 'resize', {\n             *     width: 1600,\n             *     height: 1600\n             * });\n             */\n            option: function( key, val ) {\n                var opts = this.options;\n    \n                // setter\n                if ( arguments.length > 1 ) {\n    \n                    if ( $.isPlainObject( val ) &&\n                            $.isPlainObject( opts[ key ] ) ) {\n                        $.extend( opts[ key ], val );\n                    } else {\n                        opts[ key ] = val;\n                    }\n    \n                } else {    // getter\n                    return key ? opts[ key ] : opts;\n                }\n            },\n    \n            /**\n             * 获取文件统计信息。返回一个包含一下信息的对象。\n             * * `successNum` 上传成功的文件数\n             * * `uploadFailNum` 上传失败的文件数\n             * * `cancelNum` 被删除的文件数\n             * * `invalidNum` 无效的文件数\n             * * `queueNum` 还在队列中的文件数\n             * @method getStats\n             * @grammar getStats() => Object\n             */\n            getStats: function() {\n                // return this._mgr.getStats.apply( this._mgr, arguments );\n                var stats = this.request('get-stats');\n    \n                return {\n                    successNum: stats.numOfSuccess,\n    \n                    // who care?\n                    // queueFailNum: 0,\n                    cancelNum: stats.numOfCancel,\n                    invalidNum: stats.numOfInvalid,\n                    uploadFailNum: stats.numOfUploadFailed,\n                    queueNum: stats.numOfQueue\n                };\n            },\n    \n            // 需要重写此方法来来支持opts.onEvent和instance.onEvent的处理器\n            trigger: function( type/*, args...*/ ) {\n                var args = [].slice.call( arguments, 1 ),\n                    opts = this.options,\n                    name = 'on' + type.substring( 0, 1 ).toUpperCase() +\n                        type.substring( 1 );\n    \n                if (\n                        // 调用通过on方法注册的handler.\n                        Mediator.trigger.apply( this, arguments ) === false ||\n    \n                        // 调用opts.onEvent\n                        $.isFunction( opts[ name ] ) &&\n                        opts[ name ].apply( this, args ) === false ||\n    \n                        // 调用this.onEvent\n                        $.isFunction( this[ name ] ) &&\n                        this[ name ].apply( this, args ) === false ||\n    \n                        // 广播所有uploader的事件。\n                        Mediator.trigger.apply( Mediator,\n                        [ this, type ].concat( args ) ) === false ) {\n    \n                    return false;\n                }\n    \n                return true;\n            },\n    \n            // widgets/widget.js将补充此方法的详细文档。\n            request: Base.noop\n        });\n    \n        /**\n         * 创建Uploader实例，等同于new Uploader( opts );\n         * @method create\n         * @class Base\n         * @static\n         * @grammar Base.create( opts ) => Uploader\n         */\n        Base.create = Uploader.create = function( opts ) {\n            return new Uploader( opts );\n        };\n    \n        // 暴露Uploader，可以通过它来扩展业务逻辑。\n        Base.Uploader = Uploader;\n    \n        return Uploader;\n    });\n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/runtime',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$,\n            factories = {},\n    \n            // 获取对象的第一个key\n            getFirstKey = function( obj ) {\n                for ( var key in obj ) {\n                    if ( obj.hasOwnProperty( key ) ) {\n                        return key;\n                    }\n                }\n                return null;\n            };\n    \n        // 接口类。\n        function Runtime( options ) {\n            this.options = $.extend({\n                container: document.body\n            }, options );\n            this.uid = Base.guid('rt_');\n        }\n    \n        $.extend( Runtime.prototype, {\n    \n            getContainer: function() {\n                var opts = this.options,\n                    parent, container;\n    \n                if ( this._container ) {\n                    return this._container;\n                }\n    \n                parent = $( opts.container || document.body );\n                container = $( document.createElement('div') );\n    \n                container.attr( 'id', 'rt_' + this.uid );\n                container.css({\n                    position: 'absolute',\n                    top: '0px',\n                    left: '0px',\n                    width: '1px',\n                    height: '1px',\n                    overflow: 'hidden'\n                });\n    \n                parent.append( container );\n                parent.addClass('webuploader-container');\n                this._container = container;\n                return container;\n            },\n    \n            init: Base.noop,\n            exec: Base.noop,\n    \n            destroy: function() {\n                if ( this._container ) {\n                    this._container.parentNode.removeChild( this.__container );\n                }\n    \n                this.off();\n            }\n        });\n    \n        Runtime.orders = 'html5,flash';\n    \n    \n        /**\n         * 添加Runtime实现。\n         * @param {String} type    类型\n         * @param {Runtime} factory 具体Runtime实现。\n         */\n        Runtime.addRuntime = function( type, factory ) {\n            factories[ type ] = factory;\n        };\n    \n        Runtime.hasRuntime = function( type ) {\n            return !!(type ? factories[ type ] : getFirstKey( factories ));\n        };\n    \n        Runtime.create = function( opts, orders ) {\n            var type, runtime;\n    \n            orders = orders || Runtime.orders;\n            $.each( orders.split( /\\s*,\\s*/g ), function() {\n                if ( factories[ this ] ) {\n                    type = this;\n                    return false;\n                }\n            });\n    \n            type = type || getFirstKey( factories );\n    \n            if ( !type ) {\n                throw new Error('Runtime Error');\n            }\n    \n            runtime = new factories[ type ]( opts );\n            return runtime;\n        };\n    \n        Mediator.installTo( Runtime.prototype );\n        return Runtime;\n    });\n    \n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/client',[\n        'base',\n        'mediator',\n        'runtime/runtime'\n    ], function( Base, Mediator, Runtime ) {\n    \n        var cache;\n    \n        cache = (function() {\n            var obj = {};\n    \n            return {\n                add: function( runtime ) {\n                    obj[ runtime.uid ] = runtime;\n                },\n    \n                get: function( ruid, standalone ) {\n                    var i;\n    \n                    if ( ruid ) {\n                        return obj[ ruid ];\n                    }\n    \n                    for ( i in obj ) {\n                        // 有些类型不能重用，比如filepicker.\n                        if ( standalone && obj[ i ].__standalone ) {\n                            continue;\n                        }\n    \n                        return obj[ i ];\n                    }\n    \n                    return null;\n                },\n    \n                remove: function( runtime ) {\n                    delete obj[ runtime.uid ];\n                }\n            };\n        })();\n    \n        function RuntimeClient( component, standalone ) {\n            var deferred = Base.Deferred(),\n                runtime;\n    \n            this.uid = Base.guid('client_');\n    \n            // 允许runtime没有初始化之前，注册一些方法在初始化后执行。\n            this.runtimeReady = function( cb ) {\n                return deferred.done( cb );\n            };\n    \n            this.connectRuntime = function( opts, cb ) {\n    \n                // already connected.\n                if ( runtime ) {\n                    throw new Error('already connected!');\n                }\n    \n                deferred.done( cb );\n    \n                if ( typeof opts === 'string' && cache.get( opts ) ) {\n                    runtime = cache.get( opts );\n                }\n    \n                // 像filePicker只能独立存在，不能公用。\n                runtime = runtime || cache.get( null, standalone );\n    \n                // 需要创建\n                if ( !runtime ) {\n                    runtime = Runtime.create( opts, opts.runtimeOrder );\n                    runtime.__promise = deferred.promise();\n                    runtime.once( 'ready', deferred.resolve );\n                    runtime.init();\n                    cache.add( runtime );\n                    runtime.__client = 1;\n                } else {\n                    // 来自cache\n                    Base.$.extend( runtime.options, opts );\n                    runtime.__promise.then( deferred.resolve );\n                    runtime.__client++;\n                }\n    \n                standalone && (runtime.__standalone = standalone);\n                return runtime;\n            };\n    \n            this.getRuntime = function() {\n                return runtime;\n            };\n    \n            this.disconnectRuntime = function() {\n                if ( !runtime ) {\n                    return;\n                }\n    \n                runtime.__client--;\n    \n                if ( runtime.__client <= 0 ) {\n                    cache.remove( runtime );\n                    delete runtime.__promise;\n                    runtime.destroy();\n                }\n    \n                runtime = null;\n            };\n    \n            this.exec = function() {\n                if ( !runtime ) {\n                    return;\n                }\n    \n                var args = Base.slice( arguments );\n                component && args.unshift( component );\n    \n                return runtime.exec.apply( this, args );\n            };\n    \n            this.getRuid = function() {\n                return runtime && runtime.uid;\n            };\n    \n            this.destroy = (function( destroy ) {\n                return function() {\n                    destroy && destroy.apply( this, arguments );\n                    this.trigger('destroy');\n                    this.off();\n                    this.exec('destroy');\n                    this.disconnectRuntime();\n                };\n            })( this.destroy );\n        }\n    \n        Mediator.installTo( RuntimeClient.prototype );\n        return RuntimeClient;\n    });\n    /**\n     * @fileOverview 错误信息\n     */\n    define('lib/dnd',[\n        'base',\n        'mediator',\n        'runtime/client'\n    ], function( Base, Mediator, RuntimeClent ) {\n    \n        var $ = Base.$;\n    \n        function DragAndDrop( opts ) {\n            opts = this.options = $.extend({}, DragAndDrop.options, opts );\n    \n            opts.container = $( opts.container );\n    \n            if ( !opts.container.length ) {\n                return;\n            }\n    \n            RuntimeClent.call( this, 'DragAndDrop' );\n        }\n    \n        DragAndDrop.options = {\n            accept: null,\n            disableGlobalDnd: false\n        };\n    \n        Base.inherits( RuntimeClent, {\n            constructor: DragAndDrop,\n    \n            init: function() {\n                var me = this;\n    \n                me.connectRuntime( me.options, function() {\n                    me.exec('init');\n                    me.trigger('ready');\n                });\n            },\n    \n            destroy: function() {\n                this.disconnectRuntime();\n            }\n        });\n    \n        Mediator.installTo( DragAndDrop.prototype );\n    \n        return DragAndDrop;\n    });\n    /**\n     * @fileOverview 组件基类。\n     */\n    define('widgets/widget',[\n        'base',\n        'uploader'\n    ], function( Base, Uploader ) {\n    \n        var $ = Base.$,\n            _init = Uploader.prototype._init,\n            IGNORE = {},\n            widgetClass = [];\n    \n        function isArrayLike( obj ) {\n            if ( !obj ) {\n                return false;\n            }\n    \n            var length = obj.length,\n                type = $.type( obj );\n    \n            if ( obj.nodeType === 1 && length ) {\n                return true;\n            }\n    \n            return type === 'array' || type !== 'function' && type !== 'string' &&\n                    (length === 0 || typeof length === 'number' && length > 0 &&\n                    (length - 1) in obj);\n        }\n    \n        function Widget( uploader ) {\n            this.owner = uploader;\n            this.options = uploader.options;\n        }\n    \n        $.extend( Widget.prototype, {\n    \n            init: Base.noop,\n    \n            // 类Backbone的事件监听声明，监听uploader实例上的事件\n            // widget直接无法监听事件，事件只能通过uploader来传递\n            invoke: function( apiName, args ) {\n    \n                /*\n                    {\n                        'make-thumb': 'makeThumb'\n                    }\n                 */\n                var map = this.responseMap;\n    \n                // 如果无API响应声明则忽略\n                if ( !map || !(apiName in map) || !(map[ apiName ] in this) ||\n                        !$.isFunction( this[ map[ apiName ] ] ) ) {\n    \n                    return IGNORE;\n                }\n    \n                return this[ map[ apiName ] ].apply( this, args );\n    \n            },\n    \n            /**\n             * 发送命令。当传入`callback`或者`handler`中返回`promise`时。返回一个当所有`handler`中的promise都完成后完成的新`promise`。\n             * @method request\n             * @grammar request( command, args ) => * | Promise\n             * @grammar request( command, args, callback ) => Promise\n             * @for  Uploader\n             */\n            request: function() {\n                return this.owner.request.apply( this.owner, arguments );\n            }\n        });\n    \n        // 扩展Uploader.\n        $.extend( Uploader.prototype, {\n    \n            // 覆写_init用来初始化widgets\n            _init: function() {\n                var me = this,\n                    widgets = me._widgets = [];\n    \n                $.each( widgetClass, function( _, klass ) {\n                    widgets.push( new klass( me ) );\n                });\n    \n                return _init.apply( me, arguments );\n            },\n    \n            request: function( apiName, args, callback ) {\n                var i = 0,\n                    widgets = this._widgets,\n                    len = widgets.length,\n                    rlts = [],\n                    dfds = [],\n                    widget, rlt, promise, key;\n    \n                args = isArrayLike( args ) ? args : [ args ];\n    \n                for ( ; i < len; i++ ) {\n                    widget = widgets[ i ];\n                    rlt = widget.invoke( apiName, args );\n    \n                    if ( rlt !== IGNORE ) {\n    \n                        // Deferred对象\n                        if ( Base.isPromise( rlt ) ) {\n                            dfds.push( rlt );\n                        } else {\n                            rlts.push( rlt );\n                        }\n                    }\n                }\n    \n                // 如果有callback，则用异步方式。\n                if ( callback || dfds.length ) {\n                    promise = Base.when.apply( Base, dfds );\n                    key = promise.pipe ? 'pipe' : 'then';\n    \n                    // 很重要不能删除。删除了会死循环。\n                    // 保证执行顺序。让callback总是在下一个tick中执行。\n                    return promise[ key ](function() {\n                                var deferred = Base.Deferred(),\n                                    args = arguments;\n    \n                                setTimeout(function() {\n                                    deferred.resolve.apply( deferred, args );\n                                }, 1 );\n    \n                                return deferred.promise();\n                            })[ key ]( callback || Base.noop );\n                } else {\n                    return rlts[ 0 ];\n                }\n            }\n        });\n    \n        /**\n         * 添加组件\n         * @param  {object} widgetProto 组件原型，构造函数通过constructor属性定义\n         * @param  {object} responseMap API名称与函数实现的映射\n         * @example\n         *     Uploader.register( {\n         *         init: function( options ) {},\n         *         makeThumb: function() {}\n         *     }, {\n         *         'make-thumb': 'makeThumb'\n         *     } );\n         */\n        Uploader.register = Widget.register = function( responseMap, widgetProto ) {\n            var map = { init: 'init' },\n                klass;\n    \n            if ( arguments.length === 1 ) {\n                widgetProto = responseMap;\n                widgetProto.responseMap = map;\n            } else {\n                widgetProto.responseMap = $.extend( map, responseMap );\n            }\n    \n            klass = Base.inherits( Widget, widgetProto );\n            widgetClass.push( klass );\n    \n            return klass;\n        };\n    \n        return Widget;\n    });\n    /**\n     * @fileOverview DragAndDrop Widget。\n     */\n    define('widgets/filednd',[\n        'base',\n        'uploader',\n        'lib/dnd',\n        'widgets/widget'\n    ], function( Base, Uploader, Dnd ) {\n        var $ = Base.$;\n    \n        Uploader.options.dnd = '';\n    \n        /**\n         * @property {Selector} [dnd=undefined]  指定Drag And Drop拖拽的容器，如果不指定，则不启动。\n         * @namespace options\n         * @for Uploader\n         */\n    \n        /**\n         * @event dndAccept\n         * @param {DataTransferItemList} items DataTransferItem\n         * @description 阻止此事件可以拒绝某些类型的文件拖入进来。目前只有 chrome 提供这样的 API，且只能通过 mime-type 验证。\n         * @for  Uploader\n         */\n        return Uploader.register({\n            init: function( opts ) {\n    \n                if ( !opts.dnd ||\n                        this.request('predict-runtime-type') !== 'html5' ) {\n                    return;\n                }\n    \n                var me = this,\n                    deferred = Base.Deferred(),\n                    options = $.extend({}, {\n                        disableGlobalDnd: opts.disableGlobalDnd,\n                        container: opts.dnd,\n                        accept: opts.accept\n                    }),\n                    dnd;\n    \n                dnd = new Dnd( options );\n    \n                dnd.once( 'ready', deferred.resolve );\n                dnd.on( 'drop', function( files ) {\n                    me.request( 'add-file', [ files ]);\n                });\n    \n                // 检测文件是否全部允许添加。\n                dnd.on( 'accept', function( items ) {\n                    return me.owner.trigger( 'dndAccept', items );\n                });\n    \n                dnd.init();\n    \n                return deferred.promise();\n            }\n        });\n    });\n    \n    /**\n     * @fileOverview 错误信息\n     */\n    define('lib/filepaste',[\n        'base',\n        'mediator',\n        'runtime/client'\n    ], function( Base, Mediator, RuntimeClent ) {\n    \n        var $ = Base.$;\n    \n        function FilePaste( opts ) {\n            opts = this.options = $.extend({}, opts );\n            opts.container = $( opts.container || document.body );\n            RuntimeClent.call( this, 'FilePaste' );\n        }\n    \n        Base.inherits( RuntimeClent, {\n            constructor: FilePaste,\n    \n            init: function() {\n                var me = this;\n    \n                me.connectRuntime( me.options, function() {\n                    me.exec('init');\n                    me.trigger('ready');\n                });\n            },\n    \n            destroy: function() {\n                this.exec('destroy');\n                this.disconnectRuntime();\n                this.off();\n            }\n        });\n    \n        Mediator.installTo( FilePaste.prototype );\n    \n        return FilePaste;\n    });\n    /**\n     * @fileOverview 组件基类。\n     */\n    define('widgets/filepaste',[\n        'base',\n        'uploader',\n        'lib/filepaste',\n        'widgets/widget'\n    ], function( Base, Uploader, FilePaste ) {\n        var $ = Base.$;\n    \n        /**\n         * @property {Selector} [paste=undefined]  指定监听paste事件的容器，如果不指定，不启用此功能。此功能为通过粘贴来添加截屏的图片。建议设置为`document.body`.\n         * @namespace options\n         * @for Uploader\n         */\n        return Uploader.register({\n            init: function( opts ) {\n    \n                if ( !opts.paste ||\n                        this.request('predict-runtime-type') !== 'html5' ) {\n                    return;\n                }\n    \n                var me = this,\n                    deferred = Base.Deferred(),\n                    options = $.extend({}, {\n                        container: opts.paste,\n                        accept: opts.accept\n                    }),\n                    paste;\n    \n                paste = new FilePaste( options );\n    \n                paste.once( 'ready', deferred.resolve );\n                paste.on( 'paste', function( files ) {\n                    me.owner.request( 'add-file', [ files ]);\n                });\n                paste.init();\n    \n                return deferred.promise();\n            }\n        });\n    });\n    /**\n     * @fileOverview Blob\n     */\n    define('lib/blob',[\n        'base',\n        'runtime/client'\n    ], function( Base, RuntimeClient ) {\n    \n        function Blob( ruid, source ) {\n            var me = this;\n    \n            me.source = source;\n            me.ruid = ruid;\n    \n            RuntimeClient.call( me, 'Blob' );\n    \n            this.uid = source.uid || this.uid;\n            this.type = source.type || '';\n            this.size = source.size || 0;\n    \n            if ( ruid ) {\n                me.connectRuntime( ruid );\n            }\n        }\n    \n        Base.inherits( RuntimeClient, {\n            constructor: Blob,\n    \n            slice: function( start, end ) {\n                return this.exec( 'slice', start, end );\n            },\n    \n            getSource: function() {\n                return this.source;\n            }\n        });\n    \n        return Blob;\n    });\n    /**\n     * 为了统一化Flash的File和HTML5的File而存在。\n     * 以至于要调用Flash里面的File，也可以像调用HTML5版本的File一下。\n     * @fileOverview File\n     */\n    define('lib/file',[\n        'base',\n        'lib/blob'\n    ], function( Base, Blob ) {\n    \n        var uid = 1,\n            rExt = /\\.([^.]+)$/;\n    \n        function File( ruid, file ) {\n            var ext;\n    \n            Blob.apply( this, arguments );\n            this.name = file.name || ('untitled' + uid++);\n            ext = rExt.exec( file.name ) ? RegExp.$1.toLowerCase() : '';\n    \n            // todo 支持其他类型文件的转换。\n    \n            // 如果有mimetype, 但是文件名里面没有找出后缀规律\n            if ( !ext && this.type ) {\n                ext = /\\/(jpg|jpeg|png|gif|bmp)$/i.exec( this.type ) ?\n                        RegExp.$1.toLowerCase() : '';\n                this.name += '.' + ext;\n            }\n    \n            // 如果没有指定mimetype, 但是知道文件后缀。\n            if ( !this.type &&  ~'jpg,jpeg,png,gif,bmp'.indexOf( ext ) ) {\n                this.type = 'image/' + (ext === 'jpg' ? 'jpeg' : ext);\n            }\n    \n            this.ext = ext;\n            this.lastModifiedDate = file.lastModifiedDate ||\n                    (new Date()).toLocaleString();\n        }\n    \n        return Base.inherits( Blob, File );\n    });\n    \n    /**\n     * @fileOverview 错误信息\n     */\n    define('lib/filepicker',[\n        'base',\n        'runtime/client',\n        'lib/file'\n    ], function( Base, RuntimeClent, File ) {\n    \n        var $ = Base.$;\n    \n        function FilePicker( opts ) {\n            opts = this.options = $.extend({}, FilePicker.options, opts );\n    \n            opts.container = $( opts.id );\n    \n            if ( !opts.container.length ) {\n                throw new Error('按钮指定错误');\n            }\n    \n            opts.innerHTML = opts.innerHTML || opts.label ||\n                    opts.container.html() || '';\n    \n            opts.button = $( opts.button || document.createElement('div') );\n            opts.button.html( opts.innerHTML );\n            opts.container.html( opts.button );\n    \n            RuntimeClent.call( this, 'FilePicker', true );\n        }\n    \n        FilePicker.options = {\n            button: null,\n            container: null,\n            label: null,\n            innerHTML: null,\n            multiple: true,\n            accept: null,\n            name: 'file'\n        };\n    \n        Base.inherits( RuntimeClent, {\n            constructor: FilePicker,\n    \n            init: function() {\n                var me = this,\n                    opts = me.options,\n                    button = opts.button;\n    \n                button.addClass('webuploader-pick');\n    \n                me.on( 'all', function( type ) {\n                    var files;\n    \n                    switch ( type ) {\n                        case 'mouseenter':\n                            button.addClass('webuploader-pick-hover');\n                            break;\n    \n                        case 'mouseleave':\n                            button.removeClass('webuploader-pick-hover');\n                            break;\n    \n                        case 'change':\n                            files = me.exec('getFiles');\n                            me.trigger( 'select', $.map( files, function( file ) {\n                                file = new File( me.getRuid(), file );\n    \n                                // 记录来源。\n                                file._refer = opts.container;\n                                return file;\n                            }), opts.container );\n                            break;\n                    }\n                });\n    \n                me.connectRuntime( opts, function() {\n                    me.refresh();\n                    me.exec( 'init', opts );\n                    me.trigger('ready');\n                });\n    \n                $( window ).on( 'resize', function() {\n                    me.refresh();\n                });\n            },\n    \n            refresh: function() {\n                var shimContainer = this.getRuntime().getContainer(),\n                    button = this.options.button,\n                    width = button.outerWidth ?\n                            button.outerWidth() : button.width(),\n    \n                    height = button.outerHeight ?\n                            button.outerHeight() : button.height(),\n    \n                    pos = button.offset();\n    \n                width && height && shimContainer.css({\n                    bottom: 'auto',\n                    right: 'auto',\n                    width: width + 'px',\n                    height: height + 'px'\n                }).offset( pos );\n            },\n    \n            enable: function() {\n                var btn = this.options.button;\n    \n                btn.removeClass('webuploader-pick-disable');\n                this.refresh();\n            },\n    \n            disable: function() {\n                var btn = this.options.button;\n    \n                this.getRuntime().getContainer().css({\n                    top: '-99999px'\n                });\n    \n                btn.addClass('webuploader-pick-disable');\n            },\n    \n            destroy: function() {\n                if ( this.runtime ) {\n                    this.exec('destroy');\n                    this.disconnectRuntime();\n                }\n            }\n        });\n    \n        return FilePicker;\n    });\n    \n    /**\n     * @fileOverview 文件选择相关\n     */\n    define('widgets/filepicker',[\n        'base',\n        'uploader',\n        'lib/filepicker',\n        'widgets/widget'\n    ], function( Base, Uploader, FilePicker ) {\n        var $ = Base.$;\n    \n        $.extend( Uploader.options, {\n    \n            /**\n             * @property {Selector | Object} [pick=undefined]\n             * @namespace options\n             * @for Uploader\n             * @description 指定选择文件的按钮容器，不指定则不创建按钮。\n             *\n             * * `id` {Seletor} 指定选择文件的按钮容器，不指定则不创建按钮。\n             * * `label` {String} 请采用 `innerHTML` 代替\n             * * `innerHTML` {String} 指定按钮文字。不指定时优先从指定的容器中看是否自带文字。\n             * * `multiple` {Boolean} 是否开起同时选择多个文件能力。\n             */\n            pick: null,\n    \n            /**\n             * @property {Arroy} [accept=null]\n             * @namespace options\n             * @for Uploader\n             * @description 指定接受哪些类型的文件。 由于目前还有ext转mimeType表，所以这里需要分开指定。\n             *\n             * * `title` {String} 文字描述\n             * * `extensions` {String} 允许的文件后缀，不带点，多个用逗号分割。\n             * * `mimeTypes` {String} 多个用逗号分割。\n             *\n             * 如：\n             *\n             * ```\n             * {\n             *     title: 'Images',\n             *     extensions: 'gif,jpg,jpeg,bmp,png',\n             *     mimeTypes: 'image/*'\n             * }\n             * ```\n             */\n            accept: null/*{\n                title: 'Images',\n                extensions: 'gif,jpg,jpeg,bmp,png',\n                mimeTypes: 'image/*'\n            }*/\n        });\n    \n        return Uploader.register({\n            'add-btn': 'addButton',\n            refresh: 'refresh',\n            disable: 'disable',\n            enable: 'enable'\n        }, {\n    \n            init: function( opts ) {\n                this.pickers = [];\n                return opts.pick && this.addButton( opts.pick );\n            },\n    \n            refresh: function() {\n                $.each( this.pickers, function() {\n                    this.refresh();\n                });\n            },\n    \n            /**\n             * @method addButton\n             * @for Uploader\n             * @grammar addButton( pick ) => Promise\n             * @description\n             * 添加文件选择按钮，如果一个按钮不够，需要调用此方法来添加。参数跟[options.pick](#WebUploader:Uploader:options)一致。\n             * @example\n             * uploader.addButton({\n             *     id: '#btnContainer',\n             *     innerHTML: '选择文件'\n             * });\n             */\n            addButton: function( pick ) {\n                var me = this,\n                    opts = me.options,\n                    accept = opts.accept,\n                    options, picker, deferred;\n    \n                if ( !pick ) {\n                    return;\n                }\n    \n                deferred = Base.Deferred();\n                $.isPlainObject( pick ) || (pick = {\n                    id: pick\n                });\n    \n                options = $.extend({}, pick, {\n                    accept: $.isPlainObject( accept ) ? [ accept ] : accept,\n                    swf: opts.swf,\n                    runtimeOrder: opts.runtimeOrder\n                });\n    \n                picker = new FilePicker( options );\n    \n                picker.once( 'ready', deferred.resolve );\n                picker.on( 'select', function( files ) {\n                    me.owner.request( 'add-file', [ files ]);\n                });\n                picker.init();\n    \n                this.pickers.push( picker );\n    \n                return deferred.promise();\n            },\n    \n            disable: function() {\n                $.each( this.pickers, function() {\n                    this.disable();\n                });\n            },\n    \n            enable: function() {\n                $.each( this.pickers, function() {\n                    this.enable();\n                });\n            }\n        });\n    });\n    /**\n     * @fileOverview Image\n     */\n    define('lib/image',[\n        'base',\n        'runtime/client',\n        'lib/blob'\n    ], function( Base, RuntimeClient, Blob ) {\n        var $ = Base.$;\n    \n        // 构造器。\n        function Image( opts ) {\n            this.options = $.extend({}, Image.options, opts );\n            RuntimeClient.call( this, 'Image' );\n    \n            this.on( 'load', function() {\n                this._info = this.exec('info');\n                this._meta = this.exec('meta');\n            });\n        }\n    \n        // 默认选项。\n        Image.options = {\n    \n            // 默认的图片处理质量\n            quality: 90,\n    \n            // 是否裁剪\n            crop: false,\n    \n            // 是否保留头部信息\n            preserveHeaders: true,\n    \n            // 是否允许放大。\n            allowMagnify: true\n        };\n    \n        // 继承RuntimeClient.\n        Base.inherits( RuntimeClient, {\n            constructor: Image,\n    \n            info: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._info = val;\n                    return this;\n                }\n    \n                // getter\n                return this._info;\n            },\n    \n            meta: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._meta = val;\n                    return this;\n                }\n    \n                // getter\n                return this._meta;\n            },\n    \n            loadFromBlob: function( blob ) {\n                var me = this,\n                    ruid = blob.getRuid();\n    \n                this.connectRuntime( ruid, function() {\n                    me.exec( 'init', me.options );\n                    me.exec( 'loadFromBlob', blob );\n                });\n            },\n    \n            resize: function() {\n                var args = Base.slice( arguments );\n                return this.exec.apply( this, [ 'resize' ].concat( args ) );\n            },\n    \n            getAsDataUrl: function( type ) {\n                return this.exec( 'getAsDataUrl', type );\n            },\n    \n            getAsBlob: function( type ) {\n                var blob = this.exec( 'getAsBlob', type );\n    \n                return new Blob( this.getRuid(), blob );\n            }\n        });\n    \n        return Image;\n    });\n    /**\n     * @fileOverview 图片操作, 负责预览图片和上传前压缩图片\n     */\n    define('widgets/image',[\n        'base',\n        'uploader',\n        'lib/image',\n        'widgets/widget'\n    ], function( Base, Uploader, Image ) {\n    \n        var $ = Base.$,\n            throttle;\n    \n        // 根据要处理的文件大小来节流，一次不能处理太多，会卡。\n        throttle = (function( max ) {\n            var occupied = 0,\n                waiting = [],\n                tick = function() {\n                    var item;\n    \n                    while ( waiting.length && occupied < max ) {\n                        item = waiting.shift();\n                        occupied += item[ 0 ];\n                        item[ 1 ]();\n                    }\n                };\n    \n            return function( emiter, size, cb ) {\n                waiting.push([ size, cb ]);\n                emiter.once( 'destroy', function() {\n                    occupied -= size;\n                    setTimeout( tick, 1 );\n                });\n                setTimeout( tick, 1 );\n            };\n        })( 5 * 1024 * 1024 );\n    \n        $.extend( Uploader.options, {\n    \n            /**\n             * @property {Object} [thumb]\n             * @namespace options\n             * @for Uploader\n             * @description 配置生成缩略图的选项。\n             *\n             * 默认为：\n             *\n             * ```javascript\n             * {\n             *     width: 110,\n             *     height: 110,\n             *\n             *     // 图片质量，只有type为`image/jpeg`的时候才有效。\n             *     quality: 70,\n             *\n             *     // 是否允许放大，如果想要生成小图的时候不失真，此选项应该设置为false.\n             *     allowMagnify: true,\n             *\n             *     // 是否允许裁剪。\n             *     crop: true,\n             *\n             *     // 是否保留头部meta信息。\n             *     preserveHeaders: false,\n             *\n             *     // 为空的话则保留原有图片格式。\n             *     // 否则强制转换成指定的类型。\n             *     type: 'image/jpeg'\n             * }\n             * ```\n             */\n            thumb: {\n                width: 110,\n                height: 110,\n                quality: 70,\n                allowMagnify: true,\n                crop: true,\n                preserveHeaders: false,\n    \n                // 为空的话则保留原有图片格式。\n                // 否则强制转换成指定的类型。\n                // IE 8下面 base64 大小不能超过 32K 否则预览失败，而非 jpeg 编码的图片很可\n                // 能会超过 32k, 所以这里设置成预览的时候都是 image/jpeg\n                type: 'image/jpeg'\n            },\n    \n            /**\n             * @property {Object} [compress]\n             * @namespace options\n             * @for Uploader\n             * @description 配置压缩的图片的选项。如果此选项为`false`, 则图片在上传前不进行压缩。\n             *\n             * 默认为：\n             *\n             * ```javascript\n             * {\n             *     width: 1600,\n             *     height: 1600,\n             *\n             *     // 图片质量，只有type为`image/jpeg`的时候才有效。\n             *     quality: 90,\n             *\n             *     // 是否允许放大，如果想要生成小图的时候不失真，此选项应该设置为false.\n             *     allowMagnify: false,\n             *\n             *     // 是否允许裁剪。\n             *     crop: false,\n             *\n             *     // 是否保留头部meta信息。\n             *     preserveHeaders: true\n             * }\n             * ```\n             */\n            compress: {\n                width: 1600,\n                height: 1600,\n                quality: 90,\n                allowMagnify: false,\n                crop: false,\n                preserveHeaders: true\n            }\n        });\n    \n        return Uploader.register({\n            'make-thumb': 'makeThumb',\n            'before-send-file': 'compressImage'\n        }, {\n    \n    \n            /**\n             * 生成缩略图，此过程为异步，所以需要传入`callback`。\n             * 通常情况在图片加入队里后调用此方法来生成预览图以增强交互效果。\n             *\n             * `callback`中可以接收到两个参数。\n             * * 第一个为error，如果生成缩略图有错误，此error将为真。\n             * * 第二个为ret, 缩略图的Data URL值。\n             *\n             * **注意**\n             * Date URL在IE6/7中不支持，所以不用调用此方法了，直接显示一张暂不支持预览图片好了。\n             *\n             *\n             * @method makeThumb\n             * @grammar makeThumb( file, callback ) => undefined\n             * @grammar makeThumb( file, callback, width, height ) => undefined\n             * @for Uploader\n             * @example\n             *\n             * uploader.on( 'fileQueued', function( file ) {\n             *     var $li = ...;\n             *\n             *     uploader.makeThumb( file, function( error, ret ) {\n             *         if ( error ) {\n             *             $li.text('预览错误');\n             *         } else {\n             *             $li.append('<img alt=\"\" src=\"' + ret + '\" />');\n             *         }\n             *     });\n             *\n             * });\n             */\n            makeThumb: function( file, cb, width, height ) {\n                var opts, image;\n    \n                file = this.request( 'get-file', file );\n    \n                // 只预览图片格式。\n                if ( !file.type.match( /^image/ ) ) {\n                    cb( true );\n                    return;\n                }\n    \n                opts = $.extend({}, this.options.thumb );\n    \n                // 如果传入的是object.\n                if ( $.isPlainObject( width ) ) {\n                    opts = $.extend( opts, width );\n                    width = null;\n                }\n    \n                width = width || opts.width;\n                height = height || opts.height;\n    \n                image = new Image( opts );\n    \n                image.once( 'load', function() {\n                    file._info = file._info || image.info();\n                    file._meta = file._meta || image.meta();\n                    image.resize( width, height );\n                });\n    \n                image.once( 'complete', function() {\n                    cb( false, image.getAsDataUrl( opts.type ) );\n                    image.destroy();\n                });\n    \n                image.once( 'error', function() {\n                    cb( true );\n                    image.destroy();\n                });\n    \n                throttle( image, file.source.size, function() {\n                    file._info && image.info( file._info );\n                    file._meta && image.meta( file._meta );\n                    image.loadFromBlob( file.source );\n                });\n            },\n    \n            compressImage: function( file ) {\n                var opts = this.options.compress || this.options.resize,\n                    compressSize = opts && opts.compressSize || 300 * 1024,\n                    image, deferred;\n    \n                file = this.request( 'get-file', file );\n    \n                // 只预览图片格式。\n                if ( !opts || !~'image/jpeg,image/jpg'.indexOf( file.type ) ||\n                        file.size < compressSize ||\n                        file._compressed ) {\n                    return;\n                }\n    \n                opts = $.extend({}, opts );\n                deferred = Base.Deferred();\n    \n                image = new Image( opts );\n    \n                deferred.always(function() {\n                    image.destroy();\n                    image = null;\n                });\n                image.once( 'error', deferred.reject );\n                image.once( 'load', function() {\n                    file._info = file._info || image.info();\n                    file._meta = file._meta || image.meta();\n                    image.resize( opts.width, opts.height );\n                });\n    \n                image.once( 'complete', function() {\n                    var blob, size;\n    \n                    // 移动端 UC / qq 浏览器的无图模式下\n                    // ctx.getImageData 处理大图的时候会报 Exception\n                    // INDEX_SIZE_ERR: DOM Exception 1\n                    try {\n                        blob = image.getAsBlob( opts.type );\n    \n                        size = file.size;\n    \n                        // 如果压缩后，比原来还大则不用压缩后的。\n                        if ( blob.size < size ) {\n                            // file.source.destroy && file.source.destroy();\n                            file.source = blob;\n                            file.size = blob.size;\n    \n                            file.trigger( 'resize', blob.size, size );\n                        }\n    \n                        // 标记，避免重复压缩。\n                        file._compressed = true;\n                        deferred.resolve();\n                    } catch ( e ) {\n                        // 出错了直接继续，让其上传原始图片\n                        deferred.resolve();\n                    }\n                });\n    \n                file._info && image.info( file._info );\n                file._meta && image.meta( file._meta );\n    \n                image.loadFromBlob( file.source );\n                return deferred.promise();\n            }\n        });\n    });\n    /**\n     * @fileOverview 文件属性封装\n     */\n    define('file',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$,\n            idPrefix = 'WU_FILE_',\n            idSuffix = 0,\n            rExt = /\\.([^.]+)$/,\n            statusMap = {};\n    \n        function gid() {\n            return idPrefix + idSuffix++;\n        }\n    \n        /**\n         * 文件类\n         * @class File\n         * @constructor 构造函数\n         * @grammar new File( source ) => File\n         * @param {Lib.File} source [lib.File](#Lib.File)实例, 此source对象是带有Runtime信息的。\n         */\n        function WUFile( source ) {\n    \n            /**\n             * 文件名，包括扩展名（后缀）\n             * @property name\n             * @type {string}\n             */\n            this.name = source.name || 'Untitled';\n    \n            /**\n             * 文件体积（字节）\n             * @property size\n             * @type {uint}\n             * @default 0\n             */\n            this.size = source.size || 0;\n    \n            /**\n             * 文件MIMETYPE类型，与文件类型的对应关系请参考[http://t.cn/z8ZnFny](http://t.cn/z8ZnFny)\n             * @property type\n             * @type {string}\n             * @default 'application'\n             */\n            this.type = source.type || 'application';\n    \n            /**\n             * 文件最后修改日期\n             * @property lastModifiedDate\n             * @type {int}\n             * @default 当前时间戳\n             */\n            this.lastModifiedDate = source.lastModifiedDate || (new Date() * 1);\n    \n            /**\n             * 文件ID，每个对象具有唯一ID，与文件名无关\n             * @property id\n             * @type {string}\n             */\n            this.id = gid();\n    \n            /**\n             * 文件扩展名，通过文件名获取，例如test.png的扩展名为png\n             * @property ext\n             * @type {string}\n             */\n            this.ext = rExt.exec( this.name ) ? RegExp.$1 : '';\n    \n    \n            /**\n             * 状态文字说明。在不同的status语境下有不同的用途。\n             * @property statusText\n             * @type {string}\n             */\n            this.statusText = '';\n    \n            // 存储文件状态，防止通过属性直接修改\n            statusMap[ this.id ] = WUFile.Status.INITED;\n    \n            this.source = source;\n            this.loaded = 0;\n    \n            this.on( 'error', function( msg ) {\n                this.setStatus( WUFile.Status.ERROR, msg );\n            });\n        }\n    \n        $.extend( WUFile.prototype, {\n    \n            /**\n             * 设置状态，状态变化时会触发`change`事件。\n             * @method setStatus\n             * @grammar setStatus( status[, statusText] );\n             * @param {File.Status|String} status [文件状态值](#WebUploader:File:File.Status)\n             * @param {String} [statusText=''] 状态说明，常在error时使用，用http, abort,server等来标记是由于什么原因导致文件错误。\n             */\n            setStatus: function( status, text ) {\n    \n                var prevStatus = statusMap[ this.id ];\n    \n                typeof text !== 'undefined' && (this.statusText = text);\n    \n                if ( status !== prevStatus ) {\n                    statusMap[ this.id ] = status;\n                    /**\n                     * 文件状态变化\n                     * @event statuschange\n                     */\n                    this.trigger( 'statuschange', status, prevStatus );\n                }\n    \n            },\n    \n            /**\n             * 获取文件状态\n             * @return {File.Status}\n             * @example\n                     文件状态具体包括以下几种类型：\n                     {\n                         // 初始化\n                        INITED:     0,\n                        // 已入队列\n                        QUEUED:     1,\n                        // 正在上传\n                        PROGRESS:     2,\n                        // 上传出错\n                        ERROR:         3,\n                        // 上传成功\n                        COMPLETE:     4,\n                        // 上传取消\n                        CANCELLED:     5\n                    }\n             */\n            getStatus: function() {\n                return statusMap[ this.id ];\n            },\n    \n            /**\n             * 获取文件原始信息。\n             * @return {*}\n             */\n            getSource: function() {\n                return this.source;\n            },\n    \n            destory: function() {\n                delete statusMap[ this.id ];\n            }\n        });\n    \n        Mediator.installTo( WUFile.prototype );\n    \n        /**\n         * 文件状态值，具体包括以下几种类型：\n         * * `inited` 初始状态\n         * * `queued` 已经进入队列, 等待上传\n         * * `progress` 上传中\n         * * `complete` 上传完成。\n         * * `error` 上传出错，可重试\n         * * `interrupt` 上传中断，可续传。\n         * * `invalid` 文件不合格，不能重试上传。会自动从队列中移除。\n         * * `cancelled` 文件被移除。\n         * @property {Object} Status\n         * @namespace File\n         * @class File\n         * @static\n         */\n        WUFile.Status = {\n            INITED:     'inited',    // 初始状态\n            QUEUED:     'queued',    // 已经进入队列, 等待上传\n            PROGRESS:   'progress',    // 上传中\n            ERROR:      'error',    // 上传出错，可重试\n            COMPLETE:   'complete',    // 上传完成。\n            CANCELLED:  'cancelled',    // 上传取消。\n            INTERRUPT:  'interrupt',    // 上传中断，可续传。\n            INVALID:    'invalid'    // 文件不合格，不能重试上传。\n        };\n    \n        return WUFile;\n    });\n    \n    /**\n     * @fileOverview 文件队列\n     */\n    define('queue',[\n        'base',\n        'mediator',\n        'file'\n    ], function( Base, Mediator, WUFile ) {\n    \n        var $ = Base.$,\n            STATUS = WUFile.Status;\n    \n        /**\n         * 文件队列, 用来存储各个状态中的文件。\n         * @class Queue\n         * @extends Mediator\n         */\n        function Queue() {\n    \n            /**\n             * 统计文件数。\n             * * `numOfQueue` 队列中的文件数。\n             * * `numOfSuccess` 上传成功的文件数\n             * * `numOfCancel` 被移除的文件数\n             * * `numOfProgress` 正在上传中的文件数\n             * * `numOfUploadFailed` 上传错误的文件数。\n             * * `numOfInvalid` 无效的文件数。\n             * @property {Object} stats\n             */\n            this.stats = {\n                numOfQueue: 0,\n                numOfSuccess: 0,\n                numOfCancel: 0,\n                numOfProgress: 0,\n                numOfUploadFailed: 0,\n                numOfInvalid: 0\n            };\n    \n            // 上传队列，仅包括等待上传的文件\n            this._queue = [];\n    \n            // 存储所有文件\n            this._map = {};\n        }\n    \n        $.extend( Queue.prototype, {\n    \n            /**\n             * 将新文件加入对队列尾部\n             *\n             * @method append\n             * @param  {File} file   文件对象\n             */\n            append: function( file ) {\n                this._queue.push( file );\n                this._fileAdded( file );\n                return this;\n            },\n    \n            /**\n             * 将新文件加入对队列头部\n             *\n             * @method prepend\n             * @param  {File} file   文件对象\n             */\n            prepend: function( file ) {\n                this._queue.unshift( file );\n                this._fileAdded( file );\n                return this;\n            },\n    \n            /**\n             * 获取文件对象\n             *\n             * @method getFile\n             * @param  {String} fileId   文件ID\n             * @return {File}\n             */\n            getFile: function( fileId ) {\n                if ( typeof fileId !== 'string' ) {\n                    return fileId;\n                }\n                return this._map[ fileId ];\n            },\n    \n            /**\n             * 从队列中取出一个指定状态的文件。\n             * @grammar fetch( status ) => File\n             * @method fetch\n             * @param {String} status [文件状态值](#WebUploader:File:File.Status)\n             * @return {File} [File](#WebUploader:File)\n             */\n            fetch: function( status ) {\n                var len = this._queue.length,\n                    i, file;\n    \n                status = status || STATUS.QUEUED;\n    \n                for ( i = 0; i < len; i++ ) {\n                    file = this._queue[ i ];\n    \n                    if ( status === file.getStatus() ) {\n                        return file;\n                    }\n                }\n    \n                return null;\n            },\n    \n            /**\n             * 对队列进行排序，能够控制文件上传顺序。\n             * @grammar sort( fn ) => undefined\n             * @method sort\n             * @param {Function} fn 排序方法\n             */\n            sort: function( fn ) {\n                if ( typeof fn === 'function' ) {\n                    this._queue.sort( fn );\n                }\n            },\n    \n            /**\n             * 获取指定类型的文件列表, 列表中每一个成员为[File](#WebUploader:File)对象。\n             * @grammar getFiles( [status1[, status2 ...]] ) => Array\n             * @method getFiles\n             * @param {String} [status] [文件状态值](#WebUploader:File:File.Status)\n             */\n            getFiles: function() {\n                var sts = [].slice.call( arguments, 0 ),\n                    ret = [],\n                    i = 0,\n                    len = this._queue.length,\n                    file;\n    \n                for ( ; i < len; i++ ) {\n                    file = this._queue[ i ];\n    \n                    if ( sts.length && !~$.inArray( file.getStatus(), sts ) ) {\n                        continue;\n                    }\n    \n                    ret.push( file );\n                }\n    \n                return ret;\n            },\n    \n            _fileAdded: function( file ) {\n                var me = this,\n                    existing = this._map[ file.id ];\n    \n                if ( !existing ) {\n                    this._map[ file.id ] = file;\n    \n                    file.on( 'statuschange', function( cur, pre ) {\n                        me._onFileStatusChange( cur, pre );\n                    });\n                }\n    \n                file.setStatus( STATUS.QUEUED );\n            },\n    \n            _onFileStatusChange: function( curStatus, preStatus ) {\n                var stats = this.stats;\n    \n                switch ( preStatus ) {\n                    case STATUS.PROGRESS:\n                        stats.numOfProgress--;\n                        break;\n    \n                    case STATUS.QUEUED:\n                        stats.numOfQueue --;\n                        break;\n    \n                    case STATUS.ERROR:\n                        stats.numOfUploadFailed--;\n                        break;\n    \n                    case STATUS.INVALID:\n                        stats.numOfInvalid--;\n                        break;\n                }\n    \n                switch ( curStatus ) {\n                    case STATUS.QUEUED:\n                        stats.numOfQueue++;\n                        break;\n    \n                    case STATUS.PROGRESS:\n                        stats.numOfProgress++;\n                        break;\n    \n                    case STATUS.ERROR:\n                        stats.numOfUploadFailed++;\n                        break;\n    \n                    case STATUS.COMPLETE:\n                        stats.numOfSuccess++;\n                        break;\n    \n                    case STATUS.CANCELLED:\n                        stats.numOfCancel++;\n                        break;\n    \n                    case STATUS.INVALID:\n                        stats.numOfInvalid++;\n                        break;\n                }\n            }\n    \n        });\n    \n        Mediator.installTo( Queue.prototype );\n    \n        return Queue;\n    });\n    /**\n     * @fileOverview 队列\n     */\n    define('widgets/queue',[\n        'base',\n        'uploader',\n        'queue',\n        'file',\n        'lib/file',\n        'runtime/client',\n        'widgets/widget'\n    ], function( Base, Uploader, Queue, WUFile, File, RuntimeClient ) {\n    \n        var $ = Base.$,\n            rExt = /\\.\\w+$/,\n            Status = WUFile.Status;\n    \n        return Uploader.register({\n            'sort-files': 'sortFiles',\n            'add-file': 'addFiles',\n            'get-file': 'getFile',\n            'fetch-file': 'fetchFile',\n            'get-stats': 'getStats',\n            'get-files': 'getFiles',\n            'remove-file': 'removeFile',\n            'retry': 'retry',\n            'reset': 'reset',\n            'accept-file': 'acceptFile'\n        }, {\n    \n            init: function( opts ) {\n                var me = this,\n                    deferred, len, i, item, arr, accept, runtime;\n    \n                if ( $.isPlainObject( opts.accept ) ) {\n                    opts.accept = [ opts.accept ];\n                }\n    \n                // accept中的中生成匹配正则。\n                if ( opts.accept ) {\n                    arr = [];\n    \n                    for ( i = 0, len = opts.accept.length; i < len; i++ ) {\n                        item = opts.accept[ i ].extensions;\n                        item && arr.push( item );\n                    }\n    \n                    if ( arr.length ) {\n                        accept = '\\\\.' + arr.join(',')\n                                .replace( /,/g, '$|\\\\.' )\n                                .replace( /\\*/g, '.*' ) + '$';\n                    }\n    \n                    me.accept = new RegExp( accept, 'i' );\n                }\n    \n                me.queue = new Queue();\n                me.stats = me.queue.stats;\n    \n                // 如果当前不是html5运行时，那就算了。\n                // 不执行后续操作\n                if ( this.request('predict-runtime-type') !== 'html5' ) {\n                    return;\n                }\n    \n                // 创建一个 html5 运行时的 placeholder\n                // 以至于外部添加原生 File 对象的时候能正确包裹一下供 webuploader 使用。\n                deferred = Base.Deferred();\n                runtime = new RuntimeClient('Placeholder');\n                runtime.connectRuntime({\n                    runtimeOrder: 'html5'\n                }, function() {\n                    me._ruid = runtime.getRuid();\n                    deferred.resolve();\n                });\n                return deferred.promise();\n            },\n    \n    \n            // 为了支持外部直接添加一个原生File对象。\n            _wrapFile: function( file ) {\n                if ( !(file instanceof WUFile) ) {\n    \n                    if ( !(file instanceof File) ) {\n                        if ( !this._ruid ) {\n                            throw new Error('Can\\'t add external files.');\n                        }\n                        file = new File( this._ruid, file );\n                    }\n    \n                    file = new WUFile( file );\n                }\n    \n                return file;\n            },\n    \n            // 判断文件是否可以被加入队列\n            acceptFile: function( file ) {\n                var invalid = !file || file.size < 6 || this.accept &&\n    \n                        // 如果名字中有后缀，才做后缀白名单处理。\n                        rExt.exec( file.name ) && !this.accept.test( file.name );\n    \n                return !invalid;\n            },\n    \n    \n            /**\n             * @event beforeFileQueued\n             * @param {File} file File对象\n             * @description 当文件被加入队列之前触发，此事件的handler返回值为`false`，则此文件不会被添加进入队列。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event fileQueued\n             * @param {File} file File对象\n             * @description 当文件被加入队列以后触发。\n             * @for  Uploader\n             */\n    \n            _addFile: function( file ) {\n                var me = this;\n    \n                file = me._wrapFile( file );\n    \n                // 不过类型判断允许不允许，先派送 `beforeFileQueued`\n                if ( !me.owner.trigger( 'beforeFileQueued', file ) ) {\n                    return;\n                }\n    \n                // 类型不匹配，则派送错误事件，并返回。\n                if ( !me.acceptFile( file ) ) {\n                    me.owner.trigger( 'error', 'Q_TYPE_DENIED', file );\n                    return;\n                }\n    \n                me.queue.append( file );\n                me.owner.trigger( 'fileQueued', file );\n                return file;\n            },\n    \n            getFile: function( fileId ) {\n                return this.queue.getFile( fileId );\n            },\n    \n            /**\n             * @event filesQueued\n             * @param {File} files 数组，内容为原始File(lib/File）对象。\n             * @description 当一批文件添加进队列以后触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @method addFiles\n             * @grammar addFiles( file ) => undefined\n             * @grammar addFiles( [file1, file2 ...] ) => undefined\n             * @param {Array of File or File} [files] Files 对象 数组\n             * @description 添加文件到队列\n             * @for  Uploader\n             */\n            addFiles: function( files ) {\n                var me = this;\n    \n                if ( !files.length ) {\n                    files = [ files ];\n                }\n    \n                files = $.map( files, function( file ) {\n                    return me._addFile( file );\n                });\n    \n                me.owner.trigger( 'filesQueued', files );\n    \n                if ( me.options.auto ) {\n                    me.request('start-upload');\n                }\n            },\n    \n            getStats: function() {\n                return this.stats;\n            },\n    \n            /**\n             * @event fileDequeued\n             * @param {File} file File对象\n             * @description 当文件被移除队列后触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @method removeFile\n             * @grammar removeFile( file ) => undefined\n             * @grammar removeFile( id ) => undefined\n             * @param {File|id} file File对象或这File对象的id\n             * @description 移除某一文件。\n             * @for  Uploader\n             * @example\n             *\n             * $li.on('click', '.remove-this', function() {\n             *     uploader.removeFile( file );\n             * })\n             */\n            removeFile: function( file ) {\n                var me = this;\n    \n                file = file.id ? file : me.queue.getFile( file );\n    \n                file.setStatus( Status.CANCELLED );\n                me.owner.trigger( 'fileDequeued', file );\n            },\n    \n            /**\n             * @method getFiles\n             * @grammar getFiles() => Array\n             * @grammar getFiles( status1, status2, status... ) => Array\n             * @description 返回指定状态的文件集合，不传参数将返回所有状态的文件。\n             * @for  Uploader\n             * @example\n             * console.log( uploader.getFiles() );    // => all files\n             * console.log( uploader.getFiles('error') )    // => all error files.\n             */\n            getFiles: function() {\n                return this.queue.getFiles.apply( this.queue, arguments );\n            },\n    \n            fetchFile: function() {\n                return this.queue.fetch.apply( this.queue, arguments );\n            },\n    \n            /**\n             * @method retry\n             * @grammar retry() => undefined\n             * @grammar retry( file ) => undefined\n             * @description 重试上传，重试指定文件，或者从出错的文件开始重新上传。\n             * @for  Uploader\n             * @example\n             * function retry() {\n             *     uploader.retry();\n             * }\n             */\n            retry: function( file, noForceStart ) {\n                var me = this,\n                    files, i, len;\n    \n                if ( file ) {\n                    file = file.id ? file : me.queue.getFile( file );\n                    file.setStatus( Status.QUEUED );\n                    noForceStart || me.request('start-upload');\n                    return;\n                }\n    \n                files = me.queue.getFiles( Status.ERROR );\n                i = 0;\n                len = files.length;\n    \n                for ( ; i < len; i++ ) {\n                    file = files[ i ];\n                    file.setStatus( Status.QUEUED );\n                }\n    \n                me.request('start-upload');\n            },\n    \n            /**\n             * @method sort\n             * @grammar sort( fn ) => undefined\n             * @description 排序队列中的文件，在上传之前调整可以控制上传顺序。\n             * @for  Uploader\n             */\n            sortFiles: function() {\n                return this.queue.sort.apply( this.queue, arguments );\n            },\n    \n            /**\n             * @method reset\n             * @grammar reset() => undefined\n             * @description 重置uploader。目前只重置了队列。\n             * @for  Uploader\n             * @example\n             * uploader.reset();\n             */\n            reset: function() {\n                this.queue = new Queue();\n                this.stats = this.queue.stats;\n            }\n        });\n    \n    });\n    /**\n     * @fileOverview 添加获取Runtime相关信息的方法。\n     */\n    define('widgets/runtime',[\n        'uploader',\n        'runtime/runtime',\n        'widgets/widget'\n    ], function( Uploader, Runtime ) {\n    \n        Uploader.support = function() {\n            return Runtime.hasRuntime.apply( Runtime, arguments );\n        };\n    \n        return Uploader.register({\n            'predict-runtime-type': 'predictRuntmeType'\n        }, {\n    \n            init: function() {\n                if ( !this.predictRuntmeType() ) {\n                    throw Error('Runtime Error');\n                }\n            },\n    \n            /**\n             * 预测Uploader将采用哪个`Runtime`\n             * @grammar predictRuntmeType() => String\n             * @method predictRuntmeType\n             * @for  Uploader\n             */\n            predictRuntmeType: function() {\n                var orders = this.options.runtimeOrder || Runtime.orders,\n                    type = this.type,\n                    i, len;\n    \n                if ( !type ) {\n                    orders = orders.split( /\\s*,\\s*/g );\n    \n                    for ( i = 0, len = orders.length; i < len; i++ ) {\n                        if ( Runtime.hasRuntime( orders[ i ] ) ) {\n                            this.type = type = orders[ i ];\n                            break;\n                        }\n                    }\n                }\n    \n                return type;\n            }\n        });\n    });\n    /**\n     * @fileOverview Transport\n     */\n    define('lib/transport',[\n        'base',\n        'runtime/client',\n        'mediator'\n    ], function( Base, RuntimeClient, Mediator ) {\n    \n        var $ = Base.$;\n    \n        function Transport( opts ) {\n            var me = this;\n    \n            opts = me.options = $.extend( true, {}, Transport.options, opts || {} );\n            RuntimeClient.call( this, 'Transport' );\n    \n            this._blob = null;\n            this._formData = opts.formData || {};\n            this._headers = opts.headers || {};\n    \n            this.on( 'progress', this._timeout );\n            this.on( 'load error', function() {\n                me.trigger( 'progress', 1 );\n                clearTimeout( me._timer );\n            });\n        }\n    \n        Transport.options = {\n            server: '',\n            method: 'POST',\n    \n            // 跨域时，是否允许携带cookie, 只有html5 runtime才有效\n            withCredentials: false,\n            fileVal: 'file',\n            timeout: 2 * 60 * 1000,    // 2分钟\n            formData: {},\n            headers: {},\n            sendAsBinary: false\n        };\n    \n        $.extend( Transport.prototype, {\n    \n            // 添加Blob, 只能添加一次，最后一次有效。\n            appendBlob: function( key, blob, filename ) {\n                var me = this,\n                    opts = me.options;\n    \n                if ( me.getRuid() ) {\n                    me.disconnectRuntime();\n                }\n    \n                // 连接到blob归属的同一个runtime.\n                me.connectRuntime( blob.ruid, function() {\n                    me.exec('init');\n                });\n    \n                me._blob = blob;\n                opts.fileVal = key || opts.fileVal;\n                opts.filename = filename || opts.filename;\n            },\n    \n            // 添加其他字段\n            append: function( key, value ) {\n                if ( typeof key === 'object' ) {\n                    $.extend( this._formData, key );\n                } else {\n                    this._formData[ key ] = value;\n                }\n            },\n    \n            setRequestHeader: function( key, value ) {\n                if ( typeof key === 'object' ) {\n                    $.extend( this._headers, key );\n                } else {\n                    this._headers[ key ] = value;\n                }\n            },\n    \n            send: function( method ) {\n                this.exec( 'send', method );\n                this._timeout();\n            },\n    \n            abort: function() {\n                clearTimeout( this._timer );\n                return this.exec('abort');\n            },\n    \n            destroy: function() {\n                this.trigger('destroy');\n                this.off();\n                this.exec('destroy');\n                this.disconnectRuntime();\n            },\n    \n            getResponse: function() {\n                return this.exec('getResponse');\n            },\n    \n            getResponseAsJson: function() {\n                return this.exec('getResponseAsJson');\n            },\n    \n            getStatus: function() {\n                return this.exec('getStatus');\n            },\n    \n            _timeout: function() {\n                var me = this,\n                    duration = me.options.timeout;\n    \n                if ( !duration ) {\n                    return;\n                }\n    \n                clearTimeout( me._timer );\n                me._timer = setTimeout(function() {\n                    me.abort();\n                    me.trigger( 'error', 'timeout' );\n                }, duration );\n            }\n    \n        });\n    \n        // 让Transport具备事件功能。\n        Mediator.installTo( Transport.prototype );\n    \n        return Transport;\n    });\n    /**\n     * @fileOverview 负责文件上传相关。\n     */\n    define('widgets/upload',[\n        'base',\n        'uploader',\n        'file',\n        'lib/transport',\n        'widgets/widget'\n    ], function( Base, Uploader, WUFile, Transport ) {\n    \n        var $ = Base.$,\n            isPromise = Base.isPromise,\n            Status = WUFile.Status;\n    \n        // 添加默认配置项\n        $.extend( Uploader.options, {\n    \n    \n            /**\n             * @property {Boolean} [prepareNextFile=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否允许在文件传输时提前把下一个文件准备好。\n             * 对于一个文件的准备工作比较耗时，比如图片压缩，md5序列化。\n             * 如果能提前在当前文件传输期处理，可以节省总体耗时。\n             */\n            prepareNextFile: false,\n    \n            /**\n             * @property {Boolean} [chunked=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否要分片处理大文件上传。\n             */\n            chunked: false,\n    \n            /**\n             * @property {Boolean} [chunkSize=5242880]\n             * @namespace options\n             * @for Uploader\n             * @description 如果要分片，分多大一片？ 默认大小为5M.\n             */\n            chunkSize: 5 * 1024 * 1024,\n    \n            /**\n             * @property {Boolean} [chunkRetry=2]\n             * @namespace options\n             * @for Uploader\n             * @description 如果某个分片由于网络问题出错，允许自动重传多少次？\n             */\n            chunkRetry: 2,\n    \n            /**\n             * @property {Boolean} [threads=3]\n             * @namespace options\n             * @for Uploader\n             * @description 上传并发数。允许同时最大上传进程数。\n             */\n            threads: 3,\n    \n    \n            /**\n             * @property {Object} [formData]\n             * @namespace options\n             * @for Uploader\n             * @description 文件上传请求的参数表，每次发送都会发送此对象中的参数。\n             */\n            formData: null\n    \n            /**\n             * @property {Object} [fileVal='file']\n             * @namespace options\n             * @for Uploader\n             * @description 设置文件上传域的name。\n             */\n    \n            /**\n             * @property {Object} [method='POST']\n             * @namespace options\n             * @for Uploader\n             * @description 文件上传方式，`POST`或者`GET`。\n             */\n    \n            /**\n             * @property {Object} [sendAsBinary=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否已二进制的流的方式发送文件，这样整个上传内容`php://input`都为文件内容，\n             * 其他参数在$_GET数组中。\n             */\n        });\n    \n        // 负责将文件切片。\n        function CuteFile( file, chunkSize ) {\n            var pending = [],\n                blob = file.source,\n                total = blob.size,\n                chunks = chunkSize ? Math.ceil( total / chunkSize ) : 1,\n                start = 0,\n                index = 0,\n                len;\n    \n            while ( index < chunks ) {\n                len = Math.min( chunkSize, total - start );\n    \n                pending.push({\n                    file: file,\n                    start: start,\n                    end: chunkSize ? (start + len) : total,\n                    total: total,\n                    chunks: chunks,\n                    chunk: index++\n                });\n                start += len;\n            }\n    \n            file.blocks = pending.concat();\n            file.remaning = pending.length;\n    \n            return {\n                file: file,\n    \n                has: function() {\n                    return !!pending.length;\n                },\n    \n                fetch: function() {\n                    return pending.shift();\n                }\n            };\n        }\n    \n        Uploader.register({\n            'start-upload': 'start',\n            'stop-upload': 'stop',\n            'skip-file': 'skipFile',\n            'is-in-progress': 'isInProgress'\n        }, {\n    \n            init: function() {\n                var owner = this.owner;\n    \n                this.runing = false;\n    \n                // 记录当前正在传的数据，跟threads相关\n                this.pool = [];\n    \n                // 缓存即将上传的文件。\n                this.pending = [];\n    \n                // 跟踪还有多少分片没有完成上传。\n                this.remaning = 0;\n                this.__tick = Base.bindFn( this._tick, this );\n    \n                owner.on( 'uploadComplete', function( file ) {\n                    // 把其他块取消了。\n                    file.blocks && $.each( file.blocks, function( _, v ) {\n                        v.transport && (v.transport.abort(), v.transport.destroy());\n                        delete v.transport;\n                    });\n    \n                    delete file.blocks;\n                    delete file.remaning;\n                });\n            },\n    \n            /**\n             * @event startUpload\n             * @description 当开始上传流程时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * 开始上传。此方法可以从初始状态调用开始上传流程，也可以从暂停状态调用，继续上传流程。\n             * @grammar upload() => undefined\n             * @method upload\n             * @for  Uploader\n             */\n            start: function() {\n                var me = this;\n    \n                // 移出invalid的文件\n                $.each( me.request( 'get-files', Status.INVALID ), function() {\n                    me.request( 'remove-file', this );\n                });\n    \n                if ( me.runing ) {\n                    return;\n                }\n    \n                me.runing = true;\n    \n                // 如果有暂停的，则续传\n                $.each( me.pool, function( _, v ) {\n                    var file = v.file;\n    \n                    if ( file.getStatus() === Status.INTERRUPT ) {\n                        file.setStatus( Status.PROGRESS );\n                        me._trigged = false;\n                        v.transport && v.transport.send();\n                    }\n                });\n    \n                me._trigged = false;\n                me.owner.trigger('startUpload');\n                Base.nextTick( me.__tick );\n            },\n    \n            /**\n             * @event stopUpload\n             * @description 当开始上传流程暂停时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * 暂停上传。第一个参数为是否中断上传当前正在上传的文件。\n             * @grammar stop() => undefined\n             * @grammar stop( true ) => undefined\n             * @method stop\n             * @for  Uploader\n             */\n            stop: function( interrupt ) {\n                var me = this;\n    \n                if ( me.runing === false ) {\n                    return;\n                }\n    \n                me.runing = false;\n    \n                interrupt && $.each( me.pool, function( _, v ) {\n                    v.transport && v.transport.abort();\n                    v.file.setStatus( Status.INTERRUPT );\n                });\n    \n                me.owner.trigger('stopUpload');\n            },\n    \n            /**\n             * 判断`Uplaode`r是否正在上传中。\n             * @grammar isInProgress() => Boolean\n             * @method isInProgress\n             * @for  Uploader\n             */\n            isInProgress: function() {\n                return !!this.runing;\n            },\n    \n            getStats: function() {\n                return this.request('get-stats');\n            },\n    \n            /**\n             * 掉过一个文件上传，直接标记指定文件为已上传状态。\n             * @grammar skipFile( file ) => undefined\n             * @method skipFile\n             * @for  Uploader\n             */\n            skipFile: function( file, status ) {\n                file = this.request( 'get-file', file );\n    \n                file.setStatus( status || Status.COMPLETE );\n                file.skipped = true;\n    \n                // 如果正在上传。\n                file.blocks && $.each( file.blocks, function( _, v ) {\n                    var _tr = v.transport;\n    \n                    if ( _tr ) {\n                        _tr.abort();\n                        _tr.destroy();\n                        delete v.transport;\n                    }\n                });\n    \n                this.owner.trigger( 'uploadSkip', file );\n            },\n    \n            /**\n             * @event uploadFinished\n             * @description 当所有文件上传结束时触发。\n             * @for  Uploader\n             */\n            _tick: function() {\n                var me = this,\n                    opts = me.options,\n                    fn, val;\n    \n                // 上一个promise还没有结束，则等待完成后再执行。\n                if ( me._promise ) {\n                    return me._promise.always( me.__tick );\n                }\n    \n                // 还有位置，且还有文件要处理的话。\n                if ( me.pool.length < opts.threads && (val = me._nextBlock()) ) {\n                    me._trigged = false;\n    \n                    fn = function( val ) {\n                        me._promise = null;\n    \n                        // 有可能是reject过来的，所以要检测val的类型。\n                        val && val.file && me._startSend( val );\n                        Base.nextTick( me.__tick );\n                    };\n    \n                    me._promise = isPromise( val ) ? val.always( fn ) : fn( val );\n    \n                // 没有要上传的了，且没有正在传输的了。\n                } else if ( !me.remaning && !me.getStats().numOfQueue ) {\n                    me.runing = false;\n    \n                    me._trigged || Base.nextTick(function() {\n                        me.owner.trigger('uploadFinished');\n                    });\n                    me._trigged = true;\n                }\n            },\n    \n            _nextBlock: function() {\n                var me = this,\n                    act = me._act,\n                    opts = me.options,\n                    next, done;\n    \n                // 如果当前文件还有没有需要传输的，则直接返回剩下的。\n                if ( act && act.has() &&\n                        act.file.getStatus() === Status.PROGRESS ) {\n    \n                    // 是否提前准备下一个文件\n                    if ( opts.prepareNextFile && !me.pending.length ) {\n                        me._prepareNextFile();\n                    }\n    \n                    return act.fetch();\n    \n                // 否则，如果正在运行，则准备下一个文件，并等待完成后返回下个分片。\n                } else if ( me.runing ) {\n    \n                    // 如果缓存中有，则直接在缓存中取，没有则去queue中取。\n                    if ( !me.pending.length && me.getStats().numOfQueue ) {\n                        me._prepareNextFile();\n                    }\n    \n                    next = me.pending.shift();\n                    done = function( file ) {\n                        if ( !file ) {\n                            return null;\n                        }\n    \n                        act = CuteFile( file, opts.chunked ? opts.chunkSize : 0 );\n                        me._act = act;\n                        return act.fetch();\n                    };\n    \n                    // 文件可能还在prepare中，也有可能已经完全准备好了。\n                    return isPromise( next ) ?\n                            next[ next.pipe ? 'pipe' : 'then']( done ) :\n                            done( next );\n                }\n            },\n    \n    \n            /**\n             * @event uploadStart\n             * @param {File} file File对象\n             * @description 某个文件开始上传前触发，一个文件只会触发一次。\n             * @for  Uploader\n             */\n            _prepareNextFile: function() {\n                var me = this,\n                    file = me.request('fetch-file'),\n                    pending = me.pending,\n                    promise;\n    \n                if ( file ) {\n                    promise = me.request( 'before-send-file', file, function() {\n    \n                        // 有可能文件被skip掉了。文件被skip掉后，状态坑定不是Queued.\n                        if ( file.getStatus() === Status.QUEUED ) {\n                            me.owner.trigger( 'uploadStart', file );\n                            file.setStatus( Status.PROGRESS );\n                            return file;\n                        }\n    \n                        return me._finishFile( file );\n                    });\n    \n                    // 如果还在pending中，则替换成文件本身。\n                    promise.done(function() {\n                        var idx = $.inArray( promise, pending );\n    \n                        ~idx && pending.splice( idx, 1, file );\n                    });\n    \n                    // befeore-send-file的钩子就有错误发生。\n                    promise.fail(function( reason ) {\n                        file.setStatus( Status.ERROR, reason );\n                        me.owner.trigger( 'uploadError', file, reason );\n                        me.owner.trigger( 'uploadComplete', file );\n                    });\n    \n                    pending.push( promise );\n                }\n            },\n    \n            // 让出位置了，可以让其他分片开始上传\n            _popBlock: function( block ) {\n                var idx = $.inArray( block, this.pool );\n    \n                this.pool.splice( idx, 1 );\n                block.file.remaning--;\n                this.remaning--;\n            },\n    \n            // 开始上传，可以被掉过。如果promise被reject了，则表示跳过此分片。\n            _startSend: function( block ) {\n                var me = this,\n                    file = block.file,\n                    promise;\n    \n                me.pool.push( block );\n                me.remaning++;\n    \n                // 如果没有分片，则直接使用原始的。\n                // 不会丢失content-type信息。\n                block.blob = block.chunks === 1 ? file.source :\n                        file.source.slice( block.start, block.end );\n    \n                // hook, 每个分片发送之前可能要做些异步的事情。\n                promise = me.request( 'before-send', block, function() {\n    \n                    // 有可能文件已经上传出错了，所以不需要再传输了。\n                    if ( file.getStatus() === Status.PROGRESS ) {\n                        me._doSend( block );\n                    } else {\n                        me._popBlock( block );\n                        Base.nextTick( me.__tick );\n                    }\n                });\n    \n                // 如果为fail了，则跳过此分片。\n                promise.fail(function() {\n                    if ( file.remaning === 1 ) {\n                        me._finishFile( file ).always(function() {\n                            block.percentage = 1;\n                            me._popBlock( block );\n                            me.owner.trigger( 'uploadComplete', file );\n                            Base.nextTick( me.__tick );\n                        });\n                    } else {\n                        block.percentage = 1;\n                        me._popBlock( block );\n                        Base.nextTick( me.__tick );\n                    }\n                });\n            },\n    \n    \n            /**\n             * @event uploadBeforeSend\n             * @param {Object} object\n             * @param {Object} data 默认的上传参数，可以扩展此对象来控制上传参数。\n             * @description 当某个文件的分块在发送前触发，主要用来询问是否要添加附带参数，大文件在开起分片上传的前提下此事件可能会触发多次。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadAccept\n             * @param {Object} object\n             * @param {Object} ret 服务端的返回数据，json格式，如果服务端不是json格式，从ret._raw中取数据，自行解析。\n             * @description 当某个文件上传到服务端响应后，会派送此事件来询问服务端响应是否有效。如果此事件handler返回值为`false`, 则此文件将派送`server`类型的`uploadError`事件。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadProgress\n             * @param {File} file File对象\n             * @param {Number} percentage 上传进度\n             * @description 上传过程中触发，携带上传进度。\n             * @for  Uploader\n             */\n    \n    \n            /**\n             * @event uploadError\n             * @param {File} file File对象\n             * @param {String} reason 出错的code\n             * @description 当文件上传出错时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadSuccess\n             * @param {File} file File对象\n             * @param {Object} response 服务端返回的数据\n             * @description 当文件上传成功时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadComplete\n             * @param {File} [file] File对象\n             * @description 不管成功或者失败，文件上传完成时触发。\n             * @for  Uploader\n             */\n    \n            // 做上传操作。\n            _doSend: function( block ) {\n                var me = this,\n                    owner = me.owner,\n                    opts = me.options,\n                    file = block.file,\n                    tr = new Transport( opts ),\n                    data = $.extend({}, opts.formData ),\n                    headers = $.extend({}, opts.headers ),\n                    requestAccept, ret;\n    \n                block.transport = tr;\n    \n                tr.on( 'destroy', function() {\n                    delete block.transport;\n                    me._popBlock( block );\n                    Base.nextTick( me.__tick );\n                });\n    \n                // 广播上传进度。以文件为单位。\n                tr.on( 'progress', function( percentage ) {\n                    var totalPercent = 0,\n                        uploaded = 0;\n    \n                    // 可能没有abort掉，progress还是执行进来了。\n                    // if ( !file.blocks ) {\n                    //     return;\n                    // }\n    \n                    totalPercent = block.percentage = percentage;\n    \n                    if ( block.chunks > 1 ) {    // 计算文件的整体速度。\n                        $.each( file.blocks, function( _, v ) {\n                            uploaded += (v.percentage || 0) * (v.end - v.start);\n                        });\n    \n                        totalPercent = uploaded / file.size;\n                    }\n    \n                    owner.trigger( 'uploadProgress', file, totalPercent || 0 );\n                });\n    \n                // 用来询问，是否返回的结果是有错误的。\n                requestAccept = function( reject ) {\n                    var fn;\n    \n                    ret = tr.getResponseAsJson() || {};\n                    ret._raw = tr.getResponse();\n                    fn = function( value ) {\n                        reject = value;\n                    };\n    \n                    // 服务端响应了，不代表成功了，询问是否响应正确。\n                    if ( !owner.trigger( 'uploadAccept', block, ret, fn ) ) {\n                        reject = reject || 'server';\n                    }\n    \n                    return reject;\n                };\n    \n                // 尝试重试，然后广播文件上传出错。\n                tr.on( 'error', function( type, flag ) {\n                    block.retried = block.retried || 0;\n    \n                    // 自动重试\n                    if ( block.chunks > 1 && ~'http,abort'.indexOf( type ) &&\n                            block.retried < opts.chunkRetry ) {\n    \n                        block.retried++;\n                        tr.send();\n    \n                    } else {\n    \n                        // http status 500 ~ 600\n                        if ( !flag && type === 'server' ) {\n                            type = requestAccept( type );\n                        }\n    \n                        file.setStatus( Status.ERROR, type );\n                        owner.trigger( 'uploadError', file, type );\n                        owner.trigger( 'uploadComplete', file );\n                    }\n                });\n    \n                // 上传成功\n                tr.on( 'load', function() {\n                    var reason;\n    \n                    // 如果非预期，转向上传出错。\n                    if ( (reason = requestAccept()) ) {\n                        tr.trigger( 'error', reason, true );\n                        return;\n                    }\n    \n                    // 全部上传完成。\n                    if ( file.remaning === 1 ) {\n                        me._finishFile( file, ret );\n                    } else {\n                        tr.destroy();\n                    }\n                });\n    \n                // 配置默认的上传字段。\n                data = $.extend( data, {\n                    id: file.id,\n                    name: file.name,\n                    type: file.type,\n                    lastModifiedDate: file.lastModifiedDate,\n                    size: file.size\n                });\n    \n                block.chunks > 1 && $.extend( data, {\n                    chunks: block.chunks,\n                    chunk: block.chunk\n                });\n    \n                // 在发送之间可以添加字段什么的。。。\n                // 如果默认的字段不够使用，可以通过监听此事件来扩展\n                owner.trigger( 'uploadBeforeSend', block, data, headers );\n    \n                // 开始发送。\n                tr.appendBlob( opts.fileVal, block.blob, file.name );\n                tr.append( data );\n                tr.setRequestHeader( headers );\n                tr.send();\n            },\n    \n            // 完成上传。\n            _finishFile: function( file, ret, hds ) {\n                var owner = this.owner;\n    \n                return owner\n                        .request( 'after-send-file', arguments, function() {\n                            file.setStatus( Status.COMPLETE );\n                            owner.trigger( 'uploadSuccess', file, ret, hds );\n                        })\n                        .fail(function( reason ) {\n    \n                            // 如果外部已经标记为invalid什么的，不再改状态。\n                            if ( file.getStatus() === Status.PROGRESS ) {\n                                file.setStatus( Status.ERROR, reason );\n                            }\n    \n                            owner.trigger( 'uploadError', file, reason );\n                        })\n                        .always(function() {\n                            owner.trigger( 'uploadComplete', file );\n                        });\n            }\n    \n        });\n    });\n    /**\n     * @fileOverview 各种验证，包括文件总大小是否超出、单文件是否超出和文件是否重复。\n     */\n    \n    define('widgets/validator',[\n        'base',\n        'uploader',\n        'file',\n        'widgets/widget'\n    ], function( Base, Uploader, WUFile ) {\n    \n        var $ = Base.$,\n            validators = {},\n            api;\n    \n        /**\n         * @event error\n         * @param {String} type 错误类型。\n         * @description 当validate不通过时，会以派送错误事件的形式通知调用者。通过`upload.on('error', handler)`可以捕获到此类错误，目前有以下错误会在特定的情况下派送错来。\n         *\n         * * `Q_EXCEED_NUM_LIMIT` 在设置了`fileNumLimit`且尝试给`uploader`添加的文件数量超出这个值时派送。\n         * * `Q_EXCEED_SIZE_LIMIT` 在设置了`Q_EXCEED_SIZE_LIMIT`且尝试给`uploader`添加的文件总大小超出这个值时派送。\n         * @for  Uploader\n         */\n    \n        // 暴露给外面的api\n        api = {\n    \n            // 添加验证器\n            addValidator: function( type, cb ) {\n                validators[ type ] = cb;\n            },\n    \n            // 移除验证器\n            removeValidator: function( type ) {\n                delete validators[ type ];\n            }\n        };\n    \n        // 在Uploader初始化的时候启动Validators的初始化\n        Uploader.register({\n            init: function() {\n                var me = this;\n                $.each( validators, function() {\n                    this.call( me.owner );\n                });\n            }\n        });\n    \n        /**\n         * @property {int} [fileNumLimit=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 验证文件总数量, 超出则不允许加入队列。\n         */\n        api.addValidator( 'fileNumLimit', function() {\n            var uploader = this,\n                opts = uploader.options,\n                count = 0,\n                max = opts.fileNumLimit >> 0,\n                flag = true;\n    \n            if ( !max ) {\n                return;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n    \n                if ( count >= max && flag ) {\n                    flag = false;\n                    this.trigger( 'error', 'Q_EXCEED_NUM_LIMIT', max, file );\n                    setTimeout(function() {\n                        flag = true;\n                    }, 1 );\n                }\n    \n                return count >= max ? false : true;\n            });\n    \n            uploader.on( 'fileQueued', function() {\n                count++;\n            });\n    \n            uploader.on( 'fileDequeued', function() {\n                count--;\n            });\n    \n            uploader.on( 'uploadFinished', function() {\n                count = 0;\n            });\n        });\n    \n    \n        /**\n         * @property {int} [fileSizeLimit=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 验证文件总大小是否超出限制, 超出则不允许加入队列。\n         */\n        api.addValidator( 'fileSizeLimit', function() {\n            var uploader = this,\n                opts = uploader.options,\n                count = 0,\n                max = opts.fileSizeLimit >> 0,\n                flag = true;\n    \n            if ( !max ) {\n                return;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n                var invalid = count + file.size > max;\n    \n                if ( invalid && flag ) {\n                    flag = false;\n                    this.trigger( 'error', 'Q_EXCEED_SIZE_LIMIT', max, file );\n                    setTimeout(function() {\n                        flag = true;\n                    }, 1 );\n                }\n    \n                return invalid ? false : true;\n            });\n    \n            uploader.on( 'fileQueued', function( file ) {\n                count += file.size;\n            });\n    \n            uploader.on( 'fileDequeued', function( file ) {\n                count -= file.size;\n            });\n    \n            uploader.on( 'uploadFinished', function() {\n                count = 0;\n            });\n        });\n    \n        /**\n         * @property {int} [fileSingleSizeLimit=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 验证单个文件大小是否超出限制, 超出则不允许加入队列。\n         */\n        api.addValidator( 'fileSingleSizeLimit', function() {\n            var uploader = this,\n                opts = uploader.options,\n                max = opts.fileSingleSizeLimit;\n    \n            if ( !max ) {\n                return;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n    \n                if ( file.size > max ) {\n                    file.setStatus( WUFile.Status.INVALID, 'exceed_size' );\n                    this.trigger( 'error', 'F_EXCEED_SIZE', file );\n                    return false;\n                }\n    \n            });\n    \n        });\n    \n        /**\n         * @property {int} [duplicate=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 去重， 根据文件名字、文件大小和最后修改时间来生成hash Key.\n         */\n        api.addValidator( 'duplicate', function() {\n            var uploader = this,\n                opts = uploader.options,\n                mapping = {};\n    \n            if ( opts.duplicate ) {\n                return;\n            }\n    \n            function hashString( str ) {\n                var hash = 0,\n                    i = 0,\n                    len = str.length,\n                    _char;\n    \n                for ( ; i < len; i++ ) {\n                    _char = str.charCodeAt( i );\n                    hash = _char + (hash << 6) + (hash << 16) - hash;\n                }\n    \n                return hash;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n                var hash = file.__hash || (file.__hash = hashString( file.name +\n                        file.size + file.lastModifiedDate ));\n    \n                // 已经重复了\n                if ( mapping[ hash ] ) {\n                    this.trigger( 'error', 'F_DUPLICATE', file );\n                    return false;\n                }\n            });\n    \n            uploader.on( 'fileQueued', function( file ) {\n                var hash = file.__hash;\n    \n                hash && (mapping[ hash ] = true);\n            });\n    \n            uploader.on( 'fileDequeued', function( file ) {\n                var hash = file.__hash;\n    \n                hash && (delete mapping[ hash ]);\n            });\n        });\n    \n        return api;\n    });\n    \n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/compbase',[],function() {\n    \n        function CompBase( owner, runtime ) {\n    \n            this.owner = owner;\n            this.options = owner.options;\n    \n            this.getRuntime = function() {\n                return runtime;\n            };\n    \n            this.getRuid = function() {\n                return runtime.uid;\n            };\n    \n            this.trigger = function() {\n                return owner.trigger.apply( owner, arguments );\n            };\n        }\n    \n        return CompBase;\n    });\n    /**\n     * @fileOverview Html5Runtime\n     */\n    define('runtime/html5/runtime',[\n        'base',\n        'runtime/runtime',\n        'runtime/compbase'\n    ], function( Base, Runtime, CompBase ) {\n    \n        var type = 'html5',\n            components = {};\n    \n        function Html5Runtime() {\n            var pool = {},\n                me = this,\n                destory = this.destory;\n    \n            Runtime.apply( me, arguments );\n            me.type = type;\n    \n    \n            // 这个方法的调用者，实际上是RuntimeClient\n            me.exec = function( comp, fn/*, args...*/) {\n                var client = this,\n                    uid = client.uid,\n                    args = Base.slice( arguments, 2 ),\n                    instance;\n    \n                if ( components[ comp ] ) {\n                    instance = pool[ uid ] = pool[ uid ] ||\n                            new components[ comp ]( client, me );\n    \n                    if ( instance[ fn ] ) {\n                        return instance[ fn ].apply( instance, args );\n                    }\n                }\n            };\n    \n            me.destory = function() {\n                // @todo 删除池子中的所有实例\n                return destory && destory.apply( this, arguments );\n            };\n        }\n    \n        Base.inherits( Runtime, {\n            constructor: Html5Runtime,\n    \n            // 不需要连接其他程序，直接执行callback\n            init: function() {\n                var me = this;\n                setTimeout(function() {\n                    me.trigger('ready');\n                }, 1 );\n            }\n    \n        });\n    \n        // 注册Components\n        Html5Runtime.register = function( name, component ) {\n            var klass = components[ name ] = Base.inherits( CompBase, component );\n            return klass;\n        };\n    \n        // 注册html5运行时。\n        // 只有在支持的前提下注册。\n        if ( window.Blob && window.FileReader && window.DataView ) {\n            Runtime.addRuntime( type, Html5Runtime );\n        }\n    \n        return Html5Runtime;\n    });\n    /**\n     * @fileOverview Blob Html实现\n     */\n    define('runtime/html5/blob',[\n        'runtime/html5/runtime',\n        'lib/blob'\n    ], function( Html5Runtime, Blob ) {\n    \n        return Html5Runtime.register( 'Blob', {\n            slice: function( start, end ) {\n                var blob = this.owner.source,\n                    slice = blob.slice || blob.webkitSlice || blob.mozSlice;\n    \n                blob = slice.call( blob, start, end );\n    \n                return new Blob( this.getRuid(), blob );\n            }\n        });\n    });\n    /**\n     * @fileOverview FilePaste\n     */\n    define('runtime/html5/dnd',[\n        'base',\n        'runtime/html5/runtime',\n        'lib/file'\n    ], function( Base, Html5Runtime, File ) {\n    \n        var $ = Base.$,\n            prefix = 'webuploader-dnd-';\n    \n        return Html5Runtime.register( 'DragAndDrop', {\n            init: function() {\n                var elem = this.elem = this.options.container;\n    \n                this.dragEnterHandler = Base.bindFn( this._dragEnterHandler, this );\n                this.dragOverHandler = Base.bindFn( this._dragOverHandler, this );\n                this.dragLeaveHandler = Base.bindFn( this._dragLeaveHandler, this );\n                this.dropHandler = Base.bindFn( this._dropHandler, this );\n                this.dndOver = false;\n    \n                elem.on( 'dragenter', this.dragEnterHandler );\n                elem.on( 'dragover', this.dragOverHandler );\n                elem.on( 'dragleave', this.dragLeaveHandler );\n                elem.on( 'drop', this.dropHandler );\n    \n                if ( this.options.disableGlobalDnd ) {\n                    $( document ).on( 'dragover', this.dragOverHandler );\n                    $( document ).on( 'drop', this.dropHandler );\n                }\n            },\n    \n            _dragEnterHandler: function( e ) {\n                var me = this,\n                    denied = me._denied || false,\n                    items;\n    \n                e = e.originalEvent || e;\n    \n                if ( !me.dndOver ) {\n                    me.dndOver = true;\n    \n                    // 注意只有 chrome 支持。\n                    items = e.dataTransfer.items;\n    \n                    if ( items && items.length ) {\n                        me._denied = denied = !me.trigger( 'accept', items );\n                    }\n    \n                    me.elem.addClass( prefix + 'over' );\n                    me.elem[ denied ? 'addClass' :\n                            'removeClass' ]( prefix + 'denied' );\n                }\n    \n    \n                e.dataTransfer.dropEffect = denied ? 'none' : 'copy';\n    \n                return false;\n            },\n    \n            _dragOverHandler: function( e ) {\n                // 只处理框内的。\n                var parentElem = this.elem.parent().get( 0 );\n                if ( parentElem && !$.contains( parentElem, e.currentTarget ) ) {\n                    return false;\n                }\n    \n                clearTimeout( this._leaveTimer );\n                this._dragEnterHandler.call( this, e );\n    \n                return false;\n            },\n    \n            _dragLeaveHandler: function() {\n                var me = this,\n                    handler;\n    \n                handler = function() {\n                    me.dndOver = false;\n                    me.elem.removeClass( prefix + 'over ' + prefix + 'denied' );\n                };\n    \n                clearTimeout( me._leaveTimer );\n                me._leaveTimer = setTimeout( handler, 100 );\n                return false;\n            },\n    \n            _dropHandler: function( e ) {\n                var me = this,\n                    ruid = me.getRuid(),\n                    parentElem = me.elem.parent().get( 0 );\n    \n                // 只处理框内的。\n                if ( parentElem && !$.contains( parentElem, e.currentTarget ) ) {\n                    return false;\n                }\n    \n                me._getTansferFiles( e, function( results ) {\n                    me.trigger( 'drop', $.map( results, function( file ) {\n                        return new File( ruid, file );\n                    }) );\n                });\n    \n                me.dndOver = false;\n                me.elem.removeClass( prefix + 'over' );\n                return false;\n            },\n    \n            // 如果传入 callback 则去查看文件夹，否则只管当前文件夹。\n            _getTansferFiles: function( e, callback ) {\n                var results  = [],\n                    promises = [],\n                    items, files, dataTransfer, file, item, i, len, canAccessFolder;\n    \n                e = e.originalEvent || e;\n    \n                dataTransfer = e.dataTransfer;\n                items = dataTransfer.items;\n                files = dataTransfer.files;\n    \n                canAccessFolder = !!(items && items[ 0 ].webkitGetAsEntry);\n    \n                for ( i = 0, len = files.length; i < len; i++ ) {\n                    file = files[ i ];\n                    item = items && items[ i ];\n    \n                    if ( canAccessFolder && item.webkitGetAsEntry().isDirectory ) {\n    \n                        promises.push( this._traverseDirectoryTree(\n                                item.webkitGetAsEntry(), results ) );\n                    } else {\n                        results.push( file );\n                    }\n                }\n    \n                Base.when.apply( Base, promises ).done(function() {\n    \n                    if ( !results.length ) {\n                        return;\n                    }\n    \n                    callback( results );\n                });\n            },\n    \n            _traverseDirectoryTree: function( entry, results ) {\n                var deferred = Base.Deferred(),\n                    me = this;\n    \n                if ( entry.isFile ) {\n                    entry.file(function( file ) {\n                        results.push( file );\n                        deferred.resolve();\n                    });\n                } else if ( entry.isDirectory ) {\n                    entry.createReader().readEntries(function( entries ) {\n                        var len = entries.length,\n                            promises = [],\n                            arr = [],    // 为了保证顺序。\n                            i;\n    \n                        for ( i = 0; i < len; i++ ) {\n                            promises.push( me._traverseDirectoryTree(\n                                    entries[ i ], arr ) );\n                        }\n    \n                        Base.when.apply( Base, promises ).then(function() {\n                            results.push.apply( results, arr );\n                            deferred.resolve();\n                        }, deferred.reject );\n                    });\n                }\n    \n                return deferred.promise();\n            },\n    \n            destroy: function() {\n                var elem = this.elem;\n    \n                elem.off( 'dragenter', this.dragEnterHandler );\n                elem.off( 'dragover', this.dragEnterHandler );\n                elem.off( 'dragleave', this.dragLeaveHandler );\n                elem.off( 'drop', this.dropHandler );\n    \n                if ( this.options.disableGlobalDnd ) {\n                    $( document ).off( 'dragover', this.dragOverHandler );\n                    $( document ).off( 'drop', this.dropHandler );\n                }\n            }\n        });\n    });\n    \n    /**\n     * @fileOverview FilePaste\n     */\n    define('runtime/html5/filepaste',[\n        'base',\n        'runtime/html5/runtime',\n        'lib/file'\n    ], function( Base, Html5Runtime, File ) {\n    \n        return Html5Runtime.register( 'FilePaste', {\n            init: function() {\n                var opts = this.options,\n                    elem = this.elem = opts.container,\n                    accept = '.*',\n                    arr, i, len, item;\n    \n                // accetp的mimeTypes中生成匹配正则。\n                if ( opts.accept ) {\n                    arr = [];\n    \n                    for ( i = 0, len = opts.accept.length; i < len; i++ ) {\n                        item = opts.accept[ i ].mimeTypes;\n                        item && arr.push( item );\n                    }\n    \n                    if ( arr.length ) {\n                        accept = arr.join(',');\n                        accept = accept.replace( /,/g, '|' ).replace( /\\*/g, '.*' );\n                    }\n                }\n                this.accept = accept = new RegExp( accept, 'i' );\n                this.hander = Base.bindFn( this._pasteHander, this );\n                elem.on( 'paste', this.hander );\n            },\n    \n            _pasteHander: function( e ) {\n                var allowed = [],\n                    ruid = this.getRuid(),\n                    items, item, blob, i, len;\n    \n                e = e.originalEvent || e;\n                items = e.clipboardData.items;\n    \n                for ( i = 0, len = items.length; i < len; i++ ) {\n                    item = items[ i ];\n    \n                    if ( item.kind !== 'file' || !(blob = item.getAsFile()) ) {\n                        continue;\n                    }\n    \n                    allowed.push( new File( ruid, blob ) );\n                }\n    \n                if ( allowed.length ) {\n                    // 不阻止非文件粘贴（文字粘贴）的事件冒泡\n                    e.preventDefault();\n                    e.stopPropagation();\n                    this.trigger( 'paste', allowed );\n                }\n            },\n    \n            destroy: function() {\n                this.elem.off( 'paste', this.hander );\n            }\n        });\n    });\n    \n    /**\n     * @fileOverview FilePicker\n     */\n    define('runtime/html5/filepicker',[\n        'base',\n        'runtime/html5/runtime'\n    ], function( Base, Html5Runtime ) {\n    \n        var $ = Base.$;\n    \n        return Html5Runtime.register( 'FilePicker', {\n            init: function() {\n                var container = this.getRuntime().getContainer(),\n                    me = this,\n                    owner = me.owner,\n                    opts = me.options,\n                    lable = $( document.createElement('label') ),\n                    input = $( document.createElement('input') ),\n                    arr, i, len, mouseHandler;\n    \n                input.attr( 'type', 'file' );\n                input.attr( 'name', opts.name );\n                input.addClass('webuploader-element-invisible');\n    \n                lable.on( 'click', function() {\n                    input.trigger('click');\n                });\n    \n                lable.css({\n                    opacity: 0,\n                    width: '100%',\n                    height: '100%',\n                    display: 'block',\n                    cursor: 'pointer',\n                    background: '#ffffff'\n                });\n    \n                if ( opts.multiple ) {\n                    input.attr( 'multiple', 'multiple' );\n                }\n    \n                // @todo Firefox不支持单独指定后缀\n                if ( opts.accept && opts.accept.length > 0 ) {\n                    arr = [];\n    \n                    for ( i = 0, len = opts.accept.length; i < len; i++ ) {\n                        arr.push( opts.accept[ i ].mimeTypes );\n                    }\n    \n                    input.attr( 'accept', arr.join(',') );\n                }\n    \n                container.append( input );\n                container.append( lable );\n    \n                mouseHandler = function( e ) {\n                    owner.trigger( e.type );\n                };\n    \n                input.on( 'change', function( e ) {\n                    var fn = arguments.callee,\n                        clone;\n    \n                    me.files = e.target.files;\n    \n                    // reset input\n                    clone = this.cloneNode( true );\n                    this.parentNode.replaceChild( clone, this );\n    \n                    input.off();\n                    input = $( clone ).on( 'change', fn )\n                            .on( 'mouseenter mouseleave', mouseHandler );\n    \n                    owner.trigger('change');\n                });\n    \n                lable.on( 'mouseenter mouseleave', mouseHandler );\n    \n            },\n    \n    \n            getFiles: function() {\n                return this.files;\n            },\n    \n            destroy: function() {\n                // todo\n            }\n        });\n    });\n    /**\n     * Terms:\n     *\n     * Uint8Array, FileReader, BlobBuilder, atob, ArrayBuffer\n     * @fileOverview Image控件\n     */\n    define('runtime/html5/util',[\n        'base'\n    ], function( Base ) {\n    \n        var urlAPI = window.createObjectURL && window ||\n                window.URL && URL.revokeObjectURL && URL ||\n                window.webkitURL,\n            createObjectURL = Base.noop,\n            revokeObjectURL = createObjectURL;\n    \n        if ( urlAPI ) {\n    \n            // 更安全的方式调用，比如android里面就能把context改成其他的对象。\n            createObjectURL = function() {\n                return urlAPI.createObjectURL.apply( urlAPI, arguments );\n            };\n    \n            revokeObjectURL = function() {\n                return urlAPI.revokeObjectURL.apply( urlAPI, arguments );\n            };\n        }\n    \n        return {\n            createObjectURL: createObjectURL,\n            revokeObjectURL: revokeObjectURL,\n    \n            dataURL2Blob: function( dataURI ) {\n                var byteStr, intArray, ab, i, mimetype, parts;\n    \n                parts = dataURI.split(',');\n    \n                if ( ~parts[ 0 ].indexOf('base64') ) {\n                    byteStr = atob( parts[ 1 ] );\n                } else {\n                    byteStr = decodeURIComponent( parts[ 1 ] );\n                }\n    \n                ab = new ArrayBuffer( byteStr.length );\n                intArray = new Uint8Array( ab );\n    \n                for ( i = 0; i < byteStr.length; i++ ) {\n                    intArray[ i ] = byteStr.charCodeAt( i );\n                }\n    \n                mimetype = parts[ 0 ].split(':')[ 1 ].split(';')[ 0 ];\n    \n                return this.arrayBufferToBlob( ab, mimetype );\n            },\n    \n            dataURL2ArrayBuffer: function( dataURI ) {\n                var byteStr, intArray, i, parts;\n    \n                parts = dataURI.split(',');\n    \n                if ( ~parts[ 0 ].indexOf('base64') ) {\n                    byteStr = atob( parts[ 1 ] );\n                } else {\n                    byteStr = decodeURIComponent( parts[ 1 ] );\n                }\n    \n                intArray = new Uint8Array( byteStr.length );\n    \n                for ( i = 0; i < byteStr.length; i++ ) {\n                    intArray[ i ] = byteStr.charCodeAt( i );\n                }\n    \n                return intArray.buffer;\n            },\n    \n            arrayBufferToBlob: function( buffer, type ) {\n                var builder = window.BlobBuilder || window.WebKitBlobBuilder,\n                    bb;\n    \n                // android不支持直接new Blob, 只能借助blobbuilder.\n                if ( builder ) {\n                    bb = new builder();\n                    bb.append( buffer );\n                    return bb.getBlob( type );\n                }\n    \n                return new Blob([ buffer ], type ? { type: type } : {} );\n            },\n    \n            // 抽出来主要是为了解决android下面canvas.toDataUrl不支持jpeg.\n            // 你得到的结果是png.\n            canvasToDataUrl: function( canvas, type, quality ) {\n                return canvas.toDataURL( type, quality / 100 );\n            },\n    \n            // imagemeat会复写这个方法，如果用户选择加载那个文件了的话。\n            parseMeta: function( blob, callback ) {\n                callback( false, {});\n            },\n    \n            // imagemeat会复写这个方法，如果用户选择加载那个文件了的话。\n            updateImageHead: function( data ) {\n                return data;\n            }\n        };\n    });\n    /**\n     * Terms:\n     *\n     * Uint8Array, FileReader, BlobBuilder, atob, ArrayBuffer\n     * @fileOverview Image控件\n     */\n    define('runtime/html5/imagemeta',[\n        'runtime/html5/util'\n    ], function( Util ) {\n    \n        var api;\n    \n        api = {\n            parsers: {\n                0xffe1: []\n            },\n    \n            maxMetaDataSize: 262144,\n    \n            parse: function( blob, cb ) {\n                var me = this,\n                    fr = new FileReader();\n    \n                fr.onload = function() {\n                    cb( false, me._parse( this.result ) );\n                    fr = fr.onload = fr.onerror = null;\n                };\n    \n                fr.onerror = function( e ) {\n                    cb( e.message );\n                    fr = fr.onload = fr.onerror = null;\n                };\n    \n                blob = blob.slice( 0, me.maxMetaDataSize );\n                fr.readAsArrayBuffer( blob.getSource() );\n            },\n    \n            _parse: function( buffer, noParse ) {\n                if ( buffer.byteLength < 6 ) {\n                    return;\n                }\n    \n                var dataview = new DataView( buffer ),\n                    offset = 2,\n                    maxOffset = dataview.byteLength - 4,\n                    headLength = offset,\n                    ret = {},\n                    markerBytes, markerLength, parsers, i;\n    \n                if ( dataview.getUint16( 0 ) === 0xffd8 ) {\n    \n                    while ( offset < maxOffset ) {\n                        markerBytes = dataview.getUint16( offset );\n    \n                        if ( markerBytes >= 0xffe0 && markerBytes <= 0xffef ||\n                                markerBytes === 0xfffe ) {\n    \n                            markerLength = dataview.getUint16( offset + 2 ) + 2;\n    \n                            if ( offset + markerLength > dataview.byteLength ) {\n                                break;\n                            }\n    \n                            parsers = api.parsers[ markerBytes ];\n    \n                            if ( !noParse && parsers ) {\n                                for ( i = 0; i < parsers.length; i += 1 ) {\n                                    parsers[ i ].call( api, dataview, offset,\n                                            markerLength, ret );\n                                }\n                            }\n    \n                            offset += markerLength;\n                            headLength = offset;\n                        } else {\n                            break;\n                        }\n                    }\n    \n                    if ( headLength > 6 ) {\n                        if ( buffer.slice ) {\n                            ret.imageHead = buffer.slice( 2, headLength );\n                        } else {\n                            // Workaround for IE10, which does not yet\n                            // support ArrayBuffer.slice:\n                            ret.imageHead = new Uint8Array( buffer )\n                                    .subarray( 2, headLength );\n                        }\n                    }\n                }\n    \n                return ret;\n            },\n    \n            updateImageHead: function( buffer, head ) {\n                var data = this._parse( buffer, true ),\n                    buf1, buf2, bodyoffset;\n    \n    \n                bodyoffset = 2;\n                if ( data.imageHead ) {\n                    bodyoffset = 2 + data.imageHead.byteLength;\n                }\n    \n                if ( buffer.slice ) {\n                    buf2 = buffer.slice( bodyoffset );\n                } else {\n                    buf2 = new Uint8Array( buffer ).subarray( bodyoffset );\n                }\n    \n                buf1 = new Uint8Array( head.byteLength + 2 + buf2.byteLength );\n    \n                buf1[ 0 ] = 0xFF;\n                buf1[ 1 ] = 0xD8;\n                buf1.set( new Uint8Array( head ), 2 );\n                buf1.set( new Uint8Array( buf2 ), head.byteLength + 2 );\n    \n                return buf1.buffer;\n            }\n        };\n    \n        Util.parseMeta = function() {\n            return api.parse.apply( api, arguments );\n        };\n    \n        Util.updateImageHead = function() {\n            return api.updateImageHead.apply( api, arguments );\n        };\n    \n        return api;\n    });\n    /**\n     * 代码来自于：https://github.com/blueimp/JavaScript-Load-Image\n     * 暂时项目中只用了orientation.\n     *\n     * 去除了 Exif Sub IFD Pointer, GPS Info IFD Pointer, Exif Thumbnail.\n     * @fileOverview EXIF解析\n     */\n    \n    // Sample\n    // ====================================\n    // Make : Apple\n    // Model : iPhone 4S\n    // Orientation : 1\n    // XResolution : 72 [72/1]\n    // YResolution : 72 [72/1]\n    // ResolutionUnit : 2\n    // Software : QuickTime 7.7.1\n    // DateTime : 2013:09:01 22:53:55\n    // ExifIFDPointer : 190\n    // ExposureTime : 0.058823529411764705 [1/17]\n    // FNumber : 2.4 [12/5]\n    // ExposureProgram : Normal program\n    // ISOSpeedRatings : 800\n    // ExifVersion : 0220\n    // DateTimeOriginal : 2013:09:01 22:52:51\n    // DateTimeDigitized : 2013:09:01 22:52:51\n    // ComponentsConfiguration : YCbCr\n    // ShutterSpeedValue : 4.058893515764426\n    // ApertureValue : 2.5260688216892597 [4845/1918]\n    // BrightnessValue : -0.3126686601998395\n    // MeteringMode : Pattern\n    // Flash : Flash did not fire, compulsory flash mode\n    // FocalLength : 4.28 [107/25]\n    // SubjectArea : [4 values]\n    // FlashpixVersion : 0100\n    // ColorSpace : 1\n    // PixelXDimension : 2448\n    // PixelYDimension : 3264\n    // SensingMethod : One-chip color area sensor\n    // ExposureMode : 0\n    // WhiteBalance : Auto white balance\n    // FocalLengthIn35mmFilm : 35\n    // SceneCaptureType : Standard\n    define('runtime/html5/imagemeta/exif',[\n        'base',\n        'runtime/html5/imagemeta'\n    ], function( Base, ImageMeta ) {\n    \n        var EXIF = {};\n    \n        EXIF.ExifMap = function() {\n            return this;\n        };\n    \n        EXIF.ExifMap.prototype.map = {\n            'Orientation': 0x0112\n        };\n    \n        EXIF.ExifMap.prototype.get = function( id ) {\n            return this[ id ] || this[ this.map[ id ] ];\n        };\n    \n        EXIF.exifTagTypes = {\n            // byte, 8-bit unsigned int:\n            1: {\n                getValue: function( dataView, dataOffset ) {\n                    return dataView.getUint8( dataOffset );\n                },\n                size: 1\n            },\n    \n            // ascii, 8-bit byte:\n            2: {\n                getValue: function( dataView, dataOffset ) {\n                    return String.fromCharCode( dataView.getUint8( dataOffset ) );\n                },\n                size: 1,\n                ascii: true\n            },\n    \n            // short, 16 bit int:\n            3: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getUint16( dataOffset, littleEndian );\n                },\n                size: 2\n            },\n    \n            // long, 32 bit int:\n            4: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getUint32( dataOffset, littleEndian );\n                },\n                size: 4\n            },\n    \n            // rational = two long values,\n            // first is numerator, second is denominator:\n            5: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getUint32( dataOffset, littleEndian ) /\n                        dataView.getUint32( dataOffset + 4, littleEndian );\n                },\n                size: 8\n            },\n    \n            // slong, 32 bit signed int:\n            9: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getInt32( dataOffset, littleEndian );\n                },\n                size: 4\n            },\n    \n            // srational, two slongs, first is numerator, second is denominator:\n            10: {\n                getValue: function( dataView, dataOffset, littleEndian ) {\n                    return dataView.getInt32( dataOffset, littleEndian ) /\n                        dataView.getInt32( dataOffset + 4, littleEndian );\n                },\n                size: 8\n            }\n        };\n    \n        // undefined, 8-bit byte, value depending on field:\n        EXIF.exifTagTypes[ 7 ] = EXIF.exifTagTypes[ 1 ];\n    \n        EXIF.getExifValue = function( dataView, tiffOffset, offset, type, length,\n                littleEndian ) {\n    \n            var tagType = EXIF.exifTagTypes[ type ],\n                tagSize, dataOffset, values, i, str, c;\n    \n            if ( !tagType ) {\n                Base.log('Invalid Exif data: Invalid tag type.');\n                return;\n            }\n    \n            tagSize = tagType.size * length;\n    \n            // Determine if the value is contained in the dataOffset bytes,\n            // or if the value at the dataOffset is a pointer to the actual data:\n            dataOffset = tagSize > 4 ? tiffOffset + dataView.getUint32( offset + 8,\n                    littleEndian ) : (offset + 8);\n    \n            if ( dataOffset + tagSize > dataView.byteLength ) {\n                Base.log('Invalid Exif data: Invalid data offset.');\n                return;\n            }\n    \n            if ( length === 1 ) {\n                return tagType.getValue( dataView, dataOffset, littleEndian );\n            }\n    \n            values = [];\n    \n            for ( i = 0; i < length; i += 1 ) {\n                values[ i ] = tagType.getValue( dataView,\n                        dataOffset + i * tagType.size, littleEndian );\n            }\n    \n            if ( tagType.ascii ) {\n                str = '';\n    \n                // Concatenate the chars:\n                for ( i = 0; i < values.length; i += 1 ) {\n                    c = values[ i ];\n    \n                    // Ignore the terminating NULL byte(s):\n                    if ( c === '\\u0000' ) {\n                        break;\n                    }\n                    str += c;\n                }\n    \n                return str;\n            }\n            return values;\n        };\n    \n        EXIF.parseExifTag = function( dataView, tiffOffset, offset, littleEndian,\n                data ) {\n    \n            var tag = dataView.getUint16( offset, littleEndian );\n            data.exif[ tag ] = EXIF.getExifValue( dataView, tiffOffset, offset,\n                    dataView.getUint16( offset + 2, littleEndian ),    // tag type\n                    dataView.getUint32( offset + 4, littleEndian ),    // tag length\n                    littleEndian );\n        };\n    \n        EXIF.parseExifTags = function( dataView, tiffOffset, dirOffset,\n                littleEndian, data ) {\n    \n            var tagsNumber, dirEndOffset, i;\n    \n            if ( dirOffset + 6 > dataView.byteLength ) {\n                Base.log('Invalid Exif data: Invalid directory offset.');\n                return;\n            }\n    \n            tagsNumber = dataView.getUint16( dirOffset, littleEndian );\n            dirEndOffset = dirOffset + 2 + 12 * tagsNumber;\n    \n            if ( dirEndOffset + 4 > dataView.byteLength ) {\n                Base.log('Invalid Exif data: Invalid directory size.');\n                return;\n            }\n    \n            for ( i = 0; i < tagsNumber; i += 1 ) {\n                this.parseExifTag( dataView, tiffOffset,\n                        dirOffset + 2 + 12 * i,    // tag offset\n                        littleEndian, data );\n            }\n    \n            // Return the offset to the next directory:\n            return dataView.getUint32( dirEndOffset, littleEndian );\n        };\n    \n        // EXIF.getExifThumbnail = function(dataView, offset, length) {\n        //     var hexData,\n        //         i,\n        //         b;\n        //     if (!length || offset + length > dataView.byteLength) {\n        //         Base.log('Invalid Exif data: Invalid thumbnail data.');\n        //         return;\n        //     }\n        //     hexData = [];\n        //     for (i = 0; i < length; i += 1) {\n        //         b = dataView.getUint8(offset + i);\n        //         hexData.push((b < 16 ? '0' : '') + b.toString(16));\n        //     }\n        //     return 'data:image/jpeg,%' + hexData.join('%');\n        // };\n    \n        EXIF.parseExifData = function( dataView, offset, length, data ) {\n    \n            var tiffOffset = offset + 10,\n                littleEndian, dirOffset;\n    \n            // Check for the ASCII code for \"Exif\" (0x45786966):\n            if ( dataView.getUint32( offset + 4 ) !== 0x45786966 ) {\n                // No Exif data, might be XMP data instead\n                return;\n            }\n            if ( tiffOffset + 8 > dataView.byteLength ) {\n                Base.log('Invalid Exif data: Invalid segment size.');\n                return;\n            }\n    \n            // Check for the two null bytes:\n            if ( dataView.getUint16( offset + 8 ) !== 0x0000 ) {\n                Base.log('Invalid Exif data: Missing byte alignment offset.');\n                return;\n            }\n    \n            // Check the byte alignment:\n            switch ( dataView.getUint16( tiffOffset ) ) {\n                case 0x4949:\n                    littleEndian = true;\n                    break;\n    \n                case 0x4D4D:\n                    littleEndian = false;\n                    break;\n    \n                default:\n                    Base.log('Invalid Exif data: Invalid byte alignment marker.');\n                    return;\n            }\n    \n            // Check for the TIFF tag marker (0x002A):\n            if ( dataView.getUint16( tiffOffset + 2, littleEndian ) !== 0x002A ) {\n                Base.log('Invalid Exif data: Missing TIFF marker.');\n                return;\n            }\n    \n            // Retrieve the directory offset bytes, usually 0x00000008 or 8 decimal:\n            dirOffset = dataView.getUint32( tiffOffset + 4, littleEndian );\n            // Create the exif object to store the tags:\n            data.exif = new EXIF.ExifMap();\n            // Parse the tags of the main image directory and retrieve the\n            // offset to the next directory, usually the thumbnail directory:\n            dirOffset = EXIF.parseExifTags( dataView, tiffOffset,\n                    tiffOffset + dirOffset, littleEndian, data );\n    \n            // 尝试读取缩略图\n            // if ( dirOffset ) {\n            //     thumbnailData = {exif: {}};\n            //     dirOffset = EXIF.parseExifTags(\n            //         dataView,\n            //         tiffOffset,\n            //         tiffOffset + dirOffset,\n            //         littleEndian,\n            //         thumbnailData\n            //     );\n    \n            //     // Check for JPEG Thumbnail offset:\n            //     if (thumbnailData.exif[0x0201]) {\n            //         data.exif.Thumbnail = EXIF.getExifThumbnail(\n            //             dataView,\n            //             tiffOffset + thumbnailData.exif[0x0201],\n            //             thumbnailData.exif[0x0202] // Thumbnail data length\n            //         );\n            //     }\n            // }\n        };\n    \n        ImageMeta.parsers[ 0xffe1 ].push( EXIF.parseExifData );\n        return EXIF;\n    });\n    /**\n     * 这个方式性能不行，但是可以解决android里面的toDataUrl的bug\n     * android里面toDataUrl('image/jpege')得到的结果却是png.\n     *\n     * 所以这里没辙，只能借助这个工具\n     * @fileOverview jpeg encoder\n     */\n    define('runtime/html5/jpegencoder',[], function( require, exports, module ) {\n    \n        /*\n          Copyright (c) 2008, Adobe Systems Incorporated\n          All rights reserved.\n    \n          Redistribution and use in source and binary forms, with or without\n          modification, are permitted provided that the following conditions are\n          met:\n    \n          * Redistributions of source code must retain the above copyright notice,\n            this list of conditions and the following disclaimer.\n    \n          * Redistributions in binary form must reproduce the above copyright\n            notice, this list of conditions and the following disclaimer in the\n            documentation and/or other materials provided with the distribution.\n    \n          * Neither the name of Adobe Systems Incorporated nor the names of its\n            contributors may be used to endorse or promote products derived from\n            this software without specific prior written permission.\n    \n          THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS\n          IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,\n          THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\n          PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR\n          CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,\n          EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,\n          PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR\n          PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF\n          LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING\n          NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS\n          SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n        */\n        /*\n        JPEG encoder ported to JavaScript and optimized by Andreas Ritter, www.bytestrom.eu, 11/2009\n    \n        Basic GUI blocking jpeg encoder\n        */\n    \n        function JPEGEncoder(quality) {\n          var self = this;\n            var fround = Math.round;\n            var ffloor = Math.floor;\n            var YTable = new Array(64);\n            var UVTable = new Array(64);\n            var fdtbl_Y = new Array(64);\n            var fdtbl_UV = new Array(64);\n            var YDC_HT;\n            var UVDC_HT;\n            var YAC_HT;\n            var UVAC_HT;\n    \n            var bitcode = new Array(65535);\n            var category = new Array(65535);\n            var outputfDCTQuant = new Array(64);\n            var DU = new Array(64);\n            var byteout = [];\n            var bytenew = 0;\n            var bytepos = 7;\n    \n            var YDU = new Array(64);\n            var UDU = new Array(64);\n            var VDU = new Array(64);\n            var clt = new Array(256);\n            var RGB_YUV_TABLE = new Array(2048);\n            var currentQuality;\n    \n            var ZigZag = [\n                     0, 1, 5, 6,14,15,27,28,\n                     2, 4, 7,13,16,26,29,42,\n                     3, 8,12,17,25,30,41,43,\n                     9,11,18,24,31,40,44,53,\n                    10,19,23,32,39,45,52,54,\n                    20,22,33,38,46,51,55,60,\n                    21,34,37,47,50,56,59,61,\n                    35,36,48,49,57,58,62,63\n                ];\n    \n            var std_dc_luminance_nrcodes = [0,0,1,5,1,1,1,1,1,1,0,0,0,0,0,0,0];\n            var std_dc_luminance_values = [0,1,2,3,4,5,6,7,8,9,10,11];\n            var std_ac_luminance_nrcodes = [0,0,2,1,3,3,2,4,3,5,5,4,4,0,0,1,0x7d];\n            var std_ac_luminance_values = [\n                    0x01,0x02,0x03,0x00,0x04,0x11,0x05,0x12,\n                    0x21,0x31,0x41,0x06,0x13,0x51,0x61,0x07,\n                    0x22,0x71,0x14,0x32,0x81,0x91,0xa1,0x08,\n                    0x23,0x42,0xb1,0xc1,0x15,0x52,0xd1,0xf0,\n                    0x24,0x33,0x62,0x72,0x82,0x09,0x0a,0x16,\n                    0x17,0x18,0x19,0x1a,0x25,0x26,0x27,0x28,\n                    0x29,0x2a,0x34,0x35,0x36,0x37,0x38,0x39,\n                    0x3a,0x43,0x44,0x45,0x46,0x47,0x48,0x49,\n                    0x4a,0x53,0x54,0x55,0x56,0x57,0x58,0x59,\n                    0x5a,0x63,0x64,0x65,0x66,0x67,0x68,0x69,\n                    0x6a,0x73,0x74,0x75,0x76,0x77,0x78,0x79,\n                    0x7a,0x83,0x84,0x85,0x86,0x87,0x88,0x89,\n                    0x8a,0x92,0x93,0x94,0x95,0x96,0x97,0x98,\n                    0x99,0x9a,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7,\n                    0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,0xb5,0xb6,\n                    0xb7,0xb8,0xb9,0xba,0xc2,0xc3,0xc4,0xc5,\n                    0xc6,0xc7,0xc8,0xc9,0xca,0xd2,0xd3,0xd4,\n                    0xd5,0xd6,0xd7,0xd8,0xd9,0xda,0xe1,0xe2,\n                    0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,0xea,\n                    0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,\n                    0xf9,0xfa\n                ];\n    \n            var std_dc_chrominance_nrcodes = [0,0,3,1,1,1,1,1,1,1,1,1,0,0,0,0,0];\n            var std_dc_chrominance_values = [0,1,2,3,4,5,6,7,8,9,10,11];\n            var std_ac_chrominance_nrcodes = [0,0,2,1,2,4,4,3,4,7,5,4,4,0,1,2,0x77];\n            var std_ac_chrominance_values = [\n                    0x00,0x01,0x02,0x03,0x11,0x04,0x05,0x21,\n                    0x31,0x06,0x12,0x41,0x51,0x07,0x61,0x71,\n                    0x13,0x22,0x32,0x81,0x08,0x14,0x42,0x91,\n                    0xa1,0xb1,0xc1,0x09,0x23,0x33,0x52,0xf0,\n                    0x15,0x62,0x72,0xd1,0x0a,0x16,0x24,0x34,\n                    0xe1,0x25,0xf1,0x17,0x18,0x19,0x1a,0x26,\n                    0x27,0x28,0x29,0x2a,0x35,0x36,0x37,0x38,\n                    0x39,0x3a,0x43,0x44,0x45,0x46,0x47,0x48,\n                    0x49,0x4a,0x53,0x54,0x55,0x56,0x57,0x58,\n                    0x59,0x5a,0x63,0x64,0x65,0x66,0x67,0x68,\n                    0x69,0x6a,0x73,0x74,0x75,0x76,0x77,0x78,\n                    0x79,0x7a,0x82,0x83,0x84,0x85,0x86,0x87,\n                    0x88,0x89,0x8a,0x92,0x93,0x94,0x95,0x96,\n                    0x97,0x98,0x99,0x9a,0xa2,0xa3,0xa4,0xa5,\n                    0xa6,0xa7,0xa8,0xa9,0xaa,0xb2,0xb3,0xb4,\n                    0xb5,0xb6,0xb7,0xb8,0xb9,0xba,0xc2,0xc3,\n                    0xc4,0xc5,0xc6,0xc7,0xc8,0xc9,0xca,0xd2,\n                    0xd3,0xd4,0xd5,0xd6,0xd7,0xd8,0xd9,0xda,\n                    0xe2,0xe3,0xe4,0xe5,0xe6,0xe7,0xe8,0xe9,\n                    0xea,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7,0xf8,\n                    0xf9,0xfa\n                ];\n    \n            function initQuantTables(sf){\n                    var YQT = [\n                        16, 11, 10, 16, 24, 40, 51, 61,\n                        12, 12, 14, 19, 26, 58, 60, 55,\n                        14, 13, 16, 24, 40, 57, 69, 56,\n                        14, 17, 22, 29, 51, 87, 80, 62,\n                        18, 22, 37, 56, 68,109,103, 77,\n                        24, 35, 55, 64, 81,104,113, 92,\n                        49, 64, 78, 87,103,121,120,101,\n                        72, 92, 95, 98,112,100,103, 99\n                    ];\n    \n                    for (var i = 0; i < 64; i++) {\n                        var t = ffloor((YQT[i]*sf+50)/100);\n                        if (t < 1) {\n                            t = 1;\n                        } else if (t > 255) {\n                            t = 255;\n                        }\n                        YTable[ZigZag[i]] = t;\n                    }\n                    var UVQT = [\n                        17, 18, 24, 47, 99, 99, 99, 99,\n                        18, 21, 26, 66, 99, 99, 99, 99,\n                        24, 26, 56, 99, 99, 99, 99, 99,\n                        47, 66, 99, 99, 99, 99, 99, 99,\n                        99, 99, 99, 99, 99, 99, 99, 99,\n                        99, 99, 99, 99, 99, 99, 99, 99,\n                        99, 99, 99, 99, 99, 99, 99, 99,\n                        99, 99, 99, 99, 99, 99, 99, 99\n                    ];\n                    for (var j = 0; j < 64; j++) {\n                        var u = ffloor((UVQT[j]*sf+50)/100);\n                        if (u < 1) {\n                            u = 1;\n                        } else if (u > 255) {\n                            u = 255;\n                        }\n                        UVTable[ZigZag[j]] = u;\n                    }\n                    var aasf = [\n                        1.0, 1.387039845, 1.306562965, 1.175875602,\n                        1.0, 0.785694958, 0.541196100, 0.275899379\n                    ];\n                    var k = 0;\n                    for (var row = 0; row < 8; row++)\n                    {\n                        for (var col = 0; col < 8; col++)\n                        {\n                            fdtbl_Y[k]  = (1.0 / (YTable [ZigZag[k]] * aasf[row] * aasf[col] * 8.0));\n                            fdtbl_UV[k] = (1.0 / (UVTable[ZigZag[k]] * aasf[row] * aasf[col] * 8.0));\n                            k++;\n                        }\n                    }\n                }\n    \n                function computeHuffmanTbl(nrcodes, std_table){\n                    var codevalue = 0;\n                    var pos_in_table = 0;\n                    var HT = new Array();\n                    for (var k = 1; k <= 16; k++) {\n                        for (var j = 1; j <= nrcodes[k]; j++) {\n                            HT[std_table[pos_in_table]] = [];\n                            HT[std_table[pos_in_table]][0] = codevalue;\n                            HT[std_table[pos_in_table]][1] = k;\n                            pos_in_table++;\n                            codevalue++;\n                        }\n                        codevalue*=2;\n                    }\n                    return HT;\n                }\n    \n                function initHuffmanTbl()\n                {\n                    YDC_HT = computeHuffmanTbl(std_dc_luminance_nrcodes,std_dc_luminance_values);\n                    UVDC_HT = computeHuffmanTbl(std_dc_chrominance_nrcodes,std_dc_chrominance_values);\n                    YAC_HT = computeHuffmanTbl(std_ac_luminance_nrcodes,std_ac_luminance_values);\n                    UVAC_HT = computeHuffmanTbl(std_ac_chrominance_nrcodes,std_ac_chrominance_values);\n                }\n    \n                function initCategoryNumber()\n                {\n                    var nrlower = 1;\n                    var nrupper = 2;\n                    for (var cat = 1; cat <= 15; cat++) {\n                        //Positive numbers\n                        for (var nr = nrlower; nr<nrupper; nr++) {\n                            category[32767+nr] = cat;\n                            bitcode[32767+nr] = [];\n                            bitcode[32767+nr][1] = cat;\n                            bitcode[32767+nr][0] = nr;\n                        }\n                        //Negative numbers\n                        for (var nrneg =-(nrupper-1); nrneg<=-nrlower; nrneg++) {\n                            category[32767+nrneg] = cat;\n                            bitcode[32767+nrneg] = [];\n                            bitcode[32767+nrneg][1] = cat;\n                            bitcode[32767+nrneg][0] = nrupper-1+nrneg;\n                        }\n                        nrlower <<= 1;\n                        nrupper <<= 1;\n                    }\n                }\n    \n                function initRGBYUVTable() {\n                    for(var i = 0; i < 256;i++) {\n                        RGB_YUV_TABLE[i]            =  19595 * i;\n                        RGB_YUV_TABLE[(i+ 256)>>0]  =  38470 * i;\n                        RGB_YUV_TABLE[(i+ 512)>>0]  =   7471 * i + 0x8000;\n                        RGB_YUV_TABLE[(i+ 768)>>0]  = -11059 * i;\n                        RGB_YUV_TABLE[(i+1024)>>0]  = -21709 * i;\n                        RGB_YUV_TABLE[(i+1280)>>0]  =  32768 * i + 0x807FFF;\n                        RGB_YUV_TABLE[(i+1536)>>0]  = -27439 * i;\n                        RGB_YUV_TABLE[(i+1792)>>0]  = - 5329 * i;\n                    }\n                }\n    \n                // IO functions\n                function writeBits(bs)\n                {\n                    var value = bs[0];\n                    var posval = bs[1]-1;\n                    while ( posval >= 0 ) {\n                        if (value & (1 << posval) ) {\n                            bytenew |= (1 << bytepos);\n                        }\n                        posval--;\n                        bytepos--;\n                        if (bytepos < 0) {\n                            if (bytenew == 0xFF) {\n                                writeByte(0xFF);\n                                writeByte(0);\n                            }\n                            else {\n                                writeByte(bytenew);\n                            }\n                            bytepos=7;\n                            bytenew=0;\n                        }\n                    }\n                }\n    \n                function writeByte(value)\n                {\n                    byteout.push(clt[value]); // write char directly instead of converting later\n                }\n    \n                function writeWord(value)\n                {\n                    writeByte((value>>8)&0xFF);\n                    writeByte((value   )&0xFF);\n                }\n    \n                // DCT & quantization core\n                function fDCTQuant(data, fdtbl)\n                {\n                    var d0, d1, d2, d3, d4, d5, d6, d7;\n                    /* Pass 1: process rows. */\n                    var dataOff=0;\n                    var i;\n                    var I8 = 8;\n                    var I64 = 64;\n                    for (i=0; i<I8; ++i)\n                    {\n                        d0 = data[dataOff];\n                        d1 = data[dataOff+1];\n                        d2 = data[dataOff+2];\n                        d3 = data[dataOff+3];\n                        d4 = data[dataOff+4];\n                        d5 = data[dataOff+5];\n                        d6 = data[dataOff+6];\n                        d7 = data[dataOff+7];\n    \n                        var tmp0 = d0 + d7;\n                        var tmp7 = d0 - d7;\n                        var tmp1 = d1 + d6;\n                        var tmp6 = d1 - d6;\n                        var tmp2 = d2 + d5;\n                        var tmp5 = d2 - d5;\n                        var tmp3 = d3 + d4;\n                        var tmp4 = d3 - d4;\n    \n                        /* Even part */\n                        var tmp10 = tmp0 + tmp3;    /* phase 2 */\n                        var tmp13 = tmp0 - tmp3;\n                        var tmp11 = tmp1 + tmp2;\n                        var tmp12 = tmp1 - tmp2;\n    \n                        data[dataOff] = tmp10 + tmp11; /* phase 3 */\n                        data[dataOff+4] = tmp10 - tmp11;\n    \n                        var z1 = (tmp12 + tmp13) * 0.707106781; /* c4 */\n                        data[dataOff+2] = tmp13 + z1; /* phase 5 */\n                        data[dataOff+6] = tmp13 - z1;\n    \n                        /* Odd part */\n                        tmp10 = tmp4 + tmp5; /* phase 2 */\n                        tmp11 = tmp5 + tmp6;\n                        tmp12 = tmp6 + tmp7;\n    \n                        /* The rotator is modified from fig 4-8 to avoid extra negations. */\n                        var z5 = (tmp10 - tmp12) * 0.382683433; /* c6 */\n                        var z2 = 0.541196100 * tmp10 + z5; /* c2-c6 */\n                        var z4 = 1.306562965 * tmp12 + z5; /* c2+c6 */\n                        var z3 = tmp11 * 0.707106781; /* c4 */\n    \n                        var z11 = tmp7 + z3;    /* phase 5 */\n                        var z13 = tmp7 - z3;\n    \n                        data[dataOff+5] = z13 + z2; /* phase 6 */\n                        data[dataOff+3] = z13 - z2;\n                        data[dataOff+1] = z11 + z4;\n                        data[dataOff+7] = z11 - z4;\n    \n                        dataOff += 8; /* advance pointer to next row */\n                    }\n    \n                    /* Pass 2: process columns. */\n                    dataOff = 0;\n                    for (i=0; i<I8; ++i)\n                    {\n                        d0 = data[dataOff];\n                        d1 = data[dataOff + 8];\n                        d2 = data[dataOff + 16];\n                        d3 = data[dataOff + 24];\n                        d4 = data[dataOff + 32];\n                        d5 = data[dataOff + 40];\n                        d6 = data[dataOff + 48];\n                        d7 = data[dataOff + 56];\n    \n                        var tmp0p2 = d0 + d7;\n                        var tmp7p2 = d0 - d7;\n                        var tmp1p2 = d1 + d6;\n                        var tmp6p2 = d1 - d6;\n                        var tmp2p2 = d2 + d5;\n                        var tmp5p2 = d2 - d5;\n                        var tmp3p2 = d3 + d4;\n                        var tmp4p2 = d3 - d4;\n    \n                        /* Even part */\n                        var tmp10p2 = tmp0p2 + tmp3p2;  /* phase 2 */\n                        var tmp13p2 = tmp0p2 - tmp3p2;\n                        var tmp11p2 = tmp1p2 + tmp2p2;\n                        var tmp12p2 = tmp1p2 - tmp2p2;\n    \n                        data[dataOff] = tmp10p2 + tmp11p2; /* phase 3 */\n                        data[dataOff+32] = tmp10p2 - tmp11p2;\n    \n                        var z1p2 = (tmp12p2 + tmp13p2) * 0.707106781; /* c4 */\n                        data[dataOff+16] = tmp13p2 + z1p2; /* phase 5 */\n                        data[dataOff+48] = tmp13p2 - z1p2;\n    \n                        /* Odd part */\n                        tmp10p2 = tmp4p2 + tmp5p2; /* phase 2 */\n                        tmp11p2 = tmp5p2 + tmp6p2;\n                        tmp12p2 = tmp6p2 + tmp7p2;\n    \n                        /* The rotator is modified from fig 4-8 to avoid extra negations. */\n                        var z5p2 = (tmp10p2 - tmp12p2) * 0.382683433; /* c6 */\n                        var z2p2 = 0.541196100 * tmp10p2 + z5p2; /* c2-c6 */\n                        var z4p2 = 1.306562965 * tmp12p2 + z5p2; /* c2+c6 */\n                        var z3p2 = tmp11p2 * 0.707106781; /* c4 */\n    \n                        var z11p2 = tmp7p2 + z3p2;  /* phase 5 */\n                        var z13p2 = tmp7p2 - z3p2;\n    \n                        data[dataOff+40] = z13p2 + z2p2; /* phase 6 */\n                        data[dataOff+24] = z13p2 - z2p2;\n                        data[dataOff+ 8] = z11p2 + z4p2;\n                        data[dataOff+56] = z11p2 - z4p2;\n    \n                        dataOff++; /* advance pointer to next column */\n                    }\n    \n                    // Quantize/descale the coefficients\n                    var fDCTQuant;\n                    for (i=0; i<I64; ++i)\n                    {\n                        // Apply the quantization and scaling factor & Round to nearest integer\n                        fDCTQuant = data[i]*fdtbl[i];\n                        outputfDCTQuant[i] = (fDCTQuant > 0.0) ? ((fDCTQuant + 0.5)|0) : ((fDCTQuant - 0.5)|0);\n                        //outputfDCTQuant[i] = fround(fDCTQuant);\n    \n                    }\n                    return outputfDCTQuant;\n                }\n    \n                function writeAPP0()\n                {\n                    writeWord(0xFFE0); // marker\n                    writeWord(16); // length\n                    writeByte(0x4A); // J\n                    writeByte(0x46); // F\n                    writeByte(0x49); // I\n                    writeByte(0x46); // F\n                    writeByte(0); // = \"JFIF\",'\\0'\n                    writeByte(1); // versionhi\n                    writeByte(1); // versionlo\n                    writeByte(0); // xyunits\n                    writeWord(1); // xdensity\n                    writeWord(1); // ydensity\n                    writeByte(0); // thumbnwidth\n                    writeByte(0); // thumbnheight\n                }\n    \n                function writeSOF0(width, height)\n                {\n                    writeWord(0xFFC0); // marker\n                    writeWord(17);   // length, truecolor YUV JPG\n                    writeByte(8);    // precision\n                    writeWord(height);\n                    writeWord(width);\n                    writeByte(3);    // nrofcomponents\n                    writeByte(1);    // IdY\n                    writeByte(0x11); // HVY\n                    writeByte(0);    // QTY\n                    writeByte(2);    // IdU\n                    writeByte(0x11); // HVU\n                    writeByte(1);    // QTU\n                    writeByte(3);    // IdV\n                    writeByte(0x11); // HVV\n                    writeByte(1);    // QTV\n                }\n    \n                function writeDQT()\n                {\n                    writeWord(0xFFDB); // marker\n                    writeWord(132);    // length\n                    writeByte(0);\n                    for (var i=0; i<64; i++) {\n                        writeByte(YTable[i]);\n                    }\n                    writeByte(1);\n                    for (var j=0; j<64; j++) {\n                        writeByte(UVTable[j]);\n                    }\n                }\n    \n                function writeDHT()\n                {\n                    writeWord(0xFFC4); // marker\n                    writeWord(0x01A2); // length\n    \n                    writeByte(0); // HTYDCinfo\n                    for (var i=0; i<16; i++) {\n                        writeByte(std_dc_luminance_nrcodes[i+1]);\n                    }\n                    for (var j=0; j<=11; j++) {\n                        writeByte(std_dc_luminance_values[j]);\n                    }\n    \n                    writeByte(0x10); // HTYACinfo\n                    for (var k=0; k<16; k++) {\n                        writeByte(std_ac_luminance_nrcodes[k+1]);\n                    }\n                    for (var l=0; l<=161; l++) {\n                        writeByte(std_ac_luminance_values[l]);\n                    }\n    \n                    writeByte(1); // HTUDCinfo\n                    for (var m=0; m<16; m++) {\n                        writeByte(std_dc_chrominance_nrcodes[m+1]);\n                    }\n                    for (var n=0; n<=11; n++) {\n                        writeByte(std_dc_chrominance_values[n]);\n                    }\n    \n                    writeByte(0x11); // HTUACinfo\n                    for (var o=0; o<16; o++) {\n                        writeByte(std_ac_chrominance_nrcodes[o+1]);\n                    }\n                    for (var p=0; p<=161; p++) {\n                        writeByte(std_ac_chrominance_values[p]);\n                    }\n                }\n    \n                function writeSOS()\n                {\n                    writeWord(0xFFDA); // marker\n                    writeWord(12); // length\n                    writeByte(3); // nrofcomponents\n                    writeByte(1); // IdY\n                    writeByte(0); // HTY\n                    writeByte(2); // IdU\n                    writeByte(0x11); // HTU\n                    writeByte(3); // IdV\n                    writeByte(0x11); // HTV\n                    writeByte(0); // Ss\n                    writeByte(0x3f); // Se\n                    writeByte(0); // Bf\n                }\n    \n                function processDU(CDU, fdtbl, DC, HTDC, HTAC){\n                    var EOB = HTAC[0x00];\n                    var M16zeroes = HTAC[0xF0];\n                    var pos;\n                    var I16 = 16;\n                    var I63 = 63;\n                    var I64 = 64;\n                    var DU_DCT = fDCTQuant(CDU, fdtbl);\n                    //ZigZag reorder\n                    for (var j=0;j<I64;++j) {\n                        DU[ZigZag[j]]=DU_DCT[j];\n                    }\n                    var Diff = DU[0] - DC; DC = DU[0];\n                    //Encode DC\n                    if (Diff==0) {\n                        writeBits(HTDC[0]); // Diff might be 0\n                    } else {\n                        pos = 32767+Diff;\n                        writeBits(HTDC[category[pos]]);\n                        writeBits(bitcode[pos]);\n                    }\n                    //Encode ACs\n                    var end0pos = 63; // was const... which is crazy\n                    for (; (end0pos>0)&&(DU[end0pos]==0); end0pos--) {};\n                    //end0pos = first element in reverse order !=0\n                    if ( end0pos == 0) {\n                        writeBits(EOB);\n                        return DC;\n                    }\n                    var i = 1;\n                    var lng;\n                    while ( i <= end0pos ) {\n                        var startpos = i;\n                        for (; (DU[i]==0) && (i<=end0pos); ++i) {}\n                        var nrzeroes = i-startpos;\n                        if ( nrzeroes >= I16 ) {\n                            lng = nrzeroes>>4;\n                            for (var nrmarker=1; nrmarker <= lng; ++nrmarker)\n                                writeBits(M16zeroes);\n                            nrzeroes = nrzeroes&0xF;\n                        }\n                        pos = 32767+DU[i];\n                        writeBits(HTAC[(nrzeroes<<4)+category[pos]]);\n                        writeBits(bitcode[pos]);\n                        i++;\n                    }\n                    if ( end0pos != I63 ) {\n                        writeBits(EOB);\n                    }\n                    return DC;\n                }\n    \n                function initCharLookupTable(){\n                    var sfcc = String.fromCharCode;\n                    for(var i=0; i < 256; i++){ ///// ACHTUNG // 255\n                        clt[i] = sfcc(i);\n                    }\n                }\n    \n                this.encode = function(image,quality) // image data object\n                {\n                    // var time_start = new Date().getTime();\n    \n                    if(quality) setQuality(quality);\n    \n                    // Initialize bit writer\n                    byteout = new Array();\n                    bytenew=0;\n                    bytepos=7;\n    \n                    // Add JPEG headers\n                    writeWord(0xFFD8); // SOI\n                    writeAPP0();\n                    writeDQT();\n                    writeSOF0(image.width,image.height);\n                    writeDHT();\n                    writeSOS();\n    \n    \n                    // Encode 8x8 macroblocks\n                    var DCY=0;\n                    var DCU=0;\n                    var DCV=0;\n    \n                    bytenew=0;\n                    bytepos=7;\n    \n    \n                    this.encode.displayName = \"_encode_\";\n    \n                    var imageData = image.data;\n                    var width = image.width;\n                    var height = image.height;\n    \n                    var quadWidth = width*4;\n                    var tripleWidth = width*3;\n    \n                    var x, y = 0;\n                    var r, g, b;\n                    var start,p, col,row,pos;\n                    while(y < height){\n                        x = 0;\n                        while(x < quadWidth){\n                        start = quadWidth * y + x;\n                        p = start;\n                        col = -1;\n                        row = 0;\n    \n                        for(pos=0; pos < 64; pos++){\n                            row = pos >> 3;// /8\n                            col = ( pos & 7 ) * 4; // %8\n                            p = start + ( row * quadWidth ) + col;\n    \n                            if(y+row >= height){ // padding bottom\n                                p-= (quadWidth*(y+1+row-height));\n                            }\n    \n                            if(x+col >= quadWidth){ // padding right\n                                p-= ((x+col) - quadWidth +4)\n                            }\n    \n                            r = imageData[ p++ ];\n                            g = imageData[ p++ ];\n                            b = imageData[ p++ ];\n    \n    \n                            /* // calculate YUV values dynamically\n                            YDU[pos]=((( 0.29900)*r+( 0.58700)*g+( 0.11400)*b))-128; //-0x80\n                            UDU[pos]=(((-0.16874)*r+(-0.33126)*g+( 0.50000)*b));\n                            VDU[pos]=((( 0.50000)*r+(-0.41869)*g+(-0.08131)*b));\n                            */\n    \n                            // use lookup table (slightly faster)\n                            YDU[pos] = ((RGB_YUV_TABLE[r]             + RGB_YUV_TABLE[(g +  256)>>0] + RGB_YUV_TABLE[(b +  512)>>0]) >> 16)-128;\n                            UDU[pos] = ((RGB_YUV_TABLE[(r +  768)>>0] + RGB_YUV_TABLE[(g + 1024)>>0] + RGB_YUV_TABLE[(b + 1280)>>0]) >> 16)-128;\n                            VDU[pos] = ((RGB_YUV_TABLE[(r + 1280)>>0] + RGB_YUV_TABLE[(g + 1536)>>0] + RGB_YUV_TABLE[(b + 1792)>>0]) >> 16)-128;\n    \n                        }\n    \n                        DCY = processDU(YDU, fdtbl_Y, DCY, YDC_HT, YAC_HT);\n                        DCU = processDU(UDU, fdtbl_UV, DCU, UVDC_HT, UVAC_HT);\n                        DCV = processDU(VDU, fdtbl_UV, DCV, UVDC_HT, UVAC_HT);\n                        x+=32;\n                        }\n                        y+=8;\n                    }\n    \n    \n                    ////////////////////////////////////////////////////////////////\n    \n                    // Do the bit alignment of the EOI marker\n                    if ( bytepos >= 0 ) {\n                        var fillbits = [];\n                        fillbits[1] = bytepos+1;\n                        fillbits[0] = (1<<(bytepos+1))-1;\n                        writeBits(fillbits);\n                    }\n    \n                    writeWord(0xFFD9); //EOI\n    \n                    var jpegDataUri = 'data:image/jpeg;base64,' + btoa(byteout.join(''));\n    \n                    byteout = [];\n    \n                    // benchmarking\n                    // var duration = new Date().getTime() - time_start;\n                    // console.log('Encoding time: '+ currentQuality + 'ms');\n                    //\n    \n                    return jpegDataUri\n            }\n    \n            function setQuality(quality){\n                if (quality <= 0) {\n                    quality = 1;\n                }\n                if (quality > 100) {\n                    quality = 100;\n                }\n    \n                if(currentQuality == quality) return // don't recalc if unchanged\n    \n                var sf = 0;\n                if (quality < 50) {\n                    sf = Math.floor(5000 / quality);\n                } else {\n                    sf = Math.floor(200 - quality*2);\n                }\n    \n                initQuantTables(sf);\n                currentQuality = quality;\n                // console.log('Quality set to: '+quality +'%');\n            }\n    \n            function init(){\n                // var time_start = new Date().getTime();\n                if(!quality) quality = 50;\n                // Create tables\n                initCharLookupTable()\n                initHuffmanTbl();\n                initCategoryNumber();\n                initRGBYUVTable();\n    \n                setQuality(quality);\n                // var duration = new Date().getTime() - time_start;\n                // console.log('Initialization '+ duration + 'ms');\n            }\n    \n            init();\n    \n        };\n    \n        JPEGEncoder.encode = function( data, quality ) {\n            var encoder = new JPEGEncoder( quality );\n    \n            return encoder.encode( data );\n        }\n    \n        return JPEGEncoder;\n    });\n    /**\n     * @fileOverview Fix android canvas.toDataUrl bug.\n     */\n    define('runtime/html5/androidpatch',[\n        'runtime/html5/util',\n        'runtime/html5/jpegencoder',\n        'base'\n    ], function( Util, encoder, Base ) {\n        var origin = Util.canvasToDataUrl,\n            supportJpeg;\n    \n        Util.canvasToDataUrl = function( canvas, type, quality ) {\n            var ctx, w, h, fragement, parts;\n    \n            // 非android手机直接跳过。\n            if ( !Base.os.android ) {\n                return origin.apply( null, arguments );\n            }\n    \n            // 检测是否canvas支持jpeg导出，根据数据格式来判断。\n            // JPEG 前两位分别是：255, 216\n            if ( type === 'image/jpeg' && typeof supportJpeg === 'undefined' ) {\n                fragement = origin.apply( null, arguments );\n    \n                parts = fragement.split(',');\n    \n                if ( ~parts[ 0 ].indexOf('base64') ) {\n                    fragement = atob( parts[ 1 ] );\n                } else {\n                    fragement = decodeURIComponent( parts[ 1 ] );\n                }\n    \n                fragement = fragement.substring( 0, 2 );\n    \n                supportJpeg = fragement.charCodeAt( 0 ) === 255 &&\n                        fragement.charCodeAt( 1 ) === 216;\n            }\n    \n            // 只有在android环境下才修复\n            if ( type === 'image/jpeg' && !supportJpeg ) {\n                w = canvas.width;\n                h = canvas.height;\n                ctx = canvas.getContext('2d');\n    \n                return encoder.encode( ctx.getImageData( 0, 0, w, h ), quality );\n            }\n    \n            return origin.apply( null, arguments );\n        };\n    });\n    /**\n     * @fileOverview Image\n     */\n    define('runtime/html5/image',[\n        'base',\n        'runtime/html5/runtime',\n        'runtime/html5/util'\n    ], function( Base, Html5Runtime, Util ) {\n    \n        var BLANK = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs%3D';\n    \n        return Html5Runtime.register( 'Image', {\n    \n            // flag: 标记是否被修改过。\n            modified: false,\n    \n            init: function() {\n                var me = this,\n                    img = new Image();\n    \n                img.onload = function() {\n    \n                    me._info = {\n                        type: me.type,\n                        width: this.width,\n                        height: this.height\n                    };\n    \n                    // 读取meta信息。\n                    if ( !me._metas && 'image/jpeg' === me.type ) {\n                        Util.parseMeta( me._blob, function( error, ret ) {\n                            me._metas = ret;\n                            me.owner.trigger('load');\n                        });\n                    } else {\n                        me.owner.trigger('load');\n                    }\n                };\n    \n                img.onerror = function() {\n                    me.owner.trigger('error');\n                };\n    \n                me._img = img;\n            },\n    \n            loadFromBlob: function( blob ) {\n                var me = this,\n                    img = me._img;\n    \n                me._blob = blob;\n                me.type = blob.type;\n                img.src = Util.createObjectURL( blob.getSource() );\n                me.owner.once( 'load', function() {\n                    Util.revokeObjectURL( img.src );\n                });\n            },\n    \n            resize: function( width, height ) {\n                var canvas = this._canvas ||\n                        (this._canvas = document.createElement('canvas'));\n    \n                this._resize( this._img, canvas, width, height );\n                this._blob = null;    // 没用了，可以删掉了。\n                this.modified = true;\n                this.owner.trigger('complete');\n            },\n    \n            getAsBlob: function( type ) {\n                var blob = this._blob,\n                    opts = this.options,\n                    canvas;\n    \n                type = type || this.type;\n    \n                // blob需要重新生成。\n                if ( this.modified || this.type !== type ) {\n                    canvas = this._canvas;\n    \n                    if ( type === 'image/jpeg' ) {\n    \n                        blob = Util.canvasToDataUrl( canvas, 'image/jpeg',\n                                opts.quality );\n    \n                        if ( opts.preserveHeaders && this._metas &&\n                                this._metas.imageHead ) {\n    \n                            blob = Util.dataURL2ArrayBuffer( blob );\n                            blob = Util.updateImageHead( blob,\n                                    this._metas.imageHead );\n                            blob = Util.arrayBufferToBlob( blob, type );\n                            return blob;\n                        }\n                    } else {\n                        blob = Util.canvasToDataUrl( canvas, type );\n                    }\n    \n                    blob = Util.dataURL2Blob( blob );\n                }\n    \n                return blob;\n            },\n    \n            getAsDataUrl: function( type ) {\n                var opts = this.options;\n    \n                type = type || this.type;\n    \n                if ( type === 'image/jpeg' ) {\n                    return Util.canvasToDataUrl( this._canvas, type, opts.quality );\n                } else {\n                    return this._canvas.toDataURL( type );\n                }\n            },\n    \n            getOrientation: function() {\n                return this._metas && this._metas.exif &&\n                        this._metas.exif.get('Orientation') || 1;\n            },\n    \n            info: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._info = val;\n                    return this;\n                }\n    \n                // getter\n                return this._info;\n            },\n    \n            meta: function( val ) {\n    \n                // setter\n                if ( val ) {\n                    this._meta = val;\n                    return this;\n                }\n    \n                // getter\n                return this._meta;\n            },\n    \n            destroy: function() {\n                var canvas = this._canvas;\n                this._img.onload = null;\n    \n                if ( canvas ) {\n                    canvas.getContext('2d')\n                            .clearRect( 0, 0, canvas.width, canvas.height );\n                    canvas.width = canvas.height = 0;\n                    this._canvas = null;\n                }\n    \n                // 释放内存。非常重要，否则释放不了image的内存。\n                this._img.src = BLANK;\n                this._img = this._blob = null;\n            },\n    \n            _resize: function( img, cvs, width, height ) {\n                var opts = this.options,\n                    naturalWidth = img.width,\n                    naturalHeight = img.height,\n                    orientation = this.getOrientation(),\n                    scale, w, h, x, y;\n    \n                // values that require 90 degree rotation\n                if ( ~[ 5, 6, 7, 8 ].indexOf( orientation ) ) {\n    \n                    // 交换width, height的值。\n                    width ^= height;\n                    height ^= width;\n                    width ^= height;\n                }\n    \n                scale = Math[ opts.crop ? 'max' : 'min' ]( width / naturalWidth,\n                        height / naturalHeight );\n    \n                // 不允许放大。\n                opts.allowMagnify || (scale = Math.min( 1, scale ));\n    \n                w = naturalWidth * scale;\n                h = naturalHeight * scale;\n    \n                if ( opts.crop ) {\n                    cvs.width = width;\n                    cvs.height = height;\n                } else {\n                    cvs.width = w;\n                    cvs.height = h;\n                }\n    \n                x = (cvs.width - w) / 2;\n                y = (cvs.height - h) / 2;\n    \n                opts.preserveHeaders || this._rotate2Orientaion( cvs, orientation );\n    \n                this._renderImageToCanvas( cvs, img, x, y, w, h );\n            },\n    \n            _rotate2Orientaion: function( canvas, orientation ) {\n                var width = canvas.width,\n                    height = canvas.height,\n                    ctx = canvas.getContext('2d');\n    \n                switch ( orientation ) {\n                    case 5:\n                    case 6:\n                    case 7:\n                    case 8:\n                        canvas.width = height;\n                        canvas.height = width;\n                        break;\n                }\n    \n                switch ( orientation ) {\n                    case 2:    // horizontal flip\n                        ctx.translate( width, 0 );\n                        ctx.scale( -1, 1 );\n                        break;\n    \n                    case 3:    // 180 rotate left\n                        ctx.translate( width, height );\n                        ctx.rotate( Math.PI );\n                        break;\n    \n                    case 4:    // vertical flip\n                        ctx.translate( 0, height );\n                        ctx.scale( 1, -1 );\n                        break;\n    \n                    case 5:    // vertical flip + 90 rotate right\n                        ctx.rotate( 0.5 * Math.PI );\n                        ctx.scale( 1, -1 );\n                        break;\n    \n                    case 6:    // 90 rotate right\n                        ctx.rotate( 0.5 * Math.PI );\n                        ctx.translate( 0, -height );\n                        break;\n    \n                    case 7:    // horizontal flip + 90 rotate right\n                        ctx.rotate( 0.5 * Math.PI );\n                        ctx.translate( width, -height );\n                        ctx.scale( -1, 1 );\n                        break;\n    \n                    case 8:    // 90 rotate left\n                        ctx.rotate( -0.5 * Math.PI );\n                        ctx.translate( -width, 0 );\n                        break;\n                }\n            },\n    \n            // https://github.com/stomita/ios-imagefile-megapixel/\n            // blob/master/src/megapix-image.js\n            _renderImageToCanvas: (function() {\n    \n                // 如果不是ios, 不需要这么复杂！\n                if ( !Base.os.ios ) {\n                    return function( canvas, img, x, y, w, h ) {\n                        canvas.getContext('2d').drawImage( img, x, y, w, h );\n                    };\n                }\n    \n                /**\n                 * Detecting vertical squash in loaded image.\n                 * Fixes a bug which squash image vertically while drawing into\n                 * canvas for some images.\n                 */\n                function detectVerticalSquash( img, iw, ih ) {\n                    var canvas = document.createElement('canvas'),\n                        ctx = canvas.getContext('2d'),\n                        sy = 0,\n                        ey = ih,\n                        py = ih,\n                        data, alpha, ratio;\n    \n    \n                    canvas.width = 1;\n                    canvas.height = ih;\n                    ctx.drawImage( img, 0, 0 );\n                    data = ctx.getImageData( 0, 0, 1, ih ).data;\n    \n                    // search image edge pixel position in case\n                    // it is squashed vertically.\n                    while ( py > sy ) {\n                        alpha = data[ (py - 1) * 4 + 3 ];\n    \n                        if ( alpha === 0 ) {\n                            ey = py;\n                        } else {\n                            sy = py;\n                        }\n    \n                        py = (ey + sy) >> 1;\n                    }\n    \n                    ratio = (py / ih);\n                    return (ratio === 0) ? 1 : ratio;\n                }\n    \n                // fix ie7 bug\n                // http://stackoverflow.com/questions/11929099/\n                // html5-canvas-drawimage-ratio-bug-ios\n                if ( Base.os.ios >= 7 ) {\n                    return function( canvas, img, x, y, w, h ) {\n                        var iw = img.naturalWidth,\n                            ih = img.naturalHeight,\n                            vertSquashRatio = detectVerticalSquash( img, iw, ih );\n    \n                        return canvas.getContext('2d').drawImage( img, 0, 0,\n                            iw * vertSquashRatio, ih * vertSquashRatio,\n                            x, y, w, h );\n                    };\n                }\n    \n                /**\n                 * Detect subsampling in loaded image.\n                 * In iOS, larger images than 2M pixels may be\n                 * subsampled in rendering.\n                 */\n                function detectSubsampling( img ) {\n                    var iw = img.naturalWidth,\n                        ih = img.naturalHeight,\n                        canvas, ctx;\n    \n                    // subsampling may happen overmegapixel image\n                    if ( iw * ih > 1024 * 1024 ) {\n                        canvas = document.createElement('canvas');\n                        canvas.width = canvas.height = 1;\n                        ctx = canvas.getContext('2d');\n                        ctx.drawImage( img, -iw + 1, 0 );\n    \n                        // subsampled image becomes half smaller in rendering size.\n                        // check alpha channel value to confirm image is covering\n                        // edge pixel or not. if alpha value is 0\n                        // image is not covering, hence subsampled.\n                        return ctx.getImageData( 0, 0, 1, 1 ).data[ 3 ] === 0;\n                    } else {\n                        return false;\n                    }\n                }\n    \n    \n                return function( canvas, img, x, y, width, height ) {\n                    var iw = img.naturalWidth,\n                        ih = img.naturalHeight,\n                        ctx = canvas.getContext('2d'),\n                        subsampled = detectSubsampling( img ),\n                        doSquash = this.type === 'image/jpeg',\n                        d = 1024,\n                        sy = 0,\n                        dy = 0,\n                        tmpCanvas, tmpCtx, vertSquashRatio, dw, dh, sx, dx;\n    \n                    if ( subsampled ) {\n                        iw /= 2;\n                        ih /= 2;\n                    }\n    \n                    ctx.save();\n                    tmpCanvas = document.createElement('canvas');\n                    tmpCanvas.width = tmpCanvas.height = d;\n    \n                    tmpCtx = tmpCanvas.getContext('2d');\n                    vertSquashRatio = doSquash ?\n                            detectVerticalSquash( img, iw, ih ) : 1;\n    \n                    dw = Math.ceil( d * width / iw );\n                    dh = Math.ceil( d * height / ih / vertSquashRatio );\n    \n                    while ( sy < ih ) {\n                        sx = 0;\n                        dx = 0;\n                        while ( sx < iw ) {\n                            tmpCtx.clearRect( 0, 0, d, d );\n                            tmpCtx.drawImage( img, -sx, -sy );\n                            ctx.drawImage( tmpCanvas, 0, 0, d, d,\n                                    x + dx, y + dy, dw, dh );\n                            sx += d;\n                            dx += dw;\n                        }\n                        sy += d;\n                        dy += dh;\n                    }\n                    ctx.restore();\n                    tmpCanvas = tmpCtx = null;\n                };\n            })()\n        });\n    });\n    /**\n     * @fileOverview Transport\n     * @todo 支持chunked传输，优势：\n     * 可以将大文件分成小块，挨个传输，可以提高大文件成功率，当失败的时候，也只需要重传那小部分，\n     * 而不需要重头再传一次。另外断点续传也需要用chunked方式。\n     */\n    define('runtime/html5/transport',[\n        'base',\n        'runtime/html5/runtime'\n    ], function( Base, Html5Runtime ) {\n    \n        var noop = Base.noop,\n            $ = Base.$;\n    \n        return Html5Runtime.register( 'Transport', {\n            init: function() {\n                this._status = 0;\n                this._response = null;\n            },\n    \n            send: function() {\n                var owner = this.owner,\n                    opts = this.options,\n                    xhr = this._initAjax(),\n                    blob = owner._blob,\n                    server = opts.server,\n                    formData, binary, fr;\n    \n                if ( opts.sendAsBinary ) {\n                    server += (/\\?/.test( server ) ? '&' : '?') +\n                            $.param( owner._formData );\n    \n                    binary = blob.getSource();\n                } else {\n                    formData = new FormData();\n                    $.each( owner._formData, function( k, v ) {\n                        formData.append( k, v );\n                    });\n    \n                    formData.append( opts.fileVal, blob.getSource(),\n                            opts.filename || owner._formData.name || '' );\n                }\n    \n                if ( opts.withCredentials && 'withCredentials' in xhr ) {\n                    xhr.open( opts.method, server, true );\n                    xhr.withCredentials = true;\n                } else {\n                    xhr.open( opts.method, server );\n                }\n    \n                this._setRequestHeader( xhr, opts.headers );\n    \n                if ( binary ) {\n                    xhr.overrideMimeType('application/octet-stream');\n    \n                    // android直接发送blob会导致服务端接收到的是空文件。\n                    // bug详情。\n                    // https://code.google.com/p/android/issues/detail?id=39882\n                    // 所以先用fileReader读取出来再通过arraybuffer的方式发送。\n                    if ( Base.os.android ) {\n                        fr = new FileReader();\n    \n                        fr.onload = function() {\n                            xhr.send( this.result );\n                            fr = fr.onload = null;\n                        };\n    \n                        fr.readAsArrayBuffer( binary );\n                    } else {\n                        xhr.send( binary );\n                    }\n                } else {\n                    xhr.send( formData );\n                }\n            },\n    \n            getResponse: function() {\n                return this._response;\n            },\n    \n            getResponseAsJson: function() {\n                return this._parseJson( this._response );\n            },\n    \n            getStatus: function() {\n                return this._status;\n            },\n    \n            abort: function() {\n                var xhr = this._xhr;\n    \n                if ( xhr ) {\n                    xhr.upload.onprogress = noop;\n                    xhr.onreadystatechange = noop;\n                    xhr.abort();\n    \n                    this._xhr = xhr = null;\n                }\n            },\n    \n            destroy: function() {\n                this.abort();\n            },\n    \n            _initAjax: function() {\n                var me = this,\n                    xhr = new XMLHttpRequest(),\n                    opts = this.options;\n    \n                if ( opts.withCredentials && !('withCredentials' in xhr) &&\n                        typeof XDomainRequest !== 'undefined' ) {\n                    xhr = new XDomainRequest();\n                }\n    \n                xhr.upload.onprogress = function( e ) {\n                    var percentage = 0;\n    \n                    if ( e.lengthComputable ) {\n                        percentage = e.loaded / e.total;\n                    }\n    \n                    return me.trigger( 'progress', percentage );\n                };\n    \n                xhr.onreadystatechange = function() {\n    \n                    if ( xhr.readyState !== 4 ) {\n                        return;\n                    }\n    \n                    xhr.upload.onprogress = noop;\n                    xhr.onreadystatechange = noop;\n                    me._xhr = null;\n                    me._status = xhr.status;\n    \n                    if ( xhr.status >= 200 && xhr.status < 300 ) {\n                        me._response = xhr.responseText;\n                        return me.trigger('load');\n                    } else if ( xhr.status >= 500 && xhr.status < 600 ) {\n                        me._response = xhr.responseText;\n                        return me.trigger( 'error', 'server' );\n                    }\n    \n    \n                    return me.trigger( 'error', me._status ? 'http' : 'abort' );\n                };\n    \n                me._xhr = xhr;\n                return xhr;\n            },\n    \n            _setRequestHeader: function( xhr, headers ) {\n                $.each( headers, function( key, val ) {\n                    xhr.setRequestHeader( key, val );\n                });\n            },\n    \n            _parseJson: function( str ) {\n                var json;\n    \n                try {\n                    json = JSON.parse( str );\n                } catch ( ex ) {\n                    json = {};\n                }\n    \n                return json;\n            }\n        });\n    });\n    /**\n     * @fileOverview FlashRuntime\n     */\n    define('runtime/flash/runtime',[\n        'base',\n        'runtime/runtime',\n        'runtime/compbase'\n    ], function( Base, Runtime, CompBase ) {\n    \n        var $ = Base.$,\n            type = 'flash',\n            components = {};\n    \n    \n        function getFlashVersion() {\n            var version;\n    \n            try {\n                version = navigator.plugins[ 'Shockwave Flash' ];\n                version = version.description;\n            } catch ( ex ) {\n                try {\n                    version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash')\n                            .GetVariable('$version');\n                } catch ( ex2 ) {\n                    version = '0.0';\n                }\n            }\n            version = version.match( /\\d+/g );\n            return parseFloat( version[ 0 ] + '.' + version[ 1 ], 10 );\n        }\n    \n        function FlashRuntime() {\n            var pool = {},\n                clients = {},\n                destory = this.destory,\n                me = this,\n                jsreciver = Base.guid('webuploader_');\n    \n            Runtime.apply( me, arguments );\n            me.type = type;\n    \n    \n            // 这个方法的调用者，实际上是RuntimeClient\n            me.exec = function( comp, fn/*, args...*/ ) {\n                var client = this,\n                    uid = client.uid,\n                    args = Base.slice( arguments, 2 ),\n                    instance;\n    \n                clients[ uid ] = client;\n    \n                if ( components[ comp ] ) {\n                    if ( !pool[ uid ] ) {\n                        pool[ uid ] = new components[ comp ]( client, me );\n                    }\n    \n                    instance = pool[ uid ];\n    \n                    if ( instance[ fn ] ) {\n                        return instance[ fn ].apply( instance, args );\n                    }\n                }\n    \n                return me.flashExec.apply( client, arguments );\n            };\n    \n            function handler( evt, obj ) {\n                var type = evt.type || evt,\n                    parts, uid;\n    \n                parts = type.split('::');\n                uid = parts[ 0 ];\n                type = parts[ 1 ];\n    \n                // console.log.apply( console, arguments );\n    \n                if ( type === 'Ready' && uid === me.uid ) {\n                    me.trigger('ready');\n                } else if ( clients[ uid ] ) {\n                    clients[ uid ].trigger( type.toLowerCase(), evt, obj );\n                }\n    \n                // Base.log( evt, obj );\n            }\n    \n            // flash的接受器。\n            window[ jsreciver ] = function() {\n                var args = arguments;\n    \n                // 为了能捕获得到。\n                setTimeout(function() {\n                    handler.apply( null, args );\n                }, 1 );\n            };\n    \n            this.jsreciver = jsreciver;\n    \n            this.destory = function() {\n                // @todo 删除池子中的所有实例\n                return destory && destory.apply( this, arguments );\n            };\n    \n            this.flashExec = function( comp, fn ) {\n                var flash = me.getFlash(),\n                    args = Base.slice( arguments, 2 );\n    \n                return flash.exec( this.uid, comp, fn, args );\n            };\n    \n            // @todo\n        }\n    \n        Base.inherits( Runtime, {\n            constructor: FlashRuntime,\n    \n            init: function() {\n                var container = this.getContainer(),\n                    opts = this.options,\n                    html;\n    \n                // if not the minimal height, shims are not initialized\n                // in older browsers (e.g FF3.6, IE6,7,8, Safari 4.0,5.0, etc)\n                container.css({\n                    position: 'absolute',\n                    top: '-8px',\n                    left: '-8px',\n                    width: '9px',\n                    height: '9px',\n                    overflow: 'hidden'\n                });\n    \n                // insert flash object\n                html = '<object id=\"' + this.uid + '\" type=\"application/' +\n                        'x-shockwave-flash\" data=\"' +  opts.swf + '\" ';\n    \n                if ( Base.browser.ie ) {\n                    html += 'classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" ';\n                }\n    \n                html += 'width=\"100%\" height=\"100%\" style=\"outline:0\">'  +\n                    '<param name=\"movie\" value=\"' + opts.swf + '\" />' +\n                    '<param name=\"flashvars\" value=\"uid=' + this.uid +\n                    '&jsreciver=' + this.jsreciver + '\" />' +\n                    '<param name=\"wmode\" value=\"transparent\" />' +\n                    '<param name=\"allowscriptaccess\" value=\"always\" />' +\n                '</object>';\n    \n                container.html( html );\n            },\n    \n            getFlash: function() {\n                if ( this._flash ) {\n                    return this._flash;\n                }\n    \n                this._flash = $( '#' + this.uid ).get( 0 );\n                return this._flash;\n            }\n    \n        });\n    \n        FlashRuntime.register = function( name, component ) {\n            component = components[ name ] = Base.inherits( CompBase, $.extend({\n    \n                // @todo fix this later\n                flashExec: function() {\n                    var owner = this.owner,\n                        runtime = this.getRuntime();\n    \n                    return runtime.flashExec.apply( owner, arguments );\n                }\n            }, component ) );\n    \n            return component;\n        };\n    \n        if ( getFlashVersion() >= 11.4 ) {\n            Runtime.addRuntime( type, FlashRuntime );\n        }\n    \n        return FlashRuntime;\n    });\n    /**\n     * @fileOverview FilePicker\n     */\n    define('runtime/flash/filepicker',[\n        'base',\n        'runtime/flash/runtime'\n    ], function( Base, FlashRuntime ) {\n        var $ = Base.$;\n    \n        return FlashRuntime.register( 'FilePicker', {\n            init: function( opts ) {\n                var copy = $.extend({}, opts ),\n                    len, i;\n    \n                // 修复Flash再没有设置title的情况下无法弹出flash文件选择框的bug.\n                len = copy.accept && copy.accept.length;\n                for (  i = 0; i < len; i++ ) {\n                    if ( !copy.accept[ i ].title ) {\n                        copy.accept[ i ].title = 'Files';\n                    }\n                }\n    \n                delete copy.button;\n                delete copy.container;\n    \n                this.flashExec( 'FilePicker', 'init', copy );\n            },\n    \n            destroy: function() {\n                // todo\n            }\n        });\n    });\n    /**\n     * @fileOverview 图片压缩\n     */\n    define('runtime/flash/image',[\n        'runtime/flash/runtime'\n    ], function( FlashRuntime ) {\n    \n        return FlashRuntime.register( 'Image', {\n            // init: function( options ) {\n            //     var owner = this.owner;\n    \n            //     this.flashExec( 'Image', 'init', options );\n            //     owner.on( 'load', function() {\n            //         debugger;\n            //     });\n            // },\n    \n            loadFromBlob: function( blob ) {\n                var owner = this.owner;\n    \n                owner.info() && this.flashExec( 'Image', 'info', owner.info() );\n                owner.meta() && this.flashExec( 'Image', 'meta', owner.meta() );\n    \n                this.flashExec( 'Image', 'loadFromBlob', blob.uid );\n            }\n        });\n    });\n    /**\n     * @fileOverview  Transport flash实现\n     */\n    define('runtime/flash/transport',[\n        'base',\n        'runtime/flash/runtime',\n        'runtime/client'\n    ], function( Base, FlashRuntime, RuntimeClient ) {\n        var $ = Base.$;\n    \n        return FlashRuntime.register( 'Transport', {\n            init: function() {\n                this._status = 0;\n                this._response = null;\n                this._responseJson = null;\n            },\n    \n            send: function() {\n                var owner = this.owner,\n                    opts = this.options,\n                    xhr = this._initAjax(),\n                    blob = owner._blob,\n                    server = opts.server,\n                    binary;\n    \n                xhr.connectRuntime( blob.ruid );\n    \n                if ( opts.sendAsBinary ) {\n                    server += (/\\?/.test( server ) ? '&' : '?') +\n                            $.param( owner._formData );\n    \n                    binary = blob.uid;\n                } else {\n                    $.each( owner._formData, function( k, v ) {\n                        xhr.exec( 'append', k, v );\n                    });\n    \n                    xhr.exec( 'appendBlob', opts.fileVal, blob.uid,\n                            opts.filename || owner._formData.name || '' );\n                }\n    \n                this._setRequestHeader( xhr, opts.headers );\n                xhr.exec( 'send', {\n                    method: opts.method,\n                    url: server\n                }, binary );\n            },\n    \n            getStatus: function() {\n                return this._status;\n            },\n    \n            getResponse: function() {\n                return this._response;\n            },\n    \n            getResponseAsJson: function() {\n                return this._responseJson;\n            },\n    \n            abort: function() {\n                var xhr = this._xhr;\n    \n                if ( xhr ) {\n                    xhr.exec('abort');\n                    xhr.destroy();\n                    this._xhr = xhr = null;\n                }\n            },\n    \n            destroy: function() {\n                this.abort();\n            },\n    \n            _initAjax: function() {\n                var me = this,\n                    xhr = new RuntimeClient('XMLHttpRequest');\n    \n                xhr.on( 'uploadprogress progress', function( e ) {\n                    return me.trigger( 'progress', e.loaded / e.total );\n                });\n    \n                xhr.on( 'load', function() {\n                    var status = xhr.exec('getStatus'),\n                        err = '';\n    \n                    xhr.off();\n                    me._xhr = null;\n    \n                    if ( status >= 200 && status < 300 ) {\n                        me._response = xhr.exec('getResponse');\n                        me._responseJson = xhr.exec('getResponseAsJson');\n                    } else if ( status >= 500 && status < 600 ) {\n                        me._response = xhr.exec('getResponse');\n                        me._responseJson = xhr.exec('getResponseAsJson');\n                        err = 'server';\n                    } else {\n                        err = 'http';\n                    }\n    \n                    xhr.destroy();\n                    xhr = null;\n    \n                    return err ? me.trigger( 'error', err ) : me.trigger('load');\n                });\n    \n                xhr.on( 'error', function() {\n                    xhr.off();\n                    me._xhr = null;\n                    me.trigger( 'error', 'http' );\n                });\n    \n                me._xhr = xhr;\n                return xhr;\n            },\n    \n            _setRequestHeader: function( xhr, headers ) {\n                $.each( headers, function( key, val ) {\n                    xhr.exec( 'setRequestHeader', key, val );\n                });\n            }\n        });\n    });\n    /**\n     * @fileOverview 完全版本。\n     */\n    define('preset/all',[\n        'base',\n    \n        // widgets\n        'widgets/filednd',\n        'widgets/filepaste',\n        'widgets/filepicker',\n        'widgets/image',\n        'widgets/queue',\n        'widgets/runtime',\n        'widgets/upload',\n        'widgets/validator',\n    \n        // runtimes\n        // html5\n        'runtime/html5/blob',\n        'runtime/html5/dnd',\n        'runtime/html5/filepaste',\n        'runtime/html5/filepicker',\n        'runtime/html5/imagemeta/exif',\n        'runtime/html5/androidpatch',\n        'runtime/html5/image',\n        'runtime/html5/transport',\n    \n        // flash\n        'runtime/flash/filepicker',\n        'runtime/flash/image',\n        'runtime/flash/transport'\n    ], function( Base ) {\n        return Base;\n    });\n    define('webuploader',[\n        'preset/all'\n    ], function( preset ) {\n        return preset;\n    });\n    return require('webuploader');\n});\n"
  },
  {
    "path": "public/static/ueditor/third-party/webuploader/webuploader.withoutimage.js",
    "content": "/*! WebUploader 0.1.2 */\n\n\n/**\n * @fileOverview 让内部各个部件的代码可以用[amd](https://github.com/amdjs/amdjs-api/wiki/AMD)模块定义方式组织起来。\n *\n * AMD API 内部的简单不完全实现，请忽略。只有当WebUploader被合并成一个文件的时候才会引入。\n */\n(function( root, factory ) {\n    var modules = {},\n\n        // 内部require, 简单不完全实现。\n        // https://github.com/amdjs/amdjs-api/wiki/require\n        _require = function( deps, callback ) {\n            var args, len, i;\n\n            // 如果deps不是数组，则直接返回指定module\n            if ( typeof deps === 'string' ) {\n                return getModule( deps );\n            } else {\n                args = [];\n                for( len = deps.length, i = 0; i < len; i++ ) {\n                    args.push( getModule( deps[ i ] ) );\n                }\n\n                return callback.apply( null, args );\n            }\n        },\n\n        // 内部define，暂时不支持不指定id.\n        _define = function( id, deps, factory ) {\n            if ( arguments.length === 2 ) {\n                factory = deps;\n                deps = null;\n            }\n\n            _require( deps || [], function() {\n                setModule( id, factory, arguments );\n            });\n        },\n\n        // 设置module, 兼容CommonJs写法。\n        setModule = function( id, factory, args ) {\n            var module = {\n                    exports: factory\n                },\n                returned;\n\n            if ( typeof factory === 'function' ) {\n                args.length || (args = [ _require, module.exports, module ]);\n                returned = factory.apply( null, args );\n                returned !== undefined && (module.exports = returned);\n            }\n\n            modules[ id ] = module.exports;\n        },\n\n        // 根据id获取module\n        getModule = function( id ) {\n            var module = modules[ id ] || root[ id ];\n\n            if ( !module ) {\n                throw new Error( '`' + id + '` is undefined' );\n            }\n\n            return module;\n        },\n\n        // 将所有modules，将路径ids装换成对象。\n        exportsTo = function( obj ) {\n            var key, host, parts, part, last, ucFirst;\n\n            // make the first character upper case.\n            ucFirst = function( str ) {\n                return str && (str.charAt( 0 ).toUpperCase() + str.substr( 1 ));\n            };\n\n            for ( key in modules ) {\n                host = obj;\n\n                if ( !modules.hasOwnProperty( key ) ) {\n                    continue;\n                }\n\n                parts = key.split('/');\n                last = ucFirst( parts.pop() );\n\n                while( (part = ucFirst( parts.shift() )) ) {\n                    host[ part ] = host[ part ] || {};\n                    host = host[ part ];\n                }\n\n                host[ last ] = modules[ key ];\n            }\n        },\n\n        exports = factory( root, _define, _require ),\n        origin;\n\n    // exports every module.\n    exportsTo( exports );\n\n    if ( typeof module === 'object' && typeof module.exports === 'object' ) {\n\n        // For CommonJS and CommonJS-like environments where a proper window is present,\n        module.exports = exports;\n    } else if ( typeof define === 'function' && define.amd ) {\n\n        // Allow using this built library as an AMD module\n        // in another project. That other project will only\n        // see this AMD call, not the internal modules in\n        // the closure below.\n        define([], exports );\n    } else {\n\n        // Browser globals case. Just assign the\n        // result to a property on the global.\n        origin = root.WebUploader;\n        root.WebUploader = exports;\n        root.WebUploader.noConflict = function() {\n            root.WebUploader = origin;\n        };\n    }\n})( this, function( window, define, require ) {\n\n\n    /**\n     * @fileOverview jQuery or Zepto\n     */\n    define('dollar-third',[],function() {\n        return window.jQuery || window.Zepto;\n    });\n    /**\n     * @fileOverview Dom 操作相关\n     */\n    define('dollar',[\n        'dollar-third'\n    ], function( _ ) {\n        return _;\n    });\n    /**\n     * @fileOverview 使用jQuery的Promise\n     */\n    define('promise-third',[\n        'dollar'\n    ], function( $ ) {\n        return {\n            Deferred: $.Deferred,\n            when: $.when,\n    \n            isPromise: function( anything ) {\n                return anything && typeof anything.then === 'function';\n            }\n        };\n    });\n    /**\n     * @fileOverview Promise/A+\n     */\n    define('promise',[\n        'promise-third'\n    ], function( _ ) {\n        return _;\n    });\n    /**\n     * @fileOverview 基础类方法。\n     */\n    \n    /**\n     * Web Uploader内部类的详细说明，以下提及的功能类，都可以在`WebUploader`这个变量中访问到。\n     *\n     * As you know, Web Uploader的每个文件都是用过[AMD](https://github.com/amdjs/amdjs-api/wiki/AMD)规范中的`define`组织起来的, 每个Module都会有个module id.\n     * 默认module id该文件的路径，而此路径将会转化成名字空间存放在WebUploader中。如：\n     *\n     * * module `base`：WebUploader.Base\n     * * module `file`: WebUploader.File\n     * * module `lib/dnd`: WebUploader.Lib.Dnd\n     * * module `runtime/html5/dnd`: WebUploader.Runtime.Html5.Dnd\n     *\n     *\n     * 以下文档将可能省略`WebUploader`前缀。\n     * @module WebUploader\n     * @title WebUploader API文档\n     */\n    define('base',[\n        'dollar',\n        'promise'\n    ], function( $, promise ) {\n    \n        var noop = function() {},\n            call = Function.call;\n    \n        // http://jsperf.com/uncurrythis\n        // 反科里化\n        function uncurryThis( fn ) {\n            return function() {\n                return call.apply( fn, arguments );\n            };\n        }\n    \n        function bindFn( fn, context ) {\n            return function() {\n                return fn.apply( context, arguments );\n            };\n        }\n    \n        function createObject( proto ) {\n            var f;\n    \n            if ( Object.create ) {\n                return Object.create( proto );\n            } else {\n                f = function() {};\n                f.prototype = proto;\n                return new f();\n            }\n        }\n    \n    \n        /**\n         * 基础类，提供一些简单常用的方法。\n         * @class Base\n         */\n        return {\n    \n            /**\n             * @property {String} version 当前版本号。\n             */\n            version: '0.1.2',\n    \n            /**\n             * @property {jQuery|Zepto} $ 引用依赖的jQuery或者Zepto对象。\n             */\n            $: $,\n    \n            Deferred: promise.Deferred,\n    \n            isPromise: promise.isPromise,\n    \n            when: promise.when,\n    \n            /**\n             * @description  简单的浏览器检查结果。\n             *\n             * * `webkit`  webkit版本号，如果浏览器为非webkit内核，此属性为`undefined`。\n             * * `chrome`  chrome浏览器版本号，如果浏览器为chrome，此属性为`undefined`。\n             * * `ie`  ie浏览器版本号，如果浏览器为非ie，此属性为`undefined`。**暂不支持ie10+**\n             * * `firefox`  firefox浏览器版本号，如果浏览器为非firefox，此属性为`undefined`。\n             * * `safari`  safari浏览器版本号，如果浏览器为非safari，此属性为`undefined`。\n             * * `opera`  opera浏览器版本号，如果浏览器为非opera，此属性为`undefined`。\n             *\n             * @property {Object} [browser]\n             */\n            browser: (function( ua ) {\n                var ret = {},\n                    webkit = ua.match( /WebKit\\/([\\d.]+)/ ),\n                    chrome = ua.match( /Chrome\\/([\\d.]+)/ ) ||\n                        ua.match( /CriOS\\/([\\d.]+)/ ),\n    \n                    ie = ua.match( /MSIE\\s([\\d\\.]+)/ ) ||\n                        ua.match(/(?:trident)(?:.*rv:([\\w.]+))?/i),\n                    firefox = ua.match( /Firefox\\/([\\d.]+)/ ),\n                    safari = ua.match( /Safari\\/([\\d.]+)/ ),\n                    opera = ua.match( /OPR\\/([\\d.]+)/ );\n    \n                webkit && (ret.webkit = parseFloat( webkit[ 1 ] ));\n                chrome && (ret.chrome = parseFloat( chrome[ 1 ] ));\n                ie && (ret.ie = parseFloat( ie[ 1 ] ));\n                firefox && (ret.firefox = parseFloat( firefox[ 1 ] ));\n                safari && (ret.safari = parseFloat( safari[ 1 ] ));\n                opera && (ret.opera = parseFloat( opera[ 1 ] ));\n    \n                return ret;\n            })( navigator.userAgent ),\n    \n            /**\n             * @description  操作系统检查结果。\n             *\n             * * `android`  如果在android浏览器环境下，此值为对应的android版本号，否则为`undefined`。\n             * * `ios` 如果在ios浏览器环境下，此值为对应的ios版本号，否则为`undefined`。\n             * @property {Object} [os]\n             */\n            os: (function( ua ) {\n                var ret = {},\n    \n                    // osx = !!ua.match( /\\(Macintosh\\; Intel / ),\n                    android = ua.match( /(?:Android);?[\\s\\/]+([\\d.]+)?/ ),\n                    ios = ua.match( /(?:iPad|iPod|iPhone).*OS\\s([\\d_]+)/ );\n    \n                // osx && (ret.osx = true);\n                android && (ret.android = parseFloat( android[ 1 ] ));\n                ios && (ret.ios = parseFloat( ios[ 1 ].replace( /_/g, '.' ) ));\n    \n                return ret;\n            })( navigator.userAgent ),\n    \n            /**\n             * 实现类与类之间的继承。\n             * @method inherits\n             * @grammar Base.inherits( super ) => child\n             * @grammar Base.inherits( super, protos ) => child\n             * @grammar Base.inherits( super, protos, statics ) => child\n             * @param  {Class} super 父类\n             * @param  {Object | Function} [protos] 子类或者对象。如果对象中包含constructor，子类将是用此属性值。\n             * @param  {Function} [protos.constructor] 子类构造器，不指定的话将创建个临时的直接执行父类构造器的方法。\n             * @param  {Object} [statics] 静态属性或方法。\n             * @return {Class} 返回子类。\n             * @example\n             * function Person() {\n             *     console.log( 'Super' );\n             * }\n             * Person.prototype.hello = function() {\n             *     console.log( 'hello' );\n             * };\n             *\n             * var Manager = Base.inherits( Person, {\n             *     world: function() {\n             *         console.log( 'World' );\n             *     }\n             * });\n             *\n             * // 因为没有指定构造器，父类的构造器将会执行。\n             * var instance = new Manager();    // => Super\n             *\n             * // 继承子父类的方法\n             * instance.hello();    // => hello\n             * instance.world();    // => World\n             *\n             * // 子类的__super__属性指向父类\n             * console.log( Manager.__super__ === Person );    // => true\n             */\n            inherits: function( Super, protos, staticProtos ) {\n                var child;\n    \n                if ( typeof protos === 'function' ) {\n                    child = protos;\n                    protos = null;\n                } else if ( protos && protos.hasOwnProperty('constructor') ) {\n                    child = protos.constructor;\n                } else {\n                    child = function() {\n                        return Super.apply( this, arguments );\n                    };\n                }\n    \n                // 复制静态方法\n                $.extend( true, child, Super, staticProtos || {} );\n    \n                /* jshint camelcase: false */\n    \n                // 让子类的__super__属性指向父类。\n                child.__super__ = Super.prototype;\n    \n                // 构建原型，添加原型方法或属性。\n                // 暂时用Object.create实现。\n                child.prototype = createObject( Super.prototype );\n                protos && $.extend( true, child.prototype, protos );\n    \n                return child;\n            },\n    \n            /**\n             * 一个不做任何事情的方法。可以用来赋值给默认的callback.\n             * @method noop\n             */\n            noop: noop,\n    \n            /**\n             * 返回一个新的方法，此方法将已指定的`context`来执行。\n             * @grammar Base.bindFn( fn, context ) => Function\n             * @method bindFn\n             * @example\n             * var doSomething = function() {\n             *         console.log( this.name );\n             *     },\n             *     obj = {\n             *         name: 'Object Name'\n             *     },\n             *     aliasFn = Base.bind( doSomething, obj );\n             *\n             *  aliasFn();    // => Object Name\n             *\n             */\n            bindFn: bindFn,\n    \n            /**\n             * 引用Console.log如果存在的话，否则引用一个[空函数loop](#WebUploader:Base.log)。\n             * @grammar Base.log( args... ) => undefined\n             * @method log\n             */\n            log: (function() {\n                if ( window.console ) {\n                    return bindFn( console.log, console );\n                }\n                return noop;\n            })(),\n    \n            nextTick: (function() {\n    \n                return function( cb ) {\n                    setTimeout( cb, 1 );\n                };\n    \n                // @bug 当浏览器不在当前窗口时就停了。\n                // var next = window.requestAnimationFrame ||\n                //     window.webkitRequestAnimationFrame ||\n                //     window.mozRequestAnimationFrame ||\n                //     function( cb ) {\n                //         window.setTimeout( cb, 1000 / 60 );\n                //     };\n    \n                // // fix: Uncaught TypeError: Illegal invocation\n                // return bindFn( next, window );\n            })(),\n    \n            /**\n             * 被[uncurrythis](http://www.2ality.com/2011/11/uncurrying-this.html)的数组slice方法。\n             * 将用来将非数组对象转化成数组对象。\n             * @grammar Base.slice( target, start[, end] ) => Array\n             * @method slice\n             * @example\n             * function doSomthing() {\n             *     var args = Base.slice( arguments, 1 );\n             *     console.log( args );\n             * }\n             *\n             * doSomthing( 'ignored', 'arg2', 'arg3' );    // => Array [\"arg2\", \"arg3\"]\n             */\n            slice: uncurryThis( [].slice ),\n    \n            /**\n             * 生成唯一的ID\n             * @method guid\n             * @grammar Base.guid() => String\n             * @grammar Base.guid( prefx ) => String\n             */\n            guid: (function() {\n                var counter = 0;\n    \n                return function( prefix ) {\n                    var guid = (+new Date()).toString( 32 ),\n                        i = 0;\n    \n                    for ( ; i < 5; i++ ) {\n                        guid += Math.floor( Math.random() * 65535 ).toString( 32 );\n                    }\n    \n                    return (prefix || 'wu_') + guid + (counter++).toString( 32 );\n                };\n            })(),\n    \n            /**\n             * 格式化文件大小, 输出成带单位的字符串\n             * @method formatSize\n             * @grammar Base.formatSize( size ) => String\n             * @grammar Base.formatSize( size, pointLength ) => String\n             * @grammar Base.formatSize( size, pointLength, units ) => String\n             * @param {Number} size 文件大小\n             * @param {Number} [pointLength=2] 精确到的小数点数。\n             * @param {Array} [units=[ 'B', 'K', 'M', 'G', 'TB' ]] 单位数组。从字节，到千字节，一直往上指定。如果单位数组里面只指定了到了K(千字节)，同时文件大小大于M, 此方法的输出将还是显示成多少K.\n             * @example\n             * console.log( Base.formatSize( 100 ) );    // => 100B\n             * console.log( Base.formatSize( 1024 ) );    // => 1.00K\n             * console.log( Base.formatSize( 1024, 0 ) );    // => 1K\n             * console.log( Base.formatSize( 1024 * 1024 ) );    // => 1.00M\n             * console.log( Base.formatSize( 1024 * 1024 * 1024 ) );    // => 1.00G\n             * console.log( Base.formatSize( 1024 * 1024 * 1024, 0, ['B', 'KB', 'MB'] ) );    // => 1024MB\n             */\n            formatSize: function( size, pointLength, units ) {\n                var unit;\n    \n                units = units || [ 'B', 'K', 'M', 'G', 'TB' ];\n    \n                while ( (unit = units.shift()) && size > 1024 ) {\n                    size = size / 1024;\n                }\n    \n                return (unit === 'B' ? size : size.toFixed( pointLength || 2 )) +\n                        unit;\n            }\n        };\n    });\n    /**\n     * 事件处理类，可以独立使用，也可以扩展给对象使用。\n     * @fileOverview Mediator\n     */\n    define('mediator',[\n        'base'\n    ], function( Base ) {\n        var $ = Base.$,\n            slice = [].slice,\n            separator = /\\s+/,\n            protos;\n    \n        // 根据条件过滤出事件handlers.\n        function findHandlers( arr, name, callback, context ) {\n            return $.grep( arr, function( handler ) {\n                return handler &&\n                        (!name || handler.e === name) &&\n                        (!callback || handler.cb === callback ||\n                        handler.cb._cb === callback) &&\n                        (!context || handler.ctx === context);\n            });\n        }\n    \n        function eachEvent( events, callback, iterator ) {\n            // 不支持对象，只支持多个event用空格隔开\n            $.each( (events || '').split( separator ), function( _, key ) {\n                iterator( key, callback );\n            });\n        }\n    \n        function triggerHanders( events, args ) {\n            var stoped = false,\n                i = -1,\n                len = events.length,\n                handler;\n    \n            while ( ++i < len ) {\n                handler = events[ i ];\n    \n                if ( handler.cb.apply( handler.ctx2, args ) === false ) {\n                    stoped = true;\n                    break;\n                }\n            }\n    \n            return !stoped;\n        }\n    \n        protos = {\n    \n            /**\n             * 绑定事件。\n             *\n             * `callback`方法在执行时，arguments将会来源于trigger的时候携带的参数。如\n             * ```javascript\n             * var obj = {};\n             *\n             * // 使得obj有事件行为\n             * Mediator.installTo( obj );\n             *\n             * obj.on( 'testa', function( arg1, arg2 ) {\n             *     console.log( arg1, arg2 ); // => 'arg1', 'arg2'\n             * });\n             *\n             * obj.trigger( 'testa', 'arg1', 'arg2' );\n             * ```\n             *\n             * 如果`callback`中，某一个方法`return false`了，则后续的其他`callback`都不会被执行到。\n             * 切会影响到`trigger`方法的返回值，为`false`。\n             *\n             * `on`还可以用来添加一个特殊事件`all`, 这样所有的事件触发都会响应到。同时此类`callback`中的arguments有一个不同处，\n             * 就是第一个参数为`type`，记录当前是什么事件在触发。此类`callback`的优先级比脚低，会再正常`callback`执行完后触发。\n             * ```javascript\n             * obj.on( 'all', function( type, arg1, arg2 ) {\n             *     console.log( type, arg1, arg2 ); // => 'testa', 'arg1', 'arg2'\n             * });\n             * ```\n             *\n             * @method on\n             * @grammar on( name, callback[, context] ) => self\n             * @param  {String}   name     事件名，支持多个事件用空格隔开\n             * @param  {Function} callback 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             * @class Mediator\n             */\n            on: function( name, callback, context ) {\n                var me = this,\n                    set;\n    \n                if ( !callback ) {\n                    return this;\n                }\n    \n                set = this._events || (this._events = []);\n    \n                eachEvent( name, callback, function( name, callback ) {\n                    var handler = { e: name };\n    \n                    handler.cb = callback;\n                    handler.ctx = context;\n                    handler.ctx2 = context || me;\n                    handler.id = set.length;\n    \n                    set.push( handler );\n                });\n    \n                return this;\n            },\n    \n            /**\n             * 绑定事件，且当handler执行完后，自动解除绑定。\n             * @method once\n             * @grammar once( name, callback[, context] ) => self\n             * @param  {String}   name     事件名\n             * @param  {Function} callback 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             */\n            once: function( name, callback, context ) {\n                var me = this;\n    \n                if ( !callback ) {\n                    return me;\n                }\n    \n                eachEvent( name, callback, function( name, callback ) {\n                    var once = function() {\n                            me.off( name, once );\n                            return callback.apply( context || me, arguments );\n                        };\n    \n                    once._cb = callback;\n                    me.on( name, once, context );\n                });\n    \n                return me;\n            },\n    \n            /**\n             * 解除事件绑定\n             * @method off\n             * @grammar off( [name[, callback[, context] ] ] ) => self\n             * @param  {String}   [name]     事件名\n             * @param  {Function} [callback] 事件处理器\n             * @param  {Object}   [context]  事件处理器的上下文。\n             * @return {self} 返回自身，方便链式\n             * @chainable\n             */\n            off: function( name, cb, ctx ) {\n                var events = this._events;\n    \n                if ( !events ) {\n                    return this;\n                }\n    \n                if ( !name && !cb && !ctx ) {\n                    this._events = [];\n                    return this;\n                }\n    \n                eachEvent( name, cb, function( name, cb ) {\n                    $.each( findHandlers( events, name, cb, ctx ), function() {\n                        delete events[ this.id ];\n                    });\n                });\n    \n                return this;\n            },\n    \n            /**\n             * 触发事件\n             * @method trigger\n             * @grammar trigger( name[, args...] ) => self\n             * @param  {String}   type     事件名\n             * @param  {*} [...] 任意参数\n             * @return {Boolean} 如果handler中return false了，则返回false, 否则返回true\n             */\n            trigger: function( type ) {\n                var args, events, allEvents;\n    \n                if ( !this._events || !type ) {\n                    return this;\n                }\n    \n                args = slice.call( arguments, 1 );\n                events = findHandlers( this._events, type );\n                allEvents = findHandlers( this._events, 'all' );\n    \n                return triggerHanders( events, args ) &&\n                        triggerHanders( allEvents, arguments );\n            }\n        };\n    \n        /**\n         * 中介者，它本身是个单例，但可以通过[installTo](#WebUploader:Mediator:installTo)方法，使任何对象具备事件行为。\n         * 主要目的是负责模块与模块之间的合作，降低耦合度。\n         *\n         * @class Mediator\n         */\n        return $.extend({\n    \n            /**\n             * 可以通过这个接口，使任何对象具备事件功能。\n             * @method installTo\n             * @param  {Object} obj 需要具备事件行为的对象。\n             * @return {Object} 返回obj.\n             */\n            installTo: function( obj ) {\n                return $.extend( obj, protos );\n            }\n    \n        }, protos );\n    });\n    /**\n     * @fileOverview Uploader上传类\n     */\n    define('uploader',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$;\n    \n        /**\n         * 上传入口类。\n         * @class Uploader\n         * @constructor\n         * @grammar new Uploader( opts ) => Uploader\n         * @example\n         * var uploader = WebUploader.Uploader({\n         *     swf: 'path_of_swf/Uploader.swf',\n         *\n         *     // 开起分片上传。\n         *     chunked: true\n         * });\n         */\n        function Uploader( opts ) {\n            this.options = $.extend( true, {}, Uploader.options, opts );\n            this._init( this.options );\n        }\n    \n        // default Options\n        // widgets中有相应扩展\n        Uploader.options = {};\n        Mediator.installTo( Uploader.prototype );\n    \n        // 批量添加纯命令式方法。\n        $.each({\n            upload: 'start-upload',\n            stop: 'stop-upload',\n            getFile: 'get-file',\n            getFiles: 'get-files',\n            addFile: 'add-file',\n            addFiles: 'add-file',\n            sort: 'sort-files',\n            removeFile: 'remove-file',\n            skipFile: 'skip-file',\n            retry: 'retry',\n            isInProgress: 'is-in-progress',\n            makeThumb: 'make-thumb',\n            getDimension: 'get-dimension',\n            addButton: 'add-btn',\n            getRuntimeType: 'get-runtime-type',\n            refresh: 'refresh',\n            disable: 'disable',\n            enable: 'enable',\n            reset: 'reset'\n        }, function( fn, command ) {\n            Uploader.prototype[ fn ] = function() {\n                return this.request( command, arguments );\n            };\n        });\n    \n        $.extend( Uploader.prototype, {\n            state: 'pending',\n    \n            _init: function( opts ) {\n                var me = this;\n    \n                me.request( 'init', opts, function() {\n                    me.state = 'ready';\n                    me.trigger('ready');\n                });\n            },\n    \n            /**\n             * 获取或者设置Uploader配置项。\n             * @method option\n             * @grammar option( key ) => *\n             * @grammar option( key, val ) => self\n             * @example\n             *\n             * // 初始状态图片上传前不会压缩\n             * var uploader = new WebUploader.Uploader({\n             *     resize: null;\n             * });\n             *\n             * // 修改后图片上传前，尝试将图片压缩到1600 * 1600\n             * uploader.options( 'resize', {\n             *     width: 1600,\n             *     height: 1600\n             * });\n             */\n            option: function( key, val ) {\n                var opts = this.options;\n    \n                // setter\n                if ( arguments.length > 1 ) {\n    \n                    if ( $.isPlainObject( val ) &&\n                            $.isPlainObject( opts[ key ] ) ) {\n                        $.extend( opts[ key ], val );\n                    } else {\n                        opts[ key ] = val;\n                    }\n    \n                } else {    // getter\n                    return key ? opts[ key ] : opts;\n                }\n            },\n    \n            /**\n             * 获取文件统计信息。返回一个包含一下信息的对象。\n             * * `successNum` 上传成功的文件数\n             * * `uploadFailNum` 上传失败的文件数\n             * * `cancelNum` 被删除的文件数\n             * * `invalidNum` 无效的文件数\n             * * `queueNum` 还在队列中的文件数\n             * @method getStats\n             * @grammar getStats() => Object\n             */\n            getStats: function() {\n                // return this._mgr.getStats.apply( this._mgr, arguments );\n                var stats = this.request('get-stats');\n    \n                return {\n                    successNum: stats.numOfSuccess,\n    \n                    // who care?\n                    // queueFailNum: 0,\n                    cancelNum: stats.numOfCancel,\n                    invalidNum: stats.numOfInvalid,\n                    uploadFailNum: stats.numOfUploadFailed,\n                    queueNum: stats.numOfQueue\n                };\n            },\n    \n            // 需要重写此方法来来支持opts.onEvent和instance.onEvent的处理器\n            trigger: function( type/*, args...*/ ) {\n                var args = [].slice.call( arguments, 1 ),\n                    opts = this.options,\n                    name = 'on' + type.substring( 0, 1 ).toUpperCase() +\n                        type.substring( 1 );\n    \n                if (\n                        // 调用通过on方法注册的handler.\n                        Mediator.trigger.apply( this, arguments ) === false ||\n    \n                        // 调用opts.onEvent\n                        $.isFunction( opts[ name ] ) &&\n                        opts[ name ].apply( this, args ) === false ||\n    \n                        // 调用this.onEvent\n                        $.isFunction( this[ name ] ) &&\n                        this[ name ].apply( this, args ) === false ||\n    \n                        // 广播所有uploader的事件。\n                        Mediator.trigger.apply( Mediator,\n                        [ this, type ].concat( args ) ) === false ) {\n    \n                    return false;\n                }\n    \n                return true;\n            },\n    \n            // widgets/widget.js将补充此方法的详细文档。\n            request: Base.noop\n        });\n    \n        /**\n         * 创建Uploader实例，等同于new Uploader( opts );\n         * @method create\n         * @class Base\n         * @static\n         * @grammar Base.create( opts ) => Uploader\n         */\n        Base.create = Uploader.create = function( opts ) {\n            return new Uploader( opts );\n        };\n    \n        // 暴露Uploader，可以通过它来扩展业务逻辑。\n        Base.Uploader = Uploader;\n    \n        return Uploader;\n    });\n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/runtime',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$,\n            factories = {},\n    \n            // 获取对象的第一个key\n            getFirstKey = function( obj ) {\n                for ( var key in obj ) {\n                    if ( obj.hasOwnProperty( key ) ) {\n                        return key;\n                    }\n                }\n                return null;\n            };\n    \n        // 接口类。\n        function Runtime( options ) {\n            this.options = $.extend({\n                container: document.body\n            }, options );\n            this.uid = Base.guid('rt_');\n        }\n    \n        $.extend( Runtime.prototype, {\n    \n            getContainer: function() {\n                var opts = this.options,\n                    parent, container;\n    \n                if ( this._container ) {\n                    return this._container;\n                }\n    \n                parent = $( opts.container || document.body );\n                container = $( document.createElement('div') );\n    \n                container.attr( 'id', 'rt_' + this.uid );\n                container.css({\n                    position: 'absolute',\n                    top: '0px',\n                    left: '0px',\n                    width: '1px',\n                    height: '1px',\n                    overflow: 'hidden'\n                });\n    \n                parent.append( container );\n                parent.addClass('webuploader-container');\n                this._container = container;\n                return container;\n            },\n    \n            init: Base.noop,\n            exec: Base.noop,\n    \n            destroy: function() {\n                if ( this._container ) {\n                    this._container.parentNode.removeChild( this.__container );\n                }\n    \n                this.off();\n            }\n        });\n    \n        Runtime.orders = 'html5,flash';\n    \n    \n        /**\n         * 添加Runtime实现。\n         * @param {String} type    类型\n         * @param {Runtime} factory 具体Runtime实现。\n         */\n        Runtime.addRuntime = function( type, factory ) {\n            factories[ type ] = factory;\n        };\n    \n        Runtime.hasRuntime = function( type ) {\n            return !!(type ? factories[ type ] : getFirstKey( factories ));\n        };\n    \n        Runtime.create = function( opts, orders ) {\n            var type, runtime;\n    \n            orders = orders || Runtime.orders;\n            $.each( orders.split( /\\s*,\\s*/g ), function() {\n                if ( factories[ this ] ) {\n                    type = this;\n                    return false;\n                }\n            });\n    \n            type = type || getFirstKey( factories );\n    \n            if ( !type ) {\n                throw new Error('Runtime Error');\n            }\n    \n            runtime = new factories[ type ]( opts );\n            return runtime;\n        };\n    \n        Mediator.installTo( Runtime.prototype );\n        return Runtime;\n    });\n    \n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/client',[\n        'base',\n        'mediator',\n        'runtime/runtime'\n    ], function( Base, Mediator, Runtime ) {\n    \n        var cache;\n    \n        cache = (function() {\n            var obj = {};\n    \n            return {\n                add: function( runtime ) {\n                    obj[ runtime.uid ] = runtime;\n                },\n    \n                get: function( ruid, standalone ) {\n                    var i;\n    \n                    if ( ruid ) {\n                        return obj[ ruid ];\n                    }\n    \n                    for ( i in obj ) {\n                        // 有些类型不能重用，比如filepicker.\n                        if ( standalone && obj[ i ].__standalone ) {\n                            continue;\n                        }\n    \n                        return obj[ i ];\n                    }\n    \n                    return null;\n                },\n    \n                remove: function( runtime ) {\n                    delete obj[ runtime.uid ];\n                }\n            };\n        })();\n    \n        function RuntimeClient( component, standalone ) {\n            var deferred = Base.Deferred(),\n                runtime;\n    \n            this.uid = Base.guid('client_');\n    \n            // 允许runtime没有初始化之前，注册一些方法在初始化后执行。\n            this.runtimeReady = function( cb ) {\n                return deferred.done( cb );\n            };\n    \n            this.connectRuntime = function( opts, cb ) {\n    \n                // already connected.\n                if ( runtime ) {\n                    throw new Error('already connected!');\n                }\n    \n                deferred.done( cb );\n    \n                if ( typeof opts === 'string' && cache.get( opts ) ) {\n                    runtime = cache.get( opts );\n                }\n    \n                // 像filePicker只能独立存在，不能公用。\n                runtime = runtime || cache.get( null, standalone );\n    \n                // 需要创建\n                if ( !runtime ) {\n                    runtime = Runtime.create( opts, opts.runtimeOrder );\n                    runtime.__promise = deferred.promise();\n                    runtime.once( 'ready', deferred.resolve );\n                    runtime.init();\n                    cache.add( runtime );\n                    runtime.__client = 1;\n                } else {\n                    // 来自cache\n                    Base.$.extend( runtime.options, opts );\n                    runtime.__promise.then( deferred.resolve );\n                    runtime.__client++;\n                }\n    \n                standalone && (runtime.__standalone = standalone);\n                return runtime;\n            };\n    \n            this.getRuntime = function() {\n                return runtime;\n            };\n    \n            this.disconnectRuntime = function() {\n                if ( !runtime ) {\n                    return;\n                }\n    \n                runtime.__client--;\n    \n                if ( runtime.__client <= 0 ) {\n                    cache.remove( runtime );\n                    delete runtime.__promise;\n                    runtime.destroy();\n                }\n    \n                runtime = null;\n            };\n    \n            this.exec = function() {\n                if ( !runtime ) {\n                    return;\n                }\n    \n                var args = Base.slice( arguments );\n                component && args.unshift( component );\n    \n                return runtime.exec.apply( this, args );\n            };\n    \n            this.getRuid = function() {\n                return runtime && runtime.uid;\n            };\n    \n            this.destroy = (function( destroy ) {\n                return function() {\n                    destroy && destroy.apply( this, arguments );\n                    this.trigger('destroy');\n                    this.off();\n                    this.exec('destroy');\n                    this.disconnectRuntime();\n                };\n            })( this.destroy );\n        }\n    \n        Mediator.installTo( RuntimeClient.prototype );\n        return RuntimeClient;\n    });\n    /**\n     * @fileOverview 错误信息\n     */\n    define('lib/dnd',[\n        'base',\n        'mediator',\n        'runtime/client'\n    ], function( Base, Mediator, RuntimeClent ) {\n    \n        var $ = Base.$;\n    \n        function DragAndDrop( opts ) {\n            opts = this.options = $.extend({}, DragAndDrop.options, opts );\n    \n            opts.container = $( opts.container );\n    \n            if ( !opts.container.length ) {\n                return;\n            }\n    \n            RuntimeClent.call( this, 'DragAndDrop' );\n        }\n    \n        DragAndDrop.options = {\n            accept: null,\n            disableGlobalDnd: false\n        };\n    \n        Base.inherits( RuntimeClent, {\n            constructor: DragAndDrop,\n    \n            init: function() {\n                var me = this;\n    \n                me.connectRuntime( me.options, function() {\n                    me.exec('init');\n                    me.trigger('ready');\n                });\n            },\n    \n            destroy: function() {\n                this.disconnectRuntime();\n            }\n        });\n    \n        Mediator.installTo( DragAndDrop.prototype );\n    \n        return DragAndDrop;\n    });\n    /**\n     * @fileOverview 组件基类。\n     */\n    define('widgets/widget',[\n        'base',\n        'uploader'\n    ], function( Base, Uploader ) {\n    \n        var $ = Base.$,\n            _init = Uploader.prototype._init,\n            IGNORE = {},\n            widgetClass = [];\n    \n        function isArrayLike( obj ) {\n            if ( !obj ) {\n                return false;\n            }\n    \n            var length = obj.length,\n                type = $.type( obj );\n    \n            if ( obj.nodeType === 1 && length ) {\n                return true;\n            }\n    \n            return type === 'array' || type !== 'function' && type !== 'string' &&\n                    (length === 0 || typeof length === 'number' && length > 0 &&\n                    (length - 1) in obj);\n        }\n    \n        function Widget( uploader ) {\n            this.owner = uploader;\n            this.options = uploader.options;\n        }\n    \n        $.extend( Widget.prototype, {\n    \n            init: Base.noop,\n    \n            // 类Backbone的事件监听声明，监听uploader实例上的事件\n            // widget直接无法监听事件，事件只能通过uploader来传递\n            invoke: function( apiName, args ) {\n    \n                /*\n                    {\n                        'make-thumb': 'makeThumb'\n                    }\n                 */\n                var map = this.responseMap;\n    \n                // 如果无API响应声明则忽略\n                if ( !map || !(apiName in map) || !(map[ apiName ] in this) ||\n                        !$.isFunction( this[ map[ apiName ] ] ) ) {\n    \n                    return IGNORE;\n                }\n    \n                return this[ map[ apiName ] ].apply( this, args );\n    \n            },\n    \n            /**\n             * 发送命令。当传入`callback`或者`handler`中返回`promise`时。返回一个当所有`handler`中的promise都完成后完成的新`promise`。\n             * @method request\n             * @grammar request( command, args ) => * | Promise\n             * @grammar request( command, args, callback ) => Promise\n             * @for  Uploader\n             */\n            request: function() {\n                return this.owner.request.apply( this.owner, arguments );\n            }\n        });\n    \n        // 扩展Uploader.\n        $.extend( Uploader.prototype, {\n    \n            // 覆写_init用来初始化widgets\n            _init: function() {\n                var me = this,\n                    widgets = me._widgets = [];\n    \n                $.each( widgetClass, function( _, klass ) {\n                    widgets.push( new klass( me ) );\n                });\n    \n                return _init.apply( me, arguments );\n            },\n    \n            request: function( apiName, args, callback ) {\n                var i = 0,\n                    widgets = this._widgets,\n                    len = widgets.length,\n                    rlts = [],\n                    dfds = [],\n                    widget, rlt, promise, key;\n    \n                args = isArrayLike( args ) ? args : [ args ];\n    \n                for ( ; i < len; i++ ) {\n                    widget = widgets[ i ];\n                    rlt = widget.invoke( apiName, args );\n    \n                    if ( rlt !== IGNORE ) {\n    \n                        // Deferred对象\n                        if ( Base.isPromise( rlt ) ) {\n                            dfds.push( rlt );\n                        } else {\n                            rlts.push( rlt );\n                        }\n                    }\n                }\n    \n                // 如果有callback，则用异步方式。\n                if ( callback || dfds.length ) {\n                    promise = Base.when.apply( Base, dfds );\n                    key = promise.pipe ? 'pipe' : 'then';\n    \n                    // 很重要不能删除。删除了会死循环。\n                    // 保证执行顺序。让callback总是在下一个tick中执行。\n                    return promise[ key ](function() {\n                                var deferred = Base.Deferred(),\n                                    args = arguments;\n    \n                                setTimeout(function() {\n                                    deferred.resolve.apply( deferred, args );\n                                }, 1 );\n    \n                                return deferred.promise();\n                            })[ key ]( callback || Base.noop );\n                } else {\n                    return rlts[ 0 ];\n                }\n            }\n        });\n    \n        /**\n         * 添加组件\n         * @param  {object} widgetProto 组件原型，构造函数通过constructor属性定义\n         * @param  {object} responseMap API名称与函数实现的映射\n         * @example\n         *     Uploader.register( {\n         *         init: function( options ) {},\n         *         makeThumb: function() {}\n         *     }, {\n         *         'make-thumb': 'makeThumb'\n         *     } );\n         */\n        Uploader.register = Widget.register = function( responseMap, widgetProto ) {\n            var map = { init: 'init' },\n                klass;\n    \n            if ( arguments.length === 1 ) {\n                widgetProto = responseMap;\n                widgetProto.responseMap = map;\n            } else {\n                widgetProto.responseMap = $.extend( map, responseMap );\n            }\n    \n            klass = Base.inherits( Widget, widgetProto );\n            widgetClass.push( klass );\n    \n            return klass;\n        };\n    \n        return Widget;\n    });\n    /**\n     * @fileOverview DragAndDrop Widget。\n     */\n    define('widgets/filednd',[\n        'base',\n        'uploader',\n        'lib/dnd',\n        'widgets/widget'\n    ], function( Base, Uploader, Dnd ) {\n        var $ = Base.$;\n    \n        Uploader.options.dnd = '';\n    \n        /**\n         * @property {Selector} [dnd=undefined]  指定Drag And Drop拖拽的容器，如果不指定，则不启动。\n         * @namespace options\n         * @for Uploader\n         */\n    \n        /**\n         * @event dndAccept\n         * @param {DataTransferItemList} items DataTransferItem\n         * @description 阻止此事件可以拒绝某些类型的文件拖入进来。目前只有 chrome 提供这样的 API，且只能通过 mime-type 验证。\n         * @for  Uploader\n         */\n        return Uploader.register({\n            init: function( opts ) {\n    \n                if ( !opts.dnd ||\n                        this.request('predict-runtime-type') !== 'html5' ) {\n                    return;\n                }\n    \n                var me = this,\n                    deferred = Base.Deferred(),\n                    options = $.extend({}, {\n                        disableGlobalDnd: opts.disableGlobalDnd,\n                        container: opts.dnd,\n                        accept: opts.accept\n                    }),\n                    dnd;\n    \n                dnd = new Dnd( options );\n    \n                dnd.once( 'ready', deferred.resolve );\n                dnd.on( 'drop', function( files ) {\n                    me.request( 'add-file', [ files ]);\n                });\n    \n                // 检测文件是否全部允许添加。\n                dnd.on( 'accept', function( items ) {\n                    return me.owner.trigger( 'dndAccept', items );\n                });\n    \n                dnd.init();\n    \n                return deferred.promise();\n            }\n        });\n    });\n    \n    /**\n     * @fileOverview 错误信息\n     */\n    define('lib/filepaste',[\n        'base',\n        'mediator',\n        'runtime/client'\n    ], function( Base, Mediator, RuntimeClent ) {\n    \n        var $ = Base.$;\n    \n        function FilePaste( opts ) {\n            opts = this.options = $.extend({}, opts );\n            opts.container = $( opts.container || document.body );\n            RuntimeClent.call( this, 'FilePaste' );\n        }\n    \n        Base.inherits( RuntimeClent, {\n            constructor: FilePaste,\n    \n            init: function() {\n                var me = this;\n    \n                me.connectRuntime( me.options, function() {\n                    me.exec('init');\n                    me.trigger('ready');\n                });\n            },\n    \n            destroy: function() {\n                this.exec('destroy');\n                this.disconnectRuntime();\n                this.off();\n            }\n        });\n    \n        Mediator.installTo( FilePaste.prototype );\n    \n        return FilePaste;\n    });\n    /**\n     * @fileOverview 组件基类。\n     */\n    define('widgets/filepaste',[\n        'base',\n        'uploader',\n        'lib/filepaste',\n        'widgets/widget'\n    ], function( Base, Uploader, FilePaste ) {\n        var $ = Base.$;\n    \n        /**\n         * @property {Selector} [paste=undefined]  指定监听paste事件的容器，如果不指定，不启用此功能。此功能为通过粘贴来添加截屏的图片。建议设置为`document.body`.\n         * @namespace options\n         * @for Uploader\n         */\n        return Uploader.register({\n            init: function( opts ) {\n    \n                if ( !opts.paste ||\n                        this.request('predict-runtime-type') !== 'html5' ) {\n                    return;\n                }\n    \n                var me = this,\n                    deferred = Base.Deferred(),\n                    options = $.extend({}, {\n                        container: opts.paste,\n                        accept: opts.accept\n                    }),\n                    paste;\n    \n                paste = new FilePaste( options );\n    \n                paste.once( 'ready', deferred.resolve );\n                paste.on( 'paste', function( files ) {\n                    me.owner.request( 'add-file', [ files ]);\n                });\n                paste.init();\n    \n                return deferred.promise();\n            }\n        });\n    });\n    /**\n     * @fileOverview Blob\n     */\n    define('lib/blob',[\n        'base',\n        'runtime/client'\n    ], function( Base, RuntimeClient ) {\n    \n        function Blob( ruid, source ) {\n            var me = this;\n    \n            me.source = source;\n            me.ruid = ruid;\n    \n            RuntimeClient.call( me, 'Blob' );\n    \n            this.uid = source.uid || this.uid;\n            this.type = source.type || '';\n            this.size = source.size || 0;\n    \n            if ( ruid ) {\n                me.connectRuntime( ruid );\n            }\n        }\n    \n        Base.inherits( RuntimeClient, {\n            constructor: Blob,\n    \n            slice: function( start, end ) {\n                return this.exec( 'slice', start, end );\n            },\n    \n            getSource: function() {\n                return this.source;\n            }\n        });\n    \n        return Blob;\n    });\n    /**\n     * 为了统一化Flash的File和HTML5的File而存在。\n     * 以至于要调用Flash里面的File，也可以像调用HTML5版本的File一下。\n     * @fileOverview File\n     */\n    define('lib/file',[\n        'base',\n        'lib/blob'\n    ], function( Base, Blob ) {\n    \n        var uid = 1,\n            rExt = /\\.([^.]+)$/;\n    \n        function File( ruid, file ) {\n            var ext;\n    \n            Blob.apply( this, arguments );\n            this.name = file.name || ('untitled' + uid++);\n            ext = rExt.exec( file.name ) ? RegExp.$1.toLowerCase() : '';\n    \n            // todo 支持其他类型文件的转换。\n    \n            // 如果有mimetype, 但是文件名里面没有找出后缀规律\n            if ( !ext && this.type ) {\n                ext = /\\/(jpg|jpeg|png|gif|bmp)$/i.exec( this.type ) ?\n                        RegExp.$1.toLowerCase() : '';\n                this.name += '.' + ext;\n            }\n    \n            // 如果没有指定mimetype, 但是知道文件后缀。\n            if ( !this.type &&  ~'jpg,jpeg,png,gif,bmp'.indexOf( ext ) ) {\n                this.type = 'image/' + (ext === 'jpg' ? 'jpeg' : ext);\n            }\n    \n            this.ext = ext;\n            this.lastModifiedDate = file.lastModifiedDate ||\n                    (new Date()).toLocaleString();\n        }\n    \n        return Base.inherits( Blob, File );\n    });\n    \n    /**\n     * @fileOverview 错误信息\n     */\n    define('lib/filepicker',[\n        'base',\n        'runtime/client',\n        'lib/file'\n    ], function( Base, RuntimeClent, File ) {\n    \n        var $ = Base.$;\n    \n        function FilePicker( opts ) {\n            opts = this.options = $.extend({}, FilePicker.options, opts );\n    \n            opts.container = $( opts.id );\n    \n            if ( !opts.container.length ) {\n                throw new Error('按钮指定错误');\n            }\n    \n            opts.innerHTML = opts.innerHTML || opts.label ||\n                    opts.container.html() || '';\n    \n            opts.button = $( opts.button || document.createElement('div') );\n            opts.button.html( opts.innerHTML );\n            opts.container.html( opts.button );\n    \n            RuntimeClent.call( this, 'FilePicker', true );\n        }\n    \n        FilePicker.options = {\n            button: null,\n            container: null,\n            label: null,\n            innerHTML: null,\n            multiple: true,\n            accept: null,\n            name: 'file'\n        };\n    \n        Base.inherits( RuntimeClent, {\n            constructor: FilePicker,\n    \n            init: function() {\n                var me = this,\n                    opts = me.options,\n                    button = opts.button;\n    \n                button.addClass('webuploader-pick');\n    \n                me.on( 'all', function( type ) {\n                    var files;\n    \n                    switch ( type ) {\n                        case 'mouseenter':\n                            button.addClass('webuploader-pick-hover');\n                            break;\n    \n                        case 'mouseleave':\n                            button.removeClass('webuploader-pick-hover');\n                            break;\n    \n                        case 'change':\n                            files = me.exec('getFiles');\n                            me.trigger( 'select', $.map( files, function( file ) {\n                                file = new File( me.getRuid(), file );\n    \n                                // 记录来源。\n                                file._refer = opts.container;\n                                return file;\n                            }), opts.container );\n                            break;\n                    }\n                });\n    \n                me.connectRuntime( opts, function() {\n                    me.refresh();\n                    me.exec( 'init', opts );\n                    me.trigger('ready');\n                });\n    \n                $( window ).on( 'resize', function() {\n                    me.refresh();\n                });\n            },\n    \n            refresh: function() {\n                var shimContainer = this.getRuntime().getContainer(),\n                    button = this.options.button,\n                    width = button.outerWidth ?\n                            button.outerWidth() : button.width(),\n    \n                    height = button.outerHeight ?\n                            button.outerHeight() : button.height(),\n    \n                    pos = button.offset();\n    \n                width && height && shimContainer.css({\n                    bottom: 'auto',\n                    right: 'auto',\n                    width: width + 'px',\n                    height: height + 'px'\n                }).offset( pos );\n            },\n    \n            enable: function() {\n                var btn = this.options.button;\n    \n                btn.removeClass('webuploader-pick-disable');\n                this.refresh();\n            },\n    \n            disable: function() {\n                var btn = this.options.button;\n    \n                this.getRuntime().getContainer().css({\n                    top: '-99999px'\n                });\n    \n                btn.addClass('webuploader-pick-disable');\n            },\n    \n            destroy: function() {\n                if ( this.runtime ) {\n                    this.exec('destroy');\n                    this.disconnectRuntime();\n                }\n            }\n        });\n    \n        return FilePicker;\n    });\n    \n    /**\n     * @fileOverview 文件选择相关\n     */\n    define('widgets/filepicker',[\n        'base',\n        'uploader',\n        'lib/filepicker',\n        'widgets/widget'\n    ], function( Base, Uploader, FilePicker ) {\n        var $ = Base.$;\n    \n        $.extend( Uploader.options, {\n    \n            /**\n             * @property {Selector | Object} [pick=undefined]\n             * @namespace options\n             * @for Uploader\n             * @description 指定选择文件的按钮容器，不指定则不创建按钮。\n             *\n             * * `id` {Seletor} 指定选择文件的按钮容器，不指定则不创建按钮。\n             * * `label` {String} 请采用 `innerHTML` 代替\n             * * `innerHTML` {String} 指定按钮文字。不指定时优先从指定的容器中看是否自带文字。\n             * * `multiple` {Boolean} 是否开起同时选择多个文件能力。\n             */\n            pick: null,\n    \n            /**\n             * @property {Arroy} [accept=null]\n             * @namespace options\n             * @for Uploader\n             * @description 指定接受哪些类型的文件。 由于目前还有ext转mimeType表，所以这里需要分开指定。\n             *\n             * * `title` {String} 文字描述\n             * * `extensions` {String} 允许的文件后缀，不带点，多个用逗号分割。\n             * * `mimeTypes` {String} 多个用逗号分割。\n             *\n             * 如：\n             *\n             * ```\n             * {\n             *     title: 'Images',\n             *     extensions: 'gif,jpg,jpeg,bmp,png',\n             *     mimeTypes: 'image/*'\n             * }\n             * ```\n             */\n            accept: null/*{\n                title: 'Images',\n                extensions: 'gif,jpg,jpeg,bmp,png',\n                mimeTypes: 'image/*'\n            }*/\n        });\n    \n        return Uploader.register({\n            'add-btn': 'addButton',\n            refresh: 'refresh',\n            disable: 'disable',\n            enable: 'enable'\n        }, {\n    \n            init: function( opts ) {\n                this.pickers = [];\n                return opts.pick && this.addButton( opts.pick );\n            },\n    \n            refresh: function() {\n                $.each( this.pickers, function() {\n                    this.refresh();\n                });\n            },\n    \n            /**\n             * @method addButton\n             * @for Uploader\n             * @grammar addButton( pick ) => Promise\n             * @description\n             * 添加文件选择按钮，如果一个按钮不够，需要调用此方法来添加。参数跟[options.pick](#WebUploader:Uploader:options)一致。\n             * @example\n             * uploader.addButton({\n             *     id: '#btnContainer',\n             *     innerHTML: '选择文件'\n             * });\n             */\n            addButton: function( pick ) {\n                var me = this,\n                    opts = me.options,\n                    accept = opts.accept,\n                    options, picker, deferred;\n    \n                if ( !pick ) {\n                    return;\n                }\n    \n                deferred = Base.Deferred();\n                $.isPlainObject( pick ) || (pick = {\n                    id: pick\n                });\n    \n                options = $.extend({}, pick, {\n                    accept: $.isPlainObject( accept ) ? [ accept ] : accept,\n                    swf: opts.swf,\n                    runtimeOrder: opts.runtimeOrder\n                });\n    \n                picker = new FilePicker( options );\n    \n                picker.once( 'ready', deferred.resolve );\n                picker.on( 'select', function( files ) {\n                    me.owner.request( 'add-file', [ files ]);\n                });\n                picker.init();\n    \n                this.pickers.push( picker );\n    \n                return deferred.promise();\n            },\n    \n            disable: function() {\n                $.each( this.pickers, function() {\n                    this.disable();\n                });\n            },\n    \n            enable: function() {\n                $.each( this.pickers, function() {\n                    this.enable();\n                });\n            }\n        });\n    });\n    /**\n     * @fileOverview 文件属性封装\n     */\n    define('file',[\n        'base',\n        'mediator'\n    ], function( Base, Mediator ) {\n    \n        var $ = Base.$,\n            idPrefix = 'WU_FILE_',\n            idSuffix = 0,\n            rExt = /\\.([^.]+)$/,\n            statusMap = {};\n    \n        function gid() {\n            return idPrefix + idSuffix++;\n        }\n    \n        /**\n         * 文件类\n         * @class File\n         * @constructor 构造函数\n         * @grammar new File( source ) => File\n         * @param {Lib.File} source [lib.File](#Lib.File)实例, 此source对象是带有Runtime信息的。\n         */\n        function WUFile( source ) {\n    \n            /**\n             * 文件名，包括扩展名（后缀）\n             * @property name\n             * @type {string}\n             */\n            this.name = source.name || 'Untitled';\n    \n            /**\n             * 文件体积（字节）\n             * @property size\n             * @type {uint}\n             * @default 0\n             */\n            this.size = source.size || 0;\n    \n            /**\n             * 文件MIMETYPE类型，与文件类型的对应关系请参考[http://t.cn/z8ZnFny](http://t.cn/z8ZnFny)\n             * @property type\n             * @type {string}\n             * @default 'application'\n             */\n            this.type = source.type || 'application';\n    \n            /**\n             * 文件最后修改日期\n             * @property lastModifiedDate\n             * @type {int}\n             * @default 当前时间戳\n             */\n            this.lastModifiedDate = source.lastModifiedDate || (new Date() * 1);\n    \n            /**\n             * 文件ID，每个对象具有唯一ID，与文件名无关\n             * @property id\n             * @type {string}\n             */\n            this.id = gid();\n    \n            /**\n             * 文件扩展名，通过文件名获取，例如test.png的扩展名为png\n             * @property ext\n             * @type {string}\n             */\n            this.ext = rExt.exec( this.name ) ? RegExp.$1 : '';\n    \n    \n            /**\n             * 状态文字说明。在不同的status语境下有不同的用途。\n             * @property statusText\n             * @type {string}\n             */\n            this.statusText = '';\n    \n            // 存储文件状态，防止通过属性直接修改\n            statusMap[ this.id ] = WUFile.Status.INITED;\n    \n            this.source = source;\n            this.loaded = 0;\n    \n            this.on( 'error', function( msg ) {\n                this.setStatus( WUFile.Status.ERROR, msg );\n            });\n        }\n    \n        $.extend( WUFile.prototype, {\n    \n            /**\n             * 设置状态，状态变化时会触发`change`事件。\n             * @method setStatus\n             * @grammar setStatus( status[, statusText] );\n             * @param {File.Status|String} status [文件状态值](#WebUploader:File:File.Status)\n             * @param {String} [statusText=''] 状态说明，常在error时使用，用http, abort,server等来标记是由于什么原因导致文件错误。\n             */\n            setStatus: function( status, text ) {\n    \n                var prevStatus = statusMap[ this.id ];\n    \n                typeof text !== 'undefined' && (this.statusText = text);\n    \n                if ( status !== prevStatus ) {\n                    statusMap[ this.id ] = status;\n                    /**\n                     * 文件状态变化\n                     * @event statuschange\n                     */\n                    this.trigger( 'statuschange', status, prevStatus );\n                }\n    \n            },\n    \n            /**\n             * 获取文件状态\n             * @return {File.Status}\n             * @example\n                     文件状态具体包括以下几种类型：\n                     {\n                         // 初始化\n                        INITED:     0,\n                        // 已入队列\n                        QUEUED:     1,\n                        // 正在上传\n                        PROGRESS:     2,\n                        // 上传出错\n                        ERROR:         3,\n                        // 上传成功\n                        COMPLETE:     4,\n                        // 上传取消\n                        CANCELLED:     5\n                    }\n             */\n            getStatus: function() {\n                return statusMap[ this.id ];\n            },\n    \n            /**\n             * 获取文件原始信息。\n             * @return {*}\n             */\n            getSource: function() {\n                return this.source;\n            },\n    \n            destory: function() {\n                delete statusMap[ this.id ];\n            }\n        });\n    \n        Mediator.installTo( WUFile.prototype );\n    \n        /**\n         * 文件状态值，具体包括以下几种类型：\n         * * `inited` 初始状态\n         * * `queued` 已经进入队列, 等待上传\n         * * `progress` 上传中\n         * * `complete` 上传完成。\n         * * `error` 上传出错，可重试\n         * * `interrupt` 上传中断，可续传。\n         * * `invalid` 文件不合格，不能重试上传。会自动从队列中移除。\n         * * `cancelled` 文件被移除。\n         * @property {Object} Status\n         * @namespace File\n         * @class File\n         * @static\n         */\n        WUFile.Status = {\n            INITED:     'inited',    // 初始状态\n            QUEUED:     'queued',    // 已经进入队列, 等待上传\n            PROGRESS:   'progress',    // 上传中\n            ERROR:      'error',    // 上传出错，可重试\n            COMPLETE:   'complete',    // 上传完成。\n            CANCELLED:  'cancelled',    // 上传取消。\n            INTERRUPT:  'interrupt',    // 上传中断，可续传。\n            INVALID:    'invalid'    // 文件不合格，不能重试上传。\n        };\n    \n        return WUFile;\n    });\n    \n    /**\n     * @fileOverview 文件队列\n     */\n    define('queue',[\n        'base',\n        'mediator',\n        'file'\n    ], function( Base, Mediator, WUFile ) {\n    \n        var $ = Base.$,\n            STATUS = WUFile.Status;\n    \n        /**\n         * 文件队列, 用来存储各个状态中的文件。\n         * @class Queue\n         * @extends Mediator\n         */\n        function Queue() {\n    \n            /**\n             * 统计文件数。\n             * * `numOfQueue` 队列中的文件数。\n             * * `numOfSuccess` 上传成功的文件数\n             * * `numOfCancel` 被移除的文件数\n             * * `numOfProgress` 正在上传中的文件数\n             * * `numOfUploadFailed` 上传错误的文件数。\n             * * `numOfInvalid` 无效的文件数。\n             * @property {Object} stats\n             */\n            this.stats = {\n                numOfQueue: 0,\n                numOfSuccess: 0,\n                numOfCancel: 0,\n                numOfProgress: 0,\n                numOfUploadFailed: 0,\n                numOfInvalid: 0\n            };\n    \n            // 上传队列，仅包括等待上传的文件\n            this._queue = [];\n    \n            // 存储所有文件\n            this._map = {};\n        }\n    \n        $.extend( Queue.prototype, {\n    \n            /**\n             * 将新文件加入对队列尾部\n             *\n             * @method append\n             * @param  {File} file   文件对象\n             */\n            append: function( file ) {\n                this._queue.push( file );\n                this._fileAdded( file );\n                return this;\n            },\n    \n            /**\n             * 将新文件加入对队列头部\n             *\n             * @method prepend\n             * @param  {File} file   文件对象\n             */\n            prepend: function( file ) {\n                this._queue.unshift( file );\n                this._fileAdded( file );\n                return this;\n            },\n    \n            /**\n             * 获取文件对象\n             *\n             * @method getFile\n             * @param  {String} fileId   文件ID\n             * @return {File}\n             */\n            getFile: function( fileId ) {\n                if ( typeof fileId !== 'string' ) {\n                    return fileId;\n                }\n                return this._map[ fileId ];\n            },\n    \n            /**\n             * 从队列中取出一个指定状态的文件。\n             * @grammar fetch( status ) => File\n             * @method fetch\n             * @param {String} status [文件状态值](#WebUploader:File:File.Status)\n             * @return {File} [File](#WebUploader:File)\n             */\n            fetch: function( status ) {\n                var len = this._queue.length,\n                    i, file;\n    \n                status = status || STATUS.QUEUED;\n    \n                for ( i = 0; i < len; i++ ) {\n                    file = this._queue[ i ];\n    \n                    if ( status === file.getStatus() ) {\n                        return file;\n                    }\n                }\n    \n                return null;\n            },\n    \n            /**\n             * 对队列进行排序，能够控制文件上传顺序。\n             * @grammar sort( fn ) => undefined\n             * @method sort\n             * @param {Function} fn 排序方法\n             */\n            sort: function( fn ) {\n                if ( typeof fn === 'function' ) {\n                    this._queue.sort( fn );\n                }\n            },\n    \n            /**\n             * 获取指定类型的文件列表, 列表中每一个成员为[File](#WebUploader:File)对象。\n             * @grammar getFiles( [status1[, status2 ...]] ) => Array\n             * @method getFiles\n             * @param {String} [status] [文件状态值](#WebUploader:File:File.Status)\n             */\n            getFiles: function() {\n                var sts = [].slice.call( arguments, 0 ),\n                    ret = [],\n                    i = 0,\n                    len = this._queue.length,\n                    file;\n    \n                for ( ; i < len; i++ ) {\n                    file = this._queue[ i ];\n    \n                    if ( sts.length && !~$.inArray( file.getStatus(), sts ) ) {\n                        continue;\n                    }\n    \n                    ret.push( file );\n                }\n    \n                return ret;\n            },\n    \n            _fileAdded: function( file ) {\n                var me = this,\n                    existing = this._map[ file.id ];\n    \n                if ( !existing ) {\n                    this._map[ file.id ] = file;\n    \n                    file.on( 'statuschange', function( cur, pre ) {\n                        me._onFileStatusChange( cur, pre );\n                    });\n                }\n    \n                file.setStatus( STATUS.QUEUED );\n            },\n    \n            _onFileStatusChange: function( curStatus, preStatus ) {\n                var stats = this.stats;\n    \n                switch ( preStatus ) {\n                    case STATUS.PROGRESS:\n                        stats.numOfProgress--;\n                        break;\n    \n                    case STATUS.QUEUED:\n                        stats.numOfQueue --;\n                        break;\n    \n                    case STATUS.ERROR:\n                        stats.numOfUploadFailed--;\n                        break;\n    \n                    case STATUS.INVALID:\n                        stats.numOfInvalid--;\n                        break;\n                }\n    \n                switch ( curStatus ) {\n                    case STATUS.QUEUED:\n                        stats.numOfQueue++;\n                        break;\n    \n                    case STATUS.PROGRESS:\n                        stats.numOfProgress++;\n                        break;\n    \n                    case STATUS.ERROR:\n                        stats.numOfUploadFailed++;\n                        break;\n    \n                    case STATUS.COMPLETE:\n                        stats.numOfSuccess++;\n                        break;\n    \n                    case STATUS.CANCELLED:\n                        stats.numOfCancel++;\n                        break;\n    \n                    case STATUS.INVALID:\n                        stats.numOfInvalid++;\n                        break;\n                }\n            }\n    \n        });\n    \n        Mediator.installTo( Queue.prototype );\n    \n        return Queue;\n    });\n    /**\n     * @fileOverview 队列\n     */\n    define('widgets/queue',[\n        'base',\n        'uploader',\n        'queue',\n        'file',\n        'lib/file',\n        'runtime/client',\n        'widgets/widget'\n    ], function( Base, Uploader, Queue, WUFile, File, RuntimeClient ) {\n    \n        var $ = Base.$,\n            rExt = /\\.\\w+$/,\n            Status = WUFile.Status;\n    \n        return Uploader.register({\n            'sort-files': 'sortFiles',\n            'add-file': 'addFiles',\n            'get-file': 'getFile',\n            'fetch-file': 'fetchFile',\n            'get-stats': 'getStats',\n            'get-files': 'getFiles',\n            'remove-file': 'removeFile',\n            'retry': 'retry',\n            'reset': 'reset',\n            'accept-file': 'acceptFile'\n        }, {\n    \n            init: function( opts ) {\n                var me = this,\n                    deferred, len, i, item, arr, accept, runtime;\n    \n                if ( $.isPlainObject( opts.accept ) ) {\n                    opts.accept = [ opts.accept ];\n                }\n    \n                // accept中的中生成匹配正则。\n                if ( opts.accept ) {\n                    arr = [];\n    \n                    for ( i = 0, len = opts.accept.length; i < len; i++ ) {\n                        item = opts.accept[ i ].extensions;\n                        item && arr.push( item );\n                    }\n    \n                    if ( arr.length ) {\n                        accept = '\\\\.' + arr.join(',')\n                                .replace( /,/g, '$|\\\\.' )\n                                .replace( /\\*/g, '.*' ) + '$';\n                    }\n    \n                    me.accept = new RegExp( accept, 'i' );\n                }\n    \n                me.queue = new Queue();\n                me.stats = me.queue.stats;\n    \n                // 如果当前不是html5运行时，那就算了。\n                // 不执行后续操作\n                if ( this.request('predict-runtime-type') !== 'html5' ) {\n                    return;\n                }\n    \n                // 创建一个 html5 运行时的 placeholder\n                // 以至于外部添加原生 File 对象的时候能正确包裹一下供 webuploader 使用。\n                deferred = Base.Deferred();\n                runtime = new RuntimeClient('Placeholder');\n                runtime.connectRuntime({\n                    runtimeOrder: 'html5'\n                }, function() {\n                    me._ruid = runtime.getRuid();\n                    deferred.resolve();\n                });\n                return deferred.promise();\n            },\n    \n    \n            // 为了支持外部直接添加一个原生File对象。\n            _wrapFile: function( file ) {\n                if ( !(file instanceof WUFile) ) {\n    \n                    if ( !(file instanceof File) ) {\n                        if ( !this._ruid ) {\n                            throw new Error('Can\\'t add external files.');\n                        }\n                        file = new File( this._ruid, file );\n                    }\n    \n                    file = new WUFile( file );\n                }\n    \n                return file;\n            },\n    \n            // 判断文件是否可以被加入队列\n            acceptFile: function( file ) {\n                var invalid = !file || file.size < 6 || this.accept &&\n    \n                        // 如果名字中有后缀，才做后缀白名单处理。\n                        rExt.exec( file.name ) && !this.accept.test( file.name );\n    \n                return !invalid;\n            },\n    \n    \n            /**\n             * @event beforeFileQueued\n             * @param {File} file File对象\n             * @description 当文件被加入队列之前触发，此事件的handler返回值为`false`，则此文件不会被添加进入队列。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event fileQueued\n             * @param {File} file File对象\n             * @description 当文件被加入队列以后触发。\n             * @for  Uploader\n             */\n    \n            _addFile: function( file ) {\n                var me = this;\n    \n                file = me._wrapFile( file );\n    \n                // 不过类型判断允许不允许，先派送 `beforeFileQueued`\n                if ( !me.owner.trigger( 'beforeFileQueued', file ) ) {\n                    return;\n                }\n    \n                // 类型不匹配，则派送错误事件，并返回。\n                if ( !me.acceptFile( file ) ) {\n                    me.owner.trigger( 'error', 'Q_TYPE_DENIED', file );\n                    return;\n                }\n    \n                me.queue.append( file );\n                me.owner.trigger( 'fileQueued', file );\n                return file;\n            },\n    \n            getFile: function( fileId ) {\n                return this.queue.getFile( fileId );\n            },\n    \n            /**\n             * @event filesQueued\n             * @param {File} files 数组，内容为原始File(lib/File）对象。\n             * @description 当一批文件添加进队列以后触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @method addFiles\n             * @grammar addFiles( file ) => undefined\n             * @grammar addFiles( [file1, file2 ...] ) => undefined\n             * @param {Array of File or File} [files] Files 对象 数组\n             * @description 添加文件到队列\n             * @for  Uploader\n             */\n            addFiles: function( files ) {\n                var me = this;\n    \n                if ( !files.length ) {\n                    files = [ files ];\n                }\n    \n                files = $.map( files, function( file ) {\n                    return me._addFile( file );\n                });\n    \n                me.owner.trigger( 'filesQueued', files );\n    \n                if ( me.options.auto ) {\n                    me.request('start-upload');\n                }\n            },\n    \n            getStats: function() {\n                return this.stats;\n            },\n    \n            /**\n             * @event fileDequeued\n             * @param {File} file File对象\n             * @description 当文件被移除队列后触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @method removeFile\n             * @grammar removeFile( file ) => undefined\n             * @grammar removeFile( id ) => undefined\n             * @param {File|id} file File对象或这File对象的id\n             * @description 移除某一文件。\n             * @for  Uploader\n             * @example\n             *\n             * $li.on('click', '.remove-this', function() {\n             *     uploader.removeFile( file );\n             * })\n             */\n            removeFile: function( file ) {\n                var me = this;\n    \n                file = file.id ? file : me.queue.getFile( file );\n    \n                file.setStatus( Status.CANCELLED );\n                me.owner.trigger( 'fileDequeued', file );\n            },\n    \n            /**\n             * @method getFiles\n             * @grammar getFiles() => Array\n             * @grammar getFiles( status1, status2, status... ) => Array\n             * @description 返回指定状态的文件集合，不传参数将返回所有状态的文件。\n             * @for  Uploader\n             * @example\n             * console.log( uploader.getFiles() );    // => all files\n             * console.log( uploader.getFiles('error') )    // => all error files.\n             */\n            getFiles: function() {\n                return this.queue.getFiles.apply( this.queue, arguments );\n            },\n    \n            fetchFile: function() {\n                return this.queue.fetch.apply( this.queue, arguments );\n            },\n    \n            /**\n             * @method retry\n             * @grammar retry() => undefined\n             * @grammar retry( file ) => undefined\n             * @description 重试上传，重试指定文件，或者从出错的文件开始重新上传。\n             * @for  Uploader\n             * @example\n             * function retry() {\n             *     uploader.retry();\n             * }\n             */\n            retry: function( file, noForceStart ) {\n                var me = this,\n                    files, i, len;\n    \n                if ( file ) {\n                    file = file.id ? file : me.queue.getFile( file );\n                    file.setStatus( Status.QUEUED );\n                    noForceStart || me.request('start-upload');\n                    return;\n                }\n    \n                files = me.queue.getFiles( Status.ERROR );\n                i = 0;\n                len = files.length;\n    \n                for ( ; i < len; i++ ) {\n                    file = files[ i ];\n                    file.setStatus( Status.QUEUED );\n                }\n    \n                me.request('start-upload');\n            },\n    \n            /**\n             * @method sort\n             * @grammar sort( fn ) => undefined\n             * @description 排序队列中的文件，在上传之前调整可以控制上传顺序。\n             * @for  Uploader\n             */\n            sortFiles: function() {\n                return this.queue.sort.apply( this.queue, arguments );\n            },\n    \n            /**\n             * @method reset\n             * @grammar reset() => undefined\n             * @description 重置uploader。目前只重置了队列。\n             * @for  Uploader\n             * @example\n             * uploader.reset();\n             */\n            reset: function() {\n                this.queue = new Queue();\n                this.stats = this.queue.stats;\n            }\n        });\n    \n    });\n    /**\n     * @fileOverview 添加获取Runtime相关信息的方法。\n     */\n    define('widgets/runtime',[\n        'uploader',\n        'runtime/runtime',\n        'widgets/widget'\n    ], function( Uploader, Runtime ) {\n    \n        Uploader.support = function() {\n            return Runtime.hasRuntime.apply( Runtime, arguments );\n        };\n    \n        return Uploader.register({\n            'predict-runtime-type': 'predictRuntmeType'\n        }, {\n    \n            init: function() {\n                if ( !this.predictRuntmeType() ) {\n                    throw Error('Runtime Error');\n                }\n            },\n    \n            /**\n             * 预测Uploader将采用哪个`Runtime`\n             * @grammar predictRuntmeType() => String\n             * @method predictRuntmeType\n             * @for  Uploader\n             */\n            predictRuntmeType: function() {\n                var orders = this.options.runtimeOrder || Runtime.orders,\n                    type = this.type,\n                    i, len;\n    \n                if ( !type ) {\n                    orders = orders.split( /\\s*,\\s*/g );\n    \n                    for ( i = 0, len = orders.length; i < len; i++ ) {\n                        if ( Runtime.hasRuntime( orders[ i ] ) ) {\n                            this.type = type = orders[ i ];\n                            break;\n                        }\n                    }\n                }\n    \n                return type;\n            }\n        });\n    });\n    /**\n     * @fileOverview Transport\n     */\n    define('lib/transport',[\n        'base',\n        'runtime/client',\n        'mediator'\n    ], function( Base, RuntimeClient, Mediator ) {\n    \n        var $ = Base.$;\n    \n        function Transport( opts ) {\n            var me = this;\n    \n            opts = me.options = $.extend( true, {}, Transport.options, opts || {} );\n            RuntimeClient.call( this, 'Transport' );\n    \n            this._blob = null;\n            this._formData = opts.formData || {};\n            this._headers = opts.headers || {};\n    \n            this.on( 'progress', this._timeout );\n            this.on( 'load error', function() {\n                me.trigger( 'progress', 1 );\n                clearTimeout( me._timer );\n            });\n        }\n    \n        Transport.options = {\n            server: '',\n            method: 'POST',\n    \n            // 跨域时，是否允许携带cookie, 只有html5 runtime才有效\n            withCredentials: false,\n            fileVal: 'file',\n            timeout: 2 * 60 * 1000,    // 2分钟\n            formData: {},\n            headers: {},\n            sendAsBinary: false\n        };\n    \n        $.extend( Transport.prototype, {\n    \n            // 添加Blob, 只能添加一次，最后一次有效。\n            appendBlob: function( key, blob, filename ) {\n                var me = this,\n                    opts = me.options;\n    \n                if ( me.getRuid() ) {\n                    me.disconnectRuntime();\n                }\n    \n                // 连接到blob归属的同一个runtime.\n                me.connectRuntime( blob.ruid, function() {\n                    me.exec('init');\n                });\n    \n                me._blob = blob;\n                opts.fileVal = key || opts.fileVal;\n                opts.filename = filename || opts.filename;\n            },\n    \n            // 添加其他字段\n            append: function( key, value ) {\n                if ( typeof key === 'object' ) {\n                    $.extend( this._formData, key );\n                } else {\n                    this._formData[ key ] = value;\n                }\n            },\n    \n            setRequestHeader: function( key, value ) {\n                if ( typeof key === 'object' ) {\n                    $.extend( this._headers, key );\n                } else {\n                    this._headers[ key ] = value;\n                }\n            },\n    \n            send: function( method ) {\n                this.exec( 'send', method );\n                this._timeout();\n            },\n    \n            abort: function() {\n                clearTimeout( this._timer );\n                return this.exec('abort');\n            },\n    \n            destroy: function() {\n                this.trigger('destroy');\n                this.off();\n                this.exec('destroy');\n                this.disconnectRuntime();\n            },\n    \n            getResponse: function() {\n                return this.exec('getResponse');\n            },\n    \n            getResponseAsJson: function() {\n                return this.exec('getResponseAsJson');\n            },\n    \n            getStatus: function() {\n                return this.exec('getStatus');\n            },\n    \n            _timeout: function() {\n                var me = this,\n                    duration = me.options.timeout;\n    \n                if ( !duration ) {\n                    return;\n                }\n    \n                clearTimeout( me._timer );\n                me._timer = setTimeout(function() {\n                    me.abort();\n                    me.trigger( 'error', 'timeout' );\n                }, duration );\n            }\n    \n        });\n    \n        // 让Transport具备事件功能。\n        Mediator.installTo( Transport.prototype );\n    \n        return Transport;\n    });\n    /**\n     * @fileOverview 负责文件上传相关。\n     */\n    define('widgets/upload',[\n        'base',\n        'uploader',\n        'file',\n        'lib/transport',\n        'widgets/widget'\n    ], function( Base, Uploader, WUFile, Transport ) {\n    \n        var $ = Base.$,\n            isPromise = Base.isPromise,\n            Status = WUFile.Status;\n    \n        // 添加默认配置项\n        $.extend( Uploader.options, {\n    \n    \n            /**\n             * @property {Boolean} [prepareNextFile=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否允许在文件传输时提前把下一个文件准备好。\n             * 对于一个文件的准备工作比较耗时，比如图片压缩，md5序列化。\n             * 如果能提前在当前文件传输期处理，可以节省总体耗时。\n             */\n            prepareNextFile: false,\n    \n            /**\n             * @property {Boolean} [chunked=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否要分片处理大文件上传。\n             */\n            chunked: false,\n    \n            /**\n             * @property {Boolean} [chunkSize=5242880]\n             * @namespace options\n             * @for Uploader\n             * @description 如果要分片，分多大一片？ 默认大小为5M.\n             */\n            chunkSize: 5 * 1024 * 1024,\n    \n            /**\n             * @property {Boolean} [chunkRetry=2]\n             * @namespace options\n             * @for Uploader\n             * @description 如果某个分片由于网络问题出错，允许自动重传多少次？\n             */\n            chunkRetry: 2,\n    \n            /**\n             * @property {Boolean} [threads=3]\n             * @namespace options\n             * @for Uploader\n             * @description 上传并发数。允许同时最大上传进程数。\n             */\n            threads: 3,\n    \n    \n            /**\n             * @property {Object} [formData]\n             * @namespace options\n             * @for Uploader\n             * @description 文件上传请求的参数表，每次发送都会发送此对象中的参数。\n             */\n            formData: null\n    \n            /**\n             * @property {Object} [fileVal='file']\n             * @namespace options\n             * @for Uploader\n             * @description 设置文件上传域的name。\n             */\n    \n            /**\n             * @property {Object} [method='POST']\n             * @namespace options\n             * @for Uploader\n             * @description 文件上传方式，`POST`或者`GET`。\n             */\n    \n            /**\n             * @property {Object} [sendAsBinary=false]\n             * @namespace options\n             * @for Uploader\n             * @description 是否已二进制的流的方式发送文件，这样整个上传内容`php://input`都为文件内容，\n             * 其他参数在$_GET数组中。\n             */\n        });\n    \n        // 负责将文件切片。\n        function CuteFile( file, chunkSize ) {\n            var pending = [],\n                blob = file.source,\n                total = blob.size,\n                chunks = chunkSize ? Math.ceil( total / chunkSize ) : 1,\n                start = 0,\n                index = 0,\n                len;\n    \n            while ( index < chunks ) {\n                len = Math.min( chunkSize, total - start );\n    \n                pending.push({\n                    file: file,\n                    start: start,\n                    end: chunkSize ? (start + len) : total,\n                    total: total,\n                    chunks: chunks,\n                    chunk: index++\n                });\n                start += len;\n            }\n    \n            file.blocks = pending.concat();\n            file.remaning = pending.length;\n    \n            return {\n                file: file,\n    \n                has: function() {\n                    return !!pending.length;\n                },\n    \n                fetch: function() {\n                    return pending.shift();\n                }\n            };\n        }\n    \n        Uploader.register({\n            'start-upload': 'start',\n            'stop-upload': 'stop',\n            'skip-file': 'skipFile',\n            'is-in-progress': 'isInProgress'\n        }, {\n    \n            init: function() {\n                var owner = this.owner;\n    \n                this.runing = false;\n    \n                // 记录当前正在传的数据，跟threads相关\n                this.pool = [];\n    \n                // 缓存即将上传的文件。\n                this.pending = [];\n    \n                // 跟踪还有多少分片没有完成上传。\n                this.remaning = 0;\n                this.__tick = Base.bindFn( this._tick, this );\n    \n                owner.on( 'uploadComplete', function( file ) {\n                    // 把其他块取消了。\n                    file.blocks && $.each( file.blocks, function( _, v ) {\n                        v.transport && (v.transport.abort(), v.transport.destroy());\n                        delete v.transport;\n                    });\n    \n                    delete file.blocks;\n                    delete file.remaning;\n                });\n            },\n    \n            /**\n             * @event startUpload\n             * @description 当开始上传流程时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * 开始上传。此方法可以从初始状态调用开始上传流程，也可以从暂停状态调用，继续上传流程。\n             * @grammar upload() => undefined\n             * @method upload\n             * @for  Uploader\n             */\n            start: function() {\n                var me = this;\n    \n                // 移出invalid的文件\n                $.each( me.request( 'get-files', Status.INVALID ), function() {\n                    me.request( 'remove-file', this );\n                });\n    \n                if ( me.runing ) {\n                    return;\n                }\n    \n                me.runing = true;\n    \n                // 如果有暂停的，则续传\n                $.each( me.pool, function( _, v ) {\n                    var file = v.file;\n    \n                    if ( file.getStatus() === Status.INTERRUPT ) {\n                        file.setStatus( Status.PROGRESS );\n                        me._trigged = false;\n                        v.transport && v.transport.send();\n                    }\n                });\n    \n                me._trigged = false;\n                me.owner.trigger('startUpload');\n                Base.nextTick( me.__tick );\n            },\n    \n            /**\n             * @event stopUpload\n             * @description 当开始上传流程暂停时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * 暂停上传。第一个参数为是否中断上传当前正在上传的文件。\n             * @grammar stop() => undefined\n             * @grammar stop( true ) => undefined\n             * @method stop\n             * @for  Uploader\n             */\n            stop: function( interrupt ) {\n                var me = this;\n    \n                if ( me.runing === false ) {\n                    return;\n                }\n    \n                me.runing = false;\n    \n                interrupt && $.each( me.pool, function( _, v ) {\n                    v.transport && v.transport.abort();\n                    v.file.setStatus( Status.INTERRUPT );\n                });\n    \n                me.owner.trigger('stopUpload');\n            },\n    \n            /**\n             * 判断`Uplaode`r是否正在上传中。\n             * @grammar isInProgress() => Boolean\n             * @method isInProgress\n             * @for  Uploader\n             */\n            isInProgress: function() {\n                return !!this.runing;\n            },\n    \n            getStats: function() {\n                return this.request('get-stats');\n            },\n    \n            /**\n             * 掉过一个文件上传，直接标记指定文件为已上传状态。\n             * @grammar skipFile( file ) => undefined\n             * @method skipFile\n             * @for  Uploader\n             */\n            skipFile: function( file, status ) {\n                file = this.request( 'get-file', file );\n    \n                file.setStatus( status || Status.COMPLETE );\n                file.skipped = true;\n    \n                // 如果正在上传。\n                file.blocks && $.each( file.blocks, function( _, v ) {\n                    var _tr = v.transport;\n    \n                    if ( _tr ) {\n                        _tr.abort();\n                        _tr.destroy();\n                        delete v.transport;\n                    }\n                });\n    \n                this.owner.trigger( 'uploadSkip', file );\n            },\n    \n            /**\n             * @event uploadFinished\n             * @description 当所有文件上传结束时触发。\n             * @for  Uploader\n             */\n            _tick: function() {\n                var me = this,\n                    opts = me.options,\n                    fn, val;\n    \n                // 上一个promise还没有结束，则等待完成后再执行。\n                if ( me._promise ) {\n                    return me._promise.always( me.__tick );\n                }\n    \n                // 还有位置，且还有文件要处理的话。\n                if ( me.pool.length < opts.threads && (val = me._nextBlock()) ) {\n                    me._trigged = false;\n    \n                    fn = function( val ) {\n                        me._promise = null;\n    \n                        // 有可能是reject过来的，所以要检测val的类型。\n                        val && val.file && me._startSend( val );\n                        Base.nextTick( me.__tick );\n                    };\n    \n                    me._promise = isPromise( val ) ? val.always( fn ) : fn( val );\n    \n                // 没有要上传的了，且没有正在传输的了。\n                } else if ( !me.remaning && !me.getStats().numOfQueue ) {\n                    me.runing = false;\n    \n                    me._trigged || Base.nextTick(function() {\n                        me.owner.trigger('uploadFinished');\n                    });\n                    me._trigged = true;\n                }\n            },\n    \n            _nextBlock: function() {\n                var me = this,\n                    act = me._act,\n                    opts = me.options,\n                    next, done;\n    \n                // 如果当前文件还有没有需要传输的，则直接返回剩下的。\n                if ( act && act.has() &&\n                        act.file.getStatus() === Status.PROGRESS ) {\n    \n                    // 是否提前准备下一个文件\n                    if ( opts.prepareNextFile && !me.pending.length ) {\n                        me._prepareNextFile();\n                    }\n    \n                    return act.fetch();\n    \n                // 否则，如果正在运行，则准备下一个文件，并等待完成后返回下个分片。\n                } else if ( me.runing ) {\n    \n                    // 如果缓存中有，则直接在缓存中取，没有则去queue中取。\n                    if ( !me.pending.length && me.getStats().numOfQueue ) {\n                        me._prepareNextFile();\n                    }\n    \n                    next = me.pending.shift();\n                    done = function( file ) {\n                        if ( !file ) {\n                            return null;\n                        }\n    \n                        act = CuteFile( file, opts.chunked ? opts.chunkSize : 0 );\n                        me._act = act;\n                        return act.fetch();\n                    };\n    \n                    // 文件可能还在prepare中，也有可能已经完全准备好了。\n                    return isPromise( next ) ?\n                            next[ next.pipe ? 'pipe' : 'then']( done ) :\n                            done( next );\n                }\n            },\n    \n    \n            /**\n             * @event uploadStart\n             * @param {File} file File对象\n             * @description 某个文件开始上传前触发，一个文件只会触发一次。\n             * @for  Uploader\n             */\n            _prepareNextFile: function() {\n                var me = this,\n                    file = me.request('fetch-file'),\n                    pending = me.pending,\n                    promise;\n    \n                if ( file ) {\n                    promise = me.request( 'before-send-file', file, function() {\n    \n                        // 有可能文件被skip掉了。文件被skip掉后，状态坑定不是Queued.\n                        if ( file.getStatus() === Status.QUEUED ) {\n                            me.owner.trigger( 'uploadStart', file );\n                            file.setStatus( Status.PROGRESS );\n                            return file;\n                        }\n    \n                        return me._finishFile( file );\n                    });\n    \n                    // 如果还在pending中，则替换成文件本身。\n                    promise.done(function() {\n                        var idx = $.inArray( promise, pending );\n    \n                        ~idx && pending.splice( idx, 1, file );\n                    });\n    \n                    // befeore-send-file的钩子就有错误发生。\n                    promise.fail(function( reason ) {\n                        file.setStatus( Status.ERROR, reason );\n                        me.owner.trigger( 'uploadError', file, reason );\n                        me.owner.trigger( 'uploadComplete', file );\n                    });\n    \n                    pending.push( promise );\n                }\n            },\n    \n            // 让出位置了，可以让其他分片开始上传\n            _popBlock: function( block ) {\n                var idx = $.inArray( block, this.pool );\n    \n                this.pool.splice( idx, 1 );\n                block.file.remaning--;\n                this.remaning--;\n            },\n    \n            // 开始上传，可以被掉过。如果promise被reject了，则表示跳过此分片。\n            _startSend: function( block ) {\n                var me = this,\n                    file = block.file,\n                    promise;\n    \n                me.pool.push( block );\n                me.remaning++;\n    \n                // 如果没有分片，则直接使用原始的。\n                // 不会丢失content-type信息。\n                block.blob = block.chunks === 1 ? file.source :\n                        file.source.slice( block.start, block.end );\n    \n                // hook, 每个分片发送之前可能要做些异步的事情。\n                promise = me.request( 'before-send', block, function() {\n    \n                    // 有可能文件已经上传出错了，所以不需要再传输了。\n                    if ( file.getStatus() === Status.PROGRESS ) {\n                        me._doSend( block );\n                    } else {\n                        me._popBlock( block );\n                        Base.nextTick( me.__tick );\n                    }\n                });\n    \n                // 如果为fail了，则跳过此分片。\n                promise.fail(function() {\n                    if ( file.remaning === 1 ) {\n                        me._finishFile( file ).always(function() {\n                            block.percentage = 1;\n                            me._popBlock( block );\n                            me.owner.trigger( 'uploadComplete', file );\n                            Base.nextTick( me.__tick );\n                        });\n                    } else {\n                        block.percentage = 1;\n                        me._popBlock( block );\n                        Base.nextTick( me.__tick );\n                    }\n                });\n            },\n    \n    \n            /**\n             * @event uploadBeforeSend\n             * @param {Object} object\n             * @param {Object} data 默认的上传参数，可以扩展此对象来控制上传参数。\n             * @description 当某个文件的分块在发送前触发，主要用来询问是否要添加附带参数，大文件在开起分片上传的前提下此事件可能会触发多次。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadAccept\n             * @param {Object} object\n             * @param {Object} ret 服务端的返回数据，json格式，如果服务端不是json格式，从ret._raw中取数据，自行解析。\n             * @description 当某个文件上传到服务端响应后，会派送此事件来询问服务端响应是否有效。如果此事件handler返回值为`false`, 则此文件将派送`server`类型的`uploadError`事件。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadProgress\n             * @param {File} file File对象\n             * @param {Number} percentage 上传进度\n             * @description 上传过程中触发，携带上传进度。\n             * @for  Uploader\n             */\n    \n    \n            /**\n             * @event uploadError\n             * @param {File} file File对象\n             * @param {String} reason 出错的code\n             * @description 当文件上传出错时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadSuccess\n             * @param {File} file File对象\n             * @param {Object} response 服务端返回的数据\n             * @description 当文件上传成功时触发。\n             * @for  Uploader\n             */\n    \n            /**\n             * @event uploadComplete\n             * @param {File} [file] File对象\n             * @description 不管成功或者失败，文件上传完成时触发。\n             * @for  Uploader\n             */\n    \n            // 做上传操作。\n            _doSend: function( block ) {\n                var me = this,\n                    owner = me.owner,\n                    opts = me.options,\n                    file = block.file,\n                    tr = new Transport( opts ),\n                    data = $.extend({}, opts.formData ),\n                    headers = $.extend({}, opts.headers ),\n                    requestAccept, ret;\n    \n                block.transport = tr;\n    \n                tr.on( 'destroy', function() {\n                    delete block.transport;\n                    me._popBlock( block );\n                    Base.nextTick( me.__tick );\n                });\n    \n                // 广播上传进度。以文件为单位。\n                tr.on( 'progress', function( percentage ) {\n                    var totalPercent = 0,\n                        uploaded = 0;\n    \n                    // 可能没有abort掉，progress还是执行进来了。\n                    // if ( !file.blocks ) {\n                    //     return;\n                    // }\n    \n                    totalPercent = block.percentage = percentage;\n    \n                    if ( block.chunks > 1 ) {    // 计算文件的整体速度。\n                        $.each( file.blocks, function( _, v ) {\n                            uploaded += (v.percentage || 0) * (v.end - v.start);\n                        });\n    \n                        totalPercent = uploaded / file.size;\n                    }\n    \n                    owner.trigger( 'uploadProgress', file, totalPercent || 0 );\n                });\n    \n                // 用来询问，是否返回的结果是有错误的。\n                requestAccept = function( reject ) {\n                    var fn;\n    \n                    ret = tr.getResponseAsJson() || {};\n                    ret._raw = tr.getResponse();\n                    fn = function( value ) {\n                        reject = value;\n                    };\n    \n                    // 服务端响应了，不代表成功了，询问是否响应正确。\n                    if ( !owner.trigger( 'uploadAccept', block, ret, fn ) ) {\n                        reject = reject || 'server';\n                    }\n    \n                    return reject;\n                };\n    \n                // 尝试重试，然后广播文件上传出错。\n                tr.on( 'error', function( type, flag ) {\n                    block.retried = block.retried || 0;\n    \n                    // 自动重试\n                    if ( block.chunks > 1 && ~'http,abort'.indexOf( type ) &&\n                            block.retried < opts.chunkRetry ) {\n    \n                        block.retried++;\n                        tr.send();\n    \n                    } else {\n    \n                        // http status 500 ~ 600\n                        if ( !flag && type === 'server' ) {\n                            type = requestAccept( type );\n                        }\n    \n                        file.setStatus( Status.ERROR, type );\n                        owner.trigger( 'uploadError', file, type );\n                        owner.trigger( 'uploadComplete', file );\n                    }\n                });\n    \n                // 上传成功\n                tr.on( 'load', function() {\n                    var reason;\n    \n                    // 如果非预期，转向上传出错。\n                    if ( (reason = requestAccept()) ) {\n                        tr.trigger( 'error', reason, true );\n                        return;\n                    }\n    \n                    // 全部上传完成。\n                    if ( file.remaning === 1 ) {\n                        me._finishFile( file, ret );\n                    } else {\n                        tr.destroy();\n                    }\n                });\n    \n                // 配置默认的上传字段。\n                data = $.extend( data, {\n                    id: file.id,\n                    name: file.name,\n                    type: file.type,\n                    lastModifiedDate: file.lastModifiedDate,\n                    size: file.size\n                });\n    \n                block.chunks > 1 && $.extend( data, {\n                    chunks: block.chunks,\n                    chunk: block.chunk\n                });\n    \n                // 在发送之间可以添加字段什么的。。。\n                // 如果默认的字段不够使用，可以通过监听此事件来扩展\n                owner.trigger( 'uploadBeforeSend', block, data, headers );\n    \n                // 开始发送。\n                tr.appendBlob( opts.fileVal, block.blob, file.name );\n                tr.append( data );\n                tr.setRequestHeader( headers );\n                tr.send();\n            },\n    \n            // 完成上传。\n            _finishFile: function( file, ret, hds ) {\n                var owner = this.owner;\n    \n                return owner\n                        .request( 'after-send-file', arguments, function() {\n                            file.setStatus( Status.COMPLETE );\n                            owner.trigger( 'uploadSuccess', file, ret, hds );\n                        })\n                        .fail(function( reason ) {\n    \n                            // 如果外部已经标记为invalid什么的，不再改状态。\n                            if ( file.getStatus() === Status.PROGRESS ) {\n                                file.setStatus( Status.ERROR, reason );\n                            }\n    \n                            owner.trigger( 'uploadError', file, reason );\n                        })\n                        .always(function() {\n                            owner.trigger( 'uploadComplete', file );\n                        });\n            }\n    \n        });\n    });\n    /**\n     * @fileOverview 各种验证，包括文件总大小是否超出、单文件是否超出和文件是否重复。\n     */\n    \n    define('widgets/validator',[\n        'base',\n        'uploader',\n        'file',\n        'widgets/widget'\n    ], function( Base, Uploader, WUFile ) {\n    \n        var $ = Base.$,\n            validators = {},\n            api;\n    \n        /**\n         * @event error\n         * @param {String} type 错误类型。\n         * @description 当validate不通过时，会以派送错误事件的形式通知调用者。通过`upload.on('error', handler)`可以捕获到此类错误，目前有以下错误会在特定的情况下派送错来。\n         *\n         * * `Q_EXCEED_NUM_LIMIT` 在设置了`fileNumLimit`且尝试给`uploader`添加的文件数量超出这个值时派送。\n         * * `Q_EXCEED_SIZE_LIMIT` 在设置了`Q_EXCEED_SIZE_LIMIT`且尝试给`uploader`添加的文件总大小超出这个值时派送。\n         * @for  Uploader\n         */\n    \n        // 暴露给外面的api\n        api = {\n    \n            // 添加验证器\n            addValidator: function( type, cb ) {\n                validators[ type ] = cb;\n            },\n    \n            // 移除验证器\n            removeValidator: function( type ) {\n                delete validators[ type ];\n            }\n        };\n    \n        // 在Uploader初始化的时候启动Validators的初始化\n        Uploader.register({\n            init: function() {\n                var me = this;\n                $.each( validators, function() {\n                    this.call( me.owner );\n                });\n            }\n        });\n    \n        /**\n         * @property {int} [fileNumLimit=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 验证文件总数量, 超出则不允许加入队列。\n         */\n        api.addValidator( 'fileNumLimit', function() {\n            var uploader = this,\n                opts = uploader.options,\n                count = 0,\n                max = opts.fileNumLimit >> 0,\n                flag = true;\n    \n            if ( !max ) {\n                return;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n    \n                if ( count >= max && flag ) {\n                    flag = false;\n                    this.trigger( 'error', 'Q_EXCEED_NUM_LIMIT', max, file );\n                    setTimeout(function() {\n                        flag = true;\n                    }, 1 );\n                }\n    \n                return count >= max ? false : true;\n            });\n    \n            uploader.on( 'fileQueued', function() {\n                count++;\n            });\n    \n            uploader.on( 'fileDequeued', function() {\n                count--;\n            });\n    \n            uploader.on( 'uploadFinished', function() {\n                count = 0;\n            });\n        });\n    \n    \n        /**\n         * @property {int} [fileSizeLimit=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 验证文件总大小是否超出限制, 超出则不允许加入队列。\n         */\n        api.addValidator( 'fileSizeLimit', function() {\n            var uploader = this,\n                opts = uploader.options,\n                count = 0,\n                max = opts.fileSizeLimit >> 0,\n                flag = true;\n    \n            if ( !max ) {\n                return;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n                var invalid = count + file.size > max;\n    \n                if ( invalid && flag ) {\n                    flag = false;\n                    this.trigger( 'error', 'Q_EXCEED_SIZE_LIMIT', max, file );\n                    setTimeout(function() {\n                        flag = true;\n                    }, 1 );\n                }\n    \n                return invalid ? false : true;\n            });\n    \n            uploader.on( 'fileQueued', function( file ) {\n                count += file.size;\n            });\n    \n            uploader.on( 'fileDequeued', function( file ) {\n                count -= file.size;\n            });\n    \n            uploader.on( 'uploadFinished', function() {\n                count = 0;\n            });\n        });\n    \n        /**\n         * @property {int} [fileSingleSizeLimit=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 验证单个文件大小是否超出限制, 超出则不允许加入队列。\n         */\n        api.addValidator( 'fileSingleSizeLimit', function() {\n            var uploader = this,\n                opts = uploader.options,\n                max = opts.fileSingleSizeLimit;\n    \n            if ( !max ) {\n                return;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n    \n                if ( file.size > max ) {\n                    file.setStatus( WUFile.Status.INVALID, 'exceed_size' );\n                    this.trigger( 'error', 'F_EXCEED_SIZE', file );\n                    return false;\n                }\n    \n            });\n    \n        });\n    \n        /**\n         * @property {int} [duplicate=undefined]\n         * @namespace options\n         * @for Uploader\n         * @description 去重， 根据文件名字、文件大小和最后修改时间来生成hash Key.\n         */\n        api.addValidator( 'duplicate', function() {\n            var uploader = this,\n                opts = uploader.options,\n                mapping = {};\n    \n            if ( opts.duplicate ) {\n                return;\n            }\n    \n            function hashString( str ) {\n                var hash = 0,\n                    i = 0,\n                    len = str.length,\n                    _char;\n    \n                for ( ; i < len; i++ ) {\n                    _char = str.charCodeAt( i );\n                    hash = _char + (hash << 6) + (hash << 16) - hash;\n                }\n    \n                return hash;\n            }\n    \n            uploader.on( 'beforeFileQueued', function( file ) {\n                var hash = file.__hash || (file.__hash = hashString( file.name +\n                        file.size + file.lastModifiedDate ));\n    \n                // 已经重复了\n                if ( mapping[ hash ] ) {\n                    this.trigger( 'error', 'F_DUPLICATE', file );\n                    return false;\n                }\n            });\n    \n            uploader.on( 'fileQueued', function( file ) {\n                var hash = file.__hash;\n    \n                hash && (mapping[ hash ] = true);\n            });\n    \n            uploader.on( 'fileDequeued', function( file ) {\n                var hash = file.__hash;\n    \n                hash && (delete mapping[ hash ]);\n            });\n        });\n    \n        return api;\n    });\n    \n    /**\n     * @fileOverview Runtime管理器，负责Runtime的选择, 连接\n     */\n    define('runtime/compbase',[],function() {\n    \n        function CompBase( owner, runtime ) {\n    \n            this.owner = owner;\n            this.options = owner.options;\n    \n            this.getRuntime = function() {\n                return runtime;\n            };\n    \n            this.getRuid = function() {\n                return runtime.uid;\n            };\n    \n            this.trigger = function() {\n                return owner.trigger.apply( owner, arguments );\n            };\n        }\n    \n        return CompBase;\n    });\n    /**\n     * @fileOverview Html5Runtime\n     */\n    define('runtime/html5/runtime',[\n        'base',\n        'runtime/runtime',\n        'runtime/compbase'\n    ], function( Base, Runtime, CompBase ) {\n    \n        var type = 'html5',\n            components = {};\n    \n        function Html5Runtime() {\n            var pool = {},\n                me = this,\n                destory = this.destory;\n    \n            Runtime.apply( me, arguments );\n            me.type = type;\n    \n    \n            // 这个方法的调用者，实际上是RuntimeClient\n            me.exec = function( comp, fn/*, args...*/) {\n                var client = this,\n                    uid = client.uid,\n                    args = Base.slice( arguments, 2 ),\n                    instance;\n    \n                if ( components[ comp ] ) {\n                    instance = pool[ uid ] = pool[ uid ] ||\n                            new components[ comp ]( client, me );\n    \n                    if ( instance[ fn ] ) {\n                        return instance[ fn ].apply( instance, args );\n                    }\n                }\n            };\n    \n            me.destory = function() {\n                // @todo 删除池子中的所有实例\n                return destory && destory.apply( this, arguments );\n            };\n        }\n    \n        Base.inherits( Runtime, {\n            constructor: Html5Runtime,\n    \n            // 不需要连接其他程序，直接执行callback\n            init: function() {\n                var me = this;\n                setTimeout(function() {\n                    me.trigger('ready');\n                }, 1 );\n            }\n    \n        });\n    \n        // 注册Components\n        Html5Runtime.register = function( name, component ) {\n            var klass = components[ name ] = Base.inherits( CompBase, component );\n            return klass;\n        };\n    \n        // 注册html5运行时。\n        // 只有在支持的前提下注册。\n        if ( window.Blob && window.FileReader && window.DataView ) {\n            Runtime.addRuntime( type, Html5Runtime );\n        }\n    \n        return Html5Runtime;\n    });\n    /**\n     * @fileOverview Blob Html实现\n     */\n    define('runtime/html5/blob',[\n        'runtime/html5/runtime',\n        'lib/blob'\n    ], function( Html5Runtime, Blob ) {\n    \n        return Html5Runtime.register( 'Blob', {\n            slice: function( start, end ) {\n                var blob = this.owner.source,\n                    slice = blob.slice || blob.webkitSlice || blob.mozSlice;\n    \n                blob = slice.call( blob, start, end );\n    \n                return new Blob( this.getRuid(), blob );\n            }\n        });\n    });\n    /**\n     * @fileOverview FilePaste\n     */\n    define('runtime/html5/dnd',[\n        'base',\n        'runtime/html5/runtime',\n        'lib/file'\n    ], function( Base, Html5Runtime, File ) {\n    \n        var $ = Base.$,\n            prefix = 'webuploader-dnd-';\n    \n        return Html5Runtime.register( 'DragAndDrop', {\n            init: function() {\n                var elem = this.elem = this.options.container;\n    \n                this.dragEnterHandler = Base.bindFn( this._dragEnterHandler, this );\n                this.dragOverHandler = Base.bindFn( this._dragOverHandler, this );\n                this.dragLeaveHandler = Base.bindFn( this._dragLeaveHandler, this );\n                this.dropHandler = Base.bindFn( this._dropHandler, this );\n                this.dndOver = false;\n    \n                elem.on( 'dragenter', this.dragEnterHandler );\n                elem.on( 'dragover', this.dragOverHandler );\n                elem.on( 'dragleave', this.dragLeaveHandler );\n                elem.on( 'drop', this.dropHandler );\n    \n                if ( this.options.disableGlobalDnd ) {\n                    $( document ).on( 'dragover', this.dragOverHandler );\n                    $( document ).on( 'drop', this.dropHandler );\n                }\n            },\n    \n            _dragEnterHandler: function( e ) {\n                var me = this,\n                    denied = me._denied || false,\n                    items;\n    \n                e = e.originalEvent || e;\n    \n                if ( !me.dndOver ) {\n                    me.dndOver = true;\n    \n                    // 注意只有 chrome 支持。\n                    items = e.dataTransfer.items;\n    \n                    if ( items && items.length ) {\n                        me._denied = denied = !me.trigger( 'accept', items );\n                    }\n    \n                    me.elem.addClass( prefix + 'over' );\n                    me.elem[ denied ? 'addClass' :\n                            'removeClass' ]( prefix + 'denied' );\n                }\n    \n    \n                e.dataTransfer.dropEffect = denied ? 'none' : 'copy';\n    \n                return false;\n            },\n    \n            _dragOverHandler: function( e ) {\n                // 只处理框内的。\n                var parentElem = this.elem.parent().get( 0 );\n                if ( parentElem && !$.contains( parentElem, e.currentTarget ) ) {\n                    return false;\n                }\n    \n                clearTimeout( this._leaveTimer );\n                this._dragEnterHandler.call( this, e );\n    \n                return false;\n            },\n    \n            _dragLeaveHandler: function() {\n                var me = this,\n                    handler;\n    \n                handler = function() {\n                    me.dndOver = false;\n                    me.elem.removeClass( prefix + 'over ' + prefix + 'denied' );\n                };\n    \n                clearTimeout( me._leaveTimer );\n                me._leaveTimer = setTimeout( handler, 100 );\n                return false;\n            },\n    \n            _dropHandler: function( e ) {\n                var me = this,\n                    ruid = me.getRuid(),\n                    parentElem = me.elem.parent().get( 0 );\n    \n                // 只处理框内的。\n                if ( parentElem && !$.contains( parentElem, e.currentTarget ) ) {\n                    return false;\n                }\n    \n                me._getTansferFiles( e, function( results ) {\n                    me.trigger( 'drop', $.map( results, function( file ) {\n                        return new File( ruid, file );\n                    }) );\n                });\n    \n                me.dndOver = false;\n                me.elem.removeClass( prefix + 'over' );\n                return false;\n            },\n    \n            // 如果传入 callback 则去查看文件夹，否则只管当前文件夹。\n            _getTansferFiles: function( e, callback ) {\n                var results  = [],\n                    promises = [],\n                    items, files, dataTransfer, file, item, i, len, canAccessFolder;\n    \n                e = e.originalEvent || e;\n    \n                dataTransfer = e.dataTransfer;\n                items = dataTransfer.items;\n                files = dataTransfer.files;\n    \n                canAccessFolder = !!(items && items[ 0 ].webkitGetAsEntry);\n    \n                for ( i = 0, len = files.length; i < len; i++ ) {\n                    file = files[ i ];\n                    item = items && items[ i ];\n    \n                    if ( canAccessFolder && item.webkitGetAsEntry().isDirectory ) {\n    \n                        promises.push( this._traverseDirectoryTree(\n                                item.webkitGetAsEntry(), results ) );\n                    } else {\n                        results.push( file );\n                    }\n                }\n    \n                Base.when.apply( Base, promises ).done(function() {\n    \n                    if ( !results.length ) {\n                        return;\n                    }\n    \n                    callback( results );\n                });\n            },\n    \n            _traverseDirectoryTree: function( entry, results ) {\n                var deferred = Base.Deferred(),\n                    me = this;\n    \n                if ( entry.isFile ) {\n                    entry.file(function( file ) {\n                        results.push( file );\n                        deferred.resolve();\n                    });\n                } else if ( entry.isDirectory ) {\n                    entry.createReader().readEntries(function( entries ) {\n                        var len = entries.length,\n                            promises = [],\n                            arr = [],    // 为了保证顺序。\n                            i;\n    \n                        for ( i = 0; i < len; i++ ) {\n                            promises.push( me._traverseDirectoryTree(\n                                    entries[ i ], arr ) );\n                        }\n    \n                        Base.when.apply( Base, promises ).then(function() {\n                            results.push.apply( results, arr );\n                            deferred.resolve();\n                        }, deferred.reject );\n                    });\n                }\n    \n                return deferred.promise();\n            },\n    \n            destroy: function() {\n                var elem = this.elem;\n    \n                elem.off( 'dragenter', this.dragEnterHandler );\n                elem.off( 'dragover', this.dragEnterHandler );\n                elem.off( 'dragleave', this.dragLeaveHandler );\n                elem.off( 'drop', this.dropHandler );\n    \n                if ( this.options.disableGlobalDnd ) {\n                    $( document ).off( 'dragover', this.dragOverHandler );\n                    $( document ).off( 'drop', this.dropHandler );\n                }\n            }\n        });\n    });\n    \n    /**\n     * @fileOverview FilePaste\n     */\n    define('runtime/html5/filepaste',[\n        'base',\n        'runtime/html5/runtime',\n        'lib/file'\n    ], function( Base, Html5Runtime, File ) {\n    \n        return Html5Runtime.register( 'FilePaste', {\n            init: function() {\n                var opts = this.options,\n                    elem = this.elem = opts.container,\n                    accept = '.*',\n                    arr, i, len, item;\n    \n                // accetp的mimeTypes中生成匹配正则。\n                if ( opts.accept ) {\n                    arr = [];\n    \n                    for ( i = 0, len = opts.accept.length; i < len; i++ ) {\n                        item = opts.accept[ i ].mimeTypes;\n                        item && arr.push( item );\n                    }\n    \n                    if ( arr.length ) {\n                        accept = arr.join(',');\n                        accept = accept.replace( /,/g, '|' ).replace( /\\*/g, '.*' );\n                    }\n                }\n                this.accept = accept = new RegExp( accept, 'i' );\n                this.hander = Base.bindFn( this._pasteHander, this );\n                elem.on( 'paste', this.hander );\n            },\n    \n            _pasteHander: function( e ) {\n                var allowed = [],\n                    ruid = this.getRuid(),\n                    items, item, blob, i, len;\n    \n                e = e.originalEvent || e;\n                items = e.clipboardData.items;\n    \n                for ( i = 0, len = items.length; i < len; i++ ) {\n                    item = items[ i ];\n    \n                    if ( item.kind !== 'file' || !(blob = item.getAsFile()) ) {\n                        continue;\n                    }\n    \n                    allowed.push( new File( ruid, blob ) );\n                }\n    \n                if ( allowed.length ) {\n                    // 不阻止非文件粘贴（文字粘贴）的事件冒泡\n                    e.preventDefault();\n                    e.stopPropagation();\n                    this.trigger( 'paste', allowed );\n                }\n            },\n    \n            destroy: function() {\n                this.elem.off( 'paste', this.hander );\n            }\n        });\n    });\n    \n    /**\n     * @fileOverview FilePicker\n     */\n    define('runtime/html5/filepicker',[\n        'base',\n        'runtime/html5/runtime'\n    ], function( Base, Html5Runtime ) {\n    \n        var $ = Base.$;\n    \n        return Html5Runtime.register( 'FilePicker', {\n            init: function() {\n                var container = this.getRuntime().getContainer(),\n                    me = this,\n                    owner = me.owner,\n                    opts = me.options,\n                    lable = $( document.createElement('label') ),\n                    input = $( document.createElement('input') ),\n                    arr, i, len, mouseHandler;\n    \n                input.attr( 'type', 'file' );\n                input.attr( 'name', opts.name );\n                input.addClass('webuploader-element-invisible');\n    \n                lable.on( 'click', function() {\n                    input.trigger('click');\n                });\n    \n                lable.css({\n                    opacity: 0,\n                    width: '100%',\n                    height: '100%',\n                    display: 'block',\n                    cursor: 'pointer',\n                    background: '#ffffff'\n                });\n    \n                if ( opts.multiple ) {\n                    input.attr( 'multiple', 'multiple' );\n                }\n    \n                // @todo Firefox不支持单独指定后缀\n                if ( opts.accept && opts.accept.length > 0 ) {\n                    arr = [];\n    \n                    for ( i = 0, len = opts.accept.length; i < len; i++ ) {\n                        arr.push( opts.accept[ i ].mimeTypes );\n                    }\n    \n                    input.attr( 'accept', arr.join(',') );\n                }\n    \n                container.append( input );\n                container.append( lable );\n    \n                mouseHandler = function( e ) {\n                    owner.trigger( e.type );\n                };\n    \n                input.on( 'change', function( e ) {\n                    var fn = arguments.callee,\n                        clone;\n    \n                    me.files = e.target.files;\n    \n                    // reset input\n                    clone = this.cloneNode( true );\n                    this.parentNode.replaceChild( clone, this );\n    \n                    input.off();\n                    input = $( clone ).on( 'change', fn )\n                            .on( 'mouseenter mouseleave', mouseHandler );\n    \n                    owner.trigger('change');\n                });\n    \n                lable.on( 'mouseenter mouseleave', mouseHandler );\n    \n            },\n    \n    \n            getFiles: function() {\n                return this.files;\n            },\n    \n            destroy: function() {\n                // todo\n            }\n        });\n    });\n    /**\n     * @fileOverview Transport\n     * @todo 支持chunked传输，优势：\n     * 可以将大文件分成小块，挨个传输，可以提高大文件成功率，当失败的时候，也只需要重传那小部分，\n     * 而不需要重头再传一次。另外断点续传也需要用chunked方式。\n     */\n    define('runtime/html5/transport',[\n        'base',\n        'runtime/html5/runtime'\n    ], function( Base, Html5Runtime ) {\n    \n        var noop = Base.noop,\n            $ = Base.$;\n    \n        return Html5Runtime.register( 'Transport', {\n            init: function() {\n                this._status = 0;\n                this._response = null;\n            },\n    \n            send: function() {\n                var owner = this.owner,\n                    opts = this.options,\n                    xhr = this._initAjax(),\n                    blob = owner._blob,\n                    server = opts.server,\n                    formData, binary, fr;\n    \n                if ( opts.sendAsBinary ) {\n                    server += (/\\?/.test( server ) ? '&' : '?') +\n                            $.param( owner._formData );\n    \n                    binary = blob.getSource();\n                } else {\n                    formData = new FormData();\n                    $.each( owner._formData, function( k, v ) {\n                        formData.append( k, v );\n                    });\n    \n                    formData.append( opts.fileVal, blob.getSource(),\n                            opts.filename || owner._formData.name || '' );\n                }\n    \n                if ( opts.withCredentials && 'withCredentials' in xhr ) {\n                    xhr.open( opts.method, server, true );\n                    xhr.withCredentials = true;\n                } else {\n                    xhr.open( opts.method, server );\n                }\n    \n                this._setRequestHeader( xhr, opts.headers );\n    \n                if ( binary ) {\n                    xhr.overrideMimeType('application/octet-stream');\n    \n                    // android直接发送blob会导致服务端接收到的是空文件。\n                    // bug详情。\n                    // https://code.google.com/p/android/issues/detail?id=39882\n                    // 所以先用fileReader读取出来再通过arraybuffer的方式发送。\n                    if ( Base.os.android ) {\n                        fr = new FileReader();\n    \n                        fr.onload = function() {\n                            xhr.send( this.result );\n                            fr = fr.onload = null;\n                        };\n    \n                        fr.readAsArrayBuffer( binary );\n                    } else {\n                        xhr.send( binary );\n                    }\n                } else {\n                    xhr.send( formData );\n                }\n            },\n    \n            getResponse: function() {\n                return this._response;\n            },\n    \n            getResponseAsJson: function() {\n                return this._parseJson( this._response );\n            },\n    \n            getStatus: function() {\n                return this._status;\n            },\n    \n            abort: function() {\n                var xhr = this._xhr;\n    \n                if ( xhr ) {\n                    xhr.upload.onprogress = noop;\n                    xhr.onreadystatechange = noop;\n                    xhr.abort();\n    \n                    this._xhr = xhr = null;\n                }\n            },\n    \n            destroy: function() {\n                this.abort();\n            },\n    \n            _initAjax: function() {\n                var me = this,\n                    xhr = new XMLHttpRequest(),\n                    opts = this.options;\n    \n                if ( opts.withCredentials && !('withCredentials' in xhr) &&\n                        typeof XDomainRequest !== 'undefined' ) {\n                    xhr = new XDomainRequest();\n                }\n    \n                xhr.upload.onprogress = function( e ) {\n                    var percentage = 0;\n    \n                    if ( e.lengthComputable ) {\n                        percentage = e.loaded / e.total;\n                    }\n    \n                    return me.trigger( 'progress', percentage );\n                };\n    \n                xhr.onreadystatechange = function() {\n    \n                    if ( xhr.readyState !== 4 ) {\n                        return;\n                    }\n    \n                    xhr.upload.onprogress = noop;\n                    xhr.onreadystatechange = noop;\n                    me._xhr = null;\n                    me._status = xhr.status;\n    \n                    if ( xhr.status >= 200 && xhr.status < 300 ) {\n                        me._response = xhr.responseText;\n                        return me.trigger('load');\n                    } else if ( xhr.status >= 500 && xhr.status < 600 ) {\n                        me._response = xhr.responseText;\n                        return me.trigger( 'error', 'server' );\n                    }\n    \n    \n                    return me.trigger( 'error', me._status ? 'http' : 'abort' );\n                };\n    \n                me._xhr = xhr;\n                return xhr;\n            },\n    \n            _setRequestHeader: function( xhr, headers ) {\n                $.each( headers, function( key, val ) {\n                    xhr.setRequestHeader( key, val );\n                });\n            },\n    \n            _parseJson: function( str ) {\n                var json;\n    \n                try {\n                    json = JSON.parse( str );\n                } catch ( ex ) {\n                    json = {};\n                }\n    \n                return json;\n            }\n        });\n    });\n    /**\n     * @fileOverview FlashRuntime\n     */\n    define('runtime/flash/runtime',[\n        'base',\n        'runtime/runtime',\n        'runtime/compbase'\n    ], function( Base, Runtime, CompBase ) {\n    \n        var $ = Base.$,\n            type = 'flash',\n            components = {};\n    \n    \n        function getFlashVersion() {\n            var version;\n    \n            try {\n                version = navigator.plugins[ 'Shockwave Flash' ];\n                version = version.description;\n            } catch ( ex ) {\n                try {\n                    version = new ActiveXObject('ShockwaveFlash.ShockwaveFlash')\n                            .GetVariable('$version');\n                } catch ( ex2 ) {\n                    version = '0.0';\n                }\n            }\n            version = version.match( /\\d+/g );\n            return parseFloat( version[ 0 ] + '.' + version[ 1 ], 10 );\n        }\n    \n        function FlashRuntime() {\n            var pool = {},\n                clients = {},\n                destory = this.destory,\n                me = this,\n                jsreciver = Base.guid('webuploader_');\n    \n            Runtime.apply( me, arguments );\n            me.type = type;\n    \n    \n            // 这个方法的调用者，实际上是RuntimeClient\n            me.exec = function( comp, fn/*, args...*/ ) {\n                var client = this,\n                    uid = client.uid,\n                    args = Base.slice( arguments, 2 ),\n                    instance;\n    \n                clients[ uid ] = client;\n    \n                if ( components[ comp ] ) {\n                    if ( !pool[ uid ] ) {\n                        pool[ uid ] = new components[ comp ]( client, me );\n                    }\n    \n                    instance = pool[ uid ];\n    \n                    if ( instance[ fn ] ) {\n                        return instance[ fn ].apply( instance, args );\n                    }\n                }\n    \n                return me.flashExec.apply( client, arguments );\n            };\n    \n            function handler( evt, obj ) {\n                var type = evt.type || evt,\n                    parts, uid;\n    \n                parts = type.split('::');\n                uid = parts[ 0 ];\n                type = parts[ 1 ];\n    \n                // console.log.apply( console, arguments );\n    \n                if ( type === 'Ready' && uid === me.uid ) {\n                    me.trigger('ready');\n                } else if ( clients[ uid ] ) {\n                    clients[ uid ].trigger( type.toLowerCase(), evt, obj );\n                }\n    \n                // Base.log( evt, obj );\n            }\n    \n            // flash的接受器。\n            window[ jsreciver ] = function() {\n                var args = arguments;\n    \n                // 为了能捕获得到。\n                setTimeout(function() {\n                    handler.apply( null, args );\n                }, 1 );\n            };\n    \n            this.jsreciver = jsreciver;\n    \n            this.destory = function() {\n                // @todo 删除池子中的所有实例\n                return destory && destory.apply( this, arguments );\n            };\n    \n            this.flashExec = function( comp, fn ) {\n                var flash = me.getFlash(),\n                    args = Base.slice( arguments, 2 );\n    \n                return flash.exec( this.uid, comp, fn, args );\n            };\n    \n            // @todo\n        }\n    \n        Base.inherits( Runtime, {\n            constructor: FlashRuntime,\n    \n            init: function() {\n                var container = this.getContainer(),\n                    opts = this.options,\n                    html;\n    \n                // if not the minimal height, shims are not initialized\n                // in older browsers (e.g FF3.6, IE6,7,8, Safari 4.0,5.0, etc)\n                container.css({\n                    position: 'absolute',\n                    top: '-8px',\n                    left: '-8px',\n                    width: '9px',\n                    height: '9px',\n                    overflow: 'hidden'\n                });\n    \n                // insert flash object\n                html = '<object id=\"' + this.uid + '\" type=\"application/' +\n                        'x-shockwave-flash\" data=\"' +  opts.swf + '\" ';\n    \n                if ( Base.browser.ie ) {\n                    html += 'classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\" ';\n                }\n    \n                html += 'width=\"100%\" height=\"100%\" style=\"outline:0\">'  +\n                    '<param name=\"movie\" value=\"' + opts.swf + '\" />' +\n                    '<param name=\"flashvars\" value=\"uid=' + this.uid +\n                    '&jsreciver=' + this.jsreciver + '\" />' +\n                    '<param name=\"wmode\" value=\"transparent\" />' +\n                    '<param name=\"allowscriptaccess\" value=\"always\" />' +\n                '</object>';\n    \n                container.html( html );\n            },\n    \n            getFlash: function() {\n                if ( this._flash ) {\n                    return this._flash;\n                }\n    \n                this._flash = $( '#' + this.uid ).get( 0 );\n                return this._flash;\n            }\n    \n        });\n    \n        FlashRuntime.register = function( name, component ) {\n            component = components[ name ] = Base.inherits( CompBase, $.extend({\n    \n                // @todo fix this later\n                flashExec: function() {\n                    var owner = this.owner,\n                        runtime = this.getRuntime();\n    \n                    return runtime.flashExec.apply( owner, arguments );\n                }\n            }, component ) );\n    \n            return component;\n        };\n    \n        if ( getFlashVersion() >= 11.4 ) {\n            Runtime.addRuntime( type, FlashRuntime );\n        }\n    \n        return FlashRuntime;\n    });\n    /**\n     * @fileOverview FilePicker\n     */\n    define('runtime/flash/filepicker',[\n        'base',\n        'runtime/flash/runtime'\n    ], function( Base, FlashRuntime ) {\n        var $ = Base.$;\n    \n        return FlashRuntime.register( 'FilePicker', {\n            init: function( opts ) {\n                var copy = $.extend({}, opts ),\n                    len, i;\n    \n                // 修复Flash再没有设置title的情况下无法弹出flash文件选择框的bug.\n                len = copy.accept && copy.accept.length;\n                for (  i = 0; i < len; i++ ) {\n                    if ( !copy.accept[ i ].title ) {\n                        copy.accept[ i ].title = 'Files';\n                    }\n                }\n    \n                delete copy.button;\n                delete copy.container;\n    \n                this.flashExec( 'FilePicker', 'init', copy );\n            },\n    \n            destroy: function() {\n                // todo\n            }\n        });\n    });\n    /**\n     * @fileOverview  Transport flash实现\n     */\n    define('runtime/flash/transport',[\n        'base',\n        'runtime/flash/runtime',\n        'runtime/client'\n    ], function( Base, FlashRuntime, RuntimeClient ) {\n        var $ = Base.$;\n    \n        return FlashRuntime.register( 'Transport', {\n            init: function() {\n                this._status = 0;\n                this._response = null;\n                this._responseJson = null;\n            },\n    \n            send: function() {\n                var owner = this.owner,\n                    opts = this.options,\n                    xhr = this._initAjax(),\n                    blob = owner._blob,\n                    server = opts.server,\n                    binary;\n    \n                xhr.connectRuntime( blob.ruid );\n    \n                if ( opts.sendAsBinary ) {\n                    server += (/\\?/.test( server ) ? '&' : '?') +\n                            $.param( owner._formData );\n    \n                    binary = blob.uid;\n                } else {\n                    $.each( owner._formData, function( k, v ) {\n                        xhr.exec( 'append', k, v );\n                    });\n    \n                    xhr.exec( 'appendBlob', opts.fileVal, blob.uid,\n                            opts.filename || owner._formData.name || '' );\n                }\n    \n                this._setRequestHeader( xhr, opts.headers );\n                xhr.exec( 'send', {\n                    method: opts.method,\n                    url: server\n                }, binary );\n            },\n    \n            getStatus: function() {\n                return this._status;\n            },\n    \n            getResponse: function() {\n                return this._response;\n            },\n    \n            getResponseAsJson: function() {\n                return this._responseJson;\n            },\n    \n            abort: function() {\n                var xhr = this._xhr;\n    \n                if ( xhr ) {\n                    xhr.exec('abort');\n                    xhr.destroy();\n                    this._xhr = xhr = null;\n                }\n            },\n    \n            destroy: function() {\n                this.abort();\n            },\n    \n            _initAjax: function() {\n                var me = this,\n                    xhr = new RuntimeClient('XMLHttpRequest');\n    \n                xhr.on( 'uploadprogress progress', function( e ) {\n                    return me.trigger( 'progress', e.loaded / e.total );\n                });\n    \n                xhr.on( 'load', function() {\n                    var status = xhr.exec('getStatus'),\n                        err = '';\n    \n                    xhr.off();\n                    me._xhr = null;\n    \n                    if ( status >= 200 && status < 300 ) {\n                        me._response = xhr.exec('getResponse');\n                        me._responseJson = xhr.exec('getResponseAsJson');\n                    } else if ( status >= 500 && status < 600 ) {\n                        me._response = xhr.exec('getResponse');\n                        me._responseJson = xhr.exec('getResponseAsJson');\n                        err = 'server';\n                    } else {\n                        err = 'http';\n                    }\n    \n                    xhr.destroy();\n                    xhr = null;\n    \n                    return err ? me.trigger( 'error', err ) : me.trigger('load');\n                });\n    \n                xhr.on( 'error', function() {\n                    xhr.off();\n                    me._xhr = null;\n                    me.trigger( 'error', 'http' );\n                });\n    \n                me._xhr = xhr;\n                return xhr;\n            },\n    \n            _setRequestHeader: function( xhr, headers ) {\n                $.each( headers, function( key, val ) {\n                    xhr.exec( 'setRequestHeader', key, val );\n                });\n            }\n        });\n    });\n    /**\n     * @fileOverview 没有图像处理的版本。\n     */\n    define('preset/withoutimage',[\n        'base',\n    \n        // widgets\n        'widgets/filednd',\n        'widgets/filepaste',\n        'widgets/filepicker',\n        'widgets/queue',\n        'widgets/runtime',\n        'widgets/upload',\n        'widgets/validator',\n    \n        // runtimes\n        // html5\n        'runtime/html5/blob',\n        'runtime/html5/dnd',\n        'runtime/html5/filepaste',\n        'runtime/html5/filepicker',\n        'runtime/html5/transport',\n    \n        // flash\n        'runtime/flash/filepicker',\n        'runtime/flash/transport'\n    ], function( Base ) {\n        return Base;\n    });\n    define('webuploader',[\n        'preset/withoutimage'\n    ], function( preset ) {\n        return preset;\n    });\n    return require('webuploader');\n});\n"
  },
  {
    "path": "public/static/ueditor/third-party/zeroclipboard/ZeroClipboard.js",
    "content": "/*!\n* ZeroClipboard\n* The ZeroClipboard library provides an easy way to copy text to the clipboard using an invisible Adobe Flash movie and a JavaScript interface.\n* Copyright (c) 2014 Jon Rohan, James M. Greene\n* Licensed MIT\n* http://zeroclipboard.org/\n* v2.0.0-beta.5\n*/\n(function(window) {\n  \"use strict\";\n  var _currentElement;\n  var _flashState = {\n    bridge: null,\n    version: \"0.0.0\",\n    pluginType: \"unknown\",\n    disabled: null,\n    outdated: null,\n    unavailable: null,\n    deactivated: null,\n    overdue: null,\n    ready: null\n  };\n  var _clipData = {};\n  var _clipDataFormatMap = null;\n  var _clientIdCounter = 0;\n  var _clientMeta = {};\n  var _elementIdCounter = 0;\n  var _elementMeta = {};\n  var _swfPath = function() {\n    var i, jsDir, tmpJsPath, jsPath, swfPath = \"ZeroClipboard.swf\";\n    if (!(document.currentScript && (jsPath = document.currentScript.src))) {\n      var scripts = document.getElementsByTagName(\"script\");\n      if (\"readyState\" in scripts[0]) {\n        for (i = scripts.length; i--; ) {\n          if (scripts[i].readyState === \"interactive\" && (jsPath = scripts[i].src)) {\n            break;\n          }\n        }\n      } else if (document.readyState === \"loading\") {\n        jsPath = scripts[scripts.length - 1].src;\n      } else {\n        for (i = scripts.length; i--; ) {\n          tmpJsPath = scripts[i].src;\n          if (!tmpJsPath) {\n            jsDir = null;\n            break;\n          }\n          tmpJsPath = tmpJsPath.split(\"#\")[0].split(\"?\")[0];\n          tmpJsPath = tmpJsPath.slice(0, tmpJsPath.lastIndexOf(\"/\") + 1);\n          if (jsDir == null) {\n            jsDir = tmpJsPath;\n          } else if (jsDir !== tmpJsPath) {\n            jsDir = null;\n            break;\n          }\n        }\n        if (jsDir !== null) {\n          jsPath = jsDir;\n        }\n      }\n    }\n    if (jsPath) {\n      jsPath = jsPath.split(\"#\")[0].split(\"?\")[0];\n      swfPath = jsPath.slice(0, jsPath.lastIndexOf(\"/\") + 1) + swfPath;\n    }\n    return swfPath;\n  }();\n  var _camelizeCssPropName = function() {\n    var matcherRegex = /\\-([a-z])/g, replacerFn = function(match, group) {\n      return group.toUpperCase();\n    };\n    return function(prop) {\n      return prop.replace(matcherRegex, replacerFn);\n    };\n  }();\n  var _getStyle = function(el, prop) {\n    var value, camelProp, tagName;\n    if (window.getComputedStyle) {\n      value = window.getComputedStyle(el, null).getPropertyValue(prop);\n    } else {\n      camelProp = _camelizeCssPropName(prop);\n      if (el.currentStyle) {\n        value = el.currentStyle[camelProp];\n      } else {\n        value = el.style[camelProp];\n      }\n    }\n    if (prop === \"cursor\") {\n      if (!value || value === \"auto\") {\n        tagName = el.tagName.toLowerCase();\n        if (tagName === \"a\") {\n          return \"pointer\";\n        }\n      }\n    }\n    return value;\n  };\n  var _elementMouseOver = function(event) {\n    if (!event) {\n      event = window.event;\n    }\n    var target;\n    if (this !== window) {\n      target = this;\n    } else if (event.target) {\n      target = event.target;\n    } else if (event.srcElement) {\n      target = event.srcElement;\n    }\n    ZeroClipboard.activate(target);\n  };\n  var _addEventHandler = function(element, method, func) {\n    if (!element || element.nodeType !== 1) {\n      return;\n    }\n    if (element.addEventListener) {\n      element.addEventListener(method, func, false);\n    } else if (element.attachEvent) {\n      element.attachEvent(\"on\" + method, func);\n    }\n  };\n  var _removeEventHandler = function(element, method, func) {\n    if (!element || element.nodeType !== 1) {\n      return;\n    }\n    if (element.removeEventListener) {\n      element.removeEventListener(method, func, false);\n    } else if (element.detachEvent) {\n      element.detachEvent(\"on\" + method, func);\n    }\n  };\n  var _addClass = function(element, value) {\n    if (!element || element.nodeType !== 1) {\n      return element;\n    }\n    if (element.classList) {\n      if (!element.classList.contains(value)) {\n        element.classList.add(value);\n      }\n      return element;\n    }\n    if (value && typeof value === \"string\") {\n      var classNames = (value || \"\").split(/\\s+/);\n      if (element.nodeType === 1) {\n        if (!element.className) {\n          element.className = value;\n        } else {\n          var className = \" \" + element.className + \" \", setClass = element.className;\n          for (var c = 0, cl = classNames.length; c < cl; c++) {\n            if (className.indexOf(\" \" + classNames[c] + \" \") < 0) {\n              setClass += \" \" + classNames[c];\n            }\n          }\n          element.className = setClass.replace(/^\\s+|\\s+$/g, \"\");\n        }\n      }\n    }\n    return element;\n  };\n  var _removeClass = function(element, value) {\n    if (!element || element.nodeType !== 1) {\n      return element;\n    }\n    if (element.classList) {\n      if (element.classList.contains(value)) {\n        element.classList.remove(value);\n      }\n      return element;\n    }\n    if (value && typeof value === \"string\" || value === undefined) {\n      var classNames = (value || \"\").split(/\\s+/);\n      if (element.nodeType === 1 && element.className) {\n        if (value) {\n          var className = (\" \" + element.className + \" \").replace(/[\\n\\t]/g, \" \");\n          for (var c = 0, cl = classNames.length; c < cl; c++) {\n            className = className.replace(\" \" + classNames[c] + \" \", \" \");\n          }\n          element.className = className.replace(/^\\s+|\\s+$/g, \"\");\n        } else {\n          element.className = \"\";\n        }\n      }\n    }\n    return element;\n  };\n  var _getZoomFactor = function() {\n    var rect, physicalWidth, logicalWidth, zoomFactor = 1;\n    if (typeof document.body.getBoundingClientRect === \"function\") {\n      rect = document.body.getBoundingClientRect();\n      physicalWidth = rect.right - rect.left;\n      logicalWidth = document.body.offsetWidth;\n      zoomFactor = Math.round(physicalWidth / logicalWidth * 100) / 100;\n    }\n    return zoomFactor;\n  };\n  var _getDOMObjectPosition = function(obj, defaultZIndex) {\n    var info = {\n      left: 0,\n      top: 0,\n      width: 0,\n      height: 0,\n      zIndex: _getSafeZIndex(defaultZIndex) - 1\n    };\n    if (obj.getBoundingClientRect) {\n      var rect = obj.getBoundingClientRect();\n      var pageXOffset, pageYOffset, zoomFactor;\n      if (\"pageXOffset\" in window && \"pageYOffset\" in window) {\n        pageXOffset = window.pageXOffset;\n        pageYOffset = window.pageYOffset;\n      } else {\n        zoomFactor = _getZoomFactor();\n        pageXOffset = Math.round(document.documentElement.scrollLeft / zoomFactor);\n        pageYOffset = Math.round(document.documentElement.scrollTop / zoomFactor);\n      }\n      var leftBorderWidth = document.documentElement.clientLeft || 0;\n      var topBorderWidth = document.documentElement.clientTop || 0;\n      info.left = rect.left + pageXOffset - leftBorderWidth;\n      info.top = rect.top + pageYOffset - topBorderWidth;\n      info.width = \"width\" in rect ? rect.width : rect.right - rect.left;\n      info.height = \"height\" in rect ? rect.height : rect.bottom - rect.top;\n    }\n    return info;\n  };\n  var _cacheBust = function(path, options) {\n    var cacheBust = options == null || options && options.cacheBust === true;\n    if (cacheBust) {\n      return (path.indexOf(\"?\") === -1 ? \"?\" : \"&\") + \"noCache=\" + new Date().getTime();\n    } else {\n      return \"\";\n    }\n  };\n  var _vars = function(options) {\n    var i, len, domain, domains, str = \"\", trustedOriginsExpanded = [];\n    if (options.trustedDomains) {\n      if (typeof options.trustedDomains === \"string\") {\n        domains = [ options.trustedDomains ];\n      } else if (typeof options.trustedDomains === \"object\" && \"length\" in options.trustedDomains) {\n        domains = options.trustedDomains;\n      }\n    }\n    if (domains && domains.length) {\n      for (i = 0, len = domains.length; i < len; i++) {\n        if (domains.hasOwnProperty(i) && domains[i] && typeof domains[i] === \"string\") {\n          domain = _extractDomain(domains[i]);\n          if (!domain) {\n            continue;\n          }\n          if (domain === \"*\") {\n            trustedOriginsExpanded = [ domain ];\n            break;\n          }\n          trustedOriginsExpanded.push.apply(trustedOriginsExpanded, [ domain, \"//\" + domain, window.location.protocol + \"//\" + domain ]);\n        }\n      }\n    }\n    if (trustedOriginsExpanded.length) {\n      str += \"trustedOrigins=\" + encodeURIComponent(trustedOriginsExpanded.join(\",\"));\n    }\n    if (options.forceEnhancedClipboard === true) {\n      str += (str ? \"&\" : \"\") + \"forceEnhancedClipboard=true\";\n    }\n    return str;\n  };\n  var _inArray = function(elem, array, fromIndex) {\n    if (typeof array.indexOf === \"function\") {\n      return array.indexOf(elem, fromIndex);\n    }\n    var i, len = array.length;\n    if (typeof fromIndex === \"undefined\") {\n      fromIndex = 0;\n    } else if (fromIndex < 0) {\n      fromIndex = len + fromIndex;\n    }\n    for (i = fromIndex; i < len; i++) {\n      if (array.hasOwnProperty(i) && array[i] === elem) {\n        return i;\n      }\n    }\n    return -1;\n  };\n  var _prepClip = function(elements) {\n    if (typeof elements === \"string\") {\n      throw new TypeError(\"ZeroClipboard doesn't accept query strings.\");\n    }\n    return typeof elements.length !== \"number\" ? [ elements ] : elements;\n  };\n  var _dispatchCallback = function(func, context, args, async) {\n    if (async) {\n      window.setTimeout(function() {\n        func.apply(context, args);\n      }, 0);\n    } else {\n      func.apply(context, args);\n    }\n  };\n  var _getSafeZIndex = function(val) {\n    var zIndex, tmp;\n    if (val) {\n      if (typeof val === \"number\" && val > 0) {\n        zIndex = val;\n      } else if (typeof val === \"string\" && (tmp = parseInt(val, 10)) && !isNaN(tmp) && tmp > 0) {\n        zIndex = tmp;\n      }\n    }\n    if (!zIndex) {\n      if (typeof _globalConfig.zIndex === \"number\" && _globalConfig.zIndex > 0) {\n        zIndex = _globalConfig.zIndex;\n      } else if (typeof _globalConfig.zIndex === \"string\" && (tmp = parseInt(_globalConfig.zIndex, 10)) && !isNaN(tmp) && tmp > 0) {\n        zIndex = tmp;\n      }\n    }\n    return zIndex || 0;\n  };\n  var _extend = function() {\n    var i, len, arg, prop, src, copy, target = arguments[0] || {};\n    for (i = 1, len = arguments.length; i < len; i++) {\n      if ((arg = arguments[i]) != null) {\n        for (prop in arg) {\n          if (arg.hasOwnProperty(prop)) {\n            src = target[prop];\n            copy = arg[prop];\n            if (target === copy) {\n              continue;\n            }\n            if (copy !== undefined) {\n              target[prop] = copy;\n            }\n          }\n        }\n      }\n    }\n    return target;\n  };\n  var _extractDomain = function(originOrUrl) {\n    if (originOrUrl == null || originOrUrl === \"\") {\n      return null;\n    }\n    originOrUrl = originOrUrl.replace(/^\\s+|\\s+$/g, \"\");\n    if (originOrUrl === \"\") {\n      return null;\n    }\n    var protocolIndex = originOrUrl.indexOf(\"//\");\n    originOrUrl = protocolIndex === -1 ? originOrUrl : originOrUrl.slice(protocolIndex + 2);\n    var pathIndex = originOrUrl.indexOf(\"/\");\n    originOrUrl = pathIndex === -1 ? originOrUrl : protocolIndex === -1 || pathIndex === 0 ? null : originOrUrl.slice(0, pathIndex);\n    if (originOrUrl && originOrUrl.slice(-4).toLowerCase() === \".swf\") {\n      return null;\n    }\n    return originOrUrl || null;\n  };\n  var _determineScriptAccess = function() {\n    var _extractAllDomains = function(origins, resultsArray) {\n      var i, len, tmp;\n      if (origins == null || resultsArray[0] === \"*\") {\n        return;\n      }\n      if (typeof origins === \"string\") {\n        origins = [ origins ];\n      }\n      if (!(typeof origins === \"object\" && typeof origins.length === \"number\")) {\n        return;\n      }\n      for (i = 0, len = origins.length; i < len; i++) {\n        if (origins.hasOwnProperty(i) && (tmp = _extractDomain(origins[i]))) {\n          if (tmp === \"*\") {\n            resultsArray.length = 0;\n            resultsArray.push(\"*\");\n            break;\n          }\n          if (_inArray(tmp, resultsArray) === -1) {\n            resultsArray.push(tmp);\n          }\n        }\n      }\n    };\n    return function(currentDomain, configOptions) {\n      var swfDomain = _extractDomain(configOptions.swfPath);\n      if (swfDomain === null) {\n        swfDomain = currentDomain;\n      }\n      var trustedDomains = [];\n      _extractAllDomains(configOptions.trustedOrigins, trustedDomains);\n      _extractAllDomains(configOptions.trustedDomains, trustedDomains);\n      var len = trustedDomains.length;\n      if (len > 0) {\n        if (len === 1 && trustedDomains[0] === \"*\") {\n          return \"always\";\n        }\n        if (_inArray(currentDomain, trustedDomains) !== -1) {\n          if (len === 1 && currentDomain === swfDomain) {\n            return \"sameDomain\";\n          }\n          return \"always\";\n        }\n      }\n      return \"never\";\n    };\n  }();\n  var _objectKeys = function(obj) {\n    if (obj == null) {\n      return [];\n    }\n    if (Object.keys) {\n      return Object.keys(obj);\n    }\n    var keys = [];\n    for (var prop in obj) {\n      if (obj.hasOwnProperty(prop)) {\n        keys.push(prop);\n      }\n    }\n    return keys;\n  };\n  var _deleteOwnProperties = function(obj) {\n    if (obj) {\n      for (var prop in obj) {\n        if (obj.hasOwnProperty(prop)) {\n          delete obj[prop];\n        }\n      }\n    }\n    return obj;\n  };\n  var _safeActiveElement = function() {\n    try {\n      return document.activeElement;\n    } catch (err) {}\n    return null;\n  };\n  var _pick = function(obj, keys) {\n    var newObj = {};\n    for (var i = 0, len = keys.length; i < len; i++) {\n      if (keys[i] in obj) {\n        newObj[keys[i]] = obj[keys[i]];\n      }\n    }\n    return newObj;\n  };\n  var _omit = function(obj, keys) {\n    var newObj = {};\n    for (var prop in obj) {\n      if (_inArray(prop, keys) === -1) {\n        newObj[prop] = obj[prop];\n      }\n    }\n    return newObj;\n  };\n  var _mapClipDataToFlash = function(clipData) {\n    var newClipData = {}, formatMap = {};\n    if (!(typeof clipData === \"object\" && clipData)) {\n      return;\n    }\n    for (var dataFormat in clipData) {\n      if (dataFormat && clipData.hasOwnProperty(dataFormat) && typeof clipData[dataFormat] === \"string\" && clipData[dataFormat]) {\n        switch (dataFormat.toLowerCase()) {\n         case \"text/plain\":\n         case \"text\":\n         case \"air:text\":\n         case \"flash:text\":\n          newClipData.text = clipData[dataFormat];\n          formatMap.text = dataFormat;\n          break;\n\n         case \"text/html\":\n         case \"html\":\n         case \"air:html\":\n         case \"flash:html\":\n          newClipData.html = clipData[dataFormat];\n          formatMap.html = dataFormat;\n          break;\n\n         case \"application/rtf\":\n         case \"text/rtf\":\n         case \"rtf\":\n         case \"richtext\":\n         case \"air:rtf\":\n         case \"flash:rtf\":\n          newClipData.rtf = clipData[dataFormat];\n          formatMap.rtf = dataFormat;\n          break;\n\n         default:\n          break;\n        }\n      }\n    }\n    return {\n      data: newClipData,\n      formatMap: formatMap\n    };\n  };\n  var _mapClipResultsFromFlash = function(clipResults, formatMap) {\n    if (!(typeof clipResults === \"object\" && clipResults && typeof formatMap === \"object\" && formatMap)) {\n      return clipResults;\n    }\n    var newResults = {};\n    for (var prop in clipResults) {\n      if (clipResults.hasOwnProperty(prop)) {\n        if (prop !== \"success\" && prop !== \"data\") {\n          newResults[prop] = clipResults[prop];\n          continue;\n        }\n        newResults[prop] = {};\n        var tmpHash = clipResults[prop];\n        for (var dataFormat in tmpHash) {\n          if (dataFormat && tmpHash.hasOwnProperty(dataFormat) && formatMap.hasOwnProperty(dataFormat)) {\n            newResults[prop][formatMap[dataFormat]] = tmpHash[dataFormat];\n          }\n        }\n      }\n    }\n    return newResults;\n  };\n  var _args = function(arraySlice) {\n    return function(args) {\n      return arraySlice.call(args, 0);\n    };\n  }(window.Array.prototype.slice);\n  var _detectFlashSupport = function() {\n    var plugin, ax, mimeType, hasFlash = false, isActiveX = false, isPPAPI = false, flashVersion = \"\";\n    function parseFlashVersion(desc) {\n      var matches = desc.match(/[\\d]+/g);\n      matches.length = 3;\n      return matches.join(\".\");\n    }\n    function isPepperFlash(flashPlayerFileName) {\n      return !!flashPlayerFileName && (flashPlayerFileName = flashPlayerFileName.toLowerCase()) && (/^(pepflashplayer\\.dll|libpepflashplayer\\.so|pepperflashplayer\\.plugin)$/.test(flashPlayerFileName) || flashPlayerFileName.slice(-13) === \"chrome.plugin\");\n    }\n    function inspectPlugin(plugin) {\n      if (plugin) {\n        hasFlash = true;\n        if (plugin.version) {\n          flashVersion = parseFlashVersion(plugin.version);\n        }\n        if (!flashVersion && plugin.description) {\n          flashVersion = parseFlashVersion(plugin.description);\n        }\n        if (plugin.filename) {\n          isPPAPI = isPepperFlash(plugin.filename);\n        }\n      }\n    }\n    if (navigator.plugins && navigator.plugins.length) {\n      plugin = navigator.plugins[\"Shockwave Flash\"];\n      inspectPlugin(plugin);\n      if (navigator.plugins[\"Shockwave Flash 2.0\"]) {\n        hasFlash = true;\n        flashVersion = \"2.0.0.11\";\n      }\n    } else if (navigator.mimeTypes && navigator.mimeTypes.length) {\n      mimeType = navigator.mimeTypes[\"application/x-shockwave-flash\"];\n      plugin = mimeType && mimeType.enabledPlugin;\n      inspectPlugin(plugin);\n    } else if (typeof ActiveXObject !== \"undefined\") {\n      isActiveX = true;\n      try {\n        ax = new ActiveXObject(\"ShockwaveFlash.ShockwaveFlash.7\");\n        hasFlash = true;\n        flashVersion = parseFlashVersion(ax.GetVariable(\"$version\"));\n      } catch (e1) {\n        try {\n          ax = new ActiveXObject(\"ShockwaveFlash.ShockwaveFlash.6\");\n          hasFlash = true;\n          flashVersion = \"6.0.21\";\n        } catch (e2) {\n          try {\n            ax = new ActiveXObject(\"ShockwaveFlash.ShockwaveFlash\");\n            hasFlash = true;\n            flashVersion = parseFlashVersion(ax.GetVariable(\"$version\"));\n          } catch (e3) {\n            isActiveX = false;\n          }\n        }\n      }\n    }\n    _flashState.disabled = hasFlash !== true;\n    _flashState.outdated = flashVersion && parseFloat(flashVersion) < 11;\n    _flashState.version = flashVersion || \"0.0.0\";\n    _flashState.pluginType = isPPAPI ? \"pepper\" : isActiveX ? \"activex\" : hasFlash ? \"netscape\" : \"unknown\";\n  };\n  _detectFlashSupport();\n  var ZeroClipboard = function(elements) {\n    if (!(this instanceof ZeroClipboard)) {\n      return new ZeroClipboard(elements);\n    }\n    this.id = \"\" + _clientIdCounter++;\n    _clientMeta[this.id] = {\n      instance: this,\n      elements: [],\n      handlers: {}\n    };\n    if (elements) {\n      this.clip(elements);\n    }\n    if (typeof _flashState.ready !== \"boolean\") {\n      _flashState.ready = false;\n    }\n    if (!ZeroClipboard.isFlashUnusable() && _flashState.bridge === null) {\n      var _client = this;\n      var maxWait = _globalConfig.flashLoadTimeout;\n      if (typeof maxWait === \"number\" && maxWait >= 0) {\n        setTimeout(function() {\n          if (typeof _flashState.deactivated !== \"boolean\") {\n            _flashState.deactivated = true;\n          }\n          if (_flashState.deactivated === true) {\n            ZeroClipboard.emit({\n              type: \"error\",\n              name: \"flash-deactivated\",\n              client: _client\n            });\n          }\n        }, maxWait);\n      }\n      _flashState.overdue = false;\n      _bridge();\n    }\n  };\n  ZeroClipboard.prototype.setText = function(text) {\n    ZeroClipboard.setData(\"text/plain\", text);\n    return this;\n  };\n  ZeroClipboard.prototype.setHtml = function(html) {\n    ZeroClipboard.setData(\"text/html\", html);\n    return this;\n  };\n  ZeroClipboard.prototype.setRichText = function(richText) {\n    ZeroClipboard.setData(\"application/rtf\", richText);\n    return this;\n  };\n  ZeroClipboard.prototype.setData = function() {\n    ZeroClipboard.setData.apply(ZeroClipboard, _args(arguments));\n    return this;\n  };\n  ZeroClipboard.prototype.clearData = function() {\n    ZeroClipboard.clearData.apply(ZeroClipboard, _args(arguments));\n    return this;\n  };\n  ZeroClipboard.prototype.setSize = function(width, height) {\n    _setSize(width, height);\n    return this;\n  };\n  var _setHandCursor = function(enabled) {\n    if (_flashState.ready === true && _flashState.bridge && typeof _flashState.bridge.setHandCursor === \"function\") {\n      _flashState.bridge.setHandCursor(enabled);\n    } else {\n      _flashState.ready = false;\n    }\n  };\n  ZeroClipboard.prototype.destroy = function() {\n    this.unclip();\n    this.off();\n    delete _clientMeta[this.id];\n  };\n  var _getAllClients = function() {\n    var i, len, client, clients = [], clientIds = _objectKeys(_clientMeta);\n    for (i = 0, len = clientIds.length; i < len; i++) {\n      client = _clientMeta[clientIds[i]].instance;\n      if (client && client instanceof ZeroClipboard) {\n        clients.push(client);\n      }\n    }\n    return clients;\n  };\n  ZeroClipboard.version = \"2.0.0-beta.5\";\n  var _globalConfig = {\n    swfPath: _swfPath,\n    trustedDomains: window.location.host ? [ window.location.host ] : [],\n    cacheBust: true,\n    forceHandCursor: false,\n    forceEnhancedClipboard: false,\n    zIndex: 999999999,\n    debug: false,\n    title: null,\n    autoActivate: true,\n    flashLoadTimeout: 3e4\n  };\n  ZeroClipboard.isFlashUnusable = function() {\n    return !!(_flashState.disabled || _flashState.outdated || _flashState.unavailable || _flashState.deactivated);\n  };\n  ZeroClipboard.config = function(options) {\n    if (typeof options === \"object\" && options !== null) {\n      _extend(_globalConfig, options);\n    }\n    if (typeof options === \"string\" && options) {\n      if (_globalConfig.hasOwnProperty(options)) {\n        return _globalConfig[options];\n      }\n      return;\n    }\n    var copy = {};\n    for (var prop in _globalConfig) {\n      if (_globalConfig.hasOwnProperty(prop)) {\n        if (typeof _globalConfig[prop] === \"object\" && _globalConfig[prop] !== null) {\n          if (\"length\" in _globalConfig[prop]) {\n            copy[prop] = _globalConfig[prop].slice(0);\n          } else {\n            copy[prop] = _extend({}, _globalConfig[prop]);\n          }\n        } else {\n          copy[prop] = _globalConfig[prop];\n        }\n      }\n    }\n    return copy;\n  };\n  ZeroClipboard.destroy = function() {\n    ZeroClipboard.deactivate();\n    for (var clientId in _clientMeta) {\n      if (_clientMeta.hasOwnProperty(clientId) && _clientMeta[clientId]) {\n        var client = _clientMeta[clientId].instance;\n        if (client && typeof client.destroy === \"function\") {\n          client.destroy();\n        }\n      }\n    }\n    var flashBridge = _flashState.bridge;\n    if (flashBridge) {\n      var htmlBridge = _getHtmlBridge(flashBridge);\n      if (htmlBridge) {\n        if (_flashState.pluginType === \"activex\" && \"readyState\" in flashBridge) {\n          flashBridge.style.display = \"none\";\n          (function removeSwfFromIE() {\n            if (flashBridge.readyState === 4) {\n              for (var prop in flashBridge) {\n                if (typeof flashBridge[prop] === \"function\") {\n                  flashBridge[prop] = null;\n                }\n              }\n              flashBridge.parentNode.removeChild(flashBridge);\n              if (htmlBridge.parentNode) {\n                htmlBridge.parentNode.removeChild(htmlBridge);\n              }\n            } else {\n              setTimeout(removeSwfFromIE, 10);\n            }\n          })();\n        } else {\n          flashBridge.parentNode.removeChild(flashBridge);\n          if (htmlBridge.parentNode) {\n            htmlBridge.parentNode.removeChild(htmlBridge);\n          }\n        }\n      }\n      _flashState.ready = null;\n      _flashState.bridge = null;\n      _flashState.deactivated = null;\n    }\n    ZeroClipboard.clearData();\n  };\n  ZeroClipboard.activate = function(element) {\n    if (_currentElement) {\n      _removeClass(_currentElement, _globalConfig.hoverClass);\n      _removeClass(_currentElement, _globalConfig.activeClass);\n    }\n    _currentElement = element;\n    _addClass(element, _globalConfig.hoverClass);\n    _reposition();\n    var newTitle = _globalConfig.title || element.getAttribute(\"title\");\n    if (newTitle) {\n      var htmlBridge = _getHtmlBridge(_flashState.bridge);\n      if (htmlBridge) {\n        htmlBridge.setAttribute(\"title\", newTitle);\n      }\n    }\n    var useHandCursor = _globalConfig.forceHandCursor === true || _getStyle(element, \"cursor\") === \"pointer\";\n    _setHandCursor(useHandCursor);\n  };\n  ZeroClipboard.deactivate = function() {\n    var htmlBridge = _getHtmlBridge(_flashState.bridge);\n    if (htmlBridge) {\n      htmlBridge.removeAttribute(\"title\");\n      htmlBridge.style.left = \"0px\";\n      htmlBridge.style.top = \"-9999px\";\n      _setSize(1, 1);\n    }\n    if (_currentElement) {\n      _removeClass(_currentElement, _globalConfig.hoverClass);\n      _removeClass(_currentElement, _globalConfig.activeClass);\n      _currentElement = null;\n    }\n  };\n  ZeroClipboard.state = function() {\n    return {\n      browser: _pick(window.navigator, [ \"userAgent\", \"platform\", \"appName\" ]),\n      flash: _omit(_flashState, [ \"bridge\" ]),\n      zeroclipboard: {\n        version: ZeroClipboard.version,\n        config: ZeroClipboard.config()\n      }\n    };\n  };\n  ZeroClipboard.setData = function(format, data) {\n    var dataObj;\n    if (typeof format === \"object\" && format && typeof data === \"undefined\") {\n      dataObj = format;\n      ZeroClipboard.clearData();\n    } else if (typeof format === \"string\" && format) {\n      dataObj = {};\n      dataObj[format] = data;\n    } else {\n      return;\n    }\n    for (var dataFormat in dataObj) {\n      if (dataFormat && dataObj.hasOwnProperty(dataFormat) && typeof dataObj[dataFormat] === \"string\" && dataObj[dataFormat]) {\n        _clipData[dataFormat] = dataObj[dataFormat];\n      }\n    }\n  };\n  ZeroClipboard.clearData = function(format) {\n    if (typeof format === \"undefined\") {\n      _deleteOwnProperties(_clipData);\n      _clipDataFormatMap = null;\n    } else if (typeof format === \"string\" && _clipData.hasOwnProperty(format)) {\n      delete _clipData[format];\n    }\n  };\n  var _bridge = function() {\n    var flashBridge, len;\n    var container = document.getElementById(\"global-zeroclipboard-html-bridge\");\n    if (!container) {\n      var allowScriptAccess = _determineScriptAccess(window.location.host, _globalConfig);\n      var allowNetworking = allowScriptAccess === \"never\" ? \"none\" : \"all\";\n      var flashvars = _vars(_globalConfig);\n      var swfUrl = _globalConfig.swfPath + _cacheBust(_globalConfig.swfPath, _globalConfig);\n      container = _createHtmlBridge();\n      var divToBeReplaced = document.createElement(\"div\");\n      container.appendChild(divToBeReplaced);\n      document.body.appendChild(container);\n      var tmpDiv = document.createElement(\"div\");\n      var oldIE = _flashState.pluginType === \"activex\";\n      tmpDiv.innerHTML = '<object id=\"global-zeroclipboard-flash-bridge\" name=\"global-zeroclipboard-flash-bridge\" ' + 'width=\"100%\" height=\"100%\" ' + (oldIE ? 'classid=\"clsid:d27cdb6e-ae6d-11cf-96b8-444553540000\"' : 'type=\"application/x-shockwave-flash\" data=\"' + swfUrl + '\"') + \">\" + (oldIE ? '<param name=\"movie\" value=\"' + swfUrl + '\"/>' : \"\") + '<param name=\"allowScriptAccess\" value=\"' + allowScriptAccess + '\"/>' + '<param name=\"allowNetworking\" value=\"' + allowNetworking + '\"/>' + '<param name=\"menu\" value=\"false\"/>' + '<param name=\"wmode\" value=\"transparent\"/>' + '<param name=\"flashvars\" value=\"' + flashvars + '\"/>' + \"</object>\";\n      flashBridge = tmpDiv.firstChild;\n      tmpDiv = null;\n      flashBridge.ZeroClipboard = ZeroClipboard;\n      container.replaceChild(flashBridge, divToBeReplaced);\n    }\n    if (!flashBridge) {\n      flashBridge = document[\"global-zeroclipboard-flash-bridge\"];\n      if (flashBridge && (len = flashBridge.length)) {\n        flashBridge = flashBridge[len - 1];\n      }\n      if (!flashBridge) {\n        flashBridge = container.firstChild;\n      }\n    }\n    _flashState.bridge = flashBridge || null;\n  };\n  var _createHtmlBridge = function() {\n    var container = document.createElement(\"div\");\n    container.id = \"global-zeroclipboard-html-bridge\";\n    container.className = \"global-zeroclipboard-container\";\n    container.style.position = \"absolute\";\n    container.style.left = \"0px\";\n    container.style.top = \"-9999px\";\n    container.style.width = \"1px\";\n    container.style.height = \"1px\";\n    container.style.zIndex = \"\" + _getSafeZIndex(_globalConfig.zIndex);\n    return container;\n  };\n  var _getHtmlBridge = function(flashBridge) {\n    var htmlBridge = flashBridge && flashBridge.parentNode;\n    while (htmlBridge && htmlBridge.nodeName === \"OBJECT\" && htmlBridge.parentNode) {\n      htmlBridge = htmlBridge.parentNode;\n    }\n    return htmlBridge || null;\n  };\n  var _reposition = function() {\n    if (_currentElement) {\n      var pos = _getDOMObjectPosition(_currentElement, _globalConfig.zIndex);\n      var htmlBridge = _getHtmlBridge(_flashState.bridge);\n      if (htmlBridge) {\n        htmlBridge.style.top = pos.top + \"px\";\n        htmlBridge.style.left = pos.left + \"px\";\n        htmlBridge.style.width = pos.width + \"px\";\n        htmlBridge.style.height = pos.height + \"px\";\n        htmlBridge.style.zIndex = pos.zIndex + 1;\n      }\n      _setSize(pos.width, pos.height);\n    }\n  };\n  var _setSize = function(width, height) {\n    var htmlBridge = _getHtmlBridge(_flashState.bridge);\n    if (htmlBridge) {\n      htmlBridge.style.width = width + \"px\";\n      htmlBridge.style.height = height + \"px\";\n    }\n  };\n  ZeroClipboard.emit = function(event) {\n    var eventType, eventObj, performCallbackAsync, clients, i, len, eventCopy, returnVal, tmp;\n    if (typeof event === \"string\" && event) {\n      eventType = event;\n    }\n    if (typeof event === \"object\" && event && typeof event.type === \"string\" && event.type) {\n      eventType = event.type;\n      eventObj = event;\n    }\n    if (!eventType) {\n      return;\n    }\n    event = _createEvent(eventType, eventObj);\n    _preprocessEvent(event);\n    if (event.type === \"ready\" && _flashState.overdue === true) {\n      return ZeroClipboard.emit({\n        type: \"error\",\n        name: \"flash-overdue\"\n      });\n    }\n    performCallbackAsync = !/^(before)?copy$/.test(event.type);\n    if (event.client) {\n      _dispatchClientCallbacks.call(event.client, event, performCallbackAsync);\n    } else {\n      clients = event.target && event.target !== window && _globalConfig.autoActivate === true ? _getAllClientsClippedToElement(event.target) : _getAllClients();\n      for (i = 0, len = clients.length; i < len; i++) {\n        eventCopy = _extend({}, event, {\n          client: clients[i]\n        });\n        _dispatchClientCallbacks.call(clients[i], eventCopy, performCallbackAsync);\n      }\n    }\n    if (event.type === \"copy\") {\n      tmp = _mapClipDataToFlash(_clipData);\n      returnVal = tmp.data;\n      _clipDataFormatMap = tmp.formatMap;\n    }\n    return returnVal;\n  };\n  var _dispatchClientCallbacks = function(event, async) {\n    var handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers[event.type];\n    if (handlers && handlers.length) {\n      var i, len, func, context, originalContext = this;\n      for (i = 0, len = handlers.length; i < len; i++) {\n        func = handlers[i];\n        context = originalContext;\n        if (typeof func === \"string\" && typeof window[func] === \"function\") {\n          func = window[func];\n        }\n        if (typeof func === \"object\" && func && typeof func.handleEvent === \"function\") {\n          context = func;\n          func = func.handleEvent;\n        }\n        if (typeof func === \"function\") {\n          _dispatchCallback(func, context, [ event ], async);\n        }\n      }\n    }\n    return this;\n  };\n  var _eventMessages = {\n    ready: \"Flash communication is established\",\n    error: {\n      \"flash-disabled\": \"Flash is disabled or not installed\",\n      \"flash-outdated\": \"Flash is too outdated to support ZeroClipboard\",\n      \"flash-unavailable\": \"Flash is unable to communicate bidirectionally with JavaScript\",\n      \"flash-deactivated\": \"Flash is too outdated for your browser and/or is configured as click-to-activate\",\n      \"flash-overdue\": \"Flash communication was established but NOT within the acceptable time limit\"\n    }\n  };\n  var _createEvent = function(eventType, event) {\n    if (!(eventType || event && event.type)) {\n      return;\n    }\n    event = event || {};\n    eventType = (eventType || event.type).toLowerCase();\n    _extend(event, {\n      type: eventType,\n      target: event.target || _currentElement || null,\n      relatedTarget: event.relatedTarget || null,\n      currentTarget: _flashState && _flashState.bridge || null\n    });\n    var msg = _eventMessages[event.type];\n    if (event.type === \"error\" && event.name && msg) {\n      msg = msg[event.name];\n    }\n    if (msg) {\n      event.message = msg;\n    }\n    if (event.type === \"ready\") {\n      _extend(event, {\n        target: null,\n        version: _flashState.version\n      });\n    }\n    if (event.type === \"error\") {\n      event.target = null;\n      if (/^flash-(outdated|unavailable|deactivated|overdue)$/.test(event.name)) {\n        _extend(event, {\n          version: _flashState.version,\n          minimumVersion: \"11.0.0\"\n        });\n      }\n    }\n    if (event.type === \"copy\") {\n      event.clipboardData = {\n        setData: ZeroClipboard.setData,\n        clearData: ZeroClipboard.clearData\n      };\n    }\n    if (event.type === \"aftercopy\") {\n      event = _mapClipResultsFromFlash(event, _clipDataFormatMap);\n    }\n    if (event.target && !event.relatedTarget) {\n      event.relatedTarget = _getRelatedTarget(event.target);\n    }\n    return event;\n  };\n  var _getRelatedTarget = function(targetEl) {\n    var relatedTargetId = targetEl && targetEl.getAttribute && targetEl.getAttribute(\"data-clipboard-target\");\n    return relatedTargetId ? document.getElementById(relatedTargetId) : null;\n  };\n  var _preprocessEvent = function(event) {\n    var element = event.target || _currentElement;\n    switch (event.type) {\n     case \"error\":\n      if (_inArray(event.name, [ \"flash-disabled\", \"flash-outdated\", \"flash-deactivated\", \"flash-overdue\" ])) {\n        _extend(_flashState, {\n          disabled: event.name === \"flash-disabled\",\n          outdated: event.name === \"flash-outdated\",\n          unavailable: event.name === \"flash-unavailable\",\n          deactivated: event.name === \"flash-deactivated\",\n          overdue: event.name === \"flash-overdue\",\n          ready: false\n        });\n      }\n      break;\n\n     case \"ready\":\n      var wasDeactivated = _flashState.deactivated === true;\n      _extend(_flashState, {\n        disabled: false,\n        outdated: false,\n        unavailable: false,\n        deactivated: false,\n        overdue: wasDeactivated,\n        ready: !wasDeactivated\n      });\n      break;\n\n     case \"copy\":\n      var textContent, htmlContent, targetEl = event.relatedTarget;\n      if (!(_clipData[\"text/html\"] || _clipData[\"text/plain\"]) && targetEl && (htmlContent = targetEl.value || targetEl.outerHTML || targetEl.innerHTML) && (textContent = targetEl.value || targetEl.textContent || targetEl.innerText)) {\n        event.clipboardData.clearData();\n        event.clipboardData.setData(\"text/plain\", textContent);\n        if (htmlContent !== textContent) {\n          event.clipboardData.setData(\"text/html\", htmlContent);\n        }\n      } else if (!_clipData[\"text/plain\"] && event.target && (textContent = event.target.getAttribute(\"data-clipboard-text\"))) {\n        event.clipboardData.clearData();\n        event.clipboardData.setData(\"text/plain\", textContent);\n      }\n      break;\n\n     case \"aftercopy\":\n      ZeroClipboard.clearData();\n      if (element && element !== _safeActiveElement() && element.focus) {\n        element.focus();\n      }\n      break;\n\n     case \"mouseover\":\n      _addClass(element, _globalConfig.hoverClass);\n      break;\n\n     case \"mouseout\":\n      if (_globalConfig.autoActivate === true) {\n        ZeroClipboard.deactivate();\n      }\n      break;\n\n     case \"mousedown\":\n      _addClass(element, _globalConfig.activeClass);\n      break;\n\n     case \"mouseup\":\n      _removeClass(element, _globalConfig.activeClass);\n      break;\n    }\n  };\n  ZeroClipboard.prototype.on = function(eventName, func) {\n    var i, len, events, added = {}, handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers;\n    if (typeof eventName === \"string\" && eventName) {\n      events = eventName.toLowerCase().split(/\\s+/);\n    } else if (typeof eventName === \"object\" && eventName && typeof func === \"undefined\") {\n      for (i in eventName) {\n        if (eventName.hasOwnProperty(i) && typeof i === \"string\" && i && typeof eventName[i] === \"function\") {\n          this.on(i, eventName[i]);\n        }\n      }\n    }\n    if (events && events.length) {\n      for (i = 0, len = events.length; i < len; i++) {\n        eventName = events[i].replace(/^on/, \"\");\n        added[eventName] = true;\n        if (!handlers[eventName]) {\n          handlers[eventName] = [];\n        }\n        handlers[eventName].push(func);\n      }\n      if (added.ready && _flashState.ready) {\n        ZeroClipboard.emit({\n          type: \"ready\",\n          client: this\n        });\n      }\n      if (added.error) {\n        var errorTypes = [ \"disabled\", \"outdated\", \"unavailable\", \"deactivated\", \"overdue\" ];\n        for (i = 0, len = errorTypes.length; i < len; i++) {\n          if (_flashState[errorTypes[i]]) {\n            ZeroClipboard.emit({\n              type: \"error\",\n              name: \"flash-\" + errorTypes[i],\n              client: this\n            });\n            break;\n          }\n        }\n      }\n    }\n    return this;\n  };\n  ZeroClipboard.prototype.off = function(eventName, func) {\n    var i, len, foundIndex, events, perEventHandlers, handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers;\n    if (arguments.length === 0) {\n      events = _objectKeys(handlers);\n    } else if (typeof eventName === \"string\" && eventName) {\n      events = eventName.split(/\\s+/);\n    } else if (typeof eventName === \"object\" && eventName && typeof func === \"undefined\") {\n      for (i in eventName) {\n        if (eventName.hasOwnProperty(i) && typeof i === \"string\" && i && typeof eventName[i] === \"function\") {\n          this.off(i, eventName[i]);\n        }\n      }\n    }\n    if (events && events.length) {\n      for (i = 0, len = events.length; i < len; i++) {\n        eventName = events[i].toLowerCase().replace(/^on/, \"\");\n        perEventHandlers = handlers[eventName];\n        if (perEventHandlers && perEventHandlers.length) {\n          if (func) {\n            foundIndex = _inArray(func, perEventHandlers);\n            while (foundIndex !== -1) {\n              perEventHandlers.splice(foundIndex, 1);\n              foundIndex = _inArray(func, perEventHandlers, foundIndex);\n            }\n          } else {\n            handlers[eventName].length = 0;\n          }\n        }\n      }\n    }\n    return this;\n  };\n  ZeroClipboard.prototype.handlers = function(eventName) {\n    var prop, copy = null, handlers = _clientMeta[this.id] && _clientMeta[this.id].handlers;\n    if (handlers) {\n      if (typeof eventName === \"string\" && eventName) {\n        return handlers[eventName] ? handlers[eventName].slice(0) : null;\n      }\n      copy = {};\n      for (prop in handlers) {\n        if (handlers.hasOwnProperty(prop) && handlers[prop]) {\n          copy[prop] = handlers[prop].slice(0);\n        }\n      }\n    }\n    return copy;\n  };\n  ZeroClipboard.prototype.clip = function(elements) {\n    elements = _prepClip(elements);\n    for (var i = 0; i < elements.length; i++) {\n      if (elements.hasOwnProperty(i) && elements[i] && elements[i].nodeType === 1) {\n        if (!elements[i].zcClippingId) {\n          elements[i].zcClippingId = \"zcClippingId_\" + _elementIdCounter++;\n          _elementMeta[elements[i].zcClippingId] = [ this.id ];\n          if (_globalConfig.autoActivate === true) {\n            _addEventHandler(elements[i], \"mouseover\", _elementMouseOver);\n          }\n        } else if (_inArray(this.id, _elementMeta[elements[i].zcClippingId]) === -1) {\n          _elementMeta[elements[i].zcClippingId].push(this.id);\n        }\n        var clippedElements = _clientMeta[this.id].elements;\n        if (_inArray(elements[i], clippedElements) === -1) {\n          clippedElements.push(elements[i]);\n        }\n      }\n    }\n    return this;\n  };\n  ZeroClipboard.prototype.unclip = function(elements) {\n    var meta = _clientMeta[this.id];\n    if (!meta) {\n      return this;\n    }\n    var clippedElements = meta.elements;\n    var arrayIndex;\n    if (typeof elements === \"undefined\") {\n      elements = clippedElements.slice(0);\n    } else {\n      elements = _prepClip(elements);\n    }\n    for (var i = elements.length; i--; ) {\n      if (elements.hasOwnProperty(i) && elements[i] && elements[i].nodeType === 1) {\n        arrayIndex = 0;\n        while ((arrayIndex = _inArray(elements[i], clippedElements, arrayIndex)) !== -1) {\n          clippedElements.splice(arrayIndex, 1);\n        }\n        var clientIds = _elementMeta[elements[i].zcClippingId];\n        if (clientIds) {\n          arrayIndex = 0;\n          while ((arrayIndex = _inArray(this.id, clientIds, arrayIndex)) !== -1) {\n            clientIds.splice(arrayIndex, 1);\n          }\n          if (clientIds.length === 0) {\n            if (_globalConfig.autoActivate === true) {\n              _removeEventHandler(elements[i], \"mouseover\", _elementMouseOver);\n            }\n            delete elements[i].zcClippingId;\n          }\n        }\n      }\n    }\n    return this;\n  };\n  ZeroClipboard.prototype.elements = function() {\n    var meta = _clientMeta[this.id];\n    return meta && meta.elements ? meta.elements.slice(0) : [];\n  };\n  var _getAllClientsClippedToElement = function(element) {\n    var elementMetaId, clientIds, i, len, client, clients = [];\n    if (element && element.nodeType === 1 && (elementMetaId = element.zcClippingId) && _elementMeta.hasOwnProperty(elementMetaId)) {\n      clientIds = _elementMeta[elementMetaId];\n      if (clientIds && clientIds.length) {\n        for (i = 0, len = clientIds.length; i < len; i++) {\n          client = _clientMeta[clientIds[i]].instance;\n          if (client && client instanceof ZeroClipboard) {\n            clients.push(client);\n          }\n        }\n      }\n    }\n    return clients;\n  };\n  _globalConfig.hoverClass = \"zeroclipboard-is-hover\";\n  _globalConfig.activeClass = \"zeroclipboard-is-active\";\n  if (typeof define === \"function\" && define.amd) {\n    define(function() {\n      return ZeroClipboard;\n    });\n  } else if (typeof module === \"object\" && module && typeof module.exports === \"object\" && module.exports) {\n    module.exports = ZeroClipboard;\n  } else {\n    window.ZeroClipboard = ZeroClipboard;\n  }\n})(function() {\n  return this;\n}());"
  },
  {
    "path": "public/static/ueditor/ueditor.all.js",
    "content": "/*!\n * UEditor\n * version: ueditor\n * build: Wed Aug 10 2016 11:06:02 GMT+0800 (CST)\n */\n\n(function(){\n\n// editor.js\nUEDITOR_CONFIG = window.UEDITOR_CONFIG || {};\r\n\r\nvar baidu = window.baidu || {};\r\n\r\nwindow.baidu = baidu;\r\n\r\nwindow.UE = baidu.editor =  window.UE || {};\r\n\r\nUE.plugins = {};\r\n\r\nUE.commands = {};\r\n\r\nUE.instants = {};\r\n\r\nUE.I18N = {};\r\n\r\nUE._customizeUI = {};\r\n\r\nUE.version = \"1.4.3\";\r\n\r\nvar dom = UE.dom = {};\n\n// core/browser.js\n/**\r\n * 浏览器判断模块\r\n * @file\r\n * @module UE.browser\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 提供浏览器检测的模块\r\n * @unfile\r\n * @module UE.browser\r\n */\r\nvar browser = UE.browser = function(){\r\n    var agent = navigator.userAgent.toLowerCase(),\r\n        opera = window.opera,\r\n        browser = {\r\n        /**\r\n         * @property {boolean} ie 检测当前浏览器是否为IE\r\n         * @example\r\n         * ```javascript\r\n         * if ( UE.browser.ie ) {\r\n         *     console.log( '当前浏览器是IE' );\r\n         * }\r\n         * ```\r\n         */\r\n        ie\t\t:  /(msie\\s|trident.*rv:)([\\w.]+)/.test(agent),\r\n\r\n        /**\r\n         * @property {boolean} opera 检测当前浏览器是否为Opera\r\n         * @example\r\n         * ```javascript\r\n         * if ( UE.browser.opera ) {\r\n         *     console.log( '当前浏览器是Opera' );\r\n         * }\r\n         * ```\r\n         */\r\n        opera\t: ( !!opera && opera.version ),\r\n\r\n        /**\r\n         * @property {boolean} webkit 检测当前浏览器是否是webkit内核的浏览器\r\n         * @example\r\n         * ```javascript\r\n         * if ( UE.browser.webkit ) {\r\n         *     console.log( '当前浏览器是webkit内核浏览器' );\r\n         * }\r\n         * ```\r\n         */\r\n        webkit\t: ( agent.indexOf( ' applewebkit/' ) > -1 ),\r\n\r\n        /**\r\n         * @property {boolean} mac 检测当前浏览器是否是运行在mac平台下\r\n         * @example\r\n         * ```javascript\r\n         * if ( UE.browser.mac ) {\r\n         *     console.log( '当前浏览器运行在mac平台下' );\r\n         * }\r\n         * ```\r\n         */\r\n        mac\t: ( agent.indexOf( 'macintosh' ) > -1 ),\r\n\r\n        /**\r\n         * @property {boolean} quirks 检测当前浏览器是否处于“怪异模式”下\r\n         * @example\r\n         * ```javascript\r\n         * if ( UE.browser.quirks ) {\r\n         *     console.log( '当前浏览器运行处于“怪异模式”' );\r\n         * }\r\n         * ```\r\n         */\r\n        quirks : ( document.compatMode == 'BackCompat' )\r\n    };\r\n\r\n    /**\r\n    * @property {boolean} gecko 检测当前浏览器内核是否是gecko内核\r\n    * @example\r\n    * ```javascript\r\n    * if ( UE.browser.gecko ) {\r\n    *     console.log( '当前浏览器内核是gecko内核' );\r\n    * }\r\n    * ```\r\n    */\r\n    browser.gecko =( navigator.product == 'Gecko' && !browser.webkit && !browser.opera && !browser.ie);\r\n\r\n    var version = 0;\r\n\r\n    // Internet Explorer 6.0+\r\n    if ( browser.ie ){\r\n\r\n        var v1 =  agent.match(/(?:msie\\s([\\w.]+))/);\r\n        var v2 = agent.match(/(?:trident.*rv:([\\w.]+))/);\r\n        if(v1 && v2 && v1[1] && v2[1]){\r\n            version = Math.max(v1[1]*1,v2[1]*1);\r\n        }else if(v1 && v1[1]){\r\n            version = v1[1]*1;\r\n        }else if(v2 && v2[1]){\r\n            version = v2[1]*1;\r\n        }else{\r\n            version = 0;\r\n        }\r\n\r\n        browser.ie11Compat = document.documentMode == 11;\r\n        /**\r\n         * @property { boolean } ie9Compat 检测浏览器模式是否为 IE9 兼容模式\r\n         * @warning 如果浏览器不是IE， 则该值为undefined\r\n         * @example\r\n         * ```javascript\r\n         * if ( UE.browser.ie9Compat ) {\r\n         *     console.log( '当前浏览器运行在IE9兼容模式下' );\r\n         * }\r\n         * ```\r\n         */\r\n        browser.ie9Compat = document.documentMode == 9;\r\n\r\n        /**\r\n         * @property { boolean } ie8 检测浏览器是否是IE8浏览器\r\n         * @warning 如果浏览器不是IE， 则该值为undefined\r\n         * @example\r\n         * ```javascript\r\n         * if ( UE.browser.ie8 ) {\r\n         *     console.log( '当前浏览器是IE8浏览器' );\r\n         * }\r\n         * ```\r\n         */\r\n        browser.ie8 = !!document.documentMode;\r\n\r\n        /**\r\n         * @property { boolean } ie8Compat 检测浏览器模式是否为 IE8 兼容模式\r\n         * @warning 如果浏览器不是IE， 则该值为undefined\r\n         * @example\r\n         * ```javascript\r\n         * if ( UE.browser.ie8Compat ) {\r\n         *     console.log( '当前浏览器运行在IE8兼容模式下' );\r\n         * }\r\n         * ```\r\n         */\r\n        browser.ie8Compat = document.documentMode == 8;\r\n\r\n        /**\r\n         * @property { boolean } ie7Compat 检测浏览器模式是否为 IE7 兼容模式\r\n         * @warning 如果浏览器不是IE， 则该值为undefined\r\n         * @example\r\n         * ```javascript\r\n         * if ( UE.browser.ie7Compat ) {\r\n         *     console.log( '当前浏览器运行在IE7兼容模式下' );\r\n         * }\r\n         * ```\r\n         */\r\n        browser.ie7Compat = ( ( version == 7 && !document.documentMode )\r\n                || document.documentMode == 7 );\r\n\r\n        /**\r\n         * @property { boolean } ie6Compat 检测浏览器模式是否为 IE6 模式 或者怪异模式\r\n         * @warning 如果浏览器不是IE， 则该值为undefined\r\n         * @example\r\n         * ```javascript\r\n         * if ( UE.browser.ie6Compat ) {\r\n         *     console.log( '当前浏览器运行在IE6模式或者怪异模式下' );\r\n         * }\r\n         * ```\r\n         */\r\n        browser.ie6Compat = ( version < 7 || browser.quirks );\r\n\r\n        browser.ie9above = version > 8;\r\n\r\n        browser.ie9below = version < 9;\r\n\r\n        browser.ie11above = version > 10;\r\n\r\n        browser.ie11below = version < 11;\r\n\r\n    }\r\n\r\n    // Gecko.\r\n    if ( browser.gecko ){\r\n        var geckoRelease = agent.match( /rv:([\\d\\.]+)/ );\r\n        if ( geckoRelease )\r\n        {\r\n            geckoRelease = geckoRelease[1].split( '.' );\r\n            version = geckoRelease[0] * 10000 + ( geckoRelease[1] || 0 ) * 100 + ( geckoRelease[2] || 0 ) * 1;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @property { Number } chrome 检测当前浏览器是否为Chrome, 如果是，则返回Chrome的大版本号\r\n     * @warning 如果浏览器不是chrome， 则该值为undefined\r\n     * @example\r\n     * ```javascript\r\n     * if ( UE.browser.chrome ) {\r\n     *     console.log( '当前浏览器是Chrome' );\r\n     * }\r\n     * ```\r\n     */\r\n    if (/chrome\\/(\\d+\\.\\d)/i.test(agent)) {\r\n        browser.chrome = + RegExp['\\x241'];\r\n    }\r\n\r\n    /**\r\n     * @property { Number } safari 检测当前浏览器是否为Safari, 如果是，则返回Safari的大版本号\r\n     * @warning 如果浏览器不是safari， 则该值为undefined\r\n     * @example\r\n     * ```javascript\r\n     * if ( UE.browser.safari ) {\r\n     *     console.log( '当前浏览器是Safari' );\r\n     * }\r\n     * ```\r\n     */\r\n    if(/(\\d+\\.\\d)?(?:\\.\\d)?\\s+safari\\/?(\\d+\\.\\d+)?/i.test(agent) && !/chrome/i.test(agent)){\r\n    \tbrowser.safari = + (RegExp['\\x241'] || RegExp['\\x242']);\r\n    }\r\n\r\n\r\n    // Opera 9.50+\r\n    if ( browser.opera )\r\n        version = parseFloat( opera.version() );\r\n\r\n    // WebKit 522+ (Safari 3+)\r\n    if ( browser.webkit )\r\n        version = parseFloat( agent.match( / applewebkit\\/(\\d+)/ )[1] );\r\n\r\n    /**\r\n     * @property { Number } version 检测当前浏览器版本号\r\n     * @remind\r\n     * <ul>\r\n     *     <li>IE系列返回值为5,6,7,8,9,10等</li>\r\n     *     <li>gecko系列会返回10900，158900等</li>\r\n     *     <li>webkit系列会返回其build号 (如 522等)</li>\r\n     * </ul>\r\n     * @example\r\n     * ```javascript\r\n     * console.log( '当前浏览器版本号是： ' + UE.browser.version );\r\n     * ```\r\n     */\r\n    browser.version = version;\r\n\r\n    /**\r\n     * @property { boolean } isCompatible 检测当前浏览器是否能够与UEditor良好兼容\r\n     * @example\r\n     * ```javascript\r\n     * if ( UE.browser.isCompatible ) {\r\n     *     console.log( '浏览器与UEditor能够良好兼容' );\r\n     * }\r\n     * ```\r\n     */\r\n    browser.isCompatible =\r\n        !browser.mobile && (\r\n        ( browser.ie && version >= 6 ) ||\r\n        ( browser.gecko && version >= 10801 ) ||\r\n        ( browser.opera && version >= 9.5 ) ||\r\n        ( browser.air && version >= 1 ) ||\r\n        ( browser.webkit && version >= 522 ) ||\r\n        false );\r\n    return browser;\r\n}();\r\n//快捷方式\r\nvar ie = browser.ie,\r\n    webkit = browser.webkit,\r\n    gecko = browser.gecko,\r\n    opera = browser.opera;\n\n// core/utils.js\n/**\r\n * 工具函数包\r\n * @file\r\n * @module UE.utils\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * UEditor封装使用的静态工具函数\r\n * @module UE.utils\r\n * @unfile\r\n */\r\n\r\nvar utils = UE.utils = {\r\n\r\n    /**\r\n     * 用给定的迭代器遍历对象\r\n     * @method each\r\n     * @param { Object } obj 需要遍历的对象\r\n     * @param { Function } iterator 迭代器， 该方法接受两个参数， 第一个参数是当前所处理的value， 第二个参数是当前遍历对象的key\r\n     * @example\r\n     * ```javascript\r\n     * var demoObj = {\r\n     *     key1: 1,\r\n     *     key2: 2\r\n     * };\r\n     *\r\n     * //output: key1: 1, key2: 2\r\n     * UE.utils.each( demoObj, funciton ( value, key ) {\r\n     *\r\n     *     console.log( key + \":\" + value );\r\n     *\r\n     * } );\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 用给定的迭代器遍历数组或类数组对象\r\n     * @method each\r\n     * @param { Array } array 需要遍历的数组或者类数组\r\n     * @param { Function } iterator 迭代器， 该方法接受两个参数， 第一个参数是当前所处理的value， 第二个参数是当前遍历对象的key\r\n     * @example\r\n     * ```javascript\r\n     * var divs = document.getElmentByTagNames( \"div\" );\r\n     *\r\n     * //output: 0: DIV, 1: DIV ...\r\n     * UE.utils.each( divs, funciton ( value, key ) {\r\n     *\r\n     *     console.log( key + \":\" + value.tagName );\r\n     *\r\n     * } );\r\n     * ```\r\n     */\r\n    each : function(obj, iterator, context) {\r\n        if (obj == null) return;\r\n        if (obj.length === +obj.length) {\r\n            for (var i = 0, l = obj.length; i < l; i++) {\r\n                if(iterator.call(context, obj[i], i, obj) === false)\r\n                    return false;\r\n            }\r\n        } else {\r\n            for (var key in obj) {\r\n                if (obj.hasOwnProperty(key)) {\r\n                    if(iterator.call(context, obj[key], key, obj) === false)\r\n                        return false;\r\n                }\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     * 以给定对象作为原型创建一个新对象\r\n     * @method makeInstance\r\n     * @param { Object } protoObject 该对象将作为新创建对象的原型\r\n     * @return { Object } 新的对象， 该对象的原型是给定的protoObject对象\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * var protoObject = { sayHello: function () { console.log('Hello UEditor!'); } };\r\n     *\r\n     * var newObject = UE.utils.makeInstance( protoObject );\r\n     * //output: Hello UEditor!\r\n     * newObject.sayHello();\r\n     * ```\r\n     */\r\n    makeInstance:function (obj) {\r\n        var noop = new Function();\r\n        noop.prototype = obj;\r\n        obj = new noop;\r\n        noop.prototype = null;\r\n        return obj;\r\n    },\r\n\r\n    /**\r\n     * 将source对象中的属性扩展到target对象上\r\n     * @method extend\r\n     * @remind 该方法将强制把source对象上的属性复制到target对象上\r\n     * @see UE.utils.extend(Object,Object,Boolean)\r\n     * @param { Object } target 目标对象， 新的属性将附加到该对象上\r\n     * @param { Object } source 源对象， 该对象的属性会被附加到target对象上\r\n     * @return { Object } 返回target对象\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * var target = { name: 'target', sex: 1 },\r\n     *      source = { name: 'source', age: 17 };\r\n     *\r\n     * UE.utils.extend( target, source );\r\n     *\r\n     * //output: { name: 'source', sex: 1, age: 17 }\r\n     * console.log( target );\r\n     *\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 将source对象中的属性扩展到target对象上， 根据指定的isKeepTarget值决定是否保留目标对象中与\r\n     * 源对象属性名相同的属性值。\r\n     * @method extend\r\n     * @param { Object } target 目标对象， 新的属性将附加到该对象上\r\n     * @param { Object } source 源对象， 该对象的属性会被附加到target对象上\r\n     * @param { Boolean } isKeepTarget 是否保留目标对象中与源对象中属性名相同的属性\r\n     * @return { Object } 返回target对象\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * var target = { name: 'target', sex: 1 },\r\n     *      source = { name: 'source', age: 17 };\r\n     *\r\n     * UE.utils.extend( target, source, true );\r\n     *\r\n     * //output: { name: 'target', sex: 1, age: 17 }\r\n     * console.log( target );\r\n     *\r\n     * ```\r\n     */\r\n    extend:function (t, s, b) {\r\n        if (s) {\r\n            for (var k in s) {\r\n                if (!b || !t.hasOwnProperty(k)) {\r\n                    t[k] = s[k];\r\n                }\r\n            }\r\n        }\r\n        return t;\r\n    },\r\n\r\n    /**\r\n     * 将给定的多个对象的属性复制到目标对象target上\r\n     * @method extend2\r\n     * @remind 该方法将强制把源对象上的属性复制到target对象上\r\n     * @remind 该方法支持两个及以上的参数， 从第二个参数开始， 其属性都会被复制到第一个参数上。 如果遇到同名的属性，\r\n     *          将会覆盖掉之前的值。\r\n     * @param { Object } target 目标对象， 新的属性将附加到该对象上\r\n     * @param { Object... } source 源对象， 支持多个对象， 该对象的属性会被附加到target对象上\r\n     * @return { Object } 返回target对象\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * var target = {},\r\n     *     source1 = { name: 'source', age: 17 },\r\n     *     source2 = { title: 'dev' };\r\n     *\r\n     * UE.utils.extend2( target, source1, source2 );\r\n     *\r\n     * //output: { name: 'source', age: 17, title: 'dev' }\r\n     * console.log( target );\r\n     *\r\n     * ```\r\n     */\r\n    extend2:function (t) {\r\n        var a = arguments;\r\n        for (var i = 1; i < a.length; i++) {\r\n            var x = a[i];\r\n            for (var k in x) {\r\n                if (!t.hasOwnProperty(k)) {\r\n                    t[k] = x[k];\r\n                }\r\n            }\r\n        }\r\n        return t;\r\n    },\r\n\r\n    /**\r\n     * 模拟继承机制， 使得subClass继承自superClass\r\n     * @method inherits\r\n     * @param { Object } subClass 子类对象\r\n     * @param { Object } superClass 超类对象\r\n     * @warning 该方法只能让subClass继承超类的原型， subClass对象自身的属性和方法不会被继承\r\n     * @return { Object } 继承superClass后的子类对象\r\n     * @example\r\n     * ```javascript\r\n     * function SuperClass(){\r\n     *     this.name = \"小李\";\r\n     * }\r\n     *\r\n     * SuperClass.prototype = {\r\n     *     hello:function(str){\r\n     *         console.log(this.name + str);\r\n     *     }\r\n     * }\r\n     *\r\n     * function SubClass(){\r\n     *     this.name = \"小张\";\r\n     * }\r\n     *\r\n     * UE.utils.inherits(SubClass,SuperClass);\r\n     *\r\n     * var sub = new SubClass();\r\n     * //output: '小张早上好!\r\n     * sub.hello(\"早上好!\");\r\n     * ```\r\n     */\r\n    inherits:function (subClass, superClass) {\r\n        var oldP = subClass.prototype,\r\n            newP = utils.makeInstance(superClass.prototype);\r\n        utils.extend(newP, oldP, true);\r\n        subClass.prototype = newP;\r\n        return (newP.constructor = subClass);\r\n    },\r\n\r\n    /**\r\n     * 用指定的context对象作为函数fn的上下文\r\n     * @method bind\r\n     * @param { Function } fn 需要绑定上下文的函数对象\r\n     * @param { Object } content 函数fn新的上下文对象\r\n     * @return { Function } 一个新的函数， 该函数作为原始函数fn的代理， 将完成fn的上下文调换工作。\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * var name = 'window',\r\n     *     newTest = null;\r\n     *\r\n     * function test () {\r\n     *     console.log( this.name );\r\n     * }\r\n     *\r\n     * newTest = UE.utils.bind( test, { name: 'object' } );\r\n     *\r\n     * //output: object\r\n     * newTest();\r\n     *\r\n     * //output: window\r\n     * test();\r\n     *\r\n     * ```\r\n     */\r\n    bind:function (fn, context) {\r\n        return function () {\r\n            return fn.apply(context, arguments);\r\n        };\r\n    },\r\n\r\n    /**\r\n     * 创建延迟指定时间后执行的函数fn\r\n     * @method defer\r\n     * @param { Function } fn 需要延迟执行的函数对象\r\n     * @param { int } delay 延迟的时间， 单位是毫秒\r\n     * @warning 该方法的时间控制是不精确的，仅仅只能保证函数的执行是在给定的时间之后，\r\n     *           而不能保证刚好到达延迟时间时执行。\r\n     * @return { Function } 目标函数fn的代理函数， 只有执行该函数才能起到延时效果\r\n     * @example\r\n     * ```javascript\r\n     * var start = 0;\r\n     *\r\n     * function test(){\r\n     *     console.log( new Date() - start );\r\n     * }\r\n     *\r\n     * var testDefer = UE.utils.defer( test, 1000 );\r\n     * //\r\n     * start = new Date();\r\n     * //output: (大约在1000毫秒之后输出) 1000\r\n     * testDefer();\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 创建延迟指定时间后执行的函数fn, 如果在延迟时间内再次执行该方法， 将会根据指定的exclusion的值，\r\n     * 决定是否取消前一次函数的执行， 如果exclusion的值为true， 则取消执行，反之，将继续执行前一个方法。\r\n     * @method defer\r\n     * @param { Function } fn 需要延迟执行的函数对象\r\n     * @param { int } delay 延迟的时间， 单位是毫秒\r\n     * @param { Boolean } exclusion 如果在延迟时间内再次执行该函数，该值将决定是否取消执行前一次函数的执行，\r\n     *                     值为true表示取消执行， 反之则将在执行前一次函数之后才执行本次函数调用。\r\n     * @warning 该方法的时间控制是不精确的，仅仅只能保证函数的执行是在给定的时间之后，\r\n     *           而不能保证刚好到达延迟时间时执行。\r\n     * @return { Function } 目标函数fn的代理函数， 只有执行该函数才能起到延时效果\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * function test(){\r\n     *     console.log(1);\r\n     * }\r\n     *\r\n     * var testDefer = UE.utils.defer( test, 1000, true );\r\n     *\r\n     * //output: (两次调用仅有一次输出) 1\r\n     * testDefer();\r\n     * testDefer();\r\n     * ```\r\n     */\r\n    defer:function (fn, delay, exclusion) {\r\n        var timerID;\r\n        return function () {\r\n            if (exclusion) {\r\n                clearTimeout(timerID);\r\n            }\r\n            timerID = setTimeout(fn, delay);\r\n        };\r\n    },\r\n\r\n    /**\r\n     * 获取元素item在数组array中首次出现的位置, 如果未找到item， 则返回-1\r\n     * @method indexOf\r\n     * @remind 该方法的匹配过程使用的是恒等“===”\r\n     * @param { Array } array 需要查找的数组对象\r\n     * @param { * } item 需要在目标数组中查找的值\r\n     * @return { int } 返回item在目标数组array中首次出现的位置， 如果在数组中未找到item， 则返回-1\r\n     * @example\r\n     * ```javascript\r\n     * var item = 1,\r\n     *     arr = [ 3, 4, 6, 8, 1, 1, 2 ];\r\n     *\r\n     * //output: 4\r\n     * console.log( UE.utils.indexOf( arr, item ) );\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 获取元素item数组array中首次出现的位置, 如果未找到item， 则返回-1。通过start的值可以指定搜索的起始位置。\r\n     * @method indexOf\r\n     * @remind 该方法的匹配过程使用的是恒等“===”\r\n     * @param { Array } array 需要查找的数组对象\r\n     * @param { * } item 需要在目标数组中查找的值\r\n     * @param { int } start 搜索的起始位置\r\n     * @return { int } 返回item在目标数组array中的start位置之后首次出现的位置， 如果在数组中未找到item， 则返回-1\r\n     * @example\r\n     * ```javascript\r\n     * var item = 1,\r\n     *     arr = [ 3, 4, 6, 8, 1, 2, 8, 3, 2, 1, 1, 4 ];\r\n     *\r\n     * //output: 9\r\n     * console.log( UE.utils.indexOf( arr, item, 5 ) );\r\n     * ```\r\n     */\r\n    indexOf:function (array, item, start) {\r\n        var index = -1;\r\n        start = this.isNumber(start) ? start : 0;\r\n        this.each(array, function (v, i) {\r\n            if (i >= start && v === item) {\r\n                index = i;\r\n                return false;\r\n            }\r\n        });\r\n        return index;\r\n    },\r\n\r\n    /**\r\n     * 移除数组array中所有的元素item\r\n     * @method removeItem\r\n     * @param { Array } array 要移除元素的目标数组\r\n     * @param { * } item 将要被移除的元素\r\n     * @remind 该方法的匹配过程使用的是恒等“===”\r\n     * @example\r\n     * ```javascript\r\n     * var arr = [ 4, 5, 7, 1, 3, 4, 6 ];\r\n     *\r\n     * UE.utils.removeItem( arr, 4 );\r\n     * //output: [ 5, 7, 1, 3, 6 ]\r\n     * console.log( arr );\r\n     *\r\n     * ```\r\n     */\r\n    removeItem:function (array, item) {\r\n        for (var i = 0, l = array.length; i < l; i++) {\r\n            if (array[i] === item) {\r\n                array.splice(i, 1);\r\n                i--;\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     * 删除字符串str的首尾空格\r\n     * @method trim\r\n     * @param { String } str 需要删除首尾空格的字符串\r\n     * @return { String } 删除了首尾的空格后的字符串\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * var str = \" UEdtior \";\r\n     *\r\n     * //output: 9\r\n     * console.log( str.length );\r\n     *\r\n     * //output: 7\r\n     * console.log( UE.utils.trim( \" UEdtior \" ).length );\r\n     *\r\n     * //output: 9\r\n     * console.log( str.length );\r\n     *\r\n     *  ```\r\n     */\r\n    trim:function (str) {\r\n        return str.replace(/(^[ \\t\\n\\r]+)|([ \\t\\n\\r]+$)/g, '');\r\n    },\r\n\r\n    /**\r\n     * 将字符串str以','分隔成数组后，将该数组转换成哈希对象， 其生成的hash对象的key为数组中的元素， value为1\r\n     * @method listToMap\r\n     * @warning 该方法在生成的hash对象中，会为每一个key同时生成一个另一个全大写的key。\r\n     * @param { String } str 该字符串将被以','分割为数组， 然后进行转化\r\n     * @return { Object } 转化之后的hash对象\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * //output: Object {UEdtior: 1, UEDTIOR: 1, Hello: 1, HELLO: 1}\r\n     * console.log( UE.utils.listToMap( 'UEdtior,Hello' ) );\r\n     *\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 将字符串数组转换成哈希对象， 其生成的hash对象的key为数组中的元素， value为1\r\n     * @method listToMap\r\n     * @warning 该方法在生成的hash对象中，会为每一个key同时生成一个另一个全大写的key。\r\n     * @param { Array } arr 字符串数组\r\n     * @return { Object } 转化之后的hash对象\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * //output: Object {UEdtior: 1, UEDTIOR: 1, Hello: 1, HELLO: 1}\r\n     * console.log( UE.utils.listToMap( [ 'UEdtior', 'Hello' ] ) );\r\n     *\r\n     * ```\r\n     */\r\n    listToMap:function (list) {\r\n        if (!list)return {};\r\n        list = utils.isArray(list) ? list : list.split(',');\r\n        for (var i = 0, ci, obj = {}; ci = list[i++];) {\r\n            obj[ci.toUpperCase()] = obj[ci] = 1;\r\n        }\r\n        return obj;\r\n    },\r\n\r\n    /**\r\n     * 将str中的html符号转义,将转义“'，&，<，\"，>”五个字符\r\n     * @method unhtml\r\n     * @param { String } str 需要转义的字符串\r\n     * @return { String } 转义后的字符串\r\n     * @example\r\n     * ```javascript\r\n     * var html = '<body>&</body>';\r\n     *\r\n     * //output: &lt;body&gt;&amp;&lt;/body&gt;\r\n     * console.log( UE.utils.unhtml( html ) );\r\n     *\r\n     * ```\r\n     */\r\n    unhtml:function (str, reg) {\r\n        return str ? str.replace(reg || /[&<\">'](?:(amp|lt|quot|gt|#39|nbsp|#\\d+);)?/g, function (a, b) {\r\n            if (b) {\r\n                return a;\r\n            } else {\r\n                return {\r\n                    '<':'&lt;',\r\n                    '&':'&amp;',\r\n                    '\"':'&quot;',\r\n                    '>':'&gt;',\r\n                    \"'\":'&#39;'\r\n                }[a]\r\n            }\r\n\r\n        }) : '';\r\n    },\r\n    /**\r\n     * 将url中的html字符转义， 仅转义  ', \", <, > 四个字符\r\n     * @param  { String } str 需要转义的字符串\r\n     * @param  { RegExp } reg 自定义的正则\r\n     * @return { String }     转义后的字符串\r\n     */\r\n    unhtmlForUrl:function (str, reg) {\r\n        return str ? str.replace(reg || /[<\">']/g, function (a) {\r\n            return {\r\n                '<':'&lt;',\r\n                '&':'&amp;',\r\n                '\"':'&quot;',\r\n                '>':'&gt;',\r\n                \"'\":'&#39;'\r\n            }[a]\r\n\r\n        }) : '';\r\n    },\r\n\r\n    /**\r\n     * 将str中的转义字符还原成html字符\r\n     * @see UE.utils.unhtml(String);\r\n     * @method html\r\n     * @param { String } str 需要逆转义的字符串\r\n     * @return { String } 逆转义后的字符串\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * var str = '&lt;body&gt;&amp;&lt;/body&gt;';\r\n     *\r\n     * //output: <body>&</body>\r\n     * console.log( UE.utils.html( str ) );\r\n     *\r\n     * ```\r\n     */\r\n    html:function (str) {\r\n        return str ? str.replace(/&((g|l|quo)t|amp|#39|nbsp);/g, function (m) {\r\n            return {\r\n                '&lt;':'<',\r\n                '&amp;':'&',\r\n                '&quot;':'\"',\r\n                '&gt;':'>',\r\n                '&#39;':\"'\",\r\n                '&nbsp;':' '\r\n            }[m]\r\n        }) : '';\r\n    },\r\n\r\n    /**\r\n     * 将css样式转换为驼峰的形式\r\n     * @method cssStyleToDomStyle\r\n     * @param { String } cssName 需要转换的css样式名\r\n     * @return { String } 转换成驼峰形式后的css样式名\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * var str = 'border-top';\r\n     *\r\n     * //output: borderTop\r\n     * console.log( UE.utils.cssStyleToDomStyle( str ) );\r\n     *\r\n     * ```\r\n     */\r\n    cssStyleToDomStyle:function () {\r\n        var test = document.createElement('div').style,\r\n            cache = {\r\n                'float':test.cssFloat != undefined ? 'cssFloat' : test.styleFloat != undefined ? 'styleFloat' : 'float'\r\n            };\r\n\r\n        return function (cssName) {\r\n            return cache[cssName] || (cache[cssName] = cssName.toLowerCase().replace(/-./g, function (match) {\r\n                return match.charAt(1).toUpperCase();\r\n            }));\r\n        };\r\n    }(),\r\n\r\n    /**\r\n     * 动态加载文件到doc中\r\n     * @method loadFile\r\n     * @param { DomDocument } document 需要加载资源文件的文档对象\r\n     * @param { Object } options 加载资源文件的属性集合， 取值请参考代码示例\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * UE.utils.loadFile( document, {\r\n     *     src:\"test.js\",\r\n     *     tag:\"script\",\r\n     *     type:\"text/javascript\",\r\n     *     defer:\"defer\"\r\n     * } );\r\n     *\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 动态加载文件到doc中，加载成功后执行的回调函数fn\r\n     * @method loadFile\r\n     * @param { DomDocument } document 需要加载资源文件的文档对象\r\n     * @param { Object } options 加载资源文件的属性集合， 该集合支持的值是script标签和style标签支持的所有属性。\r\n     * @param { Function } fn 资源文件加载成功之后执行的回调\r\n     * @warning 对于在同一个文档中多次加载同一URL的文件， 该方法会在第一次加载之后缓存该请求，\r\n     *           在此之后的所有同一URL的请求， 将会直接触发回调。\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * UE.utils.loadFile( document, {\r\n     *     src:\"test.js\",\r\n     *     tag:\"script\",\r\n     *     type:\"text/javascript\",\r\n     *     defer:\"defer\"\r\n     * }, function () {\r\n     *     console.log('加载成功');\r\n     * } );\r\n     *\r\n     * ```\r\n     */\r\n    loadFile:function () {\r\n        var tmpList = [];\r\n\r\n        function getItem(doc, obj) {\r\n            try {\r\n                for (var i = 0, ci; ci = tmpList[i++];) {\r\n                    if (ci.doc === doc && ci.url == (obj.src || obj.href)) {\r\n                        return ci;\r\n                    }\r\n                }\r\n            } catch (e) {\r\n                return null;\r\n            }\r\n\r\n        }\r\n\r\n        return function (doc, obj, fn) {\r\n            var item = getItem(doc, obj);\r\n            if (item) {\r\n                if (item.ready) {\r\n                    fn && fn();\r\n                } else {\r\n                    item.funs.push(fn)\r\n                }\r\n                return;\r\n            }\r\n            tmpList.push({\r\n                doc:doc,\r\n                url:obj.src || obj.href,\r\n                funs:[fn]\r\n            });\r\n            if (!doc.body) {\r\n                var html = [];\r\n                for (var p in obj) {\r\n                    if (p == 'tag')continue;\r\n                    html.push(p + '=\"' + obj[p] + '\"')\r\n                }\r\n                doc.write('<' + obj.tag + ' ' + html.join(' ') + ' ></' + obj.tag + '>');\r\n                return;\r\n            }\r\n            if (obj.id && doc.getElementById(obj.id)) {\r\n                return;\r\n            }\r\n            var element = doc.createElement(obj.tag);\r\n            delete obj.tag;\r\n            for (var p in obj) {\r\n                element.setAttribute(p, obj[p]);\r\n            }\r\n            element.onload = element.onreadystatechange = function () {\r\n                if (!this.readyState || /loaded|complete/.test(this.readyState)) {\r\n                    item = getItem(doc, obj);\r\n                    if (item.funs.length > 0) {\r\n                        item.ready = 1;\r\n                        for (var fi; fi = item.funs.pop();) {\r\n                            fi();\r\n                        }\r\n                    }\r\n                    element.onload = element.onreadystatechange = null;\r\n                }\r\n            };\r\n            element.onerror = function () {\r\n                throw Error('The load ' + (obj.href || obj.src) + ' fails,check the url settings of file ueditor.config.js ')\r\n            };\r\n            doc.getElementsByTagName(\"head\")[0].appendChild(element);\r\n        }\r\n    }(),\r\n\r\n    /**\r\n     * 判断obj对象是否为空\r\n     * @method isEmptyObject\r\n     * @param { * } obj 需要判断的对象\r\n     * @remind 如果判断的对象是NULL， 将直接返回true， 如果是数组且为空， 返回true， 如果是字符串， 且字符串为空，\r\n     *          返回true， 如果是普通对象， 且该对象没有任何实例属性， 返回true\r\n     * @return { Boolean } 对象是否为空\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * //output: true\r\n     * console.log( UE.utils.isEmptyObject( {} ) );\r\n     *\r\n     * //output: true\r\n     * console.log( UE.utils.isEmptyObject( [] ) );\r\n     *\r\n     * //output: true\r\n     * console.log( UE.utils.isEmptyObject( \"\" ) );\r\n     *\r\n     * //output: false\r\n     * console.log( UE.utils.isEmptyObject( { key: 1 } ) );\r\n     *\r\n     * //output: false\r\n     * console.log( UE.utils.isEmptyObject( [1] ) );\r\n     *\r\n     * //output: false\r\n     * console.log( UE.utils.isEmptyObject( \"1\" ) );\r\n     *\r\n     * ```\r\n     */\r\n    isEmptyObject:function (obj) {\r\n        if (obj == null) return true;\r\n        if (this.isArray(obj) || this.isString(obj)) return obj.length === 0;\r\n        for (var key in obj) if (obj.hasOwnProperty(key)) return false;\r\n        return true;\r\n    },\r\n\r\n    /**\r\n     * 把rgb格式的颜色值转换成16进制格式\r\n     * @method fixColor\r\n     * @param { String } rgb格式的颜色值\r\n     * @param { String }\r\n     * @example\r\n     * rgb(255,255,255)  => \"#ffffff\"\r\n     */\r\n    fixColor:function (name, value) {\r\n        if (/color/i.test(name) && /rgba?/.test(value)) {\r\n            var array = value.split(\",\");\r\n            if (array.length > 3)\r\n                return \"\";\r\n            value = \"#\";\r\n            for (var i = 0, color; color = array[i++];) {\r\n                color = parseInt(color.replace(/[^\\d]/gi, ''), 10).toString(16);\r\n                value += color.length == 1 ? \"0\" + color : color;\r\n            }\r\n            value = value.toUpperCase();\r\n        }\r\n        return  value;\r\n    },\r\n    /**\r\n     * 只针对border,padding,margin做了处理，因为性能问题\r\n     * @public\r\n     * @function\r\n     * @param {String}    val style字符串\r\n     */\r\n    optCss:function (val) {\r\n        var padding, margin, border;\r\n        val = val.replace(/(padding|margin|border)\\-([^:]+):([^;]+);?/gi, function (str, key, name, val) {\r\n            if (val.split(' ').length == 1) {\r\n                switch (key) {\r\n                    case 'padding':\r\n                        !padding && (padding = {});\r\n                        padding[name] = val;\r\n                        return '';\r\n                    case 'margin':\r\n                        !margin && (margin = {});\r\n                        margin[name] = val;\r\n                        return '';\r\n                    case 'border':\r\n                        return val == 'initial' ? '' : str;\r\n                }\r\n            }\r\n            return str;\r\n        });\r\n\r\n        function opt(obj, name) {\r\n            if (!obj) {\r\n                return '';\r\n            }\r\n            var t = obj.top , b = obj.bottom, l = obj.left, r = obj.right, val = '';\r\n            if (!t || !l || !b || !r) {\r\n                for (var p in obj) {\r\n                    val += ';' + name + '-' + p + ':' + obj[p] + ';';\r\n                }\r\n            } else {\r\n                val += ';' + name + ':' +\r\n                    (t == b && b == l && l == r ? t :\r\n                        t == b && l == r ? (t + ' ' + l) :\r\n                            l == r ? (t + ' ' + l + ' ' + b) : (t + ' ' + r + ' ' + b + ' ' + l)) + ';'\r\n            }\r\n            return val;\r\n        }\r\n\r\n        val += opt(padding, 'padding') + opt(margin, 'margin');\r\n        return val.replace(/^[ \\n\\r\\t;]*|[ \\n\\r\\t]*$/, '').replace(/;([ \\n\\r\\t]+)|\\1;/g, ';')\r\n            .replace(/(&((l|g)t|quot|#39))?;{2,}/g, function (a, b) {\r\n                return b ? b + \";;\" : ';'\r\n            });\r\n    },\r\n\r\n    /**\r\n     * 克隆对象\r\n     * @method clone\r\n     * @param { Object } source 源对象\r\n     * @return { Object } source的一个副本\r\n     */\r\n\r\n    /**\r\n     * 深度克隆对象，将source的属性克隆到target对象， 会覆盖target重名的属性。\r\n     * @method clone\r\n     * @param { Object } source 源对象\r\n     * @param { Object } target 目标对象\r\n     * @return { Object } 附加了source对象所有属性的target对象\r\n     */\r\n    clone:function (source, target) {\r\n        var tmp;\r\n        target = target || {};\r\n        for (var i in source) {\r\n            if (source.hasOwnProperty(i)) {\r\n                tmp = source[i];\r\n                if (typeof tmp == 'object') {\r\n                    target[i] = utils.isArray(tmp) ? [] : {};\r\n                    utils.clone(source[i], target[i])\r\n                } else {\r\n                    target[i] = tmp;\r\n                }\r\n            }\r\n        }\r\n        return target;\r\n    },\r\n\r\n    /**\r\n     * 把cm／pt为单位的值转换为px为单位的值\r\n     * @method transUnitToPx\r\n     * @param { String } 待转换的带单位的字符串\r\n     * @return { String } 转换为px为计量单位的值的字符串\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * //output: 500px\r\n     * console.log( UE.utils.transUnitToPx( '20cm' ) );\r\n     *\r\n     * //output: 27px\r\n     * console.log( UE.utils.transUnitToPx( '20pt' ) );\r\n     *\r\n     * ```\r\n     */\r\n    transUnitToPx:function (val) {\r\n        if (!/(pt|cm)/.test(val)) {\r\n            return val\r\n        }\r\n        var unit;\r\n        val.replace(/([\\d.]+)(\\w+)/, function (str, v, u) {\r\n            val = v;\r\n            unit = u;\r\n        });\r\n        switch (unit) {\r\n            case 'cm':\r\n                val = parseFloat(val) * 25;\r\n                break;\r\n            case 'pt':\r\n                val = Math.round(parseFloat(val) * 96 / 72);\r\n        }\r\n        return val + (val ? 'px' : '');\r\n    },\r\n\r\n    /**\r\n     * 在dom树ready之后执行给定的回调函数\r\n     * @method domReady\r\n     * @remind 如果在执行该方法的时候， dom树已经ready， 那么回调函数将立刻执行\r\n     * @param { Function } fn dom树ready之后的回调函数\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * UE.utils.domReady( function () {\r\n     *\r\n     *     console.log('123');\r\n     *\r\n     * } );\r\n     *\r\n     * ```\r\n     */\r\n    domReady:function () {\r\n\r\n        var fnArr = [];\r\n\r\n        function doReady(doc) {\r\n            //确保onready只执行一次\r\n            doc.isReady = true;\r\n            for (var ci; ci = fnArr.pop(); ci()) {\r\n            }\r\n        }\r\n\r\n        return function (onready, win) {\r\n            win = win || window;\r\n            var doc = win.document;\r\n            onready && fnArr.push(onready);\r\n            if (doc.readyState === \"complete\") {\r\n                doReady(doc);\r\n            } else {\r\n                doc.isReady && doReady(doc);\r\n                if (browser.ie && browser.version != 11) {\r\n                    (function () {\r\n                        if (doc.isReady) return;\r\n                        try {\r\n                            doc.documentElement.doScroll(\"left\");\r\n                        } catch (error) {\r\n                            setTimeout(arguments.callee, 0);\r\n                            return;\r\n                        }\r\n                        doReady(doc);\r\n                    })();\r\n                    win.attachEvent('onload', function () {\r\n                        doReady(doc)\r\n                    });\r\n                } else {\r\n                    doc.addEventListener(\"DOMContentLoaded\", function () {\r\n                        doc.removeEventListener(\"DOMContentLoaded\", arguments.callee, false);\r\n                        doReady(doc);\r\n                    }, false);\r\n                    win.addEventListener('load', function () {\r\n                        doReady(doc)\r\n                    }, false);\r\n                }\r\n            }\r\n\r\n        }\r\n    }(),\r\n\r\n    /**\r\n     * 动态添加css样式\r\n     * @method cssRule\r\n     * @param { String } 节点名称\r\n     * @grammar UE.utils.cssRule('添加的样式的节点名称',['样式'，'放到哪个document上'])\r\n     * @grammar UE.utils.cssRule('body','body{background:#ccc}') => null  //给body添加背景颜色\r\n     * @grammar UE.utils.cssRule('body') =>样式的字符串  //取得key值为body的样式的内容,如果没有找到key值先关的样式将返回空，例如刚才那个背景颜色，将返回 body{background:#ccc}\r\n     * @grammar UE.utils.cssRule('body',document) => 返回指定key的样式，并且指定是哪个document\r\n     * @grammar UE.utils.cssRule('body','') =>null //清空给定的key值的背景颜色\r\n     */\r\n    cssRule:browser.ie && browser.version != 11 ? function (key, style, doc) {\r\n        var indexList, index;\r\n        if(style === undefined || style && style.nodeType && style.nodeType == 9){\r\n            //获取样式\r\n            doc = style && style.nodeType && style.nodeType == 9 ? style : (doc || document);\r\n            indexList = doc.indexList || (doc.indexList = {});\r\n            index = indexList[key];\r\n            if(index !==  undefined){\r\n                return doc.styleSheets[index].cssText\r\n            }\r\n            return undefined;\r\n        }\r\n        doc = doc || document;\r\n        indexList = doc.indexList || (doc.indexList = {});\r\n        index = indexList[key];\r\n        //清除样式\r\n        if(style === ''){\r\n            if(index!== undefined){\r\n                doc.styleSheets[index].cssText = '';\r\n                delete indexList[key];\r\n                return true\r\n            }\r\n            return false;\r\n        }\r\n\r\n        //添加样式\r\n        if(index!== undefined){\r\n            sheetStyle =  doc.styleSheets[index];\r\n        }else{\r\n            sheetStyle = doc.createStyleSheet('', index = doc.styleSheets.length);\r\n            indexList[key] = index;\r\n        }\r\n        sheetStyle.cssText = style;\r\n    }: function (key, style, doc) {\r\n        var head, node;\r\n        if(style === undefined || style && style.nodeType && style.nodeType == 9){\r\n            //获取样式\r\n            doc = style && style.nodeType && style.nodeType == 9 ? style : (doc || document);\r\n            node = doc.getElementById(key);\r\n            return node ? node.innerHTML : undefined;\r\n        }\r\n        doc = doc || document;\r\n        node = doc.getElementById(key);\r\n\r\n        //清除样式\r\n        if(style === ''){\r\n            if(node){\r\n                node.parentNode.removeChild(node);\r\n                return true\r\n            }\r\n            return false;\r\n        }\r\n\r\n        //添加样式\r\n        if(node){\r\n            node.innerHTML = style;\r\n        }else{\r\n            node = doc.createElement('style');\r\n            node.id = key;\r\n            node.innerHTML = style;\r\n            doc.getElementsByTagName('head')[0].appendChild(node);\r\n        }\r\n    },\r\n    sort:function(array,compareFn){\r\n        compareFn = compareFn || function(item1, item2){ return item1.localeCompare(item2);};\r\n        for(var i= 0,len = array.length; i<len; i++){\r\n            for(var j = i,length = array.length; j<length; j++){\r\n                if(compareFn(array[i], array[j]) > 0){\r\n                    var t = array[i];\r\n                    array[i] = array[j];\r\n                    array[j] = t;\r\n                }\r\n            }\r\n        }\r\n        return array;\r\n    },\r\n    serializeParam:function (json) {\r\n        var strArr = [];\r\n        for (var i in json) {\r\n            //忽略默认的几个参数\r\n            if(i==\"method\" || i==\"timeout\" || i==\"async\") continue;\r\n            //传递过来的对象和函数不在提交之列\r\n            if (!((typeof json[i]).toLowerCase() == \"function\" || (typeof json[i]).toLowerCase() == \"object\")) {\r\n                strArr.push( encodeURIComponent(i) + \"=\"+encodeURIComponent(json[i]) );\r\n            } else if (utils.isArray(json[i])) {\r\n                //支持传数组内容\r\n                for(var j = 0; j < json[i].length; j++) {\r\n                    strArr.push( encodeURIComponent(i) + \"[]=\"+encodeURIComponent(json[i][j]) );\r\n                }\r\n            }\r\n        }\r\n        return strArr.join(\"&\");\r\n    },\r\n    formatUrl:function (url) {\r\n        var u = url.replace(/&&/g, '&');\r\n        u = u.replace(/\\?&/g, '?');\r\n        u = u.replace(/&$/g, '');\r\n        u = u.replace(/&#/g, '#');\r\n        u = u.replace(/&+/g, '&');\r\n        return u;\r\n    },\r\n    isCrossDomainUrl:function (url) {\r\n        var a = document.createElement('a');\r\n        a.href = url;\r\n        if (browser.ie) {\r\n            a.href = a.href;\r\n        }\r\n        return !(a.protocol == location.protocol && a.hostname == location.hostname &&\r\n        (a.port == location.port || (a.port == '80' && location.port == '') || (a.port == '' && location.port == '80')));\r\n    },\r\n    clearEmptyAttrs : function(obj){\r\n        for(var p in obj){\r\n            if(obj[p] === ''){\r\n                delete obj[p]\r\n            }\r\n        }\r\n        return obj;\r\n    },\r\n    str2json : function(s){\r\n\r\n        if (!utils.isString(s)) return null;\r\n        if (window.JSON) {\r\n            return JSON.parse(s);\r\n        } else {\r\n            return (new Function(\"return \" + utils.trim(s || '')))();\r\n        }\r\n\r\n    },\r\n    json2str : (function(){\r\n\r\n        if (window.JSON) {\r\n\r\n            return JSON.stringify;\r\n\r\n        } else {\r\n\r\n            var escapeMap = {\r\n                \"\\b\": '\\\\b',\r\n                \"\\t\": '\\\\t',\r\n                \"\\n\": '\\\\n',\r\n                \"\\f\": '\\\\f',\r\n                \"\\r\": '\\\\r',\r\n                '\"' : '\\\\\"',\r\n                \"\\\\\": '\\\\\\\\'\r\n            };\r\n\r\n            function encodeString(source) {\r\n                if (/[\"\\\\\\x00-\\x1f]/.test(source)) {\r\n                    source = source.replace(\r\n                        /[\"\\\\\\x00-\\x1f]/g,\r\n                        function (match) {\r\n                            var c = escapeMap[match];\r\n                            if (c) {\r\n                                return c;\r\n                            }\r\n                            c = match.charCodeAt();\r\n                            return \"\\\\u00\"\r\n                            + Math.floor(c / 16).toString(16)\r\n                            + (c % 16).toString(16);\r\n                        });\r\n                }\r\n                return '\"' + source + '\"';\r\n            }\r\n\r\n            function encodeArray(source) {\r\n                var result = [\"[\"],\r\n                    l = source.length,\r\n                    preComma, i, item;\r\n\r\n                for (i = 0; i < l; i++) {\r\n                    item = source[i];\r\n\r\n                    switch (typeof item) {\r\n                        case \"undefined\":\r\n                        case \"function\":\r\n                        case \"unknown\":\r\n                            break;\r\n                        default:\r\n                            if(preComma) {\r\n                                result.push(',');\r\n                            }\r\n                            result.push(utils.json2str(item));\r\n                            preComma = 1;\r\n                    }\r\n                }\r\n                result.push(\"]\");\r\n                return result.join(\"\");\r\n            }\r\n\r\n            function pad(source) {\r\n                return source < 10 ? '0' + source : source;\r\n            }\r\n\r\n            function encodeDate(source){\r\n                return '\"' + source.getFullYear() + \"-\"\r\n                + pad(source.getMonth() + 1) + \"-\"\r\n                + pad(source.getDate()) + \"T\"\r\n                + pad(source.getHours()) + \":\"\r\n                + pad(source.getMinutes()) + \":\"\r\n                + pad(source.getSeconds()) + '\"';\r\n            }\r\n\r\n            return function (value) {\r\n                switch (typeof value) {\r\n                    case 'undefined':\r\n                        return 'undefined';\r\n\r\n                    case 'number':\r\n                        return isFinite(value) ? String(value) : \"null\";\r\n\r\n                    case 'string':\r\n                        return encodeString(value);\r\n\r\n                    case 'boolean':\r\n                        return String(value);\r\n\r\n                    default:\r\n                        if (value === null) {\r\n                            return 'null';\r\n                        } else if (utils.isArray(value)) {\r\n                            return encodeArray(value);\r\n                        } else if (utils.isDate(value)) {\r\n                            return encodeDate(value);\r\n                        } else {\r\n                            var result = ['{'],\r\n                                encode = utils.json2str,\r\n                                preComma,\r\n                                item;\r\n\r\n                            for (var key in value) {\r\n                                if (Object.prototype.hasOwnProperty.call(value, key)) {\r\n                                    item = value[key];\r\n                                    switch (typeof item) {\r\n                                        case 'undefined':\r\n                                        case 'unknown':\r\n                                        case 'function':\r\n                                            break;\r\n                                        default:\r\n                                            if (preComma) {\r\n                                                result.push(',');\r\n                                            }\r\n                                            preComma = 1;\r\n                                            result.push(encode(key) + ':' + encode(item));\r\n                                    }\r\n                                }\r\n                            }\r\n                            result.push('}');\r\n                            return result.join('');\r\n                        }\r\n                }\r\n            };\r\n        }\r\n\r\n    })()\r\n\r\n};\r\n/**\r\n * 判断给定的对象是否是字符串\r\n * @method isString\r\n * @param { * } object 需要判断的对象\r\n * @return { Boolean } 给定的对象是否是字符串\r\n */\r\n\r\n/**\r\n * 判断给定的对象是否是数组\r\n * @method isArray\r\n * @param { * } object 需要判断的对象\r\n * @return { Boolean } 给定的对象是否是数组\r\n */\r\n\r\n/**\r\n * 判断给定的对象是否是一个Function\r\n * @method isFunction\r\n * @param { * } object 需要判断的对象\r\n * @return { Boolean } 给定的对象是否是Function\r\n */\r\n\r\n/**\r\n * 判断给定的对象是否是Number\r\n * @method isNumber\r\n * @param { * } object 需要判断的对象\r\n * @return { Boolean } 给定的对象是否是Number\r\n */\r\n\r\n/**\r\n * 判断给定的对象是否是一个正则表达式\r\n * @method isRegExp\r\n * @param { * } object 需要判断的对象\r\n * @return { Boolean } 给定的对象是否是正则表达式\r\n */\r\n\r\n/**\r\n * 判断给定的对象是否是一个普通对象\r\n * @method isObject\r\n * @param { * } object 需要判断的对象\r\n * @return { Boolean } 给定的对象是否是普通对象\r\n */\r\nutils.each(['String', 'Function', 'Array', 'Number', 'RegExp', 'Object', 'Date'], function (v) {\r\n    UE.utils['is' + v] = function (obj) {\r\n        return Object.prototype.toString.apply(obj) == '[object ' + v + ']';\r\n    }\r\n});\r\n\n\n// core/EventBase.js\n/**\r\n * UE采用的事件基类\r\n * @file\r\n * @module UE\r\n * @class EventBase\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * UEditor公用空间，UEditor所有的功能都挂载在该空间下\r\n * @unfile\r\n * @module UE\r\n */\r\n\r\n/**\r\n * UE采用的事件基类，继承此类的对应类将获取addListener,removeListener,fireEvent方法。\r\n * 在UE中，Editor以及所有ui实例都继承了该类，故可以在对应的ui对象以及editor对象上使用上述方法。\r\n * @unfile\r\n * @module UE\r\n * @class EventBase\r\n */\r\n\r\n/**\r\n * 通过此构造器，子类可以继承EventBase获取事件监听的方法\r\n * @constructor\r\n * @example\r\n * ```javascript\r\n * UE.EventBase.call(editor);\r\n * ```\r\n */\r\nvar EventBase = UE.EventBase = function () {};\r\n\r\nEventBase.prototype = {\r\n\r\n    /**\r\n     * 注册事件监听器\r\n     * @method addListener\r\n     * @param { String } types 监听的事件名称，同时监听多个事件使用空格分隔\r\n     * @param { Function } fn 监听的事件被触发时，会执行该回调函数\r\n     * @waining 事件被触发时，监听的函数假如返回的值恒等于true，回调函数的队列中后面的函数将不执行\r\n     * @example\r\n     * ```javascript\r\n     * editor.addListener('selectionchange',function(){\r\n     *      console.log(\"选区已经变化！\");\r\n     * })\r\n     * editor.addListener('beforegetcontent aftergetcontent',function(type){\r\n     *         if(type == 'beforegetcontent'){\r\n     *             //do something\r\n     *         }else{\r\n     *             //do something\r\n     *         }\r\n     *         console.log(this.getContent) // this是注册的事件的编辑器实例\r\n     * })\r\n     * ```\r\n     * @see UE.EventBase:fireEvent(String)\r\n     */\r\n    addListener:function (types, listener) {\r\n        types = utils.trim(types).split(/\\s+/);\r\n        for (var i = 0, ti; ti = types[i++];) {\r\n            getListener(this, ti, true).push(listener);\r\n        }\r\n    },\r\n\r\n    on : function(types, listener){\r\n      return this.addListener(types,listener);\r\n    },\r\n    off : function(types, listener){\r\n        return this.removeListener(types, listener)\r\n    },\r\n    trigger:function(){\r\n        return this.fireEvent.apply(this,arguments);\r\n    },\r\n    /**\r\n     * 移除事件监听器\r\n     * @method removeListener\r\n     * @param { String } types 移除的事件名称，同时移除多个事件使用空格分隔\r\n     * @param { Function } fn 移除监听事件的函数引用\r\n     * @example\r\n     * ```javascript\r\n     * //changeCallback为方法体\r\n     * editor.removeListener(\"selectionchange\",changeCallback);\r\n     * ```\r\n     */\r\n    removeListener:function (types, listener) {\r\n        types = utils.trim(types).split(/\\s+/);\r\n        for (var i = 0, ti; ti = types[i++];) {\r\n            utils.removeItem(getListener(this, ti) || [], listener);\r\n        }\r\n    },\r\n\r\n    /**\r\n     * 触发事件\r\n     * @method fireEvent\r\n     * @param { String } types 触发的事件名称，同时触发多个事件使用空格分隔\r\n     * @remind 该方法会触发addListener\r\n     * @return { * } 返回触发事件的队列中，最后执行的回调函数的返回值\r\n     * @example\r\n     * ```javascript\r\n     * editor.fireEvent(\"selectionchange\");\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 触发事件\r\n     * @method fireEvent\r\n     * @param { String } types 触发的事件名称，同时触发多个事件使用空格分隔\r\n     * @param { *... } options 可选参数，可以传入一个或多个参数，会传给事件触发的回调函数\r\n     * @return { * } 返回触发事件的队列中，最后执行的回调函数的返回值\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * editor.addListener( \"selectionchange\", function ( type, arg1, arg2 ) {\r\n     *\r\n     *     console.log( arg1 + \" \" + arg2 );\r\n     *\r\n     * } );\r\n     *\r\n     * //触发selectionchange事件， 会执行上面的事件监听器\r\n     * //output: Hello World\r\n     * editor.fireEvent(\"selectionchange\", \"Hello\", \"World\");\r\n     * ```\r\n     */\r\n    fireEvent:function () {\r\n        var types = arguments[0];\r\n        types = utils.trim(types).split(' ');\r\n        for (var i = 0, ti; ti = types[i++];) {\r\n            var listeners = getListener(this, ti),\r\n                r, t, k;\r\n            if (listeners) {\r\n                k = listeners.length;\r\n                while (k--) {\r\n                    if(!listeners[k])continue;\r\n                    t = listeners[k].apply(this, arguments);\r\n                    if(t === true){\r\n                        return t;\r\n                    }\r\n                    if (t !== undefined) {\r\n                        r = t;\r\n                    }\r\n                }\r\n            }\r\n            if (t = this['on' + ti.toLowerCase()]) {\r\n                r = t.apply(this, arguments);\r\n            }\r\n        }\r\n        return r;\r\n    }\r\n};\r\n/**\r\n * 获得对象所拥有监听类型的所有监听器\r\n * @unfile\r\n * @module UE\r\n * @since 1.2.6.1\r\n * @method getListener\r\n * @public\r\n * @param { Object } obj  查询监听器的对象\r\n * @param { String } type 事件类型\r\n * @param { Boolean } force  为true且当前所有type类型的侦听器不存在时，创建一个空监听器数组\r\n * @return { Array } 监听器数组\r\n */\r\nfunction getListener(obj, type, force) {\r\n    var allListeners;\r\n    type = type.toLowerCase();\r\n    return ( ( allListeners = ( obj.__allListeners || force && ( obj.__allListeners = {} ) ) )\r\n        && ( allListeners[type] || force && ( allListeners[type] = [] ) ) );\r\n}\r\n\r\n\n\n// core/dtd.js\n///import editor.js\r\n///import core/dom/dom.js\r\n///import core/utils.js\r\n/**\r\n * dtd html语义化的体现类\r\n * @constructor\r\n * @namespace dtd\r\n */\r\nvar dtd = dom.dtd = (function() {\r\n    function _( s ) {\r\n        for (var k in s) {\r\n            s[k.toUpperCase()] = s[k];\r\n        }\r\n        return s;\r\n    }\r\n    var X = utils.extend2;\r\n    var A = _({isindex:1,fieldset:1}),\r\n        B = _({input:1,button:1,select:1,textarea:1,label:1}),\r\n        C = X( _({a:1}), B ),\r\n        D = X( {iframe:1}, C ),\r\n        E = _({hr:1,ul:1,menu:1,div:1,blockquote:1,noscript:1,table:1,center:1,address:1,dir:1,pre:1,h5:1,dl:1,h4:1,noframes:1,h6:1,ol:1,h1:1,h3:1,h2:1}),\r\n        F = _({ins:1,del:1,script:1,style:1}),\r\n        G = X( _({b:1,acronym:1,bdo:1,'var':1,'#':1,abbr:1,code:1,br:1,i:1,cite:1,kbd:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,dfn:1,span:1}), F ),\r\n        H = X( _({sub:1,img:1,embed:1,object:1,sup:1,basefont:1,map:1,applet:1,font:1,big:1,small:1}), G ),\r\n        I = X( _({p:1}), H ),\r\n        J = X( _({iframe:1}), H, B ),\r\n        K = _({img:1,embed:1,noscript:1,br:1,kbd:1,center:1,button:1,basefont:1,h5:1,h4:1,samp:1,h6:1,ol:1,h1:1,h3:1,h2:1,form:1,font:1,'#':1,select:1,menu:1,ins:1,abbr:1,label:1,code:1,table:1,script:1,cite:1,input:1,iframe:1,strong:1,textarea:1,noframes:1,big:1,small:1,span:1,hr:1,sub:1,bdo:1,'var':1,div:1,object:1,sup:1,strike:1,dir:1,map:1,dl:1,applet:1,del:1,isindex:1,fieldset:1,ul:1,b:1,acronym:1,a:1,blockquote:1,i:1,u:1,s:1,tt:1,address:1,q:1,pre:1,p:1,em:1,dfn:1}),\r\n\r\n        L = X( _({a:0}), J ),//a不能被切开，所以把他\r\n        M = _({tr:1}),\r\n        N = _({'#':1}),\r\n        O = X( _({param:1}), K ),\r\n        P = X( _({form:1}), A, D, E, I ),\r\n        Q = _({li:1,ol:1,ul:1}),\r\n        R = _({style:1,script:1}),\r\n        S = _({base:1,link:1,meta:1,title:1}),\r\n        T = X( S, R ),\r\n        U = _({head:1,body:1}),\r\n        V = _({html:1});\r\n\r\n    var block = _({address:1,blockquote:1,center:1,dir:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,isindex:1,menu:1,noframes:1,ol:1,p:1,pre:1,table:1,ul:1}),\r\n\r\n        empty =  _({area:1,base:1,basefont:1,br:1,col:1,command:1,dialog:1,embed:1,hr:1,img:1,input:1,isindex:1,keygen:1,link:1,meta:1,param:1,source:1,track:1,wbr:1});\r\n\r\n    return  _({\r\n\r\n        // $ 表示自定的属性\r\n\r\n        // body外的元素列表.\r\n        $nonBodyContent: X( V, U, S ),\r\n\r\n        //块结构元素列表\r\n        $block : block,\r\n\r\n        //内联元素列表\r\n        $inline : L,\r\n\r\n        $inlineWithA : X(_({a:1}),L),\r\n\r\n        $body : X( _({script:1,style:1}), block ),\r\n\r\n        $cdata : _({script:1,style:1}),\r\n\r\n        //自闭和元素\r\n        $empty : empty,\r\n\r\n        //不是自闭合，但不能让range选中里边\r\n        $nonChild : _({iframe:1,textarea:1}),\r\n        //列表元素列表\r\n        $listItem : _({dd:1,dt:1,li:1}),\r\n\r\n        //列表根元素列表\r\n        $list: _({ul:1,ol:1,dl:1}),\r\n\r\n        //不能认为是空的元素\r\n        $isNotEmpty : _({table:1,ul:1,ol:1,dl:1,iframe:1,area:1,base:1,col:1,hr:1,img:1,embed:1,input:1,link:1,meta:1,param:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1}),\r\n\r\n        //如果没有子节点就可以删除的元素列表，像span,a\r\n        $removeEmpty : _({a:1,abbr:1,acronym:1,address:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,s:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,'var':1}),\r\n\r\n        $removeEmptyBlock : _({'p':1,'div':1}),\r\n\r\n        //在table元素里的元素列表\r\n        $tableContent : _({caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1,table:1}),\r\n        //不转换的标签\r\n        $notTransContent : _({pre:1,script:1,style:1,textarea:1}),\r\n        html: U,\r\n        head: T,\r\n        style: N,\r\n        script: N,\r\n        body: P,\r\n        base: {},\r\n        link: {},\r\n        meta: {},\r\n        title: N,\r\n        col : {},\r\n        tr : _({td:1,th:1}),\r\n        img : {},\r\n        embed: {},\r\n        colgroup : _({thead:1,col:1,tbody:1,tr:1,tfoot:1}),\r\n        noscript : P,\r\n        td : P,\r\n        br : {},\r\n        th : P,\r\n        center : P,\r\n        kbd : L,\r\n        button : X( I, E ),\r\n        basefont : {},\r\n        h5 : L,\r\n        h4 : L,\r\n        samp : L,\r\n        h6 : L,\r\n        ol : Q,\r\n        h1 : L,\r\n        h3 : L,\r\n        option : N,\r\n        h2 : L,\r\n        form : X( A, D, E, I ),\r\n        select : _({optgroup:1,option:1}),\r\n        font : L,\r\n        ins : L,\r\n        menu : Q,\r\n        abbr : L,\r\n        label : L,\r\n        table : _({thead:1,col:1,tbody:1,tr:1,colgroup:1,caption:1,tfoot:1}),\r\n        code : L,\r\n        tfoot : M,\r\n        cite : L,\r\n        li : P,\r\n        input : {},\r\n        iframe : P,\r\n        strong : L,\r\n        textarea : N,\r\n        noframes : P,\r\n        big : L,\r\n        small : L,\r\n        //trace:\r\n        span :_({'#':1,br:1,b:1,strong:1,u:1,i:1,em:1,sub:1,sup:1,strike:1,span:1}),\r\n        hr : L,\r\n        dt : L,\r\n        sub : L,\r\n        optgroup : _({option:1}),\r\n        param : {},\r\n        bdo : L,\r\n        'var' : L,\r\n        div : P,\r\n        object : O,\r\n        sup : L,\r\n        dd : P,\r\n        strike : L,\r\n        area : {},\r\n        dir : Q,\r\n        map : X( _({area:1,form:1,p:1}), A, F, E ),\r\n        applet : O,\r\n        dl : _({dt:1,dd:1}),\r\n        del : L,\r\n        isindex : {},\r\n        fieldset : X( _({legend:1}), K ),\r\n        thead : M,\r\n        ul : Q,\r\n        acronym : L,\r\n        b : L,\r\n        a : X( _({a:1}), J ),\r\n        blockquote :X(_({td:1,tr:1,tbody:1,li:1}),P),\r\n        caption : L,\r\n        i : L,\r\n        u : L,\r\n        tbody : M,\r\n        s : L,\r\n        address : X( D, I ),\r\n        tt : L,\r\n        legend : L,\r\n        q : L,\r\n        pre : X( G, C ),\r\n        p : X(_({'a':1}),L),\r\n        em :L,\r\n        dfn : L\r\n    });\r\n})();\r\n\n\n// core/domUtils.js\n/**\r\n * Dom操作工具包\r\n * @file\r\n * @module UE.dom.domUtils\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * Dom操作工具包\r\n * @unfile\r\n * @module UE.dom.domUtils\r\n */\r\nfunction getDomNode(node, start, ltr, startFromChild, fn, guard) {\r\n    var tmpNode = startFromChild && node[start],\r\n        parent;\r\n    !tmpNode && (tmpNode = node[ltr]);\r\n    while (!tmpNode && (parent = (parent || node).parentNode)) {\r\n        if (parent.tagName == 'BODY' || guard && !guard(parent)) {\r\n            return null;\r\n        }\r\n        tmpNode = parent[ltr];\r\n    }\r\n    if (tmpNode && fn && !fn(tmpNode)) {\r\n        return  getDomNode(tmpNode, start, ltr, false, fn);\r\n    }\r\n    return tmpNode;\r\n}\r\nvar attrFix = ie && browser.version < 9 ? {\r\n        tabindex:\"tabIndex\",\r\n        readonly:\"readOnly\",\r\n        \"for\":\"htmlFor\",\r\n        \"class\":\"className\",\r\n        maxlength:\"maxLength\",\r\n        cellspacing:\"cellSpacing\",\r\n        cellpadding:\"cellPadding\",\r\n        rowspan:\"rowSpan\",\r\n        colspan:\"colSpan\",\r\n        usemap:\"useMap\",\r\n        frameborder:\"frameBorder\"\r\n    } : {\r\n        tabindex:\"tabIndex\",\r\n        readonly:\"readOnly\"\r\n    },\r\n    styleBlock = utils.listToMap([\r\n        '-webkit-box', '-moz-box', 'block' ,\r\n        'list-item' , 'table' , 'table-row-group' ,\r\n        'table-header-group', 'table-footer-group' ,\r\n        'table-row' , 'table-column-group' , 'table-column' ,\r\n        'table-cell' , 'table-caption'\r\n    ]);\r\nvar domUtils = dom.domUtils = {\r\n    //节点常量\r\n    NODE_ELEMENT:1,\r\n    NODE_DOCUMENT:9,\r\n    NODE_TEXT:3,\r\n    NODE_COMMENT:8,\r\n    NODE_DOCUMENT_FRAGMENT:11,\r\n\r\n    //位置关系\r\n    POSITION_IDENTICAL:0,\r\n    POSITION_DISCONNECTED:1,\r\n    POSITION_FOLLOWING:2,\r\n    POSITION_PRECEDING:4,\r\n    POSITION_IS_CONTAINED:8,\r\n    POSITION_CONTAINS:16,\r\n    //ie6使用其他的会有一段空白出现\r\n    fillChar:ie && browser.version == '6' ? '\\ufeff' : '\\u200B',\r\n    //-------------------------Node部分--------------------------------\r\n    keys:{\r\n        /*Backspace*/ 8:1, /*Delete*/ 46:1,\r\n        /*Shift*/ 16:1, /*Ctrl*/ 17:1, /*Alt*/ 18:1,\r\n        37:1, 38:1, 39:1, 40:1,\r\n        13:1 /*enter*/\r\n    },\r\n    /**\r\n     * 获取节点A相对于节点B的位置关系\r\n     * @method getPosition\r\n     * @param { Node } nodeA 需要查询位置关系的节点A\r\n     * @param { Node } nodeB 需要查询位置关系的节点B\r\n     * @return { Number } 节点A与节点B的关系\r\n     * @example\r\n     * ```javascript\r\n     * //output: 20\r\n     * var position = UE.dom.domUtils.getPosition( document.documentElement, document.body );\r\n     *\r\n     * switch ( position ) {\r\n     *\r\n     *      //0\r\n     *      case UE.dom.domUtils.POSITION_IDENTICAL:\r\n     *          console.log('元素相同');\r\n     *          break;\r\n     *      //1\r\n     *      case UE.dom.domUtils.POSITION_DISCONNECTED:\r\n     *          console.log('两个节点在不同的文档中');\r\n     *          break;\r\n     *      //2\r\n     *      case UE.dom.domUtils.POSITION_FOLLOWING:\r\n     *          console.log('节点A在节点B之后');\r\n     *          break;\r\n     *      //4\r\n     *      case UE.dom.domUtils.POSITION_PRECEDING;\r\n     *          console.log('节点A在节点B之前');\r\n     *          break;\r\n     *      //8\r\n     *      case UE.dom.domUtils.POSITION_IS_CONTAINED:\r\n     *          console.log('节点A被节点B包含');\r\n     *          break;\r\n     *      case 10:\r\n     *          console.log('节点A被节点B包含且节点A在节点B之后');\r\n     *          break;\r\n     *      //16\r\n     *      case UE.dom.domUtils.POSITION_CONTAINS:\r\n     *          console.log('节点A包含节点B');\r\n     *          break;\r\n     *      case 20:\r\n     *          console.log('节点A包含节点B且节点A在节点B之前');\r\n     *          break;\r\n     *\r\n     * }\r\n     * ```\r\n     */\r\n    getPosition:function (nodeA, nodeB) {\r\n        // 如果两个节点是同一个节点\r\n        if (nodeA === nodeB) {\r\n            // domUtils.POSITION_IDENTICAL\r\n            return 0;\r\n        }\r\n        var node,\r\n            parentsA = [nodeA],\r\n            parentsB = [nodeB];\r\n        node = nodeA;\r\n        while (node = node.parentNode) {\r\n            // 如果nodeB是nodeA的祖先节点\r\n            if (node === nodeB) {\r\n                // domUtils.POSITION_IS_CONTAINED + domUtils.POSITION_FOLLOWING\r\n                return 10;\r\n            }\r\n            parentsA.push(node);\r\n        }\r\n        node = nodeB;\r\n        while (node = node.parentNode) {\r\n            // 如果nodeA是nodeB的祖先节点\r\n            if (node === nodeA) {\r\n                // domUtils.POSITION_CONTAINS + domUtils.POSITION_PRECEDING\r\n                return 20;\r\n            }\r\n            parentsB.push(node);\r\n        }\r\n        parentsA.reverse();\r\n        parentsB.reverse();\r\n        if (parentsA[0] !== parentsB[0]) {\r\n            // domUtils.POSITION_DISCONNECTED\r\n            return 1;\r\n        }\r\n        var i = -1;\r\n        while (i++, parentsA[i] === parentsB[i]) {\r\n        }\r\n        nodeA = parentsA[i];\r\n        nodeB = parentsB[i];\r\n        while (nodeA = nodeA.nextSibling) {\r\n            if (nodeA === nodeB) {\r\n                // domUtils.POSITION_PRECEDING\r\n                return 4\r\n            }\r\n        }\r\n        // domUtils.POSITION_FOLLOWING\r\n        return  2;\r\n    },\r\n\r\n    /**\r\n     * 检测节点node在父节点中的索引位置\r\n     * @method getNodeIndex\r\n     * @param { Node } node 需要检测的节点对象\r\n     * @return { Number } 该节点在父节点中的位置\r\n     * @see UE.dom.domUtils.getNodeIndex(Node,Boolean)\r\n     */\r\n\r\n    /**\r\n     * 检测节点node在父节点中的索引位置， 根据给定的mergeTextNode参数决定是否要合并多个连续的文本节点为一个节点\r\n     * @method getNodeIndex\r\n     * @param { Node } node 需要检测的节点对象\r\n     * @param { Boolean } mergeTextNode 是否合并多个连续的文本节点为一个节点\r\n     * @return { Number } 该节点在父节点中的位置\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     *      var node = document.createElement(\"div\");\r\n     *\r\n     *      node.appendChild( document.createTextNode( \"hello\" ) );\r\n     *      node.appendChild( document.createTextNode( \"world\" ) );\r\n     *      node.appendChild( node = document.createElement( \"div\" ) );\r\n     *\r\n     *      //output: 2\r\n     *      console.log( UE.dom.domUtils.getNodeIndex( node ) );\r\n     *\r\n     *      //output: 1\r\n     *      console.log( UE.dom.domUtils.getNodeIndex( node, true ) );\r\n     *\r\n     * ```\r\n     */\r\n    getNodeIndex:function (node, ignoreTextNode) {\r\n        var preNode = node,\r\n            i = 0;\r\n        while (preNode = preNode.previousSibling) {\r\n            if (ignoreTextNode && preNode.nodeType == 3) {\r\n                if(preNode.nodeType != preNode.nextSibling.nodeType ){\r\n                    i++;\r\n                }\r\n                continue;\r\n            }\r\n            i++;\r\n        }\r\n        return i;\r\n    },\r\n\r\n    /**\r\n     * 检测节点node是否在给定的document对象上\r\n     * @method inDoc\r\n     * @param { Node } node 需要检测的节点对象\r\n     * @param { DomDocument } doc 需要检测的document对象\r\n     * @return { Boolean } 该节点node是否在给定的document的dom树上\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * var node = document.createElement(\"div\");\r\n     *\r\n     * //output: false\r\n     * console.log( UE.do.domUtils.inDoc( node, document ) );\r\n     *\r\n     * document.body.appendChild( node );\r\n     *\r\n     * //output: true\r\n     * console.log( UE.do.domUtils.inDoc( node, document ) );\r\n     *\r\n     * ```\r\n     */\r\n    inDoc:function (node, doc) {\r\n        return domUtils.getPosition(node, doc) == 10;\r\n    },\r\n    /**\r\n     * 根据给定的过滤规则filterFn， 查找符合该过滤规则的node节点的第一个祖先节点，\r\n     * 查找的起点是给定node节点的父节点。\r\n     * @method findParent\r\n     * @param { Node } node 需要查找的节点\r\n     * @param { Function } filterFn 自定义的过滤方法。\r\n     * @warning 查找的终点是到body节点为止\r\n     * @remind 自定义的过滤方法filterFn接受一个Node对象作为参数， 该对象代表当前执行检测的祖先节点。 如果该\r\n     *          节点满足过滤条件， 则要求返回true， 这时将直接返回该节点作为findParent()的结果， 否则， 请返回false。\r\n     * @return { Node | Null } 如果找到符合过滤条件的节点， 就返回该节点， 否则返回NULL\r\n     * @example\r\n     * ```javascript\r\n     * var filterNode = UE.dom.domUtils.findParent( document.body.firstChild, function ( node ) {\r\n     *\r\n     *     //由于查找的终点是body节点， 所以永远也不会匹配当前过滤器的条件， 即这里永远会返回false\r\n     *     return node.tagName === \"HTML\";\r\n     *\r\n     * } );\r\n     *\r\n     * //output: true\r\n     * console.log( filterNode === null );\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 根据给定的过滤规则filterFn， 查找符合该过滤规则的node节点的第一个祖先节点，\r\n     * 如果includeSelf的值为true，则查找的起点是给定的节点node， 否则， 起点是node的父节点\r\n     * @method findParent\r\n     * @param { Node } node 需要查找的节点\r\n     * @param { Function } filterFn 自定义的过滤方法。\r\n     * @param { Boolean } includeSelf 查找过程是否包含自身\r\n     * @warning 查找的终点是到body节点为止\r\n     * @remind 自定义的过滤方法filterFn接受一个Node对象作为参数， 该对象代表当前执行检测的祖先节点。 如果该\r\n     *          节点满足过滤条件， 则要求返回true， 这时将直接返回该节点作为findParent()的结果， 否则， 请返回false。\r\n     * @remind 如果includeSelf为true， 则过滤器第一次执行时的参数会是节点本身。\r\n     *          反之， 过滤器第一次执行时的参数将是该节点的父节点。\r\n     * @return { Node | Null } 如果找到符合过滤条件的节点， 就返回该节点， 否则返回NULL\r\n     * @example\r\n     * ```html\r\n     * <body>\r\n     *\r\n     *      <div id=\"test\">\r\n     *      </div>\r\n     *\r\n     *      <script type=\"text/javascript\">\r\n     *\r\n     *          //output: DIV, BODY\r\n     *          var filterNode = UE.dom.domUtils.findParent( document.getElementById( \"test\" ), function ( node ) {\r\n     *\r\n     *              console.log( node.tagName );\r\n     *              return false;\r\n     *\r\n     *          }, true );\r\n     *\r\n     *      </script>\r\n     * </body>\r\n     * ```\r\n     */\r\n    findParent:function (node, filterFn, includeSelf) {\r\n        if (node && !domUtils.isBody(node)) {\r\n            node = includeSelf ? node : node.parentNode;\r\n            while (node) {\r\n                if (!filterFn || filterFn(node) || domUtils.isBody(node)) {\r\n                    return filterFn && !filterFn(node) && domUtils.isBody(node) ? null : node;\r\n                }\r\n                node = node.parentNode;\r\n            }\r\n        }\r\n        return null;\r\n    },\r\n    /**\r\n     * 查找node的节点名为tagName的第一个祖先节点， 查找的起点是node节点的父节点。\r\n     * @method findParentByTagName\r\n     * @param { Node } node 需要查找的节点对象\r\n     * @param { Array } tagNames 需要查找的父节点的名称数组\r\n     * @warning 查找的终点是到body节点为止\r\n     * @return { Node | NULL } 如果找到符合条件的节点， 则返回该节点， 否则返回NULL\r\n     * @example\r\n     * ```javascript\r\n     * var node = UE.dom.domUtils.findParentByTagName( document.getElementsByTagName(\"div\")[0], [ \"BODY\" ] );\r\n     * //output: BODY\r\n     * console.log( node.tagName );\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 查找node的节点名为tagName的祖先节点， 如果includeSelf的值为true，则查找的起点是给定的节点node，\r\n     * 否则， 起点是node的父节点。\r\n     * @method findParentByTagName\r\n     * @param { Node } node 需要查找的节点对象\r\n     * @param { Array } tagNames 需要查找的父节点的名称数组\r\n     * @param { Boolean } includeSelf 查找过程是否包含node节点自身\r\n     * @warning 查找的终点是到body节点为止\r\n     * @return { Node | NULL } 如果找到符合条件的节点， 则返回该节点， 否则返回NULL\r\n     * @example\r\n     * ```javascript\r\n     * var queryTarget = document.getElementsByTagName(\"div\")[0];\r\n     * var node = UE.dom.domUtils.findParentByTagName( queryTarget, [ \"DIV\" ], true );\r\n     * //output: true\r\n     * console.log( queryTarget === node );\r\n     * ```\r\n     */\r\n    findParentByTagName:function (node, tagNames, includeSelf, excludeFn) {\r\n        tagNames = utils.listToMap(utils.isArray(tagNames) ? tagNames : [tagNames]);\r\n        return domUtils.findParent(node, function (node) {\r\n            return tagNames[node.tagName] && !(excludeFn && excludeFn(node));\r\n        }, includeSelf);\r\n    },\r\n    /**\r\n     * 查找节点node的祖先节点集合， 查找的起点是给定节点的父节点，结果集中不包含给定的节点。\r\n     * @method findParents\r\n     * @param { Node } node 需要查找的节点对象\r\n     * @return { Array } 给定节点的祖先节点数组\r\n     * @grammar UE.dom.domUtils.findParents(node)  => Array  //返回一个祖先节点数组集合，不包含自身\r\n     * @grammar UE.dom.domUtils.findParents(node,includeSelf)  => Array  //返回一个祖先节点数组集合，includeSelf指定是否包含自身\r\n     * @grammar UE.dom.domUtils.findParents(node,includeSelf,filterFn)  => Array  //返回一个祖先节点数组集合，filterFn指定过滤条件，返回true的node将被选取\r\n     * @grammar UE.dom.domUtils.findParents(node,includeSelf,filterFn,closerFirst)  => Array  //返回一个祖先节点数组集合，closerFirst为true的话，node的直接父亲节点是数组的第0个\r\n     */\r\n\r\n    /**\r\n     * 查找节点node的祖先节点集合， 如果includeSelf的值为true，\r\n     * 则返回的结果集中允许出现当前给定的节点， 否则， 该节点不会出现在其结果集中。\r\n     * @method findParents\r\n     * @param { Node } node 需要查找的节点对象\r\n     * @param { Boolean } includeSelf 查找的结果中是否允许包含当前查找的节点对象\r\n     * @return { Array } 给定节点的祖先节点数组\r\n     */\r\n    findParents:function (node, includeSelf, filterFn, closerFirst) {\r\n        var parents = includeSelf && ( filterFn && filterFn(node) || !filterFn ) ? [node] : [];\r\n        while (node = domUtils.findParent(node, filterFn)) {\r\n            parents.push(node);\r\n        }\r\n        return closerFirst ? parents : parents.reverse();\r\n    },\r\n\r\n    /**\r\n     * 在节点node后面插入新节点newNode\r\n     * @method insertAfter\r\n     * @param { Node } node 目标节点\r\n     * @param { Node } newNode 新插入的节点， 该节点将置于目标节点之后\r\n     * @return { Node } 新插入的节点\r\n     */\r\n    insertAfter:function (node, newNode) {\r\n        return node.nextSibling ? node.parentNode.insertBefore(newNode, node.nextSibling):\r\n            node.parentNode.appendChild(newNode);\r\n    },\r\n\r\n    /**\r\n     * 删除节点node及其下属的所有节点\r\n     * @method remove\r\n     * @param { Node } node 需要删除的节点对象\r\n     * @return { Node } 返回刚删除的节点对象\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\">\r\n     *     <div id=\"child\">你好</div>\r\n     * </div>\r\n     * <script>\r\n     *     UE.dom.domUtils.remove( document.body, false );\r\n     *     //output: false\r\n     *     console.log( document.getElementById( \"child\" ) !== null );\r\n     * </script>\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 删除节点node，并根据keepChildren的值决定是否保留子节点\r\n     * @method remove\r\n     * @param { Node } node 需要删除的节点对象\r\n     * @param { Boolean } keepChildren 是否需要保留子节点\r\n     * @return { Node } 返回刚删除的节点对象\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\">\r\n     *     <div id=\"child\">你好</div>\r\n     * </div>\r\n     * <script>\r\n     *     UE.dom.domUtils.remove( document.body, true );\r\n     *     //output: true\r\n     *     console.log( document.getElementById( \"child\" ) !== null );\r\n     * </script>\r\n     * ```\r\n     */\r\n    remove:function (node, keepChildren) {\r\n        var parent = node.parentNode,\r\n            child;\r\n        if (parent) {\r\n            if (keepChildren && node.hasChildNodes()) {\r\n                while (child = node.firstChild) {\r\n                    parent.insertBefore(child, node);\r\n                }\r\n            }\r\n            parent.removeChild(node);\r\n        }\r\n        return node;\r\n    },\r\n\r\n    /**\r\n     * 取得node节点的下一个兄弟节点， 如果该节点其后没有兄弟节点， 则递归查找其父节点之后的第一个兄弟节点，\r\n     * 直到找到满足条件的节点或者递归到BODY节点之后才会结束。\r\n     * @method getNextDomNode\r\n     * @param { Node } node 需要获取其后的兄弟节点的节点对象\r\n     * @return { Node | NULL } 如果找满足条件的节点， 则返回该节点， 否则返回NULL\r\n     * @example\r\n     * ```html\r\n     *     <body>\r\n     *      <div id=\"test\">\r\n     *          <span></span>\r\n     *      </div>\r\n     *      <i>xxx</i>\r\n     * </body>\r\n     * <script>\r\n     *\r\n     *     //output: i节点\r\n     *     console.log( UE.dom.domUtils.getNextDomNode( document.getElementById( \"test\" ) ) );\r\n     *\r\n     * </script>\r\n     * ```\r\n     * @example\r\n     * ```html\r\n     * <body>\r\n     *      <div>\r\n     *          <span></span>\r\n     *          <i id=\"test\">xxx</i>\r\n     *      </div>\r\n     *      <b>xxx</b>\r\n     * </body>\r\n     * <script>\r\n     *\r\n     *     //由于id为test的i节点之后没有兄弟节点， 则查找其父节点（div）后面的兄弟节点\r\n     *     //output: b节点\r\n     *     console.log( UE.dom.domUtils.getNextDomNode( document.getElementById( \"test\" ) ) );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 取得node节点的下一个兄弟节点， 如果startFromChild的值为ture，则先获取其子节点，\r\n     * 如果有子节点则直接返回第一个子节点；如果没有子节点或者startFromChild的值为false，\r\n     * 则执行<a href=\"#UE.dom.domUtils.getNextDomNode(Node)\">getNextDomNode(Node node)</a>的查找过程。\r\n     * @method getNextDomNode\r\n     * @param { Node } node 需要获取其后的兄弟节点的节点对象\r\n     * @param { Boolean } startFromChild 查找过程是否从其子节点开始\r\n     * @return { Node | NULL } 如果找满足条件的节点， 则返回该节点， 否则返回NULL\r\n     * @see UE.dom.domUtils.getNextDomNode(Node)\r\n     */\r\n    getNextDomNode:function (node, startFromChild, filterFn, guard) {\r\n        return getDomNode(node, 'firstChild', 'nextSibling', startFromChild, filterFn, guard);\r\n    },\r\n    getPreDomNode:function (node, startFromChild, filterFn, guard) {\r\n        return getDomNode(node, 'lastChild', 'previousSibling', startFromChild, filterFn, guard);\r\n    },\r\n    /**\r\n     * 检测节点node是否属是UEditor定义的bookmark节点\r\n     * @method isBookmarkNode\r\n     * @private\r\n     * @param { Node } node 需要检测的节点对象\r\n     * @return { Boolean } 是否是bookmark节点\r\n     * @example\r\n     * ```html\r\n     * <span id=\"_baidu_bookmark_1\"></span>\r\n     * <script>\r\n     *      var bookmarkNode = document.getElementById(\"_baidu_bookmark_1\");\r\n     *      //output: true\r\n     *      console.log( UE.dom.domUtils.isBookmarkNode( bookmarkNode ) );\r\n     * </script>\r\n     * ```\r\n     */\r\n    isBookmarkNode:function (node) {\r\n        return node.nodeType == 1 && node.id && /^_baidu_bookmark_/i.test(node.id);\r\n    },\r\n    /**\r\n     * 获取节点node所属的window对象\r\n     * @method  getWindow\r\n     * @param { Node } node 节点对象\r\n     * @return { Window } 当前节点所属的window对象\r\n     * @example\r\n     * ```javascript\r\n     * //output: true\r\n     * console.log( UE.dom.domUtils.getWindow( document.body ) === window );\r\n     * ```\r\n     */\r\n    getWindow:function (node) {\r\n        var doc = node.ownerDocument || node;\r\n        return doc.defaultView || doc.parentWindow;\r\n    },\r\n    /**\r\n     * 获取离nodeA与nodeB最近的公共的祖先节点\r\n     * @method  getCommonAncestor\r\n     * @param { Node } nodeA 第一个节点\r\n     * @param { Node } nodeB 第二个节点\r\n     * @remind 如果给定的两个节点是同一个节点， 将直接返回该节点。\r\n     * @return { Node | NULL } 如果未找到公共节点， 返回NULL， 否则返回最近的公共祖先节点。\r\n     * @example\r\n     * ```javascript\r\n     * var commonAncestor = UE.dom.domUtils.getCommonAncestor( document.body, document.body.firstChild );\r\n     * //output: true\r\n     * console.log( commonAncestor.tagName.toLowerCase() === 'body' );\r\n     * ```\r\n     */\r\n    getCommonAncestor:function (nodeA, nodeB) {\r\n        if (nodeA === nodeB)\r\n            return nodeA;\r\n        var parentsA = [nodeA] , parentsB = [nodeB], parent = nodeA, i = -1;\r\n        while (parent = parent.parentNode) {\r\n            if (parent === nodeB) {\r\n                return parent;\r\n            }\r\n            parentsA.push(parent);\r\n        }\r\n        parent = nodeB;\r\n        while (parent = parent.parentNode) {\r\n            if (parent === nodeA)\r\n                return parent;\r\n            parentsB.push(parent);\r\n        }\r\n        parentsA.reverse();\r\n        parentsB.reverse();\r\n        while (i++, parentsA[i] === parentsB[i]) {\r\n        }\r\n        return i == 0 ? null : parentsA[i - 1];\r\n\r\n    },\r\n    /**\r\n     * 清除node节点左右连续为空的兄弟inline节点\r\n     * @method clearEmptySibling\r\n     * @param { Node } node 执行的节点对象， 如果该节点的左右连续的兄弟节点是空的inline节点，\r\n     * 则这些兄弟节点将被删除\r\n     * @grammar UE.dom.domUtils.clearEmptySibling(node,ignoreNext)  //ignoreNext指定是否忽略右边空节点\r\n     * @grammar UE.dom.domUtils.clearEmptySibling(node,ignoreNext,ignorePre)  //ignorePre指定是否忽略左边空节点\r\n     * @example\r\n     * ```html\r\n     * <body>\r\n     *     <div></div>\r\n     *     <span id=\"test\"></span>\r\n     *     <i></i>\r\n     *     <b></b>\r\n     *     <em>xxx</em>\r\n     *     <span></span>\r\n     * </body>\r\n     * <script>\r\n     *\r\n     *      UE.dom.domUtils.clearEmptySibling( document.getElementById( \"test\" ) );\r\n     *\r\n     *      //output: <div></div><span id=\"test\"></span><em>xxx</em><span></span>\r\n     *      console.log( document.body.innerHTML );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 清除node节点左右连续为空的兄弟inline节点， 如果ignoreNext的值为true，\r\n     * 则忽略对右边兄弟节点的操作。\r\n     * @method clearEmptySibling\r\n     * @param { Node } node 执行的节点对象， 如果该节点的左右连续的兄弟节点是空的inline节点，\r\n     * @param { Boolean } ignoreNext 是否忽略忽略对右边的兄弟节点的操作\r\n     * 则这些兄弟节点将被删除\r\n     * @see UE.dom.domUtils.clearEmptySibling(Node)\r\n     */\r\n\r\n    /**\r\n     * 清除node节点左右连续为空的兄弟inline节点， 如果ignoreNext的值为true，\r\n     * 则忽略对右边兄弟节点的操作， 如果ignorePre的值为true，则忽略对左边兄弟节点的操作。\r\n     * @method clearEmptySibling\r\n     * @param { Node } node 执行的节点对象， 如果该节点的左右连续的兄弟节点是空的inline节点，\r\n     * @param { Boolean } ignoreNext 是否忽略忽略对右边的兄弟节点的操作\r\n     * @param { Boolean } ignorePre 是否忽略忽略对左边的兄弟节点的操作\r\n     * 则这些兄弟节点将被删除\r\n     * @see UE.dom.domUtils.clearEmptySibling(Node)\r\n     */\r\n    clearEmptySibling:function (node, ignoreNext, ignorePre) {\r\n        function clear(next, dir) {\r\n            var tmpNode;\r\n            while (next && !domUtils.isBookmarkNode(next) && (domUtils.isEmptyInlineElement(next)\r\n                //这里不能把空格算进来会吧空格干掉，出现文字间的空格丢掉了\r\n                || !new RegExp('[^\\t\\n\\r' + domUtils.fillChar + ']').test(next.nodeValue) )) {\r\n                tmpNode = next[dir];\r\n                domUtils.remove(next);\r\n                next = tmpNode;\r\n            }\r\n        }\r\n        !ignoreNext && clear(node.nextSibling, 'nextSibling');\r\n        !ignorePre && clear(node.previousSibling, 'previousSibling');\r\n    },\r\n    /**\r\n     * 将一个文本节点textNode拆分成两个文本节点，offset指定拆分位置\r\n     * @method split\r\n     * @param { Node } textNode 需要拆分的文本节点对象\r\n     * @param { int } offset 需要拆分的位置， 位置计算从0开始\r\n     * @return { Node } 拆分后形成的新节点\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\">abcdef</div>\r\n     * <script>\r\n     *      var newNode = UE.dom.domUtils.split( document.getElementById( \"test\" ).firstChild, 3 );\r\n     *      //output: def\r\n     *      console.log( newNode.nodeValue );\r\n     * </script>\r\n     * ```\r\n     */\r\n    split:function (node, offset) {\r\n        var doc = node.ownerDocument;\r\n        if (browser.ie && offset == node.nodeValue.length) {\r\n            var next = doc.createTextNode('');\r\n            return domUtils.insertAfter(node, next);\r\n        }\r\n        var retval = node.splitText(offset);\r\n        //ie8下splitText不会跟新childNodes,我们手动触发他的更新\r\n        if (browser.ie8) {\r\n            var tmpNode = doc.createTextNode('');\r\n            domUtils.insertAfter(retval, tmpNode);\r\n            domUtils.remove(tmpNode);\r\n        }\r\n        return retval;\r\n    },\r\n\r\n    /**\r\n     * 检测文本节点textNode是否为空节点（包括空格、换行、占位符等字符）\r\n     * @method  isWhitespace\r\n     * @param { Node } node 需要检测的节点对象\r\n     * @return { Boolean } 检测的节点是否为空\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\">\r\n     *\r\n     * </div>\r\n     * <script>\r\n     *      //output: true\r\n     *      console.log( UE.dom.domUtils.isWhitespace( document.getElementById(\"test\").firstChild ) );\r\n     * </script>\r\n     * ```\r\n     */\r\n    isWhitespace:function (node) {\r\n        return !new RegExp('[^ \\t\\n\\r' + domUtils.fillChar + ']').test(node.nodeValue);\r\n    },\r\n    /**\r\n     * 获取元素element相对于viewport的位置坐标\r\n     * @method getXY\r\n     * @param { Node } element 需要计算位置的节点对象\r\n     * @return { Object } 返回形如{x:left,y:top}的一个key-value映射对象， 其中键x代表水平偏移距离，\r\n     *                          y代表垂直偏移距离。\r\n     *\r\n     * @example\r\n     * ```javascript\r\n     * var location = UE.dom.domUtils.getXY( document.getElementById(\"test\") );\r\n     * //output: test的坐标为: 12, 24\r\n     * console.log( 'test的坐标为： ', location.x, ',', location.y );\r\n     * ```\r\n     */\r\n    getXY:function (element) {\r\n        var x = 0, y = 0;\r\n        while (element.offsetParent) {\r\n            y += element.offsetTop;\r\n            x += element.offsetLeft;\r\n            element = element.offsetParent;\r\n        }\r\n        return { 'x':x, 'y':y};\r\n    },\r\n    /**\r\n     * 为元素element绑定原生DOM事件，type为事件类型，handler为处理函数\r\n     * @method on\r\n     * @param { Node } element 需要绑定事件的节点对象\r\n     * @param { String } type 绑定的事件类型\r\n     * @param { Function } handler 事件处理器\r\n     * @example\r\n     * ```javascript\r\n     * UE.dom.domUtils.on(document.body,\"click\",function(e){\r\n     *     //e为事件对象，this为被点击元素对戏那个\r\n     * });\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 为元素element绑定原生DOM事件，type为事件类型，handler为处理函数\r\n     * @method on\r\n     * @param { Node } element 需要绑定事件的节点对象\r\n     * @param { Array } type 绑定的事件类型数组\r\n     * @param { Function } handler 事件处理器\r\n     * @example\r\n     * ```javascript\r\n     * UE.dom.domUtils.on(document.body,[\"click\",\"mousedown\"],function(evt){\r\n     *     //evt为事件对象，this为被点击元素对象\r\n     * });\r\n     * ```\r\n     */\r\n    on:function (element, type, handler) {\r\n\r\n        var types = utils.isArray(type) ? type : utils.trim(type).split(/\\s+/),\r\n            k = types.length;\r\n        if (k) while (k--) {\r\n            type = types[k];\r\n            if (element.addEventListener) {\r\n                element.addEventListener(type, handler, false);\r\n            } else {\r\n                if (!handler._d) {\r\n                    handler._d = {\r\n                        els : []\r\n                    };\r\n                }\r\n                var key = type + handler.toString(),index = utils.indexOf(handler._d.els,element);\r\n                if (!handler._d[key] || index == -1) {\r\n                    if(index == -1){\r\n                        handler._d.els.push(element);\r\n                    }\r\n                    if(!handler._d[key]){\r\n                        handler._d[key] = function (evt) {\r\n                            return handler.call(evt.srcElement, evt || window.event);\r\n                        };\r\n                    }\r\n\r\n\r\n                    element.attachEvent('on' + type, handler._d[key]);\r\n                }\r\n            }\r\n        }\r\n        element = null;\r\n    },\r\n    /**\r\n     * 解除DOM事件绑定\r\n     * @method un\r\n     * @param { Node } element 需要解除事件绑定的节点对象\r\n     * @param { String } type 需要接触绑定的事件类型\r\n     * @param { Function } handler 对应的事件处理器\r\n     * @example\r\n     * ```javascript\r\n     * UE.dom.domUtils.un(document.body,\"click\",function(evt){\r\n     *     //evt为事件对象，this为被点击元素对象\r\n     * });\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 解除DOM事件绑定\r\n     * @method un\r\n     * @param { Node } element 需要解除事件绑定的节点对象\r\n     * @param { Array } type 需要接触绑定的事件类型数组\r\n     * @param { Function } handler 对应的事件处理器\r\n     * @example\r\n     * ```javascript\r\n     * UE.dom.domUtils.un(document.body, [\"click\",\"mousedown\"],function(evt){\r\n     *     //evt为事件对象，this为被点击元素对象\r\n     * });\r\n     * ```\r\n     */\r\n    un:function (element, type, handler) {\r\n        var types = utils.isArray(type) ? type : utils.trim(type).split(/\\s+/),\r\n            k = types.length;\r\n        if (k) while (k--) {\r\n            type = types[k];\r\n            if (element.removeEventListener) {\r\n                element.removeEventListener(type, handler, false);\r\n            } else {\r\n                var key = type + handler.toString();\r\n                try{\r\n                    element.detachEvent('on' + type, handler._d ? handler._d[key] : handler);\r\n                }catch(e){}\r\n                if (handler._d && handler._d[key]) {\r\n                    var index = utils.indexOf(handler._d.els,element);\r\n                    if(index!=-1){\r\n                        handler._d.els.splice(index,1);\r\n                    }\r\n                    handler._d.els.length == 0 && delete handler._d[key];\r\n                }\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     * 比较节点nodeA与节点nodeB是否具有相同的标签名、属性名以及属性值\r\n     * @method  isSameElement\r\n     * @param { Node } nodeA 需要比较的节点\r\n     * @param { Node } nodeB 需要比较的节点\r\n     * @return { Boolean } 两个节点是否具有相同的标签名、属性名以及属性值\r\n     * @example\r\n     * ```html\r\n     * <span style=\"font-size:12px\">ssss</span>\r\n     * <span style=\"font-size:12px\">bbbbb</span>\r\n     * <span style=\"font-size:13px\">ssss</span>\r\n     * <span style=\"font-size:14px\">bbbbb</span>\r\n     *\r\n     * <script>\r\n     *\r\n     *     var nodes = document.getElementsByTagName( \"span\" );\r\n     *\r\n     *     //output: true\r\n     *     console.log( UE.dom.domUtils.isSameElement( nodes[0], nodes[1] ) );\r\n     *\r\n     *     //output: false\r\n     *     console.log( UE.dom.domUtils.isSameElement( nodes[2], nodes[3] ) );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    isSameElement:function (nodeA, nodeB) {\r\n        if (nodeA.tagName != nodeB.tagName) {\r\n            return false;\r\n        }\r\n        var thisAttrs = nodeA.attributes,\r\n            otherAttrs = nodeB.attributes;\r\n        if (!ie && thisAttrs.length != otherAttrs.length) {\r\n            return false;\r\n        }\r\n        var attrA, attrB, al = 0, bl = 0;\r\n        for (var i = 0; attrA = thisAttrs[i++];) {\r\n            if (attrA.nodeName == 'style') {\r\n                if (attrA.specified) {\r\n                    al++;\r\n                }\r\n                if (domUtils.isSameStyle(nodeA, nodeB)) {\r\n                    continue;\r\n                } else {\r\n                    return false;\r\n                }\r\n            }\r\n            if (ie) {\r\n                if (attrA.specified) {\r\n                    al++;\r\n                    attrB = otherAttrs.getNamedItem(attrA.nodeName);\r\n                } else {\r\n                    continue;\r\n                }\r\n            } else {\r\n                attrB = nodeB.attributes[attrA.nodeName];\r\n            }\r\n            if (!attrB.specified || attrA.nodeValue != attrB.nodeValue) {\r\n                return false;\r\n            }\r\n        }\r\n        // 有可能attrB的属性包含了attrA的属性之外还有自己的属性\r\n        if (ie) {\r\n            for (i = 0; attrB = otherAttrs[i++];) {\r\n                if (attrB.specified) {\r\n                    bl++;\r\n                }\r\n            }\r\n            if (al != bl) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    },\r\n\r\n    /**\r\n     * 判断节点nodeA与节点nodeB的元素的style属性是否一致\r\n     * @method isSameStyle\r\n     * @param { Node } nodeA 需要比较的节点\r\n     * @param { Node } nodeB 需要比较的节点\r\n     * @return { Boolean } 两个节点是否具有相同的style属性值\r\n     * @example\r\n     * ```html\r\n     * <span style=\"font-size:12px\">ssss</span>\r\n     * <span style=\"font-size:12px\">bbbbb</span>\r\n     * <span style=\"font-size:13px\">ssss</span>\r\n     * <span style=\"font-size:14px\">bbbbb</span>\r\n     *\r\n     * <script>\r\n     *\r\n     *     var nodes = document.getElementsByTagName( \"span\" );\r\n     *\r\n     *     //output: true\r\n     *     console.log( UE.dom.domUtils.isSameStyle( nodes[0], nodes[1] ) );\r\n     *\r\n     *     //output: false\r\n     *     console.log( UE.dom.domUtils.isSameStyle( nodes[2], nodes[3] ) );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    isSameStyle:function (nodeA, nodeB) {\r\n        var styleA = nodeA.style.cssText.replace(/( ?; ?)/g, ';').replace(/( ?: ?)/g, ':'),\r\n            styleB = nodeB.style.cssText.replace(/( ?; ?)/g, ';').replace(/( ?: ?)/g, ':');\r\n        if (browser.opera) {\r\n            styleA = nodeA.style;\r\n            styleB = nodeB.style;\r\n            if (styleA.length != styleB.length)\r\n                return false;\r\n            for (var p in styleA) {\r\n                if (/^(\\d+|csstext)$/i.test(p)) {\r\n                    continue;\r\n                }\r\n                if (styleA[p] != styleB[p]) {\r\n                    return false;\r\n                }\r\n            }\r\n            return true;\r\n        }\r\n        if (!styleA || !styleB) {\r\n            return styleA == styleB;\r\n        }\r\n        styleA = styleA.split(';');\r\n        styleB = styleB.split(';');\r\n        if (styleA.length != styleB.length) {\r\n            return false;\r\n        }\r\n        for (var i = 0, ci; ci = styleA[i++];) {\r\n            if (utils.indexOf(styleB, ci) == -1) {\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    },\r\n    /**\r\n     * 检查节点node是否为block元素\r\n     * @method isBlockElm\r\n     * @param { Node } node 需要检测的节点对象\r\n     * @return { Boolean } 是否是block元素节点\r\n     * @warning 该方法的判断规则如下： 如果该元素原本是block元素， 则不论该元素当前的css样式是什么都会返回true；\r\n     *          否则，检测该元素的css样式， 如果该元素当前是block元素， 则返回true。 其余情况下都返回false。\r\n     * @example\r\n     * ```html\r\n     * <span id=\"test1\" style=\"display: block\"></span>\r\n     * <span id=\"test2\"></span>\r\n     * <div id=\"test3\" style=\"display: inline\"></div>\r\n     *\r\n     * <script>\r\n     *\r\n     *     //output: true\r\n     *     console.log( UE.dom.domUtils.isBlockElm( document.getElementById(\"test1\") ) );\r\n     *\r\n     *     //output: false\r\n     *     console.log( UE.dom.domUtils.isBlockElm( document.getElementById(\"test2\") ) );\r\n     *\r\n     *     //output: true\r\n     *     console.log( UE.dom.domUtils.isBlockElm( document.getElementById(\"test3\") ) );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    isBlockElm:function (node) {\r\n        return node.nodeType == 1 && (dtd.$block[node.tagName] || styleBlock[domUtils.getComputedStyle(node, 'display')]) && !dtd.$nonChild[node.tagName];\r\n    },\r\n    /**\r\n     * 检测node节点是否为body节点\r\n     * @method isBody\r\n     * @param { Element } node 需要检测的dom元素\r\n     * @return { Boolean } 给定的元素是否是body元素\r\n     * @example\r\n     * ```javascript\r\n     * //output: true\r\n     * console.log( UE.dom.domUtils.isBody( document.body ) );\r\n     * ```\r\n     */\r\n    isBody:function (node) {\r\n        return  node && node.nodeType == 1 && node.tagName.toLowerCase() == 'body';\r\n    },\r\n    /**\r\n     * 以node节点为分界，将该节点的指定祖先节点parent拆分成两个独立的节点，\r\n     * 拆分形成的两个节点之间是node节点\r\n     * @method breakParent\r\n     * @param { Node } node 作为分界的节点对象\r\n     * @param { Node } parent 该节点必须是node节点的祖先节点， 且是block节点。\r\n     * @return { Node } 给定的node分界节点\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     *      var node = document.createElement(\"span\"),\r\n     *          wrapNode = document.createElement( \"div\" ),\r\n     *          parent = document.createElement(\"p\");\r\n     *\r\n     *      parent.appendChild( node );\r\n     *      wrapNode.appendChild( parent );\r\n     *\r\n     *      //拆分前\r\n     *      //output: <p><span></span></p>\r\n     *      console.log( wrapNode.innerHTML );\r\n     *\r\n     *\r\n     *      UE.dom.domUtils.breakParent( node, parent );\r\n     *      //拆分后\r\n     *      //output: <p></p><span></span><p></p>\r\n     *      console.log( wrapNode.innerHTML );\r\n     *\r\n     * ```\r\n     */\r\n    breakParent:function (node, parent) {\r\n        var tmpNode,\r\n            parentClone = node,\r\n            clone = node,\r\n            leftNodes,\r\n            rightNodes;\r\n        do {\r\n            parentClone = parentClone.parentNode;\r\n            if (leftNodes) {\r\n                tmpNode = parentClone.cloneNode(false);\r\n                tmpNode.appendChild(leftNodes);\r\n                leftNodes = tmpNode;\r\n                tmpNode = parentClone.cloneNode(false);\r\n                tmpNode.appendChild(rightNodes);\r\n                rightNodes = tmpNode;\r\n            } else {\r\n                leftNodes = parentClone.cloneNode(false);\r\n                rightNodes = leftNodes.cloneNode(false);\r\n            }\r\n            while (tmpNode = clone.previousSibling) {\r\n                leftNodes.insertBefore(tmpNode, leftNodes.firstChild);\r\n            }\r\n            while (tmpNode = clone.nextSibling) {\r\n                rightNodes.appendChild(tmpNode);\r\n            }\r\n            clone = parentClone;\r\n        } while (parent !== parentClone);\r\n        tmpNode = parent.parentNode;\r\n        tmpNode.insertBefore(leftNodes, parent);\r\n        tmpNode.insertBefore(rightNodes, parent);\r\n        tmpNode.insertBefore(node, rightNodes);\r\n        domUtils.remove(parent);\r\n        return node;\r\n    },\r\n    /**\r\n     * 检查节点node是否是空inline节点\r\n     * @method  isEmptyInlineElement\r\n     * @param { Node } node 需要检测的节点对象\r\n     * @return { Number }  如果给定的节点是空的inline节点， 则返回1, 否则返回0。\r\n     * @example\r\n     * ```html\r\n     * <b><i></i></b> => 1\r\n     * <b><i></i><u></u></b> => 1\r\n     * <b></b> => 1\r\n     * <b>xx<i></i></b> => 0\r\n     * ```\r\n     */\r\n    isEmptyInlineElement:function (node) {\r\n        if (node.nodeType != 1 || !dtd.$removeEmpty[ node.tagName ]) {\r\n            return 0;\r\n        }\r\n        node = node.firstChild;\r\n        while (node) {\r\n            //如果是创建的bookmark就跳过\r\n            if (domUtils.isBookmarkNode(node)) {\r\n                return 0;\r\n            }\r\n            if (node.nodeType == 1 && !domUtils.isEmptyInlineElement(node) ||\r\n                node.nodeType == 3 && !domUtils.isWhitespace(node)\r\n                ) {\r\n                return 0;\r\n            }\r\n            node = node.nextSibling;\r\n        }\r\n        return 1;\r\n\r\n    },\r\n\r\n    /**\r\n     * 删除node节点下首尾两端的空白文本子节点\r\n     * @method trimWhiteTextNode\r\n     * @param { Element } node 需要执行删除操作的元素对象\r\n     * @example\r\n     * ```javascript\r\n     *      var node = document.createElement(\"div\");\r\n     *\r\n     *      node.appendChild( document.createTextNode( \"\" ) );\r\n     *\r\n     *      node.appendChild( document.createElement(\"div\") );\r\n     *\r\n     *      node.appendChild( document.createTextNode( \"\" ) );\r\n     *\r\n     *      //3\r\n     *      console.log( node.childNodes.length );\r\n     *\r\n     *      UE.dom.domUtils.trimWhiteTextNode( node );\r\n     *\r\n     *      //1\r\n     *      console.log( node.childNodes.length );\r\n     * ```\r\n     */\r\n    trimWhiteTextNode:function (node) {\r\n        function remove(dir) {\r\n            var child;\r\n            while ((child = node[dir]) && child.nodeType == 3 && domUtils.isWhitespace(child)) {\r\n                node.removeChild(child);\r\n            }\r\n        }\r\n        remove('firstChild');\r\n        remove('lastChild');\r\n    },\r\n\r\n    /**\r\n     * 合并node节点下相同的子节点\r\n     * @name mergeChild\r\n     * @desc\r\n     * UE.dom.domUtils.mergeChild(node,tagName) //tagName要合并的子节点的标签\r\n     * @example\r\n     * <p><span style=\"font-size:12px;\">xx<span style=\"font-size:12px;\">aa</span>xx</span></p>\r\n     * ==> UE.dom.domUtils.mergeChild(node,'span')\r\n     * <p><span style=\"font-size:12px;\">xxaaxx</span></p>\r\n     */\r\n    mergeChild:function (node, tagName, attrs) {\r\n        var list = domUtils.getElementsByTagName(node, node.tagName.toLowerCase());\r\n        for (var i = 0, ci; ci = list[i++];) {\r\n            if (!ci.parentNode || domUtils.isBookmarkNode(ci)) {\r\n                continue;\r\n            }\r\n            //span单独处理\r\n            if (ci.tagName.toLowerCase() == 'span') {\r\n                if (node === ci.parentNode) {\r\n                    domUtils.trimWhiteTextNode(node);\r\n                    if (node.childNodes.length == 1) {\r\n                        node.style.cssText = ci.style.cssText + \";\" + node.style.cssText;\r\n                        domUtils.remove(ci, true);\r\n                        continue;\r\n                    }\r\n                }\r\n                ci.style.cssText = node.style.cssText + ';' + ci.style.cssText;\r\n                if (attrs) {\r\n                    var style = attrs.style;\r\n                    if (style) {\r\n                        style = style.split(';');\r\n                        for (var j = 0, s; s = style[j++];) {\r\n                            ci.style[utils.cssStyleToDomStyle(s.split(':')[0])] = s.split(':')[1];\r\n                        }\r\n                    }\r\n                }\r\n                if (domUtils.isSameStyle(ci, node)) {\r\n                    domUtils.remove(ci, true);\r\n                }\r\n                continue;\r\n            }\r\n            if (domUtils.isSameElement(node, ci)) {\r\n                domUtils.remove(ci, true);\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     * 原生方法getElementsByTagName的封装\r\n     * @method getElementsByTagName\r\n     * @param { Node } node 目标节点对象\r\n     * @param { String } tagName 需要查找的节点的tagName， 多个tagName以空格分割\r\n     * @return { Array } 符合条件的节点集合\r\n     */\r\n    getElementsByTagName:function (node, name,filter) {\r\n        if(filter && utils.isString(filter)){\r\n           var className = filter;\r\n           filter =  function(node){return domUtils.hasClass(node,className)}\r\n        }\r\n        name = utils.trim(name).replace(/[ ]{2,}/g,' ').split(' ');\r\n        var arr = [];\r\n        for(var n = 0,ni;ni=name[n++];){\r\n            var list = node.getElementsByTagName(ni);\r\n            for (var i = 0, ci; ci = list[i++];) {\r\n                if(!filter || filter(ci))\r\n                    arr.push(ci);\r\n            }\r\n        }\r\n\r\n        return arr;\r\n    },\r\n    /**\r\n     * 将节点node提取到父节点上\r\n     * @method mergeToParent\r\n     * @param { Element } node 需要提取的元素对象\r\n     * @example\r\n     * ```html\r\n     * <div id=\"parent\">\r\n     *     <div id=\"sub\">\r\n     *         <span id=\"child\"></span>\r\n     *     </div>\r\n     * </div>\r\n     *\r\n     * <script>\r\n     *\r\n     *     var child = document.getElementById( \"child\" );\r\n     *\r\n     *     //output: sub\r\n     *     console.log( child.parentNode.id );\r\n     *\r\n     *     UE.dom.domUtils.mergeToParent( child );\r\n     *\r\n     *     //output: parent\r\n     *     console.log( child.parentNode.id );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    mergeToParent:function (node) {\r\n        var parent = node.parentNode;\r\n        while (parent && dtd.$removeEmpty[parent.tagName]) {\r\n            if (parent.tagName == node.tagName || parent.tagName == 'A') {//针对a标签单独处理\r\n                domUtils.trimWhiteTextNode(parent);\r\n                //span需要特殊处理  不处理这样的情况 <span stlye=\"color:#fff\">xxx<span style=\"color:#ccc\">xxx</span>xxx</span>\r\n                if (parent.tagName == 'SPAN' && !domUtils.isSameStyle(parent, node)\r\n                    || (parent.tagName == 'A' && node.tagName == 'SPAN')) {\r\n                    if (parent.childNodes.length > 1 || parent !== node.parentNode) {\r\n                        node.style.cssText = parent.style.cssText + \";\" + node.style.cssText;\r\n                        parent = parent.parentNode;\r\n                        continue;\r\n                    } else {\r\n                        parent.style.cssText += \";\" + node.style.cssText;\r\n                        //trace:952 a标签要保持下划线\r\n                        if (parent.tagName == 'A') {\r\n                            parent.style.textDecoration = 'underline';\r\n                        }\r\n                    }\r\n                }\r\n                if (parent.tagName != 'A') {\r\n                    parent === node.parentNode && domUtils.remove(node, true);\r\n                    break;\r\n                }\r\n            }\r\n            parent = parent.parentNode;\r\n        }\r\n    },\r\n    /**\r\n     * 合并节点node的左右兄弟节点\r\n     * @method mergeSibling\r\n     * @param { Element } node 需要合并的目标节点\r\n     * @example\r\n     * ```html\r\n     * <b>xxxx</b><b id=\"test\">ooo</b><b>xxxx</b>\r\n     *\r\n     * <script>\r\n     *     var demoNode = document.getElementById(\"test\");\r\n     *     UE.dom.domUtils.mergeSibling( demoNode );\r\n     *     //output: xxxxoooxxxx\r\n     *     console.log( demoNode.innerHTML );\r\n     * </script>\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 合并节点node的左右兄弟节点， 可以根据给定的条件选择是否忽略合并左节点。\r\n     * @method mergeSibling\r\n     * @param { Element } node 需要合并的目标节点\r\n     * @param { Boolean } ignorePre 是否忽略合并左节点\r\n     * @example\r\n     * ```html\r\n     * <b>xxxx</b><b id=\"test\">ooo</b><b>xxxx</b>\r\n     *\r\n     * <script>\r\n     *     var demoNode = document.getElementById(\"test\");\r\n     *     UE.dom.domUtils.mergeSibling( demoNode, true );\r\n     *     //output: oooxxxx\r\n     *     console.log( demoNode.innerHTML );\r\n     * </script>\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 合并节点node的左右兄弟节点，可以根据给定的条件选择是否忽略合并左右节点。\r\n     * @method mergeSibling\r\n     * @param { Element } node 需要合并的目标节点\r\n     * @param { Boolean } ignorePre 是否忽略合并左节点\r\n     * @param { Boolean } ignoreNext 是否忽略合并右节点\r\n     * @remind 如果同时忽略左右节点， 则该操作什么也不会做\r\n     * @example\r\n     * ```html\r\n     * <b>xxxx</b><b id=\"test\">ooo</b><b>xxxx</b>\r\n     *\r\n     * <script>\r\n     *     var demoNode = document.getElementById(\"test\");\r\n     *     UE.dom.domUtils.mergeSibling( demoNode, false, true );\r\n     *     //output: xxxxooo\r\n     *     console.log( demoNode.innerHTML );\r\n     * </script>\r\n     * ```\r\n     */\r\n    mergeSibling:function (node, ignorePre, ignoreNext) {\r\n        function merge(rtl, start, node) {\r\n            var next;\r\n            if ((next = node[rtl]) && !domUtils.isBookmarkNode(next) && next.nodeType == 1 && domUtils.isSameElement(node, next)) {\r\n                while (next.firstChild) {\r\n                    if (start == 'firstChild') {\r\n                        node.insertBefore(next.lastChild, node.firstChild);\r\n                    } else {\r\n                        node.appendChild(next.firstChild);\r\n                    }\r\n                }\r\n                domUtils.remove(next);\r\n            }\r\n        }\r\n        !ignorePre && merge('previousSibling', 'firstChild', node);\r\n        !ignoreNext && merge('nextSibling', 'lastChild', node);\r\n    },\r\n\r\n    /**\r\n     * 设置节点node及其子节点不会被选中\r\n     * @method unSelectable\r\n     * @param { Element } node 需要执行操作的dom元素\r\n     * @remind 执行该操作后的节点， 将不能被鼠标选中\r\n     * @example\r\n     * ```javascript\r\n     * UE.dom.domUtils.unSelectable( document.body );\r\n     * ```\r\n     */\r\n    unSelectable:ie && browser.ie9below || browser.opera ? function (node) {\r\n        //for ie9\r\n        node.onselectstart = function () {\r\n            return false;\r\n        };\r\n        node.onclick = node.onkeyup = node.onkeydown = function () {\r\n            return false;\r\n        };\r\n        node.unselectable = 'on';\r\n        node.setAttribute(\"unselectable\", \"on\");\r\n        for (var i = 0, ci; ci = node.all[i++];) {\r\n            switch (ci.tagName.toLowerCase()) {\r\n                case 'iframe' :\r\n                case 'textarea' :\r\n                case 'input' :\r\n                case 'select' :\r\n                    break;\r\n                default :\r\n                    ci.unselectable = 'on';\r\n                    node.setAttribute(\"unselectable\", \"on\");\r\n            }\r\n        }\r\n    } : function (node) {\r\n        node.style.MozUserSelect =\r\n            node.style.webkitUserSelect =\r\n                node.style.msUserSelect =\r\n                    node.style.KhtmlUserSelect = 'none';\r\n    },\r\n    /**\r\n     * 删除节点node上的指定属性名称的属性\r\n     * @method  removeAttributes\r\n     * @param { Node } node 需要删除属性的节点对象\r\n     * @param { String } attrNames 可以是空格隔开的多个属性名称，该操作将会依次删除相应的属性\r\n     * @example\r\n     * ```html\r\n     * <div id=\"wrap\">\r\n     *      <span style=\"font-size:14px;\" id=\"test\" name=\"followMe\">xxxxx</span>\r\n     * </div>\r\n     *\r\n     * <script>\r\n     *\r\n     *     UE.dom.domUtils.removeAttributes( document.getElementById( \"test\" ), \"id name\" );\r\n     *\r\n     *     //output: <span style=\"font-size:14px;\">xxxxx</span>\r\n     *     console.log( document.getElementById(\"wrap\").innerHTML );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 删除节点node上的指定属性名称的属性\r\n     * @method  removeAttributes\r\n     * @param { Node } node 需要删除属性的节点对象\r\n     * @param { Array } attrNames 需要删除的属性名数组\r\n     * @example\r\n     * ```html\r\n     * <div id=\"wrap\">\r\n     *      <span style=\"font-size:14px;\" id=\"test\" name=\"followMe\">xxxxx</span>\r\n     * </div>\r\n     *\r\n     * <script>\r\n     *\r\n     *     UE.dom.domUtils.removeAttributes( document.getElementById( \"test\" ), [\"id\", \"name\"] );\r\n     *\r\n     *     //output: <span style=\"font-size:14px;\">xxxxx</span>\r\n     *     console.log( document.getElementById(\"wrap\").innerHTML );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    removeAttributes:function (node, attrNames) {\r\n        attrNames = utils.isArray(attrNames) ? attrNames : utils.trim(attrNames).replace(/[ ]{2,}/g,' ').split(' ');\r\n        for (var i = 0, ci; ci = attrNames[i++];) {\r\n            ci = attrFix[ci] || ci;\r\n            switch (ci) {\r\n                case 'className':\r\n                    node[ci] = '';\r\n                    break;\r\n                case 'style':\r\n                    node.style.cssText = '';\r\n                    var val = node.getAttributeNode('style');\r\n                    !browser.ie && val && node.removeAttributeNode(val);\r\n            }\r\n            node.removeAttribute(ci);\r\n        }\r\n    },\r\n    /**\r\n     * 在doc下创建一个标签名为tag，属性为attrs的元素\r\n     * @method createElement\r\n     * @param { DomDocument } doc 新创建的元素属于该document节点创建\r\n     * @param { String } tagName 需要创建的元素的标签名\r\n     * @param { Object } attrs 新创建的元素的属性key-value集合\r\n     * @return { Element } 新创建的元素对象\r\n     * @example\r\n     * ```javascript\r\n     * var ele = UE.dom.domUtils.createElement( document, 'div', {\r\n     *     id: 'test'\r\n     * } );\r\n     *\r\n     * //output: DIV\r\n     * console.log( ele.tagName );\r\n     *\r\n     * //output: test\r\n     * console.log( ele.id );\r\n     *\r\n     * ```\r\n     */\r\n    createElement:function (doc, tag, attrs) {\r\n        return domUtils.setAttributes(doc.createElement(tag), attrs)\r\n    },\r\n    /**\r\n     * 为节点node添加属性attrs，attrs为属性键值对\r\n     * @method setAttributes\r\n     * @param { Element } node 需要设置属性的元素对象\r\n     * @param { Object } attrs 需要设置的属性名-值对\r\n     * @return { Element } 设置属性的元素对象\r\n     * @example\r\n     * ```html\r\n     * <span id=\"test\"></span>\r\n     *\r\n     * <script>\r\n     *\r\n     *     var testNode = UE.dom.domUtils.setAttributes( document.getElementById( \"test\" ), {\r\n     *         id: 'demo'\r\n     *     } );\r\n     *\r\n     *     //output: demo\r\n     *     console.log( testNode.id );\r\n     *\r\n     * </script>\r\n     *\r\n     */\r\n    setAttributes:function (node, attrs) {\r\n        for (var attr in attrs) {\r\n            if(attrs.hasOwnProperty(attr)){\r\n                var value = attrs[attr];\r\n                switch (attr) {\r\n                    case 'class':\r\n                        //ie下要这样赋值，setAttribute不起作用\r\n                        node.className = value;\r\n                        break;\r\n                    case 'style' :\r\n                        node.style.cssText = node.style.cssText + \";\" + value;\r\n                        break;\r\n                    case 'innerHTML':\r\n                        node[attr] = value;\r\n                        break;\r\n                    case 'value':\r\n                        node.value = value;\r\n                        break;\r\n                    default:\r\n                        node.setAttribute(attrFix[attr] || attr, value);\r\n                }\r\n            }\r\n        }\r\n        return node;\r\n    },\r\n\r\n    /**\r\n     * 获取元素element经过计算后的样式值\r\n     * @method getComputedStyle\r\n     * @param { Element } element 需要获取样式的元素对象\r\n     * @param { String } styleName 需要获取的样式名\r\n     * @return { String } 获取到的样式值\r\n     * @example\r\n     * ```html\r\n     * <style type=\"text/css\">\r\n     *      #test {\r\n     *          font-size: 15px;\r\n     *      }\r\n     * </style>\r\n     *\r\n     * <span id=\"test\"></span>\r\n     *\r\n     * <script>\r\n     *     //output: 15px\r\n     *     console.log( UE.dom.domUtils.getComputedStyle( document.getElementById( \"test\" ), 'font-size' ) );\r\n     * </script>\r\n     * ```\r\n     */\r\n    getComputedStyle:function (element, styleName) {\r\n        //一下的属性单独处理\r\n        var pros = 'width height top left';\r\n\r\n        if(pros.indexOf(styleName) > -1){\r\n            return element['offset' + styleName.replace(/^\\w/,function(s){return s.toUpperCase()})] + 'px';\r\n        }\r\n        //忽略文本节点\r\n        if (element.nodeType == 3) {\r\n            element = element.parentNode;\r\n        }\r\n        //ie下font-size若body下定义了font-size，则从currentStyle里会取到这个font-size. 取不到实际值，故此修改.\r\n        if (browser.ie && browser.version < 9 && styleName == 'font-size' && !element.style.fontSize &&\r\n            !dtd.$empty[element.tagName] && !dtd.$nonChild[element.tagName]) {\r\n            var span = element.ownerDocument.createElement('span');\r\n            span.style.cssText = 'padding:0;border:0;font-family:simsun;';\r\n            span.innerHTML = '.';\r\n            element.appendChild(span);\r\n            var result = span.offsetHeight;\r\n            element.removeChild(span);\r\n            span = null;\r\n            return result + 'px';\r\n        }\r\n        try {\r\n            var value = domUtils.getStyle(element, styleName) ||\r\n                (window.getComputedStyle ? domUtils.getWindow(element).getComputedStyle(element, '').getPropertyValue(styleName) :\r\n                    ( element.currentStyle || element.style )[utils.cssStyleToDomStyle(styleName)]);\r\n\r\n        } catch (e) {\r\n            return \"\";\r\n        }\r\n        return utils.transUnitToPx(utils.fixColor(styleName, value));\r\n    },\r\n    /**\r\n     * 删除元素element指定的className\r\n     * @method removeClasses\r\n     * @param { Element } ele 需要删除class的元素节点\r\n     * @param { String } classNames 需要删除的className， 多个className之间以空格分开\r\n     * @example\r\n     * ```html\r\n     * <span id=\"test\" class=\"test1 test2 test3\">xxx</span>\r\n     *\r\n     * <script>\r\n     *\r\n     *     var testNode = document.getElementById( \"test\" );\r\n     *     UE.dom.domUtils.removeClasses( testNode, \"test1 test2\" );\r\n     *\r\n     *     //output: test3\r\n     *     console.log( testNode.className );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 删除元素element指定的className\r\n     * @method removeClasses\r\n     * @param { Element } ele 需要删除class的元素节点\r\n     * @param { Array } classNames 需要删除的className数组\r\n     * @example\r\n     * ```html\r\n     * <span id=\"test\" class=\"test1 test2 test3\">xxx</span>\r\n     *\r\n     * <script>\r\n     *\r\n     *     var testNode = document.getElementById( \"test\" );\r\n     *     UE.dom.domUtils.removeClasses( testNode, [\"test1\", \"test2\"] );\r\n     *\r\n     *     //output: test3\r\n     *     console.log( testNode.className );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    removeClasses:function (elm, classNames) {\r\n        classNames = utils.isArray(classNames) ? classNames :\r\n            utils.trim(classNames).replace(/[ ]{2,}/g,' ').split(' ');\r\n        for(var i = 0,ci,cls = elm.className;ci=classNames[i++];){\r\n            cls = cls.replace(new RegExp('\\\\b' + ci + '\\\\b'),'')\r\n        }\r\n        cls = utils.trim(cls).replace(/[ ]{2,}/g,' ');\r\n        if(cls){\r\n            elm.className = cls;\r\n        }else{\r\n            domUtils.removeAttributes(elm,['class']);\r\n        }\r\n    },\r\n    /**\r\n     * 给元素element添加className\r\n     * @method addClass\r\n     * @param { Node } ele 需要增加className的元素\r\n     * @param { String } classNames 需要添加的className， 多个className之间以空格分割\r\n     * @remind 相同的类名不会被重复添加\r\n     * @example\r\n     * ```html\r\n     * <span id=\"test\" class=\"cls1 cls2\"></span>\r\n     *\r\n     * <script>\r\n     *     var testNode = document.getElementById(\"test\");\r\n     *\r\n     *     UE.dom.domUtils.addClass( testNode, \"cls2 cls3 cls4\" );\r\n     *\r\n     *     //output: cl1 cls2 cls3 cls4\r\n     *     console.log( testNode.className );\r\n     *\r\n     * <script>\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 给元素element添加className\r\n     * @method addClass\r\n     * @param { Node } ele 需要增加className的元素\r\n     * @param { Array } classNames 需要添加的className的数组\r\n     * @remind 相同的类名不会被重复添加\r\n     * @example\r\n     * ```html\r\n     * <span id=\"test\" class=\"cls1 cls2\"></span>\r\n     *\r\n     * <script>\r\n     *     var testNode = document.getElementById(\"test\");\r\n     *\r\n     *     UE.dom.domUtils.addClass( testNode, [\"cls2\", \"cls3\", \"cls4\"] );\r\n     *\r\n     *     //output: cl1 cls2 cls3 cls4\r\n     *     console.log( testNode.className );\r\n     *\r\n     * <script>\r\n     * ```\r\n     */\r\n    addClass:function (elm, classNames) {\r\n        if(!elm)return;\r\n        classNames = utils.trim(classNames).replace(/[ ]{2,}/g,' ').split(' ');\r\n        for(var i = 0,ci,cls = elm.className;ci=classNames[i++];){\r\n            if(!new RegExp('\\\\b' + ci + '\\\\b').test(cls)){\r\n                cls += ' ' + ci;\r\n            }\r\n        }\r\n        elm.className = utils.trim(cls);\r\n    },\r\n    /**\r\n     * 判断元素element是否包含给定的样式类名className\r\n     * @method hasClass\r\n     * @param { Node } ele 需要检测的元素\r\n     * @param { String } classNames 需要检测的className， 多个className之间用空格分割\r\n     * @return { Boolean } 元素是否包含所有给定的className\r\n     * @example\r\n     * ```html\r\n     * <span id=\"test1\" class=\"cls1 cls2\"></span>\r\n     *\r\n     * <script>\r\n     *     var test1 = document.getElementById(\"test1\");\r\n     *\r\n     *     //output: false\r\n     *     console.log( UE.dom.domUtils.hasClass( test1, \"cls2 cls1 cls3\" ) );\r\n     *\r\n     *     //output: true\r\n     *     console.log( UE.dom.domUtils.hasClass( test1, \"cls2 cls1\" ) );\r\n     * </script>\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 判断元素element是否包含给定的样式类名className\r\n     * @method hasClass\r\n     * @param { Node } ele 需要检测的元素\r\n     * @param { Array } classNames 需要检测的className数组\r\n     * @return { Boolean } 元素是否包含所有给定的className\r\n     * @example\r\n     * ```html\r\n     * <span id=\"test1\" class=\"cls1 cls2\"></span>\r\n     *\r\n     * <script>\r\n     *     var test1 = document.getElementById(\"test1\");\r\n     *\r\n     *     //output: false\r\n     *     console.log( UE.dom.domUtils.hasClass( test1, [ \"cls2\", \"cls1\", \"cls3\" ] ) );\r\n     *\r\n     *     //output: true\r\n     *     console.log( UE.dom.domUtils.hasClass( test1, [ \"cls2\", \"cls1\" ]) );\r\n     * </script>\r\n     * ```\r\n     */\r\n    hasClass:function (element, className) {\r\n        if(utils.isRegExp(className)){\r\n            return className.test(element.className)\r\n        }\r\n        className = utils.trim(className).replace(/[ ]{2,}/g,' ').split(' ');\r\n        for(var i = 0,ci,cls = element.className;ci=className[i++];){\r\n            if(!new RegExp('\\\\b' + ci + '\\\\b','i').test(cls)){\r\n                return false;\r\n            }\r\n        }\r\n        return i - 1 == className.length;\r\n    },\r\n\r\n    /**\r\n     * 阻止事件默认行为\r\n     * @method preventDefault\r\n     * @param { Event } evt 需要阻止默认行为的事件对象\r\n     * @example\r\n     * ```javascript\r\n     * UE.dom.domUtils.preventDefault( evt );\r\n     * ```\r\n     */\r\n    preventDefault:function (evt) {\r\n        evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false);\r\n    },\r\n    /**\r\n     * 删除元素element指定的样式\r\n     * @method removeStyle\r\n     * @param { Element } element 需要删除样式的元素\r\n     * @param { String } styleName 需要删除的样式名\r\n     * @example\r\n     * ```html\r\n     * <span id=\"test\" style=\"color: red; background: blue;\"></span>\r\n     *\r\n     * <script>\r\n     *\r\n     *     var testNode = document.getElementById(\"test\");\r\n     *\r\n     *     UE.dom.domUtils.removeStyle( testNode, 'color' );\r\n     *\r\n     *     //output: background: blue;\r\n     *     console.log( testNode.style.cssText );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    removeStyle:function (element, name) {\r\n        if(browser.ie ){\r\n            //针对color先单独处理一下\r\n            if(name == 'color'){\r\n                name = '(^|;)' + name;\r\n            }\r\n            element.style.cssText = element.style.cssText.replace(new RegExp(name + '[^:]*:[^;]+;?','ig'),'')\r\n        }else{\r\n            if (element.style.removeProperty) {\r\n                element.style.removeProperty (name);\r\n            }else {\r\n                element.style.removeAttribute (utils.cssStyleToDomStyle(name));\r\n            }\r\n        }\r\n\r\n\r\n        if (!element.style.cssText) {\r\n            domUtils.removeAttributes(element, ['style']);\r\n        }\r\n    },\r\n    /**\r\n     * 获取元素element的style属性的指定值\r\n     * @method getStyle\r\n     * @param { Element } element 需要获取属性值的元素\r\n     * @param { String } styleName 需要获取的style的名称\r\n     * @warning 该方法仅获取元素style属性中所标明的值\r\n     * @return { String } 该元素包含指定的style属性值\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\" style=\"color: red;\"></div>\r\n     *\r\n     * <script>\r\n     *\r\n     *      var testNode = document.getElementById( \"test\" );\r\n     *\r\n     *      //output: red\r\n     *      console.log( UE.dom.domUtils.getStyle( testNode, \"color\" ) );\r\n     *\r\n     *      //output: \"\"\r\n     *      console.log( UE.dom.domUtils.getStyle( testNode, \"background\" ) );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    getStyle:function (element, name) {\r\n        var value = element.style[ utils.cssStyleToDomStyle(name) ];\r\n        return utils.fixColor(name, value);\r\n    },\r\n    /**\r\n     * 为元素element设置样式属性值\r\n     * @method setStyle\r\n     * @param { Element } element 需要设置样式的元素\r\n     * @param { String } styleName 样式名\r\n     * @param { String } styleValue 样式值\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\"></div>\r\n     *\r\n     * <script>\r\n     *\r\n     *      var testNode = document.getElementById( \"test\" );\r\n     *\r\n     *      //output: \"\"\r\n     *      console.log( testNode.style.color );\r\n     *\r\n     *      UE.dom.domUtils.setStyle( testNode, 'color', 'red' );\r\n     *      //output: \"red\"\r\n     *      console.log( testNode.style.color );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    setStyle:function (element, name, value) {\r\n        element.style[utils.cssStyleToDomStyle(name)] = value;\r\n        if(!utils.trim(element.style.cssText)){\r\n            this.removeAttributes(element,'style')\r\n        }\r\n    },\r\n    /**\r\n     * 为元素element设置多个样式属性值\r\n     * @method setStyles\r\n     * @param { Element } element 需要设置样式的元素\r\n     * @param { Object } styles 样式名值对\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\"></div>\r\n     *\r\n     * <script>\r\n     *\r\n     *      var testNode = document.getElementById( \"test\" );\r\n     *\r\n     *      //output: \"\"\r\n     *      console.log( testNode.style.color );\r\n     *\r\n     *      UE.dom.domUtils.setStyles( testNode, {\r\n     *          'color': 'red'\r\n     *      } );\r\n     *      //output: \"red\"\r\n     *      console.log( testNode.style.color );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    setStyles:function (element, styles) {\r\n        for (var name in styles) {\r\n            if (styles.hasOwnProperty(name)) {\r\n                domUtils.setStyle(element, name, styles[name]);\r\n            }\r\n        }\r\n    },\r\n    /**\r\n     * 删除_moz_dirty属性\r\n     * @private\r\n     * @method removeDirtyAttr\r\n     */\r\n    removeDirtyAttr:function (node) {\r\n        for (var i = 0, ci, nodes = node.getElementsByTagName('*'); ci = nodes[i++];) {\r\n            ci.removeAttribute('_moz_dirty');\r\n        }\r\n        node.removeAttribute('_moz_dirty');\r\n    },\r\n    /**\r\n     * 获取子节点的数量\r\n     * @method getChildCount\r\n     * @param { Element } node 需要检测的元素\r\n     * @return { Number } 给定的node元素的子节点数量\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\">\r\n     *      <span></span>\r\n     * </div>\r\n     *\r\n     * <script>\r\n     *\r\n     *     //output: 3\r\n     *     console.log( UE.dom.domUtils.getChildCount( document.getElementById(\"test\") ) );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 根据给定的过滤规则， 获取符合条件的子节点的数量\r\n     * @method getChildCount\r\n     * @param { Element } node 需要检测的元素\r\n     * @param { Function } fn 过滤器， 要求对符合条件的子节点返回true， 反之则要求返回false\r\n     * @return { Number } 符合过滤条件的node元素的子节点数量\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\">\r\n     *      <span></span>\r\n     * </div>\r\n     *\r\n     * <script>\r\n     *\r\n     *     //output: 1\r\n     *     console.log( UE.dom.domUtils.getChildCount( document.getElementById(\"test\"), function ( node ) {\r\n     *\r\n     *         return node.nodeType === 1;\r\n     *\r\n     *     } ) );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    getChildCount:function (node, fn) {\r\n        var count = 0, first = node.firstChild;\r\n        fn = fn || function () {\r\n            return 1;\r\n        };\r\n        while (first) {\r\n            if (fn(first)) {\r\n                count++;\r\n            }\r\n            first = first.nextSibling;\r\n        }\r\n        return count;\r\n    },\r\n\r\n    /**\r\n     * 判断给定节点是否为空节点\r\n     * @method isEmptyNode\r\n     * @param { Node } node 需要检测的节点对象\r\n     * @return { Boolean } 节点是否为空\r\n     * @example\r\n     * ```javascript\r\n     * UE.dom.domUtils.isEmptyNode( document.body );\r\n     * ```\r\n     */\r\n    isEmptyNode:function (node) {\r\n        return !node.firstChild || domUtils.getChildCount(node, function (node) {\r\n            return  !domUtils.isBr(node) && !domUtils.isBookmarkNode(node) && !domUtils.isWhitespace(node)\r\n        }) == 0\r\n    },\r\n    clearSelectedArr:function (nodes) {\r\n        var node;\r\n        while (node = nodes.pop()) {\r\n            domUtils.removeAttributes(node, ['class']);\r\n        }\r\n    },\r\n    /**\r\n     * 将显示区域滚动到指定节点的位置\r\n     * @method scrollToView\r\n     * @param    {Node}   node    节点\r\n     * @param    {window}   win      window对象\r\n     * @param    {Number}    offsetTop    距离上方的偏移量\r\n     */\r\n    scrollToView:function (node, win, offsetTop) {\r\n        var getViewPaneSize = function () {\r\n                var doc = win.document,\r\n                    mode = doc.compatMode == 'CSS1Compat';\r\n                return {\r\n                    width:( mode ? doc.documentElement.clientWidth : doc.body.clientWidth ) || 0,\r\n                    height:( mode ? doc.documentElement.clientHeight : doc.body.clientHeight ) || 0\r\n                };\r\n            },\r\n            getScrollPosition = function (win) {\r\n                if ('pageXOffset' in win) {\r\n                    return {\r\n                        x:win.pageXOffset || 0,\r\n                        y:win.pageYOffset || 0\r\n                    };\r\n                }\r\n                else {\r\n                    var doc = win.document;\r\n                    return {\r\n                        x:doc.documentElement.scrollLeft || doc.body.scrollLeft || 0,\r\n                        y:doc.documentElement.scrollTop || doc.body.scrollTop || 0\r\n                    };\r\n                }\r\n            };\r\n        var winHeight = getViewPaneSize().height, offset = winHeight * -1 + offsetTop;\r\n        offset += (node.offsetHeight || 0);\r\n        var elementPosition = domUtils.getXY(node);\r\n        offset += elementPosition.y;\r\n        var currentScroll = getScrollPosition(win).y;\r\n        // offset += 50;\r\n        if (offset > currentScroll || offset < currentScroll - winHeight) {\r\n            win.scrollTo(0, offset + (offset < 0 ? -20 : 20));\r\n        }\r\n    },\r\n    /**\r\n     * 判断给定节点是否为br\r\n     * @method isBr\r\n     * @param { Node } node 需要判断的节点对象\r\n     * @return { Boolean } 给定的节点是否是br节点\r\n     */\r\n    isBr:function (node) {\r\n        return node.nodeType == 1 && node.tagName == 'BR';\r\n    },\r\n    /**\r\n     * 判断给定的节点是否是一个“填充”节点\r\n     * @private\r\n     * @method isFillChar\r\n     * @param { Node } node 需要判断的节点\r\n     * @param { Boolean } isInStart 是否从节点内容的开始位置匹配\r\n     * @returns { Boolean } 节点是否是填充节点\r\n     */\r\n    isFillChar:function (node,isInStart) {\r\n        if(node.nodeType != 3)\r\n            return false;\r\n        var text = node.nodeValue;\r\n        if(isInStart){\r\n            return new RegExp('^' + domUtils.fillChar).test(text)\r\n        }\r\n        return !text.replace(new RegExp(domUtils.fillChar,'g'), '').length\r\n    },\r\n    isStartInblock:function (range) {\r\n        var tmpRange = range.cloneRange(),\r\n            flag = 0,\r\n            start = tmpRange.startContainer,\r\n            tmp;\r\n        if(start.nodeType == 1 && start.childNodes[tmpRange.startOffset]){\r\n            start = start.childNodes[tmpRange.startOffset];\r\n            var pre = start.previousSibling;\r\n            while(pre && domUtils.isFillChar(pre)){\r\n                start = pre;\r\n                pre = pre.previousSibling;\r\n            }\r\n        }\r\n        if(this.isFillChar(start,true) && tmpRange.startOffset == 1){\r\n            tmpRange.setStartBefore(start);\r\n            start = tmpRange.startContainer;\r\n        }\r\n\r\n        while (start && domUtils.isFillChar(start)) {\r\n            tmp = start;\r\n            start = start.previousSibling\r\n        }\r\n        if (tmp) {\r\n            tmpRange.setStartBefore(tmp);\r\n            start = tmpRange.startContainer;\r\n        }\r\n        if (start.nodeType == 1 && domUtils.isEmptyNode(start) && tmpRange.startOffset == 1) {\r\n            tmpRange.setStart(start, 0).collapse(true);\r\n        }\r\n        while (!tmpRange.startOffset) {\r\n            start = tmpRange.startContainer;\r\n            if (domUtils.isBlockElm(start) || domUtils.isBody(start)) {\r\n                flag = 1;\r\n                break;\r\n            }\r\n            var pre = tmpRange.startContainer.previousSibling,\r\n                tmpNode;\r\n            if (!pre) {\r\n                tmpRange.setStartBefore(tmpRange.startContainer);\r\n            } else {\r\n                while (pre && domUtils.isFillChar(pre)) {\r\n                    tmpNode = pre;\r\n                    pre = pre.previousSibling;\r\n                }\r\n                if (tmpNode) {\r\n                    tmpRange.setStartBefore(tmpNode);\r\n                } else {\r\n                    tmpRange.setStartBefore(tmpRange.startContainer);\r\n                }\r\n            }\r\n        }\r\n        return flag && !domUtils.isBody(tmpRange.startContainer) ? 1 : 0;\r\n    },\r\n\r\n    /**\r\n     * 判断给定的元素是否是一个空元素\r\n     * @method isEmptyBlock\r\n     * @param { Element } node 需要判断的元素\r\n     * @return { Boolean } 是否是空元素\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\"></div>\r\n     *\r\n     * <script>\r\n     *     //output: true\r\n     *     console.log( UE.dom.domUtils.isEmptyBlock( document.getElementById(\"test\") ) );\r\n     * </script>\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 根据指定的判断规则判断给定的元素是否是一个空元素\r\n     * @method isEmptyBlock\r\n     * @param { Element } node 需要判断的元素\r\n     * @param { RegExp } reg 对内容执行判断的正则表达式对象\r\n     * @return { Boolean } 是否是空元素\r\n     */\r\n    isEmptyBlock:function (node,reg) {\r\n        if(node.nodeType != 1)\r\n            return 0;\r\n        reg = reg || new RegExp('[ \\xa0\\t\\r\\n' + domUtils.fillChar + ']', 'g');\r\n\r\n        if (node[browser.ie ? 'innerText' : 'textContent'].replace(reg, '').length > 0) {\r\n            return 0;\r\n        }\r\n        for (var n in dtd.$isNotEmpty) {\r\n            if (node.getElementsByTagName(n).length) {\r\n                return 0;\r\n            }\r\n        }\r\n        return 1;\r\n    },\r\n\r\n    /**\r\n     * 移动元素使得该元素的位置移动指定的偏移量的距离\r\n     * @method setViewportOffset\r\n     * @param { Element } element 需要设置偏移量的元素\r\n     * @param { Object } offset 偏移量， 形如{ left: 100, top: 50 }的一个键值对， 表示该元素将在\r\n     *                                  现有的位置上向水平方向偏移offset.left的距离， 在竖直方向上偏移\r\n     *                                  offset.top的距离\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\" style=\"top: 100px; left: 50px; position: absolute;\"></div>\r\n     *\r\n     * <script>\r\n     *\r\n     *     var testNode = document.getElementById(\"test\");\r\n     *\r\n     *     UE.dom.domUtils.setViewportOffset( testNode, {\r\n     *         left: 200,\r\n     *         top: 50\r\n     *     } );\r\n     *\r\n     *     //output: top: 300px; left: 100px; position: absolute;\r\n     *     console.log( testNode.style.cssText );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    setViewportOffset:function (element, offset) {\r\n        var left = parseInt(element.style.left) | 0;\r\n        var top = parseInt(element.style.top) | 0;\r\n        var rect = element.getBoundingClientRect();\r\n        var offsetLeft = offset.left - rect.left;\r\n        var offsetTop = offset.top - rect.top;\r\n        if (offsetLeft) {\r\n            element.style.left = left + offsetLeft + 'px';\r\n        }\r\n        if (offsetTop) {\r\n            element.style.top = top + offsetTop + 'px';\r\n        }\r\n    },\r\n\r\n    /**\r\n     * 用“填充字符”填充节点\r\n     * @method fillNode\r\n     * @private\r\n     * @param { DomDocument } doc 填充的节点所在的docment对象\r\n     * @param { Node } node 需要填充的节点对象\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\"></div>\r\n     *\r\n     * <script>\r\n     *     var testNode = document.getElementById(\"test\");\r\n     *\r\n     *     //output: 0\r\n     *     console.log( testNode.childNodes.length );\r\n     *\r\n     *     UE.dom.domUtils.fillNode( document, testNode );\r\n     *\r\n     *     //output: 1\r\n     *     console.log( testNode.childNodes.length );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    fillNode:function (doc, node) {\r\n        var tmpNode = browser.ie ? doc.createTextNode(domUtils.fillChar) : doc.createElement('br');\r\n        node.innerHTML = '';\r\n        node.appendChild(tmpNode);\r\n    },\r\n\r\n    /**\r\n     * 把节点src的所有子节点追加到另一个节点tag上去\r\n     * @method moveChild\r\n     * @param { Node } src 源节点， 该节点下的所有子节点将被移除\r\n     * @param { Node } tag 目标节点， 从源节点移除的子节点将被追加到该节点下\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test1\">\r\n     *      <span></span>\r\n     * </div>\r\n     * <div id=\"test2\">\r\n     *     <div></div>\r\n     * </div>\r\n     *\r\n     * <script>\r\n     *\r\n     *     var test1 = document.getElementById(\"test1\"),\r\n     *         test2 = document.getElementById(\"test2\");\r\n     *\r\n     *     UE.dom.domUtils.moveChild( test1, test2 );\r\n     *\r\n     *     //output: \"\"（空字符串）\r\n     *     console.log( test1.innerHTML );\r\n     *\r\n     *     //output: \"<div></div><span></span>\"\r\n     *     console.log( test2.innerHTML );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 把节点src的所有子节点移动到另一个节点tag上去, 可以通过dir参数控制附加的行为是“追加”还是“插入顶部”\r\n     * @method moveChild\r\n     * @param { Node } src 源节点， 该节点下的所有子节点将被移除\r\n     * @param { Node } tag 目标节点， 从源节点移除的子节点将被附加到该节点下\r\n     * @param { Boolean } dir 附加方式， 如果为true， 则附加进去的节点将被放到目标节点的顶部， 反之，则放到末尾\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test1\">\r\n     *      <span></span>\r\n     * </div>\r\n     * <div id=\"test2\">\r\n     *     <div></div>\r\n     * </div>\r\n     *\r\n     * <script>\r\n     *\r\n     *     var test1 = document.getElementById(\"test1\"),\r\n     *         test2 = document.getElementById(\"test2\");\r\n     *\r\n     *     UE.dom.domUtils.moveChild( test1, test2, true );\r\n     *\r\n     *     //output: \"\"（空字符串）\r\n     *     console.log( test1.innerHTML );\r\n     *\r\n     *     //output: \"<span></span><div></div>\"\r\n     *     console.log( test2.innerHTML );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    moveChild:function (src, tag, dir) {\r\n        while (src.firstChild) {\r\n            if (dir && tag.firstChild) {\r\n                tag.insertBefore(src.lastChild, tag.firstChild);\r\n            } else {\r\n                tag.appendChild(src.firstChild);\r\n            }\r\n        }\r\n    },\r\n\r\n    /**\r\n     * 判断节点的标签上是否不存在任何属性\r\n     * @method hasNoAttributes\r\n     * @private\r\n     * @param { Node } node 需要检测的节点对象\r\n     * @return { Boolean } 节点是否不包含任何属性\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\"><span>xxxx</span></div>\r\n     *\r\n     * <script>\r\n     *\r\n     *     //output: false\r\n     *     console.log( UE.dom.domUtils.hasNoAttributes( document.getElementById(\"test\") ) );\r\n     *\r\n     *     //output: true\r\n     *     console.log( UE.dom.domUtils.hasNoAttributes( document.getElementById(\"test\").firstChild ) );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    hasNoAttributes:function (node) {\r\n        return browser.ie ? /^<\\w+\\s*?>/.test(node.outerHTML) : node.attributes.length == 0;\r\n    },\r\n\r\n    /**\r\n     * 检测节点是否是UEditor所使用的辅助节点\r\n     * @method isCustomeNode\r\n     * @private\r\n     * @param { Node } node 需要检测的节点\r\n     * @remind 辅助节点是指编辑器要完成工作临时添加的节点， 在输出的时候将会从编辑器内移除， 不会影响最终的结果。\r\n     * @return { Boolean } 给定的节点是否是一个辅助节点\r\n     */\r\n    isCustomeNode:function (node) {\r\n        return node.nodeType == 1 && node.getAttribute('_ue_custom_node_');\r\n    },\r\n\r\n    /**\r\n     * 检测节点的标签是否是给定的标签\r\n     * @method isTagNode\r\n     * @param { Node } node 需要检测的节点对象\r\n     * @param { String } tagName 标签\r\n     * @return { Boolean } 节点的标签是否是给定的标签\r\n     * @example\r\n     * ```html\r\n     * <div id=\"test\"></div>\r\n     *\r\n     * <script>\r\n     *\r\n     *     //output: true\r\n     *     console.log( UE.dom.domUtils.isTagNode( document.getElementById(\"test\"), \"div\" ) );\r\n     *\r\n     * </script>\r\n     * ```\r\n     */\r\n    isTagNode:function (node, tagNames) {\r\n        return node.nodeType == 1 && new RegExp('\\\\b' + node.tagName + '\\\\b','i').test(tagNames)\r\n    },\r\n\r\n    /**\r\n     * 给定一个节点数组，在通过指定的过滤器过滤后， 获取其中满足过滤条件的第一个节点\r\n     * @method filterNodeList\r\n     * @param { Array } nodeList 需要过滤的节点数组\r\n     * @param { Function } fn 过滤器， 对符合条件的节点， 执行结果返回true， 反之则返回false\r\n     * @return { Node | NULL } 如果找到符合过滤条件的节点， 则返回该节点， 否则返回NULL\r\n     * @example\r\n     * ```javascript\r\n     * var divNodes = document.getElementsByTagName(\"div\");\r\n     * divNodes = [].slice.call( divNodes, 0 );\r\n     *\r\n     * //output: null\r\n     * console.log( UE.dom.domUtils.filterNodeList( divNodes, function ( node ) {\r\n     *     return node.tagName.toLowerCase() !== 'div';\r\n     * } ) );\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 给定一个节点数组nodeList和一组标签名tagNames， 获取其中能够匹配标签名的节点集合中的第一个节点\r\n     * @method filterNodeList\r\n     * @param { Array } nodeList 需要过滤的节点数组\r\n     * @param { String } tagNames 需要匹配的标签名， 多个标签名之间用空格分割\r\n     * @return { Node | NULL } 如果找到标签名匹配的节点， 则返回该节点， 否则返回NULL\r\n     * @example\r\n     * ```javascript\r\n     * var divNodes = document.getElementsByTagName(\"div\");\r\n     * divNodes = [].slice.call( divNodes, 0 );\r\n     *\r\n     * //output: null\r\n     * console.log( UE.dom.domUtils.filterNodeList( divNodes, 'a span' ) );\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 给定一个节点数组，在通过指定的过滤器过滤后， 如果参数forAll为true， 则会返回所有满足过滤\r\n     * 条件的节点集合， 否则， 返回满足条件的节点集合中的第一个节点\r\n     * @method filterNodeList\r\n     * @param { Array } nodeList 需要过滤的节点数组\r\n     * @param { Function } fn 过滤器， 对符合条件的节点， 执行结果返回true， 反之则返回false\r\n     * @param { Boolean } forAll 是否返回整个节点数组, 如果该参数为false， 则返回节点集合中的第一个节点\r\n     * @return { Array | Node | NULL } 如果找到符合过滤条件的节点， 则根据参数forAll的值决定返回满足\r\n     *                                      过滤条件的节点数组或第一个节点， 否则返回NULL\r\n     * @example\r\n     * ```javascript\r\n     * var divNodes = document.getElementsByTagName(\"div\");\r\n     * divNodes = [].slice.call( divNodes, 0 );\r\n     *\r\n     * //output: 3（假定有3个div）\r\n     * console.log( divNodes.length );\r\n     *\r\n     * var nodes = UE.dom.domUtils.filterNodeList( divNodes, function ( node ) {\r\n     *     return node.tagName.toLowerCase() === 'div';\r\n     * }, true );\r\n     *\r\n     * //output: 3\r\n     * console.log( nodes.length );\r\n     *\r\n     * var node = UE.dom.domUtils.filterNodeList( divNodes, function ( node ) {\r\n     *     return node.tagName.toLowerCase() === 'div';\r\n     * }, false );\r\n     *\r\n     * //output: div\r\n     * console.log( node.nodeName );\r\n     * ```\r\n     */\r\n    filterNodeList : function(nodelist,filter,forAll){\r\n        var results = [];\r\n        if(!utils .isFunction(filter)){\r\n            var str = filter;\r\n            filter = function(n){\r\n                return utils.indexOf(utils.isArray(str) ? str:str.split(' '), n.tagName.toLowerCase()) != -1\r\n            };\r\n        }\r\n        utils.each(nodelist,function(n){\r\n            filter(n) && results.push(n)\r\n        });\r\n        return results.length  == 0 ? null : results.length == 1 || !forAll ? results[0] : results\r\n    },\r\n\r\n    /**\r\n     * 查询给定的range选区是否在给定的node节点内，且在该节点的最末尾\r\n     * @method isInNodeEndBoundary\r\n     * @param { UE.dom.Range } rng 需要判断的range对象， 该对象的startContainer不能为NULL\r\n     * @param node 需要检测的节点对象\r\n     * @return { Number } 如果给定的选取range对象是在node内部的最末端， 则返回1, 否则返回0\r\n     */\r\n    isInNodeEndBoundary : function (rng,node){\r\n        var start = rng.startContainer;\r\n        if(start.nodeType == 3 && rng.startOffset != start.nodeValue.length){\r\n            return 0;\r\n        }\r\n        if(start.nodeType == 1 && rng.startOffset != start.childNodes.length){\r\n            return 0;\r\n        }\r\n        while(start !== node){\r\n            if(start.nextSibling){\r\n                return 0\r\n            };\r\n            start = start.parentNode;\r\n        }\r\n        return 1;\r\n    },\r\n    isBoundaryNode : function (node,dir){\r\n        var tmp;\r\n        while(!domUtils.isBody(node)){\r\n            tmp = node;\r\n            node = node.parentNode;\r\n            if(tmp !== node[dir]){\r\n                return false;\r\n            }\r\n        }\r\n        return true;\r\n    },\r\n    fillHtml :  browser.ie11below ? '&nbsp;' : '<br/>'\r\n};\r\nvar fillCharReg = new RegExp(domUtils.fillChar, 'g');\n\n// core/Range.js\n/**\r\n * Range封装\r\n * @file\r\n * @module UE.dom\r\n * @class Range\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * dom操作封装\r\n * @unfile\r\n * @module UE.dom\r\n */\r\n\r\n/**\r\n * Range实现类，本类是UEditor底层核心类，封装不同浏览器之间的Range操作。\r\n * @unfile\r\n * @module UE.dom\r\n * @class Range\r\n */\r\n\r\n\r\n(function () {\r\n    var guid = 0,\r\n        fillChar = domUtils.fillChar,\r\n        fillData;\r\n\r\n    /**\r\n     * 更新range的collapse状态\r\n     * @param  {Range}   range    range对象\r\n     */\r\n    function updateCollapse(range) {\r\n        range.collapsed =\r\n            range.startContainer && range.endContainer &&\r\n                range.startContainer === range.endContainer &&\r\n                range.startOffset == range.endOffset;\r\n    }\r\n\r\n    function selectOneNode(rng){\r\n        return !rng.collapsed && rng.startContainer.nodeType == 1 && rng.startContainer === rng.endContainer && rng.endOffset - rng.startOffset == 1\r\n    }\r\n    function setEndPoint(toStart, node, offset, range) {\r\n        //如果node是自闭合标签要处理\r\n        if (node.nodeType == 1 && (dtd.$empty[node.tagName] || dtd.$nonChild[node.tagName])) {\r\n            offset = domUtils.getNodeIndex(node) + (toStart ? 0 : 1);\r\n            node = node.parentNode;\r\n        }\r\n        if (toStart) {\r\n            range.startContainer = node;\r\n            range.startOffset = offset;\r\n            if (!range.endContainer) {\r\n                range.collapse(true);\r\n            }\r\n        } else {\r\n            range.endContainer = node;\r\n            range.endOffset = offset;\r\n            if (!range.startContainer) {\r\n                range.collapse(false);\r\n            }\r\n        }\r\n        updateCollapse(range);\r\n        return range;\r\n    }\r\n\r\n    function execContentsAction(range, action) {\r\n        //调整边界\r\n        //range.includeBookmark();\r\n        var start = range.startContainer,\r\n            end = range.endContainer,\r\n            startOffset = range.startOffset,\r\n            endOffset = range.endOffset,\r\n            doc = range.document,\r\n            frag = doc.createDocumentFragment(),\r\n            tmpStart, tmpEnd;\r\n        if (start.nodeType == 1) {\r\n            start = start.childNodes[startOffset] || (tmpStart = start.appendChild(doc.createTextNode('')));\r\n        }\r\n        if (end.nodeType == 1) {\r\n            end = end.childNodes[endOffset] || (tmpEnd = end.appendChild(doc.createTextNode('')));\r\n        }\r\n        if (start === end && start.nodeType == 3) {\r\n            frag.appendChild(doc.createTextNode(start.substringData(startOffset, endOffset - startOffset)));\r\n            //is not clone\r\n            if (action) {\r\n                start.deleteData(startOffset, endOffset - startOffset);\r\n                range.collapse(true);\r\n            }\r\n            return frag;\r\n        }\r\n        var current, currentLevel, clone = frag,\r\n            startParents = domUtils.findParents(start, true), endParents = domUtils.findParents(end, true);\r\n        for (var i = 0; startParents[i] == endParents[i];) {\r\n            i++;\r\n        }\r\n        for (var j = i, si; si = startParents[j]; j++) {\r\n            current = si.nextSibling;\r\n            if (si == start) {\r\n                if (!tmpStart) {\r\n                    if (range.startContainer.nodeType == 3) {\r\n                        clone.appendChild(doc.createTextNode(start.nodeValue.slice(startOffset)));\r\n                        //is not clone\r\n                        if (action) {\r\n                            start.deleteData(startOffset, start.nodeValue.length - startOffset);\r\n                        }\r\n                    } else {\r\n                        clone.appendChild(!action ? start.cloneNode(true) : start);\r\n                    }\r\n                }\r\n            } else {\r\n                currentLevel = si.cloneNode(false);\r\n                clone.appendChild(currentLevel);\r\n            }\r\n            while (current) {\r\n                if (current === end || current === endParents[j]) {\r\n                    break;\r\n                }\r\n                si = current.nextSibling;\r\n                clone.appendChild(!action ? current.cloneNode(true) : current);\r\n                current = si;\r\n            }\r\n            clone = currentLevel;\r\n        }\r\n        clone = frag;\r\n        if (!startParents[i]) {\r\n            clone.appendChild(startParents[i - 1].cloneNode(false));\r\n            clone = clone.firstChild;\r\n        }\r\n        for (var j = i, ei; ei = endParents[j]; j++) {\r\n            current = ei.previousSibling;\r\n            if (ei == end) {\r\n                if (!tmpEnd && range.endContainer.nodeType == 3) {\r\n                    clone.appendChild(doc.createTextNode(end.substringData(0, endOffset)));\r\n                    //is not clone\r\n                    if (action) {\r\n                        end.deleteData(0, endOffset);\r\n                    }\r\n                }\r\n            } else {\r\n                currentLevel = ei.cloneNode(false);\r\n                clone.appendChild(currentLevel);\r\n            }\r\n            //如果两端同级，右边第一次已经被开始做了\r\n            if (j != i || !startParents[i]) {\r\n                while (current) {\r\n                    if (current === start) {\r\n                        break;\r\n                    }\r\n                    ei = current.previousSibling;\r\n                    clone.insertBefore(!action ? current.cloneNode(true) : current, clone.firstChild);\r\n                    current = ei;\r\n                }\r\n            }\r\n            clone = currentLevel;\r\n        }\r\n        if (action) {\r\n            range.setStartBefore(!endParents[i] ? endParents[i - 1] : !startParents[i] ? startParents[i - 1] : endParents[i]).collapse(true);\r\n        }\r\n        tmpStart && domUtils.remove(tmpStart);\r\n        tmpEnd && domUtils.remove(tmpEnd);\r\n        return frag;\r\n    }\r\n\r\n    /**\r\n     * 创建一个跟document绑定的空的Range实例\r\n     * @constructor\r\n     * @param { Document } document 新建的选区所属的文档对象\r\n     */\r\n\r\n    /**\r\n     * @property { Node } startContainer 当前Range的开始边界的容器节点, 可以是一个元素节点或者是文本节点\r\n     */\r\n\r\n    /**\r\n     * @property { Node } startOffset 当前Range的开始边界容器节点的偏移量, 如果是元素节点，\r\n     *                              该值就是childNodes中的第几个节点， 如果是文本节点就是文本内容的第几个字符\r\n     */\r\n\r\n    /**\r\n     * @property { Node } endContainer 当前Range的结束边界的容器节点, 可以是一个元素节点或者是文本节点\r\n     */\r\n\r\n    /**\r\n     * @property { Node } endOffset 当前Range的结束边界容器节点的偏移量, 如果是元素节点，\r\n     *                              该值就是childNodes中的第几个节点， 如果是文本节点就是文本内容的第几个字符\r\n     */\r\n\r\n    /**\r\n     * @property { Boolean } collapsed 当前Range是否闭合\r\n     * @default true\r\n     * @remind Range是闭合的时候， startContainer === endContainer && startOffset === endOffset\r\n     */\r\n\r\n    /**\r\n     * @property { Document } document 当前Range所属的Document对象\r\n     * @remind 不同range的的document属性可以是不同的\r\n     */\r\n    var Range = dom.Range = function (document) {\r\n        var me = this;\r\n        me.startContainer =\r\n            me.startOffset =\r\n                me.endContainer =\r\n                    me.endOffset = null;\r\n        me.document = document;\r\n        me.collapsed = true;\r\n    };\r\n\r\n    /**\r\n     * 删除fillData\r\n     * @param doc\r\n     * @param excludeNode\r\n     */\r\n    function removeFillData(doc, excludeNode) {\r\n        try {\r\n            if (fillData && domUtils.inDoc(fillData, doc)) {\r\n                if (!fillData.nodeValue.replace(fillCharReg, '').length) {\r\n                    var tmpNode = fillData.parentNode;\r\n                    domUtils.remove(fillData);\r\n                    while (tmpNode && domUtils.isEmptyInlineElement(tmpNode) &&\r\n                        //safari的contains有bug\r\n                        (browser.safari ? !(domUtils.getPosition(tmpNode,excludeNode) & domUtils.POSITION_CONTAINS) : !tmpNode.contains(excludeNode))\r\n                        ) {\r\n                        fillData = tmpNode.parentNode;\r\n                        domUtils.remove(tmpNode);\r\n                        tmpNode = fillData;\r\n                    }\r\n                } else {\r\n                    fillData.nodeValue = fillData.nodeValue.replace(fillCharReg, '');\r\n                }\r\n            }\r\n        } catch (e) {\r\n        }\r\n    }\r\n\r\n    /**\r\n     * @param node\r\n     * @param dir\r\n     */\r\n    function mergeSibling(node, dir) {\r\n        var tmpNode;\r\n        node = node[dir];\r\n        while (node && domUtils.isFillChar(node)) {\r\n            tmpNode = node[dir];\r\n            domUtils.remove(node);\r\n            node = tmpNode;\r\n        }\r\n    }\r\n\r\n    Range.prototype = {\r\n\r\n        /**\r\n         * 克隆选区的内容到一个DocumentFragment里\r\n         * @method cloneContents\r\n         * @return { DocumentFragment | NULL } 如果选区是闭合的将返回null， 否则， 返回包含所clone内容的DocumentFragment元素\r\n         * @example\r\n         * ```html\r\n         * <body>\r\n         *      <!-- 中括号表示选区 -->\r\n         *      <b>x<i>x[x</i>xx]x</b>\r\n         *\r\n         *      <script>\r\n         *          //range是已选中的选区\r\n         *          var fragment = range.cloneContents(),\r\n         *              node = document.createElement(\"div\");\r\n         *\r\n         *          node.appendChild( fragment );\r\n         *\r\n         *          //output: <i>x</i>xx\r\n         *          console.log( node.innerHTML );\r\n         *\r\n         *      </script>\r\n         * </body>\r\n         * ```\r\n         */\r\n        cloneContents:function () {\r\n            return this.collapsed ? null : execContentsAction(this, 0);\r\n        },\r\n\r\n        /**\r\n         * 删除当前选区范围中的所有内容\r\n         * @method deleteContents\r\n         * @remind 执行完该操作后， 当前Range对象变成了闭合状态\r\n         * @return { UE.dom.Range } 当前操作的Range对象\r\n         * @example\r\n         * ```html\r\n         * <body>\r\n         *      <!-- 中括号表示选区 -->\r\n         *      <b>x<i>x[x</i>xx]x</b>\r\n         *\r\n         *      <script>\r\n         *          //range是已选中的选区\r\n         *          range.deleteContents();\r\n         *\r\n         *          //竖线表示闭合后的选区位置\r\n         *          //output: <b>x<i>x</i>|x</b>\r\n         *          console.log( document.body.innerHTML );\r\n         *\r\n         *          //此时， range的各项属性为\r\n         *          //output: B\r\n         *          console.log( range.startContainer.tagName );\r\n         *          //output: 2\r\n         *          console.log( range.startOffset );\r\n         *          //output: B\r\n         *          console.log( range.endContainer.tagName );\r\n         *          //output: 2\r\n         *          console.log( range.endOffset );\r\n         *          //output: true\r\n         *          console.log( range.collapsed );\r\n         *\r\n         *      </script>\r\n         * </body>\r\n         * ```\r\n         */\r\n        deleteContents:function () {\r\n            var txt;\r\n            if (!this.collapsed) {\r\n                execContentsAction(this, 1);\r\n            }\r\n            if (browser.webkit) {\r\n                txt = this.startContainer;\r\n                if (txt.nodeType == 3 && !txt.nodeValue.length) {\r\n                    this.setStartBefore(txt).collapse(true);\r\n                    domUtils.remove(txt);\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * 将当前选区的内容提取到一个DocumentFragment里\r\n         * @method extractContents\r\n         * @remind 执行该操作后， 选区将变成闭合状态\r\n         * @warning 执行该操作后， 原来选区所选中的内容将从dom树上剥离出来\r\n         * @return { DocumentFragment } 返回包含所提取内容的DocumentFragment对象\r\n         * @example\r\n         * ```html\r\n         * <body>\r\n         *      <!-- 中括号表示选区 -->\r\n         *      <b>x<i>x[x</i>xx]x</b>\r\n         *\r\n         *      <script>\r\n         *          //range是已选中的选区\r\n         *          var fragment = range.extractContents(),\r\n         *              node = document.createElement( \"div\" );\r\n         *\r\n         *          node.appendChild( fragment );\r\n         *\r\n         *          //竖线表示闭合后的选区位置\r\n         *\r\n         *          //output: <b>x<i>x</i>|x</b>\r\n         *          console.log( document.body.innerHTML );\r\n         *          //output: <i>x</i>xx\r\n         *          console.log( node.innerHTML );\r\n         *\r\n         *          //此时， range的各项属性为\r\n         *          //output: B\r\n         *          console.log( range.startContainer.tagName );\r\n         *          //output: 2\r\n         *          console.log( range.startOffset );\r\n         *          //output: B\r\n         *          console.log( range.endContainer.tagName );\r\n         *          //output: 2\r\n         *          console.log( range.endOffset );\r\n         *          //output: true\r\n         *          console.log( range.collapsed );\r\n         *\r\n         *      </script>\r\n         * </body>\r\n         */\r\n        extractContents:function () {\r\n            return this.collapsed ? null : execContentsAction(this, 2);\r\n        },\r\n\r\n        /**\r\n         * 设置Range的开始容器节点和偏移量\r\n         * @method  setStart\r\n         * @remind 如果给定的节点是元素节点，那么offset指的是其子元素中索引为offset的元素，\r\n         *          如果是文本节点，那么offset指的是其文本内容的第offset个字符\r\n         * @remind 如果提供的容器节点是一个不能包含子元素的节点， 则该选区的开始容器将被设置\r\n         *          为该节点的父节点， 此时， 其距离开始容器的偏移量也变成了该节点在其父节点\r\n         *          中的索引\r\n         * @param { Node } node 将被设为当前选区开始边界容器的节点对象\r\n         * @param { int } offset 选区的开始位置偏移量\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @example\r\n         * ```html\r\n         * <!-- 选区 -->\r\n         * <b>xxx<i>x<span>xx</span>xx<em>xx</em>xxx</i>[xxx]</b>\r\n         *\r\n         * <script>\r\n         *\r\n         *     //执行操作\r\n         *     range.setStart( document.getElementsByTagName(\"i\")[0], 1 );\r\n         *\r\n         *     //此时， 选区变成了\r\n         *     //<b>xxx<i>x[<span>xx</span>xx<em>xx</em>xxx</i>xxx]</b>\r\n         *\r\n         * </script>\r\n         * ```\r\n         * @example\r\n         * ```html\r\n         * <!-- 选区 -->\r\n         * <b>xxx<img>[xx]x</b>\r\n         *\r\n         * <script>\r\n         *\r\n         *     //执行操作\r\n         *     range.setStart( document.getElementsByTagName(\"img\")[0], 3 );\r\n         *\r\n         *     //此时， 选区变成了\r\n         *     //<b>xxx[<img>xx]x</b>\r\n         *\r\n         * </script>\r\n         * ```\r\n         */\r\n        setStart:function (node, offset) {\r\n            return setEndPoint(true, node, offset, this);\r\n        },\r\n\r\n        /**\r\n         * 设置Range的结束容器和偏移量\r\n         * @method  setEnd\r\n         * @param { Node } node 作为当前选区结束边界容器的节点对象\r\n         * @param { int } offset 结束边界的偏移量\r\n         * @see UE.dom.Range:setStart(Node,int)\r\n         * @return { UE.dom.Range } 当前range对象\r\n         */\r\n        setEnd:function (node, offset) {\r\n            return setEndPoint(false, node, offset, this);\r\n        },\r\n\r\n        /**\r\n         * 将Range开始位置设置到node节点之后\r\n         * @method  setStartAfter\r\n         * @remind 该操作将会把给定节点的父节点作为range的开始容器， 且偏移量是该节点在其父节点中的位置索引+1\r\n         * @param { Node } node 选区的开始边界将紧接着该节点之后\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @example\r\n         * ```html\r\n         * <!-- 选区示例 -->\r\n         * <b>xx<i>xxx</i><span>xx[x</span>xxx]</b>\r\n         *\r\n         * <script>\r\n         *\r\n         *     //执行操作\r\n         *     range.setStartAfter( document.getElementsByTagName(\"i\")[0] );\r\n         *\r\n         *     //结果选区\r\n         *     //<b>xx<i>xxx</i>[<span>xxx</span>xxx]</b>\r\n         *\r\n         * </script>\r\n         * ```\r\n         */\r\n        setStartAfter:function (node) {\r\n            return this.setStart(node.parentNode, domUtils.getNodeIndex(node) + 1);\r\n        },\r\n\r\n        /**\r\n         * 将Range开始位置设置到node节点之前\r\n         * @method  setStartBefore\r\n         * @remind 该操作将会把给定节点的父节点作为range的开始容器， 且偏移量是该节点在其父节点中的位置索引\r\n         * @param { Node } node 新的选区开始位置在该节点之前\r\n         * @see UE.dom.Range:setStartAfter(Node)\r\n         * @return { UE.dom.Range } 当前range对象\r\n         */\r\n        setStartBefore:function (node) {\r\n            return this.setStart(node.parentNode, domUtils.getNodeIndex(node));\r\n        },\r\n\r\n        /**\r\n         * 将Range结束位置设置到node节点之后\r\n         * @method  setEndAfter\r\n         * @remind 该操作将会把给定节点的父节点作为range的结束容器， 且偏移量是该节点在其父节点中的位置索引+1\r\n         * @param { Node } node 目标节点\r\n         * @see UE.dom.Range:setStartAfter(Node)\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @example\r\n         * ```html\r\n         * <!-- 选区示例 -->\r\n         * <b>[xx<i>xxx</i><span>xx]x</span>xxx</b>\r\n         *\r\n         * <script>\r\n         *\r\n         *     //执行操作\r\n         *     range.setStartAfter( document.getElementsByTagName(\"span\")[0] );\r\n         *\r\n         *     //结果选区\r\n         *     //<b>[xx<i>xxx</i><span>xxx</span>]xxx</b>\r\n         *\r\n         * </script>\r\n         * ```\r\n         */\r\n        setEndAfter:function (node) {\r\n            return this.setEnd(node.parentNode, domUtils.getNodeIndex(node) + 1);\r\n        },\r\n\r\n        /**\r\n         * 将Range结束位置设置到node节点之前\r\n         * @method  setEndBefore\r\n         * @remind 该操作将会把给定节点的父节点作为range的结束容器， 且偏移量是该节点在其父节点中的位置索引\r\n         * @param { Node } node 目标节点\r\n         * @see UE.dom.Range:setEndAfter(Node)\r\n         * @return { UE.dom.Range } 当前range对象\r\n         */\r\n        setEndBefore:function (node) {\r\n            return this.setEnd(node.parentNode, domUtils.getNodeIndex(node));\r\n        },\r\n\r\n        /**\r\n         * 设置Range的开始位置到node节点内的第一个子节点之前\r\n         * @method  setStartAtFirst\r\n         * @remind 选区的开始容器将变成给定的节点， 且偏移量为0\r\n         * @remind 如果给定的节点是元素节点， 则该节点必须是允许包含子节点的元素。\r\n         * @param { Node } node 目标节点\r\n         * @see UE.dom.Range:setStartBefore(Node)\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @example\r\n         * ```html\r\n         * <!-- 选区示例 -->\r\n         * <b>xx<i>xxx</i><span>[xx]x</span>xxx</b>\r\n         *\r\n         * <script>\r\n         *\r\n         *     //执行操作\r\n         *     range.setStartAtFirst( document.getElementsByTagName(\"i\")[0] );\r\n         *\r\n         *     //结果选区\r\n         *     //<b>xx<i>[xxx</i><span>xx]x</span>xxx</b>\r\n         *\r\n         * </script>\r\n         * ```\r\n         */\r\n        setStartAtFirst:function (node) {\r\n            return this.setStart(node, 0);\r\n        },\r\n\r\n        /**\r\n         * 设置Range的开始位置到node节点内的最后一个节点之后\r\n         * @method setStartAtLast\r\n         * @remind 选区的开始容器将变成给定的节点， 且偏移量为该节点的子节点数\r\n         * @remind 如果给定的节点是元素节点， 则该节点必须是允许包含子节点的元素。\r\n         * @param { Node } node 目标节点\r\n         * @see UE.dom.Range:setStartAtFirst(Node)\r\n         * @return { UE.dom.Range } 当前range对象\r\n         */\r\n        setStartAtLast:function (node) {\r\n            return this.setStart(node, node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length);\r\n        },\r\n\r\n        /**\r\n         * 设置Range的结束位置到node节点内的第一个节点之前\r\n         * @method  setEndAtFirst\r\n         * @param { Node } node 目标节点\r\n         * @remind 选区的结束容器将变成给定的节点， 且偏移量为0\r\n         * @remind node必须是一个元素节点， 且必须是允许包含子节点的元素。\r\n         * @see UE.dom.Range:setStartAtFirst(Node)\r\n         * @return { UE.dom.Range } 当前range对象\r\n         */\r\n        setEndAtFirst:function (node) {\r\n            return this.setEnd(node, 0);\r\n        },\r\n\r\n        /**\r\n         * 设置Range的结束位置到node节点内的最后一个节点之后\r\n         * @method  setEndAtLast\r\n         * @param { Node } node 目标节点\r\n         * @remind 选区的结束容器将变成给定的节点， 且偏移量为该节点的子节点数量\r\n         * @remind node必须是一个元素节点， 且必须是允许包含子节点的元素。\r\n         * @see UE.dom.Range:setStartAtFirst(Node)\r\n         * @return { UE.dom.Range } 当前range对象\r\n         */\r\n        setEndAtLast:function (node) {\r\n            return this.setEnd(node, node.nodeType == 3 ? node.nodeValue.length : node.childNodes.length);\r\n        },\r\n\r\n        /**\r\n         * 选中给定节点\r\n         * @method  selectNode\r\n         * @remind 此时， 选区的开始容器和结束容器都是该节点的父节点， 其startOffset是该节点在父节点中的位置索引，\r\n         *          而endOffset为startOffset+1\r\n         * @param { Node } node 需要选中的节点\r\n         * @return { UE.dom.Range } 当前range对象，此时的range仅包含当前给定的节点对象\r\n         * @example\r\n         * ```html\r\n         * <!-- 选区示例 -->\r\n         * <b>xx<i>xxx</i><span>[xx]x</span>xxx</b>\r\n         *\r\n         * <script>\r\n         *\r\n         *     //执行操作\r\n         *     range.selectNode( document.getElementsByTagName(\"i\")[0] );\r\n         *\r\n         *     //结果选区\r\n         *     //<b>xx[<i>xxx</i>]<span>xxx</span>xxx</b>\r\n         *\r\n         * </script>\r\n         * ```\r\n         */\r\n        selectNode:function (node) {\r\n            return this.setStartBefore(node).setEndAfter(node);\r\n        },\r\n\r\n        /**\r\n         * 选中给定节点内部的所有节点\r\n         * @method  selectNodeContents\r\n         * @remind 此时， 选区的开始容器和结束容器都是该节点， 其startOffset为0，\r\n         *          而endOffset是该节点的子节点数。\r\n         * @param { Node } node 目标节点， 当前range将包含该节点内的所有节点\r\n         * @return { UE.dom.Range } 当前range对象， 此时range仅包含给定节点的所有子节点\r\n         * @example\r\n         * ```html\r\n         * <!-- 选区示例 -->\r\n         * <b>xx<i>xxx</i><span>[xx]x</span>xxx</b>\r\n         *\r\n         * <script>\r\n         *\r\n         *     //执行操作\r\n         *     range.selectNode( document.getElementsByTagName(\"b\")[0] );\r\n         *\r\n         *     //结果选区\r\n         *     //<b>[xx<i>xxx</i><span>xxx</span>xxx]</b>\r\n         *\r\n         * </script>\r\n         * ```\r\n         */\r\n        selectNodeContents:function (node) {\r\n            return this.setStart(node, 0).setEndAtLast(node);\r\n        },\r\n\r\n        /**\r\n         * clone当前Range对象\r\n         * @method  cloneRange\r\n         * @remind 返回的range是一个全新的range对象， 其内部所有属性与当前被clone的range相同。\r\n         * @return { UE.dom.Range } 当前range对象的一个副本\r\n         */\r\n        cloneRange:function () {\r\n            var me = this;\r\n            return new Range(me.document).setStart(me.startContainer, me.startOffset).setEnd(me.endContainer, me.endOffset);\r\n\r\n        },\r\n\r\n        /**\r\n         * 向当前选区的结束处闭合选区\r\n         * @method  collapse\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @example\r\n         * ```html\r\n         * <!-- 选区示例 -->\r\n         * <b>xx<i>xxx</i><span>[xx]x</span>xxx</b>\r\n         *\r\n         * <script>\r\n         *\r\n         *     //执行操作\r\n         *     range.collapse();\r\n         *\r\n         *     //结果选区\r\n         *     //“|”表示选区已闭合\r\n         *     //<b>xx<i>xxx</i><span>xx|x</span>xxx</b>\r\n         *\r\n         * </script>\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 闭合当前选区，根据给定的toStart参数项决定是向当前选区开始处闭合还是向结束处闭合，\r\n         * 如果toStart的值为true，则向开始位置闭合， 反之，向结束位置闭合。\r\n         * @method  collapse\r\n         * @param { Boolean } toStart 是否向选区开始处闭合\r\n         * @return { UE.dom.Range } 当前range对象，此时range对象处于闭合状态\r\n         * @see UE.dom.Range:collapse()\r\n         * @example\r\n         * ```html\r\n         * <!-- 选区示例 -->\r\n         * <b>xx<i>xxx</i><span>[xx]x</span>xxx</b>\r\n         *\r\n         * <script>\r\n         *\r\n         *     //执行操作\r\n         *     range.collapse( true );\r\n         *\r\n         *     //结果选区\r\n         *     //“|”表示选区已闭合\r\n         *     //<b>xx<i>xxx</i><span>|xxx</span>xxx</b>\r\n         *\r\n         * </script>\r\n         * ```\r\n         */\r\n        collapse:function (toStart) {\r\n            var me = this;\r\n            if (toStart) {\r\n                me.endContainer = me.startContainer;\r\n                me.endOffset = me.startOffset;\r\n            } else {\r\n                me.startContainer = me.endContainer;\r\n                me.startOffset = me.endOffset;\r\n            }\r\n            me.collapsed = true;\r\n            return me;\r\n        },\r\n\r\n        /**\r\n         * 调整range的开始位置和结束位置，使其\"收缩\"到最小的位置\r\n         * @method  shrinkBoundary\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @example\r\n         * ```html\r\n         * <span>xx<b>xx[</b>xxxxx]</span> => <span>xx<b>xx</b>[xxxxx]</span>\r\n         * ```\r\n         *\r\n         * @example\r\n         * ```html\r\n         * <!-- 选区示例 -->\r\n         * <b>x[xx</b><i>]xxx</i>\r\n         *\r\n         * <script>\r\n         *\r\n         *     //执行收缩\r\n         *     range.shrinkBoundary();\r\n         *\r\n         *     //结果选区\r\n         *     //<b>x[xx]</b><i>xxx</i>\r\n         * </script>\r\n         * ```\r\n         *\r\n         * @example\r\n         * ```html\r\n         * [<b><i>xxxx</i>xxxxxxx</b>] => <b><i>[xxxx</i>xxxxxxx]</b>\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 调整range的开始位置和结束位置，使其\"收缩\"到最小的位置，\r\n         * 如果ignoreEnd的值为true，则忽略对结束位置的调整\r\n         * @method  shrinkBoundary\r\n         * @param { Boolean } ignoreEnd 是否忽略对结束位置的调整\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @see UE.dom.domUtils.Range:shrinkBoundary()\r\n         */\r\n        shrinkBoundary:function (ignoreEnd) {\r\n            var me = this, child,\r\n                collapsed = me.collapsed;\r\n            function check(node){\r\n                return node.nodeType == 1 && !domUtils.isBookmarkNode(node) && !dtd.$empty[node.tagName] && !dtd.$nonChild[node.tagName]\r\n            }\r\n            while (me.startContainer.nodeType == 1 //是element\r\n                && (child = me.startContainer.childNodes[me.startOffset]) //子节点也是element\r\n                && check(child)) {\r\n                me.setStart(child, 0);\r\n            }\r\n            if (collapsed) {\r\n                return me.collapse(true);\r\n            }\r\n            if (!ignoreEnd) {\r\n                while (me.endContainer.nodeType == 1//是element\r\n                    && me.endOffset > 0 //如果是空元素就退出 endOffset=0那么endOffst-1为负值，childNodes[endOffset]报错\r\n                    && (child = me.endContainer.childNodes[me.endOffset - 1]) //子节点也是element\r\n                    && check(child)) {\r\n                    me.setEnd(child, child.childNodes.length);\r\n                }\r\n            }\r\n            return me;\r\n        },\r\n\r\n        /**\r\n         * 获取离当前选区内包含的所有节点最近的公共祖先节点，\r\n         * @method  getCommonAncestor\r\n         * @remind 返回的公共祖先节点一定不是range自身的容器节点， 但有可能是一个文本节点\r\n         * @return { Node } 当前range对象内所有节点的公共祖先节点\r\n         * @example\r\n         * ```html\r\n         * //选区示例\r\n         * <span>xxx<b>x[x<em>xx]x</em>xxx</b>xx</span>\r\n         * <script>\r\n         *\r\n         *     var node = range.getCommonAncestor();\r\n         *\r\n         *     //公共祖先节点是： b节点\r\n         *     //输出： B\r\n         *     console.log(node.tagName);\r\n         *\r\n         * </script>\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 获取当前选区所包含的所有节点的公共祖先节点， 可以根据给定的参数 includeSelf 决定获取到\r\n         * 的公共祖先节点是否可以是当前选区的startContainer或endContainer节点， 如果 includeSelf\r\n         * 的取值为true， 则返回的节点可以是自身的容器节点， 否则， 则不能是容器节点\r\n         * @method  getCommonAncestor\r\n         * @param { Boolean } includeSelf 是否允许获取到的公共祖先节点是当前range对象的容器节点\r\n         * @return { Node } 当前range对象内所有节点的公共祖先节点\r\n         * @see UE.dom.Range:getCommonAncestor()\r\n         * @example\r\n         * ```html\r\n         * <body>\r\n         *\r\n         *     <!-- 选区示例 -->\r\n         *     <b>xxx<i>xxxx<span>xx[x</span>xx]x</i>xxxxxxx</b>\r\n         *\r\n         *     <script>\r\n         *\r\n         *         var node = range.getCommonAncestor( false );\r\n         *\r\n         *         //这里的公共祖先节点是B而不是I， 是因为参数限制了获取到的节点不能是容器节点\r\n         *         //output: B\r\n         *         console.log( node.tagName );\r\n         *\r\n         *     </script>\r\n         *\r\n         * </body>\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 获取当前选区所包含的所有节点的公共祖先节点， 可以根据给定的参数 includeSelf 决定获取到\r\n         * 的公共祖先节点是否可以是当前选区的startContainer或endContainer节点， 如果 includeSelf\r\n         * 的取值为true， 则返回的节点可以是自身的容器节点， 否则， 则不能是容器节点； 同时可以根据\r\n         * ignoreTextNode 参数的取值决定是否忽略类型为文本节点的祖先节点。\r\n         * @method  getCommonAncestor\r\n         * @param { Boolean } includeSelf 是否允许获取到的公共祖先节点是当前range对象的容器节点\r\n         * @param { Boolean } ignoreTextNode 获取祖先节点的过程中是否忽略类型为文本节点的祖先节点\r\n         * @return { Node } 当前range对象内所有节点的公共祖先节点\r\n         * @see UE.dom.Range:getCommonAncestor()\r\n         * @see UE.dom.Range:getCommonAncestor(Boolean)\r\n         * @example\r\n         * ```html\r\n         * <body>\r\n         *\r\n         *     <!-- 选区示例 -->\r\n         *     <b>xxx<i>xxxx<span>x[x]x</span>xxx</i>xxxxxxx</b>\r\n         *\r\n         *     <script>\r\n         *\r\n         *         var node = range.getCommonAncestor( true, false );\r\n         *\r\n         *         //output: SPAN\r\n         *         console.log( node.tagName );\r\n         *\r\n         *     </script>\r\n         *\r\n         * </body>\r\n         * ```\r\n         */\r\n        getCommonAncestor:function (includeSelf, ignoreTextNode) {\r\n            var me = this,\r\n                start = me.startContainer,\r\n                end = me.endContainer;\r\n            if (start === end) {\r\n                if (includeSelf && selectOneNode(this)) {\r\n                    start = start.childNodes[me.startOffset];\r\n                    if(start.nodeType == 1)\r\n                        return start;\r\n                }\r\n                //只有在上来就相等的情况下才会出现是文本的情况\r\n                return ignoreTextNode && start.nodeType == 3 ? start.parentNode : start;\r\n            }\r\n            return domUtils.getCommonAncestor(start, end);\r\n        },\r\n\r\n        /**\r\n         * 调整当前Range的开始和结束边界容器，如果是容器节点是文本节点,就调整到包含该文本节点的父节点上\r\n         * @method trimBoundary\r\n         * @remind 该操作有可能会引起文本节点被切开\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @example\r\n         * ```html\r\n         *\r\n         * //选区示例\r\n         * <b>xxx<i>[xxxxx]</i>xxx</b>\r\n         *\r\n         * <script>\r\n         *     //未调整前， 选区的开始容器和结束都是文本节点\r\n         *     //执行调整\r\n         *     range.trimBoundary();\r\n         *\r\n         *     //调整之后， 容器节点变成了i节点\r\n         *     //<b>xxx[<i>xxxxx</i>]xxx</b>\r\n         * </script>\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 调整当前Range的开始和结束边界容器，如果是容器节点是文本节点,就调整到包含该文本节点的父节点上，\r\n         * 可以根据 ignoreEnd 参数的值决定是否调整对结束边界的调整\r\n         * @method trimBoundary\r\n         * @param { Boolean } ignoreEnd 是否忽略对结束边界的调整\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @example\r\n         * ```html\r\n         *\r\n         * //选区示例\r\n         * <b>xxx<i>[xxxxx]</i>xxx</b>\r\n         *\r\n         * <script>\r\n         *     //未调整前， 选区的开始容器和结束都是文本节点\r\n         *     //执行调整\r\n         *     range.trimBoundary( true );\r\n         *\r\n         *     //调整之后， 开始容器节点变成了i节点\r\n         *     //但是， 结束容器没有发生变化\r\n         *     //<b>xxx[<i>xxxxx]</i>xxx</b>\r\n         * </script>\r\n         * ```\r\n         */\r\n        trimBoundary:function (ignoreEnd) {\r\n            this.txtToElmBoundary();\r\n            var start = this.startContainer,\r\n                offset = this.startOffset,\r\n                collapsed = this.collapsed,\r\n                end = this.endContainer;\r\n            if (start.nodeType == 3) {\r\n                if (offset == 0) {\r\n                    this.setStartBefore(start);\r\n                } else {\r\n                    if (offset >= start.nodeValue.length) {\r\n                        this.setStartAfter(start);\r\n                    } else {\r\n                        var textNode = domUtils.split(start, offset);\r\n                        //跟新结束边界\r\n                        if (start === end) {\r\n                            this.setEnd(textNode, this.endOffset - offset);\r\n                        } else if (start.parentNode === end) {\r\n                            this.endOffset += 1;\r\n                        }\r\n                        this.setStartBefore(textNode);\r\n                    }\r\n                }\r\n                if (collapsed) {\r\n                    return this.collapse(true);\r\n                }\r\n            }\r\n            if (!ignoreEnd) {\r\n                offset = this.endOffset;\r\n                end = this.endContainer;\r\n                if (end.nodeType == 3) {\r\n                    if (offset == 0) {\r\n                        this.setEndBefore(end);\r\n                    } else {\r\n                        offset < end.nodeValue.length && domUtils.split(end, offset);\r\n                        this.setEndAfter(end);\r\n                    }\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * 如果选区在文本的边界上，就扩展选区到文本的父节点上, 如果当前选区是闭合的， 则什么也不做\r\n         * @method txtToElmBoundary\r\n         * @remind 该操作不会修改dom节点\r\n         * @return { UE.dom.Range } 当前range对象\r\n         */\r\n\r\n        /**\r\n         * 如果选区在文本的边界上，就扩展选区到文本的父节点上, 如果当前选区是闭合的， 则根据参数项\r\n         * ignoreCollapsed 的值决定是否执行该调整\r\n         * @method txtToElmBoundary\r\n         * @param { Boolean } ignoreCollapsed 是否忽略选区的闭合状态， 如果该参数取值为true， 则\r\n         *                      不论选区是否闭合， 都会执行该操作， 反之， 则不会对闭合的选区执行该操作\r\n         * @return { UE.dom.Range } 当前range对象\r\n         */\r\n        txtToElmBoundary:function (ignoreCollapsed) {\r\n            function adjust(r, c) {\r\n                var container = r[c + 'Container'],\r\n                    offset = r[c + 'Offset'];\r\n                if (container.nodeType == 3) {\r\n                    if (!offset) {\r\n                        r['set' + c.replace(/(\\w)/, function (a) {\r\n                            return a.toUpperCase();\r\n                        }) + 'Before'](container);\r\n                    } else if (offset >= container.nodeValue.length) {\r\n                        r['set' + c.replace(/(\\w)/, function (a) {\r\n                            return a.toUpperCase();\r\n                        }) + 'After' ](container);\r\n                    }\r\n                }\r\n            }\r\n\r\n            if (ignoreCollapsed || !this.collapsed) {\r\n                adjust(this, 'start');\r\n                adjust(this, 'end');\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * 在当前选区的开始位置前插入节点，新插入的节点会被该range包含\r\n         * @method  insertNode\r\n         * @param { Node } node 需要插入的节点\r\n         * @remind 插入的节点可以是一个DocumentFragment依次插入多个节点\r\n         * @return { UE.dom.Range } 当前range对象\r\n         */\r\n        insertNode:function (node) {\r\n            var first = node, length = 1;\r\n            if (node.nodeType == 11) {\r\n                first = node.firstChild;\r\n                length = node.childNodes.length;\r\n            }\r\n            this.trimBoundary(true);\r\n            var start = this.startContainer,\r\n                offset = this.startOffset;\r\n            var nextNode = start.childNodes[ offset ];\r\n            if (nextNode) {\r\n                start.insertBefore(node, nextNode);\r\n            } else {\r\n                start.appendChild(node);\r\n            }\r\n            if (first.parentNode === this.endContainer) {\r\n                this.endOffset = this.endOffset + length;\r\n            }\r\n            return this.setStartBefore(first);\r\n        },\r\n\r\n        /**\r\n         * 闭合选区到当前选区的开始位置， 并且定位光标到闭合后的位置\r\n         * @method  setCursor\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @see UE.dom.Range:collapse()\r\n         */\r\n\r\n        /**\r\n         * 闭合选区，可以根据参数toEnd的值控制选区是向前闭合还是向后闭合， 并且定位光标到闭合后的位置。\r\n         * @method  setCursor\r\n         * @param { Boolean } toEnd 是否向后闭合， 如果为true， 则闭合选区时， 将向结束容器方向闭合，\r\n         *                      反之，则向开始容器方向闭合\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @see UE.dom.Range:collapse(Boolean)\r\n         */\r\n        setCursor:function (toEnd, noFillData) {\r\n            return this.collapse(!toEnd).select(noFillData);\r\n        },\r\n\r\n        /**\r\n         * 创建当前range的一个书签，记录下当前range的位置，方便当dom树改变时，还能找回原来的选区位置\r\n         * @method createBookmark\r\n         * @param { Boolean } serialize 控制返回的标记位置是对当前位置的引用还是ID，如果该值为true，则\r\n         *                              返回标记位置的ID， 反之则返回标记位置节点的引用\r\n         * @return { Object } 返回一个书签记录键值对， 其包含的key有： start => 开始标记的ID或者引用，\r\n         *                          end => 结束标记的ID或引用， id => 当前标记的类型， 如果为true，则表示\r\n         *                          返回的记录的类型为ID， 反之则为引用\r\n         */\r\n        createBookmark:function (serialize, same) {\r\n            var endNode,\r\n                startNode = this.document.createElement('span');\r\n            startNode.style.cssText = 'display:none;line-height:0px;';\r\n            startNode.appendChild(this.document.createTextNode('\\u200D'));\r\n            startNode.id = '_baidu_bookmark_start_' + (same ? '' : guid++);\r\n\r\n            if (!this.collapsed) {\r\n                endNode = startNode.cloneNode(true);\r\n                endNode.id = '_baidu_bookmark_end_' + (same ? '' : guid++);\r\n            }\r\n            this.insertNode(startNode);\r\n            if (endNode) {\r\n                this.collapse().insertNode(endNode).setEndBefore(endNode);\r\n            }\r\n            this.setStartAfter(startNode);\r\n            return {\r\n                start:serialize ? startNode.id : startNode,\r\n                end:endNode ? serialize ? endNode.id : endNode : null,\r\n                id:serialize\r\n            }\r\n        },\r\n\r\n        /**\r\n         *  调整当前range的边界到书签位置，并删除该书签对象所标记的位置内的节点\r\n         *  @method  moveToBookmark\r\n         *  @param { BookMark } bookmark createBookmark所创建的标签对象\r\n         *  @return { UE.dom.Range } 当前range对象\r\n         *  @see UE.dom.Range:createBookmark(Boolean)\r\n         */\r\n        moveToBookmark:function (bookmark) {\r\n            var start = bookmark.id ? this.document.getElementById(bookmark.start) : bookmark.start,\r\n                end = bookmark.end && bookmark.id ? this.document.getElementById(bookmark.end) : bookmark.end;\r\n            this.setStartBefore(start);\r\n            domUtils.remove(start);\r\n            if (end) {\r\n                this.setEndBefore(end);\r\n                domUtils.remove(end);\r\n            } else {\r\n                this.collapse(true);\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * 调整range的边界，使其\"放大\"到最近的父节点\r\n         * @method  enlarge\r\n         * @remind 会引起选区的变化\r\n         * @return { UE.dom.Range } 当前range对象\r\n         */\r\n\r\n        /**\r\n         * 调整range的边界，使其\"放大\"到最近的父节点，根据参数 toBlock 的取值， 可以\r\n         * 要求扩大之后的父节点是block节点\r\n         * @method  enlarge\r\n         * @param { Boolean } toBlock 是否要求扩大之后的父节点必须是block节点\r\n         * @return { UE.dom.Range } 当前range对象\r\n         */\r\n        enlarge:function (toBlock, stopFn) {\r\n            var isBody = domUtils.isBody,\r\n                pre, node, tmp = this.document.createTextNode('');\r\n            if (toBlock) {\r\n                node = this.startContainer;\r\n                if (node.nodeType == 1) {\r\n                    if (node.childNodes[this.startOffset]) {\r\n                        pre = node = node.childNodes[this.startOffset]\r\n                    } else {\r\n                        node.appendChild(tmp);\r\n                        pre = node = tmp;\r\n                    }\r\n                } else {\r\n                    pre = node;\r\n                }\r\n                while (1) {\r\n                    if (domUtils.isBlockElm(node)) {\r\n                        node = pre;\r\n                        while ((pre = node.previousSibling) && !domUtils.isBlockElm(pre)) {\r\n                            node = pre;\r\n                        }\r\n                        this.setStartBefore(node);\r\n                        break;\r\n                    }\r\n                    pre = node;\r\n                    node = node.parentNode;\r\n                }\r\n                node = this.endContainer;\r\n                if (node.nodeType == 1) {\r\n                    if (pre = node.childNodes[this.endOffset]) {\r\n                        node.insertBefore(tmp, pre);\r\n                    } else {\r\n                        node.appendChild(tmp);\r\n                    }\r\n                    pre = node = tmp;\r\n                } else {\r\n                    pre = node;\r\n                }\r\n                while (1) {\r\n                    if (domUtils.isBlockElm(node)) {\r\n                        node = pre;\r\n                        while ((pre = node.nextSibling) && !domUtils.isBlockElm(pre)) {\r\n                            node = pre;\r\n                        }\r\n                        this.setEndAfter(node);\r\n                        break;\r\n                    }\r\n                    pre = node;\r\n                    node = node.parentNode;\r\n                }\r\n                if (tmp.parentNode === this.endContainer) {\r\n                    this.endOffset--;\r\n                }\r\n                domUtils.remove(tmp);\r\n            }\r\n\r\n            // 扩展边界到最大\r\n            if (!this.collapsed) {\r\n                while (this.startOffset == 0) {\r\n                    if (stopFn && stopFn(this.startContainer)) {\r\n                        break;\r\n                    }\r\n                    if (isBody(this.startContainer)) {\r\n                        break;\r\n                    }\r\n                    this.setStartBefore(this.startContainer);\r\n                }\r\n                while (this.endOffset == (this.endContainer.nodeType == 1 ? this.endContainer.childNodes.length : this.endContainer.nodeValue.length)) {\r\n                    if (stopFn && stopFn(this.endContainer)) {\r\n                        break;\r\n                    }\r\n                    if (isBody(this.endContainer)) {\r\n                        break;\r\n                    }\r\n                    this.setEndAfter(this.endContainer);\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n        enlargeToBlockElm:function(ignoreEnd){\r\n            while(!domUtils.isBlockElm(this.startContainer)){\r\n                this.setStartBefore(this.startContainer);\r\n            }\r\n            if(!ignoreEnd){\r\n                while(!domUtils.isBlockElm(this.endContainer)){\r\n                    this.setEndAfter(this.endContainer);\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n        /**\r\n         * 调整Range的边界，使其\"缩小\"到最合适的位置\r\n         * @method adjustmentBoundary\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @see UE.dom.Range:shrinkBoundary()\r\n         */\r\n        adjustmentBoundary:function () {\r\n            if (!this.collapsed) {\r\n                while (!domUtils.isBody(this.startContainer) &&\r\n                    this.startOffset == this.startContainer[this.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length &&\r\n                    this.startContainer[this.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length\r\n                    ) {\r\n\r\n                    this.setStartAfter(this.startContainer);\r\n                }\r\n                while (!domUtils.isBody(this.endContainer) && !this.endOffset &&\r\n                    this.endContainer[this.endContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length\r\n                    ) {\r\n                    this.setEndBefore(this.endContainer);\r\n                }\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * 给range选区中的内容添加给定的inline标签\r\n         * @method applyInlineStyle\r\n         * @param { String } tagName 需要添加的标签名\r\n         * @example\r\n         * ```html\r\n         * <p>xxxx[xxxx]x</p>  ==>  range.applyInlineStyle(\"strong\")  ==>  <p>xxxx[<strong>xxxx</strong>]x</p>\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 给range选区中的内容添加给定的inline标签， 并且为标签附加上一些初始化属性。\r\n         * @method applyInlineStyle\r\n         * @param { String } tagName 需要添加的标签名\r\n         * @param { Object } attrs 跟随新添加的标签的属性\r\n         * @return { UE.dom.Range } 当前选区\r\n         * @example\r\n         * ```html\r\n         * <p>xxxx[xxxx]x</p>\r\n         *\r\n         * ==>\r\n         *\r\n         * <!-- 执行操作 -->\r\n         * range.applyInlineStyle(\"strong\",{\"style\":\"font-size:12px\"})\r\n         *\r\n         * ==>\r\n         *\r\n         * <p>xxxx[<strong style=\"font-size:12px\">xxxx</strong>]x</p>\r\n         * ```\r\n         */\r\n        applyInlineStyle:function (tagName, attrs, list) {\r\n            if (this.collapsed)return this;\r\n            this.trimBoundary().enlarge(false,\r\n                function (node) {\r\n                    return node.nodeType == 1 && domUtils.isBlockElm(node)\r\n                }).adjustmentBoundary();\r\n            var bookmark = this.createBookmark(),\r\n                end = bookmark.end,\r\n                filterFn = function (node) {\r\n                    return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' : !domUtils.isWhitespace(node);\r\n                },\r\n                current = domUtils.getNextDomNode(bookmark.start, false, filterFn),\r\n                node,\r\n                pre,\r\n                range = this.cloneRange();\r\n            while (current && (domUtils.getPosition(current, end) & domUtils.POSITION_PRECEDING)) {\r\n                if (current.nodeType == 3 || dtd[tagName][current.tagName]) {\r\n                    range.setStartBefore(current);\r\n                    node = current;\r\n                    while (node && (node.nodeType == 3 || dtd[tagName][node.tagName]) && node !== end) {\r\n                        pre = node;\r\n                        node = domUtils.getNextDomNode(node, node.nodeType == 1, null, function (parent) {\r\n                            return dtd[tagName][parent.tagName];\r\n                        });\r\n                    }\r\n                    var frag = range.setEndAfter(pre).extractContents(), elm;\r\n                    if (list && list.length > 0) {\r\n                        var level, top;\r\n                        top = level = list[0].cloneNode(false);\r\n                        for (var i = 1, ci; ci = list[i++];) {\r\n                            level.appendChild(ci.cloneNode(false));\r\n                            level = level.firstChild;\r\n                        }\r\n                        elm = level;\r\n                    } else {\r\n                        elm = range.document.createElement(tagName);\r\n                    }\r\n                    if (attrs) {\r\n                        domUtils.setAttributes(elm, attrs);\r\n                    }\r\n                    elm.appendChild(frag);\r\n                    range.insertNode(list ? top : elm);\r\n                    //处理下滑线在a上的情况\r\n                    var aNode;\r\n                    if (tagName == 'span' && attrs.style && /text\\-decoration/.test(attrs.style) && (aNode = domUtils.findParentByTagName(elm, 'a', true))) {\r\n                        domUtils.setAttributes(aNode, attrs);\r\n                        domUtils.remove(elm, true);\r\n                        elm = aNode;\r\n                    } else {\r\n                        domUtils.mergeSibling(elm);\r\n                        domUtils.clearEmptySibling(elm);\r\n                    }\r\n                    //去除子节点相同的\r\n                    domUtils.mergeChild(elm, attrs);\r\n                    current = domUtils.getNextDomNode(elm, false, filterFn);\r\n                    domUtils.mergeToParent(elm);\r\n                    if (node === end) {\r\n                        break;\r\n                    }\r\n                } else {\r\n                    current = domUtils.getNextDomNode(current, true, filterFn);\r\n                }\r\n            }\r\n            return this.moveToBookmark(bookmark);\r\n        },\r\n\r\n        /**\r\n         * 移除当前选区内指定的inline标签，但保留其中的内容\r\n         * @method removeInlineStyle\r\n         * @param { String } tagName 需要移除的标签名\r\n         * @return { UE.dom.Range } 当前的range对象\r\n         * @example\r\n         * ```html\r\n         * xx[x<span>xxx<em>yyy</em>zz]z</span>  => range.removeInlineStyle([\"em\"])  => xx[x<span>xxxyyyzz]z</span>\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 移除当前选区内指定的一组inline标签，但保留其中的内容\r\n         * @method removeInlineStyle\r\n         * @param { Array } tagNameArr 需要移除的标签名的数组\r\n         * @return { UE.dom.Range } 当前的range对象\r\n         * @see UE.dom.Range:removeInlineStyle(String)\r\n         */\r\n        removeInlineStyle:function (tagNames) {\r\n            if (this.collapsed)return this;\r\n            tagNames = utils.isArray(tagNames) ? tagNames : [tagNames];\r\n            this.shrinkBoundary().adjustmentBoundary();\r\n            var start = this.startContainer, end = this.endContainer;\r\n            while (1) {\r\n                if (start.nodeType == 1) {\r\n                    if (utils.indexOf(tagNames, start.tagName.toLowerCase()) > -1) {\r\n                        break;\r\n                    }\r\n                    if (start.tagName.toLowerCase() == 'body') {\r\n                        start = null;\r\n                        break;\r\n                    }\r\n                }\r\n                start = start.parentNode;\r\n            }\r\n            while (1) {\r\n                if (end.nodeType == 1) {\r\n                    if (utils.indexOf(tagNames, end.tagName.toLowerCase()) > -1) {\r\n                        break;\r\n                    }\r\n                    if (end.tagName.toLowerCase() == 'body') {\r\n                        end = null;\r\n                        break;\r\n                    }\r\n                }\r\n                end = end.parentNode;\r\n            }\r\n            var bookmark = this.createBookmark(),\r\n                frag,\r\n                tmpRange;\r\n            if (start) {\r\n                tmpRange = this.cloneRange().setEndBefore(bookmark.start).setStartBefore(start);\r\n                frag = tmpRange.extractContents();\r\n                tmpRange.insertNode(frag);\r\n                domUtils.clearEmptySibling(start, true);\r\n                start.parentNode.insertBefore(bookmark.start, start);\r\n            }\r\n            if (end) {\r\n                tmpRange = this.cloneRange().setStartAfter(bookmark.end).setEndAfter(end);\r\n                frag = tmpRange.extractContents();\r\n                tmpRange.insertNode(frag);\r\n                domUtils.clearEmptySibling(end, false, true);\r\n                end.parentNode.insertBefore(bookmark.end, end.nextSibling);\r\n            }\r\n            var current = domUtils.getNextDomNode(bookmark.start, false, function (node) {\r\n                return node.nodeType == 1;\r\n            }), next;\r\n            while (current && current !== bookmark.end) {\r\n                next = domUtils.getNextDomNode(current, true, function (node) {\r\n                    return node.nodeType == 1;\r\n                });\r\n                if (utils.indexOf(tagNames, current.tagName.toLowerCase()) > -1) {\r\n                    domUtils.remove(current, true);\r\n                }\r\n                current = next;\r\n            }\r\n            return this.moveToBookmark(bookmark);\r\n        },\r\n\r\n        /**\r\n         * 获取当前选中的自闭合的节点\r\n         * @method  getClosedNode\r\n         * @return { Node | NULL } 如果当前选中的是自闭合节点， 则返回该节点， 否则返回NULL\r\n         */\r\n        getClosedNode:function () {\r\n            var node;\r\n            if (!this.collapsed) {\r\n                var range = this.cloneRange().adjustmentBoundary().shrinkBoundary();\r\n                if (selectOneNode(range)) {\r\n                    var child = range.startContainer.childNodes[range.startOffset];\r\n                    if (child && child.nodeType == 1 && (dtd.$empty[child.tagName] || dtd.$nonChild[child.tagName])) {\r\n                        node = child;\r\n                    }\r\n                }\r\n            }\r\n            return node;\r\n        },\r\n\r\n        /**\r\n         * 在页面上高亮range所表示的选区\r\n         * @method select\r\n         * @return { UE.dom.Range } 返回当前Range对象\r\n         */\r\n            //这里不区分ie9以上，trace:3824\r\n        select:browser.ie ? function (noFillData, textRange) {\r\n            var nativeRange;\r\n            if (!this.collapsed)\r\n                this.shrinkBoundary();\r\n            var node = this.getClosedNode();\r\n            if (node && !textRange) {\r\n                try {\r\n                    nativeRange = this.document.body.createControlRange();\r\n                    nativeRange.addElement(node);\r\n                    nativeRange.select();\r\n                } catch (e) {}\r\n                return this;\r\n            }\r\n            var bookmark = this.createBookmark(),\r\n                start = bookmark.start,\r\n                end;\r\n            nativeRange = this.document.body.createTextRange();\r\n            nativeRange.moveToElementText(start);\r\n            nativeRange.moveStart('character', 1);\r\n            if (!this.collapsed) {\r\n                var nativeRangeEnd = this.document.body.createTextRange();\r\n                end = bookmark.end;\r\n                nativeRangeEnd.moveToElementText(end);\r\n                nativeRange.setEndPoint('EndToEnd', nativeRangeEnd);\r\n            } else {\r\n                if (!noFillData && this.startContainer.nodeType != 3) {\r\n                    //使用<span>|x<span>固定住光标\r\n                    var tmpText = this.document.createTextNode(fillChar),\r\n                        tmp = this.document.createElement('span');\r\n                    tmp.appendChild(this.document.createTextNode(fillChar));\r\n                    start.parentNode.insertBefore(tmp, start);\r\n                    start.parentNode.insertBefore(tmpText, start);\r\n                    //当点b,i,u时，不能清除i上边的b\r\n                    removeFillData(this.document, tmpText);\r\n                    fillData = tmpText;\r\n                    mergeSibling(tmp, 'previousSibling');\r\n                    mergeSibling(start, 'nextSibling');\r\n                    nativeRange.moveStart('character', -1);\r\n                    nativeRange.collapse(true);\r\n                }\r\n            }\r\n            this.moveToBookmark(bookmark);\r\n            tmp && domUtils.remove(tmp);\r\n            //IE在隐藏状态下不支持range操作，catch一下\r\n            try {\r\n                nativeRange.select();\r\n            } catch (e) {\r\n            }\r\n            return this;\r\n        } : function (notInsertFillData) {\r\n            function checkOffset(rng){\r\n\r\n                function check(node,offset,dir){\r\n                    if(node.nodeType == 3 && node.nodeValue.length < offset){\r\n                        rng[dir + 'Offset'] = node.nodeValue.length\r\n                    }\r\n                }\r\n                check(rng.startContainer,rng.startOffset,'start');\r\n                check(rng.endContainer,rng.endOffset,'end');\r\n            }\r\n            var win = domUtils.getWindow(this.document),\r\n                sel = win.getSelection(),\r\n                txtNode;\r\n            //FF下关闭自动长高时滚动条在关闭dialog时会跳\r\n            //ff下如果不body.focus将不能定位闭合光标到编辑器内\r\n            browser.gecko ? this.document.body.focus() : win.focus();\r\n            if (sel) {\r\n                sel.removeAllRanges();\r\n                // trace:870 chrome/safari后边是br对于闭合得range不能定位 所以去掉了判断\r\n                // this.startContainer.nodeType != 3 &&! ((child = this.startContainer.childNodes[this.startOffset]) && child.nodeType == 1 && child.tagName == 'BR'\r\n                if (this.collapsed && !notInsertFillData) {\r\n//                    //opear如果没有节点接着，原生的不能够定位,不能在body的第一级插入空白节点\r\n//                    if (notInsertFillData && browser.opera && !domUtils.isBody(this.startContainer) && this.startContainer.nodeType == 1) {\r\n//                        var tmp = this.document.createTextNode('');\r\n//                        this.insertNode(tmp).setStart(tmp, 0).collapse(true);\r\n//                    }\r\n//\r\n                    //处理光标落在文本节点的情况\r\n                    //处理以下的情况\r\n                    //<b>|xxxx</b>\r\n                    //<b>xxxx</b>|xxxx\r\n                    //xxxx<b>|</b>\r\n                    var start = this.startContainer,child = start;\r\n                    if(start.nodeType == 1){\r\n                        child = start.childNodes[this.startOffset];\r\n\r\n                    }\r\n                    if( !(start.nodeType == 3 && this.startOffset)  &&\r\n                        (child ?\r\n                            (!child.previousSibling || child.previousSibling.nodeType != 3)\r\n                            :\r\n                            (!start.lastChild || start.lastChild.nodeType != 3)\r\n                        )\r\n                    ){\r\n                        txtNode = this.document.createTextNode(fillChar);\r\n                        //跟着前边走\r\n                        this.insertNode(txtNode);\r\n                        removeFillData(this.document, txtNode);\r\n                        mergeSibling(txtNode, 'previousSibling');\r\n                        mergeSibling(txtNode, 'nextSibling');\r\n                        fillData = txtNode;\r\n                        this.setStart(txtNode, browser.webkit ? 1 : 0).collapse(true);\r\n                    }\r\n                }\r\n                var nativeRange = this.document.createRange();\r\n                if(this.collapsed && browser.opera && this.startContainer.nodeType == 1){\r\n                    var child = this.startContainer.childNodes[this.startOffset];\r\n                    if(!child){\r\n                        //往前靠拢\r\n                        child = this.startContainer.lastChild;\r\n                        if( child && domUtils.isBr(child)){\r\n                            this.setStartBefore(child).collapse(true);\r\n                        }\r\n                    }else{\r\n                        //向后靠拢\r\n                        while(child && domUtils.isBlockElm(child)){\r\n                            if(child.nodeType == 1 && child.childNodes[0]){\r\n                                child = child.childNodes[0]\r\n                            }else{\r\n                                break;\r\n                            }\r\n                        }\r\n                        child && this.setStartBefore(child).collapse(true)\r\n                    }\r\n\r\n                }\r\n                //是createAddress最后一位算的不准，现在这里进行微调\r\n                checkOffset(this);\r\n                nativeRange.setStart(this.startContainer, this.startOffset);\r\n                nativeRange.setEnd(this.endContainer, this.endOffset);\r\n                sel.addRange(nativeRange);\r\n            }\r\n            return this;\r\n        },\r\n\r\n        /**\r\n         * 滚动到当前range开始的位置\r\n         * @method scrollToView\r\n         * @param { Window } win 当前range对象所属的window对象\r\n         * @return { UE.dom.Range } 当前Range对象\r\n         */\r\n\r\n        /**\r\n         * 滚动到距离当前range开始位置 offset 的位置处\r\n         * @method scrollToView\r\n         * @param { Window } win 当前range对象所属的window对象\r\n         * @param { Number } offset 距离range开始位置处的偏移量， 如果为正数， 则向下偏移， 反之， 则向上偏移\r\n         * @return { UE.dom.Range } 当前Range对象\r\n         */\r\n        scrollToView:function (win, offset) {\r\n            win = win ? window : domUtils.getWindow(this.document);\r\n            var me = this,\r\n                span = me.document.createElement('span');\r\n            //trace:717\r\n            span.innerHTML = '&nbsp;';\r\n            me.cloneRange().insertNode(span);\r\n            domUtils.scrollToView(span, win, offset);\r\n            domUtils.remove(span);\r\n            return me;\r\n        },\r\n\r\n        /**\r\n         * 判断当前选区内容是否占位符\r\n         * @private\r\n         * @method inFillChar\r\n         * @return { Boolean } 如果是占位符返回true，否则返回false\r\n         */\r\n        inFillChar : function(){\r\n            var start = this.startContainer;\r\n            if(this.collapsed && start.nodeType == 3\r\n                && start.nodeValue.replace(new RegExp('^' + domUtils.fillChar),'').length + 1 == start.nodeValue.length\r\n                ){\r\n                return true;\r\n            }\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * 保存\r\n         * @method createAddress\r\n         * @private\r\n         * @return { Boolean } 返回开始和结束的位置\r\n         * @example\r\n         * ```html\r\n         * <body>\r\n         *     <p>\r\n         *         aaaa\r\n         *         <em>\r\n         *             <!-- 选区开始 -->\r\n         *             bbbb\r\n         *             <!-- 选区结束 -->\r\n         *         </em>\r\n         *     </p>\r\n         *\r\n         *     <script>\r\n         *         //output: {startAddress:[0,1,0,0],endAddress:[0,1,0,4]}\r\n         *         console.log( range.createAddress() );\r\n         *     </script>\r\n         * </body>\r\n         * ```\r\n         */\r\n        createAddress : function(ignoreEnd,ignoreTxt){\r\n            var addr = {},me = this;\r\n\r\n            function getAddress(isStart){\r\n                var node = isStart ? me.startContainer : me.endContainer;\r\n                var parents = domUtils.findParents(node,true,function(node){return !domUtils.isBody(node)}),\r\n                    addrs = [];\r\n                for(var i = 0,ci;ci = parents[i++];){\r\n                    addrs.push(domUtils.getNodeIndex(ci,ignoreTxt));\r\n                }\r\n                var firstIndex = 0;\r\n\r\n                if(ignoreTxt){\r\n                    if(node.nodeType == 3){\r\n                        var tmpNode = node.previousSibling;\r\n                        while(tmpNode && tmpNode.nodeType == 3){\r\n                            firstIndex += tmpNode.nodeValue.replace(fillCharReg,'').length;\r\n                            tmpNode = tmpNode.previousSibling;\r\n                        }\r\n                        firstIndex +=  (isStart ? me.startOffset : me.endOffset)// - (fillCharReg.test(node.nodeValue) ? 1 : 0 )\r\n                    }else{\r\n                        node =  node.childNodes[ isStart ? me.startOffset : me.endOffset];\r\n                        if(node){\r\n                            firstIndex = domUtils.getNodeIndex(node,ignoreTxt);\r\n                        }else{\r\n                            node = isStart ? me.startContainer : me.endContainer;\r\n                            var first = node.firstChild;\r\n                            while(first){\r\n                                if(domUtils.isFillChar(first)){\r\n                                    first = first.nextSibling;\r\n                                    continue;\r\n                                }\r\n                                firstIndex++;\r\n                                if(first.nodeType == 3){\r\n                                    while( first && first.nodeType == 3){\r\n                                        first = first.nextSibling;\r\n                                    }\r\n                                }else{\r\n                                    first = first.nextSibling;\r\n                                }\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                }else{\r\n                    firstIndex = isStart ? domUtils.isFillChar(node) ? 0 : me.startOffset  : me.endOffset\r\n                }\r\n                if(firstIndex < 0){\r\n                    firstIndex = 0;\r\n                }\r\n                addrs.push(firstIndex);\r\n                return addrs;\r\n            }\r\n            addr.startAddress = getAddress(true);\r\n            if(!ignoreEnd){\r\n                addr.endAddress = me.collapsed ? [].concat(addr.startAddress) : getAddress();\r\n            }\r\n            return addr;\r\n        },\r\n\r\n        /**\r\n         * 保存\r\n         * @method createAddress\r\n         * @private\r\n         * @return { Boolean } 返回开始和结束的位置\r\n         * @example\r\n         * ```html\r\n         * <body>\r\n         *     <p>\r\n         *         aaaa\r\n         *         <em>\r\n         *             <!-- 选区开始 -->\r\n         *             bbbb\r\n         *             <!-- 选区结束 -->\r\n         *         </em>\r\n         *     </p>\r\n         *\r\n         *     <script>\r\n         *         var range = editor.selection.getRange();\r\n         *         range.moveToAddress({startAddress:[0,1,0,0],endAddress:[0,1,0,4]});\r\n         *         range.select();\r\n         *         //output: 'bbbb'\r\n         *         console.log(editor.selection.getText());\r\n         *     </script>\r\n         * </body>\r\n         * ```\r\n         */\r\n        moveToAddress : function(addr,ignoreEnd){\r\n            var me = this;\r\n            function getNode(address,isStart){\r\n                var tmpNode = me.document.body,\r\n                    parentNode,offset;\r\n                for(var i= 0,ci,l=address.length;i<l;i++){\r\n                    ci = address[i];\r\n                    parentNode = tmpNode;\r\n                    tmpNode = tmpNode.childNodes[ci];\r\n                    if(!tmpNode){\r\n                        offset = ci;\r\n                        break;\r\n                    }\r\n                }\r\n                if(isStart){\r\n                    if(tmpNode){\r\n                        me.setStartBefore(tmpNode)\r\n                    }else{\r\n                        me.setStart(parentNode,offset)\r\n                    }\r\n                }else{\r\n                    if(tmpNode){\r\n                        me.setEndBefore(tmpNode)\r\n                    }else{\r\n                        me.setEnd(parentNode,offset)\r\n                    }\r\n                }\r\n            }\r\n            getNode(addr.startAddress,true);\r\n            !ignoreEnd && addr.endAddress &&  getNode(addr.endAddress);\r\n            return me;\r\n        },\r\n\r\n        /**\r\n         * 判断给定的Range对象是否和当前Range对象表示的是同一个选区\r\n         * @method equals\r\n         * @param { UE.dom.Range } 需要判断的Range对象\r\n         * @return { Boolean } 如果给定的Range对象与当前Range对象表示的是同一个选区， 则返回true， 否则返回false\r\n         */\r\n        equals : function(rng){\r\n            for(var p in this){\r\n                if(this.hasOwnProperty(p)){\r\n                    if(this[p] !== rng[p])\r\n                        return false\r\n                }\r\n            }\r\n            return true;\r\n\r\n        },\r\n\r\n        /**\r\n         * 遍历range内的节点。每当遍历一个节点时， 都会执行参数项 doFn 指定的函数， 该函数的接受当前遍历的节点\r\n         * 作为其参数。\r\n         * @method traversal\r\n         * @param { Function }  doFn 对每个遍历的节点要执行的方法， 该方法接受当前遍历的节点作为其参数\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @example\r\n         * ```html\r\n         *\r\n         * <body>\r\n         *\r\n         *     <!-- 选区开始 -->\r\n         *     <span></span>\r\n         *     <a></a>\r\n         *     <!-- 选区结束 -->\r\n         * </body>\r\n         *\r\n         * <script>\r\n         *\r\n         *     //output: <span></span><a></a>\r\n         *     console.log( range.cloneContents() );\r\n         *\r\n         *     range.traversal( function ( node ) {\r\n         *\r\n         *         if ( node.nodeType === 1 ) {\r\n         *             node.className = \"test\";\r\n         *         }\r\n         *\r\n         *     } );\r\n         *\r\n         *     //output: <span class=\"test\"></span><a class=\"test\"></a>\r\n         *     console.log( range.cloneContents() );\r\n         *\r\n         * </script>\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 遍历range内的节点。\r\n         * 每当遍历一个节点时， 都会执行参数项 doFn 指定的函数， 该函数的接受当前遍历的节点\r\n         * 作为其参数。\r\n         * 可以通过参数项 filterFn 来指定一个过滤器， 只有符合该过滤器过滤规则的节点才会触\r\n         * 发doFn函数的执行\r\n         * @method traversal\r\n         * @param { Function } doFn 对每个遍历的节点要执行的方法， 该方法接受当前遍历的节点作为其参数\r\n         * @param { Function } filterFn 过滤器， 该函数接受当前遍历的节点作为参数， 如果该节点满足过滤\r\n         *                      规则， 请返回true， 该节点会触发doFn， 否则， 请返回false， 则该节点不\r\n         *                      会触发doFn。\r\n         * @return { UE.dom.Range } 当前range对象\r\n         * @see UE.dom.Range:traversal(Function)\r\n         * @example\r\n         * ```html\r\n         *\r\n         * <body>\r\n         *\r\n         *     <!-- 选区开始 -->\r\n         *     <span></span>\r\n         *     <a></a>\r\n         *     <!-- 选区结束 -->\r\n         * </body>\r\n         *\r\n         * <script>\r\n         *\r\n         *     //output: <span></span><a></a>\r\n         *     console.log( range.cloneContents() );\r\n         *\r\n         *     range.traversal( function ( node ) {\r\n         *\r\n         *         node.className = \"test\";\r\n         *\r\n         *     }, function ( node ) {\r\n         *          return node.nodeType === 1;\r\n         *     } );\r\n         *\r\n         *     //output: <span class=\"test\"></span><a class=\"test\"></a>\r\n         *     console.log( range.cloneContents() );\r\n         *\r\n         * </script>\r\n         * ```\r\n         */\r\n        traversal:function(doFn,filterFn){\r\n            if (this.collapsed)\r\n                return this;\r\n            var bookmark = this.createBookmark(),\r\n                end = bookmark.end,\r\n                current = domUtils.getNextDomNode(bookmark.start, false, filterFn);\r\n            while (current && current !== end && (domUtils.getPosition(current, end) & domUtils.POSITION_PRECEDING)) {\r\n                var tmpNode = domUtils.getNextDomNode(current,false,filterFn);\r\n                doFn(current);\r\n                current = tmpNode;\r\n            }\r\n            return this.moveToBookmark(bookmark);\r\n        }\r\n    };\r\n})();\n\n// core/Selection.js\n/**\r\n * 选集\r\n * @file\r\n * @module UE.dom\r\n * @class Selection\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 选区集合\r\n * @unfile\r\n * @module UE.dom\r\n * @class Selection\r\n */\r\n(function () {\r\n\r\n    function getBoundaryInformation( range, start ) {\r\n        var getIndex = domUtils.getNodeIndex;\r\n        range = range.duplicate();\r\n        range.collapse( start );\r\n        var parent = range.parentElement();\r\n        //如果节点里没有子节点，直接退出\r\n        if ( !parent.hasChildNodes() ) {\r\n            return  {container:parent, offset:0};\r\n        }\r\n        var siblings = parent.children,\r\n            child,\r\n            testRange = range.duplicate(),\r\n            startIndex = 0, endIndex = siblings.length - 1, index = -1,\r\n            distance;\r\n        while ( startIndex <= endIndex ) {\r\n            index = Math.floor( (startIndex + endIndex) / 2 );\r\n            child = siblings[index];\r\n            testRange.moveToElementText( child );\r\n            var position = testRange.compareEndPoints( 'StartToStart', range );\r\n            if ( position > 0 ) {\r\n                endIndex = index - 1;\r\n            } else if ( position < 0 ) {\r\n                startIndex = index + 1;\r\n            } else {\r\n                //trace:1043\r\n                return  {container:parent, offset:getIndex( child )};\r\n            }\r\n        }\r\n        if ( index == -1 ) {\r\n            testRange.moveToElementText( parent );\r\n            testRange.setEndPoint( 'StartToStart', range );\r\n            distance = testRange.text.replace( /(\\r\\n|\\r)/g, '\\n' ).length;\r\n            siblings = parent.childNodes;\r\n            if ( !distance ) {\r\n                child = siblings[siblings.length - 1];\r\n                return  {container:child, offset:child.nodeValue.length};\r\n            }\r\n\r\n            var i = siblings.length;\r\n            while ( distance > 0 ){\r\n                distance -= siblings[ --i ].nodeValue.length;\r\n            }\r\n            return {container:siblings[i], offset:-distance};\r\n        }\r\n        testRange.collapse( position > 0 );\r\n        testRange.setEndPoint( position > 0 ? 'StartToStart' : 'EndToStart', range );\r\n        distance = testRange.text.replace( /(\\r\\n|\\r)/g, '\\n' ).length;\r\n        if ( !distance ) {\r\n            return  dtd.$empty[child.tagName] || dtd.$nonChild[child.tagName] ?\r\n            {container:parent, offset:getIndex( child ) + (position > 0 ? 0 : 1)} :\r\n            {container:child, offset:position > 0 ? 0 : child.childNodes.length}\r\n        }\r\n        while ( distance > 0 ) {\r\n            try {\r\n                var pre = child;\r\n                child = child[position > 0 ? 'previousSibling' : 'nextSibling'];\r\n                distance -= child.nodeValue.length;\r\n            } catch ( e ) {\r\n                return {container:parent, offset:getIndex( pre )};\r\n            }\r\n        }\r\n        return  {container:child, offset:position > 0 ? -distance : child.nodeValue.length + distance}\r\n    }\r\n\r\n    /**\r\n     * 将ieRange转换为Range对象\r\n     * @param {Range}   ieRange    ieRange对象\r\n     * @param {Range}   range      Range对象\r\n     * @return  {Range}  range       返回转换后的Range对象\r\n     */\r\n    function transformIERangeToRange( ieRange, range ) {\r\n        if ( ieRange.item ) {\r\n            range.selectNode( ieRange.item( 0 ) );\r\n        } else {\r\n            var bi = getBoundaryInformation( ieRange, true );\r\n            range.setStart( bi.container, bi.offset );\r\n            if ( ieRange.compareEndPoints( 'StartToEnd', ieRange ) != 0 ) {\r\n                bi = getBoundaryInformation( ieRange, false );\r\n                range.setEnd( bi.container, bi.offset );\r\n            }\r\n        }\r\n        return range;\r\n    }\r\n\r\n    /**\r\n     * 获得ieRange\r\n     * @param {Selection} sel    Selection对象\r\n     * @return {ieRange}    得到ieRange\r\n     */\r\n    function _getIERange( sel ) {\r\n        var ieRange;\r\n        //ie下有可能报错\r\n        try {\r\n            ieRange = sel.getNative().createRange();\r\n        } catch ( e ) {\r\n            return null;\r\n        }\r\n        var el = ieRange.item ? ieRange.item( 0 ) : ieRange.parentElement();\r\n        if ( ( el.ownerDocument || el ) === sel.document ) {\r\n            return ieRange;\r\n        }\r\n        return null;\r\n    }\r\n\r\n    var Selection = dom.Selection = function ( doc ) {\r\n        var me = this, iframe;\r\n        me.document = doc;\r\n        if ( browser.ie9below ) {\r\n            iframe = domUtils.getWindow( doc ).frameElement;\r\n            domUtils.on( iframe, 'beforedeactivate', function () {\r\n                me._bakIERange = me.getIERange();\r\n            } );\r\n            domUtils.on( iframe, 'activate', function () {\r\n                try {\r\n                    if ( !_getIERange( me ) && me._bakIERange ) {\r\n                        me._bakIERange.select();\r\n                    }\r\n                } catch ( ex ) {\r\n                }\r\n                me._bakIERange = null;\r\n            } );\r\n        }\r\n        iframe = doc = null;\r\n    };\r\n\r\n    Selection.prototype = {\r\n\r\n        rangeInBody : function(rng,txtRange){\r\n            var node = browser.ie9below || txtRange ? rng.item ? rng.item() : rng.parentElement() : rng.startContainer;\r\n\r\n            return node === this.document.body || domUtils.inDoc(node,this.document);\r\n        },\r\n\r\n        /**\r\n         * 获取原生seleciton对象\r\n         * @method getNative\r\n         * @return { Object } 获得selection对象\r\n         * @example\r\n         * ```javascript\r\n         * editor.selection.getNative();\r\n         * ```\r\n         */\r\n        getNative:function () {\r\n            var doc = this.document;\r\n            try {\r\n                return !doc ? null : browser.ie9below ? doc.selection : domUtils.getWindow( doc ).getSelection();\r\n            } catch ( e ) {\r\n                return null;\r\n            }\r\n        },\r\n\r\n        /**\r\n         * 获得ieRange\r\n         * @method getIERange\r\n         * @return { Object } 返回ie原生的Range\r\n         * @example\r\n         * ```javascript\r\n         * editor.selection.getIERange();\r\n         * ```\r\n         */\r\n        getIERange:function () {\r\n            var ieRange = _getIERange( this );\r\n            if ( !ieRange ) {\r\n                if ( this._bakIERange ) {\r\n                    return this._bakIERange;\r\n                }\r\n            }\r\n            return ieRange;\r\n        },\r\n\r\n        /**\r\n         * 缓存当前选区的range和选区的开始节点\r\n         * @method cache\r\n         */\r\n        cache:function () {\r\n            this.clear();\r\n            this._cachedRange = this.getRange();\r\n            this._cachedStartElement = this.getStart();\r\n            this._cachedStartElementPath = this.getStartElementPath();\r\n        },\r\n\r\n        /**\r\n         * 获取选区开始位置的父节点到body\r\n         * @method getStartElementPath\r\n         * @return { Array } 返回父节点集合\r\n         * @example\r\n         * ```javascript\r\n         * editor.selection.getStartElementPath();\r\n         * ```\r\n         */\r\n        getStartElementPath:function () {\r\n            if ( this._cachedStartElementPath ) {\r\n                return this._cachedStartElementPath;\r\n            }\r\n            var start = this.getStart();\r\n            if ( start ) {\r\n                return domUtils.findParents( start, true, null, true )\r\n            }\r\n            return [];\r\n        },\r\n\r\n        /**\r\n         * 清空缓存\r\n         * @method clear\r\n         */\r\n        clear:function () {\r\n            this._cachedStartElementPath = this._cachedRange = this._cachedStartElement = null;\r\n        },\r\n\r\n        /**\r\n         * 编辑器是否得到了选区\r\n         * @method isFocus\r\n         */\r\n        isFocus:function () {\r\n            try {\r\n                if(browser.ie9below){\r\n\r\n                    var nativeRange = _getIERange(this);\r\n                    return !!(nativeRange && this.rangeInBody(nativeRange));\r\n                }else{\r\n                    return !!this.getNative().rangeCount;\r\n                }\r\n            } catch ( e ) {\r\n                return false;\r\n            }\r\n\r\n        },\r\n\r\n        /**\r\n         * 获取选区对应的Range\r\n         * @method getRange\r\n         * @return { Object } 得到Range对象\r\n         * @example\r\n         * ```javascript\r\n         * editor.selection.getRange();\r\n         * ```\r\n         */\r\n        getRange:function () {\r\n            var me = this;\r\n            function optimze( range ) {\r\n                var child = me.document.body.firstChild,\r\n                    collapsed = range.collapsed;\r\n                while ( child && child.firstChild ) {\r\n                    range.setStart( child, 0 );\r\n                    child = child.firstChild;\r\n                }\r\n                if ( !range.startContainer ) {\r\n                    range.setStart( me.document.body, 0 )\r\n                }\r\n                if ( collapsed ) {\r\n                    range.collapse( true );\r\n                }\r\n            }\r\n\r\n            if ( me._cachedRange != null ) {\r\n                return this._cachedRange;\r\n            }\r\n            var range = new baidu.editor.dom.Range( me.document );\r\n\r\n            if ( browser.ie9below ) {\r\n                var nativeRange = me.getIERange();\r\n                if ( nativeRange ) {\r\n                    //备份的_bakIERange可能已经实效了，dom树发生了变化比如从源码模式切回来，所以try一下，实效就放到body开始位置\r\n                    try{\r\n                        transformIERangeToRange( nativeRange, range );\r\n                    }catch(e){\r\n                        optimze( range );\r\n                    }\r\n\r\n                } else {\r\n                    optimze( range );\r\n                }\r\n            } else {\r\n                var sel = me.getNative();\r\n                if ( sel && sel.rangeCount ) {\r\n                    var firstRange = sel.getRangeAt( 0 );\r\n                    var lastRange = sel.getRangeAt( sel.rangeCount - 1 );\r\n                    range.setStart( firstRange.startContainer, firstRange.startOffset ).setEnd( lastRange.endContainer, lastRange.endOffset );\r\n                    if ( range.collapsed && domUtils.isBody( range.startContainer ) && !range.startOffset ) {\r\n                        optimze( range );\r\n                    }\r\n                } else {\r\n                    //trace:1734 有可能已经不在dom树上了，标识的节点\r\n                    if ( this._bakRange && domUtils.inDoc( this._bakRange.startContainer, this.document ) ){\r\n                        return this._bakRange;\r\n                    }\r\n                    optimze( range );\r\n                }\r\n            }\r\n            return this._bakRange = range;\r\n        },\r\n\r\n        /**\r\n         * 获取开始元素，用于状态反射\r\n         * @method getStart\r\n         * @return { Element } 获得开始元素\r\n         * @example\r\n         * ```javascript\r\n         * editor.selection.getStart();\r\n         * ```\r\n         */\r\n        getStart:function () {\r\n            if ( this._cachedStartElement ) {\r\n                return this._cachedStartElement;\r\n            }\r\n            var range = browser.ie9below ? this.getIERange() : this.getRange(),\r\n                tmpRange,\r\n                start, tmp, parent;\r\n            if ( browser.ie9below ) {\r\n                if ( !range ) {\r\n                    //todo 给第一个值可能会有问题\r\n                    return this.document.body.firstChild;\r\n                }\r\n                //control元素\r\n                if ( range.item ){\r\n                    return range.item( 0 );\r\n                }\r\n                tmpRange = range.duplicate();\r\n                //修正ie下<b>x</b>[xx] 闭合后 <b>x|</b>xx\r\n                tmpRange.text.length > 0 && tmpRange.moveStart( 'character', 1 );\r\n                tmpRange.collapse( 1 );\r\n                start = tmpRange.parentElement();\r\n                parent = tmp = range.parentElement();\r\n                while ( tmp = tmp.parentNode ) {\r\n                    if ( tmp == start ) {\r\n                        start = parent;\r\n                        break;\r\n                    }\r\n                }\r\n            } else {\r\n                range.shrinkBoundary();\r\n                start = range.startContainer;\r\n                if ( start.nodeType == 1 && start.hasChildNodes() ){\r\n                    start = start.childNodes[Math.min( start.childNodes.length - 1, range.startOffset )];\r\n                }\r\n                if ( start.nodeType == 3 ){\r\n                    return start.parentNode;\r\n                }\r\n            }\r\n            return start;\r\n        },\r\n\r\n        /**\r\n         * 得到选区中的文本\r\n         * @method getText\r\n         * @return { String } 选区中包含的文本\r\n         * @example\r\n         * ```javascript\r\n         * editor.selection.getText();\r\n         * ```\r\n         */\r\n        getText:function () {\r\n            var nativeSel, nativeRange;\r\n            if ( this.isFocus() && (nativeSel = this.getNative()) ) {\r\n                nativeRange = browser.ie9below ? nativeSel.createRange() : nativeSel.getRangeAt( 0 );\r\n                return browser.ie9below ? nativeRange.text : nativeRange.toString();\r\n            }\r\n            return '';\r\n        },\r\n\r\n        /**\r\n         * 清除选区\r\n         * @method clearRange\r\n         * @example\r\n         * ```javascript\r\n         * editor.selection.clearRange();\r\n         * ```\r\n         */\r\n        clearRange : function(){\r\n            this.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges']();\r\n        }\r\n    };\r\n})();\n\n// core/Editor.js\n/**\r\n * 编辑器主类，包含编辑器提供的大部分公用接口\r\n * @file\r\n * @module UE\r\n * @class Editor\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * UEditor公用空间，UEditor所有的功能都挂载在该空间下\r\n * @unfile\r\n * @module UE\r\n */\r\n\r\n/**\r\n * UEditor的核心类，为用户提供与编辑器交互的接口。\r\n * @unfile\r\n * @module UE\r\n * @class Editor\r\n */\r\n\r\n(function () {\r\n    var uid = 0, _selectionChangeTimer;\r\n\r\n    /**\r\n     * 获取编辑器的html内容，赋值到编辑器所在表单的textarea文本域里面\r\n     * @private\r\n     * @method setValue\r\n     * @param { UE.Editor } editor 编辑器事例\r\n     */\r\n    function setValue(form, editor) {\r\n        var textarea;\r\n        if (editor.textarea) {\r\n            if (utils.isString(editor.textarea)) {\r\n                for (var i = 0, ti, tis = domUtils.getElementsByTagName(form, 'textarea'); ti = tis[i++];) {\r\n                    if (ti.id == 'ueditor_textarea_' + editor.options.textarea) {\r\n                        textarea = ti;\r\n                        break;\r\n                    }\r\n                }\r\n            } else {\r\n                textarea = editor.textarea;\r\n            }\r\n        }\r\n        if (!textarea) {\r\n            form.appendChild(textarea = domUtils.createElement(document, 'textarea', {\r\n                'name': editor.options.textarea,\r\n                'id': 'ueditor_textarea_' + editor.options.textarea,\r\n                'style': \"display:none\"\r\n            }));\r\n            //不要产生多个textarea\r\n            editor.textarea = textarea;\r\n        }\r\n        !textarea.getAttribute('name') && textarea.setAttribute('name', editor.options.textarea );\r\n        textarea.value = editor.hasContents() ?\r\n            (editor.options.allHtmlEnabled ? editor.getAllHtml() : editor.getContent(null, null, true)) :\r\n            ''\r\n    }\r\n    function loadPlugins(me){\r\n        //初始化插件\r\n        for (var pi in UE.plugins) {\r\n            UE.plugins[pi].call(me);\r\n        }\r\n\r\n    }\r\n    function checkCurLang(I18N){\r\n        for(var lang in I18N){\r\n            return lang\r\n        }\r\n    }\r\n\r\n    function langReadied(me){\r\n        me.langIsReady = true;\r\n\r\n        me.fireEvent(\"langReady\");\r\n    }\r\n\r\n    /**\r\n     * 编辑器准备就绪后会触发该事件\r\n     * @module UE\r\n     * @class Editor\r\n     * @event ready\r\n     * @remind render方法执行完成之后,会触发该事件\r\n     * @remind\r\n     * @example\r\n     * ```javascript\r\n     * editor.addListener( 'ready', function( editor ) {\r\n     *     editor.execCommand( 'focus' ); //编辑器家在完成后，让编辑器拿到焦点\r\n     * } );\r\n     * ```\r\n     */\r\n    /**\r\n     * 执行destroy方法,会触发该事件\r\n     * @module UE\r\n     * @class Editor\r\n     * @event destroy\r\n     * @see UE.Editor:destroy()\r\n     */\r\n    /**\r\n     * 执行reset方法,会触发该事件\r\n     * @module UE\r\n     * @class Editor\r\n     * @event reset\r\n     * @see UE.Editor:reset()\r\n     */\r\n    /**\r\n     * 执行focus方法,会触发该事件\r\n     * @module UE\r\n     * @class Editor\r\n     * @event focus\r\n     * @see UE.Editor:focus(Boolean)\r\n     */\r\n    /**\r\n     * 语言加载完成会触发该事件\r\n     * @module UE\r\n     * @class Editor\r\n     * @event langReady\r\n     */\r\n    /**\r\n     * 运行命令之后会触发该命令\r\n     * @module UE\r\n     * @class Editor\r\n     * @event beforeExecCommand\r\n     */\r\n    /**\r\n     * 运行命令之后会触发该命令\r\n     * @module UE\r\n     * @class Editor\r\n     * @event afterExecCommand\r\n     */\r\n    /**\r\n     * 运行命令之前会触发该命令\r\n     * @module UE\r\n     * @class Editor\r\n     * @event firstBeforeExecCommand\r\n     */\r\n    /**\r\n     * 在getContent方法执行之前会触发该事件\r\n     * @module UE\r\n     * @class Editor\r\n     * @event beforeGetContent\r\n     * @see UE.Editor:getContent()\r\n     */\r\n    /**\r\n     * 在getContent方法执行之后会触发该事件\r\n     * @module UE\r\n     * @class Editor\r\n     * @event afterGetContent\r\n     * @see UE.Editor:getContent()\r\n     */\r\n    /**\r\n     * 在getAllHtml方法执行时会触发该事件\r\n     * @module UE\r\n     * @class Editor\r\n     * @event getAllHtml\r\n     * @see UE.Editor:getAllHtml()\r\n     */\r\n    /**\r\n     * 在setContent方法执行之前会触发该事件\r\n     * @module UE\r\n     * @class Editor\r\n     * @event beforeSetContent\r\n     * @see UE.Editor:setContent(String)\r\n     */\r\n    /**\r\n     * 在setContent方法执行之后会触发该事件\r\n     * @module UE\r\n     * @class Editor\r\n     * @event afterSetContent\r\n     * @see UE.Editor:setContent(String)\r\n     */\r\n    /**\r\n     * 每当编辑器内部选区发生改变时，将触发该事件\r\n     * @event selectionchange\r\n     * @warning 该事件的触发非常频繁，不建议在该事件的处理过程中做重量级的处理\r\n     * @example\r\n     * ```javascript\r\n     * editor.addListener( 'selectionchange', function( editor ) {\r\n     *     console.log('选区发生改变');\r\n     * }\r\n     */\r\n    /**\r\n     * 在所有selectionchange的监听函数执行之前，会触发该事件\r\n     * @module UE\r\n     * @class Editor\r\n     * @event beforeSelectionChange\r\n     * @see UE.Editor:selectionchange\r\n     */\r\n    /**\r\n     * 在所有selectionchange的监听函数执行完之后，会触发该事件\r\n     * @module UE\r\n     * @class Editor\r\n     * @event afterSelectionChange\r\n     * @see UE.Editor:selectionchange\r\n     */\r\n    /**\r\n     * 编辑器内容发生改变时会触发该事件\r\n     * @module UE\r\n     * @class Editor\r\n     * @event contentChange\r\n     */\r\n\r\n\r\n    /**\r\n     * 以默认参数构建一个编辑器实例\r\n     * @constructor\r\n     * @remind 通过 改构造方法实例化的编辑器,不带ui层.需要render到一个容器,编辑器实例才能正常渲染到页面\r\n     * @example\r\n     * ```javascript\r\n     * var editor = new UE.Editor();\r\n     * editor.execCommand('blod');\r\n     * ```\r\n     * @see UE.Config\r\n     */\r\n\r\n    /**\r\n     * 以给定的参数集合创建一个编辑器实例，对于未指定的参数，将应用默认参数。\r\n     * @constructor\r\n     * @remind 通过 改构造方法实例化的编辑器,不带ui层.需要render到一个容器,编辑器实例才能正常渲染到页面\r\n     * @param { Object } setting 创建编辑器的参数\r\n     * @example\r\n     * ```javascript\r\n     * var editor = new UE.Editor();\r\n     * editor.execCommand('blod');\r\n     * ```\r\n     * @see UE.Config\r\n     */\r\n    var Editor = UE.Editor = function (options) {\r\n        var me = this;\r\n        me.uid = uid++;\r\n        EventBase.call(me);\r\n        me.commands = {};\r\n        me.options = utils.extend(utils.clone(options || {}), UEDITOR_CONFIG, true);\r\n        me.shortcutkeys = {};\r\n        me.inputRules = [];\r\n        me.outputRules = [];\r\n        //设置默认的常用属性\r\n        me.setOpt(Editor.defaultOptions(me));\r\n\r\n        /* 尝试异步加载后台配置 */\r\n        me.loadServerConfig();\r\n\r\n        if(!utils.isEmptyObject(UE.I18N)){\r\n            //修改默认的语言类型\r\n            me.options.lang = checkCurLang(UE.I18N);\r\n            UE.plugin.load(me);\r\n            langReadied(me);\r\n\r\n        }else{\r\n            utils.loadFile(document, {\r\n                src: me.options.langPath + me.options.lang + \"/\" + me.options.lang + \".js\",\r\n                tag: \"script\",\r\n                type: \"text/javascript\",\r\n                defer: \"defer\"\r\n            }, function () {\r\n                UE.plugin.load(me);\r\n                langReadied(me);\r\n            });\r\n        }\r\n\r\n        UE.instants['ueditorInstant' + me.uid] = me;\r\n    };\r\n    Editor.prototype = {\r\n         registerCommand : function(name,obj){\r\n            this.commands[name] = obj;\r\n         },\r\n        /**\r\n         * 编辑器对外提供的监听ready事件的接口， 通过调用该方法，达到的效果与监听ready事件是一致的\r\n         * @method ready\r\n         * @param { Function } fn 编辑器ready之后所执行的回调, 如果在注册事件之前编辑器已经ready，将会\r\n         * 立即触发该回调。\r\n         * @remind 需要等待编辑器加载完成后才能执行的代码,可以使用该方法传入\r\n         * @example\r\n         * ```javascript\r\n         * editor.ready( function( editor ) {\r\n         *     editor.setContent('初始化完毕');\r\n         * } );\r\n         * ```\r\n         * @see UE.Editor.event:ready\r\n         */\r\n        ready: function (fn) {\r\n            var me = this;\r\n            if (fn) {\r\n                me.isReady ? fn.apply(me) : me.addListener('ready', fn);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * 该方法是提供给插件里面使用，设置配置项默认值\r\n         * @method setOpt\r\n         * @warning 三处设置配置项的优先级: 实例化时传入参数 > setOpt()设置 > config文件里设置\r\n         * @warning 该方法仅供编辑器插件内部和编辑器初始化时调用，其他地方不能调用。\r\n         * @param { String } key 编辑器的可接受的选项名称\r\n         * @param { * } val  该选项可接受的值\r\n         * @example\r\n         * ```javascript\r\n         * editor.setOpt( 'initContent', '欢迎使用编辑器' );\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 该方法是提供给插件里面使用，以{key:value}集合的方式设置插件内用到的配置项默认值\r\n         * @method setOpt\r\n         * @warning 三处设置配置项的优先级: 实例化时传入参数 > setOpt()设置 > config文件里设置\r\n         * @warning 该方法仅供编辑器插件内部和编辑器初始化时调用，其他地方不能调用。\r\n         * @param { Object } options 将要设置的选项的键值对对象\r\n         * @example\r\n         * ```javascript\r\n         * editor.setOpt( {\r\n         *     'initContent': '欢迎使用编辑器'\r\n         * } );\r\n         * ```\r\n         */\r\n        setOpt: function (key, val) {\r\n            var obj = {};\r\n            if (utils.isString(key)) {\r\n                obj[key] = val\r\n            } else {\r\n                obj = key;\r\n            }\r\n            utils.extend(this.options, obj, true);\r\n        },\r\n        getOpt:function(key){\r\n            return this.options[key]\r\n        },\r\n        /**\r\n         * 销毁编辑器实例，使用textarea代替\r\n         * @method destroy\r\n         * @example\r\n         * ```javascript\r\n         * editor.destroy();\r\n         * ```\r\n         */\r\n        destroy: function () {\r\n\r\n            var me = this;\r\n            me.fireEvent('destroy');\r\n            var container = me.container.parentNode;\r\n            var textarea = me.textarea;\r\n            if (!textarea) {\r\n                textarea = document.createElement('textarea');\r\n                container.parentNode.insertBefore(textarea, container);\r\n            } else {\r\n                textarea.style.display = ''\r\n            }\r\n\r\n            textarea.style.width = me.iframe.offsetWidth + 'px';\r\n            textarea.style.height = me.iframe.offsetHeight + 'px';\r\n            textarea.value = me.getContent();\r\n            textarea.id = me.key;\r\n            container.innerHTML = '';\r\n            domUtils.remove(container);\r\n            var key = me.key;\r\n            //trace:2004\r\n            for (var p in me) {\r\n                if (me.hasOwnProperty(p)) {\r\n                    delete this[p];\r\n                }\r\n            }\r\n            UE.delEditor(key);\r\n        },\r\n\r\n        /**\r\n         * 渲染编辑器的DOM到指定容器\r\n         * @method render\r\n         * @param { String } containerId 指定一个容器ID\r\n         * @remind 执行该方法,会触发ready事件\r\n         * @warning 必须且只能调用一次\r\n         */\r\n\r\n        /**\r\n         * 渲染编辑器的DOM到指定容器\r\n         * @method render\r\n         * @param { Element } containerDom 直接指定容器对象\r\n         * @remind 执行该方法,会触发ready事件\r\n         * @warning 必须且只能调用一次\r\n         */\r\n        render: function (container) {\r\n            var me = this,\r\n                options = me.options,\r\n                getStyleValue=function(attr){\r\n                    return parseInt(domUtils.getComputedStyle(container,attr));\r\n                };\r\n            if (utils.isString(container)) {\r\n                container = document.getElementById(container);\r\n            }\r\n            if (container) {\r\n                if(options.initialFrameWidth){\r\n                    options.minFrameWidth = options.initialFrameWidth\r\n                }else{\r\n                    options.minFrameWidth = options.initialFrameWidth = container.offsetWidth;\r\n                }\r\n                if(options.initialFrameHeight){\r\n                    options.minFrameHeight = options.initialFrameHeight\r\n                }else{\r\n                    options.initialFrameHeight = options.minFrameHeight = container.offsetHeight;\r\n                }\r\n\r\n                container.style.width = /%$/.test(options.initialFrameWidth) ?  '100%' : options.initialFrameWidth-\r\n                    getStyleValue(\"padding-left\")- getStyleValue(\"padding-right\") +'px';\r\n                container.style.height = /%$/.test(options.initialFrameHeight) ?  '100%' : options.initialFrameHeight -\r\n                    getStyleValue(\"padding-top\")- getStyleValue(\"padding-bottom\") +'px';\r\n\r\n                container.style.zIndex = options.zIndex;\r\n\r\n                var html = ( ie && browser.version < 9  ? '' : '<!DOCTYPE html>') +\r\n                    '<html xmlns=\\'http://www.w3.org/1999/xhtml\\' class=\\'view\\' ><head>' +\r\n                    '<style type=\\'text/css\\'>' +\r\n                    //设置四周的留边\r\n                    '.view{padding:0;word-wrap:break-word;cursor:text;height:90%;}\\n' +\r\n                    //设置默认字体和字号\r\n                    //font-family不能呢随便改，在safari下fillchar会有解析问题\r\n                    'body{margin:8px;font-family:sans-serif;font-size:16px;}' +\r\n                    //设置段落间距\r\n                    'p{margin:5px 0;}</style>' +\r\n                    ( options.iframeCssUrl ? '<link rel=\\'stylesheet\\' type=\\'text/css\\' href=\\'' + utils.unhtml(options.iframeCssUrl) + '\\'/>' : '' ) +\r\n                    (options.initialStyle ? '<style>' + options.initialStyle + '</style>' : '') +\r\n                    '</head><body class=\\'view\\' ></body>' +\r\n                    '<script type=\\'text/javascript\\' ' + (ie ? 'defer=\\'defer\\'' : '' ) +' id=\\'_initialScript\\'>' +\r\n                    'setTimeout(function(){editor = window.parent.UE.instants[\\'ueditorInstant' + me.uid + '\\'];editor._setup(document);},0);' +\r\n                    'var _tmpScript = document.getElementById(\\'_initialScript\\');_tmpScript.parentNode.removeChild(_tmpScript);</script></html>';\r\n                container.appendChild(domUtils.createElement(document, 'iframe', {\r\n                    id: 'ueditor_' + me.uid,\r\n                    width: \"100%\",\r\n                    height: \"100%\",\r\n                    frameborder: \"0\",\r\n                    //先注释掉了，加的原因忘记了，但开启会直接导致全屏模式下内容多时不会出现滚动条\r\n//                    scrolling :'no',\r\n                    src: 'javascript:void(function(){document.open();' + (options.customDomain && document.domain != location.hostname ?  'document.domain=\"' + document.domain + '\";' : '') +\r\n                        'document.write(\"' + html + '\");document.close();}())'\r\n                }));\r\n                container.style.overflow = 'hidden';\r\n                //解决如果是给定的百分比，会导致高度算不对的问题\r\n                setTimeout(function(){\r\n                    if( /%$/.test(options.initialFrameWidth)){\r\n                        options.minFrameWidth = options.initialFrameWidth = container.offsetWidth;\r\n                        //如果这里给定宽度，会导致ie在拖动窗口大小时，编辑区域不随着变化\r\n//                        container.style.width = options.initialFrameWidth + 'px';\r\n                    }\r\n                    if(/%$/.test(options.initialFrameHeight)){\r\n                        options.minFrameHeight = options.initialFrameHeight = container.offsetHeight;\r\n                        container.style.height = options.initialFrameHeight + 'px';\r\n                    }\r\n                })\r\n            }\r\n        },\r\n\r\n        /**\r\n         * 编辑器初始化\r\n         * @method _setup\r\n         * @private\r\n         * @param { Element } doc 编辑器Iframe中的文档对象\r\n         */\r\n        _setup: function (doc) {\r\n\r\n            var me = this,\r\n                options = me.options;\r\n            if (ie) {\r\n                doc.body.disabled = true;\r\n                doc.body.contentEditable = true;\r\n                doc.body.disabled = false;\r\n            } else {\r\n                doc.body.contentEditable = true;\r\n            }\r\n            doc.body.spellcheck = false;\r\n            me.document = doc;\r\n            me.window = doc.defaultView || doc.parentWindow;\r\n            me.iframe = me.window.frameElement;\r\n            me.body = doc.body;\r\n            me.selection = new dom.Selection(doc);\r\n            //gecko初始化就能得到range,无法判断isFocus了\r\n            var geckoSel;\r\n            if (browser.gecko && (geckoSel = this.selection.getNative())) {\r\n                geckoSel.removeAllRanges();\r\n            }\r\n            this._initEvents();\r\n            //为form提交提供一个隐藏的textarea\r\n            for (var form = this.iframe.parentNode; !domUtils.isBody(form); form = form.parentNode) {\r\n                if (form.tagName == 'FORM') {\r\n                    me.form = form;\r\n                    if(me.options.autoSyncData){\r\n                        domUtils.on(me.window,'blur',function(){\r\n                            setValue(form,me);\r\n                        });\r\n                    }else{\r\n                        domUtils.on(form, 'submit', function () {\r\n                            setValue(this, me);\r\n                        });\r\n                    }\r\n                    break;\r\n                }\r\n            }\r\n            if (options.initialContent) {\r\n                if (options.autoClearinitialContent) {\r\n                    var oldExecCommand = me.execCommand;\r\n                    me.execCommand = function () {\r\n                        me.fireEvent('firstBeforeExecCommand');\r\n                        return oldExecCommand.apply(me, arguments);\r\n                    };\r\n                    this._setDefaultContent(options.initialContent);\r\n                } else\r\n                    this.setContent(options.initialContent, false, true);\r\n            }\r\n\r\n            //编辑器不能为空内容\r\n\r\n            if (domUtils.isEmptyNode(me.body)) {\r\n                me.body.innerHTML = '<p>' + (browser.ie ? '' : '<br/>') + '</p>';\r\n            }\r\n            //如果要求focus, 就把光标定位到内容开始\r\n            if (options.focus) {\r\n                setTimeout(function () {\r\n                    me.focus(me.options.focusInEnd);\r\n                    //如果自动清除开着，就不需要做selectionchange;\r\n                    !me.options.autoClearinitialContent && me._selectionChange();\r\n                }, 0);\r\n            }\r\n            if (!me.container) {\r\n                me.container = this.iframe.parentNode;\r\n            }\r\n            if (options.fullscreen && me.ui) {\r\n                me.ui.setFullScreen(true);\r\n            }\r\n\r\n            try {\r\n                me.document.execCommand('2D-position', false, false);\r\n            } catch (e) {\r\n            }\r\n            try {\r\n                me.document.execCommand('enableInlineTableEditing', false, false);\r\n            } catch (e) {\r\n            }\r\n            try {\r\n                me.document.execCommand('enableObjectResizing', false, false);\r\n            } catch (e) {\r\n            }\r\n\r\n            //挂接快捷键\r\n            me._bindshortcutKeys();\r\n            me.isReady = 1;\r\n            me.fireEvent('ready');\r\n            options.onready && options.onready.call(me);\r\n            if (!browser.ie9below) {\r\n                domUtils.on(me.window, ['blur', 'focus'], function (e) {\r\n                    //chrome下会出现alt+tab切换时，导致选区位置不对\r\n                    if (e.type == 'blur') {\r\n                        me._bakRange = me.selection.getRange();\r\n                        try {\r\n                            me._bakNativeRange = me.selection.getNative().getRangeAt(0);\r\n                            me.selection.getNative().removeAllRanges();\r\n                        } catch (e) {\r\n                            me._bakNativeRange = null;\r\n                        }\r\n\r\n                    } else {\r\n                        try {\r\n                            me._bakRange && me._bakRange.select();\r\n                        } catch (e) {\r\n                        }\r\n                    }\r\n                });\r\n            }\r\n            //trace:1518 ff3.6body不够寛，会导致点击空白处无法获得焦点\r\n            if (browser.gecko && browser.version <= 10902) {\r\n                //修复ff3.6初始化进来，不能点击获得焦点\r\n                me.body.contentEditable = false;\r\n                setTimeout(function () {\r\n                    me.body.contentEditable = true;\r\n                }, 100);\r\n                setInterval(function () {\r\n                    me.body.style.height = me.iframe.offsetHeight - 20 + 'px'\r\n                }, 100)\r\n            }\r\n\r\n            !options.isShow && me.setHide();\r\n            options.readonly && me.setDisabled();\r\n        },\r\n\r\n        /**\r\n         * 同步数据到编辑器所在的form\r\n         * 从编辑器的容器节点向上查找form元素，若找到，就同步编辑内容到找到的form里，为提交数据做准备，主要用于是手动提交的情况\r\n         * 后台取得数据的键值，使用你容器上的name属性，如果没有就使用参数里的textarea项\r\n         * @method sync\r\n         * @example\r\n         * ```javascript\r\n         * editor.sync();\r\n         * form.sumbit(); //form变量已经指向了form元素\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 根据传入的formId，在页面上查找要同步数据的表单，若找到，就同步编辑内容到找到的form里，为提交数据做准备\r\n         * 后台取得数据的键值，该键值默认使用给定的编辑器容器的name属性，如果没有name属性则使用参数项里给定的“textarea”项\r\n         * @method sync\r\n         * @param { String } formID 指定一个要同步数据的form的id,编辑器的数据会同步到你指定form下\r\n         */\r\n        sync: function (formId) {\r\n            var me = this,\r\n                form = formId ? document.getElementById(formId) :\r\n                    domUtils.findParent(me.iframe.parentNode, function (node) {\r\n                        return node.tagName == 'FORM'\r\n                    }, true);\r\n            form && setValue(form, me);\r\n        },\r\n\r\n        /**\r\n         * 设置编辑器高度\r\n         * @method setHeight\r\n         * @remind 当配置项autoHeightEnabled为真时,该方法无效\r\n         * @param { Number } number 设置的高度值，纯数值，不带单位\r\n         * @example\r\n         * ```javascript\r\n         * editor.setHeight(number);\r\n         * ```\r\n         */\r\n        setHeight: function (height,notSetHeight) {\r\n            if (height !== parseInt(this.iframe.parentNode.style.height)) {\r\n                this.iframe.parentNode.style.height = height + 'px';\r\n            }\r\n            !notSetHeight && (this.options.minFrameHeight = this.options.initialFrameHeight = height);\r\n            this.body.style.height = height + 'px';\r\n            !notSetHeight && this.trigger('setHeight')\r\n        },\r\n\r\n        /**\r\n         * 为编辑器的编辑命令提供快捷键\r\n         * 这个接口是为插件扩展提供的接口,主要是为新添加的插件，如果需要添加快捷键，所提供的接口\r\n         * @method addshortcutkey\r\n         * @param { Object } keyset 命令名和快捷键键值对对象，多个按钮的快捷键用“＋”分隔\r\n         * @example\r\n         * ```javascript\r\n         * editor.addshortcutkey({\r\n         *     \"Bold\" : \"ctrl+66\",//^B\r\n         *     \"Italic\" : \"ctrl+73\", //^I\r\n         * });\r\n         * ```\r\n         */\r\n        /**\r\n         * 这个接口是为插件扩展提供的接口,主要是为新添加的插件，如果需要添加快捷键，所提供的接口\r\n         * @method addshortcutkey\r\n         * @param { String } cmd 触发快捷键时，响应的命令\r\n         * @param { String } keys 快捷键的字符串，多个按钮用“＋”分隔\r\n         * @example\r\n         * ```javascript\r\n         * editor.addshortcutkey(\"Underline\", \"ctrl+85\"); //^U\r\n         * ```\r\n         */\r\n        addshortcutkey: function (cmd, keys) {\r\n            var obj = {};\r\n            if (keys) {\r\n                obj[cmd] = keys\r\n            } else {\r\n                obj = cmd;\r\n            }\r\n            utils.extend(this.shortcutkeys, obj)\r\n        },\r\n\r\n        /**\r\n         * 对编辑器设置keydown事件监听，绑定快捷键和命令，当快捷键组合触发成功，会响应对应的命令\r\n         * @method _bindshortcutKeys\r\n         * @private\r\n         */\r\n        _bindshortcutKeys: function () {\r\n            var me = this, shortcutkeys = this.shortcutkeys;\r\n            me.addListener('keydown', function (type, e) {\r\n                var keyCode = e.keyCode || e.which;\r\n                for (var i in shortcutkeys) {\r\n                    var tmp = shortcutkeys[i].split(',');\r\n                    for (var t = 0, ti; ti = tmp[t++];) {\r\n                        ti = ti.split(':');\r\n                        var key = ti[0], param = ti[1];\r\n                        if (/^(ctrl)(\\+shift)?\\+(\\d+)$/.test(key.toLowerCase()) || /^(\\d+)$/.test(key)) {\r\n                            if (( (RegExp.$1 == 'ctrl' ? (e.ctrlKey || e.metaKey) : 0)\r\n                                && (RegExp.$2 != \"\" ? e[RegExp.$2.slice(1) + \"Key\"] : 1)\r\n                                && keyCode == RegExp.$3\r\n                                ) ||\r\n                                keyCode == RegExp.$1\r\n                                ) {\r\n                                if (me.queryCommandState(i,param) != -1)\r\n                                    me.execCommand(i, param);\r\n                                domUtils.preventDefault(e);\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                }\r\n            });\r\n        },\r\n\r\n        /**\r\n         * 获取编辑器的内容\r\n         * @method getContent\r\n         * @warning 该方法获取到的是经过编辑器内置的过滤规则进行过滤后得到的内容\r\n         * @return { String } 编辑器的内容字符串, 如果编辑器的内容为空，或者是空的标签内容（如:”&lt;p&gt;&lt;br/&gt;&lt;/p&gt;“）， 则返回空字符串\r\n         * @example\r\n         * ```javascript\r\n         * //编辑器html内容:<p>1<strong>2<em>34</em>5</strong>6</p>\r\n         * var content = editor.getContent(); //返回值:<p>1<strong>2<em>34</em>5</strong>6</p>\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 获取编辑器的内容。 可以通过参数定义编辑器内置的判空规则\r\n         * @method getContent\r\n         * @param { Function } fn 自定的判空规则， 要求该方法返回一个boolean类型的值，\r\n         *                      代表当前编辑器的内容是否空，\r\n         *                      如果返回true， 则该方法将直接返回空字符串；如果返回false，则编辑器将返回\r\n         *                      经过内置过滤规则处理后的内容。\r\n         * @remind 该方法在处理包含有初始化内容的时候能起到很好的作用。\r\n         * @warning 该方法获取到的是经过编辑器内置的过滤规则进行过滤后得到的内容\r\n         * @return { String } 编辑器的内容字符串\r\n         * @example\r\n         * ```javascript\r\n         * // editor 是一个编辑器的实例\r\n         * var content = editor.getContent( function ( editor ) {\r\n         *      return editor.body.innerHTML === '欢迎使用UEditor'; //返回空字符串\r\n         * } );\r\n         * ```\r\n         */\r\n        getContent: function (cmd, fn,notSetCursor,ignoreBlank,formatter) {\r\n            var me = this;\r\n            if (cmd && utils.isFunction(cmd)) {\r\n                fn = cmd;\r\n                cmd = '';\r\n            }\r\n            if (fn ? !fn() : !this.hasContents()) {\r\n                return '';\r\n            }\r\n            me.fireEvent('beforegetcontent');\r\n            var root = UE.htmlparser(me.body.innerHTML,ignoreBlank);\r\n            me.filterOutputRule(root);\r\n            me.fireEvent('aftergetcontent', cmd,root);\r\n            return  root.toHtml(formatter);\r\n        },\r\n\r\n        /**\r\n         * 取得完整的html代码，可以直接显示成完整的html文档\r\n         * @method getAllHtml\r\n         * @return { String } 编辑器的内容html文档字符串\r\n         * @eaxmple\r\n         * ```javascript\r\n         * editor.getAllHtml(); //返回格式大致是: <html><head>...</head><body>...</body></html>\r\n         * ```\r\n         */\r\n        getAllHtml: function () {\r\n            var me = this,\r\n                headHtml = [],\r\n                html = '';\r\n            me.fireEvent('getAllHtml', headHtml);\r\n            if (browser.ie && browser.version > 8) {\r\n                var headHtmlForIE9 = '';\r\n                utils.each(me.document.styleSheets, function (si) {\r\n                    headHtmlForIE9 += ( si.href ? '<link rel=\"stylesheet\" type=\"text/css\" href=\"' + si.href + '\" />' : '<style>' + si.cssText + '</style>');\r\n                });\r\n                utils.each(me.document.getElementsByTagName('script'), function (si) {\r\n                    headHtmlForIE9 += si.outerHTML;\r\n                });\r\n\r\n            }\r\n            return '<html><head>' + (me.options.charset ? '<meta http-equiv=\"Content-Type\" content=\"text/html; charset=' + me.options.charset + '\"/>' : '')\r\n                + (headHtmlForIE9 || me.document.getElementsByTagName('head')[0].innerHTML) + headHtml.join('\\n') + '</head>'\r\n                + '<body ' + (ie && browser.version < 9 ? 'class=\"view\"' : '') + '>' + me.getContent(null, null, true) + '</body></html>';\r\n        },\r\n\r\n        /**\r\n         * 得到编辑器的纯文本内容，但会保留段落格式\r\n         * @method getPlainTxt\r\n         * @return { String } 编辑器带段落格式的纯文本内容字符串\r\n         * @example\r\n         * ```javascript\r\n         * //编辑器html内容:<p><strong>1</strong></p><p><strong>2</strong></p>\r\n         * console.log(editor.getPlainTxt()); //输出:\"1\\n2\\n\r\n         * ```\r\n         */\r\n        getPlainTxt: function () {\r\n            var reg = new RegExp(domUtils.fillChar, 'g'),\r\n                html = this.body.innerHTML.replace(/[\\n\\r]/g, '');//ie要先去了\\n在处理\r\n            html = html.replace(/<(p|div)[^>]*>(<br\\/?>|&nbsp;)<\\/\\1>/gi, '\\n')\r\n                .replace(/<br\\/?>/gi, '\\n')\r\n                .replace(/<[^>/]+>/g, '')\r\n                .replace(/(\\n)?<\\/([^>]+)>/g, function (a, b, c) {\r\n                    return dtd.$block[c] ? '\\n' : b ? b : '';\r\n                });\r\n            //取出来的空格会有c2a0会变成乱码，处理这种情况\\u00a0\r\n            return html.replace(reg, '').replace(/\\u00a0/g, ' ').replace(/&nbsp;/g, ' ');\r\n        },\r\n\r\n        /**\r\n         * 获取编辑器中的纯文本内容,没有段落格式\r\n         * @method getContentTxt\r\n         * @return { String } 编辑器不带段落格式的纯文本内容字符串\r\n         * @example\r\n         * ```javascript\r\n         * //编辑器html内容:<p><strong>1</strong></p><p><strong>2</strong></p>\r\n         * console.log(editor.getPlainTxt()); //输出:\"12\r\n         * ```\r\n         */\r\n        getContentTxt: function () {\r\n            var reg = new RegExp(domUtils.fillChar, 'g');\r\n            //取出来的空格会有c2a0会变成乱码，处理这种情况\\u00a0\r\n            return this.body[browser.ie ? 'innerText' : 'textContent'].replace(reg, '').replace(/\\u00a0/g, ' ');\r\n        },\r\n\r\n        /**\r\n         * 设置编辑器的内容，可修改编辑器当前的html内容\r\n         * @method setContent\r\n         * @warning 通过该方法插入的内容，是经过编辑器内置的过滤规则进行过滤后得到的内容\r\n         * @warning 该方法会触发selectionchange事件\r\n         * @param { String } html 要插入的html内容\r\n         * @example\r\n         * ```javascript\r\n         * editor.getContent('<p>test</p>');\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 设置编辑器的内容，可修改编辑器当前的html内容\r\n         * @method setContent\r\n         * @warning 通过该方法插入的内容，是经过编辑器内置的过滤规则进行过滤后得到的内容\r\n         * @warning 该方法会触发selectionchange事件\r\n         * @param { String } html 要插入的html内容\r\n         * @param { Boolean } isAppendTo 若传入true，不清空原来的内容，在最后插入内容，否则，清空内容再插入\r\n         * @example\r\n         * ```javascript\r\n         * //假设设置前的编辑器内容是 <p>old text</p>\r\n         * editor.setContent('<p>new text</p>', true); //插入的结果是<p>old text</p><p>new text</p>\r\n         * ```\r\n         */\r\n        setContent: function (html, isAppendTo, notFireSelectionchange) {\r\n            var me = this;\r\n\r\n            me.fireEvent('beforesetcontent', html);\r\n            var root = UE.htmlparser(html);\r\n            me.filterInputRule(root);\r\n            html = root.toHtml();\r\n\r\n            me.body.innerHTML = (isAppendTo ? me.body.innerHTML : '') + html;\r\n\r\n\r\n            function isCdataDiv(node){\r\n                return  node.tagName == 'DIV' && node.getAttribute('cdata_tag');\r\n            }\r\n            //给文本或者inline节点套p标签\r\n            if (me.options.enterTag == 'p') {\r\n\r\n                var child = this.body.firstChild, tmpNode;\r\n                if (!child || child.nodeType == 1 &&\r\n                    (dtd.$cdata[child.tagName] || isCdataDiv(child) ||\r\n                        domUtils.isCustomeNode(child)\r\n                        )\r\n                    && child === this.body.lastChild) {\r\n                    this.body.innerHTML = '<p>' + (browser.ie ? '&nbsp;' : '<br/>') + '</p>' + this.body.innerHTML;\r\n\r\n                } else {\r\n                    var p = me.document.createElement('p');\r\n                    while (child) {\r\n                        while (child && (child.nodeType == 3 || child.nodeType == 1 && dtd.p[child.tagName] && !dtd.$cdata[child.tagName])) {\r\n                            tmpNode = child.nextSibling;\r\n                            p.appendChild(child);\r\n                            child = tmpNode;\r\n                        }\r\n                        if (p.firstChild) {\r\n                            if (!child) {\r\n                                me.body.appendChild(p);\r\n                                break;\r\n                            } else {\r\n                                child.parentNode.insertBefore(p, child);\r\n                                p = me.document.createElement('p');\r\n                            }\r\n                        }\r\n                        child = child.nextSibling;\r\n                    }\r\n                }\r\n            }\r\n            me.fireEvent('aftersetcontent');\r\n            me.fireEvent('contentchange');\r\n\r\n            !notFireSelectionchange && me._selectionChange();\r\n            //清除保存的选区\r\n            me._bakRange = me._bakIERange = me._bakNativeRange = null;\r\n            //trace:1742 setContent后gecko能得到焦点问题\r\n            var geckoSel;\r\n            if (browser.gecko && (geckoSel = this.selection.getNative())) {\r\n                geckoSel.removeAllRanges();\r\n            }\r\n            if(me.options.autoSyncData){\r\n                me.form && setValue(me.form,me);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * 让编辑器获得焦点，默认focus到编辑器头部\r\n         * @method focus\r\n         * @example\r\n         * ```javascript\r\n         * editor.focus()\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 让编辑器获得焦点，toEnd确定focus位置\r\n         * @method focus\r\n         * @param { Boolean } toEnd 默认focus到编辑器头部，toEnd为true时focus到内容尾部\r\n         * @example\r\n         * ```javascript\r\n         * editor.focus(true)\r\n         * ```\r\n         */\r\n        focus: function (toEnd) {\r\n            try {\r\n                var me = this,\r\n                    rng = me.selection.getRange();\r\n                if (toEnd) {\r\n                    var node = me.body.lastChild;\r\n                    if(node && node.nodeType == 1 && !dtd.$empty[node.tagName]){\r\n                        if(domUtils.isEmptyBlock(node)){\r\n                            rng.setStartAtFirst(node)\r\n                        }else{\r\n                            rng.setStartAtLast(node)\r\n                        }\r\n                        rng.collapse(true);\r\n                    }\r\n                    rng.setCursor(true);\r\n                } else {\r\n                    if(!rng.collapsed && domUtils.isBody(rng.startContainer) && rng.startOffset == 0){\r\n\r\n                        var node = me.body.firstChild;\r\n                        if(node && node.nodeType == 1 && !dtd.$empty[node.tagName]){\r\n                            rng.setStartAtFirst(node).collapse(true);\r\n                        }\r\n                    }\r\n\r\n                    rng.select(true);\r\n\r\n                }\r\n                this.fireEvent('focus selectionchange');\r\n            } catch (e) {\r\n            }\r\n\r\n        },\r\n        isFocus:function(){\r\n            return this.selection.isFocus();\r\n        },\r\n        blur:function(){\r\n            var sel = this.selection.getNative();\r\n            if(sel.empty && browser.ie){\r\n                var nativeRng = document.body.createTextRange();\r\n                nativeRng.moveToElementText(document.body);\r\n                nativeRng.collapse(true);\r\n                nativeRng.select();\r\n                sel.empty()\r\n            }else{\r\n                sel.removeAllRanges()\r\n            }\r\n\r\n            //this.fireEvent('blur selectionchange');\r\n        },\r\n        /**\r\n         * 初始化UE事件及部分事件代理\r\n         * @method _initEvents\r\n         * @private\r\n         */\r\n        _initEvents: function () {\r\n            var me = this,\r\n                doc = me.document,\r\n                win = me.window;\r\n            me._proxyDomEvent = utils.bind(me._proxyDomEvent, me);\r\n            domUtils.on(doc, ['click', 'contextmenu', 'mousedown', 'keydown', 'keyup', 'keypress', 'mouseup', 'mouseover', 'mouseout', 'selectstart'], me._proxyDomEvent);\r\n            domUtils.on(win, ['focus', 'blur'], me._proxyDomEvent);\r\n            domUtils.on(me.body,'drop',function(e){\r\n                //阻止ff下默认的弹出新页面打开图片\r\n                if(browser.gecko && e.stopPropagation) { e.stopPropagation(); }\r\n                me.fireEvent('contentchange')\r\n            });\r\n            domUtils.on(doc, ['mouseup', 'keydown'], function (evt) {\r\n                //特殊键不触发selectionchange\r\n                if (evt.type == 'keydown' && (evt.ctrlKey || evt.metaKey || evt.shiftKey || evt.altKey)) {\r\n                    return;\r\n                }\r\n                if (evt.button == 2)return;\r\n                me._selectionChange(250, evt);\r\n            });\r\n        },\r\n        /**\r\n         * 触发事件代理\r\n         * @method _proxyDomEvent\r\n         * @private\r\n         * @return { * } fireEvent的返回值\r\n         * @see UE.EventBase:fireEvent(String)\r\n         */\r\n        _proxyDomEvent: function (evt) {\r\n            if(this.fireEvent('before' + evt.type.replace(/^on/, '').toLowerCase()) === false){\r\n                return false;\r\n            }\r\n            if(this.fireEvent(evt.type.replace(/^on/, ''), evt) === false){\r\n                return false;\r\n            }\r\n            return this.fireEvent('after' + evt.type.replace(/^on/, '').toLowerCase())\r\n        },\r\n        /**\r\n         * 变化选区\r\n         * @method _selectionChange\r\n         * @private\r\n         */\r\n        _selectionChange: function (delay, evt) {\r\n            var me = this;\r\n            //有光标才做selectionchange 为了解决未focus时点击source不能触发更改工具栏状态的问题（source命令notNeedUndo=1）\r\n//            if ( !me.selection.isFocus() ){\r\n//                return;\r\n//            }\r\n\r\n\r\n            var hackForMouseUp = false;\r\n            var mouseX, mouseY;\r\n            if (browser.ie && browser.version < 9 && evt && evt.type == 'mouseup') {\r\n                var range = this.selection.getRange();\r\n                if (!range.collapsed) {\r\n                    hackForMouseUp = true;\r\n                    mouseX = evt.clientX;\r\n                    mouseY = evt.clientY;\r\n                }\r\n            }\r\n            clearTimeout(_selectionChangeTimer);\r\n            _selectionChangeTimer = setTimeout(function () {\r\n                if (!me.selection || !me.selection.getNative()) {\r\n                    return;\r\n                }\r\n                //修复一个IE下的bug: 鼠标点击一段已选择的文本中间时，可能在mouseup后的一段时间内取到的range是在selection的type为None下的错误值.\r\n                //IE下如果用户是拖拽一段已选择文本，则不会触发mouseup事件，所以这里的特殊处理不会对其有影响\r\n                var ieRange;\r\n                if (hackForMouseUp && me.selection.getNative().type == 'None') {\r\n                    ieRange = me.document.body.createTextRange();\r\n                    try {\r\n                        ieRange.moveToPoint(mouseX, mouseY);\r\n                    } catch (ex) {\r\n                        ieRange = null;\r\n                    }\r\n                }\r\n                var bakGetIERange;\r\n                if (ieRange) {\r\n                    bakGetIERange = me.selection.getIERange;\r\n                    me.selection.getIERange = function () {\r\n                        return ieRange;\r\n                    };\r\n                }\r\n                me.selection.cache();\r\n                if (bakGetIERange) {\r\n                    me.selection.getIERange = bakGetIERange;\r\n                }\r\n                if (me.selection._cachedRange && me.selection._cachedStartElement) {\r\n                    me.fireEvent('beforeselectionchange');\r\n                    // 第二个参数causeByUi为true代表由用户交互造成的selectionchange.\r\n                    me.fireEvent('selectionchange', !!evt);\r\n                    me.fireEvent('afterselectionchange');\r\n                    me.selection.clear();\r\n                }\r\n            }, delay || 50);\r\n        },\r\n\r\n        /**\r\n         * 执行编辑命令\r\n         * @method _callCmdFn\r\n         * @private\r\n         * @param { String } fnName 函数名称\r\n         * @param { * } args 传给命令函数的参数\r\n         * @return { * } 返回命令函数运行的返回值\r\n         */\r\n        _callCmdFn: function (fnName, args) {\r\n            var cmdName = args[0].toLowerCase(),\r\n                cmd, cmdFn;\r\n            cmd = this.commands[cmdName] || UE.commands[cmdName];\r\n            cmdFn = cmd && cmd[fnName];\r\n            //没有querycommandstate或者没有command的都默认返回0\r\n            if ((!cmd || !cmdFn) && fnName == 'queryCommandState') {\r\n                return 0;\r\n            } else if (cmdFn) {\r\n                return cmdFn.apply(this, args);\r\n            }\r\n        },\r\n\r\n        /**\r\n         * 执行编辑命令cmdName，完成富文本编辑效果\r\n         * @method execCommand\r\n         * @param { String } cmdName 需要执行的命令\r\n         * @remind 具体命令的使用请参考<a href=\"#COMMAND.LIST\">命令列表</a>\r\n         * @return { * } 返回命令函数运行的返回值\r\n         * @example\r\n         * ```javascript\r\n         * editor.execCommand(cmdName);\r\n         * ```\r\n         */\r\n        execCommand: function (cmdName) {\r\n            cmdName = cmdName.toLowerCase();\r\n            var me = this,\r\n                result,\r\n                cmd = me.commands[cmdName] || UE.commands[cmdName];\r\n            if (!cmd || !cmd.execCommand) {\r\n                return null;\r\n            }\r\n            if (!cmd.notNeedUndo && !me.__hasEnterExecCommand) {\r\n                me.__hasEnterExecCommand = true;\r\n                if (me.queryCommandState.apply(me,arguments) != -1) {\r\n                    me.fireEvent('saveScene');\r\n                    me.fireEvent.apply(me, ['beforeexeccommand', cmdName].concat(arguments));\r\n                    result = this._callCmdFn('execCommand', arguments);\r\n                    //保存场景时，做了内容对比，再看是否进行contentchange触发，这里多触发了一次，去掉\r\n//                    (!cmd.ignoreContentChange && !me._ignoreContentChange) && me.fireEvent('contentchange');\r\n                    me.fireEvent.apply(me, ['afterexeccommand', cmdName].concat(arguments));\r\n                    me.fireEvent('saveScene');\r\n                }\r\n                me.__hasEnterExecCommand = false;\r\n            } else {\r\n                result = this._callCmdFn('execCommand', arguments);\r\n                (!me.__hasEnterExecCommand && !cmd.ignoreContentChange && !me._ignoreContentChange) && me.fireEvent('contentchange')\r\n            }\r\n            (!me.__hasEnterExecCommand && !cmd.ignoreContentChange && !me._ignoreContentChange) && me._selectionChange();\r\n            return result;\r\n        },\r\n\r\n        /**\r\n         * 根据传入的command命令，查选编辑器当前的选区，返回命令的状态\r\n         * @method  queryCommandState\r\n         * @param { String } cmdName 需要查询的命令名称\r\n         * @remind 具体命令的使用请参考<a href=\"#COMMAND.LIST\">命令列表</a>\r\n         * @return { Number } number 返回放前命令的状态，返回值三种情况：(-1|0|1)\r\n         * @example\r\n         * ```javascript\r\n         * editor.queryCommandState(cmdName)  => (-1|0|1)\r\n         * ```\r\n         * @see COMMAND.LIST\r\n         */\r\n        queryCommandState: function (cmdName) {\r\n            return this._callCmdFn('queryCommandState', arguments);\r\n        },\r\n\r\n        /**\r\n         * 根据传入的command命令，查选编辑器当前的选区，根据命令返回相关的值\r\n         * @method queryCommandValue\r\n         * @param { String } cmdName 需要查询的命令名称\r\n         * @remind 具体命令的使用请参考<a href=\"#COMMAND.LIST\">命令列表</a>\r\n         * @remind 只有部分插件有此方法\r\n         * @return { * } 返回每个命令特定的当前状态值\r\n         * @grammar editor.queryCommandValue(cmdName)  =>  {*}\r\n         * @see COMMAND.LIST\r\n         */\r\n        queryCommandValue: function (cmdName) {\r\n            return this._callCmdFn('queryCommandValue', arguments);\r\n        },\r\n\r\n        /**\r\n         * 检查编辑区域中是否有内容\r\n         * @method  hasContents\r\n         * @remind 默认有文本内容，或者有以下节点都不认为是空\r\n         * table,ul,ol,dl,iframe,area,base,col,hr,img,embed,input,link,meta,param\r\n         * @return { Boolean } 检查有内容返回true，否则返回false\r\n         * @example\r\n         * ```javascript\r\n         * editor.hasContents()\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 检查编辑区域中是否有内容，若包含参数tags中的节点类型，直接返回true\r\n         * @method  hasContents\r\n         * @param { Array } tags 传入数组判断时用到的节点类型\r\n         * @return { Boolean } 若文档中包含tags数组里对应的tag，返回true，否则返回false\r\n         * @example\r\n         * ```javascript\r\n         * editor.hasContents(['span']);\r\n         * ```\r\n         */\r\n        hasContents: function (tags) {\r\n            if (tags) {\r\n                for (var i = 0, ci; ci = tags[i++];) {\r\n                    if (this.document.getElementsByTagName(ci).length > 0) {\r\n                        return true;\r\n                    }\r\n                }\r\n            }\r\n            if (!domUtils.isEmptyBlock(this.body)) {\r\n                return true\r\n            }\r\n            //随时添加,定义的特殊标签如果存在，不能认为是空\r\n            tags = ['div'];\r\n            for (i = 0; ci = tags[i++];) {\r\n                var nodes = domUtils.getElementsByTagName(this.document, ci);\r\n                for (var n = 0, cn; cn = nodes[n++];) {\r\n                    if (domUtils.isCustomeNode(cn)) {\r\n                        return true;\r\n                    }\r\n                }\r\n            }\r\n            return false;\r\n        },\r\n\r\n        /**\r\n         * 重置编辑器，可用来做多个tab使用同一个编辑器实例\r\n         * @method  reset\r\n         * @remind 此方法会清空编辑器内容，清空回退列表，会触发reset事件\r\n         * @example\r\n         * ```javascript\r\n         * editor.reset()\r\n         * ```\r\n         */\r\n        reset: function () {\r\n            this.fireEvent('reset');\r\n        },\r\n\r\n        /**\r\n         * 设置当前编辑区域可以编辑\r\n         * @method setEnabled\r\n         * @example\r\n         * ```javascript\r\n         * editor.setEnabled()\r\n         * ```\r\n         */\r\n        setEnabled: function () {\r\n            var me = this, range;\r\n            if (me.body.contentEditable == 'false') {\r\n                me.body.contentEditable = true;\r\n                range = me.selection.getRange();\r\n                //有可能内容丢失了\r\n                try {\r\n                    range.moveToBookmark(me.lastBk);\r\n                    delete me.lastBk\r\n                } catch (e) {\r\n                    range.setStartAtFirst(me.body).collapse(true)\r\n                }\r\n                range.select(true);\r\n                if (me.bkqueryCommandState) {\r\n                    me.queryCommandState = me.bkqueryCommandState;\r\n                    delete me.bkqueryCommandState;\r\n                }\r\n                if (me.bkqueryCommandValue) {\r\n                    me.queryCommandValue = me.bkqueryCommandValue;\r\n                    delete me.bkqueryCommandValue;\r\n                }\r\n                me.fireEvent('selectionchange');\r\n            }\r\n        },\r\n        enable: function () {\r\n            return this.setEnabled();\r\n        },\r\n\r\n        /** 设置当前编辑区域不可编辑\r\n         * @method setDisabled\r\n         */\r\n\r\n        /** 设置当前编辑区域不可编辑,except中的命令除外\r\n         * @method setDisabled\r\n         * @param { String } except 例外命令的字符串\r\n         * @remind 即使设置了disable，此处配置的例外命令仍然可以执行\r\n         * @example\r\n         * ```javascript\r\n         * editor.setDisabled('bold'); //禁用工具栏中除加粗之外的所有功能\r\n         * ```\r\n         */\r\n\r\n        /** 设置当前编辑区域不可编辑,except中的命令除外\r\n         * @method setDisabled\r\n         * @param { Array } except 例外命令的字符串数组，数组中的命令仍然可以执行\r\n         * @remind 即使设置了disable，此处配置的例外命令仍然可以执行\r\n         * @example\r\n         * ```javascript\r\n         * editor.setDisabled(['bold','insertimage']); //禁用工具栏中除加粗和插入图片之外的所有功能\r\n         * ```\r\n         */\r\n        setDisabled: function (except) {\r\n            var me = this;\r\n            except = except ? utils.isArray(except) ? except : [except] : [];\r\n            if (me.body.contentEditable == 'true') {\r\n                if (!me.lastBk) {\r\n                    me.lastBk = me.selection.getRange().createBookmark(true);\r\n                }\r\n                me.body.contentEditable = false;\r\n                me.bkqueryCommandState = me.queryCommandState;\r\n                me.bkqueryCommandValue = me.queryCommandValue;\r\n                me.queryCommandState = function (type) {\r\n                    if (utils.indexOf(except, type) != -1) {\r\n                        return me.bkqueryCommandState.apply(me, arguments);\r\n                    }\r\n                    return -1;\r\n                };\r\n                me.queryCommandValue = function (type) {\r\n                    if (utils.indexOf(except, type) != -1) {\r\n                        return me.bkqueryCommandValue.apply(me, arguments);\r\n                    }\r\n                    return null;\r\n                };\r\n                me.fireEvent('selectionchange');\r\n            }\r\n        },\r\n        disable: function (except) {\r\n            return this.setDisabled(except);\r\n        },\r\n\r\n        /**\r\n         * 设置默认内容\r\n         * @method _setDefaultContent\r\n         * @private\r\n         * @param  { String } cont 要存入的内容\r\n         */\r\n        _setDefaultContent: function () {\r\n            function clear() {\r\n                var me = this;\r\n                if (me.document.getElementById('initContent')) {\r\n                    me.body.innerHTML = '<p>' + (ie ? '' : '<br/>') + '</p>';\r\n                    me.removeListener('firstBeforeExecCommand focus', clear);\r\n                    setTimeout(function () {\r\n                        me.focus();\r\n                        me._selectionChange();\r\n                    }, 0)\r\n                }\r\n            }\r\n\r\n            return function (cont) {\r\n                var me = this;\r\n                me.body.innerHTML = '<p id=\"initContent\">' + cont + '</p>';\r\n\r\n                me.addListener('firstBeforeExecCommand focus', clear);\r\n            }\r\n        }(),\r\n\r\n        /**\r\n         * 显示编辑器\r\n         * @method setShow\r\n         * @example\r\n         * ```javascript\r\n         * editor.setShow()\r\n         * ```\r\n         */\r\n        setShow: function () {\r\n            var me = this, range = me.selection.getRange();\r\n            if (me.container.style.display == 'none') {\r\n                //有可能内容丢失了\r\n                try {\r\n                    range.moveToBookmark(me.lastBk);\r\n                    delete me.lastBk\r\n                } catch (e) {\r\n                    range.setStartAtFirst(me.body).collapse(true)\r\n                }\r\n                //ie下focus实效，所以做了个延迟\r\n                setTimeout(function () {\r\n                    range.select(true);\r\n                }, 100);\r\n                me.container.style.display = '';\r\n            }\r\n\r\n        },\r\n        show: function () {\r\n            return this.setShow();\r\n        },\r\n        /**\r\n         * 隐藏编辑器\r\n         * @method setHide\r\n         * @example\r\n         * ```javascript\r\n         * editor.setHide()\r\n         * ```\r\n         */\r\n        setHide: function () {\r\n            var me = this;\r\n            if (!me.lastBk) {\r\n                me.lastBk = me.selection.getRange().createBookmark(true);\r\n            }\r\n            me.container.style.display = 'none'\r\n        },\r\n        hide: function () {\r\n            return this.setHide();\r\n        },\r\n\r\n        /**\r\n         * 根据指定的路径，获取对应的语言资源\r\n         * @method getLang\r\n         * @param { String } path 路径根据的是lang目录下的语言文件的路径结构\r\n         * @return { Object | String } 根据路径返回语言资源的Json格式对象或者语言字符串\r\n         * @example\r\n         * ```javascript\r\n         * editor.getLang('contextMenu.delete'); //如果当前是中文，那返回是的是'删除'\r\n         * ```\r\n         */\r\n        getLang: function (path) {\r\n            var lang = UE.I18N[this.options.lang];\r\n            if (!lang) {\r\n                throw Error(\"not import language file\");\r\n            }\r\n            path = (path || \"\").split(\".\");\r\n            for (var i = 0, ci; ci = path[i++];) {\r\n                lang = lang[ci];\r\n                if (!lang)break;\r\n            }\r\n            return lang;\r\n        },\r\n\r\n        /**\r\n         * 计算编辑器html内容字符串的长度\r\n         * @method  getContentLength\r\n         * @return { Number } 返回计算的长度\r\n         * @example\r\n         * ```javascript\r\n         * //编辑器html内容<p><strong>132</strong></p>\r\n         * editor.getContentLength() //返回27\r\n         * ```\r\n         */\r\n        /**\r\n         * 计算编辑器当前纯文本内容的长度\r\n         * @method  getContentLength\r\n         * @param { Boolean } ingoneHtml 传入true时，只按照纯文本来计算\r\n         * @return { Number } 返回计算的长度，内容中有hr/img/iframe标签，长度加1\r\n         * @example\r\n         * ```javascript\r\n         * //编辑器html内容<p><strong>132</strong></p>\r\n         * editor.getContentLength() //返回3\r\n         * ```\r\n         */\r\n        getContentLength: function (ingoneHtml, tagNames) {\r\n            var count = this.getContent(false,false,true).length;\r\n            if (ingoneHtml) {\r\n                tagNames = (tagNames || []).concat([ 'hr', 'img', 'iframe']);\r\n                count = this.getContentTxt().replace(/[\\t\\r\\n]+/g, '').length;\r\n                for (var i = 0, ci; ci = tagNames[i++];) {\r\n                    count += this.document.getElementsByTagName(ci).length;\r\n                }\r\n            }\r\n            return count;\r\n        },\r\n\r\n        /**\r\n         * 注册输入过滤规则\r\n         * @method  addInputRule\r\n         * @param { Function } rule 要添加的过滤规则\r\n         * @example\r\n         * ```javascript\r\n         * editor.addInputRule(function(root){\r\n         *   $.each(root.getNodesByTagName('div'),function(i,node){\r\n         *       node.tagName=\"p\";\r\n         *   });\r\n         * });\r\n         * ```\r\n         */\r\n        addInputRule: function (rule) {\r\n            this.inputRules.push(rule);\r\n        },\r\n\r\n        /**\r\n         * 执行注册的过滤规则\r\n         * @method  filterInputRule\r\n         * @param { UE.uNode } root 要过滤的uNode节点\r\n         * @remind 执行editor.setContent方法和执行'inserthtml'命令后，会运行该过滤函数\r\n         * @example\r\n         * ```javascript\r\n         * editor.filterInputRule(editor.body);\r\n         * ```\r\n         * @see UE.Editor:addInputRule\r\n         */\r\n        filterInputRule: function (root) {\r\n            for (var i = 0, ci; ci = this.inputRules[i++];) {\r\n                ci.call(this, root)\r\n            }\r\n        },\r\n\r\n        /**\r\n         * 注册输出过滤规则\r\n         * @method  addOutputRule\r\n         * @param { Function } rule 要添加的过滤规则\r\n         * @example\r\n         * ```javascript\r\n         * editor.addOutputRule(function(root){\r\n         *   $.each(root.getNodesByTagName('p'),function(i,node){\r\n         *       node.tagName=\"div\";\r\n         *   });\r\n         * });\r\n         * ```\r\n         */\r\n        addOutputRule: function (rule) {\r\n            this.outputRules.push(rule)\r\n        },\r\n\r\n        /**\r\n         * 根据输出过滤规则，过滤编辑器内容\r\n         * @method  filterOutputRule\r\n         * @remind 执行editor.getContent方法的时候，会先运行该过滤函数\r\n         * @param { UE.uNode } root 要过滤的uNode节点\r\n         * @example\r\n         * ```javascript\r\n         * editor.filterOutputRule(editor.body);\r\n         * ```\r\n         * @see UE.Editor:addOutputRule\r\n         */\r\n        filterOutputRule: function (root) {\r\n            for (var i = 0, ci; ci = this.outputRules[i++];) {\r\n                ci.call(this, root)\r\n            }\r\n        },\r\n\r\n        /**\r\n         * 根据action名称获取请求的路径\r\n         * @method  getActionUrl\r\n         * @remind 假如没有设置serverUrl,会根据imageUrl设置默认的controller路径\r\n         * @param { String } action action名称\r\n         * @example\r\n         * ```javascript\r\n         * editor.getActionUrl('config'); //返回 \"/ueditor/php/controller.php?action=config\"\r\n         * editor.getActionUrl('image'); //返回 \"/ueditor/php/controller.php?action=uplaodimage\"\r\n         * editor.getActionUrl('scrawl'); //返回 \"/ueditor/php/controller.php?action=uplaodscrawl\"\r\n         * editor.getActionUrl('imageManager'); //返回 \"/ueditor/php/controller.php?action=listimage\"\r\n         * ```\r\n         */\r\n        getActionUrl: function(action){\r\n            var actionName = this.getOpt(action) || action,\r\n                imageUrl = this.getOpt('imageUrl'),\r\n                serverUrl = this.getOpt('serverUrl');\r\n\r\n            if(!serverUrl && imageUrl) {\r\n                serverUrl = imageUrl.replace(/^(.*[\\/]).+([\\.].+)$/, '$1controller$2');\r\n            }\r\n\r\n            if(serverUrl) {\r\n                serverUrl = serverUrl + (serverUrl.indexOf('?') == -1 ? '?':'&') + 'action=' + (actionName || '');\r\n                return utils.formatUrl(serverUrl);\r\n            } else {\r\n                return '';\r\n            }\r\n        }\r\n    };\r\n    utils.inherits(Editor, EventBase);\r\n})();\r\n\n\n// core/Editor.defaultoptions.js\n//维护编辑器一下默认的不在插件中的配置项\nUE.Editor.defaultOptions = function(editor){\n\n    var _url = editor.options.UEDITOR_HOME_URL;\n    return {\n        isShow: true,\n        initialContent: '',\n        initialStyle:'',\n        autoClearinitialContent: false,\n        iframeCssUrl: _url + 'themes/iframe.css',\n        textarea: 'editorValue',\n        focus: false,\n        focusInEnd: true,\n        autoClearEmptyNode: true,\n        fullscreen: false,\n        readonly: false,\n        zIndex: 999,\n        imagePopup: true,\n        enterTag: 'p',\n        customDomain: false,\n        lang: 'zh-cn',\n        langPath: _url + 'lang/',\n        theme: 'default',\n        themePath: _url + 'themes/',\n        allHtmlEnabled: false,\n        scaleEnabled: false,\n        tableNativeEditInFF: false,\n        autoSyncData : true,\n        fileNameFormat: '{time}{rand:6}'\n    }\n};\n\n// core/loadconfig.js\n(function(){\n\n    UE.Editor.prototype.loadServerConfig = function(){\n        var me = this;\n        setTimeout(function(){\n            try{\n                me.options.imageUrl && me.setOpt('serverUrl', me.options.imageUrl.replace(/^(.*[\\/]).+([\\.].+)$/, '$1controller$2'));\n\n                var configUrl = me.getActionUrl('config'),\n                    isJsonp = utils.isCrossDomainUrl(configUrl);\n\n                /* 发出ajax请求 */\n                me._serverConfigLoaded = false;\n\n                configUrl && UE.ajax.request(configUrl,{\n                    'method': 'GET',\n                    'dataType': isJsonp ? 'jsonp':'',\n                    'onsuccess':function(r){\n                        try {\n                            var config = isJsonp ? r:eval(\"(\"+r.responseText+\")\");\n                            utils.extend(me.options, config);\n                            me.fireEvent('serverConfigLoaded');\n                            me._serverConfigLoaded = true;\n                        } catch (e) {\n                            showErrorMsg(me.getLang('loadconfigFormatError'));\n                        }\n                    },\n                    'onerror':function(){\n                        showErrorMsg(me.getLang('loadconfigHttpError'));\n                    }\n                });\n            } catch(e){\n                showErrorMsg(me.getLang('loadconfigError'));\n            }\n        });\n\n        function showErrorMsg(msg) {\n            console && console.error(msg);\n            //me.fireEvent('showMessage', {\n            //    'title': msg,\n            //    'type': 'error'\n            //});\n        }\n    };\n\n    UE.Editor.prototype.isServerConfigLoaded = function(){\n        var me = this;\n        return me._serverConfigLoaded || false;\n    };\n\n    UE.Editor.prototype.afterConfigReady = function(handler){\n        if (!handler || !utils.isFunction(handler)) return;\n        var me = this;\n        var readyHandler = function(){\n            handler.apply(me, arguments);\n            me.removeListener('serverConfigLoaded', readyHandler);\n        };\n\n        if (me.isServerConfigLoaded()) {\n            handler.call(me, 'serverConfigLoaded');\n        } else {\n            me.addListener('serverConfigLoaded', readyHandler);\n        }\n    };\n\n})();\n\n\n// core/ajax.js\n/**\r\n * @file\r\n * @module UE.ajax\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 提供对ajax请求的支持\r\n * @module UE.ajax\r\n */\r\nUE.ajax = function() {\r\n\r\n    //创建一个ajaxRequest对象\r\n    var fnStr = 'XMLHttpRequest()';\r\n    try {\r\n        new ActiveXObject(\"Msxml2.XMLHTTP\");\r\n        fnStr = 'ActiveXObject(\\'Msxml2.XMLHTTP\\')';\r\n    } catch (e) {\r\n        try {\r\n            new ActiveXObject(\"Microsoft.XMLHTTP\");\r\n            fnStr = 'ActiveXObject(\\'Microsoft.XMLHTTP\\')'\r\n        } catch (e) {\r\n        }\r\n    }\r\n    var creatAjaxRequest = new Function('return new ' + fnStr);\r\n\r\n\r\n    /**\r\n     * 将json参数转化成适合ajax提交的参数列表\r\n     * @param json\r\n     */\r\n    function json2str(json) {\r\n        var strArr = [];\r\n        for (var i in json) {\r\n            //忽略默认的几个参数\r\n            if(i==\"method\" || i==\"timeout\" || i==\"async\" || i==\"dataType\" || i==\"callback\") continue;\r\n            //忽略控制\r\n            if(json[i] == undefined || json[i] == null) continue;\r\n            //传递过来的对象和函数不在提交之列\r\n            if (!((typeof json[i]).toLowerCase() == \"function\" || (typeof json[i]).toLowerCase() == \"object\")) {\r\n                strArr.push( encodeURIComponent(i) + \"=\"+encodeURIComponent(json[i]) );\r\n            } else if (utils.isArray(json[i])) {\r\n            //支持传数组内容\r\n                for(var j = 0; j < json[i].length; j++) {\r\n                    strArr.push( encodeURIComponent(i) + \"[]=\"+encodeURIComponent(json[i][j]) );\r\n                }\r\n            }\r\n        }\r\n        return strArr.join(\"&\");\r\n    }\r\n\r\n    function doAjax(url, ajaxOptions) {\r\n        var xhr = creatAjaxRequest(),\r\n        //是否超时\r\n            timeIsOut = false,\r\n        //默认参数\r\n            defaultAjaxOptions = {\r\n                method:\"POST\",\r\n                timeout:5000,\r\n                async:true,\r\n                data:{},//需要传递对象的话只能覆盖\r\n                onsuccess:function() {\r\n                },\r\n                onerror:function() {\r\n                }\r\n            };\r\n\r\n        if (typeof url === \"object\") {\r\n            ajaxOptions = url;\r\n            url = ajaxOptions.url;\r\n        }\r\n        if (!xhr || !url) return;\r\n        var ajaxOpts = ajaxOptions ? utils.extend(defaultAjaxOptions,ajaxOptions) : defaultAjaxOptions;\r\n\r\n        var submitStr = json2str(ajaxOpts);  // { name:\"Jim\",city:\"Beijing\" } --> \"name=Jim&city=Beijing\"\r\n        //如果用户直接通过data参数传递json对象过来，则也要将此json对象转化为字符串\r\n        if (!utils.isEmptyObject(ajaxOpts.data)){\r\n            submitStr += (submitStr? \"&\":\"\") + json2str(ajaxOpts.data);\r\n        }\r\n        //超时检测\r\n        var timerID = setTimeout(function() {\r\n            if (xhr.readyState != 4) {\r\n                timeIsOut = true;\r\n                xhr.abort();\r\n                clearTimeout(timerID);\r\n            }\r\n        }, ajaxOpts.timeout);\r\n\r\n        var method = ajaxOpts.method.toUpperCase();\r\n        var str = url + (url.indexOf(\"?\")==-1?\"?\":\"&\") + (method==\"POST\"?\"\":submitStr+ \"&noCache=\" + +new Date);\r\n        xhr.open(method, str, ajaxOpts.async);\r\n        xhr.onreadystatechange = function() {\r\n            if (xhr.readyState == 4) {\r\n                if (!timeIsOut && xhr.status == 200) {\r\n                    ajaxOpts.onsuccess(xhr);\r\n                } else {\r\n                    ajaxOpts.onerror(xhr);\r\n                }\r\n            }\r\n        };\r\n        if (method == \"POST\") {\r\n            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');\r\n            xhr.send(submitStr);\r\n        } else {\r\n            xhr.send(null);\r\n        }\r\n    }\r\n\r\n    function doJsonp(url, opts) {\r\n\r\n        var successhandler = opts.onsuccess || function(){},\r\n            scr = document.createElement('SCRIPT'),\r\n            options = opts || {},\r\n            charset = options['charset'],\r\n            callbackField = options['jsonp'] || 'callback',\r\n            callbackFnName,\r\n            timeOut = options['timeOut'] || 0,\r\n            timer,\r\n            reg = new RegExp('(\\\\?|&)' + callbackField + '=([^&]*)'),\r\n            matches;\r\n\r\n        if (utils.isFunction(successhandler)) {\r\n            callbackFnName = 'bd__editor__' + Math.floor(Math.random() * 2147483648).toString(36);\r\n            window[callbackFnName] = getCallBack(0);\r\n        } else if(utils.isString(successhandler)){\r\n            callbackFnName = successhandler;\r\n        } else {\r\n            if (matches = reg.exec(url)) {\r\n                callbackFnName = matches[2];\r\n            }\r\n        }\r\n\r\n        url = url.replace(reg, '\\x241' + callbackField + '=' + callbackFnName);\r\n\r\n        if (url.search(reg) < 0) {\r\n            url += (url.indexOf('?') < 0 ? '?' : '&') + callbackField + '=' + callbackFnName;\r\n        }\r\n\r\n        var queryStr = json2str(opts);  // { name:\"Jim\",city:\"Beijing\" } --> \"name=Jim&city=Beijing\"\r\n        //如果用户直接通过data参数传递json对象过来，则也要将此json对象转化为字符串\r\n        if (!utils.isEmptyObject(opts.data)){\r\n            queryStr += (queryStr? \"&\":\"\") + json2str(opts.data);\r\n        }\r\n        if (queryStr) {\r\n            url = url.replace(/\\?/, '?' + queryStr + '&');\r\n        }\r\n\r\n        scr.onerror = getCallBack(1);\r\n        if( timeOut ){\r\n            timer = setTimeout(getCallBack(1), timeOut);\r\n        }\r\n        createScriptTag(scr, url, charset);\r\n\r\n        function createScriptTag(scr, url, charset) {\r\n            scr.setAttribute('type', 'text/javascript');\r\n            scr.setAttribute('defer', 'defer');\r\n            charset && scr.setAttribute('charset', charset);\r\n            scr.setAttribute('src', url);\r\n            document.getElementsByTagName('head')[0].appendChild(scr);\r\n        }\r\n\r\n        function getCallBack(onTimeOut){\r\n            return function(){\r\n                try {\r\n                    if(onTimeOut){\r\n                        options.onerror && options.onerror();\r\n                    }else{\r\n                        try{\r\n                            clearTimeout(timer);\r\n                            successhandler.apply(window, arguments);\r\n                        } catch (e){}\r\n                    }\r\n                } catch (exception) {\r\n                    options.onerror && options.onerror.call(window, exception);\r\n                } finally {\r\n                    options.oncomplete && options.oncomplete.apply(window, arguments);\r\n                    scr.parentNode && scr.parentNode.removeChild(scr);\r\n                    window[callbackFnName] = null;\r\n                    try {\r\n                        delete window[callbackFnName];\r\n                    }catch(e){}\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    return {\r\n        /**\r\n         * 根据给定的参数项，向指定的url发起一个ajax请求。 ajax请求完成后，会根据请求结果调用相应回调： 如果请求\r\n         * 成功， 则调用onsuccess回调， 失败则调用 onerror 回调\r\n         * @method request\r\n         * @param { URLString } url ajax请求的url地址\r\n         * @param { Object } ajaxOptions ajax请求选项的键值对，支持的选项如下：\r\n         * @example\r\n         * ```javascript\r\n         * //向sayhello.php发起一个异步的Ajax GET请求, 请求超时时间为10s， 请求完成后执行相应的回调。\r\n         * UE.ajax.requeset( 'sayhello.php', {\r\n         *\r\n         *     //请求方法。可选值： 'GET', 'POST'，默认值是'POST'\r\n         *     method: 'GET',\r\n         *\r\n         *     //超时时间。 默认为5000， 单位是ms\r\n         *     timeout: 10000,\r\n         *\r\n         *     //是否是异步请求。 true为异步请求， false为同步请求\r\n         *     async: true,\r\n         *\r\n         *     //请求携带的数据。如果请求为GET请求， data会经过stringify后附加到请求url之后。\r\n         *     data: {\r\n         *         name: 'ueditor'\r\n         *     },\r\n         *\r\n         *     //请求成功后的回调， 该回调接受当前的XMLHttpRequest对象作为参数。\r\n         *     onsuccess: function ( xhr ) {\r\n         *         console.log( xhr.responseText );\r\n         *     },\r\n         *\r\n         *     //请求失败或者超时后的回调。\r\n         *     onerror: function ( xhr ) {\r\n         *          alert( 'Ajax请求失败' );\r\n         *     }\r\n         *\r\n         * } );\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 根据给定的参数项发起一个ajax请求， 参数项里必须包含一个url地址。 ajax请求完成后，会根据请求结果调用相应回调： 如果请求\r\n         * 成功， 则调用onsuccess回调， 失败则调用 onerror 回调。\r\n         * @method request\r\n         * @warning 如果在参数项里未提供一个key为“url”的地址值，则该请求将直接退出。\r\n         * @param { Object } ajaxOptions ajax请求选项的键值对，支持的选项如下：\r\n         * @example\r\n         * ```javascript\r\n         *\r\n         * //向sayhello.php发起一个异步的Ajax POST请求, 请求超时时间为5s， 请求完成后不执行任何回调。\r\n         * UE.ajax.requeset( 'sayhello.php', {\r\n         *\r\n         *     //请求的地址， 该项是必须的。\r\n         *     url: 'sayhello.php'\r\n         *\r\n         * } );\r\n         * ```\r\n         */\r\n\t\trequest:function(url, opts) {\r\n            if (opts && opts.dataType == 'jsonp') {\r\n                doJsonp(url, opts);\r\n            } else {\r\n                doAjax(url, opts);\r\n            }\r\n\t\t},\r\n        getJSONP:function(url, data, fn) {\r\n            var opts = {\r\n                'data': data,\r\n                'oncomplete': fn\r\n            };\r\n            doJsonp(url, opts);\r\n\t\t}\r\n\t};\r\n\r\n\r\n}();\r\n\n\n// core/filterword.js\n/**\r\n * UE过滤word的静态方法\r\n * @file\r\n */\r\n\r\n/**\r\n * UEditor公用空间，UEditor所有的功能都挂载在该空间下\r\n * @module UE\r\n */\r\n\r\n\r\n/**\r\n * 根据传入html字符串过滤word\r\n * @module UE\r\n * @since 1.2.6.1\r\n * @method filterWord\r\n * @param { String } html html字符串\r\n * @return { String } 已过滤后的结果字符串\r\n * @example\r\n * ```javascript\r\n * UE.filterWord(html);\r\n * ```\r\n */\r\nvar filterWord = UE.filterWord = function () {\r\n\r\n    //是否是word过来的内容\r\n    function isWordDocument( str ) {\r\n        return /(class=\"?Mso|style=\"[^\"]*\\bmso\\-|w:WordDocument|<(v|o):|lang=)/ig.test( str );\r\n    }\r\n    //去掉小数\r\n    function transUnit( v ) {\r\n        v = v.replace( /[\\d.]+\\w+/g, function ( m ) {\r\n            return utils.transUnitToPx(m);\r\n        } );\r\n        return v;\r\n    }\r\n\r\n    function filterPasteWord( str ) {\r\n        return str.replace(/[\\t\\r\\n]+/g,' ')\r\n                .replace( /<!--[\\s\\S]*?-->/ig, \"\" )\r\n                //转换图片\r\n                .replace(/<v:shape [^>]*>[\\s\\S]*?.<\\/v:shape>/gi,function(str){\r\n                    //opera能自己解析出image所这里直接返回空\r\n                    if(browser.opera){\r\n                        return '';\r\n                    }\r\n                    try{\r\n                        //有可能是bitmap占为图，无用，直接过滤掉，主要体现在粘贴excel表格中\r\n                        if(/Bitmap/i.test(str)){\r\n                            return '';\r\n                        }\r\n                        var width = str.match(/width:([ \\d.]*p[tx])/i)[1],\r\n                            height = str.match(/height:([ \\d.]*p[tx])/i)[1],\r\n                            src =  str.match(/src=\\s*\"([^\"]*)\"/i)[1];\r\n                        return '<img width=\"'+ transUnit(width) +'\" height=\"'+transUnit(height) +'\" src=\"' + src + '\" />';\r\n                    } catch(e){\r\n                        return '';\r\n                    }\r\n                })\r\n                //针对wps添加的多余标签处理\r\n                .replace(/<\\/?div[^>]*>/g,'')\r\n                //去掉多余的属性\r\n                .replace( /v:\\w+=([\"']?)[^'\"]+\\1/g, '' )\r\n                .replace( /<(!|script[^>]*>.*?<\\/script(?=[>\\s])|\\/?(\\?xml(:\\w+)?|xml|meta|link|style|\\w+:\\w+)(?=[\\s\\/>]))[^>]*>/gi, \"\" )\r\n                .replace( /<p [^>]*class=\"?MsoHeading\"?[^>]*>(.*?)<\\/p>/gi, \"<p><strong>$1</strong></p>\" )\r\n                //去掉多余的属性\r\n                .replace( /\\s+(class|lang|align)\\s*=\\s*(['\"]?)([\\w-]+)\\2/ig, function(str,name,marks,val){\r\n                    //保留list的标示\r\n                    return name == 'class' && val == 'MsoListParagraph' ? str : ''\r\n                })\r\n                //清除多余的font/span不能匹配&nbsp;有可能是空格\r\n                .replace( /<(font|span)[^>]*>(\\s*)<\\/\\1>/gi, function(a,b,c){\r\n                    return c.replace(/[\\t\\r\\n ]+/g,' ')\r\n                })\r\n                //处理style的问题\r\n                .replace( /(<[a-z][^>]*)\\sstyle=([\"'])([^\\2]*?)\\2/gi, function( str, tag, tmp, style ) {\r\n                    var n = [],\r\n                        s = style.replace( /^\\s+|\\s+$/, '' )\r\n                            .replace(/&#39;/g,'\\'')\r\n                            .replace( /&quot;/gi, \"'\" )\r\n                            .replace(/[\\d.]+(cm|pt)/g,function(str){\r\n                                return utils.transUnitToPx(str)\r\n                            })\r\n                            .split( /;\\s*/g );\r\n\r\n                    for ( var i = 0,v; v = s[i];i++ ) {\r\n\r\n                        var name, value,\r\n                            parts = v.split( \":\" );\r\n\r\n                        if ( parts.length == 2 ) {\r\n                            name = parts[0].toLowerCase();\r\n                            value = parts[1].toLowerCase();\r\n                            if(/^(background)\\w*/.test(name) && value.replace(/(initial|\\s)/g,'').length == 0\r\n                                ||\r\n                                /^(margin)\\w*/.test(name) && /^0\\w+$/.test(value)\r\n                            ){\r\n                                continue;\r\n                            }\r\n\r\n                            switch ( name ) {\r\n                                case \"mso-padding-alt\":\r\n                                case \"mso-padding-top-alt\":\r\n                                case \"mso-padding-right-alt\":\r\n                                case \"mso-padding-bottom-alt\":\r\n                                case \"mso-padding-left-alt\":\r\n                                case \"mso-margin-alt\":\r\n                                case \"mso-margin-top-alt\":\r\n                                case \"mso-margin-right-alt\":\r\n                                case \"mso-margin-bottom-alt\":\r\n                                case \"mso-margin-left-alt\":\r\n                                //ie下会出现挤到一起的情况\r\n                               //case \"mso-table-layout-alt\":\r\n                                case \"mso-height\":\r\n                                case \"mso-width\":\r\n                                case \"mso-vertical-align-alt\":\r\n                                    //trace:1819 ff下会解析出padding在table上\r\n                                    if(!/<table/.test(tag))\r\n                                        n[i] = name.replace( /^mso-|-alt$/g, \"\" ) + \":\" + transUnit( value );\r\n                                    continue;\r\n                                case \"horiz-align\":\r\n                                    n[i] = \"text-align:\" + value;\r\n                                    continue;\r\n\r\n                                case \"vert-align\":\r\n                                    n[i] = \"vertical-align:\" + value;\r\n                                    continue;\r\n\r\n                                case \"font-color\":\r\n                                case \"mso-foreground\":\r\n                                    n[i] = \"color:\" + value;\r\n                                    continue;\r\n\r\n                                case \"mso-background\":\r\n                                case \"mso-highlight\":\r\n                                    n[i] = \"background:\" + value;\r\n                                    continue;\r\n\r\n                                case \"mso-default-height\":\r\n                                    n[i] = \"min-height:\" + transUnit( value );\r\n                                    continue;\r\n\r\n                                case \"mso-default-width\":\r\n                                    n[i] = \"min-width:\" + transUnit( value );\r\n                                    continue;\r\n\r\n                                case \"mso-padding-between-alt\":\r\n                                    n[i] = \"border-collapse:separate;border-spacing:\" + transUnit( value );\r\n                                    continue;\r\n\r\n                                case \"text-line-through\":\r\n                                    if ( (value == \"single\") || (value == \"double\") ) {\r\n                                        n[i] = \"text-decoration:line-through\";\r\n                                    }\r\n                                    continue;\r\n                                case \"mso-zero-height\":\r\n                                    if ( value == \"yes\" ) {\r\n                                        n[i] = \"display:none\";\r\n                                    }\r\n                                    continue;\r\n//                                case 'background':\r\n//                                    break;\r\n                                case 'margin':\r\n                                    if ( !/[1-9]/.test( value ) ) {\r\n                                        continue;\r\n                                    }\r\n\r\n                            }\r\n\r\n                            if ( /^(mso|column|font-emph|lang|layout|line-break|list-image|nav|panose|punct|row|ruby|sep|size|src|tab-|table-border|text-(?:decor|trans)|top-bar|version|vnd|word-break)/.test( name )\r\n                                ||\r\n                                /text\\-indent|padding|margin/.test(name) && /\\-[\\d.]+/.test(value)\r\n                            ) {\r\n                                continue;\r\n                            }\r\n\r\n                            n[i] = name + \":\" + parts[1];\r\n                        }\r\n                    }\r\n                    return tag + (n.length ? ' style=\"' + n.join( ';').replace(/;{2,}/g,';') + '\"' : '');\r\n                })\r\n\r\n\r\n    }\r\n\r\n    return function ( html ) {\r\n        return (isWordDocument( html ) ? filterPasteWord( html ) : html);\r\n    };\r\n}();\n\n// core/node.js\n/**\n * 编辑器模拟的节点类\n * @file\n * @module UE\n * @class uNode\n * @since 1.2.6.1\n */\n\n/**\n * UEditor公用空间，UEditor所有的功能都挂载在该空间下\n * @unfile\n * @module UE\n */\n\n(function () {\n\n    /**\n     * 编辑器模拟的节点类\n     * @unfile\n     * @module UE\n     * @class uNode\n     */\n\n    /**\n     * 通过一个键值对，创建一个uNode对象\n     * @constructor\n     * @param { Object } attr 传入要创建的uNode的初始属性\n     * @example\n     * ```javascript\n     * var node = new uNode({\n     *     type:'element',\n     *     tagName:'span',\n     *     attrs:{style:'font-size:14px;'}\n     * }\n     * ```\n     */\n    var uNode = UE.uNode = function (obj) {\n        this.type = obj.type;\n        this.data = obj.data;\n        this.tagName = obj.tagName;\n        this.parentNode = obj.parentNode;\n        this.attrs = obj.attrs || {};\n        this.children = obj.children;\n    };\n\n    var notTransAttrs = {\n        'href':1,\n        'src':1,\n        '_src':1,\n        '_href':1,\n        'cdata_data':1\n    };\n\n    var notTransTagName = {\n        style:1,\n        script:1\n    };\n\n    var indentChar = '    ',\n        breakChar = '\\n';\n\n    function insertLine(arr, current, begin) {\n        arr.push(breakChar);\n        return current + (begin ? 1 : -1);\n    }\n\n    function insertIndent(arr, current) {\n        //插入缩进\n        for (var i = 0; i < current; i++) {\n            arr.push(indentChar);\n        }\n    }\n\n    //创建uNode的静态方法\n    //支持标签和html\n    uNode.createElement = function (html) {\n        if (/[<>]/.test(html)) {\n            return UE.htmlparser(html).children[0]\n        } else {\n            return new uNode({\n                type:'element',\n                children:[],\n                tagName:html\n            })\n        }\n    };\n    uNode.createText = function (data,noTrans) {\n        return new UE.uNode({\n            type:'text',\n            'data':noTrans ? data : utils.unhtml(data || '')\n        })\n    };\n    function nodeToHtml(node, arr, formatter, current) {\n        switch (node.type) {\n            case 'root':\n                for (var i = 0, ci; ci = node.children[i++];) {\n                    //插入新行\n                    if (formatter && ci.type == 'element' && !dtd.$inlineWithA[ci.tagName] && i > 1) {\n                        insertLine(arr, current, true);\n                        insertIndent(arr, current)\n                    }\n                    nodeToHtml(ci, arr, formatter, current)\n                }\n                break;\n            case 'text':\n                isText(node, arr);\n                break;\n            case 'element':\n                isElement(node, arr, formatter, current);\n                break;\n            case 'comment':\n                isComment(node, arr, formatter);\n        }\n        return arr;\n    }\n\n    function isText(node, arr) {\n        if(node.parentNode.tagName == 'pre'){\n            //源码模式下输入html标签，不能做转换处理，直接输出\n            arr.push(node.data)\n        }else{\n            arr.push(notTransTagName[node.parentNode.tagName] ? utils.html(node.data) : node.data.replace(/[ ]{2}/g,' &nbsp;'))\n        }\n\n    }\n\n    function isElement(node, arr, formatter, current) {\n        var attrhtml = '';\n        if (node.attrs) {\n            attrhtml = [];\n            var attrs = node.attrs;\n            for (var a in attrs) {\n                //这里就针对\n                //<p>'<img src='http://nsclick.baidu.com/u.gif?&asdf=\\\"sdf&asdfasdfs;asdf'></p>\n                //这里边的\\\"做转换，要不用innerHTML直接被截断了，属性src\n                //有可能做的不够\n                attrhtml.push(a + (attrs[a] !== undefined ? '=\"' + (notTransAttrs[a] ? utils.html(attrs[a]).replace(/[\"]/g, function (a) {\n                   return '&quot;'\n                }) : utils.unhtml(attrs[a])) + '\"' : ''))\n            }\n            attrhtml = attrhtml.join(' ');\n        }\n        arr.push('<' + node.tagName +\n            (attrhtml ? ' ' + attrhtml  : '') +\n            (dtd.$empty[node.tagName] ? '\\/' : '' ) + '>'\n        );\n        //插入新行\n        if (formatter  &&  !dtd.$inlineWithA[node.tagName] && node.tagName != 'pre') {\n            if(node.children && node.children.length){\n                current = insertLine(arr, current, true);\n                insertIndent(arr, current)\n            }\n\n        }\n        if (node.children && node.children.length) {\n            for (var i = 0, ci; ci = node.children[i++];) {\n                if (formatter && ci.type == 'element' &&  !dtd.$inlineWithA[ci.tagName] && i > 1) {\n                    insertLine(arr, current);\n                    insertIndent(arr, current)\n                }\n                nodeToHtml(ci, arr, formatter, current)\n            }\n        }\n        if (!dtd.$empty[node.tagName]) {\n            if (formatter && !dtd.$inlineWithA[node.tagName]  && node.tagName != 'pre') {\n\n                if(node.children && node.children.length){\n                    current = insertLine(arr, current);\n                    insertIndent(arr, current)\n                }\n            }\n            arr.push('<\\/' + node.tagName + '>');\n        }\n\n    }\n\n    function isComment(node, arr) {\n        arr.push('<!--' + node.data + '-->');\n    }\n\n    function getNodeById(root, id) {\n        var node;\n        if (root.type == 'element' && root.getAttr('id') == id) {\n            return root;\n        }\n        if (root.children && root.children.length) {\n            for (var i = 0, ci; ci = root.children[i++];) {\n                if (node = getNodeById(ci, id)) {\n                    return node;\n                }\n            }\n        }\n    }\n\n    function getNodesByTagName(node, tagName, arr) {\n        if (node.type == 'element' && node.tagName == tagName) {\n            arr.push(node);\n        }\n        if (node.children && node.children.length) {\n            for (var i = 0, ci; ci = node.children[i++];) {\n                getNodesByTagName(ci, tagName, arr)\n            }\n        }\n    }\n    function nodeTraversal(root,fn){\n        if(root.children && root.children.length){\n            for(var i= 0,ci;ci=root.children[i];){\n                nodeTraversal(ci,fn);\n                //ci被替换的情况，这里就不再走 fn了\n                if(ci.parentNode ){\n                    if(ci.children && ci.children.length){\n                        fn(ci)\n                    }\n                    if(ci.parentNode) i++\n                }\n            }\n        }else{\n            fn(root)\n        }\n\n    }\n    uNode.prototype = {\n\n        /**\n         * 当前节点对象，转换成html文本\n         * @method toHtml\n         * @return { String } 返回转换后的html字符串\n         * @example\n         * ```javascript\n         * node.toHtml();\n         * ```\n         */\n\n        /**\n         * 当前节点对象，转换成html文本\n         * @method toHtml\n         * @param { Boolean } formatter 是否格式化返回值\n         * @return { String } 返回转换后的html字符串\n         * @example\n         * ```javascript\n         * node.toHtml( true );\n         * ```\n         */\n        toHtml:function (formatter) {\n            var arr = [];\n            nodeToHtml(this, arr, formatter, 0);\n            return arr.join('')\n        },\n\n        /**\n         * 获取节点的html内容\n         * @method innerHTML\n         * @warning 假如节点的type不是'element'，或节点的标签名称不在dtd列表里，直接返回当前节点\n         * @return { String } 返回节点的html内容\n         * @example\n         * ```javascript\n         * var htmlstr = node.innerHTML();\n         * ```\n         */\n\n        /**\n         * 设置节点的html内容\n         * @method innerHTML\n         * @warning 假如节点的type不是'element'，或节点的标签名称不在dtd列表里，直接返回当前节点\n         * @param { String } htmlstr 传入要设置的html内容\n         * @return { UE.uNode } 返回节点本身\n         * @example\n         * ```javascript\n         * node.innerHTML('<span>text</span>');\n         * ```\n         */\n        innerHTML:function (htmlstr) {\n            if (this.type != 'element' || dtd.$empty[this.tagName]) {\n                return this;\n            }\n            if (utils.isString(htmlstr)) {\n                if(this.children){\n                    for (var i = 0, ci; ci = this.children[i++];) {\n                        ci.parentNode = null;\n                    }\n                }\n                this.children = [];\n                var tmpRoot = UE.htmlparser(htmlstr);\n                for (var i = 0, ci; ci = tmpRoot.children[i++];) {\n                    this.children.push(ci);\n                    ci.parentNode = this;\n                }\n                return this;\n            } else {\n                var tmpRoot = new UE.uNode({\n                    type:'root',\n                    children:this.children\n                });\n                return tmpRoot.toHtml();\n            }\n        },\n\n        /**\n         * 获取节点的纯文本内容\n         * @method innerText\n         * @warning 假如节点的type不是'element'，或节点的标签名称不在dtd列表里，直接返回当前节点\n         * @return { String } 返回节点的存文本内容\n         * @example\n         * ```javascript\n         * var textStr = node.innerText();\n         * ```\n         */\n\n        /**\n         * 设置节点的纯文本内容\n         * @method innerText\n         * @warning 假如节点的type不是'element'，或节点的标签名称不在dtd列表里，直接返回当前节点\n         * @param { String } textStr 传入要设置的文本内容\n         * @return { UE.uNode } 返回节点本身\n         * @example\n         * ```javascript\n         * node.innerText('<span>text</span>');\n         * ```\n         */\n        innerText:function (textStr,noTrans) {\n            if (this.type != 'element' || dtd.$empty[this.tagName]) {\n                return this;\n            }\n            if (textStr) {\n                if(this.children){\n                    for (var i = 0, ci; ci = this.children[i++];) {\n                        ci.parentNode = null;\n                    }\n                }\n                this.children = [];\n                this.appendChild(uNode.createText(textStr,noTrans));\n                return this;\n            } else {\n                return this.toHtml().replace(/<[^>]+>/g, '');\n            }\n        },\n\n        /**\n         * 获取当前对象的data属性\n         * @method getData\n         * @return { Object } 若节点的type值是elemenet，返回空字符串，否则返回节点的data属性\n         * @example\n         * ```javascript\n         * node.getData();\n         * ```\n         */\n        getData:function () {\n            if (this.type == 'element')\n                return '';\n            return this.data\n        },\n\n        /**\n         * 获取当前节点下的第一个子节点\n         * @method firstChild\n         * @return { UE.uNode } 返回第一个子节点\n         * @example\n         * ```javascript\n         * node.firstChild(); //返回第一个子节点\n         * ```\n         */\n        firstChild:function () {\n//            if (this.type != 'element' || dtd.$empty[this.tagName]) {\n//                return this;\n//            }\n            return this.children ? this.children[0] : null;\n        },\n\n        /**\n         * 获取当前节点下的最后一个子节点\n         * @method lastChild\n         * @return { UE.uNode } 返回最后一个子节点\n         * @example\n         * ```javascript\n         * node.lastChild(); //返回最后一个子节点\n         * ```\n         */\n        lastChild:function () {\n//            if (this.type != 'element' || dtd.$empty[this.tagName] ) {\n//                return this;\n//            }\n            return this.children ? this.children[this.children.length - 1] : null;\n        },\n\n        /**\n         * 获取和当前节点有相同父亲节点的前一个节点\n         * @method previousSibling\n         * @return { UE.uNode } 返回前一个节点\n         * @example\n         * ```javascript\n         * node.children[2].previousSibling(); //返回子节点node.children[1]\n         * ```\n         */\n        previousSibling : function(){\n            var parent = this.parentNode;\n            for (var i = 0, ci; ci = parent.children[i]; i++) {\n                if (ci === this) {\n                   return i == 0 ? null : parent.children[i-1];\n                }\n            }\n\n        },\n\n        /**\n         * 获取和当前节点有相同父亲节点的后一个节点\n         * @method nextSibling\n         * @return { UE.uNode } 返回后一个节点,找不到返回null\n         * @example\n         * ```javascript\n         * node.children[2].nextSibling(); //如果有，返回子节点node.children[3]\n         * ```\n         */\n        nextSibling : function(){\n            var parent = this.parentNode;\n            for (var i = 0, ci; ci = parent.children[i++];) {\n                if (ci === this) {\n                    return parent.children[i];\n                }\n            }\n        },\n\n        /**\n         * 用新的节点替换当前节点\n         * @method replaceChild\n         * @param { UE.uNode } target 要替换成该节点参数\n         * @param { UE.uNode } source 要被替换掉的节点\n         * @return { UE.uNode } 返回替换之后的节点对象\n         * @example\n         * ```javascript\n         * node.replaceChild(newNode, childNode); //用newNode替换childNode,childNode是node的子节点\n         * ```\n         */\n        replaceChild:function (target, source) {\n            if (this.children) {\n                if(target.parentNode){\n                    target.parentNode.removeChild(target);\n                }\n                for (var i = 0, ci; ci = this.children[i]; i++) {\n                    if (ci === source) {\n                        this.children.splice(i, 1, target);\n                        source.parentNode = null;\n                        target.parentNode = this;\n                        return target;\n                    }\n                }\n            }\n        },\n\n        /**\n         * 在节点的子节点列表最后位置插入一个节点\n         * @method appendChild\n         * @param { UE.uNode } node 要插入的节点\n         * @return { UE.uNode } 返回刚插入的子节点\n         * @example\n         * ```javascript\n         * node.appendChild( newNode ); //在node内插入子节点newNode\n         * ```\n         */\n        appendChild:function (node) {\n            if (this.type == 'root' || (this.type == 'element' && !dtd.$empty[this.tagName])) {\n                if (!this.children) {\n                    this.children = []\n                }\n                if(node.parentNode){\n                    node.parentNode.removeChild(node);\n                }\n                for (var i = 0, ci; ci = this.children[i]; i++) {\n                    if (ci === node) {\n                        this.children.splice(i, 1);\n                        break;\n                    }\n                }\n                this.children.push(node);\n                node.parentNode = this;\n                return node;\n            }\n\n\n        },\n\n        /**\n         * 在传入节点的前面插入一个节点\n         * @method insertBefore\n         * @param { UE.uNode } target 要插入的节点\n         * @param { UE.uNode } source 在该参数节点前面插入\n         * @return { UE.uNode } 返回刚插入的子节点\n         * @example\n         * ```javascript\n         * node.parentNode.insertBefore(newNode, node); //在node节点后面插入newNode\n         * ```\n         */\n        insertBefore:function (target, source) {\n            if (this.children) {\n                if(target.parentNode){\n                    target.parentNode.removeChild(target);\n                }\n                for (var i = 0, ci; ci = this.children[i]; i++) {\n                    if (ci === source) {\n                        this.children.splice(i, 0, target);\n                        target.parentNode = this;\n                        return target;\n                    }\n                }\n\n            }\n        },\n\n        /**\n         * 在传入节点的后面插入一个节点\n         * @method insertAfter\n         * @param { UE.uNode } target 要插入的节点\n         * @param { UE.uNode } source 在该参数节点后面插入\n         * @return { UE.uNode } 返回刚插入的子节点\n         * @example\n         * ```javascript\n         * node.parentNode.insertAfter(newNode, node); //在node节点后面插入newNode\n         * ```\n         */\n        insertAfter:function (target, source) {\n            if (this.children) {\n                if(target.parentNode){\n                    target.parentNode.removeChild(target);\n                }\n                for (var i = 0, ci; ci = this.children[i]; i++) {\n                    if (ci === source) {\n                        this.children.splice(i + 1, 0, target);\n                        target.parentNode = this;\n                        return target;\n                    }\n\n                }\n            }\n        },\n\n        /**\n         * 从当前节点的子节点列表中，移除节点\n         * @method removeChild\n         * @param { UE.uNode } node 要移除的节点引用\n         * @param { Boolean } keepChildren 是否保留移除节点的子节点，若传入true，自动把移除节点的子节点插入到移除的位置\n         * @return { * } 返回刚移除的子节点\n         * @example\n         * ```javascript\n         * node.removeChild(childNode,true); //在node的子节点列表中移除child节点，并且吧child的子节点插入到移除的位置\n         * ```\n         */\n        removeChild:function (node,keepChildren) {\n            if (this.children) {\n                for (var i = 0, ci; ci = this.children[i]; i++) {\n                    if (ci === node) {\n                        this.children.splice(i, 1);\n                        ci.parentNode = null;\n                        if(keepChildren && ci.children && ci.children.length){\n                            for(var j= 0,cj;cj=ci.children[j];j++){\n                                this.children.splice(i+j,0,cj);\n                                cj.parentNode = this;\n\n                            }\n                        }\n                        return ci;\n                    }\n                }\n            }\n        },\n\n        /**\n         * 获取当前节点所代表的元素属性，即获取attrs对象下的属性值\n         * @method getAttr\n         * @param { String } attrName 要获取的属性名称\n         * @return { * } 返回attrs对象下的属性值\n         * @example\n         * ```javascript\n         * node.getAttr('title');\n         * ```\n         */\n        getAttr:function (attrName) {\n            return this.attrs && this.attrs[attrName.toLowerCase()]\n        },\n\n        /**\n         * 设置当前节点所代表的元素属性，即设置attrs对象下的属性值\n         * @method setAttr\n         * @param { String } attrName 要设置的属性名称\n         * @param { * } attrVal 要设置的属性值，类型视设置的属性而定\n         * @return { * } 返回attrs对象下的属性值\n         * @example\n         * ```javascript\n         * node.setAttr('title','标题');\n         * ```\n         */\n        setAttr:function (attrName, attrVal) {\n            if (!attrName) {\n                delete this.attrs;\n                return;\n            }\n            if(!this.attrs){\n                this.attrs = {};\n            }\n            if (utils.isObject(attrName)) {\n                for (var a in attrName) {\n                    if (!attrName[a]) {\n                        delete this.attrs[a]\n                    } else {\n                        this.attrs[a.toLowerCase()] = attrName[a];\n                    }\n                }\n            } else {\n                if (!attrVal) {\n                    delete this.attrs[attrName]\n                } else {\n                    this.attrs[attrName.toLowerCase()] = attrVal;\n                }\n\n            }\n        },\n\n        /**\n         * 获取当前节点在父节点下的位置索引\n         * @method getIndex\n         * @return { Number } 返回索引数值，如果没有父节点，返回-1\n         * @example\n         * ```javascript\n         * node.getIndex();\n         * ```\n         */\n        getIndex:function(){\n            var parent = this.parentNode;\n            for(var i= 0,ci;ci=parent.children[i];i++){\n                if(ci === this){\n                    return i;\n                }\n            }\n            return -1;\n        },\n\n        /**\n         * 在当前节点下，根据id查找节点\n         * @method getNodeById\n         * @param { String } id 要查找的id\n         * @return { UE.uNode } 返回找到的节点\n         * @example\n         * ```javascript\n         * node.getNodeById('textId');\n         * ```\n         */\n        getNodeById:function (id) {\n            var node;\n            if (this.children && this.children.length) {\n                for (var i = 0, ci; ci = this.children[i++];) {\n                    if (node = getNodeById(ci, id)) {\n                        return node;\n                    }\n                }\n            }\n        },\n\n        /**\n         * 在当前节点下，根据元素名称查找节点列表\n         * @method getNodesByTagName\n         * @param { String } tagNames 要查找的元素名称\n         * @return { Array } 返回找到的节点列表\n         * @example\n         * ```javascript\n         * node.getNodesByTagName('span');\n         * ```\n         */\n        getNodesByTagName:function (tagNames) {\n            tagNames = utils.trim(tagNames).replace(/[ ]{2,}/g, ' ').split(' ');\n            var arr = [], me = this;\n            utils.each(tagNames, function (tagName) {\n                if (me.children && me.children.length) {\n                    for (var i = 0, ci; ci = me.children[i++];) {\n                        getNodesByTagName(ci, tagName, arr)\n                    }\n                }\n            });\n            return arr;\n        },\n\n        /**\n         * 根据样式名称，获取节点的样式值\n         * @method getStyle\n         * @param { String } name 要获取的样式名称\n         * @return { String } 返回样式值\n         * @example\n         * ```javascript\n         * node.getStyle('font-size');\n         * ```\n         */\n        getStyle:function (name) {\n            var cssStyle = this.getAttr('style');\n            if (!cssStyle) {\n                return ''\n            }\n            var reg = new RegExp('(^|;)\\\\s*' + name + ':([^;]+)','i');\n            var match = cssStyle.match(reg);\n            if (match && match[0]) {\n                return match[2]\n            }\n            return '';\n        },\n\n        /**\n         * 给节点设置样式\n         * @method setStyle\n         * @param { String } name 要设置的的样式名称\n         * @param { String } val 要设置的的样值\n         * @example\n         * ```javascript\n         * node.setStyle('font-size', '12px');\n         * ```\n         */\n        setStyle:function (name, val) {\n            function exec(name, val) {\n                var reg = new RegExp('(^|;)\\\\s*' + name + ':([^;]+;?)', 'gi');\n                cssStyle = cssStyle.replace(reg, '$1');\n                if (val) {\n                    cssStyle = name + ':' + utils.unhtml(val) + ';' + cssStyle\n                }\n\n            }\n\n            var cssStyle = this.getAttr('style');\n            if (!cssStyle) {\n                cssStyle = '';\n            }\n            if (utils.isObject(name)) {\n                for (var a in name) {\n                    exec(a, name[a])\n                }\n            } else {\n                exec(name, val)\n            }\n            this.setAttr('style', utils.trim(cssStyle))\n        },\n\n        /**\n         * 传入一个函数，递归遍历当前节点下的所有节点\n         * @method traversal\n         * @param { Function } fn 遍历到节点的时，传入节点作为参数，运行此函数\n         * @example\n         * ```javascript\n         * traversal(node, function(){\n         *     console.log(node.type);\n         * });\n         * ```\n         */\n        traversal:function(fn){\n            if(this.children && this.children.length){\n                nodeTraversal(this,fn);\n            }\n            return this;\n        }\n    }\n})();\n\n\n// core/htmlparser.js\n/**\n * html字符串转换成uNode节点\n * @file\n * @module UE\n * @since 1.2.6.1\n */\n\n/**\n * UEditor公用空间，UEditor所有的功能都挂载在该空间下\n * @unfile\n * @module UE\n */\n\n/**\n * html字符串转换成uNode节点的静态方法\n * @method htmlparser\n * @param { String } htmlstr 要转换的html代码\n * @param { Boolean } ignoreBlank 若设置为true，转换的时候忽略\\n\\r\\t等空白字符\n * @return { uNode } 给定的html片段转换形成的uNode对象\n * @example\n * ```javascript\n * var root = UE.htmlparser('<p><b>htmlparser</b></p>', true);\n * ```\n */\n\nvar htmlparser = UE.htmlparser = function (htmlstr,ignoreBlank) {\n    //todo 原来的方式  [^\"'<>\\/] 有\\/就不能配对上 <TD vAlign=top background=../AAA.JPG> 这样的标签了\n    //先去掉了，加上的原因忘了，这里先记录\n    var re_tag = /<(?:(?:\\/([^>]+)>)|(?:!--([\\S|\\s]*?)-->)|(?:([^\\s\\/<>]+)\\s*((?:(?:\"[^\"]*\")|(?:'[^']*')|[^\"'<>])*)\\/?>))/g,\n        re_attr = /([\\w\\-:.]+)(?:(?:\\s*=\\s*(?:(?:\"([^\"]*)\")|(?:'([^']*)')|([^\\s>]+)))|(?=\\s|$))/g;\n\n    //ie下取得的html可能会有\\n存在，要去掉，在处理replace(/[\\t\\r\\n]*/g,'');代码高量的\\n不能去除\n    var allowEmptyTags = {\n        b:1,code:1,i:1,u:1,strike:1,s:1,tt:1,strong:1,q:1,samp:1,em:1,span:1,\n        sub:1,img:1,sup:1,font:1,big:1,small:1,iframe:1,a:1,br:1,pre:1\n    };\n    htmlstr = htmlstr.replace(new RegExp(domUtils.fillChar, 'g'), '');\n    if(!ignoreBlank){\n        htmlstr = htmlstr.replace(new RegExp('[\\\\r\\\\t\\\\n'+(ignoreBlank?'':' ')+']*<\\/?(\\\\w+)\\\\s*(?:[^>]*)>[\\\\r\\\\t\\\\n'+(ignoreBlank?'':' ')+']*','g'), function(a,b){\n            //br暂时单独处理\n            if(b && allowEmptyTags[b.toLowerCase()]){\n                return a.replace(/(^[\\n\\r]+)|([\\n\\r]+$)/g,'');\n            }\n            return a.replace(new RegExp('^[\\\\r\\\\n'+(ignoreBlank?'':' ')+']+'),'').replace(new RegExp('[\\\\r\\\\n'+(ignoreBlank?'':' ')+']+$'),'');\n        });\n    }\n\n    var notTransAttrs = {\n        'href':1,\n        'src':1\n    };\n\n    var uNode = UE.uNode,\n        needParentNode = {\n            'td':'tr',\n            'tr':['tbody','thead','tfoot'],\n            'tbody':'table',\n            'th':'tr',\n            'thead':'table',\n            'tfoot':'table',\n            'caption':'table',\n            'li':['ul', 'ol'],\n            'dt':'dl',\n            'dd':'dl',\n            'option':'select'\n        },\n        needChild = {\n            'ol':'li',\n            'ul':'li'\n        };\n\n    function text(parent, data) {\n\n        if(needChild[parent.tagName]){\n            var tmpNode = uNode.createElement(needChild[parent.tagName]);\n            parent.appendChild(tmpNode);\n            tmpNode.appendChild(uNode.createText(data));\n            parent = tmpNode;\n        }else{\n\n            parent.appendChild(uNode.createText(data));\n        }\n    }\n\n    function element(parent, tagName, htmlattr) {\n        var needParentTag;\n        if (needParentTag = needParentNode[tagName]) {\n            var tmpParent = parent,hasParent;\n            while(tmpParent.type != 'root'){\n                if(utils.isArray(needParentTag) ? utils.indexOf(needParentTag, tmpParent.tagName) != -1 : needParentTag == tmpParent.tagName){\n                    parent = tmpParent;\n                    hasParent = true;\n                    break;\n                }\n                tmpParent = tmpParent.parentNode;\n            }\n            if(!hasParent){\n                parent = element(parent, utils.isArray(needParentTag) ? needParentTag[0] : needParentTag)\n            }\n        }\n        //按dtd处理嵌套\n//        if(parent.type != 'root' && !dtd[parent.tagName][tagName])\n//            parent = parent.parentNode;\n        var elm = new uNode({\n            parentNode:parent,\n            type:'element',\n            tagName:tagName.toLowerCase(),\n            //是自闭合的处理一下\n            children:dtd.$empty[tagName] ? null : []\n        });\n        //如果属性存在，处理属性\n        if (htmlattr) {\n            var attrs = {}, match;\n            while (match = re_attr.exec(htmlattr)) {\n                attrs[match[1].toLowerCase()] = notTransAttrs[match[1].toLowerCase()] ? (match[2] || match[3] || match[4]) : utils.unhtml(match[2] || match[3] || match[4])\n            }\n            elm.attrs = attrs;\n        }\n        //trace:3970\n//        //如果parent下不能放elm\n//        if(dtd.$inline[parent.tagName] && dtd.$block[elm.tagName] && !dtd[parent.tagName][elm.tagName]){\n//            parent = parent.parentNode;\n//            elm.parentNode = parent;\n//        }\n        parent.children.push(elm);\n        //如果是自闭合节点返回父亲节点\n        return  dtd.$empty[tagName] ? parent : elm\n    }\n\n    function comment(parent, data) {\n        parent.children.push(new uNode({\n            type:'comment',\n            data:data,\n            parentNode:parent\n        }));\n    }\n\n    var match, currentIndex = 0, nextIndex = 0;\n    //设置根节点\n    var root = new uNode({\n        type:'root',\n        children:[]\n    });\n    var currentParent = root;\n\n    while (match = re_tag.exec(htmlstr)) {\n        currentIndex = match.index;\n        try{\n            if (currentIndex > nextIndex) {\n                //text node\n                text(currentParent, htmlstr.slice(nextIndex, currentIndex));\n            }\n            if (match[3]) {\n\n                if(dtd.$cdata[currentParent.tagName]){\n                    text(currentParent, match[0]);\n                }else{\n                    //start tag\n                    currentParent = element(currentParent, match[3].toLowerCase(), match[4]);\n                }\n\n\n            } else if (match[1]) {\n                if(currentParent.type != 'root'){\n                    if(dtd.$cdata[currentParent.tagName] && !dtd.$cdata[match[1]]){\n                        text(currentParent, match[0]);\n                    }else{\n                        var tmpParent = currentParent;\n                        while(currentParent.type == 'element' && currentParent.tagName != match[1].toLowerCase()){\n                            currentParent = currentParent.parentNode;\n                            if(currentParent.type == 'root'){\n                                currentParent = tmpParent;\n                                throw 'break'\n                            }\n                        }\n                        //end tag\n                        currentParent = currentParent.parentNode;\n                    }\n\n                }\n\n            } else if (match[2]) {\n                //comment\n                comment(currentParent, match[2])\n            }\n        }catch(e){}\n\n        nextIndex = re_tag.lastIndex;\n\n    }\n    //如果结束是文本，就有可能丢掉，所以这里手动判断一下\n    //例如 <li>sdfsdfsdf<li>sdfsdfsdfsdf\n    if (nextIndex < htmlstr.length) {\n        text(currentParent, htmlstr.slice(nextIndex));\n    }\n    return root;\n};\n\n\n// core/filternode.js\n/**\r\n * UE过滤节点的静态方法\r\n * @file\r\n */\r\n\r\n/**\r\n * UEditor公用空间，UEditor所有的功能都挂载在该空间下\r\n * @module UE\r\n */\r\n\r\n\r\n/**\r\n * 根据传入节点和过滤规则过滤相应节点\r\n * @module UE\r\n * @since 1.2.6.1\r\n * @method filterNode\r\n * @param { Object } root 指定root节点\r\n * @param { Object } rules 过滤规则json对象\r\n * @example\r\n * ```javascript\r\n * UE.filterNode(root,editor.options.filterRules);\r\n * ```\r\n */\r\nvar filterNode = UE.filterNode = function () {\r\n    function filterNode(node,rules){\r\n        switch (node.type) {\r\n            case 'text':\r\n                break;\r\n            case 'element':\r\n                var val;\r\n                if(val = rules[node.tagName]){\r\n                   if(val === '-'){\r\n                       node.parentNode.removeChild(node)\r\n                   }else if(utils.isFunction(val)){\r\n                       var parentNode = node.parentNode,\r\n                           index = node.getIndex();\r\n                       val(node);\r\n                       if(node.parentNode){\r\n                           if(node.children){\r\n                               for(var i = 0,ci;ci=node.children[i];){\r\n                                   filterNode(ci,rules);\r\n                                   if(ci.parentNode){\r\n                                       i++;\r\n                                   }\r\n                               }\r\n                           }\r\n                       }else{\r\n                           for(var i = index,ci;ci=parentNode.children[i];){\r\n                               filterNode(ci,rules);\r\n                               if(ci.parentNode){\r\n                                   i++;\r\n                               }\r\n                           }\r\n                       }\r\n\r\n\r\n                   }else{\r\n                       var attrs = val['$'];\r\n                       if(attrs && node.attrs){\r\n                           var tmpAttrs = {},tmpVal;\r\n                           for(var a in attrs){\r\n                               tmpVal = node.getAttr(a);\r\n                               //todo 只先对style单独处理\r\n                               if(a == 'style' && utils.isArray(attrs[a])){\r\n                                   var tmpCssStyle = [];\r\n                                   utils.each(attrs[a],function(v){\r\n                                       var tmp;\r\n                                       if(tmp = node.getStyle(v)){\r\n                                           tmpCssStyle.push(v + ':' + tmp);\r\n                                       }\r\n                                   });\r\n                                   tmpVal = tmpCssStyle.join(';')\r\n                               }\r\n                               if(tmpVal){\r\n                                   tmpAttrs[a] = tmpVal;\r\n                               }\r\n\r\n                           }\r\n                           node.attrs = tmpAttrs;\r\n                       }\r\n                       if(node.children){\r\n                           for(var i = 0,ci;ci=node.children[i];){\r\n                               filterNode(ci,rules);\r\n                               if(ci.parentNode){\r\n                                   i++;\r\n                               }\r\n                           }\r\n                       }\r\n                   }\r\n                }else{\r\n                    //如果不在名单里扣出子节点并删除该节点,cdata除外\r\n                    if(dtd.$cdata[node.tagName]){\r\n                        node.parentNode.removeChild(node)\r\n                    }else{\r\n                        var parentNode = node.parentNode,\r\n                            index = node.getIndex();\r\n                        node.parentNode.removeChild(node,true);\r\n                        for(var i = index,ci;ci=parentNode.children[i];){\r\n                            filterNode(ci,rules);\r\n                            if(ci.parentNode){\r\n                                i++;\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n                break;\r\n            case 'comment':\r\n                node.parentNode.removeChild(node)\r\n        }\r\n\r\n    }\r\n    return function(root,rules){\r\n        if(utils.isEmptyObject(rules)){\r\n            return root;\r\n        }\r\n        var val;\r\n        if(val = rules['-']){\r\n            utils.each(val.split(' '),function(k){\r\n                rules[k] = '-'\r\n            })\r\n        }\r\n        for(var i= 0,ci;ci=root.children[i];){\r\n            filterNode(ci,rules);\r\n            if(ci.parentNode){\r\n               i++;\r\n            }\r\n        }\r\n        return root;\r\n    }\r\n}();\n\n// core/plugin.js\n/**\n * Created with JetBrains PhpStorm.\n * User: campaign\n * Date: 10/8/13\n * Time: 6:15 PM\n * To change this template use File | Settings | File Templates.\n */\nUE.plugin = function(){\n    var _plugins = {};\n    return {\n        register : function(pluginName,fn,oldOptionName,afterDisabled){\n            if(oldOptionName && utils.isFunction(oldOptionName)){\n                afterDisabled = oldOptionName;\n                oldOptionName = null\n            }\n            _plugins[pluginName] = {\n                optionName : oldOptionName || pluginName,\n                execFn : fn,\n                //当插件被禁用时执行\n                afterDisabled : afterDisabled\n            }\n        },\n        load : function(editor){\n            utils.each(_plugins,function(plugin){\n                var _export = plugin.execFn.call(editor);\n                if(editor.options[plugin.optionName] !== false){\n                    if(_export){\n                        //后边需要再做扩展\n                        utils.each(_export,function(v,k){\n                            switch(k.toLowerCase()){\n                                case 'shortcutkey':\n                                    editor.addshortcutkey(v);\n                                    break;\n                                case 'bindevents':\n                                    utils.each(v,function(fn,eventName){\n                                        editor.addListener(eventName,fn);\n                                    });\n                                    break;\n                                case 'bindmultievents':\n                                    utils.each(utils.isArray(v) ? v:[v],function(event){\n                                        var types = utils.trim(event.type).split(/\\s+/);\n                                        utils.each(types,function(eventName){\n                                            editor.addListener(eventName, event.handler);\n                                        });\n                                    });\n                                    break;\n                                case 'commands':\n                                    utils.each(v,function(execFn,execName){\n                                        editor.commands[execName] = execFn\n                                    });\n                                    break;\n                                case 'outputrule':\n                                    editor.addOutputRule(v);\n                                    break;\n                                case 'inputrule':\n                                    editor.addInputRule(v);\n                                    break;\n                                case 'defaultoptions':\n                                    editor.setOpt(v)\n                            }\n                        })\n                    }\n\n                }else if(plugin.afterDisabled){\n                    plugin.afterDisabled.call(editor)\n                }\n\n            });\n            //向下兼容\n            utils.each(UE.plugins,function(plugin){\n                plugin.call(editor);\n            });\n        },\n        run : function(pluginName,editor){\n            var plugin = _plugins[pluginName];\n            if(plugin){\n                plugin.exeFn.call(editor)\n            }\n        }\n    }\n}();\n\n// core/keymap.js\nvar keymap = UE.keymap  = {\n    'Backspace' : 8,\n    'Tab' : 9,\n    'Enter' : 13,\n\n    'Shift':16,\n    'Control':17,\n    'Alt':18,\n    'CapsLock':20,\n\n    'Esc':27,\n\n    'Spacebar':32,\n\n    'PageUp':33,\n    'PageDown':34,\n    'End':35,\n    'Home':36,\n\n    'Left':37,\n    'Up':38,\n    'Right':39,\n    'Down':40,\n\n    'Insert':45,\n\n    'Del':46,\n\n    'NumLock':144,\n\n    'Cmd':91,\n\n    '=':187,\n    '-':189,\n\n    \"b\":66,\n    'i':73,\n    //回退\n    'z':90,\n    'y':89,\n    //粘贴\n    'v' : 86,\n    'x' : 88,\n\n    's' : 83,\n\n    'n' : 78\n};\n\n// core/localstorage.js\n//存储媒介封装\nvar LocalStorage = UE.LocalStorage = (function () {\n\n    var storage = window.localStorage || getUserData() || null,\n        LOCAL_FILE = 'localStorage';\n\n    return {\n\n        saveLocalData: function (key, data) {\n\n            if (storage && data) {\n                storage.setItem(key, data);\n                return true;\n            }\n\n            return false;\n\n        },\n\n        getLocalData: function (key) {\n\n            if (storage) {\n                return storage.getItem(key);\n            }\n\n            return null;\n\n        },\n\n        removeItem: function (key) {\n\n            storage && storage.removeItem(key);\n\n        }\n\n    };\n\n    function getUserData() {\n\n        var container = document.createElement(\"div\");\n        container.style.display = \"none\";\n\n        if (!container.addBehavior) {\n            return null;\n        }\n\n        container.addBehavior(\"#default#userdata\");\n\n        return {\n\n            getItem: function (key) {\n\n                var result = null;\n\n                try {\n                    document.body.appendChild(container);\n                    container.load(LOCAL_FILE);\n                    result = container.getAttribute(key);\n                    document.body.removeChild(container);\n                } catch (e) {\n                }\n\n                return result;\n\n            },\n\n            setItem: function (key, value) {\n\n                document.body.appendChild(container);\n                container.setAttribute(key, value);\n                container.save(LOCAL_FILE);\n                document.body.removeChild(container);\n\n            },\n\n            //// 暂时没有用到\n            //clear: function () {\n            //\n            //    var expiresTime = new Date();\n            //    expiresTime.setFullYear(expiresTime.getFullYear() - 1);\n            //    document.body.appendChild(container);\n            //    container.expires = expiresTime.toUTCString();\n            //    container.save(LOCAL_FILE);\n            //    document.body.removeChild(container);\n            //\n            //},\n\n            removeItem: function (key) {\n\n                document.body.appendChild(container);\n                container.removeAttribute(key);\n                container.save(LOCAL_FILE);\n                document.body.removeChild(container);\n\n            }\n\n        };\n\n    }\n\n})();\n\n(function () {\n\n    var ROOTKEY = 'ueditor_preference';\n\n    UE.Editor.prototype.setPreferences = function(key,value){\n        var obj = {};\n        if (utils.isString(key)) {\n            obj[ key ] = value;\n        } else {\n            obj = key;\n        }\n        var data = LocalStorage.getLocalData(ROOTKEY);\n        if (data && (data = utils.str2json(data))) {\n            utils.extend(data, obj);\n        } else {\n            data = obj;\n        }\n        data && LocalStorage.saveLocalData(ROOTKEY, utils.json2str(data));\n    };\n\n    UE.Editor.prototype.getPreferences = function(key){\n        var data = LocalStorage.getLocalData(ROOTKEY);\n        if (data && (data = utils.str2json(data))) {\n            return key ? data[key] : data\n        }\n        return null;\n    };\n\n    UE.Editor.prototype.removePreferences = function (key) {\n        var data = LocalStorage.getLocalData(ROOTKEY);\n        if (data && (data = utils.str2json(data))) {\n            data[key] = undefined;\n            delete data[key]\n        }\n        data && LocalStorage.saveLocalData(ROOTKEY, utils.json2str(data));\n    };\n\n})();\n\n\n// plugins/defaultfilter.js\n///import core\r\n///plugin 编辑器默认的过滤转换机制\r\n\r\nUE.plugins['defaultfilter'] = function () {\r\n    var me = this;\r\n    me.setOpt({\r\n        'allowDivTransToP':true,\r\n        'disabledTableInTable':true\r\n    });\r\n    //默认的过滤处理\r\n    //进入编辑器的内容处理\r\n    me.addInputRule(function (root) {\r\n        var allowDivTransToP = this.options.allowDivTransToP;\r\n        var val;\r\n        function tdParent(node){\r\n            while(node && node.type == 'element'){\r\n                if(node.tagName == 'td'){\r\n                    return true;\r\n                }\r\n                node = node.parentNode;\r\n            }\r\n            return false;\r\n        }\r\n        //进行默认的处理\r\n        root.traversal(function (node) {\r\n            if (node.type == 'element') {\r\n                if (!dtd.$cdata[node.tagName] && me.options.autoClearEmptyNode && dtd.$inline[node.tagName] && !dtd.$empty[node.tagName] && (!node.attrs || utils.isEmptyObject(node.attrs))) {\r\n                    if (!node.firstChild()) node.parentNode.removeChild(node);\r\n                    else if (node.tagName == 'span' && (!node.attrs || utils.isEmptyObject(node.attrs))) {\r\n                        node.parentNode.removeChild(node, true)\r\n                    }\r\n                    return;\r\n                }\r\n                switch (node.tagName) {\r\n                    case 'style':\r\n                    case 'script':\r\n                        node.setAttr({\r\n                            cdata_tag: node.tagName,\r\n                            cdata_data: (node.innerHTML() || ''),\r\n                            '_ue_custom_node_':'true'\r\n                        });\r\n                        node.tagName = 'div';\r\n                        node.innerHTML('');\r\n                        break;\r\n                    case 'a':\r\n                        if (val = node.getAttr('href')) {\r\n                            node.setAttr('_href', val)\r\n                        }\r\n                        break;\r\n                    case 'img':\r\n                        //todo base64暂时去掉，后边做远程图片上传后，干掉这个\r\n                        if (val = node.getAttr('src')) {\r\n                            if (/^data:/.test(val)) {\r\n                                node.parentNode.removeChild(node);\r\n                                break;\r\n                            }\r\n                        }\r\n                        node.setAttr('_src', node.getAttr('src'));\r\n                        break;\r\n                    case 'span':\r\n                        if (browser.webkit && (val = node.getStyle('white-space'))) {\r\n                            if (/nowrap|normal/.test(val)) {\r\n                                node.setStyle('white-space', '');\r\n                                if (me.options.autoClearEmptyNode && utils.isEmptyObject(node.attrs)) {\r\n                                    node.parentNode.removeChild(node, true)\r\n                                }\r\n                            }\r\n                        }\r\n                        val = node.getAttr('id');\r\n                        if(val && /^_baidu_bookmark_/i.test(val)){\r\n                            node.parentNode.removeChild(node)\r\n                        }\r\n                        break;\r\n                    case 'p':\r\n                        if (val = node.getAttr('align')) {\r\n                            node.setAttr('align');\r\n                            node.setStyle('text-align', val)\r\n                        }\r\n                        //trace:3431\r\n//                        var cssStyle = node.getAttr('style');\r\n//                        if (cssStyle) {\r\n//                            cssStyle = cssStyle.replace(/(margin|padding)[^;]+/g, '');\r\n//                            node.setAttr('style', cssStyle)\r\n//\r\n//                        }\r\n                        //p标签不允许嵌套\r\n                        utils.each(node.children,function(n){\r\n                            if(n.type == 'element' && n.tagName == 'p'){\r\n                                var next = n.nextSibling();\r\n                                node.parentNode.insertAfter(n,node);\r\n                                var last = n;\r\n                                while(next){\r\n                                    var tmp = next.nextSibling();\r\n                                    node.parentNode.insertAfter(next,last);\r\n                                    last = next;\r\n                                    next = tmp;\r\n                                }\r\n                                return false;\r\n                            }\r\n                        });\r\n                        if (!node.firstChild()) {\r\n                            node.innerHTML(browser.ie ? '&nbsp;' : '<br/>')\r\n                        }\r\n                        break;\r\n                    case 'div':\r\n                        if(node.getAttr('cdata_tag')){\r\n                            break;\r\n                        }\r\n                        //针对代码这里不处理插入代码的div\r\n                        val = node.getAttr('class');\r\n                        if(val && /^line number\\d+/.test(val)){\r\n                            break;\r\n                        }\r\n                        if(!allowDivTransToP){\r\n                            break;\r\n                        }\r\n                        var tmpNode, p = UE.uNode.createElement('p');\r\n                        while (tmpNode = node.firstChild()) {\r\n                            if (tmpNode.type == 'text' || !UE.dom.dtd.$block[tmpNode.tagName]) {\r\n                                p.appendChild(tmpNode);\r\n                            } else {\r\n                                if (p.firstChild()) {\r\n                                    node.parentNode.insertBefore(p, node);\r\n                                    p = UE.uNode.createElement('p');\r\n                                } else {\r\n                                    node.parentNode.insertBefore(tmpNode, node);\r\n                                }\r\n                            }\r\n                        }\r\n                        if (p.firstChild()) {\r\n                            node.parentNode.insertBefore(p, node);\r\n                        }\r\n                        node.parentNode.removeChild(node);\r\n                        break;\r\n                    case 'dl':\r\n                        node.tagName = 'ul';\r\n                        break;\r\n                    case 'dt':\r\n                    case 'dd':\r\n                        node.tagName = 'li';\r\n                        break;\r\n                    case 'li':\r\n                        var className = node.getAttr('class');\r\n                        if (!className || !/list\\-/.test(className)) {\r\n                            node.setAttr()\r\n                        }\r\n                        var tmpNodes = node.getNodesByTagName('ol ul');\r\n                        UE.utils.each(tmpNodes, function (n) {\r\n                            node.parentNode.insertAfter(n, node);\r\n                        });\r\n                        break;\r\n                    case 'td':\r\n                    case 'th':\r\n                    case 'caption':\r\n                        if(!node.children || !node.children.length){\r\n                            node.appendChild(browser.ie11below ? UE.uNode.createText(' ') : UE.uNode.createElement('br'))\r\n                        }\r\n                        break;\r\n                    case 'table':\r\n                        if(me.options.disabledTableInTable && tdParent(node)){\r\n                            node.parentNode.insertBefore(UE.uNode.createText(node.innerText()),node);\r\n                            node.parentNode.removeChild(node)\r\n                        }\r\n                }\r\n\r\n            }\r\n//            if(node.type == 'comment'){\r\n//                node.parentNode.removeChild(node);\r\n//            }\r\n        })\r\n\r\n    });\r\n\r\n    //从编辑器出去的内容处理\r\n    me.addOutputRule(function (root) {\r\n\r\n        var val;\r\n        root.traversal(function (node) {\r\n            if (node.type == 'element') {\r\n\r\n                if (me.options.autoClearEmptyNode && dtd.$inline[node.tagName] && !dtd.$empty[node.tagName] && (!node.attrs || utils.isEmptyObject(node.attrs))) {\r\n\r\n                    if (!node.firstChild()) node.parentNode.removeChild(node);\r\n                    else if (node.tagName == 'span' && (!node.attrs || utils.isEmptyObject(node.attrs))) {\r\n                        node.parentNode.removeChild(node, true)\r\n                    }\r\n                    return;\r\n                }\r\n                switch (node.tagName) {\r\n                    case 'div':\r\n                        if (val = node.getAttr('cdata_tag')) {\r\n                            node.tagName = val;\r\n                            node.appendChild(UE.uNode.createText(node.getAttr('cdata_data')));\r\n                            node.setAttr({cdata_tag: '', cdata_data: '','_ue_custom_node_':''});\r\n                        }\r\n                        break;\r\n                    case 'a':\r\n                        if (val = node.getAttr('_href')) {\r\n                            node.setAttr({\r\n                                'href': utils.html(val),\r\n                                '_href': ''\r\n                            })\r\n                        }\r\n                        break;\r\n                        break;\r\n                    case 'span':\r\n                        val = node.getAttr('id');\r\n                        if(val && /^_baidu_bookmark_/i.test(val)){\r\n                            node.parentNode.removeChild(node)\r\n                        }\r\n                        break;\r\n                    case 'img':\r\n                        if (val = node.getAttr('_src')) {\r\n                            node.setAttr({\r\n                                'src': node.getAttr('_src'),\r\n                                '_src': ''\r\n                            })\r\n                        }\r\n\r\n\r\n                }\r\n            }\r\n\r\n        })\r\n\r\n\r\n    });\r\n};\r\n\n\n// plugins/inserthtml.js\n/**\r\n * 插入html字符串插件\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 插入html代码\r\n * @command inserthtml\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @param { String } html 插入的html字符串\r\n * @remaind 插入的标签内容是在当前的选区位置上插入，如果当前是闭合状态，那直接插入内容， 如果当前是选中状态，将先清除当前选中内容后，再做插入\r\n * @warning 注意:该命令会对当前选区的位置，对插入的内容进行过滤转换处理。 过滤的规则遵循html语意化的原则。\r\n * @example\r\n * ```javascript\r\n * //xxx[BB]xxx 当前选区为非闭合选区，选中BB这两个文本\r\n * //执行命令，插入<b>CC</b>\r\n * //插入后的效果 xxx<b>CC</b>xxx\r\n * //<p>xx|xxx</p> 当前选区为闭合状态\r\n * //插入<p>CC</p>\r\n * //结果 <p>xx</p><p>CC</p><p>xxx</p>\r\n * //<p>xxxx</p>|</p>xxx</p> 当前选区在两个p标签之间\r\n * //插入 xxxx\r\n * //结果 <p>xxxx</p><p>xxxx</p></p>xxx</p>\r\n * ```\r\n */\r\n\r\nUE.commands['inserthtml'] = {\r\n    execCommand: function (command,html,notNeedFilter){\r\n        var me = this,\r\n            range,\r\n            div;\r\n        if(!html){\r\n            return;\r\n        }\r\n        if(me.fireEvent('beforeinserthtml',html) === true){\r\n            return;\r\n        }\r\n        range = me.selection.getRange();\r\n        div = range.document.createElement( 'div' );\r\n        div.style.display = 'inline';\r\n\r\n        if (!notNeedFilter) {\r\n            var root = UE.htmlparser(html);\r\n            //如果给了过滤规则就先进行过滤\r\n            if(me.options.filterRules){\r\n                UE.filterNode(root,me.options.filterRules);\r\n            }\r\n            //执行默认的处理\r\n            me.filterInputRule(root);\r\n            html = root.toHtml()\r\n        }\r\n        div.innerHTML = utils.trim( html );\r\n\r\n        if ( !range.collapsed ) {\r\n            var tmpNode = range.startContainer;\r\n            if(domUtils.isFillChar(tmpNode)){\r\n                range.setStartBefore(tmpNode)\r\n            }\r\n            tmpNode = range.endContainer;\r\n            if(domUtils.isFillChar(tmpNode)){\r\n                range.setEndAfter(tmpNode)\r\n            }\r\n            range.txtToElmBoundary();\r\n            //结束边界可能放到了br的前边，要把br包含进来\r\n            // x[xxx]<br/>\r\n            if(range.endContainer && range.endContainer.nodeType == 1){\r\n                tmpNode = range.endContainer.childNodes[range.endOffset];\r\n                if(tmpNode && domUtils.isBr(tmpNode)){\r\n                    range.setEndAfter(tmpNode);\r\n                }\r\n            }\r\n            if(range.startOffset == 0){\r\n                tmpNode = range.startContainer;\r\n                if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){\r\n                    tmpNode = range.endContainer;\r\n                    if(range.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){\r\n                        me.body.innerHTML = '<p>'+(browser.ie ? '' : '<br/>')+'</p>';\r\n                        range.setStart(me.body.firstChild,0).collapse(true)\r\n\r\n                    }\r\n                }\r\n            }\r\n            !range.collapsed && range.deleteContents();\r\n            if(range.startContainer.nodeType == 1){\r\n                var child = range.startContainer.childNodes[range.startOffset],pre;\r\n                if(child && domUtils.isBlockElm(child) && (pre = child.previousSibling) && domUtils.isBlockElm(pre)){\r\n                    range.setEnd(pre,pre.childNodes.length).collapse();\r\n                    while(child.firstChild){\r\n                        pre.appendChild(child.firstChild);\r\n                    }\r\n                    domUtils.remove(child);\r\n                }\r\n            }\r\n\r\n        }\r\n\r\n\r\n        var child,parent,pre,tmp,hadBreak = 0, nextNode;\r\n        //如果当前位置选中了fillchar要干掉，要不会产生空行\r\n        if(range.inFillChar()){\r\n            child = range.startContainer;\r\n            if(domUtils.isFillChar(child)){\r\n                range.setStartBefore(child).collapse(true);\r\n                domUtils.remove(child);\r\n            }else if(domUtils.isFillChar(child,true)){\r\n                child.nodeValue = child.nodeValue.replace(fillCharReg,'');\r\n                range.startOffset--;\r\n                range.collapsed && range.collapse(true)\r\n            }\r\n        }\r\n        //列表单独处理\r\n        var li = domUtils.findParentByTagName(range.startContainer,'li',true);\r\n        if(li){\r\n            var next,last;\r\n            while(child = div.firstChild){\r\n                //针对hr单独处理一下先\r\n                while(child && (child.nodeType == 3 || !domUtils.isBlockElm(child) || child.tagName=='HR' )){\r\n                    next = child.nextSibling;\r\n                    range.insertNode( child).collapse();\r\n                    last = child;\r\n                    child = next;\r\n\r\n                }\r\n                if(child){\r\n                    if(/^(ol|ul)$/i.test(child.tagName)){\r\n                        while(child.firstChild){\r\n                            last = child.firstChild;\r\n                            domUtils.insertAfter(li,child.firstChild);\r\n                            li = li.nextSibling;\r\n                        }\r\n                        domUtils.remove(child)\r\n                    }else{\r\n                        var tmpLi;\r\n                        next = child.nextSibling;\r\n                        tmpLi = me.document.createElement('li');\r\n                        domUtils.insertAfter(li,tmpLi);\r\n                        tmpLi.appendChild(child);\r\n                        last = child;\r\n                        child = next;\r\n                        li = tmpLi;\r\n                    }\r\n                }\r\n            }\r\n            li = domUtils.findParentByTagName(range.startContainer,'li',true);\r\n            if(domUtils.isEmptyBlock(li)){\r\n                domUtils.remove(li)\r\n            }\r\n            if(last){\r\n\r\n                range.setStartAfter(last).collapse(true).select(true)\r\n            }\r\n        }else{\r\n            while ( child = div.firstChild ) {\r\n                if(hadBreak){\r\n                    var p = me.document.createElement('p');\r\n                    while(child && (child.nodeType == 3 || !dtd.$block[child.tagName])){\r\n                        nextNode = child.nextSibling;\r\n                        p.appendChild(child);\r\n                        child = nextNode;\r\n                    }\r\n                    if(p.firstChild){\r\n\r\n                        child = p\r\n                    }\r\n                }\r\n                range.insertNode( child );\r\n                nextNode = child.nextSibling;\r\n                if ( !hadBreak && child.nodeType == domUtils.NODE_ELEMENT && domUtils.isBlockElm( child ) ){\r\n\r\n                    parent = domUtils.findParent( child,function ( node ){ return domUtils.isBlockElm( node ); } );\r\n                    if ( parent && parent.tagName.toLowerCase() != 'body' && !(dtd[parent.tagName][child.nodeName] && child.parentNode === parent)){\r\n                        if(!dtd[parent.tagName][child.nodeName]){\r\n                            pre = parent;\r\n                        }else{\r\n                            tmp = child.parentNode;\r\n                            while (tmp !== parent){\r\n                                pre = tmp;\r\n                                tmp = tmp.parentNode;\r\n\r\n                            }\r\n                        }\r\n\r\n\r\n                        domUtils.breakParent( child, pre || tmp );\r\n                        //去掉break后前一个多余的节点  <p>|<[p> ==> <p></p><div></div><p>|</p>\r\n                        var pre = child.previousSibling;\r\n                        domUtils.trimWhiteTextNode(pre);\r\n                        if(!pre.childNodes.length){\r\n                            domUtils.remove(pre);\r\n                        }\r\n                        //trace:2012,在非ie的情况，切开后剩下的节点有可能不能点入光标添加br占位\r\n\r\n                        if(!browser.ie &&\r\n                            (next = child.nextSibling) &&\r\n                            domUtils.isBlockElm(next) &&\r\n                            next.lastChild &&\r\n                            !domUtils.isBr(next.lastChild)){\r\n                            next.appendChild(me.document.createElement('br'));\r\n                        }\r\n                        hadBreak = 1;\r\n                    }\r\n                }\r\n                var next = child.nextSibling;\r\n                if(!div.firstChild && next && domUtils.isBlockElm(next)){\r\n\r\n                    range.setStart(next,0).collapse(true);\r\n                    break;\r\n                }\r\n                range.setEndAfter( child ).collapse();\r\n\r\n            }\r\n\r\n            child = range.startContainer;\r\n\r\n            if(nextNode && domUtils.isBr(nextNode)){\r\n                domUtils.remove(nextNode)\r\n            }\r\n            //用chrome可能有空白展位符\r\n            if(domUtils.isBlockElm(child) && domUtils.isEmptyNode(child)){\r\n                if(nextNode = child.nextSibling){\r\n                    domUtils.remove(child);\r\n                    if(nextNode.nodeType == 1 && dtd.$block[nextNode.tagName]){\r\n\r\n                        range.setStart(nextNode,0).collapse(true).shrinkBoundary()\r\n                    }\r\n                }else{\r\n\r\n                    try{\r\n                        child.innerHTML = browser.ie ? domUtils.fillChar : '<br/>';\r\n                    }catch(e){\r\n                        range.setStartBefore(child);\r\n                        domUtils.remove(child)\r\n                    }\r\n\r\n                }\r\n\r\n            }\r\n            //加上true因为在删除表情等时会删两次，第一次是删的fillData\r\n            try{\r\n                range.select(true);\r\n            }catch(e){}\r\n\r\n        }\r\n\r\n\r\n\r\n        setTimeout(function(){\r\n            range = me.selection.getRange();\r\n            range.scrollToView(me.autoHeightEnabled,me.autoHeightEnabled ? domUtils.getXY(me.iframe).y:0);\r\n            me.fireEvent('afterinserthtml', html);\r\n        },200);\r\n    }\r\n};\r\n\n\n// plugins/autotypeset.js\n/**\r\n * 自动排版\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 对当前编辑器的内容执行自动排版， 排版的行为根据config配置文件里的“autotypeset”选项进行控制。\r\n * @command autotypeset\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'autotypeset' );\r\n * ```\r\n */\r\n\r\nUE.plugins['autotypeset'] = function(){\r\n\r\n    this.setOpt({'autotypeset': {\r\n        mergeEmptyline: true,           //合并空行\r\n        removeClass: true,              //去掉冗余的class\r\n        removeEmptyline: false,         //去掉空行\r\n        textAlign:\"left\",               //段落的排版方式，可以是 left,right,center,justify 去掉这个属性表示不执行排版\r\n        imageBlockLine: 'center',       //图片的浮动方式，独占一行剧中,左右浮动，默认: center,left,right,none 去掉这个属性表示不执行排版\r\n        pasteFilter: false,             //根据规则过滤没事粘贴进来的内容\r\n        clearFontSize: false,           //去掉所有的内嵌字号，使用编辑器默认的字号\r\n        clearFontFamily: false,         //去掉所有的内嵌字体，使用编辑器默认的字体\r\n        removeEmptyNode: false,         // 去掉空节点\r\n        //可以去掉的标签\r\n        removeTagNames: utils.extend({div:1},dtd.$removeEmpty),\r\n        indent: false,                  // 行首缩进\r\n        indentValue : '2em',            //行首缩进的大小\r\n        bdc2sb: false,\r\n        tobdc: false\r\n    }});\r\n\r\n    var me = this,\r\n        opt = me.options.autotypeset,\r\n        remainClass = {\r\n            'selectTdClass':1,\r\n            'pagebreak':1,\r\n            'anchorclass':1\r\n        },\r\n        remainTag = {\r\n            'li':1\r\n        },\r\n        tags = {\r\n            div:1,\r\n            p:1,\r\n            //trace:2183 这些也认为是行\r\n            blockquote:1,center:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,\r\n            span:1\r\n        },\r\n        highlightCont;\r\n    //升级了版本，但配置项目里没有autotypeset\r\n    if(!opt){\r\n        return;\r\n    }\r\n\r\n    readLocalOpts();\r\n\r\n    function isLine(node,notEmpty){\r\n        if(!node || node.nodeType == 3)\r\n            return 0;\r\n        if(domUtils.isBr(node))\r\n            return 1;\r\n        if(node && node.parentNode && tags[node.tagName.toLowerCase()]){\r\n            if(highlightCont && highlightCont.contains(node)\r\n                ||\r\n                node.getAttribute('pagebreak')\r\n            ){\r\n                return 0;\r\n            }\r\n\r\n            return notEmpty ? !domUtils.isEmptyBlock(node) : domUtils.isEmptyBlock(node,new RegExp('[\\\\s'+domUtils.fillChar\r\n                +']','g'));\r\n        }\r\n    }\r\n\r\n    function removeNotAttributeSpan(node){\r\n        if(!node.style.cssText){\r\n            domUtils.removeAttributes(node,['style']);\r\n            if(node.tagName.toLowerCase() == 'span' && domUtils.hasNoAttributes(node)){\r\n                domUtils.remove(node,true);\r\n            }\r\n        }\r\n    }\r\n    function autotype(type,html){\r\n\r\n        var me = this,cont;\r\n        if(html){\r\n            if(!opt.pasteFilter){\r\n                return;\r\n            }\r\n            cont = me.document.createElement('div');\r\n            cont.innerHTML = html.html;\r\n        }else{\r\n            cont = me.document.body;\r\n        }\r\n        var nodes = domUtils.getElementsByTagName(cont,'*');\r\n\r\n        // 行首缩进，段落方向，段间距，段内间距\r\n        for(var i=0,ci;ci=nodes[i++];){\r\n\r\n            if(me.fireEvent('excludeNodeinautotype',ci) === true){\r\n                continue;\r\n            }\r\n             //font-size\r\n            if(opt.clearFontSize && ci.style.fontSize){\r\n                domUtils.removeStyle(ci,'font-size');\r\n\r\n                removeNotAttributeSpan(ci);\r\n\r\n            }\r\n            //font-family\r\n            if(opt.clearFontFamily && ci.style.fontFamily){\r\n                domUtils.removeStyle(ci,'font-family');\r\n                removeNotAttributeSpan(ci);\r\n            }\r\n\r\n            if(isLine(ci)){\r\n                //合并空行\r\n                if(opt.mergeEmptyline ){\r\n                    var next = ci.nextSibling,tmpNode,isBr = domUtils.isBr(ci);\r\n                    while(isLine(next)){\r\n                        tmpNode = next;\r\n                        next = tmpNode.nextSibling;\r\n                        if(isBr && (!next || next && !domUtils.isBr(next))){\r\n                            break;\r\n                        }\r\n                        domUtils.remove(tmpNode);\r\n                    }\r\n\r\n                }\r\n                 //去掉空行，保留占位的空行\r\n                if(opt.removeEmptyline && domUtils.inDoc(ci,cont) && !remainTag[ci.parentNode.tagName.toLowerCase()] ){\r\n                    if(domUtils.isBr(ci)){\r\n                        next = ci.nextSibling;\r\n                        if(next && !domUtils.isBr(next)){\r\n                            continue;\r\n                        }\r\n                    }\r\n                    domUtils.remove(ci);\r\n                    continue;\r\n\r\n                }\r\n\r\n            }\r\n            if(isLine(ci,true) && ci.tagName != 'SPAN'){\r\n                if(opt.indent){\r\n                    ci.style.textIndent = opt.indentValue;\r\n                }\r\n                if(opt.textAlign){\r\n                    ci.style.textAlign = opt.textAlign;\r\n                }\r\n                // if(opt.lineHeight)\r\n                //     ci.style.lineHeight = opt.lineHeight + 'cm';\r\n\r\n            }\r\n\r\n            //去掉class,保留的class不去掉\r\n            if(opt.removeClass && ci.className && !remainClass[ci.className.toLowerCase()]){\r\n\r\n                if(highlightCont && highlightCont.contains(ci)){\r\n                     continue;\r\n                }\r\n                domUtils.removeAttributes(ci,['class']);\r\n            }\r\n\r\n            //表情不处理\r\n            if(opt.imageBlockLine && ci.tagName.toLowerCase() == 'img' && !ci.getAttribute('emotion')){\r\n                if(html){\r\n                    var img = ci;\r\n                    switch (opt.imageBlockLine){\r\n                        case 'left':\r\n                        case 'right':\r\n                        case 'none':\r\n                            var pN = img.parentNode,tmpNode,pre,next;\r\n                            while(dtd.$inline[pN.tagName] || pN.tagName == 'A'){\r\n                                pN = pN.parentNode;\r\n                            }\r\n                            tmpNode = pN;\r\n                            if(tmpNode.tagName == 'P' && domUtils.getStyle(tmpNode,'text-align') == 'center'){\r\n                                if(!domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode,function(node){return !domUtils.isBr(node) && !domUtils.isWhitespace(node)}) == 1){\r\n                                    pre = tmpNode.previousSibling;\r\n                                    next = tmpNode.nextSibling;\r\n                                    if(pre && next && pre.nodeType == 1 &&  next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre)){\r\n                                        pre.appendChild(tmpNode.firstChild);\r\n                                        while(next.firstChild){\r\n                                            pre.appendChild(next.firstChild);\r\n                                        }\r\n                                        domUtils.remove(tmpNode);\r\n                                        domUtils.remove(next);\r\n                                    }else{\r\n                                        domUtils.setStyle(tmpNode,'text-align','');\r\n                                    }\r\n\r\n\r\n                                }\r\n\r\n\r\n                            }\r\n                            domUtils.setStyle(img,'float', opt.imageBlockLine);\r\n                            break;\r\n                        case 'center':\r\n                            if(me.queryCommandValue('imagefloat') != 'center'){\r\n                                pN = img.parentNode;\r\n                                domUtils.setStyle(img,'float','none');\r\n                                tmpNode = img;\r\n                                while(pN && domUtils.getChildCount(pN,function(node){return !domUtils.isBr(node) && !domUtils.isWhitespace(node)}) == 1\r\n                                    && (dtd.$inline[pN.tagName] || pN.tagName == 'A')){\r\n                                    tmpNode = pN;\r\n                                    pN = pN.parentNode;\r\n                                }\r\n                                var pNode = me.document.createElement('p');\r\n                                domUtils.setAttributes(pNode,{\r\n\r\n                                    style:'text-align:center'\r\n                                });\r\n                                tmpNode.parentNode.insertBefore(pNode,tmpNode);\r\n                                pNode.appendChild(tmpNode);\r\n                                domUtils.setStyle(tmpNode,'float','');\r\n\r\n                            }\r\n\r\n\r\n                    }\r\n                } else {\r\n                    var range = me.selection.getRange();\r\n                    range.selectNode(ci).select();\r\n                    me.execCommand('imagefloat', opt.imageBlockLine);\r\n                }\r\n\r\n            }\r\n\r\n            //去掉冗余的标签\r\n            if(opt.removeEmptyNode){\r\n                if(opt.removeTagNames[ci.tagName.toLowerCase()] && domUtils.hasNoAttributes(ci) && domUtils.isEmptyBlock(ci)){\r\n                    domUtils.remove(ci);\r\n                }\r\n            }\r\n        }\r\n        if(opt.tobdc){\r\n            var root = UE.htmlparser(cont.innerHTML);\r\n            root.traversal(function(node){\r\n                if(node.type == 'text'){\r\n                    node.data = ToDBC(node.data)\r\n                }\r\n            });\r\n            cont.innerHTML = root.toHtml()\r\n        }\r\n        if(opt.bdc2sb){\r\n            var root = UE.htmlparser(cont.innerHTML);\r\n            root.traversal(function(node){\r\n                if(node.type == 'text'){\r\n                    node.data = DBC2SB(node.data)\r\n                }\r\n            });\r\n            cont.innerHTML = root.toHtml()\r\n        }\r\n        if(html){\r\n            html.html = cont.innerHTML;\r\n        }\r\n    }\r\n    if(opt.pasteFilter){\r\n        me.addListener('beforepaste',autotype);\r\n    }\r\n\r\n    function DBC2SB(str) {\r\n        var result = '';\r\n        for (var i = 0; i < str.length; i++) {\r\n            var code = str.charCodeAt(i); //获取当前字符的unicode编码\r\n            if (code >= 65281 && code <= 65373)//在这个unicode编码范围中的是所有的英文字母已经各种字符\r\n            {\r\n                result += String.fromCharCode(str.charCodeAt(i) - 65248); //把全角字符的unicode编码转换为对应半角字符的unicode码\r\n            } else if (code == 12288)//空格\r\n            {\r\n                result += String.fromCharCode(str.charCodeAt(i) - 12288 + 32);\r\n            } else {\r\n                result += str.charAt(i);\r\n            }\r\n        }\r\n        return result;\r\n    }\r\n    function ToDBC(txtstring) {\r\n        txtstring = utils.html(txtstring);\r\n        var tmp = \"\";\r\n        var mark = \"\";/*用于判断,如果是html尖括里的标记,则不进行全角的转换*/\r\n        for (var i = 0; i < txtstring.length; i++) {\r\n            if (txtstring.charCodeAt(i) == 32) {\r\n                tmp = tmp + String.fromCharCode(12288);\r\n            }\r\n            else if (txtstring.charCodeAt(i) < 127) {\r\n                tmp = tmp + String.fromCharCode(txtstring.charCodeAt(i) + 65248);\r\n            }\r\n            else {\r\n                tmp += txtstring.charAt(i);\r\n            }\r\n        }\r\n        return tmp;\r\n    }\r\n\r\n    function readLocalOpts() {\r\n        var cookieOpt = me.getPreferences('autotypeset');\r\n        utils.extend(me.options.autotypeset, cookieOpt);\r\n    }\r\n\r\n    me.commands['autotypeset'] = {\r\n        execCommand:function () {\r\n            me.removeListener('beforepaste',autotype);\r\n            if(opt.pasteFilter){\r\n                me.addListener('beforepaste',autotype);\r\n            }\r\n            autotype.call(me)\r\n        }\r\n\r\n    };\r\n\r\n};\r\n\r\n\n\n// plugins/autosubmit.js\n/**\r\n * 快捷键提交\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 提交表单\r\n * @command autosubmit\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'autosubmit' );\r\n * ```\r\n */\r\n\r\nUE.plugin.register('autosubmit',function(){\r\n    return {\r\n        shortcutkey:{\r\n            \"autosubmit\":\"ctrl+13\" //手动提交\r\n        },\r\n        commands:{\r\n            'autosubmit':{\r\n                execCommand:function () {\r\n                    var me=this,\r\n                        form = domUtils.findParentByTagName(me.iframe,\"form\", false);\r\n                    if (form){\r\n                        if(me.fireEvent(\"beforesubmit\")===false){\r\n                            return;\r\n                        }\r\n                        me.sync();\r\n                        form.submit();\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    }\r\n});\n\n// plugins/background.js\n/**\r\n * 背景插件，为UEditor提供设置背景功能\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\nUE.plugin.register('background', function () {\r\n    var me = this,\r\n        cssRuleId = 'editor_background',\r\n        isSetColored,\r\n        reg = new RegExp('body[\\\\s]*\\\\{(.+)\\\\}', 'i');\r\n\r\n    function stringToObj(str) {\r\n        var obj = {}, styles = str.split(';');\r\n        utils.each(styles, function (v) {\r\n            var index = v.indexOf(':'),\r\n                key = utils.trim(v.substr(0, index)).toLowerCase();\r\n            key && (obj[key] = utils.trim(v.substr(index + 1) || ''));\r\n        });\r\n        return obj;\r\n    }\r\n\r\n    function setBackground(obj) {\r\n        if (obj) {\r\n            var styles = [];\r\n            for (var name in obj) {\r\n                if (obj.hasOwnProperty(name)) {\r\n                    styles.push(name + \":\" + obj[name] + '; ');\r\n                }\r\n            }\r\n            utils.cssRule(cssRuleId, styles.length ? ('body{' + styles.join(\"\") + '}') : '', me.document);\r\n        } else {\r\n            utils.cssRule(cssRuleId, '', me.document)\r\n        }\r\n    }\r\n    //重写editor.hasContent方法\r\n\r\n    var orgFn = me.hasContents;\r\n    me.hasContents = function(){\r\n        if(me.queryCommandValue('background')){\r\n            return true\r\n        }\r\n        return orgFn.apply(me,arguments);\r\n    };\r\n    return {\r\n        bindEvents: {\r\n            'getAllHtml': function (type, headHtml) {\r\n                var body = this.body,\r\n                    su = domUtils.getComputedStyle(body, \"background-image\"),\r\n                    url = \"\";\r\n                if (su.indexOf(me.options.imagePath) > 0) {\r\n                    url = su.substring(su.indexOf(me.options.imagePath), su.length - 1).replace(/\"|\\(|\\)/ig, \"\");\r\n                } else {\r\n                    url = su != \"none\" ? su.replace(/url\\(\"?|\"?\\)/ig, \"\") : \"\";\r\n                }\r\n                var html = '<style type=\"text/css\">body{';\r\n                var bgObj = {\r\n                    \"background-color\": domUtils.getComputedStyle(body, \"background-color\") || \"#ffffff\",\r\n                    'background-image': url ? 'url(' + url + ')' : '',\r\n                    'background-repeat': domUtils.getComputedStyle(body, \"background-repeat\") || \"\",\r\n                    'background-position': browser.ie ? (domUtils.getComputedStyle(body, \"background-position-x\") + \" \" + domUtils.getComputedStyle(body, \"background-position-y\")) : domUtils.getComputedStyle(body, \"background-position\"),\r\n                    'height': domUtils.getComputedStyle(body, \"height\")\r\n                };\r\n                for (var name in bgObj) {\r\n                    if (bgObj.hasOwnProperty(name)) {\r\n                        html += name + \":\" + bgObj[name] + \"; \";\r\n                    }\r\n                }\r\n                html += '}</style> ';\r\n                headHtml.push(html);\r\n            },\r\n            'aftersetcontent': function () {\r\n                if(isSetColored == false) setBackground();\r\n            }\r\n        },\r\n        inputRule: function (root) {\r\n            isSetColored = false;\r\n            utils.each(root.getNodesByTagName('p'), function (p) {\r\n                var styles = p.getAttr('data-background');\r\n                if (styles) {\r\n                    isSetColored = true;\r\n                    setBackground(stringToObj(styles));\r\n                    p.parentNode.removeChild(p);\r\n                }\r\n            })\r\n        },\r\n        outputRule: function (root) {\r\n            var me = this,\r\n                styles = (utils.cssRule(cssRuleId, me.document) || '').replace(/[\\n\\r]+/g, '').match(reg);\r\n            if (styles) {\r\n                root.appendChild(UE.uNode.createElement('<p style=\"display:none;\" data-background=\"' + utils.trim(styles[1].replace(/\"/g, '').replace(/[\\s]+/g, ' ')) + '\"><br/></p>'));\r\n            }\r\n        },\r\n        commands: {\r\n            'background': {\r\n                execCommand: function (cmd, obj) {\r\n                    setBackground(obj);\r\n                },\r\n                queryCommandValue: function () {\r\n                    var me = this,\r\n                        styles = (utils.cssRule(cssRuleId, me.document) || '').replace(/[\\n\\r]+/g, '').match(reg);\r\n                    return styles ? stringToObj(styles[1]) : null;\r\n                },\r\n                notNeedUndo: true\r\n            }\r\n        }\r\n    }\r\n});\n\n// plugins/image.js\n/**\n * 图片插入、排版插件\n * @file\n * @since 1.2.6.1\n */\n\n/**\n * 图片对齐方式\n * @command imagefloat\n * @method execCommand\n * @remind 值center为独占一行居中\n * @param { String } cmd 命令字符串\n * @param { String } align 对齐方式，可传left、right、none、center\n * @remaind center表示图片独占一行\n * @example\n * ```javascript\n * editor.execCommand( 'imagefloat', 'center' );\n * ```\n */\n\n/**\n * 如果选区所在位置是图片区域\n * @command imagefloat\n * @method queryCommandValue\n * @param { String } cmd 命令字符串\n * @return { String } 返回图片对齐方式\n * @example\n * ```javascript\n * editor.queryCommandValue( 'imagefloat' );\n * ```\n */\n\nUE.commands['imagefloat'] = {\n    execCommand:function (cmd, align) {\n        var me = this,\n            range = me.selection.getRange();\n        if (!range.collapsed) {\n            var img = range.getClosedNode();\n            if (img && img.tagName == 'IMG') {\n                switch (align) {\n                    case 'left':\n                    case 'right':\n                    case 'none':\n                        var pN = img.parentNode, tmpNode, pre, next;\n                        while (dtd.$inline[pN.tagName] || pN.tagName == 'A') {\n                            pN = pN.parentNode;\n                        }\n                        tmpNode = pN;\n                        if (tmpNode.tagName == 'P' && domUtils.getStyle(tmpNode, 'text-align') == 'center') {\n                            if (!domUtils.isBody(tmpNode) && domUtils.getChildCount(tmpNode, function (node) {\n                                return !domUtils.isBr(node) && !domUtils.isWhitespace(node);\n                            }) == 1) {\n                                pre = tmpNode.previousSibling;\n                                next = tmpNode.nextSibling;\n                                if (pre && next && pre.nodeType == 1 && next.nodeType == 1 && pre.tagName == next.tagName && domUtils.isBlockElm(pre)) {\n                                    pre.appendChild(tmpNode.firstChild);\n                                    while (next.firstChild) {\n                                        pre.appendChild(next.firstChild);\n                                    }\n                                    domUtils.remove(tmpNode);\n                                    domUtils.remove(next);\n                                } else {\n                                    domUtils.setStyle(tmpNode, 'text-align', '');\n                                }\n\n\n                            }\n\n                            range.selectNode(img).select();\n                        }\n                        domUtils.setStyle(img, 'float', align == 'none' ? '' : align);\n                        if(align == 'none'){\n                            domUtils.removeAttributes(img,'align');\n                        }\n\n                        break;\n                    case 'center':\n                        if (me.queryCommandValue('imagefloat') != 'center') {\n                            pN = img.parentNode;\n                            domUtils.setStyle(img, 'float', '');\n                            domUtils.removeAttributes(img,'align');\n                            tmpNode = img;\n                            while (pN && domUtils.getChildCount(pN, function (node) {\n                                return !domUtils.isBr(node) && !domUtils.isWhitespace(node);\n                            }) == 1\n                                && (dtd.$inline[pN.tagName] || pN.tagName == 'A')) {\n                                tmpNode = pN;\n                                pN = pN.parentNode;\n                            }\n                            range.setStartBefore(tmpNode).setCursor(false);\n                            pN = me.document.createElement('div');\n                            pN.appendChild(tmpNode);\n                            domUtils.setStyle(tmpNode, 'float', '');\n\n                            me.execCommand('insertHtml', '<p id=\"_img_parent_tmp\" style=\"text-align:center\">' + pN.innerHTML + '</p>');\n\n                            tmpNode = me.document.getElementById('_img_parent_tmp');\n                            tmpNode.removeAttribute('id');\n                            tmpNode = tmpNode.firstChild;\n                            range.selectNode(tmpNode).select();\n                            //去掉后边多余的元素\n                            next = tmpNode.parentNode.nextSibling;\n                            if (next && domUtils.isEmptyNode(next)) {\n                                domUtils.remove(next);\n                            }\n\n                        }\n\n                        break;\n                }\n\n            }\n        }\n    },\n    queryCommandValue:function () {\n        var range = this.selection.getRange(),\n            startNode, floatStyle;\n        if (range.collapsed) {\n            return 'none';\n        }\n        startNode = range.getClosedNode();\n        if (startNode && startNode.nodeType == 1 && startNode.tagName == 'IMG') {\n            floatStyle = domUtils.getComputedStyle(startNode, 'float') || startNode.getAttribute('align');\n\n            if (floatStyle == 'none') {\n                floatStyle = domUtils.getComputedStyle(startNode.parentNode, 'text-align') == 'center' ? 'center' : floatStyle;\n            }\n            return {\n                left:1,\n                right:1,\n                center:1\n            }[floatStyle] ? floatStyle : 'none';\n        }\n        return 'none';\n\n\n    },\n    queryCommandState:function () {\n        var range = this.selection.getRange(),\n            startNode;\n\n        if (range.collapsed)  return -1;\n\n        startNode = range.getClosedNode();\n        if (startNode && startNode.nodeType == 1 && startNode.tagName == 'IMG') {\n            return 0;\n        }\n        return -1;\n    }\n};\n\n\n/**\n * 插入图片\n * @command insertimage\n * @method execCommand\n * @param { String } cmd 命令字符串\n * @param { Object } opt 属性键值对，这些属性都将被复制到当前插入图片\n * @remind 该命令第二个参数可接受一个图片配置项对象的数组，可以插入多张图片，\n * 此时数组的每一个元素都是一个Object类型的图片属性集合。\n * @example\n * ```javascript\n * editor.execCommand( 'insertimage', {\n *     src:'a/b/c.jpg',\n *     width:'100',\n *     height:'100'\n * } );\n * ```\n * @example\n * ```javascript\n * editor.execCommand( 'insertimage', [{\n *     src:'a/b/c.jpg',\n *     width:'100',\n *     height:'100'\n * },{\n *     src:'a/b/d.jpg',\n *     width:'100',\n *     height:'100'\n * }] );\n * ```\n */\n\nUE.commands['insertimage'] = {\n    execCommand:function (cmd, opt) {\n\n        opt = utils.isArray(opt) ? opt : [opt];\n        if (!opt.length) {\n            return;\n        }\n        var me = this,\n            range = me.selection.getRange(),\n            img = range.getClosedNode();\n\n        if(me.fireEvent('beforeinsertimage', opt) === true){\n            return;\n        }\n\n        function unhtmlData(imgCi) {\n\n            utils.each('width,height,border,hspace,vspace'.split(','), function (item) {\n\n                if (imgCi[item]) {\n                    imgCi[item] = parseInt(imgCi[item], 10) || 0;\n                }\n            });\n\n            utils.each('src,_src'.split(','), function (item) {\n\n                if (imgCi[item]) {\n                    imgCi[item] = utils.unhtmlForUrl(imgCi[item]);\n                }\n            });\n            utils.each('title,alt'.split(','), function (item) {\n\n                if (imgCi[item]) {\n                    imgCi[item] = utils.unhtml(imgCi[item]);\n                }\n            });\n        }\n\n        if (img && /img/i.test(img.tagName) && (img.className != \"edui-faked-video\" || img.className.indexOf(\"edui-upload-video\")!=-1) && !img.getAttribute(\"word_img\")) {\n            var first = opt.shift();\n            var floatStyle = first['floatStyle'];\n            delete first['floatStyle'];\n////                img.style.border = (first.border||0) +\"px solid #000\";\n////                img.style.margin = (first.margin||0) +\"px\";\n//                img.style.cssText += ';margin:' + (first.margin||0) +\"px;\" + 'border:' + (first.border||0) +\"px solid #000\";\n            domUtils.setAttributes(img, first);\n            me.execCommand('imagefloat', floatStyle);\n            if (opt.length > 0) {\n                range.setStartAfter(img).setCursor(false, true);\n                me.execCommand('insertimage', opt);\n            }\n\n        } else {\n            var html = [], str = '', ci;\n            ci = opt[0];\n            if (opt.length == 1) {\n                unhtmlData(ci);\n\n                str = '<img src=\"' + ci.src + '\" ' + (ci._src ? ' _src=\"' + ci._src + '\" ' : '') +\n                    (ci.width ? 'width=\"' + ci.width + '\" ' : '') +\n                    (ci.height ? ' height=\"' + ci.height + '\" ' : '') +\n                    (ci['floatStyle'] == 'left' || ci['floatStyle'] == 'right' ? ' style=\"float:' + ci['floatStyle'] + ';\"' : '') +\n                    (ci.title && ci.title != \"\" ? ' title=\"' + ci.title + '\"' : '') +\n                    (ci.border && ci.border != \"0\" ? ' border=\"' + ci.border + '\"' : '') +\n                    (ci.alt && ci.alt != \"\" ? ' alt=\"' + ci.alt + '\"' : '') +\n                    (ci.hspace && ci.hspace != \"0\" ? ' hspace = \"' + ci.hspace + '\"' : '') +\n                    (ci.vspace && ci.vspace != \"0\" ? ' vspace = \"' + ci.vspace + '\"' : '') + '/>';\n                if (ci['floatStyle'] == 'center') {\n                    str = '<p style=\"text-align: center\">' + str + '</p>';\n                }\n                html.push(str);\n\n            } else {\n                for (var i = 0; ci = opt[i++];) {\n                    unhtmlData(ci);\n                    str = '<p ' + (ci['floatStyle'] == 'center' ? 'style=\"text-align: center\" ' : '') + '><img src=\"' + ci.src + '\" ' +\n                        (ci.width ? 'width=\"' + ci.width + '\" ' : '') + (ci._src ? ' _src=\"' + ci._src + '\" ' : '') +\n                        (ci.height ? ' height=\"' + ci.height + '\" ' : '') +\n                        ' style=\"' + (ci['floatStyle'] && ci['floatStyle'] != 'center' ? 'float:' + ci['floatStyle'] + ';' : '') +\n                        (ci.border || '') + '\" ' +\n                        (ci.title ? ' title=\"' + ci.title + '\"' : '') + ' /></p>';\n                    html.push(str);\n                }\n            }\n\n            me.execCommand('insertHtml', html.join(''));\n        }\n\n        me.fireEvent('afterinsertimage', opt)\n    }\n};\n\n\n// plugins/justify.js\n/**\r\n * 段落格式\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 段落对齐方式\r\n * @command justify\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @param { String } align 对齐方式：left => 居左，right => 居右，center => 居中，justify => 两端对齐\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'justify', 'center' );\r\n * ```\r\n */\r\n/**\r\n * 如果选区所在位置是段落区域，返回当前段落对齐方式\r\n * @command justify\r\n * @method queryCommandValue\r\n * @param { String } cmd 命令字符串\r\n * @return { String } 返回段落对齐方式\r\n * @example\r\n * ```javascript\r\n * editor.queryCommandValue( 'justify' );\r\n * ```\r\n */\r\n\r\nUE.plugins['justify']=function(){\r\n    var me=this,\r\n        block = domUtils.isBlockElm,\r\n        defaultValue = {\r\n            left:1,\r\n            right:1,\r\n            center:1,\r\n            justify:1\r\n        },\r\n        doJustify = function (range, style) {\r\n            var bookmark = range.createBookmark(),\r\n                filterFn = function (node) {\r\n                    return node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' && !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace(node);\r\n                };\r\n\r\n            range.enlarge(true);\r\n            var bookmark2 = range.createBookmark(),\r\n                current = domUtils.getNextDomNode(bookmark2.start, false, filterFn),\r\n                tmpRange = range.cloneRange(),\r\n                tmpNode;\r\n            while (current && !(domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING)) {\r\n                if (current.nodeType == 3 || !block(current)) {\r\n                    tmpRange.setStartBefore(current);\r\n                    while (current && current !== bookmark2.end && !block(current)) {\r\n                        tmpNode = current;\r\n                        current = domUtils.getNextDomNode(current, false, null, function (node) {\r\n                            return !block(node);\r\n                        });\r\n                    }\r\n                    tmpRange.setEndAfter(tmpNode);\r\n                    var common = tmpRange.getCommonAncestor();\r\n                    if (!domUtils.isBody(common) && block(common)) {\r\n                        domUtils.setStyles(common, utils.isString(style) ? {'text-align':style} : style);\r\n                        current = common;\r\n                    } else {\r\n                        var p = range.document.createElement('p');\r\n                        domUtils.setStyles(p, utils.isString(style) ? {'text-align':style} : style);\r\n                        var frag = tmpRange.extractContents();\r\n                        p.appendChild(frag);\r\n                        tmpRange.insertNode(p);\r\n                        current = p;\r\n                    }\r\n                    current = domUtils.getNextDomNode(current, false, filterFn);\r\n                } else {\r\n                    current = domUtils.getNextDomNode(current, true, filterFn);\r\n                }\r\n            }\r\n            return range.moveToBookmark(bookmark2).moveToBookmark(bookmark);\r\n        };\r\n\r\n    UE.commands['justify'] = {\r\n        execCommand:function (cmdName, align) {\r\n            var range = this.selection.getRange(),\r\n                txt;\r\n\r\n            //闭合时单独处理\r\n            if (range.collapsed) {\r\n                txt = this.document.createTextNode('p');\r\n                range.insertNode(txt);\r\n            }\r\n            doJustify(range, align);\r\n            if (txt) {\r\n                range.setStartBefore(txt).collapse(true);\r\n                domUtils.remove(txt);\r\n            }\r\n\r\n            range.select();\r\n\r\n\r\n            return true;\r\n        },\r\n        queryCommandValue:function () {\r\n            var startNode = this.selection.getStart(),\r\n                value = domUtils.getComputedStyle(startNode, 'text-align');\r\n            return defaultValue[value] ? value : 'left';\r\n        },\r\n        queryCommandState:function () {\r\n            var start = this.selection.getStart(),\r\n                cell = start && domUtils.findParentByTagName(start, [\"td\", \"th\",\"caption\"], true);\r\n\r\n            return cell? -1:0;\r\n        }\r\n\r\n    };\r\n};\r\n\n\n// plugins/font.js\n/**\r\n * 字体颜色,背景色,字号,字体,下划线,删除线\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 字体颜色\r\n * @command forecolor\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @param { String } value 色值(必须十六进制)\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'forecolor', '#000' );\r\n * ```\r\n */\r\n/**\r\n * 返回选区字体颜色\r\n * @command forecolor\r\n * @method queryCommandValue\r\n * @param { String } cmd 命令字符串\r\n * @return { String } 返回字体颜色\r\n * @example\r\n * ```javascript\r\n * editor.queryCommandValue( 'forecolor' );\r\n * ```\r\n */\r\n\r\n/**\r\n * 字体背景颜色\r\n * @command backcolor\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @param { String } value 色值(必须十六进制)\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'backcolor', '#000' );\r\n * ```\r\n */\r\n/**\r\n * 返回选区字体颜色\r\n * @command backcolor\r\n * @method queryCommandValue\r\n * @param { String } cmd 命令字符串\r\n * @return { String } 返回字体背景颜色\r\n * @example\r\n * ```javascript\r\n * editor.queryCommandValue( 'backcolor' );\r\n * ```\r\n */\r\n\r\n/**\r\n * 字体大小\r\n * @command fontsize\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @param { String } value 字体大小\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'fontsize', '14px' );\r\n * ```\r\n */\r\n/**\r\n * 返回选区字体大小\r\n * @command fontsize\r\n * @method queryCommandValue\r\n * @param { String } cmd 命令字符串\r\n * @return { String } 返回字体大小\r\n * @example\r\n * ```javascript\r\n * editor.queryCommandValue( 'fontsize' );\r\n * ```\r\n */\r\n\r\n/**\r\n * 字体样式\r\n * @command fontfamily\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @param { String } value 字体样式\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'fontfamily', '微软雅黑' );\r\n * ```\r\n */\r\n/**\r\n * 返回选区字体样式\r\n * @command fontfamily\r\n * @method queryCommandValue\r\n * @param { String } cmd 命令字符串\r\n * @return { String } 返回字体样式\r\n * @example\r\n * ```javascript\r\n * editor.queryCommandValue( 'fontfamily' );\r\n * ```\r\n */\r\n\r\n/**\r\n * 字体下划线,与删除线互斥\r\n * @command underline\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'underline' );\r\n * ```\r\n */\r\n\r\n/**\r\n * 字体删除线,与下划线互斥\r\n * @command strikethrough\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'strikethrough' );\r\n * ```\r\n */\r\n\r\n/**\r\n * 字体边框\r\n * @command fontborder\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'fontborder' );\r\n * ```\r\n */\r\n\r\nUE.plugins['font'] = function () {\r\n    var me = this,\r\n        fonts = {\r\n            'forecolor': 'color',\r\n            'backcolor': 'background-color',\r\n            'fontsize': 'font-size',\r\n            'fontfamily': 'font-family',\r\n            'underline': 'text-decoration',\r\n            'strikethrough': 'text-decoration',\r\n            'fontborder': 'border'\r\n        },\r\n        needCmd = {'underline': 1, 'strikethrough': 1, 'fontborder': 1},\r\n        needSetChild = {\r\n            'forecolor': 'color',\r\n            'backcolor': 'background-color',\r\n            'fontsize': 'font-size',\r\n            'fontfamily': 'font-family'\r\n\r\n        };\r\n    me.setOpt({\r\n        'fontfamily': [\r\n            { name: 'songti', val: '宋体,SimSun'},\r\n            { name: 'yahei', val: '微软雅黑,Microsoft YaHei'},\r\n            { name: 'kaiti', val: '楷体,楷体_GB2312, SimKai'},\r\n            { name: 'heiti', val: '黑体, SimHei'},\r\n            { name: 'lishu', val: '隶书, SimLi'},\r\n            { name: 'andaleMono', val: 'andale mono'},\r\n            { name: 'arial', val: 'arial, helvetica,sans-serif'},\r\n            { name: 'arialBlack', val: 'arial black,avant garde'},\r\n            { name: 'comicSansMs', val: 'comic sans ms'},\r\n            { name: 'impact', val: 'impact,chicago'},\r\n            { name: 'timesNewRoman', val: 'times new roman'}\r\n        ],\r\n        'fontsize': [10, 11, 12, 14, 16, 18, 20, 24, 36]\r\n    });\r\n\r\n    function mergeWithParent(node){\r\n        var parent;\r\n        while(parent = node.parentNode){\r\n            if(parent.tagName == 'SPAN' && domUtils.getChildCount(parent,function(child){\r\n                return !domUtils.isBookmarkNode(child) && !domUtils.isBr(child)\r\n            }) == 1) {\r\n                parent.style.cssText += node.style.cssText;\r\n                domUtils.remove(node,true);\r\n                node = parent;\r\n\r\n            }else{\r\n                break;\r\n            }\r\n        }\r\n\r\n    }\r\n    function mergeChild(rng,cmdName,value){\r\n        if(needSetChild[cmdName]){\r\n            rng.adjustmentBoundary();\r\n            if(!rng.collapsed && rng.startContainer.nodeType == 1){\r\n                var start = rng.startContainer.childNodes[rng.startOffset];\r\n                if(start && domUtils.isTagNode(start,'span')){\r\n                    var bk = rng.createBookmark();\r\n                    utils.each(domUtils.getElementsByTagName(start, 'span'), function (span) {\r\n                        if (!span.parentNode || domUtils.isBookmarkNode(span))return;\r\n                        if(cmdName == 'backcolor' && domUtils.getComputedStyle(span,'background-color').toLowerCase() === value){\r\n                            return;\r\n                        }\r\n                        domUtils.removeStyle(span,needSetChild[cmdName]);\r\n                        if(span.style.cssText.replace(/^\\s+$/,'').length == 0){\r\n                            domUtils.remove(span,true)\r\n                        }\r\n                    });\r\n                    rng.moveToBookmark(bk)\r\n                }\r\n            }\r\n        }\r\n\r\n    }\r\n    function mergesibling(rng,cmdName,value) {\r\n        var collapsed = rng.collapsed,\r\n            bk = rng.createBookmark(), common;\r\n        if (collapsed) {\r\n            common = bk.start.parentNode;\r\n            while (dtd.$inline[common.tagName]) {\r\n                common = common.parentNode;\r\n            }\r\n        } else {\r\n            common = domUtils.getCommonAncestor(bk.start, bk.end);\r\n        }\r\n        utils.each(domUtils.getElementsByTagName(common, 'span'), function (span) {\r\n            if (!span.parentNode || domUtils.isBookmarkNode(span))return;\r\n            if (/\\s*border\\s*:\\s*none;?\\s*/i.test(span.style.cssText)) {\r\n                if(/^\\s*border\\s*:\\s*none;?\\s*$/.test(span.style.cssText)){\r\n                    domUtils.remove(span, true);\r\n                }else{\r\n                    domUtils.removeStyle(span,'border');\r\n                }\r\n                return\r\n            }\r\n            if (/border/i.test(span.style.cssText) && span.parentNode.tagName == 'SPAN' && /border/i.test(span.parentNode.style.cssText)) {\r\n                span.style.cssText = span.style.cssText.replace(/border[^:]*:[^;]+;?/gi, '');\r\n            }\r\n            if(!(cmdName=='fontborder' && value=='none')){\r\n                var next = span.nextSibling;\r\n                while (next && next.nodeType == 1 && next.tagName == 'SPAN' ) {\r\n                    if(domUtils.isBookmarkNode(next) && cmdName == 'fontborder') {\r\n                        span.appendChild(next);\r\n                        next = span.nextSibling;\r\n                        continue;\r\n                    }\r\n                    if (next.style.cssText == span.style.cssText) {\r\n                        domUtils.moveChild(next, span);\r\n                        domUtils.remove(next);\r\n                    }\r\n                    if (span.nextSibling === next)\r\n                        break;\r\n                    next = span.nextSibling;\r\n                }\r\n            }\r\n\r\n\r\n            mergeWithParent(span);\r\n            if(browser.ie && browser.version > 8 ){\r\n                //拷贝父亲们的特别的属性,这里只做背景颜色的处理\r\n                var parent = domUtils.findParent(span,function(n){return n.tagName == 'SPAN' && /background-color/.test(n.style.cssText)});\r\n                if(parent && !/background-color/.test(span.style.cssText)){\r\n                    span.style.backgroundColor = parent.style.backgroundColor;\r\n                }\r\n            }\r\n\r\n        });\r\n        rng.moveToBookmark(bk);\r\n        mergeChild(rng,cmdName,value)\r\n    }\r\n\r\n    me.addInputRule(function (root) {\r\n        utils.each(root.getNodesByTagName('u s del font strike'), function (node) {\r\n            if (node.tagName == 'font') {\r\n                var cssStyle = [];\r\n                for (var p in node.attrs) {\r\n                    switch (p) {\r\n                        case 'size':\r\n                            cssStyle.push('font-size:' +\r\n                                ({\r\n                                '1':'10',\r\n                                '2':'12',\r\n                                '3':'16',\r\n                                '4':'18',\r\n                                '5':'24',\r\n                                '6':'32',\r\n                                '7':'48'\r\n                            }[node.attrs[p]] || node.attrs[p]) + 'px');\r\n                            break;\r\n                        case 'color':\r\n                            cssStyle.push('color:' + node.attrs[p]);\r\n                            break;\r\n                        case 'face':\r\n                            cssStyle.push('font-family:' + node.attrs[p]);\r\n                            break;\r\n                        case 'style':\r\n                            cssStyle.push(node.attrs[p]);\r\n                    }\r\n                }\r\n                node.attrs = {\r\n                    'style': cssStyle.join(';')\r\n                };\r\n            } else {\r\n                var val = node.tagName == 'u' ? 'underline' : 'line-through';\r\n                node.attrs = {\r\n                    'style': (node.getAttr('style') || '') + 'text-decoration:' + val + ';'\r\n                }\r\n            }\r\n            node.tagName = 'span';\r\n        });\r\n//        utils.each(root.getNodesByTagName('span'), function (node) {\r\n//            var val;\r\n//            if(val = node.getAttr('class')){\r\n//                if(/fontstrikethrough/.test(val)){\r\n//                    node.setStyle('text-decoration','line-through');\r\n//                    if(node.attrs['class']){\r\n//                        node.attrs['class'] = node.attrs['class'].replace(/fontstrikethrough/,'');\r\n//                    }else{\r\n//                        node.setAttr('class')\r\n//                    }\r\n//                }\r\n//                if(/fontborder/.test(val)){\r\n//                    node.setStyle('border','1px solid #000');\r\n//                    if(node.attrs['class']){\r\n//                        node.attrs['class'] = node.attrs['class'].replace(/fontborder/,'');\r\n//                    }else{\r\n//                        node.setAttr('class')\r\n//                    }\r\n//                }\r\n//            }\r\n//        });\r\n    });\r\n//    me.addOutputRule(function(root){\r\n//        utils.each(root.getNodesByTagName('span'), function (node) {\r\n//            var val;\r\n//            if(val = node.getStyle('text-decoration')){\r\n//                if(/line-through/.test(val)){\r\n//                    if(node.attrs['class']){\r\n//                        node.attrs['class'] += ' fontstrikethrough';\r\n//                    }else{\r\n//                        node.setAttr('class','fontstrikethrough')\r\n//                    }\r\n//                }\r\n//\r\n//                node.setStyle('text-decoration')\r\n//            }\r\n//            if(val = node.getStyle('border')){\r\n//                if(/1px/.test(val) && /solid/.test(val)){\r\n//                    if(node.attrs['class']){\r\n//                        node.attrs['class'] += ' fontborder';\r\n//\r\n//                    }else{\r\n//                        node.setAttr('class','fontborder')\r\n//                    }\r\n//                }\r\n//                node.setStyle('border')\r\n//\r\n//            }\r\n//        });\r\n//    });\r\n    for (var p in fonts) {\r\n        (function (cmd, style) {\r\n            UE.commands[cmd] = {\r\n                execCommand: function (cmdName, value) {\r\n                    value = value || (this.queryCommandState(cmdName) ? 'none' : cmdName == 'underline' ? 'underline' :\r\n                        cmdName == 'fontborder' ? '1px solid #000' :\r\n                            'line-through');\r\n                    var me = this,\r\n                        range = this.selection.getRange(),\r\n                        text;\r\n\r\n                    if (value == 'default') {\r\n\r\n                        if (range.collapsed) {\r\n                            text = me.document.createTextNode('font');\r\n                            range.insertNode(text).select();\r\n\r\n                        }\r\n                        me.execCommand('removeFormat', 'span,a', style);\r\n                        if (text) {\r\n                            range.setStartBefore(text).collapse(true);\r\n                            domUtils.remove(text);\r\n                        }\r\n                        mergesibling(range,cmdName,value);\r\n                        range.select()\r\n                    } else {\r\n                        if (!range.collapsed) {\r\n                            if (needCmd[cmd] && me.queryCommandValue(cmd)) {\r\n                                me.execCommand('removeFormat', 'span,a', style);\r\n                            }\r\n                            range = me.selection.getRange();\r\n\r\n                            range.applyInlineStyle('span', {'style': style + ':' + value});\r\n                            mergesibling(range, cmdName,value);\r\n                            range.select();\r\n                        } else {\r\n\r\n                            var span = domUtils.findParentByTagName(range.startContainer, 'span', true);\r\n                            text = me.document.createTextNode('font');\r\n                            if (span && !span.children.length && !span[browser.ie ? 'innerText' : 'textContent'].replace(fillCharReg, '').length) {\r\n                                //for ie hack when enter\r\n                                range.insertNode(text);\r\n                                if (needCmd[cmd]) {\r\n                                    range.selectNode(text).select();\r\n                                    me.execCommand('removeFormat', 'span,a', style, null);\r\n\r\n                                    span = domUtils.findParentByTagName(text, 'span', true);\r\n                                    range.setStartBefore(text);\r\n\r\n                                }\r\n                                span && (span.style.cssText += ';' + style + ':' + value);\r\n                                range.collapse(true).select();\r\n\r\n\r\n                            } else {\r\n                                range.insertNode(text);\r\n                                range.selectNode(text).select();\r\n                                span = range.document.createElement('span');\r\n\r\n                                if (needCmd[cmd]) {\r\n                                    //a标签内的不处理跳过\r\n                                    if (domUtils.findParentByTagName(text, 'a', true)) {\r\n                                        range.setStartBefore(text).setCursor();\r\n                                        domUtils.remove(text);\r\n                                        return;\r\n                                    }\r\n                                    me.execCommand('removeFormat', 'span,a', style);\r\n                                }\r\n\r\n                                span.style.cssText = style + ':' + value;\r\n\r\n\r\n                                text.parentNode.insertBefore(span, text);\r\n                                //修复，span套span 但样式不继承的问题\r\n                                if (!browser.ie || browser.ie && browser.version == 9) {\r\n                                    var spanParent = span.parentNode;\r\n                                    while (!domUtils.isBlockElm(spanParent)) {\r\n                                        if (spanParent.tagName == 'SPAN') {\r\n                                            //opera合并style不会加入\";\"\r\n                                            span.style.cssText = spanParent.style.cssText + \";\" + span.style.cssText;\r\n                                        }\r\n                                        spanParent = spanParent.parentNode;\r\n                                    }\r\n                                }\r\n\r\n\r\n                                if (opera) {\r\n                                    setTimeout(function () {\r\n                                        range.setStart(span, 0).collapse(true);\r\n                                        mergesibling(range, cmdName,value);\r\n                                        range.select();\r\n                                    });\r\n                                } else {\r\n                                    range.setStart(span, 0).collapse(true);\r\n                                    mergesibling(range,cmdName,value);\r\n                                    range.select();\r\n                                }\r\n\r\n                                //trace:981\r\n                                //domUtils.mergeToParent(span)\r\n                            }\r\n                            domUtils.remove(text);\r\n                        }\r\n\r\n\r\n                    }\r\n                    return true;\r\n                },\r\n                queryCommandValue: function (cmdName) {\r\n                    var startNode = this.selection.getStart();\r\n\r\n                    //trace:946\r\n                    if (cmdName == 'underline' || cmdName == 'strikethrough') {\r\n                        var tmpNode = startNode, value;\r\n                        while (tmpNode && !domUtils.isBlockElm(tmpNode) && !domUtils.isBody(tmpNode)) {\r\n                            if (tmpNode.nodeType == 1) {\r\n                                value = domUtils.getComputedStyle(tmpNode, style);\r\n                                if (value != 'none') {\r\n                                    return value;\r\n                                }\r\n                            }\r\n\r\n                            tmpNode = tmpNode.parentNode;\r\n                        }\r\n                        return 'none';\r\n                    }\r\n                    if (cmdName == 'fontborder') {\r\n                        var tmp = startNode, val;\r\n                        while (tmp && dtd.$inline[tmp.tagName]) {\r\n                            if (val = domUtils.getComputedStyle(tmp, 'border')) {\r\n\r\n                                if (/1px/.test(val) && /solid/.test(val)) {\r\n                                    return val;\r\n                                }\r\n                            }\r\n                            tmp = tmp.parentNode;\r\n                        }\r\n                        return ''\r\n                    }\r\n\r\n                    if( cmdName == 'FontSize' ) {\r\n                        var styleVal = domUtils.getComputedStyle(startNode, style),\r\n                            tmp = /^([\\d\\.]+)(\\w+)$/.exec( styleVal );\r\n\r\n                        if( tmp ) {\r\n\r\n                            return Math.floor( tmp[1] ) + tmp[2];\r\n\r\n                        }\r\n\r\n                        return styleVal;\r\n\r\n                    }\r\n\r\n                    return  domUtils.getComputedStyle(startNode, style);\r\n                },\r\n                queryCommandState: function (cmdName) {\r\n                    if (!needCmd[cmdName])\r\n                        return 0;\r\n                    var val = this.queryCommandValue(cmdName);\r\n                    if (cmdName == 'fontborder') {\r\n                        return /1px/.test(val) && /solid/.test(val)\r\n                    } else {\r\n                        return  cmdName == 'underline' ? /underline/.test(val) : /line\\-through/.test(val);\r\n\r\n                    }\r\n\r\n                }\r\n            };\r\n        })(p, fonts[p]);\r\n    }\r\n};\n\n// plugins/link.js\n/**\r\n * 超链接\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 插入超链接\r\n * @command link\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @param { Object } options   设置自定义属性，例如：url、title、target\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'link', '{\r\n *     url:'ueditor.baidu.com',\r\n *     title:'ueditor',\r\n *     target:'_blank'\r\n * }' );\r\n * ```\r\n */\r\n/**\r\n * 返回当前选中的第一个超链接节点\r\n * @command link\r\n * @method queryCommandValue\r\n * @param { String } cmd 命令字符串\r\n * @return { Element } 超链接节点\r\n * @example\r\n * ```javascript\r\n * editor.queryCommandValue( 'link' );\r\n * ```\r\n */\r\n\r\n/**\r\n * 取消超链接\r\n * @command unlink\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'unlink');\r\n * ```\r\n */\r\n\r\nUE.plugins['link'] = function(){\r\n    function optimize( range ) {\r\n        var start = range.startContainer,end = range.endContainer;\r\n\r\n        if ( start = domUtils.findParentByTagName( start, 'a', true ) ) {\r\n            range.setStartBefore( start );\r\n        }\r\n        if ( end = domUtils.findParentByTagName( end, 'a', true ) ) {\r\n            range.setEndAfter( end );\r\n        }\r\n    }\r\n\r\n\r\n    UE.commands['unlink'] = {\r\n        execCommand : function() {\r\n            var range = this.selection.getRange(),\r\n                bookmark;\r\n            if(range.collapsed && !domUtils.findParentByTagName( range.startContainer, 'a', true )){\r\n                return;\r\n            }\r\n            bookmark = range.createBookmark();\r\n            optimize( range );\r\n            range.removeInlineStyle( 'a' ).moveToBookmark( bookmark ).select();\r\n        },\r\n        queryCommandState : function(){\r\n            return !this.highlight && this.queryCommandValue('link') ?  0 : -1;\r\n        }\r\n\r\n    };\r\n    function doLink(range,opt,me){\r\n        var rngClone = range.cloneRange(),\r\n            link = me.queryCommandValue('link');\r\n        optimize( range = range.adjustmentBoundary() );\r\n        var start = range.startContainer;\r\n        if(start.nodeType == 1 && link){\r\n            start = start.childNodes[range.startOffset];\r\n            if(start && start.nodeType == 1 && start.tagName == 'A' && /^(?:https?|ftp|file)\\s*:\\s*\\/\\//.test(start[browser.ie?'innerText':'textContent'])){\r\n                start[browser.ie ? 'innerText' : 'textContent'] =  utils.html(opt.textValue||opt.href);\r\n\r\n            }\r\n        }\r\n        if( !rngClone.collapsed || link){\r\n            range.removeInlineStyle( 'a' );\r\n            rngClone = range.cloneRange();\r\n        }\r\n\r\n        if ( rngClone.collapsed ) {\r\n            var a = range.document.createElement( 'a'),\r\n                text = '';\r\n            if(opt.textValue){\r\n\r\n                text =   utils.html(opt.textValue);\r\n                delete opt.textValue;\r\n            }else{\r\n                text =   utils.html(opt.href);\r\n\r\n            }\r\n            domUtils.setAttributes( a, opt );\r\n            start =  domUtils.findParentByTagName( rngClone.startContainer, 'a', true );\r\n            if(start && domUtils.isInNodeEndBoundary(rngClone,start)){\r\n                range.setStartAfter(start).collapse(true);\r\n\r\n            }\r\n            a[browser.ie ? 'innerText' : 'textContent'] = text;\r\n            range.insertNode(a).selectNode( a );\r\n        } else {\r\n            range.applyInlineStyle( 'a', opt );\r\n\r\n        }\r\n    }\r\n    UE.commands['link'] = {\r\n        execCommand : function( cmdName, opt ) {\r\n            var range;\r\n            opt._href && (opt._href = utils.unhtml(opt._href,/[<\">]/g));\r\n            opt.href && (opt.href = utils.unhtml(opt.href,/[<\">]/g));\r\n            opt.textValue && (opt.textValue = utils.unhtml(opt.textValue,/[<\">]/g));\r\n            doLink(range=this.selection.getRange(),opt,this);\r\n            //闭合都不加占位符，如果加了会在a后边多个占位符节点，导致a是图片背景组成的列表，出现空白问题\r\n            range.collapse().select(true);\r\n\r\n        },\r\n        queryCommandValue : function() {\r\n            var range = this.selection.getRange(),\r\n                node;\r\n            if ( range.collapsed ) {\r\n//                    node = this.selection.getStart();\r\n                //在ie下getstart()取值偏上了\r\n                node = range.startContainer;\r\n                node = node.nodeType == 1 ? node : node.parentNode;\r\n\r\n                if ( node && (node = domUtils.findParentByTagName( node, 'a', true )) && ! domUtils.isInNodeEndBoundary(range,node)) {\r\n\r\n                    return node;\r\n                }\r\n            } else {\r\n                //trace:1111  如果是<p><a>xx</a></p> startContainer是p就会找不到a\r\n                range.shrinkBoundary();\r\n                var start = range.startContainer.nodeType  == 3 || !range.startContainer.childNodes[range.startOffset] ? range.startContainer : range.startContainer.childNodes[range.startOffset],\r\n                    end =  range.endContainer.nodeType == 3 || range.endOffset == 0 ? range.endContainer : range.endContainer.childNodes[range.endOffset-1],\r\n                    common = range.getCommonAncestor();\r\n                node = domUtils.findParentByTagName( common, 'a', true );\r\n                if ( !node && common.nodeType == 1){\r\n\r\n                    var as = common.getElementsByTagName( 'a' ),\r\n                        ps,pe;\r\n\r\n                    for ( var i = 0,ci; ci = as[i++]; ) {\r\n                        ps = domUtils.getPosition( ci, start ),pe = domUtils.getPosition( ci,end);\r\n                        if ( (ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS)\r\n                            &&\r\n                            (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS)\r\n                            ) {\r\n                            node = ci;\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n                return node;\r\n            }\r\n\r\n        },\r\n        queryCommandState : function() {\r\n            //判断如果是视频的话连接不可用\r\n            //fix 853\r\n            var img = this.selection.getRange().getClosedNode(),\r\n                flag = img && (img.className == \"edui-faked-video\" || img.className.indexOf(\"edui-upload-video\")!=-1);\r\n            return flag ? -1 : 0;\r\n        }\r\n    };\r\n};\n\n// plugins/iframe.js\n///import core\n///import plugins\\inserthtml.js\n///commands 插入框架\n///commandsName  InsertFrame\n///commandsTitle  插入Iframe\n///commandsDialog  dialogs\\insertframe\n\nUE.plugins['insertframe'] = function() {\n   var me =this;\n    function deleteIframe(){\n        me._iframe && delete me._iframe;\n    }\n\n    me.addListener(\"selectionchange\",function(){\n        deleteIframe();\n    });\n\n};\n\n\n\n// plugins/scrawl.js\n///import core\r\n///commands 涂鸦\r\n///commandsName  Scrawl\r\n///commandsTitle  涂鸦\r\n///commandsDialog  dialogs\\scrawl\r\nUE.commands['scrawl'] = {\r\n    queryCommandState : function(){\r\n        return ( browser.ie && browser.version  <= 8 ) ? -1 :0;\r\n    }\r\n};\r\n\n\n// plugins/removeformat.js\n/**\r\n * 清除格式\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 清除文字样式\r\n * @command removeformat\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @param   {String}   tags     以逗号隔开的标签。如：strong\r\n * @param   {String}   style    样式如：color\r\n * @param   {String}   attrs    属性如:width\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'removeformat', 'strong','color','width' );\r\n * ```\r\n */\r\n\r\nUE.plugins['removeformat'] = function(){\r\n    var me = this;\r\n    me.setOpt({\r\n       'removeFormatTags': 'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var',\r\n       'removeFormatAttributes':'class,style,lang,width,height,align,hspace,valign'\r\n    });\r\n    me.commands['removeformat'] = {\r\n        execCommand : function( cmdName, tags, style, attrs,notIncludeA ) {\r\n\r\n            var tagReg = new RegExp( '^(?:' + (tags || this.options.removeFormatTags).replace( /,/g, '|' ) + ')$', 'i' ) ,\r\n                removeFormatAttributes = style ? [] : (attrs || this.options.removeFormatAttributes).split( ',' ),\r\n                range = new dom.Range( this.document ),\r\n                bookmark,node,parent,\r\n                filter = function( node ) {\r\n                    return node.nodeType == 1;\r\n                };\r\n\r\n            function isRedundantSpan (node) {\r\n                if (node.nodeType == 3 || node.tagName.toLowerCase() != 'span'){\r\n                    return 0;\r\n                }\r\n                if (browser.ie) {\r\n                    //ie 下判断实效，所以只能简单用style来判断\r\n                    //return node.style.cssText == '' ? 1 : 0;\r\n                    var attrs = node.attributes;\r\n                    if ( attrs.length ) {\r\n                        for ( var i = 0,l = attrs.length; i<l; i++ ) {\r\n                            if ( attrs[i].specified ) {\r\n                                return 0;\r\n                            }\r\n                        }\r\n                        return 1;\r\n                    }\r\n                }\r\n                return !node.attributes.length;\r\n            }\r\n            function doRemove( range ) {\r\n\r\n                var bookmark1 = range.createBookmark();\r\n                if ( range.collapsed ) {\r\n                    range.enlarge( true );\r\n                }\r\n\r\n                //不能把a标签切了\r\n                if(!notIncludeA){\r\n                    var aNode = domUtils.findParentByTagName(range.startContainer,'a',true);\r\n                    if(aNode){\r\n                        range.setStartBefore(aNode);\r\n                    }\r\n\r\n                    aNode = domUtils.findParentByTagName(range.endContainer,'a',true);\r\n                    if(aNode){\r\n                        range.setEndAfter(aNode);\r\n                    }\r\n\r\n                }\r\n\r\n\r\n                bookmark = range.createBookmark();\r\n\r\n                node = bookmark.start;\r\n\r\n                //切开始\r\n                while ( (parent = node.parentNode) && !domUtils.isBlockElm( parent ) ) {\r\n                    domUtils.breakParent( node, parent );\r\n\r\n                    domUtils.clearEmptySibling( node );\r\n                }\r\n                if ( bookmark.end ) {\r\n                    //切结束\r\n                    node = bookmark.end;\r\n                    while ( (parent = node.parentNode) && !domUtils.isBlockElm( parent ) ) {\r\n                        domUtils.breakParent( node, parent );\r\n                        domUtils.clearEmptySibling( node );\r\n                    }\r\n\r\n                    //开始去除样式\r\n                    var current = domUtils.getNextDomNode( bookmark.start, false, filter ),\r\n                        next;\r\n                    while ( current ) {\r\n                        if ( current == bookmark.end ) {\r\n                            break;\r\n                        }\r\n\r\n                        next = domUtils.getNextDomNode( current, true, filter );\r\n\r\n                        if ( !dtd.$empty[current.tagName.toLowerCase()] && !domUtils.isBookmarkNode( current ) ) {\r\n                            if ( tagReg.test( current.tagName ) ) {\r\n                                if ( style ) {\r\n                                    domUtils.removeStyle( current, style );\r\n                                    if ( isRedundantSpan( current ) && style != 'text-decoration'){\r\n                                        domUtils.remove( current, true );\r\n                                    }\r\n                                } else {\r\n                                    domUtils.remove( current, true );\r\n                                }\r\n                            } else {\r\n                                //trace:939  不能把list上的样式去掉\r\n                                if(!dtd.$tableContent[current.tagName] && !dtd.$list[current.tagName]){\r\n                                    domUtils.removeAttributes( current, removeFormatAttributes );\r\n                                    if ( isRedundantSpan( current ) ){\r\n                                        domUtils.remove( current, true );\r\n                                    }\r\n                                }\r\n\r\n                            }\r\n                        }\r\n                        current = next;\r\n                    }\r\n                }\r\n                //trace:1035\r\n                //trace:1096 不能把td上的样式去掉，比如边框\r\n                var pN = bookmark.start.parentNode;\r\n                if(domUtils.isBlockElm(pN) && !dtd.$tableContent[pN.tagName] && !dtd.$list[pN.tagName]){\r\n                    domUtils.removeAttributes(  pN,removeFormatAttributes );\r\n                }\r\n                pN = bookmark.end.parentNode;\r\n                if(bookmark.end && domUtils.isBlockElm(pN) && !dtd.$tableContent[pN.tagName]&& !dtd.$list[pN.tagName]){\r\n                    domUtils.removeAttributes(  pN,removeFormatAttributes );\r\n                }\r\n                range.moveToBookmark( bookmark ).moveToBookmark(bookmark1);\r\n                //清除冗余的代码 <b><bookmark></b>\r\n                var node = range.startContainer,\r\n                    tmp,\r\n                    collapsed = range.collapsed;\r\n                while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){\r\n                    tmp = node.parentNode;\r\n                    range.setStartBefore(node);\r\n                    //trace:937\r\n                    //更新结束边界\r\n                    if(range.startContainer === range.endContainer){\r\n                        range.endOffset--;\r\n                    }\r\n                    domUtils.remove(node);\r\n                    node = tmp;\r\n                }\r\n\r\n                if(!collapsed){\r\n                    node = range.endContainer;\r\n                    while(node.nodeType == 1 && domUtils.isEmptyNode(node) && dtd.$removeEmpty[node.tagName]){\r\n                        tmp = node.parentNode;\r\n                        range.setEndBefore(node);\r\n                        domUtils.remove(node);\r\n\r\n                        node = tmp;\r\n                    }\r\n\r\n\r\n                }\r\n            }\r\n\r\n\r\n\r\n            range = this.selection.getRange();\r\n            doRemove( range );\r\n            range.select();\r\n\r\n        }\r\n\r\n    };\r\n\r\n};\r\n\n\n// plugins/blockquote.js\n/**\r\n * 添加引用\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 添加引用\r\n * @command blockquote\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'blockquote' );\r\n * ```\r\n */\r\n\r\n/**\r\n * 添加引用\r\n * @command blockquote\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @param { Object } attrs 节点属性\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'blockquote',{\r\n *     style: \"color: red;\"\r\n * } );\r\n * ```\r\n */\r\n\r\n\r\nUE.plugins['blockquote'] = function(){\r\n    var me = this;\r\n    function getObj(editor){\r\n        return domUtils.filterNodeList(editor.selection.getStartElementPath(),'blockquote');\r\n    }\r\n    me.commands['blockquote'] = {\r\n        execCommand : function( cmdName, attrs ) {\r\n            var range = this.selection.getRange(),\r\n                obj = getObj(this),\r\n                blockquote = dtd.blockquote,\r\n                bookmark = range.createBookmark();\r\n\r\n            if ( obj ) {\r\n\r\n                    var start = range.startContainer,\r\n                        startBlock = domUtils.isBlockElm(start) ? start : domUtils.findParent(start,function(node){return domUtils.isBlockElm(node)}),\r\n\r\n                        end = range.endContainer,\r\n                        endBlock = domUtils.isBlockElm(end) ? end :  domUtils.findParent(end,function(node){return domUtils.isBlockElm(node)});\r\n\r\n                    //处理一下li\r\n                    startBlock = domUtils.findParentByTagName(startBlock,'li',true) || startBlock;\r\n                    endBlock = domUtils.findParentByTagName(endBlock,'li',true) || endBlock;\r\n\r\n\r\n                    if(startBlock.tagName == 'LI' || startBlock.tagName == 'TD' || startBlock === obj || domUtils.isBody(startBlock)){\r\n                        domUtils.remove(obj,true);\r\n                    }else{\r\n                        domUtils.breakParent(startBlock,obj);\r\n                    }\r\n\r\n                    if(startBlock !== endBlock){\r\n                        obj = domUtils.findParentByTagName(endBlock,'blockquote');\r\n                        if(obj){\r\n                            if(endBlock.tagName == 'LI' || endBlock.tagName == 'TD'|| domUtils.isBody(endBlock)){\r\n                                obj.parentNode && domUtils.remove(obj,true);\r\n                            }else{\r\n                                domUtils.breakParent(endBlock,obj);\r\n                            }\r\n\r\n                        }\r\n                    }\r\n\r\n                    var blockquotes = domUtils.getElementsByTagName(this.document,'blockquote');\r\n                    for(var i=0,bi;bi=blockquotes[i++];){\r\n                        if(!bi.childNodes.length){\r\n                            domUtils.remove(bi);\r\n                        }else if(domUtils.getPosition(bi,startBlock)&domUtils.POSITION_FOLLOWING && domUtils.getPosition(bi,endBlock)&domUtils.POSITION_PRECEDING){\r\n                            domUtils.remove(bi,true);\r\n                        }\r\n                    }\r\n\r\n\r\n\r\n\r\n            } else {\r\n\r\n                var tmpRange = range.cloneRange(),\r\n                    node = tmpRange.startContainer.nodeType == 1 ? tmpRange.startContainer : tmpRange.startContainer.parentNode,\r\n                    preNode = node,\r\n                    doEnd = 1;\r\n\r\n                //调整开始\r\n                while ( 1 ) {\r\n                    if ( domUtils.isBody(node) ) {\r\n                        if ( preNode !== node ) {\r\n                            if ( range.collapsed ) {\r\n                                tmpRange.selectNode( preNode );\r\n                                doEnd = 0;\r\n                            } else {\r\n                                tmpRange.setStartBefore( preNode );\r\n                            }\r\n                        }else{\r\n                            tmpRange.setStart(node,0);\r\n                        }\r\n\r\n                        break;\r\n                    }\r\n                    if ( !blockquote[node.tagName] ) {\r\n                        if ( range.collapsed ) {\r\n                            tmpRange.selectNode( preNode );\r\n                        } else{\r\n                            tmpRange.setStartBefore( preNode);\r\n                        }\r\n                        break;\r\n                    }\r\n\r\n                    preNode = node;\r\n                    node = node.parentNode;\r\n                }\r\n\r\n                //调整结束\r\n                if ( doEnd ) {\r\n                    preNode = node =  node = tmpRange.endContainer.nodeType == 1 ? tmpRange.endContainer : tmpRange.endContainer.parentNode;\r\n                    while ( 1 ) {\r\n\r\n                        if ( domUtils.isBody( node ) ) {\r\n                            if ( preNode !== node ) {\r\n\r\n                                tmpRange.setEndAfter( preNode );\r\n\r\n                            } else {\r\n                                tmpRange.setEnd( node, node.childNodes.length );\r\n                            }\r\n\r\n                            break;\r\n                        }\r\n                        if ( !blockquote[node.tagName] ) {\r\n                            tmpRange.setEndAfter( preNode );\r\n                            break;\r\n                        }\r\n\r\n                        preNode = node;\r\n                        node = node.parentNode;\r\n                    }\r\n\r\n                }\r\n\r\n\r\n                node = range.document.createElement( 'blockquote' );\r\n                domUtils.setAttributes( node, attrs );\r\n                node.appendChild( tmpRange.extractContents() );\r\n                tmpRange.insertNode( node );\r\n                //去除重复的\r\n                var childs = domUtils.getElementsByTagName(node,'blockquote');\r\n                for(var i=0,ci;ci=childs[i++];){\r\n                    if(ci.parentNode){\r\n                        domUtils.remove(ci,true);\r\n                    }\r\n                }\r\n\r\n            }\r\n            range.moveToBookmark( bookmark ).select();\r\n        },\r\n        queryCommandState : function() {\r\n            return getObj(this) ? 1 : 0;\r\n        }\r\n    };\r\n};\r\n\r\n\n\n// plugins/convertcase.js\n/**\r\n * 大小写转换\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 把选区内文本变大写，与“tolowercase”命令互斥\r\n * @command touppercase\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'touppercase' );\r\n * ```\r\n */\r\n\r\n/**\r\n * 把选区内文本变小写，与“touppercase”命令互斥\r\n * @command tolowercase\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'tolowercase' );\r\n * ```\r\n */\r\nUE.commands['touppercase'] =\r\nUE.commands['tolowercase'] = {\r\n    execCommand:function (cmd) {\r\n        var me = this;\r\n        var rng = me.selection.getRange();\r\n        if(rng.collapsed){\r\n            return rng;\r\n        }\r\n        var bk = rng.createBookmark(),\r\n            bkEnd = bk.end,\r\n            filterFn = function( node ) {\r\n                return !domUtils.isBr(node) && !domUtils.isWhitespace( node );\r\n            },\r\n            curNode = domUtils.getNextDomNode( bk.start, false, filterFn );\r\n        while ( curNode && (domUtils.getPosition( curNode, bkEnd ) & domUtils.POSITION_PRECEDING) ) {\r\n\r\n            if ( curNode.nodeType == 3 ) {\r\n                curNode.nodeValue = curNode.nodeValue[cmd == 'touppercase' ? 'toUpperCase' : 'toLowerCase']();\r\n            }\r\n            curNode = domUtils.getNextDomNode( curNode, true, filterFn );\r\n            if(curNode === bkEnd){\r\n                break;\r\n            }\r\n\r\n        }\r\n        rng.moveToBookmark(bk).select();\r\n    }\r\n};\r\n\r\n\n\n// plugins/indent.js\n/**\r\n * 首行缩进\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 缩进\r\n * @command indent\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'indent' );\r\n * ```\r\n */\r\nUE.commands['indent'] = {\r\n    execCommand : function() {\r\n         var me = this,value = me.queryCommandState(\"indent\") ? \"0em\" : (me.options.indentValue || '2em');\r\n         me.execCommand('Paragraph','p',{style:'text-indent:'+ value});\r\n    },\r\n    queryCommandState : function() {\r\n        var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),'p h1 h2 h3 h4 h5 h6');\r\n        return pN && pN.style.textIndent && parseInt(pN.style.textIndent) ?  1 : 0;\r\n    }\r\n\r\n};\r\n\n\n// plugins/print.js\n/**\r\n * 打印\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 打印\r\n * @command print\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'print' );\r\n * ```\r\n */\r\nUE.commands['print'] = {\r\n    execCommand : function(){\r\n        this.window.print();\r\n    },\r\n    notNeedUndo : 1\r\n};\r\n\r\n\n\n// plugins/preview.js\n/**\n * 预览\n * @file\n * @since 1.2.6.1\n */\n\n/**\n * 预览\n * @command preview\n * @method execCommand\n * @param { String } cmd 命令字符串\n * @example\n * ```javascript\n * editor.execCommand( 'preview' );\n * ```\n */\nUE.commands['preview'] = {\n    execCommand : function(){\n        var w = window.open('', '_blank', ''),\n            d = w.document;\n        d.open();\n        d.write('<!DOCTYPE html><html><head><meta charset=\"utf-8\"/><script src=\"'+this.options.UEDITOR_HOME_URL+'ueditor.parse.js\"></script><script>' +\n            \"setTimeout(function(){uParse('div',{rootPath: '\"+ this.options.UEDITOR_HOME_URL +\"'})},300)\" +\n            '</script></head><body><div>'+this.getContent(null,null,true)+'</div></body></html>');\n        d.close();\n    },\n    notNeedUndo : 1\n};\n\n\n// plugins/selectall.js\n/**\r\n * 全选\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 选中所有内容\r\n * @command selectall\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'selectall' );\r\n * ```\r\n */\r\nUE.plugins['selectall'] = function(){\r\n    var me = this;\r\n    me.commands['selectall'] = {\r\n        execCommand : function(){\r\n            //去掉了原生的selectAll,因为会出现报错和当内容为空时，不能出现闭合状态的光标\r\n            var me = this,body = me.body,\r\n                range = me.selection.getRange();\r\n            range.selectNodeContents(body);\r\n            if(domUtils.isEmptyBlock(body)){\r\n                //opera不能自动合并到元素的里边，要手动处理一下\r\n                if(browser.opera && body.firstChild && body.firstChild.nodeType == 1){\r\n                    range.setStartAtFirst(body.firstChild);\r\n                }\r\n                range.collapse(true);\r\n            }\r\n            range.select(true);\r\n        },\r\n        notNeedUndo : 1\r\n    };\r\n\r\n\r\n    //快捷键\r\n    me.addshortcutkey({\r\n         \"selectAll\" : \"ctrl+65\"\r\n    });\r\n};\r\n\n\n// plugins/paragraph.js\n/**\r\n * 段落样式\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 段落格式\r\n * @command paragraph\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @param {String}   style               标签值为：'p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'\r\n * @param {Object}   attrs               标签的属性\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'Paragraph','h1','{\r\n *     class:'test'\r\n * }' );\r\n * ```\r\n */\r\n\r\n/**\r\n * 返回选区内节点标签名\r\n * @command paragraph\r\n * @method queryCommandValue\r\n * @param { String } cmd 命令字符串\r\n * @return { String } 节点标签名\r\n * @example\r\n * ```javascript\r\n * editor.queryCommandValue( 'Paragraph' );\r\n * ```\r\n */\r\n\r\nUE.plugins['paragraph'] = function() {\r\n    var me = this,\r\n        block = domUtils.isBlockElm,\r\n        notExchange = ['TD','LI','PRE'],\r\n\r\n        doParagraph = function(range,style,attrs,sourceCmdName){\r\n            var bookmark = range.createBookmark(),\r\n                filterFn = function( node ) {\r\n                    return   node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' &&  !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace( node );\r\n                },\r\n                para;\r\n\r\n            range.enlarge( true );\r\n            var bookmark2 = range.createBookmark(),\r\n                current = domUtils.getNextDomNode( bookmark2.start, false, filterFn ),\r\n                tmpRange = range.cloneRange(),\r\n                tmpNode;\r\n            while ( current && !(domUtils.getPosition( current, bookmark2.end ) & domUtils.POSITION_FOLLOWING) ) {\r\n                if ( current.nodeType == 3 || !block( current ) ) {\r\n                    tmpRange.setStartBefore( current );\r\n                    while ( current && current !== bookmark2.end && !block( current ) ) {\r\n                        tmpNode = current;\r\n                        current = domUtils.getNextDomNode( current, false, null, function( node ) {\r\n                            return !block( node );\r\n                        } );\r\n                    }\r\n                    tmpRange.setEndAfter( tmpNode );\r\n                    \r\n                    para = range.document.createElement( style );\r\n                    if(attrs){\r\n                        domUtils.setAttributes(para,attrs);\r\n                        if(sourceCmdName && sourceCmdName == 'customstyle' && attrs.style){\r\n                            para.style.cssText = attrs.style;\r\n                        }\r\n                    }\r\n                    para.appendChild( tmpRange.extractContents() );\r\n                    //需要内容占位\r\n                    if(domUtils.isEmptyNode(para)){\r\n                        domUtils.fillChar(range.document,para);\r\n                        \r\n                    }\r\n\r\n                    tmpRange.insertNode( para );\r\n\r\n                    var parent = para.parentNode;\r\n                    //如果para上一级是一个block元素且不是body,td就删除它\r\n                    if ( block( parent ) && !domUtils.isBody( para.parentNode ) && utils.indexOf(notExchange,parent.tagName)==-1) {\r\n                        //存储dir,style\r\n                        if(!(sourceCmdName && sourceCmdName == 'customstyle')){\r\n                            parent.getAttribute('dir') && para.setAttribute('dir',parent.getAttribute('dir'));\r\n                            //trace:1070\r\n                            parent.style.cssText && (para.style.cssText = parent.style.cssText + ';' + para.style.cssText);\r\n                            //trace:1030\r\n                            parent.style.textAlign && !para.style.textAlign && (para.style.textAlign = parent.style.textAlign);\r\n                            parent.style.textIndent && !para.style.textIndent && (para.style.textIndent = parent.style.textIndent);\r\n                            parent.style.padding && !para.style.padding && (para.style.padding = parent.style.padding);\r\n                        }\r\n\r\n                        //trace:1706 选择的就是h1-6要删除\r\n                        if(attrs && /h\\d/i.test(parent.tagName) && !/h\\d/i.test(para.tagName) ){\r\n                            domUtils.setAttributes(parent,attrs);\r\n                            if(sourceCmdName && sourceCmdName == 'customstyle' && attrs.style){\r\n                                parent.style.cssText = attrs.style;\r\n                            }\r\n                            domUtils.remove(para,true);\r\n                            para = parent;\r\n                        }else{\r\n                            domUtils.remove( para.parentNode, true );\r\n                        }\r\n\r\n                    }\r\n                    if(  utils.indexOf(notExchange,parent.tagName)!=-1){\r\n                        current = parent;\r\n                    }else{\r\n                       current = para;\r\n                    }\r\n\r\n\r\n                    current = domUtils.getNextDomNode( current, false, filterFn );\r\n                } else {\r\n                    current = domUtils.getNextDomNode( current, true, filterFn );\r\n                }\r\n            }\r\n            return range.moveToBookmark( bookmark2 ).moveToBookmark( bookmark );\r\n        };\r\n    me.setOpt('paragraph',{'p':'', 'h1':'', 'h2':'', 'h3':'', 'h4':'', 'h5':'', 'h6':''});\r\n    me.commands['paragraph'] = {\r\n        execCommand : function( cmdName, style,attrs,sourceCmdName ) {\r\n            var range = this.selection.getRange();\r\n             //闭合时单独处理\r\n            if(range.collapsed){\r\n                var txt = this.document.createTextNode('p');\r\n                range.insertNode(txt);\r\n                //去掉冗余的fillchar\r\n                if(browser.ie){\r\n                    var node = txt.previousSibling;\r\n                    if(node && domUtils.isWhitespace(node)){\r\n                        domUtils.remove(node);\r\n                    }\r\n                    node = txt.nextSibling;\r\n                    if(node && domUtils.isWhitespace(node)){\r\n                        domUtils.remove(node);\r\n                    }\r\n                }\r\n\r\n            }\r\n            range = doParagraph(range,style,attrs,sourceCmdName);\r\n            if(txt){\r\n                range.setStartBefore(txt).collapse(true);\r\n                pN = txt.parentNode;\r\n\r\n                domUtils.remove(txt);\r\n\r\n                if(domUtils.isBlockElm(pN)&&domUtils.isEmptyNode(pN)){\r\n                    domUtils.fillNode(this.document,pN);\r\n                }\r\n\r\n            }\r\n\r\n            if(browser.gecko && range.collapsed && range.startContainer.nodeType == 1){\r\n                var child = range.startContainer.childNodes[range.startOffset];\r\n                if(child && child.nodeType == 1 && child.tagName.toLowerCase() == style){\r\n                    range.setStart(child,0).collapse(true);\r\n                }\r\n            }\r\n            //trace:1097 原来有true，原因忘了，但去了就不能清除多余的占位符了\r\n            range.select();\r\n\r\n\r\n            return true;\r\n        },\r\n        queryCommandValue : function() {\r\n            var node = domUtils.filterNodeList(this.selection.getStartElementPath(),'p h1 h2 h3 h4 h5 h6');\r\n            return node ? node.tagName.toLowerCase() : '';\r\n        }\r\n    };\r\n};\r\n\n\n// plugins/directionality.js\n/**\r\n * 设置文字输入的方向的插件\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n(function() {\r\n    var block = domUtils.isBlockElm ,\r\n        getObj = function(editor){\r\n//            var startNode = editor.selection.getStart(),\r\n//                parents;\r\n//            if ( startNode ) {\r\n//                //查找所有的是block的父亲节点\r\n//                parents = domUtils.findParents( startNode, true, block, true );\r\n//                for ( var i = 0,ci; ci = parents[i++]; ) {\r\n//                    if ( ci.getAttribute( 'dir' ) ) {\r\n//                        return ci;\r\n//                    }\r\n//                }\r\n//            }\r\n            return domUtils.filterNodeList(editor.selection.getStartElementPath(),function(n){return n && n.nodeType == 1 && n.getAttribute('dir')});\r\n\r\n        },\r\n        doDirectionality = function(range,editor,forward){\r\n            \r\n            var bookmark,\r\n                filterFn = function( node ) {\r\n                    return   node.nodeType == 1 ? !domUtils.isBookmarkNode(node) : !domUtils.isWhitespace(node);\r\n                },\r\n\r\n                obj = getObj( editor );\r\n\r\n            if ( obj && range.collapsed ) {\r\n                obj.setAttribute( 'dir', forward );\r\n                return range;\r\n            }\r\n            bookmark = range.createBookmark();\r\n            range.enlarge( true );\r\n            var bookmark2 = range.createBookmark(),\r\n                current = domUtils.getNextDomNode( bookmark2.start, false, filterFn ),\r\n                tmpRange = range.cloneRange(),\r\n                tmpNode;\r\n            while ( current &&  !(domUtils.getPosition( current, bookmark2.end ) & domUtils.POSITION_FOLLOWING) ) {\r\n                if ( current.nodeType == 3 || !block( current ) ) {\r\n                    tmpRange.setStartBefore( current );\r\n                    while ( current && current !== bookmark2.end && !block( current ) ) {\r\n                        tmpNode = current;\r\n                        current = domUtils.getNextDomNode( current, false, null, function( node ) {\r\n                            return !block( node );\r\n                        } );\r\n                    }\r\n                    tmpRange.setEndAfter( tmpNode );\r\n                    var common = tmpRange.getCommonAncestor();\r\n                    if ( !domUtils.isBody( common ) && block( common ) ) {\r\n                        //遍历到了block节点\r\n                        common.setAttribute( 'dir', forward );\r\n                        current = common;\r\n                    } else {\r\n                        //没有遍历到，添加一个block节点\r\n                        var p = range.document.createElement( 'p' );\r\n                        p.setAttribute( 'dir', forward );\r\n                        var frag = tmpRange.extractContents();\r\n                        p.appendChild( frag );\r\n                        tmpRange.insertNode( p );\r\n                        current = p;\r\n                    }\r\n\r\n                    current = domUtils.getNextDomNode( current, false, filterFn );\r\n                } else {\r\n                    current = domUtils.getNextDomNode( current, true, filterFn );\r\n                }\r\n            }\r\n            return range.moveToBookmark( bookmark2 ).moveToBookmark( bookmark );\r\n        };\r\n\r\n    /**\r\n     * 文字输入方向\r\n     * @command directionality\r\n     * @method execCommand\r\n     * @param { String } cmdName 命令字符串\r\n     * @param { String } forward 传入'ltr'表示从左向右输入，传入'rtl'表示从右向左输入\r\n     * @example\r\n     * ```javascript\r\n     * editor.execCommand( 'directionality', 'ltr');\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 查询当前选区的文字输入方向\r\n     * @command directionality\r\n     * @method queryCommandValue\r\n     * @param { String } cmdName 命令字符串\r\n     * @return { String } 返回'ltr'表示从左向右输入，返回'rtl'表示从右向左输入\r\n     * @example\r\n     * ```javascript\r\n     * editor.queryCommandValue( 'directionality');\r\n     * ```\r\n     */\r\n    UE.commands['directionality'] = {\r\n        execCommand : function( cmdName,forward ) {\r\n            var range = this.selection.getRange();\r\n            //闭合时单独处理\r\n            if(range.collapsed){\r\n                var txt = this.document.createTextNode('d');\r\n                range.insertNode(txt);\r\n            }\r\n            doDirectionality(range,this,forward);\r\n            if(txt){\r\n                range.setStartBefore(txt).collapse(true);\r\n                domUtils.remove(txt);\r\n            }\r\n\r\n            range.select();\r\n            return true;\r\n        },\r\n        queryCommandValue : function() {\r\n            var node = getObj(this);\r\n            return node ? node.getAttribute('dir') : 'ltr';\r\n        }\r\n    };\r\n})();\r\n\r\n\n\n// plugins/horizontal.js\n/**\r\n * 插入分割线插件\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 插入分割线\r\n * @command horizontal\r\n * @method execCommand\r\n * @param { String } cmdName 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'horizontal' );\r\n * ```\r\n */\r\nUE.plugins['horizontal'] = function(){\r\n    var me = this;\r\n    me.commands['horizontal'] = {\r\n        execCommand : function( cmdName ) {\r\n            var me = this;\r\n            if(me.queryCommandState(cmdName)!==-1){\r\n                me.execCommand('insertHtml','<hr>');\r\n                var range = me.selection.getRange(),\r\n                    start = range.startContainer;\r\n                if(start.nodeType == 1 && !start.childNodes[range.startOffset] ){\r\n\r\n                    var tmp;\r\n                    if(tmp = start.childNodes[range.startOffset - 1]){\r\n                        if(tmp.nodeType == 1 && tmp.tagName == 'HR'){\r\n                            if(me.options.enterTag == 'p'){\r\n                                tmp = me.document.createElement('p');\r\n                                range.insertNode(tmp);\r\n                                range.setStart(tmp,0).setCursor();\r\n\r\n                            }else{\r\n                                tmp = me.document.createElement('br');\r\n                                range.insertNode(tmp);\r\n                                range.setStartBefore(tmp).setCursor();\r\n                            }\r\n                        }\r\n                    }\r\n\r\n                }\r\n                return true;\r\n            }\r\n\r\n        },\r\n        //边界在table里不能加分隔线\r\n        queryCommandState : function() {\r\n            return domUtils.filterNodeList(this.selection.getStartElementPath(),'table') ? -1 : 0;\r\n        }\r\n    };\r\n//    me.addListener('delkeyup',function(){\r\n//        var rng = this.selection.getRange();\r\n//        if(browser.ie && browser.version > 8){\r\n//            rng.txtToElmBoundary(true);\r\n//            if(domUtils.isStartInblock(rng)){\r\n//                var tmpNode = rng.startContainer;\r\n//                var pre = tmpNode.previousSibling;\r\n//                if(pre && domUtils.isTagNode(pre,'hr')){\r\n//                    domUtils.remove(pre);\r\n//                    rng.select();\r\n//                    return;\r\n//                }\r\n//            }\r\n//        }\r\n//        if(domUtils.isBody(rng.startContainer)){\r\n//            var hr = rng.startContainer.childNodes[rng.startOffset -1];\r\n//            if(hr && hr.nodeName == 'HR'){\r\n//                var next = hr.nextSibling;\r\n//                if(next){\r\n//                    rng.setStart(next,0)\r\n//                }else if(hr.previousSibling){\r\n//                    rng.setStartAtLast(hr.previousSibling)\r\n//                }else{\r\n//                    var p = this.document.createElement('p');\r\n//                    hr.parentNode.insertBefore(p,hr);\r\n//                    domUtils.fillNode(this.document,p);\r\n//                    rng.setStart(p,0);\r\n//                }\r\n//                domUtils.remove(hr);\r\n//                rng.setCursor(false,true);\r\n//            }\r\n//        }\r\n//    })\r\n    me.addListener('delkeydown',function(name,evt){\r\n        var rng = this.selection.getRange();\r\n        rng.txtToElmBoundary(true);\r\n        if(domUtils.isStartInblock(rng)){\r\n            var tmpNode = rng.startContainer;\r\n            var pre = tmpNode.previousSibling;\r\n            if(pre && domUtils.isTagNode(pre,'hr')){\r\n                domUtils.remove(pre);\r\n                rng.select();\r\n                domUtils.preventDefault(evt);\r\n                return true;\r\n\r\n            }\r\n        }\r\n\r\n    })\r\n};\r\n\r\n\n\n// plugins/time.js\n/**\r\n * 插入时间和日期\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 插入时间，默认格式：12:59:59\r\n * @command time\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'time');\r\n * ```\r\n */\r\n\r\n/**\r\n * 插入日期，默认格式：2013-08-30\r\n * @command date\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'date');\r\n * ```\r\n */\r\nUE.commands['time'] = UE.commands[\"date\"] = {\r\n    execCommand : function(cmd, format){\r\n        var date = new Date;\r\n\r\n        function formatTime(date, format) {\r\n            var hh = ('0' + date.getHours()).slice(-2),\r\n                ii = ('0' + date.getMinutes()).slice(-2),\r\n                ss = ('0' + date.getSeconds()).slice(-2);\r\n            format = format || 'hh:ii:ss';\r\n            return format.replace(/hh/ig, hh).replace(/ii/ig, ii).replace(/ss/ig, ss);\r\n        }\r\n        function formatDate(date, format) {\r\n            var yyyy = ('000' + date.getFullYear()).slice(-4),\r\n                yy = yyyy.slice(-2),\r\n                mm = ('0' + (date.getMonth()+1)).slice(-2),\r\n                dd = ('0' + date.getDate()).slice(-2);\r\n            format = format || 'yyyy-mm-dd';\r\n            return format.replace(/yyyy/ig, yyyy).replace(/yy/ig, yy).replace(/mm/ig, mm).replace(/dd/ig, dd);\r\n        }\r\n\r\n        this.execCommand('insertHtml',cmd == \"time\" ? formatTime(date, format):formatDate(date, format) );\r\n    }\r\n};\r\n\n\n// plugins/rowspacing.js\n/**\r\n * 段前段后间距插件\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 设置段间距\r\n * @command rowspacing\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @param { String } value 段间距的值，以px为单位\r\n * @param { String } dir 间距位置，top或bottom，分别表示段前和段后\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'rowspacing', '10', 'top' );\r\n * ```\r\n */\r\n\r\nUE.plugins['rowspacing'] = function(){\r\n    var me = this;\r\n    me.setOpt({\r\n        'rowspacingtop':['5', '10', '15', '20', '25'],\r\n        'rowspacingbottom':['5', '10', '15', '20', '25']\r\n\r\n    });\r\n    me.commands['rowspacing'] =  {\r\n        execCommand : function( cmdName,value,dir ) {\r\n            this.execCommand('paragraph','p',{style:'margin-'+dir+':'+value + 'px'});\r\n            return true;\r\n        },\r\n        queryCommandValue : function(cmdName,dir) {\r\n            var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),function(node){return domUtils.isBlockElm(node) }),\r\n                value;\r\n            //trace:1026\r\n            if(pN){\r\n                value = domUtils.getComputedStyle(pN,'margin-'+dir).replace(/[^\\d]/g,'');\r\n                return !value ? 0 : value;\r\n            }\r\n            return 0;\r\n\r\n        }\r\n    };\r\n};\r\n\r\n\r\n\n\n// plugins/lineheight.js\n/**\r\n * 设置行内间距\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\nUE.plugins['lineheight'] = function(){\r\n    var me = this;\r\n    me.setOpt({'lineheight':['1', '1.5','1.75','2', '3', '4', '5']});\r\n\r\n    /**\r\n     * 行距\r\n     * @command lineheight\r\n     * @method execCommand\r\n     * @param { String } cmdName 命令字符串\r\n     * @param { String } value 传入的行高值， 该值是当前字体的倍数， 例如： 1.5, 1.75\r\n     * @example\r\n     * ```javascript\r\n     * editor.execCommand( 'lineheight', 1.5);\r\n     * ```\r\n     */\r\n    /**\r\n     * 查询当前选区内容的行高大小\r\n     * @command lineheight\r\n     * @method queryCommandValue\r\n     * @param { String } cmd 命令字符串\r\n     * @return { String } 返回当前行高大小\r\n     * @example\r\n     * ```javascript\r\n     * editor.queryCommandValue( 'lineheight' );\r\n     * ```\r\n     */\r\n\r\n    me.commands['lineheight'] =  {\r\n        execCommand : function( cmdName,value ) {\r\n            this.execCommand('paragraph','p',{style:'line-height:'+ (value == \"1\" ? \"normal\" : value + 'em') });\r\n            return true;\r\n        },\r\n        queryCommandValue : function() {\r\n            var pN = domUtils.filterNodeList(this.selection.getStartElementPath(),function(node){return domUtils.isBlockElm(node)});\r\n            if(pN){\r\n                var value = domUtils.getComputedStyle(pN,'line-height');\r\n                return value == 'normal' ? 1 : value.replace(/[^\\d.]*/ig,\"\");\r\n            }\r\n        }\r\n    };\r\n};\r\n\r\n\r\n\n\n// plugins/insertcode.js\n/**\n * 插入代码插件\n * @file\n * @since 1.2.6.1\n */\n\nUE.plugins['insertcode'] = function() {\n    var me = this;\n    me.ready(function(){\n        utils.cssRule('pre','pre{margin:.5em 0;padding:.4em .6em;border-radius:8px;background:#f8f8f8;}',\n            me.document)\n    });\n    me.setOpt('insertcode',{\n            'as3':'ActionScript3',\n            'bash':'Bash/Shell',\n            'cpp':'C/C++',\n            'css':'Css',\n            'cf':'CodeFunction',\n            'c#':'C#',\n            'delphi':'Delphi',\n            'diff':'Diff',\n            'erlang':'Erlang',\n            'groovy':'Groovy',\n            'html':'Html',\n            'java':'Java',\n            'jfx':'JavaFx',\n            'js':'Javascript',\n            'pl':'Perl',\n            'php':'Php',\n            'plain':'Plain Text',\n            'ps':'PowerShell',\n            'python':'Python',\n            'ruby':'Ruby',\n            'scala':'Scala',\n            'sql':'Sql',\n            'vb':'Vb',\n            'xml':'Xml'\n    });\n\n    /**\n     * 插入代码\n     * @command insertcode\n     * @method execCommand\n     * @param { String } cmd 命令字符串\n     * @param { String } lang 插入代码的语言\n     * @example\n     * ```javascript\n     * editor.execCommand( 'insertcode', 'javascript' );\n     * ```\n     */\n\n    /**\n     * 如果选区所在位置是插入插入代码区域，返回代码的语言\n     * @command insertcode\n     * @method queryCommandValue\n     * @param { String } cmd 命令字符串\n     * @return { String } 返回代码的语言\n     * @example\n     * ```javascript\n     * editor.queryCommandValue( 'insertcode' );\n     * ```\n     */\n\n    me.commands['insertcode'] = {\n        execCommand : function(cmd,lang){\n            var me = this,\n                rng = me.selection.getRange(),\n                pre = domUtils.findParentByTagName(rng.startContainer,'pre',true);\n            if(pre){\n                pre.className = 'brush:'+lang+';toolbar:false;';\n            }else{\n                var code = '';\n                if(rng.collapsed){\n                    code = browser.ie && browser.ie11below ? (browser.version <= 8 ? '&nbsp;':''):'<br/>';\n                }else{\n                    var frag = rng.extractContents();\n                    var div = me.document.createElement('div');\n                    div.appendChild(frag);\n\n                    utils.each(UE.filterNode(UE.htmlparser(div.innerHTML.replace(/[\\r\\t]/g,'')),me.options.filterTxtRules).children,function(node){\n                        if(browser.ie && browser.ie11below && browser.version > 8){\n\n                            if(node.type =='element'){\n                                if(node.tagName == 'br'){\n                                    code += '\\n'\n                                }else if(!dtd.$empty[node.tagName]){\n                                    utils.each(node.children,function(cn){\n                                        if(cn.type =='element'){\n                                            if(cn.tagName == 'br'){\n                                                code += '\\n'\n                                            }else if(!dtd.$empty[node.tagName]){\n                                                code += cn.innerText();\n                                            }\n                                        }else{\n                                            code += cn.data\n                                        }\n                                    })\n                                    if(!/\\n$/.test(code)){\n                                        code += '\\n';\n                                    }\n                                }\n                            }else{\n                                code += node.data + '\\n'\n                            }\n                            if(!node.nextSibling() && /\\n$/.test(code)){\n                                code = code.replace(/\\n$/,'');\n                            }\n                        }else{\n                            if(browser.ie && browser.ie11below){\n\n                                if(node.type =='element'){\n                                    if(node.tagName == 'br'){\n                                        code += '<br>'\n                                    }else if(!dtd.$empty[node.tagName]){\n                                        utils.each(node.children,function(cn){\n                                            if(cn.type =='element'){\n                                                if(cn.tagName == 'br'){\n                                                    code += '<br>'\n                                                }else if(!dtd.$empty[node.tagName]){\n                                                    code += cn.innerText();\n                                                }\n                                            }else{\n                                                code += cn.data\n                                            }\n                                        });\n                                        if(!/br>$/.test(code)){\n                                            code += '<br>';\n                                        }\n                                    }\n                                }else{\n                                    code += node.data + '<br>'\n                                }\n                                if(!node.nextSibling() && /<br>$/.test(code)){\n                                    code = code.replace(/<br>$/,'');\n                                }\n\n                            }else{\n                                code += (node.type == 'element' ? (dtd.$empty[node.tagName] ?  '' : node.innerText()) : node.data);\n                                if(!/br\\/?\\s*>$/.test(code)){\n                                    if(!node.nextSibling())\n                                        return;\n                                    code += '<br>'\n                                }\n                            }\n\n                        }\n\n                    });\n                }\n                me.execCommand('inserthtml','<pre id=\"coder\"class=\"brush:'+lang+';toolbar:false\">'+code+'</pre>',true);\n\n                pre = me.document.getElementById('coder');\n                domUtils.removeAttributes(pre,'id');\n                var tmpNode = pre.previousSibling;\n\n                if(tmpNode && (tmpNode.nodeType == 3 && tmpNode.nodeValue.length == 1 && browser.ie && browser.version == 6 ||  domUtils.isEmptyBlock(tmpNode))){\n\n                    domUtils.remove(tmpNode)\n                }\n                var rng = me.selection.getRange();\n                if(domUtils.isEmptyBlock(pre)){\n                    rng.setStart(pre,0).setCursor(false,true)\n                }else{\n                    rng.selectNodeContents(pre).select()\n                }\n            }\n\n\n\n        },\n        queryCommandValue : function(){\n            var path = this.selection.getStartElementPath();\n            var lang = '';\n            utils.each(path,function(node){\n                if(node.nodeName =='PRE'){\n                    var match = node.className.match(/brush:([^;]+)/);\n                    lang = match && match[1] ? match[1] : '';\n                    return false;\n                }\n            });\n            return lang;\n        }\n    };\n\n    me.addInputRule(function(root){\n       utils.each(root.getNodesByTagName('pre'),function(pre){\n           var brs = pre.getNodesByTagName('br');\n           if(brs.length){\n               browser.ie && browser.ie11below && browser.version > 8 && utils.each(brs,function(br){\n                   var txt = UE.uNode.createText('\\n');\n                   br.parentNode.insertBefore(txt,br);\n                   br.parentNode.removeChild(br);\n               });\n               return;\n            }\n           if(browser.ie && browser.ie11below && browser.version > 8)\n                return;\n            var code = pre.innerText().split(/\\n/);\n            pre.innerHTML('');\n            utils.each(code,function(c){\n                if(c.length){\n                    pre.appendChild(UE.uNode.createText(c));\n                }\n                pre.appendChild(UE.uNode.createElement('br'))\n            })\n       })\n    });\n    me.addOutputRule(function(root){\n        utils.each(root.getNodesByTagName('pre'),function(pre){\n            var code = '';\n            utils.each(pre.children,function(n){\n               if(n.type == 'text'){\n                   //在ie下文本内容有可能末尾带有\\n要去掉\n                   //trace:3396\n                   code += n.data.replace(/[ ]/g,'&nbsp;').replace(/\\n$/,'');\n               }else{\n                   if(n.tagName == 'br'){\n                       code  += '\\n'\n                   }else{\n                       code += (!dtd.$empty[n.tagName] ? '' : n.innerText());\n                   }\n\n               }\n\n            });\n\n            pre.innerText(code.replace(/(&nbsp;|\\n)+$/,''))\n        })\n    });\n    //不需要判断highlight的command列表\n    me.notNeedCodeQuery ={\n        help:1,\n        undo:1,\n        redo:1,\n        source:1,\n        print:1,\n        searchreplace:1,\n        fullscreen:1,\n        preview:1,\n        insertparagraph:1,\n        elementpath:1,\n        insertcode:1,\n        inserthtml:1,\n        selectall:1\n    };\n    //将queyCommamndState重置\n    var orgQuery = me.queryCommandState;\n    me.queryCommandState = function(cmd){\n        var me = this;\n\n        if(!me.notNeedCodeQuery[cmd.toLowerCase()] && me.selection && me.queryCommandValue('insertcode')){\n            return -1;\n        }\n        return UE.Editor.prototype.queryCommandState.apply(this,arguments)\n    };\n    me.addListener('beforeenterkeydown',function(){\n        var rng = me.selection.getRange();\n        var pre = domUtils.findParentByTagName(rng.startContainer,'pre',true);\n        if(pre){\n            me.fireEvent('saveScene');\n            if(!rng.collapsed){\n               rng.deleteContents();\n            }\n            if(!browser.ie || browser.ie9above){\n                var tmpNode = me.document.createElement('br'),pre;\n                rng.insertNode(tmpNode).setStartAfter(tmpNode).collapse(true);\n                var next = tmpNode.nextSibling;\n                if(!next && (!browser.ie || browser.version > 10)){\n                    rng.insertNode(tmpNode.cloneNode(false));\n                }else{\n                    rng.setStartAfter(tmpNode);\n                }\n                pre = tmpNode.previousSibling;\n                var tmp;\n                while(pre ){\n                    tmp = pre;\n                    pre = pre.previousSibling;\n                    if(!pre || pre.nodeName == 'BR'){\n                        pre = tmp;\n                        break;\n                    }\n                }\n                if(pre){\n                    var str = '';\n                    while(pre && pre.nodeName != 'BR' &&  new RegExp('^[\\\\s'+domUtils.fillChar+']*$').test(pre.nodeValue)){\n                        str += pre.nodeValue;\n                        pre = pre.nextSibling;\n                    }\n                    if(pre.nodeName != 'BR'){\n                        var match = pre.nodeValue.match(new RegExp('^([\\\\s'+domUtils.fillChar+']+)'));\n                        if(match && match[1]){\n                            str += match[1]\n                        }\n\n                    }\n                    if(str){\n                        str = me.document.createTextNode(str);\n                        rng.insertNode(str).setStartAfter(str);\n                    }\n                }\n                rng.collapse(true).select(true);\n            }else{\n                if(browser.version > 8){\n\n                    var txt = me.document.createTextNode('\\n');\n                    var start = rng.startContainer;\n                    if(rng.startOffset == 0){\n                        var preNode = start.previousSibling;\n                        if(preNode){\n                            rng.insertNode(txt);\n                            var fillchar = me.document.createTextNode(' ');\n                            rng.setStartAfter(txt).insertNode(fillchar).setStart(fillchar,0).collapse(true).select(true)\n                        }\n                    }else{\n                        rng.insertNode(txt).setStartAfter(txt);\n                        var fillchar = me.document.createTextNode(' ');\n                        start = rng.startContainer.childNodes[rng.startOffset];\n                        if(start && !/^\\n/.test(start.nodeValue)){\n                            rng.setStartBefore(txt)\n                        }\n                        rng.insertNode(fillchar).setStart(fillchar,0).collapse(true).select(true)\n                    }\n\n                }else{\n                    var tmpNode = me.document.createElement('br');\n                    rng.insertNode(tmpNode);\n                    rng.insertNode(me.document.createTextNode(domUtils.fillChar));\n                    rng.setStartAfter(tmpNode);\n                    pre = tmpNode.previousSibling;\n                    var tmp;\n                    while(pre ){\n                        tmp = pre;\n                        pre = pre.previousSibling;\n                        if(!pre || pre.nodeName == 'BR'){\n                            pre = tmp;\n                            break;\n                        }\n                    }\n                    if(pre){\n                        var str = '';\n                        while(pre && pre.nodeName != 'BR' &&  new RegExp('^[ '+domUtils.fillChar+']*$').test(pre.nodeValue)){\n                            str += pre.nodeValue;\n                            pre = pre.nextSibling;\n                        }\n                        if(pre.nodeName != 'BR'){\n                            var match = pre.nodeValue.match(new RegExp('^([ '+domUtils.fillChar+']+)'));\n                            if(match && match[1]){\n                                str += match[1]\n                            }\n\n                        }\n\n                        str = me.document.createTextNode(str);\n                        rng.insertNode(str).setStartAfter(str);\n                    }\n                    rng.collapse(true).select();\n                }\n\n\n            }\n            me.fireEvent('saveScene');\n            return true;\n        }\n\n\n    });\n\n    me.addListener('tabkeydown',function(cmd,evt){\n        var rng = me.selection.getRange();\n        var pre = domUtils.findParentByTagName(rng.startContainer,'pre',true);\n        if(pre){\n            me.fireEvent('saveScene');\n            if(evt.shiftKey){\n\n            }else{\n                if(!rng.collapsed){\n                    var bk = rng.createBookmark();\n                    var start = bk.start.previousSibling;\n\n                    while(start){\n                        if(pre.firstChild === start && !domUtils.isBr(start)){\n                            pre.insertBefore(me.document.createTextNode('    '),start);\n\n                            break;\n                        }\n                        if(domUtils.isBr(start)){\n                            pre.insertBefore(me.document.createTextNode('    '),start.nextSibling);\n\n                            break;\n                        }\n                        start = start.previousSibling;\n                    }\n                    var end = bk.end;\n                    start = bk.start.nextSibling;\n                    if(pre.firstChild === bk.start){\n                        pre.insertBefore(me.document.createTextNode('    '),start.nextSibling)\n\n                    }\n                    while(start && start !== end){\n                        if(domUtils.isBr(start) && start.nextSibling){\n                            if(start.nextSibling === end){\n                                break;\n                            }\n                            pre.insertBefore(me.document.createTextNode('    '),start.nextSibling)\n                        }\n\n                        start = start.nextSibling;\n                    }\n                    rng.moveToBookmark(bk).select();\n                }else{\n                    var tmpNode = me.document.createTextNode('    ');\n                    rng.insertNode(tmpNode).setStartAfter(tmpNode).collapse(true).select(true);\n                }\n            }\n\n\n            me.fireEvent('saveScene');\n            return true;\n        }\n\n\n    });\n\n\n    me.addListener('beforeinserthtml',function(evtName,html){\n        var me = this,\n            rng = me.selection.getRange(),\n            pre = domUtils.findParentByTagName(rng.startContainer,'pre',true);\n        if(pre){\n            if(!rng.collapsed){\n                rng.deleteContents()\n            }\n            var htmlstr = '';\n            if(browser.ie && browser.version > 8){\n\n                utils.each(UE.filterNode(UE.htmlparser(html),me.options.filterTxtRules).children,function(node){\n                    if(node.type =='element'){\n                        if(node.tagName == 'br'){\n                            htmlstr += '\\n'\n                        }else if(!dtd.$empty[node.tagName]){\n                            utils.each(node.children,function(cn){\n                                if(cn.type =='element'){\n                                    if(cn.tagName == 'br'){\n                                        htmlstr += '\\n'\n                                    }else if(!dtd.$empty[node.tagName]){\n                                        htmlstr += cn.innerText();\n                                    }\n                                }else{\n                                    htmlstr += cn.data\n                                }\n                            })\n                            if(!/\\n$/.test(htmlstr)){\n                                htmlstr += '\\n';\n                            }\n                        }\n                    }else{\n                        htmlstr += node.data + '\\n'\n                    }\n                    if(!node.nextSibling() && /\\n$/.test(htmlstr)){\n                        htmlstr = htmlstr.replace(/\\n$/,'');\n                    }\n                });\n                var tmpNode = me.document.createTextNode(utils.html(htmlstr.replace(/&nbsp;/g,' ')));\n                rng.insertNode(tmpNode).selectNode(tmpNode).select();\n            }else{\n                var frag = me.document.createDocumentFragment();\n\n                utils.each(UE.filterNode(UE.htmlparser(html),me.options.filterTxtRules).children,function(node){\n                    if(node.type =='element'){\n                        if(node.tagName == 'br'){\n                            frag.appendChild(me.document.createElement('br'))\n                        }else if(!dtd.$empty[node.tagName]){\n                            utils.each(node.children,function(cn){\n                                if(cn.type =='element'){\n                                    if(cn.tagName == 'br'){\n\n                                        frag.appendChild(me.document.createElement('br'))\n                                    }else if(!dtd.$empty[node.tagName]){\n                                        frag.appendChild(me.document.createTextNode(utils.html(cn.innerText().replace(/&nbsp;/g,' '))));\n\n                                    }\n                                }else{\n                                    frag.appendChild(me.document.createTextNode(utils.html( cn.data.replace(/&nbsp;/g,' '))));\n\n                                }\n                            })\n                            if(frag.lastChild.nodeName != 'BR'){\n                                frag.appendChild(me.document.createElement('br'))\n                            }\n                        }\n                    }else{\n                        frag.appendChild(me.document.createTextNode(utils.html( node.data.replace(/&nbsp;/g,' '))));\n                    }\n                    if(!node.nextSibling() && frag.lastChild.nodeName == 'BR'){\n                       frag.removeChild(frag.lastChild)\n                    }\n\n\n                });\n                rng.insertNode(frag).select();\n\n            }\n\n            return true;\n        }\n    });\n    //方向键的处理\n    me.addListener('keydown',function(cmd,evt){\n        var me = this,keyCode = evt.keyCode || evt.which;\n        if(keyCode == 40){\n            var rng = me.selection.getRange(),pre,start = rng.startContainer;\n            if(rng.collapsed && (pre = domUtils.findParentByTagName(rng.startContainer,'pre',true)) && !pre.nextSibling){\n                var last = pre.lastChild\n                while(last && last.nodeName == 'BR'){\n                    last = last.previousSibling;\n                }\n                if(last === start || rng.startContainer === pre && rng.startOffset == pre.childNodes.length){\n                    me.execCommand('insertparagraph');\n                    domUtils.preventDefault(evt)\n                }\n\n            }\n        }\n    });\n    //trace:3395\n    me.addListener('delkeydown',function(type,evt){\n        var rng = this.selection.getRange();\n        rng.txtToElmBoundary(true);\n        var start = rng.startContainer;\n        if(domUtils.isTagNode(start,'pre') && rng.collapsed && domUtils.isStartInblock(rng)){\n            var p = me.document.createElement('p');\n            domUtils.fillNode(me.document,p);\n            start.parentNode.insertBefore(p,start);\n            domUtils.remove(start);\n            rng.setStart(p,0).setCursor(false,true);\n            domUtils.preventDefault(evt);\n            return true;\n        }\n    })\n};\n\n\n// plugins/cleardoc.js\n/**\r\n * 清空文档插件\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 清空文档\r\n * @command cleardoc\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * //editor 是编辑器实例\r\n * editor.execCommand('cleardoc');\r\n * ```\r\n */\r\n\r\nUE.commands['cleardoc'] = {\r\n    execCommand : function( cmdName) {\r\n        var me = this,\r\n            enterTag = me.options.enterTag,\r\n            range = me.selection.getRange();\r\n        if(enterTag == \"br\"){\r\n            me.body.innerHTML = \"<br/>\";\r\n            range.setStart(me.body,0).setCursor();\r\n        }else{\r\n            me.body.innerHTML = \"<p>\"+(ie ? \"\" : \"<br/>\")+\"</p>\";\r\n            range.setStart(me.body.firstChild,0).setCursor(false,true);\r\n        }\r\n        setTimeout(function(){\r\n            me.fireEvent(\"clearDoc\");\r\n        },0);\r\n\r\n    }\r\n};\r\n\r\n\n\n// plugins/anchor.js\n/**\r\n * 锚点插件，为UEditor提供插入锚点支持\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\nUE.plugin.register('anchor', function (){\r\n\r\n    return {\r\n        bindEvents:{\r\n            'ready':function(){\r\n                utils.cssRule('anchor',\r\n                    '.anchorclass{background: url(\\''\r\n                        + this.options.themePath\r\n                        + this.options.theme +'/images/anchor.gif\\') no-repeat scroll left center transparent;cursor: auto;display: inline-block;height: 16px;width: 15px;}',\r\n                    this.document);\r\n            }\r\n        },\r\n       outputRule: function(root){\r\n           utils.each(root.getNodesByTagName('img'),function(a){\r\n               var val;\r\n               if(val = a.getAttr('anchorname')){\r\n                   a.tagName = 'a';\r\n                   a.setAttr({\r\n                       anchorname : '',\r\n                       name : val,\r\n                       'class' : ''\r\n                   })\r\n               }\r\n           })\r\n       },\r\n       inputRule:function(root){\r\n           utils.each(root.getNodesByTagName('a'),function(a){\r\n               var val;\r\n               if((val = a.getAttr('name')) && !a.getAttr('href')){\r\n                   a.tagName = 'img';\r\n                   a.setAttr({\r\n                       anchorname :a.getAttr('name'),\r\n                       'class' : 'anchorclass'\r\n                   });\r\n                   a.setAttr('name')\r\n\r\n               }\r\n           })\r\n\r\n       },\r\n       commands:{\r\n           /**\r\n            * 插入锚点\r\n            * @command anchor\r\n            * @method execCommand\r\n            * @param { String } cmd 命令字符串\r\n            * @param { String } name 锚点名称字符串\r\n            * @example\r\n            * ```javascript\r\n            * //editor 是编辑器实例\r\n            * editor.execCommand('anchor', 'anchor1');\r\n            * ```\r\n            */\r\n           'anchor':{\r\n               execCommand:function (cmd, name) {\r\n                   var range = this.selection.getRange(),img = range.getClosedNode();\r\n                   if (img && img.getAttribute('anchorname')) {\r\n                       if (name) {\r\n                           img.setAttribute('anchorname', name);\r\n                       } else {\r\n                           range.setStartBefore(img).setCursor();\r\n                           domUtils.remove(img);\r\n                       }\r\n                   } else {\r\n                       if (name) {\r\n                           //只在选区的开始插入\r\n                           var anchor = this.document.createElement('img');\r\n                           range.collapse(true);\r\n                           domUtils.setAttributes(anchor,{\r\n                               'anchorname':name,\r\n                               'class':'anchorclass'\r\n                           });\r\n                           range.insertNode(anchor).setStartAfter(anchor).setCursor(false,true);\r\n                       }\r\n                   }\r\n               }\r\n           }\r\n       }\r\n    }\r\n});\r\n\n\n// plugins/wordcount.js\n///import core\r\n///commands 字数统计\r\n///commandsName  WordCount,wordCount\r\n///commandsTitle  字数统计\r\n/*\r\n * Created by JetBrains WebStorm.\r\n * User: taoqili\r\n * Date: 11-9-7\r\n * Time: 下午8:18\r\n * To change this template use File | Settings | File Templates.\r\n */\r\n\r\nUE.plugins['wordcount'] = function(){\r\n    var me = this;\r\n    me.setOpt('wordCount',true);\r\n    me.addListener('contentchange',function(){\r\n        me.fireEvent('wordcount');\r\n    });\r\n    var timer;\r\n    me.addListener('ready',function(){\r\n        var me = this;\r\n        domUtils.on(me.body,\"keyup\",function(evt){\r\n            var code = evt.keyCode||evt.which,\r\n                //忽略的按键,ctr,alt,shift,方向键\r\n                ignores = {\"16\":1,\"18\":1,\"20\":1,\"37\":1,\"38\":1,\"39\":1,\"40\":1};\r\n            if(code in ignores) return;\r\n            clearTimeout(timer);\r\n            timer = setTimeout(function(){\r\n                me.fireEvent('wordcount');\r\n            },200)\r\n        })\r\n    });\r\n};\r\n\n\n// plugins/pagebreak.js\n/**\r\n * 分页功能插件\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\nUE.plugins['pagebreak'] = function () {\r\n    var me = this,\r\n        notBreakTags = ['td'];\r\n    me.setOpt('pageBreakTag','_ueditor_page_break_tag_');\r\n\r\n    function fillNode(node){\r\n        if(domUtils.isEmptyBlock(node)){\r\n            var firstChild = node.firstChild,tmpNode;\r\n\r\n            while(firstChild && firstChild.nodeType == 1 && domUtils.isEmptyBlock(firstChild)){\r\n                tmpNode = firstChild;\r\n                firstChild = firstChild.firstChild;\r\n            }\r\n            !tmpNode && (tmpNode = node);\r\n            domUtils.fillNode(me.document,tmpNode);\r\n        }\r\n    }\r\n    //分页符样式添加\r\n\r\n    me.ready(function(){\r\n        utils.cssRule('pagebreak','.pagebreak{display:block;clear:both !important;cursor:default !important;width: 100% !important;margin:0;}',me.document);\r\n    });\r\n    function isHr(node){\r\n        return node && node.nodeType == 1 && node.tagName == 'HR' && node.className == 'pagebreak';\r\n    }\r\n    me.addInputRule(function(root){\r\n        root.traversal(function(node){\r\n            if(node.type == 'text' && node.data == me.options.pageBreakTag){\r\n                var hr = UE.uNode.createElement('<hr class=\"pagebreak\" noshade=\"noshade\" size=\"5\" style=\"-webkit-user-select: none;\">');\r\n                node.parentNode.insertBefore(hr,node);\r\n                node.parentNode.removeChild(node)\r\n            }\r\n        })\r\n    });\r\n    me.addOutputRule(function(node){\r\n        utils.each(node.getNodesByTagName('hr'),function(n){\r\n            if(n.getAttr('class') == 'pagebreak'){\r\n                var txt = UE.uNode.createText(me.options.pageBreakTag);\r\n                n.parentNode.insertBefore(txt,n);\r\n                n.parentNode.removeChild(n);\r\n            }\r\n        })\r\n\r\n    });\r\n\r\n    /**\r\n     * 插入分页符\r\n     * @command pagebreak\r\n     * @method execCommand\r\n     * @param { String } cmd 命令字符串\r\n     * @remind 在表格中插入分页符会把表格切分成两部分\r\n     * @remind 获取编辑器内的数据时， 编辑器会把分页符转换成“_ueditor_page_break_tag_”字符串，\r\n     *          以便于提交数据到服务器端后处理分页。\r\n     * @example\r\n     * ```javascript\r\n     * editor.execCommand( 'pagebreak'); //插入一个hr标签，带有样式类名pagebreak\r\n     * ```\r\n     */\r\n\r\n    me.commands['pagebreak'] = {\r\n        execCommand:function () {\r\n            var range = me.selection.getRange(),hr = me.document.createElement('hr');\r\n            domUtils.setAttributes(hr,{\r\n                'class' : 'pagebreak',\r\n                noshade:\"noshade\",\r\n                size:\"5\"\r\n            });\r\n            domUtils.unSelectable(hr);\r\n            //table单独处理\r\n            var node = domUtils.findParentByTagName(range.startContainer, notBreakTags, true),\r\n\r\n                parents = [], pN;\r\n            if (node) {\r\n                switch (node.tagName) {\r\n                    case 'TD':\r\n                        pN = node.parentNode;\r\n                        if (!pN.previousSibling) {\r\n                            var table = domUtils.findParentByTagName(pN, 'table');\r\n//                            var tableWrapDiv = table.parentNode;\r\n//                            if(tableWrapDiv && tableWrapDiv.nodeType == 1\r\n//                                && tableWrapDiv.tagName == 'DIV'\r\n//                                && tableWrapDiv.getAttribute('dropdrag')\r\n//                                ){\r\n//                                domUtils.remove(tableWrapDiv,true);\r\n//                            }\r\n                            table.parentNode.insertBefore(hr, table);\r\n                            parents = domUtils.findParents(hr, true);\r\n\r\n                        } else {\r\n                            pN.parentNode.insertBefore(hr, pN);\r\n                            parents = domUtils.findParents(hr);\r\n\r\n                        }\r\n                        pN = parents[1];\r\n                        if (hr !== pN) {\r\n                            domUtils.breakParent(hr, pN);\r\n\r\n                        }\r\n                        //table要重写绑定一下拖拽\r\n                        me.fireEvent('afteradjusttable',me.document);\r\n                }\r\n\r\n            } else {\r\n\r\n                if (!range.collapsed) {\r\n                    range.deleteContents();\r\n                    var start = range.startContainer;\r\n                    while ( !domUtils.isBody(start) && domUtils.isBlockElm(start) && domUtils.isEmptyNode(start)) {\r\n                        range.setStartBefore(start).collapse(true);\r\n                        domUtils.remove(start);\r\n                        start = range.startContainer;\r\n                    }\r\n\r\n                }\r\n                range.insertNode(hr);\r\n\r\n                var pN = hr.parentNode, nextNode;\r\n                while (!domUtils.isBody(pN)) {\r\n                    domUtils.breakParent(hr, pN);\r\n                    nextNode = hr.nextSibling;\r\n                    if (nextNode && domUtils.isEmptyBlock(nextNode)) {\r\n                        domUtils.remove(nextNode);\r\n                    }\r\n                    pN = hr.parentNode;\r\n                }\r\n                nextNode = hr.nextSibling;\r\n                var pre = hr.previousSibling;\r\n                if(isHr(pre)){\r\n                    domUtils.remove(pre);\r\n                }else{\r\n                    pre && fillNode(pre);\r\n                }\r\n\r\n                if(!nextNode){\r\n                    var p = me.document.createElement('p');\r\n\r\n                    hr.parentNode.appendChild(p);\r\n                    domUtils.fillNode(me.document,p);\r\n                    range.setStart(p,0).collapse(true);\r\n                }else{\r\n                    if(isHr(nextNode)){\r\n                        domUtils.remove(nextNode);\r\n                    }else{\r\n                        fillNode(nextNode);\r\n                    }\r\n                    range.setEndAfter(hr).collapse(false);\r\n                }\r\n\r\n                range.select(true);\r\n\r\n            }\r\n\r\n        }\r\n    };\r\n};\n\n// plugins/wordimage.js\n///import core\r\n///commands 本地图片引导上传\r\n///commandsName  WordImage\r\n///commandsTitle  本地图片引导上传\r\n///commandsDialog  dialogs\\wordimage\r\n\r\nUE.plugin.register('wordimage',function(){\r\n    var me = this,\r\n        images = [];\r\n    return {\r\n        commands : {\r\n            'wordimage':{\r\n                execCommand:function () {\r\n                    var images = domUtils.getElementsByTagName(me.body, \"img\");\r\n                    var urlList = [];\r\n                    for (var i = 0, ci; ci = images[i++];) {\r\n                        var url = ci.getAttribute(\"word_img\");\r\n                        url && urlList.push(url);\r\n                    }\r\n                    return urlList;\r\n                },\r\n                queryCommandState:function () {\r\n                    images = domUtils.getElementsByTagName(me.body, \"img\");\r\n                    for (var i = 0, ci; ci = images[i++];) {\r\n                        if (ci.getAttribute(\"word_img\")) {\r\n                            return 1;\r\n                        }\r\n                    }\r\n                    return -1;\r\n                },\r\n                notNeedUndo:true\r\n            }\r\n        },\r\n        inputRule : function (root) {\r\n            utils.each(root.getNodesByTagName('img'), function (img) {\r\n                var attrs = img.attrs,\r\n                    flag = parseInt(attrs.width) < 128 || parseInt(attrs.height) < 43,\r\n                    opt = me.options,\r\n                    src = opt.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif';\r\n                if (attrs['src'] && /^(?:(file:\\/+))/.test(attrs['src'])) {\r\n                    img.setAttr({\r\n                        width:attrs.width,\r\n                        height:attrs.height,\r\n                        alt:attrs.alt,\r\n                        word_img: attrs.src,\r\n                        src:src,\r\n                        'style':'background:url(' + ( flag ? opt.themePath + opt.theme + '/images/word.gif' : opt.langPath + opt.lang + '/images/localimage.png') + ') no-repeat center center;border:1px solid #ddd'\r\n                    })\r\n                }\r\n            })\r\n        }\r\n    }\r\n});\n\n// plugins/dragdrop.js\nUE.plugins['dragdrop'] = function (){\r\n\r\n    var me = this;\r\n    me.ready(function(){\r\n        domUtils.on(this.body,'dragend',function(){\r\n            var rng = me.selection.getRange();\r\n            var node = rng.getClosedNode()||me.selection.getStart();\r\n\r\n            if(node && node.tagName == 'IMG'){\r\n\r\n                var pre = node.previousSibling,next;\r\n                while(next = node.nextSibling){\r\n                    if(next.nodeType == 1 && next.tagName == 'SPAN' && !next.firstChild){\r\n                        domUtils.remove(next)\r\n                    }else{\r\n                        break;\r\n                    }\r\n                }\r\n\r\n\r\n                if((pre && pre.nodeType == 1 && !domUtils.isEmptyBlock(pre) || !pre) && (!next || next && !domUtils.isEmptyBlock(next))){\r\n                    if(pre && pre.tagName == 'P' && !domUtils.isEmptyBlock(pre)){\r\n                        pre.appendChild(node);\r\n                        domUtils.moveChild(next,pre);\r\n                        domUtils.remove(next);\r\n                    }else  if(next && next.tagName == 'P' && !domUtils.isEmptyBlock(next)){\r\n                        next.insertBefore(node,next.firstChild);\r\n                    }\r\n\r\n                    if(pre && pre.tagName == 'P' && domUtils.isEmptyBlock(pre)){\r\n                        domUtils.remove(pre)\r\n                    }\r\n                    if(next && next.tagName == 'P' && domUtils.isEmptyBlock(next)){\r\n                        domUtils.remove(next)\r\n                    }\r\n                    rng.selectNode(node).select();\r\n                    me.fireEvent('saveScene');\r\n\r\n                }\r\n\r\n            }\r\n\r\n        })\r\n    });\r\n    me.addListener('keyup', function(type, evt) {\r\n        var keyCode = evt.keyCode || evt.which;\r\n        if (keyCode == 13) {\r\n            var rng = me.selection.getRange(),node;\r\n            if(node = domUtils.findParentByTagName(rng.startContainer,'p',true)){\r\n                if(domUtils.getComputedStyle(node,'text-align') == 'center'){\r\n                    domUtils.removeStyle(node,'text-align')\r\n                }\r\n            }\r\n        }\r\n    })\r\n};\r\n\n\n// plugins/undo.js\n/**\r\n * undo redo\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 撤销上一次执行的命令\r\n * @command undo\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'undo' );\r\n * ```\r\n */\r\n\r\n/**\r\n * 重做上一次执行的命令\r\n * @command redo\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'redo' );\r\n * ```\r\n */\r\n\r\nUE.plugins['undo'] = function () {\r\n    var saveSceneTimer;\r\n    var me = this,\r\n        maxUndoCount = me.options.maxUndoCount || 20,\r\n        maxInputCount = me.options.maxInputCount || 20,\r\n        fillchar = new RegExp(domUtils.fillChar + '|<\\/hr>', 'gi');// ie会产生多余的</hr>\r\n    var noNeedFillCharTags = {\r\n        ol:1,ul:1,table:1,tbody:1,tr:1,body:1\r\n    };\r\n    var orgState = me.options.autoClearEmptyNode;\r\n    function compareAddr(indexA, indexB) {\r\n        if (indexA.length != indexB.length)\r\n            return 0;\r\n        for (var i = 0, l = indexA.length; i < l; i++) {\r\n            if (indexA[i] != indexB[i])\r\n                return 0\r\n        }\r\n        return 1;\r\n    }\r\n\r\n    function compareRangeAddress(rngAddrA, rngAddrB) {\r\n        if (rngAddrA.collapsed != rngAddrB.collapsed) {\r\n            return 0;\r\n        }\r\n        if (!compareAddr(rngAddrA.startAddress, rngAddrB.startAddress) || !compareAddr(rngAddrA.endAddress, rngAddrB.endAddress)) {\r\n            return 0;\r\n        }\r\n        return 1;\r\n    }\r\n\r\n    function UndoManager() {\r\n        this.list = [];\r\n        this.index = 0;\r\n        this.hasUndo = false;\r\n        this.hasRedo = false;\r\n        this.undo = function () {\r\n            if (this.hasUndo) {\r\n                if (!this.list[this.index - 1] && this.list.length == 1) {\r\n                    this.reset();\r\n                    return;\r\n                }\r\n                while (this.list[this.index].content == this.list[this.index - 1].content) {\r\n                    this.index--;\r\n                    if (this.index == 0) {\r\n                        return this.restore(0);\r\n                    }\r\n                }\r\n                this.restore(--this.index);\r\n            }\r\n        };\r\n        this.redo = function () {\r\n            if (this.hasRedo) {\r\n                while (this.list[this.index].content == this.list[this.index + 1].content) {\r\n                    this.index++;\r\n                    if (this.index == this.list.length - 1) {\r\n                        return this.restore(this.index);\r\n                    }\r\n                }\r\n                this.restore(++this.index);\r\n            }\r\n        };\r\n\r\n        this.restore = function () {\r\n            var me = this.editor;\r\n            var scene = this.list[this.index];\r\n            var root = UE.htmlparser(scene.content.replace(fillchar, ''));\r\n            me.options.autoClearEmptyNode = false;\r\n            me.filterInputRule(root);\r\n            me.options.autoClearEmptyNode = orgState;\r\n            //trace:873\r\n            //去掉展位符\r\n            me.document.body.innerHTML = root.toHtml();\r\n            me.fireEvent('afterscencerestore');\r\n            //处理undo后空格不展位的问题\r\n            if (browser.ie) {\r\n                utils.each(domUtils.getElementsByTagName(me.document,'td th caption p'),function(node){\r\n                    if(domUtils.isEmptyNode(node)){\r\n                        domUtils.fillNode(me.document, node);\r\n                    }\r\n                })\r\n            }\r\n\r\n            try{\r\n                var rng = new dom.Range(me.document).moveToAddress(scene.address);\r\n                rng.select(noNeedFillCharTags[rng.startContainer.nodeName.toLowerCase()]);\r\n            }catch(e){}\r\n\r\n            this.update();\r\n            this.clearKey();\r\n            //不能把自己reset了\r\n            me.fireEvent('reset', true);\r\n        };\r\n\r\n        this.getScene = function () {\r\n            var me = this.editor;\r\n            var rng = me.selection.getRange(),\r\n                rngAddress = rng.createAddress(false,true);\r\n            me.fireEvent('beforegetscene');\r\n            var root = UE.htmlparser(me.body.innerHTML);\r\n            me.options.autoClearEmptyNode = false;\r\n            me.filterOutputRule(root);\r\n            me.options.autoClearEmptyNode = orgState;\r\n            var cont = root.toHtml();\r\n            //trace:3461\r\n            //这个会引起回退时导致空格丢失的情况\r\n//            browser.ie && (cont = cont.replace(/>&nbsp;</g, '><').replace(/\\s*</g, '<').replace(/>\\s*/g, '>'));\r\n            me.fireEvent('aftergetscene');\r\n\r\n            return {\r\n                address:rngAddress,\r\n                content:cont\r\n            }\r\n        };\r\n        this.save = function (notCompareRange,notSetCursor) {\r\n            clearTimeout(saveSceneTimer);\r\n            var currentScene = this.getScene(notSetCursor),\r\n                lastScene = this.list[this.index];\r\n\r\n            if(lastScene && lastScene.content != currentScene.content){\r\n                me.trigger('contentchange')\r\n            }\r\n            //内容相同位置相同不存\r\n            if (lastScene && lastScene.content == currentScene.content &&\r\n                ( notCompareRange ? 1 : compareRangeAddress(lastScene.address, currentScene.address) )\r\n                ) {\r\n                return;\r\n            }\r\n            this.list = this.list.slice(0, this.index + 1);\r\n            this.list.push(currentScene);\r\n            //如果大于最大数量了，就把最前的剔除\r\n            if (this.list.length > maxUndoCount) {\r\n                this.list.shift();\r\n            }\r\n            this.index = this.list.length - 1;\r\n            this.clearKey();\r\n            //跟新undo/redo状态\r\n            this.update();\r\n\r\n        };\r\n        this.update = function () {\r\n            this.hasRedo = !!this.list[this.index + 1];\r\n            this.hasUndo = !!this.list[this.index - 1];\r\n        };\r\n        this.reset = function () {\r\n            this.list = [];\r\n            this.index = 0;\r\n            this.hasUndo = false;\r\n            this.hasRedo = false;\r\n            this.clearKey();\r\n        };\r\n        this.clearKey = function () {\r\n            keycont = 0;\r\n            lastKeyCode = null;\r\n        };\r\n    }\r\n\r\n    me.undoManger = new UndoManager();\r\n    me.undoManger.editor = me;\r\n    function saveScene() {\r\n        this.undoManger.save();\r\n    }\r\n\r\n    me.addListener('saveScene', function () {\r\n        var args = Array.prototype.splice.call(arguments,1);\r\n        this.undoManger.save.apply(this.undoManger,args);\r\n    });\r\n\r\n//    me.addListener('beforeexeccommand', saveScene);\r\n//    me.addListener('afterexeccommand', saveScene);\r\n\r\n    me.addListener('reset', function (type, exclude) {\r\n        if (!exclude) {\r\n            this.undoManger.reset();\r\n        }\r\n    });\r\n    me.commands['redo'] = me.commands['undo'] = {\r\n        execCommand:function (cmdName) {\r\n            this.undoManger[cmdName]();\r\n        },\r\n        queryCommandState:function (cmdName) {\r\n            return this.undoManger['has' + (cmdName.toLowerCase() == 'undo' ? 'Undo' : 'Redo')] ? 0 : -1;\r\n        },\r\n        notNeedUndo:1\r\n    };\r\n\r\n    var keys = {\r\n            //  /*Backspace*/ 8:1, /*Delete*/ 46:1,\r\n            /*Shift*/ 16:1, /*Ctrl*/ 17:1, /*Alt*/ 18:1,\r\n            37:1, 38:1, 39:1, 40:1\r\n\r\n        },\r\n        keycont = 0,\r\n        lastKeyCode;\r\n    //输入法状态下不计算字符数\r\n    var inputType = false;\r\n    me.addListener('ready', function () {\r\n        domUtils.on(this.body, 'compositionstart', function () {\r\n            inputType = true;\r\n        });\r\n        domUtils.on(this.body, 'compositionend', function () {\r\n            inputType = false;\r\n        })\r\n    });\r\n    //快捷键\r\n    me.addshortcutkey({\r\n        \"Undo\":\"ctrl+90\", //undo\r\n        \"Redo\":\"ctrl+89\" //redo\r\n\r\n    });\r\n    var isCollapsed = true;\r\n    me.addListener('keydown', function (type, evt) {\r\n\r\n        var me = this;\r\n        var keyCode = evt.keyCode || evt.which;\r\n        if (!keys[keyCode] && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) {\r\n            if (inputType)\r\n                return;\r\n\r\n            if(!me.selection.getRange().collapsed){\r\n                me.undoManger.save(false,true);\r\n                isCollapsed = false;\r\n                return;\r\n            }\r\n            if (me.undoManger.list.length == 0) {\r\n                me.undoManger.save(true);\r\n            }\r\n            clearTimeout(saveSceneTimer);\r\n            function save(cont){\r\n                cont.undoManger.save(false,true);\r\n                cont.fireEvent('selectionchange');\r\n            }\r\n            saveSceneTimer = setTimeout(function(){\r\n                if(inputType){\r\n                    var interalTimer = setInterval(function(){\r\n                        if(!inputType){\r\n                            save(me);\r\n                            clearInterval(interalTimer)\r\n                        }\r\n                    },300)\r\n                    return;\r\n                }\r\n                save(me);\r\n            },200);\r\n\r\n            lastKeyCode = keyCode;\r\n            keycont++;\r\n            if (keycont >= maxInputCount ) {\r\n                save(me)\r\n            }\r\n        }\r\n    });\r\n    me.addListener('keyup', function (type, evt) {\r\n        var keyCode = evt.keyCode || evt.which;\r\n        if (!keys[keyCode] && !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) {\r\n            if (inputType)\r\n                return;\r\n            if(!isCollapsed){\r\n                this.undoManger.save(false,true);\r\n                isCollapsed = true;\r\n            }\r\n        }\r\n    });\r\n    //扩展实例，添加关闭和开启命令undo\r\n    me.stopCmdUndo = function(){\r\n        me.__hasEnterExecCommand = true;\r\n    };\r\n    me.startCmdUndo = function(){\r\n        me.__hasEnterExecCommand = false;\r\n    }\r\n};\r\n\n\n// plugins/copy.js\nUE.plugin.register('copy', function () {\n\n    var me = this;\n\n    function initZeroClipboard() {\n\n        ZeroClipboard.config({\n            debug: false,\n            swfPath: me.options.UEDITOR_HOME_URL + 'third-party/zeroclipboard/ZeroClipboard.swf'\n        });\n\n        var client = me.zeroclipboard = new ZeroClipboard();\n\n        // 复制内容\n        client.on('copy', function (e) {\n            var client = e.client,\n                rng = me.selection.getRange(),\n                div = document.createElement('div');\n\n            div.appendChild(rng.cloneContents());\n            client.setText(div.innerText || div.textContent);\n            client.setHtml(div.innerHTML);\n            rng.select();\n        });\n        // hover事件传递到target\n        client.on('mouseover mouseout', function (e) {\n            var target = e.target;\n            if (e.type == 'mouseover') {\n                domUtils.addClass(target, 'edui-state-hover');\n            } else if (e.type == 'mouseout') {\n                domUtils.removeClasses(target, 'edui-state-hover');\n            }\n        });\n        // flash加载不成功\n        client.on('wrongflash noflash', function () {\n            ZeroClipboard.destroy();\n        });\n    }\n\n    return {\n        bindEvents: {\n            'ready': function () {\n                if (!browser.ie) {\n                    if (window.ZeroClipboard) {\n                        initZeroClipboard();\n                    } else {\n                        utils.loadFile(document, {\n                            src: me.options.UEDITOR_HOME_URL + \"third-party/zeroclipboard/ZeroClipboard.js\",\n                            tag: \"script\",\n                            type: \"text/javascript\",\n                            defer: \"defer\"\n                        }, function () {\n                            initZeroClipboard();\n                        });\n                    }\n                }\n            }\n        },\n        commands: {\n            'copy': {\n                execCommand: function (cmd) {\n                    if (!me.document.execCommand('copy')) {\n                        alert(me.getLang('copymsg'));\n                    }\n                }\n            }\n        }\n    }\n});\n\n\n// plugins/paste.js\n///import core\n///import plugins/inserthtml.js\n///import plugins/undo.js\n///import plugins/serialize.js\n///commands 粘贴\n///commandsName  PastePlain\n///commandsTitle  纯文本粘贴模式\n/**\n * @description 粘贴\n * @author zhanyi\n */\nUE.plugins['paste'] = function () {\n    function getClipboardData(callback) {\n        var doc = this.document;\n        if (doc.getElementById('baidu_pastebin')) {\n            return;\n        }\n        var range = this.selection.getRange(),\n            bk = range.createBookmark(),\n        //创建剪贴的容器div\n            pastebin = doc.createElement('div');\n        pastebin.id = 'baidu_pastebin';\n        // Safari 要求div必须有内容，才能粘贴内容进来\n        browser.webkit && pastebin.appendChild(doc.createTextNode(domUtils.fillChar + domUtils.fillChar));\n        doc.body.appendChild(pastebin);\n        //trace:717 隐藏的span不能得到top\n        //bk.start.innerHTML = '&nbsp;';\n        bk.start.style.display = '';\n        pastebin.style.cssText = \"position:absolute;width:1px;height:1px;overflow:hidden;left:-1000px;white-space:nowrap;top:\" +\n            //要在现在光标平行的位置加入，否则会出现跳动的问题\n            domUtils.getXY(bk.start).y + 'px';\n\n        range.selectNodeContents(pastebin).select(true);\n\n        setTimeout(function () {\n            if (browser.webkit) {\n                for (var i = 0, pastebins = doc.querySelectorAll('#baidu_pastebin'), pi; pi = pastebins[i++];) {\n                    if (domUtils.isEmptyNode(pi)) {\n                        domUtils.remove(pi);\n                    } else {\n                        pastebin = pi;\n                        break;\n                    }\n                }\n            }\n            try {\n                pastebin.parentNode.removeChild(pastebin);\n            } catch (e) {\n            }\n            range.moveToBookmark(bk).select(true);\n            callback(pastebin);\n        }, 0);\n    }\n\n    var me = this;\n\n    me.setOpt({\n        retainOnlyLabelPasted : false\n    });\n\n    var txtContent, htmlContent, address;\n\n    function getPureHtml(html){\n        return html.replace(/<(\\/?)([\\w\\-]+)([^>]*)>/gi, function (a, b, tagName, attrs) {\n            tagName = tagName.toLowerCase();\n            if ({img: 1}[tagName]) {\n                return a;\n            }\n            attrs = attrs.replace(/([\\w\\-]*?)\\s*=\\s*((\"([^\"]*)\")|('([^']*)')|([^\\s>]+))/gi, function (str, atr, val) {\n                if ({\n                    'src': 1,\n                    'href': 1,\n                    'name': 1\n                }[atr.toLowerCase()]) {\n                    return atr + '=' + val + ' '\n                }\n                return ''\n            });\n            if ({\n                'span': 1,\n                'div': 1\n            }[tagName]) {\n                return ''\n            } else {\n\n                return '<' + b + tagName + ' ' + utils.trim(attrs) + '>'\n            }\n\n        });\n    }\n    function filter(div) {\n        var html;\n        if (div.firstChild) {\n            //去掉cut中添加的边界值\n            var nodes = domUtils.getElementsByTagName(div, 'span');\n            for (var i = 0, ni; ni = nodes[i++];) {\n                if (ni.id == '_baidu_cut_start' || ni.id == '_baidu_cut_end') {\n                    domUtils.remove(ni);\n                }\n            }\n\n            if (browser.webkit) {\n\n                var brs = div.querySelectorAll('div br');\n                for (var i = 0, bi; bi = brs[i++];) {\n                    var pN = bi.parentNode;\n                    if (pN.tagName == 'DIV' && pN.childNodes.length == 1) {\n                        pN.innerHTML = '<p><br/></p>';\n                        domUtils.remove(pN);\n                    }\n                }\n                var divs = div.querySelectorAll('#baidu_pastebin');\n                for (var i = 0, di; di = divs[i++];) {\n                    var tmpP = me.document.createElement('p');\n                    di.parentNode.insertBefore(tmpP, di);\n                    while (di.firstChild) {\n                        tmpP.appendChild(di.firstChild);\n                    }\n                    domUtils.remove(di);\n                }\n\n                var metas = div.querySelectorAll('meta');\n                for (var i = 0, ci; ci = metas[i++];) {\n                    domUtils.remove(ci);\n                }\n\n                var brs = div.querySelectorAll('br');\n                for (i = 0; ci = brs[i++];) {\n                    if (/^apple-/i.test(ci.className)) {\n                        domUtils.remove(ci);\n                    }\n                }\n            }\n            if (browser.gecko) {\n                var dirtyNodes = div.querySelectorAll('[_moz_dirty]');\n                for (i = 0; ci = dirtyNodes[i++];) {\n                    ci.removeAttribute('_moz_dirty');\n                }\n            }\n            if (!browser.ie) {\n                var spans = div.querySelectorAll('span.Apple-style-span');\n                for (var i = 0, ci; ci = spans[i++];) {\n                    domUtils.remove(ci, true);\n                }\n            }\n\n            //ie下使用innerHTML会产生多余的\\r\\n字符，也会产生&nbsp;这里过滤掉\n            html = div.innerHTML;//.replace(/>(?:(\\s|&nbsp;)*?)</g,'><');\n\n            //过滤word粘贴过来的冗余属性\n            html = UE.filterWord(html);\n            //取消了忽略空白的第二个参数，粘贴过来的有些是有空白的，会被套上相关的标签\n            var root = UE.htmlparser(html);\n            //如果给了过滤规则就先进行过滤\n            if (me.options.filterRules) {\n                UE.filterNode(root, me.options.filterRules);\n            }\n            //执行默认的处理\n            me.filterInputRule(root);\n            //针对chrome的处理\n            if (browser.webkit) {\n                var br = root.lastChild();\n                if (br && br.type == 'element' && br.tagName == 'br') {\n                    root.removeChild(br)\n                }\n                utils.each(me.body.querySelectorAll('div'), function (node) {\n                    if (domUtils.isEmptyBlock(node)) {\n                        domUtils.remove(node,true)\n                    }\n                })\n            }\n            html = {'html': root.toHtml()};\n            me.fireEvent('beforepaste', html, root);\n            //抢了默认的粘贴，那后边的内容就不执行了，比如表格粘贴\n            if(!html.html){\n                return;\n            }\n            root = UE.htmlparser(html.html,true);\n            //如果开启了纯文本模式\n            if (me.queryCommandState('pasteplain') === 1) {\n                me.execCommand('insertHtml', UE.filterNode(root, me.options.filterTxtRules).toHtml(), true);\n            } else {\n                //文本模式\n                UE.filterNode(root, me.options.filterTxtRules);\n                txtContent = root.toHtml();\n                //完全模式\n                htmlContent = html.html;\n\n                address = me.selection.getRange().createAddress(true);\n                me.execCommand('insertHtml', me.getOpt('retainOnlyLabelPasted') === true ?  getPureHtml(htmlContent) : htmlContent, true);\n            }\n            me.fireEvent(\"afterpaste\", html);\n        }\n    }\n\n    me.addListener('pasteTransfer', function (cmd, plainType) {\n\n        if (address && txtContent && htmlContent && txtContent != htmlContent) {\n            var range = me.selection.getRange();\n            range.moveToAddress(address, true);\n\n            if (!range.collapsed) {\n\n                while (!domUtils.isBody(range.startContainer)\n                    ) {\n                    var start = range.startContainer;\n                    if(start.nodeType == 1){\n                        start = start.childNodes[range.startOffset];\n                        if(!start){\n                            range.setStartBefore(range.startContainer);\n                            continue;\n                        }\n                        var pre = start.previousSibling;\n\n                        if(pre && pre.nodeType == 3 && new RegExp('^[\\n\\r\\t '+domUtils.fillChar+']*$').test(pre.nodeValue)){\n                            range.setStartBefore(pre)\n                        }\n                    }\n                    if(range.startOffset == 0){\n                        range.setStartBefore(range.startContainer);\n                    }else{\n                        break;\n                    }\n\n                }\n                while (!domUtils.isBody(range.endContainer)\n                    ) {\n                    var end = range.endContainer;\n                    if(end.nodeType == 1){\n                        end = end.childNodes[range.endOffset];\n                        if(!end){\n                            range.setEndAfter(range.endContainer);\n                            continue;\n                        }\n                        var next = end.nextSibling;\n                        if(next && next.nodeType == 3 && new RegExp('^[\\n\\r\\t'+domUtils.fillChar+']*$').test(next.nodeValue)){\n                            range.setEndAfter(next)\n                        }\n                    }\n                    if(range.endOffset == range.endContainer[range.endContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length){\n                        range.setEndAfter(range.endContainer);\n                    }else{\n                        break;\n                    }\n\n                }\n\n            }\n\n            range.deleteContents();\n            range.select(true);\n            me.__hasEnterExecCommand = true;\n            var html = htmlContent;\n            if (plainType === 2 ) {\n                html = getPureHtml(html);\n            } else if (plainType) {\n                html = txtContent;\n            }\n            me.execCommand('inserthtml', html, true);\n            me.__hasEnterExecCommand = false;\n            var rng = me.selection.getRange();\n            while (!domUtils.isBody(rng.startContainer) && !rng.startOffset &&\n                rng.startContainer[rng.startContainer.nodeType == 3 ? 'nodeValue' : 'childNodes'].length\n                ) {\n                rng.setStartBefore(rng.startContainer);\n            }\n            var tmpAddress = rng.createAddress(true);\n            address.endAddress = tmpAddress.startAddress;\n        }\n    });\n\n    me.addListener('ready', function () {\n        domUtils.on(me.body, 'cut', function () {\n            var range = me.selection.getRange();\n            if (!range.collapsed && me.undoManger) {\n                me.undoManger.save();\n            }\n        });\n\n        //ie下beforepaste在点击右键时也会触发，所以用监控键盘才处理\n        domUtils.on(me.body, browser.ie || browser.opera ? 'keydown' : 'paste', function (e) {\n            if ((browser.ie || browser.opera) && ((!e.ctrlKey && !e.metaKey) || e.keyCode != '86')) {\n                return;\n            }\n            getClipboardData.call(me, function (div) {\n                filter(div);\n            });\n        });\n\n    });\n\n    me.commands['paste'] = {\n        execCommand: function (cmd) {\n            if (browser.ie) {\n                getClipboardData.call(me, function (div) {\n                    filter(div);\n                });\n                me.document.execCommand('paste');\n            } else {\n                alert(me.getLang('pastemsg'));\n            }\n        }\n    }\n};\n\n\n\n// plugins/puretxtpaste.js\n/**\r\n * 纯文本粘贴插件\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\nUE.plugins['pasteplain'] = function(){\r\n    var me = this;\r\n    me.setOpt({\r\n        'pasteplain':false,\r\n        'filterTxtRules' : function(){\r\n            function transP(node){\r\n                node.tagName = 'p';\r\n                node.setStyle();\r\n            }\r\n            function removeNode(node){\r\n                node.parentNode.removeChild(node,true)\r\n            }\r\n            return {\r\n                //直接删除及其字节点内容\r\n                '-' : 'script style object iframe embed input select',\r\n                'p': {$:{}},\r\n                'br':{$:{}},\r\n                div: function (node) {\r\n                    var tmpNode, p = UE.uNode.createElement('p');\r\n                    while (tmpNode = node.firstChild()) {\r\n                        if (tmpNode.type == 'text' || !UE.dom.dtd.$block[tmpNode.tagName]) {\r\n                            p.appendChild(tmpNode);\r\n                        } else {\r\n                            if (p.firstChild()) {\r\n                                node.parentNode.insertBefore(p, node);\r\n                                p = UE.uNode.createElement('p');\r\n                            } else {\r\n                                node.parentNode.insertBefore(tmpNode, node);\r\n                            }\r\n                        }\r\n                    }\r\n                    if (p.firstChild()) {\r\n                        node.parentNode.insertBefore(p, node);\r\n                    }\r\n                    node.parentNode.removeChild(node);\r\n                },\r\n                ol: removeNode,\r\n                ul: removeNode,\r\n                dl:removeNode,\r\n                dt:removeNode,\r\n                dd:removeNode,\r\n                'li':removeNode,\r\n                'caption':transP,\r\n                'th':transP,\r\n                'tr':transP,\r\n                'h1':transP,'h2':transP,'h3':transP,'h4':transP,'h5':transP,'h6':transP,\r\n                'td':function(node){\r\n                        //没有内容的td直接删掉\r\n                        var txt = !!node.innerText();\r\n                        if(txt){\r\n                         node.parentNode.insertAfter(UE.uNode.createText(' &nbsp; &nbsp;'),node);\r\n                    }\r\n                    node.parentNode.removeChild(node,node.innerText())\r\n                }\r\n            }\r\n        }()\r\n    });\r\n    //暂时这里支持一下老版本的属性\r\n    var pasteplain = me.options.pasteplain;\r\n\r\n    /**\r\n     * 启用或取消纯文本粘贴模式\r\n     * @command pasteplain\r\n     * @method execCommand\r\n     * @param { String } cmd 命令字符串\r\n     * @example\r\n     * ```javascript\r\n     * editor.queryCommandState( 'pasteplain' );\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 查询当前是否处于纯文本粘贴模式\r\n     * @command pasteplain\r\n     * @method queryCommandState\r\n     * @param { String } cmd 命令字符串\r\n     * @return { int } 如果处于纯文本模式，返回1，否则，返回0\r\n     * @example\r\n     * ```javascript\r\n     * editor.queryCommandState( 'pasteplain' );\r\n     * ```\r\n     */\r\n    me.commands['pasteplain'] = {\r\n        queryCommandState: function (){\r\n            return pasteplain ? 1 : 0;\r\n        },\r\n        execCommand: function (){\r\n            pasteplain = !pasteplain|0;\r\n        },\r\n        notNeedUndo : 1\r\n    };\r\n};\n\n// plugins/list.js\n/**\r\n * 有序列表,无序列表插件\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\nUE.plugins['list'] = function () {\r\n    var me = this,\r\n        notExchange = {\r\n            'TD':1,\r\n            'PRE':1,\r\n            'BLOCKQUOTE':1\r\n        };\r\n    var customStyle = {\r\n        'cn' : 'cn-1-',\r\n        'cn1' : 'cn-2-',\r\n        'cn2' : 'cn-3-',\r\n        'num':  'num-1-',\r\n        'num1' : 'num-2-',\r\n        'num2' : 'num-3-',\r\n        'dash'  : 'dash',\r\n        'dot':'dot'\r\n    };\r\n\r\n    me.setOpt( {\r\n        'autoTransWordToList':false,\r\n        'insertorderedlist':{\r\n            'num':'',\r\n            'num1':'',\r\n            'num2':'',\r\n            'cn':'',\r\n            'cn1':'',\r\n            'cn2':'',\r\n            'decimal':'',\r\n            'lower-alpha':'',\r\n            'lower-roman':'',\r\n            'upper-alpha':'',\r\n            'upper-roman':''\r\n        },\r\n        'insertunorderedlist':{\r\n            'circle':'',\r\n            'disc':'',\r\n            'square':'',\r\n            'dash' : '',\r\n            'dot':''\r\n        },\r\n        listDefaultPaddingLeft : '30',\r\n        listiconpath : 'http://bs.baidu.com/listicon/',\r\n        maxListLevel : -1,//-1不限制\r\n        disablePInList:false\r\n    } );\r\n    function listToArray(list){\r\n        var arr = [];\r\n        for(var p in list){\r\n            arr.push(p)\r\n        }\r\n        return arr;\r\n    }\r\n    var listStyle = {\r\n        'OL':listToArray(me.options.insertorderedlist),\r\n        'UL':listToArray(me.options.insertunorderedlist)\r\n    };\r\n    var liiconpath = me.options.listiconpath;\r\n\r\n    //根据用户配置，调整customStyle\r\n    for(var s in customStyle){\r\n        if(!me.options.insertorderedlist.hasOwnProperty(s) && !me.options.insertunorderedlist.hasOwnProperty(s)){\r\n            delete customStyle[s];\r\n        }\r\n    }\r\n\r\n    me.ready(function () {\r\n        var customCss = [];\r\n        for(var p in customStyle){\r\n            if(p == 'dash' || p == 'dot'){\r\n                customCss.push('li.list-' + customStyle[p] + '{background-image:url(' + liiconpath +customStyle[p]+'.gif)}');\r\n                customCss.push('ul.custom_'+p+'{list-style:none;}ul.custom_'+p+' li{background-position:0 3px;background-repeat:no-repeat}');\r\n            }else{\r\n                for(var i= 0;i<99;i++){\r\n                    customCss.push('li.list-' + customStyle[p] + i + '{background-image:url(' + liiconpath + 'list-'+customStyle[p] + i + '.gif)}')\r\n                }\r\n                customCss.push('ol.custom_'+p+'{list-style:none;}ol.custom_'+p+' li{background-position:0 3px;background-repeat:no-repeat}');\r\n            }\r\n            switch(p){\r\n                case 'cn':\r\n                    customCss.push('li.list-'+p+'-paddingleft-1{padding-left:25px}');\r\n                    customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}');\r\n                    customCss.push('li.list-'+p+'-paddingleft-3{padding-left:55px}');\r\n                    break;\r\n                case 'cn1':\r\n                    customCss.push('li.list-'+p+'-paddingleft-1{padding-left:30px}');\r\n                    customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}');\r\n                    customCss.push('li.list-'+p+'-paddingleft-3{padding-left:55px}');\r\n                    break;\r\n                case 'cn2':\r\n                    customCss.push('li.list-'+p+'-paddingleft-1{padding-left:40px}');\r\n                    customCss.push('li.list-'+p+'-paddingleft-2{padding-left:55px}');\r\n                    customCss.push('li.list-'+p+'-paddingleft-3{padding-left:68px}');\r\n                    break;\r\n                case 'num':\r\n                case 'num1':\r\n                    customCss.push('li.list-'+p+'-paddingleft-1{padding-left:25px}');\r\n                    break;\r\n                case 'num2':\r\n                    customCss.push('li.list-'+p+'-paddingleft-1{padding-left:35px}');\r\n                    customCss.push('li.list-'+p+'-paddingleft-2{padding-left:40px}');\r\n                    break;\r\n                case 'dash':\r\n                    customCss.push('li.list-'+p+'-paddingleft{padding-left:35px}');\r\n                    break;\r\n                case 'dot':\r\n                    customCss.push('li.list-'+p+'-paddingleft{padding-left:20px}');\r\n            }\r\n        }\r\n        customCss.push('.list-paddingleft-1{padding-left:0}');\r\n        customCss.push('.list-paddingleft-2{padding-left:'+me.options.listDefaultPaddingLeft+'px}');\r\n        customCss.push('.list-paddingleft-3{padding-left:'+me.options.listDefaultPaddingLeft*2+'px}');\r\n        //如果不给宽度会在自定应样式里出现滚动条\r\n        utils.cssRule('list', 'ol,ul{margin:0;pading:0;'+(browser.ie ? '' : 'width:95%')+'}li{clear:both;}'+customCss.join('\\n'), me.document);\r\n    });\r\n    //单独处理剪切的问题\r\n    me.ready(function(){\r\n        domUtils.on(me.body,'cut',function(){\r\n            setTimeout(function(){\r\n                var rng = me.selection.getRange(),li;\r\n                //trace:3416\r\n                if(!rng.collapsed){\r\n                    if(li = domUtils.findParentByTagName(rng.startContainer,'li',true)){\r\n                        if(!li.nextSibling && domUtils.isEmptyBlock(li)){\r\n                            var pn = li.parentNode,node;\r\n                            if(node = pn.previousSibling){\r\n                                domUtils.remove(pn);\r\n                                rng.setStartAtLast(node).collapse(true);\r\n                                rng.select(true);\r\n                            }else if(node = pn.nextSibling){\r\n                                domUtils.remove(pn);\r\n                                rng.setStartAtFirst(node).collapse(true);\r\n                                rng.select(true);\r\n                            }else{\r\n                                var tmpNode = me.document.createElement('p');\r\n                                domUtils.fillNode(me.document,tmpNode);\r\n                                pn.parentNode.insertBefore(tmpNode,pn);\r\n                                domUtils.remove(pn);\r\n                                rng.setStart(tmpNode,0).collapse(true);\r\n                                rng.select(true);\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n\r\n            })\r\n        })\r\n    });\r\n\r\n    function getStyle(node){\r\n        var cls = node.className;\r\n        if(domUtils.hasClass(node,/custom_/)){\r\n            return cls.match(/custom_(\\w+)/)[1]\r\n        }\r\n        return domUtils.getStyle(node, 'list-style-type')\r\n\r\n    }\r\n\r\n    me.addListener('beforepaste',function(type,html){\r\n        var me = this,\r\n            rng = me.selection.getRange(),li;\r\n        var root = UE.htmlparser(html.html,true);\r\n        if(li = domUtils.findParentByTagName(rng.startContainer,'li',true)){\r\n            var list = li.parentNode,tagName = list.tagName == 'OL' ? 'ul':'ol';\r\n            utils.each(root.getNodesByTagName(tagName),function(n){\r\n                n.tagName = list.tagName;\r\n                n.setAttr();\r\n                if(n.parentNode === root){\r\n                    type = getStyle(list) || (list.tagName == 'OL' ? 'decimal' : 'disc')\r\n                }else{\r\n                    var className = n.parentNode.getAttr('class');\r\n                    if(className && /custom_/.test(className)){\r\n                        type = className.match(/custom_(\\w+)/)[1]\r\n                    }else{\r\n                        type = n.parentNode.getStyle('list-style-type');\r\n                    }\r\n                    if(!type){\r\n                        type = list.tagName == 'OL' ? 'decimal' : 'disc';\r\n                    }\r\n                }\r\n                var index = utils.indexOf(listStyle[list.tagName], type);\r\n                if(n.parentNode !== root)\r\n                    index = index + 1 == listStyle[list.tagName].length ? 0 : index + 1;\r\n                var currentStyle = listStyle[list.tagName][index];\r\n                if(customStyle[currentStyle]){\r\n                    n.setAttr('class', 'custom_' + currentStyle)\r\n\r\n                }else{\r\n                    n.setStyle('list-style-type',currentStyle)\r\n                }\r\n            })\r\n\r\n        }\r\n\r\n        html.html = root.toHtml();\r\n    });\r\n    //导出时，去掉p标签\r\n    me.getOpt('disablePInList') === true && me.addOutputRule(function(root){\r\n        utils.each(root.getNodesByTagName('li'),function(li){\r\n            var newChildrens = [],index=0;\r\n            utils.each(li.children,function(n){\r\n                if(n.tagName == 'p'){\r\n                    var tmpNode;\r\n                    while(tmpNode = n.children.pop()) {\r\n                        newChildrens.splice(index,0,tmpNode);\r\n                        tmpNode.parentNode = li;\r\n                        lastNode = tmpNode;\r\n                    }\r\n                    tmpNode = newChildrens[newChildrens.length-1];\r\n                    if(!tmpNode || tmpNode.type != 'element' || tmpNode.tagName != 'br'){\r\n                        var br = UE.uNode.createElement('br');\r\n                        br.parentNode = li;\r\n                        newChildrens.push(br);\r\n                    }\r\n\r\n                    index = newChildrens.length;\r\n                }\r\n            });\r\n            if(newChildrens.length){\r\n                li.children = newChildrens;\r\n            }\r\n        });\r\n    });\r\n    //进入编辑器的li要套p标签\r\n    me.addInputRule(function(root){\r\n        utils.each(root.getNodesByTagName('li'),function(li){\r\n            var tmpP = UE.uNode.createElement('p');\r\n            for(var i= 0,ci;ci=li.children[i];){\r\n                if(ci.type == 'text' || dtd.p[ci.tagName]){\r\n                    tmpP.appendChild(ci);\r\n                }else{\r\n                    if(tmpP.firstChild()){\r\n                        li.insertBefore(tmpP,ci);\r\n                        tmpP = UE.uNode.createElement('p');\r\n                        i = i + 2;\r\n                    }else{\r\n                        i++;\r\n                    }\r\n\r\n                }\r\n            }\r\n            if(tmpP.firstChild() && !tmpP.parentNode || !li.firstChild()){\r\n                li.appendChild(tmpP);\r\n            }\r\n            //trace:3357\r\n            //p不能为空\r\n            if (!tmpP.firstChild()) {\r\n                tmpP.innerHTML(browser.ie ? '&nbsp;' : '<br/>')\r\n            }\r\n            //去掉末尾的空白\r\n            var p = li.firstChild();\r\n            var lastChild = p.lastChild();\r\n            if(lastChild && lastChild.type == 'text' && /^\\s*$/.test(lastChild.data)){\r\n                p.removeChild(lastChild)\r\n            }\r\n        });\r\n        if(me.options.autoTransWordToList){\r\n            var orderlisttype = {\r\n                    'num1':/^\\d+\\)/,\r\n                    'decimal':/^\\d+\\./,\r\n                    'lower-alpha':/^[a-z]+\\)/,\r\n                    'upper-alpha':/^[A-Z]+\\./,\r\n                    'cn':/^[\\u4E00\\u4E8C\\u4E09\\u56DB\\u516d\\u4e94\\u4e03\\u516b\\u4e5d]+[\\u3001]/,\r\n                    'cn2':/^\\([\\u4E00\\u4E8C\\u4E09\\u56DB\\u516d\\u4e94\\u4e03\\u516b\\u4e5d]+\\)/\r\n                },\r\n                unorderlisttype = {\r\n                    'square':'n'\r\n                };\r\n            function checkListType(content,container){\r\n                var span = container.firstChild();\r\n                if(span &&  span.type == 'element' && span.tagName == 'span' && /Wingdings|Symbol/.test(span.getStyle('font-family'))){\r\n                    for(var p in unorderlisttype){\r\n                        if(unorderlisttype[p] == span.data){\r\n                            return p\r\n                        }\r\n                    }\r\n                    return 'disc'\r\n                }\r\n                for(var p in orderlisttype){\r\n                    if(orderlisttype[p].test(content)){\r\n                        return p;\r\n                    }\r\n                }\r\n\r\n            }\r\n            utils.each(root.getNodesByTagName('p'),function(node){\r\n                if(node.getAttr('class') != 'MsoListParagraph'){\r\n                    return\r\n                }\r\n\r\n                //word粘贴过来的会带有margin要去掉,但这样也可能会误命中一些央视\r\n                node.setStyle('margin','');\r\n                node.setStyle('margin-left','');\r\n                node.setAttr('class','');\r\n\r\n                function appendLi(list,p,type){\r\n                    if(list.tagName == 'ol'){\r\n                        if(browser.ie){\r\n                            var first = p.firstChild();\r\n                            if(first.type =='element' && first.tagName == 'span' && orderlisttype[type].test(first.innerText())){\r\n                                p.removeChild(first);\r\n                            }\r\n                        }else{\r\n                            p.innerHTML(p.innerHTML().replace(orderlisttype[type],''));\r\n                        }\r\n                    }else{\r\n                        p.removeChild(p.firstChild())\r\n                    }\r\n\r\n                    var li = UE.uNode.createElement('li');\r\n                    li.appendChild(p);\r\n                    list.appendChild(li);\r\n                }\r\n                var tmp = node,type,cacheNode = node;\r\n\r\n                if(node.parentNode.tagName != 'li' && (type = checkListType(node.innerText(),node))){\r\n\r\n                    var list = UE.uNode.createElement(me.options.insertorderedlist.hasOwnProperty(type) ? 'ol' : 'ul');\r\n                    if(customStyle[type]){\r\n                        list.setAttr('class','custom_'+type)\r\n                    }else{\r\n                        list.setStyle('list-style-type',type)\r\n                    }\r\n                    while(node && node.parentNode.tagName != 'li' && checkListType(node.innerText(),node)){\r\n                        tmp = node.nextSibling();\r\n                        if(!tmp){\r\n                            node.parentNode.insertBefore(list,node)\r\n                        }\r\n                        appendLi(list,node,type);\r\n                        node = tmp;\r\n                    }\r\n                    if(!list.parentNode && node && node.parentNode){\r\n                        node.parentNode.insertBefore(list,node)\r\n                    }\r\n                }\r\n                var span = cacheNode.firstChild();\r\n                if(span && span.type == 'element' && span.tagName == 'span' && /^\\s*(&nbsp;)+\\s*$/.test(span.innerText())){\r\n                    span.parentNode.removeChild(span)\r\n                }\r\n            })\r\n        }\r\n\r\n    });\r\n\r\n    //调整索引标签\r\n    me.addListener('contentchange',function(){\r\n        adjustListStyle(me.document)\r\n    });\r\n\r\n    function adjustListStyle(doc,ignore){\r\n        utils.each(domUtils.getElementsByTagName(doc,'ol ul'),function(node){\r\n\r\n            if(!domUtils.inDoc(node,doc))\r\n                return;\r\n\r\n            var parent = node.parentNode;\r\n            if(parent.tagName == node.tagName){\r\n                var nodeStyleType = getStyle(node) || (node.tagName == 'OL' ? 'decimal' : 'disc'),\r\n                    parentStyleType = getStyle(parent) || (parent.tagName == 'OL' ? 'decimal' : 'disc');\r\n                if(nodeStyleType == parentStyleType){\r\n                    var styleIndex = utils.indexOf(listStyle[node.tagName], nodeStyleType);\r\n                    styleIndex = styleIndex + 1 == listStyle[node.tagName].length ? 0 : styleIndex + 1;\r\n                    setListStyle(node,listStyle[node.tagName][styleIndex])\r\n                }\r\n\r\n            }\r\n            var index = 0,type = 2;\r\n            if( domUtils.hasClass(node,/custom_/)){\r\n                if(!(/[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent,/custom_/))){\r\n                    type = 1;\r\n                }\r\n            }else{\r\n                if(/[ou]l/i.test(parent.tagName) && domUtils.hasClass(parent,/custom_/)){\r\n                    type = 3;\r\n                }\r\n            }\r\n\r\n            var style = domUtils.getStyle(node, 'list-style-type');\r\n            style && (node.style.cssText = 'list-style-type:' + style);\r\n            node.className = utils.trim(node.className.replace(/list-paddingleft-\\w+/,'')) + ' list-paddingleft-' + type;\r\n            utils.each(domUtils.getElementsByTagName(node,'li'),function(li){\r\n                li.style.cssText && (li.style.cssText = '');\r\n                if(!li.firstChild){\r\n                    domUtils.remove(li);\r\n                    return;\r\n                }\r\n                if(li.parentNode !== node){\r\n                    return;\r\n                }\r\n                index++;\r\n                if(domUtils.hasClass(node,/custom_/) ){\r\n                    var paddingLeft = 1,currentStyle = getStyle(node);\r\n                    if(node.tagName == 'OL'){\r\n                        if(currentStyle){\r\n                            switch(currentStyle){\r\n                                case 'cn' :\r\n                                case 'cn1':\r\n                                case 'cn2':\r\n                                    if(index > 10 && (index % 10 == 0 || index > 10 && index < 20)){\r\n                                        paddingLeft = 2\r\n                                    }else if(index > 20){\r\n                                        paddingLeft = 3\r\n                                    }\r\n                                    break;\r\n                                case 'num2' :\r\n                                    if(index > 9){\r\n                                        paddingLeft = 2\r\n                                    }\r\n                            }\r\n                        }\r\n                        li.className = 'list-'+customStyle[currentStyle]+ index + ' ' + 'list-'+currentStyle+'-paddingleft-' + paddingLeft;\r\n                    }else{\r\n                        li.className = 'list-'+customStyle[currentStyle]  + ' ' + 'list-'+currentStyle+'-paddingleft';\r\n                    }\r\n                }else{\r\n                    li.className = li.className.replace(/list-[\\w\\-]+/gi,'');\r\n                }\r\n                var className = li.getAttribute('class');\r\n                if(className !== null && !className.replace(/\\s/g,'')){\r\n                    domUtils.removeAttributes(li,'class')\r\n                }\r\n            });\r\n            !ignore && adjustList(node,node.tagName.toLowerCase(),getStyle(node)||domUtils.getStyle(node, 'list-style-type'),true);\r\n        })\r\n    }\r\n    function adjustList(list, tag, style,ignoreEmpty) {\r\n        var nextList = list.nextSibling;\r\n        if (nextList && nextList.nodeType == 1 && nextList.tagName.toLowerCase() == tag && (getStyle(nextList) || domUtils.getStyle(nextList, 'list-style-type') || (tag == 'ol' ? 'decimal' : 'disc')) == style) {\r\n            domUtils.moveChild(nextList, list);\r\n            if (nextList.childNodes.length == 0) {\r\n                domUtils.remove(nextList);\r\n            }\r\n        }\r\n        if(nextList && domUtils.isFillChar(nextList)){\r\n            domUtils.remove(nextList);\r\n        }\r\n        var preList = list.previousSibling;\r\n        if (preList && preList.nodeType == 1 && preList.tagName.toLowerCase() == tag && (getStyle(preList) || domUtils.getStyle(preList, 'list-style-type') || (tag == 'ol' ? 'decimal' : 'disc')) == style) {\r\n            domUtils.moveChild(list, preList);\r\n        }\r\n        if(preList && domUtils.isFillChar(preList)){\r\n            domUtils.remove(preList);\r\n        }\r\n        !ignoreEmpty && domUtils.isEmptyBlock(list) && domUtils.remove(list);\r\n        if(getStyle(list)){\r\n            adjustListStyle(list.ownerDocument,true)\r\n        }\r\n    }\r\n\r\n    function setListStyle(list,style){\r\n        if(customStyle[style]){\r\n            list.className = 'custom_' + style;\r\n        }\r\n        try{\r\n            domUtils.setStyle(list, 'list-style-type', style);\r\n        }catch(e){}\r\n    }\r\n    function clearEmptySibling(node) {\r\n        var tmpNode = node.previousSibling;\r\n        if (tmpNode && domUtils.isEmptyBlock(tmpNode)) {\r\n            domUtils.remove(tmpNode);\r\n        }\r\n        tmpNode = node.nextSibling;\r\n        if (tmpNode && domUtils.isEmptyBlock(tmpNode)) {\r\n            domUtils.remove(tmpNode);\r\n        }\r\n    }\r\n\r\n    me.addListener('keydown', function (type, evt) {\r\n        function preventAndSave() {\r\n            evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false);\r\n            me.fireEvent('contentchange');\r\n            me.undoManger && me.undoManger.save();\r\n        }\r\n        function findList(node,filterFn){\r\n            while(node && !domUtils.isBody(node)){\r\n                if(filterFn(node)){\r\n                    return null\r\n                }\r\n                if(node.nodeType == 1 && /[ou]l/i.test(node.tagName)){\r\n                    return node;\r\n                }\r\n                node = node.parentNode;\r\n            }\r\n            return null;\r\n        }\r\n        var keyCode = evt.keyCode || evt.which;\r\n        if (keyCode == 13 && !evt.shiftKey) {//回车\r\n            var rng = me.selection.getRange(),\r\n                parent = domUtils.findParent(rng.startContainer,function(node){return domUtils.isBlockElm(node)},true),\r\n                li = domUtils.findParentByTagName(rng.startContainer,'li',true);\r\n            if(parent && parent.tagName != 'PRE' && !li){\r\n                var html = parent.innerHTML.replace(new RegExp(domUtils.fillChar, 'g'),'');\r\n                if(/^\\s*1\\s*\\.[^\\d]/.test(html)){\r\n                    parent.innerHTML = html.replace(/^\\s*1\\s*\\./,'');\r\n                    rng.setStartAtLast(parent).collapse(true).select();\r\n                    me.__hasEnterExecCommand = true;\r\n                    me.execCommand('insertorderedlist');\r\n                    me.__hasEnterExecCommand = false;\r\n                }\r\n            }\r\n            var range = me.selection.getRange(),\r\n                start = findList(range.startContainer,function (node) {\r\n                    return node.tagName == 'TABLE';\r\n                }),\r\n                end = range.collapsed ? start : findList(range.endContainer,function (node) {\r\n                    return node.tagName == 'TABLE';\r\n                });\r\n\r\n            if (start && end && start === end) {\r\n\r\n                if (!range.collapsed) {\r\n                    start = domUtils.findParentByTagName(range.startContainer, 'li', true);\r\n                    end = domUtils.findParentByTagName(range.endContainer, 'li', true);\r\n                    if (start && end && start === end) {\r\n                        range.deleteContents();\r\n                        li = domUtils.findParentByTagName(range.startContainer, 'li', true);\r\n                        if (li && domUtils.isEmptyBlock(li)) {\r\n\r\n                            pre = li.previousSibling;\r\n                            next = li.nextSibling;\r\n                            p = me.document.createElement('p');\r\n\r\n                            domUtils.fillNode(me.document, p);\r\n                            parentList = li.parentNode;\r\n                            if (pre && next) {\r\n                                range.setStart(next, 0).collapse(true).select(true);\r\n                                domUtils.remove(li);\r\n\r\n                            } else {\r\n                                if (!pre && !next || !pre) {\r\n\r\n                                    parentList.parentNode.insertBefore(p, parentList);\r\n\r\n\r\n                                } else {\r\n                                    li.parentNode.parentNode.insertBefore(p, parentList.nextSibling);\r\n                                }\r\n                                domUtils.remove(li);\r\n                                if (!parentList.firstChild) {\r\n                                    domUtils.remove(parentList);\r\n                                }\r\n                                range.setStart(p, 0).setCursor();\r\n\r\n\r\n                            }\r\n                            preventAndSave();\r\n                            return;\r\n\r\n                        }\r\n                    } else {\r\n                        var tmpRange = range.cloneRange(),\r\n                            bk = tmpRange.collapse(false).createBookmark();\r\n\r\n                        range.deleteContents();\r\n                        tmpRange.moveToBookmark(bk);\r\n                        var li = domUtils.findParentByTagName(tmpRange.startContainer, 'li', true);\r\n\r\n                        clearEmptySibling(li);\r\n                        tmpRange.select();\r\n                        preventAndSave();\r\n                        return;\r\n                    }\r\n                }\r\n\r\n\r\n                li = domUtils.findParentByTagName(range.startContainer, 'li', true);\r\n\r\n                if (li) {\r\n                    if (domUtils.isEmptyBlock(li)) {\r\n                        bk = range.createBookmark();\r\n                        var parentList = li.parentNode;\r\n                        if (li !== parentList.lastChild) {\r\n                            domUtils.breakParent(li, parentList);\r\n                            clearEmptySibling(li);\r\n                        } else {\r\n\r\n                            parentList.parentNode.insertBefore(li, parentList.nextSibling);\r\n                            if (domUtils.isEmptyNode(parentList)) {\r\n                                domUtils.remove(parentList);\r\n                            }\r\n                        }\r\n                        //嵌套不处理\r\n                        if (!dtd.$list[li.parentNode.tagName]) {\r\n\r\n                            if (!domUtils.isBlockElm(li.firstChild)) {\r\n                                p = me.document.createElement('p');\r\n                                li.parentNode.insertBefore(p, li);\r\n                                while (li.firstChild) {\r\n                                    p.appendChild(li.firstChild);\r\n                                }\r\n                                domUtils.remove(li);\r\n                            } else {\r\n                                domUtils.remove(li, true);\r\n                            }\r\n                        }\r\n                        range.moveToBookmark(bk).select();\r\n\r\n\r\n                    } else {\r\n                        var first = li.firstChild;\r\n                        if (!first || !domUtils.isBlockElm(first)) {\r\n                            var p = me.document.createElement('p');\r\n\r\n                            !li.firstChild && domUtils.fillNode(me.document, p);\r\n                            while (li.firstChild) {\r\n\r\n                                p.appendChild(li.firstChild);\r\n                            }\r\n                            li.appendChild(p);\r\n                            first = p;\r\n                        }\r\n\r\n                        var span = me.document.createElement('span');\r\n\r\n                        range.insertNode(span);\r\n                        domUtils.breakParent(span, li);\r\n\r\n                        var nextLi = span.nextSibling;\r\n                        first = nextLi.firstChild;\r\n\r\n                        if (!first) {\r\n                            p = me.document.createElement('p');\r\n\r\n                            domUtils.fillNode(me.document, p);\r\n                            nextLi.appendChild(p);\r\n                            first = p;\r\n                        }\r\n                        if (domUtils.isEmptyNode(first)) {\r\n                            first.innerHTML = '';\r\n                            domUtils.fillNode(me.document, first);\r\n                        }\r\n\r\n                        range.setStart(first, 0).collapse(true).shrinkBoundary().select();\r\n                        domUtils.remove(span);\r\n                        var pre = nextLi.previousSibling;\r\n                        if (pre && domUtils.isEmptyBlock(pre)) {\r\n                            pre.innerHTML = '<p></p>';\r\n                            domUtils.fillNode(me.document, pre.firstChild);\r\n                        }\r\n\r\n                    }\r\n//                        }\r\n                    preventAndSave();\r\n                }\r\n\r\n\r\n            }\r\n\r\n\r\n        }\r\n        if (keyCode == 8) {\r\n            //修中ie中li下的问题\r\n            range = me.selection.getRange();\r\n            if (range.collapsed && domUtils.isStartInblock(range)) {\r\n                tmpRange = range.cloneRange().trimBoundary();\r\n                li = domUtils.findParentByTagName(range.startContainer, 'li', true);\r\n                //要在li的最左边，才能处理\r\n                if (li && domUtils.isStartInblock(tmpRange)) {\r\n                    start = domUtils.findParentByTagName(range.startContainer, 'p', true);\r\n                    if (start && start !== li.firstChild) {\r\n                        var parentList = domUtils.findParentByTagName(start,['ol','ul']);\r\n                        domUtils.breakParent(start,parentList);\r\n                        clearEmptySibling(start);\r\n                        me.fireEvent('contentchange');\r\n                        range.setStart(start,0).setCursor(false,true);\r\n                        me.fireEvent('saveScene');\r\n                        domUtils.preventDefault(evt);\r\n                        return;\r\n                    }\r\n\r\n                    if (li && (pre = li.previousSibling)) {\r\n                        if (keyCode == 46 && li.childNodes.length) {\r\n                            return;\r\n                        }\r\n                        //有可能上边的兄弟节点是个2级菜单，要追加到2级菜单的最后的li\r\n                        if (dtd.$list[pre.tagName]) {\r\n                            pre = pre.lastChild;\r\n                        }\r\n                        me.undoManger && me.undoManger.save();\r\n                        first = li.firstChild;\r\n                        if (domUtils.isBlockElm(first)) {\r\n                            if (domUtils.isEmptyNode(first)) {\r\n//                                    range.setEnd(pre, pre.childNodes.length).shrinkBoundary().collapse().select(true);\r\n                                pre.appendChild(first);\r\n                                range.setStart(first, 0).setCursor(false, true);\r\n                                //first不是唯一的节点\r\n                                while (li.firstChild) {\r\n                                    pre.appendChild(li.firstChild);\r\n                                }\r\n                            } else {\r\n\r\n                                span = me.document.createElement('span');\r\n                                range.insertNode(span);\r\n                                //判断pre是否是空的节点,如果是<p><br/></p>类型的空节点，干掉p标签防止它占位\r\n                                if (domUtils.isEmptyBlock(pre)) {\r\n                                    pre.innerHTML = '';\r\n                                }\r\n                                domUtils.moveChild(li, pre);\r\n                                range.setStartBefore(span).collapse(true).select(true);\r\n\r\n                                domUtils.remove(span);\r\n\r\n                            }\r\n                        } else {\r\n                            if (domUtils.isEmptyNode(li)) {\r\n                                var p = me.document.createElement('p');\r\n                                pre.appendChild(p);\r\n                                range.setStart(p, 0).setCursor();\r\n//                                    range.setEnd(pre, pre.childNodes.length).shrinkBoundary().collapse().select(true);\r\n                            } else {\r\n                                range.setEnd(pre, pre.childNodes.length).collapse().select(true);\r\n                                while (li.firstChild) {\r\n                                    pre.appendChild(li.firstChild);\r\n                                }\r\n                            }\r\n                        }\r\n                        domUtils.remove(li);\r\n                        me.fireEvent('contentchange');\r\n                        me.fireEvent('saveScene');\r\n                        domUtils.preventDefault(evt);\r\n                        return;\r\n\r\n                    }\r\n                    //trace:980\r\n\r\n                    if (li && !li.previousSibling) {\r\n                        var parentList = li.parentNode;\r\n                        var bk = range.createBookmark();\r\n                        if(domUtils.isTagNode(parentList.parentNode,'ol ul')){\r\n                            parentList.parentNode.insertBefore(li,parentList);\r\n                            if(domUtils.isEmptyNode(parentList)){\r\n                                domUtils.remove(parentList)\r\n                            }\r\n                        }else{\r\n\r\n                            while(li.firstChild){\r\n                                parentList.parentNode.insertBefore(li.firstChild,parentList);\r\n                            }\r\n\r\n                            domUtils.remove(li);\r\n                            if(domUtils.isEmptyNode(parentList)){\r\n                                domUtils.remove(parentList)\r\n                            }\r\n\r\n                        }\r\n                        range.moveToBookmark(bk).setCursor(false,true);\r\n                        me.fireEvent('contentchange');\r\n                        me.fireEvent('saveScene');\r\n                        domUtils.preventDefault(evt);\r\n                        return;\r\n\r\n                    }\r\n\r\n\r\n                }\r\n\r\n\r\n            }\r\n\r\n        }\r\n    });\r\n\r\n    me.addListener('keyup',function(type, evt){\r\n        var keyCode = evt.keyCode || evt.which;\r\n        if (keyCode == 8) {\r\n            var rng = me.selection.getRange(),list;\r\n            if(list = domUtils.findParentByTagName(rng.startContainer,['ol', 'ul'],true)){\r\n                adjustList(list,list.tagName.toLowerCase(),getStyle(list)||domUtils.getComputedStyle(list,'list-style-type'),true)\r\n            }\r\n        }\r\n    });\r\n    //处理tab键\r\n    me.addListener('tabkeydown',function(){\r\n\r\n        var range = me.selection.getRange();\r\n\r\n        //控制级数\r\n        function checkLevel(li){\r\n            if(me.options.maxListLevel != -1){\r\n                var level = li.parentNode,levelNum = 0;\r\n                while(/[ou]l/i.test(level.tagName)){\r\n                    levelNum++;\r\n                    level = level.parentNode;\r\n                }\r\n                if(levelNum >= me.options.maxListLevel){\r\n                    return true;\r\n                }\r\n            }\r\n        }\r\n        //只以开始为准\r\n        //todo 后续改进\r\n        var li = domUtils.findParentByTagName(range.startContainer, 'li', true);\r\n        if(li){\r\n\r\n            var bk;\r\n            if(range.collapsed){\r\n                if(checkLevel(li))\r\n                    return true;\r\n                var parentLi = li.parentNode,\r\n                    list = me.document.createElement(parentLi.tagName),\r\n                    index = utils.indexOf(listStyle[list.tagName], getStyle(parentLi)||domUtils.getComputedStyle(parentLi, 'list-style-type'));\r\n                index = index + 1 == listStyle[list.tagName].length ? 0 : index + 1;\r\n                var currentStyle = listStyle[list.tagName][index];\r\n                setListStyle(list,currentStyle);\r\n                if(domUtils.isStartInblock(range)){\r\n                    me.fireEvent('saveScene');\r\n                    bk = range.createBookmark();\r\n                    parentLi.insertBefore(list, li);\r\n                    list.appendChild(li);\r\n                    adjustList(list,list.tagName.toLowerCase(),currentStyle);\r\n                    me.fireEvent('contentchange');\r\n                    range.moveToBookmark(bk).select(true);\r\n                    return true;\r\n                }\r\n            }else{\r\n                me.fireEvent('saveScene');\r\n                bk = range.createBookmark();\r\n                for(var i= 0,closeList,parents = domUtils.findParents(li),ci;ci=parents[i++];){\r\n                    if(domUtils.isTagNode(ci,'ol ul')){\r\n                        closeList = ci;\r\n                        break;\r\n                    }\r\n                }\r\n                var current = li;\r\n                if(bk.end){\r\n                    while(current && !(domUtils.getPosition(current, bk.end) & domUtils.POSITION_FOLLOWING)){\r\n                        if(checkLevel(current)){\r\n                            current = domUtils.getNextDomNode(current,false,null,function(node){return node !== closeList});\r\n                            continue;\r\n                        }\r\n                        var parentLi = current.parentNode,\r\n                            list = me.document.createElement(parentLi.tagName),\r\n                            index = utils.indexOf(listStyle[list.tagName], getStyle(parentLi)||domUtils.getComputedStyle(parentLi, 'list-style-type'));\r\n                        var currentIndex = index + 1 == listStyle[list.tagName].length ? 0 : index + 1;\r\n                        var currentStyle = listStyle[list.tagName][currentIndex];\r\n                        setListStyle(list,currentStyle);\r\n                        parentLi.insertBefore(list, current);\r\n                        while(current && !(domUtils.getPosition(current, bk.end) & domUtils.POSITION_FOLLOWING)){\r\n                            li = current.nextSibling;\r\n                            list.appendChild(current);\r\n                            if(!li || domUtils.isTagNode(li,'ol ul')){\r\n                                if(li){\r\n                                    while(li = li.firstChild){\r\n                                        if(li.tagName == 'LI'){\r\n                                            break;\r\n                                        }\r\n                                    }\r\n                                }else{\r\n                                    li = domUtils.getNextDomNode(current,false,null,function(node){return node !== closeList});\r\n                                }\r\n                                break;\r\n                            }\r\n                            current = li;\r\n                        }\r\n                        adjustList(list,list.tagName.toLowerCase(),currentStyle);\r\n                        current = li;\r\n                    }\r\n                }\r\n                me.fireEvent('contentchange');\r\n                range.moveToBookmark(bk).select();\r\n                return true;\r\n            }\r\n        }\r\n\r\n    });\r\n    function getLi(start){\r\n        while(start && !domUtils.isBody(start)){\r\n            if(start.nodeName == 'TABLE'){\r\n                return null;\r\n            }\r\n            if(start.nodeName == 'LI'){\r\n                return start\r\n            }\r\n            start = start.parentNode;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 有序列表，与“insertunorderedlist”命令互斥\r\n     * @command insertorderedlist\r\n     * @method execCommand\r\n     * @param { String } command 命令字符串\r\n     * @param { String } style 插入的有序列表类型，值为：decimal,lower-alpha,lower-roman,upper-alpha,upper-roman,cn,cn1,cn2,num,num1,num2\r\n     * @example\r\n     * ```javascript\r\n     * editor.execCommand( 'insertorderedlist','decimal');\r\n     * ```\r\n     */\r\n    /**\r\n     * 查询当前选区内容是否有序列表\r\n     * @command insertorderedlist\r\n     * @method queryCommandState\r\n     * @param { String } cmd 命令字符串\r\n     * @return { int } 如果当前选区是有序列表返回1，否则返回0\r\n     * @example\r\n     * ```javascript\r\n     * editor.queryCommandState( 'insertorderedlist' );\r\n     * ```\r\n     */\r\n    /**\r\n     * 查询当前选区内容是否有序列表\r\n     * @command insertorderedlist\r\n     * @method queryCommandValue\r\n     * @param { String } cmd 命令字符串\r\n     * @return { String } 返回当前有序列表的类型，值为null或decimal,lower-alpha,lower-roman,upper-alpha,upper-roman,cn,cn1,cn2,num,num1,num2\r\n     * @example\r\n     * ```javascript\r\n     * editor.queryCommandValue( 'insertorderedlist' );\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 无序列表，与“insertorderedlist”命令互斥\r\n     * @command insertunorderedlist\r\n     * @method execCommand\r\n     * @param { String } command 命令字符串\r\n     * @param { String } style 插入的无序列表类型，值为：circle,disc,square,dash,dot\r\n     * @example\r\n     * ```javascript\r\n     * editor.execCommand( 'insertunorderedlist','circle');\r\n     * ```\r\n     */\r\n    /**\r\n     * 查询当前是否有word文档粘贴进来的图片\r\n     * @command insertunorderedlist\r\n     * @method insertunorderedlist\r\n     * @param { String } command 命令字符串\r\n     * @return { int } 如果当前选区是无序列表返回1，否则返回0\r\n     * @example\r\n     * ```javascript\r\n     * editor.queryCommandState( 'insertunorderedlist' );\r\n     * ```\r\n     */\r\n    /**\r\n     * 查询当前选区内容是否有序列表\r\n     * @command insertunorderedlist\r\n     * @method queryCommandValue\r\n     * @param { String } command 命令字符串\r\n     * @return { String } 返回当前无序列表的类型，值为null或circle,disc,square,dash,dot\r\n     * @example\r\n     * ```javascript\r\n     * editor.queryCommandValue( 'insertunorderedlist' );\r\n     * ```\r\n     */\r\n\r\n    me.commands['insertorderedlist'] =\r\n    me.commands['insertunorderedlist'] = {\r\n            execCommand:function (command, style) {\r\n\r\n                if (!style) {\r\n                    style = command.toLowerCase() == 'insertorderedlist' ? 'decimal' : 'disc';\r\n                }\r\n                var me = this,\r\n                    range = this.selection.getRange(),\r\n                    filterFn = function (node) {\r\n                        return   node.nodeType == 1 ? node.tagName.toLowerCase() != 'br' : !domUtils.isWhitespace(node);\r\n                    },\r\n                    tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul',\r\n                    frag = me.document.createDocumentFragment();\r\n                //去掉是因为会出现选到末尾，导致adjustmentBoundary缩到ol/ul的位置\r\n                //range.shrinkBoundary();//.adjustmentBoundary();\r\n                range.adjustmentBoundary().shrinkBoundary();\r\n                var bko = range.createBookmark(true),\r\n                    start = getLi(me.document.getElementById(bko.start)),\r\n                    modifyStart = 0,\r\n                    end =  getLi(me.document.getElementById(bko.end)),\r\n                    modifyEnd = 0,\r\n                    startParent, endParent,\r\n                    list, tmp;\r\n\r\n                if (start || end) {\r\n                    start && (startParent = start.parentNode);\r\n                    if (!bko.end) {\r\n                        end = start;\r\n                    }\r\n                    end && (endParent = end.parentNode);\r\n\r\n                    if (startParent === endParent) {\r\n                        while (start !== end) {\r\n                            tmp = start;\r\n                            start = start.nextSibling;\r\n                            if (!domUtils.isBlockElm(tmp.firstChild)) {\r\n                                var p = me.document.createElement('p');\r\n                                while (tmp.firstChild) {\r\n                                    p.appendChild(tmp.firstChild);\r\n                                }\r\n                                tmp.appendChild(p);\r\n                            }\r\n                            frag.appendChild(tmp);\r\n                        }\r\n                        tmp = me.document.createElement('span');\r\n                        startParent.insertBefore(tmp, end);\r\n                        if (!domUtils.isBlockElm(end.firstChild)) {\r\n                            p = me.document.createElement('p');\r\n                            while (end.firstChild) {\r\n                                p.appendChild(end.firstChild);\r\n                            }\r\n                            end.appendChild(p);\r\n                        }\r\n                        frag.appendChild(end);\r\n                        domUtils.breakParent(tmp, startParent);\r\n                        if (domUtils.isEmptyNode(tmp.previousSibling)) {\r\n                            domUtils.remove(tmp.previousSibling);\r\n                        }\r\n                        if (domUtils.isEmptyNode(tmp.nextSibling)) {\r\n                            domUtils.remove(tmp.nextSibling)\r\n                        }\r\n                        var nodeStyle = getStyle(startParent) || domUtils.getComputedStyle(startParent, 'list-style-type') || (command.toLowerCase() == 'insertorderedlist' ? 'decimal' : 'disc');\r\n                        if (startParent.tagName.toLowerCase() == tag && nodeStyle == style) {\r\n                            for (var i = 0, ci, tmpFrag = me.document.createDocumentFragment(); ci = frag.firstChild;) {\r\n                                if(domUtils.isTagNode(ci,'ol ul')){\r\n//                                  删除时，子列表不处理\r\n//                                  utils.each(domUtils.getElementsByTagName(ci,'li'),function(li){\r\n//                                        while(li.firstChild){\r\n//                                            tmpFrag.appendChild(li.firstChild);\r\n//                                        }\r\n//\r\n//                                    });\r\n                                    tmpFrag.appendChild(ci);\r\n                                }else{\r\n                                    while (ci.firstChild) {\r\n\r\n                                        tmpFrag.appendChild(ci.firstChild);\r\n                                        domUtils.remove(ci);\r\n                                    }\r\n                                }\r\n\r\n                            }\r\n                            tmp.parentNode.insertBefore(tmpFrag, tmp);\r\n                        } else {\r\n                            list = me.document.createElement(tag);\r\n                            setListStyle(list,style);\r\n                            list.appendChild(frag);\r\n                            tmp.parentNode.insertBefore(list, tmp);\r\n                        }\r\n\r\n                        domUtils.remove(tmp);\r\n                        list && adjustList(list, tag, style);\r\n                        range.moveToBookmark(bko).select();\r\n                        return;\r\n                    }\r\n                    //开始\r\n                    if (start) {\r\n                        while (start) {\r\n                            tmp = start.nextSibling;\r\n                            if (domUtils.isTagNode(start, 'ol ul')) {\r\n                                frag.appendChild(start);\r\n                            } else {\r\n                                var tmpfrag = me.document.createDocumentFragment(),\r\n                                    hasBlock = 0;\r\n                                while (start.firstChild) {\r\n                                    if (domUtils.isBlockElm(start.firstChild)) {\r\n                                        hasBlock = 1;\r\n                                    }\r\n                                    tmpfrag.appendChild(start.firstChild);\r\n                                }\r\n                                if (!hasBlock) {\r\n                                    var tmpP = me.document.createElement('p');\r\n                                    tmpP.appendChild(tmpfrag);\r\n                                    frag.appendChild(tmpP);\r\n                                } else {\r\n                                    frag.appendChild(tmpfrag);\r\n                                }\r\n                                domUtils.remove(start);\r\n                            }\r\n\r\n                            start = tmp;\r\n                        }\r\n                        startParent.parentNode.insertBefore(frag, startParent.nextSibling);\r\n                        if (domUtils.isEmptyNode(startParent)) {\r\n                            range.setStartBefore(startParent);\r\n                            domUtils.remove(startParent);\r\n                        } else {\r\n                            range.setStartAfter(startParent);\r\n                        }\r\n                        modifyStart = 1;\r\n                    }\r\n\r\n                    if (end && domUtils.inDoc(endParent, me.document)) {\r\n                        //结束\r\n                        start = endParent.firstChild;\r\n                        while (start && start !== end) {\r\n                            tmp = start.nextSibling;\r\n                            if (domUtils.isTagNode(start, 'ol ul')) {\r\n                                frag.appendChild(start);\r\n                            } else {\r\n                                tmpfrag = me.document.createDocumentFragment();\r\n                                hasBlock = 0;\r\n                                while (start.firstChild) {\r\n                                    if (domUtils.isBlockElm(start.firstChild)) {\r\n                                        hasBlock = 1;\r\n                                    }\r\n                                    tmpfrag.appendChild(start.firstChild);\r\n                                }\r\n                                if (!hasBlock) {\r\n                                    tmpP = me.document.createElement('p');\r\n                                    tmpP.appendChild(tmpfrag);\r\n                                    frag.appendChild(tmpP);\r\n                                } else {\r\n                                    frag.appendChild(tmpfrag);\r\n                                }\r\n                                domUtils.remove(start);\r\n                            }\r\n                            start = tmp;\r\n                        }\r\n                        var tmpDiv = domUtils.createElement(me.document, 'div', {\r\n                            'tmpDiv':1\r\n                        });\r\n                        domUtils.moveChild(end, tmpDiv);\r\n\r\n                        frag.appendChild(tmpDiv);\r\n                        domUtils.remove(end);\r\n                        endParent.parentNode.insertBefore(frag, endParent);\r\n                        range.setEndBefore(endParent);\r\n                        if (domUtils.isEmptyNode(endParent)) {\r\n                            domUtils.remove(endParent);\r\n                        }\r\n\r\n                        modifyEnd = 1;\r\n                    }\r\n\r\n\r\n                }\r\n\r\n                if (!modifyStart) {\r\n                    range.setStartBefore(me.document.getElementById(bko.start));\r\n                }\r\n                if (bko.end && !modifyEnd) {\r\n                    range.setEndAfter(me.document.getElementById(bko.end));\r\n                }\r\n                range.enlarge(true, function (node) {\r\n                    return notExchange[node.tagName];\r\n                });\r\n\r\n                frag = me.document.createDocumentFragment();\r\n\r\n                var bk = range.createBookmark(),\r\n                    current = domUtils.getNextDomNode(bk.start, false, filterFn),\r\n                    tmpRange = range.cloneRange(),\r\n                    tmpNode,\r\n                    block = domUtils.isBlockElm;\r\n\r\n                while (current && current !== bk.end && (domUtils.getPosition(current, bk.end) & domUtils.POSITION_PRECEDING)) {\r\n\r\n                    if (current.nodeType == 3 || dtd.li[current.tagName]) {\r\n                        if (current.nodeType == 1 && dtd.$list[current.tagName]) {\r\n                            while (current.firstChild) {\r\n                                frag.appendChild(current.firstChild);\r\n                            }\r\n                            tmpNode = domUtils.getNextDomNode(current, false, filterFn);\r\n                            domUtils.remove(current);\r\n                            current = tmpNode;\r\n                            continue;\r\n\r\n                        }\r\n                        tmpNode = current;\r\n                        tmpRange.setStartBefore(current);\r\n\r\n                        while (current && current !== bk.end && (!block(current) || domUtils.isBookmarkNode(current) )) {\r\n                            tmpNode = current;\r\n                            current = domUtils.getNextDomNode(current, false, null, function (node) {\r\n                                return !notExchange[node.tagName];\r\n                            });\r\n                        }\r\n\r\n                        if (current && block(current)) {\r\n                            tmp = domUtils.getNextDomNode(tmpNode, false, filterFn);\r\n                            if (tmp && domUtils.isBookmarkNode(tmp)) {\r\n                                current = domUtils.getNextDomNode(tmp, false, filterFn);\r\n                                tmpNode = tmp;\r\n                            }\r\n                        }\r\n                        tmpRange.setEndAfter(tmpNode);\r\n\r\n                        current = domUtils.getNextDomNode(tmpNode, false, filterFn);\r\n\r\n                        var li = range.document.createElement('li');\r\n\r\n                        li.appendChild(tmpRange.extractContents());\r\n                        if(domUtils.isEmptyNode(li)){\r\n                            var tmpNode = range.document.createElement('p');\r\n                            while(li.firstChild){\r\n                                tmpNode.appendChild(li.firstChild)\r\n                            }\r\n                            li.appendChild(tmpNode);\r\n                        }\r\n                        frag.appendChild(li);\r\n                    } else {\r\n                        current = domUtils.getNextDomNode(current, true, filterFn);\r\n                    }\r\n                }\r\n                range.moveToBookmark(bk).collapse(true);\r\n                list = me.document.createElement(tag);\r\n                setListStyle(list,style);\r\n                list.appendChild(frag);\r\n                range.insertNode(list);\r\n                //当前list上下看能否合并\r\n                adjustList(list, tag, style);\r\n                //去掉冗余的tmpDiv\r\n                for (var i = 0, ci, tmpDivs = domUtils.getElementsByTagName(list, 'div'); ci = tmpDivs[i++];) {\r\n                    if (ci.getAttribute('tmpDiv')) {\r\n                        domUtils.remove(ci, true)\r\n                    }\r\n                }\r\n                range.moveToBookmark(bko).select();\r\n\r\n            },\r\n            queryCommandState:function (command) {\r\n                var tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul';\r\n                var path = this.selection.getStartElementPath();\r\n                for(var i= 0,ci;ci = path[i++];){\r\n                    if(ci.nodeName == 'TABLE'){\r\n                        return 0\r\n                    }\r\n                    if(tag == ci.nodeName.toLowerCase()){\r\n                        return 1\r\n                    };\r\n                }\r\n                return 0;\r\n\r\n            },\r\n            queryCommandValue:function (command) {\r\n                var tag = command.toLowerCase() == 'insertorderedlist' ? 'ol' : 'ul';\r\n                var path = this.selection.getStartElementPath(),\r\n                    node;\r\n                for(var i= 0,ci;ci = path[i++];){\r\n                    if(ci.nodeName == 'TABLE'){\r\n                        node = null;\r\n                        break;\r\n                    }\r\n                    if(tag == ci.nodeName.toLowerCase()){\r\n                        node = ci;\r\n                        break;\r\n                    };\r\n                }\r\n                return node ? getStyle(node) || domUtils.getComputedStyle(node, 'list-style-type') : null;\r\n            }\r\n        };\r\n};\r\n\r\n\n\n// plugins/source.js\n/**\r\n * 源码编辑插件\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n(function (){\r\n    var sourceEditors = {\r\n        textarea: function (editor, holder){\r\n            var textarea = holder.ownerDocument.createElement('textarea');\r\n            textarea.style.cssText = 'position:absolute;resize:none;width:100%;height:100%;border:0;padding:0;margin:0;overflow-y:auto;';\r\n            // todo: IE下只有onresize属性可用... 很纠结\r\n            if (browser.ie && browser.version < 8) {\r\n                textarea.style.width = holder.offsetWidth + 'px';\r\n                textarea.style.height = holder.offsetHeight + 'px';\r\n                holder.onresize = function (){\r\n                    textarea.style.width = holder.offsetWidth + 'px';\r\n                    textarea.style.height = holder.offsetHeight + 'px';\r\n                };\r\n            }\r\n            holder.appendChild(textarea);\r\n            return {\r\n                setContent: function (content){\r\n                    textarea.value = content;\r\n                },\r\n                getContent: function (){\r\n                    return textarea.value;\r\n                },\r\n                select: function (){\r\n                    var range;\r\n                    if (browser.ie) {\r\n                        range = textarea.createTextRange();\r\n                        range.collapse(true);\r\n                        range.select();\r\n                    } else {\r\n                        //todo: chrome下无法设置焦点\r\n                        textarea.setSelectionRange(0, 0);\r\n                        textarea.focus();\r\n                    }\r\n                },\r\n                dispose: function (){\r\n                    holder.removeChild(textarea);\r\n                    // todo\r\n                    holder.onresize = null;\r\n                    textarea = null;\r\n                    holder = null;\r\n                }\r\n            };\r\n        },\r\n        codemirror: function (editor, holder){\r\n\r\n            var codeEditor = window.CodeMirror(holder, {\r\n                mode: \"text/html\",\r\n                tabMode: \"indent\",\r\n                lineNumbers: true,\r\n                lineWrapping:true\r\n            });\r\n            var dom = codeEditor.getWrapperElement();\r\n            dom.style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;font-family:consolas,\"Courier new\",monospace;font-size:13px;';\r\n            codeEditor.getScrollerElement().style.cssText = 'position:absolute;left:0;top:0;width:100%;height:100%;';\r\n            codeEditor.refresh();\r\n            return {\r\n                getCodeMirror:function(){\r\n                    return codeEditor;\r\n                },\r\n                setContent: function (content){\r\n                    codeEditor.setValue(content);\r\n                },\r\n                getContent: function (){\r\n                    return codeEditor.getValue();\r\n                },\r\n                select: function (){\r\n                    codeEditor.focus();\r\n                },\r\n                dispose: function (){\r\n                    holder.removeChild(dom);\r\n                    dom = null;\r\n                    codeEditor = null;\r\n                }\r\n            };\r\n        }\r\n    };\r\n\r\n    UE.plugins['source'] = function (){\r\n        var me = this;\r\n        var opt = this.options;\r\n        var sourceMode = false;\r\n        var sourceEditor;\r\n        var orgSetContent;\r\n        opt.sourceEditor = browser.ie  ? 'textarea' : (opt.sourceEditor || 'codemirror');\r\n\r\n        me.setOpt({\r\n            sourceEditorFirst:false\r\n        });\r\n        function createSourceEditor(holder){\r\n            return sourceEditors[opt.sourceEditor == 'codemirror' && window.CodeMirror ? 'codemirror' : 'textarea'](me, holder);\r\n        }\r\n\r\n        var bakCssText;\r\n        //解决在源码模式下getContent不能得到最新的内容问题\r\n        var oldGetContent,\r\n            bakAddress;\r\n\r\n        /**\r\n         * 切换源码模式和编辑模式\r\n         * @command source\r\n         * @method execCommand\r\n         * @param { String } cmd 命令字符串\r\n         * @example\r\n         * ```javascript\r\n         * editor.execCommand( 'source');\r\n         * ```\r\n         */\r\n\r\n        /**\r\n         * 查询当前编辑区域的状态是源码模式还是可视化模式\r\n         * @command source\r\n         * @method queryCommandState\r\n         * @param { String } cmd 命令字符串\r\n         * @return { int } 如果当前是源码编辑模式，返回1，否则返回0\r\n         * @example\r\n         * ```javascript\r\n         * editor.queryCommandState( 'source' );\r\n         * ```\r\n         */\r\n\r\n        me.commands['source'] = {\r\n            execCommand: function (){\r\n\r\n                sourceMode = !sourceMode;\r\n                if (sourceMode) {\r\n                    bakAddress = me.selection.getRange().createAddress(false,true);\r\n                    me.undoManger && me.undoManger.save(true);\r\n                    if(browser.gecko){\r\n                        me.body.contentEditable = false;\r\n                    }\r\n\r\n                    bakCssText = me.iframe.style.cssText;\r\n                    me.iframe.style.cssText += 'position:absolute;left:-32768px;top:-32768px;';\r\n\r\n\r\n                    me.fireEvent('beforegetcontent');\r\n                    var root = UE.htmlparser(me.body.innerHTML);\r\n                    me.filterOutputRule(root);\r\n                    root.traversal(function (node) {\r\n                        if (node.type == 'element') {\r\n                            switch (node.tagName) {\r\n                                case 'td':\r\n                                case 'th':\r\n                                case 'caption':\r\n                                if(node.children && node.children.length == 1){\r\n                                    if(node.firstChild().tagName == 'br' ){\r\n                                        node.removeChild(node.firstChild())\r\n                                    }\r\n                                };\r\n                                break;\r\n                                case 'pre':\r\n                                    node.innerText(node.innerText().replace(/&nbsp;/g,' '))\r\n\r\n                            }\r\n                        }\r\n                    });\r\n\r\n                    me.fireEvent('aftergetcontent');\r\n\r\n                    var content = root.toHtml(true);\r\n\r\n                    sourceEditor = createSourceEditor(me.iframe.parentNode);\r\n\r\n                    sourceEditor.setContent(content);\r\n\r\n                    orgSetContent = me.setContent;\r\n\r\n                    me.setContent = function(html){\r\n                        //这里暂时不触发事件，防止报错\r\n                        var root = UE.htmlparser(html);\r\n                        me.filterInputRule(root);\r\n                        html = root.toHtml();\r\n                        sourceEditor.setContent(html);\r\n                    };\r\n\r\n                    setTimeout(function (){\r\n                        sourceEditor.select();\r\n                        me.addListener('fullscreenchanged', function(){\r\n                            try{\r\n                                sourceEditor.getCodeMirror().refresh()\r\n                            }catch(e){}\r\n                        });\r\n                    });\r\n\r\n                    //重置getContent，源码模式下取值也能是最新的数据\r\n                    oldGetContent = me.getContent;\r\n                    me.getContent = function (){\r\n                        return sourceEditor.getContent() || '<p>' + (browser.ie ? '' : '<br/>')+'</p>';\r\n                    };\r\n                } else {\r\n                    me.iframe.style.cssText = bakCssText;\r\n                    var cont = sourceEditor.getContent() || '<p>' + (browser.ie ? '' : '<br/>')+'</p>';\r\n                    //处理掉block节点前后的空格,有可能会误命中，暂时不考虑\r\n                    cont = cont.replace(new RegExp('[\\\\r\\\\t\\\\n ]*<\\/?(\\\\w+)\\\\s*(?:[^>]*)>','g'), function(a,b){\r\n                        if(b && !dtd.$inlineWithA[b.toLowerCase()]){\r\n                            return a.replace(/(^[\\n\\r\\t ]*)|([\\n\\r\\t ]*$)/g,'');\r\n                        }\r\n                        return a.replace(/(^[\\n\\r\\t]*)|([\\n\\r\\t]*$)/g,'')\r\n                    });\r\n\r\n                    me.setContent = orgSetContent;\r\n\r\n                    me.setContent(cont);\r\n                    sourceEditor.dispose();\r\n                    sourceEditor = null;\r\n                    //还原getContent方法\r\n                    me.getContent = oldGetContent;\r\n                    var first = me.body.firstChild;\r\n                    //trace:1106 都删除空了，下边会报错，所以补充一个p占位\r\n                    if(!first){\r\n                        me.body.innerHTML = '<p>'+(browser.ie?'':'<br/>')+'</p>';\r\n                        first = me.body.firstChild;\r\n                    }\r\n\r\n\r\n                    //要在ifm为显示时ff才能取到selection,否则报错\r\n                    //这里不能比较位置了\r\n                    me.undoManger && me.undoManger.save(true);\r\n\r\n                    if(browser.gecko){\r\n\r\n                        var input = document.createElement('input');\r\n                        input.style.cssText = 'position:absolute;left:0;top:-32768px';\r\n\r\n                        document.body.appendChild(input);\r\n\r\n                        me.body.contentEditable = false;\r\n                        setTimeout(function(){\r\n                            domUtils.setViewportOffset(input, { left: -32768, top: 0 });\r\n                            input.focus();\r\n                            setTimeout(function(){\r\n                                me.body.contentEditable = true;\r\n                                me.selection.getRange().moveToAddress(bakAddress).select(true);\r\n                                domUtils.remove(input);\r\n                            });\r\n\r\n                        });\r\n                    }else{\r\n                        //ie下有可能报错，比如在代码顶头的情况\r\n                        try{\r\n                            me.selection.getRange().moveToAddress(bakAddress).select(true);\r\n                        }catch(e){}\r\n\r\n                    }\r\n                }\r\n                this.fireEvent('sourcemodechanged', sourceMode);\r\n            },\r\n            queryCommandState: function (){\r\n                return sourceMode|0;\r\n            },\r\n            notNeedUndo : 1\r\n        };\r\n        var oldQueryCommandState = me.queryCommandState;\r\n\r\n        me.queryCommandState = function (cmdName){\r\n            cmdName = cmdName.toLowerCase();\r\n            if (sourceMode) {\r\n                //源码模式下可以开启的命令\r\n                return cmdName in {\r\n                    'source' : 1,\r\n                    'fullscreen' : 1\r\n                } ? 1 : -1\r\n            }\r\n            return oldQueryCommandState.apply(this, arguments);\r\n        };\r\n\r\n        if(opt.sourceEditor == \"codemirror\"){\r\n\r\n            me.addListener(\"ready\",function(){\r\n                utils.loadFile(document,{\r\n                    src : opt.codeMirrorJsUrl || opt.UEDITOR_HOME_URL + \"third-party/codemirror/codemirror.js\",\r\n                    tag : \"script\",\r\n                    type : \"text/javascript\",\r\n                    defer : \"defer\"\r\n                },function(){\r\n                    if(opt.sourceEditorFirst){\r\n                        setTimeout(function(){\r\n                            me.execCommand(\"source\");\r\n                        },0);\r\n                    }\r\n                });\r\n                utils.loadFile(document,{\r\n                    tag : \"link\",\r\n                    rel : \"stylesheet\",\r\n                    type : \"text/css\",\r\n                    href : opt.codeMirrorCssUrl || opt.UEDITOR_HOME_URL + \"third-party/codemirror/codemirror.css\"\r\n                });\r\n\r\n            });\r\n        }\r\n\r\n    };\r\n\r\n})();\n\n// plugins/enterkey.js\n///import core\r\n///import plugins/undo.js\r\n///commands 设置回车标签p或br\r\n///commandsName  EnterKey\r\n///commandsTitle  设置回车标签p或br\r\n/**\r\n * @description 处理回车\r\n * @author zhanyi\r\n */\r\nUE.plugins['enterkey'] = function() {\r\n    var hTag,\r\n        me = this,\r\n        tag = me.options.enterTag;\r\n    me.addListener('keyup', function(type, evt) {\r\n\r\n        var keyCode = evt.keyCode || evt.which;\r\n        if (keyCode == 13) {\r\n            var range = me.selection.getRange(),\r\n                start = range.startContainer,\r\n                doSave;\r\n\r\n            //修正在h1-h6里边回车后不能嵌套p的问题\r\n            if (!browser.ie) {\r\n\r\n                if (/h\\d/i.test(hTag)) {\r\n                    if (browser.gecko) {\r\n                        var h = domUtils.findParentByTagName(start, [ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6','blockquote','caption','table'], true);\r\n                        if (!h) {\r\n                            me.document.execCommand('formatBlock', false, '<p>');\r\n                            doSave = 1;\r\n                        }\r\n                    } else {\r\n                        //chrome remove div\r\n                        if (start.nodeType == 1) {\r\n                            var tmp = me.document.createTextNode(''),div;\r\n                            range.insertNode(tmp);\r\n                            div = domUtils.findParentByTagName(tmp, 'div', true);\r\n                            if (div) {\r\n                                var p = me.document.createElement('p');\r\n                                while (div.firstChild) {\r\n                                    p.appendChild(div.firstChild);\r\n                                }\r\n                                div.parentNode.insertBefore(p, div);\r\n                                domUtils.remove(div);\r\n                                range.setStartBefore(tmp).setCursor();\r\n                                doSave = 1;\r\n                            }\r\n                            domUtils.remove(tmp);\r\n\r\n                        }\r\n                    }\r\n\r\n                    if (me.undoManger && doSave) {\r\n                        me.undoManger.save();\r\n                    }\r\n                }\r\n                //没有站位符，会出现多行的问题\r\n                browser.opera &&  range.select();\r\n            }else{\r\n                me.fireEvent('saveScene',true,true)\r\n            }\r\n        }\r\n    });\r\n\r\n    me.addListener('keydown', function(type, evt) {\r\n        var keyCode = evt.keyCode || evt.which;\r\n        if (keyCode == 13) {//回车\r\n            if(me.fireEvent('beforeenterkeydown')){\r\n                domUtils.preventDefault(evt);\r\n                return;\r\n            }\r\n            me.fireEvent('saveScene',true,true);\r\n            hTag = '';\r\n\r\n\r\n            var range = me.selection.getRange();\r\n\r\n            if (!range.collapsed) {\r\n                //跨td不能删\r\n                var start = range.startContainer,\r\n                    end = range.endContainer,\r\n                    startTd = domUtils.findParentByTagName(start, 'td', true),\r\n                    endTd = domUtils.findParentByTagName(end, 'td', true);\r\n                if (startTd && endTd && startTd !== endTd || !startTd && endTd || startTd && !endTd) {\r\n                    evt.preventDefault ? evt.preventDefault() : ( evt.returnValue = false);\r\n                    return;\r\n                }\r\n            }\r\n            if (tag == 'p') {\r\n\r\n\r\n                if (!browser.ie) {\r\n\r\n                    start = domUtils.findParentByTagName(range.startContainer, ['ol','ul','p', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6','blockquote','caption'], true);\r\n\r\n                    //opera下执行formatblock会在table的场景下有问题，回车在opera原生支持很好，所以暂时在opera去掉调用这个原生的command\r\n                    //trace:2431\r\n                    if (!start && !browser.opera) {\r\n\r\n                        me.document.execCommand('formatBlock', false, '<p>');\r\n\r\n                        if (browser.gecko) {\r\n                            range = me.selection.getRange();\r\n                            start = domUtils.findParentByTagName(range.startContainer, 'p', true);\r\n                            start && domUtils.removeDirtyAttr(start);\r\n                        }\r\n\r\n\r\n                    } else {\r\n                        hTag = start.tagName;\r\n                        start.tagName.toLowerCase() == 'p' && browser.gecko && domUtils.removeDirtyAttr(start);\r\n                    }\r\n\r\n                }\r\n\r\n            } else {\r\n                evt.preventDefault ? evt.preventDefault() : ( evt.returnValue = false);\r\n\r\n                if (!range.collapsed) {\r\n                    range.deleteContents();\r\n                    start = range.startContainer;\r\n                    if (start.nodeType == 1 && (start = start.childNodes[range.startOffset])) {\r\n                        while (start.nodeType == 1) {\r\n                            if (dtd.$empty[start.tagName]) {\r\n                                range.setStartBefore(start).setCursor();\r\n                                if (me.undoManger) {\r\n                                    me.undoManger.save();\r\n                                }\r\n                                return false;\r\n                            }\r\n                            if (!start.firstChild) {\r\n                                var br = range.document.createElement('br');\r\n                                start.appendChild(br);\r\n                                range.setStart(start, 0).setCursor();\r\n                                if (me.undoManger) {\r\n                                    me.undoManger.save();\r\n                                }\r\n                                return false;\r\n                            }\r\n                            start = start.firstChild;\r\n                        }\r\n                        if (start === range.startContainer.childNodes[range.startOffset]) {\r\n                            br = range.document.createElement('br');\r\n                            range.insertNode(br).setCursor();\r\n\r\n                        } else {\r\n                            range.setStart(start, 0).setCursor();\r\n                        }\r\n\r\n\r\n                    } else {\r\n                        br = range.document.createElement('br');\r\n                        range.insertNode(br).setStartAfter(br).setCursor();\r\n                    }\r\n\r\n\r\n                } else {\r\n                    br = range.document.createElement('br');\r\n                    range.insertNode(br);\r\n                    var parent = br.parentNode;\r\n                    if (parent.lastChild === br) {\r\n                        br.parentNode.insertBefore(br.cloneNode(true), br);\r\n                        range.setStartBefore(br);\r\n                    } else {\r\n                        range.setStartAfter(br);\r\n                    }\r\n                    range.setCursor();\r\n\r\n                }\r\n\r\n            }\r\n\r\n        }\r\n    });\r\n};\r\n\n\n// plugins/keystrokes.js\n/* 处理特殊键的兼容性问题 */\r\nUE.plugins['keystrokes'] = function() {\r\n    var me = this;\r\n    var collapsed = true;\r\n    me.addListener('keydown', function(type, evt) {\r\n        var keyCode = evt.keyCode || evt.which,\r\n            rng = me.selection.getRange();\r\n\r\n        //处理全选的情况\r\n        if(!rng.collapsed && !(evt.ctrlKey || evt.shiftKey || evt.altKey || evt.metaKey) && (keyCode >= 65 && keyCode <=90\r\n            || keyCode >= 48 && keyCode <= 57 ||\r\n            keyCode >= 96 && keyCode <= 111 || {\r\n                    13:1,\r\n                    8:1,\r\n                    46:1\r\n                }[keyCode])\r\n            ){\r\n\r\n            var tmpNode = rng.startContainer;\r\n            if(domUtils.isFillChar(tmpNode)){\r\n                rng.setStartBefore(tmpNode)\r\n            }\r\n            tmpNode = rng.endContainer;\r\n            if(domUtils.isFillChar(tmpNode)){\r\n                rng.setEndAfter(tmpNode)\r\n            }\r\n            rng.txtToElmBoundary();\r\n            //结束边界可能放到了br的前边，要把br包含进来\r\n            // x[xxx]<br/>\r\n            if(rng.endContainer && rng.endContainer.nodeType == 1){\r\n                tmpNode = rng.endContainer.childNodes[rng.endOffset];\r\n                if(tmpNode && domUtils.isBr(tmpNode)){\r\n                    rng.setEndAfter(tmpNode);\r\n                }\r\n            }\r\n            if(rng.startOffset == 0){\r\n                tmpNode = rng.startContainer;\r\n                if(domUtils.isBoundaryNode(tmpNode,'firstChild') ){\r\n                    tmpNode = rng.endContainer;\r\n                    if(rng.endOffset == (tmpNode.nodeType == 3 ? tmpNode.nodeValue.length : tmpNode.childNodes.length) && domUtils.isBoundaryNode(tmpNode,'lastChild')){\r\n                        me.fireEvent('saveScene');\r\n                        me.body.innerHTML = '<p>'+(browser.ie ? '' : '<br/>')+'</p>';\r\n                        rng.setStart(me.body.firstChild,0).setCursor(false,true);\r\n                        me._selectionChange();\r\n                        return;\r\n                    }\r\n                }\r\n            }\r\n        }\r\n\r\n        //处理backspace\r\n        if (keyCode == keymap.Backspace) {\r\n            rng = me.selection.getRange();\r\n            collapsed = rng.collapsed;\r\n            if(me.fireEvent('delkeydown',evt)){\r\n                return;\r\n            }\r\n            var start,end;\r\n            //避免按两次删除才能生效的问题\r\n            if(rng.collapsed && rng.inFillChar()){\r\n                start = rng.startContainer;\r\n\r\n                if(domUtils.isFillChar(start)){\r\n                    rng.setStartBefore(start).shrinkBoundary(true).collapse(true);\r\n                    domUtils.remove(start)\r\n                }else{\r\n                    start.nodeValue = start.nodeValue.replace(new RegExp('^' + domUtils.fillChar ),'');\r\n                    rng.startOffset--;\r\n                    rng.collapse(true).select(true)\r\n                }\r\n            }\r\n\r\n            //解决选中control元素不能删除的问题\r\n            if (start = rng.getClosedNode()) {\r\n                me.fireEvent('saveScene');\r\n                rng.setStartBefore(start);\r\n                domUtils.remove(start);\r\n                rng.setCursor();\r\n                me.fireEvent('saveScene');\r\n                domUtils.preventDefault(evt);\r\n                return;\r\n            }\r\n            //阻止在table上的删除\r\n            if (!browser.ie) {\r\n                start = domUtils.findParentByTagName(rng.startContainer, 'table', true);\r\n                end = domUtils.findParentByTagName(rng.endContainer, 'table', true);\r\n                if (start && !end || !start && end || start !== end) {\r\n                    evt.preventDefault();\r\n                    return;\r\n                }\r\n            }\r\n\r\n        }\r\n        //处理tab键的逻辑\r\n        if (keyCode == keymap.Tab) {\r\n            //不处理以下标签\r\n            var excludeTagNameForTabKey = {\r\n                'ol' : 1,\r\n                'ul' : 1,\r\n                'table':1\r\n            };\r\n            //处理组件里的tab按下事件\r\n            if(me.fireEvent('tabkeydown',evt)){\r\n                domUtils.preventDefault(evt);\r\n                return;\r\n            }\r\n            var range = me.selection.getRange();\r\n            me.fireEvent('saveScene');\r\n            for (var i = 0,txt = '',tabSize = me.options.tabSize|| 4,tabNode =  me.options.tabNode || '&nbsp;'; i < tabSize; i++) {\r\n                txt += tabNode;\r\n            }\r\n            var span = me.document.createElement('span');\r\n            span.innerHTML = txt + domUtils.fillChar;\r\n            if (range.collapsed) {\r\n                range.insertNode(span.cloneNode(true).firstChild).setCursor(true);\r\n            } else {\r\n                var filterFn = function(node) {\r\n                    return domUtils.isBlockElm(node) && !excludeTagNameForTabKey[node.tagName.toLowerCase()]\r\n\r\n                };\r\n                //普通的情况\r\n                start = domUtils.findParent(range.startContainer, filterFn,true);\r\n                end = domUtils.findParent(range.endContainer, filterFn,true);\r\n                if (start && end && start === end) {\r\n                    range.deleteContents();\r\n                    range.insertNode(span.cloneNode(true).firstChild).setCursor(true);\r\n                } else {\r\n                    var bookmark = range.createBookmark();\r\n                    range.enlarge(true);\r\n                    var bookmark2 = range.createBookmark(),\r\n                        current = domUtils.getNextDomNode(bookmark2.start, false, filterFn);\r\n                    while (current && !(domUtils.getPosition(current, bookmark2.end) & domUtils.POSITION_FOLLOWING)) {\r\n                        current.insertBefore(span.cloneNode(true).firstChild, current.firstChild);\r\n                        current = domUtils.getNextDomNode(current, false, filterFn);\r\n                    }\r\n                    range.moveToBookmark(bookmark2).moveToBookmark(bookmark).select();\r\n                }\r\n            }\r\n            domUtils.preventDefault(evt)\r\n        }\r\n        //trace:1634\r\n        //ff的del键在容器空的时候，也会删除\r\n        if(browser.gecko && keyCode == 46){\r\n            range = me.selection.getRange();\r\n            if(range.collapsed){\r\n                start = range.startContainer;\r\n                if(domUtils.isEmptyBlock(start)){\r\n                    var parent = start.parentNode;\r\n                    while(domUtils.getChildCount(parent) == 1 && !domUtils.isBody(parent)){\r\n                        start = parent;\r\n                        parent = parent.parentNode;\r\n                    }\r\n                    if(start === parent.lastChild)\r\n                        evt.preventDefault();\r\n                    return;\r\n                }\r\n            }\r\n        }\r\n    });\r\n    me.addListener('keyup', function(type, evt) {\r\n        var keyCode = evt.keyCode || evt.which,\r\n            rng,me = this;\r\n        if(keyCode == keymap.Backspace){\r\n            if(me.fireEvent('delkeyup')){\r\n                return;\r\n            }\r\n            rng = me.selection.getRange();\r\n            if(rng.collapsed){\r\n                var tmpNode,\r\n                    autoClearTagName = ['h1','h2','h3','h4','h5','h6'];\r\n                if(tmpNode = domUtils.findParentByTagName(rng.startContainer,autoClearTagName,true)){\r\n                    if(domUtils.isEmptyBlock(tmpNode)){\r\n                        var pre = tmpNode.previousSibling;\r\n                        if(pre && pre.nodeName != 'TABLE'){\r\n                            domUtils.remove(tmpNode);\r\n                            rng.setStartAtLast(pre).setCursor(false,true);\r\n                            return;\r\n                        }else{\r\n                            var next = tmpNode.nextSibling;\r\n                            if(next && next.nodeName != 'TABLE'){\r\n                                domUtils.remove(tmpNode);\r\n                                rng.setStartAtFirst(next).setCursor(false,true);\r\n                                return;\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n                //处理当删除到body时，要重新给p标签展位\r\n                if(domUtils.isBody(rng.startContainer)){\r\n                    var tmpNode = domUtils.createElement(me.document,'p',{\r\n                        'innerHTML' : browser.ie ? domUtils.fillChar : '<br/>'\r\n                    });\r\n                    rng.insertNode(tmpNode).setStart(tmpNode,0).setCursor(false,true);\r\n                }\r\n            }\r\n\r\n\r\n            //chrome下如果删除了inline标签，浏览器会有记忆，在输入文字还是会套上刚才删除的标签，所以这里再选一次就不会了\r\n            if( !collapsed && (rng.startContainer.nodeType == 3 || rng.startContainer.nodeType == 1 && domUtils.isEmptyBlock(rng.startContainer))){\r\n                if(browser.ie){\r\n                    var span = rng.document.createElement('span');\r\n                    rng.insertNode(span).setStartBefore(span).collapse(true);\r\n                    rng.select();\r\n                    domUtils.remove(span)\r\n                }else{\r\n                    rng.select()\r\n                }\r\n\r\n            }\r\n        }\r\n\r\n\r\n    })\r\n};\n\n// plugins/fiximgclick.js\n///import core\n///commands 修复chrome下图片不能点击的问题，出现八个角可改变大小\n///commandsName  FixImgClick\n///commandsTitle  修复chrome下图片不能点击的问题，出现八个角可改变大小\n//修复chrome下图片不能点击的问题，出现八个角可改变大小\n\nUE.plugins['fiximgclick'] = (function () {\n\n    var elementUpdated = false;\n    function Scale() {\n        this.editor = null;\n        this.resizer = null;\n        this.cover = null;\n        this.doc = document;\n        this.prePos = {x: 0, y: 0};\n        this.startPos = {x: 0, y: 0};\n    }\n\n    (function () {\n        var rect = [\n            //[left, top, width, height]\n            [0, 0, -1, -1],\n            [0, 0, 0, -1],\n            [0, 0, 1, -1],\n            [0, 0, -1, 0],\n            [0, 0, 1, 0],\n            [0, 0, -1, 1],\n            [0, 0, 0, 1],\n            [0, 0, 1, 1]\n        ];\n\n        Scale.prototype = {\n            init: function (editor) {\n                var me = this;\n                me.editor = editor;\n                me.startPos = this.prePos = {x: 0, y: 0};\n                me.dragId = -1;\n\n                var hands = [],\n                    cover = me.cover = document.createElement('div'),\n                    resizer = me.resizer = document.createElement('div');\n\n                cover.id = me.editor.ui.id + '_imagescale_cover';\n                cover.style.cssText = 'position:absolute;display:none;z-index:' + (me.editor.options.zIndex) + ';filter:alpha(opacity=0); opacity:0;background:#CCC;';\n                domUtils.on(cover, 'mousedown click', function () {\n                    me.hide();\n                });\n\n                for (i = 0; i < 8; i++) {\n                    hands.push('<span class=\"edui-editor-imagescale-hand' + i + '\"></span>');\n                }\n                resizer.id = me.editor.ui.id + '_imagescale';\n                resizer.className = 'edui-editor-imagescale';\n                resizer.innerHTML = hands.join('');\n                resizer.style.cssText += ';display:none;border:1px solid #3b77ff;z-index:' + (me.editor.options.zIndex) + ';';\n\n                me.editor.ui.getDom().appendChild(cover);\n                me.editor.ui.getDom().appendChild(resizer);\n\n                me.initStyle();\n                me.initEvents();\n            },\n            initStyle: function () {\n                utils.cssRule('imagescale', '.edui-editor-imagescale{display:none;position:absolute;border:1px solid #38B2CE;cursor:hand;-webkit-box-sizing: content-box;-moz-box-sizing: content-box;box-sizing: content-box;}' +\n                    '.edui-editor-imagescale span{position:absolute;width:6px;height:6px;overflow:hidden;font-size:0px;display:block;background-color:#3C9DD0;}'\n                    + '.edui-editor-imagescale .edui-editor-imagescale-hand0{cursor:nw-resize;top:0;margin-top:-4px;left:0;margin-left:-4px;}'\n                    + '.edui-editor-imagescale .edui-editor-imagescale-hand1{cursor:n-resize;top:0;margin-top:-4px;left:50%;margin-left:-4px;}'\n                    + '.edui-editor-imagescale .edui-editor-imagescale-hand2{cursor:ne-resize;top:0;margin-top:-4px;left:100%;margin-left:-3px;}'\n                    + '.edui-editor-imagescale .edui-editor-imagescale-hand3{cursor:w-resize;top:50%;margin-top:-4px;left:0;margin-left:-4px;}'\n                    + '.edui-editor-imagescale .edui-editor-imagescale-hand4{cursor:e-resize;top:50%;margin-top:-4px;left:100%;margin-left:-3px;}'\n                    + '.edui-editor-imagescale .edui-editor-imagescale-hand5{cursor:sw-resize;top:100%;margin-top:-3px;left:0;margin-left:-4px;}'\n                    + '.edui-editor-imagescale .edui-editor-imagescale-hand6{cursor:s-resize;top:100%;margin-top:-3px;left:50%;margin-left:-4px;}'\n                    + '.edui-editor-imagescale .edui-editor-imagescale-hand7{cursor:se-resize;top:100%;margin-top:-3px;left:100%;margin-left:-3px;}');\n            },\n            initEvents: function () {\n                var me = this;\n\n                me.startPos.x = me.startPos.y = 0;\n                me.isDraging = false;\n            },\n            _eventHandler: function (e) {\n                var me = this;\n                switch (e.type) {\n                    case 'mousedown':\n                        var hand = e.target || e.srcElement, hand;\n                        if (hand.className.indexOf('edui-editor-imagescale-hand') != -1 && me.dragId == -1) {\n                            me.dragId = hand.className.slice(-1);\n                            me.startPos.x = me.prePos.x = e.clientX;\n                            me.startPos.y = me.prePos.y = e.clientY;\n                            domUtils.on(me.doc,'mousemove', me.proxy(me._eventHandler, me));\n                        }\n                        break;\n                    case 'mousemove':\n                        if (me.dragId != -1) {\n                            me.updateContainerStyle(me.dragId, {x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y});\n                            me.prePos.x = e.clientX;\n                            me.prePos.y = e.clientY;\n                            elementUpdated = true;\n                            me.updateTargetElement();\n\n                        }\n                        break;\n                    case 'mouseup':\n                        if (me.dragId != -1) {\n                            me.updateContainerStyle(me.dragId, {x: e.clientX - me.prePos.x, y: e.clientY - me.prePos.y});\n                            me.updateTargetElement();\n                            if (me.target.parentNode) me.attachTo(me.target);\n                            me.dragId = -1;\n                        }\n                        domUtils.un(me.doc,'mousemove', me.proxy(me._eventHandler, me));\n                        //修复只是点击挪动点，但没有改变大小，不应该触发contentchange\n                        if(elementUpdated){\n                            elementUpdated = false;\n                            me.editor.fireEvent('contentchange');\n                        }\n\n                        break;\n                    default:\n                        break;\n                }\n            },\n            updateTargetElement: function () {\n                var me = this;\n                domUtils.setStyles(me.target, {\n                    'width': me.resizer.style.width,\n                    'height': me.resizer.style.height\n                });\n                me.target.width = parseInt(me.resizer.style.width);\n                me.target.height = parseInt(me.resizer.style.height);\n                me.attachTo(me.target);\n            },\n            updateContainerStyle: function (dir, offset) {\n                var me = this,\n                    dom = me.resizer, tmp;\n\n                if (rect[dir][0] != 0) {\n                    tmp = parseInt(dom.style.left) + offset.x;\n                    dom.style.left = me._validScaledProp('left', tmp) + 'px';\n                }\n                if (rect[dir][1] != 0) {\n                    tmp = parseInt(dom.style.top) + offset.y;\n                    dom.style.top = me._validScaledProp('top', tmp) + 'px';\n                }\n                if (rect[dir][2] != 0) {\n                    tmp = dom.clientWidth + rect[dir][2] * offset.x;\n                    dom.style.width = me._validScaledProp('width', tmp) + 'px';\n                }\n                if (rect[dir][3] != 0) {\n                    tmp = dom.clientHeight + rect[dir][3] * offset.y;\n                    dom.style.height = me._validScaledProp('height', tmp) + 'px';\n                }\n            },\n            _validScaledProp: function (prop, value) {\n                var ele = this.resizer,\n                    wrap = document;\n\n                value = isNaN(value) ? 0 : value;\n                switch (prop) {\n                    case 'left':\n                        return value < 0 ? 0 : (value + ele.clientWidth) > wrap.clientWidth ? wrap.clientWidth - ele.clientWidth : value;\n                    case 'top':\n                        return value < 0 ? 0 : (value + ele.clientHeight) > wrap.clientHeight ? wrap.clientHeight - ele.clientHeight : value;\n                    case 'width':\n                        return value <= 0 ? 1 : (value + ele.offsetLeft) > wrap.clientWidth ? wrap.clientWidth - ele.offsetLeft : value;\n                    case 'height':\n                        return value <= 0 ? 1 : (value + ele.offsetTop) > wrap.clientHeight ? wrap.clientHeight - ele.offsetTop : value;\n                }\n            },\n            hideCover: function () {\n                this.cover.style.display = 'none';\n            },\n            showCover: function () {\n                var me = this,\n                    editorPos = domUtils.getXY(me.editor.ui.getDom()),\n                    iframePos = domUtils.getXY(me.editor.iframe);\n\n                domUtils.setStyles(me.cover, {\n                    'width': me.editor.iframe.offsetWidth + 'px',\n                    'height': me.editor.iframe.offsetHeight + 'px',\n                    'top': iframePos.y - editorPos.y + 'px',\n                    'left': iframePos.x - editorPos.x + 'px',\n                    'position': 'absolute',\n                    'display': ''\n                })\n            },\n            show: function (targetObj) {\n                var me = this;\n                me.resizer.style.display = 'block';\n                if(targetObj) me.attachTo(targetObj);\n\n                domUtils.on(this.resizer, 'mousedown', me.proxy(me._eventHandler, me));\n                domUtils.on(me.doc, 'mouseup', me.proxy(me._eventHandler, me));\n\n                me.showCover();\n                me.editor.fireEvent('afterscaleshow', me);\n                me.editor.fireEvent('saveScene');\n            },\n            hide: function () {\n                var me = this;\n                me.hideCover();\n                me.resizer.style.display = 'none';\n\n                domUtils.un(me.resizer, 'mousedown', me.proxy(me._eventHandler, me));\n                domUtils.un(me.doc, 'mouseup', me.proxy(me._eventHandler, me));\n                me.editor.fireEvent('afterscalehide', me);\n            },\n            proxy: function( fn, context ) {\n                return function(e) {\n                    return fn.apply( context || this, arguments);\n                };\n            },\n            attachTo: function (targetObj) {\n                var me = this,\n                    target = me.target = targetObj,\n                    resizer = this.resizer,\n                    imgPos = domUtils.getXY(target),\n                    iframePos = domUtils.getXY(me.editor.iframe),\n                    editorPos = domUtils.getXY(resizer.parentNode);\n\n                domUtils.setStyles(resizer, {\n                    'width': target.width + 'px',\n                    'height': target.height + 'px',\n                    'left': iframePos.x + imgPos.x - me.editor.document.body.scrollLeft - editorPos.x - parseInt(resizer.style.borderLeftWidth) + 'px',\n                    'top': iframePos.y + imgPos.y - me.editor.document.body.scrollTop - editorPos.y - parseInt(resizer.style.borderTopWidth) + 'px'\n                });\n            }\n        }\n    })();\n\n    return function () {\n        var me = this,\n            imageScale;\n\n        me.setOpt('imageScaleEnabled', true);\n\n        if ( !browser.ie && me.options.imageScaleEnabled) {\n            me.addListener('click', function (type, e) {\n\n                var range = me.selection.getRange(),\n                    img = range.getClosedNode();\n\n                if (img && img.tagName == 'IMG' && me.body.contentEditable!=\"false\") {\n\n                    if (img.className.indexOf(\"edui-faked-music\") != -1 ||\n                        img.getAttribute(\"anchorname\") ||\n                        domUtils.hasClass(img, 'loadingclass') ||\n                        domUtils.hasClass(img, 'loaderrorclass')) { return }\n\n                    if (!imageScale) {\n                        imageScale = new Scale();\n                        imageScale.init(me);\n                        me.ui.getDom().appendChild(imageScale.resizer);\n\n                        var _keyDownHandler = function (e) {\n                            imageScale.hide();\n                            if(imageScale.target) me.selection.getRange().selectNode(imageScale.target).select();\n                        }, _mouseDownHandler = function (e) {\n                            var ele = e.target || e.srcElement;\n                            if (ele && (ele.className===undefined || ele.className.indexOf('edui-editor-imagescale') == -1)) {\n                                _keyDownHandler(e);\n                            }\n                        }, timer;\n\n                        me.addListener('afterscaleshow', function (e) {\n                            me.addListener('beforekeydown', _keyDownHandler);\n                            me.addListener('beforemousedown', _mouseDownHandler);\n                            domUtils.on(document, 'keydown', _keyDownHandler);\n                            domUtils.on(document,'mousedown', _mouseDownHandler);\n                            me.selection.getNative().removeAllRanges();\n                        });\n                        me.addListener('afterscalehide', function (e) {\n                            me.removeListener('beforekeydown', _keyDownHandler);\n                            me.removeListener('beforemousedown', _mouseDownHandler);\n                            domUtils.un(document, 'keydown', _keyDownHandler);\n                            domUtils.un(document,'mousedown', _mouseDownHandler);\n                            var target = imageScale.target;\n                            if (target.parentNode) {\n                                me.selection.getRange().selectNode(target).select();\n                            }\n                        });\n                        //TODO 有iframe的情况，mousedown不能往下传。。\n                        domUtils.on(imageScale.resizer, 'mousedown', function (e) {\n                            me.selection.getNative().removeAllRanges();\n                            var ele = e.target || e.srcElement;\n                            if (ele && ele.className.indexOf('edui-editor-imagescale-hand') == -1) {\n                                timer = setTimeout(function () {\n                                    imageScale.hide();\n                                    if(imageScale.target) me.selection.getRange().selectNode(ele).select();\n                                }, 200);\n                            }\n                        });\n                        domUtils.on(imageScale.resizer, 'mouseup', function (e) {\n                            var ele = e.target || e.srcElement;\n                            if (ele && ele.className.indexOf('edui-editor-imagescale-hand') == -1) {\n                                clearTimeout(timer);\n                            }\n                        });\n                    }\n                    imageScale.show(img);\n                } else {\n                    if (imageScale && imageScale.resizer.style.display != 'none') imageScale.hide();\n                }\n            });\n        }\n\n        if (browser.webkit) {\n            me.addListener('click', function (type, e) {\n                if (e.target.tagName == 'IMG' && me.body.contentEditable!=\"false\") {\n                    var range = new dom.Range(me.document);\n                    range.selectNode(e.target).select();\n                }\n            });\n        }\n    }\n})();\n\n// plugins/autolink.js\n///import core\r\n///commands 为非ie浏览器自动添加a标签\r\n///commandsName  AutoLink\r\n///commandsTitle  自动增加链接\r\n/**\r\n * @description 为非ie浏览器自动添加a标签\r\n * @author zhanyi\r\n */\r\n\r\nUE.plugin.register('autolink',function(){\r\n    var cont = 0;\r\n\r\n    return !browser.ie ? {\r\n\r\n            bindEvents:{\r\n                'reset' : function(){\r\n                    cont = 0;\r\n                },\r\n                'keydown':function(type, evt) {\r\n                    var me = this;\r\n                    var keyCode = evt.keyCode || evt.which;\r\n\r\n                    if (keyCode == 32 || keyCode == 13) {\r\n\r\n                        var sel = me.selection.getNative(),\r\n                            range = sel.getRangeAt(0).cloneRange(),\r\n                            offset,\r\n                            charCode;\r\n\r\n                        var start = range.startContainer;\r\n                        while (start.nodeType == 1 && range.startOffset > 0) {\r\n                            start = range.startContainer.childNodes[range.startOffset - 1];\r\n                            if (!start){\r\n                                break;\r\n                            }\r\n                            range.setStart(start, start.nodeType == 1 ? start.childNodes.length : start.nodeValue.length);\r\n                            range.collapse(true);\r\n                            start = range.startContainer;\r\n                        }\r\n\r\n                        do{\r\n                            if (range.startOffset == 0) {\r\n                                start = range.startContainer.previousSibling;\r\n\r\n                                while (start && start.nodeType == 1) {\r\n                                    start = start.lastChild;\r\n                                }\r\n                                if (!start || domUtils.isFillChar(start)){\r\n                                    break;\r\n                                }\r\n                                offset = start.nodeValue.length;\r\n                            } else {\r\n                                start = range.startContainer;\r\n                                offset = range.startOffset;\r\n                            }\r\n                            range.setStart(start, offset - 1);\r\n                            charCode = range.toString().charCodeAt(0);\r\n                        } while (charCode != 160 && charCode != 32);\r\n\r\n                        if (range.toString().replace(new RegExp(domUtils.fillChar, 'g'), '').match(/(?:https?:\\/\\/|ssh:\\/\\/|ftp:\\/\\/|file:\\/|www\\.)/i)) {\r\n                            while(range.toString().length){\r\n                                if(/^(?:https?:\\/\\/|ssh:\\/\\/|ftp:\\/\\/|file:\\/|www\\.)/i.test(range.toString())){\r\n                                    break;\r\n                                }\r\n                                try{\r\n                                    range.setStart(range.startContainer,range.startOffset+1);\r\n                                }catch(e){\r\n                                    //trace:2121\r\n                                    var start = range.startContainer;\r\n                                    while(!(next = start.nextSibling)){\r\n                                        if(domUtils.isBody(start)){\r\n                                            return;\r\n                                        }\r\n                                        start = start.parentNode;\r\n\r\n                                    }\r\n                                    range.setStart(next,0);\r\n\r\n                                }\r\n\r\n                            }\r\n                            //range的开始边界已经在a标签里的不再处理\r\n                            if(domUtils.findParentByTagName(range.startContainer,'a',true)){\r\n                                return;\r\n                            }\r\n                            var a = me.document.createElement('a'),text = me.document.createTextNode(' '),href;\r\n\r\n                            me.undoManger && me.undoManger.save();\r\n                            a.appendChild(range.extractContents());\r\n                            a.href = a.innerHTML = a.innerHTML.replace(/<[^>]+>/g,'');\r\n                            href = a.getAttribute(\"href\").replace(new RegExp(domUtils.fillChar,'g'),'');\r\n                            href = /^(?:https?:\\/\\/)/ig.test(href) ? href : \"http://\"+ href;\r\n                            a.setAttribute('_src',utils.html(href));\r\n                            a.href = utils.html(href);\r\n\r\n                            range.insertNode(a);\r\n                            a.parentNode.insertBefore(text, a.nextSibling);\r\n                            range.setStart(text, 0);\r\n                            range.collapse(true);\r\n                            sel.removeAllRanges();\r\n                            sel.addRange(range);\r\n                            me.undoManger && me.undoManger.save();\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }:{}\r\n    },function(){\r\n        var keyCodes = {\r\n            37:1, 38:1, 39:1, 40:1,\r\n            13:1,32:1\r\n        };\r\n        function checkIsCludeLink(node){\r\n            if(node.nodeType == 3){\r\n                return null\r\n            }\r\n            if(node.nodeName == 'A'){\r\n                return node;\r\n            }\r\n            var lastChild = node.lastChild;\r\n\r\n            while(lastChild){\r\n                if(lastChild.nodeName == 'A'){\r\n                    return lastChild;\r\n                }\r\n                if(lastChild.nodeType == 3){\r\n                    if(domUtils.isWhitespace(lastChild)){\r\n                        lastChild = lastChild.previousSibling;\r\n                        continue;\r\n                    }\r\n                    return null\r\n                }\r\n                lastChild = lastChild.lastChild;\r\n            }\r\n        }\r\n        browser.ie && this.addListener('keyup',function(cmd,evt){\r\n            var me = this,keyCode = evt.keyCode;\r\n            if(keyCodes[keyCode]){\r\n                var rng = me.selection.getRange();\r\n                var start = rng.startContainer;\r\n\r\n                if(keyCode == 13){\r\n                    while(start && !domUtils.isBody(start) && !domUtils.isBlockElm(start)){\r\n                        start = start.parentNode;\r\n                    }\r\n                    if(start && !domUtils.isBody(start) && start.nodeName == 'P'){\r\n                        var pre = start.previousSibling;\r\n                        if(pre && pre.nodeType == 1){\r\n                            var pre = checkIsCludeLink(pre);\r\n                            if(pre && !pre.getAttribute('_href')){\r\n                                domUtils.remove(pre,true);\r\n                            }\r\n                        }\r\n                    }\r\n                }else if(keyCode == 32 ){\r\n                    if(start.nodeType == 3 && /^\\s$/.test(start.nodeValue)){\r\n                        start = start.previousSibling;\r\n                        if(start && start.nodeName == 'A' && !start.getAttribute('_href')){\r\n                            domUtils.remove(start,true);\r\n                        }\r\n                    }\r\n                }else {\r\n                    start = domUtils.findParentByTagName(start,'a',true);\r\n                    if(start && !start.getAttribute('_href')){\r\n                        var bk = rng.createBookmark();\r\n\r\n                        domUtils.remove(start,true);\r\n                        rng.moveToBookmark(bk).select(true)\r\n                    }\r\n                }\r\n\r\n            }\r\n\r\n\r\n        });\r\n    }\r\n);\n\n// plugins/autoheight.js\n///import core\r\n///commands 当输入内容超过编辑器高度时，编辑器自动增高\r\n///commandsName  AutoHeight,autoHeightEnabled\r\n///commandsTitle  自动增高\r\n/**\r\n * @description 自动伸展\r\n * @author zhanyi\r\n */\r\nUE.plugins['autoheight'] = function () {\r\n    var me = this;\r\n    //提供开关，就算加载也可以关闭\r\n    me.autoHeightEnabled = me.options.autoHeightEnabled !== false;\r\n    if (!me.autoHeightEnabled) {\r\n        return;\r\n    }\r\n\r\n    var bakOverflow,\r\n        lastHeight = 0,\r\n        options = me.options,\r\n        currentHeight,\r\n        timer;\r\n\r\n    function adjustHeight() {\r\n        var me = this;\r\n        clearTimeout(timer);\r\n        if(isFullscreen)return;\r\n        if (!me.queryCommandState || me.queryCommandState && me.queryCommandState('source') != 1) {\r\n            timer = setTimeout(function(){\r\n\r\n                var node = me.body.lastChild;\r\n                while(node && node.nodeType != 1){\r\n                    node = node.previousSibling;\r\n                }\r\n                if(node && node.nodeType == 1){\r\n                    node.style.clear = 'both';\r\n                    currentHeight = Math.max(domUtils.getXY(node).y + node.offsetHeight + 25 ,Math.max(options.minFrameHeight, options.initialFrameHeight)) ;\r\n                    if (currentHeight != lastHeight) {\r\n                        if (currentHeight !== parseInt(me.iframe.parentNode.style.height)) {\r\n                            me.iframe.parentNode.style.height = currentHeight + 'px';\r\n                        }\r\n                        me.body.style.height = currentHeight + 'px';\r\n                        lastHeight = currentHeight;\r\n                    }\r\n                    domUtils.removeStyle(node,'clear');\r\n                }\r\n\r\n\r\n            },50)\r\n        }\r\n    }\r\n    var isFullscreen;\r\n    me.addListener('fullscreenchanged',function(cmd,f){\r\n        isFullscreen = f\r\n    });\r\n    me.addListener('destroy', function () {\r\n        me.removeListener('contentchange afterinserthtml keyup mouseup',adjustHeight)\r\n    });\r\n    me.enableAutoHeight = function () {\r\n        var me = this;\r\n        if (!me.autoHeightEnabled) {\r\n            return;\r\n        }\r\n        var doc = me.document;\r\n        me.autoHeightEnabled = true;\r\n        bakOverflow = doc.body.style.overflowY;\r\n        doc.body.style.overflowY = 'hidden';\r\n        me.addListener('contentchange afterinserthtml keyup mouseup',adjustHeight);\r\n        //ff不给事件算得不对\r\n\r\n        setTimeout(function () {\r\n            adjustHeight.call(me);\r\n        }, browser.gecko ? 100 : 0);\r\n        me.fireEvent('autoheightchanged', me.autoHeightEnabled);\r\n    };\r\n    me.disableAutoHeight = function () {\r\n\r\n        me.body.style.overflowY = bakOverflow || '';\r\n\r\n        me.removeListener('contentchange', adjustHeight);\r\n        me.removeListener('keyup', adjustHeight);\r\n        me.removeListener('mouseup', adjustHeight);\r\n        me.autoHeightEnabled = false;\r\n        me.fireEvent('autoheightchanged', me.autoHeightEnabled);\r\n    };\r\n\r\n    me.on('setHeight',function(){\r\n        me.disableAutoHeight()\r\n    });\r\n    me.addListener('ready', function () {\r\n        me.enableAutoHeight();\r\n        //trace:1764\r\n        var timer;\r\n        domUtils.on(browser.ie ? me.body : me.document, browser.webkit ? 'dragover' : 'drop', function () {\r\n            clearTimeout(timer);\r\n            timer = setTimeout(function () {\r\n                //trace:3681\r\n                adjustHeight.call(me);\r\n            }, 100);\r\n\r\n        });\r\n        //修复内容过多时，回到顶部，顶部内容被工具栏遮挡问题\r\n        var lastScrollY;\r\n        window.onscroll = function(){\r\n            if(lastScrollY === null){\r\n                lastScrollY = this.scrollY\r\n            }else if(this.scrollY == 0 && lastScrollY != 0){\r\n                me.window.scrollTo(0,0);\r\n                lastScrollY = null;\r\n            }\r\n        }\r\n    });\r\n\r\n\r\n};\r\n\r\n\n\n// plugins/autofloat.js\n///import core\r\n///commands 悬浮工具栏\r\n///commandsName  AutoFloat,autoFloatEnabled\r\n///commandsTitle  悬浮工具栏\r\n/**\r\n *  modified by chengchao01\r\n *  注意： 引入此功能后，在IE6下会将body的背景图片覆盖掉！\r\n */\r\nUE.plugins['autofloat'] = function() {\r\n    var me = this,\r\n        lang = me.getLang();\r\n    me.setOpt({\r\n        topOffset:0\r\n    });\r\n    var optsAutoFloatEnabled = me.options.autoFloatEnabled !== false,\r\n        topOffset = me.options.topOffset;\r\n\r\n\r\n    //如果不固定toolbar的位置，则直接退出\r\n    if(!optsAutoFloatEnabled){\r\n        return;\r\n    }\r\n    var uiUtils = UE.ui.uiUtils,\r\n        LteIE6 = browser.ie && browser.version <= 6,\r\n        quirks = browser.quirks;\r\n\r\n    function checkHasUI(){\r\n        if(!UE.ui){\r\n            alert(lang.autofloatMsg);\r\n            return 0;\r\n        }\r\n        return 1;\r\n    }\r\n    function fixIE6FixedPos(){\r\n        var docStyle = document.body.style;\r\n        docStyle.backgroundImage = 'url(\"about:blank\")';\r\n        docStyle.backgroundAttachment = 'fixed';\r\n    }\r\n    var\tbakCssText,\r\n        placeHolder = document.createElement('div'),\r\n        toolbarBox,orgTop,\r\n        getPosition,\r\n        flag =true;   //ie7模式下需要偏移\r\n    function setFloating(){\r\n        var toobarBoxPos = domUtils.getXY(toolbarBox),\r\n            origalFloat = domUtils.getComputedStyle(toolbarBox,'position'),\r\n            origalLeft = domUtils.getComputedStyle(toolbarBox,'left');\r\n        toolbarBox.style.width = toolbarBox.offsetWidth + 'px';\r\n        toolbarBox.style.zIndex = me.options.zIndex * 1 + 1;\r\n        toolbarBox.parentNode.insertBefore(placeHolder, toolbarBox);\r\n        if (LteIE6 || (quirks && browser.ie)) {\r\n            if(toolbarBox.style.position != 'absolute'){\r\n                toolbarBox.style.position = 'absolute';\r\n            }\r\n            toolbarBox.style.top = (document.body.scrollTop||document.documentElement.scrollTop) - orgTop + topOffset  + 'px';\r\n        } else {\r\n            if (browser.ie7Compat && flag) {\r\n                flag = false;\r\n                toolbarBox.style.left =  domUtils.getXY(toolbarBox).x - document.documentElement.getBoundingClientRect().left+2  + 'px';\r\n            }\r\n            if(toolbarBox.style.position != 'fixed'){\r\n                toolbarBox.style.position = 'fixed';\r\n                toolbarBox.style.top = topOffset +\"px\";\r\n                ((origalFloat == 'absolute' || origalFloat == 'relative') && parseFloat(origalLeft)) && (toolbarBox.style.left = toobarBoxPos.x + 'px');\r\n            }\r\n        }\r\n    }\r\n    function unsetFloating(){\r\n        flag = true;\r\n        if(placeHolder.parentNode){\r\n            placeHolder.parentNode.removeChild(placeHolder);\r\n        }\r\n\r\n        toolbarBox.style.cssText = bakCssText;\r\n    }\r\n\r\n    function updateFloating(){\r\n        var rect3 = getPosition(me.container);\r\n        var offset=me.options.toolbarTopOffset||0;\r\n        if (rect3.top < 0 && rect3.bottom - toolbarBox.offsetHeight > offset) {\r\n            setFloating();\r\n        }else{\r\n            unsetFloating();\r\n        }\r\n    }\r\n    var defer_updateFloating = utils.defer(function(){\r\n        updateFloating();\r\n    },browser.ie ? 200 : 100,true);\r\n\r\n    me.addListener('destroy',function(){\r\n        domUtils.un(window, ['scroll','resize'], updateFloating);\r\n        me.removeListener('keydown', defer_updateFloating);\r\n    });\r\n\r\n    me.addListener('ready', function(){\r\n        if(checkHasUI(me)){\r\n            //加载了ui组件，但在new时，没有加载ui，导致编辑器实例上没有ui类，所以这里做判断\r\n            if(!me.ui){\r\n                return;\r\n            }\r\n            getPosition = uiUtils.getClientRect;\r\n            toolbarBox = me.ui.getDom('toolbarbox');\r\n            orgTop = getPosition(toolbarBox).top;\r\n            bakCssText = toolbarBox.style.cssText;\r\n            placeHolder.style.height = toolbarBox.offsetHeight + 'px';\r\n            if(LteIE6){\r\n                fixIE6FixedPos();\r\n            }\r\n            domUtils.on(window, ['scroll','resize'], updateFloating);\r\n            me.addListener('keydown', defer_updateFloating);\r\n\r\n            me.addListener('beforefullscreenchange', function (t, enabled){\r\n                if (enabled) {\r\n                    unsetFloating();\r\n                }\r\n            });\r\n            me.addListener('fullscreenchanged', function (t, enabled){\r\n                if (!enabled) {\r\n                    updateFloating();\r\n                }\r\n            });\r\n            me.addListener('sourcemodechanged', function (t, enabled){\r\n                setTimeout(function (){\r\n                    updateFloating();\r\n                },0);\r\n            });\r\n            me.addListener(\"clearDoc\",function(){\r\n                setTimeout(function(){\r\n                    updateFloating();\r\n                },0);\r\n\r\n            })\r\n        }\r\n    });\r\n};\r\n\n\n// plugins/video.js\n/**\r\n * video插件， 为UEditor提供视频插入支持\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\nUE.plugins['video'] = function (){\r\n    var me =this;\r\n\r\n    /**\r\n     * 创建插入视频字符窜\r\n     * @param url 视频地址\r\n     * @param width 视频宽度\r\n     * @param height 视频高度\r\n     * @param align 视频对齐\r\n     * @param toEmbed 是否以flash代替显示\r\n     * @param addParagraph  是否需要添加P 标签\r\n     */\r\n    function creatInsertStr(url,width,height,id,align,classname,type){\r\n\r\n        url = utils.unhtmlForUrl(url);\r\n        align = utils.unhtml(align);\r\n        classname = utils.unhtml(classname);\r\n\r\n        width = parseInt(width, 10) || 0;\r\n        height = parseInt(height, 10) || 0;\r\n\r\n        var str;\r\n        switch (type){\r\n            case 'image':\r\n                str = '<img ' + (id ? 'id=\"' + id+'\"' : '') + ' width=\"'+ width +'\" height=\"' + height + '\" _url=\"'+url+'\" class=\"' + classname.replace(/\\bvideo-js\\b/, '') + '\"'  +\r\n                    ' src=\"' + me.options.UEDITOR_HOME_URL+'themes/default/images/spacer.gif\" style=\"background:url('+me.options.UEDITOR_HOME_URL+'themes/default/images/videologo.gif) no-repeat center center; border:1px solid gray;'+(align ? 'float:' + align + ';': '')+'\" />'\r\n                break;\r\n            case 'embed':\r\n                str = '<embed type=\"application/x-shockwave-flash\" class=\"' + classname + '\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\"' +\r\n                    ' src=\"' +  utils.html(url) + '\" width=\"' + width  + '\" height=\"' + height  + '\"'  + (align ? ' style=\"float:' + align + '\"': '') +\r\n                    ' wmode=\"transparent\" play=\"true\" loop=\"false\" menu=\"false\" allowscriptaccess=\"never\" allowfullscreen=\"true\" >';\r\n                break;\r\n            case 'video':\r\n                var ext = url.substr(url.lastIndexOf('.') + 1);\r\n                if(ext == 'ogv') ext = 'ogg';\r\n                str = '<video' + (id ? ' id=\"' + id + '\"' : '') + ' class=\"' + classname + ' video-js\" ' + (align ? ' style=\"float:' + align + '\"': '') +\r\n                    ' controls preload=\"none\" width=\"' + width + '\" height=\"' + height + '\" src=\"' + url + '\" data-setup=\"{}\">' +\r\n                    '<source src=\"' + url + '\" type=\"video/' + ext + '\" /></video>';\r\n                break;\r\n        }\r\n        return str;\r\n    }\r\n\r\n    function switchImgAndVideo(root,img2video){\r\n        utils.each(root.getNodesByTagName(img2video ? 'img' : 'embed video'),function(node){\r\n            var className = node.getAttr('class');\r\n            if(className && className.indexOf('edui-faked-video') != -1){\r\n                var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr('width'),node.getAttr('height'),null,node.getStyle('float') || '',className,img2video ? 'embed':'image');\r\n                node.parentNode.replaceChild(UE.uNode.createElement(html),node);\r\n            }\r\n            if(className && className.indexOf('edui-upload-video') != -1){\r\n                var html = creatInsertStr( img2video ? node.getAttr('_url') : node.getAttr('src'),node.getAttr('width'),node.getAttr('height'),null,node.getStyle('float') || '',className,img2video ? 'video':'image');\r\n                node.parentNode.replaceChild(UE.uNode.createElement(html),node);\r\n            }\r\n        })\r\n    }\r\n\r\n    me.addOutputRule(function(root){\r\n        switchImgAndVideo(root,true)\r\n    });\r\n    me.addInputRule(function(root){\r\n        switchImgAndVideo(root)\r\n    });\r\n\r\n    /**\r\n     * 插入视频\r\n     * @command insertvideo\r\n     * @method execCommand\r\n     * @param { String } cmd 命令字符串\r\n     * @param { Object } videoAttr 键值对对象， 描述一个视频的所有属性\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * var videoAttr = {\r\n     *      //视频地址\r\n     *      url: 'http://www.youku.com/xxx',\r\n     *      //视频宽高值， 单位px\r\n     *      width: 200,\r\n     *      height: 100\r\n     * };\r\n     *\r\n     * //editor 是编辑器实例\r\n     * //向编辑器插入单个视频\r\n     * editor.execCommand( 'insertvideo', videoAttr );\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 插入视频\r\n     * @command insertvideo\r\n     * @method execCommand\r\n     * @param { String } cmd 命令字符串\r\n     * @param { Array } videoArr 需要插入的视频的数组， 其中的每一个元素都是一个键值对对象， 描述了一个视频的所有属性\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * var videoAttr1 = {\r\n     *      //视频地址\r\n     *      url: 'http://www.youku.com/xxx',\r\n     *      //视频宽高值， 单位px\r\n     *      width: 200,\r\n     *      height: 100\r\n     * },\r\n     * videoAttr2 = {\r\n     *      //视频地址\r\n     *      url: 'http://www.youku.com/xxx',\r\n     *      //视频宽高值， 单位px\r\n     *      width: 200,\r\n     *      height: 100\r\n     * }\r\n     *\r\n     * //editor 是编辑器实例\r\n     * //该方法将会向编辑器内插入两个视频\r\n     * editor.execCommand( 'insertvideo', [ videoAttr1, videoAttr2 ] );\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 查询当前光标所在处是否是一个视频\r\n     * @command insertvideo\r\n     * @method queryCommandState\r\n     * @param { String } cmd 需要查询的命令字符串\r\n     * @return { int } 如果当前光标所在处的元素是一个视频对象， 则返回1，否则返回0\r\n     * @example\r\n     * ```javascript\r\n     *\r\n     * //editor 是编辑器实例\r\n     * editor.queryCommandState( 'insertvideo' );\r\n     * ```\r\n     */\r\n    me.commands[\"insertvideo\"] = {\r\n        execCommand: function (cmd, videoObjs, type){\r\n            videoObjs = utils.isArray(videoObjs)?videoObjs:[videoObjs];\r\n            var html = [],id = 'tmpVedio', cl;\r\n            for(var i=0,vi,len = videoObjs.length;i<len;i++){\r\n                vi = videoObjs[i];\r\n                cl = (type == 'upload' ? 'edui-upload-video video-js vjs-default-skin':'edui-faked-video');\r\n                html.push(creatInsertStr( vi.url, vi.width || 420,  vi.height || 280, id + i, null, cl, 'image'));\r\n            }\r\n            me.execCommand(\"inserthtml\",html.join(\"\"),true);\r\n            var rng = this.selection.getRange();\r\n            for(var i= 0,len=videoObjs.length;i<len;i++){\r\n                var img = this.document.getElementById('tmpVedio'+i);\r\n                domUtils.removeAttributes(img,'id');\r\n                rng.selectNode(img).select();\r\n                me.execCommand('imagefloat',videoObjs[i].align)\r\n            }\r\n        },\r\n        queryCommandState : function(){\r\n            var img = me.selection.getRange().getClosedNode(),\r\n                flag = img && (img.className == \"edui-faked-video\" || img.className.indexOf(\"edui-upload-video\")!=-1);\r\n            return flag ? 1 : 0;\r\n        }\r\n    };\r\n};\r\n\n\n// plugins/table.core.js\n/**\r\n * Created with JetBrains WebStorm.\r\n * User: taoqili\r\n * Date: 13-1-18\r\n * Time: 上午11:09\r\n * To change this template use File | Settings | File Templates.\r\n */\r\n/**\r\n * UE表格操作类\r\n * @param table\r\n * @constructor\r\n */\r\n(function () {\r\n    var UETable = UE.UETable = function (table) {\r\n        this.table = table;\r\n        this.indexTable = [];\r\n        this.selectedTds = [];\r\n        this.cellsRange = {};\r\n        this.update(table);\r\n    };\r\n\r\n    //===以下为静态工具方法===\r\n    UETable.removeSelectedClass = function (cells) {\r\n        utils.each(cells, function (cell) {\r\n            domUtils.removeClasses(cell, \"selectTdClass\");\r\n        })\r\n    };\r\n    UETable.addSelectedClass = function (cells) {\r\n        utils.each(cells, function (cell) {\r\n            domUtils.addClass(cell, \"selectTdClass\");\r\n        })\r\n    };\r\n    UETable.isEmptyBlock = function (node) {\r\n        var reg = new RegExp(domUtils.fillChar, 'g');\r\n        if (node[browser.ie ? 'innerText' : 'textContent'].replace(/^\\s*$/, '').replace(reg, '').length > 0) {\r\n            return 0;\r\n        }\r\n        for (var i in dtd.$isNotEmpty) if (dtd.$isNotEmpty.hasOwnProperty(i)) {\r\n            if (node.getElementsByTagName(i).length) {\r\n                return 0;\r\n            }\r\n        }\r\n        return 1;\r\n    };\r\n    UETable.getWidth = function (cell) {\r\n        if (!cell)return 0;\r\n        return parseInt(domUtils.getComputedStyle(cell, \"width\"), 10);\r\n    };\r\n\r\n    /**\r\n     * 获取单元格或者单元格组的“对齐”状态。 如果当前的检测对象是一个单元格组， 只有在满足所有单元格的 水平和竖直 对齐属性都相同的\r\n     * 条件时才会返回其状态值，否则将返回null； 如果当前只检测了一个单元格， 则直接返回当前单元格的对齐状态；\r\n     * @param table cell or table cells , 支持单个单元格dom对象 或者 单元格dom对象数组\r\n     * @return { align: 'left' || 'right' || 'center', valign: 'top' || 'middle' || 'bottom' } 或者 null\r\n     */\r\n    UETable.getTableCellAlignState = function ( cells ) {\r\n\r\n        !utils.isArray( cells ) && ( cells = [cells] );\r\n\r\n        var result = {},\r\n            status = ['align', 'valign'],\r\n            tempStatus = null,\r\n            isSame = true;//状态是否相同\r\n\r\n        utils.each( cells, function( cellNode ){\r\n\r\n            utils.each( status, function( currentState ){\r\n\r\n                tempStatus = cellNode.getAttribute( currentState );\r\n\r\n                if( !result[ currentState ] && tempStatus ) {\r\n                    result[ currentState ] = tempStatus;\r\n                } else if( !result[ currentState ] || ( tempStatus !== result[ currentState ] ) ) {\r\n                    isSame = false;\r\n                    return false;\r\n                }\r\n\r\n            } );\r\n\r\n            return isSame;\r\n\r\n        });\r\n\r\n        return isSame ? result : null;\r\n\r\n    };\r\n\r\n    /**\r\n     * 根据当前选区获取相关的table信息\r\n     * @return {Object}\r\n     */\r\n    UETable.getTableItemsByRange = function (editor) {\r\n        var start = editor.selection.getStart();\r\n\r\n        //ff下会选中bookmark\r\n        if( start && start.id && start.id.indexOf('_baidu_bookmark_start_') === 0 && start.nextSibling) {\r\n            start = start.nextSibling;\r\n        }\r\n\r\n        //在table或者td边缘有可能存在选中tr的情况\r\n        var cell = start && domUtils.findParentByTagName(start, [\"td\", \"th\"], true),\r\n            tr = cell && cell.parentNode,\r\n            caption = start && domUtils.findParentByTagName(start, 'caption', true),\r\n            table = caption ? caption.parentNode : tr && tr.parentNode.parentNode;\r\n\r\n        return {\r\n            cell:cell,\r\n            tr:tr,\r\n            table:table,\r\n            caption:caption\r\n        }\r\n    };\r\n    UETable.getUETableBySelected = function (editor) {\r\n        var table = UETable.getTableItemsByRange(editor).table;\r\n        if (table && table.ueTable && table.ueTable.selectedTds.length) {\r\n            return table.ueTable;\r\n        }\r\n        return null;\r\n    };\r\n\r\n    UETable.getDefaultValue = function (editor, table) {\r\n        var borderMap = {\r\n                thin:'0px',\r\n                medium:'1px',\r\n                thick:'2px'\r\n            },\r\n            tableBorder, tdPadding, tdBorder, tmpValue;\r\n        if (!table) {\r\n            table = editor.document.createElement('table');\r\n            table.insertRow(0).insertCell(0).innerHTML = 'xxx';\r\n            editor.body.appendChild(table);\r\n            var td = table.getElementsByTagName('td')[0];\r\n            tmpValue = domUtils.getComputedStyle(table, 'border-left-width');\r\n            tableBorder = parseInt(borderMap[tmpValue] || tmpValue, 10);\r\n            tmpValue = domUtils.getComputedStyle(td, 'padding-left');\r\n            tdPadding = parseInt(borderMap[tmpValue] || tmpValue, 10);\r\n            tmpValue = domUtils.getComputedStyle(td, 'border-left-width');\r\n            tdBorder = parseInt(borderMap[tmpValue] || tmpValue, 10);\r\n            domUtils.remove(table);\r\n            return {\r\n                tableBorder:tableBorder,\r\n                tdPadding:tdPadding,\r\n                tdBorder:tdBorder\r\n            };\r\n        } else {\r\n            td = table.getElementsByTagName('td')[0];\r\n            tmpValue = domUtils.getComputedStyle(table, 'border-left-width');\r\n            tableBorder = parseInt(borderMap[tmpValue] || tmpValue, 10);\r\n            tmpValue = domUtils.getComputedStyle(td, 'padding-left');\r\n            tdPadding = parseInt(borderMap[tmpValue] || tmpValue, 10);\r\n            tmpValue = domUtils.getComputedStyle(td, 'border-left-width');\r\n            tdBorder = parseInt(borderMap[tmpValue] || tmpValue, 10);\r\n            return {\r\n                tableBorder:tableBorder,\r\n                tdPadding:tdPadding,\r\n                tdBorder:tdBorder\r\n            };\r\n        }\r\n    };\r\n    /**\r\n     * 根据当前点击的td或者table获取索引对象\r\n     * @param tdOrTable\r\n     */\r\n    UETable.getUETable = function (tdOrTable) {\r\n        var tag = tdOrTable.tagName.toLowerCase();\r\n        tdOrTable = (tag == \"td\" || tag == \"th\" || tag == 'caption') ? domUtils.findParentByTagName(tdOrTable, \"table\", true) : tdOrTable;\r\n        if (!tdOrTable.ueTable) {\r\n            tdOrTable.ueTable = new UETable(tdOrTable);\r\n        }\r\n        return tdOrTable.ueTable;\r\n    };\r\n\r\n    UETable.cloneCell = function(cell,ignoreMerge,keepPro){\r\n        if (!cell || utils.isString(cell)) {\r\n            return this.table.ownerDocument.createElement(cell || 'td');\r\n        }\r\n        var flag = domUtils.hasClass(cell, \"selectTdClass\");\r\n        flag && domUtils.removeClasses(cell, \"selectTdClass\");\r\n        var tmpCell = cell.cloneNode(true);\r\n        if (ignoreMerge) {\r\n            tmpCell.rowSpan = tmpCell.colSpan = 1;\r\n        }\r\n        //去掉宽高\r\n        !keepPro && domUtils.removeAttributes(tmpCell,'width height');\r\n        !keepPro && domUtils.removeAttributes(tmpCell,'style');\r\n\r\n        tmpCell.style.borderLeftStyle = \"\";\r\n        tmpCell.style.borderTopStyle = \"\";\r\n        tmpCell.style.borderLeftColor = cell.style.borderRightColor;\r\n        tmpCell.style.borderLeftWidth = cell.style.borderRightWidth;\r\n        tmpCell.style.borderTopColor = cell.style.borderBottomColor;\r\n        tmpCell.style.borderTopWidth = cell.style.borderBottomWidth;\r\n        flag && domUtils.addClass(cell, \"selectTdClass\");\r\n        return tmpCell;\r\n    }\r\n\r\n    UETable.prototype = {\r\n        getMaxRows:function () {\r\n            var rows = this.table.rows, maxLen = 1;\r\n            for (var i = 0, row; row = rows[i]; i++) {\r\n                var currentMax = 1;\r\n                for (var j = 0, cj; cj = row.cells[j++];) {\r\n                    currentMax = Math.max(cj.rowSpan || 1, currentMax);\r\n                }\r\n                maxLen = Math.max(currentMax + i, maxLen);\r\n            }\r\n            return maxLen;\r\n        },\r\n        /**\r\n         * 获取当前表格的最大列数\r\n         */\r\n        getMaxCols:function () {\r\n            var rows = this.table.rows, maxLen = 0, cellRows = {};\r\n            for (var i = 0, row; row = rows[i]; i++) {\r\n                var cellsNum = 0;\r\n                for (var j = 0, cj; cj = row.cells[j++];) {\r\n                    cellsNum += (cj.colSpan || 1);\r\n                    if (cj.rowSpan && cj.rowSpan > 1) {\r\n                        for (var k = 1; k < cj.rowSpan; k++) {\r\n                            if (!cellRows['row_' + (i + k)]) {\r\n                                cellRows['row_' + (i + k)] = (cj.colSpan || 1);\r\n                            } else {\r\n                                cellRows['row_' + (i + k)]++\r\n                            }\r\n                        }\r\n\r\n                    }\r\n                }\r\n                cellsNum += cellRows['row_' + i] || 0;\r\n                maxLen = Math.max(cellsNum, maxLen);\r\n            }\r\n            return maxLen;\r\n        },\r\n        getCellColIndex:function (cell) {\r\n\r\n        },\r\n        /**\r\n         * 获取当前cell旁边的单元格，\r\n         * @param cell\r\n         * @param right\r\n         */\r\n        getHSideCell:function (cell, right) {\r\n            try {\r\n                var cellInfo = this.getCellInfo(cell),\r\n                    previewRowIndex, previewColIndex;\r\n                var len = this.selectedTds.length,\r\n                    range = this.cellsRange;\r\n                //首行或者首列没有前置单元格\r\n                if ((!right && (!len ? !cellInfo.colIndex : !range.beginColIndex)) || (right && (!len ? (cellInfo.colIndex == (this.colsNum - 1)) : (range.endColIndex == this.colsNum - 1)))) return null;\r\n\r\n                previewRowIndex = !len ? cellInfo.rowIndex : range.beginRowIndex;\r\n                previewColIndex = !right ? ( !len ? (cellInfo.colIndex < 1 ? 0 : (cellInfo.colIndex - 1)) : range.beginColIndex - 1)\r\n                    : ( !len ? cellInfo.colIndex + 1 : range.endColIndex + 1);\r\n                return this.getCell(this.indexTable[previewRowIndex][previewColIndex].rowIndex, this.indexTable[previewRowIndex][previewColIndex].cellIndex);\r\n            } catch (e) {\r\n                showError(e);\r\n            }\r\n        },\r\n        getTabNextCell:function (cell, preRowIndex) {\r\n            var cellInfo = this.getCellInfo(cell),\r\n                rowIndex = preRowIndex || cellInfo.rowIndex,\r\n                colIndex = cellInfo.colIndex + 1 + (cellInfo.colSpan - 1),\r\n                nextCell;\r\n            try {\r\n                nextCell = this.getCell(this.indexTable[rowIndex][colIndex].rowIndex, this.indexTable[rowIndex][colIndex].cellIndex);\r\n            } catch (e) {\r\n                try {\r\n                    rowIndex = rowIndex * 1 + 1;\r\n                    colIndex = 0;\r\n                    nextCell = this.getCell(this.indexTable[rowIndex][colIndex].rowIndex, this.indexTable[rowIndex][colIndex].cellIndex);\r\n                } catch (e) {\r\n                }\r\n            }\r\n            return nextCell;\r\n\r\n        },\r\n        /**\r\n         * 获取视觉上的后置单元格\r\n         * @param cell\r\n         * @param bottom\r\n         */\r\n        getVSideCell:function (cell, bottom, ignoreRange) {\r\n            try {\r\n                var cellInfo = this.getCellInfo(cell),\r\n                    nextRowIndex, nextColIndex;\r\n                var len = this.selectedTds.length && !ignoreRange,\r\n                    range = this.cellsRange;\r\n                //末行或者末列没有后置单元格\r\n                if ((!bottom && (cellInfo.rowIndex == 0)) || (bottom && (!len ? (cellInfo.rowIndex + cellInfo.rowSpan > this.rowsNum - 1) : (range.endRowIndex == this.rowsNum - 1)))) return null;\r\n\r\n                nextRowIndex = !bottom ? ( !len ? cellInfo.rowIndex - 1 : range.beginRowIndex - 1)\r\n                    : ( !len ? (cellInfo.rowIndex + cellInfo.rowSpan) : range.endRowIndex + 1);\r\n                nextColIndex = !len ? cellInfo.colIndex : range.beginColIndex;\r\n                return this.getCell(this.indexTable[nextRowIndex][nextColIndex].rowIndex, this.indexTable[nextRowIndex][nextColIndex].cellIndex);\r\n            } catch (e) {\r\n                showError(e);\r\n            }\r\n        },\r\n        /**\r\n         * 获取相同结束位置的单元格，xOrY指代了是获取x轴相同还是y轴相同\r\n         */\r\n        getSameEndPosCells:function (cell, xOrY) {\r\n            try {\r\n                var flag = (xOrY.toLowerCase() === \"x\"),\r\n                    end = domUtils.getXY(cell)[flag ? 'x' : 'y'] + cell[\"offset\" + (flag ? 'Width' : 'Height')],\r\n                    rows = this.table.rows,\r\n                    cells = null, returns = [];\r\n                for (var i = 0; i < this.rowsNum; i++) {\r\n                    cells = rows[i].cells;\r\n                    for (var j = 0, tmpCell; tmpCell = cells[j++];) {\r\n                        var tmpEnd = domUtils.getXY(tmpCell)[flag ? 'x' : 'y'] + tmpCell[\"offset\" + (flag ? 'Width' : 'Height')];\r\n                        //对应行的td已经被上面行rowSpan了\r\n                        if (tmpEnd > end && flag) break;\r\n                        if (cell == tmpCell || end == tmpEnd) {\r\n                            //只获取单一的单元格\r\n                            //todo 仅获取单一单元格在特定情况下会造成returns为空，从而影响后续的拖拽实现，修正这个。需考虑性能\r\n                            if (tmpCell[flag ? \"colSpan\" : \"rowSpan\"] == 1) {\r\n                                returns.push(tmpCell);\r\n                            }\r\n                            if (flag) break;\r\n                        }\r\n                    }\r\n                }\r\n                return returns;\r\n            } catch (e) {\r\n                showError(e);\r\n            }\r\n        },\r\n        setCellContent:function (cell, content) {\r\n            cell.innerHTML = content || (browser.ie ? domUtils.fillChar : \"<br />\");\r\n        },\r\n        cloneCell:UETable.cloneCell,\r\n        /**\r\n         * 获取跟当前单元格的右边竖线为左边的所有未合并单元格\r\n         */\r\n        getSameStartPosXCells:function (cell) {\r\n            try {\r\n                var start = domUtils.getXY(cell).x + cell.offsetWidth,\r\n                    rows = this.table.rows, cells , returns = [];\r\n                for (var i = 0; i < this.rowsNum; i++) {\r\n                    cells = rows[i].cells;\r\n                    for (var j = 0, tmpCell; tmpCell = cells[j++];) {\r\n                        var tmpStart = domUtils.getXY(tmpCell).x;\r\n                        if (tmpStart > start) break;\r\n                        if (tmpStart == start && tmpCell.colSpan == 1) {\r\n                            returns.push(tmpCell);\r\n                            break;\r\n                        }\r\n                    }\r\n                }\r\n                return returns;\r\n            } catch (e) {\r\n                showError(e);\r\n            }\r\n        },\r\n        /**\r\n         * 更新table对应的索引表\r\n         */\r\n        update:function (table) {\r\n            this.table = table || this.table;\r\n            this.selectedTds = [];\r\n            this.cellsRange = {};\r\n            this.indexTable = [];\r\n            var rows = this.table.rows,\r\n                rowsNum = this.getMaxRows(),\r\n                dNum = rowsNum - rows.length,\r\n                colsNum = this.getMaxCols();\r\n            while (dNum--) {\r\n                this.table.insertRow(rows.length);\r\n            }\r\n            this.rowsNum = rowsNum;\r\n            this.colsNum = colsNum;\r\n            for (var i = 0, len = rows.length; i < len; i++) {\r\n                this.indexTable[i] = new Array(colsNum);\r\n            }\r\n            //填充索引表\r\n            for (var rowIndex = 0, row; row = rows[rowIndex]; rowIndex++) {\r\n                for (var cellIndex = 0, cell, cells = row.cells; cell = cells[cellIndex]; cellIndex++) {\r\n                    //修正整行被rowSpan时导致的行数计算错误\r\n                    if (cell.rowSpan > rowsNum) {\r\n                        cell.rowSpan = rowsNum;\r\n                    }\r\n                    var colIndex = cellIndex,\r\n                        rowSpan = cell.rowSpan || 1,\r\n                        colSpan = cell.colSpan || 1;\r\n                    //当已经被上一行rowSpan或者被前一列colSpan了，则跳到下一个单元格进行\r\n                    while (this.indexTable[rowIndex][colIndex]) colIndex++;\r\n                    for (var j = 0; j < rowSpan; j++) {\r\n                        for (var k = 0; k < colSpan; k++) {\r\n                            this.indexTable[rowIndex + j][colIndex + k] = {\r\n                                rowIndex:rowIndex,\r\n                                cellIndex:cellIndex,\r\n                                colIndex:colIndex,\r\n                                rowSpan:rowSpan,\r\n                                colSpan:colSpan\r\n                            }\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            //修复残缺td\r\n            for (j = 0; j < rowsNum; j++) {\r\n                for (k = 0; k < colsNum; k++) {\r\n                    if (this.indexTable[j][k] === undefined) {\r\n                        row = rows[j];\r\n                        cell = row.cells[row.cells.length - 1];\r\n                        cell = cell ? cell.cloneNode(true) : this.table.ownerDocument.createElement(\"td\");\r\n                        this.setCellContent(cell);\r\n                        if (cell.colSpan !== 1)cell.colSpan = 1;\r\n                        if (cell.rowSpan !== 1)cell.rowSpan = 1;\r\n                        row.appendChild(cell);\r\n                        this.indexTable[j][k] = {\r\n                            rowIndex:j,\r\n                            cellIndex:cell.cellIndex,\r\n                            colIndex:k,\r\n                            rowSpan:1,\r\n                            colSpan:1\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n            //当框选后删除行或者列后撤销，需要重建选区。\r\n            var tds = domUtils.getElementsByTagName(this.table, \"td\"),\r\n                selectTds = [];\r\n            utils.each(tds, function (td) {\r\n                if (domUtils.hasClass(td, \"selectTdClass\")) {\r\n                    selectTds.push(td);\r\n                }\r\n            });\r\n            if (selectTds.length) {\r\n                var start = selectTds[0],\r\n                    end = selectTds[selectTds.length - 1],\r\n                    startInfo = this.getCellInfo(start),\r\n                    endInfo = this.getCellInfo(end);\r\n                this.selectedTds = selectTds;\r\n                this.cellsRange = {\r\n                    beginRowIndex:startInfo.rowIndex,\r\n                    beginColIndex:startInfo.colIndex,\r\n                    endRowIndex:endInfo.rowIndex + endInfo.rowSpan - 1,\r\n                    endColIndex:endInfo.colIndex + endInfo.colSpan - 1\r\n                };\r\n            }\r\n            //给第一行设置firstRow的样式名称,在排序图标的样式上使用到\r\n            if(!domUtils.hasClass(this.table.rows[0], \"firstRow\")) {\r\n                domUtils.addClass(this.table.rows[0], \"firstRow\");\r\n                for(var i = 1; i< this.table.rows.length; i++) {\r\n                    domUtils.removeClasses(this.table.rows[i], \"firstRow\");\r\n                }\r\n            }\r\n        },\r\n        /**\r\n         * 获取单元格的索引信息\r\n         */\r\n        getCellInfo:function (cell) {\r\n            if (!cell) return;\r\n            var cellIndex = cell.cellIndex,\r\n                rowIndex = cell.parentNode.rowIndex,\r\n                rowInfo = this.indexTable[rowIndex],\r\n                numCols = this.colsNum;\r\n            for (var colIndex = cellIndex; colIndex < numCols; colIndex++) {\r\n                var cellInfo = rowInfo[colIndex];\r\n                if (cellInfo.rowIndex === rowIndex && cellInfo.cellIndex === cellIndex) {\r\n                    return cellInfo;\r\n                }\r\n            }\r\n        },\r\n        /**\r\n         * 根据行列号获取单元格\r\n         */\r\n        getCell:function (rowIndex, cellIndex) {\r\n            return rowIndex < this.rowsNum && this.table.rows[rowIndex].cells[cellIndex] || null;\r\n        },\r\n        /**\r\n         * 删除单元格\r\n         */\r\n        deleteCell:function (cell, rowIndex) {\r\n            rowIndex = typeof rowIndex == 'number' ? rowIndex : cell.parentNode.rowIndex;\r\n            var row = this.table.rows[rowIndex];\r\n            row.deleteCell(cell.cellIndex);\r\n        },\r\n        /**\r\n         * 根据始末两个单元格获取被框选的所有单元格范围\r\n         */\r\n        getCellsRange:function (cellA, cellB) {\r\n            function checkRange(beginRowIndex, beginColIndex, endRowIndex, endColIndex) {\r\n                var tmpBeginRowIndex = beginRowIndex,\r\n                    tmpBeginColIndex = beginColIndex,\r\n                    tmpEndRowIndex = endRowIndex,\r\n                    tmpEndColIndex = endColIndex,\r\n                    cellInfo, colIndex, rowIndex;\r\n                // 通过indexTable检查是否存在超出TableRange上边界的情况\r\n                if (beginRowIndex > 0) {\r\n                    for (colIndex = beginColIndex; colIndex < endColIndex; colIndex++) {\r\n                        cellInfo = me.indexTable[beginRowIndex][colIndex];\r\n                        rowIndex = cellInfo.rowIndex;\r\n                        if (rowIndex < beginRowIndex) {\r\n                            tmpBeginRowIndex = Math.min(rowIndex, tmpBeginRowIndex);\r\n                        }\r\n                    }\r\n                }\r\n                // 通过indexTable检查是否存在超出TableRange右边界的情况\r\n                if (endColIndex < me.colsNum) {\r\n                    for (rowIndex = beginRowIndex; rowIndex < endRowIndex; rowIndex++) {\r\n                        cellInfo = me.indexTable[rowIndex][endColIndex];\r\n                        colIndex = cellInfo.colIndex + cellInfo.colSpan - 1;\r\n                        if (colIndex > endColIndex) {\r\n                            tmpEndColIndex = Math.max(colIndex, tmpEndColIndex);\r\n                        }\r\n                    }\r\n                }\r\n                // 检查是否有超出TableRange下边界的情况\r\n                if (endRowIndex < me.rowsNum) {\r\n                    for (colIndex = beginColIndex; colIndex < endColIndex; colIndex++) {\r\n                        cellInfo = me.indexTable[endRowIndex][colIndex];\r\n                        rowIndex = cellInfo.rowIndex + cellInfo.rowSpan - 1;\r\n                        if (rowIndex > endRowIndex) {\r\n                            tmpEndRowIndex = Math.max(rowIndex, tmpEndRowIndex);\r\n                        }\r\n                    }\r\n                }\r\n                // 检查是否有超出TableRange左边界的情况\r\n                if (beginColIndex > 0) {\r\n                    for (rowIndex = beginRowIndex; rowIndex < endRowIndex; rowIndex++) {\r\n                        cellInfo = me.indexTable[rowIndex][beginColIndex];\r\n                        colIndex = cellInfo.colIndex;\r\n                        if (colIndex < beginColIndex) {\r\n                            tmpBeginColIndex = Math.min(cellInfo.colIndex, tmpBeginColIndex);\r\n                        }\r\n                    }\r\n                }\r\n                //递归调用直至所有完成所有框选单元格的扩展\r\n                if (tmpBeginRowIndex != beginRowIndex || tmpBeginColIndex != beginColIndex || tmpEndRowIndex != endRowIndex || tmpEndColIndex != endColIndex) {\r\n                    return checkRange(tmpBeginRowIndex, tmpBeginColIndex, tmpEndRowIndex, tmpEndColIndex);\r\n                } else {\r\n                    // 不需要扩展TableRange的情况\r\n                    return {\r\n                        beginRowIndex:beginRowIndex,\r\n                        beginColIndex:beginColIndex,\r\n                        endRowIndex:endRowIndex,\r\n                        endColIndex:endColIndex\r\n                    };\r\n                }\r\n            }\r\n\r\n            try {\r\n                var me = this,\r\n                    cellAInfo = me.getCellInfo(cellA);\r\n                if (cellA === cellB) {\r\n                    return {\r\n                        beginRowIndex:cellAInfo.rowIndex,\r\n                        beginColIndex:cellAInfo.colIndex,\r\n                        endRowIndex:cellAInfo.rowIndex + cellAInfo.rowSpan - 1,\r\n                        endColIndex:cellAInfo.colIndex + cellAInfo.colSpan - 1\r\n                    };\r\n                }\r\n                var cellBInfo = me.getCellInfo(cellB);\r\n                // 计算TableRange的四个边\r\n                var beginRowIndex = Math.min(cellAInfo.rowIndex, cellBInfo.rowIndex),\r\n                    beginColIndex = Math.min(cellAInfo.colIndex, cellBInfo.colIndex),\r\n                    endRowIndex = Math.max(cellAInfo.rowIndex + cellAInfo.rowSpan - 1, cellBInfo.rowIndex + cellBInfo.rowSpan - 1),\r\n                    endColIndex = Math.max(cellAInfo.colIndex + cellAInfo.colSpan - 1, cellBInfo.colIndex + cellBInfo.colSpan - 1);\r\n\r\n                return checkRange(beginRowIndex, beginColIndex, endRowIndex, endColIndex);\r\n            } catch (e) {\r\n                //throw e;\r\n            }\r\n        },\r\n        /**\r\n         * 依据cellsRange获取对应的单元格集合\r\n         */\r\n        getCells:function (range) {\r\n            //每次获取cells之前必须先清除上次的选择，否则会对后续获取操作造成影响\r\n            this.clearSelected();\r\n            var beginRowIndex = range.beginRowIndex,\r\n                beginColIndex = range.beginColIndex,\r\n                endRowIndex = range.endRowIndex,\r\n                endColIndex = range.endColIndex,\r\n                cellInfo, rowIndex, colIndex, tdHash = {}, returnTds = [];\r\n            for (var i = beginRowIndex; i <= endRowIndex; i++) {\r\n                for (var j = beginColIndex; j <= endColIndex; j++) {\r\n                    cellInfo = this.indexTable[i][j];\r\n                    rowIndex = cellInfo.rowIndex;\r\n                    colIndex = cellInfo.colIndex;\r\n                    // 如果Cells里已经包含了此Cell则跳过\r\n                    var key = rowIndex + '|' + colIndex;\r\n                    if (tdHash[key]) continue;\r\n                    tdHash[key] = 1;\r\n                    if (rowIndex < i || colIndex < j || rowIndex + cellInfo.rowSpan - 1 > endRowIndex || colIndex + cellInfo.colSpan - 1 > endColIndex) {\r\n                        return null;\r\n                    }\r\n                    returnTds.push(this.getCell(rowIndex, cellInfo.cellIndex));\r\n                }\r\n            }\r\n            return returnTds;\r\n        },\r\n        /**\r\n         * 清理已经选中的单元格\r\n         */\r\n        clearSelected:function () {\r\n            UETable.removeSelectedClass(this.selectedTds);\r\n            this.selectedTds = [];\r\n            this.cellsRange = {};\r\n        },\r\n        /**\r\n         * 根据range设置已经选中的单元格\r\n         */\r\n        setSelected:function (range) {\r\n            var cells = this.getCells(range);\r\n            UETable.addSelectedClass(cells);\r\n            this.selectedTds = cells;\r\n            this.cellsRange = range;\r\n        },\r\n        isFullRow:function () {\r\n            var range = this.cellsRange;\r\n            return (range.endColIndex - range.beginColIndex + 1) == this.colsNum;\r\n        },\r\n        isFullCol:function () {\r\n            var range = this.cellsRange,\r\n                table = this.table,\r\n                ths = table.getElementsByTagName(\"th\"),\r\n                rows = range.endRowIndex - range.beginRowIndex + 1;\r\n            return  !ths.length ? rows == this.rowsNum : rows == this.rowsNum || (rows == this.rowsNum - 1);\r\n\r\n        },\r\n        /**\r\n         * 获取视觉上的前置单元格，默认是左边，top传入时\r\n         * @param cell\r\n         * @param top\r\n         */\r\n        getNextCell:function (cell, bottom, ignoreRange) {\r\n            try {\r\n                var cellInfo = this.getCellInfo(cell),\r\n                    nextRowIndex, nextColIndex;\r\n                var len = this.selectedTds.length && !ignoreRange,\r\n                    range = this.cellsRange;\r\n                //末行或者末列没有后置单元格\r\n                if ((!bottom && (cellInfo.rowIndex == 0)) || (bottom && (!len ? (cellInfo.rowIndex + cellInfo.rowSpan > this.rowsNum - 1) : (range.endRowIndex == this.rowsNum - 1)))) return null;\r\n\r\n                nextRowIndex = !bottom ? ( !len ? cellInfo.rowIndex - 1 : range.beginRowIndex - 1)\r\n                    : ( !len ? (cellInfo.rowIndex + cellInfo.rowSpan) : range.endRowIndex + 1);\r\n                nextColIndex = !len ? cellInfo.colIndex : range.beginColIndex;\r\n                return this.getCell(this.indexTable[nextRowIndex][nextColIndex].rowIndex, this.indexTable[nextRowIndex][nextColIndex].cellIndex);\r\n            } catch (e) {\r\n                showError(e);\r\n            }\r\n        },\r\n        getPreviewCell:function (cell, top) {\r\n            try {\r\n                var cellInfo = this.getCellInfo(cell),\r\n                    previewRowIndex, previewColIndex;\r\n                var len = this.selectedTds.length,\r\n                    range = this.cellsRange;\r\n                //首行或者首列没有前置单元格\r\n                if ((!top && (!len ? !cellInfo.colIndex : !range.beginColIndex)) || (top && (!len ? (cellInfo.rowIndex > (this.colsNum - 1)) : (range.endColIndex == this.colsNum - 1)))) return null;\r\n\r\n                previewRowIndex = !top ? ( !len ? cellInfo.rowIndex : range.beginRowIndex )\r\n                    : ( !len ? (cellInfo.rowIndex < 1 ? 0 : (cellInfo.rowIndex - 1)) : range.beginRowIndex);\r\n                previewColIndex = !top ? ( !len ? (cellInfo.colIndex < 1 ? 0 : (cellInfo.colIndex - 1)) : range.beginColIndex - 1)\r\n                    : ( !len ? cellInfo.colIndex : range.endColIndex + 1);\r\n                return this.getCell(this.indexTable[previewRowIndex][previewColIndex].rowIndex, this.indexTable[previewRowIndex][previewColIndex].cellIndex);\r\n            } catch (e) {\r\n                showError(e);\r\n            }\r\n        },\r\n        /**\r\n         * 移动单元格中的内容\r\n         */\r\n        moveContent:function (cellTo, cellFrom) {\r\n            if (UETable.isEmptyBlock(cellFrom)) return;\r\n            if (UETable.isEmptyBlock(cellTo)) {\r\n                cellTo.innerHTML = cellFrom.innerHTML;\r\n                return;\r\n            }\r\n            var child = cellTo.lastChild;\r\n            if (child.nodeType == 3 || !dtd.$block[child.tagName]) {\r\n                cellTo.appendChild(cellTo.ownerDocument.createElement('br'))\r\n            }\r\n            while (child = cellFrom.firstChild) {\r\n                cellTo.appendChild(child);\r\n            }\r\n        },\r\n        /**\r\n         * 向右合并单元格\r\n         */\r\n        mergeRight:function (cell) {\r\n            var cellInfo = this.getCellInfo(cell),\r\n                rightColIndex = cellInfo.colIndex + cellInfo.colSpan,\r\n                rightCellInfo = this.indexTable[cellInfo.rowIndex][rightColIndex],\r\n                rightCell = this.getCell(rightCellInfo.rowIndex, rightCellInfo.cellIndex);\r\n            //合并\r\n            cell.colSpan = cellInfo.colSpan + rightCellInfo.colSpan;\r\n            //被合并的单元格不应存在宽度属性\r\n            cell.removeAttribute(\"width\");\r\n            //移动内容\r\n            this.moveContent(cell, rightCell);\r\n            //删掉被合并的Cell\r\n            this.deleteCell(rightCell, rightCellInfo.rowIndex);\r\n            this.update();\r\n        },\r\n        /**\r\n         * 向下合并单元格\r\n         */\r\n        mergeDown:function (cell) {\r\n            var cellInfo = this.getCellInfo(cell),\r\n                downRowIndex = cellInfo.rowIndex + cellInfo.rowSpan,\r\n                downCellInfo = this.indexTable[downRowIndex][cellInfo.colIndex],\r\n                downCell = this.getCell(downCellInfo.rowIndex, downCellInfo.cellIndex);\r\n            cell.rowSpan = cellInfo.rowSpan + downCellInfo.rowSpan;\r\n            cell.removeAttribute(\"height\");\r\n            this.moveContent(cell, downCell);\r\n            this.deleteCell(downCell, downCellInfo.rowIndex);\r\n            this.update();\r\n        },\r\n        /**\r\n         * 合并整个range中的内容\r\n         */\r\n        mergeRange:function () {\r\n            //由于合并操作可以在任意时刻进行，所以无法通过鼠标位置等信息实时生成range，只能通过缓存实例中的cellsRange对象来访问\r\n            var range = this.cellsRange,\r\n                leftTopCell = this.getCell(range.beginRowIndex, this.indexTable[range.beginRowIndex][range.beginColIndex].cellIndex);\r\n\r\n            if (leftTopCell.tagName == \"TH\" && range.endRowIndex !== range.beginRowIndex) {\r\n                var index = this.indexTable,\r\n                    info = this.getCellInfo(leftTopCell);\r\n                leftTopCell = this.getCell(1, index[1][info.colIndex].cellIndex);\r\n                range = this.getCellsRange(leftTopCell, this.getCell(index[this.rowsNum - 1][info.colIndex].rowIndex, index[this.rowsNum - 1][info.colIndex].cellIndex));\r\n            }\r\n\r\n            // 删除剩余的Cells\r\n            var cells = this.getCells(range);\r\n            for(var i= 0,ci;ci=cells[i++];){\r\n                if (ci !== leftTopCell) {\r\n                    this.moveContent(leftTopCell, ci);\r\n                    this.deleteCell(ci);\r\n                }\r\n            }\r\n            // 修改左上角Cell的rowSpan和colSpan，并调整宽度属性设置\r\n            leftTopCell.rowSpan = range.endRowIndex - range.beginRowIndex + 1;\r\n            leftTopCell.rowSpan > 1 && leftTopCell.removeAttribute(\"height\");\r\n            leftTopCell.colSpan = range.endColIndex - range.beginColIndex + 1;\r\n            leftTopCell.colSpan > 1 && leftTopCell.removeAttribute(\"width\");\r\n            if (leftTopCell.rowSpan == this.rowsNum && leftTopCell.colSpan != 1) {\r\n                leftTopCell.colSpan = 1;\r\n            }\r\n\r\n            if (leftTopCell.colSpan == this.colsNum && leftTopCell.rowSpan != 1) {\r\n                var rowIndex = leftTopCell.parentNode.rowIndex;\r\n                //解决IE下的表格操作问题\r\n                if( this.table.deleteRow ) {\r\n                    for (var i = rowIndex+ 1, curIndex=rowIndex+ 1, len=leftTopCell.rowSpan; i < len; i++) {\r\n                        this.table.deleteRow(curIndex);\r\n                    }\r\n                } else {\r\n                    for (var i = 0, len=leftTopCell.rowSpan - 1; i < len; i++) {\r\n                        var row = this.table.rows[rowIndex + 1];\r\n                        row.parentNode.removeChild(row);\r\n                    }\r\n                }\r\n                leftTopCell.rowSpan = 1;\r\n            }\r\n            this.update();\r\n        },\r\n        /**\r\n         * 插入一行单元格\r\n         */\r\n        insertRow:function (rowIndex, sourceCell) {\r\n            var numCols = this.colsNum,\r\n                table = this.table,\r\n                row = table.insertRow(rowIndex), cell,\r\n                isInsertTitle = typeof sourceCell == 'string' && sourceCell.toUpperCase() == 'TH';\r\n\r\n            function replaceTdToTh(colIndex, cell, tableRow) {\r\n                if (colIndex == 0) {\r\n                    var tr = tableRow.nextSibling || tableRow.previousSibling,\r\n                        th = tr.cells[colIndex];\r\n                    if (th.tagName == 'TH') {\r\n                        th = cell.ownerDocument.createElement(\"th\");\r\n                        th.appendChild(cell.firstChild);\r\n                        tableRow.insertBefore(th, cell);\r\n                        domUtils.remove(cell)\r\n                    }\r\n                }else{\r\n                    if (cell.tagName == 'TH') {\r\n                        var td = cell.ownerDocument.createElement(\"td\");\r\n                        td.appendChild(cell.firstChild);\r\n                        tableRow.insertBefore(td, cell);\r\n                        domUtils.remove(cell)\r\n                    }\r\n                }\r\n            }\r\n\r\n            //首行直接插入,无需考虑部分单元格被rowspan的情况\r\n            if (rowIndex == 0 || rowIndex == this.rowsNum) {\r\n                for (var colIndex = 0; colIndex < numCols; colIndex++) {\r\n                    cell = this.cloneCell(sourceCell, true);\r\n                    this.setCellContent(cell);\r\n                    cell.getAttribute('vAlign') && cell.setAttribute('vAlign', cell.getAttribute('vAlign'));\r\n                    row.appendChild(cell);\r\n                    if(!isInsertTitle) replaceTdToTh(colIndex, cell, row);\r\n                }\r\n            } else {\r\n                var infoRow = this.indexTable[rowIndex],\r\n                    cellIndex = 0;\r\n                for (colIndex = 0; colIndex < numCols; colIndex++) {\r\n                    var cellInfo = infoRow[colIndex];\r\n                    //如果存在某个单元格的rowspan穿过待插入行的位置，则修改该单元格的rowspan即可，无需插入单元格\r\n                    if (cellInfo.rowIndex < rowIndex) {\r\n                        cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex);\r\n                        cell.rowSpan = cellInfo.rowSpan + 1;\r\n                    } else {\r\n                        cell = this.cloneCell(sourceCell, true);\r\n                        this.setCellContent(cell);\r\n                        row.appendChild(cell);\r\n                    }\r\n                    if(!isInsertTitle) replaceTdToTh(colIndex, cell, row);\r\n                }\r\n            }\r\n            //框选时插入不触发contentchange，需要手动更新索引。\r\n            this.update();\r\n            return row;\r\n        },\r\n        /**\r\n         * 删除一行单元格\r\n         * @param rowIndex\r\n         */\r\n        deleteRow:function (rowIndex) {\r\n            var row = this.table.rows[rowIndex],\r\n                infoRow = this.indexTable[rowIndex],\r\n                colsNum = this.colsNum,\r\n                count = 0;     //处理计数\r\n            for (var colIndex = 0; colIndex < colsNum;) {\r\n                var cellInfo = infoRow[colIndex],\r\n                    cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex);\r\n                if (cell.rowSpan > 1) {\r\n                    if (cellInfo.rowIndex == rowIndex) {\r\n                        var clone = cell.cloneNode(true);\r\n                        clone.rowSpan = cell.rowSpan - 1;\r\n                        clone.innerHTML = \"\";\r\n                        cell.rowSpan = 1;\r\n                        var nextRowIndex = rowIndex + 1,\r\n                            nextRow = this.table.rows[nextRowIndex],\r\n                            insertCellIndex,\r\n                            preMerged = this.getPreviewMergedCellsNum(nextRowIndex, colIndex) - count;\r\n                        if (preMerged < colIndex) {\r\n                            insertCellIndex = colIndex - preMerged - 1;\r\n                            //nextRow.insertCell(insertCellIndex);\r\n                            domUtils.insertAfter(nextRow.cells[insertCellIndex], clone);\r\n                        } else {\r\n                            if (nextRow.cells.length) nextRow.insertBefore(clone, nextRow.cells[0])\r\n                        }\r\n                        count += 1;\r\n                        //cell.parentNode.removeChild(cell);\r\n                    }\r\n                }\r\n                colIndex += cell.colSpan || 1;\r\n            }\r\n            var deleteTds = [], cacheMap = {};\r\n            for (colIndex = 0; colIndex < colsNum; colIndex++) {\r\n                var tmpRowIndex = infoRow[colIndex].rowIndex,\r\n                    tmpCellIndex = infoRow[colIndex].cellIndex,\r\n                    key = tmpRowIndex + \"_\" + tmpCellIndex;\r\n                if (cacheMap[key])continue;\r\n                cacheMap[key] = 1;\r\n                cell = this.getCell(tmpRowIndex, tmpCellIndex);\r\n                deleteTds.push(cell);\r\n            }\r\n            var mergeTds = [];\r\n            utils.each(deleteTds, function (td) {\r\n                if (td.rowSpan == 1) {\r\n                    td.parentNode.removeChild(td);\r\n                } else {\r\n                    mergeTds.push(td);\r\n                }\r\n            });\r\n            utils.each(mergeTds, function (td) {\r\n                td.rowSpan--;\r\n            });\r\n            row.parentNode.removeChild(row);\r\n            //浏览器方法本身存在bug,采用自定义方法删除\r\n            //this.table.deleteRow(rowIndex);\r\n            this.update();\r\n        },\r\n        insertCol:function (colIndex, sourceCell, defaultValue) {\r\n            var rowsNum = this.rowsNum,\r\n                rowIndex = 0,\r\n                tableRow, cell,\r\n                backWidth = parseInt((this.table.offsetWidth - (this.colsNum + 1) * 20 - (this.colsNum + 1)) / (this.colsNum + 1), 10),\r\n                isInsertTitleCol = typeof sourceCell == 'string' && sourceCell.toUpperCase() == 'TH';\r\n\r\n            function replaceTdToTh(rowIndex, cell, tableRow) {\r\n                if (rowIndex == 0) {\r\n                    var th = cell.nextSibling || cell.previousSibling;\r\n                    if (th.tagName == 'TH') {\r\n                        th = cell.ownerDocument.createElement(\"th\");\r\n                        th.appendChild(cell.firstChild);\r\n                        tableRow.insertBefore(th, cell);\r\n                        domUtils.remove(cell)\r\n                    }\r\n                }else{\r\n                    if (cell.tagName == 'TH') {\r\n                        var td = cell.ownerDocument.createElement(\"td\");\r\n                        td.appendChild(cell.firstChild);\r\n                        tableRow.insertBefore(td, cell);\r\n                        domUtils.remove(cell)\r\n                    }\r\n                }\r\n            }\r\n\r\n            var preCell;\r\n            if (colIndex == 0 || colIndex == this.colsNum) {\r\n                for (; rowIndex < rowsNum; rowIndex++) {\r\n                    tableRow = this.table.rows[rowIndex];\r\n                    preCell = tableRow.cells[colIndex == 0 ? colIndex : tableRow.cells.length];\r\n                    cell = this.cloneCell(sourceCell, true); //tableRow.insertCell(colIndex == 0 ? colIndex : tableRow.cells.length);\r\n                    this.setCellContent(cell);\r\n                    cell.setAttribute('vAlign', cell.getAttribute('vAlign'));\r\n                    preCell && cell.setAttribute('width', preCell.getAttribute('width'));\r\n                    if (!colIndex) {\r\n                        tableRow.insertBefore(cell, tableRow.cells[0]);\r\n                    } else {\r\n                        domUtils.insertAfter(tableRow.cells[tableRow.cells.length - 1], cell);\r\n                    }\r\n                    if(!isInsertTitleCol) replaceTdToTh(rowIndex, cell, tableRow)\r\n                }\r\n            } else {\r\n                for (; rowIndex < rowsNum; rowIndex++) {\r\n                    var cellInfo = this.indexTable[rowIndex][colIndex];\r\n                    if (cellInfo.colIndex < colIndex) {\r\n                        cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex);\r\n                        cell.colSpan = cellInfo.colSpan + 1;\r\n                    } else {\r\n                        tableRow = this.table.rows[rowIndex];\r\n                        preCell = tableRow.cells[cellInfo.cellIndex];\r\n\r\n                        cell = this.cloneCell(sourceCell, true);//tableRow.insertCell(cellInfo.cellIndex);\r\n                        this.setCellContent(cell);\r\n                        cell.setAttribute('vAlign', cell.getAttribute('vAlign'));\r\n                        preCell && cell.setAttribute('width', preCell.getAttribute('width'));\r\n                        //防止IE下报错\r\n                        preCell ? tableRow.insertBefore(cell, preCell) : tableRow.appendChild(cell);\r\n                    }\r\n                    if(!isInsertTitleCol) replaceTdToTh(rowIndex, cell, tableRow);\r\n                }\r\n            }\r\n            //框选时插入不触发contentchange，需要手动更新索引\r\n            this.update();\r\n            this.updateWidth(backWidth, defaultValue || {tdPadding:10, tdBorder:1});\r\n        },\r\n        updateWidth:function (width, defaultValue) {\r\n            var table = this.table,\r\n                tmpWidth = UETable.getWidth(table) - defaultValue.tdPadding * 2 - defaultValue.tdBorder + width;\r\n            if (tmpWidth < table.ownerDocument.body.offsetWidth) {\r\n                table.setAttribute(\"width\", tmpWidth);\r\n                return;\r\n            }\r\n            var tds = domUtils.getElementsByTagName(this.table, \"td th\");\r\n            utils.each(tds, function (td) {\r\n                td.setAttribute(\"width\", width);\r\n            })\r\n        },\r\n        deleteCol:function (colIndex) {\r\n            var indexTable = this.indexTable,\r\n                tableRows = this.table.rows,\r\n                backTableWidth = this.table.getAttribute(\"width\"),\r\n                backTdWidth = 0,\r\n                rowsNum = this.rowsNum,\r\n                cacheMap = {};\r\n            for (var rowIndex = 0; rowIndex < rowsNum;) {\r\n                var infoRow = indexTable[rowIndex],\r\n                    cellInfo = infoRow[colIndex],\r\n                    key = cellInfo.rowIndex + '_' + cellInfo.colIndex;\r\n                // 跳过已经处理过的Cell\r\n                if (cacheMap[key])continue;\r\n                cacheMap[key] = 1;\r\n                var cell = this.getCell(cellInfo.rowIndex, cellInfo.cellIndex);\r\n                if (!backTdWidth) backTdWidth = cell && parseInt(cell.offsetWidth / cell.colSpan, 10).toFixed(0);\r\n                // 如果Cell的colSpan大于1, 就修改colSpan, 否则就删掉这个Cell\r\n                if (cell.colSpan > 1) {\r\n                    cell.colSpan--;\r\n                } else {\r\n                    tableRows[rowIndex].deleteCell(cellInfo.cellIndex);\r\n                }\r\n                rowIndex += cellInfo.rowSpan || 1;\r\n            }\r\n            this.table.setAttribute(\"width\", backTableWidth - backTdWidth);\r\n            this.update();\r\n        },\r\n        splitToCells:function (cell) {\r\n            var me = this,\r\n                cells = this.splitToRows(cell);\r\n            utils.each(cells, function (cell) {\r\n                me.splitToCols(cell);\r\n            })\r\n        },\r\n        splitToRows:function (cell) {\r\n            var cellInfo = this.getCellInfo(cell),\r\n                rowIndex = cellInfo.rowIndex,\r\n                colIndex = cellInfo.colIndex,\r\n                results = [];\r\n            // 修改Cell的rowSpan\r\n            cell.rowSpan = 1;\r\n            results.push(cell);\r\n            // 补齐单元格\r\n            for (var i = rowIndex, endRow = rowIndex + cellInfo.rowSpan; i < endRow; i++) {\r\n                if (i == rowIndex)continue;\r\n                var tableRow = this.table.rows[i],\r\n                    tmpCell = tableRow.insertCell(colIndex - this.getPreviewMergedCellsNum(i, colIndex));\r\n                tmpCell.colSpan = cellInfo.colSpan;\r\n                this.setCellContent(tmpCell);\r\n                tmpCell.setAttribute('vAlign', cell.getAttribute('vAlign'));\r\n                tmpCell.setAttribute('align', cell.getAttribute('align'));\r\n                if (cell.style.cssText) {\r\n                    tmpCell.style.cssText = cell.style.cssText;\r\n                }\r\n                results.push(tmpCell);\r\n            }\r\n            this.update();\r\n            return results;\r\n        },\r\n        getPreviewMergedCellsNum:function (rowIndex, colIndex) {\r\n            var indexRow = this.indexTable[rowIndex],\r\n                num = 0;\r\n            for (var i = 0; i < colIndex;) {\r\n                var colSpan = indexRow[i].colSpan,\r\n                    tmpRowIndex = indexRow[i].rowIndex;\r\n                num += (colSpan - (tmpRowIndex == rowIndex ? 1 : 0));\r\n                i += colSpan;\r\n            }\r\n            return num;\r\n        },\r\n        splitToCols:function (cell) {\r\n            var backWidth = (cell.offsetWidth / cell.colSpan - 22).toFixed(0),\r\n\r\n                cellInfo = this.getCellInfo(cell),\r\n                rowIndex = cellInfo.rowIndex,\r\n                colIndex = cellInfo.colIndex,\r\n                results = [];\r\n            // 修改Cell的rowSpan\r\n            cell.colSpan = 1;\r\n            cell.setAttribute(\"width\", backWidth);\r\n            results.push(cell);\r\n            // 补齐单元格\r\n            for (var j = colIndex, endCol = colIndex + cellInfo.colSpan; j < endCol; j++) {\r\n                if (j == colIndex)continue;\r\n                var tableRow = this.table.rows[rowIndex],\r\n                    tmpCell = tableRow.insertCell(this.indexTable[rowIndex][j].cellIndex + 1);\r\n                tmpCell.rowSpan = cellInfo.rowSpan;\r\n                this.setCellContent(tmpCell);\r\n                tmpCell.setAttribute('vAlign', cell.getAttribute('vAlign'));\r\n                tmpCell.setAttribute('align', cell.getAttribute('align'));\r\n                tmpCell.setAttribute('width', backWidth);\r\n                if (cell.style.cssText) {\r\n                    tmpCell.style.cssText = cell.style.cssText;\r\n                }\r\n                //处理th的情况\r\n                if (cell.tagName == 'TH') {\r\n                    var th = cell.ownerDocument.createElement('th');\r\n                    th.appendChild(tmpCell.firstChild);\r\n                    th.setAttribute('vAlign', cell.getAttribute('vAlign'));\r\n                    th.rowSpan = tmpCell.rowSpan;\r\n                    tableRow.insertBefore(th, tmpCell);\r\n                    domUtils.remove(tmpCell);\r\n                }\r\n                results.push(tmpCell);\r\n            }\r\n            this.update();\r\n            return results;\r\n        },\r\n        isLastCell:function (cell, rowsNum, colsNum) {\r\n            rowsNum = rowsNum || this.rowsNum;\r\n            colsNum = colsNum || this.colsNum;\r\n            var cellInfo = this.getCellInfo(cell);\r\n            return ((cellInfo.rowIndex + cellInfo.rowSpan) == rowsNum) &&\r\n                ((cellInfo.colIndex + cellInfo.colSpan) == colsNum);\r\n        },\r\n        getLastCell:function (cells) {\r\n            cells = cells || this.table.getElementsByTagName(\"td\");\r\n            var firstInfo = this.getCellInfo(cells[0]);\r\n            var me = this, last = cells[0],\r\n                tr = last.parentNode,\r\n                cellsNum = 0, cols = 0, rows;\r\n            utils.each(cells, function (cell) {\r\n                if (cell.parentNode == tr)cols += cell.colSpan || 1;\r\n                cellsNum += cell.rowSpan * cell.colSpan || 1;\r\n            });\r\n            rows = cellsNum / cols;\r\n            utils.each(cells, function (cell) {\r\n                if (me.isLastCell(cell, rows, cols)) {\r\n                    last = cell;\r\n                    return false;\r\n                }\r\n            });\r\n            return last;\r\n\r\n        },\r\n        selectRow:function (rowIndex) {\r\n            var indexRow = this.indexTable[rowIndex],\r\n                start = this.getCell(indexRow[0].rowIndex, indexRow[0].cellIndex),\r\n                end = this.getCell(indexRow[this.colsNum - 1].rowIndex, indexRow[this.colsNum - 1].cellIndex),\r\n                range = this.getCellsRange(start, end);\r\n            this.setSelected(range);\r\n        },\r\n        selectTable:function () {\r\n            var tds = this.table.getElementsByTagName(\"td\"),\r\n                range = this.getCellsRange(tds[0], tds[tds.length - 1]);\r\n            this.setSelected(range);\r\n        },\r\n        setBackground:function (cells, value) {\r\n            if (typeof value === \"string\") {\r\n                utils.each(cells, function (cell) {\r\n                    cell.style.backgroundColor = value;\r\n                })\r\n            } else if (typeof value === \"object\") {\r\n                value = utils.extend({\r\n                    repeat:true,\r\n                    colorList:[\"#ddd\", \"#fff\"]\r\n                }, value);\r\n                var rowIndex = this.getCellInfo(cells[0]).rowIndex,\r\n                    count = 0,\r\n                    colors = value.colorList,\r\n                    getColor = function (list, index, repeat) {\r\n                        return list[index] ? list[index] : repeat ? list[index % list.length] : \"\";\r\n                    };\r\n                for (var i = 0, cell; cell = cells[i++];) {\r\n                    var cellInfo = this.getCellInfo(cell);\r\n                    cell.style.backgroundColor = getColor(colors, ((rowIndex + count) == cellInfo.rowIndex) ? count : ++count, value.repeat);\r\n                }\r\n            }\r\n        },\r\n        removeBackground:function (cells) {\r\n            utils.each(cells, function (cell) {\r\n                cell.style.backgroundColor = \"\";\r\n            })\r\n        }\r\n\r\n\r\n    };\r\n    function showError(e) {\r\n    }\r\n})();\n\n// plugins/table.cmds.js\n/**\r\n * Created with JetBrains PhpStorm.\r\n * User: taoqili\r\n * Date: 13-2-20\r\n * Time: 下午6:25\r\n * To change this template use File | Settings | File Templates.\r\n */\r\n;\r\n(function () {\r\n    var UT = UE.UETable,\r\n        getTableItemsByRange = function (editor) {\r\n            return UT.getTableItemsByRange(editor);\r\n        },\r\n        getUETableBySelected = function (editor) {\r\n            return UT.getUETableBySelected(editor)\r\n        },\r\n        getDefaultValue = function (editor, table) {\r\n            return UT.getDefaultValue(editor, table);\r\n        },\r\n        getUETable = function (tdOrTable) {\r\n            return UT.getUETable(tdOrTable);\r\n        };\r\n\r\n\r\n    UE.commands['inserttable'] = {\r\n        queryCommandState: function () {\r\n            return getTableItemsByRange(this).table ? -1 : 0;\r\n        },\r\n        execCommand: function (cmd, opt) {\r\n            function createTable(opt, tdWidth) {\r\n                var html = [],\r\n                    rowsNum = opt.numRows,\r\n                    colsNum = opt.numCols;\r\n                for (var r = 0; r < rowsNum; r++) {\r\n                    html.push('<tr' + (r == 0 ? ' class=\"firstRow\"':'') + '>');\r\n                    for (var c = 0; c < colsNum; c++) {\r\n                        html.push('<td width=\"' + tdWidth + '\"  vAlign=\"' + opt.tdvalign + '\" >' + (browser.ie && browser.version < 11 ? domUtils.fillChar : '<br/>') + '</td>')\r\n                    }\r\n                    html.push('</tr>')\r\n                }\r\n                //禁止指定table-width\r\n                return '<table><tbody>' + html.join('') + '</tbody></table>'\r\n            }\r\n\r\n            if (!opt) {\r\n                opt = utils.extend({}, {\r\n                    numCols: this.options.defaultCols,\r\n                    numRows: this.options.defaultRows,\r\n                    tdvalign: this.options.tdvalign\r\n                })\r\n            }\r\n            var me = this;\r\n            var range = this.selection.getRange(),\r\n                start = range.startContainer,\r\n                firstParentBlock = domUtils.findParent(start, function (node) {\r\n                    return domUtils.isBlockElm(node);\r\n                }, true) || me.body;\r\n\r\n            var defaultValue = getDefaultValue(me),\r\n                tableWidth = firstParentBlock.offsetWidth,\r\n                tdWidth = Math.floor(tableWidth / opt.numCols - defaultValue.tdPadding * 2 - defaultValue.tdBorder);\r\n\r\n            //todo其他属性\r\n            !opt.tdvalign && (opt.tdvalign = me.options.tdvalign);\r\n            me.execCommand(\"inserthtml\", createTable(opt, tdWidth));\r\n        }\r\n    };\r\n\r\n    UE.commands['insertparagraphbeforetable'] = {\r\n        queryCommandState: function () {\r\n            return getTableItemsByRange(this).cell ? 0 : -1;\r\n        },\r\n        execCommand: function () {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (table) {\r\n                var p = this.document.createElement(\"p\");\r\n                p.innerHTML = browser.ie ? '&nbsp;' : '<br />';\r\n                table.parentNode.insertBefore(p, table);\r\n                this.selection.getRange().setStart(p, 0).setCursor();\r\n            }\r\n        }\r\n    };\r\n\r\n    UE.commands['deletetable'] = {\r\n        queryCommandState: function () {\r\n            var rng = this.selection.getRange();\r\n            return domUtils.findParentByTagName(rng.startContainer, 'table', true) ? 0 : -1;\r\n        },\r\n        execCommand: function (cmd, table) {\r\n            var rng = this.selection.getRange();\r\n            table = table || domUtils.findParentByTagName(rng.startContainer, 'table', true);\r\n            if (table) {\r\n                var next = table.nextSibling;\r\n                if (!next) {\r\n                    next = domUtils.createElement(this.document, 'p', {\r\n                        'innerHTML': browser.ie ? domUtils.fillChar : '<br/>'\r\n                    });\r\n                    table.parentNode.insertBefore(next, table);\r\n                }\r\n                domUtils.remove(table);\r\n                rng = this.selection.getRange();\r\n                if (next.nodeType == 3) {\r\n                    rng.setStartBefore(next)\r\n                } else {\r\n                    rng.setStart(next, 0)\r\n                }\r\n                rng.setCursor(false, true)\r\n                this.fireEvent(\"tablehasdeleted\")\r\n\r\n            }\r\n\r\n        }\r\n    };\r\n    UE.commands['cellalign'] = {\r\n        queryCommandState: function () {\r\n            return getSelectedArr(this).length ? 0 : -1\r\n        },\r\n        execCommand: function (cmd, align) {\r\n            var selectedTds = getSelectedArr(this);\r\n            if (selectedTds.length) {\r\n                for (var i = 0, ci; ci = selectedTds[i++];) {\r\n                    ci.setAttribute('align', align);\r\n                }\r\n            }\r\n        }\r\n    };\r\n    UE.commands['cellvalign'] = {\r\n        queryCommandState: function () {\r\n            return getSelectedArr(this).length ? 0 : -1;\r\n        },\r\n        execCommand: function (cmd, valign) {\r\n            var selectedTds = getSelectedArr(this);\r\n            if (selectedTds.length) {\r\n                for (var i = 0, ci; ci = selectedTds[i++];) {\r\n                    ci.setAttribute('vAlign', valign);\r\n                }\r\n            }\r\n        }\r\n    };\r\n    UE.commands['insertcaption'] = {\r\n        queryCommandState: function () {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (table) {\r\n                return table.getElementsByTagName('caption').length == 0 ? 1 : -1;\r\n            }\r\n            return -1;\r\n        },\r\n        execCommand: function () {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (table) {\r\n                var caption = this.document.createElement('caption');\r\n                caption.innerHTML = browser.ie ? domUtils.fillChar : '<br/>';\r\n                table.insertBefore(caption, table.firstChild);\r\n                var range = this.selection.getRange();\r\n                range.setStart(caption, 0).setCursor();\r\n            }\r\n\r\n        }\r\n    };\r\n    UE.commands['deletecaption'] = {\r\n        queryCommandState: function () {\r\n            var rng = this.selection.getRange(),\r\n                table = domUtils.findParentByTagName(rng.startContainer, 'table');\r\n            if (table) {\r\n                return table.getElementsByTagName('caption').length == 0 ? -1 : 1;\r\n            }\r\n            return -1;\r\n        },\r\n        execCommand: function () {\r\n            var rng = this.selection.getRange(),\r\n                table = domUtils.findParentByTagName(rng.startContainer, 'table');\r\n            if (table) {\r\n                domUtils.remove(table.getElementsByTagName('caption')[0]);\r\n                var range = this.selection.getRange();\r\n                range.setStart(table.rows[0].cells[0], 0).setCursor();\r\n            }\r\n\r\n        }\r\n    };\r\n    UE.commands['inserttitle'] = {\r\n        queryCommandState: function () {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (table) {\r\n                var firstRow = table.rows[0];\r\n                return firstRow.cells[firstRow.cells.length-1].tagName.toLowerCase() != 'th' ? 0 : -1\r\n            }\r\n            return -1;\r\n        },\r\n        execCommand: function () {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (table) {\r\n                getUETable(table).insertRow(0, 'th');\r\n            }\r\n            var th = table.getElementsByTagName('th')[0];\r\n            this.selection.getRange().setStart(th, 0).setCursor(false, true);\r\n        }\r\n    };\r\n    UE.commands['deletetitle'] = {\r\n        queryCommandState: function () {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (table) {\r\n                var firstRow = table.rows[0];\r\n                return firstRow.cells[firstRow.cells.length-1].tagName.toLowerCase() == 'th' ? 0 : -1\r\n            }\r\n            return -1;\r\n        },\r\n        execCommand: function () {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (table) {\r\n                domUtils.remove(table.rows[0])\r\n            }\r\n            var td = table.getElementsByTagName('td')[0];\r\n            this.selection.getRange().setStart(td, 0).setCursor(false, true);\r\n        }\r\n    };\r\n    UE.commands['inserttitlecol'] = {\r\n        queryCommandState: function () {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (table) {\r\n                var lastRow = table.rows[table.rows.length-1];\r\n                return lastRow.getElementsByTagName('th').length ? -1 : 0;\r\n            }\r\n            return -1;\r\n        },\r\n        execCommand: function (cmd) {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (table) {\r\n                getUETable(table).insertCol(0, 'th');\r\n            }\r\n            resetTdWidth(table, this);\r\n            var th = table.getElementsByTagName('th')[0];\r\n            this.selection.getRange().setStart(th, 0).setCursor(false, true);\r\n        }\r\n    };\r\n    UE.commands['deletetitlecol'] = {\r\n        queryCommandState: function () {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (table) {\r\n                var lastRow = table.rows[table.rows.length-1];\r\n                return lastRow.getElementsByTagName('th').length ? 0 : -1;\r\n            }\r\n            return -1;\r\n        },\r\n        execCommand: function () {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (table) {\r\n                for(var i = 0; i< table.rows.length; i++ ){\r\n                    domUtils.remove(table.rows[i].children[0])\r\n                }\r\n            }\r\n            resetTdWidth(table, this);\r\n            var td = table.getElementsByTagName('td')[0];\r\n            this.selection.getRange().setStart(td, 0).setCursor(false, true);\r\n        }\r\n    };\r\n\r\n    UE.commands[\"mergeright\"] = {\r\n        queryCommandState: function (cmd) {\r\n            var tableItems = getTableItemsByRange(this),\r\n                table = tableItems.table,\r\n                cell = tableItems.cell;\r\n\r\n            if (!table || !cell) return -1;\r\n            var ut = getUETable(table);\r\n            if (ut.selectedTds.length) return -1;\r\n\r\n            var cellInfo = ut.getCellInfo(cell),\r\n                rightColIndex = cellInfo.colIndex + cellInfo.colSpan;\r\n            if (rightColIndex >= ut.colsNum) return -1; // 如果处于最右边则不能向右合并\r\n\r\n            var rightCellInfo = ut.indexTable[cellInfo.rowIndex][rightColIndex],\r\n                rightCell = table.rows[rightCellInfo.rowIndex].cells[rightCellInfo.cellIndex];\r\n            if (!rightCell || cell.tagName != rightCell.tagName) return -1; // TH和TD不能相互合并\r\n\r\n            // 当且仅当两个Cell的开始列号和结束列号一致时能进行合并\r\n            return (rightCellInfo.rowIndex == cellInfo.rowIndex && rightCellInfo.rowSpan == cellInfo.rowSpan) ? 0 : -1;\r\n        },\r\n        execCommand: function (cmd) {\r\n            var rng = this.selection.getRange(),\r\n                bk = rng.createBookmark(true);\r\n            var cell = getTableItemsByRange(this).cell,\r\n                ut = getUETable(cell);\r\n            ut.mergeRight(cell);\r\n            rng.moveToBookmark(bk).select();\r\n        }\r\n    };\r\n    UE.commands[\"mergedown\"] = {\r\n        queryCommandState: function (cmd) {\r\n            var tableItems = getTableItemsByRange(this),\r\n                table = tableItems.table,\r\n                cell = tableItems.cell;\r\n\r\n            if (!table || !cell) return -1;\r\n            var ut = getUETable(table);\r\n            if (ut.selectedTds.length)return -1;\r\n\r\n            var cellInfo = ut.getCellInfo(cell),\r\n                downRowIndex = cellInfo.rowIndex + cellInfo.rowSpan;\r\n            if (downRowIndex >= ut.rowsNum) return -1; // 如果处于最下边则不能向下合并\r\n\r\n            var downCellInfo = ut.indexTable[downRowIndex][cellInfo.colIndex],\r\n                downCell = table.rows[downCellInfo.rowIndex].cells[downCellInfo.cellIndex];\r\n            if (!downCell || cell.tagName != downCell.tagName) return -1; // TH和TD不能相互合并\r\n\r\n            // 当且仅当两个Cell的开始列号和结束列号一致时能进行合并\r\n            return (downCellInfo.colIndex == cellInfo.colIndex && downCellInfo.colSpan == cellInfo.colSpan) ? 0 : -1;\r\n        },\r\n        execCommand: function () {\r\n            var rng = this.selection.getRange(),\r\n                bk = rng.createBookmark(true);\r\n            var cell = getTableItemsByRange(this).cell,\r\n                ut = getUETable(cell);\r\n            ut.mergeDown(cell);\r\n            rng.moveToBookmark(bk).select();\r\n        }\r\n    };\r\n    UE.commands[\"mergecells\"] = {\r\n        queryCommandState: function () {\r\n            return getUETableBySelected(this) ? 0 : -1;\r\n        },\r\n        execCommand: function () {\r\n            var ut = getUETableBySelected(this);\r\n            if (ut && ut.selectedTds.length) {\r\n                var cell = ut.selectedTds[0];\r\n                ut.mergeRange();\r\n                var rng = this.selection.getRange();\r\n                if (domUtils.isEmptyBlock(cell)) {\r\n                    rng.setStart(cell, 0).collapse(true)\r\n                } else {\r\n                    rng.selectNodeContents(cell)\r\n                }\r\n                rng.select();\r\n            }\r\n\r\n\r\n        }\r\n    };\r\n    UE.commands[\"insertrow\"] = {\r\n        queryCommandState: function () {\r\n            var tableItems = getTableItemsByRange(this),\r\n                cell = tableItems.cell;\r\n            return cell && (cell.tagName == \"TD\" || (cell.tagName == 'TH' && tableItems.tr !== tableItems.table.rows[0])) &&\r\n                getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1;\r\n        },\r\n        execCommand: function () {\r\n            var rng = this.selection.getRange(),\r\n                bk = rng.createBookmark(true);\r\n            var tableItems = getTableItemsByRange(this),\r\n                cell = tableItems.cell,\r\n                table = tableItems.table,\r\n                ut = getUETable(table),\r\n                cellInfo = ut.getCellInfo(cell);\r\n            //ut.insertRow(!ut.selectedTds.length ? cellInfo.rowIndex:ut.cellsRange.beginRowIndex,'');\r\n            if (!ut.selectedTds.length) {\r\n                ut.insertRow(cellInfo.rowIndex, cell);\r\n            } else {\r\n                var range = ut.cellsRange;\r\n                for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) {\r\n                    ut.insertRow(range.beginRowIndex, cell);\r\n                }\r\n            }\r\n            rng.moveToBookmark(bk).select();\r\n            if (table.getAttribute(\"interlaced\") === \"enabled\")this.fireEvent(\"interlacetable\", table);\r\n        }\r\n    };\r\n    //后插入行\r\n    UE.commands[\"insertrownext\"] = {\r\n        queryCommandState: function () {\r\n            var tableItems = getTableItemsByRange(this),\r\n                cell = tableItems.cell;\r\n            return cell && (cell.tagName == \"TD\") && getUETable(tableItems.table).rowsNum < this.options.maxRowNum ? 0 : -1;\r\n        },\r\n        execCommand: function () {\r\n            var rng = this.selection.getRange(),\r\n                bk = rng.createBookmark(true);\r\n            var tableItems = getTableItemsByRange(this),\r\n                cell = tableItems.cell,\r\n                table = tableItems.table,\r\n                ut = getUETable(table),\r\n                cellInfo = ut.getCellInfo(cell);\r\n            //ut.insertRow(!ut.selectedTds.length? cellInfo.rowIndex + cellInfo.rowSpan : ut.cellsRange.endRowIndex + 1,'');\r\n            if (!ut.selectedTds.length) {\r\n                ut.insertRow(cellInfo.rowIndex + cellInfo.rowSpan, cell);\r\n            } else {\r\n                var range = ut.cellsRange;\r\n                for (var i = 0, len = range.endRowIndex - range.beginRowIndex + 1; i < len; i++) {\r\n                    ut.insertRow(range.endRowIndex + 1, cell);\r\n                }\r\n            }\r\n            rng.moveToBookmark(bk).select();\r\n            if (table.getAttribute(\"interlaced\") === \"enabled\")this.fireEvent(\"interlacetable\", table);\r\n        }\r\n    };\r\n    UE.commands[\"deleterow\"] = {\r\n        queryCommandState: function () {\r\n            var tableItems = getTableItemsByRange(this);\r\n            return tableItems.cell ? 0 : -1;\r\n        },\r\n        execCommand: function () {\r\n            var cell = getTableItemsByRange(this).cell,\r\n                ut = getUETable(cell),\r\n                cellsRange = ut.cellsRange,\r\n                cellInfo = ut.getCellInfo(cell),\r\n                preCell = ut.getVSideCell(cell),\r\n                nextCell = ut.getVSideCell(cell, true),\r\n                rng = this.selection.getRange();\r\n            if (utils.isEmptyObject(cellsRange)) {\r\n                ut.deleteRow(cellInfo.rowIndex);\r\n            } else {\r\n                for (var i = cellsRange.beginRowIndex; i < cellsRange.endRowIndex + 1; i++) {\r\n                    ut.deleteRow(cellsRange.beginRowIndex);\r\n                }\r\n            }\r\n            var table = ut.table;\r\n            if (!table.getElementsByTagName('td').length) {\r\n                var nextSibling = table.nextSibling;\r\n                domUtils.remove(table);\r\n                if (nextSibling) {\r\n                    rng.setStart(nextSibling, 0).setCursor(false, true);\r\n                }\r\n            } else {\r\n                if (cellInfo.rowSpan == 1 || cellInfo.rowSpan == cellsRange.endRowIndex - cellsRange.beginRowIndex + 1) {\r\n                    if (nextCell || preCell) rng.selectNodeContents(nextCell || preCell).setCursor(false, true);\r\n                } else {\r\n                    var newCell = ut.getCell(cellInfo.rowIndex, ut.indexTable[cellInfo.rowIndex][cellInfo.colIndex].cellIndex);\r\n                    if (newCell) rng.selectNodeContents(newCell).setCursor(false, true);\r\n                }\r\n            }\r\n            if (table.getAttribute(\"interlaced\") === \"enabled\")this.fireEvent(\"interlacetable\", table);\r\n        }\r\n    };\r\n    UE.commands[\"insertcol\"] = {\r\n        queryCommandState: function (cmd) {\r\n            var tableItems = getTableItemsByRange(this),\r\n                cell = tableItems.cell;\r\n            return cell && (cell.tagName == \"TD\" || (cell.tagName == 'TH' && cell !== tableItems.tr.cells[0])) &&\r\n                getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1;\r\n        },\r\n        execCommand: function (cmd) {\r\n            var rng = this.selection.getRange(),\r\n                bk = rng.createBookmark(true);\r\n            if (this.queryCommandState(cmd) == -1)return;\r\n            var cell = getTableItemsByRange(this).cell,\r\n                ut = getUETable(cell),\r\n                cellInfo = ut.getCellInfo(cell);\r\n\r\n            //ut.insertCol(!ut.selectedTds.length ? cellInfo.colIndex:ut.cellsRange.beginColIndex);\r\n            if (!ut.selectedTds.length) {\r\n                ut.insertCol(cellInfo.colIndex, cell);\r\n            } else {\r\n                var range = ut.cellsRange;\r\n                for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) {\r\n                    ut.insertCol(range.beginColIndex, cell);\r\n                }\r\n            }\r\n            rng.moveToBookmark(bk).select(true);\r\n        }\r\n    };\r\n    UE.commands[\"insertcolnext\"] = {\r\n        queryCommandState: function () {\r\n            var tableItems = getTableItemsByRange(this),\r\n                cell = tableItems.cell;\r\n            return cell && getUETable(tableItems.table).colsNum < this.options.maxColNum ? 0 : -1;\r\n        },\r\n        execCommand: function () {\r\n            var rng = this.selection.getRange(),\r\n                bk = rng.createBookmark(true);\r\n            var cell = getTableItemsByRange(this).cell,\r\n                ut = getUETable(cell),\r\n                cellInfo = ut.getCellInfo(cell);\r\n            //ut.insertCol(!ut.selectedTds.length ? cellInfo.colIndex + cellInfo.colSpan:ut.cellsRange.endColIndex +1);\r\n            if (!ut.selectedTds.length) {\r\n                ut.insertCol(cellInfo.colIndex + cellInfo.colSpan, cell);\r\n            } else {\r\n                var range = ut.cellsRange;\r\n                for (var i = 0, len = range.endColIndex - range.beginColIndex + 1; i < len; i++) {\r\n                    ut.insertCol(range.endColIndex + 1, cell);\r\n                }\r\n            }\r\n            rng.moveToBookmark(bk).select();\r\n        }\r\n    };\r\n\r\n    UE.commands[\"deletecol\"] = {\r\n        queryCommandState: function () {\r\n            var tableItems = getTableItemsByRange(this);\r\n            return tableItems.cell ? 0 : -1;\r\n        },\r\n        execCommand: function () {\r\n            var cell = getTableItemsByRange(this).cell,\r\n                ut = getUETable(cell),\r\n                range = ut.cellsRange,\r\n                cellInfo = ut.getCellInfo(cell),\r\n                preCell = ut.getHSideCell(cell),\r\n                nextCell = ut.getHSideCell(cell, true);\r\n            if (utils.isEmptyObject(range)) {\r\n                ut.deleteCol(cellInfo.colIndex);\r\n            } else {\r\n                for (var i = range.beginColIndex; i < range.endColIndex + 1; i++) {\r\n                    ut.deleteCol(range.beginColIndex);\r\n                }\r\n            }\r\n            var table = ut.table,\r\n                rng = this.selection.getRange();\r\n\r\n            if (!table.getElementsByTagName('td').length) {\r\n                var nextSibling = table.nextSibling;\r\n                domUtils.remove(table);\r\n                if (nextSibling) {\r\n                    rng.setStart(nextSibling, 0).setCursor(false, true);\r\n                }\r\n            } else {\r\n                if (domUtils.inDoc(cell, this.document)) {\r\n                    rng.setStart(cell, 0).setCursor(false, true);\r\n                } else {\r\n                    if (nextCell && domUtils.inDoc(nextCell, this.document)) {\r\n                        rng.selectNodeContents(nextCell).setCursor(false, true);\r\n                    } else {\r\n                        if (preCell && domUtils.inDoc(preCell, this.document)) {\r\n                            rng.selectNodeContents(preCell).setCursor(true, true);\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n        }\r\n    };\r\n    UE.commands[\"splittocells\"] = {\r\n        queryCommandState: function () {\r\n            var tableItems = getTableItemsByRange(this),\r\n                cell = tableItems.cell;\r\n            if (!cell) return -1;\r\n            var ut = getUETable(tableItems.table);\r\n            if (ut.selectedTds.length > 0) return -1;\r\n            return cell && (cell.colSpan > 1 || cell.rowSpan > 1) ? 0 : -1;\r\n        },\r\n        execCommand: function () {\r\n            var rng = this.selection.getRange(),\r\n                bk = rng.createBookmark(true);\r\n            var cell = getTableItemsByRange(this).cell,\r\n                ut = getUETable(cell);\r\n            ut.splitToCells(cell);\r\n            rng.moveToBookmark(bk).select();\r\n        }\r\n    };\r\n    UE.commands[\"splittorows\"] = {\r\n        queryCommandState: function () {\r\n            var tableItems = getTableItemsByRange(this),\r\n                cell = tableItems.cell;\r\n            if (!cell) return -1;\r\n            var ut = getUETable(tableItems.table);\r\n            if (ut.selectedTds.length > 0) return -1;\r\n            return cell && cell.rowSpan > 1 ? 0 : -1;\r\n        },\r\n        execCommand: function () {\r\n            var rng = this.selection.getRange(),\r\n                bk = rng.createBookmark(true);\r\n            var cell = getTableItemsByRange(this).cell,\r\n                ut = getUETable(cell);\r\n            ut.splitToRows(cell);\r\n            rng.moveToBookmark(bk).select();\r\n        }\r\n    };\r\n    UE.commands[\"splittocols\"] = {\r\n        queryCommandState: function () {\r\n            var tableItems = getTableItemsByRange(this),\r\n                cell = tableItems.cell;\r\n            if (!cell) return -1;\r\n            var ut = getUETable(tableItems.table);\r\n            if (ut.selectedTds.length > 0) return -1;\r\n            return cell && cell.colSpan > 1 ? 0 : -1;\r\n        },\r\n        execCommand: function () {\r\n            var rng = this.selection.getRange(),\r\n                bk = rng.createBookmark(true);\r\n            var cell = getTableItemsByRange(this).cell,\r\n                ut = getUETable(cell);\r\n            ut.splitToCols(cell);\r\n            rng.moveToBookmark(bk).select();\r\n\r\n        }\r\n    };\r\n\r\n    UE.commands[\"adaptbytext\"] =\r\n        UE.commands[\"adaptbywindow\"] = {\r\n            queryCommandState: function () {\r\n                return getTableItemsByRange(this).table ? 0 : -1\r\n            },\r\n            execCommand: function (cmd) {\r\n                var tableItems = getTableItemsByRange(this),\r\n                    table = tableItems.table;\r\n                if (table) {\r\n                    if (cmd == 'adaptbywindow') {\r\n                        resetTdWidth(table, this);\r\n                    } else {\r\n                        var cells = domUtils.getElementsByTagName(table, \"td th\");\r\n                        utils.each(cells, function (cell) {\r\n                            cell.removeAttribute(\"width\");\r\n                        });\r\n                        table.removeAttribute(\"width\");\r\n                    }\r\n                }\r\n            }\r\n        };\r\n\r\n    //平均分配各列\r\n    UE.commands['averagedistributecol'] = {\r\n        queryCommandState: function () {\r\n            var ut = getUETableBySelected(this);\r\n            if (!ut) return -1;\r\n            return ut.isFullRow() || ut.isFullCol() ? 0 : -1;\r\n        },\r\n        execCommand: function (cmd) {\r\n            var me = this,\r\n                ut = getUETableBySelected(me);\r\n\r\n            function getAverageWidth() {\r\n                var tb = ut.table,\r\n                    averageWidth, sumWidth = 0, colsNum = 0,\r\n                    tbAttr = getDefaultValue(me, tb);\r\n\r\n                if (ut.isFullRow()) {\r\n                    sumWidth = tb.offsetWidth;\r\n                    colsNum = ut.colsNum;\r\n                } else {\r\n                    var begin = ut.cellsRange.beginColIndex,\r\n                        end = ut.cellsRange.endColIndex,\r\n                        node;\r\n                    for (var i = begin; i <= end;) {\r\n                        node = ut.selectedTds[i];\r\n                        sumWidth += node.offsetWidth;\r\n                        i += node.colSpan;\r\n                        colsNum += 1;\r\n                    }\r\n                }\r\n                averageWidth = Math.ceil(sumWidth / colsNum) - tbAttr.tdBorder * 2 - tbAttr.tdPadding * 2;\r\n                return averageWidth;\r\n            }\r\n\r\n            function setAverageWidth(averageWidth) {\r\n                utils.each(domUtils.getElementsByTagName(ut.table, \"th\"), function (node) {\r\n                    node.setAttribute(\"width\", \"\");\r\n                });\r\n                var cells = ut.isFullRow() ? domUtils.getElementsByTagName(ut.table, \"td\") : ut.selectedTds;\r\n\r\n                utils.each(cells, function (node) {\r\n                    if (node.colSpan == 1) {\r\n                        node.setAttribute(\"width\", averageWidth);\r\n                    }\r\n                });\r\n            }\r\n\r\n            if (ut && ut.selectedTds.length) {\r\n                setAverageWidth(getAverageWidth());\r\n            }\r\n        }\r\n    };\r\n    //平均分配各行\r\n    UE.commands['averagedistributerow'] = {\r\n        queryCommandState: function () {\r\n            var ut = getUETableBySelected(this);\r\n            if (!ut) return -1;\r\n            if (ut.selectedTds && /th/ig.test(ut.selectedTds[0].tagName)) return -1;\r\n            return ut.isFullRow() || ut.isFullCol() ? 0 : -1;\r\n        },\r\n        execCommand: function (cmd) {\r\n            var me = this,\r\n                ut = getUETableBySelected(me);\r\n\r\n            function getAverageHeight() {\r\n                var averageHeight, rowNum, sumHeight = 0,\r\n                    tb = ut.table,\r\n                    tbAttr = getDefaultValue(me, tb),\r\n                    tdpadding = parseInt(domUtils.getComputedStyle(tb.getElementsByTagName('td')[0], \"padding-top\"));\r\n\r\n                if (ut.isFullCol()) {\r\n                    var captionArr = domUtils.getElementsByTagName(tb, \"caption\"),\r\n                        thArr = domUtils.getElementsByTagName(tb, \"th\"),\r\n                        captionHeight, thHeight;\r\n\r\n                    if (captionArr.length > 0) {\r\n                        captionHeight = captionArr[0].offsetHeight;\r\n                    }\r\n                    if (thArr.length > 0) {\r\n                        thHeight = thArr[0].offsetHeight;\r\n                    }\r\n\r\n                    sumHeight = tb.offsetHeight - (captionHeight || 0) - (thHeight || 0);\r\n                    rowNum = thArr.length == 0 ? ut.rowsNum : (ut.rowsNum - 1);\r\n                } else {\r\n                    var begin = ut.cellsRange.beginRowIndex,\r\n                        end = ut.cellsRange.endRowIndex,\r\n                        count = 0,\r\n                        trs = domUtils.getElementsByTagName(tb, \"tr\");\r\n                    for (var i = begin; i <= end; i++) {\r\n                        sumHeight += trs[i].offsetHeight;\r\n                        count += 1;\r\n                    }\r\n                    rowNum = count;\r\n                }\r\n                //ie8下是混杂模式\r\n                if (browser.ie && browser.version < 9) {\r\n                    averageHeight = Math.ceil(sumHeight / rowNum);\r\n                } else {\r\n                    averageHeight = Math.ceil(sumHeight / rowNum) - tbAttr.tdBorder * 2 - tdpadding * 2;\r\n                }\r\n                return averageHeight;\r\n            }\r\n\r\n            function setAverageHeight(averageHeight) {\r\n                var cells = ut.isFullCol() ? domUtils.getElementsByTagName(ut.table, \"td\") : ut.selectedTds;\r\n                utils.each(cells, function (node) {\r\n                    if (node.rowSpan == 1) {\r\n                        node.setAttribute(\"height\", averageHeight);\r\n                    }\r\n                });\r\n            }\r\n\r\n            if (ut && ut.selectedTds.length) {\r\n                setAverageHeight(getAverageHeight());\r\n            }\r\n        }\r\n    };\r\n\r\n    //单元格对齐方式\r\n    UE.commands['cellalignment'] = {\r\n        queryCommandState: function () {\r\n            return getTableItemsByRange(this).table ? 0 : -1\r\n        },\r\n        execCommand: function (cmd, data) {\r\n            var me = this,\r\n                ut = getUETableBySelected(me);\r\n\r\n            if (!ut) {\r\n                var start = me.selection.getStart(),\r\n                    cell = start && domUtils.findParentByTagName(start, [\"td\", \"th\", \"caption\"], true);\r\n                if (!/caption/ig.test(cell.tagName)) {\r\n                    domUtils.setAttributes(cell, data);\r\n                } else {\r\n                    cell.style.textAlign = data.align;\r\n                    cell.style.verticalAlign = data.vAlign;\r\n                }\r\n                me.selection.getRange().setCursor(true);\r\n            } else {\r\n                utils.each(ut.selectedTds, function (cell) {\r\n                    domUtils.setAttributes(cell, data);\r\n                });\r\n            }\r\n        },\r\n        /**\r\n         * 查询当前点击的单元格的对齐状态， 如果当前已经选择了多个单元格， 则会返回所有单元格经过统一协调过后的状态\r\n         * @see UE.UETable.getTableCellAlignState\r\n         */\r\n        queryCommandValue: function (cmd) {\r\n\r\n            var activeMenuCell = getTableItemsByRange( this).cell;\r\n\r\n            if( !activeMenuCell ) {\r\n                activeMenuCell = getSelectedArr(this)[0];\r\n            }\r\n\r\n            if (!activeMenuCell) {\r\n\r\n                return null;\r\n\r\n            } else {\r\n\r\n                //获取同时选中的其他单元格\r\n                var cells = UE.UETable.getUETable(activeMenuCell).selectedTds;\r\n\r\n                !cells.length && ( cells = activeMenuCell );\r\n\r\n                return UE.UETable.getTableCellAlignState(cells);\r\n\r\n            }\r\n\r\n        }\r\n    };\r\n    //表格对齐方式\r\n    UE.commands['tablealignment'] = {\r\n        queryCommandState: function () {\r\n            if (browser.ie && browser.version < 8) {\r\n                return -1;\r\n            }\r\n            return getTableItemsByRange(this).table ? 0 : -1\r\n        },\r\n        execCommand: function (cmd, value) {\r\n            var me = this,\r\n                start = me.selection.getStart(),\r\n                table = start && domUtils.findParentByTagName(start, [\"table\"], true);\r\n\r\n            if (table) {\r\n                table.setAttribute(\"align\",value);\r\n            }\r\n        }\r\n    };\r\n\r\n    //表格属性\r\n    UE.commands['edittable'] = {\r\n        queryCommandState: function () {\r\n            return getTableItemsByRange(this).table ? 0 : -1\r\n        },\r\n        execCommand: function (cmd, color) {\r\n            var rng = this.selection.getRange(),\r\n                table = domUtils.findParentByTagName(rng.startContainer, 'table');\r\n            if (table) {\r\n                var arr = domUtils.getElementsByTagName(table, \"td\").concat(\r\n                    domUtils.getElementsByTagName(table, \"th\"),\r\n                    domUtils.getElementsByTagName(table, \"caption\")\r\n                );\r\n                utils.each(arr, function (node) {\r\n                    node.style.borderColor = color;\r\n                });\r\n            }\r\n        }\r\n    };\r\n    //单元格属性\r\n    UE.commands['edittd'] = {\r\n        queryCommandState: function () {\r\n            return getTableItemsByRange(this).table ? 0 : -1\r\n        },\r\n        execCommand: function (cmd, bkColor) {\r\n            var me = this,\r\n                ut = getUETableBySelected(me);\r\n\r\n            if (!ut) {\r\n                var start = me.selection.getStart(),\r\n                    cell = start && domUtils.findParentByTagName(start, [\"td\", \"th\", \"caption\"], true);\r\n                if (cell) {\r\n                    cell.style.backgroundColor = bkColor;\r\n                }\r\n            } else {\r\n                utils.each(ut.selectedTds, function (cell) {\r\n                    cell.style.backgroundColor = bkColor;\r\n                });\r\n            }\r\n        }\r\n    };\r\n\r\n    UE.commands[\"settablebackground\"] = {\r\n        queryCommandState: function () {\r\n            return getSelectedArr(this).length > 1 ? 0 : -1;\r\n        },\r\n        execCommand: function (cmd, value) {\r\n            var cells, ut;\r\n            cells = getSelectedArr(this);\r\n            ut = getUETable(cells[0]);\r\n            ut.setBackground(cells, value);\r\n        }\r\n    };\r\n\r\n    UE.commands[\"cleartablebackground\"] = {\r\n        queryCommandState: function () {\r\n            var cells = getSelectedArr(this);\r\n            if (!cells.length)return -1;\r\n            for (var i = 0, cell; cell = cells[i++];) {\r\n                if (cell.style.backgroundColor !== \"\") return 0;\r\n            }\r\n            return -1;\r\n        },\r\n        execCommand: function () {\r\n            var cells = getSelectedArr(this),\r\n                ut = getUETable(cells[0]);\r\n            ut.removeBackground(cells);\r\n        }\r\n    };\r\n\r\n    UE.commands[\"interlacetable\"] = UE.commands[\"uninterlacetable\"] = {\r\n        queryCommandState: function (cmd) {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (!table) return -1;\r\n            var interlaced = table.getAttribute(\"interlaced\");\r\n            if (cmd == \"interlacetable\") {\r\n                //TODO 待定\r\n                //是否需要待定，如果设置，则命令只能单次执行成功，但反射具备toggle效果；否则可以覆盖前次命令，但反射将不存在toggle效果\r\n                return (interlaced === \"enabled\") ? -1 : 0;\r\n            } else {\r\n                return (!interlaced || interlaced === \"disabled\") ? -1 : 0;\r\n            }\r\n        },\r\n        execCommand: function (cmd, classList) {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (cmd == \"interlacetable\") {\r\n                table.setAttribute(\"interlaced\", \"enabled\");\r\n                this.fireEvent(\"interlacetable\", table, classList);\r\n            } else {\r\n                table.setAttribute(\"interlaced\", \"disabled\");\r\n                this.fireEvent(\"uninterlacetable\", table);\r\n            }\r\n        }\r\n    };\r\n    UE.commands[\"setbordervisible\"] = {\r\n        queryCommandState: function (cmd) {\r\n            var table = getTableItemsByRange(this).table;\r\n            if (!table) return -1;\r\n            return 0;\r\n        },\r\n        execCommand: function () {\r\n            var table = getTableItemsByRange(this).table;\r\n            utils.each(domUtils.getElementsByTagName(table,'td'),function(td){\r\n                td.style.borderWidth = '1px';\r\n                td.style.borderStyle = 'solid';\r\n            })\r\n        }\r\n    };\r\n    function resetTdWidth(table, editor) {\r\n        var tds = domUtils.getElementsByTagName(table,'td th');\r\n        utils.each(tds, function (td) {\r\n            td.removeAttribute(\"width\");\r\n        });\r\n        table.setAttribute('width', getTableWidth(editor, true, getDefaultValue(editor, table)));\r\n        var tdsWidths = [];\r\n        setTimeout(function () {\r\n            utils.each(tds, function (td) {\r\n                (td.colSpan == 1) && tdsWidths.push(td.offsetWidth)\r\n            })\r\n            utils.each(tds, function (td,i) {\r\n                (td.colSpan == 1) && td.setAttribute(\"width\", tdsWidths[i] + \"\");\r\n            })\r\n        }, 0);\r\n    }\r\n\r\n    function getTableWidth(editor, needIEHack, defaultValue) {\r\n        var body = editor.body;\r\n        return body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (editor.options.offsetWidth || 0);\r\n    }\r\n\r\n    function getSelectedArr(editor) {\r\n        var cell = getTableItemsByRange(editor).cell;\r\n        if (cell) {\r\n            var ut = getUETable(cell);\r\n            return ut.selectedTds.length ? ut.selectedTds : [cell];\r\n        } else {\r\n            return [];\r\n        }\r\n    }\r\n})();\r\n\n\n// plugins/table.action.js\n/**\r\n * Created with JetBrains PhpStorm.\r\n * User: taoqili\r\n * Date: 12-10-12\r\n * Time: 上午10:05\r\n * To change this template use File | Settings | File Templates.\r\n */\r\nUE.plugins['table'] = function () {\r\n    var me = this,\r\n        tabTimer = null,\r\n        //拖动计时器\r\n        tableDragTimer = null,\r\n        //双击计时器\r\n        tableResizeTimer = null,\r\n        //单元格最小宽度\r\n        cellMinWidth = 5,\r\n        isInResizeBuffer = false,\r\n        //单元格边框大小\r\n        cellBorderWidth = 5,\r\n        //鼠标偏移距离\r\n        offsetOfTableCell = 10,\r\n        //记录在有限时间内的点击状态， 共有3个取值， 0, 1, 2。 0代表未初始化， 1代表单击了1次，2代表2次\r\n        singleClickState = 0,\r\n        userActionStatus = null,\r\n        //双击允许的时间范围\r\n        dblclickTime = 360,\r\n        UT = UE.UETable,\r\n        getUETable = function (tdOrTable) {\r\n            return UT.getUETable(tdOrTable);\r\n        },\r\n        getUETableBySelected = function (editor) {\r\n            return UT.getUETableBySelected(editor);\r\n        },\r\n        getDefaultValue = function (editor, table) {\r\n            return UT.getDefaultValue(editor, table);\r\n        },\r\n        removeSelectedClass = function (cells) {\r\n            return UT.removeSelectedClass(cells);\r\n        };\r\n\r\n    function showError(e) {\r\n//        throw e;\r\n    }\r\n    me.ready(function(){\r\n        var me = this;\r\n        var orgGetText = me.selection.getText;\r\n        me.selection.getText = function(){\r\n            var table = getUETableBySelected(me);\r\n            if(table){\r\n                var str = '';\r\n                utils.each(table.selectedTds,function(td){\r\n                    str += td[browser.ie?'innerText':'textContent'];\r\n                })\r\n                return str;\r\n            }else{\r\n                return orgGetText.call(me.selection)\r\n            }\r\n\r\n        }\r\n    })\r\n\r\n    //处理拖动及框选相关方法\r\n    var startTd = null, //鼠标按下时的锚点td\r\n        currentTd = null, //当前鼠标经过时的td\r\n        onDrag = \"\", //指示当前拖动状态，其值可为\"\",\"h\",\"v\" ,分别表示未拖动状态，横向拖动状态，纵向拖动状态，用于鼠标移动过程中的判断\r\n        onBorder = false, //检测鼠标按下时是否处在单元格边缘位置\r\n        dragButton = null,\r\n        dragOver = false,\r\n        dragLine = null, //模拟的拖动线\r\n        dragTd = null;    //发生拖动的目标td\r\n\r\n    var mousedown = false,\r\n    //todo 判断混乱模式\r\n        needIEHack = true;\r\n\r\n    me.setOpt({\r\n        'maxColNum':20,\r\n        'maxRowNum':100,\r\n        'defaultCols':5,\r\n        'defaultRows':5,\r\n        'tdvalign':'top',\r\n        'cursorpath':me.options.UEDITOR_HOME_URL + \"themes/default/images/cursor_\",\r\n        'tableDragable':false,\r\n        'classList':[\"ue-table-interlace-color-single\",\"ue-table-interlace-color-double\"]\r\n    });\r\n    me.getUETable = getUETable;\r\n    var commands = {\r\n        'deletetable':1,\r\n        'inserttable':1,\r\n        'cellvalign':1,\r\n        'insertcaption':1,\r\n        'deletecaption':1,\r\n        'inserttitle':1,\r\n        'deletetitle':1,\r\n        \"mergeright\":1,\r\n        \"mergedown\":1,\r\n        \"mergecells\":1,\r\n        \"insertrow\":1,\r\n        \"insertrownext\":1,\r\n        \"deleterow\":1,\r\n        \"insertcol\":1,\r\n        \"insertcolnext\":1,\r\n        \"deletecol\":1,\r\n        \"splittocells\":1,\r\n        \"splittorows\":1,\r\n        \"splittocols\":1,\r\n        \"adaptbytext\":1,\r\n        \"adaptbywindow\":1,\r\n        \"adaptbycustomer\":1,\r\n        \"insertparagraph\":1,\r\n        \"insertparagraphbeforetable\":1,\r\n        \"averagedistributecol\":1,\r\n        \"averagedistributerow\":1\r\n    };\r\n    me.ready(function () {\r\n        utils.cssRule('table',\r\n            //选中的td上的样式\r\n            '.selectTdClass{background-color:#edf5fa !important}' +\r\n                'table.noBorderTable td,table.noBorderTable th,table.noBorderTable caption{border:1px dashed #ddd !important}' +\r\n                //插入的表格的默认样式\r\n                'table{margin-bottom:10px;border-collapse:collapse;display:table;}' +\r\n                'td,th{padding: 5px 10px;border: 1px solid #DDD;}' +\r\n                'caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center;}' +\r\n                'th{border-top:1px solid #BBB;background-color:#F7F7F7;}' +\r\n                'table tr.firstRow th{border-top-width:2px;}' +\r\n                '.ue-table-interlace-color-single{ background-color: #fcfcfc; } .ue-table-interlace-color-double{ background-color: #f7faff; }' +\r\n                'td p{margin:0;padding:0;}', me.document);\r\n\r\n        var tableCopyList, isFullCol, isFullRow;\r\n        //注册del/backspace事件\r\n        me.addListener('keydown', function (cmd, evt) {\r\n            var me = this;\r\n            var keyCode = evt.keyCode || evt.which;\r\n\r\n            if (keyCode == 8) {\r\n\r\n                var ut = getUETableBySelected(me);\r\n                if (ut && ut.selectedTds.length) {\r\n\r\n                    if (ut.isFullCol()) {\r\n                        me.execCommand('deletecol')\r\n                    } else if (ut.isFullRow()) {\r\n                        me.execCommand('deleterow')\r\n                    } else {\r\n                        me.fireEvent('delcells');\r\n                    }\r\n                    domUtils.preventDefault(evt);\r\n                }\r\n\r\n                var caption = domUtils.findParentByTagName(me.selection.getStart(), 'caption', true),\r\n                    range = me.selection.getRange();\r\n                if (range.collapsed && caption && isEmptyBlock(caption)) {\r\n                    me.fireEvent('saveScene');\r\n                    var table = caption.parentNode;\r\n                    domUtils.remove(caption);\r\n                    if (table) {\r\n                        range.setStart(table.rows[0].cells[0], 0).setCursor(false, true);\r\n                    }\r\n                    me.fireEvent('saveScene');\r\n                }\r\n\r\n            }\r\n\r\n            if (keyCode == 46) {\r\n\r\n                ut = getUETableBySelected(me);\r\n                if (ut) {\r\n                    me.fireEvent('saveScene');\r\n                    for (var i = 0, ci; ci = ut.selectedTds[i++];) {\r\n                        domUtils.fillNode(me.document, ci)\r\n                    }\r\n                    me.fireEvent('saveScene');\r\n                    domUtils.preventDefault(evt);\r\n\r\n                }\r\n\r\n            }\r\n            if (keyCode == 13) {\r\n\r\n                var rng = me.selection.getRange(),\r\n                    caption = domUtils.findParentByTagName(rng.startContainer, 'caption', true);\r\n                if (caption) {\r\n                    var table = domUtils.findParentByTagName(caption, 'table');\r\n                    if (!rng.collapsed) {\r\n\r\n                        rng.deleteContents();\r\n                        me.fireEvent('saveScene');\r\n                    } else {\r\n                        if (caption) {\r\n                            rng.setStart(table.rows[0].cells[0], 0).setCursor(false, true);\r\n                        }\r\n                    }\r\n                    domUtils.preventDefault(evt);\r\n                    return;\r\n                }\r\n                if (rng.collapsed) {\r\n                    var table = domUtils.findParentByTagName(rng.startContainer, 'table');\r\n                    if (table) {\r\n                        var cell = table.rows[0].cells[0],\r\n                            start = domUtils.findParentByTagName(me.selection.getStart(), ['td', 'th'], true),\r\n                            preNode = table.previousSibling;\r\n                        if (cell === start && (!preNode || preNode.nodeType == 1 && preNode.tagName == 'TABLE' ) && domUtils.isStartInblock(rng)) {\r\n                            var first = domUtils.findParent(me.selection.getStart(), function(n){return domUtils.isBlockElm(n)}, true);\r\n                            if(first && ( /t(h|d)/i.test(first.tagName) || first ===  start.firstChild )){\r\n                                me.execCommand('insertparagraphbeforetable');\r\n                                domUtils.preventDefault(evt);\r\n                            }\r\n\r\n                        }\r\n                    }\r\n                }\r\n            }\r\n\r\n            if ((evt.ctrlKey || evt.metaKey) && evt.keyCode == '67') {\r\n                tableCopyList = null;\r\n                var ut = getUETableBySelected(me);\r\n                if (ut) {\r\n                    var tds = ut.selectedTds;\r\n                    isFullCol = ut.isFullCol();\r\n                    isFullRow = ut.isFullRow();\r\n                    tableCopyList = [\r\n                        [ut.cloneCell(tds[0],null,true)]\r\n                    ];\r\n                    for (var i = 1, ci; ci = tds[i]; i++) {\r\n                        if (ci.parentNode !== tds[i - 1].parentNode) {\r\n                            tableCopyList.push([ut.cloneCell(ci,null,true)]);\r\n                        } else {\r\n                            tableCopyList[tableCopyList.length - 1].push(ut.cloneCell(ci,null,true));\r\n                        }\r\n\r\n                    }\r\n                }\r\n            }\r\n        });\r\n        me.addListener(\"tablehasdeleted\",function(){\r\n            toggleDraggableState(this, false, \"\", null);\r\n            if (dragButton)domUtils.remove(dragButton);\r\n        });\r\n\r\n        me.addListener('beforepaste', function (cmd, html) {\r\n            var me = this;\r\n            var rng = me.selection.getRange();\r\n            if (domUtils.findParentByTagName(rng.startContainer, 'caption', true)) {\r\n                var div = me.document.createElement(\"div\");\r\n                div.innerHTML = html.html;\r\n                //trace:3729\r\n                html.html = div[browser.ie9below ? 'innerText' : 'textContent'];\r\n                return;\r\n            }\r\n            var table = getUETableBySelected(me);\r\n            if (tableCopyList) {\r\n                me.fireEvent('saveScene');\r\n                var rng = me.selection.getRange();\r\n                var td = domUtils.findParentByTagName(rng.startContainer, ['td', 'th'], true), tmpNode, preNode;\r\n                if (td) {\r\n                    var ut = getUETable(td);\r\n                    if (isFullRow) {\r\n                        var rowIndex = ut.getCellInfo(td).rowIndex;\r\n                        if (td.tagName == 'TH') {\r\n                            rowIndex++;\r\n                        }\r\n                        for (var i = 0, ci; ci = tableCopyList[i++];) {\r\n                            var tr = ut.insertRow(rowIndex++, \"td\");\r\n                            for (var j = 0, cj; cj = ci[j]; j++) {\r\n                                var cell = tr.cells[j];\r\n                                if (!cell) {\r\n                                    cell = tr.insertCell(j)\r\n                                }\r\n                                cell.innerHTML = cj.innerHTML;\r\n                                cj.getAttribute('width') && cell.setAttribute('width', cj.getAttribute('width'));\r\n                                cj.getAttribute('vAlign') && cell.setAttribute('vAlign', cj.getAttribute('vAlign'));\r\n                                cj.getAttribute('align') && cell.setAttribute('align', cj.getAttribute('align'));\r\n                                cj.style.cssText && (cell.style.cssText = cj.style.cssText)\r\n                            }\r\n                            for (var j = 0, cj; cj = tr.cells[j]; j++) {\r\n                                if (!ci[j])\r\n                                    break;\r\n                                cj.innerHTML = ci[j].innerHTML;\r\n                                ci[j].getAttribute('width') && cj.setAttribute('width', ci[j].getAttribute('width'));\r\n                                ci[j].getAttribute('vAlign') && cj.setAttribute('vAlign', ci[j].getAttribute('vAlign'));\r\n                                ci[j].getAttribute('align') && cj.setAttribute('align', ci[j].getAttribute('align'));\r\n                                ci[j].style.cssText && (cj.style.cssText = ci[j].style.cssText)\r\n                            }\r\n                        }\r\n                    } else {\r\n                        if (isFullCol) {\r\n                            cellInfo = ut.getCellInfo(td);\r\n                            var maxColNum = 0;\r\n                            for (var j = 0, ci = tableCopyList[0], cj; cj = ci[j++];) {\r\n                                maxColNum += cj.colSpan || 1;\r\n                            }\r\n                            me.__hasEnterExecCommand = true;\r\n                            for (i = 0; i < maxColNum; i++) {\r\n                                me.execCommand('insertcol');\r\n                            }\r\n                            me.__hasEnterExecCommand = false;\r\n                            td = ut.table.rows[0].cells[cellInfo.cellIndex];\r\n                            if (td.tagName == 'TH') {\r\n                                td = ut.table.rows[1].cells[cellInfo.cellIndex];\r\n                            }\r\n                        }\r\n                        for (var i = 0, ci; ci = tableCopyList[i++];) {\r\n                            tmpNode = td;\r\n                            for (var j = 0, cj; cj = ci[j++];) {\r\n                                if (td) {\r\n                                    td.innerHTML = cj.innerHTML;\r\n                                    //todo 定制处理\r\n                                    cj.getAttribute('width') && td.setAttribute('width', cj.getAttribute('width'));\r\n                                    cj.getAttribute('vAlign') && td.setAttribute('vAlign', cj.getAttribute('vAlign'));\r\n                                    cj.getAttribute('align') && td.setAttribute('align', cj.getAttribute('align'));\r\n                                    cj.style.cssText && (td.style.cssText = cj.style.cssText);\r\n                                    preNode = td;\r\n                                    td = td.nextSibling;\r\n                                } else {\r\n                                    var cloneTd = cj.cloneNode(true);\r\n                                    domUtils.removeAttributes(cloneTd, ['class', 'rowSpan', 'colSpan']);\r\n\r\n                                    preNode.parentNode.appendChild(cloneTd)\r\n                                }\r\n                            }\r\n                            td = ut.getNextCell(tmpNode, true, true);\r\n                            if (!tableCopyList[i])\r\n                                break;\r\n                            if (!td) {\r\n                                var cellInfo = ut.getCellInfo(tmpNode);\r\n                                ut.table.insertRow(ut.table.rows.length);\r\n                                ut.update();\r\n                                td = ut.getVSideCell(tmpNode, true);\r\n                            }\r\n                        }\r\n                    }\r\n                    ut.update();\r\n                } else {\r\n                    table = me.document.createElement('table');\r\n                    for (var i = 0, ci; ci = tableCopyList[i++];) {\r\n                        var tr = table.insertRow(table.rows.length);\r\n                        for (var j = 0, cj; cj = ci[j++];) {\r\n                            cloneTd = UT.cloneCell(cj,null,true);\r\n                            domUtils.removeAttributes(cloneTd, ['class']);\r\n                            tr.appendChild(cloneTd)\r\n                        }\r\n                        if (j == 2 && cloneTd.rowSpan > 1) {\r\n                            cloneTd.rowSpan = 1;\r\n                        }\r\n                    }\r\n\r\n                    var defaultValue = getDefaultValue(me),\r\n                        width = me.body.offsetWidth -\r\n                            (needIEHack ? parseInt(domUtils.getComputedStyle(me.body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (me.options.offsetWidth || 0);\r\n                    me.execCommand('insertHTML', '<table  ' +\r\n                        ( isFullCol && isFullRow ? 'width=\"' + width + '\"' : '') +\r\n                        '>' + table.innerHTML.replace(/>\\s*</g, '><').replace(/\\bth\\b/gi, \"td\") + '</table>')\r\n                }\r\n                me.fireEvent('contentchange');\r\n                me.fireEvent('saveScene');\r\n                html.html = '';\r\n                return true;\r\n            } else {\r\n                var div = me.document.createElement(\"div\"), tables;\r\n                div.innerHTML = html.html;\r\n                tables = div.getElementsByTagName(\"table\");\r\n                if (domUtils.findParentByTagName(me.selection.getStart(), 'table')) {\r\n                    utils.each(tables, function (t) {\r\n                        domUtils.remove(t)\r\n                    });\r\n                    if (domUtils.findParentByTagName(me.selection.getStart(), 'caption', true)) {\r\n                        div.innerHTML = div[browser.ie ? 'innerText' : 'textContent'];\r\n                    }\r\n                } else {\r\n                    utils.each(tables, function (table) {\r\n                        removeStyleSize(table, true);\r\n                        domUtils.removeAttributes(table, ['style', 'border']);\r\n                        utils.each(domUtils.getElementsByTagName(table, \"td\"), function (td) {\r\n                            if (isEmptyBlock(td)) {\r\n                                domUtils.fillNode(me.document, td);\r\n                            }\r\n                            removeStyleSize(td, true);\r\n//                            domUtils.removeAttributes(td, ['style'])\r\n                        });\r\n                    });\r\n                }\r\n                html.html = div.innerHTML;\r\n            }\r\n        });\r\n\r\n        me.addListener('afterpaste', function () {\r\n            utils.each(domUtils.getElementsByTagName(me.body, \"table\"), function (table) {\r\n                if (table.offsetWidth > me.body.offsetWidth) {\r\n                    var defaultValue = getDefaultValue(me, table);\r\n                    table.style.width = me.body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(me.body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (me.options.offsetWidth || 0) + 'px'\r\n                }\r\n            })\r\n        });\r\n        me.addListener('blur', function () {\r\n            tableCopyList = null;\r\n        });\r\n        var timer;\r\n        me.addListener('keydown', function () {\r\n            clearTimeout(timer);\r\n            timer = setTimeout(function () {\r\n                var rng = me.selection.getRange(),\r\n                    cell = domUtils.findParentByTagName(rng.startContainer, ['th', 'td'], true);\r\n                if (cell) {\r\n                    var table = cell.parentNode.parentNode.parentNode;\r\n                    if (table.offsetWidth > table.getAttribute(\"width\")) {\r\n                        cell.style.wordBreak = \"break-all\";\r\n                    }\r\n                }\r\n\r\n            }, 100);\r\n        });\r\n        me.addListener(\"selectionchange\", function () {\r\n            toggleDraggableState(me, false, \"\", null);\r\n        });\r\n\r\n\r\n        //内容变化时触发索引更新\r\n        //todo 可否考虑标记检测，如果不涉及表格的变化就不进行索引重建和更新\r\n        me.addListener(\"contentchange\", function () {\r\n            var me = this;\r\n            //尽可能排除一些不需要更新的状况\r\n            hideDragLine(me);\r\n            if (getUETableBySelected(me))return;\r\n            var rng = me.selection.getRange();\r\n            var start = rng.startContainer;\r\n            start = domUtils.findParentByTagName(start, ['td', 'th'], true);\r\n            utils.each(domUtils.getElementsByTagName(me.document, 'table'), function (table) {\r\n                if (me.fireEvent(\"excludetable\", table) === true) return;\r\n                table.ueTable = new UT(table);\r\n                //trace:3742\r\n//                utils.each(domUtils.getElementsByTagName(me.document, 'td'), function (td) {\r\n//\r\n//                    if (domUtils.isEmptyBlock(td) && td !== start) {\r\n//                        domUtils.fillNode(me.document, td);\r\n//                        if (browser.ie && browser.version == 6) {\r\n//                            td.innerHTML = '&nbsp;'\r\n//                        }\r\n//                    }\r\n//                });\r\n//                utils.each(domUtils.getElementsByTagName(me.document, 'th'), function (th) {\r\n//                    if (domUtils.isEmptyBlock(th) && th !== start) {\r\n//                        domUtils.fillNode(me.document, th);\r\n//                        if (browser.ie && browser.version == 6) {\r\n//                            th.innerHTML = '&nbsp;'\r\n//                        }\r\n//                    }\r\n//                });\r\n                table.onmouseover = function () {\r\n                    me.fireEvent('tablemouseover', table);\r\n                };\r\n                table.onmousemove = function () {\r\n                    me.fireEvent('tablemousemove', table);\r\n                    me.options.tableDragable && toggleDragButton(true, this, me);\r\n                    utils.defer(function(){\r\n                        me.fireEvent('contentchange',50)\r\n                    },true)\r\n                };\r\n                table.onmouseout = function () {\r\n                    me.fireEvent('tablemouseout', table);\r\n                    toggleDraggableState(me, false, \"\", null);\r\n                    hideDragLine(me);\r\n                };\r\n                table.onclick = function (evt) {\r\n                    evt = me.window.event || evt;\r\n                    var target = getParentTdOrTh(evt.target || evt.srcElement);\r\n                    if (!target)return;\r\n                    var ut = getUETable(target),\r\n                        table = ut.table,\r\n                        cellInfo = ut.getCellInfo(target),\r\n                        cellsRange,\r\n                        rng = me.selection.getRange();\r\n//                    if (\"topLeft\" == inPosition(table, mouseCoords(evt))) {\r\n//                        cellsRange = ut.getCellsRange(ut.table.rows[0].cells[0], ut.getLastCell());\r\n//                        ut.setSelected(cellsRange);\r\n//                        return;\r\n//                    }\r\n//                    if (\"bottomRight\" == inPosition(table, mouseCoords(evt))) {\r\n//\r\n//                        return;\r\n//                    }\r\n                    if (inTableSide(table, target, evt, true)) {\r\n                        var endTdCol = ut.getCell(ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].rowIndex, ut.indexTable[ut.rowsNum - 1][cellInfo.colIndex].cellIndex);\r\n                        if (evt.shiftKey && ut.selectedTds.length) {\r\n                            if (ut.selectedTds[0] !== endTdCol) {\r\n                                cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdCol);\r\n                                ut.setSelected(cellsRange);\r\n                            } else {\r\n                                rng && rng.selectNodeContents(endTdCol).select();\r\n                            }\r\n                        } else {\r\n                            if (target !== endTdCol) {\r\n                                cellsRange = ut.getCellsRange(target, endTdCol);\r\n                                ut.setSelected(cellsRange);\r\n                            } else {\r\n                                rng && rng.selectNodeContents(endTdCol).select();\r\n                            }\r\n                        }\r\n                        return;\r\n                    }\r\n                    if (inTableSide(table, target, evt)) {\r\n                        var endTdRow = ut.getCell(ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].rowIndex, ut.indexTable[cellInfo.rowIndex][ut.colsNum - 1].cellIndex);\r\n                        if (evt.shiftKey && ut.selectedTds.length) {\r\n                            if (ut.selectedTds[0] !== endTdRow) {\r\n                                cellsRange = ut.getCellsRange(ut.selectedTds[0], endTdRow);\r\n                                ut.setSelected(cellsRange);\r\n                            } else {\r\n                                rng && rng.selectNodeContents(endTdRow).select();\r\n                            }\r\n                        } else {\r\n                            if (target !== endTdRow) {\r\n                                cellsRange = ut.getCellsRange(target, endTdRow);\r\n                                ut.setSelected(cellsRange);\r\n                            } else {\r\n                                rng && rng.selectNodeContents(endTdRow).select();\r\n                            }\r\n                        }\r\n                    }\r\n                };\r\n            });\r\n\r\n            switchBorderColor(me, true);\r\n        });\r\n\r\n        domUtils.on(me.document, \"mousemove\", mouseMoveEvent);\r\n\r\n        domUtils.on(me.document, \"mouseout\", function (evt) {\r\n            var target = evt.target || evt.srcElement;\r\n            if (target.tagName == \"TABLE\") {\r\n                toggleDraggableState(me, false, \"\", null);\r\n            }\r\n        });\r\n        /**\r\n         * 表格隔行变色\r\n         */\r\n        me.addListener(\"interlacetable\",function(type,table,classList){\r\n            if(!table) return;\r\n            var me = this,\r\n                rows = table.rows,\r\n                len = rows.length,\r\n                getClass = function(list,index,repeat){\r\n                    return list[index] ? list[index] : repeat ? list[index % list.length]: \"\";\r\n                };\r\n            for(var i = 0;i<len;i++){\r\n                rows[i].className = getClass( classList|| me.options.classList,i,true);\r\n            }\r\n        });\r\n        me.addListener(\"uninterlacetable\",function(type,table){\r\n            if(!table) return;\r\n            var me = this,\r\n                rows = table.rows,\r\n                classList = me.options.classList,\r\n                len = rows.length;\r\n            for(var i = 0;i<len;i++){\r\n                domUtils.removeClasses( rows[i], classList );\r\n            }\r\n        });\r\n\r\n        me.addListener(\"mousedown\", mouseDownEvent);\r\n        me.addListener(\"mouseup\", mouseUpEvent);\r\n        //拖动的时候触发mouseup\r\n        domUtils.on( me.body, 'dragstart', function( evt ){\r\n            mouseUpEvent.call( me, 'dragstart', evt );\r\n        });\r\n        me.addOutputRule(function(root){\r\n            utils.each(root.getNodesByTagName('div'),function(n){\r\n                if (n.getAttr('id') == 'ue_tableDragLine') {\r\n                    n.parentNode.removeChild(n);\r\n                }\r\n            });\r\n        });\r\n\r\n        var currentRowIndex = 0;\r\n        me.addListener(\"mousedown\", function () {\r\n            currentRowIndex = 0;\r\n        });\r\n        me.addListener('tabkeydown', function () {\r\n            var range = this.selection.getRange(),\r\n                common = range.getCommonAncestor(true, true),\r\n                table = domUtils.findParentByTagName(common, 'table');\r\n            if (table) {\r\n                if (domUtils.findParentByTagName(common, 'caption', true)) {\r\n                    var cell = domUtils.getElementsByTagName(table, 'th td');\r\n                    if (cell && cell.length) {\r\n                        range.setStart(cell[0], 0).setCursor(false, true)\r\n                    }\r\n                } else {\r\n                    var cell = domUtils.findParentByTagName(common, ['td', 'th'], true),\r\n                        ua = getUETable(cell);\r\n                    currentRowIndex = cell.rowSpan > 1 ? currentRowIndex : ua.getCellInfo(cell).rowIndex;\r\n                    var nextCell = ua.getTabNextCell(cell, currentRowIndex);\r\n                    if (nextCell) {\r\n                        if (isEmptyBlock(nextCell)) {\r\n                            range.setStart(nextCell, 0).setCursor(false, true)\r\n                        } else {\r\n                            range.selectNodeContents(nextCell).select()\r\n                        }\r\n                    } else {\r\n                        me.fireEvent('saveScene');\r\n                        me.__hasEnterExecCommand = true;\r\n                        this.execCommand('insertrownext');\r\n                        me.__hasEnterExecCommand = false;\r\n                        range = this.selection.getRange();\r\n                        range.setStart(table.rows[table.rows.length - 1].cells[0], 0).setCursor();\r\n                        me.fireEvent('saveScene');\r\n                    }\r\n                }\r\n                return true;\r\n            }\r\n\r\n        });\r\n        browser.ie && me.addListener('selectionchange', function () {\r\n            toggleDraggableState(this, false, \"\", null);\r\n        });\r\n        me.addListener(\"keydown\", function (type, evt) {\r\n            var me = this;\r\n            //处理在表格的最后一个输入tab产生新的表格\r\n            var keyCode = evt.keyCode || evt.which;\r\n            if (keyCode == 8 || keyCode == 46) {\r\n                return;\r\n            }\r\n            var notCtrlKey = !evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey;\r\n            notCtrlKey && removeSelectedClass(domUtils.getElementsByTagName(me.body, \"td\"));\r\n            var ut = getUETableBySelected(me);\r\n            if (!ut) return;\r\n            notCtrlKey && ut.clearSelected();\r\n        });\r\n\r\n        me.addListener(\"beforegetcontent\", function () {\r\n            switchBorderColor(this, false);\r\n            browser.ie && utils.each(this.document.getElementsByTagName('caption'), function (ci) {\r\n                if (domUtils.isEmptyNode(ci)) {\r\n                    ci.innerHTML = '&nbsp;'\r\n                }\r\n            });\r\n        });\r\n        me.addListener(\"aftergetcontent\", function () {\r\n            switchBorderColor(this, true);\r\n        });\r\n        me.addListener(\"getAllHtml\", function () {\r\n            removeSelectedClass(me.document.getElementsByTagName(\"td\"));\r\n        });\r\n        //修正全屏状态下插入的表格宽度在非全屏状态下撑开编辑器的情况\r\n        me.addListener(\"fullscreenchanged\", function (type, fullscreen) {\r\n            if (!fullscreen) {\r\n                var ratio = this.body.offsetWidth / document.body.offsetWidth,\r\n                    tables = domUtils.getElementsByTagName(this.body, \"table\");\r\n                utils.each(tables, function (table) {\r\n                    if (table.offsetWidth < me.body.offsetWidth) return false;\r\n                    var tds = domUtils.getElementsByTagName(table, \"td\"),\r\n                        backWidths = [];\r\n                    utils.each(tds, function (td) {\r\n                        backWidths.push(td.offsetWidth);\r\n                    });\r\n                    for (var i = 0, td; td = tds[i]; i++) {\r\n                        td.setAttribute(\"width\", Math.floor(backWidths[i] * ratio));\r\n                    }\r\n                    table.setAttribute(\"width\", Math.floor(getTableWidth(me, needIEHack, getDefaultValue(me))))\r\n                });\r\n            }\r\n        });\r\n\r\n        //重写execCommand命令，用于处理框选时的处理\r\n        var oldExecCommand = me.execCommand;\r\n        me.execCommand = function (cmd, datatat) {\r\n\r\n            var me = this,\r\n                args = arguments;\r\n\r\n            cmd = cmd.toLowerCase();\r\n            var ut = getUETableBySelected(me), tds,\r\n                range = new dom.Range(me.document),\r\n                cmdFun = me.commands[cmd] || UE.commands[cmd],\r\n                result;\r\n            if (!cmdFun) return;\r\n            if (ut && !commands[cmd] && !cmdFun.notNeedUndo && !me.__hasEnterExecCommand) {\r\n                me.__hasEnterExecCommand = true;\r\n                me.fireEvent(\"beforeexeccommand\", cmd);\r\n                tds = ut.selectedTds;\r\n                var lastState = -2, lastValue = -2, value, state;\r\n                for (var i = 0, td; td = tds[i]; i++) {\r\n                    if (isEmptyBlock(td)) {\r\n                        range.setStart(td, 0).setCursor(false, true)\r\n                    } else {\r\n                        range.selectNode(td).select(true);\r\n                    }\r\n                    state = me.queryCommandState(cmd);\r\n                    value = me.queryCommandValue(cmd);\r\n                    if (state != -1) {\r\n                        if (lastState !== state || lastValue !== value) {\r\n                            me._ignoreContentChange = true;\r\n                            result = oldExecCommand.apply(me, arguments);\r\n                            me._ignoreContentChange = false;\r\n\r\n                        }\r\n                        lastState = me.queryCommandState(cmd);\r\n                        lastValue = me.queryCommandValue(cmd);\r\n                        if (domUtils.isEmptyBlock(td)) {\r\n                            domUtils.fillNode(me.document, td)\r\n                        }\r\n                    }\r\n                }\r\n                range.setStart(tds[0], 0).shrinkBoundary(true).setCursor(false, true);\r\n                me.fireEvent('contentchange');\r\n                me.fireEvent(\"afterexeccommand\", cmd);\r\n                me.__hasEnterExecCommand = false;\r\n                me._selectionChange();\r\n            } else {\r\n                result = oldExecCommand.apply(me, arguments);\r\n            }\r\n            return result;\r\n        };\r\n\r\n\r\n    });\r\n    /**\r\n     * 删除obj的宽高style，改成属性宽高\r\n     * @param obj\r\n     * @param replaceToProperty\r\n     */\r\n    function removeStyleSize(obj, replaceToProperty) {\r\n        removeStyle(obj, \"width\", true);\r\n        removeStyle(obj, \"height\", true);\r\n    }\r\n\r\n    function removeStyle(obj, styleName, replaceToProperty) {\r\n        if (obj.style[styleName]) {\r\n            replaceToProperty && obj.setAttribute(styleName, parseInt(obj.style[styleName], 10));\r\n            obj.style[styleName] = \"\";\r\n        }\r\n    }\r\n\r\n    function getParentTdOrTh(ele) {\r\n        if (ele.tagName == \"TD\" || ele.tagName == \"TH\") return ele;\r\n        var td;\r\n        if (td = domUtils.findParentByTagName(ele, \"td\", true) || domUtils.findParentByTagName(ele, \"th\", true)) return td;\r\n        return null;\r\n    }\r\n\r\n    function isEmptyBlock(node) {\r\n        var reg = new RegExp(domUtils.fillChar, 'g');\r\n        if (node[browser.ie ? 'innerText' : 'textContent'].replace(/^\\s*$/, '').replace(reg, '').length > 0) {\r\n            return 0;\r\n        }\r\n        for (var n in dtd.$isNotEmpty) {\r\n            if (node.getElementsByTagName(n).length) {\r\n                return 0;\r\n            }\r\n        }\r\n        return 1;\r\n    }\r\n\r\n\r\n    function mouseCoords(evt) {\r\n        if (evt.pageX || evt.pageY) {\r\n            return { x:evt.pageX, y:evt.pageY };\r\n        }\r\n        return {\r\n            x:evt.clientX + me.document.body.scrollLeft - me.document.body.clientLeft,\r\n            y:evt.clientY + me.document.body.scrollTop - me.document.body.clientTop\r\n        };\r\n    }\r\n\r\n    function mouseMoveEvent(evt) {\r\n\r\n        if( isEditorDisabled() ) {\r\n            return;\r\n        }\r\n\r\n        try {\r\n\r\n            //普通状态下鼠标移动\r\n            var target = getParentTdOrTh(evt.target || evt.srcElement),\r\n                pos;\r\n\r\n            //区分用户的行为是拖动还是双击\r\n            if( isInResizeBuffer  ) {\r\n\r\n                me.body.style.webkitUserSelect = 'none';\r\n\r\n                if( Math.abs( userActionStatus.x - evt.clientX ) > offsetOfTableCell || Math.abs( userActionStatus.y - evt.clientY ) > offsetOfTableCell ) {\r\n                    clearTableDragTimer();\r\n                    isInResizeBuffer = false;\r\n                    singleClickState = 0;\r\n                    //drag action\r\n                    tableBorderDrag(evt);\r\n                }\r\n            }\r\n\r\n            //修改单元格大小时的鼠标移动\r\n            if (onDrag && dragTd) {\r\n                singleClickState = 0;\r\n                me.body.style.webkitUserSelect = 'none';\r\n                me.selection.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges']();\r\n                pos = mouseCoords(evt);\r\n                toggleDraggableState(me, true, onDrag, pos, target);\r\n                if (onDrag == \"h\") {\r\n                    dragLine.style.left = getPermissionX(dragTd, evt) + \"px\";\r\n                } else if (onDrag == \"v\") {\r\n                    dragLine.style.top = getPermissionY(dragTd, evt) + \"px\";\r\n                }\r\n                return;\r\n            }\r\n            //当鼠标处于table上时，修改移动过程中的光标状态\r\n            if (target) {\r\n                //针对使用table作为容器的组件不触发拖拽效果\r\n                if (me.fireEvent('excludetable', target) === true)\r\n                    return;\r\n                pos = mouseCoords(evt);\r\n                var state = getRelation(target, pos),\r\n                    table = domUtils.findParentByTagName(target, \"table\", true);\r\n\r\n                if (inTableSide(table, target, evt, true)) {\r\n                    if (me.fireEvent(\"excludetable\", table) === true) return;\r\n                    me.body.style.cursor = \"url(\" + me.options.cursorpath + \"h.png),pointer\";\r\n                } else if (inTableSide(table, target, evt)) {\r\n                    if (me.fireEvent(\"excludetable\", table) === true) return;\r\n                    me.body.style.cursor = \"url(\" + me.options.cursorpath + \"v.png),pointer\";\r\n                } else {\r\n                    me.body.style.cursor = \"text\";\r\n                    var curCell = target;\r\n                    if (/\\d/.test(state)) {\r\n                        state = state.replace(/\\d/, '');\r\n                        target = getUETable(target).getPreviewCell(target, state == \"v\");\r\n                    }\r\n                    //位于第一行的顶部或者第一列的左边时不可拖动\r\n                    toggleDraggableState(me, target ? !!state : false, target ? state : '', pos, target);\r\n\r\n                }\r\n            } else {\r\n                toggleDragButton(false, table, me);\r\n            }\r\n\r\n        } catch (e) {\r\n            showError(e);\r\n        }\r\n    }\r\n\r\n    var dragButtonTimer;\r\n\r\n    function toggleDragButton(show, table, editor) {\r\n        if (!show) {\r\n            if (dragOver)return;\r\n            dragButtonTimer = setTimeout(function () {\r\n                !dragOver && dragButton && dragButton.parentNode && dragButton.parentNode.removeChild(dragButton);\r\n            }, 2000);\r\n        } else {\r\n            createDragButton(table, editor);\r\n        }\r\n    }\r\n\r\n    function createDragButton(table, editor) {\r\n        var pos = domUtils.getXY(table),\r\n            doc = table.ownerDocument;\r\n        if (dragButton && dragButton.parentNode)return dragButton;\r\n        dragButton = doc.createElement(\"div\");\r\n        dragButton.contentEditable = false;\r\n        dragButton.innerHTML = \"\";\r\n        dragButton.style.cssText = \"width:15px;height:15px;background-image:url(\" + editor.options.UEDITOR_HOME_URL + \"dialogs/table/dragicon.png);position: absolute;cursor:move;top:\" + (pos.y - 15) + \"px;left:\" + (pos.x) + \"px;\";\r\n        domUtils.unSelectable(dragButton);\r\n        dragButton.onmouseover = function (evt) {\r\n            dragOver = true;\r\n        };\r\n        dragButton.onmouseout = function (evt) {\r\n            dragOver = false;\r\n        };\r\n        domUtils.on(dragButton, 'click', function (type, evt) {\r\n            doClick(evt, this);\r\n        });\r\n        domUtils.on(dragButton, 'dblclick', function (type, evt) {\r\n            doDblClick(evt);\r\n        });\r\n        domUtils.on(dragButton, 'dragstart', function (type, evt) {\r\n            domUtils.preventDefault(evt);\r\n        });\r\n        var timer;\r\n\r\n        function doClick(evt, button) {\r\n            // 部分浏览器下需要清理\r\n            clearTimeout(timer);\r\n            timer = setTimeout(function () {\r\n                editor.fireEvent(\"tableClicked\", table, button);\r\n            }, 300);\r\n        }\r\n\r\n        function doDblClick(evt) {\r\n            clearTimeout(timer);\r\n            var ut = getUETable(table),\r\n                start = table.rows[0].cells[0],\r\n                end = ut.getLastCell(),\r\n                range = ut.getCellsRange(start, end);\r\n            editor.selection.getRange().setStart(start, 0).setCursor(false, true);\r\n            ut.setSelected(range);\r\n        }\r\n\r\n        doc.body.appendChild(dragButton);\r\n    }\r\n\r\n\r\n//    function inPosition(table, pos) {\r\n//        var tablePos = domUtils.getXY(table),\r\n//            width = table.offsetWidth,\r\n//            height = table.offsetHeight;\r\n//        if (pos.x - tablePos.x < 5 && pos.y - tablePos.y < 5) {\r\n//            return \"topLeft\";\r\n//        } else if (tablePos.x + width - pos.x < 5 && tablePos.y + height - pos.y < 5) {\r\n//            return \"bottomRight\";\r\n//        }\r\n//    }\r\n\r\n    function inTableSide(table, cell, evt, top) {\r\n        var pos = mouseCoords(evt),\r\n            state = getRelation(cell, pos);\r\n\r\n        if (top) {\r\n            var caption = table.getElementsByTagName(\"caption\")[0],\r\n                capHeight = caption ? caption.offsetHeight : 0;\r\n            return (state == \"v1\") && ((pos.y - domUtils.getXY(table).y - capHeight) < 8);\r\n        } else {\r\n            return (state == \"h1\") && ((pos.x - domUtils.getXY(table).x) < 8);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 获取拖动时允许的X轴坐标\r\n     * @param dragTd\r\n     * @param evt\r\n     */\r\n    function getPermissionX(dragTd, evt) {\r\n        var ut = getUETable(dragTd);\r\n        if (ut) {\r\n            var preTd = ut.getSameEndPosCells(dragTd, \"x\")[0],\r\n                nextTd = ut.getSameStartPosXCells(dragTd)[0],\r\n                mouseX = mouseCoords(evt).x,\r\n                left = (preTd ? domUtils.getXY(preTd).x : domUtils.getXY(ut.table).x) + 20 ,\r\n                right = nextTd ? domUtils.getXY(nextTd).x + nextTd.offsetWidth - 20 : (me.body.offsetWidth + 5 || parseInt(domUtils.getComputedStyle(me.body, \"width\"), 10));\r\n\r\n            left += cellMinWidth;\r\n            right -= cellMinWidth;\r\n\r\n            return mouseX < left ? left : mouseX > right ? right : mouseX;\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 获取拖动时允许的Y轴坐标\r\n     */\r\n    function getPermissionY(dragTd, evt) {\r\n        try {\r\n            var top = domUtils.getXY(dragTd).y,\r\n                mousePosY = mouseCoords(evt).y;\r\n            return mousePosY < top ? top : mousePosY;\r\n        } catch (e) {\r\n            showError(e);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 移动状态切换\r\n     */\r\n    function toggleDraggableState(editor, draggable, dir, mousePos, cell) {\r\n        try {\r\n            editor.body.style.cursor = dir == \"h\" ? \"col-resize\" : dir == \"v\" ? \"row-resize\" : \"text\";\r\n            if (browser.ie) {\r\n                if (dir && !mousedown && !getUETableBySelected(editor)) {\r\n                    getDragLine(editor, editor.document);\r\n                    showDragLineAt(dir, cell);\r\n                } else {\r\n                    hideDragLine(editor)\r\n                }\r\n            }\r\n            onBorder = draggable;\r\n        } catch (e) {\r\n            showError(e);\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 获取与UETable相关的resize line\r\n     * @param uetable UETable对象\r\n     */\r\n    function getResizeLineByUETable() {\r\n\r\n        var lineId = '_UETableResizeLine',\r\n            line = this.document.getElementById( lineId );\r\n\r\n        if( !line ) {\r\n            line = this.document.createElement(\"div\");\r\n            line.id = lineId;\r\n            line.contnetEditable = false;\r\n            line.setAttribute(\"unselectable\", \"on\");\r\n\r\n            var styles = {\r\n                width: 2*cellBorderWidth + 1 + 'px',\r\n                position: 'absolute',\r\n                'z-index': 100000,\r\n                cursor: 'col-resize',\r\n                background: 'red',\r\n                display: 'none'\r\n            };\r\n\r\n            //切换状态\r\n            line.onmouseout = function(){\r\n                this.style.display = 'none';\r\n            };\r\n\r\n            utils.extend( line.style, styles );\r\n\r\n            this.document.body.appendChild( line );\r\n\r\n        }\r\n\r\n        return line;\r\n\r\n    }\r\n\r\n    /**\r\n     * 更新resize-line\r\n     */\r\n    function updateResizeLine( cell, uetable ) {\r\n\r\n        var line = getResizeLineByUETable.call( this ),\r\n            table = uetable.table,\r\n            styles = {\r\n                top: domUtils.getXY( table ).y + 'px',\r\n                left: domUtils.getXY( cell).x + cell.offsetWidth - cellBorderWidth + 'px',\r\n                display: 'block',\r\n                height: table.offsetHeight + 'px'\r\n            };\r\n\r\n        utils.extend( line.style, styles );\r\n\r\n    }\r\n\r\n    /**\r\n     * 显示resize-line\r\n     */\r\n    function showResizeLine( cell ) {\r\n\r\n        var uetable = getUETable( cell );\r\n\r\n        updateResizeLine.call( this, cell, uetable );\r\n\r\n    }\r\n\r\n    /**\r\n     * 获取鼠标与当前单元格的相对位置\r\n     * @param ele\r\n     * @param mousePos\r\n     */\r\n    function getRelation(ele, mousePos) {\r\n        var elePos = domUtils.getXY(ele);\r\n\r\n        if( !elePos ) {\r\n            return '';\r\n        }\r\n\r\n        if (elePos.x + ele.offsetWidth - mousePos.x < cellBorderWidth) {\r\n            return \"h\";\r\n        }\r\n        if (mousePos.x - elePos.x < cellBorderWidth) {\r\n            return 'h1'\r\n        }\r\n        if (elePos.y + ele.offsetHeight - mousePos.y < cellBorderWidth) {\r\n            return \"v\";\r\n        }\r\n        if (mousePos.y - elePos.y < cellBorderWidth) {\r\n            return 'v1'\r\n        }\r\n        return '';\r\n    }\r\n\r\n    function mouseDownEvent(type, evt) {\r\n\r\n        if( isEditorDisabled() ) {\r\n            return ;\r\n        }\r\n\r\n        userActionStatus = {\r\n            x: evt.clientX,\r\n            y: evt.clientY\r\n        };\r\n\r\n        //右键菜单单独处理\r\n        if (evt.button == 2) {\r\n            var ut = getUETableBySelected(me),\r\n                flag = false;\r\n\r\n            if (ut) {\r\n                var td = getTargetTd(me, evt);\r\n                utils.each(ut.selectedTds, function (ti) {\r\n                    if (ti === td) {\r\n                        flag = true;\r\n                    }\r\n                });\r\n                if (!flag) {\r\n                    removeSelectedClass(domUtils.getElementsByTagName(me.body, \"th td\"));\r\n                    ut.clearSelected()\r\n                } else {\r\n                    td = ut.selectedTds[0];\r\n                    setTimeout(function () {\r\n                        me.selection.getRange().setStart(td, 0).setCursor(false, true);\r\n                    }, 0);\r\n\r\n                }\r\n            }\r\n        } else {\r\n            tableClickHander( evt );\r\n        }\r\n\r\n    }\r\n\r\n    //清除表格的计时器\r\n    function clearTableTimer() {\r\n        tabTimer && clearTimeout( tabTimer );\r\n        tabTimer = null;\r\n    }\r\n\r\n    //双击收缩\r\n    function tableDbclickHandler(evt) {\r\n        singleClickState = 0;\r\n        evt = evt || me.window.event;\r\n        var target = getParentTdOrTh(evt.target || evt.srcElement);\r\n        if (target) {\r\n            var h;\r\n            if (h = getRelation(target, mouseCoords(evt))) {\r\n\r\n                hideDragLine( me );\r\n\r\n                if (h == 'h1') {\r\n                    h = 'h';\r\n                    if (inTableSide(domUtils.findParentByTagName(target, \"table\"), target, evt)) {\r\n                        me.execCommand('adaptbywindow');\r\n                    } else {\r\n                        target = getUETable(target).getPreviewCell(target);\r\n                        if (target) {\r\n                            var rng = me.selection.getRange();\r\n                            rng.selectNodeContents(target).setCursor(true, true)\r\n                        }\r\n                    }\r\n                }\r\n                if (h == 'h') {\r\n                    var ut = getUETable(target),\r\n                        table = ut.table,\r\n                        cells = getCellsByMoveBorder( target, table, true );\r\n\r\n                    cells = extractArray( cells, 'left' );\r\n\r\n                    ut.width = ut.offsetWidth;\r\n\r\n                    var oldWidth = [],\r\n                        newWidth = [];\r\n\r\n                    utils.each( cells, function( cell ){\r\n\r\n                        oldWidth.push( cell.offsetWidth );\r\n\r\n                    } );\r\n\r\n                    utils.each( cells, function( cell ){\r\n\r\n                        cell.removeAttribute(\"width\");\r\n\r\n                    } );\r\n\r\n                    window.setTimeout( function(){\r\n\r\n                        //是否允许改变\r\n                        var changeable = true;\r\n\r\n                        utils.each( cells, function( cell, index ){\r\n\r\n                            var width = cell.offsetWidth;\r\n\r\n                            if( width > oldWidth[index] ) {\r\n                                changeable = false;\r\n                                return false;\r\n                            }\r\n\r\n                            newWidth.push( width );\r\n\r\n                        } );\r\n\r\n                        var change = changeable ? newWidth : oldWidth;\r\n\r\n                        utils.each( cells, function( cell, index ){\r\n\r\n                            cell.width = change[index] - getTabcellSpace();\r\n\r\n                        } );\r\n\r\n\r\n                    }, 0 );\r\n\r\n//                    minWidth -= cellMinWidth;\r\n//\r\n//                    table.removeAttribute(\"width\");\r\n//                    utils.each(cells, function (cell) {\r\n//                        cell.style.width = \"\";\r\n//                        cell.width -= minWidth;\r\n//                    });\r\n\r\n                }\r\n            }\r\n        }\r\n    }\r\n\r\n    function tableClickHander( evt ) {\r\n\r\n        removeSelectedClass(domUtils.getElementsByTagName(me.body, \"td th\"));\r\n        //trace:3113\r\n        //选中单元格，点击table外部，不会清掉table上挂的ueTable,会引起getUETableBySelected方法返回值\r\n        utils.each(me.document.getElementsByTagName('table'), function (t) {\r\n            t.ueTable = null;\r\n        });\r\n        startTd = getTargetTd(me, evt);\r\n        if( !startTd ) return;\r\n        var table = domUtils.findParentByTagName(startTd, \"table\", true);\r\n        ut = getUETable(table);\r\n        ut && ut.clearSelected();\r\n\r\n        //判断当前鼠标状态\r\n        if (!onBorder) {\r\n            me.document.body.style.webkitUserSelect = '';\r\n            mousedown = true;\r\n            me.addListener('mouseover', mouseOverEvent);\r\n        } else {\r\n            //边框上的动作处理\r\n            borderActionHandler( evt );\r\n        }\r\n\r\n\r\n    }\r\n\r\n    //处理表格边框上的动作, 这里做延时处理，避免两种动作互相影响\r\n    function borderActionHandler( evt ) {\r\n\r\n        if ( browser.ie ) {\r\n            evt = reconstruct(evt );\r\n        }\r\n\r\n        clearTableDragTimer();\r\n\r\n        //是否正在等待resize的缓冲中\r\n        isInResizeBuffer = true;\r\n\r\n        tableDragTimer = setTimeout(function(){\r\n            tableBorderDrag( evt );\r\n        }, dblclickTime);\r\n\r\n    }\r\n\r\n    function extractArray( originArr, key ) {\r\n\r\n        var result = [],\r\n            tmp = null;\r\n\r\n        for( var i = 0, len = originArr.length; i<len; i++ ) {\r\n\r\n            tmp = originArr[ i ][ key ];\r\n\r\n            if( tmp ) {\r\n                result.push( tmp );\r\n            }\r\n\r\n        }\r\n\r\n        return result;\r\n\r\n    }\r\n\r\n    function clearTableDragTimer() {\r\n        tableDragTimer && clearTimeout(tableDragTimer);\r\n        tableDragTimer = null;\r\n    }\r\n\r\n    function reconstruct( obj ) {\r\n\r\n        var attrs = ['pageX', 'pageY', 'clientX', 'clientY', 'srcElement', 'target'],\r\n            newObj = {};\r\n\r\n        if( obj ) {\r\n\r\n            for( var i = 0, key, val; key = attrs[i]; i++ ) {\r\n                val=obj[ key ];\r\n                val && (newObj[ key ] = val);\r\n            }\r\n\r\n        }\r\n\r\n        return newObj;\r\n\r\n    }\r\n\r\n    //边框拖动\r\n    function tableBorderDrag( evt ) {\r\n\r\n        isInResizeBuffer = false;\r\n\r\n        startTd = evt.target || evt.srcElement;\r\n        if( !startTd ) return;\r\n        var state = getRelation(startTd, mouseCoords(evt));\r\n        if (/\\d/.test(state)) {\r\n            state = state.replace(/\\d/, '');\r\n            startTd = getUETable(startTd).getPreviewCell(startTd, state == 'v');\r\n        }\r\n        hideDragLine(me);\r\n        getDragLine(me, me.document);\r\n        me.fireEvent('saveScene');\r\n        showDragLineAt(state, startTd);\r\n        mousedown = true;\r\n        //拖动开始\r\n        onDrag = state;\r\n        dragTd = startTd;\r\n    }\r\n\r\n    function mouseUpEvent(type, evt) {\r\n\r\n        if( isEditorDisabled() ) {\r\n            return ;\r\n        }\r\n\r\n        clearTableDragTimer();\r\n\r\n        isInResizeBuffer = false;\r\n\r\n        if( onBorder ) {\r\n            singleClickState = ++singleClickState % 3;\r\n\r\n            userActionStatus = {\r\n                x: evt.clientX,\r\n                y: evt.clientY\r\n            };\r\n\r\n            tableResizeTimer = setTimeout(function(){\r\n                singleClickState > 0 && singleClickState--;\r\n            }, dblclickTime );\r\n\r\n            if( singleClickState === 2 ) {\r\n\r\n                singleClickState = 0;\r\n                tableDbclickHandler(evt);\r\n                return;\r\n\r\n            }\r\n\r\n        }\r\n\r\n        if (evt.button == 2)return;\r\n        var me = this;\r\n        //清除表格上原生跨选问题\r\n        var range = me.selection.getRange(),\r\n            start = domUtils.findParentByTagName(range.startContainer, 'table', true),\r\n            end = domUtils.findParentByTagName(range.endContainer, 'table', true);\r\n\r\n        if (start || end) {\r\n            if (start === end) {\r\n                start = domUtils.findParentByTagName(range.startContainer, ['td', 'th', 'caption'], true);\r\n                end = domUtils.findParentByTagName(range.endContainer, ['td', 'th', 'caption'], true);\r\n                if (start !== end) {\r\n                    me.selection.clearRange()\r\n                }\r\n            } else {\r\n                me.selection.clearRange()\r\n            }\r\n        }\r\n        mousedown = false;\r\n        me.document.body.style.webkitUserSelect = '';\r\n        //拖拽状态下的mouseUP\r\n        if ( onDrag && dragTd ) {\r\n\r\n            me.selection.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges']();\r\n\r\n            singleClickState = 0;\r\n            dragLine = me.document.getElementById('ue_tableDragLine');\r\n\r\n            // trace 3973\r\n            if (dragLine) {\r\n                var dragTdPos = domUtils.getXY(dragTd),\r\n                    dragLinePos = domUtils.getXY(dragLine);\r\n\r\n                switch (onDrag) {\r\n                    case \"h\":\r\n                        changeColWidth(dragTd, dragLinePos.x - dragTdPos.x);\r\n                        break;\r\n                    case \"v\":\r\n                        changeRowHeight(dragTd, dragLinePos.y - dragTdPos.y - dragTd.offsetHeight);\r\n                        break;\r\n                    default:\r\n                }\r\n                onDrag = \"\";\r\n                dragTd = null;\r\n\r\n                hideDragLine(me);\r\n                me.fireEvent('saveScene');\r\n                return;\r\n            }\r\n        }\r\n        //正常状态下的mouseup\r\n        if (!startTd) {\r\n            var target = domUtils.findParentByTagName(evt.target || evt.srcElement, \"td\", true);\r\n            if (!target) target = domUtils.findParentByTagName(evt.target || evt.srcElement, \"th\", true);\r\n            if (target && (target.tagName == \"TD\" || target.tagName == \"TH\")) {\r\n                if (me.fireEvent(\"excludetable\", target) === true) return;\r\n                range = new dom.Range(me.document);\r\n                range.setStart(target, 0).setCursor(false, true);\r\n            }\r\n        } else {\r\n            var ut = getUETable(startTd),\r\n                cell = ut ? ut.selectedTds[0] : null;\r\n            if (cell) {\r\n                range = new dom.Range(me.document);\r\n                if (domUtils.isEmptyBlock(cell)) {\r\n                    range.setStart(cell, 0).setCursor(false, true);\r\n                } else {\r\n                    range.selectNodeContents(cell).shrinkBoundary().setCursor(false, true);\r\n                }\r\n            } else {\r\n                range = me.selection.getRange().shrinkBoundary();\r\n                if (!range.collapsed) {\r\n                    var start = domUtils.findParentByTagName(range.startContainer, ['td', 'th'], true),\r\n                        end = domUtils.findParentByTagName(range.endContainer, ['td', 'th'], true);\r\n                    //在table里边的不能清除\r\n                    if (start && !end || !start && end || start && end && start !== end) {\r\n                        range.setCursor(false, true);\r\n                    }\r\n                }\r\n            }\r\n            startTd = null;\r\n            me.removeListener('mouseover', mouseOverEvent);\r\n        }\r\n        me._selectionChange(250, evt);\r\n    }\r\n\r\n    function mouseOverEvent(type, evt) {\r\n\r\n        if( isEditorDisabled() ) {\r\n            return;\r\n        }\r\n\r\n        var me = this,\r\n            tar = evt.target || evt.srcElement;\r\n        currentTd = domUtils.findParentByTagName(tar, \"td\", true) || domUtils.findParentByTagName(tar, \"th\", true);\r\n        //需要判断两个TD是否位于同一个表格内\r\n        if (startTd && currentTd &&\r\n            ((startTd.tagName == \"TD\" && currentTd.tagName == \"TD\") || (startTd.tagName == \"TH\" && currentTd.tagName == \"TH\")) &&\r\n            domUtils.findParentByTagName(startTd, 'table') == domUtils.findParentByTagName(currentTd, 'table')) {\r\n            var ut = getUETable(currentTd);\r\n            if (startTd != currentTd) {\r\n                me.document.body.style.webkitUserSelect = 'none';\r\n                me.selection.getNative()[browser.ie9below ? 'empty' : 'removeAllRanges']();\r\n                var range = ut.getCellsRange(startTd, currentTd);\r\n                ut.setSelected(range);\r\n            } else {\r\n                me.document.body.style.webkitUserSelect = '';\r\n                ut.clearSelected();\r\n            }\r\n\r\n        }\r\n        evt.preventDefault ? evt.preventDefault() : (evt.returnValue = false);\r\n    }\r\n\r\n    function setCellHeight(cell, height, backHeight) {\r\n        var lineHight = parseInt(domUtils.getComputedStyle(cell, \"line-height\"), 10),\r\n            tmpHeight = backHeight + height;\r\n        height = tmpHeight < lineHight ? lineHight : tmpHeight;\r\n        if (cell.style.height) cell.style.height = \"\";\r\n        cell.rowSpan == 1 ? cell.setAttribute(\"height\", height) : (cell.removeAttribute && cell.removeAttribute(\"height\"));\r\n    }\r\n\r\n    function getWidth(cell) {\r\n        if (!cell)return 0;\r\n        return parseInt(domUtils.getComputedStyle(cell, \"width\"), 10);\r\n    }\r\n\r\n    function changeColWidth(cell, changeValue) {\r\n\r\n        var ut = getUETable(cell);\r\n        if (ut) {\r\n\r\n            //根据当前移动的边框获取相关的单元格\r\n            var table = ut.table,\r\n                cells = getCellsByMoveBorder( cell, table );\r\n\r\n            table.style.width = \"\";\r\n            table.removeAttribute(\"width\");\r\n\r\n            //修正改变量\r\n            changeValue = correctChangeValue( changeValue, cell, cells );\r\n\r\n            if (cell.nextSibling) {\r\n\r\n                var i=0;\r\n\r\n                utils.each( cells, function( cellGroup ){\r\n\r\n                    cellGroup.left.width = (+cellGroup.left.width)+changeValue;\r\n                    cellGroup.right && ( cellGroup.right.width = (+cellGroup.right.width)-changeValue );\r\n\r\n                } );\r\n\r\n            } else {\r\n\r\n                utils.each( cells, function( cellGroup ){\r\n                    cellGroup.left.width -= -changeValue;\r\n                } );\r\n\r\n            }\r\n        }\r\n\r\n    }\r\n\r\n    function isEditorDisabled() {\r\n        return me.body.contentEditable === \"false\";\r\n    }\r\n\r\n    function changeRowHeight(td, changeValue) {\r\n        if (Math.abs(changeValue) < 10) return;\r\n        var ut = getUETable(td);\r\n        if (ut) {\r\n            var cells = ut.getSameEndPosCells(td, \"y\"),\r\n            //备份需要连带变化的td的原始高度，否则后期无法获取正确的值\r\n                backHeight = cells[0] ? cells[0].offsetHeight : 0;\r\n            for (var i = 0, cell; cell = cells[i++];) {\r\n                setCellHeight(cell, changeValue, backHeight);\r\n            }\r\n        }\r\n\r\n    }\r\n\r\n    /**\r\n     * 获取调整单元格大小的相关单元格\r\n     * @isContainMergeCell 返回的结果中是否包含发生合并后的单元格\r\n     */\r\n    function getCellsByMoveBorder( cell, table, isContainMergeCell ) {\r\n\r\n        if( !table ) {\r\n            table = domUtils.findParentByTagName( cell, 'table' );\r\n        }\r\n\r\n        if( !table ) {\r\n            return null;\r\n        }\r\n\r\n        //获取到该单元格所在行的序列号\r\n        var index = domUtils.getNodeIndex( cell ),\r\n            temp = cell,\r\n            rows = table.rows,\r\n            colIndex = 0;\r\n\r\n        while( temp ) {\r\n            //获取到当前单元格在未发生单元格合并时的序列\r\n            if( temp.nodeType === 1 ) {\r\n                colIndex += (temp.colSpan || 1);\r\n            }\r\n            temp = temp.previousSibling;\r\n        }\r\n\r\n        temp = null;\r\n\r\n        //记录想关的单元格\r\n        var borderCells = [];\r\n\r\n        utils.each(rows, function( tabRow ){\r\n\r\n            var cells = tabRow.cells,\r\n                currIndex = 0;\r\n\r\n            utils.each( cells, function( tabCell ){\r\n\r\n                currIndex += (tabCell.colSpan || 1);\r\n\r\n                if( currIndex === colIndex ) {\r\n\r\n                    borderCells.push({\r\n                        left: tabCell,\r\n                        right: tabCell.nextSibling || null\r\n                    });\r\n\r\n                    return false;\r\n\r\n                } else if( currIndex > colIndex ) {\r\n\r\n                    if( isContainMergeCell ) {\r\n                        borderCells.push({\r\n                            left: tabCell\r\n                        });\r\n                    }\r\n\r\n                    return false;\r\n                }\r\n\r\n\r\n            } );\r\n\r\n        });\r\n\r\n        return borderCells;\r\n\r\n    }\r\n\r\n\r\n    /**\r\n     * 通过给定的单元格集合获取最小的单元格width\r\n     */\r\n    function getMinWidthByTableCells( cells ) {\r\n\r\n        var minWidth = Number.MAX_VALUE;\r\n\r\n        for( var i = 0, curCell; curCell = cells[ i ] ; i++ ) {\r\n\r\n            minWidth = Math.min( minWidth, curCell.width || getTableCellWidth( curCell ) );\r\n\r\n        }\r\n\r\n        return minWidth;\r\n\r\n    }\r\n\r\n    function correctChangeValue( changeValue, relatedCell, cells ) {\r\n\r\n        //为单元格的paading预留空间\r\n        changeValue -= getTabcellSpace();\r\n\r\n        if( changeValue < 0 ) {\r\n            return 0;\r\n        }\r\n\r\n        changeValue -= getTableCellWidth( relatedCell );\r\n\r\n        //确定方向\r\n        var direction = changeValue < 0 ? 'left':'right';\r\n\r\n        changeValue = Math.abs(changeValue);\r\n\r\n        //只关心非最后一个单元格就可以\r\n        utils.each( cells, function( cellGroup ){\r\n\r\n            var curCell = cellGroup[direction];\r\n\r\n            //为单元格保留最小空间\r\n            if( curCell ) {\r\n                changeValue = Math.min( changeValue, getTableCellWidth( curCell )-cellMinWidth );\r\n            }\r\n\r\n\r\n        } );\r\n\r\n\r\n        //修正越界\r\n        changeValue = changeValue < 0 ? 0 : changeValue;\r\n\r\n        return direction === 'left' ? -changeValue : changeValue;\r\n\r\n    }\r\n\r\n    function getTableCellWidth( cell ) {\r\n\r\n        var width = 0,\r\n            //偏移纠正量\r\n            offset = 0,\r\n            width = cell.offsetWidth - getTabcellSpace();\r\n\r\n        //最后一个节点纠正一下\r\n        if( !cell.nextSibling ) {\r\n\r\n            width -= getTableCellOffset( cell );\r\n\r\n        }\r\n\r\n        width = width < 0 ? 0 : width;\r\n\r\n        try {\r\n            cell.width = width;\r\n        } catch(e) {\r\n        }\r\n\r\n        return width;\r\n\r\n    }\r\n\r\n    /**\r\n     * 获取单元格所在表格的最末单元格的偏移量\r\n     */\r\n    function getTableCellOffset( cell ) {\r\n\r\n        tab = domUtils.findParentByTagName( cell, \"table\", false);\r\n\r\n        if( tab.offsetVal === undefined ) {\r\n\r\n            var prev = cell.previousSibling;\r\n\r\n            if( prev ) {\r\n\r\n                //最后一个单元格和前一个单元格的width diff结果 如果恰好为一个border width， 则条件成立\r\n                tab.offsetVal = cell.offsetWidth - prev.offsetWidth === UT.borderWidth ? UT.borderWidth : 0;\r\n\r\n            } else {\r\n                tab.offsetVal = 0;\r\n            }\r\n\r\n        }\r\n\r\n        return tab.offsetVal;\r\n\r\n    }\r\n\r\n    function getTabcellSpace() {\r\n\r\n        if( UT.tabcellSpace === undefined ) {\r\n\r\n            var cell = null,\r\n                tab = me.document.createElement(\"table\"),\r\n                tbody = me.document.createElement(\"tbody\"),\r\n                trow = me.document.createElement(\"tr\"),\r\n                tabcell = me.document.createElement(\"td\"),\r\n                mirror = null;\r\n\r\n            tabcell.style.cssText = 'border: 0;';\r\n            tabcell.width = 1;\r\n\r\n            trow.appendChild( tabcell );\r\n            trow.appendChild( mirror = tabcell.cloneNode( false ) );\r\n\r\n            tbody.appendChild( trow );\r\n\r\n            tab.appendChild( tbody );\r\n\r\n            tab.style.cssText = \"visibility: hidden;\";\r\n\r\n            me.body.appendChild( tab );\r\n\r\n            UT.paddingSpace = tabcell.offsetWidth - 1;\r\n\r\n            var tmpTabWidth = tab.offsetWidth;\r\n\r\n            tabcell.style.cssText = '';\r\n            mirror.style.cssText = '';\r\n\r\n            UT.borderWidth = ( tab.offsetWidth - tmpTabWidth ) / 3;\r\n\r\n            UT.tabcellSpace = UT.paddingSpace + UT.borderWidth;\r\n\r\n            me.body.removeChild( tab );\r\n\r\n        }\r\n\r\n        getTabcellSpace = function(){ return UT.tabcellSpace; };\r\n\r\n        return UT.tabcellSpace;\r\n\r\n    }\r\n\r\n    function getDragLine(editor, doc) {\r\n        if (mousedown)return;\r\n        dragLine = editor.document.createElement(\"div\");\r\n        domUtils.setAttributes(dragLine, {\r\n            id:\"ue_tableDragLine\",\r\n            unselectable:'on',\r\n            contenteditable:false,\r\n            'onresizestart':'return false',\r\n            'ondragstart':'return false',\r\n            'onselectstart':'return false',\r\n            style:\"background-color:blue;position:absolute;padding:0;margin:0;background-image:none;border:0px none;opacity:0;filter:alpha(opacity=0)\"\r\n        });\r\n        editor.body.appendChild(dragLine);\r\n    }\r\n\r\n    function hideDragLine(editor) {\r\n        if (mousedown)return;\r\n        var line;\r\n        while (line = editor.document.getElementById('ue_tableDragLine')) {\r\n            domUtils.remove(line)\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 依据state（v|h）在cell位置显示横线\r\n     * @param state\r\n     * @param cell\r\n     */\r\n    function showDragLineAt(state, cell) {\r\n        if (!cell) return;\r\n        var table = domUtils.findParentByTagName(cell, \"table\"),\r\n            caption = table.getElementsByTagName('caption'),\r\n            width = table.offsetWidth,\r\n            height = table.offsetHeight - (caption.length > 0 ? caption[0].offsetHeight : 0),\r\n            tablePos = domUtils.getXY(table),\r\n            cellPos = domUtils.getXY(cell), css;\r\n        switch (state) {\r\n            case \"h\":\r\n                css = 'height:' + height + 'px;top:' + (tablePos.y + (caption.length > 0 ? caption[0].offsetHeight : 0)) + 'px;left:' + (cellPos.x + cell.offsetWidth);\r\n                dragLine.style.cssText = css + 'px;position: absolute;display:block;background-color:blue;width:1px;border:0; color:blue;opacity:.3;filter:alpha(opacity=30)';\r\n                break;\r\n            case \"v\":\r\n                css = 'width:' + width + 'px;left:' + tablePos.x + 'px;top:' + (cellPos.y + cell.offsetHeight );\r\n                //必须加上border:0和color:blue，否则低版ie不支持背景色显示\r\n                dragLine.style.cssText = css + 'px;overflow:hidden;position: absolute;display:block;background-color:blue;height:1px;border:0;color:blue;opacity:.2;filter:alpha(opacity=20)';\r\n                break;\r\n            default:\r\n        }\r\n    }\r\n\r\n    /**\r\n     * 当表格边框颜色为白色时设置为虚线,true为添加虚线\r\n     * @param editor\r\n     * @param flag\r\n     */\r\n    function switchBorderColor(editor, flag) {\r\n        var tableArr = domUtils.getElementsByTagName(editor.body, \"table\"), color;\r\n        for (var i = 0, node; node = tableArr[i++];) {\r\n            var td = domUtils.getElementsByTagName(node, \"td\");\r\n            if (td[0]) {\r\n                if (flag) {\r\n                    color = (td[0].style.borderColor).replace(/\\s/g, \"\");\r\n                    if (/(#ffffff)|(rgb\\(255,255,255\\))/ig.test(color))\r\n                        domUtils.addClass(node, \"noBorderTable\")\r\n                } else {\r\n                    domUtils.removeClasses(node, \"noBorderTable\")\r\n                }\r\n            }\r\n\r\n        }\r\n    }\r\n\r\n    function getTableWidth(editor, needIEHack, defaultValue) {\r\n        var body = editor.body;\r\n        return body.offsetWidth - (needIEHack ? parseInt(domUtils.getComputedStyle(body, 'margin-left'), 10) * 2 : 0) - defaultValue.tableBorder * 2 - (editor.options.offsetWidth || 0);\r\n    }\r\n\r\n    /**\r\n     * 获取当前拖动的单元格\r\n     */\r\n    function getTargetTd(editor, evt) {\r\n\r\n        var target = domUtils.findParentByTagName(evt.target || evt.srcElement, [\"td\", \"th\"], true),\r\n            dir = null;\r\n\r\n        if( !target ) {\r\n            return null;\r\n        }\r\n\r\n        dir = getRelation( target, mouseCoords( evt ) );\r\n\r\n        //如果有前一个节点， 需要做一个修正， 否则可能会得到一个错误的td\r\n\r\n        if( !target ) {\r\n            return null;\r\n        }\r\n\r\n        if( dir === 'h1' && target.previousSibling ) {\r\n\r\n            var position = domUtils.getXY( target),\r\n                cellWidth = target.offsetWidth;\r\n\r\n            if( Math.abs( position.x + cellWidth - evt.clientX ) > cellWidth / 3 ) {\r\n                target = target.previousSibling;\r\n            }\r\n\r\n        } else if( dir === 'v1' && target.parentNode.previousSibling ) {\r\n\r\n            var position = domUtils.getXY( target),\r\n                cellHeight = target.offsetHeight;\r\n\r\n            if( Math.abs( position.y + cellHeight - evt.clientY ) > cellHeight / 3 ) {\r\n                target = target.parentNode.previousSibling.firstChild;\r\n            }\r\n\r\n        }\r\n\r\n\r\n        //排除了非td内部以及用于代码高亮部分的td\r\n        return target && !(editor.fireEvent(\"excludetable\", target) === true) ? target : null;\r\n    }\r\n\r\n};\r\n\n\n// plugins/table.sort.js\n/**\n * Created with JetBrains PhpStorm.\n * User: Jinqn\n * Date: 13-10-12\n * Time: 上午10:20\n * To change this template use File | Settings | File Templates.\n */\n\nUE.UETable.prototype.sortTable = function (sortByCellIndex, compareFn) {\n    var table = this.table,\n        rows = table.rows,\n        trArray = [],\n        flag = rows[0].cells[0].tagName === \"TH\",\n        lastRowIndex = 0;\n    if(this.selectedTds.length){\n        var range = this.cellsRange,\n            len = range.endRowIndex + 1;\n        for (var i = range.beginRowIndex; i < len; i++) {\n            trArray[i] = rows[i];\n        }\n        trArray.splice(0,range.beginRowIndex);\n        lastRowIndex = (range.endRowIndex +1) === this.rowsNum ? 0 : range.endRowIndex +1;\n    }else{\n        for (var i = 0,len = rows.length; i < len; i++) {\n            trArray[i] = rows[i];\n        }\n    }\n\n    var Fn = {\n        'reversecurrent': function(td1,td2){\n            return 1;\n        },\n        'orderbyasc': function(td1,td2){\n            var value1 = td1.innerText||td1.textContent,\n                value2 = td2.innerText||td2.textContent;\n            return value1.localeCompare(value2);\n        },\n        'reversebyasc': function(td1,td2){\n            var value1 = td1.innerHTML,\n                value2 = td2.innerHTML;\n            return value2.localeCompare(value1);\n        },\n        'orderbynum': function(td1,td2){\n            var value1 = td1[browser.ie ? 'innerText':'textContent'].match(/\\d+/),\n                value2 = td2[browser.ie ? 'innerText':'textContent'].match(/\\d+/);\n            if(value1) value1 = +value1[0];\n            if(value2) value2 = +value2[0];\n            return (value1||0) - (value2||0);\n        },\n        'reversebynum': function(td1,td2){\n            var value1 = td1[browser.ie ? 'innerText':'textContent'].match(/\\d+/),\n                value2 = td2[browser.ie ? 'innerText':'textContent'].match(/\\d+/);\n            if(value1) value1 = +value1[0];\n            if(value2) value2 = +value2[0];\n            return (value2||0) - (value1||0);\n        }\n    };\n\n    //对表格设置排序的标记data-sort-type\n    table.setAttribute('data-sort-type', compareFn && typeof compareFn === \"string\" && Fn[compareFn] ? compareFn:'');\n\n    //th不参与排序\n    flag && trArray.splice(0, 1);\n    trArray = utils.sort(trArray,function (tr1, tr2) {\n        var result;\n        if (compareFn && typeof compareFn === \"function\") {\n            result = compareFn.call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]);\n        } else if (compareFn && typeof compareFn === \"number\") {\n            result = 1;\n        } else if (compareFn && typeof compareFn === \"string\" && Fn[compareFn]) {\n            result = Fn[compareFn].call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]);\n        } else {\n            result = Fn['orderbyasc'].call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]);\n        }\n        return result;\n    });\n    var fragment = table.ownerDocument.createDocumentFragment();\n    for (var j = 0, len = trArray.length; j < len; j++) {\n        fragment.appendChild(trArray[j]);\n    }\n    var tbody = table.getElementsByTagName(\"tbody\")[0];\n    if(!lastRowIndex){\n        tbody.appendChild(fragment);\n    }else{\n        tbody.insertBefore(fragment,rows[lastRowIndex- range.endRowIndex + range.beginRowIndex - 1])\n    }\n};\n\nUE.plugins['tablesort'] = function () {\n    var me = this,\n        UT = UE.UETable,\n        getUETable = function (tdOrTable) {\n            return UT.getUETable(tdOrTable);\n        },\n        getTableItemsByRange = function (editor) {\n            return UT.getTableItemsByRange(editor);\n        };\n\n\n    me.ready(function () {\n        //添加表格可排序的样式\n        utils.cssRule('tablesort',\n            'table.sortEnabled tr.firstRow th,table.sortEnabled tr.firstRow td{padding-right:20px;background-repeat: no-repeat;background-position: center right;' +\n                '   background-image:url(' + me.options.themePath + me.options.theme + '/images/sortable.png);}',\n            me.document);\n\n        //做单元格合并操作时,清除可排序标识\n        me.addListener(\"afterexeccommand\", function (type, cmd) {\n            if( cmd == 'mergeright' || cmd == 'mergedown' || cmd == 'mergecells') {\n                this.execCommand('disablesort');\n            }\n        });\n    });\n\n\n\n    //表格排序\n    UE.commands['sorttable'] = {\n        queryCommandState: function () {\n            var me = this,\n                tableItems = getTableItemsByRange(me);\n            if (!tableItems.cell) return -1;\n            var table = tableItems.table,\n                cells = table.getElementsByTagName(\"td\");\n            for (var i = 0, cell; cell = cells[i++];) {\n                if (cell.rowSpan != 1 || cell.colSpan != 1) return -1;\n            }\n            return 0;\n        },\n        execCommand: function (cmd, fn) {\n            var me = this,\n                range = me.selection.getRange(),\n                bk = range.createBookmark(true),\n                tableItems = getTableItemsByRange(me),\n                cell = tableItems.cell,\n                ut = getUETable(tableItems.table),\n                cellInfo = ut.getCellInfo(cell);\n            ut.sortTable(cellInfo.cellIndex, fn);\n            range.moveToBookmark(bk);\n            try{\n                range.select();\n            }catch(e){}\n        }\n    };\n\n    //设置表格可排序,清除表格可排序\n    UE.commands[\"enablesort\"] = UE.commands[\"disablesort\"] = {\n        queryCommandState: function (cmd) {\n            var table = getTableItemsByRange(this).table;\n            if(table && cmd=='enablesort') {\n                var cells = domUtils.getElementsByTagName(table, 'th td');\n                for(var i = 0; i<cells.length; i++) {\n                    if(cells[i].getAttribute('colspan')>1 || cells[i].getAttribute('rowspan')>1) return -1;\n                }\n            }\n\n            return !table ? -1: cmd=='enablesort' ^ table.getAttribute('data-sort')!='sortEnabled' ? -1:0;\n        },\n        execCommand: function (cmd) {\n            var table = getTableItemsByRange(this).table;\n            table.setAttribute(\"data-sort\", cmd == \"enablesort\" ? \"sortEnabled\" : \"sortDisabled\");\n            cmd == \"enablesort\" ? domUtils.addClass(table,\"sortEnabled\"):domUtils.removeClasses(table,\"sortEnabled\");\n        }\n    };\n};\n\n\n// plugins/contextmenu.js\n///import core\r\n///commands 右键菜单\r\n///commandsName  ContextMenu\r\n///commandsTitle  右键菜单\r\n/**\r\n * 右键菜单\r\n * @function\r\n * @name baidu.editor.plugins.contextmenu\r\n * @author zhanyi\r\n */\r\n\r\nUE.plugins['contextmenu'] = function () {\r\n    var me = this;\r\n    me.setOpt('enableContextMenu',true);\r\n    if(me.getOpt('enableContextMenu') === false){\r\n        return;\r\n    }\r\n    var lang = me.getLang( \"contextMenu\" ),\r\n            menu,\r\n            items = me.options.contextMenu || [\r\n                {label:lang['selectall'], cmdName:'selectall'},\r\n                {\r\n                    label:lang.cleardoc,\r\n                    cmdName:'cleardoc',\r\n                    exec:function () {\r\n                        if ( confirm( lang.confirmclear ) ) {\r\n                            this.execCommand( 'cleardoc' );\r\n                        }\r\n                    }\r\n                },\r\n                '-',\r\n                {\r\n                    label:lang.unlink,\r\n                    cmdName:'unlink'\r\n                },\r\n                '-',\r\n                {\r\n                    group:lang.paragraph,\r\n                    icon:'justifyjustify',\r\n                    subMenu:[\r\n                        {\r\n                            label:lang.justifyleft,\r\n                            cmdName:'justify',\r\n                            value:'left'\r\n                        },\r\n                        {\r\n                            label:lang.justifyright,\r\n                            cmdName:'justify',\r\n                            value:'right'\r\n                        },\r\n                        {\r\n                            label:lang.justifycenter,\r\n                            cmdName:'justify',\r\n                            value:'center'\r\n                        },\r\n                        {\r\n                            label:lang.justifyjustify,\r\n                            cmdName:'justify',\r\n                            value:'justify'\r\n                        }\r\n                    ]\r\n                },\r\n                '-',\r\n                {\r\n                    group:lang.table,\r\n                    icon:'table',\r\n                    subMenu:[\r\n                        {\r\n                            label:lang.inserttable,\r\n                            cmdName:'inserttable'\r\n                        },\r\n                        {\r\n                            label:lang.deletetable,\r\n                            cmdName:'deletetable'\r\n                        },\r\n                        '-',\r\n                        {\r\n                            label:lang.deleterow,\r\n                            cmdName:'deleterow'\r\n                        },\r\n                        {\r\n                            label:lang.deletecol,\r\n                            cmdName:'deletecol'\r\n                        },\r\n                        {\r\n                            label:lang.insertcol,\r\n                            cmdName:'insertcol'\r\n                        },\r\n                        {\r\n                            label:lang.insertcolnext,\r\n                            cmdName:'insertcolnext'\r\n                        },\r\n                        {\r\n                            label:lang.insertrow,\r\n                            cmdName:'insertrow'\r\n                        },\r\n                        {\r\n                            label:lang.insertrownext,\r\n                            cmdName:'insertrownext'\r\n                        },\r\n                        '-',\r\n                        {\r\n                            label:lang.insertcaption,\r\n                            cmdName:'insertcaption'\r\n                        },\r\n                        {\r\n                            label:lang.deletecaption,\r\n                            cmdName:'deletecaption'\r\n                        },\r\n                        {\r\n                            label:lang.inserttitle,\r\n                            cmdName:'inserttitle'\r\n                        },\r\n                        {\r\n                            label:lang.deletetitle,\r\n                            cmdName:'deletetitle'\r\n                        },\r\n                        {\r\n                            label:lang.inserttitlecol,\r\n                            cmdName:'inserttitlecol'\r\n                        },\r\n                        {\r\n                            label:lang.deletetitlecol,\r\n                            cmdName:'deletetitlecol'\r\n                        },\r\n                        '-',\r\n                        {\r\n                            label:lang.mergecells,\r\n                            cmdName:'mergecells'\r\n                        },\r\n                        {\r\n                            label:lang.mergeright,\r\n                            cmdName:'mergeright'\r\n                        },\r\n                        {\r\n                            label:lang.mergedown,\r\n                            cmdName:'mergedown'\r\n                        },\r\n                        '-',\r\n                        {\r\n                            label:lang.splittorows,\r\n                            cmdName:'splittorows'\r\n                        },\r\n                        {\r\n                            label:lang.splittocols,\r\n                            cmdName:'splittocols'\r\n                        },\r\n                        {\r\n                            label:lang.splittocells,\r\n                            cmdName:'splittocells'\r\n                        },\r\n                        '-',\r\n                        {\r\n                            label:lang.averageDiseRow,\r\n                            cmdName:'averagedistributerow'\r\n                        },\r\n                        {\r\n                            label:lang.averageDisCol,\r\n                            cmdName:'averagedistributecol'\r\n                        },\r\n                        '-',\r\n                        {\r\n                            label:lang.edittd,\r\n                            cmdName:'edittd',\r\n                            exec:function () {\r\n                                if ( UE.ui['edittd'] ) {\r\n                                    new UE.ui['edittd']( this );\r\n                                }\r\n                                this.getDialog('edittd').open();\r\n                            }\r\n                        },\r\n                        {\r\n                            label:lang.edittable,\r\n                            cmdName:'edittable',\r\n                            exec:function () {\r\n                                if ( UE.ui['edittable'] ) {\r\n                                    new UE.ui['edittable']( this );\r\n                                }\r\n                                this.getDialog('edittable').open();\r\n                            }\r\n                        },\r\n                        {\r\n                            label:lang.setbordervisible,\r\n                            cmdName:'setbordervisible'\r\n                        }\r\n                    ]\r\n                },\r\n                {\r\n                    group:lang.tablesort,\r\n                    icon:'tablesort',\r\n                    subMenu:[\r\n                        {\r\n                            label:lang.enablesort,\r\n                            cmdName:'enablesort'\r\n                        },\r\n                        {\r\n                            label:lang.disablesort,\r\n                            cmdName:'disablesort'\r\n                        },\r\n                        '-',\r\n                        {\r\n                            label:lang.reversecurrent,\r\n                            cmdName:'sorttable',\r\n                            value:'reversecurrent'\r\n                        },\r\n                        {\r\n                            label:lang.orderbyasc,\r\n                            cmdName:'sorttable',\r\n                            value:'orderbyasc'\r\n                        },\r\n                        {\r\n                            label:lang.reversebyasc,\r\n                            cmdName:'sorttable',\r\n                            value:'reversebyasc'\r\n                        },\r\n                        {\r\n                            label:lang.orderbynum,\r\n                            cmdName:'sorttable',\r\n                            value:'orderbynum'\r\n                        },\r\n                        {\r\n                            label:lang.reversebynum,\r\n                            cmdName:'sorttable',\r\n                            value:'reversebynum'\r\n                        }\r\n                    ]\r\n                },\r\n                {\r\n                    group:lang.borderbk,\r\n                    icon:'borderBack',\r\n                    subMenu:[\r\n                        {\r\n                            label:lang.setcolor,\r\n                            cmdName:\"interlacetable\",\r\n                            exec:function(){\r\n                                this.execCommand(\"interlacetable\");\r\n                            }\r\n                        },\r\n                        {\r\n                            label:lang.unsetcolor,\r\n                            cmdName:\"uninterlacetable\",\r\n                            exec:function(){\r\n                                this.execCommand(\"uninterlacetable\");\r\n                            }\r\n                        },\r\n                        {\r\n                            label:lang.setbackground,\r\n                            cmdName:\"settablebackground\",\r\n                            exec:function(){\r\n                                this.execCommand(\"settablebackground\",{repeat:true,colorList:[\"#bbb\",\"#ccc\"]});\r\n                            }\r\n                        },\r\n                        {\r\n                            label:lang.unsetbackground,\r\n                            cmdName:\"cleartablebackground\",\r\n                            exec:function(){\r\n                                this.execCommand(\"cleartablebackground\");\r\n                            }\r\n                        },\r\n                        {\r\n                            label:lang.redandblue,\r\n                            cmdName:\"settablebackground\",\r\n                            exec:function(){\r\n                                this.execCommand(\"settablebackground\",{repeat:true,colorList:[\"red\",\"blue\"]});\r\n                            }\r\n                        },\r\n                        {\r\n                            label:lang.threecolorgradient,\r\n                            cmdName:\"settablebackground\",\r\n                            exec:function(){\r\n                                this.execCommand(\"settablebackground\",{repeat:true,colorList:[\"#aaa\",\"#bbb\",\"#ccc\"]});\r\n                            }\r\n                        }\r\n                    ]\r\n                },\r\n                {\r\n                    group:lang.aligntd,\r\n                    icon:'aligntd',\r\n                    subMenu:[\r\n                        {\r\n                            cmdName:'cellalignment',\r\n                            value:{align:'left',vAlign:'top'}\r\n                        },\r\n                        {\r\n                            cmdName:'cellalignment',\r\n                            value:{align:'center',vAlign:'top'}\r\n                        },\r\n                        {\r\n                            cmdName:'cellalignment',\r\n                            value:{align:'right',vAlign:'top'}\r\n                        },\r\n                        {\r\n                            cmdName:'cellalignment',\r\n                            value:{align:'left',vAlign:'middle'}\r\n                        },\r\n                        {\r\n                            cmdName:'cellalignment',\r\n                            value:{align:'center',vAlign:'middle'}\r\n                        },\r\n                        {\r\n                            cmdName:'cellalignment',\r\n                            value:{align:'right',vAlign:'middle'}\r\n                        },\r\n                        {\r\n                            cmdName:'cellalignment',\r\n                            value:{align:'left',vAlign:'bottom'}\r\n                        },\r\n                        {\r\n                            cmdName:'cellalignment',\r\n                            value:{align:'center',vAlign:'bottom'}\r\n                        },\r\n                        {\r\n                            cmdName:'cellalignment',\r\n                            value:{align:'right',vAlign:'bottom'}\r\n                        }\r\n                    ]\r\n                },\r\n                {\r\n                    group:lang.aligntable,\r\n                    icon:'aligntable',\r\n                    subMenu:[\r\n                        {\r\n                            cmdName:'tablealignment',\r\n                            className: 'left',\r\n                            label:lang.tableleft,\r\n                            value:\"left\"\r\n                        },\r\n                        {\r\n                            cmdName:'tablealignment',\r\n                            className: 'center',\r\n                            label:lang.tablecenter,\r\n                            value:\"center\"\r\n                        },\r\n                        {\r\n                            cmdName:'tablealignment',\r\n                            className: 'right',\r\n                            label:lang.tableright,\r\n                            value:\"right\"\r\n                        }\r\n                    ]\r\n                },\r\n                '-',\r\n                {\r\n                    label:lang.insertparagraphbefore,\r\n                    cmdName:'insertparagraph',\r\n                    value:true\r\n                },\r\n                {\r\n                    label:lang.insertparagraphafter,\r\n                    cmdName:'insertparagraph'\r\n                },\r\n                {\r\n                    label:lang['copy'],\r\n                    cmdName:'copy'\r\n                },\r\n                {\r\n                    label:lang['paste'],\r\n                    cmdName:'paste'\r\n                }\r\n            ];\r\n    if ( !items.length ) {\r\n        return;\r\n    }\r\n    var uiUtils = UE.ui.uiUtils;\r\n\r\n    me.addListener( 'contextmenu', function ( type, evt ) {\r\n\r\n        var offset = uiUtils.getViewportOffsetByEvent( evt );\r\n        me.fireEvent( 'beforeselectionchange' );\r\n        if ( menu ) {\r\n            menu.destroy();\r\n        }\r\n        for ( var i = 0, ti, contextItems = []; ti = items[i]; i++ ) {\r\n            var last;\r\n            (function ( item ) {\r\n                if ( item == '-' ) {\r\n                    if ( (last = contextItems[contextItems.length - 1 ] ) && last !== '-' ) {\r\n                        contextItems.push( '-' );\r\n                    }\r\n                } else if ( item.hasOwnProperty( \"group\" ) ) {\r\n                    for ( var j = 0, cj, subMenu = []; cj = item.subMenu[j]; j++ ) {\r\n                        (function ( subItem ) {\r\n                            if ( subItem == '-' ) {\r\n                                if ( (last = subMenu[subMenu.length - 1 ] ) && last !== '-' ) {\r\n                                    subMenu.push( '-' );\r\n                                }else{\r\n                                    subMenu.splice(subMenu.length-1);\r\n                                }\r\n                            } else {\r\n                                if ( (me.commands[subItem.cmdName] || UE.commands[subItem.cmdName] || subItem.query) &&\r\n                                        (subItem.query ? subItem.query() : me.queryCommandState( subItem.cmdName )) > -1 ) {\r\n                                    subMenu.push( {\r\n                                        'label':subItem.label || me.getLang( \"contextMenu.\" + subItem.cmdName + (subItem.value || '') )||\"\",\r\n                                        'className':'edui-for-' +subItem.cmdName + ( subItem.className ? ( ' edui-for-' + subItem.cmdName + '-' + subItem.className ) : '' ),\r\n                                        onclick:subItem.exec ? function () {\r\n                                                subItem.exec.call( me );\r\n                                        } : function () {\r\n                                            me.execCommand( subItem.cmdName, subItem.value );\r\n                                        }\r\n                                    } );\r\n                                }\r\n                            }\r\n                        })( cj );\r\n                    }\r\n                    if ( subMenu.length ) {\r\n                        function getLabel(){\r\n                            switch (item.icon){\r\n                                case \"table\":\r\n                                    return me.getLang( \"contextMenu.table\" );\r\n                                case \"justifyjustify\":\r\n                                    return me.getLang( \"contextMenu.paragraph\" );\r\n                                case \"aligntd\":\r\n                                    return me.getLang(\"contextMenu.aligntd\");\r\n                                case \"aligntable\":\r\n                                    return me.getLang(\"contextMenu.aligntable\");\r\n                                case \"tablesort\":\r\n                                    return lang.tablesort;\r\n                                case \"borderBack\":\r\n                                    return lang.borderbk;\r\n                                default :\r\n                                    return '';\r\n                            }\r\n                        }\r\n                        contextItems.push( {\r\n                            //todo 修正成自动获取方式\r\n                            'label':getLabel(),\r\n                            className:'edui-for-' + item.icon,\r\n                            'subMenu':{\r\n                                items:subMenu,\r\n                                editor:me\r\n                            }\r\n                        } );\r\n                    }\r\n\r\n                } else {\r\n                    //有可能commmand没有加载右键不能出来，或者没有command也想能展示出来添加query方法\r\n                    if ( (me.commands[item.cmdName] || UE.commands[item.cmdName] || item.query) &&\r\n                            (item.query ? item.query.call(me) : me.queryCommandState( item.cmdName )) > -1 ) {\r\n\r\n                        contextItems.push( {\r\n                            'label':item.label || me.getLang( \"contextMenu.\" + item.cmdName ),\r\n                            className:'edui-for-' + (item.icon ? item.icon : item.cmdName + (item.value || '')),\r\n                            onclick:item.exec ? function () {\r\n                                item.exec.call( me );\r\n                            } : function () {\r\n                                me.execCommand( item.cmdName, item.value );\r\n                            }\r\n                        } );\r\n                    }\r\n\r\n                }\r\n\r\n            })( ti );\r\n        }\r\n        if ( contextItems[contextItems.length - 1] == '-' ) {\r\n            contextItems.pop();\r\n        }\r\n\r\n        menu = new UE.ui.Menu( {\r\n            items:contextItems,\r\n            className:\"edui-contextmenu\",\r\n            editor:me\r\n        } );\r\n        menu.render();\r\n        menu.showAt( offset );\r\n\r\n        me.fireEvent(\"aftershowcontextmenu\",menu);\r\n\r\n        domUtils.preventDefault( evt );\r\n        if ( browser.ie ) {\r\n            var ieRange;\r\n            try {\r\n                ieRange = me.selection.getNative().createRange();\r\n            } catch ( e ) {\r\n                return;\r\n            }\r\n            if ( ieRange.item ) {\r\n                var range = new dom.Range( me.document );\r\n                range.selectNode( ieRange.item( 0 ) ).select( true, true );\r\n            }\r\n        }\r\n    });\r\n\r\n    // 添加复制的flash按钮\r\n    me.addListener('aftershowcontextmenu', function(type, menu) {\r\n        if (me.zeroclipboard) {\r\n            var items = menu.items;\r\n            for (var key in items) {\r\n                if (items[key].className == 'edui-for-copy') {\r\n                    me.zeroclipboard.clip(items[key].getDom());\r\n                }\r\n            }\r\n        }\r\n    });\r\n\r\n};\r\n\n\n// plugins/shortcutmenu.js\n///import core\n///commands       弹出菜单\n// commandsName  popupmenu\n///commandsTitle  弹出菜单\n/**\n * 弹出菜单\n * @function\n * @name baidu.editor.plugins.popupmenu\n * @author xuheng\n */\n\nUE.plugins['shortcutmenu'] = function () {\n    var me = this,\n        menu,\n        items = me.options.shortcutMenu || [];\n\n    if (!items.length) {\n        return;\n    }\n\n    me.addListener ('contextmenu mouseup' , function (type , e) {\n        var me = this,\n            customEvt = {\n                type : type ,\n                target : e.target || e.srcElement ,\n                screenX : e.screenX ,\n                screenY : e.screenY ,\n                clientX : e.clientX ,\n                clientY : e.clientY\n            };\n\n        setTimeout (function () {\n            var rng = me.selection.getRange ();\n            if (rng.collapsed === false || type == \"contextmenu\") {\n\n                if (!menu) {\n                    menu = new baidu.editor.ui.ShortCutMenu ({\n                        editor : me ,\n                        items : items ,\n                        theme : me.options.theme ,\n                        className : 'edui-shortcutmenu'\n                    });\n\n                    menu.render ();\n                    me.fireEvent (\"afterrendershortcutmenu\" , menu);\n                }\n\n                menu.show (customEvt , !!UE.plugins['contextmenu']);\n            }\n        });\n\n        if (type == 'contextmenu') {\n            domUtils.preventDefault (e);\n            if (browser.ie9below) {\n                var ieRange;\n                try {\n                    ieRange = me.selection.getNative().createRange();\n                } catch (e) {\n                    return;\n                }\n                if (ieRange.item) {\n                    var range = new dom.Range (me.document);\n                    range.selectNode (ieRange.item (0)).select (true , true);\n\n                }\n            }\n        }\n    });\n\n    me.addListener ('keydown' , function (type) {\n        if (type == \"keydown\") {\n            menu && !menu.isHidden && menu.hide ();\n        }\n\n    });\n\n};\n\n\n\n\n// plugins/basestyle.js\n/**\r\n * B、I、sub、super命令支持\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\nUE.plugins['basestyle'] = function(){\r\n\r\n    /**\r\n     * 字体加粗\r\n     * @command bold\r\n     * @param { String } cmd 命令字符串\r\n     * @remind 对已加粗的文本内容执行该命令， 将取消加粗\r\n     * @method execCommand\r\n     * @example\r\n     * ```javascript\r\n     * //editor是编辑器实例\r\n     * //对当前选中的文本内容执行加粗操作\r\n     * //第一次执行， 文本内容加粗\r\n     * editor.execCommand( 'bold' );\r\n     *\r\n     * //第二次执行， 文本内容取消加粗\r\n     * editor.execCommand( 'bold' );\r\n     * ```\r\n     */\r\n\r\n\r\n    /**\r\n     * 字体倾斜\r\n     * @command italic\r\n     * @method execCommand\r\n     * @param { String } cmd 命令字符串\r\n     * @remind 对已倾斜的文本内容执行该命令， 将取消倾斜\r\n     * @example\r\n     * ```javascript\r\n     * //editor是编辑器实例\r\n     * //对当前选中的文本内容执行斜体操作\r\n     * //第一次操作， 文本内容将变成斜体\r\n     * editor.execCommand( 'italic' );\r\n     *\r\n     * //再次对同一文本内容执行， 则文本内容将恢复正常\r\n     * editor.execCommand( 'italic' );\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 下标文本，与“superscript”命令互斥\r\n     * @command subscript\r\n     * @method execCommand\r\n     * @remind  把选中的文本内容切换成下标文本， 如果当前选中的文本已经是下标， 则该操作会把文本内容还原成正常文本\r\n     * @param { String } cmd 命令字符串\r\n     * @example\r\n     * ```javascript\r\n     * //editor是编辑器实例\r\n     * //对当前选中的文本内容执行下标操作\r\n     * //第一次操作， 文本内容将变成下标文本\r\n     * editor.execCommand( 'subscript' );\r\n     *\r\n     * //再次对同一文本内容执行， 则文本内容将恢复正常\r\n     * editor.execCommand( 'subscript' );\r\n     * ```\r\n     */\r\n\r\n    /**\r\n     * 上标文本，与“subscript”命令互斥\r\n     * @command superscript\r\n     * @method execCommand\r\n     * @remind 把选中的文本内容切换成上标文本， 如果当前选中的文本已经是上标， 则该操作会把文本内容还原成正常文本\r\n     * @param { String } cmd 命令字符串\r\n     * @example\r\n     * ```javascript\r\n     * //editor是编辑器实例\r\n     * //对当前选中的文本内容执行上标操作\r\n     * //第一次操作， 文本内容将变成上标文本\r\n     * editor.execCommand( 'superscript' );\r\n     *\r\n     * //再次对同一文本内容执行， 则文本内容将恢复正常\r\n     * editor.execCommand( 'superscript' );\r\n     * ```\r\n     */\r\n    var basestyles = {\r\n            'bold':['strong','b'],\r\n            'italic':['em','i'],\r\n            'subscript':['sub'],\r\n            'superscript':['sup']\r\n        },\r\n        getObj = function(editor,tagNames){\r\n            return domUtils.filterNodeList(editor.selection.getStartElementPath(),tagNames);\r\n        },\r\n        me = this;\r\n    //添加快捷键\r\n    me.addshortcutkey({\r\n        \"Bold\" : \"ctrl+66\",//^B\r\n        \"Italic\" : \"ctrl+73\", //^I\r\n        \"Underline\" : \"ctrl+85\"//^U\r\n    });\r\n    me.addInputRule(function(root){\r\n        utils.each(root.getNodesByTagName('b i'),function(node){\r\n            switch (node.tagName){\r\n                case 'b':\r\n                    node.tagName = 'strong';\r\n                    break;\r\n                case 'i':\r\n                    node.tagName = 'em';\r\n            }\r\n        });\r\n    });\r\n    for ( var style in basestyles ) {\r\n        (function( cmd, tagNames ) {\r\n            me.commands[cmd] = {\r\n                execCommand : function( cmdName ) {\r\n                    var range = me.selection.getRange(),obj = getObj(this,tagNames);\r\n                    if ( range.collapsed ) {\r\n                        if ( obj ) {\r\n                            var tmpText =  me.document.createTextNode('');\r\n                            range.insertNode( tmpText ).removeInlineStyle( tagNames );\r\n                            range.setStartBefore(tmpText);\r\n                            domUtils.remove(tmpText);\r\n                        } else {\r\n                            var tmpNode = range.document.createElement( tagNames[0] );\r\n                            if(cmdName == 'superscript' || cmdName == 'subscript'){\r\n                                tmpText = me.document.createTextNode('');\r\n                                range.insertNode(tmpText)\r\n                                    .removeInlineStyle(['sub','sup'])\r\n                                    .setStartBefore(tmpText)\r\n                                    .collapse(true);\r\n                            }\r\n                            range.insertNode( tmpNode ).setStart( tmpNode, 0 );\r\n                        }\r\n                        range.collapse( true );\r\n                    } else {\r\n                        if(cmdName == 'superscript' || cmdName == 'subscript'){\r\n                            if(!obj || obj.tagName.toLowerCase() != cmdName){\r\n                                range.removeInlineStyle(['sub','sup']);\r\n                            }\r\n                        }\r\n                        obj ? range.removeInlineStyle( tagNames ) : range.applyInlineStyle( tagNames[0] );\r\n                    }\r\n                    range.select();\r\n                },\r\n                queryCommandState : function() {\r\n                   return getObj(this,tagNames) ? 1 : 0;\r\n                }\r\n            };\r\n        })( style, basestyles[style] );\r\n    }\r\n};\r\n\r\n\n\n// plugins/elementpath.js\n/**\r\n * 选取路径命令\r\n * @file\r\n */\r\nUE.plugins['elementpath'] = function(){\r\n    var currentLevel,\r\n        tagNames,\r\n        me = this;\r\n    me.setOpt('elementPathEnabled',true);\r\n    if(!me.options.elementPathEnabled){\r\n        return;\r\n    }\r\n    me.commands['elementpath'] = {\r\n        execCommand : function( cmdName, level ) {\r\n            var start = tagNames[level],\r\n                range = me.selection.getRange();\r\n            currentLevel = level*1;\r\n            range.selectNode(start).select();\r\n        },\r\n        queryCommandValue : function() {\r\n            //产生一个副本，不能修改原来的startElementPath;\r\n            var parents = [].concat(this.selection.getStartElementPath()).reverse(),\r\n                names = [];\r\n            tagNames = parents;\r\n            for(var i=0,ci;ci=parents[i];i++){\r\n                if(ci.nodeType == 3) {\r\n                    continue;\r\n                }\r\n                var name = ci.tagName.toLowerCase();\r\n                if(name == 'img' && ci.getAttribute('anchorname')){\r\n                    name = 'anchor';\r\n                }\r\n                names[i] = name;\r\n                if(currentLevel == i){\r\n                   currentLevel = -1;\r\n                    break;\r\n                }\r\n            }\r\n            return names;\r\n        }\r\n    };\r\n};\r\n\r\n\n\n// plugins/formatmatch.js\n/**\n * 格式刷，只格式inline的\n * @file\n * @since 1.2.6.1\n */\n\n/**\n * 格式刷\n * @command formatmatch\n * @method execCommand\n * @remind 该操作不能复制段落格式\n * @param { String } cmd 命令字符串\n * @example\n * ```javascript\n * //editor是编辑器实例\n * //获取格式刷\n * editor.execCommand( 'formatmatch' );\n * ```\n */\nUE.plugins['formatmatch'] = function(){\n\n    var me = this,\n        list = [],img,\n        flag = 0;\n\n     me.addListener('reset',function(){\n         list = [];\n         flag = 0;\n     });\n\n    function addList(type,evt){\n        \n        if(browser.webkit){\n            var target = evt.target.tagName == 'IMG' ? evt.target : null;\n        }\n\n        function addFormat(range){\n\n            if(text){\n                range.selectNode(text);\n            }\n            return range.applyInlineStyle(list[list.length-1].tagName,null,list);\n\n        }\n\n        me.undoManger && me.undoManger.save();\n\n        var range = me.selection.getRange(),\n            imgT = target || range.getClosedNode();\n        if(img && imgT && imgT.tagName == 'IMG'){\n            //trace:964\n\n            imgT.style.cssText += ';float:' + (img.style.cssFloat || img.style.styleFloat ||'none') + ';display:' + (img.style.display||'inline');\n\n            img = null;\n        }else{\n            if(!img){\n                var collapsed = range.collapsed;\n                if(collapsed){\n                    var text = me.document.createTextNode('match');\n                    range.insertNode(text).select();\n\n\n                }\n                me.__hasEnterExecCommand = true;\n                //不能把block上的属性干掉\n                //trace:1553\n                var removeFormatAttributes = me.options.removeFormatAttributes;\n                me.options.removeFormatAttributes = '';\n                me.execCommand('removeformat');\n                me.options.removeFormatAttributes = removeFormatAttributes;\n                me.__hasEnterExecCommand = false;\n                //trace:969\n                range = me.selection.getRange();\n                if(list.length){\n                    addFormat(range);\n                }\n                if(text){\n                    range.setStartBefore(text).collapse(true);\n\n                }\n                range.select();\n                text && domUtils.remove(text);\n            }\n\n        }\n\n\n\n\n        me.undoManger && me.undoManger.save();\n        me.removeListener('mouseup',addList);\n        flag = 0;\n    }\n\n    me.commands['formatmatch'] = {\n        execCommand : function( cmdName ) {\n          \n            if(flag){\n                flag = 0;\n                list = [];\n                 me.removeListener('mouseup',addList);\n                return;\n            }\n\n\n              \n            var range = me.selection.getRange();\n            img = range.getClosedNode();\n            if(!img || img.tagName != 'IMG'){\n               range.collapse(true).shrinkBoundary();\n               var start = range.startContainer;\n               list = domUtils.findParents(start,true,function(node){\n                   return !domUtils.isBlockElm(node) && node.nodeType == 1;\n               });\n               //a不能加入格式刷, 并且克隆节点\n               for(var i=0,ci;ci=list[i];i++){\n                   if(ci.tagName == 'A'){\n                       list.splice(i,1);\n                       break;\n                   }\n               }\n\n            }\n\n            me.addListener('mouseup',addList);\n            flag = 1;\n\n\n        },\n        queryCommandState : function() {\n            return flag;\n        },\n        notNeedUndo : 1\n    };\n};\n\n\n\n// plugins/searchreplace.js\n///import core\r\n///commands 查找替换\r\n///commandsName  SearchReplace\r\n///commandsTitle  查询替换\r\n///commandsDialog  dialogs\\searchreplace\r\n/**\r\n * @description 查找替换\r\n * @author zhanyi\r\n */\r\n\r\nUE.plugin.register('searchreplace',function(){\r\n    var me = this;\r\n\r\n    var _blockElm = {'table':1,'tbody':1,'tr':1,'ol':1,'ul':1};\r\n\r\n    function findTextInString(textContent,opt,currentIndex){\r\n        var str = opt.searchStr;\r\n        if(opt.dir == -1){\r\n            textContent = textContent.split('').reverse().join('');\r\n            str = str.split('').reverse().join('');\r\n            currentIndex = textContent.length - currentIndex;\r\n\r\n        }\r\n        var reg = new RegExp(str,'g' + (opt.casesensitive ? '' : 'i')),match;\r\n\r\n        while(match = reg.exec(textContent)){\r\n            if(match.index >= currentIndex){\r\n                return opt.dir == -1 ? textContent.length - match.index - opt.searchStr.length : match.index;\r\n            }\r\n        }\r\n        return  -1\r\n    }\r\n    function findTextBlockElm(node,currentIndex,opt){\r\n        var textContent,index,methodName = opt.all || opt.dir == 1 ? 'getNextDomNode' : 'getPreDomNode';\r\n        if(domUtils.isBody(node)){\r\n            node = node.firstChild;\r\n        }\r\n        var first = 1;\r\n        while(node){\r\n            textContent = node.nodeType == 3 ? node.nodeValue : node[browser.ie ? 'innerText' : 'textContent'];\r\n            index = findTextInString(textContent,opt,currentIndex );\r\n            first = 0;\r\n            if(index!=-1){\r\n                return {\r\n                    'node':node,\r\n                    'index':index\r\n                }\r\n            }\r\n            node = domUtils[methodName](node);\r\n            while(node && _blockElm[node.nodeName.toLowerCase()]){\r\n                node = domUtils[methodName](node,true);\r\n            }\r\n            if(node){\r\n                currentIndex = opt.dir == -1 ? (node.nodeType == 3 ? node.nodeValue : node[browser.ie ? 'innerText' : 'textContent']).length : 0;\r\n            }\r\n\r\n        }\r\n    }\r\n    function findNTextInBlockElm(node,index,str){\r\n        var currentIndex = 0,\r\n            currentNode = node.firstChild,\r\n            currentNodeLength = 0,\r\n            result;\r\n        while(currentNode){\r\n            if(currentNode.nodeType == 3){\r\n                currentNodeLength = currentNode.nodeValue.replace(/(^[\\t\\r\\n]+)|([\\t\\r\\n]+$)/,'').length;\r\n                currentIndex += currentNodeLength;\r\n                if(currentIndex >= index){\r\n                    return {\r\n                        'node':currentNode,\r\n                        'index': currentNodeLength - (currentIndex - index)\r\n                    }\r\n                }\r\n            }else if(!dtd.$empty[currentNode.tagName]){\r\n                currentNodeLength = currentNode[browser.ie ? 'innerText' : 'textContent'].replace(/(^[\\t\\r\\n]+)|([\\t\\r\\n]+$)/,'').length\r\n                currentIndex += currentNodeLength;\r\n                if(currentIndex >= index){\r\n                    result = findNTextInBlockElm(currentNode,currentNodeLength - (currentIndex - index),str);\r\n                    if(result){\r\n                        return result;\r\n                    }\r\n                }\r\n            }\r\n            currentNode = domUtils.getNextDomNode(currentNode);\r\n\r\n        }\r\n    }\r\n\r\n    function searchReplace(me,opt){\r\n\r\n        var rng = me.selection.getRange(),\r\n            startBlockNode,\r\n            searchStr = opt.searchStr,\r\n            span = me.document.createElement('span');\r\n        span.innerHTML = '$$ueditor_searchreplace_key$$';\r\n\r\n        rng.shrinkBoundary(true);\r\n\r\n        //判断是不是第一次选中\r\n        if(!rng.collapsed){\r\n            rng.select();\r\n            var rngText = me.selection.getText();\r\n            if(new RegExp('^' + opt.searchStr + '$',(opt.casesensitive ? '' : 'i')).test(rngText)){\r\n                if(opt.replaceStr != undefined){\r\n                    replaceText(rng,opt.replaceStr);\r\n                    rng.select();\r\n                    return true;\r\n                }else{\r\n                    rng.collapse(opt.dir == -1)\r\n                }\r\n\r\n            }\r\n        }\r\n\r\n\r\n        rng.insertNode(span);\r\n        rng.enlargeToBlockElm(true);\r\n        startBlockNode = rng.startContainer;\r\n        var currentIndex = startBlockNode[browser.ie ? 'innerText' : 'textContent'].indexOf('$$ueditor_searchreplace_key$$');\r\n        rng.setStartBefore(span);\r\n        domUtils.remove(span);\r\n        var result = findTextBlockElm(startBlockNode,currentIndex,opt);\r\n        if(result){\r\n            var rngStart = findNTextInBlockElm(result.node,result.index,searchStr);\r\n            var rngEnd = findNTextInBlockElm(result.node,result.index + searchStr.length,searchStr);\r\n            rng.setStart(rngStart.node,rngStart.index).setEnd(rngEnd.node,rngEnd.index);\r\n\r\n            if(opt.replaceStr !== undefined){\r\n                replaceText(rng,opt.replaceStr)\r\n            }\r\n            rng.select();\r\n            return true;\r\n        }else{\r\n            rng.setCursor()\r\n        }\r\n\r\n    }\r\n    function replaceText(rng,str){\r\n\r\n        str = me.document.createTextNode(str);\r\n        rng.deleteContents().insertNode(str);\r\n\r\n    }\r\n    return {\r\n        commands:{\r\n            'searchreplace':{\r\n                execCommand:function(cmdName,opt){\r\n                    utils.extend(opt,{\r\n                        all : false,\r\n                        casesensitive : false,\r\n                        dir : 1\r\n                    },true);\r\n                    var num = 0;\r\n                    if(opt.all){\r\n\r\n                        var rng = me.selection.getRange(),\r\n                            first = me.body.firstChild;\r\n                        if(first && first.nodeType == 1){\r\n                            rng.setStart(first,0);\r\n                            rng.shrinkBoundary(true);\r\n                        }else if(first.nodeType == 3){\r\n                            rng.setStartBefore(first)\r\n                        }\r\n                        rng.collapse(true).select(true);\r\n                        if(opt.replaceStr !== undefined){\r\n                            me.fireEvent('saveScene');\r\n                        }\r\n                        while(searchReplace(this,opt)){\r\n                            num++;\r\n                        }\r\n                        if(num){\r\n                            me.fireEvent('saveScene');\r\n                        }\r\n                    }else{\r\n                        if(opt.replaceStr !== undefined){\r\n                            me.fireEvent('saveScene');\r\n                        }\r\n                        if(searchReplace(this,opt)){\r\n                            num++\r\n                        }\r\n                        if(num){\r\n                            me.fireEvent('saveScene');\r\n                        }\r\n\r\n                    }\r\n\r\n                    return num;\r\n                },\r\n                notNeedUndo:1\r\n            }\r\n        }\r\n    }\r\n});\n\n// plugins/customstyle.js\n/**\r\n * 自定义样式\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n/**\r\n * 根据config配置文件里“customstyle”选项的值对匹配的标签执行样式替换。\r\n * @command customstyle\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * editor.execCommand( 'customstyle' );\r\n * ```\r\n */\r\nUE.plugins['customstyle'] = function() {\r\n    var me = this;\r\n    me.setOpt({ 'customstyle':[\r\n        {tag:'h1',name:'tc', style:'font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:center;margin:0 0 20px 0;'},\r\n        {tag:'h1',name:'tl', style:'font-size:32px;font-weight:bold;border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:left;margin:0 0 10px 0;'},\r\n        {tag:'span',name:'im', style:'font-size:16px;font-style:italic;font-weight:bold;line-height:18px;'},\r\n        {tag:'span',name:'hi', style:'font-size:16px;font-style:italic;font-weight:bold;color:rgb(51, 153, 204);line-height:18px;'}\r\n    ]});\r\n    me.commands['customstyle'] = {\r\n        execCommand : function(cmdName, obj) {\r\n            var me = this,\r\n                    tagName = obj.tag,\r\n                    node = domUtils.findParent(me.selection.getStart(), function(node) {\r\n                        return node.getAttribute('label');\r\n                    }, true),\r\n                    range,bk,tmpObj = {};\r\n            for (var p in obj) {\r\n               if(obj[p]!==undefined)\r\n                    tmpObj[p] = obj[p];\r\n            }\r\n            delete tmpObj.tag;\r\n            if (node && node.getAttribute('label') == obj.label) {\r\n                range = this.selection.getRange();\r\n                bk = range.createBookmark();\r\n                if (range.collapsed) {\r\n                    //trace:1732 删掉自定义标签，要有p来回填站位\r\n                    if(dtd.$block[node.tagName]){\r\n                        var fillNode = me.document.createElement('p');\r\n                        domUtils.moveChild(node, fillNode);\r\n                        node.parentNode.insertBefore(fillNode, node);\r\n                        domUtils.remove(node);\r\n                    }else{\r\n                        domUtils.remove(node,true);\r\n                    }\r\n\r\n                } else {\r\n\r\n                    var common = domUtils.getCommonAncestor(bk.start, bk.end),\r\n                            nodes = domUtils.getElementsByTagName(common, tagName);\r\n                    if(new RegExp(tagName,'i').test(common.tagName)){\r\n                        nodes.push(common);\r\n                    }\r\n                    for (var i = 0,ni; ni = nodes[i++];) {\r\n                        if (ni.getAttribute('label') == obj.label) {\r\n                            var ps = domUtils.getPosition(ni, bk.start),pe = domUtils.getPosition(ni, bk.end);\r\n                            if ((ps & domUtils.POSITION_FOLLOWING || ps & domUtils.POSITION_CONTAINS)\r\n                                    &&\r\n                                    (pe & domUtils.POSITION_PRECEDING || pe & domUtils.POSITION_CONTAINS)\r\n                                    )\r\n                                if (dtd.$block[tagName]) {\r\n                                    var fillNode = me.document.createElement('p');\r\n                                    domUtils.moveChild(ni, fillNode);\r\n                                    ni.parentNode.insertBefore(fillNode, ni);\r\n                                }\r\n                            domUtils.remove(ni, true);\r\n                        }\r\n                    }\r\n                    node = domUtils.findParent(common, function(node) {\r\n                        return node.getAttribute('label') == obj.label;\r\n                    }, true);\r\n                    if (node) {\r\n\r\n                        domUtils.remove(node, true);\r\n\r\n                    }\r\n\r\n                }\r\n                range.moveToBookmark(bk).select();\r\n            } else {\r\n                if (dtd.$block[tagName]) {\r\n                    this.execCommand('paragraph', tagName, tmpObj,'customstyle');\r\n                    range = me.selection.getRange();\r\n                    if (!range.collapsed) {\r\n                        range.collapse();\r\n                        node = domUtils.findParent(me.selection.getStart(), function(node) {\r\n                            return node.getAttribute('label') == obj.label;\r\n                        }, true);\r\n                        var pNode = me.document.createElement('p');\r\n                        domUtils.insertAfter(node, pNode);\r\n                        domUtils.fillNode(me.document, pNode);\r\n                        range.setStart(pNode, 0).setCursor();\r\n                    }\r\n                } else {\r\n\r\n                    range = me.selection.getRange();\r\n                    if (range.collapsed) {\r\n                        node = me.document.createElement(tagName);\r\n                        domUtils.setAttributes(node, tmpObj);\r\n                        range.insertNode(node).setStart(node, 0).setCursor();\r\n\r\n                        return;\r\n                    }\r\n\r\n                    bk = range.createBookmark();\r\n                    range.applyInlineStyle(tagName, tmpObj).moveToBookmark(bk).select();\r\n                }\r\n            }\r\n\r\n        },\r\n        queryCommandValue : function() {\r\n            var parent = domUtils.filterNodeList(\r\n                this.selection.getStartElementPath(),\r\n                function(node){return node.getAttribute('label')}\r\n            );\r\n            return  parent ? parent.getAttribute('label') : '';\r\n        }\r\n    };\r\n    //当去掉customstyle是，如果是块元素，用p代替\r\n    me.addListener('keyup', function(type, evt) {\r\n        var keyCode = evt.keyCode || evt.which;\r\n\r\n        if (keyCode == 32 || keyCode == 13) {\r\n            var range = me.selection.getRange();\r\n            if (range.collapsed) {\r\n                var node = domUtils.findParent(me.selection.getStart(), function(node) {\r\n                    return node.getAttribute('label');\r\n                }, true);\r\n                if (node && dtd.$block[node.tagName] && domUtils.isEmptyNode(node)) {\r\n                        var p = me.document.createElement('p');\r\n                        domUtils.insertAfter(node, p);\r\n                        domUtils.fillNode(me.document, p);\r\n                        domUtils.remove(node);\r\n                        range.setStart(p, 0).setCursor();\r\n\r\n\r\n                }\r\n            }\r\n        }\r\n    });\r\n};\n\n// plugins/catchremoteimage.js\n///import core\r\n///commands 远程图片抓取\r\n///commandsName  catchRemoteImage,catchremoteimageenable\r\n///commandsTitle  远程图片抓取\r\n/**\r\n * 远程图片抓取,当开启本插件时所有不符合本地域名的图片都将被抓取成为本地服务器上的图片\r\n */\r\nUE.plugins['catchremoteimage'] = function () {\r\n    var me = this,\r\n        ajax = UE.ajax;\r\n\r\n    /* 设置默认值 */\r\n    if (me.options.catchRemoteImageEnable === false) return;\r\n    me.setOpt({\r\n        catchRemoteImageEnable: false\r\n    });\r\n\r\n    me.addListener(\"afterpaste\", function () {\r\n        me.fireEvent(\"catchRemoteImage\");\r\n    });\r\n\r\n    me.addListener(\"catchRemoteImage\", function () {\r\n\r\n        var catcherLocalDomain = me.getOpt('catcherLocalDomain'),\r\n            catcherActionUrl = me.getActionUrl(me.getOpt('catcherActionName')),\r\n            catcherUrlPrefix = me.getOpt('catcherUrlPrefix'),\r\n            catcherFieldName = me.getOpt('catcherFieldName');\r\n\r\n        var remoteImages = [],\r\n            imgs = domUtils.getElementsByTagName(me.document, \"img\"),\r\n            test = function (src, urls) {\r\n                if (src.indexOf(location.host) != -1 || /(^\\.)|(^\\/)/.test(src)) {\r\n                    return true;\r\n                }\r\n                if (urls) {\r\n                    for (var j = 0, url; url = urls[j++];) {\r\n                        if (src.indexOf(url) !== -1) {\r\n                            return true;\r\n                        }\r\n                    }\r\n                }\r\n                return false;\r\n            };\r\n\r\n        for (var i = 0, ci; ci = imgs[i++];) {\r\n            if (ci.getAttribute(\"word_img\")) {\r\n                continue;\r\n            }\r\n            var src = ci.getAttribute(\"_src\") || ci.src || \"\";\r\n            if (/^(https?|ftp):/i.test(src) && !test(src, catcherLocalDomain)) {\r\n                remoteImages.push(src);\r\n            }\r\n        }\r\n\r\n        if (remoteImages.length) {\r\n            catchremoteimage(remoteImages, {\r\n                //成功抓取\r\n                success: function (r) {\r\n                    try {\r\n                        var info = r.state !== undefined ? r:eval(\"(\" + r.responseText + \")\");\r\n                    } catch (e) {\r\n                        return;\r\n                    }\r\n\r\n                    /* 获取源路径和新路径 */\r\n                    var i, j, ci, cj, oldSrc, newSrc, list = info.list;\r\n\r\n                    for (i = 0; ci = imgs[i++];) {\r\n                        oldSrc = ci.getAttribute(\"_src\") || ci.src || \"\";\r\n                        for (j = 0; cj = list[j++];) {\r\n                            if (oldSrc == cj.source && cj.state == \"SUCCESS\") {  //抓取失败时不做替换处理\r\n                                newSrc = catcherUrlPrefix + cj.url;\r\n                                domUtils.setAttributes(ci, {\r\n                                    \"src\": newSrc,\r\n                                    \"_src\": newSrc\r\n                                });\r\n                                break;\r\n                            }\r\n                        }\r\n                    }\r\n                    me.fireEvent('catchremotesuccess')\r\n                },\r\n                //回调失败，本次请求超时\r\n                error: function () {\r\n                    me.fireEvent(\"catchremoteerror\");\r\n                }\r\n            });\r\n        }\r\n\r\n        function catchremoteimage(imgs, callbacks) {\r\n            var params = utils.serializeParam(me.queryCommandValue('serverparam')) || '',\r\n                url = utils.formatUrl(catcherActionUrl + (catcherActionUrl.indexOf('?') == -1 ? '?':'&') + params),\r\n                isJsonp = utils.isCrossDomainUrl(url),\r\n                opt = {\r\n                    'method': 'POST',\r\n                    'dataType': isJsonp ? 'jsonp':'',\r\n                    'timeout': 60000, //单位：毫秒，回调请求超时设置。目标用户如果网速不是很快的话此处建议设置一个较大的数值\r\n                    'onsuccess': callbacks[\"success\"],\r\n                    'onerror': callbacks[\"error\"]\r\n                };\r\n            opt[catcherFieldName] = imgs;\r\n            ajax.request(url, opt);\r\n        }\r\n\r\n    });\r\n};\n\n// plugins/snapscreen.js\n/**\r\n * 截屏插件，为UEditor提供插入支持\r\n * @file\r\n * @since 1.4.2\r\n */\r\nUE.plugin.register('snapscreen', function (){\r\n\r\n    var me = this;\r\n    var snapplugin;\r\n\r\n    function getLocation(url){\r\n        var search,\r\n            a = document.createElement('a'),\r\n            params = utils.serializeParam(me.queryCommandValue('serverparam')) || '';\r\n\r\n        a.href = url;\r\n        if (browser.ie) {\r\n            a.href = a.href;\r\n        }\r\n\r\n\r\n        search = a.search;\r\n        if (params) {\r\n            search = search + (search.indexOf('?') == -1 ? '?':'&')+ params;\r\n            search = search.replace(/[&]+/ig, '&');\r\n        }\r\n        return {\r\n            'port': a.port,\r\n            'hostname': a.hostname,\r\n            'path': a.pathname + search ||  + a.hash\r\n        }\r\n    }\r\n\r\n    return {\r\n        commands:{\r\n            /**\r\n             * 字体背景颜色\r\n             * @command snapscreen\r\n             * @method execCommand\r\n             * @param { String } cmd 命令字符串\r\n             * @example\r\n             * ```javascript\r\n             * editor.execCommand('snapscreen');\r\n             * ```\r\n             */\r\n            'snapscreen':{\r\n                execCommand:function (cmd) {\r\n                    var url, local, res;\r\n                    var lang = me.getLang(\"snapScreen_plugin\");\r\n\r\n                    if(!snapplugin){\r\n                        var container = me.container;\r\n                        var doc = me.container.ownerDocument || me.container.document;\r\n                        snapplugin = doc.createElement(\"object\");\r\n                        try{snapplugin.type = \"application/x-pluginbaidusnap\";}catch(e){\r\n                            return;\r\n                        }\r\n                        snapplugin.style.cssText = \"position:absolute;left:-9999px;width:0;height:0;\";\r\n                        snapplugin.setAttribute(\"width\",\"0\");\r\n                        snapplugin.setAttribute(\"height\",\"0\");\r\n                        container.appendChild(snapplugin);\r\n                    }\r\n\r\n                    function onSuccess(rs){\r\n                        try{\r\n                            rs = eval(\"(\"+ rs +\")\");\r\n                            if(rs.state == 'SUCCESS'){\r\n                                var opt = me.options;\r\n                                me.execCommand('insertimage', {\r\n                                    src: opt.snapscreenUrlPrefix + rs.url,\r\n                                    _src: opt.snapscreenUrlPrefix + rs.url,\r\n                                    alt: rs.title || '',\r\n                                    floatStyle: opt.snapscreenImgAlign\r\n                                });\r\n                            } else {\r\n                                alert(rs.state);\r\n                            }\r\n                        }catch(e){\r\n                            alert(lang.callBackErrorMsg);\r\n                        }\r\n                    }\r\n                    url = me.getActionUrl(me.getOpt('snapscreenActionName'));\r\n                    local = getLocation(url);\r\n                    setTimeout(function () {\r\n                        try{\r\n                            res =snapplugin.saveSnapshot(local.hostname, local.path, local.port);\r\n                        }catch(e){\r\n                            me.ui._dialogs['snapscreenDialog'].open();\r\n                            return;\r\n                        }\r\n\r\n                        onSuccess(res);\r\n                    }, 50);\r\n                },\r\n                queryCommandState: function(){\r\n                    return (navigator.userAgent.indexOf(\"Windows\",0) != -1) ? 0:-1;\r\n                }\r\n            }\r\n        }\r\n    }\r\n});\r\n\n\n// plugins/insertparagraph.js\n/**\r\n * 插入段落\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n\r\n/**\r\n * 插入段落\r\n * @command insertparagraph\r\n * @method execCommand\r\n * @param { String } cmd 命令字符串\r\n * @example\r\n * ```javascript\r\n * //editor是编辑器实例\r\n * editor.execCommand( 'insertparagraph' );\r\n * ```\r\n */\r\n\r\nUE.commands['insertparagraph'] = {\r\n    execCommand : function( cmdName,front) {\r\n        var me = this,\r\n            range = me.selection.getRange(),\r\n            start = range.startContainer,tmpNode;\r\n        while(start ){\r\n            if(domUtils.isBody(start)){\r\n                break;\r\n            }\r\n            tmpNode = start;\r\n            start = start.parentNode;\r\n        }\r\n        if(tmpNode){\r\n            var p = me.document.createElement('p');\r\n            if(front){\r\n                tmpNode.parentNode.insertBefore(p,tmpNode)\r\n            }else{\r\n                tmpNode.parentNode.insertBefore(p,tmpNode.nextSibling)\r\n            }\r\n            domUtils.fillNode(me.document,p);\r\n            range.setStart(p,0).setCursor(false,true);\r\n        }\r\n    }\r\n};\r\n\r\n\n\n// plugins/webapp.js\n/**\r\n * 百度应用\r\n * @file\r\n * @since 1.2.6.1\r\n */\r\n\r\n\r\n/**\r\n * 插入百度应用\r\n * @command webapp\r\n * @method execCommand\r\n * @remind 需要百度APPKey\r\n * @remind 百度应用主页： <a href=\"http://app.baidu.com/\" target=\"_blank\">http://app.baidu.com/</a>\r\n * @param { Object } appOptions 应用所需的参数项， 支持的key有： title=>应用标题， width=>应用容器宽度，\r\n * height=>应用容器高度，logo=>应用logo，url=>应用地址\r\n * @example\r\n * ```javascript\r\n * //editor是编辑器实例\r\n * //在编辑器里插入一个“植物大战僵尸”的APP\r\n * editor.execCommand( 'webapp' , {\r\n *     title: '植物大战僵尸',\r\n *     width: 560,\r\n *     height: 465,\r\n *     logo: '应用展示的图片',\r\n *     url: '百度应用的地址'\r\n * } );\r\n * ```\r\n */\r\n\r\n//UE.plugins['webapp'] = function () {\r\n//    var me = this;\r\n//    function createInsertStr( obj, toIframe, addParagraph ) {\r\n//        return !toIframe ?\r\n//                (addParagraph ? '<p>' : '') + '<img title=\"'+obj.title+'\" width=\"' + obj.width + '\" height=\"' + obj.height + '\"' +\r\n//                        ' src=\"' + me.options.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif\" style=\"background:url(' + obj.logo+') no-repeat center center; border:1px solid gray;\" class=\"edui-faked-webapp\" _url=\"' + obj.url + '\" />' +\r\n//                        (addParagraph ? '</p>' : '')\r\n//                :\r\n//                '<iframe class=\"edui-faked-webapp\" title=\"'+obj.title+'\" width=\"' + obj.width + '\" height=\"' + obj.height + '\"  scrolling=\"no\" frameborder=\"0\" src=\"' + obj.url + '\" logo_url = '+obj.logo+'></iframe>';\r\n//    }\r\n//\r\n//    function switchImgAndIframe( img2frame ) {\r\n//        var tmpdiv,\r\n//                nodes = domUtils.getElementsByTagName( me.document, !img2frame ? \"iframe\" : \"img\" );\r\n//        for ( var i = 0, node; node = nodes[i++]; ) {\r\n//            if ( node.className != \"edui-faked-webapp\" ){\r\n//                continue;\r\n//            }\r\n//            tmpdiv = me.document.createElement( \"div\" );\r\n//            tmpdiv.innerHTML = createInsertStr( img2frame ? {url:node.getAttribute( \"_url\" ), width:node.width, height:node.height,title:node.title,logo:node.style.backgroundImage.replace(\"url(\",\"\").replace(\")\",\"\")} : {url:node.getAttribute( \"src\", 2 ),title:node.title, width:node.width, height:node.height,logo:node.getAttribute(\"logo_url\")}, img2frame ? true : false,false );\r\n//            node.parentNode.replaceChild( tmpdiv.firstChild, node );\r\n//        }\r\n//    }\r\n//\r\n//    me.addListener( \"beforegetcontent\", function () {\r\n//        switchImgAndIframe( true );\r\n//    } );\r\n//    me.addListener( 'aftersetcontent', function () {\r\n//        switchImgAndIframe( false );\r\n//    } );\r\n//    me.addListener( 'aftergetcontent', function ( cmdName ) {\r\n//        if ( cmdName == 'aftergetcontent' && me.queryCommandState( 'source' ) ){\r\n//            return;\r\n//        }\r\n//        switchImgAndIframe( false );\r\n//    } );\r\n//\r\n//    me.commands['webapp'] = {\r\n//        execCommand:function ( cmd, obj ) {\r\n//            me.execCommand( \"inserthtml\", createInsertStr( obj, false,true ) );\r\n//        }\r\n//    };\r\n//};\r\n\r\nUE.plugin.register('webapp', function (){\r\n    var me = this;\r\n    function createInsertStr(obj,toEmbed){\r\n        return  !toEmbed ?\r\n            '<img title=\"'+obj.title+'\" width=\"' + obj.width + '\" height=\"' + obj.height + '\"' +\r\n                ' src=\"' + me.options.UEDITOR_HOME_URL + 'themes/default/images/spacer.gif\" _logo_url=\"'+obj.logo+'\" style=\"background:url(' + obj.logo\r\n                +') no-repeat center center; border:1px solid gray;\" class=\"edui-faked-webapp\" _url=\"' + obj.url + '\" ' +\r\n                (obj.align && !obj.cssfloat? 'align=\"' + obj.align + '\"' : '') +\r\n                (obj.cssfloat ? 'style=\"float:' + obj.cssfloat + '\"' : '') +\r\n                '/>'\r\n            :\r\n            '<iframe class=\"edui-faked-webapp\" title=\"'+obj.title+'\" ' +\r\n                (obj.align && !obj.cssfloat? 'align=\"' + obj.align + '\"' : '') +\r\n                (obj.cssfloat ? 'style=\"float:' + obj.cssfloat + '\"' : '') +\r\n                'width=\"' + obj.width + '\" height=\"' + obj.height + '\"  scrolling=\"no\" frameborder=\"0\" src=\"' + obj.url + '\" logo_url = \"'+obj.logo+'\"></iframe>'\r\n\r\n    }\r\n    return {\r\n        outputRule: function(root){\r\n            utils.each(root.getNodesByTagName('img'),function(node){\r\n                var html;\r\n                if(node.getAttr('class') == 'edui-faked-webapp'){\r\n                    html =  createInsertStr({\r\n                        title:node.getAttr('title'),\r\n                        'width':node.getAttr('width'),\r\n                        'height':node.getAttr('height'),\r\n                        'align':node.getAttr('align'),\r\n                        'cssfloat':node.getStyle('float'),\r\n                        'url':node.getAttr(\"_url\"),\r\n                        'logo':node.getAttr('_logo_url')\r\n                    },true);\r\n                    var embed = UE.uNode.createElement(html);\r\n                    node.parentNode.replaceChild(embed,node);\r\n                }\r\n            })\r\n        },\r\n        inputRule:function(root){\r\n            utils.each(root.getNodesByTagName('iframe'),function(node){\r\n                if(node.getAttr('class') == 'edui-faked-webapp'){\r\n                    var img = UE.uNode.createElement(createInsertStr({\r\n                        title:node.getAttr('title'),\r\n                        'width':node.getAttr('width'),\r\n                        'height':node.getAttr('height'),\r\n                        'align':node.getAttr('align'),\r\n                        'cssfloat':node.getStyle('float'),\r\n                        'url':node.getAttr(\"src\"),\r\n                        'logo':node.getAttr('logo_url')\r\n                    }));\r\n                    node.parentNode.replaceChild(img,node);\r\n                }\r\n            })\r\n\r\n        },\r\n        commands:{\r\n            /**\r\n             * 插入百度应用\r\n             * @command webapp\r\n             * @method execCommand\r\n             * @remind 需要百度APPKey\r\n             * @remind 百度应用主页： <a href=\"http://app.baidu.com/\" target=\"_blank\">http://app.baidu.com/</a>\r\n             * @param { Object } appOptions 应用所需的参数项， 支持的key有： title=>应用标题， width=>应用容器宽度，\r\n             * height=>应用容器高度，logo=>应用logo，url=>应用地址\r\n             * @example\r\n             * ```javascript\r\n             * //editor是编辑器实例\r\n             * //在编辑器里插入一个“植物大战僵尸”的APP\r\n             * editor.execCommand( 'webapp' , {\r\n             *     title: '植物大战僵尸',\r\n             *     width: 560,\r\n             *     height: 465,\r\n             *     logo: '应用展示的图片',\r\n             *     url: '百度应用的地址'\r\n             * } );\r\n             * ```\r\n             */\r\n            'webapp':{\r\n                execCommand:function (cmd, obj) {\r\n\r\n                    var me = this,\r\n                        str = createInsertStr(utils.extend(obj,{\r\n                            align:'none'\r\n                        }), false);\r\n                    me.execCommand(\"inserthtml\",str);\r\n                },\r\n                queryCommandState:function () {\r\n                    var me = this,\r\n                        img = me.selection.getRange().getClosedNode(),\r\n                        flag = img && (img.className == \"edui-faked-webapp\");\r\n                    return flag ? 1 : 0;\r\n                }\r\n            }\r\n        }\r\n    }\r\n});\n\n// plugins/template.js\n///import core\r\n///import plugins\\inserthtml.js\r\n///import plugins\\cleardoc.js\r\n///commands 模板\r\n///commandsName  template\r\n///commandsTitle  模板\r\n///commandsDialog  dialogs\\template\r\nUE.plugins['template'] = function () {\r\n    UE.commands['template'] = {\r\n        execCommand:function (cmd, obj) {\r\n            obj.html && this.execCommand(\"inserthtml\", obj.html);\r\n        }\r\n    };\r\n    this.addListener(\"click\", function (type, evt) {\r\n        var el = evt.target || evt.srcElement,\r\n            range = this.selection.getRange();\r\n        var tnode = domUtils.findParent(el, function (node) {\r\n            if (node.className && domUtils.hasClass(node, \"ue_t\")) {\r\n                return node;\r\n            }\r\n        }, true);\r\n        tnode && range.selectNode(tnode).shrinkBoundary().select();\r\n    });\r\n    this.addListener(\"keydown\", function (type, evt) {\r\n        var range = this.selection.getRange();\r\n        if (!range.collapsed) {\r\n            if (!evt.ctrlKey && !evt.metaKey && !evt.shiftKey && !evt.altKey) {\r\n                var tnode = domUtils.findParent(range.startContainer, function (node) {\r\n                    if (node.className && domUtils.hasClass(node, \"ue_t\")) {\r\n                        return node;\r\n                    }\r\n                }, true);\r\n                if (tnode) {\r\n                    domUtils.removeClasses(tnode, [\"ue_t\"]);\r\n                }\r\n            }\r\n        }\r\n    });\r\n};\r\n\n\n// plugins/music.js\n/**\r\n * 插入音乐命令\r\n * @file\r\n */\r\nUE.plugin.register('music', function (){\r\n    var me = this;\r\n    function creatInsertStr(url,width,height,align,cssfloat,toEmbed){\r\n        return  !toEmbed ?\r\n                '<img ' +\r\n                    (align && !cssfloat? 'align=\"' + align + '\"' : '') +\r\n                    (cssfloat ? 'style=\"float:' + cssfloat + '\"' : '') +\r\n                    ' width=\"'+ width +'\" height=\"' + height + '\" _url=\"'+url+'\" class=\"edui-faked-music\"' +\r\n                    ' src=\"'+me.options.langPath+me.options.lang+'/images/music.png\" />'\r\n            :\r\n            '<embed type=\"application/x-shockwave-flash\" class=\"edui-faked-music\" pluginspage=\"http://www.macromedia.com/go/getflashplayer\"' +\r\n                ' src=\"' + url + '\" width=\"' + width  + '\" height=\"' + height  + '\" '+ (align && !cssfloat? 'align=\"' + align + '\"' : '') +\r\n                (cssfloat ? 'style=\"float:' + cssfloat + '\"' : '') +\r\n                ' wmode=\"transparent\" play=\"true\" loop=\"false\" menu=\"false\" allowscriptaccess=\"never\" allowfullscreen=\"true\" >';\r\n    }\r\n    return {\r\n        outputRule: function(root){\r\n            utils.each(root.getNodesByTagName('img'),function(node){\r\n                var html;\r\n                if(node.getAttr('class') == 'edui-faked-music'){\r\n                    var cssfloat = node.getStyle('float');\r\n                    var align = node.getAttr('align');\r\n                    html =  creatInsertStr(node.getAttr(\"_url\"), node.getAttr('width'), node.getAttr('height'), align, cssfloat, true);\r\n                    var embed = UE.uNode.createElement(html);\r\n                    node.parentNode.replaceChild(embed,node);\r\n                }\r\n            })\r\n        },\r\n        inputRule:function(root){\r\n            utils.each(root.getNodesByTagName('embed'),function(node){\r\n                if(node.getAttr('class') == 'edui-faked-music'){\r\n                    var cssfloat = node.getStyle('float');\r\n                    var align = node.getAttr('align');\r\n                    html =  creatInsertStr(node.getAttr(\"src\"), node.getAttr('width'), node.getAttr('height'), align, cssfloat,false);\r\n                    var img = UE.uNode.createElement(html);\r\n                    node.parentNode.replaceChild(img,node);\r\n                }\r\n            })\r\n\r\n        },\r\n        commands:{\r\n            /**\r\n             * 插入音乐\r\n             * @command music\r\n             * @method execCommand\r\n             * @param { Object } musicOptions 插入音乐的参数项， 支持的key有： url=>音乐地址；\r\n             * width=>音乐容器宽度；height=>音乐容器高度；align=>音乐文件的对齐方式， 可选值有: left, center, right, none\r\n             * @example\r\n             * ```javascript\r\n             * //editor是编辑器实例\r\n             * //在编辑器里插入一个“植物大战僵尸”的APP\r\n             * editor.execCommand( 'music' , {\r\n             *     width: 400,\r\n             *     height: 95,\r\n             *     align: \"center\",\r\n             *     url: \"音乐地址\"\r\n             * } );\r\n             * ```\r\n             */\r\n            'music':{\r\n                execCommand:function (cmd, musicObj) {\r\n                    var me = this,\r\n                        str = creatInsertStr(musicObj.url, musicObj.width || 400, musicObj.height || 95, \"none\", false);\r\n                    me.execCommand(\"inserthtml\",str);\r\n                },\r\n                queryCommandState:function () {\r\n                    var me = this,\r\n                        img = me.selection.getRange().getClosedNode(),\r\n                        flag = img && (img.className == \"edui-faked-music\");\r\n                    return flag ? 1 : 0;\r\n                }\r\n            }\r\n        }\r\n    }\r\n});\n\n// plugins/autoupload.js\n/**\n * @description\n * 1.拖放文件到编辑区域，自动上传并插入到选区\n * 2.插入粘贴板的图片，自动上传并插入到选区\n * @author Jinqn\n * @date 2013-10-14\n */\nUE.plugin.register('autoupload', function (){\n\n    function sendAndInsertFile(file, editor) {\n        var me  = editor;\n        //模拟数据\n        var fieldName, urlPrefix, maxSize, allowFiles, actionUrl,\n            loadingHtml, errorHandler, successHandler,\n            filetype = /image\\/\\w+/i.test(file.type) ? 'image':'file',\n            loadingId = 'loading_' + (+new Date()).toString(36);\n\n        fieldName = me.getOpt(filetype + 'FieldName');\n        urlPrefix = me.getOpt(filetype + 'UrlPrefix');\n        maxSize = me.getOpt(filetype + 'MaxSize');\n        allowFiles = me.getOpt(filetype + 'AllowFiles');\n        actionUrl = me.getActionUrl(me.getOpt(filetype + 'ActionName'));\n        errorHandler = function(title) {\n            var loader = me.document.getElementById(loadingId);\n            loader && domUtils.remove(loader);\n            me.fireEvent('showmessage', {\n                'id': loadingId,\n                'content': title,\n                'type': 'error',\n                'timeout': 4000\n            });\n        };\n\n        if (filetype == 'image') {\n            loadingHtml = '<img class=\"loadingclass\" id=\"' + loadingId + '\" src=\"' +\n                me.options.themePath + me.options.theme +\n                '/images/spacer.gif\" title=\"' + (me.getLang('autoupload.loading') || '') + '\" >';\n            successHandler = function(data) {\n                var link = urlPrefix + data.url,\n                    loader = me.document.getElementById(loadingId);\n                if (loader) {\n                    loader.setAttribute('src', link);\n                    loader.setAttribute('_src', link);\n                    loader.setAttribute('title', data.title || '');\n                    loader.setAttribute('alt', data.original || '');\n                    loader.removeAttribute('id');\n                    domUtils.removeClasses(loader, 'loadingclass');\n                }\n            };\n        } else {\n            loadingHtml = '<p>' +\n                '<img class=\"loadingclass\" id=\"' + loadingId + '\" src=\"' +\n                me.options.themePath + me.options.theme +\n                '/images/spacer.gif\" title=\"' + (me.getLang('autoupload.loading') || '') + '\" >' +\n                '</p>';\n            successHandler = function(data) {\n                var link = urlPrefix + data.url,\n                    loader = me.document.getElementById(loadingId);\n\n                var rng = me.selection.getRange(),\n                    bk = rng.createBookmark();\n                rng.selectNode(loader).select();\n                me.execCommand('insertfile', {'url': link});\n                rng.moveToBookmark(bk).select();\n            };\n        }\n\n        /* 插入loading的占位符 */\n        me.execCommand('inserthtml', loadingHtml);\n\n        /* 判断后端配置是否没有加载成功 */\n        if (!me.getOpt(filetype + 'ActionName')) {\n            errorHandler(me.getLang('autoupload.errorLoadConfig'));\n            return;\n        }\n        /* 判断文件大小是否超出限制 */\n        if(file.size > maxSize) {\n            errorHandler(me.getLang('autoupload.exceedSizeError'));\n            return;\n        }\n        /* 判断文件格式是否超出允许 */\n        var fileext = file.name ? file.name.substr(file.name.lastIndexOf('.')):'';\n        if ((fileext && filetype != 'image') || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) {\n            errorHandler(me.getLang('autoupload.exceedTypeError'));\n            return;\n        }\n\n        /* 创建Ajax并提交 */\n        var xhr = new XMLHttpRequest(),\n            fd = new FormData(),\n            params = utils.serializeParam(me.queryCommandValue('serverparam')) || '',\n            url = utils.formatUrl(actionUrl + (actionUrl.indexOf('?') == -1 ? '?':'&') + params);\n\n        fd.append(fieldName, file, file.name || ('blob.' + file.type.substr('image/'.length)));\n        fd.append('type', 'ajax');\n        xhr.open(\"post\", url, true);\n        xhr.setRequestHeader(\"X-Requested-With\", \"XMLHttpRequest\");\n        xhr.addEventListener('load', function (e) {\n            try{\n                var json = (new Function(\"return \" + utils.trim(e.target.response)))();\n                if (json.state == 'SUCCESS' && json.url) {\n                    successHandler(json);\n                } else {\n                    errorHandler(json.state);\n                }\n            }catch(er){\n                errorHandler(me.getLang('autoupload.loadError'));\n            }\n        });\n        xhr.send(fd);\n    }\n\n    function getPasteImage(e){\n        return e.clipboardData && e.clipboardData.items && e.clipboardData.items.length == 1 && /^image\\//.test(e.clipboardData.items[0].type) ? e.clipboardData.items:null;\n    }\n    function getDropImage(e){\n        return  e.dataTransfer && e.dataTransfer.files ? e.dataTransfer.files:null;\n    }\n\n    return {\n        outputRule: function(root){\n            utils.each(root.getNodesByTagName('img'),function(n){\n                if (/\\b(loaderrorclass)|(bloaderrorclass)\\b/.test(n.getAttr('class'))) {\n                    n.parentNode.removeChild(n);\n                }\n            });\n            utils.each(root.getNodesByTagName('p'),function(n){\n                if (/\\bloadpara\\b/.test(n.getAttr('class'))) {\n                    n.parentNode.removeChild(n);\n                }\n            });\n        },\n        bindEvents:{\n            //插入粘贴板的图片，拖放插入图片\n            'ready':function(e){\n                var me = this;\n                if(window.FormData && window.FileReader) {\n                    domUtils.on(me.body, 'paste drop', function(e){\n                        var hasImg = false,\n                            items;\n                        //获取粘贴板文件列表或者拖放文件列表\n                        items = e.type == 'paste' ? getPasteImage(e):getDropImage(e);\n                        if(items){\n                            var len = items.length,\n                                file;\n                            while (len--){\n                                file = items[len];\n                                if(file.getAsFile) file = file.getAsFile();\n                                if(file && file.size > 0) {\n                                    sendAndInsertFile(file, me);\n                                    hasImg = true;\n                                }\n                            }\n                            hasImg && e.preventDefault();\n                        }\n\n                    });\n                    //取消拖放图片时出现的文字光标位置提示\n                    domUtils.on(me.body, 'dragover', function (e) {\n                        if(e.dataTransfer.types[0] == 'Files') {\n                            e.preventDefault();\n                        }\n                    });\n\n                    //设置loading的样式\n                    utils.cssRule('loading',\n                        '.loadingclass{display:inline-block;cursor:default;background: url(\\''\n                            + this.options.themePath\n                            + this.options.theme +'/images/loading.gif\\') no-repeat center center transparent;border:1px solid #cccccc;margin-left:1px;height: 22px;width: 22px;}\\n' +\n                            '.loaderrorclass{display:inline-block;cursor:default;background: url(\\''\n                            + this.options.themePath\n                            + this.options.theme +'/images/loaderror.png\\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;' +\n                            '}',\n                        this.document);\n                }\n            }\n        }\n    }\n});\n\n// plugins/autosave.js\nUE.plugin.register('autosave', function (){\n\n    var me = this,\n        //无限循环保护\n        lastSaveTime = new Date(),\n        //最小保存间隔时间\n        MIN_TIME = 20,\n        //auto save key\n        saveKey = null;\n\n    function save ( editor ) {\n\n        var saveData;\n\n        if ( new Date() - lastSaveTime < MIN_TIME ) {\n            return;\n        }\n\n        if ( !editor.hasContents() ) {\n            //这里不能调用命令来删除， 会造成事件死循环\n            saveKey && me.removePreferences( saveKey );\n            return;\n        }\n\n        lastSaveTime = new Date();\n\n        editor._saveFlag = null;\n\n        saveData = me.body.innerHTML;\n\n        if ( editor.fireEvent( \"beforeautosave\", {\n            content: saveData\n        } ) === false ) {\n            return;\n        }\n\n        me.setPreferences( saveKey, saveData );\n\n        editor.fireEvent( \"afterautosave\", {\n            content: saveData\n        } );\n\n    }\n\n    return {\n        defaultOptions: {\n            //默认间隔时间\n            saveInterval: 500\n        },\n        bindEvents:{\n            'ready':function(){\n\n                var _suffix = \"-drafts-data\",\n                    key = null;\n\n                if ( me.key ) {\n                    key = me.key + _suffix;\n                } else {\n                    key = ( me.container.parentNode.id || 'ue-common' ) + _suffix;\n                }\n\n                //页面地址+编辑器ID 保持唯一\n                saveKey = ( location.protocol + location.host + location.pathname ).replace( /[.:\\/]/g, '_' ) + key;\n\n            },\n\n            'contentchange': function () {\n\n                if ( !saveKey ) {\n                    return;\n                }\n\n                if ( me._saveFlag ) {\n                    window.clearTimeout( me._saveFlag );\n                }\n\n                if ( me.options.saveInterval > 0 ) {\n\n                    me._saveFlag = window.setTimeout( function () {\n\n                        save( me );\n\n                    }, me.options.saveInterval );\n\n                } else {\n\n                    save(me);\n\n                }\n\n\n            }\n        },\n        commands:{\n            'clearlocaldata':{\n                execCommand:function (cmd, name) {\n                    if ( saveKey && me.getPreferences( saveKey ) ) {\n                        me.removePreferences( saveKey )\n                    }\n                },\n                notNeedUndo: true,\n                ignoreContentChange:true\n            },\n\n            'getlocaldata':{\n                execCommand:function (cmd, name) {\n                    return saveKey ? me.getPreferences( saveKey ) || '' : '';\n                },\n                notNeedUndo: true,\n                ignoreContentChange:true\n            },\n\n            'drafts':{\n                execCommand:function (cmd, name) {\n                    if ( saveKey ) {\n                        me.body.innerHTML = me.getPreferences( saveKey ) || '<p>'+domUtils.fillHtml+'</p>';\n                        me.focus(true);\n                    }\n                },\n                queryCommandState: function () {\n                    return saveKey ? ( me.getPreferences( saveKey ) === null ? -1 : 0 ) : -1;\n                },\n                notNeedUndo: true,\n                ignoreContentChange:true\n            }\n        }\n    }\n\n});\n\n// plugins/charts.js\nUE.plugin.register('charts', function (){\n\n    var me = this;\n\n    return {\n        bindEvents: {\n            'chartserror': function () {\n            }\n        },\n        commands:{\n            'charts': {\n                execCommand: function ( cmd, data ) {\n\n                    var tableNode = domUtils.findParentByTagName(this.selection.getRange().startContainer, 'table', true),\n                        flagText = [],\n                        config = {};\n\n                    if ( !tableNode ) {\n                        return false;\n                    }\n\n                    if ( !validData( tableNode ) ) {\n                        me.fireEvent( \"chartserror\" );\n                        return false;\n                    }\n\n                    config.title = data.title || '';\n                    config.subTitle = data.subTitle || '';\n                    config.xTitle = data.xTitle || '';\n                    config.yTitle = data.yTitle || '';\n                    config.suffix = data.suffix || '';\n                    config.tip = data.tip || '';\n                    //数据对齐方式\n                    config.dataFormat = data.tableDataFormat || '';\n                    //图表类型\n                    config.chartType = data.chartType || 0;\n\n                    for ( var key in config ) {\n\n                        if ( !config.hasOwnProperty( key ) ) {\n                            continue;\n                        }\n\n                        flagText.push( key+\":\"+config[ key ] );\n\n                    }\n\n                    tableNode.setAttribute( \"data-chart\", flagText.join( \";\" ) );\n                    domUtils.addClass( tableNode, \"edui-charts-table\" );\n\n\n\n                },\n                queryCommandState: function ( cmd, name ) {\n\n                    var tableNode = domUtils.findParentByTagName(this.selection.getRange().startContainer, 'table', true);\n                    return tableNode && validData( tableNode ) ? 0 : -1;\n\n                }\n            }\n        },\n        inputRule:function(root){\n            utils.each(root.getNodesByTagName('table'),function( tableNode ){\n\n                if ( tableNode.getAttr(\"data-chart\") !== undefined ) {\n                    tableNode.setAttr(\"style\");\n                }\n\n            })\n\n        },\n        outputRule:function(root){\n            utils.each(root.getNodesByTagName('table'),function( tableNode ){\n\n                if ( tableNode.getAttr(\"data-chart\") !== undefined ) {\n                    tableNode.setAttr(\"style\", \"display: none;\");\n                }\n\n            })\n\n        }\n    }\n\n    function validData ( table ) {\n\n        var firstRows = null,\n            cellCount = 0;\n\n        //行数不够\n        if ( table.rows.length < 2 ) {\n            return false;\n        }\n\n        //列数不够\n        if ( table.rows[0].cells.length < 2 ) {\n            return false;\n        }\n\n        //第一行所有cell必须是th\n        firstRows = table.rows[ 0 ].cells;\n        cellCount = firstRows.length;\n\n        for ( var i = 0, cell; cell = firstRows[ i ]; i++ ) {\n\n            if ( cell.tagName.toLowerCase() !== 'th' ) {\n                return false;\n            }\n\n        }\n\n        for ( var i = 1, row; row = table.rows[ i ]; i++ ) {\n\n            //每行单元格数不匹配， 返回false\n            if ( row.cells.length != cellCount ) {\n                return false;\n            }\n\n            //第一列不是th也返回false\n            if ( row.cells[0].tagName.toLowerCase() !== 'th' ) {\n                return false;\n            }\n\n            for ( var j = 1, cell; cell = row.cells[ j ]; j++ ) {\n\n                var value = utils.trim( ( cell.innerText || cell.textContent || '' ) );\n\n                value = value.replace( new RegExp( UE.dom.domUtils.fillChar, 'g' ), '' ).replace( /^\\s+|\\s+$/g, '' );\n\n                //必须是数字\n                if ( !/^\\d*\\.?\\d+$/.test( value ) ) {\n                    return false;\n                }\n\n            }\n\n        }\n\n        return true;\n\n    }\n\n});\n\n// plugins/section.js\n/**\n * 目录大纲支持插件\n * @file\n * @since 1.3.0\n */\nUE.plugin.register('section', function (){\n    /* 目录节点对象 */\n    function Section(option){\n        this.tag = '';\n        this.level = -1,\n            this.dom = null;\n        this.nextSection = null;\n        this.previousSection = null;\n        this.parentSection = null;\n        this.startAddress = [];\n        this.endAddress = [];\n        this.children = [];\n    }\n    function getSection(option) {\n        var section = new Section();\n        return utils.extend(section, option);\n    }\n    function getNodeFromAddress(startAddress, root) {\n        var current = root;\n        for(var i = 0;i < startAddress.length; i++) {\n            if(!current.childNodes) return null;\n            current = current.childNodes[startAddress[i]];\n        }\n        return current;\n    }\n\n    var me = this;\n\n    return {\n        bindMultiEvents:{\n            type: 'aftersetcontent afterscencerestore',\n            handler: function(){\n                me.fireEvent('updateSections');\n            }\n        },\n        bindEvents:{\n            /* 初始化、拖拽、粘贴、执行setcontent之后 */\n            'ready': function (){\n                me.fireEvent('updateSections');\n                domUtils.on(me.body, 'drop paste', function(){\n                    me.fireEvent('updateSections');\n                });\n            },\n            /* 执行paragraph命令之后 */\n            'afterexeccommand': function (type, cmd) {\n                if(cmd == 'paragraph') {\n                    me.fireEvent('updateSections');\n                }\n            },\n            /* 部分键盘操作，触发updateSections事件 */\n            'keyup': function (type, e) {\n                var me = this,\n                    range = me.selection.getRange();\n                if(range.collapsed != true) {\n                    me.fireEvent('updateSections');\n                } else {\n                    var keyCode = e.keyCode || e.which;\n                    if(keyCode == 13 || keyCode == 8 || keyCode == 46) {\n                        me.fireEvent('updateSections');\n                    }\n                }\n            }\n        },\n        commands:{\n            'getsections': {\n                execCommand: function (cmd, levels) {\n                    var levelFn = levels || ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];\n\n                    for (var i = 0; i < levelFn.length; i++) {\n                        if (typeof levelFn[i] == 'string') {\n                            levelFn[i] = function(fn){\n                                return function(node){\n                                    return node.tagName == fn.toUpperCase()\n                                };\n                            }(levelFn[i]);\n                        } else if (typeof levelFn[i] != 'function') {\n                            levelFn[i] = function (node) {\n                                return null;\n                            }\n                        }\n                    }\n                    function getSectionLevel(node) {\n                        for (var i = 0; i < levelFn.length; i++) {\n                            if (levelFn[i](node)) return i;\n                        }\n                        return -1;\n                    }\n\n                    var me = this,\n                        Directory = getSection({'level':-1, 'title':'root'}),\n                        previous = Directory;\n\n                    function traversal(node, Directory) {\n                        var level,\n                            tmpSection = null,\n                            parent,\n                            child,\n                            children = node.childNodes;\n                        for (var i = 0, len = children.length; i < len; i++) {\n                            child = children[i];\n                            level = getSectionLevel(child);\n                            if (level >= 0) {\n                                var address = me.selection.getRange().selectNode(child).createAddress(true).startAddress,\n                                    current = getSection({\n                                        'tag': child.tagName,\n                                        'title': child.innerText || child.textContent || '',\n                                        'level': level,\n                                        'dom': child,\n                                        'startAddress': utils.clone(address, []),\n                                        'endAddress': utils.clone(address, []),\n                                        'children': []\n                                    });\n                                previous.nextSection = current;\n                                current.previousSection = previous;\n                                parent = previous;\n                                while(level <= parent.level){\n                                    parent = parent.parentSection;\n                                }\n                                current.parentSection = parent;\n                                parent.children.push(current);\n                                tmpSection = previous = current;\n                            } else {\n                                child.nodeType === 1 && traversal(child, Directory);\n                                tmpSection && tmpSection.endAddress[tmpSection.endAddress.length - 1] ++;\n                            }\n                        }\n                    }\n                    traversal(me.body, Directory);\n                    return Directory;\n                },\n                notNeedUndo: true\n            },\n            'movesection': {\n                execCommand: function (cmd, sourceSection, targetSection, isAfter) {\n\n                    var me = this,\n                        targetAddress,\n                        target;\n\n                    if(!sourceSection || !targetSection || targetSection.level == -1) return;\n\n                    targetAddress = isAfter ? targetSection.endAddress:targetSection.startAddress;\n                    target = getNodeFromAddress(targetAddress, me.body);\n\n                    /* 判断目标地址是否被源章节包含 */\n                    if(!targetAddress || !target || isContainsAddress(sourceSection.startAddress, sourceSection.endAddress, targetAddress)) return;\n\n                    var startNode = getNodeFromAddress(sourceSection.startAddress, me.body),\n                        endNode = getNodeFromAddress(sourceSection.endAddress, me.body),\n                        current,\n                        nextNode;\n\n                    if(isAfter) {\n                        current = endNode;\n                        while ( current && !(domUtils.getPosition( startNode, current ) & domUtils.POSITION_FOLLOWING) ) {\n                            nextNode = current.previousSibling;\n                            domUtils.insertAfter(target, current);\n                            if(current == startNode) break;\n                            current = nextNode;\n                        }\n                    } else {\n                        current = startNode;\n                        while ( current && !(domUtils.getPosition( current, endNode ) & domUtils.POSITION_FOLLOWING) ) {\n                            nextNode = current.nextSibling;\n                            target.parentNode.insertBefore(current, target);\n                            if(current == endNode) break;\n                            current = nextNode;\n                        }\n                    }\n\n                    me.fireEvent('updateSections');\n\n                    /* 获取地址的包含关系 */\n                    function isContainsAddress(startAddress, endAddress, addressTarget){\n                        var isAfterStartAddress = false,\n                            isBeforeEndAddress = false;\n                        for(var i = 0; i< startAddress.length; i++){\n                            if(i >= addressTarget.length) break;\n                            if(addressTarget[i] > startAddress[i]) {\n                                isAfterStartAddress = true;\n                                break;\n                            } else if(addressTarget[i] < startAddress[i]) {\n                                break;\n                            }\n                        }\n                        for(var i = 0; i< endAddress.length; i++){\n                            if(i >= addressTarget.length) break;\n                            if(addressTarget[i] < startAddress[i]) {\n                                isBeforeEndAddress = true;\n                                break;\n                            } else if(addressTarget[i] > startAddress[i]) {\n                                break;\n                            }\n                        }\n                        return isAfterStartAddress && isBeforeEndAddress;\n                    }\n                }\n            },\n            'deletesection': {\n                execCommand: function (cmd, section, keepChildren) {\n                    var me = this;\n\n                    if(!section) return;\n\n                    function getNodeFromAddress(startAddress) {\n                        var current = me.body;\n                        for(var i = 0;i < startAddress.length; i++) {\n                            if(!current.childNodes) return null;\n                            current = current.childNodes[startAddress[i]];\n                        }\n                        return current;\n                    }\n\n                    var startNode = getNodeFromAddress(section.startAddress),\n                        endNode = getNodeFromAddress(section.endAddress),\n                        current = startNode,\n                        nextNode;\n\n                    if(!keepChildren) {\n                        while ( current && domUtils.inDoc(endNode, me.document) && !(domUtils.getPosition( current, endNode ) & domUtils.POSITION_FOLLOWING) ) {\n                            nextNode = current.nextSibling;\n                            domUtils.remove(current);\n                            current = nextNode;\n                        }\n                    } else {\n                        domUtils.remove(current);\n                    }\n\n                    me.fireEvent('updateSections');\n                }\n            },\n            'selectsection': {\n                execCommand: function (cmd, section) {\n                    if(!section && !section.dom) return false;\n                    var me = this,\n                        range = me.selection.getRange(),\n                        address = {\n                            'startAddress':utils.clone(section.startAddress, []),\n                            'endAddress':utils.clone(section.endAddress, [])\n                        };\n                    address.endAddress[address.endAddress.length - 1]++;\n                    range.moveToAddress(address).select().scrollToView();\n                    return true;\n                },\n                notNeedUndo: true\n            },\n            'scrolltosection': {\n                execCommand: function (cmd, section) {\n                    if(!section && !section.dom) return false;\n                    var me = this,\n                        range = me.selection.getRange(),\n                        address = {\n                            'startAddress':section.startAddress,\n                            'endAddress':section.endAddress\n                        };\n                    address.endAddress[address.endAddress.length - 1]++;\n                    range.moveToAddress(address).scrollToView();\n                    return true;\n                },\n                notNeedUndo: true\n            }\n        }\n    }\n});\n\n// plugins/simpleupload.js\n/**\n * @description\n * 简单上传:点击按钮,直接选择文件上传\n * @author Jinqn\n * @date 2014-03-31\n */\nUE.plugin.register('simpleupload', function (){\n    var me = this,\n        isLoaded = false,\n        containerBtn;\n\n    function initUploadBtn(){\n        var w = containerBtn.offsetWidth || 20,\n            h = containerBtn.offsetHeight || 20,\n            btnIframe = document.createElement('iframe'),\n            btnStyle = 'display:block;width:' + w + 'px;height:' + h + 'px;overflow:hidden;border:0;margin:0;padding:0;position:absolute;top:0;left:0;filter:alpha(opacity=0);-moz-opacity:0;-khtml-opacity: 0;opacity: 0;cursor:pointer;';\n\n        domUtils.on(btnIframe, 'load', function(){\n\n            var timestrap = (+new Date()).toString(36),\n                wrapper,\n                btnIframeDoc,\n                btnIframeBody;\n\n            btnIframeDoc = (btnIframe.contentDocument || btnIframe.contentWindow.document);\n            btnIframeBody = btnIframeDoc.body;\n            wrapper = btnIframeDoc.createElement('div');\n\n            wrapper.innerHTML = '<form id=\"edui_form_' + timestrap + '\" target=\"edui_iframe_' + timestrap + '\" method=\"POST\" enctype=\"multipart/form-data\" action=\"' + me.getOpt('serverUrl') + '\" ' +\n            'style=\"' + btnStyle + '\">' +\n            '<input id=\"edui_input_' + timestrap + '\" type=\"file\" accept=\"image/*\" name=\"' + me.options.imageFieldName + '\" ' +\n            'style=\"' + btnStyle + '\">' +\n            '</form>' +\n            '<iframe id=\"edui_iframe_' + timestrap + '\" name=\"edui_iframe_' + timestrap + '\" style=\"display:none;width:0;height:0;border:0;margin:0;padding:0;position:absolute;\"></iframe>';\n\n            wrapper.className = 'edui-' + me.options.theme;\n            wrapper.id = me.ui.id + '_iframeupload';\n            btnIframeBody.style.cssText = btnStyle;\n            btnIframeBody.style.width = w + 'px';\n            btnIframeBody.style.height = h + 'px';\n            btnIframeBody.appendChild(wrapper);\n\n            if (btnIframeBody.parentNode) {\n                btnIframeBody.parentNode.style.width = w + 'px';\n                btnIframeBody.parentNode.style.height = w + 'px';\n            }\n\n            var form = btnIframeDoc.getElementById('edui_form_' + timestrap);\n            var input = btnIframeDoc.getElementById('edui_input_' + timestrap);\n            var iframe = btnIframeDoc.getElementById('edui_iframe_' + timestrap);\n\n            domUtils.on(input, 'change', function(){\n                if(!input.value) return;\n                var loadingId = 'loading_' + (+new Date()).toString(36);\n                var params = utils.serializeParam(me.queryCommandValue('serverparam')) || '';\n\n                var imageActionUrl = me.getActionUrl(me.getOpt('imageActionName'));\n                var allowFiles = me.getOpt('imageAllowFiles');\n\n                me.focus();\n                me.execCommand('inserthtml', '<img class=\"loadingclass\" id=\"' + loadingId + '\" src=\"' + me.options.themePath + me.options.theme +'/images/spacer.gif\" title=\"' + (me.getLang('simpleupload.loading') || '') + '\" >');\n\n                function callback(){\n                    try{\n                        var link, json, loader,\n                            body = (iframe.contentDocument || iframe.contentWindow.document).body,\n                            result = body.innerText || body.textContent || '';\n                        json = (new Function(\"return \" + result))();\n                        link = me.options.imageUrlPrefix + json.url;\n                        if(json.state == 'SUCCESS' && json.url) {\n                            loader = me.document.getElementById(loadingId);\n                            loader.setAttribute('src', link);\n                            loader.setAttribute('_src', link);\n                            loader.setAttribute('title', json.title || '');\n                            loader.setAttribute('alt', json.original || '');\n                            loader.removeAttribute('id');\n                            domUtils.removeClasses(loader, 'loadingclass');\n                        } else {\n                            showErrorLoader && showErrorLoader(json.state);\n                        }\n                    }catch(er){\n                        showErrorLoader && showErrorLoader(me.getLang('simpleupload.loadError'));\n                    }\n                    form.reset();\n                    domUtils.un(iframe, 'load', callback);\n                }\n                function showErrorLoader(title){\n                    if(loadingId) {\n                        var loader = me.document.getElementById(loadingId);\n                        loader && domUtils.remove(loader);\n                        me.fireEvent('showmessage', {\n                            'id': loadingId,\n                            'content': title,\n                            'type': 'error',\n                            'timeout': 4000\n                        });\n                    }\n                }\n\n                /* 判断后端配置是否没有加载成功 */\n                if (!me.getOpt('imageActionName')) {\n                    errorHandler(me.getLang('autoupload.errorLoadConfig'));\n                    return;\n                }\n                // 判断文件格式是否错误\n                var filename = input.value,\n                    fileext = filename ? filename.substr(filename.lastIndexOf('.')):'';\n                if (!fileext || (allowFiles && (allowFiles.join('') + '.').indexOf(fileext.toLowerCase() + '.') == -1)) {\n                    showErrorLoader(me.getLang('simpleupload.exceedTypeError'));\n                    return;\n                }\n\n                domUtils.on(iframe, 'load', callback);\n                form.action = utils.formatUrl(imageActionUrl + (imageActionUrl.indexOf('?') == -1 ? '?':'&') + params);\n                form.submit();\n            });\n\n            var stateTimer;\n            me.addListener('selectionchange', function () {\n                clearTimeout(stateTimer);\n                stateTimer = setTimeout(function() {\n                    var state = me.queryCommandState('simpleupload');\n                    if (state == -1) {\n                        input.disabled = 'disabled';\n                    } else {\n                        input.disabled = false;\n                    }\n                }, 400);\n            });\n            isLoaded = true;\n        });\n\n        btnIframe.style.cssText = btnStyle;\n        containerBtn.appendChild(btnIframe);\n    }\n\n    return {\n        bindEvents:{\n            'ready': function() {\n                //设置loading的样式\n                utils.cssRule('loading',\n                    '.loadingclass{display:inline-block;cursor:default;background: url(\\''\n                    + this.options.themePath\n                    + this.options.theme +'/images/loading.gif\\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;}\\n' +\n                    '.loaderrorclass{display:inline-block;cursor:default;background: url(\\''\n                    + this.options.themePath\n                    + this.options.theme +'/images/loaderror.png\\') no-repeat center center transparent;border:1px solid #cccccc;margin-right:1px;height: 22px;width: 22px;' +\n                    '}',\n                    this.document);\n            },\n            /* 初始化简单上传按钮 */\n            'simpleuploadbtnready': function(type, container) {\n                containerBtn = container;\n                me.afterConfigReady(initUploadBtn);\n            }\n        },\n        outputRule: function(root){\n            utils.each(root.getNodesByTagName('img'),function(n){\n                if (/\\b(loaderrorclass)|(bloaderrorclass)\\b/.test(n.getAttr('class'))) {\n                    n.parentNode.removeChild(n);\n                }\n            });\n        },\n        commands: {\n            'simpleupload': {\n                queryCommandState: function () {\n                    return isLoaded ? 0:-1;\n                }\n            }\n        }\n    }\n});\n\n// plugins/serverparam.js\n/**\n * 服务器提交的额外参数列表设置插件\n * @file\n * @since 1.2.6.1\n */\nUE.plugin.register('serverparam', function (){\n\n    var me = this,\n        serverParam = {};\n\n    return {\n        commands:{\n            /**\n             * 修改服务器提交的额外参数列表,清除所有项\n             * @command serverparam\n             * @method execCommand\n             * @param { String } cmd 命令字符串\n             * @example\n             * ```javascript\n             * editor.execCommand('serverparam');\n             * editor.queryCommandValue('serverparam'); //返回空\n             * ```\n             */\n            /**\n             * 修改服务器提交的额外参数列表,删除指定项\n             * @command serverparam\n             * @method execCommand\n             * @param { String } cmd 命令字符串\n             * @param { String } key 要清除的属性\n             * @example\n             * ```javascript\n             * editor.execCommand('serverparam', 'name'); //删除属性name\n             * ```\n             */\n            /**\n             * 修改服务器提交的额外参数列表,使用键值添加项\n             * @command serverparam\n             * @method execCommand\n             * @param { String } cmd 命令字符串\n             * @param { String } key 要添加的属性\n             * @param { String } value 要添加属性的值\n             * @example\n             * ```javascript\n             * editor.execCommand('serverparam', 'name', 'hello');\n             * editor.queryCommandValue('serverparam'); //返回对象 {'name': 'hello'}\n             * ```\n             */\n            /**\n             * 修改服务器提交的额外参数列表,传入键值对对象添加多项\n             * @command serverparam\n             * @method execCommand\n             * @param { String } cmd 命令字符串\n             * @param { Object } key 传入的键值对对象\n             * @example\n             * ```javascript\n             * editor.execCommand('serverparam', {'name': 'hello'});\n             * editor.queryCommandValue('serverparam'); //返回对象 {'name': 'hello'}\n             * ```\n             */\n            /**\n             * 修改服务器提交的额外参数列表,使用自定义函数添加多项\n             * @command serverparam\n             * @method execCommand\n             * @param { String } cmd 命令字符串\n             * @param { Function } key 自定义获取参数的函数\n             * @example\n             * ```javascript\n             * editor.execCommand('serverparam', function(editor){\n             *     return {'key': 'value'};\n             * });\n             * editor.queryCommandValue('serverparam'); //返回对象 {'key': 'value'}\n             * ```\n             */\n\n            /**\n             * 获取服务器提交的额外参数列表\n             * @command serverparam\n             * @method queryCommandValue\n             * @param { String } cmd 命令字符串\n             * @example\n             * ```javascript\n             * editor.queryCommandValue( 'serverparam' ); //返回对象 {'key': 'value'}\n             * ```\n             */\n            'serverparam':{\n                execCommand:function (cmd, key, value) {\n                    if (key === undefined || key === null) { //不传参数,清空列表\n                        serverParam = {};\n                    } else if (utils.isString(key)) { //传入键值\n                        if(value === undefined || value === null) {\n                            delete serverParam[key];\n                        } else {\n                            serverParam[key] = value;\n                        }\n                    } else if (utils.isObject(key)) { //传入对象,覆盖列表项\n                        utils.extend(serverParam, key, true);\n                    } else if (utils.isFunction(key)){ //传入函数,添加列表项\n                        utils.extend(serverParam, key(), true);\n                    }\n                },\n                queryCommandValue: function(){\n                    return serverParam || {};\n                }\n            }\n        }\n    }\n});\n\n\n// plugins/insertfile.js\n/**\n * 插入附件\n */\nUE.plugin.register('insertfile', function (){\n\n    var me = this;\n\n    function getFileIcon(url){\n        var ext = url.substr(url.lastIndexOf('.') + 1).toLowerCase(),\n            maps = {\n                \"rar\":\"icon_rar.gif\",\n                \"zip\":\"icon_rar.gif\",\n                \"tar\":\"icon_rar.gif\",\n                \"gz\":\"icon_rar.gif\",\n                \"bz2\":\"icon_rar.gif\",\n                \"doc\":\"icon_doc.gif\",\n                \"docx\":\"icon_doc.gif\",\n                \"pdf\":\"icon_pdf.gif\",\n                \"mp3\":\"icon_mp3.gif\",\n                \"xls\":\"icon_xls.gif\",\n                \"chm\":\"icon_chm.gif\",\n                \"ppt\":\"icon_ppt.gif\",\n                \"pptx\":\"icon_ppt.gif\",\n                \"avi\":\"icon_mv.gif\",\n                \"rmvb\":\"icon_mv.gif\",\n                \"wmv\":\"icon_mv.gif\",\n                \"flv\":\"icon_mv.gif\",\n                \"swf\":\"icon_mv.gif\",\n                \"rm\":\"icon_mv.gif\",\n                \"exe\":\"icon_exe.gif\",\n                \"psd\":\"icon_psd.gif\",\n                \"txt\":\"icon_txt.gif\",\n                \"jpg\":\"icon_jpg.gif\",\n                \"png\":\"icon_jpg.gif\",\n                \"jpeg\":\"icon_jpg.gif\",\n                \"gif\":\"icon_jpg.gif\",\n                \"ico\":\"icon_jpg.gif\",\n                \"bmp\":\"icon_jpg.gif\"\n            };\n        return maps[ext] ? maps[ext]:maps['txt'];\n    }\n\n    return {\n        commands:{\n            'insertfile': {\n                execCommand: function (command, filelist){\n                    filelist = utils.isArray(filelist) ? filelist : [filelist];\n\n                    var i, item, icon, title,\n                        html = '',\n                        URL = me.getOpt('UEDITOR_HOME_URL'),\n                        iconDir = URL + (URL.substr(URL.length - 1) == '/' ? '':'/') + 'dialogs/attachment/fileTypeImages/';\n                    for (i = 0; i < filelist.length; i++) {\n                        item = filelist[i];\n                        icon = iconDir + getFileIcon(item.url);\n                        title = item.title || item.url.substr(item.url.lastIndexOf('/') + 1);\n                        html += '<p style=\"line-height: 16px;\">' +\n                            '<img style=\"vertical-align: middle; margin-right: 2px;\" src=\"'+ icon + '\" _src=\"' + icon + '\" />' +\n                            '<a style=\"font-size:12px; color:#0066cc;\" href=\"' + item.url +'\" title=\"' + title + '\">' + title + '</a>' +\n                            '</p>';\n                    }\n                    me.execCommand('insertHtml', html);\n                }\n            }\n        }\n    }\n});\n\n\n\n\n// plugins/xssFilter.js\n/**\n * @file xssFilter.js\n * @desc xss过滤器\n * @author robbenmu\n */\n\nUE.plugins.xssFilter = function() {\n\n\tvar config = UEDITOR_CONFIG;\n\tvar whitList = config.whitList;\n\n\tfunction filter(node) {\n\n\t\tvar tagName = node.tagName;\n\t\tvar attrs = node.attrs;\n\n\t\tif (!whitList.hasOwnProperty(tagName)) {\n\t\t\tnode.parentNode.removeChild(node);\n\t\t\treturn false;\n\t\t}\n\n\t\tUE.utils.each(attrs, function (val, key) {\n\n\t\t\tif (whitList[tagName].indexOf(key) === -1) {\n\t\t\t\tnode.setAttr(key);\n\t\t\t}\n\t\t});\n\t}\n\n\t// 添加inserthtml\\paste等操作用的过滤规则\n\tif (whitList && config.xssFilterRules) {\n\t\tthis.options.filterRules = function () {\n\n\t\t\tvar result = {};\n\n\t\t\tUE.utils.each(whitList, function(val, key) {\n\t\t\t\tresult[key] = function (node) {\n\t\t\t\t\treturn filter(node);\n\t\t\t\t};\n\t\t\t});\n\n\t\t\treturn result;\n\t\t}();\n\t}\n\n\tvar tagList = [];\n\n\tUE.utils.each(whitList, function (val, key) {\n\t\ttagList.push(key);\n\t});\n\n\t// 添加input过滤规则\n\t//\n\tif (whitList && config.inputXssFilter) {\n\t\tthis.addInputRule(function (root) {\n\n\t\t\troot.traversal(function(node) {\n\t\t\t\tif (node.type !== 'element') {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tfilter(node);\n\t\t\t});\n\t\t});\n\t}\n\t// 添加output过滤规则\n\t//\n\tif (whitList && config.outputXssFilter) {\n\t\tthis.addOutputRule(function (root) {\n\n\t\t\troot.traversal(function(node) {\n\t\t\t\tif (node.type !== 'element') {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tfilter(node);\n\t\t\t});\n\t\t});\n\t}\n\n};\n\n\n// ui/ui.js\nvar baidu = baidu || {};\r\nbaidu.editor = baidu.editor || {};\r\nUE.ui = baidu.editor.ui = {};\n\n// ui/uiutils.js\n(function (){\r\n    var browser = baidu.editor.browser,\r\n        domUtils = baidu.editor.dom.domUtils;\r\n\r\n    var magic = '$EDITORUI';\r\n    var root = window[magic] = {};\r\n    var uidMagic = 'ID' + magic;\r\n    var uidCount = 0;\r\n\r\n    var uiUtils = baidu.editor.ui.uiUtils = {\r\n        uid: function (obj){\r\n            return (obj ? obj[uidMagic] || (obj[uidMagic] = ++ uidCount) : ++ uidCount);\r\n        },\r\n        hook: function ( fn, callback ) {\r\n            var dg;\r\n            if (fn && fn._callbacks) {\r\n                dg = fn;\r\n            } else {\r\n                dg = function (){\r\n                    var q;\r\n                    if (fn) {\r\n                        q = fn.apply(this, arguments);\r\n                    }\r\n                    var callbacks = dg._callbacks;\r\n                    var k = callbacks.length;\r\n                    while (k --) {\r\n                        var r = callbacks[k].apply(this, arguments);\r\n                        if (q === undefined) {\r\n                            q = r;\r\n                        }\r\n                    }\r\n                    return q;\r\n                };\r\n                dg._callbacks = [];\r\n            }\r\n            dg._callbacks.push(callback);\r\n            return dg;\r\n        },\r\n        createElementByHtml: function (html){\r\n            var el = document.createElement('div');\r\n            el.innerHTML = html;\r\n            el = el.firstChild;\r\n            el.parentNode.removeChild(el);\r\n            return el;\r\n        },\r\n        getViewportElement: function (){\r\n            return (browser.ie && browser.quirks) ?\r\n                document.body : document.documentElement;\r\n        },\r\n        getClientRect: function (element){\r\n            var bcr;\r\n            //trace  IE6下在控制编辑器显隐时可能会报错，catch一下\r\n            try{\r\n                bcr = element.getBoundingClientRect();\r\n            }catch(e){\r\n                bcr={left:0,top:0,height:0,width:0}\r\n            }\r\n            var rect = {\r\n                left: Math.round(bcr.left),\r\n                top: Math.round(bcr.top),\r\n                height: Math.round(bcr.bottom - bcr.top),\r\n                width: Math.round(bcr.right - bcr.left)\r\n            };\r\n            var doc;\r\n            while ((doc = element.ownerDocument) !== document &&\r\n                (element = domUtils.getWindow(doc).frameElement)) {\r\n                bcr = element.getBoundingClientRect();\r\n                rect.left += bcr.left;\r\n                rect.top += bcr.top;\r\n            }\r\n            rect.bottom = rect.top + rect.height;\r\n            rect.right = rect.left + rect.width;\r\n            return rect;\r\n        },\r\n        getViewportRect: function (){\r\n            var viewportEl = uiUtils.getViewportElement();\r\n            var width = (window.innerWidth || viewportEl.clientWidth) | 0;\r\n            var height = (window.innerHeight ||viewportEl.clientHeight) | 0;\r\n            return {\r\n                left: 0,\r\n                top: 0,\r\n                height: height,\r\n                width: width,\r\n                bottom: height,\r\n                right: width\r\n            };\r\n        },\r\n        setViewportOffset: function (element, offset){\r\n            var rect;\r\n            var fixedLayer = uiUtils.getFixedLayer();\r\n            if (element.parentNode === fixedLayer) {\r\n                element.style.left = offset.left + 'px';\r\n                element.style.top = offset.top + 'px';\r\n            } else {\r\n                domUtils.setViewportOffset(element, offset);\r\n            }\r\n        },\r\n        getEventOffset: function (evt){\r\n            var el = evt.target || evt.srcElement;\r\n            var rect = uiUtils.getClientRect(el);\r\n            var offset = uiUtils.getViewportOffsetByEvent(evt);\r\n            return {\r\n                left: offset.left - rect.left,\r\n                top: offset.top - rect.top\r\n            };\r\n        },\r\n        getViewportOffsetByEvent: function (evt){\r\n            var el = evt.target || evt.srcElement;\r\n            var frameEl = domUtils.getWindow(el).frameElement;\r\n            var offset = {\r\n                left: evt.clientX,\r\n                top: evt.clientY\r\n            };\r\n            if (frameEl && el.ownerDocument !== document) {\r\n                var rect = uiUtils.getClientRect(frameEl);\r\n                offset.left += rect.left;\r\n                offset.top += rect.top;\r\n            }\r\n            return offset;\r\n        },\r\n        setGlobal: function (id, obj){\r\n            root[id] = obj;\r\n            return magic + '[\"' + id  + '\"]';\r\n        },\r\n        unsetGlobal: function (id){\r\n            delete root[id];\r\n        },\r\n        copyAttributes: function (tgt, src){\r\n            var attributes = src.attributes;\r\n            var k = attributes.length;\r\n            while (k --) {\r\n                var attrNode = attributes[k];\r\n                if ( attrNode.nodeName != 'style' && attrNode.nodeName != 'class' && (!browser.ie || attrNode.specified) ) {\r\n                    tgt.setAttribute(attrNode.nodeName, attrNode.nodeValue);\r\n                }\r\n            }\r\n            if (src.className) {\r\n                domUtils.addClass(tgt,src.className);\r\n            }\r\n            if (src.style.cssText) {\r\n                tgt.style.cssText += ';' + src.style.cssText;\r\n            }\r\n        },\r\n        removeStyle: function (el, styleName){\r\n            if (el.style.removeProperty) {\r\n                el.style.removeProperty(styleName);\r\n            } else if (el.style.removeAttribute) {\r\n                el.style.removeAttribute(styleName);\r\n            } else throw '';\r\n        },\r\n        contains: function (elA, elB){\r\n            return elA && elB && (elA === elB ? false : (\r\n                elA.contains ? elA.contains(elB) :\r\n                    elA.compareDocumentPosition(elB) & 16\r\n                ));\r\n        },\r\n        startDrag: function (evt, callbacks,doc){\r\n            var doc = doc || document;\r\n            var startX = evt.clientX;\r\n            var startY = evt.clientY;\r\n            function handleMouseMove(evt){\r\n                var x = evt.clientX - startX;\r\n                var y = evt.clientY - startY;\r\n                callbacks.ondragmove(x, y,evt);\r\n                if (evt.stopPropagation) {\r\n                    evt.stopPropagation();\r\n                } else {\r\n                    evt.cancelBubble = true;\r\n                }\r\n            }\r\n            if (doc.addEventListener) {\r\n                function handleMouseUp(evt){\r\n                    doc.removeEventListener('mousemove', handleMouseMove, true);\r\n                    doc.removeEventListener('mouseup', handleMouseUp, true);\r\n                    window.removeEventListener('mouseup', handleMouseUp, true);\r\n                    callbacks.ondragstop();\r\n                }\r\n                doc.addEventListener('mousemove', handleMouseMove, true);\r\n                doc.addEventListener('mouseup', handleMouseUp, true);\r\n                window.addEventListener('mouseup', handleMouseUp, true);\r\n\r\n                evt.preventDefault();\r\n            } else {\r\n                var elm = evt.srcElement;\r\n                elm.setCapture();\r\n                function releaseCaptrue(){\r\n                    elm.releaseCapture();\r\n                    elm.detachEvent('onmousemove', handleMouseMove);\r\n                    elm.detachEvent('onmouseup', releaseCaptrue);\r\n                    elm.detachEvent('onlosecaptrue', releaseCaptrue);\r\n                    callbacks.ondragstop();\r\n                }\r\n                elm.attachEvent('onmousemove', handleMouseMove);\r\n                elm.attachEvent('onmouseup', releaseCaptrue);\r\n                elm.attachEvent('onlosecaptrue', releaseCaptrue);\r\n                evt.returnValue = false;\r\n            }\r\n            callbacks.ondragstart();\r\n        },\r\n        getFixedLayer: function (){\r\n            var layer = document.getElementById('edui_fixedlayer');\r\n            if (layer == null) {\r\n                layer = document.createElement('div');\r\n                layer.id = 'edui_fixedlayer';\r\n                document.body.appendChild(layer);\r\n                if (browser.ie && browser.version <= 8) {\r\n                    layer.style.position = 'absolute';\r\n                    bindFixedLayer();\r\n                    setTimeout(updateFixedOffset);\r\n                } else {\r\n                    layer.style.position = 'fixed';\r\n                }\r\n                layer.style.left = '0';\r\n                layer.style.top = '0';\r\n                layer.style.width = '0';\r\n                layer.style.height = '0';\r\n            }\r\n            return layer;\r\n        },\r\n        makeUnselectable: function (element){\r\n            if (browser.opera || (browser.ie && browser.version < 9)) {\r\n                element.unselectable = 'on';\r\n                if (element.hasChildNodes()) {\r\n                    for (var i=0; i<element.childNodes.length; i++) {\r\n                        if (element.childNodes[i].nodeType == 1) {\r\n                            uiUtils.makeUnselectable(element.childNodes[i]);\r\n                        }\r\n                    }\r\n                }\r\n            } else {\r\n                if (element.style.MozUserSelect !== undefined) {\r\n                    element.style.MozUserSelect = 'none';\r\n                } else if (element.style.WebkitUserSelect !== undefined) {\r\n                    element.style.WebkitUserSelect = 'none';\r\n                } else if (element.style.KhtmlUserSelect !== undefined) {\r\n                    element.style.KhtmlUserSelect = 'none';\r\n                }\r\n            }\r\n        }\r\n    };\r\n    function updateFixedOffset(){\r\n        var layer = document.getElementById('edui_fixedlayer');\r\n        uiUtils.setViewportOffset(layer, {\r\n            left: 0,\r\n            top: 0\r\n        });\r\n//        layer.style.display = 'none';\r\n//        layer.style.display = 'block';\r\n\r\n        //#trace: 1354\r\n//        setTimeout(updateFixedOffset);\r\n    }\r\n    function bindFixedLayer(adjOffset){\r\n        domUtils.on(window, 'scroll', updateFixedOffset);\r\n        domUtils.on(window, 'resize', baidu.editor.utils.defer(updateFixedOffset, 0, true));\r\n    }\r\n})();\r\n\n\n// ui/uibase.js\n(function () {\r\n    var utils = baidu.editor.utils,\r\n        uiUtils = baidu.editor.ui.uiUtils,\r\n        EventBase = baidu.editor.EventBase,\r\n        UIBase = baidu.editor.ui.UIBase = function () {\r\n        };\r\n\r\n    UIBase.prototype = {\r\n        className:'',\r\n        uiName:'',\r\n        initOptions:function (options) {\r\n            var me = this;\r\n            for (var k in options) {\r\n                me[k] = options[k];\r\n            }\r\n            this.id = this.id || 'edui' + uiUtils.uid();\r\n        },\r\n        initUIBase:function () {\r\n            this._globalKey = utils.unhtml(uiUtils.setGlobal(this.id, this));\r\n        },\r\n        render:function (holder) {\r\n            var html = this.renderHtml();\r\n            var el = uiUtils.createElementByHtml(html);\r\n\r\n            //by xuheng 给每个node添加class\r\n            var list = domUtils.getElementsByTagName(el, \"*\");\r\n            var theme = \"edui-\" + (this.theme || this.editor.options.theme);\r\n            var layer = document.getElementById('edui_fixedlayer');\r\n            for (var i = 0, node; node = list[i++];) {\r\n                domUtils.addClass(node, theme);\r\n            }\r\n            domUtils.addClass(el, theme);\r\n            if(layer){\r\n                layer.className=\"\";\r\n                domUtils.addClass(layer,theme);\r\n            }\r\n\r\n            var seatEl = this.getDom();\r\n            if (seatEl != null) {\r\n                seatEl.parentNode.replaceChild(el, seatEl);\r\n                uiUtils.copyAttributes(el, seatEl);\r\n            } else {\r\n                if (typeof holder == 'string') {\r\n                    holder = document.getElementById(holder);\r\n                }\r\n                holder = holder || uiUtils.getFixedLayer();\r\n                domUtils.addClass(holder, theme);\r\n                holder.appendChild(el);\r\n            }\r\n            this.postRender();\r\n        },\r\n        getDom:function (name) {\r\n            if (!name) {\r\n                return document.getElementById(this.id);\r\n            } else {\r\n                return document.getElementById(this.id + '_' + name);\r\n            }\r\n        },\r\n        postRender:function () {\r\n            this.fireEvent('postrender');\r\n        },\r\n        getHtmlTpl:function () {\r\n            return '';\r\n        },\r\n        formatHtml:function (tpl) {\r\n            var prefix = 'edui-' + this.uiName;\r\n            return (tpl\r\n                .replace(/##/g, this.id)\r\n                .replace(/%%-/g, this.uiName ? prefix + '-' : '')\r\n                .replace(/%%/g, (this.uiName ? prefix : '') + ' ' + this.className)\r\n                .replace(/\\$\\$/g, this._globalKey));\r\n        },\r\n        renderHtml:function () {\r\n            return this.formatHtml(this.getHtmlTpl());\r\n        },\r\n        dispose:function () {\r\n            var box = this.getDom();\r\n            if (box) baidu.editor.dom.domUtils.remove(box);\r\n            uiUtils.unsetGlobal(this.id);\r\n        }\r\n    };\r\n    utils.inherits(UIBase, EventBase);\r\n})();\r\n\n\n// ui/separator.js\n(function (){\r\n    var utils = baidu.editor.utils,\r\n        UIBase = baidu.editor.ui.UIBase,\r\n        Separator = baidu.editor.ui.Separator = function (options){\r\n            this.initOptions(options);\r\n            this.initSeparator();\r\n        };\r\n    Separator.prototype = {\r\n        uiName: 'separator',\r\n        initSeparator: function (){\r\n            this.initUIBase();\r\n        },\r\n        getHtmlTpl: function (){\r\n            return '<div id=\"##\" class=\"edui-box %%\"></div>';\r\n        }\r\n    };\r\n    utils.inherits(Separator, UIBase);\r\n\r\n})();\r\n\n\n// ui/mask.js\n///import core\r\n///import uicore\r\n(function (){\r\n    var utils = baidu.editor.utils,\r\n        domUtils = baidu.editor.dom.domUtils,\r\n        UIBase = baidu.editor.ui.UIBase,\r\n        uiUtils = baidu.editor.ui.uiUtils;\r\n    \r\n    var Mask = baidu.editor.ui.Mask = function (options){\r\n        this.initOptions(options);\r\n        this.initUIBase();\r\n    };\r\n    Mask.prototype = {\r\n        getHtmlTpl: function (){\r\n            return '<div id=\"##\" class=\"edui-mask %%\" onclick=\"return $$._onClick(event, this);\" onmousedown=\"return $$._onMouseDown(event, this);\"></div>';\r\n        },\r\n        postRender: function (){\r\n            var me = this;\r\n            domUtils.on(window, 'resize', function (){\r\n                setTimeout(function (){\r\n                    if (!me.isHidden()) {\r\n                        me._fill();\r\n                    }\r\n                });\r\n            });\r\n        },\r\n        show: function (zIndex){\r\n            this._fill();\r\n            this.getDom().style.display = '';\r\n            this.getDom().style.zIndex = zIndex;\r\n        },\r\n        hide: function (){\r\n            this.getDom().style.display = 'none';\r\n            this.getDom().style.zIndex = '';\r\n        },\r\n        isHidden: function (){\r\n            return this.getDom().style.display == 'none';\r\n        },\r\n        _onMouseDown: function (){\r\n            return false;\r\n        },\r\n        _onClick: function (e, target){\r\n            this.fireEvent('click', e, target);\r\n        },\r\n        _fill: function (){\r\n            var el = this.getDom();\r\n            var vpRect = uiUtils.getViewportRect();\r\n            el.style.width = vpRect.width + 'px';\r\n            el.style.height = vpRect.height + 'px';\r\n        }\r\n    };\r\n    utils.inherits(Mask, UIBase);\r\n})();\r\n\n\n// ui/popup.js\n///import core\r\n///import uicore\r\n(function () {\r\n    var utils = baidu.editor.utils,\r\n        uiUtils = baidu.editor.ui.uiUtils,\r\n        domUtils = baidu.editor.dom.domUtils,\r\n        UIBase = baidu.editor.ui.UIBase,\r\n        Popup = baidu.editor.ui.Popup = function (options){\r\n            this.initOptions(options);\r\n            this.initPopup();\r\n        };\r\n\r\n    var allPopups = [];\r\n    function closeAllPopup( evt,el ){\r\n        for ( var i = 0; i < allPopups.length; i++ ) {\r\n            var pop = allPopups[i];\r\n            if (!pop.isHidden()) {\r\n                if (pop.queryAutoHide(el) !== false) {\r\n                    if(evt&&/scroll/ig.test(evt.type)&&pop.className==\"edui-wordpastepop\")   return;\r\n                    pop.hide();\r\n                }\r\n            }\r\n        }\r\n\r\n        if(allPopups.length)\r\n            pop.editor.fireEvent(\"afterhidepop\");\r\n    }\r\n\r\n    Popup.postHide = closeAllPopup;\r\n\r\n    var ANCHOR_CLASSES = ['edui-anchor-topleft','edui-anchor-topright',\r\n        'edui-anchor-bottomleft','edui-anchor-bottomright'];\r\n    Popup.prototype = {\r\n        SHADOW_RADIUS: 5,\r\n        content: null,\r\n        _hidden: false,\r\n        autoRender: true,\r\n        canSideLeft: true,\r\n        canSideUp: true,\r\n        initPopup: function (){\r\n            this.initUIBase();\r\n            allPopups.push( this );\r\n        },\r\n        getHtmlTpl: function (){\r\n            return '<div id=\"##\" class=\"edui-popup %%\" onmousedown=\"return false;\">' +\r\n                ' <div id=\"##_body\" class=\"edui-popup-body\">' +\r\n                ' <iframe style=\"position:absolute;z-index:-1;left:0;top:0;background-color: transparent;\" frameborder=\"0\" width=\"100%\" height=\"100%\" src=\"about:blank\"></iframe>' +\r\n                ' <div class=\"edui-shadow\"></div>' +\r\n                ' <div id=\"##_content\" class=\"edui-popup-content\">' +\r\n                this.getContentHtmlTpl() +\r\n                '  </div>' +\r\n                ' </div>' +\r\n                '</div>';\r\n        },\r\n        getContentHtmlTpl: function (){\r\n            if(this.content){\r\n                if (typeof this.content == 'string') {\r\n                    return this.content;\r\n                }\r\n                return this.content.renderHtml();\r\n            }else{\r\n                return ''\r\n            }\r\n\r\n        },\r\n        _UIBase_postRender: UIBase.prototype.postRender,\r\n        postRender: function (){\r\n\r\n\r\n            if (this.content instanceof UIBase) {\r\n                this.content.postRender();\r\n            }\r\n\r\n            //捕获鼠标滚轮\r\n            if( this.captureWheel && !this.captured ) {\r\n\r\n                this.captured = true;\r\n\r\n                var winHeight = ( document.documentElement.clientHeight || document.body.clientHeight )  - 80,\r\n                    _height = this.getDom().offsetHeight,\r\n                    _top = uiUtils.getClientRect( this.combox.getDom() ).top,\r\n                    content = this.getDom('content'),\r\n                    ifr = this.getDom('body').getElementsByTagName('iframe'),\r\n                    me = this;\r\n\r\n                ifr.length && ( ifr = ifr[0] );\r\n\r\n                while( _top + _height > winHeight ) {\r\n                    _height -= 30;\r\n                }\r\n                content.style.height = _height + 'px';\r\n                //同步更改iframe高度\r\n                ifr && ( ifr.style.height = _height + 'px' );\r\n\r\n                //阻止在combox上的鼠标滚轮事件, 防止用户的正常操作被误解\r\n                if( window.XMLHttpRequest ) {\r\n\r\n                    domUtils.on( content, ( 'onmousewheel' in document.body ) ? 'mousewheel' :'DOMMouseScroll' , function(e){\r\n\r\n                        if(e.preventDefault) {\r\n                            e.preventDefault();\r\n                        } else {\r\n                            e.returnValue = false;\r\n                        }\r\n\r\n                        if( e.wheelDelta ) {\r\n\r\n                            content.scrollTop -= ( e.wheelDelta / 120 )*60;\r\n\r\n                        } else {\r\n\r\n                            content.scrollTop -= ( e.detail / -3 )*60;\r\n\r\n                        }\r\n\r\n                    });\r\n\r\n                } else {\r\n\r\n                    //ie6\r\n                    domUtils.on( this.getDom(), 'mousewheel' , function(e){\r\n\r\n                        e.returnValue = false;\r\n\r\n                        me.getDom('content').scrollTop -= ( e.wheelDelta / 120 )*60;\r\n\r\n                    });\r\n\r\n                }\r\n\r\n            }\r\n            this.fireEvent('postRenderAfter');\r\n            this.hide(true);\r\n            this._UIBase_postRender();\r\n        },\r\n        _doAutoRender: function (){\r\n            if (!this.getDom() && this.autoRender) {\r\n                this.render();\r\n            }\r\n        },\r\n        mesureSize: function (){\r\n            var box = this.getDom('content');\r\n            return uiUtils.getClientRect(box);\r\n        },\r\n        fitSize: function (){\r\n            if( this.captureWheel && this.sized ) {\r\n                return this.__size;\r\n            }\r\n            this.sized = true;\r\n            var popBodyEl = this.getDom('body');\r\n            popBodyEl.style.width = '';\r\n            popBodyEl.style.height = '';\r\n            var size = this.mesureSize();\r\n            if( this.captureWheel ) {\r\n                popBodyEl.style.width =  -(-20 -size.width) + 'px';\r\n                var height = parseInt( this.getDom('content').style.height, 10 );\r\n                !window.isNaN( height ) && ( size.height = height );\r\n            } else {\r\n                popBodyEl.style.width =  size.width + 'px';\r\n            }\r\n            popBodyEl.style.height = size.height + 'px';\r\n            this.__size = size;\r\n            this.captureWheel && (this.getDom('content').style.overflow = 'auto');\r\n            return size;\r\n        },\r\n        showAnchor: function ( element, hoz ){\r\n            this.showAnchorRect( uiUtils.getClientRect( element ), hoz );\r\n        },\r\n        showAnchorRect: function ( rect, hoz, adj ){\r\n            this._doAutoRender();\r\n            var vpRect = uiUtils.getViewportRect();\r\n            this.getDom().style.visibility = 'hidden';\r\n            this._show();\r\n            var popSize = this.fitSize();\r\n\r\n            var sideLeft, sideUp, left, top;\r\n            if (hoz) {\r\n                sideLeft = this.canSideLeft && (rect.right + popSize.width > vpRect.right && rect.left > popSize.width);\r\n                sideUp = this.canSideUp && (rect.top + popSize.height > vpRect.bottom && rect.bottom > popSize.height);\r\n                left = (sideLeft ? rect.left - popSize.width : rect.right);\r\n                top = (sideUp ? rect.bottom - popSize.height : rect.top);\r\n            } else {\r\n                sideLeft = this.canSideLeft && (rect.right + popSize.width > vpRect.right && rect.left > popSize.width);\r\n                sideUp = this.canSideUp && (rect.top + popSize.height > vpRect.bottom && rect.bottom > popSize.height);\r\n                left = (sideLeft ? rect.right - popSize.width : rect.left);\r\n                top = (sideUp ? rect.top - popSize.height : rect.bottom);\r\n            }\r\n\r\n            var popEl = this.getDom();\r\n            uiUtils.setViewportOffset(popEl, {\r\n                left: left,\r\n                top: top\r\n            });\r\n            domUtils.removeClasses(popEl, ANCHOR_CLASSES);\r\n            popEl.className += ' ' + ANCHOR_CLASSES[(sideUp ? 1 : 0) * 2 + (sideLeft ? 1 : 0)];\r\n            if(this.editor){\r\n                popEl.style.zIndex = this.editor.container.style.zIndex * 1 + 10;\r\n                baidu.editor.ui.uiUtils.getFixedLayer().style.zIndex = popEl.style.zIndex - 1;\r\n            }\r\n            this.getDom().style.visibility = 'visible';\r\n\r\n        },\r\n        showAt: function (offset) {\r\n            var left = offset.left;\r\n            var top = offset.top;\r\n            var rect = {\r\n                left: left,\r\n                top: top,\r\n                right: left,\r\n                bottom: top,\r\n                height: 0,\r\n                width: 0\r\n            };\r\n            this.showAnchorRect(rect, false, true);\r\n        },\r\n        _show: function (){\r\n            if (this._hidden) {\r\n                var box = this.getDom();\r\n                box.style.display = '';\r\n                this._hidden = false;\r\n//                if (box.setActive) {\r\n//                    box.setActive();\r\n//                }\r\n                this.fireEvent('show');\r\n            }\r\n        },\r\n        isHidden: function (){\r\n            return this._hidden;\r\n        },\r\n        show: function (){\r\n            this._doAutoRender();\r\n            this._show();\r\n        },\r\n        hide: function (notNofity){\r\n            if (!this._hidden && this.getDom()) {\r\n                this.getDom().style.display = 'none';\r\n                this._hidden = true;\r\n                if (!notNofity) {\r\n                    this.fireEvent('hide');\r\n                }\r\n            }\r\n        },\r\n        queryAutoHide: function (el){\r\n            return !el || !uiUtils.contains(this.getDom(), el);\r\n        }\r\n    };\r\n    utils.inherits(Popup, UIBase);\r\n    \r\n    domUtils.on( document, 'mousedown', function ( evt ) {\r\n        var el = evt.target || evt.srcElement;\r\n        closeAllPopup( evt,el );\r\n    } );\r\n    domUtils.on( window, 'scroll', function (evt,el) {\r\n        closeAllPopup( evt,el );\r\n    } );\r\n\r\n})();\r\n\n\n// ui/colorpicker.js\n///import core\r\n///import uicore\r\n(function (){\r\n    var utils = baidu.editor.utils,\r\n        UIBase = baidu.editor.ui.UIBase,\r\n        ColorPicker = baidu.editor.ui.ColorPicker = function (options){\r\n            this.initOptions(options);\r\n            this.noColorText = this.noColorText || this.editor.getLang(\"clearColor\");\r\n            this.initUIBase();\r\n        };\r\n\r\n    ColorPicker.prototype = {\r\n        getHtmlTpl: function (){\r\n            return genColorPicker(this.noColorText,this.editor);\r\n        },\r\n        _onTableClick: function (evt){\r\n            var tgt = evt.target || evt.srcElement;\r\n            var color = tgt.getAttribute('data-color');\r\n            if (color) {\r\n                this.fireEvent('pickcolor', color);\r\n            }\r\n        },\r\n        _onTableOver: function (evt){\r\n            var tgt = evt.target || evt.srcElement;\r\n            var color = tgt.getAttribute('data-color');\r\n            if (color) {\r\n                this.getDom('preview').style.backgroundColor = color;\r\n            }\r\n        },\r\n        _onTableOut: function (){\r\n            this.getDom('preview').style.backgroundColor = '';\r\n        },\r\n        _onPickNoColor: function (){\r\n            this.fireEvent('picknocolor');\r\n        }\r\n    };\r\n    utils.inherits(ColorPicker, UIBase);\r\n\r\n    var COLORS = (\r\n        'ffffff,000000,eeece1,1f497d,4f81bd,c0504d,9bbb59,8064a2,4bacc6,f79646,' +\r\n            'f2f2f2,7f7f7f,ddd9c3,c6d9f0,dbe5f1,f2dcdb,ebf1dd,e5e0ec,dbeef3,fdeada,' +\r\n            'd8d8d8,595959,c4bd97,8db3e2,b8cce4,e5b9b7,d7e3bc,ccc1d9,b7dde8,fbd5b5,' +\r\n            'bfbfbf,3f3f3f,938953,548dd4,95b3d7,d99694,c3d69b,b2a2c7,92cddc,fac08f,' +\r\n            'a5a5a5,262626,494429,17365d,366092,953734,76923c,5f497a,31859b,e36c09,' +\r\n            '7f7f7f,0c0c0c,1d1b10,0f243e,244061,632423,4f6128,3f3151,205867,974806,' +\r\n            'c00000,ff0000,ffc000,ffff00,92d050,00b050,00b0f0,0070c0,002060,7030a0,').split(',');\r\n\r\n    function genColorPicker(noColorText,editor){\r\n        var html = '<div id=\"##\" class=\"edui-colorpicker %%\">' +\r\n            '<div class=\"edui-colorpicker-topbar edui-clearfix\">' +\r\n            '<div unselectable=\"on\" id=\"##_preview\" class=\"edui-colorpicker-preview\"></div>' +\r\n            '<div unselectable=\"on\" class=\"edui-colorpicker-nocolor\" onclick=\"$$._onPickNoColor(event, this);\">'+ noColorText +'</div>' +\r\n            '</div>' +\r\n            '<table  class=\"edui-box\" style=\"border-collapse: collapse;\" onmouseover=\"$$._onTableOver(event, this);\" onmouseout=\"$$._onTableOut(event, this);\" onclick=\"return $$._onTableClick(event, this);\" cellspacing=\"0\" cellpadding=\"0\">' +\r\n            '<tr style=\"border-bottom: 1px solid #ddd;font-size: 13px;line-height: 25px;color:#39C;padding-top: 2px\"><td colspan=\"10\">'+editor.getLang(\"themeColor\")+'</td> </tr>'+\r\n            '<tr class=\"edui-colorpicker-tablefirstrow\" >';\r\n        for (var i=0; i<COLORS.length; i++) {\r\n            if (i && i%10 === 0) {\r\n                html += '</tr>'+(i==60?'<tr style=\"border-bottom: 1px solid #ddd;font-size: 13px;line-height: 25px;color:#39C;\"><td colspan=\"10\">'+editor.getLang(\"standardColor\")+'</td></tr>':'')+'<tr'+(i==60?' class=\"edui-colorpicker-tablefirstrow\"':'')+'>';\r\n            }\r\n            html += i<70 ? '<td style=\"padding: 0 2px;\"><a hidefocus title=\"'+COLORS[i]+'\" onclick=\"return false;\" href=\"javascript:\" unselectable=\"on\" class=\"edui-box edui-colorpicker-colorcell\"' +\r\n                ' data-color=\"#'+ COLORS[i] +'\"'+\r\n                ' style=\"background-color:#'+ COLORS[i] +';border:solid #ccc;'+\r\n                (i<10 || i>=60?'border-width:1px;':\r\n                    i>=10&&i<20?'border-width:1px 1px 0 1px;':\r\n\r\n                        'border-width:0 1px 0 1px;')+\r\n                '\"' +\r\n                '></a></td>':'';\r\n        }\r\n        html += '</tr></table></div>';\r\n        return html;\r\n    }\r\n})();\r\n\n\n// ui/tablepicker.js\n///import core\r\n///import uicore\r\n(function (){\r\n    var utils = baidu.editor.utils,\r\n        uiUtils = baidu.editor.ui.uiUtils,\r\n        UIBase = baidu.editor.ui.UIBase;\r\n    \r\n    var TablePicker = baidu.editor.ui.TablePicker = function (options){\r\n        this.initOptions(options);\r\n        this.initTablePicker();\r\n    };\r\n    TablePicker.prototype = {\r\n        defaultNumRows: 10,\r\n        defaultNumCols: 10,\r\n        maxNumRows: 20,\r\n        maxNumCols: 20,\r\n        numRows: 10,\r\n        numCols: 10,\r\n        lengthOfCellSide: 22,\r\n        initTablePicker: function (){\r\n            this.initUIBase();\r\n        },\r\n        getHtmlTpl: function (){\r\n            var me = this;\r\n            return '<div id=\"##\" class=\"edui-tablepicker %%\">' +\r\n                 '<div class=\"edui-tablepicker-body\">' +\r\n                  '<div class=\"edui-infoarea\">' +\r\n                   '<span id=\"##_label\" class=\"edui-label\"></span>' +\r\n                  '</div>' +\r\n                  '<div class=\"edui-pickarea\"' +\r\n                   ' onmousemove=\"$$._onMouseMove(event, this);\"' +\r\n                   ' onmouseover=\"$$._onMouseOver(event, this);\"' +\r\n                   ' onmouseout=\"$$._onMouseOut(event, this);\"' +\r\n                   ' onclick=\"$$._onClick(event, this);\"' +\r\n                  '>' +\r\n                    '<div id=\"##_overlay\" class=\"edui-overlay\"></div>' +\r\n                  '</div>' +\r\n                 '</div>' +\r\n                '</div>';\r\n        },\r\n        _UIBase_render: UIBase.prototype.render,\r\n        render: function (holder){\r\n            this._UIBase_render(holder);\r\n            this.getDom('label').innerHTML = '0'+this.editor.getLang(\"t_row\")+' x 0'+this.editor.getLang(\"t_col\");\r\n        },\r\n        _track: function (numCols, numRows){\r\n            var style = this.getDom('overlay').style;\r\n            var sideLen = this.lengthOfCellSide;\r\n            style.width = numCols * sideLen + 'px';\r\n            style.height = numRows * sideLen + 'px';\r\n            var label = this.getDom('label');\r\n            label.innerHTML = numCols +this.editor.getLang(\"t_col\")+' x ' + numRows + this.editor.getLang(\"t_row\");\r\n            this.numCols = numCols;\r\n            this.numRows = numRows;\r\n        },\r\n        _onMouseOver: function (evt, el){\r\n            var rel = evt.relatedTarget || evt.fromElement;\r\n            if (!uiUtils.contains(el, rel) && el !== rel) {\r\n                this.getDom('label').innerHTML = '0'+this.editor.getLang(\"t_col\")+' x 0'+this.editor.getLang(\"t_row\");\r\n                this.getDom('overlay').style.visibility = '';\r\n            }\r\n        },\r\n        _onMouseOut: function (evt, el){\r\n            var rel = evt.relatedTarget || evt.toElement;\r\n            if (!uiUtils.contains(el, rel) && el !== rel) {\r\n                this.getDom('label').innerHTML = '0'+this.editor.getLang(\"t_col\")+' x 0'+this.editor.getLang(\"t_row\");\r\n                this.getDom('overlay').style.visibility = 'hidden';\r\n            }\r\n        },\r\n        _onMouseMove: function (evt, el){\r\n            var style = this.getDom('overlay').style;\r\n            var offset = uiUtils.getEventOffset(evt);\r\n            var sideLen = this.lengthOfCellSide;\r\n            var numCols = Math.ceil(offset.left / sideLen);\r\n            var numRows = Math.ceil(offset.top / sideLen);\r\n            this._track(numCols, numRows);\r\n        },\r\n        _onClick: function (){\r\n            this.fireEvent('picktable', this.numCols, this.numRows);\r\n        }\r\n    };\r\n    utils.inherits(TablePicker, UIBase);\r\n})();\r\n\n\n// ui/stateful.js\n(function (){\r\n    var browser = baidu.editor.browser,\r\n        domUtils = baidu.editor.dom.domUtils,\r\n        uiUtils = baidu.editor.ui.uiUtils;\r\n    \r\n    var TPL_STATEFUL = 'onmousedown=\"$$.Stateful_onMouseDown(event, this);\"' +\r\n        ' onmouseup=\"$$.Stateful_onMouseUp(event, this);\"' +\r\n        ( browser.ie ? (\r\n        ' onmouseenter=\"$$.Stateful_onMouseEnter(event, this);\"' +\r\n        ' onmouseleave=\"$$.Stateful_onMouseLeave(event, this);\"' )\r\n        : (\r\n        ' onmouseover=\"$$.Stateful_onMouseOver(event, this);\"' +\r\n        ' onmouseout=\"$$.Stateful_onMouseOut(event, this);\"' ));\r\n    \r\n    baidu.editor.ui.Stateful = {\r\n        alwalysHoverable: false,\r\n        target:null,//目标元素和this指向dom不一样\r\n        Stateful_init: function (){\r\n            this._Stateful_dGetHtmlTpl = this.getHtmlTpl;\r\n            this.getHtmlTpl = this.Stateful_getHtmlTpl;\r\n        },\r\n        Stateful_getHtmlTpl: function (){\r\n            var tpl = this._Stateful_dGetHtmlTpl();\r\n            // 使用function避免$转义\r\n            return tpl.replace(/stateful/g, function (){ return TPL_STATEFUL; });\r\n        },\r\n        Stateful_onMouseEnter: function (evt, el){\r\n            this.target=el;\r\n            if (!this.isDisabled() || this.alwalysHoverable) {\r\n                this.addState('hover');\r\n                this.fireEvent('over');\r\n            }\r\n        },\r\n        Stateful_onMouseLeave: function (evt, el){\r\n            if (!this.isDisabled() || this.alwalysHoverable) {\r\n                this.removeState('hover');\r\n                this.removeState('active');\r\n                this.fireEvent('out');\r\n            }\r\n        },\r\n        Stateful_onMouseOver: function (evt, el){\r\n            var rel = evt.relatedTarget;\r\n            if (!uiUtils.contains(el, rel) && el !== rel) {\r\n                this.Stateful_onMouseEnter(evt, el);\r\n            }\r\n        },\r\n        Stateful_onMouseOut: function (evt, el){\r\n            var rel = evt.relatedTarget;\r\n            if (!uiUtils.contains(el, rel) && el !== rel) {\r\n                this.Stateful_onMouseLeave(evt, el);\r\n            }\r\n        },\r\n        Stateful_onMouseDown: function (evt, el){\r\n            if (!this.isDisabled()) {\r\n                this.addState('active');\r\n            }\r\n        },\r\n        Stateful_onMouseUp: function (evt, el){\r\n            if (!this.isDisabled()) {\r\n                this.removeState('active');\r\n            }\r\n        },\r\n        Stateful_postRender: function (){\r\n            if (this.disabled && !this.hasState('disabled')) {\r\n                this.addState('disabled');\r\n            }\r\n        },\r\n        hasState: function (state){\r\n            return domUtils.hasClass(this.getStateDom(), 'edui-state-' + state);\r\n        },\r\n        addState: function (state){\r\n            if (!this.hasState(state)) {\r\n                this.getStateDom().className += ' edui-state-' + state;\r\n            }\r\n        },\r\n        removeState: function (state){\r\n            if (this.hasState(state)) {\r\n                domUtils.removeClasses(this.getStateDom(), ['edui-state-' + state]);\r\n            }\r\n        },\r\n        getStateDom: function (){\r\n            return this.getDom('state');\r\n        },\r\n        isChecked: function (){\r\n            return this.hasState('checked');\r\n        },\r\n        setChecked: function (checked){\r\n            if (!this.isDisabled() && checked) {\r\n                this.addState('checked');\r\n            } else {\r\n                this.removeState('checked');\r\n            }\r\n        },\r\n        isDisabled: function (){\r\n            return this.hasState('disabled');\r\n        },\r\n        setDisabled: function (disabled){\r\n            if (disabled) {\r\n                this.removeState('hover');\r\n                this.removeState('checked');\r\n                this.removeState('active');\r\n                this.addState('disabled');\r\n            } else {\r\n                this.removeState('disabled');\r\n            }\r\n        }\r\n    };\r\n})();\r\n\n\n// ui/button.js\n///import core\r\n///import uicore\r\n///import ui/stateful.js\r\n(function (){\r\n    var utils = baidu.editor.utils,\r\n        UIBase = baidu.editor.ui.UIBase,\r\n        Stateful = baidu.editor.ui.Stateful,\r\n        Button = baidu.editor.ui.Button = function (options){\r\n            if(options.name){\r\n                var btnName = options.name;\r\n                var cssRules = options.cssRules;\r\n                if(!options.className){\r\n                    options.className =  'edui-for-' + btnName;\r\n                }\r\n                options.cssRules = '.edui-default  .edui-for-'+ btnName +' .edui-icon {'+ cssRules +'}'\r\n            }\r\n            this.initOptions(options);\r\n            this.initButton();\r\n        };\r\n    Button.prototype = {\r\n        uiName: 'button',\r\n        label: '',\r\n        title: '',\r\n        showIcon: true,\r\n        showText: true,\r\n        cssRules:'',\r\n        initButton: function (){\r\n            this.initUIBase();\r\n            this.Stateful_init();\r\n            if(this.cssRules){\r\n                utils.cssRule('edui-customize-'+this.name+'-style',this.cssRules);\r\n            }\r\n        },\r\n        getHtmlTpl: function (){\r\n            return '<div id=\"##\" class=\"edui-box %%\">' +\r\n                '<div id=\"##_state\" stateful>' +\r\n                 '<div class=\"%%-wrap\"><div id=\"##_body\" unselectable=\"on\" ' + (this.title ? 'title=\"' + this.title + '\"' : '') +\r\n                 ' class=\"%%-body\" onmousedown=\"return $$._onMouseDown(event, this);\" onclick=\"return $$._onClick(event, this);\">' +\r\n                  (this.showIcon ? '<div class=\"edui-box edui-icon\"></div>' : '') +\r\n                  (this.showText ? '<div class=\"edui-box edui-label\">' + this.label + '</div>' : '') +\r\n                 '</div>' +\r\n                '</div>' +\r\n                '</div></div>';\r\n        },\r\n        postRender: function (){\r\n            this.Stateful_postRender();\r\n            this.setDisabled(this.disabled)\r\n        },\r\n        _onMouseDown: function (e){\r\n            var target = e.target || e.srcElement,\r\n                tagName = target && target.tagName && target.tagName.toLowerCase();\r\n            if (tagName == 'input' || tagName == 'object' || tagName == 'object') {\r\n                return false;\r\n            }\r\n        },\r\n        _onClick: function (){\r\n            if (!this.isDisabled()) {\r\n                this.fireEvent('click');\r\n            }\r\n        },\r\n        setTitle: function(text){\r\n            var label = this.getDom('label');\r\n            label.innerHTML = text;\r\n        }\r\n    };\r\n    utils.inherits(Button, UIBase);\r\n    utils.extend(Button.prototype, Stateful);\r\n\r\n})();\r\n\n\n// ui/splitbutton.js\n///import core\r\n///import uicore\r\n///import ui/stateful.js\r\n(function (){\r\n    var utils = baidu.editor.utils,\r\n        uiUtils = baidu.editor.ui.uiUtils,\r\n        domUtils = baidu.editor.dom.domUtils,\r\n        UIBase = baidu.editor.ui.UIBase,\r\n        Stateful = baidu.editor.ui.Stateful,\r\n        SplitButton = baidu.editor.ui.SplitButton = function (options){\r\n            this.initOptions(options);\r\n            this.initSplitButton();\r\n        };\r\n    SplitButton.prototype = {\r\n        popup: null,\r\n        uiName: 'splitbutton',\r\n        title: '',\r\n        initSplitButton: function (){\r\n            this.initUIBase();\r\n            this.Stateful_init();\r\n            var me = this;\r\n            if (this.popup != null) {\r\n                var popup = this.popup;\r\n                this.popup = null;\r\n                this.setPopup(popup);\r\n            }\r\n        },\r\n        _UIBase_postRender: UIBase.prototype.postRender,\r\n        postRender: function (){\r\n            this.Stateful_postRender();\r\n            this._UIBase_postRender();\r\n        },\r\n        setPopup: function (popup){\r\n            if (this.popup === popup) return;\r\n            if (this.popup != null) {\r\n                this.popup.dispose();\r\n            }\r\n            popup.addListener('show', utils.bind(this._onPopupShow, this));\r\n            popup.addListener('hide', utils.bind(this._onPopupHide, this));\r\n            popup.addListener('postrender', utils.bind(function (){\r\n                popup.getDom('body').appendChild(\r\n                    uiUtils.createElementByHtml('<div id=\"' +\r\n                        this.popup.id + '_bordereraser\" class=\"edui-bordereraser edui-background\" style=\"width:' +\r\n                        (uiUtils.getClientRect(this.getDom()).width + 20) + 'px\"></div>')\r\n                    );\r\n                popup.getDom().className += ' ' + this.className;\r\n            }, this));\r\n            this.popup = popup;\r\n        },\r\n        _onPopupShow: function (){\r\n            this.addState('opened');\r\n        },\r\n        _onPopupHide: function (){\r\n            this.removeState('opened');\r\n        },\r\n        getHtmlTpl: function (){\r\n            return '<div id=\"##\" class=\"edui-box %%\">' +\r\n                '<div '+ (this.title ? 'title=\"' + this.title + '\"' : '') +' id=\"##_state\" stateful><div class=\"%%-body\">' +\r\n                '<div id=\"##_button_body\" class=\"edui-box edui-button-body\" onclick=\"$$._onButtonClick(event, this);\">' +\r\n                '<div class=\"edui-box edui-icon\"></div>' +\r\n                '</div>' +\r\n                '<div class=\"edui-box edui-splitborder\"></div>' +\r\n                '<div class=\"edui-box edui-arrow\" onclick=\"$$._onArrowClick();\"></div>' +\r\n                '</div></div></div>';\r\n        },\r\n        showPopup: function (){\r\n            // 当popup往上弹出的时候，做特殊处理\r\n            var rect = uiUtils.getClientRect(this.getDom());\r\n            rect.top -= this.popup.SHADOW_RADIUS;\r\n            rect.height += this.popup.SHADOW_RADIUS;\r\n            this.popup.showAnchorRect(rect);\r\n        },\r\n        _onArrowClick: function (event, el){\r\n            if (!this.isDisabled()) {\r\n                this.showPopup();\r\n            }\r\n        },\r\n        _onButtonClick: function (){\r\n            if (!this.isDisabled()) {\r\n                this.fireEvent('buttonclick');\r\n            }\r\n        }\r\n    };\r\n    utils.inherits(SplitButton, UIBase);\r\n    utils.extend(SplitButton.prototype, Stateful, true);\r\n\r\n})();\r\n\n\n// ui/colorbutton.js\n///import core\r\n///import uicore\r\n///import ui/colorpicker.js\r\n///import ui/popup.js\r\n///import ui/splitbutton.js\r\n(function (){\r\n    var utils = baidu.editor.utils,\r\n        uiUtils = baidu.editor.ui.uiUtils,\r\n        ColorPicker = baidu.editor.ui.ColorPicker,\r\n        Popup = baidu.editor.ui.Popup,\r\n        SplitButton = baidu.editor.ui.SplitButton,\r\n        ColorButton = baidu.editor.ui.ColorButton = function (options){\r\n            this.initOptions(options);\r\n            this.initColorButton();\r\n        };\r\n    ColorButton.prototype = {\r\n        initColorButton: function (){\r\n            var me = this;\r\n            this.popup = new Popup({\r\n                content: new ColorPicker({\r\n                    noColorText: me.editor.getLang(\"clearColor\"),\r\n                    editor:me.editor,\r\n                    onpickcolor: function (t, color){\r\n                        me._onPickColor(color);\r\n                    },\r\n                    onpicknocolor: function (t, color){\r\n                        me._onPickNoColor(color);\r\n                    }\r\n                }),\r\n                editor:me.editor\r\n            });\r\n            this.initSplitButton();\r\n        },\r\n        _SplitButton_postRender: SplitButton.prototype.postRender,\r\n        postRender: function (){\r\n            this._SplitButton_postRender();\r\n            this.getDom('button_body').appendChild(\r\n                uiUtils.createElementByHtml('<div id=\"' + this.id + '_colorlump\" class=\"edui-colorlump\"></div>')\r\n            );\r\n            this.getDom().className += ' edui-colorbutton';\r\n        },\r\n        setColor: function (color){\r\n            this.getDom('colorlump').style.backgroundColor = color;\r\n            this.color = color;\r\n        },\r\n        _onPickColor: function (color){\r\n            if (this.fireEvent('pickcolor', color) !== false) {\r\n                this.setColor(color);\r\n                this.popup.hide();\r\n            }\r\n        },\r\n        _onPickNoColor: function (color){\r\n            if (this.fireEvent('picknocolor') !== false) {\r\n                this.popup.hide();\r\n            }\r\n        }\r\n    };\r\n    utils.inherits(ColorButton, SplitButton);\r\n\r\n})();\r\n\n\n// ui/tablebutton.js\n///import core\r\n///import uicore\r\n///import ui/popup.js\r\n///import ui/tablepicker.js\r\n///import ui/splitbutton.js\r\n(function (){\r\n    var utils = baidu.editor.utils,\r\n        Popup = baidu.editor.ui.Popup,\r\n        TablePicker = baidu.editor.ui.TablePicker,\r\n        SplitButton = baidu.editor.ui.SplitButton,\r\n        TableButton = baidu.editor.ui.TableButton = function (options){\r\n            this.initOptions(options);\r\n            this.initTableButton();\r\n        };\r\n    TableButton.prototype = {\r\n        initTableButton: function (){\r\n            var me = this;\r\n            this.popup = new Popup({\r\n                content: new TablePicker({\r\n                    editor:me.editor,\r\n                    onpicktable: function (t, numCols, numRows){\r\n                        me._onPickTable(numCols, numRows);\r\n                    }\r\n                }),\r\n                'editor':me.editor\r\n            });\r\n            this.initSplitButton();\r\n        },\r\n        _onPickTable: function (numCols, numRows){\r\n            if (this.fireEvent('picktable', numCols, numRows) !== false) {\r\n                this.popup.hide();\r\n            }\r\n        }\r\n    };\r\n    utils.inherits(TableButton, SplitButton);\r\n\r\n})();\r\n\n\n// ui/autotypesetpicker.js\n///import core\r\n///import uicore\r\n(function () {\r\n    var utils = baidu.editor.utils,\r\n        UIBase = baidu.editor.ui.UIBase;\r\n\r\n    var AutoTypeSetPicker = baidu.editor.ui.AutoTypeSetPicker = function (options) {\r\n        this.initOptions(options);\r\n        this.initAutoTypeSetPicker();\r\n    };\r\n    AutoTypeSetPicker.prototype = {\r\n        initAutoTypeSetPicker:function () {\r\n            this.initUIBase();\r\n        },\r\n        getHtmlTpl:function () {\r\n            var me = this.editor,\r\n                opt = me.options.autotypeset,\r\n                lang = me.getLang(\"autoTypeSet\");\r\n\r\n            var textAlignInputName = 'textAlignValue' + me.uid,\r\n                imageBlockInputName = 'imageBlockLineValue' + me.uid,\r\n                symbolConverInputName = 'symbolConverValue' + me.uid;\r\n\r\n            return '<div id=\"##\" class=\"edui-autotypesetpicker %%\">' +\r\n                '<div class=\"edui-autotypesetpicker-body\">' +\r\n                '<table >' +\r\n                '<tr><td nowrap><input type=\"checkbox\" name=\"mergeEmptyline\" ' + (opt[\"mergeEmptyline\"] ? \"checked\" : \"\" ) + '>' + lang.mergeLine + '</td><td colspan=\"2\"><input type=\"checkbox\" name=\"removeEmptyline\" ' + (opt[\"removeEmptyline\"] ? \"checked\" : \"\" ) + '>' + lang.delLine + '</td></tr>' +\r\n                '<tr><td nowrap><input type=\"checkbox\" name=\"removeClass\" ' + (opt[\"removeClass\"] ? \"checked\" : \"\" ) + '>' + lang.removeFormat + '</td><td colspan=\"2\"><input type=\"checkbox\" name=\"indent\" ' + (opt[\"indent\"] ? \"checked\" : \"\" ) + '>' + lang.indent + '</td></tr>' +\r\n                '<tr>' +\r\n                '<td nowrap><input type=\"checkbox\" name=\"textAlign\" ' + (opt[\"textAlign\"] ? \"checked\" : \"\" ) + '>' + lang.alignment + '</td>' +\r\n                '<td colspan=\"2\" id=\"' + textAlignInputName + '\">' +\r\n                '<input type=\"radio\" name=\"'+ textAlignInputName +'\" value=\"left\" ' + ((opt[\"textAlign\"] && opt[\"textAlign\"] == \"left\") ? \"checked\" : \"\") + '>' + me.getLang(\"justifyleft\") +\r\n                '<input type=\"radio\" name=\"'+ textAlignInputName +'\" value=\"center\" ' + ((opt[\"textAlign\"] && opt[\"textAlign\"] == \"center\") ? \"checked\" : \"\") + '>' + me.getLang(\"justifycenter\") +\r\n                '<input type=\"radio\" name=\"'+ textAlignInputName +'\" value=\"right\" ' + ((opt[\"textAlign\"] && opt[\"textAlign\"] == \"right\") ? \"checked\" : \"\") + '>' + me.getLang(\"justifyright\") +\r\n                '</td>' +\r\n                '</tr>' +\r\n                '<tr>' +\r\n                '<td nowrap><input type=\"checkbox\" name=\"imageBlockLine\" ' + (opt[\"imageBlockLine\"] ? \"checked\" : \"\" ) + '>' + lang.imageFloat + '</td>' +\r\n                '<td nowrap id=\"'+ imageBlockInputName +'\">' +\r\n                '<input type=\"radio\" name=\"'+ imageBlockInputName +'\" value=\"none\" ' + ((opt[\"imageBlockLine\"] && opt[\"imageBlockLine\"] == \"none\") ? \"checked\" : \"\") + '>' + me.getLang(\"default\") +\r\n                '<input type=\"radio\" name=\"'+ imageBlockInputName +'\" value=\"left\" ' + ((opt[\"imageBlockLine\"] && opt[\"imageBlockLine\"] == \"left\") ? \"checked\" : \"\") + '>' + me.getLang(\"justifyleft\") +\r\n                '<input type=\"radio\" name=\"'+ imageBlockInputName +'\" value=\"center\" ' + ((opt[\"imageBlockLine\"] && opt[\"imageBlockLine\"] == \"center\") ? \"checked\" : \"\") + '>' + me.getLang(\"justifycenter\") +\r\n                '<input type=\"radio\" name=\"'+ imageBlockInputName +'\" value=\"right\" ' + ((opt[\"imageBlockLine\"] && opt[\"imageBlockLine\"] == \"right\") ? \"checked\" : \"\") + '>' + me.getLang(\"justifyright\") +\r\n                '</td>' +\r\n                '</tr>' +\r\n                '<tr><td nowrap><input type=\"checkbox\" name=\"clearFontSize\" ' + (opt[\"clearFontSize\"] ? \"checked\" : \"\" ) + '>' + lang.removeFontsize + '</td><td colspan=\"2\"><input type=\"checkbox\" name=\"clearFontFamily\" ' + (opt[\"clearFontFamily\"] ? \"checked\" : \"\" ) + '>' + lang.removeFontFamily + '</td></tr>' +\r\n                '<tr><td nowrap colspan=\"3\"><input type=\"checkbox\" name=\"removeEmptyNode\" ' + (opt[\"removeEmptyNode\"] ? \"checked\" : \"\" ) + '>' + lang.removeHtml + '</td></tr>' +\r\n                '<tr><td nowrap colspan=\"3\"><input type=\"checkbox\" name=\"pasteFilter\" ' + (opt[\"pasteFilter\"] ? \"checked\" : \"\" ) + '>' + lang.pasteFilter + '</td></tr>' +\r\n                '<tr>' +\r\n                '<td nowrap><input type=\"checkbox\" name=\"symbolConver\" ' + (opt[\"bdc2sb\"] || opt[\"tobdc\"] ? \"checked\" : \"\" ) + '>' + lang.symbol + '</td>' +\r\n                '<td id=\"' + symbolConverInputName + '\">' +\r\n                '<input type=\"radio\" name=\"bdc\" value=\"bdc2sb\" ' + (opt[\"bdc2sb\"] ? \"checked\" : \"\" ) + '>' + lang.bdc2sb +\r\n                '<input type=\"radio\" name=\"bdc\" value=\"tobdc\" ' + (opt[\"tobdc\"] ? \"checked\" : \"\" ) + '>' + lang.tobdc + '' +\r\n                '</td>' +\r\n                '<td nowrap align=\"right\"><button >' + lang.run + '</button></td>' +\r\n                '</tr>' +\r\n                '</table>' +\r\n                '</div>' +\r\n                '</div>';\r\n\r\n\r\n        },\r\n        _UIBase_render:UIBase.prototype.render\r\n    };\r\n    utils.inherits(AutoTypeSetPicker, UIBase);\r\n})();\r\n\n\n// ui/autotypesetbutton.js\n///import core\r\n///import uicore\r\n///import ui/popup.js\r\n///import ui/autotypesetpicker.js\r\n///import ui/splitbutton.js\r\n(function (){\r\n    var utils = baidu.editor.utils,\r\n        Popup = baidu.editor.ui.Popup,\r\n        AutoTypeSetPicker = baidu.editor.ui.AutoTypeSetPicker,\r\n        SplitButton = baidu.editor.ui.SplitButton,\r\n        AutoTypeSetButton = baidu.editor.ui.AutoTypeSetButton = function (options){\r\n            this.initOptions(options);\r\n            this.initAutoTypeSetButton();\r\n        };\r\n    function getPara(me){\r\n\r\n        var opt = {},\r\n            cont = me.getDom(),\r\n            editorId = me.editor.uid,\r\n            inputType = null,\r\n            attrName = null,\r\n            ipts = domUtils.getElementsByTagName(cont,\"input\");\r\n        for(var i=ipts.length-1,ipt;ipt=ipts[i--];){\r\n            inputType = ipt.getAttribute(\"type\");\r\n            if(inputType==\"checkbox\"){\r\n                attrName = ipt.getAttribute(\"name\");\r\n                opt[attrName] && delete opt[attrName];\r\n                if(ipt.checked){\r\n                    var attrValue = document.getElementById( attrName + \"Value\" + editorId );\r\n                    if(attrValue){\r\n                        if(/input/ig.test(attrValue.tagName)){\r\n                            opt[attrName] = attrValue.value;\r\n                        } else {\r\n                            var iptChilds = attrValue.getElementsByTagName(\"input\");\r\n                            for(var j=iptChilds.length-1,iptchild;iptchild=iptChilds[j--];){\r\n                                if(iptchild.checked){\r\n                                    opt[attrName] = iptchild.value;\r\n                                    break;\r\n                                }\r\n                            }\r\n                        }\r\n                    } else {\r\n                        opt[attrName] = true;\r\n                    }\r\n                } else {\r\n                    opt[attrName] = false;\r\n                }\r\n            } else {\r\n                opt[ipt.getAttribute(\"value\")] = ipt.checked;\r\n            }\r\n\r\n        }\r\n\r\n        var selects = domUtils.getElementsByTagName(cont,\"select\");\r\n        for(var i=0,si;si=selects[i++];){\r\n            var attr = si.getAttribute('name');\r\n            opt[attr] = opt[attr] ? si.value : '';\r\n        }\r\n\r\n        utils.extend(me.editor.options.autotypeset,opt);\r\n\r\n        me.editor.setPreferences('autotypeset', opt);\r\n    }\r\n\r\n    AutoTypeSetButton.prototype = {\r\n        initAutoTypeSetButton: function (){\r\n\r\n            var me = this;\r\n            this.popup = new Popup({\r\n                //传入配置参数\r\n                content: new AutoTypeSetPicker({editor:me.editor}),\r\n                'editor':me.editor,\r\n                hide : function(){\r\n                    if (!this._hidden && this.getDom()) {\r\n                        getPara(this);\r\n                        this.getDom().style.display = 'none';\r\n                        this._hidden = true;\r\n                        this.fireEvent('hide');\r\n                    }\r\n                }\r\n            });\r\n            var flag = 0;\r\n            this.popup.addListener('postRenderAfter',function(){\r\n                var popupUI = this;\r\n                if(flag)return;\r\n                var cont = this.getDom(),\r\n                    btn = cont.getElementsByTagName('button')[0];\r\n\r\n                btn.onclick = function(){\r\n                    getPara(popupUI);\r\n                    me.editor.execCommand('autotypeset');\r\n                    popupUI.hide()\r\n                };\r\n\r\n                domUtils.on(cont, 'click', function(e) {\r\n                    var target = e.target || e.srcElement,\r\n                        editorId = me.editor.uid;\r\n                    if (target && target.tagName == 'INPUT') {\r\n\r\n                        // 点击图片浮动的checkbox,去除对应的radio\r\n                        if (target.name == 'imageBlockLine' || target.name == 'textAlign' || target.name == 'symbolConver') {\r\n                            var checked = target.checked,\r\n                                radioTd = document.getElementById( target.name + 'Value' + editorId),\r\n                                radios = radioTd.getElementsByTagName('input'),\r\n                                defalutSelect = {\r\n                                    'imageBlockLine': 'none',\r\n                                    'textAlign': 'left',\r\n                                    'symbolConver': 'tobdc'\r\n                                };\r\n\r\n                            for (var i = 0; i < radios.length; i++) {\r\n                                if (checked) {\r\n                                    if (radios[i].value == defalutSelect[target.name]) {\r\n                                        radios[i].checked = 'checked';\r\n                                    }\r\n                                } else {\r\n                                    radios[i].checked = false;\r\n                                }\r\n                            }\r\n                        }\r\n                        // 点击radio,选中对应的checkbox\r\n                        if (target.name == ('imageBlockLineValue' + editorId) || target.name == ('textAlignValue' + editorId) || target.name == 'bdc') {\r\n                            var checkboxs = target.parentNode.previousSibling.getElementsByTagName('input');\r\n                            checkboxs && (checkboxs[0].checked = true);\r\n                        }\r\n\r\n                        getPara(popupUI);\r\n                    }\r\n                });\r\n\r\n                flag = 1;\r\n            });\r\n            this.initSplitButton();\r\n        }\r\n    };\r\n    utils.inherits(AutoTypeSetButton, SplitButton);\r\n\r\n})();\r\n\n\n// ui/cellalignpicker.js\n///import core\n///import uicore\n(function () {\n    var utils = baidu.editor.utils,\n        Popup = baidu.editor.ui.Popup,\n        Stateful = baidu.editor.ui.Stateful,\n        UIBase = baidu.editor.ui.UIBase;\n\n    /**\n     * 该参数将新增一个参数： selected， 参数类型为一个Object， 形如{ 'align': 'center', 'valign': 'top' }， 表示单元格的初始\n     * 对齐状态为： 竖直居上，水平居中; 其中 align的取值为：'center', 'left', 'right'; valign的取值为: 'top', 'middle', 'bottom'\n     * @update 2013/4/2 hancong03@baidu.com\n     */\n    var CellAlignPicker = baidu.editor.ui.CellAlignPicker = function (options) {\n        this.initOptions(options);\n        this.initSelected();\n        this.initCellAlignPicker();\n    };\n    CellAlignPicker.prototype = {\n        //初始化选中状态， 该方法将根据传递进来的参数获取到应该选中的对齐方式图标的索引\n        initSelected: function(){\n\n            var status = {\n\n                valign: {\n                    top: 0,\n                    middle: 1,\n                    bottom: 2\n                },\n                align: {\n                    left: 0,\n                    center: 1,\n                    right: 2\n                },\n                count: 3\n\n                },\n                result = -1;\n\n            if( this.selected ) {\n                this.selectedIndex = status.valign[ this.selected.valign ] * status.count + status.align[ this.selected.align ];\n            }\n\n        },\n        initCellAlignPicker:function () {\n            this.initUIBase();\n            this.Stateful_init();\n        },\n        getHtmlTpl:function () {\n\n            var alignType = [ 'left', 'center', 'right' ],\n                COUNT = 9,\n                tempClassName = null,\n                tempIndex = -1,\n                tmpl = [];\n\n\n            for( var i= 0; i<COUNT; i++ ) {\n\n                tempClassName = this.selectedIndex === i ? ' class=\"edui-cellalign-selected\" ' : '';\n                tempIndex = i % 3;\n\n                tempIndex === 0 && tmpl.push('<tr>');\n\n                tmpl.push( '<td index=\"'+ i +'\" ' + tempClassName + ' stateful><div class=\"edui-icon edui-'+ alignType[ tempIndex ] +'\"></div></td>' );\n\n                tempIndex === 2 && tmpl.push('</tr>');\n\n            }\n\n            return '<div id=\"##\" class=\"edui-cellalignpicker %%\">' +\n                '<div class=\"edui-cellalignpicker-body\">' +\n                '<table onclick=\"$$._onClick(event);\">' +\n                tmpl.join('') +\n                '</table>' +\n                '</div>' +\n                '</div>';\n        },\n        getStateDom: function (){\n            return this.target;\n        },\n        _onClick: function (evt){\n            var target= evt.target || evt.srcElement;\n            if(/icon/.test(target.className)){\n                this.items[target.parentNode.getAttribute(\"index\")].onclick();\n                Popup.postHide(evt);\n            }\n        },\n        _UIBase_render:UIBase.prototype.render\n    };\n    utils.inherits(CellAlignPicker, UIBase);\n    utils.extend(CellAlignPicker.prototype, Stateful,true);\n})();\n\n\n\n\n\n// ui/pastepicker.js\n///import core\n///import uicore\n(function () {\n    var utils = baidu.editor.utils,\n        Stateful = baidu.editor.ui.Stateful,\n        uiUtils = baidu.editor.ui.uiUtils,\n        UIBase = baidu.editor.ui.UIBase;\n\n    var PastePicker = baidu.editor.ui.PastePicker = function (options) {\n        this.initOptions(options);\n        this.initPastePicker();\n    };\n    PastePicker.prototype = {\n        initPastePicker:function () {\n            this.initUIBase();\n            this.Stateful_init();\n        },\n        getHtmlTpl:function () {\n            return '<div class=\"edui-pasteicon\" onclick=\"$$._onClick(this)\"></div>' +\n                '<div class=\"edui-pastecontainer\">' +\n                '<div class=\"edui-title\">' + this.editor.getLang(\"pasteOpt\") + '</div>' +\n                '<div class=\"edui-button\">' +\n                '<div title=\"' + this.editor.getLang(\"pasteSourceFormat\") + '\" onclick=\"$$.format(false)\" stateful>' +\n                '<div class=\"edui-richtxticon\"></div></div>' +\n                '<div title=\"' + this.editor.getLang(\"tagFormat\") + '\" onclick=\"$$.format(2)\" stateful>' +\n                '<div class=\"edui-tagicon\"></div></div>' +\n                '<div title=\"' + this.editor.getLang(\"pasteTextFormat\") + '\" onclick=\"$$.format(true)\" stateful>' +\n                '<div class=\"edui-plaintxticon\"></div></div>' +\n                '</div>' +\n                '</div>' +\n                '</div>'\n        },\n        getStateDom:function () {\n            return this.target;\n        },\n        format:function (param) {\n            this.editor.ui._isTransfer = true;\n            this.editor.fireEvent('pasteTransfer', param);\n        },\n        _onClick:function (cur) {\n            var node = domUtils.getNextDomNode(cur),\n                screenHt = uiUtils.getViewportRect().height,\n                subPop = uiUtils.getClientRect(node);\n\n            if ((subPop.top + subPop.height) > screenHt)\n                node.style.top = (-subPop.height - cur.offsetHeight) + \"px\";\n            else\n                node.style.top = \"\";\n\n            if (/hidden/ig.test(domUtils.getComputedStyle(node, \"visibility\"))) {\n                node.style.visibility = \"visible\";\n                domUtils.addClass(cur, \"edui-state-opened\");\n            } else {\n                node.style.visibility = \"hidden\";\n                domUtils.removeClasses(cur, \"edui-state-opened\")\n            }\n        },\n        _UIBase_render:UIBase.prototype.render\n    };\n    utils.inherits(PastePicker, UIBase);\n    utils.extend(PastePicker.prototype, Stateful, true);\n})();\n\n\n\n\n\n\n// ui/toolbar.js\n(function (){\r\n    var utils = baidu.editor.utils,\r\n        uiUtils = baidu.editor.ui.uiUtils,\r\n        UIBase = baidu.editor.ui.UIBase,\r\n        Toolbar = baidu.editor.ui.Toolbar = function (options){\r\n            this.initOptions(options);\r\n            this.initToolbar();\r\n        };\r\n    Toolbar.prototype = {\r\n        items: null,\r\n        initToolbar: function (){\r\n            this.items = this.items || [];\r\n            this.initUIBase();\r\n        },\r\n        add: function (item,index){\r\n            if(index === undefined){\r\n                this.items.push(item);\r\n            }else{\r\n                this.items.splice(index,0,item)\r\n            }\r\n\r\n        },\r\n        getHtmlTpl: function (){\r\n            var buff = [];\r\n            for (var i=0; i<this.items.length; i++) {\r\n                buff[i] = this.items[i].renderHtml();\r\n            }\r\n            return '<div id=\"##\" class=\"edui-toolbar %%\" onselectstart=\"return false;\" onmousedown=\"return $$._onMouseDown(event, this);\">' +\r\n                buff.join('') +\r\n                '</div>'\r\n        },\r\n        postRender: function (){\r\n            var box = this.getDom();\r\n            for (var i=0; i<this.items.length; i++) {\r\n                this.items[i].postRender();\r\n            }\r\n            uiUtils.makeUnselectable(box);\r\n        },\r\n        _onMouseDown: function (e){\r\n            var target = e.target || e.srcElement,\r\n                tagName = target && target.tagName && target.tagName.toLowerCase();\r\n            if (tagName == 'input' || tagName == 'object' || tagName == 'object') {\r\n                return false;\r\n            }\r\n        }\r\n    };\r\n    utils.inherits(Toolbar, UIBase);\r\n\r\n})();\r\n\n\n// ui/menu.js\n///import core\r\n///import uicore\r\n///import ui\\popup.js\r\n///import ui\\stateful.js\r\n(function () {\r\n    var utils = baidu.editor.utils,\r\n        domUtils = baidu.editor.dom.domUtils,\r\n        uiUtils = baidu.editor.ui.uiUtils,\r\n        UIBase = baidu.editor.ui.UIBase,\r\n        Popup = baidu.editor.ui.Popup,\r\n        Stateful = baidu.editor.ui.Stateful,\r\n        CellAlignPicker = baidu.editor.ui.CellAlignPicker,\r\n\r\n        Menu = baidu.editor.ui.Menu = function (options) {\r\n            this.initOptions(options);\r\n            this.initMenu();\r\n        };\r\n\r\n    var menuSeparator = {\r\n        renderHtml:function () {\r\n            return '<div class=\"edui-menuitem edui-menuseparator\"><div class=\"edui-menuseparator-inner\"></div></div>';\r\n        },\r\n        postRender:function () {\r\n        },\r\n        queryAutoHide:function () {\r\n            return true;\r\n        }\r\n    };\r\n    Menu.prototype = {\r\n        items:null,\r\n        uiName:'menu',\r\n        initMenu:function () {\r\n            this.items = this.items || [];\r\n            this.initPopup();\r\n            this.initItems();\r\n        },\r\n        initItems:function () {\r\n            for (var i = 0; i < this.items.length; i++) {\r\n                var item = this.items[i];\r\n                if (item == '-') {\r\n                    this.items[i] = this.getSeparator();\r\n                } else if (!(item instanceof MenuItem)) {\r\n                    item.editor = this.editor;\r\n                    item.theme = this.editor.options.theme;\r\n                    this.items[i] = this.createItem(item);\r\n                }\r\n            }\r\n        },\r\n        getSeparator:function () {\r\n            return menuSeparator;\r\n        },\r\n        createItem:function (item) {\r\n            //新增一个参数menu, 该参数存储了menuItem所对应的menu引用\r\n            item.menu = this;\r\n            return new MenuItem(item);\r\n        },\r\n        _Popup_getContentHtmlTpl:Popup.prototype.getContentHtmlTpl,\r\n        getContentHtmlTpl:function () {\r\n            if (this.items.length == 0) {\r\n                return this._Popup_getContentHtmlTpl();\r\n            }\r\n            var buff = [];\r\n            for (var i = 0; i < this.items.length; i++) {\r\n                var item = this.items[i];\r\n                buff[i] = item.renderHtml();\r\n            }\r\n            return ('<div class=\"%%-body\">' + buff.join('') + '</div>');\r\n        },\r\n        _Popup_postRender:Popup.prototype.postRender,\r\n        postRender:function () {\r\n            var me = this;\r\n            for (var i = 0; i < this.items.length; i++) {\r\n                var item = this.items[i];\r\n                item.ownerMenu = this;\r\n                item.postRender();\r\n            }\r\n            domUtils.on(this.getDom(), 'mouseover', function (evt) {\r\n                evt = evt || event;\r\n                var rel = evt.relatedTarget || evt.fromElement;\r\n                var el = me.getDom();\r\n                if (!uiUtils.contains(el, rel) && el !== rel) {\r\n                    me.fireEvent('over');\r\n                }\r\n            });\r\n            this._Popup_postRender();\r\n        },\r\n        queryAutoHide:function (el) {\r\n            if (el) {\r\n                if (uiUtils.contains(this.getDom(), el)) {\r\n                    return false;\r\n                }\r\n                for (var i = 0; i < this.items.length; i++) {\r\n                    var item = this.items[i];\r\n                    if (item.queryAutoHide(el) === false) {\r\n                        return false;\r\n                    }\r\n                }\r\n            }\r\n        },\r\n        clearItems:function () {\r\n            for (var i = 0; i < this.items.length; i++) {\r\n                var item = this.items[i];\r\n                clearTimeout(item._showingTimer);\r\n                clearTimeout(item._closingTimer);\r\n                if (item.subMenu) {\r\n                    item.subMenu.destroy();\r\n                }\r\n            }\r\n            this.items = [];\r\n        },\r\n        destroy:function () {\r\n            if (this.getDom()) {\r\n                domUtils.remove(this.getDom());\r\n            }\r\n            this.clearItems();\r\n        },\r\n        dispose:function () {\r\n            this.destroy();\r\n        }\r\n    };\r\n    utils.inherits(Menu, Popup);\r\n\r\n    /**\r\n     * @update 2013/04/03 hancong03 新增一个参数menu, 该参数存储了menuItem所对应的menu引用\r\n     * @type {Function}\r\n     */\r\n    var MenuItem = baidu.editor.ui.MenuItem = function (options) {\r\n        this.initOptions(options);\r\n        this.initUIBase();\r\n        this.Stateful_init();\r\n        if (this.subMenu && !(this.subMenu instanceof Menu)) {\r\n            if (options.className && options.className.indexOf(\"aligntd\") != -1) {\r\n                var me = this;\r\n\r\n                //获取单元格对齐初始状态\r\n                this.subMenu.selected = this.editor.queryCommandValue( 'cellalignment' );\r\n\r\n                this.subMenu = new Popup({\r\n                    content:new CellAlignPicker(this.subMenu),\r\n                    parentMenu:me,\r\n                    editor:me.editor,\r\n                    destroy:function () {\r\n                        if (this.getDom()) {\r\n                            domUtils.remove(this.getDom());\r\n                        }\r\n                    }\r\n                });\r\n                this.subMenu.addListener(\"postRenderAfter\", function () {\r\n                    domUtils.on(this.getDom(), \"mouseover\", function () {\r\n                        me.addState('opened');\r\n                    });\r\n                });\r\n            } else {\r\n                this.subMenu = new Menu(this.subMenu);\r\n            }\r\n        }\r\n    };\r\n    MenuItem.prototype = {\r\n        label:'',\r\n        subMenu:null,\r\n        ownerMenu:null,\r\n        uiName:'menuitem',\r\n        alwalysHoverable:true,\r\n        getHtmlTpl:function () {\r\n            return '<div id=\"##\" class=\"%%\" stateful onclick=\"$$._onClick(event, this);\">' +\r\n                '<div class=\"%%-body\">' +\r\n                this.renderLabelHtml() +\r\n                '</div>' +\r\n                '</div>';\r\n        },\r\n        postRender:function () {\r\n            var me = this;\r\n            this.addListener('over', function () {\r\n                me.ownerMenu.fireEvent('submenuover', me);\r\n                if (me.subMenu) {\r\n                    me.delayShowSubMenu();\r\n                }\r\n            });\r\n            if (this.subMenu) {\r\n                this.getDom().className += ' edui-hassubmenu';\r\n                this.subMenu.render();\r\n                this.addListener('out', function () {\r\n                    me.delayHideSubMenu();\r\n                });\r\n                this.subMenu.addListener('over', function () {\r\n                    clearTimeout(me._closingTimer);\r\n                    me._closingTimer = null;\r\n                    me.addState('opened');\r\n                });\r\n                this.ownerMenu.addListener('hide', function () {\r\n                    me.hideSubMenu();\r\n                });\r\n                this.ownerMenu.addListener('submenuover', function (t, subMenu) {\r\n                    if (subMenu !== me) {\r\n                        me.delayHideSubMenu();\r\n                    }\r\n                });\r\n                this.subMenu._bakQueryAutoHide = this.subMenu.queryAutoHide;\r\n                this.subMenu.queryAutoHide = function (el) {\r\n                    if (el && uiUtils.contains(me.getDom(), el)) {\r\n                        return false;\r\n                    }\r\n                    return this._bakQueryAutoHide(el);\r\n                };\r\n            }\r\n            this.getDom().style.tabIndex = '-1';\r\n            uiUtils.makeUnselectable(this.getDom());\r\n            this.Stateful_postRender();\r\n        },\r\n        delayShowSubMenu:function () {\r\n            var me = this;\r\n            if (!me.isDisabled()) {\r\n                me.addState('opened');\r\n                clearTimeout(me._showingTimer);\r\n                clearTimeout(me._closingTimer);\r\n                me._closingTimer = null;\r\n                me._showingTimer = setTimeout(function () {\r\n                    me.showSubMenu();\r\n                }, 250);\r\n            }\r\n        },\r\n        delayHideSubMenu:function () {\r\n            var me = this;\r\n            if (!me.isDisabled()) {\r\n                me.removeState('opened');\r\n                clearTimeout(me._showingTimer);\r\n                if (!me._closingTimer) {\r\n                    me._closingTimer = setTimeout(function () {\r\n                        if (!me.hasState('opened')) {\r\n                            me.hideSubMenu();\r\n                        }\r\n                        me._closingTimer = null;\r\n                    }, 400);\r\n                }\r\n            }\r\n        },\r\n        renderLabelHtml:function () {\r\n            return '<div class=\"edui-arrow\"></div>' +\r\n                '<div class=\"edui-box edui-icon\"></div>' +\r\n                '<div class=\"edui-box edui-label %%-label\">' + (this.label || '') + '</div>';\r\n        },\r\n        getStateDom:function () {\r\n            return this.getDom();\r\n        },\r\n        queryAutoHide:function (el) {\r\n            if (this.subMenu && this.hasState('opened')) {\r\n                return this.subMenu.queryAutoHide(el);\r\n            }\r\n        },\r\n        _onClick:function (event, this_) {\r\n            if (this.hasState('disabled')) return;\r\n            if (this.fireEvent('click', event, this_) !== false) {\r\n                if (this.subMenu) {\r\n                    this.showSubMenu();\r\n                } else {\r\n                    Popup.postHide(event);\r\n                }\r\n            }\r\n        },\r\n        showSubMenu:function () {\r\n            var rect = uiUtils.getClientRect(this.getDom());\r\n            rect.right -= 5;\r\n            rect.left += 2;\r\n            rect.width -= 7;\r\n            rect.top -= 4;\r\n            rect.bottom += 4;\r\n            rect.height += 8;\r\n            this.subMenu.showAnchorRect(rect, true, true);\r\n        },\r\n        hideSubMenu:function () {\r\n            this.subMenu.hide();\r\n        }\r\n    };\r\n    utils.inherits(MenuItem, UIBase);\r\n    utils.extend(MenuItem.prototype, Stateful, true);\r\n})();\r\n\n\n// ui/combox.js\n///import core\r\n///import uicore\r\n///import ui/menu.js\r\n///import ui/splitbutton.js\r\n(function (){\r\n    // todo: menu和item提成通用list\r\n    var utils = baidu.editor.utils,\r\n        uiUtils = baidu.editor.ui.uiUtils,\r\n        Menu = baidu.editor.ui.Menu,\r\n        SplitButton = baidu.editor.ui.SplitButton,\r\n        Combox = baidu.editor.ui.Combox = function (options){\r\n            this.initOptions(options);\r\n            this.initCombox();\r\n        };\r\n    Combox.prototype = {\r\n        uiName: 'combox',\r\n        onbuttonclick:function () {\r\n            this.showPopup();\r\n        },\r\n        initCombox: function (){\r\n            var me = this;\r\n            this.items = this.items || [];\r\n            for (var i=0; i<this.items.length; i++) {\r\n                var item = this.items[i];\r\n                item.uiName = 'listitem';\r\n                item.index = i;\r\n                item.onclick = function (){\r\n                    me.selectByIndex(this.index);\r\n                };\r\n            }\r\n            this.popup = new Menu({\r\n                items: this.items,\r\n                uiName: 'list',\r\n                editor:this.editor,\r\n                captureWheel: true,\r\n                combox: this\r\n            });\r\n\r\n            this.initSplitButton();\r\n        },\r\n        _SplitButton_postRender: SplitButton.prototype.postRender,\r\n        postRender: function (){\r\n            this._SplitButton_postRender();\r\n            this.setLabel(this.label || '');\r\n            this.setValue(this.initValue || '');\r\n        },\r\n        showPopup: function (){\r\n            var rect = uiUtils.getClientRect(this.getDom());\r\n            rect.top += 1;\r\n            rect.bottom -= 1;\r\n            rect.height -= 2;\r\n            this.popup.showAnchorRect(rect);\r\n        },\r\n        getValue: function (){\r\n            return this.value;\r\n        },\r\n        setValue: function (value){\r\n            var index = this.indexByValue(value);\r\n            if (index != -1) {\r\n                this.selectedIndex = index;\r\n                this.setLabel(this.items[index].label);\r\n                this.value = this.items[index].value;\r\n            } else {\r\n                this.selectedIndex = -1;\r\n                this.setLabel(this.getLabelForUnknowValue(value));\r\n                this.value = value;\r\n            }\r\n        },\r\n        setLabel: function (label){\r\n            this.getDom('button_body').innerHTML = label;\r\n            this.label = label;\r\n        },\r\n        getLabelForUnknowValue: function (value){\r\n            return value;\r\n        },\r\n        indexByValue: function (value){\r\n            for (var i=0; i<this.items.length; i++) {\r\n                if (value == this.items[i].value) {\r\n                    return i;\r\n                }\r\n            }\r\n            return -1;\r\n        },\r\n        getItem: function (index){\r\n            return this.items[index];\r\n        },\r\n        selectByIndex: function (index){\r\n            if (index < this.items.length && this.fireEvent('select', index) !== false) {\r\n                this.selectedIndex = index;\r\n                this.value = this.items[index].value;\r\n                this.setLabel(this.items[index].label);\r\n            }\r\n        }\r\n    };\r\n    utils.inherits(Combox, SplitButton);\r\n})();\r\n\n\n// ui/dialog.js\n///import core\r\n///import uicore\r\n///import ui/mask.js\r\n///import ui/button.js\r\n(function (){\r\n    var utils = baidu.editor.utils,\r\n        domUtils = baidu.editor.dom.domUtils,\r\n        uiUtils = baidu.editor.ui.uiUtils,\r\n        Mask = baidu.editor.ui.Mask,\r\n        UIBase = baidu.editor.ui.UIBase,\r\n        Button = baidu.editor.ui.Button,\r\n        Dialog = baidu.editor.ui.Dialog = function (options){\r\n            if(options.name){\r\n                var name = options.name;\r\n                var cssRules = options.cssRules;\r\n                if(!options.className){\r\n                    options.className =  'edui-for-' + name;\r\n                }\r\n                if(cssRules){\r\n                    options.cssRules = '.edui-default .edui-for-'+ name +' .edui-dialog-content  {'+ cssRules +'}'\r\n                }\r\n            }\r\n            this.initOptions(utils.extend({\r\n                autoReset: true,\r\n                draggable: true,\r\n                onok: function (){},\r\n                oncancel: function (){},\r\n                onclose: function (t, ok){\r\n                    return ok ? this.onok() : this.oncancel();\r\n                },\r\n                //是否控制dialog中的scroll事件， 默认为不阻止\r\n                holdScroll: false\r\n            },options));\r\n            this.initDialog();\r\n        };\r\n    var modalMask;\r\n    var dragMask;\r\n    var activeDialog;\r\n    Dialog.prototype = {\r\n        draggable: false,\r\n        uiName: 'dialog',\r\n        initDialog: function (){\r\n            var me = this,\r\n                theme=this.editor.options.theme;\r\n            if(this.cssRules){\r\n                utils.cssRule('edui-customize-'+this.name+'-style',this.cssRules);\r\n            }\r\n            this.initUIBase();\r\n            this.modalMask = (modalMask || (modalMask = new Mask({\r\n                className: 'edui-dialog-modalmask',\r\n                theme:theme,\r\n                onclick: function (){\r\n                    activeDialog && activeDialog.close(false);\r\n                }\r\n            })));\r\n            this.dragMask = (dragMask || (dragMask = new Mask({\r\n                className: 'edui-dialog-dragmask',\r\n                theme:theme\r\n            })));\r\n            this.closeButton = new Button({\r\n                className: 'edui-dialog-closebutton',\r\n                title: me.closeDialog,\r\n                theme:theme,\r\n                onclick: function (){\r\n                    me.close(false);\r\n                }\r\n            });\r\n\r\n            this.fullscreen && this.initResizeEvent();\r\n\r\n            if (this.buttons) {\r\n                for (var i=0; i<this.buttons.length; i++) {\r\n                    if (!(this.buttons[i] instanceof Button)) {\r\n                        this.buttons[i] = new Button(utils.extend(this.buttons[i],{\r\n                            editor : this.editor\r\n                        },true));\r\n                    }\r\n                }\r\n            }\r\n        },\r\n        initResizeEvent: function () {\r\n\r\n            var me = this;\r\n\r\n            domUtils.on( window, \"resize\", function () {\r\n\r\n                if ( me._hidden || me._hidden === undefined ) {\r\n                    return;\r\n                }\r\n\r\n                if ( me.__resizeTimer ) {\r\n                    window.clearTimeout( me.__resizeTimer );\r\n                }\r\n\r\n                me.__resizeTimer = window.setTimeout( function () {\r\n\r\n                    me.__resizeTimer = null;\r\n\r\n                    var dialogWrapNode = me.getDom(),\r\n                        contentNode = me.getDom('content'),\r\n                        wrapRect = UE.ui.uiUtils.getClientRect( dialogWrapNode ),\r\n                        contentRect = UE.ui.uiUtils.getClientRect( contentNode ),\r\n                        vpRect = uiUtils.getViewportRect();\r\n\r\n                    contentNode.style.width = ( vpRect.width - wrapRect.width + contentRect.width ) + \"px\";\r\n                    contentNode.style.height = ( vpRect.height - wrapRect.height + contentRect.height ) + \"px\";\r\n\r\n                    dialogWrapNode.style.width = vpRect.width + \"px\";\r\n                    dialogWrapNode.style.height = vpRect.height + \"px\";\r\n\r\n                    me.fireEvent( \"resize\" );\r\n\r\n                }, 100 );\r\n\r\n            } );\r\n\r\n        },\r\n        fitSize: function (){\r\n            var popBodyEl = this.getDom('body');\r\n//            if (!(baidu.editor.browser.ie && baidu.editor.browser.version == 7)) {\r\n//                uiUtils.removeStyle(popBodyEl, 'width');\r\n//                uiUtils.removeStyle(popBodyEl, 'height');\r\n//            }\r\n            var size = this.mesureSize();\r\n            popBodyEl.style.width = size.width + 'px';\r\n            popBodyEl.style.height = size.height + 'px';\r\n            return size;\r\n        },\r\n        safeSetOffset: function (offset){\r\n            var me = this;\r\n            var el = me.getDom();\r\n            var vpRect = uiUtils.getViewportRect();\r\n            var rect = uiUtils.getClientRect(el);\r\n            var left = offset.left;\r\n            if (left + rect.width > vpRect.right) {\r\n                left = vpRect.right - rect.width;\r\n            }\r\n            var top = offset.top;\r\n            if (top + rect.height > vpRect.bottom) {\r\n                top = vpRect.bottom - rect.height;\r\n            }\r\n            el.style.left = Math.max(left, 0) + 'px';\r\n            el.style.top = Math.max(top, 0) + 'px';\r\n        },\r\n        showAtCenter: function (){\r\n\r\n            var vpRect = uiUtils.getViewportRect();\r\n\r\n            if ( !this.fullscreen ) {\r\n                this.getDom().style.display = '';\r\n                var popSize = this.fitSize();\r\n                var titleHeight = this.getDom('titlebar').offsetHeight | 0;\r\n                var left = vpRect.width / 2 - popSize.width / 2;\r\n                var top = vpRect.height / 2 - (popSize.height - titleHeight) / 2 - titleHeight;\r\n                var popEl = this.getDom();\r\n                this.safeSetOffset({\r\n                    left: Math.max(left | 0, 0),\r\n                    top: Math.max(top | 0, 0)\r\n                });\r\n                if (!domUtils.hasClass(popEl, 'edui-state-centered')) {\r\n                    popEl.className += ' edui-state-centered';\r\n                }\r\n            } else {\r\n                var dialogWrapNode = this.getDom(),\r\n                    contentNode = this.getDom('content');\r\n\r\n                dialogWrapNode.style.display = \"block\";\r\n\r\n                var wrapRect = UE.ui.uiUtils.getClientRect( dialogWrapNode ),\r\n                    contentRect = UE.ui.uiUtils.getClientRect( contentNode );\r\n                dialogWrapNode.style.left = \"-100000px\";\r\n\r\n                contentNode.style.width = ( vpRect.width - wrapRect.width + contentRect.width ) + \"px\";\r\n                contentNode.style.height = ( vpRect.height - wrapRect.height + contentRect.height ) + \"px\";\r\n\r\n                dialogWrapNode.style.width = vpRect.width + \"px\";\r\n                dialogWrapNode.style.height = vpRect.height + \"px\";\r\n                dialogWrapNode.style.left = 0;\r\n\r\n                //保存环境的overflow值\r\n                this._originalContext = {\r\n                    html: {\r\n                        overflowX: document.documentElement.style.overflowX,\r\n                        overflowY: document.documentElement.style.overflowY\r\n                    },\r\n                    body: {\r\n                        overflowX: document.body.style.overflowX,\r\n                        overflowY: document.body.style.overflowY\r\n                    }\r\n                };\r\n\r\n                document.documentElement.style.overflowX = 'hidden';\r\n                document.documentElement.style.overflowY = 'hidden';\r\n                document.body.style.overflowX = 'hidden';\r\n                document.body.style.overflowY = 'hidden';\r\n\r\n            }\r\n\r\n            this._show();\r\n        },\r\n        getContentHtml: function (){\r\n            var contentHtml = '';\r\n            if (typeof this.content == 'string') {\r\n                contentHtml = this.content;\r\n            } else if (this.iframeUrl) {\r\n                contentHtml = '<span id=\"'+ this.id +'_contmask\" class=\"dialogcontmask\"></span><iframe id=\"'+ this.id +\r\n                    '_iframe\" class=\"%%-iframe\" height=\"100%\" width=\"100%\" frameborder=\"0\" src=\"'+ this.iframeUrl +'\"></iframe>';\r\n            }\r\n            return contentHtml;\r\n        },\r\n        getHtmlTpl: function (){\r\n            var footHtml = '';\r\n\r\n            if (this.buttons) {\r\n                var buff = [];\r\n                for (var i=0; i<this.buttons.length; i++) {\r\n                    buff[i] = this.buttons[i].renderHtml();\r\n                }\r\n                footHtml = '<div class=\"%%-foot\">' +\r\n                     '<div id=\"##_buttons\" class=\"%%-buttons\">' + buff.join('') + '</div>' +\r\n                    '</div>';\r\n            }\r\n\r\n            return '<div id=\"##\" class=\"%%\"><div '+ ( !this.fullscreen ? 'class=\"%%\"' : 'class=\"%%-wrap edui-dialog-fullscreen-flag\"' ) +'><div id=\"##_body\" class=\"%%-body\">' +\r\n                '<div class=\"%%-shadow\"></div>' +\r\n                '<div id=\"##_titlebar\" class=\"%%-titlebar\">' +\r\n                '<div class=\"%%-draghandle\" onmousedown=\"$$._onTitlebarMouseDown(event, this);\">' +\r\n                 '<span class=\"%%-caption\">' + (this.title || '') + '</span>' +\r\n                '</div>' +\r\n                this.closeButton.renderHtml() +\r\n                '</div>' +\r\n                '<div id=\"##_content\" class=\"%%-content\">'+ ( this.autoReset ? '' : this.getContentHtml()) +'</div>' +\r\n                footHtml +\r\n                '</div></div></div>';\r\n        },\r\n        postRender: function (){\r\n            // todo: 保持居中/记住上次关闭位置选项\r\n            if (!this.modalMask.getDom()) {\r\n                this.modalMask.render();\r\n                this.modalMask.hide();\r\n            }\r\n            if (!this.dragMask.getDom()) {\r\n                this.dragMask.render();\r\n                this.dragMask.hide();\r\n            }\r\n            var me = this;\r\n            this.addListener('show', function (){\r\n                me.modalMask.show(this.getDom().style.zIndex - 2);\r\n            });\r\n            this.addListener('hide', function (){\r\n                me.modalMask.hide();\r\n            });\r\n            if (this.buttons) {\r\n                for (var i=0; i<this.buttons.length; i++) {\r\n                    this.buttons[i].postRender();\r\n                }\r\n            }\r\n            domUtils.on(window, 'resize', function (){\r\n                setTimeout(function (){\r\n                    if (!me.isHidden()) {\r\n                        me.safeSetOffset(uiUtils.getClientRect(me.getDom()));\r\n                    }\r\n                });\r\n            });\r\n\r\n            //hold住scroll事件，防止dialog的滚动影响页面\r\n//            if( this.holdScroll ) {\r\n//\r\n//                if( !me.iframeUrl ) {\r\n//                    domUtils.on( document.getElementById( me.id + \"_iframe\"), !browser.gecko ? \"mousewheel\" : \"DOMMouseScroll\", function(e){\r\n//                        domUtils.preventDefault(e);\r\n//                    } );\r\n//                } else {\r\n//                    me.addListener('dialogafterreset', function(){\r\n//                        window.setTimeout(function(){\r\n//                            var iframeWindow = document.getElementById( me.id + \"_iframe\").contentWindow;\r\n//\r\n//                            if( browser.ie ) {\r\n//\r\n//                                var timer = window.setInterval(function(){\r\n//\r\n//                                    if( iframeWindow.document && iframeWindow.document.body ) {\r\n//                                        window.clearInterval( timer );\r\n//                                        timer = null;\r\n//                                        domUtils.on( iframeWindow.document.body, !browser.gecko ? \"mousewheel\" : \"DOMMouseScroll\", function(e){\r\n//                                            domUtils.preventDefault(e);\r\n//                                        } );\r\n//                                    }\r\n//\r\n//                                }, 100);\r\n//\r\n//                            } else {\r\n//                                domUtils.on( iframeWindow, !browser.gecko ? \"mousewheel\" : \"DOMMouseScroll\", function(e){\r\n//                                    domUtils.preventDefault(e);\r\n//                                } );\r\n//                            }\r\n//\r\n//                        }, 1);\r\n//                    });\r\n//                }\r\n//\r\n//            }\r\n            this._hide();\r\n        },\r\n        mesureSize: function (){\r\n            var body = this.getDom('body');\r\n            var width = uiUtils.getClientRect(this.getDom('content')).width;\r\n            var dialogBodyStyle = body.style;\r\n            dialogBodyStyle.width = width;\r\n            return uiUtils.getClientRect(body);\r\n        },\r\n        _onTitlebarMouseDown: function (evt, el){\r\n            if (this.draggable) {\r\n                var rect;\r\n                var vpRect = uiUtils.getViewportRect();\r\n                var me = this;\r\n                uiUtils.startDrag(evt, {\r\n                    ondragstart: function (){\r\n                        rect = uiUtils.getClientRect(me.getDom());\r\n                        me.getDom('contmask').style.visibility = 'visible';\r\n                        me.dragMask.show(me.getDom().style.zIndex - 1);\r\n                    },\r\n                    ondragmove: function (x, y){\r\n                        var left = rect.left + x;\r\n                        var top = rect.top + y;\r\n                        me.safeSetOffset({\r\n                            left: left,\r\n                            top: top\r\n                        });\r\n                    },\r\n                    ondragstop: function (){\r\n                        me.getDom('contmask').style.visibility = 'hidden';\r\n                        domUtils.removeClasses(me.getDom(), ['edui-state-centered']);\r\n                        me.dragMask.hide();\r\n                    }\r\n                });\r\n            }\r\n        },\r\n        reset: function (){\r\n            this.getDom('content').innerHTML = this.getContentHtml();\r\n            this.fireEvent('dialogafterreset');\r\n        },\r\n        _show: function (){\r\n            if (this._hidden) {\r\n                this.getDom().style.display = '';\r\n\r\n                //要高过编辑器的zindxe\r\n                this.editor.container.style.zIndex && (this.getDom().style.zIndex = this.editor.container.style.zIndex * 1 + 10);\r\n                this._hidden = false;\r\n                this.fireEvent('show');\r\n                baidu.editor.ui.uiUtils.getFixedLayer().style.zIndex = this.getDom().style.zIndex - 4;\r\n            }\r\n        },\r\n        isHidden: function (){\r\n            return this._hidden;\r\n        },\r\n        _hide: function (){\r\n            if (!this._hidden) {\r\n                var wrapNode = this.getDom();\r\n                wrapNode.style.display = 'none';\r\n                wrapNode.style.zIndex = '';\r\n                wrapNode.style.width = '';\r\n                wrapNode.style.height = '';\r\n                this._hidden = true;\r\n                this.fireEvent('hide');\r\n            }\r\n        },\r\n        open: function (){\r\n            if (this.autoReset) {\r\n                //有可能还没有渲染\r\n                try{\r\n                    this.reset();\r\n                }catch(e){\r\n                    this.render();\r\n                    this.open()\r\n                }\r\n            }\r\n            this.showAtCenter();\r\n            if (this.iframeUrl) {\r\n                try {\r\n                    this.getDom('iframe').focus();\r\n                } catch(ex){}\r\n            }\r\n            activeDialog = this;\r\n        },\r\n        _onCloseButtonClick: function (evt, el){\r\n            this.close(false);\r\n        },\r\n        close: function (ok){\r\n            if (this.fireEvent('close', ok) !== false) {\r\n                //还原环境\r\n                if ( this.fullscreen ) {\r\n\r\n                    document.documentElement.style.overflowX = this._originalContext.html.overflowX;\r\n                    document.documentElement.style.overflowY = this._originalContext.html.overflowY;\r\n                    document.body.style.overflowX = this._originalContext.body.overflowX;\r\n                    document.body.style.overflowY = this._originalContext.body.overflowY;\r\n                    delete this._originalContext;\r\n\r\n                }\r\n                this._hide();\r\n\r\n                //销毁content\r\n                var content = this.getDom('content');\r\n                var iframe = this.getDom('iframe');\r\n                if (content && iframe) {\r\n                    var doc = iframe.contentDocument || iframe.contentWindow.document;\r\n                    doc && (doc.body.innerHTML = '');\r\n                    domUtils.remove(content);\r\n                }\r\n            }\r\n        }\r\n    };\r\n    utils.inherits(Dialog, UIBase);\r\n})();\r\n\n\n// ui/menubutton.js\n///import core\r\n///import uicore\r\n///import ui/menu.js\r\n///import ui/splitbutton.js\r\n(function (){\r\n    var utils = baidu.editor.utils,\r\n        Menu = baidu.editor.ui.Menu,\r\n        SplitButton = baidu.editor.ui.SplitButton,\r\n        MenuButton = baidu.editor.ui.MenuButton = function (options){\r\n            this.initOptions(options);\r\n            this.initMenuButton();\r\n        };\r\n    MenuButton.prototype = {\r\n        initMenuButton: function (){\r\n            var me = this;\r\n            this.uiName = \"menubutton\";\r\n            this.popup = new Menu({\r\n                items: me.items,\r\n                className: me.className,\r\n                editor:me.editor\r\n            });\r\n            this.popup.addListener('show', function (){\r\n                var list = this;\r\n                for (var i=0; i<list.items.length; i++) {\r\n                    list.items[i].removeState('checked');\r\n                    if (list.items[i].value == me._value) {\r\n                        list.items[i].addState('checked');\r\n                        this.value = me._value;\r\n                    }\r\n                }\r\n            });\r\n            this.initSplitButton();\r\n        },\r\n        setValue : function(value){\r\n            this._value = value;\r\n        }\r\n        \r\n    };\r\n    utils.inherits(MenuButton, SplitButton);\r\n})();\n\n// ui/multiMenu.js\n///import core\r\n///import uicore\r\n ///commands 表情\r\n(function(){\r\n    var utils = baidu.editor.utils,\r\n        Popup = baidu.editor.ui.Popup,\r\n        SplitButton = baidu.editor.ui.SplitButton,\r\n        MultiMenuPop = baidu.editor.ui.MultiMenuPop = function(options){\r\n            this.initOptions(options);\r\n            this.initMultiMenu();\r\n        };\r\n\r\n    MultiMenuPop.prototype = {\r\n        initMultiMenu: function (){\r\n            var me = this;\r\n            this.popup = new Popup({\r\n                content: '',\r\n                editor : me.editor,\r\n                iframe_rendered: false,\r\n                onshow: function (){\r\n                    if (!this.iframe_rendered) {\r\n                        this.iframe_rendered = true;\r\n                        this.getDom('content').innerHTML = '<iframe id=\"'+me.id+'_iframe\" src=\"'+ me.iframeUrl +'\" frameborder=\"0\"></iframe>';\r\n                        me.editor.container.style.zIndex && (this.getDom().style.zIndex = me.editor.container.style.zIndex * 1 + 1);\r\n                    }\r\n                }\r\n               // canSideUp:false,\r\n               // canSideLeft:false\r\n            });\r\n            this.onbuttonclick = function(){\r\n                this.showPopup();\r\n            };\r\n            this.initSplitButton();\r\n        }\r\n\r\n    };\r\n\r\n    utils.inherits(MultiMenuPop, SplitButton);\r\n})();\r\n\n\n// ui/shortcutmenu.js\n(function () {\n    var UI = baidu.editor.ui,\n        UIBase = UI.UIBase,\n        uiUtils = UI.uiUtils,\n        utils = baidu.editor.utils,\n        domUtils = baidu.editor.dom.domUtils;\n\n    var allMenus = [],//存储所有快捷菜单\n        timeID,\n        isSubMenuShow = false;//是否有子pop显示\n\n    var ShortCutMenu = UI.ShortCutMenu = function (options) {\n        this.initOptions (options);\n        this.initShortCutMenu ();\n    };\n\n    ShortCutMenu.postHide = hideAllMenu;\n\n    ShortCutMenu.prototype = {\n        isHidden : true ,\n        SPACE : 5 ,\n        initShortCutMenu : function () {\n            this.items = this.items || [];\n            this.initUIBase ();\n            this.initItems ();\n            this.initEvent ();\n            allMenus.push (this);\n        } ,\n        initEvent : function () {\n            var me = this,\n                doc = me.editor.document;\n\n            domUtils.on (doc , \"mousemove\" , function (e) {\n                if (me.isHidden === false) {\n                    //有pop显示就不隐藏快捷菜单\n                    if (me.getSubMenuMark () || me.eventType == \"contextmenu\")   return;\n\n\n                    var flag = true,\n                        el = me.getDom (),\n                        wt = el.offsetWidth,\n                        ht = el.offsetHeight,\n                        distanceX = wt / 2 + me.SPACE,//距离中心X标准\n                        distanceY = ht / 2,//距离中心Y标准\n                        x = Math.abs (e.screenX - me.left),//离中心距离横坐标\n                        y = Math.abs (e.screenY - me.top);//离中心距离纵坐标\n\n                    clearTimeout (timeID);\n                    timeID = setTimeout (function () {\n                        if (y > 0 && y < distanceY) {\n                            me.setOpacity (el , \"1\");\n                        } else if (y > distanceY && y < distanceY + 70) {\n                            me.setOpacity (el , \"0.5\");\n                            flag = false;\n                        } else if (y > distanceY + 70 && y < distanceY + 140) {\n                            me.hide ();\n                        }\n\n                        if (flag && x > 0 && x < distanceX) {\n                            me.setOpacity (el , \"1\")\n                        } else if (x > distanceX && x < distanceX + 70) {\n                            me.setOpacity (el , \"0.5\")\n                        } else if (x > distanceX + 70 && x < distanceX + 140) {\n                            me.hide ();\n                        }\n                    });\n                }\n            });\n\n            //ie\\ff下 mouseout不准\n            if (browser.chrome) {\n                domUtils.on (doc , \"mouseout\" , function (e) {\n                    var relatedTgt = e.relatedTarget || e.toElement;\n\n                    if (relatedTgt == null || relatedTgt.tagName == \"HTML\") {\n                        me.hide ();\n                    }\n                });\n            }\n\n            me.editor.addListener (\"afterhidepop\" , function () {\n                if (!me.isHidden) {\n                    isSubMenuShow = true;\n                }\n            });\n\n        } ,\n        initItems : function () {\n            if (utils.isArray (this.items)) {\n                for (var i = 0, len = this.items.length ; i < len ; i++) {\n                    var item = this.items[i].toLowerCase ();\n\n                    if (UI[item]) {\n                        this.items[i] = new UI[item] (this.editor);\n                        this.items[i].className += \" edui-shortcutsubmenu \";\n                    }\n                }\n            }\n        } ,\n        setOpacity : function (el , value) {\n            if (browser.ie && browser.version < 9) {\n                el.style.filter = \"alpha(opacity = \" + parseFloat (value) * 100 + \");\"\n            } else {\n                el.style.opacity = value;\n            }\n        } ,\n        getSubMenuMark : function () {\n            isSubMenuShow = false;\n            var layerEle = uiUtils.getFixedLayer ();\n            var list = domUtils.getElementsByTagName (layerEle , \"div\" , function (node) {\n                return domUtils.hasClass (node , \"edui-shortcutsubmenu edui-popup\")\n            });\n\n            for (var i = 0, node ; node = list[i++] ;) {\n                if (node.style.display != \"none\") {\n                    isSubMenuShow = true;\n                }\n            }\n            return isSubMenuShow;\n        } ,\n        show : function (e , hasContextmenu) {\n            var me = this,\n                offset = {},\n                el = this.getDom (),\n                fixedlayer = uiUtils.getFixedLayer ();\n\n            function setPos (offset) {\n                if (offset.left < 0) {\n                    offset.left = 0;\n                }\n                if (offset.top < 0) {\n                    offset.top = 0;\n                }\n                el.style.cssText = \"position:absolute;left:\" + offset.left + \"px;top:\" + offset.top + \"px;\";\n            }\n\n            function setPosByCxtMenu (menu) {\n                if (!menu.tagName) {\n                    menu = menu.getDom ();\n                }\n                offset.left = parseInt (menu.style.left);\n                offset.top = parseInt (menu.style.top);\n                offset.top -= el.offsetHeight + 15;\n                setPos (offset);\n            }\n\n\n            me.eventType = e.type;\n            el.style.cssText = \"display:block;left:-9999px\";\n\n            if (e.type == \"contextmenu\" && hasContextmenu) {\n                var menu = domUtils.getElementsByTagName (fixedlayer , \"div\" , \"edui-contextmenu\")[0];\n                if (menu) {\n                    setPosByCxtMenu (menu)\n                } else {\n                    me.editor.addListener (\"aftershowcontextmenu\" , function (type , menu) {\n                        setPosByCxtMenu (menu);\n                    });\n                }\n            } else {\n                offset = uiUtils.getViewportOffsetByEvent (e);\n                offset.top -= el.offsetHeight + me.SPACE;\n                offset.left += me.SPACE + 20;\n                setPos (offset);\n                me.setOpacity (el , 0.2);\n            }\n\n\n            me.isHidden = false;\n            me.left = e.screenX + el.offsetWidth / 2 - me.SPACE;\n            me.top = e.screenY - (el.offsetHeight / 2) - me.SPACE;\n\n            if (me.editor) {\n                el.style.zIndex = me.editor.container.style.zIndex * 1 + 10;\n                fixedlayer.style.zIndex = el.style.zIndex - 1;\n            }\n        } ,\n        hide : function () {\n            if (this.getDom ()) {\n                this.getDom ().style.display = \"none\";\n            }\n            this.isHidden = true;\n        } ,\n        postRender : function () {\n            if (utils.isArray (this.items)) {\n                for (var i = 0, item ; item = this.items[i++] ;) {\n                    item.postRender ();\n                }\n            }\n        } ,\n        getHtmlTpl : function () {\n            var buff;\n            if (utils.isArray (this.items)) {\n                buff = [];\n                for (var i = 0 ; i < this.items.length ; i++) {\n                    buff[i] = this.items[i].renderHtml ();\n                }\n                buff = buff.join (\"\");\n            } else {\n                buff = this.items;\n            }\n\n            return '<div id=\"##\" class=\"%% edui-toolbar\" data-src=\"shortcutmenu\" onmousedown=\"return false;\" onselectstart=\"return false;\" >' +\n                buff +\n                '</div>';\n        }\n    };\n\n    utils.inherits (ShortCutMenu , UIBase);\n\n    function hideAllMenu (e) {\n        var tgt = e.target || e.srcElement,\n            cur = domUtils.findParent (tgt , function (node) {\n                return domUtils.hasClass (node , \"edui-shortcutmenu\") || domUtils.hasClass (node , \"edui-popup\");\n            } , true);\n\n        if (!cur) {\n            for (var i = 0, menu ; menu = allMenus[i++] ;) {\n                menu.hide ()\n            }\n        }\n    }\n\n    domUtils.on (document , 'mousedown' , function (e) {\n        hideAllMenu (e);\n    });\n\n    domUtils.on (window , 'scroll' , function (e) {\n        hideAllMenu (e);\n    });\n\n}) ();\n\n\n// ui/breakline.js\n(function (){\n    var utils = baidu.editor.utils,\n        UIBase = baidu.editor.ui.UIBase,\n        Breakline = baidu.editor.ui.Breakline = function (options){\n            this.initOptions(options);\n            this.initSeparator();\n        };\n    Breakline.prototype = {\n        uiName: 'Breakline',\n        initSeparator: function (){\n            this.initUIBase();\n        },\n        getHtmlTpl: function (){\n            return '<br/>';\n        }\n    };\n    utils.inherits(Breakline, UIBase);\n\n})();\n\n\n// ui/message.js\n///import core\n///import uicore\n(function () {\n    var utils = baidu.editor.utils,\n        domUtils = baidu.editor.dom.domUtils,\n        UIBase = baidu.editor.ui.UIBase,\n        Message = baidu.editor.ui.Message = function (options){\n            this.initOptions(options);\n            this.initMessage();\n        };\n\n    Message.prototype = {\n        initMessage: function (){\n            this.initUIBase();\n        },\n        getHtmlTpl: function (){\n            return '<div id=\"##\" class=\"edui-message %%\">' +\n            ' <div id=\"##_closer\" class=\"edui-message-closer\">×</div>' +\n            ' <div id=\"##_body\" class=\"edui-message-body edui-message-type-info\">' +\n            ' <iframe style=\"position:absolute;z-index:-1;left:0;top:0;background-color: transparent;\" frameborder=\"0\" width=\"100%\" height=\"100%\" src=\"about:blank\"></iframe>' +\n            ' <div class=\"edui-shadow\"></div>' +\n            ' <div id=\"##_content\" class=\"edui-message-content\">' +\n            '  </div>' +\n            ' </div>' +\n            '</div>';\n        },\n        reset: function(opt){\n            var me = this;\n            if (!opt.keepshow) {\n                clearTimeout(this.timer);\n                me.timer = setTimeout(function(){\n                    me.hide();\n                }, opt.timeout || 4000);\n            }\n\n            opt.content !== undefined && me.setContent(opt.content);\n            opt.type !== undefined && me.setType(opt.type);\n\n            me.show();\n        },\n        postRender: function(){\n            var me = this,\n                closer = this.getDom('closer');\n            closer && domUtils.on(closer, 'click', function(){\n                me.hide();\n            });\n        },\n        setContent: function(content){\n            this.getDom('content').innerHTML = content;\n        },\n        setType: function(type){\n            type = type || 'info';\n            var body = this.getDom('body');\n            body.className = body.className.replace(/edui-message-type-[\\w-]+/, 'edui-message-type-' + type);\n        },\n        getContent: function(){\n            return this.getDom('content').innerHTML;\n        },\n        getType: function(){\n            var arr = this.getDom('body').match(/edui-message-type-([\\w-]+)/);\n            return arr ? arr[1]:'';\n        },\n        show: function (){\n            this.getDom().style.display = 'block';\n        },\n        hide: function (){\n            var dom = this.getDom();\n            if (dom) {\n                dom.style.display = 'none';\n                dom.parentNode && dom.parentNode.removeChild(dom);\n            }\n        }\n    };\n\n    utils.inherits(Message, UIBase);\n\n})();\n\n\n// adapter/editorui.js\n//ui跟编辑器的适配層\n//那个按钮弹出是dialog，是下拉筐等都是在这个js中配置\n//自己写的ui也要在这里配置，放到baidu.editor.ui下边，当编辑器实例化的时候会根据ueditor.config中的toolbars找到相应的进行实例化\n(function () {\n    var utils = baidu.editor.utils;\n    var editorui = baidu.editor.ui;\n    var _Dialog = editorui.Dialog;\n    editorui.buttons = {};\n\n    editorui.Dialog = function (options) {\n        var dialog = new _Dialog(options);\n        dialog.addListener('hide', function () {\n\n            if (dialog.editor) {\n                var editor = dialog.editor;\n                try {\n                    if (browser.gecko) {\n                        var y = editor.window.scrollY,\n                            x = editor.window.scrollX;\n                        editor.body.focus();\n                        editor.window.scrollTo(x, y);\n                    } else {\n                        editor.focus();\n                    }\n\n\n                } catch (ex) {\n                }\n            }\n        });\n        return dialog;\n    };\n\n    var iframeUrlMap = {\n        'anchor':'~/dialogs/anchor/anchor.html',\n        'insertimage':'~/dialogs/image/image.html',\n        'link':'~/dialogs/link/link.html',\n        'spechars':'~/dialogs/spechars/spechars.html',\n        'searchreplace':'~/dialogs/searchreplace/searchreplace.html',\n        'map':'~/dialogs/map/map.html',\n        'gmap':'~/dialogs/gmap/gmap.html',\n        'insertvideo':'~/dialogs/video/video.html',\n        'help':'~/dialogs/help/help.html',\n        'preview':'~/dialogs/preview/preview.html',\n        'emotion':'~/dialogs/emotion/emotion.html',\n        'wordimage':'~/dialogs/wordimage/wordimage.html',\n        'attachment':'~/dialogs/attachment/attachment.html',\n        'insertframe':'~/dialogs/insertframe/insertframe.html',\n        'edittip':'~/dialogs/table/edittip.html',\n        'edittable':'~/dialogs/table/edittable.html',\n        'edittd':'~/dialogs/table/edittd.html',\n        'webapp':'~/dialogs/webapp/webapp.html',\n        'snapscreen':'~/dialogs/snapscreen/snapscreen.html',\n        'scrawl':'~/dialogs/scrawl/scrawl.html',\n        'music':'~/dialogs/music/music.html',\n        'template':'~/dialogs/template/template.html',\n        'background':'~/dialogs/background/background.html',\n        'charts': '~/dialogs/charts/charts.html'\n    };\n    //为工具栏添加按钮，以下都是统一的按钮触发命令，所以写在一起\n    var btnCmds = ['undo', 'redo', 'formatmatch',\n        'bold', 'italic', 'underline', 'fontborder', 'touppercase', 'tolowercase',\n        'strikethrough', 'subscript', 'superscript', 'source', 'indent', 'outdent',\n        'blockquote', 'pasteplain', 'pagebreak',\n        'selectall', 'print','horizontal', 'removeformat', 'time', 'date', 'unlink',\n        'insertparagraphbeforetable', 'insertrow', 'insertcol', 'mergeright', 'mergedown', 'deleterow',\n        'deletecol', 'splittorows', 'splittocols', 'splittocells', 'mergecells', 'deletetable', 'drafts'];\n\n    for (var i = 0, ci; ci = btnCmds[i++];) {\n        ci = ci.toLowerCase();\n        editorui[ci] = function (cmd) {\n            return function (editor) {\n                var ui = new editorui.Button({\n                    className:'edui-for-' + cmd,\n                    title:editor.options.labelMap[cmd] || editor.getLang(\"labelMap.\" + cmd) || '',\n                    onclick:function () {\n                        editor.execCommand(cmd);\n                    },\n                    theme:editor.options.theme,\n                    showText:false\n                });\n                editorui.buttons[cmd] = ui;\n                editor.addListener('selectionchange', function (type, causeByUi, uiReady) {\n                    var state = editor.queryCommandState(cmd);\n                    if (state == -1) {\n                        ui.setDisabled(true);\n                        ui.setChecked(false);\n                    } else {\n                        if (!uiReady) {\n                            ui.setDisabled(false);\n                            ui.setChecked(state);\n                        }\n                    }\n                });\n                return ui;\n            };\n        }(ci);\n    }\n\n    //清除文档\n    editorui.cleardoc = function (editor) {\n        var ui = new editorui.Button({\n            className:'edui-for-cleardoc',\n            title:editor.options.labelMap.cleardoc || editor.getLang(\"labelMap.cleardoc\") || '',\n            theme:editor.options.theme,\n            onclick:function () {\n                if (confirm(editor.getLang(\"confirmClear\"))) {\n                    editor.execCommand('cleardoc');\n                }\n            }\n        });\n        editorui.buttons[\"cleardoc\"] = ui;\n        editor.addListener('selectionchange', function () {\n            ui.setDisabled(editor.queryCommandState('cleardoc') == -1);\n        });\n        return ui;\n    };\n\n    //排版，图片排版，文字方向\n    var typeset = {\n        'justify':['left', 'right', 'center', 'justify'],\n        'imagefloat':['none', 'left', 'center', 'right'],\n        'directionality':['ltr', 'rtl']\n    };\n\n    for (var p in typeset) {\n\n        (function (cmd, val) {\n            for (var i = 0, ci; ci = val[i++];) {\n                (function (cmd2) {\n                    editorui[cmd.replace('float', '') + cmd2] = function (editor) {\n                        var ui = new editorui.Button({\n                            className:'edui-for-' + cmd.replace('float', '') + cmd2,\n                            title:editor.options.labelMap[cmd.replace('float', '') + cmd2] || editor.getLang(\"labelMap.\" + cmd.replace('float', '') + cmd2) || '',\n                            theme:editor.options.theme,\n                            onclick:function () {\n                                editor.execCommand(cmd, cmd2);\n                            }\n                        });\n                        editorui.buttons[cmd] = ui;\n                        editor.addListener('selectionchange', function (type, causeByUi, uiReady) {\n                            ui.setDisabled(editor.queryCommandState(cmd) == -1);\n                            ui.setChecked(editor.queryCommandValue(cmd) == cmd2 && !uiReady);\n                        });\n                        return ui;\n                    };\n                })(ci)\n            }\n        })(p, typeset[p])\n    }\n\n    //字体颜色和背景颜色\n    for (var i = 0, ci; ci = ['backcolor', 'forecolor'][i++];) {\n        editorui[ci] = function (cmd) {\n            return function (editor) {\n                var ui = new editorui.ColorButton({\n                    className:'edui-for-' + cmd,\n                    color:'default',\n                    title:editor.options.labelMap[cmd] || editor.getLang(\"labelMap.\" + cmd) || '',\n                    editor:editor,\n                    onpickcolor:function (t, color) {\n                        editor.execCommand(cmd, color);\n                    },\n                    onpicknocolor:function () {\n                        editor.execCommand(cmd, 'default');\n                        this.setColor('transparent');\n                        this.color = 'default';\n                    },\n                    onbuttonclick:function () {\n                        editor.execCommand(cmd, this.color);\n                    }\n                });\n                editorui.buttons[cmd] = ui;\n                editor.addListener('selectionchange', function () {\n                    ui.setDisabled(editor.queryCommandState(cmd) == -1);\n                });\n                return ui;\n            };\n        }(ci);\n    }\n\n\n    var dialogBtns = {\n        noOk:['searchreplace', 'help', 'spechars', 'webapp','preview'],\n        ok:['attachment', 'anchor', 'link', 'insertimage', 'map', 'gmap', 'insertframe', 'wordimage',\n            'insertvideo', 'insertframe', 'edittip', 'edittable', 'edittd', 'scrawl', 'template', 'music', 'background', 'charts']\n    };\n\n    for (var p in dialogBtns) {\n        (function (type, vals) {\n            for (var i = 0, ci; ci = vals[i++];) {\n                //todo opera下存在问题\n                if (browser.opera && ci === \"searchreplace\") {\n                    continue;\n                }\n                (function (cmd) {\n                    editorui[cmd] = function (editor, iframeUrl, title) {\n                        iframeUrl = iframeUrl || (editor.options.iframeUrlMap || {})[cmd] || iframeUrlMap[cmd];\n                        title = editor.options.labelMap[cmd] || editor.getLang(\"labelMap.\" + cmd) || '';\n\n                        var dialog;\n                        //没有iframeUrl不创建dialog\n                        if (iframeUrl) {\n                            dialog = new editorui.Dialog(utils.extend({\n                                iframeUrl:editor.ui.mapUrl(iframeUrl),\n                                editor:editor,\n                                className:'edui-for-' + cmd,\n                                title:title,\n                                holdScroll: cmd === 'insertimage',\n                                fullscreen: /charts|preview/.test(cmd),\n                                closeDialog:editor.getLang(\"closeDialog\")\n                            }, type == 'ok' ? {\n                                buttons:[\n                                    {\n                                        className:'edui-okbutton',\n                                        label:editor.getLang(\"ok\"),\n                                        editor:editor,\n                                        onclick:function () {\n                                            dialog.close(true);\n                                        }\n                                    },\n                                    {\n                                        className:'edui-cancelbutton',\n                                        label:editor.getLang(\"cancel\"),\n                                        editor:editor,\n                                        onclick:function () {\n                                            dialog.close(false);\n                                        }\n                                    }\n                                ]\n                            } : {}));\n\n                            editor.ui._dialogs[cmd + \"Dialog\"] = dialog;\n                        }\n\n                        var ui = new editorui.Button({\n                            className:'edui-for-' + cmd,\n                            title:title,\n                            onclick:function () {\n                                if (dialog) {\n                                    switch (cmd) {\n                                        case \"wordimage\":\n                                            var images = editor.execCommand(\"wordimage\");\n                                            if (images && images.length) {\n                                                dialog.render();\n                                                dialog.open();\n                                            }\n                                            break;\n                                        case \"scrawl\":\n                                            if (editor.queryCommandState(\"scrawl\") != -1) {\n                                                dialog.render();\n                                                dialog.open();\n                                            }\n\n                                            break;\n                                        default:\n                                            dialog.render();\n                                            dialog.open();\n                                    }\n                                }\n                            },\n                            theme:editor.options.theme,\n                            disabled:(cmd == 'scrawl' && editor.queryCommandState(\"scrawl\") == -1) || ( cmd == 'charts' )\n                        });\n                        editorui.buttons[cmd] = ui;\n                        editor.addListener('selectionchange', function () {\n                            //只存在于右键菜单而无工具栏按钮的ui不需要检测状态\n                            var unNeedCheckState = {'edittable':1};\n                            if (cmd in unNeedCheckState)return;\n\n                            var state = editor.queryCommandState(cmd);\n                            if (ui.getDom()) {\n                                ui.setDisabled(state == -1);\n                                ui.setChecked(state);\n                            }\n\n                        });\n\n                        return ui;\n                    };\n                })(ci.toLowerCase())\n            }\n        })(p, dialogBtns[p]);\n    }\n\n    editorui.snapscreen = function (editor, iframeUrl, title) {\n        title = editor.options.labelMap['snapscreen'] || editor.getLang(\"labelMap.snapscreen\") || '';\n        var ui = new editorui.Button({\n            className:'edui-for-snapscreen',\n            title:title,\n            onclick:function () {\n                editor.execCommand(\"snapscreen\");\n            },\n            theme:editor.options.theme\n\n        });\n        editorui.buttons['snapscreen'] = ui;\n        iframeUrl = iframeUrl || (editor.options.iframeUrlMap || {})[\"snapscreen\"] || iframeUrlMap[\"snapscreen\"];\n        if (iframeUrl) {\n            var dialog = new editorui.Dialog({\n                iframeUrl:editor.ui.mapUrl(iframeUrl),\n                editor:editor,\n                className:'edui-for-snapscreen',\n                title:title,\n                buttons:[\n                    {\n                        className:'edui-okbutton',\n                        label:editor.getLang(\"ok\"),\n                        editor:editor,\n                        onclick:function () {\n                            dialog.close(true);\n                        }\n                    },\n                    {\n                        className:'edui-cancelbutton',\n                        label:editor.getLang(\"cancel\"),\n                        editor:editor,\n                        onclick:function () {\n                            dialog.close(false);\n                        }\n                    }\n                ]\n\n            });\n            dialog.render();\n            editor.ui._dialogs[\"snapscreenDialog\"] = dialog;\n        }\n        editor.addListener('selectionchange', function () {\n            ui.setDisabled(editor.queryCommandState('snapscreen') == -1);\n        });\n        return ui;\n    };\n\n    editorui.insertcode = function (editor, list, title) {\n        list = editor.options['insertcode'] || [];\n        title = editor.options.labelMap['insertcode'] || editor.getLang(\"labelMap.insertcode\") || '';\n       // if (!list.length) return;\n        var items = [];\n        utils.each(list,function(key,val){\n            items.push({\n                label:key,\n                value:val,\n                theme:editor.options.theme,\n                renderLabelHtml:function () {\n                    return '<div class=\"edui-label %%-label\" >' + (this.label || '') + '</div>';\n                }\n            });\n        });\n\n        var ui = new editorui.Combox({\n            editor:editor,\n            items:items,\n            onselect:function (t, index) {\n                editor.execCommand('insertcode', this.items[index].value);\n            },\n            onbuttonclick:function () {\n                this.showPopup();\n            },\n            title:title,\n            initValue:title,\n            className:'edui-for-insertcode',\n            indexByValue:function (value) {\n                if (value) {\n                    for (var i = 0, ci; ci = this.items[i]; i++) {\n                        if (ci.value.indexOf(value) != -1)\n                            return i;\n                    }\n                }\n\n                return -1;\n            }\n        });\n        editorui.buttons['insertcode'] = ui;\n        editor.addListener('selectionchange', function (type, causeByUi, uiReady) {\n            if (!uiReady) {\n                var state = editor.queryCommandState('insertcode');\n                if (state == -1) {\n                    ui.setDisabled(true);\n                } else {\n                    ui.setDisabled(false);\n                    var value = editor.queryCommandValue('insertcode');\n                    if(!value){\n                        ui.setValue(title);\n                        return;\n                    }\n                    //trace:1871 ie下从源码模式切换回来时，字体会带单引号，而且会有逗号\n                    value && (value = value.replace(/['\"]/g, '').split(',')[0]);\n                    ui.setValue(value);\n\n                }\n            }\n\n        });\n        return ui;\n    };\n    editorui.fontfamily = function (editor, list, title) {\n\n        list = editor.options['fontfamily'] || [];\n        title = editor.options.labelMap['fontfamily'] || editor.getLang(\"labelMap.fontfamily\") || '';\n        if (!list.length) return;\n        for (var i = 0, ci, items = []; ci = list[i]; i++) {\n            var langLabel = editor.getLang('fontfamily')[ci.name] || \"\";\n            (function (key, val) {\n                items.push({\n                    label:key,\n                    value:val,\n                    theme:editor.options.theme,\n                    renderLabelHtml:function () {\n                        return '<div class=\"edui-label %%-label\" style=\"font-family:' +\n                            utils.unhtml(this.value) + '\">' + (this.label || '') + '</div>';\n                    }\n                });\n            })(ci.label || langLabel, ci.val)\n        }\n        var ui = new editorui.Combox({\n            editor:editor,\n            items:items,\n            onselect:function (t, index) {\n                editor.execCommand('FontFamily', this.items[index].value);\n            },\n            onbuttonclick:function () {\n                this.showPopup();\n            },\n            title:title,\n            initValue:title,\n            className:'edui-for-fontfamily',\n            indexByValue:function (value) {\n                if (value) {\n                    for (var i = 0, ci; ci = this.items[i]; i++) {\n                        if (ci.value.indexOf(value) != -1)\n                            return i;\n                    }\n                }\n\n                return -1;\n            }\n        });\n        editorui.buttons['fontfamily'] = ui;\n        editor.addListener('selectionchange', function (type, causeByUi, uiReady) {\n            if (!uiReady) {\n                var state = editor.queryCommandState('FontFamily');\n                if (state == -1) {\n                    ui.setDisabled(true);\n                } else {\n                    ui.setDisabled(false);\n                    var value = editor.queryCommandValue('FontFamily');\n                    //trace:1871 ie下从源码模式切换回来时，字体会带单引号，而且会有逗号\n                    value && (value = value.replace(/['\"]/g, '').split(',')[0]);\n                    ui.setValue(value);\n\n                }\n            }\n\n        });\n        return ui;\n    };\n\n    editorui.fontsize = function (editor, list, title) {\n        title = editor.options.labelMap['fontsize'] || editor.getLang(\"labelMap.fontsize\") || '';\n        list = list || editor.options['fontsize'] || [];\n        if (!list.length) return;\n        var items = [];\n        for (var i = 0; i < list.length; i++) {\n            var size = list[i] + 'px';\n            items.push({\n                label:size,\n                value:size,\n                theme:editor.options.theme,\n                renderLabelHtml:function () {\n                    return '<div class=\"edui-label %%-label\" style=\"line-height:1;font-size:' +\n                        this.value + '\">' + (this.label || '') + '</div>';\n                }\n            });\n        }\n        var ui = new editorui.Combox({\n            editor:editor,\n            items:items,\n            title:title,\n            initValue:title,\n            onselect:function (t, index) {\n                editor.execCommand('FontSize', this.items[index].value);\n            },\n            onbuttonclick:function () {\n                this.showPopup();\n            },\n            className:'edui-for-fontsize'\n        });\n        editorui.buttons['fontsize'] = ui;\n        editor.addListener('selectionchange', function (type, causeByUi, uiReady) {\n            if (!uiReady) {\n                var state = editor.queryCommandState('FontSize');\n                if (state == -1) {\n                    ui.setDisabled(true);\n                } else {\n                    ui.setDisabled(false);\n                    ui.setValue(editor.queryCommandValue('FontSize'));\n                }\n            }\n\n        });\n        return ui;\n    };\n\n    editorui.paragraph = function (editor, list, title) {\n        title = editor.options.labelMap['paragraph'] || editor.getLang(\"labelMap.paragraph\") || '';\n        list = editor.options['paragraph'] || [];\n        if (utils.isEmptyObject(list)) return;\n        var items = [];\n        for (var i in list) {\n            items.push({\n                value:i,\n                label:list[i] || editor.getLang(\"paragraph\")[i],\n                theme:editor.options.theme,\n                renderLabelHtml:function () {\n                    return '<div class=\"edui-label %%-label\"><span class=\"edui-for-' + this.value + '\">' + (this.label || '') + '</span></div>';\n                }\n            })\n        }\n        var ui = new editorui.Combox({\n            editor:editor,\n            items:items,\n            title:title,\n            initValue:title,\n            className:'edui-for-paragraph',\n            onselect:function (t, index) {\n                editor.execCommand('Paragraph', this.items[index].value);\n            },\n            onbuttonclick:function () {\n                this.showPopup();\n            }\n        });\n        editorui.buttons['paragraph'] = ui;\n        editor.addListener('selectionchange', function (type, causeByUi, uiReady) {\n            if (!uiReady) {\n                var state = editor.queryCommandState('Paragraph');\n                if (state == -1) {\n                    ui.setDisabled(true);\n                } else {\n                    ui.setDisabled(false);\n                    var value = editor.queryCommandValue('Paragraph');\n                    var index = ui.indexByValue(value);\n                    if (index != -1) {\n                        ui.setValue(value);\n                    } else {\n                        ui.setValue(ui.initValue);\n                    }\n                }\n            }\n\n        });\n        return ui;\n    };\n\n\n    //自定义标题\n    editorui.customstyle = function (editor) {\n        var list = editor.options['customstyle'] || [],\n            title = editor.options.labelMap['customstyle'] || editor.getLang(\"labelMap.customstyle\") || '';\n        if (!list.length)return;\n        var langCs = editor.getLang('customstyle');\n        for (var i = 0, items = [], t; t = list[i++];) {\n            (function (t) {\n                var ck = {};\n                ck.label = t.label ? t.label : langCs[t.name];\n                ck.style = t.style;\n                ck.className = t.className;\n                ck.tag = t.tag;\n                items.push({\n                    label:ck.label,\n                    value:ck,\n                    theme:editor.options.theme,\n                    renderLabelHtml:function () {\n                        return '<div class=\"edui-label %%-label\">' + '<' + ck.tag + ' ' + (ck.className ? ' class=\"' + ck.className + '\"' : \"\")\n                            + (ck.style ? ' style=\"' + ck.style + '\"' : \"\") + '>' + ck.label + \"<\\/\" + ck.tag + \">\"\n                            + '</div>';\n                    }\n                });\n            })(t);\n        }\n\n        var ui = new editorui.Combox({\n            editor:editor,\n            items:items,\n            title:title,\n            initValue:title,\n            className:'edui-for-customstyle',\n            onselect:function (t, index) {\n                editor.execCommand('customstyle', this.items[index].value);\n            },\n            onbuttonclick:function () {\n                this.showPopup();\n            },\n            indexByValue:function (value) {\n                for (var i = 0, ti; ti = this.items[i++];) {\n                    if (ti.label == value) {\n                        return i - 1\n                    }\n                }\n                return -1;\n            }\n        });\n        editorui.buttons['customstyle'] = ui;\n        editor.addListener('selectionchange', function (type, causeByUi, uiReady) {\n            if (!uiReady) {\n                var state = editor.queryCommandState('customstyle');\n                if (state == -1) {\n                    ui.setDisabled(true);\n                } else {\n                    ui.setDisabled(false);\n                    var value = editor.queryCommandValue('customstyle');\n                    var index = ui.indexByValue(value);\n                    if (index != -1) {\n                        ui.setValue(value);\n                    } else {\n                        ui.setValue(ui.initValue);\n                    }\n                }\n            }\n\n        });\n        return ui;\n    };\n    editorui.inserttable = function (editor, iframeUrl, title) {\n        title = editor.options.labelMap['inserttable'] || editor.getLang(\"labelMap.inserttable\") || '';\n        var ui = new editorui.TableButton({\n            editor:editor,\n            title:title,\n            className:'edui-for-inserttable',\n            onpicktable:function (t, numCols, numRows) {\n                editor.execCommand('InsertTable', {numRows:numRows, numCols:numCols, border:1});\n            },\n            onbuttonclick:function () {\n                this.showPopup();\n            }\n        });\n        editorui.buttons['inserttable'] = ui;\n        editor.addListener('selectionchange', function () {\n            ui.setDisabled(editor.queryCommandState('inserttable') == -1);\n        });\n        return ui;\n    };\n\n    editorui.lineheight = function (editor) {\n        var val = editor.options.lineheight || [];\n        if (!val.length)return;\n        for (var i = 0, ci, items = []; ci = val[i++];) {\n            items.push({\n                //todo:写死了\n                label:ci,\n                value:ci,\n                theme:editor.options.theme,\n                onclick:function () {\n                    editor.execCommand(\"lineheight\", this.value);\n                }\n            })\n        }\n        var ui = new editorui.MenuButton({\n            editor:editor,\n            className:'edui-for-lineheight',\n            title:editor.options.labelMap['lineheight'] || editor.getLang(\"labelMap.lineheight\") || '',\n            items:items,\n            onbuttonclick:function () {\n                var value = editor.queryCommandValue('LineHeight') || this.value;\n                editor.execCommand(\"LineHeight\", value);\n            }\n        });\n        editorui.buttons['lineheight'] = ui;\n        editor.addListener('selectionchange', function () {\n            var state = editor.queryCommandState('LineHeight');\n            if (state == -1) {\n                ui.setDisabled(true);\n            } else {\n                ui.setDisabled(false);\n                var value = editor.queryCommandValue('LineHeight');\n                value && ui.setValue((value + '').replace(/cm/, ''));\n                ui.setChecked(state)\n            }\n        });\n        return ui;\n    };\n\n    var rowspacings = ['top', 'bottom'];\n    for (var r = 0, ri; ri = rowspacings[r++];) {\n        (function (cmd) {\n            editorui['rowspacing' + cmd] = function (editor) {\n                var val = editor.options['rowspacing' + cmd] || [];\n                if (!val.length) return null;\n                for (var i = 0, ci, items = []; ci = val[i++];) {\n                    items.push({\n                        label:ci,\n                        value:ci,\n                        theme:editor.options.theme,\n                        onclick:function () {\n                            editor.execCommand(\"rowspacing\", this.value, cmd);\n                        }\n                    })\n                }\n                var ui = new editorui.MenuButton({\n                    editor:editor,\n                    className:'edui-for-rowspacing' + cmd,\n                    title:editor.options.labelMap['rowspacing' + cmd] || editor.getLang(\"labelMap.rowspacing\" + cmd) || '',\n                    items:items,\n                    onbuttonclick:function () {\n                        var value = editor.queryCommandValue('rowspacing', cmd) || this.value;\n                        editor.execCommand(\"rowspacing\", value, cmd);\n                    }\n                });\n                editorui.buttons[cmd] = ui;\n                editor.addListener('selectionchange', function () {\n                    var state = editor.queryCommandState('rowspacing', cmd);\n                    if (state == -1) {\n                        ui.setDisabled(true);\n                    } else {\n                        ui.setDisabled(false);\n                        var value = editor.queryCommandValue('rowspacing', cmd);\n                        value && ui.setValue((value + '').replace(/%/, ''));\n                        ui.setChecked(state)\n                    }\n                });\n                return ui;\n            }\n        })(ri)\n    }\n    //有序，无序列表\n    var lists = ['insertorderedlist', 'insertunorderedlist'];\n    for (var l = 0, cl; cl = lists[l++];) {\n        (function (cmd) {\n            editorui[cmd] = function (editor) {\n                var vals = editor.options[cmd],\n                    _onMenuClick = function () {\n                        editor.execCommand(cmd, this.value);\n                    }, items = [];\n                for (var i in vals) {\n                    items.push({\n                        label:vals[i] || editor.getLang()[cmd][i] || \"\",\n                        value:i,\n                        theme:editor.options.theme,\n                        onclick:_onMenuClick\n                    })\n                }\n                var ui = new editorui.MenuButton({\n                    editor:editor,\n                    className:'edui-for-' + cmd,\n                    title:editor.getLang(\"labelMap.\" + cmd) || '',\n                    'items':items,\n                    onbuttonclick:function () {\n                        var value = editor.queryCommandValue(cmd) || this.value;\n                        editor.execCommand(cmd, value);\n                    }\n                });\n                editorui.buttons[cmd] = ui;\n                editor.addListener('selectionchange', function () {\n                    var state = editor.queryCommandState(cmd);\n                    if (state == -1) {\n                        ui.setDisabled(true);\n                    } else {\n                        ui.setDisabled(false);\n                        var value = editor.queryCommandValue(cmd);\n                        ui.setValue(value);\n                        ui.setChecked(state)\n                    }\n                });\n                return ui;\n            };\n        })(cl)\n    }\n\n    editorui.fullscreen = function (editor, title) {\n        title = editor.options.labelMap['fullscreen'] || editor.getLang(\"labelMap.fullscreen\") || '';\n        var ui = new editorui.Button({\n            className:'edui-for-fullscreen',\n            title:title,\n            theme:editor.options.theme,\n            onclick:function () {\n                if (editor.ui) {\n                    editor.ui.setFullScreen(!editor.ui.isFullScreen());\n                }\n                this.setChecked(editor.ui.isFullScreen());\n            }\n        });\n        editorui.buttons['fullscreen'] = ui;\n        editor.addListener('selectionchange', function () {\n            var state = editor.queryCommandState('fullscreen');\n            ui.setDisabled(state == -1);\n            ui.setChecked(editor.ui.isFullScreen());\n        });\n        return ui;\n    };\n\n    // 表情\n    editorui[\"emotion\"] = function (editor, iframeUrl) {\n        var cmd = \"emotion\";\n        var ui = new editorui.MultiMenuPop({\n            title:editor.options.labelMap[cmd] || editor.getLang(\"labelMap.\" + cmd + \"\") || '',\n            editor:editor,\n            className:'edui-for-' + cmd,\n            iframeUrl:editor.ui.mapUrl(iframeUrl || (editor.options.iframeUrlMap || {})[cmd] || iframeUrlMap[cmd])\n        });\n        editorui.buttons[cmd] = ui;\n\n        editor.addListener('selectionchange', function () {\n            ui.setDisabled(editor.queryCommandState(cmd) == -1)\n        });\n        return ui;\n    };\n\n    editorui.autotypeset = function (editor) {\n        var ui = new editorui.AutoTypeSetButton({\n            editor:editor,\n            title:editor.options.labelMap['autotypeset'] || editor.getLang(\"labelMap.autotypeset\") || '',\n            className:'edui-for-autotypeset',\n            onbuttonclick:function () {\n                editor.execCommand('autotypeset')\n            }\n        });\n        editorui.buttons['autotypeset'] = ui;\n        editor.addListener('selectionchange', function () {\n            ui.setDisabled(editor.queryCommandState('autotypeset') == -1);\n        });\n        return ui;\n    };\n\n    /* 简单上传插件 */\n    editorui[\"simpleupload\"] = function (editor) {\n        var name = 'simpleupload',\n            ui = new editorui.Button({\n                className:'edui-for-' + name,\n                title:editor.options.labelMap[name] || editor.getLang(\"labelMap.\" + name) || '',\n                onclick:function () {},\n                theme:editor.options.theme,\n                showText:false\n            });\n        editorui.buttons[name] = ui;\n        editor.addListener('ready', function() {\n            var b = ui.getDom('body'),\n                iconSpan = b.children[0];\n            editor.fireEvent('simpleuploadbtnready', iconSpan);\n        });\n        editor.addListener('selectionchange', function (type, causeByUi, uiReady) {\n            var state = editor.queryCommandState(name);\n            if (state == -1) {\n                ui.setDisabled(true);\n                ui.setChecked(false);\n            } else {\n                if (!uiReady) {\n                    ui.setDisabled(false);\n                    ui.setChecked(state);\n                }\n            }\n        });\n        return ui;\n    };\n\n})();\n\n\n// adapter/editor.js\n///import core\n///commands 全屏\n///commandsName FullScreen\n///commandsTitle  全屏\n(function () {\n    var utils = baidu.editor.utils,\n        uiUtils = baidu.editor.ui.uiUtils,\n        UIBase = baidu.editor.ui.UIBase,\n        domUtils = baidu.editor.dom.domUtils;\n    var nodeStack = [];\n\n    function EditorUI(options) {\n        this.initOptions(options);\n        this.initEditorUI();\n    }\n\n    EditorUI.prototype = {\n        uiName:'editor',\n        initEditorUI:function () {\n            this.editor.ui = this;\n            this._dialogs = {};\n            this.initUIBase();\n            this._initToolbars();\n            var editor = this.editor,\n                me = this;\n\n            editor.addListener('ready', function () {\n                //提供getDialog方法\n                editor.getDialog = function (name) {\n                    return editor.ui._dialogs[name + \"Dialog\"];\n                };\n                domUtils.on(editor.window, 'scroll', function (evt) {\n                    baidu.editor.ui.Popup.postHide(evt);\n                });\n                //提供编辑器实时宽高(全屏时宽高不变化)\n                editor.ui._actualFrameWidth = editor.options.initialFrameWidth;\n\n                UE.browser.ie && UE.browser.version === 6 && editor.container.ownerDocument.execCommand(\"BackgroundImageCache\", false, true);\n\n                //display bottom-bar label based on config\n                if (editor.options.elementPathEnabled) {\n                    editor.ui.getDom('elementpath').innerHTML = '<div class=\"edui-editor-breadcrumb\">' + editor.getLang(\"elementPathTip\") + ':</div>';\n                }\n                if (editor.options.wordCount) {\n                    function countFn() {\n                        setCount(editor,me);\n                        domUtils.un(editor.document, \"click\", arguments.callee);\n                    }\n                    domUtils.on(editor.document, \"click\", countFn);\n                    editor.ui.getDom('wordcount').innerHTML = editor.getLang(\"wordCountTip\");\n                }\n                editor.ui._scale();\n                if (editor.options.scaleEnabled) {\n                    if (editor.autoHeightEnabled) {\n                        editor.disableAutoHeight();\n                    }\n                    me.enableScale();\n                } else {\n                    me.disableScale();\n                }\n                if (!editor.options.elementPathEnabled && !editor.options.wordCount && !editor.options.scaleEnabled) {\n                    editor.ui.getDom('elementpath').style.display = \"none\";\n                    editor.ui.getDom('wordcount').style.display = \"none\";\n                    editor.ui.getDom('scale').style.display = \"none\";\n                }\n\n                if (!editor.selection.isFocus())return;\n                editor.fireEvent('selectionchange', false, true);\n\n\n            });\n\n            editor.addListener('mousedown', function (t, evt) {\n                var el = evt.target || evt.srcElement;\n                baidu.editor.ui.Popup.postHide(evt, el);\n                baidu.editor.ui.ShortCutMenu.postHide(evt);\n\n            });\n            editor.addListener(\"delcells\", function () {\n                if (UE.ui['edittip']) {\n                    new UE.ui['edittip'](editor);\n                }\n                editor.getDialog('edittip').open();\n            });\n\n            var pastePop, isPaste = false, timer;\n            editor.addListener(\"afterpaste\", function () {\n                if(editor.queryCommandState('pasteplain'))\n                    return;\n                if(baidu.editor.ui.PastePicker){\n                    pastePop = new baidu.editor.ui.Popup({\n                        content:new baidu.editor.ui.PastePicker({editor:editor}),\n                        editor:editor,\n                        className:'edui-wordpastepop'\n                    });\n                    pastePop.render();\n                }\n                isPaste = true;\n            });\n\n            editor.addListener(\"afterinserthtml\", function () {\n                clearTimeout(timer);\n                timer = setTimeout(function () {\n                    if (pastePop && (isPaste || editor.ui._isTransfer)) {\n                        if(pastePop.isHidden()){\n                            var span = domUtils.createElement(editor.document, 'span', {\n                                    'style':\"line-height:0px;\",\n                                    'innerHTML':'\\ufeff'\n                                }),\n                                range = editor.selection.getRange();\n                            range.insertNode(span);\n                            var tmp= getDomNode(span, 'firstChild', 'previousSibling');\n                            tmp && pastePop.showAnchor(tmp.nodeType == 3 ? tmp.parentNode : tmp);\n                            domUtils.remove(span);\n                        }else{\n                            pastePop.show();\n                        }\n                        delete editor.ui._isTransfer;\n                        isPaste = false;\n                    }\n                }, 200)\n            });\n            editor.addListener('contextmenu', function (t, evt) {\n                baidu.editor.ui.Popup.postHide(evt);\n            });\n            editor.addListener('keydown', function (t, evt) {\n                if (pastePop)    pastePop.dispose(evt);\n                var keyCode = evt.keyCode || evt.which;\n                if(evt.altKey&&keyCode==90){\n                    UE.ui.buttons['fullscreen'].onclick();\n                }\n            });\n            editor.addListener('wordcount', function (type) {\n                setCount(this,me);\n            });\n            function setCount(editor,ui) {\n                editor.setOpt({\n                    wordCount:true,\n                    maximumWords:10000,\n                    wordCountMsg:editor.options.wordCountMsg || editor.getLang(\"wordCountMsg\"),\n                    wordOverFlowMsg:editor.options.wordOverFlowMsg || editor.getLang(\"wordOverFlowMsg\")\n                });\n                var opt = editor.options,\n                    max = opt.maximumWords,\n                    msg = opt.wordCountMsg ,\n                    errMsg = opt.wordOverFlowMsg,\n                    countDom = ui.getDom('wordcount');\n                if (!opt.wordCount) {\n                    return;\n                }\n                var count = editor.getContentLength(true);\n                if (count > max) {\n                    countDom.innerHTML = errMsg;\n                    editor.fireEvent(\"wordcountoverflow\");\n                } else {\n                    countDom.innerHTML = msg.replace(\"{#leave}\", max - count).replace(\"{#count}\", count);\n                }\n            }\n\n            editor.addListener('selectionchange', function () {\n                if (editor.options.elementPathEnabled) {\n                    me[(editor.queryCommandState('elementpath') == -1 ? 'dis' : 'en') + 'ableElementPath']()\n                }\n                if (editor.options.scaleEnabled) {\n                    me[(editor.queryCommandState('scale') == -1 ? 'dis' : 'en') + 'ableScale']();\n\n                }\n            });\n            var popup = new baidu.editor.ui.Popup({\n                editor:editor,\n                content:'',\n                className:'edui-bubble',\n                _onEditButtonClick:function () {\n                    this.hide();\n                    editor.ui._dialogs.linkDialog.open();\n                },\n                _onImgEditButtonClick:function (name) {\n                    this.hide();\n                    editor.ui._dialogs[name] && editor.ui._dialogs[name].open();\n\n                },\n                _onImgSetFloat:function (value) {\n                    this.hide();\n                    editor.execCommand(\"imagefloat\", value);\n\n                },\n                _setIframeAlign:function (value) {\n                    var frame = popup.anchorEl;\n                    var newFrame = frame.cloneNode(true);\n                    switch (value) {\n                        case -2:\n                            newFrame.setAttribute(\"align\", \"\");\n                            break;\n                        case -1:\n                            newFrame.setAttribute(\"align\", \"left\");\n                            break;\n                        case 1:\n                            newFrame.setAttribute(\"align\", \"right\");\n                            break;\n                    }\n                    frame.parentNode.insertBefore(newFrame, frame);\n                    domUtils.remove(frame);\n                    popup.anchorEl = newFrame;\n                    popup.showAnchor(popup.anchorEl);\n                },\n                _updateIframe:function () {\n                    var frame = editor._iframe = popup.anchorEl;\n                    if(domUtils.hasClass(frame, 'ueditor_baidumap')) {\n                        editor.selection.getRange().selectNode(frame).select();\n                        editor.ui._dialogs.mapDialog.open();\n                        popup.hide();\n                    } else {\n                        editor.ui._dialogs.insertframeDialog.open();\n                        popup.hide();\n                    }\n                },\n                _onRemoveButtonClick:function (cmdName) {\n                    editor.execCommand(cmdName);\n                    this.hide();\n                },\n                queryAutoHide:function (el) {\n                    if (el && el.ownerDocument == editor.document) {\n                        if (el.tagName.toLowerCase() == 'img' || domUtils.findParentByTagName(el, 'a', true)) {\n                            return el !== popup.anchorEl;\n                        }\n                    }\n                    return baidu.editor.ui.Popup.prototype.queryAutoHide.call(this, el);\n                }\n            });\n            popup.render();\n            if (editor.options.imagePopup) {\n                editor.addListener('mouseover', function (t, evt) {\n                    evt = evt || window.event;\n                    var el = evt.target || evt.srcElement;\n                    if (editor.ui._dialogs.insertframeDialog && /iframe/ig.test(el.tagName)) {\n                        var html = popup.formatHtml(\n                            '<nobr>' + editor.getLang(\"property\") + ': <span onclick=$$._setIframeAlign(-2) class=\"edui-clickable\">' + editor.getLang(\"default\") + '</span>&nbsp;&nbsp;<span onclick=$$._setIframeAlign(-1) class=\"edui-clickable\">' + editor.getLang(\"justifyleft\") + '</span>&nbsp;&nbsp;<span onclick=$$._setIframeAlign(1) class=\"edui-clickable\">' + editor.getLang(\"justifyright\") + '</span>&nbsp;&nbsp;' +\n                                ' <span onclick=\"$$._updateIframe( this);\" class=\"edui-clickable\">' + editor.getLang(\"modify\") + '</span></nobr>');\n                        if (html) {\n                            popup.getDom('content').innerHTML = html;\n                            popup.anchorEl = el;\n                            popup.showAnchor(popup.anchorEl);\n                        } else {\n                            popup.hide();\n                        }\n                    }\n                });\n                editor.addListener('selectionchange', function (t, causeByUi) {\n                    if (!causeByUi) return;\n                    var html = '', str = \"\",\n                        img = editor.selection.getRange().getClosedNode(),\n                        dialogs = editor.ui._dialogs;\n                    if (img && img.tagName == 'IMG') {\n                        var dialogName = 'insertimageDialog';\n                        if (img.className.indexOf(\"edui-faked-video\") != -1 || img.className.indexOf(\"edui-upload-video\") != -1) {\n                            dialogName = \"insertvideoDialog\"\n                        }\n                        if (img.className.indexOf(\"edui-faked-webapp\") != -1) {\n                            dialogName = \"webappDialog\"\n                        }\n                        if (img.src.indexOf(\"http://api.map.baidu.com\") != -1) {\n                            dialogName = \"mapDialog\"\n                        }\n                        if (img.className.indexOf(\"edui-faked-music\") != -1) {\n                            dialogName = \"musicDialog\"\n                        }\n                        if (img.src.indexOf(\"http://maps.google.com/maps/api/staticmap\") != -1) {\n                            dialogName = \"gmapDialog\"\n                        }\n                        if (img.getAttribute(\"anchorname\")) {\n                            dialogName = \"anchorDialog\";\n                            html = popup.formatHtml(\n                                '<nobr>' + editor.getLang(\"property\") + ': <span onclick=$$._onImgEditButtonClick(\"anchorDialog\") class=\"edui-clickable\">' + editor.getLang(\"modify\") + '</span>&nbsp;&nbsp;' +\n                                    '<span onclick=$$._onRemoveButtonClick(\\'anchor\\') class=\"edui-clickable\">' + editor.getLang(\"delete\") + '</span></nobr>');\n                        }\n                        if (img.getAttribute(\"word_img\")) {\n                            //todo 放到dialog去做查询\n                            editor.word_img = [img.getAttribute(\"word_img\")];\n                            dialogName = \"wordimageDialog\"\n                        }\n                        if(domUtils.hasClass(img, 'loadingclass') || domUtils.hasClass(img, 'loaderrorclass')) {\n                            dialogName = \"\";\n                        }\n                        if (!dialogs[dialogName]) {\n                            return;\n                        }\n                        str = '<nobr>' + editor.getLang(\"property\") + ': '+\n                            '<span onclick=$$._onImgSetFloat(\"none\") class=\"edui-clickable\">' + editor.getLang(\"default\") + '</span>&nbsp;&nbsp;' +\n                            '<span onclick=$$._onImgSetFloat(\"left\") class=\"edui-clickable\">' + editor.getLang(\"justifyleft\") + '</span>&nbsp;&nbsp;' +\n                            '<span onclick=$$._onImgSetFloat(\"right\") class=\"edui-clickable\">' + editor.getLang(\"justifyright\") + '</span>&nbsp;&nbsp;' +\n                            '<span onclick=$$._onImgSetFloat(\"center\") class=\"edui-clickable\">' + editor.getLang(\"justifycenter\") + '</span>&nbsp;&nbsp;'+\n                            '<span onclick=\"$$._onImgEditButtonClick(\\'' + dialogName + '\\');\" class=\"edui-clickable\">' + editor.getLang(\"modify\") + '</span></nobr>';\n\n                        !html && (html = popup.formatHtml(str))\n\n                    }\n                    if (editor.ui._dialogs.linkDialog) {\n                        var link = editor.queryCommandValue('link');\n                        var url;\n                        if (link && (url = (link.getAttribute('_href') || link.getAttribute('href', 2)))) {\n                            var txt = url;\n                            if (url.length > 30) {\n                                txt = url.substring(0, 20) + \"...\";\n                            }\n                            if (html) {\n                                html += '<div style=\"height:5px;\"></div>'\n                            }\n                            html += popup.formatHtml(\n                                '<nobr>' + editor.getLang(\"anthorMsg\") + ': <a target=\"_blank\" href=\"' + url + '\" title=\"' + url + '\" >' + txt + '</a>' +\n                                    ' <span class=\"edui-clickable\" onclick=\"$$._onEditButtonClick();\">' + editor.getLang(\"modify\") + '</span>' +\n                                    ' <span class=\"edui-clickable\" onclick=\"$$._onRemoveButtonClick(\\'unlink\\');\"> ' + editor.getLang(\"clear\") + '</span></nobr>');\n                            popup.showAnchor(link);\n                        }\n                    }\n\n                    if (html) {\n                        popup.getDom('content').innerHTML = html;\n                        popup.anchorEl = img || link;\n                        popup.showAnchor(popup.anchorEl);\n                    } else {\n                        popup.hide();\n                    }\n                });\n            }\n\n        },\n        _initToolbars:function () {\n            var editor = this.editor;\n            var toolbars = this.toolbars || [];\n            var toolbarUis = [];\n            for (var i = 0; i < toolbars.length; i++) {\n                var toolbar = toolbars[i];\n                var toolbarUi = new baidu.editor.ui.Toolbar({theme:editor.options.theme});\n                for (var j = 0; j < toolbar.length; j++) {\n                    var toolbarItem = toolbar[j];\n                    var toolbarItemUi = null;\n                    if (typeof toolbarItem == 'string') {\n                        toolbarItem = toolbarItem.toLowerCase();\n                        if (toolbarItem == '|') {\n                            toolbarItem = 'Separator';\n                        }\n                        if(toolbarItem == '||'){\n                            toolbarItem = 'Breakline';\n                        }\n                        if (baidu.editor.ui[toolbarItem]) {\n                            toolbarItemUi = new baidu.editor.ui[toolbarItem](editor);\n                        }\n\n                        //fullscreen这里单独处理一下，放到首行去\n                        if (toolbarItem == 'fullscreen') {\n                            if (toolbarUis && toolbarUis[0]) {\n                                toolbarUis[0].items.splice(0, 0, toolbarItemUi);\n                            } else {\n                                toolbarItemUi && toolbarUi.items.splice(0, 0, toolbarItemUi);\n                            }\n\n                            continue;\n\n\n                        }\n                    } else {\n                        toolbarItemUi = toolbarItem;\n                    }\n                    if (toolbarItemUi && toolbarItemUi.id) {\n\n                        toolbarUi.add(toolbarItemUi);\n                    }\n                }\n                toolbarUis[i] = toolbarUi;\n            }\n\n            //接受外部定制的UI\n\n            utils.each(UE._customizeUI,function(obj,key){\n                var itemUI,index;\n                if(obj.id && obj.id != editor.key){\n                   return false;\n                }\n                itemUI = obj.execFn.call(editor,editor,key);\n                if(itemUI){\n                    index = obj.index;\n                    if(index === undefined){\n                        index = toolbarUi.items.length;\n                    }\n                    toolbarUi.add(itemUI,index)\n                }\n            });\n\n            this.toolbars = toolbarUis;\n        },\n        getHtmlTpl:function () {\n            return '<div id=\"##\" class=\"%%\">' +\n                '<div id=\"##_toolbarbox\" class=\"%%-toolbarbox\">' +\n                (this.toolbars.length ?\n                    '<div id=\"##_toolbarboxouter\" class=\"%%-toolbarboxouter\"><div class=\"%%-toolbarboxinner\">' +\n                        this.renderToolbarBoxHtml() +\n                        '</div></div>' : '') +\n                '<div id=\"##_toolbarmsg\" class=\"%%-toolbarmsg\" style=\"display:none;\">' +\n                '<div id = \"##_upload_dialog\" class=\"%%-toolbarmsg-upload\" onclick=\"$$.showWordImageDialog();\">' + this.editor.getLang(\"clickToUpload\") + '</div>' +\n                '<div class=\"%%-toolbarmsg-close\" onclick=\"$$.hideToolbarMsg();\">x</div>' +\n                '<div id=\"##_toolbarmsg_label\" class=\"%%-toolbarmsg-label\"></div>' +\n                '<div style=\"height:0;overflow:hidden;clear:both;\"></div>' +\n                '</div>' +\n                '<div id=\"##_message_holder\" class=\"%%-messageholder\"></div>' +\n                '</div>' +\n                '<div id=\"##_iframeholder\" class=\"%%-iframeholder\">' +\n                '</div>' +\n                //modify wdcount by matao\n                '<div id=\"##_bottombar\" class=\"%%-bottomContainer\"><table><tr>' +\n                '<td id=\"##_elementpath\" class=\"%%-bottombar\"></td>' +\n                '<td id=\"##_wordcount\" class=\"%%-wordcount\"></td>' +\n                '<td id=\"##_scale\" class=\"%%-scale\"><div class=\"%%-icon\"></div></td>' +\n                '</tr></table></div>' +\n                '<div id=\"##_scalelayer\"></div>' +\n                '</div>';\n        },\n        showWordImageDialog:function () {\n            this._dialogs['wordimageDialog'].open();\n        },\n        renderToolbarBoxHtml:function () {\n            var buff = [];\n            for (var i = 0; i < this.toolbars.length; i++) {\n                buff.push(this.toolbars[i].renderHtml());\n            }\n            return buff.join('');\n        },\n        setFullScreen:function (fullscreen) {\n\n            var editor = this.editor,\n                container = editor.container.parentNode.parentNode;\n            if (this._fullscreen != fullscreen) {\n                this._fullscreen = fullscreen;\n                this.editor.fireEvent('beforefullscreenchange', fullscreen);\n                if (baidu.editor.browser.gecko) {\n                    var bk = editor.selection.getRange().createBookmark();\n                }\n                if (fullscreen) {\n                    while (container.tagName != \"BODY\") {\n                        var position = baidu.editor.dom.domUtils.getComputedStyle(container, \"position\");\n                        nodeStack.push(position);\n                        container.style.position = \"static\";\n                        container = container.parentNode;\n                    }\n                    this._bakHtmlOverflow = document.documentElement.style.overflow;\n                    this._bakBodyOverflow = document.body.style.overflow;\n                    this._bakAutoHeight = this.editor.autoHeightEnabled;\n                    this._bakScrollTop = Math.max(document.documentElement.scrollTop, document.body.scrollTop);\n\n                    this._bakEditorContaninerWidth = editor.iframe.parentNode.offsetWidth;\n                    if (this._bakAutoHeight) {\n                        //当全屏时不能执行自动长高\n                        editor.autoHeightEnabled = false;\n                        this.editor.disableAutoHeight();\n                    }\n\n                    document.documentElement.style.overflow = 'hidden';\n                    //修复，滚动条不收起的问题\n\n                    window.scrollTo(0,window.scrollY);\n                    this._bakCssText = this.getDom().style.cssText;\n                    this._bakCssText1 = this.getDom('iframeholder').style.cssText;\n                    editor.iframe.parentNode.style.width = '';\n                    this._updateFullScreen();\n                } else {\n                    while (container.tagName != \"BODY\") {\n                        container.style.position = nodeStack.shift();\n                        container = container.parentNode;\n                    }\n                    this.getDom().style.cssText = this._bakCssText;\n                    this.getDom('iframeholder').style.cssText = this._bakCssText1;\n                    if (this._bakAutoHeight) {\n                        editor.autoHeightEnabled = true;\n                        this.editor.enableAutoHeight();\n                    }\n\n                    document.documentElement.style.overflow = this._bakHtmlOverflow;\n                    document.body.style.overflow = this._bakBodyOverflow;\n                    editor.iframe.parentNode.style.width = this._bakEditorContaninerWidth + 'px';\n                    window.scrollTo(0, this._bakScrollTop);\n                }\n                if (browser.gecko && editor.body.contentEditable === 'true') {\n                    var input = document.createElement('input');\n                    document.body.appendChild(input);\n                    editor.body.contentEditable = false;\n                    setTimeout(function () {\n                        input.focus();\n                        setTimeout(function () {\n                            editor.body.contentEditable = true;\n                            editor.fireEvent('fullscreenchanged', fullscreen);\n                            editor.selection.getRange().moveToBookmark(bk).select(true);\n                            baidu.editor.dom.domUtils.remove(input);\n                            fullscreen && window.scroll(0, 0);\n                        }, 0)\n                    }, 0)\n                }\n\n                if(editor.body.contentEditable === 'true'){\n                    this.editor.fireEvent('fullscreenchanged', fullscreen);\n                    this.triggerLayout();\n                }\n\n            }\n        },\n        _updateFullScreen:function () {\n            if (this._fullscreen) {\n                var vpRect = uiUtils.getViewportRect();\n                this.getDom().style.cssText = 'border:0;position:absolute;left:0;top:' + (this.editor.options.topOffset || 0) + 'px;width:' + vpRect.width + 'px;height:' + vpRect.height + 'px;z-index:' + (this.getDom().style.zIndex * 1 + 100);\n                uiUtils.setViewportOffset(this.getDom(), { left:0, top:this.editor.options.topOffset || 0 });\n                this.editor.setHeight(vpRect.height - this.getDom('toolbarbox').offsetHeight - this.getDom('bottombar').offsetHeight - (this.editor.options.topOffset || 0),true);\n                //不手动调一下，会导致全屏失效\n                if(browser.gecko){\n                    try{\n                        window.onresize();\n                    }catch(e){\n\n                    }\n\n                }\n            }\n        },\n        _updateElementPath:function () {\n            var bottom = this.getDom('elementpath'), list;\n            if (this.elementPathEnabled && (list = this.editor.queryCommandValue('elementpath'))) {\n\n                var buff = [];\n                for (var i = 0, ci; ci = list[i]; i++) {\n                    buff[i] = this.formatHtml('<span unselectable=\"on\" onclick=\"$$.editor.execCommand(&quot;elementpath&quot;, &quot;' + i + '&quot;);\">' + ci + '</span>');\n                }\n                bottom.innerHTML = '<div class=\"edui-editor-breadcrumb\" onmousedown=\"return false;\">' + this.editor.getLang(\"elementPathTip\") + ': ' + buff.join(' &gt; ') + '</div>';\n\n            } else {\n                bottom.style.display = 'none'\n            }\n        },\n        disableElementPath:function () {\n            var bottom = this.getDom('elementpath');\n            bottom.innerHTML = '';\n            bottom.style.display = 'none';\n            this.elementPathEnabled = false;\n\n        },\n        enableElementPath:function () {\n            var bottom = this.getDom('elementpath');\n            bottom.style.display = '';\n            this.elementPathEnabled = true;\n            this._updateElementPath();\n        },\n        _scale:function () {\n            var doc = document,\n                editor = this.editor,\n                editorHolder = editor.container,\n                editorDocument = editor.document,\n                toolbarBox = this.getDom(\"toolbarbox\"),\n                bottombar = this.getDom(\"bottombar\"),\n                scale = this.getDom(\"scale\"),\n                scalelayer = this.getDom(\"scalelayer\");\n\n            var isMouseMove = false,\n                position = null,\n                minEditorHeight = 0,\n                minEditorWidth = editor.options.minFrameWidth,\n                pageX = 0,\n                pageY = 0,\n                scaleWidth = 0,\n                scaleHeight = 0;\n\n            function down() {\n                position = domUtils.getXY(editorHolder);\n\n                if (!minEditorHeight) {\n                    minEditorHeight = editor.options.minFrameHeight + toolbarBox.offsetHeight + bottombar.offsetHeight;\n                }\n\n                scalelayer.style.cssText = \"position:absolute;left:0;display:;top:0;background-color:#41ABFF;opacity:0.4;filter: Alpha(opacity=40);width:\" + editorHolder.offsetWidth + \"px;height:\"\n                    + editorHolder.offsetHeight + \"px;z-index:\" + (editor.options.zIndex + 1);\n\n                domUtils.on(doc, \"mousemove\", move);\n                domUtils.on(editorDocument, \"mouseup\", up);\n                domUtils.on(doc, \"mouseup\", up);\n            }\n\n            var me = this;\n            //by xuheng 全屏时关掉缩放\n            this.editor.addListener('fullscreenchanged', function (e, fullScreen) {\n                if (fullScreen) {\n                    me.disableScale();\n\n                } else {\n                    if (me.editor.options.scaleEnabled) {\n                        me.enableScale();\n                        var tmpNode = me.editor.document.createElement('span');\n                        me.editor.body.appendChild(tmpNode);\n                        me.editor.body.style.height = Math.max(domUtils.getXY(tmpNode).y, me.editor.iframe.offsetHeight - 20) + 'px';\n                        domUtils.remove(tmpNode)\n                    }\n                }\n            });\n            function move(event) {\n                clearSelection();\n                var e = event || window.event;\n                pageX = e.pageX || (doc.documentElement.scrollLeft + e.clientX);\n                pageY = e.pageY || (doc.documentElement.scrollTop + e.clientY);\n                scaleWidth = pageX - position.x;\n                scaleHeight = pageY - position.y;\n\n                if (scaleWidth >= minEditorWidth) {\n                    isMouseMove = true;\n                    scalelayer.style.width = scaleWidth + 'px';\n                }\n                if (scaleHeight >= minEditorHeight) {\n                    isMouseMove = true;\n                    scalelayer.style.height = scaleHeight + \"px\";\n                }\n            }\n\n            function up() {\n                if (isMouseMove) {\n                    isMouseMove = false;\n                    editor.ui._actualFrameWidth = scalelayer.offsetWidth - 2;\n                    editorHolder.style.width = editor.ui._actualFrameWidth + 'px';\n\n                    editor.setHeight(scalelayer.offsetHeight - bottombar.offsetHeight - toolbarBox.offsetHeight - 2,true);\n                }\n                if (scalelayer) {\n                    scalelayer.style.display = \"none\";\n                }\n                clearSelection();\n                domUtils.un(doc, \"mousemove\", move);\n                domUtils.un(editorDocument, \"mouseup\", up);\n                domUtils.un(doc, \"mouseup\", up);\n            }\n\n            function clearSelection() {\n                if (browser.ie)\n                    doc.selection.clear();\n                else\n                    window.getSelection().removeAllRanges();\n            }\n\n            this.enableScale = function () {\n                //trace:2868\n                if (editor.queryCommandState(\"source\") == 1)    return;\n                scale.style.display = \"\";\n                this.scaleEnabled = true;\n                domUtils.on(scale, \"mousedown\", down);\n            };\n            this.disableScale = function () {\n                scale.style.display = \"none\";\n                this.scaleEnabled = false;\n                domUtils.un(scale, \"mousedown\", down);\n            };\n        },\n        isFullScreen:function () {\n            return this._fullscreen;\n        },\n        postRender:function () {\n            UIBase.prototype.postRender.call(this);\n            for (var i = 0; i < this.toolbars.length; i++) {\n                this.toolbars[i].postRender();\n            }\n            var me = this;\n            var timerId,\n                domUtils = baidu.editor.dom.domUtils,\n                updateFullScreenTime = function () {\n                    clearTimeout(timerId);\n                    timerId = setTimeout(function () {\n                        me._updateFullScreen();\n                    });\n                };\n            domUtils.on(window, 'resize', updateFullScreenTime);\n\n            me.addListener('destroy', function () {\n                domUtils.un(window, 'resize', updateFullScreenTime);\n                clearTimeout(timerId);\n            })\n        },\n        showToolbarMsg:function (msg, flag) {\n            this.getDom('toolbarmsg_label').innerHTML = msg;\n            this.getDom('toolbarmsg').style.display = '';\n            //\n            if (!flag) {\n                var w = this.getDom('upload_dialog');\n                w.style.display = 'none';\n            }\n        },\n        hideToolbarMsg:function () {\n            this.getDom('toolbarmsg').style.display = 'none';\n        },\n        mapUrl:function (url) {\n            return url ? url.replace('~/', this.editor.options.UEDITOR_HOME_URL || '') : ''\n        },\n        triggerLayout:function () {\n            var dom = this.getDom();\n            if (dom.style.zoom == '1') {\n                dom.style.zoom = '100%';\n            } else {\n                dom.style.zoom = '1';\n            }\n        }\n    };\n    utils.inherits(EditorUI, baidu.editor.ui.UIBase);\n\n\n    var instances = {};\n\n\n    UE.ui.Editor = function (options) {\n        var editor = new UE.Editor(options);\n        editor.options.editor = editor;\n        utils.loadFile(document, {\n            href:editor.options.themePath + editor.options.theme + \"/css/ueditor.css\",\n            tag:\"link\",\n            type:\"text/css\",\n            rel:\"stylesheet\"\n        });\n\n        var oldRender = editor.render;\n        editor.render = function (holder) {\n            if (holder.constructor === String) {\n                editor.key = holder;\n                instances[holder] = editor;\n            }\n            utils.domReady(function () {\n                editor.langIsReady ? renderUI() : editor.addListener(\"langReady\", renderUI);\n                function renderUI() {\n                    editor.setOpt({\n                        labelMap:editor.options.labelMap || editor.getLang('labelMap')\n                    });\n                    new EditorUI(editor.options);\n                    if (holder) {\n                        if (holder.constructor === String) {\n                            holder = document.getElementById(holder);\n                        }\n                        holder && holder.getAttribute('name') && ( editor.options.textarea = holder.getAttribute('name'));\n                        if (holder && /script|textarea/ig.test(holder.tagName)) {\n                            var newDiv = document.createElement('div');\n                            holder.parentNode.insertBefore(newDiv, holder);\n                            var cont = holder.value || holder.innerHTML;\n                            editor.options.initialContent = /^[\\t\\r\\n ]*$/.test(cont) ? editor.options.initialContent :\n                                cont.replace(/>[\\n\\r\\t]+([ ]{4})+/g, '>')\n                                    .replace(/[\\n\\r\\t]+([ ]{4})+</g, '<')\n                                    .replace(/>[\\n\\r\\t]+</g, '><');\n                            holder.className && (newDiv.className = holder.className);\n                            holder.style.cssText && (newDiv.style.cssText = holder.style.cssText);\n                            if (/textarea/i.test(holder.tagName)) {\n                                editor.textarea = holder;\n                                editor.textarea.style.display = 'none';\n\n\n                            } else {\n                                holder.parentNode.removeChild(holder);\n\n\n                            }\n                            if(holder.id){\n                                newDiv.id = holder.id;\n                                domUtils.removeAttributes(holder,'id');\n                            }\n                            holder = newDiv;\n                            holder.innerHTML = '';\n                        }\n\n                    }\n                    domUtils.addClass(holder, \"edui-\" + editor.options.theme);\n                    editor.ui.render(holder);\n                    var opt = editor.options;\n                    //给实例添加一个编辑器的容器引用\n                    editor.container = editor.ui.getDom();\n                    var parents = domUtils.findParents(holder,true);\n                    var displays = [];\n                    for(var i = 0 ,ci;ci=parents[i];i++){\n                        displays[i] = ci.style.display;\n                        ci.style.display = 'block'\n                    }\n                    if (opt.initialFrameWidth) {\n                        opt.minFrameWidth = opt.initialFrameWidth;\n                    } else {\n                        opt.minFrameWidth = opt.initialFrameWidth = holder.offsetWidth;\n                        var styleWidth = holder.style.width;\n                        if(/%$/.test(styleWidth)) {\n                            opt.initialFrameWidth = styleWidth;\n                        }\n                    }\n                    if (opt.initialFrameHeight) {\n                        opt.minFrameHeight = opt.initialFrameHeight;\n                    } else {\n                        opt.initialFrameHeight = opt.minFrameHeight = holder.offsetHeight;\n                    }\n                    for(var i = 0 ,ci;ci=parents[i];i++){\n                        ci.style.display =  displays[i]\n                    }\n                    //编辑器最外容器设置了高度，会导致，编辑器不占位\n                    //todo 先去掉，没有找到原因\n                    if(holder.style.height){\n                        holder.style.height = ''\n                    }\n                    editor.container.style.width = opt.initialFrameWidth + (/%$/.test(opt.initialFrameWidth) ? '' : 'px');\n                    editor.container.style.zIndex = opt.zIndex;\n                    oldRender.call(editor, editor.ui.getDom('iframeholder'));\n                    editor.fireEvent(\"afteruiready\");\n                }\n            })\n        };\n        return editor;\n    };\n\n\n    /**\n     * @file\n     * @name UE\n     * @short UE\n     * @desc UEditor的顶部命名空间\n     */\n    /**\n     * @name getEditor\n     * @since 1.2.4+\n     * @grammar UE.getEditor(id,[opt])  =>  Editor实例\n     * @desc 提供一个全局的方法得到编辑器实例\n     *\n     * * ''id''  放置编辑器的容器id, 如果容器下的编辑器已经存在，就直接返回\n     * * ''opt'' 编辑器的可选参数\n     * @example\n     *  UE.getEditor('containerId',{onready:function(){//创建一个编辑器实例\n     *      this.setContent('hello')\n     *  }});\n     *  UE.getEditor('containerId'); //返回刚创建的实例\n     *\n     */\n    UE.getEditor = function (id, opt) {\n        var editor = instances[id];\n        if (!editor) {\n            editor = instances[id] = new UE.ui.Editor(opt);\n            editor.render(id);\n        }\n        return editor;\n    };\n\n\n    UE.delEditor = function (id) {\n        var editor;\n        if (editor = instances[id]) {\n            editor.key && editor.destroy();\n            delete instances[id]\n        }\n    };\n\n    UE.registerUI = function(uiName,fn,index,editorId){\n        utils.each(uiName.split(/\\s+/), function (name) {\n            UE._customizeUI[name] = {\n                id : editorId,\n                execFn:fn,\n                index:index\n            };\n        })\n\n    }\n\n})();\n\n// adapter/message.js\nUE.registerUI('message', function(editor) {\n\n    var editorui = baidu.editor.ui;\n    var Message = editorui.Message;\n    var holder;\n    var _messageItems = [];\n    var me = editor;\n\n    me.addListener('ready', function(){\n        holder = document.getElementById(me.ui.id + '_message_holder');\n        updateHolderPos();\n        setTimeout(function(){\n            updateHolderPos();\n        }, 500);\n    });\n\n    me.addListener('showmessage', function(type, opt){\n        opt = utils.isString(opt) ? {\n            'content': opt\n        } : opt;\n        var message = new Message({\n                'timeout': opt.timeout,\n                'type': opt.type,\n                'content': opt.content,\n                'keepshow': opt.keepshow,\n                'editor': me\n            }),\n            mid = opt.id || ('msg_' + (+new Date()).toString(36));\n        message.render(holder);\n        _messageItems[mid] = message;\n        message.reset(opt);\n        updateHolderPos();\n        return mid;\n    });\n\n    me.addListener('updatemessage',function(type, id, opt){\n        opt = utils.isString(opt) ? {\n            'content': opt\n        } : opt;\n        var message = _messageItems[id];\n        message.render(holder);\n        message && message.reset(opt);\n    });\n\n    me.addListener('hidemessage',function(type, id){\n        var message = _messageItems[id];\n        message && message.hide();\n    });\n\n    function updateHolderPos(){\n        var toolbarbox = me.ui.getDom('toolbarbox');\n        if (toolbarbox) {\n            holder.style.top = toolbarbox.offsetHeight + 3 + 'px';\n        }\n        holder.style.zIndex = Math.max(me.options.zIndex, me.iframe.style.zIndex) + 1;\n    }\n\n});\n\n\n// adapter/autosave.js\nUE.registerUI('autosave', function(editor) {\n    var timer = null,uid = null;\n    editor.on('afterautosave',function(){\n        clearTimeout(timer);\n\n        timer = setTimeout(function(){\n            if(uid){\n                editor.trigger('hidemessage',uid);\n            }\n            uid = editor.trigger('showmessage',{\n                content : editor.getLang('autosave.success'),\n                timeout : 2000\n            });\n\n        },2000)\n    })\n\n});\n\n\n\n})();\n"
  },
  {
    "path": "public/static/ueditor/ueditor.config.js",
    "content": "/**\n * ueditor完整配置项\n * 可以在这里配置整个编辑器的特性\n */\n/**************************提示********************************\n * 所有被注释的配置项均为UEditor默认值。\n * 修改默认配置请首先确保已经完全明确该参数的真实用途。\n * 主要有两种修改方案，一种是取消此处注释，然后修改成对应参数；另一种是在实例化编辑器时传入对应参数。\n * 当升级编辑器时，可直接使用旧版配置文件替换新版配置文件,不用担心旧版配置文件中因缺少新功能所需的参数而导致脚本报错。\n **************************提示********************************/\n\n(function () {\n\n    /**\n     * 编辑器资源文件根路径。它所表示的含义是：以编辑器实例化页面为当前路径，指向编辑器资源文件（即dialog等文件夹）的路径。\n     * 鉴于很多同学在使用编辑器的时候出现的种种路径问题，此处强烈建议大家使用\"相对于网站根目录的相对路径\"进行配置。\n     * \"相对于网站根目录的相对路径\"也就是以斜杠开头的形如\"/myProject/ueditor/\"这样的路径。\n     * 如果站点中有多个不在同一层级的页面需要实例化编辑器，且引用了同一UEditor的时候，此处的URL可能不适用于每个页面的编辑器。\n     * 因此，UEditor提供了针对不同页面的编辑器可单独配置的根路径，具体来说，在需要实例化编辑器的页面最顶部写上如下代码即可。当然，需要令此处的URL等于对应的配置。\n     * window.UEDITOR_HOME_URL = \"/xxxx/xxxx/\";\n     */\n    var URL = window.UEDITOR_HOME_URL || getUEBasePath();\n\n    /**\n     * 配置项主体。注意，此处所有涉及到路径的配置别遗漏URL变量。\n     */\n    window.UEDITOR_CONFIG = {\n\n        //为编辑器实例添加一个路径，这个不能被注释\n        UEDITOR_HOME_URL: URL\n\n        // 服务器统一请求接口路径\n        , serverUrl: URL + \"php/controller.php\"\n\n        //工具栏上的所有的功能按钮和下拉框，可以在new编辑器的实例时选择自己需要的重新定义\n        , toolbars: [[\n            'fullscreen', 'source', '|', 'undo', 'redo', '|',\n            'bold', 'italic', 'underline', 'fontborder', 'strikethrough', 'superscript', 'subscript', 'removeformat', 'formatmatch', 'autotypeset', 'blockquote', 'pasteplain', '|', 'forecolor', 'backcolor', 'insertorderedlist', 'insertunorderedlist', 'selectall', 'cleardoc', '|',\n            'rowspacingtop', 'rowspacingbottom', 'lineheight', '|',\n            'customstyle', 'paragraph', 'fontfamily', 'fontsize', '|',\n            'directionalityltr', 'directionalityrtl', 'indent', '|',\n            'justifyleft', 'justifycenter', 'justifyright', 'justifyjustify', '|', 'touppercase', 'tolowercase', '|',\n            'link', 'unlink', 'anchor', '|', 'imagenone', 'imageleft', 'imageright', 'imagecenter', '|',\n            'simpleupload', 'insertimage', 'emotion', 'scrawl', 'insertvideo', 'music', 'attachment', 'map', 'gmap', 'insertframe', 'insertcode', 'webapp', 'pagebreak', 'template', 'background', '|',\n            'horizontal', 'date', 'time', 'spechars', 'snapscreen', 'wordimage', '|',\n            'inserttable', 'deletetable', 'insertparagraphbeforetable', 'insertrow', 'deleterow', 'insertcol', 'deletecol', 'mergecells', 'mergeright', 'mergedown', 'splittocells', 'splittorows', 'splittocols', 'charts', '|',\n            'print', 'preview', 'searchreplace', 'drafts', 'help'\n        ]]\n        //当鼠标放在工具栏上时显示的tooltip提示,留空支持自动多语言配置，否则以配置值为准\n        //,labelMap:{\n        //    'anchor':'', 'undo':''\n        //}\n\n        //语言配置项,默认是zh-cn。有需要的话也可以使用如下这样的方式来自动多语言切换，当然，前提条件是lang文件夹下存在对应的语言文件：\n        //lang值也可以通过自动获取 (navigator.language||navigator.browserLanguage ||navigator.userLanguage).toLowerCase()\n        //,lang:\"zh-cn\"\n        //,langPath:URL +\"lang/\"\n\n        //主题配置项,默认是default。有需要的话也可以使用如下这样的方式来自动多主题切换，当然，前提条件是themes文件夹下存在对应的主题文件：\n        //现有如下皮肤:default\n        //,theme:'default'\n        //,themePath:URL +\"themes/\"\n\n        //,zIndex : 900     //编辑器层级的基数,默认是900\n\n        //针对getAllHtml方法，会在对应的head标签中增加该编码设置。\n        //,charset:\"utf-8\"\n\n        //若实例化编辑器的页面手动修改的domain，此处需要设置为true\n        //,customDomain:false\n\n        //常用配置项目\n        //,isShow : true    //默认显示编辑器\n\n        //,textarea:'editorValue' // 提交表单时，服务器获取编辑器提交内容的所用的参数，多实例时可以给容器name属性，会将name给定的值最为每个实例的键值，不用每次实例化的时候都设置这个值\n\n        //,initialContent:'欢迎使用ueditor!'    //初始化编辑器的内容,也可以通过textarea/script给值，看官网例子\n\n        //,autoClearinitialContent:true //是否自动清除编辑器初始内容，注意：如果focus属性设置为true,这个也为真，那么编辑器一上来就会触发导致初始化的内容看不到了\n\n        //,focus:false //初始化时，是否让编辑器获得焦点true或false\n\n        //如果自定义，最好给p标签如下的行高，要不输入中文时，会有跳动感\n        //,initialStyle:'p{line-height:1em}'//编辑器层级的基数,可以用来改变字体等\n\n        //,iframeCssUrl: URL + '/themes/iframe.css' //给编辑区域的iframe引入一个css文件\n\n        //indentValue\n        //首行缩进距离,默认是2em\n        //,indentValue:'2em'\n\n        //,initialFrameWidth:1000  //初始化编辑器宽度,默认1000\n        //,initialFrameHeight:320  //初始化编辑器高度,默认320\n\n        //,readonly : false //编辑器初始化结束后,编辑区域是否是只读的，默认是false\n\n        //,autoClearEmptyNode : true //getContent时，是否删除空的inlineElement节点（包括嵌套的情况）\n\n        //启用自动保存\n        //,enableAutoSave: true\n        //自动保存间隔时间， 单位ms\n        //,saveInterval: 500\n\n        //,fullscreen : false //是否开启初始化时即全屏，默认关闭\n\n        //,imagePopup:true      //图片操作的浮层开关，默认打开\n\n        //,autoSyncData:true //自动同步编辑器要提交的数据\n        //,emotionLocalization:false //是否开启表情本地化，默认关闭。若要开启请确保emotion文件夹下包含官网提供的images表情文件夹\n\n        //粘贴只保留标签，去除标签所有属性\n        //,retainOnlyLabelPasted: false\n\n        //,pasteplain:false  //是否默认为纯文本粘贴。false为不使用纯文本粘贴，true为使用纯文本粘贴\n        //纯文本粘贴模式下的过滤规则\n        //'filterTxtRules' : function(){\n        //    function transP(node){\n        //        node.tagName = 'p';\n        //        node.setStyle();\n        //    }\n        //    return {\n        //        //直接删除及其字节点内容\n        //        '-' : 'script style object iframe embed input select',\n        //        'p': {$:{}},\n        //        'br':{$:{}},\n        //        'div':{'$':{}},\n        //        'li':{'$':{}},\n        //        'caption':transP,\n        //        'th':transP,\n        //        'tr':transP,\n        //        'h1':transP,'h2':transP,'h3':transP,'h4':transP,'h5':transP,'h6':transP,\n        //        'td':function(node){\n        //            //没有内容的td直接删掉\n        //            var txt = !!node.innerText();\n        //            if(txt){\n        //                node.parentNode.insertAfter(UE.uNode.createText(' &nbsp; &nbsp;'),node);\n        //            }\n        //            node.parentNode.removeChild(node,node.innerText())\n        //        }\n        //    }\n        //}()\n\n        //,allHtmlEnabled:false //提交到后台的数据是否包含整个html字符串\n\n        //insertorderedlist\n        //有序列表的下拉配置,值留空时支持多语言自动识别，若配置值，则以此值为准\n        //,'insertorderedlist':{\n        //      //自定的样式\n        //        'num':'1,2,3...',\n        //        'num1':'1),2),3)...',\n        //        'num2':'(1),(2),(3)...',\n        //        'cn':'一,二,三....',\n        //        'cn1':'一),二),三)....',\n        //        'cn2':'(一),(二),(三)....',\n        //     //系统自带\n        //     'decimal' : '' ,         //'1,2,3...'\n        //     'lower-alpha' : '' ,    // 'a,b,c...'\n        //     'lower-roman' : '' ,    //'i,ii,iii...'\n        //     'upper-alpha' : '' , lang   //'A,B,C'\n        //     'upper-roman' : ''      //'I,II,III...'\n        //}\n\n        //insertunorderedlist\n        //无序列表的下拉配置，值留空时支持多语言自动识别，若配置值，则以此值为准\n        //,insertunorderedlist : { //自定的样式\n        //    'dash' :'— 破折号', //-破折号\n        //    'dot':' 。 小圆圈', //系统自带\n        //    'circle' : '',  // '○ 小圆圈'\n        //    'disc' : '',    // '● 小圆点'\n        //    'square' : ''   //'■ 小方块'\n        //}\n        //,listDefaultPaddingLeft : '30'//默认的左边缩进的基数倍\n        //,listiconpath : 'http://bs.baidu.com/listicon/'//自定义标号的路径\n        //,maxListLevel : 3 //限制可以tab的级数, 设置-1为不限制\n\n        //,autoTransWordToList:false  //禁止word中粘贴进来的列表自动变成列表标签\n\n        //fontfamily\n        //字体设置 label留空支持多语言自动切换，若配置，则以配置值为准\n        //,'fontfamily':[\n        //    { label:'',name:'songti',val:'宋体,SimSun'},\n        //    { label:'',name:'kaiti',val:'楷体,楷体_GB2312, SimKai'},\n        //    { label:'',name:'yahei',val:'微软雅黑,Microsoft YaHei'},\n        //    { label:'',name:'heiti',val:'黑体, SimHei'},\n        //    { label:'',name:'lishu',val:'隶书, SimLi'},\n        //    { label:'',name:'andaleMono',val:'andale mono'},\n        //    { label:'',name:'arial',val:'arial, helvetica,sans-serif'},\n        //    { label:'',name:'arialBlack',val:'arial black,avant garde'},\n        //    { label:'',name:'comicSansMs',val:'comic sans ms'},\n        //    { label:'',name:'impact',val:'impact,chicago'},\n        //    { label:'',name:'timesNewRoman',val:'times new roman'}\n        //]\n\n        //fontsize\n        //字号\n        //,'fontsize':[10, 11, 12, 14, 16, 18, 20, 24, 36]\n\n        //paragraph\n        //段落格式 值留空时支持多语言自动识别，若配置，则以配置值为准\n        //,'paragraph':{'p':'', 'h1':'', 'h2':'', 'h3':'', 'h4':'', 'h5':'', 'h6':''}\n\n        //rowspacingtop\n        //段间距 值和显示的名字相同\n        //,'rowspacingtop':['5', '10', '15', '20', '25']\n\n        //rowspacingBottom\n        //段间距 值和显示的名字相同\n        //,'rowspacingbottom':['5', '10', '15', '20', '25']\n\n        //lineheight\n        //行内间距 值和显示的名字相同\n        //,'lineheight':['1', '1.5','1.75','2', '3', '4', '5']\n\n        //customstyle\n        //自定义样式，不支持国际化，此处配置值即可最后显示值\n        //block的元素是依据设置段落的逻辑设置的，inline的元素依据BIU的逻辑设置\n        //尽量使用一些常用的标签\n        //参数说明\n        //tag 使用的标签名字\n        //label 显示的名字也是用来标识不同类型的标识符，注意这个值每个要不同，\n        //style 添加的样式\n        //每一个对象就是一个自定义的样式\n        //,'customstyle':[\n        //    {tag:'h1', name:'tc', label:'', style:'border-bottom:#ccc 2px solid;padding:0 4px 0 0;text-align:center;margin:0 0 20px 0;'},\n        //    {tag:'h1', name:'tl',label:'', style:'border-bottom:#ccc 2px solid;padding:0 4px 0 0;margin:0 0 10px 0;'},\n        //    {tag:'span',name:'im', label:'', style:'font-style:italic;font-weight:bold'},\n        //    {tag:'span',name:'hi', label:'', style:'font-style:italic;font-weight:bold;color:rgb(51, 153, 204)'}\n        //]\n\n        //打开右键菜单功能\n        //,enableContextMenu: true\n        //右键菜单的内容，可以参考plugins/contextmenu.js里边的默认菜单的例子，label留空支持国际化，否则以此配置为准\n        //,contextMenu:[\n        //    {\n        //        label:'',       //显示的名称\n        //        cmdName:'selectall',//执行的command命令，当点击这个右键菜单时\n        //        //exec可选，有了exec就会在点击时执行这个function，优先级高于cmdName\n        //        exec:function () {\n        //            //this是当前编辑器的实例\n        //            //this.ui._dialogs['inserttableDialog'].open();\n        //        }\n        //    }\n        //]\n\n        //快捷菜单\n        //,shortcutMenu:[\"fontfamily\", \"fontsize\", \"bold\", \"italic\", \"underline\", \"forecolor\", \"backcolor\", \"insertorderedlist\", \"insertunorderedlist\"]\n\n        //elementPathEnabled\n        //是否启用元素路径，默认是显示\n        //,elementPathEnabled : true\n\n        //wordCount\n        //,wordCount:true          //是否开启字数统计\n        //,maximumWords:10000       //允许的最大字符数\n        //字数统计提示，{#count}代表当前字数，{#leave}代表还可以输入多少字符数,留空支持多语言自动切换，否则按此配置显示\n        //,wordCountMsg:''   //当前已输入 {#count} 个字符，您还可以输入{#leave} 个字符\n        //超出字数限制提示  留空支持多语言自动切换，否则按此配置显示\n        //,wordOverFlowMsg:''    //<span style=\"color:red;\">你输入的字符个数已经超出最大允许值，服务器可能会拒绝保存！</span>\n\n        //tab\n        //点击tab键时移动的距离,tabSize倍数，tabNode什么字符做为单位\n        //,tabSize:4\n        //,tabNode:'&nbsp;'\n\n        //removeFormat\n        //清除格式时可以删除的标签和属性\n        //removeForamtTags标签\n        //,removeFormatTags:'b,big,code,del,dfn,em,font,i,ins,kbd,q,samp,small,span,strike,strong,sub,sup,tt,u,var'\n        //removeFormatAttributes属性\n        //,removeFormatAttributes:'class,style,lang,width,height,align,hspace,valign'\n\n        //undo\n        //可以最多回退的次数,默认20\n        //,maxUndoCount:20\n        //当输入的字符数超过该值时，保存一次现场\n        //,maxInputCount:1\n\n        //autoHeightEnabled\n        // 是否自动长高,默认true\n        //,autoHeightEnabled:true\n\n        //scaleEnabled\n        //是否可以拉伸长高,默认true(当开启时，自动长高失效)\n        //,scaleEnabled:false\n        //,minFrameWidth:800    //编辑器拖动时最小宽度,默认800\n        //,minFrameHeight:220  //编辑器拖动时最小高度,默认220\n\n        //autoFloatEnabled\n        //是否保持toolbar的位置不动,默认true\n        //,autoFloatEnabled:true\n        //浮动时工具栏距离浏览器顶部的高度，用于某些具有固定头部的页面\n        //,topOffset:30\n        //编辑器底部距离工具栏高度(如果参数大于等于编辑器高度，则设置无效)\n        //,toolbarTopOffset:400\n\n        //设置远程图片是否抓取到本地保存\n        //,catchRemoteImageEnable: true //设置是否抓取远程图片\n\n        //pageBreakTag\n        //分页标识符,默认是_ueditor_page_break_tag_\n        //,pageBreakTag:'_ueditor_page_break_tag_'\n\n        //autotypeset\n        //自动排版参数\n        //,autotypeset: {\n        //    mergeEmptyline: true,           //合并空行\n        //    removeClass: true,              //去掉冗余的class\n        //    removeEmptyline: false,         //去掉空行\n        //    textAlign:\"left\",               //段落的排版方式，可以是 left,right,center,justify 去掉这个属性表示不执行排版\n        //    imageBlockLine: 'center',       //图片的浮动方式，独占一行剧中,左右浮动，默认: center,left,right,none 去掉这个属性表示不执行排版\n        //    pasteFilter: false,             //根据规则过滤没事粘贴进来的内容\n        //    clearFontSize: false,           //去掉所有的内嵌字号，使用编辑器默认的字号\n        //    clearFontFamily: false,         //去掉所有的内嵌字体，使用编辑器默认的字体\n        //    removeEmptyNode: false,         // 去掉空节点\n        //    //可以去掉的标签\n        //    removeTagNames: {标签名字:1},\n        //    indent: false,                  // 行首缩进\n        //    indentValue : '2em',            //行首缩进的大小\n        //    bdc2sb: false,\n        //    tobdc: false\n        //}\n\n        //tableDragable\n        //表格是否可以拖拽\n        //,tableDragable: true\n\n\n\n        //sourceEditor\n        //源码的查看方式,codemirror 是代码高亮，textarea是文本框,默认是codemirror\n        //注意默认codemirror只能在ie8+和非ie中使用\n        //,sourceEditor:\"codemirror\"\n        //如果sourceEditor是codemirror，还用配置一下两个参数\n        //codeMirrorJsUrl js加载的路径，默认是 URL + \"third-party/codemirror/codemirror.js\"\n        //,codeMirrorJsUrl:URL + \"third-party/codemirror/codemirror.js\"\n        //codeMirrorCssUrl css加载的路径，默认是 URL + \"third-party/codemirror/codemirror.css\"\n        //,codeMirrorCssUrl:URL + \"third-party/codemirror/codemirror.css\"\n        //编辑器初始化完成后是否进入源码模式，默认为否。\n        //,sourceEditorFirst:false\n\n        //iframeUrlMap\n        //dialog内容的路径 ～会被替换成URL,垓属性一旦打开，将覆盖所有的dialog的默认路径\n        //,iframeUrlMap:{\n        //    'anchor':'~/dialogs/anchor/anchor.html',\n        //}\n\n        //allowLinkProtocol 允许的链接地址，有这些前缀的链接地址不会自动添加http\n        //, allowLinkProtocols: ['http:', 'https:', '#', '/', 'ftp:', 'mailto:', 'tel:', 'git:', 'svn:']\n\n        //webAppKey 百度应用的APIkey，每个站长必须首先去百度官网注册一个key后方能正常使用app功能，注册介绍，http://app.baidu.com/static/cms/getapikey.html\n        //, webAppKey: \"\"\n\n        //默认过滤规则相关配置项目\n        //,disabledTableInTable:true  //禁止表格嵌套\n        //,allowDivTransToP:true      //允许进入编辑器的div标签自动变成p标签\n        //,rgb2Hex:true               //默认产出的数据中的color自动从rgb格式变成16进制格式\n\n\t\t// xss 过滤是否开启,inserthtml等操作\n\t\t,xssFilterRules: true\n\t\t//input xss过滤\n\t\t,inputXssFilter: true\n\t\t//output xss过滤\n\t\t,outputXssFilter: true\n\t\t// xss过滤白名单 名单来源: https://raw.githubusercontent.com/leizongmin/js-xss/master/lib/default.js\n\t\t,whitList: {\n\t\t\ta:      ['target', 'href', 'title', 'class', 'style'],\n\t\t\tabbr:   ['title', 'class', 'style'],\n\t\t\taddress: ['class', 'style'],\n\t\t\tarea:   ['shape', 'coords', 'href', 'alt'],\n\t\t\tarticle: [],\n\t\t\taside:  [],\n\t\t\taudio:  ['autoplay', 'controls', 'loop', 'preload', 'src', 'class', 'style'],\n\t\t\tb:      ['class', 'style'],\n\t\t\tbdi:    ['dir'],\n\t\t\tbdo:    ['dir'],\n\t\t\tbig:    [],\n\t\t\tblockquote: ['cite', 'class', 'style'],\n\t\t\tbr:     [],\n\t\t\tcaption: ['class', 'style'],\n\t\t\tcenter: [],\n\t\t\tcite:   [],\n\t\t\tcode:   ['class', 'style'],\n\t\t\tcol:    ['align', 'valign', 'span', 'width', 'class', 'style'],\n\t\t\tcolgroup: ['align', 'valign', 'span', 'width', 'class', 'style'],\n\t\t\tdd:     ['class', 'style'],\n\t\t\tdel:    ['datetime'],\n\t\t\tdetails: ['open'],\n\t\t\tdiv:    ['class', 'style'],\n\t\t\tdl:     ['class', 'style'],\n\t\t\tdt:     ['class', 'style'],\n\t\t\tem:     ['class', 'style'],\n\t\t\tfont:   ['color', 'size', 'face'],\n\t\t\tfooter: [],\n\t\t\th1:     ['class', 'style'],\n\t\t\th2:     ['class', 'style'],\n\t\t\th3:     ['class', 'style'],\n\t\t\th4:     ['class', 'style'],\n\t\t\th5:     ['class', 'style'],\n\t\t\th6:     ['class', 'style'],\n\t\t\theader: [],\n\t\t\thr:     [],\n\t\t\ti:      ['class', 'style'],\n\t\t\timg:    ['src', 'alt', 'title', 'width', 'height', 'id', '_src', 'loadingclass', 'class', 'data-latex'],\n\t\t\tins:    ['datetime'],\n\t\t\tli:     ['class', 'style'],\n\t\t\tmark:   [],\n\t\t\tnav:    [],\n\t\t\tol:     ['class', 'style'],\n\t\t\tp:      ['class', 'style'],\n\t\t\tpre:    ['class', 'style'],\n\t\t\ts:      [],\n\t\t\tsection:[],\n\t\t\tsmall:  [],\n\t\t\tspan:   ['class', 'style'],\n\t\t\tsub:    ['class', 'style'],\n\t\t\tsup:    ['class', 'style'],\n\t\t\tstrong: ['class', 'style'],\n\t\t\ttable:  ['width', 'border', 'align', 'valign', 'class', 'style'],\n\t\t\ttbody:  ['align', 'valign', 'class', 'style'],\n\t\t\ttd:     ['width', 'rowspan', 'colspan', 'align', 'valign', 'class', 'style'],\n\t\t\ttfoot:  ['align', 'valign', 'class', 'style'],\n\t\t\tth:     ['width', 'rowspan', 'colspan', 'align', 'valign', 'class', 'style'],\n\t\t\tthead:  ['align', 'valign', 'class', 'style'],\n\t\t\ttr:     ['rowspan', 'align', 'valign', 'class', 'style'],\n\t\t\ttt:     [],\n\t\t\tu:      [],\n\t\t\tul:     ['class', 'style'],\n\t\t\tvideo:  ['autoplay', 'controls', 'loop', 'preload', 'src', 'height', 'width', 'class', 'style']\n\t\t}\n    };\n\n    function getUEBasePath(docUrl, confUrl) {\n\n        return getBasePath(docUrl || self.document.URL || self.location.href, confUrl || getConfigFilePath());\n\n    }\n\n    function getConfigFilePath() {\n\n        var configPath = document.getElementsByTagName('script');\n\n        return configPath[ configPath.length - 1 ].src;\n\n    }\n\n    function getBasePath(docUrl, confUrl) {\n\n        var basePath = confUrl;\n\n\n        if (/^(\\/|\\\\\\\\)/.test(confUrl)) {\n\n            basePath = /^.+?\\w(\\/|\\\\\\\\)/.exec(docUrl)[0] + confUrl.replace(/^(\\/|\\\\\\\\)/, '');\n\n        } else if (!/^[a-z]+:/i.test(confUrl)) {\n\n            docUrl = docUrl.split(\"#\")[0].split(\"?\")[0].replace(/[^\\\\\\/]+$/, '');\n\n            basePath = docUrl + \"\" + confUrl;\n\n        }\n\n        return optimizationPath(basePath);\n\n    }\n\n    function optimizationPath(path) {\n\n        var protocol = /^[a-z]+:\\/\\//.exec(path)[ 0 ],\n            tmp = null,\n            res = [];\n\n        path = path.replace(protocol, \"\").split(\"?\")[0].split(\"#\")[0];\n\n        path = path.replace(/\\\\/g, '/').split(/\\//);\n\n        path[ path.length - 1 ] = \"\";\n\n        while (path.length) {\n\n            if (( tmp = path.shift() ) === \"..\") {\n                res.pop();\n            } else if (tmp !== \".\") {\n                res.push(tmp);\n            }\n\n        }\n\n        return protocol + res.join(\"/\");\n\n    }\n\n    window.UE = {\n        getUEBasePath: getUEBasePath\n    };\n\n})();\n"
  },
  {
    "path": "public/static/ueditor/ueditor.parse.js",
    "content": "/*!\n * UEditor\n * version: ueditor\n * build: Wed Aug 10 2016 11:06:03 GMT+0800 (CST)\n */\n\n(function(){\n\n(function(){\n    UE = window.UE || {};\n    var isIE = !!window.ActiveXObject;\n    //定义utils工具\n    var utils = {\n            removeLastbs : function(url){\n                return url.replace(/\\/$/,'')\n            },\n            extend : function(t,s){\n                var a = arguments,\n                    notCover = this.isBoolean(a[a.length - 1]) ? a[a.length - 1] : false,\n                    len = this.isBoolean(a[a.length - 1]) ? a.length - 1 : a.length;\n                for (var i = 1; i < len; i++) {\n                    var x = a[i];\n                    for (var k in x) {\n                        if (!notCover || !t.hasOwnProperty(k)) {\n                            t[k] = x[k];\n                        }\n                    }\n                }\n                return t;\n            },\n            isIE : isIE,\n            cssRule : isIE ? function(key,style,doc){\n                var indexList,index;\n                doc = doc || document;\n                if(doc.indexList){\n                    indexList = doc.indexList;\n                }else{\n                    indexList = doc.indexList =  {};\n                }\n                var sheetStyle;\n                if(!indexList[key]){\n                    if(style === undefined){\n                        return ''\n                    }\n                    sheetStyle = doc.createStyleSheet('',index = doc.styleSheets.length);\n                    indexList[key] = index;\n                }else{\n                    sheetStyle = doc.styleSheets[indexList[key]];\n                }\n                if(style === undefined){\n                    return sheetStyle.cssText\n                }\n                sheetStyle.cssText = sheetStyle.cssText + '\\n' + (style || '')\n            } : function(key,style,doc){\n                doc = doc || document;\n                var head = doc.getElementsByTagName('head')[0],node;\n                if(!(node = doc.getElementById(key))){\n                    if(style === undefined){\n                        return ''\n                    }\n                    node = doc.createElement('style');\n                    node.id = key;\n                    head.appendChild(node)\n                }\n                if(style === undefined){\n                    return node.innerHTML\n                }\n                if(style !== ''){\n                    node.innerHTML = node.innerHTML + '\\n' + style;\n                }else{\n                    head.removeChild(node)\n                }\n            },\n            domReady : function (onready) {\n                var doc = window.document;\n                if (doc.readyState === \"complete\") {\n                    onready();\n                }else{\n                    if (isIE) {\n                        (function () {\n                            if (doc.isReady) return;\n                            try {\n                                doc.documentElement.doScroll(\"left\");\n                            } catch (error) {\n                                setTimeout(arguments.callee, 0);\n                                return;\n                            }\n                            onready();\n                        })();\n                        window.attachEvent('onload', function(){\n                            onready()\n                        });\n                    } else {\n                        doc.addEventListener(\"DOMContentLoaded\", function () {\n                            doc.removeEventListener(\"DOMContentLoaded\", arguments.callee, false);\n                            onready();\n                        }, false);\n                        window.addEventListener('load', function(){onready()}, false);\n                    }\n                }\n\n            },\n            each : function(obj, iterator, context) {\n                if (obj == null) return;\n                if (obj.length === +obj.length) {\n                    for (var i = 0, l = obj.length; i < l; i++) {\n                        if(iterator.call(context, obj[i], i, obj) === false)\n                            return false;\n                    }\n                } else {\n                    for (var key in obj) {\n                        if (obj.hasOwnProperty(key)) {\n                            if(iterator.call(context, obj[key], key, obj) === false)\n                                return false;\n                        }\n                    }\n                }\n            },\n            inArray : function(arr,item){\n                var index = -1;\n                this.each(arr,function(v,i){\n                    if(v === item){\n                        index = i;\n                        return false;\n                    }\n                });\n                return index;\n            },\n            pushItem : function(arr,item){\n                if(this.inArray(arr,item)==-1){\n                    arr.push(item)\n                }\n            },\n            trim: function (str) {\n                return str.replace(/(^[ \\t\\n\\r]+)|([ \\t\\n\\r]+$)/g, '');\n            },\n            indexOf: function (array, item, start) {\n                var index = -1;\n                start = this.isNumber(start) ? start : 0;\n                this.each(array, function (v, i) {\n                    if (i >= start && v === item) {\n                        index = i;\n                        return false;\n                    }\n                });\n                return index;\n            },\n            hasClass: function (element, className) {\n                className = className.replace(/(^[ ]+)|([ ]+$)/g, '').replace(/[ ]{2,}/g, ' ').split(' ');\n                for (var i = 0, ci, cls = element.className; ci = className[i++];) {\n                    if (!new RegExp('\\\\b' + ci + '\\\\b', 'i').test(cls)) {\n                        return false;\n                    }\n                }\n                return i - 1 == className.length;\n            },\n            addClass:function (elm, classNames) {\n                if(!elm)return;\n                classNames = this.trim(classNames).replace(/[ ]{2,}/g,' ').split(' ');\n                for(var i = 0,ci,cls = elm.className;ci=classNames[i++];){\n                    if(!new RegExp('\\\\b' + ci + '\\\\b').test(cls)){\n                        cls += ' ' + ci;\n                    }\n                }\n                elm.className = utils.trim(cls);\n            },\n            removeClass:function (elm, classNames) {\n                classNames = this.isArray(classNames) ? classNames :\n                    this.trim(classNames).replace(/[ ]{2,}/g,' ').split(' ');\n                for(var i = 0,ci,cls = elm.className;ci=classNames[i++];){\n                    cls = cls.replace(new RegExp('\\\\b' + ci + '\\\\b'),'')\n                }\n                cls = this.trim(cls).replace(/[ ]{2,}/g,' ');\n                elm.className = cls;\n                !cls && elm.removeAttribute('className');\n            },\n            on: function (element, type, handler) {\n                var types = this.isArray(type) ? type : type.split(/\\s+/),\n                    k = types.length;\n                if (k) while (k--) {\n                    type = types[k];\n                    if (element.addEventListener) {\n                        element.addEventListener(type, handler, false);\n                    } else {\n                        if (!handler._d) {\n                            handler._d = {\n                                els : []\n                            };\n                        }\n                        var key = type + handler.toString(),index = utils.indexOf(handler._d.els,element);\n                        if (!handler._d[key] || index == -1) {\n                            if(index == -1){\n                                handler._d.els.push(element);\n                            }\n                            if(!handler._d[key]){\n                                handler._d[key] = function (evt) {\n                                    return handler.call(evt.srcElement, evt || window.event);\n                                };\n                            }\n\n\n                            element.attachEvent('on' + type, handler._d[key]);\n                        }\n                    }\n                }\n                element = null;\n            },\n            off: function (element, type, handler) {\n                var types = this.isArray(type) ? type : type.split(/\\s+/),\n                    k = types.length;\n                if (k) while (k--) {\n                    type = types[k];\n                    if (element.removeEventListener) {\n                        element.removeEventListener(type, handler, false);\n                    } else {\n                        var key = type + handler.toString();\n                        try{\n                            element.detachEvent('on' + type, handler._d ? handler._d[key] : handler);\n                        }catch(e){}\n                        if (handler._d && handler._d[key]) {\n                            var index = utils.indexOf(handler._d.els,element);\n                            if(index!=-1){\n                                handler._d.els.splice(index,1);\n                            }\n                            handler._d.els.length == 0 && delete handler._d[key];\n                        }\n                    }\n                }\n            },\n            loadFile : function () {\n                var tmpList = [];\n                function getItem(doc,obj){\n                    try{\n                        for(var i= 0,ci;ci=tmpList[i++];){\n                            if(ci.doc === doc && ci.url == (obj.src || obj.href)){\n                                return ci;\n                            }\n                        }\n                    }catch(e){\n                        return null;\n                    }\n\n                }\n                return function (doc, obj, fn) {\n                    var item = getItem(doc,obj);\n                    if (item) {\n                        if(item.ready){\n                            fn && fn();\n                        }else{\n                            item.funs.push(fn)\n                        }\n                        return;\n                    }\n                    tmpList.push({\n                        doc:doc,\n                        url:obj.src||obj.href,\n                        funs:[fn]\n                    });\n                    if (!doc.body) {\n                        var html = [];\n                        for(var p in obj){\n                            if(p == 'tag')continue;\n                            html.push(p + '=\"' + obj[p] + '\"')\n                        }\n                        doc.write('<' + obj.tag + ' ' + html.join(' ') + ' ></'+obj.tag+'>');\n                        return;\n                    }\n                    if (obj.id && doc.getElementById(obj.id)) {\n                        return;\n                    }\n                    var element = doc.createElement(obj.tag);\n                    delete obj.tag;\n                    for (var p in obj) {\n                        element.setAttribute(p, obj[p]);\n                    }\n                    element.onload = element.onreadystatechange = function () {\n                        if (!this.readyState || /loaded|complete/.test(this.readyState)) {\n                            item = getItem(doc,obj);\n                            if (item.funs.length > 0) {\n                                item.ready = 1;\n                                for (var fi; fi = item.funs.pop();) {\n                                    fi();\n                                }\n                            }\n                            element.onload = element.onreadystatechange = null;\n                        }\n                    };\n                    element.onerror = function(){\n                        throw Error('The load '+(obj.href||obj.src)+' fails,check the url')\n                    };\n                    doc.getElementsByTagName(\"head\")[0].appendChild(element);\n                }\n            }()\n    };\n    utils.each(['String', 'Function', 'Array', 'Number', 'RegExp', 'Object','Boolean'], function (v) {\n        utils['is' + v] = function (obj) {\n            return Object.prototype.toString.apply(obj) == '[object ' + v + ']';\n        }\n    });\n    var parselist = {};\n    UE.parse = {\n        register : function(parseName,fn){\n            parselist[parseName] = fn;\n        },\n        load : function(opt){\n            utils.each(parselist,function(v){\n                v.call(opt,utils);\n            })\n        }\n    };\n    uParse = function(selector,opt){\n        utils.domReady(function(){\n            var contents;\n            if(document.querySelectorAll){\n                contents = document.querySelectorAll(selector)\n            }else{\n                if(/^#/.test(selector)){\n                    contents = [document.getElementById(selector.replace(/^#/,''))]\n                }else if(/^\\./.test(selector)){\n                    var contents = [];\n                    utils.each(document.getElementsByTagName('*'),function(node){\n                        if(node.className && new RegExp('\\\\b' + selector.replace(/^\\./,'') + '\\\\b','i').test(node.className)){\n                            contents.push(node)\n                        }\n                    })\n                }else{\n                    contents = document.getElementsByTagName(selector)\n                }\n            }\n            utils.each(contents,function(v){\n                UE.parse.load(utils.extend({root:v,selector:selector},opt))\n            })\n        })\n    }\n})();\n\nUE.parse.register('insertcode',function(utils){\n    var pres = this.root.getElementsByTagName('pre');\n    if(pres.length){\n        if(typeof XRegExp == \"undefined\"){\n            var jsurl,cssurl;\n            if(this.rootPath !== undefined){\n                jsurl = utils.removeLastbs(this.rootPath)  + '/third-party/SyntaxHighlighter/shCore.js';\n                cssurl = utils.removeLastbs(this.rootPath) + '/third-party/SyntaxHighlighter/shCoreDefault.css';\n            }else{\n                jsurl = this.highlightJsUrl;\n                cssurl = this.highlightCssUrl;\n            }\n            utils.loadFile(document,{\n                id : \"syntaxhighlighter_css\",\n                tag : \"link\",\n                rel : \"stylesheet\",\n                type : \"text/css\",\n                href : cssurl\n            });\n            utils.loadFile(document,{\n                id : \"syntaxhighlighter_js\",\n                src : jsurl,\n                tag : \"script\",\n                type : \"text/javascript\",\n                defer : \"defer\"\n            },function(){\n                utils.each(pres,function(pi){\n                    if(pi && /brush/i.test(pi.className)){\n                        SyntaxHighlighter.highlight(pi);\n                    }\n                });\n            });\n        }else{\n            utils.each(pres,function(pi){\n                if(pi && /brush/i.test(pi.className)){\n                    SyntaxHighlighter.highlight(pi);\n                }\n            });\n        }\n    }\n\n});\nUE.parse.register('table', function (utils) {\n    var me = this,\n        root = this.root,\n        tables = root.getElementsByTagName('table');\n    if (tables.length) {\n        var selector = this.selector;\n        //追加默认的表格样式\n        utils.cssRule('table',\n            selector + ' table.noBorderTable td,' +\n                selector + ' table.noBorderTable th,' +\n                selector + ' table.noBorderTable caption{border:1px dashed #ddd !important}' +\n                selector + ' table.sortEnabled tr.firstRow th,' + selector + ' table.sortEnabled tr.firstRow td{padding-right:20px; background-repeat: no-repeat;' +\n                    'background-position: center right; background-image:url(' + this.rootPath + 'themes/default/images/sortable.png);}' +\n                selector + ' table.sortEnabled tr.firstRow th:hover,' + selector + ' table.sortEnabled tr.firstRow td:hover{background-color: #EEE;}' +\n                selector + ' table{margin-bottom:10px;border-collapse:collapse;display:table;}' +\n                selector + ' td,' + selector + ' th{ background:white; padding: 5px 10px;border: 1px solid #DDD;}' +\n                selector + ' caption{border:1px dashed #DDD;border-bottom:0;padding:3px;text-align:center;}' +\n                selector + ' th{border-top:1px solid #BBB;background:#F7F7F7;}' +\n                selector + ' table tr.firstRow th{border-top:2px solid #BBB;background:#F7F7F7;}' +\n                selector + ' tr.ue-table-interlace-color-single td{ background: #fcfcfc; }' +\n                selector + ' tr.ue-table-interlace-color-double td{ background: #f7faff; }' +\n                selector + ' td p{margin:0;padding:0;}',\n            document);\n        //填充空的单元格\n\n        utils.each('td th caption'.split(' '), function (tag) {\n            var cells = root.getElementsByTagName(tag);\n            cells.length && utils.each(cells, function (node) {\n                if (!node.firstChild) {\n                    node.innerHTML = '&nbsp;';\n\n                }\n            })\n        });\n\n        //表格可排序\n        var tables = root.getElementsByTagName('table');\n        utils.each(tables, function (table) {\n            if (/\\bsortEnabled\\b/.test(table.className)) {\n                utils.on(table, 'click', function(e){\n                    var target = e.target || e.srcElement,\n                        cell = findParentByTagName(target, ['td', 'th']);\n                    var table = findParentByTagName(target, 'table'),\n                        colIndex = utils.indexOf(table.rows[0].cells, cell),\n                        sortType = table.getAttribute('data-sort-type');\n                    if(colIndex != -1) {\n                        sortTable(table, colIndex, me.tableSortCompareFn || sortType);\n                        updateTable(table);\n                    }\n                });\n            }\n        });\n\n        //按照标签名查找父节点\n        function findParentByTagName(target, tagNames) {\n            var i, current = target;\n            tagNames = utils.isArray(tagNames) ? tagNames:[tagNames];\n            while(current){\n                for(i = 0;i < tagNames.length; i++) {\n                    if(current.tagName == tagNames[i].toUpperCase()) return current;\n                }\n                current = current.parentNode;\n            }\n            return null;\n        }\n        //表格排序\n        function sortTable(table, sortByCellIndex, compareFn) {\n            var rows = table.rows,\n                trArray = [],\n                flag = rows[0].cells[0].tagName === \"TH\",\n                lastRowIndex = 0;\n\n            for (var i = 0,len = rows.length; i < len; i++) {\n                trArray[i] = rows[i];\n            }\n\n            var Fn = {\n                'reversecurrent': function(td1,td2){\n                    return 1;\n                },\n                'orderbyasc': function(td1,td2){\n                    var value1 = td1.innerText||td1.textContent,\n                        value2 = td2.innerText||td2.textContent;\n                    return value1.localeCompare(value2);\n                },\n                'reversebyasc': function(td1,td2){\n                    var value1 = td1.innerHTML,\n                        value2 = td2.innerHTML;\n                    return value2.localeCompare(value1);\n                },\n                'orderbynum': function(td1,td2){\n                    var value1 = td1[utils.isIE ? 'innerText':'textContent'].match(/\\d+/),\n                        value2 = td2[utils.isIE ? 'innerText':'textContent'].match(/\\d+/);\n                    if(value1) value1 = +value1[0];\n                    if(value2) value2 = +value2[0];\n                    return (value1||0) - (value2||0);\n                },\n                'reversebynum': function(td1,td2){\n                    var value1 = td1[utils.isIE ? 'innerText':'textContent'].match(/\\d+/),\n                        value2 = td2[utils.isIE ? 'innerText':'textContent'].match(/\\d+/);\n                    if(value1) value1 = +value1[0];\n                    if(value2) value2 = +value2[0];\n                    return (value2||0) - (value1||0);\n                }\n            };\n\n            //对表格设置排序的标记data-sort-type\n            table.setAttribute('data-sort-type', compareFn && typeof compareFn === \"string\" && Fn[compareFn] ? compareFn:'');\n\n            //th不参与排序\n            flag && trArray.splice(0, 1);\n            trArray = sort(trArray,function (tr1, tr2) {\n                var result;\n                if (compareFn && typeof compareFn === \"function\") {\n                    result = compareFn.call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]);\n                } else if (compareFn && typeof compareFn === \"number\") {\n                    result = 1;\n                } else if (compareFn && typeof compareFn === \"string\" && Fn[compareFn]) {\n                    result = Fn[compareFn].call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]);\n                } else {\n                    result = Fn['orderbyasc'].call(this, tr1.cells[sortByCellIndex], tr2.cells[sortByCellIndex]);\n                }\n                return result;\n            });\n            var fragment = table.ownerDocument.createDocumentFragment();\n            for (var j = 0, len = trArray.length; j < len; j++) {\n                fragment.appendChild(trArray[j]);\n            }\n            var tbody = table.getElementsByTagName(\"tbody\")[0];\n            if(!lastRowIndex){\n                tbody.appendChild(fragment);\n            }else{\n                tbody.insertBefore(fragment,rows[lastRowIndex- range.endRowIndex + range.beginRowIndex - 1])\n            }\n        }\n        //冒泡排序\n        function sort(array, compareFn){\n            compareFn = compareFn || function(item1, item2){ return item1.localeCompare(item2);};\n            for(var i= 0,len = array.length; i<len; i++){\n                for(var j = i,length = array.length; j<length; j++){\n                    if(compareFn(array[i], array[j]) > 0){\n                        var t = array[i];\n                        array[i] = array[j];\n                        array[j] = t;\n                    }\n                }\n            }\n            return array;\n        }\n        //更新表格\n        function updateTable(table) {\n            //给第一行设置firstRow的样式名称,在排序图标的样式上使用到\n            if(!utils.hasClass(table.rows[0], \"firstRow\")) {\n                for(var i = 1; i< table.rows.length; i++) {\n                    utils.removeClass(table.rows[i], \"firstRow\");\n                }\n                utils.addClass(table.rows[0], \"firstRow\");\n            }\n        }\n    }\n});\nUE.parse.register('charts',function( utils ){\n\n    utils.cssRule('chartsContainerHeight','.edui-chart-container { height:'+(this.chartContainerHeight||300)+'px}');\n    var resourceRoot = this.rootPath,\n        containers = this.root,\n        sources = null;\n\n    //不存在指定的根路径， 则直接退出\n    if ( !resourceRoot ) {\n        return;\n    }\n\n    if ( sources = parseSources() ) {\n\n        loadResources();\n\n    }\n\n\n    function parseSources () {\n\n        if ( !containers ) {\n            return null;\n        }\n\n        return extractChartData( containers );\n\n    }\n\n    /**\n     * 提取数据\n     */\n    function extractChartData ( rootNode ) {\n\n        var data = [],\n            tables = rootNode.getElementsByTagName( \"table\" );\n\n        for ( var i = 0, tableNode; tableNode = tables[ i ]; i++ ) {\n\n            if ( tableNode.getAttribute( \"data-chart\" ) !== null ) {\n\n                data.push( formatData( tableNode ) );\n\n            }\n\n        }\n\n        return data.length ? data : null;\n\n    }\n\n    function formatData ( tableNode ) {\n\n        var meta = tableNode.getAttribute( \"data-chart\" ),\n            metaConfig = {},\n            data = [];\n\n        //提取table数据\n        for ( var i = 0, row; row = tableNode.rows[ i ]; i++ ) {\n\n            var rowData = [];\n\n            for ( var j = 0, cell; cell = row.cells[ j ]; j++ ) {\n\n                var value = ( cell.innerText || cell.textContent || '' );\n                rowData.push( cell.tagName == 'TH' ? value:(value | 0) );\n\n            }\n\n            data.push( rowData );\n\n        }\n\n        //解析元信息\n        meta = meta.split( \";\" );\n        for ( var i = 0, metaData; metaData = meta[ i ]; i++ ) {\n\n            metaData = metaData.split( \":\" );\n            metaConfig[ metaData[ 0 ] ] = metaData[ 1 ];\n\n        }\n\n\n        return {\n            table: tableNode,\n            meta: metaConfig,\n            data: data\n        };\n\n    }\n\n    //加载资源\n    function loadResources () {\n\n        loadJQuery();\n\n    }\n\n    function loadJQuery () {\n\n        //不存在jquery， 则加载jquery\n        if ( !window.jQuery ) {\n\n            utils.loadFile(document,{\n                src : resourceRoot + \"/third-party/jquery-1.10.2.min.js\",\n                tag : \"script\",\n                type : \"text/javascript\",\n                defer : \"defer\"\n            },function(){\n\n                loadHighcharts();\n\n            });\n\n        } else {\n\n            loadHighcharts();\n\n        }\n\n    }\n\n    function loadHighcharts () {\n\n        //不存在Highcharts， 则加载Highcharts\n        if ( !window.Highcharts ) {\n\n            utils.loadFile(document,{\n                src : resourceRoot + \"/third-party/highcharts/highcharts.js\",\n                tag : \"script\",\n                type : \"text/javascript\",\n                defer : \"defer\"\n            },function(){\n\n                loadTypeConfig();\n\n            });\n\n        } else {\n\n            loadTypeConfig();\n\n        }\n\n    }\n\n    //加载图表差异化配置文件\n    function loadTypeConfig () {\n\n        utils.loadFile(document,{\n            src : resourceRoot + \"/dialogs/charts/chart.config.js\",\n            tag : \"script\",\n            type : \"text/javascript\",\n            defer : \"defer\"\n        },function(){\n\n            render();\n\n        });\n\n    }\n\n    //渲染图表\n    function render () {\n\n        var config = null,\n            chartConfig = null,\n            container = null;\n\n        for ( var i = 0, len = sources.length; i < len; i++ ) {\n\n            config = sources[ i ];\n\n            chartConfig = analysisConfig( config );\n\n            container = createContainer( config.table );\n\n            renderChart( container, typeConfig[ config.meta.chartType ], chartConfig );\n\n        }\n\n\n    }\n\n    /**\n     * 渲染图表\n     * @param container 图表容器节点对象\n     * @param typeConfig 图表类型配置\n     * @param config 图表通用配置\n     * */\n    function renderChart ( container, typeConfig, config ) {\n\n\n        $( container ).highcharts( $.extend( {}, typeConfig, {\n\n            credits: {\n                enabled: false\n            },\n            exporting: {\n                enabled: false\n            },\n            title: {\n                text: config.title,\n                x: -20 //center\n            },\n            subtitle: {\n                text: config.subTitle,\n                x: -20\n            },\n            xAxis: {\n                title: {\n                    text: config.xTitle\n                },\n                categories: config.categories\n            },\n            yAxis: {\n                title: {\n                    text: config.yTitle\n                },\n                plotLines: [{\n                    value: 0,\n                    width: 1,\n                    color: '#808080'\n                }]\n            },\n            tooltip: {\n                enabled: true,\n                valueSuffix: config.suffix\n            },\n            legend: {\n                layout: 'vertical',\n                align: 'right',\n                verticalAlign: 'middle',\n                borderWidth: 1\n            },\n            series: config.series\n\n        } ));\n\n    }\n\n    /**\n     * 创建图表的容器\n     * 新创建的容器会替换掉对应的table对象\n     * */\n    function createContainer ( tableNode ) {\n\n        var container = document.createElement( \"div\" );\n        container.className = \"edui-chart-container\";\n\n        tableNode.parentNode.replaceChild( container, tableNode );\n\n        return container;\n\n    }\n\n    //根据config解析出正确的类别和图表数据信息\n    function analysisConfig ( config ) {\n\n        var series = [],\n        //数据类别\n            categories = [],\n            result = [],\n            data = config.data,\n            meta = config.meta;\n\n        //数据对齐方式为相反的方式， 需要反转数据\n        if ( meta.dataFormat != \"1\" ) {\n\n            for ( var i = 0, len = data.length; i < len ; i++ ) {\n\n                for ( var j = 0, jlen = data[ i ].length; j < jlen; j++ ) {\n\n                    if ( !result[ j ] ) {\n                        result[ j ] = [];\n                    }\n\n                    result[ j ][ i ] = data[ i ][ j ];\n\n                }\n\n            }\n\n            data = result;\n\n        }\n\n        result = {};\n\n        //普通图表\n        if ( meta.chartType != typeConfig.length - 1 ) {\n\n            categories = data[ 0 ].slice( 1 );\n\n            for ( var i = 1, curData; curData = data[ i ]; i++ ) {\n                series.push( {\n                    name: curData[ 0 ],\n                    data: curData.slice( 1 )\n                } );\n            }\n\n            result.series = series;\n            result.categories = categories;\n            result.title = meta.title;\n            result.subTitle = meta.subTitle;\n            result.xTitle = meta.xTitle;\n            result.yTitle = meta.yTitle;\n            result.suffix = meta.suffix;\n\n        } else {\n\n            var curData = [];\n\n            for ( var i = 1, len = data[ 0 ].length; i < len; i++ ) {\n\n                curData.push( [ data[ 0 ][ i ], data[ 1 ][ i ] | 0 ] );\n\n            }\n\n            //饼图\n            series[ 0 ] = {\n                type: 'pie',\n                name: meta.tip,\n                data: curData\n            };\n\n            result.series = series;\n            result.title = meta.title;\n            result.suffix = meta.suffix;\n\n        }\n\n        return result;\n\n    }\n\n});\nUE.parse.register('background', function (utils) {\n    var me = this,\n        root = me.root,\n        p = root.getElementsByTagName('p'),\n        styles;\n\n    for (var i = 0,ci; ci = p[i++];) {\n        styles = ci.getAttribute('data-background');\n        if (styles){\n            ci.parentNode.removeChild(ci);\n        }\n    }\n\n    //追加默认的表格样式\n    styles && utils.cssRule('ueditor_background', me.selector + '{' + styles + '}', document);\n});\nUE.parse.register('list',function(utils){\n    var customCss = [],\n        customStyle = {\n            'cn'    :   'cn-1-',\n            'cn1'   :   'cn-2-',\n            'cn2'   :   'cn-3-',\n            'num'   :   'num-1-',\n            'num1'  :   'num-2-',\n            'num2'  :   'num-3-',\n            'dash'  :   'dash',\n            'dot'   :   'dot'\n        };\n\n\n    utils.extend(this,{\n        liiconpath : 'http://bs.baidu.com/listicon/',\n        listDefaultPaddingLeft : '20'\n    });\n\n    var root = this.root,\n        ols = root.getElementsByTagName('ol'),\n        uls = root.getElementsByTagName('ul'),\n        selector = this.selector;\n\n    if(ols.length){\n        applyStyle.call(this,ols);\n    }\n\n    if(uls.length){\n        applyStyle.call(this,uls);\n    }\n\n    if(ols.length || uls.length){\n        customCss.push(selector +' .list-paddingleft-1{padding-left:0}');\n        customCss.push(selector +' .list-paddingleft-2{padding-left:'+ this.listDefaultPaddingLeft+'px}');\n        customCss.push(selector +' .list-paddingleft-3{padding-left:'+ this.listDefaultPaddingLeft*2+'px}');\n\n        utils.cssRule('list', selector +' ol,'+selector +' ul{margin:0;padding:0;}li{clear:both;}'+customCss.join('\\n'), document);\n    }\n    function applyStyle(nodes){\n        var T = this;\n        utils.each(nodes,function(list){\n            if(list.className && /custom_/i.test(list.className)){\n                var listStyle = list.className.match(/custom_(\\w+)/)[1];\n                if(listStyle == 'dash' || listStyle == 'dot'){\n                    utils.pushItem(customCss,selector +' li.list-' + customStyle[listStyle] + '{background-image:url(' + T.liiconpath +customStyle[listStyle]+'.gif)}');\n                    utils.pushItem(customCss,selector +' ul.custom_'+listStyle+'{list-style:none;} '+ selector +' ul.custom_'+listStyle+' li{background-position:0 3px;background-repeat:no-repeat}');\n\n                }else{\n                    var index = 1;\n                    utils.each(list.childNodes,function(li){\n                        if(li.tagName == 'LI'){\n                            utils.pushItem(customCss,selector + ' li.list-' + customStyle[listStyle] + index + '{background-image:url(' + T.liiconpath  + 'list-'+customStyle[listStyle] +index + '.gif)}');\n                            index++;\n                        }\n                    });\n                    utils.pushItem(customCss,selector + ' ol.custom_'+listStyle+'{list-style:none;}'+selector+' ol.custom_'+listStyle+' li{background-position:0 3px;background-repeat:no-repeat}');\n                }\n                switch(listStyle){\n                    case 'cn':\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-1{padding-left:25px}');\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-2{padding-left:40px}');\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-3{padding-left:55px}');\n                        break;\n                    case 'cn1':\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-1{padding-left:30px}');\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-2{padding-left:40px}');\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-3{padding-left:55px}');\n                        break;\n                    case 'cn2':\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-1{padding-left:40px}');\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-2{padding-left:55px}');\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-3{padding-left:68px}');\n                        break;\n                    case 'num':\n                    case 'num1':\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-1{padding-left:25px}');\n                        break;\n                    case 'num2':\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-1{padding-left:35px}');\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft-2{padding-left:40px}');\n                        break;\n                    case 'dash':\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft{padding-left:35px}');\n                        break;\n                    case 'dot':\n                        utils.pushItem(customCss,selector + ' li.list-'+listStyle+'-paddingleft{padding-left:20px}');\n                }\n            }\n        });\n    }\n\n\n});\nUE.parse.register('vedio',function(utils){\n    var video = this.root.getElementsByTagName('video'),\n        audio = this.root.getElementsByTagName('audio');\n\n    document.createElement('video');document.createElement('audio');\n    if(video.length || audio.length){\n        var sourcePath = utils.removeLastbs(this.rootPath),\n            jsurl = sourcePath + '/third-party/video-js/video.js',\n            cssurl = sourcePath + '/third-party/video-js/video-js.min.css',\n            swfUrl = sourcePath + '/third-party/video-js/video-js.swf';\n\n        if(window.videojs) {\n            videojs.autoSetup();\n        } else {\n            utils.loadFile(document,{\n                id : \"video_css\",\n                tag : \"link\",\n                rel : \"stylesheet\",\n                type : \"text/css\",\n                href : cssurl\n            });\n            utils.loadFile(document,{\n                id : \"video_js\",\n                src : jsurl,\n                tag : \"script\",\n                type : \"text/javascript\"\n            },function(){\n                videojs.options.flash.swf = swfUrl;\n                videojs.autoSetup();\n            });\n        }\n\n    }\n});\n\n})();\n"
  },
  {
    "path": "think",
    "content": "#!/usr/bin/env php\r\n<?php\r\n// +----------------------------------------------------------------------\r\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\r\n// +----------------------------------------------------------------------\r\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\r\n// +----------------------------------------------------------------------\r\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\r\n// +----------------------------------------------------------------------\r\n// | Author: yunwuxin <448901948@qq.com>\r\n// +----------------------------------------------------------------------\r\n\r\n// 定义项目路径\r\ndefine('APP_PATH', __DIR__ . '/application/');\r\n\r\n// 加载框架引导文件\r\nrequire './thinkphp/console.php';"
  },
  {
    "path": "thinkphp/.gitignore",
    "content": "/composer.lock\n/vendor\n.idea\n.DS_Store\n"
  },
  {
    "path": "thinkphp/.htaccess",
    "content": "deny from all"
  },
  {
    "path": "thinkphp/.travis.yml",
    "content": "sudo: false\n\nlanguage: php\n\nservices:\n  - memcached\n  - mongodb\n  - mysql\n  - postgresql\n  - redis-server\n\nmatrix:\n  fast_finish: true\n  include:\n    - php: 5.4\n    - php: 5.5\n    - php: 5.6\n    - php: 7.0\n    - php: hhvm\n  allow_failures:\n    - php: hhvm\n\ncache:\n  directories:\n    - $HOME/.composer/cache\n\nbefore_install:\n  - composer self-update\n  - mysql -e \"create database IF NOT EXISTS test;\" -uroot\n  - psql -c 'DROP DATABASE IF EXISTS test;' -U postgres\n  - psql -c 'create database test;' -U postgres\n\ninstall:\n  - ./tests/script/install.sh\n\nscript:\n  ## LINT\n  - find . -path ./vendor -prune -o -type f -name \\*.php -exec php -l {} \\;\n  ## PHP Copy/Paste Detector\n  - vendor/bin/phpcpd --verbose --exclude vendor ./ || true\n  ## PHPLOC\n  - vendor/bin/phploc --exclude vendor ./\n  ## PHPUNIT\n  - vendor/bin/phpunit --coverage-clover=coverage.xml --configuration=phpunit.xml\n\nafter_success:\n  - bash <(curl -s https://codecov.io/bash)\n"
  },
  {
    "path": "thinkphp/CONTRIBUTING.md",
    "content": "如何贡献我的源代码\n===\n\n此文档介绍了 ThinkPHP 团队的组成以及运转机制，您提交的代码将给 ThinkPHP 项目带来什么好处，以及如何才能加入我们的行列。\n\n## 通过 Github 贡献代码\n\nThinkPHP 目前使用 Git 来控制程序版本，如果你想为 ThinkPHP 贡献源代码，请先大致了解 Git 的使用方法。我们目前把项目托管在 GitHub 上，任何 GitHub 用户都可以向我们贡献代码。\n\n参与的方式很简单，`fork`一份 ThinkPHP 的代码到你的仓库中，修改后提交，并向我们发起`pull request`申请，我们会及时对代码进行审查并处理你的申请并。审查通过后，你的代码将被`merge`进我们的仓库中，这样你就会自动出现在贡献者名单里了，非常方便。\n\n我们希望你贡献的代码符合：\n\n* ThinkPHP 的编码规范\n* 适当的注释，能让其他人读懂\n* 遵循 Apache2 开源协议\n\n**如果想要了解更多细节或有任何疑问，请继续阅读下面的内容**\n\n### 注意事项\n\n* 本项目代码格式化标准选用 [**PSR-2**](http://www.kancloud.cn/thinkphp/php-fig-psr/3141)；\n* 类名和类文件名遵循 [**PSR-4**](http://www.kancloud.cn/thinkphp/php-fig-psr/3144)；\n* 对于 Issues 的处理，请使用诸如 `fix #xxx(Issue ID)` 的 commit title 直接关闭 issue。\n* 系统会自动在 PHP 5.4 5.5 5.6 7.0 和 HHVM 上测试修改，其中 HHVM 下的测试容许报错，请确保你的修改符合 PHP 5.4 ~ 5.6 和 PHP 7.0 的语法规范；\n* 管理员不会合并造成 CI faild 的修改，若出现 CI faild 请检查自己的源代码或修改相应的[单元测试文件](tests)；\n\n## GitHub Issue\n\nGitHub 提供了 Issue 功能，该功能可以用于：\n\n* 提出 bug\n* 提出功能改进\n* 反馈使用体验\n\n该功能不应该用于：\n\n * 提出修改意见（涉及代码署名和修订追溯问题）\n * 不友善的言论\n\n## 快速修改\n\n**GitHub 提供了快速编辑文件的功能**\n\n1. 登录 GitHub 帐号；\n2. 浏览项目文件，找到要进行修改的文件；\n3. 点击右上角铅笔图标进行修改；\n4. 填写 `Commit changes` 相关内容（Title 必填）；\n5. 提交修改，等待 CI 验证和管理员合并。\n\n**若您需要一次提交大量修改，请继续阅读下面的内容**\n\n## 完整流程\n\n1. `fork`本项目；\n2. 克隆(`clone`)你 `fork` 的项目到本地；\n3. 新建分支(`branch`)并检出(`checkout`)新分支；\n4. 添加本项目到你的本地 git 仓库作为上游(`upstream`)；\n5. 进行修改，若你的修改包含方法或函数的增减，请记得修改[单元测试文件](tests)；\n6. 变基（衍合 `rebase`）你的分支到上游 master 分支；\n7. `push` 你的本地仓库到 GitHub；\n8. 提交 `pull request`；\n9. 等待 CI 验证（若不通过则重复 5~7，GitHub 会自动更新你的 `pull request`）；\n10. 等待管理员处理，并及时 `rebase` 你的分支到上游 master 分支（若上游 master 分支有修改）。\n\n*若有必要，可以 `git push -f` 强行推送 rebase 后的分支到自己的 `fork`*\n\n*绝对不可以使用 `git push -f` 强行推送修改到上游*\n\n### 注意事项\n\n* 若对上述流程有任何不清楚的地方，请查阅 GIT 教程，如 [这个](http://backlogtool.com/git-guide/cn/)；\n* 对于代码**不同方面**的修改，请在自己 `fork` 的项目中**创建不同的分支**（原因参见`完整流程`第9条备注部分）；\n* 变基及交互式变基操作参见 [Git 交互式变基](http://pakchoi.me/2015/03/17/git-interactive-rebase/)\n\n## 推荐资源\n\n### 开发环境\n\n* XAMPP for Windows 5.5.x\n* WampServer (for Windows)\n* upupw Apache PHP5.4 ( for Windows)\n\n或自行安装\n\n- Apache / Nginx\n- PHP 5.4 ~ 5.6\n- MySQL / MariaDB\n\n*Windows 用户推荐添加 PHP bin 目录到 PATH，方便使用 composer*\n\n*Linux 用户自行配置环境， Mac 用户推荐使用内置 Apache 配合 Homebrew 安装 PHP 和 MariaDB*\n\n### 编辑器\n\nSublime Text 3 + phpfmt 插件\n\nphpfmt 插件参数\n\n```json\n{\n\t\"autocomplete\": true,\n\t\"enable_auto_align\": true,\n\t\"format_on_save\": true,\n\t\"indent_with_space\": true,\n\t\"psr1_naming\": false,\n\t\"psr2\": true,\n\t\"version\": 4\n}\n```\n\n或其他 编辑器 / IDE 配合 PSR2 自动格式化工具\n\n### Git GUI\n\n* SourceTree\n* GitHub Desktop\n\n或其他 Git 图形界面客户端\n"
  },
  {
    "path": "thinkphp/LICENSE.txt",
    "content": "\nThinkPHP遵循Apache2开源协议发布，并提供免费使用。\n版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)\nAll rights reserved。\nThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。\n\nApache Licence是著名的非盈利开源组织Apache采用的协议。\n该协议和BSD类似，鼓励代码共享和尊重原作者的著作权，\n允许代码修改，再作为开源或商业软件发布。需要满足\n的条件： \n1． 需要给代码的用户一份Apache Licence ；\n2． 如果你修改了代码，需要在被修改的文件中说明；\n3． 在延伸的代码中（修改和有源代码衍生的代码中）需要\n带有原来代码中的协议，商标，专利声明和其他原来作者规\n定需要包含的说明；\n4． 如果再发布的产品中包含一个Notice文件，则在Notice文\n件中需要带有本协议内容。你可以在Notice中增加自己的\n许可，但不可以表现为对Apache Licence构成更改。 \n具体的协议参考：http://www.apache.org/licenses/LICENSE-2.0\n\nTHIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS\n\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT\nLIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS\nFOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE\nCOPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\nINCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,\nBUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\nLOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER\nCAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\nLIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\nANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\nPOSSIBILITY OF SUCH DAMAGE.\n"
  },
  {
    "path": "thinkphp/README.md",
    "content": "ThinkPHP 5.0\n===============\n\n[![StyleCI](https://styleci.io/repos/48530411/shield?style=flat&branch=master)](https://styleci.io/repos/48530411)\n[![Build Status](https://travis-ci.org/top-think/framework.svg?branch=master)](https://travis-ci.org/top-think/framework)\n[![codecov.io](http://codecov.io/github/top-think/framework/coverage.svg?branch=master)](http://codecov.io/github/github/top-think/framework?branch=master)\n[![Total Downloads](https://poser.pugx.org/topthink/framework/downloads)](https://packagist.org/packages/topthink/framework)\n[![Latest Stable Version](https://poser.pugx.org/topthink/framework/v/stable)](https://packagist.org/packages/topthink/framework)\n[![Latest Unstable Version](https://poser.pugx.org/topthink/framework/v/unstable)](https://packagist.org/packages/topthink/framework)\n[![License](https://poser.pugx.org/topthink/framework/license)](https://packagist.org/packages/topthink/framework)\n\nThinkPHP5在保持快速开发和大道至简的核心理念不变的同时，PHP版本要求提升到5.4，优化核心，减少依赖，基于全新的架构思想和命名空间实现，是ThinkPHP突破原有框架思路的颠覆之作，其主要特性包括：\n\n + 基于命名空间和众多PHP新特性\n + 核心功能组件化\n + 强化路由功能\n + 更灵活的控制器\n + 重构的模型和数据库类\n + 配置文件可分离\n + 重写的自动验证和完成\n + 简化扩展机制\n + API支持完善\n + 改进的Log类\n + 命令行访问支持\n + REST支持\n + 引导文件支持\n + 方便的自动生成定义\n + 真正惰性加载\n + 分布式环境支持\n + 支持Composer\n + 支持MongoDb\n\n> ThinkPHP5的运行环境要求PHP5.4以上。\n\n详细开发文档参考 [ThinkPHP5完全开发手册](http://www.kancloud.cn/manual/thinkphp5) 以及[ThinkPHP5入门系列教程](http://www.kancloud.cn/special/thinkphp5_quickstart)\n\n## 目录结构\n\n初始的目录结构如下：\n\n~~~\nwww  WEB部署目录（或者子目录）\n├─application           应用目录\n│  ├─common             公共模块目录（可以更改）\n│  ├─module_name        模块目录\n│  │  ├─config.php      模块配置文件\n│  │  ├─common.php      模块函数文件\n│  │  ├─controller      控制器目录\n│  │  ├─model           模型目录\n│  │  ├─view            视图目录\n│  │  └─ ...            更多类库目录\n│  │\n│  ├─command.php        命令行工具配置文件\n│  ├─common.php         公共函数文件\n│  ├─config.php         公共配置文件\n│  ├─route.php          路由配置文件\n│  ├─tags.php           应用行为扩展定义文件\n│  └─database.php       数据库配置文件\n│\n├─public                WEB目录（对外访问目录）\n│  ├─index.php          入口文件\n│  ├─router.php         快速测试文件\n│  └─.htaccess          用于apache的重写\n│\n├─thinkphp              框架系统目录\n│  ├─lang               语言文件目录\n│  ├─library            框架类库目录\n│  │  ├─think           Think类库包目录\n│  │  └─traits          系统Trait目录\n│  │\n│  ├─tpl                系统模板目录\n│  ├─base.php           基础定义文件\n│  ├─console.php        控制台入口文件\n│  ├─convention.php     框架惯例配置文件\n│  ├─helper.php         助手函数文件\n│  ├─phpunit.xml        phpunit配置文件\n│  └─start.php          框架入口文件\n│\n├─extend                扩展类库目录\n├─runtime               应用的运行时目录（可写，可定制）\n├─vendor                第三方类库目录（Composer依赖库）\n├─build.php             自动生成定义文件（参考）\n├─composer.json         composer 定义文件\n├─LICENSE.txt           授权说明文件\n├─README.md             README 文件\n├─think                 命令行入口文件\n~~~\n\n> router.php用于php自带webserver支持，可用于快速测试\n> 切换到public目录后，启动命令：php -S localhost:8888  router.php\n> 上面的目录结构和名称是可以改变的，这取决于你的入口文件和配置参数。\n\n## 命名规范\n\nThinkPHP5的命名规范遵循PSR-2规范以及PSR-4自动加载规范。\n\n## 参与开发\n注册并登录 Github 帐号， fork 本项目并进行改动。\n\n更多细节参阅 [CONTRIBUTING.md](CONTRIBUTING.md)\n\n## 版权信息\n\nThinkPHP遵循Apache2开源协议发布，并提供免费使用。\n\n本项目包含的第三方源码和二进制文件之版权信息另行标注。\n\n版权所有Copyright © 2006-2016 by ThinkPHP (http://thinkphp.cn)\n\nAll rights reserved。\n\nThinkPHP® 商标和著作权所有者为上海顶想信息科技有限公司。\n\n更多细节参阅 [LICENSE.txt](LICENSE.txt)\n"
  },
  {
    "path": "thinkphp/base.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\ndefine('THINK_VERSION', '5.0.8');\ndefine('THINK_START_TIME', microtime(true));\ndefine('THINK_START_MEM', memory_get_usage());\ndefine('EXT', '.php');\ndefine('DS', DIRECTORY_SEPARATOR);\ndefined('THINK_PATH') or define('THINK_PATH', __DIR__ . DS);\ndefine('LIB_PATH', THINK_PATH . 'library' . DS);\ndefine('CORE_PATH', LIB_PATH . 'think' . DS);\ndefine('TRAIT_PATH', LIB_PATH . 'traits' . DS);\ndefined('APP_PATH') or define('APP_PATH', dirname($_SERVER['SCRIPT_FILENAME']) . DS);\ndefined('ROOT_PATH') or define('ROOT_PATH', dirname(realpath(APP_PATH)) . DS);\ndefined('EXTEND_PATH') or define('EXTEND_PATH', ROOT_PATH . 'extend' . DS);\ndefined('VENDOR_PATH') or define('VENDOR_PATH', ROOT_PATH . 'vendor' . DS);\ndefined('RUNTIME_PATH') or define('RUNTIME_PATH', ROOT_PATH . 'runtime' . DS);\ndefined('LOG_PATH') or define('LOG_PATH', RUNTIME_PATH . 'log' . DS);\ndefined('CACHE_PATH') or define('CACHE_PATH', RUNTIME_PATH . 'cache' . DS);\ndefined('TEMP_PATH') or define('TEMP_PATH', RUNTIME_PATH . 'temp' . DS);\ndefined('CONF_PATH') or define('CONF_PATH', APP_PATH); // 配置文件目录\ndefined('CONF_EXT') or define('CONF_EXT', EXT); // 配置文件后缀\ndefined('ENV_PREFIX') or define('ENV_PREFIX', 'PHP_'); // 环境变量的配置前缀\n\n// 环境常量\ndefine('IS_CLI', PHP_SAPI == 'cli' ? true : false);\ndefine('IS_WIN', strpos(PHP_OS, 'WIN') !== false);\n\n// 载入Loader类\nrequire CORE_PATH . 'Loader.php';\n\n// 加载环境变量配置文件\nif (is_file(ROOT_PATH . '.env')) {\n    $env = parse_ini_file(ROOT_PATH . '.env', true);\n    foreach ($env as $key => $val) {\n        $name = ENV_PREFIX . strtoupper($key);\n        if (is_array($val)) {\n            foreach ($val as $k => $v) {\n                $item = $name . '_' . strtoupper($k);\n                putenv(\"$item=$v\");\n            }\n        } else {\n            putenv(\"$name=$val\");\n        }\n    }\n}\n\n// 注册自动加载\n\\think\\Loader::register();\n\n// 注册错误和异常处理机制\n\\think\\Error::register();\n\n// 加载惯例配置文件\n\\think\\Config::set(include THINK_PATH . 'convention' . EXT);\n"
  },
  {
    "path": "thinkphp/codecov.yml",
    "content": "comment:\n  layout: header, changes, diff\ncoverage:\n  ignore:\n  - base.php\n  - helper.php\n  - convention.php\n  - lang/zh-cn.php\n  - start.php\n  - console.php\n  status:\n    patch: false\n"
  },
  {
    "path": "thinkphp/composer.json",
    "content": "{\n    \"name\": \"topthink/framework\",\n    \"description\": \"the new thinkphp framework\",\n    \"type\": \"think-framework\",\n    \"keywords\": [\n        \"framework\",\n        \"thinkphp\",\n        \"ORM\"\n    ],\n    \"homepage\": \"http://thinkphp.cn/\",\n    \"license\": \"Apache-2.0\",\n    \"authors\": [\n        {\n            \"name\": \"liu21st\",\n            \"email\": \"liu21st@gmail.com\"\n        }\n    ],\n    \"require\": {\n        \"php\": \">=5.4.0\",\n        \"topthink/think-installer\": \"~1.0\"\n    },\n    \"require-dev\": {\n        \"phpunit/phpunit\": \"4.8.*\",\n        \"johnkary/phpunit-speedtrap\": \"^1.0\",\n        \"mikey179/vfsStream\": \"~1.6\",\n        \"phploc/phploc\": \"2.*\",\n        \"sebastian/phpcpd\": \"2.*\",\n        \"phpdocumentor/reflection-docblock\": \"^2.0\"\n    },\n    \"autoload\": {\n        \"psr-4\": {\n            \"think\\\\\": \"library/think\"\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/console.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\n// ThinkPHP 引导文件\n// 加载基础文件\nrequire __DIR__ . '/base.php';\n\n// 执行应用\nApp::initCommon();\nConsole::init();\n"
  },
  {
    "path": "thinkphp/convention.php",
    "content": "<?php\n\nreturn [\n    // +----------------------------------------------------------------------\n    // | 应用设置\n    // +----------------------------------------------------------------------\n\n    // 应用调试模式\n    'app_debug'              => true,\n    // 应用Trace\n    'app_trace'              => false,\n    // 应用模式状态\n    'app_status'             => '',\n    // 是否支持多模块\n    'app_multi_module'       => true,\n    // 入口自动绑定模块\n    'auto_bind_module'       => false,\n    // 注册的根命名空间\n    'root_namespace'         => [],\n    // 扩展函数文件\n    'extra_file_list'        => [THINK_PATH . 'helper' . EXT],\n    // 默认输出类型\n    'default_return_type'    => 'html',\n    // 默认AJAX 数据返回格式,可选json xml ...\n    'default_ajax_return'    => 'json',\n    // 默认JSONP格式返回的处理方法\n    'default_jsonp_handler'  => 'jsonpReturn',\n    // 默认JSONP处理方法\n    'var_jsonp_handler'      => 'callback',\n    // 默认时区\n    'default_timezone'       => 'PRC',\n    // 是否开启多语言\n    'lang_switch_on'         => false,\n    // 默认全局过滤方法 用逗号分隔多个\n    'default_filter'         => '',\n    // 默认语言\n    'default_lang'           => 'zh-cn',\n    // 应用类库后缀\n    'class_suffix'           => false,\n    // 控制器类后缀\n    'controller_suffix'      => false,\n\n    // +----------------------------------------------------------------------\n    // | 模块设置\n    // +----------------------------------------------------------------------\n\n    // 默认模块名\n    'default_module'         => 'index',\n    // 禁止访问模块\n    'deny_module_list'       => ['common'],\n    // 默认控制器名\n    'default_controller'     => 'Index',\n    // 默认操作名\n    'default_action'         => 'index',\n    // 默认验证器\n    'default_validate'       => '',\n    // 默认的空控制器名\n    'empty_controller'       => 'Error',\n    // 操作方法前缀\n    'use_action_prefix'      => false,\n    // 操作方法后缀\n    'action_suffix'          => '',\n    // 自动搜索控制器\n    'controller_auto_search' => false,\n\n    // +----------------------------------------------------------------------\n    // | URL设置\n    // +----------------------------------------------------------------------\n\n    // PATHINFO变量名 用于兼容模式\n    'var_pathinfo'           => 's',\n    // 兼容PATH_INFO获取\n    'pathinfo_fetch'         => ['ORIG_PATH_INFO', 'REDIRECT_PATH_INFO', 'REDIRECT_URL'],\n    // pathinfo分隔符\n    'pathinfo_depr'          => '/',\n    // URL伪静态后缀\n    'url_html_suffix'        => 'html',\n    // URL普通方式参数 用于自动生成\n    'url_common_param'       => false,\n    // URL参数方式 0 按名称成对解析 1 按顺序解析\n    'url_param_type'         => 0,\n    // 是否开启路由\n    'url_route_on'           => true,\n    // 路由配置文件（支持配置多个）\n    'route_config_file'      => ['route'],\n    // 路由使用完整匹配\n    'route_complete_match'   => false,\n    // 是否强制使用路由\n    'url_route_must'         => false,\n    // 域名部署\n    'url_domain_deploy'      => false,\n    // 域名根，如thinkphp.cn\n    'url_domain_root'        => '',\n    // 是否自动转换URL中的控制器和操作名\n    'url_convert'            => true,\n    // 默认的访问控制器层\n    'url_controller_layer'   => 'controller',\n    // 表单请求类型伪装变量\n    'var_method'             => '_method',\n    // 表单ajax伪装变量\n    'var_ajax'               => '_ajax',\n    // 表单pjax伪装变量\n    'var_pjax'               => '_pjax',\n    // 是否开启请求缓存 true自动缓存 支持设置请求缓存规则\n    'request_cache'          => false,\n    // 请求缓存有效期\n    'request_cache_expire'   => null,\n    // 全局请求缓存排除规则\n    'request_cache_except'   => [],\n\n    // +----------------------------------------------------------------------\n    // | 模板设置\n    // +----------------------------------------------------------------------\n\n    'template'               => [\n        // 模板引擎类型 支持 php think 支持扩展\n        'type'         => 'Think',\n        // 视图基础目录，配置目录为所有模块的视图起始目录\n        'view_base'    => '',\n        // 当前模板的视图目录 留空为自动获取\n        'view_path'    => '',\n        // 模板后缀\n        'view_suffix'  => 'html',\n        // 模板文件名分隔符\n        'view_depr'    => DS,\n        // 模板引擎普通标签开始标记\n        'tpl_begin'    => '{',\n        // 模板引擎普通标签结束标记\n        'tpl_end'      => '}',\n        // 标签库标签开始标记\n        'taglib_begin' => '{',\n        // 标签库标签结束标记\n        'taglib_end'   => '}',\n    ],\n\n    // 视图输出字符串内容替换\n    'view_replace_str'       => [],\n    // 默认跳转页面对应的模板文件\n    'dispatch_success_tmpl'  => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',\n    'dispatch_error_tmpl'    => THINK_PATH . 'tpl' . DS . 'dispatch_jump.tpl',\n\n    // +----------------------------------------------------------------------\n    // | 异常及错误设置\n    // +----------------------------------------------------------------------\n\n    // 异常页面的模板文件\n    'exception_tmpl'         => THINK_PATH . 'tpl' . DS . 'think_exception.tpl',\n\n    // 错误显示信息,非调试模式有效\n    'error_message'          => '页面错误！请稍后再试～',\n    // 显示错误信息\n    'show_error_msg'         => false,\n    // 异常处理handle类 留空使用 \\think\\exception\\Handle\n    'exception_handle'       => '',\n\n    // +----------------------------------------------------------------------\n    // | 日志设置\n    // +----------------------------------------------------------------------\n\n    'log'                    => [\n        // 日志记录方式，内置 file socket 支持扩展\n        'type'  => 'File',\n        // 日志保存目录\n        'path'  => LOG_PATH,\n        // 日志记录级别\n        'level' => [],\n    ],\n\n    // +----------------------------------------------------------------------\n    // | Trace设置 开启 app_trace 后 有效\n    // +----------------------------------------------------------------------\n    'trace'                  => [\n        // 内置Html Console 支持扩展\n        'type' => 'Html',\n    ],\n\n    // +----------------------------------------------------------------------\n    // | 缓存设置\n    // +----------------------------------------------------------------------\n\n    'cache'                  => [\n        // 驱动方式\n        'type'   => 'File',\n        // 缓存保存目录\n        'path'   => CACHE_PATH,\n        // 缓存前缀\n        'prefix' => '',\n        // 缓存有效期 0表示永久缓存\n        'expire' => 0,\n    ],\n\n    // +----------------------------------------------------------------------\n    // | 会话设置\n    // +----------------------------------------------------------------------\n\n    'session'                => [\n        'id'             => '',\n        // SESSION_ID的提交变量,解决flash上传跨域\n        'var_session_id' => '',\n        // SESSION 前缀\n        'prefix'         => 'think',\n        // 驱动方式 支持redis memcache memcached\n        'type'           => '',\n        // 是否自动开启 SESSION\n        'auto_start'     => true,\n        'httponly'       => true,\n        'secure'         => false,\n    ],\n\n    // +----------------------------------------------------------------------\n    // | Cookie设置\n    // +----------------------------------------------------------------------\n    'cookie'                 => [\n        // cookie 名称前缀\n        'prefix'    => '',\n        // cookie 保存时间\n        'expire'    => 0,\n        // cookie 保存路径\n        'path'      => '/',\n        // cookie 有效域名\n        'domain'    => '',\n        //  cookie 启用安全传输\n        'secure'    => false,\n        // httponly设置\n        'httponly'  => '',\n        // 是否使用 setcookie\n        'setcookie' => true,\n    ],\n\n    // +----------------------------------------------------------------------\n    // | 数据库设置\n    // +----------------------------------------------------------------------\n\n    'database'               => [\n        // 数据库类型\n        'type'            => 'mysql',\n        // 数据库连接DSN配置\n        'dsn'             => '',\n        // 服务器地址\n        'hostname'        => '127.0.0.1',\n        // 数据库名\n        'database'        => '',\n        // 数据库用户名\n        'username'        => 'root',\n        // 数据库密码\n        'password'        => '',\n        // 数据库连接端口\n        'hostport'        => '',\n        // 数据库连接参数\n        'params'          => [],\n        // 数据库编码默认采用utf8\n        'charset'         => 'utf8',\n        // 数据库表前缀\n        'prefix'          => '',\n        // 数据库调试模式\n        'debug'           => false,\n        // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)\n        'deploy'          => 0,\n        // 数据库读写是否分离 主从式有效\n        'rw_separate'     => false,\n        // 读写分离后 主服务器数量\n        'master_num'      => 1,\n        // 指定从服务器序号\n        'slave_no'        => '',\n        // 是否严格检查字段是否存在\n        'fields_strict'   => true,\n        // 数据集返回类型\n        'resultset_type'  => 'array',\n        // 自动写入时间戳字段\n        'auto_timestamp'  => false,\n        // 时间字段取出后的默认时间格式\n        'datetime_format' => 'Y-m-d H:i:s',\n        // 是否需要进行SQL性能分析\n        'sql_explain'     => false,\n    ],\n\n    //分页配置\n    'paginate'               => [\n        'type'      => 'bootstrap',\n        'var_page'  => 'page',\n        'list_rows' => 15,\n    ],\n\n];\n"
  },
  {
    "path": "thinkphp/helper.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\n//------------------------\n// ThinkPHP 助手函数\n//-------------------------\n\nuse think\\Cache;\nuse think\\Config;\nuse think\\Cookie;\nuse think\\Db;\nuse think\\Debug;\nuse think\\exception\\HttpException;\nuse think\\exception\\HttpResponseException;\nuse think\\Lang;\nuse think\\Loader;\nuse think\\Log;\nuse think\\Model;\nuse think\\Request;\nuse think\\Response;\nuse think\\Session;\nuse think\\Url;\nuse think\\View;\n\nif (!function_exists('load_trait')) {\n    /**\n     * 快速导入Traits PHP5.5以上无需调用\n     * @param string    $class trait库\n     * @param string    $ext 类库后缀\n     * @return boolean\n     */\n    function load_trait($class, $ext = EXT)\n    {\n        return Loader::import($class, TRAIT_PATH, $ext);\n    }\n}\n\nif (!function_exists('exception')) {\n    /**\n     * 抛出异常处理\n     *\n     * @param string    $msg  异常消息\n     * @param integer   $code 异常代码 默认为0\n     * @param string    $exception 异常类\n     *\n     * @throws Exception\n     */\n    function exception($msg, $code = 0, $exception = '')\n    {\n        $e = $exception ?: '\\think\\Exception';\n        throw new $e($msg, $code);\n    }\n}\n\nif (!function_exists('debug')) {\n    /**\n     * 记录时间（微秒）和内存使用情况\n     * @param string            $start 开始标签\n     * @param string            $end 结束标签\n     * @param integer|string    $dec 小数位 如果是m 表示统计内存占用\n     * @return mixed\n     */\n    function debug($start, $end = '', $dec = 6)\n    {\n        if ('' == $end) {\n            Debug::remark($start);\n        } else {\n            return 'm' == $dec ? Debug::getRangeMem($start, $end) : Debug::getRangeTime($start, $end, $dec);\n        }\n    }\n}\n\nif (!function_exists('lang')) {\n    /**\n     * 获取语言变量值\n     * @param string    $name 语言变量名\n     * @param array     $vars 动态变量值\n     * @param string    $lang 语言\n     * @return mixed\n     */\n    function lang($name, $vars = [], $lang = '')\n    {\n        return Lang::get($name, $vars, $lang);\n    }\n}\n\nif (!function_exists('config')) {\n    /**\n     * 获取和设置配置参数\n     * @param string|array  $name 参数名\n     * @param mixed         $value 参数值\n     * @param string        $range 作用域\n     * @return mixed\n     */\n    function config($name = '', $value = null, $range = '')\n    {\n        if (is_null($value) && is_string($name)) {\n            return 0 === strpos($name, '?') ? Config::has(substr($name, 1), $range) : Config::get($name, $range);\n        } else {\n            return Config::set($name, $value, $range);\n        }\n    }\n}\n\nif (!function_exists('input')) {\n    /**\n     * 获取输入数据 支持默认值和过滤\n     * @param string    $key 获取的变量名\n     * @param mixed     $default 默认值\n     * @param string    $filter 过滤方法\n     * @return mixed\n     */\n    function input($key = '', $default = null, $filter = '')\n    {\n        if (0 === strpos($key, '?')) {\n            $key = substr($key, 1);\n            $has = true;\n        }\n        if ($pos = strpos($key, '.')) {\n            // 指定参数来源\n            list($method, $key) = explode('.', $key, 2);\n            if (!in_array($method, ['get', 'post', 'put', 'patch', 'delete', 'param', 'request', 'session', 'cookie', 'server', 'env', 'path', 'file'])) {\n                $key    = $method . '.' . $key;\n                $method = 'param';\n            }\n        } else {\n            // 默认为自动判断\n            $method = 'param';\n        }\n        if (isset($has)) {\n            return request()->has($key, $method, $default);\n        } else {\n            return request()->$method($key, $default, $filter);\n        }\n    }\n}\n\nif (!function_exists('widget')) {\n    /**\n     * 渲染输出Widget\n     * @param string    $name Widget名称\n     * @param array     $data 传入的参数\n     * @return mixed\n     */\n    function widget($name, $data = [])\n    {\n        return Loader::action($name, $data, 'widget');\n    }\n}\n\nif (!function_exists('model')) {\n    /**\n     * 实例化Model\n     * @param string    $name Model名称\n     * @param string    $layer 业务层名称\n     * @param bool      $appendSuffix 是否添加类名后缀\n     * @return \\think\\Model\n     */\n    function model($name = '', $layer = 'model', $appendSuffix = false)\n    {\n        return Loader::model($name, $layer, $appendSuffix);\n    }\n}\n\nif (!function_exists('validate')) {\n    /**\n     * 实例化验证器\n     * @param string    $name 验证器名称\n     * @param string    $layer 业务层名称\n     * @param bool      $appendSuffix 是否添加类名后缀\n     * @return \\think\\Validate\n     */\n    function validate($name = '', $layer = 'validate', $appendSuffix = false)\n    {\n        return Loader::validate($name, $layer, $appendSuffix);\n    }\n}\n\nif (!function_exists('db')) {\n    /**\n     * 实例化数据库类\n     * @param string        $name 操作的数据表名称（不含前缀）\n     * @param array|string  $config 数据库配置参数\n     * @param bool          $force 是否强制重新连接\n     * @return \\think\\db\\Query\n     */\n    function db($name = '', $config = [], $force = true)\n    {\n        return Db::connect($config, $force)->name($name);\n    }\n}\n\nif (!function_exists('controller')) {\n    /**\n     * 实例化控制器 格式：[模块/]控制器\n     * @param string    $name 资源地址\n     * @param string    $layer 控制层名称\n     * @param bool      $appendSuffix 是否添加类名后缀\n     * @return \\think\\Controller\n     */\n    function controller($name, $layer = 'controller', $appendSuffix = false)\n    {\n        return Loader::controller($name, $layer, $appendSuffix);\n    }\n}\n\nif (!function_exists('action')) {\n    /**\n     * 调用模块的操作方法 参数格式 [模块/控制器/]操作\n     * @param string        $url 调用地址\n     * @param string|array  $vars 调用参数 支持字符串和数组\n     * @param string        $layer 要调用的控制层名称\n     * @param bool          $appendSuffix 是否添加类名后缀\n     * @return mixed\n     */\n    function action($url, $vars = [], $layer = 'controller', $appendSuffix = false)\n    {\n        return Loader::action($url, $vars, $layer, $appendSuffix);\n    }\n}\n\nif (!function_exists('import')) {\n    /**\n     * 导入所需的类库 同java的Import 本函数有缓存功能\n     * @param string    $class 类库命名空间字符串\n     * @param string    $baseUrl 起始路径\n     * @param string    $ext 导入的文件扩展名\n     * @return boolean\n     */\n    function import($class, $baseUrl = '', $ext = EXT)\n    {\n        return Loader::import($class, $baseUrl, $ext);\n    }\n}\n\nif (!function_exists('vendor')) {\n    /**\n     * 快速导入第三方框架类库 所有第三方框架的类库文件统一放到 系统的Vendor目录下面\n     * @param string    $class 类库\n     * @param string    $ext 类库后缀\n     * @return boolean\n     */\n    function vendor($class, $ext = EXT)\n    {\n        return Loader::import($class, VENDOR_PATH, $ext);\n    }\n}\n\nif (!function_exists('dump')) {\n    /**\n     * 浏览器友好的变量输出\n     * @param mixed     $var 变量\n     * @param boolean   $echo 是否输出 默认为true 如果为false 则返回输出字符串\n     * @param string    $label 标签 默认为空\n     * @return void|string\n     */\n    function dump($var, $echo = true, $label = null)\n    {\n        return Debug::dump($var, $echo, $label);\n    }\n}\n\nif (!function_exists('url')) {\n    /**\n     * Url生成\n     * @param string        $url 路由地址\n     * @param string|array  $vars 变量\n     * @param bool|string   $suffix 生成的URL后缀\n     * @param bool|string   $domain 域名\n     * @return string\n     */\n    function url($url = '', $vars = '', $suffix = true, $domain = false)\n    {\n        return Url::build($url, $vars, $suffix, $domain);\n    }\n}\n\nif (!function_exists('session')) {\n    /**\n     * Session管理\n     * @param string|array  $name session名称，如果为数组表示进行session设置\n     * @param mixed         $value session值\n     * @param string        $prefix 前缀\n     * @return mixed\n     */\n    function session($name, $value = '', $prefix = null)\n    {\n        if (is_array($name)) {\n            // 初始化\n            Session::init($name);\n        } elseif (is_null($name)) {\n            // 清除\n            Session::clear('' === $value ? null : $value);\n        } elseif ('' === $value) {\n            // 判断或获取\n            return 0 === strpos($name, '?') ? Session::has(substr($name, 1), $prefix) : Session::get($name, $prefix);\n        } elseif (is_null($value)) {\n            // 删除\n            return Session::delete($name, $prefix);\n        } else {\n            // 设置\n            return Session::set($name, $value, $prefix);\n        }\n    }\n}\n\nif (!function_exists('cookie')) {\n    /**\n     * Cookie管理\n     * @param string|array  $name cookie名称，如果为数组表示进行cookie设置\n     * @param mixed         $value cookie值\n     * @param mixed         $option 参数\n     * @return mixed\n     */\n    function cookie($name, $value = '', $option = null)\n    {\n        if (is_array($name)) {\n            // 初始化\n            Cookie::init($name);\n        } elseif (is_null($name)) {\n            // 清除\n            Cookie::clear($value);\n        } elseif ('' === $value) {\n            // 获取\n            return 0 === strpos($name, '?') ? Cookie::has(substr($name, 1), $option) : Cookie::get($name, $option);\n        } elseif (is_null($value)) {\n            // 删除\n            return Cookie::delete($name);\n        } else {\n            // 设置\n            return Cookie::set($name, $value, $option);\n        }\n    }\n}\n\nif (!function_exists('cache')) {\n    /**\n     * 缓存管理\n     * @param mixed     $name 缓存名称，如果为数组表示进行缓存设置\n     * @param mixed     $value 缓存值\n     * @param mixed     $options 缓存参数\n     * @param string    $tag 缓存标签\n     * @return mixed\n     */\n    function cache($name, $value = '', $options = null, $tag = null)\n    {\n        if (is_array($options)) {\n            // 缓存操作的同时初始化\n            $cache = Cache::connect($options);\n        } elseif (is_array($name)) {\n            // 缓存初始化\n            return Cache::connect($name);\n        } else {\n            $cache = Cache::init();\n        }\n\n        if (is_null($name)) {\n            return $cache->clear($value);\n        } elseif ('' === $value) {\n            // 获取缓存\n            return 0 === strpos($name, '?') ? $cache->has(substr($name, 1)) : $cache->get($name);\n        } elseif (is_null($value)) {\n            // 删除缓存\n            return $cache->rm($name);\n        } elseif (0 === strpos($name, '?') && '' !== $value) {\n            $expire = is_numeric($options) ? $options : null;\n            return $cache->remember(substr($name, 1), $value, $expire);\n        } else {\n            // 缓存数据\n            if (is_array($options)) {\n                $expire = isset($options['expire']) ? $options['expire'] : null; //修复查询缓存无法设置过期时间\n            } else {\n                $expire = is_numeric($options) ? $options : null; //默认快捷缓存设置过期时间\n            }\n            if (is_null($tag)) {\n                return $cache->set($name, $value, $expire);\n            } else {\n                return $cache->tag($tag)->set($name, $value, $expire);\n            }\n        }\n    }\n}\n\nif (!function_exists('trace')) {\n    /**\n     * 记录日志信息\n     * @param mixed     $log log信息 支持字符串和数组\n     * @param string    $level 日志级别\n     * @return void|array\n     */\n    function trace($log = '[think]', $level = 'log')\n    {\n        if ('[think]' === $log) {\n            return Log::getLog();\n        } else {\n            Log::record($log, $level);\n        }\n    }\n}\n\nif (!function_exists('request')) {\n    /**\n     * 获取当前Request对象实例\n     * @return Request\n     */\n    function request()\n    {\n        return Request::instance();\n    }\n}\n\nif (!function_exists('response')) {\n    /**\n     * 创建普通 Response 对象实例\n     * @param mixed      $data   输出数据\n     * @param int|string $code   状态码\n     * @param array      $header 头信息\n     * @param string     $type\n     * @return Response\n     */\n    function response($data = [], $code = 200, $header = [], $type = 'html')\n    {\n        return Response::create($data, $type, $code, $header);\n    }\n}\n\nif (!function_exists('view')) {\n    /**\n     * 渲染模板输出\n     * @param string    $template 模板文件\n     * @param array     $vars 模板变量\n     * @param array     $replace 模板替换\n     * @param integer   $code 状态码\n     * @return \\think\\response\\View\n     */\n    function view($template = '', $vars = [], $replace = [], $code = 200)\n    {\n        return Response::create($template, 'view', $code)->replace($replace)->assign($vars);\n    }\n}\n\nif (!function_exists('json')) {\n    /**\n     * 获取\\think\\response\\Json对象实例\n     * @param mixed   $data 返回的数据\n     * @param integer $code 状态码\n     * @param array   $header 头部\n     * @param array   $options 参数\n     * @return \\think\\response\\Json\n     */\n    function json($data = [], $code = 200, $header = [], $options = [])\n    {\n        return Response::create($data, 'json', $code, $header, $options);\n    }\n}\n\nif (!function_exists('jsonp')) {\n    /**\n     * 获取\\think\\response\\Jsonp对象实例\n     * @param mixed   $data    返回的数据\n     * @param integer $code    状态码\n     * @param array   $header 头部\n     * @param array   $options 参数\n     * @return \\think\\response\\Jsonp\n     */\n    function jsonp($data = [], $code = 200, $header = [], $options = [])\n    {\n        return Response::create($data, 'jsonp', $code, $header, $options);\n    }\n}\n\nif (!function_exists('xml')) {\n    /**\n     * 获取\\think\\response\\Xml对象实例\n     * @param mixed   $data    返回的数据\n     * @param integer $code    状态码\n     * @param array   $header  头部\n     * @param array   $options 参数\n     * @return \\think\\response\\Xml\n     */\n    function xml($data = [], $code = 200, $header = [], $options = [])\n    {\n        return Response::create($data, 'xml', $code, $header, $options);\n    }\n}\n\nif (!function_exists('redirect')) {\n    /**\n     * 获取\\think\\response\\Redirect对象实例\n     * @param mixed         $url 重定向地址 支持Url::build方法的地址\n     * @param array|integer $params 额外参数\n     * @param integer       $code 状态码\n     * @param array         $with 隐式传参\n     * @return \\think\\response\\Redirect\n     */\n    function redirect($url = [], $params = [], $code = 302, $with = [])\n    {\n        if (is_integer($params)) {\n            $code   = $params;\n            $params = [];\n        }\n        return Response::create($url, 'redirect', $code)->params($params)->with($with);\n    }\n}\n\nif (!function_exists('abort')) {\n    /**\n     * 抛出HTTP异常\n     * @param integer|Response      $code 状态码 或者 Response对象实例\n     * @param string                $message 错误信息\n     * @param array                 $header 参数\n     */\n    function abort($code, $message = null, $header = [])\n    {\n        if ($code instanceof Response) {\n            throw new HttpResponseException($code);\n        } else {\n            throw new HttpException($code, $message, null, $header);\n        }\n    }\n}\n\nif (!function_exists('halt')) {\n    /**\n     * 调试变量并且中断输出\n     * @param mixed      $var 调试变量或者信息\n     */\n    function halt($var)\n    {\n        dump($var);\n        throw new HttpResponseException(new Response);\n    }\n}\n\nif (!function_exists('token')) {\n    /**\n     * 生成表单令牌\n     * @param string $name 令牌名称\n     * @param mixed  $type 令牌生成方法\n     * @return string\n     */\n    function token($name = '__token__', $type = 'md5')\n    {\n        $token = Request::instance()->token($name, $type);\n        return '<input type=\"hidden\" name=\"' . $name . '\" value=\"' . $token . '\" />';\n    }\n}\n\nif (!function_exists('load_relation')) {\n    /**\n     * 延迟预载入关联查询\n     * @param mixed $resultSet 数据集\n     * @param mixed $relation 关联\n     * @return array\n     */\n    function load_relation($resultSet, $relation)\n    {\n        $item = current($resultSet);\n        if ($item instanceof Model) {\n            $item->eagerlyResultSet($resultSet, $relation);\n        }\n        return $resultSet;\n    }\n}\n\nif (!function_exists('collection')) {\n    /**\n     * 数组转换为数据集对象\n     * @param array $resultSet 数据集数组\n     * @return \\think\\model\\Collection|\\think\\Collection\n     */\n    function collection($resultSet)\n    {\n        $item = current($resultSet);\n        if ($item instanceof Model) {\n            return \\think\\model\\Collection::make($resultSet);\n        } else {\n            return \\think\\Collection::make($resultSet);\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/lang/zh-cn.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\n// 核心中文语言包\nreturn [\n    // 系统错误提示\n    'Undefined variable'        => '未定义变量',\n    'Undefined index'           => '未定义数组索引',\n    'Undefined offset'          => '未定义数组下标',\n    'Parse error'               => '语法解析错误',\n    'Type error'                => '类型错误',\n    'Fatal error'               => '致命错误',\n    'syntax error'              => '语法错误',\n\n    // 框架核心错误提示\n    'dispatch type not support' => '不支持的调度类型',\n    'method param miss'         => '方法参数错误',\n    'method not exists'         => '方法不存在',\n    'module not exists'         => '模块不存在',\n    'controller not exists'     => '控制器不存在',\n    'class not exists'          => '类不存在',\n    'property not exists'       => '类的属性不存在',\n    'template not exists'       => '模板文件不存在',\n    'illegal controller name'   => '非法的控制器名称',\n    'illegal action name'       => '非法的操作名称',\n    'url suffix deny'           => '禁止的URL后缀访问',\n    'Route Not Found'           => '当前访问路由未定义',\n    'Underfined db type'        => '未定义数据库类型',\n    'variable type error'       => '变量类型错误',\n    'PSR-4 error'               => 'PSR-4 规范错误',\n    'not support total'         => '简洁模式下不能获取数据总数',\n    'not support last'          => '简洁模式下不能获取最后一页',\n    'error session handler'     => '错误的SESSION处理器类',\n    'not allow php tag'         => '模板不允许使用PHP语法',\n    'not support'               => '不支持',\n    'redisd master'             => 'Redisd 主服务器错误',\n    'redisd slave'              => 'Redisd 从服务器错误',\n    'must run at sae'           => '必须在SAE运行',\n    'memcache init error'       => '未开通Memcache服务，请在SAE管理平台初始化Memcache服务',\n    'KVDB init error'           => '没有初始化KVDB，请在SAE管理平台初始化KVDB服务',\n    'fields not exists'         => '数据表字段不存在',\n    'where express error'       => '查询表达式错误',\n    'no data to update'         => '没有任何数据需要更新',\n    'miss data to insert'       => '缺少需要写入的数据',\n    'miss complex primary data' => '缺少复合主键数据',\n    'miss update condition'     => '缺少更新条件',\n    'model data Not Found'      => '模型数据不存在',\n    'table data not Found'      => '表数据不存在',\n    'delete without condition'  => '没有条件不会执行删除操作',\n    'miss relation data'        => '缺少关联表数据',\n    'tag attr must'             => '模板标签属性必须',\n    'tag error'                 => '模板标签错误',\n    'cache write error'         => '缓存写入失败',\n    'sae mc write error'        => 'SAE mc 写入错误',\n    'route name not exists'     => '路由标识不存在（或参数不够）',\n    'invalid request'           => '非法请求',\n    'bind attr has exists'      => '模型的属性已经存在',\n    'relation data not exists'  => '关联数据不存在',\n    'relation not support'      => '关联不支持',\n];\n"
  },
  {
    "path": "thinkphp/library/think/App.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\exception\\HttpException;\nuse think\\exception\\HttpResponseException;\nuse think\\exception\\RouteNotFoundException;\n\n/**\n * App 应用管理\n * @author  liu21st <liu21st@gmail.com>\n */\nclass App\n{\n    /**\n     * @var bool 是否初始化过\n     */\n    protected static $init = false;\n\n    /**\n     * @var string 当前模块路径\n     */\n    public static $modulePath;\n\n    /**\n     * @var bool 应用调试模式\n     */\n    public static $debug = true;\n\n    /**\n     * @var string 应用类库命名空间\n     */\n    public static $namespace = 'app';\n\n    /**\n     * @var bool 应用类库后缀\n     */\n    public static $suffix = false;\n\n    /**\n     * @var bool 应用路由检测\n     */\n    protected static $routeCheck;\n\n    /**\n     * @var bool 严格路由检测\n     */\n    protected static $routeMust;\n\n    protected static $dispatch;\n    protected static $file = [];\n\n    /**\n     * 执行应用程序\n     * @access public\n     * @param Request $request Request对象\n     * @return Response\n     * @throws Exception\n     */\n    public static function run(Request $request = null)\n    {\n        is_null($request) && $request = Request::instance();\n\n        try {\n            $config = self::initCommon();\n            if (defined('BIND_MODULE')) {\n                // 模块/控制器绑定\n                BIND_MODULE && Route::bind(BIND_MODULE);\n            } elseif ($config['auto_bind_module']) {\n                // 入口自动绑定\n                $name = pathinfo($request->baseFile(), PATHINFO_FILENAME);\n                if ($name && 'index' != $name && is_dir(APP_PATH . $name)) {\n                    Route::bind($name);\n                }\n            }\n\n            $request->filter($config['default_filter']);\n\n            // 默认语言\n            Lang::range($config['default_lang']);\n            if ($config['lang_switch_on']) {\n                // 开启多语言机制 检测当前语言\n                Lang::detect();\n            }\n            $request->langset(Lang::range());\n\n            // 加载系统语言包\n            Lang::load([\n                THINK_PATH . 'lang' . DS . $request->langset() . EXT,\n                APP_PATH . 'lang' . DS . $request->langset() . EXT,\n            ]);\n\n            // 获取应用调度信息\n            $dispatch = self::$dispatch;\n            if (empty($dispatch)) {\n                // 进行URL路由检测\n                $dispatch = self::routeCheck($request, $config);\n            }\n            // 记录当前调度信息\n            $request->dispatch($dispatch);\n\n            // 记录路由和请求信息\n            if (self::$debug) {\n                Log::record('[ ROUTE ] ' . var_export($dispatch, true), 'info');\n                Log::record('[ HEADER ] ' . var_export($request->header(), true), 'info');\n                Log::record('[ PARAM ] ' . var_export($request->param(), true), 'info');\n            }\n\n            // 监听app_begin\n            Hook::listen('app_begin', $dispatch);\n            // 请求缓存检查\n            $request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']);\n\n            $data = self::exec($dispatch, $config);\n        } catch (HttpResponseException $exception) {\n            $data = $exception->getResponse();\n        }\n\n        // 清空类的实例化\n        Loader::clearInstance();\n\n        // 输出数据到客户端\n        if ($data instanceof Response) {\n            $response = $data;\n        } elseif (!is_null($data)) {\n            // 默认自动识别响应输出类型\n            $isAjax   = $request->isAjax();\n            $type     = $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type');\n            $response = Response::create($data, $type);\n        } else {\n            $response = Response::create();\n        }\n\n        // 监听app_end\n        Hook::listen('app_end', $response);\n\n        return $response;\n    }\n\n    /**\n     * 设置当前请求的调度信息\n     * @access public\n     * @param array|string  $dispatch 调度信息\n     * @param string        $type 调度类型\n     * @return void\n     */\n    public static function dispatch($dispatch, $type = 'module')\n    {\n        self::$dispatch = ['type' => $type, $type => $dispatch];\n    }\n\n    /**\n     * 执行函数或者闭包方法 支持参数调用\n     * @access public\n     * @param string|array|\\Closure $function 函数或者闭包\n     * @param array                 $vars     变量\n     * @return mixed\n     */\n    public static function invokeFunction($function, $vars = [])\n    {\n        $reflect = new \\ReflectionFunction($function);\n        $args    = self::bindParams($reflect, $vars);\n        // 记录执行信息\n        self::$debug && Log::record('[ RUN ] ' . $reflect->__toString(), 'info');\n        return $reflect->invokeArgs($args);\n    }\n\n    /**\n     * 调用反射执行类的方法 支持参数绑定\n     * @access public\n     * @param string|array $method 方法\n     * @param array        $vars   变量\n     * @return mixed\n     */\n    public static function invokeMethod($method, $vars = [])\n    {\n        if (is_array($method)) {\n            $class   = is_object($method[0]) ? $method[0] : self::invokeClass($method[0]);\n            $reflect = new \\ReflectionMethod($class, $method[1]);\n        } else {\n            // 静态方法\n            $reflect = new \\ReflectionMethod($method);\n        }\n        $args = self::bindParams($reflect, $vars);\n\n        self::$debug && Log::record('[ RUN ] ' . $reflect->class . '->' . $reflect->name . '[ ' . $reflect->getFileName() . ' ]', 'info');\n        return $reflect->invokeArgs(isset($class) ? $class : null, $args);\n    }\n\n    /**\n     * 调用反射执行类的实例化 支持依赖注入\n     * @access public\n     * @param string    $class 类名\n     * @param array     $vars  变量\n     * @return mixed\n     */\n    public static function invokeClass($class, $vars = [])\n    {\n        $reflect     = new \\ReflectionClass($class);\n        $constructor = $reflect->getConstructor();\n        if ($constructor) {\n            $args = self::bindParams($constructor, $vars);\n        } else {\n            $args = [];\n        }\n        return $reflect->newInstanceArgs($args);\n    }\n\n    /**\n     * 绑定参数\n     * @access private\n     * @param \\ReflectionMethod|\\ReflectionFunction $reflect 反射类\n     * @param array                                 $vars    变量\n     * @return array\n     */\n    private static function bindParams($reflect, $vars = [])\n    {\n        if (empty($vars)) {\n            // 自动获取请求变量\n            if (Config::get('url_param_type')) {\n                $vars = Request::instance()->route();\n            } else {\n                $vars = Request::instance()->param();\n            }\n        }\n        $args = [];\n        if ($reflect->getNumberOfParameters() > 0) {\n            // 判断数组类型 数字数组时按顺序绑定参数\n            reset($vars);\n            $type   = key($vars) === 0 ? 1 : 0;\n            $params = $reflect->getParameters();\n            foreach ($params as $param) {\n                $args[] = self::getParamValue($param, $vars, $type);\n            }\n        }\n        return $args;\n    }\n\n    /**\n     * 获取参数值\n     * @access private\n     * @param \\ReflectionParameter  $param\n     * @param array                 $vars    变量\n     * @param string                $type\n     * @return array\n     */\n    private static function getParamValue($param, &$vars, $type)\n    {\n        $name  = $param->getName();\n        $class = $param->getClass();\n        if ($class) {\n            $className = $class->getName();\n            $bind      = Request::instance()->$name;\n            if ($bind instanceof $className) {\n                $result = $bind;\n            } else {\n                if (method_exists($className, 'invoke')) {\n                    $method = new \\ReflectionMethod($className, 'invoke');\n                    if ($method->isPublic() && $method->isStatic()) {\n                        return $className::invoke(Request::instance());\n                    }\n                }\n                $result = method_exists($className, 'instance') ? $className::instance() : new $className;\n            }\n        } elseif (1 == $type && !empty($vars)) {\n            $result = array_shift($vars);\n        } elseif (0 == $type && isset($vars[$name])) {\n            $result = $vars[$name];\n        } elseif ($param->isDefaultValueAvailable()) {\n            $result = $param->getDefaultValue();\n        } else {\n            throw new \\InvalidArgumentException('method param miss:' . $name);\n        }\n        return $result;\n    }\n\n    protected static function exec($dispatch, $config)\n    {\n        switch ($dispatch['type']) {\n            case 'redirect':\n                // 执行重定向跳转\n                $data = Response::create($dispatch['url'], 'redirect')->code($dispatch['status']);\n                break;\n            case 'module':\n                // 模块/控制器/操作\n                $data = self::module($dispatch['module'], $config, isset($dispatch['convert']) ? $dispatch['convert'] : null);\n                break;\n            case 'controller':\n                // 执行控制器操作\n                $vars = array_merge(Request::instance()->param(), $dispatch['var']);\n                $data = Loader::action($dispatch['controller'], $vars, $config['url_controller_layer'], $config['controller_suffix']);\n                break;\n            case 'method':\n                // 执行回调方法\n                $vars = array_merge(Request::instance()->param(), $dispatch['var']);\n                $data = self::invokeMethod($dispatch['method'], $vars);\n                break;\n            case 'function':\n                // 执行闭包\n                $data = self::invokeFunction($dispatch['function']);\n                break;\n            case 'response':\n                $data = $dispatch['response'];\n                break;\n            default:\n                throw new \\InvalidArgumentException('dispatch type not support');\n        }\n        return $data;\n    }\n\n    /**\n     * 执行模块\n     * @access public\n     * @param array $result 模块/控制器/操作\n     * @param array $config 配置参数\n     * @param bool  $convert 是否自动转换控制器和操作名\n     * @return mixed\n     */\n    public static function module($result, $config, $convert = null)\n    {\n        if (is_string($result)) {\n            $result = explode('/', $result);\n        }\n        $request = Request::instance();\n        if ($config['app_multi_module']) {\n            // 多模块部署\n            $module    = strip_tags(strtolower($result[0] ?: $config['default_module']));\n            $bind      = Route::getBind('module');\n            $available = false;\n            if ($bind) {\n                // 绑定模块\n                list($bindModule) = explode('/', $bind);\n                if (empty($result[0])) {\n                    $module    = $bindModule;\n                    $available = true;\n                } elseif ($module == $bindModule) {\n                    $available = true;\n                }\n            } elseif (!in_array($module, $config['deny_module_list']) && is_dir(APP_PATH . $module)) {\n                $available = true;\n            }\n\n            // 模块初始化\n            if ($module && $available) {\n                // 初始化模块\n                $request->module($module);\n                $config = self::init($module);\n                // 模块请求缓存检查\n                $request->cache($config['request_cache'], $config['request_cache_expire'], $config['request_cache_except']);\n            } else {\n                throw new HttpException(404, 'module not exists:' . $module);\n            }\n        } else {\n            // 单一模块部署\n            $module = '';\n            $request->module($module);\n        }\n        // 当前模块路径\n        App::$modulePath = APP_PATH . ($module ? $module . DS : '');\n\n        // 是否自动转换控制器和操作名\n        $convert = is_bool($convert) ? $convert : $config['url_convert'];\n        // 获取控制器名\n        $controller = strip_tags($result[1] ?: $config['default_controller']);\n        $controller = $convert ? strtolower($controller) : $controller;\n\n        // 获取操作名\n        $actionName = strip_tags($result[2] ?: $config['default_action']);\n        $actionName = $convert ? strtolower($actionName) : $actionName;\n\n        // 设置当前请求的控制器、操作\n        $request->controller(Loader::parseName($controller, 1))->action($actionName);\n\n        // 监听module_init\n        Hook::listen('module_init', $request);\n\n        $instance = Loader::controller($controller, $config['url_controller_layer'], $config['controller_suffix'], $config['empty_controller']);\n        if (is_null($instance)) {\n            throw new HttpException(404, 'controller not exists:' . Loader::parseName($controller, 1));\n        }\n        // 获取当前操作名\n        $action = $actionName . $config['action_suffix'];\n\n        $vars = [];\n        if (is_callable([$instance, $action])) {\n            // 执行操作方法\n            $call = [$instance, $action];\n        } elseif (is_callable([$instance, '_empty'])) {\n            // 空操作\n            $call = [$instance, '_empty'];\n            $vars = [$actionName];\n        } else {\n            // 操作不存在\n            throw new HttpException(404, 'method not exists:' . get_class($instance) . '->' . $action . '()');\n        }\n\n        Hook::listen('action_begin', $call);\n\n        return self::invokeMethod($call, $vars);\n    }\n\n    /**\n     * 初始化应用\n     */\n    public static function initCommon()\n    {\n        if (empty(self::$init)) {\n            if (defined('APP_NAMESPACE')) {\n                self::$namespace = APP_NAMESPACE;\n            }\n            Loader::addNamespace(self::$namespace, APP_PATH);\n\n            // 初始化应用\n            $config       = self::init();\n            self::$suffix = $config['class_suffix'];\n\n            // 应用调试模式\n            self::$debug = Env::get('app_debug', Config::get('app_debug'));\n            if (!self::$debug) {\n                ini_set('display_errors', 'Off');\n            } elseif (!IS_CLI) {\n                //重新申请一块比较大的buffer\n                if (ob_get_level() > 0) {\n                    $output = ob_get_clean();\n                }\n                ob_start();\n                if (!empty($output)) {\n                    echo $output;\n                }\n            }\n\n            if (!empty($config['root_namespace'])) {\n                Loader::addNamespace($config['root_namespace']);\n            }\n\n            // 加载额外文件\n            if (!empty($config['extra_file_list'])) {\n                foreach ($config['extra_file_list'] as $file) {\n                    $file = strpos($file, '.') ? $file : APP_PATH . $file . EXT;\n                    if (is_file($file) && !isset(self::$file[$file])) {\n                        include $file;\n                        self::$file[$file] = true;\n                    }\n                }\n            }\n\n            // 设置系统时区\n            date_default_timezone_set($config['default_timezone']);\n\n            // 监听app_init\n            Hook::listen('app_init');\n\n            self::$init = true;\n        }\n        return Config::get();\n    }\n\n    /**\n     * 初始化应用或模块\n     * @access public\n     * @param string $module 模块名\n     * @return array\n     */\n    private static function init($module = '')\n    {\n        // 定位模块目录\n        $module = $module ? $module . DS : '';\n\n        // 加载初始化文件\n        if (is_file(APP_PATH . $module . 'init' . EXT)) {\n            include APP_PATH . $module . 'init' . EXT;\n        } elseif (is_file(RUNTIME_PATH . $module . 'init' . EXT)) {\n            include RUNTIME_PATH . $module . 'init' . EXT;\n        } else {\n            $path = APP_PATH . $module;\n            // 加载模块配置\n            $config = Config::load(CONF_PATH . $module . 'config' . CONF_EXT);\n            // 读取数据库配置文件\n            $filename = CONF_PATH . $module . 'database' . CONF_EXT;\n            Config::load($filename, 'database');\n            // 读取扩展配置文件\n            if (is_dir(CONF_PATH . $module . 'extra')) {\n                $dir   = CONF_PATH . $module . 'extra';\n                $files = scandir($dir);\n                foreach ($files as $file) {\n                    if (strpos($file, CONF_EXT)) {\n                        $filename = $dir . DS . $file;\n                        Config::load($filename, pathinfo($file, PATHINFO_FILENAME));\n                    }\n                }\n            }\n\n            // 加载应用状态配置\n            if ($config['app_status']) {\n                $config = Config::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT);\n            }\n\n            // 加载行为扩展文件\n            if (is_file(CONF_PATH . $module . 'tags' . EXT)) {\n                Hook::import(include CONF_PATH . $module . 'tags' . EXT);\n            }\n\n            // 加载公共文件\n            if (is_file($path . 'common' . EXT)) {\n                include $path . 'common' . EXT;\n            }\n\n            // 加载当前模块语言包\n            if ($module) {\n                Lang::load($path . 'lang' . DS . Request::instance()->langset() . EXT);\n            }\n        }\n        return Config::get();\n    }\n\n    /**\n     * URL路由检测（根据PATH_INFO)\n     * @access public\n     * @param  \\think\\Request $request\n     * @param  array          $config\n     * @return array\n     * @throws \\think\\Exception\n     */\n    public static function routeCheck($request, array $config)\n    {\n        $path   = $request->path();\n        $depr   = $config['pathinfo_depr'];\n        $result = false;\n        // 路由检测\n        $check = !is_null(self::$routeCheck) ? self::$routeCheck : $config['url_route_on'];\n        if ($check) {\n            // 开启路由\n            if (is_file(RUNTIME_PATH . 'route.php')) {\n                // 读取路由缓存\n                $rules = include RUNTIME_PATH . 'route.php';\n                if (is_array($rules)) {\n                    Route::rules($rules);\n                }\n            } else {\n                $files = $config['route_config_file'];\n                foreach ($files as $file) {\n                    if (is_file(CONF_PATH . $file . CONF_EXT)) {\n                        // 导入路由配置\n                        $rules = include CONF_PATH . $file . CONF_EXT;\n                        if (is_array($rules)) {\n                            Route::import($rules);\n                        }\n                    }\n                }\n            }\n\n            // 路由检测（根据路由定义返回不同的URL调度）\n            $result = Route::check($request, $path, $depr, $config['url_domain_deploy']);\n            $must   = !is_null(self::$routeMust) ? self::$routeMust : $config['url_route_must'];\n            if ($must && false === $result) {\n                // 路由无效\n                throw new RouteNotFoundException();\n            }\n        }\n        if (false === $result) {\n            // 路由无效 解析模块/控制器/操作/参数... 支持控制器自动搜索\n            $result = Route::parseUrl($path, $depr, $config['controller_auto_search']);\n        }\n        return $result;\n    }\n\n    /**\n     * 设置应用的路由检测机制\n     * @access public\n     * @param  bool $route 是否需要检测路由\n     * @param  bool $must  是否强制检测路由\n     * @return void\n     */\n    public static function route($route, $must = false)\n    {\n        self::$routeCheck = $route;\n        self::$routeMust  = $must;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Build.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nclass Build\n{\n    /**\n     * 根据传入的build资料创建目录和文件\n     * @access protected\n     * @param  array  $build build列表\n     * @param  string $namespace 应用类库命名空间\n     * @param  bool   $suffix 类库后缀\n     * @return void\n     */\n    public static function run(array $build = [], $namespace = 'app', $suffix = false)\n    {\n        // 锁定\n        $lockfile = APP_PATH . 'build.lock';\n        if (is_writable($lockfile)) {\n            return;\n        } elseif (!touch($lockfile)) {\n            throw new Exception('应用目录[' . APP_PATH . ']不可写，目录无法自动生成！<BR>请手动生成项目目录~', 10006);\n        }\n        foreach ($build as $module => $list) {\n            if ('__dir__' == $module) {\n                // 创建目录列表\n                self::buildDir($list);\n            } elseif ('__file__' == $module) {\n                // 创建文件列表\n                self::buildFile($list);\n            } else {\n                // 创建模块\n                self::module($module, $list, $namespace, $suffix);\n            }\n        }\n        // 解除锁定\n        unlink($lockfile);\n    }\n\n    /**\n     * 创建目录\n     * @access protected\n     * @param  array $list 目录列表\n     * @return void\n     */\n    protected static function buildDir($list)\n    {\n        foreach ($list as $dir) {\n            if (!is_dir(APP_PATH . $dir)) {\n                // 创建目录\n                mkdir(APP_PATH . $dir, 0755, true);\n            }\n        }\n    }\n\n    /**\n     * 创建文件\n     * @access protected\n     * @param  array $list 文件列表\n     * @return void\n     */\n    protected static function buildFile($list)\n    {\n        foreach ($list as $file) {\n            if (!is_dir(APP_PATH . dirname($file))) {\n                // 创建目录\n                mkdir(APP_PATH . dirname($file), 0755, true);\n            }\n            if (!is_file(APP_PATH . $file)) {\n                file_put_contents(APP_PATH . $file, 'php' == pathinfo($file, PATHINFO_EXTENSION) ? \"<?php\\n\" : '');\n            }\n        }\n    }\n\n    /**\n     * 创建模块\n     * @access public\n     * @param  string $module 模块名\n     * @param  array  $list build列表\n     * @param  string $namespace 应用类库命名空间\n     * @param  bool   $suffix 类库后缀\n     * @return void\n     */\n    public static function module($module = '', $list = [], $namespace = 'app', $suffix = false)\n    {\n        $module = $module ? $module : '';\n        if (!is_dir(APP_PATH . $module)) {\n            // 创建模块目录\n            mkdir(APP_PATH . $module);\n        }\n        if (basename(RUNTIME_PATH) != $module) {\n            // 创建配置文件和公共文件\n            self::buildCommon($module);\n            // 创建模块的默认页面\n            self::buildHello($module, $namespace, $suffix);\n        }\n        if (empty($list)) {\n            // 创建默认的模块目录和文件\n            $list = [\n                '__file__' => ['config.php', 'common.php'],\n                '__dir__'  => ['controller', 'model', 'view'],\n            ];\n        }\n        // 创建子目录和文件\n        foreach ($list as $path => $file) {\n            $modulePath = APP_PATH . $module . DS;\n            if ('__dir__' == $path) {\n                // 生成子目录\n                foreach ($file as $dir) {\n                    if (!is_dir($modulePath . $dir)) {\n                        // 创建目录\n                        mkdir($modulePath . $dir, 0755, true);\n                    }\n                }\n            } elseif ('__file__' == $path) {\n                // 生成（空白）文件\n                foreach ($file as $name) {\n                    if (!is_file($modulePath . $name)) {\n                        file_put_contents($modulePath . $name, 'php' == pathinfo($name, PATHINFO_EXTENSION) ? \"<?php\\n\" : '');\n                    }\n                }\n            } else {\n                // 生成相关MVC文件\n                foreach ($file as $val) {\n                    $val      = trim($val);\n                    $filename = $modulePath . $path . DS . $val . ($suffix ? ucfirst($path) : '') . EXT;\n                    $space    = $namespace . '\\\\' . ($module ? $module . '\\\\' : '') . $path;\n                    $class    = $val . ($suffix ? ucfirst($path) : '');\n                    switch ($path) {\n                        case 'controller': // 控制器\n                            $content = \"<?php\\nnamespace {$space};\\n\\nclass {$class}\\n{\\n\\n}\";\n                            break;\n                        case 'model': // 模型\n                            $content = \"<?php\\nnamespace {$space};\\n\\nuse think\\Model;\\n\\nclass {$class} extends Model\\n{\\n\\n}\";\n                            break;\n                        case 'view': // 视图\n                            $filename = $modulePath . $path . DS . $val . '.html';\n                            if (!is_dir(dirname($filename))) {\n                                // 创建目录\n                                mkdir(dirname($filename), 0755, true);\n                            }\n                            $content = '';\n                            break;\n                        default:\n                            // 其他文件\n                            $content = \"<?php\\nnamespace {$space};\\n\\nclass {$class}\\n{\\n\\n}\";\n                    }\n\n                    if (!is_file($filename)) {\n                        file_put_contents($filename, $content);\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * 创建模块的欢迎页面\n     * @access public\n     * @param  string $module 模块名\n     * @param  string $namespace 应用类库命名空间\n     * @param  bool   $suffix 类库后缀\n     * @return void\n     */\n    protected static function buildHello($module, $namespace, $suffix = false)\n    {\n        $filename = APP_PATH . ($module ? $module . DS : '') . 'controller' . DS . 'Index' . ($suffix ? 'Controller' : '') . EXT;\n        if (!is_file($filename)) {\n            $content = file_get_contents(THINK_PATH . 'tpl' . DS . 'default_index.tpl');\n            $content = str_replace(['{$app}', '{$module}', '{layer}', '{$suffix}'], [$namespace, $module ? $module . '\\\\' : '', 'controller', $suffix ? 'Controller' : ''], $content);\n            if (!is_dir(dirname($filename))) {\n                mkdir(dirname($filename), 0755, true);\n            }\n            file_put_contents($filename, $content);\n        }\n    }\n\n    /**\n     * 创建模块的公共文件\n     * @access public\n     * @param  string $module 模块名\n     * @return void\n     */\n    protected static function buildCommon($module)\n    {\n        $filename = CONF_PATH . ($module ? $module . DS : '') . 'config.php';\n        if (!is_file($filename)) {\n            file_put_contents($filename, \"<?php\\n//配置文件\\nreturn [\\n\\n];\");\n        }\n        $filename = APP_PATH . ($module ? $module . DS : '') . 'common.php';\n        if (!is_file($filename)) {\n            file_put_contents($filename, \"<?php\\n\");\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Cache.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\cache\\Driver;\n\nclass Cache\n{\n    protected static $instance = [];\n    public static $readTimes   = 0;\n    public static $writeTimes  = 0;\n\n    /**\n     * 操作句柄\n     * @var object\n     * @access protected\n     */\n    protected static $handler;\n\n    /**\n     * 连接缓存\n     * @access public\n     * @param array         $options  配置数组\n     * @param bool|string   $name 缓存连接标识 true 强制重新连接\n     * @return Driver\n     */\n    public static function connect(array $options = [], $name = false)\n    {\n        $type = !empty($options['type']) ? $options['type'] : 'File';\n        if (false === $name) {\n            $name = md5(serialize($options));\n        }\n\n        if (true === $name || !isset(self::$instance[$name])) {\n            $class = false !== strpos($type, '\\\\') ? $type : '\\\\think\\\\cache\\\\driver\\\\' . ucwords($type);\n\n            // 记录初始化信息\n            App::$debug && Log::record('[ CACHE ] INIT ' . $type, 'info');\n            if (true === $name) {\n                return new $class($options);\n            } else {\n                self::$instance[$name] = new $class($options);\n            }\n        }\n        return self::$instance[$name];\n    }\n\n    /**\n     * 自动初始化缓存\n     * @access public\n     * @param array         $options  配置数组\n     * @return Driver\n     */\n    public static function init(array $options = [])\n    {\n        if (is_null(self::$handler)) {\n            // 自动初始化缓存\n            if (!empty($options)) {\n                $connect = self::connect($options);\n            } elseif ('complex' == Config::get('cache.type')) {\n                $connect = self::connect(Config::get('cache.default'));\n            } else {\n                $connect = self::connect(Config::get('cache'));\n            }\n            self::$handler = $connect;\n        }\n        return self::$handler;\n    }\n\n    /**\n     * 切换缓存类型 需要配置 cache.type 为 complex\n     * @access public\n     * @param string $name 缓存标识\n     * @return Driver\n     */\n    public static function store($name = '')\n    {\n        if ('' !== $name && 'complex' == Config::get('cache.type')) {\n            return self::connect(Config::get('cache.' . $name), strtolower($name));\n        }\n        return self::init();\n    }\n\n    /**\n     * 判断缓存是否存在\n     * @access public\n     * @param string $name 缓存变量名\n     * @return bool\n     */\n    public static function has($name)\n    {\n        self::$readTimes++;\n        return self::init()->has($name);\n    }\n\n    /**\n     * 读取缓存\n     * @access public\n     * @param string $name 缓存标识\n     * @param mixed  $default 默认值\n     * @return mixed\n     */\n    public static function get($name, $default = false)\n    {\n        self::$readTimes++;\n        return self::init()->get($name, $default);\n    }\n\n    /**\n     * 写入缓存\n     * @access public\n     * @param string        $name 缓存标识\n     * @param mixed         $value  存储数据\n     * @param int|null      $expire  有效时间 0为永久\n     * @return boolean\n     */\n    public static function set($name, $value, $expire = null)\n    {\n        self::$writeTimes++;\n        return self::init()->set($name, $value, $expire);\n    }\n\n    /**\n     * 自增缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public static function inc($name, $step = 1)\n    {\n        self::$writeTimes++;\n        return self::init()->inc($name, $step);\n    }\n\n    /**\n     * 自减缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public static function dec($name, $step = 1)\n    {\n        self::$writeTimes++;\n        return self::init()->dec($name, $step);\n    }\n\n    /**\n     * 删除缓存\n     * @access public\n     * @param string    $name 缓存标识\n     * @return boolean\n     */\n    public static function rm($name)\n    {\n        self::$writeTimes++;\n        return self::init()->rm($name);\n    }\n\n    /**\n     * 清除缓存\n     * @access public\n     * @param string $tag 标签名\n     * @return boolean\n     */\n    public static function clear($tag = null)\n    {\n        self::$writeTimes++;\n        return self::init()->clear($tag);\n    }\n\n    /**\n     * 读取缓存并删除\n     * @access public\n     * @param string $name 缓存变量名\n     * @return mixed\n     */\n    public static function pull($name)\n    {\n        self::$readTimes++;\n        self::$writeTimes++;\n        return self::init()->pull($name);\n    }\n\n    /**\n     * 如果不存在则写入缓存\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param mixed     $value  存储数据\n     * @param int       $expire  有效时间 0为永久\n     * @return mixed\n     */\n    public static function remember($name, $value, $expire = null)\n    {\n        self::$readTimes++;\n        return self::init()->remember($name, $value, $expire);\n    }\n\n    /**\n     * 缓存标签\n     * @access public\n     * @param string        $name 标签名\n     * @param string|array  $keys 缓存标识\n     * @param bool          $overlay 是否覆盖\n     * @return Driver\n     */\n    public static function tag($name, $keys = null, $overlay = false)\n    {\n        return self::init()->tag($name, $keys, $overlay);\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/Collection.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: zhangyajun <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse ArrayAccess;\nuse ArrayIterator;\nuse Countable;\nuse IteratorAggregate;\nuse JsonSerializable;\n\nclass Collection implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable\n{\n    protected $items = [];\n\n    public function __construct($items = [])\n    {\n        $this->items = $this->convertToArray($items);\n    }\n\n    public static function make($items = [])\n    {\n        return new static($items);\n    }\n\n    /**\n     * 是否为空\n     * @return bool\n     */\n    public function isEmpty()\n    {\n        return empty($this->items);\n    }\n\n    public function toArray()\n    {\n        return array_map(function ($value) {\n            return ($value instanceof Model || $value instanceof self) ? $value->toArray() : $value;\n        }, $this->items);\n    }\n\n    public function all()\n    {\n        return $this->items;\n    }\n\n    /**\n     * 合并数组\n     *\n     * @param  mixed $items\n     * @return static\n     */\n    public function merge($items)\n    {\n        return new static(array_merge($this->items, $this->convertToArray($items)));\n    }\n\n    /**\n     * 比较数组，返回差集\n     *\n     * @param  mixed $items\n     * @return static\n     */\n    public function diff($items)\n    {\n        return new static(array_diff($this->items, $this->convertToArray($items)));\n    }\n\n    /**\n     * 交换数组中的键和值\n     *\n     * @return static\n     */\n    public function flip()\n    {\n        return new static(array_flip($this->items));\n    }\n\n    /**\n     * 比较数组，返回交集\n     *\n     * @param  mixed $items\n     * @return static\n     */\n    public function intersect($items)\n    {\n        return new static(array_intersect($this->items, $this->convertToArray($items)));\n    }\n\n    /**\n     * 返回数组中所有的键名\n     *\n     * @return static\n     */\n    public function keys()\n    {\n        return new static(array_keys($this->items));\n    }\n\n    /**\n     * 删除数组的最后一个元素（出栈）\n     *\n     * @return mixed\n     */\n    public function pop()\n    {\n        return array_pop($this->items);\n    }\n\n    /**\n     * 通过使用用户自定义函数，以字符串返回数组\n     *\n     * @param  callable $callback\n     * @param  mixed    $initial\n     * @return mixed\n     */\n    public function reduce(callable $callback, $initial = null)\n    {\n        return array_reduce($this->items, $callback, $initial);\n    }\n\n    /**\n     * 以相反的顺序返回数组。\n     *\n     * @return static\n     */\n    public function reverse()\n    {\n        return new static(array_reverse($this->items));\n    }\n\n    /**\n     * 删除数组中首个元素，并返回被删除元素的值\n     *\n     * @return mixed\n     */\n    public function shift()\n    {\n        return array_shift($this->items);\n    }\n\n    /**\n     * 把一个数组分割为新的数组块.\n     *\n     * @param  int  $size\n     * @param  bool $preserveKeys\n     * @return static\n     */\n    public function chunk($size, $preserveKeys = false)\n    {\n        $chunks = [];\n\n        foreach (array_chunk($this->items, $size, $preserveKeys) as $chunk) {\n            $chunks[] = new static($chunk);\n        }\n\n        return new static($chunks);\n    }\n\n    /**\n     * 在数组开头插入一个元素\n     * @param mixed $value\n     * @param null  $key\n     * @return int\n     */\n    public function unshift($value, $key = null)\n    {\n        if (is_null($key)) {\n            array_unshift($this->items, $value);\n        } else {\n            $this->items = [$key => $value] + $this->items;\n        }\n    }\n\n    /**\n     * 给每个元素执行个回调\n     *\n     * @param  callable $callback\n     * @return $this\n     */\n    public function each(callable $callback)\n    {\n        foreach ($this->items as $key => $item) {\n            if ($callback($item, $key) === false) {\n                break;\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * 用回调函数过滤数组中的元素\n     * @param callable|null $callback\n     * @return static\n     */\n    public function filter(callable $callback = null)\n    {\n        if ($callback) {\n            return new static(array_filter($this->items, $callback));\n        }\n\n        return new static(array_filter($this->items));\n    }\n\n    /**\n     * 返回数组中指定的一列\n     * @param      $column_key\n     * @param null $index_key\n     * @return array\n     */\n    public function column($column_key, $index_key = null)\n    {\n        if (function_exists('array_column')) {\n            return array_column($this->items, $column_key, $index_key);\n        }\n\n        $result = [];\n        foreach ($this->items as $row) {\n            $key    = $value    = null;\n            $keySet = $valueSet = false;\n            if (null !== $index_key && array_key_exists($index_key, $row)) {\n                $keySet = true;\n                $key    = (string) $row[$index_key];\n            }\n            if (null === $column_key) {\n                $valueSet = true;\n                $value    = $row;\n            } elseif (is_array($row) && array_key_exists($column_key, $row)) {\n                $valueSet = true;\n                $value    = $row[$column_key];\n            }\n            if ($valueSet) {\n                if ($keySet) {\n                    $result[$key] = $value;\n                } else {\n                    $result[] = $value;\n                }\n            }\n        }\n        return $result;\n    }\n\n    /**\n     * 对数组排序\n     *\n     * @param  callable|null $callback\n     * @return static\n     */\n    public function sort(callable $callback = null)\n    {\n        $items = $this->items;\n\n        $callback ? uasort($items, $callback) : uasort($items, function ($a, $b) {\n\n            if ($a == $b) {\n                return 0;\n            }\n\n            return ($a < $b) ? -1 : 1;\n        });\n\n        return new static($items);\n    }\n\n    /**\n     * 将数组打乱\n     *\n     * @return static\n     */\n    public function shuffle()\n    {\n        $items = $this->items;\n\n        shuffle($items);\n\n        return new static($items);\n    }\n\n    /**\n     * 截取数组\n     *\n     * @param  int  $offset\n     * @param  int  $length\n     * @param  bool $preserveKeys\n     * @return static\n     */\n    public function slice($offset, $length = null, $preserveKeys = false)\n    {\n        return new static(array_slice($this->items, $offset, $length, $preserveKeys));\n    }\n\n    // ArrayAccess\n    public function offsetExists($offset)\n    {\n        return array_key_exists($offset, $this->items);\n    }\n\n    public function offsetGet($offset)\n    {\n        return $this->items[$offset];\n    }\n\n    public function offsetSet($offset, $value)\n    {\n        if (is_null($offset)) {\n            $this->items[] = $value;\n        } else {\n            $this->items[$offset] = $value;\n        }\n    }\n\n    public function offsetUnset($offset)\n    {\n        unset($this->items[$offset]);\n    }\n\n    //Countable\n    public function count()\n    {\n        return count($this->items);\n    }\n\n    //IteratorAggregate\n    public function getIterator()\n    {\n        return new ArrayIterator($this->items);\n    }\n\n    //JsonSerializable\n    public function jsonSerialize()\n    {\n        return $this->toArray();\n    }\n\n    /**\n     * 转换当前数据集为JSON字符串\n     * @access public\n     * @param integer $options json参数\n     * @return string\n     */\n    public function toJson($options = JSON_UNESCAPED_UNICODE)\n    {\n        return json_encode($this->toArray(), $options);\n    }\n\n    public function __toString()\n    {\n        return $this->toJson();\n    }\n\n    /**\n     * 转换成数组\n     *\n     * @param  mixed $items\n     * @return array\n     */\n    protected function convertToArray($items)\n    {\n        if ($items instanceof self) {\n            return $items->all();\n        }\n        return (array) $items;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Config.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nclass Config\n{\n    // 配置参数\n    private static $config = [];\n    // 参数作用域\n    private static $range = '_sys_';\n\n    // 设定配置参数的作用域\n    public static function range($range)\n    {\n        self::$range = $range;\n        if (!isset(self::$config[$range])) {\n            self::$config[$range] = [];\n        }\n    }\n\n    /**\n     * 解析配置文件或内容\n     * @param string    $config 配置文件路径或内容\n     * @param string    $type 配置解析类型\n     * @param string    $name 配置名（如设置即表示二级配置）\n     * @param string    $range  作用域\n     * @return mixed\n     */\n    public static function parse($config, $type = '', $name = '', $range = '')\n    {\n        $range = $range ?: self::$range;\n        if (empty($type)) {\n            $type = pathinfo($config, PATHINFO_EXTENSION);\n        }\n        $class = false !== strpos($type, '\\\\') ? $type : '\\\\think\\\\config\\\\driver\\\\' . ucwords($type);\n        return self::set((new $class())->parse($config), $name, $range);\n    }\n\n    /**\n     * 加载配置文件（PHP格式）\n     * @param string    $file 配置文件名\n     * @param string    $name 配置名（如设置即表示二级配置）\n     * @param string    $range  作用域\n     * @return mixed\n     */\n    public static function load($file, $name = '', $range = '')\n    {\n        $range = $range ?: self::$range;\n        if (!isset(self::$config[$range])) {\n            self::$config[$range] = [];\n        }\n        if (is_file($file)) {\n            $name = strtolower($name);\n            $type = pathinfo($file, PATHINFO_EXTENSION);\n            if ('php' == $type) {\n                return self::set(include $file, $name, $range);\n            } elseif ('yaml' == $type && function_exists('yaml_parse_file')) {\n                return self::set(yaml_parse_file($file), $name, $range);\n            } else {\n                return self::parse($file, $type, $name, $range);\n            }\n        } else {\n            return self::$config[$range];\n        }\n    }\n\n    /**\n     * 检测配置是否存在\n     * @param string    $name 配置参数名（支持二级配置 .号分割）\n     * @param string    $range  作用域\n     * @return bool\n     */\n    public static function has($name, $range = '')\n    {\n        $range = $range ?: self::$range;\n\n        if (!strpos($name, '.')) {\n            return isset(self::$config[$range][strtolower($name)]);\n        } else {\n            // 二维数组设置和获取支持\n            $name = explode('.', $name, 2);\n            return isset(self::$config[$range][strtolower($name[0])][$name[1]]);\n        }\n    }\n\n    /**\n     * 获取配置参数 为空则获取所有配置\n     * @param string    $name 配置参数名（支持二级配置 .号分割）\n     * @param string    $range  作用域\n     * @return mixed\n     */\n    public static function get($name = null, $range = '')\n    {\n        $range = $range ?: self::$range;\n        // 无参数时获取所有\n        if (empty($name) && isset(self::$config[$range])) {\n            return self::$config[$range];\n        }\n\n        if (!strpos($name, '.')) {\n            $name = strtolower($name);\n            return isset(self::$config[$range][$name]) ? self::$config[$range][$name] : null;\n        } else {\n            // 二维数组设置和获取支持\n            $name    = explode('.', $name, 2);\n            $name[0] = strtolower($name[0]);\n            return isset(self::$config[$range][$name[0]][$name[1]]) ? self::$config[$range][$name[0]][$name[1]] : null;\n        }\n    }\n\n    /**\n     * 设置配置参数 name为数组则为批量设置\n     * @param string|array  $name 配置参数名（支持二级配置 .号分割）\n     * @param mixed         $value 配置值\n     * @param string        $range  作用域\n     * @return mixed\n     */\n    public static function set($name, $value = null, $range = '')\n    {\n        $range = $range ?: self::$range;\n        if (!isset(self::$config[$range])) {\n            self::$config[$range] = [];\n        }\n        if (is_string($name)) {\n            if (!strpos($name, '.')) {\n                self::$config[$range][strtolower($name)] = $value;\n            } else {\n                // 二维数组设置和获取支持\n                $name                                                 = explode('.', $name, 2);\n                self::$config[$range][strtolower($name[0])][$name[1]] = $value;\n            }\n            return;\n        } elseif (is_array($name)) {\n            // 批量设置\n            if (!empty($value)) {\n                self::$config[$range][$value] = isset(self::$config[$range][$value]) ?\n                array_merge(self::$config[$range][$value], $name) :\n                self::$config[$range][$value] = $name;\n                return self::$config[$range][$value];\n            } else {\n                return self::$config[$range] = array_merge(self::$config[$range], array_change_key_case($name));\n            }\n        } else {\n            // 为空直接返回 已有配置\n            return self::$config[$range];\n        }\n    }\n\n    /**\n     * 重置配置参数\n     */\n    public static function reset($range = '')\n    {\n        $range = $range ?: self::$range;\n        if (true === $range) {\n            self::$config = [];\n        } else {\n            self::$config[$range] = [];\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Console.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | TopThink [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2015 http://www.topthink.com All rights reserved.\n// +----------------------------------------------------------------------\n// | Author: zhangyajun <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\console\\Command;\nuse think\\console\\command\\Help as HelpCommand;\nuse think\\console\\Input;\nuse think\\console\\input\\Argument as InputArgument;\nuse think\\console\\input\\Definition as InputDefinition;\nuse think\\console\\input\\Option as InputOption;\nuse think\\console\\Output;\nuse think\\console\\output\\driver\\Buffer;\n\nclass Console\n{\n\n    private $name;\n    private $version;\n\n    /** @var Command[] */\n    private $commands = [];\n\n    private $wantHelps = false;\n\n    private $catchExceptions = true;\n    private $autoExit        = true;\n    private $definition;\n    private $defaultCommand;\n\n    private static $defaultCommands = [\n        \"think\\\\console\\\\command\\\\Help\",\n        \"think\\\\console\\\\command\\\\Lists\",\n        \"think\\\\console\\\\command\\\\Build\",\n        \"think\\\\console\\\\command\\\\Clear\",\n        \"think\\\\console\\\\command\\\\make\\\\Controller\",\n        \"think\\\\console\\\\command\\\\make\\\\Model\",\n        \"think\\\\console\\\\command\\\\optimize\\\\Autoload\",\n        \"think\\\\console\\\\command\\\\optimize\\\\Config\",\n        \"think\\\\console\\\\command\\\\optimize\\\\Route\",\n        \"think\\\\console\\\\command\\\\optimize\\\\Schema\",\n    ];\n\n    public function __construct($name = 'UNKNOWN', $version = 'UNKNOWN')\n    {\n        $this->name    = $name;\n        $this->version = $version;\n\n        $this->defaultCommand = 'list';\n        $this->definition     = $this->getDefaultInputDefinition();\n\n        foreach ($this->getDefaultCommands() as $command) {\n            $this->add($command);\n        }\n    }\n\n    public static function init($run = true)\n    {\n        static $console;\n        if (!$console) {\n            // 实例化console\n            $console = new self('Think Console', '0.1');\n            // 读取指令集\n            if (is_file(CONF_PATH . 'command' . EXT)) {\n                $commands = include CONF_PATH . 'command' . EXT;\n                if (is_array($commands)) {\n                    foreach ($commands as $command) {\n                        if (class_exists($command) && is_subclass_of($command, \"\\\\think\\\\console\\\\Command\")) {\n                            // 注册指令\n                            $console->add(new $command());\n                        }\n                    }\n                }\n            }\n        }\n        if ($run) {\n            // 运行\n            return $console->run();\n        } else {\n            return $console;\n        }\n    }\n\n    /**\n     * @param        $command\n     * @param array  $parameters\n     * @param string $driver\n     * @return Output|Buffer\n     */\n    public static function call($command, array $parameters = [], $driver = 'buffer')\n    {\n        $console = self::init(false);\n\n        array_unshift($parameters, $command);\n\n        $input  = new Input($parameters);\n        $output = new Output($driver);\n\n        $console->setCatchExceptions(false);\n        $console->find($command)->run($input, $output);\n\n        return $output;\n    }\n\n    /**\n     * 执行当前的指令\n     * @return int\n     * @throws \\Exception\n     * @api\n     */\n    public function run()\n    {\n        $input  = new Input();\n        $output = new Output();\n\n        $this->configureIO($input, $output);\n\n        try {\n            $exitCode = $this->doRun($input, $output);\n        } catch (\\Exception $e) {\n            if (!$this->catchExceptions) {\n                throw $e;\n            }\n\n            $output->renderException($e);\n\n            $exitCode = $e->getCode();\n            if (is_numeric($exitCode)) {\n                $exitCode = (int) $exitCode;\n                if (0 === $exitCode) {\n                    $exitCode = 1;\n                }\n            } else {\n                $exitCode = 1;\n            }\n        }\n\n        if ($this->autoExit) {\n            if ($exitCode > 255) {\n                $exitCode = 255;\n            }\n\n            exit($exitCode);\n        }\n\n        return $exitCode;\n    }\n\n    /**\n     * 执行指令\n     * @param Input  $input\n     * @param Output $output\n     * @return int\n     */\n    public function doRun(Input $input, Output $output)\n    {\n        if (true === $input->hasParameterOption(['--version', '-V'])) {\n            $output->writeln($this->getLongVersion());\n\n            return 0;\n        }\n\n        $name = $this->getCommandName($input);\n\n        if (true === $input->hasParameterOption(['--help', '-h'])) {\n            if (!$name) {\n                $name  = 'help';\n                $input = new Input(['help']);\n            } else {\n                $this->wantHelps = true;\n            }\n        }\n\n        if (!$name) {\n            $name  = $this->defaultCommand;\n            $input = new Input([$this->defaultCommand]);\n        }\n\n        $command = $this->find($name);\n\n        $exitCode = $this->doRunCommand($command, $input, $output);\n\n        return $exitCode;\n    }\n\n    /**\n     * 设置输入参数定义\n     * @param InputDefinition $definition\n     */\n    public function setDefinition(InputDefinition $definition)\n    {\n        $this->definition = $definition;\n    }\n\n    /**\n     * 获取输入参数定义\n     * @return InputDefinition The InputDefinition instance\n     */\n    public function getDefinition()\n    {\n        return $this->definition;\n    }\n\n    /**\n     * Gets the help message.\n     * @return string A help message.\n     */\n    public function getHelp()\n    {\n        return $this->getLongVersion();\n    }\n\n    /**\n     * 是否捕获异常\n     * @param bool $boolean\n     * @api\n     */\n    public function setCatchExceptions($boolean)\n    {\n        $this->catchExceptions = (bool) $boolean;\n    }\n\n    /**\n     * 是否自动退出\n     * @param bool $boolean\n     * @api\n     */\n    public function setAutoExit($boolean)\n    {\n        $this->autoExit = (bool) $boolean;\n    }\n\n    /**\n     * 获取名称\n     * @return string\n     */\n    public function getName()\n    {\n        return $this->name;\n    }\n\n    /**\n     * 设置名称\n     * @param string $name\n     */\n    public function setName($name)\n    {\n        $this->name = $name;\n    }\n\n    /**\n     * 获取版本\n     * @return string\n     * @api\n     */\n    public function getVersion()\n    {\n        return $this->version;\n    }\n\n    /**\n     * 设置版本\n     * @param string $version\n     */\n    public function setVersion($version)\n    {\n        $this->version = $version;\n    }\n\n    /**\n     * 获取完整的版本号\n     * @return string\n     */\n    public function getLongVersion()\n    {\n        if ('UNKNOWN' !== $this->getName() && 'UNKNOWN' !== $this->getVersion()) {\n            return sprintf('<info>%s</info> version <comment>%s</comment>', $this->getName(), $this->getVersion());\n        }\n\n        return '<info>Console Tool</info>';\n    }\n\n    /**\n     * 注册一个指令\n     * @param string $name\n     * @return Command\n     */\n    public function register($name)\n    {\n        return $this->add(new Command($name));\n    }\n\n    /**\n     * 添加指令\n     * @param Command[] $commands\n     */\n    public function addCommands(array $commands)\n    {\n        foreach ($commands as $command) {\n            $this->add($command);\n        }\n    }\n\n    /**\n     * 添加一个指令\n     * @param Command $command\n     * @return Command\n     */\n    public function add(Command $command)\n    {\n        $command->setConsole($this);\n\n        if (!$command->isEnabled()) {\n            $command->setConsole(null);\n            return;\n        }\n\n        if (null === $command->getDefinition()) {\n            throw new \\LogicException(sprintf('Command class \"%s\" is not correctly initialized. You probably forgot to call the parent constructor.', get_class($command)));\n        }\n\n        $this->commands[$command->getName()] = $command;\n\n        foreach ($command->getAliases() as $alias) {\n            $this->commands[$alias] = $command;\n        }\n\n        return $command;\n    }\n\n    /**\n     * 获取指令\n     * @param string $name 指令名称\n     * @return Command\n     * @throws \\InvalidArgumentException\n     */\n    public function get($name)\n    {\n        if (!isset($this->commands[$name])) {\n            throw new \\InvalidArgumentException(sprintf('The command \"%s\" does not exist.', $name));\n        }\n\n        $command = $this->commands[$name];\n\n        if ($this->wantHelps) {\n            $this->wantHelps = false;\n\n            /** @var HelpCommand $helpCommand */\n            $helpCommand = $this->get('help');\n            $helpCommand->setCommand($command);\n\n            return $helpCommand;\n        }\n\n        return $command;\n    }\n\n    /**\n     * 某个指令是否存在\n     * @param string $name 指令名称\n     * @return bool\n     */\n    public function has($name)\n    {\n        return isset($this->commands[$name]);\n    }\n\n    /**\n     * 获取所有的命名空间\n     * @return array\n     */\n    public function getNamespaces()\n    {\n        $namespaces = [];\n        foreach ($this->commands as $command) {\n            $namespaces = array_merge($namespaces, $this->extractAllNamespaces($command->getName()));\n\n            foreach ($command->getAliases() as $alias) {\n                $namespaces = array_merge($namespaces, $this->extractAllNamespaces($alias));\n            }\n        }\n\n        return array_values(array_unique(array_filter($namespaces)));\n    }\n\n    /**\n     * 查找注册命名空间中的名称或缩写。\n     * @param string $namespace\n     * @return string\n     * @throws \\InvalidArgumentException\n     */\n    public function findNamespace($namespace)\n    {\n        $allNamespaces = $this->getNamespaces();\n        $expr          = preg_replace_callback('{([^:]+|)}', function ($matches) {\n            return preg_quote($matches[1]) . '[^:]*';\n        }, $namespace);\n        $namespaces = preg_grep('{^' . $expr . '}', $allNamespaces);\n\n        if (empty($namespaces)) {\n            $message = sprintf('There are no commands defined in the \"%s\" namespace.', $namespace);\n\n            if ($alternatives = $this->findAlternatives($namespace, $allNamespaces)) {\n                if (1 == count($alternatives)) {\n                    $message .= \"\\n\\nDid you mean this?\\n    \";\n                } else {\n                    $message .= \"\\n\\nDid you mean one of these?\\n    \";\n                }\n\n                $message .= implode(\"\\n    \", $alternatives);\n            }\n\n            throw new \\InvalidArgumentException($message);\n        }\n\n        $exact = in_array($namespace, $namespaces, true);\n        if (count($namespaces) > 1 && !$exact) {\n            throw new \\InvalidArgumentException(sprintf('The namespace \"%s\" is ambiguous (%s).', $namespace, $this->getAbbreviationSuggestions(array_values($namespaces))));\n        }\n\n        return $exact ? $namespace : reset($namespaces);\n    }\n\n    /**\n     * 查找指令\n     * @param string $name 名称或者别名\n     * @return Command\n     * @throws \\InvalidArgumentException\n     */\n    public function find($name)\n    {\n        $allCommands = array_keys($this->commands);\n        $expr        = preg_replace_callback('{([^:]+|)}', function ($matches) {\n            return preg_quote($matches[1]) . '[^:]*';\n        }, $name);\n        $commands = preg_grep('{^' . $expr . '}', $allCommands);\n\n        if (empty($commands) || count(preg_grep('{^' . $expr . '$}', $commands)) < 1) {\n            if (false !== $pos = strrpos($name, ':')) {\n                $this->findNamespace(substr($name, 0, $pos));\n            }\n\n            $message = sprintf('Command \"%s\" is not defined.', $name);\n\n            if ($alternatives = $this->findAlternatives($name, $allCommands)) {\n                if (1 == count($alternatives)) {\n                    $message .= \"\\n\\nDid you mean this?\\n    \";\n                } else {\n                    $message .= \"\\n\\nDid you mean one of these?\\n    \";\n                }\n                $message .= implode(\"\\n    \", $alternatives);\n            }\n\n            throw new \\InvalidArgumentException($message);\n        }\n\n        if (count($commands) > 1) {\n            $commandList = $this->commands;\n            $commands    = array_filter($commands, function ($nameOrAlias) use ($commandList, $commands) {\n                $commandName = $commandList[$nameOrAlias]->getName();\n\n                return $commandName === $nameOrAlias || !in_array($commandName, $commands);\n            });\n        }\n\n        $exact = in_array($name, $commands, true);\n        if (count($commands) > 1 && !$exact) {\n            $suggestions = $this->getAbbreviationSuggestions(array_values($commands));\n\n            throw new \\InvalidArgumentException(sprintf('Command \"%s\" is ambiguous (%s).', $name, $suggestions));\n        }\n\n        return $this->get($exact ? $name : reset($commands));\n    }\n\n    /**\n     * 获取所有的指令\n     * @param string $namespace 命名空间\n     * @return Command[]\n     * @api\n     */\n    public function all($namespace = null)\n    {\n        if (null === $namespace) {\n            return $this->commands;\n        }\n\n        $commands = [];\n        foreach ($this->commands as $name => $command) {\n            if ($this->extractNamespace($name, substr_count($namespace, ':') + 1) === $namespace) {\n                $commands[$name] = $command;\n            }\n        }\n\n        return $commands;\n    }\n\n    /**\n     * 获取可能的指令名\n     * @param array $names\n     * @return array\n     */\n    public static function getAbbreviations($names)\n    {\n        $abbrevs = [];\n        foreach ($names as $name) {\n            for ($len = strlen($name); $len > 0; --$len) {\n                $abbrev             = substr($name, 0, $len);\n                $abbrevs[$abbrev][] = $name;\n            }\n        }\n\n        return $abbrevs;\n    }\n\n    /**\n     * 配置基于用户的参数和选项的输入和输出实例。\n     * @param Input  $input  输入实例\n     * @param Output $output 输出实例\n     */\n    protected function configureIO(Input $input, Output $output)\n    {\n        if (true === $input->hasParameterOption(['--ansi'])) {\n            $output->setDecorated(true);\n        } elseif (true === $input->hasParameterOption(['--no-ansi'])) {\n            $output->setDecorated(false);\n        }\n\n        if (true === $input->hasParameterOption(['--no-interaction', '-n'])) {\n            $input->setInteractive(false);\n        }\n\n        if (true === $input->hasParameterOption(['--quiet', '-q'])) {\n            $output->setVerbosity(Output::VERBOSITY_QUIET);\n        } else {\n            if ($input->hasParameterOption('-vvv') || $input->hasParameterOption('--verbose=3') || $input->getParameterOption('--verbose') === 3) {\n                $output->setVerbosity(Output::VERBOSITY_DEBUG);\n            } elseif ($input->hasParameterOption('-vv') || $input->hasParameterOption('--verbose=2') || $input->getParameterOption('--verbose') === 2) {\n                $output->setVerbosity(Output::VERBOSITY_VERY_VERBOSE);\n            } elseif ($input->hasParameterOption('-v') || $input->hasParameterOption('--verbose=1') || $input->hasParameterOption('--verbose') || $input->getParameterOption('--verbose')) {\n                $output->setVerbosity(Output::VERBOSITY_VERBOSE);\n            }\n        }\n    }\n\n    /**\n     * 执行指令\n     * @param Command $command 指令实例\n     * @param Input   $input   输入实例\n     * @param Output  $output  输出实例\n     * @return int\n     * @throws \\Exception\n     */\n    protected function doRunCommand(Command $command, Input $input, Output $output)\n    {\n        return $command->run($input, $output);\n    }\n\n    /**\n     * 获取指令的基础名称\n     * @param Input $input\n     * @return string\n     */\n    protected function getCommandName(Input $input)\n    {\n        return $input->getFirstArgument();\n    }\n\n    /**\n     * 获取默认输入定义\n     * @return InputDefinition\n     */\n    protected function getDefaultInputDefinition()\n    {\n        return new InputDefinition([\n            new InputArgument('command', InputArgument::REQUIRED, 'The command to execute'),\n            new InputOption('--help', '-h', InputOption::VALUE_NONE, 'Display this help message'),\n            new InputOption('--version', '-V', InputOption::VALUE_NONE, 'Display this console version'),\n            new InputOption('--quiet', '-q', InputOption::VALUE_NONE, 'Do not output any message'),\n            new InputOption('--verbose', '-v|vv|vvv', InputOption::VALUE_NONE, 'Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug'),\n            new InputOption('--ansi', '', InputOption::VALUE_NONE, 'Force ANSI output'),\n            new InputOption('--no-ansi', '', InputOption::VALUE_NONE, 'Disable ANSI output'),\n            new InputOption('--no-interaction', '-n', InputOption::VALUE_NONE, 'Do not ask any interactive question'),\n        ]);\n    }\n\n    /**\n     * 设置默认命令\n     * @return Command[] An array of default Command instances\n     */\n    protected function getDefaultCommands()\n    {\n        $defaultCommands = [];\n\n        foreach (self::$defaultCommands as $classname) {\n            if (class_exists($classname) && is_subclass_of($classname, \"think\\\\console\\\\Command\")) {\n                $defaultCommands[] = new $classname();\n            }\n        }\n\n        return $defaultCommands;\n    }\n\n    public static function addDefaultCommands(array $classnames)\n    {\n        self::$defaultCommands = array_merge(self::$defaultCommands, $classnames);\n    }\n\n    /**\n     * 获取可能的建议\n     * @param array $abbrevs\n     * @return string\n     */\n    private function getAbbreviationSuggestions($abbrevs)\n    {\n        return sprintf('%s, %s%s', $abbrevs[0], $abbrevs[1], count($abbrevs) > 2 ? sprintf(' and %d more', count($abbrevs) - 2) : '');\n    }\n\n    /**\n     * 返回命名空间部分\n     * @param string $name  指令\n     * @param string $limit 部分的命名空间的最大数量\n     * @return string\n     */\n    public function extractNamespace($name, $limit = null)\n    {\n        $parts = explode(':', $name);\n        array_pop($parts);\n\n        return implode(':', null === $limit ? $parts : array_slice($parts, 0, $limit));\n    }\n\n    /**\n     * 查找可替代的建议\n     * @param string             $name\n     * @param array|\\Traversable $collection\n     * @return array\n     */\n    private function findAlternatives($name, $collection)\n    {\n        $threshold    = 1e3;\n        $alternatives = [];\n\n        $collectionParts = [];\n        foreach ($collection as $item) {\n            $collectionParts[$item] = explode(':', $item);\n        }\n\n        foreach (explode(':', $name) as $i => $subname) {\n            foreach ($collectionParts as $collectionName => $parts) {\n                $exists = isset($alternatives[$collectionName]);\n                if (!isset($parts[$i]) && $exists) {\n                    $alternatives[$collectionName] += $threshold;\n                    continue;\n                } elseif (!isset($parts[$i])) {\n                    continue;\n                }\n\n                $lev = levenshtein($subname, $parts[$i]);\n                if ($lev <= strlen($subname) / 3 || '' !== $subname && false !== strpos($parts[$i], $subname)) {\n                    $alternatives[$collectionName] = $exists ? $alternatives[$collectionName] + $lev : $lev;\n                } elseif ($exists) {\n                    $alternatives[$collectionName] += $threshold;\n                }\n            }\n        }\n\n        foreach ($collection as $item) {\n            $lev = levenshtein($name, $item);\n            if ($lev <= strlen($name) / 3 || false !== strpos($item, $name)) {\n                $alternatives[$item] = isset($alternatives[$item]) ? $alternatives[$item] - $lev : $lev;\n            }\n        }\n\n        $alternatives = array_filter($alternatives, function ($lev) use ($threshold) {\n            return $lev < 2 * $threshold;\n        });\n        asort($alternatives);\n\n        return array_keys($alternatives);\n    }\n\n    /**\n     * 设置默认的指令\n     * @param string $commandName The Command name\n     */\n    public function setDefaultCommand($commandName)\n    {\n        $this->defaultCommand = $commandName;\n    }\n\n    /**\n     * 返回所有的命名空间\n     * @param string $name\n     * @return array\n     */\n    private function extractAllNamespaces($name)\n    {\n        $parts      = explode(':', $name, -1);\n        $namespaces = [];\n\n        foreach ($parts as $part) {\n            if (count($namespaces)) {\n                $namespaces[] = end($namespaces) . ':' . $part;\n            } else {\n                $namespaces[] = $part;\n            }\n        }\n\n        return $namespaces;\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/Controller.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\n\\think\\Loader::import('controller/Jump', TRAIT_PATH, EXT);\n\nuse think\\exception\\ValidateException;\n\nclass Controller\n{\n    use \\traits\\controller\\Jump;\n\n    /**\n     * @var \\think\\View 视图类实例\n     */\n    protected $view;\n    /**\n     * @var \\think\\Request Request实例\n     */\n    protected $request;\n    // 验证失败是否抛出异常\n    protected $failException = false;\n    // 是否批量验证\n    protected $batchValidate = false;\n\n    /**\n     * 前置操作方法列表\n     * @var array $beforeActionList\n     * @access protected\n     */\n    protected $beforeActionList = [];\n\n    /**\n     * 构造方法\n     * @param Request $request Request对象\n     * @access public\n     */\n    public function __construct(Request $request = null)\n    {\n        if (is_null($request)) {\n            $request = Request::instance();\n        }\n        $this->view    = View::instance(Config::get('template'), Config::get('view_replace_str'));\n        $this->request = $request;\n\n        // 控制器初始化\n        $this->_initialize();\n\n        // 前置操作方法\n        if ($this->beforeActionList) {\n            foreach ($this->beforeActionList as $method => $options) {\n                is_numeric($method) ?\n                $this->beforeAction($options) :\n                $this->beforeAction($method, $options);\n            }\n        }\n    }\n\n    // 初始化\n    protected function _initialize()\n    {\n    }\n\n    /**\n     * 前置操作\n     * @access protected\n     * @param string $method  前置操作方法名\n     * @param array  $options 调用参数 ['only'=>[...]] 或者['except'=>[...]]\n     */\n    protected function beforeAction($method, $options = [])\n    {\n        if (isset($options['only'])) {\n            if (is_string($options['only'])) {\n                $options['only'] = explode(',', $options['only']);\n            }\n            if (!in_array($this->request->action(), $options['only'])) {\n                return;\n            }\n        } elseif (isset($options['except'])) {\n            if (is_string($options['except'])) {\n                $options['except'] = explode(',', $options['except']);\n            }\n            if (in_array($this->request->action(), $options['except'])) {\n                return;\n            }\n        }\n\n        call_user_func([$this, $method]);\n    }\n\n    /**\n     * 加载模板输出\n     * @access protected\n     * @param string $template 模板文件名\n     * @param array  $vars     模板输出变量\n     * @param array  $replace  模板替换\n     * @param array  $config   模板参数\n     * @return mixed\n     */\n    protected function fetch($template = '', $vars = [], $replace = [], $config = [])\n    {\n        return $this->view->fetch($template, $vars, $replace, $config);\n    }\n\n    /**\n     * 渲染内容输出\n     * @access protected\n     * @param string $content 模板内容\n     * @param array  $vars    模板输出变量\n     * @param array  $replace 替换内容\n     * @param array  $config  模板参数\n     * @return mixed\n     */\n    protected function display($content = '', $vars = [], $replace = [], $config = [])\n    {\n        return $this->view->display($content, $vars, $replace, $config);\n    }\n\n    /**\n     * 模板变量赋值\n     * @access protected\n     * @param mixed $name  要显示的模板变量\n     * @param mixed $value 变量的值\n     * @return void\n     */\n    protected function assign($name, $value = '')\n    {\n        $this->view->assign($name, $value);\n    }\n\n    /**\n     * 初始化模板引擎\n     * @access protected\n     * @param array|string $engine 引擎参数\n     * @return void\n     */\n    protected function engine($engine)\n    {\n        $this->view->engine($engine);\n    }\n\n    /**\n     * 设置验证失败后是否抛出异常\n     * @access protected\n     * @param bool $fail 是否抛出异常\n     * @return $this\n     */\n    protected function validateFailException($fail = true)\n    {\n        $this->failException = $fail;\n        return $this;\n    }\n\n    /**\n     * 验证数据\n     * @access protected\n     * @param array        $data     数据\n     * @param string|array $validate 验证器名或者验证规则数组\n     * @param array        $message  提示信息\n     * @param bool         $batch    是否批量验证\n     * @param mixed        $callback 回调方法（闭包）\n     * @return array|string|true\n     * @throws ValidateException\n     */\n    protected function validate($data, $validate, $message = [], $batch = false, $callback = null)\n    {\n        if (is_array($validate)) {\n            $v = Loader::validate();\n            $v->rule($validate);\n        } else {\n            if (strpos($validate, '.')) {\n                // 支持场景\n                list($validate, $scene) = explode('.', $validate);\n            }\n            $v = Loader::validate($validate);\n            if (!empty($scene)) {\n                $v->scene($scene);\n            }\n        }\n        // 是否批量验证\n        if ($batch || $this->batchValidate) {\n            $v->batch(true);\n        }\n\n        if (is_array($message)) {\n            $v->message($message);\n        }\n\n        if ($callback && is_callable($callback)) {\n            call_user_func_array($callback, [$v, &$data]);\n        }\n\n        if (!$v->check($data)) {\n            if ($this->failException) {\n                throw new ValidateException($v->getError());\n            } else {\n                return $v->getError();\n            }\n        } else {\n            return true;\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Cookie.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nclass Cookie\n{\n    protected static $config = [\n        // cookie 名称前缀\n        'prefix'    => '',\n        // cookie 保存时间\n        'expire'    => 0,\n        // cookie 保存路径\n        'path'      => '/',\n        // cookie 有效域名\n        'domain'    => '',\n        //  cookie 启用安全传输\n        'secure'    => false,\n        // httponly设置\n        'httponly'  => '',\n        // 是否使用 setcookie\n        'setcookie' => true,\n    ];\n\n    protected static $init;\n\n    /**\n     * Cookie初始化\n     * @param array $config\n     * @return void\n     */\n    public static function init(array $config = [])\n    {\n        if (empty($config)) {\n            $config = Config::get('cookie');\n        }\n        self::$config = array_merge(self::$config, array_change_key_case($config));\n        if (!empty(self::$config['httponly'])) {\n            ini_set('session.cookie_httponly', 1);\n        }\n        self::$init = true;\n    }\n\n    /**\n     * 设置或者获取cookie作用域（前缀）\n     * @param string $prefix\n     * @return string|void\n     */\n    public static function prefix($prefix = '')\n    {\n        if (empty($prefix)) {\n            return self::$config['prefix'];\n        }\n        self::$config['prefix'] = $prefix;\n    }\n\n    /**\n     * Cookie 设置、获取、删除\n     *\n     * @param string $name  cookie名称\n     * @param mixed  $value cookie值\n     * @param mixed  $option 可选参数 可能会是 null|integer|string\n     *\n     * @return mixed\n     * @internal param mixed $options cookie参数\n     */\n    public static function set($name, $value = '', $option = null)\n    {\n        !isset(self::$init) && self::init();\n        // 参数设置(会覆盖黙认设置)\n        if (!is_null($option)) {\n            if (is_numeric($option)) {\n                $option = ['expire' => $option];\n            } elseif (is_string($option)) {\n                parse_str($option, $option);\n            }\n            $config = array_merge(self::$config, array_change_key_case($option));\n        } else {\n            $config = self::$config;\n        }\n        $name = $config['prefix'] . $name;\n        // 设置cookie\n        if (is_array($value)) {\n            array_walk_recursive($value, 'self::jsonFormatProtect', 'encode');\n            $value = 'think:' . json_encode($value);\n        }\n        $expire = !empty($config['expire']) ? $_SERVER['REQUEST_TIME'] + intval($config['expire']) : 0;\n        if ($config['setcookie']) {\n            setcookie($name, $value, $expire, $config['path'], $config['domain'], $config['secure'], $config['httponly']);\n        }\n        $_COOKIE[$name] = $value;\n    }\n\n    /**\n     * 永久保存Cookie数据\n     * @param string $name  cookie名称\n     * @param mixed  $value cookie值\n     * @param mixed  $option 可选参数 可能会是 null|integer|string\n     * @return void\n     */\n    public static function forever($name, $value = '', $option = null)\n    {\n        if (is_null($option) || is_numeric($option)) {\n            $option = [];\n        }\n        $option['expire'] = 315360000;\n        self::set($name, $value, $option);\n    }\n\n    /**\n     * 判断Cookie数据\n     * @param string        $name cookie名称\n     * @param string|null   $prefix cookie前缀\n     * @return bool\n     */\n    public static function has($name, $prefix = null)\n    {\n        !isset(self::$init) && self::init();\n        $prefix = !is_null($prefix) ? $prefix : self::$config['prefix'];\n        $name   = $prefix . $name;\n        return isset($_COOKIE[$name]);\n    }\n\n    /**\n     * Cookie获取\n     * @param string        $name cookie名称\n     * @param string|null   $prefix cookie前缀\n     * @return mixed\n     */\n    public static function get($name = '', $prefix = null)\n    {\n        !isset(self::$init) && self::init();\n        $prefix = !is_null($prefix) ? $prefix : self::$config['prefix'];\n        $key    = $prefix . $name;\n\n        if ('' == $name) {\n            // 获取全部\n            if ($prefix) {\n                $value = [];\n                foreach ($_COOKIE as $k => $val) {\n                    if (0 === strpos($k, $prefix)) {\n                        $value[$k] = $val;\n                    }\n                }\n            } else {\n                $value = $_COOKIE;\n            }\n        } elseif (isset($_COOKIE[$key])) {\n            $value = $_COOKIE[$key];\n            if (0 === strpos($value, 'think:')) {\n                $value = substr($value, 6);\n                $value = json_decode($value, true);\n                array_walk_recursive($value, 'self::jsonFormatProtect', 'decode');\n            }\n        } else {\n            $value = null;\n        }\n        return $value;\n    }\n\n    /**\n     * Cookie删除\n     * @param string        $name cookie名称\n     * @param string|null   $prefix cookie前缀\n     * @return mixed\n     */\n    public static function delete($name, $prefix = null)\n    {\n        !isset(self::$init) && self::init();\n        $config = self::$config;\n        $prefix = !is_null($prefix) ? $prefix : $config['prefix'];\n        $name   = $prefix . $name;\n        if ($config['setcookie']) {\n            setcookie($name, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']);\n        }\n        // 删除指定cookie\n        unset($_COOKIE[$name]);\n    }\n\n    /**\n     * Cookie清空\n     * @param string|null $prefix cookie前缀\n     * @return mixed\n     */\n    public static function clear($prefix = null)\n    {\n        // 清除指定前缀的所有cookie\n        if (empty($_COOKIE)) {\n            return;\n        }\n        !isset(self::$init) && self::init();\n        // 要删除的cookie前缀，不指定则删除config设置的指定前缀\n        $config = self::$config;\n        $prefix = !is_null($prefix) ? $prefix : $config['prefix'];\n        if ($prefix) {\n            // 如果前缀为空字符串将不作处理直接返回\n            foreach ($_COOKIE as $key => $val) {\n                if (0 === strpos($key, $prefix)) {\n                    if ($config['setcookie']) {\n                        setcookie($key, '', $_SERVER['REQUEST_TIME'] - 3600, $config['path'], $config['domain'], $config['secure'], $config['httponly']);\n                    }\n                    unset($_COOKIE[$key]);\n                }\n            }\n        }\n        return;\n    }\n\n    private static function jsonFormatProtect(&$val, $key, $type = 'encode')\n    {\n        if (!empty($val) && true !== $val) {\n            $val = 'decode' == $type ? urldecode($val) : urlencode($val);\n        }\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/Db.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\db\\Connection;\nuse think\\db\\Query;\n\n/**\n * Class Db\n * @package think\n * @method Query table(string $table) static 指定数据表（含前缀）\n * @method Query name(string $name) static 指定数据表（不含前缀）\n * @method Query where(mixed $field, string $op = null, mixed $condition = null) static 查询条件\n * @method Query join(mixed $join, mixed $condition = null, string $type = 'INNER') static JOIN查询\n * @method Query union(mixed $union, boolean $all = false) static UNION查询\n * @method Query limit(mixed $offset, integer $length = null) static 查询LIMIT\n * @method Query order(mixed $field, string $order = null) static 查询ORDER\n * @method Query cache(mixed $key = null , integer $expire = null) static 设置查询缓存\n * @method mixed value(string $field) static 获取某个字段的值\n * @method array column(string $field, string $key = '') static 获取某个列的值\n * @method Query view(mixed $join, mixed $field = null, mixed $on = null, string $type = 'INNER') static 视图查询\n * @method mixed find(mixed $data = null) static 查询单个记录\n * @method mixed select(mixed $data = null) static 查询多个记录\n * @method integer insert(array $data, boolean $replace = false, boolean $getLastInsID = false, string $sequence = null) static 插入一条记录\n * @method integer insertGetId(array $data, boolean $replace = false, string $sequence = null) static 插入一条记录并返回自增ID\n * @method integer insertAll(array $dataSet) static 插入多条记录\n * @method integer update(array $data) static 更新记录\n * @method integer delete(mixed $data = null) static 删除记录\n * @method boolean chunk(integer $count, callable $callback, string $column = null) static 分块获取数据\n * @method mixed query(string $sql, array $bind = [], boolean $master = false, bool $pdo = false) static SQL查询\n * @method integer execute(string $sql, array $bind = [], boolean $fetch = false, boolean $getLastInsID = false, string $sequence = null) static SQL执行\n * @method Paginator paginate(integer $listRows = 15, mixed $simple = null, array $config = []) static 分页查询\n * @method mixed transaction(callable $callback) static 执行数据库事务\n * @method void startTrans() static 启动事务\n * @method void commit() static 用于非自动提交状态下面的查询提交\n * @method void rollback() static 事务回滚\n * @method boolean batchQuery(array $sqlArray) static 批处理执行SQL语句\n * @method string quote(string $str) static SQL指令安全过滤\n * @method string getLastInsID($sequence = null) static 获取最近插入的ID\n */\nclass Db\n{\n    //  数据库连接实例\n    private static $instance = [];\n    // 查询次数\n    public static $queryTimes = 0;\n    // 执行次数\n    public static $executeTimes = 0;\n\n    /**\n     * 数据库初始化 并取得数据库类实例\n     * @static\n     * @access public\n     * @param mixed         $config 连接配置\n     * @param bool|string   $name 连接标识 true 强制重新连接\n     * @return Connection\n     * @throws Exception\n     */\n    public static function connect($config = [], $name = false)\n    {\n        if (false === $name) {\n            $name = md5(serialize($config));\n        }\n        if (true === $name || !isset(self::$instance[$name])) {\n            // 解析连接参数 支持数组和字符串\n            $options = self::parseConfig($config);\n            if (empty($options['type'])) {\n                throw new \\InvalidArgumentException('Underfined db type');\n            }\n            $class = false !== strpos($options['type'], '\\\\') ? $options['type'] : '\\\\think\\\\db\\\\connector\\\\' . ucwords($options['type']);\n            // 记录初始化信息\n            if (App::$debug) {\n                Log::record('[ DB ] INIT ' . $options['type'], 'info');\n            }\n            if (true === $name) {\n                return new $class($options);\n            } else {\n                self::$instance[$name] = new $class($options);\n            }\n        }\n        return self::$instance[$name];\n    }\n\n    /**\n     * 数据库连接参数解析\n     * @static\n     * @access private\n     * @param mixed $config\n     * @return array\n     */\n    private static function parseConfig($config)\n    {\n        if (empty($config)) {\n            $config = Config::get('database');\n        } elseif (is_string($config) && false === strpos($config, '/')) {\n            // 支持读取配置参数\n            $config = Config::get($config);\n        }\n        if (is_string($config)) {\n            return self::parseDsn($config);\n        } else {\n            return $config;\n        }\n    }\n\n    /**\n     * DSN解析\n     * 格式： mysql://username:passwd@localhost:3306/DbName?param1=val1&param2=val2#utf8\n     * @static\n     * @access private\n     * @param string $dsnStr\n     * @return array\n     */\n    private static function parseDsn($dsnStr)\n    {\n        $info = parse_url($dsnStr);\n        if (!$info) {\n            return [];\n        }\n        $dsn = [\n            'type'     => $info['scheme'],\n            'username' => isset($info['user']) ? $info['user'] : '',\n            'password' => isset($info['pass']) ? $info['pass'] : '',\n            'hostname' => isset($info['host']) ? $info['host'] : '',\n            'hostport' => isset($info['port']) ? $info['port'] : '',\n            'database' => !empty($info['path']) ? ltrim($info['path'], '/') : '',\n            'charset'  => isset($info['fragment']) ? $info['fragment'] : 'utf8',\n        ];\n\n        if (isset($info['query'])) {\n            parse_str($info['query'], $dsn['params']);\n        } else {\n            $dsn['params'] = [];\n        }\n        return $dsn;\n    }\n\n    // 调用驱动类的方法\n    public static function __callStatic($method, $params)\n    {\n        // 自动初始化数据库\n        return call_user_func_array([self::connect(), $method], $params);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Debug.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\exception\\ClassNotFoundException;\nuse think\\response\\Redirect;\n\nclass Debug\n{\n    // 区间时间信息\n    protected static $info = [];\n    // 区间内存信息\n    protected static $mem = [];\n\n    /**\n     * 记录时间（微秒）和内存使用情况\n     * @param string    $name 标记位置\n     * @param mixed     $value 标记值 留空则取当前 time 表示仅记录时间 否则同时记录时间和内存\n     * @return mixed\n     */\n    public static function remark($name, $value = '')\n    {\n        // 记录时间和内存使用\n        self::$info[$name] = is_float($value) ? $value : microtime(true);\n        if ('time' != $value) {\n            self::$mem['mem'][$name]  = is_float($value) ? $value : memory_get_usage();\n            self::$mem['peak'][$name] = memory_get_peak_usage();\n        }\n    }\n\n    /**\n     * 统计某个区间的时间（微秒）使用情况\n     * @param string            $start 开始标签\n     * @param string            $end 结束标签\n     * @param integer|string    $dec 小数位\n     * @return integer\n     */\n    public static function getRangeTime($start, $end, $dec = 6)\n    {\n        if (!isset(self::$info[$end])) {\n            self::$info[$end] = microtime(true);\n        }\n        return number_format((self::$info[$end] - self::$info[$start]), $dec);\n    }\n\n    /**\n     * 统计从开始到统计时的时间（微秒）使用情况\n     * @param integer|string $dec 小数位\n     * @return integer\n     */\n    public static function getUseTime($dec = 6)\n    {\n        return number_format((microtime(true) - THINK_START_TIME), $dec);\n    }\n\n    /**\n     * 获取当前访问的吞吐率情况\n     * @return string\n     */\n    public static function getThroughputRate()\n    {\n        return number_format(1 / self::getUseTime(), 2) . 'req/s';\n    }\n\n    /**\n     * 记录区间的内存使用情况\n     * @param string            $start 开始标签\n     * @param string            $end 结束标签\n     * @param integer|string    $dec 小数位\n     * @return string\n     */\n    public static function getRangeMem($start, $end, $dec = 2)\n    {\n        if (!isset(self::$mem['mem'][$end])) {\n            self::$mem['mem'][$end] = memory_get_usage();\n        }\n        $size = self::$mem['mem'][$end] - self::$mem['mem'][$start];\n        $a    = ['B', 'KB', 'MB', 'GB', 'TB'];\n        $pos  = 0;\n        while ($size >= 1024) {\n            $size /= 1024;\n            $pos++;\n        }\n        return round($size, $dec) . \" \" . $a[$pos];\n    }\n\n    /**\n     * 统计从开始到统计时的内存使用情况\n     * @param integer|string $dec 小数位\n     * @return string\n     */\n    public static function getUseMem($dec = 2)\n    {\n        $size = memory_get_usage() - THINK_START_MEM;\n        $a    = ['B', 'KB', 'MB', 'GB', 'TB'];\n        $pos  = 0;\n        while ($size >= 1024) {\n            $size /= 1024;\n            $pos++;\n        }\n        return round($size, $dec) . \" \" . $a[$pos];\n    }\n\n    /**\n     * 统计区间的内存峰值情况\n     * @param string            $start 开始标签\n     * @param string            $end 结束标签\n     * @param integer|string    $dec 小数位\n     * @return mixed\n     */\n    public static function getMemPeak($start, $end, $dec = 2)\n    {\n        if (!isset(self::$mem['peak'][$end])) {\n            self::$mem['peak'][$end] = memory_get_peak_usage();\n        }\n        $size = self::$mem['peak'][$end] - self::$mem['peak'][$start];\n        $a    = ['B', 'KB', 'MB', 'GB', 'TB'];\n        $pos  = 0;\n        while ($size >= 1024) {\n            $size /= 1024;\n            $pos++;\n        }\n        return round($size, $dec) . \" \" . $a[$pos];\n    }\n\n    /**\n     * 获取文件加载信息\n     * @param bool  $detail 是否显示详细\n     * @return integer|array\n     */\n    public static function getFile($detail = false)\n    {\n        if ($detail) {\n            $files = get_included_files();\n            $info  = [];\n            foreach ($files as $key => $file) {\n                $info[] = $file . ' ( ' . number_format(filesize($file) / 1024, 2) . ' KB )';\n            }\n            return $info;\n        }\n        return count(get_included_files());\n    }\n\n    /**\n     * 浏览器友好的变量输出\n     * @param mixed         $var 变量\n     * @param boolean       $echo 是否输出 默认为true 如果为false 则返回输出字符串\n     * @param string        $label 标签 默认为空\n     * @param integer       $flags htmlspecialchars flags\n     * @return void|string\n     */\n    public static function dump($var, $echo = true, $label = null, $flags = ENT_SUBSTITUTE)\n    {\n        $label = (null === $label) ? '' : rtrim($label) . ':';\n        ob_start();\n        var_dump($var);\n        $output = ob_get_clean();\n        $output = preg_replace('/\\]\\=\\>\\n(\\s+)/m', '] => ', $output);\n        if (IS_CLI) {\n            $output = PHP_EOL . $label . $output . PHP_EOL;\n        } else {\n            if (!extension_loaded('xdebug')) {\n                $output = htmlspecialchars($output, $flags);\n            }\n            $output = '<pre>' . $label . $output . '</pre>';\n        }\n        if ($echo) {\n            echo($output);\n            return;\n        } else {\n            return $output;\n        }\n    }\n\n    public static function inject(Response $response, &$content)\n    {\n        $config  = Config::get('trace');\n        $type    = isset($config['type']) ? $config['type'] : 'Html';\n        $request = Request::instance();\n        $class   = false !== strpos($type, '\\\\') ? $type : '\\\\think\\\\debug\\\\' . ucwords($type);\n        unset($config['type']);\n        if (class_exists($class)) {\n            $trace = new $class($config);\n        } else {\n            throw new ClassNotFoundException('class not exists:' . $class, $class);\n        }\n\n        if ($response instanceof Redirect) {\n            //TODO 记录\n        } else {\n            $output = $trace->output($response, Log::getLog());\n            if (is_string($output)) {\n                // trace调试信息注入\n                $pos = strripos($content, '</body>');\n                if (false !== $pos) {\n                    $content = substr($content, 0, $pos) . $output . substr($content, $pos);\n                } else {\n                    $content = $content . $output;\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Env.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nclass Env\n{\n    /**\n     * 获取环境变量值\n     * @param string    $name 环境变量名（支持二级 .号分割）\n     * @param string    $default  默认值\n     * @return mixed\n     */\n    public static function get($name, $default = null)\n    {\n        $result = getenv(ENV_PREFIX . strtoupper(str_replace('.', '_', $name)));\n        if (false !== $result) {\n            return $result;\n        } else {\n            return $default;\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Error.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\console\\Output as ConsoleOutput;\nuse think\\exception\\ErrorException;\nuse think\\exception\\Handle;\nuse think\\exception\\ThrowableError;\n\nclass Error\n{\n    /**\n     * 注册异常处理\n     * @return void\n     */\n    public static function register()\n    {\n        error_reporting(E_ALL);\n        set_error_handler([__CLASS__, 'appError']);\n        set_exception_handler([__CLASS__, 'appException']);\n        register_shutdown_function([__CLASS__, 'appShutdown']);\n    }\n\n    /**\n     * Exception Handler\n     * @param  \\Exception|\\Throwable $e\n     */\n    public static function appException($e)\n    {\n        if (!$e instanceof \\Exception) {\n            $e = new ThrowableError($e);\n        }\n\n        self::getExceptionHandler()->report($e);\n        if (IS_CLI) {\n            self::getExceptionHandler()->renderForConsole(new ConsoleOutput, $e);\n        } else {\n            self::getExceptionHandler()->render($e)->send();\n        }\n    }\n\n    /**\n     * Error Handler\n     * @param  integer $errno   错误编号\n     * @param  integer $errstr  详细错误信息\n     * @param  string  $errfile 出错的文件\n     * @param  integer $errline 出错行号\n     * @param array    $errcontext\n     * @throws ErrorException\n     */\n    public static function appError($errno, $errstr, $errfile = '', $errline = 0, $errcontext = [])\n    {\n        $exception = new ErrorException($errno, $errstr, $errfile, $errline, $errcontext);\n        if (error_reporting() & $errno) {\n            // 将错误信息托管至 think\\exception\\ErrorException\n            throw $exception;\n        } else {\n            self::getExceptionHandler()->report($exception);\n        }\n    }\n\n    /**\n     * Shutdown Handler\n     */\n    public static function appShutdown()\n    {\n        if (!is_null($error = error_get_last()) && self::isFatal($error['type'])) {\n            // 将错误信息托管至think\\ErrorException\n            $exception = new ErrorException($error['type'], $error['message'], $error['file'], $error['line']);\n\n            self::appException($exception);\n        }\n\n        // 写入日志\n        Log::save();\n    }\n\n    /**\n     * 确定错误类型是否致命\n     *\n     * @param  int $type\n     * @return bool\n     */\n    protected static function isFatal($type)\n    {\n        return in_array($type, [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE]);\n    }\n\n    /**\n     * Get an instance of the exception handler.\n     *\n     * @return Handle\n     */\n    public static function getExceptionHandler()\n    {\n        static $handle;\n        if (!$handle) {\n            // 异常处理handle\n            $class = Config::get('exception_handle');\n            if ($class && class_exists($class) && is_subclass_of($class, \"\\\\think\\\\exception\\\\Handle\")) {\n                $handle = new $class;\n            } else {\n                $handle = new Handle;\n            }\n        }\n        return $handle;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Exception.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nclass Exception extends \\Exception\n{\n\n    /**\n     * 保存异常页面显示的额外Debug数据\n     * @var array\n     */\n    protected $data = [];\n\n    /**\n     * 设置异常额外的Debug数据\n     * 数据将会显示为下面的格式\n     *\n     * Exception Data\n     * --------------------------------------------------\n     * Label 1\n     *   key1      value1\n     *   key2      value2\n     * Label 2\n     *   key1      value1\n     *   key2      value2\n     *\n     * @param string $label 数据分类，用于异常页面显示\n     * @param array  $data  需要显示的数据，必须为关联数组\n     */\n    final protected function setData($label, array $data)\n    {\n        $this->data[$label] = $data;\n    }\n\n    /**\n     * 获取异常额外Debug数据\n     * 主要用于输出到异常页面便于调试\n     * @return array 由setData设置的Debug数据\n     */\n    final public function getData()\n    {\n        return $this->data;\n    }\n    \n}\n"
  },
  {
    "path": "thinkphp/library/think/File.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse SplFileObject;\n\nclass File extends SplFileObject\n{\n    /**\n     * 错误信息\n     * @var string\n     */\n    private $error = '';\n    // 当前完整文件名\n    protected $filename;\n    // 上传文件名\n    protected $saveName;\n    // 文件上传命名规则\n    protected $rule = 'date';\n    // 文件上传验证规则\n    protected $validate = [];\n    // 单元测试\n    protected $isTest;\n    // 上传文件信息\n    protected $info;\n    // 文件hash信息\n    protected $hash = [];\n\n    public function __construct($filename, $mode = 'r')\n    {\n        parent::__construct($filename, $mode);\n        $this->filename = $this->getRealPath() ?: $this->getPathname();\n    }\n\n    /**\n     * 是否测试\n     * @param  bool   $test 是否测试\n     * @return $this\n     */\n    public function isTest($test = false)\n    {\n        $this->isTest = $test;\n        return $this;\n    }\n\n    /**\n     * 设置上传信息\n     * @param  array   $info 上传文件信息\n     * @return $this\n     */\n    public function setUploadInfo($info)\n    {\n        $this->info = $info;\n        return $this;\n    }\n\n    /**\n     * 获取上传文件的信息\n     * @param  string   $name\n     * @return array|string\n     */\n    public function getInfo($name = '')\n    {\n        return isset($this->info[$name]) ? $this->info[$name] : $this->info;\n    }\n\n    /**\n     * 获取上传文件的文件名\n     * @return string\n     */\n    public function getSaveName()\n    {\n        return $this->saveName;\n    }\n\n    /**\n     * 设置上传文件的保存文件名\n     * @param  string   $saveName\n     * @return $this\n     */\n    public function setSaveName($saveName)\n    {\n        $this->saveName = $saveName;\n        return $this;\n    }\n\n    /**\n     * 获取文件的哈希散列值\n     * @return $string\n     */\n    public function hash($type = 'sha1')\n    {\n        if (!isset($this->hash[$type])) {\n            $this->hash[$type] = hash_file($type, $this->filename);\n        }\n        return $this->hash[$type];\n    }\n\n    /**\n     * 检查目录是否可写\n     * @param  string   $path    目录\n     * @return boolean\n     */\n    protected function checkPath($path)\n    {\n        if (is_dir($path)) {\n            return true;\n        }\n\n        if (mkdir($path, 0755, true)) {\n            return true;\n        } else {\n            $this->error = \"目录 {$path} 创建失败！\";\n            return false;\n        }\n    }\n\n    /**\n     * 获取文件类型信息\n     * @return string\n     */\n    public function getMime()\n    {\n        $finfo = finfo_open(FILEINFO_MIME_TYPE);\n        return finfo_file($finfo, $this->filename);\n    }\n\n    /**\n     * 设置文件的命名规则\n     * @param  string   $rule    文件命名规则\n     * @return $this\n     */\n    public function rule($rule)\n    {\n        $this->rule = $rule;\n        return $this;\n    }\n\n    /**\n     * 设置上传文件的验证规则\n     * @param  array   $rule    验证规则\n     * @return $this\n     */\n    public function validate($rule = [])\n    {\n        $this->validate = $rule;\n        return $this;\n    }\n\n    /**\n     * 检测是否合法的上传文件\n     * @return bool\n     */\n    public function isValid()\n    {\n        if ($this->isTest) {\n            return is_file($this->filename);\n        }\n        return is_uploaded_file($this->filename);\n    }\n\n    /**\n     * 检测上传文件\n     * @param  array   $rule    验证规则\n     * @return bool\n     */\n    public function check($rule = [])\n    {\n        $rule = $rule ?: $this->validate;\n\n        /* 检查文件大小 */\n        if (isset($rule['size']) && !$this->checkSize($rule['size'])) {\n            $this->error = '上传文件大小不符！';\n            return false;\n        }\n\n        /* 检查文件Mime类型 */\n        if (isset($rule['type']) && !$this->checkMime($rule['type'])) {\n            $this->error = '上传文件MIME类型不允许！';\n            return false;\n        }\n\n        /* 检查文件后缀 */\n        if (isset($rule['ext']) && !$this->checkExt($rule['ext'])) {\n            $this->error = '上传文件后缀不允许';\n            return false;\n        }\n\n        /* 检查图像文件 */\n        if (!$this->checkImg()) {\n            $this->error = '非法图像文件！';\n            return false;\n        }\n\n        return true;\n    }\n\n    /**\n     * 检测上传文件后缀\n     * @param  array|string   $ext    允许后缀\n     * @return bool\n     */\n    public function checkExt($ext)\n    {\n        if (is_string($ext)) {\n            $ext = explode(',', $ext);\n        }\n        $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION));\n        if (!in_array($extension, $ext)) {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * 检测图像文件\n     * @return bool\n     */\n    public function checkImg()\n    {\n        $extension = strtolower(pathinfo($this->getInfo('name'), PATHINFO_EXTENSION));\n        /* 对图像文件进行严格检测 */\n        if (in_array($extension, ['gif', 'jpg', 'jpeg', 'bmp', 'png', 'swf']) && !in_array($this->getImageType($this->filename), [1, 2, 3, 4, 6])) {\n            return false;\n        }\n        return true;\n    }\n\n    // 判断图像类型\n    protected function getImageType($image)\n    {\n        if (function_exists('exif_imagetype')) {\n            return exif_imagetype($image);\n        } else {\n            $info = getimagesize($image);\n            return $info[2];\n        }\n    }\n\n    /**\n     * 检测上传文件大小\n     * @param  integer   $size    最大大小\n     * @return bool\n     */\n    public function checkSize($size)\n    {\n        if ($this->getSize() > $size) {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * 检测上传文件类型\n     * @param  array|string   $mime    允许类型\n     * @return bool\n     */\n    public function checkMime($mime)\n    {\n        if (is_string($mime)) {\n            $mime = explode(',', $mime);\n        }\n        if (!in_array(strtolower($this->getMime()), $mime)) {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * 移动文件\n     * @param  string           $path    保存路径\n     * @param  string|bool      $savename    保存的文件名 默认自动生成\n     * @param  boolean          $replace 同名文件是否覆盖\n     * @return false|File false-失败 否则返回File实例\n     */\n    public function move($path, $savename = true, $replace = true)\n    {\n        // 文件上传失败，捕获错误代码\n        if (!empty($this->info['error'])) {\n            $this->error($this->info['error']);\n            return false;\n        }\n\n        // 检测合法性\n        if (!$this->isValid()) {\n            $this->error = '非法上传文件';\n            return false;\n        }\n\n        // 验证上传\n        if (!$this->check()) {\n            return false;\n        }\n        $path = rtrim($path, DS) . DS;\n        // 文件保存命名规则\n        $saveName = $this->buildSaveName($savename);\n        $filename = $path . $saveName;\n\n        // 检测目录\n        if (false === $this->checkPath(dirname($filename))) {\n            return false;\n        }\n\n        /* 不覆盖同名文件 */\n        if (!$replace && is_file($filename)) {\n            $this->error = '存在同名文件' . $filename;\n            return false;\n        }\n\n        /* 移动文件 */\n        if ($this->isTest) {\n            rename($this->filename, $filename);\n        } elseif (!move_uploaded_file($this->filename, $filename)) {\n            $this->error = '文件上传保存错误！';\n            return false;\n        }\n        // 返回 File对象实例\n        $file = new self($filename);\n        $file->setSaveName($saveName);\n        $file->setUploadInfo($this->info);\n        return $file;\n    }\n\n    /**\n     * 获取保存文件名\n     * @param  string|bool   $savename    保存的文件名 默认自动生成\n     * @return string\n     */\n    protected function buildSaveName($savename)\n    {\n        if (true === $savename) {\n            // 自动生成文件名\n            if ($this->rule instanceof \\Closure) {\n                $savename = call_user_func_array($this->rule, [$this]);\n            } else {\n                switch ($this->rule) {\n                    case 'date':\n                        $savename = date('Ymd') . DS . md5(microtime(true));\n                        break;\n                    default:\n                        if (in_array($this->rule, hash_algos())) {\n                            $hash     = $this->hash($this->rule);\n                            $savename = substr($hash, 0, 2) . DS . substr($hash, 2);\n                        } elseif (is_callable($this->rule)) {\n                            $savename = call_user_func($this->rule);\n                        } else {\n                            $savename = date('Ymd') . DS . md5(microtime(true));\n                        }\n                }\n            }\n        } elseif ('' === $savename) {\n            $savename = $this->getInfo('name');\n        }\n        if (!strpos($savename, '.')) {\n            $savename .= '.' . pathinfo($this->getInfo('name'), PATHINFO_EXTENSION);\n        }\n        return $savename;\n    }\n\n    /**\n     * 获取错误代码信息\n     * @param int $errorNo  错误号\n     */\n    private function error($errorNo)\n    {\n        switch ($errorNo) {\n            case 1:\n            case 2:\n                $this->error = '上传文件大小超过了最大值！';\n                break;\n            case 3:\n                $this->error = '文件只有部分被上传！';\n                break;\n            case 4:\n                $this->error = '没有文件被上传！';\n                break;\n            case 6:\n                $this->error = '找不到临时文件夹！';\n                break;\n            case 7:\n                $this->error = '文件写入失败！';\n                break;\n            default:\n                $this->error = '未知上传错误！';\n        }\n    }\n\n    /**\n     * 获取错误信息\n     * @return mixed\n     */\n    public function getError()\n    {\n        return $this->error;\n    }\n\n    public function __call($method, $args)\n    {\n        return $this->hash($method);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Hook.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nclass Hook\n{\n\n    private static $tags = [];\n\n    /**\n     * 动态添加行为扩展到某个标签\n     * @param string    $tag 标签名称\n     * @param mixed     $behavior 行为名称\n     * @param bool      $first 是否放到开头执行\n     * @return void\n     */\n    public static function add($tag, $behavior, $first = false)\n    {\n        isset(self::$tags[$tag]) || self::$tags[$tag] = [];\n        if (is_array($behavior) && !is_callable($behavior)) {\n            if (!array_key_exists('_overlay', $behavior) || !$behavior['_overlay']) {\n                unset($behavior['_overlay']);\n                self::$tags[$tag] = array_merge(self::$tags[$tag], $behavior);\n            } else {\n                unset($behavior['_overlay']);\n                self::$tags[$tag] = $behavior;\n            }\n        } elseif ($first) {\n            array_unshift(self::$tags[$tag], $behavior);\n        } else {\n            self::$tags[$tag][] = $behavior;\n        }\n    }\n\n    /**\n     * 批量导入插件\n     * @param array        $tags 插件信息\n     * @param boolean     $recursive 是否递归合并\n     */\n    public static function import(array $tags, $recursive = true)\n    {\n        if ($recursive) {\n            foreach ($tags as $tag => $behavior) {\n                self::add($tag, $behavior);\n            }\n        } else {\n            self::$tags = $tags + self::$tags;\n        }\n    }\n\n    /**\n     * 获取插件信息\n     * @param string $tag 插件位置 留空获取全部\n     * @return array\n     */\n    public static function get($tag = '')\n    {\n        if (empty($tag)) {\n            //获取全部的插件信息\n            return self::$tags;\n        } else {\n            return array_key_exists($tag, self::$tags) ? self::$tags[$tag] : [];\n        }\n    }\n\n    /**\n     * 监听标签的行为\n     * @param string $tag    标签名称\n     * @param mixed  $params 传入参数\n     * @param mixed  $extra  额外参数\n     * @param bool   $once   只获取一个有效返回值\n     * @return mixed\n     */\n    public static function listen($tag, &$params = null, $extra = null, $once = false)\n    {\n        $results = [];\n        $tags    = static::get($tag);\n        foreach ($tags as $key => $name) {\n            $results[$key] = self::exec($name, $tag, $params, $extra);\n            if (false === $results[$key]) {\n                // 如果返回false 则中断行为执行\n                break;\n            } elseif (!is_null($results[$key]) && $once) {\n                break;\n            }\n        }\n        return $once ? end($results) : $results;\n    }\n\n    /**\n     * 执行某个行为\n     * @param mixed     $class 要执行的行为\n     * @param string    $tag 方法名（标签名）\n     * @param Mixed     $params 传人的参数\n     * @param mixed     $extra 额外参数\n     * @return mixed\n     */\n    public static function exec($class, $tag = '', &$params = null, $extra = null)\n    {\n        App::$debug && Debug::remark('behavior_start', 'time');\n        $method = Loader::parseName($tag, 1, false);\n        if ($class instanceof \\Closure) {\n            $result = call_user_func_array($class, [ & $params, $extra]);\n            $class  = 'Closure';\n        } elseif (is_array($class)) {\n            list($class, $method) = $class;\n\n            $result = (new $class())->$method($params, $extra);\n            $class  = $class . '->' . $method;\n        } elseif (is_object($class)) {\n            $result = $class->$method($params, $extra);\n            $class  = get_class($class);\n        } elseif (strpos($class, '::')) {\n            $result = call_user_func_array($class, [ & $params, $extra]);\n        } else {\n            $obj    = new $class();\n            $method = ($tag && is_callable([$obj, $method])) ? $method : 'run';\n            $result = $obj->$method($params, $extra);\n        }\n        if (App::$debug) {\n            Debug::remark('behavior_end', 'time');\n            Log::record('[ BEHAVIOR ] Run ' . $class . ' @' . $tag . ' [ RunTime:' . Debug::getRangeTime('behavior_start', 'behavior_end') . 's ]', 'info');\n        }\n        return $result;\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/Lang.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nclass Lang\n{\n    // 语言数据\n    private static $lang = [];\n    // 语言作用域\n    private static $range = 'zh-cn';\n    // 语言自动侦测的变量\n    protected static $langDetectVar = 'lang';\n    // 语言Cookie变量\n    protected static $langCookieVar = 'think_var';\n    // 语言Cookie的过期时间\n    protected static $langCookieExpire = 3600;\n    // 允许语言列表\n    protected static $allowLangList = [];\n    // Accept-Language转义为对应语言包名称 系统默认配置\n    protected static $acceptLanguage = [\n        'zh-hans-cn' => 'zh-cn',\n    ];\n\n    // 设定当前的语言\n    public static function range($range = '')\n    {\n        if ('' == $range) {\n            return self::$range;\n        } else {\n            self::$range = $range;\n        }\n        return self::$range;\n    }\n\n    /**\n     * 设置语言定义(不区分大小写)\n     * @param string|array  $name 语言变量\n     * @param string        $value 语言值\n     * @param string        $range 语言作用域\n     * @return mixed\n     */\n    public static function set($name, $value = null, $range = '')\n    {\n        $range = $range ?: self::$range;\n        // 批量定义\n        if (!isset(self::$lang[$range])) {\n            self::$lang[$range] = [];\n        }\n        if (is_array($name)) {\n            return self::$lang[$range] = array_change_key_case($name) + self::$lang[$range];\n        } else {\n            return self::$lang[$range][strtolower($name)] = $value;\n        }\n    }\n\n    /**\n     * 加载语言定义(不区分大小写)\n     * @param string $file 语言文件\n     * @param string $range 语言作用域\n     * @return mixed\n     */\n    public static function load($file, $range = '')\n    {\n        $range = $range ?: self::$range;\n        if (!isset(self::$lang[$range])) {\n            self::$lang[$range] = [];\n        }\n        // 批量定义\n        if (is_string($file)) {\n            $file = [$file];\n        }\n        $lang = [];\n        foreach ($file as $_file) {\n            if (is_file($_file)) {\n                // 记录加载信息\n                App::$debug && Log::record('[ LANG ] ' . $_file, 'info');\n                $_lang = include $_file;\n                if (is_array($_lang)) {\n                    $lang = array_change_key_case($_lang) + $lang;\n                }\n            }\n        }\n        if (!empty($lang)) {\n            self::$lang[$range] = $lang + self::$lang[$range];\n        }\n        return self::$lang[$range];\n    }\n\n    /**\n     * 获取语言定义(不区分大小写)\n     * @param string|null   $name 语言变量\n     * @param string        $range 语言作用域\n     * @return mixed\n     */\n    public static function has($name, $range = '')\n    {\n        $range = $range ?: self::$range;\n        return isset(self::$lang[$range][strtolower($name)]);\n    }\n\n    /**\n     * 获取语言定义(不区分大小写)\n     * @param string|null   $name 语言变量\n     * @param array         $vars 变量替换\n     * @param string        $range 语言作用域\n     * @return mixed\n     */\n    public static function get($name = null, $vars = [], $range = '')\n    {\n        $range = $range ?: self::$range;\n        // 空参数返回所有定义\n        if (empty($name)) {\n            return self::$lang[$range];\n        }\n        $key   = strtolower($name);\n        $value = isset(self::$lang[$range][$key]) ? self::$lang[$range][$key] : $name;\n\n        // 变量解析\n        if (!empty($vars) && is_array($vars)) {\n            /**\n             * Notes:\n             * 为了检测的方便，数字索引的判断仅仅是参数数组的第一个元素的key为数字0\n             * 数字索引采用的是系统的 sprintf 函数替换，用法请参考 sprintf 函数\n             */\n            if (key($vars) === 0) {\n                // 数字索引解析\n                array_unshift($vars, $value);\n                $value = call_user_func_array('sprintf', $vars);\n            } else {\n                // 关联索引解析\n                $replace = array_keys($vars);\n                foreach ($replace as &$v) {\n                    $v = \"{:{$v}}\";\n                }\n                $value = str_replace($replace, $vars, $value);\n            }\n\n        }\n        return $value;\n    }\n\n    /**\n     * 自动侦测设置获取语言选择\n     * @return string\n     */\n    public static function detect()\n    {\n        // 自动侦测设置获取语言选择\n        $langSet = '';\n\n        if (isset($_GET[self::$langDetectVar])) {\n            // url中设置了语言变量\n            $langSet = strtolower($_GET[self::$langDetectVar]);\n        } elseif (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {\n            // 自动侦测浏览器语言\n            preg_match('/^([a-z\\d\\-]+)/i', $_SERVER['HTTP_ACCEPT_LANGUAGE'], $matches);\n            $langSet     = strtolower($matches[1]);\n            $acceptLangs = Config::get('header_accept_lang');\n            if (isset($acceptLangs[$langSet])) {\n                $langSet = $acceptLangs[$langSet];\n            } elseif (isset(self::$acceptLanguage[$langSet])) {\n                $langSet = self::$acceptLanguage[$langSet];\n            }\n        }\n        if (empty(self::$allowLangList) || in_array($langSet, self::$allowLangList)) {\n            // 合法的语言\n            self::$range = $langSet ?: self::$range;\n        }\n        return self::$range;\n    }\n\n    /**\n     * 设置语言自动侦测的变量\n     * @param string $var 变量名称\n     * @return void\n     */\n    public static function setLangDetectVar($var)\n    {\n        self::$langDetectVar = $var;\n    }\n\n    /**\n     * 设置语言的cookie保存变量\n     * @param string $var 变量名称\n     * @return void\n     */\n    public static function setLangCookieVar($var)\n    {\n        self::$langCookieVar = $var;\n    }\n\n    /**\n     * 设置语言的cookie的过期时间\n     * @param string $expire 过期时间\n     * @return void\n     */\n    public static function setLangCookieExpire($expire)\n    {\n        self::$langCookieExpire = $expire;\n    }\n\n    /**\n     * 设置允许的语言列表\n     * @param array $list 语言列表\n     * @return void\n     */\n    public static function setAllowLangList($list)\n    {\n        self::$allowLangList = $list;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Loader.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\exception\\ClassNotFoundException;\n\nclass Loader\n{\n    protected static $instance = [];\n    // 类名映射\n    protected static $map = [];\n\n    // 命名空间别名\n    protected static $namespaceAlias = [];\n\n    // PSR-4\n    private static $prefixLengthsPsr4 = [];\n    private static $prefixDirsPsr4    = [];\n    private static $fallbackDirsPsr4  = [];\n\n    // PSR-0\n    private static $prefixesPsr0     = [];\n    private static $fallbackDirsPsr0 = [];\n\n    // 自动加载的文件\n    private static $autoloadFiles = [];\n\n    // 自动加载\n    public static function autoload($class)\n    {\n        // 检测命名空间别名\n        if (!empty(self::$namespaceAlias)) {\n            $namespace = dirname($class);\n            if (isset(self::$namespaceAlias[$namespace])) {\n                $original = self::$namespaceAlias[$namespace] . '\\\\' . basename($class);\n                if (class_exists($original)) {\n                    return class_alias($original, $class, false);\n                }\n            }\n        }\n\n        if ($file = self::findFile($class)) {\n\n            // Win环境严格区分大小写\n            if (IS_WIN && pathinfo($file, PATHINFO_FILENAME) != pathinfo(realpath($file), PATHINFO_FILENAME)) {\n                return false;\n            }\n\n            __include_file($file);\n            return true;\n        }\n    }\n\n    /**\n     * 查找文件\n     * @param $class\n     * @return bool\n     */\n    private static function findFile($class)\n    {\n        if (!empty(self::$map[$class])) {\n            // 类库映射\n            return self::$map[$class];\n        }\n\n        // 查找 PSR-4\n        $logicalPathPsr4 = strtr($class, '\\\\', DS) . EXT;\n\n        $first = $class[0];\n        if (isset(self::$prefixLengthsPsr4[$first])) {\n            foreach (self::$prefixLengthsPsr4[$first] as $prefix => $length) {\n                if (0 === strpos($class, $prefix)) {\n                    foreach (self::$prefixDirsPsr4[$prefix] as $dir) {\n                        if (is_file($file = $dir . DS . substr($logicalPathPsr4, $length))) {\n                            return $file;\n                        }\n                    }\n                }\n            }\n        }\n\n        // 查找 PSR-4 fallback dirs\n        foreach (self::$fallbackDirsPsr4 as $dir) {\n            if (is_file($file = $dir . DS . $logicalPathPsr4)) {\n                return $file;\n            }\n        }\n\n        // 查找 PSR-0\n        if (false !== $pos = strrpos($class, '\\\\')) {\n            // namespaced class name\n            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)\n            . strtr(substr($logicalPathPsr4, $pos + 1), '_', DS);\n        } else {\n            // PEAR-like class name\n            $logicalPathPsr0 = strtr($class, '_', DS) . EXT;\n        }\n\n        if (isset(self::$prefixesPsr0[$first])) {\n            foreach (self::$prefixesPsr0[$first] as $prefix => $dirs) {\n                if (0 === strpos($class, $prefix)) {\n                    foreach ($dirs as $dir) {\n                        if (is_file($file = $dir . DS . $logicalPathPsr0)) {\n                            return $file;\n                        }\n                    }\n                }\n            }\n        }\n\n        // 查找 PSR-0 fallback dirs\n        foreach (self::$fallbackDirsPsr0 as $dir) {\n            if (is_file($file = $dir . DS . $logicalPathPsr0)) {\n                return $file;\n            }\n        }\n\n        return self::$map[$class] = false;\n    }\n\n    // 注册classmap\n    public static function addClassMap($class, $map = '')\n    {\n        if (is_array($class)) {\n            self::$map = array_merge(self::$map, $class);\n        } else {\n            self::$map[$class] = $map;\n        }\n    }\n\n    // 注册命名空间\n    public static function addNamespace($namespace, $path = '')\n    {\n        if (is_array($namespace)) {\n            foreach ($namespace as $prefix => $paths) {\n                self::addPsr4($prefix . '\\\\', rtrim($paths, DS), true);\n            }\n        } else {\n            self::addPsr4($namespace . '\\\\', rtrim($path, DS), true);\n        }\n    }\n\n    // 添加Ps0空间\n    private static function addPsr0($prefix, $paths, $prepend = false)\n    {\n        if (!$prefix) {\n            if ($prepend) {\n                self::$fallbackDirsPsr0 = array_merge(\n                    (array) $paths,\n                    self::$fallbackDirsPsr0\n                );\n            } else {\n                self::$fallbackDirsPsr0 = array_merge(\n                    self::$fallbackDirsPsr0,\n                    (array) $paths\n                );\n            }\n\n            return;\n        }\n\n        $first = $prefix[0];\n        if (!isset(self::$prefixesPsr0[$first][$prefix])) {\n            self::$prefixesPsr0[$first][$prefix] = (array) $paths;\n\n            return;\n        }\n        if ($prepend) {\n            self::$prefixesPsr0[$first][$prefix] = array_merge(\n                (array) $paths,\n                self::$prefixesPsr0[$first][$prefix]\n            );\n        } else {\n            self::$prefixesPsr0[$first][$prefix] = array_merge(\n                self::$prefixesPsr0[$first][$prefix],\n                (array) $paths\n            );\n        }\n    }\n\n    // 添加Psr4空间\n    private static function addPsr4($prefix, $paths, $prepend = false)\n    {\n        if (!$prefix) {\n            // Register directories for the root namespace.\n            if ($prepend) {\n                self::$fallbackDirsPsr4 = array_merge(\n                    (array) $paths,\n                    self::$fallbackDirsPsr4\n                );\n            } else {\n                self::$fallbackDirsPsr4 = array_merge(\n                    self::$fallbackDirsPsr4,\n                    (array) $paths\n                );\n            }\n        } elseif (!isset(self::$prefixDirsPsr4[$prefix])) {\n            // Register directories for a new namespace.\n            $length = strlen($prefix);\n            if ('\\\\' !== $prefix[$length - 1]) {\n                throw new \\InvalidArgumentException(\"A non-empty PSR-4 prefix must end with a namespace separator.\");\n            }\n            self::$prefixLengthsPsr4[$prefix[0]][$prefix] = $length;\n            self::$prefixDirsPsr4[$prefix]                = (array) $paths;\n        } elseif ($prepend) {\n            // Prepend directories for an already registered namespace.\n            self::$prefixDirsPsr4[$prefix] = array_merge(\n                (array) $paths,\n                self::$prefixDirsPsr4[$prefix]\n            );\n        } else {\n            // Append directories for an already registered namespace.\n            self::$prefixDirsPsr4[$prefix] = array_merge(\n                self::$prefixDirsPsr4[$prefix],\n                (array) $paths\n            );\n        }\n    }\n\n    // 注册命名空间别名\n    public static function addNamespaceAlias($namespace, $original = '')\n    {\n        if (is_array($namespace)) {\n            self::$namespaceAlias = array_merge(self::$namespaceAlias, $namespace);\n        } else {\n            self::$namespaceAlias[$namespace] = $original;\n        }\n    }\n\n    // 注册自动加载机制\n    public static function register($autoload = '')\n    {\n        // 注册系统自动加载\n        spl_autoload_register($autoload ?: 'think\\\\Loader::autoload', true, true);\n        // 注册命名空间定义\n        self::addNamespace([\n            'think'    => LIB_PATH . 'think' . DS,\n            'behavior' => LIB_PATH . 'behavior' . DS,\n            'traits'   => LIB_PATH . 'traits' . DS,\n        ]);\n        // 加载类库映射文件\n        if (is_file(RUNTIME_PATH . 'classmap' . EXT)) {\n            self::addClassMap(__include_file(RUNTIME_PATH . 'classmap' . EXT));\n        }\n\n        // Composer自动加载支持\n        if (is_dir(VENDOR_PATH . 'composer')) {\n            self::registerComposerLoader();\n        }\n\n        // 自动加载extend目录\n        self::$fallbackDirsPsr4[] = rtrim(EXTEND_PATH, DS);\n    }\n\n    // 注册composer自动加载\n    private static function registerComposerLoader()\n    {\n        if (is_file(VENDOR_PATH . 'composer/autoload_namespaces.php')) {\n            $map = require VENDOR_PATH . 'composer/autoload_namespaces.php';\n            foreach ($map as $namespace => $path) {\n                self::addPsr0($namespace, $path);\n            }\n        }\n\n        if (is_file(VENDOR_PATH . 'composer/autoload_psr4.php')) {\n            $map = require VENDOR_PATH . 'composer/autoload_psr4.php';\n            foreach ($map as $namespace => $path) {\n                self::addPsr4($namespace, $path);\n            }\n        }\n\n        if (is_file(VENDOR_PATH . 'composer/autoload_classmap.php')) {\n            $classMap = require VENDOR_PATH . 'composer/autoload_classmap.php';\n            if ($classMap) {\n                self::addClassMap($classMap);\n            }\n        }\n\n        if (is_file(VENDOR_PATH . 'composer/autoload_files.php')) {\n            $includeFiles = require VENDOR_PATH . 'composer/autoload_files.php';\n            foreach ($includeFiles as $fileIdentifier => $file) {\n                if (empty(self::$autoloadFiles[$fileIdentifier])) {\n                    __require_file($file);\n                    self::$autoloadFiles[$fileIdentifier] = true;\n                }\n            }\n        }\n    }\n\n    /**\n     * 导入所需的类库 同java的Import 本函数有缓存功能\n     * @param string $class   类库命名空间字符串\n     * @param string $baseUrl 起始路径\n     * @param string $ext     导入的文件扩展名\n     * @return boolean\n     */\n    public static function import($class, $baseUrl = '', $ext = EXT)\n    {\n        static $_file = [];\n        $key          = $class . $baseUrl;\n        $class        = str_replace(['.', '#'], [DS, '.'], $class);\n        if (isset($_file[$key])) {\n            return true;\n        }\n\n        if (empty($baseUrl)) {\n            list($name, $class) = explode(DS, $class, 2);\n\n            if (isset(self::$prefixDirsPsr4[$name . '\\\\'])) {\n                // 注册的命名空间\n                $baseUrl = self::$prefixDirsPsr4[$name . '\\\\'];\n            } elseif ('@' == $name) {\n                //加载当前模块应用类库\n                $baseUrl = App::$modulePath;\n            } elseif (is_dir(EXTEND_PATH . $name)) {\n                $baseUrl = EXTEND_PATH . $name . DS;\n            } else {\n                // 加载其它模块的类库\n                $baseUrl = APP_PATH . $name . DS;\n            }\n        } elseif (substr($baseUrl, -1) != DS) {\n            $baseUrl .= DS;\n        }\n        // 如果类存在 则导入类库文件\n        if (is_array($baseUrl)) {\n            foreach ($baseUrl as $path) {\n                $filename = $path . DS . $class . $ext;\n                if (is_file($filename)) {\n                    break;\n                }\n            }\n        } else {\n            $filename = $baseUrl . $class . $ext;\n        }\n\n        if (!empty($filename) && is_file($filename)) {\n            // 开启调试模式Win环境严格区分大小写\n            if (IS_WIN && pathinfo($filename, PATHINFO_FILENAME) != pathinfo(realpath($filename), PATHINFO_FILENAME)) {\n                return false;\n            }\n            __include_file($filename);\n            $_file[$key] = true;\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 实例化（分层）模型\n     * @param string $name         Model名称\n     * @param string $layer        业务层名称\n     * @param bool   $appendSuffix 是否添加类名后缀\n     * @param string $common       公共模块名\n     * @return Object\n     * @throws ClassNotFoundException\n     */\n    public static function model($name = '', $layer = 'model', $appendSuffix = false, $common = 'common')\n    {\n        $guid = $name . $layer;\n        if (isset(self::$instance[$guid])) {\n            return self::$instance[$guid];\n        }\n        if (false !== strpos($name, '\\\\')) {\n            $class  = $name;\n            $module = Request::instance()->module();\n        } else {\n            if (strpos($name, '/')) {\n                list($module, $name) = explode('/', $name, 2);\n            } else {\n                $module = Request::instance()->module();\n            }\n            $class = self::parseClass($module, $layer, $name, $appendSuffix);\n        }\n        if (class_exists($class)) {\n            $model = new $class();\n        } else {\n            $class = str_replace('\\\\' . $module . '\\\\', '\\\\' . $common . '\\\\', $class);\n            if (class_exists($class)) {\n                $model = new $class();\n            } else {\n                throw new ClassNotFoundException('class not exists:' . $class, $class);\n            }\n        }\n        self::$instance[$guid] = $model;\n        return $model;\n    }\n\n    /**\n     * 实例化（分层）控制器 格式：[模块名/]控制器名\n     * @param string $name         资源地址\n     * @param string $layer        控制层名称\n     * @param bool   $appendSuffix 是否添加类名后缀\n     * @param string $empty        空控制器名称\n     * @return Object|false\n     * @throws ClassNotFoundException\n     */\n    public static function controller($name, $layer = 'controller', $appendSuffix = false, $empty = '')\n    {\n        if (false !== strpos($name, '\\\\')) {\n            $class  = $name;\n            $module = Request::instance()->module();\n        } else {\n            if (strpos($name, '/')) {\n                list($module, $name) = explode('/', $name);\n            } else {\n                $module = Request::instance()->module();\n            }\n            $class = self::parseClass($module, $layer, $name, $appendSuffix);\n        }\n        if (class_exists($class)) {\n            return App::invokeClass($class);\n        } elseif ($empty && class_exists($emptyClass = self::parseClass($module, $layer, $empty, $appendSuffix))) {\n            return new $emptyClass(Request::instance());\n        }\n    }\n\n    /**\n     * 实例化验证类 格式：[模块名/]验证器名\n     * @param string $name         资源地址\n     * @param string $layer        验证层名称\n     * @param bool   $appendSuffix 是否添加类名后缀\n     * @param string $common       公共模块名\n     * @return Object|false\n     * @throws ClassNotFoundException\n     */\n    public static function validate($name = '', $layer = 'validate', $appendSuffix = false, $common = 'common')\n    {\n        $name = $name ?: Config::get('default_validate');\n        if (empty($name)) {\n            return new Validate;\n        }\n        $guid = $name . $layer;\n        if (isset(self::$instance[$guid])) {\n            return self::$instance[$guid];\n        }\n        if (false !== strpos($name, '\\\\')) {\n            $class  = $name;\n            $module = Request::instance()->module();\n        } else {\n            if (strpos($name, '/')) {\n                list($module, $name) = explode('/', $name);\n            } else {\n                $module = Request::instance()->module();\n            }\n            $class = self::parseClass($module, $layer, $name, $appendSuffix);\n        }\n        if (class_exists($class)) {\n            $validate = new $class;\n        } else {\n            $class = str_replace('\\\\' . $module . '\\\\', '\\\\' . $common . '\\\\', $class);\n            if (class_exists($class)) {\n                $validate = new $class;\n            } else {\n                throw new ClassNotFoundException('class not exists:' . $class, $class);\n            }\n        }\n        self::$instance[$guid] = $validate;\n        return $validate;\n    }\n\n    /**\n     * 数据库初始化 并取得数据库类实例\n     * @param mixed         $config 数据库配置\n     * @param bool|string   $name 连接标识 true 强制重新连接\n     * @return \\think\\db\\Connection\n     */\n    public static function db($config = [], $name = false)\n    {\n        return Db::connect($config, $name);\n    }\n\n    /**\n     * 远程调用模块的操作方法 参数格式 [模块/控制器/]操作\n     * @param string       $url          调用地址\n     * @param string|array $vars         调用参数 支持字符串和数组\n     * @param string       $layer        要调用的控制层名称\n     * @param bool         $appendSuffix 是否添加类名后缀\n     * @return mixed\n     */\n    public static function action($url, $vars = [], $layer = 'controller', $appendSuffix = false)\n    {\n        $info   = pathinfo($url);\n        $action = $info['basename'];\n        $module = '.' != $info['dirname'] ? $info['dirname'] : Request::instance()->controller();\n        $class  = self::controller($module, $layer, $appendSuffix);\n        if ($class) {\n            if (is_scalar($vars)) {\n                if (strpos($vars, '=')) {\n                    parse_str($vars, $vars);\n                } else {\n                    $vars = [$vars];\n                }\n            }\n            return App::invokeMethod([$class, $action . Config::get('action_suffix')], $vars);\n        }\n    }\n\n    /**\n     * 字符串命名风格转换\n     * type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格\n     * @param string  $name 字符串\n     * @param integer $type 转换类型\n     * @param bool    $ucfirst 首字母是否大写（驼峰规则）\n     * @return string\n     */\n    public static function parseName($name, $type = 0, $ucfirst = true)\n    {\n        if ($type) {\n            $name = preg_replace_callback('/_([a-zA-Z])/', function ($match) {\n                return strtoupper($match[1]);\n            }, $name);\n            return $ucfirst ? ucfirst($name) : lcfirst($name);\n        } else {\n            return strtolower(trim(preg_replace(\"/[A-Z]/\", \"_\\\\0\", $name), \"_\"));\n        }\n    }\n\n    /**\n     * 解析应用类的类名\n     * @param string $module 模块名\n     * @param string $layer  层名 controller model ...\n     * @param string $name   类名\n     * @param bool   $appendSuffix\n     * @return string\n     */\n    public static function parseClass($module, $layer, $name, $appendSuffix = false)\n    {\n        $name  = str_replace(['/', '.'], '\\\\', $name);\n        $array = explode('\\\\', $name);\n        $class = self::parseName(array_pop($array), 1) . (App::$suffix || $appendSuffix ? ucfirst($layer) : '');\n        $path  = $array ? implode('\\\\', $array) . '\\\\' : '';\n        return App::$namespace . '\\\\' . ($module ? $module . '\\\\' : '') . $layer . '\\\\' . $path . $class;\n    }\n\n    /**\n     * 初始化类的实例\n     * @return void\n     */\n    public static function clearInstance()\n    {\n        self::$instance = [];\n    }\n}\n\n/**\n * 作用范围隔离\n *\n * @param $file\n * @return mixed\n */\nfunction __include_file($file)\n{\n    return include $file;\n}\n\nfunction __require_file($file)\n{\n    return require $file;\n}\n"
  },
  {
    "path": "thinkphp/library/think/Log.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\exception\\ClassNotFoundException;\n\n/**\n * Class Log\n * @package think\n *\n * @method void log($msg) static\n * @method void error($msg) static\n * @method void info($msg) static\n * @method void sql($msg) static\n * @method void notice($msg) static\n * @method void alert($msg) static\n */\nclass Log\n{\n    const LOG    = 'log';\n    const ERROR  = 'error';\n    const INFO   = 'info';\n    const SQL    = 'sql';\n    const NOTICE = 'notice';\n    const ALERT  = 'alert';\n    const DEBUG  = 'debug';\n\n    // 日志信息\n    protected static $log = [];\n    // 配置参数\n    protected static $config = [];\n    // 日志类型\n    protected static $type = ['log', 'error', 'info', 'sql', 'notice', 'alert', 'debug'];\n    // 日志写入驱动\n    protected static $driver;\n\n    // 当前日志授权key\n    protected static $key;\n\n    /**\n     * 日志初始化\n     * @param array $config\n     */\n    public static function init($config = [])\n    {\n        $type         = isset($config['type']) ? $config['type'] : 'File';\n        $class        = false !== strpos($type, '\\\\') ? $type : '\\\\think\\\\log\\\\driver\\\\' . ucwords($type);\n        self::$config = $config;\n        unset($config['type']);\n        if (class_exists($class)) {\n            self::$driver = new $class($config);\n        } else {\n            throw new ClassNotFoundException('class not exists:' . $class, $class);\n        }\n        // 记录初始化信息\n        App::$debug && Log::record('[ LOG ] INIT ' . $type, 'info');\n    }\n\n    /**\n     * 获取日志信息\n     * @param string $type 信息类型\n     * @return array\n     */\n    public static function getLog($type = '')\n    {\n        return $type ? self::$log[$type] : self::$log;\n    }\n\n    /**\n     * 记录调试信息\n     * @param mixed  $msg  调试信息\n     * @param string $type 信息类型\n     * @return void\n     */\n    public static function record($msg, $type = 'log')\n    {\n        self::$log[$type][] = $msg;\n        if (IS_CLI) {\n            // 命令行下面日志写入改进\n            self::save();\n        }\n    }\n\n    /**\n     * 清空日志信息\n     * @return void\n     */\n    public static function clear()\n    {\n        self::$log = [];\n    }\n\n    /**\n     * 当前日志记录的授权key\n     * @param string $key 授权key\n     * @return void\n     */\n    public static function key($key)\n    {\n        self::$key = $key;\n    }\n\n    /**\n     * 检查日志写入权限\n     * @param array $config 当前日志配置参数\n     * @return bool\n     */\n    public static function check($config)\n    {\n        if (self::$key && !empty($config['allow_key']) && !in_array(self::$key, $config['allow_key'])) {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * 保存调试信息\n     * @return bool\n     */\n    public static function save()\n    {\n        if (!empty(self::$log)) {\n            if (is_null(self::$driver)) {\n                self::init(Config::get('log'));\n            }\n\n            if (!self::check(self::$config)) {\n                // 检测日志写入权限\n                return false;\n            }\n\n            if (empty(self::$config['level'])) {\n                // 获取全部日志\n                $log = self::$log;\n                if (!App::$debug && isset($log['debug'])) {\n                    unset($log['debug']);\n                }\n            } else {\n                // 记录允许级别\n                $log = [];\n                foreach (self::$config['level'] as $level) {\n                    if (isset(self::$log[$level])) {\n                        $log[$level] = self::$log[$level];\n                    }\n                }\n            }\n\n            $result = self::$driver->save($log);\n            if ($result) {\n                self::$log = [];\n            }\n\n            return $result;\n        }\n        return true;\n    }\n\n    /**\n     * 实时写入日志信息 并支持行为\n     * @param mixed  $msg   调试信息\n     * @param string $type  信息类型\n     * @param bool   $force 是否强制写入\n     * @return bool\n     */\n    public static function write($msg, $type = 'log', $force = false)\n    {\n        $log = self::$log;\n        // 封装日志信息\n        if (true === $force || empty(self::$config['level'])) {\n            $log[$type][] = $msg;\n        } elseif (in_array($type, self::$config['level'])) {\n            $log[$type][] = $msg;\n        } else {\n            return false;\n        }\n\n        // 监听log_write\n        Hook::listen('log_write', $log);\n        if (is_null(self::$driver)) {\n            self::init(Config::get('log'));\n        }\n        // 写入日志\n        $result = self::$driver->save($log);\n        if ($result) {\n            self::$log = [];\n        }\n        return $result;\n    }\n\n    /**\n     * 静态调用\n     * @param $method\n     * @param $args\n     * @return mixed\n     */\n    public static function __callStatic($method, $args)\n    {\n        if (in_array($method, self::$type)) {\n            array_push($args, $method);\n            return call_user_func_array('\\\\think\\\\Log::record', $args);\n        }\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/Model.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse InvalidArgumentException;\nuse think\\db\\Query;\nuse think\\Exception\\ValidateException;\nuse think\\model\\Collection as ModelCollection;\nuse think\\model\\Relation;\nuse think\\model\\relation\\BelongsTo;\nuse think\\model\\relation\\BelongsToMany;\nuse think\\model\\relation\\HasMany;\nuse think\\model\\relation\\HasManyThrough;\nuse think\\model\\relation\\HasOne;\nuse think\\model\\relation\\MorphMany;\nuse think\\model\\relation\\MorphOne;\nuse think\\model\\relation\\MorphTo;\n\n/**\n * Class Model\n * @package think\n * @mixin Query\n */\nabstract class Model implements \\JsonSerializable, \\ArrayAccess\n{\n    // 数据库查询对象池\n    protected static $links = [];\n    // 数据库配置\n    protected $connection = [];\n    // 父关联模型对象\n    protected $parent;\n    // 数据库查询对象\n    protected $query;\n    // 当前模型名称\n    protected $name;\n    // 数据表名称\n    protected $table;\n    // 当前类名称\n    protected $class;\n    // 回调事件\n    private static $event = [];\n    // 错误信息\n    protected $error;\n    // 字段验证规则\n    protected $validate;\n    // 数据表主键 复合主键使用数组定义 不设置则自动获取\n    protected $pk;\n    // 数据表字段信息 留空则自动获取\n    protected $field = [];\n    // 只读字段\n    protected $readonly = [];\n    // 显示属性\n    protected $visible = [];\n    // 隐藏属性\n    protected $hidden = [];\n    // 追加属性\n    protected $append = [];\n    // 数据信息\n    protected $data = [];\n    // 原始数据\n    protected $origin = [];\n    // 关联模型\n    protected $relation = [];\n\n    // 保存自动完成列表\n    protected $auto = [];\n    // 新增自动完成列表\n    protected $insert = [];\n    // 更新自动完成列表\n    protected $update = [];\n    // 是否需要自动写入时间戳 如果设置为字符串 则表示时间字段的类型\n    protected $autoWriteTimestamp;\n    // 创建时间字段\n    protected $createTime = 'create_time';\n    // 更新时间字段\n    protected $updateTime = 'update_time';\n    // 时间字段取出后的默认时间格式\n    protected $dateFormat;\n    // 字段类型或者格式转换\n    protected $type = [];\n    // 是否为更新数据\n    protected $isUpdate = false;\n    // 更新条件\n    protected $updateWhere;\n    // 验证失败是否抛出异常\n    protected $failException = false;\n    // 全局查询范围\n    protected $useGlobalScope = true;\n    // 是否采用批量验证\n    protected $batchValidate = false;\n    // 查询数据集对象\n    protected $resultSetType;\n    // 关联自动写入\n    protected $relationWrite;\n\n    /**\n     * 初始化过的模型.\n     *\n     * @var array\n     */\n    protected static $initialized = [];\n\n    /**\n     * 构造方法\n     * @access public\n     * @param array|object $data 数据\n     */\n    public function __construct($data = [])\n    {\n        if (is_object($data)) {\n            $this->data = get_object_vars($data);\n        } else {\n            $this->data = $data;\n        }\n        // 记录原始数据\n        $this->origin = $this->data;\n\n        // 当前类名\n        $this->class = get_called_class();\n\n        if (empty($this->name)) {\n            // 当前模型名\n            $name       = str_replace('\\\\', '/', $this->class);\n            $this->name = basename($name);\n            if (Config::get('class_suffix')) {\n                $suffix     = basename(dirname($name));\n                $this->name = substr($this->name, 0, -strlen($suffix));\n            }\n        }\n\n        if (is_null($this->autoWriteTimestamp)) {\n            // 自动写入时间戳\n            $this->autoWriteTimestamp = $this->getQuery()->getConfig('auto_timestamp');\n        }\n\n        if (is_null($this->dateFormat)) {\n            // 设置时间戳格式\n            $this->dateFormat = $this->getQuery()->getConfig('datetime_format');\n        }\n\n        if (is_null($this->resultSetType)) {\n            $this->resultSetType = $this->getQuery()->getConfig('resultset_type');\n        }\n        // 执行初始化操作\n        $this->initialize();\n    }\n\n    /**\n     * 创建模型的查询对象\n     * @access protected\n     * @return Query\n     */\n    protected function buildQuery()\n    {\n        // 合并数据库配置\n        if (!empty($this->connection)) {\n            if (is_array($this->connection)) {\n                $connection = array_merge(Config::get('database'), $this->connection);\n            } else {\n                $connection = $this->connection;\n            }\n        } else {\n            $connection = [];\n        }\n\n        $con = Db::connect($connection);\n        // 设置当前模型 确保查询返回模型对象\n        $queryClass = $this->query ?: $con->getConfig('query');\n        $query      = new $queryClass($con, $this->class);\n        $con->setQuery($query, $this->class);\n\n        // 设置当前数据表和模型名\n        if (!empty($this->table)) {\n            $query->setTable($this->table);\n        } else {\n            $query->name($this->name);\n        }\n\n        if (!empty($this->pk)) {\n            $query->pk($this->pk);\n        }\n\n        return $query;\n    }\n\n    /**\n     * 获取当前模型的查询对象\n     * @access public\n     * @param bool      $buildNewQuery  创建新的查询对象\n     * @return Query\n     */\n    public function getQuery($buildNewQuery = false)\n    {\n        if ($buildNewQuery) {\n            return $this->buildQuery();\n        } elseif (!isset(self::$links[$this->class])) {\n            // 创建模型查询对象\n            self::$links[$this->class] = $this->buildQuery();\n        }\n\n        return self::$links[$this->class];\n    }\n\n    /**\n     * 获取当前模型的数据库查询对象\n     * @access public\n     * @param bool $useBaseQuery 是否调用全局查询范围\n     * @param bool $buildNewQuery 创建新的查询对象\n     * @return Query\n     */\n    public function db($useBaseQuery = true, $buildNewQuery = true)\n    {\n        $query = $this->getQuery($buildNewQuery);\n\n        // 全局作用域\n        if ($useBaseQuery && method_exists($this, 'base')) {\n            call_user_func_array([$this, 'base'], [ & $query]);\n        }\n\n        // 返回当前模型的数据库查询对象\n        return $query;\n    }\n\n    /**\n     *  初始化模型\n     * @access protected\n     * @return void\n     */\n    protected function initialize()\n    {\n        $class = get_class($this);\n        if (!isset(static::$initialized[$class])) {\n            static::$initialized[$class] = true;\n            static::init();\n        }\n    }\n\n    /**\n     * 初始化处理\n     * @access protected\n     * @return void\n     */\n    protected static function init()\n    {\n    }\n\n    /**\n     * 设置父关联对象\n     * @access public\n     * @param Model $model  模型对象\n     * @return $this\n     */\n    public function setParent($model)\n    {\n        $this->parent = $model;\n\n        return $this;\n    }\n\n    /**\n     * 获取父关联对象\n     * @access public\n     * @return Model\n     */\n    public function getParent()\n    {\n        return $this->parent;\n    }\n\n    /**\n     * 设置数据对象值\n     * @access public\n     * @param mixed $data  数据或者属性名\n     * @param mixed $value 值\n     * @return $this\n     */\n    public function data($data, $value = null)\n    {\n        if (is_string($data)) {\n            $this->data[$data] = $value;\n        } else {\n            // 清空数据\n            $this->data = [];\n            if (is_object($data)) {\n                $data = get_object_vars($data);\n            }\n            if (true === $value) {\n                // 数据对象赋值\n                foreach ($data as $key => $value) {\n                    $this->setAttr($key, $value, $data);\n                }\n            } else {\n                $this->data = $data;\n            }\n        }\n        return $this;\n    }\n\n    /**\n     * 获取对象原始数据 如果不存在指定字段返回false\n     * @access public\n     * @param string $name 字段名 留空获取全部\n     * @return mixed\n     * @throws InvalidArgumentException\n     */\n    public function getData($name = null)\n    {\n        if (is_null($name)) {\n            return $this->data;\n        } elseif (array_key_exists($name, $this->data)) {\n            return $this->data[$name];\n        } elseif (array_key_exists($name, $this->relation)) {\n            return $this->relation[$name];\n        } else {\n            throw new InvalidArgumentException('property not exists:' . $this->class . '->' . $name);\n        }\n    }\n\n    /**\n     * 修改器 设置数据对象值\n     * @access public\n     * @param string $name  属性名\n     * @param mixed  $value 属性值\n     * @param array  $data  数据\n     * @return $this\n     */\n    public function setAttr($name, $value, $data = [])\n    {\n        if (is_null($value) && $this->autoWriteTimestamp && in_array($name, [$this->createTime, $this->updateTime])) {\n            // 自动写入的时间戳字段\n            $value = $this->autoWriteTimestamp($name);\n        } else {\n            // 检测修改器\n            $method = 'set' . Loader::parseName($name, 1) . 'Attr';\n            if (method_exists($this, $method)) {\n                $value = $this->$method($value, array_merge($this->data, $data));\n            } elseif (isset($this->type[$name])) {\n                // 类型转换\n                $value = $this->writeTransform($value, $this->type[$name]);\n            }\n        }\n\n        // 设置数据对象属性\n        $this->data[$name] = $value;\n        return $this;\n    }\n\n    /**\n     * 获取当前模型的关联模型数据\n     * @access public\n     * @param string $name 关联方法名\n     * @return mixed\n     */\n    public function getRelation($name = null)\n    {\n        if (is_null($name)) {\n            return $this->relation;\n        } elseif (array_key_exists($name, $this->relation)) {\n            return $this->relation[$name];\n        } else {\n            return;\n        }\n    }\n\n    /**\n     * 设置关联数据对象值\n     * @access public\n     * @param string $name  属性名\n     * @param mixed  $value 属性值\n     * @return $this\n     */\n    public function setRelation($name, $value)\n    {\n        $this->relation[$name] = $value;\n        return $this;\n    }\n\n    /**\n     * 自动写入时间戳\n     * @access public\n     * @param string $name 时间戳字段\n     * @return mixed\n     */\n    protected function autoWriteTimestamp($name)\n    {\n        if (isset($this->type[$name])) {\n            $type = $this->type[$name];\n            if (strpos($type, ':')) {\n                list($type, $param) = explode(':', $type, 2);\n            }\n            switch ($type) {\n                case 'datetime':\n                case 'date':\n                    $format = !empty($param) ? $param : $this->dateFormat;\n                    $value  = $this->formatDateTime(time(), $format);\n                    break;\n                case 'timestamp':\n                case 'integer':\n                default:\n                    $value = time();\n                    break;\n            }\n        } elseif (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), [\n            'datetime',\n            'date',\n            'timestamp',\n        ])\n        ) {\n            $value = $this->formatDateTime(time(), $this->dateFormat);\n        } else {\n            $value = $this->formatDateTime(time(), $this->dateFormat, true);\n        }\n        return $value;\n    }\n\n    /**\n     * 时间日期字段格式化处理\n     * @access public\n     * @param mixed $time      时间日期表达式\n     * @param mixed $format    日期格式\n     * @param bool  $timestamp 是否进行时间戳转换\n     * @return mixed\n     */\n    protected function formatDateTime($time, $format, $timestamp = false)\n    {\n        if (false !== strpos($format, '\\\\')) {\n            $time = new $format($time);\n        } elseif (!$timestamp && false !== $format) {\n            $time = date($format, $time);\n        }\n        return $time;\n    }\n\n    /**\n     * 数据写入 类型转换\n     * @access public\n     * @param mixed        $value 值\n     * @param string|array $type  要转换的类型\n     * @return mixed\n     */\n    protected function writeTransform($value, $type)\n    {\n        if (is_null($value)) {\n            return;\n        }\n\n        if (is_array($type)) {\n            list($type, $param) = $type;\n        } elseif (strpos($type, ':')) {\n            list($type, $param) = explode(':', $type, 2);\n        }\n        switch ($type) {\n            case 'integer':\n                $value = (int) $value;\n                break;\n            case 'float':\n                if (empty($param)) {\n                    $value = (float) $value;\n                } else {\n                    $value = (float) number_format($value, $param, '.', '');\n                }\n                break;\n            case 'boolean':\n                $value = (bool) $value;\n                break;\n            case 'timestamp':\n                if (!is_numeric($value)) {\n                    $value = strtotime($value);\n                }\n                break;\n            case 'datetime':\n                $format = !empty($param) ? $param : $this->dateFormat;\n                $value  = is_numeric($value) ? $value : strtotime($value);\n                $value  = $this->formatDateTime($value, $format);\n                break;\n            case 'object':\n                if (is_object($value)) {\n                    $value = json_encode($value, JSON_FORCE_OBJECT);\n                }\n                break;\n            case 'array':\n                $value = (array) $value;\n            case 'json':\n                $option = !empty($param) ? (int) $param : JSON_UNESCAPED_UNICODE;\n                $value  = json_encode($value, $option);\n                break;\n            case 'serialize':\n                $value = serialize($value);\n                break;\n\n        }\n        return $value;\n    }\n\n    /**\n     * 获取器 获取数据对象的值\n     * @access public\n     * @param string $name 名称\n     * @return mixed\n     * @throws InvalidArgumentException\n     */\n    public function getAttr($name)\n    {\n        try {\n            $notFound = false;\n            $value    = $this->getData($name);\n        } catch (InvalidArgumentException $e) {\n            $notFound = true;\n            $value    = null;\n        }\n\n        // 检测属性获取器\n        $method = 'get' . Loader::parseName($name, 1) . 'Attr';\n        if (method_exists($this, $method)) {\n            $value = $this->$method($value, $this->data);\n        } elseif (isset($this->type[$name])) {\n            // 类型转换\n            $value = $this->readTransform($value, $this->type[$name]);\n        } elseif (in_array($name, [$this->createTime, $this->updateTime])) {\n            if (is_string($this->autoWriteTimestamp) && in_array(strtolower($this->autoWriteTimestamp), [\n                'datetime',\n                'date',\n                'timestamp',\n            ])\n            ) {\n                $value = $this->formatDateTime(strtotime($value), $this->dateFormat);\n            } else {\n                $value = $this->formatDateTime($value, $this->dateFormat);\n            }\n        } elseif ($notFound) {\n            $relation = Loader::parseName($name, 1, false);\n            if (method_exists($this, $relation)) {\n                $modelRelation = $this->$relation();\n                // 不存在该字段 获取关联数据\n                $value = $this->getRelationData($modelRelation);\n                // 保存关联对象值\n                $this->relation[$name] = $value;\n            } else {\n                throw new InvalidArgumentException('property not exists:' . $this->class . '->' . $name);\n            }\n        }\n        return $value;\n    }\n\n    /**\n     * 获取关联模型数据\n     * @access public\n     * @param Relation        $modelRelation 模型关联对象\n     * @return mixed\n     */\n    protected function getRelationData(Relation $modelRelation)\n    {\n        if ($this->parent && get_class($this->parent) == $modelRelation->getModel()) {\n            $value = $this->parent;\n        } else {\n            // 首先获取关联数据\n            $value = $modelRelation->getRelation();\n        }\n        return $value;\n    }\n\n    /**\n     * 数据读取 类型转换\n     * @access public\n     * @param mixed        $value 值\n     * @param string|array $type  要转换的类型\n     * @return mixed\n     */\n    protected function readTransform($value, $type)\n    {\n        if (is_null($value)) {\n            return;\n        }\n\n        if (is_array($type)) {\n            list($type, $param) = $type;\n        } elseif (strpos($type, ':')) {\n            list($type, $param) = explode(':', $type, 2);\n        }\n        switch ($type) {\n            case 'integer':\n                $value = (int) $value;\n                break;\n            case 'float':\n                if (empty($param)) {\n                    $value = (float) $value;\n                } else {\n                    $value = (float) number_format($value, $param, '.', '');\n                }\n                break;\n            case 'boolean':\n                $value = (bool) $value;\n                break;\n            case 'timestamp':\n                if (!is_null($value)) {\n                    $format = !empty($param) ? $param : $this->dateFormat;\n                    $value  = $this->formatDateTime($value, $format);\n                }\n                break;\n            case 'datetime':\n                if (!is_null($value)) {\n                    $format = !empty($param) ? $param : $this->dateFormat;\n                    $value  = $this->formatDateTime(strtotime($value), $format);\n                }\n                break;\n            case 'json':\n                $value = json_decode($value, true);\n                break;\n            case 'array':\n                $value = empty($value) ? [] : json_decode($value, true);\n                break;\n            case 'object':\n                $value = empty($value) ? new \\stdClass() : json_decode($value);\n                break;\n            case 'serialize':\n                $value = unserialize($value);\n                break;\n            default:\n                if (false !== strpos($type, '\\\\')) {\n                    // 对象类型\n                    $value = new $type($value);\n                }\n        }\n        return $value;\n    }\n\n    /**\n     * 设置需要追加的输出属性\n     * @access public\n     * @param array $append   属性列表\n     * @param bool  $override 是否覆盖\n     * @return $this\n     */\n    public function append($append = [], $override = false)\n    {\n        $this->append = $override ? $append : array_merge($this->append, $append);\n        return $this;\n    }\n\n    /**\n     * 设置附加关联对象的属性\n     * @access public\n     * @param string       $relation 关联方法\n     * @param string|array $append   追加属性名\n     * @return $this\n     * @throws Exception\n     */\n    public function appendRelationAttr($relation, $append)\n    {\n        if (is_string($append)) {\n            $append = explode(',', $append);\n        }\n        $model = $this->getAttr($relation);\n        if ($model instanceof Model) {\n            foreach ($append as $key => $attr) {\n                $key = is_numeric($key) ? $attr : $key;\n                if ($this->__isset($key)) {\n                    throw new Exception('bind attr has exists:' . $key);\n                } else {\n                    $this->setAttr($key, $model->$attr);\n                }\n            }\n        }\n        return $this;\n    }\n\n    /**\n     * 设置需要隐藏的输出属性\n     * @access public\n     * @param array $hidden   属性列表\n     * @param bool  $override 是否覆盖\n     * @return $this\n     */\n    public function hidden($hidden = [], $override = false)\n    {\n        $this->hidden = $override ? $hidden : array_merge($this->hidden, $hidden);\n        return $this;\n    }\n\n    /**\n     * 设置需要输出的属性\n     * @access public\n     * @param array $visible\n     * @param bool  $override 是否覆盖\n     * @return $this\n     */\n    public function visible($visible = [], $override = false)\n    {\n        $this->visible = $override ? $visible : array_merge($this->visible, $visible);\n        return $this;\n    }\n\n    /**\n     * 解析隐藏及显示属性\n     * @access protected\n     * @param array $attrs  属性\n     * @param array $result 结果集\n     * @param bool  $visible\n     * @return array\n     */\n    protected function parseAttr($attrs, &$result, $visible = true)\n    {\n        $array = [];\n        foreach ($attrs as $key => $val) {\n            if (is_array($val)) {\n                if ($visible) {\n                    $array[] = $key;\n                }\n                $result[$key] = $val;\n            } elseif (strpos($val, '.')) {\n                list($key, $name) = explode('.', $val);\n                if ($visible) {\n                    $array[] = $key;\n                }\n                $result[$key][] = $name;\n            } else {\n                $array[] = $val;\n            }\n        }\n        return $array;\n    }\n\n    /**\n     * 转换子模型对象\n     * @access protected\n     * @param Model|ModelCollection $model\n     * @param                  $visible\n     * @param                  $hidden\n     * @param                  $key\n     * @return array\n     */\n    protected function subToArray($model, $visible, $hidden, $key)\n    {\n        // 关联模型对象\n        if (isset($visible[$key])) {\n            $model->visible($visible[$key]);\n        } elseif (isset($hidden[$key])) {\n            $model->hidden($hidden[$key]);\n        }\n        return $model->toArray();\n    }\n\n    /**\n     * 转换当前模型对象为数组\n     * @access public\n     * @return array\n     */\n    public function toArray()\n    {\n        $item    = [];\n        $visible = [];\n        $hidden  = [];\n\n        $data = array_merge($this->data, $this->relation);\n\n        // 过滤属性\n        if (!empty($this->visible)) {\n            $array = $this->parseAttr($this->visible, $visible);\n            $data  = array_intersect_key($data, array_flip($array));\n        } elseif (!empty($this->hidden)) {\n            $array = $this->parseAttr($this->hidden, $hidden, false);\n            $data  = array_diff_key($data, array_flip($array));\n        }\n\n        foreach ($data as $key => $val) {\n            if ($val instanceof Model || $val instanceof ModelCollection) {\n                // 关联模型对象\n                $item[$key] = $this->subToArray($val, $visible, $hidden, $key);\n            } elseif (is_array($val) && reset($val) instanceof Model) {\n                // 关联模型数据集\n                $arr = [];\n                foreach ($val as $k => $value) {\n                    $arr[$k] = $this->subToArray($value, $visible, $hidden, $k);\n                }\n                $item[$key] = $arr;\n            } else {\n                // 模型属性\n                $item[$key] = $this->getAttr($key);\n            }\n        }\n        // 追加属性（必须定义获取器）\n        if (!empty($this->append)) {\n            foreach ($this->append as $key => $name) {\n                if (is_array($name)) {\n                    // 追加关联对象属性\n                    $relation   = $this->getAttr($key);\n                    $item[$key] = $relation->append($name)->toArray();\n                } elseif (strpos($name, '.')) {\n                    list($key, $attr) = explode('.', $name);\n                    // 追加关联对象属性\n                    $relation   = $this->getAttr($key);\n                    $item[$key] = $relation->append([$attr])->toArray();\n                } else {\n                    $item[$name] = $this->getAttr($name);\n                }\n            }\n        }\n        return !empty($item) ? $item : [];\n    }\n\n    /**\n     * 转换当前模型对象为JSON字符串\n     * @access public\n     * @param integer $options json参数\n     * @return string\n     */\n    public function toJson($options = JSON_UNESCAPED_UNICODE)\n    {\n        return json_encode($this->toArray(), $options);\n    }\n\n    /**\n     * 转换当前模型数据集为数据集对象\n     * @access public\n     * @param array|\\think\\Collection $collection 数据集\n     * @return \\think\\Collection\n     */\n    public function toCollection($collection)\n    {\n        if ($this->resultSetType) {\n            if ('collection' == $this->resultSetType) {\n                $collection = new ModelCollection($collection);\n            } elseif (false !== strpos($this->resultSetType, '\\\\')) {\n                $class      = $this->resultSetType;\n                $collection = new $class($collection);\n            }\n        }\n        return $collection;\n    }\n\n    /**\n     * 关联数据一起更新\n     * @access public\n     * @param mixed $relation 关联\n     * @return $this\n     */\n    public function together($relation)\n    {\n        if (is_string($relation)) {\n            $relation = explode(',', $relation);\n        }\n        $this->relationWrite = $relation;\n        return $this;\n    }\n\n    /**\n     * 获取模型对象的主键\n     * @access public\n     * @param string $name 模型名\n     * @return mixed\n     */\n    public function getPk($name = '')\n    {\n        if (!empty($name)) {\n            $table = $this->getQuery()->getTable($name);\n            return $this->getQuery()->getPk($table);\n        } elseif (empty($this->pk)) {\n            $this->pk = $this->getQuery()->getPk();\n        }\n        return $this->pk;\n    }\n\n    /**\n     * 判断一个字段名是否为主键字段\n     * @access public\n     * @param string $key 名称\n     * @return bool\n     */\n    protected function isPk($key)\n    {\n        $pk = $this->getPk();\n        if (is_string($pk) && $pk == $key) {\n            return true;\n        } elseif (is_array($pk) && in_array($key, $pk)) {\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 保存当前数据对象\n     * @access public\n     * @param array  $data     数据\n     * @param array  $where    更新条件\n     * @param string $sequence 自增序列名\n     * @return integer|false\n     */\n    public function save($data = [], $where = [], $sequence = null)\n    {\n        if (!empty($data)) {\n            // 数据自动验证\n            if (!$this->validateData($data)) {\n                return false;\n            }\n            // 数据对象赋值\n            foreach ($data as $key => $value) {\n                $this->setAttr($key, $value, $data);\n            }\n            if (!empty($where)) {\n                $this->isUpdate = true;\n            }\n        }\n\n        // 自动关联写入\n        if (!empty($this->relationWrite)) {\n            $relation = [];\n            foreach ($this->relationWrite as $key => $name) {\n                if (is_array($name)) {\n                    if (key($name) === 0) {\n                        $relation[$key] = [];\n                        foreach ($name as $val) {\n                            if (isset($this->data[$val])) {\n                                $relation[$key][$val] = $this->data[$val];\n                                unset($this->data[$val]);\n                            }\n                        }\n                    } else {\n                        $relation[$key] = $name;\n                    }\n                } elseif (isset($this->relation[$name])) {\n                    $relation[$name] = $this->relation[$name];\n                }\n            }\n        }\n\n        // 检测字段\n        if (!empty($this->field)) {\n            if (true === $this->field) {\n                $this->field = $this->getQuery()->getTableInfo('', 'fields');\n            }\n            foreach ($this->data as $key => $val) {\n                if (!in_array($key, $this->field)) {\n                    unset($this->data[$key]);\n                }\n            }\n        }\n\n        // 数据自动完成\n        $this->autoCompleteData($this->auto);\n\n        // 事件回调\n        if (false === $this->trigger('before_write', $this)) {\n            return false;\n        }\n        $pk = $this->getPk();\n        if ($this->isUpdate) {\n            // 自动更新\n            $this->autoCompleteData($this->update);\n\n            // 事件回调\n            if (false === $this->trigger('before_update', $this)) {\n                return false;\n            }\n\n            // 获取有更新的数据\n            $data = $this->getChangedData();\n\n            if (empty($data) || (count($data) == 1 && is_string($pk) && isset($data[$pk]))) {\n                // 关联更新\n                if (isset($relation)) {\n                    $this->autoRelationUpdate($relation);\n                }\n                return 0;\n            } elseif ($this->autoWriteTimestamp && $this->updateTime && !isset($data[$this->updateTime])) {\n                // 自动写入更新时间\n                $data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime);\n            }\n\n            if (empty($where) && !empty($this->updateWhere)) {\n                $where = $this->updateWhere;\n            }\n\n            // 保留主键数据\n            foreach ($this->data as $key => $val) {\n                if ($this->isPk($key)) {\n                    $data[$key] = $val;\n                }\n            }\n\n            if (is_string($pk) && isset($data[$pk])) {\n                if (!isset($where[$pk])) {\n                    unset($where);\n                    $where[$pk] = $data[$pk];\n                }\n                unset($data[$pk]);\n            }\n\n            // 模型更新\n            $result = $this->db()->where($where)->update($data);\n\n            // 关联更新\n            if (isset($relation)) {\n                $this->autoRelationUpdate($relation);\n            }\n\n            // 更新回调\n            $this->trigger('after_update', $this);\n\n        } else {\n            // 自动写入\n            $this->autoCompleteData($this->insert);\n            // 自动写入创建时间和更新时间\n            if ($this->autoWriteTimestamp) {\n                if ($this->createTime && !isset($this->data[$this->createTime])) {\n                    $this->data[$this->createTime] = $this->autoWriteTimestamp($this->createTime);\n                }\n                if ($this->updateTime && !isset($this->data[$this->updateTime])) {\n                    $this->data[$this->updateTime] = $this->autoWriteTimestamp($this->updateTime);\n                }\n            }\n\n            if (false === $this->trigger('before_insert', $this)) {\n                return false;\n            }\n\n            $result = $this->db()->insert($this->data);\n\n            // 获取自动增长主键\n            if ($result && is_string($pk) && (!isset($this->data[$pk]) || '' == $this->data[$pk])) {\n                $insertId = $this->db()->getLastInsID($sequence);\n                if ($insertId) {\n                    $this->data[$pk] = $insertId;\n                }\n            }\n\n            // 关联写入\n            if (isset($relation)) {\n                foreach ($relation as $name => $val) {\n                    $method = Loader::parseName($name, 1, false);\n                    $this->$method()->save($val);\n                }\n            }\n\n            // 标记为更新\n            $this->isUpdate = true;\n\n            // 新增回调\n            $this->trigger('after_insert', $this);\n        }\n        // 写入回调\n        $this->trigger('after_write', $this);\n\n        // 重新记录原始数据\n        $this->origin = $this->data;\n\n        return $result;\n    }\n\n    protected function autoRelationUpdate($relation)\n    {\n        foreach ($relation as $name => $val) {\n            if ($val instanceof Model) {\n                $val->save();\n            } else {\n                unset($this->data[$name]);\n                $model = $this->getAttr($name);\n                if ($model instanceof Model) {\n                    $model->save($val);\n                }\n            }\n        }\n    }\n\n    /**\n     * 获取变化的数据 并排除只读数据\n     * @access public\n     * @return array\n     */\n    public function getChangedData()\n    {\n        $data = array_udiff_assoc($this->data, $this->origin, function ($a, $b) {\n            return is_object($a) || $a != $b ? 1 : 0;\n        });\n\n        if (!empty($this->readonly)) {\n            // 只读字段不允许更新\n            foreach ($this->readonly as $key => $field) {\n                if (isset($data[$field])) {\n                    unset($data[$field]);\n                }\n            }\n        }\n\n        return $data;\n    }\n\n    /**\n     * 保存多个数据到当前数据对象\n     * @access public\n     * @param array   $dataSet 数据\n     * @param boolean $replace 是否自动识别更新和写入\n     * @return array|false\n     * @throws \\Exception\n     */\n    public function saveAll($dataSet, $replace = true)\n    {\n        if ($this->validate) {\n            // 数据批量验证\n            $validate = $this->validate;\n            foreach ($dataSet as $data) {\n                if (!$this->validateData($data, $validate)) {\n                    return false;\n                }\n            }\n        }\n\n        $result = [];\n        $db     = $this->db();\n        $db->startTrans();\n        try {\n            $pk = $this->getPk();\n            if (is_string($pk) && $replace) {\n                $auto = true;\n            }\n            foreach ($dataSet as $key => $data) {\n                if (!empty($auto) && isset($data[$pk])) {\n                    $result[$key] = self::update($data, [], $this->field);\n                } else {\n                    $result[$key] = self::create($data, $this->field);\n                }\n            }\n            $db->commit();\n            return $result;\n        } catch (\\Exception $e) {\n            $db->rollback();\n            throw $e;\n        }\n    }\n\n    /**\n     * 设置允许写入的字段\n     * @access public\n     * @param mixed $field 允许写入的字段 如果为true只允许写入数据表字段\n     * @return $this\n     */\n    public function allowField($field)\n    {\n        if (is_string($field)) {\n            $field = explode(',', $field);\n        }\n        $this->field = $field;\n        return $this;\n    }\n\n    /**\n     * 设置只读字段\n     * @access public\n     * @param mixed $field 只读字段\n     * @return $this\n     */\n    public function readonly($field)\n    {\n        if (is_string($field)) {\n            $field = explode(',', $field);\n        }\n        $this->readonly = $field;\n        return $this;\n    }\n\n    /**\n     * 是否为更新数据\n     * @access public\n     * @param bool  $update\n     * @param mixed $where\n     * @return $this\n     */\n    public function isUpdate($update = true, $where = null)\n    {\n        $this->isUpdate = $update;\n        if (!empty($where)) {\n            $this->updateWhere = $where;\n        }\n        return $this;\n    }\n\n    /**\n     * 数据自动完成\n     * @access public\n     * @param array $auto 要自动更新的字段列表\n     * @return void\n     */\n    protected function autoCompleteData($auto = [])\n    {\n        foreach ($auto as $field => $value) {\n            if (is_integer($field)) {\n                $field = $value;\n                $value = null;\n            }\n\n            if (!isset($this->data[$field])) {\n                $default = null;\n            } else {\n                $default = $this->data[$field];\n            }\n\n            $this->setAttr($field, !is_null($value) ? $value : $default);\n        }\n    }\n\n    /**\n     * 删除当前的记录\n     * @access public\n     * @return integer\n     */\n    public function delete()\n    {\n        if (false === $this->trigger('before_delete', $this)) {\n            return false;\n        }\n\n        // 删除条件\n        $pk = $this->getPk();\n        if (is_string($pk) && isset($this->data[$pk])) {\n            $where = [$pk => $this->data[$pk]];\n        } elseif (!empty($this->updateWhere)) {\n            $where = $this->updateWhere;\n        } else {\n            $where = null;\n        }\n\n        // 删除当前模型数据\n        $result = $this->db()->where($where)->delete();\n\n        // 关联删除\n        if (!empty($this->relationWrite)) {\n            foreach ($this->relationWrite as $key => $name) {\n                $name  = is_numeric($key) ? $name : $key;\n                $model = $this->getAttr($name);\n                if ($model instanceof Model) {\n                    $model->delete();\n                }\n            }\n        }\n\n        $this->trigger('after_delete', $this);\n        // 清空原始数据\n        $this->origin = [];\n\n        return $result;\n    }\n\n    /**\n     * 设置自动完成的字段（ 规则通过修改器定义）\n     * @access public\n     * @param array $fields 需要自动完成的字段\n     * @return $this\n     */\n    public function auto($fields)\n    {\n        $this->auto = $fields;\n        return $this;\n    }\n\n    /**\n     * 设置字段验证\n     * @access public\n     * @param array|string|bool $rule  验证规则 true表示自动读取验证器类\n     * @param array             $msg   提示信息\n     * @param bool              $batch 批量验证\n     * @return $this\n     */\n    public function validate($rule = true, $msg = [], $batch = false)\n    {\n        if (is_array($rule)) {\n            $this->validate = [\n                'rule' => $rule,\n                'msg'  => $msg,\n            ];\n        } else {\n            $this->validate = true === $rule ? $this->name : $rule;\n        }\n        $this->batchValidate = $batch;\n        return $this;\n    }\n\n    /**\n     * 设置验证失败后是否抛出异常\n     * @access public\n     * @param bool $fail 是否抛出异常\n     * @return $this\n     */\n    public function validateFailException($fail = true)\n    {\n        $this->failException = $fail;\n        return $this;\n    }\n\n    /**\n     * 自动验证数据\n     * @access protected\n     * @param array $data  验证数据\n     * @param mixed $rule  验证规则\n     * @param bool  $batch 批量验证\n     * @return bool\n     */\n    protected function validateData($data, $rule = null, $batch = null)\n    {\n        $info = is_null($rule) ? $this->validate : $rule;\n\n        if (!empty($info)) {\n            if (is_array($info)) {\n                $validate = Loader::validate();\n                $validate->rule($info['rule']);\n                $validate->message($info['msg']);\n            } else {\n                $name = is_string($info) ? $info : $this->name;\n                if (strpos($name, '.')) {\n                    list($name, $scene) = explode('.', $name);\n                }\n                $validate = Loader::validate($name);\n                if (!empty($scene)) {\n                    $validate->scene($scene);\n                }\n            }\n            $batch = is_null($batch) ? $this->batchValidate : $batch;\n\n            if (!$validate->batch($batch)->check($data)) {\n                $this->error = $validate->getError();\n                if ($this->failException) {\n                    throw new ValidateException($this->error);\n                } else {\n                    return false;\n                }\n            }\n            $this->validate = null;\n        }\n        return true;\n    }\n\n    /**\n     * 返回模型的错误信息\n     * @access public\n     * @return string|array\n     */\n    public function getError()\n    {\n        return $this->error;\n    }\n\n    /**\n     * 注册回调方法\n     * @access public\n     * @param string   $event    事件名\n     * @param callable $callback 回调方法\n     * @param bool     $override 是否覆盖\n     * @return void\n     */\n    public static function event($event, $callback, $override = false)\n    {\n        $class = get_called_class();\n        if ($override) {\n            self::$event[$class][$event] = [];\n        }\n        self::$event[$class][$event][] = $callback;\n    }\n\n    /**\n     * 触发事件\n     * @access protected\n     * @param string $event  事件名\n     * @param mixed  $params 传入参数（引用）\n     * @return bool\n     */\n    protected function trigger($event, &$params)\n    {\n        if (isset(self::$event[$this->class][$event])) {\n            foreach (self::$event[$this->class][$event] as $callback) {\n                if (is_callable($callback)) {\n                    $result = call_user_func_array($callback, [ & $params]);\n                    if (false === $result) {\n                        return false;\n                    }\n                }\n            }\n        }\n        return true;\n    }\n\n    /**\n     * 写入数据\n     * @access public\n     * @param array      $data  数据数组\n     * @param array|true $field 允许字段\n     * @return $this\n     */\n    public static function create($data = [], $field = null)\n    {\n        $model = new static();\n        if (!empty($field)) {\n            $model->allowField($field);\n        }\n        $model->isUpdate(false)->save($data, []);\n        return $model;\n    }\n\n    /**\n     * 更新数据\n     * @access public\n     * @param array      $data  数据数组\n     * @param array      $where 更新条件\n     * @param array|true $field 允许字段\n     * @return $this\n     */\n    public static function update($data = [], $where = [], $field = null)\n    {\n        $model = new static();\n        if (!empty($field)) {\n            $model->allowField($field);\n        }\n        $result = $model->isUpdate(true)->save($data, $where);\n        return $model;\n    }\n\n    /**\n     * 查找单条记录\n     * @access public\n     * @param mixed        $data  主键值或者查询条件（闭包）\n     * @param array|string $with  关联预查询\n     * @param bool         $cache 是否缓存\n     * @return static|null\n     * @throws exception\\DbException\n     */\n    public static function get($data, $with = [], $cache = false)\n    {\n        if (is_null($data)) {\n            return;\n        }\n\n        if (true === $with || is_int($with)) {\n            $cache = $with;\n            $with  = [];\n        }\n        $query = static::parseQuery($data, $with, $cache);\n        return $query->find($data);\n    }\n\n    /**\n     * 查找所有记录\n     * @access public\n     * @param mixed        $data  主键列表或者查询条件（闭包）\n     * @param array|string $with  关联预查询\n     * @param bool         $cache 是否缓存\n     * @return static[]|false\n     * @throws exception\\DbException\n     */\n    public static function all($data = null, $with = [], $cache = false)\n    {\n        if (true === $with || is_int($with)) {\n            $cache = $with;\n            $with  = [];\n        }\n        $query = static::parseQuery($data, $with, $cache);\n        return $query->select($data);\n    }\n\n    /**\n     * 分析查询表达式\n     * @access public\n     * @param mixed  $data  主键列表或者查询条件（闭包）\n     * @param string $with  关联预查询\n     * @param bool   $cache 是否缓存\n     * @return Query\n     */\n    protected static function parseQuery(&$data, $with, $cache)\n    {\n        $result = self::with($with)->cache($cache);\n        if (is_array($data) && key($data) !== 0) {\n            $result = $result->where($data);\n            $data   = null;\n        } elseif ($data instanceof \\Closure) {\n            call_user_func_array($data, [ & $result]);\n            $data = null;\n        } elseif ($data instanceof Query) {\n            $result = $data->with($with)->cache($cache);\n            $data   = null;\n        }\n        return $result;\n    }\n\n    /**\n     * 删除记录\n     * @access public\n     * @param mixed $data 主键列表 支持闭包查询条件\n     * @return integer 成功删除的记录数\n     */\n    public static function destroy($data)\n    {\n        $model = new static();\n        $query = $model->db();\n        if (is_array($data) && key($data) !== 0) {\n            $query->where($data);\n            $data = null;\n        } elseif ($data instanceof \\Closure) {\n            call_user_func_array($data, [ & $query]);\n            $data = null;\n        } elseif (is_null($data)) {\n            return 0;\n        }\n        $resultSet = $query->select($data);\n        $count     = 0;\n        if ($resultSet) {\n            foreach ($resultSet as $data) {\n                $result = $data->delete();\n                $count += $result;\n            }\n        }\n        return $count;\n    }\n\n    /**\n     * 命名范围\n     * @access public\n     * @param string|array|\\Closure $name 命名范围名称 逗号分隔\n     * @internal  mixed                 ...$params 参数调用\n     * @return Query\n     */\n    public static function scope($name)\n    {\n        $model  = new static();\n        $query  = $model->db();\n        $params = func_get_args();\n        array_unshift($params, $query);\n        if ($name instanceof \\Closure) {\n            call_user_func_array($name, $params);\n        } elseif (is_string($name)) {\n            $name = explode(',', $name);\n        }\n        if (is_array($name)) {\n            foreach ($name as $scope) {\n                $method = 'scope' . trim($scope);\n                if (method_exists($model, $method)) {\n                    call_user_func_array([$model, $method], $params);\n                }\n            }\n        }\n        return $query;\n    }\n\n    /**\n     * 设置是否使用全局查询范围\n     * @param bool $use 是否启用全局查询范围\n     * @access public\n     * @return Model\n     */\n    public static function useGlobalScope($use)\n    {\n        $model = new static();\n        return $model->db($use);\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param string  $relation 关联方法名\n     * @param mixed   $operator 比较操作符\n     * @param integer $count    个数\n     * @param string  $id       关联表的统计字段\n     * @return Relation|Query\n     */\n    public static function has($relation, $operator = '>=', $count = 1, $id = '*')\n    {\n        $relation = (new static())->$relation();\n        if (is_array($operator) || $operator instanceof \\Closure) {\n            return $relation->hasWhere($operator);\n        }\n        return $relation->has($operator, $count, $id);\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param string $relation 关联方法名\n     * @param mixed  $where    查询条件（数组或者闭包）\n     * @return Relation|Query\n     */\n    public static function hasWhere($relation, $where = [])\n    {\n        return (new static())->$relation()->hasWhere($where);\n    }\n\n    /**\n     * 解析模型的完整命名空间\n     * @access public\n     * @param string $model 模型名（或者完整类名）\n     * @return string\n     */\n    protected function parseModel($model)\n    {\n        if (false === strpos($model, '\\\\')) {\n            $path = explode('\\\\', get_called_class());\n            array_pop($path);\n            array_push($path, Loader::parseName($model, 1));\n            $model = implode('\\\\', $path);\n        }\n        return $model;\n    }\n\n    /**\n     * 查询当前模型的关联数据\n     * @access public\n     * @param string|array $relations 关联名\n     * @return $this\n     */\n    public function relationQuery($relations)\n    {\n        if (is_string($relations)) {\n            $relations = explode(',', $relations);\n        }\n\n        foreach ($relations as $key => $relation) {\n            $subRelation = '';\n            $closure     = null;\n            if ($relation instanceof \\Closure) {\n                // 支持闭包查询过滤关联条件\n                $closure  = $relation;\n                $relation = $key;\n            }\n            if (is_array($relation)) {\n                $subRelation = $relation;\n                $relation    = $key;\n            } elseif (strpos($relation, '.')) {\n                list($relation, $subRelation) = explode('.', $relation, 2);\n            }\n            $method                = Loader::parseName($relation, 1, false);\n            $this->data[$relation] = $this->$method()->getRelation($subRelation, $closure);\n        }\n        return $this;\n    }\n\n    /**\n     * 预载入关联查询 返回数据集\n     * @access public\n     * @param array  $resultSet 数据集\n     * @param string $relation  关联名\n     * @return array\n     */\n    public function eagerlyResultSet(&$resultSet, $relation)\n    {\n        $relations = is_string($relation) ? explode(',', $relation) : $relation;\n        foreach ($relations as $key => $relation) {\n            $subRelation = '';\n            $closure     = false;\n            if ($relation instanceof \\Closure) {\n                $closure  = $relation;\n                $relation = $key;\n            }\n            if (is_array($relation)) {\n                $subRelation = $relation;\n                $relation    = $key;\n            } elseif (strpos($relation, '.')) {\n                list($relation, $subRelation) = explode('.', $relation, 2);\n            }\n            $relation = Loader::parseName($relation, 1, false);\n            $this->$relation()->eagerlyResultSet($resultSet, $relation, $subRelation, $closure);\n        }\n    }\n\n    /**\n     * 预载入关联查询 返回模型对象\n     * @access public\n     * @param Model  $result   数据对象\n     * @param string $relation 关联名\n     * @return Model\n     */\n    public function eagerlyResult(&$result, $relation)\n    {\n        $relations = is_string($relation) ? explode(',', $relation) : $relation;\n\n        foreach ($relations as $key => $relation) {\n            $subRelation = '';\n            $closure     = false;\n            if ($relation instanceof \\Closure) {\n                $closure  = $relation;\n                $relation = $key;\n            }\n            if (is_array($relation)) {\n                $subRelation = $relation;\n                $relation    = $key;\n            } elseif (strpos($relation, '.')) {\n                list($relation, $subRelation) = explode('.', $relation, 2);\n            }\n            $relation = Loader::parseName($relation, 1, false);\n            $this->$relation()->eagerlyResult($result, $relation, $subRelation, $closure);\n        }\n    }\n\n    /**\n     * 关联统计\n     * @access public\n     * @param Model        $result   数据对象\n     * @param string|array $relation 关联名\n     * @return void\n     */\n    public function relationCount(&$result, $relation)\n    {\n        $relations = is_string($relation) ? explode(',', $relation) : $relation;\n\n        foreach ($relations as $key => $relation) {\n            $closure = false;\n            if ($relation instanceof \\Closure) {\n                $closure  = $relation;\n                $relation = $key;\n            } elseif (is_string($key)) {\n                $name     = $relation;\n                $relation = $key;\n            }\n            $relation = Loader::parseName($relation, 1, false);\n            $count    = $this->$relation()->relationCount($result, $closure);\n            if (!isset($name)) {\n                $name = Loader::parseName($relation) . '_count';\n            }\n            $result->setAttr($name, $count);\n        }\n    }\n\n    /**\n     * 获取模型的默认外键名\n     * @access public\n     * @param string $name 模型名\n     * @return string\n     */\n    protected function getForeignKey($name)\n    {\n        if (strpos($name, '\\\\')) {\n            $name = basename(str_replace('\\\\', '/', $name));\n        }\n        return Loader::parseName($name) . '_id';\n    }\n\n    /**\n     * HAS ONE 关联定义\n     * @access public\n     * @param string $model      模型名\n     * @param string $foreignKey 关联外键\n     * @param string $localKey   关联主键\n     * @param array  $alias      别名定义（已经废弃）\n     * @param string $joinType   JOIN类型\n     * @return HasOne\n     */\n    public function hasOne($model, $foreignKey = '', $localKey = '', $alias = [], $joinType = 'INNER')\n    {\n        // 记录当前关联信息\n        $model      = $this->parseModel($model);\n        $localKey   = $localKey ?: $this->getPk();\n        $foreignKey = $foreignKey ?: $this->getForeignKey($this->name);\n        return new HasOne($this, $model, $foreignKey, $localKey, $joinType);\n    }\n\n    /**\n     * BELONGS TO 关联定义\n     * @access public\n     * @param string $model      模型名\n     * @param string $foreignKey 关联外键\n     * @param string $localKey   关联主键\n     * @param array  $alias      别名定义（已经废弃）\n     * @param string $joinType   JOIN类型\n     * @return BelongsTo\n     */\n    public function belongsTo($model, $foreignKey = '', $localKey = '', $alias = [], $joinType = 'INNER')\n    {\n        // 记录当前关联信息\n        $model      = $this->parseModel($model);\n        $foreignKey = $foreignKey ?: $this->getForeignKey($model);\n        $localKey   = $localKey ?: (new $model)->getPk();\n        $trace      = debug_backtrace(false, 2);\n        $relation   = Loader::parseName($trace[1]['function']);\n        return new BelongsTo($this, $model, $foreignKey, $localKey, $joinType, $relation);\n    }\n\n    /**\n     * HAS MANY 关联定义\n     * @access public\n     * @param string $model      模型名\n     * @param string $foreignKey 关联外键\n     * @param string $localKey   关联主键\n     * @return HasMany\n     */\n    public function hasMany($model, $foreignKey = '', $localKey = '')\n    {\n        // 记录当前关联信息\n        $model      = $this->parseModel($model);\n        $localKey   = $localKey ?: $this->getPk();\n        $foreignKey = $foreignKey ?: $this->getForeignKey($this->name);\n        return new HasMany($this, $model, $foreignKey, $localKey);\n    }\n\n    /**\n     * HAS MANY 远程关联定义\n     * @access public\n     * @param string $model      模型名\n     * @param string $through    中间模型名\n     * @param string $foreignKey 关联外键\n     * @param string $throughKey 关联外键\n     * @param string $localKey   关联主键\n     * @return HasManyThrough\n     */\n    public function hasManyThrough($model, $through, $foreignKey = '', $throughKey = '', $localKey = '')\n    {\n        // 记录当前关联信息\n        $model      = $this->parseModel($model);\n        $through    = $this->parseModel($through);\n        $localKey   = $localKey ?: $this->getPk();\n        $foreignKey = $foreignKey ?: $this->getForeignKey($this->name);\n        $throughKey = $throughKey ?: $this->getForeignKey($through);\n        return new HasManyThrough($this, $model, $through, $foreignKey, $throughKey, $localKey);\n    }\n\n    /**\n     * BELONGS TO MANY 关联定义\n     * @access public\n     * @param string $model      模型名\n     * @param string $table      中间表名\n     * @param string $foreignKey 关联外键\n     * @param string $localKey   当前模型关联键\n     * @return BelongsToMany\n     */\n    public function belongsToMany($model, $table = '', $foreignKey = '', $localKey = '')\n    {\n        // 记录当前关联信息\n        $model      = $this->parseModel($model);\n        $name       = Loader::parseName(basename(str_replace('\\\\', '/', $model)));\n        $table      = $table ?: $this->getQuery()->getTable(Loader::parseName($this->name) . '_' . $name);\n        $foreignKey = $foreignKey ?: $name . '_id';\n        $localKey   = $localKey ?: $this->getForeignKey($this->name);\n        return new BelongsToMany($this, $model, $table, $foreignKey, $localKey);\n    }\n\n    /**\n     * MORPH  MANY 关联定义\n     * @access public\n     * @param string       $model 模型名\n     * @param string|array $morph 多态字段信息\n     * @param string       $type  多态类型\n     * @return MorphMany\n     */\n    public function morphMany($model, $morph = null, $type = '')\n    {\n        // 记录当前关联信息\n        $model = $this->parseModel($model);\n        if (is_null($morph)) {\n            $trace = debug_backtrace(false, 2);\n            $morph = Loader::parseName($trace[1]['function']);\n        }\n        $type = $type ?: Loader::parseName($this->name);\n        if (is_array($morph)) {\n            list($morphType, $foreignKey) = $morph;\n        } else {\n            $morphType  = $morph . '_type';\n            $foreignKey = $morph . '_id';\n        }\n        return new MorphMany($this, $model, $foreignKey, $morphType, $type);\n    }\n\n    /**\n     * MORPH  One 关联定义\n     * @access public\n     * @param string       $model 模型名\n     * @param string|array $morph 多态字段信息\n     * @param string       $type  多态类型\n     * @return MorphOne\n     */\n    public function morphOne($model, $morph = null, $type = '')\n    {\n        // 记录当前关联信息\n        $model = $this->parseModel($model);\n        if (is_null($morph)) {\n            $trace = debug_backtrace(false, 2);\n            $morph = Loader::parseName($trace[1]['function']);\n        }\n        $type = $type ?: Loader::parseName($this->name);\n        if (is_array($morph)) {\n            list($morphType, $foreignKey) = $morph;\n        } else {\n            $morphType  = $morph . '_type';\n            $foreignKey = $morph . '_id';\n        }\n        return new MorphOne($this, $model, $foreignKey, $morphType, $type);\n    }\n\n    /**\n     * MORPH TO 关联定义\n     * @access public\n     * @param string|array $morph 多态字段信息\n     * @param array        $alias 多态别名定义\n     * @return MorphTo\n     */\n    public function morphTo($morph = null, $alias = [])\n    {\n        $trace    = debug_backtrace(false, 2);\n        $relation = Loader::parseName($trace[1]['function']);\n\n        if (is_null($morph)) {\n            $morph = $relation;\n        }\n        // 记录当前关联信息\n        if (is_array($morph)) {\n            list($morphType, $foreignKey) = $morph;\n        } else {\n            $morphType  = $morph . '_type';\n            $foreignKey = $morph . '_id';\n        }\n        return new MorphTo($this, $morphType, $foreignKey, $alias, $relation);\n    }\n\n    public function __call($method, $args)\n    {\n        $query = $this->db(true, false);\n\n        if (method_exists($this, 'scope' . $method)) {\n            // 动态调用命名范围\n            $method = 'scope' . $method;\n            array_unshift($args, $query);\n            call_user_func_array([$this, $method], $args);\n            return $this;\n        } else {\n            return call_user_func_array([$query, $method], $args);\n        }\n    }\n\n    public static function __callStatic($method, $args)\n    {\n        $model = new static();\n        $query = $model->db();\n\n        if (method_exists($model, 'scope' . $method)) {\n            // 动态调用命名范围\n            $method = 'scope' . $method;\n            array_unshift($args, $query);\n\n            call_user_func_array([$model, $method], $args);\n            return $query;\n        } else {\n            return call_user_func_array([$query, $method], $args);\n        }\n    }\n\n    /**\n     * 修改器 设置数据对象的值\n     * @access public\n     * @param string $name  名称\n     * @param mixed  $value 值\n     * @return void\n     */\n    public function __set($name, $value)\n    {\n        $this->setAttr($name, $value);\n    }\n\n    /**\n     * 获取器 获取数据对象的值\n     * @access public\n     * @param string $name 名称\n     * @return mixed\n     */\n    public function __get($name)\n    {\n        return $this->getAttr($name);\n    }\n\n    /**\n     * 检测数据对象的值\n     * @access public\n     * @param string $name 名称\n     * @return boolean\n     */\n    public function __isset($name)\n    {\n        try {\n            if (array_key_exists($name, $this->data) || array_key_exists($name, $this->relation)) {\n                return true;\n            } else {\n                $this->getAttr($name);\n                return true;\n            }\n        } catch (InvalidArgumentException $e) {\n            return false;\n        }\n\n    }\n\n    /**\n     * 销毁数据对象的值\n     * @access public\n     * @param string $name 名称\n     * @return void\n     */\n    public function __unset($name)\n    {\n        unset($this->data[$name], $this->relation[$name]);\n    }\n\n    public function __toString()\n    {\n        return $this->toJson();\n    }\n\n    // JsonSerializable\n    public function jsonSerialize()\n    {\n        return $this->toArray();\n    }\n\n    // ArrayAccess\n    public function offsetSet($name, $value)\n    {\n        $this->setAttr($name, $value);\n    }\n\n    public function offsetExists($name)\n    {\n        return $this->__isset($name);\n    }\n\n    public function offsetUnset($name)\n    {\n        $this->__unset($name);\n    }\n\n    public function offsetGet($name)\n    {\n        return $this->getAttr($name);\n    }\n\n    /**\n     * 解序列化后处理\n     */\n    public function __wakeup()\n    {\n        $this->initialize();\n    }\n\n    /**\n     * 模型事件快捷方法\n     * @param      $callback\n     * @param bool $override\n     */\n    protected static function beforeInsert($callback, $override = false)\n    {\n        self::event('before_insert', $callback, $override);\n    }\n\n    protected static function afterInsert($callback, $override = false)\n    {\n        self::event('after_insert', $callback, $override);\n    }\n\n    protected static function beforeUpdate($callback, $override = false)\n    {\n        self::event('before_update', $callback, $override);\n    }\n\n    protected static function afterUpdate($callback, $override = false)\n    {\n        self::event('after_update', $callback, $override);\n    }\n\n    protected static function beforeWrite($callback, $override = false)\n    {\n        self::event('before_write', $callback, $override);\n    }\n\n    protected static function afterWrite($callback, $override = false)\n    {\n        self::event('after_write', $callback, $override);\n    }\n\n    protected static function beforeDelete($callback, $override = false)\n    {\n        self::event('before_delete', $callback, $override);\n    }\n\n    protected static function afterDelete($callback, $override = false)\n    {\n        self::event('after_delete', $callback, $override);\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/Paginator.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: zhangyajun <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse ArrayAccess;\nuse ArrayIterator;\nuse Countable;\nuse IteratorAggregate;\nuse JsonSerializable;\nuse Traversable;\n\nabstract class Paginator implements ArrayAccess, Countable, IteratorAggregate, JsonSerializable\n{\n    /** @var bool 是否为简洁模式 */\n    protected $simple = false;\n\n    /** @var Collection 数据集 */\n    protected $items;\n\n    /** @var integer 当前页 */\n    protected $currentPage;\n\n    /** @var  integer 最后一页 */\n    protected $lastPage;\n\n    /** @var integer|null 数据总数 */\n    protected $total;\n\n    /** @var  integer 每页的数量 */\n    protected $listRows;\n\n    /** @var bool 是否有下一页 */\n    protected $hasMore;\n\n    /** @var array 一些配置 */\n    protected $options = [\n        'var_page' => 'page',\n        'path'     => '/',\n        'query'    => [],\n        'fragment' => '',\n    ];\n\n    public function __construct($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = [])\n    {\n        $this->options = array_merge($this->options, $options);\n\n        $this->options['path'] = '/' != $this->options['path'] ? rtrim($this->options['path'], '/') : $this->options['path'];\n\n        $this->simple   = $simple;\n        $this->listRows = $listRows;\n\n        if (!$items instanceof Collection) {\n            $items = Collection::make($items);\n        }\n\n        if ($simple) {\n            $this->currentPage = $this->setCurrentPage($currentPage);\n            $this->hasMore     = count($items) > ($this->listRows);\n            $items             = $items->slice(0, $this->listRows);\n        } else {\n            $this->total       = $total;\n            $this->lastPage    = (int) ceil($total / $listRows);\n            $this->currentPage = $this->setCurrentPage($currentPage);\n            $this->hasMore     = $this->currentPage < $this->lastPage;\n        }\n        $this->items = $items;\n    }\n\n    /**\n     * @param       $items\n     * @param       $listRows\n     * @param null  $currentPage\n     * @param bool  $simple\n     * @param null  $total\n     * @param array $options\n     * @return Paginator\n     */\n    public static function make($items, $listRows, $currentPage = null, $total = null, $simple = false, $options = [])\n    {\n        return new static($items, $listRows, $currentPage, $total, $simple, $options);\n    }\n\n    protected function setCurrentPage($currentPage)\n    {\n        if (!$this->simple && $currentPage > $this->lastPage) {\n            return $this->lastPage > 0 ? $this->lastPage : 1;\n        }\n\n        return $currentPage;\n    }\n\n    /**\n     * 获取页码对应的链接\n     *\n     * @param $page\n     * @return string\n     */\n    protected function url($page)\n    {\n        if ($page <= 0) {\n            $page = 1;\n        }\n\n        if (strpos($this->options['path'], '[PAGE]') === false) {\n            $parameters = [$this->options['var_page'] => $page];\n            $path       = $this->options['path'];\n        } else {\n            $parameters = [];\n            $path       = str_replace('[PAGE]', $page, $this->options['path']);\n        }\n        if (count($this->options['query']) > 0) {\n            $parameters = array_merge($this->options['query'], $parameters);\n        }\n        $url = $path;\n        if (!empty($parameters)) {\n            $url .= '?' . urldecode(http_build_query($parameters, null, '&'));\n        }\n        return $url . $this->buildFragment();\n    }\n\n    /**\n     * 自动获取当前页码\n     * @param string $varPage\n     * @param int    $default\n     * @return int\n     */\n    public static function getCurrentPage($varPage = 'page', $default = 1)\n    {\n        $page = Request::instance()->request($varPage);\n\n        if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int) $page >= 1) {\n            return $page;\n        }\n\n        return $default;\n    }\n\n    /**\n     * 自动获取当前的path\n     * @return string\n     */\n    public static function getCurrentPath()\n    {\n        return Request::instance()->baseUrl();\n    }\n\n    public function total()\n    {\n        if ($this->simple) {\n            throw new \\DomainException('not support total');\n        }\n        return $this->total;\n    }\n\n    public function listRows()\n    {\n        return $this->listRows;\n    }\n\n    public function currentPage()\n    {\n        return $this->currentPage;\n    }\n\n    public function lastPage()\n    {\n        if ($this->simple) {\n            throw new \\DomainException('not support last');\n        }\n        return $this->lastPage;\n    }\n\n    /**\n     * 数据是否足够分页\n     * @return boolean\n     */\n    public function hasPages()\n    {\n        return !(1 == $this->currentPage && !$this->hasMore);\n    }\n\n    /**\n     * 创建一组分页链接\n     *\n     * @param  int $start\n     * @param  int $end\n     * @return array\n     */\n    public function getUrlRange($start, $end)\n    {\n        $urls = [];\n\n        for ($page = $start; $page <= $end; $page++) {\n            $urls[$page] = $this->url($page);\n        }\n\n        return $urls;\n    }\n\n    /**\n     * 设置URL锚点\n     *\n     * @param  string|null $fragment\n     * @return $this\n     */\n    public function fragment($fragment)\n    {\n        $this->options['fragment'] = $fragment;\n        return $this;\n    }\n\n    /**\n     * 添加URL参数\n     *\n     * @param  array|string $key\n     * @param  string|null  $value\n     * @return $this\n     */\n    public function appends($key, $value = null)\n    {\n        if (!is_array($key)) {\n            $queries = [$key => $value];\n        } else {\n            $queries = $key;\n        }\n\n        foreach ($queries as $k => $v) {\n            if ($k !== $this->options['var_page']) {\n                $this->options['query'][$k] = $v;\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * 构造锚点字符串\n     *\n     * @return string\n     */\n    protected function buildFragment()\n    {\n        return $this->options['fragment'] ? '#' . $this->options['fragment'] : '';\n    }\n\n    /**\n     * 渲染分页html\n     * @return mixed\n     */\n    abstract public function render();\n\n    public function items()\n    {\n        return $this->items->all();\n    }\n\n    public function getCollection()\n    {\n        return $this->items;\n    }\n\n    public function isEmpty()\n    {\n        return $this->items->isEmpty();\n    }\n\n    /**\n     * Retrieve an external iterator\n     * @return Traversable An instance of an object implementing <b>Iterator</b> or\n     * <b>Traversable</b>\n     */\n    public function getIterator()\n    {\n        return new ArrayIterator($this->items->all());\n    }\n\n    /**\n     * Whether a offset exists\n     * @param mixed $offset\n     * @return bool\n     */\n    public function offsetExists($offset)\n    {\n        return $this->items->offsetExists($offset);\n    }\n\n    /**\n     * Offset to retrieve\n     * @param mixed $offset\n     * @return mixed\n     */\n    public function offsetGet($offset)\n    {\n        return $this->items->offsetGet($offset);\n    }\n\n    /**\n     * Offset to set\n     * @param mixed $offset\n     * @param mixed $value\n     */\n    public function offsetSet($offset, $value)\n    {\n        $this->items->offsetSet($offset, $value);\n    }\n\n    /**\n     * Offset to unset\n     * @param mixed $offset\n     * @return void\n     * @since 5.0.0\n     */\n    public function offsetUnset($offset)\n    {\n        $this->items->offsetUnset($offset);\n    }\n\n    /**\n     * Count elements of an object\n     */\n    public function count()\n    {\n        return $this->items->count();\n    }\n\n    public function __toString()\n    {\n        return (string) $this->render();\n    }\n\n    public function toArray()\n    {\n        try {\n            $total = $this->total();\n        } catch (\\DomainException $e) {\n            $total = null;\n        }\n\n        return [\n            'total'        => $total,\n            'per_page'     => $this->listRows(),\n            'current_page' => $this->currentPage(),\n            'data'         => $this->items->toArray(),\n        ];\n    }\n\n    /**\n     * Specify data which should be serialized to JSON\n     */\n    public function jsonSerialize()\n    {\n        return $this->toArray();\n    }\n\n    public function __call($name, $arguments)\n    {\n        return call_user_func_array([$this->getCollection(), $name], $arguments);\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/Process.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\process\\exception\\Failed as ProcessFailedException;\nuse think\\process\\exception\\Timeout as ProcessTimeoutException;\nuse think\\process\\pipes\\Pipes;\nuse think\\process\\pipes\\Unix as UnixPipes;\nuse think\\process\\pipes\\Windows as WindowsPipes;\nuse think\\process\\Utils;\n\nclass Process\n{\n\n    const ERR = 'err';\n    const OUT = 'out';\n\n    const STATUS_READY      = 'ready';\n    const STATUS_STARTED    = 'started';\n    const STATUS_TERMINATED = 'terminated';\n\n    const STDIN  = 0;\n    const STDOUT = 1;\n    const STDERR = 2;\n\n    const TIMEOUT_PRECISION = 0.2;\n\n    private $callback;\n    private $commandline;\n    private $cwd;\n    private $env;\n    private $input;\n    private $starttime;\n    private $lastOutputTime;\n    private $timeout;\n    private $idleTimeout;\n    private $options;\n    private $exitcode;\n    private $fallbackExitcode;\n    private $processInformation;\n    private $outputDisabled = false;\n    private $stdout;\n    private $stderr;\n    private $enhanceWindowsCompatibility = true;\n    private $enhanceSigchildCompatibility;\n    private $process;\n    private $status                       = self::STATUS_READY;\n    private $incrementalOutputOffset      = 0;\n    private $incrementalErrorOutputOffset = 0;\n    private $tty;\n    private $pty;\n\n    private $useFileHandles = false;\n\n    /** @var Pipes */\n    private $processPipes;\n\n    private $latestSignal;\n\n    private static $sigchild;\n\n    /**\n     * @var array\n     */\n    public static $exitCodes = [\n        0   => 'OK',\n        1   => 'General error',\n        2   => 'Misuse of shell builtins',\n        126 => 'Invoked command cannot execute',\n        127 => 'Command not found',\n        128 => 'Invalid exit argument',\n        // signals\n        129 => 'Hangup',\n        130 => 'Interrupt',\n        131 => 'Quit and dump core',\n        132 => 'Illegal instruction',\n        133 => 'Trace/breakpoint trap',\n        134 => 'Process aborted',\n        135 => 'Bus error: \"access to undefined portion of memory object\"',\n        136 => 'Floating point exception: \"erroneous arithmetic operation\"',\n        137 => 'Kill (terminate immediately)',\n        138 => 'User-defined 1',\n        139 => 'Segmentation violation',\n        140 => 'User-defined 2',\n        141 => 'Write to pipe with no one reading',\n        142 => 'Signal raised by alarm',\n        143 => 'Termination (request to terminate)',\n        // 144 - not defined\n        145 => 'Child process terminated, stopped (or continued*)',\n        146 => 'Continue if stopped',\n        147 => 'Stop executing temporarily',\n        148 => 'Terminal stop signal',\n        149 => 'Background process attempting to read from tty (\"in\")',\n        150 => 'Background process attempting to write to tty (\"out\")',\n        151 => 'Urgent data available on socket',\n        152 => 'CPU time limit exceeded',\n        153 => 'File size limit exceeded',\n        154 => 'Signal raised by timer counting virtual time: \"virtual timer expired\"',\n        155 => 'Profiling timer expired',\n        // 156 - not defined\n        157 => 'Pollable event',\n        // 158 - not defined\n        159 => 'Bad syscall',\n    ];\n\n    /**\n     * 构造方法\n     * @param string         $commandline 指令\n     * @param string|null    $cwd         工作目录\n     * @param array|null     $env         环境变量\n     * @param string|null    $input       输入\n     * @param int|float|null $timeout     超时时间\n     * @param array          $options     proc_open的选项\n     * @throws \\RuntimeException\n     * @api\n     */\n    public function __construct($commandline, $cwd = null, array $env = null, $input = null, $timeout = 60, array $options = [])\n    {\n        if (!function_exists('proc_open')) {\n            throw new \\RuntimeException('The Process class relies on proc_open, which is not available on your PHP installation.');\n        }\n\n        $this->commandline = $commandline;\n        $this->cwd         = $cwd;\n\n        if (null === $this->cwd && (defined('ZEND_THREAD_SAFE') || '\\\\' === DS)) {\n            $this->cwd = getcwd();\n        }\n        if (null !== $env) {\n            $this->setEnv($env);\n        }\n\n        $this->input = $input;\n        $this->setTimeout($timeout);\n        $this->useFileHandles               = '\\\\' === DS;\n        $this->pty                          = false;\n        $this->enhanceWindowsCompatibility  = true;\n        $this->enhanceSigchildCompatibility = '\\\\' !== DS && $this->isSigchildEnabled();\n        $this->options                      = array_replace([\n            'suppress_errors' => true,\n            'binary_pipes'    => true,\n        ], $options);\n    }\n\n    public function __destruct()\n    {\n        $this->stop();\n    }\n\n    public function __clone()\n    {\n        $this->resetProcessData();\n    }\n\n    /**\n     * 运行指令\n     * @param callback|null $callback\n     * @return int\n     */\n    public function run($callback = null)\n    {\n        $this->start($callback);\n\n        return $this->wait();\n    }\n\n    /**\n     * 运行指令\n     * @param callable|null $callback\n     * @return self\n     * @throws \\RuntimeException\n     * @throws ProcessFailedException\n     */\n    public function mustRun($callback = null)\n    {\n        if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) {\n            throw new \\RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');\n        }\n\n        if (0 !== $this->run($callback)) {\n            throw new ProcessFailedException($this);\n        }\n\n        return $this;\n    }\n\n    /**\n     * 启动进程并写到 STDIN 输入后返回。\n     * @param callable|null $callback\n     * @throws \\RuntimeException\n     * @throws \\RuntimeException\n     * @throws \\LogicException\n     */\n    public function start($callback = null)\n    {\n        if ($this->isRunning()) {\n            throw new \\RuntimeException('Process is already running');\n        }\n        if ($this->outputDisabled && null !== $callback) {\n            throw new \\LogicException('Output has been disabled, enable it to allow the use of a callback.');\n        }\n\n        $this->resetProcessData();\n        $this->starttime = $this->lastOutputTime = microtime(true);\n        $this->callback  = $this->buildCallback($callback);\n        $descriptors     = $this->getDescriptors();\n\n        $commandline = $this->commandline;\n\n        if ('\\\\' === DS && $this->enhanceWindowsCompatibility) {\n            $commandline = 'cmd /V:ON /E:ON /C \"(' . $commandline . ')';\n            foreach ($this->processPipes->getFiles() as $offset => $filename) {\n                $commandline .= ' ' . $offset . '>' . Utils::escapeArgument($filename);\n            }\n            $commandline .= '\"';\n\n            if (!isset($this->options['bypass_shell'])) {\n                $this->options['bypass_shell'] = true;\n            }\n        }\n\n        $this->process = proc_open($commandline, $descriptors, $this->processPipes->pipes, $this->cwd, $this->env, $this->options);\n\n        if (!is_resource($this->process)) {\n            throw new \\RuntimeException('Unable to launch a new process.');\n        }\n        $this->status = self::STATUS_STARTED;\n\n        if ($this->tty) {\n            return;\n        }\n\n        $this->updateStatus(false);\n        $this->checkTimeout();\n    }\n\n    /**\n     * 重启进程\n     * @param callable|null $callback\n     * @return Process\n     * @throws \\RuntimeException\n     * @throws \\RuntimeException\n     */\n    public function restart($callback = null)\n    {\n        if ($this->isRunning()) {\n            throw new \\RuntimeException('Process is already running');\n        }\n\n        $process = clone $this;\n        $process->start($callback);\n\n        return $process;\n    }\n\n    /**\n     * 等待要终止的进程\n     * @param callable|null $callback\n     * @return int\n     */\n    public function wait($callback = null)\n    {\n        $this->requireProcessIsStarted(__FUNCTION__);\n\n        $this->updateStatus(false);\n        if (null !== $callback) {\n            $this->callback = $this->buildCallback($callback);\n        }\n\n        do {\n            $this->checkTimeout();\n            $running = '\\\\' === DS ? $this->isRunning() : $this->processPipes->areOpen();\n            $close   = '\\\\' !== DS || !$running;\n            $this->readPipes(true, $close);\n        } while ($running);\n\n        while ($this->isRunning()) {\n            usleep(1000);\n        }\n\n        if ($this->processInformation['signaled'] && $this->processInformation['termsig'] !== $this->latestSignal) {\n            throw new \\RuntimeException(sprintf('The process has been signaled with signal \"%s\".', $this->processInformation['termsig']));\n        }\n\n        return $this->exitcode;\n    }\n\n    /**\n     * 获取PID\n     * @return int|null\n     * @throws \\RuntimeException\n     */\n    public function getPid()\n    {\n        if ($this->isSigchildEnabled()) {\n            throw new \\RuntimeException('This PHP has been compiled with --enable-sigchild. The process identifier can not be retrieved.');\n        }\n\n        $this->updateStatus(false);\n\n        return $this->isRunning() ? $this->processInformation['pid'] : null;\n    }\n\n    /**\n     * 将一个 POSIX 信号发送到进程中\n     * @param int $signal\n     * @return Process\n     */\n    public function signal($signal)\n    {\n        $this->doSignal($signal, true);\n\n        return $this;\n    }\n\n    /**\n     * 禁用从底层过程获取输出和错误输出。\n     * @return Process\n     */\n    public function disableOutput()\n    {\n        if ($this->isRunning()) {\n            throw new \\RuntimeException('Disabling output while the process is running is not possible.');\n        }\n        if (null !== $this->idleTimeout) {\n            throw new \\LogicException('Output can not be disabled while an idle timeout is set.');\n        }\n\n        $this->outputDisabled = true;\n\n        return $this;\n    }\n\n    /**\n     * 开启从底层过程获取输出和错误输出。\n     * @return Process\n     * @throws \\RuntimeException\n     */\n    public function enableOutput()\n    {\n        if ($this->isRunning()) {\n            throw new \\RuntimeException('Enabling output while the process is running is not possible.');\n        }\n\n        $this->outputDisabled = false;\n\n        return $this;\n    }\n\n    /**\n     * 输出是否禁用\n     * @return bool\n     */\n    public function isOutputDisabled()\n    {\n        return $this->outputDisabled;\n    }\n\n    /**\n     * 获取当前的输出管道\n     * @return string\n     * @throws \\LogicException\n     * @throws \\LogicException\n     * @api\n     */\n    public function getOutput()\n    {\n        if ($this->outputDisabled) {\n            throw new \\LogicException('Output has been disabled.');\n        }\n\n        $this->requireProcessIsStarted(__FUNCTION__);\n\n        $this->readPipes(false, '\\\\' === DS ? !$this->processInformation['running'] : true);\n\n        return $this->stdout;\n    }\n\n    /**\n     * 以增量方式返回的输出结果。\n     * @return string\n     */\n    public function getIncrementalOutput()\n    {\n        $this->requireProcessIsStarted(__FUNCTION__);\n\n        $data = $this->getOutput();\n\n        $latest = substr($data, $this->incrementalOutputOffset);\n\n        if (false === $latest) {\n            return '';\n        }\n\n        $this->incrementalOutputOffset = strlen($data);\n\n        return $latest;\n    }\n\n    /**\n     * 清空输出\n     * @return Process\n     */\n    public function clearOutput()\n    {\n        $this->stdout                  = '';\n        $this->incrementalOutputOffset = 0;\n\n        return $this;\n    }\n\n    /**\n     * 返回当前的错误输出的过程 (STDERR)。\n     * @return string\n     */\n    public function getErrorOutput()\n    {\n        if ($this->outputDisabled) {\n            throw new \\LogicException('Output has been disabled.');\n        }\n\n        $this->requireProcessIsStarted(__FUNCTION__);\n\n        $this->readPipes(false, '\\\\' === DS ? !$this->processInformation['running'] : true);\n\n        return $this->stderr;\n    }\n\n    /**\n     * 以增量方式返回 errorOutput\n     * @return string\n     */\n    public function getIncrementalErrorOutput()\n    {\n        $this->requireProcessIsStarted(__FUNCTION__);\n\n        $data = $this->getErrorOutput();\n\n        $latest = substr($data, $this->incrementalErrorOutputOffset);\n\n        if (false === $latest) {\n            return '';\n        }\n\n        $this->incrementalErrorOutputOffset = strlen($data);\n\n        return $latest;\n    }\n\n    /**\n     * 清空 errorOutput\n     * @return Process\n     */\n    public function clearErrorOutput()\n    {\n        $this->stderr                       = '';\n        $this->incrementalErrorOutputOffset = 0;\n\n        return $this;\n    }\n\n    /**\n     * 获取退出码\n     * @return null|int\n     */\n    public function getExitCode()\n    {\n        if ($this->isSigchildEnabled() && !$this->enhanceSigchildCompatibility) {\n            throw new \\RuntimeException('This PHP has been compiled with --enable-sigchild. You must use setEnhanceSigchildCompatibility() to use this method.');\n        }\n\n        $this->updateStatus(false);\n\n        return $this->exitcode;\n    }\n\n    /**\n     * 获取退出文本\n     * @return null|string\n     */\n    public function getExitCodeText()\n    {\n        if (null === $exitcode = $this->getExitCode()) {\n            return;\n        }\n\n        return isset(self::$exitCodes[$exitcode]) ? self::$exitCodes[$exitcode] : 'Unknown error';\n    }\n\n    /**\n     * 检查是否成功\n     * @return bool\n     */\n    public function isSuccessful()\n    {\n        return 0 === $this->getExitCode();\n    }\n\n    /**\n     * 是否未捕获的信号已被终止子进程\n     * @return bool\n     */\n    public function hasBeenSignaled()\n    {\n        $this->requireProcessIsTerminated(__FUNCTION__);\n\n        if ($this->isSigchildEnabled()) {\n            throw new \\RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');\n        }\n\n        $this->updateStatus(false);\n\n        return $this->processInformation['signaled'];\n    }\n\n    /**\n     * 返回导致子进程终止其执行的数。\n     * @return int\n     */\n    public function getTermSignal()\n    {\n        $this->requireProcessIsTerminated(__FUNCTION__);\n\n        if ($this->isSigchildEnabled()) {\n            throw new \\RuntimeException('This PHP has been compiled with --enable-sigchild. Term signal can not be retrieved.');\n        }\n\n        $this->updateStatus(false);\n\n        return $this->processInformation['termsig'];\n    }\n\n    /**\n     * 检查子进程信号是否已停止\n     * @return bool\n     */\n    public function hasBeenStopped()\n    {\n        $this->requireProcessIsTerminated(__FUNCTION__);\n\n        $this->updateStatus(false);\n\n        return $this->processInformation['stopped'];\n    }\n\n    /**\n     * 返回导致子进程停止其执行的数。\n     * @return int\n     */\n    public function getStopSignal()\n    {\n        $this->requireProcessIsTerminated(__FUNCTION__);\n\n        $this->updateStatus(false);\n\n        return $this->processInformation['stopsig'];\n    }\n\n    /**\n     * 检查是否正在运行\n     * @return bool\n     */\n    public function isRunning()\n    {\n        if (self::STATUS_STARTED !== $this->status) {\n            return false;\n        }\n\n        $this->updateStatus(false);\n\n        return $this->processInformation['running'];\n    }\n\n    /**\n     * 检查是否已开始\n     * @return bool\n     */\n    public function isStarted()\n    {\n        return self::STATUS_READY != $this->status;\n    }\n\n    /**\n     * 检查是否已终止\n     * @return bool\n     */\n    public function isTerminated()\n    {\n        $this->updateStatus(false);\n\n        return self::STATUS_TERMINATED == $this->status;\n    }\n\n    /**\n     * 获取当前的状态\n     * @return string\n     */\n    public function getStatus()\n    {\n        $this->updateStatus(false);\n\n        return $this->status;\n    }\n\n    /**\n     * 终止进程\n     */\n    public function stop()\n    {\n        if ($this->isRunning()) {\n            if ('\\\\' === DS && !$this->isSigchildEnabled()) {\n                exec(sprintf('taskkill /F /T /PID %d 2>&1', $this->getPid()), $output, $exitCode);\n                if ($exitCode > 0) {\n                    throw new \\RuntimeException('Unable to kill the process');\n                }\n            } else {\n                $pids = preg_split('/\\s+/', `ps -o pid --no-heading --ppid {$this->getPid()}`);\n                foreach ($pids as $pid) {\n                    if (is_numeric($pid)) {\n                        posix_kill($pid, 9);\n                    }\n                }\n            }\n        }\n\n        $this->updateStatus(false);\n        if ($this->processInformation['running']) {\n            $this->close();\n        }\n\n        return $this->exitcode;\n    }\n\n    /**\n     * 添加一行输出\n     * @param string $line\n     */\n    public function addOutput($line)\n{\n        $this->lastOutputTime = microtime(true);\n        $this->stdout .= $line;\n    }\n\n    /**\n     * 添加一行错误输出\n     * @param string $line\n     */\n    public function addErrorOutput($line)\n{\n        $this->lastOutputTime = microtime(true);\n        $this->stderr .= $line;\n    }\n\n    /**\n     * 获取被执行的指令\n     * @return string\n     */\n    public function getCommandLine()\n{\n        return $this->commandline;\n    }\n\n    /**\n     * 设置指令\n     * @param string $commandline\n     * @return self\n     */\n    public function setCommandLine($commandline)\n{\n        $this->commandline = $commandline;\n\n        return $this;\n    }\n\n    /**\n     * 获取超时时间\n     * @return float|null\n     */\n    public function getTimeout()\n{\n        return $this->timeout;\n    }\n\n    /**\n     * 获取idle超时时间\n     * @return float|null\n     */\n    public function getIdleTimeout()\n{\n        return $this->idleTimeout;\n    }\n\n    /**\n     * 设置超时时间\n     * @param int|float|null $timeout\n     * @return self\n     */\n    public function setTimeout($timeout)\n{\n        $this->timeout = $this->validateTimeout($timeout);\n\n        return $this;\n    }\n\n    /**\n     * 设置idle超时时间\n     * @param int|float|null $timeout\n     * @return self\n     */\n    public function setIdleTimeout($timeout)\n{\n        if (null !== $timeout && $this->outputDisabled) {\n            throw new \\LogicException('Idle timeout can not be set while the output is disabled.');\n        }\n\n        $this->idleTimeout = $this->validateTimeout($timeout);\n\n        return $this;\n    }\n\n    /**\n     * 设置TTY\n     * @param bool $tty\n     * @return self\n     */\n    public function setTty($tty)\n{\n        if ('\\\\' === DS && $tty) {\n            throw new \\RuntimeException('TTY mode is not supported on Windows platform.');\n        }\n        if ($tty && (!file_exists('/dev/tty') || !is_readable('/dev/tty'))) {\n            throw new \\RuntimeException('TTY mode requires /dev/tty to be readable.');\n        }\n\n        $this->tty = (bool) $tty;\n\n        return $this;\n    }\n\n    /**\n     * 检查是否是tty模式\n     * @return bool\n     */\n    public function isTty()\n{\n        return $this->tty;\n    }\n\n    /**\n     * 设置pty模式\n     * @param bool $bool\n     * @return self\n     */\n    public function setPty($bool)\n{\n        $this->pty = (bool) $bool;\n\n        return $this;\n    }\n\n    /**\n     * 是否是pty模式\n     * @return bool\n     */\n    public function isPty()\n{\n        return $this->pty;\n    }\n\n    /**\n     * 获取工作目录\n     * @return string|null\n     */\n    public function getWorkingDirectory()\n{\n        if (null === $this->cwd) {\n            return getcwd() ?: null;\n        }\n\n        return $this->cwd;\n    }\n\n    /**\n     * 设置工作目录\n     * @param string $cwd\n     * @return self\n     */\n    public function setWorkingDirectory($cwd)\n{\n        $this->cwd = $cwd;\n\n        return $this;\n    }\n\n    /**\n     * 获取环境变量\n     * @return array\n     */\n    public function getEnv()\n{\n        return $this->env;\n    }\n\n    /**\n     * 设置环境变量\n     * @param array $env\n     * @return self\n     */\n    public function setEnv(array $env)\n{\n        $env = array_filter($env, function ($value) {\n            return !is_array($value);\n        });\n\n        $this->env = [];\n        foreach ($env as $key => $value) {\n            $this->env[(binary) $key] = (binary) $value;\n        }\n\n        return $this;\n    }\n\n    /**\n     * 获取输入\n     * @return null|string\n     */\n    public function getInput()\n{\n        return $this->input;\n    }\n\n    /**\n     * 设置输入\n     * @param mixed $input\n     * @return self\n     */\n    public function setInput($input)\n{\n        if ($this->isRunning()) {\n            throw new \\LogicException('Input can not be set while the process is running.');\n        }\n\n        $this->input = Utils::validateInput(sprintf('%s::%s', __CLASS__, __FUNCTION__), $input);\n\n        return $this;\n    }\n\n    /**\n     * 获取proc_open的选项\n     * @return array\n     */\n    public function getOptions()\n{\n        return $this->options;\n    }\n\n    /**\n     * 设置proc_open的选项\n     * @param array $options\n     * @return self\n     */\n    public function setOptions(array $options)\n{\n        $this->options = $options;\n\n        return $this;\n    }\n\n    /**\n     * 是否兼容windows\n     * @return bool\n     */\n    public function getEnhanceWindowsCompatibility()\n{\n        return $this->enhanceWindowsCompatibility;\n    }\n\n    /**\n     * 设置是否兼容windows\n     * @param bool $enhance\n     * @return self\n     */\n    public function setEnhanceWindowsCompatibility($enhance)\n{\n        $this->enhanceWindowsCompatibility = (bool) $enhance;\n\n        return $this;\n    }\n\n    /**\n     * 返回是否 sigchild 兼容模式激活\n     * @return bool\n     */\n    public function getEnhanceSigchildCompatibility()\n{\n        return $this->enhanceSigchildCompatibility;\n    }\n\n    /**\n     * 激活 sigchild 兼容性模式。\n     * @param bool $enhance\n     * @return self\n     */\n    public function setEnhanceSigchildCompatibility($enhance)\n{\n        $this->enhanceSigchildCompatibility = (bool) $enhance;\n\n        return $this;\n    }\n\n    /**\n     * 是否超时\n     */\n    public function checkTimeout()\n{\n        if (self::STATUS_STARTED !== $this->status) {\n            return;\n        }\n\n        if (null !== $this->timeout && $this->timeout < microtime(true) - $this->starttime) {\n            $this->stop();\n\n            throw new ProcessTimeoutException($this, ProcessTimeoutException::TYPE_GENERAL);\n        }\n\n        if (null !== $this->idleTimeout && $this->idleTimeout < microtime(true) - $this->lastOutputTime) {\n            $this->stop();\n\n            throw new ProcessTimeoutException($this, ProcessTimeoutException::TYPE_IDLE);\n        }\n    }\n\n    /**\n     * 是否支持pty\n     * @return bool\n     */\n    public static function isPtySupported()\n{\n        static $result;\n\n        if (null !== $result) {\n            return $result;\n        }\n\n        if ('\\\\' === DS) {\n            return $result = false;\n        }\n\n        $proc = @proc_open('echo 1', [['pty'], ['pty'], ['pty']], $pipes);\n        if (is_resource($proc)) {\n            proc_close($proc);\n\n            return $result = true;\n        }\n\n        return $result = false;\n    }\n\n    /**\n     * 创建所需的 proc_open 的描述符\n     * @return array\n     */\n    private function getDescriptors()\n{\n        if ('\\\\' === DS) {\n            $this->processPipes = WindowsPipes::create($this, $this->input);\n        } else {\n            $this->processPipes = UnixPipes::create($this, $this->input);\n        }\n        $descriptors = $this->processPipes->getDescriptors($this->outputDisabled);\n\n        if (!$this->useFileHandles && $this->enhanceSigchildCompatibility && $this->isSigchildEnabled()) {\n\n            $descriptors = array_merge($descriptors, [['pipe', 'w']]);\n\n            $this->commandline = '(' . $this->commandline . ') 3>/dev/null; code=$?; echo $code >&3; exit $code';\n        }\n\n        return $descriptors;\n    }\n\n    /**\n     * 建立 wait () 使用的回调。\n     * @param callable|null $callback\n     * @return callable\n     */\n    protected function buildCallback($callback)\n{\n        $out      = self::OUT;\n        $callback = function ($type, $data) use ($callback, $out) {\n            if ($out == $type) {\n                $this->addOutput($data);\n            } else {\n                $this->addErrorOutput($data);\n            }\n\n            if (null !== $callback) {\n                call_user_func($callback, $type, $data);\n            }\n        };\n\n        return $callback;\n    }\n\n    /**\n     * 更新状态\n     * @param bool $blocking\n     */\n    protected function updateStatus($blocking)\n{\n        if (self::STATUS_STARTED !== $this->status) {\n            return;\n        }\n\n        $this->processInformation = proc_get_status($this->process);\n        $this->captureExitCode();\n\n        $this->readPipes($blocking, '\\\\' === DS ? !$this->processInformation['running'] : true);\n\n        if (!$this->processInformation['running']) {\n            $this->close();\n        }\n    }\n\n    /**\n     * 是否开启 '--enable-sigchild'\n     * @return bool\n     */\n    protected function isSigchildEnabled()\n{\n        if (null !== self::$sigchild) {\n            return self::$sigchild;\n        }\n\n        if (!function_exists('phpinfo')) {\n            return self::$sigchild = false;\n        }\n\n        ob_start();\n        phpinfo(INFO_GENERAL);\n\n        return self::$sigchild = false !== strpos(ob_get_clean(), '--enable-sigchild');\n    }\n\n    /**\n     * 验证是否超时\n     * @param int|float|null $timeout\n     * @return float|null\n     */\n    private function validateTimeout($timeout)\n{\n        $timeout = (float) $timeout;\n\n        if (0.0 === $timeout) {\n            $timeout = null;\n        } elseif ($timeout < 0) {\n            throw new \\InvalidArgumentException('The timeout value must be a valid positive integer or float number.');\n        }\n\n        return $timeout;\n    }\n\n    /**\n     * 读取pipes\n     * @param bool $blocking\n     * @param bool $close\n     */\n    private function readPipes($blocking, $close)\n{\n        $result = $this->processPipes->readAndWrite($blocking, $close);\n\n        $callback = $this->callback;\n        foreach ($result as $type => $data) {\n            if (3 == $type) {\n                $this->fallbackExitcode = (int) $data;\n            } else {\n                $callback(self::STDOUT === $type ? self::OUT : self::ERR, $data);\n            }\n        }\n    }\n\n    /**\n     * 捕获退出码\n     */\n    private function captureExitCode()\n{\n        if (isset($this->processInformation['exitcode']) && -1 != $this->processInformation['exitcode']) {\n            $this->exitcode = $this->processInformation['exitcode'];\n        }\n    }\n\n    /**\n     * 关闭资源\n     * @return int 退出码\n     */\n    private function close()\n{\n        $this->processPipes->close();\n        if (is_resource($this->process)) {\n            $exitcode = proc_close($this->process);\n        } else {\n            $exitcode = -1;\n        }\n\n        $this->exitcode = -1 !== $exitcode ? $exitcode : (null !== $this->exitcode ? $this->exitcode : -1);\n        $this->status   = self::STATUS_TERMINATED;\n\n        if (-1 === $this->exitcode && null !== $this->fallbackExitcode) {\n            $this->exitcode = $this->fallbackExitcode;\n        } elseif (-1 === $this->exitcode && $this->processInformation['signaled']\n            && 0 < $this->processInformation['termsig']\n        ) {\n            $this->exitcode = 128 + $this->processInformation['termsig'];\n        }\n\n        return $this->exitcode;\n    }\n\n    /**\n     * 重置数据\n     */\n    private function resetProcessData()\n{\n        $this->starttime                    = null;\n        $this->callback                     = null;\n        $this->exitcode                     = null;\n        $this->fallbackExitcode             = null;\n        $this->processInformation           = null;\n        $this->stdout                       = null;\n        $this->stderr                       = null;\n        $this->process                      = null;\n        $this->latestSignal                 = null;\n        $this->status                       = self::STATUS_READY;\n        $this->incrementalOutputOffset      = 0;\n        $this->incrementalErrorOutputOffset = 0;\n    }\n\n    /**\n     * 将一个 POSIX 信号发送到进程中。\n     * @param int  $signal\n     * @param bool $throwException\n     * @return bool\n     */\n    private function doSignal($signal, $throwException)\n{\n        if (!$this->isRunning()) {\n            if ($throwException) {\n                throw new \\LogicException('Can not send signal on a non running process.');\n            }\n\n            return false;\n        }\n\n        if ($this->isSigchildEnabled()) {\n            if ($throwException) {\n                throw new \\RuntimeException('This PHP has been compiled with --enable-sigchild. The process can not be signaled.');\n            }\n\n            return false;\n        }\n\n        if (true !== @proc_terminate($this->process, $signal)) {\n            if ($throwException) {\n                throw new \\RuntimeException(sprintf('Error while sending signal `%s`.', $signal));\n            }\n\n            return false;\n        }\n\n        $this->latestSignal = $signal;\n\n        return true;\n    }\n\n    /**\n     * 确保进程已经开启\n     * @param string $functionName\n     */\n    private function requireProcessIsStarted($functionName)\n{\n        if (!$this->isStarted()) {\n            throw new \\LogicException(sprintf('Process must be started before calling %s.', $functionName));\n        }\n    }\n\n    /**\n     * 确保进程已经终止\n     * @param string $functionName\n     */\n    private function requireProcessIsTerminated($functionName)\n{\n        if (!$this->isTerminated()) {\n            throw new \\LogicException(sprintf('Process must be terminated before calling %s.', $functionName));\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Request.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nclass Request\n{\n    /**\n     * @var object 对象实例\n     */\n    protected static $instance;\n\n    protected $method;\n    /**\n     * @var string 域名（含协议和端口）\n     */\n    protected $domain;\n\n    /**\n     * @var string URL地址\n     */\n    protected $url;\n\n    /**\n     * @var string 基础URL\n     */\n    protected $baseUrl;\n\n    /**\n     * @var string 当前执行的文件\n     */\n    protected $baseFile;\n\n    /**\n     * @var string 访问的ROOT地址\n     */\n    protected $root;\n\n    /**\n     * @var string pathinfo\n     */\n    protected $pathinfo;\n\n    /**\n     * @var string pathinfo（不含后缀）\n     */\n    protected $path;\n\n    /**\n     * @var array 当前路由信息\n     */\n    protected $routeInfo = [];\n\n    /**\n     * @var array 当前调度信息\n     */\n    protected $dispatch = [];\n    protected $module;\n    protected $controller;\n    protected $action;\n    // 当前语言集\n    protected $langset;\n\n    /**\n     * @var array 请求参数\n     */\n    protected $param   = [];\n    protected $get     = [];\n    protected $post    = [];\n    protected $request = [];\n    protected $route   = [];\n    protected $put;\n    protected $session = [];\n    protected $file    = [];\n    protected $cookie  = [];\n    protected $server  = [];\n    protected $header  = [];\n\n    /**\n     * @var array 资源类型\n     */\n    protected $mimeType = [\n        'xml'  => 'application/xml,text/xml,application/x-xml',\n        'json' => 'application/json,text/x-json,application/jsonrequest,text/json',\n        'js'   => 'text/javascript,application/javascript,application/x-javascript',\n        'css'  => 'text/css',\n        'rss'  => 'application/rss+xml',\n        'yaml' => 'application/x-yaml,text/yaml',\n        'atom' => 'application/atom+xml',\n        'pdf'  => 'application/pdf',\n        'text' => 'text/plain',\n        'png'  => 'image/png',\n        'jpg'  => 'image/jpg,image/jpeg,image/pjpeg',\n        'gif'  => 'image/gif',\n        'csv'  => 'text/csv',\n        'html' => 'text/html,application/xhtml+xml,*/*',\n    ];\n\n    protected $content;\n\n    // 全局过滤规则\n    protected $filter;\n    // Hook扩展方法\n    protected static $hook = [];\n    // 绑定的属性\n    protected $bind = [];\n    // php://input\n    protected $input;\n    // 请求缓存\n    protected $cache;\n    // 缓存是否检查\n    protected $isCheckCache;\n\n    /**\n     * 构造函数\n     * @access protected\n     * @param array $options 参数\n     */\n    protected function __construct($options = [])\n    {\n        foreach ($options as $name => $item) {\n            if (property_exists($this, $name)) {\n                $this->$name = $item;\n            }\n        }\n        if (is_null($this->filter)) {\n            $this->filter = Config::get('default_filter');\n        }\n        // 保存 php://input\n        $this->input = file_get_contents('php://input');\n    }\n\n    public function __call($method, $args)\n    {\n        if (array_key_exists($method, self::$hook)) {\n            array_unshift($args, $this);\n            return call_user_func_array(self::$hook[$method], $args);\n        } else {\n            throw new Exception('method not exists:' . __CLASS__ . '->' . $method);\n        }\n    }\n\n    /**\n     * Hook 方法注入\n     * @access public\n     * @param string|array  $method 方法名\n     * @param mixed         $callback callable\n     * @return void\n     */\n    public static function hook($method, $callback = null)\n    {\n        if (is_array($method)) {\n            self::$hook = array_merge(self::$hook, $method);\n        } else {\n            self::$hook[$method] = $callback;\n        }\n    }\n\n    /**\n     * 初始化\n     * @access public\n     * @param array $options 参数\n     * @return \\think\\Request\n     */\n    public static function instance($options = [])\n    {\n        if (is_null(self::$instance)) {\n            self::$instance = new static($options);\n        }\n        return self::$instance;\n    }\n\n    /**\n     * 创建一个URL请求\n     * @access public\n     * @param string    $uri URL地址\n     * @param string    $method 请求类型\n     * @param array     $params 请求参数\n     * @param array     $cookie\n     * @param array     $files\n     * @param array     $server\n     * @param string    $content\n     * @return \\think\\Request\n     */\n    public static function create($uri, $method = 'GET', $params = [], $cookie = [], $files = [], $server = [], $content = null)\n    {\n        $server['PATH_INFO']      = '';\n        $server['REQUEST_METHOD'] = strtoupper($method);\n        $info                     = parse_url($uri);\n        if (isset($info['host'])) {\n            $server['SERVER_NAME'] = $info['host'];\n            $server['HTTP_HOST']   = $info['host'];\n        }\n        if (isset($info['scheme'])) {\n            if ('https' === $info['scheme']) {\n                $server['HTTPS']       = 'on';\n                $server['SERVER_PORT'] = 443;\n            } else {\n                unset($server['HTTPS']);\n                $server['SERVER_PORT'] = 80;\n            }\n        }\n        if (isset($info['port'])) {\n            $server['SERVER_PORT'] = $info['port'];\n            $server['HTTP_HOST']   = $server['HTTP_HOST'] . ':' . $info['port'];\n        }\n        if (isset($info['user'])) {\n            $server['PHP_AUTH_USER'] = $info['user'];\n        }\n        if (isset($info['pass'])) {\n            $server['PHP_AUTH_PW'] = $info['pass'];\n        }\n        if (!isset($info['path'])) {\n            $info['path'] = '/';\n        }\n        $options                      = [];\n        $options[strtolower($method)] = $params;\n        $queryString                  = '';\n        if (isset($info['query'])) {\n            parse_str(html_entity_decode($info['query']), $query);\n            if (!empty($params)) {\n                $params      = array_replace($query, $params);\n                $queryString = http_build_query($query, '', '&');\n            } else {\n                $params      = $query;\n                $queryString = $info['query'];\n            }\n        } elseif (!empty($params)) {\n            $queryString = http_build_query($params, '', '&');\n        }\n        if ($queryString) {\n            parse_str($queryString, $get);\n            $options['get'] = isset($options['get']) ? array_merge($get, $options['get']) : $get;\n        }\n\n        $server['REQUEST_URI']  = $info['path'] . ('' !== $queryString ? '?' . $queryString : '');\n        $server['QUERY_STRING'] = $queryString;\n        $options['cookie']      = $cookie;\n        $options['param']       = $params;\n        $options['file']        = $files;\n        $options['server']      = $server;\n        $options['url']         = $server['REQUEST_URI'];\n        $options['baseUrl']     = $info['path'];\n        $options['pathinfo']    = '/' == $info['path'] ? '/' : ltrim($info['path'], '/');\n        $options['method']      = $server['REQUEST_METHOD'];\n        $options['domain']      = isset($info['scheme']) ? $info['scheme'] . '://' . $server['HTTP_HOST'] : '';\n        $options['content']     = $content;\n        self::$instance         = new self($options);\n        return self::$instance;\n    }\n\n    /**\n     * 设置或获取当前包含协议的域名\n     * @access public\n     * @param string $domain 域名\n     * @return string\n     */\n    public function domain($domain = null)\n    {\n        if (!is_null($domain)) {\n            $this->domain = $domain;\n            return $this;\n        } elseif (!$this->domain) {\n            $this->domain = $this->scheme() . '://' . $this->host();\n        }\n        return $this->domain;\n    }\n\n    /**\n     * 设置或获取当前完整URL 包括QUERY_STRING\n     * @access public\n     * @param string|true $url URL地址 true 带域名获取\n     * @return string\n     */\n    public function url($url = null)\n    {\n        if (!is_null($url) && true !== $url) {\n            $this->url = $url;\n            return $this;\n        } elseif (!$this->url) {\n            if (IS_CLI) {\n                $this->url = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';\n            } elseif (isset($_SERVER['HTTP_X_REWRITE_URL'])) {\n                $this->url = $_SERVER['HTTP_X_REWRITE_URL'];\n            } elseif (isset($_SERVER['REQUEST_URI'])) {\n                $this->url = $_SERVER['REQUEST_URI'];\n            } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {\n                $this->url = $_SERVER['ORIG_PATH_INFO'] . (!empty($_SERVER['QUERY_STRING']) ? '?' . $_SERVER['QUERY_STRING'] : '');\n            } else {\n                $this->url = '';\n            }\n        }\n        return true === $url ? $this->domain() . $this->url : $this->url;\n    }\n\n    /**\n     * 设置或获取当前URL 不含QUERY_STRING\n     * @access public\n     * @param string $url URL地址\n     * @return string\n     */\n    public function baseUrl($url = null)\n    {\n        if (!is_null($url) && true !== $url) {\n            $this->baseUrl = $url;\n            return $this;\n        } elseif (!$this->baseUrl) {\n            $str           = $this->url();\n            $this->baseUrl = strpos($str, '?') ? strstr($str, '?', true) : $str;\n        }\n        return true === $url ? $this->domain() . $this->baseUrl : $this->baseUrl;\n    }\n\n    /**\n     * 设置或获取当前执行的文件 SCRIPT_NAME\n     * @access public\n     * @param string $file 当前执行的文件\n     * @return string\n     */\n    public function baseFile($file = null)\n    {\n        if (!is_null($file) && true !== $file) {\n            $this->baseFile = $file;\n            return $this;\n        } elseif (!$this->baseFile) {\n            $url = '';\n            if (!IS_CLI) {\n                $script_name = basename($_SERVER['SCRIPT_FILENAME']);\n                if (basename($_SERVER['SCRIPT_NAME']) === $script_name) {\n                    $url = $_SERVER['SCRIPT_NAME'];\n                } elseif (basename($_SERVER['PHP_SELF']) === $script_name) {\n                    $url = $_SERVER['PHP_SELF'];\n                } elseif (isset($_SERVER['ORIG_SCRIPT_NAME']) && basename($_SERVER['ORIG_SCRIPT_NAME']) === $script_name) {\n                    $url = $_SERVER['ORIG_SCRIPT_NAME'];\n                } elseif (($pos = strpos($_SERVER['PHP_SELF'], '/' . $script_name)) !== false) {\n                    $url = substr($_SERVER['SCRIPT_NAME'], 0, $pos) . '/' . $script_name;\n                } elseif (isset($_SERVER['DOCUMENT_ROOT']) && strpos($_SERVER['SCRIPT_FILENAME'], $_SERVER['DOCUMENT_ROOT']) === 0) {\n                    $url = str_replace('\\\\', '/', str_replace($_SERVER['DOCUMENT_ROOT'], '', $_SERVER['SCRIPT_FILENAME']));\n                }\n            }\n            $this->baseFile = $url;\n        }\n        return true === $file ? $this->domain() . $this->baseFile : $this->baseFile;\n    }\n\n    /**\n     * 设置或获取URL访问根地址\n     * @access public\n     * @param string $url URL地址\n     * @return string\n     */\n    public function root($url = null)\n    {\n        if (!is_null($url) && true !== $url) {\n            $this->root = $url;\n            return $this;\n        } elseif (!$this->root) {\n            $file = $this->baseFile();\n            if ($file && 0 !== strpos($this->url(), $file)) {\n                $file = str_replace('\\\\', '/', dirname($file));\n            }\n            $this->root = rtrim($file, '/');\n        }\n        return true === $url ? $this->domain() . $this->root : $this->root;\n    }\n\n    /**\n     * 获取当前请求URL的pathinfo信息（含URL后缀）\n     * @access public\n     * @return string\n     */\n    public function pathinfo()\n    {\n        if (is_null($this->pathinfo)) {\n            if (isset($_GET[Config::get('var_pathinfo')])) {\n                // 判断URL里面是否有兼容模式参数\n                $_SERVER['PATH_INFO'] = $_GET[Config::get('var_pathinfo')];\n                unset($_GET[Config::get('var_pathinfo')]);\n            } elseif (IS_CLI) {\n                // CLI模式下 index.php module/controller/action/params/...\n                $_SERVER['PATH_INFO'] = isset($_SERVER['argv'][1]) ? $_SERVER['argv'][1] : '';\n            }\n\n            // 分析PATHINFO信息\n            if (!isset($_SERVER['PATH_INFO'])) {\n                foreach (Config::get('pathinfo_fetch') as $type) {\n                    if (!empty($_SERVER[$type])) {\n                        $_SERVER['PATH_INFO'] = (0 === strpos($_SERVER[$type], $_SERVER['SCRIPT_NAME'])) ?\n                        substr($_SERVER[$type], strlen($_SERVER['SCRIPT_NAME'])) : $_SERVER[$type];\n                        break;\n                    }\n                }\n            }\n            $this->pathinfo = empty($_SERVER['PATH_INFO']) ? '/' : ltrim($_SERVER['PATH_INFO'], '/');\n        }\n        return $this->pathinfo;\n    }\n\n    /**\n     * 获取当前请求URL的pathinfo信息(不含URL后缀)\n     * @access public\n     * @return string\n     */\n    public function path()\n    {\n        if (is_null($this->path)) {\n            $suffix   = Config::get('url_html_suffix');\n            $pathinfo = $this->pathinfo();\n            if (false === $suffix) {\n                // 禁止伪静态访问\n                $this->path = $pathinfo;\n            } elseif ($suffix) {\n                // 去除正常的URL后缀\n                $this->path = preg_replace('/\\.(' . ltrim($suffix, '.') . ')$/i', '', $pathinfo);\n            } else {\n                // 允许任何后缀访问\n                $this->path = preg_replace('/\\.' . $this->ext() . '$/i', '', $pathinfo);\n            }\n        }\n        return $this->path;\n    }\n\n    /**\n     * 当前URL的访问后缀\n     * @access public\n     * @return string\n     */\n    public function ext()\n    {\n        return pathinfo($this->pathinfo(), PATHINFO_EXTENSION);\n    }\n\n    /**\n     * 获取当前请求的时间\n     * @access public\n     * @param bool $float 是否使用浮点类型\n     * @return integer|float\n     */\n    public function time($float = false)\n    {\n        return $float ? $_SERVER['REQUEST_TIME_FLOAT'] : $_SERVER['REQUEST_TIME'];\n    }\n\n    /**\n     * 当前请求的资源类型\n     * @access public\n     * @return false|string\n     */\n    public function type()\n    {\n        $accept = $this->server('HTTP_ACCEPT');\n        if (empty($accept)) {\n            return false;\n        }\n\n        foreach ($this->mimeType as $key => $val) {\n            $array = explode(',', $val);\n            foreach ($array as $k => $v) {\n                if (stristr($accept, $v)) {\n                    return $key;\n                }\n            }\n        }\n        return false;\n    }\n\n    /**\n     * 设置资源类型\n     * @access public\n     * @param string|array  $type 资源类型名\n     * @param string        $val 资源类型\n     * @return void\n     */\n    public function mimeType($type, $val = '')\n    {\n        if (is_array($type)) {\n            $this->mimeType = array_merge($this->mimeType, $type);\n        } else {\n            $this->mimeType[$type] = $val;\n        }\n    }\n\n    /**\n     * 当前的请求类型\n     * @access public\n     * @param bool $method  true 获取原始请求类型\n     * @return string\n     */\n    public function method($method = false)\n    {\n        if (true === $method) {\n            // 获取原始请求类型\n            return IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']);\n        } elseif (!$this->method) {\n            if (isset($_POST[Config::get('var_method')])) {\n                $this->method = strtoupper($_POST[Config::get('var_method')]);\n                $this->{$this->method}($_POST);\n            } elseif (isset($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE'])) {\n                $this->method = strtoupper($_SERVER['HTTP_X_HTTP_METHOD_OVERRIDE']);\n            } else {\n                $this->method = IS_CLI ? 'GET' : (isset($this->server['REQUEST_METHOD']) ? $this->server['REQUEST_METHOD'] : $_SERVER['REQUEST_METHOD']);\n            }\n        }\n        return $this->method;\n    }\n\n    /**\n     * 是否为GET请求\n     * @access public\n     * @return bool\n     */\n    public function isGet()\n    {\n        return $this->method() == 'GET';\n    }\n\n    /**\n     * 是否为POST请求\n     * @access public\n     * @return bool\n     */\n    public function isPost()\n    {\n        return $this->method() == 'POST';\n    }\n\n    /**\n     * 是否为PUT请求\n     * @access public\n     * @return bool\n     */\n    public function isPut()\n    {\n        return $this->method() == 'PUT';\n    }\n\n    /**\n     * 是否为DELTE请求\n     * @access public\n     * @return bool\n     */\n    public function isDelete()\n    {\n        return $this->method() == 'DELETE';\n    }\n\n    /**\n     * 是否为HEAD请求\n     * @access public\n     * @return bool\n     */\n    public function isHead()\n    {\n        return $this->method() == 'HEAD';\n    }\n\n    /**\n     * 是否为PATCH请求\n     * @access public\n     * @return bool\n     */\n    public function isPatch()\n    {\n        return $this->method() == 'PATCH';\n    }\n\n    /**\n     * 是否为OPTIONS请求\n     * @access public\n     * @return bool\n     */\n    public function isOptions()\n    {\n        return $this->method() == 'OPTIONS';\n    }\n\n    /**\n     * 是否为cli\n     * @access public\n     * @return bool\n     */\n    public function isCli()\n    {\n        return PHP_SAPI == 'cli';\n    }\n\n    /**\n     * 是否为cgi\n     * @access public\n     * @return bool\n     */\n    public function isCgi()\n    {\n        return strpos(PHP_SAPI, 'cgi') === 0;\n    }\n\n    /**\n     * 获取获取当前请求的参数\n     * @access public\n     * @param string|array  $name 变量名\n     * @param mixed         $default 默认值\n     * @param string|array  $filter 过滤方法\n     * @return mixed\n     */\n    public function param($name = '', $default = null, $filter = '')\n    {\n        if (empty($this->param)) {\n            $method = $this->method(true);\n            // 自动获取请求变量\n            switch ($method) {\n                case 'POST':\n                    $vars = $this->post(false);\n                    break;\n                case 'PUT':\n                case 'DELETE':\n                case 'PATCH':\n                    $vars = $this->put(false);\n                    break;\n                default:\n                    $vars = [];\n            }\n            // 当前请求参数和URL地址中的参数合并\n            $this->param = array_merge($this->get(false), $vars, $this->route(false));\n        }\n        if (true === $name) {\n            // 获取包含文件上传信息的数组\n            $file = $this->file();\n            $data = is_array($file) ? array_merge($this->param, $file) : $this->param;\n            return $this->input($data, '', $default, $filter);\n        }\n        return $this->input($this->param, $name, $default, $filter);\n    }\n\n    /**\n     * 设置获取获取路由参数\n     * @access public\n     * @param string|array  $name 变量名\n     * @param mixed         $default 默认值\n     * @param string|array  $filter 过滤方法\n     * @return mixed\n     */\n    public function route($name = '', $default = null, $filter = '')\n    {\n        if (is_array($name)) {\n            $this->param        = [];\n            return $this->route = array_merge($this->route, $name);\n        }\n        return $this->input($this->route, $name, $default, $filter);\n    }\n\n    /**\n     * 设置获取获取GET参数\n     * @access public\n     * @param string|array  $name 变量名\n     * @param mixed         $default 默认值\n     * @param string|array  $filter 过滤方法\n     * @return mixed\n     */\n    public function get($name = '', $default = null, $filter = '')\n    {\n        if (empty($this->get)) {\n            $this->get = $_GET;\n        }\n        if (is_array($name)) {\n            $this->param      = [];\n            return $this->get = array_merge($this->get, $name);\n        }\n        return $this->input($this->get, $name, $default, $filter);\n    }\n\n    /**\n     * 设置获取获取POST参数\n     * @access public\n     * @param string        $name 变量名\n     * @param mixed         $default 默认值\n     * @param string|array  $filter 过滤方法\n     * @return mixed\n     */\n    public function post($name = '', $default = null, $filter = '')\n    {\n        if (empty($this->post)) {\n            $content = $this->input;\n            if (empty($_POST) && false !== strpos($this->contentType(), 'application/json')) {\n                $this->post = (array) json_decode($content, true);\n            } else {\n                $this->post = $_POST;\n            }\n        }\n        if (is_array($name)) {\n            $this->param       = [];\n            return $this->post = array_merge($this->post, $name);\n        }\n        return $this->input($this->post, $name, $default, $filter);\n    }\n\n    /**\n     * 设置获取获取PUT参数\n     * @access public\n     * @param string|array      $name 变量名\n     * @param mixed             $default 默认值\n     * @param string|array      $filter 过滤方法\n     * @return mixed\n     */\n    public function put($name = '', $default = null, $filter = '')\n    {\n        if (is_null($this->put)) {\n            $content = $this->input;\n            if (false !== strpos($this->contentType(), 'application/json')) {\n                $this->put = (array) json_decode($content, true);\n            } else {\n                parse_str($content, $this->put);\n            }\n        }\n        if (is_array($name)) {\n            $this->param      = [];\n            return $this->put = is_null($this->put) ? $name : array_merge($this->put, $name);\n        }\n\n        return $this->input($this->put, $name, $default, $filter);\n    }\n\n    /**\n     * 设置获取获取DELETE参数\n     * @access public\n     * @param string|array      $name 变量名\n     * @param mixed             $default 默认值\n     * @param string|array      $filter 过滤方法\n     * @return mixed\n     */\n    public function delete($name = '', $default = null, $filter = '')\n    {\n        return $this->put($name, $default, $filter);\n    }\n\n    /**\n     * 设置获取获取PATCH参数\n     * @access public\n     * @param string|array      $name 变量名\n     * @param mixed             $default 默认值\n     * @param string|array      $filter 过滤方法\n     * @return mixed\n     */\n    public function patch($name = '', $default = null, $filter = '')\n    {\n        return $this->put($name, $default, $filter);\n    }\n\n    /**\n     * 获取request变量\n     * @param string        $name 数据名称\n     * @param string        $default 默认值\n     * @param string|array  $filter 过滤方法\n     * @return mixed\n     */\n    public function request($name = '', $default = null, $filter = '')\n    {\n        if (empty($this->request)) {\n            $this->request = $_REQUEST;\n        }\n        if (is_array($name)) {\n            $this->param          = [];\n            return $this->request = array_merge($this->request, $name);\n        }\n        return $this->input($this->request, $name, $default, $filter);\n    }\n\n    /**\n     * 获取session数据\n     * @access public\n     * @param string|array  $name 数据名称\n     * @param string        $default 默认值\n     * @param string|array  $filter 过滤方法\n     * @return mixed\n     */\n    public function session($name = '', $default = null, $filter = '')\n    {\n        if (empty($this->session)) {\n            $this->session = Session::get();\n        }\n        if (is_array($name)) {\n            return $this->session = array_merge($this->session, $name);\n        }\n        return $this->input($this->session, $name, $default, $filter);\n    }\n\n    /**\n     * 获取cookie参数\n     * @access public\n     * @param string|array  $name 数据名称\n     * @param string        $default 默认值\n     * @param string|array  $filter 过滤方法\n     * @return mixed\n     */\n    public function cookie($name = '', $default = null, $filter = '')\n    {\n        if (empty($this->cookie)) {\n            $this->cookie = Cookie::get();\n        }\n        if (is_array($name)) {\n            return $this->cookie = array_merge($this->cookie, $name);\n        } elseif (!empty($name)) {\n            $data = Cookie::has($name) ? Cookie::get($name) : $default;\n        } else {\n            $data = $this->cookie;\n        }\n\n        // 解析过滤器\n        $filter = $this->getFilter($filter, $default);\n\n        if (is_array($data)) {\n            array_walk_recursive($data, [$this, 'filterValue'], $filter);\n            reset($data);\n        } else {\n            $this->filterValue($data, $name, $filter);\n        }\n        return $data;\n    }\n\n    /**\n     * 获取server参数\n     * @access public\n     * @param string|array  $name 数据名称\n     * @param string        $default 默认值\n     * @param string|array  $filter 过滤方法\n     * @return mixed\n     */\n    public function server($name = '', $default = null, $filter = '')\n    {\n        if (empty($this->server)) {\n            $this->server = $_SERVER;\n        }\n        if (is_array($name)) {\n            return $this->server = array_merge($this->server, $name);\n        }\n        return $this->input($this->server, false === $name ? false : strtoupper($name), $default, $filter);\n    }\n\n    /**\n     * 获取上传的文件信息\n     * @access public\n     * @param string|array $name 名称\n     * @return null|array|\\think\\File\n     */\n    public function file($name = '')\n    {\n        if (empty($this->file)) {\n            $this->file = isset($_FILES) ? $_FILES : [];\n        }\n        if (is_array($name)) {\n            return $this->file = array_merge($this->file, $name);\n        }\n        $files = $this->file;\n        if (!empty($files)) {\n            // 处理上传文件\n            $array = [];\n            foreach ($files as $key => $file) {\n                if (is_array($file['name'])) {\n                    $item  = [];\n                    $keys  = array_keys($file);\n                    $count = count($file['name']);\n                    for ($i = 0; $i < $count; $i++) {\n                        if (empty($file['tmp_name'][$i]) || !is_file($file['tmp_name'][$i])) {\n                            continue;\n                        }\n                        $temp['key'] = $key;\n                        foreach ($keys as $_key) {\n                            $temp[$_key] = $file[$_key][$i];\n                        }\n                        $item[] = (new File($temp['tmp_name']))->setUploadInfo($temp);\n                    }\n                    $array[$key] = $item;\n                } else {\n                    if ($file instanceof File) {\n                        $array[$key] = $file;\n                    } else {\n                        if (empty($file['tmp_name']) || !is_file($file['tmp_name'])) {\n                            continue;\n                        }\n                        $array[$key] = (new File($file['tmp_name']))->setUploadInfo($file);\n                    }\n                }\n            }\n            if (strpos($name, '.')) {\n                list($name, $sub) = explode('.', $name);\n            }\n            if ('' === $name) {\n                // 获取全部文件\n                return $array;\n            } elseif (isset($sub) && isset($array[$name][$sub])) {\n                return $array[$name][$sub];\n            } elseif (isset($array[$name])) {\n                return $array[$name];\n            }\n        }\n        return;\n    }\n\n    /**\n     * 获取环境变量\n     * @param string|array  $name 数据名称\n     * @param string        $default 默认值\n     * @param string|array  $filter 过滤方法\n     * @return mixed\n     */\n    public function env($name = '', $default = null, $filter = '')\n    {\n        if (empty($this->env)) {\n            $this->env = $_ENV;\n        }\n        if (is_array($name)) {\n            return $this->env = array_merge($this->env, $name);\n        }\n        return $this->input($this->env, false === $name ? false : strtoupper($name), $default, $filter);\n    }\n\n    /**\n     * 设置或者获取当前的Header\n     * @access public\n     * @param string|array  $name header名称\n     * @param string        $default 默认值\n     * @return string\n     */\n    public function header($name = '', $default = null)\n    {\n        if (empty($this->header)) {\n            $header = [];\n            if (function_exists('apache_request_headers') && $result = apache_request_headers()) {\n                $header = $result;\n            } else {\n                $server = $this->server ?: $_SERVER;\n                foreach ($server as $key => $val) {\n                    if (0 === strpos($key, 'HTTP_')) {\n                        $key          = str_replace('_', '-', strtolower(substr($key, 5)));\n                        $header[$key] = $val;\n                    }\n                }\n                if (isset($server['CONTENT_TYPE'])) {\n                    $header['content-type'] = $server['CONTENT_TYPE'];\n                }\n                if (isset($server['CONTENT_LENGTH'])) {\n                    $header['content-length'] = $server['CONTENT_LENGTH'];\n                }\n            }\n            $this->header = array_change_key_case($header);\n        }\n        if (is_array($name)) {\n            return $this->header = array_merge($this->header, $name);\n        }\n        if ('' === $name) {\n            return $this->header;\n        }\n        $name = str_replace('_', '-', strtolower($name));\n        return isset($this->header[$name]) ? $this->header[$name] : $default;\n    }\n\n    /**\n     * 获取变量 支持过滤和默认值\n     * @param array         $data 数据源\n     * @param string|false  $name 字段名\n     * @param mixed         $default 默认值\n     * @param string|array  $filter 过滤函数\n     * @return mixed\n     */\n    public function input($data = [], $name = '', $default = null, $filter = '')\n    {\n        if (false === $name) {\n            // 获取原始数据\n            return $data;\n        }\n        $name = (string) $name;\n        if ('' != $name) {\n            // 解析name\n            if (strpos($name, '/')) {\n                list($name, $type) = explode('/', $name);\n            } else {\n                $type = 's';\n            }\n            // 按.拆分成多维数组进行判断\n            foreach (explode('.', $name) as $val) {\n                if (isset($data[$val])) {\n                    $data = $data[$val];\n                } else {\n                    // 无输入数据，返回默认值\n                    return $default;\n                }\n            }\n            if (is_object($data)) {\n                return $data;\n            }\n        }\n\n        // 解析过滤器\n        $filter = $this->getFilter($filter, $default);\n\n        if (is_array($data)) {\n            array_walk_recursive($data, [$this, 'filterValue'], $filter);\n            reset($data);\n        } else {\n            $this->filterValue($data, $name, $filter);\n        }\n\n        if (isset($type) && $data !== $default) {\n            // 强制类型转换\n            $this->typeCast($data, $type);\n        }\n        return $data;\n    }\n\n    /**\n     * 设置或获取当前的过滤规则\n     * @param mixed $filter 过滤规则\n     * @return mixed\n     */\n    public function filter($filter = null)\n    {\n        if (is_null($filter)) {\n            return $this->filter;\n        } else {\n            $this->filter = $filter;\n        }\n    }\n\n    protected function getFilter($filter, $default)\n    {\n        if (is_null($filter)) {\n            $filter = [];\n        } else {\n            $filter = $filter ?: $this->filter;\n            if (is_string($filter)) {\n                $filter = explode(',', $filter);\n            } else {\n                $filter = (array) $filter;\n            }\n        }\n\n        $filter[] = $default;\n        return $filter;\n    }\n\n    /**\n     * 递归过滤给定的值\n     * @param mixed     $value 键值\n     * @param mixed     $key 键名\n     * @param array     $filters 过滤方法+默认值\n     * @return mixed\n     */\n    private function filterValue(&$value, $key, $filters)\n    {\n        $default = array_pop($filters);\n        foreach ($filters as $filter) {\n            if (is_callable($filter)) {\n                // 调用函数或者方法过滤\n                $value = call_user_func($filter, $value);\n            } elseif (is_scalar($value)) {\n                if (strpos($filter, '/')) {\n                    // 正则过滤\n                    if (!preg_match($filter, $value)) {\n                        // 匹配不成功返回默认值\n                        $value = $default;\n                        break;\n                    }\n                } elseif (!empty($filter)) {\n                    // filter函数不存在时, 则使用filter_var进行过滤\n                    // filter为非整形值时, 调用filter_id取得过滤id\n                    $value = filter_var($value, is_int($filter) ? $filter : filter_id($filter));\n                    if (false === $value) {\n                        $value = $default;\n                        break;\n                    }\n                }\n            }\n        }\n        return $this->filterExp($value);\n    }\n\n    /**\n     * 过滤表单中的表达式\n     * @param string $value\n     * @return void\n     */\n    public function filterExp(&$value)\n    {\n        // 过滤查询特殊字符\n        if (is_string($value) && preg_match('/^(EXP|NEQ|GT|EGT|LT|ELT|OR|XOR|LIKE|NOTLIKE|NOT BETWEEN|NOTBETWEEN|BETWEEN|NOTIN|NOT IN|IN)$/i', $value)) {\n            $value .= ' ';\n        }\n        // TODO 其他安全过滤\n    }\n\n    /**\n     * 强制类型转换\n     * @param string $data\n     * @param string $type\n     * @return mixed\n     */\n    private function typeCast(&$data, $type)\n    {\n        switch (strtolower($type)) {\n            // 数组\n            case 'a':\n                $data = (array) $data;\n                break;\n            // 数字\n            case 'd':\n                $data = (int) $data;\n                break;\n            // 浮点\n            case 'f':\n                $data = (float) $data;\n                break;\n            // 布尔\n            case 'b':\n                $data = (boolean) $data;\n                break;\n            // 字符串\n            case 's':\n            default:\n                if (is_scalar($data)) {\n                    $data = (string) $data;\n                } else {\n                    throw new \\InvalidArgumentException('variable type error：' . gettype($data));\n                }\n        }\n    }\n\n    /**\n     * 是否存在某个请求参数\n     * @access public\n     * @param string    $name 变量名\n     * @param string    $type 变量类型\n     * @param bool      $checkEmpty 是否检测空值\n     * @return mixed\n     */\n    public function has($name, $type = 'param', $checkEmpty = false)\n    {\n        if (empty($this->$type)) {\n            $param = $this->$type();\n        } else {\n            $param = $this->$type;\n        }\n        // 按.拆分成多维数组进行判断\n        foreach (explode('.', $name) as $val) {\n            if (isset($param[$val])) {\n                $param = $param[$val];\n            } else {\n                return false;\n            }\n        }\n        return ($checkEmpty && '' === $param) ? false : true;\n    }\n\n    /**\n     * 获取指定的参数\n     * @access public\n     * @param string|array  $name 变量名\n     * @param string        $type 变量类型\n     * @return mixed\n     */\n    public function only($name, $type = 'param')\n    {\n        $param = $this->$type();\n        if (is_string($name)) {\n            $name = explode(',', $name);\n        }\n        $item = [];\n        foreach ($name as $key) {\n            if (isset($param[$key])) {\n                $item[$key] = $param[$key];\n            }\n        }\n        return $item;\n    }\n\n    /**\n     * 排除指定参数获取\n     * @access public\n     * @param string|array  $name 变量名\n     * @param string        $type 变量类型\n     * @return mixed\n     */\n    public function except($name, $type = 'param')\n    {\n        $param = $this->$type();\n        if (is_string($name)) {\n            $name = explode(',', $name);\n        }\n        foreach ($name as $key) {\n            if (isset($param[$key])) {\n                unset($param[$key]);\n            }\n        }\n        return $param;\n    }\n\n    /**\n     * 当前是否ssl\n     * @access public\n     * @return bool\n     */\n    public function isSsl()\n    {\n        $server = array_merge($_SERVER, $this->server);\n        if (isset($server['HTTPS']) && ('1' == $server['HTTPS'] || 'on' == strtolower($server['HTTPS']))) {\n            return true;\n        } elseif (isset($server['REQUEST_SCHEME']) && 'https' == $server['REQUEST_SCHEME']) {\n            return true;\n        } elseif (isset($server['SERVER_PORT']) && ('443' == $server['SERVER_PORT'])) {\n            return true;\n        } elseif (isset($server['HTTP_X_FORWARDED_PROTO']) && 'https' == $server['HTTP_X_FORWARDED_PROTO']) {\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 当前是否Ajax请求\n     * @access public\n     * @param bool $ajax  true 获取原始ajax请求\n     * @return bool\n     */\n    public function isAjax($ajax = false)\n    {\n        $value  = $this->server('HTTP_X_REQUESTED_WITH', '', 'strtolower');\n        $result = ('xmlhttprequest' == $value) ? true : false;\n        if (true === $ajax) {\n            return $result;\n        } else {\n            return $this->param(Config::get('var_ajax')) ? true : $result;\n        }\n    }\n\n    /**\n     * 当前是否Pjax请求\n     * @access public\n     * @param bool $pjax  true 获取原始pjax请求\n     * @return bool\n     */\n    public function isPjax($pjax = false)\n    {\n        $result = !is_null($this->server('HTTP_X_PJAX')) ? true : false;\n        if (true === $pjax) {\n            return $result;\n        } else {\n            return $this->param(Config::get('var_pjax')) ? true : $result;\n        }\n    }\n\n    /**\n     * 获取客户端IP地址\n     * @param integer   $type 返回类型 0 返回IP地址 1 返回IPV4地址数字\n     * @param boolean   $adv 是否进行高级模式获取（有可能被伪装）\n     * @return mixed\n     */\n    public function ip($type = 0, $adv = false)\n    {\n        $type      = $type ? 1 : 0;\n        static $ip = null;\n        if (null !== $ip) {\n            return $ip[$type];\n        }\n\n        if ($adv) {\n            if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {\n                $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);\n                $pos = array_search('unknown', $arr);\n                if (false !== $pos) {\n                    unset($arr[$pos]);\n                }\n                $ip = trim(current($arr));\n            } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {\n                $ip = $_SERVER['HTTP_CLIENT_IP'];\n            } elseif (isset($_SERVER['REMOTE_ADDR'])) {\n                $ip = $_SERVER['REMOTE_ADDR'];\n            }\n        } elseif (isset($_SERVER['REMOTE_ADDR'])) {\n            $ip = $_SERVER['REMOTE_ADDR'];\n        }\n        // IP地址合法验证\n        $long = sprintf(\"%u\", ip2long($ip));\n        $ip   = $long ? [$ip, $long] : ['0.0.0.0', 0];\n        return $ip[$type];\n    }\n\n    /**\n     * 检测是否使用手机访问\n     * @access public\n     * @return bool\n     */\n    public function isMobile()\n    {\n        if (isset($_SERVER['HTTP_VIA']) && stristr($_SERVER['HTTP_VIA'], \"wap\")) {\n            return true;\n        } elseif (isset($_SERVER['HTTP_ACCEPT']) && strpos(strtoupper($_SERVER['HTTP_ACCEPT']), \"VND.WAP.WML\")) {\n            return true;\n        } elseif (isset($_SERVER['HTTP_X_WAP_PROFILE']) || isset($_SERVER['HTTP_PROFILE'])) {\n            return true;\n        } elseif (isset($_SERVER['HTTP_USER_AGENT']) && preg_match('/(blackberry|configuration\\/cldc|hp |hp-|htc |htc_|htc-|iemobile|kindle|midp|mmp|motorola|mobile|nokia|opera mini|opera |Googlebot-Mobile|YahooSeeker\\/M1A1-R2D2|android|iphone|ipod|mobi|palm|palmos|pocket|portalmmm|ppc;|smartphone|sonyericsson|sqh|spv|symbian|treo|up.browser|up.link|vodafone|windows ce|xda |xda_)/i', $_SERVER['HTTP_USER_AGENT'])) {\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * 当前URL地址中的scheme参数\n     * @access public\n     * @return string\n     */\n    public function scheme()\n    {\n        return $this->isSsl() ? 'https' : 'http';\n    }\n\n    /**\n     * 当前请求URL地址中的query参数\n     * @access public\n     * @return string\n     */\n    public function query()\n    {\n        return $this->server('QUERY_STRING');\n    }\n\n    /**\n     * 当前请求的host\n     * @access public\n     * @return string\n     */\n    public function host()\n    {\n        return $this->server('HTTP_HOST');\n    }\n\n    /**\n     * 当前请求URL地址中的port参数\n     * @access public\n     * @return integer\n     */\n    public function port()\n    {\n        return $this->server('SERVER_PORT');\n    }\n\n    /**\n     * 当前请求 SERVER_PROTOCOL\n     * @access public\n     * @return integer\n     */\n    public function protocol()\n    {\n        return $this->server('SERVER_PROTOCOL');\n    }\n\n    /**\n     * 当前请求 REMOTE_PORT\n     * @access public\n     * @return integer\n     */\n    public function remotePort()\n    {\n        return $this->server('REMOTE_PORT');\n    }\n\n    /**\n     * 当前请求 HTTP_CONTENT_TYPE\n     * @access public\n     * @return string\n     */\n    public function contentType()\n    {\n        $contentType = $this->server('CONTENT_TYPE');\n        if ($contentType) {\n            if (strpos($contentType, ';')) {\n                list($type) = explode(';', $contentType);\n            } else {\n                $type = $contentType;\n            }\n            return trim($type);\n        }\n        return '';\n    }\n\n    /**\n     * 获取当前请求的路由信息\n     * @access public\n     * @param array $route 路由名称\n     * @return array\n     */\n    public function routeInfo($route = [])\n    {\n        if (!empty($route)) {\n            $this->routeInfo = $route;\n        } else {\n            return $this->routeInfo;\n        }\n    }\n\n    /**\n     * 设置或者获取当前请求的调度信息\n     * @access public\n     * @param array  $dispatch 调度信息\n     * @return array\n     */\n    public function dispatch($dispatch = null)\n    {\n        if (!is_null($dispatch)) {\n            $this->dispatch = $dispatch;\n        }\n        return $this->dispatch;\n    }\n\n    /**\n     * 设置或者获取当前的模块名\n     * @access public\n     * @param string $module 模块名\n     * @return string|Request\n     */\n    public function module($module = null)\n    {\n        if (!is_null($module)) {\n            $this->module = $module;\n            return $this;\n        } else {\n            return $this->module ?: '';\n        }\n    }\n\n    /**\n     * 设置或者获取当前的控制器名\n     * @access public\n     * @param string $controller 控制器名\n     * @return string|Request\n     */\n    public function controller($controller = null)\n    {\n        if (!is_null($controller)) {\n            $this->controller = $controller;\n            return $this;\n        } else {\n            return $this->controller ?: '';\n        }\n    }\n\n    /**\n     * 设置或者获取当前的操作名\n     * @access public\n     * @param string $action 操作名\n     * @return string|Request\n     */\n    public function action($action = null)\n    {\n        if (!is_null($action)) {\n            $this->action = $action;\n            return $this;\n        } else {\n            return $this->action ?: '';\n        }\n    }\n\n    /**\n     * 设置或者获取当前的语言\n     * @access public\n     * @param string $lang 语言名\n     * @return string|Request\n     */\n    public function langset($lang = null)\n    {\n        if (!is_null($lang)) {\n            $this->langset = $lang;\n            return $this;\n        } else {\n            return $this->langset ?: '';\n        }\n    }\n\n    /**\n     * 设置或者获取当前请求的content\n     * @access public\n     * @return string\n     */\n    public function getContent()\n    {\n        if (is_null($this->content)) {\n            $this->content = $this->input;\n        }\n        return $this->content;\n    }\n\n    /**\n     * 获取当前请求的php://input\n     * @access public\n     * @return string\n     */\n    public function getInput()\n    {\n        return $this->input;\n    }\n\n    /**\n     * 生成请求令牌\n     * @access public\n     * @param string $name 令牌名称\n     * @param mixed  $type 令牌生成方法\n     * @return string\n     */\n    public function token($name = '__token__', $type = 'md5')\n    {\n        $type  = is_callable($type) ? $type : 'md5';\n        $token = call_user_func($type, $_SERVER['REQUEST_TIME_FLOAT']);\n        if ($this->isAjax()) {\n            header($name . ': ' . $token);\n        }\n        Session::set($name, $token);\n        return $token;\n    }\n\n    /**\n     * 设置当前地址的请求缓存\n     * @access public\n     * @param string $key 缓存标识，支持变量规则 ，例如 item/:name/:id\n     * @param mixed  $expire 缓存有效期\n     * @param array  $except 缓存排除\n     * @return void\n     */\n    public function cache($key, $expire = null, $except = [])\n    {\n        if (false !== $key && $this->isGet() && !$this->isCheckCache) {\n            // 标记请求缓存检查\n            $this->isCheckCache = true;\n            if (false === $expire) {\n                // 关闭当前缓存\n                return;\n            }\n            if ($key instanceof \\Closure) {\n                $key = call_user_func_array($key, [$this]);\n            } elseif (true === $key) {\n                foreach ($except as $rule) {\n                    if (0 === strpos($this->url(), $rule)) {\n                        return;\n                    }\n                }\n                // 自动缓存功能\n                $key = '__URL__';\n            } elseif (strpos($key, '|')) {\n                list($key, $fun) = explode('|', $key);\n            }\n            // 特殊规则替换\n            if (false !== strpos($key, '__')) {\n                $key = str_replace(['__MODULE__', '__CONTROLLER__', '__ACTION__', '__URL__', ''], [$this->module, $this->controller, $this->action, md5($this->url(true))], $key);\n            }\n\n            if (false !== strpos($key, ':')) {\n                $param = $this->param();\n                foreach ($param as $item => $val) {\n                    if (is_string($val) && false !== strpos($key, ':' . $item)) {\n                        $key = str_replace(':' . $item, $val, $key);\n                    }\n                }\n            } elseif (strpos($key, ']')) {\n                if ('[' . $this->ext() . ']' == $key) {\n                    // 缓存某个后缀的请求\n                    $key = md5($this->url());\n                } else {\n                    return;\n                }\n            }\n            if (isset($fun)) {\n                $key = $fun($key);\n            }\n\n            if (strtotime($this->server('HTTP_IF_MODIFIED_SINCE')) + $expire > $_SERVER['REQUEST_TIME']) {\n                // 读取缓存\n                $response = Response::create()->code(304);\n                throw new \\think\\exception\\HttpResponseException($response);\n            } elseif (Cache::has($key)) {\n                list($content, $header) = Cache::get($key);\n                $response               = Response::create($content)->header($header);\n                throw new \\think\\exception\\HttpResponseException($response);\n            } else {\n                $this->cache = [$key, $expire];\n            }\n        }\n    }\n\n    /**\n     * 读取请求缓存设置\n     * @access public\n     * @return array\n     */\n    public function getCache()\n    {\n        return $this->cache;\n    }\n\n    /**\n     * 设置当前请求绑定的对象实例\n     * @access public\n     * @param string $name 绑定的对象标识\n     * @param mixed  $obj 绑定的对象实例\n     * @return mixed\n     */\n    public function bind($name, $obj = null)\n    {\n        if (is_array($name)) {\n            $this->bind = array_merge($this->bind, $name);\n        } else {\n            $this->bind[$name] = $obj;\n        }\n    }\n\n    public function __set($name, $value)\n    {\n        $this->bind[$name] = $value;\n    }\n\n    public function __get($name)\n    {\n        return isset($this->bind[$name]) ? $this->bind[$name] : null;\n    }\n\n    public function __isset($name)\n    {\n        return isset($this->bind[$name]);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Response.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\response\\Json as JsonResponse;\nuse think\\response\\Jsonp as JsonpResponse;\nuse think\\response\\Redirect as RedirectResponse;\nuse think\\response\\View as ViewResponse;\nuse think\\response\\Xml as XmlResponse;\n\nclass Response\n{\n\n    // 原始数据\n    protected $data;\n\n    // 当前的contentType\n    protected $contentType = 'text/html';\n\n    // 字符集\n    protected $charset = 'utf-8';\n\n    //状态\n    protected $code = 200;\n\n    // 输出参数\n    protected $options = [];\n    // header参数\n    protected $header = [];\n\n    protected $content = null;\n\n    /**\n     * 构造函数\n     * @access   public\n     * @param mixed $data    输出数据\n     * @param int   $code\n     * @param array $header\n     * @param array $options 输出参数\n     */\n    public function __construct($data = '', $code = 200, array $header = [], $options = [])\n    {\n        $this->data($data);\n        $this->header = $header;\n        $this->code   = $code;\n        if (!empty($options)) {\n            $this->options = array_merge($this->options, $options);\n        }\n        $this->contentType($this->contentType, $this->charset);\n    }\n\n    /**\n     * 创建Response对象\n     * @access public\n     * @param mixed  $data    输出数据\n     * @param string $type    输出类型\n     * @param int    $code\n     * @param array  $header\n     * @param array  $options 输出参数\n     * @return Response|JsonResponse|ViewResponse|XmlResponse|RedirectResponse|JsonpResponse\n     */\n    public static function create($data = '', $type = '', $code = 200, array $header = [], $options = [])\n    {\n        $type = empty($type) ? 'null' : strtolower($type);\n\n        $class = false !== strpos($type, '\\\\') ? $type : '\\\\think\\\\response\\\\' . ucfirst($type);\n        if (class_exists($class)) {\n            $response = new $class($data, $code, $header, $options);\n        } else {\n            $response = new static($data, $code, $header, $options);\n        }\n\n        return $response;\n    }\n\n    /**\n     * 发送数据到客户端\n     * @access public\n     * @return mixed\n     * @throws \\InvalidArgumentException\n     */\n    public function send()\n    {\n        // 处理输出数据\n        $data = $this->getContent();\n\n        // Trace调试注入\n        if (Env::get('app_trace', Config::get('app_trace'))) {\n            Debug::inject($this, $data);\n        }\n\n        if (200 == $this->code) {\n            $cache = Request::instance()->getCache();\n            if ($cache) {\n                $this->header['Cache-Control'] = 'max-age=' . $cache[1] . ',must-revalidate';\n                $this->header['Last-Modified'] = gmdate('D, d M Y H:i:s') . ' GMT';\n                $this->header['Expires']       = gmdate('D, d M Y H:i:s', $_SERVER['REQUEST_TIME'] + $cache[1]) . ' GMT';\n                Cache::set($cache[0], [$data, $this->header], $cache[1]);\n            }\n        }\n\n        if (!headers_sent() && !empty($this->header)) {\n            // 发送状态码\n            http_response_code($this->code);\n            // 发送头部信息\n            foreach ($this->header as $name => $val) {\n                if (is_null($val)) {\n                    header($name);\n                } else {\n                    header($name . ':' . $val);\n                }\n            }\n        }\n\n        echo $data;\n\n        if (function_exists('fastcgi_finish_request')) {\n            // 提高页面响应\n            fastcgi_finish_request();\n        }\n\n        // 监听response_end\n        Hook::listen('response_end', $this);\n\n        // 清空当次请求有效的数据\n        if (!($this instanceof RedirectResponse)) {\n            Session::flush();\n        }\n    }\n\n    /**\n     * 处理数据\n     * @access protected\n     * @param mixed $data 要处理的数据\n     * @return mixed\n     */\n    protected function output($data)\n    {\n        return $data;\n    }\n\n    /**\n     * 输出的参数\n     * @access public\n     * @param mixed $options 输出参数\n     * @return $this\n     */\n    public function options($options = [])\n    {\n        $this->options = array_merge($this->options, $options);\n        return $this;\n    }\n\n    /**\n     * 输出数据设置\n     * @access public\n     * @param mixed $data 输出数据\n     * @return $this\n     */\n    public function data($data)\n    {\n        $this->data = $data;\n        return $this;\n    }\n\n    /**\n     * 设置响应头\n     * @access public\n     * @param string|array $name  参数名\n     * @param string       $value 参数值\n     * @return $this\n     */\n    public function header($name, $value = null)\n    {\n        if (is_array($name)) {\n            $this->header = array_merge($this->header, $name);\n        } else {\n            $this->header[$name] = $value;\n        }\n        return $this;\n    }\n\n    /**\n     * 设置页面输出内容\n     * @param $content\n     * @return $this\n     */\n    public function content($content)\n    {\n        if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([\n                $content,\n                '__toString',\n            ])\n        ) {\n            throw new \\InvalidArgumentException(sprintf('variable type error： %s', gettype($content)));\n        }\n\n        $this->content = (string) $content;\n\n        return $this;\n    }\n\n    /**\n     * 发送HTTP状态\n     * @param integer $code 状态码\n     * @return $this\n     */\n    public function code($code)\n    {\n        $this->code = $code;\n        return $this;\n    }\n\n    /**\n     * LastModified\n     * @param string $time\n     * @return $this\n     */\n    public function lastModified($time)\n    {\n        $this->header['Last-Modified'] = $time;\n        return $this;\n    }\n\n    /**\n     * Expires\n     * @param string $time\n     * @return $this\n     */\n    public function expires($time)\n    {\n        $this->header['Expires'] = $time;\n        return $this;\n    }\n\n    /**\n     * ETag\n     * @param string $eTag\n     * @return $this\n     */\n    public function eTag($eTag)\n    {\n        $this->header['ETag'] = $eTag;\n        return $this;\n    }\n\n    /**\n     * 页面缓存控制\n     * @param string $cache 状态码\n     * @return $this\n     */\n    public function cacheControl($cache)\n    {\n        $this->header['Cache-control'] = $cache;\n        return $this;\n    }\n\n    /**\n     * 页面输出类型\n     * @param string $contentType 输出类型\n     * @param string $charset     输出编码\n     * @return $this\n     */\n    public function contentType($contentType, $charset = 'utf-8')\n    {\n        $this->header['Content-Type'] = $contentType . '; charset=' . $charset;\n        return $this;\n    }\n\n    /**\n     * 获取头部信息\n     * @param string $name 头部名称\n     * @return mixed\n     */\n    public function getHeader($name = '')\n    {\n        if (!empty($name)) {\n            return isset($this->header[$name]) ? $this->header[$name] : null;\n        } else {\n            return $this->header;\n        }\n    }\n\n    /**\n     * 获取原始数据\n     * @return mixed\n     */\n    public function getData()\n    {\n        return $this->data;\n    }\n\n    /**\n     * 获取输出数据\n     * @return mixed\n     */\n    public function getContent()\n    {\n        if (null == $this->content) {\n            $content = $this->output($this->data);\n\n            if (null !== $content && !is_string($content) && !is_numeric($content) && !is_callable([\n                    $content,\n                    '__toString',\n                ])\n            ) {\n                throw new \\InvalidArgumentException(sprintf('variable type error： %s', gettype($content)));\n            }\n\n            $this->content = (string) $content;\n        }\n        return $this->content;\n    }\n\n    /**\n     * 获取状态码\n     * @return integer\n     */\n    public function getCode()\n    {\n        return $this->code;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Route.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\exception\\HttpException;\n\nclass Route\n{\n    // 路由规则\n    private static $rules = [\n        'get'     => [],\n        'post'    => [],\n        'put'     => [],\n        'delete'  => [],\n        'patch'   => [],\n        'head'    => [],\n        'options' => [],\n        '*'       => [],\n        'alias'   => [],\n        'domain'  => [],\n        'pattern' => [],\n        'name'    => [],\n    ];\n\n    // REST路由操作方法定义\n    private static $rest = [\n        'index'  => ['get', '', 'index'],\n        'create' => ['get', '/create', 'create'],\n        'edit'   => ['get', '/:id/edit', 'edit'],\n        'read'   => ['get', '/:id', 'read'],\n        'save'   => ['post', '', 'save'],\n        'update' => ['put', '/:id', 'update'],\n        'delete' => ['delete', '/:id', 'delete'],\n    ];\n\n    // 不同请求类型的方法前缀\n    private static $methodPrefix = [\n        'get'    => 'get',\n        'post'   => 'post',\n        'put'    => 'put',\n        'delete' => 'delete',\n        'patch'  => 'patch',\n    ];\n\n    // 子域名\n    private static $subDomain = '';\n    // 域名绑定\n    private static $bind = [];\n    // 当前分组信息\n    private static $group = [];\n    // 当前子域名绑定\n    private static $domainBind;\n    private static $domainRule;\n    // 当前域名\n    private static $domain;\n    // 当前路由执行过程中的参数\n    private static $option = [];\n\n    /**\n     * 注册变量规则\n     * @access public\n     * @param string|array  $name 变量名\n     * @param string        $rule 变量规则\n     * @return void\n     */\n    public static function pattern($name = null, $rule = '')\n    {\n        if (is_array($name)) {\n            self::$rules['pattern'] = array_merge(self::$rules['pattern'], $name);\n        } else {\n            self::$rules['pattern'][$name] = $rule;\n        }\n    }\n\n    /**\n     * 注册子域名部署规则\n     * @access public\n     * @param string|array  $domain 子域名\n     * @param mixed         $rule 路由规则\n     * @param array         $option 路由参数\n     * @param array         $pattern 变量规则\n     * @return void\n     */\n    public static function domain($domain, $rule = '', $option = [], $pattern = [])\n    {\n        if (is_array($domain)) {\n            foreach ($domain as $key => $item) {\n                self::domain($key, $item, $option, $pattern);\n            }\n        } elseif ($rule instanceof \\Closure) {\n            // 执行闭包\n            self::setDomain($domain);\n            call_user_func_array($rule, []);\n            self::setDomain(null);\n        } elseif (is_array($rule)) {\n            self::setDomain($domain);\n            self::group('', function () use ($rule) {\n                // 动态注册域名的路由规则\n                self::registerRules($rule);\n            }, $option, $pattern);\n            self::setDomain(null);\n        } else {\n            self::$rules['domain'][$domain]['[bind]'] = [$rule, $option, $pattern];\n        }\n    }\n\n    private static function setDomain($domain)\n    {\n        self::$domain = $domain;\n    }\n\n    /**\n     * 设置路由绑定\n     * @access public\n     * @param mixed     $bind 绑定信息\n     * @param string    $type 绑定类型 默认为module 支持 namespace class controller\n     * @return mixed\n     */\n    public static function bind($bind, $type = 'module')\n    {\n        self::$bind = ['type' => $type, $type => $bind];\n    }\n\n    /**\n     * 设置或者获取路由标识\n     * @access public\n     * @param string|array     $name 路由命名标识 数组表示批量设置\n     * @param array            $value 路由地址及变量信息\n     * @return array\n     */\n    public static function name($name = '', $value = null)\n    {\n        if (is_array($name)) {\n            return self::$rules['name'] = $name;\n        } elseif ('' === $name) {\n            return self::$rules['name'];\n        } elseif (!is_null($value)) {\n            self::$rules['name'][strtolower($name)][] = $value;\n        } else {\n            $name = strtolower($name);\n            return isset(self::$rules['name'][$name]) ? self::$rules['name'][$name] : null;\n        }\n    }\n\n    /**\n     * 读取路由绑定\n     * @access public\n     * @param string    $type 绑定类型\n     * @return mixed\n     */\n    public static function getBind($type)\n    {\n        return isset(self::$bind[$type]) ? self::$bind[$type] : null;\n    }\n\n    /**\n     * 导入配置文件的路由规则\n     * @access public\n     * @param array     $rule 路由规则\n     * @param string    $type 请求类型\n     * @return void\n     */\n    public static function import(array $rule, $type = '*')\n    {\n        // 检查域名部署\n        if (isset($rule['__domain__'])) {\n            self::domain($rule['__domain__']);\n            unset($rule['__domain__']);\n        }\n\n        // 检查变量规则\n        if (isset($rule['__pattern__'])) {\n            self::pattern($rule['__pattern__']);\n            unset($rule['__pattern__']);\n        }\n\n        // 检查路由别名\n        if (isset($rule['__alias__'])) {\n            self::alias($rule['__alias__']);\n            unset($rule['__alias__']);\n        }\n\n        // 检查资源路由\n        if (isset($rule['__rest__'])) {\n            self::resource($rule['__rest__']);\n            unset($rule['__rest__']);\n        }\n\n        self::registerRules($rule, strtolower($type));\n    }\n\n    // 批量注册路由\n    protected static function registerRules($rules, $type = '*')\n    {\n        foreach ($rules as $key => $val) {\n            if (is_numeric($key)) {\n                $key = array_shift($val);\n            }\n            if (empty($val)) {\n                continue;\n            }\n            if (is_string($key) && 0 === strpos($key, '[')) {\n                $key = substr($key, 1, -1);\n                self::group($key, $val);\n            } elseif (is_array($val)) {\n                self::setRule($key, $val[0], $type, $val[1], isset($val[2]) ? $val[2] : []);\n            } else {\n                self::setRule($key, $val, $type);\n            }\n        }\n    }\n\n    /**\n     * 注册路由规则\n     * @access public\n     * @param string    $rule 路由规则\n     * @param string    $route 路由地址\n     * @param string    $type 请求类型\n     * @param array     $option 路由参数\n     * @param array     $pattern 变量规则\n     * @return void\n     */\n    public static function rule($rule, $route = '', $type = '*', $option = [], $pattern = [])\n    {\n        $group = self::getGroup('name');\n\n        if (!is_null($group)) {\n            // 路由分组\n            $option  = array_merge(self::getGroup('option'), $option);\n            $pattern = array_merge(self::getGroup('pattern'), $pattern);\n        }\n\n        $type = strtolower($type);\n\n        if (strpos($type, '|')) {\n            $option['method'] = $type;\n            $type             = '*';\n        }\n        if (is_array($rule) && empty($route)) {\n            foreach ($rule as $key => $val) {\n                if (is_numeric($key)) {\n                    $key = array_shift($val);\n                }\n                if (is_array($val)) {\n                    $route    = $val[0];\n                    $option1  = array_merge($option, $val[1]);\n                    $pattern1 = array_merge($pattern, isset($val[2]) ? $val[2] : []);\n                } else {\n                    $route = $val;\n                }\n                self::setRule($key, $route, $type, isset($option1) ? $option1 : $option, isset($pattern1) ? $pattern1 : $pattern, $group);\n            }\n        } else {\n            self::setRule($rule, $route, $type, $option, $pattern, $group);\n        }\n\n    }\n\n    /**\n     * 设置路由规则\n     * @access public\n     * @param string    $rule 路由规则\n     * @param string    $route 路由地址\n     * @param string    $type 请求类型\n     * @param array     $option 路由参数\n     * @param array     $pattern 变量规则\n     * @param string    $group 所属分组\n     * @return void\n     */\n    protected static function setRule($rule, $route, $type = '*', $option = [], $pattern = [], $group = '')\n    {\n        if (is_array($rule)) {\n            $name = $rule[0];\n            $rule = $rule[1];\n        } elseif (is_string($route)) {\n            $name = $route;\n        }\n        if (!isset($option['complete_match'])) {\n            if (Config::get('route_complete_match')) {\n                $option['complete_match'] = true;\n            } elseif ('$' == substr($rule, -1, 1)) {\n                // 是否完整匹配\n                $option['complete_match'] = true;\n            }\n        } elseif (empty($option['complete_match']) && '$' == substr($rule, -1, 1)) {\n            // 是否完整匹配\n            $option['complete_match'] = true;\n        }\n\n        if ('$' == substr($rule, -1, 1)) {\n            $rule = substr($rule, 0, -1);\n        }\n\n        if ('/' != $rule || $group) {\n            $rule = trim($rule, '/');\n        }\n        $vars = self::parseVar($rule);\n        if (isset($name)) {\n            $key    = $group ? $group . ($rule ? '/' . $rule : '') : $rule;\n            $suffix = isset($option['ext']) ? $option['ext'] : null;\n            self::name($name, [$key, $vars, self::$domain, $suffix]);\n        }\n        if (isset($option['modular'])) {\n            $route = $option['modular'] . '/' . $route;\n        }\n        if ($group) {\n            if ('*' != $type) {\n                $option['method'] = $type;\n            }\n            if (self::$domain) {\n                self::$rules['domain'][self::$domain]['*'][$group]['rule'][] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern];\n            } else {\n                self::$rules['*'][$group]['rule'][] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern];\n            }\n        } else {\n            if ('*' != $type && isset(self::$rules['*'][$rule])) {\n                unset(self::$rules['*'][$rule]);\n            }\n            if (self::$domain) {\n                self::$rules['domain'][self::$domain][$type][$rule] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern];\n            } else {\n                self::$rules[$type][$rule] = ['rule' => $rule, 'route' => $route, 'var' => $vars, 'option' => $option, 'pattern' => $pattern];\n            }\n            if ('*' == $type) {\n                // 注册路由快捷方式\n                foreach (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as $method) {\n                    if (self::$domain) {\n                        self::$rules['domain'][self::$domain][$method][$rule] = true;\n                    } else {\n                        self::$rules[$method][$rule] = true;\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * 设置当前执行的参数信息\n     * @access public\n     * @param array    $options 参数信息\n     * @return mixed\n     */\n    protected static function setOption($options = [])\n    {\n        self::$option[] = $options;\n    }\n\n    /**\n     * 获取当前执行的所有参数信息\n     * @access public\n     * @return array\n     */\n    public static function getOption()\n    {\n        return self::$option;\n    }\n\n    /**\n     * 获取当前的分组信息\n     * @access public\n     * @param string    $type 分组信息名称 name option pattern\n     * @return mixed\n     */\n    public static function getGroup($type)\n    {\n        if (isset(self::$group[$type])) {\n            return self::$group[$type];\n        } else {\n            return 'name' == $type ? null : [];\n        }\n    }\n\n    /**\n     * 设置当前的路由分组\n     * @access public\n     * @param string    $name 分组名称\n     * @param array     $option 分组路由参数\n     * @param array     $pattern 分组变量规则\n     * @return void\n     */\n    public static function setGroup($name, $option = [], $pattern = [])\n    {\n        self::$group['name']    = $name;\n        self::$group['option']  = $option ?: [];\n        self::$group['pattern'] = $pattern ?: [];\n    }\n\n    /**\n     * 注册路由分组\n     * @access public\n     * @param string|array      $name 分组名称或者参数\n     * @param array|\\Closure    $routes 路由地址\n     * @param array             $option 路由参数\n     * @param array             $pattern 变量规则\n     * @return void\n     */\n    public static function group($name, $routes, $option = [], $pattern = [])\n    {\n        if (is_array($name)) {\n            $option = $name;\n            $name   = isset($option['name']) ? $option['name'] : '';\n        }\n        // 分组\n        $currentGroup = self::getGroup('name');\n        if ($currentGroup) {\n            $name = $currentGroup . ($name ? '/' . ltrim($name, '/') : '');\n        }\n        if (!empty($name)) {\n            if ($routes instanceof \\Closure) {\n                $currentOption  = self::getGroup('option');\n                $currentPattern = self::getGroup('pattern');\n                self::setGroup($name, array_merge($currentOption, $option), array_merge($currentPattern, $pattern));\n                call_user_func_array($routes, []);\n                self::setGroup($currentGroup, $currentOption, $currentPattern);\n                if ($currentGroup != $name) {\n                    self::$rules['*'][$name]['route']   = '';\n                    self::$rules['*'][$name]['var']     = self::parseVar($name);\n                    self::$rules['*'][$name]['option']  = $option;\n                    self::$rules['*'][$name]['pattern'] = $pattern;\n                }\n            } else {\n                $item = [];\n                foreach ($routes as $key => $val) {\n                    if (is_numeric($key)) {\n                        $key = array_shift($val);\n                    }\n                    if (is_array($val)) {\n                        $route    = $val[0];\n                        $option1  = array_merge($option, isset($val[1]) ? $val[1] : []);\n                        $pattern1 = array_merge($pattern, isset($val[2]) ? $val[2] : []);\n                    } else {\n                        $route = $val;\n                    }\n\n                    $options  = isset($option1) ? $option1 : $option;\n                    $patterns = isset($pattern1) ? $pattern1 : $pattern;\n                    if ('$' == substr($key, -1, 1)) {\n                        // 是否完整匹配\n                        $options['complete_match'] = true;\n                        $key                       = substr($key, 0, -1);\n                    }\n                    $key    = trim($key, '/');\n                    $vars   = self::parseVar($key);\n                    $item[] = ['rule' => $key, 'route' => $route, 'var' => $vars, 'option' => $options, 'pattern' => $patterns];\n                    // 设置路由标识\n                    $suffix = isset($options['ext']) ? $options['ext'] : null;\n                    self::name($route, [$name . ($key ? '/' . $key : ''), $vars, self::$domain, $suffix]);\n                }\n                self::$rules['*'][$name] = ['rule' => $item, 'route' => '', 'var' => [], 'option' => $option, 'pattern' => $pattern];\n            }\n\n            foreach (['get', 'post', 'put', 'delete', 'patch', 'head', 'options'] as $method) {\n                if (!isset(self::$rules[$method][$name])) {\n                    self::$rules[$method][$name] = true;\n                } elseif (is_array(self::$rules[$method][$name])) {\n                    self::$rules[$method][$name] = array_merge(self::$rules['*'][$name], self::$rules[$method][$name]);\n                }\n            }\n\n        } elseif ($routes instanceof \\Closure) {\n            // 闭包注册\n            $currentOption  = self::getGroup('option');\n            $currentPattern = self::getGroup('pattern');\n            self::setGroup('', array_merge($currentOption, $option), array_merge($currentPattern, $pattern));\n            call_user_func_array($routes, []);\n            self::setGroup($currentGroup, $currentOption, $currentPattern);\n        } else {\n            // 批量注册路由\n            self::rule($routes, '', '*', $option, $pattern);\n        }\n    }\n\n    /**\n     * 注册路由\n     * @access public\n     * @param string    $rule 路由规则\n     * @param string    $route 路由地址\n     * @param array     $option 路由参数\n     * @param array     $pattern 变量规则\n     * @return void\n     */\n    public static function any($rule, $route = '', $option = [], $pattern = [])\n    {\n        self::rule($rule, $route, '*', $option, $pattern);\n    }\n\n    /**\n     * 注册GET路由\n     * @access public\n     * @param string    $rule 路由规则\n     * @param string    $route 路由地址\n     * @param array     $option 路由参数\n     * @param array     $pattern 变量规则\n     * @return void\n     */\n    public static function get($rule, $route = '', $option = [], $pattern = [])\n    {\n        self::rule($rule, $route, 'GET', $option, $pattern);\n    }\n\n    /**\n     * 注册POST路由\n     * @access public\n     * @param string    $rule 路由规则\n     * @param string    $route 路由地址\n     * @param array     $option 路由参数\n     * @param array     $pattern 变量规则\n     * @return void\n     */\n    public static function post($rule, $route = '', $option = [], $pattern = [])\n    {\n        self::rule($rule, $route, 'POST', $option, $pattern);\n    }\n\n    /**\n     * 注册PUT路由\n     * @access public\n     * @param string    $rule 路由规则\n     * @param string    $route 路由地址\n     * @param array     $option 路由参数\n     * @param array     $pattern 变量规则\n     * @return void\n     */\n    public static function put($rule, $route = '', $option = [], $pattern = [])\n    {\n        self::rule($rule, $route, 'PUT', $option, $pattern);\n    }\n\n    /**\n     * 注册DELETE路由\n     * @access public\n     * @param string    $rule 路由规则\n     * @param string    $route 路由地址\n     * @param array     $option 路由参数\n     * @param array     $pattern 变量规则\n     * @return void\n     */\n    public static function delete($rule, $route = '', $option = [], $pattern = [])\n    {\n        self::rule($rule, $route, 'DELETE', $option, $pattern);\n    }\n\n    /**\n     * 注册PATCH路由\n     * @access public\n     * @param string    $rule 路由规则\n     * @param string    $route 路由地址\n     * @param array     $option 路由参数\n     * @param array     $pattern 变量规则\n     * @return void\n     */\n    public static function patch($rule, $route = '', $option = [], $pattern = [])\n    {\n        self::rule($rule, $route, 'PATCH', $option, $pattern);\n    }\n\n    /**\n     * 注册资源路由\n     * @access public\n     * @param string    $rule 路由规则\n     * @param string    $route 路由地址\n     * @param array     $option 路由参数\n     * @param array     $pattern 变量规则\n     * @return void\n     */\n    public static function resource($rule, $route = '', $option = [], $pattern = [])\n    {\n        if (is_array($rule)) {\n            foreach ($rule as $key => $val) {\n                if (is_array($val)) {\n                    list($val, $option, $pattern) = array_pad($val, 3, []);\n                }\n                self::resource($key, $val, $option, $pattern);\n            }\n        } else {\n            if (strpos($rule, '.')) {\n                // 注册嵌套资源路由\n                $array = explode('.', $rule);\n                $last  = array_pop($array);\n                $item  = [];\n                foreach ($array as $val) {\n                    $item[] = $val . '/:' . (isset($option['var'][$val]) ? $option['var'][$val] : $val . '_id');\n                }\n                $rule = implode('/', $item) . '/' . $last;\n            }\n            // 注册资源路由\n            foreach (self::$rest as $key => $val) {\n                if ((isset($option['only']) && !in_array($key, $option['only']))\n                    || (isset($option['except']) && in_array($key, $option['except']))) {\n                    continue;\n                }\n                if (isset($last) && strpos($val[1], ':id') && isset($option['var'][$last])) {\n                    $val[1] = str_replace(':id', ':' . $option['var'][$last], $val[1]);\n                } elseif (strpos($val[1], ':id') && isset($option['var'][$rule])) {\n                    $val[1] = str_replace(':id', ':' . $option['var'][$rule], $val[1]);\n                }\n                $item           = ltrim($rule . $val[1], '/');\n                $option['rest'] = $key;\n                self::rule($item . '$', $route . '/' . $val[2], $val[0], $option, $pattern);\n            }\n        }\n    }\n\n    /**\n     * 注册控制器路由 操作方法对应不同的请求后缀\n     * @access public\n     * @param string    $rule 路由规则\n     * @param string    $route 路由地址\n     * @param array     $option 路由参数\n     * @param array     $pattern 变量规则\n     * @return void\n     */\n    public static function controller($rule, $route = '', $option = [], $pattern = [])\n    {\n        foreach (self::$methodPrefix as $type => $val) {\n            self::$type($rule . '/:action', $route . '/' . $val . ':action', $option, $pattern);\n        }\n    }\n\n    /**\n     * 注册别名路由\n     * @access public\n     * @param string|array  $rule 路由别名\n     * @param string        $route 路由地址\n     * @param array         $option 路由参数\n     * @return void\n     */\n    public static function alias($rule = null, $route = '', $option = [])\n    {\n        if (is_array($rule)) {\n            self::$rules['alias'] = array_merge(self::$rules['alias'], $rule);\n        } else {\n            self::$rules['alias'][$rule] = $option ? [$route, $option] : $route;\n        }\n    }\n\n    /**\n     * 设置不同请求类型下面的方法前缀\n     * @access public\n     * @param string    $method 请求类型\n     * @param string    $prefix 类型前缀\n     * @return void\n     */\n    public static function setMethodPrefix($method, $prefix = '')\n    {\n        if (is_array($method)) {\n            self::$methodPrefix = array_merge(self::$methodPrefix, array_change_key_case($method));\n        } else {\n            self::$methodPrefix[strtolower($method)] = $prefix;\n        }\n    }\n\n    /**\n     * rest方法定义和修改\n     * @access public\n     * @param string        $name 方法名称\n     * @param array|bool    $resource 资源\n     * @return void\n     */\n    public static function rest($name, $resource = [])\n    {\n        if (is_array($name)) {\n            self::$rest = $resource ? $name : array_merge(self::$rest, $name);\n        } else {\n            self::$rest[$name] = $resource;\n        }\n    }\n\n    /**\n     * 注册未匹配路由规则后的处理\n     * @access public\n     * @param string    $route 路由地址\n     * @param string    $method 请求类型\n     * @param array     $option 路由参数\n     * @return void\n     */\n    public static function miss($route, $method = '*', $option = [])\n    {\n        self::rule('__miss__', $route, $method, $option, []);\n    }\n\n    /**\n     * 注册一个自动解析的URL路由\n     * @access public\n     * @param string    $route 路由地址\n     * @return void\n     */\n    public static function auto($route)\n    {\n        self::rule('__auto__', $route, '*', [], []);\n    }\n\n    /**\n     * 获取或者批量设置路由定义\n     * @access public\n     * @param mixed $rules 请求类型或者路由定义数组\n     * @return array\n     */\n    public static function rules($rules = '')\n    {\n        if (is_array($rules)) {\n            self::$rules = $rules;\n        } elseif ($rules) {\n            return true === $rules ? self::$rules : self::$rules[strtolower($rules)];\n        } else {\n            $rules = self::$rules;\n            unset($rules['pattern'], $rules['alias'], $rules['domain'], $rules['name']);\n            return $rules;\n        }\n    }\n\n    /**\n     * 检测子域名部署\n     * @access public\n     * @param Request   $request Request请求对象\n     * @param array     $currentRules 当前路由规则\n     * @param string    $method 请求类型\n     * @return void\n     */\n    public static function checkDomain($request, &$currentRules, $method = 'get')\n    {\n        // 域名规则\n        $rules = self::$rules['domain'];\n        // 开启子域名部署 支持二级和三级域名\n        if (!empty($rules)) {\n            $host = $request->host();\n            if (isset($rules[$host])) {\n                // 完整域名或者IP配置\n                $item = $rules[$host];\n            } else {\n                $rootDomain = Config::get('url_domain_root');\n                if ($rootDomain) {\n                    // 配置域名根 例如 thinkphp.cn 163.com.cn 如果是国家级域名 com.cn net.cn 之类的域名需要配置\n                    $domain = explode('.', rtrim(stristr($host, $rootDomain, true), '.'));\n                } else {\n                    $domain = explode('.', $host, -2);\n                }\n                // 子域名配置\n                if (!empty($domain)) {\n                    // 当前子域名\n                    $subDomain       = implode('.', $domain);\n                    self::$subDomain = $subDomain;\n                    $domain2         = array_pop($domain);\n                    if ($domain) {\n                        // 存在三级域名\n                        $domain3 = array_pop($domain);\n                    }\n                    if ($subDomain && isset($rules[$subDomain])) {\n                        // 子域名配置\n                        $item = $rules[$subDomain];\n                    } elseif (isset($rules['*.' . $domain2]) && !empty($domain3)) {\n                        // 泛三级域名\n                        $item      = $rules['*.' . $domain2];\n                        $panDomain = $domain3;\n                    } elseif (isset($rules['*']) && !empty($domain2)) {\n                        // 泛二级域名\n                        if ('www' != $domain2) {\n                            $item      = $rules['*'];\n                            $panDomain = $domain2;\n                        }\n                    }\n                }\n            }\n            if (!empty($item)) {\n                if (isset($panDomain)) {\n                    // 保存当前泛域名\n                    $request->route(['__domain__' => $panDomain]);\n                }\n                if (isset($item['[bind]'])) {\n                    // 解析子域名部署规则\n                    list($rule, $option, $pattern) = $item['[bind]'];\n                    if (!empty($option['https']) && !$request->isSsl()) {\n                        // https检测\n                        throw new HttpException(404, 'must use https request:' . $host);\n                    }\n\n                    if (strpos($rule, '?')) {\n                        // 传入其它参数\n                        $array  = parse_url($rule);\n                        $result = $array['path'];\n                        parse_str($array['query'], $params);\n                        if (isset($panDomain)) {\n                            $pos = array_search('*', $params);\n                            if (false !== $pos) {\n                                // 泛域名作为参数\n                                $params[$pos] = $panDomain;\n                            }\n                        }\n                        $_GET = array_merge($_GET, $params);\n                    } else {\n                        $result = $rule;\n                    }\n\n                    if (0 === strpos($result, '\\\\')) {\n                        // 绑定到命名空间 例如 \\app\\index\\behavior\n                        self::$bind = ['type' => 'namespace', 'namespace' => $result];\n                    } elseif (0 === strpos($result, '@')) {\n                        // 绑定到类 例如 @app\\index\\controller\\User\n                        self::$bind = ['type' => 'class', 'class' => substr($result, 1)];\n                    } else {\n                        // 绑定到模块/控制器 例如 index/user\n                        self::$bind = ['type' => 'module', 'module' => $result];\n                    }\n                    self::$domainBind = true;\n                } else {\n                    self::$domainRule = $item;\n                    $currentRules     = isset($item[$method]) ? $item[$method] : $item['*'];\n                }\n            }\n        }\n    }\n\n    /**\n     * 检测URL路由\n     * @access public\n     * @param Request   $request Request请求对象\n     * @param string    $url URL地址\n     * @param string    $depr URL分隔符\n     * @param bool      $checkDomain 是否检测域名规则\n     * @return false|array\n     */\n    public static function check($request, $url, $depr = '/', $checkDomain = false)\n    {\n        // 分隔符替换 确保路由定义使用统一的分隔符\n        $url = str_replace($depr, '|', $url);\n\n        if (isset(self::$rules['alias'][$url]) || isset(self::$rules['alias'][strstr($url, '|', true)])) {\n            // 检测路由别名\n            $result = self::checkRouteAlias($request, $url, $depr);\n            if (false !== $result) {\n                return $result;\n            }\n        }\n        $method = strtolower($request->method());\n        // 获取当前请求类型的路由规则\n        $rules = isset(self::$rules[$method]) ? self::$rules[$method] : [];\n        // 检测域名部署\n        if ($checkDomain) {\n            self::checkDomain($request, $rules, $method);\n        }\n        // 检测URL绑定\n        $return = self::checkUrlBind($url, $rules, $depr);\n        if (false !== $return) {\n            return $return;\n        }\n        if ('|' != $url) {\n            $url = rtrim($url, '|');\n        }\n        $item = str_replace('|', '/', $url);\n        if (isset($rules[$item])) {\n            // 静态路由规则检测\n            $rule = $rules[$item];\n            if (true === $rule) {\n                $rule = self::getRouteExpress($item);\n            }\n            if (!empty($rule['route']) && self::checkOption($rule['option'], $request)) {\n                self::setOption($rule['option']);\n                return self::parseRule($item, $rule['route'], $url, $rule['option']);\n            }\n        }\n\n        // 路由规则检测\n        if (!empty($rules)) {\n            return self::checkRoute($request, $rules, $url, $depr);\n        }\n        return false;\n    }\n\n    private static function getRouteExpress($key)\n    {\n        return self::$domainRule ? self::$domainRule['*'][$key] : self::$rules['*'][$key];\n    }\n\n    /**\n     * 检测路由规则\n     * @access private\n     * @param Request   $request\n     * @param array     $rules 路由规则\n     * @param string    $url URL地址\n     * @param string    $depr URL分割符\n     * @param string    $group 路由分组名\n     * @param array     $options 路由参数（分组）\n     * @return mixed\n     */\n    private static function checkRoute($request, $rules, $url, $depr = '/', $group = '', $options = [])\n    {\n        foreach ($rules as $key => $item) {\n            if (true === $item) {\n                $item = self::getRouteExpress($key);\n            }\n            if (!isset($item['rule'])) {\n                continue;\n            }\n            $rule    = $item['rule'];\n            $route   = $item['route'];\n            $vars    = $item['var'];\n            $option  = $item['option'];\n            $pattern = $item['pattern'];\n\n            // 检查参数有效性\n            if (!self::checkOption($option, $request)) {\n                continue;\n            }\n\n            if (isset($option['ext'])) {\n                // 路由ext参数 优先于系统配置的URL伪静态后缀参数\n                $url = preg_replace('/\\.' . $request->ext() . '$/i', '', $url);\n            }\n\n            if (is_array($rule)) {\n                // 分组路由\n                $pos = strpos(str_replace('<', ':', $key), ':');\n                if (false !== $pos) {\n                    $str = substr($key, 0, $pos);\n                } else {\n                    $str = $key;\n                }\n                if (is_string($str) && $str && 0 !== strpos(str_replace('|', '/', $url), $str)) {\n                    continue;\n                }\n                self::setOption($option);\n                $result = self::checkRoute($request, $rule, $url, $depr, $key, $option);\n                if (false !== $result) {\n                    return $result;\n                }\n            } elseif ($route) {\n                if ('__miss__' == $rule || '__auto__' == $rule) {\n                    // 指定特殊路由\n                    $var    = trim($rule, '__');\n                    ${$var} = $item;\n                    continue;\n                }\n                if ($group) {\n                    $rule = $group . ($rule ? '/' . ltrim($rule, '/') : '');\n                }\n\n                self::setOption($option);\n                if (isset($options['bind_model']) && isset($option['bind_model'])) {\n                    $option['bind_model'] = array_merge($options['bind_model'], $option['bind_model']);\n                }\n                $result = self::checkRule($rule, $route, $url, $pattern, $option, $depr);\n                if (false !== $result) {\n                    return $result;\n                }\n            }\n        }\n        if (isset($auto)) {\n            // 自动解析URL地址\n            return self::parseUrl($auto['route'] . '/' . $url, $depr);\n        } elseif (isset($miss)) {\n            // 未匹配所有路由的路由规则处理\n            return self::parseRule('', $miss['route'], $url, $miss['option']);\n        }\n        return false;\n    }\n\n    /**\n     * 检测路由别名\n     * @access private\n     * @param Request   $request\n     * @param string    $url URL地址\n     * @param string    $depr URL分隔符\n     * @return mixed\n     */\n    private static function checkRouteAlias($request, $url, $depr)\n    {\n        $array = explode('|', $url);\n        $alias = array_shift($array);\n        $item  = self::$rules['alias'][$alias];\n\n        if (is_array($item)) {\n            list($rule, $option) = $item;\n            $action              = $array[0];\n            if (isset($option['allow']) && !in_array($action, explode(',', $option['allow']))) {\n                // 允许操作\n                return false;\n            } elseif (isset($option['except']) && in_array($action, explode(',', $option['except']))) {\n                // 排除操作\n                return false;\n            }\n            if (isset($option['method'][$action])) {\n                $option['method'] = $option['method'][$action];\n            }\n        } else {\n            $rule = $item;\n        }\n        $bind = implode('|', $array);\n        // 参数有效性检查\n        if (isset($option) && !self::checkOption($option, $request)) {\n            // 路由不匹配\n            return false;\n        } elseif (0 === strpos($rule, '\\\\')) {\n            // 路由到类\n            return self::bindToClass($bind, substr($rule, 1), $depr);\n        } elseif (0 === strpos($rule, '@')) {\n            // 路由到控制器类\n            return self::bindToController($bind, substr($rule, 1), $depr);\n        } else {\n            // 路由到模块/控制器\n            return self::bindToModule($bind, $rule, $depr);\n        }\n    }\n\n    /**\n     * 检测URL绑定\n     * @access private\n     * @param string    $url URL地址\n     * @param array     $rules 路由规则\n     * @param string    $depr URL分隔符\n     * @return mixed\n     */\n    private static function checkUrlBind(&$url, &$rules, $depr = '/')\n    {\n        if (!empty(self::$bind)) {\n            $type = self::$bind['type'];\n            $bind = self::$bind[$type];\n            // 记录绑定信息\n            App::$debug && Log::record('[ BIND ] ' . var_export($bind, true), 'info');\n            // 如果有URL绑定 则进行绑定检测\n            switch ($type) {\n                case 'class':\n                    // 绑定到类\n                    return self::bindToClass($url, $bind, $depr);\n                case 'controller':\n                    // 绑定到控制器类\n                    return self::bindToController($url, $bind, $depr);\n                case 'namespace':\n                    // 绑定到命名空间\n                    return self::bindToNamespace($url, $bind, $depr);\n            }\n        }\n        return false;\n    }\n\n    /**\n     * 绑定到类\n     * @access public\n     * @param string    $url URL地址\n     * @param string    $class 类名（带命名空间）\n     * @param string    $depr URL分隔符\n     * @return array\n     */\n    public static function bindToClass($url, $class, $depr = '/')\n    {\n        $url    = str_replace($depr, '|', $url);\n        $array  = explode('|', $url, 2);\n        $action = !empty($array[0]) ? $array[0] : Config::get('default_action');\n        if (!empty($array[1])) {\n            self::parseUrlParams($array[1]);\n        }\n        return ['type' => 'method', 'method' => [$class, $action], 'var' => []];\n    }\n\n    /**\n     * 绑定到命名空间\n     * @access public\n     * @param string    $url URL地址\n     * @param string    $namespace 命名空间\n     * @param string    $depr URL分隔符\n     * @return array\n     */\n    public static function bindToNamespace($url, $namespace, $depr = '/')\n    {\n        $url    = str_replace($depr, '|', $url);\n        $array  = explode('|', $url, 3);\n        $class  = !empty($array[0]) ? $array[0] : Config::get('default_controller');\n        $method = !empty($array[1]) ? $array[1] : Config::get('default_action');\n        if (!empty($array[2])) {\n            self::parseUrlParams($array[2]);\n        }\n        return ['type' => 'method', 'method' => [$namespace . '\\\\' . Loader::parseName($class, 1), $method], 'var' => []];\n    }\n\n    /**\n     * 绑定到控制器类\n     * @access public\n     * @param string    $url URL地址\n     * @param string    $controller 控制器名 （支持带模块名 index/user ）\n     * @param string    $depr URL分隔符\n     * @return array\n     */\n    public static function bindToController($url, $controller, $depr = '/')\n    {\n        $url    = str_replace($depr, '|', $url);\n        $array  = explode('|', $url, 2);\n        $action = !empty($array[0]) ? $array[0] : Config::get('default_action');\n        if (!empty($array[1])) {\n            self::parseUrlParams($array[1]);\n        }\n        return ['type' => 'controller', 'controller' => $controller . '/' . $action, 'var' => []];\n    }\n\n    /**\n     * 绑定到模块/控制器\n     * @access public\n     * @param string    $url URL地址\n     * @param string    $controller 控制器类名（带命名空间）\n     * @param string    $depr URL分隔符\n     * @return array\n     */\n    public static function bindToModule($url, $controller, $depr = '/')\n    {\n        $url    = str_replace($depr, '|', $url);\n        $array  = explode('|', $url, 2);\n        $action = !empty($array[0]) ? $array[0] : Config::get('default_action');\n        if (!empty($array[1])) {\n            self::parseUrlParams($array[1]);\n        }\n        return ['type' => 'module', 'module' => $controller . '/' . $action];\n    }\n\n    /**\n     * 路由参数有效性检查\n     * @access private\n     * @param array     $option 路由参数\n     * @param Request   $request Request对象\n     * @return bool\n     */\n    private static function checkOption($option, $request)\n    {\n        if ((isset($option['method']) && is_string($option['method']) && false === stripos($option['method'], $request->method()))\n            || (isset($option['ajax']) && $option['ajax'] && !$request->isAjax()) // Ajax检测\n             || (isset($option['ajax']) && !$option['ajax'] && $request->isAjax()) // 非Ajax检测\n             || (isset($option['pjax']) && $option['pjax'] && !$request->isPjax()) // Pjax检测\n             || (isset($option['pjax']) && !$option['pjax'] && $request->isPjax()) // 非Pjax检测\n             || (isset($option['ext']) && false === stripos('|' . $option['ext'] . '|', '|' . $request->ext() . '|')) // 伪静态后缀检测\n             || (isset($option['deny_ext']) && false !== stripos('|' . $option['deny_ext'] . '|', '|' . $request->ext() . '|'))\n            || (isset($option['domain']) && !in_array($option['domain'], [$_SERVER['HTTP_HOST'], self::$subDomain])) // 域名检测\n             || (isset($option['https']) && $option['https'] && !$request->isSsl()) // https检测\n             || (isset($option['https']) && !$option['https'] && $request->isSsl()) // https检测\n             || (!empty($option['before_behavior']) && false === Hook::exec($option['before_behavior'])) // 行为检测\n             || (!empty($option['callback']) && is_callable($option['callback']) && false === call_user_func($option['callback'])) // 自定义检测\n        ) {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * 检测路由规则\n     * @access private\n     * @param string    $rule 路由规则\n     * @param string    $route 路由地址\n     * @param string    $url URL地址\n     * @param array     $pattern 变量规则\n     * @param array     $option 路由参数\n     * @param string    $depr URL分隔符（全局）\n     * @return array|false\n     */\n    private static function checkRule($rule, $route, $url, $pattern, $option, $depr)\n    {\n        // 检查完整规则定义\n        if (isset($pattern['__url__']) && !preg_match('/^' . $pattern['__url__'] . '/', str_replace('|', $depr, $url))) {\n            return false;\n        }\n        // 检查路由的参数分隔符\n        if (isset($option['param_depr'])) {\n            $url = str_replace(['|', $option['param_depr']], [$depr, '|'], $url);\n        }\n\n        $len1 = substr_count($url, '|');\n        $len2 = substr_count($rule, '/');\n        // 多余参数是否合并\n        $merge = !empty($option['merge_extra_vars']);\n        if ($merge && $len1 > $len2) {\n            $url = str_replace('|', $depr, $url);\n            $url = implode('|', explode($depr, $url, $len2 + 1));\n        }\n\n        if ($len1 >= $len2 || strpos($rule, '[')) {\n            if (!empty($option['complete_match'])) {\n                // 完整匹配\n                if (!$merge && $len1 != $len2 && (false === strpos($rule, '[') || $len1 > $len2 || $len1 < $len2 - substr_count($rule, '['))) {\n                    return false;\n                }\n            }\n            $pattern = array_merge(self::$rules['pattern'], $pattern);\n            if (false !== $match = self::match($url, $rule, $pattern)) {\n                // 匹配到路由规则\n                return self::parseRule($rule, $route, $url, $option, $match);\n            }\n        }\n        return false;\n    }\n\n    /**\n     * 解析模块的URL地址 [模块/控制器/操作?]参数1=值1&参数2=值2...\n     * @access public\n     * @param string    $url URL地址\n     * @param string    $depr URL分隔符\n     * @param bool      $autoSearch 是否自动深度搜索控制器\n     * @return array\n     */\n    public static function parseUrl($url, $depr = '/', $autoSearch = false)\n    {\n\n        if (isset(self::$bind['module'])) {\n            $bind = str_replace('/', $depr, self::$bind['module']);\n            // 如果有模块/控制器绑定\n            $url = $bind . ('.' != substr($bind, -1) ? $depr : '') . ltrim($url, $depr);\n        }\n        $url              = str_replace($depr, '|', $url);\n        list($path, $var) = self::parseUrlPath($url);\n        $route            = [null, null, null];\n        if (isset($path)) {\n            // 解析模块\n            $module = Config::get('app_multi_module') ? array_shift($path) : null;\n            if ($autoSearch) {\n                // 自动搜索控制器\n                $dir    = APP_PATH . ($module ? $module . DS : '') . Config::get('url_controller_layer');\n                $suffix = App::$suffix || Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : '';\n                $item   = [];\n                $find   = false;\n                foreach ($path as $val) {\n                    $item[] = $val;\n                    $file   = $dir . DS . str_replace('.', DS, $val) . $suffix . EXT;\n                    $file   = pathinfo($file, PATHINFO_DIRNAME) . DS . Loader::parseName(pathinfo($file, PATHINFO_FILENAME), 1) . EXT;\n                    if (is_file($file)) {\n                        $find = true;\n                        break;\n                    } else {\n                        $dir .= DS . Loader::parseName($val);\n                    }\n                }\n                if ($find) {\n                    $controller = implode('.', $item);\n                    $path       = array_slice($path, count($item));\n                } else {\n                    $controller = array_shift($path);\n                }\n            } else {\n                // 解析控制器\n                $controller = !empty($path) ? array_shift($path) : null;\n            }\n            // 解析操作\n            $action = !empty($path) ? array_shift($path) : null;\n            // 解析额外参数\n            self::parseUrlParams(empty($path) ? '' : implode('|', $path));\n            // 封装路由\n            $route = [$module, $controller, $action];\n            // 检查地址是否被定义过路由\n            $name  = strtolower($module . '/' . Loader::parseName($controller, 1) . '/' . $action);\n            $name2 = '';\n            if (empty($module) || isset($bind) && $module == $bind) {\n                $name2 = strtolower(Loader::parseName($controller, 1) . '/' . $action);\n            }\n\n            if (isset(self::$rules['name'][$name]) || isset(self::$rules['name'][$name2])) {\n                throw new HttpException(404, 'invalid request:' . str_replace('|', $depr, $url));\n            }\n        }\n        return ['type' => 'module', 'module' => $route];\n    }\n\n    /**\n     * 解析URL的pathinfo参数和变量\n     * @access private\n     * @param string    $url URL地址\n     * @return array\n     */\n    private static function parseUrlPath($url)\n    {\n        // 分隔符替换 确保路由定义使用统一的分隔符\n        $url = str_replace('|', '/', $url);\n        $url = trim($url, '/');\n        $var = [];\n        if (false !== strpos($url, '?')) {\n            // [模块/控制器/操作?]参数1=值1&参数2=值2...\n            $info = parse_url($url);\n            $path = explode('/', $info['path']);\n            parse_str($info['query'], $var);\n        } elseif (strpos($url, '/')) {\n            // [模块/控制器/操作]\n            $path = explode('/', $url);\n        } else {\n            $path = [$url];\n        }\n        return [$path, $var];\n    }\n\n    /**\n     * 检测URL和规则路由是否匹配\n     * @access private\n     * @param string    $url URL地址\n     * @param string    $rule 路由规则\n     * @param array     $pattern 变量规则\n     * @return array|false\n     */\n    private static function match($url, $rule, $pattern)\n    {\n        $m2 = explode('/', $rule);\n        $m1 = explode('|', $url);\n\n        $var = [];\n        foreach ($m2 as $key => $val) {\n            // val中定义了多个变量 <id><name>\n            if (false !== strpos($val, '<') && preg_match_all('/<(\\w+(\\??))>/', $val, $matches)) {\n                $value   = [];\n                $replace = [];\n                foreach ($matches[1] as $name) {\n                    if (strpos($name, '?')) {\n                        $name      = substr($name, 0, -1);\n                        $replace[] = '(' . (isset($pattern[$name]) ? $pattern[$name] : '\\w+') . ')?';\n                    } else {\n                        $replace[] = '(' . (isset($pattern[$name]) ? $pattern[$name] : '\\w+') . ')';\n                    }\n                    $value[] = $name;\n                }\n                $val = str_replace($matches[0], $replace, $val);\n                if (preg_match('/^' . $val . '$/', isset($m1[$key]) ? $m1[$key] : '', $match)) {\n                    array_shift($match);\n                    foreach ($value as $k => $name) {\n                        if (isset($match[$k])) {\n                            $var[$name] = $match[$k];\n                        }\n                    }\n                    continue;\n                } else {\n                    return false;\n                }\n            }\n\n            if (0 === strpos($val, '[:')) {\n                // 可选参数\n                $val      = substr($val, 1, -1);\n                $optional = true;\n            } else {\n                $optional = false;\n            }\n            if (0 === strpos($val, ':')) {\n                // URL变量\n                $name = substr($val, 1);\n                if (!$optional && !isset($m1[$key])) {\n                    return false;\n                }\n                if (isset($m1[$key]) && isset($pattern[$name])) {\n                    // 检查变量规则\n                    if ($pattern[$name] instanceof \\Closure) {\n                        $result = call_user_func_array($pattern[$name], [$m1[$key]]);\n                        if (false === $result) {\n                            return false;\n                        }\n                    } elseif (!preg_match('/^' . $pattern[$name] . '$/', $m1[$key])) {\n                        return false;\n                    }\n                }\n                $var[$name] = isset($m1[$key]) ? $m1[$key] : '';\n            } elseif (!isset($m1[$key]) || 0 !== strcasecmp($val, $m1[$key])) {\n                return false;\n            }\n        }\n        // 成功匹配后返回URL中的动态变量数组\n        return $var;\n    }\n\n    /**\n     * 解析规则路由\n     * @access private\n     * @param string    $rule 路由规则\n     * @param string    $route 路由地址\n     * @param string    $pathinfo URL地址\n     * @param array     $option 路由参数\n     * @param array     $matches 匹配的变量\n     * @return array\n     */\n    private static function parseRule($rule, $route, $pathinfo, $option = [], $matches = [])\n    {\n        $request = Request::instance();\n        // 解析路由规则\n        if ($rule) {\n            $rule = explode('/', $rule);\n            // 获取URL地址中的参数\n            $paths = explode('|', $pathinfo);\n            foreach ($rule as $item) {\n                $fun = '';\n                if (0 === strpos($item, '[:')) {\n                    $item = substr($item, 1, -1);\n                }\n                if (0 === strpos($item, ':')) {\n                    $var           = substr($item, 1);\n                    $matches[$var] = array_shift($paths);\n                } else {\n                    // 过滤URL中的静态变量\n                    array_shift($paths);\n                }\n            }\n        } else {\n            $paths = explode('|', $pathinfo);\n        }\n\n        // 获取路由地址规则\n        if (is_string($route) && isset($option['prefix'])) {\n            // 路由地址前缀\n            $route = $option['prefix'] . $route;\n        }\n        // 替换路由地址中的变量\n        if (is_string($route) && !empty($matches)) {\n            foreach ($matches as $key => $val) {\n                if (false !== strpos($route, ':' . $key)) {\n                    $route = str_replace(':' . $key, $val, $route);\n                }\n            }\n        }\n\n        // 绑定模型数据\n        if (isset($option['bind_model'])) {\n            $bind = [];\n            foreach ($option['bind_model'] as $key => $val) {\n                if ($val instanceof \\Closure) {\n                    $result = call_user_func_array($val, [$matches]);\n                } else {\n                    if (is_array($val)) {\n                        $fields    = explode('&', $val[1]);\n                        $model     = $val[0];\n                        $exception = isset($val[2]) ? $val[2] : true;\n                    } else {\n                        $fields    = ['id'];\n                        $model     = $val;\n                        $exception = true;\n                    }\n                    $where = [];\n                    $match = true;\n                    foreach ($fields as $field) {\n                        if (!isset($matches[$field])) {\n                            $match = false;\n                            break;\n                        } else {\n                            $where[$field] = $matches[$field];\n                        }\n                    }\n                    if ($match) {\n                        $query  = strpos($model, '\\\\') ? $model::where($where) : Loader::model($model)->where($where);\n                        $result = $query->failException($exception)->find();\n                    }\n                }\n                if (!empty($result)) {\n                    $bind[$key] = $result;\n                }\n            }\n            $request->bind($bind);\n        }\n\n        // 解析额外参数\n        self::parseUrlParams(empty($paths) ? '' : implode('|', $paths), $matches);\n        // 记录匹配的路由信息\n        $request->routeInfo(['rule' => $rule, 'route' => $route, 'option' => $option, 'var' => $matches]);\n\n        // 检测路由after行为\n        if (!empty($option['after_behavior'])) {\n            if ($option['after_behavior'] instanceof \\Closure) {\n                $result = call_user_func_array($option['after_behavior'], []);\n            } else {\n                foreach ((array) $option['after_behavior'] as $behavior) {\n                    $result = Hook::exec($behavior, '');\n                    if (!is_null($result)) {\n                        break;\n                    }\n                }\n            }\n            // 路由规则重定向\n            if ($result instanceof Response) {\n                return ['type' => 'response', 'response' => $result];\n            } elseif (is_array($result)) {\n                return $result;\n            }\n        }\n\n        if ($route instanceof \\Closure) {\n            // 执行闭包\n            $result = ['type' => 'function', 'function' => $route];\n        } elseif (0 === strpos($route, '/') || strpos($route, '://')) {\n            // 路由到重定向地址\n            $result = ['type' => 'redirect', 'url' => $route, 'status' => isset($option['status']) ? $option['status'] : 301];\n        } elseif (false !== strpos($route, '\\\\')) {\n            // 路由到方法\n            list($path, $var) = self::parseUrlPath($route);\n            $route            = str_replace('/', '@', implode('/', $path));\n            $method           = strpos($route, '@') ? explode('@', $route) : $route;\n            $result           = ['type' => 'method', 'method' => $method, 'var' => $var];\n        } elseif (0 === strpos($route, '@')) {\n            // 路由到控制器\n            $route             = substr($route, 1);\n            list($route, $var) = self::parseUrlPath($route);\n            $result            = ['type' => 'controller', 'controller' => implode('/', $route), 'var' => $var];\n            $request->action(array_pop($route));\n            $request->controller($route ? array_pop($route) : Config::get('default_controller'));\n            $request->module($route ? array_pop($route) : Config::get('default_module'));\n            App::$modulePath = APP_PATH . (Config::get('app_multi_module') ? $request->module() . DS : '');\n        } else {\n            // 路由到模块/控制器/操作\n            $result = self::parseModule($route);\n        }\n        // 开启请求缓存\n        if ($request->isGet() && isset($option['cache'])) {\n            $cache = $option['cache'];\n            if (is_array($cache)) {\n                list($key, $expire) = $cache;\n            } else {\n                $key    = str_replace('|', '/', $pathinfo);\n                $expire = $cache;\n            }\n            $request->cache($key, $expire);\n        }\n        return $result;\n    }\n\n    /**\n     * 解析URL地址为 模块/控制器/操作\n     * @access private\n     * @param string    $url URL地址\n     * @return array\n     */\n    private static function parseModule($url)\n    {\n        list($path, $var) = self::parseUrlPath($url);\n        $action           = array_pop($path);\n        $controller       = !empty($path) ? array_pop($path) : null;\n        $module           = Config::get('app_multi_module') && !empty($path) ? array_pop($path) : null;\n        $method           = Request::instance()->method();\n        if (Config::get('use_action_prefix') && !empty(self::$methodPrefix[$method])) {\n            // 操作方法前缀支持\n            $action = 0 !== strpos($action, self::$methodPrefix[$method]) ? self::$methodPrefix[$method] . $action : $action;\n        }\n        // 设置当前请求的路由变量\n        Request::instance()->route($var);\n        // 路由到模块/控制器/操作\n        return ['type' => 'module', 'module' => [$module, $controller, $action], 'convert' => false];\n    }\n\n    /**\n     * 解析URL地址中的参数Request对象\n     * @access private\n     * @param string    $rule 路由规则\n     * @param array     $var 变量\n     * @return void\n     */\n    private static function parseUrlParams($url, &$var = [])\n    {\n        if ($url) {\n            if (Config::get('url_param_type')) {\n                $var += explode('|', $url);\n            } else {\n                preg_replace_callback('/(\\w+)\\|([^\\|]+)/', function ($match) use (&$var) {\n                    $var[$match[1]] = strip_tags($match[2]);\n                }, $url);\n            }\n        }\n        // 设置当前请求的参数\n        Request::instance()->route($var);\n    }\n\n    // 分析路由规则中的变量\n    private static function parseVar($rule)\n    {\n        // 提取路由规则中的变量\n        $var = [];\n        foreach (explode('/', $rule) as $val) {\n            $optional = false;\n            if (false !== strpos($val, '<') && preg_match_all('/<(\\w+(\\??))>/', $val, $matches)) {\n                foreach ($matches[1] as $name) {\n                    if (strpos($name, '?')) {\n                        $name     = substr($name, 0, -1);\n                        $optional = true;\n                    } else {\n                        $optional = false;\n                    }\n                    $var[$name] = $optional ? 2 : 1;\n                }\n            }\n\n            if (0 === strpos($val, '[:')) {\n                // 可选参数\n                $optional = true;\n                $val      = substr($val, 1, -1);\n            }\n            if (0 === strpos($val, ':')) {\n                // URL变量\n                $name       = substr($val, 1);\n                $var[$name] = $optional ? 2 : 1;\n            }\n        }\n        return $var;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Session.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\exception\\ClassNotFoundException;\n\nclass Session\n{\n    protected static $prefix = '';\n    protected static $init   = null;\n\n    /**\n     * 设置或者获取session作用域（前缀）\n     * @param string $prefix\n     * @return string|void\n     */\n    public static function prefix($prefix = '')\n    {\n        if (empty($prefix) && null !== $prefix) {\n            return self::$prefix;\n        } else {\n            self::$prefix = $prefix;\n        }\n    }\n\n    /**\n     * session初始化\n     * @param array $config\n     * @return void\n     * @throws \\think\\Exception\n     */\n    public static function init(array $config = [])\n    {\n        if (empty($config)) {\n            $config = Config::get('session');\n        }\n        // 记录初始化信息\n        App::$debug && Log::record('[ SESSION ] INIT ' . var_export($config, true), 'info');\n        $isDoStart = false;\n        if (isset($config['use_trans_sid'])) {\n            ini_set('session.use_trans_sid', $config['use_trans_sid'] ? 1 : 0);\n        }\n\n        // 启动session\n        if (!empty($config['auto_start']) && PHP_SESSION_ACTIVE != session_status()) {\n            ini_set('session.auto_start', 0);\n            $isDoStart = true;\n        }\n\n        if (isset($config['prefix']) && (self::$prefix === '' || self::$prefix === null)) {\n            self::$prefix = $config['prefix'];\n        }\n        if (isset($config['var_session_id']) && isset($_REQUEST[$config['var_session_id']])) {\n            session_id($_REQUEST[$config['var_session_id']]);\n        } elseif (isset($config['id']) && !empty($config['id'])) {\n            session_id($config['id']);\n        }\n        if (isset($config['name'])) {\n            session_name($config['name']);\n        }\n        if (isset($config['path'])) {\n            session_save_path($config['path']);\n        }\n        if (isset($config['domain'])) {\n            ini_set('session.cookie_domain', $config['domain']);\n        }\n        if (isset($config['expire'])) {\n            ini_set('session.gc_maxlifetime', $config['expire']);\n            ini_set('session.cookie_lifetime', $config['expire']);\n        }\n        if (isset($config['secure'])) {\n            ini_set('session.cookie_secure', $config['secure']);\n        }\n        if (isset($config['httponly'])) {\n            ini_set('session.cookie_httponly', $config['httponly']);\n        }\n        if (isset($config['use_cookies'])) {\n            ini_set('session.use_cookies', $config['use_cookies'] ? 1 : 0);\n        }\n        if (isset($config['cache_limiter'])) {\n            session_cache_limiter($config['cache_limiter']);\n        }\n        if (isset($config['cache_expire'])) {\n            session_cache_expire($config['cache_expire']);\n        }\n        if (!empty($config['type'])) {\n            // 读取session驱动\n            $class = false !== strpos($config['type'], '\\\\') ? $config['type'] : '\\\\think\\\\session\\\\driver\\\\' . ucwords($config['type']);\n\n            // 检查驱动类\n            if (!class_exists($class) || !session_set_save_handler(new $class($config))) {\n                throw new ClassNotFoundException('error session handler:' . $class, $class);\n            }\n        }\n        if ($isDoStart) {\n            session_start();\n            self::$init = true;\n        } else {\n            self::$init = false;\n        }\n    }\n\n    /**\n     * session自动启动或者初始化\n     * @return void\n     */\n    public static function boot()\n    {\n        if (is_null(self::$init)) {\n            self::init();\n        } elseif (false === self::$init) {\n            if (PHP_SESSION_ACTIVE != session_status()) {\n                session_start();\n            }\n            self::$init = true;\n        }\n    }\n\n    /**\n     * session设置\n     * @param string        $name session名称\n     * @param mixed         $value session值\n     * @param string|null   $prefix 作用域（前缀）\n     * @return void\n     */\n    public static function set($name, $value = '', $prefix = null)\n    {\n        empty(self::$init) && self::boot();\n\n        $prefix = !is_null($prefix) ? $prefix : self::$prefix;\n        if (strpos($name, '.')) {\n            // 二维数组赋值\n            list($name1, $name2) = explode('.', $name);\n            if ($prefix) {\n                $_SESSION[$prefix][$name1][$name2] = $value;\n            } else {\n                $_SESSION[$name1][$name2] = $value;\n            }\n        } elseif ($prefix) {\n            $_SESSION[$prefix][$name] = $value;\n        } else {\n            $_SESSION[$name] = $value;\n        }\n    }\n\n    /**\n     * session获取\n     * @param string        $name session名称\n     * @param string|null   $prefix 作用域（前缀）\n     * @return mixed\n     */\n    public static function get($name = '', $prefix = null)\n    {\n        empty(self::$init) && self::boot();\n        $prefix = !is_null($prefix) ? $prefix : self::$prefix;\n        if ('' == $name) {\n            // 获取全部的session\n            $value = $prefix ? (!empty($_SESSION[$prefix]) ? $_SESSION[$prefix] : []) : $_SESSION;\n        } elseif ($prefix) {\n            // 获取session\n            if (strpos($name, '.')) {\n                list($name1, $name2) = explode('.', $name);\n                $value               = isset($_SESSION[$prefix][$name1][$name2]) ? $_SESSION[$prefix][$name1][$name2] : null;\n            } else {\n                $value = isset($_SESSION[$prefix][$name]) ? $_SESSION[$prefix][$name] : null;\n            }\n        } else {\n            if (strpos($name, '.')) {\n                list($name1, $name2) = explode('.', $name);\n                $value               = isset($_SESSION[$name1][$name2]) ? $_SESSION[$name1][$name2] : null;\n            } else {\n                $value = isset($_SESSION[$name]) ? $_SESSION[$name] : null;\n            }\n        }\n        return $value;\n    }\n\n    /**\n     * session获取并删除\n     * @param string        $name session名称\n     * @param string|null   $prefix 作用域（前缀）\n     * @return mixed\n     */\n    public static function pull($name, $prefix = null)\n    {\n        $result = self::get($name, $prefix);\n        if ($result) {\n            self::delete($name, $prefix);\n            return $result;\n        } else {\n            return;\n        }\n    }\n\n    /**\n     * session设置 下一次请求有效\n     * @param string        $name session名称\n     * @param mixed         $value session值\n     * @param string|null   $prefix 作用域（前缀）\n     * @return void\n     */\n    public static function flash($name, $value)\n    {\n        self::set($name, $value);\n        if (!self::has('__flash__.__time__')) {\n            self::set('__flash__.__time__', $_SERVER['REQUEST_TIME_FLOAT']);\n        }\n        self::push('__flash__', $name);\n    }\n\n    /**\n     * 清空当前请求的session数据\n     * @return void\n     */\n    public static function flush()\n    {\n        if (self::$init) {\n            $item = self::get('__flash__');\n\n            if (!empty($item)) {\n                $time = $item['__time__'];\n                if ($_SERVER['REQUEST_TIME_FLOAT'] > $time) {\n                    unset($item['__time__']);\n                    self::delete($item);\n                    self::set('__flash__', []);\n                }\n            }\n        }\n    }\n\n    /**\n     * 删除session数据\n     * @param string|array  $name session名称\n     * @param string|null   $prefix 作用域（前缀）\n     * @return void\n     */\n    public static function delete($name, $prefix = null)\n    {\n        empty(self::$init) && self::boot();\n        $prefix = !is_null($prefix) ? $prefix : self::$prefix;\n        if (is_array($name)) {\n            foreach ($name as $key) {\n                self::delete($key, $prefix);\n            }\n        } elseif (strpos($name, '.')) {\n            list($name1, $name2) = explode('.', $name);\n            if ($prefix) {\n                unset($_SESSION[$prefix][$name1][$name2]);\n            } else {\n                unset($_SESSION[$name1][$name2]);\n            }\n        } else {\n            if ($prefix) {\n                unset($_SESSION[$prefix][$name]);\n            } else {\n                unset($_SESSION[$name]);\n            }\n        }\n    }\n\n    /**\n     * 清空session数据\n     * @param string|null   $prefix 作用域（前缀）\n     * @return void\n     */\n    public static function clear($prefix = null)\n    {\n        empty(self::$init) && self::boot();\n        $prefix = !is_null($prefix) ? $prefix : self::$prefix;\n        if ($prefix) {\n            unset($_SESSION[$prefix]);\n        } else {\n            $_SESSION = [];\n        }\n    }\n\n    /**\n     * 判断session数据\n     * @param string        $name session名称\n     * @param string|null   $prefix\n     * @return bool\n     */\n    public static function has($name, $prefix = null)\n    {\n        empty(self::$init) && self::boot();\n        $prefix = !is_null($prefix) ? $prefix : self::$prefix;\n        if (strpos($name, '.')) {\n            // 支持数组\n            list($name1, $name2) = explode('.', $name);\n            return $prefix ? isset($_SESSION[$prefix][$name1][$name2]) : isset($_SESSION[$name1][$name2]);\n        } else {\n            return $prefix ? isset($_SESSION[$prefix][$name]) : isset($_SESSION[$name]);\n        }\n    }\n\n    /**\n     * 添加数据到一个session数组\n     * @param  string  $key\n     * @param  mixed   $value\n     * @return void\n     */\n    public static function push($key, $value)\n    {\n        $array = self::get($key);\n        if (is_null($array)) {\n            $array = [];\n        }\n        $array[] = $value;\n        self::set($key, $array);\n    }\n\n    /**\n     * 启动session\n     * @return void\n     */\n    public static function start()\n    {\n        session_start();\n        self::$init = true;\n    }\n\n    /**\n     * 销毁session\n     * @return void\n     */\n    public static function destroy()\n    {\n        if (!empty($_SESSION)) {\n            $_SESSION = [];\n        }\n        session_unset();\n        session_destroy();\n        self::$init = null;\n    }\n\n    /**\n     * 重新生成session_id\n     * @param bool $delete 是否删除关联会话文件\n     * @return void\n     */\n    private static function regenerate($delete = false)\n    {\n        session_regenerate_id($delete);\n    }\n\n    /**\n     * 暂停session\n     * @return void\n     */\n    public static function pause()\n    {\n        // 暂停session\n        session_write_close();\n        self::$init = false;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Template.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\exception\\TemplateNotFoundException;\n\n/**\n * ThinkPHP分离出来的模板引擎\n * 支持XML标签和普通标签的模板解析\n * 编译型模板引擎 支持动态缓存\n */\nclass Template\n{\n    // 模板变量\n    protected $data = [];\n    // 引擎配置\n    protected $config = [\n        'view_path'          => '', // 模板路径\n        'view_base'          => '',\n        'view_suffix'        => 'html', // 默认模板文件后缀\n        'view_depr'          => DS,\n        'cache_suffix'       => 'php', // 默认模板缓存后缀\n        'tpl_deny_func_list' => 'echo,exit', // 模板引擎禁用函数\n        'tpl_deny_php'       => false, // 默认模板引擎是否禁用PHP原生代码\n        'tpl_begin'          => '{', // 模板引擎普通标签开始标记\n        'tpl_end'            => '}', // 模板引擎普通标签结束标记\n        'strip_space'        => false, // 是否去除模板文件里面的html空格与换行\n        'tpl_cache'          => true, // 是否开启模板编译缓存,设为false则每次都会重新编译\n        'compile_type'       => 'file', // 模板编译类型\n        'cache_prefix'       => '', // 模板缓存前缀标识，可以动态改变\n        'cache_time'         => 0, // 模板缓存有效期 0 为永久，(以数字为值，单位:秒)\n        'layout_on'          => false, // 布局模板开关\n        'layout_name'        => 'layout', // 布局模板入口文件\n        'layout_item'        => '{__CONTENT__}', // 布局模板的内容替换标识\n        'taglib_begin'       => '{', // 标签库标签开始标记\n        'taglib_end'         => '}', // 标签库标签结束标记\n        'taglib_load'        => true, // 是否使用内置标签库之外的其它标签库，默认自动检测\n        'taglib_build_in'    => 'cx', // 内置标签库名称(标签使用不必指定标签库名称),以逗号分隔 注意解析顺序\n        'taglib_pre_load'    => '', // 需要额外加载的标签库(须指定标签库名称)，多个以逗号分隔\n        'display_cache'      => false, // 模板渲染缓存\n        'cache_id'           => '', // 模板缓存ID\n        'tpl_replace_string' => [],\n        'tpl_var_identify'   => 'array', // .语法变量识别，array|object|'', 为空时自动识别\n    ];\n\n    private $literal     = [];\n    private $includeFile = []; // 记录所有模板包含的文件路径及更新时间\n    protected $storage;\n\n    /**\n     * 构造函数\n     * @access public\n     */\n    public function __construct(array $config = [])\n    {\n        $this->config['cache_path']   = TEMP_PATH;\n        $this->config                 = array_merge($this->config, $config);\n        $this->config['taglib_begin'] = $this->stripPreg($this->config['taglib_begin']);\n        $this->config['taglib_end']   = $this->stripPreg($this->config['taglib_end']);\n        $this->config['tpl_begin']    = $this->stripPreg($this->config['tpl_begin']);\n        $this->config['tpl_end']      = $this->stripPreg($this->config['tpl_end']);\n\n        // 初始化模板编译存储器\n        $type          = $this->config['compile_type'] ? $this->config['compile_type'] : 'File';\n        $class         = false !== strpos($type, '\\\\') ? $type : '\\\\think\\\\template\\\\driver\\\\' . ucwords($type);\n        $this->storage = new $class();\n    }\n\n    /**\n     * 字符串替换 避免正则混淆\n     * @access private\n     * @param string $str\n     * @return string\n     */\n    private function stripPreg($str)\n    {\n        return str_replace(\n            ['{', '}', '(', ')', '|', '[', ']', '-', '+', '*', '.', '^', '?'],\n            ['\\{', '\\}', '\\(', '\\)', '\\|', '\\[', '\\]', '\\-', '\\+', '\\*', '\\.', '\\^', '\\?'],\n            $str);\n    }\n\n    /**\n     * 模板变量赋值\n     * @access public\n     * @param mixed $name\n     * @param mixed $value\n     * @return void\n     */\n    public function assign($name, $value = '')\n    {\n        if (is_array($name)) {\n            $this->data = array_merge($this->data, $name);\n        } else {\n            $this->data[$name] = $value;\n        }\n    }\n\n    /**\n     * 模板引擎参数赋值\n     * @access public\n     * @param mixed $name\n     * @param mixed $value\n     */\n    public function __set($name, $value)\n    {\n        $this->config[$name] = $value;\n    }\n\n    /**\n     * 模板引擎配置项\n     * @access public\n     * @param array|string $config\n     * @return void|array\n     */\n    public function config($config)\n    {\n        if (is_array($config)) {\n            $this->config = array_merge($this->config, $config);\n        } elseif (isset($this->config[$config])) {\n            return $this->config[$config];\n        } else {\n            return;\n        }\n    }\n\n    /**\n     * 模板变量获取\n     * @access public\n     * @param  string $name 变量名\n     * @return mixed\n     */\n    public function get($name = '')\n    {\n        if ('' == $name) {\n            return $this->data;\n        } else {\n            $data = $this->data;\n            foreach (explode('.', $name) as $key => $val) {\n                if (isset($data[$val])) {\n                    $data = $data[$val];\n                } else {\n                    $data = null;\n                    break;\n                }\n            }\n            return $data;\n        }\n    }\n\n    /**\n     * 渲染模板文件\n     * @access public\n     * @param string    $template 模板文件\n     * @param array     $vars 模板变量\n     * @param array     $config 模板参数\n     * @return void\n     */\n    public function fetch($template, $vars = [], $config = [])\n    {\n        if ($vars) {\n            $this->data = $vars;\n        }\n        if ($config) {\n            $this->config($config);\n        }\n        if (!empty($this->config['cache_id']) && $this->config['display_cache']) {\n            // 读取渲染缓存\n            $cacheContent = Cache::get($this->config['cache_id']);\n            if (false !== $cacheContent) {\n                echo $cacheContent;\n                return;\n            }\n        }\n        $template = $this->parseTemplateFile($template);\n        if ($template) {\n            $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($template) . '.' . ltrim($this->config['cache_suffix'], '.');\n            if (!$this->checkCache($cacheFile)) {\n                // 缓存无效 重新模板编译\n                $content = file_get_contents($template);\n                $this->compiler($content, $cacheFile);\n            }\n            // 页面缓存\n            ob_start();\n            ob_implicit_flush(0);\n            // 读取编译存储\n            $this->storage->read($cacheFile, $this->data);\n            // 获取并清空缓存\n            $content = ob_get_clean();\n            if (!empty($this->config['cache_id']) && $this->config['display_cache']) {\n                // 缓存页面输出\n                Cache::set($this->config['cache_id'], $content, $this->config['cache_time']);\n            }\n            echo $content;\n        }\n    }\n\n    /**\n     * 渲染模板内容\n     * @access public\n     * @param string    $content 模板内容\n     * @param array     $vars 模板变量\n     * @param array     $config 模板参数\n     * @return void\n     */\n    public function display($content, $vars = [], $config = [])\n    {\n        if ($vars) {\n            $this->data = $vars;\n        }\n        if ($config) {\n            $this->config($config);\n        }\n        $cacheFile = $this->config['cache_path'] . $this->config['cache_prefix'] . md5($content) . '.' . ltrim($this->config['cache_suffix'], '.');\n        if (!$this->checkCache($cacheFile)) {\n            // 缓存无效 模板编译\n            $this->compiler($content, $cacheFile);\n        }\n        // 读取编译存储\n        $this->storage->read($cacheFile, $this->data);\n    }\n\n    /**\n     * 设置布局\n     * @access public\n     * @param mixed     $name 布局模板名称 false 则关闭布局\n     * @param string    $replace 布局模板内容替换标识\n     * @return object\n     */\n    public function layout($name, $replace = '')\n    {\n        if (false === $name) {\n            // 关闭布局\n            $this->config['layout_on'] = false;\n        } else {\n            // 开启布局\n            $this->config['layout_on'] = true;\n            // 名称必须为字符串\n            if (is_string($name)) {\n                $this->config['layout_name'] = $name;\n            }\n            if (!empty($replace)) {\n                $this->config['layout_item'] = $replace;\n            }\n        }\n        return $this;\n    }\n\n    /**\n     * 检查编译缓存是否有效\n     * 如果无效则需要重新编译\n     * @access private\n     * @param string $cacheFile 缓存文件名\n     * @return boolean\n     */\n    private function checkCache($cacheFile)\n    {\n        // 未开启缓存功能\n        if (!$this->config['tpl_cache']) {\n            return false;\n        }\n        // 缓存文件不存在\n        if (!is_file($cacheFile)) {\n            return false;\n        }\n        // 读取缓存文件失败\n        if (!$handle = @fopen($cacheFile, \"r\")) {\n            return false;\n        }\n        // 读取第一行\n        preg_match('/\\/\\*(.+?)\\*\\//', fgets($handle), $matches);\n        if (!isset($matches[1])) {\n            return false;\n        }\n        $includeFile = unserialize($matches[1]);\n        if (!is_array($includeFile)) {\n            return false;\n        }\n        // 检查模板文件是否有更新\n        foreach ($includeFile as $path => $time) {\n            if (is_file($path) && filemtime($path) > $time) {\n                // 模板文件如果有更新则缓存需要更新\n                return false;\n            }\n        }\n        // 检查编译存储是否有效\n        return $this->storage->check($cacheFile, $this->config['cache_time']);\n    }\n\n    /**\n     * 检查编译缓存是否存在\n     * @access public\n     * @param string $cacheId 缓存的id\n     * @return boolean\n     */\n    public function isCache($cacheId)\n    {\n        if ($cacheId && $this->config['display_cache']) {\n            // 缓存页面输出\n            return Cache::has($cacheId);\n        }\n        return false;\n    }\n\n    /**\n     * 编译模板文件内容\n     * @access private\n     * @param string    $content 模板内容\n     * @param string    $cacheFile 缓存文件名\n     * @return void\n     */\n    private function compiler(&$content, $cacheFile)\n    {\n        // 判断是否启用布局\n        if ($this->config['layout_on']) {\n            if (false !== strpos($content, '{__NOLAYOUT__}')) {\n                // 可以单独定义不使用布局\n                $content = str_replace('{__NOLAYOUT__}', '', $content);\n            } else {\n                // 读取布局模板\n                $layoutFile = $this->parseTemplateFile($this->config['layout_name']);\n                if ($layoutFile) {\n                    // 替换布局的主体内容\n                    $content = str_replace($this->config['layout_item'], $content, file_get_contents($layoutFile));\n                }\n            }\n        } else {\n            $content = str_replace('{__NOLAYOUT__}', '', $content);\n        }\n\n        // 模板解析\n        $this->parse($content);\n        if ($this->config['strip_space']) {\n            /* 去除html空格与换行 */\n            $find    = ['~>\\s+<~', '~>(\\s+\\n|\\r)~'];\n            $replace = ['><', '>'];\n            $content = preg_replace($find, $replace, $content);\n        }\n        // 优化生成的php代码\n        $content = preg_replace('/\\?>\\s*<\\?php\\s(?!echo\\b)/s', '', $content);\n        // 模板过滤输出\n        $replace = $this->config['tpl_replace_string'];\n        $content = str_replace(array_keys($replace), array_values($replace), $content);\n        // 添加安全代码及模板引用记录\n        $content = '<?php if (!defined(\\'THINK_PATH\\')) exit(); /*' . serialize($this->includeFile) . '*/ ?>' . \"\\n\" . $content;\n        // 编译存储\n        $this->storage->write($cacheFile, $content);\n        $this->includeFile = [];\n        return;\n    }\n\n    /**\n     * 模板解析入口\n     * 支持普通标签和TagLib解析 支持自定义标签库\n     * @access public\n     * @param string $content 要解析的模板内容\n     * @return void\n     */\n    public function parse(&$content)\n    {\n        // 内容为空不解析\n        if (empty($content)) {\n            return;\n        }\n        // 替换literal标签内容\n        $this->parseLiteral($content);\n        // 解析继承\n        $this->parseExtend($content);\n        // 解析布局\n        $this->parseLayout($content);\n        // 检查include语法\n        $this->parseInclude($content);\n        // 替换包含文件中literal标签内容\n        $this->parseLiteral($content);\n        // 检查PHP语法\n        $this->parsePhp($content);\n\n        // 获取需要引入的标签库列表\n        // 标签库只需要定义一次，允许引入多个一次\n        // 一般放在文件的最前面\n        // 格式：<taglib name=\"html,mytag...\" />\n        // 当TAGLIB_LOAD配置为true时才会进行检测\n        if ($this->config['taglib_load']) {\n            $tagLibs = $this->getIncludeTagLib($content);\n            if (!empty($tagLibs)) {\n                // 对导入的TagLib进行解析\n                foreach ($tagLibs as $tagLibName) {\n                    $this->parseTagLib($tagLibName, $content);\n                }\n            }\n        }\n        // 预先加载的标签库 无需在每个模板中使用taglib标签加载 但必须使用标签库XML前缀\n        if ($this->config['taglib_pre_load']) {\n            $tagLibs = explode(',', $this->config['taglib_pre_load']);\n            foreach ($tagLibs as $tag) {\n                $this->parseTagLib($tag, $content);\n            }\n        }\n        // 内置标签库 无需使用taglib标签导入就可以使用 并且不需使用标签库XML前缀\n        $tagLibs = explode(',', $this->config['taglib_build_in']);\n        foreach ($tagLibs as $tag) {\n            $this->parseTagLib($tag, $content, true);\n        }\n        // 解析普通模板标签 {$tagName}\n        $this->parseTag($content);\n\n        // 还原被替换的Literal标签\n        $this->parseLiteral($content, true);\n        return;\n    }\n\n    /**\n     * 检查PHP语法\n     * @access private\n     * @param string $content 要解析的模板内容\n     * @return void\n     * @throws \\think\\Exception\n     */\n    private function parsePhp(&$content)\n    {\n        // 短标签的情况要将<?标签用echo方式输出 否则无法正常输出xml标识\n        $content = preg_replace('/(<\\?(?!php|=|$))/i', '<?php echo \\'\\\\1\\'; ?>' . \"\\n\", $content);\n        // PHP语法检查\n        if ($this->config['tpl_deny_php'] && false !== strpos($content, '<?php')) {\n            throw new Exception('not allow php tag', 11600);\n        }\n        return;\n    }\n\n    /**\n     * 解析模板中的布局标签\n     * @access private\n     * @param string $content 要解析的模板内容\n     * @return void\n     */\n    private function parseLayout(&$content)\n    {\n        // 读取模板中的布局标签\n        if (preg_match($this->getRegex('layout'), $content, $matches)) {\n            // 替换Layout标签\n            $content = str_replace($matches[0], '', $content);\n            // 解析Layout标签\n            $array = $this->parseAttr($matches[0]);\n            if (!$this->config['layout_on'] || $this->config['layout_name'] != $array['name']) {\n                // 读取布局模板\n                $layoutFile = $this->parseTemplateFile($array['name']);\n                if ($layoutFile) {\n                    $replace = isset($array['replace']) ? $array['replace'] : $this->config['layout_item'];\n                    // 替换布局的主体内容\n                    $content = str_replace($replace, $content, file_get_contents($layoutFile));\n                }\n            }\n        } else {\n            $content = str_replace('{__NOLAYOUT__}', '', $content);\n        }\n        return;\n    }\n\n    /**\n     * 解析模板中的include标签\n     * @access private\n     * @param  string $content 要解析的模板内容\n     * @return void\n     */\n    private function parseInclude(&$content)\n    {\n        $regex = $this->getRegex('include');\n        $func  = function ($template) use (&$func, &$regex, &$content) {\n            if (preg_match_all($regex, $template, $matches, PREG_SET_ORDER)) {\n                foreach ($matches as $match) {\n                    $array = $this->parseAttr($match[0]);\n                    $file  = $array['file'];\n                    unset($array['file']);\n                    // 分析模板文件名并读取内容\n                    $parseStr = $this->parseTemplateName($file);\n                    foreach ($array as $k => $v) {\n                        // 以$开头字符串转换成模板变量\n                        if (0 === strpos($v, '$')) {\n                            $v = $this->get(substr($v, 1));\n                        }\n                        $parseStr = str_replace('[' . $k . ']', $v, $parseStr);\n                    }\n                    $content = str_replace($match[0], $parseStr, $content);\n                    // 再次对包含文件进行模板分析\n                    $func($parseStr);\n                }\n                unset($matches);\n            }\n        };\n        // 替换模板中的include标签\n        $func($content);\n        return;\n    }\n\n    /**\n     * 解析模板中的extend标签\n     * @access private\n     * @param  string $content 要解析的模板内容\n     * @return void\n     */\n    private function parseExtend(&$content)\n    {\n        $regex  = $this->getRegex('extend');\n        $array  = $blocks  = $baseBlocks  = [];\n        $extend = '';\n        $func   = function ($template) use (&$func, &$regex, &$array, &$extend, &$blocks, &$baseBlocks) {\n            if (preg_match($regex, $template, $matches)) {\n                if (!isset($array[$matches['name']])) {\n                    $array[$matches['name']] = 1;\n                    // 读取继承模板\n                    $extend = $this->parseTemplateName($matches['name']);\n                    // 递归检查继承\n                    $func($extend);\n                    // 取得block标签内容\n                    $blocks = array_merge($blocks, $this->parseBlock($template));\n                    return;\n                }\n            } else {\n                // 取得顶层模板block标签内容\n                $baseBlocks = $this->parseBlock($template, true);\n                if (empty($extend)) {\n                    // 无extend标签但有block标签的情况\n                    $extend = $template;\n                }\n            }\n        };\n\n        $func($content);\n        if (!empty($extend)) {\n            if ($baseBlocks) {\n                $children = [];\n                foreach ($baseBlocks as $name => $val) {\n                    $replace = $val['content'];\n                    if (!empty($children[$name])) {\n                        // 如果包含有子block标签\n                        foreach ($children[$name] as $key) {\n                            $replace = str_replace($baseBlocks[$key]['begin'] . $baseBlocks[$key]['content'] . $baseBlocks[$key]['end'], $blocks[$key]['content'], $replace);\n                        }\n                    }\n                    if (isset($blocks[$name])) {\n                        // 带有{__block__}表示与所继承模板的相应标签合并，而不是覆盖\n                        $replace = str_replace(['{__BLOCK__}', '{__block__}'], $replace, $blocks[$name]['content']);\n                        if (!empty($val['parent'])) {\n                            // 如果不是最顶层的block标签\n                            $parent = $val['parent'];\n                            if (isset($blocks[$parent])) {\n                                $blocks[$parent]['content'] = str_replace($blocks[$name]['begin'] . $blocks[$name]['content'] . $blocks[$name]['end'], $replace, $blocks[$parent]['content']);\n                            }\n                            $blocks[$name]['content'] = $replace;\n                            $children[$parent][]      = $name;\n                            continue;\n                        }\n                    } elseif (!empty($val['parent'])) {\n                        // 如果子标签没有被继承则用原值\n                        $children[$val['parent']][] = $name;\n                        $blocks[$name]              = $val;\n                    }\n                    if (!$val['parent']) {\n                        // 替换模板中的顶级block标签\n                        $extend = str_replace($val['begin'] . $val['content'] . $val['end'], $replace, $extend);\n                    }\n                }\n            }\n            $content = $extend;\n            unset($blocks, $baseBlocks);\n        }\n        return;\n    }\n\n    /**\n     * 替换页面中的literal标签\n     * @access private\n     * @param  string   $content 模板内容\n     * @param  boolean  $restore 是否为还原\n     * @return void\n     */\n    private function parseLiteral(&$content, $restore = false)\n    {\n        $regex = $this->getRegex($restore ? 'restoreliteral' : 'literal');\n        if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) {\n            if (!$restore) {\n                $count = count($this->literal);\n                // 替换literal标签\n                foreach ($matches as $match) {\n                    $this->literal[] = substr($match[0], strlen($match[1]), -strlen($match[2]));\n                    $content         = str_replace($match[0], \"<!--###literal{$count}###-->\", $content);\n                    $count++;\n                }\n            } else {\n                // 还原literal标签\n                foreach ($matches as $match) {\n                    $content = str_replace($match[0], $this->literal[$match[1]], $content);\n                }\n                // 清空literal记录\n                $this->literal = [];\n            }\n            unset($matches);\n        }\n        return;\n    }\n\n    /**\n     * 获取模板中的block标签\n     * @access private\n     * @param  string   $content 模板内容\n     * @param  boolean  $sort 是否排序\n     * @return array\n     */\n    private function parseBlock(&$content, $sort = false)\n    {\n        $regex  = $this->getRegex('block');\n        $result = [];\n        if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {\n            $right = $keys = [];\n            foreach ($matches as $match) {\n                if (empty($match['name'][0])) {\n                    if (count($right) > 0) {\n                        $tag                  = array_pop($right);\n                        $start                = $tag['offset'] + strlen($tag['tag']);\n                        $length               = $match[0][1] - $start;\n                        $result[$tag['name']] = [\n                            'begin'   => $tag['tag'],\n                            'content' => substr($content, $start, $length),\n                            'end'     => $match[0][0],\n                            'parent'  => count($right) ? end($right)['name'] : '',\n                        ];\n                        $keys[$tag['name']] = $match[0][1];\n                    }\n                } else {\n                    // 标签头压入栈\n                    $right[] = [\n                        'name'   => $match[2][0],\n                        'offset' => $match[0][1],\n                        'tag'    => $match[0][0],\n                    ];\n                }\n            }\n            unset($right, $matches);\n            if ($sort) {\n                // 按block标签结束符在模板中的位置排序\n                array_multisort($keys, $result);\n            }\n        }\n        return $result;\n    }\n\n    /**\n     * 搜索模板页面中包含的TagLib库\n     * 并返回列表\n     * @access private\n     * @param  string $content 模板内容\n     * @return array|null\n     */\n    private function getIncludeTagLib(&$content)\n    {\n        // 搜索是否有TagLib标签\n        if (preg_match($this->getRegex('taglib'), $content, $matches)) {\n            // 替换TagLib标签\n            $content = str_replace($matches[0], '', $content);\n            return explode(',', $matches['name']);\n        }\n        return;\n    }\n\n    /**\n     * TagLib库解析\n     * @access public\n     * @param  string   $tagLib 要解析的标签库\n     * @param  string   $content 要解析的模板内容\n     * @param  boolean  $hide 是否隐藏标签库前缀\n     * @return void\n     */\n    public function parseTagLib($tagLib, &$content, $hide = false)\n    {\n        if (false !== strpos($tagLib, '\\\\')) {\n            // 支持指定标签库的命名空间\n            $className = $tagLib;\n            $tagLib    = substr($tagLib, strrpos($tagLib, '\\\\') + 1);\n        } else {\n            $className = '\\\\think\\\\template\\\\taglib\\\\' . ucwords($tagLib);\n        }\n        $tLib = new $className($this);\n        $tLib->parseTag($content, $hide ? '' : $tagLib);\n        return;\n    }\n\n    /**\n     * 分析标签属性\n     * @access public\n     * @param  string   $str 属性字符串\n     * @param  string   $name 不为空时返回指定的属性名\n     * @return array\n     */\n    public function parseAttr($str, $name = null)\n    {\n        $regex = '/\\s+(?>(?P<name>[\\w-]+)\\s*)=(?>\\s*)([\\\"\\'])(?P<value>(?:(?!\\\\2).)*)\\\\2/is';\n        $array = [];\n        if (preg_match_all($regex, $str, $matches, PREG_SET_ORDER)) {\n            foreach ($matches as $match) {\n                $array[$match['name']] = $match['value'];\n            }\n            unset($matches);\n        }\n        if (!empty($name) && isset($array[$name])) {\n            return $array[$name];\n        } else {\n            return $array;\n        }\n    }\n\n    /**\n     * 模板标签解析\n     * 格式： {TagName:args [|content] }\n     * @access private\n     * @param  string $content 要解析的模板内容\n     * @return void\n     */\n    private function parseTag(&$content)\n    {\n        $regex = $this->getRegex('tag');\n        if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER)) {\n            foreach ($matches as $match) {\n                $str  = stripslashes($match[1]);\n                $flag = substr($str, 0, 1);\n                switch ($flag) {\n                    case '$':\n                        // 解析模板变量 格式 {$varName}\n                        // 是否带有?号\n                        if (false !== $pos = strpos($str, '?')) {\n                            $array = preg_split('/([!=]={1,2}|(?<!-)[><]={0,1})/', substr($str, 0, $pos), 2, PREG_SPLIT_DELIM_CAPTURE);\n                            $name  = $array[0];\n                            $this->parseVar($name);\n                            $this->parseVarFunction($name);\n\n                            $str = trim(substr($str, $pos + 1));\n                            $this->parseVar($str);\n                            $first = substr($str, 0, 1);\n                            if (strpos($name, ')')) {\n                                // $name为对象或是自动识别，或者含有函数\n                                if (isset($array[1])) {\n                                    $this->parseVar($array[2]);\n                                    $name .= $array[1] . $array[2];\n                                }\n                                switch ($first) {\n                                    case '?':\n                                        $str = '<?php echo (' . $name . ') ? ' . $name . ' : ' . substr($str, 1) . '; ?>';\n                                        break;\n                                    case '=':\n                                        $str = '<?php if(' . $name . ') echo ' . substr($str, 1) . '; ?>';\n                                        break;\n                                    default:\n                                        $str = '<?php echo ' . $name . '?' . $str . '; ?>';\n                                }\n                            } else {\n                                if (isset($array[1])) {\n                                    $this->parseVar($array[2]);\n                                    $_name = ' && ' . $name . $array[1] . $array[2];\n                                } else {\n                                    $_name = '';\n                                }\n                                // $name为数组\n                                switch ($first) {\n                                    case '?':\n                                        // {$varname??'xxx'} $varname有定义则输出$varname,否则输出xxx\n                                        $str = '<?php echo isset(' . $name . ')' . $_name . ' ? ' . $name . ' : ' . substr($str, 1) . '; ?>';\n                                        break;\n                                    case '=':\n                                        // {$varname?='xxx'} $varname为真时才输出xxx\n                                        $str = '<?php if(!empty(' . $name . ')' . $_name . ') echo ' . substr($str, 1) . '; ?>';\n                                        break;\n                                    case ':':\n                                        // {$varname?:'xxx'} $varname为真时输出$varname,否则输出xxx\n                                        $str = '<?php echo !empty(' . $name . ')' . $_name . '?' . $name . $str . '; ?>';\n                                        break;\n                                    default:\n                                        if (strpos($str, ':')) {\n                                            // {$varname ? 'a' : 'b'} $varname为真时输出a,否则输出b\n                                            $str = '<?php echo !empty(' . $name . ')' . $_name . '?' . $str . '; ?>';\n                                        } else {\n                                            $str = '<?php echo ' . $_name . '?' . $str . '; ?>';\n                                        }\n                                }\n                            }\n                        } else {\n                            $this->parseVar($str);\n                            $this->parseVarFunction($str);\n                            $str = '<?php echo ' . $str . '; ?>';\n                        }\n                        break;\n                    case ':':\n                        // 输出某个函数的结果\n                        $str = substr($str, 1);\n                        $this->parseVar($str);\n                        $str = '<?php echo ' . $str . '; ?>';\n                        break;\n                    case '~':\n                        // 执行某个函数\n                        $str = substr($str, 1);\n                        $this->parseVar($str);\n                        $str = '<?php ' . $str . '; ?>';\n                        break;\n                    case '-':\n                    case '+':\n                        // 输出计算\n                        $this->parseVar($str);\n                        $str = '<?php echo ' . $str . '; ?>';\n                        break;\n                    case '/':\n                        // 注释标签\n                        $flag2 = substr($str, 1, 1);\n                        if ('/' == $flag2 || ('*' == $flag2 && substr(rtrim($str), -2) == '*/')) {\n                            $str = '';\n                        }\n                        break;\n                    default:\n                        // 未识别的标签直接返回\n                        $str = $this->config['tpl_begin'] . $str . $this->config['tpl_end'];\n                        break;\n                }\n                $content = str_replace($match[0], $str, $content);\n            }\n            unset($matches);\n        }\n        return;\n    }\n\n    /**\n     * 模板变量解析,支持使用函数\n     * 格式： {$varname|function1|function2=arg1,arg2}\n     * @access public\n     * @param  string $varStr 变量数据\n     * @return void\n     */\n    public function parseVar(&$varStr)\n    {\n        $varStr = trim($varStr);\n        if (preg_match_all('/\\$[a-zA-Z_](?>\\w*)(?:[:\\.][0-9a-zA-Z_](?>\\w*))+/', $varStr, $matches, PREG_OFFSET_CAPTURE)) {\n            static $_varParseList = [];\n            while ($matches[0]) {\n                $match = array_pop($matches[0]);\n                //如果已经解析过该变量字串，则直接返回变量值\n                if (isset($_varParseList[$match[0]])) {\n                    $parseStr = $_varParseList[$match[0]];\n                } else {\n                    if (strpos($match[0], '.')) {\n                        $vars  = explode('.', $match[0]);\n                        $first = array_shift($vars);\n                        if ('$Think' == $first) {\n                            // 所有以Think.打头的以特殊变量对待 无需模板赋值就可以输出\n                            $parseStr = $this->parseThinkVar($vars);\n                        } elseif ('$Request' == $first) {\n                            // 获取Request请求对象参数\n                            $method = array_shift($vars);\n                            if (!empty($vars)) {\n                                $params = implode('.', $vars);\n                                if ('true' != $params) {\n                                    $params = '\\'' . $params . '\\'';\n                                }\n                            } else {\n                                $params = '';\n                            }\n                            $parseStr = '\\think\\Request::instance()->' . $method . '(' . $params . ')';\n                        } else {\n                            switch ($this->config['tpl_var_identify']) {\n                                case 'array': // 识别为数组\n                                    $parseStr = $first . '[\\'' . implode('\\'][\\'', $vars) . '\\']';\n                                    break;\n                                case 'obj': // 识别为对象\n                                    $parseStr = $first . '->' . implode('->', $vars);\n                                    break;\n                                default: // 自动判断数组或对象\n                                    $parseStr = '(is_array(' . $first . ')?' . $first . '[\\'' . implode('\\'][\\'', $vars) . '\\']:' . $first . '->' . implode('->', $vars) . ')';\n                            }\n                        }\n                    } else {\n                        $parseStr = str_replace(':', '->', $match[0]);\n                    }\n                    $_varParseList[$match[0]] = $parseStr;\n                }\n                $varStr = substr_replace($varStr, $parseStr, $match[1], strlen($match[0]));\n            }\n            unset($matches);\n        }\n        return;\n    }\n\n    /**\n     * 对模板中使用了函数的变量进行解析\n     * 格式 {$varname|function1|function2=arg1,arg2}\n     * @access public\n     * @param  string $varStr 变量字符串\n     * @return void\n     */\n    public function parseVarFunction(&$varStr)\n    {\n        if (false == strpos($varStr, '|')) {\n            return;\n        }\n        static $_varFunctionList = [];\n        $_key                    = md5($varStr);\n        //如果已经解析过该变量字串，则直接返回变量值\n        if (isset($_varFunctionList[$_key])) {\n            $varStr = $_varFunctionList[$_key];\n        } else {\n            $varArray = explode('|', $varStr);\n            // 取得变量名称\n            $name = array_shift($varArray);\n            // 对变量使用函数\n            $length = count($varArray);\n            // 取得模板禁止使用函数列表\n            $template_deny_funs = explode(',', $this->config['tpl_deny_func_list']);\n            for ($i = 0; $i < $length; $i++) {\n                $args = explode('=', $varArray[$i], 2);\n                // 模板函数过滤\n                $fun = trim($args[0]);\n                switch ($fun) {\n                    case 'default': // 特殊模板函数\n                        if (false === strpos($name, '(')) {\n                            $name = '(isset(' . $name . ') && (' . $name . ' !== \\'\\')?' . $name . ':' . $args[1] . ')';\n                        } else {\n                            $name = '(' . $name . ' ?: ' . $args[1] . ')';\n                        }\n                        break;\n                    default: // 通用模板函数\n                        if (!in_array($fun, $template_deny_funs)) {\n                            if (isset($args[1])) {\n                                if (strstr($args[1], '###')) {\n                                    $args[1] = str_replace('###', $name, $args[1]);\n                                    $name    = \"$fun($args[1])\";\n                                } else {\n                                    $name = \"$fun($name,$args[1])\";\n                                }\n                            } else {\n                                if (!empty($args[0])) {\n                                    $name = \"$fun($name)\";\n                                }\n                            }\n                        }\n                }\n            }\n            $_varFunctionList[$_key] = $name;\n            $varStr                  = $name;\n        }\n        return;\n    }\n\n    /**\n     * 特殊模板变量解析\n     * 格式 以 $Think. 打头的变量属于特殊模板变量\n     * @access public\n     * @param  array $vars 变量数组\n     * @return string\n     */\n    public function parseThinkVar($vars)\n    {\n        $type  = strtoupper(trim(array_shift($vars)));\n        $param = implode('.', $vars);\n        if ($vars) {\n            switch ($type) {\n                case 'SERVER':\n                    $parseStr = '\\\\think\\\\Request::instance()->server(\\'' . $param . '\\')';\n                    break;\n                case 'GET':\n                    $parseStr = '\\\\think\\\\Request::instance()->get(\\'' . $param . '\\')';\n                    break;\n                case 'POST':\n                    $parseStr = '\\\\think\\\\Request::instance()->post(\\'' . $param . '\\')';\n                    break;\n                case 'COOKIE':\n                    $parseStr = '\\\\think\\\\Cookie::get(\\'' . $param . '\\')';\n                    break;\n                case 'SESSION':\n                    $parseStr = '\\\\think\\\\Session::get(\\'' . $param . '\\')';\n                    break;\n                case 'ENV':\n                    $parseStr = '\\\\think\\\\Request::instance()->env(\\'' . $param . '\\')';\n                    break;\n                case 'REQUEST':\n                    $parseStr = '\\\\think\\\\Request::instance()->request(\\'' . $param . '\\')';\n                    break;\n                case 'CONST':\n                    $parseStr = strtoupper($param);\n                    break;\n                case 'LANG':\n                    $parseStr = '\\\\think\\\\Lang::get(\\'' . $param . '\\')';\n                    break;\n                case 'CONFIG':\n                    $parseStr = '\\\\think\\\\Config::get(\\'' . $param . '\\')';\n                    break;\n                default:\n                    $parseStr = '\\'\\'';\n                    break;\n            }\n        } else {\n            switch ($type) {\n                case 'NOW':\n                    $parseStr = \"date('Y-m-d g:i a',time())\";\n                    break;\n                case 'VERSION':\n                    $parseStr = 'THINK_VERSION';\n                    break;\n                case 'LDELIM':\n                    $parseStr = '\\'' . ltrim($this->config['tpl_begin'], '\\\\') . '\\'';\n                    break;\n                case 'RDELIM':\n                    $parseStr = '\\'' . ltrim($this->config['tpl_end'], '\\\\') . '\\'';\n                    break;\n                default:\n                    if (defined($type)) {\n                        $parseStr = $type;\n                    } else {\n                        $parseStr = '';\n                    }\n            }\n        }\n        return $parseStr;\n    }\n\n    /**\n     * 分析加载的模板文件并读取内容 支持多个模板文件读取\n     * @access private\n     * @param  string $templateName 模板文件名\n     * @return string\n     */\n    private function parseTemplateName($templateName)\n    {\n        $array    = explode(',', $templateName);\n        $parseStr = '';\n        foreach ($array as $templateName) {\n            if (empty($templateName)) {\n                continue;\n            }\n            if (0 === strpos($templateName, '$')) {\n                //支持加载变量文件名\n                $templateName = $this->get(substr($templateName, 1));\n            }\n            $template = $this->parseTemplateFile($templateName);\n            if ($template) {\n                // 获取模板文件内容\n                $parseStr .= file_get_contents($template);\n            }\n        }\n        return $parseStr;\n    }\n\n    /**\n     * 解析模板文件名\n     * @access private\n     * @param  string $template 文件名\n     * @return string|false\n     */\n    private function parseTemplateFile($template)\n    {\n        if ('' == pathinfo($template, PATHINFO_EXTENSION)) {\n            if (strpos($template, '@')) {\n                list($module, $template) = explode('@', $template);\n            }\n            if (0 !== strpos($template, '/')) {\n                $template = str_replace(['/', ':'], $this->config['view_depr'], $template);\n            } else {\n                $template = str_replace(['/', ':'], $this->config['view_depr'], substr($template, 1));\n            }\n            if ($this->config['view_base']) {\n                $module = isset($module) ? $module : Request::instance()->module();\n                $path   = $this->config['view_base'] . ($module ? $module . DS : '');\n            } else {\n                $path = isset($module) ? APP_PATH . $module . DS . basename($this->config['view_path']) . DS : $this->config['view_path'];\n            }\n            $template = $path . $template . '.' . ltrim($this->config['view_suffix'], '.');\n        }\n\n        if (is_file($template)) {\n            // 记录模板文件的更新时间\n            $this->includeFile[$template] = filemtime($template);\n            return $template;\n        } else {\n            throw new TemplateNotFoundException('template not exists:' . $template, $template);\n        }\n    }\n\n    /**\n     * 按标签生成正则\n     * @access private\n     * @param  string $tagName 标签名\n     * @return string\n     */\n    private function getRegex($tagName)\n    {\n        $regex = '';\n        if ('tag' == $tagName) {\n            $begin = $this->config['tpl_begin'];\n            $end   = $this->config['tpl_end'];\n            if (strlen(ltrim($begin, '\\\\')) == 1 && strlen(ltrim($end, '\\\\')) == 1) {\n                $regex = $begin . '((?:[\\$]{1,2}[a-wA-w_]|[\\:\\~][\\$a-wA-w_]|[+]{2}[\\$][a-wA-w_]|[-]{2}[\\$][a-wA-w_]|\\/[\\*\\/])(?>[^' . $end . ']*))' . $end;\n            } else {\n                $regex = $begin . '((?:[\\$]{1,2}[a-wA-w_]|[\\:\\~][\\$a-wA-w_]|[+]{2}[\\$][a-wA-w_]|[-]{2}[\\$][a-wA-w_]|\\/[\\*\\/])(?>(?:(?!' . $end . ').)*))' . $end;\n            }\n        } else {\n            $begin  = $this->config['taglib_begin'];\n            $end    = $this->config['taglib_end'];\n            $single = strlen(ltrim($begin, '\\\\')) == 1 && strlen(ltrim($end, '\\\\')) == 1 ? true : false;\n            switch ($tagName) {\n                case 'block':\n                    if ($single) {\n                        $regex = $begin . '(?:' . $tagName . '\\b(?>(?:(?!name=).)*)\\bname=([\\'\\\"])(?P<name>[\\$\\w\\-\\/\\.]+)\\\\1(?>[^' . $end . ']*)|\\/' . $tagName . ')' . $end;\n                    } else {\n                        $regex = $begin . '(?:' . $tagName . '\\b(?>(?:(?!name=).)*)\\bname=([\\'\\\"])(?P<name>[\\$\\w\\-\\/\\.]+)\\\\1(?>(?:(?!' . $end . ').)*)|\\/' . $tagName . ')' . $end;\n                    }\n                    break;\n                case 'literal':\n                    if ($single) {\n                        $regex = '(' . $begin . $tagName . '\\b(?>[^' . $end . ']*)' . $end . ')';\n                        $regex .= '(?:(?>[^' . $begin . ']*)(?>(?!' . $begin . '(?>' . $tagName . '\\b[^' . $end . ']*|\\/' . $tagName . ')' . $end . ')' . $begin . '[^' . $begin . ']*)*)';\n                        $regex .= '(' . $begin . '\\/' . $tagName . $end . ')';\n                    } else {\n                        $regex = '(' . $begin . $tagName . '\\b(?>(?:(?!' . $end . ').)*)' . $end . ')';\n                        $regex .= '(?:(?>(?:(?!' . $begin . ').)*)(?>(?!' . $begin . '(?>' . $tagName . '\\b(?>(?:(?!' . $end . ').)*)|\\/' . $tagName . ')' . $end . ')' . $begin . '(?>(?:(?!' . $begin . ').)*))*)';\n                        $regex .= '(' . $begin . '\\/' . $tagName . $end . ')';\n                    }\n                    break;\n                case 'restoreliteral':\n                    $regex = '<!--###literal(\\d+)###-->';\n                    break;\n                case 'include':\n                    $name = 'file';\n                case 'taglib':\n                case 'layout':\n                case 'extend':\n                    if (empty($name)) {\n                        $name = 'name';\n                    }\n                    if ($single) {\n                        $regex = $begin . $tagName . '\\b(?>(?:(?!' . $name . '=).)*)\\b' . $name . '=([\\'\\\"])(?P<name>[\\$\\w\\-\\/\\.\\:@,\\\\\\\\]+)\\\\1(?>[^' . $end . ']*)' . $end;\n                    } else {\n                        $regex = $begin . $tagName . '\\b(?>(?:(?!' . $name . '=).)*)\\b' . $name . '=([\\'\\\"])(?P<name>[\\$\\w\\-\\/\\.\\:@,\\\\\\\\]+)\\\\1(?>(?:(?!' . $end . ').)*)' . $end;\n                    }\n                    break;\n            }\n        }\n        return '/' . $regex . '/is';\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Url.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nclass Url\n{\n    // 生成URL地址的root\n    protected static $root;\n    protected static $bindCheck;\n\n    /**\n     * URL生成 支持路由反射\n     * @param string            $url 路由地址\n     * @param string|array      $vars 参数（支持数组和字符串）a=val&b=val2... ['a'=>'val1', 'b'=>'val2']\n     * @param string|bool       $suffix 伪静态后缀，默认为true表示获取配置值\n     * @param boolean|string    $domain 是否显示域名 或者直接传入域名\n     * @return string\n     */\n    public static function build($url = '', $vars = '', $suffix = true, $domain = false)\n    {\n        if (false === $domain && Route::rules('domain')) {\n            $domain = true;\n        }\n        // 解析URL\n        if (0 === strpos($url, '[') && $pos = strpos($url, ']')) {\n            // [name] 表示使用路由命名标识生成URL\n            $name = substr($url, 1, $pos - 1);\n            $url  = 'name' . substr($url, $pos + 1);\n        }\n        if (false === strpos($url, '://') && 0 !== strpos($url, '/')) {\n            $info = parse_url($url);\n            $url  = !empty($info['path']) ? $info['path'] : '';\n            if (isset($info['fragment'])) {\n                // 解析锚点\n                $anchor = $info['fragment'];\n                if (false !== strpos($anchor, '?')) {\n                    // 解析参数\n                    list($anchor, $info['query']) = explode('?', $anchor, 2);\n                }\n                if (false !== strpos($anchor, '@')) {\n                    // 解析域名\n                    list($anchor, $domain) = explode('@', $anchor, 2);\n                }\n            } elseif (strpos($url, '@') && false === strpos($url, '\\\\')) {\n                // 解析域名\n                list($url, $domain) = explode('@', $url, 2);\n            }\n        }\n\n        // 解析参数\n        if (is_string($vars)) {\n            // aaa=1&bbb=2 转换成数组\n            parse_str($vars, $vars);\n        }\n\n        if ($url) {\n            $rule = Route::name(isset($name) ? $name : $url . (isset($info['query']) ? '?' . $info['query'] : ''));\n            if (is_null($rule) && isset($info['query'])) {\n                $rule = Route::name($url);\n                // 解析地址里面参数 合并到vars\n                parse_str($info['query'], $params);\n                $vars = array_merge($params, $vars);\n                unset($info['query']);\n            }\n        }\n        if (!empty($rule) && $match = self::getRuleUrl($rule, $vars)) {\n            // 匹配路由命名标识\n            $url = $match[0];\n            // 替换可选分隔符\n            $url = preg_replace(['/(\\W)\\?$/', '/(\\W)\\?/'], ['', '\\1'], $url);\n            if (!empty($match[1])) {\n                $domain = $match[1];\n            }\n            if (!is_null($match[2])) {\n                $suffix = $match[2];\n            }\n        } elseif (!empty($rule) && isset($name)) {\n            throw new \\InvalidArgumentException('route name not exists:' . $name);\n        } else {\n            // 检查别名路由\n            $alias      = Route::rules('alias');\n            $matchAlias = false;\n            if ($alias) {\n                // 别名路由解析\n                foreach ($alias as $key => $val) {\n                    if (is_array($val)) {\n                        $val = $val[0];\n                    }\n                    if (0 === strpos($url, $val)) {\n                        $url        = $key . substr($url, strlen($val));\n                        $matchAlias = true;\n                        break;\n                    }\n                }\n            }\n            if (!$matchAlias) {\n                // 路由标识不存在 直接解析\n                $url = self::parseUrl($url, $domain);\n            }\n            if (isset($info['query'])) {\n                // 解析地址里面参数 合并到vars\n                parse_str($info['query'], $params);\n                $vars = array_merge($params, $vars);\n            }\n        }\n\n        // 检测URL绑定\n        if (!self::$bindCheck) {\n            $type = Route::getBind('type');\n            if ($type) {\n                $bind = Route::getBind($type);\n                if (0 === strpos($url, $bind)) {\n                    $url = substr($url, strlen($bind) + 1);\n                }\n            }\n        }\n        // 还原URL分隔符\n        $depr = Config::get('pathinfo_depr');\n        $url  = str_replace('/', $depr, $url);\n\n        // URL后缀\n        $suffix = in_array($url, ['/', '']) ? '' : self::parseSuffix($suffix);\n        // 锚点\n        $anchor = !empty($anchor) ? '#' . $anchor : '';\n        // 参数组装\n        if (!empty($vars)) {\n            // 添加参数\n            if (Config::get('url_common_param')) {\n                $vars = urldecode(http_build_query($vars));\n                $url .= $suffix . '?' . $vars . $anchor;\n            } else {\n                $paramType = Config::get('url_param_type');\n                foreach ($vars as $var => $val) {\n                    if ('' !== trim($val)) {\n                        if ($paramType) {\n                            $url .= $depr . urlencode($val);\n                        } else {\n                            $url .= $depr . $var . $depr . urlencode($val);\n                        }\n                    }\n                }\n                $url .= $suffix . $anchor;\n            }\n        } else {\n            $url .= $suffix . $anchor;\n        }\n        // 检测域名\n        $domain = self::parseDomain($url, $domain);\n        // URL组装\n        $url = $domain . rtrim(self::$root ?: Request::instance()->root(), '/') . '/' . ltrim($url, '/');\n\n        self::$bindCheck = false;\n        return $url;\n    }\n\n    // 直接解析URL地址\n    protected static function parseUrl($url, &$domain)\n    {\n        $request = Request::instance();\n        if (0 === strpos($url, '/')) {\n            // 直接作为路由地址解析\n            $url = substr($url, 1);\n        } elseif (false !== strpos($url, '\\\\')) {\n            // 解析到类\n            $url = ltrim(str_replace('\\\\', '/', $url), '/');\n        } elseif (0 === strpos($url, '@')) {\n            // 解析到控制器\n            $url = substr($url, 1);\n        } else {\n            // 解析到 模块/控制器/操作\n            $module  = $request->module();\n            $domains = Route::rules('domain');\n            if (true === $domain && 2 == substr_count($url, '/')) {\n                $current = $request->host();\n                $match   = [];\n                $pos     = [];\n                foreach ($domains as $key => $item) {\n                    if (isset($item['[bind]']) && 0 === strpos($url, $item['[bind]'][0])) {\n                        $pos[$key] = strlen($item['[bind]'][0]) + 1;\n                        $match[]   = $key;\n                        $module    = '';\n                    }\n                }\n                if ($match) {\n                    $domain = current($match);\n                    foreach ($match as $item) {\n                        if (0 === strpos($current, $item)) {\n                            $domain = $item;\n                        }\n                    }\n                    self::$bindCheck = true;\n                    $url             = substr($url, $pos[$domain]);\n                }\n            } elseif ($domain) {\n                if (isset($domains[$domain]['[bind]'][0])) {\n                    $bindModule = $domains[$domain]['[bind]'][0];\n                    if ($bindModule && !in_array($bindModule[0], ['\\\\', '@'])) {\n                        $module = '';\n                    }\n                }\n            }\n            $module = $module ? $module . '/' : '';\n\n            $controller = Loader::parseName($request->controller());\n            if ('' == $url) {\n                // 空字符串输出当前的 模块/控制器/操作\n                $url = $module . $controller . '/' . $request->action();\n            } else {\n                $path       = explode('/', $url);\n                $action     = Config::get('url_convert') ? strtolower(array_pop($path)) : array_pop($path);\n                $controller = empty($path) ? $controller : (Config::get('url_convert') ? Loader::parseName(array_pop($path)) : array_pop($path));\n                $module     = empty($path) ? $module : array_pop($path) . '/';\n                $url        = $module . $controller . '/' . $action;\n            }\n        }\n        return $url;\n    }\n\n    // 检测域名\n    protected static function parseDomain(&$url, $domain)\n    {\n        if (!$domain) {\n            return '';\n        }\n        $request    = Request::instance();\n        $rootDomain = Config::get('url_domain_root');\n        if (true === $domain) {\n            // 自动判断域名\n            $domain = $request->host();\n\n            $domains = Route::rules('domain');\n            if ($domains) {\n                $route_domain = array_keys($domains);\n                foreach ($route_domain as $domain_prefix) {\n                    if (0 === strpos($domain_prefix, '*.') && strpos($domain, ltrim($domain_prefix, '*.')) !== false) {\n                        foreach ($domains as $key => $rule) {\n                            $rule = is_array($rule) ? $rule[0] : $rule;\n                            if (is_string($rule) && false === strpos($key, '*') && 0 === strpos($url, $rule)) {\n                                $url    = ltrim($url, $rule);\n                                $domain = $key;\n                                // 生成对应子域名\n                                if (!empty($rootDomain)) {\n                                    $domain .= $rootDomain;\n                                }\n                                break;\n                            } elseif (false !== strpos($key, '*')) {\n                                if (!empty($rootDomain)) {\n                                    $domain .= $rootDomain;\n                                }\n                                break;\n                            }\n                        }\n                    }\n                }\n            }\n\n        } else {\n            if (empty($rootDomain)) {\n                $host       = $request->host();\n                $rootDomain = substr_count($host, '.') > 1 ? substr(strstr($host, '.'), 1) : $host;\n            }\n            if (substr_count($domain, '.') < 2 && !strpos($domain, $rootDomain)) {\n                $domain .= '.' . $rootDomain;\n            }\n        }\n        return ($request->isSsl() ? 'https://' : 'http://') . $domain;\n    }\n\n    // 解析URL后缀\n    protected static function parseSuffix($suffix)\n    {\n        if ($suffix) {\n            $suffix = true === $suffix ? Config::get('url_html_suffix') : $suffix;\n            if ($pos = strpos($suffix, '|')) {\n                $suffix = substr($suffix, 0, $pos);\n            }\n        }\n        return (empty($suffix) || 0 === strpos($suffix, '.')) ? $suffix : '.' . $suffix;\n    }\n\n    // 匹配路由地址\n    public static function getRuleUrl($rule, &$vars = [])\n    {\n        foreach ($rule as $item) {\n            list($url, $pattern, $domain, $suffix) = $item;\n            if (empty($pattern)) {\n                return [$url, $domain, $suffix];\n            }\n            foreach ($pattern as $key => $val) {\n                if (isset($vars[$key])) {\n                    $url = str_replace(['[:' . $key . ']', '<' . $key . '?>', ':' . $key . '', '<' . $key . '>'], $vars[$key], $url);\n                    unset($vars[$key]);\n                    $result = [$url, $domain, $suffix];\n                } elseif (2 == $val) {\n                    $url    = str_replace(['/[:' . $key . ']', '[:' . $key . ']', '<' . $key . '?>'], '', $url);\n                    $result = [$url, $domain, $suffix];\n                } else {\n                    break;\n                }\n            }\n            if (isset($result)) {\n                return $result;\n            }\n        }\n        return false;\n    }\n\n    // 指定当前生成URL地址的root\n    public static function root($root)\n    {\n        self::$root = $root;\n        Request::instance()->root($root);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/Validate.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nuse think\\exception\\ClassNotFoundException;\n\nclass Validate\n{\n    // 实例\n    protected static $instance;\n\n    // 自定义的验证类型\n    protected static $type = [];\n\n    // 验证类型别名\n    protected $alias = [\n        '>' => 'gt', '>=' => 'egt', '<' => 'lt', '<=' => 'elt', '=' => 'eq', 'same' => 'eq',\n    ];\n\n    // 当前验证的规则\n    protected $rule = [];\n\n    // 验证提示信息\n    protected $message = [];\n    // 验证字段描述\n    protected $field = [];\n\n    // 验证规则默认提示信息\n    protected static $typeMsg = [\n        'require'     => ':attribute不能为空',\n        'number'      => ':attribute必须是数字',\n        'float'       => ':attribute必须是浮点数',\n        'boolean'     => ':attribute必须是布尔值',\n        'email'       => ':attribute格式不符',\n        'array'       => ':attribute必须是数组',\n        'accepted'    => ':attribute必须是yes、on或者1',\n        'date'        => ':attribute格式不符合',\n        'file'        => ':attribute不是有效的上传文件',\n        'image'       => ':attribute不是有效的图像文件',\n        'alpha'       => ':attribute只能是字母',\n        'alphaNum'    => ':attribute只能是字母和数字',\n        'alphaDash'   => ':attribute只能是字母、数字和下划线_及破折号-',\n        'activeUrl'   => ':attribute不是有效的域名或者IP',\n        'chs'         => ':attribute只能是汉字',\n        'chsAlpha'    => ':attribute只能是汉字、字母',\n        'chsAlphaNum' => ':attribute只能是汉字、字母和数字',\n        'chsDash'     => ':attribute只能是汉字、字母、数字和下划线_及破折号-',\n        'url'         => ':attribute不是有效的URL地址',\n        'ip'          => ':attribute不是有效的IP地址',\n        'dateFormat'  => ':attribute必须使用日期格式 :rule',\n        'in'          => ':attribute必须在 :rule 范围内',\n        'notIn'       => ':attribute不能在 :rule 范围内',\n        'between'     => ':attribute只能在 :1 - :2 之间',\n        'notBetween'  => ':attribute不能在 :1 - :2 之间',\n        'length'      => ':attribute长度不符合要求 :rule',\n        'max'         => ':attribute长度不能超过 :rule',\n        'min'         => ':attribute长度不能小于 :rule',\n        'after'       => ':attribute日期不能小于 :rule',\n        'before'      => ':attribute日期不能超过 :rule',\n        'expire'      => '不在有效期内 :rule',\n        'allowIp'     => '不允许的IP访问',\n        'denyIp'      => '禁止的IP访问',\n        'confirm'     => ':attribute和确认字段:2不一致',\n        'different'   => ':attribute和比较字段:2不能相同',\n        'egt'         => ':attribute必须大于等于 :rule',\n        'gt'          => ':attribute必须大于 :rule',\n        'elt'         => ':attribute必须小于等于 :rule',\n        'lt'          => ':attribute必须小于 :rule',\n        'eq'          => ':attribute必须等于 :rule',\n        'unique'      => ':attribute已存在',\n        'regex'       => ':attribute不符合指定规则',\n        'method'      => '无效的请求类型',\n        'token'       => '令牌数据无效',\n        'fileSize'    => '上传文件大小不符',\n        'fileExt'     => '上传文件后缀不符',\n        'fileMime'    => '上传文件类型不符',\n\n    ];\n\n    // 当前验证场景\n    protected $currentScene = null;\n\n    // 正则表达式 regex = ['zip'=>'\\d{6}',...]\n    protected $regex = [];\n\n    // 验证场景 scene = ['edit'=>'name1,name2,...']\n    protected $scene = [];\n\n    // 验证失败错误信息\n    protected $error = [];\n\n    // 批量验证\n    protected $batch = false;\n\n    /**\n     * 构造函数\n     * @access public\n     * @param array $rules 验证规则\n     * @param array $message 验证提示信息\n     * @param array $field 验证字段描述信息\n     */\n    public function __construct(array $rules = [], $message = [], $field = [])\n    {\n        $this->rule    = array_merge($this->rule, $rules);\n        $this->message = array_merge($this->message, $message);\n        $this->field   = array_merge($this->field, $field);\n    }\n\n    /**\n     * 实例化验证\n     * @access public\n     * @param array     $rules 验证规则\n     * @param array     $message 验证提示信息\n     * @param array     $field 验证字段描述信息\n     * @return Validate\n     */\n    public static function make($rules = [], $message = [], $field = [])\n    {\n        if (is_null(self::$instance)) {\n            self::$instance = new self($rules, $message, $field);\n        }\n        return self::$instance;\n    }\n\n    /**\n     * 添加字段验证规则\n     * @access protected\n     * @param string|array  $name  字段名称或者规则数组\n     * @param mixed         $rule  验证规则\n     * @return Validate\n     */\n    public function rule($name, $rule = '')\n    {\n        if (is_array($name)) {\n            $this->rule = array_merge($this->rule, $name);\n        } else {\n            $this->rule[$name] = $rule;\n        }\n        return $this;\n    }\n\n    /**\n     * 注册验证（类型）规则\n     * @access public\n     * @param string    $type  验证规则类型\n     * @param mixed     $callback callback方法(或闭包)\n     * @return void\n     */\n    public static function extend($type, $callback = null)\n    {\n        if (is_array($type)) {\n            self::$type = array_merge(self::$type, $type);\n        } else {\n            self::$type[$type] = $callback;\n        }\n    }\n\n    /**\n     * 获取验证规则的默认提示信息\n     * @access protected\n     * @param string|array  $type  验证规则类型名称或者数组\n     * @param string        $msg  验证提示信息\n     * @return void\n     */\n    public static function setTypeMsg($type, $msg = null)\n    {\n        if (is_array($type)) {\n            self::$typeMsg = array_merge(self::$typeMsg, $type);\n        } else {\n            self::$typeMsg[$type] = $msg;\n        }\n    }\n\n    /**\n     * 设置提示信息\n     * @access public\n     * @param string|array  $name  字段名称\n     * @param string        $message 提示信息\n     * @return Validate\n     */\n    public function message($name, $message = '')\n    {\n        if (is_array($name)) {\n            $this->message = array_merge($this->message, $name);\n        } else {\n            $this->message[$name] = $message;\n        }\n        return $this;\n    }\n\n    /**\n     * 设置验证场景\n     * @access public\n     * @param string|array  $name  场景名或者场景设置数组\n     * @param mixed         $fields 要验证的字段\n     * @return Validate\n     */\n    public function scene($name, $fields = null)\n    {\n        if (is_array($name)) {\n            $this->scene = array_merge($this->scene, $name);\n        }if (is_null($fields)) {\n            // 设置当前场景\n            $this->currentScene = $name;\n        } else {\n            // 设置验证场景\n            $this->scene[$name] = $fields;\n        }\n        return $this;\n    }\n\n    /**\n     * 判断是否存在某个验证场景\n     * @access public\n     * @param string $name 场景名\n     * @return bool\n     */\n    public function hasScene($name)\n    {\n        return isset($this->scene[$name]);\n    }\n\n    /**\n     * 设置批量验证\n     * @access public\n     * @param bool $batch  是否批量验证\n     * @return Validate\n     */\n    public function batch($batch = true)\n    {\n        $this->batch = $batch;\n        return $this;\n    }\n\n    /**\n     * 数据自动验证\n     * @access public\n     * @param array     $data  数据\n     * @param mixed     $rules  验证规则\n     * @param string    $scene 验证场景\n     * @return bool\n     */\n    public function check($data, $rules = [], $scene = '')\n    {\n        $this->error = [];\n\n        if (empty($rules)) {\n            // 读取验证规则\n            $rules = $this->rule;\n        }\n\n        // 分析验证规则\n        $scene = $this->getScene($scene);\n        if (is_array($scene)) {\n            // 处理场景验证字段\n            $change = [];\n            $array  = [];\n            foreach ($scene as $k => $val) {\n                if (is_numeric($k)) {\n                    $array[] = $val;\n                } else {\n                    $array[]    = $k;\n                    $change[$k] = $val;\n                }\n            }\n        }\n\n        foreach ($rules as $key => $item) {\n            // field => rule1|rule2... field=>['rule1','rule2',...]\n            if (is_numeric($key)) {\n                // [field,rule1|rule2,msg1|msg2]\n                $key  = $item[0];\n                $rule = $item[1];\n                if (isset($item[2])) {\n                    $msg = is_string($item[2]) ? explode('|', $item[2]) : $item[2];\n                } else {\n                    $msg = [];\n                }\n            } else {\n                $rule = $item;\n                $msg  = [];\n            }\n            if (strpos($key, '|')) {\n                // 字段|描述 用于指定属性名称\n                list($key, $title) = explode('|', $key);\n            } else {\n                $title = isset($this->field[$key]) ? $this->field[$key] : $key;\n            }\n\n            // 场景检测\n            if (!empty($scene)) {\n                if ($scene instanceof \\Closure && !call_user_func_array($scene, [$key, $data])) {\n                    continue;\n                } elseif (is_array($scene)) {\n                    if (!in_array($key, $array)) {\n                        continue;\n                    } elseif (isset($change[$key])) {\n                        // 重载某个验证规则\n                        $rule = $change[$key];\n                    }\n                }\n            }\n\n            // 获取数据 支持二维数组\n            $value = $this->getDataValue($data, $key);\n\n            // 字段验证\n            if ($rule instanceof \\Closure) {\n                // 匿名函数验证 支持传入当前字段和所有字段两个数据\n                $result = call_user_func_array($rule, [$value, $data]);\n            } else {\n                $result = $this->checkItem($key, $value, $rule, $data, $title, $msg);\n            }\n\n            if (true !== $result) {\n                // 没有返回true 则表示验证失败\n                if (!empty($this->batch)) {\n                    // 批量验证\n                    if (is_array($result)) {\n                        $this->error = array_merge($this->error, $result);\n                    } else {\n                        $this->error[$key] = $result;\n                    }\n                } else {\n                    $this->error = $result;\n                    return false;\n                }\n            }\n        }\n        return !empty($this->error) ? false : true;\n    }\n\n    /**\n     * 验证单个字段规则\n     * @access protected\n     * @param string    $field  字段名\n     * @param mixed     $value  字段值\n     * @param mixed     $rules  验证规则\n     * @param array     $data  数据\n     * @param string    $title  字段描述\n     * @param array     $msg  提示信息\n     * @return mixed\n     */\n    protected function checkItem($field, $value, $rules, $data, $title = '', $msg = [])\n    {\n        // 支持多规则验证 require|in:a,b,c|... 或者 ['require','in'=>'a,b,c',...]\n        if (is_string($rules)) {\n            $rules = explode('|', $rules);\n        }\n        $i = 0;\n        foreach ($rules as $key => $rule) {\n            if ($rule instanceof \\Closure) {\n                $result = call_user_func_array($rule, [$value, $data]);\n                $info   = is_numeric($key) ? '' : $key;\n            } else {\n                // 判断验证类型\n                if (is_numeric($key)) {\n                    if (strpos($rule, ':')) {\n                        list($type, $rule) = explode(':', $rule, 2);\n                        if (isset($this->alias[$type])) {\n                            // 判断别名\n                            $type = $this->alias[$type];\n                        }\n                        $info = $type;\n                    } elseif (method_exists($this, $rule)) {\n                        $type = $rule;\n                        $info = $rule;\n                        $rule = '';\n                    } else {\n                        $type = 'is';\n                        $info = $rule;\n                    }\n                } else {\n                    $info = $type = $key;\n                }\n\n                // 如果不是require 有数据才会行验证\n                if (0 === strpos($info, 'require') || (!is_null($value) && '' !== $value)) {\n                    // 验证类型\n                    $callback = isset(self::$type[$type]) ? self::$type[$type] : [$this, $type];\n                    // 验证数据\n                    $result = call_user_func_array($callback, [$value, $rule, $data, $field, $title]);\n                } else {\n                    $result = true;\n                }\n            }\n\n            if (false === $result) {\n                // 验证失败 返回错误信息\n                if (isset($msg[$i])) {\n                    $message = $msg[$i];\n                    if (is_string($message) && strpos($message, '{%') === 0) {\n                        $message = Lang::get(substr($message, 2, -1));\n                    }\n                } else {\n                    $message = $this->getRuleMsg($field, $title, $info, $rule);\n                }\n                return $message;\n            } elseif (true !== $result) {\n                // 返回自定义错误信息\n                if (is_string($result) && false !== strpos($result, ':')) {\n                    $result = str_replace([':attribute', ':rule'], [$title, (string) $rule], $result);\n                }\n                return $result;\n            }\n            $i++;\n        }\n        return $result;\n    }\n\n    /**\n     * 验证是否和某个字段的值一致\n     * @access protected\n     * @param mixed     $value 字段值\n     * @param mixed     $rule  验证规则\n     * @param array     $data  数据\n     * @param string    $field 字段名\n     * @return bool\n     */\n    protected function confirm($value, $rule, $data, $field = '')\n    {\n        if ('' == $rule) {\n            if (strpos($field, '_confirm')) {\n                $rule = strstr($field, '_confirm', true);\n            } else {\n                $rule = $field . '_confirm';\n            }\n        }\n        return $this->getDataValue($data, $rule) === $value;\n    }\n\n    /**\n     * 验证是否和某个字段的值是否不同\n     * @access protected\n     * @param mixed $value 字段值\n     * @param mixed $rule  验证规则\n     * @param array $data  数据\n     * @return bool\n     */\n    protected function different($value, $rule, $data)\n    {\n        return $this->getDataValue($data, $rule) != $value;\n    }\n\n    /**\n     * 验证是否大于等于某个值\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @param array     $data  数据\n     * @return bool\n     */\n    protected function egt($value, $rule, $data)\n    {\n        $val = $this->getDataValue($data, $rule);\n        return !is_null($val) && $value >= $val;\n    }\n\n    /**\n     * 验证是否大于某个值\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @param array     $data  数据\n     * @return bool\n     */\n    protected function gt($value, $rule, $data)\n    {\n        $val = $this->getDataValue($data, $rule);\n        return !is_null($val) && $value > $val;\n    }\n\n    /**\n     * 验证是否小于等于某个值\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @param array     $data  数据\n     * @return bool\n     */\n    protected function elt($value, $rule, $data)\n    {\n        $val = $this->getDataValue($data, $rule);\n        return !is_null($val) && $value <= $val;\n    }\n\n    /**\n     * 验证是否小于某个值\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @param array     $data  数据\n     * @return bool\n     */\n    protected function lt($value, $rule, $data)\n    {\n        $val = $this->getDataValue($data, $rule);\n        return !is_null($val) && $value < $val;\n    }\n\n    /**\n     * 验证是否等于某个值\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function eq($value, $rule)\n    {\n        return $value == $rule;\n    }\n\n    /**\n     * 验证字段值是否为有效格式\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param string    $rule  验证规则\n     * @param array     $data  验证数据\n     * @return bool\n     */\n    protected function is($value, $rule, $data = [])\n    {\n        switch ($rule) {\n            case 'require':\n                // 必须\n                $result = !empty($value) || '0' == $value;\n                break;\n            case 'accepted':\n                // 接受\n                $result = in_array($value, ['1', 'on', 'yes']);\n                break;\n            case 'date':\n                // 是否是一个有效日期\n                $result = false !== strtotime($value);\n                break;\n            case 'alpha':\n                // 只允许字母\n                $result = $this->regex($value, '/^[A-Za-z]+$/');\n                break;\n            case 'alphaNum':\n                // 只允许字母和数字\n                $result = $this->regex($value, '/^[A-Za-z0-9]+$/');\n                break;\n            case 'alphaDash':\n                // 只允许字母、数字和下划线 破折号\n                $result = $this->regex($value, '/^[A-Za-z0-9\\-\\_]+$/');\n                break;\n            case 'chs':\n                // 只允许汉字\n                $result = $this->regex($value, '/^[\\x{4e00}-\\x{9fa5}]+$/u');\n                break;\n            case 'chsAlpha':\n                // 只允许汉字、字母\n                $result = $this->regex($value, '/^[\\x{4e00}-\\x{9fa5}a-zA-Z]+$/u');\n                break;\n            case 'chsAlphaNum':\n                // 只允许汉字、字母和数字\n                $result = $this->regex($value, '/^[\\x{4e00}-\\x{9fa5}a-zA-Z0-9]+$/u');\n                break;\n            case 'chsDash':\n                // 只允许汉字、字母、数字和下划线_及破折号-\n                $result = $this->regex($value, '/^[\\x{4e00}-\\x{9fa5}a-zA-Z0-9\\_\\-]+$/u');\n                break;\n            case 'activeUrl':\n                // 是否为有效的网址\n                $result = checkdnsrr($value);\n                break;\n            case 'ip':\n                // 是否为IP地址\n                $result = $this->filter($value, [FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_IPV6]);\n                break;\n            case 'url':\n                // 是否为一个URL地址\n                $result = $this->filter($value, FILTER_VALIDATE_URL);\n                break;\n            case 'float':\n                // 是否为float\n                $result = $this->filter($value, FILTER_VALIDATE_FLOAT);\n                break;\n            case 'number':\n                $result = is_numeric($value);\n                break;\n            case 'integer':\n                // 是否为整型\n                $result = $this->filter($value, FILTER_VALIDATE_INT);\n                break;\n            case 'email':\n                // 是否为邮箱地址\n                $result = $this->filter($value, FILTER_VALIDATE_EMAIL);\n                break;\n            case 'boolean':\n                // 是否为布尔值\n                $result = in_array($value, [true, false, 0, 1, '0', '1'], true);\n                break;\n            case 'array':\n                // 是否为数组\n                $result = is_array($value);\n                break;\n            case 'file':\n                $result = $value instanceof File;\n                break;\n            case 'image':\n                $result = $value instanceof File && in_array($this->getImageType($value->getRealPath()), [1, 2, 3, 6]);\n                break;\n            case 'token':\n                $result = $this->token($value, '__token__', $data);\n                break;\n            default:\n                if (isset(self::$type[$rule])) {\n                    // 注册的验证规则\n                    $result = call_user_func_array(self::$type[$rule], [$value]);\n                } else {\n                    // 正则验证\n                    $result = $this->regex($value, $rule);\n                }\n        }\n        return $result;\n    }\n\n    // 判断图像类型\n    protected function getImageType($image)\n    {\n        if (function_exists('exif_imagetype')) {\n            return exif_imagetype($image);\n        } else {\n            $info = getimagesize($image);\n            return $info[2];\n        }\n    }\n\n    /**\n     * 验证是否为合格的域名或者IP 支持A，MX，NS，SOA，PTR，CNAME，AAAA，A6， SRV，NAPTR，TXT 或者 ANY类型\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function activeUrl($value, $rule)\n    {\n        if (!in_array($rule, ['A', 'MX', 'NS', 'SOA', 'PTR', 'CNAME', 'AAAA', 'A6', 'SRV', 'NAPTR', 'TXT', 'ANY'])) {\n            $rule = 'MX';\n        }\n        return checkdnsrr($value, $rule);\n    }\n\n    /**\n     * 验证是否有效IP\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则 ipv4 ipv6\n     * @return bool\n     */\n    protected function ip($value, $rule)\n    {\n        if (!in_array($rule, ['ipv4', 'ipv6'])) {\n            $rule = 'ipv4';\n        }\n        return $this->filter($value, [FILTER_VALIDATE_IP, 'ipv6' == $rule ? FILTER_FLAG_IPV6 : FILTER_FLAG_IPV4]);\n    }\n\n    /**\n     * 验证上传文件后缀\n     * @access protected\n     * @param mixed     $file  上传文件\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function fileExt($file, $rule)\n    {\n        if (!($file instanceof File)) {\n            return false;\n        }\n        if (is_string($rule)) {\n            $rule = explode(',', $rule);\n        }\n        if (is_array($file)) {\n            foreach ($file as $item) {\n                if (!$item->checkExt($rule)) {\n                    return false;\n                }\n            }\n            return true;\n        } else {\n            return $file->checkExt($rule);\n        }\n    }\n\n    /**\n     * 验证上传文件类型\n     * @access protected\n     * @param mixed     $file  上传文件\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function fileMime($file, $rule)\n    {\n        if (!($file instanceof File)) {\n            return false;\n        }\n        if (is_string($rule)) {\n            $rule = explode(',', $rule);\n        }\n        if (is_array($file)) {\n            foreach ($file as $item) {\n                if (!$item->checkMime($rule)) {\n                    return false;\n                }\n            }\n            return true;\n        } else {\n            return $file->checkMime($rule);\n        }\n    }\n\n    /**\n     * 验证上传文件大小\n     * @access protected\n     * @param mixed     $file  上传文件\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function fileSize($file, $rule)\n    {\n        if (!($file instanceof File)) {\n            return false;\n        }\n        if (is_array($file)) {\n            foreach ($file as $item) {\n                if (!$item->checkSize($rule)) {\n                    return false;\n                }\n            }\n            return true;\n        } else {\n            return $file->checkSize($rule);\n        }\n    }\n\n    /**\n     * 验证图片的宽高及类型\n     * @access protected\n     * @param mixed     $file  上传文件\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function image($file, $rule)\n    {\n        if (!($file instanceof File)) {\n            return false;\n        }\n        if ($rule) {\n            $rule                        = explode(',', $rule);\n            list($width, $height, $type) = getimagesize($file->getRealPath());\n            if (isset($rule[2])) {\n                $imageType = strtolower($rule[2]);\n                if ('jpeg' == $imageType) {\n                    $imageType = 'jpg';\n                }\n                if (image_type_to_extension($type, false) != $imageType) {\n                    return false;\n                }\n            }\n\n            list($w, $h) = $rule;\n            return $w == $width && $h == $height;\n        } else {\n            return in_array($this->getImageType($file->getRealPath()), [1, 2, 3, 6]);\n        }\n    }\n\n    /**\n     * 验证请求类型\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function method($value, $rule)\n    {\n        $method = Request::instance()->method();\n        return strtoupper($rule) == $method;\n    }\n\n    /**\n     * 验证时间和日期是否符合指定格式\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function dateFormat($value, $rule)\n    {\n        $info = date_parse_from_format($rule, $value);\n        return 0 == $info['warning_count'] && 0 == $info['error_count'];\n    }\n\n    /**\n     * 验证是否唯一\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则 格式：数据表,字段名,排除ID,主键名\n     * @param array     $data  数据\n     * @param string    $field  验证字段名\n     * @return bool\n     */\n    protected function unique($value, $rule, $data, $field)\n    {\n        if (is_string($rule)) {\n            $rule = explode(',', $rule);\n        }\n        if (false !== strpos($rule[0], '\\\\')) {\n            // 指定模型类\n            $db = new $rule[0];\n        } else {\n            try {\n                $db = Loader::model($rule[0]);\n            } catch (ClassNotFoundException $e) {\n                $db = Db::name($rule[0]);\n            }\n        }\n        $key = isset($rule[1]) ? $rule[1] : $field;\n\n        if (strpos($key, '^')) {\n            // 支持多个字段验证\n            $fields = explode('^', $key);\n            foreach ($fields as $key) {\n                $map[$key] = $data[$key];\n            }\n        } elseif (strpos($key, '=')) {\n            parse_str($key, $map);\n        } else {\n            $map[$key] = $data[$field];\n        }\n\n        $pk = strval(isset($rule[3]) ? $rule[3] : $db->getPk());\n        if (isset($rule[2])) {\n            $map[$pk] = ['neq', $rule[2]];\n        } elseif (isset($data[$pk])) {\n            $map[$pk] = ['neq', $data[$pk]];\n        }\n\n        if ($db->where($map)->field($pk)->find()) {\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * 使用行为类验证\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @param array     $data  数据\n     * @return mixed\n     */\n    protected function behavior($value, $rule, $data)\n    {\n        return Hook::exec($rule, '', $data);\n    }\n\n    /**\n     * 使用filter_var方式验证\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function filter($value, $rule)\n    {\n        if (is_string($rule) && strpos($rule, ',')) {\n            list($rule, $param) = explode(',', $rule);\n        } elseif (is_array($rule)) {\n            $param = isset($rule[1]) ? $rule[1] : null;\n            $rule  = $rule[0];\n        } else {\n            $param = null;\n        }\n        return false !== filter_var($value, is_int($rule) ? $rule : filter_id($rule), $param);\n    }\n\n    /**\n     * 验证某个字段等于某个值的时候必须\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @param array     $data  数据\n     * @return bool\n     */\n    protected function requireIf($value, $rule, $data)\n    {\n        list($field, $val) = explode(',', $rule);\n        if ($this->getDataValue($data, $field) == $val) {\n            return !empty($value);\n        } else {\n            return true;\n        }\n    }\n\n    /**\n     * 通过回调方法验证某个字段是否必须\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @param array     $data  数据\n     * @return bool\n     */\n    protected function requireCallback($value, $rule, $data)\n    {\n        $result = call_user_func_array($rule, [$value, $data]);\n        if ($result) {\n            return !empty($value);\n        } else {\n            return true;\n        }\n    }\n\n    /**\n     * 验证某个字段有值的情况下必须\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @param array     $data  数据\n     * @return bool\n     */\n    protected function requireWith($value, $rule, $data)\n    {\n        $val = $this->getDataValue($data, $rule);\n        if (!empty($val)) {\n            return !empty($value);\n        } else {\n            return true;\n        }\n    }\n\n    /**\n     * 验证是否在范围内\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function in($value, $rule)\n    {\n        return in_array($value, is_array($rule) ? $rule : explode(',', $rule));\n    }\n\n    /**\n     * 验证是否不在某个范围\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function notIn($value, $rule)\n    {\n        return !in_array($value, is_array($rule) ? $rule : explode(',', $rule));\n    }\n\n    /**\n     * between验证数据\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function between($value, $rule)\n    {\n        if (is_string($rule)) {\n            $rule = explode(',', $rule);\n        }\n        list($min, $max) = $rule;\n        return $value >= $min && $value <= $max;\n    }\n\n    /**\n     * 使用notbetween验证数据\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function notBetween($value, $rule)\n    {\n        if (is_string($rule)) {\n            $rule = explode(',', $rule);\n        }\n        list($min, $max) = $rule;\n        return $value < $min || $value > $max;\n    }\n\n    /**\n     * 验证数据长度\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function length($value, $rule)\n    {\n        if (is_array($value)) {\n            $length = count($value);\n        } elseif ($value instanceof File) {\n            $length = $value->getSize();\n        } else {\n            $length = mb_strlen((string) $value);\n        }\n\n        if (strpos($rule, ',')) {\n            // 长度区间\n            list($min, $max) = explode(',', $rule);\n            return $length >= $min && $length <= $max;\n        } else {\n            // 指定长度\n            return $length == $rule;\n        }\n    }\n\n    /**\n     * 验证数据最大长度\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function max($value, $rule)\n    {\n        if (is_array($value)) {\n            $length = count($value);\n        } elseif ($value instanceof File) {\n            $length = $value->getSize();\n        } else {\n            $length = mb_strlen((string) $value);\n        }\n        return $length <= $rule;\n    }\n\n    /**\n     * 验证数据最小长度\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function min($value, $rule)\n    {\n        if (is_array($value)) {\n            $length = count($value);\n        } elseif ($value instanceof File) {\n            $length = $value->getSize();\n        } else {\n            $length = mb_strlen((string) $value);\n        }\n        return $length >= $rule;\n    }\n\n    /**\n     * 验证日期\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function after($value, $rule)\n    {\n        return strtotime($value) >= strtotime($rule);\n    }\n\n    /**\n     * 验证日期\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function before($value, $rule)\n    {\n        return strtotime($value) <= strtotime($rule);\n    }\n\n    /**\n     * 验证有效期\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return bool\n     */\n    protected function expire($value, $rule)\n    {\n        if (is_string($rule)) {\n            $rule = explode(',', $rule);\n        }\n        list($start, $end) = $rule;\n        if (!is_numeric($start)) {\n            $start = strtotime($start);\n        }\n\n        if (!is_numeric($end)) {\n            $end = strtotime($end);\n        }\n        return $_SERVER['REQUEST_TIME'] >= $start && $_SERVER['REQUEST_TIME'] <= $end;\n    }\n\n    /**\n     * 验证IP许可\n     * @access protected\n     * @param string    $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return mixed\n     */\n    protected function allowIp($value, $rule)\n    {\n        return in_array($_SERVER['REMOTE_ADDR'], is_array($rule) ? $rule : explode(',', $rule));\n    }\n\n    /**\n     * 验证IP禁用\n     * @access protected\n     * @param string    $value  字段值\n     * @param mixed     $rule  验证规则\n     * @return mixed\n     */\n    protected function denyIp($value, $rule)\n    {\n        return !in_array($_SERVER['REMOTE_ADDR'], is_array($rule) ? $rule : explode(',', $rule));\n    }\n\n    /**\n     * 使用正则验证数据\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则 正则规则或者预定义正则名\n     * @return mixed\n     */\n    protected function regex($value, $rule)\n    {\n        if (isset($this->regex[$rule])) {\n            $rule = $this->regex[$rule];\n        }\n        if (0 !== strpos($rule, '/') && !preg_match('/\\/[imsU]{0,4}$/', $rule)) {\n            // 不是正则表达式则两端补上/\n            $rule = '/^' . $rule . '$/';\n        }\n        return 1 === preg_match($rule, (string) $value);\n    }\n\n    /**\n     * 验证表单令牌\n     * @access protected\n     * @param mixed     $value  字段值\n     * @param mixed     $rule  验证规则\n     * @param array     $data  数据\n     * @return bool\n     */\n    protected function token($value, $rule, $data)\n    {\n        $rule = !empty($rule) ? $rule : '__token__';\n        if (!isset($data[$rule]) || !Session::has($rule)) {\n            // 令牌数据无效\n            return false;\n        }\n\n        // 令牌验证\n        if (isset($data[$rule]) && Session::get($rule) === $data[$rule]) {\n            // 防止重复提交\n            Session::delete($rule); // 验证完成销毁session\n            return true;\n        }\n        // 开启TOKEN重置\n        Session::delete($rule);\n        return false;\n    }\n\n    // 获取错误信息\n    public function getError()\n    {\n        return $this->error;\n    }\n\n    /**\n     * 获取数据值\n     * @access protected\n     * @param array $data 数据\n     * @param string $key 数据标识 支持二维\n     * @return mixed\n     */\n    protected function getDataValue($data, $key)\n    {\n        if (is_numeric($key)) {\n            $value = $key;\n        } elseif (strpos($key, '.')) {\n            // 支持二维数组验证\n            list($name1, $name2) = explode('.', $key);\n            $value               = isset($data[$name1][$name2]) ? $data[$name1][$name2] : null;\n        } else {\n            $value = isset($data[$key]) ? $data[$key] : null;\n        }\n        return $value;\n    }\n\n    /**\n     * 获取验证规则的错误提示信息\n     * @access protected\n     * @param string    $attribute  字段英文名\n     * @param string    $title  字段描述名\n     * @param string    $type  验证规则名称\n     * @param mixed     $rule  验证规则数据\n     * @return string\n     */\n    protected function getRuleMsg($attribute, $title, $type, $rule)\n    {\n        if (isset($this->message[$attribute . '.' . $type])) {\n            $msg = $this->message[$attribute . '.' . $type];\n        } elseif (isset($this->message[$attribute][$type])) {\n            $msg = $this->message[$attribute][$type];\n        } elseif (isset($this->message[$attribute])) {\n            $msg = $this->message[$attribute];\n        } elseif (isset(self::$typeMsg[$type])) {\n            $msg = self::$typeMsg[$type];\n        } else {\n            $msg = $title . '规则错误';\n        }\n\n        if (is_string($msg) && 0 === strpos($msg, '{%')) {\n            $msg = Lang::get(substr($msg, 2, -1));\n        }\n\n        if (is_string($msg) && is_scalar($rule) && false !== strpos($msg, ':')) {\n            // 变量替换\n            if (is_string($rule) && strpos($rule, ',')) {\n                $array = array_pad(explode(',', $rule), 3, '');\n            } else {\n                $array = array_pad([], 3, '');\n            }\n            $msg = str_replace(\n                [':attribute', ':rule', ':1', ':2', ':3'],\n                [$title, (string) $rule, $array[0], $array[1], $array[2]],\n                $msg);\n        }\n        return $msg;\n    }\n\n    /**\n     * 获取数据验证的场景\n     * @access protected\n     * @param string $scene  验证场景\n     * @return array\n     */\n    protected function getScene($scene = '')\n    {\n        if (empty($scene)) {\n            // 读取指定场景\n            $scene = $this->currentScene;\n        }\n\n        if (!empty($scene) && isset($this->scene[$scene])) {\n            // 如果设置了验证适用场景\n            $scene = $this->scene[$scene];\n            if (is_string($scene)) {\n                $scene = explode(',', $scene);\n            }\n        } else {\n            $scene = [];\n        }\n        return $scene;\n    }\n\n    public static function __callStatic($method, $params)\n    {\n        $class = self::make();\n        if (method_exists($class, $method)) {\n            return call_user_func_array([$class, $method], $params);\n        } else {\n            throw new \\BadMethodCallException('method not exists:' . __CLASS__ . '->' . $method);\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/View.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\nclass View\n{\n    // 视图实例\n    protected static $instance;\n    // 模板引擎实例\n    public $engine;\n    // 模板变量\n    protected $data = [];\n    // 用于静态赋值的模板变量\n    protected static $var = [];\n    // 视图输出替换\n    protected $replace = [];\n\n    /**\n     * 构造函数\n     * @access public\n     * @param array $engine  模板引擎参数\n     * @param array $replace  字符串替换参数\n     */\n    public function __construct($engine = [], $replace = [])\n    {\n        // 初始化模板引擎\n        $this->engine((array) $engine);\n        // 基础替换字符串\n        $request = Request::instance();\n        $base    = $request->root();\n        $root    = strpos($base, '.') ? ltrim(dirname($base), DS) : $base;\n        if ('' != $root) {\n            $root = '/' . ltrim($root, '/');\n        }\n        $baseReplace = [\n            '__ROOT__'   => $root,\n            '__URL__'    => $base . '/' . $request->module() . '/' . Loader::parseName($request->controller()),\n            '__STATIC__' => $root . '/static',\n            '__CSS__'    => $root . '/static/css',\n            '__JS__'     => $root . '/static/js',\n        ];\n        $this->replace = array_merge($baseReplace, (array) $replace);\n    }\n\n    /**\n     * 初始化视图\n     * @access public\n     * @param array $engine  模板引擎参数\n     * @param array $replace  字符串替换参数\n     * @return object\n     */\n    public static function instance($engine = [], $replace = [])\n    {\n        if (is_null(self::$instance)) {\n            self::$instance = new self($engine, $replace);\n        }\n        return self::$instance;\n    }\n\n    /**\n     * 模板变量静态赋值\n     * @access public\n     * @param mixed $name  变量名\n     * @param mixed $value 变量值\n     * @return void\n     */\n    public static function share($name, $value = '')\n    {\n        if (is_array($name)) {\n            self::$var = array_merge(self::$var, $name);\n        } else {\n            self::$var[$name] = $value;\n        }\n    }\n\n    /**\n     * 模板变量赋值\n     * @access public\n     * @param mixed $name  变量名\n     * @param mixed $value 变量值\n     * @return $this\n     */\n    public function assign($name, $value = '')\n    {\n        if (is_array($name)) {\n            $this->data = array_merge($this->data, $name);\n        } else {\n            $this->data[$name] = $value;\n        }\n        return $this;\n    }\n\n    /**\n     * 设置当前模板解析的引擎\n     * @access public\n     * @param array|string $options 引擎参数\n     * @return $this\n     */\n    public function engine($options = [])\n    {\n        if (is_string($options)) {\n            $type    = $options;\n            $options = [];\n        } else {\n            $type = !empty($options['type']) ? $options['type'] : 'Think';\n        }\n\n        $class = false !== strpos($type, '\\\\') ? $type : '\\\\think\\\\view\\\\driver\\\\' . ucfirst($type);\n        if (isset($options['type'])) {\n            unset($options['type']);\n        }\n        $this->engine = new $class($options);\n        return $this;\n    }\n\n    /**\n     * 配置模板引擎\n     * @access private\n     * @param string|array  $name 参数名\n     * @param mixed         $value 参数值\n     * @return void\n     */\n    public function config($name, $value = null)\n    {\n        $this->engine->config($name, $value);\n        return $this;\n    }\n\n    /**\n     * 解析和获取模板内容 用于输出\n     * @param string    $template 模板文件名或者内容\n     * @param array     $vars     模板输出变量\n     * @param array     $replace 替换内容\n     * @param array     $config     模板参数\n     * @param bool      $renderContent     是否渲染内容\n     * @return string\n     * @throws Exception\n     */\n    public function fetch($template = '', $vars = [], $replace = [], $config = [], $renderContent = false)\n    {\n        // 模板变量\n        $vars = array_merge(self::$var, $this->data, $vars);\n\n        // 页面缓存\n        ob_start();\n        ob_implicit_flush(0);\n\n        // 渲染输出\n        $method = $renderContent ? 'display' : 'fetch';\n        $this->engine->$method($template, $vars, $config);\n\n        // 获取并清空缓存\n        $content = ob_get_clean();\n        // 内容过滤标签\n        Hook::listen('view_filter', $content);\n        // 允许用户自定义模板的字符串替换\n        $replace = array_merge($this->replace, $replace);\n        if (!empty($replace)) {\n            $content = strtr($content, $replace);\n        }\n        return $content;\n    }\n\n    /**\n     * 视图内容替换\n     * @access public\n     * @param string|array  $content 被替换内容（支持批量替换）\n     * @param string        $replace    替换内容\n     * @return $this\n     */\n    public function replace($content, $replace = '')\n    {\n        if (is_array($content)) {\n            $this->replace = array_merge($this->replace, $content);\n        } else {\n            $this->replace[$content] = $replace;\n        }\n        return $this;\n    }\n\n    /**\n     * 渲染内容输出\n     * @access public\n     * @param string $content 内容\n     * @param array  $vars    模板输出变量\n     * @param array  $replace 替换内容\n     * @param array  $config     模板参数\n     * @return mixed\n     */\n    public function display($content, $vars = [], $replace = [], $config = [])\n    {\n        return $this->fetch($content, $vars, $replace, $config, true);\n    }\n\n    /**\n     * 模板变量赋值\n     * @access public\n     * @param string    $name  变量名\n     * @param mixed     $value 变量值\n     */\n    public function __set($name, $value)\n    {\n        $this->data[$name] = $value;\n    }\n\n    /**\n     * 取得模板显示变量的值\n     * @access protected\n     * @param string $name 模板变量\n     * @return mixed\n     */\n    public function __get($name)\n    {\n        return $this->data[$name];\n    }\n\n    /**\n     * 检测模板变量是否设置\n     * @access public\n     * @param string $name 模板变量名\n     * @return bool\n     */\n    public function __isset($name)\n    {\n        return isset($this->data[$name]);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/cache/Driver.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\cache;\n\n/**\n * 缓存基础类\n */\nabstract class Driver\n{\n    protected $handler = null;\n    protected $options = [];\n    protected $tag;\n\n    /**\n     * 判断缓存是否存在\n     * @access public\n     * @param string $name 缓存变量名\n     * @return bool\n     */\n    abstract public function has($name);\n\n    /**\n     * 读取缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @param mixed  $default 默认值\n     * @return mixed\n     */\n    abstract public function get($name, $default = false);\n\n    /**\n     * 写入缓存\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param mixed     $value  存储数据\n     * @param int       $expire  有效时间 0为永久\n     * @return boolean\n     */\n    abstract public function set($name, $value, $expire = null);\n\n    /**\n     * 自增缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    abstract public function inc($name, $step = 1);\n\n    /**\n     * 自减缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    abstract public function dec($name, $step = 1);\n\n    /**\n     * 删除缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @return boolean\n     */\n    abstract public function rm($name);\n\n    /**\n     * 清除缓存\n     * @access public\n     * @param string $tag 标签名\n     * @return boolean\n     */\n    abstract public function clear($tag = null);\n\n    /**\n     * 获取实际的缓存标识\n     * @access public\n     * @param string $name 缓存名\n     * @return string\n     */\n    protected function getCacheKey($name)\n    {\n        return $this->options['prefix'] . $name;\n    }\n\n    /**\n     * 读取缓存并删除\n     * @access public\n     * @param string $name 缓存变量名\n     * @return mixed\n     */\n    public function pull($name)\n    {\n        $result = $this->get($name, false);\n        if ($result) {\n            $this->rm($name);\n            return $result;\n        } else {\n            return;\n        }\n    }\n\n    /**\n     * 如果不存在则写入缓存\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param mixed     $value  存储数据\n     * @param int       $expire  有效时间 0为永久\n     * @return mixed\n     */\n    public function remember($name, $value, $expire = null)\n    {\n        if (!$this->has($name)) {\n            if ($value instanceof \\Closure) {\n                $value = call_user_func($value);\n            }\n            $this->set($name, $value, $expire);\n        } else {\n            $value = $this->get($name);\n        }\n        return $value;\n    }\n\n    /**\n     * 缓存标签\n     * @access public\n     * @param string        $name 标签名\n     * @param string|array  $keys 缓存标识\n     * @param bool          $overlay 是否覆盖\n     * @return $this\n     */\n    public function tag($name, $keys = null, $overlay = false)\n    {\n        if (is_null($keys)) {\n            $this->tag = $name;\n        } else {\n            $key = 'tag_' . md5($name);\n            if (is_string($keys)) {\n                $keys = explode(',', $keys);\n            }\n            $keys = array_map([$this, 'getCacheKey'], $keys);\n            if ($overlay) {\n                $value = $keys;\n            } else {\n                $value = array_unique(array_merge($this->getTagItem($name), $keys));\n            }\n            $this->set($key, implode(',', $value));\n        }\n        return $this;\n    }\n\n    /**\n     * 更新标签\n     * @access public\n     * @param string $name 缓存标识\n     * @return void\n     */\n    protected function setTagItem($name)\n    {\n        if ($this->tag) {\n            $key       = 'tag_' . md5($this->tag);\n            $this->tag = null;\n            if ($this->has($key)) {\n                $value = $this->get($key);\n                $value .= ',' . $name;\n            } else {\n                $value = $name;\n            }\n            $this->set($key, $value);\n        }\n    }\n\n    /**\n     * 获取标签包含的缓存标识\n     * @access public\n     * @param string $tag 缓存标签\n     * @return array\n     */\n    protected function getTagItem($tag)\n    {\n        $key   = 'tag_' . md5($tag);\n        $value = $this->get($key);\n        if ($value) {\n            return explode(',', $value);\n        } else {\n            return [];\n        }\n    }\n\n    /**\n     * 返回句柄对象，可执行其它高级方法\n     *\n     * @access public\n     * @return object\n     */\n    public function handler()\n    {\n        return $this->handler;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/cache/driver/File.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\cache\\driver;\n\nuse think\\cache\\Driver;\n\n/**\n * 文件类型缓存类\n * @author    liu21st <liu21st@gmail.com>\n */\nclass File extends Driver\n{\n    protected $options = [\n        'expire'        => 0,\n        'cache_subdir'  => true,\n        'prefix'        => '',\n        'path'          => CACHE_PATH,\n        'data_compress' => false,\n    ];\n\n    /**\n     * 构造函数\n     * @param array $options\n     */\n    public function __construct($options = [])\n    {\n        if (!empty($options)) {\n            $this->options = array_merge($this->options, $options);\n        }\n        if (substr($this->options['path'], -1) != DS) {\n            $this->options['path'] .= DS;\n        }\n        $this->init();\n    }\n\n    /**\n     * 初始化检查\n     * @access private\n     * @return boolean\n     */\n    private function init()\n    {\n        // 创建项目缓存目录\n        if (!is_dir($this->options['path'])) {\n            if (mkdir($this->options['path'], 0755, true)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * 取得变量的存储文件名\n     * @access protected\n     * @param string $name 缓存变量名\n     * @return string\n     */\n    protected function getCacheKey($name)\n    {\n        $name = md5($name);\n        if ($this->options['cache_subdir']) {\n            // 使用子目录\n            $name = substr($name, 0, 2) . DS . substr($name, 2);\n        }\n        if ($this->options['prefix']) {\n            $name = $this->options['prefix'] . DS . $name;\n        }\n        $filename = $this->options['path'] . $name . '.php';\n        $dir      = dirname($filename);\n        if (!is_dir($dir)) {\n            mkdir($dir, 0755, true);\n        }\n        return $filename;\n    }\n\n    /**\n     * 判断缓存是否存在\n     * @access public\n     * @param string $name 缓存变量名\n     * @return bool\n     */\n    public function has($name)\n    {\n        return $this->get($name) ? true : false;\n    }\n\n    /**\n     * 读取缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @param mixed  $default 默认值\n     * @return mixed\n     */\n    public function get($name, $default = false)\n    {\n        $filename = $this->getCacheKey($name);\n        if (!is_file($filename)) {\n            return $default;\n        }\n        $content = file_get_contents($filename);\n        if (false !== $content) {\n            $expire = (int) substr($content, 8, 12);\n            if (0 != $expire && $_SERVER['REQUEST_TIME'] > filemtime($filename) + $expire) {\n                //缓存过期删除缓存文件\n                $this->unlink($filename);\n                return $default;\n            }\n            $content = substr($content, 20, -3);\n            if ($this->options['data_compress'] && function_exists('gzcompress')) {\n                //启用数据压缩\n                $content = gzuncompress($content);\n            }\n            $content = unserialize($content);\n            return $content;\n        } else {\n            return $default;\n        }\n    }\n\n    /**\n     * 写入缓存\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param mixed     $value  存储数据\n     * @param int       $expire  有效时间 0为永久\n     * @return boolean\n     */\n    public function set($name, $value, $expire = null)\n    {\n        if (is_null($expire)) {\n            $expire = $this->options['expire'];\n        }\n        $filename = $this->getCacheKey($name);\n        if ($this->tag && !is_file($filename)) {\n            $first = true;\n        }\n        $data = serialize($value);\n        if ($this->options['data_compress'] && function_exists('gzcompress')) {\n            //数据压缩\n            $data = gzcompress($data, 3);\n        }\n        $data   = \"<?php\\n//\" . sprintf('%012d', $expire) . $data . \"\\n?>\";\n        $result = file_put_contents($filename, $data);\n        if ($result) {\n            isset($first) && $this->setTagItem($filename);\n            clearstatcache();\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * 自增缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function inc($name, $step = 1)\n    {\n        if ($this->has($name)) {\n            $value = $this->get($name) + $step;\n        } else {\n            $value = $step;\n        }\n        return $this->set($name, $value, 0) ? $value : false;\n    }\n\n    /**\n     * 自减缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function dec($name, $step = 1)\n    {\n        if ($this->has($name)) {\n            $value = $this->get($name) - $step;\n        } else {\n            $value = $step;\n        }\n        return $this->set($name, $value, 0) ? $value : false;\n    }\n\n    /**\n     * 删除缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @return boolean\n     */\n    public function rm($name)\n    {\n        return $this->unlink($this->getCacheKey($name));\n    }\n\n    /**\n     * 清除缓存\n     * @access public\n     * @param string $tag 标签名\n     * @return boolean\n     */\n    public function clear($tag = null)\n    {\n        if ($tag) {\n            // 指定标签清除\n            $keys = $this->getTagItem($tag);\n            foreach ($keys as $key) {\n                $this->unlink($key);\n            }\n            $this->rm('tag_' . md5($tag));\n            return true;\n        }\n        $files = (array) glob($this->options['path'] . ($this->options['prefix'] ? $this->options['prefix'] . DS : '') . '*');\n        foreach ($files as $path) {\n            if (is_dir($path)) {\n                array_map('unlink', glob($path . '/*.php'));\n                rmdir($path);\n            } else {\n                unlink($path);\n            }\n        }\n        return true;\n    }\n\n    /**\n     * 判断文件是否存在后，删除\n     * @param $path\n     * @return bool\n     * @author byron sampson <xiaobo.sun@qq.com>\n     * @return boolean\n     */\n    private function unlink($path)\n    {\n        return is_file($path) && unlink($path);\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/cache/driver/Lite.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\cache\\driver;\n\nuse think\\cache\\Driver;\n\n/**\n * 文件类型缓存类\n * @author    liu21st <liu21st@gmail.com>\n */\nclass Lite extends Driver\n{\n    protected $options = [\n        'prefix' => '',\n        'path'   => '',\n        'expire' => 0, // 等于 10*365*24*3600（10年）\n    ];\n\n    /**\n     * 构造函数\n     * @access public\n     *\n     * @param array $options\n     */\n    public function __construct($options = [])\n    {\n        if (!empty($options)) {\n            $this->options = array_merge($this->options, $options);\n        }\n        if (substr($this->options['path'], -1) != DS) {\n            $this->options['path'] .= DS;\n        }\n\n    }\n\n    /**\n     * 取得变量的存储文件名\n     * @access protected\n     * @param string $name 缓存变量名\n     * @return string\n     */\n    protected function getCacheKey($name)\n    {\n        return $this->options['path'] . $this->options['prefix'] . md5($name) . '.php';\n    }\n\n    /**\n     * 判断缓存是否存在\n     * @access public\n     * @param string $name 缓存变量名\n     * @return mixed\n     */\n    public function has($name)\n    {\n        return $this->get($name) ? true : false;\n    }\n\n    /**\n     * 读取缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @param mixed  $default 默认值\n     * @return mixed\n     */\n    public function get($name, $default = false)\n    {\n        $filename = $this->getCacheKey($name);\n        if (is_file($filename)) {\n            // 判断是否过期\n            $mtime = filemtime($filename);\n            if ($mtime < $_SERVER['REQUEST_TIME']) {\n                // 清除已经过期的文件\n                unlink($filename);\n                return $default;\n            }\n            return include $filename;\n        } else {\n            return $default;\n        }\n    }\n\n    /**\n     * 写入缓存\n     * @access   public\n     * @param string    $name  缓存变量名\n     * @param mixed     $value 存储数据\n     * @param int       $expire 有效时间 0为永久\n     * @return bool\n     */\n    public function set($name, $value, $expire = null)\n    {\n        if (is_null($expire)) {\n            $expire = $this->options['expire'];\n        }\n        // 模拟永久\n        if (0 === $expire) {\n            $expire = 10 * 365 * 24 * 3600;\n        }\n        $filename = $this->getCacheKey($name);\n        if ($this->tag && !is_file($filename)) {\n            $first = true;\n        }\n        $ret = file_put_contents($filename, (\"<?php return \" . var_export($value, true) . \";\"));\n        // 通过设置修改时间实现有效期\n        if ($ret) {\n            isset($first) && $this->setTagItem($filename);\n            touch($filename, $_SERVER['REQUEST_TIME'] + $expire);\n        }\n        return $ret;\n    }\n\n    /**\n     * 自增缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function inc($name, $step = 1)\n    {\n        if ($this->has($name)) {\n            $value = $this->get($name) + $step;\n        } else {\n            $value = $step;\n        }\n        return $this->set($name, $value, 0) ? $value : false;\n    }\n\n    /**\n     * 自减缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function dec($name, $step = 1)\n    {\n        if ($this->has($name)) {\n            $value = $this->get($name) - $step;\n        } else {\n            $value = $step;\n        }\n        return $this->set($name, $value, 0) ? $value : false;\n    }\n\n    /**\n     * 删除缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @return boolean\n     */\n    public function rm($name)\n    {\n        return unlink($this->getCacheKey($name));\n    }\n\n    /**\n     * 清除缓存\n     * @access   public\n     * @param string $tag 标签名\n     * @return bool\n     */\n    public function clear($tag = null)\n    {\n        if ($tag) {\n            // 指定标签清除\n            $keys = $this->getTagItem($tag);\n            foreach ($keys as $key) {\n                unlink($key);\n            }\n            $this->rm('tag_' . md5($tag));\n            return true;\n        }\n        array_map(\"unlink\", glob($this->options['path'] . ($this->options['prefix'] ? $this->options['prefix'] . DS : '') . '*.php'));\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/cache/driver/Memcache.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\cache\\driver;\n\nuse think\\cache\\Driver;\n\nclass Memcache extends Driver\n{\n    protected $options = [\n        'host'       => '127.0.0.1',\n        'port'       => 11211,\n        'expire'     => 0,\n        'timeout'    => 0, // 超时时间（单位：毫秒）\n        'persistent' => true,\n        'prefix'     => '',\n    ];\n\n    /**\n     * 构造函数\n     * @param array $options 缓存参数\n     * @access public\n     * @throws \\BadFunctionCallException\n     */\n    public function __construct($options = [])\n    {\n        if (!extension_loaded('memcache')) {\n            throw new \\BadFunctionCallException('not support: memcache');\n        }\n        if (!empty($options)) {\n            $this->options = array_merge($this->options, $options);\n        }\n        $this->handler = new \\Memcache;\n        // 支持集群\n        $hosts = explode(',', $this->options['host']);\n        $ports = explode(',', $this->options['port']);\n        if (empty($ports[0])) {\n            $ports[0] = 11211;\n        }\n        // 建立连接\n        foreach ((array) $hosts as $i => $host) {\n            $port = isset($ports[$i]) ? $ports[$i] : $ports[0];\n            $this->options['timeout'] > 0 ?\n            $this->handler->addServer($host, $port, $this->options['persistent'], 1, $this->options['timeout']) :\n            $this->handler->addServer($host, $port, $this->options['persistent'], 1);\n        }\n    }\n\n    /**\n     * 判断缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @return bool\n     */\n    public function has($name)\n    {\n        $key = $this->getCacheKey($name);\n        return $this->handler->get($key) ? true : false;\n    }\n\n    /**\n     * 读取缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @param mixed  $default 默认值\n     * @return mixed\n     */\n    public function get($name, $default = false)\n    {\n        $result = $this->handler->get($this->getCacheKey($name));\n        return false !== $result ? $result : $default;\n    }\n\n    /**\n     * 写入缓存\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param mixed     $value  存储数据\n     * @param integer   $expire  有效时间（秒）\n     * @return bool\n     */\n    public function set($name, $value, $expire = null)\n    {\n        if (is_null($expire)) {\n            $expire = $this->options['expire'];\n        }\n        if ($this->tag && !$this->has($name)) {\n            $first = true;\n        }\n        $key = $this->getCacheKey($name);\n        if ($this->handler->set($key, $value, 0, $expire)) {\n            isset($first) && $this->setTagItem($key);\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 自增缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function inc($name, $step = 1)\n    {\n        $key = $this->getCacheKey($name);\n        if ($this->handler->get($key)) {\n            return $this->handler->increment($key, $step);\n        }\n        return $this->handler->set($key, $step);\n    }\n\n    /**\n     * 自减缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function dec($name, $step = 1)\n    {\n        $key   = $this->getCacheKey($name);\n        $value = $this->handler->get($key) - $step;\n        $res   = $this->handler->set($key, $value);\n        if (!$res) {\n            return false;\n        } else {\n            return $value;\n        }\n    }\n\n    /**\n     * 删除缓存\n     * @param    string  $name 缓存变量名\n     * @param bool|false $ttl\n     * @return bool\n     */\n    public function rm($name, $ttl = false)\n    {\n        $key = $this->getCacheKey($name);\n        return false === $ttl ?\n        $this->handler->delete($key) :\n        $this->handler->delete($key, $ttl);\n    }\n\n    /**\n     * 清除缓存\n     * @access public\n     * @param string $tag 标签名\n     * @return bool\n     */\n    public function clear($tag = null)\n    {\n        if ($tag) {\n            // 指定标签清除\n            $keys = $this->getTagItem($tag);\n            foreach ($keys as $key) {\n                $this->handler->delete($key);\n            }\n            $this->rm('tag_' . md5($tag));\n            return true;\n        }\n        return $this->handler->flush();\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/cache/driver/Memcached.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\cache\\driver;\n\nuse think\\cache\\Driver;\n\nclass Memcached extends Driver\n{\n    protected $options = [\n        'host'     => '127.0.0.1',\n        'port'     => 11211,\n        'expire'   => 0,\n        'timeout'  => 0, // 超时时间（单位：毫秒）\n        'prefix'   => '',\n        'username' => '', //账号\n        'password' => '', //密码\n        'option'   => [],\n    ];\n\n    /**\n     * 构造函数\n     * @param array $options 缓存参数\n     * @access public\n     */\n    public function __construct($options = [])\n    {\n        if (!extension_loaded('memcached')) {\n            throw new \\BadFunctionCallException('not support: memcached');\n        }\n        if (!empty($options)) {\n            $this->options = array_merge($this->options, $options);\n        }\n        $this->handler = new \\Memcached;\n        if (!empty($this->options['option'])) {\n            $this->handler->setOptions($this->options['option']);\n        }\n        // 设置连接超时时间（单位：毫秒）\n        if ($this->options['timeout'] > 0) {\n            $this->handler->setOption(\\Memcached::OPT_CONNECT_TIMEOUT, $this->options['timeout']);\n        }\n        // 支持集群\n        $hosts = explode(',', $this->options['host']);\n        $ports = explode(',', $this->options['port']);\n        if (empty($ports[0])) {\n            $ports[0] = 11211;\n        }\n        // 建立连接\n        $servers = [];\n        foreach ((array) $hosts as $i => $host) {\n            $servers[] = [$host, (isset($ports[$i]) ? $ports[$i] : $ports[0]), 1];\n        }\n        $this->handler->addServers($servers);\n        if ('' != $this->options['username']) {\n            $this->handler->setOption(\\Memcached::OPT_BINARY_PROTOCOL, true);\n            $this->handler->setSaslAuthData($this->options['username'], $this->options['password']);\n        }\n    }\n\n    /**\n     * 判断缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @return bool\n     */\n    public function has($name)\n    {\n        $key = $this->getCacheKey($name);\n        return $this->handler->get($key) ? true : false;\n    }\n\n    /**\n     * 读取缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @param mixed  $default 默认值\n     * @return mixed\n     */\n    public function get($name, $default = false)\n    {\n        $result = $this->handler->get($this->getCacheKey($name));\n        return false !== $result ? $result : $default;\n    }\n\n    /**\n     * 写入缓存\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param mixed     $value  存储数据\n     * @param integer   $expire  有效时间（秒）\n     * @return bool\n     */\n    public function set($name, $value, $expire = null)\n    {\n        if (is_null($expire)) {\n            $expire = $this->options['expire'];\n        }\n        if ($this->tag && !$this->has($name)) {\n            $first = true;\n        }\n        $key    = $this->getCacheKey($name);\n        $expire = 0 == $expire ? 0 : $_SERVER['REQUEST_TIME'] + $expire;\n        if ($this->handler->set($key, $value, $expire)) {\n            isset($first) && $this->setTagItem($key);\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 自增缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function inc($name, $step = 1)\n    {\n        $key = $this->getCacheKey($name);\n        if ($this->handler->get($key)) {\n            return $this->handler->increment($key, $step);\n        }\n        return $this->handler->set($key, $step);\n    }\n\n    /**\n     * 自减缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function dec($name, $step = 1)\n    {\n        $key   = $this->getCacheKey($name);\n        $value = $this->handler->get($key) - $step;\n        $res   = $this->handler->set($key, $value);\n        if (!$res) {\n            return false;\n        } else {\n            return $value;\n        }\n    }\n\n    /**\n     * 删除缓存\n     * @param    string  $name 缓存变量名\n     * @param bool|false $ttl\n     * @return bool\n     */\n    public function rm($name, $ttl = false)\n    {\n        $key = $this->getCacheKey($name);\n        return false === $ttl ?\n        $this->handler->delete($key) :\n        $this->handler->delete($key, $ttl);\n    }\n\n    /**\n     * 清除缓存\n     * @access public\n     * @param string $tag 标签名\n     * @return bool\n     */\n    public function clear($tag = null)\n    {\n        if ($tag) {\n            // 指定标签清除\n            $keys = $this->getTagItem($tag);\n            $this->handler->deleteMulti($keys);\n            $this->rm('tag_' . md5($tag));\n            return true;\n        }\n        return $this->handler->flush();\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/cache/driver/Redis.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\cache\\driver;\n\nuse think\\cache\\Driver;\n\n/**\n * Redis缓存驱动，适合单机部署、有前端代理实现高可用的场景，性能最好\n * 有需要在业务层实现读写分离、或者使用RedisCluster的需求，请使用Redisd驱动\n *\n * 要求安装phpredis扩展：https://github.com/nicolasff/phpredis\n * @author    尘缘 <130775@qq.com>\n */\nclass Redis extends Driver\n{\n    protected $options = [\n        'host'       => '127.0.0.1',\n        'port'       => 6379,\n        'password'   => '',\n        'select'     => 0,\n        'timeout'    => 0,\n        'expire'     => 0,\n        'persistent' => false,\n        'prefix'     => '',\n    ];\n\n    /**\n     * 构造函数\n     * @param array $options 缓存参数\n     * @access public\n     */\n    public function __construct($options = [])\n    {\n        if (!extension_loaded('redis')) {\n            throw new \\BadFunctionCallException('not support: redis');\n        }\n        if (!empty($options)) {\n            $this->options = array_merge($this->options, $options);\n        }\n        $func          = $this->options['persistent'] ? 'pconnect' : 'connect';\n        $this->handler = new \\Redis;\n        $this->handler->$func($this->options['host'], $this->options['port'], $this->options['timeout']);\n\n        if ('' != $this->options['password']) {\n            $this->handler->auth($this->options['password']);\n        }\n\n        if (0 != $this->options['select']) {\n            $this->handler->select($this->options['select']);\n        }\n    }\n\n    /**\n     * 判断缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @return bool\n     */\n    public function has($name)\n    {\n        return $this->handler->get($this->getCacheKey($name)) ? true : false;\n    }\n\n    /**\n     * 读取缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @param mixed  $default 默认值\n     * @return mixed\n     */\n    public function get($name, $default = false)\n    {\n        $value = $this->handler->get($this->getCacheKey($name));\n        if (is_null($value)) {\n            return $default;\n        }\n        $jsonData = json_decode($value, true);\n        // 检测是否为JSON数据 true 返回JSON解析数组, false返回源数据 byron sampson<xiaobo.sun@qq.com>\n        return (null === $jsonData) ? $value : $jsonData;\n    }\n\n    /**\n     * 写入缓存\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param mixed     $value  存储数据\n     * @param integer   $expire  有效时间（秒）\n     * @return boolean\n     */\n    public function set($name, $value, $expire = null)\n    {\n        if (is_null($expire)) {\n            $expire = $this->options['expire'];\n        }\n        if ($this->tag && !$this->has($name)) {\n            $first = true;\n        }\n        $key = $this->getCacheKey($name);\n        //对数组/对象数据进行缓存处理，保证数据完整性  byron sampson<xiaobo.sun@qq.com>\n        $value = (is_object($value) || is_array($value)) ? json_encode($value) : $value;\n        if (is_int($expire) && $expire) {\n            $result = $this->handler->setex($key, $expire, $value);\n        } else {\n            $result = $this->handler->set($key, $value);\n        }\n        isset($first) && $this->setTagItem($key);\n        return $result;\n    }\n\n    /**\n     * 自增缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function inc($name, $step = 1)\n    {\n        $key = $this->getCacheKey($name);\n        return $this->handler->incrby($key, $step);\n    }\n\n    /**\n     * 自减缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function dec($name, $step = 1)\n    {\n        $key = $this->getCacheKey($name);\n        return $this->handler->decrby($key, $step);\n    }\n\n    /**\n     * 删除缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @return boolean\n     */\n    public function rm($name)\n    {\n        return $this->handler->delete($this->getCacheKey($name));\n    }\n\n    /**\n     * 清除缓存\n     * @access public\n     * @param string $tag 标签名\n     * @return boolean\n     */\n    public function clear($tag = null)\n    {\n        if ($tag) {\n            // 指定标签清除\n            $keys = $this->getTagItem($tag);\n            foreach ($keys as $key) {\n                $this->handler->delete($key);\n            }\n            $this->rm('tag_' . md5($tag));\n            return true;\n        }\n        return $this->handler->flushDB();\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/cache/driver/Sqlite.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\cache\\driver;\n\nuse think\\cache\\Driver;\n\n/**\n * Sqlite缓存驱动\n * @author    liu21st <liu21st@gmail.com>\n */\nclass Sqlite extends Driver\n{\n    protected $options = [\n        'db'         => ':memory:',\n        'table'      => 'sharedmemory',\n        'prefix'     => '',\n        'expire'     => 0,\n        'persistent' => false,\n    ];\n\n    /**\n     * 构造函数\n     * @param array $options 缓存参数\n     * @throws \\BadFunctionCallException\n     * @access public\n     */\n    public function __construct($options = [])\n    {\n        if (!extension_loaded('sqlite')) {\n            throw new \\BadFunctionCallException('not support: sqlite');\n        }\n        if (!empty($options)) {\n            $this->options = array_merge($this->options, $options);\n        }\n        $func          = $this->options['persistent'] ? 'sqlite_popen' : 'sqlite_open';\n        $this->handler = $func($this->options['db']);\n    }\n\n    /**\n     * 获取实际的缓存标识\n     * @access public\n     * @param string $name 缓存名\n     * @return string\n     */\n    protected function getCacheKey($name)\n    {\n        return $this->options['prefix'] . sqlite_escape_string($name);\n    }\n\n    /**\n     * 判断缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @return bool\n     */\n    public function has($name)\n    {\n        $name   = $this->getCacheKey($name);\n        $sql    = 'SELECT value FROM ' . $this->options['table'] . ' WHERE var=\\'' . $name . '\\' AND (expire=0 OR expire >' . $_SERVER['REQUEST_TIME'] . ') LIMIT 1';\n        $result = sqlite_query($this->handler, $sql);\n        return sqlite_num_rows($result);\n    }\n\n    /**\n     * 读取缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @param mixed  $default 默认值\n     * @return mixed\n     */\n    public function get($name, $default = false)\n    {\n        $name   = $this->getCacheKey($name);\n        $sql    = 'SELECT value FROM ' . $this->options['table'] . ' WHERE var=\\'' . $name . '\\' AND (expire=0 OR expire >' . $_SERVER['REQUEST_TIME'] . ') LIMIT 1';\n        $result = sqlite_query($this->handler, $sql);\n        if (sqlite_num_rows($result)) {\n            $content = sqlite_fetch_single($result);\n            if (function_exists('gzcompress')) {\n                //启用数据压缩\n                $content = gzuncompress($content);\n            }\n            return unserialize($content);\n        }\n        return $default;\n    }\n\n    /**\n     * 写入缓存\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param mixed     $value  存储数据\n     * @param integer   $expire  有效时间（秒）\n     * @return boolean\n     */\n    public function set($name, $value, $expire = null)\n    {\n        $name  = $this->getCacheKey($name);\n        $value = sqlite_escape_string(serialize($value));\n        if (is_null($expire)) {\n            $expire = $this->options['expire'];\n        }\n        $expire = (0 == $expire) ? 0 : ($_SERVER['REQUEST_TIME'] + $expire); //缓存有效期为0表示永久缓存\n        if (function_exists('gzcompress')) {\n            //数据压缩\n            $value = gzcompress($value, 3);\n        }\n        if ($this->tag) {\n            $tag       = $this->tag;\n            $this->tag = null;\n        } else {\n            $tag = '';\n        }\n        $sql = 'REPLACE INTO ' . $this->options['table'] . ' (var, value, expire, tag) VALUES (\\'' . $name . '\\', \\'' . $value . '\\', \\'' . $expire . '\\', \\'' . $tag . '\\')';\n        if (sqlite_query($this->handler, $sql)) {\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 自增缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function inc($name, $step = 1)\n    {\n        if ($this->has($name)) {\n            $value = $this->get($name) + $step;\n        } else {\n            $value = $step;\n        }\n        return $this->set($name, $value, 0) ? $value : false;\n    }\n\n    /**\n     * 自减缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function dec($name, $step = 1)\n    {\n        if ($this->has($name)) {\n            $value = $this->get($name) - $step;\n        } else {\n            $value = $step;\n        }\n        return $this->set($name, $value, 0) ? $value : false;\n    }\n\n    /**\n     * 删除缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @return boolean\n     */\n    public function rm($name)\n    {\n        $name = $this->getCacheKey($name);\n        $sql  = 'DELETE FROM ' . $this->options['table'] . ' WHERE var=\\'' . $name . '\\'';\n        sqlite_query($this->handler, $sql);\n        return true;\n    }\n\n    /**\n     * 清除缓存\n     * @access public\n     * @param string $tag 标签名\n     * @return boolean\n     */\n    public function clear($tag = null)\n    {\n        if ($tag) {\n            $name = sqlite_escape_string($tag);\n            $sql  = 'DELETE FROM ' . $this->options['table'] . ' WHERE tag=\\'' . $name . '\\'';\n            sqlite_query($this->handler, $sql);\n            return true;\n        }\n        $sql = 'DELETE FROM ' . $this->options['table'];\n        sqlite_query($this->handler, $sql);\n        return true;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/cache/driver/Wincache.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\cache\\driver;\n\nuse think\\cache\\Driver;\n\n/**\n * Wincache缓存驱动\n * @author    liu21st <liu21st@gmail.com>\n */\nclass Wincache extends Driver\n{\n    protected $options = [\n        'prefix' => '',\n        'expire' => 0,\n    ];\n\n    /**\n     * 构造函数\n     * @param array $options 缓存参数\n     * @throws \\BadFunctionCallException\n     * @access public\n     */\n    public function __construct($options = [])\n    {\n        if (!function_exists('wincache_ucache_info')) {\n            throw new \\BadFunctionCallException('not support: WinCache');\n        }\n        if (!empty($options)) {\n            $this->options = array_merge($this->options, $options);\n        }\n    }\n\n    /**\n     * 判断缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @return bool\n     */\n    public function has($name)\n    {\n        $key = $this->getCacheKey($name);\n        return wincache_ucache_exists($key);\n    }\n\n    /**\n     * 读取缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @param mixed  $default 默认值\n     * @return mixed\n     */\n    public function get($name, $default = false)\n    {\n        $key = $this->getCacheKey($name);\n        return wincache_ucache_exists($key) ? wincache_ucache_get($key) : $default;\n    }\n\n    /**\n     * 写入缓存\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param mixed     $value  存储数据\n     * @param integer   $expire  有效时间（秒）\n     * @return boolean\n     */\n    public function set($name, $value, $expire = null)\n    {\n        if (is_null($expire)) {\n            $expire = $this->options['expire'];\n        }\n        $key = $this->getCacheKey($name);\n        if ($this->tag && !$this->has($name)) {\n            $first = true;\n        }\n        if (wincache_ucache_set($key, $value, $expire)) {\n            isset($first) && $this->setTagItem($key);\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 自增缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function inc($name, $step = 1)\n    {\n        $key = $this->getCacheKey($name);\n        return wincache_ucache_inc($key, $step);\n    }\n\n    /**\n     * 自减缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function dec($name, $step = 1)\n    {\n        $key = $this->getCacheKey($name);\n        return wincache_ucache_dec($key, $step);\n    }\n\n    /**\n     * 删除缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @return boolean\n     */\n    public function rm($name)\n    {\n        return wincache_ucache_delete($this->getCacheKey($name));\n    }\n\n    /**\n     * 清除缓存\n     * @access public\n     * @param string $tag 标签名\n     * @return boolean\n     */\n    public function clear($tag = null)\n    {\n        if ($tag) {\n            $keys = $this->getTagItem($tag);\n            foreach ($keys as $key) {\n                wincache_ucache_delete($key);\n            }\n            $this->rm('tag_' . md5($tag));\n            return true;\n        } else {\n            return wincache_ucache_clear();\n        }\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/cache/driver/Xcache.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\cache\\driver;\n\nuse think\\cache\\Driver;\n\n/**\n * Xcache缓存驱动\n * @author    liu21st <liu21st@gmail.com>\n */\nclass Xcache extends Driver\n{\n    protected $options = [\n        'prefix' => '',\n        'expire' => 0,\n    ];\n\n    /**\n     * 构造函数\n     * @param array $options 缓存参数\n     * @access public\n     * @throws \\BadFunctionCallException\n     */\n    public function __construct($options = [])\n    {\n        if (!function_exists('xcache_info')) {\n            throw new \\BadFunctionCallException('not support: Xcache');\n        }\n        if (!empty($options)) {\n            $this->options = array_merge($this->options, $options);\n        }\n    }\n\n    /**\n     * 判断缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @return bool\n     */\n    public function has($name)\n    {\n        $key = $this->getCacheKey($name);\n        return xcache_isset($key);\n    }\n\n    /**\n     * 读取缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @param mixed  $default 默认值\n     * @return mixed\n     */\n    public function get($name, $default = false)\n    {\n        $key = $this->getCacheKey($name);\n        return xcache_isset($key) ? xcache_get($key) : $default;\n    }\n\n    /**\n     * 写入缓存\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param mixed     $value  存储数据\n     * @param integer   $expire  有效时间（秒）\n     * @return boolean\n     */\n    public function set($name, $value, $expire = null)\n    {\n        if (is_null($expire)) {\n            $expire = $this->options['expire'];\n        }\n        if ($this->tag && !$this->has($name)) {\n            $first = true;\n        }\n        $key = $this->getCacheKey($name);\n        if (xcache_set($key, $value, $expire)) {\n            isset($first) && $this->setTagItem($key);\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 自增缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function inc($name, $step = 1)\n    {\n        $key = $this->getCacheKey($name);\n        return xcache_inc($key, $step);\n    }\n\n    /**\n     * 自减缓存（针对数值缓存）\n     * @access public\n     * @param string    $name 缓存变量名\n     * @param int       $step 步长\n     * @return false|int\n     */\n    public function dec($name, $step = 1)\n    {\n        $key = $this->getCacheKey($name);\n        return xcache_dec($key, $step);\n    }\n\n    /**\n     * 删除缓存\n     * @access public\n     * @param string $name 缓存变量名\n     * @return boolean\n     */\n    public function rm($name)\n    {\n        return xcache_unset($this->getCacheKey($name));\n    }\n\n    /**\n     * 清除缓存\n     * @access public\n     * @param string $tag 标签名\n     * @return boolean\n     */\n    public function clear($tag = null)\n    {\n        if ($tag) {\n            // 指定标签清除\n            $keys = $this->getTagItem($tag);\n            foreach ($keys as $key) {\n                xcache_unset($key);\n            }\n            $this->rm('tag_' . md5($tag));\n            return true;\n        }\n        if (function_exists('xcache_unset_by_prefix')) {\n            return xcache_unset_by_prefix($this->options['prefix']);\n        } else {\n            return false;\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/config/driver/Ini.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\config\\driver;\n\nclass Ini\n{\n    public function parse($config)\n    {\n        if (is_file($config)) {\n            return parse_ini_file($config, true);\n        } else {\n            return parse_ini_string($config, true);\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/config/driver/Json.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\config\\driver;\n\nclass Json\n{\n    public function parse($config)\n    {\n        if (is_file($config)) {\n            $config = file_get_contents($config);\n        }\n        $result = json_decode($config, true);\n        return $result;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/config/driver/Xml.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\config\\driver;\n\nclass Xml\n{\n    public function parse($config)\n    {\n        if (is_file($config)) {\n            $content = simplexml_load_file($config);\n        } else {\n            $content = simplexml_load_string($config);\n        }\n        $result = (array) $content;\n        foreach ($result as $key => $val) {\n            if (is_object($val)) {\n                $result[$key] = (array) $val;\n            }\n        }\n        return $result;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/Command.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console;\n\nuse think\\Console;\nuse think\\console\\input\\Argument;\nuse think\\console\\input\\Definition;\nuse think\\console\\input\\Option;\n\nclass Command\n{\n\n    /** @var  Console */\n    private $console;\n    private $name;\n    private $aliases = [];\n    private $definition;\n    private $help;\n    private $description;\n    private $ignoreValidationErrors          = false;\n    private $consoleDefinitionMerged         = false;\n    private $consoleDefinitionMergedWithArgs = false;\n    private $code;\n    private $synopsis = [];\n    private $usages   = [];\n\n    /** @var  Input */\n    protected $input;\n\n    /** @var  Output */\n    protected $output;\n\n    /**\n     * 构造方法\n     * @param string|null $name 命令名称,如果没有设置则比如在 configure() 里设置\n     * @throws \\LogicException\n     * @api\n     */\n    public function __construct($name = null)\n    {\n        $this->definition = new Definition();\n\n        if (null !== $name) {\n            $this->setName($name);\n        }\n\n        $this->configure();\n\n        if (!$this->name) {\n            throw new \\LogicException(sprintf('The command defined in \"%s\" cannot have an empty name.', get_class($this)));\n        }\n    }\n\n    /**\n     * 忽略验证错误\n     */\n    public function ignoreValidationErrors()\n    {\n        $this->ignoreValidationErrors = true;\n    }\n\n    /**\n     * 设置控制台\n     * @param Console $console\n     */\n    public function setConsole(Console $console = null)\n    {\n        $this->console = $console;\n    }\n\n    /**\n     * 获取控制台\n     * @return Console\n     * @api\n     */\n    public function getConsole()\n    {\n        return $this->console;\n    }\n\n    /**\n     * 是否有效\n     * @return bool\n     */\n    public function isEnabled()\n    {\n        return true;\n    }\n\n    /**\n     * 配置指令\n     */\n    protected function configure()\n    {\n    }\n\n    /**\n     * 执行指令\n     * @param Input  $input\n     * @param Output $output\n     * @return null|int\n     * @throws \\LogicException\n     * @see setCode()\n     */\n    protected function execute(Input $input, Output $output)\n    {\n        throw new \\LogicException('You must override the execute() method in the concrete command class.');\n    }\n\n    /**\n     * 用户验证\n     * @param Input  $input\n     * @param Output $output\n     */\n    protected function interact(Input $input, Output $output)\n    {\n    }\n\n    /**\n     * 初始化\n     * @param Input  $input  An InputInterface instance\n     * @param Output $output An OutputInterface instance\n     */\n    protected function initialize(Input $input, Output $output)\n    {\n    }\n\n    /**\n     * 执行\n     * @param Input  $input\n     * @param Output $output\n     * @return int\n     * @throws \\Exception\n     * @see setCode()\n     * @see execute()\n     */\n    public function run(Input $input, Output $output)\n    {\n        $this->input  = $input;\n        $this->output = $output;\n\n        $this->getSynopsis(true);\n        $this->getSynopsis(false);\n\n        $this->mergeConsoleDefinition();\n\n        try {\n            $input->bind($this->definition);\n        } catch (\\Exception $e) {\n            if (!$this->ignoreValidationErrors) {\n                throw $e;\n            }\n        }\n\n        $this->initialize($input, $output);\n\n        if ($input->isInteractive()) {\n            $this->interact($input, $output);\n        }\n\n        $input->validate();\n\n        if ($this->code) {\n            $statusCode = call_user_func($this->code, $input, $output);\n        } else {\n            $statusCode = $this->execute($input, $output);\n        }\n\n        return is_numeric($statusCode) ? (int) $statusCode : 0;\n    }\n\n    /**\n     * 设置执行代码\n     * @param callable $code callable(InputInterface $input, OutputInterface $output)\n     * @return Command\n     * @throws \\InvalidArgumentException\n     * @see execute()\n     */\n    public function setCode(callable $code)\n    {\n        if (!is_callable($code)) {\n            throw new \\InvalidArgumentException('Invalid callable provided to Command::setCode.');\n        }\n\n        if (PHP_VERSION_ID >= 50400 && $code instanceof \\Closure) {\n            $r = new \\ReflectionFunction($code);\n            if (null === $r->getClosureThis()) {\n                $code = \\Closure::bind($code, $this);\n            }\n        }\n\n        $this->code = $code;\n\n        return $this;\n    }\n\n    /**\n     * 合并参数定义\n     * @param bool $mergeArgs\n     */\n    public function mergeConsoleDefinition($mergeArgs = true)\n    {\n        if (null === $this->console\n            || (true === $this->consoleDefinitionMerged\n                && ($this->consoleDefinitionMergedWithArgs || !$mergeArgs))\n        ) {\n            return;\n        }\n\n        if ($mergeArgs) {\n            $currentArguments = $this->definition->getArguments();\n            $this->definition->setArguments($this->console->getDefinition()->getArguments());\n            $this->definition->addArguments($currentArguments);\n        }\n\n        $this->definition->addOptions($this->console->getDefinition()->getOptions());\n\n        $this->consoleDefinitionMerged = true;\n        if ($mergeArgs) {\n            $this->consoleDefinitionMergedWithArgs = true;\n        }\n    }\n\n    /**\n     * 设置参数定义\n     * @param array|Definition $definition\n     * @return Command\n     * @api\n     */\n    public function setDefinition($definition)\n    {\n        if ($definition instanceof Definition) {\n            $this->definition = $definition;\n        } else {\n            $this->definition->setDefinition($definition);\n        }\n\n        $this->consoleDefinitionMerged = false;\n\n        return $this;\n    }\n\n    /**\n     * 获取参数定义\n     * @return Definition\n     * @api\n     */\n    public function getDefinition()\n    {\n        return $this->definition;\n    }\n\n    /**\n     * 获取当前指令的参数定义\n     * @return Definition\n     */\n    public function getNativeDefinition()\n    {\n        return $this->getDefinition();\n    }\n\n    /**\n     * 添加参数\n     * @param string $name        名称\n     * @param int    $mode        类型\n     * @param string $description 描述\n     * @param mixed  $default     默认值\n     * @return Command\n     */\n    public function addArgument($name, $mode = null, $description = '', $default = null)\n    {\n        $this->definition->addArgument(new Argument($name, $mode, $description, $default));\n\n        return $this;\n    }\n\n    /**\n     * 添加选项\n     * @param string $name        选项名称\n     * @param string $shortcut    别名\n     * @param int    $mode        类型\n     * @param string $description 描述\n     * @param mixed  $default     默认值\n     * @return Command\n     */\n    public function addOption($name, $shortcut = null, $mode = null, $description = '', $default = null)\n    {\n        $this->definition->addOption(new Option($name, $shortcut, $mode, $description, $default));\n\n        return $this;\n    }\n\n    /**\n     * 设置指令名称\n     * @param string $name\n     * @return Command\n     * @throws \\InvalidArgumentException\n     */\n    public function setName($name)\n    {\n        $this->validateName($name);\n\n        $this->name = $name;\n\n        return $this;\n    }\n\n    /**\n     * 获取指令名称\n     * @return string\n     */\n    public function getName()\n    {\n        return $this->name;\n    }\n\n    /**\n     * 设置描述\n     * @param string $description\n     * @return Command\n     */\n    public function setDescription($description)\n    {\n        $this->description = $description;\n\n        return $this;\n    }\n\n    /**\n     *  获取描述\n     * @return string\n     */\n    public function getDescription()\n    {\n        return $this->description;\n    }\n\n    /**\n     * 设置帮助信息\n     * @param string $help\n     * @return Command\n     */\n    public function setHelp($help)\n    {\n        $this->help = $help;\n\n        return $this;\n    }\n\n    /**\n     * 获取帮助信息\n     * @return string\n     */\n    public function getHelp()\n    {\n        return $this->help;\n    }\n\n    /**\n     * 描述信息\n     * @return string\n     */\n    public function getProcessedHelp()\n    {\n        $name = $this->name;\n\n        $placeholders = [\n            '%command.name%',\n            '%command.full_name%',\n        ];\n        $replacements = [\n            $name,\n            $_SERVER['PHP_SELF'] . ' ' . $name,\n        ];\n\n        return str_replace($placeholders, $replacements, $this->getHelp());\n    }\n\n    /**\n     * 设置别名\n     * @param string[] $aliases\n     * @return Command\n     * @throws \\InvalidArgumentException\n     */\n    public function setAliases($aliases)\n    {\n        if (!is_array($aliases) && !$aliases instanceof \\Traversable) {\n            throw new \\InvalidArgumentException('$aliases must be an array or an instance of \\Traversable');\n        }\n\n        foreach ($aliases as $alias) {\n            $this->validateName($alias);\n        }\n\n        $this->aliases = $aliases;\n\n        return $this;\n    }\n\n    /**\n     * 获取别名\n     * @return array\n     */\n    public function getAliases()\n    {\n        return $this->aliases;\n    }\n\n    /**\n     * 获取简介\n     * @param bool $short 是否简单的\n     * @return string\n     */\n    public function getSynopsis($short = false)\n    {\n        $key = $short ? 'short' : 'long';\n\n        if (!isset($this->synopsis[$key])) {\n            $this->synopsis[$key] = trim(sprintf('%s %s', $this->name, $this->definition->getSynopsis($short)));\n        }\n\n        return $this->synopsis[$key];\n    }\n\n    /**\n     * 添加用法介绍\n     * @param string $usage\n     * @return $this\n     */\n    public function addUsage($usage)\n    {\n        if (0 !== strpos($usage, $this->name)) {\n            $usage = sprintf('%s %s', $this->name, $usage);\n        }\n\n        $this->usages[] = $usage;\n\n        return $this;\n    }\n\n    /**\n     * 获取用法介绍\n     * @return array\n     */\n    public function getUsages()\n    {\n        return $this->usages;\n    }\n\n    /**\n     * 验证指令名称\n     * @param string $name\n     * @throws \\InvalidArgumentException\n     */\n    private function validateName($name)\n    {\n        if (!preg_match('/^[^\\:]++(\\:[^\\:]++)*$/', $name)) {\n            throw new \\InvalidArgumentException(sprintf('Command name \"%s\" is invalid.', $name));\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/Input.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console;\n\nuse think\\console\\input\\Argument;\nuse think\\console\\input\\Definition;\nuse think\\console\\input\\Option;\n\nclass Input\n{\n\n    /**\n     * @var Definition\n     */\n    protected $definition;\n\n    /**\n     * @var Option[]\n     */\n    protected $options = [];\n\n    /**\n     * @var Argument[]\n     */\n    protected $arguments = [];\n\n    protected $interactive = true;\n\n    private $tokens;\n    private $parsed;\n\n    public function __construct($argv = null)\n    {\n        if (null === $argv) {\n            $argv = $_SERVER['argv'];\n            // 去除命令名\n            array_shift($argv);\n        }\n\n        $this->tokens = $argv;\n\n        $this->definition = new Definition();\n    }\n\n    protected function setTokens(array $tokens)\n    {\n        $this->tokens = $tokens;\n    }\n\n    /**\n     * 绑定实例\n     * @param Definition $definition A InputDefinition instance\n     */\n    public function bind(Definition $definition)\n    {\n        $this->arguments  = [];\n        $this->options    = [];\n        $this->definition = $definition;\n\n        $this->parse();\n    }\n\n    /**\n     * 解析参数\n     */\n    protected function parse()\n    {\n        $parseOptions = true;\n        $this->parsed = $this->tokens;\n        while (null !== $token = array_shift($this->parsed)) {\n            if ($parseOptions && '' == $token) {\n                $this->parseArgument($token);\n            } elseif ($parseOptions && '--' == $token) {\n                $parseOptions = false;\n            } elseif ($parseOptions && 0 === strpos($token, '--')) {\n                $this->parseLongOption($token);\n            } elseif ($parseOptions && '-' === $token[0] && '-' !== $token) {\n                $this->parseShortOption($token);\n            } else {\n                $this->parseArgument($token);\n            }\n        }\n    }\n\n    /**\n     * 解析短选项\n     * @param string $token 当前的指令.\n     */\n    private function parseShortOption($token)\n    {\n        $name = substr($token, 1);\n\n        if (strlen($name) > 1) {\n            if ($this->definition->hasShortcut($name[0])\n                && $this->definition->getOptionForShortcut($name[0])->acceptValue()\n            ) {\n                $this->addShortOption($name[0], substr($name, 1));\n            } else {\n                $this->parseShortOptionSet($name);\n            }\n        } else {\n            $this->addShortOption($name, null);\n        }\n    }\n\n    /**\n     * 解析短选项\n     * @param string $name 当前指令\n     * @throws \\RuntimeException\n     */\n    private function parseShortOptionSet($name)\n    {\n        $len = strlen($name);\n        for ($i = 0; $i < $len; ++$i) {\n            if (!$this->definition->hasShortcut($name[$i])) {\n                throw new \\RuntimeException(sprintf('The \"-%s\" option does not exist.', $name[$i]));\n            }\n\n            $option = $this->definition->getOptionForShortcut($name[$i]);\n            if ($option->acceptValue()) {\n                $this->addLongOption($option->getName(), $i === $len - 1 ? null : substr($name, $i + 1));\n\n                break;\n            } else {\n                $this->addLongOption($option->getName(), null);\n            }\n        }\n    }\n\n    /**\n     * 解析完整选项\n     * @param string $token 当前指令\n     */\n    private function parseLongOption($token)\n    {\n        $name = substr($token, 2);\n\n        if (false !== $pos = strpos($name, '=')) {\n            $this->addLongOption(substr($name, 0, $pos), substr($name, $pos + 1));\n        } else {\n            $this->addLongOption($name, null);\n        }\n    }\n\n    /**\n     * 解析参数\n     * @param string $token 当前指令\n     * @throws \\RuntimeException\n     */\n    private function parseArgument($token)\n    {\n        $c = count($this->arguments);\n\n        if ($this->definition->hasArgument($c)) {\n            $arg = $this->definition->getArgument($c);\n\n            $this->arguments[$arg->getName()] = $arg->isArray() ? [$token] : $token;\n\n        } elseif ($this->definition->hasArgument($c - 1) && $this->definition->getArgument($c - 1)->isArray()) {\n            $arg = $this->definition->getArgument($c - 1);\n\n            $this->arguments[$arg->getName()][] = $token;\n        } else {\n            throw new \\RuntimeException('Too many arguments.');\n        }\n    }\n\n    /**\n     * 添加一个短选项的值\n     * @param string $shortcut 短名称\n     * @param mixed  $value    值\n     * @throws \\RuntimeException\n     */\n    private function addShortOption($shortcut, $value)\n    {\n        if (!$this->definition->hasShortcut($shortcut)) {\n            throw new \\RuntimeException(sprintf('The \"-%s\" option does not exist.', $shortcut));\n        }\n\n        $this->addLongOption($this->definition->getOptionForShortcut($shortcut)->getName(), $value);\n    }\n\n    /**\n     * 添加一个完整选项的值\n     * @param string $name  选项名\n     * @param mixed  $value 值\n     * @throws \\RuntimeException\n     */\n    private function addLongOption($name, $value)\n    {\n        if (!$this->definition->hasOption($name)) {\n            throw new \\RuntimeException(sprintf('The \"--%s\" option does not exist.', $name));\n        }\n\n        $option = $this->definition->getOption($name);\n\n        if (false === $value) {\n            $value = null;\n        }\n\n        if (null !== $value && !$option->acceptValue()) {\n            throw new \\RuntimeException(sprintf('The \"--%s\" option does not accept a value.', $name, $value));\n        }\n\n        if (null === $value && $option->acceptValue() && count($this->parsed)) {\n            $next = array_shift($this->parsed);\n            if (isset($next[0]) && '-' !== $next[0]) {\n                $value = $next;\n            } elseif (empty($next)) {\n                $value = '';\n            } else {\n                array_unshift($this->parsed, $next);\n            }\n        }\n\n        if (null === $value) {\n            if ($option->isValueRequired()) {\n                throw new \\RuntimeException(sprintf('The \"--%s\" option requires a value.', $name));\n            }\n\n            if (!$option->isArray()) {\n                $value = $option->isValueOptional() ? $option->getDefault() : true;\n            }\n        }\n\n        if ($option->isArray()) {\n            $this->options[$name][] = $value;\n        } else {\n            $this->options[$name] = $value;\n        }\n    }\n\n    /**\n     * 获取第一个参数\n     * @return string|null\n     */\n    public function getFirstArgument()\n    {\n        foreach ($this->tokens as $token) {\n            if ($token && '-' === $token[0]) {\n                continue;\n            }\n\n            return $token;\n        }\n        return;\n    }\n\n    /**\n     * 检查原始参数是否包含某个值\n     * @param string|array $values 需要检查的值\n     * @return bool\n     */\n    public function hasParameterOption($values)\n    {\n        $values = (array) $values;\n\n        foreach ($this->tokens as $token) {\n            foreach ($values as $value) {\n                if ($token === $value || 0 === strpos($token, $value . '=')) {\n                    return true;\n                }\n            }\n        }\n\n        return false;\n    }\n\n    /**\n     * 获取原始选项的值\n     * @param string|array $values  需要检查的值\n     * @param mixed        $default 默认值\n     * @return mixed The option value\n     */\n    public function getParameterOption($values, $default = false)\n    {\n        $values = (array) $values;\n        $tokens = $this->tokens;\n\n        while (0 < count($tokens)) {\n            $token = array_shift($tokens);\n\n            foreach ($values as $value) {\n                if ($token === $value || 0 === strpos($token, $value . '=')) {\n                    if (false !== $pos = strpos($token, '=')) {\n                        return substr($token, $pos + 1);\n                    }\n\n                    return array_shift($tokens);\n                }\n            }\n        }\n\n        return $default;\n    }\n\n    /**\n     * 验证输入\n     * @throws \\RuntimeException\n     */\n    public function validate()\n    {\n        if (count($this->arguments) < $this->definition->getArgumentRequiredCount()) {\n            throw new \\RuntimeException('Not enough arguments.');\n        }\n    }\n\n    /**\n     * 检查输入是否是交互的\n     * @return bool\n     */\n    public function isInteractive()\n    {\n        return $this->interactive;\n    }\n\n    /**\n     * 设置输入的交互\n     * @param bool\n     */\n    public function setInteractive($interactive)\n    {\n        $this->interactive = (bool) $interactive;\n    }\n\n    /**\n     * 获取所有的参数\n     * @return Argument[]\n     */\n    public function getArguments()\n    {\n        return array_merge($this->definition->getArgumentDefaults(), $this->arguments);\n    }\n\n    /**\n     * 根据名称获取参数\n     * @param string $name 参数名\n     * @return mixed\n     * @throws \\InvalidArgumentException\n     */\n    public function getArgument($name)\n    {\n        if (!$this->definition->hasArgument($name)) {\n            throw new \\InvalidArgumentException(sprintf('The \"%s\" argument does not exist.', $name));\n        }\n\n        return isset($this->arguments[$name]) ? $this->arguments[$name] : $this->definition->getArgument($name)\n            ->getDefault();\n    }\n\n    /**\n     * 设置参数的值\n     * @param string $name  参数名\n     * @param string $value 值\n     * @throws \\InvalidArgumentException\n     */\n    public function setArgument($name, $value)\n    {\n        if (!$this->definition->hasArgument($name)) {\n            throw new \\InvalidArgumentException(sprintf('The \"%s\" argument does not exist.', $name));\n        }\n\n        $this->arguments[$name] = $value;\n    }\n\n    /**\n     * 检查是否存在某个参数\n     * @param string|int $name 参数名或位置\n     * @return bool\n     */\n    public function hasArgument($name)\n    {\n        return $this->definition->hasArgument($name);\n    }\n\n    /**\n     * 获取所有的选项\n     * @return Option[]\n     */\n    public function getOptions()\n    {\n        return array_merge($this->definition->getOptionDefaults(), $this->options);\n    }\n\n    /**\n     * 获取选项值\n     * @param string $name 选项名称\n     * @return mixed\n     * @throws \\InvalidArgumentException\n     */\n    public function getOption($name)\n    {\n        if (!$this->definition->hasOption($name)) {\n            throw new \\InvalidArgumentException(sprintf('The \"%s\" option does not exist.', $name));\n        }\n\n        return isset($this->options[$name]) ? $this->options[$name] : $this->definition->getOption($name)->getDefault();\n    }\n\n    /**\n     * 设置选项值\n     * @param string      $name  选项名\n     * @param string|bool $value 值\n     * @throws \\InvalidArgumentException\n     */\n    public function setOption($name, $value)\n    {\n        if (!$this->definition->hasOption($name)) {\n            throw new \\InvalidArgumentException(sprintf('The \"%s\" option does not exist.', $name));\n        }\n\n        $this->options[$name] = $value;\n    }\n\n    /**\n     * 是否有某个选项\n     * @param string $name 选项名\n     * @return bool\n     */\n    public function hasOption($name)\n    {\n        return $this->definition->hasOption($name) && isset($this->options[$name]);\n    }\n\n    /**\n     * 转义指令\n     * @param string $token\n     * @return string\n     */\n    public function escapeToken($token)\n    {\n        return preg_match('{^[\\w-]+$}', $token) ? $token : escapeshellarg($token);\n    }\n\n    /**\n     * 返回传递给命令的参数的字符串\n     * @return string\n     */\n    public function __toString()\n    {\n        $tokens = array_map(function ($token) {\n            if (preg_match('{^(-[^=]+=)(.+)}', $token, $match)) {\n                return $match[1] . $this->escapeToken($match[2]);\n            }\n\n            if ($token && '-' !== $token[0]) {\n                return $this->escapeToken($token);\n            }\n\n            return $token;\n        }, $this->tokens);\n\n        return implode(' ', $tokens);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/LICENSE",
    "content": "Copyright (c) 2004-2016 Fabien Potencier\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is furnished\nto do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE."
  },
  {
    "path": "thinkphp/library/think/console/Output.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console;\n\nuse Exception;\nuse think\\console\\output\\Ask;\nuse think\\console\\output\\Descriptor;\nuse think\\console\\output\\driver\\Buffer;\nuse think\\console\\output\\driver\\Console;\nuse think\\console\\output\\driver\\Nothing;\nuse think\\console\\output\\Question;\nuse think\\console\\output\\question\\Choice;\nuse think\\console\\output\\question\\Confirmation;\n\n/**\n * Class Output\n * @package think\\console\n *\n * @see     \\think\\console\\output\\driver\\Console::setDecorated\n * @method void setDecorated($decorated)\n *\n * @see     \\think\\console\\output\\driver\\Buffer::fetch\n * @method string fetch()\n *\n * @method void info($message)\n * @method void error($message)\n * @method void comment($message)\n * @method void warning($message)\n * @method void highlight($message)\n * @method void question($message)\n */\nclass Output\n{\n    const VERBOSITY_QUIET        = 0;\n    const VERBOSITY_NORMAL       = 1;\n    const VERBOSITY_VERBOSE      = 2;\n    const VERBOSITY_VERY_VERBOSE = 3;\n    const VERBOSITY_DEBUG        = 4;\n\n    const OUTPUT_NORMAL = 0;\n    const OUTPUT_RAW    = 1;\n    const OUTPUT_PLAIN  = 2;\n\n    private $verbosity = self::VERBOSITY_NORMAL;\n\n    /** @var Buffer|Console|Nothing */\n    private $handle = null;\n\n    protected $styles = [\n        'info',\n        'error',\n        'comment',\n        'question',\n        'highlight',\n        'warning'\n    ];\n\n    public function __construct($driver = 'console')\n    {\n        $class = '\\\\think\\\\console\\\\output\\\\driver\\\\' . ucwords($driver);\n\n        $this->handle = new $class($this);\n    }\n\n    public function ask(Input $input, $question, $default = null, $validator = null)\n    {\n        $question = new Question($question, $default);\n        $question->setValidator($validator);\n\n        return $this->askQuestion($input, $question);\n    }\n\n    public function askHidden(Input $input, $question, $validator = null)\n    {\n        $question = new Question($question);\n\n        $question->setHidden(true);\n        $question->setValidator($validator);\n\n        return $this->askQuestion($input, $question);\n    }\n\n    public function confirm(Input $input, $question, $default = true)\n    {\n        return $this->askQuestion($input, new Confirmation($question, $default));\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function choice(Input $input, $question, array $choices, $default = null)\n    {\n        if (null !== $default) {\n            $values  = array_flip($choices);\n            $default = $values[$default];\n        }\n\n        return $this->askQuestion($input, new Choice($question, $choices, $default));\n    }\n\n    protected function askQuestion(Input $input, Question $question)\n    {\n        $ask    = new Ask($input, $this, $question);\n        $answer = $ask->run();\n\n        if ($input->isInteractive()) {\n            $this->newLine();\n        }\n\n        return $answer;\n    }\n\n    protected function block($style, $message)\n    {\n        $this->writeln(\"<{$style}>{$message}</$style>\");\n    }\n\n    /**\n     * 输出空行\n     * @param int $count\n     */\n    public function newLine($count = 1)\n    {\n        $this->write(str_repeat(PHP_EOL, $count));\n    }\n\n    /**\n     * 输出信息并换行\n     * @param string $messages\n     * @param int    $type\n     */\n    public function writeln($messages, $type = self::OUTPUT_NORMAL)\n    {\n        $this->write($messages, true, $type);\n    }\n\n    /**\n     * 输出信息\n     * @param string $messages\n     * @param bool   $newline\n     * @param int    $type\n     */\n    public function write($messages, $newline = false, $type = self::OUTPUT_NORMAL)\n    {\n        $this->handle->write($messages, $newline, $type);\n    }\n\n    public function renderException(\\Exception $e)\n    {\n        $this->handle->renderException($e);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function setVerbosity($level)\n    {\n        $this->verbosity = (int) $level;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getVerbosity()\n    {\n        return $this->verbosity;\n    }\n\n    public function isQuiet()\n    {\n        return self::VERBOSITY_QUIET === $this->verbosity;\n    }\n\n    public function isVerbose()\n    {\n        return self::VERBOSITY_VERBOSE <= $this->verbosity;\n    }\n\n    public function isVeryVerbose()\n    {\n        return self::VERBOSITY_VERY_VERBOSE <= $this->verbosity;\n    }\n\n    public function isDebug()\n    {\n        return self::VERBOSITY_DEBUG <= $this->verbosity;\n    }\n\n    public function describe($object, array $options = [])\n    {\n        $descriptor = new Descriptor();\n        $options    = array_merge([\n            'raw_text' => false,\n        ], $options);\n\n        $descriptor->describe($this, $object, $options);\n    }\n\n    public function __call($method, $args)\n    {\n        if (in_array($method, $this->styles)) {\n            array_unshift($args, $method);\n            return call_user_func_array([$this, 'block'], $args);\n        }\n\n        if ($this->handle && method_exists($this->handle, $method)) {\n            return call_user_func_array([$this->handle, $method], $args);\n        } else {\n            throw new Exception('method not exists:' . __CLASS__ . '->' . $method);\n        }\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/bin/README.md",
    "content": "console 工具使用 hiddeninput.exe 在 windows 上隐藏密码输入，该二进制文件由第三方提供，相关源码和其他细节可以在 [Hidden Input](https://github.com/Seldaek/hidden-input) 找到。\n"
  },
  {
    "path": "thinkphp/library/think/console/command/Build.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\command;\n\nuse think\\console\\Command;\nuse think\\console\\Input;\nuse think\\console\\input\\Option;\nuse think\\console\\Output;\n\nclass Build extends Command\n{\n\n    /**\n     * {@inheritdoc}\n     */\n    protected function configure()\n    {\n        $this->setName('build')\n            ->setDefinition([\n                new Option('config', null, Option::VALUE_OPTIONAL, \"build.php path\"),\n                new Option('module', null, Option::VALUE_OPTIONAL, \"module name\"),\n            ])\n            ->setDescription('Build Application Dirs');\n    }\n\n    protected function execute(Input $input, Output $output)\n    {\n        if ($input->hasOption('module')) {\n            \\think\\Build::module($input->getOption('module'));\n            $output->writeln(\"Successed\");\n            return;\n        }\n\n        if ($input->hasOption('config')) {\n            $build = include $input->getOption('config');\n        } else {\n            $build = include APP_PATH . 'build.php';\n        }\n        if (empty($build)) {\n            $output->writeln(\"Build Config Is Empty\");\n            return;\n        }\n        \\think\\Build::run($build);\n        $output->writeln(\"Successed\");\n\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/command/Clear.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\nnamespace think\\console\\command;\n\nuse think\\console\\Command;\nuse think\\console\\Input;\nuse think\\console\\input\\Option;\nuse think\\console\\Output;\n\nclass Clear extends Command\n{\n    protected function configure()\n    {\n        // 指令配置\n        $this\n            ->setName('clear')\n            ->addOption('path', 'd', Option::VALUE_OPTIONAL, 'path to clear', null)\n            ->setDescription('Clear runtime file');\n    }\n\n    protected function execute(Input $input, Output $output)\n    {\n        $path = $input->getOption('path') ?: RUNTIME_PATH;\n\n        if (is_dir($path)) {\n            $this->clearPath($path);\n        }\n\n        $output->writeln(\"<info>Clear Successed</info>\");\n    }\n\n    protected function clearPath($path)\n    {\n        $path  = realpath($path) . DS;\n        $files = scandir($path);\n        if ($files) {\n            foreach ($files as $file) {\n                if ('.' != $file && '..' != $file && is_dir($path . $file)) {\n                    $this->clearPath($path . $file);\n                } elseif ('.gitignore' != $file && is_file($path . $file)) {\n                    unlink($path . $file);\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/command/Help.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\command;\n\nuse think\\console\\Command;\nuse think\\console\\Input;\nuse think\\console\\input\\Argument as InputArgument;\nuse think\\console\\input\\Option as InputOption;\nuse think\\console\\Output;\n\nclass Help extends Command\n{\n\n    private $command;\n\n    /**\n     * {@inheritdoc}\n     */\n    protected function configure()\n    {\n        $this->ignoreValidationErrors();\n\n        $this->setName('help')->setDefinition([\n            new InputArgument('command_name', InputArgument::OPTIONAL, 'The command name', 'help'),\n            new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command help'),\n        ])->setDescription('Displays help for a command')->setHelp(<<<EOF\nThe <info>%command.name%</info> command displays help for a given command:\n\n  <info>php %command.full_name% list</info>\n\nTo display the list of available commands, please use the <info>list</info> command.\nEOF\n        );\n    }\n\n    /**\n     * Sets the command.\n     * @param Command $command The command to set\n     */\n    public function setCommand(Command $command)\n    {\n        $this->command = $command;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    protected function execute(Input $input, Output $output)\n    {\n        if (null === $this->command) {\n            $this->command = $this->getConsole()->find($input->getArgument('command_name'));\n        }\n\n        $output->describe($this->command, [\n            'raw_text' => $input->getOption('raw'),\n        ]);\n\n        $this->command = null;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/command/Lists.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\command;\n\nuse think\\console\\Command;\nuse think\\console\\Input;\nuse think\\console\\Output;\nuse think\\console\\input\\Argument as InputArgument;\nuse think\\console\\input\\Option as InputOption;\nuse think\\console\\input\\Definition as InputDefinition;\n\nclass Lists extends Command\n{\n\n    /**\n     * {@inheritdoc}\n     */\n    protected function configure()\n    {\n        $this->setName('list')->setDefinition($this->createDefinition())->setDescription('Lists commands')->setHelp(<<<EOF\nThe <info>%command.name%</info> command lists all commands:\n\n  <info>php %command.full_name%</info>\n\nYou can also display the commands for a specific namespace:\n\n  <info>php %command.full_name% test</info>\n\nIt's also possible to get raw list of commands (useful for embedding command runner):\n\n  <info>php %command.full_name% --raw</info>\nEOF\n        );\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getNativeDefinition()\n    {\n        return $this->createDefinition();\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    protected function execute(Input $input, Output $output)\n    {\n        $output->describe($this->getConsole(), [\n            'raw_text'  => $input->getOption('raw'),\n            'namespace' => $input->getArgument('namespace'),\n        ]);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    private function createDefinition()\n    {\n        return new InputDefinition([\n            new InputArgument('namespace', InputArgument::OPTIONAL, 'The namespace name'),\n            new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw command list')\n        ]);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/command/Make.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: 刘志淳 <chun@engineer.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\command;\n\nuse think\\Config;\nuse think\\console\\Command;\nuse think\\console\\Input;\nuse think\\console\\input\\Argument;\nuse think\\console\\Output;\n\nabstract class Make extends Command\n{\n\n    protected $type;\n\n    abstract protected function getStub();\n\n    protected function configure()\n    {\n        $this->addArgument('name', Argument::REQUIRED, \"The name of the class\");\n    }\n\n    protected function execute(Input $input, Output $output)\n    {\n\n        $name = trim($input->getArgument('name'));\n\n        $classname = $this->getClassName($name);\n\n        $pathname = $this->getPathName($classname);\n\n        if (is_file($pathname)) {\n            $output->writeln('<error>' . $this->type . ' already exists!</error>');\n            return false;\n        }\n\n        if (!is_dir(dirname($pathname))) {\n            mkdir(strtolower(dirname($pathname)), 0755, true);\n        }\n\n        file_put_contents($pathname, $this->buildClass($classname));\n\n        $output->writeln('<info>' . $this->type . ' created successfully.</info>');\n\n    }\n\n    protected function buildClass($name)\n    {\n        $stub = file_get_contents($this->getStub());\n\n        $namespace = trim(implode('\\\\', array_slice(explode('\\\\', $name), 0, -1)), '\\\\');\n\n        $class = str_replace($namespace . '\\\\', '', $name);\n\n        return str_replace(['{%className%}', '{%namespace%}', '{%app_namespace%}'], [\n            $class,\n            $namespace,\n            Config::get('app_namespace')\n        ], $stub);\n\n    }\n\n    protected function getPathName($name)\n    {\n        $name = str_replace(Config::get('app_namespace') . '\\\\', '', $name);\n\n        return APP_PATH . str_replace('\\\\', '/', $name) . '.php';\n    }\n\n    protected function getClassName($name)\n    {\n        $appNamespace = Config::get('app_namespace');\n\n        if (strpos($name, $appNamespace . '\\\\') === 0) {\n            return $name;\n        }\n\n        if (Config::get('app_multi_module')) {\n            if (strpos($name, '/')) {\n                list($module, $name) = explode('/', $name, 2);\n            } else {\n                $module = 'common';\n            }\n        } else {\n            $module = null;\n        }\n\n        if (strpos($name, '/') !== false) {\n            $name = str_replace('/', '\\\\', $name);\n        }\n\n        return $this->getNamespace($appNamespace, $module) . '\\\\' . $name;\n    }\n\n    protected function getNamespace($appNamespace, $module)\n    {\n        return $module ? ($appNamespace . '\\\\' . $module) : $appNamespace;\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/command/make/Controller.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: 刘志淳 <chun@engineer.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\command\\make;\n\nuse think\\Config;\nuse think\\console\\command\\Make;\nuse think\\console\\input\\Option;\n\nclass Controller extends Make\n{\n\n    protected $type = \"Controller\";\n\n    protected function configure()\n    {\n        parent::configure();\n        $this->setName('make:controller')\n            ->addOption('plain', null, Option::VALUE_NONE, 'Generate an empty controller class.')\n            ->setDescription('Create a new resource controller class');\n    }\n\n    protected function getStub()\n    {\n        if ($this->input->getOption('plain')) {\n            return __DIR__ . '/stubs/controller.plain.stub';\n        }\n\n        return __DIR__ . '/stubs/controller.stub';\n    }\n\n    protected function getClassName($name)\n    {\n        return parent::getClassName($name) . (Config::get('controller_suffix') ? ucfirst(Config::get('url_controller_layer')) : '');\n    }\n\n    protected function getNamespace($appNamespace, $module)\n    {\n        return parent::getNamespace($appNamespace, $module) . '\\controller';\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/command/make/Model.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: 刘志淳 <chun@engineer.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\command\\make;\n\nuse think\\console\\command\\Make;\n\nclass Model extends Make\n{\n    protected $type = \"Model\";\n\n    protected function configure()\n    {\n        parent::configure();\n        $this->setName('make:model')\n            ->setDescription('Create a new model class');\n    }\n\n    protected function getStub()\n    {\n        return __DIR__ . '/stubs/model.stub';\n    }\n\n    protected function getNamespace($appNamespace, $module)\n    {\n        return parent::getNamespace($appNamespace, $module) . '\\model';\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/command/make/stubs/controller.plain.stub",
    "content": "<?php\n\nnamespace {%namespace%};\n\nuse think\\Controller;\n\nclass {%className%} extends Controller\n{\n    //\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/command/make/stubs/controller.stub",
    "content": "<?php\n\nnamespace {%namespace%};\n\nuse think\\Controller;\nuse think\\Request;\n\nclass {%className%} extends Controller\n{\n    /**\n     * 显示资源列表\n     *\n     * @return \\think\\Response\n     */\n    public function index()\n    {\n        //\n    }\n\n    /**\n     * 显示创建资源表单页.\n     *\n     * @return \\think\\Response\n     */\n    public function create()\n    {\n        //\n    }\n\n    /**\n     * 保存新建的资源\n     *\n     * @param  \\think\\Request  $request\n     * @return \\think\\Response\n     */\n    public function save(Request $request)\n    {\n        //\n    }\n\n    /**\n     * 显示指定的资源\n     *\n     * @param  int  $id\n     * @return \\think\\Response\n     */\n    public function read($id)\n    {\n        //\n    }\n\n    /**\n     * 显示编辑资源表单页.\n     *\n     * @param  int  $id\n     * @return \\think\\Response\n     */\n    public function edit($id)\n    {\n        //\n    }\n\n    /**\n     * 保存更新的资源\n     *\n     * @param  \\think\\Request  $request\n     * @param  int  $id\n     * @return \\think\\Response\n     */\n    public function update(Request $request, $id)\n    {\n        //\n    }\n\n    /**\n     * 删除指定资源\n     *\n     * @param  int  $id\n     * @return \\think\\Response\n     */\n    public function delete($id)\n    {\n        //\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/command/make/stubs/model.stub",
    "content": "<?php\n\nnamespace {%namespace%};\n\nuse think\\Model;\n\nclass {%className%} extends Model\n{\n    //\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/command/optimize/Autoload.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\nnamespace think\\console\\command\\optimize;\n\nuse think\\App;\nuse think\\Config;\nuse think\\console\\Command;\nuse think\\console\\Input;\nuse think\\console\\Output;\n\nclass Autoload extends Command\n{\n\n    protected function configure()\n    {\n        $this->setName('optimize:autoload')\n            ->setDescription('Optimizes PSR0 and PSR4 packages to be loaded with classmaps too, good for production.');\n    }\n\n    protected function execute(Input $input, Output $output)\n    {\n\n        $classmapFile = <<<EOF\n<?php\n/**\n * 类库映射\n */\n\nreturn [\n\nEOF;\n\n        $namespacesToScan = [\n            App::$namespace . '\\\\' => realpath(rtrim(APP_PATH)),\n            'think\\\\'              => LIB_PATH . 'think',\n            'behavior\\\\'           => LIB_PATH . 'behavior',\n            'traits\\\\'             => LIB_PATH . 'traits',\n            ''                     => realpath(rtrim(EXTEND_PATH)),\n        ];\n\n        $root_namespace = Config::get('root_namespace');\n        foreach ($root_namespace as $namespace => $dir) {\n            $namespacesToScan[$namespace . '\\\\'] = realpath($dir);\n        }\n\n        krsort($namespacesToScan);\n        $classMap = [];\n        foreach ($namespacesToScan as $namespace => $dir) {\n\n            if (!is_dir($dir)) {\n                continue;\n            }\n\n            $namespaceFilter = $namespace === '' ? null : $namespace;\n            $classMap        = $this->addClassMapCode($dir, $namespaceFilter, $classMap);\n        }\n\n        ksort($classMap);\n        foreach ($classMap as $class => $code) {\n            $classmapFile .= '    ' . var_export($class, true) . ' => ' . $code;\n        }\n        $classmapFile .= \"];\\n\";\n\n        if (!is_dir(RUNTIME_PATH)) {\n            @mkdir(RUNTIME_PATH, 0755, true);\n        }\n\n        file_put_contents(RUNTIME_PATH . 'classmap' . EXT, $classmapFile);\n\n        $output->writeln('<info>Succeed!</info>');\n    }\n\n    protected function addClassMapCode($dir, $namespace, $classMap)\n    {\n        foreach ($this->createMap($dir, $namespace) as $class => $path) {\n\n            $pathCode = $this->getPathCode($path) . \",\\n\";\n\n            if (!isset($classMap[$class])) {\n                $classMap[$class] = $pathCode;\n            } elseif ($classMap[$class] !== $pathCode && !preg_match('{/(test|fixture|example|stub)s?/}i', strtr($classMap[$class] . ' ' . $path, '\\\\', '/'))) {\n                $this->output->writeln(\n                    '<warning>Warning: Ambiguous class resolution, \"' . $class . '\"' .\n                    ' was found in both \"' . str_replace([\"',\\n\"], [\n                        '',\n                    ], $classMap[$class]) . '\" and \"' . $path . '\", the first will be used.</warning>'\n                );\n            }\n        }\n        return $classMap;\n    }\n\n    protected function getPathCode($path)\n    {\n\n        $baseDir    = '';\n        $libPath    = $this->normalizePath(realpath(LIB_PATH));\n        $appPath    = $this->normalizePath(realpath(APP_PATH));\n        $extendPath = $this->normalizePath(realpath(EXTEND_PATH));\n        $rootPath   = $this->normalizePath(realpath(ROOT_PATH));\n        $path       = $this->normalizePath($path);\n\n        if ($libPath !== null && strpos($path, $libPath . '/') === 0) {\n            $path    = substr($path, strlen(LIB_PATH));\n            $baseDir = 'LIB_PATH';\n        } elseif ($appPath !== null && strpos($path, $appPath . '/') === 0) {\n            $path    = substr($path, strlen($appPath) + 1);\n            $baseDir = 'APP_PATH';\n        } elseif ($extendPath !== null && strpos($path, $extendPath . '/') === 0) {\n            $path    = substr($path, strlen($extendPath) + 1);\n            $baseDir = 'EXTEND_PATH';\n        } elseif ($rootPath !== null && strpos($path, $rootPath . '/') === 0) {\n            $path    = substr($path, strlen($rootPath) + 1);\n            $baseDir = 'ROOT_PATH';\n        }\n\n        if ($path !== false) {\n            $baseDir .= \" . \";\n        }\n\n        return $baseDir . (($path !== false) ? var_export($path, true) : \"\");\n    }\n\n    protected function normalizePath($path)\n    {\n        if ($path === false) {\n            return;\n        }\n        $parts    = [];\n        $path     = strtr($path, '\\\\', '/');\n        $prefix   = '';\n        $absolute = false;\n\n        if (preg_match('{^([0-9a-z]+:(?://(?:[a-z]:)?)?)}i', $path, $match)) {\n            $prefix = $match[1];\n            $path   = substr($path, strlen($prefix));\n        }\n\n        if (substr($path, 0, 1) === '/') {\n            $absolute = true;\n            $path     = substr($path, 1);\n        }\n\n        $up = false;\n        foreach (explode('/', $path) as $chunk) {\n            if ('..' === $chunk && ($absolute || $up)) {\n                array_pop($parts);\n                $up = !(empty($parts) || '..' === end($parts));\n            } elseif ('.' !== $chunk && '' !== $chunk) {\n                $parts[] = $chunk;\n                $up      = '..' !== $chunk;\n            }\n        }\n\n        return $prefix . ($absolute ? '/' : '') . implode('/', $parts);\n    }\n\n    protected function createMap($path, $namespace = null)\n    {\n        if (is_string($path)) {\n            if (is_file($path)) {\n                $path = [new \\SplFileInfo($path)];\n            } elseif (is_dir($path)) {\n\n                $objects = new \\RecursiveIteratorIterator(new \\RecursiveDirectoryIterator($path), \\RecursiveIteratorIterator::SELF_FIRST);\n\n                $path = [];\n\n                /** @var \\SplFileInfo $object */\n                foreach ($objects as $object) {\n                    if ($object->isFile() && $object->getExtension() == 'php') {\n                        $path[] = $object;\n                    }\n                }\n            } else {\n                throw new \\RuntimeException(\n                    'Could not scan for classes inside \"' . $path .\n                    '\" which does not appear to be a file nor a folder'\n                );\n            }\n        }\n\n        $map = [];\n\n        /** @var \\SplFileInfo $file */\n        foreach ($path as $file) {\n            $filePath = $file->getRealPath();\n\n            if (pathinfo($filePath, PATHINFO_EXTENSION) != 'php') {\n                continue;\n            }\n\n            $classes = $this->findClasses($filePath);\n\n            foreach ($classes as $class) {\n                if (null !== $namespace && 0 !== strpos($class, $namespace)) {\n                    continue;\n                }\n\n                if (!isset($map[$class])) {\n                    $map[$class] = $filePath;\n                } elseif ($map[$class] !== $filePath && !preg_match('{/(test|fixture|example|stub)s?/}i', strtr($map[$class] . ' ' . $filePath, '\\\\', '/'))) {\n                    $this->output->writeln(\n                        '<warning>Warning: Ambiguous class resolution, \"' . $class . '\"' .\n                        ' was found in both \"' . $map[$class] . '\" and \"' . $filePath . '\", the first will be used.</warning>'\n                    );\n                }\n            }\n        }\n\n        return $map;\n    }\n\n    protected function findClasses($path)\n    {\n        $extraTypes = '|trait';\n\n        $contents = @php_strip_whitespace($path);\n        if (!$contents) {\n            if (!file_exists($path)) {\n                $message = 'File at \"%s\" does not exist, check your classmap definitions';\n            } elseif (!is_readable($path)) {\n                $message = 'File at \"%s\" is not readable, check its permissions';\n            } elseif ('' === trim(file_get_contents($path))) {\n                return [];\n            } else {\n                $message = 'File at \"%s\" could not be parsed as PHP, it may be binary or corrupted';\n            }\n            $error = error_get_last();\n            if (isset($error['message'])) {\n                $message .= PHP_EOL . 'The following message may be helpful:' . PHP_EOL . $error['message'];\n            }\n            throw new \\RuntimeException(sprintf($message, $path));\n        }\n\n        if (!preg_match('{\\b(?:class|interface' . $extraTypes . ')\\s}i', $contents)) {\n            return [];\n        }\n\n        // strip heredocs/nowdocs\n        $contents = preg_replace('{<<<\\s*(\\'?)(\\w+)\\\\1(?:\\r\\n|\\n|\\r)(?:.*?)(?:\\r\\n|\\n|\\r)\\\\2(?=\\r\\n|\\n|\\r|;)}s', 'null', $contents);\n        // strip strings\n        $contents = preg_replace('{\"[^\"\\\\\\\\]*+(\\\\\\\\.[^\"\\\\\\\\]*+)*+\"|\\'[^\\'\\\\\\\\]*+(\\\\\\\\.[^\\'\\\\\\\\]*+)*+\\'}s', 'null', $contents);\n        // strip leading non-php code if needed\n        if (substr($contents, 0, 2) !== '<?') {\n            $contents = preg_replace('{^.+?<\\?}s', '<?', $contents, 1, $replacements);\n            if ($replacements === 0) {\n                return [];\n            }\n        }\n        // strip non-php blocks in the file\n        $contents = preg_replace('{\\?>.+<\\?}s', '?><?', $contents);\n        // strip trailing non-php code if needed\n        $pos = strrpos($contents, '?>');\n        if (false !== $pos && false === strpos(substr($contents, $pos), '<?')) {\n            $contents = substr($contents, 0, $pos);\n        }\n\n        preg_match_all('{\n            (?:\n                 \\b(?<![\\$:>])(?P<type>class|interface' . $extraTypes . ') \\s++ (?P<name>[a-zA-Z_\\x7f-\\xff:][a-zA-Z0-9_\\x7f-\\xff:\\-]*+)\n               | \\b(?<![\\$:>])(?P<ns>namespace) (?P<nsname>\\s++[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+(?:\\s*+\\\\\\\\\\s*+[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*+)*+)? \\s*+ [\\{;]\n            )\n        }ix', $contents, $matches);\n\n        $classes   = [];\n        $namespace = '';\n\n        for ($i = 0, $len = count($matches['type']); $i < $len; $i++) {\n            if (!empty($matches['ns'][$i])) {\n                $namespace = str_replace([' ', \"\\t\", \"\\r\", \"\\n\"], '', $matches['nsname'][$i]) . '\\\\';\n            } else {\n                $name = $matches['name'][$i];\n                if ($name[0] === ':') {\n                    $name = 'xhp' . substr(str_replace(['-', ':'], ['_', '__'], $name), 1);\n                } elseif ($matches['type'][$i] === 'enum') {\n                    $name = rtrim($name, ':');\n                }\n                $classes[] = ltrim($namespace . $name, '\\\\');\n            }\n        }\n\n        return $classes;\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/command/optimize/Config.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\nnamespace think\\console\\command\\optimize;\n\nuse think\\Config as ThinkConfig;\nuse think\\console\\Command;\nuse think\\console\\Input;\nuse think\\console\\input\\Argument;\nuse think\\console\\Output;\n\nclass Config extends Command\n{\n    /** @var  Output */\n    protected $output;\n\n    protected function configure()\n    {\n        $this->setName('optimize:config')\n            ->addArgument('module', Argument::OPTIONAL, 'Build module config cache .')\n            ->setDescription('Build config and common file cache.');\n    }\n\n    protected function execute(Input $input, Output $output)\n    {\n        if ($input->hasArgument('module')) {\n            $module = $input->getArgument('module') . DS;\n        } else {\n            $module = '';\n        }\n\n        $content = '<?php ' . PHP_EOL . $this->buildCacheContent($module);\n\n        if (!is_dir(RUNTIME_PATH . $module)) {\n            @mkdir(RUNTIME_PATH . $module, 0755, true);\n        }\n\n        file_put_contents(RUNTIME_PATH . $module . 'init' . EXT, $content);\n\n        $output->writeln('<info>Succeed!</info>');\n    }\n\n    protected function buildCacheContent($module)\n    {\n        $content = '';\n        $path    = realpath(APP_PATH . $module) . DS;\n\n        if ($module) {\n            // 加载模块配置\n            $config = ThinkConfig::load(CONF_PATH . $module . 'config' . CONF_EXT);\n\n            // 读取数据库配置文件\n            $filename = CONF_PATH . $module . 'database' . CONF_EXT;\n            ThinkConfig::load($filename, 'database');\n\n            // 加载应用状态配置\n            if ($config['app_status']) {\n                $config = ThinkConfig::load(CONF_PATH . $module . $config['app_status'] . CONF_EXT);\n            }\n            // 读取扩展配置文件\n            if (is_dir(CONF_PATH . $module . 'extra')) {\n                $dir   = CONF_PATH . $module . 'extra';\n                $files = scandir($dir);\n                foreach ($files as $file) {\n                    if (strpos($file, CONF_EXT)) {\n                        $filename = $dir . DS . $file;\n                        ThinkConfig::load($filename, pathinfo($file, PATHINFO_FILENAME));\n                    }\n                }\n            }\n        }\n\n        // 加载行为扩展文件\n        if (is_file(CONF_PATH . $module . 'tags' . EXT)) {\n            $content .= '\\think\\Hook::import(' . (var_export(include CONF_PATH . $module . 'tags' . EXT, true)) . ');' . PHP_EOL;\n        }\n\n        // 加载公共文件\n        if (is_file($path . 'common' . EXT)) {\n            $content .= substr(php_strip_whitespace($path . 'common' . EXT), 5) . PHP_EOL;\n        }\n\n        $content .= '\\think\\Config::set(' . var_export(ThinkConfig::get(), true) . ');';\n        return $content;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/command/optimize/Route.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\nnamespace think\\console\\command\\optimize;\n\nuse think\\console\\Command;\nuse think\\console\\Input;\nuse think\\console\\Output;\n\nclass Route extends Command\n{\n    /** @var  Output */\n    protected $output;\n\n    protected function configure()\n    {\n        $this->setName('optimize:route')\n            ->setDescription('Build route cache.');\n    }\n\n    protected function execute(Input $input, Output $output)\n    {\n        file_put_contents(RUNTIME_PATH . 'route.php', $this->buildRouteCache());\n        $output->writeln('<info>Succeed!</info>');\n    }\n\n    protected function buildRouteCache()\n    {\n        $files = \\think\\Config::get('route_config_file');\n        foreach ($files as $file) {\n            if (is_file(CONF_PATH . $file . CONF_EXT)) {\n                $config = include CONF_PATH . $file . CONF_EXT;\n                if (is_array($config)) {\n                    \\think\\Route::import($config);\n                }\n            }\n        }\n        $rules = \\think\\Route::rules(true);\n        array_walk_recursive($rules, [$this, 'buildClosure']);\n        $content = '<?php ' . PHP_EOL . 'return ';\n        $content .= var_export($rules, true) . ';';\n        $content = str_replace(['\\'[__start__', '__end__]\\''], '', stripcslashes($content));\n        return $content;\n    }\n\n    protected function buildClosure(&$value)\n    {\n        if ($value instanceof \\Closure) {\n            $reflection = new \\ReflectionFunction($value);\n            $startLine  = $reflection->getStartLine();\n            $endLine    = $reflection->getEndLine();\n            $file       = $reflection->getFileName();\n            $item       = file($file);\n            $content    = '';\n            for ($i = $startLine - 1; $i <= $endLine - 1; $i++) {\n                $content .= $item[$i];\n            }\n            $start = strpos($content, 'function');\n            $end   = strrpos($content, '}');\n            $value = '[__start__' . substr($content, $start, $end - $start + 1) . '__end__]';\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/command/optimize/Schema.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\nnamespace think\\console\\command\\optimize;\n\nuse think\\App;\nuse think\\console\\Command;\nuse think\\console\\Input;\nuse think\\console\\input\\Option;\nuse think\\console\\Output;\nuse think\\Db;\n\nclass Schema extends Command\n{\n    /** @var  Output */\n    protected $output;\n\n    protected function configure()\n    {\n        $this->setName('optimize:schema')\n            ->addOption('config', null, Option::VALUE_REQUIRED, 'db config .')\n            ->addOption('db', null, Option::VALUE_REQUIRED, 'db name .')\n            ->addOption('table', null, Option::VALUE_REQUIRED, 'table name .')\n            ->addOption('module', null, Option::VALUE_REQUIRED, 'module name .')\n            ->setDescription('Build database schema cache.');\n    }\n\n    protected function execute(Input $input, Output $output)\n    {\n        if (!is_dir(RUNTIME_PATH . 'schema')) {\n            @mkdir(RUNTIME_PATH . 'schema', 0755, true);\n        }\n        $config = [];\n        if ($input->hasOption('config')) {\n            $config = $input->getOption('config');\n        }\n        if ($input->hasOption('module')) {\n            $module = $input->getOption('module');\n            // 读取模型\n            $list = scandir(APP_PATH . $module . DS . 'model');\n            $app  = App::$namespace;\n            foreach ($list as $file) {\n                if (0 === strpos($file, '.')) {\n                    continue;\n                }\n                $class = '\\\\' . $app . '\\\\' . $module . '\\\\model\\\\' . pathinfo($file, PATHINFO_FILENAME);\n                $this->buildModelSchema($class);\n            }\n            $output->writeln('<info>Succeed!</info>');\n            return;\n        } elseif ($input->hasOption('table')) {\n            $table = $input->getOption('table');\n            if (!strpos($table, '.')) {\n                $dbName = Db::connect($config)->getConfig('database');\n            }\n            $tables[] = $table;\n        } elseif ($input->hasOption('db')) {\n            $dbName = $input->getOption('db');\n            $tables = Db::connect($config)->getTables($dbName);\n        } elseif (!\\think\\Config::get('app_multi_module')) {\n            $app  = App::$namespace;\n            $list = scandir(APP_PATH . 'model');\n            foreach ($list as $file) {\n                if (0 === strpos($file, '.')) {\n                    continue;\n                }\n                $class = '\\\\' . $app . '\\\\model\\\\' . pathinfo($file, PATHINFO_FILENAME);\n                $this->buildModelSchema($class);\n            }\n            $output->writeln('<info>Succeed!</info>');\n            return;\n        } else {\n            $tables = Db::connect($config)->getTables();\n        }\n\n        $db = isset($dbName) ? $dbName . '.' : '';\n        $this->buildDataBaseSchema($tables, $db, $config);\n\n        $output->writeln('<info>Succeed!</info>');\n    }\n\n    protected function buildModelSchema($class)\n    {\n        $reflect = new \\ReflectionClass($class);\n        if (!$reflect->isAbstract() && $reflect->isSubclassOf('\\think\\Model')) {\n            $table   = $class::getTable();\n            $dbName  = $class::getConfig('database');\n            $content = '<?php ' . PHP_EOL . 'return ';\n            $info    = $class::getConnection()->getFields($table);\n            $content .= var_export($info, true) . ';';\n            file_put_contents(RUNTIME_PATH . 'schema' . DS . $dbName . '.' . $table . EXT, $content);\n        }\n    }\n\n    protected function buildDataBaseSchema($tables, $db, $config)\n    {\n        if ('' == $db) {\n            $dbName = Db::connect($config)->getConfig('database') . '.';\n        } else {\n            $dbName = $db;\n        }\n        foreach ($tables as $table) {\n            $content = '<?php ' . PHP_EOL . 'return ';\n            $info    = Db::connect($config)->getFields($db . $table);\n            $content .= var_export($info, true) . ';';\n            file_put_contents(RUNTIME_PATH . 'schema' . DS . $dbName . $table . EXT, $content);\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/input/Argument.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\input;\n\nclass Argument\n{\n\n    const REQUIRED = 1;\n    const OPTIONAL = 2;\n    const IS_ARRAY = 4;\n\n    private $name;\n    private $mode;\n    private $default;\n    private $description;\n\n    /**\n     * 构造方法\n     * @param string $name        参数名\n     * @param int    $mode        参数类型: self::REQUIRED 或者 self::OPTIONAL\n     * @param string $description 描述\n     * @param mixed  $default     默认值 (仅 self::OPTIONAL 类型有效)\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct($name, $mode = null, $description = '', $default = null)\n    {\n        if (null === $mode) {\n            $mode = self::OPTIONAL;\n        } elseif (!is_int($mode) || $mode > 7 || $mode < 1) {\n            throw new \\InvalidArgumentException(sprintf('Argument mode \"%s\" is not valid.', $mode));\n        }\n\n        $this->name        = $name;\n        $this->mode        = $mode;\n        $this->description = $description;\n\n        $this->setDefault($default);\n    }\n\n    /**\n     * 获取参数名\n     * @return string\n     */\n    public function getName()\n    {\n        return $this->name;\n    }\n\n    /**\n     * 是否必须\n     * @return bool\n     */\n    public function isRequired()\n    {\n        return self::REQUIRED === (self::REQUIRED & $this->mode);\n    }\n\n    /**\n     * 该参数是否接受数组\n     * @return bool\n     */\n    public function isArray()\n    {\n        return self::IS_ARRAY === (self::IS_ARRAY & $this->mode);\n    }\n\n    /**\n     * 设置默认值\n     * @param mixed $default 默认值\n     * @throws \\LogicException\n     */\n    public function setDefault($default = null)\n    {\n        if (self::REQUIRED === $this->mode && null !== $default) {\n            throw new \\LogicException('Cannot set a default value except for InputArgument::OPTIONAL mode.');\n        }\n\n        if ($this->isArray()) {\n            if (null === $default) {\n                $default = [];\n            } elseif (!is_array($default)) {\n                throw new \\LogicException('A default value for an array argument must be an array.');\n            }\n        }\n\n        $this->default = $default;\n    }\n\n    /**\n     * 获取默认值\n     * @return mixed\n     */\n    public function getDefault()\n    {\n        return $this->default;\n    }\n\n    /**\n     * 获取描述\n     * @return string\n     */\n    public function getDescription()\n    {\n        return $this->description;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/input/Definition.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\input;\n\nclass Definition\n{\n\n    /**\n     * @var Argument[]\n     */\n    private $arguments;\n\n    private $requiredCount;\n    private $hasAnArrayArgument = false;\n    private $hasOptional;\n\n    /**\n     * @var Option[]\n     */\n    private $options;\n    private $shortcuts;\n\n    /**\n     * 构造方法\n     * @param array $definition\n     * @api\n     */\n    public function __construct(array $definition = [])\n    {\n        $this->setDefinition($definition);\n    }\n\n    /**\n     * 设置指令的定义\n     * @param array $definition 定义的数组\n     */\n    public function setDefinition(array $definition)\n    {\n        $arguments = [];\n        $options   = [];\n        foreach ($definition as $item) {\n            if ($item instanceof Option) {\n                $options[] = $item;\n            } else {\n                $arguments[] = $item;\n            }\n        }\n\n        $this->setArguments($arguments);\n        $this->setOptions($options);\n    }\n\n    /**\n     * 设置参数\n     * @param Argument[] $arguments 参数数组\n     */\n    public function setArguments($arguments = [])\n    {\n        $this->arguments          = [];\n        $this->requiredCount      = 0;\n        $this->hasOptional        = false;\n        $this->hasAnArrayArgument = false;\n        $this->addArguments($arguments);\n    }\n\n    /**\n     * 添加参数\n     * @param Argument[] $arguments 参数数组\n     * @api\n     */\n    public function addArguments($arguments = [])\n    {\n        if (null !== $arguments) {\n            foreach ($arguments as $argument) {\n                $this->addArgument($argument);\n            }\n        }\n    }\n\n    /**\n     * 添加一个参数\n     * @param Argument $argument 参数\n     * @throws \\LogicException\n     */\n    public function addArgument(Argument $argument)\n    {\n        if (isset($this->arguments[$argument->getName()])) {\n            throw new \\LogicException(sprintf('An argument with name \"%s\" already exists.', $argument->getName()));\n        }\n\n        if ($this->hasAnArrayArgument) {\n            throw new \\LogicException('Cannot add an argument after an array argument.');\n        }\n\n        if ($argument->isRequired() && $this->hasOptional) {\n            throw new \\LogicException('Cannot add a required argument after an optional one.');\n        }\n\n        if ($argument->isArray()) {\n            $this->hasAnArrayArgument = true;\n        }\n\n        if ($argument->isRequired()) {\n            ++$this->requiredCount;\n        } else {\n            $this->hasOptional = true;\n        }\n\n        $this->arguments[$argument->getName()] = $argument;\n    }\n\n    /**\n     * 根据名称或者位置获取参数\n     * @param string|int $name 参数名或者位置\n     * @return Argument 参数\n     * @throws \\InvalidArgumentException\n     */\n    public function getArgument($name)\n    {\n        if (!$this->hasArgument($name)) {\n            throw new \\InvalidArgumentException(sprintf('The \"%s\" argument does not exist.', $name));\n        }\n\n        $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;\n\n        return $arguments[$name];\n    }\n\n    /**\n     * 根据名称或位置检查是否具有某个参数\n     * @param string|int $name 参数名或者位置\n     * @return bool\n     * @api\n     */\n    public function hasArgument($name)\n    {\n        $arguments = is_int($name) ? array_values($this->arguments) : $this->arguments;\n\n        return isset($arguments[$name]);\n    }\n\n    /**\n     * 获取所有的参数\n     * @return Argument[] 参数数组\n     */\n    public function getArguments()\n    {\n        return $this->arguments;\n    }\n\n    /**\n     * 获取参数数量\n     * @return int\n     */\n    public function getArgumentCount()\n    {\n        return $this->hasAnArrayArgument ? PHP_INT_MAX : count($this->arguments);\n    }\n\n    /**\n     * 获取必填的参数的数量\n     * @return int\n     */\n    public function getArgumentRequiredCount()\n    {\n        return $this->requiredCount;\n    }\n\n    /**\n     * 获取参数默认值\n     * @return array\n     */\n    public function getArgumentDefaults()\n    {\n        $values = [];\n        foreach ($this->arguments as $argument) {\n            $values[$argument->getName()] = $argument->getDefault();\n        }\n\n        return $values;\n    }\n\n    /**\n     * 设置选项\n     * @param Option[] $options 选项数组\n     */\n    public function setOptions($options = [])\n    {\n        $this->options   = [];\n        $this->shortcuts = [];\n        $this->addOptions($options);\n    }\n\n    /**\n     * 添加选项\n     * @param Option[] $options 选项数组\n     * @api\n     */\n    public function addOptions($options = [])\n    {\n        foreach ($options as $option) {\n            $this->addOption($option);\n        }\n    }\n\n    /**\n     * 添加一个选项\n     * @param Option $option 选项\n     * @throws \\LogicException\n     * @api\n     */\n    public function addOption(Option $option)\n    {\n        if (isset($this->options[$option->getName()]) && !$option->equals($this->options[$option->getName()])) {\n            throw new \\LogicException(sprintf('An option named \"%s\" already exists.', $option->getName()));\n        }\n\n        if ($option->getShortcut()) {\n            foreach (explode('|', $option->getShortcut()) as $shortcut) {\n                if (isset($this->shortcuts[$shortcut])\n                    && !$option->equals($this->options[$this->shortcuts[$shortcut]])\n                ) {\n                    throw new \\LogicException(sprintf('An option with shortcut \"%s\" already exists.', $shortcut));\n                }\n            }\n        }\n\n        $this->options[$option->getName()] = $option;\n        if ($option->getShortcut()) {\n            foreach (explode('|', $option->getShortcut()) as $shortcut) {\n                $this->shortcuts[$shortcut] = $option->getName();\n            }\n        }\n    }\n\n    /**\n     * 根据名称获取选项\n     * @param string $name 选项名\n     * @return Option\n     * @throws \\InvalidArgumentException\n     * @api\n     */\n    public function getOption($name)\n    {\n        if (!$this->hasOption($name)) {\n            throw new \\InvalidArgumentException(sprintf('The \"--%s\" option does not exist.', $name));\n        }\n\n        return $this->options[$name];\n    }\n\n    /**\n     * 根据名称检查是否有这个选项\n     * @param string $name 选项名\n     * @return bool\n     * @api\n     */\n    public function hasOption($name)\n    {\n        return isset($this->options[$name]);\n    }\n\n    /**\n     * 获取所有选项\n     * @return Option[]\n     * @api\n     */\n    public function getOptions()\n    {\n        return $this->options;\n    }\n\n    /**\n     * 根据名称检查某个选项是否有短名称\n     * @param string $name 短名称\n     * @return bool\n     */\n    public function hasShortcut($name)\n    {\n        return isset($this->shortcuts[$name]);\n    }\n\n    /**\n     * 根据短名称获取选项\n     * @param string $shortcut 短名称\n     * @return Option\n     */\n    public function getOptionForShortcut($shortcut)\n    {\n        return $this->getOption($this->shortcutToName($shortcut));\n    }\n\n    /**\n     * 获取所有选项的默认值\n     * @return array\n     */\n    public function getOptionDefaults()\n    {\n        $values = [];\n        foreach ($this->options as $option) {\n            $values[$option->getName()] = $option->getDefault();\n        }\n\n        return $values;\n    }\n\n    /**\n     * 根据短名称获取选项名\n     * @param string $shortcut 短名称\n     * @return string\n     * @throws \\InvalidArgumentException\n     */\n    private function shortcutToName($shortcut)\n    {\n        if (!isset($this->shortcuts[$shortcut])) {\n            throw new \\InvalidArgumentException(sprintf('The \"-%s\" option does not exist.', $shortcut));\n        }\n\n        return $this->shortcuts[$shortcut];\n    }\n\n    /**\n     * 获取该指令的介绍\n     * @param bool $short 是否简洁介绍\n     * @return string\n     */\n    public function getSynopsis($short = false)\n    {\n        $elements = [];\n\n        if ($short && $this->getOptions()) {\n            $elements[] = '[options]';\n        } elseif (!$short) {\n            foreach ($this->getOptions() as $option) {\n                $value = '';\n                if ($option->acceptValue()) {\n                    $value = sprintf(' %s%s%s', $option->isValueOptional() ? '[' : '', strtoupper($option->getName()), $option->isValueOptional() ? ']' : '');\n                }\n\n                $shortcut   = $option->getShortcut() ? sprintf('-%s|', $option->getShortcut()) : '';\n                $elements[] = sprintf('[%s--%s%s]', $shortcut, $option->getName(), $value);\n            }\n        }\n\n        if (count($elements) && $this->getArguments()) {\n            $elements[] = '[--]';\n        }\n\n        foreach ($this->getArguments() as $argument) {\n            $element = '<' . $argument->getName() . '>';\n            if (!$argument->isRequired()) {\n                $element = '[' . $element . ']';\n            } elseif ($argument->isArray()) {\n                $element .= ' (' . $element . ')';\n            }\n\n            if ($argument->isArray()) {\n                $element .= '...';\n            }\n\n            $elements[] = $element;\n        }\n\n        return implode(' ', $elements);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/input/Option.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\input;\n\nclass Option\n{\n\n    const VALUE_NONE     = 1;\n    const VALUE_REQUIRED = 2;\n    const VALUE_OPTIONAL = 4;\n    const VALUE_IS_ARRAY = 8;\n\n    private $name;\n    private $shortcut;\n    private $mode;\n    private $default;\n    private $description;\n\n    /**\n     * 构造方法\n     * @param string       $name        选项名\n     * @param string|array $shortcut    短名称,多个用|隔开或者使用数组\n     * @param int          $mode        选项类型(可选类型为 self::VALUE_*)\n     * @param string       $description 描述\n     * @param mixed        $default     默认值 (类型为 self::VALUE_REQUIRED 或者 self::VALUE_NONE 的时候必须为null)\n     * @throws \\InvalidArgumentException\n     */\n    public function __construct($name, $shortcut = null, $mode = null, $description = '', $default = null)\n    {\n        if (0 === strpos($name, '--')) {\n            $name = substr($name, 2);\n        }\n\n        if (empty($name)) {\n            throw new \\InvalidArgumentException('An option name cannot be empty.');\n        }\n\n        if (empty($shortcut)) {\n            $shortcut = null;\n        }\n\n        if (null !== $shortcut) {\n            if (is_array($shortcut)) {\n                $shortcut = implode('|', $shortcut);\n            }\n            $shortcuts = preg_split('{(\\|)-?}', ltrim($shortcut, '-'));\n            $shortcuts = array_filter($shortcuts);\n            $shortcut  = implode('|', $shortcuts);\n\n            if (empty($shortcut)) {\n                throw new \\InvalidArgumentException('An option shortcut cannot be empty.');\n            }\n        }\n\n        if (null === $mode) {\n            $mode = self::VALUE_NONE;\n        } elseif (!is_int($mode) || $mode > 15 || $mode < 1) {\n            throw new \\InvalidArgumentException(sprintf('Option mode \"%s\" is not valid.', $mode));\n        }\n\n        $this->name        = $name;\n        $this->shortcut    = $shortcut;\n        $this->mode        = $mode;\n        $this->description = $description;\n\n        if ($this->isArray() && !$this->acceptValue()) {\n            throw new \\InvalidArgumentException('Impossible to have an option mode VALUE_IS_ARRAY if the option does not accept a value.');\n        }\n\n        $this->setDefault($default);\n    }\n\n    /**\n     * 获取短名称\n     * @return string\n     */\n    public function getShortcut()\n    {\n        return $this->shortcut;\n    }\n\n    /**\n     * 获取选项名\n     * @return string\n     */\n    public function getName()\n    {\n        return $this->name;\n    }\n\n    /**\n     * 是否可以设置值\n     * @return bool 类型不是 self::VALUE_NONE 的时候返回true,其他均返回false\n     */\n    public function acceptValue()\n    {\n        return $this->isValueRequired() || $this->isValueOptional();\n    }\n\n    /**\n     * 是否必须\n     * @return bool 类型是 self::VALUE_REQUIRED 的时候返回true,其他均返回false\n     */\n    public function isValueRequired()\n    {\n        return self::VALUE_REQUIRED === (self::VALUE_REQUIRED & $this->mode);\n    }\n\n    /**\n     * 是否可选\n     * @return bool 类型是 self::VALUE_OPTIONAL 的时候返回true,其他均返回false\n     */\n    public function isValueOptional()\n    {\n        return self::VALUE_OPTIONAL === (self::VALUE_OPTIONAL & $this->mode);\n    }\n\n    /**\n     * 选项值是否接受数组\n     * @return bool 类型是 self::VALUE_IS_ARRAY 的时候返回true,其他均返回false\n     */\n    public function isArray()\n    {\n        return self::VALUE_IS_ARRAY === (self::VALUE_IS_ARRAY & $this->mode);\n    }\n\n    /**\n     * 设置默认值\n     * @param mixed $default 默认值\n     * @throws \\LogicException\n     */\n    public function setDefault($default = null)\n    {\n        if (self::VALUE_NONE === (self::VALUE_NONE & $this->mode) && null !== $default) {\n            throw new \\LogicException('Cannot set a default value when using InputOption::VALUE_NONE mode.');\n        }\n\n        if ($this->isArray()) {\n            if (null === $default) {\n                $default = [];\n            } elseif (!is_array($default)) {\n                throw new \\LogicException('A default value for an array option must be an array.');\n            }\n        }\n\n        $this->default = $this->acceptValue() ? $default : false;\n    }\n\n    /**\n     * 获取默认值\n     * @return mixed\n     */\n    public function getDefault()\n    {\n        return $this->default;\n    }\n\n    /**\n     * 获取描述文字\n     * @return string\n     */\n    public function getDescription()\n    {\n        return $this->description;\n    }\n\n    /**\n     * 检查所给选项是否是当前这个\n     * @param Option $option\n     * @return bool\n     */\n    public function equals(Option $option)\n    {\n        return $option->getName() === $this->getName()\n        && $option->getShortcut() === $this->getShortcut()\n        && $option->getDefault() === $this->getDefault()\n        && $option->isArray() === $this->isArray()\n        && $option->isValueRequired() === $this->isValueRequired()\n        && $option->isValueOptional() === $this->isValueOptional();\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/output/Ask.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\output;\n\nuse think\\console\\Input;\nuse think\\console\\Output;\nuse think\\console\\output\\question\\Choice;\nuse think\\console\\output\\question\\Confirmation;\n\nclass Ask\n{\n    private static $stty;\n\n    private static $shell;\n\n    /** @var  Input */\n    protected $input;\n\n    /** @var  Output */\n    protected $output;\n\n    /** @var  Question */\n    protected $question;\n\n    public function __construct(Input $input, Output $output, Question $question)\n    {\n        $this->input    = $input;\n        $this->output   = $output;\n        $this->question = $question;\n    }\n\n    public function run()\n    {\n        if (!$this->input->isInteractive()) {\n            return $this->question->getDefault();\n        }\n\n        if (!$this->question->getValidator()) {\n            return $this->doAsk();\n        }\n\n        $that = $this;\n\n        $interviewer = function () use ($that) {\n            return $that->doAsk();\n        };\n\n        return $this->validateAttempts($interviewer);\n    }\n\n    protected function doAsk()\n    {\n        $this->writePrompt();\n\n        $inputStream  = STDIN;\n        $autocomplete = $this->question->getAutocompleterValues();\n\n        if (null === $autocomplete || !$this->hasSttyAvailable()) {\n            $ret = false;\n            if ($this->question->isHidden()) {\n                try {\n                    $ret = trim($this->getHiddenResponse($inputStream));\n                } catch (\\RuntimeException $e) {\n                    if (!$this->question->isHiddenFallback()) {\n                        throw $e;\n                    }\n                }\n            }\n\n            if (false === $ret) {\n                $ret = fgets($inputStream, 4096);\n                if (false === $ret) {\n                    throw new \\RuntimeException('Aborted');\n                }\n                $ret = trim($ret);\n            }\n        } else {\n            $ret = trim($this->autocomplete($inputStream));\n        }\n\n        $ret = strlen($ret) > 0 ? $ret : $this->question->getDefault();\n\n        if ($normalizer = $this->question->getNormalizer()) {\n            return $normalizer($ret);\n        }\n\n        return $ret;\n    }\n\n    private function autocomplete($inputStream)\n    {\n        $autocomplete = $this->question->getAutocompleterValues();\n        $ret          = '';\n\n        $i          = 0;\n        $ofs        = -1;\n        $matches    = $autocomplete;\n        $numMatches = count($matches);\n\n        $sttyMode = shell_exec('stty -g');\n\n        shell_exec('stty -icanon -echo');\n\n        while (!feof($inputStream)) {\n            $c = fread($inputStream, 1);\n\n            if (\"\\177\" === $c) {\n                if (0 === $numMatches && 0 !== $i) {\n                    --$i;\n                    $this->output->write(\"\\033[1D\");\n                }\n\n                if ($i === 0) {\n                    $ofs        = -1;\n                    $matches    = $autocomplete;\n                    $numMatches = count($matches);\n                } else {\n                    $numMatches = 0;\n                }\n\n                $ret = substr($ret, 0, $i);\n            } elseif (\"\\033\" === $c) {\n                $c .= fread($inputStream, 2);\n\n                if (isset($c[2]) && ('A' === $c[2] || 'B' === $c[2])) {\n                    if ('A' === $c[2] && -1 === $ofs) {\n                        $ofs = 0;\n                    }\n\n                    if (0 === $numMatches) {\n                        continue;\n                    }\n\n                    $ofs += ('A' === $c[2]) ? -1 : 1;\n                    $ofs = ($numMatches + $ofs) % $numMatches;\n                }\n            } elseif (ord($c) < 32) {\n                if (\"\\t\" === $c || \"\\n\" === $c) {\n                    if ($numMatches > 0 && -1 !== $ofs) {\n                        $ret = $matches[$ofs];\n                        $this->output->write(substr($ret, $i));\n                        $i = strlen($ret);\n                    }\n\n                    if (\"\\n\" === $c) {\n                        $this->output->write($c);\n                        break;\n                    }\n\n                    $numMatches = 0;\n                }\n\n                continue;\n            } else {\n                $this->output->write($c);\n                $ret .= $c;\n                ++$i;\n\n                $numMatches = 0;\n                $ofs        = 0;\n\n                foreach ($autocomplete as $value) {\n                    if (0 === strpos($value, $ret) && $i !== strlen($value)) {\n                        $matches[$numMatches++] = $value;\n                    }\n                }\n            }\n\n            $this->output->write(\"\\033[K\");\n\n            if ($numMatches > 0 && -1 !== $ofs) {\n                $this->output->write(\"\\0337\");\n                $this->output->highlight(substr($matches[$ofs], $i));\n                $this->output->write(\"\\0338\");\n            }\n        }\n\n        shell_exec(sprintf('stty %s', $sttyMode));\n\n        return $ret;\n    }\n\n    protected function getHiddenResponse($inputStream)\n    {\n        if ('\\\\' === DIRECTORY_SEPARATOR) {\n            $exe = __DIR__ . '/../bin/hiddeninput.exe';\n\n            $value = rtrim(shell_exec($exe));\n            $this->output->writeln('');\n\n            if (isset($tmpExe)) {\n                unlink($tmpExe);\n            }\n\n            return $value;\n        }\n\n        if ($this->hasSttyAvailable()) {\n            $sttyMode = shell_exec('stty -g');\n\n            shell_exec('stty -echo');\n            $value = fgets($inputStream, 4096);\n            shell_exec(sprintf('stty %s', $sttyMode));\n\n            if (false === $value) {\n                throw new \\RuntimeException('Aborted');\n            }\n\n            $value = trim($value);\n            $this->output->writeln('');\n\n            return $value;\n        }\n\n        if (false !== $shell = $this->getShell()) {\n            $readCmd = $shell === 'csh' ? 'set mypassword = $<' : 'read -r mypassword';\n            $command = sprintf(\"/usr/bin/env %s -c 'stty -echo; %s; stty echo; echo \\$mypassword'\", $shell, $readCmd);\n            $value   = rtrim(shell_exec($command));\n            $this->output->writeln('');\n\n            return $value;\n        }\n\n        throw new \\RuntimeException('Unable to hide the response.');\n    }\n\n    protected function validateAttempts($interviewer)\n    {\n        /** @var \\Exception $error */\n        $error    = null;\n        $attempts = $this->question->getMaxAttempts();\n        while (null === $attempts || $attempts--) {\n            if (null !== $error) {\n                $this->output->error($error->getMessage());\n            }\n\n            try {\n                return call_user_func($this->question->getValidator(), $interviewer());\n            } catch (\\Exception $error) {\n            }\n        }\n\n        throw $error;\n    }\n\n    /**\n     * 显示问题的提示信息\n     */\n    protected function writePrompt()\n    {\n        $text    = $this->question->getQuestion();\n        $default = $this->question->getDefault();\n\n        switch (true) {\n            case null === $default:\n                $text = sprintf(' <info>%s</info>:', $text);\n\n                break;\n\n            case $this->question instanceof Confirmation:\n                $text = sprintf(' <info>%s (yes/no)</info> [<comment>%s</comment>]:', $text, $default ? 'yes' : 'no');\n\n                break;\n\n            case $this->question instanceof Choice && $this->question->isMultiselect():\n                $choices = $this->question->getChoices();\n                $default = explode(',', $default);\n\n                foreach ($default as $key => $value) {\n                    $default[$key] = $choices[trim($value)];\n                }\n\n                $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, implode(', ', $default));\n\n                break;\n\n            case $this->question instanceof Choice:\n                $choices = $this->question->getChoices();\n                $text    = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, $choices[$default]);\n\n                break;\n\n            default:\n                $text = sprintf(' <info>%s</info> [<comment>%s</comment>]:', $text, $default);\n        }\n\n        $this->output->writeln($text);\n\n        if ($this->question instanceof Choice) {\n            $width = max(array_map('strlen', array_keys($this->question->getChoices())));\n\n            foreach ($this->question->getChoices() as $key => $value) {\n                $this->output->writeln(sprintf(\"  [<comment>%-${width}s</comment>] %s\", $key, $value));\n            }\n        }\n\n        $this->output->write(' > ');\n    }\n\n    private function getShell()\n    {\n        if (null !== self::$shell) {\n            return self::$shell;\n        }\n\n        self::$shell = false;\n\n        if (file_exists('/usr/bin/env')) {\n            $test = \"/usr/bin/env %s -c 'echo OK' 2> /dev/null\";\n            foreach (['bash', 'zsh', 'ksh', 'csh'] as $sh) {\n                if ('OK' === rtrim(shell_exec(sprintf($test, $sh)))) {\n                    self::$shell = $sh;\n                    break;\n                }\n            }\n        }\n\n        return self::$shell;\n    }\n\n    private function hasSttyAvailable()\n    {\n        if (null !== self::$stty) {\n            return self::$stty;\n        }\n\n        exec('stty 2>&1', $output, $exitcode);\n\n        return self::$stty = $exitcode === 0;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/output/Descriptor.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\output;\n\nuse think\\Console;\nuse think\\console\\Command;\nuse think\\console\\input\\Argument as InputArgument;\nuse think\\console\\input\\Definition as InputDefinition;\nuse think\\console\\input\\Option as InputOption;\nuse think\\console\\Output;\nuse think\\console\\output\\descriptor\\Console as ConsoleDescription;\n\nclass Descriptor\n{\n\n    /**\n     * @var Output\n     */\n    protected $output;\n\n    /**\n     * {@inheritdoc}\n     */\n    public function describe(Output $output, $object, array $options = [])\n    {\n        $this->output = $output;\n\n        switch (true) {\n            case $object instanceof InputArgument:\n                $this->describeInputArgument($object, $options);\n                break;\n            case $object instanceof InputOption:\n                $this->describeInputOption($object, $options);\n                break;\n            case $object instanceof InputDefinition:\n                $this->describeInputDefinition($object, $options);\n                break;\n            case $object instanceof Command:\n                $this->describeCommand($object, $options);\n                break;\n            case $object instanceof Console:\n                $this->describeConsole($object, $options);\n                break;\n            default:\n                throw new \\InvalidArgumentException(sprintf('Object of type \"%s\" is not describable.', get_class($object)));\n        }\n    }\n\n    /**\n     * 输出内容\n     * @param string $content\n     * @param bool   $decorated\n     */\n    protected function write($content, $decorated = false)\n    {\n        $this->output->write($content, false, $decorated ? Output::OUTPUT_NORMAL : Output::OUTPUT_RAW);\n    }\n\n    /**\n     * 描述参数\n     * @param InputArgument $argument\n     * @param array         $options\n     * @return string|mixed\n     */\n    protected function describeInputArgument(InputArgument $argument, array $options = [])\n    {\n        if (null !== $argument->getDefault()\n            && (!is_array($argument->getDefault())\n                || count($argument->getDefault()))\n        ) {\n            $default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($argument->getDefault()));\n        } else {\n            $default = '';\n        }\n\n        $totalWidth   = isset($options['total_width']) ? $options['total_width'] : strlen($argument->getName());\n        $spacingWidth = $totalWidth - strlen($argument->getName()) + 2;\n\n        $this->writeText(sprintf(\"  <info>%s</info>%s%s%s\", $argument->getName(), str_repeat(' ', $spacingWidth), // + 17 = 2 spaces + <info> + </info> + 2 spaces\n            preg_replace('/\\s*\\R\\s*/', PHP_EOL . str_repeat(' ', $totalWidth + 17), $argument->getDescription()), $default), $options);\n    }\n\n    /**\n     * 描述选项\n     * @param InputOption $option\n     * @param array       $options\n     * @return string|mixed\n     */\n    protected function describeInputOption(InputOption $option, array $options = [])\n    {\n        if ($option->acceptValue() && null !== $option->getDefault()\n            && (!is_array($option->getDefault())\n                || count($option->getDefault()))\n        ) {\n            $default = sprintf('<comment> [default: %s]</comment>', $this->formatDefaultValue($option->getDefault()));\n        } else {\n            $default = '';\n        }\n\n        $value = '';\n        if ($option->acceptValue()) {\n            $value = '=' . strtoupper($option->getName());\n\n            if ($option->isValueOptional()) {\n                $value = '[' . $value . ']';\n            }\n        }\n\n        $totalWidth = isset($options['total_width']) ? $options['total_width'] : $this->calculateTotalWidthForOptions([$option]);\n        $synopsis   = sprintf('%s%s', $option->getShortcut() ? sprintf('-%s, ', $option->getShortcut()) : '    ', sprintf('--%s%s', $option->getName(), $value));\n\n        $spacingWidth = $totalWidth - strlen($synopsis) + 2;\n\n        $this->writeText(sprintf(\"  <info>%s</info>%s%s%s%s\", $synopsis, str_repeat(' ', $spacingWidth), // + 17 = 2 spaces + <info> + </info> + 2 spaces\n            preg_replace('/\\s*\\R\\s*/', \"\\n\" . str_repeat(' ', $totalWidth + 17), $option->getDescription()), $default, $option->isArray() ? '<comment> (multiple values allowed)</comment>' : ''), $options);\n    }\n\n    /**\n     * 描述输入\n     * @param InputDefinition $definition\n     * @param array           $options\n     * @return string|mixed\n     */\n    protected function describeInputDefinition(InputDefinition $definition, array $options = [])\n    {\n        $totalWidth = $this->calculateTotalWidthForOptions($definition->getOptions());\n        foreach ($definition->getArguments() as $argument) {\n            $totalWidth = max($totalWidth, strlen($argument->getName()));\n        }\n\n        if ($definition->getArguments()) {\n            $this->writeText('<comment>Arguments:</comment>', $options);\n            $this->writeText(\"\\n\");\n            foreach ($definition->getArguments() as $argument) {\n                $this->describeInputArgument($argument, array_merge($options, ['total_width' => $totalWidth]));\n                $this->writeText(\"\\n\");\n            }\n        }\n\n        if ($definition->getArguments() && $definition->getOptions()) {\n            $this->writeText(\"\\n\");\n        }\n\n        if ($definition->getOptions()) {\n            $laterOptions = [];\n\n            $this->writeText('<comment>Options:</comment>', $options);\n            foreach ($definition->getOptions() as $option) {\n                if (strlen($option->getShortcut()) > 1) {\n                    $laterOptions[] = $option;\n                    continue;\n                }\n                $this->writeText(\"\\n\");\n                $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth]));\n            }\n            foreach ($laterOptions as $option) {\n                $this->writeText(\"\\n\");\n                $this->describeInputOption($option, array_merge($options, ['total_width' => $totalWidth]));\n            }\n        }\n    }\n\n    /**\n     * 描述指令\n     * @param Command $command\n     * @param array   $options\n     * @return string|mixed\n     */\n    protected function describeCommand(Command $command, array $options = [])\n    {\n        $command->getSynopsis(true);\n        $command->getSynopsis(false);\n        $command->mergeConsoleDefinition(false);\n\n        $this->writeText('<comment>Usage:</comment>', $options);\n        foreach (array_merge([$command->getSynopsis(true)], $command->getAliases(), $command->getUsages()) as $usage) {\n            $this->writeText(\"\\n\");\n            $this->writeText('  ' . $usage, $options);\n        }\n        $this->writeText(\"\\n\");\n\n        $definition = $command->getNativeDefinition();\n        if ($definition->getOptions() || $definition->getArguments()) {\n            $this->writeText(\"\\n\");\n            $this->describeInputDefinition($definition, $options);\n            $this->writeText(\"\\n\");\n        }\n\n        if ($help = $command->getProcessedHelp()) {\n            $this->writeText(\"\\n\");\n            $this->writeText('<comment>Help:</comment>', $options);\n            $this->writeText(\"\\n\");\n            $this->writeText(' ' . str_replace(\"\\n\", \"\\n \", $help), $options);\n            $this->writeText(\"\\n\");\n        }\n    }\n\n    /**\n     * 描述控制台\n     * @param Console $console\n     * @param array   $options\n     * @return string|mixed\n     */\n    protected function describeConsole(Console $console, array $options = [])\n    {\n        $describedNamespace = isset($options['namespace']) ? $options['namespace'] : null;\n        $description        = new ConsoleDescription($console, $describedNamespace);\n\n        if (isset($options['raw_text']) && $options['raw_text']) {\n            $width = $this->getColumnWidth($description->getCommands());\n\n            foreach ($description->getCommands() as $command) {\n                $this->writeText(sprintf(\"%-${width}s %s\", $command->getName(), $command->getDescription()), $options);\n                $this->writeText(\"\\n\");\n            }\n        } else {\n            if ('' != $help = $console->getHelp()) {\n                $this->writeText(\"$help\\n\\n\", $options);\n            }\n\n            $this->writeText(\"<comment>Usage:</comment>\\n\", $options);\n            $this->writeText(\"  command [options] [arguments]\\n\\n\", $options);\n\n            $this->describeInputDefinition(new InputDefinition($console->getDefinition()->getOptions()), $options);\n\n            $this->writeText(\"\\n\");\n            $this->writeText(\"\\n\");\n\n            $width = $this->getColumnWidth($description->getCommands());\n\n            if ($describedNamespace) {\n                $this->writeText(sprintf('<comment>Available commands for the \"%s\" namespace:</comment>', $describedNamespace), $options);\n            } else {\n                $this->writeText('<comment>Available commands:</comment>', $options);\n            }\n\n            // add commands by namespace\n            foreach ($description->getNamespaces() as $namespace) {\n                if (!$describedNamespace && ConsoleDescription::GLOBAL_NAMESPACE !== $namespace['id']) {\n                    $this->writeText(\"\\n\");\n                    $this->writeText(' <comment>' . $namespace['id'] . '</comment>', $options);\n                }\n\n                foreach ($namespace['commands'] as $name) {\n                    $this->writeText(\"\\n\");\n                    $spacingWidth = $width - strlen($name);\n                    $this->writeText(sprintf(\"  <info>%s</info>%s%s\", $name, str_repeat(' ', $spacingWidth), $description->getCommand($name)\n                            ->getDescription()), $options);\n                }\n            }\n\n            $this->writeText(\"\\n\");\n        }\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    private function writeText($content, array $options = [])\n    {\n        $this->write(isset($options['raw_text'])\n            && $options['raw_text'] ? strip_tags($content) : $content, isset($options['raw_output']) ? !$options['raw_output'] : true);\n    }\n\n    /**\n     * 格式化\n     * @param mixed $default\n     * @return string\n     */\n    private function formatDefaultValue($default)\n    {\n        return json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);\n    }\n\n    /**\n     * @param Command[] $commands\n     * @return int\n     */\n    private function getColumnWidth(array $commands)\n    {\n        $width = 0;\n        foreach ($commands as $command) {\n            $width = strlen($command->getName()) > $width ? strlen($command->getName()) : $width;\n        }\n\n        return $width + 2;\n    }\n\n    /**\n     * @param InputOption[] $options\n     * @return int\n     */\n    private function calculateTotalWidthForOptions($options)\n    {\n        $totalWidth = 0;\n        foreach ($options as $option) {\n            $nameLength = 4 + strlen($option->getName()) + 2; // - + shortcut + , + whitespace + name + --\n\n            if ($option->acceptValue()) {\n                $valueLength = 1 + strlen($option->getName()); // = + value\n                $valueLength += $option->isValueOptional() ? 2 : 0; // [ + ]\n\n                $nameLength += $valueLength;\n            }\n            $totalWidth = max($totalWidth, $nameLength);\n        }\n\n        return $totalWidth;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/output/Formatter.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\nnamespace think\\console\\output;\n\nuse think\\console\\output\\formatter\\Stack as StyleStack;\nuse think\\console\\output\\formatter\\Style;\n\nclass Formatter\n{\n\n    private $decorated = false;\n    private $styles    = [];\n    private $styleStack;\n\n    /**\n     * 转义\n     * @param string $text\n     * @return string\n     */\n    public static function escape($text)\n    {\n        return preg_replace('/([^\\\\\\\\]?)</is', '$1\\\\<', $text);\n    }\n\n    /**\n     * 初始化命令行输出格式\n     */\n    public function __construct()\n    {\n        $this->setStyle('error', new Style('white', 'red'));\n        $this->setStyle('info', new Style('green'));\n        $this->setStyle('comment', new Style('yellow'));\n        $this->setStyle('question', new Style('black', 'cyan'));\n        $this->setStyle('highlight', new Style('red'));\n        $this->setStyle('warning', new Style('black', 'yellow'));\n\n        $this->styleStack = new StyleStack();\n    }\n\n    /**\n     * 设置外观标识\n     * @param bool $decorated 是否美化文字\n     */\n    public function setDecorated($decorated)\n    {\n        $this->decorated = (bool) $decorated;\n    }\n\n    /**\n     * 获取外观标识\n     * @return bool\n     */\n    public function isDecorated()\n    {\n        return $this->decorated;\n    }\n\n    /**\n     * 添加一个新样式\n     * @param string $name  样式名\n     * @param Style  $style 样式实例\n     */\n    public function setStyle($name, Style $style)\n    {\n        $this->styles[strtolower($name)] = $style;\n    }\n\n    /**\n     * 是否有这个样式\n     * @param string $name\n     * @return bool\n     */\n    public function hasStyle($name)\n    {\n        return isset($this->styles[strtolower($name)]);\n    }\n\n    /**\n     * 获取样式\n     * @param string $name\n     * @return Style\n     * @throws \\InvalidArgumentException\n     */\n    public function getStyle($name)\n    {\n        if (!$this->hasStyle($name)) {\n            throw new \\InvalidArgumentException(sprintf('Undefined style: %s', $name));\n        }\n\n        return $this->styles[strtolower($name)];\n    }\n\n    /**\n     * 使用所给的样式格式化文字\n     * @param string $message 文字\n     * @return string\n     */\n    public function format($message)\n    {\n        $offset   = 0;\n        $output   = '';\n        $tagRegex = '[a-z][a-z0-9_=;-]*';\n        preg_match_all(\"#<(($tagRegex) | /($tagRegex)?)>#isx\", $message, $matches, PREG_OFFSET_CAPTURE);\n        foreach ($matches[0] as $i => $match) {\n            $pos  = $match[1];\n            $text = $match[0];\n\n            if (0 != $pos && '\\\\' == $message[$pos - 1]) {\n                continue;\n            }\n\n            $output .= $this->applyCurrentStyle(substr($message, $offset, $pos - $offset));\n            $offset = $pos + strlen($text);\n\n            if ($open = '/' != $text[1]) {\n                $tag = $matches[1][$i][0];\n            } else {\n                $tag = isset($matches[3][$i][0]) ? $matches[3][$i][0] : '';\n            }\n\n            if (!$open && !$tag) {\n                // </>\n                $this->styleStack->pop();\n            } elseif (false === $style = $this->createStyleFromString(strtolower($tag))) {\n                $output .= $this->applyCurrentStyle($text);\n            } elseif ($open) {\n                $this->styleStack->push($style);\n            } else {\n                $this->styleStack->pop($style);\n            }\n        }\n\n        $output .= $this->applyCurrentStyle(substr($message, $offset));\n\n        return str_replace('\\\\<', '<', $output);\n    }\n\n    /**\n     * @return StyleStack\n     */\n    public function getStyleStack()\n    {\n        return $this->styleStack;\n    }\n\n    /**\n     * 根据字符串创建新的样式实例\n     * @param string $string\n     * @return Style|bool\n     */\n    private function createStyleFromString($string)\n    {\n        if (isset($this->styles[$string])) {\n            return $this->styles[$string];\n        }\n\n        if (!preg_match_all('/([^=]+)=([^;]+)(;|$)/', strtolower($string), $matches, PREG_SET_ORDER)) {\n            return false;\n        }\n\n        $style = new Style();\n        foreach ($matches as $match) {\n            array_shift($match);\n\n            if ('fg' == $match[0]) {\n                $style->setForeground($match[1]);\n            } elseif ('bg' == $match[0]) {\n                $style->setBackground($match[1]);\n            } else {\n                try {\n                    $style->setOption($match[1]);\n                } catch (\\InvalidArgumentException $e) {\n                    return false;\n                }\n            }\n        }\n\n        return $style;\n    }\n\n    /**\n     * 从堆栈应用样式到文字\n     * @param string $text 文字\n     * @return string\n     */\n    private function applyCurrentStyle($text)\n    {\n        return $this->isDecorated() && strlen($text) > 0 ? $this->styleStack->getCurrent()->apply($text) : $text;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/output/Question.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\output;\n\nclass Question\n{\n\n    private $question;\n    private $attempts;\n    private $hidden         = false;\n    private $hiddenFallback = true;\n    private $autocompleterValues;\n    private $validator;\n    private $default;\n    private $normalizer;\n\n    /**\n     * 构造方法\n     * @param string $question 问题\n     * @param mixed  $default  默认答案\n     */\n    public function __construct($question, $default = null)\n    {\n        $this->question = $question;\n        $this->default  = $default;\n    }\n\n    /**\n     * 获取问题\n     * @return string\n     */\n    public function getQuestion()\n    {\n        return $this->question;\n    }\n\n    /**\n     * 获取默认答案\n     * @return mixed\n     */\n    public function getDefault()\n    {\n        return $this->default;\n    }\n\n    /**\n     * 是否隐藏答案\n     * @return bool\n     */\n    public function isHidden()\n    {\n        return $this->hidden;\n    }\n\n    /**\n     * 隐藏答案\n     * @param bool $hidden\n     * @return Question\n     */\n    public function setHidden($hidden)\n    {\n        if ($this->autocompleterValues) {\n            throw new \\LogicException('A hidden question cannot use the autocompleter.');\n        }\n\n        $this->hidden = (bool) $hidden;\n\n        return $this;\n    }\n\n    /**\n     * 不能被隐藏是否撤销\n     * @return bool\n     */\n    public function isHiddenFallback()\n    {\n        return $this->hiddenFallback;\n    }\n\n    /**\n     * 设置不能被隐藏的时候的操作\n     * @param bool $fallback\n     * @return Question\n     */\n    public function setHiddenFallback($fallback)\n    {\n        $this->hiddenFallback = (bool) $fallback;\n\n        return $this;\n    }\n\n    /**\n     * 获取自动完成\n     * @return null|array|\\Traversable\n     */\n    public function getAutocompleterValues()\n    {\n        return $this->autocompleterValues;\n    }\n\n    /**\n     * 设置自动完成的值\n     * @param null|array|\\Traversable $values\n     * @return Question\n     * @throws \\InvalidArgumentException\n     * @throws \\LogicException\n     */\n    public function setAutocompleterValues($values)\n    {\n        if (is_array($values) && $this->isAssoc($values)) {\n            $values = array_merge(array_keys($values), array_values($values));\n        }\n\n        if (null !== $values && !is_array($values)) {\n            if (!$values instanceof \\Traversable || $values instanceof \\Countable) {\n                throw new \\InvalidArgumentException('Autocompleter values can be either an array, `null` or an object implementing both `Countable` and `Traversable` interfaces.');\n            }\n        }\n\n        if ($this->hidden) {\n            throw new \\LogicException('A hidden question cannot use the autocompleter.');\n        }\n\n        $this->autocompleterValues = $values;\n\n        return $this;\n    }\n\n    /**\n     * 设置答案的验证器\n     * @param null|callable $validator\n     * @return Question The current instance\n     */\n    public function setValidator($validator)\n    {\n        $this->validator = $validator;\n\n        return $this;\n    }\n\n    /**\n     * 获取验证器\n     * @return null|callable\n     */\n    public function getValidator()\n    {\n        return $this->validator;\n    }\n\n    /**\n     * 设置最大重试次数\n     * @param null|int $attempts\n     * @return Question\n     * @throws \\InvalidArgumentException\n     */\n    public function setMaxAttempts($attempts)\n    {\n        if (null !== $attempts && $attempts < 1) {\n            throw new \\InvalidArgumentException('Maximum number of attempts must be a positive value.');\n        }\n\n        $this->attempts = $attempts;\n\n        return $this;\n    }\n\n    /**\n     * 获取最大重试次数\n     * @return null|int\n     */\n    public function getMaxAttempts()\n    {\n        return $this->attempts;\n    }\n\n    /**\n     * 设置响应的回调\n     * @param string|\\Closure $normalizer\n     * @return Question\n     */\n    public function setNormalizer($normalizer)\n    {\n        $this->normalizer = $normalizer;\n\n        return $this;\n    }\n\n    /**\n     * 获取响应回调\n     * The normalizer can ba a callable (a string), a closure or a class implementing __invoke.\n     * @return string|\\Closure\n     */\n    public function getNormalizer()\n    {\n        return $this->normalizer;\n    }\n\n    protected function isAssoc($array)\n    {\n        return (bool) count(array_filter(array_keys($array), 'is_string'));\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/output/descriptor/Console.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\output\\descriptor;\n\nuse think\\Console as ThinkConsole;\nuse think\\console\\Command;\n\nclass Console\n{\n\n    const GLOBAL_NAMESPACE = '_global';\n\n    /**\n     * @var ThinkConsole\n     */\n    private $console;\n\n    /**\n     * @var null|string\n     */\n    private $namespace;\n\n    /**\n     * @var array\n     */\n    private $namespaces;\n\n    /**\n     * @var Command[]\n     */\n    private $commands;\n\n    /**\n     * @var Command[]\n     */\n    private $aliases;\n\n    /**\n     * 构造方法\n     * @param ThinkConsole $console\n     * @param string|null  $namespace\n     */\n    public function __construct(ThinkConsole $console, $namespace = null)\n    {\n        $this->console   = $console;\n        $this->namespace = $namespace;\n    }\n\n    /**\n     * @return array\n     */\n    public function getNamespaces()\n    {\n        if (null === $this->namespaces) {\n            $this->inspectConsole();\n        }\n\n        return $this->namespaces;\n    }\n\n    /**\n     * @return Command[]\n     */\n    public function getCommands()\n    {\n        if (null === $this->commands) {\n            $this->inspectConsole();\n        }\n\n        return $this->commands;\n    }\n\n    /**\n     * @param string $name\n     * @return Command\n     * @throws \\InvalidArgumentException\n     */\n    public function getCommand($name)\n    {\n        if (!isset($this->commands[$name]) && !isset($this->aliases[$name])) {\n            throw new \\InvalidArgumentException(sprintf('Command %s does not exist.', $name));\n        }\n\n        return isset($this->commands[$name]) ? $this->commands[$name] : $this->aliases[$name];\n    }\n\n    private function inspectConsole()\n    {\n        $this->commands   = [];\n        $this->namespaces = [];\n\n        $all = $this->console->all($this->namespace ? $this->console->findNamespace($this->namespace) : null);\n        foreach ($this->sortCommands($all) as $namespace => $commands) {\n            $names = [];\n\n            /** @var Command $command */\n            foreach ($commands as $name => $command) {\n                if (!$command->getName()) {\n                    continue;\n                }\n\n                if ($command->getName() === $name) {\n                    $this->commands[$name] = $command;\n                } else {\n                    $this->aliases[$name] = $command;\n                }\n\n                $names[] = $name;\n            }\n\n            $this->namespaces[$namespace] = ['id' => $namespace, 'commands' => $names];\n        }\n    }\n\n    /**\n     * @param array $commands\n     * @return array\n     */\n    private function sortCommands(array $commands)\n    {\n        $namespacedCommands = [];\n        foreach ($commands as $name => $command) {\n            $key = $this->console->extractNamespace($name, 1);\n            if (!$key) {\n                $key = self::GLOBAL_NAMESPACE;\n            }\n\n            $namespacedCommands[$key][$name] = $command;\n        }\n        ksort($namespacedCommands);\n\n        foreach ($namespacedCommands as &$commandsSet) {\n            ksort($commandsSet);\n        }\n        // unset reference to keep scope clear\n        unset($commandsSet);\n\n        return $namespacedCommands;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/output/driver/Buffer.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\output\\driver;\n\nuse think\\console\\Output;\n\nclass Buffer\n{\n    /**\n     * @var string\n     */\n    private $buffer = '';\n\n    public function __construct(Output $output)\n    {\n        // do nothing\n    }\n\n    public function fetch()\n    {\n        $content      = $this->buffer;\n        $this->buffer = '';\n        return $content;\n    }\n\n    public function write($messages, $newline = false, $options = Output::OUTPUT_NORMAL)\n    {\n        $messages = (array) $messages;\n\n        foreach ($messages as $message) {\n            $this->buffer .= $message;\n        }\n        if ($newline) {\n            $this->buffer .= \"\\n\";\n        }\n    }\n\n    public function renderException(\\Exception $e)\n    {\n        // do nothing\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/output/driver/Console.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\output\\driver;\n\nuse think\\console\\Output;\nuse think\\console\\output\\Formatter;\n\nclass Console\n{\n\n    /** @var  Resource */\n    private $stdout;\n\n    /** @var  Formatter */\n    private $formatter;\n\n    private $terminalDimensions;\n\n    /** @var  Output */\n    private $output;\n\n    public function __construct(Output $output)\n    {\n        $this->output    = $output;\n        $this->formatter = new Formatter();\n        $this->stdout    = $this->openOutputStream();\n        $decorated       = $this->hasColorSupport($this->stdout);\n        $this->formatter->setDecorated($decorated);\n    }\n\n    public function getFormatter()\n    {\n        return $this->formatter;\n    }\n\n    public function setDecorated($decorated)\n    {\n        $this->formatter->setDecorated($decorated);\n    }\n\n    public function write($messages, $newline = false, $type = Output::OUTPUT_NORMAL, $stream = null)\n    {\n        if (Output::VERBOSITY_QUIET === $this->output->getVerbosity()) {\n            return;\n        }\n\n        $messages = (array) $messages;\n\n        foreach ($messages as $message) {\n            switch ($type) {\n                case Output::OUTPUT_NORMAL:\n                    $message = $this->formatter->format($message);\n                    break;\n                case Output::OUTPUT_RAW:\n                    break;\n                case Output::OUTPUT_PLAIN:\n                    $message = strip_tags($this->formatter->format($message));\n                    break;\n                default:\n                    throw new \\InvalidArgumentException(sprintf('Unknown output type given (%s)', $type));\n            }\n\n            $this->doWrite($message, $newline, $stream);\n        }\n    }\n\n    public function renderException(\\Exception $e)\n    {\n        $stderr    = $this->openErrorStream();\n        $decorated = $this->hasColorSupport($stderr);\n        $this->formatter->setDecorated($decorated);\n\n        do {\n            $title = sprintf('  [%s]  ', get_class($e));\n\n            $len = $this->stringWidth($title);\n\n            $width = $this->getTerminalWidth() ? $this->getTerminalWidth() - 1 : PHP_INT_MAX;\n\n            if (defined('HHVM_VERSION') && $width > 1 << 31) {\n                $width = 1 << 31;\n            }\n            $lines = [];\n            foreach (preg_split('/\\r?\\n/', $e->getMessage()) as $line) {\n                foreach ($this->splitStringByWidth($line, $width - 4) as $line) {\n\n                    $lineLength = $this->stringWidth(preg_replace('/\u001b\\[[^m]*m/', '', $line)) + 4;\n                    $lines[]    = [$line, $lineLength];\n\n                    $len = max($lineLength, $len);\n                }\n            }\n\n            $messages   = ['', ''];\n            $messages[] = $emptyLine = sprintf('<error>%s</error>', str_repeat(' ', $len));\n            $messages[] = sprintf('<error>%s%s</error>', $title, str_repeat(' ', max(0, $len - $this->stringWidth($title))));\n            foreach ($lines as $line) {\n                $messages[] = sprintf('<error>  %s  %s</error>', $line[0], str_repeat(' ', $len - $line[1]));\n            }\n            $messages[] = $emptyLine;\n            $messages[] = '';\n            $messages[] = '';\n\n            $this->write($messages, true, Output::OUTPUT_NORMAL, $stderr);\n\n            if (Output::VERBOSITY_VERBOSE <= $this->output->getVerbosity()) {\n                $this->write('<comment>Exception trace:</comment>', true, Output::OUTPUT_NORMAL, $stderr);\n\n                // exception related properties\n                $trace = $e->getTrace();\n                array_unshift($trace, [\n                    'function' => '',\n                    'file'     => $e->getFile() !== null ? $e->getFile() : 'n/a',\n                    'line'     => $e->getLine() !== null ? $e->getLine() : 'n/a',\n                    'args'     => [],\n                ]);\n\n                for ($i = 0, $count = count($trace); $i < $count; ++$i) {\n                    $class    = isset($trace[$i]['class']) ? $trace[$i]['class'] : '';\n                    $type     = isset($trace[$i]['type']) ? $trace[$i]['type'] : '';\n                    $function = $trace[$i]['function'];\n                    $file     = isset($trace[$i]['file']) ? $trace[$i]['file'] : 'n/a';\n                    $line     = isset($trace[$i]['line']) ? $trace[$i]['line'] : 'n/a';\n\n                    $this->write(sprintf(' %s%s%s() at <info>%s:%s</info>', $class, $type, $function, $file, $line), true, Output::OUTPUT_NORMAL, $stderr);\n                }\n\n                $this->write('', true, Output::OUTPUT_NORMAL, $stderr);\n                $this->write('', true, Output::OUTPUT_NORMAL, $stderr);\n            }\n        } while ($e = $e->getPrevious());\n\n    }\n\n    /**\n     * 获取终端宽度\n     * @return int|null\n     */\n    protected function getTerminalWidth()\n    {\n        $dimensions = $this->getTerminalDimensions();\n\n        return $dimensions[0];\n    }\n\n    /**\n     * 获取终端高度\n     * @return int|null\n     */\n    protected function getTerminalHeight()\n    {\n        $dimensions = $this->getTerminalDimensions();\n\n        return $dimensions[1];\n    }\n\n    /**\n     * 获取当前终端的尺寸\n     * @return array\n     */\n    public function getTerminalDimensions()\n    {\n        if ($this->terminalDimensions) {\n            return $this->terminalDimensions;\n        }\n\n        if ('\\\\' === DS) {\n            if (preg_match('/^(\\d+)x\\d+ \\(\\d+x(\\d+)\\)$/', trim(getenv('ANSICON')), $matches)) {\n                return [(int) $matches[1], (int) $matches[2]];\n            }\n            if (preg_match('/^(\\d+)x(\\d+)$/', $this->getMode(), $matches)) {\n                return [(int) $matches[1], (int) $matches[2]];\n            }\n        }\n\n        if ($sttyString = $this->getSttyColumns()) {\n            if (preg_match('/rows.(\\d+);.columns.(\\d+);/i', $sttyString, $matches)) {\n                return [(int) $matches[2], (int) $matches[1]];\n            }\n            if (preg_match('/;.(\\d+).rows;.(\\d+).columns/i', $sttyString, $matches)) {\n                return [(int) $matches[2], (int) $matches[1]];\n            }\n        }\n\n        return [null, null];\n    }\n\n    /**\n     * 获取stty列数\n     * @return string\n     */\n    private function getSttyColumns()\n    {\n        if (!function_exists('proc_open')) {\n            return;\n        }\n\n        $descriptorspec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']];\n        $process        = proc_open('stty -a | grep columns', $descriptorspec, $pipes, null, null, ['suppress_errors' => true]);\n        if (is_resource($process)) {\n            $info = stream_get_contents($pipes[1]);\n            fclose($pipes[1]);\n            fclose($pipes[2]);\n            proc_close($process);\n\n            return $info;\n        }\n        return;\n    }\n\n    /**\n     * 获取终端模式\n     * @return string <width>x<height> 或 null\n     */\n    private function getMode()\n    {\n        if (!function_exists('proc_open')) {\n            return;\n        }\n\n        $descriptorspec = [1 => ['pipe', 'w'], 2 => ['pipe', 'w']];\n        $process        = proc_open('mode CON', $descriptorspec, $pipes, null, null, ['suppress_errors' => true]);\n        if (is_resource($process)) {\n            $info = stream_get_contents($pipes[1]);\n            fclose($pipes[1]);\n            fclose($pipes[2]);\n            proc_close($process);\n\n            if (preg_match('/--------+\\r?\\n.+?(\\d+)\\r?\\n.+?(\\d+)\\r?\\n/', $info, $matches)) {\n                return $matches[2] . 'x' . $matches[1];\n            }\n        }\n        return;\n    }\n\n    private function stringWidth($string)\n    {\n        if (!function_exists('mb_strwidth')) {\n            return strlen($string);\n        }\n\n        if (false === $encoding = mb_detect_encoding($string)) {\n            return strlen($string);\n        }\n\n        return mb_strwidth($string, $encoding);\n    }\n\n    private function splitStringByWidth($string, $width)\n    {\n        if (!function_exists('mb_strwidth')) {\n            return str_split($string, $width);\n        }\n\n        if (false === $encoding = mb_detect_encoding($string)) {\n            return str_split($string, $width);\n        }\n\n        $utf8String = mb_convert_encoding($string, 'utf8', $encoding);\n        $lines      = [];\n        $line       = '';\n        foreach (preg_split('//u', $utf8String) as $char) {\n            if (mb_strwidth($line . $char, 'utf8') <= $width) {\n                $line .= $char;\n                continue;\n            }\n            $lines[] = str_pad($line, $width);\n            $line    = $char;\n        }\n        if (strlen($line)) {\n            $lines[] = count($lines) ? str_pad($line, $width) : $line;\n        }\n\n        mb_convert_variables($encoding, 'utf8', $lines);\n\n        return $lines;\n    }\n\n    private function isRunningOS400()\n    {\n        $checks = [\n            function_exists('php_uname') ? php_uname('s') : '',\n            getenv('OSTYPE'),\n            PHP_OS,\n        ];\n        return false !== stripos(implode(';', $checks), 'OS400');\n    }\n\n    /**\n     * 当前环境是否支持写入控制台输出到stdout.\n     *\n     * @return bool\n     */\n    protected function hasStdoutSupport()\n    {\n        return false === $this->isRunningOS400();\n    }\n\n    /**\n     * 当前环境是否支持写入控制台输出到stderr.\n     *\n     * @return bool\n     */\n    protected function hasStderrSupport()\n    {\n        return false === $this->isRunningOS400();\n    }\n\n    /**\n     * @return resource\n     */\n    private function openOutputStream()\n    {\n        if (!$this->hasStdoutSupport()) {\n            return fopen('php://output', 'w');\n        }\n        return @fopen('php://stdout', 'w') ?: fopen('php://output', 'w');\n    }\n\n    /**\n     * @return resource\n     */\n    private function openErrorStream()\n    {\n        return fopen($this->hasStderrSupport() ? 'php://stderr' : 'php://output', 'w');\n    }\n\n    /**\n     * 将消息写入到输出。\n     * @param string $message 消息\n     * @param bool   $newline 是否另起一行\n     * @param null   $stream\n     */\n    protected function doWrite($message, $newline, $stream = null)\n    {\n        if (null === $stream) {\n            $stream = $this->stdout;\n        }\n        if (false === @fwrite($stream, $message . ($newline ? PHP_EOL : ''))) {\n            throw new \\RuntimeException('Unable to write output.');\n        }\n\n        fflush($stream);\n    }\n\n    /**\n     * 是否支持着色\n     * @param $stream\n     * @return bool\n     */\n    protected function hasColorSupport($stream)\n    {\n        if (DIRECTORY_SEPARATOR === '\\\\') {\n            return\n            '10.0.10586' === PHP_WINDOWS_VERSION_MAJOR . '.' . PHP_WINDOWS_VERSION_MINOR . '.' . PHP_WINDOWS_VERSION_BUILD\n            || false !== getenv('ANSICON')\n            || 'ON' === getenv('ConEmuANSI')\n            || 'xterm' === getenv('TERM');\n        }\n\n        return function_exists('posix_isatty') && @posix_isatty($stream);\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/output/driver/Nothing.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\output\\driver;\n\nuse think\\console\\Output;\n\nclass Nothing\n{\n\n    public function __construct(Output $output)\n    {\n        // do nothing\n    }\n\n    public function write($messages, $newline = false, $options = Output::OUTPUT_NORMAL)\n    {\n        // do nothing\n    }\n\n    public function renderException(\\Exception $e)\n    {\n        // do nothing\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/output/formatter/Stack.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\output\\formatter;\n\nclass Stack\n{\n\n    /**\n     * @var Style[]\n     */\n    private $styles;\n\n    /**\n     * @var Style\n     */\n    private $emptyStyle;\n\n    /**\n     * 构造方法\n     * @param Style|null $emptyStyle\n     */\n    public function __construct(Style $emptyStyle = null)\n    {\n        $this->emptyStyle = $emptyStyle ?: new Style();\n        $this->reset();\n    }\n\n    /**\n     * 重置堆栈\n     */\n    public function reset()\n    {\n        $this->styles = [];\n    }\n\n    /**\n     * 推一个样式进入堆栈\n     * @param Style $style\n     */\n    public function push(Style $style)\n    {\n        $this->styles[] = $style;\n    }\n\n    /**\n     * 从堆栈中弹出一个样式\n     * @param Style|null $style\n     * @return Style\n     * @throws \\InvalidArgumentException\n     */\n    public function pop(Style $style = null)\n    {\n        if (empty($this->styles)) {\n            return $this->emptyStyle;\n        }\n\n        if (null === $style) {\n            return array_pop($this->styles);\n        }\n\n        /**\n         * @var int   $index\n         * @var Style $stackedStyle\n         */\n        foreach (array_reverse($this->styles, true) as $index => $stackedStyle) {\n            if ($style->apply('') === $stackedStyle->apply('')) {\n                $this->styles = array_slice($this->styles, 0, $index);\n\n                return $stackedStyle;\n            }\n        }\n\n        throw new \\InvalidArgumentException('Incorrectly nested style tag found.');\n    }\n\n    /**\n     * 计算堆栈的当前样式。\n     * @return Style\n     */\n    public function getCurrent()\n    {\n        if (empty($this->styles)) {\n            return $this->emptyStyle;\n        }\n\n        return $this->styles[count($this->styles) - 1];\n    }\n\n    /**\n     * @param Style $emptyStyle\n     * @return Stack\n     */\n    public function setEmptyStyle(Style $emptyStyle)\n    {\n        $this->emptyStyle = $emptyStyle;\n\n        return $this;\n    }\n\n    /**\n     * @return Style\n     */\n    public function getEmptyStyle()\n    {\n        return $this->emptyStyle;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/output/formatter/Style.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\output\\formatter;\n\nclass Style\n{\n\n    private static $availableForegroundColors = [\n        'black'   => ['set' => 30, 'unset' => 39],\n        'red'     => ['set' => 31, 'unset' => 39],\n        'green'   => ['set' => 32, 'unset' => 39],\n        'yellow'  => ['set' => 33, 'unset' => 39],\n        'blue'    => ['set' => 34, 'unset' => 39],\n        'magenta' => ['set' => 35, 'unset' => 39],\n        'cyan'    => ['set' => 36, 'unset' => 39],\n        'white'   => ['set' => 37, 'unset' => 39],\n    ];\n    private static $availableBackgroundColors = [\n        'black'   => ['set' => 40, 'unset' => 49],\n        'red'     => ['set' => 41, 'unset' => 49],\n        'green'   => ['set' => 42, 'unset' => 49],\n        'yellow'  => ['set' => 43, 'unset' => 49],\n        'blue'    => ['set' => 44, 'unset' => 49],\n        'magenta' => ['set' => 45, 'unset' => 49],\n        'cyan'    => ['set' => 46, 'unset' => 49],\n        'white'   => ['set' => 47, 'unset' => 49],\n    ];\n    private static $availableOptions = [\n        'bold'       => ['set' => 1, 'unset' => 22],\n        'underscore' => ['set' => 4, 'unset' => 24],\n        'blink'      => ['set' => 5, 'unset' => 25],\n        'reverse'    => ['set' => 7, 'unset' => 27],\n        'conceal'    => ['set' => 8, 'unset' => 28],\n    ];\n\n    private $foreground;\n    private $background;\n    private $options = [];\n\n    /**\n     * 初始化输出的样式\n     * @param string|null $foreground 字体颜色\n     * @param string|null $background 背景色\n     * @param array       $options    格式\n     * @api\n     */\n    public function __construct($foreground = null, $background = null, array $options = [])\n    {\n        if (null !== $foreground) {\n            $this->setForeground($foreground);\n        }\n        if (null !== $background) {\n            $this->setBackground($background);\n        }\n        if (count($options)) {\n            $this->setOptions($options);\n        }\n    }\n\n    /**\n     * 设置字体颜色\n     * @param string|null $color 颜色名\n     * @throws \\InvalidArgumentException\n     * @api\n     */\n    public function setForeground($color = null)\n    {\n        if (null === $color) {\n            $this->foreground = null;\n\n            return;\n        }\n\n        if (!isset(static::$availableForegroundColors[$color])) {\n            throw new \\InvalidArgumentException(sprintf('Invalid foreground color specified: \"%s\". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableForegroundColors))));\n        }\n\n        $this->foreground = static::$availableForegroundColors[$color];\n    }\n\n    /**\n     * 设置背景色\n     * @param string|null $color 颜色名\n     * @throws \\InvalidArgumentException\n     * @api\n     */\n    public function setBackground($color = null)\n    {\n        if (null === $color) {\n            $this->background = null;\n\n            return;\n        }\n\n        if (!isset(static::$availableBackgroundColors[$color])) {\n            throw new \\InvalidArgumentException(sprintf('Invalid background color specified: \"%s\". Expected one of (%s)', $color, implode(', ', array_keys(static::$availableBackgroundColors))));\n        }\n\n        $this->background = static::$availableBackgroundColors[$color];\n    }\n\n    /**\n     * 设置字体格式\n     * @param string $option 格式名\n     * @throws \\InvalidArgumentException When the option name isn't defined\n     * @api\n     */\n    public function setOption($option)\n    {\n        if (!isset(static::$availableOptions[$option])) {\n            throw new \\InvalidArgumentException(sprintf('Invalid option specified: \"%s\". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions))));\n        }\n\n        if (!in_array(static::$availableOptions[$option], $this->options)) {\n            $this->options[] = static::$availableOptions[$option];\n        }\n    }\n\n    /**\n     * 重置字体格式\n     * @param string $option 格式名\n     * @throws \\InvalidArgumentException\n     */\n    public function unsetOption($option)\n    {\n        if (!isset(static::$availableOptions[$option])) {\n            throw new \\InvalidArgumentException(sprintf('Invalid option specified: \"%s\". Expected one of (%s)', $option, implode(', ', array_keys(static::$availableOptions))));\n        }\n\n        $pos = array_search(static::$availableOptions[$option], $this->options);\n        if (false !== $pos) {\n            unset($this->options[$pos]);\n        }\n    }\n\n    /**\n     * 批量设置字体格式\n     * @param array $options\n     */\n    public function setOptions(array $options)\n    {\n        $this->options = [];\n\n        foreach ($options as $option) {\n            $this->setOption($option);\n        }\n    }\n\n    /**\n     * 应用样式到文字\n     * @param string $text 文字\n     * @return string\n     */\n    public function apply($text)\n    {\n        $setCodes   = [];\n        $unsetCodes = [];\n\n        if (null !== $this->foreground) {\n            $setCodes[]   = $this->foreground['set'];\n            $unsetCodes[] = $this->foreground['unset'];\n        }\n        if (null !== $this->background) {\n            $setCodes[]   = $this->background['set'];\n            $unsetCodes[] = $this->background['unset'];\n        }\n        if (count($this->options)) {\n            foreach ($this->options as $option) {\n                $setCodes[]   = $option['set'];\n                $unsetCodes[] = $option['unset'];\n            }\n        }\n\n        if (0 === count($setCodes)) {\n            return $text;\n        }\n\n        return sprintf(\"\\033[%sm%s\\033[%sm\", implode(';', $setCodes), $text, implode(';', $unsetCodes));\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/output/question/Choice.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\output\\question;\n\nuse think\\console\\output\\Question;\n\nclass Choice extends Question\n{\n\n    private $choices;\n    private $multiselect  = false;\n    private $prompt       = ' > ';\n    private $errorMessage = 'Value \"%s\" is invalid';\n\n    /**\n     * 构造方法\n     * @param string $question 问题\n     * @param array  $choices  选项\n     * @param mixed  $default  默认答案\n     */\n    public function __construct($question, array $choices, $default = null)\n    {\n        parent::__construct($question, $default);\n\n        $this->choices = $choices;\n        $this->setValidator($this->getDefaultValidator());\n        $this->setAutocompleterValues($choices);\n    }\n\n    /**\n     * 可选项\n     * @return array\n     */\n    public function getChoices()\n    {\n        return $this->choices;\n    }\n\n    /**\n     * 设置可否多选\n     * @param bool $multiselect\n     * @return self\n     */\n    public function setMultiselect($multiselect)\n    {\n        $this->multiselect = $multiselect;\n        $this->setValidator($this->getDefaultValidator());\n\n        return $this;\n    }\n\n    public function isMultiselect()\n    {\n        return $this->multiselect;\n    }\n\n    /**\n     * 获取提示\n     * @return string\n     */\n    public function getPrompt()\n    {\n        return $this->prompt;\n    }\n\n    /**\n     * 设置提示\n     * @param string $prompt\n     * @return self\n     */\n    public function setPrompt($prompt)\n    {\n        $this->prompt = $prompt;\n\n        return $this;\n    }\n\n    /**\n     * 设置错误提示信息\n     * @param string $errorMessage\n     * @return self\n     */\n    public function setErrorMessage($errorMessage)\n    {\n        $this->errorMessage = $errorMessage;\n        $this->setValidator($this->getDefaultValidator());\n\n        return $this;\n    }\n\n    /**\n     * 获取默认的验证方法\n     * @return callable\n     */\n    private function getDefaultValidator()\n    {\n        $choices      = $this->choices;\n        $errorMessage = $this->errorMessage;\n        $multiselect  = $this->multiselect;\n        $isAssoc      = $this->isAssoc($choices);\n\n        return function ($selected) use ($choices, $errorMessage, $multiselect, $isAssoc) {\n            // Collapse all spaces.\n            $selectedChoices = str_replace(' ', '', $selected);\n\n            if ($multiselect) {\n                // Check for a separated comma values\n                if (!preg_match('/^[a-zA-Z0-9_-]+(?:,[a-zA-Z0-9_-]+)*$/', $selectedChoices, $matches)) {\n                    throw new \\InvalidArgumentException(sprintf($errorMessage, $selected));\n                }\n                $selectedChoices = explode(',', $selectedChoices);\n            } else {\n                $selectedChoices = [$selected];\n            }\n\n            $multiselectChoices = [];\n            foreach ($selectedChoices as $value) {\n                $results = [];\n                foreach ($choices as $key => $choice) {\n                    if ($choice === $value) {\n                        $results[] = $key;\n                    }\n                }\n\n                if (count($results) > 1) {\n                    throw new \\InvalidArgumentException(sprintf('The provided answer is ambiguous. Value should be one of %s.', implode(' or ', $results)));\n                }\n\n                $result = array_search($value, $choices);\n\n                if (!$isAssoc) {\n                    if (!empty($result)) {\n                        $result = $choices[$result];\n                    } elseif (isset($choices[$value])) {\n                        $result = $choices[$value];\n                    }\n                } elseif (empty($result) && array_key_exists($value, $choices)) {\n                    $result = $value;\n                }\n\n                if (empty($result)) {\n                    throw new \\InvalidArgumentException(sprintf($errorMessage, $value));\n                }\n                array_push($multiselectChoices, $result);\n            }\n\n            if ($multiselect) {\n                return $multiselectChoices;\n            }\n\n            return current($multiselectChoices);\n        };\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/console/output/question/Confirmation.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\console\\output\\question;\n\nuse think\\console\\output\\Question;\n\nclass Confirmation extends Question\n{\n\n    private $trueAnswerRegex;\n\n    /**\n     * 构造方法\n     * @param string $question        问题\n     * @param bool   $default         默认答案\n     * @param string $trueAnswerRegex 验证正则\n     */\n    public function __construct($question, $default = true, $trueAnswerRegex = '/^y/i')\n    {\n        parent::__construct($question, (bool) $default);\n\n        $this->trueAnswerRegex = $trueAnswerRegex;\n        $this->setNormalizer($this->getDefaultNormalizer());\n    }\n\n    /**\n     * 获取默认的答案回调\n     * @return callable\n     */\n    private function getDefaultNormalizer()\n    {\n        $default = $this->getDefault();\n        $regex   = $this->trueAnswerRegex;\n\n        return function ($answer) use ($default, $regex) {\n            if (is_bool($answer)) {\n                return $answer;\n            }\n\n            $answerIsTrue = (bool) preg_match($regex, $answer);\n            if (false === $default) {\n                return $answer && $answerIsTrue;\n            }\n\n            return !$answer || $answerIsTrue;\n        };\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/controller/Rest.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\controller;\n\nuse think\\App;\nuse think\\Request;\nuse think\\Response;\n\nabstract class Rest\n{\n\n    protected $method; // 当前请求类型\n    protected $type; // 当前资源类型\n    // 输出类型\n    protected $restMethodList    = 'get|post|put|delete';\n    protected $restDefaultMethod = 'get';\n    protected $restTypeList      = 'html|xml|json|rss';\n    protected $restDefaultType   = 'html';\n    protected $restOutputType    = [ // REST允许输出的资源类型列表\n        'xml'  => 'application/xml',\n        'json' => 'application/json',\n        'html' => 'text/html',\n    ];\n\n    /**\n     * 构造函数 取得模板对象实例\n     * @access public\n     */\n    public function __construct()\n    {\n        // 资源类型检测\n        $request = Request::instance();\n        $ext     = $request->ext();\n        if ('' == $ext) {\n            // 自动检测资源类型\n            $this->type = $request->type();\n        } elseif (!preg_match('/\\(' . $this->restTypeList . '\\)$/i', $ext)) {\n            // 资源类型非法 则用默认资源类型访问\n            $this->type = $this->restDefaultType;\n        } else {\n            $this->type = $ext;\n        }\n        // 请求方式检测\n        $method = strtolower($request->method());\n        if (false === stripos($this->restMethodList, $method)) {\n            // 请求方式非法 则用默认请求方法\n            $method = $this->restDefaultMethod;\n        }\n        $this->method = $method;\n    }\n\n    /**\n     * REST 调用\n     * @access public\n     * @param string $method 方法名\n     * @return mixed\n     * @throws \\Exception\n     */\n    public function _empty($method)\n    {\n        if (method_exists($this, $method . '_' . $this->method . '_' . $this->type)) {\n            // RESTFul方法支持\n            $fun = $method . '_' . $this->method . '_' . $this->type;\n        } elseif ($this->method == $this->restDefaultMethod && method_exists($this, $method . '_' . $this->type)) {\n            $fun = $method . '_' . $this->type;\n        } elseif ($this->type == $this->restDefaultType && method_exists($this, $method . '_' . $this->method)) {\n            $fun = $method . '_' . $this->method;\n        }\n        if (isset($fun)) {\n            return App::invokeMethod([$this, $fun]);\n        } else {\n            // 抛出异常\n            throw new \\Exception('error action :' . $method);\n        }\n    }\n\n    /**\n     * 输出返回数据\n     * @access protected\n     * @param mixed     $data 要返回的数据\n     * @param String    $type 返回类型 JSON XML\n     * @param integer   $code HTTP状态码\n     * @return Response\n     */\n    protected function response($data, $type = 'json', $code = 200)\n    {\n        return Response::create($data, $type)->code($code);\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/controller/Yar.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2014 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\controller;\n\n/**\n * ThinkPHP Yar控制器类\n */\nabstract class Yar\n{\n\n    /**\n     * 构造函数\n     * @access public\n     */\n    public function __construct()\n    {\n        //控制器初始化\n        if (method_exists($this, '_initialize')) {\n            $this->_initialize();\n        }\n\n        //判断扩展是否存在\n        if (!extension_loaded('yar')) {\n            throw new \\Exception('not support yar');\n        }\n\n        //实例化Yar_Server\n        $server = new \\Yar_Server($this);\n        // 启动server\n        $server->handle();\n    }\n\n    /**\n     * 魔术方法 有不存在的操作的时候执行\n     * @access public\n     * @param string $method 方法名\n     * @param array $args 参数\n     * @return mixed\n     */\n    public function __call($method, $args)\n    {}\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/Builder.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\db;\n\nuse PDO;\nuse think\\Exception;\n\nabstract class Builder\n{\n    // connection对象实例\n    protected $connection;\n    // 查询对象实例\n    protected $query;\n\n    // 数据库表达式\n    protected $exp = ['eq' => '=', 'neq' => '<>', 'gt' => '>', 'egt' => '>=', 'lt' => '<', 'elt' => '<=', 'notlike' => 'NOT LIKE', 'like' => 'LIKE', 'in' => 'IN', 'exp' => 'EXP', 'notin' => 'NOT IN', 'not in' => 'NOT IN', 'between' => 'BETWEEN', 'not between' => 'NOT BETWEEN', 'notbetween' => 'NOT BETWEEN', 'exists' => 'EXISTS', 'notexists' => 'NOT EXISTS', 'not exists' => 'NOT EXISTS', 'null' => 'NULL', 'notnull' => 'NOT NULL', 'not null' => 'NOT NULL', '> time' => '> TIME', '< time' => '< TIME', '>= time' => '>= TIME', '<= time' => '<= TIME', 'between time' => 'BETWEEN TIME', 'not between time' => 'NOT BETWEEN TIME', 'notbetween time' => 'NOT BETWEEN TIME'];\n\n    // SQL表达式\n    protected $selectSql    = 'SELECT%DISTINCT% %FIELD% FROM %TABLE%%FORCE%%JOIN%%WHERE%%GROUP%%HAVING%%ORDER%%LIMIT% %UNION%%LOCK%%COMMENT%';\n    protected $insertSql    = '%INSERT% INTO %TABLE% (%FIELD%) VALUES (%DATA%) %COMMENT%';\n    protected $insertAllSql = 'INSERT INTO %TABLE% (%FIELD%) %DATA% %COMMENT%';\n    protected $updateSql    = 'UPDATE %TABLE% SET %SET% %JOIN% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%';\n    protected $deleteSql    = 'DELETE FROM %TABLE% %USING% %JOIN% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%';\n\n    /**\n     * 构造函数\n     * @access public\n     * @param Connection    $connection 数据库连接对象实例\n     * @param Query         $query      数据库查询对象实例\n     */\n    public function __construct(Connection $connection, Query $query)\n    {\n        $this->connection = $connection;\n        $this->query      = $query;\n    }\n\n    /**\n     * 获取当前的连接对象实例\n     * @access public\n     * @return void\n     */\n    public function getConnection()\n    {\n        return $this->connection;\n    }\n\n    /**\n     * 获取当前的Query对象实例\n     * @access public\n     * @return void\n     */\n    public function getQuery()\n    {\n        return $this->query;\n    }\n\n    /**\n     * 将SQL语句中的__TABLE_NAME__字符串替换成带前缀的表名（小写）\n     * @access protected\n     * @param string $sql sql语句\n     * @return string\n     */\n    protected function parseSqlTable($sql)\n    {\n        return $this->query->parseSqlTable($sql);\n    }\n\n    /**\n     * 数据分析\n     * @access protected\n     * @param array     $data 数据\n     * @param array     $options 查询参数\n     * @return array\n     */\n    protected function parseData($data, $options)\n    {\n        if (empty($data)) {\n            return [];\n        }\n\n        // 获取绑定信息\n        $bind = $this->query->getFieldsBind($options);\n        if ('*' == $options['field']) {\n            $fields = array_keys($bind);\n        } else {\n            $fields = $options['field'];\n        }\n\n        $result = [];\n        foreach ($data as $key => $val) {\n            $item = $this->parseKey($key, $options);\n            if (is_object($val) && method_exists($val, '__toString')) {\n                // 对象数据写入\n                $val = $val->__toString();\n            }\n            if (false === strpos($key, '.') && !in_array($key, $fields, true)) {\n                if ($options['strict']) {\n                    throw new Exception('fields not exists:[' . $key . ']');\n                }\n            } elseif (is_null($val)) {\n                $result[$item] = 'NULL';\n            } elseif (isset($val[0]) && 'exp' == $val[0]) {\n                $result[$item] = $val[1];\n            } elseif (is_scalar($val)) {\n                // 过滤非标量数据\n                if (0 === strpos($val, ':') && $this->query->isBind(substr($val, 1))) {\n                    $result[$item] = $val;\n                } else {\n                    $key = str_replace('.', '_', $key);\n                    $this->query->bind('__data__' . $key, $val, isset($bind[$key]) ? $bind[$key] : PDO::PARAM_STR);\n                    $result[$item] = ':__data__' . $key;\n                }\n            }\n        }\n        return $result;\n    }\n\n    /**\n     * 字段名分析\n     * @access protected\n     * @param string $key\n     * @param array  $options\n     * @return string\n     */\n    protected function parseKey($key, $options = [])\n    {\n        return $key;\n    }\n\n    /**\n     * value分析\n     * @access protected\n     * @param mixed     $value\n     * @param string    $field\n     * @return string|array\n     */\n    protected function parseValue($value, $field = '')\n    {\n        if (is_string($value)) {\n            $value = strpos($value, ':') === 0 && $this->query->isBind(substr($value, 1)) ? $value : $this->connection->quote($value);\n        } elseif (is_array($value)) {\n            $value = array_map([$this, 'parseValue'], $value);\n        } elseif (is_bool($value)) {\n            $value = $value ? '1' : '0';\n        } elseif (is_null($value)) {\n            $value = 'null';\n        }\n        return $value;\n    }\n\n    /**\n     * field分析\n     * @access protected\n     * @param mixed     $fields\n     * @param array     $options\n     * @return string\n     */\n    protected function parseField($fields, $options = [])\n    {\n        if ('*' == $fields || empty($fields)) {\n            $fieldsStr = '*';\n        } elseif (is_array($fields)) {\n            // 支持 'field1'=>'field2' 这样的字段别名定义\n            $array = [];\n            foreach ($fields as $key => $field) {\n                if (!is_numeric($key)) {\n                    $array[] = $this->parseKey($key, $options) . ' AS ' . $this->parseKey($field, $options);\n                } else {\n                    $array[] = $this->parseKey($field, $options);\n                }\n            }\n            $fieldsStr = implode(',', $array);\n        }\n        return $fieldsStr;\n    }\n\n    /**\n     * table分析\n     * @access protected\n     * @param mixed $tables\n     * @param array $options\n     * @return string\n     */\n    protected function parseTable($tables, $options = [])\n    {\n        $item = [];\n        foreach ((array) $tables as $key => $table) {\n            if (!is_numeric($key)) {\n                if (strpos($key, '@think')) {\n                    $key = strstr($key, '@think', true);\n                }\n                $key    = $this->parseSqlTable($key);\n                $item[] = $this->parseKey($key) . ' ' . $this->parseKey($table);\n            } else {\n                $table = $this->parseSqlTable($table);\n                if (isset($options['alias'][$table])) {\n                    $item[] = $this->parseKey($table) . ' ' . $this->parseKey($options['alias'][$table]);\n                } else {\n                    $item[] = $this->parseKey($table);\n                }\n            }\n        }\n        return implode(',', $item);\n    }\n\n    /**\n     * where分析\n     * @access protected\n     * @param mixed $where   查询条件\n     * @param array $options 查询参数\n     * @return string\n     */\n    protected function parseWhere($where, $options)\n    {\n        $whereStr = $this->buildWhere($where, $options);\n        if (!empty($options['soft_delete'])) {\n            // 附加软删除条件\n            list($field, $condition) = $options['soft_delete'];\n\n            $binds    = $this->query->getFieldsBind($options);\n            $whereStr = $whereStr ? '( ' . $whereStr . ' ) AND ' : '';\n            $whereStr = $whereStr . $this->parseWhereItem($field, $condition, '', $options, $binds);\n        }\n        return empty($whereStr) ? '' : ' WHERE ' . $whereStr;\n    }\n\n    /**\n     * 生成查询条件SQL\n     * @access public\n     * @param mixed     $where\n     * @param array     $options\n     * @return string\n     */\n    public function buildWhere($where, $options)\n    {\n        if (empty($where)) {\n            $where = [];\n        }\n\n        if ($where instanceof Query) {\n            return $this->buildWhere($where->getOptions('where'), $options);\n        }\n\n        $whereStr = '';\n        $binds    = $this->query->getFieldsBind($options);\n        foreach ($where as $key => $val) {\n            $str = [];\n            foreach ($val as $field => $value) {\n                if ($value instanceof \\Closure) {\n                    // 使用闭包查询\n                    $query = new Query($this->connection);\n                    call_user_func_array($value, [ & $query]);\n                    $whereClause = $this->buildWhere($query->getOptions('where'), $options);\n                    if (!empty($whereClause)) {\n                        $str[] = ' ' . $key . ' ( ' . $whereClause . ' )';\n                    }\n                } elseif (strpos($field, '|')) {\n                    // 不同字段使用相同查询条件（OR）\n                    $array = explode('|', $field);\n                    $item  = [];\n                    foreach ($array as $k) {\n                        $item[] = $this->parseWhereItem($k, $value, '', $options, $binds);\n                    }\n                    $str[] = ' ' . $key . ' ( ' . implode(' OR ', $item) . ' )';\n                } elseif (strpos($field, '&')) {\n                    // 不同字段使用相同查询条件（AND）\n                    $array = explode('&', $field);\n                    $item  = [];\n                    foreach ($array as $k) {\n                        $item[] = $this->parseWhereItem($k, $value, '', $options, $binds);\n                    }\n                    $str[] = ' ' . $key . ' ( ' . implode(' AND ', $item) . ' )';\n                } else {\n                    // 对字段使用表达式查询\n                    $field = is_string($field) ? $field : '';\n                    $str[] = ' ' . $key . ' ' . $this->parseWhereItem($field, $value, $key, $options, $binds);\n                }\n            }\n\n            $whereStr .= empty($whereStr) ? substr(implode(' ', $str), strlen($key) + 1) : implode(' ', $str);\n        }\n\n        return $whereStr;\n    }\n\n    // where子单元分析\n    protected function parseWhereItem($field, $val, $rule = '', $options = [], $binds = [], $bindName = null)\n    {\n        // 字段分析\n        $key = $field ? $this->parseKey($field, $options) : '';\n\n        // 查询规则和条件\n        if (!is_array($val)) {\n            $val = ['=', $val];\n        }\n        list($exp, $value) = $val;\n\n        // 对一个字段使用多个查询条件\n        if (is_array($exp)) {\n            $item = array_pop($val);\n            // 传入 or 或者 and\n            if (is_string($item) && in_array($item, ['AND', 'and', 'OR', 'or'])) {\n                $rule = $item;\n            } else {\n                array_push($val, $item);\n            }\n            foreach ($val as $k => $item) {\n                $bindName = 'where_' . str_replace('.', '_', $field) . '_' . $k;\n                $str[]    = $this->parseWhereItem($field, $item, $rule, $options, $binds, $bindName);\n            }\n            return '( ' . implode(' ' . $rule . ' ', $str) . ' )';\n        }\n\n        // 检测操作符\n        if (!in_array($exp, $this->exp)) {\n            $exp = strtolower($exp);\n            if (isset($this->exp[$exp])) {\n                $exp = $this->exp[$exp];\n            } else {\n                throw new Exception('where express error:' . $exp);\n            }\n        }\n        $bindName = $bindName ?: 'where_' . str_replace(['.', '-'], '_', $field);\n        if (preg_match('/\\W/', $bindName)) {\n            // 处理带非单词字符的字段名\n            $bindName = md5($bindName);\n        }\n\n        $bindType = isset($binds[$field]) ? $binds[$field] : PDO::PARAM_STR;\n        if (is_scalar($value) && array_key_exists($field, $binds) && !in_array($exp, ['EXP', 'NOT NULL', 'NULL', 'IN', 'NOT IN', 'BETWEEN', 'NOT BETWEEN']) && strpos($exp, 'TIME') === false) {\n            if (strpos($value, ':') !== 0 || !$this->query->isBind(substr($value, 1))) {\n                if ($this->query->isBind($bindName)) {\n                    $bindName .= '_' . str_replace('.', '_', uniqid('', true));\n                }\n                $this->query->bind($bindName, $value, $bindType);\n                $value = ':' . $bindName;\n            }\n        }\n\n        $whereStr = '';\n        if (in_array($exp, ['=', '<>', '>', '>=', '<', '<='])) {\n            // 比较运算 及 模糊匹配\n            $whereStr .= $key . ' ' . $exp . ' ' . $this->parseValue($value, $field);\n        } elseif ('LIKE' == $exp || 'NOT LIKE' == $exp) {\n            if (is_array($value)) {\n                foreach ($value as $item) {\n                    $array[] = $key . ' ' . $exp . ' ' . $this->parseValue($item, $field);\n                }\n                $logic = isset($val[2]) ? $val[2] : 'AND';\n                $whereStr .= '(' . implode($array, ' ' . strtoupper($logic) . ' ') . ')';\n            } else {\n                $whereStr .= $key . ' ' . $exp . ' ' . $this->parseValue($value, $field);\n            }\n        } elseif ('EXP' == $exp) {\n            // 表达式查询\n            $whereStr .= '( ' . $key . ' ' . $value . ' )';\n        } elseif (in_array($exp, ['NOT NULL', 'NULL'])) {\n            // NULL 查询\n            $whereStr .= $key . ' IS ' . $exp;\n        } elseif (in_array($exp, ['NOT IN', 'IN'])) {\n            // IN 查询\n            if ($value instanceof \\Closure) {\n                $whereStr .= $key . ' ' . $exp . ' ' . $this->parseClosure($value);\n            } else {\n                $value = is_array($value) ? $value : explode(',', $value);\n                if (array_key_exists($field, $binds)) {\n                    $bind  = [];\n                    $array = [];\n                    foreach ($value as $k => $v) {\n                        if ($this->query->isBind($bindName . '_in_' . $k)) {\n                            $bindKey = $bindName . '_in_' . uniqid() . '_' . $k;\n                        } else {\n                            $bindKey = $bindName . '_in_' . $k;\n                        }\n                        $bind[$bindKey] = [$v, $bindType];\n                        $array[]        = ':' . $bindKey;\n                    }\n                    $this->query->bind($bind);\n                    $zone = implode(',', $array);\n                } else {\n                    $zone = implode(',', $this->parseValue($value, $field));\n                }\n                $whereStr .= $key . ' ' . $exp . ' (' . (empty($zone) ? \"''\" : $zone) . ')';\n            }\n        } elseif (in_array($exp, ['NOT BETWEEN', 'BETWEEN'])) {\n            // BETWEEN 查询\n            $data = is_array($value) ? $value : explode(',', $value);\n            if (array_key_exists($field, $binds)) {\n                if ($this->query->isBind($bindName . '_between_1')) {\n                    $bindKey1 = $bindName . '_between_1' . uniqid();\n                    $bindKey2 = $bindName . '_between_2' . uniqid();\n                } else {\n                    $bindKey1 = $bindName . '_between_1';\n                    $bindKey2 = $bindName . '_between_2';\n                }\n                $bind = [\n                    $bindKey1 => [$data[0], $bindType],\n                    $bindKey2 => [$data[1], $bindType],\n                ];\n                $this->query->bind($bind);\n                $between = ':' . $bindKey1 . ' AND :' . $bindKey2;\n            } else {\n                $between = $this->parseValue($data[0], $field) . ' AND ' . $this->parseValue($data[1], $field);\n            }\n            $whereStr .= $key . ' ' . $exp . ' ' . $between;\n        } elseif (in_array($exp, ['NOT EXISTS', 'EXISTS'])) {\n            // EXISTS 查询\n            if ($value instanceof \\Closure) {\n                $whereStr .= $exp . ' ' . $this->parseClosure($value);\n            } else {\n                $whereStr .= $exp . ' (' . $value . ')';\n            }\n        } elseif (in_array($exp, ['< TIME', '> TIME', '<= TIME', '>= TIME'])) {\n            $whereStr .= $key . ' ' . substr($exp, 0, 2) . ' ' . $this->parseDateTime($value, $field, $options, $bindName, $bindType);\n        } elseif (in_array($exp, ['BETWEEN TIME', 'NOT BETWEEN TIME'])) {\n            if (is_string($value)) {\n                $value = explode(',', $value);\n            }\n\n            $whereStr .= $key . ' ' . substr($exp, 0, -4) . $this->parseDateTime($value[0], $field, $options, $bindName . '_between_1', $bindType) . ' AND ' . $this->parseDateTime($value[1], $field, $options, $bindName . '_between_2', $bindType);\n        }\n        return $whereStr;\n    }\n\n    // 执行闭包子查询\n    protected function parseClosure($call, $show = true)\n    {\n        $query = new Query($this->connection);\n        call_user_func_array($call, [ & $query]);\n        return $query->buildSql($show);\n    }\n\n    /**\n     * 日期时间条件解析\n     * @access protected\n     * @param string    $value\n     * @param string    $key\n     * @param array     $options\n     * @param string    $bindName\n     * @param integer   $bindType\n     * @return string\n     */\n    protected function parseDateTime($value, $key, $options = [], $bindName = null, $bindType = null)\n    {\n        // 获取时间字段类型\n        if (strpos($key, '.')) {\n            list($table, $key) = explode('.', $key);\n            if (isset($options['alias']) && $pos = array_search($table, $options['alias'])) {\n                $table = $pos;\n            }\n        } else {\n            $table = $options['table'];\n        }\n        $type = $this->query->getTableInfo($table, 'type');\n        if (isset($type[$key])) {\n            $info = $type[$key];\n        }\n        if (isset($info)) {\n            if (is_string($value)) {\n                $value = strtotime($value) ?: $value;\n            }\n\n            if (preg_match('/(datetime|timestamp)/is', $info)) {\n                // 日期及时间戳类型\n                $value = date('Y-m-d H:i:s', $value);\n            } elseif (preg_match('/(date)/is', $info)) {\n                // 日期及时间戳类型\n                $value = date('Y-m-d', $value);\n            }\n        }\n        $bindName = $bindName ?: $key;\n        $this->query->bind($bindName, $value, $bindType);\n        return ':' . $bindName;\n    }\n\n    /**\n     * limit分析\n     * @access protected\n     * @param mixed $lmit\n     * @return string\n     */\n    protected function parseLimit($limit)\n    {\n        return (!empty($limit) && false === strpos($limit, '(')) ? ' LIMIT ' . $limit . ' ' : '';\n    }\n\n    /**\n     * join分析\n     * @access protected\n     * @param array $join\n     * @param array $options 查询条件\n     * @return string\n     */\n    protected function parseJoin($join, $options = [])\n    {\n        $joinStr = '';\n        if (!empty($join)) {\n            foreach ($join as $item) {\n                list($table, $type, $on) = $item;\n                $condition               = [];\n                foreach ((array) $on as $val) {\n                    if (strpos($val, '=')) {\n                        list($val1, $val2) = explode('=', $val, 2);\n                        $condition[]       = $this->parseKey($val1, $options) . '=' . $this->parseKey($val2, $options);\n                    } else {\n                        $condition[] = $val;\n                    }\n                }\n\n                $table = $this->parseTable($table, $options);\n                $joinStr .= ' ' . $type . ' JOIN ' . $table . ' ON ' . implode(' AND ', $condition);\n            }\n        }\n        return $joinStr;\n    }\n\n    /**\n     * order分析\n     * @access protected\n     * @param mixed $order\n     * @param array $options 查询条件\n     * @return string\n     */\n    protected function parseOrder($order, $options = [])\n    {\n        if (is_array($order)) {\n            $array = [];\n            foreach ($order as $key => $val) {\n                if (is_numeric($key)) {\n                    if ('[rand]' == $val) {\n                        $array[] = $this->parseRand();\n                    } elseif (false === strpos($val, '(')) {\n                        $array[] = $this->parseKey($val, $options);\n                    } else {\n                        $array[] = $val;\n                    }\n                } else {\n                    $sort    = in_array(strtolower(trim($val)), ['asc', 'desc']) ? ' ' . $val : '';\n                    $array[] = $this->parseKey($key, $options) . ' ' . $sort;\n                }\n            }\n            $order = implode(',', $array);\n        }\n        return !empty($order) ? ' ORDER BY ' . $order : '';\n    }\n\n    /**\n     * group分析\n     * @access protected\n     * @param mixed $group\n     * @return string\n     */\n    protected function parseGroup($group)\n    {\n        return !empty($group) ? ' GROUP BY ' . $group : '';\n    }\n\n    /**\n     * having分析\n     * @access protected\n     * @param string $having\n     * @return string\n     */\n    protected function parseHaving($having)\n    {\n        return !empty($having) ? ' HAVING ' . $having : '';\n    }\n\n    /**\n     * comment分析\n     * @access protected\n     * @param string $comment\n     * @return string\n     */\n    protected function parseComment($comment)\n    {\n        return !empty($comment) ? ' /* ' . $comment . ' */' : '';\n    }\n\n    /**\n     * distinct分析\n     * @access protected\n     * @param mixed $distinct\n     * @return string\n     */\n    protected function parseDistinct($distinct)\n    {\n        return !empty($distinct) ? ' DISTINCT ' : '';\n    }\n\n    /**\n     * union分析\n     * @access protected\n     * @param mixed $union\n     * @return string\n     */\n    protected function parseUnion($union)\n    {\n        if (empty($union)) {\n            return '';\n        }\n        $type = $union['type'];\n        unset($union['type']);\n        foreach ($union as $u) {\n            if ($u instanceof \\Closure) {\n                $sql[] = $type . ' ' . $this->parseClosure($u, false);\n            } elseif (is_string($u)) {\n                $sql[] = $type . ' ' . $this->parseSqlTable($u);\n            }\n        }\n        return implode(' ', $sql);\n    }\n\n    /**\n     * index分析，可在操作链中指定需要强制使用的索引\n     * @access protected\n     * @param mixed $index\n     * @return string\n     */\n    protected function parseForce($index)\n    {\n        if (empty($index)) {\n            return '';\n        }\n\n        if (is_array($index)) {\n            $index = join(\",\", $index);\n        }\n\n        return sprintf(\" FORCE INDEX ( %s ) \", $index);\n    }\n\n    /**\n     * 设置锁机制\n     * @access protected\n     * @param bool $locl\n     * @return string\n     */\n    protected function parseLock($lock = false)\n    {\n        return $lock ? ' FOR UPDATE ' : '';\n    }\n\n    /**\n     * 生成查询SQL\n     * @access public\n     * @param array $options 表达式\n     * @return string\n     */\n    public function select($options = [])\n    {\n        $sql = str_replace(\n            ['%TABLE%', '%DISTINCT%', '%FIELD%', '%JOIN%', '%WHERE%', '%GROUP%', '%HAVING%', '%ORDER%', '%LIMIT%', '%UNION%', '%LOCK%', '%COMMENT%', '%FORCE%'],\n            [\n                $this->parseTable($options['table'], $options),\n                $this->parseDistinct($options['distinct']),\n                $this->parseField($options['field'], $options),\n                $this->parseJoin($options['join'], $options),\n                $this->parseWhere($options['where'], $options),\n                $this->parseGroup($options['group']),\n                $this->parseHaving($options['having']),\n                $this->parseOrder($options['order'], $options),\n                $this->parseLimit($options['limit']),\n                $this->parseUnion($options['union']),\n                $this->parseLock($options['lock']),\n                $this->parseComment($options['comment']),\n                $this->parseForce($options['force']),\n            ], $this->selectSql);\n        return $sql;\n    }\n\n    /**\n     * 生成insert SQL\n     * @access public\n     * @param array     $data 数据\n     * @param array     $options 表达式\n     * @param bool      $replace 是否replace\n     * @return string\n     */\n    public function insert(array $data, $options = [], $replace = false)\n    {\n        // 分析并处理数据\n        $data = $this->parseData($data, $options);\n        if (empty($data)) {\n            return 0;\n        }\n        $fields = array_keys($data);\n        $values = array_values($data);\n\n        $sql = str_replace(\n            ['%INSERT%', '%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'],\n            [\n                $replace ? 'REPLACE' : 'INSERT',\n                $this->parseTable($options['table'], $options),\n                implode(' , ', $fields),\n                implode(' , ', $values),\n                $this->parseComment($options['comment']),\n            ], $this->insertSql);\n\n        return $sql;\n    }\n\n    /**\n     * 生成insertall SQL\n     * @access public\n     * @param array     $dataSet 数据集\n     * @param array     $options 表达式\n     * @return string\n     */\n    public function insertAll($dataSet, $options)\n    {\n        // 获取合法的字段\n        if ('*' == $options['field']) {\n            $fields = array_keys($this->query->getFieldsType($options));\n        } else {\n            $fields = $options['field'];\n        }\n\n        foreach ($dataSet as &$data) {\n            foreach ($data as $key => $val) {\n                if (!in_array($key, $fields, true)) {\n                    if ($options['strict']) {\n                        throw new Exception('fields not exists:[' . $key . ']');\n                    }\n                    unset($data[$key]);\n                } elseif (is_null($val)) {\n                    $data[$key] = 'NULL';\n                } elseif (is_scalar($val)) {\n                    $data[$key] = $this->parseValue($val, $key);\n                } elseif (is_object($val) && method_exists($val, '__toString')) {\n                    // 对象数据写入\n                    $data[$key] = $val->__toString();\n                } else {\n                    // 过滤掉非标量数据\n                    unset($data[$key]);\n                }\n            }\n            $value    = array_values($data);\n            $values[] = 'SELECT ' . implode(',', $value);\n        }\n        $fields = array_map([$this, 'parseKey'], array_keys(reset($dataSet)));\n        $sql    = str_replace(\n            ['%TABLE%', '%FIELD%', '%DATA%', '%COMMENT%'],\n            [\n                $this->parseTable($options['table'], $options),\n                implode(' , ', $fields),\n                implode(' UNION ALL ', $values),\n                $this->parseComment($options['comment']),\n            ], $this->insertAllSql);\n\n        return $sql;\n    }\n\n    /**\n     * 生成slectinsert SQL\n     * @access public\n     * @param array     $fields 数据\n     * @param string    $table 数据表\n     * @param array     $options 表达式\n     * @return string\n     */\n    public function selectInsert($fields, $table, $options)\n    {\n        if (is_string($fields)) {\n            $fields = explode(',', $fields);\n        }\n\n        $fields = array_map([$this, 'parseKey'], $fields);\n        $sql    = 'INSERT INTO ' . $this->parseTable($table, $options) . ' (' . implode(',', $fields) . ') ' . $this->select($options);\n        return $sql;\n    }\n\n    /**\n     * 生成update SQL\n     * @access public\n     * @param array     $fields 数据\n     * @param array     $options 表达式\n     * @return string\n     */\n    public function update($data, $options)\n    {\n        $table = $this->parseTable($options['table'], $options);\n        $data  = $this->parseData($data, $options);\n        if (empty($data)) {\n            return '';\n        }\n        foreach ($data as $key => $val) {\n            $set[] = $key . '=' . $val;\n        }\n\n        $sql = str_replace(\n            ['%TABLE%', '%SET%', '%JOIN%', '%WHERE%', '%ORDER%', '%LIMIT%', '%LOCK%', '%COMMENT%'],\n            [\n                $this->parseTable($options['table'], $options),\n                implode(',', $set),\n                $this->parseJoin($options['join'], $options),\n                $this->parseWhere($options['where'], $options),\n                $this->parseOrder($options['order'], $options),\n                $this->parseLimit($options['limit']),\n                $this->parseLock($options['lock']),\n                $this->parseComment($options['comment']),\n            ], $this->updateSql);\n\n        return $sql;\n    }\n\n    /**\n     * 生成delete SQL\n     * @access public\n     * @param array $options 表达式\n     * @return string\n     */\n    public function delete($options)\n    {\n        $sql = str_replace(\n            ['%TABLE%', '%USING%', '%JOIN%', '%WHERE%', '%ORDER%', '%LIMIT%', '%LOCK%', '%COMMENT%'],\n            [\n                $this->parseTable($options['table'], $options),\n                !empty($options['using']) ? ' USING ' . $this->parseTable($options['using'], $options) . ' ' : '',\n                $this->parseJoin($options['join'], $options),\n                $this->parseWhere($options['where'], $options),\n                $this->parseOrder($options['order'], $options),\n                $this->parseLimit($options['limit']),\n                $this->parseLock($options['lock']),\n                $this->parseComment($options['comment']),\n            ], $this->deleteSql);\n\n        return $sql;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/Connection.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\db;\n\nuse PDO;\nuse PDOStatement;\nuse think\\Db;\nuse think\\db\\exception\\BindParamException;\nuse think\\Debug;\nuse think\\Exception;\nuse think\\exception\\PDOException;\nuse think\\Log;\n\n/**\n * Class Connection\n * @package think\n * @method Query table(string $table) 指定数据表（含前缀）\n * @method Query name(string $name) 指定数据表（不含前缀）\n *\n */\nabstract class Connection\n{\n\n    /** @var PDOStatement PDO操作实例 */\n    protected $PDOStatement;\n\n    /** @var string 当前SQL指令 */\n    protected $queryStr = '';\n    // 返回或者影响记录数\n    protected $numRows = 0;\n    // 事务指令数\n    protected $transTimes = 0;\n    // 错误信息\n    protected $error = '';\n\n    /** @var PDO[] 数据库连接ID 支持多个连接 */\n    protected $links = [];\n\n    /** @var PDO 当前连接ID */\n    protected $linkID;\n    protected $linkRead;\n    protected $linkWrite;\n\n    // 查询结果类型\n    protected $fetchType = PDO::FETCH_ASSOC;\n    // 字段属性大小写\n    protected $attrCase = PDO::CASE_LOWER;\n    // 监听回调\n    protected static $event = [];\n    // 查询对象\n    protected $query = [];\n    // 使用Builder类\n    protected $builder;\n    // 数据库连接参数配置\n    protected $config = [\n        // 数据库类型\n        'type'            => '',\n        // 服务器地址\n        'hostname'        => '',\n        // 数据库名\n        'database'        => '',\n        // 用户名\n        'username'        => '',\n        // 密码\n        'password'        => '',\n        // 端口\n        'hostport'        => '',\n        // 连接dsn\n        'dsn'             => '',\n        // 数据库连接参数\n        'params'          => [],\n        // 数据库编码默认采用utf8\n        'charset'         => 'utf8',\n        // 数据库表前缀\n        'prefix'          => '',\n        // 数据库调试模式\n        'debug'           => false,\n        // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)\n        'deploy'          => 0,\n        // 数据库读写是否分离 主从式有效\n        'rw_separate'     => false,\n        // 读写分离后 主服务器数量\n        'master_num'      => 1,\n        // 指定从服务器序号\n        'slave_no'        => '',\n        // 是否严格检查字段是否存在\n        'fields_strict'   => true,\n        // 数据返回类型\n        'result_type'     => PDO::FETCH_ASSOC,\n        // 数据集返回类型\n        'resultset_type'  => 'array',\n        // 自动写入时间戳字段\n        'auto_timestamp'  => false,\n        // 时间字段取出后的默认时间格式\n        'datetime_format' => 'Y-m-d H:i:s',\n        // 是否需要进行SQL性能分析\n        'sql_explain'     => false,\n        // Builder类\n        'builder'         => '',\n        // Query类\n        'query'           => '\\\\think\\\\db\\\\Query',\n        // 是否需要断线重连\n        'break_reconnect' => false,\n    ];\n\n    // PDO连接参数\n    protected $params = [\n        PDO::ATTR_CASE              => PDO::CASE_NATURAL,\n        PDO::ATTR_ERRMODE           => PDO::ERRMODE_EXCEPTION,\n        PDO::ATTR_ORACLE_NULLS      => PDO::NULL_NATURAL,\n        PDO::ATTR_STRINGIFY_FETCHES => false,\n        PDO::ATTR_EMULATE_PREPARES  => false,\n    ];\n\n    // 绑定参数\n    protected $bind = [];\n\n    /**\n     * 构造函数 读取数据库配置信息\n     * @access public\n     * @param array $config 数据库配置数组\n     */\n    public function __construct(array $config = [])\n    {\n        if (!empty($config)) {\n            $this->config = array_merge($this->config, $config);\n        }\n    }\n\n    /**\n     * 指定当前使用的查询对象\n     * @access public\n     * @param Query $query 查询对象\n     * @return $this\n     */\n    public function setQuery($query, $model = 'db')\n    {\n        $this->query[$model] = $query;\n\n        return $this;\n    }\n\n    /**\n     * 创建指定模型的查询对象\n     * @access public\n     * @return Query\n     */\n    public function getQuery($model = 'db')\n    {\n        if (!isset($this->query[$model])) {\n            $class = $this->config['query'];\n\n            $this->query[$model] = new $class($this, 'db' == $model ? '' : $model);\n        }\n\n        return $this->query[$model];\n    }\n\n    /**\n     * 获取当前连接器类对应的Builder类\n     * @access public\n     * @return string\n     */\n    public function getBuilder()\n    {\n        if (!empty($this->builder)) {\n            return $this->builder;\n        } else {\n            return $this->getConfig('builder') ?: '\\\\think\\\\db\\\\builder\\\\' . ucfirst($this->getConfig('type'));\n        }\n    }\n\n    /**\n     * 调用Query类的查询方法\n     * @access public\n     * @param string    $method 方法名称\n     * @param array     $args 调用参数\n     * @return mixed\n     */\n    public function __call($method, $args)\n    {\n        return call_user_func_array([$this->getQuery(), $method], $args);\n    }\n\n    /**\n     * 解析pdo连接的dsn信息\n     * @access protected\n     * @param array $config 连接信息\n     * @return string\n     */\n    abstract protected function parseDsn($config);\n\n    /**\n     * 取得数据表的字段信息\n     * @access public\n     * @param string $tableName\n     * @return array\n     */\n    abstract public function getFields($tableName);\n\n    /**\n     * 取得数据库的表信息\n     * @access public\n     * @param string $dbName\n     * @return array\n     */\n    abstract public function getTables($dbName);\n\n    /**\n     * SQL性能分析\n     * @access protected\n     * @param string $sql\n     * @return array\n     */\n    abstract protected function getExplain($sql);\n\n    /**\n     * 对返数据表字段信息进行大小写转换出来\n     * @access public\n     * @param array $info 字段信息\n     * @return array\n     */\n    public function fieldCase($info)\n    {\n        // 字段大小写转换\n        switch ($this->attrCase) {\n            case PDO::CASE_LOWER:\n                $info = array_change_key_case($info);\n                break;\n            case PDO::CASE_UPPER:\n                $info = array_change_key_case($info, CASE_UPPER);\n                break;\n            case PDO::CASE_NATURAL:\n            default:\n                // 不做转换\n        }\n        return $info;\n    }\n\n    /**\n     * 获取数据库的配置参数\n     * @access public\n     * @param string $config 配置名称\n     * @return mixed\n     */\n    public function getConfig($config = '')\n    {\n        return $config ? $this->config[$config] : $this->config;\n    }\n\n    /**\n     * 设置数据库的配置参数\n     * @access public\n     * @param string|array      $config 配置名称\n     * @param mixed             $value 配置值\n     * @return void\n     */\n    public function setConfig($config, $value = '')\n    {\n        if (is_array($config)) {\n            $this->config = array_merge($this->config, $config);\n        } else {\n            $this->config[$config] = $value;\n        }\n    }\n\n    /**\n     * 连接数据库方法\n     * @access public\n     * @param array         $config 连接参数\n     * @param integer       $linkNum 连接序号\n     * @param array|bool    $autoConnection 是否自动连接主数据库（用于分布式）\n     * @return PDO\n     * @throws Exception\n     */\n    public function connect(array $config = [], $linkNum = 0, $autoConnection = false)\n    {\n        if (!isset($this->links[$linkNum])) {\n            if (!$config) {\n                $config = $this->config;\n            } else {\n                $config = array_merge($this->config, $config);\n            }\n            // 连接参数\n            if (isset($config['params']) && is_array($config['params'])) {\n                $params = $config['params'] + $this->params;\n            } else {\n                $params = $this->params;\n            }\n            // 记录当前字段属性大小写设置\n            $this->attrCase = $params[PDO::ATTR_CASE];\n\n            // 数据返回类型\n            if (isset($config['result_type'])) {\n                $this->fetchType = $config['result_type'];\n            }\n            try {\n                if (empty($config['dsn'])) {\n                    $config['dsn'] = $this->parseDsn($config);\n                }\n                if ($config['debug']) {\n                    $startTime = microtime(true);\n                }\n                $this->links[$linkNum] = new PDO($config['dsn'], $config['username'], $config['password'], $params);\n                if ($config['debug']) {\n                    // 记录数据库连接信息\n                    Log::record('[ DB ] CONNECT:[ UseTime:' . number_format(microtime(true) - $startTime, 6) . 's ] ' . $config['dsn'], 'sql');\n                }\n            } catch (\\PDOException $e) {\n                if ($autoConnection) {\n                    Log::record($e->getMessage(), 'error');\n                    return $this->connect($autoConnection, $linkNum);\n                } else {\n                    throw $e;\n                }\n            }\n        }\n        return $this->links[$linkNum];\n    }\n\n    /**\n     * 释放查询结果\n     * @access public\n     */\n    public function free()\n    {\n        $this->PDOStatement = null;\n    }\n\n    /**\n     * 获取PDO对象\n     * @access public\n     * @return \\PDO|false\n     */\n    public function getPdo()\n    {\n        if (!$this->linkID) {\n            return false;\n        } else {\n            return $this->linkID;\n        }\n    }\n\n    /**\n     * 执行查询 返回数据集\n     * @access public\n     * @param string        $sql sql指令\n     * @param array         $bind 参数绑定\n     * @param bool          $master 是否在主服务器读操作\n     * @param bool          $pdo 是否返回PDO对象\n     * @return mixed\n     * @throws BindParamException\n     * @throws PDOException\n     */\n    public function query($sql, $bind = [], $master = false, $pdo = false)\n    {\n        $this->initConnect($master);\n        if (!$this->linkID) {\n            return false;\n        }\n\n        // 记录SQL语句\n        $this->queryStr = $sql;\n        if ($bind) {\n            $this->bind = $bind;\n        }\n\n        // 释放前次的查询结果\n        if (!empty($this->PDOStatement)) {\n            $this->free();\n        }\n\n        Db::$queryTimes++;\n        try {\n            // 调试开始\n            $this->debug(true);\n            // 预处理\n            if (empty($this->PDOStatement)) {\n                $this->PDOStatement = $this->linkID->prepare($sql);\n            }\n            // 是否为存储过程调用\n            $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']);\n            // 参数绑定\n            if ($procedure) {\n                $this->bindParam($bind);\n            } else {\n                $this->bindValue($bind);\n            }\n            // 执行查询\n            $this->PDOStatement->execute();\n            // 调试结束\n            $this->debug(false);\n            // 返回结果集\n            return $this->getResult($pdo, $procedure);\n        } catch (\\PDOException $e) {\n            if ($this->config['break_reconnect'] && $this->isBreak($e)) {\n                return $this->close()->query($sql, $bind, $master, $pdo);\n            }\n            throw new PDOException($e, $this->config, $this->getLastsql());\n        }\n    }\n\n    /**\n     * 执行语句\n     * @access public\n     * @param string        $sql sql指令\n     * @param array         $bind 参数绑定\n     * @return int\n     * @throws BindParamException\n     * @throws PDOException\n     */\n    public function execute($sql, $bind = [])\n    {\n        $this->initConnect(true);\n        if (!$this->linkID) {\n            return false;\n        }\n\n        // 记录SQL语句\n        $this->queryStr = $sql;\n        if ($bind) {\n            $this->bind = $bind;\n        }\n\n        //释放前次的查询结果\n        if (!empty($this->PDOStatement) && $this->PDOStatement->queryString != $sql) {\n            $this->free();\n        }\n\n        Db::$executeTimes++;\n        try {\n            // 调试开始\n            $this->debug(true);\n            // 预处理\n            if (empty($this->PDOStatement)) {\n                $this->PDOStatement = $this->linkID->prepare($sql);\n            }\n            // 是否为存储过程调用\n            $procedure = in_array(strtolower(substr(trim($sql), 0, 4)), ['call', 'exec']);\n            // 参数绑定\n            if ($procedure) {\n                $this->bindParam($bind);\n            } else {\n                $this->bindValue($bind);\n            }\n            // 执行语句\n            $this->PDOStatement->execute();\n            // 调试结束\n            $this->debug(false);\n\n            $this->numRows = $this->PDOStatement->rowCount();\n            return $this->numRows;\n        } catch (\\PDOException $e) {\n            if ($this->config['break_reconnect'] && $this->isBreak($e)) {\n                return $this->close()->execute($sql, $bind);\n            }\n            throw new PDOException($e, $this->config, $this->getLastsql());\n        }\n    }\n\n    /**\n     * 根据参数绑定组装最终的SQL语句 便于调试\n     * @access public\n     * @param string    $sql 带参数绑定的sql语句\n     * @param array     $bind 参数绑定列表\n     * @return string\n     */\n    public function getRealSql($sql, array $bind = [])\n    {\n        foreach ($bind as $key => $val) {\n            $value = is_array($val) ? $val[0] : $val;\n            $type  = is_array($val) ? $val[1] : PDO::PARAM_STR;\n            if (PDO::PARAM_STR == $type) {\n                $value = $this->quote($value);\n            } elseif (PDO::PARAM_INT == $type) {\n                $value = (float) $value;\n            }\n            // 判断占位符\n            $sql = is_numeric($key) ?\n            substr_replace($sql, $value, strpos($sql, '?'), 1) :\n            str_replace(\n                [':' . $key . ')', ':' . $key . ',', ':' . $key . ' '],\n                [$value . ')', $value . ',', $value . ' '],\n                $sql . ' ');\n        }\n        return rtrim($sql);\n    }\n\n    /**\n     * 参数绑定\n     * 支持 ['name'=>'value','id'=>123] 对应命名占位符\n     * 或者 ['value',123] 对应问号占位符\n     * @access public\n     * @param array $bind 要绑定的参数列表\n     * @return void\n     * @throws BindParamException\n     */\n    protected function bindValue(array $bind = [])\n    {\n        foreach ($bind as $key => $val) {\n            // 占位符\n            $param = is_numeric($key) ? $key + 1 : ':' . $key;\n            if (is_array($val)) {\n                if (PDO::PARAM_INT == $val[1] && '' === $val[0]) {\n                    $val[0] = 0;\n                }\n                $result = $this->PDOStatement->bindValue($param, $val[0], $val[1]);\n            } else {\n                $result = $this->PDOStatement->bindValue($param, $val);\n            }\n            if (!$result) {\n                throw new BindParamException(\n                    \"Error occurred  when binding parameters '{$param}'\",\n                    $this->config,\n                    $this->getLastsql(),\n                    $bind\n                );\n            }\n        }\n    }\n\n    /**\n     * 存储过程的输入输出参数绑定\n     * @access public\n     * @param array $bind 要绑定的参数列表\n     * @return void\n     * @throws BindParamException\n     */\n    protected function bindParam($bind)\n    {\n        foreach ($bind as $key => $val) {\n            $param = is_numeric($key) ? $key + 1 : ':' . $key;\n            if (is_array($val)) {\n                array_unshift($val, $param);\n                $result = call_user_func_array([$this->PDOStatement, 'bindParam'], $val);\n            } else {\n                $result = $this->PDOStatement->bindValue($param, $val);\n            }\n            if (!$result) {\n                $param = array_shift($val);\n                throw new BindParamException(\n                    \"Error occurred  when binding parameters '{$param}'\",\n                    $this->config,\n                    $this->getLastsql(),\n                    $bind\n                );\n            }\n        }\n    }\n\n    /**\n     * 获得数据集数组\n     * @access protected\n     * @param bool   $pdo 是否返回PDOStatement\n     * @param bool   $procedure 是否存储过程\n     * @return array\n     */\n    protected function getResult($pdo = false, $procedure = false)\n    {\n        if ($pdo) {\n            // 返回PDOStatement对象处理\n            return $this->PDOStatement;\n        }\n        if ($procedure) {\n            // 存储过程返回结果\n            return $this->procedure();\n        }\n        $result        = $this->PDOStatement->fetchAll($this->fetchType);\n        $this->numRows = count($result);\n        return $result;\n    }\n\n    /**\n     * 获得存储过程数据集\n     * @access protected\n     * @return array\n     */\n    protected function procedure()\n    {\n        $item = [];\n        do {\n            $result = $this->getResult();\n            if ($result) {\n                $item[] = $result;\n            }\n        } while ($this->PDOStatement->nextRowset());\n        $this->numRows = count($item);\n        return $item;\n    }\n\n    /**\n     * 执行数据库事务\n     * @access public\n     * @param callable $callback 数据操作方法回调\n     * @return mixed\n     * @throws PDOException\n     * @throws \\Exception\n     * @throws \\Throwable\n     */\n    public function transaction($callback)\n    {\n        $this->startTrans();\n        try {\n            $result = null;\n            if (is_callable($callback)) {\n                $result = call_user_func_array($callback, [$this]);\n            }\n            $this->commit();\n            return $result;\n        } catch (\\Exception $e) {\n            $this->rollback();\n            throw $e;\n        } catch (\\Throwable $e) {\n            $this->rollback();\n            throw $e;\n        }\n    }\n\n    /**\n     * 启动事务\n     * @access public\n     * @return void\n     */\n    public function startTrans()\n    {\n        $this->initConnect(true);\n        if (!$this->linkID) {\n            return false;\n        }\n\n        ++$this->transTimes;\n\n        if (1 == $this->transTimes) {\n            $this->linkID->beginTransaction();\n        } elseif ($this->transTimes > 1 && $this->supportSavepoint()) {\n            $this->linkID->exec(\n                $this->parseSavepoint('trans' . $this->transTimes)\n            );\n        }\n    }\n\n    /**\n     * 用于非自动提交状态下面的查询提交\n     * @access public\n     * @return void\n     * @throws PDOException\n     */\n    public function commit()\n    {\n        $this->initConnect(true);\n\n        if (1 == $this->transTimes) {\n            $this->linkID->commit();\n        }\n\n        --$this->transTimes;\n    }\n\n    /**\n     * 事务回滚\n     * @access public\n     * @return void\n     * @throws PDOException\n     */\n    public function rollback()\n    {\n        $this->initConnect(true);\n\n        if (1 == $this->transTimes) {\n            $this->linkID->rollBack();\n        } elseif ($this->transTimes > 1 && $this->supportSavepoint()) {\n            $this->linkID->exec(\n                $this->parseSavepointRollBack('trans' . $this->transTimes)\n            );\n        }\n\n        $this->transTimes = max(0, $this->transTimes - 1);\n    }\n\n    /**\n     * 是否支持事务嵌套\n     * @return bool\n     */\n    protected function supportSavepoint()\n    {\n        return false;\n    }\n\n    /**\n     * 生成定义保存点的SQL\n     * @param $name\n     * @return string\n     */\n    protected function parseSavepoint($name)\n    {\n        return 'SAVEPOINT ' . $name;\n    }\n\n    /**\n     * 生成回滚到保存点的SQL\n     * @param $name\n     * @return string\n     */\n    protected function parseSavepointRollBack($name)\n    {\n        return 'ROLLBACK TO SAVEPOINT ' . $name;\n    }\n\n    /**\n     * 批处理执行SQL语句\n     * 批处理的指令都认为是execute操作\n     * @access public\n     * @param array $sqlArray SQL批处理指令\n     * @return boolean\n     */\n    public function batchQuery($sqlArray = [])\n    {\n        if (!is_array($sqlArray)) {\n            return false;\n        }\n        // 自动启动事务支持\n        $this->startTrans();\n        try {\n            foreach ($sqlArray as $sql) {\n                $this->execute($sql);\n            }\n            // 提交事务\n            $this->commit();\n        } catch (\\Exception $e) {\n            $this->rollback();\n            throw $e;\n        }\n        return true;\n    }\n\n    /**\n     * 获得查询次数\n     * @access public\n     * @param boolean $execute 是否包含所有查询\n     * @return integer\n     */\n    public function getQueryTimes($execute = false)\n    {\n        return $execute ? Db::$queryTimes + Db::$executeTimes : Db::$queryTimes;\n    }\n\n    /**\n     * 获得执行次数\n     * @access public\n     * @return integer\n     */\n    public function getExecuteTimes()\n    {\n        return Db::$executeTimes;\n    }\n\n    /**\n     * 关闭数据库（或者重新连接）\n     * @access public\n     * @return $this\n     */\n    public function close()\n    {\n        $this->linkID    = null;\n        $this->linkWrite = null;\n        $this->linkRead  = null;\n        $this->links     = [];\n        return $this;\n    }\n\n    /**\n     * 是否断线\n     * @access protected\n     * @param \\PDOException  $e 异常\n     * @return bool\n     */\n    protected function isBreak($e)\n    {\n        return false;\n    }\n\n    /**\n     * 获取最近一次查询的sql语句\n     * @access public\n     * @return string\n     */\n    public function getLastSql()\n    {\n        return $this->getRealSql($this->queryStr, $this->bind);\n    }\n\n    /**\n     * 获取最近插入的ID\n     * @access public\n     * @param string  $sequence     自增序列名\n     * @return string\n     */\n    public function getLastInsID($sequence = null)\n    {\n        return $this->linkID->lastInsertId($sequence);\n    }\n\n    /**\n     * 获取返回或者影响的记录数\n     * @access public\n     * @return integer\n     */\n    public function getNumRows()\n    {\n        return $this->numRows;\n    }\n\n    /**\n     * 获取最近的错误信息\n     * @access public\n     * @return string\n     */\n    public function getError()\n    {\n        if ($this->PDOStatement) {\n            $error = $this->PDOStatement->errorInfo();\n            $error = $error[1] . ':' . $error[2];\n        } else {\n            $error = '';\n        }\n        if ('' != $this->queryStr) {\n            $error .= \"\\n [ SQL语句 ] : \" . $this->getLastsql();\n        }\n        return $error;\n    }\n\n    /**\n     * SQL指令安全过滤\n     * @access public\n     * @param string $str SQL字符串\n     * @param bool   $master 是否主库查询\n     * @return string\n     */\n    public function quote($str, $master = true)\n    {\n        $this->initConnect($master);\n        return $this->linkID ? $this->linkID->quote($str) : $str;\n    }\n\n    /**\n     * 数据库调试 记录当前SQL及分析性能\n     * @access protected\n     * @param boolean $start 调试开始标记 true 开始 false 结束\n     * @param string  $sql 执行的SQL语句 留空自动获取\n     * @return void\n     */\n    protected function debug($start, $sql = '')\n    {\n        if (!empty($this->config['debug'])) {\n            // 开启数据库调试模式\n            if ($start) {\n                Debug::remark('queryStartTime', 'time');\n            } else {\n                // 记录操作结束时间\n                Debug::remark('queryEndTime', 'time');\n                $runtime = Debug::getRangeTime('queryStartTime', 'queryEndTime');\n                $sql     = $sql ?: $this->getLastsql();\n                $log     = $sql . ' [ RunTime:' . $runtime . 's ]';\n                $result  = [];\n                // SQL性能分析\n                if ($this->config['sql_explain'] && 0 === stripos(trim($sql), 'select')) {\n                    $result = $this->getExplain($sql);\n                }\n                // SQL监听\n                $this->trigger($sql, $runtime, $result);\n            }\n        }\n    }\n\n    /**\n     * 监听SQL执行\n     * @access public\n     * @param callable $callback 回调方法\n     * @return void\n     */\n    public function listen($callback)\n    {\n        self::$event[] = $callback;\n    }\n\n    /**\n     * 触发SQL事件\n     * @access protected\n     * @param string    $sql SQL语句\n     * @param float     $runtime SQL运行时间\n     * @param mixed     $explain SQL分析\n     * @return bool\n     */\n    protected function trigger($sql, $runtime, $explain = [])\n    {\n        if (!empty(self::$event)) {\n            foreach (self::$event as $callback) {\n                if (is_callable($callback)) {\n                    call_user_func_array($callback, [$sql, $runtime, $explain]);\n                }\n            }\n        } else {\n            // 未注册监听则记录到日志中\n            Log::record('[ SQL ] ' . $sql . ' [ RunTime:' . $runtime . 's ]', 'sql');\n            if (!empty($explain)) {\n                Log::record('[ EXPLAIN : ' . var_export($explain, true) . ' ]', 'sql');\n            }\n        }\n    }\n\n    /**\n     * 初始化数据库连接\n     * @access protected\n     * @param boolean $master 是否主服务器\n     * @return void\n     */\n    protected function initConnect($master = true)\n    {\n        if (!empty($this->config['deploy'])) {\n            // 采用分布式数据库\n            if ($master || $this->transTimes) {\n                if (!$this->linkWrite) {\n                    $this->linkWrite = $this->multiConnect(true);\n                }\n                $this->linkID = $this->linkWrite;\n            } else {\n                if (!$this->linkRead) {\n                    $this->linkRead = $this->multiConnect(false);\n                }\n                $this->linkID = $this->linkRead;\n            }\n        } elseif (!$this->linkID) {\n            // 默认单数据库\n            $this->linkID = $this->connect();\n        }\n    }\n\n    /**\n     * 连接分布式服务器\n     * @access protected\n     * @param boolean $master 主服务器\n     * @return PDO\n     */\n    protected function multiConnect($master = false)\n    {\n        $_config = [];\n        // 分布式数据库配置解析\n        foreach (['username', 'password', 'hostname', 'hostport', 'database', 'dsn', 'charset'] as $name) {\n            $_config[$name] = explode(',', $this->config[$name]);\n        }\n\n        // 主服务器序号\n        $m = floor(mt_rand(0, $this->config['master_num'] - 1));\n\n        if ($this->config['rw_separate']) {\n            // 主从式采用读写分离\n            if ($master) // 主服务器写入\n            {\n                $r = $m;\n            } elseif (is_numeric($this->config['slave_no'])) {\n                // 指定服务器读\n                $r = $this->config['slave_no'];\n            } else {\n                // 读操作连接从服务器 每次随机连接的数据库\n                $r = floor(mt_rand($this->config['master_num'], count($_config['hostname']) - 1));\n            }\n        } else {\n            // 读写操作不区分服务器 每次随机连接的数据库\n            $r = floor(mt_rand(0, count($_config['hostname']) - 1));\n        }\n        $dbMaster = false;\n        if ($m != $r) {\n            $dbMaster = [];\n            foreach (['username', 'password', 'hostname', 'hostport', 'database', 'dsn', 'charset'] as $name) {\n                $dbMaster[$name] = isset($_config[$name][$m]) ? $_config[$name][$m] : $_config[$name][0];\n            }\n        }\n        $dbConfig = [];\n        foreach (['username', 'password', 'hostname', 'hostport', 'database', 'dsn', 'charset'] as $name) {\n            $dbConfig[$name] = isset($_config[$name][$r]) ? $_config[$name][$r] : $_config[$name][0];\n        }\n        return $this->connect($dbConfig, $r, $r == $m ? false : $dbMaster);\n    }\n\n    /**\n     * 析构方法\n     * @access public\n     */\n    public function __destruct()\n    {\n        // 释放查询\n        if ($this->PDOStatement) {\n            $this->free();\n        }\n        // 关闭连接\n        $this->close();\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/Query.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\db;\n\nuse PDO;\nuse think\\Cache;\nuse think\\Collection;\nuse think\\Config;\nuse think\\Db;\nuse think\\db\\exception\\BindParamException;\nuse think\\db\\exception\\DataNotFoundException;\nuse think\\db\\exception\\ModelNotFoundException;\nuse think\\Exception;\nuse think\\exception\\DbException;\nuse think\\exception\\PDOException;\nuse think\\Loader;\nuse think\\Model;\nuse think\\model\\Relation;\nuse think\\model\\relation\\OneToOne;\nuse think\\Paginator;\n\nclass Query\n{\n    // 数据库Connection对象实例\n    protected $connection;\n    // 数据库Builder对象实例\n    protected $builder;\n    // 当前模型类名称\n    protected $model;\n    // 当前数据表名称（含前缀）\n    protected $table = '';\n    // 当前数据表名称（不含前缀）\n    protected $name = '';\n    // 当前数据表主键\n    protected $pk;\n    // 当前数据表前缀\n    protected $prefix = '';\n    // 查询参数\n    protected $options = [];\n    // 参数绑定\n    protected $bind = [];\n    // 数据表信息\n    protected static $info = [];\n    // 回调事件\n    private static $event = [];\n\n    /**\n     * 构造函数\n     * @access public\n     * @param Connection $connection 数据库对象实例\n     * @param string     $model      模型名\n     */\n    public function __construct(Connection $connection = null, $model = '')\n    {\n        $this->connection = $connection ?: Db::connect([], true);\n        $this->prefix     = $this->connection->getConfig('prefix');\n        $this->model      = $model;\n        // 设置当前连接的Builder对象\n        $this->setBuilder();\n    }\n\n    /**\n     * 利用__call方法实现一些特殊的Model方法\n     * @access public\n     * @param string $method 方法名称\n     * @param array  $args   调用参数\n     * @return mixed\n     * @throws DbException\n     * @throws Exception\n     */\n    public function __call($method, $args)\n    {\n        if (strtolower(substr($method, 0, 5)) == 'getby') {\n            // 根据某个字段获取记录\n            $field         = Loader::parseName(substr($method, 5));\n            $where[$field] = $args[0];\n            return $this->where($where)->find();\n        } elseif (strtolower(substr($method, 0, 10)) == 'getfieldby') {\n            // 根据某个字段获取记录的某个值\n            $name         = Loader::parseName(substr($method, 10));\n            $where[$name] = $args[0];\n            return $this->where($where)->value($args[1]);\n        } else {\n            throw new Exception('method not exist:' . __CLASS__ . '->' . $method);\n        }\n    }\n\n    /**\n     * 获取当前的数据库Connection对象\n     * @access public\n     * @return Connection\n     */\n    public function getConnection()\n    {\n        return $this->connection;\n    }\n\n    /**\n     * 切换当前的数据库连接\n     * @access public\n     * @param mixed $config\n     * @return $this\n     */\n    public function connect($config)\n    {\n        $this->connection = Db::connect($config);\n        $this->setBuilder();\n        return $this;\n    }\n\n    /**\n     * 设置当前的数据库Builder对象\n     * @access protected\n     * @return void\n     */\n    protected function setBuilder()\n    {\n        $class         = $this->connection->getBuilder();\n        $this->builder = new $class($this->connection, $this);\n    }\n\n    /**\n     * 获取当前的模型对象名\n     * @access public\n     * @return string\n     */\n    public function getModel()\n    {\n        return $this->model;\n    }\n\n    /**\n     * 获取当前的builder实例对象\n     * @access public\n     * @return Builder\n     */\n    public function getBuilder()\n    {\n        return $this->builder;\n    }\n\n    /**\n     * 指定默认的数据表名（不含前缀）\n     * @access public\n     * @param string $name\n     * @return $this\n     */\n    public function name($name)\n    {\n        $this->name = $name;\n        return $this;\n    }\n\n    /**\n     * 指定默认数据表名（含前缀）\n     * @access public\n     * @param string $table 表名\n     * @return $this\n     */\n    public function setTable($table)\n    {\n        $this->table = $table;\n        return $this;\n    }\n\n    /**\n     * 得到当前或者指定名称的数据表\n     * @access public\n     * @param string $name\n     * @return string\n     */\n    public function getTable($name = '')\n    {\n        if ($name || empty($this->table)) {\n            $name      = $name ?: $this->name;\n            $tableName = $this->prefix;\n            if ($name) {\n                $tableName .= Loader::parseName($name);\n            }\n        } else {\n            $tableName = $this->table;\n        }\n        return $tableName;\n    }\n\n    /**\n     * 将SQL语句中的__TABLE_NAME__字符串替换成带前缀的表名（小写）\n     * @access public\n     * @param string $sql sql语句\n     * @return string\n     */\n    public function parseSqlTable($sql)\n    {\n        if (false !== strpos($sql, '__')) {\n            $prefix = $this->prefix;\n            $sql    = preg_replace_callback(\"/__([A-Z0-9_-]+)__/sU\", function ($match) use ($prefix) {\n                return $prefix . strtolower($match[1]);\n            }, $sql);\n        }\n        return $sql;\n    }\n\n    /**\n     * 执行查询 返回数据集\n     * @access public\n     * @param string      $sql    sql指令\n     * @param array       $bind   参数绑定\n     * @param boolean     $master 是否在主服务器读操作\n     * @param bool|string $class  指定返回的数据集对象\n     * @return mixed\n     * @throws BindParamException\n     * @throws PDOException\n     */\n    public function query($sql, $bind = [], $master = false, $class = false)\n    {\n        return $this->connection->query($sql, $bind, $master, $class);\n    }\n\n    /**\n     * 执行语句\n     * @access public\n     * @param string $sql  sql指令\n     * @param array  $bind 参数绑定\n     * @return int\n     * @throws BindParamException\n     * @throws PDOException\n     */\n    public function execute($sql, $bind = [])\n    {\n        return $this->connection->execute($sql, $bind);\n    }\n\n    /**\n     * 获取最近插入的ID\n     * @access public\n     * @param string $sequence 自增序列名\n     * @return string\n     */\n    public function getLastInsID($sequence = null)\n    {\n        return $this->connection->getLastInsID($sequence);\n    }\n\n    /**\n     * 获取最近一次查询的sql语句\n     * @access public\n     * @return string\n     */\n    public function getLastSql()\n    {\n        return $this->connection->getLastSql();\n    }\n\n    /**\n     * 执行数据库事务\n     * @access public\n     * @param callable $callback 数据操作方法回调\n     * @return mixed\n     */\n    public function transaction($callback)\n    {\n        return $this->connection->transaction($callback);\n    }\n\n    /**\n     * 启动事务\n     * @access public\n     * @return void\n     */\n    public function startTrans()\n    {\n        $this->connection->startTrans();\n    }\n\n    /**\n     * 用于非自动提交状态下面的查询提交\n     * @access public\n     * @return void\n     * @throws PDOException\n     */\n    public function commit()\n    {\n        $this->connection->commit();\n    }\n\n    /**\n     * 事务回滚\n     * @access public\n     * @return void\n     * @throws PDOException\n     */\n    public function rollback()\n    {\n        $this->connection->rollback();\n    }\n\n    /**\n     * 批处理执行SQL语句\n     * 批处理的指令都认为是execute操作\n     * @access public\n     * @param array $sql SQL批处理指令\n     * @return boolean\n     */\n    public function batchQuery($sql = [])\n    {\n        return $this->connection->batchQuery($sql);\n    }\n\n    /**\n     * 获取数据库的配置参数\n     * @access public\n     * @param string $name 参数名称\n     * @return boolean\n     */\n    public function getConfig($name = '')\n    {\n        return $this->connection->getConfig($name);\n    }\n\n    /**\n     * 得到分表的的数据表名\n     * @access public\n     * @param array  $data  操作的数据\n     * @param string $field 分表依据的字段\n     * @param array  $rule  分表规则\n     * @return string\n     */\n    public function getPartitionTableName($data, $field, $rule = [])\n    {\n        // 对数据表进行分区\n        if ($field && isset($data[$field])) {\n            $value = $data[$field];\n            $type  = $rule['type'];\n            switch ($type) {\n                case 'id':\n                    // 按照id范围分表\n                    $step = $rule['expr'];\n                    $seq  = floor($value / $step) + 1;\n                    break;\n                case 'year':\n                    // 按照年份分表\n                    if (!is_numeric($value)) {\n                        $value = strtotime($value);\n                    }\n                    $seq = date('Y', $value) - $rule['expr'] + 1;\n                    break;\n                case 'mod':\n                    // 按照id的模数分表\n                    $seq = ($value % $rule['num']) + 1;\n                    break;\n                case 'md5':\n                    // 按照md5的序列分表\n                    $seq = (ord(substr(md5($value), 0, 1)) % $rule['num']) + 1;\n                    break;\n                default:\n                    if (function_exists($type)) {\n                        // 支持指定函数哈希\n                        $seq = (ord(substr($type($value), 0, 1)) % $rule['num']) + 1;\n                    } else {\n                        // 按照字段的首字母的值分表\n                        $seq = (ord($value{0}) % $rule['num']) + 1;\n                    }\n            }\n            return $this->getTable() . '_' . $seq;\n        } else {\n            // 当设置的分表字段不在查询条件或者数据中\n            // 进行联合查询，必须设定 partition['num']\n            $tableName = [];\n            for ($i = 0; $i < $rule['num']; $i++) {\n                $tableName[] = 'SELECT * FROM ' . $this->getTable() . '_' . ($i + 1);\n            }\n\n            $tableName = '( ' . implode(\" UNION \", $tableName) . ') AS ' . $this->name;\n            return $tableName;\n        }\n    }\n\n    /**\n     * 得到某个字段的值\n     * @access public\n     * @param string $field   字段名\n     * @param mixed  $default 默认值\n     * @param bool   $force   强制转为数字类型\n     * @return mixed\n     */\n    public function value($field, $default = null, $force = false)\n    {\n        $result = false;\n        if (empty($options['fetch_sql']) && !empty($this->options['cache'])) {\n            // 判断查询缓存\n            $cache = $this->options['cache'];\n            if (empty($this->options['table'])) {\n                $this->options['table'] = $this->getTable();\n            }\n            $key    = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options));\n            $result = Cache::get($key);\n        }\n        if (false === $result) {\n            if (isset($this->options['field'])) {\n                unset($this->options['field']);\n            }\n            $pdo = $this->field($field)->limit(1)->getPdo();\n            if (is_string($pdo)) {\n                // 返回SQL语句\n                return $pdo;\n            }\n            $result = $pdo->fetchColumn();\n            if ($force) {\n                $result = is_numeric($result) ? $result + 0 : $result;\n            }\n            if (isset($cache)) {\n                // 缓存数据\n                $this->cacheData($key, $result, $cache);\n            }\n        } else {\n            // 清空查询条件\n            $this->options = [];\n        }\n        return false !== $result ? $result : $default;\n    }\n\n    /**\n     * 得到某个列的数组\n     * @access public\n     * @param string $field 字段名 多个字段用逗号分隔\n     * @param string $key   索引\n     * @return array\n     */\n    public function column($field, $key = '')\n    {\n        $result = false;\n        if (empty($options['fetch_sql']) && !empty($this->options['cache'])) {\n            // 判断查询缓存\n            $cache = $this->options['cache'];\n            if (empty($this->options['table'])) {\n                $this->options['table'] = $this->getTable();\n            }\n            $guid   = is_string($cache['key']) ? $cache['key'] : md5($field . serialize($this->options));\n            $result = Cache::get($guid);\n        }\n        if (false === $result) {\n            if (isset($this->options['field'])) {\n                unset($this->options['field']);\n            }\n            if (is_null($field)) {\n                $field = '*';\n            } elseif ($key && '*' != $field) {\n                $field = $key . ',' . $field;\n            }\n            $pdo = $this->field($field)->getPdo();\n            if (is_string($pdo)) {\n                // 返回SQL语句\n                return $pdo;\n            }\n            if (1 == $pdo->columnCount()) {\n                $result = $pdo->fetchAll(PDO::FETCH_COLUMN);\n            } else {\n                $resultSet = $pdo->fetchAll(PDO::FETCH_ASSOC);\n                if ($resultSet) {\n                    $fields = array_keys($resultSet[0]);\n                    $count  = count($fields);\n                    $key1   = array_shift($fields);\n                    $key2   = $fields ? array_shift($fields) : '';\n                    $key    = $key ?: $key1;\n                    if (strpos($key, '.')) {\n                        list($alias, $key) = explode('.', $key);\n                    }\n                    foreach ($resultSet as $val) {\n                        if ($count > 2) {\n                            $result[$val[$key]] = $val;\n                        } elseif (2 == $count) {\n                            $result[$val[$key]] = $val[$key2];\n                        } elseif (1 == $count) {\n                            $result[$val[$key]] = $val[$key1];\n                        }\n                    }\n                } else {\n                    $result = [];\n                }\n            }\n            if (isset($cache) && isset($guid)) {\n                // 缓存数据\n                $this->cacheData($guid, $result, $cache);\n            }\n        } else {\n            // 清空查询条件\n            $this->options = [];\n        }\n        return $result;\n    }\n\n    /**\n     * COUNT查询\n     * @access public\n     * @param string $field 字段名\n     * @return integer|string\n     */\n    public function count($field = '*')\n    {\n        if (isset($this->options['group'])) {\n            // 支持GROUP\n            $options = $this->getOptions();\n            $subSql  = $this->options($options)->field('count(' . $field . ')')->bind($this->bind)->buildSql();\n            return $this->table([$subSql => '_group_count_'])->value('COUNT(*) AS tp_count', 0, true);\n        }\n\n        return $this->value('COUNT(' . $field . ') AS tp_count', 0, true);\n    }\n\n    /**\n     * SUM查询\n     * @access public\n     * @param string $field 字段名\n     * @return float|int\n     */\n    public function sum($field)\n    {\n        return $this->value('SUM(' . $field . ') AS tp_sum', 0, true);\n    }\n\n    /**\n     * MIN查询\n     * @access public\n     * @param string $field 字段名\n     * @return mixed\n     */\n    public function min($field)\n    {\n        return $this->value('MIN(' . $field . ') AS tp_min', 0, true);\n    }\n\n    /**\n     * MAX查询\n     * @access public\n     * @param string $field 字段名\n     * @return mixed\n     */\n    public function max($field)\n    {\n        return $this->value('MAX(' . $field . ') AS tp_max', 0, true);\n    }\n\n    /**\n     * AVG查询\n     * @access public\n     * @param string $field 字段名\n     * @return float|int\n     */\n    public function avg($field)\n    {\n        return $this->value('AVG(' . $field . ') AS tp_avg', 0, true);\n    }\n\n    /**\n     * 设置记录的某个字段值\n     * 支持使用数据库字段和方法\n     * @access public\n     * @param string|array $field 字段名\n     * @param mixed        $value 字段值\n     * @return integer\n     */\n    public function setField($field, $value = '')\n    {\n        if (is_array($field)) {\n            $data = $field;\n        } else {\n            $data[$field] = $value;\n        }\n        return $this->update($data);\n    }\n\n    /**\n     * 字段值(延迟)增长\n     * @access public\n     * @param string  $field    字段名\n     * @param integer $step     增长值\n     * @param integer $lazyTime 延时时间(s)\n     * @return integer|true\n     * @throws Exception\n     */\n    public function setInc($field, $step = 1, $lazyTime = 0)\n    {\n        $condition = !empty($this->options['where']) ? $this->options['where'] : [];\n        if (empty($condition)) {\n            // 没有条件不做任何更新\n            throw new Exception('no data to update');\n        }\n        if ($lazyTime > 0) {\n            // 延迟写入\n            $guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition));\n            $step = $this->lazyWrite('inc', $guid, $step, $lazyTime);\n            if (false === $step) {\n                // 清空查询条件\n                $this->options = [];\n                return true;\n            }\n        }\n        return $this->setField($field, ['exp', $field . '+' . $step]);\n    }\n\n    /**\n     * 字段值（延迟）减少\n     * @access public\n     * @param string  $field    字段名\n     * @param integer $step     减少值\n     * @param integer $lazyTime 延时时间(s)\n     * @return integer|true\n     * @throws Exception\n     */\n    public function setDec($field, $step = 1, $lazyTime = 0)\n    {\n        $condition = !empty($this->options['where']) ? $this->options['where'] : [];\n        if (empty($condition)) {\n            // 没有条件不做任何更新\n            throw new Exception('no data to update');\n        }\n        if ($lazyTime > 0) {\n            // 延迟写入\n            $guid = md5($this->getTable() . '_' . $field . '_' . serialize($condition));\n            $step = $this->lazyWrite('dec', $guid, $step, $lazyTime);\n            if (false === $step) {\n                // 清空查询条件\n                $this->options = [];\n                return true;\n            }\n        }\n        return $this->setField($field, ['exp', $field . '-' . $step]);\n    }\n\n    /**\n     * 延时更新检查 返回false表示需要延时\n     * 否则返回实际写入的数值\n     * @access protected\n     * @param string  $type     自增或者自减\n     * @param string  $guid     写入标识\n     * @param integer $step     写入步进值\n     * @param integer $lazyTime 延时时间(s)\n     * @return false|integer\n     */\n    protected function lazyWrite($type, $guid, $step, $lazyTime)\n    {\n        if (!Cache::has($guid . '_time')) {\n            // 计时开始\n            Cache::set($guid . '_time', $_SERVER['REQUEST_TIME'], 0);\n            Cache::$type($guid, $step);\n        } elseif ($_SERVER['REQUEST_TIME'] > Cache::get($guid . '_time') + $lazyTime) {\n            // 删除缓存\n            $value = Cache::$type($guid, $step);\n            Cache::rm($guid);\n            Cache::rm($guid . '_time');\n            return 0 === $value ? false : $value;\n        } else {\n            // 更新缓存\n            Cache::$type($guid, $step);\n        }\n        return false;\n    }\n\n    /**\n     * 查询SQL组装 join\n     * @access public\n     * @param mixed  $join      关联的表名\n     * @param mixed  $condition 条件\n     * @param string $type      JOIN类型\n     * @return $this\n     */\n    public function join($join, $condition = null, $type = 'INNER')\n    {\n        if (empty($condition)) {\n            // 如果为组数，则循环调用join\n            foreach ($join as $key => $value) {\n                if (is_array($value) && 2 <= count($value)) {\n                    $this->join($value[0], $value[1], isset($value[2]) ? $value[2] : $type);\n                }\n            }\n        } else {\n            $table = $this->getJoinTable($join);\n\n            $this->options['join'][] = [$table, strtoupper($type), $condition];\n        }\n        return $this;\n    }\n\n    /**\n     * 获取Join表名及别名 支持\n     * ['prefix_table或者子查询'=>'alias'] 'prefix_table alias' 'table alias'\n     * @access public\n     * @param array|string $join\n     * @return array|string\n     */\n    protected function getJoinTable($join, &$alias = null)\n    {\n        // 传入的表名为数组\n        if (is_array($join)) {\n            list($table, $alias) = each($join);\n        } else {\n            $join = trim($join);\n            if (false !== strpos($join, '(')) {\n                // 使用子查询\n                $table = $join;\n            } else {\n                $prefix = $this->prefix;\n                if (strpos($join, ' ')) {\n                    // 使用别名\n                    list($table, $alias) = explode(' ', $join);\n                } else {\n                    $table = $join;\n                    if (false === strpos($join, '.') && 0 !== strpos($join, '__')) {\n                        $alias = $join;\n                    }\n                }\n                if ($prefix && false === strpos($table, '.') && 0 !== strpos($table, $prefix) && 0 !== strpos($table, '__')) {\n                    $table = $this->getTable($table);\n                }\n            }\n        }\n        if (isset($alias)) {\n            if (isset($this->options['alias'][$table])) {\n                $table = $table . '@think' . uniqid();\n            }\n            $table = [$table => $alias];\n            $this->alias($table);\n        }\n        return $table;\n    }\n\n    /**\n     * 查询SQL组装 union\n     * @access public\n     * @param mixed   $union\n     * @param boolean $all\n     * @return $this\n     */\n    public function union($union, $all = false)\n    {\n        $this->options['union']['type'] = $all ? 'UNION ALL' : 'UNION';\n\n        if (is_array($union)) {\n            $this->options['union'] = array_merge($this->options['union'], $union);\n        } else {\n            $this->options['union'][] = $union;\n        }\n        return $this;\n    }\n\n    /**\n     * 指定查询字段 支持字段排除和指定数据表\n     * @access public\n     * @param mixed   $field\n     * @param boolean $except    是否排除\n     * @param string  $tableName 数据表名\n     * @param string  $prefix    字段前缀\n     * @param string  $alias     别名前缀\n     * @return $this\n     */\n    public function field($field, $except = false, $tableName = '', $prefix = '', $alias = '')\n    {\n        if (empty($field)) {\n            return $this;\n        }\n        if (is_string($field)) {\n            $field = array_map('trim', explode(',', $field));\n        }\n        if (true === $field) {\n            // 获取全部字段\n            $fields = $this->getTableInfo($tableName ?: (isset($this->options['table']) ? $this->options['table'] : ''), 'fields');\n            $field  = $fields ?: ['*'];\n        } elseif ($except) {\n            // 字段排除\n            $fields = $this->getTableInfo($tableName ?: (isset($this->options['table']) ? $this->options['table'] : ''), 'fields');\n            $field  = $fields ? array_diff($fields, $field) : $field;\n        }\n        if ($tableName) {\n            // 添加统一的前缀\n            $prefix = $prefix ?: $tableName;\n            foreach ($field as $key => $val) {\n                if (is_numeric($key)) {\n                    $val = $prefix . '.' . $val . ($alias ? ' AS ' . $alias . $val : '');\n                }\n                $field[$key] = $val;\n            }\n        }\n\n        if (isset($this->options['field'])) {\n            $field = array_merge($this->options['field'], $field);\n        }\n        $this->options['field'] = array_unique($field);\n        return $this;\n    }\n\n    /**\n     * 设置数据\n     * @access public\n     * @param mixed $field 字段名或者数据\n     * @param mixed $value 字段值\n     * @return $this\n     */\n    public function data($field, $value = null)\n    {\n        if (is_array($field)) {\n            $this->options['data'] = isset($this->options['data']) ? array_merge($this->options['data'], $field) : $field;\n        } else {\n            $this->options['data'][$field] = $value;\n        }\n        return $this;\n    }\n\n    /**\n     * 字段值增长\n     * @access public\n     * @param string|array $field 字段名\n     * @param integer      $step  增长值\n     * @return $this\n     */\n    public function inc($field, $step = 1)\n    {\n        $fields = is_string($field) ? explode(',', $field) : $field;\n        foreach ($fields as $field) {\n            $this->data($field, ['exp', $field . '+' . $step]);\n        }\n        return $this;\n    }\n\n    /**\n     * 字段值减少\n     * @access public\n     * @param string|array $field 字段名\n     * @param integer      $step  增长值\n     * @return $this\n     */\n    public function dec($field, $step = 1)\n    {\n        $fields = is_string($field) ? explode(',', $field) : $field;\n        foreach ($fields as $field) {\n            $this->data($field, ['exp', $field . '-' . $step]);\n        }\n        return $this;\n    }\n\n    /**\n     * 使用表达式设置数据\n     * @access public\n     * @param string $field 字段名\n     * @param string $value 字段值\n     * @return $this\n     */\n    public function exp($field, $value)\n    {\n        $this->data($field, ['exp', $value]);\n        return $this;\n    }\n\n    /**\n     * 指定JOIN查询字段\n     * @access public\n     * @param string|array $table 数据表\n     * @param string|array $field 查询字段\n     * @param string|array $on    JOIN条件\n     * @param string       $type  JOIN类型\n     * @return $this\n     */\n    public function view($join, $field = true, $on = null, $type = 'INNER')\n    {\n        $this->options['view'] = true;\n        if (is_array($join) && key($join) !== 0) {\n            foreach ($join as $key => $val) {\n                $this->view($key, $val[0], isset($val[1]) ? $val[1] : null, isset($val[2]) ? $val[2] : 'INNER');\n            }\n        } else {\n            $fields = [];\n            $table  = $this->getJoinTable($join, $alias);\n\n            if (true === $field) {\n                $fields = $alias . '.*';\n            } else {\n                if (is_string($field)) {\n                    $field = explode(',', $field);\n                }\n                foreach ($field as $key => $val) {\n                    if (is_numeric($key)) {\n                        $fields[]                   = $alias . '.' . $val;\n                        $this->options['map'][$val] = $alias . '.' . $val;\n                    } else {\n                        if (preg_match('/[,=\\.\\'\\\"\\(\\s]/', $key)) {\n                            $name = $key;\n                        } else {\n                            $name = $alias . '.' . $key;\n                        }\n                        $fields[$name]              = $val;\n                        $this->options['map'][$val] = $name;\n                    }\n                }\n            }\n            $this->field($fields);\n            if ($on) {\n                $this->join($table, $on, $type);\n            } else {\n                $this->table($table);\n            }\n        }\n        return $this;\n    }\n\n    /**\n     * 设置分表规则\n     * @access public\n     * @param array  $data  操作的数据\n     * @param string $field 分表依据的字段\n     * @param array  $rule  分表规则\n     * @return $this\n     */\n    public function partition($data, $field, $rule = [])\n    {\n        $this->options['table'] = $this->getPartitionTableName($data, $field, $rule);\n        return $this;\n    }\n\n    /**\n     * 指定AND查询条件\n     * @access public\n     * @param mixed $field     查询字段\n     * @param mixed $op        查询表达式\n     * @param mixed $condition 查询条件\n     * @return $this\n     */\n    public function where($field, $op = null, $condition = null)\n    {\n        $param = func_get_args();\n        array_shift($param);\n        $this->parseWhereExp('AND', $field, $op, $condition, $param);\n        return $this;\n    }\n\n    /**\n     * 指定OR查询条件\n     * @access public\n     * @param mixed $field     查询字段\n     * @param mixed $op        查询表达式\n     * @param mixed $condition 查询条件\n     * @return $this\n     */\n    public function whereOr($field, $op = null, $condition = null)\n    {\n        $param = func_get_args();\n        array_shift($param);\n        $this->parseWhereExp('OR', $field, $op, $condition, $param);\n        return $this;\n    }\n\n    /**\n     * 指定XOR查询条件\n     * @access public\n     * @param mixed $field     查询字段\n     * @param mixed $op        查询表达式\n     * @param mixed $condition 查询条件\n     * @return $this\n     */\n    public function whereXor($field, $op = null, $condition = null)\n    {\n        $param = func_get_args();\n        array_shift($param);\n        $this->parseWhereExp('XOR', $field, $op, $condition, $param);\n        return $this;\n    }\n\n    /**\n     * 指定Null查询条件\n     * @access public\n     * @param mixed  $field 查询字段\n     * @param string $logic 查询逻辑 and or xor\n     * @return $this\n     */\n    public function whereNull($field, $logic = 'AND')\n    {\n        $this->parseWhereExp($logic, $field, 'null', null);\n        return $this;\n    }\n\n    /**\n     * 指定NotNull查询条件\n     * @access public\n     * @param mixed  $field 查询字段\n     * @param string $logic 查询逻辑 and or xor\n     * @return $this\n     */\n    public function whereNotNull($field, $logic = 'AND')\n    {\n        $this->parseWhereExp($logic, $field, 'notnull', null);\n        return $this;\n    }\n\n    /**\n     * 指定Exists查询条件\n     * @access public\n     * @param mixed  $condition 查询条件\n     * @param string $logic     查询逻辑 and or xor\n     * @return $this\n     */\n    public function whereExists($condition, $logic = 'AND')\n    {\n        $this->options['where'][strtoupper($logic)][] = ['exists', $condition];\n        return $this;\n    }\n\n    /**\n     * 指定NotExists查询条件\n     * @access public\n     * @param mixed  $condition 查询条件\n     * @param string $logic     查询逻辑 and or xor\n     * @return $this\n     */\n    public function whereNotExists($condition, $logic = 'AND')\n    {\n        $this->options['where'][strtoupper($logic)][] = ['not exists', $condition];\n        return $this;\n    }\n\n    /**\n     * 指定In查询条件\n     * @access public\n     * @param mixed  $field     查询字段\n     * @param mixed  $condition 查询条件\n     * @param string $logic     查询逻辑 and or xor\n     * @return $this\n     */\n    public function whereIn($field, $condition, $logic = 'AND')\n    {\n        $this->parseWhereExp($logic, $field, 'in', $condition);\n        return $this;\n    }\n\n    /**\n     * 指定NotIn查询条件\n     * @access public\n     * @param mixed  $field     查询字段\n     * @param mixed  $condition 查询条件\n     * @param string $logic     查询逻辑 and or xor\n     * @return $this\n     */\n    public function whereNotIn($field, $condition, $logic = 'AND')\n    {\n        $this->parseWhereExp($logic, $field, 'not in', $condition);\n        return $this;\n    }\n\n    /**\n     * 指定Like查询条件\n     * @access public\n     * @param mixed  $field     查询字段\n     * @param mixed  $condition 查询条件\n     * @param string $logic     查询逻辑 and or xor\n     * @return $this\n     */\n    public function whereLike($field, $condition, $logic = 'AND')\n    {\n        $this->parseWhereExp($logic, $field, 'like', $condition);\n        return $this;\n    }\n\n    /**\n     * 指定NotLike查询条件\n     * @access public\n     * @param mixed  $field     查询字段\n     * @param mixed  $condition 查询条件\n     * @param string $logic     查询逻辑 and or xor\n     * @return $this\n     */\n    public function whereNotLike($field, $condition, $logic = 'AND')\n    {\n        $this->parseWhereExp($logic, $field, 'not like', $condition);\n        return $this;\n    }\n\n    /**\n     * 指定Between查询条件\n     * @access public\n     * @param mixed  $field     查询字段\n     * @param mixed  $condition 查询条件\n     * @param string $logic     查询逻辑 and or xor\n     * @return $this\n     */\n    public function whereBetween($field, $condition, $logic = 'AND')\n    {\n        $this->parseWhereExp($logic, $field, 'between', $condition);\n        return $this;\n    }\n\n    /**\n     * 指定NotBetween查询条件\n     * @access public\n     * @param mixed  $field     查询字段\n     * @param mixed  $condition 查询条件\n     * @param string $logic     查询逻辑 and or xor\n     * @return $this\n     */\n    public function whereNotBetween($field, $condition, $logic = 'AND')\n    {\n        $this->parseWhereExp($logic, $field, 'not between', $condition);\n        return $this;\n    }\n\n    /**\n     * 指定Exp查询条件\n     * @access public\n     * @param mixed  $field     查询字段\n     * @param mixed  $condition 查询条件\n     * @param string $logic     查询逻辑 and or xor\n     * @return $this\n     */\n    public function whereExp($field, $condition, $logic = 'AND')\n    {\n        $this->parseWhereExp($logic, $field, 'exp', $condition);\n        return $this;\n    }\n\n    /**\n     * 设置软删除字段及条件\n     * @access public\n     * @param false|string  $field     查询字段\n     * @param mixed         $condition 查询条件\n     * @return $this\n     */\n    public function useSoftDelete($field, $condition = null)\n    {\n        if ($field) {\n            $this->options['soft_delete'] = [$field, $condition ?: ['null', '']];\n        }\n    }\n\n    /**\n     * 分析查询表达式\n     * @access public\n     * @param string                $logic     查询逻辑 and or xor\n     * @param string|array|\\Closure $field     查询字段\n     * @param mixed                 $op        查询表达式\n     * @param mixed                 $condition 查询条件\n     * @param array                 $param     查询参数\n     * @return void\n     */\n    protected function parseWhereExp($logic, $field, $op, $condition, $param = [])\n    {\n        $logic = strtoupper($logic);\n        if ($field instanceof \\Closure) {\n            $this->options['where'][$logic][] = is_string($op) ? [$op, $field] : $field;\n            return;\n        }\n\n        if (is_string($field) && !empty($this->options['via']) && !strpos($field, '.')) {\n            $field = $this->options['via'] . '.' . $field;\n        }\n        if (is_string($field) && preg_match('/[,=\\>\\<\\'\\\"\\(\\s]/', $field)) {\n            $where[] = ['exp', $field];\n            if (is_array($op)) {\n                // 参数绑定\n                $this->bind($op);\n            }\n        } elseif (is_null($op) && is_null($condition)) {\n            if (is_array($field)) {\n                // 数组批量查询\n                $where = $field;\n                foreach ($where as $k => $val) {\n                    $this->options['multi'][$logic][$k][] = $val;\n                }\n            } elseif ($field && is_string($field)) {\n                // 字符串查询\n                $where[$field]                            = ['null', ''];\n                $this->options['multi'][$logic][$field][] = $where[$field];\n            }\n        } elseif (is_array($op)) {\n            $where[$field] = $param;\n        } elseif (in_array(strtolower($op), ['null', 'notnull', 'not null'])) {\n            // null查询\n            $where[$field]                            = [$op, ''];\n            $this->options['multi'][$logic][$field][] = $where[$field];\n        } elseif (is_null($condition)) {\n            // 字段相等查询\n            $where[$field] = ['eq', $op];\n            if ('AND' != $logic) {\n                $this->options['multi'][$logic][$field][] = $where[$field];\n            }\n        } else {\n            $where[$field] = [$op, $condition, isset($param[2]) ? $param[2] : null];\n            if ('exp' == strtolower($op) && isset($param[2]) && is_array($param[2])) {\n                // 参数绑定\n                $this->bind($param[2]);\n            }\n            // 记录一个字段多次查询条件\n            $this->options['multi'][$logic][$field][] = $where[$field];\n        }\n        if (!empty($where)) {\n            if (!isset($this->options['where'][$logic])) {\n                $this->options['where'][$logic] = [];\n            }\n            if (is_string($field) && $this->checkMultiField($field, $logic)) {\n                $where[$field] = $this->options['multi'][$logic][$field];\n            } elseif (is_array($field)) {\n                foreach ($field as $key => $val) {\n                    if ($this->checkMultiField($key, $logic)) {\n                        $where[$key] = $this->options['multi'][$logic][$key];\n                    }\n                }\n            }\n            $this->options['where'][$logic] = array_merge($this->options['where'][$logic], $where);\n        }\n    }\n\n    /**\n     * 检查是否存在一个字段多次查询条件\n     * @access public\n     * @param string $field 查询字段\n     * @param string $logic 查询逻辑 and or xor\n     * @return bool\n     */\n    private function checkMultiField($field, $logic)\n    {\n        return isset($this->options['multi'][$logic][$field]) && count($this->options['multi'][$logic][$field]) > 1;\n    }\n\n    /**\n     * 去除某个查询条件\n     * @access public\n     * @param string $field 查询字段\n     * @param string $logic 查询逻辑 and or xor\n     * @return $this\n     */\n    public function removeWhereField($field, $logic = 'AND')\n    {\n        $logic = strtoupper($logic);\n        if (isset($this->options['where'][$logic][$field])) {\n            unset($this->options['where'][$logic][$field]);\n        }\n        return $this;\n    }\n\n    /**\n     * 去除查询参数\n     * @access public\n     * @param string|bool $option 参数名 true 表示去除所有参数\n     * @return $this\n     */\n    public function removeOption($option = true)\n    {\n        if (true === $option) {\n            $this->options = [];\n        } elseif (is_string($option) && isset($this->options[$option])) {\n            unset($this->options[$option]);\n        }\n        return $this;\n    }\n\n    /**\n     * 指定查询数量\n     * @access public\n     * @param mixed $offset 起始位置\n     * @param mixed $length 查询数量\n     * @return $this\n     */\n    public function limit($offset, $length = null)\n    {\n        if (is_null($length) && strpos($offset, ',')) {\n            list($offset, $length) = explode(',', $offset);\n        }\n        $this->options['limit'] = intval($offset) . ($length ? ',' . intval($length) : '');\n        return $this;\n    }\n\n    /**\n     * 指定分页\n     * @access public\n     * @param mixed $page     页数\n     * @param mixed $listRows 每页数量\n     * @return $this\n     */\n    public function page($page, $listRows = null)\n    {\n        if (is_null($listRows) && strpos($page, ',')) {\n            list($page, $listRows) = explode(',', $page);\n        }\n        $this->options['page'] = [intval($page), intval($listRows)];\n        return $this;\n    }\n\n    /**\n     * 分页查询\n     * @param int|array $listRows 每页数量 数组表示配置参数\n     * @param int|bool  $simple   是否简洁模式或者总记录数\n     * @param array     $config   配置参数\n     *                            page:当前页,\n     *                            path:url路径,\n     *                            query:url额外参数,\n     *                            fragment:url锚点,\n     *                            var_page:分页变量,\n     *                            list_rows:每页数量\n     *                            type:分页类名\n     * @return \\think\\Paginator\n     * @throws DbException\n     */\n    public function paginate($listRows = null, $simple = false, $config = [])\n    {\n        if (is_int($simple)) {\n            $total  = $simple;\n            $simple = false;\n        }\n        if (is_array($listRows)) {\n            $config   = array_merge(Config::get('paginate'), $listRows);\n            $listRows = $config['list_rows'];\n        } else {\n            $config   = array_merge(Config::get('paginate'), $config);\n            $listRows = $listRows ?: $config['list_rows'];\n        }\n\n        /** @var Paginator $class */\n        $class = false !== strpos($config['type'], '\\\\') ? $config['type'] : '\\\\think\\\\paginator\\\\driver\\\\' . ucwords($config['type']);\n        $page  = isset($config['page']) ? (int) $config['page'] : call_user_func([\n            $class,\n            'getCurrentPage',\n        ], $config['var_page']);\n\n        $page = $page < 1 ? 1 : $page;\n\n        $config['path'] = isset($config['path']) ? $config['path'] : call_user_func([$class, 'getCurrentPath']);\n\n        if (!isset($total) && !$simple) {\n            $options = $this->getOptions();\n\n            unset($this->options['order'], $this->options['limit'], $this->options['page'], $this->options['field']);\n\n            $bind    = $this->bind;\n            $total   = $this->count();\n            $results = $this->options($options)->bind($bind)->page($page, $listRows)->select();\n        } elseif ($simple) {\n            $results = $this->limit(($page - 1) * $listRows, $listRows + 1)->select();\n            $total   = null;\n        } else {\n            $results = $this->page($page, $listRows)->select();\n        }\n        return $class::make($results, $listRows, $page, $total, $simple, $config);\n    }\n\n    /**\n     * 指定当前操作的数据表\n     * @access public\n     * @param mixed $table 表名\n     * @return $this\n     */\n    public function table($table)\n    {\n        if (is_string($table)) {\n            if (strpos($table, ')')) {\n                // 子查询\n            } elseif (strpos($table, ',')) {\n                $tables = explode(',', $table);\n                $table  = [];\n                foreach ($tables as $item) {\n                    list($item, $alias) = explode(' ', trim($item));\n                    if ($alias) {\n                        $this->alias([$item => $alias]);\n                        $table[$item] = $alias;\n                    } else {\n                        $table[] = $item;\n                    }\n                }\n            } elseif (strpos($table, ' ')) {\n                list($table, $alias) = explode(' ', $table);\n\n                $table = [$table => $alias];\n                $this->alias($table);\n            }\n        } else {\n            $tables = $table;\n            $table  = [];\n            foreach ($tables as $key => $val) {\n                if (is_numeric($key)) {\n                    $table[] = $val;\n                } else {\n                    $this->alias([$key => $val]);\n                    $table[$key] = $val;\n                }\n            }\n        }\n        $this->options['table'] = $table;\n        return $this;\n    }\n\n    /**\n     * USING支持 用于多表删除\n     * @access public\n     * @param mixed $using\n     * @return $this\n     */\n    public function using($using)\n    {\n        $this->options['using'] = $using;\n        return $this;\n    }\n\n    /**\n     * 指定排序 order('id','desc') 或者 order(['id'=>'desc','create_time'=>'desc'])\n     * @access public\n     * @param string|array $field 排序字段\n     * @param string       $order 排序\n     * @return $this\n     */\n    public function order($field, $order = null)\n    {\n        if (!empty($field)) {\n            if (is_string($field)) {\n                if (!empty($this->options['via'])) {\n                    $field = $this->options['via'] . '.' . $field;\n                }\n                $field = empty($order) ? $field : [$field => $order];\n            } elseif (!empty($this->options['via'])) {\n                foreach ($field as $key => $val) {\n                    if (is_numeric($key)) {\n                        $field[$key] = $this->options['via'] . '.' . $val;\n                    } else {\n                        $field[$this->options['via'] . '.' . $key] = $val;\n                        unset($field[$key]);\n                    }\n                }\n            }\n            if (!isset($this->options['order'])) {\n                $this->options['order'] = [];\n            }\n            if (is_array($field)) {\n                $this->options['order'] = array_merge($this->options['order'], $field);\n            } else {\n                $this->options['order'][] = $field;\n            }\n        }\n        return $this;\n    }\n\n    /**\n     * 查询缓存\n     * @access public\n     * @param mixed   $key    缓存key\n     * @param integer $expire 缓存有效期\n     * @param string  $tag    缓存标签\n     * @return $this\n     */\n    public function cache($key = true, $expire = null, $tag = null)\n    {\n        // 增加快捷调用方式 cache(10) 等同于 cache(true, 10)\n        if (is_numeric($key) && is_null($expire)) {\n            $expire = $key;\n            $key    = true;\n        }\n        if (false !== $key) {\n            $this->options['cache'] = ['key' => $key, 'expire' => $expire, 'tag' => $tag];\n        }\n        return $this;\n    }\n\n    /**\n     * 指定group查询\n     * @access public\n     * @param string $group GROUP\n     * @return $this\n     */\n    public function group($group)\n    {\n        $this->options['group'] = $group;\n        return $this;\n    }\n\n    /**\n     * 指定having查询\n     * @access public\n     * @param string $having having\n     * @return $this\n     */\n    public function having($having)\n    {\n        $this->options['having'] = $having;\n        return $this;\n    }\n\n    /**\n     * 指定查询lock\n     * @access public\n     * @param boolean $lock 是否lock\n     * @return $this\n     */\n    public function lock($lock = false)\n    {\n        $this->options['lock']   = $lock;\n        $this->options['master'] = true;\n        return $this;\n    }\n\n    /**\n     * 指定distinct查询\n     * @access public\n     * @param string $distinct 是否唯一\n     * @return $this\n     */\n    public function distinct($distinct)\n    {\n        $this->options['distinct'] = $distinct;\n        return $this;\n    }\n\n    /**\n     * 指定数据表别名\n     * @access public\n     * @param mixed $alias 数据表别名\n     * @return $this\n     */\n    public function alias($alias)\n    {\n        if (is_array($alias)) {\n            foreach ($alias as $key => $val) {\n                $this->options['alias'][$key] = $val;\n            }\n        } else {\n            if (isset($this->options['table'])) {\n                $table = is_array($this->options['table']) ? key($this->options['table']) : $this->options['table'];\n                if (false !== strpos($table, '__')) {\n                    $table = $this->parseSqlTable($table);\n                }\n            } else {\n                $table = $this->getTable();\n            }\n\n            $this->options['alias'][$table] = $alias;\n        }\n        return $this;\n    }\n\n    /**\n     * 指定强制索引\n     * @access public\n     * @param string $force 索引名称\n     * @return $this\n     */\n    public function force($force)\n    {\n        $this->options['force'] = $force;\n        return $this;\n    }\n\n    /**\n     * 查询注释\n     * @access public\n     * @param string $comment 注释\n     * @return $this\n     */\n    public function comment($comment)\n    {\n        $this->options['comment'] = $comment;\n        return $this;\n    }\n\n    /**\n     * 获取执行的SQL语句\n     * @access public\n     * @param boolean $fetch 是否返回sql\n     * @return $this\n     */\n    public function fetchSql($fetch = true)\n    {\n        $this->options['fetch_sql'] = $fetch;\n        return $this;\n    }\n\n    /**\n     * 不主动获取数据集\n     * @access public\n     * @param bool $pdo 是否返回 PDOStatement 对象\n     * @return $this\n     */\n    public function fetchPdo($pdo = true)\n    {\n        $this->options['fetch_pdo'] = $pdo;\n        return $this;\n    }\n\n    /**\n     * 设置从主服务器读取数据\n     * @access public\n     * @return $this\n     */\n    public function master()\n    {\n        $this->options['master'] = true;\n        return $this;\n    }\n\n    /**\n     * 设置是否严格检查字段名\n     * @access public\n     * @param bool $strict 是否严格检查字段\n     * @return $this\n     */\n    public function strict($strict = true)\n    {\n        $this->options['strict'] = $strict;\n        return $this;\n    }\n\n    /**\n     * 设置查询数据不存在是否抛出异常\n     * @access public\n     * @param bool $fail 数据不存在是否抛出异常\n     * @return $this\n     */\n    public function failException($fail = true)\n    {\n        $this->options['fail'] = $fail;\n        return $this;\n    }\n\n    /**\n     * 设置自增序列名\n     * @access public\n     * @param string $sequence 自增序列名\n     * @return $this\n     */\n    public function sequence($sequence = null)\n    {\n        $this->options['sequence'] = $sequence;\n        return $this;\n    }\n\n    /**\n     * 指定数据表主键\n     * @access public\n     * @param string $pk 主键\n     * @return $this\n     */\n    public function pk($pk)\n    {\n        $this->pk = $pk;\n        return $this;\n    }\n\n    /**\n     * 查询日期或者时间\n     * @access public\n     * @param string       $field 日期字段名\n     * @param string       $op    比较运算符或者表达式\n     * @param string|array $range 比较范围\n     * @return $this\n     */\n    public function whereTime($field, $op, $range = null)\n    {\n        if (is_null($range)) {\n            // 使用日期表达式\n            $date = getdate();\n            switch (strtolower($op)) {\n                case 'today':\n                case 'd':\n                    $range = ['today', 'tomorrow'];\n                    break;\n                case 'week':\n                case 'w':\n                    $range = 'this week 00:00:00';\n                    break;\n                case 'month':\n                case 'm':\n                    $range = mktime(0, 0, 0, $date['mon'], 1, $date['year']);\n                    break;\n                case 'year':\n                case 'y':\n                    $range = mktime(0, 0, 0, 1, 1, $date['year']);\n                    break;\n                case 'yesterday':\n                    $range = ['yesterday', 'today'];\n                    break;\n                case 'last week':\n                    $range = ['last week 00:00:00', 'this week 00:00:00'];\n                    break;\n                case 'last month':\n                    $range = [date('y-m-01', strtotime('-1 month')), mktime(0, 0, 0, $date['mon'], 1, $date['year'])];\n                    break;\n                case 'last year':\n                    $range = [mktime(0, 0, 0, 1, 1, $date['year'] - 1), mktime(0, 0, 0, 1, 1, $date['year'])];\n                    break;\n                default:\n                    $range = $op;\n            }\n            $op = is_array($range) ? 'between' : '>';\n        }\n        $this->where($field, strtolower($op) . ' time', $range);\n        return $this;\n    }\n\n    /**\n     * 获取数据表信息\n     * @access public\n     * @param mixed  $tableName 数据表名 留空自动获取\n     * @param string $fetch     获取信息类型 包括 fields type bind pk\n     * @return mixed\n     */\n    public function getTableInfo($tableName = '', $fetch = '')\n    {\n        if (!$tableName) {\n            $tableName = $this->getTable();\n        }\n        if (is_array($tableName)) {\n            $tableName = key($tableName) ?: current($tableName);\n        }\n\n        if (strpos($tableName, ',')) {\n            // 多表不获取字段信息\n            return false;\n        } else {\n            $tableName = $this->parseSqlTable($tableName);\n        }\n\n        // 修正子查询作为表名的问题\n        if (strpos($tableName, ')')) {\n            return [];\n        }\n\n        list($guid) = explode(' ', $tableName);\n        $db         = $this->getConfig('database');\n        if (!isset(self::$info[$db . '.' . $guid])) {\n            if (!strpos($guid, '.')) {\n                $schema = $db . '.' . $guid;\n            } else {\n                $schema = $guid;\n            }\n            // 读取缓存\n            if (is_file(RUNTIME_PATH . 'schema/' . $schema . '.php')) {\n                $info = include RUNTIME_PATH . 'schema/' . $schema . '.php';\n            } else {\n                $info = $this->connection->getFields($guid);\n            }\n            $fields = array_keys($info);\n            $bind   = $type   = [];\n            foreach ($info as $key => $val) {\n                // 记录字段类型\n                $type[$key] = $val['type'];\n                $bind[$key] = $this->getFieldBindType($val['type']);\n                if (!empty($val['primary'])) {\n                    $pk[] = $key;\n                }\n            }\n            if (isset($pk)) {\n                // 设置主键\n                $pk = count($pk) > 1 ? $pk : $pk[0];\n            } else {\n                $pk = null;\n            }\n            self::$info[$db . '.' . $guid] = ['fields' => $fields, 'type' => $type, 'bind' => $bind, 'pk' => $pk];\n        }\n        return $fetch ? self::$info[$db . '.' . $guid][$fetch] : self::$info[$db . '.' . $guid];\n    }\n\n    /**\n     * 获取当前数据表的主键\n     * @access public\n     * @param string|array $options 数据表名或者查询参数\n     * @return string|array\n     */\n    public function getPk($options = '')\n    {\n        if (!empty($this->pk)) {\n            $pk = $this->pk;\n        } else {\n            $pk = $this->getTableInfo(is_array($options) ? $options['table'] : $options, 'pk');\n        }\n        return $pk;\n    }\n\n    // 获取当前数据表字段信息\n    public function getTableFields($options)\n    {\n        return $this->getTableInfo($options['table'], 'fields');\n    }\n\n    // 获取当前数据表字段类型\n    public function getFieldsType($options)\n    {\n        return $this->getTableInfo($options['table'], 'type');\n    }\n\n    // 获取当前数据表绑定信息\n    public function getFieldsBind($options)\n    {\n        $types = $this->getFieldsType($options);\n        $bind  = [];\n        if ($types) {\n            foreach ($types as $key => $type) {\n                $bind[$key] = $this->getFieldBindType($type);\n            }\n        }\n        return $bind;\n    }\n\n    /**\n     * 获取字段绑定类型\n     * @access public\n     * @param string $type 字段类型\n     * @return integer\n     */\n    protected function getFieldBindType($type)\n    {\n        if (preg_match('/(int|double|float|decimal|real|numeric|serial|bit)/is', $type)) {\n            $bind = PDO::PARAM_INT;\n        } elseif (preg_match('/bool/is', $type)) {\n            $bind = PDO::PARAM_BOOL;\n        } else {\n            $bind = PDO::PARAM_STR;\n        }\n        return $bind;\n    }\n\n    /**\n     * 参数绑定\n     * @access public\n     * @param mixed   $key   参数名\n     * @param mixed   $value 绑定变量值\n     * @param integer $type  绑定类型\n     * @return $this\n     */\n    public function bind($key, $value = false, $type = PDO::PARAM_STR)\n    {\n        if (is_array($key)) {\n            $this->bind = array_merge($this->bind, $key);\n        } else {\n            $this->bind[$key] = [$value, $type];\n        }\n        return $this;\n    }\n\n    /**\n     * 检测参数是否已经绑定\n     * @access public\n     * @param string $key 参数名\n     * @return bool\n     */\n    public function isBind($key)\n    {\n        return isset($this->bind[$key]);\n    }\n\n    /**\n     * 查询参数赋值\n     * @access protected\n     * @param array $options 表达式参数\n     * @return $this\n     */\n    protected function options(array $options)\n    {\n        $this->options = $options;\n        return $this;\n    }\n\n    /**\n     * 获取当前的查询参数\n     * @access public\n     * @param string $name 参数名\n     * @return mixed\n     */\n    public function getOptions($name = '')\n    {\n        if ('' === $name) {\n            return $this->options;\n        } else {\n            return isset($this->options[$name]) ? $this->options[$name] : null;\n        }\n    }\n\n    /**\n     * 设置关联查询JOIN预查询\n     * @access public\n     * @param string|array $with 关联方法名称\n     * @return $this\n     */\n    public function with($with)\n    {\n        if (empty($with)) {\n            return $this;\n        }\n\n        if (is_string($with)) {\n            $with = explode(',', $with);\n        }\n\n        $first        = true;\n        $currentModel = $this->model;\n\n        /** @var Model $class */\n        $class = new $currentModel;\n        foreach ($with as $key => $relation) {\n            $subRelation = '';\n            $closure     = false;\n            if ($relation instanceof \\Closure) {\n                // 支持闭包查询过滤关联条件\n                $closure    = $relation;\n                $relation   = $key;\n                $with[$key] = $key;\n            } elseif (is_string($relation) && strpos($relation, '.')) {\n                $with[$key]                   = $relation;\n                list($relation, $subRelation) = explode('.', $relation, 2);\n            }\n\n            /** @var Relation $model */\n            $relation = Loader::parseName($relation, 1, false);\n            $model    = $class->$relation();\n            if ($model instanceof OneToOne && 0 == $model->getEagerlyType()) {\n                $model->eagerly($this, $relation, $subRelation, $closure, $first);\n                $first = false;\n            } elseif ($closure) {\n                $with[$key] = $closure;\n            }\n        }\n        $this->via();\n        if (isset($this->options['with'])) {\n            $this->options['with'] = array_merge($this->options['with'], $with);\n        } else {\n            $this->options['with'] = $with;\n        }\n        return $this;\n    }\n\n    /**\n     * 关联统计\n     * @access public\n     * @param string|array $relation 关联方法名\n     * @param bool         $subQuery 是否使用子查询\n     * @return $this\n     */\n    public function withCount($relation, $subQuery = true)\n    {\n        if (!$subQuery) {\n            $this->options['with_count'] = $relation;\n        } else {\n            $relations = is_string($relation) ? explode(',', $relation) : $relation;\n            if (!isset($this->options['field'])) {\n                $this->field('*');\n            }\n            foreach ($relations as $key => $relation) {\n                $closure = false;\n                if ($relation instanceof \\Closure) {\n                    $closure  = $relation;\n                    $relation = $key;\n                }\n                $relation = Loader::parseName($relation, 1, false);\n                $count    = '(' . (new $this->model)->$relation()->getRelationCountQuery($closure) . ')';\n                $this->field([$count => Loader::parseName($relation) . '_count']);\n            }\n        }\n        return $this;\n    }\n\n    /**\n     * 关联预加载中 获取关联指定字段值\n     * example:\n     * Model::with(['relation' => function($query){\n     *     $query->withField(\"id,name\");\n     * }])\n     *\n     * @param string | array $field 指定获取的字段\n     * @return $this\n     */\n    public function withField($field)\n    {\n        $this->options['with_field'] = $field;\n        return $this;\n    }\n\n    /**\n     * 设置当前字段添加的表别名\n     * @access public\n     * @param string $via\n     * @return $this\n     */\n    public function via($via = '')\n    {\n        $this->options['via'] = $via;\n        return $this;\n    }\n\n    /**\n     * 设置关联查询\n     * @access public\n     * @param string|array $relation 关联名称\n     * @return $this\n     */\n    public function relation($relation)\n    {\n        if (empty($relation)) {\n            return $this;\n        }\n        if (is_string($relation)) {\n            $relation = explode(',', $relation);\n        }\n        if (isset($this->options['relation'])) {\n            $this->options['relation'] = array_merge($this->options['relation'], $relation);\n        } else {\n            $this->options['relation'] = $relation;\n        }\n        return $this;\n    }\n\n    /**\n     * 把主键值转换为查询条件 支持复合主键\n     * @access public\n     * @param array|string $data    主键数据\n     * @param mixed        $options 表达式参数\n     * @return void\n     * @throws Exception\n     */\n    protected function parsePkWhere($data, &$options)\n    {\n        $pk = $this->getPk($options);\n        // 获取当前数据表\n        $table = is_array($options['table']) ? key($options['table']) : $options['table'];\n        if (!empty($options['alias'][$table])) {\n            $alias = $options['alias'][$table];\n        }\n        if (is_string($pk)) {\n            $key = isset($alias) ? $alias . '.' . $pk : $pk;\n            // 根据主键查询\n            if (is_array($data)) {\n                $where[$key] = isset($data[$pk]) ? $data[$pk] : ['in', $data];\n            } else {\n                $where[$key] = strpos($data, ',') ? ['IN', $data] : $data;\n            }\n        } elseif (is_array($pk) && is_array($data) && !empty($data)) {\n            // 根据复合主键查询\n            foreach ($pk as $key) {\n                if (isset($data[$key])) {\n                    $attr         = isset($alias) ? $alias . '.' . $key : $key;\n                    $where[$attr] = $data[$key];\n                } else {\n                    throw new Exception('miss complex primary data');\n                }\n            }\n        }\n\n        if (!empty($where)) {\n            if (isset($options['where']['AND'])) {\n                $options['where']['AND'] = array_merge($options['where']['AND'], $where);\n            } else {\n                $options['where']['AND'] = $where;\n            }\n        }\n        return;\n    }\n\n    /**\n     * 插入记录\n     * @access public\n     * @param mixed   $data         数据\n     * @param boolean $replace      是否replace\n     * @param boolean $getLastInsID 返回自增主键\n     * @param string  $sequence     自增序列名\n     * @return integer|string\n     */\n    public function insert(array $data = [], $replace = false, $getLastInsID = false, $sequence = null)\n    {\n        // 分析查询表达式\n        $options = $this->parseExpress();\n        $data    = array_merge($options['data'], $data);\n        // 生成SQL语句\n        $sql = $this->builder->insert($data, $options, $replace);\n        // 获取参数绑定\n        $bind = $this->getBind();\n        if ($options['fetch_sql']) {\n            // 获取实际执行的SQL语句\n            return $this->connection->getRealSql($sql, $bind);\n        }\n\n        // 执行操作\n        $result = $this->execute($sql, $bind);\n        if ($result) {\n            $sequence  = $sequence ?: (isset($options['sequence']) ? $options['sequence'] : null);\n            $lastInsId = $this->getLastInsID($sequence);\n            if ($lastInsId) {\n                $pk = $this->getPk($options);\n                if (is_string($pk)) {\n                    $data[$pk] = $lastInsId;\n                }\n            }\n            $options['data'] = $data;\n            $this->trigger('after_insert', $options);\n\n            if ($getLastInsID) {\n                return $lastInsId;\n            }\n        }\n        return $result;\n    }\n\n    /**\n     * 插入记录并获取自增ID\n     * @access public\n     * @param mixed   $data     数据\n     * @param boolean $replace  是否replace\n     * @param string  $sequence 自增序列名\n     * @return integer|string\n     */\n    public function insertGetId(array $data, $replace = false, $sequence = null)\n    {\n        return $this->insert($data, $replace, true, $sequence);\n    }\n\n    /**\n     * 批量插入记录\n     * @access public\n     * @param mixed $dataSet 数据集\n     * @return integer|string\n     */\n    public function insertAll(array $dataSet)\n    {\n        // 分析查询表达式\n        $options = $this->parseExpress();\n        if (!is_array(reset($dataSet))) {\n            return false;\n        }\n        // 生成SQL语句\n        $sql = $this->builder->insertAll($dataSet, $options);\n        // 获取参数绑定\n        $bind = $this->getBind();\n        if ($options['fetch_sql']) {\n            // 获取实际执行的SQL语句\n            return $this->connection->getRealSql($sql, $bind);\n        } else {\n            // 执行操作\n            return $this->execute($sql, $bind);\n        }\n    }\n\n    /**\n     * 通过Select方式插入记录\n     * @access public\n     * @param string $fields 要插入的数据表字段名\n     * @param string $table  要插入的数据表名\n     * @return integer|string\n     * @throws PDOException\n     */\n    public function selectInsert($fields, $table)\n    {\n        // 分析查询表达式\n        $options = $this->parseExpress();\n        // 生成SQL语句\n        $table = $this->parseSqlTable($table);\n        $sql   = $this->builder->selectInsert($fields, $table, $options);\n        // 获取参数绑定\n        $bind = $this->getBind();\n        if ($options['fetch_sql']) {\n            // 获取实际执行的SQL语句\n            return $this->connection->getRealSql($sql, $bind);\n        } else {\n            // 执行操作\n            return $this->execute($sql, $bind);\n        }\n    }\n\n    /**\n     * 更新记录\n     * @access public\n     * @param mixed $data 数据\n     * @return integer|string\n     * @throws Exception\n     * @throws PDOException\n     */\n    public function update(array $data = [])\n    {\n        $options = $this->parseExpress();\n        $data    = array_merge($options['data'], $data);\n        $pk      = $this->getPk($options);\n        if (isset($options['cache']) && is_string($options['cache']['key'])) {\n            $key = $options['cache']['key'];\n        }\n\n        if (empty($options['where'])) {\n            // 如果存在主键数据 则自动作为更新条件\n            if (is_string($pk) && isset($data[$pk])) {\n                $where[$pk] = $data[$pk];\n                if (!isset($key)) {\n                    $key = 'think:' . $options['table'] . '|' . $data[$pk];\n                }\n                unset($data[$pk]);\n            } elseif (is_array($pk)) {\n                // 增加复合主键支持\n                foreach ($pk as $field) {\n                    if (isset($data[$field])) {\n                        $where[$field] = $data[$field];\n                    } else {\n                        // 如果缺少复合主键数据则不执行\n                        throw new Exception('miss complex primary data');\n                    }\n                    unset($data[$field]);\n                }\n            }\n            if (!isset($where)) {\n                // 如果没有任何更新条件则不执行\n                throw new Exception('miss update condition');\n            } else {\n                $options['where']['AND'] = $where;\n            }\n        } elseif (!isset($key) && is_string($pk) && isset($options['where']['AND'][$pk])) {\n            $key = $this->getCacheKey($options['where']['AND'][$pk], $options);\n        }\n\n        // 生成UPDATE SQL语句\n        $sql = $this->builder->update($data, $options);\n        // 获取参数绑定\n        $bind = $this->getBind();\n        if ($options['fetch_sql']) {\n            // 获取实际执行的SQL语句\n            return $this->connection->getRealSql($sql, $bind);\n        } else {\n            // 检测缓存\n            if (isset($key) && Cache::get($key)) {\n                // 删除缓存\n                Cache::rm($key);\n            } elseif (!empty($options['cache']['tag'])) {\n                Cache::clear($options['cache']['tag']);\n            }\n            // 执行操作\n            $result = '' == $sql ? 0 : $this->execute($sql, $bind);\n            if ($result) {\n                if (is_string($pk) && isset($where[$pk])) {\n                    $data[$pk] = $where[$pk];\n                } elseif (is_string($pk) && isset($key) && strpos($key, '|')) {\n                    list($a, $val) = explode('|', $key);\n                    $data[$pk]     = $val;\n                }\n                $options['data'] = $data;\n                $this->trigger('after_update', $options);\n            }\n            return $result;\n        }\n    }\n\n    /**\n     * 执行查询但只返回PDOStatement对象\n     * @access public\n     * @return \\PDOStatement|string\n     */\n    public function getPdo()\n    {\n        // 分析查询表达式\n        $options = $this->parseExpress();\n        // 生成查询SQL\n        $sql = $this->builder->select($options);\n        // 获取参数绑定\n        $bind = $this->getBind();\n        if ($options['fetch_sql']) {\n            // 获取实际执行的SQL语句\n            return $this->connection->getRealSql($sql, $bind);\n        }\n        // 执行查询操作\n        return $this->query($sql, $bind, $options['master'], true);\n    }\n\n    /**\n     * 查找记录\n     * @access public\n     * @param array|string|Query|\\Closure $data\n     * @return Collection|false|\\PDOStatement|string\n     * @throws DbException\n     * @throws ModelNotFoundException\n     * @throws DataNotFoundException\n     */\n    public function select($data = null)\n    {\n        if ($data instanceof Query) {\n            return $data->select();\n        } elseif ($data instanceof \\Closure) {\n            call_user_func_array($data, [ & $this]);\n            $data = null;\n        }\n        // 分析查询表达式\n        $options = $this->parseExpress();\n\n        if (false === $data) {\n            // 用于子查询 不查询只返回SQL\n            $options['fetch_sql'] = true;\n        } elseif (!is_null($data)) {\n            // 主键条件分析\n            $this->parsePkWhere($data, $options);\n        }\n\n        $resultSet = false;\n        if (empty($options['fetch_sql']) && !empty($options['cache'])) {\n            // 判断查询缓存\n            $cache = $options['cache'];\n            unset($options['cache']);\n            $key       = is_string($cache['key']) ? $cache['key'] : md5(serialize($options));\n            $resultSet = Cache::get($key);\n        }\n        if (!$resultSet) {\n            // 生成查询SQL\n            $sql = $this->builder->select($options);\n            // 获取参数绑定\n            $bind = $this->getBind();\n            if ($options['fetch_sql']) {\n                // 获取实际执行的SQL语句\n                return $this->connection->getRealSql($sql, $bind);\n            }\n\n            $options['data'] = $data;\n            if ($resultSet = $this->trigger('before_select', $options)) {\n            } else {\n                // 执行查询操作\n                $resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']);\n\n                if ($resultSet instanceof \\PDOStatement) {\n                    // 返回PDOStatement对象\n                    return $resultSet;\n                }\n            }\n\n            if (isset($cache) && $resultSet) {\n                // 缓存数据集\n                $this->cacheData($key, $resultSet, $cache);\n            }\n        }\n\n        // 数据列表读取后的处理\n        if (!empty($this->model)) {\n            // 生成模型对象\n            $modelName = $this->model;\n            if (count($resultSet) > 0) {\n                foreach ($resultSet as $key => $result) {\n                    /** @var Model $result */\n                    $model = new $modelName($result);\n                    $model->isUpdate(true);\n\n                    // 关联查询\n                    if (!empty($options['relation'])) {\n                        $model->relationQuery($options['relation']);\n                    }\n                    // 关联统计\n                    if (!empty($options['with_count'])) {\n                        $model->relationCount($model, $options['with_count']);\n                    }\n                    $resultSet[$key] = $model;\n                }\n                if (!empty($options['with'])) {\n                    // 预载入\n                    $model->eagerlyResultSet($resultSet, $options['with']);\n                }\n                // 模型数据集转换\n                $resultSet = $model->toCollection($resultSet);\n            } else {\n                $resultSet = (new $modelName)->toCollection($resultSet);\n            }\n        } elseif ('collection' == $this->connection->getConfig('resultset_type')) {\n            // 返回Collection对象\n            $resultSet = new Collection($resultSet);\n        }\n        // 返回结果处理\n        if (!empty($options['fail']) && count($resultSet) == 0) {\n            $this->throwNotFound($options);\n        }\n        return $resultSet;\n    }\n\n    /**\n     * 缓存数据\n     * @access public\n     * @param string    $key    缓存标识\n     * @param mixed     $data   缓存数据\n     * @param array     $config 缓存参数\n     */\n    protected function cacheData($key, $data, $config = [])\n    {\n        if (isset($config['tag'])) {\n            Cache::tag($config['tag'])->set($key, $data, $config['expire']);\n        } else {\n            Cache::set($key, $data, $config['expire']);\n        }\n    }\n\n    /**\n     * 生成缓存标识\n     * @access public\n     * @param mixed     $value   缓存数据\n     * @param array     $options 缓存参数\n     */\n    protected function getCacheKey($value, $options)\n    {\n        if (is_scalar($value)) {\n            $data = $value;\n        } elseif (is_array($value) && 'eq' == strtolower($value[0])) {\n            $data = $value[1];\n        }\n        if (isset($data)) {\n            return 'think:' . $options['table'] . '|' . $data;\n        } else {\n            return md5(serialize($options));\n        }\n    }\n\n    /**\n     * 查找单条记录\n     * @access public\n     * @param array|string|Query|\\Closure $data\n     * @return array|false|\\PDOStatement|string|Model\n     * @throws DbException\n     * @throws ModelNotFoundException\n     * @throws DataNotFoundException\n     */\n    public function find($data = null)\n    {\n        if ($data instanceof Query) {\n            return $data->find();\n        } elseif ($data instanceof \\Closure) {\n            call_user_func_array($data, [ & $this]);\n            $data = null;\n        }\n        // 分析查询表达式\n        $options = $this->parseExpress();\n        $pk      = $this->getPk($options);\n        if (!is_null($data)) {\n            // AR模式分析主键条件\n            $this->parsePkWhere($data, $options);\n        } elseif (!empty($options['cache']) && true === $options['cache']['key'] && is_string($pk) && isset($options['where']['AND'][$pk])) {\n            $key = $this->getCacheKey($options['where']['AND'][$pk], $options);\n        }\n\n        $options['limit'] = 1;\n        $result           = false;\n        if (empty($options['fetch_sql']) && !empty($options['cache'])) {\n            // 判断查询缓存\n            $cache = $options['cache'];\n            if (true === $cache['key'] && !is_null($data) && !is_array($data)) {\n                $key = 'think:' . (is_array($options['table']) ? key($options['table']) : $options['table']) . '|' . $data;\n            } elseif (is_string($cache['key'])) {\n                $key = $cache['key'];\n            } elseif (!isset($key)) {\n                $key = md5(serialize($options));\n            }\n            $result = Cache::get($key);\n        }\n        if (false === $result) {\n            // 生成查询SQL\n            $sql = $this->builder->select($options);\n            // 获取参数绑定\n            $bind = $this->getBind();\n            if ($options['fetch_sql']) {\n                // 获取实际执行的SQL语句\n                return $this->connection->getRealSql($sql, $bind);\n            }\n            if (is_string($pk)) {\n                if (!is_array($data)) {\n                    if (isset($key) && strpos($key, '|')) {\n                        list($a, $val) = explode('|', $key);\n                        $item[$pk]     = $val;\n                    } else {\n                        $item[$pk] = $data;\n                    }\n                    $data = $item;\n                }\n            }\n            $options['data'] = $data;\n            // 事件回调\n            if ($result = $this->trigger('before_find', $options)) {\n            } else {\n                // 执行查询\n                $resultSet = $this->query($sql, $bind, $options['master'], $options['fetch_pdo']);\n\n                if ($resultSet instanceof \\PDOStatement) {\n                    // 返回PDOStatement对象\n                    return $resultSet;\n                }\n                $result = isset($resultSet[0]) ? $resultSet[0] : null;\n            }\n\n            if (isset($cache) && $result) {\n                // 缓存数据\n                $this->cacheData($key, $result, $cache);\n            }\n        }\n\n        // 数据处理\n        if (!empty($result)) {\n            if (!empty($this->model)) {\n                // 返回模型对象\n                $model  = $this->model;\n                $result = new $model($result);\n                $result->isUpdate(true, isset($options['where']['AND']) ? $options['where']['AND'] : null);\n                // 关联查询\n                if (!empty($options['relation'])) {\n                    $result->relationQuery($options['relation']);\n                }\n                // 预载入查询\n                if (!empty($options['with'])) {\n                    $result->eagerlyResult($result, $options['with']);\n                }\n                // 关联统计\n                if (!empty($options['with_count'])) {\n                    $result->relationCount($result, $options['with_count']);\n                }\n            }\n        } elseif (!empty($options['fail'])) {\n            $this->throwNotFound($options);\n        }\n        return $result;\n    }\n\n    /**\n     * 查询失败 抛出异常\n     * @access public\n     * @param array $options 查询参数\n     * @throws ModelNotFoundException\n     * @throws DataNotFoundException\n     */\n    protected function throwNotFound($options = [])\n    {\n        if (!empty($this->model)) {\n            throw new ModelNotFoundException('model data Not Found:' . $this->model, $this->model, $options);\n        } else {\n            $table = is_array($options['table']) ? key($options['table']) : $options['table'];\n            throw new DataNotFoundException('table data not Found:' . $table, $table, $options);\n        }\n    }\n\n    /**\n     * 查找多条记录 如果不存在则抛出异常\n     * @access public\n     * @param array|string|Query|\\Closure $data\n     * @return array|\\PDOStatement|string|Model\n     * @throws DbException\n     * @throws ModelNotFoundException\n     * @throws DataNotFoundException\n     */\n    public function selectOrFail($data = null)\n    {\n        return $this->failException(true)->select($data);\n    }\n\n    /**\n     * 查找单条记录 如果不存在则抛出异常\n     * @access public\n     * @param array|string|Query|\\Closure $data\n     * @return array|\\PDOStatement|string|Model\n     * @throws DbException\n     * @throws ModelNotFoundException\n     * @throws DataNotFoundException\n     */\n    public function findOrFail($data = null)\n    {\n        return $this->failException(true)->find($data);\n    }\n\n    /**\n     * 分批数据返回处理\n     * @access public\n     * @param integer  $count    每次处理的数据数量\n     * @param callable $callback 处理回调方法\n     * @param string   $column   分批处理的字段名\n     * @return boolean\n     */\n    public function chunk($count, $callback, $column = null)\n    {\n        $options = $this->getOptions();\n        if (isset($options['table'])) {\n            $table = is_array($options['table']) ? key($options['table']) : $options['table'];\n        } else {\n            $table = '';\n        }\n        $column    = $column ?: $this->getPk($table);\n        $bind      = $this->bind;\n        $resultSet = $this->limit($count)->order($column, 'asc')->select();\n        if (strpos($column, '.')) {\n            list($alias, $key) = explode('.', $column);\n        } else {\n            $key = $column;\n        }\n        if ($resultSet instanceof Collection) {\n            $resultSet = $resultSet->all();\n        }\n\n        while (!empty($resultSet)) {\n            if (false === call_user_func($callback, $resultSet)) {\n                return false;\n            }\n            $end       = end($resultSet);\n            $lastId    = is_array($end) ? $end[$key] : $end->$key;\n            $resultSet = $this->options($options)\n                ->limit($count)\n                ->bind($bind)\n                ->where($column, '>', $lastId)\n                ->order($column, 'asc')\n                ->select();\n            if ($resultSet instanceof Collection) {\n                $resultSet = $resultSet->all();\n            }\n        }\n        return true;\n    }\n\n    /**\n     * 获取绑定的参数 并清空\n     * @access public\n     * @return array\n     */\n    public function getBind()\n    {\n        $bind       = $this->bind;\n        $this->bind = [];\n        return $bind;\n    }\n\n    /**\n     * 创建子查询SQL\n     * @access public\n     * @param bool $sub\n     * @return string\n     * @throws DbException\n     */\n    public function buildSql($sub = true)\n    {\n        return $sub ? '( ' . $this->select(false) . ' )' : $this->select(false);\n    }\n\n    /**\n     * 删除记录\n     * @access public\n     * @param mixed $data 表达式 true 表示强制删除\n     * @return int\n     * @throws Exception\n     * @throws PDOException\n     */\n    public function delete($data = null)\n    {\n        // 分析查询表达式\n        $options = $this->parseExpress();\n        $pk      = $this->getPk($options);\n        if (isset($options['cache']) && is_string($options['cache']['key'])) {\n            $key = $options['cache']['key'];\n        }\n\n        if (!is_null($data) && true !== $data) {\n            if (!isset($key) && !is_array($data)) {\n                // 缓存标识\n                $key = 'think:' . $options['table'] . '|' . $data;\n            }\n            // AR模式分析主键条件\n            $this->parsePkWhere($data, $options);\n        } elseif (!isset($key) && is_string($pk) && isset($options['where']['AND'][$pk])) {\n            $key = $this->getCacheKey($options['where']['AND'][$pk], $options);\n        }\n\n        if (true !== $data && empty($options['where'])) {\n            // 如果条件为空 不进行删除操作 除非设置 1=1\n            throw new Exception('delete without condition');\n        }\n        // 生成删除SQL语句\n        $sql = $this->builder->delete($options);\n        // 获取参数绑定\n        $bind = $this->getBind();\n        if ($options['fetch_sql']) {\n            // 获取实际执行的SQL语句\n            return $this->connection->getRealSql($sql, $bind);\n        }\n\n        // 检测缓存\n        if (isset($key) && Cache::get($key)) {\n            // 删除缓存\n            Cache::rm($key);\n        } elseif (!empty($options['cache']['tag'])) {\n            Cache::clear($options['cache']['tag']);\n        }\n        // 执行操作\n        $result = $this->execute($sql, $bind);\n        if ($result) {\n            if (!is_array($data) && is_string($pk) && isset($key) && strpos($key, '|')) {\n                list($a, $val) = explode('|', $key);\n                $item[$pk]     = $val;\n                $data          = $item;\n            }\n            $options['data'] = $data;\n            $this->trigger('after_delete', $options);\n        }\n        return $result;\n    }\n\n    /**\n     * 分析表达式（可用于查询或者写入操作）\n     * @access protected\n     * @return array\n     */\n    protected function parseExpress()\n    {\n        $options = $this->options;\n\n        // 获取数据表\n        if (empty($options['table'])) {\n            $options['table'] = $this->getTable();\n        }\n\n        if (!isset($options['where'])) {\n            $options['where'] = [];\n        } elseif (isset($options['view'])) {\n            // 视图查询条件处理\n            foreach (['AND', 'OR'] as $logic) {\n                if (isset($options['where'][$logic])) {\n                    foreach ($options['where'][$logic] as $key => $val) {\n                        if (array_key_exists($key, $options['map'])) {\n                            $options['where'][$logic][$options['map'][$key]] = $val;\n                            unset($options['where'][$logic][$key]);\n                        }\n                    }\n                }\n            }\n\n            if (isset($options['order'])) {\n                // 视图查询排序处理\n                if (is_string($options['order'])) {\n                    $options['order'] = explode(',', $options['order']);\n                }\n                foreach ($options['order'] as $key => $val) {\n                    if (is_numeric($key)) {\n                        if (strpos($val, ' ')) {\n                            list($field, $sort) = explode(' ', $val);\n                            if (array_key_exists($field, $options['map'])) {\n                                $options['order'][$options['map'][$field]] = $sort;\n                                unset($options['order'][$key]);\n                            }\n                        } elseif (array_key_exists($val, $options['map'])) {\n                            $options['order'][$options['map'][$val]] = 'asc';\n                            unset($options['order'][$key]);\n                        }\n                    } elseif (array_key_exists($key, $options['map'])) {\n                        $options['order'][$options['map'][$key]] = $val;\n                        unset($options['order'][$key]);\n                    }\n                }\n            }\n        }\n\n        if (!isset($options['field'])) {\n            $options['field'] = '*';\n        }\n\n        if (!isset($options['data'])) {\n            $options['data'] = [];\n        }\n\n        if (!isset($options['strict'])) {\n            $options['strict'] = $this->getConfig('fields_strict');\n        }\n\n        foreach (['master', 'lock', 'fetch_pdo', 'fetch_sql', 'distinct'] as $name) {\n            if (!isset($options[$name])) {\n                $options[$name] = false;\n            }\n        }\n\n        foreach (['join', 'union', 'group', 'having', 'limit', 'order', 'force', 'comment'] as $name) {\n            if (!isset($options[$name])) {\n                $options[$name] = '';\n            }\n        }\n\n        if (isset($options['page'])) {\n            // 根据页数计算limit\n            list($page, $listRows) = $options['page'];\n            $page                  = $page > 0 ? $page : 1;\n            $listRows              = $listRows > 0 ? $listRows : (is_numeric($options['limit']) ? $options['limit'] : 20);\n            $offset                = $listRows * ($page - 1);\n            $options['limit']      = $offset . ',' . $listRows;\n        }\n\n        $this->options = [];\n        return $options;\n    }\n\n    /**\n     * 注册回调方法\n     * @access public\n     * @param string   $event    事件名\n     * @param callable $callback 回调方法\n     * @return void\n     */\n    public static function event($event, $callback)\n    {\n        self::$event[$event] = $callback;\n    }\n\n    /**\n     * 触发事件\n     * @access protected\n     * @param string $event   事件名\n     * @param mixed  $params  额外参数\n     * @return bool\n     */\n    protected function trigger($event, $params = [])\n    {\n        $result = false;\n        if (isset(self::$event[$event])) {\n            $callback = self::$event[$event];\n            $result   = call_user_func_array($callback, [$params, $this]);\n        }\n        return $result;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/builder/Mysql.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\db\\builder;\n\nuse think\\db\\Builder;\n\n/**\n * mysql数据库驱动\n */\nclass Mysql extends Builder\n{\n    protected $updateSql = 'UPDATE %TABLE% %JOIN% SET %SET% %WHERE% %ORDER%%LIMIT% %LOCK%%COMMENT%';\n\n    /**\n     * 字段和表名处理\n     * @access protected\n     * @param string $key\n     * @param array  $options\n     * @return string\n     */\n    protected function parseKey($key, $options = [])\n    {\n        $key = trim($key);\n        if (strpos($key, '$.') && false === strpos($key, '(')) {\n            // JSON字段支持\n            list($field, $name) = explode('$.', $key);\n            $key                = 'json_extract(' . $field . ', \\'$.' . $name . '\\')';\n        } elseif (strpos($key, '.') && !preg_match('/[,\\'\\\"\\(\\)`\\s]/', $key)) {\n            list($table, $key) = explode('.', $key, 2);\n            if ('__TABLE__' == $table) {\n                $table = $this->query->getTable();\n            }\n            if (isset($options['alias'][$table])) {\n                $table = $options['alias'][$table];\n            }\n        }\n        if (!preg_match('/[,\\'\\\"\\*\\(\\)`.\\s]/', $key)) {\n            $key = '`' . $key . '`';\n        }\n        if (isset($table)) {\n            if (strpos($table, '.')) {\n                $table = str_replace('.', '`.`', $table);\n            }\n            $key = '`' . $table . '`.' . $key;\n        }\n        return $key;\n    }\n\n    /**\n     * 随机排序\n     * @access protected\n     * @return string\n     */\n    protected function parseRand()\n    {\n        return 'rand()';\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/builder/Pgsql.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\db\\builder;\n\nuse think\\db\\Builder;\n\n/**\n * Pgsql数据库驱动\n */\nclass Pgsql extends Builder\n{\n\n    /**\n     * limit分析\n     * @access protected\n     * @param mixed $limit\n     * @return string\n     */\n    public function parseLimit($limit)\n    {\n        $limitStr = '';\n        if (!empty($limit)) {\n            $limit = explode(',', $limit);\n            if (count($limit) > 1) {\n                $limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' ';\n            } else {\n                $limitStr .= ' LIMIT ' . $limit[0] . ' ';\n            }\n        }\n        return $limitStr;\n    }\n\n    /**\n     * 字段和表名处理\n     * @access protected\n     * @param string $key\n     * @param array  $options\n     * @return string\n     */\n    protected function parseKey($key, $options = [])\n    {\n        $key = trim($key);\n        if (strpos($key, '$.') && false === strpos($key, '(')) {\n            // JSON字段支持\n            list($field, $name) = explode('$.', $key);\n            $key                = $field . '->>\\'' . $name . '\\'';\n        } elseif (strpos($key, '.')) {\n            list($table, $key) = explode('.', $key, 2);\n            if ('__TABLE__' == $table) {\n                $table = $this->query->getTable();\n            }\n            if (isset($options['alias'][$table])) {\n                $table = $options['alias'][$table];\n            }\n        }\n        if (isset($table)) {\n            $key = $table . '.' . $key;\n        }\n        return $key;\n    }\n\n    /**\n     * 随机排序\n     * @access protected\n     * @return string\n     */\n    protected function parseRand()\n    {\n        return 'RANDOM()';\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/builder/Sqlite.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\db\\builder;\n\nuse think\\db\\Builder;\n\n/**\n * Sqlite数据库驱动\n */\nclass Sqlite extends Builder\n{\n\n    /**\n     * limit\n     * @access public\n     * @return string\n     */\n    public function parseLimit($limit)\n    {\n        $limitStr = '';\n        if (!empty($limit)) {\n            $limit = explode(',', $limit);\n            if (count($limit) > 1) {\n                $limitStr .= ' LIMIT ' . $limit[1] . ' OFFSET ' . $limit[0] . ' ';\n            } else {\n                $limitStr .= ' LIMIT ' . $limit[0] . ' ';\n            }\n        }\n        return $limitStr;\n    }\n\n    /**\n     * 随机排序\n     * @access protected\n     * @return string\n     */\n    protected function parseRand()\n    {\n        return 'RANDOM()';\n    }\n\n    /**\n     * 字段和表名处理\n     * @access protected\n     * @param string $key\n     * @param array  $options\n     * @return string\n     */\n    protected function parseKey($key, $options = [])\n    {\n        $key = trim($key);\n        if (strpos($key, '.')) {\n            list($table, $key) = explode('.', $key, 2);\n            if ('__TABLE__' == $table) {\n                $table = $this->query->getTable();\n            }\n            if (isset($options['alias'][$table])) {\n                $table = $options['alias'][$table];\n            }\n        }\n        if (isset($table)) {\n            $key = $table . '.' . $key;\n        }\n        return $key;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/builder/Sqlsrv.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\db\\builder;\n\nuse think\\db\\Builder;\n\n/**\n * Sqlsrv数据库驱动\n */\nclass Sqlsrv extends Builder\n{\n    protected $selectSql       = 'SELECT T1.* FROM (SELECT thinkphp.*, ROW_NUMBER() OVER (%ORDER%) AS ROW_NUMBER FROM (SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%) AS thinkphp) AS T1 %LIMIT%%COMMENT%';\n    protected $selectInsertSql = 'SELECT %DISTINCT% %FIELD% FROM %TABLE%%JOIN%%WHERE%%GROUP%%HAVING%';\n    protected $updateSql       = 'UPDATE %TABLE% SET %SET% FROM %TABLE% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%';\n    protected $deleteSql       = 'DELETE FROM %TABLE% %USING% %JOIN% %WHERE% %LIMIT% %LOCK%%COMMENT%';\n\n    /**\n     * order分析\n     * @access protected\n     * @param mixed $order\n     * @param array $options\n     * @return string\n     */\n    protected function parseOrder($order, $options = [])\n    {\n        if (is_array($order)) {\n            $array = [];\n            foreach ($order as $key => $val) {\n                if (is_numeric($key)) {\n                    if (false === strpos($val, '(')) {\n                        $array[] = $this->parseKey($val, $options);\n                    } elseif ('[rand]' == $val) {\n                        $array[] = $this->parseRand();\n                    }\n                } else {\n                    $sort    = in_array(strtolower(trim($val)), ['asc', 'desc']) ? ' ' . $val : '';\n                    $array[] = $this->parseKey($key, $options) . ' ' . $sort;\n                }\n            }\n            $order = implode(',', $array);\n        }\n        return !empty($order) ? ' ORDER BY ' . $order : ' ORDER BY rand()';\n    }\n\n    /**\n     * 随机排序\n     * @access protected\n     * @return string\n     */\n    protected function parseRand()\n    {\n        return 'rand()';\n    }\n\n    /**\n     * 字段和表名处理\n     * @access protected\n     * @param string $key\n     * @param array  $options\n     * @return string\n     */\n    protected function parseKey($key, $options = [])\n    {\n        $key = trim($key);\n        if (strpos($key, '.') && !preg_match('/[,\\'\\\"\\(\\)\\[\\s]/', $key)) {\n            list($table, $key) = explode('.', $key, 2);\n            if ('__TABLE__' == $table) {\n                $table = $this->query->getTable();\n            }\n            if (isset($options['alias'][$table])) {\n                $table = $options['alias'][$table];\n            }\n        }\n        if (!is_numeric($key) && !preg_match('/[,\\'\\\"\\*\\(\\)\\[.\\s]/', $key)) {\n            $key = '[' . $key . ']';\n        }\n        if (isset($table)) {\n            $key = '[' . $table . '].' . $key;\n        }\n        return $key;\n    }\n\n    /**\n     * limit\n     * @access protected\n     * @param mixed $limit\n     * @return string\n     */\n    protected function parseLimit($limit)\n    {\n        if (empty($limit)) {\n            return '';\n        }\n\n        $limit = explode(',', $limit);\n        if (count($limit) > 1) {\n            $limitStr = '(T1.ROW_NUMBER BETWEEN ' . $limit[0] . ' + 1 AND ' . $limit[0] . ' + ' . $limit[1] . ')';\n        } else {\n            $limitStr = '(T1.ROW_NUMBER BETWEEN 1 AND ' . $limit[0] . \")\";\n        }\n        return 'WHERE ' . $limitStr;\n    }\n\n    public function selectInsert($fields, $table, $options)\n    {\n        $this->selectSql = $this->selectInsertSql;\n        return parent::selectInsert($fields, $table, $options);\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/connector/Mysql.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\db\\connector;\n\nuse PDO;\nuse think\\db\\Connection;\nuse think\\Log;\n\n/**\n * mysql数据库驱动\n */\nclass Mysql extends Connection\n{\n\n    protected $builder = '\\\\think\\\\db\\\\builder\\\\Mysql';\n\n    /**\n     * 解析pdo连接的dsn信息\n     * @access protected\n     * @param array $config 连接信息\n     * @return string\n     */\n    protected function parseDsn($config)\n    {\n        $dsn = 'mysql:dbname=' . $config['database'] . ';host=' . $config['hostname'];\n        if (!empty($config['hostport'])) {\n            $dsn .= ';port=' . $config['hostport'];\n        } elseif (!empty($config['socket'])) {\n            $dsn .= ';unix_socket=' . $config['socket'];\n        }\n        if (!empty($config['charset'])) {\n            $dsn .= ';charset=' . $config['charset'];\n        }\n        return $dsn;\n    }\n\n    /**\n     * 取得数据表的字段信息\n     * @access public\n     * @param string $tableName\n     * @return array\n     */\n    public function getFields($tableName)\n    {\n        $this->initConnect(true);\n        list($tableName) = explode(' ', $tableName);\n        if (false === strpos($tableName, '`')) {\n            if (strpos($tableName, '.')) {\n                $tableName = str_replace('.', '`.`', $tableName);\n            }\n            $tableName = '`' . $tableName . '`';\n        }\n        $sql = 'SHOW COLUMNS FROM ' . $tableName;\n        // 调试开始\n        $this->debug(true);\n        $pdo = $this->linkID->query($sql);\n        // 调试结束\n        $this->debug(false, $sql);\n        $result = $pdo->fetchAll(PDO::FETCH_ASSOC);\n        $info   = [];\n        if ($result) {\n            foreach ($result as $key => $val) {\n                $val                 = array_change_key_case($val);\n                $info[$val['field']] = [\n                    'name'    => $val['field'],\n                    'type'    => $val['type'],\n                    'notnull' => (bool) ('' === $val['null']), // not null is empty, null is yes\n                    'default' => $val['default'],\n                    'primary' => (strtolower($val['key']) == 'pri'),\n                    'autoinc' => (strtolower($val['extra']) == 'auto_increment'),\n                ];\n            }\n        }\n        return $this->fieldCase($info);\n    }\n\n    /**\n     * 取得数据库的表信息\n     * @access public\n     * @param string $dbName\n     * @return array\n     */\n    public function getTables($dbName = '')\n    {\n        $this->initConnect(true);\n        $sql = !empty($dbName) ? 'SHOW TABLES FROM ' . $dbName : 'SHOW TABLES ';\n        // 调试开始\n        $this->debug(true);\n        $pdo = $this->linkID->query($sql);\n        // 调试结束\n        $this->debug(false, $sql);\n        $result = $pdo->fetchAll(PDO::FETCH_ASSOC);\n        $info   = [];\n        foreach ($result as $key => $val) {\n            $info[$key] = current($val);\n        }\n        return $info;\n    }\n\n    /**\n     * SQL性能分析\n     * @access protected\n     * @param string $sql\n     * @return array\n     */\n    protected function getExplain($sql)\n    {\n        $pdo    = $this->linkID->query(\"EXPLAIN \" . $sql);\n        $result = $pdo->fetch(PDO::FETCH_ASSOC);\n        $result = array_change_key_case($result);\n        if (isset($result['extra'])) {\n            if (strpos($result['extra'], 'filesort') || strpos($result['extra'], 'temporary')) {\n                Log::record('SQL:' . $this->queryStr . '[' . $result['extra'] . ']', 'warn');\n            }\n        }\n        return $result;\n    }\n\n    protected function supportSavepoint()\n    {\n        return true;\n    }\n\n    /**\n     * 是否断线\n     * @access protected\n     * @param \\PDOException  $e 异常对象\n     * @return bool\n     */\n    protected function isBreak($e)\n    {\n        if (false !== stripos($e->getMessage(), 'server has gone away')) {\n            return true;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/connector/Pgsql.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\db\\connector;\n\nuse PDO;\nuse think\\db\\Connection;\n\n/**\n * Pgsql数据库驱动\n */\nclass Pgsql extends Connection\n{\n    protected $builder = '\\\\think\\\\db\\\\builder\\\\Pgsql';\n\n    /**\n     * 解析pdo连接的dsn信息\n     * @access protected\n     * @param array $config 连接信息\n     * @return string\n     */\n    protected function parseDsn($config)\n    {\n        $dsn = 'pgsql:dbname=' . $config['database'] . ';host=' . $config['hostname'];\n        if (!empty($config['hostport'])) {\n            $dsn .= ';port=' . $config['hostport'];\n        }\n        return $dsn;\n    }\n\n    /**\n     * 取得数据表的字段信息\n     * @access public\n     * @param string $tableName\n     * @return array\n     */\n    public function getFields($tableName)\n    {\n        $this->initConnect(true);\n        list($tableName) = explode(' ', $tableName);\n        $sql             = 'select fields_name as \"field\",fields_type as \"type\",fields_not_null as \"null\",fields_key_name as \"key\",fields_default as \"default\",fields_default as \"extra\" from table_msg(\\'' . $tableName . '\\');';\n        // 调试开始\n        $this->debug(true);\n        $pdo = $this->linkID->query($sql);\n        // 调试结束\n        $this->debug(false, $sql);\n        $result = $pdo->fetchAll(PDO::FETCH_ASSOC);\n        $info   = [];\n        if ($result) {\n            foreach ($result as $key => $val) {\n                $val                 = array_change_key_case($val);\n                $info[$val['field']] = [\n                    'name'    => $val['field'],\n                    'type'    => $val['type'],\n                    'notnull' => (bool) ('' !== $val['null']),\n                    'default' => $val['default'],\n                    'primary' => !empty($val['key']),\n                    'autoinc' => (0 === strpos($val['extra'], 'nextval(')),\n                ];\n            }\n        }\n        return $this->fieldCase($info);\n    }\n\n    /**\n     * 取得数据库的表信息\n     * @access public\n     * @param string $dbName\n     * @return array\n     */\n    public function getTables($dbName = '')\n    {\n        $this->initConnect(true);\n        $sql = \"select tablename as Tables_in_test from pg_tables where  schemaname ='public'\";\n        // 调试开始\n        $this->debug(true);\n        $pdo = $this->linkID->query($sql);\n        // 调试结束\n        $this->debug(false, $sql);\n        $result = $pdo->fetchAll(PDO::FETCH_ASSOC);\n        $info   = [];\n        foreach ($result as $key => $val) {\n            $info[$key] = current($val);\n        }\n        return $info;\n    }\n\n    /**\n     * SQL性能分析\n     * @access protected\n     * @param string $sql\n     * @return array\n     */\n    protected function getExplain($sql)\n    {\n        return [];\n    }\n\n    protected function supportSavepoint()\n    {\n        return true;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/connector/Sqlite.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\db\\connector;\n\nuse PDO;\nuse think\\db\\Connection;\n\n/**\n * Sqlite数据库驱动\n */\nclass Sqlite extends Connection\n{\n\n    protected $builder = '\\\\think\\\\db\\\\builder\\\\Sqlite';\n\n    /**\n     * 解析pdo连接的dsn信息\n     * @access protected\n     * @param array $config 连接信息\n     * @return string\n     */\n    protected function parseDsn($config)\n    {\n        $dsn = 'sqlite:' . $config['database'];\n        return $dsn;\n    }\n\n    /**\n     * 取得数据表的字段信息\n     * @access public\n     * @param string $tableName\n     * @return array\n     */\n    public function getFields($tableName)\n    {\n        $this->initConnect(true);\n        list($tableName) = explode(' ', $tableName);\n        $sql             = 'PRAGMA table_info( ' . $tableName . ' )';\n        // 调试开始\n        $this->debug(true);\n        $pdo = $this->linkID->query($sql);\n        // 调试结束\n        $this->debug(false, $sql);\n        $result = $pdo->fetchAll(PDO::FETCH_ASSOC);\n        $info   = [];\n        if ($result) {\n            foreach ($result as $key => $val) {\n                $val                = array_change_key_case($val);\n                $info[$val['name']] = [\n                    'name'    => $val['name'],\n                    'type'    => $val['type'],\n                    'notnull' => 1 === $val['notnull'],\n                    'default' => $val['dflt_value'],\n                    'primary' => '1' == $val['pk'],\n                    'autoinc' => '1' == $val['pk'],\n                ];\n            }\n        }\n        return $this->fieldCase($info);\n    }\n\n    /**\n     * 取得数据库的表信息\n     * @access public\n     * @param string $dbName\n     * @return array\n     */\n    public function getTables($dbName = '')\n    {\n        $this->initConnect(true);\n        $sql = \"SELECT name FROM sqlite_master WHERE type='table' \"\n            . \"UNION ALL SELECT name FROM sqlite_temp_master \"\n            . \"WHERE type='table' ORDER BY name\";\n        // 调试开始\n        $this->debug(true);\n        $pdo = $this->linkID->query($sql);\n        // 调试结束\n        $this->debug(false, $sql);\n        $result = $pdo->fetchAll(PDO::FETCH_ASSOC);\n        $info   = [];\n        foreach ($result as $key => $val) {\n            $info[$key] = current($val);\n        }\n        return $info;\n    }\n\n    /**\n     * SQL性能分析\n     * @access protected\n     * @param string $sql\n     * @return array\n     */\n    protected function getExplain($sql)\n    {\n        return [];\n    }\n\n    protected function supportSavepoint()\n    {\n        return true;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/connector/Sqlsrv.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2012 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\db\\connector;\n\nuse PDO;\nuse think\\db\\Connection;\n\n/**\n * Sqlsrv数据库驱动\n */\nclass Sqlsrv extends Connection\n{\n    // PDO连接参数\n    protected $params = [\n        PDO::ATTR_CASE              => PDO::CASE_NATURAL,\n        PDO::ATTR_ERRMODE           => PDO::ERRMODE_EXCEPTION,\n        PDO::ATTR_STRINGIFY_FETCHES => false,\n    ];\n    protected $builder = '\\\\think\\\\db\\\\builder\\\\Sqlsrv';\n    /**\n     * 解析pdo连接的dsn信息\n     * @access protected\n     * @param array $config 连接信息\n     * @return string\n     */\n    protected function parseDsn($config)\n    {\n        $dsn = 'sqlsrv:Database=' . $config['database'] . ';Server=' . $config['hostname'];\n        if (!empty($config['hostport'])) {\n            $dsn .= ',' . $config['hostport'];\n        }\n        return $dsn;\n    }\n\n    /**\n     * 取得数据表的字段信息\n     * @access public\n     * @param string $tableName\n     * @return array\n     */\n    public function getFields($tableName)\n    {\n        $this->initConnect(true);\n        list($tableName) = explode(' ', $tableName);\n        $sql             = \"SELECT   column_name,   data_type,   column_default,   is_nullable\n        FROM    information_schema.tables AS t\n        JOIN    information_schema.columns AS c\n        ON  t.table_catalog = c.table_catalog\n        AND t.table_schema  = c.table_schema\n        AND t.table_name    = c.table_name\n        WHERE   t.table_name = '$tableName'\";\n        // 调试开始\n        $this->debug(true);\n        $pdo = $this->linkID->query($sql);\n        // 调试结束\n        $this->debug(false, $sql);\n        $result = $pdo->fetchAll(PDO::FETCH_ASSOC);\n        $info   = [];\n        if ($result) {\n            foreach ($result as $key => $val) {\n                $val                       = array_change_key_case($val);\n                $info[$val['column_name']] = [\n                    'name'    => $val['column_name'],\n                    'type'    => $val['data_type'],\n                    'notnull' => (bool) ('' === $val['is_nullable']), // not null is empty, null is yes\n                    'default' => $val['column_default'],\n                    'primary' => false,\n                    'autoinc' => false,\n                ];\n            }\n        }\n        $sql = \"SELECT column_name FROM information_schema.key_column_usage WHERE table_name='$tableName'\";\n        // 调试开始\n        $this->debug(true);\n        $pdo = $this->linkID->query($sql);\n        // 调试结束\n        $this->debug(false, $sql);\n        $result = $pdo->fetch(PDO::FETCH_ASSOC);\n        if ($result) {\n            $info[$result['column_name']]['primary'] = true;\n        }\n        return $this->fieldCase($info);\n    }\n\n    /**\n     * 取得数据表的字段信息\n     * @access public\n     * @param string $dbName\n     * @return array\n     */\n    public function getTables($dbName = '')\n    {\n        $this->initConnect(true);\n        $sql = \"SELECT TABLE_NAME\n            FROM INFORMATION_SCHEMA.TABLES\n            WHERE TABLE_TYPE = 'BASE TABLE'\n            \";\n        // 调试开始\n        $this->debug(true);\n        $pdo = $this->linkID->query($sql);\n        // 调试结束\n        $this->debug(false, $sql);\n        $result = $pdo->fetchAll(PDO::FETCH_ASSOC);\n        $info   = [];\n        foreach ($result as $key => $val) {\n            $info[$key] = current($val);\n        }\n        return $info;\n    }\n\n    /**\n     * SQL性能分析\n     * @access protected\n     * @param string $sql\n     * @return array\n     */\n    protected function getExplain($sql)\n    {\n        return [];\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/connector/pgsql.sql",
    "content": "CREATE OR REPLACE FUNCTION pgsql_type(a_type varchar) RETURNS varchar AS\n$BODY$\nDECLARE\n     v_type varchar;\nBEGIN\n     IF a_type='int8' THEN\n          v_type:='bigint';\n     ELSIF a_type='int4' THEN\n          v_type:='integer';\n     ELSIF a_type='int2' THEN\n          v_type:='smallint';\n     ELSIF a_type='bpchar' THEN\n          v_type:='char';\n     ELSE\n          v_type:=a_type;\n     END IF;\n     RETURN v_type;\nEND;\n$BODY$\nLANGUAGE PLPGSQL;\n\nCREATE TYPE \"public\".\"tablestruct\" AS (\n  \"fields_key_name\" varchar(100),\n  \"fields_name\" VARCHAR(200),\n  \"fields_type\" VARCHAR(20),\n  \"fields_length\" BIGINT,\n  \"fields_not_null\" VARCHAR(10),\n  \"fields_default\" VARCHAR(500),\n  \"fields_comment\" VARCHAR(1000)\n);\n\nCREATE OR REPLACE FUNCTION \"public\".\"table_msg\" (a_schema_name varchar, a_table_name varchar) RETURNS SETOF \"public\".\"tablestruct\" AS\n$body$\nDECLARE\n     v_ret tablestruct;\n     v_oid oid;\n     v_sql varchar;\n     v_rec RECORD;\n     v_key varchar;\nBEGIN\n     SELECT\n           pg_class.oid  INTO v_oid\n     FROM\n           pg_class\n           INNER JOIN pg_namespace ON (pg_class.relnamespace = pg_namespace.oid AND lower(pg_namespace.nspname) = a_schema_name)\n     WHERE\n           pg_class.relname=a_table_name;\n     IF NOT FOUND THEN\n         RETURN;\n     END IF;\n\n     v_sql='\n     SELECT\n           pg_attribute.attname AS fields_name,\n           pg_attribute.attnum AS fields_index,\n           pgsql_type(pg_type.typname::varchar) AS fields_type,\n           pg_attribute.atttypmod-4 as fields_length,\n           CASE WHEN pg_attribute.attnotnull  THEN ''not null''\n           ELSE ''''\n           END AS fields_not_null,\n           pg_attrdef.adsrc AS fields_default,\n           pg_description.description AS fields_comment\n     FROM\n           pg_attribute\n           INNER JOIN pg_class  ON pg_attribute.attrelid = pg_class.oid\n           INNER JOIN pg_type   ON pg_attribute.atttypid = pg_type.oid\n           LEFT OUTER JOIN pg_attrdef ON pg_attrdef.adrelid = pg_class.oid AND pg_attrdef.adnum = pg_attribute.attnum\n           LEFT OUTER JOIN pg_description ON pg_description.objoid = pg_class.oid AND pg_description.objsubid = pg_attribute.attnum\n     WHERE\n           pg_attribute.attnum > 0\n           AND attisdropped <> ''t''\n           AND pg_class.oid = ' || v_oid || '\n     ORDER BY pg_attribute.attnum' ;\n\n     FOR v_rec IN EXECUTE v_sql LOOP\n         v_ret.fields_name=v_rec.fields_name;\n         v_ret.fields_type=v_rec.fields_type;\n         IF v_rec.fields_length > 0 THEN\n            v_ret.fields_length:=v_rec.fields_length;\n         ELSE\n            v_ret.fields_length:=NULL;\n         END IF;\n         v_ret.fields_not_null=v_rec.fields_not_null;\n         v_ret.fields_default=v_rec.fields_default;\n         v_ret.fields_comment=v_rec.fields_comment;\n         SELECT constraint_name INTO v_key FROM information_schema.key_column_usage WHERE table_schema=a_schema_name AND table_name=a_table_name AND column_name=v_rec.fields_name;\n         IF FOUND THEN\n            v_ret.fields_key_name=v_key;\n         ELSE\n            v_ret.fields_key_name='';\n         END IF;\n         RETURN NEXT v_ret;\n     END LOOP;\n     RETURN ;\nEND;\n$body$\nLANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;\n\nCOMMENT ON FUNCTION \"public\".\"table_msg\"(a_schema_name varchar, a_table_name varchar)\nIS '获得表信息';\n\n---重载一个函数\nCREATE OR REPLACE FUNCTION \"public\".\"table_msg\" (a_table_name varchar) RETURNS SETOF \"public\".\"tablestruct\" AS\n$body$\nDECLARE\n    v_ret tablestruct;\nBEGIN\n    FOR v_ret IN SELECT * FROM table_msg('public',a_table_name) LOOP\n        RETURN NEXT v_ret;\n    END LOOP;\n    RETURN;\nEND;\n$body$\nLANGUAGE 'plpgsql' VOLATILE CALLED ON NULL INPUT SECURITY INVOKER;\n\nCOMMENT ON FUNCTION \"public\".\"table_msg\"(a_table_name varchar)\nIS '获得表信息';"
  },
  {
    "path": "thinkphp/library/think/db/exception/BindParamException.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>\n// +----------------------------------------------------------------------\n\nnamespace think\\db\\exception;\n\nuse think\\exception\\DbException;\n\n/**\n * PDO参数绑定异常\n */\nclass BindParamException extends DbException\n{\n\n    /**\n     * BindParamException constructor.\n     * @param string $message\n     * @param array  $config\n     * @param string $sql\n     * @param array    $bind\n     * @param int    $code\n     */\n    public function __construct($message, $config, $sql, $bind, $code = 10502)\n    {\n        $this->setData('Bind Param', $bind);\n        parent::__construct($message, $config, $sql, $code);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/exception/DataNotFoundException.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>\n// +----------------------------------------------------------------------\n\nnamespace think\\db\\exception;\n\nuse think\\exception\\DbException;\n\nclass DataNotFoundException extends DbException\n{\n    protected $table;\n\n    /**\n     * DbException constructor.\n     * @param string $message\n     * @param string $table\n     * @param array $config\n     */\n    public function __construct($message, $table = '', array $config = [])\n    {\n        $this->message = $message;\n        $this->table   = $table;\n\n        $this->setData('Database Config', $config);\n    }\n\n    /**\n     * 获取数据表名\n     * @access public\n     * @return string\n     */\n    public function getTable()\n    {\n        return $this->table;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/db/exception/ModelNotFoundException.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>\n// +----------------------------------------------------------------------\n\nnamespace think\\db\\exception;\n\nuse think\\exception\\DbException;\n\nclass ModelNotFoundException extends DbException\n{\n    protected $model;\n\n    /**\n     * 构造方法\n     * @param string $message\n     * @param string $model\n     */\n    public function __construct($message, $model = '', array $config = [])\n    {\n        $this->message = $message;\n        $this->model   = $model;\n\n        $this->setData('Database Config', $config);\n    }\n\n    /**\n     * 获取模型类名\n     * @access public\n     * @return string\n     */\n    public function getModel()\n    {\n        return $this->model;\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/debug/Console.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yangweijie <yangweijiester@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\debug;\n\nuse think\\Cache;\nuse think\\Config;\nuse think\\Db;\nuse think\\Debug;\nuse think\\Request;\nuse think\\Response;\n\n/**\n * 浏览器调试输出\n */\nclass Console\n{\n    protected $config = [\n        'trace_tabs' => ['base' => '基本', 'file' => '文件', 'info' => '流程', 'notice|error' => '错误', 'sql' => 'SQL', 'debug|log' => '调试'],\n    ];\n\n    // 实例化并传入参数\n    public function __construct($config = [])\n    {\n        if (is_array($config)) {\n            $this->config = array_merge($this->config, $config);\n        }\n    }\n\n    /**\n     * 调试输出接口\n     * @access public\n     * @param Response  $response Response对象\n     * @param array     $log 日志信息\n     * @return bool\n     */\n    public function output(Response $response, array $log = [])\n    {\n        $request     = Request::instance();\n        $contentType = $response->getHeader('Content-Type');\n        $accept      = $request->header('accept');\n        if (strpos($accept, 'application/json') === 0 || $request->isAjax()) {\n            return false;\n        } elseif (!empty($contentType) && strpos($contentType, 'html') === false) {\n            return false;\n        }\n        // 获取基本信息\n        $runtime = number_format(microtime(true) - THINK_START_TIME, 10);\n        $reqs    = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞';\n        $mem     = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2);\n\n        if (isset($_SERVER['HTTP_HOST'])) {\n            $uri = $_SERVER['SERVER_PROTOCOL'] . ' ' . $_SERVER['REQUEST_METHOD'] . ' : ' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];\n        } else {\n            $uri = 'cmd:' . implode(' ', $_SERVER['argv']);\n        }\n\n        // 页面Trace信息\n        $base = [\n            '请求信息' => date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']) . ' ' . $uri,\n            '运行时间' => number_format($runtime, 6) . 's [ 吞吐率：' . $reqs . 'req/s ] 内存消耗：' . $mem . 'kb 文件加载：' . count(get_included_files()),\n            '查询信息' => Db::$queryTimes . ' queries ' . Db::$executeTimes . ' writes ',\n            '缓存信息' => Cache::$readTimes . ' reads,' . Cache::$writeTimes . ' writes',\n            '配置加载' => count(Config::get()),\n        ];\n\n        if (session_id()) {\n            $base['会话信息'] = 'SESSION_ID=' . session_id();\n        }\n\n        $info = Debug::getFile(true);\n\n        // 页面Trace信息\n        $trace = [];\n        foreach ($this->config['trace_tabs'] as $name => $title) {\n            $name = strtolower($name);\n            switch ($name) {\n                case 'base': // 基本信息\n                    $trace[$title] = $base;\n                    break;\n                case 'file': // 文件信息\n                    $trace[$title] = $info;\n                    break;\n                default: // 调试信息\n                    if (strpos($name, '|')) {\n                        // 多组信息\n                        $names  = explode('|', $name);\n                        $result = [];\n                        foreach ($names as $name) {\n                            $result = array_merge($result, isset($log[$name]) ? $log[$name] : []);\n                        }\n                        $trace[$title] = $result;\n                    } else {\n                        $trace[$title] = isset($log[$name]) ? $log[$name] : '';\n                    }\n            }\n        }\n\n        //输出到控制台\n        $lines = '';\n        foreach ($trace as $type => $msg) {\n            $lines .= $this->console($type, $msg);\n        }\n        $js = <<<JS\n\n<script type='text/javascript'>\n{$lines}\n</script>\nJS;\n        return $js;\n    }\n\n    protected function console($type, $msg)\n    {\n        $type       = strtolower($type);\n        $trace_tabs = array_values($this->config['trace_tabs']);\n        $line[]     = ($type == $trace_tabs[0] || '调试' == $type || '错误' == $type)\n        ? \"console.group('{$type}');\"\n        : \"console.groupCollapsed('{$type}');\";\n\n        foreach ((array) $msg as $key => $m) {\n            switch ($type) {\n                case '调试':\n                    $var_type = gettype($m);\n                    if (in_array($var_type, ['array', 'string'])) {\n                        $line[] = \"console.log(\" . json_encode($m) . \");\";\n                    } else {\n                        $line[] = \"console.log(\" . json_encode(var_export($m, 1)) . \");\";\n                    }\n                    break;\n                case '错误':\n                    $msg    = str_replace(\"\\n\", '\\n', $m);\n                    $style  = 'color:#F4006B;font-size:14px;';\n                    $line[] = \"console.error(\\\"%c{$msg}\\\", \\\"{$style}\\\");\";\n                    break;\n                case 'sql':\n                    $msg    = str_replace(\"\\n\", '\\n', $m);\n                    $style  = \"color:#009bb4;\";\n                    $line[] = \"console.log(\\\"%c{$msg}\\\", \\\"{$style}\\\");\";\n                    break;\n                default:\n                    $m      = is_string($key) ? $key . ' ' . $m : $key + 1 . ' ' . $m;\n                    $msg    = json_encode($m);\n                    $line[] = \"console.log({$msg});\";\n                    break;\n            }\n        }\n        $line[] = \"console.groupEnd();\";\n        return implode(PHP_EOL, $line);\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/debug/Html.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\debug;\n\nuse think\\Cache;\nuse think\\Config;\nuse think\\Db;\nuse think\\Debug;\nuse think\\Request;\nuse think\\Response;\n\n/**\n * 页面Trace调试\n */\nclass Html\n{\n    protected $config = [\n        'trace_file' => '',\n        'trace_tabs' => ['base' => '基本', 'file' => '文件', 'info' => '流程', 'notice|error' => '错误', 'sql' => 'SQL', 'debug|log' => '调试'],\n    ];\n\n    // 实例化并传入参数\n    public function __construct(array $config = [])\n    {\n        $this->config['trace_file'] = THINK_PATH . 'tpl/page_trace.tpl';\n        $this->config               = array_merge($this->config, $config);\n    }\n\n    /**\n     * 调试输出接口\n     * @access public\n     * @param Response  $response Response对象\n     * @param array     $log 日志信息\n     * @return bool\n     */\n    public function output(Response $response, array $log = [])\n    {\n        $request     = Request::instance();\n        $contentType = $response->getHeader('Content-Type');\n        $accept      = $request->header('accept');\n        if (strpos($accept, 'application/json') === 0 || $request->isAjax()) {\n            return false;\n        } elseif (!empty($contentType) && strpos($contentType, 'html') === false) {\n            return false;\n        }\n        // 获取基本信息\n        $runtime = number_format(microtime(true) - THINK_START_TIME, 10);\n        $reqs    = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞';\n        $mem     = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2);\n\n        // 页面Trace信息\n        if (isset($_SERVER['HTTP_HOST'])) {\n            $uri = $_SERVER['SERVER_PROTOCOL'] . ' ' . $_SERVER['REQUEST_METHOD'] . ' : ' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];\n        } else {\n            $uri = 'cmd:' . implode(' ', $_SERVER['argv']);\n        }\n        $base = [\n            '请求信息' => date('Y-m-d H:i:s', $_SERVER['REQUEST_TIME']) . ' ' . $uri,\n            '运行时间' => number_format($runtime, 6) . 's [ 吞吐率：' . $reqs . 'req/s ] 内存消耗：' . $mem . 'kb 文件加载：' . count(get_included_files()),\n            '查询信息' => Db::$queryTimes . ' queries ' . Db::$executeTimes . ' writes ',\n            '缓存信息' => Cache::$readTimes . ' reads,' . Cache::$writeTimes . ' writes',\n            '配置加载' => count(Config::get()),\n        ];\n\n        if (session_id()) {\n            $base['会话信息'] = 'SESSION_ID=' . session_id();\n        }\n\n        $info = Debug::getFile(true);\n\n        // 页面Trace信息\n        $trace = [];\n        foreach ($this->config['trace_tabs'] as $name => $title) {\n            $name = strtolower($name);\n            switch ($name) {\n                case 'base': // 基本信息\n                    $trace[$title] = $base;\n                    break;\n                case 'file': // 文件信息\n                    $trace[$title] = $info;\n                    break;\n                default: // 调试信息\n                    if (strpos($name, '|')) {\n                        // 多组信息\n                        $names  = explode('|', $name);\n                        $result = [];\n                        foreach ($names as $name) {\n                            $result = array_merge($result, isset($log[$name]) ? $log[$name] : []);\n                        }\n                        $trace[$title] = $result;\n                    } else {\n                        $trace[$title] = isset($log[$name]) ? $log[$name] : '';\n                    }\n            }\n        }\n        // 调用Trace页面模板\n        ob_start();\n        include $this->config['trace_file'];\n        return ob_get_clean();\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/exception/ClassNotFoundException.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\exception;\n\nclass ClassNotFoundException extends \\RuntimeException\n{\n    protected $class;\n    public function __construct($message, $class = '')\n    {\n        $this->message = $message;\n        $this->class   = $class;\n    }\n\n    /**\n     * 获取类名\n     * @access public\n     * @return string\n     */\n    public function getClass()\n    {\n        return $this->class;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/exception/DbException.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>\n// +----------------------------------------------------------------------\n\nnamespace think\\exception;\n\nuse think\\Exception;\n\n/**\n * Database相关异常处理类\n */\nclass DbException extends Exception\n{\n    /**\n     * DbException constructor.\n     * @param string    $message\n     * @param array     $config\n     * @param string    $sql\n     * @param int       $code\n     */\n    public function __construct($message, array $config, $sql, $code = 10500)\n    {\n        $this->message = $message;\n        $this->code    = $code;\n\n        $this->setData('Database Status', [\n            'Error Code'    => $code,\n            'Error Message' => $message,\n            'Error SQL'     => $sql,\n        ]);\n\n        $this->setData('Database Config', $config);\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/exception/ErrorException.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>\n// +----------------------------------------------------------------------\n\nnamespace think\\exception;\n\nuse think\\Exception;\n\n/**\n * ThinkPHP错误异常\n * 主要用于封装 set_error_handler 和 register_shutdown_function 得到的错误\n * 除开从 think\\Exception 继承的功能\n * 其他和PHP系统\\ErrorException功能基本一样\n */\nclass ErrorException extends Exception\n{\n    /**\n     * 用于保存错误级别\n     * @var integer\n     */\n    protected $severity;\n\n    /**\n     * 错误异常构造函数\n     * @param integer $severity 错误级别\n     * @param string  $message  错误详细信息\n     * @param string  $file     出错文件路径\n     * @param integer $line     出错行号\n     * @param array   $context  错误上下文，会包含错误触发处作用域内所有变量的数组\n     */\n    public function __construct($severity, $message, $file, $line, array $context = [])\n    {\n        $this->severity = $severity;\n        $this->message  = $message;\n        $this->file     = $file;\n        $this->line     = $line;\n        $this->code     = 0;\n\n        empty($context) || $this->setData('Error Context', $context);\n    }\n\n    /**\n     * 获取错误级别\n     * @return integer 错误级别\n     */\n    final public function getSeverity()\n    {\n        return $this->severity;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/exception/Handle.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\exception;\n\nuse Exception;\nuse think\\App;\nuse think\\Config;\nuse think\\console\\Output;\nuse think\\Lang;\nuse think\\Log;\nuse think\\Response;\n\nclass Handle\n{\n\n    protected $ignoreReport = [\n        '\\\\think\\\\exception\\\\HttpException',\n    ];\n\n    /**\n     * Report or log an exception.\n     *\n     * @param  \\Exception $exception\n     * @return void\n     */\n    public function report(Exception $exception)\n    {\n        if (!$this->isIgnoreReport($exception)) {\n            // 收集异常数据\n            if (App::$debug) {\n                $data = [\n                    'file'    => $exception->getFile(),\n                    'line'    => $exception->getLine(),\n                    'message' => $this->getMessage($exception),\n                    'code'    => $this->getCode($exception),\n                ];\n                $log = \"[{$data['code']}]{$data['message']}[{$data['file']}:{$data['line']}]\";\n            } else {\n                $data = [\n                    'code'    => $this->getCode($exception),\n                    'message' => $this->getMessage($exception),\n                ];\n                $log = \"[{$data['code']}]{$data['message']}\";\n            }\n\n            Log::record($log, 'error');\n        }\n    }\n\n    protected function isIgnoreReport(Exception $exception)\n    {\n        foreach ($this->ignoreReport as $class) {\n            if ($exception instanceof $class) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Render an exception into an HTTP response.\n     *\n     * @param  \\Exception $e\n     * @return Response\n     */\n    public function render(Exception $e)\n    {\n        if ($e instanceof HttpException) {\n            return $this->renderHttpException($e);\n        } else {\n            return $this->convertExceptionToResponse($e);\n        }\n    }\n\n    /**\n     * @param Output    $output\n     * @param Exception $e\n     */\n    public function renderForConsole(Output $output, Exception $e)\n    {\n        if (App::$debug) {\n            $output->setVerbosity(Output::VERBOSITY_DEBUG);\n        }\n        $output->renderException($e);\n    }\n\n    /**\n     * @param HttpException $e\n     * @return Response\n     */\n    protected function renderHttpException(HttpException $e)\n    {\n        $status   = $e->getStatusCode();\n        $template = Config::get('http_exception_template');\n        if (!App::$debug && !empty($template[$status])) {\n            return Response::create($template[$status], 'view', $status)->assign(['e' => $e]);\n        } else {\n            return $this->convertExceptionToResponse($e);\n        }\n    }\n\n    /**\n     * @param Exception $exception\n     * @return Response\n     */\n    protected function convertExceptionToResponse(Exception $exception)\n    {\n        // 收集异常数据\n        if (App::$debug) {\n            // 调试模式，获取详细的错误信息\n            $data = [\n                'name'    => get_class($exception),\n                'file'    => $exception->getFile(),\n                'line'    => $exception->getLine(),\n                'message' => $this->getMessage($exception),\n                'trace'   => $exception->getTrace(),\n                'code'    => $this->getCode($exception),\n                'source'  => $this->getSourceCode($exception),\n                'datas'   => $this->getExtendData($exception),\n                'tables'  => [\n                    'GET Data'              => $_GET,\n                    'POST Data'             => $_POST,\n                    'Files'                 => $_FILES,\n                    'Cookies'               => $_COOKIE,\n                    'Session'               => isset($_SESSION) ? $_SESSION : [],\n                    'Server/Request Data'   => $_SERVER,\n                    'Environment Variables' => $_ENV,\n                    'ThinkPHP Constants'    => $this->getConst(),\n                ],\n            ];\n        } else {\n            // 部署模式仅显示 Code 和 Message\n            $data = [\n                'code'    => $this->getCode($exception),\n                'message' => $this->getMessage($exception),\n            ];\n\n            if (!Config::get('show_error_msg')) {\n                // 不显示详细错误信息\n                $data['message'] = Config::get('error_message');\n            }\n        }\n\n        //保留一层\n        while (ob_get_level() > 1) {\n            ob_end_clean();\n        }\n\n        $data['echo'] = ob_get_clean();\n\n        ob_start();\n        extract($data);\n        include Config::get('exception_tmpl');\n        // 获取并清空缓存\n        $content  = ob_get_clean();\n        $response = new Response($content, 'html');\n\n        if ($exception instanceof HttpException) {\n            $statusCode = $exception->getStatusCode();\n            $response->header($exception->getHeaders());\n        }\n\n        if (!isset($statusCode)) {\n            $statusCode = 500;\n        }\n        $response->code($statusCode);\n        return $response;\n    }\n\n    /**\n     * 获取错误编码\n     * ErrorException则使用错误级别作为错误编码\n     * @param  \\Exception $exception\n     * @return integer                错误编码\n     */\n    protected function getCode(Exception $exception)\n    {\n        $code = $exception->getCode();\n        if (!$code && $exception instanceof ErrorException) {\n            $code = $exception->getSeverity();\n        }\n        return $code;\n    }\n\n    /**\n     * 获取错误信息\n     * ErrorException则使用错误级别作为错误编码\n     * @param  \\Exception $exception\n     * @return string                错误信息\n     */\n    protected function getMessage(Exception $exception)\n    {\n        $message = $exception->getMessage();\n        if (IS_CLI) {\n            return $message;\n        }\n\n        if (strpos($message, ':')) {\n            $name    = strstr($message, ':', true);\n            $message = Lang::has($name) ? Lang::get($name) . strstr($message, ':') : $message;\n        } elseif (strpos($message, ',')) {\n            $name    = strstr($message, ',', true);\n            $message = Lang::has($name) ? Lang::get($name) . ':' . substr(strstr($message, ','), 1) : $message;\n        } elseif (Lang::has($message)) {\n            $message = Lang::get($message);\n        }\n        return $message;\n    }\n\n    /**\n     * 获取出错文件内容\n     * 获取错误的前9行和后9行\n     * @param  \\Exception $exception\n     * @return array                 错误文件内容\n     */\n    protected function getSourceCode(Exception $exception)\n    {\n        // 读取前9行和后9行\n        $line  = $exception->getLine();\n        $first = ($line - 9 > 0) ? $line - 9 : 1;\n\n        try {\n            $contents = file($exception->getFile());\n            $source   = [\n                'first'  => $first,\n                'source' => array_slice($contents, $first - 1, 19),\n            ];\n        } catch (Exception $e) {\n            $source = [];\n        }\n        return $source;\n    }\n\n    /**\n     * 获取异常扩展信息\n     * 用于非调试模式html返回类型显示\n     * @param  \\Exception $exception\n     * @return array                 异常类定义的扩展数据\n     */\n    protected function getExtendData(Exception $exception)\n    {\n        $data = [];\n        if ($exception instanceof \\think\\Exception) {\n            $data = $exception->getData();\n        }\n        return $data;\n    }\n\n    /**\n     * 获取常量列表\n     * @return array 常量列表\n     */\n    private static function getConst()\n    {\n        return get_defined_constants(true)['user'];\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/exception/HttpException.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\exception;\n\nclass HttpException extends \\RuntimeException\n{\n    private $statusCode;\n    private $headers;\n\n    public function __construct($statusCode, $message = null, \\Exception $previous = null, array $headers = [], $code = 0)\n    {\n        $this->statusCode = $statusCode;\n        $this->headers    = $headers;\n\n        parent::__construct($message, $code, $previous);\n    }\n\n    public function getStatusCode()\n    {\n        return $this->statusCode;\n    }\n\n    public function getHeaders()\n    {\n        return $this->headers;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/exception/HttpResponseException.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\exception;\n\nuse think\\Response;\n\nclass HttpResponseException extends \\RuntimeException\n{\n    /**\n     * @var Response\n     */\n    protected $response;\n\n    public function __construct(Response $response)\n    {\n        $this->response = $response;\n    }\n\n    public function getResponse()\n    {\n        return $this->response;\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/exception/PDOException.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: 麦当苗儿 <zuojiazi@vip.qq.com> <http://zjzit.cn>\n// +----------------------------------------------------------------------\n\nnamespace think\\exception;\n\n/**\n * PDO异常处理类\n * 重新封装了系统的\\PDOException类\n */\nclass PDOException extends DbException\n{\n    /**\n     * PDOException constructor.\n     * @param \\PDOException $exception\n     * @param array         $config\n     * @param string        $sql\n     * @param int           $code\n     */\n    public function __construct(\\PDOException $exception, array $config, $sql, $code = 10501)\n    {\n        $error = $exception->errorInfo;\n\n        $this->setData('PDO Error Info', [\n            'SQLSTATE'             => $error[0],\n            'Driver Error Code'    => isset($error[1]) ? $error[1] : 0,\n            'Driver Error Message' => isset($error[2]) ? $error[2] : '',\n        ]);\n\n        parent::__construct($exception->getMessage(), $config, $sql, $code);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/exception/RouteNotFoundException.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\exception;\n\nclass RouteNotFoundException extends HttpException\n{\n\n    public function __construct()\n    {\n        parent::__construct(404);\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/exception/TemplateNotFoundException.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\exception;\n\nclass TemplateNotFoundException extends \\RuntimeException\n{\n    protected $template;\n\n    public function __construct($message, $template = '')\n    {\n        $this->message  = $message;\n        $this->template = $template;\n    }\n\n    /**\n     * 获取模板文件\n     * @access public\n     * @return string\n     */\n    public function getTemplate()\n    {\n        return $this->template;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/exception/ThrowableError.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\exception;\n\nclass ThrowableError extends \\ErrorException\n{\n    public function __construct(\\Throwable $e)\n    {\n\n        if ($e instanceof \\ParseError) {\n            $message  = 'Parse error: ' . $e->getMessage();\n            $severity = E_PARSE;\n        } elseif ($e instanceof \\TypeError) {\n            $message  = 'Type error: ' . $e->getMessage();\n            $severity = E_RECOVERABLE_ERROR;\n        } else {\n            $message  = 'Fatal error: ' . $e->getMessage();\n            $severity = E_ERROR;\n        }\n\n        parent::__construct(\n            $message,\n            $e->getCode(),\n            $severity,\n            $e->getFile(),\n            $e->getLine()\n        );\n\n        $this->setTrace($e->getTrace());\n    }\n\n    protected function setTrace($trace)\n    {\n        $traceReflector = new \\ReflectionProperty('Exception', 'trace');\n        $traceReflector->setAccessible(true);\n        $traceReflector->setValue($this, $trace);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/exception/ValidateException.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\exception;\n\nclass ValidateException extends \\RuntimeException\n{\n    protected $error;\n\n    public function __construct($error)\n    {\n        $this->error   = $error;\n        $this->message = is_array($error) ? implode(\"\\n\\r\", $error) : $error;\n    }\n\n    /**\n     * 获取验证错误信息\n     * @access public\n     * @return array|string\n     */\n    public function getError()\n    {\n        return $this->error;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/log/driver/File.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\log\\driver;\n\nuse think\\App;\n\n/**\n * 本地化调试输出到文件\n */\nclass File\n{\n    protected $config = [\n        'time_format' => ' c ',\n        'file_size'   => 2097152,\n        'path'        => LOG_PATH,\n        'apart_level' => [],\n    ];\n\n    protected $writed = [];\n\n    // 实例化并传入参数\n    public function __construct($config = [])\n    {\n        if (is_array($config)) {\n            $this->config = array_merge($this->config, $config);\n        }\n    }\n\n    /**\n     * 日志写入接口\n     * @access public\n     * @param array $log 日志信息\n     * @return bool\n     */\n    public function save(array $log = [])\n    {\n        $cli         = IS_CLI ? '_cli' : '';\n        $destination = $this->config['path'] . date('Ym') . DS . date('d') . $cli . '.log';\n\n        $path = dirname($destination);\n        !is_dir($path) && mkdir($path, 0755, true);\n\n        $info = '';\n        foreach ($log as $type => $val) {\n            $level = '';\n            foreach ($val as $msg) {\n                if (!is_string($msg)) {\n                    $msg = var_export($msg, true);\n                }\n                $level .= '[ ' . $type . ' ] ' . $msg . \"\\r\\n\";\n            }\n            if (in_array($type, $this->config['apart_level'])) {\n                // 独立记录的日志级别\n                $filename = $path . DS . date('d') . '_' . $type . $cli . '.log';\n                $this->write($level, $filename, true);\n            } else {\n                $info .= $level;\n            }\n        }\n        if ($info) {\n            return $this->write($info, $destination);\n        }\n        return true;\n    }\n\n    protected function write($message, $destination, $apart = false)\n    {\n        //检测日志文件大小，超过配置大小则备份日志文件重新生成\n        if (is_file($destination) && floor($this->config['file_size']) <= filesize($destination)) {\n            rename($destination, dirname($destination) . DS . $_SERVER['REQUEST_TIME'] . '-' . basename($destination));\n            $this->writed[$destination] = false;\n        }\n\n        if (empty($this->writed[$destination]) && !IS_CLI) {\n            if (App::$debug && !$apart) {\n                // 获取基本信息\n                if (isset($_SERVER['HTTP_HOST'])) {\n                    $current_uri = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];\n                } else {\n                    $current_uri = \"cmd:\" . implode(' ', $_SERVER['argv']);\n                }\n\n                $runtime    = round(microtime(true) - THINK_START_TIME, 10);\n                $reqs       = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞';\n                $time_str   = ' [运行时间：' . number_format($runtime, 6) . 's][吞吐率：' . $reqs . 'req/s]';\n                $memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2);\n                $memory_str = ' [内存消耗：' . $memory_use . 'kb]';\n                $file_load  = ' [文件加载：' . count(get_included_files()) . ']';\n\n                $message = '[ info ] ' . $current_uri . $time_str . $memory_str . $file_load . \"\\r\\n\" . $message;\n            }\n            $now     = date($this->config['time_format']);\n            $server  = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : '0.0.0.0';\n            $remote  = isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : '0.0.0.0';\n            $method  = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'CLI';\n            $uri     = isset($_SERVER['REQUEST_URI']) ? $_SERVER['REQUEST_URI'] : '';\n            $message = \"---------------------------------------------------------------\\r\\n[{$now}] {$server} {$remote} {$method} {$uri}\\r\\n\" . $message;\n\n            $this->writed[$destination] = true;\n        }\n\n        if (IS_CLI) {\n            $now     = date($this->config['time_format']);\n            $message = \"[{$now}]\" . $message;\n        }\n\n        return error_log($message, 3, $destination);\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/log/driver/Socket.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: luofei614 <weibo.com/luofei614>\n// +----------------------------------------------------------------------\n\nnamespace think\\log\\driver;\n\nuse think\\App;\n\n/**\n * github: https://github.com/luofei614/SocketLog\n * @author luofei614<weibo.com/luofei614>\n */\nclass Socket\n{\n    public $port = 1116; //SocketLog 服务的http的端口号\n\n    protected $config = [\n        // socket服务器地址\n        'host'                => 'localhost',\n        // 是否显示加载的文件列表\n        'show_included_files' => false,\n        // 日志强制记录到配置的client_id\n        'force_client_ids'    => [],\n        // 限制允许读取日志的client_id\n        'allow_client_ids'    => [],\n    ];\n\n    protected $css = [\n        'sql'      => 'color:#009bb4;',\n        'sql_warn' => 'color:#009bb4;font-size:14px;',\n        'error'    => 'color:#f4006b;font-size:14px;',\n        'page'     => 'color:#40e2ff;background:#171717;',\n        'big'      => 'font-size:20px;color:red;',\n    ];\n\n    protected $allowForceClientIds = []; //配置强制推送且被授权的client_id\n\n    /**\n     * 构造函数\n     * @param array $config 缓存参数\n     * @access public\n     */\n    public function __construct(array $config = [])\n    {\n        if (!empty($config)) {\n            $this->config = array_merge($this->config, $config);\n        }\n    }\n\n    /**\n     * 调试输出接口\n     * @access public\n     * @param array     $log 日志信息\n     * @return bool\n     */\n    public function save(array $log = [])\n    {\n        if (!$this->check()) {\n            return false;\n        }\n        $trace = [];\n        if (App::$debug) {\n            $runtime    = round(microtime(true) - THINK_START_TIME, 10);\n            $reqs       = $runtime > 0 ? number_format(1 / $runtime, 2) : '∞';\n            $time_str   = ' [运行时间：' . number_format($runtime, 6) . 's][吞吐率：' . $reqs . 'req/s]';\n            $memory_use = number_format((memory_get_usage() - THINK_START_MEM) / 1024, 2);\n            $memory_str = ' [内存消耗：' . $memory_use . 'kb]';\n            $file_load  = ' [文件加载：' . count(get_included_files()) . ']';\n\n            if (isset($_SERVER['HTTP_HOST'])) {\n                $current_uri = $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];\n            } else {\n                $current_uri = 'cmd:' . implode(' ', $_SERVER['argv']);\n            }\n            // 基本信息\n            $trace[] = [\n                'type' => 'group',\n                'msg'  => $current_uri . $time_str . $memory_str . $file_load,\n                'css'  => $this->css['page'],\n            ];\n        }\n\n        foreach ($log as $type => $val) {\n            $trace[] = [\n                'type' => 'groupCollapsed',\n                'msg'  => '[ ' . $type . ' ]',\n                'css'  => isset($this->css[$type]) ? $this->css[$type] : '',\n            ];\n            foreach ($val as $msg) {\n                if (!is_string($msg)) {\n                    $msg = var_export($msg, true);\n                }\n                $trace[] = [\n                    'type' => 'log',\n                    'msg'  => $msg,\n                    'css'  => '',\n                ];\n            }\n            $trace[] = [\n                'type' => 'groupEnd',\n                'msg'  => '',\n                'css'  => '',\n            ];\n        }\n\n        if ($this->config['show_included_files']) {\n            $trace[] = [\n                'type' => 'groupCollapsed',\n                'msg'  => '[ file ]',\n                'css'  => '',\n            ];\n            $trace[] = [\n                'type' => 'log',\n                'msg'  => implode(\"\\n\", get_included_files()),\n                'css'  => '',\n            ];\n            $trace[] = [\n                'type' => 'groupEnd',\n                'msg'  => '',\n                'css'  => '',\n            ];\n        }\n\n        $trace[] = [\n            'type' => 'groupEnd',\n            'msg'  => '',\n            'css'  => '',\n        ];\n\n        $tabid = $this->getClientArg('tabid');\n        if (!$client_id = $this->getClientArg('client_id')) {\n            $client_id = '';\n        }\n\n        if (!empty($this->allowForceClientIds)) {\n            //强制推送到多个client_id\n            foreach ($this->allowForceClientIds as $force_client_id) {\n                $client_id = $force_client_id;\n                $this->sendToClient($tabid, $client_id, $trace, $force_client_id);\n            }\n        } else {\n            $this->sendToClient($tabid, $client_id, $trace, '');\n        }\n        return true;\n    }\n\n    /**\n     * 发送给指定客户端\n     * @author Zjmainstay\n     * @param $tabid\n     * @param $client_id\n     * @param $logs\n     * @param $force_client_id\n     */\n    protected function sendToClient($tabid, $client_id, $logs, $force_client_id)\n    {\n        $logs = [\n            'tabid'           => $tabid,\n            'client_id'       => $client_id,\n            'logs'            => $logs,\n            'force_client_id' => $force_client_id,\n        ];\n        $msg     = @json_encode($logs);\n        $address = '/' . $client_id; //将client_id作为地址， server端通过地址判断将日志发布给谁\n        $this->send($this->config['host'], $msg, $address);\n    }\n\n    protected function check()\n    {\n        $tabid = $this->getClientArg('tabid');\n        //是否记录日志的检查\n        if (!$tabid && !$this->config['force_client_ids']) {\n            return false;\n        }\n        //用户认证\n        $allow_client_ids = $this->config['allow_client_ids'];\n        if (!empty($allow_client_ids)) {\n            //通过数组交集得出授权强制推送的client_id\n            $this->allowForceClientIds = array_intersect($allow_client_ids, $this->config['force_client_ids']);\n            if (!$tabid && count($this->allowForceClientIds)) {\n                return true;\n            }\n\n            $client_id = $this->getClientArg('client_id');\n            if (!in_array($client_id, $allow_client_ids)) {\n                return false;\n            }\n        } else {\n            $this->allowForceClientIds = $this->config['force_client_ids'];\n        }\n        return true;\n    }\n\n    protected function getClientArg($name)\n    {\n        static $args = [];\n\n        $key = 'HTTP_USER_AGENT';\n\n        if (isset($_SERVER['HTTP_SOCKETLOG'])) {\n            $key = 'HTTP_SOCKETLOG';\n        }\n\n        if (!isset($_SERVER[$key])) {\n            return;\n        }\n        if (empty($args)) {\n            if (!preg_match('/SocketLog\\((.*?)\\)/', $_SERVER[$key], $match)) {\n                $args = ['tabid' => null];\n                return;\n            }\n            parse_str($match[1], $args);\n        }\n        if (isset($args[$name])) {\n            return $args[$name];\n        }\n        return;\n    }\n\n    /**\n     * @param string $host - $host of socket server\n     * @param string $message - 发送的消息\n     * @param string $address - 地址\n     * @return bool\n     */\n    protected function send($host, $message = '', $address = '/')\n    {\n        $url = 'http://' . $host . ':' . $this->port . $address;\n        $ch  = curl_init();\n        curl_setopt($ch, CURLOPT_URL, $url);\n        curl_setopt($ch, CURLOPT_POST, true);\n        curl_setopt($ch, CURLOPT_POSTFIELDS, $message);\n        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);\n        curl_setopt($ch, CURLOPT_TIMEOUT, 10);\n        $headers = [\n            \"Content-Type: application/json;charset=UTF-8\",\n        ];\n        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); //设置header\n        return curl_exec($ch);\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/log/driver/Test.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\log\\driver;\n\n/**\n * 模拟测试输出\n */\nclass Test\n{\n    /**\n     * 日志写入接口\n     * @access public\n     * @param array $log 日志信息\n     * @return bool\n     */\n    public function save(array $log = [])\n    {\n        return true;\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/model/Collection.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: zhangyajun <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\model;\n\nuse think\\Collection as BaseCollection;\nuse think\\Model;\n\nclass Collection extends BaseCollection\n{\n    /**\n     * 延迟预载入关联查询\n     * @access public\n     * @param mixed $relation 关联\n     * @return $this\n     */\n    public function load($relation)\n    {\n        $item = current($this->items);\n        $item->eagerlyResultSet($this->items, $relation);\n        return $this;\n    }\n\n    /**\n     * 设置需要隐藏的输出属性\n     * @access public\n     * @param array $hidden   属性列表\n     * @param bool  $override 是否覆盖\n     * @return $this\n     */\n    public function hidden($hidden = [], $override = false)\n    {\n        $this->each(function ($model) use ($hidden, $override) {\n            /** @var Model $model */\n            $model->hidden($hidden, $override);\n        });\n        return $this;\n    }\n\n    /**\n     * 设置需要输出的属性\n     * @param array $visible\n     * @param bool  $override 是否覆盖\n     * @return $this\n     */\n    public function visible($visible = [], $override = false)\n    {\n        $this->each(function ($model) use ($visible, $override) {\n            /** @var Model $model */\n            $model->visible($visible, $override);\n        });\n        return $this;\n    }\n\n    /**\n     * 设置需要追加的输出属性\n     * @access public\n     * @param array $append   属性列表\n     * @param bool  $override 是否覆盖\n     * @return $this\n     */\n    public function append($append = [], $override = false)\n    {\n        $this->each(function ($model) use ($append, $override) {\n            /** @var Model $model */\n            $model->append($append, $override);\n        });\n        return $this;\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/model/Merge.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\model;\n\nuse think\\Db;\nuse think\\db\\Query;\nuse think\\Model;\n\nclass Merge extends Model\n{\n\n    protected $relationModel = []; // HAS ONE 关联的模型列表\n    protected $fk            = ''; //  外键名 默认为主表名_id\n    protected $mapFields     = []; //  需要处理的模型映射字段，避免混淆 array( id => 'user.id'  )\n\n    /**\n     * 构造函数\n     * @access public\n     * @param array|object $data 数据\n     */\n    public function __construct($data = [])\n    {\n        parent::__construct($data);\n\n        // 设置默认外键名 仅支持单一外键\n        if (empty($this->fk)) {\n            $this->fk = strtolower($this->name) . '_id';\n        }\n    }\n\n    /**\n     * 查找单条记录\n     * @access public\n     * @param mixed        $data  主键值或者查询条件（闭包）\n     * @param string|array $with  关联预查询\n     * @param bool         $cache 是否缓存\n     * @return \\think\\Model\n     */\n    public static function get($data = null, $with = [], $cache = false)\n    {\n        $query = self::parseQuery($data, $with, $cache);\n        $query = self::attachQuery($query);\n        return $query->find($data);\n    }\n\n    /**\n     * 附加查询表达式\n     * @access protected\n     * @param \\think\\db\\Query $query 查询对象\n     * @return \\think\\db\\Query\n     */\n    protected static function attachQuery($query)\n    {\n        $class  = new static();\n        $master = $class->name;\n        $fields = self::getModelField($query, $master, '', $class->mapFields, $class->field);\n        $query->alias($master)->field($fields);\n\n        foreach ($class->relationModel as $key => $model) {\n            $name  = is_int($key) ? $model : $key;\n            $table = is_int($key) ? $query->getTable($name) : $model;\n            $query->join($table . ' ' . $name, $name . '.' . $class->fk . '=' . $master . '.' . $class->getPk());\n            $fields = self::getModelField($query, $name, $table, $class->mapFields, $class->field);\n            $query->field($fields);\n        }\n        return $query;\n    }\n\n    /**\n     * 获取关联模型的字段 并解决混淆\n     * @access protected\n     * @param \\think\\db\\Query $query  查询对象\n     * @param string          $name   模型名称\n     * @param string          $table  关联表名称\n     * @param array           $map    字段映射\n     * @param array           $fields 查询字段\n     * @return array\n     */\n    protected static function getModelField($query, $name, $table = '', $map = [], $fields = [])\n    {\n        // 获取模型的字段信息\n        $fields = $fields ?: $query->getTableInfo($table, 'fields');\n        $array  = [];\n        foreach ($fields as $field) {\n            if ($key = array_search($name . '.' . $field, $map)) {\n                // 需要处理映射字段\n                $array[] = $name . '.' . $field . ' AS ' . $key;\n            } else {\n                $array[] = $field;\n            }\n        }\n        return $array;\n    }\n\n    /**\n     * 查找所有记录\n     * @access public\n     * @param mixed        $data 主键列表或者查询条件（闭包）\n     * @param array|string $with 关联预查询\n     * @param bool         $cache\n     * @return array|false|string\n     */\n    public static function all($data = null, $with = [], $cache = false)\n    {\n        $query = self::parseQuery($data, $with, $cache);\n        $query = self::attachQuery($query);\n        return $query->select($data);\n    }\n\n    /**\n     * 处理写入的模型数据\n     * @access public\n     * @param string $model  模型名称\n     * @param array  $data   数据\n     * @return array\n     */\n    protected function parseData($model, $data)\n    {\n        $item = [];\n        foreach ($data as $key => $val) {\n            if ($this->fk != $key && array_key_exists($key, $this->mapFields)) {\n                list($name, $key) = explode('.', $this->mapFields[$key]);\n                if ($model == $name) {\n                    $item[$key] = $val;\n                }\n            } else {\n                $item[$key] = $val;\n            }\n        }\n        return $item;\n    }\n\n    /**\n     * 保存模型数据 以及关联数据\n     * @access public\n     * @param mixed  $data     数据\n     * @param array  $where    更新条件\n     * @param string $sequence 自增序列名\n     * @return false|int\n     * @throws \\Exception\n     */\n    public function save($data = [], $where = [], $sequence = null)\n    {\n        if (!empty($data)) {\n            // 数据自动验证\n            if (!$this->validateData($data)) {\n                return false;\n            }\n            // 数据对象赋值\n            foreach ($data as $key => $value) {\n                $this->setAttr($key, $value, $data);\n            }\n            if (!empty($where)) {\n                $this->isUpdate = true;\n            }\n        }\n\n        // 数据自动完成\n        $this->autoCompleteData($this->auto);\n\n        // 自动写入更新时间\n        if ($this->autoWriteTimestamp && $this->updateTime && !isset($this->data[$this->updateTime])) {\n            $this->setAttr($this->updateTime, null);\n        }\n\n        // 事件回调\n        if (false === $this->trigger('before_write', $this)) {\n            return false;\n        }\n\n        $db = $this->db();\n        $db->startTrans();\n        $pk = $this->getPk();\n        try {\n            if ($this->isUpdate) {\n                // 自动写入\n                $this->autoCompleteData($this->update);\n\n                if (false === $this->trigger('before_update', $this)) {\n                    return false;\n                }\n\n                if (empty($where) && !empty($this->updateWhere)) {\n                    $where = $this->updateWhere;\n                }\n\n                // 获取有更新的数据\n                $data = $this->getChangedData();\n                // 保留主键数据\n                foreach ($this->data as $key => $val) {\n                    if ($this->isPk($key)) {\n                        $data[$key] = $val;\n                    }\n                }\n                // 处理模型数据\n                $data = $this->parseData($this->name, $data);\n                if (is_string($pk) && isset($data[$pk])) {\n                    if (!isset($where[$pk])) {\n                        unset($where);\n                        $where[$pk] = $data[$pk];\n                    }\n                    unset($data[$pk]);\n                }\n                // 写入主表数据\n                $result = $db->strict(false)->where($where)->update($data);\n\n                // 写入附表数据\n                foreach ($this->relationModel as $key => $model) {\n                    $name  = is_int($key) ? $model : $key;\n                    $table = is_int($key) ? $db->getTable($model) : $model;\n                    // 处理关联模型数据\n                    $data = $this->parseData($name, $data);\n                    if (Db::table($table)->strict(false)->where($this->fk, $this->data[$this->getPk()])->update($data)) {\n                        $result = 1;\n                    }\n                }\n\n                // 新增回调\n                $this->trigger('after_update', $this);\n            } else {\n                // 自动写入\n                $this->autoCompleteData($this->insert);\n\n                // 自动写入创建时间\n                if ($this->autoWriteTimestamp && $this->createTime && !isset($this->data[$this->createTime])) {\n                    $this->setAttr($this->createTime, null);\n                }\n\n                if (false === $this->trigger('before_insert', $this)) {\n                    return false;\n                }\n\n                // 处理模型数据\n                $data = $this->parseData($this->name, $this->data);\n                // 写入主表数据\n                $result = $db->name($this->name)->strict(false)->insert($data);\n                if ($result) {\n                    $insertId = $db->getLastInsID($sequence);\n                    // 写入外键数据\n                    if ($insertId) {\n                        if (is_string($pk)) {\n                            $this->data[$pk] = $insertId;\n                        }\n                        $this->data[$this->fk] = $insertId;\n                    }\n\n                    // 写入附表数据\n                    $source = $this->data;\n                    if ($insertId && is_string($pk) && isset($source[$pk]) && $this->fk != $pk) {\n                        unset($source[$pk]);\n                    }\n                    foreach ($this->relationModel as $key => $model) {\n                        $name  = is_int($key) ? $model : $key;\n                        $table = is_int($key) ? $db->getTable($model) : $model;\n                        // 处理关联模型数据\n                        $data = $this->parseData($name, $source);\n                        Db::table($table)->strict(false)->insert($data);\n                    }\n                }\n                // 标记为更新\n                $this->isUpdate = true;\n                // 新增回调\n                $this->trigger('after_insert', $this);\n            }\n            $db->commit();\n            // 写入回调\n            $this->trigger('after_write', $this);\n\n            $this->origin = $this->data;\n            return $result;\n        } catch (\\Exception $e) {\n            $db->rollback();\n            throw $e;\n        }\n    }\n\n    /**\n     * 删除当前的记录 并删除关联数据\n     * @access public\n     * @return int\n     * @throws \\Exception\n     */\n    public function delete()\n    {\n        if (false === $this->trigger('before_delete', $this)) {\n            return false;\n        }\n\n        $db = $this->db();\n        $db->startTrans();\n        try {\n            $result = $db->delete($this->data);\n            if ($result) {\n                // 获取主键数据\n                $pk = $this->data[$this->getPk()];\n\n                // 删除关联数据\n                foreach ($this->relationModel as $key => $model) {\n                    $table = is_int($key) ? $db->getTable($model) : $model;\n                    $query = new Query;\n                    $query->table($table)->where($this->fk, $pk)->delete();\n                }\n            }\n            $this->trigger('after_delete', $this);\n            $db->commit();\n            return $result;\n        } catch (\\Exception $e) {\n            $db->rollback();\n            throw $e;\n        }\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/model/Pivot.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\model;\n\nuse think\\Model;\n\nclass Pivot extends Model\n{\n\n    /** @var Model */\n    public $parent;\n\n    protected $autoWriteTimestamp = false;\n\n    /**\n     * 架构函数\n     * @access public\n     * @param Model         $parent 上级模型\n     * @param array|object  $data 数据\n     * @param string        $table 中间数据表名\n     */\n    public function __construct(Model $parent, $data = [], $table = '')\n    {\n        $this->parent = $parent;\n\n        if (is_null($this->name)) {\n            $this->name = $table;\n        }\n\n        parent::__construct($data);\n\n        $this->class = $this->name;\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/model/Relation.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\model;\n\nuse think\\db\\Query;\nuse think\\Exception;\nuse think\\Model;\n\n/**\n * Class Relation\n * @package think\\model\n *\n * @mixin Query\n */\nabstract class Relation\n{\n    // 父模型对象\n    protected $parent;\n    /** @var  Model 当前关联的模型类 */\n    protected $model;\n    /** @var Query 关联模型查询对象 */\n    protected $query;\n    // 关联表外键\n    protected $foreignKey;\n    // 关联表主键\n    protected $localKey;\n    // 基础查询\n    protected $baseQuery;\n\n    /**\n     * 获取关联的所属模型\n     * @access public\n     * @return Model\n     */\n    public function getParent()\n    {\n        return $this->parent;\n    }\n\n    /**\n     * 获取当前的关联模型类\n     * @access public\n     * @return string\n     */\n    public function getModel()\n    {\n        return $this->model;\n    }\n\n    /**\n     * 获取关联的查询对象\n     * @access public\n     * @return Query\n     */\n    public function getQuery()\n    {\n        return $this->query;\n    }\n\n    /**\n     * 封装关联数据集\n     * @access public\n     * @param array $resultSet 数据集\n     * @return mixed\n     */\n    protected function resultSetBuild($resultSet)\n    {\n        return (new $this->model)->toCollection($resultSet);\n    }\n\n    /**\n     * 执行基础查询（仅执行一次）\n     * @access protected\n     * @return void\n     */\n    abstract protected function baseQuery();\n\n    public function __call($method, $args)\n    {\n        if ($this->query) {\n            // 执行基础查询\n            $this->baseQuery();\n\n            $result = call_user_func_array([$this->query, $method], $args);\n            if ($result instanceof Query) {\n                return $this;\n            } else {\n                $this->baseQuery = false;\n                return $result;\n            }\n        } else {\n            throw new Exception('method not exists:' . __CLASS__ . '->' . $method);\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/model/relation/BelongsTo.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\model\\relation;\n\nuse think\\Loader;\nuse think\\Model;\n\nclass BelongsTo extends OneToOne\n{\n    /**\n     * 构造函数\n     * @access public\n     * @param Model  $parent 上级模型对象\n     * @param string $model 模型名\n     * @param string $foreignKey 关联外键\n     * @param string $localKey 关联主键\n     * @param string $joinType JOIN类型\n     * @param string $relation  关联名\n     */\n    public function __construct(Model $parent, $model, $foreignKey, $localKey, $joinType = 'INNER', $relation = null)\n    {\n        $this->parent     = $parent;\n        $this->model      = $model;\n        $this->foreignKey = $foreignKey;\n        $this->localKey   = $localKey;\n        $this->joinType   = $joinType;\n        $this->query      = (new $model)->db();\n        $this->relation   = $relation;\n    }\n\n    /**\n     * 延迟获取关联数据\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包查询条件\n     * @access public\n     * @return array|false|\\PDOStatement|string|Model\n     */\n    public function getRelation($subRelation = '', $closure = null)\n    {\n        $foreignKey = $this->foreignKey;\n        if ($closure) {\n            call_user_func_array($closure, [ & $this->query]);\n        }\n        $relationModel = $this->query\n            ->where($this->localKey, $this->parent->$foreignKey)\n            ->relation($subRelation)\n            ->find();\n\n        if ($relationModel) {\n            $relationModel->setParent(clone $this->parent);\n        }\n\n        return $relationModel;\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param string  $operator 比较操作符\n     * @param integer $count    个数\n     * @param string  $id       关联表的统计字段\n     * @param string  $joinType JOIN类型\n     * @return Query\n     */\n    public function has($operator = '>=', $count = 1, $id = '*')\n    {\n        return $this->parent;\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param mixed $where 查询条件（数组或者闭包）\n     * @return Query\n     */\n    public function hasWhere($where = [])\n    {\n        $table    = $this->query->getTable();\n        $model    = basename(str_replace('\\\\', '/', get_class($this->parent)));\n        $relation = basename(str_replace('\\\\', '/', $this->model));\n        if (is_array($where)) {\n            foreach ($where as $key => $val) {\n                if (false === strpos($key, '.')) {\n                    $where[$relation . '.' . $key] = $val;\n                    unset($where[$key]);\n                }\n            }\n        }\n        return $this->parent->db()->alias($model)\n            ->field($model . '.*')\n            ->join($table . ' ' . $relation, $model . '.' . $this->foreignKey . '=' . $relation . '.' . $this->localKey, $this->joinType)\n            ->where($where);\n    }\n\n    /**\n     * 预载入关联查询（数据集）\n     * @access public\n     * @param array     $resultSet 数据集\n     * @param string    $relation 当前关联名\n     * @param string    $subRelation 子关联名\n     * @param \\Closure  $closure 闭包\n     * @return void\n     */\n    protected function eagerlySet(&$resultSet, $relation, $subRelation, $closure)\n    {\n        $localKey   = $this->localKey;\n        $foreignKey = $this->foreignKey;\n\n        $range = [];\n        foreach ($resultSet as $result) {\n            // 获取关联外键列表\n            if (isset($result->$foreignKey)) {\n                $range[] = $result->$foreignKey;\n            }\n        }\n\n        if (!empty($range)) {\n            $data = $this->eagerlyWhere($this, [\n                $localKey => [\n                    'in',\n                    $range,\n                ],\n            ], $localKey, $relation, $subRelation, $closure);\n            // 关联属性名\n            $attr = Loader::parseName($relation);\n            // 关联数据封装\n            foreach ($resultSet as $result) {\n                // 关联模型\n                if (!isset($data[$result->$foreignKey])) {\n                    $relationModel = null;\n                } else {\n                    $relationModel = $data[$result->$foreignKey];\n                    $relationModel->setParent(clone $result);\n                    $relationModel->isUpdate(true);\n                }\n\n                if ($relationModel && !empty($this->bindAttr)) {\n                    // 绑定关联属性\n                    $this->bindAttr($relationModel, $result, $this->bindAttr);\n                }\n                // 设置关联属性\n                $result->setRelation($attr, $relationModel);\n            }\n        }\n    }\n\n    /**\n     * 预载入关联查询（数据）\n     * @access public\n     * @param Model     $result 数据对象\n     * @param string    $relation 当前关联名\n     * @param string    $subRelation 子关联名\n     * @param \\Closure  $closure 闭包\n     * @return void\n     */\n    protected function eagerlyOne(&$result, $relation, $subRelation, $closure)\n    {\n        $localKey   = $this->localKey;\n        $foreignKey = $this->foreignKey;\n        $data       = $this->eagerlyWhere($this, [$localKey => $result->$foreignKey], $localKey, $relation, $subRelation, $closure);\n        // 关联模型\n        if (!isset($data[$result->$foreignKey])) {\n            $relationModel = null;\n        } else {\n            $relationModel = $data[$result->$foreignKey];\n            $relationModel->setParent(clone $result);\n            $relationModel->isUpdate(true);\n        }\n        if ($relationModel && !empty($this->bindAttr)) {\n            // 绑定关联属性\n            $this->bindAttr($relationModel, $result, $this->bindAttr);\n        }\n        // 设置关联属性\n        $result->setRelation(Loader::parseName($relation), $relationModel);\n    }\n\n    /**\n     * 添加关联数据\n     * @access public\n     * @param Model $model       关联模型对象\n     * @return Model\n     */\n    public function associate($model)\n    {\n        $foreignKey = $this->foreignKey;\n        $pk         = $model->getPk();\n\n        $this->parent->setAttr($foreignKey, $model->$pk);\n        $this->parent->save();\n\n        return $this->parent->setRelation($this->relation, $model);\n    }\n\n    /**\n     * 注销关联数据\n     * @access public\n     * @return Model\n     */\n    public function dissociate()\n    {\n        $foreignKey = $this->foreignKey;\n\n        $this->parent->setAttr($foreignKey, null);\n        $this->parent->save();\n\n        return $this->parent->setRelation($this->relation, null);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/model/relation/BelongsToMany.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\model\\relation;\n\nuse think\\Collection;\nuse think\\db\\Query;\nuse think\\Exception;\nuse think\\Loader;\nuse think\\Model;\nuse think\\model\\Pivot;\nuse think\\model\\Relation;\nuse think\\Paginator;\n\nclass BelongsToMany extends Relation\n{\n    // 中间表表名\n    protected $middle;\n    // 中间表模型名称\n    protected $pivotName;\n    // 中间表模型对象\n    protected $pivot;\n\n    /**\n     * 构造函数\n     * @access public\n     * @param Model  $parent     上级模型对象\n     * @param string $model      模型名\n     * @param string $table      中间表名\n     * @param string $foreignKey 关联模型外键\n     * @param string $localKey   当前模型关联键\n     */\n    public function __construct(Model $parent, $model, $table, $foreignKey, $localKey)\n    {\n        $this->parent     = $parent;\n        $this->model      = $model;\n        $this->foreignKey = $foreignKey;\n        $this->localKey   = $localKey;\n        if (false !== strpos($table, '\\\\')) {\n            $this->pivotName = $table;\n            $this->middle    = basename(str_replace('\\\\', '/', $table));\n        } else {\n            $this->middle = $table;\n        }\n        $this->query = (new $model)->db();\n        $this->pivot = $this->newPivot();\n    }\n\n    /**\n     * 设置中间表模型\n     * @param $pivot\n     * @return $this\n     */\n    public function pivot($pivot)\n    {\n        $this->pivotName = $pivot;\n        return $this;\n    }\n\n    /**\n     * 实例化中间表模型\n     * @param $data\n     * @return mixed\n     */\n    protected function newPivot($data = [])\n    {\n        $pivot = $this->pivotName ?: '\\\\think\\\\model\\\\Pivot';\n        return new $pivot($this->parent, $data, $this->middle);\n    }\n\n    /**\n     * 合成中间表模型\n     * @param array|Collection|Paginator $models\n     */\n    protected function hydratePivot($models)\n    {\n        foreach ($models as $model) {\n            $pivot = [];\n            foreach ($model->getData() as $key => $val) {\n                if (strpos($key, '__')) {\n                    list($name, $attr) = explode('__', $key, 2);\n                    if ('pivot' == $name) {\n                        $pivot[$attr] = $val;\n                        unset($model->$key);\n                    }\n                }\n            }\n            $model->pivot = $this->newPivot($pivot);\n        }\n    }\n\n    /**\n     * 创建关联查询Query对象\n     * @return Query\n     */\n    protected function buildQuery()\n    {\n        $foreignKey = $this->foreignKey;\n        $localKey   = $this->localKey;\n        $middle     = $this->middle;\n        // 关联查询\n        $pk                              = $this->parent->getPk();\n        $condition['pivot.' . $localKey] = $this->parent->$pk;\n        return $this->belongsToManyQuery($foreignKey, $localKey, $condition);\n    }\n\n    /**\n     * 延迟获取关联数据\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包查询条件\n     * @return false|\\PDOStatement|string|\\think\\Collection\n     */\n    public function getRelation($subRelation = '', $closure = null)\n    {\n        if ($closure) {\n            call_user_func_array($closure, [ & $this->query]);\n        }\n        $result = $this->buildQuery()->relation($subRelation)->select();\n        $this->hydratePivot($result);\n        return $result;\n    }\n\n    /**\n     * 重载select方法\n     * @param null $data\n     * @return false|\\PDOStatement|string|Collection\n     */\n    public function select($data = null)\n    {\n        $result = $this->buildQuery()->select($data);\n        $this->hydratePivot($result);\n        return $result;\n    }\n\n    /**\n     * 重载paginate方法\n     * @param null  $listRows\n     * @param bool  $simple\n     * @param array $config\n     * @return Paginator\n     */\n    public function paginate($listRows = null, $simple = false, $config = [])\n    {\n        $result = $this->buildQuery()->paginate($listRows, $simple, $config);\n        $this->hydratePivot($result);\n        return $result;\n    }\n\n    /**\n     * 重载find方法\n     * @param null $data\n     * @return array|false|\\PDOStatement|string|Model\n     */\n    public function find($data = null)\n    {\n        $result = $this->buildQuery()->find($data);\n        $this->hydratePivot([$result]);\n        return $result;\n    }\n\n    /**\n     * 查找多条记录 如果不存在则抛出异常\n     * @access public\n     * @param array|string|Query|\\Closure $data\n     * @return array|\\PDOStatement|string|Model\n     */\n    public function selectOrFail($data = null)\n    {\n        return $this->failException(true)->select($data);\n    }\n\n    /**\n     * 查找单条记录 如果不存在则抛出异常\n     * @access public\n     * @param array|string|Query|\\Closure $data\n     * @return array|\\PDOStatement|string|Model\n     */\n    public function findOrFail($data = null)\n    {\n        return $this->failException(true)->find($data);\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param string  $operator 比较操作符\n     * @param integer $count    个数\n     * @param string  $id       关联表的统计字段\n     * @param string  $joinType JOIN类型\n     * @return Query\n     */\n    public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER')\n    {\n        return $this->parent;\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param mixed $where 查询条件（数组或者闭包）\n     * @return Query\n     * @throws Exception\n     */\n    public function hasWhere($where = [])\n    {\n        throw new Exception('relation not support: hasWhere');\n    }\n\n    /**\n     * 设置中间表的查询条件\n     * @param      $field\n     * @param null $op\n     * @param null $condition\n     * @return $this\n     */\n    public function wherePivot($field, $op = null, $condition = null)\n    {\n        $field = 'pivot.' . $field;\n        $this->query->where($field, $op, $condition);\n        return $this;\n    }\n\n    /**\n     * 预载入关联查询（数据集）\n     * @access public\n     * @param array    $resultSet   数据集\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     */\n    public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure)\n    {\n        $localKey   = $this->localKey;\n        $foreignKey = $this->foreignKey;\n\n        $pk    = $resultSet[0]->getPk();\n        $range = [];\n        foreach ($resultSet as $result) {\n            // 获取关联外键列表\n            if (isset($result->$pk)) {\n                $range[] = $result->$pk;\n            }\n        }\n\n        if (!empty($range)) {\n            // 查询关联数据\n            $data = $this->eagerlyManyToMany([\n                'pivot.' . $localKey => [\n                    'in',\n                    $range,\n                ],\n            ], $relation, $subRelation);\n            // 关联属性名\n            $attr = Loader::parseName($relation);\n            // 关联数据封装\n            foreach ($resultSet as $result) {\n                if (!isset($data[$result->$pk])) {\n                    $data[$result->$pk] = [];\n                }\n\n                $result->setRelation($attr, $this->resultSetBuild($data[$result->$pk]));\n            }\n        }\n    }\n\n    /**\n     * 预载入关联查询（单个数据）\n     * @access public\n     * @param Model    $result      数据对象\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     */\n    public function eagerlyResult(&$result, $relation, $subRelation, $closure)\n    {\n        $pk = $result->getPk();\n        if (isset($result->$pk)) {\n            $pk = $result->$pk;\n            // 查询管理数据\n            $data = $this->eagerlyManyToMany(['pivot.' . $this->localKey => $pk], $relation, $subRelation);\n\n            // 关联数据封装\n            if (!isset($data[$pk])) {\n                $data[$pk] = [];\n            }\n            $result->setRelation(Loader::parseName($relation), $this->resultSetBuild($data[$pk]));\n        }\n    }\n\n    /**\n     * 关联统计\n     * @access public\n     * @param Model    $result  数据对象\n     * @param \\Closure $closure 闭包\n     * @return integer\n     */\n    public function relationCount($result, $closure)\n    {\n        $pk    = $result->getPk();\n        $count = 0;\n        if (isset($result->$pk)) {\n            $pk    = $result->$pk;\n            $count = $this->belongsToManyQuery($this->foreignKey, $this->localKey, ['pivot.' . $this->localKey => $pk])->count();\n        }\n        return $count;\n    }\n\n    /**\n     * 获取关联统计子查询\n     * @access public\n     * @param \\Closure $closure 闭包\n     * @return string\n     */\n    public function getRelationCountQuery($closure)\n    {\n        return $this->belongsToManyQuery($this->foreignKey, $this->localKey, [\n            'pivot.' . $this->localKey => [\n                'exp',\n                '=' . $this->parent->getTable() . '.' . $this->parent->getPk(),\n            ],\n        ])->fetchSql()->count();\n    }\n\n    /**\n     * 多对多 关联模型预查询\n     * @access public\n     * @param array  $where       关联预查询条件\n     * @param string $relation    关联名\n     * @param string $subRelation 子关联\n     * @return array\n     */\n    protected function eagerlyManyToMany($where, $relation, $subRelation = '')\n    {\n        // 预载入关联查询 支持嵌套预载入\n        $list = $this->belongsToManyQuery($this->foreignKey, $this->localKey, $where)->with($subRelation)->select();\n\n        // 组装模型数据\n        $data = [];\n        foreach ($list as $set) {\n            $pivot = [];\n            foreach ($set->getData() as $key => $val) {\n                if (strpos($key, '__')) {\n                    list($name, $attr) = explode('__', $key, 2);\n                    if ('pivot' == $name) {\n                        $pivot[$attr] = $val;\n                        unset($set->$key);\n                    }\n                }\n            }\n            $set->pivot                      = $this->newPivot($pivot);\n            $data[$pivot[$this->localKey]][] = $set;\n        }\n        return $data;\n    }\n\n    /**\n     * BELONGS TO MANY 关联查询\n     * @access public\n     * @param string $foreignKey 关联模型关联键\n     * @param string $localKey   当前模型关联键\n     * @param array  $condition  关联查询条件\n     * @return Query\n     */\n    protected function belongsToManyQuery($foreignKey, $localKey, $condition = [])\n    {\n        // 关联查询封装\n        $tableName = $this->query->getTable();\n        $table     = $this->pivot->getTable();\n        $query     = $this->query->field($tableName . '.*')\n            ->field(true, false, $table, 'pivot', 'pivot__');\n\n        if (empty($this->baseQuery)) {\n            $relationFk = $this->query->getPk();\n            $query->join($table . ' pivot', 'pivot.' . $foreignKey . '=' . $tableName . '.' . $relationFk)\n                ->where($condition);\n        }\n        return $query;\n    }\n\n    /**\n     * 保存（新增）当前关联数据对象\n     * @access public\n     * @param mixed $data  数据 可以使用数组 关联模型对象 和 关联对象的主键\n     * @param array $pivot 中间表额外数据\n     * @return integer\n     */\n    public function save($data, array $pivot = [])\n    {\n        // 保存关联表/中间表数据\n        return $this->attach($data, $pivot);\n    }\n\n    /**\n     * 批量保存当前关联数据对象\n     * @access public\n     * @param array $dataSet   数据集\n     * @param array $pivot     中间表额外数据\n     * @param bool  $samePivot 额外数据是否相同\n     * @return integer\n     */\n    public function saveAll(array $dataSet, array $pivot = [], $samePivot = false)\n    {\n        $result = false;\n        foreach ($dataSet as $key => $data) {\n            if (!$samePivot) {\n                $pivotData = isset($pivot[$key]) ? $pivot[$key] : [];\n            } else {\n                $pivotData = $pivot;\n            }\n            $result = $this->attach($data, $pivotData);\n        }\n        return $result;\n    }\n\n    /**\n     * 附加关联的一个中间表数据\n     * @access public\n     * @param mixed $data  数据 可以使用数组、关联模型对象 或者 关联对象的主键\n     * @param array $pivot 中间表额外数据\n     * @return array|Pivot\n     * @throws Exception\n     */\n    public function attach($data, $pivot = [])\n    {\n        if (is_array($data)) {\n            if (key($data) === 0) {\n                $id = $data;\n            } else {\n                // 保存关联表数据\n                $model = new $this->model;\n                $model->save($data);\n                $id = $model->getLastInsID();\n            }\n        } elseif (is_numeric($data) || is_string($data)) {\n            // 根据关联表主键直接写入中间表\n            $id = $data;\n        } elseif ($data instanceof Model) {\n            // 根据关联表主键直接写入中间表\n            $relationFk = $data->getPk();\n            $id         = $data->$relationFk;\n        }\n\n        if ($id) {\n            // 保存中间表数据\n            $pk                     = $this->parent->getPk();\n            $pivot[$this->localKey] = $this->parent->$pk;\n            $ids                    = (array) $id;\n            foreach ($ids as $id) {\n                $pivot[$this->foreignKey] = $id;\n                $this->pivot->insert($pivot, true);\n                $result[] = $this->newPivot($pivot);\n            }\n            if (count($result) == 1) {\n                // 返回中间表模型对象\n                $result = $result[0];\n            }\n            return $result;\n        } else {\n            throw new Exception('miss relation data');\n        }\n    }\n\n    /**\n     * 解除关联的一个中间表数据\n     * @access public\n     * @param integer|array $data        数据 可以使用关联对象的主键\n     * @param bool          $relationDel 是否同时删除关联表数据\n     * @return integer\n     */\n    public function detach($data = null, $relationDel = false)\n    {\n        if (is_array($data)) {\n            $id = $data;\n        } elseif (is_numeric($data) || is_string($data)) {\n            // 根据关联表主键直接写入中间表\n            $id = $data;\n        } elseif ($data instanceof Model) {\n            // 根据关联表主键直接写入中间表\n            $relationFk = $data->getPk();\n            $id         = $data->$relationFk;\n        }\n        // 删除中间表数据\n        $pk                     = $this->parent->getPk();\n        $pivot[$this->localKey] = $this->parent->$pk;\n        if (isset($id)) {\n            $pivot[$this->foreignKey] = is_array($id) ? ['in', $id] : $id;\n        }\n        $this->pivot->where($pivot)->delete();\n        // 删除关联表数据\n        if (isset($id) && $relationDel) {\n            $model = $this->model;\n            $model::destroy($id);\n        }\n    }\n\n    /**\n     * 数据同步\n     * @param array $ids\n     * @param bool  $detaching\n     * @return array\n     */\n    public function sync($ids, $detaching = true)\n    {\n        $changes = [\n            'attached' => [],\n            'detached' => [],\n            'updated'  => [],\n        ];\n        $pk      = $this->parent->getPk();\n        $current = $this->pivot->where($this->localKey, $this->parent->$pk)\n            ->column($this->foreignKey);\n        $records = [];\n\n        foreach ($ids as $key => $value) {\n            if (!is_array($value)) {\n                $records[$value] = [];\n            } else {\n                $records[$key] = $value;\n            }\n        }\n\n        $detach = array_diff($current, array_keys($records));\n\n        if ($detaching && count($detach) > 0) {\n            $this->detach($detach);\n\n            $changes['detached'] = $detach;\n        }\n\n        foreach ($records as $id => $attributes) {\n            if (!in_array($id, $current)) {\n                $this->attach($id, $attributes);\n                $changes['attached'][] = $id;\n            } elseif (count($attributes) > 0 &&\n                $this->attach($id, $attributes)\n            ) {\n                $changes['updated'][] = $id;\n            }\n        }\n\n        return $changes;\n\n    }\n\n    /**\n     * 执行基础查询（进执行一次）\n     * @access protected\n     * @return void\n     */\n    protected function baseQuery()\n    {\n        if (empty($this->baseQuery) && $this->parent->getData()) {\n            $pk    = $this->parent->getPk();\n            $table = $this->pivot->getTable();\n            $this->query->join($table . ' pivot', 'pivot.' . $this->foreignKey . '=' . $this->query->getTable() . '.' . $this->query->getPk())->where('pivot.' . $this->localKey, $this->parent->$pk);\n            $this->baseQuery = true;\n        }\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/model/relation/HasMany.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\model\\relation;\n\nuse think\\db\\Query;\nuse think\\Loader;\nuse think\\Model;\nuse think\\model\\Relation;\n\nclass HasMany extends Relation\n{\n    /**\n     * 构造函数\n     * @access public\n     * @param Model  $parent     上级模型对象\n     * @param string $model      模型名\n     * @param string $foreignKey 关联外键\n     * @param string $localKey   关联主键\n     */\n    public function __construct(Model $parent, $model, $foreignKey, $localKey)\n    {\n        $this->parent     = $parent;\n        $this->model      = $model;\n        $this->foreignKey = $foreignKey;\n        $this->localKey   = $localKey;\n        $this->query      = (new $model)->db();\n    }\n\n    /**\n     * 延迟获取关联数据\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包查询条件\n     * @return false|\\PDOStatement|string|\\think\\Collection\n     */\n    public function getRelation($subRelation = '', $closure = null)\n    {\n        if ($closure) {\n            call_user_func_array($closure, [ & $this->query]);\n        }\n        $list   = $this->relation($subRelation)->select();\n        $parent = clone $this->parent;\n\n        foreach ($list as &$model) {\n            $model->setParent($parent);\n        }\n\n        return $list;\n    }\n\n    /**\n     * 预载入关联查询\n     * @access   public\n     * @param array    $resultSet   数据集\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     */\n    public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure)\n    {\n        $localKey = $this->localKey;\n        $range    = [];\n        foreach ($resultSet as $result) {\n            // 获取关联外键列表\n            if (isset($result->$localKey)) {\n                $range[] = $result->$localKey;\n            }\n        }\n\n        if (!empty($range)) {\n            $data = $this->eagerlyOneToMany($this, [\n                $this->foreignKey => [\n                    'in',\n                    $range,\n                ],\n            ], $relation, $subRelation, $closure);\n            // 关联属性名\n            $attr = Loader::parseName($relation);\n            // 关联数据封装\n            foreach ($resultSet as $result) {\n                if (!isset($data[$result->$localKey])) {\n                    $data[$result->$localKey] = [];\n                }\n\n                foreach ($data[$result->$localKey] as &$relationModel) {\n                    $relationModel->setParent(clone $result);\n                }\n\n                $result->setRelation($attr, $this->resultSetBuild($data[$result->$localKey]));\n            }\n        }\n    }\n\n    /**\n     * 预载入关联查询\n     * @access   public\n     * @param Model    $result      数据对象\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     */\n    public function eagerlyResult(&$result, $relation, $subRelation, $closure)\n    {\n        $localKey = $this->localKey;\n\n        if (isset($result->$localKey)) {\n            $data = $this->eagerlyOneToMany($this, [$this->foreignKey => $result->$localKey], $relation, $subRelation, $closure);\n            // 关联数据封装\n            if (!isset($data[$result->$localKey])) {\n                $data[$result->$localKey] = [];\n            }\n\n            foreach ($data[$result->$localKey] as &$relationModel) {\n                $relationModel->setParent(clone $result);\n            }\n\n            $result->setRelation(Loader::parseName($relation), $this->resultSetBuild($data[$result->$localKey]));\n        }\n    }\n\n    /**\n     * 关联统计\n     * @access public\n     * @param Model    $result  数据对象\n     * @param \\Closure $closure 闭包\n     * @return integer\n     */\n    public function relationCount($result, $closure)\n    {\n        $localKey = $this->localKey;\n        $count    = 0;\n        if (isset($result->$localKey)) {\n            if ($closure) {\n                call_user_func_array($closure, [ & $this->query]);\n            }\n            $count = $this->query->where([$this->foreignKey => $result->$localKey])->count();\n        }\n        return $count;\n    }\n\n    /**\n     * 创建关联统计子查询\n     * @access public\n     * @param \\Closure $closure 闭包\n     * @return string\n     */\n    public function getRelationCountQuery($closure)\n    {\n        if ($closure) {\n            call_user_func_array($closure, [ & $this->query]);\n        }\n\n        return $this->query->where([\n            $this->foreignKey => [\n                'exp',\n                '=' . $this->parent->getTable() . '.' . $this->parent->getPk(),\n            ],\n        ])->fetchSql()->count();\n    }\n\n    /**\n     * 一对多 关联模型预查询\n     * @access public\n     * @param object $model       关联模型对象\n     * @param array  $where       关联预查询条件\n     * @param string $relation    关联名\n     * @param string $subRelation 子关联\n     * @param bool   $closure\n     * @return array\n     */\n    protected function eagerlyOneToMany($model, $where, $relation, $subRelation = '', $closure = false)\n    {\n        $foreignKey = $this->foreignKey;\n        // 预载入关联查询 支持嵌套预载入\n        if ($closure) {\n            call_user_func_array($closure, [ & $model]);\n        }\n        $list = $model->where($where)->with($subRelation)->select();\n\n        // 组装模型数据\n        $data = [];\n        foreach ($list as $set) {\n            $data[$set->$foreignKey][] = $set;\n        }\n        return $data;\n    }\n\n    /**\n     * 保存（新增）当前关联数据对象\n     * @access public\n     * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键\n     * @return Model|false\n     */\n    public function save($data)\n    {\n        if ($data instanceof Model) {\n            $data = $data->getData();\n        }\n        // 保存关联表数据\n        $model                   = new $this->model;\n        $data[$this->foreignKey] = $this->parent->{$this->localKey};\n        return $model->save($data) ? $model : false;\n    }\n\n    /**\n     * 批量保存当前关联数据对象\n     * @access public\n     * @param array $dataSet 数据集\n     * @return integer\n     */\n    public function saveAll(array $dataSet)\n    {\n        $result = false;\n        foreach ($dataSet as $key => $data) {\n            $result = $this->save($data);\n        }\n        return $result;\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param string  $operator 比较操作符\n     * @param integer $count    个数\n     * @param string  $id       关联表的统计字段\n     * @param string  $joinType JOIN类型\n     * @return Query\n     */\n    public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER')\n    {\n        $table = $this->query->getTable();\n        return $this->parent->db()->alias('a')\n            ->join($table . ' b', 'a.' . $this->localKey . '=b.' . $this->foreignKey, $joinType)\n            ->group('b.' . $this->foreignKey)\n            ->having('count(' . $id . ')' . $operator . $count);\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param mixed $where 查询条件（数组或者闭包）\n     * @return Query\n     */\n    public function hasWhere($where = [])\n    {\n        $table    = $this->query->getTable();\n        $model    = basename(str_replace('\\\\', '/', get_class($this->parent)));\n        $relation = basename(str_replace('\\\\', '/', $this->model));\n        if (is_array($where)) {\n            foreach ($where as $key => $val) {\n                if (false === strpos($key, '.')) {\n                    $where[$relation . '.' . $key] = $val;\n                    unset($where[$key]);\n                }\n            }\n        }\n        return $this->parent->db()->alias($model)\n            ->field($model . '.*')\n            ->join($table . ' ' . $relation, $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey)\n            ->where($where);\n    }\n\n    /**\n     * 执行基础查询（进执行一次）\n     * @access protected\n     * @return void\n     */\n    protected function baseQuery()\n    {\n        if (empty($this->baseQuery)) {\n            if (isset($this->parent->{$this->localKey})) {\n                // 关联查询带入关联条件\n                $this->query->where($this->foreignKey, $this->parent->{$this->localKey});\n            }\n            $this->baseQuery = true;\n        }\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/model/relation/HasManyThrough.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\model\\relation;\n\nuse think\\db\\Query;\nuse think\\Exception;\nuse think\\Loader;\nuse think\\Model;\nuse think\\model\\Relation;\n\nclass HasManyThrough extends Relation\n{\n    // 中间关联表外键\n    protected $throughKey;\n    // 中间表模型\n    protected $through;\n\n    /**\n     * 构造函数\n     * @access   public\n     * @param Model  $parent     上级模型对象\n     * @param string $model      模型名\n     * @param string $through    中间模型名\n     * @param string $foreignKey 关联外键\n     * @param string $throughKey 关联外键\n     * @param string $localKey   关联主键\n     */\n    public function __construct(Model $parent, $model, $through, $foreignKey, $throughKey, $localKey)\n    {\n        $this->parent     = $parent;\n        $this->model      = $model;\n        $this->through    = $through;\n        $this->foreignKey = $foreignKey;\n        $this->throughKey = $throughKey;\n        $this->localKey   = $localKey;\n        $this->query      = (new $model)->db();\n    }\n\n    /**\n     * 延迟获取关联数据\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包查询条件\n     * @return false|\\PDOStatement|string|\\think\\Collection\n     */\n    public function getRelation($subRelation = '', $closure = null)\n    {\n        if ($closure) {\n            call_user_func_array($closure, [ & $this->query]);\n        }\n\n        return $this->relation($subRelation)->select();\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param string  $operator 比较操作符\n     * @param integer $count    个数\n     * @param string  $id       关联表的统计字段\n     * @param string  $joinType JOIN类型\n     * @return Query\n     */\n    public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER')\n    {\n        return $this->parent;\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param mixed $where 查询条件（数组或者闭包）\n     * @return Query\n     */\n    public function hasWhere($where = [])\n    {\n        throw new Exception('relation not support: hasWhere');\n    }\n\n    /**\n     * 预载入关联查询\n     * @access public\n     * @param array    $resultSet   数据集\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @param string   $class       数据集对象名 为空表示数组\n     * @return void\n     */\n    public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure, $class)\n    {}\n\n    /**\n     * 预载入关联查询 返回模型对象\n     * @access public\n     * @param Model    $result      数据对象\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @param string   $class       数据集对象名 为空表示数组\n     * @return void\n     */\n    public function eagerlyResult(&$result, $relation, $subRelation, $closure, $class)\n    {}\n\n    /**\n     * 关联统计\n     * @access public\n     * @param Model    $result  数据对象\n     * @param \\Closure $closure 闭包\n     * @return integer\n     */\n    public function relationCount($result, $closure)\n    {}\n\n    /**\n     * 执行基础查询（进执行一次）\n     * @access protected\n     * @return void\n     */\n    protected function baseQuery()\n    {\n        if (empty($this->baseQuery) && $this->parent->getData()) {\n            $through      = $this->through;\n            $model        = $this->model;\n            $alias        = Loader::parseName(basename(str_replace('\\\\', '/', $model)));\n            $throughTable = $through::getTable();\n            $pk           = (new $this->model)->getPk();\n            $throughKey   = $this->throughKey;\n            $modelTable   = $this->parent->getTable();\n            $this->query->field($alias . '.*')->alias($alias)\n                ->join($throughTable, $throughTable . '.' . $pk . '=' . $alias . '.' . $throughKey)\n                ->join($modelTable, $modelTable . '.' . $this->localKey . '=' . $throughTable . '.' . $this->foreignKey)\n                ->where($throughTable . '.' . $this->foreignKey, $this->parent->{$this->localKey});\n            $this->baseQuery = true;\n        }\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/model/relation/HasOne.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\model\\relation;\n\nuse think\\db\\Query;\nuse think\\Loader;\nuse think\\Model;\n\nclass HasOne extends OneToOne\n{\n    /**\n     * 构造函数\n     * @access public\n     * @param Model  $parent     上级模型对象\n     * @param string $model      模型名\n     * @param string $foreignKey 关联外键\n     * @param string $localKey   关联主键\n     * @param string $joinType   JOIN类型\n     */\n    public function __construct(Model $parent, $model, $foreignKey, $localKey, $joinType = 'INNER')\n    {\n        $this->parent     = $parent;\n        $this->model      = $model;\n        $this->foreignKey = $foreignKey;\n        $this->localKey   = $localKey;\n        $this->joinType   = $joinType;\n        $this->query      = (new $model)->db();\n    }\n\n    /**\n     * 延迟获取关联数据\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包查询条件\n     * @return array|false|\\PDOStatement|string|Model\n     */\n    public function getRelation($subRelation = '', $closure = null)\n    {\n        // 执行关联定义方法\n        $localKey = $this->localKey;\n        if ($closure) {\n            call_user_func_array($closure, [ & $this->query]);\n        }\n        // 判断关联类型执行查询\n        $relationModel = $this->query->where($this->foreignKey, $this->parent->$localKey)->relation($subRelation)->find();\n\n        if ($relationModel) {\n            $relationModel->setParent(clone $this->parent);\n        }\n\n        return $relationModel;\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @return Query\n     */\n    public function has()\n    {\n        $table      = $this->query->getTable();\n        $localKey   = $this->localKey;\n        $foreignKey = $this->foreignKey;\n        return $this->parent->db()->alias('a')\n            ->whereExists(function ($query) use ($table, $localKey, $foreignKey) {\n                $query->table([$table => 'b'])->field('b.' . $foreignKey)->whereExp('a.' . $localKey, '=b.' . $foreignKey);\n            });\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param mixed $where 查询条件（数组或者闭包）\n     * @return Query\n     */\n    public function hasWhere($where = [])\n    {\n        $table    = $this->query->getTable();\n        $model    = basename(str_replace('\\\\', '/', get_class($this->parent)));\n        $relation = basename(str_replace('\\\\', '/', $this->model));\n        if (is_array($where)) {\n            foreach ($where as $key => $val) {\n                if (false === strpos($key, '.')) {\n                    $where[$relation . '.' . $key] = $val;\n                    unset($where[$key]);\n                }\n            }\n        }\n        return $this->parent->db()->alias($model)\n            ->field($model . '.*')\n            ->join($table . ' ' . $relation, $model . '.' . $this->localKey . '=' . $relation . '.' . $this->foreignKey, $this->joinType)\n            ->where($where);\n    }\n\n    /**\n     * 预载入关联查询（数据集）\n     * @access public\n     * @param array    $resultSet   数据集\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     */\n    protected function eagerlySet(&$resultSet, $relation, $subRelation, $closure)\n    {\n        $localKey   = $this->localKey;\n        $foreignKey = $this->foreignKey;\n\n        $range = [];\n        foreach ($resultSet as $result) {\n            // 获取关联外键列表\n            if (isset($result->$localKey)) {\n                $range[] = $result->$localKey;\n            }\n        }\n\n        if (!empty($range)) {\n            $data = $this->eagerlyWhere($this, [\n                $foreignKey => [\n                    'in',\n                    $range,\n                ],\n            ], $foreignKey, $relation, $subRelation, $closure);\n            // 关联属性名\n            $attr = Loader::parseName($relation);\n            // 关联数据封装\n            foreach ($resultSet as $result) {\n                // 关联模型\n                if (!isset($data[$result->$localKey])) {\n                    $relationModel = null;\n                } else {\n                    $relationModel = $data[$result->$localKey];\n                    $relationModel->setParent(clone $result);\n                    $relationModel->isUpdate(true);\n                    if (!empty($this->bindAttr)) {\n                        // 绑定关联属性\n                        $this->bindAttr($relationModel, $result, $this->bindAttr);\n                    }\n                }\n                // 设置关联属性\n                $result->setRelation($attr, $relationModel);\n            }\n        }\n    }\n\n    /**\n     * 预载入关联查询（数据）\n     * @access public\n     * @param Model    $result      数据对象\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     */\n    protected function eagerlyOne(&$result, $relation, $subRelation, $closure)\n    {\n        $localKey   = $this->localKey;\n        $foreignKey = $this->foreignKey;\n        $data       = $this->eagerlyWhere($this, [$foreignKey => $result->$localKey], $foreignKey, $relation, $subRelation, $closure);\n\n        // 关联模型\n        if (!isset($data[$result->$localKey])) {\n            $relationModel = null;\n        } else {\n            $relationModel = $data[$result->$localKey];\n            $relationModel->setParent(clone $result);\n            $relationModel->isUpdate(true);\n            if (!empty($this->bindAttr)) {\n                // 绑定关联属性\n                $this->bindAttr($relationModel, $result, $this->bindAttr);\n            }\n        }\n\n        $result->setRelation(Loader::parseName($relation), $relationModel);\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/model/relation/MorphMany.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\model\\relation;\n\nuse think\\db\\Query;\nuse think\\Exception;\nuse think\\Loader;\nuse think\\Model;\nuse think\\model\\Relation;\n\nclass MorphMany extends Relation\n{\n    // 多态字段\n    protected $morphKey;\n    protected $morphType;\n    // 多态类型\n    protected $type;\n\n    /**\n     * 构造函数\n     * @access public\n     * @param Model  $parent    上级模型对象\n     * @param string $model     模型名\n     * @param string $morphKey  关联外键\n     * @param string $morphType 多态字段名\n     * @param string $type      多态类型\n     */\n    public function __construct(Model $parent, $model, $morphKey, $morphType, $type)\n    {\n        $this->parent    = $parent;\n        $this->model     = $model;\n        $this->type      = $type;\n        $this->morphKey  = $morphKey;\n        $this->morphType = $morphType;\n        $this->query     = (new $model)->db();\n    }\n\n    /**\n     * 延迟获取关联数据\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包查询条件\n     * @return false|\\PDOStatement|string|\\think\\Collection\n     */\n    public function getRelation($subRelation = '', $closure = null)\n    {\n        if ($closure) {\n            call_user_func_array($closure, [ & $this->query]);\n        }\n        $list   = $this->relation($subRelation)->select();\n        $parent = clone $this->parent;\n\n        foreach ($list as &$model) {\n            $model->setParent($parent);\n        }\n\n        return $list;\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param string  $operator 比较操作符\n     * @param integer $count    个数\n     * @param string  $id       关联表的统计字段\n     * @param string  $joinType JOIN类型\n     * @return Query\n     */\n    public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER')\n    {\n        throw new Exception('relation not support: has');\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param mixed $where 查询条件（数组或者闭包）\n     * @return Query\n     */\n    public function hasWhere($where = [])\n    {\n        throw new Exception('relation not support: hasWhere');\n    }\n\n    /**\n     * 预载入关联查询\n     * @access public\n     * @param array    $resultSet   数据集\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     */\n    public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure)\n    {\n        $morphType = $this->morphType;\n        $morphKey  = $this->morphKey;\n        $type      = $this->type;\n        $range     = [];\n        foreach ($resultSet as $result) {\n            $pk = $result->getPk();\n            // 获取关联外键列表\n            if (isset($result->$pk)) {\n                $range[] = $result->$pk;\n            }\n        }\n\n        if (!empty($range)) {\n            $data = $this->eagerlyMorphToMany([\n                $morphKey  => ['in', $range],\n                $morphType => $type,\n            ], $relation, $subRelation, $closure);\n            // 关联属性名\n            $attr = Loader::parseName($relation);\n            // 关联数据封装\n            foreach ($resultSet as $result) {\n                if (!isset($data[$result->$pk])) {\n                    $data[$result->$pk] = [];\n                }\n                foreach ($data[$result->$pk] as &$relationModel) {\n                    $relationModel->setParent(clone $result);\n                    $relationModel->isUpdate(true);\n                }\n                $result->setRelation($attr, $this->resultSetBuild($data[$result->$pk]));\n            }\n        }\n    }\n\n    /**\n     * 预载入关联查询\n     * @access public\n     * @param Model    $result      数据对象\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     */\n    public function eagerlyResult(&$result, $relation, $subRelation, $closure)\n    {\n        $pk = $result->getPk();\n        if (isset($result->$pk)) {\n            $data = $this->eagerlyMorphToMany([\n                $this->morphKey  => $result->$pk,\n                $this->morphType => $this->type,\n            ], $relation, $subRelation, $closure);\n\n            if (!isset($data[$result->$pk])) {\n                $data[$result->$pk] = [];\n            }\n\n            foreach ($data[$result->$pk] as &$relationModel) {\n                $relationModel->setParent(clone $result);\n                $relationModel->isUpdate(true);\n            }\n\n            $result->setRelation(Loader::parseName($relation), $this->resultSetBuild($data[$result->$pk]));\n        }\n    }\n\n    /**\n     * 关联统计\n     * @access public\n     * @param Model    $result  数据对象\n     * @param \\Closure $closure 闭包\n     * @return integer\n     */\n    public function relationCount($result, $closure)\n    {\n        $pk    = $result->getPk();\n        $count = 0;\n        if (isset($result->$pk)) {\n            if ($closure) {\n                call_user_func_array($closure, [ & $this->query]);\n            }\n            $count = $this->query->where([$this->morphKey => $result->$pk, $this->morphType => $this->type])->count();\n        }\n        return $count;\n    }\n\n    /**\n     * 获取关联统计子查询\n     * @access public\n     * @param \\Closure $closure 闭包\n     * @return string\n     */\n    public function getRelationCountQuery($closure)\n    {\n        if ($closure) {\n            call_user_func_array($closure, [ & $this->query]);\n        }\n\n        return $this->query->where([\n            $this->morphKey  => [\n                'exp',\n                '=' . $this->parent->getTable() . '.' . $this->parent->getPk(),\n            ],\n            $this->morphType => $this->type,\n        ])->fetchSql()->count();\n    }\n\n    /**\n     * 多态一对多 关联模型预查询\n     * @access   public\n     * @param array         $where       关联预查询条件\n     * @param string        $relation    关联名\n     * @param string        $subRelation 子关联\n     * @param bool|\\Closure $closure     闭包\n     * @return array\n     */\n    protected function eagerlyMorphToMany($where, $relation, $subRelation = '', $closure = false)\n    {\n        // 预载入关联查询 支持嵌套预载入\n        if ($closure) {\n            call_user_func_array($closure, [ & $this]);\n        }\n        $list     = $this->query->where($where)->with($subRelation)->select();\n        $morphKey = $this->morphKey;\n        // 组装模型数据\n        $data = [];\n        foreach ($list as $set) {\n            $data[$set->$morphKey][] = $set;\n        }\n        return $data;\n    }\n\n    /**\n     * 保存（新增）当前关联数据对象\n     * @access public\n     * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键\n     * @return Model|false\n     */\n    public function save($data)\n    {\n        if ($data instanceof Model) {\n            $data = $data->getData();\n        }\n        // 保存关联表数据\n        $pk = $this->parent->getPk();\n\n        $model                  = new $this->model;\n        $data[$this->morphKey]  = $this->parent->$pk;\n        $data[$this->morphType] = $this->type;\n        return $model->save($data) ? $model : false;\n    }\n\n    /**\n     * 批量保存当前关联数据对象\n     * @access public\n     * @param array $dataSet 数据集\n     * @return integer\n     */\n    public function saveAll(array $dataSet)\n    {\n        $result = false;\n        foreach ($dataSet as $key => $data) {\n            $result = $this->save($data);\n        }\n        return $result;\n    }\n\n    /**\n     * 执行基础查询（进执行一次）\n     * @access protected\n     * @return void\n     */\n    protected function baseQuery()\n    {\n        if (empty($this->baseQuery) && $this->parent->getData()) {\n            $pk                    = $this->parent->getPk();\n            $map[$this->morphKey]  = $this->parent->$pk;\n            $map[$this->morphType] = $this->type;\n            $this->query->where($map);\n            $this->baseQuery = true;\n        }\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/model/relation/MorphOne.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\model\\relation;\n\nuse think\\db\\Query;\nuse think\\Exception;\nuse think\\Loader;\nuse think\\Model;\nuse think\\model\\Relation;\n\nclass MorphOne extends Relation\n{\n    // 多态字段\n    protected $morphKey;\n    protected $morphType;\n    // 多态类型\n    protected $type;\n\n    /**\n     * 构造函数\n     * @access public\n     * @param Model  $parent    上级模型对象\n     * @param string $model     模型名\n     * @param string $morphKey  关联外键\n     * @param string $morphType 多态字段名\n     * @param string $type      多态类型\n     */\n    public function __construct(Model $parent, $model, $morphKey, $morphType, $type)\n    {\n        $this->parent    = $parent;\n        $this->model     = $model;\n        $this->type      = $type;\n        $this->morphKey  = $morphKey;\n        $this->morphType = $morphType;\n        $this->query     = (new $model)->db();\n    }\n\n    /**\n     * 延迟获取关联数据\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包查询条件\n     * @return false|\\PDOStatement|string|\\think\\Collection\n     */\n    public function getRelation($subRelation = '', $closure = null)\n    {\n        if ($closure) {\n            call_user_func_array($closure, [ & $this->query]);\n        }\n        $relationModel = $this->relation($subRelation)->find();\n\n        if ($relationModel) {\n            $relationModel->setParent(clone $this->parent);\n        }\n\n        return $relationModel;\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param string  $operator 比较操作符\n     * @param integer $count    个数\n     * @param string  $id       关联表的统计字段\n     * @param string  $joinType JOIN类型\n     * @return Query\n     */\n    public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER')\n    {\n        return $this->parent;\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param mixed $where 查询条件（数组或者闭包）\n     * @return Query\n     */\n    public function hasWhere($where = [])\n    {\n        throw new Exception('relation not support: hasWhere');\n    }\n\n    /**\n     * 预载入关联查询\n     * @access public\n     * @param array    $resultSet   数据集\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     */\n    public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure)\n    {\n        $morphType = $this->morphType;\n        $morphKey  = $this->morphKey;\n        $type      = $this->type;\n        $range     = [];\n        foreach ($resultSet as $result) {\n            $pk = $result->getPk();\n            // 获取关联外键列表\n            if (isset($result->$pk)) {\n                $range[] = $result->$pk;\n            }\n        }\n\n        if (!empty($range)) {\n            $data = $this->eagerlyMorphToOne([\n                $morphKey  => ['in', $range],\n                $morphType => $type,\n            ], $relation, $subRelation, $closure);\n            // 关联属性名\n            $attr = Loader::parseName($relation);\n            // 关联数据封装\n            foreach ($resultSet as $result) {\n                if (!isset($data[$result->$pk])) {\n                    $relationModel = null;\n                } else {\n                    $relationModel = $data[$result->$pk];\n                    $relationModel->setParent(clone $result);\n                    $relationModel->isUpdate(true);\n                }\n\n                $result->setRelation($attr, $relationModel);\n            }\n        }\n    }\n\n    /**\n     * 预载入关联查询\n     * @access public\n     * @param Model    $result      数据对象\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     */\n    public function eagerlyResult(&$result, $relation, $subRelation, $closure)\n    {\n        $pk = $result->getPk();\n        if (isset($result->$pk)) {\n            $pk   = $result->$pk;\n            $data = $this->eagerlyMorphToOne([\n                $this->morphKey  => $pk,\n                $this->morphType => $this->type,\n            ], $relation, $subRelation, $closure);\n\n            if (isset($data[$pk])) {\n                $relationModel = $data[$pk];\n                $relationModel->setParent(clone $result);\n                $relationModel->isUpdate(true);\n            } else {\n                $relationModel = null;\n            }\n\n            $result->setRelation(Loader::parseName($relation), $relationModel);\n        }\n    }\n\n    /**\n     * 多态一对一 关联模型预查询\n     * @access   public\n     * @param array         $where       关联预查询条件\n     * @param string        $relation    关联名\n     * @param string        $subRelation 子关联\n     * @param bool|\\Closure $closure     闭包\n     * @return array\n     */\n    protected function eagerlyMorphToOne($where, $relation, $subRelation = '', $closure = false)\n    {\n        // 预载入关联查询 支持嵌套预载入\n        if ($closure) {\n            call_user_func_array($closure, [ & $this]);\n        }\n        $list     = $this->query->where($where)->with($subRelation)->find();\n        $morphKey = $this->morphKey;\n        // 组装模型数据\n        $data = [];\n        foreach ($list as $set) {\n            $data[$set->$morphKey][] = $set;\n        }\n        return $data;\n    }\n\n    /**\n     * 保存（新增）当前关联数据对象\n     * @access public\n     * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键\n     * @return Model|false\n     */\n    public function save($data)\n    {\n        if ($data instanceof Model) {\n            $data = $data->getData();\n        }\n        // 保存关联表数据\n        $pk = $this->parent->getPk();\n\n        $model                  = new $this->model;\n        $data[$this->morphKey]  = $this->parent->$pk;\n        $data[$this->morphType] = $this->type;\n        return $model->save($data) ? $model : false;\n    }\n\n    /**\n     * 执行基础查询（进执行一次）\n     * @access protected\n     * @return void\n     */\n    protected function baseQuery()\n    {\n        if (empty($this->baseQuery) && $this->parent->getData()) {\n            $pk                    = $this->parent->getPk();\n            $map[$this->morphKey]  = $this->parent->$pk;\n            $map[$this->morphType] = $this->type;\n            $this->query->where($map);\n            $this->baseQuery = true;\n        }\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/model/relation/MorphTo.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\model\\relation;\n\nuse think\\Exception;\nuse think\\Loader;\nuse think\\Model;\nuse think\\model\\Relation;\n\nclass MorphTo extends Relation\n{\n    // 多态字段\n    protected $morphKey;\n    protected $morphType;\n    // 多态别名\n    protected $alias;\n    protected $relation;\n\n    /**\n     * 构造函数\n     * @access public\n     * @param Model  $parent    上级模型对象\n     * @param string $morphType 多态字段名\n     * @param string $morphKey  外键名\n     * @param array  $alias     多态别名定义\n     * @param string $relation  关联名\n     */\n    public function __construct(Model $parent, $morphType, $morphKey, $alias = [], $relation = null)\n    {\n        $this->parent    = $parent;\n        $this->morphType = $morphType;\n        $this->morphKey  = $morphKey;\n        $this->alias     = $alias;\n        $this->relation  = $relation;\n    }\n\n    /**\n     * 延迟获取关联数据\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包查询条件\n     * @return mixed\n     */\n    public function getRelation($subRelation = '', $closure = null)\n    {\n        $morphKey  = $this->morphKey;\n        $morphType = $this->morphType;\n        // 多态模型\n        $model = $this->parseModel($this->parent->$morphType);\n        // 主键数据\n        $pk            = $this->parent->$morphKey;\n        $relationModel = (new $model)->relation($subRelation)->find($pk);\n\n        if ($relationModel) {\n            $relationModel->setParent(clone $this->parent);\n        }\n        return $relationModel;\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param string  $operator 比较操作符\n     * @param integer $count    个数\n     * @param string  $id       关联表的统计字段\n     * @param string  $joinType JOIN类型\n     * @return Query\n     */\n    public function has($operator = '>=', $count = 1, $id = '*', $joinType = 'INNER')\n    {\n        return $this->parent;\n    }\n\n    /**\n     * 根据关联条件查询当前模型\n     * @access public\n     * @param mixed $where 查询条件（数组或者闭包）\n     * @return Query\n     */\n    public function hasWhere($where = [])\n    {\n        throw new Exception('relation not support: hasWhere');\n    }\n\n    /**\n     * 解析模型的完整命名空间\n     * @access public\n     * @param string $model 模型名（或者完整类名）\n     * @return string\n     */\n    protected function parseModel($model)\n    {\n        if (isset($this->alias[$model])) {\n            $model = $this->alias[$model];\n        }\n        if (false === strpos($model, '\\\\')) {\n            $path = explode('\\\\', get_class($this->parent));\n            array_pop($path);\n            array_push($path, Loader::parseName($model, 1));\n            $model = implode('\\\\', $path);\n        }\n        return $model;\n    }\n\n    /**\n     * 设置多态别名\n     * @access public\n     * @param array $alias 别名定义\n     * @return $this\n     */\n    public function setAlias($alias)\n    {\n        $this->alias = $alias;\n        return $this;\n    }\n\n    /**\n     * 移除关联查询参数\n     * @access public\n     * @return $this\n     */\n    public function removeOption()\n    {\n        return $this;\n    }\n\n    /**\n     * 预载入关联查询\n     * @access public\n     * @param array    $resultSet   数据集\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     * @throws Exception\n     */\n    public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure)\n    {\n        $morphKey  = $this->morphKey;\n        $morphType = $this->morphType;\n        $range     = [];\n        foreach ($resultSet as $result) {\n            // 获取关联外键列表\n            if (!empty($result->$morphKey)) {\n                $range[$result->$morphType][] = $result->$morphKey;\n            }\n        }\n\n        if (!empty($range)) {\n            // 关联属性名\n            $attr = Loader::parseName($relation);\n            foreach ($range as $key => $val) {\n                // 多态类型映射\n                $model = $this->parseModel($key);\n                $obj   = new $model;\n                $pk    = $obj->getPk();\n                $list  = $obj->all($val, $subRelation);\n                $data  = [];\n                foreach ($list as $k => $vo) {\n                    $data[$vo->$pk] = $vo;\n                }\n                foreach ($resultSet as $result) {\n                    if ($key == $result->$morphType) {\n                        // 关联模型\n                        if (!isset($data[$result->$morphKey])) {\n                            throw new Exception('relation data not exists :' . $this->model);\n                        } else {\n                            $relationModel = $data[$result->$morphKey];\n                            $relationModel->setParent(clone $result);\n                            $relationModel->isUpdate(true);\n\n                            $result->setRelation($attr, $relationModel);\n                        }\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * 预载入关联查询\n     * @access public\n     * @param Model    $result      数据对象\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     */\n    public function eagerlyResult(&$result, $relation, $subRelation, $closure)\n    {\n        $morphKey  = $this->morphKey;\n        $morphType = $this->morphType;\n        // 多态类型映射\n        $model = $this->parseModel($result->{$this->morphType});\n        $this->eagerlyMorphToOne($model, $relation, $result, $subRelation);\n    }\n\n    /**\n     * 关联统计\n     * @access public\n     * @param Model    $result  数据对象\n     * @param \\Closure $closure 闭包\n     * @return integer\n     */\n    public function relationCount($result, $closure)\n    {\n    }\n\n    /**\n     * 多态MorphTo 关联模型预查询\n     * @access   public\n     * @param object $model       关联模型对象\n     * @param string $relation    关联名\n     * @param        $result\n     * @param string $subRelation 子关联\n     * @return void\n     */\n    protected function eagerlyMorphToOne($model, $relation, &$result, $subRelation = '')\n    {\n        // 预载入关联查询 支持嵌套预载入\n        $pk   = $this->parent->{$this->morphKey};\n        $data = (new $model)->with($subRelation)->find($pk);\n        if ($data) {\n            $data->setParent(clone $result);\n            $data->isUpdate(true);\n        }\n        $result->setRelation(Loader::parseName($relation), $data ?: null);\n    }\n\n    /**\n     * 添加关联数据\n     * @access public\n     * @param Model $model       关联模型对象\n     * @return Model\n     */\n    public function associate($model)\n    {\n        $morphKey  = $this->morphKey;\n        $morphType = $this->morphType;\n        $pk        = $model->getPk();\n\n        $this->parent->setAttr($morphKey, $model->$pk);\n        $this->parent->setAttr($morphType, get_class($model));\n        $this->parent->save();\n\n        return $this->parent->setRelation($this->relation, $model);\n    }\n\n    /**\n     * 注销关联数据\n     * @access public\n     * @return Model\n     */\n    public function dissociate()\n    {\n        $morphKey  = $this->morphKey;\n        $morphType = $this->morphType;\n\n        $this->parent->setAttr($morphKey, null);\n        $this->parent->setAttr($morphType, null);\n        $this->parent->save();\n\n        return $this->parent->setRelation($this->relation, null);\n    }\n\n    /**\n     * 执行基础查询（进执行一次）\n     * @access protected\n     * @return void\n     */\n    protected function baseQuery()\n    {}\n}\n"
  },
  {
    "path": "thinkphp/library/think/model/relation/OneToOne.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\model\\relation;\n\nuse think\\db\\Query;\nuse think\\Exception;\nuse think\\Loader;\nuse think\\Model;\nuse think\\model\\Relation;\n\n/**\n * Class OneToOne\n * @package think\\model\\relation\n *\n */\nabstract class OneToOne extends Relation\n{\n    // 预载入方式 0 -JOIN 1 -IN\n    protected $eagerlyType = 1;\n    // 当前关联的JOIN类型\n    protected $joinType;\n    // 要绑定的属性\n    protected $bindAttr = [];\n    // 关联方法名\n    protected $relation;\n\n    /**\n     * 设置join类型\n     * @access public\n     * @param string $type JOIN类型\n     * @return $this\n     */\n    public function joinType($type)\n    {\n        $this->joinType = $type;\n        return $this;\n    }\n\n    /**\n     * 预载入关联查询（JOIN方式）\n     * @access public\n     * @param Query    $query       查询对象\n     * @param string   $relation    关联名\n     * @param string   $subRelation 子关联\n     * @param \\Closure $closure     闭包条件\n     * @param bool     $first\n     * @return void\n     */\n    public function eagerly(Query $query, $relation, $subRelation, $closure, $first)\n    {\n        $name  = Loader::parseName(basename(str_replace('\\\\', '/', $query->getModel())));\n        $alias = $name;\n        if ($first) {\n            $table = $query->getTable();\n            $query->table([$table => $alias]);\n            if ($query->getOptions('field')) {\n                $field = $query->getOptions('field');\n                $query->removeOption('field');\n            } else {\n                $field = true;\n            }\n            $query->field($field, false, $table, $alias);\n            $field = null;\n        }\n\n        // 预载入封装\n        $joinTable = $this->query->getTable();\n        $joinAlias = $relation;\n        $query->via($joinAlias);\n\n        if ($this instanceof BelongsTo) {\n            $query->join($joinTable . ' ' . $joinAlias, $alias . '.' . $this->foreignKey . '=' . $joinAlias . '.' . $this->localKey, $this->joinType);\n        } else {\n            $query->join($joinTable . ' ' . $joinAlias, $alias . '.' . $this->localKey . '=' . $joinAlias . '.' . $this->foreignKey, $this->joinType);\n        }\n\n        if ($closure) {\n            // 执行闭包查询\n            call_user_func_array($closure, [ & $query]);\n            // 使用withField指定获取关联的字段，如\n            // $query->where(['id'=>1])->withField('id,name');\n            if ($query->getOptions('with_field')) {\n                $field = $query->getOptions('with_field');\n                $query->removeOption('with_field');\n            }\n        } elseif (isset($this->option['field'])) {\n            $field = $this->option['field'];\n        }\n        $query->field(isset($field) ? $field : true, false, $joinTable, $joinAlias, $relation . '__');\n    }\n\n    /**\n     *  预载入关联查询（数据集）\n     * @param array    $resultSet\n     * @param string   $relation\n     * @param string   $subRelation\n     * @param \\Closure $closure\n     * @return mixed\n     */\n    abstract protected function eagerlySet(&$resultSet, $relation, $subRelation, $closure);\n\n    /**\n     * 预载入关联查询（数据）\n     * @param Model    $result\n     * @param string   $relation\n     * @param string   $subRelation\n     * @param \\Closure $closure\n     * @return mixed\n     */\n    abstract protected function eagerlyOne(&$result, $relation, $subRelation, $closure);\n\n    /**\n     * 预载入关联查询（数据集）\n     * @access public\n     * @param array    $resultSet   数据集\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     */\n    public function eagerlyResultSet(&$resultSet, $relation, $subRelation, $closure)\n    {\n        if (1 == $this->eagerlyType) {\n            // IN查询\n            $this->eagerlySet($resultSet, $relation, $subRelation, $closure);\n        } else {\n            // 模型关联组装\n            foreach ($resultSet as $result) {\n                $this->match($this->model, $relation, $result);\n            }\n        }\n    }\n\n    /**\n     * 预载入关联查询（数据）\n     * @access public\n     * @param Model    $result      数据对象\n     * @param string   $relation    当前关联名\n     * @param string   $subRelation 子关联名\n     * @param \\Closure $closure     闭包\n     * @return void\n     */\n    public function eagerlyResult(&$result, $relation, $subRelation, $closure)\n    {\n        if (1 == $this->eagerlyType) {\n            // IN查询\n            $this->eagerlyOne($result, $relation, $subRelation, $closure);\n        } else {\n            // 模型关联组装\n            $this->match($this->model, $relation, $result);\n        }\n    }\n\n    /**\n     * 保存（新增）当前关联数据对象\n     * @access public\n     * @param mixed $data 数据 可以使用数组 关联模型对象 和 关联对象的主键\n     * @return Model|false\n     */\n    public function save($data)\n    {\n        if ($data instanceof Model) {\n            $data = $data->getData();\n        }\n        $model = new $this->model;\n        // 保存关联表数据\n        $data[$this->foreignKey] = $this->parent->{$this->localKey};\n        return $model->save($data) ? $model : false;\n    }\n\n    /**\n     * 设置预载入方式\n     * @access public\n     * @param integer $type 预载入方式 0 JOIN查询 1 IN查询\n     * @return $this\n     */\n    public function setEagerlyType($type)\n    {\n        $this->eagerlyType = $type;\n        return $this;\n    }\n\n    /**\n     * 获取预载入方式\n     * @access public\n     * @return integer\n     */\n    public function getEagerlyType()\n    {\n        return $this->eagerlyType;\n    }\n\n    /**\n     * 绑定关联表的属性到父模型属性\n     * @access public\n     * @param mixed $attr 要绑定的属性列表\n     * @return $this\n     */\n    public function bind($attr)\n    {\n        if (is_string($attr)) {\n            $attr = explode(',', $attr);\n        }\n        $this->bindAttr = $attr;\n        return $this;\n    }\n\n    /**\n     * 关联统计\n     * @access public\n     * @param Model    $result  数据对象\n     * @param \\Closure $closure 闭包\n     * @return integer\n     */\n    public function relationCount($result, $closure)\n    {\n    }\n\n    /**\n     * 一对一 关联模型预查询拼装\n     * @access public\n     * @param string $model    模型名称\n     * @param string $relation 关联名\n     * @param Model  $result   模型对象实例\n     * @return void\n     */\n    protected function match($model, $relation, &$result)\n    {\n        // 重新组装模型数据\n        foreach ($result->getData() as $key => $val) {\n            if (strpos($key, '__')) {\n                list($name, $attr) = explode('__', $key, 2);\n                if ($name == $relation) {\n                    $list[$name][$attr] = $val;\n                    unset($result->$key);\n                }\n            }\n        }\n\n        if (isset($list[$relation])) {\n            $relationModel = new $model($list[$relation]);\n            $relationModel->setParent(clone $result);\n            $relationModel->isUpdate(true);\n\n            if (!empty($this->bindAttr)) {\n                $this->bindAttr($relationModel, $result, $this->bindAttr);\n            }\n        } else {\n            $relationModel = null;\n        }\n        $result->setRelation(Loader::parseName($relation), $relationModel);\n    }\n\n    /**\n     * 绑定关联属性到父模型\n     * @access protected\n     * @param Model $model    关联模型对象\n     * @param Model $result   父模型对象\n     * @param array $bindAttr 绑定属性\n     * @return void\n     * @throws Exception\n     */\n    protected function bindAttr($model, &$result, $bindAttr)\n    {\n        foreach ($bindAttr as $key => $attr) {\n            $key = is_numeric($key) ? $attr : $key;\n            if (isset($result->$key)) {\n                throw new Exception('bind attr has exists:' . $key);\n            } else {\n                $result->setAttr($key, $model->$attr);\n            }\n        }\n    }\n\n    /**\n     * 一对一 关联模型预查询（IN方式）\n     * @access public\n     * @param object        $model       关联模型对象\n     * @param array         $where       关联预查询条件\n     * @param string        $key         关联键名\n     * @param string        $relation    关联名\n     * @param string        $subRelation 子关联\n     * @param bool|\\Closure $closure\n     * @return array\n     */\n    protected function eagerlyWhere($model, $where, $key, $relation, $subRelation = '', $closure = false)\n    {\n        // 预载入关联查询 支持嵌套预载入\n        if ($closure) {\n            call_user_func_array($closure, [ & $model]);\n            if ($field = $model->getOptions('with_field')) {\n                $model->field($field)->removeOption('with_field');\n            }\n        }\n        $list = $model->where($where)->with($subRelation)->select();\n\n        // 组装模型数据\n        $data = [];\n        foreach ($list as $set) {\n            $data[$set->$key] = $set;\n        }\n        return $data;\n    }\n\n    /**\n     * 执行基础查询（进执行一次）\n     * @access protected\n     * @return void\n     */\n    protected function baseQuery()\n    {}\n}\n"
  },
  {
    "path": "thinkphp/library/think/paginator/driver/Bootstrap.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: zhangyajun <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\paginator\\driver;\n\nuse think\\Paginator;\n\nclass Bootstrap extends Paginator\n{\n\n    /**\n     * 上一页按钮\n     * @param string $text\n     * @return string\n     */\n    protected function getPreviousButton($text = \"&laquo;\")\n    {\n\n        if ($this->currentPage() <= 1) {\n            return $this->getDisabledTextWrapper($text);\n        }\n\n        $url = $this->url(\n            $this->currentPage() - 1\n        );\n\n        return $this->getPageLinkWrapper($url, $text);\n    }\n\n    /**\n     * 下一页按钮\n     * @param string $text\n     * @return string\n     */\n    protected function getNextButton($text = '&raquo;')\n    {\n        if (!$this->hasMore) {\n            return $this->getDisabledTextWrapper($text);\n        }\n\n        $url = $this->url($this->currentPage() + 1);\n\n        return $this->getPageLinkWrapper($url, $text);\n    }\n\n    /**\n     * 页码按钮\n     * @return string\n     */\n    protected function getLinks()\n    {\n        if ($this->simple)\n            return '';\n\n        $block = [\n            'first'  => null,\n            'slider' => null,\n            'last'   => null\n        ];\n\n        $side   = 3;\n        $window = $side * 2;\n\n        if ($this->lastPage < $window + 6) {\n            $block['first'] = $this->getUrlRange(1, $this->lastPage);\n        } elseif ($this->currentPage <= $window) {\n            $block['first'] = $this->getUrlRange(1, $window + 2);\n            $block['last']  = $this->getUrlRange($this->lastPage - 1, $this->lastPage);\n        } elseif ($this->currentPage > ($this->lastPage - $window)) {\n            $block['first'] = $this->getUrlRange(1, 2);\n            $block['last']  = $this->getUrlRange($this->lastPage - ($window + 2), $this->lastPage);\n        } else {\n            $block['first']  = $this->getUrlRange(1, 2);\n            $block['slider'] = $this->getUrlRange($this->currentPage - $side, $this->currentPage + $side);\n            $block['last']   = $this->getUrlRange($this->lastPage - 1, $this->lastPage);\n        }\n\n        $html = '';\n\n        if (is_array($block['first'])) {\n            $html .= $this->getUrlLinks($block['first']);\n        }\n\n        if (is_array($block['slider'])) {\n            $html .= $this->getDots();\n            $html .= $this->getUrlLinks($block['slider']);\n        }\n\n        if (is_array($block['last'])) {\n            $html .= $this->getDots();\n            $html .= $this->getUrlLinks($block['last']);\n        }\n\n        return $html;\n    }\n\n    /**\n     * 渲染分页html\n     * @return mixed\n     */\n    public function render()\n    {\n        if ($this->hasPages()) {\n            if ($this->simple) {\n                return sprintf(\n                    '<ul class=\"pager\">%s %s</ul>',\n                    $this->getPreviousButton(),\n                    $this->getNextButton()\n                );\n            } else {\n                return sprintf(\n                    '<ul class=\"pagination\">%s %s %s</ul>',\n                    $this->getPreviousButton(),\n                    $this->getLinks(),\n                    $this->getNextButton()\n                );\n            }\n        }\n    }\n\n    /**\n     * 生成一个可点击的按钮\n     *\n     * @param  string $url\n     * @param  int    $page\n     * @return string\n     */\n    protected function getAvailablePageWrapper($url, $page)\n    {\n        return '<li><a href=\"' . htmlentities($url) . '\">' . $page . '</a></li>';\n    }\n\n    /**\n     * 生成一个禁用的按钮\n     *\n     * @param  string $text\n     * @return string\n     */\n    protected function getDisabledTextWrapper($text)\n    {\n        return '<li class=\"disabled\"><span>' . $text . '</span></li>';\n    }\n\n    /**\n     * 生成一个激活的按钮\n     *\n     * @param  string $text\n     * @return string\n     */\n    protected function getActivePageWrapper($text)\n    {\n        return '<li class=\"active\"><span>' . $text . '</span></li>';\n    }\n\n    /**\n     * 生成省略号按钮\n     *\n     * @return string\n     */\n    protected function getDots()\n    {\n        return $this->getDisabledTextWrapper('...');\n    }\n\n    /**\n     * 批量生成页码按钮.\n     *\n     * @param  array $urls\n     * @return string\n     */\n    protected function getUrlLinks(array $urls)\n    {\n        $html = '';\n\n        foreach ($urls as $page => $url) {\n            $html .= $this->getPageLinkWrapper($url, $page);\n        }\n\n        return $html;\n    }\n\n    /**\n     * 生成普通页码按钮\n     *\n     * @param  string $url\n     * @param  int    $page\n     * @return string\n     */\n    protected function getPageLinkWrapper($url, $page)\n    {\n        if ($page == $this->currentPage()) {\n            return $this->getActivePageWrapper($page);\n        }\n\n        return $this->getAvailablePageWrapper($url, $page);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/process/Builder.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\process;\n\nuse think\\Process;\n\nclass Builder\n{\n    private $arguments;\n    private $cwd;\n    private $env = null;\n    private $input;\n    private $timeout        = 60;\n    private $options        = [];\n    private $inheritEnv     = true;\n    private $prefix         = [];\n    private $outputDisabled = false;\n\n    /**\n     * 构造方法\n     * @param string[] $arguments 参数\n     */\n    public function __construct(array $arguments = [])\n    {\n        $this->arguments = $arguments;\n    }\n\n    /**\n     * 创建一个实例\n     * @param string[] $arguments 参数\n     * @return self\n     */\n    public static function create(array $arguments = [])\n    {\n        return new static($arguments);\n    }\n\n    /**\n     * 添加一个参数\n     * @param string $argument 参数\n     * @return self\n     */\n    public function add($argument)\n    {\n        $this->arguments[] = $argument;\n\n        return $this;\n    }\n\n    /**\n     * 添加一个前缀\n     * @param string|array $prefix\n     * @return self\n     */\n    public function setPrefix($prefix)\n    {\n        $this->prefix = is_array($prefix) ? $prefix : [$prefix];\n\n        return $this;\n    }\n\n    /**\n     * 设置参数\n     * @param string[] $arguments\n     * @return  self\n     */\n    public function setArguments(array $arguments)\n    {\n        $this->arguments = $arguments;\n\n        return $this;\n    }\n\n    /**\n     * 设置工作目录\n     * @param null|string $cwd\n     * @return  self\n     */\n    public function setWorkingDirectory($cwd)\n    {\n        $this->cwd = $cwd;\n\n        return $this;\n    }\n\n    /**\n     * 是否初始化环境变量\n     * @param bool $inheritEnv\n     * @return self\n     */\n    public function inheritEnvironmentVariables($inheritEnv = true)\n    {\n        $this->inheritEnv = $inheritEnv;\n\n        return $this;\n    }\n\n    /**\n     * 设置环境变量\n     * @param string      $name\n     * @param null|string $value\n     * @return self\n     */\n    public function setEnv($name, $value)\n    {\n        $this->env[$name] = $value;\n\n        return $this;\n    }\n\n    /**\n     *  添加环境变量\n     * @param array $variables\n     * @return self\n     */\n    public function addEnvironmentVariables(array $variables)\n    {\n        $this->env = array_replace($this->env, $variables);\n\n        return $this;\n    }\n\n    /**\n     * 设置输入\n     * @param mixed $input\n     * @return self\n     */\n    public function setInput($input)\n    {\n        $this->input = Utils::validateInput(sprintf('%s::%s', __CLASS__, __FUNCTION__), $input);\n\n        return $this;\n    }\n\n    /**\n     * 设置超时时间\n     * @param float|null $timeout\n     * @return self\n     */\n    public function setTimeout($timeout)\n    {\n        if (null === $timeout) {\n            $this->timeout = null;\n\n            return $this;\n        }\n\n        $timeout = (float) $timeout;\n\n        if ($timeout < 0) {\n            throw new \\InvalidArgumentException('The timeout value must be a valid positive integer or float number.');\n        }\n\n        $this->timeout = $timeout;\n\n        return $this;\n    }\n\n    /**\n     * 设置proc_open选项\n     * @param string $name\n     * @param string $value\n     * @return self\n     */\n    public function setOption($name, $value)\n    {\n        $this->options[$name] = $value;\n\n        return $this;\n    }\n\n    /**\n     * 禁止输出\n     * @return self\n     */\n    public function disableOutput()\n    {\n        $this->outputDisabled = true;\n\n        return $this;\n    }\n\n    /**\n     * 开启输出\n     * @return self\n     */\n    public function enableOutput()\n    {\n        $this->outputDisabled = false;\n\n        return $this;\n    }\n\n    /**\n     * 创建一个Process实例\n     * @return Process\n     */\n    public function getProcess()\n    {\n        if (0 === count($this->prefix) && 0 === count($this->arguments)) {\n            throw new \\LogicException('You must add() command arguments before calling getProcess().');\n        }\n\n        $options = $this->options;\n\n        $arguments = array_merge($this->prefix, $this->arguments);\n        $script    = implode(' ', array_map([__NAMESPACE__ . '\\\\Utils', 'escapeArgument'], $arguments));\n\n        if ($this->inheritEnv) {\n            // include $_ENV for BC purposes\n            $env = array_replace($_ENV, $_SERVER, $this->env);\n        } else {\n            $env = $this->env;\n        }\n\n        $process = new Process($script, $this->cwd, $env, $this->input, $this->timeout, $options);\n\n        if ($this->outputDisabled) {\n            $process->disableOutput();\n        }\n\n        return $process;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/process/Utils.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | TopThink [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2015 http://www.topthink.com All rights reserved.\n// +----------------------------------------------------------------------\n// | Author: zhangyajun <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\process;\n\nclass Utils\n{\n\n    /**\n     * 转义字符串\n     * @param string $argument\n     * @return string\n     */\n    public static function escapeArgument($argument)\n    {\n\n        if ('' === $argument) {\n            return escapeshellarg($argument);\n        }\n        $escapedArgument = '';\n        $quote           = false;\n        foreach (preg_split('/(\")/i', $argument, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE) as $part) {\n            if ('\"' === $part) {\n                $escapedArgument .= '\\\\\"';\n            } elseif (self::isSurroundedBy($part, '%')) {\n                // Avoid environment variable expansion\n                $escapedArgument .= '^%\"' . substr($part, 1, -1) . '\"^%';\n            } else {\n                // escape trailing backslash\n                if ('\\\\' === substr($part, -1)) {\n                    $part .= '\\\\';\n                }\n                $quote = true;\n                $escapedArgument .= $part;\n            }\n        }\n        if ($quote) {\n            $escapedArgument = '\"' . $escapedArgument . '\"';\n        }\n        return $escapedArgument;\n    }\n\n    /**\n     * 验证并进行规范化Process输入。\n     * @param string $caller\n     * @param mixed  $input\n     * @return string\n     * @throws \\InvalidArgumentException\n     */\n    public static function validateInput($caller, $input)\n    {\n        if (null !== $input) {\n            if (is_resource($input)) {\n                return $input;\n            }\n            if (is_scalar($input)) {\n                return (string) $input;\n            }\n            throw new \\InvalidArgumentException(sprintf('%s only accepts strings or stream resources.', $caller));\n        }\n        return $input;\n    }\n\n    private static function isSurroundedBy($arg, $char)\n    {\n        return 2 < strlen($arg) && $char === $arg[0] && $char === $arg[strlen($arg) - 1];\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/process/exception/Failed.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\process\\exception;\n\nuse think\\Process;\n\nclass Failed extends \\RuntimeException\n{\n\n    private $process;\n\n    public function __construct(Process $process)\n    {\n        if ($process->isSuccessful()) {\n            throw new \\InvalidArgumentException('Expected a failed process, but the given process was successful.');\n        }\n\n        $error = sprintf('The command \"%s\" failed.' . \"\\nExit Code: %s(%s)\", $process->getCommandLine(), $process->getExitCode(), $process->getExitCodeText());\n\n        if (!$process->isOutputDisabled()) {\n            $error .= sprintf(\"\\n\\nOutput:\\n================\\n%s\\n\\nError Output:\\n================\\n%s\", $process->getOutput(), $process->getErrorOutput());\n        }\n\n        parent::__construct($error);\n\n        $this->process = $process;\n    }\n\n    public function getProcess()\n    {\n        return $this->process;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/process/exception/Timeout.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\process\\exception;\n\nuse think\\Process;\n\nclass Timeout extends \\RuntimeException\n{\n\n    const TYPE_GENERAL = 1;\n    const TYPE_IDLE    = 2;\n\n    private $process;\n    private $timeoutType;\n\n    public function __construct(Process $process, $timeoutType)\n    {\n        $this->process     = $process;\n        $this->timeoutType = $timeoutType;\n\n        parent::__construct(sprintf('The process \"%s\" exceeded the timeout of %s seconds.', $process->getCommandLine(), $this->getExceededTimeout()));\n    }\n\n    public function getProcess()\n    {\n        return $this->process;\n    }\n\n    public function isGeneralTimeout()\n    {\n        return $this->timeoutType === self::TYPE_GENERAL;\n    }\n\n    public function isIdleTimeout()\n    {\n        return $this->timeoutType === self::TYPE_IDLE;\n    }\n\n    public function getExceededTimeout()\n    {\n        switch ($this->timeoutType) {\n            case self::TYPE_GENERAL:\n                return $this->process->getTimeout();\n\n            case self::TYPE_IDLE:\n                return $this->process->getIdleTimeout();\n\n            default:\n                throw new \\LogicException(sprintf('Unknown timeout type \"%d\".', $this->timeoutType));\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/process/pipes/Pipes.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\process\\pipes;\n\nabstract class Pipes\n{\n\n    /** @var array */\n    public $pipes = [];\n\n    /** @var string */\n    protected $inputBuffer = '';\n    /** @var resource|null */\n    protected $input;\n\n    /** @var bool */\n    private $blocked = true;\n\n    const CHUNK_SIZE = 16384;\n\n    /**\n     * 返回用于 proc_open 描述符的数组\n     * @return array\n     */\n    abstract public function getDescriptors();\n\n    /**\n     * 返回一个数组的索引由其相关的流，以防这些管道使用的临时文件的文件名。\n     * @return string[]\n     */\n    abstract public function getFiles();\n\n    /**\n     * 文件句柄和管道中读取数据。\n     * @param bool $blocking 是否使用阻塞调用\n     * @param bool $close    是否要关闭管道，如果他们已经到达 EOF。\n     * @return string[]\n     */\n    abstract public function readAndWrite($blocking, $close = false);\n\n    /**\n     * 返回当前状态如果有打开的文件句柄或管道。\n     * @return bool\n     */\n    abstract public function areOpen();\n\n    /**\n     * {@inheritdoc}\n     */\n    public function close()\n    {\n        foreach ($this->pipes as $pipe) {\n            fclose($pipe);\n        }\n        $this->pipes = [];\n    }\n\n    /**\n     * 检查系统调用已被中断\n     * @return bool\n     */\n    protected function hasSystemCallBeenInterrupted()\n    {\n        $lastError = error_get_last();\n\n        return isset($lastError['message']) && false !== stripos($lastError['message'], 'interrupted system call');\n    }\n\n    protected function unblock()\n    {\n        if (!$this->blocked) {\n            return;\n        }\n\n        foreach ($this->pipes as $pipe) {\n            stream_set_blocking($pipe, 0);\n        }\n        if (null !== $this->input) {\n            stream_set_blocking($this->input, 0);\n        }\n\n        $this->blocked = false;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/process/pipes/Unix.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\process\\pipes;\n\nuse think\\Process;\n\nclass Unix extends Pipes\n{\n\n    /** @var bool */\n    private $ttyMode;\n    /** @var bool */\n    private $ptyMode;\n    /** @var bool */\n    private $disableOutput;\n\n    public function __construct($ttyMode, $ptyMode, $input, $disableOutput)\n    {\n        $this->ttyMode       = (bool) $ttyMode;\n        $this->ptyMode       = (bool) $ptyMode;\n        $this->disableOutput = (bool) $disableOutput;\n\n        if (is_resource($input)) {\n            $this->input = $input;\n        } else {\n            $this->inputBuffer = (string) $input;\n        }\n    }\n\n    public function __destruct()\n    {\n        $this->close();\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getDescriptors()\n    {\n        if ($this->disableOutput) {\n            $nullstream = fopen('/dev/null', 'c');\n\n            return [\n                ['pipe', 'r'],\n                $nullstream,\n                $nullstream,\n            ];\n        }\n\n        if ($this->ttyMode) {\n            return [\n                ['file', '/dev/tty', 'r'],\n                ['file', '/dev/tty', 'w'],\n                ['file', '/dev/tty', 'w'],\n            ];\n        }\n\n        if ($this->ptyMode && Process::isPtySupported()) {\n            return [\n                ['pty'],\n                ['pty'],\n                ['pty'],\n            ];\n        }\n\n        return [\n            ['pipe', 'r'],\n            ['pipe', 'w'], // stdout\n            ['pipe', 'w'], // stderr\n        ];\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getFiles()\n    {\n        return [];\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function readAndWrite($blocking, $close = false)\n    {\n\n        if (1 === count($this->pipes) && [0] === array_keys($this->pipes)) {\n            fclose($this->pipes[0]);\n            unset($this->pipes[0]);\n        }\n\n        if (empty($this->pipes)) {\n            return [];\n        }\n\n        $this->unblock();\n\n        $read = [];\n\n        if (null !== $this->input) {\n            $r = array_merge($this->pipes, ['input' => $this->input]);\n        } else {\n            $r = $this->pipes;\n        }\n\n        unset($r[0]);\n\n        $w = isset($this->pipes[0]) ? [$this->pipes[0]] : null;\n        $e = null;\n\n        if (false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) {\n\n            if (!$this->hasSystemCallBeenInterrupted()) {\n                $this->pipes = [];\n            }\n\n            return $read;\n        }\n\n        if (0 === $n) {\n            return $read;\n        }\n\n        foreach ($r as $pipe) {\n\n            $type = (false !== $found = array_search($pipe, $this->pipes)) ? $found : 'input';\n            $data = '';\n            while ('' !== $dataread = (string) fread($pipe, self::CHUNK_SIZE)) {\n                $data .= $dataread;\n            }\n\n            if ('' !== $data) {\n                if ('input' === $type) {\n                    $this->inputBuffer .= $data;\n                } else {\n                    $read[$type] = $data;\n                }\n            }\n\n            if (false === $data || (true === $close && feof($pipe) && '' === $data)) {\n                if ('input' === $type) {\n                    $this->input = null;\n                } else {\n                    fclose($this->pipes[$type]);\n                    unset($this->pipes[$type]);\n                }\n            }\n        }\n\n        if (null !== $w && 0 < count($w)) {\n            while (strlen($this->inputBuffer)) {\n                $written = fwrite($w[0], $this->inputBuffer, 2 << 18); // write 512k\n                if ($written > 0) {\n                    $this->inputBuffer = (string) substr($this->inputBuffer, $written);\n                } else {\n                    break;\n                }\n            }\n        }\n\n        if ('' === $this->inputBuffer && null === $this->input && isset($this->pipes[0])) {\n            fclose($this->pipes[0]);\n            unset($this->pipes[0]);\n        }\n\n        return $read;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function areOpen()\n    {\n        return (bool) $this->pipes;\n    }\n\n    /**\n     * 创建一个新的 UnixPipes 实例\n     * @param Process         $process\n     * @param string|resource $input\n     * @return self\n     */\n    public static function create(Process $process, $input)\n    {\n        return new static($process->isTty(), $process->isPty(), $input, $process->isOutputDisabled());\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/process/pipes/Windows.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2015 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: yunwuxin <448901948@qq.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\process\\pipes;\n\nuse think\\Process;\n\nclass Windows extends Pipes\n{\n\n    /** @var array */\n    private $files = [];\n    /** @var array */\n    private $fileHandles = [];\n    /** @var array */\n    private $readBytes = [\n        Process::STDOUT => 0,\n        Process::STDERR => 0,\n    ];\n    /** @var bool */\n    private $disableOutput;\n\n    public function __construct($disableOutput, $input)\n    {\n        $this->disableOutput = (bool) $disableOutput;\n\n        if (!$this->disableOutput) {\n\n            $this->files = [\n                Process::STDOUT => tempnam(sys_get_temp_dir(), 'sf_proc_stdout'),\n                Process::STDERR => tempnam(sys_get_temp_dir(), 'sf_proc_stderr'),\n            ];\n            foreach ($this->files as $offset => $file) {\n                $this->fileHandles[$offset] = fopen($this->files[$offset], 'rb');\n                if (false === $this->fileHandles[$offset]) {\n                    throw new \\RuntimeException('A temporary file could not be opened to write the process output to, verify that your TEMP environment variable is writable');\n                }\n            }\n        }\n\n        if (is_resource($input)) {\n            $this->input = $input;\n        } else {\n            $this->inputBuffer = $input;\n        }\n    }\n\n    public function __destruct()\n    {\n        $this->close();\n        $this->removeFiles();\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getDescriptors()\n    {\n        if ($this->disableOutput) {\n            $nullstream = fopen('NUL', 'c');\n\n            return [\n                ['pipe', 'r'],\n                $nullstream,\n                $nullstream,\n            ];\n        }\n\n        return [\n            ['pipe', 'r'],\n            ['file', 'NUL', 'w'],\n            ['file', 'NUL', 'w'],\n        ];\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function getFiles()\n    {\n        return $this->files;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function readAndWrite($blocking, $close = false)\n    {\n        $this->write($blocking, $close);\n\n        $read = [];\n        $fh   = $this->fileHandles;\n        foreach ($fh as $type => $fileHandle) {\n            if (0 !== fseek($fileHandle, $this->readBytes[$type])) {\n                continue;\n            }\n            $data     = '';\n            $dataread = null;\n            while (!feof($fileHandle)) {\n                if (false !== $dataread = fread($fileHandle, self::CHUNK_SIZE)) {\n                    $data .= $dataread;\n                }\n            }\n            if (0 < $length = strlen($data)) {\n                $this->readBytes[$type] += $length;\n                $read[$type] = $data;\n            }\n\n            if (false === $dataread || (true === $close && feof($fileHandle) && '' === $data)) {\n                fclose($this->fileHandles[$type]);\n                unset($this->fileHandles[$type]);\n            }\n        }\n\n        return $read;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function areOpen()\n    {\n        return (bool) $this->pipes && (bool) $this->fileHandles;\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function close()\n    {\n        parent::close();\n        foreach ($this->fileHandles as $handle) {\n            fclose($handle);\n        }\n        $this->fileHandles = [];\n    }\n\n    /**\n     * 创建一个新的 WindowsPipes 实例。\n     * @param Process $process\n     * @param         $input\n     * @return self\n     */\n    public static function create(Process $process, $input)\n    {\n        return new static($process->isOutputDisabled(), $input);\n    }\n\n    /**\n     * 删除临时文件\n     */\n    private function removeFiles()\n    {\n        foreach ($this->files as $filename) {\n            if (file_exists($filename)) {\n                @unlink($filename);\n            }\n        }\n        $this->files = [];\n    }\n\n    /**\n     * 写入到 stdin 输入\n     * @param bool $blocking\n     * @param bool $close\n     */\n    private function write($blocking, $close)\n    {\n        if (empty($this->pipes)) {\n            return;\n        }\n\n        $this->unblock();\n\n        $r = null !== $this->input ? ['input' => $this->input] : null;\n        $w = isset($this->pipes[0]) ? [$this->pipes[0]] : null;\n        $e = null;\n\n        if (false === $n = @stream_select($r, $w, $e, 0, $blocking ? Process::TIMEOUT_PRECISION * 1E6 : 0)) {\n            if (!$this->hasSystemCallBeenInterrupted()) {\n                $this->pipes = [];\n            }\n\n            return;\n        }\n\n        if (0 === $n) {\n            return;\n        }\n\n        if (null !== $w && 0 < count($r)) {\n            $data = '';\n            while ($dataread = fread($r['input'], self::CHUNK_SIZE)) {\n                $data .= $dataread;\n            }\n\n            $this->inputBuffer .= $data;\n\n            if (false === $data || (true === $close && feof($r['input']) && '' === $data)) {\n                $this->input = null;\n            }\n        }\n\n        if (null !== $w && 0 < count($w)) {\n            while (strlen($this->inputBuffer)) {\n                $written = fwrite($w[0], $this->inputBuffer, 2 << 18);\n                if ($written > 0) {\n                    $this->inputBuffer = (string) substr($this->inputBuffer, $written);\n                } else {\n                    break;\n                }\n            }\n        }\n\n        if ('' === $this->inputBuffer && null === $this->input && isset($this->pipes[0])) {\n            fclose($this->pipes[0]);\n            unset($this->pipes[0]);\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/response/Json.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\response;\n\nuse think\\Response;\n\nclass Json extends Response\n{\n    // 输出参数\n    protected $options = [\n        'json_encode_param' => JSON_UNESCAPED_UNICODE,\n    ];\n\n    protected $contentType = 'application/json';\n\n    /**\n     * 处理数据\n     * @access protected\n     * @param mixed $data 要处理的数据\n     * @return mixed\n     * @throws \\Exception\n     */\n    protected function output($data)\n    {\n        try {\n            // 返回JSON数据格式到客户端 包含状态信息\n            $data = json_encode($data, $this->options['json_encode_param']);\n\n            if ($data === false) {\n                throw new \\InvalidArgumentException(json_last_error_msg());\n            }\n\n            return $data;\n        } catch (\\Exception $e) {\n            if ($e->getPrevious()) {\n                throw $e->getPrevious();\n            }\n            throw $e;\n        }\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/response/Jsonp.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\response;\n\nuse think\\Request;\nuse think\\Response;\n\nclass Jsonp extends Response\n{\n    // 输出参数\n    protected $options = [\n        'var_jsonp_handler'     => 'callback',\n        'default_jsonp_handler' => 'jsonpReturn',\n        'json_encode_param'     => JSON_UNESCAPED_UNICODE,\n    ];\n\n    protected $contentType = 'application/javascript';\n\n    /**\n     * 处理数据\n     * @access protected\n     * @param mixed $data 要处理的数据\n     * @return mixed\n     * @throws \\Exception\n     */\n    protected function output($data)\n    {\n        try {\n            // 返回JSON数据格式到客户端 包含状态信息 [当url_common_param为false时是无法获取到$_GET的数据的，故使用Request来获取<xiaobo.sun@qq.com>]\n            $var_jsonp_handler = Request::instance()->param($this->options['var_jsonp_handler'], \"\");\n            $handler           = !empty($var_jsonp_handler) ? $var_jsonp_handler : $this->options['default_jsonp_handler'];\n\n            $data = json_encode($data, $this->options['json_encode_param']);\n\n            if ($data === false) {\n                throw new \\InvalidArgumentException(json_last_error_msg());\n            }\n\n            $data = $handler . '(' . $data . ');';\n            return $data;\n        } catch (\\Exception $e) {\n            if ($e->getPrevious()) {\n                throw $e->getPrevious();\n            }\n            throw $e;\n        }\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/response/Redirect.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\response;\n\nuse think\\Request;\nuse think\\Response;\nuse think\\Session;\nuse think\\Url;\n\nclass Redirect extends Response\n{\n\n    protected $options = [];\n\n    // URL参数\n    protected $params = [];\n\n    public function __construct($data = '', $code = 302, array $header = [], array $options = [])\n    {\n        parent::__construct($data, $code, $header, $options);\n        $this->cacheControl('no-cache,must-revalidate');\n    }\n\n    /**\n     * 处理数据\n     * @access protected\n     * @param mixed $data 要处理的数据\n     * @return mixed\n     */\n    protected function output($data)\n    {\n        $this->header['Location'] = $this->getTargetUrl();\n        return;\n    }\n\n    /**\n     * 重定向传值（通过Session）\n     * @access protected\n     * @param string|array  $name 变量名或者数组\n     * @param mixed         $value 值\n     * @return $this\n     */\n    public function with($name, $value = null)\n    {\n        if (is_array($name)) {\n            foreach ($name as $key => $val) {\n                Session::flash($key, $val);\n            }\n        } else {\n            Session::flash($name, $value);\n        }\n        return $this;\n    }\n\n    /**\n     * 获取跳转地址\n     * @return string\n     */\n    public function getTargetUrl()\n    {\n        return (strpos($this->data, '://') || 0 === strpos($this->data, '/')) ? $this->data : Url::build($this->data, $this->params);\n    }\n\n    public function params($params = [])\n    {\n        $this->params = $params;\n        return $this;\n    }\n\n    /**\n     * 记住当前url后跳转\n     * @return $this\n     */\n    public function remember()\n    {\n        Session::set('redirect_url', Request::instance()->url());\n        return $this;\n    }\n\n    /**\n     * 跳转到上次记住的url\n     * @return $this\n     */\n    public function restore()\n    {\n        if (Session::has('redirect_url')) {\n            $this->data = Session::get('redirect_url');\n            Session::delete('redirect_url');\n        }\n        return $this;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/response/View.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\response;\n\nuse think\\Config;\nuse think\\Response;\nuse think\\View as ViewTemplate;\n\nclass View extends Response\n{\n    // 输出参数\n    protected $options     = [];\n    protected $vars        = [];\n    protected $replace     = [];\n    protected $contentType = 'text/html';\n\n    /**\n     * 处理数据\n     * @access protected\n     * @param mixed $data 要处理的数据\n     * @return mixed\n     */\n    protected function output($data)\n    {\n        // 渲染模板输出\n        return ViewTemplate::instance(Config::get('template'), Config::get('view_replace_str'))\n            ->fetch($data, $this->vars, $this->replace);\n    }\n\n    /**\n     * 获取视图变量\n     * @access public\n     * @param string $name 模板变量\n     * @return mixed\n     */\n    public function getVars($name = null)\n    {\n        if (is_null($name)) {\n            return $this->vars;\n        } else {\n            return isset($this->vars[$name]) ? $this->vars[$name] : null;\n        }\n    }\n\n    /**\n     * 模板变量赋值\n     * @access public\n     * @param mixed $name  变量名\n     * @param mixed $value 变量值\n     * @return $this\n     */\n    public function assign($name, $value = '')\n    {\n        if (is_array($name)) {\n            $this->vars = array_merge($this->vars, $name);\n            return $this;\n        } else {\n            $this->vars[$name] = $value;\n        }\n        return $this;\n    }\n\n    /**\n     * 视图内容替换\n     * @access public\n     * @param string|array $content 被替换内容（支持批量替换）\n     * @param string  $replace    替换内容\n     * @return $this\n     */\n    public function replace($content, $replace = '')\n    {\n        if (is_array($content)) {\n            $this->replace = array_merge($this->replace, $content);\n        } else {\n            $this->replace[$content] = $replace;\n        }\n        return $this;\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/response/Xml.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\response;\n\nuse think\\Response;\n\nclass Xml extends Response\n{\n    // 输出参数\n    protected $options = [\n        // 根节点名\n        'root_node' => 'think',\n        // 根节点属性\n        'root_attr' => '',\n        //数字索引的子节点名\n        'item_node' => 'item',\n        // 数字索引子节点key转换的属性名\n        'item_key'  => 'id',\n        // 数据编码\n        'encoding'  => 'utf-8',\n    ];\n\n    protected $contentType = 'text/xml';\n\n    /**\n     * 处理数据\n     * @access protected\n     * @param mixed $data 要处理的数据\n     * @return mixed\n     */\n    protected function output($data)\n    {\n        // XML数据转换\n        return $this->xmlEncode($data, $this->options['root_node'], $this->options['item_node'], $this->options['root_attr'], $this->options['item_key'], $this->options['encoding']);\n    }\n\n    /**\n     * XML编码\n     * @param mixed $data 数据\n     * @param string $root 根节点名\n     * @param string $item 数字索引的子节点名\n     * @param string $attr 根节点属性\n     * @param string $id   数字索引子节点key转换的属性名\n     * @param string $encoding 数据编码\n     * @return string\n     */\n    protected function xmlEncode($data, $root, $item, $attr, $id, $encoding)\n    {\n        if (is_array($attr)) {\n            $array = [];\n            foreach ($attr as $key => $value) {\n                $array[] = \"{$key}=\\\"{$value}\\\"\";\n            }\n            $attr = implode(' ', $array);\n        }\n        $attr = trim($attr);\n        $attr = empty($attr) ? '' : \" {$attr}\";\n        $xml  = \"<?xml version=\\\"1.0\\\" encoding=\\\"{$encoding}\\\"?>\";\n        $xml .= \"<{$root}{$attr}>\";\n        $xml .= $this->dataToXml($data, $item, $id);\n        $xml .= \"</{$root}>\";\n        return $xml;\n    }\n\n    /**\n     * 数据XML编码\n     * @param mixed  $data 数据\n     * @param string $item 数字索引时的节点名称\n     * @param string $id   数字索引key转换为的属性名\n     * @return string\n     */\n    protected function dataToXml($data, $item, $id)\n    {\n        $xml = $attr = '';\n        foreach ($data as $key => $val) {\n            if (is_numeric($key)) {\n                $id && $attr = \" {$id}=\\\"{$key}\\\"\";\n                $key         = $item;\n            }\n            $xml .= \"<{$key}{$attr}>\";\n            $xml .= (is_array($val) || is_object($val)) ? $this->dataToXml($val, $item, $id) : $val;\n            $xml .= \"</{$key}>\";\n        }\n        return $xml;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/session/driver/Memcache.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\session\\driver;\n\nuse SessionHandler;\nuse think\\Exception;\n\nclass Memcache extends SessionHandler\n{\n    protected $handler = null;\n    protected $config  = [\n        'host'         => '127.0.0.1', // memcache主机\n        'port'         => 11211, // memcache端口\n        'expire'       => 3600, // session有效期\n        'timeout'      => 0, // 连接超时时间（单位：毫秒）\n        'persistent'   => true, // 长连接\n        'session_name' => '', // memcache key前缀\n    ];\n\n    public function __construct($config = [])\n    {\n        $this->config = array_merge($this->config, $config);\n    }\n\n    /**\n     * 打开Session\n     * @access public\n     * @param string    $savePath\n     * @param mixed     $sessName\n     */\n    public function open($savePath, $sessName)\n    {\n        // 检测php环境\n        if (!extension_loaded('memcache')) {\n            throw new Exception('not support:memcache');\n        }\n        $this->handler = new \\Memcache;\n        // 支持集群\n        $hosts = explode(',', $this->config['host']);\n        $ports = explode(',', $this->config['port']);\n        if (empty($ports[0])) {\n            $ports[0] = 11211;\n        }\n        // 建立连接\n        foreach ((array) $hosts as $i => $host) {\n            $port = isset($ports[$i]) ? $ports[$i] : $ports[0];\n            $this->config['timeout'] > 0 ?\n            $this->handler->addServer($host, $port, $this->config['persistent'], 1, $this->config['timeout']) :\n            $this->handler->addServer($host, $port, $this->config['persistent'], 1);\n        }\n        return true;\n    }\n\n    /**\n     * 关闭Session\n     * @access public\n     */\n    public function close()\n    {\n        $this->gc(ini_get('session.gc_maxlifetime'));\n        $this->handler->close();\n        $this->handler = null;\n        return true;\n    }\n\n    /**\n     * 读取Session\n     * @access public\n     * @param string $sessID\n     */\n    public function read($sessID)\n    {\n        return (string) $this->handler->get($this->config['session_name'] . $sessID);\n    }\n\n    /**\n     * 写入Session\n     * @access public\n     * @param string    $sessID\n     * @param String    $sessData\n     * @return bool\n     */\n    public function write($sessID, $sessData)\n    {\n        return $this->handler->set($this->config['session_name'] . $sessID, $sessData, 0, $this->config['expire']);\n    }\n\n    /**\n     * 删除Session\n     * @access public\n     * @param string $sessID\n     * @return bool\n     */\n    public function destroy($sessID)\n    {\n        return $this->handler->delete($this->config['session_name'] . $sessID);\n    }\n\n    /**\n     * Session 垃圾回收\n     * @access public\n     * @param string $sessMaxLifeTime\n     * @return true\n     */\n    public function gc($sessMaxLifeTime)\n    {\n        return true;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/session/driver/Memcached.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\session\\driver;\n\nuse SessionHandler;\nuse think\\Exception;\n\nclass Memcached extends SessionHandler\n{\n    protected $handler = null;\n    protected $config  = [\n        'host'         => '127.0.0.1', // memcache主机\n        'port'         => 11211, // memcache端口\n        'expire'       => 3600, // session有效期\n        'timeout'      => 0, // 连接超时时间（单位：毫秒）\n        'session_name' => '', // memcache key前缀\n        'username'     => '', //账号\n        'password'     => '', //密码\n    ];\n\n    public function __construct($config = [])\n    {\n        $this->config = array_merge($this->config, $config);\n    }\n\n    /**\n     * 打开Session\n     * @access public\n     * @param string    $savePath\n     * @param mixed     $sessName\n     */\n    public function open($savePath, $sessName)\n    {\n        // 检测php环境\n        if (!extension_loaded('memcached')) {\n            throw new Exception('not support:memcached');\n        }\n        $this->handler = new \\Memcached;\n        // 设置连接超时时间（单位：毫秒）\n        if ($this->config['timeout'] > 0) {\n            $this->handler->setOption(\\Memcached::OPT_CONNECT_TIMEOUT, $this->config['timeout']);\n        }\n        // 支持集群\n        $hosts = explode(',', $this->config['host']);\n        $ports = explode(',', $this->config['port']);\n        if (empty($ports[0])) {\n            $ports[0] = 11211;\n        }\n        // 建立连接\n        $servers = [];\n        foreach ((array) $hosts as $i => $host) {\n            $servers[] = [$host, (isset($ports[$i]) ? $ports[$i] : $ports[0]), 1];\n        }\n        $this->handler->addServers($servers);\n        if ('' != $this->config['username']) {\n            $this->handler->setOption(\\Memcached::OPT_BINARY_PROTOCOL, true);\n            $this->handler->setSaslAuthData($this->config['username'], $this->config['password']);\n        }\n        return true;\n    }\n\n    /**\n     * 关闭Session\n     * @access public\n     */\n    public function close()\n    {\n        $this->gc(ini_get('session.gc_maxlifetime'));\n        $this->handler->quit();\n        $this->handler = null;\n        return true;\n    }\n\n    /**\n     * 读取Session\n     * @access public\n     * @param string $sessID\n     */\n    public function read($sessID)\n    {\n        return (string) $this->handler->get($this->config['session_name'] . $sessID);\n    }\n\n    /**\n     * 写入Session\n     * @access public\n     * @param string $sessID\n     * @param String $sessData\n     * @return bool\n     */\n    public function write($sessID, $sessData)\n    {\n        return $this->handler->set($this->config['session_name'] . $sessID, $sessData, $this->config['expire']);\n    }\n\n    /**\n     * 删除Session\n     * @access public\n     * @param string $sessID\n     * @return bool\n     */\n    public function destroy($sessID)\n    {\n        return $this->handler->delete($this->config['session_name'] . $sessID);\n    }\n\n    /**\n     * Session 垃圾回收\n     * @access public\n     * @param string $sessMaxLifeTime\n     * @return true\n     */\n    public function gc($sessMaxLifeTime)\n    {\n        return true;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/session/driver/Redis.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\session\\driver;\n\nuse SessionHandler;\nuse think\\Exception;\n\nclass Redis extends SessionHandler\n{\n    /** @var \\Redis */\n    protected $handler = null;\n    protected $config  = [\n        'host'         => '127.0.0.1', // redis主机\n        'port'         => 6379, // redis端口\n        'password'     => '', // 密码\n        'select'       => 0, // 操作库\n        'expire'       => 3600, // 有效期(秒)\n        'timeout'      => 0, // 超时时间(秒)\n        'persistent'   => true, // 是否长连接\n        'session_name' => '', // sessionkey前缀\n    ];\n\n    public function __construct($config = [])\n    {\n        $this->config = array_merge($this->config, $config);\n    }\n\n    /**\n     * 打开Session\n     * @access public\n     * @param string $savePath\n     * @param mixed  $sessName\n     * @return bool\n     * @throws Exception\n     */\n    public function open($savePath, $sessName)\n    {\n        // 检测php环境\n        if (!extension_loaded('redis')) {\n            throw new Exception('not support:redis');\n        }\n        $this->handler = new \\Redis;\n\n        // 建立连接\n        $func = $this->config['persistent'] ? 'pconnect' : 'connect';\n        $this->handler->$func($this->config['host'], $this->config['port'], $this->config['timeout']);\n\n        if ('' != $this->config['password']) {\n            $this->handler->auth($this->config['password']);\n        }\n\n        if (0 != $this->config['select']) {\n            $this->handler->select($this->config['select']);\n        }\n\n        return true;\n    }\n\n    /**\n     * 关闭Session\n     * @access public\n     */\n    public function close()\n    {\n        $this->gc(ini_get('session.gc_maxlifetime'));\n        $this->handler->close();\n        $this->handler = null;\n        return true;\n    }\n\n    /**\n     * 读取Session\n     * @access public\n     * @param string $sessID\n     * @return string\n     */\n    public function read($sessID)\n    {\n        return (string) $this->handler->get($this->config['session_name'] . $sessID);\n    }\n\n    /**\n     * 写入Session\n     * @access public\n     * @param string $sessID\n     * @param String $sessData\n     * @return bool\n     */\n    public function write($sessID, $sessData)\n    {\n        if ($this->config['expire'] > 0) {\n            return $this->handler->setex($this->config['session_name'] . $sessID, $this->config['expire'], $sessData);\n        } else {\n            return $this->handler->set($this->config['session_name'] . $sessID, $sessData);\n        }\n    }\n\n    /**\n     * 删除Session\n     * @access public\n     * @param string $sessID\n     * @return bool\n     */\n    public function destroy($sessID)\n    {\n        return $this->handler->delete($this->config['session_name'] . $sessID) > 0;\n    }\n\n    /**\n     * Session 垃圾回收\n     * @access public\n     * @param string $sessMaxLifeTime\n     * @return bool\n     */\n    public function gc($sessMaxLifeTime)\n    {\n        return true;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/template/TagLib.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\template;\n\nuse think\\Exception;\n\n/**\n * ThinkPHP标签库TagLib解析基类\n * @category   Think\n * @package  Think\n * @subpackage  Template\n * @author    liu21st <liu21st@gmail.com>\n */\nclass TagLib\n{\n\n    /**\n     * 标签库定义XML文件\n     * @var string\n     * @access protected\n     */\n    protected $xml  = '';\n    protected $tags = []; // 标签定义\n    /**\n     * 标签库名称\n     * @var string\n     * @access protected\n     */\n    protected $tagLib = '';\n\n    /**\n     * 标签库标签列表\n     * @var array\n     * @access protected\n     */\n    protected $tagList = [];\n\n    /**\n     * 标签库分析数组\n     * @var array\n     * @access protected\n     */\n    protected $parse = [];\n\n    /**\n     * 标签库是否有效\n     * @var bool\n     * @access protected\n     */\n    protected $valid = false;\n\n    /**\n     * 当前模板对象\n     * @var object\n     * @access protected\n     */\n    protected $tpl;\n\n    protected $comparison = [' nheq ' => ' !== ', ' heq ' => ' === ', ' neq ' => ' != ', ' eq ' => ' == ', ' egt ' => ' >= ', ' gt ' => ' > ', ' elt ' => ' <= ', ' lt ' => ' < '];\n\n    /**\n     * 构造函数\n     * @access public\n     * @param \\stdClass $template 模板引擎对象\n     */\n    public function __construct($template)\n    {\n        $this->tpl = $template;\n    }\n\n    /**\n     * 按签标库替换页面中的标签\n     * @access public\n     * @param  string $content 模板内容\n     * @param  string $lib 标签库名\n     * @return void\n     */\n    public function parseTag(&$content, $lib = '')\n    {\n        $tags = [];\n        $lib  = $lib ? strtolower($lib) . ':' : '';\n        foreach ($this->tags as $name => $val) {\n            $close                      = !isset($val['close']) || $val['close'] ? 1 : 0;\n            $tags[$close][$lib . $name] = $name;\n            if (isset($val['alias'])) {\n                // 别名设置\n                $array = (array) $val['alias'];\n                foreach (explode(',', $array[0]) as $v) {\n                    $tags[$close][$lib . $v] = $name;\n                }\n            }\n        }\n\n        // 闭合标签\n        if (!empty($tags[1])) {\n            $nodes = [];\n            $regex = $this->getRegex(array_keys($tags[1]), 1);\n            if (preg_match_all($regex, $content, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE)) {\n                $right = [];\n                foreach ($matches as $match) {\n                    if ('' == $match[1][0]) {\n                        $name = strtolower($match[2][0]);\n                        // 如果有没闭合的标签头则取出最后一个\n                        if (!empty($right[$name])) {\n                            // $match[0][1]为标签结束符在模板中的位置\n                            $nodes[$match[0][1]] = [\n                                'name'  => $name,\n                                'begin' => array_pop($right[$name]), // 标签开始符\n                                'end'   => $match[0], // 标签结束符\n                            ];\n                        }\n                    } else {\n                        // 标签头压入栈\n                        $right[strtolower($match[1][0])][] = $match[0];\n                    }\n                }\n                unset($right, $matches);\n                // 按标签在模板中的位置从后向前排序\n                krsort($nodes);\n            }\n\n            $break = '<!--###break###--!>';\n            if ($nodes) {\n                $beginArray = [];\n                // 标签替换 从后向前\n                foreach ($nodes as $pos => $node) {\n                    // 对应的标签名\n                    $name  = $tags[1][$node['name']];\n                    $alias = $lib . $name != $node['name'] ? ($lib ? strstr($node['name'], $lib) : $node['name']) : '';\n                    // 解析标签属性\n                    $attrs  = $this->parseAttr($node['begin'][0], $name, $alias);\n                    $method = 'tag' . $name;\n                    // 读取标签库中对应的标签内容 replace[0]用来替换标签头，replace[1]用来替换标签尾\n                    $replace = explode($break, $this->$method($attrs, $break));\n                    if (count($replace) > 1) {\n                        while ($beginArray) {\n                            $begin = end($beginArray);\n                            // 判断当前标签尾的位置是否在栈中最后一个标签头的后面，是则为子标签\n                            if ($node['end'][1] > $begin['pos']) {\n                                break;\n                            } else {\n                                // 不为子标签时，取出栈中最后一个标签头\n                                $begin = array_pop($beginArray);\n                                // 替换标签头部\n                                $content = substr_replace($content, $begin['str'], $begin['pos'], $begin['len']);\n                            }\n                        }\n                        // 替换标签尾部\n                        $content = substr_replace($content, $replace[1], $node['end'][1], strlen($node['end'][0]));\n                        // 把标签头压入栈\n                        $beginArray[] = ['pos' => $node['begin'][1], 'len' => strlen($node['begin'][0]), 'str' => $replace[0]];\n                    }\n                }\n                while ($beginArray) {\n                    $begin = array_pop($beginArray);\n                    // 替换标签头部\n                    $content = substr_replace($content, $begin['str'], $begin['pos'], $begin['len']);\n                }\n            }\n        }\n        // 自闭合标签\n        if (!empty($tags[0])) {\n            $regex   = $this->getRegex(array_keys($tags[0]), 0);\n            $content = preg_replace_callback($regex, function ($matches) use (&$tags, &$lib) {\n                // 对应的标签名\n                $name  = $tags[0][strtolower($matches[1])];\n                $alias = $lib . $name != $matches[1] ? ($lib ? strstr($matches[1], $lib) : $matches[1]) : '';\n                // 解析标签属性\n                $attrs  = $this->parseAttr($matches[0], $name, $alias);\n                $method = 'tag' . $name;\n                return $this->$method($attrs, '');\n            }, $content);\n        }\n        return;\n    }\n\n    /**\n     * 按标签生成正则\n     * @access private\n     * @param  array|string     $tags 标签名\n     * @param  boolean          $close 是否为闭合标签\n     * @return string\n     */\n    public function getRegex($tags, $close)\n    {\n        $begin   = $this->tpl->config('taglib_begin');\n        $end     = $this->tpl->config('taglib_end');\n        $single  = strlen(ltrim($begin, '\\\\')) == 1 && strlen(ltrim($end, '\\\\')) == 1 ? true : false;\n        $tagName = is_array($tags) ? implode('|', $tags) : $tags;\n        if ($single) {\n            if ($close) {\n                // 如果是闭合标签\n                $regex = $begin . '(?:(' . $tagName . ')\\b(?>[^' . $end . ']*)|\\/(' . $tagName . '))' . $end;\n            } else {\n                $regex = $begin . '(' . $tagName . ')\\b(?>[^' . $end . ']*)' . $end;\n            }\n        } else {\n            if ($close) {\n                // 如果是闭合标签\n                $regex = $begin . '(?:(' . $tagName . ')\\b(?>(?:(?!' . $end . ').)*)|\\/(' . $tagName . '))' . $end;\n            } else {\n                $regex = $begin . '(' . $tagName . ')\\b(?>(?:(?!' . $end . ').)*)' . $end;\n            }\n        }\n        return '/' . $regex . '/is';\n    }\n\n    /**\n     * 分析标签属性 正则方式\n     * @access public\n     * @param string $str 标签属性字符串\n     * @param string $name 标签名\n     * @param string $alias 别名\n     * @return array\n     */\n    public function parseAttr($str, $name, $alias = '')\n    {\n        $regex  = '/\\s+(?>(?P<name>[\\w-]+)\\s*)=(?>\\s*)([\\\"\\'])(?P<value>(?:(?!\\\\2).)*)\\\\2/is';\n        $result = [];\n        if (preg_match_all($regex, $str, $matches)) {\n            foreach ($matches['name'] as $key => $val) {\n                $result[$val] = $matches['value'][$key];\n            }\n            if (!isset($this->tags[$name])) {\n                // 检测是否存在别名定义\n                foreach ($this->tags as $key => $val) {\n                    if (isset($val['alias'])) {\n                        $array = (array) $val['alias'];\n                        if (in_array($name, explode(',', $array[0]))) {\n                            $tag           = $val;\n                            $type          = !empty($array[1]) ? $array[1] : 'type';\n                            $result[$type] = $name;\n                            break;\n                        }\n                    }\n                }\n            } else {\n                $tag = $this->tags[$name];\n                // 设置了标签别名\n                if (!empty($alias) && isset($tag['alias'])) {\n                    $type          = !empty($tag['alias'][1]) ? $tag['alias'][1] : 'type';\n                    $result[$type] = $alias;\n                }\n            }\n            if (!empty($tag['must'])) {\n                $must = explode(',', $tag['must']);\n                foreach ($must as $name) {\n                    if (!isset($result[$name])) {\n                        throw new Exception('tag attr must:' . $name);\n                    }\n                }\n            }\n        } else {\n            // 允许直接使用表达式的标签\n            if (!empty($this->tags[$name]['expression'])) {\n                static $_taglibs;\n                if (!isset($_taglibs[$name])) {\n                    $_taglibs[$name][0] = strlen(ltrim($this->tpl->config('taglib_begin'), '\\\\') . $name);\n                    $_taglibs[$name][1] = strlen(ltrim($this->tpl->config('taglib_end'), '\\\\'));\n                }\n                $result['expression'] = substr($str, $_taglibs[$name][0], -$_taglibs[$name][1]);\n                // 清除自闭合标签尾部/\n                $result['expression'] = rtrim($result['expression'], '/');\n                $result['expression'] = trim($result['expression']);\n            } elseif (empty($this->tags[$name]) || !empty($this->tags[$name]['attr'])) {\n                throw new Exception('tag error:' . $name);\n            }\n        }\n        return $result;\n    }\n\n    /**\n     * 解析条件表达式\n     * @access public\n     * @param  string $condition 表达式标签内容\n     * @return string\n     */\n    public function parseCondition($condition)\n    {\n        if (strpos($condition, ':')) {\n            $condition = ' ' . substr(strstr($condition, ':'), 1);\n        }\n        $condition = str_ireplace(array_keys($this->comparison), array_values($this->comparison), $condition);\n        $this->tpl->parseVar($condition);\n        // $this->tpl->parseVarFunction($condition); // XXX: 此句能解析表达式中用|分隔的函数，但表达式中如果有|、||这样的逻辑运算就产生了歧异\n        return $condition;\n    }\n\n    /**\n     * 自动识别构建变量\n     * @access public\n     * @param string $name 变量描述\n     * @return string\n     */\n    public function autoBuildVar(&$name)\n    {\n        $flag = substr($name, 0, 1);\n        if (':' == $flag) {\n            // 以:开头为函数调用，解析前去掉:\n            $name = substr($name, 1);\n        } elseif ('$' != $flag && preg_match('/[a-zA-Z_]/', $flag)) {\n            // XXX: 这句的写法可能还需要改进\n            // 常量不需要解析\n            if (defined($name)) {\n                return $name;\n            }\n            // 不以$开头并且也不是常量，自动补上$前缀\n            $name = '$' . $name;\n        }\n        $this->tpl->parseVar($name);\n        $this->tpl->parseVarFunction($name);\n        return $name;\n    }\n\n    /**\n     * 获取标签列表\n     * @access public\n     * @return array\n     */\n    // 获取标签定义\n    public function getTags()\n    {\n        return $this->tags;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/template/driver/File.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\template\\driver;\n\nuse think\\Exception;\n\nclass File\n{\n    /**\n     * 写入编译缓存\n     * @param string $cacheFile 缓存的文件名\n     * @param string $content 缓存的内容\n     * @return void|array\n     */\n    public function write($cacheFile, $content)\n    {\n        // 检测模板目录\n        $dir = dirname($cacheFile);\n        if (!is_dir($dir)) {\n            mkdir($dir, 0755, true);\n        }\n        // 生成模板缓存文件\n        if (false === file_put_contents($cacheFile, $content)) {\n            throw new Exception('cache write error:' . $cacheFile, 11602);\n        }\n    }\n\n    /**\n     * 读取编译编译\n     * @param string  $cacheFile 缓存的文件名\n     * @param array   $vars 变量数组\n     * @return void\n     */\n    public function read($cacheFile, $vars = [])\n    {\n        if (!empty($vars) && is_array($vars)) {\n            // 模板阵列变量分解成为独立变量\n            extract($vars, EXTR_OVERWRITE);\n        }\n        //载入模版缓存文件\n        include $cacheFile;\n    }\n\n    /**\n     * 检查编译缓存是否有效\n     * @param string  $cacheFile 缓存的文件名\n     * @param int     $cacheTime 缓存时间\n     * @return boolean\n     */\n    public function check($cacheFile, $cacheTime)\n    {\n        // 缓存文件不存在, 直接返回false\n        if (!file_exists($cacheFile)) {\n            return false;\n        }\n        if (0 != $cacheTime && $_SERVER['REQUEST_TIME'] > filemtime($cacheFile) + $cacheTime) {\n            // 缓存是否在有效期\n            return false;\n        }\n        return true;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/template/taglib/Cx.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK IT ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006-2016 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\template\\taglib;\n\nuse think\\template\\TagLib;\n\n/**\n * CX标签库解析类\n * @category   Think\n * @package  Think\n * @subpackage  Driver.Taglib\n * @author    liu21st <liu21st@gmail.com>\n */\nclass Cx extends Taglib\n{\n\n    // 标签定义\n    protected $tags = [\n        // 标签定义： attr 属性列表 close 是否闭合（0 或者1 默认1） alias 标签别名 level 嵌套层次\n        'php'        => ['attr' => ''],\n        'volist'     => ['attr' => 'name,id,offset,length,key,mod', 'alias' => 'iterate'],\n        'foreach'    => ['attr' => 'name,id,item,key,offset,length,mod', 'expression' => true],\n        'if'         => ['attr' => 'condition', 'expression' => true],\n        'elseif'     => ['attr' => 'condition', 'close' => 0, 'expression' => true],\n        'else'       => ['attr' => '', 'close' => 0],\n        'switch'     => ['attr' => 'name', 'expression' => true],\n        'case'       => ['attr' => 'value,break', 'expression' => true],\n        'default'    => ['attr' => '', 'close' => 0],\n        'compare'    => ['attr' => 'name,value,type', 'alias' => ['eq,equal,notequal,neq,gt,lt,egt,elt,heq,nheq', 'type']],\n        'range'      => ['attr' => 'name,value,type', 'alias' => ['in,notin,between,notbetween', 'type']],\n        'empty'      => ['attr' => 'name'],\n        'notempty'   => ['attr' => 'name'],\n        'present'    => ['attr' => 'name'],\n        'notpresent' => ['attr' => 'name'],\n        'defined'    => ['attr' => 'name'],\n        'notdefined' => ['attr' => 'name'],\n        'load'       => ['attr' => 'file,href,type,value,basepath', 'close' => 0, 'alias' => ['import,css,js', 'type']],\n        'assign'     => ['attr' => 'name,value', 'close' => 0],\n        'define'     => ['attr' => 'name,value', 'close' => 0],\n        'for'        => ['attr' => 'start,end,name,comparison,step'],\n        'url'        => ['attr' => 'link,vars,suffix,domain', 'close' => 0, 'expression' => true],\n        'function'   => ['attr' => 'name,vars,use,call'],\n    ];\n\n    /**\n     * php标签解析\n     * 格式：\n     * {php}echo $name{/php}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagPhp($tag, $content)\n    {\n        $parseStr = '<?php ' . $content . ' ?>';\n        return $parseStr;\n    }\n\n    /**\n     * volist标签解析 循环输出数据集\n     * 格式：\n     * {volist name=\"userList\" id=\"user\" empty=\"\"}\n     * {user.username}\n     * {user.email}\n     * {/volist}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string|void\n     */\n    public function tagVolist($tag, $content)\n    {\n        $name   = $tag['name'];\n        $id     = $tag['id'];\n        $empty  = isset($tag['empty']) ? $tag['empty'] : '';\n        $key    = !empty($tag['key']) ? $tag['key'] : 'i';\n        $mod    = isset($tag['mod']) ? $tag['mod'] : '2';\n        $offset = !empty($tag['offset']) && is_numeric($tag['offset']) ? intval($tag['offset']) : 0;\n        $length = !empty($tag['length']) && is_numeric($tag['length']) ? intval($tag['length']) : 'null';\n        // 允许使用函数设定数据集 <volist name=\":fun('arg')\" id=\"vo\">{$vo.name}</volist>\n        $parseStr = '<?php ';\n        $flag     = substr($name, 0, 1);\n        if (':' == $flag) {\n            $name = $this->autoBuildVar($name);\n            $parseStr .= '$_result=' . $name . ';';\n            $name = '$_result';\n        } else {\n            $name = $this->autoBuildVar($name);\n        }\n\n        $parseStr .= 'if(is_array(' . $name . ') || ' . $name . ' instanceof \\think\\Collection || ' . $name . ' instanceof \\think\\Paginator): $' . $key . ' = 0;';\n        // 设置了输出数组长度\n        if (0 != $offset || 'null' != $length) {\n            $parseStr .= '$__LIST__ = is_array(' . $name . ') ? array_slice(' . $name . ',' . $offset . ',' . $length . ', true) : ' . $name . '->slice(' . $offset . ',' . $length . ', true); ';\n        } else {\n            $parseStr .= ' $__LIST__ = ' . $name . ';';\n        }\n        $parseStr .= 'if( count($__LIST__)==0 ) : echo \"' . $empty . '\" ;';\n        $parseStr .= 'else: ';\n        $parseStr .= 'foreach($__LIST__ as $key=>$' . $id . '): ';\n        $parseStr .= '$mod = ($' . $key . ' % ' . $mod . ' );';\n        $parseStr .= '++$' . $key . ';?>';\n        $parseStr .= $content;\n        $parseStr .= '<?php endforeach; endif; else: echo \"' . $empty . '\" ;endif; ?>';\n\n        if (!empty($parseStr)) {\n            return $parseStr;\n        }\n        return;\n    }\n\n    /**\n     * foreach标签解析 循环输出数据集\n     * 格式：\n     * {foreach name=\"userList\" id=\"user\" key=\"key\" index=\"i\" mod=\"2\" offset=\"3\" length=\"5\" empty=\"\"}\n     * {user.username}\n     * {/foreach}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string|void\n     */\n    public function tagForeach($tag, $content)\n    {\n        // 直接使用表达式\n        if (!empty($tag['expression'])) {\n            $expression = ltrim(rtrim($tag['expression'], ')'), '(');\n            $expression = $this->autoBuildVar($expression);\n            $parseStr   = '<?php foreach(' . $expression . '): ?>';\n            $parseStr .= $content;\n            $parseStr .= '<?php endforeach; ?>';\n            return $parseStr;\n        }\n        $name   = $tag['name'];\n        $key    = !empty($tag['key']) ? $tag['key'] : 'key';\n        $item   = !empty($tag['id']) ? $tag['id'] : $tag['item'];\n        $empty  = isset($tag['empty']) ? $tag['empty'] : '';\n        $offset = !empty($tag['offset']) && is_numeric($tag['offset']) ? intval($tag['offset']) : 0;\n        $length = !empty($tag['length']) && is_numeric($tag['length']) ? intval($tag['length']) : 'null';\n\n        $parseStr = '<?php ';\n        // 支持用函数传数组\n        if (':' == substr($name, 0, 1)) {\n            $var  = '$_' . uniqid();\n            $name = $this->autoBuildVar($name);\n            $parseStr .= $var . '=' . $name . '; ';\n            $name = $var;\n        } else {\n            $name = $this->autoBuildVar($name);\n        }\n        $parseStr .= 'if(is_array(' . $name . ') || ' . $name . ' instanceof \\think\\Collection || ' . $name . ' instanceof \\think\\Paginator): ';\n        // 设置了输出数组长度\n        if (0 != $offset || 'null' != $length) {\n            if (!isset($var)) {\n                $var = '$_' . uniqid();\n            }\n            $parseStr .= $var . ' = is_array(' . $name . ') ? array_slice(' . $name . ',' . $offset . ',' . $length . ', true) : ' . $name . '->slice(' . $offset . ',' . $length . ', true); ';\n        } else {\n            $var = &$name;\n        }\n\n        $parseStr .= 'if( count(' . $var . ')==0 ) : echo \"' . $empty . '\" ;';\n        $parseStr .= 'else: ';\n\n        // 设置了索引项\n        if (isset($tag['index'])) {\n            $index = $tag['index'];\n            $parseStr .= '$' . $index . '=0; ';\n        }\n        $parseStr .= 'foreach(' . $var . ' as $' . $key . '=>$' . $item . '): ';\n        // 设置了索引项\n        if (isset($tag['index'])) {\n            $index = $tag['index'];\n            if (isset($tag['mod'])) {\n                $mod = (int) $tag['mod'];\n                $parseStr .= '$mod = ($' . $index . ' % ' . $mod . '); ';\n            }\n            $parseStr .= '++$' . $index . '; ';\n        }\n        $parseStr .= '?>';\n        // 循环体中的内容\n        $parseStr .= $content;\n        $parseStr .= '<?php endforeach; endif; else: echo \"' . $empty . '\" ;endif; ?>';\n\n        if (!empty($parseStr)) {\n            return $parseStr;\n        }\n        return;\n    }\n\n    /**\n     * if标签解析\n     * 格式：\n     * {if condition=\" $a eq 1\"}\n     * {elseif condition=\"$a eq 2\" /}\n     * {else /}\n     * {/if}\n     * 表达式支持 eq neq gt egt lt elt == > >= < <= or and || &&\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagIf($tag, $content)\n    {\n        $condition = !empty($tag['expression']) ? $tag['expression'] : $tag['condition'];\n        $condition = $this->parseCondition($condition);\n        $parseStr  = '<?php if(' . $condition . '): ?>' . $content . '<?php endif; ?>';\n        return $parseStr;\n    }\n\n    /**\n     * elseif标签解析\n     * 格式：见if标签\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagElseif($tag, $content)\n    {\n        $condition = !empty($tag['expression']) ? $tag['expression'] : $tag['condition'];\n        $condition = $this->parseCondition($condition);\n        $parseStr  = '<?php elseif(' . $condition . '): ?>';\n        return $parseStr;\n    }\n\n    /**\n     * else标签解析\n     * 格式：见if标签\n     * @access public\n     * @param array $tag 标签属性\n     * @return string\n     */\n    public function tagElse($tag)\n    {\n        $parseStr = '<?php else: ?>';\n        return $parseStr;\n    }\n\n    /**\n     * switch标签解析\n     * 格式：\n     * {switch name=\"a.name\"}\n     * {case value=\"1\" break=\"false\"}1{/case}\n     * {case value=\"2\" }2{/case}\n     * {default /}other\n     * {/switch}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagSwitch($tag, $content)\n    {\n        $name     = !empty($tag['expression']) ? $tag['expression'] : $tag['name'];\n        $name     = $this->autoBuildVar($name);\n        $parseStr = '<?php switch(' . $name . '): ?>' . $content . '<?php endswitch; ?>';\n        return $parseStr;\n    }\n\n    /**\n     * case标签解析 需要配合switch才有效\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagCase($tag, $content)\n    {\n        $value = !empty($tag['expression']) ? $tag['expression'] : $tag['value'];\n        $flag  = substr($value, 0, 1);\n        if ('$' == $flag || ':' == $flag) {\n            $value = $this->autoBuildVar($value);\n            $value = 'case ' . $value . ':';\n        } elseif (strpos($value, '|')) {\n            $values = explode('|', $value);\n            $value  = '';\n            foreach ($values as $val) {\n                $value .= 'case \"' . addslashes($val) . '\":';\n            }\n        } else {\n            $value = 'case \"' . $value . '\":';\n        }\n        $parseStr = '<?php ' . $value . ' ?>' . $content;\n        $isBreak  = isset($tag['break']) ? $tag['break'] : '';\n        if ('' == $isBreak || $isBreak) {\n            $parseStr .= '<?php break; ?>';\n        }\n        return $parseStr;\n    }\n\n    /**\n     * default标签解析 需要配合switch才有效\n     * 使用： {default /}ddfdf\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagDefault($tag)\n    {\n        $parseStr = '<?php default: ?>';\n        return $parseStr;\n    }\n\n    /**\n     * compare标签解析\n     * 用于值的比较 支持 eq neq gt lt egt elt heq nheq 默认是eq\n     * 格式： {compare name=\"\" type=\"eq\" value=\"\" }content{/compare}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagCompare($tag, $content)\n    {\n        $name  = $tag['name'];\n        $value = $tag['value'];\n        $type  = isset($tag['type']) ? $tag['type'] : 'eq'; // 比较类型\n        $name  = $this->autoBuildVar($name);\n        $flag  = substr($value, 0, 1);\n        if ('$' == $flag || ':' == $flag) {\n            $value = $this->autoBuildVar($value);\n        } else {\n            $value = '\\'' . $value . '\\'';\n        }\n        switch ($type) {\n            case 'equal':\n                $type = 'eq';\n                break;\n            case 'notequal':\n                $type = 'neq';\n                break;\n        }\n        $type     = $this->parseCondition(' ' . $type . ' ');\n        $parseStr = '<?php if(' . $name . ' ' . $type . ' ' . $value . '): ?>' . $content . '<?php endif; ?>';\n        return $parseStr;\n    }\n\n    /**\n     * range标签解析\n     * 如果某个变量存在于某个范围 则输出内容 type= in 表示在范围内 否则表示在范围外\n     * 格式： {range name=\"var|function\"  value=\"val\" type='in|notin' }content{/range}\n     * example: {range name=\"a\"  value=\"1,2,3\" type='in' }content{/range}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagRange($tag, $content)\n    {\n        $name  = $tag['name'];\n        $value = $tag['value'];\n        $type  = isset($tag['type']) ? $tag['type'] : 'in'; // 比较类型\n\n        $name = $this->autoBuildVar($name);\n        $flag = substr($value, 0, 1);\n        if ('$' == $flag || ':' == $flag) {\n            $value = $this->autoBuildVar($value);\n            $str   = 'is_array(' . $value . ')?' . $value . ':explode(\\',\\',' . $value . ')';\n        } else {\n            $value = '\"' . $value . '\"';\n            $str   = 'explode(\\',\\',' . $value . ')';\n        }\n        if ('between' == $type) {\n            $parseStr = '<?php $_RANGE_VAR_=' . $str . ';if(' . $name . '>= $_RANGE_VAR_[0] && ' . $name . '<= $_RANGE_VAR_[1]):?>' . $content . '<?php endif; ?>';\n        } elseif ('notbetween' == $type) {\n            $parseStr = '<?php $_RANGE_VAR_=' . $str . ';if(' . $name . '<$_RANGE_VAR_[0] || ' . $name . '>$_RANGE_VAR_[1]):?>' . $content . '<?php endif; ?>';\n        } else {\n            $fun      = ('in' == $type) ? 'in_array' : '!in_array';\n            $parseStr = '<?php if(' . $fun . '((' . $name . '), ' . $str . ')): ?>' . $content . '<?php endif; ?>';\n        }\n        return $parseStr;\n    }\n\n    /**\n     * present标签解析\n     * 如果某个变量已经设置 则输出内容\n     * 格式： {present name=\"\" }content{/present}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagPresent($tag, $content)\n    {\n        $name     = $tag['name'];\n        $name     = $this->autoBuildVar($name);\n        $parseStr = '<?php if(isset(' . $name . ')): ?>' . $content . '<?php endif; ?>';\n        return $parseStr;\n    }\n\n    /**\n     * notpresent标签解析\n     * 如果某个变量没有设置，则输出内容\n     * 格式： {notpresent name=\"\" }content{/notpresent}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagNotpresent($tag, $content)\n    {\n        $name     = $tag['name'];\n        $name     = $this->autoBuildVar($name);\n        $parseStr = '<?php if(!isset(' . $name . ')): ?>' . $content . '<?php endif; ?>';\n        return $parseStr;\n    }\n\n    /**\n     * empty标签解析\n     * 如果某个变量为empty 则输出内容\n     * 格式： {empty name=\"\" }content{/empty}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagEmpty($tag, $content)\n    {\n        $name     = $tag['name'];\n        $name     = $this->autoBuildVar($name);\n        $parseStr = '<?php if(empty(' . $name . ') || ((' . $name . ' instanceof \\think\\Collection || ' . $name . ' instanceof \\think\\Paginator ) && ' . $name . '->isEmpty())): ?>' . $content . '<?php endif; ?>';\n        return $parseStr;\n    }\n\n    /**\n     * notempty标签解析\n     * 如果某个变量不为empty 则输出内容\n     * 格式： {notempty name=\"\" }content{/notempty}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagNotempty($tag, $content)\n    {\n        $name     = $tag['name'];\n        $name     = $this->autoBuildVar($name);\n        $parseStr = '<?php if(!(empty(' . $name . ') || ((' . $name . ' instanceof \\think\\Collection || ' . $name . ' instanceof \\think\\Paginator ) && ' . $name . '->isEmpty()))): ?>' . $content . '<?php endif; ?>';\n        return $parseStr;\n    }\n\n    /**\n     * 判断是否已经定义了该常量\n     * {defined name='TXT'}已定义{/defined}\n     * @param array $tag\n     * @param string $content\n     * @return string\n     */\n    public function tagDefined($tag, $content)\n    {\n        $name     = $tag['name'];\n        $parseStr = '<?php if(defined(\"' . $name . '\")): ?>' . $content . '<?php endif; ?>';\n        return $parseStr;\n    }\n\n    /**\n     * 判断是否没有定义了该常量\n     * {notdefined name='TXT'}已定义{/notdefined}\n     * @param array $tag\n     * @param string $content\n     * @return string\n     */\n    public function tagNotdefined($tag, $content)\n    {\n        $name     = $tag['name'];\n        $parseStr = '<?php if(!defined(\"' . $name . '\")): ?>' . $content . '<?php endif; ?>';\n        return $parseStr;\n    }\n\n    /**\n     * load 标签解析 {load file=\"/static/js/base.js\" /}\n     * 格式：{load file=\"/static/css/base.css\" /}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagLoad($tag, $content)\n    {\n        $file     = isset($tag['file']) ? $tag['file'] : $tag['href'];\n        $type     = isset($tag['type']) ? strtolower($tag['type']) : '';\n        $parseStr = '';\n        $endStr   = '';\n        // 判断是否存在加载条件 允许使用函数判断(默认为isset)\n        if (isset($tag['value'])) {\n            $name = $tag['value'];\n            $name = $this->autoBuildVar($name);\n            $name = 'isset(' . $name . ')';\n            $parseStr .= '<?php if(' . $name . '): ?>';\n            $endStr = '<?php endif; ?>';\n        }\n\n        // 文件方式导入\n        $array = explode(',', $file);\n        foreach ($array as $val) {\n            $type = strtolower(substr(strrchr($val, '.'), 1));\n            switch ($type) {\n                case 'js':\n                    $parseStr .= '<script type=\"text/javascript\" src=\"' . $val . '\"></script>';\n                    break;\n                case 'css':\n                    $parseStr .= '<link rel=\"stylesheet\" type=\"text/css\" href=\"' . $val . '\" />';\n                    break;\n                case 'php':\n                    $parseStr .= '<?php include \"' . $val . '\"; ?>';\n                    break;\n            }\n        }\n        return $parseStr . $endStr;\n    }\n\n    /**\n     * assign标签解析\n     * 在模板中给某个变量赋值 支持变量赋值\n     * 格式： {assign name=\"\" value=\"\" /}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagAssign($tag, $content)\n    {\n        $name = $this->autoBuildVar($tag['name']);\n        $flag = substr($tag['value'], 0, 1);\n        if ('$' == $flag || ':' == $flag) {\n            $value = $this->autoBuildVar($tag['value']);\n        } else {\n            $value = '\\'' . $tag['value'] . '\\'';\n        }\n        $parseStr = '<?php ' . $name . ' = ' . $value . '; ?>';\n        return $parseStr;\n    }\n\n    /**\n     * define标签解析\n     * 在模板中定义常量 支持变量赋值\n     * 格式： {define name=\"\" value=\"\" /}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagDefine($tag, $content)\n    {\n        $name = '\\'' . $tag['name'] . '\\'';\n        $flag = substr($tag['value'], 0, 1);\n        if ('$' == $flag || ':' == $flag) {\n            $value = $this->autoBuildVar($tag['value']);\n        } else {\n            $value = '\\'' . $tag['value'] . '\\'';\n        }\n        $parseStr = '<?php define(' . $name . ', ' . $value . '); ?>';\n        return $parseStr;\n    }\n\n    /**\n     * for标签解析\n     * 格式：\n     * {for start=\"\" end=\"\" comparison=\"\" step=\"\" name=\"\"}\n     * content\n     * {/for}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagFor($tag, $content)\n    {\n        //设置默认值\n        $start      = 0;\n        $end        = 0;\n        $step       = 1;\n        $comparison = 'lt';\n        $name       = 'i';\n        $rand       = rand(); //添加随机数，防止嵌套变量冲突\n        //获取属性\n        foreach ($tag as $key => $value) {\n            $value = trim($value);\n            $flag  = substr($value, 0, 1);\n            if ('$' == $flag || ':' == $flag) {\n                $value = $this->autoBuildVar($value);\n            }\n\n            switch ($key) {\n                case 'start':\n                    $start = $value;\n                    break;\n                case 'end':\n                    $end = $value;\n                    break;\n                case 'step':\n                    $step = $value;\n                    break;\n                case 'comparison':\n                    $comparison = $value;\n                    break;\n                case 'name':\n                    $name = $value;\n                    break;\n            }\n        }\n\n        $parseStr = '<?php $__FOR_START_' . $rand . '__=' . $start . ';$__FOR_END_' . $rand . '__=' . $end . ';';\n        $parseStr .= 'for($' . $name . '=$__FOR_START_' . $rand . '__;' . $this->parseCondition('$' . $name . ' ' . $comparison . ' $__FOR_END_' . $rand . '__') . ';$' . $name . '+=' . $step . '){ ?>';\n        $parseStr .= $content;\n        $parseStr .= '<?php } ?>';\n        return $parseStr;\n    }\n\n    /**\n     * url函数的tag标签\n     * 格式：{url link=\"模块/控制器/方法\" vars=\"参数\" suffix=\"true或者false 是否带有后缀\" domain=\"true或者false 是否携带域名\" /}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagUrl($tag, $content)\n    {\n        $url    = isset($tag['link']) ? $tag['link'] : '';\n        $vars   = isset($tag['vars']) ? $tag['vars'] : '';\n        $suffix = isset($tag['suffix']) ? $tag['suffix'] : 'true';\n        $domain = isset($tag['domain']) ? $tag['domain'] : 'false';\n        return '<?php echo url(\"' . $url . '\",\"' . $vars . '\",' . $suffix . ',' . $domain . ');?>';\n    }\n\n    /**\n     * function标签解析 匿名函数，可实现递归\n     * 使用：\n     * {function name=\"func\" vars=\"$data\" call=\"$list\" use=\"&$a,&$b\"}\n     *      {if is_array($data)}\n     *          {foreach $data as $val}\n     *              {~func($val) /}\n     *          {/foreach}\n     *      {else /}\n     *          {$data}\n     *      {/if}\n     * {/function}\n     * @access public\n     * @param array $tag 标签属性\n     * @param string $content 标签内容\n     * @return string\n     */\n    public function tagFunction($tag, $content)\n    {\n        $name = !empty($tag['name']) ? $tag['name'] : 'func';\n        $vars = !empty($tag['vars']) ? $tag['vars'] : '';\n        $call = !empty($tag['call']) ? $tag['call'] : '';\n        $use  = ['&$' . $name];\n        if (!empty($tag['use'])) {\n            foreach (explode(',', $tag['use']) as $val) {\n                $use[] = '&' . ltrim(trim($val), '&');\n            }\n        }\n        $parseStr = '<?php $' . $name . '=function(' . $vars . ') use(' . implode(',', $use) . ') {';\n        $parseStr .= ' ?>' . $content . '<?php }; ';\n        $parseStr .= $call ? '$' . $name . '(' . $call . '); ?>' : '?>';\n        return $parseStr;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/think/view/driver/Php.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\view\\driver;\n\nuse think\\App;\nuse think\\exception\\TemplateNotFoundException;\nuse think\\Loader;\nuse think\\Log;\nuse think\\Request;\n\nclass Php\n{\n    // 模板引擎参数\n    protected $config = [\n        // 视图基础目录（集中式）\n        'view_base'   => '',\n        // 模板起始路径\n        'view_path'   => '',\n        // 模板文件后缀\n        'view_suffix' => 'php',\n        // 模板文件名分隔符\n        'view_depr'   => DS,\n    ];\n\n    public function __construct($config = [])\n    {\n        $this->config = array_merge($this->config, $config);\n    }\n\n    /**\n     * 检测是否存在模板文件\n     * @access public\n     * @param string $template 模板文件或者模板规则\n     * @return bool\n     */\n    public function exists($template)\n    {\n        if ('' == pathinfo($template, PATHINFO_EXTENSION)) {\n            // 获取模板文件名\n            $template = $this->parseTemplate($template);\n        }\n        return is_file($template);\n    }\n\n    /**\n     * 渲染模板文件\n     * @access public\n     * @param string    $template 模板文件\n     * @param array     $data 模板变量\n     * @return void\n     */\n    public function fetch($template, $data = [])\n    {\n        if ('' == pathinfo($template, PATHINFO_EXTENSION)) {\n            // 获取模板文件名\n            $template = $this->parseTemplate($template);\n        }\n        // 模板不存在 抛出异常\n        if (!is_file($template)) {\n            throw new TemplateNotFoundException('template not exists:' . $template, $template);\n        }\n        // 记录视图信息\n        App::$debug && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]', 'info');\n        if (isset($data['template'])) {\n            $__template__ = $template;\n            extract($data, EXTR_OVERWRITE);\n            include $__template__;\n        } else {\n            extract($data, EXTR_OVERWRITE);\n            include $template;\n        }\n    }\n\n    /**\n     * 渲染模板内容\n     * @access public\n     * @param string    $content 模板内容\n     * @param array     $data 模板变量\n     * @return void\n     */\n    public function display($content, $data = [])\n    {\n        if (isset($data['content'])) {\n            $__content__ = $content;\n            extract($data, EXTR_OVERWRITE);\n            eval('?>' . $__content__);\n        } else {\n            extract($data, EXTR_OVERWRITE);\n            eval('?>' . $content);\n        }\n    }\n\n    /**\n     * 自动定位模板文件\n     * @access private\n     * @param string $template 模板文件规则\n     * @return string\n     */\n    private function parseTemplate($template)\n    {\n        if (empty($this->config['view_path'])) {\n            $this->config['view_path'] = App::$modulePath . 'view' . DS;\n        }\n\n        $request = Request::instance();\n        // 获取视图根目录\n        if (strpos($template, '@')) {\n            // 跨模块调用\n            list($module, $template) = explode('@', $template);\n        }\n        if ($this->config['view_base']) {\n            // 基础视图目录\n            $module = isset($module) ? $module : $request->module();\n            $path   = $this->config['view_base'] . ($module ? $module . DS : '');\n        } else {\n            $path = isset($module) ? APP_PATH . $module . DS . 'view' . DS : $this->config['view_path'];\n        }\n\n        $depr = $this->config['view_depr'];\n        if (0 !== strpos($template, '/')) {\n            $template   = str_replace(['/', ':'], $depr, $template);\n            $controller = Loader::parseName($request->controller());\n            if ($controller) {\n                if ('' == $template) {\n                    // 如果模板文件名为空 按照默认规则定位\n                    $template = str_replace('.', DS, $controller) . $depr . $request->action();\n                } elseif (false === strpos($template, $depr)) {\n                    $template = str_replace('.', DS, $controller) . $depr . $template;\n                }\n            }\n        } else {\n            $template = str_replace(['/', ':'], $depr, substr($template, 1));\n        }\n        return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');\n    }\n\n    /**\n     * 配置模板引擎\n     * @access private\n     * @param string|array  $name 参数名\n     * @param mixed         $value 参数值\n     * @return void\n     */\n    public function config($name, $value = null)\n    {\n        if (is_array($name)) {\n            $this->config = array_merge($this->config, $name);\n        } elseif (is_null($value)) {\n            return isset($this->config[$name]) ? $this->config[$name] : null;\n        } else {\n            $this->config[$name] = $value;\n        }\n    }\n\n}\n"
  },
  {
    "path": "thinkphp/library/think/view/driver/Think.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think\\view\\driver;\n\nuse think\\App;\nuse think\\exception\\TemplateNotFoundException;\nuse think\\Loader;\nuse think\\Log;\nuse think\\Request;\nuse think\\Template;\n\nclass Think\n{\n    // 模板引擎实例\n    private $template;\n    // 模板引擎参数\n    protected $config = [\n        // 视图基础目录（集中式）\n        'view_base'   => '',\n        // 模板起始路径\n        'view_path'   => '',\n        // 模板文件后缀\n        'view_suffix' => 'html',\n        // 模板文件名分隔符\n        'view_depr'   => DS,\n        // 是否开启模板编译缓存,设为false则每次都会重新编译\n        'tpl_cache'   => true,\n    ];\n\n    public function __construct($config = [])\n    {\n        $this->config = array_merge($this->config, $config);\n        if (empty($this->config['view_path'])) {\n            $this->config['view_path'] = App::$modulePath . 'view' . DS;\n        }\n\n        $this->template = new Template($this->config);\n    }\n\n    /**\n     * 检测是否存在模板文件\n     * @access public\n     * @param string $template 模板文件或者模板规则\n     * @return bool\n     */\n    public function exists($template)\n    {\n        if ('' == pathinfo($template, PATHINFO_EXTENSION)) {\n            // 获取模板文件名\n            $template = $this->parseTemplate($template);\n        }\n        return is_file($template);\n    }\n\n    /**\n     * 渲染模板文件\n     * @access public\n     * @param string    $template 模板文件\n     * @param array     $data 模板变量\n     * @param array     $config 模板参数\n     * @return void\n     */\n    public function fetch($template, $data = [], $config = [])\n    {\n        if ('' == pathinfo($template, PATHINFO_EXTENSION)) {\n            // 获取模板文件名\n            $template = $this->parseTemplate($template);\n        }\n        // 模板不存在 抛出异常\n        if (!is_file($template)) {\n            throw new TemplateNotFoundException('template not exists:' . $template, $template);\n        }\n        // 记录视图信息\n        App::$debug && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]', 'info');\n        $this->template->fetch($template, $data, $config);\n    }\n\n    /**\n     * 渲染模板内容\n     * @access public\n     * @param string    $template 模板内容\n     * @param array     $data 模板变量\n     * @param array     $config 模板参数\n     * @return void\n     */\n    public function display($template, $data = [], $config = [])\n    {\n        $this->template->display($template, $data, $config);\n    }\n\n    /**\n     * 自动定位模板文件\n     * @access private\n     * @param string $template 模板文件规则\n     * @return string\n     */\n    private function parseTemplate($template)\n    {\n        // 分析模板文件规则\n        $request = Request::instance();\n        // 获取视图根目录\n        if (strpos($template, '@')) {\n            // 跨模块调用\n            list($module, $template) = explode('@', $template);\n        }\n        if ($this->config['view_base']) {\n            // 基础视图目录\n            $module = isset($module) ? $module : $request->module();\n            $path   = $this->config['view_base'] . ($module ? $module . DS : '');\n        } else {\n            $path = isset($module) ? APP_PATH . $module . DS . 'view' . DS : $this->config['view_path'];\n        }\n\n        $depr = $this->config['view_depr'];\n        if (0 !== strpos($template, '/')) {\n            $template   = str_replace(['/', ':'], $depr, $template);\n            $controller = Loader::parseName($request->controller());\n            if ($controller) {\n                if ('' == $template) {\n                    // 如果模板文件名为空 按照默认规则定位\n                    $template = str_replace('.', DS, $controller) . $depr . $request->action();\n                } elseif (false === strpos($template, $depr)) {\n                    $template = str_replace('.', DS, $controller) . $depr . $template;\n                }\n            }\n        } else {\n            $template = str_replace(['/', ':'], $depr, substr($template, 1));\n        }\n        return $path . ltrim($template, '/') . '.' . ltrim($this->config['view_suffix'], '.');\n    }\n\n    /**\n     * 配置或者获取模板引擎参数\n     * @access private\n     * @param string|array  $name 参数名\n     * @param mixed         $value 参数值\n     * @return mixed\n     */\n    public function config($name, $value = null)\n    {\n        if (is_array($name)) {\n            $this->template->config($name);\n            $this->config = array_merge($this->config, $name);\n        } elseif (is_null($value)) {\n            return $this->template->config($name);\n        } else {\n            $this->template->$name = $value;\n            $this->config[$name]   = $value;\n        }\n    }\n\n    public function __call($method, $params)\n    {\n        return call_user_func_array([$this->template, $method], $params);\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/traits/controller/Jump.php",
    "content": "<?php\n\n/**\n * 用法：\n * load_trait('controller/Jump');\n * class index\n * {\n *     use \\traits\\controller\\Jump;\n *     public function index(){\n *         $this->error();\n *         $this->redirect();\n *     }\n * }\n */\nnamespace traits\\controller;\n\nuse think\\Config;\nuse think\\exception\\HttpResponseException;\nuse think\\Request;\nuse think\\Response;\nuse think\\response\\Redirect;\nuse think\\Url;\nuse think\\View as ViewTemplate;\n\ntrait Jump\n{\n    /**\n     * 操作成功跳转的快捷方法\n     * @access protected\n     * @param mixed     $msg 提示信息\n     * @param string    $url 跳转的URL地址\n     * @param mixed     $data 返回的数据\n     * @param integer   $wait 跳转等待时间\n     * @param array     $header 发送的Header信息\n     * @return void\n     */\n    protected function success($msg = '', $url = null, $data = '', $wait = 3, array $header = [])\n    {\n        $code = 1;\n        if (is_numeric($msg)) {\n            $code = $msg;\n            $msg  = '';\n        }\n        if (is_null($url) && isset($_SERVER[\"HTTP_REFERER\"])) {\n            $url = $_SERVER[\"HTTP_REFERER\"];\n        } elseif ('' !== $url) {\n            $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : Url::build($url);\n        }\n        $result = [\n            'code' => $code,\n            'msg'  => $msg,\n            'data' => $data,\n            'url'  => $url,\n            'wait' => $wait,\n        ];\n\n        $type = $this->getResponseType();\n        if ('html' == strtolower($type)) {\n            $result = ViewTemplate::instance(Config::get('template'), Config::get('view_replace_str'))\n                ->fetch(Config::get('dispatch_success_tmpl'), $result);\n        }\n        $response = Response::create($result, $type)->header($header);\n        throw new HttpResponseException($response);\n    }\n\n    /**\n     * 操作错误跳转的快捷方法\n     * @access protected\n     * @param mixed     $msg 提示信息\n     * @param string    $url 跳转的URL地址\n     * @param mixed     $data 返回的数据\n     * @param integer   $wait 跳转等待时间\n     * @param array     $header 发送的Header信息\n     * @return void\n     */\n    protected function error($msg = '', $url = null, $data = '', $wait = 3, array $header = [])\n    {\n        $code = 0;\n        if (is_numeric($msg)) {\n            $code = $msg;\n            $msg  = '';\n        }\n        if (is_null($url)) {\n            $url = Request::instance()->isAjax() ? '' : 'javascript:history.back(-1);';\n        } elseif ('' !== $url) {\n            $url = (strpos($url, '://') || 0 === strpos($url, '/')) ? $url : Url::build($url);\n        }\n        $result = [\n            'code' => $code,\n            'msg'  => $msg,\n            'data' => $data,\n            'url'  => $url,\n            'wait' => $wait,\n        ];\n\n        $type = $this->getResponseType();\n        if ('html' == strtolower($type)) {\n            $result = ViewTemplate::instance(Config::get('template'), Config::get('view_replace_str'))\n                ->fetch(Config::get('dispatch_error_tmpl'), $result);\n        }\n        $response = Response::create($result, $type)->header($header);\n        throw new HttpResponseException($response);\n    }\n\n    /**\n     * 返回封装后的API数据到客户端\n     * @access protected\n     * @param mixed     $data 要返回的数据\n     * @param integer   $code 返回的code\n     * @param mixed     $msg 提示信息\n     * @param string    $type 返回数据格式\n     * @param array     $header 发送的Header信息\n     * @return void\n     */\n    protected function result($data, $code = 0, $msg = '', $type = '', array $header = [])\n    {\n        $result = [\n            'code' => $code,\n            'msg'  => $msg,\n            'time' => $_SERVER['REQUEST_TIME'],\n            'data' => $data,\n        ];\n        $type     = $type ?: $this->getResponseType();\n        $response = Response::create($result, $type)->header($header);\n        throw new HttpResponseException($response);\n    }\n\n    /**\n     * URL重定向\n     * @access protected\n     * @param string         $url 跳转的URL表达式\n     * @param array|integer  $params 其它URL参数\n     * @param integer        $code http code\n     * @param array          $with 隐式传参\n     * @return void\n     */\n    protected function redirect($url, $params = [], $code = 302, $with = [])\n    {\n        $response = new Redirect($url);\n        if (is_integer($params)) {\n            $code   = $params;\n            $params = [];\n        }\n        $response->code($code)->params($params)->with($with);\n        throw new HttpResponseException($response);\n    }\n\n    /**\n     * 获取当前的response 输出类型\n     * @access protected\n     * @return string\n     */\n    protected function getResponseType()\n    {\n        $isAjax = Request::instance()->isAjax();\n        return $isAjax ? Config::get('default_ajax_return') : Config::get('default_return_type');\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/traits/model/SoftDelete.php",
    "content": "<?php\n\nnamespace traits\\model;\n\nuse think\\db\\Query;\n\ntrait SoftDelete\n{\n\n    /**\n     * 判断当前实例是否被软删除\n     * @access public\n     * @return boolean\n     */\n    public function trashed()\n    {\n        $field = $this->getDeleteTimeField();\n        if (!empty($this->data[$field])) {\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 查询软删除数据\n     * @access public\n     * @return Query\n     */\n    public static function withTrashed()\n    {\n        $model = new static();\n        $field = $model->getDeleteTimeField(true);\n        return $model->getQuery();\n    }\n\n    /**\n     * 只查询软删除数据\n     * @access public\n     * @return Query\n     */\n    public static function onlyTrashed()\n    {\n        $model = new static();\n        $field = $model->getDeleteTimeField(true);\n        return $model->getQuery()\n            ->useSoftDelete($field, ['not null', '']);\n    }\n\n    /**\n     * 删除当前的记录\n     * @access public\n     * @param bool  $force 是否强制删除\n     * @return integer\n     */\n    public function delete($force = false)\n    {\n        if (false === $this->trigger('before_delete', $this)) {\n            return false;\n        }\n        $name = $this->getDeleteTimeField();\n        if (!$force) {\n            // 软删除\n            $this->data[$name] = $this->autoWriteTimestamp($name);\n            $result            = $this->isUpdate()->save();\n        } else {\n            $result = $this->getQuery()->delete($this->data);\n        }\n\n        $this->trigger('after_delete', $this);\n        return $result;\n    }\n\n    /**\n     * 删除记录\n     * @access public\n     * @param mixed $data 主键列表 支持闭包查询条件\n     * @param bool  $force 是否强制删除\n     * @return integer 成功删除的记录数\n     */\n    public static function destroy($data, $force = false)\n    {\n        // 包含软删除数据\n        $query = self::withTrashed();\n        if (is_array($data) && key($data) !== 0) {\n            $query->where($data);\n            $data = null;\n        } elseif ($data instanceof \\Closure) {\n            call_user_func_array($data, [ & $query]);\n            $data = null;\n        } elseif (is_null($data)) {\n            return 0;\n        }\n\n        $resultSet = $query->select($data);\n        $count     = 0;\n        if ($resultSet) {\n            foreach ($resultSet as $data) {\n                $result = $data->delete($force);\n                $count += $result;\n            }\n        }\n        return $count;\n    }\n\n    /**\n     * 恢复被软删除的记录\n     * @access public\n     * @param array $where 更新条件\n     * @return integer\n     */\n    public function restore($where = [])\n    {\n        $name = $this->getDeleteTimeField();\n        if (empty($where)) {\n            $pk         = $this->getPk();\n            $where[$pk] = $this->getData($pk);\n        }\n        // 恢复删除\n        return $this->getQuery()\n            ->useSoftDelete($name, ['not null', ''])\n            ->where($where)\n            ->update([$name => null]);\n    }\n\n    /**\n     * 查询默认不包含软删除数据\n     * @access protected\n     * @param Query $query 查询对象\n     * @return void\n     */\n    protected function base($query)\n    {\n        $field = $this->getDeleteTimeField(true);\n        $query->useSoftDelete($field);\n    }\n\n    /**\n     * 获取软删除字段\n     * @access public\n     * @param bool  $read 是否查询操作 写操作的时候会自动去掉表别名\n     * @return string\n     */\n    protected function getDeleteTimeField($read = false)\n    {\n        $field = property_exists($this, 'deleteTime') && isset($this->deleteTime) ? $this->deleteTime : 'delete_time';\n        if (!strpos($field, '.')) {\n            $field = '__TABLE__.' . $field;\n        }\n        if (!$read && strpos($field, '.')) {\n            $array = explode('.', $field);\n            $field = array_pop($array);\n        }\n        return $field;\n    }\n}\n"
  },
  {
    "path": "thinkphp/library/traits/think/Instance.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace traits\\think;\n\nuse think\\Exception;\n\ntrait Instance\n{\n    protected static $instance = null;\n\n    /**\n     * @param array $options\n     * @return static\n     */\n    public static function instance($options = [])\n    {\n        if (is_null(self::$instance)) {\n            self::$instance = new self($options);\n        }\n        return self::$instance;\n    }\n\n    // 静态调用\n    public static function __callStatic($method, $params)\n    {\n        if (is_null(self::$instance)) {\n            self::$instance = new self();\n        }\n        $call = substr($method, 1);\n        if (0 === strpos($method, '_') && is_callable([self::$instance, $call])) {\n            return call_user_func_array([self::$instance, $call], $params);\n        } else {\n            throw new Exception(\"method not exists:\" . $method);\n        }\n    }\n}\n"
  },
  {
    "path": "thinkphp/phpunit.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<phpunit backupGlobals=\"false\"\n         backupStaticAttributes=\"false\"\n         bootstrap=\"tests/mock.php\"\n         colors=\"true\"\n         convertErrorsToExceptions=\"true\"\n         convertNoticesToExceptions=\"true\"\n         convertWarningsToExceptions=\"true\"\n         processIsolation=\"false\"\n         stopOnFailure=\"false\"\n         syntaxCheck=\"false\">\n    <testsuites>\n        <testsuite name=\"ThinkPHP Test Suite\">\n            <directory>./tests/thinkphp/</directory>\n        </testsuite>\n    </testsuites>\n    <listeners>\n        <listener class=\"JohnKary\\PHPUnit\\Listener\\SpeedTrapListener\" />\n    </listeners>\n    <filter>\n        <whitelist>\n            <directory suffix=\".php\">./</directory>\n            <exclude>\n                <directory suffix=\".php\">tests</directory>\n                <directory suffix=\".php\">vendor</directory>\n            </exclude>\n        </whitelist>\n    </filter>\n    <php>\n        <env name=\"APP_ENV\" value=\"testing\"/>\n        <env name=\"CACHE_DRIVER\" value=\"array\"/>\n        <env name=\"SESSION_DRIVER\" value=\"array\"/>\n        <env name=\"QUEUE_DRIVER\" value=\"sync\"/>\n    </php>\n</phpunit>\n"
  },
  {
    "path": "thinkphp/start.php",
    "content": "<?php\n// +----------------------------------------------------------------------\n// | ThinkPHP [ WE CAN DO IT JUST THINK ]\n// +----------------------------------------------------------------------\n// | Copyright (c) 2006~2017 http://thinkphp.cn All rights reserved.\n// +----------------------------------------------------------------------\n// | Licensed ( http://www.apache.org/licenses/LICENSE-2.0 )\n// +----------------------------------------------------------------------\n// | Author: liu21st <liu21st@gmail.com>\n// +----------------------------------------------------------------------\n\nnamespace think;\n\n// ThinkPHP 引导文件\n// 加载基础文件\nrequire __DIR__ . '/base.php';\n// 执行应用\nApp::run()->send();\n"
  },
  {
    "path": "thinkphp/tpl/default_index.tpl",
    "content": "<?php\nnamespace {$app}\\{$module}{layer};\n\nclass Index{$suffix}\n{\n    public function index()\n    {\n        return '<style type=\"text/css\">*{ padding: 0; margin: 0; } div{ padding: 4px 48px;} a{color:#2E5CD5;cursor: pointer;text-decoration: none} a:hover{text-decoration:underline; } body{ background: #fff; font-family: \"Century Gothic\",\"Microsoft yahei\"; color: #333;font-size:18px;} h1{ font-size: 100px; font-weight: normal; margin-bottom: 12px; } p{ line-height: 1.6em; font-size: 42px }</style><div style=\"padding: 24px 48px;\"> <h1>:)</h1><p> ThinkPHP V5<br/><span style=\"font-size:30px\">十年磨一剑 - 为API开发设计的高性能框架</span></p><span style=\"font-size:22px;\">[ V5.0 版本由 <a href=\"http://www.qiniu.com\" target=\"qiniu\">七牛云</a> 独家赞助发布 ]</span></div><script type=\"text/javascript\" src=\"http://tajs.qq.com/stats?sId=9347272\" charset=\"UTF-8\"></script><script type=\"text/javascript\" src=\"http://ad.topthink.com/Public/static/client.js\"></script><thinkad id=\"ad_bd568ce7058a1091\"></thinkad>';\n    }\n}\n"
  },
  {
    "path": "thinkphp/tpl/dispatch_jump.tpl",
    "content": "{__NOLAYOUT__}<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n    <title>跳转提示</title>\n    <style type=\"text/css\">\n        *{ padding: 0; margin: 0; }\n        body{ background: #fff; font-family: \"Microsoft Yahei\",\"Helvetica Neue\",Helvetica,Arial,sans-serif; color: #333; font-size: 16px; }\n        .system-message{ padding: 24px 48px; }\n        .system-message h1{ font-size: 100px; font-weight: normal; line-height: 120px; margin-bottom: 12px; }\n        .system-message .jump{ padding-top: 10px; }\n        .system-message .jump a{ color: #333; }\n        .system-message .success,.system-message .error{ line-height: 1.8em; font-size: 36px; }\n        .system-message .detail{ font-size: 12px; line-height: 20px; margin-top: 12px; display: none; }\n    </style>\n</head>\n<body>\n    <div class=\"system-message\">\n        <?php switch ($code) {?>\n            <?php case 1:?>\n            <h1>:)</h1>\n            <p class=\"success\"><?php echo(strip_tags($msg));?></p>\n            <?php break;?>\n            <?php case 0:?>\n            <h1>:(</h1>\n            <p class=\"error\"><?php echo(strip_tags($msg));?></p>\n            <?php break;?>\n        <?php } ?>\n        <p class=\"detail\"></p>\n        <p class=\"jump\">\n            页面自动 <a id=\"href\" href=\"<?php echo($url);?>\">跳转</a> 等待时间： <b id=\"wait\"><?php echo($wait);?></b>\n        </p>\n    </div>\n    <script type=\"text/javascript\">\n        (function(){\n            var wait = document.getElementById('wait'),\n                href = document.getElementById('href').href;\n            var interval = setInterval(function(){\n                var time = --wait.innerHTML;\n                if(time <= 0) {\n                    location.href = href;\n                    clearInterval(interval);\n                };\n            }, 1000);\n        })();\n    </script>\n</body>\n</html>\n"
  },
  {
    "path": "thinkphp/tpl/page_trace.tpl",
    "content": "<div id=\"think_page_trace\" style=\"position: fixed;bottom:0;right:0;font-size:14px;width:100%;z-index: 999999;color: #000;text-align:left;font-family:'微软雅黑';\">\n    <div id=\"think_page_trace_tab\" style=\"display: none;background:white;margin:0;height: 250px;\">\n        <div id=\"think_page_trace_tab_tit\" style=\"height:30px;padding: 6px 12px 0;border-bottom:1px solid #ececec;border-top:1px solid #ececec;font-size:16px\">\n            <?php foreach ($trace as $key => $value) {?>\n            <span style=\"color:#000;padding-right:12px;height:30px;line-height:30px;display:inline-block;margin-right:3px;cursor:pointer;font-weight:700\"><?php echo $key ?></span>\n            <?php }?>\n        </div>\n        <div id=\"think_page_trace_tab_cont\" style=\"overflow:auto;height:212px;padding:0;line-height: 24px\">\n            <?php foreach ($trace as $info) {?>\n            <div style=\"display:none;\">\n                <ol style=\"padding: 0; margin:0\">\n                    <?php\n                    if (is_array($info)) {\n                        foreach ($info as $k => $val) {\n                            echo '<li style=\"border-bottom:1px solid #EEE;font-size:14px;padding:0 12px\">' . (is_numeric($k) ? '' : $k.' : ') . htmlentities(print_r($val,true), ENT_COMPAT, 'utf-8') . '</li>';\n                        }\n                    }\n                    ?>\n                </ol>\n            </div>\n            <?php }?>\n        </div>\n    </div>\n    <div id=\"think_page_trace_close\" style=\"display:none;text-align:right;height:15px;position:absolute;top:10px;right:12px;cursor:pointer;\"><img style=\"vertical-align:top;\" src=\"data:image/gif;base64,R0lGODlhDwAPAJEAAAAAAAMDA////wAAACH/C1hNUCBEYXRhWE1QPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4gPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iQWRvYmUgWE1QIENvcmUgNS4wLWMwNjAgNjEuMTM0Nzc3LCAyMDEwLzAyLzEyLTE3OjMyOjAwICAgICAgICAiPiA8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPiA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M1IFdpbmRvd3MiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6MUQxMjc1MUJCQUJDMTFFMTk0OUVGRjc3QzU4RURFNkEiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6MUQxMjc1MUNCQUJDMTFFMTk0OUVGRjc3QzU4RURFNkEiPiA8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDoxRDEyNzUxOUJBQkMxMUUxOTQ5RUZGNzdDNThFREU2QSIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDoxRDEyNzUxQUJBQkMxMUUxOTQ5RUZGNzdDNThFREU2QSIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PgH//v38+/r5+Pf29fTz8vHw7+7t7Ovq6ejn5uXk4+Lh4N/e3dzb2tnY19bV1NPS0dDPzs3My8rJyMfGxcTDwsHAv769vLu6ubi3trW0s7KxsK+urayrqqmop6alpKOioaCfnp2cm5qZmJeWlZSTkpGQj46NjIuKiYiHhoWEg4KBgH9+fXx7enl4d3Z1dHNycXBvbm1sa2ppaGdmZWRjYmFgX15dXFtaWVhXVlVUU1JRUE9OTUxLSklIR0ZFRENCQUA/Pj08Ozo5ODc2NTQzMjEwLy4tLCsqKSgnJiUkIyIhIB8eHRwbGhkYFxYVFBMSERAPDg0MCwoJCAcGBQQDAgEAACH5BAAAAAAALAAAAAAPAA8AAAIdjI6JZqotoJPR1fnsgRR3C2jZl3Ai9aWZZooV+RQAOw==\" /></div>\n</div>\n<div id=\"think_page_trace_open\" style=\"height:30px;float:right;text-align:right;overflow:hidden;position:fixed;bottom:0;right:0;color:#000;line-height:30px;cursor:pointer;\">\n    <div style=\"background:#232323;color:#FFF;padding:0 6px;float:right;line-height:30px;font-size:14px\"><?php echo \\think\\Debug::getUseTime().'s ';?></div>\n    <img width=\"30\" style=\"\" title=\"ShowPageTrace\" src=\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADAAAAAwCAYAAABXAvmHAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyBpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMC1jMDYwIDYxLjEzNDc3NywgMjAxMC8wMi8xMi0xNzozMjowMCAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNSBXaW5kb3dzIiB4bXBNTTpJbnN0YW5jZUlEPSJ4bXAuaWlkOjVERDVENkZGQjkyNDExRTE5REY3RDQ5RTQ2RTRDQUJCIiB4bXBNTTpEb2N1bWVudElEPSJ4bXAuZGlkOjVERDVENzAwQjkyNDExRTE5REY3RDQ5RTQ2RTRDQUJCIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NURENUQ2RkRCOTI0MTFFMTlERjdENDlFNDZFNENBQkIiIHN0UmVmOmRvY3VtZW50SUQ9InhtcC5kaWQ6NURENUQ2RkVCOTI0MTFFMTlERjdENDlFNDZFNENBQkIiLz4gPC9yZGY6RGVzY3JpcHRpb24+IDwvcmRmOlJERj4gPC94OnhtcG1ldGE+IDw/eHBhY2tldCBlbmQ9InIiPz5fx6IRAAAMCElEQVR42sxae3BU1Rk/9+69+8xuNtkHJAFCSIAkhMgjCCJQUi0GtEIVbP8Qq9LH2No6TmfaztjO2OnUdvqHFMfOVFTqIK0vUEEeqUBARCsEeYQkEPJoEvIiELLvvc9z+p27u2F3s5tsBB1OZiebu5dzf7/v/L7f952zMM8cWIwY+Mk2ulCp92Fnq3XvnzArr2NZnYNldDp0Gw+/OEQ4+obQn5D+4Ubb22+YOGsWi/Todh8AHglKEGkEsnHBQ162511GZFgW6ZCBM9/W4H3iNSQqIe09O196dLKX7d1O39OViP/wthtkND62if/wj/DbMpph8BY/m9xy8BoBmQk+mHqZQGNy4JYRwCoRbwa8l4JXw6M+orJxpU0U6ToKy/5bQsAiTeokGKkTx46RRxxEUgrwGgF4MWNNEJCGgYTvpgnY1IJWg5RzfqLgvcIgktX0i8dmMlFA8qCQ5L0Z/WObPLUxT1i4lWSYDISoEfBYGvM+LlMQQdkLHoWRRZ8zYQI62Thswe5WTORGwNXDcGjqeOA9AF7B8rhzsxMBEoJ8oJKaqPu4hblHMCMPwl9XeNWyb8xkB/DDGYKfMAE6aFL7xesZ389JlgG3XHEMI6UPDOP6JHHu67T2pwNPI69mCP4rEaBDUAJaKc/AOuXiwH07VCS3w5+UQMAuF/WqGI+yFIwVNBwemBD4r0wgQiKoFZa00sEYTwss32lA1tPwVxtc8jQ5/gWCwmGCyUD8vRT0sHBFW4GJDvZmrJFWRY1EkrGA6ZB8/10fOZSSj0E6F+BSP7xidiIzhBmKB09lEwHPkG+UQIyEN44EBiT5vrv2uJXyPQqSqO930fxvcvwbR/+JAkD9EfASgI9EHlp6YiHO4W+cAB20SnrFqxBbNljiXf1Pl1K2S0HCWfiog3YlAD5RGwwxK6oUjTweuVigLjyB0mX410mAFnMoVK1lvvUvgt8fUJH0JVyjuvcmg4dE5mUiFtD24AZ4qBVELxXKS+pMxN43kSdzNwudJ+bQbLlmnxvPOQoCugSap1GnSRoG8KOiKbH+rIA0lEeSAg3y6eeQ6XI2nrYnrPM89bUTgI0Pdqvl50vlNbtZxDUBcLBK0kPd5jPziyLdojJIN0pq5/mdzwL4UVvVInV5ncQEPNOUxa9d0TU+CW5l+FoI0GSDKHVVSOs+0KOsZoxwOzSZNFGv0mQ9avyLCh2Hpm+70Y0YJoJVgmQv822wnDC8Miq6VjJ5IFed0QD1YiAbT+nQE8v/RMZfmgmcCRHIIu7Bmcp39oM9fqEychcA747KxQ/AEyqQonl7hATtJmnhO2XYtgcia01aSbVMenAXrIomPcLgEBA4liGBzFZAT8zBYqW6brI67wg8sFVhxBhwLwBP2+tqBQqqK7VJKGh/BRrfTr6nWL7nYBaZdBJHqrX3kPEPap56xwE/GvjJTRMADeMCdcGpGXL1Xh4ZL8BDOlWkUpegfi0CeDzeA5YITzEnddv+IXL+UYCmqIvqC9UlUC/ki9FipwVjunL3yX7dOTLeXmVMAhbsGporPfyOBTm/BJ23gTVehsvXRnSewagUfpBXF3p5pygKS7OceqTjb7h2vjr/XKm0ZofKSI2Q/J102wHzatZkJPYQ5JoKsuK+EoHJakVzubzuLQDepCKllTZi9AG0DYg9ZLxhFaZsOu7bvlmVI5oPXJMQJcHxHClSln1apFTvAimeg48u0RWFeZW4lVcjbQWZuIQK1KozZfIDO6CSQmQQXdpBaiKZyEWThVK1uEc6v7V7uK0ysduExPZx4vysDR+4SelhBYm0R6LBuR4PXts8MYMcJPsINo4YZCDLj0sgB0/vLpPXvA2Tn42Cv5rsLulGubzW0sEd3d4W/mJt2Kck+DzDMijfPLOjyrDhXSh852B+OvflqAkoyXO1cYfujtc/i3jJSAwhgfFlp20laMLOku/bC7prgqW7lCn4auE5NhcXPd3M7x70+IceSgZvNljCd9k3fLjYsPElqLR14PXQZqD2ZNkkrAB79UeJUebFQmXpf8ZcAQt2XrMQdyNUVBqZoUzAFyp3V3xi/MubUA/mCT4Fhf038PC8XplhWnCmnK/ZzyC2BSTRSqKVOuY2kB8Jia0lvvRIVoP+vVWJbYarf6p655E2/nANBMCWkgD49DA0VAMyI1OLFMYCXiU9bmzi9/y5i/vsaTpHPHidTofzLbM65vMPva9HlovgXp0AvjtaqYMfDD0/4mAsYE92pxa+9k1QgCnRVObCpojpzsKTPvayPetTEgBdwnssjuc0kOBFX+q3HwRQxdrOLAqeYRjkMk/trTSu2Z9Lik7CfF0AvjtqAhS4NHobGXUnB5DQs8hG8p/wMX1r4+8xkmyvQ50JVq72TVeXbz3HvpWaQJi57hJYTw4kGbtS+C2TigQUtZUX+X27QQq2ePBZBru/0lxTm8fOOQ5yaZOZMAV+he4FqIMB+LQB0UgMSajANX29j+vbmly8ipRvHeSQoQOkM5iFXcPQCVwDMs5RBCQmaPOyvbNd6uwvQJ183BZQG3Zc+Eiv7vQOKu8YeDmMcJlt2ckyftVeMIGLBCmdMHl/tFILYwGPjXWO3zOfSq/+om+oa7Mlh2fpSsRGLp7RAW3FUVjNHgiMhyE6zBFjM2BdkdJGO7nP1kJXWAtBuBpPIAu7f+hhu7bFXIuC5xWrf0X2xreykOsUyKkF2gwadbrXDcXrfKxR43zGcSj4t/cCgr+a1iy6EjE5GYktUCl9fwfMeylyooGF48bN2IGLTw8x7StS7sj8TF9FmPGWQhm3rRR+o9lhvjJvSYAdfDUevI1M6bnX/OwWaDMOQ8RPgKRo0eulBTdT8AW2kl8e9L7UHghHwMfLiZPNoSpx0yugpQZaFqKWqxVSM3a2pN1SAhC2jf94I7ybBI7EL5A2Wvu5ht3xsoEt4+Ay/abXgCQAxyOeDsDlTCQzy75ohcGgv9Tra9uiymRUYTLrswOLlCdfAQf7HPDQQ4ErAH5EDXB9cMxWYpjtXApRncojS0sbV/cCgHTHwGNBJy+1PQE2x56FpaVR7wfQGZ37V+V+19EiHNvR6q1fRUjqvbjbMq1/qfHxbTrE10ePY2gPFk48D2CVMTf1AF4PXvyYR9dV6Wf7H413m3xTWQvYGhQ7mfYwA5mAX+18Vue05v/8jG/fZX/IW5MKPKtjSYlt0ellxh+/BOCPAwYaeVr0QofZFxJWVWC8znG70au6llVmktsF0bfHF6k8fvZ5esZJbwHwwnjg59tXz6sL/P0NUZDuSNu1mnJ8Vab17+cy005A9wtOpp3i0bZdpJLUil00semAwN45LgEViZYe3amNye0B6A9chviSlzXVsFtyN5/1H3gaNmMpn8Fz0GpYFp6Zw615H/LpUuRQQDMCL82n5DpBSawkvzIdN2ypiT8nSLth8Pk9jnjwdFzH3W4XW6KMBfwB569NdcGX93mC16tTflcArcYUc/mFuYbV+8zY0SAjAVoNErNgWjtwumJ3wbn/HlBFYdxHvSkJJEc+Ngal9opSwyo9YlITX2C/P/+gf8sxURSLR+mcZUmeqaS9wrh6vxW5zxFCOqFi90RbDWq/YwZmnu1+a6OvdpvRqkNxxe44lyl4OobEnpKA6Uox5EfH9xzPs/HRKrTPWdIQrK1VZDU7ETiD3Obpl+8wPPCRBbkbwNtpW9AbBe5L1SMlj3tdTxk/9W47JUmqS5HU+JzYymUKXjtWVmT9RenIhgXc+nroWLyxXJhmL112OdB8GCsk4f8oZJucnvmmtR85mBn10GZ0EKSCMUSAR3ukcXd5s7LvLD3me61WkuTCpJzYAyRurMB44EdEJzTfU271lUJC03YjXJXzYOGZwN4D8eB5jlfLrdWfzGRW7icMPfiSO6Oe7s20bmhdgLX4Z23B+s3JgQESzUDiMboSzDMHFpNMwccGePauhfwjzwnI2wu9zKGgEFg80jcZ7MHllk07s1H+5yojtUQTlH4nFdLKTGwDmPbIklOb1L1zO4T6N8NCuDLFLS/C63c0eNRimZ++s5BMBHxU11jHchI9oFVUxRh/eMDzHEzGYu0Lg8gJ7oS/tFCwoic44fyUtix0n/46vP4bf+//BRgAYwDDar4ncHIAAAAASUVORK5CYII=\">\n</div>\n\n<script type=\"text/javascript\">\n    (function(){\n        var tab_tit  = document.getElementById('think_page_trace_tab_tit').getElementsByTagName('span');\n        var tab_cont = document.getElementById('think_page_trace_tab_cont').getElementsByTagName('div');\n        var open     = document.getElementById('think_page_trace_open');\n        var close    = document.getElementById('think_page_trace_close').children[0];\n        var trace    = document.getElementById('think_page_trace_tab');\n        var cookie   = document.cookie.match(/thinkphp_show_page_trace=(\\d\\|\\d)/);\n        var history  = (cookie && typeof cookie[1] != 'undefined' && cookie[1].split('|')) || [0,0];\n        open.onclick = function(){\n            trace.style.display = 'block';\n            this.style.display = 'none';\n            close.parentNode.style.display = 'block';\n            history[0] = 1;\n            document.cookie = 'thinkphp_show_page_trace='+history.join('|')\n        }\n        close.onclick = function(){\n            trace.style.display = 'none';\n            this.parentNode.style.display = 'none';\n            open.style.display = 'block';\n            history[0] = 0;\n            document.cookie = 'thinkphp_show_page_trace='+history.join('|')\n        }\n        for(var i = 0; i < tab_tit.length; i++){\n            tab_tit[i].onclick = (function(i){\n                return function(){\n                    for(var j = 0; j < tab_cont.length; j++){\n                        tab_cont[j].style.display = 'none';\n                        tab_tit[j].style.color = '#999';\n                    }\n                    tab_cont[i].style.display = 'block';\n                    tab_tit[i].style.color = '#000';\n                    history[1] = i;\n                    document.cookie = 'thinkphp_show_page_trace='+history.join('|')\n                }\n            })(i)\n        }\n        parseInt(history[0]) && open.click();\n        tab_tit[history[1]].click();\n    })();\n</script>\n"
  },
  {
    "path": "thinkphp/tpl/think_exception.tpl",
    "content": "<?php\n    if(!function_exists('parse_padding')){\n        function parse_padding($source)\n        {\n            $length  = strlen(strval(count($source['source']) + $source['first']));\n            return 40 + ($length - 1) * 8;\n        }\n    }\n\n    if(!function_exists('parse_class')){\n        function parse_class($name)\n        {\n            $names = explode('\\\\', $name);\n            return '<abbr title=\"'.$name.'\">'.end($names).'</abbr>';\n        }\n    }\n\n    if(!function_exists('parse_file')){\n        function parse_file($file, $line)\n        {\n            return '<a class=\"toggle\" title=\"'.\"{$file} line {$line}\".'\">'.basename($file).\" line {$line}\".'</a>';\n        }\n    }\n\n    if(!function_exists('parse_args')){\n        function parse_args($args)\n        {\n            $result = [];\n\n            foreach ($args as $key => $item) {\n                switch (true) {\n                    case is_object($item):\n                        $value = sprintf('<em>object</em>(%s)', parse_class(get_class($item)));\n                        break;\n                    case is_array($item):\n                        if(count($item) > 3){\n                            $value = sprintf('[%s, ...]', parse_args(array_slice($item, 0, 3)));\n                        } else {\n                            $value = sprintf('[%s]', parse_args($item));\n                        }\n                        break;\n                    case is_string($item):\n                        if(strlen($item) > 20){\n                            $value = sprintf(\n                                '\\'<a class=\"toggle\" title=\"%s\">%s...</a>\\'',\n                                htmlentities($item),\n                                htmlentities(substr($item, 0, 20))\n                            );\n                        } else {\n                            $value = sprintf(\"'%s'\", htmlentities($item));\n                        }\n                        break;\n                    case is_int($item):\n                    case is_float($item):\n                        $value = $item;\n                        break;\n                    case is_null($item):\n                        $value = '<em>null</em>';\n                        break;\n                    case is_bool($item):\n                        $value = '<em>' . ($item ? 'true' : 'false') . '</em>';\n                        break;\n                    case is_resource($item):\n                        $value = '<em>resource</em>';\n                        break;\n                    default:\n                        $value = htmlentities(str_replace(\"\\n\", '', var_export(strval($item), true)));\n                        break;\n                }\n\n                $result[] = is_int($key) ? $value : \"'{$key}' => {$value}\";\n            }\n\n            return implode(', ', $result);\n        }\n    }\n?>\n<!DOCTYPE html>\n<html>\n<head>\n    <meta charset=\"UTF-8\">\n    <title><?php echo lang('System Error'); ?></title>\n    <meta name=\"robots\" content=\"noindex,nofollow\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">\n    <style>\n        /* Base */\n        body {\n            color: #333;\n            font: 14px Verdana, \"Helvetica Neue\", helvetica, Arial, 'Microsoft YaHei', sans-serif;\n            margin: 0;\n            padding: 0 20px 20px;\n            word-break: break-word;\n        }\n        h1{\n            margin: 10px 0 0;\n            font-size: 28px;\n            font-weight: 500;\n            line-height: 32px;\n        }\n        h2{\n            color: #4288ce;\n            font-weight: 400;\n            padding: 6px 0;\n            margin: 6px 0 0;\n            font-size: 18px;\n            border-bottom: 1px solid #eee;\n        }\n        h3.subheading {\n            color: #4288ce;\n            margin: 6px 0 0;\n            font-weight: 400;\n        }\n        h3{\n            margin: 12px;\n            font-size: 16px;\n            font-weight: bold;\n        }\n        abbr{\n            cursor: help;\n            text-decoration: underline;\n            text-decoration-style: dotted;\n        }\n        a{\n            color: #868686;\n            cursor: pointer;\n        }\n        a:hover{\n            text-decoration: underline;\n        }\n        .line-error{\n            background: #f8cbcb;\n        }\n\n        .echo table {\n            width: 100%;\n        }\n\n        .echo pre {\n            padding: 16px;\n            overflow: auto;\n            font-size: 85%;\n            line-height: 1.45;\n            background-color: #f7f7f7;\n            border: 0;\n            border-radius: 3px;\n            font-family: Consolas, \"Liberation Mono\", Menlo, Courier, monospace;\n        }\n\n        .echo pre > pre {\n            padding: 0;\n            margin: 0;\n        }\n        /* Layout */\n        .col-md-3 {\n            width: 25%;\n        }\n        .col-md-9 {\n            width: 75%;\n        }\n        [class^=\"col-md-\"] {\n            float: left;\n        }\n        .clearfix {\n            clear:both;\n        }\n        @media only screen \n        and (min-device-width : 375px) \n        and (max-device-width : 667px) { \n            .col-md-3,\n            .col-md-9 {\n                width: 100%;\n            }\n        }\n        /* Exception Info */\n        .exception {\n            margin-top: 20px;\n        }\n        .exception .message{\n            padding: 12px;\n            border: 1px solid #ddd;\n            border-bottom: 0 none;\n            line-height: 18px;\n            font-size:16px;\n            border-top-left-radius: 4px;\n            border-top-right-radius: 4px;\n            font-family: Consolas,\"Liberation Mono\",Courier,Verdana,\"微软雅黑\";\n        }\n\n        .exception .code{\n            float: left;\n            text-align: center;\n            color: #fff;\n            margin-right: 12px;\n            padding: 16px;\n            border-radius: 4px;\n            background: #999;\n        }\n        .exception .source-code{\n            padding: 6px;\n            border: 1px solid #ddd;\n\n            background: #f9f9f9;\n            overflow-x: auto;\n\n        }\n        .exception .source-code pre{\n            margin: 0;\n        }\n        .exception .source-code pre ol{\n            margin: 0;\n            color: #4288ce;\n            display: inline-block;\n            min-width: 100%;\n            box-sizing: border-box;\n        font-size:14px;\n            font-family: \"Century Gothic\",Consolas,\"Liberation Mono\",Courier,Verdana;\n            padding-left: <?php echo (isset($source) && !empty($source)) ? parse_padding($source) : 40;  ?>px;\n        }\n        .exception .source-code pre li{\n            border-left: 1px solid #ddd;\n            height: 18px;\n            line-height: 18px;\n        }\n        .exception .source-code pre code{\n            color: #333;\n            height: 100%;\n            display: inline-block;\n            border-left: 1px solid #fff;\n        font-size:14px;\n            font-family: Consolas,\"Liberation Mono\",Courier,Verdana,\"微软雅黑\";\n        }\n        .exception .trace{\n            padding: 6px;\n            border: 1px solid #ddd;\n            border-top: 0 none;\n            line-height: 16px;\n        font-size:14px;\n            font-family: Consolas,\"Liberation Mono\",Courier,Verdana,\"微软雅黑\";\n        }\n        .exception .trace ol{\n            margin: 12px;\n        }\n        .exception .trace ol li{\n            padding: 2px 4px;\n        }\n        .exception div:last-child{\n            border-bottom-left-radius: 4px;\n            border-bottom-right-radius: 4px;\n        }\n\n        /* Exception Variables */\n        .exception-var table{\n            width: 100%;\n            margin: 12px 0;\n            box-sizing: border-box;\n            table-layout:fixed;\n            word-wrap:break-word;            \n        }\n        .exception-var table caption{\n            text-align: left;\n            font-size: 16px;\n            font-weight: bold;\n            padding: 6px 0;\n        }\n        .exception-var table caption small{\n            font-weight: 300;\n            display: inline-block;\n            margin-left: 10px;\n            color: #ccc;\n        }\n        .exception-var table tbody{\n            font-size: 13px;\n            font-family: Consolas,\"Liberation Mono\",Courier,\"微软雅黑\";\n        }\n        .exception-var table td{\n            padding: 0 6px;\n            vertical-align: top;\n            word-break: break-all;\n        }\n        .exception-var table td:first-child{\n            width: 28%;\n            font-weight: bold;\n            white-space: nowrap;\n        }\n        .exception-var table td pre{\n            margin: 0;\n        }\n\n        /* Copyright Info */\n        .copyright{\n            margin-top: 24px;\n            padding: 12px 0;\n            border-top: 1px solid #eee;\n        }\n\n        /* SPAN elements with the classes below are added by prettyprint. */\n        pre.prettyprint .pln { color: #000 }  /* plain text */\n        pre.prettyprint .str { color: #080 }  /* string content */\n        pre.prettyprint .kwd { color: #008 }  /* a keyword */\n        pre.prettyprint .com { color: #800 }  /* a comment */\n        pre.prettyprint .typ { color: #606 }  /* a type name */\n        pre.prettyprint .lit { color: #066 }  /* a literal value */\n        /* punctuation, lisp open bracket, lisp close bracket */\n        pre.prettyprint .pun, pre.prettyprint .opn, pre.prettyprint .clo { color: #660 }\n        pre.prettyprint .tag { color: #008 }  /* a markup tag name */\n        pre.prettyprint .atn { color: #606 }  /* a markup attribute name */\n        pre.prettyprint .atv { color: #080 }  /* a markup attribute value */\n        pre.prettyprint .dec, pre.prettyprint .var { color: #606 }  /* a declaration; a variable name */\n        pre.prettyprint .fun { color: red }  /* a function name */\n    </style>\n</head>\n<body>\n    <div class=\"echo\">\n        <?php echo $echo;?>\n    </div>\n    <?php if(\\think\\App::$debug) { ?>\n    <div class=\"exception\">\n    <div class=\"message\">\n        \n            <div class=\"info\">\n                <div>\n                    <h2>[<?php echo $code; ?>] <?php echo sprintf('%s in %s', parse_class($name), parse_file($file, $line)); ?></h2>\n                </div>\n                <div><h1><?php echo nl2br(htmlentities($message)); ?></h1></div>\n            </div>\n        \n    </div>\n\t<?php if(!empty($source)){?>\n        <div class=\"source-code\">\n            <pre class=\"prettyprint lang-php\"><ol start=\"<?php echo $source['first']; ?>\"><?php foreach ((array) $source['source'] as $key => $value) { ?><li class=\"line-<?php echo $key + $source['first']; ?>\"><code><?php echo htmlentities($value); ?></code></li><?php } ?></ol></pre>\n        </div>\n\t<?php }?>\n        <div class=\"trace\">\n            <h2>Call Stack</h2>\n            <ol>\n                <li><?php echo sprintf('in %s', parse_file($file, $line)); ?></li>\n                <?php foreach ((array) $trace as $value) { ?>\n                <li>\n                <?php \n                    // Show Function\n                    if($value['function']){\n                        echo sprintf(\n                            'at %s%s%s(%s)', \n                            isset($value['class']) ? parse_class($value['class']) : '',\n                            isset($value['type'])  ? $value['type'] : '', \n                            $value['function'], \n                            isset($value['args'])?parse_args($value['args']):''\n                        );\n                    }\n\n                    // Show line\n                    if (isset($value['file']) && isset($value['line'])) {\n                        echo sprintf(' in %s', parse_file($value['file'], $value['line']));\n                    }\n                ?>\n                </li>\n                <?php } ?>\n            </ol>\n        </div>\n    </div>\n    <?php } else { ?>\n    <div class=\"exception\">\n        \n            <div class=\"info\"><h1><?php echo htmlentities($message); ?></h1></div>\n        \n    </div>\n    <?php } ?>\n    \n    <?php if(!empty($datas)){ ?>\n    <div class=\"exception-var\">\n        <h2>Exception Datas</h2>\n        <?php foreach ((array) $datas as $label => $value) { ?>\n        <table>\n            <?php if(empty($value)){ ?>\n            <caption><?php echo $label; ?><small>empty</small></caption>\n            <?php } else { ?>\n            <caption><?php echo $label; ?></caption>\n            <tbody>\n                <?php foreach ((array) $value as $key => $val) { ?>\n                <tr>\n                    <td><?php echo htmlentities($key); ?></td>\n                    <td>\n                        <?php \n                            if(is_array($val) || is_object($val)){ \n                                echo htmlentities(json_encode($val, JSON_PRETTY_PRINT));\n                            } else if(is_bool($val)) { \n                                echo $val ? 'true' : 'false';\n                            } else if(is_scalar($val)) {\n                                echo htmlentities($val);\n                            } else {\n                                echo 'Resource';\n                            }\n                        ?>\n                    </td>\n                </tr>\n                <?php } ?>\n            </tbody>\n            <?php } ?>\n        </table>\n        <?php } ?>\n    </div>\n    <?php } ?>\n\n    <?php if(!empty($tables)){ ?>\n    <div class=\"exception-var\">\n        <h2>Environment Variables</h2>\n        <?php foreach ((array) $tables as $label => $value) { ?>\n        <div>\n            <?php if(empty($value)){ ?>\n            <div class=\"clearfix\">\n                <div class=\"col-md-3\"><strong><?php echo $label; ?></strong></div>\n                <div class=\"col-md-9\"><small>empty</small></div>\n            </div>\n            <?php } else { ?>\n            <h3 class=\"subheading\"><?php echo $label; ?></h3>\n            <div>\n                <?php foreach ((array) $value as $key => $val) { ?>\n                <div class=\"clearfix\">\n                    <div class=\"col-md-3\"><strong><?php echo htmlentities($key); ?></strong></div>\n                    <div class=\"col-md-9\"><small>\n                        <?php \n                            if(is_array($val) || is_object($val)){ \n                                echo htmlentities(json_encode($val, JSON_PRETTY_PRINT));\n                            } else if(is_bool($val)) { \n                                echo $val ? 'true' : 'false';\n                            } else if(is_scalar($val)) {\n                                echo htmlentities($val);\n                            } else {\n                                echo 'Resource';\n                            }\n                        ?>\n                    </small></div>\n                </div>\n                <?php } ?>\n            </div>\n            <?php } ?>\n        </div>\n        <?php } ?>\n    </div>\n    <?php } ?>\n\n    <div class=\"copyright\">\n        <a title=\"官方网站\" href=\"http://www.thinkphp.cn\">ThinkPHP</a> \n        <span>V<?php echo THINK_VERSION; ?></span> \n        <span>{ 十年磨一剑-为API开发设计的高性能框架 }</span>\n    </div>\n    <?php if(\\think\\App::$debug) { ?>\n    <script>\n        var LINE = <?php echo $line; ?>;\n\n        function $(selector, node){\n            var elements;\n\n            node = node || document;\n            if(document.querySelectorAll){\n                elements = node.querySelectorAll(selector);\n            } else {\n                switch(selector.substr(0, 1)){\n                    case '#':\n                        elements = [node.getElementById(selector.substr(1))];\n                        break;\n                    case '.':\n                        if(document.getElementsByClassName){\n                            elements = node.getElementsByClassName(selector.substr(1));\n                        } else {\n                            elements = get_elements_by_class(selector.substr(1), node);\n                        }\n                        break;\n                    default:\n                        elements = node.getElementsByTagName();\n                }\n            }\n            return elements;\n\n            function get_elements_by_class(search_class, node, tag) {\n                var elements = [], eles, \n                    pattern  = new RegExp('(^|\\\\s)' + search_class + '(\\\\s|$)');\n\n                node = node || document;\n                tag  = tag  || '*';\n\n                eles = node.getElementsByTagName(tag);\n                for(var i = 0; i < eles.length; i++) {\n                    if(pattern.test(eles[i].className)) {\n                        elements.push(eles[i])\n                    }\n                }\n\n                return elements;\n            }\n        }\n\n        $.getScript = function(src, func){\n            var script = document.createElement('script');\n            \n            script.async  = 'async';\n            script.src    = src;\n            script.onload = func || function(){};\n            \n            $('head')[0].appendChild(script);\n        }\n\n        ;(function(){\n            var files = $('.toggle');\n            var ol    = $('ol', $('.prettyprint')[0]);\n            var li    = $('li', ol[0]);   \n\n            // 短路径和长路径变换\n            for(var i = 0; i < files.length; i++){\n                files[i].ondblclick = function(){\n                    var title = this.title;\n\n                    this.title = this.innerHTML;\n                    this.innerHTML = title;\n                }\n            }\n\n            // 设置出错行\n            var err_line = $('.line-' + LINE, ol[0])[0];\n            err_line.className = err_line.className + ' line-error';\n\n            $.getScript('//cdn.bootcss.com/prettify/r298/prettify.min.js', function(){\n                prettyPrint();\n\n                // 解决Firefox浏览器一个很诡异的问题\n                // 当代码高亮后，ol的行号莫名其妙的错位\n                // 但是只要刷新li里面的html重新渲染就没有问题了\n                if(window.navigator.userAgent.indexOf('Firefox') >= 0){\n                    ol[0].innerHTML = ol[0].innerHTML;\n                }\n            });\n\n        })();\n    </script>\n    <?php } ?>\n</body>\n</html>\n"
  },
  {
    "path": "tpl/addons/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n    <title>Examples</title>\n    <meta name=\"description\" content=\"\">\n    <meta name=\"keywords\" content=\"\">\n    <link href=\"\" rel=\"stylesheet\">\n</head>\n\n<body>\n</body>\n\n</html>\n"
  },
  {
    "path": "tpl/theme/default/index.html",
    "content": "<!DOCTYPE html>\n<html>\n\n<head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\">\n    <title>前台模版</title>\n    <meta name=\"description\" content=\"\">\n    <meta name=\"keywords\" content=\"\">\n    <link href=\"\" rel=\"stylesheet\">\n</head>\n\n<body>\n抱歉，您还没有模版\n</body>\n\n</html>\n"
  },
  {
    "path": "vendor/autoload.php",
    "content": "<?php\n\n// autoload.php @generated by Composer\n\nrequire_once __DIR__ . '/composer/autoload_real.php';\n\nreturn ComposerAutoloaderInit33b14914409afe305f1e94e39551a057::getLoader();\n"
  },
  {
    "path": "vendor/composer/ClassLoader.php",
    "content": "<?php\n\n/*\n * This file is part of Composer.\n *\n * (c) Nils Adermann <naderman@naderman.de>\n *     Jordi Boggiano <j.boggiano@seld.be>\n *\n * For the full copyright and license information, please view the LICENSE\n * file that was distributed with this source code.\n */\n\nnamespace Composer\\Autoload;\n\n/**\n * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.\n *\n *     $loader = new \\Composer\\Autoload\\ClassLoader();\n *\n *     // register classes with namespaces\n *     $loader->add('Symfony\\Component', __DIR__.'/component');\n *     $loader->add('Symfony',           __DIR__.'/framework');\n *\n *     // activate the autoloader\n *     $loader->register();\n *\n *     // to enable searching the include path (eg. for PEAR packages)\n *     $loader->setUseIncludePath(true);\n *\n * In this example, if you try to use a class in the Symfony\\Component\n * namespace or one of its children (Symfony\\Component\\Console for instance),\n * the autoloader will first look for the class under the component/\n * directory, and it will then fallback to the framework/ directory if not\n * found before giving up.\n *\n * This class is loosely based on the Symfony UniversalClassLoader.\n *\n * @author Fabien Potencier <fabien@symfony.com>\n * @author Jordi Boggiano <j.boggiano@seld.be>\n * @see    http://www.php-fig.org/psr/psr-0/\n * @see    http://www.php-fig.org/psr/psr-4/\n */\nclass ClassLoader\n{\n    // PSR-4\n    private $prefixLengthsPsr4 = array();\n    private $prefixDirsPsr4 = array();\n    private $fallbackDirsPsr4 = array();\n\n    // PSR-0\n    private $prefixesPsr0 = array();\n    private $fallbackDirsPsr0 = array();\n\n    private $useIncludePath = false;\n    private $classMap = array();\n    private $classMapAuthoritative = false;\n    private $missingClasses = array();\n    private $apcuPrefix;\n\n    public function getPrefixes()\n    {\n        if (!empty($this->prefixesPsr0)) {\n            return call_user_func_array('array_merge', $this->prefixesPsr0);\n        }\n\n        return array();\n    }\n\n    public function getPrefixesPsr4()\n    {\n        return $this->prefixDirsPsr4;\n    }\n\n    public function getFallbackDirs()\n    {\n        return $this->fallbackDirsPsr0;\n    }\n\n    public function getFallbackDirsPsr4()\n    {\n        return $this->fallbackDirsPsr4;\n    }\n\n    public function getClassMap()\n    {\n        return $this->classMap;\n    }\n\n    /**\n     * @param array $classMap Class to filename map\n     */\n    public function addClassMap(array $classMap)\n    {\n        if ($this->classMap) {\n            $this->classMap = array_merge($this->classMap, $classMap);\n        } else {\n            $this->classMap = $classMap;\n        }\n    }\n\n    /**\n     * Registers a set of PSR-0 directories for a given prefix, either\n     * appending or prepending to the ones previously set for this prefix.\n     *\n     * @param string       $prefix  The prefix\n     * @param array|string $paths   The PSR-0 root directories\n     * @param bool         $prepend Whether to prepend the directories\n     */\n    public function add($prefix, $paths, $prepend = false)\n    {\n        if (!$prefix) {\n            if ($prepend) {\n                $this->fallbackDirsPsr0 = array_merge(\n                    (array) $paths,\n                    $this->fallbackDirsPsr0\n                );\n            } else {\n                $this->fallbackDirsPsr0 = array_merge(\n                    $this->fallbackDirsPsr0,\n                    (array) $paths\n                );\n            }\n\n            return;\n        }\n\n        $first = $prefix[0];\n        if (!isset($this->prefixesPsr0[$first][$prefix])) {\n            $this->prefixesPsr0[$first][$prefix] = (array) $paths;\n\n            return;\n        }\n        if ($prepend) {\n            $this->prefixesPsr0[$first][$prefix] = array_merge(\n                (array) $paths,\n                $this->prefixesPsr0[$first][$prefix]\n            );\n        } else {\n            $this->prefixesPsr0[$first][$prefix] = array_merge(\n                $this->prefixesPsr0[$first][$prefix],\n                (array) $paths\n            );\n        }\n    }\n\n    /**\n     * Registers a set of PSR-4 directories for a given namespace, either\n     * appending or prepending to the ones previously set for this namespace.\n     *\n     * @param string       $prefix  The prefix/namespace, with trailing '\\\\'\n     * @param array|string $paths   The PSR-4 base directories\n     * @param bool         $prepend Whether to prepend the directories\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function addPsr4($prefix, $paths, $prepend = false)\n    {\n        if (!$prefix) {\n            // Register directories for the root namespace.\n            if ($prepend) {\n                $this->fallbackDirsPsr4 = array_merge(\n                    (array) $paths,\n                    $this->fallbackDirsPsr4\n                );\n            } else {\n                $this->fallbackDirsPsr4 = array_merge(\n                    $this->fallbackDirsPsr4,\n                    (array) $paths\n                );\n            }\n        } elseif (!isset($this->prefixDirsPsr4[$prefix])) {\n            // Register directories for a new namespace.\n            $length = strlen($prefix);\n            if ('\\\\' !== $prefix[$length - 1]) {\n                throw new \\InvalidArgumentException(\"A non-empty PSR-4 prefix must end with a namespace separator.\");\n            }\n            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;\n            $this->prefixDirsPsr4[$prefix] = (array) $paths;\n        } elseif ($prepend) {\n            // Prepend directories for an already registered namespace.\n            $this->prefixDirsPsr4[$prefix] = array_merge(\n                (array) $paths,\n                $this->prefixDirsPsr4[$prefix]\n            );\n        } else {\n            // Append directories for an already registered namespace.\n            $this->prefixDirsPsr4[$prefix] = array_merge(\n                $this->prefixDirsPsr4[$prefix],\n                (array) $paths\n            );\n        }\n    }\n\n    /**\n     * Registers a set of PSR-0 directories for a given prefix,\n     * replacing any others previously set for this prefix.\n     *\n     * @param string       $prefix The prefix\n     * @param array|string $paths  The PSR-0 base directories\n     */\n    public function set($prefix, $paths)\n    {\n        if (!$prefix) {\n            $this->fallbackDirsPsr0 = (array) $paths;\n        } else {\n            $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;\n        }\n    }\n\n    /**\n     * Registers a set of PSR-4 directories for a given namespace,\n     * replacing any others previously set for this namespace.\n     *\n     * @param string       $prefix The prefix/namespace, with trailing '\\\\'\n     * @param array|string $paths  The PSR-4 base directories\n     *\n     * @throws \\InvalidArgumentException\n     */\n    public function setPsr4($prefix, $paths)\n    {\n        if (!$prefix) {\n            $this->fallbackDirsPsr4 = (array) $paths;\n        } else {\n            $length = strlen($prefix);\n            if ('\\\\' !== $prefix[$length - 1]) {\n                throw new \\InvalidArgumentException(\"A non-empty PSR-4 prefix must end with a namespace separator.\");\n            }\n            $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;\n            $this->prefixDirsPsr4[$prefix] = (array) $paths;\n        }\n    }\n\n    /**\n     * Turns on searching the include path for class files.\n     *\n     * @param bool $useIncludePath\n     */\n    public function setUseIncludePath($useIncludePath)\n    {\n        $this->useIncludePath = $useIncludePath;\n    }\n\n    /**\n     * Can be used to check if the autoloader uses the include path to check\n     * for classes.\n     *\n     * @return bool\n     */\n    public function getUseIncludePath()\n    {\n        return $this->useIncludePath;\n    }\n\n    /**\n     * Turns off searching the prefix and fallback directories for classes\n     * that have not been registered with the class map.\n     *\n     * @param bool $classMapAuthoritative\n     */\n    public function setClassMapAuthoritative($classMapAuthoritative)\n    {\n        $this->classMapAuthoritative = $classMapAuthoritative;\n    }\n\n    /**\n     * Should class lookup fail if not found in the current class map?\n     *\n     * @return bool\n     */\n    public function isClassMapAuthoritative()\n    {\n        return $this->classMapAuthoritative;\n    }\n\n    /**\n     * APCu prefix to use to cache found/not-found classes, if the extension is enabled.\n     *\n     * @param string|null $apcuPrefix\n     */\n    public function setApcuPrefix($apcuPrefix)\n    {\n        $this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;\n    }\n\n    /**\n     * The APCu prefix in use, or null if APCu caching is not enabled.\n     *\n     * @return string|null\n     */\n    public function getApcuPrefix()\n    {\n        return $this->apcuPrefix;\n    }\n\n    /**\n     * Registers this instance as an autoloader.\n     *\n     * @param bool $prepend Whether to prepend the autoloader or not\n     */\n    public function register($prepend = false)\n    {\n        spl_autoload_register(array($this, 'loadClass'), true, $prepend);\n    }\n\n    /**\n     * Unregisters this instance as an autoloader.\n     */\n    public function unregister()\n    {\n        spl_autoload_unregister(array($this, 'loadClass'));\n    }\n\n    /**\n     * Loads the given class or interface.\n     *\n     * @param  string    $class The name of the class\n     * @return bool|null True if loaded, null otherwise\n     */\n    public function loadClass($class)\n    {\n        if ($file = $this->findFile($class)) {\n            includeFile($file);\n\n            return true;\n        }\n    }\n\n    /**\n     * Finds the path to the file where the class is defined.\n     *\n     * @param string $class The name of the class\n     *\n     * @return string|false The path if found, false otherwise\n     */\n    public function findFile($class)\n    {\n        // class map lookup\n        if (isset($this->classMap[$class])) {\n            return $this->classMap[$class];\n        }\n        if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {\n            return false;\n        }\n        if (null !== $this->apcuPrefix) {\n            $file = apcu_fetch($this->apcuPrefix.$class, $hit);\n            if ($hit) {\n                return $file;\n            }\n        }\n\n        $file = $this->findFileWithExtension($class, '.php');\n\n        // Search for Hack files if we are running on HHVM\n        if (false === $file && defined('HHVM_VERSION')) {\n            $file = $this->findFileWithExtension($class, '.hh');\n        }\n\n        if (null !== $this->apcuPrefix) {\n            apcu_add($this->apcuPrefix.$class, $file);\n        }\n\n        if (false === $file) {\n            // Remember that this class does not exist.\n            $this->missingClasses[$class] = true;\n        }\n\n        return $file;\n    }\n\n    private function findFileWithExtension($class, $ext)\n    {\n        // PSR-4 lookup\n        $logicalPathPsr4 = strtr($class, '\\\\', DIRECTORY_SEPARATOR) . $ext;\n\n        $first = $class[0];\n        if (isset($this->prefixLengthsPsr4[$first])) {\n            foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {\n                if (0 === strpos($class, $prefix)) {\n                    foreach ($this->prefixDirsPsr4[$prefix] as $dir) {\n                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {\n                            return $file;\n                        }\n                    }\n                }\n            }\n        }\n\n        // PSR-4 fallback dirs\n        foreach ($this->fallbackDirsPsr4 as $dir) {\n            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {\n                return $file;\n            }\n        }\n\n        // PSR-0 lookup\n        if (false !== $pos = strrpos($class, '\\\\')) {\n            // namespaced class name\n            $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)\n                . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);\n        } else {\n            // PEAR-like class name\n            $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;\n        }\n\n        if (isset($this->prefixesPsr0[$first])) {\n            foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {\n                if (0 === strpos($class, $prefix)) {\n                    foreach ($dirs as $dir) {\n                        if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {\n                            return $file;\n                        }\n                    }\n                }\n            }\n        }\n\n        // PSR-0 fallback dirs\n        foreach ($this->fallbackDirsPsr0 as $dir) {\n            if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {\n                return $file;\n            }\n        }\n\n        // PSR-0 include paths.\n        if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {\n            return $file;\n        }\n\n        return false;\n    }\n}\n\n/**\n * Scope isolated include.\n *\n * Prevents access to $this/self from included files.\n */\nfunction includeFile($file)\n{\n    include $file;\n}\n"
  },
  {
    "path": "vendor/composer/LICENSE",
    "content": "\nCopyright (c) 2016 Nils Adermann, Jordi Boggiano\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is furnished\nto do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n"
  },
  {
    "path": "vendor/composer/autoload_classmap.php",
    "content": "<?php\n\n// autoload_classmap.php @generated by Composer\n\n$vendorDir = dirname(dirname(__FILE__));\n$baseDir = dirname($vendorDir);\n\nreturn array(\n    'EasyPeasyICS' => $vendorDir . '/phpmailer/phpmailer/extras/EasyPeasyICS.php',\n    'PHPMailer' => $vendorDir . '/phpmailer/phpmailer/class.phpmailer.php',\n    'PHPMailerOAuth' => $vendorDir . '/phpmailer/phpmailer/class.phpmaileroauth.php',\n    'PHPMailerOAuthGoogle' => $vendorDir . '/phpmailer/phpmailer/class.phpmaileroauthgoogle.php',\n    'POP3' => $vendorDir . '/phpmailer/phpmailer/class.pop3.php',\n    'SMTP' => $vendorDir . '/phpmailer/phpmailer/class.smtp.php',\n    'ntlm_sasl_client_class' => $vendorDir . '/phpmailer/phpmailer/extras/ntlm_sasl_client.php',\n    'phpmailerException' => $vendorDir . '/phpmailer/phpmailer/class.phpmailer.php',\n);\n"
  },
  {
    "path": "vendor/composer/autoload_files.php",
    "content": "<?php\n\n// autoload_files.php @generated by Composer\n\n$vendorDir = dirname(dirname(__FILE__));\n$baseDir = dirname($vendorDir);\n\nreturn array(\n    '9b552a3cc426e3287cc811caefa3cf53' => $vendorDir . '/topthink/think-helper/src/helper.php',\n    '1cfd2761b63b0a29ed23657ea394cb2d' => $vendorDir . '/topthink/think-captcha/src/helper.php',\n    '2364b85cc4f65d1c2b96bf0a1dfa7da5' => $vendorDir . '/qingyuexi/think-addons/src/common.php',\n);\n"
  },
  {
    "path": "vendor/composer/autoload_namespaces.php",
    "content": "<?php\n\n// autoload_namespaces.php @generated by Composer\n\n$vendorDir = dirname(dirname(__FILE__));\n$baseDir = dirname($vendorDir);\n\nreturn array(\n    'PHPExcel' => array($vendorDir . '/phpoffice/phpexcel/Classes'),\n);\n"
  },
  {
    "path": "vendor/composer/autoload_psr4.php",
    "content": "<?php\n\n// autoload_psr4.php @generated by Composer\n\n$vendorDir = dirname(dirname(__FILE__));\n$baseDir = dirname($vendorDir);\n\nreturn array(\n    'think\\\\helper\\\\' => array($vendorDir . '/topthink/think-helper/src'),\n    'think\\\\composer\\\\' => array($vendorDir . '/topthink/think-installer/src'),\n    'think\\\\captcha\\\\' => array($vendorDir . '/topthink/think-captcha/src'),\n    'think\\\\' => array($baseDir . '/thinkphp/library/think', $vendorDir . '/qingyuexi/think-addons/src'),\n    'Flc\\\\Alidayu\\\\' => array($vendorDir . '/flc/alidayu/src/Alidayu'),\n);\n"
  },
  {
    "path": "vendor/composer/autoload_real.php",
    "content": "<?php\n\n// autoload_real.php @generated by Composer\n\nclass ComposerAutoloaderInit33b14914409afe305f1e94e39551a057\n{\n    private static $loader;\n\n    public static function loadClassLoader($class)\n    {\n        if ('Composer\\Autoload\\ClassLoader' === $class) {\n            require __DIR__ . '/ClassLoader.php';\n        }\n    }\n\n    public static function getLoader()\n    {\n        if (null !== self::$loader) {\n            return self::$loader;\n        }\n\n        spl_autoload_register(array('ComposerAutoloaderInit33b14914409afe305f1e94e39551a057', 'loadClassLoader'), true, true);\n        self::$loader = $loader = new \\Composer\\Autoload\\ClassLoader();\n        spl_autoload_unregister(array('ComposerAutoloaderInit33b14914409afe305f1e94e39551a057', 'loadClassLoader'));\n\n        $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());\n        if ($useStaticLoader) {\n            require_once __DIR__ . '/autoload_static.php';\n\n            call_user_func(\\Composer\\Autoload\\ComposerStaticInit33b14914409afe305f1e94e39551a057::getInitializer($loader));\n        } else {\n            $map = require __DIR__ . '/autoload_namespaces.php';\n            foreach ($map as $namespace => $path) {\n                $loader->set($namespace, $path);\n            }\n\n            $map = require __DIR__ . '/autoload_psr4.php';\n            foreach ($map as $namespace => $path) {\n                $loader->setPsr4($namespace, $path);\n            }\n\n            $classMap = require __DIR__ . '/autoload_classmap.php';\n            if ($classMap) {\n                $loader->addClassMap($classMap);\n            }\n        }\n\n        $loader->register(true);\n\n        if ($useStaticLoader) {\n            $includeFiles = Composer\\Autoload\\ComposerStaticInit33b14914409afe305f1e94e39551a057::$files;\n        } else {\n            $includeFiles = require __DIR__ . '/autoload_files.php';\n        }\n        foreach ($includeFiles as $fileIdentifier => $file) {\n            composerRequire33b14914409afe305f1e94e39551a057($fileIdentifier, $file);\n        }\n\n        return $loader;\n    }\n}\n\nfunction composerRequire33b14914409afe305f1e94e39551a057($fileIdentifier, $file)\n{\n    if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) {\n        require $file;\n\n        $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true;\n    }\n}\n"
  },
  {
    "path": "vendor/composer/autoload_static.php",
    "content": "<?php\n\n// autoload_static.php @generated by Composer\n\nnamespace Composer\\Autoload;\n\nclass ComposerStaticInit33b14914409afe305f1e94e39551a057\n{\n    public static $files = array (\n        '9b552a3cc426e3287cc811caefa3cf53' => __DIR__ . '/..' . '/topthink/think-helper/src/helper.php',\n        '1cfd2761b63b0a29ed23657ea394cb2d' => __DIR__ . '/..' . '/topthink/think-captcha/src/helper.php',\n        '2364b85cc4f65d1c2b96bf0a1dfa7da5' => __DIR__ . '/..' . '/qingyuexi/think-addons/src/common.php',\n    );\n\n    public static $prefixLengthsPsr4 = array (\n        't' => \n        array (\n            'think\\\\helper\\\\' => 13,\n            'think\\\\composer\\\\' => 15,\n            'think\\\\captcha\\\\' => 14,\n            'think\\\\' => 6,\n        ),\n        'F' => \n        array (\n            'Flc\\\\Alidayu\\\\' => 12,\n        ),\n    );\n\n    public static $prefixDirsPsr4 = array (\n        'think\\\\helper\\\\' => \n        array (\n            0 => __DIR__ . '/..' . '/topthink/think-helper/src',\n        ),\n        'think\\\\composer\\\\' => \n        array (\n            0 => __DIR__ . '/..' . '/topthink/think-installer/src',\n        ),\n        'think\\\\captcha\\\\' => \n        array (\n            0 => __DIR__ . '/..' . '/topthink/think-captcha/src',\n        ),\n        'think\\\\' => \n        array (\n            0 => __DIR__ . '/../..' . '/thinkphp/library/think',\n            1 => __DIR__ . '/..' . '/qingyuexi/think-addons/src',\n        ),\n        'Flc\\\\Alidayu\\\\' => \n        array (\n            0 => __DIR__ . '/..' . '/flc/alidayu/src/Alidayu',\n        ),\n    );\n\n    public static $prefixesPsr0 = array (\n        'P' => \n        array (\n            'PHPExcel' => \n            array (\n                0 => __DIR__ . '/..' . '/phpoffice/phpexcel/Classes',\n            ),\n        ),\n    );\n\n    public static $classMap = array (\n        'EasyPeasyICS' => __DIR__ . '/..' . '/phpmailer/phpmailer/extras/EasyPeasyICS.php',\n        'PHPMailer' => __DIR__ . '/..' . '/phpmailer/phpmailer/class.phpmailer.php',\n        'PHPMailerOAuth' => __DIR__ . '/..' . '/phpmailer/phpmailer/class.phpmaileroauth.php',\n        'PHPMailerOAuthGoogle' => __DIR__ . '/..' . '/phpmailer/phpmailer/class.phpmaileroauthgoogle.php',\n        'POP3' => __DIR__ . '/..' . '/phpmailer/phpmailer/class.pop3.php',\n        'SMTP' => __DIR__ . '/..' . '/phpmailer/phpmailer/class.smtp.php',\n        'ntlm_sasl_client_class' => __DIR__ . '/..' . '/phpmailer/phpmailer/extras/ntlm_sasl_client.php',\n        'phpmailerException' => __DIR__ . '/..' . '/phpmailer/phpmailer/class.phpmailer.php',\n    );\n\n    public static function getInitializer(ClassLoader $loader)\n    {\n        return \\Closure::bind(function () use ($loader) {\n            $loader->prefixLengthsPsr4 = ComposerStaticInit33b14914409afe305f1e94e39551a057::$prefixLengthsPsr4;\n            $loader->prefixDirsPsr4 = ComposerStaticInit33b14914409afe305f1e94e39551a057::$prefixDirsPsr4;\n            $loader->prefixesPsr0 = ComposerStaticInit33b14914409afe305f1e94e39551a057::$prefixesPsr0;\n            $loader->classMap = ComposerStaticInit33b14914409afe305f1e94e39551a057::$classMap;\n\n        }, null, ClassLoader::class);\n    }\n}\n"
  },
  {
    "path": "vendor/composer/installed.json",
    "content": "[\n    {\n        \"name\": \"topthink/think-installer\",\n        \"version\": \"v1.0.11\",\n        \"version_normalized\": \"1.0.11.0\",\n        \"source\": {\n            \"type\": \"git\",\n            \"url\": \"https://github.com/top-think/think-installer.git\",\n            \"reference\": \"4c6e1ebecd1afce3f4ccc47e147d61bbe1bf641d\"\n        },\n        \"dist\": {\n            \"type\": \"zip\",\n            \"url\": \"https://files.phpcomposer.com/files/top-think/think-installer/4c6e1ebecd1afce3f4ccc47e147d61bbe1bf641d.zip\",\n            \"reference\": \"4c6e1ebecd1afce3f4ccc47e147d61bbe1bf641d\",\n            \"shasum\": \"\"\n        },\n        \"require\": {\n            \"composer-plugin-api\": \"^1.0\"\n        },\n        \"require-dev\": {\n            \"composer/composer\": \"1.0.*@dev\"\n        },\n        \"time\": \"2016-12-01T09:08:45+00:00\",\n        \"type\": \"composer-plugin\",\n        \"extra\": {\n            \"class\": \"think\\\\composer\\\\Plugin\"\n        },\n        \"installation-source\": \"dist\",\n        \"autoload\": {\n            \"psr-4\": {\n                \"think\\\\composer\\\\\": \"src\"\n            }\n        },\n        \"notification-url\": \"https://packagist.org/downloads/\",\n        \"license\": [\n            \"Apache-2.0\"\n        ],\n        \"authors\": [\n            {\n                \"name\": \"yunwuxin\",\n                \"email\": \"448901948@qq.com\"\n            }\n        ]\n    },\n    {\n        \"name\": \"topthink/framework\",\n        \"version\": \"v5.0.8\",\n        \"version_normalized\": \"5.0.8.0\",\n        \"source\": {\n            \"type\": \"git\",\n            \"url\": \"https://github.com/top-think/framework.git\",\n            \"reference\": \"02f8e8a9099c534d1b2c38385fcf1fa5404694d4\"\n        },\n        \"dist\": {\n            \"type\": \"zip\",\n            \"url\": \"https://files.phpcomposer.com/files/top-think/framework/02f8e8a9099c534d1b2c38385fcf1fa5404694d4.zip\",\n            \"reference\": \"02f8e8a9099c534d1b2c38385fcf1fa5404694d4\",\n            \"shasum\": \"\"\n        },\n        \"require\": {\n            \"php\": \">=5.4.0\",\n            \"topthink/think-installer\": \"~1.0\"\n        },\n        \"require-dev\": {\n            \"johnkary/phpunit-speedtrap\": \"^1.0\",\n            \"mikey179/vfsstream\": \"~1.6\",\n            \"phpdocumentor/reflection-docblock\": \"^2.0\",\n            \"phploc/phploc\": \"2.*\",\n            \"phpunit/phpunit\": \"4.8.*\",\n            \"sebastian/phpcpd\": \"2.*\"\n        },\n        \"time\": \"2017-04-28T09:33:15+00:00\",\n        \"type\": \"think-framework\",\n        \"installation-source\": \"dist\",\n        \"autoload\": {\n            \"psr-4\": {\n                \"think\\\\\": \"library/think\"\n            }\n        },\n        \"notification-url\": \"https://packagist.org/downloads/\",\n        \"license\": [\n            \"Apache-2.0\"\n        ],\n        \"authors\": [\n            {\n                \"name\": \"liu21st\",\n                \"email\": \"liu21st@gmail.com\"\n            }\n        ],\n        \"description\": \"the new thinkphp framework\",\n        \"homepage\": \"http://thinkphp.cn/\",\n        \"keywords\": [\n            \"framework\",\n            \"orm\",\n            \"thinkphp\"\n        ]\n    },\n    {\n        \"name\": \"topthink/think-captcha\",\n        \"version\": \"v1.0.7\",\n        \"version_normalized\": \"1.0.7.0\",\n        \"source\": {\n            \"type\": \"git\",\n            \"url\": \"https://github.com/top-think/think-captcha.git\",\n            \"reference\": \"0c55455df26a1626a60d0dc35d2d89002b741d44\"\n        },\n        \"dist\": {\n            \"type\": \"zip\",\n            \"url\": \"https://files.phpcomposer.com/files/top-think/think-captcha/0c55455df26a1626a60d0dc35d2d89002b741d44.zip\",\n            \"reference\": \"0c55455df26a1626a60d0dc35d2d89002b741d44\",\n            \"shasum\": \"\"\n        },\n        \"time\": \"2016-07-06T01:47:11+00:00\",\n        \"type\": \"library\",\n        \"installation-source\": \"dist\",\n        \"autoload\": {\n            \"psr-4\": {\n                \"think\\\\captcha\\\\\": \"src/\"\n            },\n            \"files\": [\n                \"src/helper.php\"\n            ]\n        },\n        \"notification-url\": \"https://packagist.org/downloads/\",\n        \"license\": [\n            \"Apache-2.0\"\n        ],\n        \"authors\": [\n            {\n                \"name\": \"yunwuxin\",\n                \"email\": \"448901948@qq.com\"\n            }\n        ],\n        \"description\": \"captcha package for thinkphp5\"\n    },\n    {\n        \"name\": \"topthink/think-helper\",\n        \"version\": \"v1.0.6\",\n        \"version_normalized\": \"1.0.6.0\",\n        \"source\": {\n            \"type\": \"git\",\n            \"url\": \"https://github.com/top-think/think-helper.git\",\n            \"reference\": \"0c99dc625b0d2d4124e1b6ca15a3ad6f0125963f\"\n        },\n        \"dist\": {\n            \"type\": \"zip\",\n            \"url\": \"https://files.phpcomposer.com/files/top-think/think-helper/0c99dc625b0d2d4124e1b6ca15a3ad6f0125963f.zip\",\n            \"reference\": \"0c99dc625b0d2d4124e1b6ca15a3ad6f0125963f\",\n            \"shasum\": \"\"\n        },\n        \"time\": \"2017-04-05T07:15:37+00:00\",\n        \"type\": \"library\",\n        \"installation-source\": \"dist\",\n        \"autoload\": {\n            \"psr-4\": {\n                \"think\\\\helper\\\\\": \"src\"\n            },\n            \"files\": [\n                \"src/helper.php\"\n            ]\n        },\n        \"notification-url\": \"https://packagist.org/downloads/\",\n        \"license\": [\n            \"Apache-2.0\"\n        ],\n        \"authors\": [\n            {\n                \"name\": \"yunwuxin\",\n                \"email\": \"448901948@qq.com\"\n            }\n        ],\n        \"description\": \"The ThinkPHP5 Helper Package\"\n    },\n    {\n        \"name\": \"qingyuexi/think-addons\",\n        \"version\": \"1.0.3\",\n        \"version_normalized\": \"1.0.3.0\",\n        \"source\": {\n            \"type\": \"git\",\n            \"url\": \"https://github.com/qingyuexi/think-addons.git\",\n            \"reference\": \"8bb03bbeb603123bfef10db13228fb1cdf286d1f\"\n        },\n        \"dist\": {\n            \"type\": \"zip\",\n            \"url\": \"https://files.phpcomposer.com/files/qingyuexi/think-addons/8bb03bbeb603123bfef10db13228fb1cdf286d1f.zip\",\n            \"reference\": \"8bb03bbeb603123bfef10db13228fb1cdf286d1f\",\n            \"shasum\": \"\"\n        },\n        \"require\": {\n            \"php\": \">=5.4.0\",\n            \"topthink/think-helper\": \">=1.0.4\",\n            \"topthink/think-installer\": \">=1.0.10\"\n        },\n        \"time\": \"2017-03-13T06:44:36+00:00\",\n        \"type\": \"library\",\n        \"extra\": {\n            \"think-config\": {\n                \"addons\": \"src/config.php\"\n            }\n        },\n        \"installation-source\": \"dist\",\n        \"autoload\": {\n            \"psr-4\": {\n                \"think\\\\\": \"src/\"\n            },\n            \"files\": [\n                \"src/common.php\"\n            ]\n        },\n        \"notification-url\": \"https://packagist.org/downloads/\",\n        \"license\": [\n            \"Apache-2.0\"\n        ],\n        \"authors\": [\n            {\n                \"name\": \"qingyuexi\",\n                \"email\": \"1604583867@qq.com\",\n                \"homepage\": \"http://www.youtellme.cc\",\n                \"role\": \"Engineer\"\n            }\n        ],\n        \"description\": \"addons package for thinkphp5\",\n        \"homepage\": \"https://github.com/qingyuexi/think-addons\",\n        \"keywords\": [\n            \"addons\",\n            \"qingyuexi-addons\",\n            \"think-addons\",\n            \"thinkphp5\",\n            \"tp5-addons\"\n        ]\n    },\n    {\n        \"name\": \"phpoffice/phpexcel\",\n        \"version\": \"1.8.1\",\n        \"version_normalized\": \"1.8.1.0\",\n        \"source\": {\n            \"type\": \"git\",\n            \"url\": \"https://github.com/PHPOffice/PHPExcel.git\",\n            \"reference\": \"372c7cbb695a6f6f1e62649381aeaa37e7e70b32\"\n        },\n        \"dist\": {\n            \"type\": \"zip\",\n            \"url\": \"https://files.phpcomposer.com/files/PHPOffice/PHPExcel/372c7cbb695a6f6f1e62649381aeaa37e7e70b32.zip\",\n            \"reference\": \"372c7cbb695a6f6f1e62649381aeaa37e7e70b32\",\n            \"shasum\": \"\"\n        },\n        \"require\": {\n            \"ext-xml\": \"*\",\n            \"ext-xmlwriter\": \"*\",\n            \"php\": \">=5.2.0\"\n        },\n        \"time\": \"2015-05-01T07:00:55+00:00\",\n        \"type\": \"library\",\n        \"installation-source\": \"dist\",\n        \"autoload\": {\n            \"psr-0\": {\n                \"PHPExcel\": \"Classes/\"\n            }\n        },\n        \"notification-url\": \"https://packagist.org/downloads/\",\n        \"license\": [\n            \"LGPL\"\n        ],\n        \"authors\": [\n            {\n                \"name\": \"Maarten Balliauw\",\n                \"homepage\": \"http://blog.maartenballiauw.be\"\n            },\n            {\n                \"name\": \"Mark Baker\"\n            },\n            {\n                \"name\": \"Franck Lefevre\",\n                \"homepage\": \"http://blog.rootslabs.net\"\n            },\n            {\n                \"name\": \"Erik Tilt\"\n            }\n        ],\n        \"description\": \"PHPExcel - OpenXML - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine\",\n        \"homepage\": \"http://phpexcel.codeplex.com\",\n        \"keywords\": [\n            \"OpenXML\",\n            \"excel\",\n            \"php\",\n            \"spreadsheet\",\n            \"xls\",\n            \"xlsx\"\n        ]\n    },\n    {\n        \"name\": \"phpmailer/phpmailer\",\n        \"version\": \"v5.2.23\",\n        \"version_normalized\": \"5.2.23.0\",\n        \"source\": {\n            \"type\": \"git\",\n            \"url\": \"https://github.com/PHPMailer/PHPMailer.git\",\n            \"reference\": \"7115df4a6f76281109ebe352900c42403b728bb4\"\n        },\n        \"dist\": {\n            \"type\": \"zip\",\n            \"url\": \"https://files.phpcomposer.com/files/PHPMailer/PHPMailer/7115df4a6f76281109ebe352900c42403b728bb4.zip\",\n            \"reference\": \"7115df4a6f76281109ebe352900c42403b728bb4\",\n            \"shasum\": \"\"\n        },\n        \"require\": {\n            \"php\": \">=5.0.0\"\n        },\n        \"require-dev\": {\n            \"doctrine/annotations\": \"1.2.*\",\n            \"jms/serializer\": \"0.16.*\",\n            \"phpdocumentor/phpdocumentor\": \"2.*\",\n            \"phpunit/phpunit\": \"4.8.*\",\n            \"symfony/debug\": \"2.8.*\",\n            \"symfony/filesystem\": \"2.8.*\",\n            \"symfony/translation\": \"2.8.*\",\n            \"symfony/yaml\": \"2.8.*\",\n            \"zendframework/zend-cache\": \"2.5.1\",\n            \"zendframework/zend-config\": \"2.5.1\",\n            \"zendframework/zend-eventmanager\": \"2.5.1\",\n            \"zendframework/zend-filter\": \"2.5.1\",\n            \"zendframework/zend-i18n\": \"2.5.1\",\n            \"zendframework/zend-json\": \"2.5.1\",\n            \"zendframework/zend-math\": \"2.5.1\",\n            \"zendframework/zend-serializer\": \"2.5.*\",\n            \"zendframework/zend-servicemanager\": \"2.5.*\",\n            \"zendframework/zend-stdlib\": \"2.5.1\"\n        },\n        \"suggest\": {\n            \"league/oauth2-google\": \"Needed for Google XOAUTH2 authentication\"\n        },\n        \"time\": \"2017-03-15T19:32:56+00:00\",\n        \"type\": \"library\",\n        \"installation-source\": \"dist\",\n        \"autoload\": {\n            \"classmap\": [\n                \"class.phpmailer.php\",\n                \"class.phpmaileroauth.php\",\n                \"class.phpmaileroauthgoogle.php\",\n                \"class.smtp.php\",\n                \"class.pop3.php\",\n                \"extras/EasyPeasyICS.php\",\n                \"extras/ntlm_sasl_client.php\"\n            ]\n        },\n        \"notification-url\": \"https://packagist.org/downloads/\",\n        \"license\": [\n            \"LGPL-2.1\"\n        ],\n        \"authors\": [\n            {\n                \"name\": \"Jim Jagielski\",\n                \"email\": \"jimjag@gmail.com\"\n            },\n            {\n                \"name\": \"Marcus Bointon\",\n                \"email\": \"phpmailer@synchromedia.co.uk\"\n            },\n            {\n                \"name\": \"Andy Prevost\",\n                \"email\": \"codeworxtech@users.sourceforge.net\"\n            },\n            {\n                \"name\": \"Brent R. Matzelle\"\n            }\n        ],\n        \"description\": \"PHPMailer is a full-featured email creation and transfer class for PHP\"\n    },\n    {\n        \"name\": \"flc/alidayu\",\n        \"version\": \"v2.0.5\",\n        \"version_normalized\": \"2.0.5.0\",\n        \"source\": {\n            \"type\": \"git\",\n            \"url\": \"https://github.com/flc1125/alidayu.git\",\n            \"reference\": \"03a2b8258c55a8530f191af55b5e18554ef7113c\"\n        },\n        \"dist\": {\n            \"type\": \"zip\",\n            \"url\": \"https://files.phpcomposer.com/files/flc1125/alidayu/03a2b8258c55a8530f191af55b5e18554ef7113c.zip\",\n            \"reference\": \"03a2b8258c55a8530f191af55b5e18554ef7113c\",\n            \"shasum\": \"\"\n        },\n        \"require\": {\n            \"php\": \">=5.4.0\"\n        },\n        \"time\": \"2017-01-25T08:12:30+00:00\",\n        \"type\": \"library\",\n        \"installation-source\": \"dist\",\n        \"autoload\": {\n            \"psr-4\": {\n                \"Flc\\\\Alidayu\\\\\": \"src/Alidayu/\"\n            }\n        },\n        \"notification-url\": \"https://packagist.org/downloads/\",\n        \"license\": [\n            \"MIT\"\n        ],\n        \"description\": \"阿里大于(鱼)API-SDK；适用任何PHP项目，包括Laravel、Yii、Thinkphp等...\",\n        \"keywords\": [\n            \"alidayu\",\n            \"flc\"\n        ]\n    }\n]\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/.gitignore",
    "content": "/nbproject/private/\n.buildpath\n/pages/\n/my/"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/JSSDK.class.php",
    "content": "<?php\n\nclass JSSDK\n{\n    public $appId;\n    public $appSecret;\n    public $url;\n\n    public function __construct($appId, $appSecret, $url)\n    {\n        $this->appId = $appId;\n        $this->appSecret = $appSecret;\n        $this->url = $url;\n    }\n\n\n    public function getSignPackage()\n    {\n        $jsapiTicket = $this->getJsApiTicket();\n        // dump($jsapiTicket);\n        // 注意 URL 一定要动态获取，不能 hardcode.\n        $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? \"https://\" : \"http://\";\n        if($this->url){\n            $url = $this->url;\n        }else{\n            $url = \"$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]\";\n        }\n\n        $timestamp = time();\n        $nonceStr = $this->createNonceStr();\n\n        // 这里参数的顺序要按照 key 值 ASCII 码升序排序\n        $string = \"jsapi_ticket=$jsapiTicket&noncestr=$nonceStr&timestamp=$timestamp&url=$url\";\n\n        $signature = sha1($string);\n\n        $signPackage = array(\n            \"appId\" => $this->appId,\n            \"nonceStr\" => $nonceStr,\n            \"timestamp\" => $timestamp,\n            \"url\" => $url,\n            \"signature\" => $signature,\n            \"rawString\" => $string\n        );\n \n        return $signPackage;\n    }\n\n    public function createNonceStr($length = 16)\n    {\n        $chars = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\n        $str = \"\";\n        for ($i = 0; $i < $length; $i++) {\n            $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);\n        }\n        return $str;\n    }\n\n    public function getJsApiTicket()\n    {\n        // jsapi_ticket 应该全局存储与更新，以下代码以写入到文件中做示例\n        $data = json_decode(file_get_contents(\"./data/jssdk_jsapi_ticket.json\"));\n        if ($data->expire_time < time()) {\n            $accessToken = $this->getAccessToken();\n            // 如果是企业号用以下 URL 获取 ticket\n            // $url = \"https://qyapi.weixin.qq.com/cgi-bin/get_jsapi_ticket?access_token=$accessToken\";\n            $url = \"https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi&access_token=$accessToken\";\n            $res = json_decode($this->httpGet($url));\n            $ticket = $res->ticket;\n            if ($ticket) {\n                $data->expire_time = time() + 7000;\n                $data->jsapi_ticket = $ticket;\n                $fp = fopen(\"./data/jssdk_jsapi_ticket.json\", \"w\");\n                fwrite($fp, json_encode($data));\n                fclose($fp);\n            }\n        } else {\n            $ticket = $data->jsapi_ticket;\n        }\n\n        return $ticket;\n    }\n\n    public function getAccessToken()\n    {\n        // access_token 应该全局存储与更新，以下代码以写入到文件中做示例\n        $data = json_decode(file_get_contents(\"./data/jssdk_access_token.json\"));\n        if ($data->expire_time < time()) {\n            // 如果是企业号用以下URL获取access_token\n            // $url = \"https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=$this->appId&corpsecret=$this->appSecret\";\n            $url = \"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$this->appId&secret=$this->appSecret\";\n            $res = json_decode($this->httpGet($url));\n            $access_token = $res->access_token;\n            if ($access_token) {\n                $data->expire_time = time() + 7000;\n                $data->access_token = $access_token;\n                $fp = fopen(\"./data/jssdk_access_token.json\", \"w\");\n                fwrite($fp, json_encode($data));\n                fclose($fp);\n            }\n        } else {\n            $access_token = $data->access_token;\n        }\n        return $access_token;\n    }\n\n    public function httpGet($url)\n    {\n        $curl = curl_init();\n        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);\n        curl_setopt($curl, CURLOPT_TIMEOUT, 500);\n        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);\n        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);\n        curl_setopt($curl, CURLOPT_URL, $url);\n\n        $res = curl_exec($curl);\n        curl_close($curl);\n\n        return $res;\n    }\n}\n\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/README.md",
    "content": "wechat-php-sdk\n==============\n\n微信公众平台php开发包,细化各项接口操作,支持链式调用,欢迎Fork此项目  \nweixin developer SDK.\n项目地址：**https://github.com/dodgepudding/wechat-php-sdk**  \n项目blog：**http://binsee.github.io/wechat-php-sdk**  \n\n## 使用详解\n使用前需先打开微信帐号的开发模式，详细步骤请查看微信公众平台接口使用说明：  \n微信公众平台： http://mp.weixin.qq.com/wiki/\n微信企业平台： http://qydev.weixin.qq.com/wiki/\n\n微信支付接入文档：\nhttps://mp.weixin.qq.com/cgi-bin/readtemplate?t=business/course2_tmpl&lang=zh_CN\n\n微信多客服：http://dkf.qq.com\n\n\n## 目录 \n> **[wechat.class.php 官方API类库](#user-content-1-wechatclassphp-官方api类库)**  \n> **[qywechat.class.php 企业号API类库](#user-content-6-qywechatclassphp-企业号api类库)**  \n> **[errCode.php|qyerrCode.php 全局返回码类](#user-content-5-errcodephp-全局返回码类)**  \n> **[old_version/wechatpay.class.php 旧版微信支付V2接口类库](#user-content-7-wechatpayclassphp-旧版微信支付V2接口类库)**  \n> ~~**[old_version/wechatext.class.php 非官方扩展API(停止维护)](#user-content-2-wechatextclassphp-非官方扩展api)**~~  \n> ~~**[old_version/wechatauth.class.php 授权登陆(停止维护)](#user-content-3-wechatauthclassphp-授权登陆)**~~  \n> ~~**[old_version/wechat.js 内嵌JS(已废弃)](#user-content-4-wechatjs-内嵌js)**~~  \n> **[为开发框架进行适配](#user-content-为开发框架进行适配)**  \n> **[调用示例](#user-content-调用示例)**  \n\n----------\n\n## 1. wechat.class.php 官方API类库\n调用官方API，具有更灵活的消息分类响应方式，支持链式调用操作 ； \n\n### 主要功能 \n- 接入验证 **（初级权限）**\n- 自动回复（文本、图片、语音、视频、音乐、图文） **（初级权限）**\n- 菜单操作（查询、创建、删除） **（菜单权限）**\n- 客服消息（文本、图片、语音、视频、音乐、图文） **（认证权限）**\n- 二维码（创建临时、永久二维码，获取二维码URL） **（服务号、认证权限）**\n- 长链接转短链接接口 **（服务号、认证权限）**\n- 分组操作（查询、创建、修改、移动用户到分组） **（认证权限）**\n- 网页授权（基本授权，用户信息授权） **（服务号、认证权限）**\n- 用户信息（查询用户基本信息、获取关注者列表） **（认证权限）**\n- 多客服功能（客服管理、获取客服记录、客服会话管理） **（认证权限）**\n- 媒体文件（上传、获取） **（认证权限）**\n- 高级群发 **（认证权限）**\n- 模板消息（设置所属行业、添加模板、发送模板消息） **（服务号、认证权限）**\n- 卡券管理（创建、修改、删除、发放、门店管理等） **（认证权限）**\n- 语义理解 **（服务号、认证权限）**\n- 获取微信服务器IP列表 **（初级权限）**  \n- 微信JSAPI授权(获取ticket、获取签名) **（初级权限）**  \n- 数据统计(用户、图文、消息、接口分析数据) **（认证权限）**  \n> 备注：  \n> 初级权限：基本权限，任何正常的公众号都有此权限  \n> 菜单权限：正常的服务号、认证后的订阅号拥有此权限  \n> 认证权限：分为订阅号、服务号认证，如前缀服务号则仅认证的服务号有此权限，否则为认证后的订阅号、服务号都有此权限  \n> 支付权限：仅认证后的服务号可以申请此权限  \n\n\n### 初始化动作 \n```php\n $options = array(\n\t'token'=>'tokenaccesskey', //填写你设定的key\n\t'encodingaeskey'=>'encodingaeskey', //填写加密用的EncodingAESKey\n\t'appid'=>'wxdk1234567890', //填写高级调用功能的app id, 请在微信开发模式后台查询\n\t'appsecret'=>'xxxxxxxxxxxxxxxxxxx' //填写高级调用功能的密钥\n\t);\n $weObj = new Wechat($options); //创建实例对象\n //TODO：调用$weObj各实例方法\n```\n\n### 被动接口方法:   \n* valid() 验证连接，被动接口处于加密模式时必须调用\n* \n* getRev() 获取微信服务器发来信息(不返回结果)，被动接口必须调用\n* getRevData() 返回微信服务器发来的信息（数组）\n* getRevFrom()  返回消息发送者的userid\n* getRevTo()  返回消息接收者的id（即公众号id）\n* getRevType() 返回接收消息的类型\n* getRevID() 返回消息id\n* getRevCtime() 返回消息发送事件\n* getRevContent() 返回消息内容正文或语音识别结果（文本型）\n* getRevPic() 返回图片信息（图片型信息） 返回数组{'mediaid'=>'','picurl'=>''}\n* getRevLink() 接收消息链接（链接型信息） 返回数组{'url'=>'','title'=>'','description'=>''}\n* getRevGeo() 返回地理位置（位置型信息） 返回数组{'x'=>'','y'=>'','scale'=>'','label'=>''}\n* getRevEventGeo() 返回事件地理位置（事件型信息） 返回数组{'x'=>'','y'=>'','precision'=>''}\n* getRevEvent() 返回事件类型（事件型信息） 返回数组{'event'=>'','key'=>''}\n* getRevScanInfo() 获取自定义菜单的扫码推事件信息，事件类型为`scancode_push`或`scancode_waitmsg` 返回数组array ('ScanType'=>'qrcode','ScanResult'=>'123123')\n* getRevSendPicsInfo() 获取自定义菜单的图片发送事件信息,事件类型为`pic_sysphoto`或`pic_photo_or_album`或`pic_weixin` 数组结构见php文件内方法说明\n* getRevSendGeoInfo() 获取自定义菜单的地理位置选择器事件推送，事件类型为`location_select` 数组结构见php文件内方法说明\n* getRevVoice() 返回语音信息（语音型信息） 返回数组{'mediaid'=>'','format'=>''}\n* getRevVideo() 返回视频信息（视频型信息） 返回数组{'mediaid'=>'','thumbmediaid'=>''}\n* getRevTicket() 返回接收TICKET（扫描带参数二维码,关注或SCAN事件） 返回二维码的ticket值\n* getRevSceneId() 返回二维码的场景值（扫描带参数二维码的关注事件） 返回二维码的参数值\n* getRevTplMsgID() 返回主动推送的消息ID（群发或模板消息事件） 返回MsgID值\n* getRevStatus() 返回模板消息发送状态（模板消息事件） 返回文本：success(成功)|failed:user block(用户拒绝接收)|failed: system failed(发送失败（非用户拒绝）)\n* getRevResult() 返回群发或模板消息发送结果（群发或模板消息事件） 返回数组，内容依事件类型而不同，参考开发文档中群发、模板消息推送事件\n* getRevKFCreate() 返回多客服-接入会话的客服账号（多客服-接入会话事件） 返回文本型\n* getRevKFClose() 返回多客服-处理会话的客服账号（多客服-接入会话事件） 返回文本型\n* getRevKFSwitch() 返回多客服-转接会话信息（多客服-转接会话事件） 返回数组\t{'FromKfAccount' => '','ToKfAccount' => ''}\n* getRevCardPass() 返回卡券-审核通过的卡券ID（卡券-卡券审核事件） 返回文本型\n* getRevCardGet() 返回卡券-用户领取卡券的相关信息（卡券-领取卡券事件） 返回数组{'CardId' => '','IsGiveByFriend' => '','UserCardCode' => ''}\n* getRevCardDel() 返回卡券-用户删除卡券的相关信息（卡券-删除卡券事件） 返回数组{'CardId' => '','UserCardCode' => ''}\n* \n* text($text) 设置文本型消息，参数：文本内容\n* image($mediaid) 设置图片型消息，参数：图片的media_id\n* voice($mediaid) 设置语音型消息，参数：语音的media_id\n* video($mediaid='',$title,$description) 设置视频型消息，参数：视频的media_id、标题、摘要\n* music($title,$desc,$musicurl,$hgmusicurl='',$thumbmediaid='') 设置回复音乐，参数：音乐标题、音乐描述、音乐链接、高音质链接、缩略图的媒体id\n* news($newsData) 设置图文型消息，参数：数组。数组结构见php文件内方法说明\n* image($mediaid) 设置图片型消息，参数：图片的media_id\n* Message($msg = '',$append = false) 设置发送的消息（一般不需要调用这个方法）\n* transfer_customer_service($customer_account = '') 转接多客服，如不指定客服可不提供参数，参数：指定客服的账号\n* reply() 将以上已经设置好的消息，回复给微信服务器\n\n### 预定义常量列表：\n```php\n////消息类型，使用实例调用getRevType()方法取得\nconst MSGTYPE_TEXT = 'text';\nconst MSGTYPE_IMAGE = 'image';\nconst MSGTYPE_LOCATION = 'location';\nconst MSGTYPE_LINK = 'link';\nconst MSGTYPE_EVENT = 'event';\nconst MSGTYPE_MUSIC = 'music';\nconst MSGTYPE_NEWS = 'news';\nconst MSGTYPE_VOICE = 'voice';\nconst MSGTYPE_VIDEO = 'video';\n////事件类型，使用实例调用getRevEvent()方法取得\nconst EVENT_SUBSCRIBE = 'subscribe';       //订阅\nconst EVENT_UNSUBSCRIBE = 'unsubscribe';   //取消订阅\nconst EVENT_SCAN = 'SCAN';                 //扫描带参数二维码\nconst EVENT_LOCATION = 'LOCATION';         //上报地理位置\nconst EVENT_MENU_VIEW = 'VIEW';                     //菜单 - 点击菜单跳转链接\nconst EVENT_MENU_CLICK = 'CLICK';                   //菜单 - 点击菜单拉取消息\nconst EVENT_MENU_SCAN_PUSH = 'scancode_push';       //菜单 - 扫码推事件(客户端跳URL)\nconst EVENT_MENU_SCAN_WAITMSG = 'scancode_waitmsg'; //菜单 - 扫码推事件(客户端不跳URL)\nconst EVENT_MENU_PIC_SYS = 'pic_sysphoto';          //菜单 - 弹出系统拍照发图\nconst EVENT_MENU_PIC_PHOTO = 'pic_photo_or_album';  //菜单 - 弹出拍照或者相册发图\nconst EVENT_MENU_PIC_WEIXIN = 'pic_weixin';         //菜单 - 弹出微信相册发图器\nconst EVENT_MENU_LOCATION = 'location_select';      //菜单 - 弹出地理位置选择器\nconst EVENT_SEND_MASS = 'MASSSENDJOBFINISH';        //发送结果 - 高级群发完成\nconst EVENT_SEND_TEMPLATE = 'TEMPLATESENDJOBFINISH';//发送结果 - 模板消息发送结果\nconst EVENT_KF_SEESION_CREATE = 'kfcreatesession';  //多客服 - 接入会话\nconst EVENT_KF_SEESION_CLOSE = 'kfclosesession';    //多客服 - 关闭会话\nconst EVENT_KF_SEESION_SWITCH = 'kfswitchsession';  //多客服 - 转接会话\nconst EVENT_CARD_PASS = 'card_pass_check';          //卡券 - 审核通过\nconst EVENT_CARD_NOTPASS = 'card_not_pass_check';   //卡券 - 审核未通过\nconst EVENT_CARD_USER_GET = 'user_get_card';        //卡券 - 用户领取卡券\nconst EVENT_CARD_USER_DEL = 'user_del_card';        //卡券 - 用户删除卡券\n```\n\n### 主动接口方法:   \n *  checkAuth($appid,$appsecret,$token) 此处传入公众后台高级接口提供的appid和appsecret, 或者手动指定$token为access_token。函数将返回access_token操作令牌\n *  resetAuth($appid='') 删除验证数据\n *  resetJsTicket($appid='') 删除JSAPI授权TICKET\n *  getJsTicket($appid='',$jsapi_ticket='') 获取JSAPI授权TICKET\n *  getJsSign($url, $timestamp=0, $noncestr='', $appid='') 获取JsApi使用签名信息数组，可只提供url地址 \n *  createMenu($data) 创建菜单 $data菜单结构详见 **[自定义菜单创建接口](http://mp.weixin.qq.com/wiki/index.php?title=自定义菜单创建接口)**\n *  getServerIp() 获取微信服务器IP地址列表 返回数组array('127.0.0.1','127.0.0.1')\n *  getMenu() 获取菜单 \n *  deleteMenu() 删除菜单 \n *  uploadMedia($data, $type) 上传多媒体文件(注意上传大文件时可能需要先调用 set_time_limit(0) 避免超时)\n *  getMedia() 获取接收到的音频、视频媒体文件 \n *  uploadMpVideo($data) 上传视频素材，当需要群发视频时，必须使用此方法得到的MediaID，否则无法显示\n *  uploadArticles($data) 上传图文消息素材\n *  sendMassMessage($data) 高级群发消息\n *  sendGroupMassMessage($data) 高级群发消息（全体或分组群发）\n *  deleteMassMessage($msg_id) 删除群发图文消息\n *  previewMassMessage($data) 预览群发消息\n *  queryMassMessage($msg_id) 查询群发消息发送状态\n *  getQRCode($scene_id,$type=0,$expire=1800) 获取推广二维码ticket字串 \n *  getQRUrl($ticket) 获取二维码图片地址\n *  getShortUrl($long_url) 长链接转短链接接口\n *  getUserList($next_openid) 批量获取关注用户列表 \n *  getUserInfo($openid) 获取关注者详细信息 \n *  updateUserRemark($openid,$remark) 设置用户备注名\n *  getGroup() 获取用户分组列表 \n *  getUserGroup($openid) 获取用户所在分组\n *  createGroup($name) 新增自定分组 \n *  updateGroup($groupid,$name) 更改分组名称 \n *  updateGroupMembers($groupid,$openid) 移动用户分组  \n *  batchUpdateGroupMembers($groupid,$openid_list) 批量移动用户分组 \n *  sendCustomMessage($data) 发送客服消息  \n *  getOauthRedirect($callback,$state,$scope) 获取网页授权oAuth跳转地址  \n *  getOauthAccessToken() 通过回调的code获取网页授权access_token  \n *  getOauthRefreshToken($refresh_token) 通过refresh_token对access_token续期  \n *  getOauthUserinfo($access_token,$openid) 通过网页授权的access_token获取用户资料  \n *  getOauthAuth($access_token,$openid)  检验授权凭证access_token是否有效\n *  getSignature($arrdata,'sha1') 生成签名字串  \n *  generateNonceStr($length=16) 获取随机字串  \n *  setTMIndustry($id1,$id2='') 模板消息，设置所属行业\n *  addTemplateMessage($tpl_id) 模板消息，添加消息模板\n *  sendTemplateMessage($data) 发送模板消息\n *  getCustomServiceMessage($data) 获取多客服会话记录\n *  transfer_customer_service($customer_account) 转发多客服消息\n *  getCustomServiceKFlist() 获取多客服客服基本信息\n *  getCustomServiceOnlineKFlist() 获取多客服在线客服接待信息\n *  createKFSession($openid,$kf_account,$text='') 创建指定多客服会话\n *  closeKFSession($openid,$kf_account,$text='') 关闭指定多客服会话\n *  getKFSession($openid) 获取用户会话状态\n *  getKFSessionlist($kf_account) 获取指定客服的会话列表\n *  getKFSessionWait() 获取未接入会话列表\n *  addKFAccount($account,$nickname,$password) 添加客服账号\n *  updateKFAccount($account,$nickname,$password) 修改客服账号信息\n *  deleteKFAccount($account) 删除客服账号\n *  setKFHeadImg($account,$imgfile) 上传客服头像\n *  querySemantic($uid,$query,$category,$latitude=0,$longitude=0,$city=\"\",$region=\"\") 语义理解接口 参数含义及返回的json内容请查看 **[微信语义理解接口](http://mp.weixin.qq.com/wiki/index.php?title=语义理解)**\n *  getDatacube($type,$subtype,$begin_date,$end_date='') 获取统计数据 参数需注意$type与$subtype的定义\n> 获取统计数据方法 参数定义\n> \n| 数据分类 | $type值(字符串)  | 数据子分类 | $subtype值(字符串) | 时间跨度(天) |\n| --------- | :-------:  | --------- | :------: | ----: |\n| 用户分析 | 'user' | 获取用户增减数据 | 'summary' | 7 |\n| 用户分析 | 'user' | 获取累计用户数据 | 'cumulate' | 7 |\n| 图文分析 | 'article' | 获取图文群发每日数据 | 'summary' | 1 |\n| 图文分析 | 'article' | 获取图文群发总数据 | 'total' | 1 |\n| 图文分析 | 'article' | 获取图文统计数据 | 'read' | 3 |\n| 图文分析 | 'article' | 获取图文统计分时数据 | 'readhour' | 1 |\n| 图文分析 | 'article' | 获取图文分享转发数据 | 'share' | 7 |\n| 图文分析 | 'article' | 获取图文分享转发分时数据 | 'sharehour' | 1 |\n| 消息分析 | 'upstreammsg' | 获取消息发送概况数据 | 'summary' | 7 |\n| 消息分析 | 'upstreammsg' | 获取消息分送分时数据 | 'hour' | 1 |\n| 消息分析 | 'upstreammsg' | 获取消息发送周数据 | 'week' | 30 |\n| 消息分析 | 'upstreammsg' | 获取消息发送月数据 | 'month' | 30 |\n| 消息分析 | 'upstreammsg' | 获取消息发送分布数据 | 'dist' | 15 |\n| 消息分析 | 'upstreammsg' | 获取消息发送分布周数据 | 'distweek' | 30 |\n| 消息分析 | 'upstreammsg' | 获取消息发送分布月数据 | 'distmonth' | 30 |\n| 接口分析 | 'interface' | 获取接口分析数据 | 'summary' | 30 |\n| 接口分析 | 'interface' | 获取接口分析分时数据 | 'summaryhour' | 1 |\n需要注意 `begin_date`和`end_date`的差值需小于“最大时间跨度”（比如最大时间跨度为1时，`begin_date`和`end_date`的差值只能为0，才能小于1）\n\n *  createCard($data) 创建卡券\n *  updateCard($data) 修改卡券\n *  delCard($card_id) 删除卡券\n *  getCardInfo($card_id) 查询卡券详情\n *  getCardColors() 获取颜色列表\n *  getCardLocations() 拉取门店列表\n *  addCardLocations($data) 批量导入门店信息\n *  createCardQrcode($card_id) 生成卡券二维码\n *  consumeCardCode($code) 消耗 code\n *  decryptCardCode($encrypt_code) code 解码\n *  checkCardCode($code) 获取 code 的有效性\n *  getCardIdList($data) 批量查询卡列表\n *  updateCardCode($code,$card_id,$new_code) 更改 code\n *  unavailableCardCode($code,$card_id='') 设置卡券失效**(不可逆)**\n *  modifyCardStock($data) 库存修改\n *  activateMemberCard($data) 激活/绑定会员卡，参数结构请参看卡券开发文档(6.1.1 激活/绑定会员卡)章节\n *  updateMemberCard($data) 会员卡交易，参数结构请参看卡券开发文档(6.1.2 会员卡交易)章节\n *  updateLuckyMoney($code,$balance,$card_id='') 更新红包金额\n *  setCardTestWhiteList($openid=array(),$user=array()) 设置卡券测试白名单\n \n \n## ~~2. wechatext.class.php 非官方扩展API~~  \n**此扩展类库已经不再更新，原因是官方对公众号开放了众多接口，此类库继续维护的意义不大**  \n非官方扩展API，需要配置公众平台账户和密码，能实现对已关注用户的点对点微信，此方式不保证长期有效。  \n类方法里提及的用户id在接口返回结构里表述为FakeId, 属同一概念, 在下面wechatauth类里则表示为Uin, 用户id对应的微信号必须通过getInfo()方法通过返回数组的Username值获取, 但非关注关系用户资料不能获取.  \n调用下列方法前必须经过login()方法和checkValid()验证方法才能获得调用权限. 有的账户无法通过登陆可能因为要求提供验证码, 可以手动登陆后把获取到的cookie写进程序存放cookie的文件解决.  \n程序使用了经过修改的snoopy兼容式HTTP类方法, 在类似BAE/SAE云服务器上可能不能正常运行, 因为云服务的curl方法是经过重写的, 某些header参数如网站来源参数不被支持.  \n\n### 类主要方法:\n *  send($id,$content) 向某用户id发送微信文字信息 \n *  sendNews($id,$msgid) 发送图文消息, 可通过getNewsList获取$msgid\n *  getUserList($page,$pagesize,$groupid) 获取用户信息\n *  getGroupList($page,$pagesize) 获取群组信息\n *  getNewsList($page,$pagesize) 获取图文信息列表 \n *  uploadFile($filepath,$type) 上传附件,包括图片/音频/视频/缩略图\n *  getFileList($type,$page,$pagesize) 获取素材库文件列表\n *  sendImage($id,$fid) 发送图片消息\n *  sendAudio($id,$fid) 发送音频消息\n *  sendVideo($id,$fid) 发送视频消息 \n *  getInfo($id) 根据id获取用户资料,注: 非关注关系用户资料不能获取  \n *  getNewMsgNum($lastid) 获取从$lastid算起新消息的数目  \n *  getTopMsg() 获取最新一条消息的数据, 此方法获取的消息id可以作为检测新消息的$lastid依据  \n *  getMsg($lastid,$offset=0,$perpage=50,$day=0,$today=0,$star=0) 获取最新的消息列表, 列表将返回消息id, 用户id, 消息类型, 文字消息等参数  \n *  消息返回结构:  {\"id\":\"消息id\",\"type\":\"类型号(1为文字,2为图片,3为语音)\",\"fileId\":\"0\",\"hasReply\":\"0\",\"fakeId\":\"用户uid\",\"nickName\":\"昵称\",\"dateTime\":\"时间戳\",\"content\":\"文字内容\"}   \n *  getMsgImage($msgid,$mode='large') 若消息type类型为2, 调用此方法获取图片数据  \n *  getMsgVoice($msgid) 若消息type类型为3, 调用此方法获取语音数据  \n\n## ~~3. wechatauth.class.php 授权登陆~~\n**此扩展类库已经不再更新，原因是官方开放平台对网站应用开放的有授权登陆接口，更标准，更好用。请查看：[微信开放平台](http://open.weixin.qq.com)**  \n通过微信二维码登陆微信的API, 能实现第三方网站同步登陆, 首先程序分别通过get_login_code和get_code_image方法获取授权二维码图片, 然后利用微信手机客户端扫描二维码图片后将自动跳出授权页面, 用户点击授权后即可获取对应的用户资料和头像信息. 详细验证步骤请看test3.php例子.   \n### 类主要方法:\n *  get_login_code() 获取登陆授权码, 通过授权码才能获取二维码  \n *  get_code_image($code='') 将上面获取的授权码转换为图片二维码  \n *  verify_code() 鉴定是否登陆成功,返回200为最终授权成功.  \n *  get_login_info() 鉴定成功后调用此方法即可获取用户基本信息  \n *  get_avatar($url) 获取用户头像图片数据  \n *  logout() 注销登陆  \n\n## ~~4. wechat.js 内嵌JS~~\n**此JS脚本已经废弃不再更新，原因是官方在微信6.0.2版本开放了全新的JSAPI接口，更全面好用。请查看：[微信公众平台WIKI](http://mp.weixin.qq.com/wiki)**\n### 微信内嵌网页特殊功能js调用：\n * WeixinJS.hideOptionMenu() 隐藏右上角按钮\n * WeixinJS.showOptionMenu() 显示右上角按钮\n * WeixinJS.hideToolbar() 隐藏工具栏\n * WeixinJS.showToolbar() 显示工具栏\n * WeixinJS.getNetworkType() 获取网络状态\n * WeixinJS.closeWindow() 关闭窗口\n * WeixinJS.scanQRCode() 扫描二维码\n * WeixinJS.openUrlByExtBrowser(url) 使用浏览器打开网址\n * WeixinJS.jumpToBizProfile(username) 跳转到指定公众账号页面\n * WeixinJS.sendEmail(title,content) 发送邮件\n * WeixinJS.openProductView(latitude,longitude,name,address,scale,infoUrl) 查看地图\n * WeixinJS.addContact(username) 添加微信账号\n * WeixinJS.imagePreview(urls,current) 调出微信内图片预览\n * WeixinJS.payCallback(appId,package,timeStamp,nonceStr,signType,paySign,callback) 微信JsApi支付接口\n * WeixinJS.editAddress(appId,addrSign,timeStamp,nonceStr,callback) 微信JsApi支付接口\n * 通过定义全局变量dataForWeixin配置触发分享的内容：\n ```javascript\n var dataForWeixin={\n\t   appId:\"\",\n\t   MsgImg:\"消息图片路径\",\n\t   TLImg:\"时间线图路径\",\n\t   url:\"分享url路径\",\n\t   title:\"标题\",\n\t   desc:\"描述\",\n\t   fakeid:\"\",\n\t   callback:function(){}\n\t};\n ```\n\n## 5. errCode.php 全局返回码类\n当调用API接口失败时，可以用此类来换取失败原因的中文说明。  \n注意：微信公众号引用`errCode.php`，企业号引用`qyerrCode.php`。\n\n### 使用方法：\n```php\ninclude \"errCode.php\";  //或 qyerrCode.php\n\n$ret=ErrCode::getErrText(48001); //错误码可以通过公众号类库的公开变量errCode得到\n\nif ($ret) \n\techo $ret;\nelse \n    echo \"未找到对应的内容\";\n\n```\n\n## 6. qywechat.class.php 企业号API类库 \n调用官方API，具有更灵活的消息分类响应方式，支持链式调用操作 ； \n\n### 主要功能 \n- 接入验证\n- 自动回复（文本、图片、语音、视频、音乐、图文）\n- 菜单操作（查询、创建、删除）\n- 部门管理（创建、更新、删除、获取部门列表）\n- 成员管理（创建、更新、删除、获取成员信息，获取部门成员列表）\n- 标签管理（创建、更新、删除、获取成员、添加成员、删除成员,获取标签列表）\n- 媒体文件管理（上传、获取）\n- 二次验证\n- OAuth2（生成授权url、获取成员信息）\n- 获取企业微信服务器IP列表\n- 微信JSAPI授权(获取ticket、获取签名)\n\n\n### 初始化动作 \n```php\n$options = array(\n  'token'=>'tokenaccesskey', //填写应用接口的Token\n  'encodingaeskey'=>'encodingaeskey', //填写加密用的EncodingAESKey\n  'appid'=>'wxdk1234567890', //填写高级调用功能的app id\n  'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥\n  'agentid'=>'1', //应用的id\n  'debug'=>false, //调试开关\n  '_logcallback'=>'logg', //调试输出方法，需要有一个string类型的参数\n);\n $weObj = new Wechat($options); //创建实例对象\n //TODO：调用$weObj各实例方法\n\n```\n\n### 被动接口方法:   \n* valid() 验证连接，被动接口必须调用\n* \n* getRev() 获取微信服务器发来信息(不返回结果)，被动接口必须调用\n* getRevData() 返回微信服务器发来的信息（数组）\n* getRevPostXml() 返回微信服务器发来的原始加密xml信息\n* getRevFrom()  返回消息发送者的userid\n* getRevTo()  返回消息接收者的id（即公众号id，一般与等同appid一致）\n* getRevAgentID() 返回接收消息的应用id\n* getRevType() 返回接收消息的类型\n* getRevID() 返回消息id\n* getRevCtime() 返回消息发送事件\n* getRevContent() 返回消息内容正文（文本型消息）\n* getRevPic() 返回图片信息（图片型信息） 返回数组{'mediaid'=>'','picurl'=>''}\n* getRevGeo() 返回地理位置（位置型信息） 返回数组{'x'=>'','y'=>'','scale'=>'','label'=>''}\n* getRevEventGeo() 返回事件地理位置（事件型信息） 返回数组{'x'=>'','y'=>'','precision'=>''}\n* getRevEvent() 返回事件类型（事件型信息） 返回数组{'event'=>'','key'=>''}\n* getRevScanInfo() 获取自定义菜单的扫码推事件信息，事件类型为`scancode_push`或`scancode_waitmsg` 返回数组array ('ScanType'=>'qrcode','ScanResult'=>'123123')\n* getRevSendPicsInfo() 获取自定义菜单的图片发送事件信息,事件类型为`pic_sysphoto`或`pic_photo_or_album`或`pic_weixin` 数组结构见php文件内方法说明\n* getRevSendGeoInfo() 获取自定义菜单的地理位置选择器事件推送，事件类型为`location_select` 数组结构见php文件内方法说明\n* getRevVoice() 返回语音信息（语音型信息） 返回数组{'mediaid'=>'','format'=>''}\n* getRevVideo() 返回视频信息（视频型信息） 返回数组{'mediaid'=>'','thumbmediaid'=>''}\n* \n* text($text) 设置文本型消息，参数：文本内容\n* image($mediaid) 设置图片型消息，参数：图片的media_id\n* voice($mediaid) 设置语音型消息，参数：语音的media_id\n* video($mediaid='',$title,$description) 设置视频型消息，参数：视频的media_id、标题、摘要\n* news($newsData) 设置图文型消息，参数：数组。数组结构见php文件内方法说明\n* image($mediaid) 设置图片型消息，参数：图片的media_id\n* Message($msg = '',$append = false) 设置发送的消息（一般不需要调用这个方法）\n* reply() 将已经设置好的消息，回复给微信服务器\n  \n### 预定义常量列表：\n```php\n////消息类型，使用实例调用getRevType()方法取得\n    const MSGTYPE_TEXT = 'text';\n    const MSGTYPE_IMAGE = 'image';\n    const MSGTYPE_LOCATION = 'location';\n    const MSGTYPE_LINK = 'link';    //暂不支持\n    const MSGTYPE_EVENT = 'event';\n    const MSGTYPE_MUSIC = 'music';    //暂不支持\n    const MSGTYPE_NEWS = 'news';\n    const MSGTYPE_VOICE = 'voice';\n    const MSGTYPE_VIDEO = 'video';\n////事件类型，使用实例调用getRevEvent()方法取得\n    const EVENT_SUBSCRIBE = 'subscribe';       //订阅\n    const EVENT_UNSUBSCRIBE = 'unsubscribe';   //取消订阅\n    const EVENT_LOCATION = 'LOCATION';         //上报地理位置\n    const EVENT_ENTER_AGENT = 'enter_agent';   //用户进入应用\n    const EVENT_MENU_VIEW = 'VIEW';                     //菜单 - 点击菜单跳转链接\n    const EVENT_MENU_CLICK = 'CLICK';                   //菜单 - 点击菜单拉取消息\n    const EVENT_MENU_SCAN_PUSH = 'scancode_push';       //菜单 - 扫码推事件(客户端跳URL)\n    const EVENT_MENU_SCAN_WAITMSG = 'scancode_waitmsg'; //菜单 - 扫码推事件(客户端不跳URL)\n    const EVENT_MENU_PIC_SYS = 'pic_sysphoto';          //菜单 - 弹出系统拍照发图\n    const EVENT_MENU_PIC_PHOTO = 'pic_photo_or_album';  //菜单 - 弹出拍照或者相册发图\n    const EVENT_MENU_PIC_WEIXIN = 'pic_weixin';         //菜单 - 弹出微信相册发图器\n    const EVENT_MENU_LOCATION = 'location_select';      //菜单 - 弹出地理位置选择器\n    const EVENT_SEND_MASS = 'MASSSENDJOBFINISH';        //发送结果 - 高级群发完成\n    const EVENT_SEND_TEMPLATE = 'TEMPLATESENDJOBFINISH';//发送结果 - 模板消息发送结果\n```\n\n### 主动接口方法：\n* checkAuth($appid='',$appsecret='',$token='') 通用auth验证方法,也用来换取ACCESS_TOKEN 。仅在需要手动指定access_token时才用`$token`\n* resetAuth($appid='') 清除记录的ACCESS_TOKEN\n* resetJsTicket($appid='') 删除JSAPI授权TICKET\n* getJsTicket($appid='',$jsapi_ticket='') 获取JSAPI授权TICKET\n* getJsSign($url, $timestamp=0, $noncestr='', $appid='') 获取JsApi使用签名信息数组，可只提供url地址 \n* getSignature($arrdata,'sha1') 生成签名字串  \n* generateNonceStr($length=16) 获取随机字串  \n* createMenu($data,$agentid='') 创建菜单,参数:菜单内容数组,要创建菜单应用id\n* getMenu($agentid='') 获取菜单内容,参数:要获取菜单内容的应用id\n* deleteMenu($agentid='') 删除菜单,参数:要删除菜单的应用id\n* uploadMedia($data, $type) 上传媒体文件,参数请看php文件内方法说明(注意上传大文件时可能需要先调用 set_time_limit(0) 避免超时)\n* getMedia($media_id) 根据媒体文件ID获取媒体文件,参数:媒体id\n* getServerIp() 获取企业微信服务器IP地址列表 返回数组array('127.0.0.1','127.0.0.1')\n* createDepartment($data) 创建部门,参数: array(\"name\"=>\"邮箱产品组\",\"parentid\"=>\"1\",\"order\" =>  \"1\")\n* updateDepartment($data) 更新部门,参数: array(\"id\"=>\"1\"，\"name\"=>\"邮箱产品组\",\"parentid\"=>\"1\",\"order\" =>  \"1\")\n* deleteDepartment($id) 删除部门,参数：要删除的部门id\n* moveDepartment($data) 移动部门,参数：array(\"department_id\" => \"5\",\"to_parentid\" => \"2\",\"to_position\" => \"1\")\n* getDepartment() 获取部门列表，返回部门数组。其中department部门列表数据。以部门的order字段从小到大排列\n* createUser($data) 创建成员，参数请看php文件内方法说明\n* updateUser($data) 更新成员，参数请看php文件内方法说明\n* deleteUser($userid) 删除成员，参数：员工UserID\n* deleteUsers($userids) 批量删除成员，参数：员工UserID数组\n* getUserInfo($userid) 获取成员信息，参数：员工UserID\n* getUserList($department_id,$fetch_child=0,$status=0) 获取部门成员，参数：部门id，是否递归获取子部门，获取类型。\n> 0获取全部员工，1获取已关注成员列表，2获取禁用成员列表，4获取未关注成员列表。status可叠加\n* getUserListInfo($department_id,$fetch_child=0,$status=0) 获取部门成员详情，参数同上\n* getUserId($code,$agentid) 根据code获取员工UserID与手机设备号，参数：Oauth2.0或者二次验证返回的code值，跳转链接时所在的企业应用ID\n* sendInvite($userid,$invite_tips='') 邀请成员关注\n* createTag($data) 创建标签，参数：array(\"tagname\" => \"UI\")\n* updateTag($data) 更新标签，参数：array(\"tagid\" => \"1\",\"tagname\" => \"UI\")\n* deleteTag($tagid) 删除标签，参数：标签TagID\n* getTag($tagid) 获取标签成员，参数：标签TagID\n* addTagUser($data) 增加标签成员，参数请看php文件内方法说明\n* delTagUser($data) 删除标签成员，参数请看php文件内方法说明\n* getTagList() 获取标签列表，返回标签数组\n* sendMessage($data) 主动发送信息接口，参数请看php文件内方法说明\n* authSucc($userid) 二次验证，参数： 员工UserID\n* getOauthRedirect($callback,$state='STATE',$scope='snsapi_base') 组合授权跳转接口url\n\n\n## 7. wechatpay.class.php 旧版微信支付V2接口类库\n旧版微信支付类库(微信支付V2)，已移动至old_version目录下。  \n自2014年8月开始申请到的微信支付都是V3接口，据官方说V2的会陆续升级为V3接口，但时间及升级渠道未确认。\n\n### 主要功能 \n- 获取access_token **（初级权限）**\n- 调用地址组件 **（支付权限）**\n- 生成订单签名数据 **（支付权限）**\n- 订单成功回调 **（支付权限）**\n- 发货通知 **（支付权限）**\n- 支付订单查询 **（支付权限）**  \n> 备注：  \n> 初级权限：基本权限，任何正常的公众号都有此权限  \n> 菜单权限：正常的服务号、认证后的订阅号拥有此权限  \n> 认证权限：分为订阅号、服务号认证，如前缀服务号则仅认证的服务号有此权限，否则为认证后的订阅号、服务号都有此权限  \n> 支付权限：仅认证后的服务号可以申请此权限  \n\n\n### 初始化动作 \n```php\n $options = array(\n\t'appid'=>'wxdk1234567890', //填写高级调用功能的app id, 请在微信开发模式后台查询\n\t'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥\n\t'partnerid'=>'88888888', //财付通商户身份标识，支付权限专用，没有可不填\n\t'partnerkey'=>'', //财付通商户权限密钥Key，支付权限专用\n\t'paysignkey'=>'' //商户签名密钥Key，支付权限专用\n\t);\n $weObj = new Wechat($options); //创建实例对象\n //TODO：调用$weObj各实例方法\n```\n\n### 主动接口方法:   \n *  checkAuth($appid='',$appsecret='',$token='') 获取access_token。可根据appid和appsecret获取，或手动指定access_token\n *  resetAuth($appid='') 删除验证数据\n *  getSignature($arrdata,'sha1') 生成签名字串  \n *  generateNonceStr($length=16) 获取随机字串  \n *  createNativeUrl($productid) 生成原生支付url\n *  createPackage($out_trade_no,$body,$total_fee,$notify_url,$spbill_create_ip,$fee_type=1,$bank_type=\"WX\",$input_charset=\"UTF-8\",$time_start=\"\",$time_expire=\"\",$transport_fee=\"\",$product_fee=\"\",$goods_tag=\"\",$attach=\"\") 生成订单package字符串  \n *  getPaySign($package, $timeStamp, $nonceStr) 支付签名(paySign)生成方法  \n *  checkOrderSignature($orderxml='') 回调通知签名验证  \n *  sendPayDeliverNotify($openid,$transid,$out_trade_no,$status=1,$msg='ok') 发货通知  \n *  getPayOrder($out_trade_no) 查询订单信息  \n *  setUserToken($user_token) 设置用户授权密钥\n *  getAddrSign($url, $timeStamp, $nonceStr, $user_token='') 获取收货地址JS的签名\n\n\n## 为开发框架进行适配\n为不同的开发框架进行适配缓存操作(保存access_token、jsapi_ticket)，及输出调试日志。\n\n由于微信api需要缓存access_token与jsapi_ticket，而在不同框架下的缓存方式不同，所以原先在Wechat.class.php和QYWechat.class.php中缓存代码做了TODO标志。\n需要各位在使用不同框架时再进行修改，但确实很麻烦，因为对结构进行了修改。\n\n>取消了原先同步维护的Thinkphp版本，为Wechat类增加操作缓存3个重载方法`setCache`, `getCache`, `removeCache`，以及修改`log`方法可以重载。\n>分别来实现在不同开发框架下的设置缓存、读取缓存、清除缓存、日志输出4个功能。  \n\n在不同的开发框架下使用Wechat类库，请继承Wechat类，根据需要实现这4个方法。  \n可参考Thinkphp版的`TPWechat.class.php`为不同框架进行适配。\n欢迎提交其他框架的适配文件到项目库来。  \n\n为Thinkphp进行适配的示例如下：\n```php\n/**\n *\t微信公众平台PHP-SDK, ThinkPHP实例\n *  @author dodgepudding@gmail.com\n *  @link https://github.com/dodgepudding/wechat-php-sdk\n *  @version 1.2\n *  usage:\n *   $options = array(\n *\t\t\t'token'=>'tokenaccesskey', //填写你设定的key\n *\t\t\t'encodingaeskey'=>'encodingaeskey', //填写加密用的EncodingAESKey\n *\t\t\t'appid'=>'wxdk1234567890', //填写高级调用功能的app id\n *\t\t\t'appsecret'=>'xxxxxxxxxxxxxxxxxxx' //填写高级调用功能的密钥\n *\t\t);\n *\t $weObj = new TPWechat($options);\n *   $weObj->valid();\n *   ...\n *  \n */\nclass TPWechat extends Wechat\n{\n\t/**\n\t * log overwrite\n\t * @see Wechat::log()\n\t */\n\tprotected function log($log){\n\t\tif ($this->debug) {\n\t\t\tif (function_exists($this->logcallback)) {\n\t\t\t\tif (is_array($log)) $log = print_r($log,true);\n\t\t\t\treturn call_user_func($this->logcallback,$log);\n\t\t\t}elseif (class_exists('Log')) {\n\t\t\t\tLog::write('wechat：'.$log, Log::DEBUG);\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 重载设置缓存\n\t * @param string $cachename\n\t * @param mixed $value\n\t * @param int $expired\n\t * @return boolean\n\t */\n\tprotected function setCache($cachename,$value,$expired){\n\t\treturn S($cachename,$value,$expired);\n\t}\n\t\n\t/**\n\t * 重载获取缓存\n\t * @param string $cachename\n\t * @return mixed\n\t */\n\tprotected function getCache($cachename){\n\t\treturn S($cachename);\n\t}\n\t\n\t/**\n\t * 重载清除缓存\n\t * @param string $cachename\n\t * @return boolean\n\t */\n\tprotected function removeCache($cachename){\n\t\treturn S($cachename,null);\n\t}\n}\n```\n\n\n\n# 调用示例\n----------\n\n## 官方Wechat调用示例：\n```php\n//test1.php\ninclude \"wechat.class.php\";\n$options = array(\n\t\t'token'=>'tokenaccesskey', //填写你设定的key\n        'encodingaeskey'=>'encodingaeskey' //填写加密用的EncodingAESKey，如接口为明文模式可忽略\n\t);\n$weObj = new Wechat($options);\n$weObj->valid();//明文或兼容模式可以在接口验证通过后注释此句，但加密模式一定不能注释，否则会验证失败\n$type = $weObj->getRev()->getRevType();\nswitch($type) {\n\tcase Wechat::MSGTYPE_TEXT:\n\t\t\t$weObj->text(\"hello, I'm wechat\")->reply();\n\t\t\texit;\n\t\t\tbreak;\n\tcase Wechat::MSGTYPE_EVENT:\n\t\t\tbreak;\n\tcase Wechat::MSGTYPE_IMAGE:\n\t\t\tbreak;\n\tdefault:\n\t\t\t$weObj->text(\"help info\")->reply();\n}\n```\n\n## 企业号API类库调用示例：\n可参考**test**目录下的**qydemo.php**\n```php\ninclude \"wechat.class.php\";\n$options = array(\n        'token'=>'9Ixxxxxxx',\t//填写应用接口的Token\n        'encodingaeskey'=>'d4o9WVg8sxxxxxxxxxxxxxxxxxxxxxx',//填写加密用的EncodingAESKey\n        'appid'=>'wxa07979baxxxxxxxx',\t//填写高级调用功能的appid\n);\n$weObj = new Wechat($options);\n$weObj->valid(); //注意, 企业号与普通公众号不同，必须打开验证，不要注释掉\n$type = $weObj->getRev()->getRevType();\nswitch($type) {\n\tcase Wechat::MSGTYPE_TEXT:\n\t\t\t$weObj->text(\"hello, I'm wechat\")->reply();\n\t\t\texit;\n\t\t\tbreak;\n\tcase Wechat::MSGTYPE_EVENT:\n\t\t\tbreak;\n\tcase Wechat::MSGTYPE_IMAGE:\n\t\t\tbreak;\n\tdefault:\n\t\t\t$weObj->text(\"help info\")->reply();\n}\n```\n\n## 扩展包Wechatext调用示例: \n```php\n// old_version/test/test2.php \n\tinclude \"wechatext.class.php\";\n\t\n\tfunction logdebug($text){\n\t\tfile_put_contents('./data/log.txt',$text.\"\\n\",FILE_APPEND);\t\t\n\t};\n\t\n\t$options = array(\n\t\t'account'=>'demo@domain.com',\n\t\t'password'=>'demo',\n\t\t'datapath'=>'./data/cookie_',\n\t\t\t'debug'=>true,\n\t\t\t'logcallback'=>'logdebug'\t\n\t); \n\t$wechat = new Wechatext($options);\n\tif ($wechat->checkValid()) {\n\t\t// 获取用户信息\n\t\t$data = $wechat->getInfo('3974255');\n\t\tvar_dump($data);\n\t\t// 获取最新一条消息\n\t\t$topmsg = $wechat->getTopMsg();\n\t\tvar_dump($topmsg);\n\t\t// 主动回复消息\n\t\tif ($topmsg && $topmsg['has_reply']==0)\n\t\t$wechat->send($topmsg['fakeid'],'hi '.$topmsg['nick_name'].',rev:'.$topmsg['content']);\t\n\t}\n```\n\n## 微信二维码Wechatauth登陆示例: \n```php\n// old_version/test/test3.php\n\tinclude \"../wechatauth.class.php\";\n\tsession_start();\n\t$sid  = session_id();\n\t$options = array(\n\t\t'account'=>$sid,\n\t\t'datapath'=>'../data/cookiecode_',\n\t); \n\t$wechat = new Wechatauth($options);\n\t\n\tif (isset($_POST['code'])) {\n\t\t$logincode = $_POST['code'];\n\t\t$vres = $wechat->set_login_code($logincode)->verify_code();\n\t\tif ($vres===false) {\n\t\t\t$result = array('status'=>0);\n\t\t} else {\n\t\t\t$result = array('status'=>$vres);\n\t\t\tif ($vres==200) {\n\t\t\t\t$result['info'] = $wechat->get_login_info();\n\t\t\t\t$result['cookie'] = $wechat->get_login_cookie(true);\n\t\t\t}\n\t\t}\n\t\t\n\t\tdie(json_encode($result));\t\n\t}\n\t$logincode =  $wechat->get_login_code(); //获取授权码\n\t$qrimg = $wechat->get_code_image(); //待输出的二维码图片\n```\nHTML部分请看old_version/test/test3.php, 主要是定时ajax查询是否已经授权成功\n\n## 新版微信JSAPI调用DEMO: \n请看test/jsapi目录\n\nLicense\n-------\nThis is licensed under the GNU LGPL, version 2.1 or later.   \nFor details, see: http://creativecommons.org/licenses/LGPL/2.1/\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/Thinkphp/EasyWechat.class.php",
    "content": "<?php\n/**\n *    微信公众平台PHP-SDK, 简单缓存实例\n *  @author binsee@163.com\n *  @link https://github.com/binsee/wechat-php-sdk\n *  @version 0.1\n *  usage:\n *   $options = array(\n *            'token'=>'tokenaccesskey', //填写你设定的key\n *            'encodingaeskey'=>'encodingaeskey', //填写加密用的EncodingAESKey\n *            'appid'=>'wxdk1234567890', //填写高级调用功能的app id\n *            'cachedir'=>'./cache/', //填写缓存目录，默认为当前运行目录的子目录cache下\n *            'logfile'=>'run.log' //填写日志输出文件，可选项。如果没有提供logcallback回调，且设置了输出文件则将日志输出至此文件，如果省略则不输出\n *        );\n *     $weObj = new EasyWechat($options);\n *   $weObj->valid();\n *   ...\n *\n */\nclass EasyWechat extends Wechat\n{\n    private $cachedir = '';\n    private $logfile = '';\n\n    public function __construct($options)\n    {\n        $this->cachedir = isset($options['cachedir']) ? dirname($options['cachedir'].'/.cache') . '/' : 'cache/';\n        $this->logfile = isset($options['logfile']) ? $options['logfile'] : '';\n        if ($this->cachedir) $this->checkDir($this->cachedir);\n        parent::__construct($options);\n    }\n\n    /**\n     * log overwrite\n     * @param string|array $log\n     */\n    protected function log($log){\n        if (is_array($log)) $log = print_r($log,true);\n        if ($this->debug) {\n            if (function_exists($this->logcallback)) {\n                return call_user_func($this->logcallback,$log);\n            }elseif ($this->logfile) {\n                return file_put_contents($this->logfile, $log.\"\\n\", FILE_APPEND) > 0 ? true : false;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * 重载设置缓存\n     * @param string $cachename\n     * @param mixed $value\n     * @param int $expired 缓存秒数，如果为0则为长期缓存\n     * @return boolean\n     */\n    protected function setCache($cachename,$value,$expired=0){\n        $file = $this->cachedir . $cachename . '.cache';\n        $data = array(\n                'value' => $value,\n                'expired' => $expired ? time() + $expired : 0\n        );\n        return file_put_contents( $file, serialize($data) ) ? true : false;\n    }\n\n    /**\n     * 重载获取缓存\n     * @param string $cachename\n     * @return mixed\n     */\n    protected function getCache($cachename){\n        $file = $this->cachedir . $cachename . '.cache';\n        if (!is_file($file)) {\n           return false;\n        }\n        $data = unserialize(file_get_contents( $file ));\n        if (!is_array($data) || !isset($data['value']) || (!empty($data['value']) && $data['expired']<time())) {\n            @unlink($file);\n            return false;\n        }\n        return $data['value'];\n    }\n\n    /**\n     * 重载清除缓存\n     * @param string $cachename\n     * @return boolean\n     */\n    protected function removeCache($cachename){\n        $file = $this->cachedir . $cachename . '.cache';\n        if ( is_file($file) ) {\n            @unlink($file);\n        }\n        return true;\n    }\n\n    private function checkDir($dir, $mode=0777) {\n        if (!$dir)  return false;\n        if(!is_dir($dir)) {\n            if (!file_exists($dir) && @mkdir($dir, $mode, true))\n                return true;\n            return false;\n        }\n        return true;\n    }\n}\n\n\n\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/Thinkphp/TPWechat.class.php",
    "content": "<?php\n/**\n *\t微信公众平台PHP-SDK, ThinkPHP实例\n *  @author dodgepudding@gmail.com\n *  @link https://github.com/dodgepudding/wechat-php-sdk\n *  @version 1.2\n *  usage:\n *   $options = array(\n *\t\t\t'token'=>'tokenaccesskey', //填写你设定的key\n *\t\t\t'encodingaeskey'=>'encodingaeskey', //填写加密用的EncodingAESKey\n *\t\t\t'appid'=>'wxdk1234567890', //填写高级调用功能的app id\n *\t\t\t'appsecret'=>'xxxxxxxxxxxxxxxxxxx' //填写高级调用功能的密钥\n *\t\t);\n *\t $weObj = new TPWechat($options);\n *   $weObj->valid();\n *   ...\n *\n */\nclass TPWechat extends Wechat\n{\n\t/**\n\t * log overwrite\n\t * @see Wechat::log()\n\t */\n\tprotected function log($log){\n\t\tif ($this->debug) {\n\t\t\tif (function_exists($this->logcallback)) {\n\t\t\t\tif (is_array($log)) $log = print_r($log,true);\n\t\t\t\treturn call_user_func($this->logcallback,$log);\n\t\t\t}elseif (class_exists('Log')) {\n\t\t\t\tLog::write('wechat：'.$log, Log::DEBUG);\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 重载设置缓存\n\t * @param string $cachename\n\t * @param mixed $value\n\t * @param int $expired\n\t * @return boolean\n\t */\n\tprotected function setCache($cachename,$value,$expired){\n\t\treturn S($cachename,$value,$expired);\n\t}\n\n\t/**\n\t * 重载获取缓存\n\t * @param string $cachename\n\t * @return mixed\n\t */\n\tprotected function getCache($cachename){\n\t\treturn S($cachename);\n\t}\n\n\t/**\n\t * 重载清除缓存\n\t * @param string $cachename\n\t * @return boolean\n\t */\n\tprotected function removeCache($cachename){\n\t\treturn S($cachename,null);\n\t}\n\n}\n\n\n\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/WxPrint.class.php",
    "content": "<?php \n/**\n * ELind Openapi SDK For PHP, Version:1.0\n * Api WebSite :http://open.10ss.net/\n * Api Doc :http://doc.10ss.net/\n * @filename : print.class.php\n * @author   : heqian@yilianyun.net\n * @date     : 2016-07-11\n */\nclass WxPrint{\n\n/**\n * 生成签名sign\n * @param  array $params 参数\n * @param  string $apiKey API密钥\n * @param  string $msign 打印机密钥\n * @return   string sign\n */\npublic function generateSign($params, $apiKey,$msign)\n{\n    //所有请求参数按照字母先后顺序排\n    ksort($params);\n    //定义字符串开始所包括的字符串\n    $stringToBeSigned = $apiKey;\n    //把所有参数名和参数值串在一起\n    foreach ($params as $k => $v)\n    {\n        $stringToBeSigned .= urldecode($k.$v);\n    }\n    unset($k, $v);\n    //定义字符串结尾所包括的字符串\n    $stringToBeSigned .= $msign;\n    //使用MD5进行加密，再转化成大写\n    return strtoupper(md5($stringToBeSigned));\n}\n/**\n * 生成字符串参数\n * @param array $param 参数\n * @return  string        参数字符串\n */\npublic function getStr($param)\n{\n    $str = '';\n    foreach ($param as $key => $value) {\n        $str=$str.$key.'='.$value.'&';\n    }\n    $str = rtrim($str,'&');\n    return $str;\n}\n/**\n * 打印接口\n * @param  int $partner     用户ID\n * @param  string $machine_code 打印机终端号\n * @param  string $content      打印内容\n * @param  string $apiKey       API密钥\n * @param  string $msign       打印机密钥\n */\npublic function  action_print($partner,$machine_code,$content,$apiKey,$msign)\n{\n    $param = array(\n        \"partner\"=>$partner,\n        'machine_code'=>$machine_code,\n        'time'=>time(),\n        );\n    //获取签名\n    $param['sign'] = $this->generateSign($param,$apiKey,$msign);\n    $param['content'] = $content;\n    $str = $this->getStr($param);\n    echo $this->sendCmd('http://open.10ss.net:8888',$str);\n}\n/**\n *  添加打印机\n * @param  int $partner     用户ID1       \n * @param  string $machine_code 打印机终端号\n * @param  string $username     用户名\n * @param  string $printname    打印机名称\n * @param  string $mobilephone  打印机卡号\n * @param  string $apiKey       API密钥\n * @param  string $msign       打印机密钥\n */\npublic function action_addprint($partner,$machine_code,$username,$printname,$mobilephone,$apiKey,$msign)\n{\n    $param = array(\n        'partner'=>$partner,\n        'machine_code'=>$machine_code,\n        'username'=>$username,\n        'printname'=>$printname,\n        'mobilephone'=>$mobilephone,\n        );\n    $param['sign'] = $this->generateSign($param,$apiKey,$msign);\n    $param['msign'] = $msign;\n    $str = $this->getStr($param);\n    echo $this->sendCmd('http://open.10ss.net:8888/addprint.php',$str);\n}\n/**\n * 删除打印机\n * @param  int $partner      用户ID\n * @param  string $machine_code 打印机终端号\n * @param  string $apiKey       API密钥\n * @param  string $msign        打印机密钥\n */\npublic function action_removeprinter($partner,$machine_code,$apiKey,$msign)\n{\n    $param = array(\n        'partner'=>$partner,\n        'machine_code'=>$machine_code,\n        );\n    $param['sign'] = $this->generateSign($param,$apiKey,$msign);\n    $str = $this->getStr($param);\n    echo $this->sendCmd('http://open.10ss.net:8888/removeprint.php',$str);\n}\n/**\n * 发起请求\n * @param  string $url  请求地址\n * @param  string $data 请求数据包\n * @return   string      请求返回数据\n */\npublic function sendCmd($url,$data)\n{\n    $curl = curl_init(); // 启动一个CURL会话      \n    curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址                  \n    curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检测    \n    curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // 从证书中检查SSL加密算法是否存在      \n    curl_setopt($curl, CURLOPT_HTTPHEADER, array('Expect:')); //解决数据包大不能提交     \n    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转      \n    curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer      \n    curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求      \n    curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的数据包      \n    curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循     \n    curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容      \n    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回 \n           \n    $tmpInfo = curl_exec($curl); // 执行操作      \n    if (curl_errno($curl)) {      \n       echo 'Errno'.curl_error($curl);      \n    }      \n    curl_close($curl); // 关键CURL会话      \n    return $tmpInfo; // 返回数据      \n}\n}\n ?>"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/composer.json",
    "content": "{\n  \"name\" : \"dodgepudding/wechat-php-sdk\",\n  \"description\" : \"the wechat api library without framework dependency\",\n  \"version\" : \"1.1\",\n  \"require\" : {\n    \"php\" : \">=5.1.0\"\n  },\n  \"authors\" : [ {\n    \"name\" : \"dodgepudding\",\n    \"email\" : \"dodgepudding@gmail.com\"\n  }, {\n    \"name\" : \"binsee\",\n    \"email\" : \"binsee@163.com\"\n  } ],\n  \"keywords\" : [ \"wechat\", \"weixin\", \"thinkphp\", \"sample\" ],\n  \"support\" : {\n    \"issues\" : \"https://github.com/dodgepudding/wechat-php-sdk/issues\",\n    \"wiki\" : \"https://github.com/dodgepudding/wechat-php-sdk/wiki\",\n    \"source\" : \"https://github.com/dodgepudding/wechat-php-sdk\"\n  },\n  \"autoload\" : {\n    \"psr-4\" : {\n      \"dodgepudding\\\\wechat\\\\sdk\\\\\" : \"\"\n    }\n  },\n  \"type\" : \"library\",\n  \"license\" : \"LGPL\"\n}"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/demo.php",
    "content": "<?php\ninclude \"wechat.class.php\";\n$options = array(\n\t\t'token'=>'tokenaccesskey', //填写你设定的key\n        'encodingaeskey'=>'encodingaeskey' //填写加密用的EncodingAESKey，如接口为明文模式可忽略\n\t);\n$weObj = new Wechat($options);\n$weObj->valid();//明文或兼容模式可以在接口验证通过后注释此句，但加密模式一定不能注释，否则会验证失败\n$type = $weObj->getRev()->getRevType();\nswitch($type) {\n\tcase Wechat::MSGTYPE_TEXT:\n\t\t\t$weObj->text(\"hello, I'm wechat\")->reply();\n\t\t\texit;\n\t\t\tbreak;\n\tcase Wechat::MSGTYPE_EVENT:\n\t\t\tbreak;\n\tcase Wechat::MSGTYPE_IMAGE:\n\t\t\tbreak;\n\tdefault:\n\t\t\t$weObj->text(\"help info\")->reply();\n}"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/errCode.php",
    "content": "<?php\n/**\n *    微信公众平台PHP-SDK, 全局返回码类\n *  @author  binsee <binsee@163.com>\n *  @link https://github.com/binsee/wechat-php-sdk\n *  @version 1.0\n *  usage:\n *      $ret=ErrCode::getErrText(40001); //错误码可以通过公众号类库的公开变量errCode得到\n *      if ($ret)\n *          echo $ret;\n *      else\n *          echo \"未找到对应的内容\";\n */\nclass ErrCode\n{\n    public static $errCode=array(\n        '-1'=>'系统繁忙',\n        '0'=>'请求成功',\n        '40001'=>'获取access_token时AppSecret错误，或者access_token无效',\n        '40002'=>'不合法的凭证类型',\n        '40003'=>'不合法的OpenID',\n        '40004'=>'不合法的媒体文件类型',\n        '40005'=>'不合法的文件类型',\n        '40006'=>'不合法的文件大小',\n        '40007'=>'不合法的媒体文件id',\n        '40008'=>'不合法的消息类型',\n        '40009'=>'不合法的图片文件大小',\n        '40010'=>'不合法的语音文件大小',\n        '40011'=>'不合法的视频文件大小',\n        '40012'=>'不合法的缩略图文件大小',\n        '40013'=>'不合法的APPID',\n        '40014'=>'不合法的access_token',\n        '40015'=>'不合法的菜单类型',\n        '40016'=>'不合法的按钮个数',\n        '40017'=>'不合法的按钮类型',\n        '40018'=>'不合法的按钮名字长度',\n        '40019'=>'不合法的按钮KEY长度',\n        '40020'=>'不合法的按钮URL长度',\n        '40021'=>'不合法的菜单版本号',\n        '40022'=>'不合法的子菜单级数',\n        '40023'=>'不合法的子菜单按钮个数',\n        '40024'=>'不合法的子菜单按钮类型',\n        '40025'=>'不合法的子菜单按钮名字长度',\n        '40026'=>'不合法的子菜单按钮KEY长度',\n        '40027'=>'不合法的子菜单按钮URL长度',\n        '40028'=>'不合法的自定义菜单使用用户',\n        '40029'=>'不合法的oauth_code',\n        '40030'=>'不合法的refresh_token',\n        '40031'=>'不合法的openid列表',\n        '40032'=>'不合法的openid列表长度',\n        '40033'=>'不合法的请求字符，不能包含\\uxxxx格式的字符',\n        '40035'=>'不合法的参数',\n        '40038'=>'不合法的请求格式',\n        '40039'=>'不合法的URL长度',\n        '40050'=>'不合法的分组id',\n        '40051'=>'分组名字不合法',\n        '40099'=>'该 code 已被核销',\n        '41001'=>'缺少access_token参数',\n        '41002'=>'缺少appid参数',\n        '41003'=>'缺少refresh_token参数',\n        '41004'=>'缺少secret参数',\n        '41005'=>'缺少多媒体文件数据',\n        '41006'=>'缺少media_id参数',\n        '41007'=>'缺少子菜单数据',\n        '41008'=>'缺少oauth code',\n        '41009'=>'缺少openid',\n        '42001'=>'access_token超时',\n        '42002'=>'refresh_token超时',\n        '42003'=>'oauth_code超时',\n        '42005'=>'调用接口频率超过上限',\n        '43001'=>'需要GET请求',\n        '43002'=>'需要POST请求',\n        '43003'=>'需要HTTPS请求',\n        '43004'=>'需要接收者关注',\n        '43005'=>'需要好友关系',\n        '44001'=>'多媒体文件为空',\n        '44002'=>'POST的数据包为空',\n        '44003'=>'图文消息内容为空',\n        '44004'=>'文本消息内容为空',\n        '45001'=>'多媒体文件大小超过限制',\n        '45002'=>'消息内容超过限制',\n        '45003'=>'标题字段超过限制',\n        '45004'=>'描述字段超过限制',\n        '45005'=>'链接字段超过限制',\n        '45006'=>'图片链接字段超过限制',\n        '45007'=>'语音播放时间超过限制',\n        '45008'=>'图文消息超过限制',\n        '45009'=>'接口调用超过限制',\n        '45010'=>'创建菜单个数超过限制',\n        '45015'=>'回复时间超过限制',\n        '45016'=>'系统分组，不允许修改',\n        '45017'=>'分组名字过长',\n        '45018'=>'分组数量超过上限',\n        '45024'=>'账号数量超过上限',\n        '46001'=>'不存在媒体数据',\n        '46002'=>'不存在的菜单版本',\n        '46003'=>'不存在的菜单数据',\n        '46004'=>'不存在的用户',\n        '47001'=>'解析JSON/XML内容错误',\n        '48001'=>'api功能未授权',\n        '50001'=>'用户未授权该api',\n        '61450'=>'系统错误',\n        '61451'=>'参数错误',\n        '61452'=>'无效客服账号',\n        '61453'=>'账号已存在',\n        '61454'=>'客服帐号名长度超过限制(仅允许10个英文字符，不包括@及@后的公众号的微信号)',\n        '61455'=>'客服账号名包含非法字符(英文+数字)',\n        '61456'=>'客服账号个数超过限制(10个客服账号)',\n        '61457'=>'无效头像文件类型',\n        '61458'=>'客户正在被其他客服接待',\n        '61459'=>'客服不在线',\n        '61500'=>'日期格式错误',\n        '61501'=>'日期范围错误',\n        '7000000'=>'请求正常，无语义结果',\n        '7000001'=>'缺失请求参数',\n        '7000002'=>'signature 参数无效',\n        '7000003'=>'地理位置相关配置 1 无效',\n        '7000004'=>'地理位置相关配置 2 无效',\n        '7000005'=>'请求地理位置信息失败',\n        '7000006'=>'地理位置结果解析失败',\n        '7000007'=>'内部初始化失败',\n        '7000008'=>'非法 appid（获取密钥失败）',\n        '7000009'=>'请求语义服务失败',\n        '7000010'=>'非法 post 请求',\n        '7000011'=>'post 请求 json 字段无效',\n        '7000030'=>'查询 query 太短',\n        '7000031'=>'查询 query 太长',\n        '7000032'=>'城市、经纬度信息缺失',\n        '7000033'=>'query 请求语义处理失败',\n        '7000034'=>'获取天气信息失败',\n        '7000035'=>'获取股票信息失败',\n        '7000036'=>'utf8 编码转换失败',\n    );\n\n    public static function getErrText($err) {\n        if (isset(self::$errCode[$err])) {\n            return self::$errCode[$err];\n        }else {\n            return false;\n        };\n    }\n}\n\n?>"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/old_version/Thinkphp/Snoopy.class.php",
    "content": "<?php\n/*************************************************\n\nSnoopy - the PHP net client\nAuthor: Monte Ohrt <monte@ispi.net>\nCopyright (c): 1999-2008 New Digital Group, all rights reserved\nVersion: 1.2.4\n\n* This library is free software; you can redistribute it and/or\n* modify it under the terms of the GNU Lesser General Public\n* License as published by the Free Software Foundation; either\n* version 2.1 of the License, or (at your option) any later version.\n*\n* This library is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n* Lesser General Public License for more details.\n*\n* You should have received a copy of the GNU Lesser General Public\n* License along with this library; if not, write to the Free Software\n* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\nYou may contact the author of Snoopy by e-mail at:\nmonte@ohrt.com\n\nThe latest version of Snoopy can be obtained from:\nhttp://snoopy.sourceforge.net/\n\n*************************************************/\n\nclass Snoopy\n{\n\t/**** Public variables ****/\n\n\t/* user definable vars */\n\n\tvar $host\t\t\t=\t\"www.php.net\";\t\t// host name we are connecting to\n\tvar $port\t\t\t=\t80;\t\t\t\t\t// port we are connecting to\n\tvar $proxy_host\t\t=\t\"\";\t\t\t\t\t// proxy host to use\n\tvar $proxy_port\t\t=\t\"\";\t\t\t\t\t// proxy port to use\n\tvar $proxy_user\t\t=\t\"\";\t\t\t\t\t// proxy user to use\n\tvar $proxy_pass\t\t=\t\"\";\t\t\t\t\t// proxy password to use\n\n\tvar $agent\t\t\t=\t\"Mozilla/5.0\";\t// agent we masquerade as\n\tvar\t$referer\t\t=\t\"\";\t\t\t\t\t// referer info to pass\n\tvar $cookies\t\t=\tarray();\t\t\t// array of cookies to pass\n\t// $cookies[\"username\"]=\"joe\";\n\tvar\t$rawheaders\t\t=\tarray();\t\t\t// array of raw headers to send\n\t// $rawheaders[\"Content-type\"]=\"text/html\";\n\n\tvar $maxredirs\t\t=\t5;\t\t\t\t\t// http redirection depth maximum. 0 = disallow\n\tvar $lastredirectaddr\t=\t\"\";\t\t\t\t// contains address of last redirected address\n\tvar\t$offsiteok\t\t=\ttrue;\t\t\t\t// allows redirection off-site\n\tvar $maxframes\t\t=\t0;\t\t\t\t\t// frame content depth maximum. 0 = disallow\n\tvar $expandlinks\t=\ttrue;\t\t\t\t// expand links to fully qualified URLs.\n\t// this only applies to fetchlinks()\n\t// submitlinks(), and submittext()\n\tvar $passcookies\t=\ttrue;\t\t\t\t// pass set cookies back through redirects\n\t// NOTE: this currently does not respect\n\t// dates, domains or paths.\n\n\tvar\t$user\t\t\t=\t\"\";\t\t\t\t\t// user for http authentication\n\tvar\t$pass\t\t\t=\t\"\";\t\t\t\t\t// password for http authentication\n\n\t// http accept types\n\tvar $accept\t\t\t=\t\"application/json, text/javascript, */*; q=0.01\";\n\n\tvar $results\t\t=\t\"\";\t\t\t\t\t// where the content is put\n\n\tvar $error\t\t\t=\t\"\";\t\t\t\t\t// error messages sent here\n\tvar\t$response_code\t=\t\"\";\t\t\t\t\t// response code returned from server\n\tvar\t$headers\t\t=\tarray();\t\t\t// headers returned from server sent here\n\tvar\t$maxlength\t\t=\t500000;\t\t\t\t// max return data length (body)\n\tvar $read_timeout\t=\t0;\t\t\t\t\t// timeout on read operations, in seconds\n\t// supported only since PHP 4 Beta 4\n\t// set to 0 to disallow timeouts\n\tvar $timed_out\t\t=\tfalse;\t\t\t\t// if a read operation timed out\n\tvar\t$status\t\t\t=\t0;\t\t\t\t\t// http request status\n\n\tvar $temp_dir\t\t=\t\"/tmp\";\t\t\t\t// temporary directory that the webserver\n\t// has permission to write to.\n\t// under Windows, this should be C:\\temp\n\n\tvar\t$curl_path\t\t=\t\"/usr/local/bin/curl\";\n\t// Snoopy will use cURL for fetching\n\t// SSL content if a full system path to\n\t// the cURL binary is supplied here.\n\t// set to false if you do not have\n\t// cURL installed. See http://curl.haxx.se\n\t// for details on installing cURL.\n\t// Snoopy does *not* use the cURL\n\t// library functions built into php,\n\t// as these functions are not stable\n\t// as of this Snoopy release.\n\n\t/**** Private variables ****/\n\n\tvar\t$_maxlinelen\t=\t4096;\t\t\t\t// max line length (headers)\n\n\tvar $_httpmethod\t=\t\"GET\";\t\t\t\t// default http request method\n\tvar $_httpversion\t=\t\"HTTP/1.0\";\t\t\t// default http request version\n\tvar $_submit_method\t=\t\"POST\";\t\t\t\t// default submit method\n\tvar $_submit_type\t=\t\"application/x-www-form-urlencoded\";\t// default submit type\n\tvar $_mime_boundary\t=   \"\";\t\t\t\t\t// MIME boundary for multipart/form-data submit type\n\tvar $_redirectaddr\t=\tfalse;\t\t\t\t// will be set if page fetched is a redirect\n\tvar $_redirectdepth\t=\t0;\t\t\t\t\t// increments on an http redirect\n\tvar $_frameurls\t\t= \tarray();\t\t\t// frame src urls\n\tvar $_framedepth\t=\t0;\t\t\t\t\t// increments on frame depth\n\n\tvar $_isproxy\t\t=\tfalse;\t\t\t\t// set if using a proxy server\n\tvar $_fp_timeout\t=\t30;\t\t\t\t\t// timeout for socket connection\n\n\t/*======================================================================*\\\n\t Function:\tfetch\n\tPurpose:\tfetch the contents of a web page\n\t(and possibly other protocols in the\n\t\t\tfuture like ftp, nntp, gopher, etc.)\n\tInput:\t\t$URI\tthe location of the page to fetch\n\tOutput:\t\t$this->results\tthe output text from the fetch\n\t\\*======================================================================*/\n\n\tfunction fetch($URI)\n\t{\n\n\t\t//preg_match(\"|^([^:]+)://([^:/]+)(:[\\d]+)*(.*)|\",$URI,$URI_PARTS);\n\t\t$URI_PARTS = parse_url($URI);\n\t\tif (!empty($URI_PARTS[\"user\"]))\n\t\t\t$this->user = $URI_PARTS[\"user\"];\n\t\tif (!empty($URI_PARTS[\"pass\"]))\n\t\t\t$this->pass = $URI_PARTS[\"pass\"];\n\t\tif (empty($URI_PARTS[\"query\"]))\n\t\t\t$URI_PARTS[\"query\"] = '';\n\t\tif (empty($URI_PARTS[\"path\"]))\n\t\t\t$URI_PARTS[\"path\"] = '';\n\n\t\tswitch(strtolower($URI_PARTS[\"scheme\"]))\n\t\t{\n\t\t\tcase \"http\":\n\t\t\t\t$this->host = $URI_PARTS[\"host\"];\n\t\t\t\tif(!empty($URI_PARTS[\"port\"]))\n\t\t\t\t\t$this->port = $URI_PARTS[\"port\"];\n\t\t\t\tif($this->_connect($fp))\n\t\t\t\t{\n\t\t\t\t\tif($this->_isproxy)\n\t\t\t\t\t{\n\t\t\t\t\t\t// using proxy, send entire URI\n\t\t\t\t\t\t$this->_httprequest($URI,$fp,$URI,$this->_httpmethod);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t$path = $URI_PARTS[\"path\"].($URI_PARTS[\"query\"] ? \"?\".$URI_PARTS[\"query\"] : \"\");\n\t\t\t\t\t\t// no proxy, send only the path\n\t\t\t\t\t\t$this->_httprequest($path, $fp, $URI, $this->_httpmethod);\n\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t$this->_disconnect($fp);\n\n\t\t\t\t\tif($this->_redirectaddr)\n\t\t\t\t\t{\n\t\t\t\t\t\t/* url was redirected, check if we've hit the max depth */\n\t\t\t\t\t\tif($this->maxredirs > $this->_redirectdepth)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// only follow redirect if it's on this site, or offsiteok is true\n\t\t\t\t\t\t\tif(preg_match(\"|^http://\".preg_quote($this->host).\"|i\",$this->_redirectaddr) || $this->offsiteok)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t/* follow the redirect */\n\t\t\t\t\t\t\t\t$this->_redirectdepth++;\n\t\t\t\t\t\t\t\t$this->lastredirectaddr=$this->_redirectaddr;\n\t\t\t\t\t\t\t\t$this->fetch($this->_redirectaddr);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t$frameurls = $this->_frameurls;\n\t\t\t\t\t\t$this->_frameurls = array();\n\n\t\t\t\t\t\twhile(list(,$frameurl) = each($frameurls))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif($this->_framedepth < $this->maxframes)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$this->fetch($frameurl);\n\t\t\t\t\t\t\t\t$this->_framedepth++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t\tbreak;\n\t\t\tcase \"https\":\n\t\t\t\tif (!function_exists('curl_init')) {\n\t\t\t\t\tif(!$this->curl_path)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif(function_exists(\"is_executable\"))\n\t\t\t\t\t\tif (!is_executable($this->curl_path))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t$this->host = $URI_PARTS[\"host\"];\n\t\t\t\tif(!empty($URI_PARTS[\"port\"]))\n\t\t\t\t\t$this->port = $URI_PARTS[\"port\"];\n\t\t\t\tif($this->_isproxy)\n\t\t\t\t{\n\t\t\t\t\t// using proxy, send entire URI\n\t\t\t\t\t$this->_httpsrequest($URI,$URI,$this->_httpmethod);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t$path = $URI_PARTS[\"path\"].($URI_PARTS[\"query\"] ? \"?\".$URI_PARTS[\"query\"] : \"\");\n\t\t\t\t\t// no proxy, send only the path\n\t\t\t\t\t$this->_httpsrequest($path, $URI, $this->_httpmethod);\n\t\t\t\t}\n\n\t\t\t\tif($this->_redirectaddr)\n\t\t\t\t{\n\t\t\t\t\t/* url was redirected, check if we've hit the max depth */\n\t\t\t\t\tif($this->maxredirs > $this->_redirectdepth)\n\t\t\t\t\t{\n\t\t\t\t\t\t// only follow redirect if it's on this site, or offsiteok is true\n\t\t\t\t\t\tif(preg_match(\"|^https://\".preg_quote($this->host).\"|i\",$this->_redirectaddr) || $this->offsiteok)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/* follow the redirect */\n\t\t\t\t\t\t\t$this->_redirectdepth++;\n\t\t\t\t\t\t\t$this->lastredirectaddr=$this->_redirectaddr;\n\t\t\t\t\t\t\t$this->fetch($this->_redirectaddr);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)\n\t\t\t\t{\n\t\t\t\t\t$frameurls = $this->_frameurls;\n\t\t\t\t\t$this->_frameurls = array();\n\n\t\t\t\t\twhile(list(,$frameurl) = each($frameurls))\n\t\t\t\t\t{\n\t\t\t\t\t\tif($this->_framedepth < $this->maxframes)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$this->fetch($frameurl);\n\t\t\t\t\t\t\t$this->_framedepth++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// not a valid protocol\n\t\t\t\t$this->error\t=\t'Invalid protocol \"'.$URI_PARTS[\"scheme\"].'\"\\n';\n\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\tsubmit\n\tPurpose:\tsubmit an http form\n\tInput:\t\t$URI\tthe location to post the data\n\t$formvars\tthe formvars to use.\n\tformat: $formvars[\"var\"] = \"val\";\n\t$formfiles  an array of files to submit\n\tformat: $formfiles[\"var\"] = \"/dir/filename.ext\";\n\tOutput:\t\t$this->results\tthe text output from the post\n\t\\*======================================================================*/\n\n\tfunction submit($URI, $formvars=\"\", $formfiles=\"\")\n\t{\n\t\tunset($postdata);\n\n\t\t$postdata = $this->_prepare_post_body($formvars, $formfiles);\n\t\t$URI_PARTS = parse_url($URI);\n\t\tif (!empty($URI_PARTS[\"user\"]))\n\t\t\t$this->user = $URI_PARTS[\"user\"];\n\t\tif (!empty($URI_PARTS[\"pass\"]))\n\t\t\t$this->pass = $URI_PARTS[\"pass\"];\n\t\tif (empty($URI_PARTS[\"query\"]))\n\t\t\t$URI_PARTS[\"query\"] = '';\n\t\tif (empty($URI_PARTS[\"path\"]))\n\t\t\t$URI_PARTS[\"path\"] = '';\n\n\t\tswitch(strtolower($URI_PARTS[\"scheme\"]))\n\t\t{\n\t\t\tcase \"http\":\n\t\t\t\t$this->host = $URI_PARTS[\"host\"];\n\t\t\t\tif(!empty($URI_PARTS[\"port\"]))\n\t\t\t\t\t$this->port = $URI_PARTS[\"port\"];\n\t\t\t\tif($this->_connect($fp))\n\t\t\t\t{\n\t\t\t\t\tif($this->_isproxy)\n\t\t\t\t\t{\n\t\t\t\t\t\t// using proxy, send entire URI\n\t\t\t\t\t\t$this->_httprequest($URI,$fp,$URI,$this->_submit_method,$this->_submit_type,$postdata);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t$path = $URI_PARTS[\"path\"].($URI_PARTS[\"query\"] ? \"?\".$URI_PARTS[\"query\"] : \"\");\n\t\t\t\t\t\t// no proxy, send only the path\n\t\t\t\t\t\t$this->_httprequest($path, $fp, $URI, $this->_submit_method, $this->_submit_type, $postdata);\n\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t$this->_disconnect($fp);\n\n\t\t\t\t\tif($this->_redirectaddr)\n\t\t\t\t\t{\n\t\t\t\t\t\t/* url was redirected, check if we've hit the max depth */\n\t\t\t\t\t\tif($this->maxredirs > $this->_redirectdepth)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(!preg_match(\"|^\".$URI_PARTS[\"scheme\"].\"://|\", $this->_redirectaddr))\n\t\t\t\t\t\t\t\t$this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS[\"scheme\"].\"://\".$URI_PARTS[\"host\"]);\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t// only follow redirect if it's on this site, or offsiteok is true\n\t\t\t\t\t\t\tif(preg_match(\"|^http://\".preg_quote($this->host).\"|i\",$this->_redirectaddr) || $this->offsiteok)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t/* follow the redirect */\n\t\t\t\t\t\t\t\t$this->_redirectdepth++;\n\t\t\t\t\t\t\t\t$this->lastredirectaddr=$this->_redirectaddr;\n\t\t\t\t\t\t\t\tif( strpos( $this->_redirectaddr, \"?\" ) > 0 )\n\t\t\t\t\t\t\t\t\t$this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t$this->submit($this->_redirectaddr,$formvars, $formfiles);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t$frameurls = $this->_frameurls;\n\t\t\t\t\t\t$this->_frameurls = array();\n\n\t\t\t\t\t\twhile(list(,$frameurl) = each($frameurls))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif($this->_framedepth < $this->maxframes)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$this->fetch($frameurl);\n\t\t\t\t\t\t\t\t$this->_framedepth++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t\tbreak;\n\t\t\tcase \"https\":\n\t\t\t\tif (!function_exists('curl_init')) {\n\t\t\t\tif(!$this->curl_path)\n\t\t\t\t\treturn false;\n\t\t\t\tif(function_exists(\"is_executable\"))\n\t\t\t\t\tif (!is_executable($this->curl_path))\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t$this->host = $URI_PARTS[\"host\"];\n\t\t\t\tif(!empty($URI_PARTS[\"port\"]))\n\t\t\t\t\t$this->port = $URI_PARTS[\"port\"];\n\t\t\t\tif($this->_isproxy)\n\t\t\t\t{\n\t\t\t\t\t// using proxy, send entire URI\n\t\t\t\t\t$this->_httpsrequest($URI, $URI, $this->_submit_method, $this->_submit_type, $postdata);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t$path = $URI_PARTS[\"path\"].($URI_PARTS[\"query\"] ? \"?\".$URI_PARTS[\"query\"] : \"\");\n\t\t\t\t\t// no proxy, send only the path\n\t\t\t\t\t$this->_httpsrequest($path, $URI, $this->_submit_method, $this->_submit_type, $postdata);\n\t\t\t\t}\n\n\t\t\t\tif($this->_redirectaddr)\n\t\t\t\t{\n\t\t\t\t\t/* url was redirected, check if we've hit the max depth */\n\t\t\t\t\tif($this->maxredirs > $this->_redirectdepth)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(!preg_match(\"|^\".$URI_PARTS[\"scheme\"].\"://|\", $this->_redirectaddr))\n\t\t\t\t\t\t\t$this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS[\"scheme\"].\"://\".$URI_PARTS[\"host\"]);\n\n\t\t\t\t\t\t// only follow redirect if it's on this site, or offsiteok is true\n\t\t\t\t\t\tif(preg_match(\"|^https://\".preg_quote($this->host).\"|i\",$this->_redirectaddr) || $this->offsiteok)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/* follow the redirect */\n\t\t\t\t\t\t\t$this->_redirectdepth++;\n\t\t\t\t\t\t\t$this->lastredirectaddr=$this->_redirectaddr;\n\t\t\t\t\t\t\tif( strpos( $this->_redirectaddr, \"?\" ) > 0 )\n\t\t\t\t\t\t\t\t$this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t$this->submit($this->_redirectaddr,$formvars, $formfiles);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)\n\t\t\t\t{\n\t\t\t\t\t$frameurls = $this->_frameurls;\n\t\t\t\t\t$this->_frameurls = array();\n\n\t\t\t\t\twhile(list(,$frameurl) = each($frameurls))\n\t\t\t\t\t{\n\t\t\t\t\t\tif($this->_framedepth < $this->maxframes)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$this->fetch($frameurl);\n\t\t\t\t\t\t\t$this->_framedepth++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// not a valid protocol\n\t\t\t\t$this->error\t=\t'Invalid protocol \"'.$URI_PARTS[\"scheme\"].'\"\\n';\n\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\tfetchlinks\n\tPurpose:\tfetch the links from a web page\n\tInput:\t\t$URI\twhere you are fetching from\n\tOutput:\t\t$this->results\tan array of the URLs\n\t\\*======================================================================*/\n\n\tfunction fetchlinks($URI)\n\t{\n\t\tif ($this->fetch($URI))\n\t\t{\n\t\t\tif($this->lastredirectaddr)\n\t\t\t\t$URI = $this->lastredirectaddr;\n\t\t\tif(is_array($this->results))\n\t\t\t{\n\t\t\t\tfor($x=0;$x<count($this->results);$x++)\n\t\t\t\t\t$this->results[$x] = $this->_striplinks($this->results[$x]);\n\t\t\t}\n\t\t\telse\n\t\t\t\t$this->results = $this->_striplinks($this->results);\n\n\t\t\tif($this->expandlinks)\n\t\t\t\t$this->results = $this->_expandlinks($this->results, $URI);\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\tfetchform\n\tPurpose:\tfetch the form elements from a web page\n\tInput:\t\t$URI\twhere you are fetching from\n\tOutput:\t\t$this->results\tthe resulting html form\n\t\\*======================================================================*/\n\n\tfunction fetchform($URI)\n\t{\n\n\t\tif ($this->fetch($URI))\n\t\t{\n\n\t\t\tif(is_array($this->results))\n\t\t\t{\n\t\t\t\tfor($x=0;$x<count($this->results);$x++)\n\t\t\t\t\t$this->results[$x] = $this->_stripform($this->results[$x]);\n\t\t\t}\n\t\t\telse\n\t\t\t\t$this->results = $this->_stripform($this->results);\n\t\t\t\t\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\n\t/*======================================================================*\\\n\t Function:\tfetchtext\n\tPurpose:\tfetch the text from a web page, stripping the links\n\tInput:\t\t$URI\twhere you are fetching from\n\tOutput:\t\t$this->results\tthe text from the web page\n\t\\*======================================================================*/\n\n\tfunction fetchtext($URI)\n\t{\n\t\tif($this->fetch($URI))\n\t\t{\n\t\t\tif(is_array($this->results))\n\t\t\t{\n\t\t\t\tfor($x=0;$x<count($this->results);$x++)\n\t\t\t\t\t$this->results[$x] = $this->_striptext($this->results[$x]);\n\t\t\t}\n\t\t\telse\n\t\t\t\t$this->results = $this->_striptext($this->results);\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\tsubmitlinks\n\tPurpose:\tgrab links from a form submission\n\tInput:\t\t$URI\twhere you are submitting from\n\tOutput:\t\t$this->results\tan array of the links from the post\n\t\\*======================================================================*/\n\n\tfunction submitlinks($URI, $formvars=\"\", $formfiles=\"\")\n\t{\n\t\tif($this->submit($URI,$formvars, $formfiles))\n\t\t{\n\t\t\tif($this->lastredirectaddr)\n\t\t\t\t$URI = $this->lastredirectaddr;\n\t\t\tif(is_array($this->results))\n\t\t\t{\n\t\t\t\tfor($x=0;$x<count($this->results);$x++)\n\t\t\t\t{\n\t\t\t\t\t$this->results[$x] = $this->_striplinks($this->results[$x]);\n\t\t\t\t\tif($this->expandlinks)\n\t\t\t\t\t\t$this->results[$x] = $this->_expandlinks($this->results[$x],$URI);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$this->results = $this->_striplinks($this->results);\n\t\t\t\tif($this->expandlinks)\n\t\t\t\t\t$this->results = $this->_expandlinks($this->results,$URI);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\tsubmittext\n\tPurpose:\tgrab text from a form submission\n\tInput:\t\t$URI\twhere you are submitting from\n\tOutput:\t\t$this->results\tthe text from the web page\n\t\\*======================================================================*/\n\n\tfunction submittext($URI, $formvars = \"\", $formfiles = \"\")\n\t{\n\t\tif($this->submit($URI,$formvars, $formfiles))\n\t\t{\n\t\t\tif($this->lastredirectaddr)\n\t\t\t\t$URI = $this->lastredirectaddr;\n\t\t\tif(is_array($this->results))\n\t\t\t{\n\t\t\t\tfor($x=0;$x<count($this->results);$x++)\n\t\t\t\t{\n\t\t\t\t\t$this->results[$x] = $this->_striptext($this->results[$x]);\n\t\t\t\t\tif($this->expandlinks)\n\t\t\t\t\t\t$this->results[$x] = $this->_expandlinks($this->results[$x],$URI);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$this->results = $this->_striptext($this->results);\n\t\t\t\tif($this->expandlinks)\n\t\t\t\t\t$this->results = $this->_expandlinks($this->results,$URI);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\n\n\t/*======================================================================*\\\n\t Function:\tset_submit_multipart\n\tPurpose:\tSet the form submission content type to\n\tmultipart/form-data\n\t\\*======================================================================*/\n\tfunction set_submit_multipart()\n\t{\n\t\t$this->_submit_type = \"multipart/form-data\";\n\t}\n\n\n\t/*======================================================================*\\\n\t Function:\tset_submit_normal\n\tPurpose:\tSet the form submission content type to\n\tapplication/x-www-form-urlencoded\n\t\\*======================================================================*/\n\tfunction set_submit_normal()\n\t{\n\t\t$this->_submit_type = \"application/x-www-form-urlencoded\";\n\t}\n\n\n\n\n\t/*======================================================================*\\\n\t Private functions\n\t\\*======================================================================*/\n\n\n\t/*======================================================================*\\\n\t Function:\t_striplinks\n\tPurpose:\tstrip the hyperlinks from an html document\n\tInput:\t\t$document\tdocument to strip.\n\tOutput:\t\t$match\t\tan array of the links\n\t\\*======================================================================*/\n\n\tfunction _striplinks($document)\n\t{\n\t\tpreg_match_all(\"'<\\s*a\\s.*?href\\s*=\\s*\t\t\t# find <a href=\n\t\t\t\t\t\t([\\\"\\'])?\t\t\t\t\t# find single or double quote\n\t\t\t\t\t\t(?(1) (.*?)\\\\1 | ([^\\s\\>]+))\t\t# if quote found, match up to next matching\n\t\t\t\t\t\t\t\t\t\t\t\t\t# quote, otherwise match up to next space\n\t\t\t\t\t\t'isx\",$document,$links);\n\n\n\t\t// catenate the non-empty matches from the conditional subpattern\n\n\t\twhile(list($key,$val) = each($links[2]))\n\t\t{\n\t\t\tif(!empty($val))\n\t\t\t\t$match[] = $val;\n\t\t}\n\n\t\twhile(list($key,$val) = each($links[3]))\n\t\t{\n\t\t\tif(!empty($val))\n\t\t\t\t$match[] = $val;\n\t\t}\n\n\t\t// return the links\n\t\treturn $match;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\t_stripform\n\tPurpose:\tstrip the form elements from an html document\n\tInput:\t\t$document\tdocument to strip.\n\tOutput:\t\t$match\t\tan array of the links\n\t\\*======================================================================*/\n\n\tfunction _stripform($document)\n\t{\n\t\tpreg_match_all(\"'<\\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\\/?(option|select)[^<>]*>[\\r\\n]*)|(?=[\\r\\n]*))|(?=[\\r\\n]*))'Usi\",$document,$elements);\n\n\t\t// catenate the matches\n\t\t$match = implode(\"\\r\\n\",$elements[0]);\n\n\t\t// return the links\n\t\treturn $match;\n\t}\n\n\n\n\t/*======================================================================*\\\n\t Function:\t_striptext\n\tPurpose:\tstrip the text from an html document\n\tInput:\t\t$document\tdocument to strip.\n\tOutput:\t\t$text\t\tthe resulting text\n\t\\*======================================================================*/\n\n\tfunction _striptext($document)\n\t{\n\n\t\t// I didn't use preg eval (//e) since that is only available in PHP 4.0.\n\t\t// so, list your entities one by one here. I included some of the\n\t\t// more common ones.\n\n\t\t$search = array(\"'<script[^>]*?>.*?</script>'si\",\t// strip out javascript\n\t\t\t\t\"'<[\\/\\!]*?[^<>]*?>'si\",\t\t\t// strip out html tags\n\t\t\t\t\"'([\\r\\n])[\\s]+'\",\t\t\t\t\t// strip out white space\n\t\t\t\t\"'&(quot|#34|#034|#x22);'i\",\t\t// replace html entities\n\t\t\t\t\"'&(amp|#38|#038|#x26);'i\",\t\t\t// added hexadecimal values\n\t\t\t\t\"'&(lt|#60|#060|#x3c);'i\",\n\t\t\t\t\"'&(gt|#62|#062|#x3e);'i\",\n\t\t\t\t\"'&(nbsp|#160|#xa0);'i\",\n\t\t\t\t\"'&(iexcl|#161);'i\",\n\t\t\t\t\"'&(cent|#162);'i\",\n\t\t\t\t\"'&(pound|#163);'i\",\n\t\t\t\t\"'&(copy|#169);'i\",\n\t\t\t\t\"'&(reg|#174);'i\",\n\t\t\t\t\"'&(deg|#176);'i\",\n\t\t\t\t\"'&(#39|#039|#x27);'\",\n\t\t\t\t\"'&(euro|#8364);'i\",\t\t\t\t// europe\n\t\t\t\t\"'&a(uml|UML);'\",\t\t\t\t\t// german\n\t\t\t\t\"'&o(uml|UML);'\",\n\t\t\t\t\"'&u(uml|UML);'\",\n\t\t\t\t\"'&A(uml|UML);'\",\n\t\t\t\t\"'&O(uml|UML);'\",\n\t\t\t\t\"'&U(uml|UML);'\",\n\t\t\t\t\"'&szlig;'i\",\n\t\t);\n\t\t$replace = array(\t\"\",\n\t\t\t\t\"\",\n\t\t\t\t\"\\\\1\",\n\t\t\t\t\"\\\"\",\n\t\t\t\t\"&\",\n\t\t\t\t\"<\",\n\t\t\t\t\">\",\n\t\t\t\t\" \",\n\t\t\t\tchr(161),\n\t\t\t\tchr(162),\n\t\t\t\tchr(163),\n\t\t\t\tchr(169),\n\t\t\t\tchr(174),\n\t\t\t\tchr(176),\n\t\t\t\tchr(39),\n\t\t\t\tchr(128),\n\t\t\t\t\"�\",\n\t\t\t\t\"�\",\n\t\t\t\t\"�\",\n\t\t\t\t\"�\",\n\t\t\t\t\"�\",\n\t\t\t\t\"�\",\n\t\t\t\t\"�\",\n\t\t);\n\t\t\t\n\t\t$text = preg_replace($search,$replace,$document);\n\n\t\treturn $text;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\t_expandlinks\n\tPurpose:\texpand each link into a fully qualified URL\n\tInput:\t\t$links\t\t\tthe links to qualify\n\t$URI\t\t\tthe full URI to get the base from\n\tOutput:\t\t$expandedLinks\tthe expanded links\n\t\\*======================================================================*/\n\n\tfunction _expandlinks($links,$URI)\n\t{\n\n\t\tpreg_match(\"/^[^\\?]+/\",$URI,$match);\n\n\t\t$match = preg_replace(\"|/[^\\/\\.]+\\.[^\\/\\.]+$|\",\"\",$match[0]);\n\t\t$match = preg_replace(\"|/$|\",\"\",$match);\n\t\t$match_part = parse_url($match);\n\t\t$match_root =\n\t\t$match_part[\"scheme\"].\"://\".$match_part[\"host\"];\n\n\t\t$search = array( \t\"|^http://\".preg_quote($this->host).\"|i\",\n\t\t\t\t\"|^(\\/)|i\",\n\t\t\t\t\"|^(?!http://)(?!mailto:)|i\",\n\t\t\t\t\"|/\\./|\",\n\t\t\t\t\"|/[^\\/]+/\\.\\./|\"\n\t\t);\n\n\t\t$replace = array(\t\"\",\n\t\t\t\t$match_root.\"/\",\n\t\t\t\t$match.\"/\",\n\t\t\t\t\"/\",\n\t\t\t\t\"/\"\n\t\t);\n\n\t\t$expandedLinks = preg_replace($search,$replace,$links);\n\n\t\treturn $expandedLinks;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\t_httprequest\n\tPurpose:\tgo get the http data from the server\n\tInput:\t\t$url\t\tthe url to fetch\n\t$fp\t\t\tthe current open file pointer\n\t$URI\t\tthe full URI\n\t$body\t\tbody contents to send if any (POST)\n\tOutput:\n\t\\*======================================================================*/\n\n\tfunction _httprequest($url,$fp,$URI,$http_method,$content_type=\"\",$body=\"\")\n\t{\n\t\t$cookie_headers = '';\n\t\tif($this->passcookies && $this->_redirectaddr)\n\t\t\t$this->setcookies();\n\t\t\t\n\t\t$URI_PARTS = parse_url($URI);\n\t\tif(empty($url))\n\t\t\t$url = \"/\";\n\t\t$headers = $http_method.\" \".$url.\" \".$this->_httpversion.\"\\r\\n\";\n\t\tif(!empty($this->agent))\n\t\t\t$headers .= \"User-Agent: \".$this->agent.\"\\r\\n\";\n\t\tif(!empty($this->host) && !isset($this->rawheaders['Host'])) {\n\t\t\t$headers .= \"Host: \".$this->host;\n\t\t\tif(!empty($this->port) && $this->port!=80)\n\t\t\t\t$headers .= \":\".$this->port;\n\t\t\t$headers .= \"\\r\\n\";\n\t\t}\n\t\tif(!empty($this->accept))\n\t\t\t$headers .= \"Accept: \".$this->accept.\"\\r\\n\";\n\t\tif(!empty($this->referer))\n\t\t\t$headers .= \"Referer: \".$this->referer.\"\\r\\n\";\n\t\tif(!empty($this->cookies))\n\t\t{\n\t\t\tif(!is_array($this->cookies))\n\t\t\t\t$this->cookies = (array)$this->cookies;\n\n\t\t\treset($this->cookies);\n\t\t\tif ( count($this->cookies) > 0 ) {\n\t\t\t\t$cookie_headers .= 'Cookie: ';\n\t\t\t\tforeach ( $this->cookies as $cookieKey => $cookieVal ) {\n\t\t\t\t\t$cookie_headers .= $cookieKey.\"=\".urlencode($cookieVal).\"; \";\n\t\t\t\t}\n\t\t\t\t$headers .= substr($cookie_headers,0,-2) . \"\\r\\n\";\n\t\t\t}\n\t\t}\n\t\tif(!empty($this->rawheaders))\n\t\t{\n\t\t\tif(!is_array($this->rawheaders))\n\t\t\t\t$this->rawheaders = (array)$this->rawheaders;\n\t\t\twhile(list($headerKey,$headerVal) = each($this->rawheaders))\n\t\t\t\t$headers .= $headerKey.\": \".$headerVal.\"\\r\\n\";\n\t\t}\n\t\tif(!empty($content_type)) {\n\t\t\t$headers .= \"Content-type: $content_type\";\n\t\t\tif ($content_type == \"multipart/form-data\")\n\t\t\t\t$headers .= \"; boundary=\".$this->_mime_boundary;\n\t\t\t$headers .= \"\\r\\n\";\n\t\t}\n\t\tif(!empty($body))\n\t\t\t$headers .= \"Content-length: \".strlen($body).\"\\r\\n\";\n\t\tif(!empty($this->user) || !empty($this->pass))\n\t\t\t$headers .= \"Authorization: Basic \".base64_encode($this->user.\":\".$this->pass).\"\\r\\n\";\n\n\t\t//add proxy auth headers\n\t\tif(!empty($this->proxy_user))\n\t\t\t$headers .= 'Proxy-Authorization: ' . 'Basic ' . base64_encode($this->proxy_user . ':' . $this->proxy_pass).\"\\r\\n\";\n\n\n\t\t$headers .= \"\\r\\n\";\n\n\t\t// set the read timeout if needed\n\t\tif ($this->read_timeout > 0)\n\t\t\tsocket_set_timeout($fp, $this->read_timeout);\n\t\t$this->timed_out = false;\n\n\t\tfwrite($fp,$headers.$body,strlen($headers.$body));\n\n\t\t$this->_redirectaddr = false;\n\t\tunset($this->headers);\n\n\t\twhile($currentHeader = fgets($fp,$this->_maxlinelen))\n\t\t{\n\t\t\tif ($this->read_timeout > 0 && $this->_check_timeout($fp))\n\t\t\t{\n\t\t\t\t$this->status=-100;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif($currentHeader == \"\\r\\n\")\n\t\t\t\tbreak;\n\n\t\t\t// if a header begins with Location: or URI:, set the redirect\n\t\t\tif(preg_match(\"/^(Location:|URI:)/i\",$currentHeader))\n\t\t\t{\n\t\t\t\t// get URL portion of the redirect\n\t\t\t\tpreg_match(\"/^(Location:|URI:)[ ]+(.*)/i\",chop($currentHeader),$matches);\n\t\t\t\t// look for :// in the Location header to see if hostname is included\n\t\t\t\tif (!empty($matches)) {\n\t\t\t\t\tif(!preg_match(\"|\\:\\/\\/|\",$matches[2]))\n\t\t\t\t\t{\n\t\t\t\t\t\t// no host in the path, so prepend\n\t\t\t\t\t\t$this->_redirectaddr = $URI_PARTS[\"scheme\"].\"://\".$this->host.\":\".$this->port;\n\t\t\t\t\t\t// eliminate double slash\n\t\t\t\t\t\tif(!preg_match(\"|^/|\",$matches[2]))\n\t\t\t\t\t\t\t$this->_redirectaddr .= \"/\".$matches[2];\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\t$this->_redirectaddr .= $matches[2];\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\t$this->_redirectaddr = $matches[2];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(preg_match(\"|^HTTP/|\",$currentHeader))\n\t\t\t{\n\t\t\t\tif(preg_match(\"|^HTTP/[^\\s]*\\s(.*?)\\s|\",$currentHeader, $status))\n\t\t\t\t{\n\t\t\t\t\t$this->status= $status[1];\n\t\t\t\t}\n\t\t\t\t$this->response_code = $currentHeader;\n\t\t\t}\n\n\t\t\t$this->headers[] = $currentHeader;\n\t\t}\n\n\t\t$results = '';\n\t\tdo {\n\t\t\t$_data = fread($fp, $this->maxlength);\n\t\t\tif (strlen($_data) == 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$results .= $_data;\n\t\t} while(true);\n\n\t\tif ($this->read_timeout > 0 && $this->_check_timeout($fp))\n\t\t{\n\t\t\t$this->status=-100;\n\t\t\treturn false;\n\t\t}\n\n\t\t// check if there is a a redirect meta tag\n\n\t\tif(preg_match(\"'<meta[\\s]*http-equiv[^>]*?content[\\s]*=[\\s]*[\\\"\\']?\\d+;[\\s]*URL[\\s]*=[\\s]*([^\\\"\\']*?)[\\\"\\']?>'i\",$results,$match))\n\n\t\t{\n\t\t\t$this->_redirectaddr = $this->_expandlinks($match[1],$URI);\n\t\t}\n\n\t\t// have we hit our frame depth and is there frame src to fetch?\n\t\tif(($this->_framedepth < $this->maxframes) && preg_match_all(\"'<frame\\s+.*src[\\s]*=[\\'\\\"]?([^\\'\\\"\\>]+)'i\",$results,$match))\n\t\t{\n\t\t\t$this->results[] = $results;\n\t\t\tfor($x=0; $x<count($match[1]); $x++)\n\t\t\t\t$this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS[\"scheme\"].\"://\".$this->host);\n\t\t}\n\t\t// have we already fetched framed content?\n\t\telseif(is_array($this->results))\n\t\t$this->results[] = $results;\n\t\t// no framed content\n\t\telse\n\t\t\t$this->results = $results;\n\n\t\treturn true;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\t_httpsrequest\n\tPurpose:\tgo get the https data from the server using curl\n\tInput:\t\t$url\t\tthe url to fetch\n\t$URI\t\tthe full URI\n\t$body\t\tbody contents to send if any (POST)\n\tOutput:\n\t\\*======================================================================*/\n\n\tfunction _httpsrequest($url,$URI,$http_method,$content_type=\"\",$body=\"\")\n\t{\n\t\tif($this->passcookies && $this->_redirectaddr)\n\t\t\t$this->setcookies();\n\n\t\t$headers = array();\n\t\t\t\n\t\t$URI_PARTS = parse_url($URI);\n\t\tif(empty($url))\n\t\t\t$url = \"/\";\n\t\t// GET ... header not needed for curl\n\t\t//$headers[] = $http_method.\" \".$url.\" \".$this->_httpversion;\n\t\tif(!empty($this->agent))\n\t\t\t$headers[] = \"User-Agent: \".$this->agent;\n\t\tif(!empty($this->host))\n\t\t\tif(!empty($this->port) && $this->port!=80)\n\t\t\t$headers[] = \"Host: \".$this->host.\":\".$this->port;\n\t\telse\n\t\t\t$headers[] = \"Host: \".$this->host;\n\t\tif(!empty($this->accept))\n\t\t\t$headers[] = \"Accept: \".$this->accept;\n\t\tif(!empty($this->referer))\n\t\t\t$headers[] = \"Referer: \".$this->referer;\n\t\tif(!empty($this->cookies))\n\t\t{\n\t\t\tif(!is_array($this->cookies))\n\t\t\t\t$this->cookies = (array)$this->cookies;\n\n\t\t\treset($this->cookies);\n\t\t\tif ( count($this->cookies) > 0 ) {\n\t\t\t\t$cookie_str = 'Cookie: ';\n\t\t\t\tforeach ( $this->cookies as $cookieKey => $cookieVal ) {\n\t\t\t\t\t$cookie_str .= $cookieKey.\"=\".urlencode($cookieVal).\"; \";\n\t\t\t\t}\n\t\t\t\t$headers[] = substr($cookie_str,0,-2);\n\t\t\t}\n\t\t}\n\t\tif(!empty($this->rawheaders))\n\t\t{\n\t\t\tif(!is_array($this->rawheaders))\n\t\t\t\t$this->rawheaders = (array)$this->rawheaders;\n\t\t\twhile(list($headerKey,$headerVal) = each($this->rawheaders))\n\t\t\t\t$headers[] = $headerKey.\": \".$headerVal;\n\t\t}\n\t\tif(!empty($content_type)) {\n\t\t\tif ($content_type == \"multipart/form-data\")\n\t\t\t\t$headers[] = \"Content-type: $content_type; boundary=\".$this->_mime_boundary;\n\t\t\telse\n\t\t\t\t$headers[] = \"Content-type: $content_type\";\n\t\t}\n\t\tif(!empty($body))\n\t\t\t$headers[] = \"Content-length: \".strlen($body);\n\t\tif(!empty($this->user) || !empty($this->pass))\n\t\t\t$headers[] = \"Authorization: BASIC \".base64_encode($this->user.\":\".$this->pass);\n\t\tif (function_exists('curl_init')) {\n\t\t\t$ch = curl_init();\n\t\t\tcurl_setopt($ch, CURLOPT_URL, $URI);\n\t\t\tcurl_setopt($ch, CURLOPT_HEADER, true); \n\t\t\tcurl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);\n\t\t\tcurl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);\n\t\t\tcurl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); \n\t\t\tcurl_setopt($ch, CURLOPT_HTTPHEADER, $headers); \n\t\t\tcurl_setopt($ch, CURLOPT_TIMEOUT, $this->read_timeout);\n\t\t\tif(!empty($body)) {\n\t\t\t\tcurl_setopt($ch, CURLOPT_POST, true);\n\t\t\t\tcurl_setopt($ch, CURLOPT_POSTFIELDS, $body);\n\t\t\t}\n\t\t\t$data = curl_exec($ch);\n\t\t\tif ($data === false) {\n\t\t\t\t$this->error = \"Error: Curl error  \".curl_error($ch);\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\t$parts = explode(\"\\r\\n\\r\\n\",$data,2);\n\t\t\t$result_headers = explode(\"\\r\\n\",$parts[0]);\n\t\t\t$results = $parts[1];\n\t\t\tunset($parts);\n\t\t} else {\n\t\t\t\tfor($curr_header = 0; $curr_header < count($headers); $curr_header++) {\n\t\t\t\t\t$safer_header = strtr( $headers[$curr_header], \"\\\"\", \" \" );\n\t\t\t\t\t$cmdline_params .= \" -H \\\"\".$safer_header.\"\\\"\";\n\t\t\t\t}\n\t\t\n\t\t\t\tif(!empty($body))\n\t\t\t\t\t$cmdline_params .= \" -d \\\"$body\\\"\";\n\t\t\n\t\t\t\tif($this->read_timeout > 0)\n\t\t\t\t\t$cmdline_params .= \" -m \".$this->read_timeout;\n\t\t\n\t\t\t\t$headerfile = tempnam($temp_dir, \"sno\");\n\t\t\n\t\t\t\texec($this->curl_path.\" -k -D \\\"$headerfile\\\"\".$cmdline_params.\" \\\"\".escapeshellcmd($URI).\"\\\"\",$results,$return);\n\t\t\n\t\t\t\tif($return)\n\t\t\t\t{\n\t\t\t\t\t$this->error = \"Error: cURL could not retrieve the document, error $return.\";\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t\n\t\t\t$results = implode(\"\\r\\n\",$results);\n\t\n\t\t\t$result_headers = file(\"$headerfile\");\n\t\t}\n\t\t$this->_redirectaddr = false;\n\t\tunset($this->headers);\n\n\t\tfor($currentHeader = 0; $currentHeader < count($result_headers); $currentHeader++)\n\t\t{\n\t\t\t\t\n\t\t\t// if a header begins with Location: or URI:, set the redirect\n\t\t\tif(preg_match(\"/^(Location: |URI: )/i\",$result_headers[$currentHeader]))\n\t\t\t{\n\t\t\t\t// get URL portion of the redirect\n\t\t\t\tpreg_match(\"/^(Location: |URI:)\\s+(.*)/\",chop($result_headers[$currentHeader]),$matches);\n\t\t\t\t// look for :// in the Location header to see if hostname is included\n\t\t\t\tif (!empty($matches)) {\n\t\t\t\t\tif(!preg_match(\"|\\:\\/\\/|\",$matches[2]))\n\t\t\t\t\t{\n\t\t\t\t\t\t// no host in the path, so prepend\n\t\t\t\t\t\t$this->_redirectaddr = $URI_PARTS[\"scheme\"].\"://\".$this->host;\n\t\t\t\t\t\t// eliminate double slash\n\t\t\t\t\t\tif(!preg_match(\"|^/|\",$matches[2]))\n\t\t\t\t\t\t\t$this->_redirectaddr .= \"/\".$matches[2];\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\t$this->_redirectaddr .= $matches[2];\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\t$this->_redirectaddr = $matches[2];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(preg_match(\"|^HTTP/|\",$result_headers[$currentHeader]))\n\t\t\t\t$this->response_code = $result_headers[$currentHeader];\n\n\t\t\t$this->headers[] = $result_headers[$currentHeader];\n\t\t}\n\n\t\t// check if there is a a redirect meta tag\n\n\t\tif(preg_match(\"'<meta[\\s]*http-equiv[^>]*?content[\\s]*=[\\s]*[\\\"\\']?\\d+;[\\s]*URL[\\s]*=[\\s]*([^\\\"\\']*?)[\\\"\\']?>'i\",$results,$match))\n\t\t{\n\t\t\t$this->_redirectaddr = $this->_expandlinks($match[1],$URI);\n\t\t}\n\n\t\t// have we hit our frame depth and is there frame src to fetch?\n\t\tif(($this->_framedepth < $this->maxframes) && preg_match_all(\"'<frame\\s+.*src[\\s]*=[\\'\\\"]?([^\\'\\\"\\>]+)'i\",$results,$match))\n\t\t{\n\t\t\t$this->results[] = $results;\n\t\t\tfor($x=0; $x<count($match[1]); $x++)\n\t\t\t\t$this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS[\"scheme\"].\"://\".$this->host);\n\t\t}\n\t\t// have we already fetched framed content?\n\t\telseif(is_array($this->results))\n\t\t\t$this->results[] = $results;\n\t\t// no framed content\n\t\telse\n\t\t\t$this->results = $results;\n\t\tif (isset($headerfile) && file_exists($headerfile))\n\t\t\tunlink($headerfile);\n\n\t\treturn true;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\tsetcookies()\n\tPurpose:\tset cookies for a redirection\n\t\\*======================================================================*/\n\n\tfunction setcookies()\n\t{\n\t\tfor($x=0; $x<count($this->headers); $x++)\n\t\t{\n\t\t\tif(preg_match('/^set-cookie:[\\s]+([^=]+)=([^;]+)/i', $this->headers[$x],$match))\n\t\t\t\t$this->cookies[$match[1]] = urldecode($match[2]);\n\t\t}\n\t}\n\n\n\t/*======================================================================*\\\n\t Function:\t_check_timeout\n\tPurpose:\tchecks whether timeout has occurred\n\tInput:\t\t$fp\tfile pointer\n\t\\*======================================================================*/\n\n\tfunction _check_timeout($fp)\n\t{\n\t\tif ($this->read_timeout > 0) {\n\t\t\t$fp_status = socket_get_status($fp);\n\t\t\tif ($fp_status[\"timed_out\"]) {\n\t\t\t\t$this->timed_out = true;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\t_connect\n\tPurpose:\tmake a socket connection\n\tInput:\t\t$fp\tfile pointer\n\t\\*======================================================================*/\n\n\tfunction _connect(&$fp)\n\t{\n\t\tif(!empty($this->proxy_host) && !empty($this->proxy_port))\n\t\t{\n\t\t\t$this->_isproxy = true;\n\n\t\t\t$host = $this->proxy_host;\n\t\t\t$port = $this->proxy_port;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t$host = $this->host;\n\t\t\t$port = $this->port;\n\t\t}\n\n\t\t$this->status = 0;\n\n\t\tif($fp = fsockopen(\n\t\t\t\t$host,\n\t\t\t\t$port,\n\t\t\t\t$errno,\n\t\t\t\t$errstr,\n\t\t\t\t$this->_fp_timeout\n\t\t))\n\t\t{\n\t\t\t// socket connection succeeded\n\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// socket connection failed\n\t\t\t$this->status = $errno;\n\t\t\tswitch($errno)\n\t\t\t{\n\t\t\t\tcase -3:\n\t\t\t\t\t$this->error=\"socket creation failed (-3)\";\n\t\t\t\tcase -4:\n\t\t\t\t\t$this->error=\"dns lookup failure (-4)\";\n\t\t\t\tcase -5:\n\t\t\t\t\t$this->error=\"connection refused or timed out (-5)\";\n\t\t\t\tdefault:\n\t\t\t\t\t$this->error=\"connection failed (\".$errno.\")\";\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\t/*======================================================================*\\\n\t Function:\t_disconnect\n\tPurpose:\tdisconnect a socket connection\n\tInput:\t\t$fp\tfile pointer\n\t\\*======================================================================*/\n\n\tfunction _disconnect($fp)\n\t{\n\t\treturn(fclose($fp));\n\t}\n\n\n\t/*======================================================================*\\\n\t Function:\t_prepare_post_body\n\tPurpose:\tPrepare post body according to encoding type\n\tInput:\t\t$formvars  - form variables\n\t$formfiles - form upload files\n\tOutput:\t\tpost body\n\t\\*======================================================================*/\n\n\tfunction _prepare_post_body($formvars, $formfiles)\n\t{\n\t\tsettype($formvars, \"array\");\n\t\tsettype($formfiles, \"array\");\n\t\t$postdata = '';\n\n\t\tif (count($formvars) == 0 && count($formfiles) == 0)\n\t\t\treturn;\n\t\tif (is_string($formvars)) return $formvars;\n\t\tif((count($formvars) == 1) && isset($formvars[0])) return $formvars[0];\n\t\tswitch ($this->_submit_type) {\n\t\t\tcase \"application/x-www-form-urlencoded\":\n\t\t\t\treset($formvars);\n\t\t\t\twhile(list($key,$val) = each($formvars)) {\n\t\t\t\t\tif (is_array($val) || is_object($val)) {\n\t\t\t\t\t\twhile (list($cur_key, $cur_val) = each($val)) {\n\t\t\t\t\t\t\t$postdata .= urlencode($key).\"[]=\".urlencode($cur_val).\"&\";\n\t\t\t\t\t\t}\n\t\t\t\t\t} else\n\t\t\t\t\t\t$postdata .= urlencode($key).\"=\".urlencode($val).\"&\";\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"multipart/form-data\":\n\t\t\t\t$this->_mime_boundary = \"--------\".md5(uniqid(microtime()));\n\n\t\t\t\treset($formvars);\n\t\t\t\twhile(list($key,$val) = each($formvars)) {\n\t\t\t\t\tif (is_array($val) || is_object($val)) {\n\t\t\t\t\t\twhile (list($cur_key, $cur_val) = each($val)) {\n\t\t\t\t\t\t\t$postdata .= \"--\".$this->_mime_boundary.\"\\r\\n\";\n\t\t\t\t\t\t\t$postdata .= \"Content-Disposition: form-data; name=\\\"$key\\[\\]\\\"\\r\\n\\r\\n\";\n\t\t\t\t\t\t\t$postdata .= \"$cur_val\\r\\n\";\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$postdata .= \"--\".$this->_mime_boundary.\"\\r\\n\";\n\t\t\t\t\t\t$postdata .= \"Content-Disposition: form-data; name=\\\"$key\\\"\\r\\n\\r\\n\";\n\t\t\t\t\t\t$postdata .= \"$val\\r\\n\";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treset($formfiles);\n\t\t\t\twhile (list($field_name, $file_names) = each($formfiles)) {\n\t\t\t\t\tsettype($file_names, \"array\");\n\t\t\t\t\twhile (list(, $file_name) = each($file_names)) {\n\t\t\t\t\t\t$file_content = file_get_contents($file_name);\n\t\t\t\t\t\tif (!$file_content) continue;\n\n\t\t\t\t\t\t$base_name = basename($file_name);\n\n\t\t\t\t\t\t$postdata .= \"--\".$this->_mime_boundary.\"\\r\\n\";\n\t\t\t\t\t\t$postdata .= \"Content-Disposition: form-data; name=\\\"$field_name\\\"; filename=\\\"$base_name\\\"\\r\\nContent-Type: image/jpeg\\r\\n\\r\\n\";\n\t\t\t\t\t\t$postdata .= \"$file_content\\r\\n\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$postdata .= \"--\".$this->_mime_boundary.\"--\\r\\n\";\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn $postdata;\n\t}\n}"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/old_version/Thinkphp/Wechatauth.class.php",
    "content": "<?php\n/**\n *\t微信公众平台PHP-SDK\n *  Wechatauth为非官方微信登陆API\n *  用户通过扫描网页提供的二维码实现登陆信息获取\n *  主要实现如下功能:\n *  get_login_code() 获取登陆授权码, 通过授权码才能获取二维码\n *  get_code_image($code='') 将上面获取的授权码转换为图片二维码\n *  verify_code() 鉴定是否登陆成功,返回200为最终授权成功.\n *  get_login_info() 鉴定成功后调用此方法即可获取用户基本信息\n *  get_avatar($url) 获取用户头像图片数据\n *  @author dodge <dodgepudding@gmail.com>\n *  @link https://github.com/dodgepudding/wechat-php-sdk\n *  @version 1.1\n *  \n */\ninclude \"Snoopy.class.php\";\nclass Wechatauth\n{\n\tprivate $cookie;\n\tprivate $skey;\n\tprivate $_cookiename;\n\tprivate $_cookieexpired = 3600;\n\tprivate $_account = 'test';\n\tprivate $_datapath = './data/cookie_';\n\tprivate $debug;\n\tprivate $_logcallback;\n\tpublic $login_user; //当前登陆用户, 调用get_login_info后获取\n\t\n\tpublic function __construct($options)\n\t{\n\t\t$this->_account = isset($options['account'])?$options['account']:'';\n\t\t$this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;\n\t\t$this->debug = isset($options['debug'])?$options['debug']:false;\n\t\t$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;\n\t\t$this->_cookiename = $this->_datapath.$this->_account;\n\t\t$this->getCookie($this->_cookiename);\n\t}\n\t/**\n\t * 把cookie写入缓存\n\t * @param  string $filename 缓存文件名\n\t * @param  string $content  文件内容\n\t * @return bool\n\t */\n\tpublic function saveCookie($filename,$content){\n\t\treturn S($filename,$content,$this->_cookieexpired);\n\t}\n\n\t/**\n\t * 读取cookie缓存内容\n\t * @param  string $filename 缓存文件名\n\t * @return string cookie\n\t */\n\tpublic function getCookie($filename){\n\t\t$data = S($filename);\n\t\tif ($data) $this->cookie = $data;\n\t\treturn $this->cookie;\n\t}\n\t\n\t/*\n\t * 删除cookie\n\t */\n\tpublic function deleteCookie($filename) {\n\t\t$this->cookie = '';\n\t\tS($filename,null);\n\t\treturn true;\n\t}\n\t\n\tprivate function log($log){\n\t\tif ($this->debug && function_exists($this->_logcallback)) {\n\t\t\tif (is_array($log)) $log = print_r($log,true);\n\t\t\treturn call_user_func($this->_logcallback,$log);\n\t\t}\n\t}\n\t\n\t/**\n\t * 获取登陆二维码对应的授权码\n\t */\t\n\tpublic function get_login_code(){\n\t\tif ($this->_logincode) return $this->_logincode;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$codeurl = 'https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_='.$t;\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->fetch($codeurl);\n\t\t$result = $send_snoopy->results;\n\t\tif ($result) {\n\t\t\tpreg_match(\"/window.QRLogin.uuid\\s+=\\s+\\\"([^\\\"]+)\\\"/\",$result,$matches);\n\t\t\tif(count($matches)>1) {\n\t\t\t\t$this->_logincode = $matches[1];\n\t\t\t\t$_SESSION['login_step'] = 0;\n\t\t\t\treturn $this->_logincode;\n\t\t\t}\n\t\t}\n\t\treturn $result;\n\t}\n\n\t/**\n\t * 通过授权码获取对应的二维码图片地址\n\t * @param string $code\n\t * @return string image url\n\t */\n\tpublic function get_code_image($code=''){\n\t\tif ($code=='') $code = $this->_logincode;\n\t\tif (!$code) return false;\n\t\treturn 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';\n\t}\n\t\n\t/**\n\t * 设置二维码对应的授权码\n\t * @param string $code\n\t * @return class $this\n\t */\n\tpublic  function set_login_code($code) {\n\t\t$this->_logincode = $code;\n\t\treturn $this;\n\t}\n\t\n\t/**\n\t * 二维码登陆验证\n\t *\n\t * @return status:\n\t * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired\n\t * 201: just scaned but not confirm\n\t * 200: confirm then you can get user info\n\t */\n\tpublic function verify_code() {\n\t\tif (!$this->_logincode) return false;\n\t\t$t = time().strval(mt_rand(100,999));\n\n\t\t\t$url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=0&_='.$t;\n\t\t\t$send_snoopy = new Snoopy; \n\t\t\t$send_snoopy->referer = \"https://wx.qq.com/\";\n\t\t\t$send_snoopy->fetch($url);\n\t\t\t$result = $send_snoopy->results;\n\t\t\t$this->log('step1:'.$result);\n\t\t\tif ($result) {\n\t\t\t\tpreg_match(\"/window\\.code=(\\d+)/\",$result,$matches);\n\t\t\t\tif(count($matches)>1) {\n\t\t\t\t\t$status = intval($matches[1]);\n\t\t\t\t\tif ($status==201) $_SESSION['login_step'] = 1;\n\t\t\t\t\tif ($status==200) {\n\t\t\t\t\t\tpreg_match(\"/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\\d+)/\",$result,$matches);\n\t\t\t\t\t\tpreg_match(\"/window.redirect_uri=\\\"([^\\\"]+)\\\"/\",$result,$matcheurl);\n\t\t\t\t\t\t$this->log('step2:'.print_r($matches,true));\n\t\t\t\t\t\tif (count($matcheurl)>1) {\n\t\t\t\t\t\t\t$ticket = $matches[1];\n\t\t\t\t\t\t\t$scan = $matches[2];\n\t\t\t\t\t\t\t//$loginurl = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';\n\t\t\t\t\t\t\t$loginurl = str_replace(\"wx.qq.com\", \"wx2.qq.com\", $matcheurl[1]).'&fun=old';\n\t\t\t\t\t\t\t$urlpart = parse_url($loginurl);\n\t\t\t\t\t\t\t$send_snoopy = new Snoopy; \n\t\t\t\t\t\t\t$send_snoopy->referer = \"https://{$urlpart['host']}/cgi-bin/mmwebwx-bin/webwxindex?t=chat\";\n\t\t\t\t\t\t\t$send_snoopy->fetch($loginurl);\n\t\t\t\t\t\t\t$result = $send_snoopy->results;\n\t\t\t\t\t\t\t$xml = simplexml_load_string($result);\n\t\t\t\t\t\t\tif ($xml->ret==\"0\") $this->skey = $xml->skey;\n\t\t\t\t\t\t\tforeach ($send_snoopy->headers as $key => $value) {\n\t\t\t\t\t\t\t\t$value = trim($value);\n\t\t\t\t\t\t\t\tif(strpos($value,'Set-Cookie: ') !== false){\n\t\t\t\t\t\t\t\t\t$tmp = str_replace(\"Set-Cookie: \",\"\",$value);\n\t\t\t\t\t\t\t\t\t$tmparray = explode(';', $tmp);\n\t\t\t\t\t\t\t\t\t$item = trim($tmparray[0]);\n\t\t\t\t\t\t\t\t\t$cookie.=$item.';';\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$cookie .=\"Domain=.qq.com;\";\n\t\t\t\t\t\t\t$this->cookie = $cookie;\n\t\t\t\t\t\t\t$this->log('step3:'.$loginurl.';cookie:'.$cookie.';respond:'.$result);\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t$this->saveCookie($this->_cookiename,$this->cookie);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn $status;\n\t\t\t\t}\n\t\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取登陆的cookie\n\t *\n\t * @param bool $is_array 是否以数值方式返回，默认否，返回字符串\n\t * @return string|array\n\t */\n\tpublic function get_login_cookie($is_array = false){\n\t\tif (!$is_array)\treturn $this->cookie;\n\t\t$c_arr = explode(';',$this->cookie);\n\t\t$cookie = array();\n\t\tforeach($c_arr as $item) {\n\t\t\t$kitem = explode('=',trim($item));\n\t\t\tif (count($kitem)>1) {\n\t\t\t\t$key = trim($kitem[0]);\n\t\t\t\t$val = trim($kitem[1]);\n\t\t\t\tif (!empty($val)) $cookie[$key] = $val;\n\t\t\t}\n\t\t}\n\t\treturn $cookie;\n\t}\n\t\n\t/**\n\t * \t 授权登陆后获取用户登陆信息\n\t */\n\tpublic function get_login_info(){\n\t\tif (!$this->cookie) return false;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$send_snoopy = new Snoopy; \n\t\t$submit = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t.'&skey='.urlencode($this->skey);\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://wx2.qq.com/\";\n\t\t$citems = $this->get_login_cookie(true);\n\t\t$post = array(\n\t\t\t\"BaseRequest\"=>array(\n\t\t\t\tarray(\n\t\t\t\t\t\"Uin\"=>$citems['wxuin'],\n\t\t\t\t\t\"Sid\"=>$citems['wxsid'],\n\t\t\t\t\t\"Skey\"=>$this->skey,\n\t\t\t\t\t\"DeviceID\"=>''\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t\t$send_snoopy->submit($submit,json_encode($post));\n\t\t$this->log('login_info:'.$send_snoopy->results);\n\t\t$result = json_decode($send_snoopy->results,true);\n\t\tif ($result['BaseResponse']['Ret']<0) return false;\n\t\t$this->_login_user = $result['User'];\n\t\treturn $result;\n\t}\n\t\n\t/**\n\t *  获取头像\n\t *  @param string $url 传入从用户信息接口获取到的头像地址\n\t */\n\tpublic function get_avatar($url) {\n\t\tif (!$this->cookie) return false;\n\t\tif (strpos($url, 'http')===false) {\n\t\t\t$url = 'http://wx2.qq.com'.$url;\n\t\t}\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://wx2.qq.com/\";\n\t\t$send_snoopy->fetch($url);\n\t\t$result = $send_snoopy->results;\n\t\tif ($result) \n\t\t\treturn $result;\n\t\telse\n\t\t\treturn false;\n\t}\n\t\n\t/**\n\t * 登出当前登陆用户\n\t */\n\tpublic function logout(){\n\t\tif (!$this->cookie) return false;\n\t\tpreg_match(\"/wxuin=(\\w+);/\",$this->cookie,$matches);\n\t\tif (count($matches)>1) $uid = $matches[1];\n\t\tpreg_match(\"/wxsid=(\\w+);/\",$this->cookie,$matches);\n\t\tif (count($matches)>1) $sid = $matches[1];\n\t\t$this->log('logout: uid='.$uid.';sid='.$sid);\n\t\t$send_snoopy = new Snoopy; \n\t\t$submit = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://wx2.qq.com/\";\n\t\t$send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));\n\t\t$this->deleteCookie($this->_cookiename);\n\t\treturn true;\n\t}\n}\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/old_version/Thinkphp/Wechatext.class.php",
    "content": "<?php\n/**\n *\t微信公众平台PHP-SDK\n *  Wechatext为非官方微信发送API\n *  注: 用户id为通过getMsg()方法获取的FakeId值\n *  主要实现如下功能:\n *  send($id,$content) 向某用户id发送微信文字信息\n *  getUserList($page,$pagesize,$groupid) 获取用户信息\n *  getGroupList($page,$pagesize) 获取群组信息\n *  sendNews($id,$msgid) 发送图文消息\n *  getNewsList($page,$pagesize) 获取图文信息列表\n *  uploadFile($filepath,$type) 上传附件,包括图片/音频/视频\n *  addPreview($title,$author,$summary,$content,$photoid,$srcurl='')   创建新的图文信息 \n *  getFileList($type,$page,$pagesize) 获取素材库文件列表\n *  sendImage($id,$fid) 发送图片消息\n *  sendAudio($id,$fid) 发送音频消息\n *  sendVideo($id,$fid) 发送视频消息\n *  getInfo($id) 根据id获取用户资料\n *  getNewMsgNum($lastid) 获取从$lastid算起新消息的数目\n *  getTopMsg() 获取最新一条消息的数据, 此方法获取的消息id可以作为检测新消息的$lastid依据\n *  getMsg($lastid,$offset=0,$perpage=50,$day=0,$today=0,$star=0) 获取最新的消息列表, 列表将返回消息id, 用户id, 消息类型, 文字消息等参数\n *  消息返回结构:  {\"id\":\"消息id\",\"type\":\"类型号(1为文字,2为图片,3为语音)\",\"fileId\":\"0\",\"hasReply\":\"0\",\"fakeId\":\"用户uid\",\"nickName\":\"昵称\",\"dateTime\":\"时间戳\",\"content\":\"文字内容\"} \n *  getMsgImage($msgid,$mode='large') 若消息type类型为2, 调用此方法获取图片数据\n *  getMsgVoice($msgid) 若消息type类型为3, 调用此方法获取语音数据\n *  quickSetInterface($url, $token) 快速设置接口信息\n *  @author dodge <dodgepudding@gmail.com>\n *  @link https://github.com/dodgepudding/wechat-php-sdk\n *  @version 1.2\n *  \n */\n\ninclude \"Snoopy.class.php\";\nclass Wechatext\n{\n\tprivate $cookie;\n\tprivate $_cookiename;\n\tprivate $_cookieexpired = 3600;\n\tprivate $_account;\n\tprivate $_password;\n\tprivate $_datapath = './data/cookie_';\n\tprivate $debug;\n\tprivate $_logcallback;\n\tprivate $_token;\n\t\n\tpublic function __construct($options)\n\t{\n\t\t$this->_account = isset($options['account'])?$options['account']:'';\n\t\t$this->_password = isset($options['password'])?$options['password']:'';\n\t\t$this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;\n\t\t$this->debug = isset($options['debug'])?$options['debug']:false;\n\t\t$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;\n\t\t$this->_cookiename = $this->_datapath.$this->_account;\n\t\t$this->cookie = $this->getCookie($this->_cookiename);\n\t}\n\n\t/**\n\t * 主动发消息\n\t * @param  string $id      用户的uid(即FakeId)\n\t * @param  string $content 发送的内容\n\t */\n\tpublic function send($id,$content)\n\t{\n\t\t$send_snoopy = new Snoopy; \n\t\t$post = array();\n\t\t$post['tofakeid'] = $id;\n\t\t$post['type'] = 1;\n\t\t$post['token'] = $this->_token;\n\t\t$post['content'] = $content;\n\t\t$post['ajax'] = 1;\n        $send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/singlesendpage?t=message/send&action=index&tofakeid=$id&token={$this->_token}&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response\";\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$this->log($send_snoopy->results);\n\t\treturn $send_snoopy->results;\n\t}\n\t\n\t/**\n\t * 群发功能 纯文本\n\t * @param string $content\n\t * @return string\n\t */\n\tpublic function mass($content) {\n\t\t$send_snoopy = new Snoopy;\n\t\t$post = array();\n\t\t$post['type'] = 1;\n\t\t$post['token'] = $this->_token;\n\t\t$post['content'] = $content;\n\t\t$post['ajax'] = 1;\n\t\t$post['city']='';\n\t\t$post['country']='';\n\t\t$post['f']='json';\n\t\t$post['groupid']='-1';\n\t\t$post['imgcode']='';\n\t\t$post['lang']='zh_CN';\n\t\t$post['province']='';\n\t\t$post['random']=  rand(0, 1);\n\t\t$post['sex']=0;\n\t\t$post['synctxnews']=0;\n\t\t$post['synctxweibo']=0;\n\t\t$post['t']='ajax-response';\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token={$this->_token}&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/masssend\";\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$this->log($send_snoopy->results);\n\t\treturn $send_snoopy->results;\n\t}\n\t\n\t/**\n\t * 群发功能 图文素材\n\t * @param int $appmsgid 图文素材ID\n\t * @return string\n\t */\n\tfunction massNews($appmsgid){\n\t\t$send_snoopy = new Snoopy;\n\t\t$post = array();\n\t\t$post['type'] = 10;\n\t\t$post['token'] = $this->_token;\n\t\t$post['appmsgid'] = $appmsgid;\n\t\t$post['ajax'] = 1;\n\t\t$post['city']='';\n\t\t$post['country']='';\n\t\t$post['f']='json';\n\t\t$post['groupid']='-1';\n\t\t$post['imgcode']='';\n\t\t$post['lang']='zh_CN';\n\t\t$post['province']='';\n\t\t$post['random']=  rand(0, 1);\n\t\t$post['sex']=0;\n\t\t$post['synctxnews']=0;\n\t\t$post['synctxweibo']=0;\n\t\t$post['t']='ajax-response';\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token={$this->_token}&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/masssend\";\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$this->log($send_snoopy->results);\n\t\treturn $send_snoopy->results;\n\t}\n\t\n\t/**\n\t * 获取用户列表列表\n\t * @param $page 页码(从0开始)\n\t * @param $pagesize 每页大小\n\t * @param $groupid 分组id\n\t * @return array ({contacts:[{id:12345667,nick_name:\"昵称\",remark_name:\"备注名\",group_id:0},{}....]})\n\t */\n\tfunction getUserList($page=0,$pagesize=10,$groupid=0){\n\t\t$send_snoopy = new Snoopy;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=\".$pagesize.\"&pageidx=\".$page.\"&type=0&groupid=0&lang=zh_CN&token=\".$this->_token;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=\".$pagesize.\"&pageidx=\".$page.\"&type=0&groupid=$groupid&lang=zh_CN&f=json&token=\".$this->_token;\n\t\t$send_snoopy->fetch($submit);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('userlist:'.$result);\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['contact_list'])) {\n\t\t\t$json = json_decode($json['contact_list'],true);\n\t\t\tif (isset($json['contacts']))\n\t\t\t\treturn $json['contacts'];\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取分组列表\n\t * \n\t */\n\tfunction getGroupList(){\n\t\t$send_snoopy = new Snoopy;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=0&lang=zh_CN&token=\".$this->_token;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=0&lang=zh_CN&f=json&token=\".$this->_token;\n\t\t$send_snoopy->fetch($submit);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('userlist:'.$result);\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['group_list'])){\n\t\t\t$json = json_decode($json['group_list'],true);\n\t\t\tif (isset($json['groups']))\n\t\t\t\treturn $json['groups'];\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取图文信息列表\n\t * @param $page 页码(从0开始)\n\t * @param $pagesize 每页大小\n\t * @return array\n\t */\n\tpublic function getNewsList($page,$pagesize=10) {\n\t\t$send_snoopy = new Snoopy;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$type=10;\n\t\t$begin = $page*$pagesize;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=\".$this->_token.\"&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/appmsg?token=\".$this->_token.\"&lang=zh_CN&type=$type&action=list&begin=$begin&count=$pagesize&f=json&random=0.\".$t;\n\t\t$send_snoopy->fetch($submit);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('newslist:'.$result);\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['app_msg_info'])) {\n\t\t\treturn $json['app_msg_info'];\n\t\t} \n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取与指定用户的对话内容\n\t * @param  $fakeid\n\t * @return  array\n\t */\n\tpublic function getDialogMsg($fakeid) {\n\t\t$send_snoopy = new Snoopy;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=\".$this->_token.\"&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/singlesendpage?t=message/send&action=index&tofakeid=\".$fakeid.\"&token=\".$this->_token.\"&lang=zh_CN&f=json&random=\".$t;\n\t\t$send_snoopy->fetch($submit);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('DialogMsg:'.$result);\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['page_info'])) {\n\t\t\treturn $json['page_info'];\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 发送图文信息,必须从图文库里选取消息ID发送\n\t * @param  string $id      用户的uid(即FakeId)\n\t * @param  string $msgid 图文消息id\n\t */\n\tpublic function sendNews($id,$msgid)\n\t{\n\t\t$send_snoopy = new Snoopy; \n\t\t$post = array();\n\t\t$post['tofakeid'] = $id;\n\t\t$post['type'] = 10;\n\t\t$post['token'] = $this->_token;\n\t\t$post['fid'] = $msgid;\n\t\t$post['appmsgid'] = $msgid;\n\t\t$post['error'] = 'false';\n\t\t$post['ajax'] = 1;\n        $send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/singlemsgpage?fromfakeid={$id}&msgid=&source=&count=20&t=wxm-singlechat&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response\";\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$this->log($send_snoopy->results);\n\t\treturn $send_snoopy->results;\n\t}\n\t\n\t/**\n\t * 上传附件(图片/音频/视频)\n\t * @param string $filepath 本地文件地址\n\t * @param int $type 文件类型: 2:图片 3:音频 4:视频\n\t */\n\tpublic function uploadFile($filepath,$type=2) {\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->referer = \"http://mp.weixin.qq.com/cgi-bin/indexpage?t=wxm-upload&lang=zh_CN&type=2&formId=1\";\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$post = array('formId'=>'');\n\t\t$postfile = array('uploadfile'=>$filepath);\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->set_submit_multipart();\n\t\t$submit = \"http://mp.weixin.qq.com/cgi-bin/uploadmaterial?cgi=uploadmaterial&type=$type&token=\".$this->_token.\"&t=iframe-uploadfile&lang=zh_CN&formId=\tfile_from_\".$t;\n\t\t$send_snoopy->submit($submit,$post,$postfile);\n\t\t$tmp = $send_snoopy->results;\n\t\t$this->log('upload:'.$tmp);\n\t\tpreg_match(\"/formId,.*?\\'(\\d+)\\'/\",$tmp,$matches);\n\t\tif (isset($matches[1])) {\n\t\t\treturn $matches[1];\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 创建图文消息\n\t * @param array $title 标题\n\t * @param array $summary 摘要\n\t * @param array $content 内容\n\t * @param array $photoid 素材库里的图片id(可通过uploadFile上传后获取)\n\t * @param array $srcurl 原文链接\n\t * @return json\n\t */\n\tpublic function addPreview($title,$author,$summary,$content,$photoid,$srcurl='') {\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->referer = 'https://mp.weixin.qq.com/cgi-bin/operate_appmsg?lang=zh_CN&sub=edit&t=wxm-appmsgs-edit-new&type=10&subtype=3&token='.$this->_token;\n\t\t\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/operate_appmsg?lang=zh_CN&t=ajax-response&sub=create&token=\".$this->_token;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t\n\t\t$send_snoopy->set_submit_normal();\n\t\t$post = array(\n\t\t\t\t'token'=>$this->_token,\n\t\t\t\t'type'=>10,\n\t\t\t\t'lang'=>'zh_CN',\n\t\t\t\t'sub'=>'create',\n\t\t\t\t'ajax'=>1,\n\t\t\t\t'AppMsgId'=>'',\t\t\t\t\n\t\t\t\t'error'=>'false',\n\t\t);\n\t\tif (count($title)==count($author)&&count($title)==count($summary)&&count($title)==count($content)&&count($title)==count($photoid))\n\t\t{\n\t\t\t$i = 0;\n\t\t\tforeach($title as $v) {\n\t\t\t\t$post['title'.$i] = $title[$i];\n\t\t\t\t$post['author'.$i] = $author[$i];\n\t\t\t\t$post['digest'.$i] = $summary[$i];\n\t\t\t\t$post['content'.$i] = $content[$i];\n\t\t\t\t$post['fileid'.$i] = $photoid[$i];\n\t\t\t\tif ($srcurl[$i]) $post['sourceurl'.$i] = $srcurl[$i];\n\t\t\t\t\n\t\t\t\t$i++;\n\t\t\t\t}\n\t\t}\n\t\t$post['count'] = $i;\n\t\t$post['token'] = $this->_token;\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$tmp = $send_snoopy->results;\n\t\t$this->log('step2:'.$tmp);\n\t\t$json = json_decode($tmp,true);\n\t\treturn $json;\n\t}\n\t\n\t/**\n\t * 发送媒体文件\n\t * @param $id 用户的uid(即FakeId)\n\t * @param $fid 文件id\n\t * @param $type 文件类型\n\t */\n\tpublic function sendFile($id,$fid,$type) {\n\t\t$send_snoopy = new Snoopy; \n\t\t$post = array();\n\t\t$post['tofakeid'] = $id;\n\t\t$post['type'] = $type;\n\t\t$post['token'] = $this->_token;\n\t\t$post['fid'] = $fid;\n\t\t$post['fileid'] = $fid;\n\t\t$post['error'] = 'false';\n\t\t$post['ajax'] = 1;\n        $send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/singlemsgpage?fromfakeid={$id}&msgid=&source=&count=20&t=wxm-singlechat&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response\";\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('sendfile:'.$result);\n\t\t$json = json_decode($result,true);\n\t\tif ($json && $json['ret']==0) \n\t\t\treturn true;\n\t\telse\n\t\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取素材库文件列表\n\t * @param $type 文件类型: 2:图片 3:音频 4:视频\n\t * @param $page 页码(从0开始)\n\t * @param $pagesize 每页大小\n\t * @return array\n\t */\n\tpublic function getFileList($type,$page,$pagesize=10) {\n\t\t$send_snoopy = new Snoopy;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$begin = $page*$pagesize;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=\".$this->_token.\"&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/filepage?token=\".$this->_token.\"&lang=zh_CN&type=$type&random=0.\".$t.\"&begin=$begin&count=$pagesize&f=json\";\n\t\t$send_snoopy->fetch($submit);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('filelist:'.$result);\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['page_info']))\n\t\t\treturn $json['page_info'];\n\t\telse\n\t\t\treturn false;\n\t}\n\t\n\t/**\n\t * 发送图文信息,必须从库里选取文件ID发送\n\t * @param  string $id      用户的uid(即FakeId)\n\t * @param  string $fid 文件id\n\t */\n\tpublic function sendImage($id,$fid)\n\t{\n\t\treturn $this->sendFile($id,$fid,2);\n\t}\n\t\n\t/**\n\t * 发送语音信息,必须从库里选取文件ID发送\n\t * @param  string $id      用户的uid(即FakeId)\n\t * @param  string $fid 语音文件id\n\t */\n\tpublic function sendAudio($id,$fid)\n\t{\n\t\treturn $this->sendFile($id,$fid,3);\n\t}\n\t\n\t/**\n\t * 发送视频信息,必须从库里选取文件ID发送\n\t * @param  string $id      用户的uid(即FakeId)\n\t * @param  string $fid 视频文件id\n\t */\n\tpublic function sendVideo($id,$fid)\n\t{\n\t\treturn $this->sendFile($id,$fid,4);\n\t}\n\t\n\t/**\n\t * 发送预览图文消息\n\t * @param string $account 账户名称(user_name)\n\t * @param string $title 标题\n\t * @param string $summary 摘要\n\t * @param string $content 内容\n\t * @param string $photoid 素材库里的图片id(可通过uploadFile上传后获取)\n\t * @param string $srcurl 原文链接\n\t * @return json\n\t */\n\tpublic function sendPreview($account,$title,$summary,$content,$photoid,$srcurl='') {\n\t\t$send_snoopy = new Snoopy;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/operate_appmsg?sub=preview&t=ajax-appmsg-preview\";\n\t\t$send_snoopy->set_submit_normal();\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = 'https://mp.weixin.qq.com/cgi-bin/operate_appmsg?sub=edit&t=wxm-appmsgs-edit-new&type=10&subtype=3&lang=zh_CN';\n\t\t$post = array(\n\t\t\t\t'AppMsgId'=>'',\n\t\t\t\t'ajax'=>1,\n\t\t\t\t'content0'=>$content,\n\t\t\t\t'count'=>1,\n\t\t\t\t'digest0'=>$summary,\n\t\t\t\t'error'=>'false',\n\t\t\t\t'fileid0'=>$photoid,\n\t\t\t\t'preusername'=>$account,\n\t\t\t\t'sourceurl0'=>$srcurl,\n\t\t\t\t'title0'=>$title,\n\t\t);\n\t\t$post['token'] = $this->_token;\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$tmp = $send_snoopy->results;\n\t\t$this->log('sendpreview:'.$tmp);\n\t\t$json = json_decode($tmp,true);\n\t\treturn $json;\n\t}\n\t\n\t/**\n\t * 获取用户的信息\n\t * @param  string $id 用户的uid(即FakeId)\n\t * @return array  {fake_id:100001,nick_name:'昵称',user_name:'用户名',signature:'签名档',country:'中国',province:'广东',city:'广州',gender:'1',group_id:'0'},groups:{[id:0,name:'未分组',cnt:20]}\n\t */\n\tpublic function getInfo($id)\n\t{\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=\".$this->_token;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/getcontactinfo\";\n\t\t$post = array('ajax'=>1,'lang'=>'zh_CN','random'=>'0.'.$t,'token'=>$this->_token,'t'=>'ajax-getcontactinfo','fakeid'=>$id);\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$this->log($send_snoopy->results);\n\t\t$result = json_decode($send_snoopy->results,true);\n\t\tif(isset($result['contact_info'])){\n\t\t\treturn $result['contact_info'];\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获得头像数据\n\t *\n\t * @param FakeId $fakeid\n\t * @return JPG二进制数据\n\t */\n\tpublic function getHeadImg($fakeid){\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=\".$this->_token;\n\t\t$url = \"https://mp.weixin.qq.com/misc/getheadimg?fakeid=$fakeid&token=\".$this->_token.\"&lang=zh_CN\";\n\t\t$send_snoopy->fetch($url);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('Head image:'.$fakeid.'; length:'.strlen($result));\n\t\tif(!$result){\n\t\t\treturn false;\n\t\t}\n\t\treturn $result;\n\t}\n\n\t/**\n\t * 获取消息更新数目\n\t * @param int $lastid 最近获取的消息ID,为0时获取总消息数目\n\t * @return int 数目\n\t */\n\tpublic function getNewMsgNum($lastid=0){\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=\".$this->_token;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/getnewmsgnum?t=ajax-getmsgnum&lastmsgid=\".$lastid;\n\t\t$post = array('ajax'=>1,'token'=>$this->_token);\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$this->log($send_snoopy->results);\n\t\t$result = json_decode($send_snoopy->results,1);\n\t\tif(!$result){\n\t\t\treturn false;\n\t\t}\n\t\treturn intval($result['newTotalMsgCount']);\n\t}\n\t\n\t/**\n\t * 获取最新一条消息\n\t * @return array {\"id\":\"最新一条id\",\"type\":\"类型号(1为文字,2为图片,3为语音)\",\"fileId\":\"0\",\"hasReply\":\"0\",\"fakeId\":\"用户uid\",\"nickName\":\"昵称\",\"dateTime\":\"时间戳\",\"content\":\"文字内容\",\"playLength\":\"0\",\"length\":\"0\",\"source\":\"\",\"starred\":\"0\",\"status\":\"4\"}        \n\t */\n\tpublic function getTopMsg(){\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=20&day=7&lang=zh_CN&token=\".$this->_token;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/message?t=message/list&f=json&count=20&day=7&lang=zh_CN&token=\".$this->_token;\n\t\t$send_snoopy->fetch($submit);\n\t\t$this->log($send_snoopy->results);\n\t\t$result = $send_snoopy->results;\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['msg_items'])) {\n\t\t\t$json = json_decode($json['msg_items'],true);\n\t\t\tif(isset($json['msg_item']))\n\t\t\t\treturn array_shift($json['msg_item']);\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取新消息\n\t * @param $lastid 传入最后的消息id编号,为0则从最新一条起倒序获取\n\t * @param $offset lastid起算第一条的偏移量\n\t * @param $perpage 每页获取多少条\n\t * @param $day 最近几天消息(0:今天,1:昨天,2:前天,3:更早,7:五天内)\n\t * @param $today 是否只显示今天的消息, 与$day参数不能同时大于0\n\t * @param $star 是否星标组信息\n\t * @return array[] 同getTopMsg()返回的字段结构相同\n\t */\n\tpublic function getMsg($lastid=0,$offset=0,$perpage=20,$day=7,$today=0,$star=0){\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/message?t=message/list&lang=zh_CN&count=50&token=\".$this->_token;\n\t\t$lastid = $lastid===0 ? '':$lastid;\n\t\t$addstar = $star?'&action=star':'';\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/message?t=message/list&f=json&lang=zh_CN{$addstar}&count=$perpage&timeline=$today&day=$day&frommsgid=$lastid&offset=$offset&token=\".$this->_token;\n\t\t$send_snoopy->fetch($submit);\n\t\t$this->log($send_snoopy->results);\n\t\t$result = $send_snoopy->results;\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['msg_items'])) {\n\t\t\t$json = json_decode($json['msg_items'],true);\n\t\t\tif(isset($json['msg_item']))\n\t\t\t\treturn $json['msg_item'];\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取图片消息\n\t * @param int $msgid 消息id\n\t * @param string $mode 图片尺寸(large/small)\n\t * @return jpg二进制文件\n\t */\n\tpublic function getMsgImage($msgid,$mode='large'){\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=\".$this->_token;\n\t\t$url = \"https://mp.weixin.qq.com/cgi-bin/getimgdata?token=\".$this->_token.\"&msgid=$msgid&mode=$mode&source=&fileId=0\";\n\t\t$send_snoopy->fetch($url);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('msg image:'.$msgid.';length:'.strlen($result));\n\t\tif(!$result){\n\t\t\treturn false;\n\t\t}\n\t\treturn $result;\n\t}\n\t\n\t/**\n\t * 获取语音消息\n\t * @param int $msgid 消息id\n\t * @return mp3二进制文件\n\t */\n\tpublic function getMsgVoice($msgid){\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=\".$this->_token;\n\t\t$url = \"https://mp.weixin.qq.com/cgi-bin/getvoicedata?token=\".$this->_token.\"&msgid=$msgid&fileId=0\";\n\t\t$send_snoopy->fetch($url);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('msg voice:'.$msgid.';length:'.strlen($result));\n\t\tif(!$result){\n\t\t\treturn false;\n\t\t}\n\t\treturn $result;\n\t}\n\t\n\t/**\n\t * 开启开发者模式\n\t */\n\tpublic function openDevModel()\n\t{\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&lang=zh_CN&token=\".$this->_token;\n\t\t$submit = \"https://mp.weixin.qq.com/misc/skeyform?form=advancedswitchform&lang=zh_CN\";\n\t\t$post['flag']=1;\n        $post['type']=2;   \n        $post['token']=$this->_token;\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log($send_snoopy->results);\n\t\t$json = json_decode($result,true);\n\t\tif(!$result){\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * 关闭编辑模式\n\t */\n\tpublic function closeEditModel()\n\t{\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&lang=zh_CN&token=\".$this->_token;\n\t\t$submit = \"https://mp.weixin.qq.com/misc/skeyform?form=advancedswitchform&lang=zh_CN\";\n\t\t$post['flag']=0;\n        $post['type']=1;   \n        $post['token']=$this->_token;\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log($send_snoopy->results);\n\t\t$json = json_decode($result,true);\n\t\tif(!$result){\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * 配置接口信息\n\t * @param  string $url      接口回调URL\n\t * @param  string $token    接口Token\n\t */\n\tpublic function setUrlToken($url, $token)\n\t{\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/advanced/advanced?action=interface&t=advanced/interface&lang=zh_CN&token=\".$this->_token;\n\t\t$submit = \"https://mp.weixin.qq.com/advanced/callbackprofile?t=ajax-response&lang=zh_CN&token=\".$this->_token;\n\t\t$post['url'] = $url;\n\t\t$post['callback_token'] = $token;\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log($send_snoopy->results);\n\t\t$json = json_decode($result,true);\n\t\tif ($json && $json['ret']==0) \n\t\t\treturn true;\n\t\treturn false;\n\t}\n\n\t/**\n\t * 快速设置接口\n\t * @param  string $url      接口回调URL\n\t * @param  string $token    接口Token\n\t */\n\tpublic function quickSetInterface($url, $token)\n\t{\n\t\tif ($this->closeEditModel() && $this->openDevModel() && $this->setUrlToken($url, $token))\n\t\t\treturn true;\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 模拟登录获取cookie\n\t * @return [type] [description]\n\t */\n\tpublic function login(){\n\t\t$snoopy = new Snoopy; \n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN\";\n\t\t$post[\"username\"] = $this->_account;\n\t\t$post[\"pwd\"] = md5($this->_password);\n\t\t$post[\"f\"] = \"json\";\n\t\t$post[\"imgcode\"] = \"\";\n\t\t$snoopy->referer = \"https://mp.weixin.qq.com/\";\n\t\t$snoopy->submit($submit,$post);\n\t\t$cookie = '';\n\t\t$this->log($snoopy->results);\n\t\t$result = json_decode($snoopy->results,true);\n\t\t\n\t\tif (!isset($result['base_resp']) || $result['base_resp']['ret'] != 0) {\n\t\t\treturn false;\n\t\t}\n        \n\t\tforeach ($snoopy->headers as $key => $value) {\n\t\t\t$value = trim($value);\n\t\t\tif(preg_match('/^set-cookie:[\\s]+([^=]+)=([^;]+)/i', $value,$match))\n\t\t\t\t$cookie .=$match[1].'='.$match[2].'; ';\n\t\t}\n\t\t\n\t\tpreg_match(\"/token=(\\d+)/i\",$result['redirect_url'],$matches);\n\t\tif($matches){\n\t\t\t$this->_token = $matches[1];\n\t\t\t$this->log('token:'.$this->_token);\n\t\t}\n\t\t$cookies='{\"cookie\":\"'.$cookie.'\",\"token\":\"'.$this->_token.'\"}';\n\t\t$this->saveCookie($this->_cookiename,$cookies);\n\t\treturn $cookie;\n\t}\n\n\t/**\n\t * 把cookie写入缓存\n\t * @param  string $filename 缓存文件名\n\t * @param  string $content  文件内容\n\t * @return bool\n\t */\n\tpublic function saveCookie($filename,$content){\n\t\treturn S($filename,$content,$this->_cookieexpired);\n\t}\n\n\t/**\n\t * 读取cookie缓存内容\n\t * @param  string $filename 缓存文件名\n\t * @return string cookie\n\t */\n\tpublic function getCookie($filename){\n\t\t$data = S($filename);\n\t\tif($data){\n\t\t\t$login=json_decode($data,true);\n\t\t\t$send_snoopy = new Snoopy;\n\t\t\t$send_snoopy->rawheaders['Cookie']= $login['cookie'];\n\t\t\t$send_snoopy->maxredirs = 0;\n\t\t\t$url = \"https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token=\".$login['token'];\n\t\t\t$send_snoopy->fetch($url);\n\t\t\t$header = $send_snoopy->headers;\n\t\t\t$this->log('header:'.print_r($send_snoopy->headers,true));\n\t\t\tif( strstr($header[3], 'EXPIRED')){\n\t\t\t\treturn $this->login();\n\t\t\t}else{\n\t\t\t\t$this->_token =$login['token'];\n\t\t\t\treturn $login['cookie'];\n\t\t\t}\n\t\t}else{\n\t\t\treturn $this->login();\n\t\t}\n\t}\n\n\t/**\n\t * 验证cookie的有效性\n\t * @return bool\n\t */\n\tpublic function checkValid()\n\t{\n\t\tif (!$this->cookie || !$this->_token) return false;\n\t\t$send_snoopy = new Snoopy; \n\t\t$post = array('ajax'=>1,'token'=>$this->_token);\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/getregions?id=1017&t=ajax-getregions&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$result = $send_snoopy->results;\n\t\tif(json_decode($result,1)){\n\t\t\treturn true;\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\tprivate function log($log){\n\t\tif ($this->debug ) {\n\t\t\tif (function_exists($this->_logcallback)) {\n\t\t\t\tif (is_array($log)) $log = print_r($log,true);\n\t\t\t\treturn call_user_func($this->_logcallback,$log);\n\t\t\t}elseif (class_exists('Log')) {\n\t\t\t\tLog::write('wechat：'.$log, Log::DEBUG);\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n}\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/old_version/Thinkphp/Wechatpay.class.php",
    "content": "<?php\n/**\n *\t微信公众平台PHP-SDK, 旧版微信支付接口(微信支付V2)\n *  @author  dodge <dodgepudding@gmail.com>\n *  @link https://github.com/dodgepudding/wechat-php-sdk\n *  @version 1.2\n *  参考旧版文档 https://mp.weixin.qq.com/cgi-bin/readtemplate?t=business/course2_tmpl&lang=zh_CN\n *  usage:\n *   $options = array(\n *\t\t\t'appid'=>'wxdk1234567890', //填写高级调用功能的app id\n *\t\t\t'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥\n *\t\t\t'partnerid'=>'88888888', //财付通商户身份标识\n *\t\t\t'partnerkey'=>'', //财付通商户权限密钥Key\n *\t\t\t'paysignkey'=>'' //商户签名密钥Key\n *\t\t);\n *\t $payObj = new Wechatpay($options);\n *   $package = $payObj->createPackage($out_trade_no,$body,$total_fee,$notify_url,$spbill_create_ip,$fee_type,$bank_type,$input_charset,$time_start,$time_expire,$transport_fee,$product_fee,$goods_tag,$attach);\n *\n */\nclass Wechatpay\n{\n\tconst API_URL_PREFIX = 'https://api.weixin.qq.com/cgi-bin';\n\tconst AUTH_URL = '/token?grant_type=client_credential&';\n\tconst API_BASE_URL_PREFIX = 'https://api.weixin.qq.com'; //以下API接口URL需要使用此前缀\n\tconst PAY_DELIVERNOTIFY = '/pay/delivernotify?';\n\tconst PAY_ORDERQUERY = '/pay/orderquery?';\n\n\tprivate $appid;\n\tprivate $appsecret;\n\tprivate $access_token;\n\tprivate $user_token;\n\tprivate $partnerid;\n\tprivate $partnerkey;\n\tprivate $paysignkey;\n\n\tpublic $debug =  false;\n\tpublic $errCode = 40001;\n\tpublic $errMsg = \"no access\";\n\tprivate $_logcallback;\n\n\tpublic function __construct($options)\n\t{\n\t\t$this->appid = isset($options['appid'])?$options['appid']:'';\n\t\t$this->appsecret = isset($options['appsecret'])?$options['appsecret']:'';\n\t\t$this->partnerid = isset($options['partnerid'])?$options['partnerid']:'';\n\t\t$this->partnerkey = isset($options['partnerkey'])?$options['partnerkey']:'';\n\t\t$this->paysignkey = isset($options['paysignkey'])?$options['paysignkey']:'';\n\t\t$this->debug = isset($options['debug'])?$options['debug']:false;\n\t\t$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;\n\t}\n\n    private function log($log){\n    \t\tif ($this->debug ) {\n    \t\t\tif (function_exists($this->_logcallback)) {\n    \t\t\tif (is_array($log)) $log = print_r($log,true);\n    \t\t\treturn call_user_func($this->_logcallback,$log);\n    \t\t\t}elseif (class_exists('Log')) {\n    \t\t\t\tLog::write('wechat：'.$log, Log::DEBUG);\n    \t\t\t}\n    \t\t}\n    \t\treturn false;\n    }\n\n\t/**\n\t * GET 请求\n\t * @param string $url\n\t */\n\tprivate function http_get($url){\n\t\t$oCurl = curl_init();\n\t\tif(stripos($url,\"https://\")!==FALSE){\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1\n\t\t}\n\t\tcurl_setopt($oCurl, CURLOPT_URL, $url);\n\t\tcurl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );\n\t\t$sContent = curl_exec($oCurl);\n\t\t$aStatus = curl_getinfo($oCurl);\n\t\tcurl_close($oCurl);\n\t\tif(intval($aStatus[\"http_code\"])==200){\n\t\t\treturn $sContent;\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * POST 请求\n\t * @param string $url\n\t * @param array $param\n\t * @param boolean $post_file 是否文件上传\n\t * @return string content\n\t */\n\tprivate function http_post($url,$param,$post_file=false){\n\t\t$oCurl = curl_init();\n\t\tif(stripos($url,\"https://\")!==FALSE){\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1\n\t\t}\n\t\tif (is_string($param) || $post_file) {\n\t\t\t$strPOST = $param;\n\t\t} else {\n\t\t\t$aPOST = array();\n\t\t\tforeach($param as $key=>$val){\n\t\t\t\t$aPOST[] = $key.\"=\".urlencode($val);\n\t\t\t}\n\t\t\t$strPOST =  join(\"&\", $aPOST);\n\t\t}\n\t\tcurl_setopt($oCurl, CURLOPT_URL, $url);\n\t\tcurl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );\n\t\tcurl_setopt($oCurl, CURLOPT_POST,true);\n\t\tcurl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);\n\t\t$sContent = curl_exec($oCurl);\n\t\t$aStatus = curl_getinfo($oCurl);\n\t\tcurl_close($oCurl);\n\t\tif(intval($aStatus[\"http_code\"])==200){\n\t\t\treturn $sContent;\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * 获取access_token\n\t * @param string $appid 如在类初始化时已提供，则可为空\n\t * @param string $appsecret 如在类初始化时已提供，则可为空\n\t * @param string $token 手动指定access_token，非必要情况不建议用\n\t */\n\tpublic function checkAuth($appid='',$appsecret='',$token=''){\n\t\tif (!$appid || !$appsecret) {\n\t\t\t$appid = $this->appid;\n\t\t\t$appsecret = $this->appsecret;\n\t\t}\n\t\t$authname = 'wechat_access_token'.$appid;\n\t\tif ($token) { //手动指定token，优先使用\n\t\t    $this->access_token=$token;\n\t\t    return $this->access_token;\n\t\t}\n\t\tif ($rs = S($authname))  {\n\t\t\t$this->access_token = $rs;\n\t\t\treturn $rs;\n\t\t}\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::AUTH_URL.'appid='.$appid.'&secret='.$appsecret);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || isset($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t$this->access_token = $json['access_token'];\n\t\t\t$expire = $json['expires_in'] ? intval($json['expires_in'])-100 : 3600;\n\t\t\tS($authname,$this->access_token,$expire);\n\t\t\treturn $this->access_token;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 删除验证数据\n\t * @param string $appid\n\t */\n\tpublic function resetAuth($appid=''){\n\t\tif (!$appid) $appid = $this->appid;\n\t\t$this->access_token = '';\n\t\t$authname = 'wechat_access_token'.$appid;\n\t\tS($authname,null);\n\t\treturn true;\n\t}\n\n\t/**\n\t * 微信api不支持中文转义的json结构\n\t * @param array $arr\n\t */\n\tstatic function json_encode($arr) {\n\t\t$parts = array ();\n\t\t$is_list = false;\n\t\t//Find out if the given array is a numerical array\n\t\t$keys = array_keys ( $arr );\n\t\t$max_length = count ( $arr ) - 1;\n\t\tif (($keys [0] === 0) && ($keys [$max_length] === $max_length )) { //See if the first key is 0 and last key is length - 1\n\t\t\t$is_list = true;\n\t\t\tfor($i = 0; $i < count ( $keys ); $i ++) { //See if each key correspondes to its position\n\t\t\t\tif ($i != $keys [$i]) { //A key fails at position check.\n\t\t\t\t\t$is_list = false; //It is an associative array.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tforeach ( $arr as $key => $value ) {\n\t\t\tif (is_array ( $value )) { //Custom handling for arrays\n\t\t\t\tif ($is_list)\n\t\t\t\t\t$parts [] = self::json_encode ( $value ); /* :RECURSION: */\n\t\t\t\telse\n\t\t\t\t\t$parts [] = '\"' . $key . '\":' . self::json_encode ( $value ); /* :RECURSION: */\n\t\t\t} else {\n\t\t\t\t$str = '';\n\t\t\t\tif (! $is_list)\n\t\t\t\t\t$str = '\"' . $key . '\":';\n\t\t\t\t//Custom handling for multiple data types\n\t\t\t\tif (!is_string ( $value ) && is_numeric ( $value ) && $value<2000000000)\n\t\t\t\t\t$str .= $value; //Numbers\n\t\t\t\telseif ($value === false)\n\t\t\t\t$str .= 'false'; //The booleans\n\t\t\t\telseif ($value === true)\n\t\t\t\t$str .= 'true';\n\t\t\t\telse\n\t\t\t\t\t$str .= '\"' . addslashes ( $value ) . '\"'; //All other things\n\t\t\t\t// :TODO: Is there any more datatype we should be in the lookout for? (Object?)\n\t\t\t\t$parts [] = $str;\n\t\t\t}\n\t\t}\n\t\t$json = implode ( ',', $parts );\n\t\tif ($is_list)\n\t\t\treturn '[' . $json . ']'; //Return numerical JSON\n\t\treturn '{' . $json . '}'; //Return associative JSON\n\t}\n\n\t/**\n\t * 获取签名\n\t * @param array $arrdata 签名数组\n\t * @param string $method 签名方法\n\t * @return boolean|string 签名值\n\t */\n\tpublic function getSignature($arrdata,$method=\"sha1\") {\n\t\tif (!function_exists($method)) return false;\n\t\tksort($arrdata);\n\t\t$paramstring = \"\";\n\t\tforeach($arrdata as $key => $value)\n\t\t{\n\t\t\tif(strlen($paramstring) == 0)\n\t\t\t\t$paramstring .= $key . \"=\" . $value;\n\t\t\telse\n\t\t\t\t$paramstring .= \"&\" . $key . \"=\" . $value;\n\t\t}\n\t\t$paySign = $method($paramstring);\n\t\treturn $paySign;\n\t}\n\n\t/**\n\t * 生成随机字串\n\t * @param number $length 长度，默认为16，最长为32字节\n\t * @return string\n\t */\n\tpublic function generateNonceStr($length=16){\n\t\t// 密码字符集，可任意添加你需要的字符\n\t\t$chars = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\n\t\t$str = \"\";\n\t\tfor($i = 0; $i < $length; $i++)\n\t\t{\n\t\t\t$str .= $chars[mt_rand(0, strlen($chars) - 1)];\n\t\t}\n\t\treturn $str;\n\t}\n\n\t/**\n\t * 生成原生支付url\n\t * @param number $productid 商品编号，最长为32字节\n\t * @return string\n\t */\n\tpublic function createNativeUrl($productid){\n\t\t    $nativeObj[\"appid\"] = $this->appid;\n\t\t    $nativeObj[\"appkey\"] = $this->paysignkey;\n\t\t    $nativeObj[\"productid\"] = urlencode($productid);\n\t\t    $nativeObj[\"timestamp\"] = time();\n\t\t    $nativeObj[\"noncestr\"] = $this->generateNonceStr();\n\t\t    $nativeObj[\"sign\"] = $this->getSignature($nativeObj);\n\t\t    unset($nativeObj[\"appkey\"]);\n\t\t    $bizString = \"\";\n\t\t    foreach($nativeObj as $key => $value)\n\t\t    {\n\t\t\tif(strlen($bizString) == 0)\n\t\t\t\t$bizString .= $key . \"=\" . $value;\n\t\t\telse\n\t\t\t\t$bizString .= \"&\" . $key . \"=\" . $value;\n\t\t    }\n\t\t    return \"weixin://wxpay/bizpayurl?\".$bizString;\n\t\t    //weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXXX&productid=XXXXXX&timestamp=XXXXXX&noncestr=XXXXXX\n\t}\n\n\n\t/**\n\t * 生成订单package字符串\n\t * @param string $out_trade_no 必填，商户系统内部的订单号,32个字符内,确保在商户系统唯一\n\t * @param string $body 必填，商品描述,128 字节以下\n\t * @param int $total_fee 必填，订单总金额,单位为分\n\t * @param string $notify_url 必填，支付完成通知回调接口，255 字节以内\n\t * @param string $spbill_create_ip 必填，用户终端IP，IPV4字串，15字节内\n\t * @param int $fee_type 必填，现金支付币种，默认1:人民币\n\t * @param string $bank_type 必填，银行通道类型,默认WX\n\t * @param string $input_charset 必填，传入参数字符编码，默认UTF-8，取值有UTF-8和GBK\n\t * @param string $time_start 交易起始时间,订单生成时间,格式yyyyMMddHHmmss\n\t * @param string $time_expire 交易结束时间,也是订单失效时间\n\t * @param int $transport_fee 物流费用,单位为分\n\t * @param int $product_fee 商品费用,单位为分,必须保证 transport_fee + product_fee=total_fee\n\t * @param string $goods_tag 商品标记,优惠券时可能用到\n\t * @param string $attach 附加数据，notify接口原样返回\n\t * @return string\n\t */\n\tpublic function createPackage($out_trade_no,$body,$total_fee,$notify_url,$spbill_create_ip,$fee_type=1,$bank_type=\"WX\",$input_charset=\"UTF-8\",$time_start=\"\",$time_expire=\"\",$transport_fee=\"\",$product_fee=\"\",$goods_tag=\"\",$attach=\"\"){\n\t\t\t$arrdata = array(\"bank_type\" => $bank_type, \"body\" => $body, \"partner\" => $this->partnerid, \"out_trade_no\" => $out_trade_no, \"total_fee\" => $total_fee, \"fee_type\" => $fee_type, \"notify_url\" => $notify_url, \"spbill_create_ip\" => $spbill_create_ip, \"input_charset\" => $input_charset);\n\t\t\tif ($time_start)  $arrdata['time_start'] = $time_start;\n\t\t\tif ($time_expire)  $arrdata['time_expire'] = $time_expire;\n\t\t\tif ($transport_fee)  $arrdata['transport_fee'] = $transport_fee;\n\t\t\tif ($product_fee)  $arrdata['product_fee'] = $product_fee;\n\t\t\tif ($goods_tag)  $arrdata['goods_tag'] = $goods_tag;\n\t\t\tif ($attach)  $arrdata['attach'] = $attach;\n\t\t\tksort($arrdata);\n\t\t\t$paramstring = \"\";\n\t\t\tforeach($arrdata as $key => $value)\n\t\t\t{\n\t\t\tif(strlen($paramstring) == 0)\n\t\t\t\t$paramstring .= $key . \"=\" . $value;\n\t\t\t\telse\n\t\t\t\t$paramstring .= \"&\" . $key . \"=\" . $value;\n\t\t\t}\n\t\t\t$stringSignTemp = $paramstring . \"&key=\" . $this->partnerkey;\n\t\t\t$signValue = strtoupper(md5($stringSignTemp));\n\t\t\t$package = http_build_query($arrdata) . \"&sign=\" . $signValue;\n\t\t\treturn $package;\n\t}\n\n\t/**\n\t * 支付签名(paySign)生成方法\n\t * @param string $package 订单详情字串\n\t * @param string $timeStamp 当前时间戳（需与JS输出的一致）\n\t * @param string $nonceStr 随机串（需与JS输出的一致）\n\t * @return string 返回签名字串\n\t */\n\tpublic function getPaySign($package, $timeStamp, $nonceStr){\n\t\t$arrdata = array(\"appid\" => $this->appid, \"timestamp\" => $timeStamp, \"noncestr\" => $nonceStr, \"package\" => $package, \"appkey\" => $this->paysignkey);\n\t\t$paySign = $this->getSignature($arrdata);\n\t\treturn $paySign;\n\t}\n\n\t/**\n\t * 回调通知签名验证\n\t * @param array $orderxml 返回的orderXml的数组表示，留空则自动从post数据获取\n\t * @return boolean\n\t */\n\tpublic function checkOrderSignature($orderxml=''){\n\t\tif (!$orderxml) {\n\t\t\t$postStr = file_get_contents(\"php://input\");\n\t\t\tif (!empty($postStr)) {\n\t\t\t\t$orderxml = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);\n\t\t\t} else return false;\n\t\t}\n\t\t$arrdata = array('appid'=>$orderxml['AppId'],'appkey'=>$this->paysignkey,'timestamp'=>$orderxml['TimeStamp'],'noncestr'=>$orderxml['NonceStr'],'openid'=>$orderxml['OpenId'],'issubscribe'=>$orderxml['IsSubscribe']);\n\t\t$paySign = $this->getSignature($arrdata);\n\t\tif ($paySign!=$orderxml['AppSignature']) return false;\n\t\treturn true;\n\t}\n\n\t/**\n\t * 发货通知\n\t * @param string $openid 用户open_id\n\t * @param string $transid 交易单号\n\t * @param string $out_trade_no 第三方订单号\n\t * @param int $status 0:发货失败；1:已发货\n\t * @param string $msg 失败原因\n\t * @return boolean|array\n\t */\n\tpublic function sendPayDeliverNotify($openid,$transid,$out_trade_no,$status=1,$msg='ok'){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$postdata = array(\n\t\t\t\t\"appid\"=>$this->appid,\n\t\t\t\t\"appkey\"=>$this->paysignkey,\n\t\t\t\t\"openid\"=>$openid,\n\t\t\t\t\"transid\"=>strval($transid),\n\t\t\t\t\"out_trade_no\"=>strval($out_trade_no),\n\t\t\t\t\"deliver_timestamp\"=>strval(time()),\n\t\t\t\t\"deliver_status\"=>strval($status),\n\t\t\t\t\"deliver_msg\"=>$msg,\n\t\t);\n\t\t$postdata['app_signature'] = $this->getSignature($postdata);\n\t\t$postdata['sign_method'] = 'sha1';\n\t\tunset($postdata['appkey']);\n\t\t$result = $this->http_post(self::API_BASE_URL_PREFIX.self::PAY_DELIVERNOTIFY.'access_token='.$this->access_token,self::json_encode($postdata));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 查询订单信息\n\t * @param string $out_trade_no 订单号\n\t * @return boolean|array\n\t */\n\tpublic function getPayOrder($out_trade_no) {\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$sign = strtoupper(md5(\"out_trade_no=$out_trade_no&partner={$this->partnerid}&key={$this->partnerkey}\"));\n\t\t$postdata = array(\n\t\t\t\t\"appid\"=>$this->appid,\n\t\t\t\t\"appkey\"=>$this->paysignkey,\n\t\t\t\t\"package\"=>\"out_trade_no=$out_trade_no&partner={$this->partnerid}&sign=$sign\",\n\t\t\t\t\"timestamp\"=>strval(time()),\n\t\t);\n\t\t$postdata['app_signature'] = $this->getSignature($postdata);\n\t\t$postdata['sign_method'] = 'sha1';\n\t\tunset($postdata['appkey']);\n\t\t$result = $this->http_post(self::API_BASE_URL_PREFIX.self::PAY_ORDERQUERY.'access_token='.$this->access_token,self::json_encode($postdata));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'].json_encode($postdata);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json[\"order_info\"];\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 设置用户授权密钥\n\t * @param string $user_token\n\t * @return string\n\t */\n\tpublic function setUserToken($user_token) {\n\t\treturn $this->user_token = $user_token;\n\t}\n\n\t/**\n\t * 获取收货地址JS的签名\n\t * @tutorial 参考weixin.js脚本的WeixinJS.editAddress方法调用\n\t * @param string $appId\n\t * @param string $url\n\t * @param int $timeStamp\n\t * @param string $nonceStr\n\t * @param string $user_token\n\t * @return Ambigous <boolean, string>\n\t */\n\tpublic function getAddrSign($url, $timeStamp, $nonceStr, $user_token=''){\n\t\tif (!$user_token) $user_token = $this->user_token;\n\t\tif (!$user_token) {\n\t\t\t$this->errMsg = 'no user access token found!';\n\t\t\treturn false;\n\t\t}\n\t\t$url = htmlspecialchars_decode($url);\n\t\t$arrdata = array(\n\t\t\t\t'appid'=>$this->appid,\n\t\t\t\t'url'=>$url,\n\t\t\t\t'timestamp'=>strval($timeStamp),\n\t\t\t\t'noncestr'=>$nonceStr,\n\t\t\t\t'accesstoken'=>$user_token\n\t\t);\n\t\treturn $this->getSignature($arrdata);\n\t}\n}\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/old_version/snoopy.class.php",
    "content": "<?php\n/*************************************************\n\nSnoopy - the PHP net client\nAuthor: Monte Ohrt <monte@ispi.net>\nCopyright (c): 1999-2008 New Digital Group, all rights reserved\nVersion: 1.2.4\n\n* This library is free software; you can redistribute it and/or\n* modify it under the terms of the GNU Lesser General Public\n* License as published by the Free Software Foundation; either\n* version 2.1 of the License, or (at your option) any later version.\n*\n* This library is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n* Lesser General Public License for more details.\n*\n* You should have received a copy of the GNU Lesser General Public\n* License along with this library; if not, write to the Free Software\n* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\nYou may contact the author of Snoopy by e-mail at:\nmonte@ohrt.com\n\nThe latest version of Snoopy can be obtained from:\nhttp://snoopy.sourceforge.net/\n\n*************************************************/\n\nclass Snoopy\n{\n\t/**** Public variables ****/\n\n\t/* user definable vars */\n\n\tvar $host\t\t\t=\t\"www.php.net\";\t\t// host name we are connecting to\n\tvar $port\t\t\t=\t80;\t\t\t\t\t// port we are connecting to\n\tvar $proxy_host\t\t=\t\"\";\t\t\t\t\t// proxy host to use\n\tvar $proxy_port\t\t=\t\"\";\t\t\t\t\t// proxy port to use\n\tvar $proxy_user\t\t=\t\"\";\t\t\t\t\t// proxy user to use\n\tvar $proxy_pass\t\t=\t\"\";\t\t\t\t\t// proxy password to use\n\n\tvar $agent\t\t\t=\t\"Mozilla/5.0\";\t// agent we masquerade as\n\tvar\t$referer\t\t=\t\"\";\t\t\t\t\t// referer info to pass\n\tvar $cookies\t\t=\tarray();\t\t\t// array of cookies to pass\n\t// $cookies[\"username\"]=\"joe\";\n\tvar\t$rawheaders\t\t=\tarray();\t\t\t// array of raw headers to send\n\t// $rawheaders[\"Content-type\"]=\"text/html\";\n\n\tvar $maxredirs\t\t=\t5;\t\t\t\t\t// http redirection depth maximum. 0 = disallow\n\tvar $lastredirectaddr\t=\t\"\";\t\t\t\t// contains address of last redirected address\n\tvar\t$offsiteok\t\t=\ttrue;\t\t\t\t// allows redirection off-site\n\tvar $maxframes\t\t=\t0;\t\t\t\t\t// frame content depth maximum. 0 = disallow\n\tvar $expandlinks\t=\ttrue;\t\t\t\t// expand links to fully qualified URLs.\n\t// this only applies to fetchlinks()\n\t// submitlinks(), and submittext()\n\tvar $passcookies\t=\ttrue;\t\t\t\t// pass set cookies back through redirects\n\t// NOTE: this currently does not respect\n\t// dates, domains or paths.\n\n\tvar\t$user\t\t\t=\t\"\";\t\t\t\t\t// user for http authentication\n\tvar\t$pass\t\t\t=\t\"\";\t\t\t\t\t// password for http authentication\n\n\t// http accept types\n\tvar $accept\t\t\t=\t\"application/json, text/javascript, */*; q=0.01\";\n\n\tvar $results\t\t=\t\"\";\t\t\t\t\t// where the content is put\n\n\tvar $error\t\t\t=\t\"\";\t\t\t\t\t// error messages sent here\n\tvar\t$response_code\t=\t\"\";\t\t\t\t\t// response code returned from server\n\tvar\t$headers\t\t=\tarray();\t\t\t// headers returned from server sent here\n\tvar\t$maxlength\t\t=\t500000;\t\t\t\t// max return data length (body)\n\tvar $read_timeout\t=\t0;\t\t\t\t\t// timeout on read operations, in seconds\n\t// supported only since PHP 4 Beta 4\n\t// set to 0 to disallow timeouts\n\tvar $timed_out\t\t=\tfalse;\t\t\t\t// if a read operation timed out\n\tvar\t$status\t\t\t=\t0;\t\t\t\t\t// http request status\n\n\tvar $temp_dir\t\t=\t\"/tmp\";\t\t\t\t// temporary directory that the webserver\n\t// has permission to write to.\n\t// under Windows, this should be C:\\temp\n\n\tvar\t$curl_path\t\t=\t\"/usr/local/bin/curl\";\n\t// Snoopy will use cURL for fetching\n\t// SSL content if a full system path to\n\t// the cURL binary is supplied here.\n\t// set to false if you do not have\n\t// cURL installed. See http://curl.haxx.se\n\t// for details on installing cURL.\n\t// Snoopy does *not* use the cURL\n\t// library functions built into php,\n\t// as these functions are not stable\n\t// as of this Snoopy release.\n\n\t/**** Private variables ****/\n\n\tvar\t$_maxlinelen\t=\t4096;\t\t\t\t// max line length (headers)\n\n\tvar $_httpmethod\t=\t\"GET\";\t\t\t\t// default http request method\n\tvar $_httpversion\t=\t\"HTTP/1.0\";\t\t\t// default http request version\n\tvar $_submit_method\t=\t\"POST\";\t\t\t\t// default submit method\n\tvar $_submit_type\t=\t\"application/x-www-form-urlencoded\";\t// default submit type\n\tvar $_mime_boundary\t=   \"\";\t\t\t\t\t// MIME boundary for multipart/form-data submit type\n\tvar $_redirectaddr\t=\tfalse;\t\t\t\t// will be set if page fetched is a redirect\n\tvar $_redirectdepth\t=\t0;\t\t\t\t\t// increments on an http redirect\n\tvar $_frameurls\t\t= \tarray();\t\t\t// frame src urls\n\tvar $_framedepth\t=\t0;\t\t\t\t\t// increments on frame depth\n\n\tvar $_isproxy\t\t=\tfalse;\t\t\t\t// set if using a proxy server\n\tvar $_fp_timeout\t=\t30;\t\t\t\t\t// timeout for socket connection\n\n\t/*======================================================================*\\\n\t Function:\tfetch\n\tPurpose:\tfetch the contents of a web page\n\t(and possibly other protocols in the\n\t\t\tfuture like ftp, nntp, gopher, etc.)\n\tInput:\t\t$URI\tthe location of the page to fetch\n\tOutput:\t\t$this->results\tthe output text from the fetch\n\t\\*======================================================================*/\n\n\tfunction fetch($URI)\n\t{\n\n\t\t//preg_match(\"|^([^:]+)://([^:/]+)(:[\\d]+)*(.*)|\",$URI,$URI_PARTS);\n\t\t$URI_PARTS = parse_url($URI);\n\t\tif (!empty($URI_PARTS[\"user\"]))\n\t\t\t$this->user = $URI_PARTS[\"user\"];\n\t\tif (!empty($URI_PARTS[\"pass\"]))\n\t\t\t$this->pass = $URI_PARTS[\"pass\"];\n\t\tif (empty($URI_PARTS[\"query\"]))\n\t\t\t$URI_PARTS[\"query\"] = '';\n\t\tif (empty($URI_PARTS[\"path\"]))\n\t\t\t$URI_PARTS[\"path\"] = '';\n\n\t\tswitch(strtolower($URI_PARTS[\"scheme\"]))\n\t\t{\n\t\t\tcase \"http\":\n\t\t\t\t$this->host = $URI_PARTS[\"host\"];\n\t\t\t\tif(!empty($URI_PARTS[\"port\"]))\n\t\t\t\t\t$this->port = $URI_PARTS[\"port\"];\n\t\t\t\tif($this->_connect($fp))\n\t\t\t\t{\n\t\t\t\t\tif($this->_isproxy)\n\t\t\t\t\t{\n\t\t\t\t\t\t// using proxy, send entire URI\n\t\t\t\t\t\t$this->_httprequest($URI,$fp,$URI,$this->_httpmethod);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t$path = $URI_PARTS[\"path\"].($URI_PARTS[\"query\"] ? \"?\".$URI_PARTS[\"query\"] : \"\");\n\t\t\t\t\t\t// no proxy, send only the path\n\t\t\t\t\t\t$this->_httprequest($path, $fp, $URI, $this->_httpmethod);\n\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t$this->_disconnect($fp);\n\n\t\t\t\t\tif($this->_redirectaddr)\n\t\t\t\t\t{\n\t\t\t\t\t\t/* url was redirected, check if we've hit the max depth */\n\t\t\t\t\t\tif($this->maxredirs > $this->_redirectdepth)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t// only follow redirect if it's on this site, or offsiteok is true\n\t\t\t\t\t\t\tif(preg_match(\"|^http://\".preg_quote($this->host).\"|i\",$this->_redirectaddr) || $this->offsiteok)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t/* follow the redirect */\n\t\t\t\t\t\t\t\t$this->_redirectdepth++;\n\t\t\t\t\t\t\t\t$this->lastredirectaddr=$this->_redirectaddr;\n\t\t\t\t\t\t\t\t$this->fetch($this->_redirectaddr);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t$frameurls = $this->_frameurls;\n\t\t\t\t\t\t$this->_frameurls = array();\n\n\t\t\t\t\t\twhile(list(,$frameurl) = each($frameurls))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif($this->_framedepth < $this->maxframes)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$this->fetch($frameurl);\n\t\t\t\t\t\t\t\t$this->_framedepth++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t\tbreak;\n\t\t\tcase \"https\":\n\t\t\t\tif (!function_exists('curl_init')) {\n\t\t\t\t\tif(!$this->curl_path)\n\t\t\t\t\t\treturn false;\n\t\t\t\t\tif(function_exists(\"is_executable\"))\n\t\t\t\t\t\tif (!is_executable($this->curl_path))\n\t\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t$this->host = $URI_PARTS[\"host\"];\n\t\t\t\tif(!empty($URI_PARTS[\"port\"]))\n\t\t\t\t\t$this->port = $URI_PARTS[\"port\"];\n\t\t\t\tif($this->_isproxy)\n\t\t\t\t{\n\t\t\t\t\t// using proxy, send entire URI\n\t\t\t\t\t$this->_httpsrequest($URI,$URI,$this->_httpmethod);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t$path = $URI_PARTS[\"path\"].($URI_PARTS[\"query\"] ? \"?\".$URI_PARTS[\"query\"] : \"\");\n\t\t\t\t\t// no proxy, send only the path\n\t\t\t\t\t$this->_httpsrequest($path, $URI, $this->_httpmethod);\n\t\t\t\t}\n\n\t\t\t\tif($this->_redirectaddr)\n\t\t\t\t{\n\t\t\t\t\t/* url was redirected, check if we've hit the max depth */\n\t\t\t\t\tif($this->maxredirs > $this->_redirectdepth)\n\t\t\t\t\t{\n\t\t\t\t\t\t// only follow redirect if it's on this site, or offsiteok is true\n\t\t\t\t\t\tif(preg_match(\"|^https://\".preg_quote($this->host).\"|i\",$this->_redirectaddr) || $this->offsiteok)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/* follow the redirect */\n\t\t\t\t\t\t\t$this->_redirectdepth++;\n\t\t\t\t\t\t\t$this->lastredirectaddr=$this->_redirectaddr;\n\t\t\t\t\t\t\t$this->fetch($this->_redirectaddr);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)\n\t\t\t\t{\n\t\t\t\t\t$frameurls = $this->_frameurls;\n\t\t\t\t\t$this->_frameurls = array();\n\n\t\t\t\t\twhile(list(,$frameurl) = each($frameurls))\n\t\t\t\t\t{\n\t\t\t\t\t\tif($this->_framedepth < $this->maxframes)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$this->fetch($frameurl);\n\t\t\t\t\t\t\t$this->_framedepth++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// not a valid protocol\n\t\t\t\t$this->error\t=\t'Invalid protocol \"'.$URI_PARTS[\"scheme\"].'\"\\n';\n\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\tsubmit\n\tPurpose:\tsubmit an http form\n\tInput:\t\t$URI\tthe location to post the data\n\t$formvars\tthe formvars to use.\n\tformat: $formvars[\"var\"] = \"val\";\n\t$formfiles  an array of files to submit\n\tformat: $formfiles[\"var\"] = \"/dir/filename.ext\";\n\tOutput:\t\t$this->results\tthe text output from the post\n\t\\*======================================================================*/\n\n\tfunction submit($URI, $formvars=\"\", $formfiles=\"\")\n\t{\n\t\tunset($postdata);\n\n\t\t$postdata = $this->_prepare_post_body($formvars, $formfiles);\n\t\t$URI_PARTS = parse_url($URI);\n\t\tif (!empty($URI_PARTS[\"user\"]))\n\t\t\t$this->user = $URI_PARTS[\"user\"];\n\t\tif (!empty($URI_PARTS[\"pass\"]))\n\t\t\t$this->pass = $URI_PARTS[\"pass\"];\n\t\tif (empty($URI_PARTS[\"query\"]))\n\t\t\t$URI_PARTS[\"query\"] = '';\n\t\tif (empty($URI_PARTS[\"path\"]))\n\t\t\t$URI_PARTS[\"path\"] = '';\n\n\t\tswitch(strtolower($URI_PARTS[\"scheme\"]))\n\t\t{\n\t\t\tcase \"http\":\n\t\t\t\t$this->host = $URI_PARTS[\"host\"];\n\t\t\t\tif(!empty($URI_PARTS[\"port\"]))\n\t\t\t\t\t$this->port = $URI_PARTS[\"port\"];\n\t\t\t\tif($this->_connect($fp))\n\t\t\t\t{\n\t\t\t\t\tif($this->_isproxy)\n\t\t\t\t\t{\n\t\t\t\t\t\t// using proxy, send entire URI\n\t\t\t\t\t\t$this->_httprequest($URI,$fp,$URI,$this->_submit_method,$this->_submit_type,$postdata);\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t{\n\t\t\t\t\t\t$path = $URI_PARTS[\"path\"].($URI_PARTS[\"query\"] ? \"?\".$URI_PARTS[\"query\"] : \"\");\n\t\t\t\t\t\t// no proxy, send only the path\n\t\t\t\t\t\t$this->_httprequest($path, $fp, $URI, $this->_submit_method, $this->_submit_type, $postdata);\n\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t\t$this->_disconnect($fp);\n\n\t\t\t\t\tif($this->_redirectaddr)\n\t\t\t\t\t{\n\t\t\t\t\t\t/* url was redirected, check if we've hit the max depth */\n\t\t\t\t\t\tif($this->maxredirs > $this->_redirectdepth)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif(!preg_match(\"|^\".$URI_PARTS[\"scheme\"].\"://|\", $this->_redirectaddr))\n\t\t\t\t\t\t\t\t$this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS[\"scheme\"].\"://\".$URI_PARTS[\"host\"]);\n\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t// only follow redirect if it's on this site, or offsiteok is true\n\t\t\t\t\t\t\tif(preg_match(\"|^http://\".preg_quote($this->host).\"|i\",$this->_redirectaddr) || $this->offsiteok)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t/* follow the redirect */\n\t\t\t\t\t\t\t\t$this->_redirectdepth++;\n\t\t\t\t\t\t\t\t$this->lastredirectaddr=$this->_redirectaddr;\n\t\t\t\t\t\t\t\tif( strpos( $this->_redirectaddr, \"?\" ) > 0 )\n\t\t\t\t\t\t\t\t\t$this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get\n\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t$this->submit($this->_redirectaddr,$formvars, $formfiles);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)\n\t\t\t\t\t{\n\t\t\t\t\t\t$frameurls = $this->_frameurls;\n\t\t\t\t\t\t$this->_frameurls = array();\n\n\t\t\t\t\t\twhile(list(,$frameurl) = each($frameurls))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tif($this->_framedepth < $this->maxframes)\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$this->fetch($frameurl);\n\t\t\t\t\t\t\t\t$this->_framedepth++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t\t\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t\tbreak;\n\t\t\tcase \"https\":\n\t\t\t\tif (!function_exists('curl_init')) {\n\t\t\t\tif(!$this->curl_path)\n\t\t\t\t\treturn false;\n\t\t\t\tif(function_exists(\"is_executable\"))\n\t\t\t\t\tif (!is_executable($this->curl_path))\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t$this->host = $URI_PARTS[\"host\"];\n\t\t\t\tif(!empty($URI_PARTS[\"port\"]))\n\t\t\t\t\t$this->port = $URI_PARTS[\"port\"];\n\t\t\t\tif($this->_isproxy)\n\t\t\t\t{\n\t\t\t\t\t// using proxy, send entire URI\n\t\t\t\t\t$this->_httpsrequest($URI, $URI, $this->_submit_method, $this->_submit_type, $postdata);\n\t\t\t\t}\n\t\t\t\telse\n\t\t\t\t{\n\t\t\t\t\t$path = $URI_PARTS[\"path\"].($URI_PARTS[\"query\"] ? \"?\".$URI_PARTS[\"query\"] : \"\");\n\t\t\t\t\t// no proxy, send only the path\n\t\t\t\t\t$this->_httpsrequest($path, $URI, $this->_submit_method, $this->_submit_type, $postdata);\n\t\t\t\t}\n\n\t\t\t\tif($this->_redirectaddr)\n\t\t\t\t{\n\t\t\t\t\t/* url was redirected, check if we've hit the max depth */\n\t\t\t\t\tif($this->maxredirs > $this->_redirectdepth)\n\t\t\t\t\t{\n\t\t\t\t\t\tif(!preg_match(\"|^\".$URI_PARTS[\"scheme\"].\"://|\", $this->_redirectaddr))\n\t\t\t\t\t\t\t$this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS[\"scheme\"].\"://\".$URI_PARTS[\"host\"]);\n\n\t\t\t\t\t\t// only follow redirect if it's on this site, or offsiteok is true\n\t\t\t\t\t\tif(preg_match(\"|^https://\".preg_quote($this->host).\"|i\",$this->_redirectaddr) || $this->offsiteok)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t/* follow the redirect */\n\t\t\t\t\t\t\t$this->_redirectdepth++;\n\t\t\t\t\t\t\t$this->lastredirectaddr=$this->_redirectaddr;\n\t\t\t\t\t\t\tif( strpos( $this->_redirectaddr, \"?\" ) > 0 )\n\t\t\t\t\t\t\t\t$this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get\n\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t$this->submit($this->_redirectaddr,$formvars, $formfiles);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif($this->_framedepth < $this->maxframes && count($this->_frameurls) > 0)\n\t\t\t\t{\n\t\t\t\t\t$frameurls = $this->_frameurls;\n\t\t\t\t\t$this->_frameurls = array();\n\n\t\t\t\t\twhile(list(,$frameurl) = each($frameurls))\n\t\t\t\t\t{\n\t\t\t\t\t\tif($this->_framedepth < $this->maxframes)\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$this->fetch($frameurl);\n\t\t\t\t\t\t\t$this->_framedepth++;\n\t\t\t\t\t\t}\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn true;\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// not a valid protocol\n\t\t\t\t$this->error\t=\t'Invalid protocol \"'.$URI_PARTS[\"scheme\"].'\"\\n';\n\t\t\t\treturn false;\n\t\t\t\tbreak;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\tfetchlinks\n\tPurpose:\tfetch the links from a web page\n\tInput:\t\t$URI\twhere you are fetching from\n\tOutput:\t\t$this->results\tan array of the URLs\n\t\\*======================================================================*/\n\n\tfunction fetchlinks($URI)\n\t{\n\t\tif ($this->fetch($URI))\n\t\t{\n\t\t\tif($this->lastredirectaddr)\n\t\t\t\t$URI = $this->lastredirectaddr;\n\t\t\tif(is_array($this->results))\n\t\t\t{\n\t\t\t\tfor($x=0;$x<count($this->results);$x++)\n\t\t\t\t\t$this->results[$x] = $this->_striplinks($this->results[$x]);\n\t\t\t}\n\t\t\telse\n\t\t\t\t$this->results = $this->_striplinks($this->results);\n\n\t\t\tif($this->expandlinks)\n\t\t\t\t$this->results = $this->_expandlinks($this->results, $URI);\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\tfetchform\n\tPurpose:\tfetch the form elements from a web page\n\tInput:\t\t$URI\twhere you are fetching from\n\tOutput:\t\t$this->results\tthe resulting html form\n\t\\*======================================================================*/\n\n\tfunction fetchform($URI)\n\t{\n\n\t\tif ($this->fetch($URI))\n\t\t{\n\n\t\t\tif(is_array($this->results))\n\t\t\t{\n\t\t\t\tfor($x=0;$x<count($this->results);$x++)\n\t\t\t\t\t$this->results[$x] = $this->_stripform($this->results[$x]);\n\t\t\t}\n\t\t\telse\n\t\t\t\t$this->results = $this->_stripform($this->results);\n\t\t\t\t\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\n\t/*======================================================================*\\\n\t Function:\tfetchtext\n\tPurpose:\tfetch the text from a web page, stripping the links\n\tInput:\t\t$URI\twhere you are fetching from\n\tOutput:\t\t$this->results\tthe text from the web page\n\t\\*======================================================================*/\n\n\tfunction fetchtext($URI)\n\t{\n\t\tif($this->fetch($URI))\n\t\t{\n\t\t\tif(is_array($this->results))\n\t\t\t{\n\t\t\t\tfor($x=0;$x<count($this->results);$x++)\n\t\t\t\t\t$this->results[$x] = $this->_striptext($this->results[$x]);\n\t\t\t}\n\t\t\telse\n\t\t\t\t$this->results = $this->_striptext($this->results);\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\tsubmitlinks\n\tPurpose:\tgrab links from a form submission\n\tInput:\t\t$URI\twhere you are submitting from\n\tOutput:\t\t$this->results\tan array of the links from the post\n\t\\*======================================================================*/\n\n\tfunction submitlinks($URI, $formvars=\"\", $formfiles=\"\")\n\t{\n\t\tif($this->submit($URI,$formvars, $formfiles))\n\t\t{\n\t\t\tif($this->lastredirectaddr)\n\t\t\t\t$URI = $this->lastredirectaddr;\n\t\t\tif(is_array($this->results))\n\t\t\t{\n\t\t\t\tfor($x=0;$x<count($this->results);$x++)\n\t\t\t\t{\n\t\t\t\t\t$this->results[$x] = $this->_striplinks($this->results[$x]);\n\t\t\t\t\tif($this->expandlinks)\n\t\t\t\t\t\t$this->results[$x] = $this->_expandlinks($this->results[$x],$URI);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$this->results = $this->_striplinks($this->results);\n\t\t\t\tif($this->expandlinks)\n\t\t\t\t\t$this->results = $this->_expandlinks($this->results,$URI);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\tsubmittext\n\tPurpose:\tgrab text from a form submission\n\tInput:\t\t$URI\twhere you are submitting from\n\tOutput:\t\t$this->results\tthe text from the web page\n\t\\*======================================================================*/\n\n\tfunction submittext($URI, $formvars = \"\", $formfiles = \"\")\n\t{\n\t\tif($this->submit($URI,$formvars, $formfiles))\n\t\t{\n\t\t\tif($this->lastredirectaddr)\n\t\t\t\t$URI = $this->lastredirectaddr;\n\t\t\tif(is_array($this->results))\n\t\t\t{\n\t\t\t\tfor($x=0;$x<count($this->results);$x++)\n\t\t\t\t{\n\t\t\t\t\t$this->results[$x] = $this->_striptext($this->results[$x]);\n\t\t\t\t\tif($this->expandlinks)\n\t\t\t\t\t\t$this->results[$x] = $this->_expandlinks($this->results[$x],$URI);\n\t\t\t\t}\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\t$this->results = $this->_striptext($this->results);\n\t\t\t\tif($this->expandlinks)\n\t\t\t\t\t$this->results = $this->_expandlinks($this->results,$URI);\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t\treturn false;\n\t}\n\n\n\n\t/*======================================================================*\\\n\t Function:\tset_submit_multipart\n\tPurpose:\tSet the form submission content type to\n\tmultipart/form-data\n\t\\*======================================================================*/\n\tfunction set_submit_multipart()\n\t{\n\t\t$this->_submit_type = \"multipart/form-data\";\n\t}\n\n\n\t/*======================================================================*\\\n\t Function:\tset_submit_normal\n\tPurpose:\tSet the form submission content type to\n\tapplication/x-www-form-urlencoded\n\t\\*======================================================================*/\n\tfunction set_submit_normal()\n\t{\n\t\t$this->_submit_type = \"application/x-www-form-urlencoded\";\n\t}\n\n\n\n\n\t/*======================================================================*\\\n\t Private functions\n\t\\*======================================================================*/\n\n\n\t/*======================================================================*\\\n\t Function:\t_striplinks\n\tPurpose:\tstrip the hyperlinks from an html document\n\tInput:\t\t$document\tdocument to strip.\n\tOutput:\t\t$match\t\tan array of the links\n\t\\*======================================================================*/\n\n\tfunction _striplinks($document)\n\t{\n\t\tpreg_match_all(\"'<\\s*a\\s.*?href\\s*=\\s*\t\t\t# find <a href=\n\t\t\t\t\t\t([\\\"\\'])?\t\t\t\t\t# find single or double quote\n\t\t\t\t\t\t(?(1) (.*?)\\\\1 | ([^\\s\\>]+))\t\t# if quote found, match up to next matching\n\t\t\t\t\t\t\t\t\t\t\t\t\t# quote, otherwise match up to next space\n\t\t\t\t\t\t'isx\",$document,$links);\n\n\n\t\t// catenate the non-empty matches from the conditional subpattern\n\n\t\twhile(list($key,$val) = each($links[2]))\n\t\t{\n\t\t\tif(!empty($val))\n\t\t\t\t$match[] = $val;\n\t\t}\n\n\t\twhile(list($key,$val) = each($links[3]))\n\t\t{\n\t\t\tif(!empty($val))\n\t\t\t\t$match[] = $val;\n\t\t}\n\n\t\t// return the links\n\t\treturn $match;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\t_stripform\n\tPurpose:\tstrip the form elements from an html document\n\tInput:\t\t$document\tdocument to strip.\n\tOutput:\t\t$match\t\tan array of the links\n\t\\*======================================================================*/\n\n\tfunction _stripform($document)\n\t{\n\t\tpreg_match_all(\"'<\\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\\/?(option|select)[^<>]*>[\\r\\n]*)|(?=[\\r\\n]*))|(?=[\\r\\n]*))'Usi\",$document,$elements);\n\n\t\t// catenate the matches\n\t\t$match = implode(\"\\r\\n\",$elements[0]);\n\n\t\t// return the links\n\t\treturn $match;\n\t}\n\n\n\n\t/*======================================================================*\\\n\t Function:\t_striptext\n\tPurpose:\tstrip the text from an html document\n\tInput:\t\t$document\tdocument to strip.\n\tOutput:\t\t$text\t\tthe resulting text\n\t\\*======================================================================*/\n\n\tfunction _striptext($document)\n\t{\n\n\t\t// I didn't use preg eval (//e) since that is only available in PHP 4.0.\n\t\t// so, list your entities one by one here. I included some of the\n\t\t// more common ones.\n\n\t\t$search = array(\"'<script[^>]*?>.*?</script>'si\",\t// strip out javascript\n\t\t\t\t\"'<[\\/\\!]*?[^<>]*?>'si\",\t\t\t// strip out html tags\n\t\t\t\t\"'([\\r\\n])[\\s]+'\",\t\t\t\t\t// strip out white space\n\t\t\t\t\"'&(quot|#34|#034|#x22);'i\",\t\t// replace html entities\n\t\t\t\t\"'&(amp|#38|#038|#x26);'i\",\t\t\t// added hexadecimal values\n\t\t\t\t\"'&(lt|#60|#060|#x3c);'i\",\n\t\t\t\t\"'&(gt|#62|#062|#x3e);'i\",\n\t\t\t\t\"'&(nbsp|#160|#xa0);'i\",\n\t\t\t\t\"'&(iexcl|#161);'i\",\n\t\t\t\t\"'&(cent|#162);'i\",\n\t\t\t\t\"'&(pound|#163);'i\",\n\t\t\t\t\"'&(copy|#169);'i\",\n\t\t\t\t\"'&(reg|#174);'i\",\n\t\t\t\t\"'&(deg|#176);'i\",\n\t\t\t\t\"'&(#39|#039|#x27);'\",\n\t\t\t\t\"'&(euro|#8364);'i\",\t\t\t\t// europe\n\t\t\t\t\"'&a(uml|UML);'\",\t\t\t\t\t// german\n\t\t\t\t\"'&o(uml|UML);'\",\n\t\t\t\t\"'&u(uml|UML);'\",\n\t\t\t\t\"'&A(uml|UML);'\",\n\t\t\t\t\"'&O(uml|UML);'\",\n\t\t\t\t\"'&U(uml|UML);'\",\n\t\t\t\t\"'&szlig;'i\",\n\t\t);\n\t\t$replace = array(\t\"\",\n\t\t\t\t\"\",\n\t\t\t\t\"\\\\1\",\n\t\t\t\t\"\\\"\",\n\t\t\t\t\"&\",\n\t\t\t\t\"<\",\n\t\t\t\t\">\",\n\t\t\t\t\" \",\n\t\t\t\tchr(161),\n\t\t\t\tchr(162),\n\t\t\t\tchr(163),\n\t\t\t\tchr(169),\n\t\t\t\tchr(174),\n\t\t\t\tchr(176),\n\t\t\t\tchr(39),\n\t\t\t\tchr(128),\n\t\t\t\t\"�\",\n\t\t\t\t\"�\",\n\t\t\t\t\"�\",\n\t\t\t\t\"�\",\n\t\t\t\t\"�\",\n\t\t\t\t\"�\",\n\t\t\t\t\"�\",\n\t\t);\n\t\t\t\n\t\t$text = preg_replace($search,$replace,$document);\n\n\t\treturn $text;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\t_expandlinks\n\tPurpose:\texpand each link into a fully qualified URL\n\tInput:\t\t$links\t\t\tthe links to qualify\n\t$URI\t\t\tthe full URI to get the base from\n\tOutput:\t\t$expandedLinks\tthe expanded links\n\t\\*======================================================================*/\n\n\tfunction _expandlinks($links,$URI)\n\t{\n\n\t\tpreg_match(\"/^[^\\?]+/\",$URI,$match);\n\n\t\t$match = preg_replace(\"|/[^\\/\\.]+\\.[^\\/\\.]+$|\",\"\",$match[0]);\n\t\t$match = preg_replace(\"|/$|\",\"\",$match);\n\t\t$match_part = parse_url($match);\n\t\t$match_root =\n\t\t$match_part[\"scheme\"].\"://\".$match_part[\"host\"];\n\n\t\t$search = array( \t\"|^http://\".preg_quote($this->host).\"|i\",\n\t\t\t\t\"|^(\\/)|i\",\n\t\t\t\t\"|^(?!http://)(?!mailto:)|i\",\n\t\t\t\t\"|/\\./|\",\n\t\t\t\t\"|/[^\\/]+/\\.\\./|\"\n\t\t);\n\n\t\t$replace = array(\t\"\",\n\t\t\t\t$match_root.\"/\",\n\t\t\t\t$match.\"/\",\n\t\t\t\t\"/\",\n\t\t\t\t\"/\"\n\t\t);\n\n\t\t$expandedLinks = preg_replace($search,$replace,$links);\n\n\t\treturn $expandedLinks;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\t_httprequest\n\tPurpose:\tgo get the http data from the server\n\tInput:\t\t$url\t\tthe url to fetch\n\t$fp\t\t\tthe current open file pointer\n\t$URI\t\tthe full URI\n\t$body\t\tbody contents to send if any (POST)\n\tOutput:\n\t\\*======================================================================*/\n\n\tfunction _httprequest($url,$fp,$URI,$http_method,$content_type=\"\",$body=\"\")\n\t{\n\t\t$cookie_headers = '';\n\t\tif($this->passcookies && $this->_redirectaddr)\n\t\t\t$this->setcookies();\n\t\t\t\n\t\t$URI_PARTS = parse_url($URI);\n\t\tif(empty($url))\n\t\t\t$url = \"/\";\n\t\t$headers = $http_method.\" \".$url.\" \".$this->_httpversion.\"\\r\\n\";\n\t\tif(!empty($this->agent))\n\t\t\t$headers .= \"User-Agent: \".$this->agent.\"\\r\\n\";\n\t\tif(!empty($this->host) && !isset($this->rawheaders['Host'])) {\n\t\t\t$headers .= \"Host: \".$this->host;\n\t\t\tif(!empty($this->port) && $this->port!=80)\n\t\t\t\t$headers .= \":\".$this->port;\n\t\t\t$headers .= \"\\r\\n\";\n\t\t}\n\t\tif(!empty($this->accept))\n\t\t\t$headers .= \"Accept: \".$this->accept.\"\\r\\n\";\n\t\tif(!empty($this->referer))\n\t\t\t$headers .= \"Referer: \".$this->referer.\"\\r\\n\";\n\t\tif(!empty($this->cookies))\n\t\t{\n\t\t\tif(!is_array($this->cookies))\n\t\t\t\t$this->cookies = (array)$this->cookies;\n\n\t\t\treset($this->cookies);\n\t\t\tif ( count($this->cookies) > 0 ) {\n\t\t\t\t$cookie_headers .= 'Cookie: ';\n\t\t\t\tforeach ( $this->cookies as $cookieKey => $cookieVal ) {\n\t\t\t\t\t$cookie_headers .= $cookieKey.\"=\".urlencode($cookieVal).\"; \";\n\t\t\t\t}\n\t\t\t\t$headers .= substr($cookie_headers,0,-2) . \"\\r\\n\";\n\t\t\t}\n\t\t}\n\t\tif(!empty($this->rawheaders))\n\t\t{\n\t\t\tif(!is_array($this->rawheaders))\n\t\t\t\t$this->rawheaders = (array)$this->rawheaders;\n\t\t\twhile(list($headerKey,$headerVal) = each($this->rawheaders))\n\t\t\t\t$headers .= $headerKey.\": \".$headerVal.\"\\r\\n\";\n\t\t}\n\t\tif(!empty($content_type)) {\n\t\t\t$headers .= \"Content-type: $content_type\";\n\t\t\tif ($content_type == \"multipart/form-data\")\n\t\t\t\t$headers .= \"; boundary=\".$this->_mime_boundary;\n\t\t\t$headers .= \"\\r\\n\";\n\t\t}\n\t\tif(!empty($body))\n\t\t\t$headers .= \"Content-length: \".strlen($body).\"\\r\\n\";\n\t\tif(!empty($this->user) || !empty($this->pass))\n\t\t\t$headers .= \"Authorization: Basic \".base64_encode($this->user.\":\".$this->pass).\"\\r\\n\";\n\n\t\t//add proxy auth headers\n\t\tif(!empty($this->proxy_user))\n\t\t\t$headers .= 'Proxy-Authorization: ' . 'Basic ' . base64_encode($this->proxy_user . ':' . $this->proxy_pass).\"\\r\\n\";\n\n\n\t\t$headers .= \"\\r\\n\";\n\n\t\t// set the read timeout if needed\n\t\tif ($this->read_timeout > 0)\n\t\t\tsocket_set_timeout($fp, $this->read_timeout);\n\t\t$this->timed_out = false;\n\n\t\tfwrite($fp,$headers.$body,strlen($headers.$body));\n\n\t\t$this->_redirectaddr = false;\n\t\tunset($this->headers);\n\n\t\twhile($currentHeader = fgets($fp,$this->_maxlinelen))\n\t\t{\n\t\t\tif ($this->read_timeout > 0 && $this->_check_timeout($fp))\n\t\t\t{\n\t\t\t\t$this->status=-100;\n\t\t\t\treturn false;\n\t\t\t}\n\n\t\t\tif($currentHeader == \"\\r\\n\")\n\t\t\t\tbreak;\n\n\t\t\t// if a header begins with Location: or URI:, set the redirect\n\t\t\tif(preg_match(\"/^(Location:|URI:)/i\",$currentHeader))\n\t\t\t{\n\t\t\t\t// get URL portion of the redirect\n\t\t\t\tpreg_match(\"/^(Location:|URI:)[ ]+(.*)/i\",chop($currentHeader),$matches);\n\t\t\t\t// look for :// in the Location header to see if hostname is included\n\t\t\t\tif (!empty($matches)) {\n\t\t\t\t\tif(!preg_match(\"|\\:\\/\\/|\",$matches[2]))\n\t\t\t\t\t{\n\t\t\t\t\t\t// no host in the path, so prepend\n\t\t\t\t\t\t$this->_redirectaddr = $URI_PARTS[\"scheme\"].\"://\".$this->host.\":\".$this->port;\n\t\t\t\t\t\t// eliminate double slash\n\t\t\t\t\t\tif(!preg_match(\"|^/|\",$matches[2]))\n\t\t\t\t\t\t\t$this->_redirectaddr .= \"/\".$matches[2];\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\t$this->_redirectaddr .= $matches[2];\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\t$this->_redirectaddr = $matches[2];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(preg_match(\"|^HTTP/|\",$currentHeader))\n\t\t\t{\n\t\t\t\tif(preg_match(\"|^HTTP/[^\\s]*\\s(.*?)\\s|\",$currentHeader, $status))\n\t\t\t\t{\n\t\t\t\t\t$this->status= $status[1];\n\t\t\t\t}\n\t\t\t\t$this->response_code = $currentHeader;\n\t\t\t}\n\n\t\t\t$this->headers[] = $currentHeader;\n\t\t}\n\n\t\t$results = '';\n\t\tdo {\n\t\t\t$_data = fread($fp, $this->maxlength);\n\t\t\tif (strlen($_data) == 0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$results .= $_data;\n\t\t} while(true);\n\n\t\tif ($this->read_timeout > 0 && $this->_check_timeout($fp))\n\t\t{\n\t\t\t$this->status=-100;\n\t\t\treturn false;\n\t\t}\n\n\t\t// check if there is a a redirect meta tag\n\n\t\tif(preg_match(\"'<meta[\\s]*http-equiv[^>]*?content[\\s]*=[\\s]*[\\\"\\']?\\d+;[\\s]*URL[\\s]*=[\\s]*([^\\\"\\']*?)[\\\"\\']?>'i\",$results,$match))\n\n\t\t{\n\t\t\t$this->_redirectaddr = $this->_expandlinks($match[1],$URI);\n\t\t}\n\n\t\t// have we hit our frame depth and is there frame src to fetch?\n\t\tif(($this->_framedepth < $this->maxframes) && preg_match_all(\"'<frame\\s+.*src[\\s]*=[\\'\\\"]?([^\\'\\\"\\>]+)'i\",$results,$match))\n\t\t{\n\t\t\t$this->results[] = $results;\n\t\t\tfor($x=0; $x<count($match[1]); $x++)\n\t\t\t\t$this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS[\"scheme\"].\"://\".$this->host);\n\t\t}\n\t\t// have we already fetched framed content?\n\t\telseif(is_array($this->results))\n\t\t$this->results[] = $results;\n\t\t// no framed content\n\t\telse\n\t\t\t$this->results = $results;\n\n\t\treturn true;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\t_httpsrequest\n\tPurpose:\tgo get the https data from the server using curl\n\tInput:\t\t$url\t\tthe url to fetch\n\t$URI\t\tthe full URI\n\t$body\t\tbody contents to send if any (POST)\n\tOutput:\n\t\\*======================================================================*/\n\n\tfunction _httpsrequest($url,$URI,$http_method,$content_type=\"\",$body=\"\")\n\t{\n\t\tif($this->passcookies && $this->_redirectaddr)\n\t\t\t$this->setcookies();\n\n\t\t$headers = array();\n\t\t\t\n\t\t$URI_PARTS = parse_url($URI);\n\t\tif(empty($url))\n\t\t\t$url = \"/\";\n\t\t// GET ... header not needed for curl\n\t\t//$headers[] = $http_method.\" \".$url.\" \".$this->_httpversion;\n\t\tif(!empty($this->agent))\n\t\t\t$headers[] = \"User-Agent: \".$this->agent;\n\t\tif(!empty($this->host))\n\t\t\tif(!empty($this->port) && $this->port!=80)\n\t\t\t$headers[] = \"Host: \".$this->host.\":\".$this->port;\n\t\telse\n\t\t\t$headers[] = \"Host: \".$this->host;\n\t\tif(!empty($this->accept))\n\t\t\t$headers[] = \"Accept: \".$this->accept;\n\t\tif(!empty($this->referer))\n\t\t\t$headers[] = \"Referer: \".$this->referer;\n\t\tif(!empty($this->cookies))\n\t\t{\n\t\t\tif(!is_array($this->cookies))\n\t\t\t\t$this->cookies = (array)$this->cookies;\n\n\t\t\treset($this->cookies);\n\t\t\tif ( count($this->cookies) > 0 ) {\n\t\t\t\t$cookie_str = 'Cookie: ';\n\t\t\t\tforeach ( $this->cookies as $cookieKey => $cookieVal ) {\n\t\t\t\t\t$cookie_str .= $cookieKey.\"=\".urlencode($cookieVal).\"; \";\n\t\t\t\t}\n\t\t\t\t$headers[] = substr($cookie_str,0,-2);\n\t\t\t}\n\t\t}\n\t\tif(!empty($this->rawheaders))\n\t\t{\n\t\t\tif(!is_array($this->rawheaders))\n\t\t\t\t$this->rawheaders = (array)$this->rawheaders;\n\t\t\twhile(list($headerKey,$headerVal) = each($this->rawheaders))\n\t\t\t\t$headers[] = $headerKey.\": \".$headerVal;\n\t\t}\n\t\tif(!empty($content_type)) {\n\t\t\tif ($content_type == \"multipart/form-data\")\n\t\t\t\t$headers[] = \"Content-type: $content_type; boundary=\".$this->_mime_boundary;\n\t\t\telse\n\t\t\t\t$headers[] = \"Content-type: $content_type\";\n\t\t}\n\t\tif(!empty($body))\n\t\t\t$headers[] = \"Content-length: \".strlen($body);\n\t\tif(!empty($this->user) || !empty($this->pass))\n\t\t\t$headers[] = \"Authorization: BASIC \".base64_encode($this->user.\":\".$this->pass);\n\t\tif (function_exists('curl_init')) {\n\t\t\t$ch = curl_init();\n\t\t\tcurl_setopt($ch, CURLOPT_URL, $URI);\n\t\t\tcurl_setopt($ch, CURLOPT_HEADER, true); \n\t\t\tcurl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);\n\t\t\tcurl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);\n\t\t\tcurl_setopt($ch, CURLOPT_SSLVERSION,3); \n\t\t\tcurl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); \n\t\t\tcurl_setopt($ch, CURLOPT_HTTPHEADER, $headers); \n\t\t\tcurl_setopt($ch, CURLOPT_TIMEOUT, $this->read_timeout);\n\t\t\tif(!empty($body)) {\n\t\t\t\tcurl_setopt($ch, CURLOPT_POST, true);\n\t\t\t\tcurl_setopt($ch, CURLOPT_POSTFIELDS, $body);\n\t\t\t}\n\t\t\t$data = curl_exec($ch);\n\t\t\tif ($data === false) {\n\t\t\t\t$this->error = \"Error: Curl error  \".curl_error($ch);\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\t$parts = explode(\"\\r\\n\\r\\n\",$data,2);\n\t\t\t$result_headers = explode(\"\\r\\n\",$parts[0]);\n\t\t\t$results = $parts[1];\n\t\t\tunset($parts);\n\t\t} else {\n\t\t\t\tfor($curr_header = 0; $curr_header < count($headers); $curr_header++) {\n\t\t\t\t\t$safer_header = strtr( $headers[$curr_header], \"\\\"\", \" \" );\n\t\t\t\t\t$cmdline_params .= \" -H \\\"\".$safer_header.\"\\\"\";\n\t\t\t\t}\n\t\t\n\t\t\t\tif(!empty($body))\n\t\t\t\t\t$cmdline_params .= \" -d \\\"$body\\\"\";\n\t\t\n\t\t\t\tif($this->read_timeout > 0)\n\t\t\t\t\t$cmdline_params .= \" -m \".$this->read_timeout;\n\t\t\n\t\t\t\t$headerfile = tempnam($temp_dir, \"sno\");\n\t\t\n\t\t\t\texec($this->curl_path.\" -k -D \\\"$headerfile\\\"\".$cmdline_params.\" \\\"\".escapeshellcmd($URI).\"\\\"\",$results,$return);\n\t\t\n\t\t\t\tif($return)\n\t\t\t\t{\n\t\t\t\t\t$this->error = \"Error: cURL could not retrieve the document, error $return.\";\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\t\n\t\t\t\t\n\t\t\t$results = implode(\"\\r\\n\",$results);\n\t\n\t\t\t$result_headers = file(\"$headerfile\");\n\t\t}\n\t\t$this->_redirectaddr = false;\n\t\tunset($this->headers);\n\n\t\tfor($currentHeader = 0; $currentHeader < count($result_headers); $currentHeader++)\n\t\t{\n\t\t\t\t\n\t\t\t// if a header begins with Location: or URI:, set the redirect\n\t\t\tif(preg_match(\"/^(Location: |URI: )/i\",$result_headers[$currentHeader]))\n\t\t\t{\n\t\t\t\t// get URL portion of the redirect\n\t\t\t\tpreg_match(\"/^(Location: |URI:)\\s+(.*)/\",chop($result_headers[$currentHeader]),$matches);\n\t\t\t\t// look for :// in the Location header to see if hostname is included\n\t\t\t\tif (!empty($matches)) {\n\t\t\t\t\tif(!preg_match(\"|\\:\\/\\/|\",$matches[2]))\n\t\t\t\t\t{\n\t\t\t\t\t\t// no host in the path, so prepend\n\t\t\t\t\t\t$this->_redirectaddr = $URI_PARTS[\"scheme\"].\"://\".$this->host;\n\t\t\t\t\t\t// eliminate double slash\n\t\t\t\t\t\tif(!preg_match(\"|^/|\",$matches[2]))\n\t\t\t\t\t\t\t$this->_redirectaddr .= \"/\".$matches[2];\n\t\t\t\t\t\telse\n\t\t\t\t\t\t\t$this->_redirectaddr .= $matches[2];\n\t\t\t\t\t}\n\t\t\t\t\telse\n\t\t\t\t\t\t$this->_redirectaddr = $matches[2];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif(preg_match(\"|^HTTP/|\",$result_headers[$currentHeader]))\n\t\t\t\t$this->response_code = $result_headers[$currentHeader];\n\n\t\t\t$this->headers[] = $result_headers[$currentHeader];\n\t\t}\n\n\t\t// check if there is a a redirect meta tag\n\n\t\tif(preg_match(\"'<meta[\\s]*http-equiv[^>]*?content[\\s]*=[\\s]*[\\\"\\']?\\d+;[\\s]*URL[\\s]*=[\\s]*([^\\\"\\']*?)[\\\"\\']?>'i\",$results,$match))\n\t\t{\n\t\t\t$this->_redirectaddr = $this->_expandlinks($match[1],$URI);\n\t\t}\n\n\t\t// have we hit our frame depth and is there frame src to fetch?\n\t\tif(($this->_framedepth < $this->maxframes) && preg_match_all(\"'<frame\\s+.*src[\\s]*=[\\'\\\"]?([^\\'\\\"\\>]+)'i\",$results,$match))\n\t\t{\n\t\t\t$this->results[] = $results;\n\t\t\tfor($x=0; $x<count($match[1]); $x++)\n\t\t\t\t$this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS[\"scheme\"].\"://\".$this->host);\n\t\t}\n\t\t// have we already fetched framed content?\n\t\telseif(is_array($this->results))\n\t\t\t$this->results[] = $results;\n\t\t// no framed content\n\t\telse\n\t\t\t$this->results = $results;\n\t\tif (isset($headerfile) && file_exists($headerfile))\n\t\t\tunlink($headerfile);\n\n\t\treturn true;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\tsetcookies()\n\tPurpose:\tset cookies for a redirection\n\t\\*======================================================================*/\n\n\tfunction setcookies()\n\t{\n\t\tfor($x=0; $x<count($this->headers); $x++)\n\t\t{\n\t\t\tif(preg_match('/^set-cookie:[\\s]+([^=]+)=([^;]+)/i', $this->headers[$x],$match))\n\t\t\t\t$this->cookies[$match[1]] = urldecode($match[2]);\n\t\t}\n\t}\n\n\n\t/*======================================================================*\\\n\t Function:\t_check_timeout\n\tPurpose:\tchecks whether timeout has occurred\n\tInput:\t\t$fp\tfile pointer\n\t\\*======================================================================*/\n\n\tfunction _check_timeout($fp)\n\t{\n\t\tif ($this->read_timeout > 0) {\n\t\t\t$fp_status = socket_get_status($fp);\n\t\t\tif ($fp_status[\"timed_out\"]) {\n\t\t\t\t$this->timed_out = true;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\t/*======================================================================*\\\n\t Function:\t_connect\n\tPurpose:\tmake a socket connection\n\tInput:\t\t$fp\tfile pointer\n\t\\*======================================================================*/\n\n\tfunction _connect(&$fp)\n\t{\n\t\tif(!empty($this->proxy_host) && !empty($this->proxy_port))\n\t\t{\n\t\t\t$this->_isproxy = true;\n\n\t\t\t$host = $this->proxy_host;\n\t\t\t$port = $this->proxy_port;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t$host = $this->host;\n\t\t\t$port = $this->port;\n\t\t}\n\n\t\t$this->status = 0;\n\n\t\tif($fp = fsockopen(\n\t\t\t\t$host,\n\t\t\t\t$port,\n\t\t\t\t$errno,\n\t\t\t\t$errstr,\n\t\t\t\t$this->_fp_timeout\n\t\t))\n\t\t{\n\t\t\t// socket connection succeeded\n\n\t\t\treturn true;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t// socket connection failed\n\t\t\t$this->status = $errno;\n\t\t\tswitch($errno)\n\t\t\t{\n\t\t\t\tcase -3:\n\t\t\t\t\t$this->error=\"socket creation failed (-3)\";\n\t\t\t\tcase -4:\n\t\t\t\t\t$this->error=\"dns lookup failure (-4)\";\n\t\t\t\tcase -5:\n\t\t\t\t\t$this->error=\"connection refused or timed out (-5)\";\n\t\t\t\tdefault:\n\t\t\t\t\t$this->error=\"connection failed (\".$errno.\")\";\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t}\n\t/*======================================================================*\\\n\t Function:\t_disconnect\n\tPurpose:\tdisconnect a socket connection\n\tInput:\t\t$fp\tfile pointer\n\t\\*======================================================================*/\n\n\tfunction _disconnect($fp)\n\t{\n\t\treturn(fclose($fp));\n\t}\n\n\n\t/*======================================================================*\\\n\t Function:\t_prepare_post_body\n\tPurpose:\tPrepare post body according to encoding type\n\tInput:\t\t$formvars  - form variables\n\t$formfiles - form upload files\n\tOutput:\t\tpost body\n\t\\*======================================================================*/\n\n\tfunction _prepare_post_body($formvars, $formfiles)\n\t{\n\t\tsettype($formvars, \"array\");\n\t\tsettype($formfiles, \"array\");\n\t\t$postdata = '';\n\n\t\tif (count($formvars) == 0 && count($formfiles) == 0)\n\t\t\treturn;\n\t\tif (is_string($formvars)) return $formvars;\n\t\tif((count($formvars) == 1) && isset($formvars[0])) return $formvars[0];\n\t\tswitch ($this->_submit_type) {\n\t\t\tcase \"application/x-www-form-urlencoded\":\n\t\t\t\treset($formvars);\n\t\t\t\twhile(list($key,$val) = each($formvars)) {\n\t\t\t\t\tif (is_array($val) || is_object($val)) {\n\t\t\t\t\t\twhile (list($cur_key, $cur_val) = each($val)) {\n\t\t\t\t\t\t\t$postdata .= urlencode($key).\"[]=\".urlencode($cur_val).\"&\";\n\t\t\t\t\t\t}\n\t\t\t\t\t} else\n\t\t\t\t\t\t$postdata .= urlencode($key).\"=\".urlencode($val).\"&\";\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase \"multipart/form-data\":\n\t\t\t\t$this->_mime_boundary = \"--------\".md5(uniqid(microtime()));\n\n\t\t\t\treset($formvars);\n\t\t\t\twhile(list($key,$val) = each($formvars)) {\n\t\t\t\t\tif (is_array($val) || is_object($val)) {\n\t\t\t\t\t\twhile (list($cur_key, $cur_val) = each($val)) {\n\t\t\t\t\t\t\t$postdata .= \"--\".$this->_mime_boundary.\"\\r\\n\";\n\t\t\t\t\t\t\t$postdata .= \"Content-Disposition: form-data; name=\\\"$key\\[\\]\\\"\\r\\n\\r\\n\";\n\t\t\t\t\t\t\t$postdata .= \"$cur_val\\r\\n\";\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$postdata .= \"--\".$this->_mime_boundary.\"\\r\\n\";\n\t\t\t\t\t\t$postdata .= \"Content-Disposition: form-data; name=\\\"$key\\\"\\r\\n\\r\\n\";\n\t\t\t\t\t\t$postdata .= \"$val\\r\\n\";\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\treset($formfiles);\n\t\t\t\twhile (list($field_name, $file_names) = each($formfiles)) {\n\t\t\t\t\tsettype($file_names, \"array\");\n\t\t\t\t\twhile (list(, $file_name) = each($file_names)) {\n\t\t\t\t\t\t$file_content = file_get_contents($file_name);\n\t\t\t\t\t\tif (!$file_content) continue;\n\n\t\t\t\t\t\t$base_name = basename($file_name);\n\n\t\t\t\t\t\t$postdata .= \"--\".$this->_mime_boundary.\"\\r\\n\";\n\t\t\t\t\t\t$postdata .= \"Content-Disposition: form-data; name=\\\"$field_name\\\"; filename=\\\"$base_name\\\"\\r\\nContent-Type: image/jpeg\\r\\n\\r\\n\";\n\t\t\t\t\t\t$postdata .= \"$file_content\\r\\n\";\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$postdata .= \"--\".$this->_mime_boundary.\"--\\r\\n\";\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn $postdata;\n\t}\n}\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/old_version/test/test2.php",
    "content": "<?php\n/**\n * 微信扩展接口测试\n */\n\tinclude(\"../wechatext.class.php\");\n\t\n\tfunction logdebug($text){\n\t\tfile_put_contents('../data/log.txt',$text.\"\\n\",FILE_APPEND);\t\t\n\t};\n\t\n\t$options = array(\n\t\t'account'=>'demo@domain.com',\n\t\t'password'=>'demo',\n\t\t'datapath'=>'../data/cookie_',\n\t\t\t'debug'=>true,\n\t\t\t'logcallback'=>'logdebug'\t\n\t); \n\t$wechat = new Wechatext($options);\n\tif ($wechat->checkValid()) {\n\t\t//获取分组列表\n\t\t$grouplist = $wechat->getGroupList();\n\t\tvar_dump($grouplist);\n\t\t//获取用户列表\n\t\t$userlist = $wechat->getUserlist(0,10);\n\t\tvar_dump($userlist);\n\t\t$user = $userlist[0];\n\t\t// 获取用户信息\n\t\t$userdata = $wechat->getInfo($user['id']);\n\t\tvar_dump($userdata);\n\t\t// 获取已保存的图文消息\n\t\t$newslist = $wechat->getNewsList(0,10);\n\t\tvar_dump($newslist);\n\t\t//获取用户最新消息\n\t\t$topmsg = $wechat->getTopMsg();\n\t\tvar_dump($topmsg);\n\t\t$msglist = $wechat->getMsg();\n\t\tvar_dump($msglist);\n\t\t// 主动回复消息\n\t\tif ($topmsg && $topmsg['has_reply']==0){\n\t\t    $wechat->send($user['id'],'hi '.$topmsg['nick_name'].',rev:'.$topmsg['content']);\n\t\t    $content = '这是一条Wechatext发出的测试微信';\n\t\t    $imgdata = file_get_contents('http://github.global.ssl.fastly.net/images/modules/dashboard/bootcamp/octocat_fork.png');\n\t\t    $img = '../data/send.png';\n\t\t    file_put_contents($img,$imgdata);\n\t\t    //上传图片\n\t\t    $fileid = $wechat->uploadFile($img);\n\t\t    echo 'fileid:'.$fileid;\n\t\t    //if ($fileid) $re = $wechat->sendImage($user['id'],$fileid);\n\t\t    //发送图文信息\n\t\t    $re = $wechat->sendPreview($userdata['user_name'],$content,$content,$content,$fileid,'http://github.com/dodgepudding/wechat-php-sdk');\n\t\t    var_dump($re);\n\t\t    //发送视频\n\t\t    //$re = $wechat->sendVideo($user['id'],$fileid);\n\t\t\t$re = $wechat->getFileList(2,0,10);\n\t\t\tvar_dump($re);\n\t\t} else {\n\t\t\techo 'no top msg';\n\t\t}\t\n\t} else {\n\t\techo \"login error\";\n\t}"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/old_version/test/test3.php",
    "content": "<?php\n/**\n * 微信二维码登陆测试\n */\n\tinclude(\"../wechatauth.class.php\");\n\tsession_start();\n\tfunction logdebug($text){\n\t\tfile_put_contents('../log/logwechat.txt',$text.\"\\n\",FILE_APPEND);\t\t\n\t};\n\t$sid  = session_id();\n\t$options = array(\n\t\t'account'=>$sid,\n\t\t'datapath'=>'../log/cookiecode_',\n\t\t\t'debug'=>true,\n\t\t\t'logcallback'=>'logdebug'\t\n\t); \n\t$wechat = new Wechatauth($options);\n\t\n\tif (isset($_POST['code'])) {\n\t\t$logincode = $_POST['code'];\n\t\t$vres = $wechat->set_login_code($logincode)->verify_code();\n\t\tif ($vres===false) {\n\t\t\t$result = array('status'=>0);\n\t\t} else {\n\t\t\t$result = array('status'=>$vres);\n\t\t\tif ($vres==200) {\n\t\t\t\t$result['info'] = $wechat->get_login_info();\n\t\t\t\t$result['cookie'] = $wechat->get_login_cookie(true);\n\t\t\t}\n\t\t}\n\t\t\n\t\tdie(json_encode($result));\t\n\t}\n\t$logincode =  $wechat->get_login_code();\n\t$qrimg = $wechat->get_code_image();\n\t\n?>\n\n<!DOCTYPE html>\n<html>\n<head>\n<meta content=\"text/html; charset=utf-8\" http-equiv=\"Content-Type\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<script type=\"text/javascript\" src=\"http://code.jquery.com/jquery-1.9.1.min.js\"></script>\n<title>微信二维码登陆接口</title>\n</head>\n<body>\n<h2>微信里扫描以下二维码实现登陆</h2>\n<div id=\"content\">\n<img src=\"<?php echo $qrimg;?>\" />\n</div>\n<script type=\"text/javascript\">\nvar ajaxlock = false;\nvar ajaxhandle;\nfunction synclogin(){\n\tif (!ajaxlock) {\n\t\tajaxlock = true;\n\t\t$.post(location.href,{code:'<?php echo $logincode;?>'},function(json){\n\t\t\t//console.log(json);\n\t\t\tif (json.status) {\n\t\t\t\tconsole.log(json.status);\n\t\t\t\tif (json.status==200) {\n\t\t\t\t\tvar nick,uid,username,sex,avatar;\n\t\t\t\t\tif (json.info && json.info.User){\n\t\t\t\t\t\tuid = json.info.User.Uin;\n\t\t\t\t\t\tnick = json.info.User.NickName;\n\t\t\t\t\t\tusername = json.info.User.UserName;\n\t\t\t\t\t\tsex = json.info.User.Sex;\n\t\t\t\t\t\tavatar = json.info.User.HeadImgUrl;\n\t\t\t\t\t\t$('#content').html('<h2>用户信息</h2><ul><li><b>Uid:</b>'+uid\n\t\t\t\t\t\t\t\t+'</li><li><b>Nick:</b>'+nick\n\t\t\t\t\t\t\t\t+'</li><li><b>username:</b>'+username\n\t\t\t\t\t\t\t\t+'</li><li><b>sex:</b>'+(sex==1?'男':'女')\n\t\t\t\t\t\t\t\t+'</li><li><b>avatar:</b>'+avatar\n\t\t\t\t\t\t\t\t+'</li></ul>');\n\t\t\t\t\t}\n\t\t\t\t\talert('login success, welcome '+nick);\n\n\t\t\t\t\tclearInterval(ajaxhandle);\n\t\t\t\t}\n\t\t\t}\n\t\t\tajaxlock = false;\n\t\t},'json');\n\t}\n}\n$(function(){\n\tajaxhandle = setInterval(\"synclogin()\",5000);\n});\n</script>\n</body>"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/old_version/test/weshare.html",
    "content": "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n<script src=\"../wechat.js\" type=\"text/javascript\"></script>\n<script>\nvar dataForWeixin={\n\t   appId:\"\",\n\t   MsgImg:\"https://open.weixin.qq.com/zh_CN/htmledition/res/assets/res-design-download/icon_res_download_wxlogo.png\",\n\t   TLImg:\"https://open.weixin.qq.com/zh_CN/htmledition/res/assets/res-design-download/icon_res_download_wxlogo.png\",\n\t   url:\"https://raw.githubusercontent.com/dodgepudding/wechat-php-sdk/master/test/weshare.html\",\n\t   title:\"微信分享测试文件\",\n\t   desc:\"这里演示了微信分享前调和回调方法\",\n\t   fakeid:\"\",\n\t   prepare:function(e){\n\t\t   var log = '';\n\t\t\tfor (var i in e) {\n\t\t\t\tlog+= i+':'+e[i]+';';\n\t\t\t}\n\t\t\talert(log);\n\t   },\n\t   callback:function(e){\n\t\t   var log = '';\n\t\t\tfor (var i in e) {\n\t\t\t\tlog+= i+':'+e[i]+';';\n\t\t\t}\n\t\t\talert(log);\n\t   }\n\t};\nWeixinJS.hideToolbar();\nWeixinJS.getNetworkType(\n\tfunction(e){\n\t\talert(e);\n\t});\n</script>\n<title>weshare</title>\n</head>\n\n<body>\n<h3>这里演示了微信分享前调和回调方法，点击微信右上角分享相关的功能，即可看到各类返回的alert信息</h3>\n</body>\n</html>\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/old_version/wechat.js",
    "content": "/**\n * 微信网页端调用JS(官方于微信6.0.2版本发布新版JSAPI接口，此接口文件废弃)\n * @author dodge\n * @contact dodgepudding@gmail.com\n * @link http://blog.4wer.com/wechat-timeline-share\n * @version 1.1\n * \n * 自定义分享使用：\n * WeixinJS.hideOptionMenu() 隐藏右上角按钮\n * WeixinJS.showOptionMenu() 显示右上角按钮\n * WeixinJS.hideToolbar() 隐藏工具栏\n * WeixinJS.showToolbar() 显示工具栏\n * WeixinJS.getNetworkType() 获取网络状态\n * WeixinJS.closeWindow() 关闭窗口\n * WeixinJS.scanQRCode() 扫描二维码\n * WeixinJS.openUrlByExtBrowser(url) 使用浏览器打开网址\n * WeixinJS.jumpToBizProfile(username) 跳转到指定公众账号页面\n * WeixinJS.sendEmail(title,content) 发送邮件\n * WeixinJS.openProductView(latitude,longitude,name,address,scale,infoUrl) 查看地图\n * WeixinJS.addContact(username) 添加微信账号\n * WeixinJS.imagePreview(urls,current) 调出微信内图片预览\n * WeixinJS.payCallback(appId,package,timeStamp,nonceStr,signType,paySign,callback) 微信JsApi支付接口\n * WeixinJS.editAddress(appId,addrSign,timeStamp,nonceStr,callback) 微信JsApi支付接口\n * 自定义分享内容数据格式：\n * var dataForWeixin={\n\t   appId:\"\",\n\t   MsgImg:\"消息图片路径\",\n\t   TLImg:\"时间线图路径\",\n\t   url:\"分享url路径\",\n\t   title:\"标题\",\n\t   desc:\"描述\",\n\t   fakeid:\"\",\n\t   prepare:function(argv){\n\t   if (typeof argv.shareTo!='undefined') \n\t   \tswitch(argv.shareTo) {\n\t   \t\tcase 'friend':\n\t   \t\t//发送给朋友\n\t   \t\talert(argv.scene); //friend\n\t   \t\tbreak;\n\t   \t\tcase 'timeline':\n\t   \t\t//发送给朋友\n\t   \t\tbreak;\n\t   \t\tcase 'weibo':\n\t   \t\t//发送到微博\n\t   \t\talert(argv.url);\n\t   \t\tbreak;\n\t   \t\tcase 'favorite':\n\t   \t\t//收藏\n\t   \t\talert(argv.scene);//favorite\n\t   \t\tbreak;\n\t   \t\tcase 'connector':\n\t   \t\t//分享到第三方应用\n\t   \t\talert(argv.scene);//connector\n\t   \t\tbreak;\n\t   \t\tdefault：\n\t   \t}\n\t   },\n\t   callback:function(res){\n\t   \t//发送给好友或应用\n\t   \tif (res.err_msg=='send_app_msg:confirm') {\n\t   \t\t//todo:func1();\n\t   \t\talert(res.err_desc);\n\t   \t}\n\t   \tif (res.err_msg=='send_app_msg:cancel') {\n\t   \t\t//todo:func2();\n\t   \t\talert(res.err_desc);\n\t   \t}\n\t   \t//分享到朋友圈\n\t   \tif (res.err_msg=='share_timeline:ok') {\n\t   \t\t//todo:func1();\n\t   \t\talert(res.err_desc);\n\t   \t}\n\t   \tif (res.err_msg=='share_timeline:cancel') {\n\t   \t\t//todo:func1();\n\t   \t\talert(res.err_desc);\n\t   \t}\n\t   \t//分享到微博\n\t   \tif (res.err_msg=='share_weibo:confirm') {\n\t   \t\t//todo:func1();\n\t   \t\talert(res.err_desc);\n\t   \t}\n\t   \tif (res.err_msg=='share_weibo:cancel') {\n\t   \t\t//todo:func1();\n\t   \t\talert(res.err_desc);\n\t   \t}\n\t   \t//收藏或分享到应用\n\t   \tif (res.err_msg=='send_app_msg:ok') {\n\t   \t\t//todo:func1();\n\t   \t\talert(res.err_desc);\n\t   \t}   \t\n\t   }\n\t};\n */\n\nWeixinJS = typeof WeixinJS!='undefined' || {};\n//隐藏右上角按钮\nWeixinJS.hideOptionMenu = function() {\n\tdocument.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {\n\t\tif (typeof WeixinJSBridge!='undefined')\tWeixinJSBridge.call('hideOptionMenu');\n\t});\n};\n//显示右上角按钮\nWeixinJS.showOptionMenu = function() {\n\tdocument.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {\n\t\tif (typeof WeixinJSBridge!='undefined')\tWeixinJSBridge.call('showOptionMenu');\n\t});\n};\n//隐藏底部导航栏\nWeixinJS.hideToolbar = function() {\n\tdocument.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {\n\t\tif (typeof WeixinJSBridge!='undefined') WeixinJSBridge.call('hideToolbar');\n\t});\n};\n//显示底部导航栏\nWeixinJS.showToolbar = function() {\n\tdocument.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {\n\t\tif (typeof WeixinJSBridge!='undefined') WeixinJSBridge.call('showToolbar');\n\t});\n};\n//网页获取用户网络状态\nnetType={\"network_type:wifi\":\"wifi网络\",\"network_type:edge\":\"非wifi,包含3G/2G\",\"network_type:fail\":\"网络断开连接\",\"network_type:wwan\":\"2g或者3g\"};\nWeixinJS.getNetworkType = function(callback) {\n\tdocument.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {\n\t\tif (typeof WeixinJSBridge!='undefined') WeixinJSBridge.invoke('getNetworkType',{},\n\t\tfunction(res){\n\t\t\t//result: network_type:wifi,network_type:edge,network_type:fail,network_type:wwan\n\t\t\t//netType[e.err_msg]\n\t\t\tcallback(res.err_msg);\n\t    });\n\t});\n};\n//关闭窗口\nWeixinJS.closeWindow = function() {\n\tif (typeof WeixinJSBridge!='undefined') WeixinJSBridge.invoke(\"closeWindow\", {});\n};\n//扫描二维码\nWeixinJS.scanQRCode = function() {\n\tif (typeof WeixinJSBridge!='undefined') WeixinJSBridge.invoke(\"scanQRCode\", {});\n};\n//使用浏览器打开网址\nWeixinJS.openUrlByExtBrowser=function(url){\n\tif (typeof WeixinJSBridge!='undefined') WeixinJSBridge.invoke(\"openUrlByExtBrowser\",{\"url\" : url});\n};\n//跳转到指定公众账号页面\nWeixinJS.jumpToBizProfile=function(username){\n\tif (typeof WeixinJSBridge!='undefined') WeixinJSBridge.invoke(\"jumpToBizProfile\",{\"tousername\" : username});\n};\n//发送邮件\nWeixinJS.sendEmail=function(title,content){\n\tif (typeof WeixinJSBridge!='undefined') WeixinJSBridge.invoke(\"sendEmail\",{\n\t    \"title\" : title,\n\t    \"content\" : content\n\t});\n};\n//查看地图\nWeixinJS.openProductView=function(latitude,longitude,name,address,scale,infoUrl){\n\tif (typeof WeixinJSBridge!='undefined') WeixinJSBridge.invoke(\"openProductView\",{\n\t    \"latitude\" : latitude, //纬度\n\t    \"longitude\" : longitude, //经度\n\t    \"name\" : name, //名称\n\t    \"address\" : address, //地址\n\t    \"scale\" : scale, //地图缩放级别\n\t    \"infoUrl\" : infoUrl, //查看位置界面底部的超链接            \n\t});\n};\n//添加微信账号\nWeixinJS.addContact=function weixinAddContact(username){\n    if (typeof WeixinJSBridge!='undefined') WeixinJSBridge.invoke(\"addContact\", {\n    \t\"webtype\": \"1\",\n    \t\"username\": username\n    }, function(e) {\n\t    WeixinJSBridge.log(e.err_msg);\n\t    //e.err_msg:add_contact:added 已经添加\n\t    //e.err_msg:add_contact:cancel 取消添加\n\t    //e.err_msg:add_contact:ok 添加成功\n\t    if(e.err_msg == 'add_contact:added' || e.err_msg == 'add_contact:ok'){\n\t            //关注成功，或者已经关注过\n\t    }\n    });\n};\n\n/**\n * 调出微信内图片预览scrollview\n * @param array urls 图片url数组\n * @param string current 当前图片url\n */\nWeixinJS.imagePreview = function(urls,current) {\n\tif (typeof WeixinJSBridge!='undefined') \n\t\tWeixinJSBridge.invoke(\"imagePreview\", {\n\t\t\tcurrent: current,\n\t\t\turls: urls\n\t\t});\n};\n\n//微信JsApi支付接口\nWeixinJS.payCallback = function(appId,package,timeStamp,nonceStr,signType,paySign,callback){\n\tif (typeof WeixinJSBridge!='undefined')\n\tWeixinJSBridge.invoke('getBrandWCPayRequest',{\n        \"appId\" : appId.toString(),\n        \"timeStamp\" : timeStamp.toString(),\n        \"nonceStr\" : nonceStr.toString(),\n        \"package\" : package.toString(),\n        \"signType\" : signType.toString(),\n        \"paySign\" : paySign.toString()\n        \n    },function(res){\n    \t// res.err_msg == \"get_brand_wcpay_request:ok\" return true;\n    \t// res.err_msg == \"get_brand_wcpay_request:cancel\" return false;\n    \tcallback(res);\n    });\n};\n//编辑收货地址\nWeixinJS.editAddress = function(appId,addrSign,timeStamp,nonceStr,callback){\n\tvar postdata = {\n\t\t\t\"appId\" : appId.toString(),\n            \"scope\" : \"jsapi_address\",\n            \"signType\" : \"sha1\",\n            \"addrSign\" : addrSign.toString(),\n            \"timeStamp\" : timeStamp.toString(),\n            \"nonceStr\" : nonceStr.toString()\n\t};\n\tif (typeof WeixinJSBridge!='undefined')\n\tWeixinJSBridge.invoke('editAddress',postdata, function(res){\n\t//return res.proviceFirstStageName,res.addressCitySecondStageName,res.addressCountiesThirdStageName,res.addressDetailInfo,res.userName,res.addressPostalCode,res.telNumber\n\t//error return res.err_msg\n\tcallback(res);\n\t});\n};\n\n(function(){\n   if (typeof dataForWeixin==\"undefined\") return;\n   var onBridgeReady=function(){\n   WeixinJSBridge.on('menu:share:appmessage', function(argv){\n\t  (dataForWeixin.prepare)(argv);\n      WeixinJSBridge.invoke('sendAppMessage',{\n         \"appid\":dataForWeixin.appId,\n         \"img_url\":dataForWeixin.MsgImg,\n         \"img_width\":\"120\",\n         \"img_height\":\"120\",\n         \"link\":dataForWeixin.url,\n         \"desc\":dataForWeixin.desc,\n         \"title\":dataForWeixin.title\n      }, function(res){(dataForWeixin.callback)(res);});\n   });\n   WeixinJSBridge.on('menu:share:timeline', function(argv){\n\t  (dataForWeixin.prepare)(argv);\n      WeixinJSBridge.invoke('shareTimeline',{\n         \"img_url\":dataForWeixin.TLImg,\n         \"img_width\":\"120\",\n         \"img_height\":\"120\",\n         \"link\":dataForWeixin.url,\n         \"desc\":dataForWeixin.desc,\n         \"title\":dataForWeixin.title\n      }, function(res){(dataForWeixin.callback)(res);});\n   });\n   WeixinJSBridge.on('menu:share:weibo', function(argv){\n\t  (dataForWeixin.prepare)(argv);\n      WeixinJSBridge.invoke('shareWeibo',{\n         \"content\":dataForWeixin.title,\n         \"url\":dataForWeixin.url\n      }, function(res){(dataForWeixin.callback)(res);});\n   });\n   WeixinJSBridge.on('menu:share:facebook', function(argv){\n\t  (dataForWeixin.prepare)(argv);\n      WeixinJSBridge.invoke('shareFB',{\n         \"img_url\":dataForWeixin.TLImg,\n         \"img_width\":\"120\",\n         \"img_height\":\"120\",\n         \"link\":dataForWeixin.url,\n         \"desc\":dataForWeixin.desc,\n         \"title\":dataForWeixin.title\n      }, function(res){(dataForWeixin.callback)(res);});\n   });\n};\nif(document.addEventListener){\n   document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false);\n}else if(document.attachEvent){\n   document.attachEvent('WeixinJSBridgeReady'   , onBridgeReady);\n   document.attachEvent('onWeixinJSBridgeReady' , onBridgeReady);\n}\n})();\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/old_version/wechatauth.class.php",
    "content": "<?php\n/**\n *\t微信公众平台PHP-SDK\n *  Wechatauth为非官方微信登陆API\n *  用户通过扫描网页提供的二维码实现登陆信息获取\n *  主要实现如下功能:\n *  get_login_code() 获取登陆授权码, 通过授权码才能获取二维码\n *  get_code_image($code='') 将上面获取的授权码转换为图片二维码\n *  verify_code() 鉴定是否登陆成功,返回200为最终授权成功.\n *  get_login_info() 鉴定成功后调用此方法即可获取用户基本信息\n *  get_avatar($url) 获取用户头像图片数据\n *  @author dodge <dodgepudding@gmail.com>\n *  @link https://github.com/dodgepudding/wechat-php-sdk\n *  @version 1.1\n *  \n */\ninclude \"snoopy.class.php\";\nclass Wechatauth\n{\n\tprivate $cookie;\n\tprivate $skey;\n\tprivate $_cookiename;\n\tprivate $_cookieexpired = 3600;\n\tprivate $_account = 'test';\n\tprivate $_datapath = './data/cookie_';\n\tprivate $debug;\n\tprivate $_logcallback;\n\tpublic $login_user; //当前登陆用户, 调用get_login_info后获取\n\t\n\tpublic function __construct($options)\n\t{\n\t\t$this->_account = isset($options['account'])?$options['account']:'';\n\t\t$this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;\n\t\t$this->debug = isset($options['debug'])?$options['debug']:false;\n\t\t$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;\n\t\t$this->_cookiename = $this->_datapath.$this->_account;\n\t\t$this->getCookie($this->_cookiename);\n\t}\n\t/**\n\t * 把cookie写入缓存\n\t * @param  string $filename 缓存文件名\n\t * @param  string $content  文件内容\n\t * @return bool\n\t */\n\tpublic function saveCookie($filename,$content){\n\t\treturn file_put_contents($filename,$content);\n\t}\n\n\t/**\n\t * 读取cookie缓存内容\n\t * @param  string $filename 缓存文件名\n\t * @return string cookie\n\t */\n\tpublic function getCookie($filename){\n\t\tif (file_exists($filename)) {\n\t\t\t$mtime = filemtime($filename);\n\t\t\tif ($mtime<time()-$this->_cookieexpired) return false;\n\t\t\t$data = file_get_contents($filename);\n\t\t\tif ($data) $this->cookie = $data;\n\t\t} \n\t\treturn $this->cookie;\n\t}\n\t\n\t/*\n\t * 删除cookie\n\t */\n\tpublic function deleteCookie($filename) {\n\t\t$this->cookie = '';\n\t\t@unlink($filename);\n\t\treturn true;\n\t}\n\t\n\tprivate function log($log){\n\t\tif ($this->debug && function_exists($this->_logcallback)) {\n\t\t\tif (is_array($log)) $log = print_r($log,true);\n\t\t\treturn call_user_func($this->_logcallback,$log);\n\t\t}\n\t}\n\t\n\t/**\n\t * 获取登陆二维码对应的授权码\n\t */\n\tpublic function get_login_code(){\n\t\tif ($this->_logincode) return $this->_logincode;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$codeurl = 'https://login.weixin.qq.com/jslogin?appid=wx782c26e4c19acffb&redirect_uri=https%3A%2F%2Fwx.qq.com%2Fcgi-bin%2Fmmwebwx-bin%2Fwebwxnewloginpage&fun=new&lang=zh_CN&_='.$t;\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->fetch($codeurl);\n\t\t$result = $send_snoopy->results;\n\t\tif ($result) {\n\t\t\tpreg_match(\"/window.QRLogin.uuid\\s+=\\s+\\\"([^\\\"]+)\\\"/\",$result,$matches);\n\t\t\tif(count($matches)>1) {\n\t\t\t\t$this->_logincode = $matches[1];\n\t\t\t\t$_SESSION['login_step'] = 0;\n\t\t\t\treturn $this->_logincode;\n\t\t\t}\n\t\t}\n\t\treturn $result;\n\t}\n\n\t/**\n\t * 通过授权码获取对应的二维码图片地址\n\t * @param string $code\n\t * @return string image url\n\t */\n\tpublic function get_code_image($code=''){\n\t\tif ($code=='') $code = $this->_logincode;\n\t\tif (!$code) return false;\n\t\treturn 'http://login.weixin.qq.com/qrcode/'.$this->_logincode.'?t=webwx';\n\t}\n\t\n\t/**\n\t * 设置二维码对应的授权码\n\t * @param string $code\n\t * @return class $this\n\t */\n\tpublic  function set_login_code($code) {\n\t\t$this->_logincode = $code;\n\t\treturn $this;\n\t}\n\t\n\t/**\n\t * 二维码登陆验证\n\t *\n\t * @return status:\n\t * >=400: invaild code; 408: not auth and wait, 400,401: not valid or expired\n\t * 201: just scaned but not confirm\n\t * 200: confirm then you can get user info\n\t */\n\tpublic function verify_code() {\n\t\tif (!$this->_logincode) return false;\n\t\t$t = time().strval(mt_rand(100,999));\n\n\t\t\t$url = 'https://login.weixin.qq.com/cgi-bin/mmwebwx-bin/login?uuid='.$this->_logincode.'&tip=0&_='.$t;\n\t\t\t$send_snoopy = new Snoopy; \n\t\t\t$send_snoopy->referer = \"https://wx.qq.com/\";\n\t\t\t$send_snoopy->fetch($url);\n\t\t\t$result = $send_snoopy->results;\n\t\t\t$this->log('step1:'.$result);\n\t\t\tif ($result) {\n\t\t\t\tpreg_match(\"/window\\.code=(\\d+)/\",$result,$matches);\n\t\t\t\tif(count($matches)>1) {\n\t\t\t\t\t$status = intval($matches[1]);\n\t\t\t\t\tif ($status==201) $_SESSION['login_step'] = 1;\n\t\t\t\t\tif ($status==200) {\n\t\t\t\t\t\tpreg_match(\"/ticket=([0-9a-z-_]+)&lang=zh_CN&scan=(\\d+)/\",$result,$matches);\n\t\t\t\t\t\tpreg_match(\"/window.redirect_uri=\\\"([^\\\"]+)\\\"/\",$result,$matcheurl);\n\t\t\t\t\t\t$this->log('step2:'.print_r($matches,true));\n\t\t\t\t\t\tif (count($matcheurl)>1) {\n\t\t\t\t\t\t\t$ticket = $matches[1];\n\t\t\t\t\t\t\t$scan = $matches[2];\n\t\t\t\t\t\t\t//$loginurl = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxnewloginpage?ticket='.$ticket.'&lang=zh_CN&scan='.$scan.'&fun=new';\n\t\t\t\t\t\t\t$loginurl = str_replace(\"wx.qq.com\", \"wx2.qq.com\", $matcheurl[1]).'&fun=old';\n\t\t\t\t\t\t\t$urlpart = parse_url($loginurl);\n\t\t\t\t\t\t\t$send_snoopy = new Snoopy; \n\t\t\t\t\t\t\t$send_snoopy->referer = \"https://{$urlpart['host']}/cgi-bin/mmwebwx-bin/webwxindex?t=chat\";\n\t\t\t\t\t\t\t$send_snoopy->fetch($loginurl);\n\t\t\t\t\t\t\t$result = $send_snoopy->results;\n\t\t\t\t\t\t\t$xml = simplexml_load_string($result);\n\t\t\t\t\t\t\tif ($xml->ret==\"0\") $this->skey = $xml->skey;\n\t\t\t\t\t\t\tforeach ($send_snoopy->headers as $key => $value) {\n\t\t\t\t\t\t\t\t$value = trim($value);\n\t\t\t\t\t\t\t\tif(strpos($value,'Set-Cookie: ') !== false){\n\t\t\t\t\t\t\t\t\t$tmp = str_replace(\"Set-Cookie: \",\"\",$value);\n\t\t\t\t\t\t\t\t\t$tmparray = explode(';', $tmp);\n\t\t\t\t\t\t\t\t\t$item = trim($tmparray[0]);\n\t\t\t\t\t\t\t\t\t$cookie.=$item.';';\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$cookie .=\"Domain=.qq.com;\";\n\t\t\t\t\t\t\t$this->cookie = $cookie;\n\t\t\t\t\t\t\t$this->log('step3:'.$loginurl.';cookie:'.$cookie.';respond:'.$result);\n\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t$this->saveCookie($this->_cookiename,$this->cookie);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\treturn $status;\n\t\t\t\t}\n\t\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取登陆的cookie\n\t *\n\t * @param bool $is_array 是否以数值方式返回，默认否，返回字符串\n\t * @return string|array\n\t */\n\tpublic function get_login_cookie($is_array = false){\n\t\tif (!$is_array)\treturn $this->cookie;\n\t\t$c_arr = explode(';',$this->cookie);\n\t\t$cookie = array();\n\t\tforeach($c_arr as $item) {\n\t\t\t$kitem = explode('=',trim($item));\n\t\t\tif (count($kitem)>1) {\n\t\t\t\t$key = trim($kitem[0]);\n\t\t\t\t$val = trim($kitem[1]);\n\t\t\t\tif (!empty($val)) $cookie[$key] = $val;\n\t\t\t}\n\t\t}\n\t\treturn $cookie;\n\t}\n\t\n\t/**\n\t * \t 授权登陆后获取用户登陆信息\n\t */\n\tpublic function get_login_info(){\n\t\tif (!$this->cookie) return false;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$send_snoopy = new Snoopy; \n\t\t$submit = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxinit?r='.$t.'&skey='.urlencode($this->skey);\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://wx2.qq.com/\";\n\t\t$citems = $this->get_login_cookie(true);\n\t\t$post = array(\n\t\t\t\"BaseRequest\"=>array(\n\t\t\t\tarray(\n\t\t\t\t\t\"Uin\"=>$citems['wxuin'],\n\t\t\t\t\t\"Sid\"=>$citems['wxsid'],\n\t\t\t\t\t\"Skey\"=>$this->skey,\n\t\t\t\t\t\"DeviceID\"=>''\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\t\t$send_snoopy->submit($submit,json_encode($post));\n\t\t$this->log('login_info:'.$send_snoopy->results);\n\t\t$result = json_decode($send_snoopy->results,true);\n\t\tif ($result['BaseResponse']['Ret']<0) return false;\n\t\t$this->_login_user = $result['User'];\n\t\treturn $result;\n\t}\n\t\n\t/**\n\t *  获取头像\n\t *  @param string $url 传入从用户信息接口获取到的头像地址\n\t */\n\tpublic function get_avatar($url) {\n\t\tif (!$this->cookie) return false;\n\t\tif (strpos($url, 'http')===false) {\n\t\t\t$url = 'http://wx2.qq.com'.$url;\n\t\t}\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://wx2.qq.com/\";\n\t\t$send_snoopy->fetch($url);\n\t\t$result = $send_snoopy->results;\n\t\tif ($result) \n\t\t\treturn $result;\n\t\telse\n\t\t\treturn false;\n\t}\n\t\n\t/**\n\t * 登出当前登陆用户\n\t */\n\tpublic function logout(){\n\t\tif (!$this->cookie) return false;\n\t\tpreg_match(\"/wxuin=(\\w+);/\",$this->cookie,$matches);\n\t\tif (count($matches)>1) $uid = $matches[1];\n\t\tpreg_match(\"/wxsid=(\\w+);/\",$this->cookie,$matches);\n\t\tif (count($matches)>1) $sid = $matches[1];\n\t\t$this->log('logout: uid='.$uid.';sid='.$sid);\n\t\t$send_snoopy = new Snoopy; \n\t\t$submit = 'https://wx2.qq.com/cgi-bin/mmwebwx-bin/webwxlogout?redirect=1&type=1';\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://wx2.qq.com/\";\n\t\t$send_snoopy->submit($submit,array('uin'=>$uid,'sid'=>$sid));\n\t\t$this->deleteCookie($this->_cookiename);\n\t\treturn true;\n\t}\n}"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/old_version/wechatext.class.php",
    "content": "<?php\n/**\n *\t微信公众平台PHP-SDK\n *  Wechatext为非官方微信发送API\n *  注: 用户id为通过getMsg()方法获取的FakeId值\n *  主要实现如下功能:\n *  send($id,$content) 向某用户id发送微信文字信息\n *  getUserList($page,$pagesize,$groupid) 获取用户信息\n *  getGroupList($page,$pagesize) 获取群组信息\n *  sendNews($id,$msgid) 发送图文消息\n *  getNewsList($page,$pagesize) 获取图文信息列表\n *  uploadFile($filepath,$type) 上传附件,包括图片/音频/视频\n *  addPreview($title,$author,$summary,$content,$photoid,$srcurl='')   创建新的图文信息 \n *  getFileList($type,$page,$pagesize) 获取素材库文件列表\n *  sendImage($id,$fid) 发送图片消息\n *  sendAudio($id,$fid) 发送音频消息\n *  sendVideo($id,$fid) 发送视频消息\n *  getInfo($id) 根据id获取用户资料\n *  getNewMsgNum($lastid) 获取从$lastid算起新消息的数目\n *  getTopMsg() 获取最新一条消息的数据, 此方法获取的消息id可以作为检测新消息的$lastid依据\n *  getMsg($lastid,$offset=0,$perpage=50,$day=0,$today=0,$star=0) 获取最新的消息列表, 列表将返回消息id, 用户id, 消息类型, 文字消息等参数\n *  消息返回结构:  {\"id\":\"消息id\",\"type\":\"类型号(1为文字,2为图片,3为语音)\",\"fileId\":\"0\",\"hasReply\":\"0\",\"fakeId\":\"用户uid\",\"nickName\":\"昵称\",\"dateTime\":\"时间戳\",\"content\":\"文字内容\"} \n *  getMsgImage($msgid,$mode='large') 若消息type类型为2, 调用此方法获取图片数据\n *  getMsgVoice($msgid) 若消息type类型为3, 调用此方法获取语音数据\n *  quickSetInterface($url, $token) 快速设置接口信息\n *  getCommonInfo($dir) 获取公众账号基本信息, 其中包含：nickname,avatar,type,qrcode,appid,appsecret\n *  @author dodge <dodgepudding@gmail.com>\n *  @link https://github.com/dodgepudding/wechat-php-sdk\n *  @version 1.2\n *  \n */\n\ninclude \"snoopy.class.php\";\nclass Wechatext\n{\n\tprivate $cookie;\n\tprivate $_cookiename;\n\tprivate $_cookieexpired = 3600;\n\tprivate $_account;\n\tprivate $_password;\n\tprivate $_datapath = './data/cookie_';\n\tprivate $debug;\n\tprivate $_logcallback;\n\tprivate $_token;\n\t\n\tpublic function __construct($options)\n\t{\n\t\t$this->_account = isset($options['account'])?$options['account']:'';\n\t\t$this->_password = isset($options['password'])?$options['password']:'';\n\t\t$this->_datapath = isset($options['datapath'])?$options['datapath']:$this->_datapath;\n\t\t$this->debug = isset($options['debug'])?$options['debug']:false;\n\t\t$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;\n\t\t$this->_cookiename = $this->_datapath.$this->_account;\n\t\t$this->cookie = $this->getCookie($this->_cookiename);\n\t}\n\n\t/**\n\t * 主动发消息\n\t * @param  string $id      用户的uid(即FakeId)\n\t * @param  string $content 发送的内容\n\t */\n\tpublic function send($id,$content)\n\t{\n\t\t$send_snoopy = new Snoopy; \n\t\t$post = array();\n\t\t$post['tofakeid'] = $id;\n\t\t$post['type'] = 1;\n\t\t$post['token'] = $this->_token;\n\t\t$post['content'] = $content;\n\t\t$post['ajax'] = 1;\n        $send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/singlesendpage?t=message/send&action=index&tofakeid=$id&token={$this->_token}&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response\";\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$this->log($send_snoopy->results);\n\t\treturn $send_snoopy->results;\n\t}\n\t\n\t/**\n\t * 群发功能 纯文本\n\t * @param string $content\n\t * @return string\n\t */\n\tpublic function mass($content) {\n\t\t$send_snoopy = new Snoopy;\n\t\t$post = array();\n\t\t$post['type'] = 1;\n\t\t$post['token'] = $this->_token;\n\t\t$post['content'] = $content;\n\t\t$post['ajax'] = 1;\n\t\t$post['city']='';\n\t\t$post['country']='';\n\t\t$post['f']='json';\n\t\t$post['groupid']='-1';\n\t\t$post['imgcode']='';\n\t\t$post['lang']='zh_CN';\n\t\t$post['province']='';\n\t\t$post['random']=  rand(0, 1);\n\t\t$post['sex']=0;\n\t\t$post['synctxnews']=0;\n\t\t$post['synctxweibo']=0;\n\t\t$post['t']='ajax-response';\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token={$this->_token}&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/masssend\";\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$this->log($send_snoopy->results);\n\t\treturn $send_snoopy->results;\n\t}\n\t\n\t/**\n\t * 群发功能 图文素材\n\t * @param int $appmsgid 图文素材ID\n\t * @return string\n\t */\n\tfunction massNews($appmsgid){\n\t\t$send_snoopy = new Snoopy;\n\t\t$post = array();\n\t\t$post['type'] = 10;\n\t\t$post['token'] = $this->_token;\n\t\t$post['appmsgid'] = $appmsgid;\n\t\t$post['ajax'] = 1;\n\t\t$post['city']='';\n\t\t$post['country']='';\n\t\t$post['f']='json';\n\t\t$post['groupid']='-1';\n\t\t$post['imgcode']='';\n\t\t$post['lang']='zh_CN';\n\t\t$post['province']='';\n\t\t$post['random']=  rand(0, 1);\n\t\t$post['sex']=0;\n\t\t$post['synctxnews']=0;\n\t\t$post['synctxweibo']=0;\n\t\t$post['t']='ajax-response';\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token={$this->_token}&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/masssend\";\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$this->log($send_snoopy->results);\n\t\treturn $send_snoopy->results;\n\t}\n\t\n\t/**\n\t * 获取用户列表列表\n\t * @param $page 页码(从0开始)\n\t * @param $pagesize 每页大小\n\t * @param $groupid 分组id\n\t * @return array ({contacts:[{id:12345667,nick_name:\"昵称\",remark_name:\"备注名\",group_id:0},{}....]})\n\t */\n\tfunction getUserList($page=0,$pagesize=10,$groupid=0){\n\t\t$send_snoopy = new Snoopy;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=\".$pagesize.\"&pageidx=\".$page.\"&type=0&groupid=0&lang=zh_CN&token=\".$this->_token;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=\".$pagesize.\"&pageidx=\".$page.\"&type=0&groupid=$groupid&lang=zh_CN&f=json&token=\".$this->_token;\n\t\t$send_snoopy->fetch($submit);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('userlist:'.$result);\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['contact_list'])) {\n\t\t\t$json = json_decode($json['contact_list'],true);\n\t\t\tif (isset($json['contacts']))\n\t\t\t\treturn $json['contacts'];\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取分组列表\n\t * \n\t */\n\tfunction getGroupList(){\n\t\t$send_snoopy = new Snoopy;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=0&lang=zh_CN&token=\".$this->_token;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/contactmanage?t=user/index&pagesize=10&pageidx=0&type=0&groupid=0&lang=zh_CN&f=json&token=\".$this->_token;\n\t\t$send_snoopy->fetch($submit);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('userlist:'.$result);\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['group_list'])){\n\t\t\t$json = json_decode($json['group_list'],true);\n\t\t\tif (isset($json['groups']))\n\t\t\t\treturn $json['groups'];\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取图文信息列表\n\t * @param $page 页码(从0开始)\n\t * @param $pagesize 每页大小\n\t * @return array\n\t */\n\tpublic function getNewsList($page,$pagesize=10) {\n\t\t$send_snoopy = new Snoopy;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$type=10;\n\t\t$begin = $page*$pagesize;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=\".$this->_token.\"&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/appmsg?token=\".$this->_token.\"&lang=zh_CN&type=$type&action=list&begin=$begin&count=$pagesize&f=json&random=0.\".$t;\n\t\t$send_snoopy->fetch($submit);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('newslist:'.$result);\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['app_msg_info'])) {\n\t\t\treturn $json['app_msg_info'];\n\t\t} \n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取与指定用户的对话内容\n\t * @param  $fakeid\n\t * @return  array\n\t */\n\tpublic function getDialogMsg($fakeid) {\n\t\t$send_snoopy = new Snoopy;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=\".$this->_token.\"&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/singlesendpage?t=message/send&action=index&tofakeid=\".$fakeid.\"&token=\".$this->_token.\"&lang=zh_CN&f=json&random=\".$t;\n\t\t$send_snoopy->fetch($submit);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('DialogMsg:'.$result);\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['page_info'])) {\n\t\t\treturn $json['page_info'];\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 发送图文信息,必须从图文库里选取消息ID发送\n\t * @param  string $id      用户的uid(即FakeId)\n\t * @param  string $msgid 图文消息id\n\t */\n\tpublic function sendNews($id,$msgid)\n\t{\n\t\t$send_snoopy = new Snoopy; \n\t\t$post = array();\n\t\t$post['tofakeid'] = $id;\n\t\t$post['type'] = 10;\n\t\t$post['token'] = $this->_token;\n\t\t$post['fid'] = $msgid;\n\t\t$post['appmsgid'] = $msgid;\n\t\t$post['error'] = 'false';\n\t\t$post['ajax'] = 1;\n        $send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/singlemsgpage?fromfakeid={$id}&msgid=&source=&count=20&t=wxm-singlechat&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response\";\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$this->log($send_snoopy->results);\n\t\treturn $send_snoopy->results;\n\t}\n\t\n\t/**\n\t * 上传附件(图片/音频/视频)\n\t * @param string $filepath 本地文件地址\n\t * @param int $type 文件类型: 2:图片 3:音频 4:视频\n\t */\n\tpublic function uploadFile($filepath,$type=2) {\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->referer = \"http://mp.weixin.qq.com/cgi-bin/indexpage?t=wxm-upload&lang=zh_CN&type=2&formId=1\";\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$post = array('formId'=>'');\n\t\t$postfile = array('uploadfile'=>$filepath);\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->set_submit_multipart();\n\t\t$submit = \"http://mp.weixin.qq.com/cgi-bin/uploadmaterial?cgi=uploadmaterial&type=$type&token=\".$this->_token.\"&t=iframe-uploadfile&lang=zh_CN&formId=\tfile_from_\".$t;\n\t\t$send_snoopy->submit($submit,$post,$postfile);\n\t\t$tmp = $send_snoopy->results;\n\t\t$this->log('upload:'.$tmp);\n\t\tpreg_match(\"/formId,.*?\\'(\\d+)\\'/\",$tmp,$matches);\n\t\tif (isset($matches[1])) {\n\t\t\treturn $matches[1];\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 创建图文消息\n\t * @param array $title 标题\n\t * @param array $summary 摘要\n\t * @param array $content 内容\n\t * @param array $photoid 素材库里的图片id(可通过uploadFile上传后获取)\n\t * @param array $srcurl 原文链接\n\t * @return json\n\t */\n\tpublic function addPreview($title,$author,$summary,$content,$photoid,$srcurl='') {\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->referer = 'https://mp.weixin.qq.com/cgi-bin/operate_appmsg?lang=zh_CN&sub=edit&t=wxm-appmsgs-edit-new&type=10&subtype=3&token='.$this->_token;\n\t\t\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/operate_appmsg?lang=zh_CN&t=ajax-response&sub=create&token=\".$this->_token;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t\n\t\t$send_snoopy->set_submit_normal();\n\t\t$post = array(\n\t\t\t\t'token'=>$this->_token,\n\t\t\t\t'type'=>10,\n\t\t\t\t'lang'=>'zh_CN',\n\t\t\t\t'sub'=>'create',\n\t\t\t\t'ajax'=>1,\n\t\t\t\t'AppMsgId'=>'',\t\t\t\t\n\t\t\t\t'error'=>'false',\n\t\t);\n\t\tif (count($title)==count($author)&&count($title)==count($summary)&&count($title)==count($content)&&count($title)==count($photoid))\n\t\t{\n\t\t\t$i = 0;\n\t\t\tforeach($title as $v) {\n\t\t\t\t$post['title'.$i] = $title[$i];\n\t\t\t\t$post['author'.$i] = $author[$i];\n\t\t\t\t$post['digest'.$i] = $summary[$i];\n\t\t\t\t$post['content'.$i] = $content[$i];\n\t\t\t\t$post['fileid'.$i] = $photoid[$i];\n\t\t\t\tif ($srcurl[$i]) $post['sourceurl'.$i] = $srcurl[$i];\n\t\t\t\t\n\t\t\t\t$i++;\n\t\t\t\t}\n\t\t}\n\t\t$post['count'] = $i;\n\t\t$post['token'] = $this->_token;\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$tmp = $send_snoopy->results;\n\t\t$this->log('step2:'.$tmp);\n\t\t$json = json_decode($tmp,true);\n\t\treturn $json;\n\t}\n\t\n\t/**\n\t * 发送媒体文件\n\t * @param $id 用户的uid(即FakeId)\n\t * @param $fid 文件id\n\t * @param $type 文件类型\n\t */\n\tpublic function sendFile($id,$fid,$type) {\n\t\t$send_snoopy = new Snoopy; \n\t\t$post = array();\n\t\t$post['tofakeid'] = $id;\n\t\t$post['type'] = $type;\n\t\t$post['token'] = $this->_token;\n\t\t$post['fid'] = $fid;\n\t\t$post['fileid'] = $fid;\n\t\t$post['error'] = 'false';\n\t\t$post['ajax'] = 1;\n        $send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/singlemsgpage?fromfakeid={$id}&msgid=&source=&count=20&t=wxm-singlechat&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/singlesend?t=ajax-response\";\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('sendfile:'.$result);\n\t\t$json = json_decode($result,true);\n\t\tif ($json && $json['ret']==0) \n\t\t\treturn true;\n\t\telse\n\t\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取素材库文件列表\n\t * @param $type 文件类型: 2:图片 3:音频 4:视频\n\t * @param $page 页码(从0开始)\n\t * @param $pagesize 每页大小\n\t * @return array\n\t */\n\tpublic function getFileList($type,$page,$pagesize=10) {\n\t\t$send_snoopy = new Snoopy;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$begin = $page*$pagesize;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/masssendpage?t=mass/send&token=\".$this->_token.\"&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/filepage?token=\".$this->_token.\"&lang=zh_CN&type=$type&random=0.\".$t.\"&begin=$begin&count=$pagesize&f=json\";\n\t\t$send_snoopy->fetch($submit);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('filelist:'.$result);\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['page_info']))\n\t\t\treturn $json['page_info'];\n\t\telse\n\t\t\treturn false;\n\t}\n\t\n\t/**\n\t * 发送图文信息,必须从库里选取文件ID发送\n\t * @param  string $id      用户的uid(即FakeId)\n\t * @param  string $fid 文件id\n\t */\n\tpublic function sendImage($id,$fid)\n\t{\n\t\treturn $this->sendFile($id,$fid,2);\n\t}\n\t\n\t/**\n\t * 发送语音信息,必须从库里选取文件ID发送\n\t * @param  string $id      用户的uid(即FakeId)\n\t * @param  string $fid 语音文件id\n\t */\n\tpublic function sendAudio($id,$fid)\n\t{\n\t\treturn $this->sendFile($id,$fid,3);\n\t}\n\t\n\t/**\n\t * 发送视频信息,必须从库里选取文件ID发送\n\t * @param  string $id      用户的uid(即FakeId)\n\t * @param  string $fid 视频文件id\n\t */\n\tpublic function sendVideo($id,$fid)\n\t{\n\t\treturn $this->sendFile($id,$fid,4);\n\t}\n\t\n\t/**\n\t * 发送预览图文消息\n\t * @param string $account 账户名称(user_name)\n\t * @param string $title 标题\n\t * @param string $summary 摘要\n\t * @param string $content 内容\n\t * @param string $photoid 素材库里的图片id(可通过uploadFile上传后获取)\n\t * @param string $srcurl 原文链接\n\t * @return json\n\t */\n\tpublic function sendPreview($account,$title,$summary,$content,$photoid,$srcurl='') {\n\t\t$send_snoopy = new Snoopy;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/operate_appmsg?sub=preview&t=ajax-appmsg-preview\";\n\t\t$send_snoopy->set_submit_normal();\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = 'https://mp.weixin.qq.com/cgi-bin/operate_appmsg?sub=edit&t=wxm-appmsgs-edit-new&type=10&subtype=3&lang=zh_CN';\n\t\t$post = array(\n\t\t\t\t'AppMsgId'=>'',\n\t\t\t\t'ajax'=>1,\n\t\t\t\t'content0'=>$content,\n\t\t\t\t'count'=>1,\n\t\t\t\t'digest0'=>$summary,\n\t\t\t\t'error'=>'false',\n\t\t\t\t'fileid0'=>$photoid,\n\t\t\t\t'preusername'=>$account,\n\t\t\t\t'sourceurl0'=>$srcurl,\n\t\t\t\t'title0'=>$title,\n\t\t);\n\t\t$post['token'] = $this->_token;\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$tmp = $send_snoopy->results;\n\t\t$this->log('sendpreview:'.$tmp);\n\t\t$json = json_decode($tmp,true);\n\t\treturn $json;\n\t}\n\t\n\t/**\n\t * 获取用户的信息\n\t * @param  string $id 用户的uid(即FakeId)\n\t * @return array  {fake_id:100001,nick_name:'昵称',user_name:'用户名',signature:'签名档',country:'中国',province:'广东',city:'广州',gender:'1',group_id:'0'},groups:{[id:0,name:'未分组',cnt:20]}\n\t */\n\tpublic function getInfo($id)\n\t{\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$t = time().strval(mt_rand(100,999));\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=\".$this->_token;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/getcontactinfo\";\n\t\t$post = array('ajax'=>1,'lang'=>'zh_CN','random'=>'0.'.$t,'token'=>$this->_token,'t'=>'ajax-getcontactinfo','fakeid'=>$id);\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$this->log($send_snoopy->results);\n\t\t$result = json_decode($send_snoopy->results,true);\n\t\tif(isset($result['contact_info'])){\n\t\t\treturn $result['contact_info'];\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获得头像数据\n\t *\n\t * @param FakeId $fakeid\n\t * @return JPG二进制数据\n\t */\n\tpublic function getHeadImg($fakeid){\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=\".$this->_token;\n\t\t$url = \"https://mp.weixin.qq.com/misc/getheadimg?fakeid=$fakeid&token=\".$this->_token.\"&lang=zh_CN\";\n\t\t$send_snoopy->fetch($url);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('Head image:'.$fakeid.'; length:'.strlen($result));\n\t\tif(!$result){\n\t\t\treturn false;\n\t\t}\n\t\treturn $result;\n\t}\n\n\t/**\n\t * 获取消息更新数目\n\t * @param int $lastid 最近获取的消息ID,为0时获取总消息数目\n\t * @return int 数目\n\t */\n\tpublic function getNewMsgNum($lastid=0){\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=\".$this->_token;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/getnewmsgnum?t=ajax-getmsgnum&lastmsgid=\".$lastid;\n\t\t$post = array('ajax'=>1,'token'=>$this->_token);\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$this->log($send_snoopy->results);\n\t\t$result = json_decode($send_snoopy->results,1);\n\t\tif(!$result){\n\t\t\treturn false;\n\t\t}\n\t\treturn intval($result['newTotalMsgCount']);\n\t}\n\t\n\t/**\n\t * 获取最新一条消息\n\t * @return array {\"id\":\"最新一条id\",\"type\":\"类型号(1为文字,2为图片,3为语音)\",\"fileId\":\"0\",\"hasReply\":\"0\",\"fakeId\":\"用户uid\",\"nickName\":\"昵称\",\"dateTime\":\"时间戳\",\"content\":\"文字内容\",\"playLength\":\"0\",\"length\":\"0\",\"source\":\"\",\"starred\":\"0\",\"status\":\"4\"}        \n\t */\n\tpublic function getTopMsg(){\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=20&day=7&lang=zh_CN&token=\".$this->_token;\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/message?t=message/list&f=json&count=20&day=7&lang=zh_CN&token=\".$this->_token;\n\t\t$send_snoopy->fetch($submit);\n\t\t$this->log($send_snoopy->results);\n\t\t$result = $send_snoopy->results;\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['msg_items'])) {\n\t\t\t$json = json_decode($json['msg_items'],true);\n\t\t\tif(isset($json['msg_item']))\n\t\t\t\treturn array_shift($json['msg_item']);\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取新消息\n\t * @param $lastid 传入最后的消息id编号,为0则从最新一条起倒序获取\n\t * @param $offset lastid起算第一条的偏移量\n\t * @param $perpage 每页获取多少条\n\t * @param $day 最近几天消息(0:今天,1:昨天,2:前天,3:更早,7:五天内)\n\t * @param $today 是否只显示今天的消息, 与$day参数不能同时大于0\n\t * @param $star 是否星标组信息\n\t * @return array[] 同getTopMsg()返回的字段结构相同\n\t */\n\tpublic function getMsg($lastid=0,$offset=0,$perpage=20,$day=7,$today=0,$star=0){\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/message?t=message/list&lang=zh_CN&count=50&token=\".$this->_token;\n\t\t$lastid = $lastid===0 ? '':$lastid;\n\t\t$addstar = $star?'&action=star':'';\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/message?t=message/list&f=json&lang=zh_CN{$addstar}&count=$perpage&timeline=$today&day=$day&frommsgid=$lastid&offset=$offset&token=\".$this->_token;\n\t\t$send_snoopy->fetch($submit);\n\t\t$this->log($send_snoopy->results);\n\t\t$result = $send_snoopy->results;\n\t\t$json = json_decode($result,true);\n\t\tif (isset($json['msg_items'])) {\n\t\t\t$json = json_decode($json['msg_items'],true);\n\t\t\tif(isset($json['msg_item']))\n\t\t\t\treturn $json['msg_item'];\n\t\t}\n\t\treturn false;\n\t}\n\t\n\t/**\n\t * 获取图片消息\n\t * @param int $msgid 消息id\n\t * @param string $mode 图片尺寸(large/small)\n\t * @return jpg二进制文件\n\t */\n\tpublic function getMsgImage($msgid,$mode='large'){\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=\".$this->_token;\n\t\t$url = \"https://mp.weixin.qq.com/cgi-bin/getimgdata?token=\".$this->_token.\"&msgid=$msgid&mode=$mode&source=&fileId=0\";\n\t\t$send_snoopy->fetch($url);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('msg image:'.$msgid.';length:'.strlen($result));\n\t\tif(!$result){\n\t\t\treturn false;\n\t\t}\n\t\treturn $result;\n\t}\n\t\n\t/**\n\t * 获取语音消息\n\t * @param int $msgid 消息id\n\t * @return mp3二进制文件\n\t */\n\tpublic function getMsgVoice($msgid){\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/getmessage?t=wxm-message&lang=zh_CN&count=50&token=\".$this->_token;\n\t\t$url = \"https://mp.weixin.qq.com/cgi-bin/getvoicedata?token=\".$this->_token.\"&msgid=$msgid&fileId=0\";\n\t\t$send_snoopy->fetch($url);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log('msg voice:'.$msgid.';length:'.strlen($result));\n\t\tif(!$result){\n\t\t\treturn false;\n\t\t}\n\t\treturn $result;\n\t}\n\n\t/**\n\t * 开启开发者模式\n\t */\n\tpublic function openDevModel()\n\t{\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&lang=zh_CN&token=\".$this->_token;\n\t\t$submit = \"https://mp.weixin.qq.com/misc/skeyform?form=advancedswitchform&lang=zh_CN\";\n\t\t$post['flag']=1;\n        $post['type']=2;   \n        $post['token']=$this->_token;\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log($send_snoopy->results);\n\t\t$json = json_decode($result,true);\n\t\tif(!$result){\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * 关闭编辑模式\n\t */\n\tpublic function closeEditModel()\n\t{\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&lang=zh_CN&token=\".$this->_token;\n\t\t$submit = \"https://mp.weixin.qq.com/misc/skeyform?form=advancedswitchform&lang=zh_CN\";\n\t\t$post['flag']=0;\n        $post['type']=1;   \n        $post['token']=$this->_token;\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log($send_snoopy->results);\n\t\t$json = json_decode($result,true);\n\t\tif(!$result){\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * 配置接口信息\n\t * @param  string $url      接口回调URL\n\t * @param  string $token    接口Token\n\t */\n\tpublic function setUrlToken($url, $token)\n\t{\n\t\t$send_snoopy = new Snoopy;\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/advanced/advanced?action=interface&t=advanced/interface&lang=zh_CN&token=\".$this->_token;\n\t\t$submit = \"https://mp.weixin.qq.com/advanced/callbackprofile?t=ajax-response&lang=zh_CN&token=\".$this->_token;\n\t\t$post['url'] = $url;\n\t\t$post['callback_token'] = $token;\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$result = $send_snoopy->results;\n\t\t$this->log($send_snoopy->results);\n\t\t$json = json_decode($result,true);\n\t\tif ($json && $json['ret']==0) \n\t\t\treturn true;\n\t\treturn false;\n\t}\n\n\t/**\n\t * 快速设置接口\n\t * @param  string $url      接口回调URL\n\t * @param  string $token    接口Token\n\t */\n\tpublic function quickSetInterface($url, $token)\n\t{\n\t\tif ($this->closeEditModel() && $this->openDevModel() && $this->setUrlToken($url, $token))\n\t\t\treturn true;\n\t\treturn false;\n\t}\n\n\t/**\n\t * 获取公众账号基本信息\n\t * @param  [string] $dir [指定相对于网站根目录的下载路径，因为需要下载二维码和用户头像]\n\t * @return [array]       [公众账号信息，其中包含：nickname,avatar,type,qrcode,appid,appsecret]\n\t */\n\tpublic function getCommonInfo($dir)\n\t{\n\t\t$userInfo = array();\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=20&day=7&lang=zh_CN&token=\".$this->_token;\n\t\t$url = \"https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token=\".$this->_token;\n\t\t$send_snoopy->fetch($url);\n\t\t$result = $send_snoopy->results;\n\t\t// 分析首页内容，获取nickname,avatar,usertype\n\t\tpreg_match_all('/class=\\\"nickname\\\">(.*)<\\/a>/', $result, $matches1);\n        preg_match_all('/<img src=\\\"(.*)\\\" class=\\\"avatar\\\"/', $result, $matches2);\n        preg_match_all('/<label for=\\\"\\\" class=\\\"type icon_service_label\\\">(.*)<\\/label>/', $result, $matches3);\n        $userInfo[\"nickname\"] = $nickname = $matches1[1][0];\n        if(strpos($nickname, '<') !== false)\n        {\n        \t$userInfo[\"nickname\"] = $nickname = substr($nickname, 0, strpos($nickname, '<'));\n        }\n        $userInfo[\"avatar\"] = $avatar = $matches2[1][0];\n        if( ! empty($matches3[1][0]))\n        {\n            $userInfo[\"type\"] = $usertype = $matches3[1][0];\n        }\n        else\n        {\n            $userInfo[\"type\"] = $usertype = \"订阅号\";\n        }\n\t\t$this->log('Analysis account info:'. \"\\nNickname:\". $nickname. \"\\nAvatar:\". $avatar. \"\\nUsertype:\". $usertype);\n\t\t// 分析设置页面，获取二维码\n\t\t$send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/message?t=message/list&count=20&day=7&lang=zh_CN&token=\".$this->_token;\n\t\t$url = \"https://mp.weixin.qq.com/cgi-bin/settingpage?t=setting/index&action=index&lang=zh_CN&token=\".$this->_token;\n\t\t$send_snoopy->fetch($url);\n\t\t$result = $send_snoopy->results;\n\t\t// $this->log(\"QRCODE contents:\". $result);\n\t\tpreg_match_all('/<img src=\\\"(.*)\\\" width=\\\"150\\\"/', $result, $matches4);\n        $userInfo[\"qrcode\"] = $qrcode = $matches4[1][0];\n        // downloads the avatar\n        $send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/settingpage?t=setting/index&action=index&lang=zh_CN&token=\".$this->_token;\n\t\t$url = \"https://mp.weixin.qq.com\". $avatar;\n\t\t$send_snoopy->fetch($url);\n\t\t$result = $send_snoopy->results;\n        $userInfo[\"avatar\"] = $this->downloadImage($result, $dir. DIRECTORY_SEPARATOR. 'avatars');\n        // downloads the qrcode\n        $send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/settingpage?t=setting/index&action=index&lang=zh_CN&token=\".$this->_token;\n\t\t$url = \"https://mp.weixin.qq.com\". $qrcode;\n\t\t$send_snoopy->fetch($url);\n\t\t$result = $send_snoopy->results;\n        $userInfo[\"qrcode\"] = $this->downloadImage($result, $dir. DIRECTORY_SEPARATOR. 'qrcodes');\n        // 获取appid和appsecret\n        $send_snoopy = new Snoopy; \n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->referer = \"https://mp.weixin.qq.com/cgi-bin/settingpage?t=setting/index&action=index&lang=zh_CN&token=\".$this->_token;\n\t\t$url = \"https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&lang=zh_CN&token=\".$this->_token;\n\t\t$send_snoopy->fetch($url);\n\t\t$result = $send_snoopy->results;\n\n\t\tpreg_match_all('/name:\\\"AppId\\\",value:\\\"(.*)\\\"/', $result, $matches_id);\n\t\tpreg_match_all('/name:\\\"AppSecret\\\",value:\\\"(.*)\\\"/', $result, $matches_secret);\n\t\t\n        $userInfo[\"appid\"] = $AppId = $matches_id[1][0];\n        $userInfo[\"appsecret\"] = $AppSecret = $matches_secret[1][0];\n        \n\t\tif(! empty($userInfo)){\n\t\t\treturn $userInfo;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 下载图片资源\n\t * @param  [string] $from    [资源链接]\n\t * @param  [string] $dir     [相对于网站根目录]\n\t * @return [string]          [返回相对地址]\n\t */\n\tpublic function downloadImage($from, $dir)\n\t{\n\t    $random_name =  str_replace('.', '', microtime(true)). rand(2, 10000);\n\t    if( ! is_dir($dir))\n\t    {\n\t    \tmkdir($dir, 0755, true);\t\n\t    }\n\t    $savefile = preg_replace('/[\\\\\\\\\\/]+/', DIRECTORY_SEPARATOR, $dir. '/'. $random_name);\n\t    file_put_contents($savefile, $from);\n\t    $filesize = filesize($savefile);\n\t    $avatar_type = $this->checkImgType($savefile);\n\t    if ($filesize <= 0 || $avatar_type=='unknown') \n\t    {\n\t        unlink($savefile);\n\t    }\n\t    exec(\"mv $savefile \". $savefile. '.'. $avatar_type);\n\t    return $dir. '/'. $random_name. '.'. $avatar_type;\n\t}\n\n\t/**\n\t * 检测图片类型\n\t * @param  [string] $imgName [文件路径]\n\t * @return [string]          [文件类型]\n\t */\n\tpublic function checkImgType($imgName){\n\t    $file = fopen($imgName, \"rb\");\n\t    $bin = fread($file, 2);\n\t    $strInfo  = @unpack(\"C2chars\", $bin);\n\t    $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);\n\t    switch($typeCode)\n\t    {\n\t        case '255216':\n\t            return 'jpg';\n\t            break;\n\t        case '7173':\n\t            return 'gif';\n\t            break;\n\t        case '13780':\n\t            return 'png';\n\t            break;\n\t        case '6677':\n\t            return 'bmp';\n\t            break;\n\t        default:\n\t            return 'unknown';\n\t            break;\n\t    }\n\t}\n\t\n\t/**\n\t * 模拟登录获取cookie\n\t * @return [type] [description]\n\t */\n\tpublic function login(){\n\t\t$snoopy = new Snoopy; \n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN\";\n\t\t$post[\"username\"] = $this->_account;\n\t\t$post[\"pwd\"] = md5($this->_password);\n\t\t$post[\"f\"] = \"json\";\n\t\t$post[\"imgcode\"] = \"\";\n\t\t$snoopy->referer = \"https://mp.weixin.qq.com/\";\n\t\t$snoopy->submit($submit,$post);\n\t\t$cookie = '';\n\t\t$this->log($snoopy->results);\n\t\t$result = json_decode($snoopy->results,true);\n\t\t\n\t\tif (!isset($result['base_resp']) || $result['base_resp']['ret'] != 0) {\n\t\t\treturn false;\n\t\t}\n        \n\t\tforeach ($snoopy->headers as $key => $value) {\n\t\t\t$value = trim($value);\n\t\t\tif(preg_match('/^set-cookie:[\\s]+([^=]+)=([^;]+)/i', $value,$match))\n\t\t\t\t$cookie .=$match[1].'='.$match[2].'; ';\n\t\t}\n\t\t\n\t\tpreg_match(\"/token=(\\d+)/i\",$result['redirect_url'],$matches);\n\t\tif($matches){\n\t\t\t$this->_token = $matches[1];\n\t\t\t$this->log('token:'.$this->_token);\n\t\t}\n\t\t$cookies='{\"cookie\":\"'.$cookie.'\",\"token\":\"'.$this->_token.'\"}';\n\t\t$this->saveCookie($this->_cookiename,$cookies);\n\t\treturn $cookie;\n\t}\n\n\t/**\n\t * 把cookie写入缓存\n\t * @param  string $filename 缓存文件名\n\t * @param  string $content  文件内容\n\t * @return bool\n\t */\n\tpublic function saveCookie($filename,$content){\n\t\treturn file_put_contents($filename,$content);\n\t}\n\n\t/**\n\t * 读取cookie缓存内容\n\t * @param  string $filename 缓存文件名\n\t * @return string cookie\n\t */\n\tpublic function getCookie($filename){\n\t\tif (file_exists($filename)) {\n\t\t\t$mtime = filemtime($filename);\n\t\t\tif ($mtime<time()-$this->_cookieexpired) \n\t\t\t\t$data = '';\n\t\t\telse\n\t\t\t\t$data = file_get_contents($filename);\n\t\t} else\n\t\t\t$data = '';\n\t\tif($data){\n\t\t\t$login=json_decode($data,true);\n\t\t\t$send_snoopy = new Snoopy;\n\t\t\t$send_snoopy->rawheaders['Cookie']= $login['cookie'];\n\t\t\t$send_snoopy->maxredirs = 0;\n\t\t\t$url = \"https://mp.weixin.qq.com/cgi-bin/home?t=home/index&lang=zh_CN&token=\".$login['token'];\n\t\t\t$send_snoopy->fetch($url);\n\t\t\t$header = $send_snoopy->headers;\n\t\t\t$this->log('header:'.print_r($send_snoopy->headers,true));\n\t\t\tif( strstr($header[3], 'EXPIRED')){\n\t\t\t\treturn $this->login();\n\t\t\t}else{\n\t\t\t\t$this->_token =$login['token'];\n\t\t\t\t$this->log('token:'.$this->_token);\n\t\t\t\treturn $login['cookie'];\n\t\t\t}\n\t\t}else{\n\t\t\treturn $this->login();\n\t\t}\n\t}\n\n\t/**\n\t * 验证cookie的有效性\n\t * @return bool\n\t */\n\tpublic function checkValid()\n\t{\n\t\tif (!$this->cookie || !$this->_token) return false;\n\t\t$send_snoopy = new Snoopy; \n\t\t$post = array('ajax'=>1,'token'=>$this->_token);\n\t\t$submit = \"https://mp.weixin.qq.com/cgi-bin/getregions?id=1017&t=ajax-getregions&lang=zh_CN\";\n\t\t$send_snoopy->rawheaders['Cookie']= $this->cookie;\n\t\t$send_snoopy->submit($submit,$post);\n\t\t$result = $send_snoopy->results;\n\t\tif(json_decode($result,1)){\n\t\t\treturn true;\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n\t\n\tprivate function log($log){\n\t\tif ($this->debug && function_exists($this->_logcallback)) {\n\t\t\tif (is_array($log)) $log = print_r($log,true);\n\t\t\treturn call_user_func($this->_logcallback,$log);\n\t\t}\n\t}\n\t\n}\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/old_version/wechatpay.class.php",
    "content": "<?php\n/**\n *\t微信公众平台PHP-SDK, 旧版微信支付接口(微信支付V2)\n *  @author  dodge <dodgepudding@gmail.com>\n *  @link https://github.com/dodgepudding/wechat-php-sdk\n *  @version 1.2\n *  参考旧版文档 https://mp.weixin.qq.com/cgi-bin/readtemplate?t=business/course2_tmpl&lang=zh_CN\n *  usage:\n *   $options = array(\n *\t\t\t'appid'=>'wxdk1234567890', //填写高级调用功能的app id\n *\t\t\t'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥\n *\t\t\t'partnerid'=>'88888888', //财付通商户身份标识\n *\t\t\t'partnerkey'=>'', //财付通商户权限密钥Key\n *\t\t\t'paysignkey'=>'' //商户签名密钥Key\n *\t\t);\n *\t $payObj = new Wechatpay($options);\n *   $package = $payObj->createPackage($out_trade_no,$body,$total_fee,$notify_url,$spbill_create_ip,$fee_type,$bank_type,$input_charset,$time_start,$time_expire,$transport_fee,$product_fee,$goods_tag,$attach);\n *\n */\nclass Wechatpay\n{\n\tconst API_URL_PREFIX = 'https://api.weixin.qq.com/cgi-bin';\n\tconst AUTH_URL = '/token?grant_type=client_credential&';\n\tconst API_BASE_URL_PREFIX = 'https://api.weixin.qq.com'; //以下API接口URL需要使用此前缀\n\tconst PAY_DELIVERNOTIFY = '/pay/delivernotify?';\n\tconst PAY_ORDERQUERY = '/pay/orderquery?';\n\n\tprivate $appid;\n\tprivate $appsecret;\n\tprivate $access_token;\n\tprivate $user_token;\n\tprivate $partnerid;\n\tprivate $partnerkey;\n\tprivate $paysignkey;\n\n\tpublic $debug =  false;\n\tpublic $errCode = 40001;\n\tpublic $errMsg = \"no access\";\n\tprivate $_logcallback;\n\n\tpublic function __construct($options)\n\t{\n\t\t$this->appid = isset($options['appid'])?$options['appid']:'';\n\t\t$this->appsecret = isset($options['appsecret'])?$options['appsecret']:'';\n\t\t$this->partnerid = isset($options['partnerid'])?$options['partnerid']:'';\n\t\t$this->partnerkey = isset($options['partnerkey'])?$options['partnerkey']:'';\n\t\t$this->paysignkey = isset($options['paysignkey'])?$options['paysignkey']:'';\n\t\t$this->debug = isset($options['debug'])?$options['debug']:false;\n\t\t$this->_logcallback = isset($options['logcallback'])?$options['logcallback']:false;\n\t}\n\n    private function log($log){\n    \t\tif ($this->debug && function_exists($this->_logcallback)) {\n    \t\t\tif (is_array($log)) $log = print_r($log,true);\n    \t\t\treturn call_user_func($this->_logcallback,$log);\n    \t\t}\n    }\n\n\t/**\n\t * GET 请求\n\t * @param string $url\n\t */\n\tprivate function http_get($url){\n\t\t$oCurl = curl_init();\n\t\tif(stripos($url,\"https://\")!==FALSE){\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1\n\t\t}\n\t\tcurl_setopt($oCurl, CURLOPT_URL, $url);\n\t\tcurl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );\n\t\t$sContent = curl_exec($oCurl);\n\t\t$aStatus = curl_getinfo($oCurl);\n\t\tcurl_close($oCurl);\n\t\tif(intval($aStatus[\"http_code\"])==200){\n\t\t\treturn $sContent;\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * POST 请求\n\t * @param string $url\n\t * @param array $param\n\t * @param boolean $post_file 是否文件上传\n\t * @return string content\n\t */\n\tprivate function http_post($url,$param,$post_file=false){\n\t\t$oCurl = curl_init();\n\t\tif(stripos($url,\"https://\")!==FALSE){\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1\n\t\t}\n\t\tif (is_string($param) || $post_file) {\n\t\t\t$strPOST = $param;\n\t\t} else {\n\t\t\t$aPOST = array();\n\t\t\tforeach($param as $key=>$val){\n\t\t\t\t$aPOST[] = $key.\"=\".urlencode($val);\n\t\t\t}\n\t\t\t$strPOST =  join(\"&\", $aPOST);\n\t\t}\n\t\tcurl_setopt($oCurl, CURLOPT_URL, $url);\n\t\tcurl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );\n\t\tcurl_setopt($oCurl, CURLOPT_POST,true);\n\t\tcurl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);\n\t\t$sContent = curl_exec($oCurl);\n\t\t$aStatus = curl_getinfo($oCurl);\n\t\tcurl_close($oCurl);\n\t\tif(intval($aStatus[\"http_code\"])==200){\n\t\t\treturn $sContent;\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * 获取access_token\n\t * @param string $appid 如在类初始化时已提供，则可为空\n\t * @param string $appsecret 如在类初始化时已提供，则可为空\n\t * @param string $token 手动指定access_token，非必要情况不建议用\n\t */\n\tpublic function checkAuth($appid='',$appsecret='',$token=''){\n\t\tif (!$appid || !$appsecret) {\n\t\t\t$appid = $this->appid;\n\t\t\t$appsecret = $this->appsecret;\n\t\t}\n\t\tif ($token) { //手动指定token，优先使用\n\t\t    $this->access_token=$token;\n\t\t    return $this->access_token;\n\t\t}\n\t\t//TODO: get the cache access_token\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::AUTH_URL.'appid='.$appid.'&secret='.$appsecret);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || isset($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t$this->access_token = $json['access_token'];\n\t\t\t$expire = $json['expires_in'] ? intval($json['expires_in'])-100 : 3600;\n\t\t\t//TODO: cache access_token\n\t\t\treturn $this->access_token;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 删除验证数据\n\t * @param string $appid\n\t */\n\tpublic function resetAuth($appid=''){\n\t\tif (!$appid) $appid = $this->appid;\n\t\t$this->access_token = '';\n\t\t//TODO: remove cache\n\t\treturn true;\n\t}\n\n\t/**\n\t * 微信api不支持中文转义的json结构\n\t * @param array $arr\n\t */\n\tstatic function json_encode($arr) {\n\t\t$parts = array ();\n\t\t$is_list = false;\n\t\t//Find out if the given array is a numerical array\n\t\t$keys = array_keys ( $arr );\n\t\t$max_length = count ( $arr ) - 1;\n\t\tif (($keys [0] === 0) && ($keys [$max_length] === $max_length )) { //See if the first key is 0 and last key is length - 1\n\t\t\t$is_list = true;\n\t\t\tfor($i = 0; $i < count ( $keys ); $i ++) { //See if each key correspondes to its position\n\t\t\t\tif ($i != $keys [$i]) { //A key fails at position check.\n\t\t\t\t\t$is_list = false; //It is an associative array.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tforeach ( $arr as $key => $value ) {\n\t\t\tif (is_array ( $value )) { //Custom handling for arrays\n\t\t\t\tif ($is_list)\n\t\t\t\t\t$parts [] = self::json_encode ( $value ); /* :RECURSION: */\n\t\t\t\telse\n\t\t\t\t\t$parts [] = '\"' . $key . '\":' . self::json_encode ( $value ); /* :RECURSION: */\n\t\t\t} else {\n\t\t\t\t$str = '';\n\t\t\t\tif (! $is_list)\n\t\t\t\t\t$str = '\"' . $key . '\":';\n\t\t\t\t//Custom handling for multiple data types\n\t\t\t\tif (!is_string ( $value ) && is_numeric ( $value ) && $value<2000000000)\n\t\t\t\t\t$str .= $value; //Numbers\n\t\t\t\telseif ($value === false)\n\t\t\t\t$str .= 'false'; //The booleans\n\t\t\t\telseif ($value === true)\n\t\t\t\t$str .= 'true';\n\t\t\t\telse\n\t\t\t\t\t$str .= '\"' . addslashes ( $value ) . '\"'; //All other things\n\t\t\t\t// :TODO: Is there any more datatype we should be in the lookout for? (Object?)\n\t\t\t\t$parts [] = $str;\n\t\t\t}\n\t\t}\n\t\t$json = implode ( ',', $parts );\n\t\tif ($is_list)\n\t\t\treturn '[' . $json . ']'; //Return numerical JSON\n\t\treturn '{' . $json . '}'; //Return associative JSON\n\t}\n\n\t/**\n\t * 获取签名\n\t * @param array $arrdata 签名数组\n\t * @param string $method 签名方法\n\t * @return boolean|string 签名值\n\t */\n\tpublic function getSignature($arrdata,$method=\"sha1\") {\n\t\tif (!function_exists($method)) return false;\n\t\tksort($arrdata);\n\t\t$paramstring = \"\";\n\t\tforeach($arrdata as $key => $value)\n\t\t{\n\t\t\tif(strlen($paramstring) == 0)\n\t\t\t\t$paramstring .= $key . \"=\" . $value;\n\t\t\telse\n\t\t\t\t$paramstring .= \"&\" . $key . \"=\" . $value;\n\t\t}\n\t\t$paySign = $method($paramstring);\n\t\treturn $paySign;\n\t}\n\n\t/**\n\t * 生成随机字串\n\t * @param number $length 长度，默认为16，最长为32字节\n\t * @return string\n\t */\n\tpublic function generateNonceStr($length=16){\n\t\t// 密码字符集，可任意添加你需要的字符\n\t\t$chars = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\n\t\t$str = \"\";\n\t\tfor($i = 0; $i < $length; $i++)\n\t\t{\n\t\t\t$str .= $chars[mt_rand(0, strlen($chars) - 1)];\n\t\t}\n\t\treturn $str;\n\t}\n\n\t/**\n\t * 生成原生支付url\n\t * @param number $productid 商品编号，最长为32字节\n\t * @return string\n\t */\n\tpublic function createNativeUrl($productid){\n\t\t    $nativeObj[\"appid\"] = $this->appid;\n\t\t    $nativeObj[\"appkey\"] = $this->paysignkey;\n\t\t    $nativeObj[\"productid\"] = urlencode($productid);\n\t\t    $nativeObj[\"timestamp\"] = time();\n\t\t    $nativeObj[\"noncestr\"] = $this->generateNonceStr();\n\t\t    $nativeObj[\"sign\"] = $this->getSignature($nativeObj);\n\t\t    unset($nativeObj[\"appkey\"]);\n\t\t    $bizString = \"\";\n\t\t    foreach($nativeObj as $key => $value)\n\t\t    {\n\t\t\tif(strlen($bizString) == 0)\n\t\t\t\t$bizString .= $key . \"=\" . $value;\n\t\t\telse\n\t\t\t\t$bizString .= \"&\" . $key . \"=\" . $value;\n\t\t    }\n\t\t    return \"weixin://wxpay/bizpayurl?\".$bizString;\n\t\t    //weixin://wxpay/bizpayurl?sign=XXXXX&appid=XXXXXX&productid=XXXXXX&timestamp=XXXXXX&noncestr=XXXXXX\n\t}\n\n\n\t/**\n\t * 生成订单package字符串\n\t * @param string $out_trade_no 必填，商户系统内部的订单号,32个字符内,确保在商户系统唯一\n\t * @param string $body 必填，商品描述,128 字节以下\n\t * @param int $total_fee 必填，订单总金额,单位为分\n\t * @param string $notify_url 必填，支付完成通知回调接口，255 字节以内\n\t * @param string $spbill_create_ip 必填，用户终端IP，IPV4字串，15字节内\n\t * @param int $fee_type 必填，现金支付币种，默认1:人民币\n\t * @param string $bank_type 必填，银行通道类型,默认WX\n\t * @param string $input_charset 必填，传入参数字符编码，默认UTF-8，取值有UTF-8和GBK\n\t * @param string $time_start 交易起始时间,订单生成时间,格式yyyyMMddHHmmss\n\t * @param string $time_expire 交易结束时间,也是订单失效时间\n\t * @param int $transport_fee 物流费用,单位为分\n\t * @param int $product_fee 商品费用,单位为分,必须保证 transport_fee + product_fee=total_fee\n\t * @param string $goods_tag 商品标记,优惠券时可能用到\n\t * @param string $attach 附加数据，notify接口原样返回\n\t * @return string\n\t */\n\tpublic function createPackage($out_trade_no,$body,$total_fee,$notify_url,$spbill_create_ip,$fee_type=1,$bank_type=\"WX\",$input_charset=\"UTF-8\",$time_start=\"\",$time_expire=\"\",$transport_fee=\"\",$product_fee=\"\",$goods_tag=\"\",$attach=\"\"){\n\t\t\t$arrdata = array(\"bank_type\" => $bank_type, \"body\" => $body, \"partner\" => $this->partnerid, \"out_trade_no\" => $out_trade_no, \"total_fee\" => $total_fee, \"fee_type\" => $fee_type, \"notify_url\" => $notify_url, \"spbill_create_ip\" => $spbill_create_ip, \"input_charset\" => $input_charset);\n\t\t\tif ($time_start)  $arrdata['time_start'] = $time_start;\n\t\t\tif ($time_expire)  $arrdata['time_expire'] = $time_expire;\n\t\t\tif ($transport_fee)  $arrdata['transport_fee'] = $transport_fee;\n\t\t\tif ($product_fee)  $arrdata['product_fee'] = $product_fee;\n\t\t\tif ($goods_tag)  $arrdata['goods_tag'] = $goods_tag;\n\t\t\tif ($attach)  $arrdata['attach'] = $attach;\n\t\t\tksort($arrdata);\n\t\t\t$paramstring = \"\";\n\t\t\tforeach($arrdata as $key => $value)\n\t\t\t{\n\t\t\tif(strlen($paramstring) == 0)\n\t\t\t\t$paramstring .= $key . \"=\" . $value;\n\t\t\t\telse\n\t\t\t\t$paramstring .= \"&\" . $key . \"=\" . $value;\n\t\t\t}\n\t\t\t$stringSignTemp = $paramstring . \"&key=\" . $this->partnerkey;\n\t\t\t$signValue = strtoupper(md5($stringSignTemp));\n\t\t\t$package = http_build_query($arrdata) . \"&sign=\" . $signValue;\n\t\t\treturn $package;\n\t}\n\n\t/**\n\t * 支付签名(paySign)生成方法\n\t * @param string $package 订单详情字串\n\t * @param string $timeStamp 当前时间戳（需与JS输出的一致）\n\t * @param string $nonceStr 随机串（需与JS输出的一致）\n\t * @return string 返回签名字串\n\t */\n\tpublic function getPaySign($package, $timeStamp, $nonceStr){\n\t\t$arrdata = array(\"appid\" => $this->appid, \"timestamp\" => $timeStamp, \"noncestr\" => $nonceStr, \"package\" => $package, \"appkey\" => $this->paysignkey);\n\t\t$paySign = $this->getSignature($arrdata);\n\t\treturn $paySign;\n\t}\n\n\t/**\n\t * 回调通知签名验证\n\t * @param array $orderxml 返回的orderXml的数组表示，留空则自动从post数据获取\n\t * @return boolean\n\t */\n\tpublic function checkOrderSignature($orderxml=''){\n\t\tif (!$orderxml) {\n\t\t\t$postStr = file_get_contents(\"php://input\");\n\t\t\tif (!empty($postStr)) {\n\t\t\t\t$orderxml = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);\n\t\t\t} else return false;\n\t\t}\n\t\t$arrdata = array('appid'=>$orderxml['AppId'],'appkey'=>$this->paysignkey,'timestamp'=>$orderxml['TimeStamp'],'noncestr'=>$orderxml['NonceStr'],'openid'=>$orderxml['OpenId'],'issubscribe'=>$orderxml['IsSubscribe']);\n\t\t$paySign = $this->getSignature($arrdata);\n\t\tif ($paySign!=$orderxml['AppSignature']) return false;\n\t\treturn true;\n\t}\n\n\t/**\n\t * 发货通知\n\t * @param string $openid 用户open_id\n\t * @param string $transid 交易单号\n\t * @param string $out_trade_no 第三方订单号\n\t * @param int $status 0:发货失败；1:已发货\n\t * @param string $msg 失败原因\n\t * @return boolean|array\n\t */\n\tpublic function sendPayDeliverNotify($openid,$transid,$out_trade_no,$status=1,$msg='ok'){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$postdata = array(\n\t\t\t\t\"appid\"=>$this->appid,\n\t\t\t\t\"appkey\"=>$this->paysignkey,\n\t\t\t\t\"openid\"=>$openid,\n\t\t\t\t\"transid\"=>strval($transid),\n\t\t\t\t\"out_trade_no\"=>strval($out_trade_no),\n\t\t\t\t\"deliver_timestamp\"=>strval(time()),\n\t\t\t\t\"deliver_status\"=>strval($status),\n\t\t\t\t\"deliver_msg\"=>$msg,\n\t\t);\n\t\t$postdata['app_signature'] = $this->getSignature($postdata);\n\t\t$postdata['sign_method'] = 'sha1';\n\t\tunset($postdata['appkey']);\n\t\t$result = $this->http_post(self::API_BASE_URL_PREFIX.self::PAY_DELIVERNOTIFY.'access_token='.$this->access_token,self::json_encode($postdata));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 查询订单信息\n\t * @param string $out_trade_no 订单号\n\t * @return boolean|array\n\t */\n\tpublic function getPayOrder($out_trade_no) {\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$sign = strtoupper(md5(\"out_trade_no=$out_trade_no&partner={$this->partnerid}&key={$this->partnerkey}\"));\n\t\t$postdata = array(\n\t\t\t\t\"appid\"=>$this->appid,\n\t\t\t\t\"appkey\"=>$this->paysignkey,\n\t\t\t\t\"package\"=>\"out_trade_no=$out_trade_no&partner={$this->partnerid}&sign=$sign\",\n\t\t\t\t\"timestamp\"=>strval(time()),\n\t\t);\n\t\t$postdata['app_signature'] = $this->getSignature($postdata);\n\t\t$postdata['sign_method'] = 'sha1';\n\t\tunset($postdata['appkey']);\n\t\t$result = $this->http_post(self::API_BASE_URL_PREFIX.self::PAY_ORDERQUERY.'access_token='.$this->access_token,self::json_encode($postdata));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'].json_encode($postdata);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json[\"order_info\"];\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 设置用户授权密钥\n\t * @param string $user_token\n\t * @return string\n\t */\n\tpublic function setUserToken($user_token) {\n\t\treturn $this->user_token = $user_token;\n\t}\n\n\t/**\n\t * 获取收货地址JS的签名\n\t * @tutorial 参考weixin.js脚本的WeixinJS.editAddress方法调用\n\t * @param string $appId\n\t * @param string $url\n\t * @param int $timeStamp\n\t * @param string $nonceStr\n\t * @param string $user_token\n\t * @return Ambigous <boolean, string>\n\t */\n\tpublic function getAddrSign($url, $timeStamp, $nonceStr, $user_token=''){\n\t\tif (!$user_token) $user_token = $this->user_token;\n\t\tif (!$user_token) {\n\t\t\t$this->errMsg = 'no user access token found!';\n\t\t\treturn false;\n\t\t}\n\t\t$url = htmlspecialchars_decode($url);\n\t\t$arrdata = array(\n\t\t\t\t'appid'=>$this->appid,\n\t\t\t\t'url'=>$url,\n\t\t\t\t'timestamp'=>strval($timeStamp),\n\t\t\t\t'noncestr'=>$nonceStr,\n\t\t\t\t'accesstoken'=>$user_token\n\t\t);\n\t\treturn $this->getSignature($arrdata);\n\t}\n}\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/qyerrCode.php",
    "content": "<?php\n/**\n *\t微信公众平台企业号PHP-SDK, 全局返回码类\n *  @author  binsee <binsee@163.com>\n *  @link https://github.com/binsee/wechat-php-sdk\n *  @version 1.0\n *  usage:\n *      $ret=ErrCode::getErrText(40001); //错误码可以通过公众号类库的公开变量errCode得到\n *      if ($ret)\n *      \techo $ret;\n *      else\n *          echo \"未找到对应的内容\";\n */\nclass ErrCode\n{\n\tpublic static $errCode=array(\n\t        '-1'=>'系统繁忙',\n\t        '0'=>'请求成功',\n\t        '40001'=>'获取access_token时AppSecret错误，或者access_token无效',\n\t        '40002'=>'不合法的凭证类型',\n\t        '40003'=>'不合法的UserID',\n\t        '40004'=>'不合法的媒体文件类型',\n\t        '40005'=>'不合法的文件类型',\n\t        '40006'=>'不合法的文件大小',\n\t        '40007'=>'不合法的媒体文件id',\n\t        '40008'=>'不合法的消息类型',\n\t        '40013'=>'不合法的corpid',\n\t        '40014'=>'不合法的access_token',\n\t        '40015'=>'不合法的菜单类型',\n\t        '40016'=>'不合法的按钮个数',\n\t        '40017'=>'不合法的按钮类型',\n\t        '40018'=>'不合法的按钮名字长度',\n\t        '40019'=>'不合法的按钮KEY长度',\n\t        '40020'=>'不合法的按钮URL长度',\n\t        '40021'=>'不合法的菜单版本号',\n\t        '40022'=>'不合法的子菜单级数',\n\t        '40023'=>'不合法的子菜单按钮个数',\n\t        '40024'=>'不合法的子菜单按钮类型',\n\t        '40025'=>'不合法的子菜单按钮名字长度',\n\t        '40026'=>'不合法的子菜单按钮KEY长度',\n\t        '40027'=>'不合法的子菜单按钮URL长度',\n\t        '40028'=>'不合法的自定义菜单使用员工',\n\t        '40029'=>'不合法的oauth_code',\n\t        '40031'=>'不合法的UserID列表',\n\t        '40032'=>'不合法的UserID列表长度',\n\t        '40033'=>'不合法的请求字符，不能包含\\uxxxx格式的字符',\n\t        '40035'=>'不合法的参数',\n\t        '40038'=>'不合法的请求格式',\n\t        '40039'=>'不合法的URL长度',\n\t        '40040'=>'不合法的插件token',\n\t        '40041'=>'不合法的插件id',\n\t        '40042'=>'不合法的插件会话',\n\t        '40048'=>'url中包含不合法domain',\n\t        '40054'=>'不合法的子菜单url域名',\n\t        '40055'=>'不合法的按钮url域名',\n\t        '40056'=>'不合法的agentid',\n\t        '40057'=>'不合法的callbackurl',\n\t        '40058'=>'不合法的红包参数',\n\t        '40059'=>'不合法的上报地理位置标志位',\n\t        '40060'=>'设置上报地理位置标志位时没有设置callbackurl',\n\t        '40061'=>'设置应用头像失败',\n\t        '40062'=>'不合法的应用模式',\n\t        '40063'=>'红包参数为空',\n\t        '40064'=>'管理组名字已存在',\n\t        '40065'=>'不合法的管理组名字长度',\n\t        '40066'=>'不合法的部门列表',\n\t        '40067'=>'标题长度不合法',\n\t        '40068'=>'不合法的标签ID',\n\t        '40069'=>'不合法的标签ID列表',\n\t        '40070'=>'列表中所有标签（用户）ID都不合法',\n\t        '40071'=>'不合法的标签名字，标签名字已经存在',\n\t        '40072'=>'不合法的标签名字长度',\n\t        '40073'=>'不合法的openid',\n\t        '40074'=>'news消息不支持指定为高保密消息',\n\t        '41001'=>'缺少access_token参数',\n\t        '41002'=>'缺少corpid参数',\n\t        '41003'=>'缺少refresh_token参数',\n\t        '41004'=>'缺少secret参数',\n\t        '41005'=>'缺少多媒体文件数据',\n\t        '41006'=>'缺少media_id参数',\n\t        '41007'=>'缺少子菜单数据',\n\t        '41008'=>'缺少oauth code',\n\t        '41009'=>'缺少UserID',\n\t        '41010'=>'缺少url',\n\t        '41011'=>'缺少agentid',\n\t        '41012'=>'缺少应用头像mediaid',\n\t        '41013'=>'缺少应用名字',\n\t        '41014'=>'缺少应用描述',\n\t        '41015'=>'缺少Content',\n\t        '41016'=>'缺少标题',\n\t        '41017'=>'缺少标签ID',\n\t        '41018'=>'缺少标签名字',\n\t        '42001'=>'access_token超时',\n\t        '42002'=>'refresh_token超时',\n\t        '42003'=>'oauth_code超时',\n\t        '42004'=>'插件token超时',\n\t        '43001'=>'需要GET请求',\n\t        '43002'=>'需要POST请求',\n\t        '43003'=>'需要HTTPS',\n\t        '43004'=>'需要接收者关注',\n\t        '43005'=>'需要好友关系',\n\t        '43006'=>'需要订阅',\n\t        '43007'=>'需要授权',\n\t        '43008'=>'需要支付授权',\n\t        '43009'=>'需要员工已关注',\n\t        '43010'=>'需要处于企业模式',\n\t        '43011'=>'需要企业授权',\n\t        '44001'=>'多媒体文件为空',\n\t        '44002'=>'POST的数据包为空',\n\t        '44003'=>'图文消息内容为空',\n\t        '44004'=>'文本消息内容为空',\n\t        '45001'=>'多媒体文件大小超过限制',\n\t        '45002'=>'消息内容超过限制',\n\t        '45003'=>'标题字段超过限制',\n\t        '45004'=>'描述字段超过限制',\n\t        '45005'=>'链接字段超过限制',\n\t        '45006'=>'图片链接字段超过限制',\n\t        '45007'=>'语音播放时间超过限制',\n\t        '45008'=>'图文消息超过限制',\n\t        '45009'=>'接口调用超过限制',\n\t        '45010'=>'创建菜单个数超过限制',\n\t        '45015'=>'回复时间超过限制',\n\t        '45016'=>'系统分组，不允许修改',\n\t        '45017'=>'分组名字过长',\n\t        '45018'=>'分组数量超过上限',\n\t        '46001'=>'不存在媒体数据',\n\t        '46002'=>'不存在的菜单版本',\n\t        '46003'=>'不存在的菜单数据',\n\t        '46004'=>'不存在的员工',\n\t        '47001'=>'解析JSON/XML内容错误',\n\t        '48002'=>'Api禁用',\n\t        '50001'=>'redirect_uri未授权',\n\t        '50002'=>'员工不在权限范围',\n\t        '50003'=>'应用已停用',\n\t        '50004'=>'员工状态不正确（未关注状态）',\n\t        '50005'=>'企业已禁用',\n\t        '60001'=>'部门长度不符合限制',\n\t        '60002'=>'部门层级深度超过限制',\n\t        '60003'=>'部门不存在',\n\t        '60004'=>'父亲部门不存在',\n\t        '60005'=>'不允许删除有成员的部门',\n\t        '60006'=>'不允许删除有子部门的部门',\n\t        '60007'=>'不允许删除根部门',\n\t        '60008'=>'部门名称已存在',\n\t        '60009'=>'部门名称含有非法字符',\n\t        '60010'=>'部门存在循环关系',\n\t        '60011'=>'管理员权限不足，（user/department/agent）无权限',\n\t        '60012'=>'不允许删除默认应用',\n\t        '60013'=>'不允许关闭应用',\n\t        '60014'=>'不允许开启应用',\n\t        '60015'=>'不允许修改默认应用可见范围',\n\t        '60016'=>'不允许删除存在成员的标签',\n\t        '60017'=>'不允许设置企业',\n\t        '60102'=>'UserID已存在',\n\t        '60103'=>'手机号码不合法',\n\t        '60104'=>'手机号码已存在',\n\t        '60105'=>'邮箱不合法',\n\t        '60106'=>'邮箱已存在',\n\t        '60107'=>'微信号不合法',\n\t        '60108'=>'微信号已存在',\n\t        '60109'=>'QQ号已存在',\n\t        '60110'=>'部门个数超出限制',\n\t        '60111'=>'UserID不存在',\n\t        '60112'=>'成员姓名不合法',\n\t        '60113'=>'身份认证信息（微信号/手机/邮箱）不能同时为空',\n\t        '60114'=>'性别不合法',\n\t        '60119'=>'用户已关注',\n\t        '60120'=>'用户已禁用',\n\t        '60121'=>'找不到该用户',\n\t        '60023'=>'应用已授权予第三方，不允许通过分级管理员修改菜单',\n\t        '80001'=>'可信域名没有IPC备案，后续将不能在该域名下正常使用jssdk',\n\n\t);\n\n\tpublic static function getErrText($err) {\n\t\tif (isset(self::$errCode[$err])) {\n\t\t\treturn self::$errCode[$err];\n\t\t}else {\n\t\t    return false;\n\t\t};\n\t}\n}\n\n?>"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/qywechat.class.php",
    "content": "<?php\n/**\n *\t微信公众平台企业号PHP-SDK, 官方API类库\n *  @author  binsee <binsee@163.com>\n *  @link https://github.com/binsee/wechat-php-sdk\n *  @version 1.0\n *  usage:\n *   $options = array(\n *\t\t\t'token'=>'tokenaccesskey', //填写应用接口的Token\n *\t\t\t'encodingaeskey'=>'encodingaeskey', //填写加密用的EncodingAESKey\n *\t\t\t'appid'=>'wxdk1234567890', //填写高级调用功能的app id\n *\t\t\t'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥\n *\t\t\t'agentid'=>'1', //应用的id\n *\t\t\t'debug'=>false, //调试开关\n *\t\t\t'logcallback'=>'logg', //调试输出方法，需要有一个string类型的参数\n *\t\t);\n *\n */\nclass Wechat\n{\n    const MSGTYPE_TEXT \t\t= 'text';\n    const MSGTYPE_IMAGE \t= 'image';\n    const MSGTYPE_LOCATION \t= 'location';\n    const MSGTYPE_LINK \t\t= 'link';    \t//暂不支持\n    const MSGTYPE_EVENT \t= 'event';\n    const MSGTYPE_MUSIC \t= 'music';    \t//暂不支持\n    const MSGTYPE_NEWS \t\t= 'news';\n    const MSGTYPE_VOICE \t= 'voice';\n    const MSGTYPE_VIDEO \t= 'video';\n\n    const EVENT_SUBSCRIBE \t= 'subscribe';      //订阅\n    const EVENT_UNSUBSCRIBE = 'unsubscribe'; \t//取消订阅\n    const EVENT_LOCATION \t= 'LOCATION';       //上报地理位置\n    const EVENT_ENTER_AGENT = 'enter_agent';   \t//用户进入应用\n\n    const EVENT_MENU_VIEW \t\t\t= 'VIEW'; \t\t\t\t//菜单 - 点击菜单跳转链接\n    const EVENT_MENU_CLICK \t\t\t= 'CLICK';              //菜单 - 点击菜单拉取消息\n    const EVENT_MENU_SCAN_PUSH \t\t= 'scancode_push';      //菜单 - 扫码推事件(客户端跳URL)\n    const EVENT_MENU_SCAN_WAITMSG \t= 'scancode_waitmsg'; \t//菜单 - 扫码推事件(客户端不跳URL)\n    const EVENT_MENU_PIC_SYS \t\t= 'pic_sysphoto';       //菜单 - 弹出系统拍照发图\n    const EVENT_MENU_PIC_PHOTO \t\t= 'pic_photo_or_album'; //菜单 - 弹出拍照或者相册发图\n    const EVENT_MENU_PIC_WEIXIN \t= 'pic_weixin';         //菜单 - 弹出微信相册发图器\n    const EVENT_MENU_LOCATION \t\t= 'location_select';    //菜单 - 弹出地理位置选择器\n\n    const EVENT_SEND_MASS = 'MASSSENDJOBFINISH';        //发送结果 - 高级群发完成\n    const EVENT_SEND_TEMPLATE = 'TEMPLATESENDJOBFINISH';//发送结果 - 模板消息发送结果\n\n    const API_URL_PREFIX = 'https://qyapi.weixin.qq.com/cgi-bin';\n\n    const USER_CREATE_URL \t\t= '/user/create?';\n    const USER_UPDATE_URL \t\t= '/user/update?';\n    const USER_DELETE_URL \t\t= '/user/delete?';\n    const USER_BATCHDELETE_URL \t= '/user/batchdelete?';\n    const USER_GET_URL \t\t\t= '/user/get?';\n    const USER_LIST_URL \t\t= '/user/simplelist?';\n    const USER_LIST_INFO_URL \t= '/user/list?';\n    const USER_GETINFO_URL \t\t= '/user/getuserinfo?';\n    const USER_INVITE_URL \t\t= '/invite/send?';\n    const DEPARTMENT_CREATE_URL = '/department/create?';\n    const DEPARTMENT_UPDATE_URL = '/department/update?';\n    const DEPARTMENT_DELETE_URL = '/department/delete?';\n    const DEPARTMENT_MOVE_URL \t= '/department/move?';\n    const DEPARTMENT_LIST_URL \t= '/department/list?';\n    const TAG_CREATE_URL \t\t= '/tag/create?';\n    const TAG_UPDATE_URL \t\t= '/tag/update?';\n    const TAG_DELETE_URL \t\t= '/tag/delete?';\n    const TAG_GET_URL \t\t\t= '/tag/get?';\n    const TAG_ADDUSER_URL \t\t= '/tag/addtagusers?';\n    const TAG_DELUSER_URL \t\t= '/tag/deltagusers?';\n    const TAG_LIST_URL \t\t\t= '/tag/list?';\n    const MEDIA_UPLOAD_URL \t\t= '/media/upload?';\n    const MEDIA_GET_URL \t\t= '/media/get?';\n    const AUTHSUCC_URL \t\t\t= '/user/authsucc?';\n    const MASS_SEND_URL \t\t= '/message/send?';\n    const MENU_CREATE_URL \t\t= '/menu/create?';\n    const MENU_GET_URL \t\t\t= '/menu/get?';\n    const MENU_DELETE_URL \t\t= '/menu/delete?';\n    const TOKEN_GET_URL \t\t= '/gettoken?';\n    const TICKET_GET_URL \t\t= '/get_jsapi_ticket?';\n\tconst CALLBACKSERVER_GET_URL = '/getcallbackip?';\n\tconst OAUTH_PREFIX \t\t\t= 'https://open.weixin.qq.com/connect/oauth2';\n\tconst OAUTH_AUTHORIZE_URL \t= '/authorize?';\n\n\tprivate $token;\n\tprivate $encodingAesKey;\n\tprivate $appid;         //也就是企业号的CorpID\n\tprivate $appsecret;\n\tprivate $access_token;\n    private $agentid;       //应用id   AgentID\n\tprivate $postxml;\n    private $agentidxml;    //接收的应用id   AgentID\n\tprivate $_msg;\n\tprivate $_receive;\n\tprivate $_sendmsg;      //主动发送消息的内容\n\tprivate $_text_filter = true;\n\tpublic $debug =  false;\n\tpublic $errCode = 40001;\n\tpublic $errMsg = \"no access\";\n\tpublic $logcallback;\n\n\tpublic function __construct($options)\n\t{\n\t\t$this->token = isset($options['token'])?$options['token']:'';\n\t\t$this->encodingAesKey = isset($options['encodingaeskey'])?$options['encodingaeskey']:'';\n\t\t$this->appid = isset($options['appid'])?$options['appid']:'';\n\t\t$this->appsecret = isset($options['appsecret'])?$options['appsecret']:'';\n\t\t$this->agentid = isset($options['agentid'])?$options['agentid']:'';\n\t\t$this->debug = isset($options['debug'])?$options['debug']:false;\n\t\t$this->logcallback = isset($options['logcallback'])?$options['logcallback']:false;\n\t}\n\n\tprotected function log($log){\n\t    if ($this->debug && function_exists($this->logcallback)) {\n\t        if (is_array($log)) $log = print_r($log,true);\n\t        return call_user_func($this->logcallback,$log);\n\t    }\n\t}\n\n\t/**\n\t * 数据XML编码\n\t * @param mixed $data 数据\n\t * @return string\n\t */\n\tpublic static function data_to_xml($data) {\n\t    $xml = '';\n\t    foreach ($data as $key => $val) {\n\t        is_numeric($key) && $key = \"item id=\\\"$key\\\"\";\n\t        $xml    .=  \"<$key>\";\n\t        $xml    .=  ( is_array($val) || is_object($val)) ? self::data_to_xml($val)  : self::xmlSafeStr($val);\n\t        list($key, ) = explode(' ', $key);\n\t        $xml    .=  \"</$key>\";\n\t    }\n\t    return $xml;\n\t}\n\n\tpublic static function xmlSafeStr($str)\n\t{\n\t    return '<![CDATA['.preg_replace(\"/[\\\\x00-\\\\x08\\\\x0b-\\\\x0c\\\\x0e-\\\\x1f]/\",'',$str).']]>';\n\t}\n\n\t/**\n\t * XML编码\n\t * @param mixed $data 数据\n\t * @param string $root 根节点名\n\t * @param string $item 数字索引的子节点名\n\t * @param string $attr 根节点属性\n\t * @param string $id   数字索引子节点key转换的属性名\n\t * @param string $encoding 数据编码\n\t * @return string\n\t */\n\tpublic function xml_encode($data, $root='xml', $item='item', $attr='', $id='id', $encoding='utf-8') {\n\t    if(is_array($attr)){\n\t        $_attr = array();\n\t        foreach ($attr as $key => $value) {\n\t            $_attr[] = \"{$key}=\\\"{$value}\\\"\";\n\t        }\n\t        $attr = implode(' ', $_attr);\n\t    }\n\t    $attr   = trim($attr);\n\t    $attr   = empty($attr) ? '' : \" {$attr}\";\n\t    $xml   = \"<{$root}{$attr}>\";\n\t    $xml   .= self::data_to_xml($data, $item, $id);\n\t    $xml   .= \"</{$root}>\";\n\t    return $xml;\n\t}\n\n\n\t/**\n\t * 微信api不支持中文转义的json结构\n\t * @param array $arr\n\t */\n\tstatic function json_encode($arr) {\n\t    $parts = array ();\n\t    $is_list = false;\n\t    //Find out if the given array is a numerical array\n\t    $keys = array_keys ( $arr );\n\t    $max_length = count ( $arr ) - 1;\n\t    if (($keys [0] === 0) && ($keys [$max_length] === $max_length )) { //See if the first key is 0 and last key is length - 1\n\t        $is_list = true;\n\t        for($i = 0; $i < count ( $keys ); $i ++) { //See if each key correspondes to its position\n\t            if ($i != $keys [$i]) { //A key fails at position check.\n\t                $is_list = false; //It is an associative array.\n\t                break;\n\t            }\n\t        }\n\t    }\n\t    foreach ( $arr as $key => $value ) {\n\t        if (is_array ( $value )) { //Custom handling for arrays\n\t            if ($is_list)\n\t                $parts [] = self::json_encode ( $value ); /* :RECURSION: */\n\t            else\n\t                $parts [] = '\"' . $key . '\":' . self::json_encode ( $value ); /* :RECURSION: */\n\t        } else {\n\t            $str = '';\n\t            if (! $is_list)\n\t                $str = '\"' . $key . '\":';\n\t            //Custom handling for multiple data types\n\t            if (!is_string ( $value ) && is_numeric ( $value ) && $value<2000000000)\n\t                $str .= $value; //Numbers\n\t            elseif ($value === false)\n\t            $str .= 'false'; //The booleans\n\t            elseif ($value === true)\n\t            $str .= 'true';\n\t            else\n\t                $str .= '\"' . addslashes ( $value ) . '\"'; //All other things\n\t            // :TODO: Is there any more datatype we should be in the lookout for? (Object?)\n\t            $parts [] = $str;\n\t        }\n\t    }\n\t    $json = implode ( ',', $parts );\n\t    if ($is_list)\n\t        return '[' . $json . ']'; //Return numerical JSON\n\t    return '{' . $json . '}'; //Return associative JSON\n\t}\n\n\t/**\n\t * 过滤文字回复\\r\\n换行符\n\t * @param string $text\n\t * @return string|mixed\n\t */\n\tprivate function _auto_text_filter($text) {\n\t    if (!$this->_text_filter) return $text;\n\t    return str_replace(\"\\r\\n\", \"\\n\", $text);\n\t}\n\n\t/**\n\t * GET 请求\n\t * @param string $url\n\t */\n\tprivate function http_get($url){\n\t    $oCurl = curl_init();\n\t    if(stripos($url,\"https://\")!==FALSE){\n\t        curl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);\n\t        curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);\n\t        curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1\n\t    }\n\t    curl_setopt($oCurl, CURLOPT_URL, $url);\n\t    curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );\n\t    $sContent = curl_exec($oCurl);\n\t    $aStatus = curl_getinfo($oCurl);\n\t    curl_close($oCurl);\n\t    if(intval($aStatus[\"http_code\"])==200){\n\t        return $sContent;\n\t    }else{\n\t        return false;\n\t    }\n\t}\n\n\t/**\n\t * POST 请求\n\t * @param string $url\n\t * @param array $param\n\t * @param boolean $post_file 是否文件上传\n\t * @return string content\n\t */\n\tprivate function http_post($url,$param,$post_file=false){\n\t\t$oCurl = curl_init();\n\t\tif(stripos($url,\"https://\")!==FALSE){\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1\n\t\t}\n\t\tif (is_string($param) || $post_file) {\n\t\t\t$strPOST = $param;\n\t\t} else {\n\t\t\t$aPOST = array();\n\t\t\tforeach($param as $key=>$val){\n\t\t\t\t$aPOST[] = $key.\"=\".urlencode($val);\n\t\t\t}\n\t\t\t$strPOST =  join(\"&\", $aPOST);\n\t\t}\n\t\tcurl_setopt($oCurl, CURLOPT_URL, $url);\n\t\tcurl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );\n\t\tcurl_setopt($oCurl, CURLOPT_POST,true);\n\t\tcurl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);\n\t\t$sContent = curl_exec($oCurl);\n\t\t$aStatus = curl_getinfo($oCurl);\n\t\tcurl_close($oCurl);\n\t\tif(intval($aStatus[\"http_code\"])==200){\n\t\t\treturn $sContent;\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * For weixin server validation\n\t */\n\tprivate function checkSignature($str)\n\t{\n\t    $signature = isset($_GET[\"msg_signature\"])?$_GET[\"msg_signature\"]:'';\n\t    $timestamp = isset($_GET[\"timestamp\"])?$_GET[\"timestamp\"]:'';\n\t    $nonce = isset($_GET[\"nonce\"])?$_GET[\"nonce\"]:'';\n\t    $tmpArr = array($str,$this->token, $timestamp, $nonce);//比普通公众平台多了一个加密的密文\n\t    sort($tmpArr, SORT_STRING);\n\t    $tmpStr = implode($tmpArr);\n\t    $shaStr = sha1($tmpStr);\n\t    if( $shaStr == $signature ){\n\t        return true;\n\t    }else{\n\t        return false;\n\t    }\n\t}\n\n\t/**\n\t * 微信验证，包括post来的xml解密\n\t * @param bool $return 是否返回\n\t */\n\tpublic function valid($return=false)\n    {\n        $encryptStr=\"\";\n        if ($_SERVER['REQUEST_METHOD'] == \"POST\") {\n            $postStr = file_get_contents(\"php://input\");\n            $array = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);\n            $this->log($postStr);\n            if (isset($array['Encrypt'])) {\n                $encryptStr = $array['Encrypt'];\n                $this->agentidxml = isset($array['AgentID']) ? $array['AgentID']: '';\n            }\n        } else {\n            $encryptStr = isset($_GET[\"echostr\"]) ? $_GET[\"echostr\"]: '';\n\n        }\n        if ($encryptStr) {\n            $ret=$this->checkSignature($encryptStr);\n        }\n        if (!isset($ret) || !$ret) {\n        \tif (!$return) {\n        \t    die('no access');\n        \t} else {\n        \t    return false;\n        \t}\n        }\n        $pc = new Prpcrypt($this->encodingAesKey);\n        $array = $pc->decrypt($encryptStr,$this->appid);\n        if (!isset($array[0]) || ($array[0] != 0)) {\n            if (!$return) {\n        \t    die('解密失败！');\n        \t} else {\n        \t    return false;\n        \t}\n        }\n        if ($_SERVER['REQUEST_METHOD'] == \"POST\") {\n            $this->postxml = $array[1];\n            //$this->log($array[1]);\n            return ($this->postxml!=\"\");\n        } else {\n            $echoStr = $array[1];\n            if ($return) {\n            \treturn $echoStr;\n            } else {\n                die($echoStr);\n            }\n        }\n        return false;\n    }\n\n    /**\n     * 获取微信服务器发来的信息\n     */\n\tpublic function getRev()\n\t{\n\t\tif ($this->_receive) return $this;\n\t\t$postStr = $this->postxml;\n\t\t$this->log($postStr);\n\t\tif (!empty($postStr)) {\n\t\t\t$this->_receive = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);\n\t\t\tif (!isset($this->_receive['AgentID'])) {\n\t\t\t     $this->_receive['AgentID']=$this->agentidxml; //当前接收消息的应用id\n\t\t\t}\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * 获取微信服务器发来的信息\n\t */\n\tpublic function getRevData()\n\t{\n\t\treturn $this->_receive;\n\t}\n\n\t/**\n\t * 获取微信服务器发来的原始加密信息\n\t */\n\tpublic function getRevPostXml()\n\t{\n\t    return $this->postxml;\n\t}\n\n\t/**\n\t * 获取消息发送者\n\t */\n\tpublic function getRevFrom() {\n\t\tif (isset($this->_receive['FromUserName']))\n\t\t\treturn $this->_receive['FromUserName'];\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取消息接受者\n\t */\n\tpublic function getRevTo() {\n\t\tif (isset($this->_receive['ToUserName']))\n\t\t\treturn $this->_receive['ToUserName'];\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收消息的应用id\n\t */\n\tpublic function getRevAgentID() {\n\t\tif (isset($this->_receive['AgentID']))\n\t\t\treturn $this->_receive['AgentID'];\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收消息的类型\n\t */\n\tpublic function getRevType() {\n\t\tif (isset($this->_receive['MsgType']))\n\t\t\treturn $this->_receive['MsgType'];\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取消息ID\n\t */\n\tpublic function getRevID() {\n\t\tif (isset($this->_receive['MsgId']))\n\t\t\treturn $this->_receive['MsgId'];\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取消息发送时间\n\t */\n\tpublic function getRevCtime() {\n\t\tif (isset($this->_receive['CreateTime']))\n\t\t\treturn $this->_receive['CreateTime'];\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收消息内容正文\n\t */\n\tpublic function getRevContent(){\n\t\tif (isset($this->_receive['Content']))\n\t\t\treturn $this->_receive['Content'];\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收消息图片\n\t */\n\tpublic function getRevPic(){\n\t\tif (isset($this->_receive['PicUrl']))\n\t\t\treturn array(\n\t\t\t\t'mediaid'=>$this->_receive['MediaId'],\n\t\t\t\t'picurl'=>(string)$this->_receive['PicUrl'],    //防止picurl为空导致解析出错\n\t\t\t);\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收地理位置\n\t */\n\tpublic function getRevGeo(){\n\t\tif (isset($this->_receive['Location_X'])){\n\t\t\treturn array(\n\t\t\t\t'x'=>$this->_receive['Location_X'],\n\t\t\t\t'y'=>$this->_receive['Location_Y'],\n\t\t\t\t'scale'=>(string)$this->_receive['Scale'],\n\t\t\t\t'label'=>(string)$this->_receive['Label']\n\t\t\t);\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取上报地理位置事件\n\t */\n\tpublic function getRevEventGeo(){\n        \tif (isset($this->_receive['Latitude'])){\n        \t\t return array(\n\t\t\t\t'x'=>$this->_receive['Latitude'],\n\t\t\t\t'y'=>$this->_receive['Longitude'],\n\t\t\t\t'precision'=>$this->_receive['Precision'],\n\t\t\t);\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收事件推送\n\t */\n\tpublic function getRevEvent(){\n\t\tif (isset($this->_receive['Event'])){\n\t\t\t$array['event'] = $this->_receive['Event'];\n\t\t}\n\t\tif (isset($this->_receive['EventKey']) && !empty($this->_receive['EventKey'])){\n\t\t\t$array['key'] = $this->_receive['EventKey'];\n\t\t}\n\t\tif (isset($array) && count($array) > 0) {\n\t\t\treturn $array;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * 获取自定义菜单的扫码推事件信息\n\t *\n\t * 事件类型为以下两种时则调用此方法有效\n\t * Event\t 事件类型，scancode_push\n\t * Event\t 事件类型，scancode_waitmsg\n\t *\n\t * @return: array | false\n\t * array (\n\t *     'ScanType'=>'qrcode',\n\t *     'ScanResult'=>'123123'\n\t * )\n\t */\n\tpublic function getRevScanInfo(){\n\t    if (isset($this->_receive['ScanCodeInfo'])){\n\t        if (!is_array($this->_receive['SendPicsInfo'])) {\n\t            $array=(array)$this->_receive['ScanCodeInfo'];\n\t            $this->_receive['ScanCodeInfo']=$array;\n\t        }else {\n\t            $array=$this->_receive['ScanCodeInfo'];\n\t        }\n\t    }\n\t    if (isset($array) && count($array) > 0) {\n\t        return $array;\n\t    } else {\n\t        return false;\n\t    }\n\t}\n\n\t/**\n\t * 获取自定义菜单的图片发送事件信息\n\t *\n\t * 事件类型为以下三种时则调用此方法有效\n\t * Event\t 事件类型，pic_sysphoto        弹出系统拍照发图的事件推送\n\t * Event\t 事件类型，pic_photo_or_album  弹出拍照或者相册发图的事件推送\n\t * Event\t 事件类型，pic_weixin          弹出微信相册发图器的事件推送\n\t *\n\t * @return: array | false\n\t * array (\n\t *   'Count' => '2',\n\t *   'PicList' =>array (\n\t *         'item' =>array (\n\t *             0 =>array ('PicMd5Sum' => 'aaae42617cf2a14342d96005af53624c'),\n\t *             1 =>array ('PicMd5Sum' => '149bd39e296860a2adc2f1bb81616ff8'),\n\t *         ),\n\t *   ),\n\t * )\n\t *\n\t */\n\tpublic function getRevSendPicsInfo(){\n\t    if (isset($this->_receive['SendPicsInfo'])){\n\t        if (!is_array($this->_receive['SendPicsInfo'])) {\n\t            $array=(array)$this->_receive['SendPicsInfo'];\n\t            if (isset($array['PicList'])){\n\t                $array['PicList']=(array)$array['PicList'];\n\t                $item=$array['PicList']['item'];\n\t                $array['PicList']['item']=array();\n\t                foreach ( $item as $key => $value ){\n\t                    $array['PicList']['item'][$key]=(array)$value;\n\t                }\n\t            }\n\t            $this->_receive['SendPicsInfo']=$array;\n\t        } else {\n\t            $array=$this->_receive['SendPicsInfo'];\n\t        }\n\t    }\n\t    if (isset($array) && count($array) > 0) {\n\t        return $array;\n\t    } else {\n\t        return false;\n\t    }\n\t}\n\n\t/**\n\t * 获取自定义菜单的地理位置选择器事件推送\n\t *\n\t * 事件类型为以下时则可以调用此方法有效\n\t * Event\t 事件类型，location_select        弹出系统拍照发图的事件推送\n\t *\n\t * @return: array | false\n\t * array (\n\t *   'Location_X' => '33.731655000061',\n\t *   'Location_Y' => '113.29955200008047',\n\t *   'Scale' => '16',\n\t *   'Label' => '某某市某某区某某路',\n\t *   'Poiname' => '',\n\t * )\n\t *\n\t */\n\tpublic function getRevSendGeoInfo(){\n\t    if (isset($this->_receive['SendLocationInfo'])){\n\t        if (!is_array($this->_receive['SendLocationInfo'])) {\n\t            $array=(array)$this->_receive['SendLocationInfo'];\n\t            if (empty($array['Poiname'])) {\n\t                $array['Poiname']=\"\";\n\t            }\n\t            if (empty($array['Label'])) {\n\t                $array['Label']=\"\";\n\t            }\n\t            $this->_receive['SendLocationInfo']=$array;\n\t        } else {\n\t            $array=$this->_receive['SendLocationInfo'];\n\t        }\n\t    }\n\t    if (isset($array) && count($array) > 0) {\n\t        return $array;\n\t    } else {\n\t        return false;\n\t    }\n\t}\n\n\t/**\n\t * 获取接收语音推送\n\t */\n\tpublic function getRevVoice(){\n\t\tif (isset($this->_receive['MediaId'])){\n\t\t\treturn array(\n\t\t\t\t'mediaid'=>$this->_receive['MediaId'],\n\t\t\t\t'format'=>$this->_receive['Format'],\n\t\t\t);\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收视频推送\n\t */\n\tpublic function getRevVideo(){\n\t\tif (isset($this->_receive['MediaId'])){\n\t\t\treturn array(\n\t\t\t\t\t'mediaid'=>$this->_receive['MediaId'],\n\t\t\t\t\t'thumbmediaid'=>$this->_receive['ThumbMediaId']\n\t\t\t);\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 设置回复消息\n\t * Example: $obj->text('hello')->reply();\n\t * @param string $text\n\t */\n\tpublic function text($text='')\n\t{\n\t\t$msg = array(\n\t\t\t'ToUserName' => $this->getRevFrom(),\n\t\t\t'FromUserName'=>$this->getRevTo(),\n\t\t\t'MsgType'=>self::MSGTYPE_TEXT,\n\t\t\t'Content'=>$this->_auto_text_filter($text),\n\t\t\t'CreateTime'=>time(),\n\t\t);\n\t\t$this->Message($msg);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * 设置回复消息\n\t * Example: $obj->image('media_id')->reply();\n\t * @param string $mediaid\n\t */\n\tpublic function image($mediaid='')\n\t{\n\t\t$msg = array(\n\t\t\t'ToUserName' => $this->getRevFrom(),\n\t\t\t'FromUserName'=>$this->getRevTo(),\n\t\t\t'MsgType'=>self::MSGTYPE_IMAGE,\n\t\t\t'Image'=>array('MediaId'=>$mediaid),\n\t\t\t'CreateTime'=>time(),\n\t\t);\n\t\t$this->Message($msg);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * 设置回复消息\n\t * Example: $obj->voice('media_id')->reply();\n\t * @param string $mediaid\n\t */\n\tpublic function voice($mediaid='')\n\t{\n\t\t$msg = array(\n\t\t\t'ToUserName' => $this->getRevFrom(),\n\t\t\t'FromUserName'=>$this->getRevTo(),\n\t\t\t'MsgType'=>self::MSGTYPE_IMAGE,\n\t\t\t'Voice'=>array('MediaId'=>$mediaid),\n\t\t\t'CreateTime'=>time(),\n\t\t);\n\t\t$this->Message($msg);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * 设置回复消息\n\t * Example: $obj->video('media_id','title','description')->reply();\n\t * @param string $mediaid\n\t */\n\tpublic function video($mediaid='',$title='',$description='')\n\t{\n\t\t$msg = array(\n\t\t\t'ToUserName' => $this->getRevFrom(),\n\t\t\t'FromUserName'=>$this->getRevTo(),\n\t\t\t'MsgType'=>self::MSGTYPE_IMAGE,\n\t\t\t'Video'=>array(\n\t\t\t        'MediaId'=>$mediaid,\n\t\t\t        'Title'=>$title,\n\t\t\t        'Description'=>$description\n\t\t\t),\n\t\t\t'CreateTime'=>time(),\n\t\t);\n\t\t$this->Message($msg);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * 设置回复图文\n\t * @param array $newsData\n\t * 数组结构:\n\t *  array(\n\t *  \t\"0\"=>array(\n\t *  \t\t'Title'=>'msg title',\n\t *  \t\t'Description'=>'summary text',\n\t *  \t\t'PicUrl'=>'http://www.domain.com/1.jpg',\n\t *  \t\t'Url'=>'http://www.domain.com/1.html'\n\t *  \t),\n\t *  \t\"1\"=>....\n\t *  )\n\t */\n\tpublic function news($newsData=array())\n\t{\n\n\t\t$count = count($newsData);\n\n\t\t$msg = array(\n\t\t\t'ToUserName' => $this->getRevFrom(),\n\t\t\t'FromUserName'=>$this->getRevTo(),\n\t\t\t'MsgType'=>self::MSGTYPE_NEWS,\n\t\t\t'CreateTime'=>time(),\n\t\t\t'ArticleCount'=>$count,\n\t\t\t'Articles'=>$newsData,\n\n\t\t);\n\t\t$this->Message($msg);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * 设置发送消息\n\t * @param array $msg 消息数组\n\t * @param bool $append 是否在原消息数组追加\n\t */\n\tpublic function Message($msg = '',$append = false){\n\t    if (is_null($msg)) {\n\t        $this->_msg =array();\n\t    }elseif (is_array($msg)) {\n\t        if ($append)\n\t            $this->_msg = array_merge($this->_msg,$msg);\n\t        else\n\t            $this->_msg = $msg;\n\t        return $this->_msg;\n\t    } else {\n\t        return $this->_msg;\n\t    }\n\t}\n\n\t/**\n\t *\n\t * 回复微信服务器, 此函数支持链式操作\n\t * Example: $this->text('msg tips')->reply();\n\t * @param string $msg 要发送的信息, 默认取$this->_msg\n\t * @param bool $return 是否返回信息而不抛出到浏览器 默认:否\n\t */\n\tpublic function reply($msg=array(),$return = false)\n\t{\n\t\tif (empty($msg))\n\t\t\t$msg = $this->_msg;\n\t\t$xmldata=  $this->xml_encode($msg);\n\t\t$this->log($xmldata);\n\t\t$pc = new Prpcrypt($this->encodingAesKey);\n\t\t$array = $pc->encrypt($xmldata, $this->appid);\n\t\t$ret = $array[0];\n\t\tif ($ret != 0) {\n\t\t    $this->log('encrypt err!');\n\t\t    return false;\n\t\t}\n\t\t$timestamp = time();\n\t\t$nonce = rand(77,999)*rand(605,888)*rand(11,99);\n\t\t$encrypt = $array[1];\n\t\t$tmpArr = array($this->token, $timestamp, $nonce,$encrypt);//比普通公众平台多了一个加密的密文\n\t\tsort($tmpArr, SORT_STRING);\n\t\t$signature = implode($tmpArr);\n\t\t$signature = sha1($signature);\n\t\t$smsg = $this->generate($encrypt, $signature, $timestamp, $nonce);\n\t\t$this->log($smsg);\n\t\tif ($return)\n\t\t    return $smsg;\n\t\telseif ($smsg){\n\t\t\techo $smsg;\n\t\t    return true;\n\n\t\t}else\n\t\t    return false;\n\t}\n\n\tprivate function generate($encrypt, $signature, $timestamp, $nonce)\n\t{\n\t    //格式化加密信息\n\t    $format = \"<xml>\n<Encrypt><![CDATA[%s]]></Encrypt>\n<MsgSignature><![CDATA[%s]]></MsgSignature>\n<TimeStamp>%s</TimeStamp>\n<Nonce><![CDATA[%s]]></Nonce>\n</xml>\";\n\t    return sprintf($format, $encrypt, $signature, $timestamp, $nonce);\n\t}\n\n\t/**\n\t * 设置缓存，按需重载\n\t * @param string $cachename\n\t * @param mixed $value\n\t * @param int $expired\n\t * @return boolean\n\t */\n\tprotected function setCache($cachename,$value,$expired){\n\t\t//TODO: set cache implementation\n\t\treturn false;\n\t}\n\n\t/**\n\t * 获取缓存，按需重载\n\t * @param string $cachename\n\t * @return mixed\n\t */\n\tprotected function getCache($cachename){\n\t\t//TODO: get cache implementation\n\t\treturn false;\n\t}\n\n\t/**\n\t * 清除缓存，按需重载\n\t * @param string $cachename\n\t * @return boolean\n\t */\n\tprotected function removeCache($cachename){\n\t\t//TODO: remove cache implementation\n\t\treturn false;\n\t}\n\n\t/**\n\t * 通用auth验证方法\n\t * @param string $appid\n\t * @param string $appsecret\n\t * @param string $token 手动指定access_token，非必要情况不建议用\n\t */\n\tpublic function checkAuth($appid='',$appsecret='',$token=''){\n\t\tif (!$appid || !$appsecret) {\n\t\t\t$appid = $this->appid;\n\t\t\t$appsecret = $this->appsecret;\n\t\t}\n\t\tif ($token) { //手动指定token，优先使用\n\t\t    $this->access_token=$token;\n\t\t    return $this->access_token;\n\t\t}\n\n\t\t$authname = 'qywechat_access_token'.$appid;\n\t\tif ($rs = $this->getCache($authname))  {\n\t\t\t$this->access_token = $rs;\n\t\t\treturn $rs;\n\t\t}\n\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::TOKEN_GET_URL.'corpid='.$appid.'&corpsecret='.$appsecret);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || isset($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t$this->access_token = $json['access_token'];\n\t\t\t$expire = $json['expires_in'] ? intval($json['expires_in'])-100 : 3600;\n\t\t\t$this->setCache($authname,$this->access_token,$expire);\n\t\t\treturn $this->access_token;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 删除验证数据\n\t * @param string $appid\n\t */\n\tpublic function resetAuth($appid=''){\n\t\tif (!$appid) $appid = $this->appid;\n\t\t$this->access_token = '';\n\t\t$authname = 'qywechat_access_token'.$appid;\n\t\t$this->removeCache($authname);\n\t\treturn true;\n\t}\n\n\t/**\n\t * 删除JSAPI授权TICKET\n\t * @param string $appid 用于多个appid时使用\n\t */\n\tpublic function resetJsTicket($appid=''){\n\t\tif (!$appid) $appid = $this->appid;\n\t\t$this->jsapi_ticket = '';\n\t\t$authname = 'qywechat_jsapi_ticket'.$appid;\n\t\t$this->removeCache($authname);\n\t\treturn true;\n\t}\n\n\t/**\n\t * 获取JSAPI授权TICKET\n\t * @param string $appid 用于多个appid时使用,可空\n\t * @param string $jsapi_ticket 手动指定jsapi_ticket，非必要情况不建议用\n\t */\n\tpublic function getJsTicket($appid='',$jsapi_ticket=''){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\tif (!$appid) $appid = $this->appid;\n\t\tif ($jsapi_ticket) { //手动指定token，优先使用\n\t\t    $this->jsapi_ticket = $jsapi_ticket;\n\t\t    return $this->jsapi_ticket;\n\t\t}\n\t\t$authname = 'qywechat_jsapi_ticket'.$appid;\n\t\tif ($rs = $this->getCache($authname))  {\n\t\t\t$this->jsapi_ticket = $rs;\n\t\t\treturn $rs;\n\t\t}\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::TICKET_GET_URL.'access_token='.$this->access_token);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t$this->jsapi_ticket = $json['ticket'];\n\t\t\t$expire = $json['expires_in'] ? intval($json['expires_in'])-100 : 3600;\n\t\t\t$this->setCache($authname, $this->jsapi_ticket, $expire);\n\t\t\treturn $this->jsapi_ticket;\n\t\t}\n\t\treturn false;\n\t}\n\n\n\t/**\n\t * 获取JsApi使用签名\n\t * @param string $url 网页的URL，自动处理#及其后面部分\n\t * @param string $timestamp 当前时间戳 (为空则自动生成)\n\t * @param string $noncestr 随机串 (为空则自动生成)\n\t * @param string $appid 用于多个appid时使用,可空\n\t * @return array|bool 返回签名字串\n\t */\n\tpublic function getJsSign($url, $timestamp=0, $noncestr='', $appid=''){\n\t    if (!$this->jsapi_ticket && !$this->getJsTicket($appid) || !$url) return false;\n\t    if (!$timestamp)\n\t        $timestamp = time();\n\t    if (!$noncestr)\n\t        $noncestr = $this->generateNonceStr();\n\t    $ret = strpos($url,'#');\n\t    if ($ret)\n\t        $url = substr($url,0,$ret);\n\t    $url = trim($url);\n\t    if (empty($url))\n\t        return false;\n\t    $arrdata = array(\"timestamp\" => $timestamp, \"noncestr\" => $noncestr, \"url\" => $url, \"jsapi_ticket\" => $this->jsapi_ticket);\n\t    $sign = $this->getSignature($arrdata);\n\t    if (!$sign)\n\t        return false;\n\t    $signPackage = array(\n\t            \"appid\"     => $this->appid,\n\t            \"noncestr\"  => $noncestr,\n\t            \"timestamp\" => $timestamp,\n\t            \"url\"       => $url,\n\t            \"signature\" => $sign\n\t    );\n\t    return $signPackage;\n\t}\n\n\t/**\n\t * 获取签名\n\t * @param array $arrdata 签名数组\n\t * @param string $method 签名方法\n\t * @return boolean|string 签名值\n\t */\n\tpublic function getSignature($arrdata,$method=\"sha1\") {\n\t\tif (!function_exists($method)) return false;\n\t\tksort($arrdata);\n\t\t$paramstring = \"\";\n\t\tforeach($arrdata as $key => $value)\n\t\t{\n\t\t\tif(strlen($paramstring) == 0)\n\t\t\t\t$paramstring .= $key . \"=\" . $value;\n\t\t\telse\n\t\t\t\t$paramstring .= \"&\" . $key . \"=\" . $value;\n\t\t}\n\t\t$Sign = $method($paramstring);\n\t\treturn $Sign;\n\t}\n\n\t/**\n\t * 生成随机字串\n\t * @param number $length 长度，默认为16，最长为32字节\n\t * @return string\n\t */\n\tpublic function generateNonceStr($length=16){\n\t\t// 密码字符集，可任意添加你需要的字符\n\t\t$chars = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\n\t\t$str = \"\";\n\t\tfor($i = 0; $i < $length; $i++)\n\t\t{\n\t\t\t$str .= $chars[mt_rand(0, strlen($chars) - 1)];\n\t\t}\n\t\treturn $str;\n\t}\n\n\n\t/**\n\t * 创建菜单\n\t * @param array $data 菜单数组数据\n\t * example:\n     * \tarray (\n     * \t    'button' => array (\n     * \t      0 => array (\n     * \t        'name' => '扫码',\n     * \t        'sub_button' => array (\n     * \t            0 => array (\n     * \t              'type' => 'scancode_waitmsg',\n     * \t              'name' => '扫码带提示',\n     * \t              'key' => 'rselfmenu_0_0',\n     * \t            ),\n     * \t            1 => array (\n     * \t              'type' => 'scancode_push',\n     * \t              'name' => '扫码推事件',\n     * \t              'key' => 'rselfmenu_0_1',\n     * \t            ),\n     * \t        ),\n     * \t      ),\n     * \t      1 => array (\n     * \t        'name' => '发图',\n     * \t        'sub_button' => array (\n     * \t            0 => array (\n     * \t              'type' => 'pic_sysphoto',\n     * \t              'name' => '系统拍照发图',\n     * \t              'key' => 'rselfmenu_1_0',\n     * \t            ),\n     * \t            1 => array (\n     * \t              'type' => 'pic_photo_or_album',\n     * \t              'name' => '拍照或者相册发图',\n     * \t              'key' => 'rselfmenu_1_1',\n     * \t            )\n     * \t        ),\n     * \t      ),\n     * \t      2 => array (\n     * \t        'type' => 'location_select',\n     * \t        'name' => '发送位置',\n     * \t        'key' => 'rselfmenu_2_0'\n     * \t      ),\n     * \t    ),\n     * \t)\n     * type可以选择为以下几种，会收到相应类型的事件推送。请注意，3到8的所有事件，仅支持微信iPhone5.4.1以上版本，\n     * 和Android5.4以上版本的微信用户，旧版本微信用户点击后将没有回应，开发者也不能正常接收到事件推送。\n     * 1、click：点击推事件\n     * 2、view：跳转URL\n     * 3、scancode_push：扫码推事件\n     * 4、scancode_waitmsg：扫码推事件且弹出“消息接收中”提示框\n     * 5、pic_sysphoto：弹出系统拍照发图\n     * 6、pic_photo_or_album：弹出拍照或者相册发图\n     * 7、pic_weixin：弹出微信相册发图器\n     * 8、location_select：弹出地理位置选择器\n\t */\n\tpublic function createMenu($data,$agentid=''){\n\t    if ($agentid=='') {\n\t    \t$agentid=$this->agentid;\n\t    }\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::MENU_CREATE_URL.'access_token='.$this->access_token.'&agentid='.$agentid,self::json_encode($data));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 获取菜单\n\t * @return array('menu'=>array(....s))\n\t */\n\tpublic function getMenu($agentid=''){\n\t    if ($agentid=='') {\n\t    \t$agentid=$this->agentid;\n\t    }\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::MENU_GET_URL.'access_token='.$this->access_token.'&agentid='.$agentid);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || isset($json['errcode']) || $json['errcode']!=0) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 删除菜单\n\t * @return boolean\n\t */\n\tpublic function deleteMenu($agentid=''){\n\t    if ($agentid=='') {\n\t    \t$agentid=$this->agentid;\n\t    }\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::MENU_DELETE_URL.'access_token='.$this->access_token.'&agentid='.$agentid);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 上传多媒体文件 (只有三天的有效期，过期自动被删除)\n\t * 注意：上传大文件时可能需要先调用 set_time_limit(0) 避免超时\n\t * 注意：数组的键值任意，但文件名前必须加@，使用单引号以避免本地路径斜杠被转义\n\t * @param array $data {\"media\":'@Path\\filename.jpg'}\n\t * @param type 媒体文件类型:图片（image）、语音（voice）、视频（video），普通文件(file)\n\t * @return boolean|array\n\t * {\n\t *    \"type\": \"image\",\n\t *    \"media_id\": \"0000001\",\n\t *    \"created_at\": \"1380000000\"\n\t * }\n\t */\n\tpublic function uploadMedia($data, $type){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::MEDIA_UPLOAD_URL.'access_token='.$this->access_token.'&type='.$type,$data,true);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 根据媒体文件ID获取媒体文件\n\t * @param string $media_id 媒体文件id\n\t * @return raw data\n\t */\n\tpublic function getMedia($media_id){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::MEDIA_GET_URL.'access_token='.$this->access_token.'&media_id='.$media_id);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (isset($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $result;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 获取企业微信服务器IP地址列表\n\t * @return array('127.0.0.1','127.0.0.1')\n\t */\n\tpublic function getServerIp(){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::CALLBACKSERVER_GET_URL.'access_token='.$this->access_token);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || isset($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json['ip_list'];\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 创建部门\n\t * @param array $data \t结构体为:\n\t * array (\n\t *     \"name\" => \"邮箱产品组\",   //部门名称\n\t *     \"parentid\" => \"1\"         //父部门id\n\t *     \"order\" =>  \"1\",            //(非必须)在父部门中的次序。从1开始，数字越大排序越靠后\n\t * )\n\t * @return boolean|array\n\t * 成功返回结果\n\t * {\n \t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"created\",  //对返回码的文本描述内容\n \t *   \"id\": 2               //创建的部门id。\n\t * }\n\t */\n\tpublic function createDepartment($data){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::DEPARTMENT_CREATE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\n\t/**\n\t * 更新部门\n\t * @param array $data \t结构体为:\n\t * array(\n\t *     \"id\" => \"1\"               //(必须)部门id\n\t *     \"name\" =>  \"邮箱产品组\",   //(非必须)部门名称\n\t *     \"parentid\" =>  \"1\",         //(非必须)父亲部门id。根部门id为1\n\t *     \"order\" =>  \"1\",            //(非必须)在父部门中的次序。从1开始，数字越大排序越靠后\n\t * )\n\t * @return boolean|array 成功返回结果\n\t * {\n\t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"updated\"  //对返回码的文本描述内容\n\t * }\n\t */\n\tpublic function updateDepartment($data){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::DEPARTMENT_UPDATE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 删除部门\n\t * @param $id\n\t * @return boolean|array 成功返回结果\n\t * {\n\t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"deleted\"  //对返回码的文本描述内容\n\t * }\n\t */\n\tpublic function deleteDepartment($id){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_URL_PREFIX.self::DEPARTMENT_DELETE_URL.'access_token='.$this->access_token.'&id='.$id);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 移动部门\n\t * @param $data\n\t * array(\n\t *    \"department_id\" => \"5\",\t//所要移动的部门\n\t *    \"to_parentid\" => \"2\",\t\t//想移动到的父部门节点，根部门为1\n\t *    \"to_position\" => \"1\"\t\t//(非必须)想移动到的父部门下的位置，1表示最上方，往后位置为2，3，4，以此类推，默认为1\n\t * )\n\t * @return boolean|array 成功返回结果\n\t * {\n\t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"ok\"  //对返回码的文本描述内容\n\t * }\n\t */\n\tpublic function moveDepartment($data){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::DEPARTMENT_MOVE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 获取部门列表\n\t * @return boolean|array\t 成功返回结果\n\t * {\n\t *    \"errcode\": 0,\n\t *    \"errmsg\": \"ok\",\n\t *    \"department\": [          //部门列表数据。以部门的order字段从小到大排列\n\t *        {\n\t *            \"id\": 1,\n\t *            \"name\": \"广州研发中心\",\n\t *            \"parentid\": 0,\n\t *            \"order\": 40\n\t *        },\n \t *       {\n\t *          \"id\": 2\n  \t *          \"name\": \"邮箱产品部\",\n  \t *          \"parentid\": 1,\n\t *          \"order\": 40\n \t *       }\n\t *    ]\n\t * }\n\t */\n\tpublic function getDepartment(){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_URL_PREFIX.self::DEPARTMENT_LIST_URL.'access_token='.$this->access_token);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 创建成员\n\t * @param array $data \t结构体为:\n     * array(\n     *    \"userid\" => \"zhangsan\",\n     *    \"name\" => \"张三\",\n     *    \"department\" => [1, 2],\n     *    \"position\" => \"产品经理\",\n     *    \"mobile\" => \"15913215421\",\n     *    \"gender\" => 1,     //性别。gender=0表示男，=1表示女\n     *    \"tel\" => \"62394\",\n     *    \"email\" => \"zhangsan@gzdev.com\",\n     *    \"weixinid\" => \"zhangsan4dev\"\n     * )\n\t * @return boolean|array\n\t * 成功返回结果\n\t * {\n\t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"created\",  //对返回码的文本描述内容\n\t * }\n\t */\n\tpublic function createUser($data){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::USER_CREATE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\n\t/**\n\t * 更新成员\n\t * @param array $data \t结构体为:\n     * array(\n     *    \"userid\" => \"zhangsan\",\n     *    \"name\" => \"张三\",\n     *    \"department\" => [1, 2],\n     *    \"position\" => \"产品经理\",\n     *    \"mobile\" => \"15913215421\",\n     *    \"gender\" => 1,     //性别。gender=0表示男，=1表示女\n     *    \"tel\" => \"62394\",\n     *    \"email\" => \"zhangsan@gzdev.com\",\n     *    \"weixinid\" => \"zhangsan4dev\"\n     * )\n\t * @return boolean|array 成功返回结果\n\t * {\n\t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"updated\"  //对返回码的文本描述内容\n\t * }\n\t */\n\tpublic function updateUser($data){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::USER_UPDATE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 删除成员\n\t * @param $userid  员工UserID。对应管理端的帐号\n\t * @return boolean|array 成功返回结果\n\t * {\n\t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"deleted\"  //对返回码的文本描述内容\n\t * }\n\t */\n\tpublic function deleteUser($userid){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_URL_PREFIX.self::USER_DELETE_URL.'access_token='.$this->access_token.'&userid='.$userid);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 批量删除成员\n\t * @param array $userid  员工UserID数组。对应管理端的帐号\n\t * {\n\t *     'userid1',\n\t *     'userid2',\n\t *     'userid3',\n\t * }\n\t * @return boolean|array 成功返回结果\n\t * {\n\t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"deleted\"  //对返回码的文本描述内容\n\t * }\n\t */\n\tpublic function deleteUsers($userids){\n\t    if (!$userids) return false;\n\t    $data = array('useridlist'=>$userids);\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::USER_BATCHDELETE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 获取成员信息\n\t * @param $userid  员工UserID。对应管理端的帐号\n\t * @return boolean|array\t 成功返回结果\n\t * {\n\t *    \"errcode\": 0,\n\t *    \"errmsg\": \"ok\",\n\t *    \"userid\": \"zhangsan\",\n\t *    \"name\": \"李四\",\n\t *    \"department\": [1, 2],\n\t *    \"position\": \"后台工程师\",\n\t *    \"mobile\": \"15913215421\",\n\t *    \"gender\": 1,     //性别。gender=0表示男，=1表示女\n\t *    \"tel\": \"62394\",\n\t *    \"email\": \"zhangsan@gzdev.com\",\n\t *    \"weixinid\": \"lisifordev\",        //微信号\n\t *    \"avatar\": \"http://wx.qlogo.cn/mmopen/ajNVdqHZLLA3W..../0\",   //头像url。注：如果要获取小图将url最后的\"/0\"改成\"/64\"即可\n\t *    \"status\": 1      //关注状态: 1=已关注，2=已冻结，4=未关注\n\t *    \"extattr\": {\"attrs\":[{\"name\":\"爱好\",\"value\":\"旅游\"},{\"name\":\"卡号\",\"value\":\"1234567234\"}]}\n\t * }\n\t */\n\tpublic function getUserInfo($userid){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_URL_PREFIX.self::USER_GET_URL.'access_token='.$this->access_token.'&userid='.$userid);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 获取部门成员\n\t * @param $department_id   部门id\n\t * @param $fetch_child     1/0：是否递归获取子部门下面的成员\n\t * @param $status          0获取全部员工，1获取已关注成员列表，2获取禁用成员列表，4获取未关注成员列表。status可叠加\n\t * @return boolean|array\t 成功返回结果\n\t * {\n\t *    \"errcode\": 0,\n\t *    \"errmsg\": \"ok\",\n\t *    \"userlist\": [\n\t *            {\n\t *                   \"userid\": \"zhangsan\",\n\t *                   \"name\": \"李四\"\n\t *            }\n\t *      ]\n\t * }\n\t */\n\tpublic function getUserList($department_id,$fetch_child=0,$status=0){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_URL_PREFIX.self::USER_LIST_URL.'access_token='.$this->access_token\n\t            .'&department_id='.$department_id.'&fetch_child='.$fetch_child.'&status='.$status);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 获取部门成员详情\n\t * @param $department_id   部门id\n\t * @param $fetch_child     1/0：是否递归获取子部门下面的成员\n\t * @param $status          0获取全部员工，1获取已关注成员列表，2获取禁用成员列表，4获取未关注成员列表。status可叠加\n\t * @return boolean|array\t 成功返回结果\n\t * {\n\t *    \"errcode\": 0,\n\t *    \"errmsg\": \"ok\",\n\t *    \"userlist\": [\n\t *            {\n\t *                   \"userid\": \"zhangsan\",\n\t *                   \"name\": \"李四\",\n\t *                   \"department\": [1, 2],\n\t *                   \"position\": \"后台工程师\",\n\t *                   \"mobile\": \"15913215421\",\n\t *                   \"gender\": 1,     //性别。gender=0表示男，=1表示女\n\t *                   \"tel\": \"62394\",\n\t *                   \"email\": \"zhangsan@gzdev.com\",\n\t *                   \"weixinid\": \"lisifordev\",        //微信号\n\t *                   \"avatar\": \"http://wx.qlogo.cn/mmopen/ajNVdqHZLLA3W..../0\",   //头像url。注：如果要获取小图将url最后的\"/0\"改成\"/64\"即可\n\t *                   \"status\": 1      //关注状态: 1=已关注，2=已冻结，4=未关注\n\t *                   \"extattr\": {\"attrs\":[{\"name\":\"爱好\",\"value\":\"旅游\"},{\"name\":\"卡号\",\"value\":\"1234567234\"}]}\n\t *            }\n\t *      ]\n\t * }\n\t */\n\tpublic function getUserListInfo($department_id,$fetch_child=0,$status=0){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_URL_PREFIX.self::USER_LIST_INFO_URL.'access_token='.$this->access_token\n\t            .'&department_id='.$department_id.'&fetch_child='.$fetch_child.'&status='.$status);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 根据code获取成员信息\n\t * 通过Oauth2.0或者设置了二次验证时获取的code，用于换取成员的UserId和DeviceId\n\t *\n\t * @param $code        Oauth2.0或者二次验证时返回的code值\n\t * @param $agentid     跳转链接时所在的企业应用ID，未填则默认为当前配置的应用id\n\t * @return boolean|array 成功返回数组\n\t * array(\n\t *     'UserId' => 'USERID',       //员工UserID\n\t *     'DeviceId' => 'DEVICEID'    //手机设备号(由微信在安装时随机生成)\n\t * )\n\t */\n\tpublic function getUserId($code,$agentid=0){\n\t    if (!$agentid) $agentid=$this->agentid;\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_URL_PREFIX.self::USER_GETINFO_URL.'access_token='.$this->access_token.'&code='.$code.'&agentid'.$agentid);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 邀请成员关注\n\t * 向未关注企业号的成员发送关注邀请。认证号优先判断顺序weixinid>手机号>邮箱绑定>邮件；非认证号只能邮件邀请\n\t *\n\t * @param $userid        用户的userid\n\t * @param $invite_tips   推送到微信上的提示语（只有认证号可以使用）。当使用微信推送时，该字段默认为“请关注XXX企业号”，邮件邀请时，该字段无效。\n\t * @return boolean|array 成功返回数组\n\t * array(\n\t *     'errcode' => 0,\n\t *     'errmsg' => 'ok',\n\t *     'type' => 1         //邀请方式 1.微信邀请 2.邮件邀请\n\t * )\n\t */\n\tpublic function sendInvite($userid,$invite_tips=''){\n\t    $data = array( 'userid' => $userid );\n\t    if (!$invite_tips) {\n\t    \t$data['invite_tips'] = $invite_tips;\n\t    }\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::USER_INVITE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 创建标签\n\t * @param array $data \t结构体为:\n\t * array(\n\t *    \"tagname\" => \"UI\"\n\t * )\n\t * @return boolean|array\n\t * 成功返回结果\n\t * {\n\t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"created\",  //对返回码的文本描述内容\n\t *   \"tagid\": \"1\"\n\t * }\n\t */\n\tpublic function createTag($data){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::TAG_CREATE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 更新标签\n\t * @param array $data \t结构体为:\n\t * array(\n\t *    \"tagid\" => \"1\",\n\t *    \"tagname\" => \"UI design\"\n\t * )\n\t * @return boolean|array 成功返回结果\n\t * {\n\t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"updated\"  //对返回码的文本描述内容\n\t * }\n\t */\n\tpublic function updateTag($data){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::TAG_UPDATE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 删除标签\n\t * @param $tagid  标签TagID\n\t * @return boolean|array 成功返回结果\n\t * {\n\t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"deleted\"  //对返回码的文本描述内容\n\t * }\n\t */\n\tpublic function deleteTag($tagid){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_URL_PREFIX.self::TAG_DELETE_URL.'access_token='.$this->access_token.'&tagid='.$tagid);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 获取标签成员\n\t * @param $tagid  标签TagID\n\t * @return boolean|array\t 成功返回结果\n\t * {\n\t *    \"errcode\": 0,\n\t *    \"errmsg\": \"ok\",\n\t *    \"userlist\": [\n\t *          {\n\t *              \"userid\": \"zhangsan\",\n\t *              \"name\": \"李四\"\n\t *          }\n\t *      ]\n\t * }\n\t */\n\tpublic function getTag($tagid){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_URL_PREFIX.self::TAG_GET_URL.'access_token='.$this->access_token.'&tagid='.$tagid);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 增加标签成员\n\t * @param array $data \t结构体为:\n\t * array (\n\t *    \"tagid\" => \"1\",\n\t *    \"userlist\" => array(    //企业员工ID列表\n\t *         \"user1\",\n\t *         \"user2\"\n\t *     )\n\t * )\n\t * @return boolean|array\n\t * 成功返回结果\n\t * {\n\t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"ok\",  //对返回码的文本描述内容\n\t *   \"invalidlist\"：\"usr1|usr2|usr\"     //若部分userid非法，则会有此段。不在权限内的员工ID列表，以“|”分隔\n\t * }\n\t */\n\tpublic function addTagUser($data){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::TAG_ADDUSER_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 删除标签成员\n\t * @param array $data \t结构体为:\n\t * array (\n\t *    \"tagid\" => \"1\",\n\t *    \"userlist\" => array(    //企业员工ID列表\n\t *         \"user1\",\n\t *         \"user2\"\n\t *     )\n\t * )\n\t * @return boolean|array\n\t * 成功返回结果\n\t * {\n\t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"deleted\",  //对返回码的文本描述内容\n\t *   \"invalidlist\"：\"usr1|usr2|usr\"     //若部分userid非法，则会有此段。不在权限内的员工ID列表，以“|”分隔\n\t * }\n\t */\n\tpublic function delTagUser($data){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::TAG_DELUSER_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 获取标签列表\n\t * @return boolean|array\t 成功返回数组结果，这里附上json样例\n\t * {\n\t *    \"errcode\": 0,\n\t *    \"errmsg\": \"ok\",\n\t *    \"taglist\":[\n\t *       {\"tagid\":1,\"tagname\":\"a\"},\n\t *       {\"tagid\":2,\"tagname\":\"b\"}\n\t *    ]\n\t * }\n\t */\n\tpublic function getTagList(){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_URL_PREFIX.self::TAG_LIST_URL.'access_token='.$this->access_token);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 主动发送信息接口\n\t * @param array $data \t结构体为:\n\t * array(\n\t *         \"touser\" => \"UserID1|UserID2|UserID3\",\n\t *         \"toparty\" => \"PartyID1|PartyID2 \",\n\t *         \"totag\" => \"TagID1|TagID2 \",\n\t *         \"safe\":\"0\"\t\t\t//是否为保密消息，对于news无效\n\t *         \"agentid\" => \"001\",\t//应用id\n\t *         \"msgtype\" => \"text\",  //根据信息类型，选择下面对应的信息结构体\n\t *\n\t *         \"text\" => array(\n\t *                 \"content\" => \"Holiday Request For Pony(http://xxxxx)\"\n\t *         ),\n\t *\n\t *         \"image\" => array(\n\t *                 \"media_id\" => \"MEDIA_ID\"\n\t *         ),\n\t *\n\t *         \"voice\" => array(\n\t *                 \"media_id\" => \"MEDIA_ID\"\n\t *         ),\n\t *\n\t *         \" video\" => array(\n\t *                 \"media_id\" => \"MEDIA_ID\",\n\t *                 \"title\" => \"Title\",\n\t *                 \"description\" => \"Description\"\n\t *         ),\n\t *\n\t *         \"file\" => array(\n\t *                 \"media_id\" => \"MEDIA_ID\"\n\t *         ),\n\t *\n\t *         \"news\" => array(\t\t\t//不支持保密\n\t *                 \"articles\" => array(    //articles  图文消息，一个图文消息支持1到10个图文\n\t *                     array(\n\t *                         \"title\" => \"Title\",             //标题\n\t *                         \"description\" => \"Description\", //描述\n\t *                         \"url\" => \"URL\",                 //点击后跳转的链接。可根据url里面带的code参数校验员工的真实身份。\n\t *                         \"picurl\" => \"PIC_URL\",          //图文消息的图片链接,支持JPG、PNG格式，较好的效果为大图640*320，\n\t *                                                         //小图80*80。如不填，在客户端不显示图片\n\t *                     ),\n\t *                 )\n\t *         ),\n\t *\n\t *         \"mpnews\" => array(\n\t *                 \"articles\" => array(    //articles  图文消息，一个图文消息支持1到10个图文\n\t *                     array(\n\t *                         \"title\" => \"Title\",             //图文消息的标题\n\t *                         \"thumb_media_id\" => \"id\",       //图文消息缩略图的media_id\n\t *                         \"author\" => \"Author\",           //图文消息的作者(可空)\n\t *                         \"content_source_url\" => \"URL\",  //图文消息点击“阅读原文”之后的页面链接(可空)\n\t *                         \"content\" => \"Content\"          //图文消息的内容，支持html标签\n\t *                         \"digest\" => \"Digest description\",   //图文消息的描述\n\t *                         \"show_cover_pic\" => \"0\"         //是否显示封面，1为显示，0为不显示(可空)\n\t *                     ),\n\t *                 )\n\t *         )\n\t * )\n\t * 请查看官方开发文档中的 发送消息 -> 消息类型及数据格式\n\t *\n\t * @return boolean|array\n\t * 如果对应用或收件人、部门、标签任何一个无权限，则本次发送失败；\n\t * 如果收件人、部门或标签不存在，发送仍然执行，但返回无效的部分。\n\t * {\n\t *    \"errcode\": 0,\n\t *    \"errmsg\": \"ok\",\n\t *    \"invaliduser\": \"UserID1\",\n\t *    \"invalidparty\":\"PartyID1\",\n\t *    \"invalidtag\":\"TagID1\"\n\t * }\n\t */\n\tpublic function sendMessage($data){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::MASS_SEND_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 二次验证\n\t * 企业在开启二次验证时，必须填写企业二次验证页面的url。\n\t * 当员工绑定通讯录中的帐号后，会收到一条图文消息，\n\t * 引导员工到企业的验证页面验证身份，企业在员工验证成功后，\n\t * 调用如下接口即可让员工关注成功。\n\t *\n\t * @param $userid\n\t * @return boolean|array 成功返回结果\n\t * {\n\t *   \"errcode\": 0,        //返回码\n\t *   \"errmsg\": \"ok\"  //对返回码的文本描述内容\n\t * }\n\t */\n\tpublic function authSucc($userid){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_URL_PREFIX.self::AUTHSUCC_URL.'access_token='.$this->access_token.'&userid='.$userid);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode']) || $json['errcode']!=0) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * oauth 授权跳转接口\n\t * @param string $callback 回调URI\n\t * @param string $state 重定向后会带上state参数，企业可以填写a-zA-Z0-9的参数值\n\t * @return string\n\t */\n\tpublic function getOauthRedirect($callback,$state='STATE',$scope='snsapi_base'){\n\t    return self::OAUTH_PREFIX.self::OAUTH_AUTHORIZE_URL.'appid='.$this->appid.'&redirect_uri='.urlencode($callback).'&response_type=code&scope='.$scope.'&state='.$state.'#wechat_redirect';\n\t}\n\n}\n\n\n\n/**\n * PKCS7Encoder class\n *\n * 提供基于PKCS7算法的加解密接口.\n */\nclass PKCS7Encoder\n{\n    public static $block_size = 32;\n\n    /**\n     * 对需要加密的明文进行填充补位\n     * @param $text 需要进行填充补位操作的明文\n     * @return 补齐明文字符串\n     */\n    function encode($text)\n    {\n        $block_size = PKCS7Encoder::$block_size;\n        $text_length = strlen($text);\n        //计算需要填充的位数\n        $amount_to_pad = PKCS7Encoder::$block_size - ($text_length % PKCS7Encoder::$block_size);\n        if ($amount_to_pad == 0) {\n            $amount_to_pad = PKCS7Encoder::block_size;\n        }\n        //获得补位所用的字符\n        $pad_chr = chr($amount_to_pad);\n        $tmp = \"\";\n        for ($index = 0; $index < $amount_to_pad; $index++) {\n            $tmp .= $pad_chr;\n        }\n        return $text . $tmp;\n    }\n\n    /**\n     * 对解密后的明文进行补位删除\n     * @param decrypted 解密后的明文\n     * @return 删除填充补位后的明文\n     */\n    function decode($text)\n    {\n\n        $pad = ord(substr($text, -1));\n        if ($pad < 1 || $pad > PKCS7Encoder::$block_size) {\n            $pad = 0;\n        }\n        return substr($text, 0, (strlen($text) - $pad));\n    }\n\n}\n\n/**\n * Prpcrypt class\n *\n * 提供接收和推送给公众平台消息的加解密接口.\n */\nclass Prpcrypt\n{\n    public $key;\n\n    function __construct($k) {\n        $this->key = base64_decode($k . \"=\");\n    }\n\n    /**\n     * 兼容老版本php构造函数，不能在 __construct() 方法前边，否则报错\n     */\n    function Prpcrypt($k)\n    {\n        $this->key = base64_decode($k . \"=\");\n    }\n\n    /**\n     * 对明文进行加密\n     * @param string $text 需要加密的明文\n     * @return string 加密后的密文\n     */\n    public function encrypt($text, $appid)\n    {\n\n        try {\n            //获得16位随机字符串，填充到明文之前\n            $random = $this->getRandomStr();//\"aaaabbbbccccdddd\";\n            $text = $random . pack(\"N\", strlen($text)) . $text . $appid;\n            // 网络字节序\n            $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);\n            $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');\n            $iv = substr($this->key, 0, 16);\n            //使用自定义的填充方式对明文进行补位填充\n            $pkc_encoder = new PKCS7Encoder;\n            $text = $pkc_encoder->encode($text);\n            mcrypt_generic_init($module, $this->key, $iv);\n            //加密\n            $encrypted = mcrypt_generic($module, $text);\n            mcrypt_generic_deinit($module);\n            mcrypt_module_close($module);\n\n            //\t\t\tprint(base64_encode($encrypted));\n            //使用BASE64对加密后的字符串进行编码\n            return array(ErrorCode::$OK, base64_encode($encrypted));\n        } catch (Exception $e) {\n            //print $e;\n            return array(ErrorCode::$EncryptAESError, null);\n        }\n    }\n\n    /**\n     * 对密文进行解密\n     * @param string $encrypted 需要解密的密文\n     * @return string 解密得到的明文\n     */\n    public function decrypt($encrypted, $appid)\n    {\n\n        try {\n            //使用BASE64对需要解密的字符串进行解码\n            $ciphertext_dec = base64_decode($encrypted);\n            $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');\n            $iv = substr($this->key, 0, 16);\n            mcrypt_generic_init($module, $this->key, $iv);\n            //解密\n            $decrypted = mdecrypt_generic($module, $ciphertext_dec);\n            mcrypt_generic_deinit($module);\n            mcrypt_module_close($module);\n        } catch (Exception $e) {\n            return array(ErrorCode::$DecryptAESError, null);\n        }\n\n\n        try {\n            //去除补位字符\n            $pkc_encoder = new PKCS7Encoder;\n            $result = $pkc_encoder->decode($decrypted);\n            //去除16位随机字符串,网络字节序和AppId\n            if (strlen($result) < 16)\n                return \"\";\n            $content = substr($result, 16, strlen($result));\n            $len_list = unpack(\"N\", substr($content, 0, 4));\n            $xml_len = $len_list[1];\n            $xml_content = substr($content, 4, $xml_len);\n            $from_appid = substr($content, $xml_len + 4);\n        } catch (Exception $e) {\n            //print $e;\n            return array(ErrorCode::$IllegalBuffer, null);\n        }\n        if ($from_appid != $appid)\n            return array(ErrorCode::$ValidateAppidError, null);\n        return array(0, $xml_content);\n\n    }\n\n\n    /**\n     * 随机生成16位字符串\n     * @return string 生成的字符串\n     */\n    function getRandomStr()\n    {\n\n        $str = \"\";\n        $str_pol = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz\";\n        $max = strlen($str_pol) - 1;\n        for ($i = 0; $i < 16; $i++) {\n            $str .= $str_pol[mt_rand(0, $max)];\n        }\n        return $str;\n    }\n\n}\n\n/**\n * error code\n * 仅用作类内部使用，不用于官方API接口的errCode码\n */\nclass ErrorCode\n{\n    public static $OK = 0;\n    public static $ValidateSignatureError = 40001;\n    public static $ParseXmlError = 40002;\n    public static $ComputeSignatureError = 40003;\n    public static $IllegalAesKey = 40004;\n    public static $ValidateAppidError = 40005;\n    public static $EncryptAESError = 40006;\n    public static $DecryptAESError = 40007;\n    public static $IllegalBuffer = 40008;\n    public static $EncodeBase64Error = 40009;\n    public static $DecodeBase64Error = 40010;\n    public static $GenReturnXmlError = 40011;\n    public static $errCode=array(\n            '0'=>'无问题',\n            '40001'=>'签名验证错误',\n            '40002'=>'xml解析失败',\n            '40003'=>'sha加密生成签名失败',\n            '40004'=>'encodingAesKey 非法',\n            '40005'=>'appid 校验错误',\n            '40006'=>'aes 加密失败',\n            '40007'=>'aes 解密失败',\n            '40008'=>'解密后得到的buffer非法',\n            '40009'=>'base64加密失败',\n            '40010'=>'base64解密失败',\n            '40011'=>'生成xml失败',\n    );\n    public static function getErrText($err) {\n        if (isset(self::$errCode[$err])) {\n            return self::$errCode[$err];\n        }else {\n            return false;\n        };\n    }\n}\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/test/auth.php",
    "content": "<?php\n/**\n * 微信oAuth认证示例\n */\ninclude(\"../wechat.class.php\");\nclass wxauth {\n\tprivate $options;\n\tpublic $open_id;\n\tpublic $wxuser;\n\t\n\tpublic function __construct($options){\n\t\t$this->options = $options;\n\t\t$this->wxoauth();\n\t\tsession_start();\n\t}\n\t\n\tpublic function wxoauth(){\n\t\t$scope = 'snsapi_base';\n\t\t$code = isset($_GET['code'])?$_GET['code']:'';\n\t\t$token_time = isset($_SESSION['token_time'])?$_SESSION['token_time']:0;\n\t\tif(!$code && isset($_SESSION['open_id']) && isset($_SESSION['user_token']) && $token_time>time()-3600)\n\t\t{\n\t\t\tif (!$this->wxuser) {\n\t\t\t\t$this->wxuser = $_SESSION['wxuser'];\n\t\t\t}\n\t\t\t$this->open_id = $_SESSION['open_id'];\n\t\t\treturn $this->open_id;\n\t\t}\n\t\telse\n\t\t{\n\t\t\t$options = array(\n\t\t\t\t\t'token'=>$this->options[\"token\"], //填写你设定的key\n\t\t\t\t\t'appid'=>$this->options[\"appid\"], //填写高级调用功能的app id\n\t\t\t\t\t'appsecret'=>$this->options[\"appsecret\"] //填写高级调用功能的密钥\n\t\t\t);\n\t\t\t$we_obj = new Wechat($options);\n\t\t\tif ($code) {\n\t\t\t\t$json = $we_obj->getOauthAccessToken();\n\t\t\t\tif (!$json) {\n\t\t\t\t\tunset($_SESSION['wx_redirect']);\n\t\t\t\t\tdie('获取用户授权失败，请重新确认');\n\t\t\t\t}\n\t\t\t\t$_SESSION['open_id'] = $this->open_id = $json[\"openid\"];\n\t\t\t\t$access_token = $json['access_token'];\n\t\t\t\t$_SESSION['user_token'] = $access_token;\n\t\t\t\t$_SESSION['token_time'] = time();\n\t\t\t\t$userinfo = $we_obj->getUserInfo($this->open_id);\n\t\t\t\tif ($userinfo && !empty($userinfo['nickname'])) {\n\t\t\t\t\t$this->wxuser = array(\n\t\t\t\t\t\t\t'open_id'=>$this->open_id,\n\t\t\t\t\t\t\t'nickname'=>$userinfo['nickname'],\n\t\t\t\t\t\t\t'sex'=>intval($userinfo['sex']),\n\t\t\t\t\t\t\t'location'=>$userinfo['province'].'-'.$userinfo['city'],\n\t\t\t\t\t\t\t'avatar'=>$userinfo['headimgurl']\n\t\t\t\t\t);\n\t\t\t\t} elseif (strstr($json['scope'],'snsapi_userinfo')!==false) {\n\t\t\t\t\t$userinfo = $we_obj->getOauthUserinfo($access_token,$this->open_id);\n\t\t\t\t\tif ($userinfo && !empty($userinfo['nickname'])) {\n\t\t\t\t\t\t$this->wxuser = array(\n\t\t\t\t\t\t\t\t'open_id'=>$this->open_id,\n\t\t\t\t\t\t\t\t'nickname'=>$userinfo['nickname'],\n\t\t\t\t\t\t\t\t'sex'=>intval($userinfo['sex']),\n\t\t\t\t\t\t\t\t'location'=>$userinfo['province'].'-'.$userinfo['city'],\n\t\t\t\t\t\t\t\t'avatar'=>$userinfo['headimgurl']\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn $this->open_id;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ($this->wxuser) {\n\t\t\t\t\t$_SESSION['wxuser'] = $this->wxuser;\n\t\t\t\t\t$_SESSION['open_id'] =  $json[\"openid\"];\n\t\t\t\t\tunset($_SESSION['wx_redirect']);\n\t\t\t\t\treturn $this->open_id;\n\t\t\t\t}\n\t\t\t\t$scope = 'snsapi_userinfo';\n\t\t\t}\n\t\t\tif ($scope=='snsapi_base') {\n\t\t\t\t$url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];\n\t\t\t\t$_SESSION['wx_redirect'] = $url;\n\t\t\t} else {\n\t\t\t\t$url = $_SESSION['wx_redirect'];\n\t\t\t}\n\t\t\tif (!$url) {\n\t\t\t\tunset($_SESSION['wx_redirect']);\n\t\t\t\tdie('获取用户授权失败');\n\t\t\t}\n\t\t\t$oauth_url = $we_obj->getOauthRedirect($url,\"wxbase\",$scope);\n\t\t\theader('Location: ' . $oauth_url);\n\t\t}\n\t}\n}\n$options = array(\n\t\t'token'=>'tokenaccesskey', //填写你设定的key\n\t\t'appid'=>'wxdk1234567890', //填写高级调用功能的app id, 请在微信开发模式后台查询\n\t\t'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥\n);\n$auth = new wxauth($options);\nvar_dump($auth->wxuser);\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/test/jsapi/jsapi-demo-6.1.js",
    "content": "wx.ready(function () {\n\talert(\"启动jsapi!\");\n  // 1 判断当前版本是否支持指定 JS 接口，支持批量判断\n  document.querySelector('#checkJsApi').onclick = function () {\n    wx.checkJsApi({\n      jsApiList: [\n                  'checkJsApi',\n                  'onMenuShareTimeline',\n                  'onMenuShareAppMessage',\n                  'onMenuShareQQ',\n                  'onMenuShareWeibo',\n                  'hideMenuItems',\n                  'showMenuItems',\n                  'hideAllNonBaseMenuItem',\n                  'showAllNonBaseMenuItem',\n                  'translateVoice',\n                  'startRecord',\n                  'stopRecord',\n                  'onRecordEnd',\n                  'playVoice',\n                  'pauseVoice',\n                  'stopVoice',\n                  'uploadVoice',\n                  'downloadVoice',\n                  'chooseImage',\n                  'previewImage',\n                  'uploadImage',\n                  'downloadImage',\n                  'getNetworkType',\n                  'openLocation',\n                  'getLocation',\n                  'hideOptionMenu',\n                  'showOptionMenu',\n                  'closeWindow',\n                  'scanQRCode',\n                  'chooseWXPay',\n                  'openProductSpecificView',\n                  'addCard',\n                  'chooseCard',\n                  'openCard'\n                ],\n      success: function (res) {\n      \talert(\"检测通过：\"  +JSON.stringify(res));\n      },\n      fail: function(res) {\n      \talert(\"检测失败：\"  +JSON.stringify(res));\n      },\n      complete: function(res) {\n      \talert(\"检测结束\");\n      }\n    });\n  };\n\n  // 2. 分享接口\n  // 2.1 监听“分享给朋友”，按钮点击、自定义分享内容及分享结果接口\n  document.querySelector('#onMenuShareAppMessage').onclick = function () {\n    wx.onMenuShareAppMessage({\n      title: 'wechat-php-sdk博客',\n      desc: '微信公众平台php开发包,细化各项接口操作,支持链式调用。项目创建人：dodgepudding 项目地址：https://github.com/dodgepudding/wechat-php-sdk',\n      link: 'http://binsee.github.io/wechat-php-sdk/',\n      imgUrl: 'http://binsee.github.io/wechat-php-sdk/img/author.jpg',\n      trigger: function (res) {\n      \talert(\"点击分享：\" +JSON.stringify(res));\n          // 用户确认分享后执行的回调函数\n      },\n      success: function (res) {\n      \talert(\"分享成功：\" +JSON.stringify(res));\n          // 用户确认分享后执行的回调函数\n      },\n      cancel: function (res) {\n      \talert(\"取消分享：\" +JSON.stringify(res));\n          // 用户取消分享后执行的回调函数\n      },\n      fail:function (res) {\n      \talert(\"分享失败：\" +JSON.stringify(res));\n      }\n    });\n    alert('已注册获取“发送给朋友”状态事件');\n  };\n\n  // 2.2 监听“分享到朋友圈”按钮点击、自定义分享内容及分享结果接口\n  document.querySelector('#onMenuShareTimeline').onclick = function () {\n    wx.onMenuShareTimeline({\n      title: 'wechat-php-sdk博客',\n      desc: '微信公众平台php开发包,细化各项接口操作,支持链式调用。项目创建人：dodgepudding 项目地址：https://github.com/dodgepudding/wechat-php-sdk',\n      link: 'http://binsee.github.io/wechat-php-sdk/',\n      imgUrl: 'http://binsee.github.io/wechat-php-sdk/img/author.jpg',\n      trigger: function (res) {\n        \talert(\"点击分享：\" +JSON.stringify(res));\n            // 用户确认分享后执行的回调函数\n        },\n        success: function (res) {\n        \talert(\"分享成功：\" +JSON.stringify(res));\n            // 用户确认分享后执行的回调函数\n        },\n        cancel: function (res) {\n        \talert(\"取消分享：\" +JSON.stringify(res));\n            // 用户取消分享后执行的回调函数\n        },\n        fail:function (res) {\n        \talert(\"分享失败：\" +JSON.stringify(res));\n        }\n    });\n    alert('已注册获取“分享到朋友圈”状态事件');\n  };\n\n  // 2.3 监听“分享到QQ”按钮点击、自定义分享内容及分享结果接口\n  document.querySelector('#onMenuShareQQ').onclick = function () {\n    wx.onMenuShareQQ({\n      title: 'wechat-php-sdk博客',\n      desc: '微信公众平台php开发包,细化各项接口操作,支持链式调用。项目创建人：dodgepudding 项目地址：https://github.com/dodgepudding/wechat-php-sdk',\n      link: 'http://binsee.github.io/wechat-php-sdk/',\n      imgUrl: 'http://binsee.github.io/wechat-php-sdk/img/author.jpg',\n      trigger: function (res) {\n      \talert(\"点击分享：\" +JSON.stringify(res));\n          // 用户确认分享后执行的回调函数\n      },\n      success: function (res) {\n      \talert(\"分享成功：\" +JSON.stringify(res));\n          // 用户确认分享后执行的回调函数\n      },\n      cancel: function (res) {\n      \talert(\"取消分享：\" +JSON.stringify(res));\n          // 用户取消分享后执行的回调函数\n      },\n      fail:function (res) {\n      \talert(\"分享失败：\" +JSON.stringify(res));\n      }\n    });\n    alert('已注册获取“分享到 QQ”状态事件');\n  };\n  \n  // 2.4 监听“分享到微博”按钮点击、自定义分享内容及分享结果接口\n  document.querySelector('#onMenuShareWeibo').onclick = function () {\n    wx.onMenuShareWeibo({\n      title: 'wechat-php-sdk博客',\n      desc: '微信公众平台php开发包,细化各项接口操作,支持链式调用。项目创建人：dodgepudding 项目地址：https://github.com/dodgepudding/wechat-php-sdk',\n      link: 'http://binsee.github.io/wechat-php-sdk/',\n      imgUrl: 'http://binsee.github.io/wechat-php-sdk/img/author.jpg',\n      trigger: function (res) {\n        \talert(\"点击分享：\" +JSON.stringify(res));\n            // 用户确认分享后执行的回调函数\n        },\n        success: function (res) {\n        \talert(\"分享成功：\" +JSON.stringify(res));\n            // 用户确认分享后执行的回调函数\n        },\n        cancel: function (res) {\n        \talert(\"取消分享：\" +JSON.stringify(res));\n            // 用户取消分享后执行的回调函数\n        },\n        fail:function (res) {\n        \talert(\"分享失败：\" +JSON.stringify(res));\n        }\n    });\n    alert('已注册获取“分享到微博”状态事件');\n  };\n\n\n  // 3 智能接口\n  var voice = {\n    localId: '',\n    serverId: ''\n  };\n  // 3.1 识别音频并返回识别结果\n  document.querySelector('#translateVoice').onclick = function () {\n    if (voice.localId == '') {\n      alert('请先使用 startRecord 接口录制一段声音');\n      return;\n    }\n    wx.translateVoice({\n      localId: voice.localId,\n      complete: function (res) {\n        if (res.hasOwnProperty('translateResult')) {\n          alert('识别结果：' + res.translateResult);\n        } else {\n          alert('无法识别');\n        }\n      }\n    });\n  };\n\n  // 4 音频接口\n  // 4.2 开始录音\n  document.querySelector('#startRecord').onclick = function () {\n    wx.startRecord({\n      cancel: function () {\n        alert('用户拒绝授权录音');\n      }\n    });\n  };\n\n  // 4.3 停止录音\n  document.querySelector('#stopRecord').onclick = function () {\n    wx.stopRecord({\n      success: function (res) {\n        voice.localId = res.localId;\n      },\n      fail: function (res) {\n        alert(JSON.stringify(res));\n      }\n    });\n  };\n\n  // 4.4 监听录音自动停止\n  wx.onVoiceRecordEnd({\n    complete: function (res) {\n      voice.localId = res.localId;\n      alert('录音时间已超过一分钟');\n    }\n  });\n\n  // 4.5 播放音频\n  document.querySelector('#playVoice').onclick = function () {\n    if (voice.localId == '') {\n      alert('请先使用 startRecord 接口录制一段声音');\n      return;\n    }\n    wx.playVoice({\n      localId: voice.localId\n    });\n  };\n\n  // 4.6 暂停播放音频\n  document.querySelector('#pauseVoice').onclick = function () {\n    wx.pauseVoice({\n      localId: voice.localId\n    });\n  };\n\n  // 4.7 停止播放音频\n  document.querySelector('#stopVoice').onclick = function () {\n    wx.stopVoice({\n      localId: voice.localId\n    });\n  };\n\n  // 4.8 监听录音播放停止\n  wx.onVoicePlayEnd({\n    complete: function (res) {\n      alert('录音（' + res.localId + '）播放结束');\n    }\n  });\n\n  // 4.8 上传语音\n  document.querySelector('#uploadVoice').onclick = function () {\n    if (voice.localId == '') {\n      alert('请先使用 startRecord 接口录制一段声音');\n      return;\n    }\n    wx.uploadVoice({\n      localId: voice.localId,\n      success: function (res) {\n        alert('上传语音成功，serverId 为' + res.serverId);\n        voice.serverId = res.serverId;\n        alert(\"上传语音信息：\" + JSON.stringify(res));\n      }\n    });\n  };\n\n  // 4.9 下载语音\n  document.querySelector('#downloadVoice').onclick = function () {\n    if (voice.serverId == '') {\n      alert('请先使用 uploadVoice 上传声音');\n      return;\n    }\n    wx.downloadVoice({\n      serverId: voice.serverId,\n      success: function (res) {\n        alert('下载语音成功，localId 为' + res.localId);\n        voice.localId = res.localId;\n        alert(\"下载语音信息：\" + JSON.stringify(res));\n      }\n    });\n  };\n\n  // 5 图片接口\n  // 5.1 拍照、本地选图\n  var images = {\n    localId: [],\n    serverId: []\n  };\n  document.querySelector('#chooseImage').onclick = function () {\n    wx.chooseImage({\n      success: function (res) {\n        images.localId = res.localIds;\n        alert('已选择 ' + res.localIds.length + ' 张图片');\n      }\n    });\n  };\n\n  // 5.2 图片预览\n  document.querySelector('#previewImage').onclick = function () {\n    wx.previewImage({\n      current: 'http://img5.douban.com/view/photo/photo/public/p1353993776.jpg',\n      urls: [\n        'http://img3.douban.com/view/photo/photo/public/p2152117150.jpg',\n        'http://img5.douban.com/view/photo/photo/public/p1353993776.jpg',\n        'http://img3.douban.com/view/photo/photo/public/p2152134700.jpg'\n      ]\n    });\n  };\n\n  // 5.3 上传图片\n  document.querySelector('#uploadImage').onclick = function () {\n    if (images.localId.length == 0) {\n      alert('请先使用 chooseImage 接口选择图片');\n      return;\n    }\n    var i = 0, length = images.localId.length;\n    images.serverId = [];\n    function upload() {\n      wx.uploadImage({\n        localId: images.localId[i],\n        success: function (res) {\n          i++;\n            alert('已上传：' + i + '/' + length);\n            alert(\"上传图片信息：\" + JSON.stringify(res));\n          images.serverId.push(res.serverId);\n          if (i < length) {\n            upload();\n          }\n        },\n        fail: function (res) {\n          alert(JSON.stringify(res));\n        }\n      });\n    }\n    upload();\n  };\n\n  // 5.4 下载图片\n  document.querySelector('#downloadImage').onclick = function () {\n    if (images.serverId.length === 0) {\n      alert('请先使用 uploadImage 上传图片');\n      return;\n    }\n    var i = 0, length = images.serverId.length;\n    images.localId = [];\n    function download() {\n      wx.downloadImage({\n        serverId: images.serverId[i],\n        success: function (res) {\n          i++;\n            alert('已下载：' + i + '/' + length);\n            alert(\"下载图片信息：\" + JSON.stringify(res));\n          images.localId.push(res.localId);\n          if (i < length) {\n            download();\n          }\n        }\n      });\n    }\n    download();\n  };\n\n  // 6 设备信息接口\n  // 6.1 获取当前网络状态\n  document.querySelector('#getNetworkType').onclick = function () {\n    wx.getNetworkType({\n      success: function (res) {\n        alert(res.networkType);\n      },\n      fail: function (res) {\n        alert(JSON.stringify(res));\n      }\n    });\n  };\n\n  // 7 地理位置接口\n  // 7.1 查看地理位置\n  document.querySelector('#openLocation').onclick = function () {\n    wx.openLocation({\n      latitude: 23.099994,\n      longitude: 113.324520,\n      name: 'TIT 创意园',\n      address: '广州市海珠区新港中路 397 号',\n      scale: 14,\n      infoUrl: 'http://weixin.qq.com'\n    });\n  };\n\n  // 7.2 获取当前地理位置\n  document.querySelector('#getLocation').onclick = function () {\n    wx.getLocation({\n      success: function (res) {\n        alert(JSON.stringify(res));\n      },\n      cancel: function (res) {\n        alert('用户拒绝授权获取地理位置');\n      }\n    });\n  };\n  \n  // 8 界面操作接口\n  // 8.1 隐藏右上角菜单\n  document.querySelector('#hideOptionMenu').onclick = function () {\n    wx.hideOptionMenu();\n  };\n\n  // 8.2 显示右上角菜单\n  document.querySelector('#showOptionMenu').onclick = function () {\n    wx.showOptionMenu();\n  };\n\n  // 8.3 批量隐藏菜单项\n  document.querySelector('#hideMenuItems').onclick = function () {\n    wx.hideMenuItems({\n      menuList: [\n        'menuItem:readMode', // 阅读模式\n        'menuItem:share:timeline', // 分享到朋友圈\n        'menuItem:copyUrl' // 复制链接\n      ],\n      success: function (res) {\n        alert('已隐藏“阅读模式”，“分享到朋友圈”，“复制链接”等按钮');\n      },\n      fail: function (res) {\n        alert(JSON.stringify(res));\n      }\n    });\n  };\n\n  // 8.4 批量显示菜单项\n  document.querySelector('#showMenuItems').onclick = function () {\n    wx.showMenuItems({\n      menuList: [\n        'menuItem:readMode', // 阅读模式\n        'menuItem:share:timeline', // 分享到朋友圈\n        'menuItem:copyUrl' // 复制链接\n      ],\n      success: function (res) {\n        alert('已显示“阅读模式”，“分享到朋友圈”，“复制链接”等按钮');\n      },\n      fail: function (res) {\n        alert(JSON.stringify(res));\n      }\n    });\n  };\n\n  // 8.5 隐藏所有非基本菜单项\n  document.querySelector('#hideAllNonBaseMenuItem').onclick = function () {\n    wx.hideAllNonBaseMenuItem({\n      success: function () {\n        alert('已隐藏所有非基本菜单项');\n      }\n    });\n  };\n\n  // 8.6 显示所有被隐藏的非基本菜单项\n  document.querySelector('#showAllNonBaseMenuItem').onclick = function () {\n    wx.showAllNonBaseMenuItem({\n      success: function () {\n        alert('已显示所有非基本菜单项');\n      }\n    });\n  };\n\n  // 8.7 关闭当前窗口\n  document.querySelector('#closeWindow').onclick = function () {\n    wx.closeWindow();\n  };\n\n  // 9 微信原生接口\n  // 9.1.1 扫描二维码并返回结果\n  document.querySelector('#scanQRCode0').onclick = function () {\n    wx.scanQRCode({\n      desc: 'scanQRCode desc'\n    });\n  };\n  // 9.1.2 扫描二维码并返回结果\n  document.querySelector('#scanQRCode1').onclick = function () {\n    wx.scanQRCode({\n      needResult: 1,\n      desc: 'scanQRCode desc',\n      success: function (res) {\n        alert(JSON.stringify(res));\n      }\n    });\n  };\n\n  // 10 微信支付接口\n  // 10.1 发起一个支付请求\n  document.querySelector('#chooseWXPay').onclick = function () {\n    wx.chooseWXPay({\n      timestamp: 1414723227,\n      nonceStr: 'noncestr',\n      package: 'addition=action_id%3dgaby1234%26limit_pay%3d&bank_type=WX&body=innertest&fee_type=1&input_charset=GBK&notify_url=http%3A%2F%2F120.204.206.246%2Fcgi-bin%2Fmmsupport-bin%2Fnotifypay&out_trade_no=1414723227818375338&partner=1900000109&spbill_create_ip=127.0.0.1&total_fee=1&sign=432B647FE95C7BF73BCD177CEECBEF8D',\n      paySign: 'bd5b1933cda6e9548862944836a9b52e8c9a2b69'\n    });\n  };\n\n  // 11.3  跳转微信商品页\n  document.querySelector('#openProductSpecificView').onclick = function () {\n    wx.openProductSpecificView({\n      productId: 'pDF3iY0ptap-mIIPYnsM5n8VtCR0'\n    });\n  };\n\n  // 12 微信卡券接口\n  // 12.1 添加卡券\n  document.querySelector('#addCard').onclick = function () {\n    wx.addCard({\n      cardList: [\n        {\n          cardId: 'pDF3iY9tv9zCGCj4jTXFOo1DxHdo',\n          cardExt: '{\"code\": \"\", \"openid\": \"\", \"timestamp\": \"1418301401\", \"signature\":\"64e6a7cc85c6e84b726f2d1cbef1b36e9b0f9750\"}'\n        },\n        {\n          cardId: 'pDF3iY9tv9zCGCj4jTXFOo1DxHdo',\n          cardExt: '{\"code\": \"\", \"openid\": \"\", \"timestamp\": \"1418301401\", \"signature\":\"64e6a7cc85c6e84b726f2d1cbef1b36e9b0f9750\"}'\n        }\n      ],\n      success: function (res) {\n        alert('已添加卡券：' + JSON.stringify(res.cardList));\n      }\n    });\n  };\n\n  // 12.2 选择卡券\n  document.querySelector('#chooseCard').onclick = function () {\n    wx.chooseCard({\n      cardSign: '97e9c5e58aab3bdf6fd6150e599d7e5806e5cb91',\n      timestamp: 1417504553,\n      nonceStr: 'k0hGdSXKZEj3Min5',\n      success: function (res) {\n        alert('已选择卡券：' + JSON.stringify(res.cardList));\n      }\n    });\n  };\n\n  // 12.3 查看卡券\n  document.querySelector('#openCard').onclick = function () {\n    alert('您没有该公众号的卡券无法打开卡券。');\n    wx.openCard({\n      cardList: [\n      ]\n    });\n  };\n});\n\nwx.error(function (res) {\n  alert(res.errMsg);\n});\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/test/jsapi/jsapi_demo.php",
    "content": "<?php\r\ninclude \"wechat.class.php\";\r\ninclude 'errCode.php';\r\n\r\n$opt = array(\r\n        'appsecret'=>'xxxxxxxxxxxxxxxxxxxxxxxxxx',//填写高级调用功能的密钥\r\n        'appid'=>'wxxxxxxxxxxxxxx'\t//填写高级调用功能的appid\r\n);\r\n\r\n$we = new Wechat($opt);\r\n$auth = $we->checkAuth();\r\n$js_ticket = $we->getJsTicket();\r\nif (!$js_ticket) {\r\n\techo \"获取js_ticket失败！<br>\";\r\n    echo '错误码：'.$we->errCode;\r\n    echo ' 错误原因：'.ErrCode::getErrText($weObj->errCode);\r\n    exit;\r\n}\r\n$url = 'http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];\r\n$js_sign = $we->getJsSign($url);\r\n?>\r\n<!DOCTYPE html>\r\n<html>\r\n<head>\r\n  <meta charset=\"utf-8\">\r\n  <title>JS-SDK测试页</title>\r\n  <meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=0\">\r\n  <link rel=\"stylesheet\" href=\"style.css?ts=1420775603\">\r\n</head>\r\n<body ontouchstart=\"\">\r\n<div class=\"wxapi_container\">\r\n    <div class=\"wxapi_index_container\">\r\n      <ul class=\"label_box lbox_close wxapi_index_list\">\r\n        <li class=\"label_item wxapi_index_item\"><a class=\"label_inner\" href=\"#menu-basic\">基础接口</a></li>\r\n        <li class=\"label_item wxapi_index_item\"><a class=\"label_inner\" href=\"#menu-share\">分享接口</a></li>\r\n        <li class=\"label_item wxapi_index_item\"><a class=\"label_inner\" href=\"#menu-image\">图像接口</a></li>\r\n        <li class=\"label_item wxapi_index_item\"><a class=\"label_inner\" href=\"#menu-voice\">音频接口</a></li>\r\n        <li class=\"label_item wxapi_index_item\"><a class=\"label_inner\" href=\"#menu-smart\">智能接口</a></li>\r\n        <li class=\"label_item wxapi_index_item\"><a class=\"label_inner\" href=\"#menu-device\">设备信息接口</a></li>\r\n        <li class=\"label_item wxapi_index_item\"><a class=\"label_inner\" href=\"#menu-location\">地理位置接口</a></li>\r\n        <li class=\"label_item wxapi_index_item\"><a class=\"label_inner\" href=\"#menu-webview\">界面操作接口</a></li>\r\n        <li class=\"label_item wxapi_index_item\"><a class=\"label_inner\" href=\"#menu-scan\">微信扫一扫接口</a></li>\r\n        <li class=\"label_item wxapi_index_item\"><a class=\"label_inner\" href=\"#menu-shopping\">微信小店接口</a></li>\r\n        <li class=\"label_item wxapi_index_item\"><a class=\"label_inner\" href=\"#menu-card\">微信卡券接口</a></li>\r\n        <li class=\"label_item wxapi_index_item\"><a class=\"label_inner\" href=\"#menu-pay\">微信支付接口</a></li>\r\n      </ul>\r\n    </div>\r\n    <div class=\"lbox_close wxapi_form\">\r\n      <h3 id=\"menu-basic\">基础接口</h3>\r\n      <span class=\"desc\">判断当前客户端是否支持指定JS接口</span>\r\n      <button class=\"btn btn_primary\" id=\"checkJsApi\">checkJsApi</button>\r\n\r\n      <h3 id=\"menu-share\">分享接口</h3>\r\n      <span class=\"desc\">获取“分享到朋友圈”按钮点击状态及自定义分享内容接口</span>\r\n      <button class=\"btn btn_primary\" id=\"onMenuShareTimeline\">onMenuShareTimeline</button>\r\n      <span class=\"desc\">获取“分享给朋友”按钮点击状态及自定义分享内容接口</span>\r\n      <button class=\"btn btn_primary\" id=\"onMenuShareAppMessage\">onMenuShareAppMessage</button>\r\n      <span class=\"desc\">获取“分享到QQ”按钮点击状态及自定义分享内容接口</span>\r\n      <button class=\"btn btn_primary\" id=\"onMenuShareQQ\">onMenuShareQQ</button>\r\n      <span class=\"desc\">获取“分享到腾讯微博”按钮点击状态及自定义分享内容接口</span>\r\n      <button class=\"btn btn_primary\" id=\"onMenuShareWeibo\">onMenuShareWeibo</button>\r\n\r\n      <h3 id=\"menu-image\">图像接口</h3>\r\n      <span class=\"desc\">拍照或从手机相册中选图接口</span>\r\n      <button class=\"btn btn_primary\" id=\"chooseImage\">chooseImage</button>\r\n      <span class=\"desc\">预览图片接口</span>\r\n      <button class=\"btn btn_primary\" id=\"previewImage\">previewImage</button>\r\n      <span class=\"desc\">上传图片接口</span>\r\n      <button class=\"btn btn_primary\" id=\"uploadImage\">uploadImage</button>\r\n      <span class=\"desc\">下载图片接口</span>\r\n      <button class=\"btn btn_primary\" id=\"downloadImage\">downloadImage</button>\r\n\r\n      <h3 id=\"menu-voice\">音频接口</h3>\r\n      <span class=\"desc\">开始录音接口</span>\r\n      <button class=\"btn btn_primary\" id=\"startRecord\">startRecord</button>\r\n      <span class=\"desc\">停止录音接口</span>\r\n      <button class=\"btn btn_primary\" id=\"stopRecord\">stopRecord</button>\r\n      <span class=\"desc\">播放语音接口</span>\r\n      <button class=\"btn btn_primary\" id=\"playVoice\">playVoice</button>\r\n      <span class=\"desc\">暂停播放接口</span>\r\n      <button class=\"btn btn_primary\" id=\"pauseVoice\">pauseVoice</button>\r\n      <span class=\"desc\">停止播放接口</span>\r\n      <button class=\"btn btn_primary\" id=\"stopVoice\">stopVoice</button>\r\n      <span class=\"desc\">上传语音接口</span>\r\n      <button class=\"btn btn_primary\" id=\"uploadVoice\">uploadVoice</button>\r\n      <span class=\"desc\">下载语音接口</span>\r\n      <button class=\"btn btn_primary\" id=\"downloadVoice\">downloadVoice</button>\r\n\r\n      <h3 id=\"menu-smart\">智能接口</h3>\r\n      <span class=\"desc\">识别音频并返回识别结果接口</span>\r\n      <button class=\"btn btn_primary\" id=\"translateVoice\">translateVoice</button>\r\n\r\n      <h3 id=\"menu-device\">设备信息接口</h3>\r\n      <span class=\"desc\">获取网络状态接口</span>\r\n      <button class=\"btn btn_primary\" id=\"getNetworkType\">getNetworkType</button>\r\n\r\n      <h3 id=\"menu-location\">地理位置接口</h3>\r\n      <span class=\"desc\">使用微信内置地图查看位置接口</span>\r\n      <button class=\"btn btn_primary\" id=\"openLocation\">openLocation</button>\r\n      <span class=\"desc\">获取地理位置接口</span>\r\n      <button class=\"btn btn_primary\" id=\"getLocation\">getLocation</button>\r\n\r\n      <h3 id=\"menu-webview\">界面操作接口</h3>\r\n      <span class=\"desc\">隐藏右上角菜单接口</span>\r\n      <button class=\"btn btn_primary\" id=\"hideOptionMenu\">hideOptionMenu</button>\r\n      <span class=\"desc\">显示右上角菜单接口</span>\r\n      <button class=\"btn btn_primary\" id=\"showOptionMenu\">showOptionMenu</button>\r\n      <span class=\"desc\">关闭当前网页窗口接口</span>\r\n      <button class=\"btn btn_primary\" id=\"closeWindow\">closeWindow</button>\r\n      <span class=\"desc\">批量隐藏功能按钮接口</span>\r\n      <button class=\"btn btn_primary\" id=\"hideMenuItems\">hideMenuItems</button>\r\n      <span class=\"desc\">批量显示功能按钮接口</span>\r\n      <button class=\"btn btn_primary\" id=\"showMenuItems\">showMenuItems</button>\r\n      <span class=\"desc\">隐藏所有非基础按钮接口</span>\r\n      <button class=\"btn btn_primary\" id=\"hideAllNonBaseMenuItem\">hideAllNonBaseMenuItem</button>\r\n      <span class=\"desc\">显示所有功能按钮接口</span>\r\n      <button class=\"btn btn_primary\" id=\"showAllNonBaseMenuItem\">showAllNonBaseMenuItem</button>\r\n\r\n      <h3 id=\"menu-scan\">微信扫一扫</h3>\r\n      <span class=\"desc\">调起微信扫一扫接口</span>\r\n      <button class=\"btn btn_primary\" id=\"scanQRCode0\">scanQRCode(微信处理结果)</button>\r\n      <button class=\"btn btn_primary\" id=\"scanQRCode1\">scanQRCode(直接返回结果)</button>\r\n\r\n      <h3 id=\"menu-shopping\">微信小店接口</h3>\r\n      <span class=\"desc\">跳转微信商品页接口</span>\r\n      <button class=\"btn btn_primary\" id=\"openProductSpecificView\">openProductSpecificView</button>\r\n\r\n      <h3 id=\"menu-card\">微信卡券接口</h3>\r\n      <span class=\"desc\">批量添加卡券接口</span>\r\n      <button class=\"btn btn_primary\" id=\"addCard\">addCard</button>\r\n      <span class=\"desc\">调起适用于门店的卡券列表并获取用户选择列表</span>\r\n      <button class=\"btn btn_primary\" id=\"chooseCard\">chooseCard</button>\r\n      <span class=\"desc\">查看微信卡包中的卡券接口</span>\r\n      <button class=\"btn btn_primary\" id=\"openCard\">openCard</button>\r\n\r\n      <h3 id=\"menu-pay\">微信支付接口</h3>\r\n      <span class=\"desc\">发起一个微信支付请求</span>\r\n      <button class=\"btn btn_primary\" id=\"chooseWXPay\">chooseWXPay</button>\r\n    </div>\r\n  </div>\r\n</body>\r\n<script src=\"http://res.wx.qq.com/open/js/jweixin-1.0.0.js\"> </script>\r\n<script>\r\n  wx.config({\r\n      debug: false,\r\n      appId: '<?php echo $js_sign['appid']; ?>', // 必填，公众号的唯一标识\r\n      timestamp: <?php echo $js_sign['timestamp']; ?>, // 必填，生成签名的时间戳，切记时间戳是整数型，别加引号\r\n      nonceStr: '<?php echo $js_sign['noncestr']; ?>', // 必填，生成签名的随机串\r\n      signature: '<?php echo $js_sign['signature']; ?>', // 必填，签名，见附录1\r\n      jsApiList: [\r\n        'checkJsApi',\r\n        'onMenuShareTimeline',\r\n        'onMenuShareAppMessage',\r\n        'onMenuShareQQ',\r\n        'onMenuShareWeibo',\r\n        'hideMenuItems',\r\n        'showMenuItems',\r\n        'hideAllNonBaseMenuItem',\r\n        'showAllNonBaseMenuItem',\r\n        'translateVoice',\r\n        'startRecord',\r\n        'stopRecord',\r\n        'onRecordEnd',\r\n        'playVoice',\r\n        'pauseVoice',\r\n        'stopVoice',\r\n        'uploadVoice',\r\n        'downloadVoice',\r\n        'chooseImage',\r\n        'previewImage',\r\n        'uploadImage',\r\n        'downloadImage',\r\n        'getNetworkType',\r\n        'openLocation',\r\n        'getLocation',\r\n        'hideOptionMenu',\r\n        'showOptionMenu',\r\n        'closeWindow',\r\n        'scanQRCode',\r\n        'chooseWXPay',\r\n        'openProductSpecificView',\r\n        'addCard',\r\n        'chooseCard',\r\n        'openCard'\r\n      ]\r\n  });\r\n</script>\r\n<script src=\"jsapi-demo-6.1.js?ts=<?php echo $timestamp; ?>\"> </script>\r\n</html>"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/test/jsapi/style.css",
    "content": "html {\r\n  -ms-text-size-adjust: 100%;\r\n  -webkit-text-size-adjust: 100%;\r\n  -webkit-user-select: none;\r\n  user-select: none;\r\n}\r\nbody {\r\n  line-height: 1.6;\r\n  font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\r\n  background-color: #f1f0f6;\r\n}\r\n* {\r\n  margin: 0;\r\n  padding: 0;\r\n}\r\nbutton {\r\n  font-family: inherit;\r\n  font-size: 100%;\r\n  margin: 0;\r\n  *font-family: \"Helvetica Neue\", Helvetica, Arial, sans-serif;\r\n}\r\nul,\r\nol {\r\n  padding-left: 0;\r\n  list-style-type: none;\r\n}\r\na {\r\n  text-decoration: none;\r\n}\r\n.label_box {\r\n  background-color: #ffffff;\r\n}\r\n.label_item {\r\n  padding-left: 15px;\r\n}\r\n.label_inner {\r\n  padding-top: 10px;\r\n  padding-bottom: 10px;\r\n  min-height: 24px;\r\n  position: relative;\r\n}\r\n.label_inner:before {\r\n  content: \" \";\r\n  position: absolute;\r\n  left: 0;\r\n  top: 0;\r\n  width: 200%;\r\n  height: 1px;\r\n  border-top: 1px solid #ededed;\r\n  -webkit-transform-origin: 0 0;\r\n  transform-origin: 0 0;\r\n  -webkit-transform: scale(0.5);\r\n  transform: scale(0.5);\r\n  top: auto;\r\n  bottom: -2px;\r\n}\r\n.lbox_close {\r\n  position: relative;\r\n}\r\n.lbox_close:before {\r\n  content: \" \";\r\n  position: absolute;\r\n  left: 0;\r\n  top: 0;\r\n  width: 200%;\r\n  height: 1px;\r\n  border-top: 1px solid #ededed;\r\n  -webkit-transform-origin: 0 0;\r\n  transform-origin: 0 0;\r\n  -webkit-transform: scale(0.5);\r\n  transform: scale(0.5);\r\n}\r\n.lbox_close:after {\r\n  content: \" \";\r\n  position: absolute;\r\n  left: 0;\r\n  top: 0;\r\n  width: 200%;\r\n  height: 1px;\r\n  border-top: 1px solid #ededed;\r\n  -webkit-transform-origin: 0 0;\r\n  transform-origin: 0 0;\r\n  -webkit-transform: scale(0.5);\r\n  transform: scale(0.5);\r\n  top: auto;\r\n  bottom: -2px;\r\n}\r\n.lbox_close .label_item:last-child .label_inner:before {\r\n  display: none;\r\n}\r\n.btn {\r\n  display: block;\r\n  margin-left: auto;\r\n  margin-right: auto;\r\n  padding-left: 14px;\r\n  padding-right: 14px;\r\n  font-size: 18px;\r\n  text-align: center;\r\n  text-decoration: none;\r\n  overflow: visible;\r\n  /*.btn_h(@btnHeight);*/\r\n  height: 42px;\r\n  border-radius: 5px;\r\n  -moz-border-radius: 5px;\r\n  -webkit-border-radius: 5px;\r\n  box-sizing: border-box;\r\n  -moz-box-sizing: border-box;\r\n  -webkit-box-sizing: border-box;\r\n  color: #ffffff;\r\n  line-height: 42px;\r\n  -webkit-tap-highlight-color: rgba(255, 255, 255, 0);\r\n}\r\n.btn.btn_inline {\r\n  display: inline-block;\r\n}\r\n.btn_primary {\r\n  background-color: #04be02;\r\n}\r\n.btn_primary:not(.btn_disabled):visited {\r\n  color: #ffffff;\r\n}\r\n.btn_primary:not(.btn_disabled):active {\r\n  color: rgba(255, 255, 255, 0.9);\r\n  background-color: #039702;\r\n}\r\nbutton.btn {\r\n  width: 100%;\r\n  border: 0;\r\n  outline: 0;\r\n  -webkit-appearance: none;\r\n}\r\nbutton.btn:focus {\r\n  outline: 0;\r\n}\r\n.wxapi_container {\r\n  font-size: 16px;\r\n}\r\nh1 {\r\n  font-size: 14px;\r\n  font-weight: 400;\r\n  line-height: 2em;\r\n  padding-left: 15px;\r\n  color: #8d8c92;\r\n}\r\n.desc {\r\n  font-size: 14px;\r\n  font-weight: 400;\r\n  line-height: 2em;\r\n  color: #8d8c92;\r\n}\r\n.wxapi_index_item a {\r\n  display: block;\r\n  color: #3e3e3e;\r\n  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);\r\n}\r\n.wxapi_form {\r\n  background-color: #ffffff;\r\n  padding: 0 15px;\r\n  margin-top: 30px;\r\n  padding-bottom: 15px;\r\n}\r\nh3 {\r\n  padding-top: 16px;\r\n  margin-top: 25px;\r\n  font-size: 16px;\r\n  font-weight: 400;\r\n  color: #3e3e3e;\r\n  position: relative;\r\n}\r\nh3:first-child {\r\n  padding-top: 15px;\r\n}\r\nh3:before {\r\n  content: \" \";\r\n  position: absolute;\r\n  left: 0;\r\n  top: 0;\r\n  width: 200%;\r\n  height: 1px;\r\n  border-top: 1px solid #ededed;\r\n  -webkit-transform-origin: 0 0;\r\n  transform-origin: 0 0;\r\n  -webkit-transform: scale(0.5);\r\n  transform: scale(0.5);\r\n}\r\n.btn {\r\n  margin-bottom: 15px;\r\n}\r\n\r\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/test/qydemo.php",
    "content": "<?php\ninclude \"../qywechat.class.php\";\n\nfunction logg($text){\n    file_put_contents('./log.txt',$text.\"\\r\\n\\r\\n\",FILE_APPEND);\n};\n\n$options = array(\n        'token'=>'9xxxxxxxxxxxx',\t//填写应用接口的Token\n        'encodingaeskey'=>'d4oxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',//填写加密用的EncodingAESKey\n        'appid'=>'wxa0xxxxxxxxxx',\t//填写高级调用功能的appid\n        'debug'=>true,\n        'logcallback'=>'logg'\n\n);\nlogg(\"GET参数为：\\n\".var_export($_GET,true));\n$weObj = new Wechat($options);\n$ret=$weObj->valid();\nif (!$ret) {\n\tlogg(\"验证失败！\");\n\tvar_dump($ret);\n\texit;\n}\n$f = $weObj->getRev()->getRevFrom();\n$t = $weObj->getRevType();\n$d = $weObj->getRevData();\n$weObj->text(\"你好！来自星星的：\".$f.\"\\n你发送的\".$t.\"类型信息：\\n原始信息如下：\\n\".var_export($d,true))->reply();\nlogg(\"-----------------------------------------\");\n?>"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/test/test1.php",
    "content": "<?php\n/**\n * 微信公共接口测试\n * \n */\n\tinclude(\"../wechat.class.php\");\n\t\n\tfunction logdebug($text){\n\t\tfile_put_contents('../data/log.txt',$text.\"\\n\",FILE_APPEND);\t\t\n\t};\n\t$options = array(\n\t\t'token'=>'tokenaccesskey', //填写你设定的key\n\t\t\t'debug'=>true,\n\t\t\t'logcallback'=>'logdebug'\n\t);\n\t$weObj = new Wechat($options);\n\t$weObj->valid();\n\t$type = $weObj->getRev()->getRevType();\n\tswitch($type) {\n\t\tcase Wechat::MSGTYPE_TEXT:\n\t\t\t\t$weObj->text(\"hello, I'm wechat\")->reply();\n\t\t\t\texit;\n\t\t\t\tbreak;\n\t\tcase Wechat::MSGTYPE_EVENT:\n\t\t\t\tbreak;\n\t\tcase Wechat::MSGTYPE_IMAGE:\n\t\t\t\tbreak;\n\t\tdefault:\n\t\t\t\t$weObj->text(\"help info\")->reply();\n\t}\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/wechat.class.php",
    "content": "<?php\n/**\n *\t微信公众平台PHP-SDK, 官方API部分\n *  @author  dodge <dodgepudding@gmail.com>\n *  @link https://github.com/dodgepudding/wechat-php-sdk\n *  @version 1.2\n *  usage:\n *   $options = array(\n *\t\t\t'token'=>'tokenaccesskey', //填写你设定的key\n *\t\t\t'encodingaeskey'=>'encodingaeskey', //填写加密用的EncodingAESKey\n *\t\t\t'appid'=>'wxdk1234567890', //填写高级调用功能的app id\n *\t\t\t'appsecret'=>'xxxxxxxxxxxxxxxxxxx' //填写高级调用功能的密钥\n *\t\t);\n *\t $weObj = new Wechat($options);\n *   $weObj->valid();\n *   $type = $weObj->getRev()->getRevType();\n *   switch($type) {\n *   \t\tcase Wechat::MSGTYPE_TEXT:\n *   \t\t\t$weObj->text(\"hello, I'm wechat\")->reply();\n *   \t\t\texit;\n *   \t\t\tbreak;\n *   \t\tcase Wechat::MSGTYPE_EVENT:\n *   \t\t\t....\n *   \t\t\tbreak;\n *   \t\tcase Wechat::MSGTYPE_IMAGE:\n *   \t\t\t...\n *   \t\t\tbreak;\n *   \t\tdefault:\n *   \t\t\t$weObj->text(\"help info\")->reply();\n *   }\n *\n *   //获取菜单操作:\n *   $menu = $weObj->getMenu();\n *   //设置菜单\n *   $newmenu =  array(\n *   \t\t\"button\"=>\n *   \t\t\tarray(\n *   \t\t\t\tarray('type'=>'click','name'=>'最新消息','key'=>'MENU_KEY_NEWS'),\n *   \t\t\t\tarray('type'=>'view','name'=>'我要搜索','url'=>'http://www.baidu.com'),\n *   \t\t\t\t)\n *  \t\t);\n *   $result = $weObj->createMenu($newmenu);\n */\nclass Wechat\n{\n\tconst MSGTYPE_TEXT = 'text';\n\tconst MSGTYPE_IMAGE = 'image';\n\tconst MSGTYPE_LOCATION = 'location';\n\tconst MSGTYPE_LINK = 'link';\n\tconst MSGTYPE_EVENT = 'event';\n\tconst MSGTYPE_MUSIC = 'music';\n\tconst MSGTYPE_NEWS = 'news';\n\tconst MSGTYPE_VOICE = 'voice';\n\tconst MSGTYPE_VIDEO = 'video';\n\tconst EVENT_SUBSCRIBE = 'subscribe';       //订阅\n\tconst EVENT_UNSUBSCRIBE = 'unsubscribe';   //取消订阅\n\tconst EVENT_SCAN = 'SCAN';                 //扫描带参数二维码\n\tconst EVENT_LOCATION = 'LOCATION';         //上报地理位置\n\tconst EVENT_MENU_VIEW = 'VIEW';                     //菜单 - 点击菜单跳转链接\n\tconst EVENT_MENU_CLICK = 'CLICK';                   //菜单 - 点击菜单拉取消息\n\tconst EVENT_MENU_SCAN_PUSH = 'scancode_push';       //菜单 - 扫码推事件(客户端跳URL)\n\tconst EVENT_MENU_SCAN_WAITMSG = 'scancode_waitmsg'; //菜单 - 扫码推事件(客户端不跳URL)\n\tconst EVENT_MENU_PIC_SYS = 'pic_sysphoto';          //菜单 - 弹出系统拍照发图\n\tconst EVENT_MENU_PIC_PHOTO = 'pic_photo_or_album';  //菜单 - 弹出拍照或者相册发图\n\tconst EVENT_MENU_PIC_WEIXIN = 'pic_weixin';         //菜单 - 弹出微信相册发图器\n\tconst EVENT_MENU_LOCATION = 'location_select';      //菜单 - 弹出地理位置选择器\n\tconst EVENT_SEND_MASS = 'MASSSENDJOBFINISH';        //发送结果 - 高级群发完成\n\tconst EVENT_SEND_TEMPLATE = 'TEMPLATESENDJOBFINISH';//发送结果 - 模板消息发送结果\n\tconst EVENT_KF_SEESION_CREATE = 'kfcreatesession';  //多客服 - 接入会话\n\tconst EVENT_KF_SEESION_CLOSE = 'kfclosesession';    //多客服 - 关闭会话\n\tconst EVENT_KF_SEESION_SWITCH = 'kfswitchsession';  //多客服 - 转接会话\n\tconst EVENT_CARD_PASS = 'card_pass_check';          //卡券 - 审核通过\n\tconst EVENT_CARD_NOTPASS = 'card_not_pass_check';   //卡券 - 审核未通过\n\tconst EVENT_CARD_USER_GET = 'user_get_card';        //卡券 - 用户领取卡券\n\tconst EVENT_CARD_USER_DEL = 'user_del_card';        //卡券 - 用户删除卡券\n\tconst API_URL_PREFIX = 'https://api.weixin.qq.com/cgi-bin';\n\tconst AUTH_URL = '/token?grant_type=client_credential&';\n\tconst MENU_CREATE_URL = '/menu/create?';\n\tconst MENU_GET_URL = '/menu/get?';\n\tconst MENU_DELETE_URL = '/menu/delete?';\n\tconst GET_TICKET_URL = '/ticket/getticket?';\n\tconst CALLBACKSERVER_GET_URL = '/getcallbackip?';\n\tconst QRCODE_CREATE_URL='/qrcode/create?';\n\tconst QR_SCENE = 0;\n\tconst QR_LIMIT_SCENE = 1;\n\tconst QRCODE_IMG_URL='https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=';\n\tconst SHORT_URL='/shorturl?';\n\tconst USER_GET_URL='/user/get?';\n\tconst USER_INFO_URL='/user/info?';\n\tconst USER_UPDATEREMARK_URL='/user/info/updateremark?';\n\tconst GROUP_GET_URL='/groups/get?';\n\tconst USER_GROUP_URL='/groups/getid?';\n\tconst GROUP_CREATE_URL='/groups/create?';\n\tconst GROUP_UPDATE_URL='/groups/update?';\n\tconst GROUP_MEMBER_UPDATE_URL='/groups/members/update?';\n\tconst GROUP_MEMBER_BATCHUPDATE_URL='/groups/members/batchupdate?';\n\tconst CUSTOM_SEND_URL='/message/custom/send?';\n\tconst MEDIA_UPLOADNEWS_URL = '/media/uploadnews?';\n\tconst MASS_SEND_URL = '/message/mass/send?';\n\tconst TEMPLATE_SET_INDUSTRY_URL = '/template/api_set_industry?';\n\tconst TEMPLATE_ADD_TPL_URL = '/template/api_add_template?';\n\tconst TEMPLATE_SEND_URL = '/message/template/send?';\n\tconst MASS_SEND_GROUP_URL = '/message/mass/sendall?';\n\tconst MASS_DELETE_URL = '/message/mass/delete?';\n\tconst MASS_PREVIEW_URL = '/message/mass/preview?';\n\tconst MASS_QUERY_URL = '/message/mass/get?';\n\tconst UPLOAD_MEDIA_URL = 'http://file.api.weixin.qq.com/cgi-bin';\n\tconst MEDIA_UPLOAD_URL = '/media/upload?';\n\tconst MEDIA_GET_URL = '/media/get?';\n\tconst MEDIA_VIDEO_UPLOAD = '/media/uploadvideo?';\n\tconst OAUTH_PREFIX = 'https://open.weixin.qq.com/connect/oauth2';\n\tconst OAUTH_AUTHORIZE_URL = '/authorize?';\n\t///多客服相关地址\n\tconst CUSTOM_SERVICE_GET_RECORD = '/customservice/getrecord?';\n\tconst CUSTOM_SERVICE_GET_KFLIST = '/customservice/getkflist?';\n\tconst CUSTOM_SERVICE_GET_ONLINEKFLIST = '/customservice/getonlinekflist?';\n\tconst API_BASE_URL_PREFIX = 'https://api.weixin.qq.com'; //以下API接口URL需要使用此前缀\n\tconst OAUTH_TOKEN_URL = '/sns/oauth2/access_token?';\n\tconst OAUTH_REFRESH_URL = '/sns/oauth2/refresh_token?';\n\tconst OAUTH_USERINFO_URL = '/sns/userinfo?';\n\tconst OAUTH_AUTH_URL = '/sns/auth?';\n\t///多客服相关地址\n\tconst CUSTOM_SESSION_CREATE = '/customservice/kfsession/create?';\n\tconst CUSTOM_SESSION_CLOSE = '/customservice/kfsession/close?';\n\tconst CUSTOM_SESSION_SWITCH = '/customservice/kfsession/switch?';\n\tconst CUSTOM_SESSION_GET = '/customservice/kfsession/getsession?';\n\tconst CUSTOM_SESSION_GET_LIST = '/customservice/kfsession/getsessionlist?';\n\tconst CUSTOM_SESSION_GET_WAIT = '/customservice/kfsession/getwaitcase?';\n\tconst CS_KF_ACCOUNT_ADD_URL = '/customservice/kfaccount/add?';\n\tconst CS_KF_ACCOUNT_UPDATE_URL = '/customservice/kfaccount/update?';\n\tconst CS_KF_ACCOUNT_DEL_URL = '/customservice/kfaccount/del?';\n\tconst CS_KF_ACCOUNT_UPLOAD_HEADIMG_URL = '/customservice/kfaccount/uploadheadimg?';\n\t///卡券相关地址\n\tconst CARD_CREATE                     = '/card/create?';\n\tconst CARD_DELETE                     = '/card/delete?';\n\tconst CARD_UPDATE                     = '/card/update?';\n\tconst CARD_GET                        = '/card/get?';\n\tconst CARD_BATCHGET                   = '/card/batchget?';\n\tconst CARD_MODIFY_STOCK               = '/card/modifystock?';\n\tconst CARD_LOCATION_BATCHADD          = '/card/location/batchadd?';\n\tconst CARD_LOCATION_BATCHGET          = '/card/location/batchget?';\n\tconst CARD_GETCOLORS                  = '/card/getcolors?';\n\tconst CARD_QRCODE_CREATE              = '/card/qrcode/create?';\n\tconst CARD_CODE_CONSUME               = '/card/code/consume?';\n\tconst CARD_CODE_DECRYPT               = '/card/code/decrypt?';\n\tconst CARD_CODE_GET                   = '/card/code/get?';\n\tconst CARD_CODE_UPDATE                = '/card/code/update?';\n\tconst CARD_CODE_UNAVAILABLE           = '/card/code/unavailable?';\n\tconst CARD_TESTWHILELIST_SET          = '/card/testwhitelist/set?';\n\tconst CARD_MEMBERCARD_ACTIVATE        = '/card/membercard/activate?';      //激活会员卡\n\tconst CARD_MEMBERCARD_UPDATEUSER      = '/card/membercard/updateuser?';    //更新会员卡\n\tconst CARD_MOVIETICKET_UPDATEUSER     = '/card/movieticket/updateuser?';   //更新电影票(未加方法)\n\tconst CARD_BOARDINGPASS_CHECKIN       = '/card/boardingpass/checkin?';     //飞机票-在线选座(未加方法)\n\tconst CARD_LUCKYMONEY_UPDATE          = '/card/luckymoney/updateuserbalance?';     //更新红包金额\n\tconst SEMANTIC_API_URL = '/semantic/semproxy/search?'; //语义理解\n\t///数据分析接口\n\tstatic $DATACUBE_URL_ARR = array(        //用户分析\n\t        'user' => array(\n\t                'summary' => '/datacube/getusersummary?',\t\t//获取用户增减数据（getusersummary）\n\t                'cumulate' => '/datacube/getusercumulate?',\t\t//获取累计用户数据（getusercumulate）\n\t        ),\n\t        'article' => array(            //图文分析\n\t                'summary' => '/datacube/getarticlesummary?',\t\t//获取图文群发每日数据（getarticlesummary）\n\t                'total' => '/datacube/getarticletotal?',\t\t//获取图文群发总数据（getarticletotal）\n\t                'read' => '/datacube/getuserread?',\t\t\t//获取图文统计数据（getuserread）\n\t                'readhour' => '/datacube/getuserreadhour?',\t\t//获取图文统计分时数据（getuserreadhour）\n\t                'share' => '/datacube/getusershare?',\t\t\t//获取图文分享转发数据（getusershare）\n\t                'sharehour' => '/datacube/getusersharehour?',\t\t//获取图文分享转发分时数据（getusersharehour）\n\t        ),\n\t        'upstreammsg' => array(        //消息分析\n\t                'summary' => '/datacube/getupstreammsg?',\t\t//获取消息发送概况数据（getupstreammsg）\n\t\t\t\t\t'hour' => '/datacube/getupstreammsghour?',\t//获取消息分送分时数据（getupstreammsghour）\n\t                'week' => '/datacube/getupstreammsgweek?',\t//获取消息发送周数据（getupstreammsgweek）\n\t                'month' => '/datacube/getupstreammsgmonth?',\t//获取消息发送月数据（getupstreammsgmonth）\n\t                'dist' => '/datacube/getupstreammsgdist?',\t//获取消息发送分布数据（getupstreammsgdist）\n\t                'distweek' => '/datacube/getupstreammsgdistweek?',\t//获取消息发送分布周数据（getupstreammsgdistweek）\n\t               \t'distmonth' => '/datacube/getupstreammsgdistmonth?',\t//获取消息发送分布月数据（getupstreammsgdistmonth）\n\t        ),\n\t        'interface' => array(        //接口分析\n\t                'summary' => '/datacube/getinterfacesummary?',\t//获取接口分析数据（getinterfacesummary）\n\t                'summaryhour' => '/datacube/getinterfacesummaryhour?',\t//获取接口分析分时数据（getinterfacesummaryhour）\n\t        )\n\t);\n\n\n\tprivate $token;\n\tprivate $encodingAesKey;\n\tprivate $encrypt_type;\n\tprivate $appid;\n\tprivate $appsecret;\n\tprivate $access_token;\n\tprivate $jsapi_ticket;\n\tprivate $user_token;\n\tprivate $partnerid;\n\tprivate $partnerkey;\n\tprivate $paysignkey;\n\tprivate $postxml;\n\tprivate $_msg;\n\tprivate $_funcflag = false;\n\tprivate $_receive;\n\tprivate $_text_filter = true;\n\tpublic $debug =  false;\n\tpublic $errCode = 40001;\n\tpublic $errMsg = \"no access\";\n\tpublic $logcallback;\n\n\tpublic function __construct($options)\n\t{\n\t\t$this->token = isset($options['token'])?$options['token']:'';\n\t\t$this->encodingAesKey = isset($options['encodingaeskey'])?$options['encodingaeskey']:'';\n\t\t$this->appid = isset($options['appid'])?$options['appid']:'';\n\t\t$this->appsecret = isset($options['appsecret'])?$options['appsecret']:'';\n\t\t$this->debug = isset($options['debug'])?$options['debug']:false;\n\t\t$this->logcallback = isset($options['logcallback'])?$options['logcallback']:false;\n\t}\n\n\t/**\n\t * For weixin server validation\n\t */\n\tprivate function checkSignature($str='')\n\t{\n        $signature = isset($_GET[\"signature\"])?$_GET[\"signature\"]:'';\n\t    $signature = isset($_GET[\"msg_signature\"])?$_GET[\"msg_signature\"]:$signature; //如果存在加密验证则用加密验证段\n        $timestamp = isset($_GET[\"timestamp\"])?$_GET[\"timestamp\"]:'';\n        $nonce = isset($_GET[\"nonce\"])?$_GET[\"nonce\"]:'';\n\n\t\t$token = $this->token;\n\t\t$tmpArr = array($token, $timestamp, $nonce,$str);\n\t\tsort($tmpArr, SORT_STRING);\n\t\t$tmpStr = implode( $tmpArr );\n\t\t$tmpStr = sha1( $tmpStr );\n\n\t\tif( $tmpStr == $signature ){\n\t\t\treturn true;\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * For weixin server validation\n\t * @param bool $return 是否返回\n\t */\n\tpublic function valid($return=false)\n    {\n        $encryptStr=\"\";\n        if ($_SERVER['REQUEST_METHOD'] == \"POST\") {\n            $postStr = file_get_contents(\"php://input\");\n            $array = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);\n            $this->encrypt_type = isset($_GET[\"encrypt_type\"]) ? $_GET[\"encrypt_type\"]: '';\n            if ($this->encrypt_type == 'aes') { //aes加密\n                $this->log($postStr);\n            \t$encryptStr = $array['Encrypt'];\n            \t$pc = new Prpcrypt($this->encodingAesKey);\n            \t$array = $pc->decrypt($encryptStr,$this->appid);\n            \tif (!isset($array[0]) || ($array[0] != 0)) {\n            \t    if (!$return) {\n            \t        die('decrypt error!');\n            \t    } else {\n            \t        return false;\n            \t    }\n            \t}\n            \t$this->postxml = $array[1];\n            \tif (!$this->appid)\n            \t    $this->appid = $array[2];//为了没有appid的订阅号。\n            } else {\n                $this->postxml = $postStr;\n            }\n        } elseif (isset($_GET[\"echostr\"])) {\n        \t$echoStr = $_GET[\"echostr\"];\n        \tif ($return) {\n        \t\tif ($this->checkSignature())\n        \t\t\treturn $echoStr;\n        \t\telse\n        \t\t\treturn false;\n        \t} else {\n        \t\tif ($this->checkSignature())\n        \t\t\tdie($echoStr);\n        \t\telse\n        \t\t\tdie('no access');\n        \t}\n        }\n\n        if (!$this->checkSignature($encryptStr)) {\n        \tif ($return)\n        \t\treturn false;\n        \telse\n        \t\tdie('no access');\n        }\n        return true;\n    }\n\n\t/**\n\t * 设置发送消息\n\t * @param array $msg 消息数组\n\t * @param bool $append 是否在原消息数组追加\n\t */\n    public function Message($msg = '',$append = false){\n    \t\tif (is_null($msg)) {\n    \t\t\t$this->_msg =array();\n    \t\t}elseif (is_array($msg)) {\n    \t\t\tif ($append)\n    \t\t\t\t$this->_msg = array_merge($this->_msg,$msg);\n    \t\t\telse\n    \t\t\t\t$this->_msg = $msg;\n    \t\t\treturn $this->_msg;\n    \t\t} else {\n    \t\t\treturn $this->_msg;\n    \t\t}\n    }\n\n    /**\n     * 设置消息的星标标志，官方已取消对此功能的支持\n     */\n    public function setFuncFlag($flag) {\n    \t\t$this->_funcflag = $flag;\n    \t\treturn $this;\n    }\n\n    /**\n     * 日志记录，可被重载。\n     * @param mixed $log 输入日志\n     * @return mixed\n     */\n    protected function log($log){\n    \t\tif ($this->debug && function_exists($this->logcallback)) {\n    \t\t\tif (is_array($log)) $log = print_r($log,true);\n    \t\t\treturn call_user_func($this->logcallback,$log);\n    \t\t}\n    }\n\n    /**\n     * 获取微信服务器发来的信息\n     */\n\tpublic function getRev()\n\t{\n\t\tif ($this->_receive) return $this;\n\t\t$postStr = !empty($this->postxml)?$this->postxml:file_get_contents(\"php://input\");\n\t\t//兼顾使用明文又不想调用valid()方法的情况\n\t\t$this->log($postStr);\n\t\tif (!empty($postStr)) {\n\t\t\t$this->_receive = (array)simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * 获取微信服务器发来的信息\n\t */\n\tpublic function getRevData()\n\t{\n\t\treturn $this->_receive;\n\t}\n\n\t/**\n\t * 获取消息发送者\n\t */\n\tpublic function getRevFrom() {\n\t\tif (isset($this->_receive['FromUserName']))\n\t\t\treturn $this->_receive['FromUserName'];\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取消息接受者\n\t */\n\tpublic function getRevTo() {\n\t\tif (isset($this->_receive['ToUserName']))\n\t\t\treturn $this->_receive['ToUserName'];\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收消息的类型\n\t */\n\tpublic function getRevType() {\n\t\tif (isset($this->_receive['MsgType']))\n\t\t\treturn $this->_receive['MsgType'];\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取消息ID\n\t */\n\tpublic function getRevID() {\n\t\tif (isset($this->_receive['MsgId']))\n\t\t\treturn $this->_receive['MsgId'];\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取消息发送时间\n\t */\n\tpublic function getRevCtime() {\n\t\tif (isset($this->_receive['CreateTime']))\n\t\t\treturn $this->_receive['CreateTime'];\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收消息内容正文\n\t */\n\tpublic function getRevContent(){\n\t\tif (isset($this->_receive['Content']))\n\t\t\treturn $this->_receive['Content'];\n\t\telse if (isset($this->_receive['Recognition'])) //获取语音识别文字内容，需申请开通\n\t\t\treturn $this->_receive['Recognition'];\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收消息图片\n\t */\n\tpublic function getRevPic(){\n\t\tif (isset($this->_receive['PicUrl']))\n\t\t\treturn array(\n\t\t\t\t'mediaid'=>$this->_receive['MediaId'],\n\t\t\t\t'picurl'=>(string)$this->_receive['PicUrl'],    //防止picurl为空导致解析出错\n\t\t\t);\n\t\telse\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收消息链接\n\t */\n\tpublic function getRevLink(){\n\t\tif (isset($this->_receive['Url'])){\n\t\t\treturn array(\n\t\t\t\t'url'=>$this->_receive['Url'],\n\t\t\t\t'title'=>$this->_receive['Title'],\n\t\t\t\t'description'=>$this->_receive['Description']\n\t\t\t);\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收地理位置\n\t */\n\tpublic function getRevGeo(){\n\t\tif (isset($this->_receive['Location_X'])){\n\t\t\treturn array(\n\t\t\t\t'x'=>$this->_receive['Location_X'],\n\t\t\t\t'y'=>$this->_receive['Location_Y'],\n\t\t\t\t'scale'=>$this->_receive['Scale'],\n\t\t\t\t'label'=>$this->_receive['Label']\n\t\t\t);\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取上报地理位置事件\n\t */\n\tpublic function getRevEventGeo(){\n        \tif (isset($this->_receive['Latitude'])){\n        \t\t return array(\n\t\t\t\t'x'=>$this->_receive['Latitude'],\n\t\t\t\t'y'=>$this->_receive['Longitude'],\n\t\t\t\t'precision'=>$this->_receive['Precision'],\n\t\t\t);\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收事件推送\n\t */\n\tpublic function getRevEvent(){\n\t\tif (isset($this->_receive['Event'])){\n\t\t\t$array['event'] = $this->_receive['Event'];\n\t\t}\n\t\tif (isset($this->_receive['EventKey'])){\n\t\t\t$array['key'] = $this->_receive['EventKey'];\n\t\t}\n\t\tif (isset($array) && count($array) > 0) {\n\t\t\treturn $array;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * 获取自定义菜单的扫码推事件信息\n\t *\n\t * 事件类型为以下两种时则调用此方法有效\n\t * Event\t 事件类型，scancode_push\n\t * Event\t 事件类型，scancode_waitmsg\n\t *\n\t * @return: array | false\n\t * array (\n\t *     'ScanType'=>'qrcode',\n\t *     'ScanResult'=>'123123'\n\t * )\n\t */\n\tpublic function getRevScanInfo(){\n\t\tif (isset($this->_receive['ScanCodeInfo'])){\n\t\t    if (!is_array($this->_receive['ScanCodeInfo'])) {\n\t\t        $array=(array)$this->_receive['ScanCodeInfo'];\n\t\t        $this->_receive['ScanCodeInfo']=$array;\n\t\t    }else {\n\t\t        $array=$this->_receive['ScanCodeInfo'];\n\t\t    }\n\t\t}\n\t\tif (isset($array) && count($array) > 0) {\n\t\t\treturn $array;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * 获取自定义菜单的图片发送事件信息\n\t *\n\t * 事件类型为以下三种时则调用此方法有效\n\t * Event\t 事件类型，pic_sysphoto        弹出系统拍照发图的事件推送\n\t * Event\t 事件类型，pic_photo_or_album  弹出拍照或者相册发图的事件推送\n\t * Event\t 事件类型，pic_weixin          弹出微信相册发图器的事件推送\n\t *\n\t * @return: array | false\n\t * array (\n\t *   'Count' => '2',\n\t *   'PicList' =>array (\n\t *         'item' =>array (\n\t *             0 =>array ('PicMd5Sum' => 'aaae42617cf2a14342d96005af53624c'),\n\t *             1 =>array ('PicMd5Sum' => '149bd39e296860a2adc2f1bb81616ff8'),\n\t *         ),\n\t *   ),\n\t * )\n\t *\n\t */\n\tpublic function getRevSendPicsInfo(){\n\t\tif (isset($this->_receive['SendPicsInfo'])){\n\t\t    if (!is_array($this->_receive['SendPicsInfo'])) {\n\t\t        $array=(array)$this->_receive['SendPicsInfo'];\n\t\t        if (isset($array['PicList'])){\n\t\t            $array['PicList']=(array)$array['PicList'];\n\t\t            $item=$array['PicList']['item'];\n\t\t            $array['PicList']['item']=array();\n\t\t            foreach ( $item as $key => $value ){\n\t\t                $array['PicList']['item'][$key]=(array)$value;\n\t\t            }\n\t\t        }\n\t\t        $this->_receive['SendPicsInfo']=$array;\n\t\t    } else {\n\t\t        $array=$this->_receive['SendPicsInfo'];\n\t\t    }\n\t\t}\n\t\tif (isset($array) && count($array) > 0) {\n\t\t\treturn $array;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * 获取自定义菜单的地理位置选择器事件推送\n\t *\n\t * 事件类型为以下时则可以调用此方法有效\n\t * Event\t 事件类型，location_select        弹出地理位置选择器的事件推送\n\t *\n\t * @return: array | false\n\t * array (\n\t *   'Location_X' => '33.731655000061',\n\t *   'Location_Y' => '113.29955200008047',\n\t *   'Scale' => '16',\n\t *   'Label' => '某某市某某区某某路',\n\t *   'Poiname' => '',\n\t * )\n\t *\n\t */\n\tpublic function getRevSendGeoInfo(){\n\t    if (isset($this->_receive['SendLocationInfo'])){\n\t        if (!is_array($this->_receive['SendLocationInfo'])) {\n\t            $array=(array)$this->_receive['SendLocationInfo'];\n\t            if (empty($array['Poiname'])) {\n\t                $array['Poiname']=\"\";\n\t            }\n\t            if (empty($array['Label'])) {\n\t                $array['Label']=\"\";\n\t            }\n\t            $this->_receive['SendLocationInfo']=$array;\n\t        } else {\n\t            $array=$this->_receive['SendLocationInfo'];\n\t        }\n\t    }\n\t    if (isset($array) && count($array) > 0) {\n\t        return $array;\n\t    } else {\n\t        return false;\n\t    }\n\t}\n\n\t/**\n\t * 获取接收语音推送\n\t */\n\tpublic function getRevVoice(){\n\t\tif (isset($this->_receive['MediaId'])){\n\t\t\treturn array(\n\t\t\t\t'mediaid'=>$this->_receive['MediaId'],\n\t\t\t\t'format'=>$this->_receive['Format'],\n\t\t\t);\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收视频推送\n\t */\n\tpublic function getRevVideo(){\n\t\tif (isset($this->_receive['MediaId'])){\n\t\t\treturn array(\n\t\t\t\t\t'mediaid'=>$this->_receive['MediaId'],\n\t\t\t\t\t'thumbmediaid'=>$this->_receive['ThumbMediaId']\n\t\t\t);\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取接收TICKET\n\t */\n\tpublic function getRevTicket(){\n\t\tif (isset($this->_receive['Ticket'])){\n\t\t\treturn $this->_receive['Ticket'];\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\t/**\n\t* 获取二维码的场景值\n\t*/\n\tpublic function getRevSceneId (){\n\t\tif (isset($this->_receive['EventKey'])){\n\t\t\treturn str_replace('qrscene_','',$this->_receive['EventKey']);\n\t\t} else{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t* 获取主动推送的消息ID\n\t* 经过验证，这个和普通的消息MsgId不一样\n\t* 当Event为 MASSSENDJOBFINISH 或 TEMPLATESENDJOBFINISH\n\t*/\n\tpublic function getRevTplMsgID(){\n\t\tif (isset($this->_receive['MsgID'])){\n\t\t\treturn $this->_receive['MsgID'];\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\t/**\n\t* 获取模板消息发送状态\n\t*/\n\tpublic function getRevStatus(){\n\t\tif (isset($this->_receive['Status'])){\n\t\t\treturn $this->_receive['Status'];\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\t/**\n\t* 获取群发或模板消息发送结果\n\t* 当Event为 MASSSENDJOBFINISH 或 TEMPLATESENDJOBFINISH，即高级群发/模板消息\n\t*/\n\tpublic function getRevResult(){\n\t\tif (isset($this->_receive['Status'])) //发送是否成功，具体的返回值请参考 高级群发/模板消息 的事件推送说明\n\t\t\t$array['Status'] = $this->_receive['Status'];\n\t\tif (isset($this->_receive['MsgID'])) //发送的消息id\n\t\t\t$array['MsgID'] = $this->_receive['MsgID'];\n\n\t\t//以下仅当群发消息时才会有的事件内容\n\t\tif (isset($this->_receive['TotalCount']))     //分组或openid列表内粉丝数量\n\t\t\t$array['TotalCount'] = $this->_receive['TotalCount'];\n\t\tif (isset($this->_receive['FilterCount']))    //过滤（过滤是指特定地区、性别的过滤、用户设置拒收的过滤，用户接收已超4条的过滤）后，准备发送的粉丝数\n\t\t\t$array['FilterCount'] = $this->_receive['FilterCount'];\n\t\tif (isset($this->_receive['SentCount']))     //发送成功的粉丝数\n\t\t\t$array['SentCount'] = $this->_receive['SentCount'];\n\t\tif (isset($this->_receive['ErrorCount']))    //发送失败的粉丝数\n\t\t\t$array['ErrorCount'] = $this->_receive['ErrorCount'];\n\t\tif (isset($array) && count($array) > 0) {\n\t\t    return $array;\n\t\t} else {\n\t\t    return false;\n\t\t}\n\t}\n\n\t/**\n\t * 获取多客服会话状态推送事件 - 接入会话\n\t * 当Event为 kfcreatesession 即接入会话\n\t * @return string | boolean  返回分配到的客服\n\t */\n\tpublic function getRevKFCreate(){\n\t\tif (isset($this->_receive['KfAccount'])){\n\t\t\treturn $this->_receive['KfAccount'];\n\t\t} else\n\t\t\treturn false;\n\t}\n\n\t/**\n\t * 获取多客服会话状态推送事件 - 关闭会话\n\t * 当Event为 kfclosesession 即关闭会话\n\t * @return string | boolean  返回分配到的客服\n\t */\n\tpublic function getRevKFClose(){\n\t    if (isset($this->_receive['KfAccount'])){\n\t        return $this->_receive['KfAccount'];\n\t    } else\n\t        return false;\n\t}\n\n\t/**\n\t * 获取多客服会话状态推送事件 - 转接会话\n\t * 当Event为 kfswitchsession 即转接会话\n\t * @return array | boolean  返回分配到的客服\n\t * {\n\t *     'FromKfAccount' => '',      //原接入客服\n\t *     'ToKfAccount' => ''            //转接到客服\n\t * }\n\t */\n\tpublic function getRevKFSwitch(){\n\t    if (isset($this->_receive['FromKfAccount']))     //原接入客服\n\t        $array['FromKfAccount'] = $this->_receive['FromKfAccount'];\n\t    if (isset($this->_receive['ToKfAccount']))    //转接到客服\n\t        $array['ToKfAccount'] = $this->_receive['ToKfAccount'];\n\t    if (isset($array) && count($array) > 0) {\n\t        return $array;\n\t    } else {\n\t        return false;\n\t    }\n\t}\n\n\t/**\n\t * 获取卡券事件推送 - 卡卷审核是否通过\n\t * 当Event为 card_pass_check(审核通过) 或 card_not_pass_check(未通过)\n\t * @return string|boolean  返回卡券ID\n\t */\n\tpublic function getRevCardPass(){\n\t    if (isset($this->_receive['CardId']))\n\t        return $this->_receive['CardId'];\n\t    else\n\t        return false;\n\t}\n\n\t/**\n\t * 获取卡券事件推送 - 领取卡券\n\t * 当Event为 user_get_card(用户领取卡券)\n\t * @return array|boolean\n\t */\n\tpublic function getRevCardGet(){\n\t    if (isset($this->_receive['CardId']))     //卡券 ID\n\t        $array['CardId'] = $this->_receive['CardId'];\n\t    if (isset($this->_receive['IsGiveByFriend']))    //是否为转赠，1 代表是，0 代表否。\n\t        $array['IsGiveByFriend'] = $this->_receive['IsGiveByFriend'];\n\t    if (isset($this->_receive['UserCardCode']) && !empty($this->_receive['UserCardCode'])) //code 序列号。自定义 code 及非自定义 code的卡券被领取后都支持事件推送。\n\t        $array['UserCardCode'] = $this->_receive['UserCardCode'];\n\t    if (isset($array) && count($array) > 0) {\n\t        return $array;\n\t    } else {\n\t        return false;\n\t    }\n\t}\n\n\t/**\n\t * 获取卡券事件推送 - 删除卡券\n\t * 当Event为 user_del_card(用户删除卡券)\n\t * @return array|boolean\n\t */\n\tpublic function getRevCardDel(){\n\t    if (isset($this->_receive['CardId']))     //卡券 ID\n\t        $array['CardId'] = $this->_receive['CardId'];\n\t    if (isset($this->_receive['UserCardCode']) && !empty($this->_receive['UserCardCode'])) //code 序列号。自定义 code 及非自定义 code的卡券被领取后都支持事件推送。\n\t        $array['UserCardCode'] = $this->_receive['UserCardCode'];\n\t    if (isset($array) && count($array) > 0) {\n\t        return $array;\n\t    } else {\n\t        return false;\n\t    }\n\t}\n\n\tpublic static function xmlSafeStr($str)\n\t{\n\t\treturn '<![CDATA['.preg_replace(\"/[\\\\x00-\\\\x08\\\\x0b-\\\\x0c\\\\x0e-\\\\x1f]/\",'',$str).']]>';\n\t}\n\n\t/**\n\t * 数据XML编码\n\t * @param mixed $data 数据\n\t * @return string\n\t */\n\tpublic static function data_to_xml($data) {\n\t    $xml = '';\n\t    foreach ($data as $key => $val) {\n\t        is_numeric($key) && $key = \"item id=\\\"$key\\\"\";\n\t        $xml    .=  \"<$key>\";\n\t        $xml    .=  ( is_array($val) || is_object($val)) ? self::data_to_xml($val)  : self::xmlSafeStr($val);\n\t        list($key, ) = explode(' ', $key);\n\t        $xml    .=  \"</$key>\";\n\t    }\n\t    return $xml;\n\t}\n\n\t/**\n\t * XML编码\n\t * @param mixed $data 数据\n\t * @param string $root 根节点名\n\t * @param string $item 数字索引的子节点名\n\t * @param string $attr 根节点属性\n\t * @param string $id   数字索引子节点key转换的属性名\n\t * @param string $encoding 数据编码\n\t * @return string\n\t*/\n\tpublic function xml_encode($data, $root='xml', $item='item', $attr='', $id='id', $encoding='utf-8') {\n\t    if(is_array($attr)){\n\t        $_attr = array();\n\t        foreach ($attr as $key => $value) {\n\t            $_attr[] = \"{$key}=\\\"{$value}\\\"\";\n\t        }\n\t        $attr = implode(' ', $_attr);\n\t    }\n\t    $attr   = trim($attr);\n\t    $attr   = empty($attr) ? '' : \" {$attr}\";\n\t    $xml   = \"<{$root}{$attr}>\";\n\t    $xml   .= self::data_to_xml($data, $item, $id);\n\t    $xml   .= \"</{$root}>\";\n\t    return $xml;\n\t}\n\n\t/**\n\t * 过滤文字回复\\r\\n换行符\n\t * @param string $text\n\t * @return string|mixed\n\t */\n\tprivate function _auto_text_filter($text) {\n\t\tif (!$this->_text_filter) return $text;\n\t\treturn str_replace(\"\\r\\n\", \"\\n\", $text);\n\t}\n\n\t/**\n\t * 设置回复消息\n\t * Example: $obj->text('hello')->reply();\n\t * @param string $text\n\t */\n\tpublic function text($text='')\n\t{\n\t\t$FuncFlag = $this->_funcflag ? 1 : 0;\n\t\t$msg = array(\n\t\t\t'ToUserName' => $this->getRevFrom(),\n\t\t\t'FromUserName'=>$this->getRevTo(),\n\t\t\t'MsgType'=>self::MSGTYPE_TEXT,\n\t\t\t'Content'=>$this->_auto_text_filter($text),\n\t\t\t'CreateTime'=>time(),\n\t\t\t'FuncFlag'=>$FuncFlag\n\t\t);\n\t\t$this->Message($msg);\n\t\treturn $this;\n\t}\n\t/**\n\t * 设置回复消息\n\t * Example: $obj->image('media_id')->reply();\n\t * @param string $mediaid\n\t */\n\tpublic function image($mediaid='')\n\t{\n\t\t$FuncFlag = $this->_funcflag ? 1 : 0;\n\t\t$msg = array(\n\t\t\t'ToUserName' => $this->getRevFrom(),\n\t\t\t'FromUserName'=>$this->getRevTo(),\n\t\t\t'MsgType'=>self::MSGTYPE_IMAGE,\n\t\t\t'Image'=>array('MediaId'=>$mediaid),\n\t\t\t'CreateTime'=>time(),\n\t\t\t'FuncFlag'=>$FuncFlag\n\t\t);\n\t\t$this->Message($msg);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * 设置回复消息\n\t * Example: $obj->voice('media_id')->reply();\n\t * @param string $mediaid\n\t */\n\tpublic function voice($mediaid='')\n\t{\n\t\t$FuncFlag = $this->_funcflag ? 1 : 0;\n\t\t$msg = array(\n\t\t\t'ToUserName' => $this->getRevFrom(),\n\t\t\t'FromUserName'=>$this->getRevTo(),\n\t\t\t'MsgType'=>self::MSGTYPE_VOICE,\n\t\t\t'Voice'=>array('MediaId'=>$mediaid),\n\t\t\t'CreateTime'=>time(),\n\t\t\t'FuncFlag'=>$FuncFlag\n\t\t);\n\t\t$this->Message($msg);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * 设置回复消息\n\t * Example: $obj->video('media_id','title','description')->reply();\n\t * @param string $mediaid\n\t */\n\tpublic function video($mediaid='',$title='',$description='')\n\t{\n\t\t$FuncFlag = $this->_funcflag ? 1 : 0;\n\t\t$msg = array(\n\t\t\t'ToUserName' => $this->getRevFrom(),\n\t\t\t'FromUserName'=>$this->getRevTo(),\n\t\t\t'MsgType'=>self::MSGTYPE_VIDEO,\n\t\t\t'Video'=>array(\n\t\t\t        'MediaId'=>$mediaid,\n\t\t\t        'Title'=>$title,\n\t\t\t        'Description'=>$description\n\t\t\t),\n\t\t\t'CreateTime'=>time(),\n\t\t\t'FuncFlag'=>$FuncFlag\n\t\t);\n\t\t$this->Message($msg);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * 设置回复音乐\n\t * @param string $title\n\t * @param string $desc\n\t * @param string $musicurl\n\t * @param string $hgmusicurl\n\t * @param string $thumbmediaid 音乐图片缩略图的媒体id，非必须\n\t */\n\tpublic function music($title,$desc,$musicurl,$hgmusicurl='',$thumbmediaid='') {\n\t\t$FuncFlag = $this->_funcflag ? 1 : 0;\n\t\t$msg = array(\n\t\t\t'ToUserName' => $this->getRevFrom(),\n\t\t\t'FromUserName'=>$this->getRevTo(),\n\t\t\t'CreateTime'=>time(),\n\t\t\t'MsgType'=>self::MSGTYPE_MUSIC,\n\t\t\t'Music'=>array(\n\t\t\t\t'Title'=>$title,\n\t\t\t\t'Description'=>$desc,\n\t\t\t\t'MusicUrl'=>$musicurl,\n\t\t\t\t'HQMusicUrl'=>$hgmusicurl\n\t\t\t),\n\t\t\t'FuncFlag'=>$FuncFlag\n\t\t);\n\t\tif ($thumbmediaid) {\n\t\t\t$msg['Music']['ThumbMediaId'] = $thumbmediaid;\n\t\t}\n\t\t$this->Message($msg);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * 设置回复图文\n\t * @param array $newsData\n\t * 数组结构:\n\t *  array(\n\t *  \t\"0\"=>array(\n\t *  \t\t'Title'=>'msg title',\n\t *  \t\t'Description'=>'summary text',\n\t *  \t\t'PicUrl'=>'http://www.domain.com/1.jpg',\n\t *  \t\t'Url'=>'http://www.domain.com/1.html'\n\t *  \t),\n\t *  \t\"1\"=>....\n\t *  )\n\t */\n\tpublic function news($newsData=array())\n\t{\n\t\t$FuncFlag = $this->_funcflag ? 1 : 0;\n\t\t$count = count($newsData);\n\n\t\t$msg = array(\n\t\t\t'ToUserName' => $this->getRevFrom(),\n\t\t\t'FromUserName'=>$this->getRevTo(),\n\t\t\t'MsgType'=>self::MSGTYPE_NEWS,\n\t\t\t'CreateTime'=>time(),\n\t\t\t'ArticleCount'=>$count,\n\t\t\t'Articles'=>$newsData,\n\t\t\t'FuncFlag'=>$FuncFlag\n\t\t);\n\t\t$this->Message($msg);\n\t\treturn $this;\n\t}\n\n\t/**\n\t *\n\t * 回复微信服务器, 此函数支持链式操作\n\t * Example: $this->text('msg tips')->reply();\n\t * @param string $msg 要发送的信息, 默认取$this->_msg\n\t * @param bool $return 是否返回信息而不抛出到浏览器 默认:否\n\t */\n\tpublic function reply($msg=array(),$return = false)\n\t{\n\t\tif (empty($msg)) {\n\t\t    if (empty($this->_msg))   //防止不先设置回复内容，直接调用reply方法导致异常\n\t\t        return false;\n\t\t\t$msg = $this->_msg;\n\t\t}\n\t\t$xmldata=  $this->xml_encode($msg);\n\t\t$this->log($xmldata);\n\t\tif ($this->encrypt_type == 'aes') { //如果来源消息为加密方式\n\t\t    $pc = new Prpcrypt($this->encodingAesKey);\n\t\t    $array = $pc->encrypt($xmldata, $this->appid);\n\t\t    $ret = $array[0];\n\t\t    if ($ret != 0) {\n\t\t        $this->log('encrypt err!');\n\t\t        return false;\n\t\t    }\n\t\t    $timestamp = time();\n\t\t    $nonce = rand(77,999)*rand(605,888)*rand(11,99);\n\t\t    $encrypt = $array[1];\n\t\t    $tmpArr = array($this->token, $timestamp, $nonce,$encrypt);//比普通公众平台多了一个加密的密文\n\t\t    sort($tmpArr, SORT_STRING);\n\t\t    $signature = implode($tmpArr);\n\t\t    $signature = sha1($signature);\n\t\t    $xmldata = $this->generate($encrypt, $signature, $timestamp, $nonce);\n\t\t    $this->log($xmldata);\n\t\t}\n\t\tif ($return)\n\t\t\treturn $xmldata;\n\t\telse\n\t\t\techo $xmldata;\n\t}\n\n    /**\n     * xml格式加密，仅请求为加密方式时再用\n     */\n\tprivate function generate($encrypt, $signature, $timestamp, $nonce)\n\t{\n\t    //格式化加密信息\n\t    $format = \"<xml>\n<Encrypt><![CDATA[%s]]></Encrypt>\n<MsgSignature><![CDATA[%s]]></MsgSignature>\n<TimeStamp>%s</TimeStamp>\n<Nonce><![CDATA[%s]]></Nonce>\n</xml>\";\n\t    return sprintf($format, $encrypt, $signature, $timestamp, $nonce);\n\t}\n\n\t/**\n\t * GET 请求\n\t * @param string $url\n\t */\n\tprivate function http_get($url){\n\t\t$oCurl = curl_init();\n\t\tif(stripos($url,\"https://\")!==FALSE){\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1\n\t\t}\n\t\tcurl_setopt($oCurl, CURLOPT_URL, $url);\n\t\tcurl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );\n\t\t$sContent = curl_exec($oCurl);\n\t\t$aStatus = curl_getinfo($oCurl);\n\t\tcurl_close($oCurl);\n\t\tif(intval($aStatus[\"http_code\"])==200){\n\t\t\treturn $sContent;\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * POST 请求\n\t * @param string $url\n\t * @param array $param\n\t * @param boolean $post_file 是否文件上传\n\t * @return string content\n\t */\n\tprivate function http_post($url,$param,$post_file=false){\n\t\t$oCurl = curl_init();\n\t\tif(stripos($url,\"https://\")!==FALSE){\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYPEER, FALSE);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);\n\t\t\tcurl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1\n\t\t}\n\t\tif (is_string($param) || $post_file) {\n\t\t\t$strPOST = $param;\n\t\t} else {\n\t\t\t$aPOST = array();\n\t\t\tforeach($param as $key=>$val){\n\t\t\t\t$aPOST[] = $key.\"=\".urlencode($val);\n\t\t\t}\n\t\t\t$strPOST =  join(\"&\", $aPOST);\n\t\t}\n\t\tcurl_setopt($oCurl, CURLOPT_URL, $url);\n\t\tcurl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );\n\t\tcurl_setopt($oCurl, CURLOPT_POST,true);\n\t\tcurl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);\n\t\t$sContent = curl_exec($oCurl);\n\t\t$aStatus = curl_getinfo($oCurl);\n\t\tcurl_close($oCurl);\n\t\tif(intval($aStatus[\"http_code\"])==200){\n\t\t\treturn $sContent;\n\t\t}else{\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t/**\n\t * 设置缓存，按需重载\n\t * @param string $cachename\n\t * @param mixed $value\n\t * @param int $expired\n\t * @return boolean\n\t */\n\tprotected function setCache($cachename,$value,$expired){\n\t\t//TODO: set cache implementation\n\t\treturn false;\n\t}\n\n\t/**\n\t * 获取缓存，按需重载\n\t * @param string $cachename\n\t * @return mixed\n\t */\n\tprotected function getCache($cachename){\n\t\t//TODO: get cache implementation\n\t\treturn false;\n\t}\n\n\t/**\n\t * 清除缓存，按需重载\n\t * @param string $cachename\n\t * @return boolean\n\t */\n\tprotected function removeCache($cachename){\n\t\t//TODO: remove cache implementation\n\t\treturn false;\n\t}\n\n\t/**\n\t * 获取access_token\n\t * @param string $appid 如在类初始化时已提供，则可为空\n\t * @param string $appsecret 如在类初始化时已提供，则可为空\n\t * @param string $token 手动指定access_token，非必要情况不建议用\n\t */\n\tpublic function checkAuth($appid='',$appsecret='',$token=''){\n\t\tif (!$appid || !$appsecret) {\n\t\t\t$appid = $this->appid;\n\t\t\t$appsecret = $this->appsecret;\n\t\t}\n\t\tif ($token) { //手动指定token，优先使用\n\t\t    $this->access_token=$token;\n\t\t    return $this->access_token;\n\t\t}\n\n\t\t$authname = 'wechat_access_token'.$appid;\n\t\tif ($rs = $this->getCache($authname))  {\n\t\t\t$this->access_token = $rs;\n\t\t\treturn $rs;\n\t\t}\n\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::AUTH_URL.'appid='.$appid.'&secret='.$appsecret);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || isset($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t$this->access_token = $json['access_token'];\n\t\t\t$expire = $json['expires_in'] ? intval($json['expires_in'])-100 : 3600;\n\t\t\t$this->setCache($authname,$this->access_token,$expire);\n\t\t\treturn $this->access_token;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 删除验证数据\n\t * @param string $appid\n\t */\n\tpublic function resetAuth($appid=''){\n\t\tif (!$appid) $appid = $this->appid;\n\t\t$this->access_token = '';\n\t\t$authname = 'wechat_access_token'.$appid;\n\t\t$this->removeCache($authname);\n\t\treturn true;\n\t}\n\n\t/**\n\t * 删除JSAPI授权TICKET\n\t * @param string $appid 用于多个appid时使用\n\t */\n\tpublic function resetJsTicket($appid=''){\n\t\tif (!$appid) $appid = $this->appid;\n\t\t$this->jsapi_ticket = '';\n\t\t$authname = 'wechat_jsapi_ticket'.$appid;\n\t\t$this->removeCache($authname);\n\t\treturn true;\n\t}\n\n\t/**\n\t * 获取JSAPI授权TICKET\n\t * @param string $appid 用于多个appid时使用,可空\n\t * @param string $jsapi_ticket 手动指定jsapi_ticket，非必要情况不建议用\n\t */\n\tpublic function getJsTicket($appid='',$jsapi_ticket=''){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\tif (!$appid) $appid = $this->appid;\n\t\tif ($jsapi_ticket) { //手动指定token，优先使用\n\t\t    $this->jsapi_ticket = $jsapi_ticket;\n\t\t    return $this->jsapi_ticket;\n\t\t}\n\t\t$authname = 'wechat_jsapi_ticket'.$appid;\n\t\tif ($rs = $this->getCache($authname))  {\n\t\t\t$this->jsapi_ticket = $rs;\n\t\t\treturn $rs;\n\t\t}\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::GET_TICKET_URL.'access_token='.$this->access_token.'&type=jsapi');\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t$this->jsapi_ticket = $json['ticket'];\n\t\t\t$expire = $json['expires_in'] ? intval($json['expires_in'])-100 : 3600;\n\t\t\t$this->setCache($authname,$this->jsapi_ticket,$expire);\n\t\t\treturn $this->jsapi_ticket;\n\t\t}\n\t\treturn false;\n\t}\n\n\n\t/**\n\t * 获取JsApi使用签名\n\t * @param string $url 网页的URL，自动处理#及其后面部分\n\t * @param string $timestamp 当前时间戳 (为空则自动生成)\n\t * @param string $noncestr 随机串 (为空则自动生成)\n\t * @param string $appid 用于多个appid时使用,可空\n\t * @return array|bool 返回签名字串\n\t */\n\tpublic function getJsSign($url, $timestamp=0, $noncestr='', $appid=''){\n\t    if (!$this->jsapi_ticket && !$this->getJsTicket($appid) || !$url) return false;\n\t    if (!$timestamp)\n\t        $timestamp = time();\n\t    if (!$noncestr)\n\t        $noncestr = $this->generateNonceStr();\n\t    $ret = strpos($url,'#');\n\t    if ($ret)\n\t        $url = substr($url,0,$ret);\n\t    $url = trim($url);\n\t    if (empty($url))\n\t        return false;\n\t    $arrdata = array(\"timestamp\" => $timestamp, \"noncestr\" => $noncestr, \"url\" => $url, \"jsapi_ticket\" => $this->jsapi_ticket);\n\t    $sign = $this->getSignature($arrdata);\n\t    if (!$sign)\n\t        return false;\n\t    $signPackage = array(\n\t            \"appid\"     => $this->appid,\n\t            \"noncestr\"  => $noncestr,\n\t            \"timestamp\" => $timestamp,\n\t            \"url\"       => $url,\n\t            \"signature\" => $sign\n\t    );\n\t    return $signPackage;\n\t}\n\n\t/**\n\t * 微信api不支持中文转义的json结构\n\t * @param array $arr\n\t */\n\tstatic function json_encode($arr) {\n\t\t$parts = array ();\n\t\t$is_list = false;\n\t\t//Find out if the given array is a numerical array\n\t\t$keys = array_keys ( $arr );\n\t\t$max_length = count ( $arr ) - 1;\n\t\tif (($keys [0] === 0) && ($keys [$max_length] === $max_length )) { //See if the first key is 0 and last key is length - 1\n\t\t\t$is_list = true;\n\t\t\tfor($i = 0; $i < count ( $keys ); $i ++) { //See if each key correspondes to its position\n\t\t\t\tif ($i != $keys [$i]) { //A key fails at position check.\n\t\t\t\t\t$is_list = false; //It is an associative array.\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tforeach ( $arr as $key => $value ) {\n\t\t\tif (is_array ( $value )) { //Custom handling for arrays\n\t\t\t\tif ($is_list)\n\t\t\t\t\t$parts [] = self::json_encode ( $value ); /* :RECURSION: */\n\t\t\t\telse\n\t\t\t\t\t$parts [] = '\"' . $key . '\":' . self::json_encode ( $value ); /* :RECURSION: */\n\t\t\t} else {\n\t\t\t\t$str = '';\n\t\t\t\tif (! $is_list)\n\t\t\t\t\t$str = '\"' . $key . '\":';\n\t\t\t\t//Custom handling for multiple data types\n\t\t\t\tif (!is_string ( $value ) && is_numeric ( $value ) && $value<2000000000)\n\t\t\t\t\t$str .= $value; //Numbers\n\t\t\t\telseif ($value === false)\n\t\t\t\t$str .= 'false'; //The booleans\n\t\t\t\telseif ($value === true)\n\t\t\t\t$str .= 'true';\n\t\t\t\telse\n\t\t\t\t\t$str .= '\"' . addslashes ( $value ) . '\"'; //All other things\n\t\t\t\t// :TODO: Is there any more datatype we should be in the lookout for? (Object?)\n\t\t\t\t$parts [] = $str;\n\t\t\t}\n\t\t}\n\t\t$json = implode ( ',', $parts );\n\t\tif ($is_list)\n\t\t\treturn '[' . $json . ']'; //Return numerical JSON\n\t\treturn '{' . $json . '}'; //Return associative JSON\n\t}\n\n\t/**\n\t * 获取签名\n\t * @param array $arrdata 签名数组\n\t * @param string $method 签名方法\n\t * @return boolean|string 签名值\n\t */\n\tpublic function getSignature($arrdata,$method=\"sha1\") {\n\t\tif (!function_exists($method)) return false;\n\t\tksort($arrdata);\n\t\t$paramstring = \"\";\n\t\tforeach($arrdata as $key => $value)\n\t\t{\n\t\t\tif(strlen($paramstring) == 0)\n\t\t\t\t$paramstring .= $key . \"=\" . $value;\n\t\t\telse\n\t\t\t\t$paramstring .= \"&\" . $key . \"=\" . $value;\n\t\t}\n\t\t$Sign = $method($paramstring);\n\t\treturn $Sign;\n\t}\n\n\t/**\n\t * 生成随机字串\n\t * @param number $length 长度，默认为16，最长为32字节\n\t * @return string\n\t */\n\tpublic function generateNonceStr($length=16){\n\t\t// 密码字符集，可任意添加你需要的字符\n\t\t$chars = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\";\n\t\t$str = \"\";\n\t\tfor($i = 0; $i < $length; $i++)\n\t\t{\n\t\t\t$str .= $chars[mt_rand(0, strlen($chars) - 1)];\n\t\t}\n\t\treturn $str;\n\t}\n\n\t/**\n\t * 获取微信服务器IP地址列表\n\t * @return array('127.0.0.1','127.0.0.1')\n\t */\n\tpublic function getServerIp(){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::CALLBACKSERVER_GET_URL.'access_token='.$this->access_token);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || isset($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json['ip_list'];\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 创建菜单(认证后的订阅号可用)\n\t * @param array $data 菜单数组数据\n\t * example:\n     * \tarray (\n     * \t    'button' => array (\n     * \t      0 => array (\n     * \t        'name' => '扫码',\n     * \t        'sub_button' => array (\n     * \t            0 => array (\n     * \t              'type' => 'scancode_waitmsg',\n     * \t              'name' => '扫码带提示',\n     * \t              'key' => 'rselfmenu_0_0',\n     * \t            ),\n     * \t            1 => array (\n     * \t              'type' => 'scancode_push',\n     * \t              'name' => '扫码推事件',\n     * \t              'key' => 'rselfmenu_0_1',\n     * \t            ),\n     * \t        ),\n     * \t      ),\n     * \t      1 => array (\n     * \t        'name' => '发图',\n     * \t        'sub_button' => array (\n     * \t            0 => array (\n     * \t              'type' => 'pic_sysphoto',\n     * \t              'name' => '系统拍照发图',\n     * \t              'key' => 'rselfmenu_1_0',\n     * \t            ),\n     * \t            1 => array (\n     * \t              'type' => 'pic_photo_or_album',\n     * \t              'name' => '拍照或者相册发图',\n     * \t              'key' => 'rselfmenu_1_1',\n     * \t            )\n     * \t        ),\n     * \t      ),\n     * \t      2 => array (\n     * \t        'type' => 'location_select',\n     * \t        'name' => '发送位置',\n     * \t        'key' => 'rselfmenu_2_0'\n     * \t      ),\n     * \t    ),\n     * \t)\n     * type可以选择为以下几种，其中5-8除了收到菜单事件以外，还会单独收到对应类型的信息。\n     * 1、click：点击推事件\n     * 2、view：跳转URL\n     * 3、scancode_push：扫码推事件\n     * 4、scancode_waitmsg：扫码推事件且弹出“消息接收中”提示框\n     * 5、pic_sysphoto：弹出系统拍照发图\n     * 6、pic_photo_or_album：弹出拍照或者相册发图\n     * 7、pic_weixin：弹出微信相册发图器\n     * 8、location_select：弹出地理位置选择器\n\t */\n\tpublic function createMenu($data){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::MENU_CREATE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 获取菜单(认证后的订阅号可用)\n\t * @return array('menu'=>array(....s))\n\t */\n\tpublic function getMenu(){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::MENU_GET_URL.'access_token='.$this->access_token);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || isset($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 删除菜单(认证后的订阅号可用)\n\t * @return boolean\n\t */\n\tpublic function deleteMenu(){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::MENU_DELETE_URL.'access_token='.$this->access_token);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 上传多媒体文件(认证后的订阅号可用)\n\t * 注意：上传大文件时可能需要先调用 set_time_limit(0) 避免超时\n\t * 注意：数组的键值任意，但文件名前必须加@，使用单引号以避免本地路径斜杠被转义\n\t * @param array $data {\"media\":'@Path\\filename.jpg'}\n\t * @param type 类型：图片:image 语音:voice 视频:video 缩略图:thumb\n\t * @return boolean|array\n\t */\n\tpublic function uploadMedia($data, $type){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_post(self::UPLOAD_MEDIA_URL.self::MEDIA_UPLOAD_URL.'access_token='.$this->access_token.'&type='.$type,$data,true);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 根据媒体文件ID获取媒体文件(认证后的订阅号可用)\n\t * @param string $media_id 媒体文件id\n\t * @return raw data\n\t */\n\tpublic function getMedia($media_id){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_get(self::UPLOAD_MEDIA_URL.self::MEDIA_GET_URL.'access_token='.$this->access_token.'&media_id='.$media_id);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (isset($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $result;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 上传图文消息素材(认证后的订阅号可用)\n\t * @param array $data 消息结构{\"articles\":[{...}]}\n\t * @return boolean|array\n\t */\n\tpublic function uploadArticles($data){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::MEDIA_UPLOADNEWS_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 上传视频素材(认证后的订阅号可用)\n\t * @param array $data 消息结构\n\t * {\n\t *     \"media_id\"=>\"\",     //通过上传媒体接口得到的MediaId\n\t *     \"title\"=>\"TITLE\",    //视频标题\n\t *     \"description\"=>\"Description\"        //视频描述\n\t * }\n\t * @return boolean|array\n\t * {\n\t *     \"type\":\"video\",\n\t *     \"media_id\":\"mediaid\",\n\t *     \"created_at\":1398848981\n\t *  }\n\t */\n\tpublic function uploadMpVideo($data){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::UPLOAD_MEDIA_URL.self::MEDIA_VIDEO_UPLOAD.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 高级群发消息, 根据OpenID列表群发图文消息(订阅号不可用)\n\t * \t注意：视频需要在调用uploadMedia()方法后，再使用 uploadMpVideo() 方法生成，\n\t *             然后获得的 mediaid 才能用于群发，且消息类型为 mpvideo 类型。\n\t * @param array $data 消息结构\n\t * {\n\t *     \"touser\"=>array(\n\t *         \"OPENID1\",\n\t *         \"OPENID2\"\n\t *     ),\n\t *      \"msgtype\"=>\"mpvideo\",\n\t *      // 在下面5种类型中选择对应的参数内容\n\t *      // mpnews | voice | image | mpvideo => array( \"media_id\"=>\"MediaId\")\n\t *      // text => array ( \"content\" => \"hello\")\n\t * }\n\t * @return boolean|array\n\t */\n\tpublic function sendMassMessage($data){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::MASS_SEND_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 高级群发消息, 根据群组id群发图文消息(认证后的订阅号可用)\n\t * \t注意：视频需要在调用uploadMedia()方法后，再使用 uploadMpVideo() 方法生成，\n\t *             然后获得的 mediaid 才能用于群发，且消息类型为 mpvideo 类型。\n\t * @param array $data 消息结构\n\t * {\n\t *     \"filter\"=>array(\n\t *         \"is_to_all\"=>False,     //是否群发给所有用户.True不用分组id，False需填写分组id\n\t *         \"group_id\"=>\"2\"     //群发的分组id\n\t *     ),\n\t *      \"msgtype\"=>\"mpvideo\",\n\t *      // 在下面5种类型中选择对应的参数内容\n\t *      // mpnews | voice | image | mpvideo => array( \"media_id\"=>\"MediaId\")\n\t *      // text => array ( \"content\" => \"hello\")\n\t * }\n\t * @return boolean|array\n\t */\n\tpublic function sendGroupMassMessage($data){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::MASS_SEND_GROUP_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 高级群发消息, 删除群发图文消息(认证后的订阅号可用)\n\t * @param int $msg_id 消息id\n\t * @return boolean|array\n\t */\n\tpublic function deleteMassMessage($msg_id){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::MASS_DELETE_URL.'access_token='.$this->access_token,self::json_encode(array('msg_id'=>$msg_id)));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 高级群发消息, 预览群发消息(认证后的订阅号可用)\n\t * \t注意：视频需要在调用uploadMedia()方法后，再使用 uploadMpVideo() 方法生成，\n\t *             然后获得的 mediaid 才能用于群发，且消息类型为 mpvideo 类型。\n\t * @param array $data 消息结构\n\t * {\n\t *     \"touser\"=>\"OPENID\",\n\t *      \"msgtype\"=>\"mpvideo\",\n\t *      // 在下面5种类型中选择对应的参数内容\n\t *      // mpnews | voice | image | mpvideo => array( \"media_id\"=>\"MediaId\")\n\t *      // text => array ( \"content\" => \"hello\")\n\t * }\n\t * @return boolean|array\n\t */\n\tpublic function previewMassMessage($data){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::MASS_PREVIEW_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 高级群发消息, 查询群发消息发送状态(认证后的订阅号可用)\n\t * @param int $msg_id 消息id\n\t * @return boolean|array\n\t * {\n\t *     \"msg_id\":201053012,     //群发消息后返回的消息id\n\t *     \"msg_status\":\"SEND_SUCCESS\" //消息发送后的状态，SENDING表示正在发送 SEND_SUCCESS表示发送成功\n\t * }\n\t */\n\tpublic function queryMassMessage($msg_id){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::MASS_QUERY_URL.'access_token='.$this->access_token,self::json_encode(array('msg_id'=>$msg_id)));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 创建二维码ticket\n\t * @param int|string $scene_id 自定义追踪id,临时二维码只能用数值型\n\t * @param int $type 0:临时二维码；1:永久二维码(此时expire参数无效)；2:永久二维码(此时expire参数无效)\n\t * @param int $expire 临时二维码有效期，最大为1800秒\n\t * @return array('ticket'=>'qrcode字串','expire_seconds'=>1800,'url'=>'二维码图片解析后的地址')\n\t */\n\tpublic function getQRCode($scene_id,$type=0,$expire=1800){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$type = ($type && is_string($scene_id))?2:$type;\n\t\t$data = array(\n\t\t\t'action_name'=>$type?($type == 2?\"QR_LIMIT_STR_SCENE\":\"QR_LIMIT_SCENE\"):\"QR_SCENE\",\n\t\t\t'expire_seconds'=>$expire,\n\t\t\t'action_info'=>array('scene'=>($type == 2?array('scene_str'=>$scene_id):array('scene_id'=>$scene_id)))\n\t\t);\n\t\tif ($type == 1) {\n\t\t\tunset($data['expire_seconds']);\n\t\t}\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::QRCODE_CREATE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 获取二维码图片\n\t * @param string $ticket 传入由getQRCode方法生成的ticket参数\n\t * @return string url 返回http地址\n\t */\n\tpublic function getQRUrl($ticket) {\n\t\treturn self::QRCODE_IMG_URL.urlencode($ticket);\n\t}\n\n\t/**\n\t * 长链接转短链接接口\n\t * @param string $long_url 传入要转换的长url\n\t * @return boolean|string url 成功则返回转换后的短url\n\t */\n\tpublic function getShortUrl($long_url){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $data = array(\n            'action'=>'long2short',\n            'long_url'=>$long_url\n\t    );\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::SHORT_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json['short_url'];\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 获取统计数据\n\t * @param string $type  数据分类(user|article|upstreammsg|interface)分别为(用户分析|图文分析|消息分析|接口分析)\n\t * @param string $subtype   数据子分类，参考 DATACUBE_URL_ARR 常量定义部分 或者README.md说明文档\n\t * @param string $begin_date 开始时间\n\t * @param string $end_date   结束时间\n\t * @return boolean|array 成功返回查询结果数组，其定义请看官方文档\n\t */\n\tpublic function getDatacube($type,$subtype,$begin_date,$end_date=''){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t\tif (!isset(self::$DATACUBE_URL_ARR[$type]) || !isset(self::$DATACUBE_URL_ARR[$type][$subtype]))\n\t\t\treturn false;\n\t    $data = array(\n            'begin_date'=>$begin_date,\n            'end_date'=>$end_date?$end_date:$begin_date\n\t    );\n\t    $result = $this->http_post(self::API_BASE_URL_PREFIX.self::$DATACUBE_URL_ARR[$type][$subtype].'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return isset($json['list'])?$json['list']:$json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 批量获取关注用户列表\n\t * @param unknown $next_openid\n\t */\n\tpublic function getUserList($next_openid=''){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::USER_GET_URL.'access_token='.$this->access_token.'&next_openid='.$next_openid);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (isset($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 获取关注者详细信息\n\t * @param string $openid\n\t * @return array {subscribe,openid,nickname,sex,city,province,country,language,headimgurl,subscribe_time,[unionid]}\n\t * 注意：unionid字段 只有在用户将公众号绑定到微信开放平台账号后，才会出现。建议调用前用isset()检测一下\n\t */\n\tpublic function getUserInfo($openid){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::USER_INFO_URL.'access_token='.$this->access_token.'&openid='.$openid);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (isset($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 设置用户备注名\n\t * @param string $openid\n\t * @param string $remark 备注名\n\t * @return boolean|array\n\t */\n\tpublic function updateUserRemark($openid,$remark){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $data = array(\n\t\t\t'openid'=>$openid,\n\t\t\t'remark'=>$remark\n\t    );\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::USER_UPDATEREMARK_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 获取用户分组列表\n\t * @return boolean|array\n\t */\n\tpublic function getGroup(){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::GROUP_GET_URL.'access_token='.$this->access_token);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (isset($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 获取用户所在分组\n\t * @param string $openid\n\t * @return boolean|int 成功则返回用户分组id\n\t */\n\tpublic function getUserGroup($openid){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $data = array(\n\t            'openid'=>$openid\n\t    );\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::USER_GROUP_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        } else\n                if (isset($json['groupid'])) return $json['groupid'];\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 新增自定分组\n\t * @param string $name 分组名称\n\t * @return boolean|array\n\t */\n\tpublic function createGroup($name){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$data = array(\n\t\t\t\t'group'=>array('name'=>$name)\n\t\t);\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::GROUP_CREATE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 更改分组名称\n\t * @param int $groupid 分组id\n\t * @param string $name 分组名称\n\t * @return boolean|array\n\t */\n\tpublic function updateGroup($groupid,$name){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$data = array(\n\t\t\t\t'group'=>array('id'=>$groupid,'name'=>$name)\n\t\t);\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::GROUP_UPDATE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 移动用户分组\n\t * @param int $groupid 分组id\n\t * @param string $openid 用户openid\n\t * @return boolean|array\n\t */\n\tpublic function updateGroupMembers($groupid,$openid){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$data = array(\n\t\t\t\t'openid'=>$openid,\n\t\t\t\t'to_groupid'=>$groupid\n\t\t);\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::GROUP_MEMBER_UPDATE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 批量移动用户分组\n\t * @param int $groupid 分组id\n\t * @param string $openid_list 用户openid数组,一次不能超过50个\n\t * @return boolean|array\n\t */\n\tpublic function batchUpdateGroupMembers($groupid,$openid_list){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$data = array(\n\t\t\t\t'openid_list'=>$openid_list,\n\t\t\t\t'to_groupid'=>$groupid\n\t\t);\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::GROUP_MEMBER_BATCHUPDATE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 发送客服消息\n\t * @param array $data 消息结构{\"touser\":\"OPENID\",\"msgtype\":\"news\",\"news\":{...}}\n\t * @return boolean|array\n\t */\n\tpublic function sendCustomMessage($data){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::CUSTOM_SEND_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * oauth 授权跳转接口\n\t * @param string $callback 回调URI\n\t * @return string\n\t */\n\tpublic function getOauthRedirect($callback,$state='',$scope='snsapi_userinfo'){\n\t\treturn self::OAUTH_PREFIX.self::OAUTH_AUTHORIZE_URL.'appid='.$this->appid.'&redirect_uri='.urlencode($callback).'&response_type=code&scope='.$scope.'&state='.$state.'#wechat_redirect';\n\t}\n\t// 获取小程序token\n\tpublic function getxOauthAccessToken($code){\n\n\t\tif (!$code) return false;\n\t\t$result = $this->http_get('https://api.weixin.qq.com/sns/jscode2session?appid='.$this->appid.'&secret='.$this->appsecret.'&js_code='.$code.'&grant_type=authorization_code');\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\t/**\n\t * 通过code获取Access Token\n\t * @return array {access_token,expires_in,refresh_token,openid,scope}\n\t */\n\tpublic function getOauthAccessToken(){\n\t\t$code = isset($_GET['code'])?$_GET['code']:'';\n\t\tif (!$code) return false;\n\t\t$result = $this->http_get(self::API_BASE_URL_PREFIX.self::OAUTH_TOKEN_URL.'appid='.$this->appid.'&secret='.$this->appsecret.'&code='.$code.'&grant_type=authorization_code');\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t$this->user_token = $json['access_token'];\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 刷新access token并续期\n\t * @param string $refresh_token\n\t * @return boolean|mixed\n\t */\n\tpublic function getOauthRefreshToken($refresh_token){\n\t\t$result = $this->http_get(self::API_BASE_URL_PREFIX.self::OAUTH_REFRESH_URL.'appid='.$this->appid.'&grant_type=refresh_token&refresh_token='.$refresh_token);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\t$this->user_token = $json['access_token'];\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 获取授权后的用户资料\n\t * @param string $access_token\n\t * @param string $openid\n\t * @return array {openid,nickname,sex,province,city,country,headimgurl,privilege,[unionid]}\n\t * 注意：unionid字段 只有在用户将公众号绑定到微信开放平台账号后，才会出现。建议调用前用isset()检测一下\n\t */\n\tpublic function getOauthUserinfo($access_token,$openid){\n\t\t$result = $this->http_get(self::API_BASE_URL_PREFIX.self::OAUTH_USERINFO_URL.'access_token='.$access_token.'&openid='.$openid);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 检验授权凭证是否有效\n\t * @param string $access_token\n\t * @param string $openid\n\t * @return boolean 是否有效\n\t */\n\tpublic function getOauthAuth($access_token,$openid){\n\t    $result = $this->http_get(self::API_BASE_URL_PREFIX.self::OAUTH_AUTH_URL.'access_token='.$access_token.'&openid='.$openid);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        } else\n\t          if ($json['errcode']==0) return true;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 模板消息 设置所属行业\n\t * @param int $id1  公众号模板消息所属行业编号，参看官方开发文档 行业代码\n\t * @param int $id2  同$id1。但如果只有一个行业，此参数可省略\n\t * @return boolean|array\n\t */\n\tpublic function setTMIndustry($id1,$id2=''){\n\t    if ($id1) $data['industry_id1'] = $id1;\n\t    if ($id2) $data['industry_id2'] = $id2;\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::TEMPLATE_SET_INDUSTRY_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if($result){\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 模板消息 添加消息模板\n\t * 成功返回消息模板的调用id\n\t * @param string $tpl_id 模板库中模板的编号，有“TM**”和“OPENTMTM**”等形式\n\t * @return boolean|string\n\t */\n\tpublic function addTemplateMessage($tpl_id){\n\t    $data = array ('template_id_short' =>$tpl_id);\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_URL_PREFIX.self::TEMPLATE_ADD_TPL_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if($result){\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json['template_id'];\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 发送模板消息\n\t * @param array $data 消息结构\n\t * ｛\n\t\t\t\"touser\":\"OPENID\",\n\t\t\t\"template_id\":\"ngqIpbwh8bUfcSsECmogfXcV14J0tQlEpBO27izEYtY\",\n\t\t\t\"url\":\"http://weixin.qq.com/download\",\n\t\t\t\"topcolor\":\"#FF0000\",\n\t\t\t\"data\":{\n\t\t\t\t\"参数名1\": {\n\t\t\t\t\t\"value\":\"参数\",\n\t\t\t\t\t\"color\":\"#173177\"\t //参数颜色\n\t\t\t\t\t},\n\t\t\t\t\"Date\":{\n\t\t\t\t\t\"value\":\"06月07日 19时24分\",\n\t\t\t\t\t\"color\":\"#173177\"\n\t\t\t\t\t},\n\t\t\t\t\"CardNumber\":{\n\t\t\t\t\t\"value\":\"0426\",\n\t\t\t\t\t\"color\":\"#173177\"\n\t\t\t\t\t},\n\t\t\t\t\"Type\":{\n\t\t\t\t\t\"value\":\"消费\",\n\t\t\t\t\t\"color\":\"#173177\"\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\t * @return boolean|array\n\t */\n\tpublic function sendTemplateMessage($data){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::TEMPLATE_SEND_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t\tif($result){\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 获取多客服会话记录\n\t * @param array $data 数据结构{\"starttime\":123456789,\"endtime\":987654321,\"openid\":\"OPENID\",\"pagesize\":10,\"pageindex\":1,}\n\t * @return boolean|array\n\t */\n\tpublic function getCustomServiceMessage($data){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_post(self::API_URL_PREFIX.self::CUSTOM_SERVICE_GET_RECORD.'access_token='.$this->access_token,self::json_encode($data));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 转发多客服消息\n\t * Example: $obj->transfer_customer_service($customer_account)->reply();\n\t * @param string $customer_account 转发到指定客服帐号：test1@test\n\t */\n\tpublic function transfer_customer_service($customer_account = '')\n\t{\n\t\t$msg = array(\n\t\t\t'ToUserName' => $this->getRevFrom(),\n\t\t\t'FromUserName'=>$this->getRevTo(),\n\t\t\t'CreateTime'=>time(),\n\t\t\t'MsgType'=>'transfer_customer_service',\n\t\t);\n\t\tif ($customer_account) {\n\t\t\t$msg['TransInfo'] = array('KfAccount'=>$customer_account);\n\t\t}\n\t\t$this->Message($msg);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * 获取多客服客服基本信息\n\t *\n\t * @return boolean|array\n\t */\n\tpublic function getCustomServiceKFlist(){\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_get(self::API_URL_PREFIX.self::CUSTOM_SERVICE_GET_KFLIST.'access_token='.$this->access_token);\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 获取多客服在线客服接待信息\n\t *\n\t * @return boolean|array {\n\t \"kf_online_list\": [\n\t {\n\t \"kf_account\": \"test1@test\",\t//客服账号@微信别名\n\t \"status\": 1,\t\t\t//客服在线状态 1：pc在线，2：手机在线,若pc和手机同时在线则为 1+2=3\n\t \"kf_id\": \"1001\",\t\t//客服工号\n\t \"auto_accept\": 0,\t\t//客服设置的最大自动接入数\n\t \"accepted_case\": 1\t\t//客服当前正在接待的会话数\n\t }\n\t ]\n\t }\n\t */\n\tpublic function getCustomServiceOnlineKFlist(){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_URL_PREFIX.self::CUSTOM_SERVICE_GET_ONLINEKFLIST.'access_token='.$this->access_token);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 创建指定多客服会话\n\t * @tutorial 当用户已被其他客服接待或指定客服不在线则会失败\n\t * @param string $openid           //用户openid\n\t * @param string $kf_account     //客服账号\n\t * @param string $text                 //附加信息，文本会展示在客服人员的多客服客户端，可为空\n\t * @return boolean | array            //成功返回json数组\n\t * {\n\t *   \"errcode\": 0,\n\t *   \"errmsg\": \"ok\",\n\t * }\n\t */\n\tpublic function createKFSession($openid,$kf_account,$text=''){\n\t    $data=array(\n\t    \t\"openid\" =>$openid,\n\t        \"kf_account\" => $kf_account\n\t    );\n\t    if ($text) $data[\"text\"] = $text;\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_BASE_URL_PREFIX.self::CUSTOM_SESSION_CREATE.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 关闭指定多客服会话\n\t * @tutorial 当用户被其他客服接待时则会失败\n\t * @param string $openid           //用户openid\n\t * @param string $kf_account     //客服账号\n\t * @param string $text                 //附加信息，文本会展示在客服人员的多客服客户端，可为空\n\t * @return boolean | array            //成功返回json数组\n\t * {\n\t *   \"errcode\": 0,\n\t *   \"errmsg\": \"ok\",\n\t * }\n\t */\n\tpublic function closeKFSession($openid,$kf_account,$text=''){\n\t    $data=array(\n\t    \t\"openid\" =>$openid,\n\t        \"nickname\" => $kf_account\n\t    );\n\t    if ($text) $data[\"text\"] = $text;\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_BASE_URL_PREFIX.self::CUSTOM_SESSION_CLOSE .'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 获取用户会话状态\n\t * @param string $openid           //用户openid\n\t * @return boolean | array            //成功返回json数组\n\t * {\n\t *     \"errcode\" : 0,\n\t *     \"errmsg\" : \"ok\",\n\t *     \"kf_account\" : \"test1@test\",    //正在接待的客服\n\t *     \"createtime\": 123456789,        //会话接入时间\n\t *  }\n\t */\n\tpublic function getKFSession($openid){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_BASE_URL_PREFIX.self::CUSTOM_SESSION_GET .'access_token='.$this->access_token.'&openid='.$openid);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 获取指定客服的会话列表\n\t * @param string $openid           //用户openid\n\t * @return boolean | array            //成功返回json数组\n\t *  array(\n\t *     'sessionlist' => array (\n\t *         array (\n\t *             'openid'=>'OPENID',             //客户 openid\n\t *             'createtime'=>123456789,  //会话创建时间，UNIX 时间戳\n\t *         ),\n\t *         array (\n\t *             'openid'=>'OPENID',             //客户 openid\n\t *             'createtime'=>123456789,  //会话创建时间，UNIX 时间戳\n\t *         ),\n\t *     )\n\t *  )\n\t */\n\tpublic function getKFSessionlist($kf_account){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_BASE_URL_PREFIX.self::CUSTOM_SESSION_GET_LIST .'access_token='.$this->access_token.'&kf_account='.$kf_account);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 获取未接入会话列表\n\t * @param string $openid           //用户openid\n\t * @return boolean | array            //成功返回json数组\n\t *  array (\n\t *     'count' => 150 ,                            //未接入会话数量\n\t *     'waitcaselist' => array (\n\t *         array (\n\t *             'openid'=>'OPENID',             //客户 openid\n\t *             'kf_account ' =>'',                   //指定接待的客服，为空则未指定\n\t *             'createtime'=>123456789,  //会话创建时间，UNIX 时间戳\n\t *         ),\n\t *         array (\n\t *             'openid'=>'OPENID',             //客户 openid\n\t *             'kf_account ' =>'',                   //指定接待的客服，为空则未指定\n\t *             'createtime'=>123456789,  //会话创建时间，UNIX 时间戳\n\t *         )\n\t *     )\n\t *  )\n\t */\n\tpublic function getKFSessionWait(){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_BASE_URL_PREFIX.self::CUSTOM_SESSION_GET_WAIT .'access_token='.$this->access_token);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 添加客服账号\n\t *\n\t * @param string $account      //完整客服账号，格式为：账号前缀@公众号微信号，账号前缀最多10个字符，必须是英文或者数字字符\n\t * @param string $nickname     //客服昵称，最长6个汉字或12个英文字符\n\t * @param string $password     //客服账号明文登录密码，会自动加密\n\t * @return boolean|array\n\t * 成功返回结果\n\t * {\n\t *   \"errcode\": 0,\n\t *   \"errmsg\": \"ok\",\n\t * }\n\t */\n\tpublic function addKFAccount($account,$nickname,$password){\n\t    $data=array(\n\t    \t\"kf_account\" =>$account,\n\t        \"nickname\" => $nickname,\n\t        \"password\" => md5($password)\n\t    );\n\t\tif (!$this->access_token && !$this->checkAuth()) return false;\n\t\t$result = $this->http_post(self::API_BASE_URL_PREFIX.self::CS_KF_ACCOUNT_ADD_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t\tif ($result)\n\t\t{\n\t\t\t$json = json_decode($result,true);\n\t\t\tif (!$json || !empty($json['errcode'])) {\n\t\t\t\t$this->errCode = $json['errcode'];\n\t\t\t\t$this->errMsg = $json['errmsg'];\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\treturn $json;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * 修改客服账号信息\n\t *\n\t * @param string $account      //完整客服账号，格式为：账号前缀@公众号微信号，账号前缀最多10个字符，必须是英文或者数字字符\n\t * @param string $nickname     //客服昵称，最长6个汉字或12个英文字符\n\t * @param string $password     //客服账号明文登录密码，会自动加密\n\t * @return boolean|array\n\t * 成功返回结果\n\t * {\n\t *   \"errcode\": 0,\n\t *   \"errmsg\": \"ok\",\n\t * }\n\t */\n\tpublic function updateKFAccount($account,$nickname,$password){\n\t    $data=array(\n\t            \"kf_account\" =>$account,\n\t            \"nickname\" => $nickname,\n\t            \"password\" => md5($password)\n\t    );\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_BASE_URL_PREFIX.self::CS_KF_ACCOUNT_UPDATE_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 删除客服账号\n\t *\n\t * @param string $account      //完整客服账号，格式为：账号前缀@公众号微信号，账号前缀最多10个字符，必须是英文或者数字字符\n\t * @return boolean|array\n\t * 成功返回结果\n\t * {\n\t *   \"errcode\": 0,\n\t *   \"errmsg\": \"ok\",\n\t * }\n\t */\n\tpublic function deleteKFAccount($account){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_get(self::API_BASE_URL_PREFIX.self::CS_KF_ACCOUNT_DEL_URL.'access_token='.$this->access_token.'&kf_account='.$account);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 上传客服头像\n\t *\n\t * @param string $account //完整客服账号，格式为：账号前缀@公众号微信号，账号前缀最多10个字符，必须是英文或者数字字符\n\t * @param string $imgfile //头像文件完整路径,如：'D:\\user.jpg'。头像文件必须JPG格式，像素建议640*640\n\t * @return boolean|array\n\t * 成功返回结果\n\t * {\n\t *   \"errcode\": 0,\n\t *   \"errmsg\": \"ok\",\n\t * }\n\t */\n\tpublic function setKFHeadImg($account,$imgfile){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $result = $this->http_post(self::API_BASE_URL_PREFIX.self::CS_KF_ACCOUNT_UPLOAD_HEADIMG_URL.'access_token='.$this->access_token.'&kf_account='.$account,array('media'=>'@'.$imgfile),true);\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n\t/**\n\t * 语义理解接口\n\t * @param String $uid      用户唯一id（非开发者id），用户区分公众号下的不同用户（建议填入用户openid）\n\t * @param String $query    输入文本串\n\t * @param String $category 需要使用的服务类型，多个用“，”隔开，不能为空\n\t * @param Float $latitude  纬度坐标，与经度同时传入；与城市二选一传入\n\t * @param Float $longitude 经度坐标，与纬度同时传入；与城市二选一传入\n\t * @param String $city     城市名称，与经纬度二选一传入\n\t * @param String $region   区域名称，在城市存在的情况下可省略；与经纬度二选一传入\n\t * @return boolean|array\n\t */\n\tpublic function querySemantic($uid,$query,$category,$latitude=0,$longitude=0,$city=\"\",$region=\"\"){\n\t    if (!$this->access_token && !$this->checkAuth()) return false;\n\t    $data=array(\n\t            'query' => $query,\n\t            'category' => $category,\n\t            'appid' => $this->appid,\n\t            'uid' => ''\n\t    );\n\t    //地理坐标或城市名称二选一\n\t    if ($latitude) {\n\t        $data['latitude'] = $latitude;\n\t        $data['longitude'] = $longitude;\n\t    } elseif ($city) {\n\t        $data['city'] = $city;\n\t    } elseif ($region) {\n\t        $data['region'] = $region;\n\t    }\n\t    $result = $this->http_post(self::API_BASE_URL_PREFIX.self::SEMANTIC_API_URL.'access_token='.$this->access_token,self::json_encode($data));\n\t    if ($result)\n\t    {\n\t        $json = json_decode($result,true);\n\t        if (!$json || !empty($json['errcode'])) {\n\t            $this->errCode = $json['errcode'];\n\t            $this->errMsg = $json['errmsg'];\n\t            return false;\n\t        }\n\t        return $json;\n\t    }\n\t    return false;\n\t}\n\n    /**\n     * 创建卡券\n     * @param Array $data      卡券数据\n     * @return array|boolean 返回数组中card_id为卡券ID\n     */\n    public function createCard($data) {\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_CREATE . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return $json;\n        }\n        return false;\n    }\n\n    /**\n     * 更改卡券信息\n     * 调用该接口更新信息后会重新送审，卡券状态变更为待审核。已被用户领取的卡券会实时更新票面信息。\n     * @param string $data\n     * @return boolean\n     */\n    public function updateCard($data) {\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_UPDATE . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 删除卡券\n     * 允许商户删除任意一类卡券。删除卡券后，该卡券对应已生成的领取用二维码、添加到卡包 JS API 均会失效。\n     * 注意：删除卡券不能删除已被用户领取，保存在微信客户端中的卡券，已领取的卡券依旧有效。\n     * @param string $card_id 卡券ID\n     * @return boolean\n     */\n    public function delCard($card_id) {\n        $data = array(\n            'card_id' => $card_id,\n        );\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_DELETE . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 查询卡券详情\n     * @param string $card_id\n     * @return boolean|array    返回数组信息比较复杂，请参看卡券接口文档\n     */\n    public function getCardInfo($card_id) {\n        $data = array(\n            'card_id' => $card_id,\n        );\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_GET . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return $json;\n        }\n        return false;\n    }\n\n    /**\n     * 获取颜色列表\n\t * 获得卡券的最新颜色列表，用于创建卡券\n\t * @return boolean|array   返回数组请参看 微信卡券接口文档 的json格式\n     */\n    public function getCardColors() {\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_get(self::API_BASE_URL_PREFIX . self::CARD_GETCOLORS . 'access_token=' . $this->access_token);\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return $json;\n        }\n        return false;\n    }\n\n    /**\n     * 拉取门店列表\n\t * 获取在公众平台上申请创建的门店列表\n\t * @param int $offset  开始拉取的偏移，默认为0从头开始\n\t * @param int $count   拉取的数量，默认为0拉取全部\n\t * @return boolean|array   返回数组请参看 微信卡券接口文档 的json格式\n     */\n    public function getCardLocations($offset=0,$count=0) {\n\t    $data=array(\n\t    \t'offset'=>$offset,\n\t        'count'=>$count\n\t    );\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_LOCATION_BATCHGET . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return $json;\n        }\n        return false;\n    }\n\n    /**\n     * 批量导入门店信息\n\t * @tutorial 返回插入的门店id列表，以逗号分隔。如果有插入失败的，则为-1，请自行核查是哪个插入失败\n\t * @param array $data    数组形式的json数据，由于内容较多，具体内容格式请查看 微信卡券接口文档\n\t * @return boolean|string 成功返回插入的门店id列表\n     */\n    public function addCardLocations($data) {\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_LOCATION_BATCHADD . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return $json;\n        }\n        return false;\n    }\n\n    /**\n     * 生成卡券二维码\n\t * 成功则直接返回ticket值，可以用 getQRUrl($ticket) 换取二维码url\n\t *\n\t * @param string $cardid 卡券ID 必须\n\t * @param string $code 指定卡券 code 码，只能被领一次。use_custom_code 字段为 true 的卡券必须填写，非自定义 code 不必填写。\n\t * @param string $openid 指定领取者的 openid，只有该用户能领取。bind_openid 字段为 true 的卡券必须填写，非自定义 openid 不必填写。\n\t * @param int $expire_seconds 指定二维码的有效时间，范围是 60 ~ 1800 秒。不填默认为永久有效。\n\t * @param boolean $is_unique_code 指定下发二维码，生成的二维码随机分配一个 code，领取后不可再次扫描。填写 true 或 false。默认 false。\n\t * @param string $balance 红包余额，以分为单位。红包类型必填（LUCKY_MONEY），其他卡券类型不填。\n     * @return boolean|string\n     */\n    public function createCardQrcode($card_id,$code='',$openid='',$expire_seconds=0,$is_unique_code=false,$balance='') {\n        $card = array(\n                'card_id' => $card_id\n        );\n        if ($code)\n            $card['code'] = $code;\n        if ($openid)\n            $card['openid'] = $openid;\n        if ($expire_seconds)\n            $card['expire_seconds'] = $expire_seconds;\n        if ($is_unique_code)\n            $card['is_unique_code'] = $is_unique_code;\n        if ($balance)\n            $card['balance'] = $balance;\n        $data = array(\n            'action_name' => \"QR_CARD\",\n            'action_info' => array('card' => $card)\n        );\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_QRCODE_CREATE . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return $json;\n        }\n        return false;\n    }\n\n    /**\n     * 消耗 code\n     * 自定义 code（use_custom_code 为 true）的优惠券，在 code 被核销时，必须调用此接口。\n     *\n     * @param string $code 要消耗的序列号\n     * @param string $card_id 要消耗序列号所述的 card_id，创建卡券时use_custom_code 填写 true 时必填。\n     * @return boolean|array\n     * {\n     *  \"errcode\":0,\n     *  \"errmsg\":\"ok\",\n     *  \"card\":{\"card_id\":\"pFS7Fjg8kV1IdDz01r4SQwMkuCKc\"},\n     *  \"openid\":\"oFS7Fjl0WsZ9AMZqrI80nbIq8xrA\"\n     * }\n     */\n    public function consumeCardCode($code,$card_id='') {\n        $data = array('code' => $code);\n        if ($card_id)\n            $data['card_id'] = $card_id;\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_CODE_CONSUME . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return $json;\n        }\n        return false;\n    }\n\n    /**\n     * code 解码\n     * @param string $encrypt_code 通过 choose_card_info 获取的加密字符串\n     * @return boolean|array\n     * {\n     *  \"errcode\":0,\n     *  \"errmsg\":\"ok\",\n     *  \"code\":\"751234212312\"\n     *  }\n     */\n    public function decryptCardCode($encrypt_code) {\n        $data = array(\n            'encrypt_code' => $encrypt_code,\n        );\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_CODE_DECRYPT . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return $json;\n        }\n        return false;\n    }\n\n    /**\n     * 查询 code 的有效性（非自定义 code）\n     * @param string $code\n     * @return boolean|array\n     * {\n     *  \"errcode\":0,\n     *  \"errmsg\":\"ok\",\n     *  \"openid\":\"oFS7Fjl0WsZ9AMZqrI80nbIq8xrA\",    //用户 openid\n     *  \"card\":{\n     *      \"card_id\":\"pFS7Fjg8kV1IdDz01r4SQwMkuCKc\",\n     *      \"begin_time\": 1404205036,               //起始使用时间\n     *      \"end_time\": 1404205036,                 //结束时间\n     *  }\n     * }\n     */\n    public function checkCardCode($code) {\n        $data = array(\n            'code' => $code,\n        );\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_CODE_GET . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return $json;\n        }\n        return false;\n    }\n\n    /**\n     * 批量查询卡列表\n\t * @param $offset  开始拉取的偏移，默认为0从头开始\n\t * @param $count   需要查询的卡片的数量（数量最大50,默认50）\n     * @return boolean|array\n     * {\n     *  \"errcode\":0,\n     *  \"errmsg\":\"ok\",\n     *  \"card_id_list\":[\"ph_gmt7cUVrlRk8swPwx7aDyF-pg\"],    //卡 id 列表\n     *  \"total_num\":1                                       //该商户名下 card_id 总数\n     * }\n     */\n    public function getCardIdList($offset=0,$count=50) {\n        if ($count>50)\n            $count = 50;\n        $data = array(\n            'offset' => $offset,\n            'count'  => $count,\n        );\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_BATCHGET . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return $json;\n        }\n        return false;\n    }\n\n    /**\n     * 更改 code\n     * 为确保转赠后的安全性，微信允许自定义code的商户对已下发的code进行更改。\n     * 注：为避免用户疑惑，建议仅在发生转赠行为后（发生转赠后，微信会通过事件推送的方式告知商户被转赠的卡券code）对用户的code进行更改。\n     * @param string $code      卡券的 code 编码\n     * @param string $card_id   卡券 ID\n     * @param string $new_code  新的卡券 code 编码\n     * @return boolean\n     */\n    public function updateCardCode($code,$card_id,$new_code) {\n        $data = array(\n            'code' => $code,\n            'card_id' => $card_id,\n            'new_code' => $new_code,\n        );\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_CODE_UPDATE . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 设置卡券失效\n     * 设置卡券失效的操作不可逆\n     * @param string $code 需要设置为失效的 code\n     * @param string $card_id 自定义 code 的卡券必填。非自定义 code 的卡券不填。\n     * @return boolean\n     */\n    public function unavailableCardCode($code,$card_id='') {\n        $data = array(\n            'code' => $code,\n        );\n        if ($card_id)\n            $data['card_id'] = $card_id;\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_CODE_UNAVAILABLE . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 库存修改\n     * @param string $data\n     * @return boolean\n     */\n    public function modifyCardStock($data) {\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_MODIFY_STOCK . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 激活/绑定会员卡\n     * @param string $data 具体结构请参看卡券开发文档(6.1.1 激活/绑定会员卡)章节\n     * @return boolean\n     */\n    public function activateMemberCard($data) {\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_MEMBERCARD_ACTIVATE . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 会员卡交易\n     * 会员卡交易后每次积分及余额变更需通过接口通知微信，便于后续消息通知及其他扩展功能。\n     * @param string $data 具体结构请参看卡券开发文档(6.1.2 会员卡交易)章节\n     * @return boolean|array\n     */\n    public function updateMemberCard($data) {\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_MEMBERCARD_UPDATEUSER . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return $json;\n        }\n        return false;\n    }\n\n    /**\n     * 更新红包金额\n     * @param string $code      红包的序列号\n     * @param $balance          红包余额\n     * @param string $card_id   自定义 code 的卡券必填。非自定义 code 可不填。\n     * @return boolean|array\n     */\n    public function updateLuckyMoney($code,$balance,$card_id='') {\n        $data = array(\n                'code' => $code,\n                'balance' => $balance\n        );\n        if ($card_id)\n            $data['card_id'] = $card_id;\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_LUCKYMONEY_UPDATE . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * 设置卡券测试白名单\n     * @param string $openid    测试的 openid 列表\n     * @param string $user      测试的微信号列表\n     * @return boolean\n     */\n    public function setCardTestWhiteList($openid=array(),$user=array()) {\n        $data = array();\n        if (count($openid) > 0)\n            $data['openid'] = $openid;\n        if (count($user) > 0)\n            $data['username'] = $user;\n        if (!$this->access_token && !$this->checkAuth()) return false;\n        $result = $this->http_post(self::API_BASE_URL_PREFIX . self::CARD_TESTWHILELIST_SET . 'access_token=' . $this->access_token, self::json_encode($data));\n        if ($result) {\n            $json = json_decode($result, true);\n            if (!$json || !empty($json['errcode'])) {\n                $this->errCode = $json['errcode'];\n                $this->errMsg  = $json['errmsg'];\n                return false;\n            }\n            return true;\n        }\n        return false;\n    }\n\n}\n/**\n * PKCS7Encoder class\n *\n * 提供基于PKCS7算法的加解密接口.\n */\nclass PKCS7Encoder\n{\n    public static $block_size = 32;\n\n    /**\n     * 对需要加密的明文进行填充补位\n     * @param $text 需要进行填充补位操作的明文\n     * @return 补齐明文字符串\n     */\n    function encode($text)\n    {\n        $block_size = PKCS7Encoder::$block_size;\n        $text_length = strlen($text);\n        //计算需要填充的位数\n        $amount_to_pad = PKCS7Encoder::$block_size - ($text_length % PKCS7Encoder::$block_size);\n        if ($amount_to_pad == 0) {\n            $amount_to_pad = PKCS7Encoder::block_size;\n        }\n        //获得补位所用的字符\n        $pad_chr = chr($amount_to_pad);\n        $tmp = \"\";\n        for ($index = 0; $index < $amount_to_pad; $index++) {\n            $tmp .= $pad_chr;\n        }\n        return $text . $tmp;\n    }\n\n    /**\n     * 对解密后的明文进行补位删除\n     * @param decrypted 解密后的明文\n     * @return 删除填充补位后的明文\n     */\n    function decode($text)\n    {\n\n        $pad = ord(substr($text, -1));\n        if ($pad < 1 || $pad > PKCS7Encoder::$block_size) {\n            $pad = 0;\n        }\n        return substr($text, 0, (strlen($text) - $pad));\n    }\n\n}\n\n/**\n * Prpcrypt class\n *\n * 提供接收和推送给公众平台消息的加解密接口.\n */\nclass Prpcrypt\n{\n    public $key;\n\n    function __construct($k) {\n        $this->key = base64_decode($k . \"=\");\n    }\n\n    /**\n     * 兼容老版本php构造函数，不能在 __construct() 方法前边，否则报错\n     */\n    function Prpcrypt($k)\n    {\n        $this->key = base64_decode($k . \"=\");\n    }\n\n    /**\n     * 对明文进行加密\n     * @param string $text 需要加密的明文\n     * @return string 加密后的密文\n     */\n    public function encrypt($text, $appid)\n    {\n\n        try {\n            //获得16位随机字符串，填充到明文之前\n            $random = $this->getRandomStr();//\"aaaabbbbccccdddd\";\n            $text = $random . pack(\"N\", strlen($text)) . $text . $appid;\n            // 网络字节序\n            $size = mcrypt_get_block_size(MCRYPT_RIJNDAEL_128, MCRYPT_MODE_CBC);\n            $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');\n            $iv = substr($this->key, 0, 16);\n            //使用自定义的填充方式对明文进行补位填充\n            $pkc_encoder = new PKCS7Encoder;\n            $text = $pkc_encoder->encode($text);\n            mcrypt_generic_init($module, $this->key, $iv);\n            //加密\n            $encrypted = mcrypt_generic($module, $text);\n            mcrypt_generic_deinit($module);\n            mcrypt_module_close($module);\n\n            //\t\t\tprint(base64_encode($encrypted));\n            //使用BASE64对加密后的字符串进行编码\n            return array(ErrorCode::$OK, base64_encode($encrypted));\n        } catch (Exception $e) {\n            //print $e;\n            return array(ErrorCode::$EncryptAESError, null);\n        }\n    }\n\n    /**\n     * 对密文进行解密\n     * @param string $encrypted 需要解密的密文\n     * @return string 解密得到的明文\n     */\n    public function decrypt($encrypted, $appid)\n    {\n\n        try {\n            //使用BASE64对需要解密的字符串进行解码\n            $ciphertext_dec = base64_decode($encrypted);\n            $module = mcrypt_module_open(MCRYPT_RIJNDAEL_128, '', MCRYPT_MODE_CBC, '');\n            $iv = substr($this->key, 0, 16);\n            mcrypt_generic_init($module, $this->key, $iv);\n            //解密\n            $decrypted = mdecrypt_generic($module, $ciphertext_dec);\n            mcrypt_generic_deinit($module);\n            mcrypt_module_close($module);\n        } catch (Exception $e) {\n            return array(ErrorCode::$DecryptAESError, null);\n        }\n\n\n        try {\n            //去除补位字符\n            $pkc_encoder = new PKCS7Encoder;\n            $result = $pkc_encoder->decode($decrypted);\n            //去除16位随机字符串,网络字节序和AppId\n            if (strlen($result) < 16)\n                return \"\";\n            $content = substr($result, 16, strlen($result));\n            $len_list = unpack(\"N\", substr($content, 0, 4));\n            $xml_len = $len_list[1];\n            $xml_content = substr($content, 4, $xml_len);\n            $from_appid = substr($content, $xml_len + 4);\n            if (!$appid)\n                $appid = $from_appid;\n            //如果传入的appid是空的，则认为是订阅号，使用数据中提取出来的appid\n        } catch (Exception $e) {\n            //print $e;\n            return array(ErrorCode::$IllegalBuffer, null);\n        }\n        if ($from_appid != $appid)\n            return array(ErrorCode::$ValidateAppidError, null);\n        //不注释上边两行，避免传入appid是错误的情况\n        return array(0, $xml_content, $from_appid); //增加appid，为了解决后面加密回复消息的时候没有appid的订阅号会无法回复\n\n    }\n\n\n    /**\n     * 随机生成16位字符串\n     * @return string 生成的字符串\n     */\n    function getRandomStr()\n    {\n\n        $str = \"\";\n        $str_pol = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz\";\n        $max = strlen($str_pol) - 1;\n        for ($i = 0; $i < 16; $i++) {\n            $str .= $str_pol[mt_rand(0, $max)];\n        }\n        return $str;\n    }\n\n}\n\n/**\n * error code\n * 仅用作类内部使用，不用于官方API接口的errCode码\n */\nclass ErrorCode\n{\n    public static $OK = 0;\n    public static $ValidateSignatureError = 40001;\n    public static $ParseXmlError = 40002;\n    public static $ComputeSignatureError = 40003;\n    public static $IllegalAesKey = 40004;\n    public static $ValidateAppidError = 40005;\n    public static $EncryptAESError = 40006;\n    public static $DecryptAESError = 40007;\n    public static $IllegalBuffer = 40008;\n    public static $EncodeBase64Error = 40009;\n    public static $DecodeBase64Error = 40010;\n    public static $GenReturnXmlError = 40011;\n    public static $errCode=array(\n            '0' => '处理成功',\n            '40001' => '校验签名失败',\n            '40002' => '解析xml失败',\n            '40003' => '计算签名失败',\n            '40004' => '不合法的AESKey',\n            '40005' => '校验AppID失败',\n            '40006' => 'AES加密失败',\n            '40007' => 'AES解密失败',\n            '40008' => '公众平台发送的xml不合法',\n            '40009' => 'Base64编码失败',\n            '40010' => 'Base64解码失败',\n            '40011' => '公众帐号生成回包xml失败'\n    );\n    public static function getErrText($err) {\n        if (isset(self::$errCode[$err])) {\n            return self::$errCode[$err];\n        }else {\n            return false;\n        };\n    }\n}\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/wiki/%B5%C4%EA%B5%D8%E2%FE%D6+%DA%D6%E5%FE%A6+զ%F4.md",
    "content": "# wechatauth.class.php  \r\n\r\n**此扩展类库已经不再更新，原因是官方开放平台对网站应用开放的有授权登陆接口，更标准，更好用。请查看：[微信开放平台](http://open.weixin.qq.com)**  \r\n\r\n通过微信二维码登陆微信的API, 能实现第三方网站同步登陆, 首先程序分别通过get_login_code和get_code_image方法获取授权二维码图片, 然后利用微信手机客户端扫描二维码图片后将自动跳出授权页面, 用户点击授权后即可获取对应的用户资料和头像信息. 详细验证步骤请看test3.php例子.   \r\n\r\n## 类主要方法:\r\n *  get_login_code() 获取登陆授权码, 通过授权码才能获取二维码  \r\n *  get_code_image($code='') 将上面获取的授权码转换为图片二维码  \r\n *  verify_code() 鉴定是否登陆成功,返回200为最终授权成功.  \r\n *  get_login_info() 鉴定成功后调用此方法即可获取用户基本信息  \r\n *  get_avatar($url) 获取用户头像图片数据  \r\n *  logout() 注销登陆  \r\n\r\n## 微信二维码Wechatauth登陆示例: \r\n```php\r\n//test3.php\r\n\tinclude \"../wechatauth.class.php\";\r\n\tsession_start();\r\n\t$sid  = session_id();\r\n\t$options = array(\r\n\t\t'account'=>$sid,\r\n\t\t'datapath'=>'../data/cookiecode_',\r\n\t); \r\n\t$wechat = new Wechatauth($options);\r\n\t\r\n\tif (isset($_POST['code'])) {\r\n\t\t$logincode = $_POST['code'];\r\n\t\t$vres = $wechat->set_login_code($logincode)->verify_code();\r\n\t\tif ($vres===false) {\r\n\t\t\t$result = array('status'=>0);\r\n\t\t} else {\r\n\t\t\t$result = array('status'=>$vres);\r\n\t\t\tif ($vres==200) {\r\n\t\t\t\t$result['info'] = $wechat->get_login_info();\r\n\t\t\t\t$result['cookie'] = $wechat->get_login_cookie(true);\r\n\t\t\t}\r\n\t\t}\r\n\t\t\r\n\t\tdie(json_encode($result));\t\r\n\t}\r\n\t$logincode =  $wechat->get_login_code(); //获取授权码\r\n\t$qrimg = $wechat->get_code_image(); //待输出的二维码图片\r\n```\r\nHTML部分请看test/test3.php, 主要是定时ajax查询是否已经授权成功"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/wiki/%B5%F9%BA%FE%EB%EAե%AB%F5+%ED%B5%F6%BB%F5+V2%B5%C4%D1%D5%C5%FA%FE%A6+զ%F4.md",
    "content": "# wechatpay.class.php \r\n\r\n旧版微信支付类库(微信支付V2)，已移动至old_version目录下。  \r\n自2014年8月开始申请到的微信支付都是V3接口，据官方说V2的会陆续升级为V3接口，但时间及升级渠道未确认。\r\n\r\n### 主要功能 \r\n- 获取access_token **（初级权限）**\r\n- 调用地址组件 **（支付权限）**\r\n- 生成订单签名数据 **（支付权限）**\r\n- 订单成功回调 **（支付权限）**\r\n- 发货通知 **（支付权限）**\r\n- 支付订单查询 **（支付权限）**  \r\n> 备注：  \r\n> 初级权限：基本权限，任何正常的公众号都有此权限  \r\n> 菜单权限：正常的服务号、认证后的订阅号拥有此权限  \r\n> 认证权限：分为订阅号、服务号认证，如前缀服务号则仅认证的服务号有此权限，否则为认证后的订阅号、服务号都有此权限  \r\n> 支付权限：仅认证后的服务号可以申请此权限  \r\n\r\n\r\n### 初始化动作 \r\n```php\r\n $options = array(\r\n\t'appid'=>'wxdk1234567890', //填写高级调用功能的app id, 请在微信开发模式后台查询\r\n\t'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥\r\n\t'partnerid'=>'88888888', //财付通商户身份标识，支付权限专用，没有可不填\r\n\t'partnerkey'=>'', //财付通商户权限密钥Key，支付权限专用\r\n\t'paysignkey'=>'' //商户签名密钥Key，支付权限专用\r\n\t);\r\n $weObj = new Wechat($options); //创建实例对象\r\n //TODO：调用$weObj各实例方法\r\n```\r\n\r\n### 主动接口方法:   \r\n *  checkAuth($appid='',$appsecret='',$token='') 获取access_token。可根据appid和appsecret获取，或手动指定access_token\r\n *  resetAuth($appid='') 删除验证数据\r\n *  getSignature($arrdata,'sha1') 生成签名字串  \r\n *  generateNonceStr($length=16) 获取随机字串  \r\n *  createNativeUrl($productid) 生成原生支付url\r\n *  createPackage($out_trade_no,$body,$total_fee,$notify_url,$spbill_create_ip,$fee_type=1,$bank_type=\"WX\",$input_charset=\"UTF-8\",$time_start=\"\",$time_expire=\"\",$transport_fee=\"\",$product_fee=\"\",$goods_tag=\"\",$attach=\"\") 生成订单package字符串  \r\n *  getPaySign($package, $timeStamp, $nonceStr) 支付签名(paySign)生成方法  \r\n *  checkOrderSignature($orderxml='') 回调通知签名验证  \r\n *  sendPayDeliverNotify($openid,$transid,$out_trade_no,$status=1,$msg='ok') 发货通知  \r\n *  getPayOrder($out_trade_no) 查询订单信息  \r\n *  setUserToken($user_token) 设置用户授权密钥\r\n *  getAddrSign($url, $timeStamp, $nonceStr, $user_token='') 获取收货地址JS的签名"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/wiki/%D5%E5%E0%D5%C1%EEJS.md",
    "content": "#wechat.js\r\n\r\n**此JS脚本已经废弃不再更新，原因是官方在微信6.0.2版本开放了全新的JSAPI接口，更全面好用。请查看：[微信公众平台WIKI](http://mp.weixin.qq.com/wiki)**\r\n\r\n##微信内嵌网页特殊功能js调用：\r\n * WeixinJS.hideOptionMenu() 隐藏右上角按钮\r\n * WeixinJS.showOptionMenu() 显示右上角按钮\r\n * WeixinJS.hideToolbar() 隐藏工具栏\r\n * WeixinJS.showToolbar() 显示工具栏\r\n * WeixinJS.getNetworkType() 获取网络状态\r\n * WeixinJS.closeWindow() 关闭窗口\r\n * WeixinJS.scanQRCode() 扫描二维码\r\n * WeixinJS.openUrlByExtBrowser(url) 使用浏览器打开网址\r\n * WeixinJS.jumpToBizProfile(username) 跳转到指定公众账号页面\r\n * WeixinJS.sendEmail(title,content) 发送邮件\r\n * WeixinJS.openProductView(latitude,longitude,name,address,scale,infoUrl) 查看地图\r\n * WeixinJS.addContact(username) 添加微信账号\r\n * WeixinJS.imagePreview(urls,current) 调出微信内图片预览\r\n * WeixinJS.payCallback(appId,package,timeStamp,nonceStr,signType,paySign,callback) 微信JsApi支付接口\r\n * WeixinJS.editAddress(appId,addrSign,timeStamp,nonceStr,callback) 微信JsApi支付接口\r\n * 通过定义全局变量dataForWeixin配置触发分享的内容：\r\n\r\n ```javascript\r\n var dataForWeixin={\r\n\t   appId:\"\",\r\n\t   MsgImg:\"消息图片路径\",\r\n\t   TLImg:\"时间线图路径\",\r\n\t   url:\"分享url路径\",\r\n\t   title:\"标题\",\r\n\t   desc:\"描述\",\r\n\t   fakeid:\"\",\r\n\t   callback:function(){}\r\n\t};\r\n ```\r\n可以参考weshare.html及wechat.js的备注进行使用"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/wiki/%DA%D8%D7ի%B5%FB%A6%B5%EB%AEզ%F2%FE%A6+զ%F4.md",
    "content": "# wechatext.class.php\r\n\r\n**此扩展类库已经不再更新，原因是官方对公众号开放了众多接口，此类库继续维护的意义不大**  \r\n\r\n非官方扩展API，需要配置公众平台账户和密码，能实现对已关注用户的点对点微信，此方式不保证长期有效。  \r\n类方法里提及的用户id在接口返回结构里表述为FakeId, 属同一概念, 在下面wechatauth类里则表示为Uin, 用户id对应的微信号必须通过getInfo()方法通过返回数组的Username值获取, 但非关注关系用户资料不能获取.  \r\n调用下列方法前必须经过login()方法和checkValid()验证方法才能获得调用权限. 有的账户无法通过登陆可能因为要求提供验证码, 可以手动登陆后把获取到的cookie写进程序存放cookie的文件解决.  \r\n程序使用了经过修改的snoopy兼容式HTTP类方法, 在类似BAE/SAE云服务器上可能不能正常运行, 因为云服务的curl方法是经过重写的, 某些header参数如网站来源参数不被支持.  \r\n\r\n## 类主要方法:\r\n *  send($id,$content) 向某用户id发送微信文字信息 \r\n *  sendNews($id,$msgid) 发送图文消息, 可通过getNewsList获取$msgid\r\n *  getUserList($page,$pagesize,$groupid) 获取用户信息\r\n *  getGroupList($page,$pagesize) 获取群组信息\r\n *  getNewsList($page,$pagesize) 获取图文信息列表 \r\n *  uploadFile($filepath,$type) 上传附件,包括图片/音频/视频/缩略图\r\n *  getFileList($type,$page,$pagesize) 获取素材库文件列表\r\n *  sendImage($id,$fid) 发送图片消息\r\n *  sendAudio($id,$fid) 发送音频消息\r\n *  sendVideo($id,$fid) 发送视频消息 \r\n *  getInfo($id) 根据id获取用户资料,注: 非关注关系用户资料不能获取  \r\n *  getNewMsgNum($lastid) 获取从$lastid算起新消息的数目  \r\n *  getTopMsg() 获取最新一条消息的数据, 此方法获取的消息id可以作为检测新消息的$lastid依据  \r\n *  getMsg($lastid,$offset=0,$perpage=50,$day=0,$today=0,$star=0) 获取最新的消息列表, 列表将返回消息id, 用户id, 消息类型, 文字消息等参数  \r\n *  消息返回结构:  {\"id\":\"消息id\",\"type\":\"类型号(1为文字,2为图片,3为语音)\",\"fileId\":\"0\",\"hasReply\":\"0\",\"fakeId\":\"用户uid\",\"nickName\":\"昵称\",\"dateTime\":\"时间戳\",\"content\":\"文字内容\"}   \r\n *  getMsgImage($msgid,$mode='large') 若消息type类型为2, 调用此方法获取图片数据  \r\n *  getMsgVoice($msgid) 若消息type类型为3, 调用此方法获取语音数据  \r\n\r\n\r\n## 扩展包Wechatext调用示例:\r\n```php\r\n//test2.php \r\n\tinclude \"wechatext.class.php\";\r\n\t\r\n\tfunction logdebug($text){\r\n\t\tfile_put_contents('./data/log.txt',$text.\"\\n\",FILE_APPEND);\t\t\r\n\t};\r\n\t\r\n\t$options = array(\r\n\t\t'account'=>'demo@domain.com',\r\n\t\t'password'=>'demo',\r\n\t\t'datapath'=>'./data/cookie_',\r\n\t\t\t'debug'=>true,\r\n\t\t\t'logcallback'=>'logdebug'\t\r\n\t); \r\n\t$wechat = new Wechatext($options);\r\n\tif ($wechat->checkValid()) {\r\n\t\t// 获取用户信息\r\n\t\t$data = $wechat->getInfo('3974255');\r\n\t\tvar_dump($data);\r\n\t\t// 获取最新一条消息\r\n\t\t$topmsg = $wechat->getTopMsg();\r\n\t\tvar_dump($topmsg);\r\n\t\t// 主动回复消息\r\n\t\tif ($topmsg && $topmsg['has_reply']==0)\r\n\t\t$wechat->send($topmsg['fakeid'],'hi '.$topmsg['nick_name'].',rev:'.$topmsg['content']);\t\r\n\t}\r\n```"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/wiki/%F5%A9%A6%D5+%C7%D5%C5%E6%B5%ED%E5%B5%D7%C2%DE+%F8%DE%ED%EE%DA%C7%E9%DA%E0%EC.md",
    "content": "#为开发框架进行适配\r\n\r\n为不同的开发框架进行适配缓存操作(保存access_token、jsapi_ticket)，及输出调试日志。\r\n\r\n由于微信api需要缓存access_token与jsapi_ticket，而在不同框架下的缓存方式不同，所以原先在Wechat.class.php和QYWechat.class.php中缓存代码做了TODO标志。\r\n需要各位在使用不同框架时再进行修改，但确实很麻烦，因为对结构进行了修改。\r\n\r\n>取消了原先同步维护的Thinkphp版本，为Wechat类增加操作缓存3个重载方法`setCache`, `getCache`, `removeCache`，以及修改`log`方法可以重载。\r\n>分别来实现在不同开发框架下的设置缓存、读取缓存、清除缓存、日志输出4个功能。  \r\n\r\n在不同的开发框架下使用Wechat类库，请继承Wechat类，根据需要实现这4个方法。  \r\n可参考Thinkphp版的`TPWechat.class.php`为不同框架进行适配。\r\n欢迎提交其他框架的适配文件到项目库来。  \r\n\r\n为Thinkphp进行适配的示例如下：\r\n```php\r\n/**\r\n *\t微信公众平台PHP-SDK, ThinkPHP实例\r\n *  @author dodgepudding@gmail.com\r\n *  @link https://github.com/dodgepudding/wechat-php-sdk\r\n *  @version 1.2\r\n *  usage:\r\n *   $options = array(\r\n *\t\t\t'token'=>'tokenaccesskey', //填写你设定的key\r\n *\t\t\t'encodingaeskey'=>'encodingaeskey', //填写加密用的EncodingAESKey\r\n *\t\t\t'appid'=>'wxdk1234567890', //填写高级调用功能的app id\r\n *\t\t\t'appsecret'=>'xxxxxxxxxxxxxxxxxxx' //填写高级调用功能的密钥\r\n *\t\t);\r\n *\t $weObj = new TPWechat($options);\r\n *   $weObj->valid();\r\n *   ...\r\n *  \r\n */\r\nclass TPWechat extends Wechat\r\n{\r\n\t/**\r\n\t * log overwrite\r\n\t * @see Wechat::log()\r\n\t */\r\n\tprotected function log($log){\r\n\t\tif ($this->debug) {\r\n\t\t\tif (function_exists($this->logcallback)) {\r\n\t\t\t\tif (is_array($log)) $log = print_r($log,true);\r\n\t\t\t\treturn call_user_func($this->logcallback,$log);\r\n\t\t\t}elseif (class_exists('Log')) {\r\n\t\t\t\tLog::write('wechat：'.$log, Log::DEBUG);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\t\r\n\t/**\r\n\t * 重载设置缓存\r\n\t * @param string $cachename\r\n\t * @param mixed $value\r\n\t * @param int $expired\r\n\t * @return boolean\r\n\t */\r\n\tprotected function setCache($cachename,$value,$expired){\r\n\t\treturn S($cachename,$value,$expired);\r\n\t}\r\n\t\r\n\t/**\r\n\t * 重载获取缓存\r\n\t * @param string $cachename\r\n\t * @return mixed\r\n\t */\r\n\tprotected function getCache($cachename){\r\n\t\treturn S($cachename);\r\n\t}\r\n\t\r\n\t/**\r\n\t * 重载清除缓存\r\n\t * @param string $cachename\r\n\t * @return boolean\r\n\t */\r\n\tprotected function removeCache($cachename){\r\n\t\treturn S($cachename,null);\r\n\t}\r\n}\r\n```"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/wiki/%F5+%FC%F5%A9%DC%D5%C5%C0API%FE%A6+զ%F4.md",
    "content": "# qywechat.class.php\r\n\r\n## 企业号API类库\r\n调用官方API，具有更灵活的消息分类响应方式，支持链式调用操作 ； \r\n\r\n## 主要功能 \r\n- 接入验证\r\n- 自动回复（文本、图片、语音、视频、音乐、图文）\r\n- 菜单操作（查询、创建、删除）\r\n- 部门管理（创建、更新、删除、获取部门列表）\r\n- 成员管理（创建、更新、删除、获取成员信息，获取部门成员列表）\r\n- 标签管理（创建、更新、删除、获取成员、添加成员、删除成员,获取标签列表）\r\n- 媒体文件管理（上传、获取）\r\n- 二次验证\r\n- OAuth2（生成授权url、获取成员信息）\r\n- 获取企业微信服务器IP列表\r\n- 微信JSAPI授权(获取ticket、获取签名)\r\n\r\n\r\n## 初始化动作 \r\n```php\r\n$options = array(\r\n  'token'=>'tokenaccesskey', //填写应用接口的Token\r\n  'encodingaeskey'=>'encodingaeskey', //填写加密用的EncodingAESKey\r\n  'appid'=>'wxdk1234567890', //填写高级调用功能的app id\r\n  'appsecret'=>'xxxxxxxxxxxxxxxxxxx', //填写高级调用功能的密钥\r\n  'agentid'=>'1', //应用的id\r\n  'debug'=>false, //调试开关\r\n  '_logcallback'=>'logg', //调试输出方法，需要有一个string类型的参数\r\n);\r\n $weObj = new Wechat($options); //创建实例对象\r\n //TODO：调用$weObj各实例方法\r\n\r\n```\r\n\r\n## 被动接口方法:   \r\n* valid() 验证连接，被动接口必须调用\r\n* \r\n* getRev() 获取微信服务器发来信息(不返回结果)，被动接口必须调用\r\n* getRevData() 返回微信服务器发来的信息（数组）\r\n* getRevPostXml() 返回微信服务器发来的原始加密xml信息\r\n* getRevFrom()  返回消息发送者的userid\r\n* getRevTo()  返回消息接收者的id（即公众号id，一般与等同appid一致）\r\n* getRevAgentID() 返回接收消息的应用id\r\n* getRevType() 返回接收消息的类型\r\n* getRevID() 返回消息id\r\n* getRevCtime() 返回消息发送事件\r\n* getRevContent() 返回消息内容正文（文本型消息）\r\n* getRevPic() 返回图片信息（图片型信息） 返回数组{'mediaid'=>'','picurl'=>''}\r\n* getRevGeo() 返回地理位置（位置型信息） 返回数组{'x'=>'','y'=>'','scale'=>'','label'=>''}\r\n* getRevEventGeo() 返回事件地理位置（事件型信息） 返回数组{'x'=>'','y'=>'','precision'=>''}\r\n* getRevEvent() 返回事件类型（事件型信息） 返回数组{'event'=>'','key'=>''}\r\n* getRevScanInfo() 获取自定义菜单的扫码推事件信息，事件类型为`scancode_push`或`scancode_waitmsg` 返回数组array ('ScanType'=>'qrcode','ScanResult'=>'123123')\r\n* getRevSendPicsInfo() 获取自定义菜单的图片发送事件信息,事件类型为`pic_sysphoto`或`pic_photo_or_album`或`pic_weixin` 数组结构见php文件内方法说明\r\n* getRevSendGeoInfo() 获取自定义菜单的地理位置选择器事件推送，事件类型为`location_select` 数组结构见php文件内方法说明\r\n* getRevVoice() 返回语音信息（语音型信息） 返回数组{'mediaid'=>'','format'=>''}\r\n* getRevVideo() 返回视频信息（视频型信息） 返回数组{'mediaid'=>'','thumbmediaid'=>''}\r\n* \r\n* text($text) 设置文本型消息，参数：文本内容\r\n* image($mediaid) 设置图片型消息，参数：图片的media_id\r\n* voice($mediaid) 设置语音型消息，参数：语音的media_id\r\n* video($mediaid='',$title,$description) 设置视频型消息，参数：视频的media_id、标题、摘要\r\n* news($newsData) 设置图文型消息，参数：数组。数组结构见php文件内方法说明\r\n* image($mediaid) 设置图片型消息，参数：图片的media_id\r\n* Message($msg = '',$append = false) 设置发送的消息（一般不需要调用这个方法）\r\n* reply() 将已经设置好的消息，回复给微信服务器\r\n  \r\n### 预定义常量列表：\r\n```php\r\n////消息类型，使用实例调用getRevType()方法取得\r\n    const MSGTYPE_TEXT = 'text';\r\n    const MSGTYPE_IMAGE = 'image';\r\n    const MSGTYPE_LOCATION = 'location';\r\n    const MSGTYPE_LINK = 'link';    //暂不支持\r\n    const MSGTYPE_EVENT = 'event';\r\n    const MSGTYPE_MUSIC = 'music';    //暂不支持\r\n    const MSGTYPE_NEWS = 'news';\r\n    const MSGTYPE_VOICE = 'voice';\r\n    const MSGTYPE_VIDEO = 'video';\r\n////事件类型，使用实例调用getRevEvent()方法取得\r\n    const EVENT_SUBSCRIBE = 'subscribe';       //订阅\r\n    const EVENT_UNSUBSCRIBE = 'unsubscribe';   //取消订阅\r\n    const EVENT_LOCATION = 'LOCATION';         //上报地理位置\r\n    const EVENT_ENTER_AGENT = 'enter_agent';   //用户进入应用\r\n    const EVENT_MENU_VIEW = 'VIEW';                     //菜单 - 点击菜单跳转链接\r\n    const EVENT_MENU_CLICK = 'CLICK';                   //菜单 - 点击菜单拉取消息\r\n    const EVENT_MENU_SCAN_PUSH = 'scancode_push';       //菜单 - 扫码推事件(客户端跳URL)\r\n    const EVENT_MENU_SCAN_WAITMSG = 'scancode_waitmsg'; //菜单 - 扫码推事件(客户端不跳URL)\r\n    const EVENT_MENU_PIC_SYS = 'pic_sysphoto';          //菜单 - 弹出系统拍照发图\r\n    const EVENT_MENU_PIC_PHOTO = 'pic_photo_or_album';  //菜单 - 弹出拍照或者相册发图\r\n    const EVENT_MENU_PIC_WEIXIN = 'pic_weixin';         //菜单 - 弹出微信相册发图器\r\n    const EVENT_MENU_LOCATION = 'location_select';      //菜单 - 弹出地理位置选择器\r\n    const EVENT_SEND_MASS = 'MASSSENDJOBFINISH';        //发送结果 - 高级群发完成\r\n    const EVENT_SEND_TEMPLATE = 'TEMPLATESENDJOBFINISH';//发送结果 - 模板消息发送结果\r\n```\r\n\r\n## 主动接口方法：\r\n* checkAuth($appid='',$appsecret='',$token='') 通用auth验证方法,也用来换取ACCESS_TOKEN 。仅在需要手动指定access_token时才用`$token`\r\n* resetAuth($appid='') 清除记录的ACCESS_TOKEN\r\n* resetJsTicket($appid='') 删除JSAPI授权TICKET\r\n* getJsTicket($appid='',$jsapi_ticket='') 获取JSAPI授权TICKET\r\n* getJsSign($url, $timestamp=0, $noncestr='', $appid='') 获取JsApi使用签名信息数组，可只提供url地址 \r\n* getSignature($arrdata,'sha1') 生成签名字串  \r\n* generateNonceStr($length=16) 获取随机字串  \r\n* createMenu($data,$agentid='') 创建菜单,参数:菜单内容数组,要创建菜单应用id\r\n* getMenu($agentid='') 获取菜单内容,参数:要获取菜单内容的应用id\r\n* deleteMenu($agentid='') 删除菜单,参数:要删除菜单的应用id\r\n* uploadMedia($data, $type) 上传媒体文件,参数请看php文件内方法说明(注意上传大文件时可能需要先调用 set_time_limit(0) 避免超时)\r\n* getMedia($media_id) 根据媒体文件ID获取媒体文件,参数:媒体id\r\n* getServerIp() 获取企业微信服务器IP地址列表 返回数组array('127.0.0.1','127.0.0.1')\r\n* createDepartment($data) 创建部门,参数: array(\"name\"=>\"邮箱产品组\",\"parentid\"=>\"1\",\"order\" =>  \"1\")\r\n* updateDepartment($data) 更新部门,参数: array(\"id\"=>\"1\"，\"name\"=>\"邮箱产品组\",\"parentid\"=>\"1\",\"order\" =>  \"1\")\r\n* deleteDepartment($id) 删除部门,参数：要删除的部门id\r\n* moveDepartment($data) 移动部门,参数：array(\"department_id\" => \"5\",\"to_parentid\" => \"2\",\"to_position\" => \"1\")\r\n* getDepartment() 获取部门列表，返回部门数组。其中department部门列表数据。以部门的order字段从小到大排列\r\n* createUser($data) 创建成员，参数请看php文件内方法说明\r\n* updateUser($data) 更新成员，参数请看php文件内方法说明\r\n* deleteUser($userid) 删除成员，参数：员工UserID\r\n* deleteUsers($userids) 批量删除成员，参数：员工UserID数组\r\n* getUserInfo($userid) 获取成员信息，参数：员工UserID\r\n* getUserList($department_id,$fetch_child=0,$status=0) 获取部门成员，参数：部门id，是否递归获取子部门，获取类型。\r\n> 0获取全部员工，1获取已关注成员列表，2获取禁用成员列表，4获取未关注成员列表。status可叠加\r\n* getUserListInfo($department_id,$fetch_child=0,$status=0) 获取部门成员详情，参数同上\r\n* getUserId($code,$agentid) 根据code获取员工UserID与手机设备号，参数：Oauth2.0或者二次验证返回的code值，跳转链接时所在的企业应用ID\r\n* sendInvite($userid,$invite_tips='') 邀请成员关注\r\n* createTag($data) 创建标签，参数：array(\"tagname\" => \"UI\")\r\n* updateTag($data) 更新标签，参数：array(\"tagid\" => \"1\",\"tagname\" => \"UI\")\r\n* deleteTag($tagid) 删除标签，参数：标签TagID\r\n* getTag($tagid) 获取标签成员，参数：标签TagID\r\n* addTagUser($data) 增加标签成员，参数请看php文件内方法说明\r\n* delTagUser($data) 删除标签成员，参数请看php文件内方法说明\r\n* getTagList() 获取标签列表，返回标签数组\r\n* sendMessage($data) 主动发送信息接口，参数请看php文件内方法说明\r\n* authSucc($userid) 二次验证，参数： 员工UserID\r\n* getOauthRedirect($callback,$state='STATE',$scope='snsapi_base') 组合授权跳转接口url\r\n\r\n\r\n\r\n\r\n\r\n\r\n## 企业号API类库调用示例：\r\n-------- \r\n可参考**test**目录下的**qydemo.php**\r\n```php\r\ninclude \"wechat.class.php\";\r\n$options = array(\r\n        'token'=>'9Ixxxxxxx',\t//填写应用接口的Token\r\n        'encodingaeskey'=>'d4o9WVg8sxxxxxxxxxxxxxxxxxxxxxx',//填写加密用的EncodingAESKey\r\n        'appid'=>'wxa07979baxxxxxxxx',\t//填写高级调用功能的appid\r\n);\r\n$weObj = new Wechat($options);\r\n$weObj->valid(); //注意, 企业号与普通公众号不同，必须打开验证，不要注释掉\r\n$type = $weObj->getRev()->getRevType();\r\nswitch($type) {\r\n\tcase Wechat::MSGTYPE_TEXT:\r\n\t\t\t$weObj->text(\"hello, I'm wechat\")->reply();\r\n\t\t\texit;\r\n\t\t\tbreak;\r\n\tcase Wechat::MSGTYPE_EVENT:\r\n\t\t\tbreak;\r\n\tcase Wechat::MSGTYPE_IMAGE:\r\n\t\t\tbreak;\r\n\tdefault:\r\n\t\t\t$weObj->text(\"help info\")->reply();\r\n}\r\n```\r\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/wiki/API%B5%C4%D1%D5%C5%FA%DA%F6%D6޻%BB%FE%E1%FC.md",
    "content": "## errCode.php\r\n### 关于API接口错误码有两个版本：\r\n**一个是普通公众号平台的errCode.php；\r\n一个是企业号平台的 qyerrCode.php\r\n用法都是一样的。**\r\n\r\n当调用API接口失败时，可以用此类来换取失败原因的中文说明。\r\n\r\n使用方法：\r\n```php\r\ninclude \"errCode.php\";  //或 qyerrCode.php\r\n\r\n$ret=ErrCode::getErrText(48001); //错误码可以通过公众号类库的公开变量errCode得到\r\n\r\nif ($ret) \r\n\techo $ret;\r\nelse \r\n    echo \"未找到对应的内容\";\r\n\r\n```"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/wiki/Home.md",
    "content": "# wechat-php-sdk\r\n\r\n微信公众平台php开发包,细化各项接口操作,支持链式调用  \r\n项目地址：**https://github.com/dodgepudding/wechat-php-sdk**  \r\n项目wiki：**http://binsee.github.io/wechat-php-sdk**  \r\n\r\n----\r\n\r\n## 使用详解\r\n使用前需先打开微信帐号的开发模式，详细步骤请查看微信公众平台接口使用说明：  \r\n微信公众平台： http://mp.weixin.qq.com/wiki/\r\n微信企业平台： http://qydev.weixin.qq.com/wiki/\r\n\r\n微信支付接入文档：https://mp.weixin.qq.com/cgi-bin/readtemplate?t=business/course2_tmpl\r\n\r\n微信多客服：http://dkf.qq.com\r\n\r\n## 功能目录\r\n\r\n - [[官方API类库]]\r\n    > wechat.class.php\r\n    > 调用官方API，具有更灵活的消息分类响应方式，支持链式调用操作 ；\r\n\r\n - [[企业号API类库]]\r\n    > qywechat.class.php\r\n    > 微信公众平台企业号PHP-SDK\r\n    > 调用官方API，具有更灵活的消息分类响应方式，支持链式调用操作 ；\r\n\r\n - [[API接口错误码]]\r\n    > errCode.php 或 qyerrCode.php\r\n    > 当调用API接口失败时，可以用此类来换取失败原因的中文说明。\r\n\r\n - [[旧版微信支付V2接口类库]]\r\n    > old_version/wechatpay.class.php\r\n    > 当调用API接口失败时，可以用此类来换取失败原因的中文说明。\r\n\r\n - ~~[[非官方扩展类库]]~~*(停止维护)*\r\n    > old_version/wechatext.class.php\r\n    > 非官方扩展API，模拟人工操作微信平台，此方式不保证长期有效。  \r\n\r\n - ~~[[授权登陆类库]]~~*(停止维护)*\r\n    > old_version/wechatauth.class.php\r\n    > 通过微信二维码登陆微信的API, 能实现第三方网站同步登陆\r\n\r\n - ~~[[内嵌JS]]~~*(已废弃)*\r\n    > old_version/wechat.js\r\n    > 微信内嵌网页功能调用js\r\n\r\n - [[为开发框架进行适配]]\r\n    > 为不同的开发框架进行适配缓存操作(保存access_token、jsapi_ticket)，及输出调试日志。\r\n\r\n\r\n\r\n"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/wiki/README.md",
    "content": "wiki目录说明\r\n==============\r\n这个目录是wechat-php-sdk项目的wiki文档\r\nMake By：binsee\r\n\r\n##说明 \r\n**这里的wiki文档可以让你更好的了解`wechat-php-sdk`项目，更好的使用。 **\r\n\r\n**欢迎对wiki文档内容进行补充，把`wechat-php-sdk`项目变得更清晰易懂。**\r\n\r\n##为你的github生成wiki\r\n**如果你在github上fork了`wechat-php-sdk`项目，而且想为项目生成wiki，可以用这里的文件来生成。**\r\n\r\n\r\n###使用步骤：\r\n1. 在你的github上，fork或者创建`wechat-php-sdk`项目\r\n\r\n2. 激活项目wiki，已激活的请跳过\r\n```\r\n进入项目的设置页面：\r\nhttps://github.com/你的用户名/wechat-php-sdk/settings\r\n找到Features一栏，把 Wikis 选项打钩，就可以激活你项目的wiki了\r\n```\r\n\r\n3. 进入项目的wiki页面：\r\n`https://github.com/你的用户名/wechat-php-sdk/wiki`\r\n\r\n4. 点绿色的 `Create the first page` 按钮\r\n\r\n5. 直接到下方点 `Save Page` 按钮\r\n\r\n6. 在右边找到 `Clone this wiki locally` 一栏，复制git地址：\r\n`git@github.com:你的用户名/wechat-php-sdk.wiki.git`\r\n\r\n7. 在项目的上一层目录执行 \r\n`git clone git@github.com:你的用户名/wechat-php-sdk.wiki.git`\r\n\r\n8. 进入新出现的 `wechat-php-sdk.wiki` 目录，把wiki目录下的文件都复制过来\r\n> **这里有个高级用法，就是使用连接方式把wiki目录链接过来，而不是复制**\r\n> windows下的用法:\r\n```\r\n#如项目目录为：E:\\wechat-php-sdk\\\r\n#项目wiki目录为:E:\\wechat-php-sdk.wiki\\\r\n执行命令：\r\nmklink /j E:\\wechat-php-sdk.wiki\\wiki E:\\wechat-php-sdk\\wiki\r\n```\r\n> 这样的话，两个目录就会被联接到一起。\r\n> 以后进行更改wiki在哪个目录都行，另一个目录都是同步的。\r\n> 分别在 项目目录 和 项目wiki目录 进行git提交就可以了。\r\n\r\n9. 然后直接缓存上传即可。\r\n\r\n10. 现在去你github上项目的wiki目录里看一下吧\r\n\r\n\r\n##生成page\r\n**你也可以将wiki文档，生成为个人站点，会更加直观。**\r\n\r\n**比如使用 Hexo 或者其他的框架之类。**\r\n\r\n**这块的话，请自行搜索相关资料。**"
  },
  {
    "path": "vendor/dodgepudding/wechat-php-sdk/wiki/ի%B5%FB%A6API%FE%A6+զ%F4.md",
    "content": "# wechat.class.php\r\n\r\n调用官方API，具有更灵活的消息分类响应方式，支持链式调用操作 ； \r\n\r\n## 主要功能 \r\n- 接入验证 **（初级权限）**\r\n- 自动回复（文本、图片、语音、视频、音乐、图文） **（初级权限）**\r\n- 菜单操作（查询、创建、删除） **（菜单权限）**\r\n- 客服消息（文本、图片、语音、视频、音乐、图文） **（认证权限）**\r\n- 二维码（创建临时、永久二维码，获取二维码URL） **（服务号、认证权限）**\r\n- 长链接转短链接接口 **（服务号、认证权限）**\r\n- 分组操作（查询、创建、修改、移动用户到分组） **（认证权限）**\r\n- 网页授权（基本授权，用户信息授权） **（服务号、认证权限）**\r\n- 用户信息（查询用户基本信息、获取关注者列表） **（认证权限）**\r\n- 多客服功能（客服管理、获取客服记录、客服会话管理） **（认证权限）**\r\n- 媒体文件（上传、获取） **（认证权限）**\r\n- 高级群发 **（认证权限）**\r\n- 模板消息（设置所属行业、添加模板、发送模板消息） **（服务号、认证权限）**\r\n- 卡券管理（创建、修改、删除、发放、门店管理等） **（认证权限）**\r\n- 语义理解 **（服务号、认证权限）**\r\n- 获取微信服务器IP列表 **（初级权限）**  \r\n- 微信JSAPI授权(获取ticket、获取签名) **（初级权限）**  \r\n- 数据统计(用户、图文、消息、接口分析数据) **（认证权限）**  \r\n> 备注：  \r\n> 初级权限：基本权限，任何正常的公众号都有此权限  \r\n> 菜单权限：正常的服务号、认证后的订阅号拥有此权限  \r\n> 认证权限：分为订阅号、服务号认证，如前缀服务号则仅认证的服务号有此权限，否则为认证后的订阅号、服务号都有此权限  \r\n> 支付权限：仅认证后的服务号可以申请此权限  \r\n\r\n\r\n## 初始化动作 \r\n```php\r\n $options = array(\r\n\t'token'=>'tokenaccesskey', //填写你设定的key\r\n\t'encodingaeskey'=>'encodingaeskey', //填写加密用的EncodingAESKey\r\n\t'appid'=>'wxdk1234567890', //填写高级调用功能的app id, 请在微信开发模式后台查询\r\n\t'appsecret'=>'xxxxxxxxxxxxxxxxxxx' //填写高级调用功能的密钥\r\n\t);\r\n $weObj = new Wechat($options); //创建实例对象\r\n //TODO：调用$weObj各实例方法\r\n```\r\n\r\n### 被动接口方法:   \r\n* valid() 验证连接，被动接口处于加密模式时必须调用\r\n* \r\n* getRev() 获取微信服务器发来信息(不返回结果)，被动接口必须调用\r\n* getRevData() 返回微信服务器发来的信息（数组）\r\n* getRevFrom()  返回消息发送者的userid\r\n* getRevTo()  返回消息接收者的id（即公众号id）\r\n* getRevType() 返回接收消息的类型\r\n* getRevID() 返回消息id\r\n* getRevCtime() 返回消息发送事件\r\n* getRevContent() 返回消息内容正文或语音识别结果（文本型）\r\n* getRevPic() 返回图片信息（图片型信息） 返回数组{'mediaid'=>'','picurl'=>''}\r\n* getRevLink() 接收消息链接（链接型信息） 返回数组{'url'=>'','title'=>'','description'=>''}\r\n* getRevGeo() 返回地理位置（位置型信息） 返回数组{'x'=>'','y'=>'','scale'=>'','label'=>''}\r\n* getRevEventGeo() 返回事件地理位置（事件型信息） 返回数组{'x'=>'','y'=>'','precision'=>''}\r\n* getRevEvent() 返回事件类型（事件型信息） 返回数组{'event'=>'','key'=>''}\r\n* getRevScanInfo() 获取自定义菜单的扫码推事件信息，事件类型为`scancode_push`或`scancode_waitmsg` 返回数组array ('ScanType'=>'qrcode','ScanResult'=>'123123')\r\n* getRevSendPicsInfo() 获取自定义菜单的图片发送事件信息,事件类型为`pic_sysphoto`或`pic_photo_or_album`或`pic_weixin` 数组结构见php文件内方法说明\r\n* getRevSendGeoInfo() 获取自定义菜单的地理位置选择器事件推送，事件类型为`location_select` 数组结构见php文件内方法说明\r\n* getRevVoice() 返回语音信息（语音型信息） 返回数组{'mediaid'=>'','format'=>''}\r\n* getRevVideo() 返回视频信息（视频型信息） 返回数组{'mediaid'=>'','thumbmediaid'=>''}\r\n* getRevTicket() 返回接收TICKET（扫描带参数二维码,关注或SCAN事件） 返回二维码的ticket值\r\n* getRevSceneId() 返回二维码的场景值（扫描带参数二维码的关注事件） 返回二维码的参数值\r\n* getRevTplMsgID() 返回主动推送的消息ID（群发或模板消息事件） 返回MsgID值\r\n* getRevStatus() 返回模板消息发送状态（模板消息事件） 返回文本：success(成功)|failed:user block(用户拒绝接收)|failed: system failed(发送失败（非用户拒绝）)\r\n* getRevResult() 返回群发或模板消息发送结果（群发或模板消息事件） 返回数组，内容依事件类型而不同，参考开发文档中群发、模板消息推送事件\r\n* getRevKFCreate() 返回多客服-接入会话的客服账号（多客服-接入会话事件） 返回文本型\r\n* getRevKFClose() 返回多客服-处理会话的客服账号（多客服-接入会话事件） 返回文本型\r\n* getRevKFSwitch() 返回多客服-转接会话信息（多客服-转接会话事件） 返回数组\t{'FromKfAccount' => '','ToKfAccount' => ''}\r\n* getRevCardPass() 返回卡券-审核通过的卡券ID（卡券-卡券审核事件） 返回文本型\r\n* getRevCardGet() 返回卡券-用户领取卡券的相关信息（卡券-领取卡券事件） 返回数组{'CardId' => '','IsGiveByFriend' => '','UserCardCode' => ''}\r\n* getRevCardDel() 返回卡券-用户删除卡券的相关信息（卡券-删除卡券事件） 返回数组{'CardId' => '','UserCardCode' => ''}\r\n* \r\n* text($text) 设置文本型消息，参数：文本内容\r\n* image($mediaid) 设置图片型消息，参数：图片的media_id\r\n* voice($mediaid) 设置语音型消息，参数：语音的media_id\r\n* video($mediaid='',$title,$description) 设置视频型消息，参数：视频的media_id、标题、摘要\r\n* music($title,$desc,$musicurl,$hgmusicurl='',$thumbmediaid='') 设置回复音乐，参数：音乐标题、音乐描述、音乐链接、高音质链接、缩略图的媒体id\r\n* news($newsData) 设置图文型消息，参数：数组。数组结构见php文件内方法说明\r\n* image($mediaid) 设置图片型消息，参数：图片的media_id\r\n* Message($msg = '',$append = false) 设置发送的消息（一般不需要调用这个方法）\r\n* transfer_customer_service($customer_account = '') 转接多客服，如不指定客服可不提供参数，参数：指定客服的账号\r\n* reply() 将以上已经设置好的消息，回复给微信服务器\r\n\r\n### 预定义常量列表：\r\n```php\r\n////消息类型，使用实例调用getRevType()方法取得\r\nconst MSGTYPE_TEXT = 'text';\r\nconst MSGTYPE_IMAGE = 'image';\r\nconst MSGTYPE_LOCATION = 'location';\r\nconst MSGTYPE_LINK = 'link';\r\nconst MSGTYPE_EVENT = 'event';\r\nconst MSGTYPE_MUSIC = 'music';\r\nconst MSGTYPE_NEWS = 'news';\r\nconst MSGTYPE_VOICE = 'voice';\r\nconst MSGTYPE_VIDEO = 'video';\r\n////事件类型，使用实例调用getRevEvent()方法取得\r\nconst EVENT_SUBSCRIBE = 'subscribe';       //订阅\r\nconst EVENT_UNSUBSCRIBE = 'unsubscribe';   //取消订阅\r\nconst EVENT_SCAN = 'SCAN';                 //扫描带参数二维码\r\nconst EVENT_LOCATION = 'LOCATION';         //上报地理位置\r\nconst EVENT_MENU_VIEW = 'VIEW';                     //菜单 - 点击菜单跳转链接\r\nconst EVENT_MENU_CLICK = 'CLICK';                   //菜单 - 点击菜单拉取消息\r\nconst EVENT_MENU_SCAN_PUSH = 'scancode_push';       //菜单 - 扫码推事件(客户端跳URL)\r\nconst EVENT_MENU_SCAN_WAITMSG = 'scancode_waitmsg'; //菜单 - 扫码推事件(客户端不跳URL)\r\nconst EVENT_MENU_PIC_SYS = 'pic_sysphoto';          //菜单 - 弹出系统拍照发图\r\nconst EVENT_MENU_PIC_PHOTO = 'pic_photo_or_album';  //菜单 - 弹出拍照或者相册发图\r\nconst EVENT_MENU_PIC_WEIXIN = 'pic_weixin';         //菜单 - 弹出微信相册发图器\r\nconst EVENT_MENU_LOCATION = 'location_select';      //菜单 - 弹出地理位置选择器\r\nconst EVENT_SEND_MASS = 'MASSSENDJOBFINISH';        //发送结果 - 高级群发完成\r\nconst EVENT_SEND_TEMPLATE = 'TEMPLATESENDJOBFINISH';//发送结果 - 模板消息发送结果\r\nconst EVENT_KF_SEESION_CREATE = 'kfcreatesession';  //多客服 - 接入会话\r\nconst EVENT_KF_SEESION_CLOSE = 'kfclosesession';    //多客服 - 关闭会话\r\nconst EVENT_KF_SEESION_SWITCH = 'kfswitchsession';  //多客服 - 转接会话\r\nconst EVENT_CARD_PASS = 'card_pass_check';          //卡券 - 审核通过\r\nconst EVENT_CARD_NOTPASS = 'card_not_pass_check';   //卡券 - 审核未通过\r\nconst EVENT_CARD_USER_GET = 'user_get_card';        //卡券 - 用户领取卡券\r\nconst EVENT_CARD_USER_DEL = 'user_del_card';        //卡券 - 用户删除卡券\r\n```\r\n\r\n### 主动接口方法:   \r\n *  checkAuth($appid,$appsecret,$token) 此处传入公众后台高级接口提供的appid和appsecret, 或者手动指定$token为access_token。函数将返回access_token操作令牌\r\n *  resetAuth($appid='') 删除验证数据\r\n *  resetJsTicket($appid='') 删除JSAPI授权TICKET\r\n *  getJsTicket($appid='',$jsapi_ticket='') 获取JSAPI授权TICKET\r\n *  getJsSign($url, $timestamp=0, $noncestr='', $appid='') 获取JsApi使用签名信息数组，可只提供url地址 \r\n *  createMenu($data) 创建菜单 $data菜单结构详见 **[自定义菜单创建接口](http://mp.weixin.qq.com/wiki/index.php?title=自定义菜单创建接口)**\r\n *  getServerIp() 获取微信服务器IP地址列表 返回数组array('127.0.0.1','127.0.0.1')\r\n *  getMenu() 获取菜单 \r\n *  deleteMenu() 删除菜单 \r\n *  uploadMedia($data, $type) 上传多媒体文件(注意上传大文件时可能需要先调用 set_time_limit(0) 避免超时)\r\n *  getMedia() 获取接收到的音频、视频媒体文件 \r\n *  uploadMpVideo($data) 上传视频素材，当需要群发视频时，必须使用此方法得到的MediaID，否则无法显示\r\n *  uploadArticles($data) 上传图文消息素材\r\n *  sendMassMessage($data) 高级群发消息\r\n *  sendGroupMassMessage($data) 高级群发消息（全体或分组群发）\r\n *  deleteMassMessage($msg_id) 删除群发图文消息\r\n *  previewMassMessage($data) 预览群发消息\r\n *  queryMassMessage($msg_id) 查询群发消息发送状态\r\n *  getQRCode($scene_id,$type=0,$expire=1800) 获取推广二维码ticket字串 \r\n *  getQRUrl($ticket) 获取二维码图片地址\r\n *  getShortUrl($long_url) 长链接转短链接接口\r\n *  getUserList($next_openid) 批量获取关注用户列表 \r\n *  getUserInfo($openid) 获取关注者详细信息 \r\n *  updateUserRemark($openid,$remark) 设置用户备注名\r\n *  getGroup() 获取用户分组列表 \r\n *  getUserGroup($openid) 获取用户所在分组\r\n *  createGroup($name) 新增自定分组 \r\n *  updateGroup($groupid,$name) 更改分组名称 \r\n *  updateGroupMembers($groupid,$openid) 移动用户分组  \r\n *  batchUpdateGroupMembers($groupid,$openid_list) 批量移动用户分组 \r\n *  sendCustomMessage($data) 发送客服消息  \r\n *  getOauthRedirect($callback,$state,$scope) 获取网页授权oAuth跳转地址  \r\n *  getOauthAccessToken() 通过回调的code获取网页授权access_token  \r\n *  getOauthRefreshToken($refresh_token) 通过refresh_token对access_token续期  \r\n *  getOauthUserinfo($access_token,$openid) 通过网页授权的access_token获取用户资料  \r\n *  getOauthAuth($access_token,$openid)  检验授权凭证access_token是否有效\r\n *  getSignature($arrdata,'sha1') 生成签名字串  \r\n *  generateNonceStr($length=16) 获取随机字串  \r\n *  setTMIndustry($id1,$id2='') 模板消息，设置所属行业\r\n *  addTemplateMessage($tpl_id) 模板消息，添加消息模板\r\n *  sendTemplateMessage($data) 发送模板消息\r\n *  getCustomServiceMessage($data) 获取多客服会话记录\r\n *  transfer_customer_service($customer_account) 转发多客服消息\r\n *  getCustomServiceKFlist() 获取多客服客服基本信息\r\n *  getCustomServiceOnlineKFlist() 获取多客服在线客服接待信息\r\n *  createKFSession($openid,$kf_account,$text='') 创建指定多客服会话\r\n *  closeKFSession($openid,$kf_account,$text='') 关闭指定多客服会话\r\n *  getKFSession($openid) 获取用户会话状态\r\n *  getKFSessionlist($kf_account) 获取指定客服的会话列表\r\n *  getKFSessionWait() 获取未接入会话列表\r\n *  addKFAccount($account,$nickname,$password) 添加客服账号\r\n *  updateKFAccount($account,$nickname,$password) 修改客服账号信息\r\n *  deleteKFAccount($account) 删除客服账号\r\n *  setKFHeadImg($account,$imgfile) 上传客服头像\r\n *  querySemantic($uid,$query,$category,$latitude=0,$longitude=0,$city=\"\",$region=\"\") 语义理解接口 参数含义及返回的json内容请查看 **[微信语义理解接口](http://mp.weixin.qq.com/wiki/index.php?title=语义理解)**\r\n *  getDatacube($type,$subtype,$begin_date,$end_date='') 获取统计数据 参数需注意$type与$subtype的定义\r\n> 获取统计数据方法 参数定义\r\n> \r\n| 数据分类 | $type值(字符串)  | 数据子分类 | $subtype值(字符串) | 时间跨度(天) |\r\n| --------- | :-------:  | --------- | :------: | ----: |\r\n| 用户分析 | 'user' | 获取用户增减数据 | 'summary' | 7 |\r\n| 用户分析 | 'user' | 获取累计用户数据 | 'cumulate' | 7 |\r\n| 图文分析 | 'article' | 获取图文群发每日数据 | 'summary' | 1 |\r\n| 图文分析 | 'article' | 获取图文群发总数据 | 'total' | 1 |\r\n| 图文分析 | 'article' | 获取图文统计数据 | 'read' | 3 |\r\n| 图文分析 | 'article' | 获取图文统计分时数据 | 'readhour' | 1 |\r\n| 图文分析 | 'article' | 获取图文分享转发数据 | 'share' | 7 |\r\n| 图文分析 | 'article' | 获取图文分享转发分时数据 | 'sharehour' | 1 |\r\n| 消息分析 | 'upstreammsg' | 获取消息发送概况数据 | 'summary' | 7 |\r\n| 消息分析 | 'upstreammsg' | 获取消息分送分时数据 | 'hour' | 1 |\r\n| 消息分析 | 'upstreammsg' | 获取消息发送周数据 | 'week' | 30 |\r\n| 消息分析 | 'upstreammsg' | 获取消息发送月数据 | 'month' | 30 |\r\n| 消息分析 | 'upstreammsg' | 获取消息发送分布数据 | 'dist' | 15 |\r\n| 消息分析 | 'upstreammsg' | 获取消息发送分布周数据 | 'distweek' | 30 |\r\n| 消息分析 | 'upstreammsg' | 获取消息发送分布月数据 | 'distmonth' | 30 |\r\n| 接口分析 | 'interface' | 获取接口分析数据 | 'summary' | 30 |\r\n| 接口分析 | 'interface' | 获取接口分析分时数据 | 'summaryhour' | 1 |\r\n需要注意 `begin_date`和`end_date`的差值需小于“最大时间跨度”（比如最大时间跨度为1时，`begin_date`和`end_date`的差值只能为0，才能小于1）\r\n\r\n *  createCard($data) 创建卡券\r\n *  updateCard($data) 修改卡券\r\n *  delCard($card_id) 删除卡券\r\n *  getCardInfo($card_id) 查询卡券详情\r\n *  getCardColors() 获取颜色列表\r\n *  getCardLocations() 拉取门店列表\r\n *  addCardLocations($data) 批量导入门店信息\r\n *  createCardQrcode($card_id) 生成卡券二维码\r\n *  consumeCardCode($code) 消耗 code\r\n *  decryptCardCode($encrypt_code) code 解码\r\n *  checkCardCode($code) 获取 code 的有效性\r\n *  getCardIdList($data) 批量查询卡列表\r\n *  updateCardCode($code,$card_id,$new_code) 更改 code\r\n *  unavailableCardCode($code,$card_id='') 设置卡券失效**(不可逆)**\r\n *  modifyCardStock($data) 库存修改\r\n *  activateMemberCard($data) 激活/绑定会员卡，参数结构请参看卡券开发文档(6.1.1 激活/绑定会员卡)章节\r\n *  updateMemberCard($data) 会员卡交易，参数结构请参看卡券开发文档(6.1.2 会员卡交易)章节\r\n *  updateLuckyMoney($code,$balance,$card_id='') 更新红包金额\r\n *  setCardTestWhiteList($openid=array(),$user=array()) 设置卡券测试白名单\r\n\r\n\r\n\r\n## 官方Wechat调用示例：\r\n```php\r\n//test1.php\r\ninclude \"wechat.class.php\";\r\n$options = array(\r\n\t\t'token'=>'tokenaccesskey' //填写你设定的key\r\n\t);\r\n$weObj = new Wechat($options);\r\n$weObj->valid();//明文或兼容模式可以在接口验证通过后注释此句，但加密模式一定不能注释，否则会验证失败\r\n$type = $weObj->getRev()->getRevType();\r\nswitch($type) {\r\n\tcase Wechat::MSGTYPE_TEXT:\r\n\t\t\t$weObj->text(\"hello, I'm wechat\")->reply();\r\n\t\t\texit;\r\n\t\t\tbreak;\r\n\tcase Wechat::MSGTYPE_EVENT:\r\n\t\t\tbreak;\r\n\tcase Wechat::MSGTYPE_IMAGE:\r\n\t\t\tbreak;\r\n\tdefault:\r\n\t\t\t$weObj->text(\"help info\")->reply();\r\n}\r\n```\r\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/LICENSE",
    "content": "\t\t  GNU LESSER GENERAL PUBLIC LICENSE\n\t\t       Version 2.1, February 1999\n\n Copyright (C) 1991, 1999 Free Software Foundation, Inc.\n     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n Everyone is permitted to copy and distribute verbatim copies\n of this license document, but changing it is not allowed.\n\n[This is the first released version of the Lesser GPL.  It also counts\n as the successor of the GNU Library Public License, version 2, hence\n the version number 2.1.]\n\n\t\t\t    Preamble\n\n  The licenses for most software are designed to take away your\nfreedom to share and change it.  By contrast, the GNU General Public\nLicenses are intended to guarantee your freedom to share and change\nfree software--to make sure the software is free for all its users.\n\n  This license, the Lesser General Public License, applies to some\nspecially designated software packages--typically libraries--of the\nFree Software Foundation and other authors who decide to use it.  You\ncan use it too, but we suggest you first think carefully about whether\nthis license or the ordinary General Public License is the better\nstrategy to use in any particular case, based on the explanations below.\n\n  When we speak of free software, we are referring to freedom of use,\nnot price.  Our General Public Licenses are designed to make sure that\nyou have the freedom to distribute copies of free software (and charge\nfor this service if you wish); that you receive source code or can get\nit if you want it; that you can change the software and use pieces of\nit in new free programs; and that you are informed that you can do\nthese things.\n\n  To protect your rights, we need to make restrictions that forbid\ndistributors to deny you these rights or to ask you to surrender these\nrights.  These restrictions translate to certain responsibilities for\nyou if you distribute copies of the library or if you modify it.\n\n  For example, if you distribute copies of the library, whether gratis\nor for a fee, you must give the recipients all the rights that we gave\nyou.  You must make sure that they, too, receive or can get the source\ncode.  If you link other code with the library, you must provide\ncomplete object files to the recipients, so that they can relink them\nwith the library after making changes to the library and recompiling\nit.  And you must show them these terms so they know their rights.\n\n  We protect your rights with a two-step method: (1) we copyright the\nlibrary, and (2) we offer you this license, which gives you legal\npermission to copy, distribute and/or modify the library.\n\n  To protect each distributor, we want to make it very clear that\nthere is no warranty for the free library.  Also, if the library is\nmodified by someone else and passed on, the recipients should know\nthat what they have is not the original version, so that the original\nauthor's reputation will not be affected by problems that might be\nintroduced by others.\n\n  Finally, software patents pose a constant threat to the existence of\nany free program.  We wish to make sure that a company cannot\neffectively restrict the users of a free program by obtaining a\nrestrictive license from a patent holder.  Therefore, we insist that\nany patent license obtained for a version of the library must be\nconsistent with the full freedom of use specified in this license.\n\n  Most GNU software, including some libraries, is covered by the\nordinary GNU General Public License.  This license, the GNU Lesser\nGeneral Public License, applies to certain designated libraries, and\nis quite different from the ordinary General Public License.  We use\nthis license for certain libraries in order to permit linking those\nlibraries into non-free programs.\n\n  When a program is linked with a library, whether statically or using\na shared library, the combination of the two is legally speaking a\ncombined work, a derivative of the original library.  The ordinary\nGeneral Public License therefore permits such linking only if the\nentire combination fits its criteria of freedom.  The Lesser General\nPublic License permits more lax criteria for linking other code with\nthe library.\n\n  We call this license the \"Lesser\" General Public License because it\ndoes Less to protect the user's freedom than the ordinary General\nPublic License.  It also provides other free software developers Less\nof an advantage over competing non-free programs.  These disadvantages\nare the reason we use the ordinary General Public License for many\nlibraries.  However, the Lesser license provides advantages in certain\nspecial circumstances.\n\n  For example, on rare occasions, there may be a special need to\nencourage the widest possible use of a certain library, so that it becomes\na de-facto standard.  To achieve this, non-free programs must be\nallowed to use the library.  A more frequent case is that a free\nlibrary does the same job as widely used non-free libraries.  In this\ncase, there is little to gain by limiting the free library to free\nsoftware only, so we use the Lesser General Public License.\n\n  In other cases, permission to use a particular library in non-free\nprograms enables a greater number of people to use a large body of\nfree software.  For example, permission to use the GNU C Library in\nnon-free programs enables many more people to use the whole GNU\noperating system, as well as its variant, the GNU/Linux operating\nsystem.\n\n  Although the Lesser General Public License is Less protective of the\nusers' freedom, it does ensure that the user of a program that is\nlinked with the Library has the freedom and the wherewithal to run\nthat program using a modified version of the Library.\n\n  The precise terms and conditions for copying, distribution and\nmodification follow.  Pay close attention to the difference between a\n\"work based on the library\" and a \"work that uses the library\".  The\nformer contains code derived from the library, whereas the latter must\nbe combined with the library in order to run.\n\n\t\t  GNU LESSER GENERAL PUBLIC LICENSE\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License Agreement applies to any software library or other\nprogram which contains a notice placed by the copyright holder or\nother authorized party saying it may be distributed under the terms of\nthis Lesser General Public License (also called \"this License\").\nEach licensee is addressed as \"you\".\n\n  A \"library\" means a collection of software functions and/or data\nprepared so as to be conveniently linked with application programs\n(which use some of those functions and data) to form executables.\n\n  The \"Library\", below, refers to any such software library or work\nwhich has been distributed under these terms.  A \"work based on the\nLibrary\" means either the Library or any derivative work under\ncopyright law: that is to say, a work containing the Library or a\nportion of it, either verbatim or with modifications and/or translated\nstraightforwardly into another language.  (Hereinafter, translation is\nincluded without limitation in the term \"modification\".)\n\n  \"Source code\" for a work means the preferred form of the work for\nmaking modifications to it.  For a library, complete source code means\nall the source code for all modules it contains, plus any associated\ninterface definition files, plus the scripts used to control compilation\nand installation of the library.\n\n  Activities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning a program using the Library is not restricted, and output from\nsuch a program is covered only if its contents constitute a work based\non the Library (independent of the use of the Library in a tool for\nwriting it).  Whether that is true depends on what the Library does\nand what the program that uses the Library does.\n  \n  1. You may copy and distribute verbatim copies of the Library's\ncomplete source code as you receive it, in any medium, provided that\nyou conspicuously and appropriately publish on each copy an\nappropriate copyright notice and disclaimer of warranty; keep intact\nall the notices that refer to this License and to the absence of any\nwarranty; and distribute a copy of this License along with the\nLibrary.\n\n  You may charge a fee for the physical act of transferring a copy,\nand you may at your option offer warranty protection in exchange for a\nfee.\n\n  2. You may modify your copy or copies of the Library or any portion\nof it, thus forming a work based on the Library, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) The modified work must itself be a software library.\n\n    b) You must cause the files modified to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    c) You must cause the whole of the work to be licensed at no\n    charge to all third parties under the terms of this License.\n\n    d) If a facility in the modified Library refers to a function or a\n    table of data to be supplied by an application program that uses\n    the facility, other than as an argument passed when the facility\n    is invoked, then you must make a good faith effort to ensure that,\n    in the event an application does not supply such function or\n    table, the facility still operates, and performs whatever part of\n    its purpose remains meaningful.\n\n    (For example, a function in a library to compute square roots has\n    a purpose that is entirely well-defined independent of the\n    application.  Therefore, Subsection 2d requires that any\n    application-supplied function or table used by this function must\n    be optional: if the application does not supply it, the square\n    root function must still compute square roots.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Library,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Library, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote\nit.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Library.\n\nIn addition, mere aggregation of another work not based on the Library\nwith the Library (or with a work based on the Library) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may opt to apply the terms of the ordinary GNU General Public\nLicense instead of this License to a given copy of the Library.  To do\nthis, you must alter all the notices that refer to this License, so\nthat they refer to the ordinary GNU General Public License, version 2,\ninstead of to this License.  (If a newer version than version 2 of the\nordinary GNU General Public License has appeared, then you can specify\nthat version instead if you wish.)  Do not make any other change in\nthese notices.\n\n  Once this change is made in a given copy, it is irreversible for\nthat copy, so the ordinary GNU General Public License applies to all\nsubsequent copies and derivative works made from that copy.\n\n  This option is useful when you wish to copy part of the code of\nthe Library into a program that is not a library.\n\n  4. You may copy and distribute the Library (or a portion or\nderivative of it, under Section 2) in object code or executable form\nunder the terms of Sections 1 and 2 above provided that you accompany\nit with the complete corresponding machine-readable source code, which\nmust be distributed under the terms of Sections 1 and 2 above on a\nmedium customarily used for software interchange.\n\n  If distribution of object code is made by offering access to copy\nfrom a designated place, then offering equivalent access to copy the\nsource code from the same place satisfies the requirement to\ndistribute the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  5. A program that contains no derivative of any portion of the\nLibrary, but is designed to work with the Library by being compiled or\nlinked with it, is called a \"work that uses the Library\".  Such a\nwork, in isolation, is not a derivative work of the Library, and\ntherefore falls outside the scope of this License.\n\n  However, linking a \"work that uses the Library\" with the Library\ncreates an executable that is a derivative of the Library (because it\ncontains portions of the Library), rather than a \"work that uses the\nlibrary\".  The executable is therefore covered by this License.\nSection 6 states terms for distribution of such executables.\n\n  When a \"work that uses the Library\" uses material from a header file\nthat is part of the Library, the object code for the work may be a\nderivative work of the Library even though the source code is not.\nWhether this is true is especially significant if the work can be\nlinked without the Library, or if the work is itself a library.  The\nthreshold for this to be true is not precisely defined by law.\n\n  If such an object file uses only numerical parameters, data\nstructure layouts and accessors, and small macros and small inline\nfunctions (ten lines or less in length), then the use of the object\nfile is unrestricted, regardless of whether it is legally a derivative\nwork.  (Executables containing this object code plus portions of the\nLibrary will still fall under Section 6.)\n\n  Otherwise, if the work is a derivative of the Library, you may\ndistribute the object code for the work under the terms of Section 6.\nAny executables containing that work also fall under Section 6,\nwhether or not they are linked directly with the Library itself.\n\n  6. As an exception to the Sections above, you may also combine or\nlink a \"work that uses the Library\" with the Library to produce a\nwork containing portions of the Library, and distribute that work\nunder terms of your choice, provided that the terms permit\nmodification of the work for the customer's own use and reverse\nengineering for debugging such modifications.\n\n  You must give prominent notice with each copy of the work that the\nLibrary is used in it and that the Library and its use are covered by\nthis License.  You must supply a copy of this License.  If the work\nduring execution displays copyright notices, you must include the\ncopyright notice for the Library among them, as well as a reference\ndirecting the user to the copy of this License.  Also, you must do one\nof these things:\n\n    a) Accompany the work with the complete corresponding\n    machine-readable source code for the Library including whatever\n    changes were used in the work (which must be distributed under\n    Sections 1 and 2 above); and, if the work is an executable linked\n    with the Library, with the complete machine-readable \"work that\n    uses the Library\", as object code and/or source code, so that the\n    user can modify the Library and then relink to produce a modified\n    executable containing the modified Library.  (It is understood\n    that the user who changes the contents of definitions files in the\n    Library will not necessarily be able to recompile the application\n    to use the modified definitions.)\n\n    b) Use a suitable shared library mechanism for linking with the\n    Library.  A suitable mechanism is one that (1) uses at run time a\n    copy of the library already present on the user's computer system,\n    rather than copying library functions into the executable, and (2)\n    will operate properly with a modified version of the library, if\n    the user installs one, as long as the modified version is\n    interface-compatible with the version that the work was made with.\n\n    c) Accompany the work with a written offer, valid for at\n    least three years, to give the same user the materials\n    specified in Subsection 6a, above, for a charge no more\n    than the cost of performing this distribution.\n\n    d) If distribution of the work is made by offering access to copy\n    from a designated place, offer equivalent access to copy the above\n    specified materials from the same place.\n\n    e) verify that the user has already received a copy of these\n    materials or that you have already sent this user a copy.\n\n  For an executable, the required form of the \"work that uses the\nLibrary\" must include any data and utility programs needed for\nreproducing the executable from it.  However, as a special exception,\nthe materials to be distributed need not include anything that is\nnormally distributed (in either source or binary form) with the major\ncomponents (compiler, kernel, and so on) of the operating system on\nwhich the executable runs, unless that component itself accompanies\nthe executable.\n\n  It may happen that this requirement contradicts the license\nrestrictions of other proprietary libraries that do not normally\naccompany the operating system.  Such a contradiction means you cannot\nuse both them and the Library together in an executable that you\ndistribute.\n\n  7. You may place library facilities that are a work based on the\nLibrary side-by-side in a single library together with other library\nfacilities not covered by this License, and distribute such a combined\nlibrary, provided that the separate distribution of the work based on\nthe Library and of the other library facilities is otherwise\npermitted, and provided that you do these two things:\n\n    a) Accompany the combined library with a copy of the same work\n    based on the Library, uncombined with any other library\n    facilities.  This must be distributed under the terms of the\n    Sections above.\n\n    b) Give prominent notice with the combined library of the fact\n    that part of it is a work based on the Library, and explaining\n    where to find the accompanying uncombined form of the same work.\n\n  8. You may not copy, modify, sublicense, link with, or distribute\nthe Library except as expressly provided under this License.  Any\nattempt otherwise to copy, modify, sublicense, link with, or\ndistribute the Library is void, and will automatically terminate your\nrights under this License.  However, parties who have received copies,\nor rights, from you under this License will not have their licenses\nterminated so long as such parties remain in full compliance.\n\n  9. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Library or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Library (or any work based on the\nLibrary), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Library or works based on it.\n\n  10. Each time you redistribute the Library (or any work based on the\nLibrary), the recipient automatically receives a license from the\noriginal licensor to copy, distribute, link with or modify the Library\nsubject to these terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties with\nthis License.\n\n  11. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Library at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Library by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Library.\n\nIf any portion of this section is held invalid or unenforceable under any\nparticular circumstance, the balance of the section is intended to apply,\nand the section as a whole is intended to apply in other circumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  12. If the distribution and/or use of the Library is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Library under this License may add\nan explicit geographical distribution limitation excluding those countries,\nso that distribution is permitted only in or among countries not thus\nexcluded.  In such case, this License incorporates the limitation as if\nwritten in the body of this License.\n\n  13. The Free Software Foundation may publish revised and/or new\nversions of the Lesser General Public License from time to time.\nSuch new versions will be similar in spirit to the present version,\nbut may differ in detail to address new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Library\nspecifies a version number of this License which applies to it and\n\"any later version\", you have the option of following the terms and\nconditions either of that version or of any later version published by\nthe Free Software Foundation.  If the Library does not specify a\nlicense version number, you may choose any version ever published by\nthe Free Software Foundation.\n\n  14. If you wish to incorporate parts of the Library into other free\nprograms whose distribution conditions are incompatible with these,\nwrite to the author to ask for permission.  For software which is\ncopyrighted by the Free Software Foundation, write to the Free\nSoftware Foundation; we sometimes make exceptions for this.  Our\ndecision will be guided by the two goals of preserving the free status\nof all derivatives of our free software and of promoting the sharing\nand reuse of software generally.\n\n\t\t\t    NO WARRANTY\n\n  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO\nWARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\nEXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\nOTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY\nKIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\nLIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME\nTHE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\nWRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\nAND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU\nFOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR\nCONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\nLIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\nRENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\nFAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF\nSUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGES.\n\n\t\t     END OF TERMS AND CONDITIONS\n\n           How to Apply These Terms to Your New Libraries\n\n  If you develop a new library, and you want it to be of the greatest\npossible use to the public, we recommend making it free software that\neveryone can redistribute and change.  You can do so by permitting\nredistribution under these terms (or, alternatively, under the terms of the\nordinary General Public License).\n\n  To apply these terms, attach the following notices to the library.  It is\nsafest to attach them to the start of each source file to most effectively\nconvey the exclusion of warranty; and each file should have at least the\n\"copyright\" line and a pointer to where the full notice is found.\n\n    <one line to give the library's name and a brief idea of what it does.>\n    Copyright (C) <year>  <name of author>\n\n    This library is free software; you can redistribute it and/or\n    modify it under the terms of the GNU Lesser General Public\n    License as published by the Free Software Foundation; either\n    version 2.1 of the License, or (at your option) any later version.\n\n    This library is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n    Lesser General Public License for more details.\n\n    You should have received a copy of the GNU Lesser General Public\n    License along with this library; if not, write to the Free Software\n    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\nAlso add information on how to contact you by electronic and paper mail.\n\nYou should also get your employer (if you work as a programmer) or your\nschool, if any, to sign a \"copyright disclaimer\" for the library, if\nnecessary.  Here is a sample; alter the names:\n\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the\n  library `Frob' (a library for tweaking knobs) written by James Random Hacker.\n\n  <signature of Ty Coon>, 1 April 1990\n  Ty Coon, President of Vice\n\nThat's all there is to it!\n\n\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/PHPMailerAutoload.php",
    "content": "<?php\n/**\n * PHPMailer SPL autoloader.\n * PHP Version 5\n * @package PHPMailer\n * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project\n * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>\n * @author Jim Jagielski (jimjag) <jimjag@gmail.com>\n * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>\n * @author Brent R. Matzelle (original founder)\n * @copyright 2012 - 2014 Marcus Bointon\n * @copyright 2010 - 2012 Jim Jagielski\n * @copyright 2004 - 2009 Andy Prevost\n * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License\n * @note This program is distributed in the hope that it will be useful - WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.\n */\n\n/**\n * PHPMailer SPL autoloader.\n * @param string $classname The name of the class to load\n */\nfunction PHPMailerAutoload($classname)\n{\n    //Can't use __DIR__ as it's only in PHP 5.3+\n    $filename = dirname(__FILE__).DIRECTORY_SEPARATOR.'class.'.strtolower($classname).'.php';\n    if (is_readable($filename)) {\n        require $filename;\n    }\n}\n\nif (version_compare(PHP_VERSION, '5.1.2', '>=')) {\n    //SPL autoloading was introduced in PHP 5.1.2\n    if (version_compare(PHP_VERSION, '5.3.0', '>=')) {\n        spl_autoload_register('PHPMailerAutoload', true, true);\n    } else {\n        spl_autoload_register('PHPMailerAutoload');\n    }\n} else {\n    /**\n     * Fall back to traditional autoload for old PHP versions\n     * @param string $classname The name of the class to load\n     */\n    function __autoload($classname)\n    {\n        PHPMailerAutoload($classname);\n    }\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/VERSION",
    "content": "5.2.23\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/class.phpmailer.php",
    "content": "<?php\n/**\n * PHPMailer - PHP email creation and transport class.\n * PHP Version 5\n * @package PHPMailer\n * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project\n * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>\n * @author Jim Jagielski (jimjag) <jimjag@gmail.com>\n * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>\n * @author Brent R. Matzelle (original founder)\n * @copyright 2012 - 2014 Marcus Bointon\n * @copyright 2010 - 2012 Jim Jagielski\n * @copyright 2004 - 2009 Andy Prevost\n * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License\n * @note This program is distributed in the hope that it will be useful - WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.\n */\n\n/**\n * PHPMailer - PHP email creation and transport class.\n * @package PHPMailer\n * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>\n * @author Jim Jagielski (jimjag) <jimjag@gmail.com>\n * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>\n * @author Brent R. Matzelle (original founder)\n */\nclass PHPMailer\n{\n    /**\n     * The PHPMailer Version number.\n     * @var string\n     */\n    public $Version = '5.2.23';\n\n    /**\n     * Email priority.\n     * Options: null (default), 1 = High, 3 = Normal, 5 = low.\n     * When null, the header is not set at all.\n     * @var integer\n     */\n    public $Priority = null;\n\n    /**\n     * The character set of the message.\n     * @var string\n     */\n    public $CharSet = 'iso-8859-1';\n\n    /**\n     * The MIME Content-type of the message.\n     * @var string\n     */\n    public $ContentType = 'text/plain';\n\n    /**\n     * The message encoding.\n     * Options: \"8bit\", \"7bit\", \"binary\", \"base64\", and \"quoted-printable\".\n     * @var string\n     */\n    public $Encoding = '8bit';\n\n    /**\n     * Holds the most recent mailer error message.\n     * @var string\n     */\n    public $ErrorInfo = '';\n\n    /**\n     * The From email address for the message.\n     * @var string\n     */\n    public $From = 'root@localhost';\n\n    /**\n     * The From name of the message.\n     * @var string\n     */\n    public $FromName = 'Root User';\n\n    /**\n     * The Sender email (Return-Path) of the message.\n     * If not empty, will be sent via -f to sendmail or as 'MAIL FROM' in smtp mode.\n     * @var string\n     */\n    public $Sender = '';\n\n    /**\n     * The Return-Path of the message.\n     * If empty, it will be set to either From or Sender.\n     * @var string\n     * @deprecated Email senders should never set a return-path header;\n     * it's the receiver's job (RFC5321 section 4.4), so this no longer does anything.\n     * @link https://tools.ietf.org/html/rfc5321#section-4.4 RFC5321 reference\n     */\n    public $ReturnPath = '';\n\n    /**\n     * The Subject of the message.\n     * @var string\n     */\n    public $Subject = '';\n\n    /**\n     * An HTML or plain text message body.\n     * If HTML then call isHTML(true).\n     * @var string\n     */\n    public $Body = '';\n\n    /**\n     * The plain-text message body.\n     * This body can be read by mail clients that do not have HTML email\n     * capability such as mutt & Eudora.\n     * Clients that can read HTML will view the normal Body.\n     * @var string\n     */\n    public $AltBody = '';\n\n    /**\n     * An iCal message part body.\n     * Only supported in simple alt or alt_inline message types\n     * To generate iCal events, use the bundled extras/EasyPeasyICS.php class or iCalcreator\n     * @link http://sprain.ch/blog/downloads/php-class-easypeasyics-create-ical-files-with-php/\n     * @link http://kigkonsult.se/iCalcreator/\n     * @var string\n     */\n    public $Ical = '';\n\n    /**\n     * The complete compiled MIME message body.\n     * @access protected\n     * @var string\n     */\n    protected $MIMEBody = '';\n\n    /**\n     * The complete compiled MIME message headers.\n     * @var string\n     * @access protected\n     */\n    protected $MIMEHeader = '';\n\n    /**\n     * Extra headers that createHeader() doesn't fold in.\n     * @var string\n     * @access protected\n     */\n    protected $mailHeader = '';\n\n    /**\n     * Word-wrap the message body to this number of chars.\n     * Set to 0 to not wrap. A useful value here is 78, for RFC2822 section 2.1.1 compliance.\n     * @var integer\n     */\n    public $WordWrap = 0;\n\n    /**\n     * Which method to use to send mail.\n     * Options: \"mail\", \"sendmail\", or \"smtp\".\n     * @var string\n     */\n    public $Mailer = 'mail';\n\n    /**\n     * The path to the sendmail program.\n     * @var string\n     */\n    public $Sendmail = '/usr/sbin/sendmail';\n\n    /**\n     * Whether mail() uses a fully sendmail-compatible MTA.\n     * One which supports sendmail's \"-oi -f\" options.\n     * @var boolean\n     */\n    public $UseSendmailOptions = true;\n\n    /**\n     * Path to PHPMailer plugins.\n     * Useful if the SMTP class is not in the PHP include path.\n     * @var string\n     * @deprecated Should not be needed now there is an autoloader.\n     */\n    public $PluginDir = '';\n\n    /**\n     * The email address that a reading confirmation should be sent to, also known as read receipt.\n     * @var string\n     */\n    public $ConfirmReadingTo = '';\n\n    /**\n     * The hostname to use in the Message-ID header and as default HELO string.\n     * If empty, PHPMailer attempts to find one with, in order,\n     * $_SERVER['SERVER_NAME'], gethostname(), php_uname('n'), or the value\n     * 'localhost.localdomain'.\n     * @var string\n     */\n    public $Hostname = '';\n\n    /**\n     * An ID to be used in the Message-ID header.\n     * If empty, a unique id will be generated.\n     * You can set your own, but it must be in the format \"<id@domain>\",\n     * as defined in RFC5322 section 3.6.4 or it will be ignored.\n     * @see https://tools.ietf.org/html/rfc5322#section-3.6.4\n     * @var string\n     */\n    public $MessageID = '';\n\n    /**\n     * The message Date to be used in the Date header.\n     * If empty, the current date will be added.\n     * @var string\n     */\n    public $MessageDate = '';\n\n    /**\n     * SMTP hosts.\n     * Either a single hostname or multiple semicolon-delimited hostnames.\n     * You can also specify a different port\n     * for each host by using this format: [hostname:port]\n     * (e.g. \"smtp1.example.com:25;smtp2.example.com\").\n     * You can also specify encryption type, for example:\n     * (e.g. \"tls://smtp1.example.com:587;ssl://smtp2.example.com:465\").\n     * Hosts will be tried in order.\n     * @var string\n     */\n    public $Host = 'localhost';\n\n    /**\n     * The default SMTP server port.\n     * @var integer\n     * @TODO Why is this needed when the SMTP class takes care of it?\n     */\n    public $Port = 25;\n\n    /**\n     * The SMTP HELO of the message.\n     * Default is $Hostname. If $Hostname is empty, PHPMailer attempts to find\n     * one with the same method described above for $Hostname.\n     * @var string\n     * @see PHPMailer::$Hostname\n     */\n    public $Helo = '';\n\n    /**\n     * What kind of encryption to use on the SMTP connection.\n     * Options: '', 'ssl' or 'tls'\n     * @var string\n     */\n    public $SMTPSecure = '';\n\n    /**\n     * Whether to enable TLS encryption automatically if a server supports it,\n     * even if `SMTPSecure` is not set to 'tls'.\n     * Be aware that in PHP >= 5.6 this requires that the server's certificates are valid.\n     * @var boolean\n     */\n    public $SMTPAutoTLS = true;\n\n    /**\n     * Whether to use SMTP authentication.\n     * Uses the Username and Password properties.\n     * @var boolean\n     * @see PHPMailer::$Username\n     * @see PHPMailer::$Password\n     */\n    public $SMTPAuth = false;\n\n    /**\n     * Options array passed to stream_context_create when connecting via SMTP.\n     * @var array\n     */\n    public $SMTPOptions = array();\n\n    /**\n     * SMTP username.\n     * @var string\n     */\n    public $Username = '';\n\n    /**\n     * SMTP password.\n     * @var string\n     */\n    public $Password = '';\n\n    /**\n     * SMTP auth type.\n     * Options are CRAM-MD5, LOGIN, PLAIN, NTLM, XOAUTH2, attempted in that order if not specified\n     * @var string\n     */\n    public $AuthType = '';\n\n    /**\n     * SMTP realm.\n     * Used for NTLM auth\n     * @var string\n     */\n    public $Realm = '';\n\n    /**\n     * SMTP workstation.\n     * Used for NTLM auth\n     * @var string\n     */\n    public $Workstation = '';\n\n    /**\n     * The SMTP server timeout in seconds.\n     * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2\n     * @var integer\n     */\n    public $Timeout = 300;\n\n    /**\n     * SMTP class debug output mode.\n     * Debug output level.\n     * Options:\n     * * `0` No output\n     * * `1` Commands\n     * * `2` Data and commands\n     * * `3` As 2 plus connection status\n     * * `4` Low-level data output\n     * @var integer\n     * @see SMTP::$do_debug\n     */\n    public $SMTPDebug = 0;\n\n    /**\n     * How to handle debug output.\n     * Options:\n     * * `echo` Output plain-text as-is, appropriate for CLI\n     * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output\n     * * `error_log` Output to error log as configured in php.ini\n     *\n     * Alternatively, you can provide a callable expecting two params: a message string and the debug level:\n     * <code>\n     * $mail->Debugoutput = function($str, $level) {echo \"debug level $level; message: $str\";};\n     * </code>\n     * @var string|callable\n     * @see SMTP::$Debugoutput\n     */\n    public $Debugoutput = 'echo';\n\n    /**\n     * Whether to keep SMTP connection open after each message.\n     * If this is set to true then to close the connection\n     * requires an explicit call to smtpClose().\n     * @var boolean\n     */\n    public $SMTPKeepAlive = false;\n\n    /**\n     * Whether to split multiple to addresses into multiple messages\n     * or send them all in one message.\n     * Only supported in `mail` and `sendmail` transports, not in SMTP.\n     * @var boolean\n     */\n    public $SingleTo = false;\n\n    /**\n     * Storage for addresses when SingleTo is enabled.\n     * @var array\n     * @TODO This should really not be public\n     */\n    public $SingleToArray = array();\n\n    /**\n     * Whether to generate VERP addresses on send.\n     * Only applicable when sending via SMTP.\n     * @link https://en.wikipedia.org/wiki/Variable_envelope_return_path\n     * @link http://www.postfix.org/VERP_README.html Postfix VERP info\n     * @var boolean\n     */\n    public $do_verp = false;\n\n    /**\n     * Whether to allow sending messages with an empty body.\n     * @var boolean\n     */\n    public $AllowEmpty = false;\n\n    /**\n     * The default line ending.\n     * @note The default remains \"\\n\". We force CRLF where we know\n     *        it must be used via self::CRLF.\n     * @var string\n     */\n    public $LE = \"\\n\";\n\n    /**\n     * DKIM selector.\n     * @var string\n     */\n    public $DKIM_selector = '';\n\n    /**\n     * DKIM Identity.\n     * Usually the email address used as the source of the email.\n     * @var string\n     */\n    public $DKIM_identity = '';\n\n    /**\n     * DKIM passphrase.\n     * Used if your key is encrypted.\n     * @var string\n     */\n    public $DKIM_passphrase = '';\n\n    /**\n     * DKIM signing domain name.\n     * @example 'example.com'\n     * @var string\n     */\n    public $DKIM_domain = '';\n\n    /**\n     * DKIM private key file path.\n     * @var string\n     */\n    public $DKIM_private = '';\n\n    /**\n     * DKIM private key string.\n     * If set, takes precedence over `$DKIM_private`.\n     * @var string\n     */\n    public $DKIM_private_string = '';\n\n    /**\n     * Callback Action function name.\n     *\n     * The function that handles the result of the send email action.\n     * It is called out by send() for each email sent.\n     *\n     * Value can be any php callable: http://www.php.net/is_callable\n     *\n     * Parameters:\n     *   boolean $result        result of the send action\n     *   string  $to            email address of the recipient\n     *   string  $cc            cc email addresses\n     *   string  $bcc           bcc email addresses\n     *   string  $subject       the subject\n     *   string  $body          the email body\n     *   string  $from          email address of sender\n     * @var string\n     */\n    public $action_function = '';\n\n    /**\n     * What to put in the X-Mailer header.\n     * Options: An empty string for PHPMailer default, whitespace for none, or a string to use\n     * @var string\n     */\n    public $XMailer = '';\n\n    /**\n     * Which validator to use by default when validating email addresses.\n     * May be a callable to inject your own validator, but there are several built-in validators.\n     * @see PHPMailer::validateAddress()\n     * @var string|callable\n     * @static\n     */\n    public static $validator = 'auto';\n\n    /**\n     * An instance of the SMTP sender class.\n     * @var SMTP\n     * @access protected\n     */\n    protected $smtp = null;\n\n    /**\n     * The array of 'to' names and addresses.\n     * @var array\n     * @access protected\n     */\n    protected $to = array();\n\n    /**\n     * The array of 'cc' names and addresses.\n     * @var array\n     * @access protected\n     */\n    protected $cc = array();\n\n    /**\n     * The array of 'bcc' names and addresses.\n     * @var array\n     * @access protected\n     */\n    protected $bcc = array();\n\n    /**\n     * The array of reply-to names and addresses.\n     * @var array\n     * @access protected\n     */\n    protected $ReplyTo = array();\n\n    /**\n     * An array of all kinds of addresses.\n     * Includes all of $to, $cc, $bcc\n     * @var array\n     * @access protected\n     * @see PHPMailer::$to @see PHPMailer::$cc @see PHPMailer::$bcc\n     */\n    protected $all_recipients = array();\n\n    /**\n     * An array of names and addresses queued for validation.\n     * In send(), valid and non duplicate entries are moved to $all_recipients\n     * and one of $to, $cc, or $bcc.\n     * This array is used only for addresses with IDN.\n     * @var array\n     * @access protected\n     * @see PHPMailer::$to @see PHPMailer::$cc @see PHPMailer::$bcc\n     * @see PHPMailer::$all_recipients\n     */\n    protected $RecipientsQueue = array();\n\n    /**\n     * An array of reply-to names and addresses queued for validation.\n     * In send(), valid and non duplicate entries are moved to $ReplyTo.\n     * This array is used only for addresses with IDN.\n     * @var array\n     * @access protected\n     * @see PHPMailer::$ReplyTo\n     */\n    protected $ReplyToQueue = array();\n\n    /**\n     * The array of attachments.\n     * @var array\n     * @access protected\n     */\n    protected $attachment = array();\n\n    /**\n     * The array of custom headers.\n     * @var array\n     * @access protected\n     */\n    protected $CustomHeader = array();\n\n    /**\n     * The most recent Message-ID (including angular brackets).\n     * @var string\n     * @access protected\n     */\n    protected $lastMessageID = '';\n\n    /**\n     * The message's MIME type.\n     * @var string\n     * @access protected\n     */\n    protected $message_type = '';\n\n    /**\n     * The array of MIME boundary strings.\n     * @var array\n     * @access protected\n     */\n    protected $boundary = array();\n\n    /**\n     * The array of available languages.\n     * @var array\n     * @access protected\n     */\n    protected $language = array();\n\n    /**\n     * The number of errors encountered.\n     * @var integer\n     * @access protected\n     */\n    protected $error_count = 0;\n\n    /**\n     * The S/MIME certificate file path.\n     * @var string\n     * @access protected\n     */\n    protected $sign_cert_file = '';\n\n    /**\n     * The S/MIME key file path.\n     * @var string\n     * @access protected\n     */\n    protected $sign_key_file = '';\n\n    /**\n     * The optional S/MIME extra certificates (\"CA Chain\") file path.\n     * @var string\n     * @access protected\n     */\n    protected $sign_extracerts_file = '';\n\n    /**\n     * The S/MIME password for the key.\n     * Used only if the key is encrypted.\n     * @var string\n     * @access protected\n     */\n    protected $sign_key_pass = '';\n\n    /**\n     * Whether to throw exceptions for errors.\n     * @var boolean\n     * @access protected\n     */\n    protected $exceptions = false;\n\n    /**\n     * Unique ID used for message ID and boundaries.\n     * @var string\n     * @access protected\n     */\n    protected $uniqueid = '';\n\n    /**\n     * Error severity: message only, continue processing.\n     */\n    const STOP_MESSAGE = 0;\n\n    /**\n     * Error severity: message, likely ok to continue processing.\n     */\n    const STOP_CONTINUE = 1;\n\n    /**\n     * Error severity: message, plus full stop, critical error reached.\n     */\n    const STOP_CRITICAL = 2;\n\n    /**\n     * SMTP RFC standard line ending.\n     */\n    const CRLF = \"\\r\\n\";\n\n    /**\n     * The maximum line length allowed by RFC 2822 section 2.1.1\n     * @var integer\n     */\n    const MAX_LINE_LENGTH = 998;\n\n    /**\n     * Constructor.\n     * @param boolean $exceptions Should we throw external exceptions?\n     */\n    public function __construct($exceptions = null)\n    {\n        if ($exceptions !== null) {\n            $this->exceptions = (boolean)$exceptions;\n        }\n    }\n\n    /**\n     * Destructor.\n     */\n    public function __destruct()\n    {\n        //Close any open SMTP connection nicely\n        $this->smtpClose();\n    }\n\n    /**\n     * Call mail() in a safe_mode-aware fashion.\n     * Also, unless sendmail_path points to sendmail (or something that\n     * claims to be sendmail), don't pass params (not a perfect fix,\n     * but it will do)\n     * @param string $to To\n     * @param string $subject Subject\n     * @param string $body Message Body\n     * @param string $header Additional Header(s)\n     * @param string $params Params\n     * @access private\n     * @return boolean\n     */\n    private function mailPassthru($to, $subject, $body, $header, $params)\n    {\n        //Check overloading of mail function to avoid double-encoding\n        if (ini_get('mbstring.func_overload') & 1) {\n            $subject = $this->secureHeader($subject);\n        } else {\n            $subject = $this->encodeHeader($this->secureHeader($subject));\n        }\n\n        //Can't use additional_parameters in safe_mode, calling mail() with null params breaks\n        //@link http://php.net/manual/en/function.mail.php\n        if (ini_get('safe_mode') or !$this->UseSendmailOptions or is_null($params)) {\n            $result = @mail($to, $subject, $body, $header);\n        } else {\n            $result = @mail($to, $subject, $body, $header, $params);\n        }\n        return $result;\n    }\n    /**\n     * Output debugging info via user-defined method.\n     * Only generates output if SMTP debug output is enabled (@see SMTP::$do_debug).\n     * @see PHPMailer::$Debugoutput\n     * @see PHPMailer::$SMTPDebug\n     * @param string $str\n     */\n    protected function edebug($str)\n    {\n        if ($this->SMTPDebug <= 0) {\n            return;\n        }\n        //Avoid clash with built-in function names\n        if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {\n            call_user_func($this->Debugoutput, $str, $this->SMTPDebug);\n            return;\n        }\n        switch ($this->Debugoutput) {\n            case 'error_log':\n                //Don't output, just log\n                error_log($str);\n                break;\n            case 'html':\n                //Cleans up output a bit for a better looking, HTML-safe output\n                echo htmlentities(\n                    preg_replace('/[\\r\\n]+/', '', $str),\n                    ENT_QUOTES,\n                    'UTF-8'\n                )\n                . \"<br>\\n\";\n                break;\n            case 'echo':\n            default:\n                //Normalize line breaks\n                $str = preg_replace('/\\r\\n?/ms', \"\\n\", $str);\n                echo gmdate('Y-m-d H:i:s') . \"\\t\" . str_replace(\n                    \"\\n\",\n                    \"\\n                   \\t                  \",\n                    trim($str)\n                ) . \"\\n\";\n        }\n    }\n\n    /**\n     * Sets message type to HTML or plain.\n     * @param boolean $isHtml True for HTML mode.\n     * @return void\n     */\n    public function isHTML($isHtml = true)\n    {\n        if ($isHtml) {\n            $this->ContentType = 'text/html';\n        } else {\n            $this->ContentType = 'text/plain';\n        }\n    }\n\n    /**\n     * Send messages using SMTP.\n     * @return void\n     */\n    public function isSMTP()\n    {\n        $this->Mailer = 'smtp';\n    }\n\n    /**\n     * Send messages using PHP's mail() function.\n     * @return void\n     */\n    public function isMail()\n    {\n        $this->Mailer = 'mail';\n    }\n\n    /**\n     * Send messages using $Sendmail.\n     * @return void\n     */\n    public function isSendmail()\n    {\n        $ini_sendmail_path = ini_get('sendmail_path');\n\n        if (!stristr($ini_sendmail_path, 'sendmail')) {\n            $this->Sendmail = '/usr/sbin/sendmail';\n        } else {\n            $this->Sendmail = $ini_sendmail_path;\n        }\n        $this->Mailer = 'sendmail';\n    }\n\n    /**\n     * Send messages using qmail.\n     * @return void\n     */\n    public function isQmail()\n    {\n        $ini_sendmail_path = ini_get('sendmail_path');\n\n        if (!stristr($ini_sendmail_path, 'qmail')) {\n            $this->Sendmail = '/var/qmail/bin/qmail-inject';\n        } else {\n            $this->Sendmail = $ini_sendmail_path;\n        }\n        $this->Mailer = 'qmail';\n    }\n\n    /**\n     * Add a \"To\" address.\n     * @param string $address The email address to send to\n     * @param string $name\n     * @return boolean true on success, false if address already used or invalid in some way\n     */\n    public function addAddress($address, $name = '')\n    {\n        return $this->addOrEnqueueAnAddress('to', $address, $name);\n    }\n\n    /**\n     * Add a \"CC\" address.\n     * @note: This function works with the SMTP mailer on win32, not with the \"mail\" mailer.\n     * @param string $address The email address to send to\n     * @param string $name\n     * @return boolean true on success, false if address already used or invalid in some way\n     */\n    public function addCC($address, $name = '')\n    {\n        return $this->addOrEnqueueAnAddress('cc', $address, $name);\n    }\n\n    /**\n     * Add a \"BCC\" address.\n     * @note: This function works with the SMTP mailer on win32, not with the \"mail\" mailer.\n     * @param string $address The email address to send to\n     * @param string $name\n     * @return boolean true on success, false if address already used or invalid in some way\n     */\n    public function addBCC($address, $name = '')\n    {\n        return $this->addOrEnqueueAnAddress('bcc', $address, $name);\n    }\n\n    /**\n     * Add a \"Reply-To\" address.\n     * @param string $address The email address to reply to\n     * @param string $name\n     * @return boolean true on success, false if address already used or invalid in some way\n     */\n    public function addReplyTo($address, $name = '')\n    {\n        return $this->addOrEnqueueAnAddress('Reply-To', $address, $name);\n    }\n\n    /**\n     * Add an address to one of the recipient arrays or to the ReplyTo array. Because PHPMailer\n     * can't validate addresses with an IDN without knowing the PHPMailer::$CharSet (that can still\n     * be modified after calling this function), addition of such addresses is delayed until send().\n     * Addresses that have been added already return false, but do not throw exceptions.\n     * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'\n     * @param string $address The email address to send, resp. to reply to\n     * @param string $name\n     * @throws phpmailerException\n     * @return boolean true on success, false if address already used or invalid in some way\n     * @access protected\n     */\n    protected function addOrEnqueueAnAddress($kind, $address, $name)\n    {\n        $address = trim($address);\n        $name = trim(preg_replace('/[\\r\\n]+/', '', $name)); //Strip breaks and trim\n        if (($pos = strrpos($address, '@')) === false) {\n            // At-sign is misssing.\n            $error_message = $this->lang('invalid_address') . \" (addAnAddress $kind): $address\";\n            $this->setError($error_message);\n            $this->edebug($error_message);\n            if ($this->exceptions) {\n                throw new phpmailerException($error_message);\n            }\n            return false;\n        }\n        $params = array($kind, $address, $name);\n        // Enqueue addresses with IDN until we know the PHPMailer::$CharSet.\n        if ($this->has8bitChars(substr($address, ++$pos)) and $this->idnSupported()) {\n            if ($kind != 'Reply-To') {\n                if (!array_key_exists($address, $this->RecipientsQueue)) {\n                    $this->RecipientsQueue[$address] = $params;\n                    return true;\n                }\n            } else {\n                if (!array_key_exists($address, $this->ReplyToQueue)) {\n                    $this->ReplyToQueue[$address] = $params;\n                    return true;\n                }\n            }\n            return false;\n        }\n        // Immediately add standard addresses without IDN.\n        return call_user_func_array(array($this, 'addAnAddress'), $params);\n    }\n\n    /**\n     * Add an address to one of the recipient arrays or to the ReplyTo array.\n     * Addresses that have been added already return false, but do not throw exceptions.\n     * @param string $kind One of 'to', 'cc', 'bcc', or 'ReplyTo'\n     * @param string $address The email address to send, resp. to reply to\n     * @param string $name\n     * @throws phpmailerException\n     * @return boolean true on success, false if address already used or invalid in some way\n     * @access protected\n     */\n    protected function addAnAddress($kind, $address, $name = '')\n    {\n        if (!in_array($kind, array('to', 'cc', 'bcc', 'Reply-To'))) {\n            $error_message = $this->lang('Invalid recipient kind: ') . $kind;\n            $this->setError($error_message);\n            $this->edebug($error_message);\n            if ($this->exceptions) {\n                throw new phpmailerException($error_message);\n            }\n            return false;\n        }\n        if (!$this->validateAddress($address)) {\n            $error_message = $this->lang('invalid_address') . \" (addAnAddress $kind): $address\";\n            $this->setError($error_message);\n            $this->edebug($error_message);\n            if ($this->exceptions) {\n                throw new phpmailerException($error_message);\n            }\n            return false;\n        }\n        if ($kind != 'Reply-To') {\n            if (!array_key_exists(strtolower($address), $this->all_recipients)) {\n                array_push($this->$kind, array($address, $name));\n                $this->all_recipients[strtolower($address)] = true;\n                return true;\n            }\n        } else {\n            if (!array_key_exists(strtolower($address), $this->ReplyTo)) {\n                $this->ReplyTo[strtolower($address)] = array($address, $name);\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Parse and validate a string containing one or more RFC822-style comma-separated email addresses\n     * of the form \"display name <address>\" into an array of name/address pairs.\n     * Uses the imap_rfc822_parse_adrlist function if the IMAP extension is available.\n     * Note that quotes in the name part are removed.\n     * @param string $addrstr The address list string\n     * @param bool $useimap Whether to use the IMAP extension to parse the list\n     * @return array\n     * @link http://www.andrew.cmu.edu/user/agreen1/testing/mrbs/web/Mail/RFC822.php A more careful implementation\n     */\n    public function parseAddresses($addrstr, $useimap = true)\n    {\n        $addresses = array();\n        if ($useimap and function_exists('imap_rfc822_parse_adrlist')) {\n            //Use this built-in parser if it's available\n            $list = imap_rfc822_parse_adrlist($addrstr, '');\n            foreach ($list as $address) {\n                if ($address->host != '.SYNTAX-ERROR.') {\n                    if ($this->validateAddress($address->mailbox . '@' . $address->host)) {\n                        $addresses[] = array(\n                            'name' => (property_exists($address, 'personal') ? $address->personal : ''),\n                            'address' => $address->mailbox . '@' . $address->host\n                        );\n                    }\n                }\n            }\n        } else {\n            //Use this simpler parser\n            $list = explode(',', $addrstr);\n            foreach ($list as $address) {\n                $address = trim($address);\n                //Is there a separate name part?\n                if (strpos($address, '<') === false) {\n                    //No separate name, just use the whole thing\n                    if ($this->validateAddress($address)) {\n                        $addresses[] = array(\n                            'name' => '',\n                            'address' => $address\n                        );\n                    }\n                } else {\n                    list($name, $email) = explode('<', $address);\n                    $email = trim(str_replace('>', '', $email));\n                    if ($this->validateAddress($email)) {\n                        $addresses[] = array(\n                            'name' => trim(str_replace(array('\"', \"'\"), '', $name)),\n                            'address' => $email\n                        );\n                    }\n                }\n            }\n        }\n        return $addresses;\n    }\n\n    /**\n     * Set the From and FromName properties.\n     * @param string $address\n     * @param string $name\n     * @param boolean $auto Whether to also set the Sender address, defaults to true\n     * @throws phpmailerException\n     * @return boolean\n     */\n    public function setFrom($address, $name = '', $auto = true)\n    {\n        $address = trim($address);\n        $name = trim(preg_replace('/[\\r\\n]+/', '', $name)); //Strip breaks and trim\n        // Don't validate now addresses with IDN. Will be done in send().\n        if (($pos = strrpos($address, '@')) === false or\n            (!$this->has8bitChars(substr($address, ++$pos)) or !$this->idnSupported()) and\n            !$this->validateAddress($address)) {\n            $error_message = $this->lang('invalid_address') . \" (setFrom) $address\";\n            $this->setError($error_message);\n            $this->edebug($error_message);\n            if ($this->exceptions) {\n                throw new phpmailerException($error_message);\n            }\n            return false;\n        }\n        $this->From = $address;\n        $this->FromName = $name;\n        if ($auto) {\n            if (empty($this->Sender)) {\n                $this->Sender = $address;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * Return the Message-ID header of the last email.\n     * Technically this is the value from the last time the headers were created,\n     * but it's also the message ID of the last sent message except in\n     * pathological cases.\n     * @return string\n     */\n    public function getLastMessageID()\n    {\n        return $this->lastMessageID;\n    }\n\n    /**\n     * Check that a string looks like an email address.\n     * @param string $address The email address to check\n     * @param string|callable $patternselect A selector for the validation pattern to use :\n     * * `auto` Pick best pattern automatically;\n     * * `pcre8` Use the squiloople.com pattern, requires PCRE > 8.0, PHP >= 5.3.2, 5.2.14;\n     * * `pcre` Use old PCRE implementation;\n     * * `php` Use PHP built-in FILTER_VALIDATE_EMAIL;\n     * * `html5` Use the pattern given by the HTML5 spec for 'email' type form input elements.\n     * * `noregex` Don't use a regex: super fast, really dumb.\n     * Alternatively you may pass in a callable to inject your own validator, for example:\n     * PHPMailer::validateAddress('user@example.com', function($address) {\n     *     return (strpos($address, '@') !== false);\n     * });\n     * You can also set the PHPMailer::$validator static to a callable, allowing built-in methods to use your validator.\n     * @return boolean\n     * @static\n     * @access public\n     */\n    public static function validateAddress($address, $patternselect = null)\n    {\n        if (is_null($patternselect)) {\n            $patternselect = self::$validator;\n        }\n        if (is_callable($patternselect)) {\n            return call_user_func($patternselect, $address);\n        }\n        //Reject line breaks in addresses; it's valid RFC5322, but not RFC5321\n        if (strpos($address, \"\\n\") !== false or strpos($address, \"\\r\") !== false) {\n            return false;\n        }\n        if (!$patternselect or $patternselect == 'auto') {\n            //Check this constant first so it works when extension_loaded() is disabled by safe mode\n            //Constant was added in PHP 5.2.4\n            if (defined('PCRE_VERSION')) {\n                //This pattern can get stuck in a recursive loop in PCRE <= 8.0.2\n                if (version_compare(PCRE_VERSION, '8.0.3') >= 0) {\n                    $patternselect = 'pcre8';\n                } else {\n                    $patternselect = 'pcre';\n                }\n            } elseif (function_exists('extension_loaded') and extension_loaded('pcre')) {\n                //Fall back to older PCRE\n                $patternselect = 'pcre';\n            } else {\n                //Filter_var appeared in PHP 5.2.0 and does not require the PCRE extension\n                if (version_compare(PHP_VERSION, '5.2.0') >= 0) {\n                    $patternselect = 'php';\n                } else {\n                    $patternselect = 'noregex';\n                }\n            }\n        }\n        switch ($patternselect) {\n            case 'pcre8':\n                /**\n                 * Uses the same RFC5322 regex on which FILTER_VALIDATE_EMAIL is based, but allows dotless domains.\n                 * @link http://squiloople.com/2009/12/20/email-address-validation/\n                 * @copyright 2009-2010 Michael Rushton\n                 * Feel free to use and redistribute this code. But please keep this copyright notice.\n                 */\n                return (boolean)preg_match(\n                    '/^(?!(?>(?1)\"?(?>\\\\\\[ -~]|[^\"])\"?(?1)){255,})(?!(?>(?1)\"?(?>\\\\\\[ -~]|[^\"])\"?(?1)){65,}@)' .\n                    '((?>(?>(?>((?>(?>(?>\\x0D\\x0A)?[\\t ])+|(?>[\\t ]*\\x0D\\x0A)?[\\t ]+)?)(\\((?>(?2)' .\n                    '(?>[\\x01-\\x08\\x0B\\x0C\\x0E-\\'*-\\[\\]-\\x7F]|\\\\\\[\\x00-\\x7F]|(?3)))*(?2)\\)))+(?2))|(?2))?)' .\n                    '([!#-\\'*+\\/-9=?^-~-]+|\"(?>(?2)(?>[\\x01-\\x08\\x0B\\x0C\\x0E-!#-\\[\\]-\\x7F]|\\\\\\[\\x00-\\x7F]))*' .\n                    '(?2)\")(?>(?1)\\.(?1)(?4))*(?1)@(?!(?1)[a-z0-9-]{64,})(?1)(?>([a-z0-9](?>[a-z0-9-]*[a-z0-9])?)' .\n                    '(?>(?1)\\.(?!(?1)[a-z0-9-]{64,})(?1)(?5)){0,126}|\\[(?:(?>IPv6:(?>([a-f0-9]{1,4})(?>:(?6)){7}' .\n                    '|(?!(?:.*[a-f0-9][:\\]]){8,})((?6)(?>:(?6)){0,6})?::(?7)?))|(?>(?>IPv6:(?>(?6)(?>:(?6)){5}:' .\n                    '|(?!(?:.*[a-f0-9]:){6,})(?8)?::(?>((?6)(?>:(?6)){0,4}):)?))?(25[0-5]|2[0-4][0-9]|1[0-9]{2}' .\n                    '|[1-9]?[0-9])(?>\\.(?9)){3}))\\])(?1)$/isD',\n                    $address\n                );\n            case 'pcre':\n                //An older regex that doesn't need a recent PCRE\n                return (boolean)preg_match(\n                    '/^(?!(?>\"?(?>\\\\\\[ -~]|[^\"])\"?){255,})(?!(?>\"?(?>\\\\\\[ -~]|[^\"])\"?){65,}@)(?>' .\n                    '[!#-\\'*+\\/-9=?^-~-]+|\"(?>(?>[\\x01-\\x08\\x0B\\x0C\\x0E-!#-\\[\\]-\\x7F]|\\\\\\[\\x00-\\xFF]))*\")' .\n                    '(?>\\.(?>[!#-\\'*+\\/-9=?^-~-]+|\"(?>(?>[\\x01-\\x08\\x0B\\x0C\\x0E-!#-\\[\\]-\\x7F]|\\\\\\[\\x00-\\xFF]))*\"))*' .\n                    '@(?>(?![a-z0-9-]{64,})(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)(?>\\.(?![a-z0-9-]{64,})' .\n                    '(?>[a-z0-9](?>[a-z0-9-]*[a-z0-9])?)){0,126}|\\[(?:(?>IPv6:(?>(?>[a-f0-9]{1,4})(?>:' .\n                    '[a-f0-9]{1,4}){7}|(?!(?:.*[a-f0-9][:\\]]){8,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?' .\n                    '::(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,6})?))|(?>(?>IPv6:(?>[a-f0-9]{1,4}(?>:' .\n                    '[a-f0-9]{1,4}){5}:|(?!(?:.*[a-f0-9]:){6,})(?>[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4})?' .\n                    '::(?>(?:[a-f0-9]{1,4}(?>:[a-f0-9]{1,4}){0,4}):)?))?(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}' .\n                    '|[1-9]?[0-9])(?>\\.(?>25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}))\\])$/isD',\n                    $address\n                );\n            case 'html5':\n                /**\n                 * This is the pattern used in the HTML5 spec for validation of 'email' type form input elements.\n                 * @link http://www.whatwg.org/specs/web-apps/current-work/#e-mail-state-(type=email)\n                 */\n                return (boolean)preg_match(\n                    '/^[a-zA-Z0-9.!#$%&\\'*+\\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}' .\n                    '[a-zA-Z0-9])?(?:\\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/sD',\n                    $address\n                );\n            case 'noregex':\n                //No PCRE! Do something _very_ approximate!\n                //Check the address is 3 chars or longer and contains an @ that's not the first or last char\n                return (strlen($address) >= 3\n                    and strpos($address, '@') >= 1\n                    and strpos($address, '@') != strlen($address) - 1);\n            case 'php':\n            default:\n                return (boolean)filter_var($address, FILTER_VALIDATE_EMAIL);\n        }\n    }\n\n    /**\n     * Tells whether IDNs (Internationalized Domain Names) are supported or not. This requires the\n     * \"intl\" and \"mbstring\" PHP extensions.\n     * @return bool \"true\" if required functions for IDN support are present\n     */\n    public function idnSupported()\n    {\n        // @TODO: Write our own \"idn_to_ascii\" function for PHP <= 5.2.\n        return function_exists('idn_to_ascii') and function_exists('mb_convert_encoding');\n    }\n\n    /**\n     * Converts IDN in given email address to its ASCII form, also known as punycode, if possible.\n     * Important: Address must be passed in same encoding as currently set in PHPMailer::$CharSet.\n     * This function silently returns unmodified address if:\n     * - No conversion is necessary (i.e. domain name is not an IDN, or is already in ASCII form)\n     * - Conversion to punycode is impossible (e.g. required PHP functions are not available)\n     *   or fails for any reason (e.g. domain has characters not allowed in an IDN)\n     * @see PHPMailer::$CharSet\n     * @param string $address The email address to convert\n     * @return string The encoded address in ASCII form\n     */\n    public function punyencodeAddress($address)\n    {\n        // Verify we have required functions, CharSet, and at-sign.\n        if ($this->idnSupported() and\n            !empty($this->CharSet) and\n            ($pos = strrpos($address, '@')) !== false) {\n            $domain = substr($address, ++$pos);\n            // Verify CharSet string is a valid one, and domain properly encoded in this CharSet.\n            if ($this->has8bitChars($domain) and @mb_check_encoding($domain, $this->CharSet)) {\n                $domain = mb_convert_encoding($domain, 'UTF-8', $this->CharSet);\n                if (($punycode = defined('INTL_IDNA_VARIANT_UTS46') ?\n                    idn_to_ascii($domain, 0, INTL_IDNA_VARIANT_UTS46) :\n                    idn_to_ascii($domain)) !== false) {\n                    return substr($address, 0, $pos) . $punycode;\n                }\n            }\n        }\n        return $address;\n    }\n\n    /**\n     * Create a message and send it.\n     * Uses the sending method specified by $Mailer.\n     * @throws phpmailerException\n     * @return boolean false on error - See the ErrorInfo property for details of the error.\n     */\n    public function send()\n    {\n        try {\n            if (!$this->preSend()) {\n                return false;\n            }\n            return $this->postSend();\n        } catch (phpmailerException $exc) {\n            $this->mailHeader = '';\n            $this->setError($exc->getMessage());\n            if ($this->exceptions) {\n                throw $exc;\n            }\n            return false;\n        }\n    }\n\n    /**\n     * Prepare a message for sending.\n     * @throws phpmailerException\n     * @return boolean\n     */\n    public function preSend()\n    {\n        try {\n            $this->error_count = 0; // Reset errors\n            $this->mailHeader = '';\n\n            // Dequeue recipient and Reply-To addresses with IDN\n            foreach (array_merge($this->RecipientsQueue, $this->ReplyToQueue) as $params) {\n                $params[1] = $this->punyencodeAddress($params[1]);\n                call_user_func_array(array($this, 'addAnAddress'), $params);\n            }\n            if ((count($this->to) + count($this->cc) + count($this->bcc)) < 1) {\n                throw new phpmailerException($this->lang('provide_address'), self::STOP_CRITICAL);\n            }\n\n            // Validate From, Sender, and ConfirmReadingTo addresses\n            foreach (array('From', 'Sender', 'ConfirmReadingTo') as $address_kind) {\n                $this->$address_kind = trim($this->$address_kind);\n                if (empty($this->$address_kind)) {\n                    continue;\n                }\n                $this->$address_kind = $this->punyencodeAddress($this->$address_kind);\n                if (!$this->validateAddress($this->$address_kind)) {\n                    $error_message = $this->lang('invalid_address') . ' (punyEncode) ' . $this->$address_kind;\n                    $this->setError($error_message);\n                    $this->edebug($error_message);\n                    if ($this->exceptions) {\n                        throw new phpmailerException($error_message);\n                    }\n                    return false;\n                }\n            }\n\n            // Set whether the message is multipart/alternative\n            if ($this->alternativeExists()) {\n                $this->ContentType = 'multipart/alternative';\n            }\n\n            $this->setMessageType();\n            // Refuse to send an empty message unless we are specifically allowing it\n            if (!$this->AllowEmpty and empty($this->Body)) {\n                throw new phpmailerException($this->lang('empty_message'), self::STOP_CRITICAL);\n            }\n\n            // Create body before headers in case body makes changes to headers (e.g. altering transfer encoding)\n            $this->MIMEHeader = '';\n            $this->MIMEBody = $this->createBody();\n            // createBody may have added some headers, so retain them\n            $tempheaders = $this->MIMEHeader;\n            $this->MIMEHeader = $this->createHeader();\n            $this->MIMEHeader .= $tempheaders;\n\n            // To capture the complete message when using mail(), create\n            // an extra header list which createHeader() doesn't fold in\n            if ($this->Mailer == 'mail') {\n                if (count($this->to) > 0) {\n                    $this->mailHeader .= $this->addrAppend('To', $this->to);\n                } else {\n                    $this->mailHeader .= $this->headerLine('To', 'undisclosed-recipients:;');\n                }\n                $this->mailHeader .= $this->headerLine(\n                    'Subject',\n                    $this->encodeHeader($this->secureHeader(trim($this->Subject)))\n                );\n            }\n\n            // Sign with DKIM if enabled\n            if (!empty($this->DKIM_domain)\n                && !empty($this->DKIM_selector)\n                && (!empty($this->DKIM_private_string)\n                   || (!empty($this->DKIM_private) && file_exists($this->DKIM_private))\n                )\n            ) {\n                $header_dkim = $this->DKIM_Add(\n                    $this->MIMEHeader . $this->mailHeader,\n                    $this->encodeHeader($this->secureHeader($this->Subject)),\n                    $this->MIMEBody\n                );\n                $this->MIMEHeader = rtrim($this->MIMEHeader, \"\\r\\n \") . self::CRLF .\n                    str_replace(\"\\r\\n\", \"\\n\", $header_dkim) . self::CRLF;\n            }\n            return true;\n        } catch (phpmailerException $exc) {\n            $this->setError($exc->getMessage());\n            if ($this->exceptions) {\n                throw $exc;\n            }\n            return false;\n        }\n    }\n\n    /**\n     * Actually send a message.\n     * Send the email via the selected mechanism\n     * @throws phpmailerException\n     * @return boolean\n     */\n    public function postSend()\n    {\n        try {\n            // Choose the mailer and send through it\n            switch ($this->Mailer) {\n                case 'sendmail':\n                case 'qmail':\n                    return $this->sendmailSend($this->MIMEHeader, $this->MIMEBody);\n                case 'smtp':\n                    return $this->smtpSend($this->MIMEHeader, $this->MIMEBody);\n                case 'mail':\n                    return $this->mailSend($this->MIMEHeader, $this->MIMEBody);\n                default:\n                    $sendMethod = $this->Mailer.'Send';\n                    if (method_exists($this, $sendMethod)) {\n                        return $this->$sendMethod($this->MIMEHeader, $this->MIMEBody);\n                    }\n\n                    return $this->mailSend($this->MIMEHeader, $this->MIMEBody);\n            }\n        } catch (phpmailerException $exc) {\n            $this->setError($exc->getMessage());\n            $this->edebug($exc->getMessage());\n            if ($this->exceptions) {\n                throw $exc;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Send mail using the $Sendmail program.\n     * @param string $header The message headers\n     * @param string $body The message body\n     * @see PHPMailer::$Sendmail\n     * @throws phpmailerException\n     * @access protected\n     * @return boolean\n     */\n    protected function sendmailSend($header, $body)\n    {\n        // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.\n        if (!empty($this->Sender) and self::isShellSafe($this->Sender)) {\n            if ($this->Mailer == 'qmail') {\n                $sendmailFmt = '%s -f%s';\n            } else {\n                $sendmailFmt = '%s -oi -f%s -t';\n            }\n        } else {\n            if ($this->Mailer == 'qmail') {\n                $sendmailFmt = '%s';\n            } else {\n                $sendmailFmt = '%s -oi -t';\n            }\n        }\n\n        // TODO: If possible, this should be changed to escapeshellarg.  Needs thorough testing.\n        $sendmail = sprintf($sendmailFmt, escapeshellcmd($this->Sendmail), $this->Sender);\n\n        if ($this->SingleTo) {\n            foreach ($this->SingleToArray as $toAddr) {\n                if (!@$mail = popen($sendmail, 'w')) {\n                    throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);\n                }\n                fputs($mail, 'To: ' . $toAddr . \"\\n\");\n                fputs($mail, $header);\n                fputs($mail, $body);\n                $result = pclose($mail);\n                $this->doCallback(\n                    ($result == 0),\n                    array($toAddr),\n                    $this->cc,\n                    $this->bcc,\n                    $this->Subject,\n                    $body,\n                    $this->From\n                );\n                if ($result != 0) {\n                    throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);\n                }\n            }\n        } else {\n            if (!@$mail = popen($sendmail, 'w')) {\n                throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);\n            }\n            fputs($mail, $header);\n            fputs($mail, $body);\n            $result = pclose($mail);\n            $this->doCallback(\n                ($result == 0),\n                $this->to,\n                $this->cc,\n                $this->bcc,\n                $this->Subject,\n                $body,\n                $this->From\n            );\n            if ($result != 0) {\n                throw new phpmailerException($this->lang('execute') . $this->Sendmail, self::STOP_CRITICAL);\n            }\n        }\n        return true;\n    }\n\n    /**\n     * Fix CVE-2016-10033 and CVE-2016-10045 by disallowing potentially unsafe shell characters.\n     *\n     * Note that escapeshellarg and escapeshellcmd are inadequate for our purposes, especially on Windows.\n     * @param string $string The string to be validated\n     * @see https://github.com/PHPMailer/PHPMailer/issues/924 CVE-2016-10045 bug report\n     * @access protected\n     * @return boolean\n     */\n    protected static function isShellSafe($string)\n    {\n        // Future-proof\n        if (escapeshellcmd($string) !== $string\n            or !in_array(escapeshellarg($string), array(\"'$string'\", \"\\\"$string\\\"\"))\n        ) {\n            return false;\n        }\n\n        $length = strlen($string);\n\n        for ($i = 0; $i < $length; $i++) {\n            $c = $string[$i];\n\n            // All other characters have a special meaning in at least one common shell, including = and +.\n            // Full stop (.) has a special meaning in cmd.exe, but its impact should be negligible here.\n            // Note that this does permit non-Latin alphanumeric characters based on the current locale.\n            if (!ctype_alnum($c) && strpos('@_-.', $c) === false) {\n                return false;\n            }\n        }\n\n        return true;\n    }\n\n    /**\n     * Send mail using the PHP mail() function.\n     * @param string $header The message headers\n     * @param string $body The message body\n     * @link http://www.php.net/manual/en/book.mail.php\n     * @throws phpmailerException\n     * @access protected\n     * @return boolean\n     */\n    protected function mailSend($header, $body)\n    {\n        $toArr = array();\n        foreach ($this->to as $toaddr) {\n            $toArr[] = $this->addrFormat($toaddr);\n        }\n        $to = implode(', ', $toArr);\n\n        $params = null;\n        //This sets the SMTP envelope sender which gets turned into a return-path header by the receiver\n        if (!empty($this->Sender) and $this->validateAddress($this->Sender)) {\n            // CVE-2016-10033, CVE-2016-10045: Don't pass -f if characters will be escaped.\n            if (self::isShellSafe($this->Sender)) {\n                $params = sprintf('-f%s', $this->Sender);\n            }\n        }\n        if (!empty($this->Sender) and !ini_get('safe_mode') and $this->validateAddress($this->Sender)) {\n            $old_from = ini_get('sendmail_from');\n            ini_set('sendmail_from', $this->Sender);\n        }\n        $result = false;\n        if ($this->SingleTo and count($toArr) > 1) {\n            foreach ($toArr as $toAddr) {\n                $result = $this->mailPassthru($toAddr, $this->Subject, $body, $header, $params);\n                $this->doCallback($result, array($toAddr), $this->cc, $this->bcc, $this->Subject, $body, $this->From);\n            }\n        } else {\n            $result = $this->mailPassthru($to, $this->Subject, $body, $header, $params);\n            $this->doCallback($result, $this->to, $this->cc, $this->bcc, $this->Subject, $body, $this->From);\n        }\n        if (isset($old_from)) {\n            ini_set('sendmail_from', $old_from);\n        }\n        if (!$result) {\n            throw new phpmailerException($this->lang('instantiate'), self::STOP_CRITICAL);\n        }\n        return true;\n    }\n\n    /**\n     * Get an instance to use for SMTP operations.\n     * Override this function to load your own SMTP implementation\n     * @return SMTP\n     */\n    public function getSMTPInstance()\n    {\n        if (!is_object($this->smtp)) {\n            $this->smtp = new SMTP;\n        }\n        return $this->smtp;\n    }\n\n    /**\n     * Send mail via SMTP.\n     * Returns false if there is a bad MAIL FROM, RCPT, or DATA input.\n     * Uses the PHPMailerSMTP class by default.\n     * @see PHPMailer::getSMTPInstance() to use a different class.\n     * @param string $header The message headers\n     * @param string $body The message body\n     * @throws phpmailerException\n     * @uses SMTP\n     * @access protected\n     * @return boolean\n     */\n    protected function smtpSend($header, $body)\n    {\n        $bad_rcpt = array();\n        if (!$this->smtpConnect($this->SMTPOptions)) {\n            throw new phpmailerException($this->lang('smtp_connect_failed'), self::STOP_CRITICAL);\n        }\n        if (!empty($this->Sender) and $this->validateAddress($this->Sender)) {\n            $smtp_from = $this->Sender;\n        } else {\n            $smtp_from = $this->From;\n        }\n        if (!$this->smtp->mail($smtp_from)) {\n            $this->setError($this->lang('from_failed') . $smtp_from . ' : ' . implode(',', $this->smtp->getError()));\n            throw new phpmailerException($this->ErrorInfo, self::STOP_CRITICAL);\n        }\n\n        // Attempt to send to all recipients\n        foreach (array($this->to, $this->cc, $this->bcc) as $togroup) {\n            foreach ($togroup as $to) {\n                if (!$this->smtp->recipient($to[0])) {\n                    $error = $this->smtp->getError();\n                    $bad_rcpt[] = array('to' => $to[0], 'error' => $error['detail']);\n                    $isSent = false;\n                } else {\n                    $isSent = true;\n                }\n                $this->doCallback($isSent, array($to[0]), array(), array(), $this->Subject, $body, $this->From);\n            }\n        }\n\n        // Only send the DATA command if we have viable recipients\n        if ((count($this->all_recipients) > count($bad_rcpt)) and !$this->smtp->data($header . $body)) {\n            throw new phpmailerException($this->lang('data_not_accepted'), self::STOP_CRITICAL);\n        }\n        if ($this->SMTPKeepAlive) {\n            $this->smtp->reset();\n        } else {\n            $this->smtp->quit();\n            $this->smtp->close();\n        }\n        //Create error message for any bad addresses\n        if (count($bad_rcpt) > 0) {\n            $errstr = '';\n            foreach ($bad_rcpt as $bad) {\n                $errstr .= $bad['to'] . ': ' . $bad['error'];\n            }\n            throw new phpmailerException(\n                $this->lang('recipients_failed') . $errstr,\n                self::STOP_CONTINUE\n            );\n        }\n        return true;\n    }\n\n    /**\n     * Initiate a connection to an SMTP server.\n     * Returns false if the operation failed.\n     * @param array $options An array of options compatible with stream_context_create()\n     * @uses SMTP\n     * @access public\n     * @throws phpmailerException\n     * @return boolean\n     */\n    public function smtpConnect($options = null)\n    {\n        if (is_null($this->smtp)) {\n            $this->smtp = $this->getSMTPInstance();\n        }\n\n        //If no options are provided, use whatever is set in the instance\n        if (is_null($options)) {\n            $options = $this->SMTPOptions;\n        }\n\n        // Already connected?\n        if ($this->smtp->connected()) {\n            return true;\n        }\n\n        $this->smtp->setTimeout($this->Timeout);\n        $this->smtp->setDebugLevel($this->SMTPDebug);\n        $this->smtp->setDebugOutput($this->Debugoutput);\n        $this->smtp->setVerp($this->do_verp);\n        $hosts = explode(';', $this->Host);\n        $lastexception = null;\n\n        foreach ($hosts as $hostentry) {\n            $hostinfo = array();\n            if (!preg_match('/^((ssl|tls):\\/\\/)*([a-zA-Z0-9\\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {\n                // Not a valid host entry\n                continue;\n            }\n            // $hostinfo[2]: optional ssl or tls prefix\n            // $hostinfo[3]: the hostname\n            // $hostinfo[4]: optional port number\n            // The host string prefix can temporarily override the current setting for SMTPSecure\n            // If it's not specified, the default value is used\n            $prefix = '';\n            $secure = $this->SMTPSecure;\n            $tls = ($this->SMTPSecure == 'tls');\n            if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {\n                $prefix = 'ssl://';\n                $tls = false; // Can't have SSL and TLS at the same time\n                $secure = 'ssl';\n            } elseif ($hostinfo[2] == 'tls') {\n                $tls = true;\n                // tls doesn't use a prefix\n                $secure = 'tls';\n            }\n            //Do we need the OpenSSL extension?\n            $sslext = defined('OPENSSL_ALGO_SHA1');\n            if ('tls' === $secure or 'ssl' === $secure) {\n                //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled\n                if (!$sslext) {\n                    throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL);\n                }\n            }\n            $host = $hostinfo[3];\n            $port = $this->Port;\n            $tport = (integer)$hostinfo[4];\n            if ($tport > 0 and $tport < 65536) {\n                $port = $tport;\n            }\n            if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {\n                try {\n                    if ($this->Helo) {\n                        $hello = $this->Helo;\n                    } else {\n                        $hello = $this->serverHostname();\n                    }\n                    $this->smtp->hello($hello);\n                    //Automatically enable TLS encryption if:\n                    // * it's not disabled\n                    // * we have openssl extension\n                    // * we are not already using SSL\n                    // * the server offers STARTTLS\n                    if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {\n                        $tls = true;\n                    }\n                    if ($tls) {\n                        if (!$this->smtp->startTLS()) {\n                            throw new phpmailerException($this->lang('connect_host'));\n                        }\n                        // We must resend EHLO after TLS negotiation\n                        $this->smtp->hello($hello);\n                    }\n                    if ($this->SMTPAuth) {\n                        if (!$this->smtp->authenticate(\n                            $this->Username,\n                            $this->Password,\n                            $this->AuthType,\n                            $this->Realm,\n                            $this->Workstation\n                        )\n                        ) {\n                            throw new phpmailerException($this->lang('authenticate'));\n                        }\n                    }\n                    return true;\n                } catch (phpmailerException $exc) {\n                    $lastexception = $exc;\n                    $this->edebug($exc->getMessage());\n                    // We must have connected, but then failed TLS or Auth, so close connection nicely\n                    $this->smtp->quit();\n                }\n            }\n        }\n        // If we get here, all connection attempts have failed, so close connection hard\n        $this->smtp->close();\n        // As we've caught all exceptions, just report whatever the last one was\n        if ($this->exceptions and !is_null($lastexception)) {\n            throw $lastexception;\n        }\n        return false;\n    }\n\n    /**\n     * Close the active SMTP session if one exists.\n     * @return void\n     */\n    public function smtpClose()\n    {\n        if (is_a($this->smtp, 'SMTP')) {\n            if ($this->smtp->connected()) {\n                $this->smtp->quit();\n                $this->smtp->close();\n            }\n        }\n    }\n\n    /**\n     * Set the language for error messages.\n     * Returns false if it cannot load the language file.\n     * The default language is English.\n     * @param string $langcode ISO 639-1 2-character language code (e.g. French is \"fr\")\n     * @param string $lang_path Path to the language file directory, with trailing separator (slash)\n     * @return boolean\n     * @access public\n     */\n    public function setLanguage($langcode = 'en', $lang_path = '')\n    {\n        // Backwards compatibility for renamed language codes\n        $renamed_langcodes = array(\n            'br' => 'pt_br',\n            'cz' => 'cs',\n            'dk' => 'da',\n            'no' => 'nb',\n            'se' => 'sv',\n        );\n\n        if (isset($renamed_langcodes[$langcode])) {\n            $langcode = $renamed_langcodes[$langcode];\n        }\n\n        // Define full set of translatable strings in English\n        $PHPMAILER_LANG = array(\n            'authenticate' => 'SMTP Error: Could not authenticate.',\n            'connect_host' => 'SMTP Error: Could not connect to SMTP host.',\n            'data_not_accepted' => 'SMTP Error: data not accepted.',\n            'empty_message' => 'Message body empty',\n            'encoding' => 'Unknown encoding: ',\n            'execute' => 'Could not execute: ',\n            'file_access' => 'Could not access file: ',\n            'file_open' => 'File Error: Could not open file: ',\n            'from_failed' => 'The following From address failed: ',\n            'instantiate' => 'Could not instantiate mail function.',\n            'invalid_address' => 'Invalid address: ',\n            'mailer_not_supported' => ' mailer is not supported.',\n            'provide_address' => 'You must provide at least one recipient email address.',\n            'recipients_failed' => 'SMTP Error: The following recipients failed: ',\n            'signing' => 'Signing Error: ',\n            'smtp_connect_failed' => 'SMTP connect() failed.',\n            'smtp_error' => 'SMTP server error: ',\n            'variable_set' => 'Cannot set or reset variable: ',\n            'extension_missing' => 'Extension missing: '\n        );\n        if (empty($lang_path)) {\n            // Calculate an absolute path so it can work if CWD is not here\n            $lang_path = dirname(__FILE__). DIRECTORY_SEPARATOR . 'language'. DIRECTORY_SEPARATOR;\n        }\n        //Validate $langcode\n        if (!preg_match('/^[a-z]{2}(?:_[a-zA-Z]{2})?$/', $langcode)) {\n            $langcode = 'en';\n        }\n        $foundlang = true;\n        $lang_file = $lang_path . 'phpmailer.lang-' . $langcode . '.php';\n        // There is no English translation file\n        if ($langcode != 'en') {\n            // Make sure language file path is readable\n            if (!is_readable($lang_file)) {\n                $foundlang = false;\n            } else {\n                // Overwrite language-specific strings.\n                // This way we'll never have missing translation keys.\n                $foundlang = include $lang_file;\n            }\n        }\n        $this->language = $PHPMAILER_LANG;\n        return (boolean)$foundlang; // Returns false if language not found\n    }\n\n    /**\n     * Get the array of strings for the current language.\n     * @return array\n     */\n    public function getTranslations()\n    {\n        return $this->language;\n    }\n\n    /**\n     * Create recipient headers.\n     * @access public\n     * @param string $type\n     * @param array $addr An array of recipient,\n     * where each recipient is a 2-element indexed array with element 0 containing an address\n     * and element 1 containing a name, like:\n     * array(array('joe@example.com', 'Joe User'), array('zoe@example.com', 'Zoe User'))\n     * @return string\n     */\n    public function addrAppend($type, $addr)\n    {\n        $addresses = array();\n        foreach ($addr as $address) {\n            $addresses[] = $this->addrFormat($address);\n        }\n        return $type . ': ' . implode(', ', $addresses) . $this->LE;\n    }\n\n    /**\n     * Format an address for use in a message header.\n     * @access public\n     * @param array $addr A 2-element indexed array, element 0 containing an address, element 1 containing a name\n     *      like array('joe@example.com', 'Joe User')\n     * @return string\n     */\n    public function addrFormat($addr)\n    {\n        if (empty($addr[1])) { // No name provided\n            return $this->secureHeader($addr[0]);\n        } else {\n            return $this->encodeHeader($this->secureHeader($addr[1]), 'phrase') . ' <' . $this->secureHeader(\n                $addr[0]\n            ) . '>';\n        }\n    }\n\n    /**\n     * Word-wrap message.\n     * For use with mailers that do not automatically perform wrapping\n     * and for quoted-printable encoded messages.\n     * Original written by philippe.\n     * @param string $message The message to wrap\n     * @param integer $length The line length to wrap to\n     * @param boolean $qp_mode Whether to run in Quoted-Printable mode\n     * @access public\n     * @return string\n     */\n    public function wrapText($message, $length, $qp_mode = false)\n    {\n        if ($qp_mode) {\n            $soft_break = sprintf(' =%s', $this->LE);\n        } else {\n            $soft_break = $this->LE;\n        }\n        // If utf-8 encoding is used, we will need to make sure we don't\n        // split multibyte characters when we wrap\n        $is_utf8 = (strtolower($this->CharSet) == 'utf-8');\n        $lelen = strlen($this->LE);\n        $crlflen = strlen(self::CRLF);\n\n        $message = $this->fixEOL($message);\n        //Remove a trailing line break\n        if (substr($message, -$lelen) == $this->LE) {\n            $message = substr($message, 0, -$lelen);\n        }\n\n        //Split message into lines\n        $lines = explode($this->LE, $message);\n        //Message will be rebuilt in here\n        $message = '';\n        foreach ($lines as $line) {\n            $words = explode(' ', $line);\n            $buf = '';\n            $firstword = true;\n            foreach ($words as $word) {\n                if ($qp_mode and (strlen($word) > $length)) {\n                    $space_left = $length - strlen($buf) - $crlflen;\n                    if (!$firstword) {\n                        if ($space_left > 20) {\n                            $len = $space_left;\n                            if ($is_utf8) {\n                                $len = $this->utf8CharBoundary($word, $len);\n                            } elseif (substr($word, $len - 1, 1) == '=') {\n                                $len--;\n                            } elseif (substr($word, $len - 2, 1) == '=') {\n                                $len -= 2;\n                            }\n                            $part = substr($word, 0, $len);\n                            $word = substr($word, $len);\n                            $buf .= ' ' . $part;\n                            $message .= $buf . sprintf('=%s', self::CRLF);\n                        } else {\n                            $message .= $buf . $soft_break;\n                        }\n                        $buf = '';\n                    }\n                    while (strlen($word) > 0) {\n                        if ($length <= 0) {\n                            break;\n                        }\n                        $len = $length;\n                        if ($is_utf8) {\n                            $len = $this->utf8CharBoundary($word, $len);\n                        } elseif (substr($word, $len - 1, 1) == '=') {\n                            $len--;\n                        } elseif (substr($word, $len - 2, 1) == '=') {\n                            $len -= 2;\n                        }\n                        $part = substr($word, 0, $len);\n                        $word = substr($word, $len);\n\n                        if (strlen($word) > 0) {\n                            $message .= $part . sprintf('=%s', self::CRLF);\n                        } else {\n                            $buf = $part;\n                        }\n                    }\n                } else {\n                    $buf_o = $buf;\n                    if (!$firstword) {\n                        $buf .= ' ';\n                    }\n                    $buf .= $word;\n\n                    if (strlen($buf) > $length and $buf_o != '') {\n                        $message .= $buf_o . $soft_break;\n                        $buf = $word;\n                    }\n                }\n                $firstword = false;\n            }\n            $message .= $buf . self::CRLF;\n        }\n\n        return $message;\n    }\n\n    /**\n     * Find the last character boundary prior to $maxLength in a utf-8\n     * quoted-printable encoded string.\n     * Original written by Colin Brown.\n     * @access public\n     * @param string $encodedText utf-8 QP text\n     * @param integer $maxLength Find the last character boundary prior to this length\n     * @return integer\n     */\n    public function utf8CharBoundary($encodedText, $maxLength)\n    {\n        $foundSplitPos = false;\n        $lookBack = 3;\n        while (!$foundSplitPos) {\n            $lastChunk = substr($encodedText, $maxLength - $lookBack, $lookBack);\n            $encodedCharPos = strpos($lastChunk, '=');\n            if (false !== $encodedCharPos) {\n                // Found start of encoded character byte within $lookBack block.\n                // Check the encoded byte value (the 2 chars after the '=')\n                $hex = substr($encodedText, $maxLength - $lookBack + $encodedCharPos + 1, 2);\n                $dec = hexdec($hex);\n                if ($dec < 128) {\n                    // Single byte character.\n                    // If the encoded char was found at pos 0, it will fit\n                    // otherwise reduce maxLength to start of the encoded char\n                    if ($encodedCharPos > 0) {\n                        $maxLength = $maxLength - ($lookBack - $encodedCharPos);\n                    }\n                    $foundSplitPos = true;\n                } elseif ($dec >= 192) {\n                    // First byte of a multi byte character\n                    // Reduce maxLength to split at start of character\n                    $maxLength = $maxLength - ($lookBack - $encodedCharPos);\n                    $foundSplitPos = true;\n                } elseif ($dec < 192) {\n                    // Middle byte of a multi byte character, look further back\n                    $lookBack += 3;\n                }\n            } else {\n                // No encoded character found\n                $foundSplitPos = true;\n            }\n        }\n        return $maxLength;\n    }\n\n    /**\n     * Apply word wrapping to the message body.\n     * Wraps the message body to the number of chars set in the WordWrap property.\n     * You should only do this to plain-text bodies as wrapping HTML tags may break them.\n     * This is called automatically by createBody(), so you don't need to call it yourself.\n     * @access public\n     * @return void\n     */\n    public function setWordWrap()\n    {\n        if ($this->WordWrap < 1) {\n            return;\n        }\n\n        switch ($this->message_type) {\n            case 'alt':\n            case 'alt_inline':\n            case 'alt_attach':\n            case 'alt_inline_attach':\n                $this->AltBody = $this->wrapText($this->AltBody, $this->WordWrap);\n                break;\n            default:\n                $this->Body = $this->wrapText($this->Body, $this->WordWrap);\n                break;\n        }\n    }\n\n    /**\n     * Assemble message headers.\n     * @access public\n     * @return string The assembled headers\n     */\n    public function createHeader()\n    {\n        $result = '';\n\n        if ($this->MessageDate == '') {\n            $this->MessageDate = self::rfcDate();\n        }\n        $result .= $this->headerLine('Date', $this->MessageDate);\n\n        // To be created automatically by mail()\n        if ($this->SingleTo) {\n            if ($this->Mailer != 'mail') {\n                foreach ($this->to as $toaddr) {\n                    $this->SingleToArray[] = $this->addrFormat($toaddr);\n                }\n            }\n        } else {\n            if (count($this->to) > 0) {\n                if ($this->Mailer != 'mail') {\n                    $result .= $this->addrAppend('To', $this->to);\n                }\n            } elseif (count($this->cc) == 0) {\n                $result .= $this->headerLine('To', 'undisclosed-recipients:;');\n            }\n        }\n\n        $result .= $this->addrAppend('From', array(array(trim($this->From), $this->FromName)));\n\n        // sendmail and mail() extract Cc from the header before sending\n        if (count($this->cc) > 0) {\n            $result .= $this->addrAppend('Cc', $this->cc);\n        }\n\n        // sendmail and mail() extract Bcc from the header before sending\n        if ((\n                $this->Mailer == 'sendmail' or $this->Mailer == 'qmail' or $this->Mailer == 'mail'\n            )\n            and count($this->bcc) > 0\n        ) {\n            $result .= $this->addrAppend('Bcc', $this->bcc);\n        }\n\n        if (count($this->ReplyTo) > 0) {\n            $result .= $this->addrAppend('Reply-To', $this->ReplyTo);\n        }\n\n        // mail() sets the subject itself\n        if ($this->Mailer != 'mail') {\n            $result .= $this->headerLine('Subject', $this->encodeHeader($this->secureHeader($this->Subject)));\n        }\n\n        // Only allow a custom message ID if it conforms to RFC 5322 section 3.6.4\n        // https://tools.ietf.org/html/rfc5322#section-3.6.4\n        if ('' != $this->MessageID and preg_match('/^<.*@.*>$/', $this->MessageID)) {\n            $this->lastMessageID = $this->MessageID;\n        } else {\n            $this->lastMessageID = sprintf('<%s@%s>', $this->uniqueid, $this->serverHostname());\n        }\n        $result .= $this->headerLine('Message-ID', $this->lastMessageID);\n        if (!is_null($this->Priority)) {\n            $result .= $this->headerLine('X-Priority', $this->Priority);\n        }\n        if ($this->XMailer == '') {\n            $result .= $this->headerLine(\n                'X-Mailer',\n                'PHPMailer ' . $this->Version . ' (https://github.com/PHPMailer/PHPMailer)'\n            );\n        } else {\n            $myXmailer = trim($this->XMailer);\n            if ($myXmailer) {\n                $result .= $this->headerLine('X-Mailer', $myXmailer);\n            }\n        }\n\n        if ($this->ConfirmReadingTo != '') {\n            $result .= $this->headerLine('Disposition-Notification-To', '<' . $this->ConfirmReadingTo . '>');\n        }\n\n        // Add custom headers\n        foreach ($this->CustomHeader as $header) {\n            $result .= $this->headerLine(\n                trim($header[0]),\n                $this->encodeHeader(trim($header[1]))\n            );\n        }\n        if (!$this->sign_key_file) {\n            $result .= $this->headerLine('MIME-Version', '1.0');\n            $result .= $this->getMailMIME();\n        }\n\n        return $result;\n    }\n\n    /**\n     * Get the message MIME type headers.\n     * @access public\n     * @return string\n     */\n    public function getMailMIME()\n    {\n        $result = '';\n        $ismultipart = true;\n        switch ($this->message_type) {\n            case 'inline':\n                $result .= $this->headerLine('Content-Type', 'multipart/related;');\n                $result .= $this->textLine(\"\\tboundary=\\\"\" . $this->boundary[1] . '\"');\n                break;\n            case 'attach':\n            case 'inline_attach':\n            case 'alt_attach':\n            case 'alt_inline_attach':\n                $result .= $this->headerLine('Content-Type', 'multipart/mixed;');\n                $result .= $this->textLine(\"\\tboundary=\\\"\" . $this->boundary[1] . '\"');\n                break;\n            case 'alt':\n            case 'alt_inline':\n                $result .= $this->headerLine('Content-Type', 'multipart/alternative;');\n                $result .= $this->textLine(\"\\tboundary=\\\"\" . $this->boundary[1] . '\"');\n                break;\n            default:\n                // Catches case 'plain': and case '':\n                $result .= $this->textLine('Content-Type: ' . $this->ContentType . '; charset=' . $this->CharSet);\n                $ismultipart = false;\n                break;\n        }\n        // RFC1341 part 5 says 7bit is assumed if not specified\n        if ($this->Encoding != '7bit') {\n            // RFC 2045 section 6.4 says multipart MIME parts may only use 7bit, 8bit or binary CTE\n            if ($ismultipart) {\n                if ($this->Encoding == '8bit') {\n                    $result .= $this->headerLine('Content-Transfer-Encoding', '8bit');\n                }\n                // The only remaining alternatives are quoted-printable and base64, which are both 7bit compatible\n            } else {\n                $result .= $this->headerLine('Content-Transfer-Encoding', $this->Encoding);\n            }\n        }\n\n        if ($this->Mailer != 'mail') {\n            $result .= $this->LE;\n        }\n\n        return $result;\n    }\n\n    /**\n     * Returns the whole MIME message.\n     * Includes complete headers and body.\n     * Only valid post preSend().\n     * @see PHPMailer::preSend()\n     * @access public\n     * @return string\n     */\n    public function getSentMIMEMessage()\n    {\n        return rtrim($this->MIMEHeader . $this->mailHeader, \"\\n\\r\") . self::CRLF . self::CRLF . $this->MIMEBody;\n    }\n\n    /**\n     * Create unique ID\n     * @return string\n     */\n    protected function generateId() {\n        return md5(uniqid(time()));\n    }\n\n    /**\n     * Assemble the message body.\n     * Returns an empty string on failure.\n     * @access public\n     * @throws phpmailerException\n     * @return string The assembled message body\n     */\n    public function createBody()\n    {\n        $body = '';\n        //Create unique IDs and preset boundaries\n        $this->uniqueid = $this->generateId();\n        $this->boundary[1] = 'b1_' . $this->uniqueid;\n        $this->boundary[2] = 'b2_' . $this->uniqueid;\n        $this->boundary[3] = 'b3_' . $this->uniqueid;\n\n        if ($this->sign_key_file) {\n            $body .= $this->getMailMIME() . $this->LE;\n        }\n\n        $this->setWordWrap();\n\n        $bodyEncoding = $this->Encoding;\n        $bodyCharSet = $this->CharSet;\n        //Can we do a 7-bit downgrade?\n        if ($bodyEncoding == '8bit' and !$this->has8bitChars($this->Body)) {\n            $bodyEncoding = '7bit';\n            //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit\n            $bodyCharSet = 'us-ascii';\n        }\n        //If lines are too long, and we're not already using an encoding that will shorten them,\n        //change to quoted-printable transfer encoding for the body part only\n        if ('base64' != $this->Encoding and self::hasLineLongerThanMax($this->Body)) {\n            $bodyEncoding = 'quoted-printable';\n        }\n\n        $altBodyEncoding = $this->Encoding;\n        $altBodyCharSet = $this->CharSet;\n        //Can we do a 7-bit downgrade?\n        if ($altBodyEncoding == '8bit' and !$this->has8bitChars($this->AltBody)) {\n            $altBodyEncoding = '7bit';\n            //All ISO 8859, Windows codepage and UTF-8 charsets are ascii compatible up to 7-bit\n            $altBodyCharSet = 'us-ascii';\n        }\n        //If lines are too long, and we're not already using an encoding that will shorten them,\n        //change to quoted-printable transfer encoding for the alt body part only\n        if ('base64' != $altBodyEncoding and self::hasLineLongerThanMax($this->AltBody)) {\n            $altBodyEncoding = 'quoted-printable';\n        }\n        //Use this as a preamble in all multipart message types\n        $mimepre = \"This is a multi-part message in MIME format.\" . $this->LE . $this->LE;\n        switch ($this->message_type) {\n            case 'inline':\n                $body .= $mimepre;\n                $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);\n                $body .= $this->encodeString($this->Body, $bodyEncoding);\n                $body .= $this->LE . $this->LE;\n                $body .= $this->attachAll('inline', $this->boundary[1]);\n                break;\n            case 'attach':\n                $body .= $mimepre;\n                $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, '', $bodyEncoding);\n                $body .= $this->encodeString($this->Body, $bodyEncoding);\n                $body .= $this->LE . $this->LE;\n                $body .= $this->attachAll('attachment', $this->boundary[1]);\n                break;\n            case 'inline_attach':\n                $body .= $mimepre;\n                $body .= $this->textLine('--' . $this->boundary[1]);\n                $body .= $this->headerLine('Content-Type', 'multipart/related;');\n                $body .= $this->textLine(\"\\tboundary=\\\"\" . $this->boundary[2] . '\"');\n                $body .= $this->LE;\n                $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, '', $bodyEncoding);\n                $body .= $this->encodeString($this->Body, $bodyEncoding);\n                $body .= $this->LE . $this->LE;\n                $body .= $this->attachAll('inline', $this->boundary[2]);\n                $body .= $this->LE;\n                $body .= $this->attachAll('attachment', $this->boundary[1]);\n                break;\n            case 'alt':\n                $body .= $mimepre;\n                $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);\n                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);\n                $body .= $this->LE . $this->LE;\n                $body .= $this->getBoundary($this->boundary[1], $bodyCharSet, 'text/html', $bodyEncoding);\n                $body .= $this->encodeString($this->Body, $bodyEncoding);\n                $body .= $this->LE . $this->LE;\n                if (!empty($this->Ical)) {\n                    $body .= $this->getBoundary($this->boundary[1], '', 'text/calendar; method=REQUEST', '');\n                    $body .= $this->encodeString($this->Ical, $this->Encoding);\n                    $body .= $this->LE . $this->LE;\n                }\n                $body .= $this->endBoundary($this->boundary[1]);\n                break;\n            case 'alt_inline':\n                $body .= $mimepre;\n                $body .= $this->getBoundary($this->boundary[1], $altBodyCharSet, 'text/plain', $altBodyEncoding);\n                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);\n                $body .= $this->LE . $this->LE;\n                $body .= $this->textLine('--' . $this->boundary[1]);\n                $body .= $this->headerLine('Content-Type', 'multipart/related;');\n                $body .= $this->textLine(\"\\tboundary=\\\"\" . $this->boundary[2] . '\"');\n                $body .= $this->LE;\n                $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);\n                $body .= $this->encodeString($this->Body, $bodyEncoding);\n                $body .= $this->LE . $this->LE;\n                $body .= $this->attachAll('inline', $this->boundary[2]);\n                $body .= $this->LE;\n                $body .= $this->endBoundary($this->boundary[1]);\n                break;\n            case 'alt_attach':\n                $body .= $mimepre;\n                $body .= $this->textLine('--' . $this->boundary[1]);\n                $body .= $this->headerLine('Content-Type', 'multipart/alternative;');\n                $body .= $this->textLine(\"\\tboundary=\\\"\" . $this->boundary[2] . '\"');\n                $body .= $this->LE;\n                $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);\n                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);\n                $body .= $this->LE . $this->LE;\n                $body .= $this->getBoundary($this->boundary[2], $bodyCharSet, 'text/html', $bodyEncoding);\n                $body .= $this->encodeString($this->Body, $bodyEncoding);\n                $body .= $this->LE . $this->LE;\n                $body .= $this->endBoundary($this->boundary[2]);\n                $body .= $this->LE;\n                $body .= $this->attachAll('attachment', $this->boundary[1]);\n                break;\n            case 'alt_inline_attach':\n                $body .= $mimepre;\n                $body .= $this->textLine('--' . $this->boundary[1]);\n                $body .= $this->headerLine('Content-Type', 'multipart/alternative;');\n                $body .= $this->textLine(\"\\tboundary=\\\"\" . $this->boundary[2] . '\"');\n                $body .= $this->LE;\n                $body .= $this->getBoundary($this->boundary[2], $altBodyCharSet, 'text/plain', $altBodyEncoding);\n                $body .= $this->encodeString($this->AltBody, $altBodyEncoding);\n                $body .= $this->LE . $this->LE;\n                $body .= $this->textLine('--' . $this->boundary[2]);\n                $body .= $this->headerLine('Content-Type', 'multipart/related;');\n                $body .= $this->textLine(\"\\tboundary=\\\"\" . $this->boundary[3] . '\"');\n                $body .= $this->LE;\n                $body .= $this->getBoundary($this->boundary[3], $bodyCharSet, 'text/html', $bodyEncoding);\n                $body .= $this->encodeString($this->Body, $bodyEncoding);\n                $body .= $this->LE . $this->LE;\n                $body .= $this->attachAll('inline', $this->boundary[3]);\n                $body .= $this->LE;\n                $body .= $this->endBoundary($this->boundary[2]);\n                $body .= $this->LE;\n                $body .= $this->attachAll('attachment', $this->boundary[1]);\n                break;\n            default:\n                // Catch case 'plain' and case '', applies to simple `text/plain` and `text/html` body content types\n                //Reset the `Encoding` property in case we changed it for line length reasons\n                $this->Encoding = $bodyEncoding;\n                $body .= $this->encodeString($this->Body, $this->Encoding);\n                break;\n        }\n\n        if ($this->isError()) {\n            $body = '';\n        } elseif ($this->sign_key_file) {\n            try {\n                if (!defined('PKCS7_TEXT')) {\n                    throw new phpmailerException($this->lang('extension_missing') . 'openssl');\n                }\n                // @TODO would be nice to use php://temp streams here, but need to wrap for PHP < 5.1\n                $file = tempnam(sys_get_temp_dir(), 'mail');\n                if (false === file_put_contents($file, $body)) {\n                    throw new phpmailerException($this->lang('signing') . ' Could not write temp file');\n                }\n                $signed = tempnam(sys_get_temp_dir(), 'signed');\n                //Workaround for PHP bug https://bugs.php.net/bug.php?id=69197\n                if (empty($this->sign_extracerts_file)) {\n                    $sign = @openssl_pkcs7_sign(\n                        $file,\n                        $signed,\n                        'file://' . realpath($this->sign_cert_file),\n                        array('file://' . realpath($this->sign_key_file), $this->sign_key_pass),\n                        null\n                    );\n                } else {\n                    $sign = @openssl_pkcs7_sign(\n                        $file,\n                        $signed,\n                        'file://' . realpath($this->sign_cert_file),\n                        array('file://' . realpath($this->sign_key_file), $this->sign_key_pass),\n                        null,\n                        PKCS7_DETACHED,\n                        $this->sign_extracerts_file\n                    );\n                }\n                if ($sign) {\n                    @unlink($file);\n                    $body = file_get_contents($signed);\n                    @unlink($signed);\n                    //The message returned by openssl contains both headers and body, so need to split them up\n                    $parts = explode(\"\\n\\n\", $body, 2);\n                    $this->MIMEHeader .= $parts[0] . $this->LE . $this->LE;\n                    $body = $parts[1];\n                } else {\n                    @unlink($file);\n                    @unlink($signed);\n                    throw new phpmailerException($this->lang('signing') . openssl_error_string());\n                }\n            } catch (phpmailerException $exc) {\n                $body = '';\n                if ($this->exceptions) {\n                    throw $exc;\n                }\n            }\n        }\n        return $body;\n    }\n\n    /**\n     * Return the start of a message boundary.\n     * @access protected\n     * @param string $boundary\n     * @param string $charSet\n     * @param string $contentType\n     * @param string $encoding\n     * @return string\n     */\n    protected function getBoundary($boundary, $charSet, $contentType, $encoding)\n    {\n        $result = '';\n        if ($charSet == '') {\n            $charSet = $this->CharSet;\n        }\n        if ($contentType == '') {\n            $contentType = $this->ContentType;\n        }\n        if ($encoding == '') {\n            $encoding = $this->Encoding;\n        }\n        $result .= $this->textLine('--' . $boundary);\n        $result .= sprintf('Content-Type: %s; charset=%s', $contentType, $charSet);\n        $result .= $this->LE;\n        // RFC1341 part 5 says 7bit is assumed if not specified\n        if ($encoding != '7bit') {\n            $result .= $this->headerLine('Content-Transfer-Encoding', $encoding);\n        }\n        $result .= $this->LE;\n\n        return $result;\n    }\n\n    /**\n     * Return the end of a message boundary.\n     * @access protected\n     * @param string $boundary\n     * @return string\n     */\n    protected function endBoundary($boundary)\n    {\n        return $this->LE . '--' . $boundary . '--' . $this->LE;\n    }\n\n    /**\n     * Set the message type.\n     * PHPMailer only supports some preset message types, not arbitrary MIME structures.\n     * @access protected\n     * @return void\n     */\n    protected function setMessageType()\n    {\n        $type = array();\n        if ($this->alternativeExists()) {\n            $type[] = 'alt';\n        }\n        if ($this->inlineImageExists()) {\n            $type[] = 'inline';\n        }\n        if ($this->attachmentExists()) {\n            $type[] = 'attach';\n        }\n        $this->message_type = implode('_', $type);\n        if ($this->message_type == '') {\n            //The 'plain' message_type refers to the message having a single body element, not that it is plain-text\n            $this->message_type = 'plain';\n        }\n    }\n\n    /**\n     * Format a header line.\n     * @access public\n     * @param string $name\n     * @param string $value\n     * @return string\n     */\n    public function headerLine($name, $value)\n    {\n        return $name . ': ' . $value . $this->LE;\n    }\n\n    /**\n     * Return a formatted mail line.\n     * @access public\n     * @param string $value\n     * @return string\n     */\n    public function textLine($value)\n    {\n        return $value . $this->LE;\n    }\n\n    /**\n     * Add an attachment from a path on the filesystem.\n     * Never use a user-supplied path to a file!\n     * Returns false if the file could not be found or read.\n     * @param string $path Path to the attachment.\n     * @param string $name Overrides the attachment name.\n     * @param string $encoding File encoding (see $Encoding).\n     * @param string $type File extension (MIME) type.\n     * @param string $disposition Disposition to use\n     * @throws phpmailerException\n     * @return boolean\n     */\n    public function addAttachment($path, $name = '', $encoding = 'base64', $type = '', $disposition = 'attachment')\n    {\n        try {\n            if (!@is_file($path)) {\n                throw new phpmailerException($this->lang('file_access') . $path, self::STOP_CONTINUE);\n            }\n\n            // If a MIME type is not specified, try to work it out from the file name\n            if ($type == '') {\n                $type = self::filenameToType($path);\n            }\n\n            $filename = basename($path);\n            if ($name == '') {\n                $name = $filename;\n            }\n\n            $this->attachment[] = array(\n                0 => $path,\n                1 => $filename,\n                2 => $name,\n                3 => $encoding,\n                4 => $type,\n                5 => false, // isStringAttachment\n                6 => $disposition,\n                7 => 0\n            );\n\n        } catch (phpmailerException $exc) {\n            $this->setError($exc->getMessage());\n            $this->edebug($exc->getMessage());\n            if ($this->exceptions) {\n                throw $exc;\n            }\n            return false;\n        }\n        return true;\n    }\n\n    /**\n     * Return the array of attachments.\n     * @return array\n     */\n    public function getAttachments()\n    {\n        return $this->attachment;\n    }\n\n    /**\n     * Attach all file, string, and binary attachments to the message.\n     * Returns an empty string on failure.\n     * @access protected\n     * @param string $disposition_type\n     * @param string $boundary\n     * @return string\n     */\n    protected function attachAll($disposition_type, $boundary)\n    {\n        // Return text of body\n        $mime = array();\n        $cidUniq = array();\n        $incl = array();\n\n        // Add all attachments\n        foreach ($this->attachment as $attachment) {\n            // Check if it is a valid disposition_filter\n            if ($attachment[6] == $disposition_type) {\n                // Check for string attachment\n                $string = '';\n                $path = '';\n                $bString = $attachment[5];\n                if ($bString) {\n                    $string = $attachment[0];\n                } else {\n                    $path = $attachment[0];\n                }\n\n                $inclhash = md5(serialize($attachment));\n                if (in_array($inclhash, $incl)) {\n                    continue;\n                }\n                $incl[] = $inclhash;\n                $name = $attachment[2];\n                $encoding = $attachment[3];\n                $type = $attachment[4];\n                $disposition = $attachment[6];\n                $cid = $attachment[7];\n                if ($disposition == 'inline' && array_key_exists($cid, $cidUniq)) {\n                    continue;\n                }\n                $cidUniq[$cid] = true;\n\n                $mime[] = sprintf('--%s%s', $boundary, $this->LE);\n                //Only include a filename property if we have one\n                if (!empty($name)) {\n                    $mime[] = sprintf(\n                        'Content-Type: %s; name=\"%s\"%s',\n                        $type,\n                        $this->encodeHeader($this->secureHeader($name)),\n                        $this->LE\n                    );\n                } else {\n                    $mime[] = sprintf(\n                        'Content-Type: %s%s',\n                        $type,\n                        $this->LE\n                    );\n                }\n                // RFC1341 part 5 says 7bit is assumed if not specified\n                if ($encoding != '7bit') {\n                    $mime[] = sprintf('Content-Transfer-Encoding: %s%s', $encoding, $this->LE);\n                }\n\n                if ($disposition == 'inline') {\n                    $mime[] = sprintf('Content-ID: <%s>%s', $cid, $this->LE);\n                }\n\n                // If a filename contains any of these chars, it should be quoted,\n                // but not otherwise: RFC2183 & RFC2045 5.1\n                // Fixes a warning in IETF's msglint MIME checker\n                // Allow for bypassing the Content-Disposition header totally\n                if (!(empty($disposition))) {\n                    $encoded_name = $this->encodeHeader($this->secureHeader($name));\n                    if (preg_match('/[ \\(\\)<>@,;:\\\\\"\\/\\[\\]\\?=]/', $encoded_name)) {\n                        $mime[] = sprintf(\n                            'Content-Disposition: %s; filename=\"%s\"%s',\n                            $disposition,\n                            $encoded_name,\n                            $this->LE . $this->LE\n                        );\n                    } else {\n                        if (!empty($encoded_name)) {\n                            $mime[] = sprintf(\n                                'Content-Disposition: %s; filename=%s%s',\n                                $disposition,\n                                $encoded_name,\n                                $this->LE . $this->LE\n                            );\n                        } else {\n                            $mime[] = sprintf(\n                                'Content-Disposition: %s%s',\n                                $disposition,\n                                $this->LE . $this->LE\n                            );\n                        }\n                    }\n                } else {\n                    $mime[] = $this->LE;\n                }\n\n                // Encode as string attachment\n                if ($bString) {\n                    $mime[] = $this->encodeString($string, $encoding);\n                    if ($this->isError()) {\n                        return '';\n                    }\n                    $mime[] = $this->LE . $this->LE;\n                } else {\n                    $mime[] = $this->encodeFile($path, $encoding);\n                    if ($this->isError()) {\n                        return '';\n                    }\n                    $mime[] = $this->LE . $this->LE;\n                }\n            }\n        }\n\n        $mime[] = sprintf('--%s--%s', $boundary, $this->LE);\n\n        return implode('', $mime);\n    }\n\n    /**\n     * Encode a file attachment in requested format.\n     * Returns an empty string on failure.\n     * @param string $path The full path to the file\n     * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'\n     * @throws phpmailerException\n     * @access protected\n     * @return string\n     */\n    protected function encodeFile($path, $encoding = 'base64')\n    {\n        try {\n            if (!is_readable($path)) {\n                throw new phpmailerException($this->lang('file_open') . $path, self::STOP_CONTINUE);\n            }\n            $magic_quotes = get_magic_quotes_runtime();\n            if ($magic_quotes) {\n                if (version_compare(PHP_VERSION, '5.3.0', '<')) {\n                    set_magic_quotes_runtime(false);\n                } else {\n                    //Doesn't exist in PHP 5.4, but we don't need to check because\n                    //get_magic_quotes_runtime always returns false in 5.4+\n                    //so it will never get here\n                    ini_set('magic_quotes_runtime', false);\n                }\n            }\n            $file_buffer = file_get_contents($path);\n            $file_buffer = $this->encodeString($file_buffer, $encoding);\n            if ($magic_quotes) {\n                if (version_compare(PHP_VERSION, '5.3.0', '<')) {\n                    set_magic_quotes_runtime($magic_quotes);\n                } else {\n                    ini_set('magic_quotes_runtime', $magic_quotes);\n                }\n            }\n            return $file_buffer;\n        } catch (Exception $exc) {\n            $this->setError($exc->getMessage());\n            return '';\n        }\n    }\n\n    /**\n     * Encode a string in requested format.\n     * Returns an empty string on failure.\n     * @param string $str The text to encode\n     * @param string $encoding The encoding to use; one of 'base64', '7bit', '8bit', 'binary', 'quoted-printable'\n     * @access public\n     * @return string\n     */\n    public function encodeString($str, $encoding = 'base64')\n    {\n        $encoded = '';\n        switch (strtolower($encoding)) {\n            case 'base64':\n                $encoded = chunk_split(base64_encode($str), 76, $this->LE);\n                break;\n            case '7bit':\n            case '8bit':\n                $encoded = $this->fixEOL($str);\n                // Make sure it ends with a line break\n                if (substr($encoded, -(strlen($this->LE))) != $this->LE) {\n                    $encoded .= $this->LE;\n                }\n                break;\n            case 'binary':\n                $encoded = $str;\n                break;\n            case 'quoted-printable':\n                $encoded = $this->encodeQP($str);\n                break;\n            default:\n                $this->setError($this->lang('encoding') . $encoding);\n                break;\n        }\n        return $encoded;\n    }\n\n    /**\n     * Encode a header string optimally.\n     * Picks shortest of Q, B, quoted-printable or none.\n     * @access public\n     * @param string $str\n     * @param string $position\n     * @return string\n     */\n    public function encodeHeader($str, $position = 'text')\n    {\n        $matchcount = 0;\n        switch (strtolower($position)) {\n            case 'phrase':\n                if (!preg_match('/[\\200-\\377]/', $str)) {\n                    // Can't use addslashes as we don't know the value of magic_quotes_sybase\n                    $encoded = addcslashes($str, \"\\0..\\37\\177\\\\\\\"\");\n                    if (($str == $encoded) && !preg_match('/[^A-Za-z0-9!#$%&\\'*+\\/=?^_`{|}~ -]/', $str)) {\n                        return ($encoded);\n                    } else {\n                        return (\"\\\"$encoded\\\"\");\n                    }\n                }\n                $matchcount = preg_match_all('/[^\\040\\041\\043-\\133\\135-\\176]/', $str, $matches);\n                break;\n            /** @noinspection PhpMissingBreakStatementInspection */\n            case 'comment':\n                $matchcount = preg_match_all('/[()\"]/', $str, $matches);\n                // Intentional fall-through\n            case 'text':\n            default:\n                $matchcount += preg_match_all('/[\\000-\\010\\013\\014\\016-\\037\\177-\\377]/', $str, $matches);\n                break;\n        }\n\n        //There are no chars that need encoding\n        if ($matchcount == 0) {\n            return ($str);\n        }\n\n        $maxlen = 75 - 7 - strlen($this->CharSet);\n        // Try to select the encoding which should produce the shortest output\n        if ($matchcount > strlen($str) / 3) {\n            // More than a third of the content will need encoding, so B encoding will be most efficient\n            $encoding = 'B';\n            if (function_exists('mb_strlen') && $this->hasMultiBytes($str)) {\n                // Use a custom function which correctly encodes and wraps long\n                // multibyte strings without breaking lines within a character\n                $encoded = $this->base64EncodeWrapMB($str, \"\\n\");\n            } else {\n                $encoded = base64_encode($str);\n                $maxlen -= $maxlen % 4;\n                $encoded = trim(chunk_split($encoded, $maxlen, \"\\n\"));\n            }\n        } else {\n            $encoding = 'Q';\n            $encoded = $this->encodeQ($str, $position);\n            $encoded = $this->wrapText($encoded, $maxlen, true);\n            $encoded = str_replace('=' . self::CRLF, \"\\n\", trim($encoded));\n        }\n\n        $encoded = preg_replace('/^(.*)$/m', ' =?' . $this->CharSet . \"?$encoding?\\\\1?=\", $encoded);\n        $encoded = trim(str_replace(\"\\n\", $this->LE, $encoded));\n\n        return $encoded;\n    }\n\n    /**\n     * Check if a string contains multi-byte characters.\n     * @access public\n     * @param string $str multi-byte text to wrap encode\n     * @return boolean\n     */\n    public function hasMultiBytes($str)\n    {\n        if (function_exists('mb_strlen')) {\n            return (strlen($str) > mb_strlen($str, $this->CharSet));\n        } else { // Assume no multibytes (we can't handle without mbstring functions anyway)\n            return false;\n        }\n    }\n\n    /**\n     * Does a string contain any 8-bit chars (in any charset)?\n     * @param string $text\n     * @return boolean\n     */\n    public function has8bitChars($text)\n    {\n        return (boolean)preg_match('/[\\x80-\\xFF]/', $text);\n    }\n\n    /**\n     * Encode and wrap long multibyte strings for mail headers\n     * without breaking lines within a character.\n     * Adapted from a function by paravoid\n     * @link http://www.php.net/manual/en/function.mb-encode-mimeheader.php#60283\n     * @access public\n     * @param string $str multi-byte text to wrap encode\n     * @param string $linebreak string to use as linefeed/end-of-line\n     * @return string\n     */\n    public function base64EncodeWrapMB($str, $linebreak = null)\n    {\n        $start = '=?' . $this->CharSet . '?B?';\n        $end = '?=';\n        $encoded = '';\n        if ($linebreak === null) {\n            $linebreak = $this->LE;\n        }\n\n        $mb_length = mb_strlen($str, $this->CharSet);\n        // Each line must have length <= 75, including $start and $end\n        $length = 75 - strlen($start) - strlen($end);\n        // Average multi-byte ratio\n        $ratio = $mb_length / strlen($str);\n        // Base64 has a 4:3 ratio\n        $avgLength = floor($length * $ratio * .75);\n\n        for ($i = 0; $i < $mb_length; $i += $offset) {\n            $lookBack = 0;\n            do {\n                $offset = $avgLength - $lookBack;\n                $chunk = mb_substr($str, $i, $offset, $this->CharSet);\n                $chunk = base64_encode($chunk);\n                $lookBack++;\n            } while (strlen($chunk) > $length);\n            $encoded .= $chunk . $linebreak;\n        }\n\n        // Chomp the last linefeed\n        $encoded = substr($encoded, 0, -strlen($linebreak));\n        return $encoded;\n    }\n\n    /**\n     * Encode a string in quoted-printable format.\n     * According to RFC2045 section 6.7.\n     * @access public\n     * @param string $string The text to encode\n     * @param integer $line_max Number of chars allowed on a line before wrapping\n     * @return string\n     * @link http://www.php.net/manual/en/function.quoted-printable-decode.php#89417 Adapted from this comment\n     */\n    public function encodeQP($string, $line_max = 76)\n    {\n        // Use native function if it's available (>= PHP5.3)\n        if (function_exists('quoted_printable_encode')) {\n            return quoted_printable_encode($string);\n        }\n        // Fall back to a pure PHP implementation\n        $string = str_replace(\n            array('%20', '%0D%0A.', '%0D%0A', '%'),\n            array(' ', \"\\r\\n=2E\", \"\\r\\n\", '='),\n            rawurlencode($string)\n        );\n        return preg_replace('/[^\\r\\n]{' . ($line_max - 3) . '}[^=\\r\\n]{2}/', \"$0=\\r\\n\", $string);\n    }\n\n    /**\n     * Backward compatibility wrapper for an old QP encoding function that was removed.\n     * @see PHPMailer::encodeQP()\n     * @access public\n     * @param string $string\n     * @param integer $line_max\n     * @param boolean $space_conv\n     * @return string\n     * @deprecated Use encodeQP instead.\n     */\n    public function encodeQPphp(\n        $string,\n        $line_max = 76,\n        /** @noinspection PhpUnusedParameterInspection */ $space_conv = false\n    ) {\n        return $this->encodeQP($string, $line_max);\n    }\n\n    /**\n     * Encode a string using Q encoding.\n     * @link http://tools.ietf.org/html/rfc2047\n     * @param string $str the text to encode\n     * @param string $position Where the text is going to be used, see the RFC for what that means\n     * @access public\n     * @return string\n     */\n    public function encodeQ($str, $position = 'text')\n    {\n        // There should not be any EOL in the string\n        $pattern = '';\n        $encoded = str_replace(array(\"\\r\", \"\\n\"), '', $str);\n        switch (strtolower($position)) {\n            case 'phrase':\n                // RFC 2047 section 5.3\n                $pattern = '^A-Za-z0-9!*+\\/ -';\n                break;\n            /** @noinspection PhpMissingBreakStatementInspection */\n            case 'comment':\n                // RFC 2047 section 5.2\n                $pattern = '\\(\\)\"';\n                // intentional fall-through\n                // for this reason we build the $pattern without including delimiters and []\n            case 'text':\n            default:\n                // RFC 2047 section 5.1\n                // Replace every high ascii, control, =, ? and _ characters\n                $pattern = '\\000-\\011\\013\\014\\016-\\037\\075\\077\\137\\177-\\377' . $pattern;\n                break;\n        }\n        $matches = array();\n        if (preg_match_all(\"/[{$pattern}]/\", $encoded, $matches)) {\n            // If the string contains an '=', make sure it's the first thing we replace\n            // so as to avoid double-encoding\n            $eqkey = array_search('=', $matches[0]);\n            if (false !== $eqkey) {\n                unset($matches[0][$eqkey]);\n                array_unshift($matches[0], '=');\n            }\n            foreach (array_unique($matches[0]) as $char) {\n                $encoded = str_replace($char, '=' . sprintf('%02X', ord($char)), $encoded);\n            }\n        }\n        // Replace every spaces to _ (more readable than =20)\n        return str_replace(' ', '_', $encoded);\n    }\n\n    /**\n     * Add a string or binary attachment (non-filesystem).\n     * This method can be used to attach ascii or binary data,\n     * such as a BLOB record from a database.\n     * @param string $string String attachment data.\n     * @param string $filename Name of the attachment.\n     * @param string $encoding File encoding (see $Encoding).\n     * @param string $type File extension (MIME) type.\n     * @param string $disposition Disposition to use\n     * @return void\n     */\n    public function addStringAttachment(\n        $string,\n        $filename,\n        $encoding = 'base64',\n        $type = '',\n        $disposition = 'attachment'\n    ) {\n        // If a MIME type is not specified, try to work it out from the file name\n        if ($type == '') {\n            $type = self::filenameToType($filename);\n        }\n        // Append to $attachment array\n        $this->attachment[] = array(\n            0 => $string,\n            1 => $filename,\n            2 => basename($filename),\n            3 => $encoding,\n            4 => $type,\n            5 => true, // isStringAttachment\n            6 => $disposition,\n            7 => 0\n        );\n    }\n\n    /**\n     * Add an embedded (inline) attachment from a file.\n     * This can include images, sounds, and just about any other document type.\n     * These differ from 'regular' attachments in that they are intended to be\n     * displayed inline with the message, not just attached for download.\n     * This is used in HTML messages that embed the images\n     * the HTML refers to using the $cid value.\n     * Never use a user-supplied path to a file!\n     * @param string $path Path to the attachment.\n     * @param string $cid Content ID of the attachment; Use this to reference\n     *        the content when using an embedded image in HTML.\n     * @param string $name Overrides the attachment name.\n     * @param string $encoding File encoding (see $Encoding).\n     * @param string $type File MIME type.\n     * @param string $disposition Disposition to use\n     * @return boolean True on successfully adding an attachment\n     */\n    public function addEmbeddedImage($path, $cid, $name = '', $encoding = 'base64', $type = '', $disposition = 'inline')\n    {\n        if (!@is_file($path)) {\n            $this->setError($this->lang('file_access') . $path);\n            return false;\n        }\n\n        // If a MIME type is not specified, try to work it out from the file name\n        if ($type == '') {\n            $type = self::filenameToType($path);\n        }\n\n        $filename = basename($path);\n        if ($name == '') {\n            $name = $filename;\n        }\n\n        // Append to $attachment array\n        $this->attachment[] = array(\n            0 => $path,\n            1 => $filename,\n            2 => $name,\n            3 => $encoding,\n            4 => $type,\n            5 => false, // isStringAttachment\n            6 => $disposition,\n            7 => $cid\n        );\n        return true;\n    }\n\n    /**\n     * Add an embedded stringified attachment.\n     * This can include images, sounds, and just about any other document type.\n     * Be sure to set the $type to an image type for images:\n     * JPEG images use 'image/jpeg', GIF uses 'image/gif', PNG uses 'image/png'.\n     * @param string $string The attachment binary data.\n     * @param string $cid Content ID of the attachment; Use this to reference\n     *        the content when using an embedded image in HTML.\n     * @param string $name\n     * @param string $encoding File encoding (see $Encoding).\n     * @param string $type MIME type.\n     * @param string $disposition Disposition to use\n     * @return boolean True on successfully adding an attachment\n     */\n    public function addStringEmbeddedImage(\n        $string,\n        $cid,\n        $name = '',\n        $encoding = 'base64',\n        $type = '',\n        $disposition = 'inline'\n    ) {\n        // If a MIME type is not specified, try to work it out from the name\n        if ($type == '' and !empty($name)) {\n            $type = self::filenameToType($name);\n        }\n\n        // Append to $attachment array\n        $this->attachment[] = array(\n            0 => $string,\n            1 => $name,\n            2 => $name,\n            3 => $encoding,\n            4 => $type,\n            5 => true, // isStringAttachment\n            6 => $disposition,\n            7 => $cid\n        );\n        return true;\n    }\n\n    /**\n     * Check if an inline attachment is present.\n     * @access public\n     * @return boolean\n     */\n    public function inlineImageExists()\n    {\n        foreach ($this->attachment as $attachment) {\n            if ($attachment[6] == 'inline') {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Check if an attachment (non-inline) is present.\n     * @return boolean\n     */\n    public function attachmentExists()\n    {\n        foreach ($this->attachment as $attachment) {\n            if ($attachment[6] == 'attachment') {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Check if this message has an alternative body set.\n     * @return boolean\n     */\n    public function alternativeExists()\n    {\n        return !empty($this->AltBody);\n    }\n\n    /**\n     * Clear queued addresses of given kind.\n     * @access protected\n     * @param string $kind 'to', 'cc', or 'bcc'\n     * @return void\n     */\n    public function clearQueuedAddresses($kind)\n    {\n        $RecipientsQueue = $this->RecipientsQueue;\n        foreach ($RecipientsQueue as $address => $params) {\n            if ($params[0] == $kind) {\n                unset($this->RecipientsQueue[$address]);\n            }\n        }\n    }\n\n    /**\n     * Clear all To recipients.\n     * @return void\n     */\n    public function clearAddresses()\n    {\n        foreach ($this->to as $to) {\n            unset($this->all_recipients[strtolower($to[0])]);\n        }\n        $this->to = array();\n        $this->clearQueuedAddresses('to');\n    }\n\n    /**\n     * Clear all CC recipients.\n     * @return void\n     */\n    public function clearCCs()\n    {\n        foreach ($this->cc as $cc) {\n            unset($this->all_recipients[strtolower($cc[0])]);\n        }\n        $this->cc = array();\n        $this->clearQueuedAddresses('cc');\n    }\n\n    /**\n     * Clear all BCC recipients.\n     * @return void\n     */\n    public function clearBCCs()\n    {\n        foreach ($this->bcc as $bcc) {\n            unset($this->all_recipients[strtolower($bcc[0])]);\n        }\n        $this->bcc = array();\n        $this->clearQueuedAddresses('bcc');\n    }\n\n    /**\n     * Clear all ReplyTo recipients.\n     * @return void\n     */\n    public function clearReplyTos()\n    {\n        $this->ReplyTo = array();\n        $this->ReplyToQueue = array();\n    }\n\n    /**\n     * Clear all recipient types.\n     * @return void\n     */\n    public function clearAllRecipients()\n    {\n        $this->to = array();\n        $this->cc = array();\n        $this->bcc = array();\n        $this->all_recipients = array();\n        $this->RecipientsQueue = array();\n    }\n\n    /**\n     * Clear all filesystem, string, and binary attachments.\n     * @return void\n     */\n    public function clearAttachments()\n    {\n        $this->attachment = array();\n    }\n\n    /**\n     * Clear all custom headers.\n     * @return void\n     */\n    public function clearCustomHeaders()\n    {\n        $this->CustomHeader = array();\n    }\n\n    /**\n     * Add an error message to the error container.\n     * @access protected\n     * @param string $msg\n     * @return void\n     */\n    protected function setError($msg)\n    {\n        $this->error_count++;\n        if ($this->Mailer == 'smtp' and !is_null($this->smtp)) {\n            $lasterror = $this->smtp->getError();\n            if (!empty($lasterror['error'])) {\n                $msg .= $this->lang('smtp_error') . $lasterror['error'];\n                if (!empty($lasterror['detail'])) {\n                    $msg .= ' Detail: '. $lasterror['detail'];\n                }\n                if (!empty($lasterror['smtp_code'])) {\n                    $msg .= ' SMTP code: ' . $lasterror['smtp_code'];\n                }\n                if (!empty($lasterror['smtp_code_ex'])) {\n                    $msg .= ' Additional SMTP info: ' . $lasterror['smtp_code_ex'];\n                }\n            }\n        }\n        $this->ErrorInfo = $msg;\n    }\n\n    /**\n     * Return an RFC 822 formatted date.\n     * @access public\n     * @return string\n     * @static\n     */\n    public static function rfcDate()\n    {\n        // Set the time zone to whatever the default is to avoid 500 errors\n        // Will default to UTC if it's not set properly in php.ini\n        date_default_timezone_set(@date_default_timezone_get());\n        return date('D, j M Y H:i:s O');\n    }\n\n    /**\n     * Get the server hostname.\n     * Returns 'localhost.localdomain' if unknown.\n     * @access protected\n     * @return string\n     */\n    protected function serverHostname()\n    {\n        $result = 'localhost.localdomain';\n        if (!empty($this->Hostname)) {\n            $result = $this->Hostname;\n        } elseif (isset($_SERVER) and array_key_exists('SERVER_NAME', $_SERVER) and !empty($_SERVER['SERVER_NAME'])) {\n            $result = $_SERVER['SERVER_NAME'];\n        } elseif (function_exists('gethostname') && gethostname() !== false) {\n            $result = gethostname();\n        } elseif (php_uname('n') !== false) {\n            $result = php_uname('n');\n        }\n        return $result;\n    }\n\n    /**\n     * Get an error message in the current language.\n     * @access protected\n     * @param string $key\n     * @return string\n     */\n    protected function lang($key)\n    {\n        if (count($this->language) < 1) {\n            $this->setLanguage('en'); // set the default language\n        }\n\n        if (array_key_exists($key, $this->language)) {\n            if ($key == 'smtp_connect_failed') {\n                //Include a link to troubleshooting docs on SMTP connection failure\n                //this is by far the biggest cause of support questions\n                //but it's usually not PHPMailer's fault.\n                return $this->language[$key] . ' https://github.com/PHPMailer/PHPMailer/wiki/Troubleshooting';\n            }\n            return $this->language[$key];\n        } else {\n            //Return the key as a fallback\n            return $key;\n        }\n    }\n\n    /**\n     * Check if an error occurred.\n     * @access public\n     * @return boolean True if an error did occur.\n     */\n    public function isError()\n    {\n        return ($this->error_count > 0);\n    }\n\n    /**\n     * Ensure consistent line endings in a string.\n     * Changes every end of line from CRLF, CR or LF to $this->LE.\n     * @access public\n     * @param string $str String to fixEOL\n     * @return string\n     */\n    public function fixEOL($str)\n    {\n        // Normalise to \\n\n        $nstr = str_replace(array(\"\\r\\n\", \"\\r\"), \"\\n\", $str);\n        // Now convert LE as needed\n        if ($this->LE !== \"\\n\") {\n            $nstr = str_replace(\"\\n\", $this->LE, $nstr);\n        }\n        return $nstr;\n    }\n\n    /**\n     * Add a custom header.\n     * $name value can be overloaded to contain\n     * both header name and value (name:value)\n     * @access public\n     * @param string $name Custom header name\n     * @param string $value Header value\n     * @return void\n     */\n    public function addCustomHeader($name, $value = null)\n    {\n        if ($value === null) {\n            // Value passed in as name:value\n            $this->CustomHeader[] = explode(':', $name, 2);\n        } else {\n            $this->CustomHeader[] = array($name, $value);\n        }\n    }\n\n    /**\n     * Returns all custom headers.\n     * @return array\n     */\n    public function getCustomHeaders()\n    {\n        return $this->CustomHeader;\n    }\n\n    /**\n     * Create a message body from an HTML string.\n     * Automatically inlines images and creates a plain-text version by converting the HTML,\n     * overwriting any existing values in Body and AltBody.\n     * Do not source $message content from user input!\n     * $basedir is prepended when handling relative URLs, e.g. <img src=\"/images/a.png\"> and must not be empty\n     * will look for an image file in $basedir/images/a.png and convert it to inline.\n     * If you don't provide a $basedir, relative paths will be left untouched (and thus probably break in email)\n     * If you don't want to apply these transformations to your HTML, just set Body and AltBody directly.\n     * @access public\n     * @param string $message HTML message string\n     * @param string $basedir Absolute path to a base directory to prepend to relative paths to images\n     * @param boolean|callable $advanced Whether to use the internal HTML to text converter\n     *    or your own custom converter @see PHPMailer::html2text()\n     * @return string $message The transformed message Body\n     */\n    public function msgHTML($message, $basedir = '', $advanced = false)\n    {\n        preg_match_all('/(src|background)=[\"\\'](.*)[\"\\']/Ui', $message, $images);\n        if (array_key_exists(2, $images)) {\n            if (strlen($basedir) > 1 && substr($basedir, -1) != '/') {\n                // Ensure $basedir has a trailing /\n                $basedir .= '/';\n            }\n            foreach ($images[2] as $imgindex => $url) {\n                // Convert data URIs into embedded images\n                if (preg_match('#^data:(image[^;,]*)(;base64)?,#', $url, $match)) {\n                    $data = substr($url, strpos($url, ','));\n                    if ($match[2]) {\n                        $data = base64_decode($data);\n                    } else {\n                        $data = rawurldecode($data);\n                    }\n                    $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2\n                    if ($this->addStringEmbeddedImage($data, $cid, 'embed' . $imgindex, 'base64', $match[1])) {\n                        $message = str_replace(\n                            $images[0][$imgindex],\n                            $images[1][$imgindex] . '=\"cid:' . $cid . '\"',\n                            $message\n                        );\n                    }\n                    continue;\n                }\n                if (\n                    // Only process relative URLs if a basedir is provided (i.e. no absolute local paths)\n                    !empty($basedir)\n                    // Ignore URLs containing parent dir traversal (..)\n                    && (strpos($url, '..') === false)\n                    // Do not change urls that are already inline images\n                    && substr($url, 0, 4) !== 'cid:'\n                    // Do not change absolute URLs, including anonymous protocol\n                    && !preg_match('#^[a-z][a-z0-9+.-]*:?//#i', $url)\n                ) {\n                    $filename = basename($url);\n                    $directory = dirname($url);\n                    if ($directory == '.') {\n                        $directory = '';\n                    }\n                    $cid = md5($url) . '@phpmailer.0'; // RFC2392 S 2\n                    if (strlen($directory) > 1 && substr($directory, -1) != '/') {\n                        $directory .= '/';\n                    }\n                    if ($this->addEmbeddedImage(\n                        $basedir . $directory . $filename,\n                        $cid,\n                        $filename,\n                        'base64',\n                        self::_mime_types((string)self::mb_pathinfo($filename, PATHINFO_EXTENSION))\n                    )\n                    ) {\n                        $message = preg_replace(\n                            '/' . $images[1][$imgindex] . '=[\"\\']' . preg_quote($url, '/') . '[\"\\']/Ui',\n                            $images[1][$imgindex] . '=\"cid:' . $cid . '\"',\n                            $message\n                        );\n                    }\n                }\n            }\n        }\n        $this->isHTML(true);\n        // Convert all message body line breaks to CRLF, makes quoted-printable encoding work much better\n        $this->Body = $this->normalizeBreaks($message);\n        $this->AltBody = $this->normalizeBreaks($this->html2text($message, $advanced));\n        if (!$this->alternativeExists()) {\n            $this->AltBody = 'To view this email message, open it in a program that understands HTML!' .\n                self::CRLF . self::CRLF;\n        }\n        return $this->Body;\n    }\n\n    /**\n     * Convert an HTML string into plain text.\n     * This is used by msgHTML().\n     * Note - older versions of this function used a bundled advanced converter\n     * which was been removed for license reasons in #232.\n     * Example usage:\n     * <code>\n     * // Use default conversion\n     * $plain = $mail->html2text($html);\n     * // Use your own custom converter\n     * $plain = $mail->html2text($html, function($html) {\n     *     $converter = new MyHtml2text($html);\n     *     return $converter->get_text();\n     * });\n     * </code>\n     * @param string $html The HTML text to convert\n     * @param boolean|callable $advanced Any boolean value to use the internal converter,\n     *   or provide your own callable for custom conversion.\n     * @return string\n     */\n    public function html2text($html, $advanced = false)\n    {\n        if (is_callable($advanced)) {\n            return call_user_func($advanced, $html);\n        }\n        return html_entity_decode(\n            trim(strip_tags(preg_replace('/<(head|title|style|script)[^>]*>.*?<\\/\\\\1>/si', '', $html))),\n            ENT_QUOTES,\n            $this->CharSet\n        );\n    }\n\n    /**\n     * Get the MIME type for a file extension.\n     * @param string $ext File extension\n     * @access public\n     * @return string MIME type of file.\n     * @static\n     */\n    public static function _mime_types($ext = '')\n    {\n        $mimes = array(\n            'xl'    => 'application/excel',\n            'js'    => 'application/javascript',\n            'hqx'   => 'application/mac-binhex40',\n            'cpt'   => 'application/mac-compactpro',\n            'bin'   => 'application/macbinary',\n            'doc'   => 'application/msword',\n            'word'  => 'application/msword',\n            'xlsx'  => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n            'xltx'  => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',\n            'potx'  => 'application/vnd.openxmlformats-officedocument.presentationml.template',\n            'ppsx'  => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',\n            'pptx'  => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n            'sldx'  => 'application/vnd.openxmlformats-officedocument.presentationml.slide',\n            'docx'  => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n            'dotx'  => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',\n            'xlam'  => 'application/vnd.ms-excel.addin.macroEnabled.12',\n            'xlsb'  => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',\n            'class' => 'application/octet-stream',\n            'dll'   => 'application/octet-stream',\n            'dms'   => 'application/octet-stream',\n            'exe'   => 'application/octet-stream',\n            'lha'   => 'application/octet-stream',\n            'lzh'   => 'application/octet-stream',\n            'psd'   => 'application/octet-stream',\n            'sea'   => 'application/octet-stream',\n            'so'    => 'application/octet-stream',\n            'oda'   => 'application/oda',\n            'pdf'   => 'application/pdf',\n            'ai'    => 'application/postscript',\n            'eps'   => 'application/postscript',\n            'ps'    => 'application/postscript',\n            'smi'   => 'application/smil',\n            'smil'  => 'application/smil',\n            'mif'   => 'application/vnd.mif',\n            'xls'   => 'application/vnd.ms-excel',\n            'ppt'   => 'application/vnd.ms-powerpoint',\n            'wbxml' => 'application/vnd.wap.wbxml',\n            'wmlc'  => 'application/vnd.wap.wmlc',\n            'dcr'   => 'application/x-director',\n            'dir'   => 'application/x-director',\n            'dxr'   => 'application/x-director',\n            'dvi'   => 'application/x-dvi',\n            'gtar'  => 'application/x-gtar',\n            'php3'  => 'application/x-httpd-php',\n            'php4'  => 'application/x-httpd-php',\n            'php'   => 'application/x-httpd-php',\n            'phtml' => 'application/x-httpd-php',\n            'phps'  => 'application/x-httpd-php-source',\n            'swf'   => 'application/x-shockwave-flash',\n            'sit'   => 'application/x-stuffit',\n            'tar'   => 'application/x-tar',\n            'tgz'   => 'application/x-tar',\n            'xht'   => 'application/xhtml+xml',\n            'xhtml' => 'application/xhtml+xml',\n            'zip'   => 'application/zip',\n            'mid'   => 'audio/midi',\n            'midi'  => 'audio/midi',\n            'mp2'   => 'audio/mpeg',\n            'mp3'   => 'audio/mpeg',\n            'mpga'  => 'audio/mpeg',\n            'aif'   => 'audio/x-aiff',\n            'aifc'  => 'audio/x-aiff',\n            'aiff'  => 'audio/x-aiff',\n            'ram'   => 'audio/x-pn-realaudio',\n            'rm'    => 'audio/x-pn-realaudio',\n            'rpm'   => 'audio/x-pn-realaudio-plugin',\n            'ra'    => 'audio/x-realaudio',\n            'wav'   => 'audio/x-wav',\n            'bmp'   => 'image/bmp',\n            'gif'   => 'image/gif',\n            'jpeg'  => 'image/jpeg',\n            'jpe'   => 'image/jpeg',\n            'jpg'   => 'image/jpeg',\n            'png'   => 'image/png',\n            'tiff'  => 'image/tiff',\n            'tif'   => 'image/tiff',\n            'eml'   => 'message/rfc822',\n            'css'   => 'text/css',\n            'html'  => 'text/html',\n            'htm'   => 'text/html',\n            'shtml' => 'text/html',\n            'log'   => 'text/plain',\n            'text'  => 'text/plain',\n            'txt'   => 'text/plain',\n            'rtx'   => 'text/richtext',\n            'rtf'   => 'text/rtf',\n            'vcf'   => 'text/vcard',\n            'vcard' => 'text/vcard',\n            'xml'   => 'text/xml',\n            'xsl'   => 'text/xml',\n            'mpeg'  => 'video/mpeg',\n            'mpe'   => 'video/mpeg',\n            'mpg'   => 'video/mpeg',\n            'mov'   => 'video/quicktime',\n            'qt'    => 'video/quicktime',\n            'rv'    => 'video/vnd.rn-realvideo',\n            'avi'   => 'video/x-msvideo',\n            'movie' => 'video/x-sgi-movie'\n        );\n        if (array_key_exists(strtolower($ext), $mimes)) {\n            return $mimes[strtolower($ext)];\n        }\n        return 'application/octet-stream';\n    }\n\n    /**\n     * Map a file name to a MIME type.\n     * Defaults to 'application/octet-stream', i.e.. arbitrary binary data.\n     * @param string $filename A file name or full path, does not need to exist as a file\n     * @return string\n     * @static\n     */\n    public static function filenameToType($filename)\n    {\n        // In case the path is a URL, strip any query string before getting extension\n        $qpos = strpos($filename, '?');\n        if (false !== $qpos) {\n            $filename = substr($filename, 0, $qpos);\n        }\n        $pathinfo = self::mb_pathinfo($filename);\n        return self::_mime_types($pathinfo['extension']);\n    }\n\n    /**\n     * Multi-byte-safe pathinfo replacement.\n     * Drop-in replacement for pathinfo(), but multibyte-safe, cross-platform-safe, old-version-safe.\n     * Works similarly to the one in PHP >= 5.2.0\n     * @link http://www.php.net/manual/en/function.pathinfo.php#107461\n     * @param string $path A filename or path, does not need to exist as a file\n     * @param integer|string $options Either a PATHINFO_* constant,\n     *      or a string name to return only the specified piece, allows 'filename' to work on PHP < 5.2\n     * @return string|array\n     * @static\n     */\n    public static function mb_pathinfo($path, $options = null)\n    {\n        $ret = array('dirname' => '', 'basename' => '', 'extension' => '', 'filename' => '');\n        $pathinfo = array();\n        if (preg_match('%^(.*?)[\\\\\\\\/]*(([^/\\\\\\\\]*?)(\\.([^\\.\\\\\\\\/]+?)|))[\\\\\\\\/\\.]*$%im', $path, $pathinfo)) {\n            if (array_key_exists(1, $pathinfo)) {\n                $ret['dirname'] = $pathinfo[1];\n            }\n            if (array_key_exists(2, $pathinfo)) {\n                $ret['basename'] = $pathinfo[2];\n            }\n            if (array_key_exists(5, $pathinfo)) {\n                $ret['extension'] = $pathinfo[5];\n            }\n            if (array_key_exists(3, $pathinfo)) {\n                $ret['filename'] = $pathinfo[3];\n            }\n        }\n        switch ($options) {\n            case PATHINFO_DIRNAME:\n            case 'dirname':\n                return $ret['dirname'];\n            case PATHINFO_BASENAME:\n            case 'basename':\n                return $ret['basename'];\n            case PATHINFO_EXTENSION:\n            case 'extension':\n                return $ret['extension'];\n            case PATHINFO_FILENAME:\n            case 'filename':\n                return $ret['filename'];\n            default:\n                return $ret;\n        }\n    }\n\n    /**\n     * Set or reset instance properties.\n     * You should avoid this function - it's more verbose, less efficient, more error-prone and\n     * harder to debug than setting properties directly.\n     * Usage Example:\n     * `$mail->set('SMTPSecure', 'tls');`\n     *   is the same as:\n     * `$mail->SMTPSecure = 'tls';`\n     * @access public\n     * @param string $name The property name to set\n     * @param mixed $value The value to set the property to\n     * @return boolean\n     * @TODO Should this not be using the __set() magic function?\n     */\n    public function set($name, $value = '')\n    {\n        if (property_exists($this, $name)) {\n            $this->$name = $value;\n            return true;\n        } else {\n            $this->setError($this->lang('variable_set') . $name);\n            return false;\n        }\n    }\n\n    /**\n     * Strip newlines to prevent header injection.\n     * @access public\n     * @param string $str\n     * @return string\n     */\n    public function secureHeader($str)\n    {\n        return trim(str_replace(array(\"\\r\", \"\\n\"), '', $str));\n    }\n\n    /**\n     * Normalize line breaks in a string.\n     * Converts UNIX LF, Mac CR and Windows CRLF line breaks into a single line break format.\n     * Defaults to CRLF (for message bodies) and preserves consecutive breaks.\n     * @param string $text\n     * @param string $breaktype What kind of line break to use, defaults to CRLF\n     * @return string\n     * @access public\n     * @static\n     */\n    public static function normalizeBreaks($text, $breaktype = \"\\r\\n\")\n    {\n        return preg_replace('/(\\r\\n|\\r|\\n)/ms', $breaktype, $text);\n    }\n\n    /**\n     * Set the public and private key files and password for S/MIME signing.\n     * @access public\n     * @param string $cert_filename\n     * @param string $key_filename\n     * @param string $key_pass Password for private key\n     * @param string $extracerts_filename Optional path to chain certificate\n     */\n    public function sign($cert_filename, $key_filename, $key_pass, $extracerts_filename = '')\n    {\n        $this->sign_cert_file = $cert_filename;\n        $this->sign_key_file = $key_filename;\n        $this->sign_key_pass = $key_pass;\n        $this->sign_extracerts_file = $extracerts_filename;\n    }\n\n    /**\n     * Quoted-Printable-encode a DKIM header.\n     * @access public\n     * @param string $txt\n     * @return string\n     */\n    public function DKIM_QP($txt)\n    {\n        $line = '';\n        for ($i = 0; $i < strlen($txt); $i++) {\n            $ord = ord($txt[$i]);\n            if (((0x21 <= $ord) && ($ord <= 0x3A)) || $ord == 0x3C || ((0x3E <= $ord) && ($ord <= 0x7E))) {\n                $line .= $txt[$i];\n            } else {\n                $line .= '=' . sprintf('%02X', $ord);\n            }\n        }\n        return $line;\n    }\n\n    /**\n     * Generate a DKIM signature.\n     * @access public\n     * @param string $signHeader\n     * @throws phpmailerException\n     * @return string The DKIM signature value\n     */\n    public function DKIM_Sign($signHeader)\n    {\n        if (!defined('PKCS7_TEXT')) {\n            if ($this->exceptions) {\n                throw new phpmailerException($this->lang('extension_missing') . 'openssl');\n            }\n            return '';\n        }\n        $privKeyStr = !empty($this->DKIM_private_string) ? $this->DKIM_private_string : file_get_contents($this->DKIM_private);\n        if ('' != $this->DKIM_passphrase) {\n            $privKey = openssl_pkey_get_private($privKeyStr, $this->DKIM_passphrase);\n        } else {\n            $privKey = openssl_pkey_get_private($privKeyStr);\n        }\n        //Workaround for missing digest algorithms in old PHP & OpenSSL versions\n        //@link http://stackoverflow.com/a/11117338/333340\n        if (version_compare(PHP_VERSION, '5.3.0') >= 0 and\n            in_array('sha256WithRSAEncryption', openssl_get_md_methods(true))) {\n            if (openssl_sign($signHeader, $signature, $privKey, 'sha256WithRSAEncryption')) {\n                openssl_pkey_free($privKey);\n                return base64_encode($signature);\n            }\n        } else {\n            $pinfo = openssl_pkey_get_details($privKey);\n            $hash = hash('sha256', $signHeader);\n            //'Magic' constant for SHA256 from RFC3447\n            //@link https://tools.ietf.org/html/rfc3447#page-43\n            $t = '3031300d060960864801650304020105000420' . $hash;\n            $pslen = $pinfo['bits'] / 8 - (strlen($t) / 2 + 3);\n            $eb = pack('H*', '0001' . str_repeat('FF', $pslen) . '00' . $t);\n\n            if (openssl_private_encrypt($eb, $signature, $privKey, OPENSSL_NO_PADDING)) {\n                openssl_pkey_free($privKey);\n                return base64_encode($signature);\n            }\n        }\n        openssl_pkey_free($privKey);\n        return '';\n    }\n\n    /**\n     * Generate a DKIM canonicalization header.\n     * @access public\n     * @param string $signHeader Header\n     * @return string\n     */\n    public function DKIM_HeaderC($signHeader)\n    {\n        $signHeader = preg_replace('/\\r\\n\\s+/', ' ', $signHeader);\n        $lines = explode(\"\\r\\n\", $signHeader);\n        foreach ($lines as $key => $line) {\n            list($heading, $value) = explode(':', $line, 2);\n            $heading = strtolower($heading);\n            $value = preg_replace('/\\s{2,}/', ' ', $value); // Compress useless spaces\n            $lines[$key] = $heading . ':' . trim($value); // Don't forget to remove WSP around the value\n        }\n        $signHeader = implode(\"\\r\\n\", $lines);\n        return $signHeader;\n    }\n\n    /**\n     * Generate a DKIM canonicalization body.\n     * @access public\n     * @param string $body Message Body\n     * @return string\n     */\n    public function DKIM_BodyC($body)\n    {\n        if ($body == '') {\n            return \"\\r\\n\";\n        }\n        // stabilize line endings\n        $body = str_replace(\"\\r\\n\", \"\\n\", $body);\n        $body = str_replace(\"\\n\", \"\\r\\n\", $body);\n        // END stabilize line endings\n        while (substr($body, strlen($body) - 4, 4) == \"\\r\\n\\r\\n\") {\n            $body = substr($body, 0, strlen($body) - 2);\n        }\n        return $body;\n    }\n\n    /**\n     * Create the DKIM header and body in a new message header.\n     * @access public\n     * @param string $headers_line Header lines\n     * @param string $subject Subject\n     * @param string $body Body\n     * @return string\n     */\n    public function DKIM_Add($headers_line, $subject, $body)\n    {\n        $DKIMsignatureType = 'rsa-sha256'; // Signature & hash algorithms\n        $DKIMcanonicalization = 'relaxed/simple'; // Canonicalization of header/body\n        $DKIMquery = 'dns/txt'; // Query method\n        $DKIMtime = time(); // Signature Timestamp = seconds since 00:00:00 - Jan 1, 1970 (UTC time zone)\n        $subject_header = \"Subject: $subject\";\n        $headers = explode($this->LE, $headers_line);\n        $from_header = '';\n        $to_header = '';\n        $date_header = '';\n        $current = '';\n        foreach ($headers as $header) {\n            if (strpos($header, 'From:') === 0) {\n                $from_header = $header;\n                $current = 'from_header';\n            } elseif (strpos($header, 'To:') === 0) {\n                $to_header = $header;\n                $current = 'to_header';\n            } elseif (strpos($header, 'Date:') === 0) {\n                $date_header = $header;\n                $current = 'date_header';\n            } else {\n                if (!empty($$current) && strpos($header, ' =?') === 0) {\n                    $$current .= $header;\n                } else {\n                    $current = '';\n                }\n            }\n        }\n        $from = str_replace('|', '=7C', $this->DKIM_QP($from_header));\n        $to = str_replace('|', '=7C', $this->DKIM_QP($to_header));\n        $date = str_replace('|', '=7C', $this->DKIM_QP($date_header));\n        $subject = str_replace(\n            '|',\n            '=7C',\n            $this->DKIM_QP($subject_header)\n        ); // Copied header fields (dkim-quoted-printable)\n        $body = $this->DKIM_BodyC($body);\n        $DKIMlen = strlen($body); // Length of body\n        $DKIMb64 = base64_encode(pack('H*', hash('sha256', $body))); // Base64 of packed binary SHA-256 hash of body\n        if ('' == $this->DKIM_identity) {\n            $ident = '';\n        } else {\n            $ident = ' i=' . $this->DKIM_identity . ';';\n        }\n        $dkimhdrs = 'DKIM-Signature: v=1; a=' .\n            $DKIMsignatureType . '; q=' .\n            $DKIMquery . '; l=' .\n            $DKIMlen . '; s=' .\n            $this->DKIM_selector .\n            \";\\r\\n\" .\n            \"\\tt=\" . $DKIMtime . '; c=' . $DKIMcanonicalization . \";\\r\\n\" .\n            \"\\th=From:To:Date:Subject;\\r\\n\" .\n            \"\\td=\" . $this->DKIM_domain . ';' . $ident . \"\\r\\n\" .\n            \"\\tz=$from\\r\\n\" .\n            \"\\t|$to\\r\\n\" .\n            \"\\t|$date\\r\\n\" .\n            \"\\t|$subject;\\r\\n\" .\n            \"\\tbh=\" . $DKIMb64 . \";\\r\\n\" .\n            \"\\tb=\";\n        $toSign = $this->DKIM_HeaderC(\n            $from_header . \"\\r\\n\" .\n            $to_header . \"\\r\\n\" .\n            $date_header . \"\\r\\n\" .\n            $subject_header . \"\\r\\n\" .\n            $dkimhdrs\n        );\n        $signed = $this->DKIM_Sign($toSign);\n        return $dkimhdrs . $signed . \"\\r\\n\";\n    }\n\n    /**\n     * Detect if a string contains a line longer than the maximum line length allowed.\n     * @param string $str\n     * @return boolean\n     * @static\n     */\n    public static function hasLineLongerThanMax($str)\n    {\n        //+2 to include CRLF line break for a 1000 total\n        return (boolean)preg_match('/^(.{'.(self::MAX_LINE_LENGTH + 2).',})/m', $str);\n    }\n\n    /**\n     * Allows for public read access to 'to' property.\n     * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.\n     * @access public\n     * @return array\n     */\n    public function getToAddresses()\n    {\n        return $this->to;\n    }\n\n    /**\n     * Allows for public read access to 'cc' property.\n     * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.\n     * @access public\n     * @return array\n     */\n    public function getCcAddresses()\n    {\n        return $this->cc;\n    }\n\n    /**\n     * Allows for public read access to 'bcc' property.\n     * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.\n     * @access public\n     * @return array\n     */\n    public function getBccAddresses()\n    {\n        return $this->bcc;\n    }\n\n    /**\n     * Allows for public read access to 'ReplyTo' property.\n     * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.\n     * @access public\n     * @return array\n     */\n    public function getReplyToAddresses()\n    {\n        return $this->ReplyTo;\n    }\n\n    /**\n     * Allows for public read access to 'all_recipients' property.\n     * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included.\n     * @access public\n     * @return array\n     */\n    public function getAllRecipientAddresses()\n    {\n        return $this->all_recipients;\n    }\n\n    /**\n     * Perform a callback.\n     * @param boolean $isSent\n     * @param array $to\n     * @param array $cc\n     * @param array $bcc\n     * @param string $subject\n     * @param string $body\n     * @param string $from\n     */\n    protected function doCallback($isSent, $to, $cc, $bcc, $subject, $body, $from)\n    {\n        if (!empty($this->action_function) && is_callable($this->action_function)) {\n            $params = array($isSent, $to, $cc, $bcc, $subject, $body, $from);\n            call_user_func_array($this->action_function, $params);\n        }\n    }\n}\n\n/**\n * PHPMailer exception handler\n * @package PHPMailer\n */\nclass phpmailerException extends Exception\n{\n    /**\n     * Prettify error message output\n     * @return string\n     */\n    public function errorMessage()\n    {\n        $errorMsg = '<strong>' . $this->getMessage() . \"</strong><br />\\n\";\n        return $errorMsg;\n    }\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/class.phpmaileroauth.php",
    "content": "<?php\n/**\n * PHPMailer - PHP email creation and transport class.\n * PHP Version 5.4\n * @package PHPMailer\n * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project\n * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>\n * @author Jim Jagielski (jimjag) <jimjag@gmail.com>\n * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>\n * @author Brent R. Matzelle (original founder)\n * @copyright 2012 - 2014 Marcus Bointon\n * @copyright 2010 - 2012 Jim Jagielski\n * @copyright 2004 - 2009 Andy Prevost\n * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License\n * @note This program is distributed in the hope that it will be useful - WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.\n */\n\n/**\n * PHPMailerOAuth - PHPMailer subclass adding OAuth support.\n * @package PHPMailer\n * @author @sherryl4george\n * @author Marcus Bointon (@Synchro) <phpmailer@synchromedia.co.uk>\n */\nclass PHPMailerOAuth extends PHPMailer\n{\n    /**\n     * The OAuth user's email address\n     * @var string\n     */\n    public $oauthUserEmail = '';\n\n    /**\n     * The OAuth refresh token\n     * @var string\n     */\n    public $oauthRefreshToken = '';\n\n    /**\n     * The OAuth client ID\n     * @var string\n     */\n    public $oauthClientId = '';\n\n    /**\n     * The OAuth client secret\n     * @var string\n     */\n    public $oauthClientSecret = '';\n\n    /**\n     * An instance of the PHPMailerOAuthGoogle class.\n     * @var PHPMailerOAuthGoogle\n     * @access protected\n     */\n    protected $oauth = null;\n\n    /**\n     * Get a PHPMailerOAuthGoogle instance to use.\n     * @return PHPMailerOAuthGoogle\n     */\n    public function getOAUTHInstance()\n    {\n        if (!is_object($this->oauth)) {\n            $this->oauth = new PHPMailerOAuthGoogle(\n                $this->oauthUserEmail,\n                $this->oauthClientSecret,\n                $this->oauthClientId,\n                $this->oauthRefreshToken\n            );\n        }\n        return $this->oauth;\n    }\n\n    /**\n     * Initiate a connection to an SMTP server.\n     * Overrides the original smtpConnect method to add support for OAuth.\n     * @param array $options An array of options compatible with stream_context_create()\n     * @uses SMTP\n     * @access public\n     * @return bool\n     * @throws phpmailerException\n     */\n    public function smtpConnect($options = array())\n    {\n        if (is_null($this->smtp)) {\n            $this->smtp = $this->getSMTPInstance();\n        }\n\n        if (is_null($this->oauth)) {\n            $this->oauth = $this->getOAUTHInstance();\n        }\n\n        // Already connected?\n        if ($this->smtp->connected()) {\n            return true;\n        }\n\n        $this->smtp->setTimeout($this->Timeout);\n        $this->smtp->setDebugLevel($this->SMTPDebug);\n        $this->smtp->setDebugOutput($this->Debugoutput);\n        $this->smtp->setVerp($this->do_verp);\n        $hosts = explode(';', $this->Host);\n        $lastexception = null;\n\n        foreach ($hosts as $hostentry) {\n            $hostinfo = array();\n            if (!preg_match('/^((ssl|tls):\\/\\/)*([a-zA-Z0-9\\.-]*):?([0-9]*)$/', trim($hostentry), $hostinfo)) {\n                // Not a valid host entry\n                continue;\n            }\n            // $hostinfo[2]: optional ssl or tls prefix\n            // $hostinfo[3]: the hostname\n            // $hostinfo[4]: optional port number\n            // The host string prefix can temporarily override the current setting for SMTPSecure\n            // If it's not specified, the default value is used\n            $prefix = '';\n            $secure = $this->SMTPSecure;\n            $tls = ($this->SMTPSecure == 'tls');\n            if ('ssl' == $hostinfo[2] or ('' == $hostinfo[2] and 'ssl' == $this->SMTPSecure)) {\n                $prefix = 'ssl://';\n                $tls = false; // Can't have SSL and TLS at the same time\n                $secure = 'ssl';\n            } elseif ($hostinfo[2] == 'tls') {\n                $tls = true;\n                // tls doesn't use a prefix\n                $secure = 'tls';\n            }\n            //Do we need the OpenSSL extension?\n            $sslext = defined('OPENSSL_ALGO_SHA1');\n            if ('tls' === $secure or 'ssl' === $secure) {\n                //Check for an OpenSSL constant rather than using extension_loaded, which is sometimes disabled\n                if (!$sslext) {\n                    throw new phpmailerException($this->lang('extension_missing').'openssl', self::STOP_CRITICAL);\n                }\n            }\n            $host = $hostinfo[3];\n            $port = $this->Port;\n            $tport = (integer)$hostinfo[4];\n            if ($tport > 0 and $tport < 65536) {\n                $port = $tport;\n            }\n            if ($this->smtp->connect($prefix . $host, $port, $this->Timeout, $options)) {\n                try {\n                    if ($this->Helo) {\n                        $hello = $this->Helo;\n                    } else {\n                        $hello = $this->serverHostname();\n                    }\n                    $this->smtp->hello($hello);\n                    //Automatically enable TLS encryption if:\n                    // * it's not disabled\n                    // * we have openssl extension\n                    // * we are not already using SSL\n                    // * the server offers STARTTLS\n                    if ($this->SMTPAutoTLS and $sslext and $secure != 'ssl' and $this->smtp->getServerExt('STARTTLS')) {\n                        $tls = true;\n                    }\n                    if ($tls) {\n                        if (!$this->smtp->startTLS()) {\n                            throw new phpmailerException($this->lang('connect_host'));\n                        }\n                        // We must resend HELO after tls negotiation\n                        $this->smtp->hello($hello);\n                    }\n                    if ($this->SMTPAuth) {\n                        if (!$this->smtp->authenticate(\n                            $this->Username,\n                            $this->Password,\n                            $this->AuthType,\n                            $this->Realm,\n                            $this->Workstation,\n                            $this->oauth\n                        )\n                        ) {\n                            throw new phpmailerException($this->lang('authenticate'));\n                        }\n                    }\n                    return true;\n                } catch (phpmailerException $exc) {\n                    $lastexception = $exc;\n                    $this->edebug($exc->getMessage());\n                    // We must have connected, but then failed TLS or Auth, so close connection nicely\n                    $this->smtp->quit();\n                }\n            }\n        }\n        // If we get here, all connection attempts have failed, so close connection hard\n        $this->smtp->close();\n        // As we've caught all exceptions, just report whatever the last one was\n        if ($this->exceptions and !is_null($lastexception)) {\n            throw $lastexception;\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/class.phpmaileroauthgoogle.php",
    "content": "<?php\n/**\n * PHPMailer - PHP email creation and transport class.\n * PHP Version 5.4\n * @package PHPMailer\n * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project\n * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>\n * @author Jim Jagielski (jimjag) <jimjag@gmail.com>\n * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>\n * @author Brent R. Matzelle (original founder)\n * @copyright 2012 - 2014 Marcus Bointon\n * @copyright 2010 - 2012 Jim Jagielski\n * @copyright 2004 - 2009 Andy Prevost\n * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License\n * @note This program is distributed in the hope that it will be useful - WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.\n */\n\n/**\n * PHPMailerOAuthGoogle - Wrapper for League OAuth2 Google provider.\n * @package PHPMailer\n * @author @sherryl4george\n * @author Marcus Bointon (@Synchro) <phpmailer@synchromedia.co.uk>\n * @link https://github.com/thephpleague/oauth2-client\n */\nclass PHPMailerOAuthGoogle\n{\n    private $oauthUserEmail = '';\n    private $oauthRefreshToken = '';\n    private $oauthClientId = '';\n    private $oauthClientSecret = '';\n\n    /**\n     * @param string $UserEmail\n     * @param string $ClientSecret\n     * @param string $ClientId\n     * @param string $RefreshToken\n     */\n    public function __construct(\n        $UserEmail,\n        $ClientSecret,\n        $ClientId,\n        $RefreshToken\n    ) {\n        $this->oauthClientId = $ClientId;\n        $this->oauthClientSecret = $ClientSecret;\n        $this->oauthRefreshToken = $RefreshToken;\n        $this->oauthUserEmail = $UserEmail;\n    }\n\n    private function getProvider()\n    {\n        return new League\\OAuth2\\Client\\Provider\\Google([\n            'clientId' => $this->oauthClientId,\n            'clientSecret' => $this->oauthClientSecret\n        ]);\n    }\n\n    private function getGrant()\n    {\n        return new \\League\\OAuth2\\Client\\Grant\\RefreshToken();\n    }\n\n    private function getToken()\n    {\n        $provider = $this->getProvider();\n        $grant = $this->getGrant();\n        return $provider->getAccessToken($grant, ['refresh_token' => $this->oauthRefreshToken]);\n    }\n\n    public function getOauth64()\n    {\n        $token = $this->getToken();\n        return base64_encode(\"user=\" . $this->oauthUserEmail . \"\\001auth=Bearer \" . $token . \"\\001\\001\");\n    }\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/class.pop3.php",
    "content": "<?php\n/**\n * PHPMailer POP-Before-SMTP Authentication Class.\n * PHP Version 5\n * @package PHPMailer\n * @link https://github.com/PHPMailer/PHPMailer/\n * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>\n * @author Jim Jagielski (jimjag) <jimjag@gmail.com>\n * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>\n * @author Brent R. Matzelle (original founder)\n * @copyright 2012 - 2014 Marcus Bointon\n * @copyright 2010 - 2012 Jim Jagielski\n * @copyright 2004 - 2009 Andy Prevost\n * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License\n * @note This program is distributed in the hope that it will be useful - WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.\n */\n\n/**\n * PHPMailer POP-Before-SMTP Authentication Class.\n * Specifically for PHPMailer to use for RFC1939 POP-before-SMTP authentication.\n * Does not support APOP.\n * @package PHPMailer\n * @author Richard Davey (original author) <rich@corephp.co.uk>\n * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>\n * @author Jim Jagielski (jimjag) <jimjag@gmail.com>\n * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>\n */\nclass POP3\n{\n    /**\n     * The POP3 PHPMailer Version number.\n     * @var string\n     * @access public\n     */\n    public $Version = '5.2.23';\n\n    /**\n     * Default POP3 port number.\n     * @var integer\n     * @access public\n     */\n    public $POP3_PORT = 110;\n\n    /**\n     * Default timeout in seconds.\n     * @var integer\n     * @access public\n     */\n    public $POP3_TIMEOUT = 30;\n\n    /**\n     * POP3 Carriage Return + Line Feed.\n     * @var string\n     * @access public\n     * @deprecated Use the constant instead\n     */\n    public $CRLF = \"\\r\\n\";\n\n    /**\n     * Debug display level.\n     * Options: 0 = no, 1+ = yes\n     * @var integer\n     * @access public\n     */\n    public $do_debug = 0;\n\n    /**\n     * POP3 mail server hostname.\n     * @var string\n     * @access public\n     */\n    public $host;\n\n    /**\n     * POP3 port number.\n     * @var integer\n     * @access public\n     */\n    public $port;\n\n    /**\n     * POP3 Timeout Value in seconds.\n     * @var integer\n     * @access public\n     */\n    public $tval;\n\n    /**\n     * POP3 username\n     * @var string\n     * @access public\n     */\n    public $username;\n\n    /**\n     * POP3 password.\n     * @var string\n     * @access public\n     */\n    public $password;\n\n    /**\n     * Resource handle for the POP3 connection socket.\n     * @var resource\n     * @access protected\n     */\n    protected $pop_conn;\n\n    /**\n     * Are we connected?\n     * @var boolean\n     * @access protected\n     */\n    protected $connected = false;\n\n    /**\n     * Error container.\n     * @var array\n     * @access protected\n     */\n    protected $errors = array();\n\n    /**\n     * Line break constant\n     */\n    const CRLF = \"\\r\\n\";\n\n    /**\n     * Simple static wrapper for all-in-one POP before SMTP\n     * @param $host\n     * @param integer|boolean $port The port number to connect to\n     * @param integer|boolean $timeout The timeout value\n     * @param string $username\n     * @param string $password\n     * @param integer $debug_level\n     * @return boolean\n     */\n    public static function popBeforeSmtp(\n        $host,\n        $port = false,\n        $timeout = false,\n        $username = '',\n        $password = '',\n        $debug_level = 0\n    ) {\n        $pop = new POP3;\n        return $pop->authorise($host, $port, $timeout, $username, $password, $debug_level);\n    }\n\n    /**\n     * Authenticate with a POP3 server.\n     * A connect, login, disconnect sequence\n     * appropriate for POP-before SMTP authorisation.\n     * @access public\n     * @param string $host The hostname to connect to\n     * @param integer|boolean $port The port number to connect to\n     * @param integer|boolean $timeout The timeout value\n     * @param string $username\n     * @param string $password\n     * @param integer $debug_level\n     * @return boolean\n     */\n    public function authorise($host, $port = false, $timeout = false, $username = '', $password = '', $debug_level = 0)\n    {\n        $this->host = $host;\n        // If no port value provided, use default\n        if (false === $port) {\n            $this->port = $this->POP3_PORT;\n        } else {\n            $this->port = (integer)$port;\n        }\n        // If no timeout value provided, use default\n        if (false === $timeout) {\n            $this->tval = $this->POP3_TIMEOUT;\n        } else {\n            $this->tval = (integer)$timeout;\n        }\n        $this->do_debug = $debug_level;\n        $this->username = $username;\n        $this->password = $password;\n        //  Reset the error log\n        $this->errors = array();\n        //  connect\n        $result = $this->connect($this->host, $this->port, $this->tval);\n        if ($result) {\n            $login_result = $this->login($this->username, $this->password);\n            if ($login_result) {\n                $this->disconnect();\n                return true;\n            }\n        }\n        // We need to disconnect regardless of whether the login succeeded\n        $this->disconnect();\n        return false;\n    }\n\n    /**\n     * Connect to a POP3 server.\n     * @access public\n     * @param string $host\n     * @param integer|boolean $port\n     * @param integer $tval\n     * @return boolean\n     */\n    public function connect($host, $port = false, $tval = 30)\n    {\n        //  Are we already connected?\n        if ($this->connected) {\n            return true;\n        }\n\n        //On Windows this will raise a PHP Warning error if the hostname doesn't exist.\n        //Rather than suppress it with @fsockopen, capture it cleanly instead\n        set_error_handler(array($this, 'catchWarning'));\n\n        if (false === $port) {\n            $port = $this->POP3_PORT;\n        }\n\n        //  connect to the POP3 server\n        $this->pop_conn = fsockopen(\n            $host, //  POP3 Host\n            $port, //  Port #\n            $errno, //  Error Number\n            $errstr, //  Error Message\n            $tval\n        ); //  Timeout (seconds)\n        //  Restore the error handler\n        restore_error_handler();\n\n        //  Did we connect?\n        if (false === $this->pop_conn) {\n            //  It would appear not...\n            $this->setError(array(\n                'error' => \"Failed to connect to server $host on port $port\",\n                'errno' => $errno,\n                'errstr' => $errstr\n            ));\n            return false;\n        }\n\n        //  Increase the stream time-out\n        stream_set_timeout($this->pop_conn, $tval, 0);\n\n        //  Get the POP3 server response\n        $pop3_response = $this->getResponse();\n        //  Check for the +OK\n        if ($this->checkResponse($pop3_response)) {\n            //  The connection is established and the POP3 server is talking\n            $this->connected = true;\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * Log in to the POP3 server.\n     * Does not support APOP (RFC 2828, 4949).\n     * @access public\n     * @param string $username\n     * @param string $password\n     * @return boolean\n     */\n    public function login($username = '', $password = '')\n    {\n        if (!$this->connected) {\n            $this->setError('Not connected to POP3 server');\n        }\n        if (empty($username)) {\n            $username = $this->username;\n        }\n        if (empty($password)) {\n            $password = $this->password;\n        }\n\n        // Send the Username\n        $this->sendString(\"USER $username\" . self::CRLF);\n        $pop3_response = $this->getResponse();\n        if ($this->checkResponse($pop3_response)) {\n            // Send the Password\n            $this->sendString(\"PASS $password\" . self::CRLF);\n            $pop3_response = $this->getResponse();\n            if ($this->checkResponse($pop3_response)) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Disconnect from the POP3 server.\n     * @access public\n     */\n    public function disconnect()\n    {\n        $this->sendString('QUIT');\n        //The QUIT command may cause the daemon to exit, which will kill our connection\n        //So ignore errors here\n        try {\n            @fclose($this->pop_conn);\n        } catch (Exception $e) {\n            //Do nothing\n        };\n    }\n\n    /**\n     * Get a response from the POP3 server.\n     * $size is the maximum number of bytes to retrieve\n     * @param integer $size\n     * @return string\n     * @access protected\n     */\n    protected function getResponse($size = 128)\n    {\n        $response = fgets($this->pop_conn, $size);\n        if ($this->do_debug >= 1) {\n            echo \"Server -> Client: $response\";\n        }\n        return $response;\n    }\n\n    /**\n     * Send raw data to the POP3 server.\n     * @param string $string\n     * @return integer\n     * @access protected\n     */\n    protected function sendString($string)\n    {\n        if ($this->pop_conn) {\n            if ($this->do_debug >= 2) { //Show client messages when debug >= 2\n                echo \"Client -> Server: $string\";\n            }\n            return fwrite($this->pop_conn, $string, strlen($string));\n        }\n        return 0;\n    }\n\n    /**\n     * Checks the POP3 server response.\n     * Looks for for +OK or -ERR.\n     * @param string $string\n     * @return boolean\n     * @access protected\n     */\n    protected function checkResponse($string)\n    {\n        if (substr($string, 0, 3) !== '+OK') {\n            $this->setError(array(\n                'error' => \"Server reported an error: $string\",\n                'errno' => 0,\n                'errstr' => ''\n            ));\n            return false;\n        } else {\n            return true;\n        }\n    }\n\n    /**\n     * Add an error to the internal error store.\n     * Also display debug output if it's enabled.\n     * @param $error\n     * @access protected\n     */\n    protected function setError($error)\n    {\n        $this->errors[] = $error;\n        if ($this->do_debug >= 1) {\n            echo '<pre>';\n            foreach ($this->errors as $error) {\n                print_r($error);\n            }\n            echo '</pre>';\n        }\n    }\n\n    /**\n     * Get an array of error messages, if any.\n     * @return array\n     */\n    public function getErrors()\n    {\n        return $this->errors;\n    }\n\n    /**\n     * POP3 connection error handler.\n     * @param integer $errno\n     * @param string $errstr\n     * @param string $errfile\n     * @param integer $errline\n     * @access protected\n     */\n    protected function catchWarning($errno, $errstr, $errfile, $errline)\n    {\n        $this->setError(array(\n            'error' => \"Connecting to the POP3 server raised a PHP warning: \",\n            'errno' => $errno,\n            'errstr' => $errstr,\n            'errfile' => $errfile,\n            'errline' => $errline\n        ));\n    }\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/class.smtp.php",
    "content": "<?php\n/**\n * PHPMailer RFC821 SMTP email transport class.\n * PHP Version 5\n * @package PHPMailer\n * @link https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project\n * @author Marcus Bointon (Synchro/coolbru) <phpmailer@synchromedia.co.uk>\n * @author Jim Jagielski (jimjag) <jimjag@gmail.com>\n * @author Andy Prevost (codeworxtech) <codeworxtech@users.sourceforge.net>\n * @author Brent R. Matzelle (original founder)\n * @copyright 2014 Marcus Bointon\n * @copyright 2010 - 2012 Jim Jagielski\n * @copyright 2004 - 2009 Andy Prevost\n * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License\n * @note This program is distributed in the hope that it will be useful - WITHOUT\n * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n * FITNESS FOR A PARTICULAR PURPOSE.\n */\n\n/**\n * PHPMailer RFC821 SMTP email transport class.\n * Implements RFC 821 SMTP commands and provides some utility methods for sending mail to an SMTP server.\n * @package PHPMailer\n * @author Chris Ryan\n * @author Marcus Bointon <phpmailer@synchromedia.co.uk>\n */\nclass SMTP\n{\n    /**\n     * The PHPMailer SMTP version number.\n     * @var string\n     */\n    const VERSION = '5.2.23';\n\n    /**\n     * SMTP line break constant.\n     * @var string\n     */\n    const CRLF = \"\\r\\n\";\n\n    /**\n     * The SMTP port to use if one is not specified.\n     * @var integer\n     */\n    const DEFAULT_SMTP_PORT = 25;\n\n    /**\n     * The maximum line length allowed by RFC 2822 section 2.1.1\n     * @var integer\n     */\n    const MAX_LINE_LENGTH = 998;\n\n    /**\n     * Debug level for no output\n     */\n    const DEBUG_OFF = 0;\n\n    /**\n     * Debug level to show client -> server messages\n     */\n    const DEBUG_CLIENT = 1;\n\n    /**\n     * Debug level to show client -> server and server -> client messages\n     */\n    const DEBUG_SERVER = 2;\n\n    /**\n     * Debug level to show connection status, client -> server and server -> client messages\n     */\n    const DEBUG_CONNECTION = 3;\n\n    /**\n     * Debug level to show all messages\n     */\n    const DEBUG_LOWLEVEL = 4;\n\n    /**\n     * The PHPMailer SMTP Version number.\n     * @var string\n     * @deprecated Use the `VERSION` constant instead\n     * @see SMTP::VERSION\n     */\n    public $Version = '5.2.23';\n\n    /**\n     * SMTP server port number.\n     * @var integer\n     * @deprecated This is only ever used as a default value, so use the `DEFAULT_SMTP_PORT` constant instead\n     * @see SMTP::DEFAULT_SMTP_PORT\n     */\n    public $SMTP_PORT = 25;\n\n    /**\n     * SMTP reply line ending.\n     * @var string\n     * @deprecated Use the `CRLF` constant instead\n     * @see SMTP::CRLF\n     */\n    public $CRLF = \"\\r\\n\";\n\n    /**\n     * Debug output level.\n     * Options:\n     * * self::DEBUG_OFF (`0`) No debug output, default\n     * * self::DEBUG_CLIENT (`1`) Client commands\n     * * self::DEBUG_SERVER (`2`) Client commands and server responses\n     * * self::DEBUG_CONNECTION (`3`) As DEBUG_SERVER plus connection status\n     * * self::DEBUG_LOWLEVEL (`4`) Low-level data output, all messages\n     * @var integer\n     */\n    public $do_debug = self::DEBUG_OFF;\n\n    /**\n     * How to handle debug output.\n     * Options:\n     * * `echo` Output plain-text as-is, appropriate for CLI\n     * * `html` Output escaped, line breaks converted to `<br>`, appropriate for browser output\n     * * `error_log` Output to error log as configured in php.ini\n     *\n     * Alternatively, you can provide a callable expecting two params: a message string and the debug level:\n     * <code>\n     * $smtp->Debugoutput = function($str, $level) {echo \"debug level $level; message: $str\";};\n     * </code>\n     * @var string|callable\n     */\n    public $Debugoutput = 'echo';\n\n    /**\n     * Whether to use VERP.\n     * @link http://en.wikipedia.org/wiki/Variable_envelope_return_path\n     * @link http://www.postfix.org/VERP_README.html Info on VERP\n     * @var boolean\n     */\n    public $do_verp = false;\n\n    /**\n     * The timeout value for connection, in seconds.\n     * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2\n     * This needs to be quite high to function correctly with hosts using greetdelay as an anti-spam measure.\n     * @link http://tools.ietf.org/html/rfc2821#section-4.5.3.2\n     * @var integer\n     */\n    public $Timeout = 300;\n\n    /**\n     * How long to wait for commands to complete, in seconds.\n     * Default of 5 minutes (300sec) is from RFC2821 section 4.5.3.2\n     * @var integer\n     */\n    public $Timelimit = 300;\n\n    /**\n     * @var array patterns to extract smtp transaction id from smtp reply\n     * Only first capture group will be use, use non-capturing group to deal with it\n     * Extend this class to override this property to fulfil your needs.\n     */\n    protected $smtp_transaction_id_patterns = array(\n        'exim' => '/[0-9]{3} OK id=(.*)/',\n        'sendmail' => '/[0-9]{3} 2.0.0 (.*) Message/',\n        'postfix' => '/[0-9]{3} 2.0.0 Ok: queued as (.*)/'\n    );\n\n    /**\n     * The socket for the server connection.\n     * @var resource\n     */\n    protected $smtp_conn;\n\n    /**\n     * Error information, if any, for the last SMTP command.\n     * @var array\n     */\n    protected $error = array(\n        'error' => '',\n        'detail' => '',\n        'smtp_code' => '',\n        'smtp_code_ex' => ''\n    );\n\n    /**\n     * The reply the server sent to us for HELO.\n     * If null, no HELO string has yet been received.\n     * @var string|null\n     */\n    protected $helo_rply = null;\n\n    /**\n     * The set of SMTP extensions sent in reply to EHLO command.\n     * Indexes of the array are extension names.\n     * Value at index 'HELO' or 'EHLO' (according to command that was sent)\n     * represents the server name. In case of HELO it is the only element of the array.\n     * Other values can be boolean TRUE or an array containing extension options.\n     * If null, no HELO/EHLO string has yet been received.\n     * @var array|null\n     */\n    protected $server_caps = null;\n\n    /**\n     * The most recent reply received from the server.\n     * @var string\n     */\n    protected $last_reply = '';\n\n    /**\n     * Output debugging info via a user-selected method.\n     * @see SMTP::$Debugoutput\n     * @see SMTP::$do_debug\n     * @param string $str Debug string to output\n     * @param integer $level The debug level of this message; see DEBUG_* constants\n     * @return void\n     */\n    protected function edebug($str, $level = 0)\n    {\n        if ($level > $this->do_debug) {\n            return;\n        }\n        //Avoid clash with built-in function names\n        if (!in_array($this->Debugoutput, array('error_log', 'html', 'echo')) and is_callable($this->Debugoutput)) {\n            call_user_func($this->Debugoutput, $str, $level);\n            return;\n        }\n        switch ($this->Debugoutput) {\n            case 'error_log':\n                //Don't output, just log\n                error_log($str);\n                break;\n            case 'html':\n                //Cleans up output a bit for a better looking, HTML-safe output\n                echo htmlentities(\n                    preg_replace('/[\\r\\n]+/', '', $str),\n                    ENT_QUOTES,\n                    'UTF-8'\n                ) . \"<br>\\n\";\n                break;\n            case 'echo':\n            default:\n                //Normalize line breaks\n                $str = preg_replace('/(\\r\\n|\\r|\\n)/ms', \"\\n\", $str);\n                echo gmdate('Y-m-d H:i:s') . \"\\t\" . str_replace(\n                    \"\\n\",\n                    \"\\n                   \\t                  \",\n                    trim($str)\n                ) . \"\\n\";\n        }\n    }\n\n    /**\n     * Connect to an SMTP server.\n     * @param string $host SMTP server IP or host name\n     * @param integer $port The port number to connect to\n     * @param integer $timeout How long to wait for the connection to open\n     * @param array $options An array of options for stream_context_create()\n     * @access public\n     * @return boolean\n     */\n    public function connect($host, $port = null, $timeout = 30, $options = array())\n    {\n        static $streamok;\n        //This is enabled by default since 5.0.0 but some providers disable it\n        //Check this once and cache the result\n        if (is_null($streamok)) {\n            $streamok = function_exists('stream_socket_client');\n        }\n        // Clear errors to avoid confusion\n        $this->setError('');\n        // Make sure we are __not__ connected\n        if ($this->connected()) {\n            // Already connected, generate error\n            $this->setError('Already connected to a server');\n            return false;\n        }\n        if (empty($port)) {\n            $port = self::DEFAULT_SMTP_PORT;\n        }\n        // Connect to the SMTP server\n        $this->edebug(\n            \"Connection: opening to $host:$port, timeout=$timeout, options=\" .\n            var_export($options, true),\n            self::DEBUG_CONNECTION\n        );\n        $errno = 0;\n        $errstr = '';\n        if ($streamok) {\n            $socket_context = stream_context_create($options);\n            set_error_handler(array($this, 'errorHandler'));\n            $this->smtp_conn = stream_socket_client(\n                $host . \":\" . $port,\n                $errno,\n                $errstr,\n                $timeout,\n                STREAM_CLIENT_CONNECT,\n                $socket_context\n            );\n            restore_error_handler();\n        } else {\n            //Fall back to fsockopen which should work in more places, but is missing some features\n            $this->edebug(\n                \"Connection: stream_socket_client not available, falling back to fsockopen\",\n                self::DEBUG_CONNECTION\n            );\n            set_error_handler(array($this, 'errorHandler'));\n            $this->smtp_conn = fsockopen(\n                $host,\n                $port,\n                $errno,\n                $errstr,\n                $timeout\n            );\n            restore_error_handler();\n        }\n        // Verify we connected properly\n        if (!is_resource($this->smtp_conn)) {\n            $this->setError(\n                'Failed to connect to server',\n                $errno,\n                $errstr\n            );\n            $this->edebug(\n                'SMTP ERROR: ' . $this->error['error']\n                . \": $errstr ($errno)\",\n                self::DEBUG_CLIENT\n            );\n            return false;\n        }\n        $this->edebug('Connection: opened', self::DEBUG_CONNECTION);\n        // SMTP server can take longer to respond, give longer timeout for first read\n        // Windows does not have support for this timeout function\n        if (substr(PHP_OS, 0, 3) != 'WIN') {\n            $max = ini_get('max_execution_time');\n            // Don't bother if unlimited\n            if ($max != 0 && $timeout > $max) {\n                @set_time_limit($timeout);\n            }\n            stream_set_timeout($this->smtp_conn, $timeout, 0);\n        }\n        // Get any announcement\n        $announce = $this->get_lines();\n        $this->edebug('SERVER -> CLIENT: ' . $announce, self::DEBUG_SERVER);\n        return true;\n    }\n\n    /**\n     * Initiate a TLS (encrypted) session.\n     * @access public\n     * @return boolean\n     */\n    public function startTLS()\n    {\n        if (!$this->sendCommand('STARTTLS', 'STARTTLS', 220)) {\n            return false;\n        }\n\n        //Allow the best TLS version(s) we can\n        $crypto_method = STREAM_CRYPTO_METHOD_TLS_CLIENT;\n\n        //PHP 5.6.7 dropped inclusion of TLS 1.1 and 1.2 in STREAM_CRYPTO_METHOD_TLS_CLIENT\n        //so add them back in manually if we can\n        if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {\n            $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;\n            $crypto_method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;\n        }\n\n        // Begin encrypted connection\n        set_error_handler(array($this, 'errorHandler'));\n        $crypto_ok = stream_socket_enable_crypto(\n            $this->smtp_conn,\n            true,\n            $crypto_method\n        );\n        restore_error_handler();\n        return $crypto_ok;\n    }\n\n    /**\n     * Perform SMTP authentication.\n     * Must be run after hello().\n     * @see hello()\n     * @param string $username The user name\n     * @param string $password The password\n     * @param string $authtype The auth type (PLAIN, LOGIN, NTLM, CRAM-MD5, XOAUTH2)\n     * @param string $realm The auth realm for NTLM\n     * @param string $workstation The auth workstation for NTLM\n     * @param null|OAuth $OAuth An optional OAuth instance (@see PHPMailerOAuth)\n     * @return bool True if successfully authenticated.* @access public\n     */\n    public function authenticate(\n        $username,\n        $password,\n        $authtype = null,\n        $realm = '',\n        $workstation = '',\n        $OAuth = null\n    ) {\n        if (!$this->server_caps) {\n            $this->setError('Authentication is not allowed before HELO/EHLO');\n            return false;\n        }\n\n        if (array_key_exists('EHLO', $this->server_caps)) {\n            // SMTP extensions are available; try to find a proper authentication method\n            if (!array_key_exists('AUTH', $this->server_caps)) {\n                $this->setError('Authentication is not allowed at this stage');\n                // 'at this stage' means that auth may be allowed after the stage changes\n                // e.g. after STARTTLS\n                return false;\n            }\n\n            self::edebug('Auth method requested: ' . ($authtype ? $authtype : 'UNKNOWN'), self::DEBUG_LOWLEVEL);\n            self::edebug(\n                'Auth methods available on the server: ' . implode(',', $this->server_caps['AUTH']),\n                self::DEBUG_LOWLEVEL\n            );\n\n            if (empty($authtype)) {\n                foreach (array('CRAM-MD5', 'LOGIN', 'PLAIN', 'NTLM', 'XOAUTH2') as $method) {\n                    if (in_array($method, $this->server_caps['AUTH'])) {\n                        $authtype = $method;\n                        break;\n                    }\n                }\n                if (empty($authtype)) {\n                    $this->setError('No supported authentication methods found');\n                    return false;\n                }\n                self::edebug('Auth method selected: ' . $authtype, self::DEBUG_LOWLEVEL);\n            }\n\n            if (!in_array($authtype, $this->server_caps['AUTH'])) {\n                $this->setError(\"The requested authentication method \\\"$authtype\\\" is not supported by the server\");\n                return false;\n            }\n        } elseif (empty($authtype)) {\n            $authtype = 'LOGIN';\n        }\n        switch ($authtype) {\n            case 'PLAIN':\n                // Start authentication\n                if (!$this->sendCommand('AUTH', 'AUTH PLAIN', 334)) {\n                    return false;\n                }\n                // Send encoded username and password\n                if (!$this->sendCommand(\n                    'User & Password',\n                    base64_encode(\"\\0\" . $username . \"\\0\" . $password),\n                    235\n                )\n                ) {\n                    return false;\n                }\n                break;\n            case 'LOGIN':\n                // Start authentication\n                if (!$this->sendCommand('AUTH', 'AUTH LOGIN', 334)) {\n                    return false;\n                }\n                if (!$this->sendCommand(\"Username\", base64_encode($username), 334)) {\n                    return false;\n                }\n                if (!$this->sendCommand(\"Password\", base64_encode($password), 235)) {\n                    return false;\n                }\n                break;\n            case 'XOAUTH2':\n                //If the OAuth Instance is not set. Can be a case when PHPMailer is used\n                //instead of PHPMailerOAuth\n                if (is_null($OAuth)) {\n                    return false;\n                }\n                $oauth = $OAuth->getOauth64();\n\n                // Start authentication\n                if (!$this->sendCommand('AUTH', 'AUTH XOAUTH2 ' . $oauth, 235)) {\n                    return false;\n                }\n                break;\n            case 'NTLM':\n                /*\n                 * ntlm_sasl_client.php\n                 * Bundled with Permission\n                 *\n                 * How to telnet in windows:\n                 * http://technet.microsoft.com/en-us/library/aa995718%28EXCHG.65%29.aspx\n                 * PROTOCOL Docs http://curl.haxx.se/rfc/ntlm.html#ntlmSmtpAuthentication\n                 */\n                require_once 'extras/ntlm_sasl_client.php';\n                $temp = new stdClass;\n                $ntlm_client = new ntlm_sasl_client_class;\n                //Check that functions are available\n                if (!$ntlm_client->initialize($temp)) {\n                    $this->setError($temp->error);\n                    $this->edebug(\n                        'You need to enable some modules in your php.ini file: '\n                        . $this->error['error'],\n                        self::DEBUG_CLIENT\n                    );\n                    return false;\n                }\n                //msg1\n                $msg1 = $ntlm_client->typeMsg1($realm, $workstation); //msg1\n\n                if (!$this->sendCommand(\n                    'AUTH NTLM',\n                    'AUTH NTLM ' . base64_encode($msg1),\n                    334\n                )\n                ) {\n                    return false;\n                }\n                //Though 0 based, there is a white space after the 3 digit number\n                //msg2\n                $challenge = substr($this->last_reply, 3);\n                $challenge = base64_decode($challenge);\n                $ntlm_res = $ntlm_client->NTLMResponse(\n                    substr($challenge, 24, 8),\n                    $password\n                );\n                //msg3\n                $msg3 = $ntlm_client->typeMsg3(\n                    $ntlm_res,\n                    $username,\n                    $realm,\n                    $workstation\n                );\n                // send encoded username\n                return $this->sendCommand('Username', base64_encode($msg3), 235);\n            case 'CRAM-MD5':\n                // Start authentication\n                if (!$this->sendCommand('AUTH CRAM-MD5', 'AUTH CRAM-MD5', 334)) {\n                    return false;\n                }\n                // Get the challenge\n                $challenge = base64_decode(substr($this->last_reply, 4));\n\n                // Build the response\n                $response = $username . ' ' . $this->hmac($challenge, $password);\n\n                // send encoded credentials\n                return $this->sendCommand('Username', base64_encode($response), 235);\n            default:\n                $this->setError(\"Authentication method \\\"$authtype\\\" is not supported\");\n                return false;\n        }\n        return true;\n    }\n\n    /**\n     * Calculate an MD5 HMAC hash.\n     * Works like hash_hmac('md5', $data, $key)\n     * in case that function is not available\n     * @param string $data The data to hash\n     * @param string $key The key to hash with\n     * @access protected\n     * @return string\n     */\n    protected function hmac($data, $key)\n    {\n        if (function_exists('hash_hmac')) {\n            return hash_hmac('md5', $data, $key);\n        }\n\n        // The following borrowed from\n        // http://php.net/manual/en/function.mhash.php#27225\n\n        // RFC 2104 HMAC implementation for php.\n        // Creates an md5 HMAC.\n        // Eliminates the need to install mhash to compute a HMAC\n        // by Lance Rushing\n\n        $bytelen = 64; // byte length for md5\n        if (strlen($key) > $bytelen) {\n            $key = pack('H*', md5($key));\n        }\n        $key = str_pad($key, $bytelen, chr(0x00));\n        $ipad = str_pad('', $bytelen, chr(0x36));\n        $opad = str_pad('', $bytelen, chr(0x5c));\n        $k_ipad = $key ^ $ipad;\n        $k_opad = $key ^ $opad;\n\n        return md5($k_opad . pack('H*', md5($k_ipad . $data)));\n    }\n\n    /**\n     * Check connection state.\n     * @access public\n     * @return boolean True if connected.\n     */\n    public function connected()\n    {\n        if (is_resource($this->smtp_conn)) {\n            $sock_status = stream_get_meta_data($this->smtp_conn);\n            if ($sock_status['eof']) {\n                // The socket is valid but we are not connected\n                $this->edebug(\n                    'SMTP NOTICE: EOF caught while checking if connected',\n                    self::DEBUG_CLIENT\n                );\n                $this->close();\n                return false;\n            }\n            return true; // everything looks good\n        }\n        return false;\n    }\n\n    /**\n     * Close the socket and clean up the state of the class.\n     * Don't use this function without first trying to use QUIT.\n     * @see quit()\n     * @access public\n     * @return void\n     */\n    public function close()\n    {\n        $this->setError('');\n        $this->server_caps = null;\n        $this->helo_rply = null;\n        if (is_resource($this->smtp_conn)) {\n            // close the connection and cleanup\n            fclose($this->smtp_conn);\n            $this->smtp_conn = null; //Makes for cleaner serialization\n            $this->edebug('Connection: closed', self::DEBUG_CONNECTION);\n        }\n    }\n\n    /**\n     * Send an SMTP DATA command.\n     * Issues a data command and sends the msg_data to the server,\n     * finializing the mail transaction. $msg_data is the message\n     * that is to be send with the headers. Each header needs to be\n     * on a single line followed by a <CRLF> with the message headers\n     * and the message body being separated by and additional <CRLF>.\n     * Implements rfc 821: DATA <CRLF>\n     * @param string $msg_data Message data to send\n     * @access public\n     * @return boolean\n     */\n    public function data($msg_data)\n    {\n        //This will use the standard timelimit\n        if (!$this->sendCommand('DATA', 'DATA', 354)) {\n            return false;\n        }\n\n        /* The server is ready to accept data!\n         * According to rfc821 we should not send more than 1000 characters on a single line (including the CRLF)\n         * so we will break the data up into lines by \\r and/or \\n then if needed we will break each of those into\n         * smaller lines to fit within the limit.\n         * We will also look for lines that start with a '.' and prepend an additional '.'.\n         * NOTE: this does not count towards line-length limit.\n         */\n\n        // Normalize line breaks before exploding\n        $lines = explode(\"\\n\", str_replace(array(\"\\r\\n\", \"\\r\"), \"\\n\", $msg_data));\n\n        /* To distinguish between a complete RFC822 message and a plain message body, we check if the first field\n         * of the first line (':' separated) does not contain a space then it _should_ be a header and we will\n         * process all lines before a blank line as headers.\n         */\n\n        $field = substr($lines[0], 0, strpos($lines[0], ':'));\n        $in_headers = false;\n        if (!empty($field) && strpos($field, ' ') === false) {\n            $in_headers = true;\n        }\n\n        foreach ($lines as $line) {\n            $lines_out = array();\n            if ($in_headers and $line == '') {\n                $in_headers = false;\n            }\n            //Break this line up into several smaller lines if it's too long\n            //Micro-optimisation: isset($str[$len]) is faster than (strlen($str) > $len),\n            while (isset($line[self::MAX_LINE_LENGTH])) {\n                //Working backwards, try to find a space within the last MAX_LINE_LENGTH chars of the line to break on\n                //so as to avoid breaking in the middle of a word\n                $pos = strrpos(substr($line, 0, self::MAX_LINE_LENGTH), ' ');\n                //Deliberately matches both false and 0\n                if (!$pos) {\n                    //No nice break found, add a hard break\n                    $pos = self::MAX_LINE_LENGTH - 1;\n                    $lines_out[] = substr($line, 0, $pos);\n                    $line = substr($line, $pos);\n                } else {\n                    //Break at the found point\n                    $lines_out[] = substr($line, 0, $pos);\n                    //Move along by the amount we dealt with\n                    $line = substr($line, $pos + 1);\n                }\n                //If processing headers add a LWSP-char to the front of new line RFC822 section 3.1.1\n                if ($in_headers) {\n                    $line = \"\\t\" . $line;\n                }\n            }\n            $lines_out[] = $line;\n\n            //Send the lines to the server\n            foreach ($lines_out as $line_out) {\n                //RFC2821 section 4.5.2\n                if (!empty($line_out) and $line_out[0] == '.') {\n                    $line_out = '.' . $line_out;\n                }\n                $this->client_send($line_out . self::CRLF);\n            }\n        }\n\n        //Message data has been sent, complete the command\n        //Increase timelimit for end of DATA command\n        $savetimelimit = $this->Timelimit;\n        $this->Timelimit = $this->Timelimit * 2;\n        $result = $this->sendCommand('DATA END', '.', 250);\n        //Restore timelimit\n        $this->Timelimit = $savetimelimit;\n        return $result;\n    }\n\n    /**\n     * Send an SMTP HELO or EHLO command.\n     * Used to identify the sending server to the receiving server.\n     * This makes sure that client and server are in a known state.\n     * Implements RFC 821: HELO <SP> <domain> <CRLF>\n     * and RFC 2821 EHLO.\n     * @param string $host The host name or IP to connect to\n     * @access public\n     * @return boolean\n     */\n    public function hello($host = '')\n    {\n        //Try extended hello first (RFC 2821)\n        return (boolean)($this->sendHello('EHLO', $host) or $this->sendHello('HELO', $host));\n    }\n\n    /**\n     * Send an SMTP HELO or EHLO command.\n     * Low-level implementation used by hello()\n     * @see hello()\n     * @param string $hello The HELO string\n     * @param string $host The hostname to say we are\n     * @access protected\n     * @return boolean\n     */\n    protected function sendHello($hello, $host)\n    {\n        $noerror = $this->sendCommand($hello, $hello . ' ' . $host, 250);\n        $this->helo_rply = $this->last_reply;\n        if ($noerror) {\n            $this->parseHelloFields($hello);\n        } else {\n            $this->server_caps = null;\n        }\n        return $noerror;\n    }\n\n    /**\n     * Parse a reply to HELO/EHLO command to discover server extensions.\n     * In case of HELO, the only parameter that can be discovered is a server name.\n     * @access protected\n     * @param string $type - 'HELO' or 'EHLO'\n     */\n    protected function parseHelloFields($type)\n    {\n        $this->server_caps = array();\n        $lines = explode(\"\\n\", $this->helo_rply);\n\n        foreach ($lines as $n => $s) {\n            //First 4 chars contain response code followed by - or space\n            $s = trim(substr($s, 4));\n            if (empty($s)) {\n                continue;\n            }\n            $fields = explode(' ', $s);\n            if (!empty($fields)) {\n                if (!$n) {\n                    $name = $type;\n                    $fields = $fields[0];\n                } else {\n                    $name = array_shift($fields);\n                    switch ($name) {\n                        case 'SIZE':\n                            $fields = ($fields ? $fields[0] : 0);\n                            break;\n                        case 'AUTH':\n                            if (!is_array($fields)) {\n                                $fields = array();\n                            }\n                            break;\n                        default:\n                            $fields = true;\n                    }\n                }\n                $this->server_caps[$name] = $fields;\n            }\n        }\n    }\n\n    /**\n     * Send an SMTP MAIL command.\n     * Starts a mail transaction from the email address specified in\n     * $from. Returns true if successful or false otherwise. If True\n     * the mail transaction is started and then one or more recipient\n     * commands may be called followed by a data command.\n     * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>\n     * @param string $from Source address of this message\n     * @access public\n     * @return boolean\n     */\n    public function mail($from)\n    {\n        $useVerp = ($this->do_verp ? ' XVERP' : '');\n        return $this->sendCommand(\n            'MAIL FROM',\n            'MAIL FROM:<' . $from . '>' . $useVerp,\n            250\n        );\n    }\n\n    /**\n     * Send an SMTP QUIT command.\n     * Closes the socket if there is no error or the $close_on_error argument is true.\n     * Implements from rfc 821: QUIT <CRLF>\n     * @param boolean $close_on_error Should the connection close if an error occurs?\n     * @access public\n     * @return boolean\n     */\n    public function quit($close_on_error = true)\n    {\n        $noerror = $this->sendCommand('QUIT', 'QUIT', 221);\n        $err = $this->error; //Save any error\n        if ($noerror or $close_on_error) {\n            $this->close();\n            $this->error = $err; //Restore any error from the quit command\n        }\n        return $noerror;\n    }\n\n    /**\n     * Send an SMTP RCPT command.\n     * Sets the TO argument to $toaddr.\n     * Returns true if the recipient was accepted false if it was rejected.\n     * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>\n     * @param string $address The address the message is being sent to\n     * @access public\n     * @return boolean\n     */\n    public function recipient($address)\n    {\n        return $this->sendCommand(\n            'RCPT TO',\n            'RCPT TO:<' . $address . '>',\n            array(250, 251)\n        );\n    }\n\n    /**\n     * Send an SMTP RSET command.\n     * Abort any transaction that is currently in progress.\n     * Implements rfc 821: RSET <CRLF>\n     * @access public\n     * @return boolean True on success.\n     */\n    public function reset()\n    {\n        return $this->sendCommand('RSET', 'RSET', 250);\n    }\n\n    /**\n     * Send a command to an SMTP server and check its return code.\n     * @param string $command The command name - not sent to the server\n     * @param string $commandstring The actual command to send\n     * @param integer|array $expect One or more expected integer success codes\n     * @access protected\n     * @return boolean True on success.\n     */\n    protected function sendCommand($command, $commandstring, $expect)\n    {\n        if (!$this->connected()) {\n            $this->setError(\"Called $command without being connected\");\n            return false;\n        }\n        //Reject line breaks in all commands\n        if (strpos($commandstring, \"\\n\") !== false or strpos($commandstring, \"\\r\") !== false) {\n            $this->setError(\"Command '$command' contained line breaks\");\n            return false;\n        }\n        $this->client_send($commandstring . self::CRLF);\n\n        $this->last_reply = $this->get_lines();\n        // Fetch SMTP code and possible error code explanation\n        $matches = array();\n        if (preg_match(\"/^([0-9]{3})[ -](?:([0-9]\\\\.[0-9]\\\\.[0-9]) )?/\", $this->last_reply, $matches)) {\n            $code = $matches[1];\n            $code_ex = (count($matches) > 2 ? $matches[2] : null);\n            // Cut off error code from each response line\n            $detail = preg_replace(\n                \"/{$code}[ -]\" .\n                ($code_ex ? str_replace('.', '\\\\.', $code_ex) . ' ' : '') . \"/m\",\n                '',\n                $this->last_reply\n            );\n        } else {\n            // Fall back to simple parsing if regex fails\n            $code = substr($this->last_reply, 0, 3);\n            $code_ex = null;\n            $detail = substr($this->last_reply, 4);\n        }\n\n        $this->edebug('SERVER -> CLIENT: ' . $this->last_reply, self::DEBUG_SERVER);\n\n        if (!in_array($code, (array)$expect)) {\n            $this->setError(\n                \"$command command failed\",\n                $detail,\n                $code,\n                $code_ex\n            );\n            $this->edebug(\n                'SMTP ERROR: ' . $this->error['error'] . ': ' . $this->last_reply,\n                self::DEBUG_CLIENT\n            );\n            return false;\n        }\n\n        $this->setError('');\n        return true;\n    }\n\n    /**\n     * Send an SMTP SAML command.\n     * Starts a mail transaction from the email address specified in $from.\n     * Returns true if successful or false otherwise. If True\n     * the mail transaction is started and then one or more recipient\n     * commands may be called followed by a data command. This command\n     * will send the message to the users terminal if they are logged\n     * in and send them an email.\n     * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>\n     * @param string $from The address the message is from\n     * @access public\n     * @return boolean\n     */\n    public function sendAndMail($from)\n    {\n        return $this->sendCommand('SAML', \"SAML FROM:$from\", 250);\n    }\n\n    /**\n     * Send an SMTP VRFY command.\n     * @param string $name The name to verify\n     * @access public\n     * @return boolean\n     */\n    public function verify($name)\n    {\n        return $this->sendCommand('VRFY', \"VRFY $name\", array(250, 251));\n    }\n\n    /**\n     * Send an SMTP NOOP command.\n     * Used to keep keep-alives alive, doesn't actually do anything\n     * @access public\n     * @return boolean\n     */\n    public function noop()\n    {\n        return $this->sendCommand('NOOP', 'NOOP', 250);\n    }\n\n    /**\n     * Send an SMTP TURN command.\n     * This is an optional command for SMTP that this class does not support.\n     * This method is here to make the RFC821 Definition complete for this class\n     * and _may_ be implemented in future\n     * Implements from rfc 821: TURN <CRLF>\n     * @access public\n     * @return boolean\n     */\n    public function turn()\n    {\n        $this->setError('The SMTP TURN command is not implemented');\n        $this->edebug('SMTP NOTICE: ' . $this->error['error'], self::DEBUG_CLIENT);\n        return false;\n    }\n\n    /**\n     * Send raw data to the server.\n     * @param string $data The data to send\n     * @access public\n     * @return integer|boolean The number of bytes sent to the server or false on error\n     */\n    public function client_send($data)\n    {\n        $this->edebug(\"CLIENT -> SERVER: $data\", self::DEBUG_CLIENT);\n        return fwrite($this->smtp_conn, $data);\n    }\n\n    /**\n     * Get the latest error.\n     * @access public\n     * @return array\n     */\n    public function getError()\n    {\n        return $this->error;\n    }\n\n    /**\n     * Get SMTP extensions available on the server\n     * @access public\n     * @return array|null\n     */\n    public function getServerExtList()\n    {\n        return $this->server_caps;\n    }\n\n    /**\n     * A multipurpose method\n     * The method works in three ways, dependent on argument value and current state\n     *   1. HELO/EHLO was not sent - returns null and set up $this->error\n     *   2. HELO was sent\n     *     $name = 'HELO': returns server name\n     *     $name = 'EHLO': returns boolean false\n     *     $name = any string: returns null and set up $this->error\n     *   3. EHLO was sent\n     *     $name = 'HELO'|'EHLO': returns server name\n     *     $name = any string: if extension $name exists, returns boolean True\n     *       or its options. Otherwise returns boolean False\n     * In other words, one can use this method to detect 3 conditions:\n     *  - null returned: handshake was not or we don't know about ext (refer to $this->error)\n     *  - false returned: the requested feature exactly not exists\n     *  - positive value returned: the requested feature exists\n     * @param string $name Name of SMTP extension or 'HELO'|'EHLO'\n     * @return mixed\n     */\n    public function getServerExt($name)\n    {\n        if (!$this->server_caps) {\n            $this->setError('No HELO/EHLO was sent');\n            return null;\n        }\n\n        // the tight logic knot ;)\n        if (!array_key_exists($name, $this->server_caps)) {\n            if ($name == 'HELO') {\n                return $this->server_caps['EHLO'];\n            }\n            if ($name == 'EHLO' || array_key_exists('EHLO', $this->server_caps)) {\n                return false;\n            }\n            $this->setError('HELO handshake was used. Client knows nothing about server extensions');\n            return null;\n        }\n\n        return $this->server_caps[$name];\n    }\n\n    /**\n     * Get the last reply from the server.\n     * @access public\n     * @return string\n     */\n    public function getLastReply()\n    {\n        return $this->last_reply;\n    }\n\n    /**\n     * Read the SMTP server's response.\n     * Either before eof or socket timeout occurs on the operation.\n     * With SMTP we can tell if we have more lines to read if the\n     * 4th character is '-' symbol. If it is a space then we don't\n     * need to read anything else.\n     * @access protected\n     * @return string\n     */\n    protected function get_lines()\n    {\n        // If the connection is bad, give up straight away\n        if (!is_resource($this->smtp_conn)) {\n            return '';\n        }\n        $data = '';\n        $endtime = 0;\n        stream_set_timeout($this->smtp_conn, $this->Timeout);\n        if ($this->Timelimit > 0) {\n            $endtime = time() + $this->Timelimit;\n        }\n        while (is_resource($this->smtp_conn) && !feof($this->smtp_conn)) {\n            $str = @fgets($this->smtp_conn, 515);\n            $this->edebug(\"SMTP -> get_lines(): \\$data is \\\"$data\\\"\", self::DEBUG_LOWLEVEL);\n            $this->edebug(\"SMTP -> get_lines(): \\$str is  \\\"$str\\\"\", self::DEBUG_LOWLEVEL);\n            $data .= $str;\n            // If 4th character is a space, we are done reading, break the loop, micro-optimisation over strlen\n            if ((isset($str[3]) and $str[3] == ' ')) {\n                break;\n            }\n            // Timed-out? Log and break\n            $info = stream_get_meta_data($this->smtp_conn);\n            if ($info['timed_out']) {\n                $this->edebug(\n                    'SMTP -> get_lines(): timed-out (' . $this->Timeout . ' sec)',\n                    self::DEBUG_LOWLEVEL\n                );\n                break;\n            }\n            // Now check if reads took too long\n            if ($endtime and time() > $endtime) {\n                $this->edebug(\n                    'SMTP -> get_lines(): timelimit reached (' .\n                    $this->Timelimit . ' sec)',\n                    self::DEBUG_LOWLEVEL\n                );\n                break;\n            }\n        }\n        return $data;\n    }\n\n    /**\n     * Enable or disable VERP address generation.\n     * @param boolean $enabled\n     */\n    public function setVerp($enabled = false)\n    {\n        $this->do_verp = $enabled;\n    }\n\n    /**\n     * Get VERP address generation mode.\n     * @return boolean\n     */\n    public function getVerp()\n    {\n        return $this->do_verp;\n    }\n\n    /**\n     * Set error messages and codes.\n     * @param string $message The error message\n     * @param string $detail Further detail on the error\n     * @param string $smtp_code An associated SMTP error code\n     * @param string $smtp_code_ex Extended SMTP code\n     */\n    protected function setError($message, $detail = '', $smtp_code = '', $smtp_code_ex = '')\n    {\n        $this->error = array(\n            'error' => $message,\n            'detail' => $detail,\n            'smtp_code' => $smtp_code,\n            'smtp_code_ex' => $smtp_code_ex\n        );\n    }\n\n    /**\n     * Set debug output method.\n     * @param string|callable $method The name of the mechanism to use for debugging output, or a callable to handle it.\n     */\n    public function setDebugOutput($method = 'echo')\n    {\n        $this->Debugoutput = $method;\n    }\n\n    /**\n     * Get debug output method.\n     * @return string\n     */\n    public function getDebugOutput()\n    {\n        return $this->Debugoutput;\n    }\n\n    /**\n     * Set debug output level.\n     * @param integer $level\n     */\n    public function setDebugLevel($level = 0)\n    {\n        $this->do_debug = $level;\n    }\n\n    /**\n     * Get debug output level.\n     * @return integer\n     */\n    public function getDebugLevel()\n    {\n        return $this->do_debug;\n    }\n\n    /**\n     * Set SMTP timeout.\n     * @param integer $timeout\n     */\n    public function setTimeout($timeout = 0)\n    {\n        $this->Timeout = $timeout;\n    }\n\n    /**\n     * Get SMTP timeout.\n     * @return integer\n     */\n    public function getTimeout()\n    {\n        return $this->Timeout;\n    }\n\n    /**\n     * Reports an error number and string.\n     * @param integer $errno The error number returned by PHP.\n     * @param string $errmsg The error message returned by PHP.\n     * @param string $errfile The file the error occurred in\n     * @param integer $errline The line number the error occurred on\n     */\n    protected function errorHandler($errno, $errmsg, $errfile = '', $errline = 0)\n    {\n        $notice = 'Connection failed.';\n        $this->setError(\n            $notice,\n            $errno,\n            $errmsg\n        );\n        $this->edebug(\n            $notice . ' Error #' . $errno . ': ' . $errmsg . \" [$errfile line $errline]\",\n            self::DEBUG_CONNECTION\n        );\n    }\n\n    /**\n     * Will return the ID of the last smtp transaction based on a list of patterns provided\n     * in SMTP::$smtp_transaction_id_patterns.\n     * If no reply has been received yet, it will return null.\n     * If no pattern has been matched, it will return false.\n     * @return bool|null|string\n     */\n    public function getLastTransactionID()\n    {\n        $reply = $this->getLastReply();\n\n        if (empty($reply)) {\n            return null;\n        }\n\n        foreach ($this->smtp_transaction_id_patterns as $smtp_transaction_id_pattern) {\n            if (preg_match($smtp_transaction_id_pattern, $reply, $matches)) {\n                return $matches[1];\n            }\n        }\n\n        return false;\n    }\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/composer.json",
    "content": "{\n    \"name\": \"phpmailer/phpmailer\",\n    \"type\": \"library\",\n    \"description\": \"PHPMailer is a full-featured email creation and transfer class for PHP\",\n    \"authors\": [\n        {\n            \"name\": \"Marcus Bointon\",\n            \"email\": \"phpmailer@synchromedia.co.uk\"\n        },\n        {\n            \"name\": \"Jim Jagielski\",\n            \"email\": \"jimjag@gmail.com\"\n        },\n        {\n            \"name\": \"Andy Prevost\",\n            \"email\": \"codeworxtech@users.sourceforge.net\"\n        },\n        {\n            \"name\": \"Brent R. Matzelle\"\n        }\n    ],\n    \"require\": {\n        \"php\": \">=5.0.0\"\n    },\n    \"require-dev\": {\n        \"doctrine/annotations\": \"1.2.*\",\n        \"jms/serializer\": \"0.16.*\",\n        \"phpdocumentor/phpdocumentor\": \"2.*\",\n        \"phpunit/phpunit\": \"4.8.*\",\n        \"symfony/debug\": \"2.8.*\",\n        \"symfony/filesystem\": \"2.8.*\",\n        \"symfony/translation\": \"2.8.*\",\n        \"symfony/yaml\": \"2.8.*\",\n        \"zendframework/zend-cache\": \"2.5.1\",\n        \"zendframework/zend-config\": \"2.5.1\",\n        \"zendframework/zend-eventmanager\": \"2.5.1\",\n        \"zendframework/zend-filter\": \"2.5.1\",\n        \"zendframework/zend-i18n\": \"2.5.1\",\n        \"zendframework/zend-json\": \"2.5.1\",\n        \"zendframework/zend-math\": \"2.5.1\",\n        \"zendframework/zend-serializer\": \"2.5.*\",\n        \"zendframework/zend-servicemanager\": \"2.5.*\",\n        \"zendframework/zend-stdlib\": \"2.5.1\"\n    },\n    \"suggest\": {\n        \"league/oauth2-google\": \"Needed for Google XOAUTH2 authentication\"\n    },\n    \"autoload\": {\n        \"classmap\": [\n            \"class.phpmailer.php\",\n            \"class.phpmaileroauth.php\",\n            \"class.phpmaileroauthgoogle.php\",\n            \"class.smtp.php\",\n            \"class.pop3.php\",\n            \"extras/EasyPeasyICS.php\",\n            \"extras/ntlm_sasl_client.php\"\n        ]\n    },\n    \"license\": \"LGPL-2.1\"\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/DKIM.phps",
    "content": "<?php\n/**\n * This example shows how to use DKIM message authentication with PHPMailer.\n * There's more to using DKIM than just this code - check out this article:\n * @link https://yomotherboard.com/how-to-setup-email-server-dkim-keys/\n * See also the DKIM code in the PHPMailer unit tests,\n * which shows how to make a key pair from PHP.\n */\n\nrequire '../PHPMailerAutoload.php';\n\n//Create a new PHPMailer instance\n$mail = new PHPMailer;\n//Set who the message is to be sent from\n$mail->setFrom('from@example.com', 'First Last');\n//Set an alternative reply-to address\n$mail->addReplyTo('replyto@example.com', 'First Last');\n//Set who the message is to be sent to\n$mail->addAddress('whoto@example.com', 'John Doe');\n//Set the subject line\n$mail->Subject = 'PHPMailer DKIM test';\n//This should be the same as the domain of your From address\n$mail->DKIM_domain = 'example.com';\n//Path to your private key file\n$mail->DKIM_private = 'dkim_private.pem';\n//Set this to your own selector\n$mail->DKIM_selector = 'phpmailer';\n//If your private key has a passphrase, set it here\n$mail->DKIM_passphrase = '';\n//The identity you're signing as - usually your From address\n$mail->DKIM_identity = $mail->From;\n\n//send the message, check for errors\nif (!$mail->send()) {\n    echo \"Mailer Error: \" . $mail->ErrorInfo;\n} else {\n    echo \"Message sent!\";\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/code_generator.phps",
    "content": "<?php\n/*\n * A web form that both generates and uses PHPMailer code.\n * revised, updated and corrected 27/02/2013\n * by matt.sturdy@gmail.com\n */\nrequire '../PHPMailerAutoload.php';\n\n$CFG['smtp_debug'] = 2; //0 == off, 1 for client output, 2 for client and server\n$CFG['smtp_debugoutput'] = 'html';\n$CFG['smtp_server'] = 'localhost';\n$CFG['smtp_port'] = '25';\n$CFG['smtp_authenticate'] = false;\n$CFG['smtp_username'] = 'name@example.com';\n$CFG['smtp_password'] = 'yourpassword';\n$CFG['smtp_secure'] = 'None';\n\n$from_name = (isset($_POST['From_Name'])) ? $_POST['From_Name'] : '';\n$from_email = (isset($_POST['From_Email'])) ? $_POST['From_Email'] : '';\n$to_name = (isset($_POST['To_Name'])) ? $_POST['To_Name'] : '';\n$to_email = (isset($_POST['To_Email'])) ? $_POST['To_Email'] : '';\n$cc_email = (isset($_POST['cc_Email'])) ? $_POST['cc_Email'] : '';\n$bcc_email = (isset($_POST['bcc_Email'])) ? $_POST['bcc_Email'] : '';\n$subject = (isset($_POST['Subject'])) ? $_POST['Subject'] : '';\n$message = (isset($_POST['Message'])) ? $_POST['Message'] : '';\n$test_type = (isset($_POST['test_type'])) ? $_POST['test_type'] : 'smtp';\n$smtp_debug = (isset($_POST['smtp_debug'])) ? $_POST['smtp_debug'] : $CFG['smtp_debug'];\n$smtp_server = (isset($_POST['smtp_server'])) ? $_POST['smtp_server'] : $CFG['smtp_server'];\n$smtp_port = (isset($_POST['smtp_port'])) ? $_POST['smtp_port'] : $CFG['smtp_port'];\n$smtp_secure = strtolower((isset($_POST['smtp_secure'])) ? $_POST['smtp_secure'] : $CFG['smtp_secure']);\n$smtp_authenticate = (isset($_POST['smtp_authenticate'])) ?\n    $_POST['smtp_authenticate'] : $CFG['smtp_authenticate'];\n$authenticate_password = (isset($_POST['authenticate_password'])) ?\n    $_POST['authenticate_password'] : $CFG['smtp_password'];\n$authenticate_username = (isset($_POST['authenticate_username'])) ?\n    $_POST['authenticate_username'] : $CFG['smtp_username'];\n\n// storing all status output from the script to be shown to the user later\n$results_messages = array();\n\n// $example_code represents the \"final code\" that we're using, and will\n// be shown to the user at the end.\n$example_code = \"\\nrequire_once '../PHPMailerAutoload.php';\";\n$example_code .= \"\\n\\n\\$results_messages = array();\";\n\n$mail = new PHPMailer(true);  //PHPMailer instance with exceptions enabled\n$mail->CharSet = 'utf-8';\nini_set('default_charset', 'UTF-8');\n$mail->Debugoutput = $CFG['smtp_debugoutput'];\n$example_code .= \"\\n\\n\\$mail = new PHPMailer(true);\";\n$example_code .= \"\\n\\$mail->CharSet = 'utf-8';\";\n$example_code .= \"\\nini_set('default_charset', 'UTF-8');\";\n\nclass phpmailerAppException extends phpmailerException\n{\n}\n\n$example_code .= \"\\n\\nclass phpmailerAppException extends phpmailerException {}\";\n$example_code .= \"\\n\\ntry {\";\n\ntry {\n    if (isset($_POST[\"submit\"]) && $_POST['submit'] == \"Submit\") {\n        $to = $_POST['To_Email'];\n        if (!PHPMailer::validateAddress($to)) {\n            throw new phpmailerAppException(\"Email address \" . $to . \" is invalid -- aborting!\");\n        }\n\n        $example_code .= \"\\n\\$to = '{$_POST['To_Email']}';\";\n        $example_code .= \"\\nif(!PHPMailer::validateAddress(\\$to)) {\";\n        $example_code .= \"\\n  throw new phpmailerAppException(\\\"Email address \\\" . \" .\n            \"\\$to . \\\" is invalid -- aborting!\\\");\";\n        $example_code .= \"\\n}\";\n\n        switch ($_POST['test_type']) {\n            case 'smtp':\n                $mail->isSMTP(); // telling the class to use SMTP\n                $mail->SMTPDebug = (integer)$_POST['smtp_debug'];\n                $mail->Host = $_POST['smtp_server']; // SMTP server\n                $mail->Port = (integer)$_POST['smtp_port']; // set the SMTP port\n                if ($_POST['smtp_secure']) {\n                    $mail->SMTPSecure = strtolower($_POST['smtp_secure']);\n                }\n                $mail->SMTPAuth = array_key_exists('smtp_authenticate', $_POST); // enable SMTP authentication?\n                if (array_key_exists('smtp_authenticate', $_POST)) {\n                    $mail->Username = $_POST['authenticate_username']; // SMTP account username\n                    $mail->Password = $_POST['authenticate_password']; // SMTP account password\n                }\n\n                $example_code .= \"\\n\\$mail->isSMTP();\";\n                $example_code .= \"\\n\\$mail->SMTPDebug  = \" . $_POST['smtp_debug'] . \";\";\n                $example_code .= \"\\n\\$mail->Host       = \\\"\" . $_POST['smtp_server'] . \"\\\";\";\n                $example_code .= \"\\n\\$mail->Port       = \\\"\" . $_POST['smtp_port'] . \"\\\";\";\n                $example_code .= \"\\n\\$mail->SMTPSecure = \\\"\" . strtolower($_POST['smtp_secure']) . \"\\\";\";\n                $example_code .= \"\\n\\$mail->SMTPAuth   = \" . (array_key_exists(\n                    'smtp_authenticate',\n                    $_POST\n                ) ? 'true' : 'false') . \";\";\n                if (array_key_exists('smtp_authenticate', $_POST)) {\n                    $example_code .= \"\\n\\$mail->Username   = \\\"\" . $_POST['authenticate_username'] . \"\\\";\";\n                    $example_code .= \"\\n\\$mail->Password   = \\\"\" . $_POST['authenticate_password'] . \"\\\";\";\n                }\n                break;\n            case 'mail':\n                $mail->isMail(); // telling the class to use PHP's mail()\n                $example_code .= \"\\n\\$mail->isMail();\";\n                break;\n            case 'sendmail':\n                $mail->isSendmail(); // telling the class to use Sendmail\n                $example_code .= \"\\n\\$mail->isSendmail();\";\n                break;\n            case 'qmail':\n                $mail->isQmail(); // telling the class to use Qmail\n                $example_code .= \"\\n\\$mail->isQmail();\";\n                break;\n            default:\n                throw new phpmailerAppException('Invalid test_type provided');\n        }\n\n        try {\n            if ($_POST['From_Name'] != '') {\n                $mail->addReplyTo($_POST['From_Email'], $_POST['From_Name']);\n                $mail->setFrom($_POST['From_Email'], $_POST['From_Name']);\n\n                $example_code .= \"\\n\\$mail->addReplyTo(\\\"\" .\n                    $_POST['From_Email'] . \"\\\", \\\"\" . $_POST['From_Name'] . \"\\\");\";\n                $example_code .= \"\\n\\$mail->setFrom(\\\"\" .\n                    $_POST['From_Email'] . \"\\\", \\\"\" . $_POST['From_Name'] . \"\\\");\";\n            } else {\n                $mail->addReplyTo($_POST['From_Email']);\n                $mail->setFrom($_POST['From_Email'], $_POST['From_Email']);\n\n                $example_code .= \"\\n\\$mail->addReplyTo(\\\"\" . $_POST['From_Email'] . \"\\\");\";\n                $example_code .= \"\\n\\$mail->setFrom(\\\"\" .\n                    $_POST['From_Email'] . \"\\\", \\\"\" . $_POST['From_Email'] . \"\\\");\";\n            }\n\n            if ($_POST['To_Name'] != '') {\n                $mail->addAddress($to, $_POST['To_Name']);\n                $example_code .= \"\\n\\$mail->addAddress(\\\"$to\\\", \\\"\" . $_POST['To_Name'] . \"\\\");\";\n            } else {\n                $mail->addAddress($to);\n                $example_code .= \"\\n\\$mail->addAddress(\\\"$to\\\");\";\n            }\n\n            if ($_POST['bcc_Email'] != '') {\n                $indiBCC = explode(\" \", $_POST['bcc_Email']);\n                foreach ($indiBCC as $key => $value) {\n                    $mail->addBCC($value);\n                    $example_code .= \"\\n\\$mail->addBCC(\\\"$value\\\");\";\n                }\n            }\n\n            if ($_POST['cc_Email'] != '') {\n                $indiCC = explode(\" \", $_POST['cc_Email']);\n                foreach ($indiCC as $key => $value) {\n                    $mail->addCC($value);\n                    $example_code .= \"\\n\\$mail->addCC(\\\"$value\\\");\";\n                }\n            }\n        } catch (phpmailerException $e) { //Catch all kinds of bad addressing\n            throw new phpmailerAppException($e->getMessage());\n        }\n        $mail->Subject = $_POST['Subject'] . ' (PHPMailer test using ' . strtoupper($_POST['test_type']) . ')';\n        $example_code .= \"\\n\\$mail->Subject  = \\\"\" . $_POST['Subject'] .\n            ' (PHPMailer test using ' . strtoupper($_POST['test_type']) . ')\";';\n\n        if ($_POST['Message'] == '') {\n            $body = file_get_contents('contents.html');\n        } else {\n            $body = $_POST['Message'];\n        }\n\n        $example_code .= \"\\n\\$body = <<<'EOT'\\n\" . htmlentities($body) . \"\\nEOT;\";\n\n        $mail->WordWrap = 78; // set word wrap to the RFC2822 limit\n        $mail->msgHTML($body, dirname(__FILE__), true); //Create message bodies and embed images\n\n        $example_code .= \"\\n\\$mail->WordWrap = 78;\";\n        $example_code .= \"\\n\\$mail->msgHTML(\\$body, dirname(__FILE__), true); //Create message bodies and embed images\";\n\n        $mail->addAttachment('images/phpmailer_mini.png', 'phpmailer_mini.png'); // optional name\n        $mail->addAttachment('images/phpmailer.png', 'phpmailer.png'); // optional name\n        $example_code .= \"\\n\\$mail->addAttachment('images/phpmailer_mini.png',\" .\n            \"'phpmailer_mini.png');  // optional name\";\n        $example_code .= \"\\n\\$mail->addAttachment('images/phpmailer.png', 'phpmailer.png');  // optional name\";\n\n        $example_code .= \"\\n\\ntry {\";\n        $example_code .= \"\\n  \\$mail->send();\";\n        $example_code .= \"\\n  \\$results_messages[] = \\\"Message has been sent using \" .\n            strtoupper($_POST['test_type']) . \"\\\";\";\n        $example_code .= \"\\n}\";\n        $example_code .= \"\\ncatch (phpmailerException \\$e) {\";\n        $example_code .= \"\\n  throw new phpmailerAppException('Unable to send to: ' . \\$to. ': '.\\$e->getMessage());\";\n        $example_code .= \"\\n}\";\n\n        try {\n            $mail->send();\n            $results_messages[] = \"Message has been sent using \" . strtoupper($_POST[\"test_type\"]);\n        } catch (phpmailerException $e) {\n            throw new phpmailerAppException(\"Unable to send to: \" . $to . ': ' . $e->getMessage());\n        }\n    }\n} catch (phpmailerAppException $e) {\n    $results_messages[] = $e->errorMessage();\n}\n$example_code .= \"\\n}\";\n$example_code .= \"\\ncatch (phpmailerAppException \\$e) {\";\n$example_code .= \"\\n  \\$results_messages[] = \\$e->errorMessage();\";\n$example_code .= \"\\n}\";\n$example_code .= \"\\n\\nif (count(\\$results_messages) > 0) {\";\n$example_code .= \"\\n  echo \\\"<h2>Run results</h2>\\\\n\\\";\";\n$example_code .= \"\\n  echo \\\"<ul>\\\\n\\\";\";\n$example_code .= \"\\nforeach (\\$results_messages as \\$result) {\";\n$example_code .= \"\\n  echo \\\"<li>\\$result</li>\\\\n\\\";\";\n$example_code .= \"\\n}\";\n$example_code .= \"\\necho \\\"</ul>\\\\n\\\";\";\n$example_code .= \"\\n}\";\n?><!DOCTYPE html>\n<html>\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <title>PHPMailer Test Page</title>\n    <script type=\"text/javascript\" src=\"scripts/shCore.js\"></script>\n    <script type=\"text/javascript\" src=\"scripts/shBrushPhp.js\"></script>\n    <link type=\"text/css\" rel=\"stylesheet\" href=\"styles/shCore.css\">\n    <link type=\"text/css\" rel=\"stylesheet\" href=\"styles/shThemeDefault.css\">\n    <style>\n        body {\n            font-family: Arial, Helvetica, sans-serif;\n            font-size: 1em;\n            padding: 1em;\n        }\n\n        table {\n            margin: 0 auto;\n            border-spacing: 0;\n            border-collapse: collapse;\n        }\n\n        table.column {\n            border-collapse: collapse;\n            background-color: #FFFFFF;\n            padding: 0.5em;\n            width: 35em;\n        }\n\n        td {\n            font-size: 1em;\n            padding: 0.1em 0.25em;\n            -moz-border-radius: 1em;\n            -webkit-border-radius: 1em;\n            border-radius: 1em;\n        }\n\n        td.colleft {\n            text-align: right;\n            width: 35%;\n        }\n\n        td.colrite {\n            text-align: left;\n            width: 65%;\n        }\n\n        fieldset {\n            padding: 1em 1em 1em 1em;\n            margin: 0 2em;\n            border-radius: 1.5em;\n            -webkit-border-radius: 1em;\n            -moz-border-radius: 1em;\n        }\n\n        fieldset.inner {\n            width: 40%;\n        }\n\n        fieldset:hover, tr:hover {\n            background-color: #fafafa;\n        }\n\n        legend {\n            font-weight: bold;\n            font-size: 1.1em;\n        }\n\n        div.column-left {\n            float: left;\n            width: 45em;\n            height: 31em;\n        }\n\n        div.column-right {\n            display: inline;\n            width: 45em;\n            max-height: 31em;\n        }\n\n        input.radio {\n            float: left;\n        }\n\n        div.radio {\n            padding: 0.2em;\n        }\n    </style>\n    <script>\n        SyntaxHighlighter.config.clipboardSwf = 'scripts/clipboard.swf';\n        SyntaxHighlighter.all();\n\n        function startAgain() {\n            var post_params = {\n                \"From_Name\": \"<?php echo $from_name; ?>\",\n                \"From_Email\": \"<?php echo $from_email; ?>\",\n                \"To_Name\": \"<?php echo $to_name; ?>\",\n                \"To_Email\": \"<?php echo $to_email; ?>\",\n                \"cc_Email\": \"<?php echo $cc_email; ?>\",\n                \"bcc_Email\": \"<?php echo $bcc_email; ?>\",\n                \"Subject\": \"<?php echo $subject; ?>\",\n                \"Message\": \"<?php echo $message; ?>\",\n                \"test_type\": \"<?php echo $test_type; ?>\",\n                \"smtp_debug\": \"<?php echo $smtp_debug; ?>\",\n                \"smtp_server\": \"<?php echo $smtp_server; ?>\",\n                \"smtp_port\": \"<?php echo $smtp_port; ?>\",\n                \"smtp_secure\": \"<?php echo $smtp_secure; ?>\",\n                \"smtp_authenticate\": \"<?php echo $smtp_authenticate; ?>\",\n                \"authenticate_username\": \"<?php echo $authenticate_username; ?>\",\n                \"authenticate_password\": \"<?php echo $authenticate_password; ?>\"\n            };\n\n            var resetForm = document.createElement(\"form\");\n            resetForm.setAttribute(\"method\", \"POST\");\n            resetForm.setAttribute(\"path\", \"index.php\");\n\n            for (var k in post_params) {\n                var h = document.createElement(\"input\");\n                h.setAttribute(\"type\", \"hidden\");\n                h.setAttribute(\"name\", k);\n                h.setAttribute(\"value\", post_params[k]);\n                resetForm.appendChild(h);\n            }\n\n            document.body.appendChild(resetForm);\n            resetForm.submit();\n        }\n\n        function showHideDiv(test, element_id) {\n            var ops = {\"smtp-options-table\": \"smtp\"};\n\n            if (test == ops[element_id]) {\n                document.getElementById(element_id).style.display = \"block\";\n            } else {\n                document.getElementById(element_id).style.display = \"none\";\n            }\n        }\n    </script>\n</head>\n<body>\n<?php\nif (version_compare(PHP_VERSION, '5.0.0', '<')) {\n    echo 'Current PHP version: ' . phpversion() . \"<br>\";\n    echo exit(\"ERROR: Wrong PHP version. Must be PHP 5 or above.\");\n}\n\nif (count($results_messages) > 0) {\n    echo '<h2>Run results</h2>';\n    echo '<ul>';\n    foreach ($results_messages as $result) {\n        echo \"<li>$result</li>\";\n    }\n    echo '</ul>';\n}\n\nif (isset($_POST[\"submit\"]) && $_POST[\"submit\"] == \"Submit\") {\n    echo \"<button type=\\\"submit\\\" onclick=\\\"startAgain();\\\">Start Over</button><br>\\n\";\n    echo \"<br><span>Script:</span>\\n\";\n    echo \"<pre class=\\\"brush: php;\\\">\\n\";\n    echo $example_code;\n    echo \"\\n</pre>\\n\";\n    echo \"\\n<hr style=\\\"margin: 3em;\\\">\\n\";\n}\n?>\n<form method=\"POST\" enctype=\"multipart/form-data\">\n    <div>\n        <div class=\"column-left\">\n            <fieldset>\n                <legend>Mail Details</legend>\n                <table border=\"1\" class=\"column\">\n                    <tr>\n                        <td class=\"colleft\">\n                            <label for=\"From_Name\"><strong>From</strong> Name</label>\n                        </td>\n                        <td class=\"colrite\">\n                            <input type=\"text\" id=\"From_Name\" name=\"From_Name\" value=\"<?php echo $from_name; ?>\"\n                                   style=\"width:95%;\" autofocus placeholder=\"Your Name\">\n                        </td>\n                    </tr>\n                    <tr>\n                        <td class=\"colleft\">\n                            <label for=\"From_Email\"><strong>From</strong> Email Address</label>\n                        </td>\n                        <td class=\"colrite\">\n                            <input type=\"text\" id=\"From_Email\" name=\"From_Email\" value=\"<?php echo $from_email; ?>\"\n                                   style=\"width:95%;\" required placeholder=\"Your.Email@example.com\">\n                        </td>\n                    </tr>\n                    <tr>\n                        <td class=\"colleft\">\n                            <label for=\"To_Name\"><strong>To</strong> Name</label>\n                        </td>\n                        <td class=\"colrite\">\n                            <input type=\"text\" id=\"To_Name\" name=\"To_Name\" value=\"<?php echo $to_name; ?>\"\n                                   style=\"width:95%;\" placeholder=\"Recipient's Name\">\n                        </td>\n                    </tr>\n                    <tr>\n                        <td class=\"colleft\">\n                            <label for=\"To_Email\"><strong>To</strong> Email Address</label>\n                        </td>\n                        <td class=\"colrite\">\n                            <input type=\"text\" id=\"To_Email\" name=\"To_Email\" value=\"<?php echo $to_email; ?>\"\n                                   style=\"width:95%;\" required placeholder=\"Recipients.Email@example.com\">\n                        </td>\n                    </tr>\n                    <tr>\n                        <td class=\"colleft\">\n                            <label for=\"cc_Email\"><strong>CC Recipients</strong><br>\n                                <small>(separate with commas)</small>\n                            </label>\n                        </td>\n                        <td class=\"colrite\">\n                            <input type=\"text\" id=\"cc_Email\" name=\"cc_Email\" value=\"<?php echo $cc_email; ?>\"\n                                   style=\"width:95%;\" placeholder=\"cc1@example.com, cc2@example.com\">\n                        </td>\n                    </tr>\n                    <tr>\n                        <td class=\"colleft\">\n                            <label for=\"bcc_Email\"><strong>BCC Recipients</strong><br>\n                                <small>(separate with commas)</small>\n                            </label>\n                        </td>\n                        <td class=\"colrite\">\n                            <input type=\"text\" id=\"bcc_Email\" name=\"bcc_Email\" value=\"<?php echo $bcc_email; ?>\"\n                                   style=\"width:95%;\" placeholder=\"bcc1@example.com, bcc2@example.com\">\n                        </td>\n                    </tr>\n                    <tr>\n                        <td class=\"colleft\">\n                            <label for=\"Subject\"><strong>Subject</strong></label>\n                        </td>\n                        <td class=\"colrite\">\n                            <input type=\"text\" name=\"Subject\" id=\"Subject\" value=\"<?php echo $subject; ?>\"\n                                   style=\"width:95%;\" placeholder=\"Email Subject\">\n                        </td>\n                    </tr>\n                    <tr>\n                        <td class=\"colleft\">\n                            <label for=\"Message\"><strong>Message</strong><br>\n                                <small>If blank, will use content.html</small>\n                            </label>\n                        </td>\n                        <td class=\"colrite\">\n                            <textarea name=\"Message\" id=\"Message\" style=\"width:95%;height:5em;\"\n                                      placeholder=\"Body of your email\"><?php echo $message; ?></textarea>\n                        </td>\n                    </tr>\n                </table>\n                <div style=\"margin:1em 0;\">Test will include two attachments.</div>\n            </fieldset>\n        </div>\n        <div class=\"column-right\">\n            <fieldset class=\"inner\"> <!-- SELECT TYPE OF MAIL -->\n                <legend>Mail Test Specs</legend>\n                <table border=\"1\" class=\"column\">\n                    <tr>\n                        <td class=\"colleft\">Test Type</td>\n                        <td class=\"colrite\">\n                            <div class=\"radio\">\n                                <label for=\"radio-mail\">Mail()</label>\n                                <input class=\"radio\" type=\"radio\" name=\"test_type\" value=\"mail\" id=\"radio-mail\"\n                                       onclick=\"showHideDiv(this.value, 'smtp-options-table');\"\n                                       <?php echo ($test_type == 'mail') ? 'checked' : ''; ?>\n                                       required>\n                            </div>\n                            <div class=\"radio\">\n                                <label for=\"radio-sendmail\">Sendmail</label>\n                                <input class=\"radio\" type=\"radio\" name=\"test_type\" value=\"sendmail\" id=\"radio-sendmail\"\n                                       onclick=\"showHideDiv(this.value, 'smtp-options-table');\"\n                                       <?php echo ($test_type == 'sendmail') ? 'checked' : ''; ?>\n                                       required>\n                            </div>\n                            <div class=\"radio\">\n                                <label for=\"radio-qmail\">Qmail</label>\n                                <input class=\"radio\" type=\"radio\" name=\"test_type\" value=\"qmail\" id=\"radio-qmail\"\n                                       onclick=\"showHideDiv(this.value, 'smtp-options-table');\"\n                                       <?php echo ($test_type == 'qmail') ? 'checked' : ''; ?>\n                                       required>\n                            </div>\n                            <div class=\"radio\">\n                                <label for=\"radio-smtp\">SMTP</label>\n                                <input class=\"radio\" type=\"radio\" name=\"test_type\" value=\"smtp\" id=\"radio-smtp\"\n                                       onclick=\"showHideDiv(this.value, 'smtp-options-table');\"\n                                       <?php echo ($test_type == 'smtp') ? 'checked' : ''; ?>\n                                       required>\n                            </div>\n                        </td>\n                    </tr>\n                </table>\n                <div id=\"smtp-options-table\" style=\"margin:1em 0 0 0;\n<?php if ($test_type != 'smtp') {\n    echo \"display: none;\";\n} ?>\">\n                    <span style=\"margin:1.25em 0; display:block;\"><strong>SMTP Specific Options:</strong></span>\n                    <table border=\"1\" class=\"column\">\n                        <tr>\n                            <td class=\"colleft\"><label for=\"smtp_debug\">SMTP Debug ?</label></td>\n                            <td class=\"colrite\">\n                                <select size=\"1\" id=\"smtp_debug\" name=\"smtp_debug\">\n                                    <option <?php echo ($smtp_debug == '0') ? 'selected' : ''; ?> value=\"0\">\n                                        0 - Disabled\n                                    </option>\n                                    <option <?php echo ($smtp_debug == '1') ? 'selected' : ''; ?> value=\"1\">\n                                        1 - Client messages\n                                    </option>\n                                    <option <?php echo ($smtp_debug == '2') ? 'selected' : ''; ?> value=\"2\">\n                                        2 - Client and server messages\n                                    </option>\n                                </select>\n                            </td>\n                        </tr>\n                        <tr>\n                            <td class=\"colleft\"><label for=\"smtp_server\">SMTP Server</label></td>\n                            <td class=\"colrite\">\n                                <input type=\"text\" id=\"smtp_server\" name=\"smtp_server\"\n                                       value=\"<?php echo $smtp_server; ?>\" style=\"width:95%;\"\n                                       placeholder=\"smtp.server.com\">\n                            </td>\n                        </tr>\n                        <tr>\n                            <td class=\"colleft\" style=\"width: 5em;\"><label for=\"smtp_port\">SMTP Port</label></td>\n                            <td class=\"colrite\">\n                                <input type=\"text\" name=\"smtp_port\" id=\"smtp_port\" size=\"3\"\n                                       value=\"<?php echo $smtp_port; ?>\" placeholder=\"Port\">\n                            </td>\n                        </tr>\n                        <tr>\n                            <td class=\"colleft\"><label for=\"smtp_secure\">SMTP Security</label></td>\n                            <td>\n                                <select size=\"1\" name=\"smtp_secure\" id=\"smtp_secure\">\n                                    <option <?php echo ($smtp_secure == 'none') ? 'selected' : '' ?>>None</option>\n                                    <option <?php echo ($smtp_secure == 'tls') ? 'selected' : '' ?>>TLS</option>\n                                    <option <?php echo ($smtp_secure == 'ssl') ? 'selected' : '' ?>>SSL</option>\n                                </select>\n                            </td>\n                        </tr>\n                        <tr>\n                            <td class=\"colleft\"><label for=\"smtp-authenticate\">SMTP Authenticate?</label></td>\n                            <td class=\"colrite\">\n                                <input type=\"checkbox\" id=\"smtp-authenticate\"\n                                       name=\"smtp_authenticate\"\n<?php if ($smtp_authenticate != '') {\n    echo \"checked\";\n} ?>\n                                       value=\"<?php echo $smtp_authenticate; ?>\">\n                            </td>\n                        </tr>\n                        <tr>\n                            <td class=\"colleft\"><label for=\"authenticate_username\">Authenticate Username</label></td>\n                            <td class=\"colrite\">\n                                <input type=\"text\" id=\"authenticate_username\" name=\"authenticate_username\"\n                                       value=\"<?php echo $authenticate_username; ?>\" style=\"width:95%;\"\n                                       placeholder=\"SMTP Server Username\">\n                            </td>\n                        </tr>\n                        <tr>\n                            <td class=\"colleft\"><label for=\"authenticate_password\">Authenticate Password</label></td>\n                            <td class=\"colrite\">\n                                <input type=\"password\" name=\"authenticate_password\" id=\"authenticate_password\"\n                                       value=\"<?php echo $authenticate_password; ?>\" style=\"width:95%;\"\n                                       placeholder=\"SMTP Server Password\">\n                            </td>\n                        </tr>\n                    </table>\n                </div>\n            </fieldset>\n        </div>\n        <br style=\"clear:both;\">\n\n        <div style=\"margin-left:2em; margin-bottom:5em; float:left;\">\n            <div style=\"margin-bottom: 1em; \">\n                <input type=\"submit\" value=\"Submit\" name=\"submit\">\n            </div>\n            <?php echo 'Current PHP version: ' . phpversion(); ?>\n        </div>\n    </div>\n</form>\n</body>\n</html>\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/contactform.phps",
    "content": "<?php\n/**\n * This example shows how to handle a simple contact form.\n */\n\n$msg = '';\n//Don't run this unless we're handling a form submission\nif (array_key_exists('email', $_POST)) {\n    date_default_timezone_set('Etc/UTC');\n\n    require '../PHPMailerAutoload.php';\n\n    //Create a new PHPMailer instance\n    $mail = new PHPMailer;\n    //Tell PHPMailer to use SMTP - requires a local mail server\n    //Faster and safer than using mail()\n    $mail->isSMTP();\n    $mail->Host = 'localhost';\n    $mail->Port = 25;\n\n    //Use a fixed address in your own domain as the from address\n    //**DO NOT** use the submitter's address here as it will be forgery\n    //and will cause your messages to fail SPF checks\n    $mail->setFrom('from@example.com', 'First Last');\n    //Send the message to yourself, or whoever should receive contact for submissions\n    $mail->addAddress('whoto@example.com', 'John Doe');\n    //Put the submitter's address in a reply-to header\n    //This will fail if the address provided is invalid,\n    //in which case we should ignore the whole request\n    if ($mail->addReplyTo($_POST['email'], $_POST['name'])) {\n        $mail->Subject = 'PHPMailer contact form';\n        //Keep it simple - don't use HTML\n        $mail->isHTML(false);\n        //Build a simple message body\n        $mail->Body = <<<EOT\nEmail: {$_POST['email']}\nName: {$_POST['name']}\nMessage: {$_POST['message']}\nEOT;\n        //Send the message, check for errors\n        if (!$mail->send()) {\n            //The reason for failing to send will be in $mail->ErrorInfo\n            //but you shouldn't display errors to users - process the error, log it on your server.\n            $msg = 'Sorry, something went wrong. Please try again later.';\n        } else {\n            $msg = 'Message sent! Thanks for contacting us.';\n        }\n    } else {\n        $msg = 'Invalid email address, message ignored.';\n    }\n}\n?>\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"UTF-8\">\n    <title>Contact form</title>\n</head>\n<body>\n<h1>Contact us</h1>\n<?php if (!empty($msg)) {\n    echo \"<h2>$msg</h2>\";\n} ?>\n<form method=\"POST\">\n    <label for=\"name\">Name: <input type=\"text\" name=\"name\" id=\"name\"></label><br>\n    <label for=\"email\">Email address: <input type=\"email\" name=\"email\" id=\"email\"></label><br>\n    <label for=\"message\">Message: <textarea name=\"message\" id=\"message\" rows=\"8\" cols=\"20\"></textarea></label><br>\n    <input type=\"submit\" value=\"Send\">\n</form>\n</body>\n</html>\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/contents.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n  <title>PHPMailer Test</title>\n</head>\n<body>\n<div style=\"width: 640px; font-family: Arial, Helvetica, sans-serif; font-size: 11px;\">\n  <h1>This is a test of PHPMailer.</h1>\n  <div align=\"center\">\n    <a href=\"https://github.com/PHPMailer/PHPMailer/\"><img src=\"images/phpmailer.png\" height=\"90\" width=\"340\" alt=\"PHPMailer rocks\"></a>\n  </div>\n  <p>This example uses <strong>HTML</strong>.</p>\n  <p>ISO-8859-1 text: </p>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/contentsutf8.html",
    "content": "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n<html>\n<head>\n  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n  <title>PHPMailer Test</title>\n</head>\n<body>\n<div style=\"width: 640px; font-family: Arial, Helvetica, sans-serif; font-size: 11px;\">\n  <h1>This is a test of PHPMailer.</h1>\n  <div align=\"center\">\n    <a href=\"https://github.com/PHPMailer/PHPMailer/\"><img src=\"images/phpmailer.png\" height=\"90\" width=\"340\" alt=\"PHPMailer rocks\"></a>\n  </div>\n  <p>This example uses <strong>HTML</strong>.</p>\n  <p>Chinese text: 郵件內容為空</p>\n  <p>Russian text: Пустое тело сообщения</p>\n  <p>Armenian text: Հաղորդագրությունը դատարկ է</p>\n  <p>Czech text: Prázdné tělo zprávy</p>\n  <p>Emoji: <span style=\"font-size: 48px\">😂 🦄 💥 📤 📧</span></p>\n</div>\n</body>\n</html>\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/exceptions.phps",
    "content": "<?php\n/**\n * This example shows how to make use of PHPMailer's exceptions for error handling.\n */\n\nrequire '../PHPMailerAutoload.php';\n\n//Create a new PHPMailer instance\n//Passing true to the constructor enables the use of exceptions for error handling\n$mail = new PHPMailer(true);\ntry {\n    //Set who the message is to be sent from\n    $mail->setFrom('from@example.com', 'First Last');\n    //Set an alternative reply-to address\n    $mail->addReplyTo('replyto@example.com', 'First Last');\n    //Set who the message is to be sent to\n    $mail->addAddress('whoto@example.com', 'John Doe');\n    //Set the subject line\n    $mail->Subject = 'PHPMailer Exceptions test';\n    //Read an HTML message body from an external file, convert referenced images to embedded,\n    //and convert the HTML into a basic plain-text alternative body\n    $mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));\n    //Replace the plain text body with one created manually\n    $mail->AltBody = 'This is a plain-text message body';\n    //Attach an image file\n    $mail->addAttachment('images/phpmailer_mini.png');\n    //send the message\n    //Note that we don't need check the response from this because it will throw an exception if it has trouble\n    $mail->send();\n    echo \"Message sent!\";\n} catch (phpmailerException $e) {\n    echo $e->errorMessage(); //Pretty error messages from PHPMailer\n} catch (Exception $e) {\n    echo $e->getMessage(); //Boring error messages from anything else!\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/gmail.phps",
    "content": "<?php\n/**\n * This example shows settings to use when sending via Google's Gmail servers.\n */\n\n//SMTP needs accurate times, and the PHP time zone MUST be set\n//This should be done in your php.ini, but this is how to do it if you don't have access to that\ndate_default_timezone_set('Etc/UTC');\n\nrequire '../PHPMailerAutoload.php';\n\n//Create a new PHPMailer instance\n$mail = new PHPMailer;\n\n//Tell PHPMailer to use SMTP\n$mail->isSMTP();\n\n//Enable SMTP debugging\n// 0 = off (for production use)\n// 1 = client messages\n// 2 = client and server messages\n$mail->SMTPDebug = 2;\n\n//Ask for HTML-friendly debug output\n$mail->Debugoutput = 'html';\n\n//Set the hostname of the mail server\n$mail->Host = 'smtp.gmail.com';\n// use\n// $mail->Host = gethostbyname('smtp.gmail.com');\n// if your network does not support SMTP over IPv6\n\n//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission\n$mail->Port = 587;\n\n//Set the encryption system to use - ssl (deprecated) or tls\n$mail->SMTPSecure = 'tls';\n\n//Whether to use SMTP authentication\n$mail->SMTPAuth = true;\n\n//Username to use for SMTP authentication - use full email address for gmail\n$mail->Username = \"username@gmail.com\";\n\n//Password to use for SMTP authentication\n$mail->Password = \"yourpassword\";\n\n//Set who the message is to be sent from\n$mail->setFrom('from@example.com', 'First Last');\n\n//Set an alternative reply-to address\n$mail->addReplyTo('replyto@example.com', 'First Last');\n\n//Set who the message is to be sent to\n$mail->addAddress('whoto@example.com', 'John Doe');\n\n//Set the subject line\n$mail->Subject = 'PHPMailer GMail SMTP test';\n\n//Read an HTML message body from an external file, convert referenced images to embedded,\n//convert HTML into a basic plain-text alternative body\n$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));\n\n//Replace the plain text body with one created manually\n$mail->AltBody = 'This is a plain-text message body';\n\n//Attach an image file\n$mail->addAttachment('images/phpmailer_mini.png');\n\n//send the message, check for errors\nif (!$mail->send()) {\n    echo \"Mailer Error: \" . $mail->ErrorInfo;\n} else {\n    echo \"Message sent!\";\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/gmail_xoauth.phps",
    "content": "<?php\n/**\n * This example shows settings to use when sending via Google's Gmail servers.\n */\n\n//SMTP needs accurate times, and the PHP time zone MUST be set\n//This should be done in your php.ini, but this is how to do it if you don't have access to that\ndate_default_timezone_set('Etc/UTC');\n\nrequire '../PHPMailerAutoload.php';\n\n//Load dependencies from composer\n//If this causes an error, run 'composer install'\nrequire '../vendor/autoload.php';\n\n//Create a new PHPMailer instance\n$mail = new PHPMailerOAuth;\n\n//Tell PHPMailer to use SMTP\n$mail->isSMTP();\n\n//Enable SMTP debugging\n// 0 = off (for production use)\n// 1 = client messages\n// 2 = client and server messages\n$mail->SMTPDebug = 0;\n\n//Ask for HTML-friendly debug output\n$mail->Debugoutput = 'html';\n\n//Set the hostname of the mail server\n$mail->Host = 'smtp.gmail.com';\n\n//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission\n$mail->Port = 587;\n\n//Set the encryption system to use - ssl (deprecated) or tls\n$mail->SMTPSecure = 'tls';\n\n//Whether to use SMTP authentication\n$mail->SMTPAuth = true;\n\n//Set AuthType\n$mail->AuthType = 'XOAUTH2';\n\n//User Email to use for SMTP authentication - Use the same Email used in Google Developer Console\n$mail->oauthUserEmail = \"someone@gmail.com\";\n\n//Obtained From Google Developer Console\n$mail->oauthClientId = \"RANDOMCHARS-----duv1n2.apps.googleusercontent.com\";\n\n//Obtained From Google Developer Console\n$mail->oauthClientSecret = \"RANDOMCHARS-----lGyjPcRtvP\";\n\n//Obtained By running get_oauth_token.php after setting up APP in Google Developer Console.\n//Set Redirect URI in Developer Console as [https/http]://<yourdomain>/<folder>/get_oauth_token.php\n// eg: http://localhost/phpmail/get_oauth_token.php\n$mail->oauthRefreshToken = \"RANDOMCHARS-----DWxgOvPT003r-yFUV49TQYag7_Aod7y0\";\n\n//Set who the message is to be sent from\n//For gmail, this generally needs to be the same as the user you logged in as\n$mail->setFrom('from@example.com', 'First Last');\n\n//Set who the message is to be sent to\n$mail->addAddress('whoto@example.com', 'John Doe');\n\n//Set the subject line\n$mail->Subject = 'PHPMailer GMail SMTP test';\n\n//Read an HTML message body from an external file, convert referenced images to embedded,\n//convert HTML into a basic plain-text alternative body\n$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));\n\n//Replace the plain text body with one created manually\n$mail->AltBody = 'This is a plain-text message body';\n\n//Attach an image file\n$mail->addAttachment('images/phpmailer_mini.png');\n\n//send the message, check for errors\nif (!$mail->send()) {\n    echo \"Mailer Error: \" . $mail->ErrorInfo;\n} else {\n    echo \"Message sent!\";\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/index.html",
    "content": "<!DOCTYPE html>\n<html>\n<head>\n\t<meta charset=\"UTF-8\">\n\t<title>PHPMailer Examples</title>\n</head>\n<body>\n<h1>PHPMailer code examples<a href=\"https://github.com/PHPMailer/PHPMailer\"><img src=\"images/phpmailer.png\" style=\"float:right; border:0;\" alt=\"PHPMailer logo\"></a></h1>\n<p>This folder contains a collection of examples of using <a href=\"https://github.com/PHPMailer/PHPMailer\">PHPMailer</a>.</p>\n<h2>About testing email sending</h2>\n<p>When working on email sending code you'll find yourself worrying about what might happen if all these test emails got sent to your mailing list. The solution is to use a fake mail server, one that acts just like the real thing, but just doesn't actually send anything out. Some offer web interfaces, feedback, logging, the ability to return specific error codes, all things that are useful for testing error handling, authentication etc. Here's a selection of mail testing tools you might like to try:</p>\n<ul>\n  <li><a href=\"https://github.com/Nilhcem/FakeSMTP\">FakeSMTP</a>, a Java desktop app with the ability to show an SMTP log and save messages to a folder. </li>\n  <li><a href=\"https://github.com/isotoma/FakeEmail\">FakeEmail</a>, a Python-based fake mail server with a web interface.</li>\n  <li><a href=\"http://www.postfix.org/smtp-sink.1.html\">smtp-sink</a>, part of the Postfix mail server, so you probably already have this installed. This is used in the Travis-CI configuration to run PHPMailer's unit tests.</li>\n  <li><a href=\"http://smtp4dev.codeplex.com\">smtp4dev</a>, a dummy SMTP server for Windows.</li>\n  <li><a href=\"https://github.com/PHPMailer/PHPMailer/blob/master/test/fakesendmail.sh\">fakesendmail.sh</a>, part of PHPMailer's test setup, this is a shell script that emulates sendmail for testing 'mail' or 'sendmail' methods in PHPMailer.</li>\n  <li><a href=\"http://tools.ietf.org/tools/msglint/\">msglint</a>, not a mail server, the IETF's MIME structure analyser checks the formatting of your messages.</li>\n</ul>\n<div style=\"padding: 8px; color: #333333; background-color: #dc8b92\">\n<h2>Security note</h2>\n<p>Before running these examples you'll need to rename them with '.php' extensions. They are supplied as '.phps' files which will usually be displayed with syntax highlighting by PHP instead of running them. This prevents potential security issues with running potential spam-gateway code if you happen to deploy these code examples on a live site - <em>please don't do that!</em> Similarly, don't leave your passwords in these files as they will be visible to the world!</p>\n</div>\n<h2><a href=\"code_generator.phps\">code_generator.phps</a></h2>\n<p>This script is a simple code generator - fill in the form and hit submit, and it will use when you entered to email you a message, and will also generate PHP code using your settings that you can copy and paste to use in your own apps. If you need to get going quickly, this is probably the best place to start.</p>\n<h2><a href=\"mail.phps\">mail.phps</a></h2>\n<p>This script is a basic example which creates an email message from an external HTML file, creates a plain text body, sets various addresses, adds an attachment and sends the message. It uses PHP's built-in mail() function which is the simplest to use, but relies on the presence of a local mail server, something which is not usually available on Windows. If you find yourself in that situation, either install a local mail server, or use a remote one and send using SMTP instead.</p>\n<h2><a href=\"exceptions.phps\">exceptions.phps</a></h2>\n<p>The same as the mail example, but shows how to use PHPMailer's optional exceptions for error handling.</p>\n<h2><a href=\"smtp.phps\">smtp.phps</a></h2>\n<p>A simple example sending using SMTP with authentication.</p>\n<h2><a href=\"smtp_no_auth.phps\">smtp_no_auth.phps</a></h2>\n<p>A simple example sending using SMTP without authentication.</p>\n<h2><a href=\"sendmail.phps\">sendmail.phps</a></h2>\n<p>A simple example using sendmail. Sendmail is a program (usually found on Linux/BSD, OS X and other UNIX-alikes) that can be used to submit messages to a local mail server without a lengthy SMTP conversation. It's probably the fastest sending mechanism, but lacks some error reporting features. There are sendmail emulators for most popular mail servers including postfix, qmail, exim etc.</p>\n<h2><a href=\"gmail.phps\">gmail.phps</a></h2>\n<p>Submitting email via Google's Gmail service is a popular use of PHPMailer. It's much the same as normal SMTP sending, just with some specific settings, namely using TLS encryption, authentication is enabled, and it connects to the SMTP submission port 587 on the smtp.gmail.com host. This example does all that.</p>\n<h2><a href=\"pop_before_smtp.phps\">pop_before_smtp.phps</a></h2>\n<p>Before effective SMTP authentication mechanisms were available, it was common for ISPs to use POP-before-SMTP authentication. As it implies, you authenticate using the POP3 protocol (an older protocol now mostly replaced by the far superior IMAP), and then the SMTP server will allow send access from your IP address for a short while, usually 5-15 minutes. PHPMailer includes a POP3 protocol client, so it can carry out this sequence - it's just like a normal SMTP conversation (without authentication), but connects via POP first.</p>\n<h2><a href=\"mailing_list.phps\">mailing_list.phps</a></h2>\n<p>This is a somewhat naïve example of sending similar emails to a list of different addresses. It sets up a PHPMailer instance using SMTP, then connects to a MySQL database to retrieve a list of recipients. The code loops over this list, sending email to each person using their info and marks them as sent in the database. It makes use of SMTP keepalive which saves reconnecting and re-authenticating between each message.</p>\n<hr>\n<h2><a href=\"smtp_check.phps\">smtp_check.phps</a></h2>\n<p>This is an example showing how to use the SMTP class by itself (without PHPMailer) to check an SMTP connection.</p>\n<hr>\n<p>Most of these examples use the 'example.com' domain. This domain is reserved by IANA for illustrative purposes, as documented in <a href=\"http://tools.ietf.org/html/rfc2606\">RFC 2606</a>. Don't use made-up domains like 'mydomain.com' or 'somedomain.com' in examples as someone, somewhere, probably owns them!</p>\n</body>\n</html>\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/mail.phps",
    "content": "<?php\n/**\n * This example shows sending a message using PHP's mail() function.\n */\n\nrequire '../PHPMailerAutoload.php';\n\n//Create a new PHPMailer instance\n$mail = new PHPMailer;\n//Set who the message is to be sent from\n$mail->setFrom('from@example.com', 'First Last');\n//Set an alternative reply-to address\n$mail->addReplyTo('replyto@example.com', 'First Last');\n//Set who the message is to be sent to\n$mail->addAddress('whoto@example.com', 'John Doe');\n//Set the subject line\n$mail->Subject = 'PHPMailer mail() test';\n//Read an HTML message body from an external file, convert referenced images to embedded,\n//convert HTML into a basic plain-text alternative body\n$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));\n//Replace the plain text body with one created manually\n$mail->AltBody = 'This is a plain-text message body';\n//Attach an image file\n$mail->addAttachment('images/phpmailer_mini.png');\n\n//send the message, check for errors\nif (!$mail->send()) {\n    echo \"Mailer Error: \" . $mail->ErrorInfo;\n} else {\n    echo \"Message sent!\";\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/mailing_list.phps",
    "content": "<?php\n\nerror_reporting(E_STRICT | E_ALL);\n\ndate_default_timezone_set('Etc/UTC');\n\nrequire '../PHPMailerAutoload.php';\n\n$mail = new PHPMailer;\n\n$body = file_get_contents('contents.html');\n\n$mail->isSMTP();\n$mail->Host = 'smtp.example.com';\n$mail->SMTPAuth = true;\n$mail->SMTPKeepAlive = true; // SMTP connection will not close after each email sent, reduces SMTP overhead\n$mail->Port = 25;\n$mail->Username = 'yourname@example.com';\n$mail->Password = 'yourpassword';\n$mail->setFrom('list@example.com', 'List manager');\n$mail->addReplyTo('list@example.com', 'List manager');\n\n$mail->Subject = \"PHPMailer Simple database mailing list test\";\n\n//Same body for all messages, so set this before the sending loop\n//If you generate a different body for each recipient (e.g. you're using a templating system),\n//set it inside the loop\n$mail->msgHTML($body);\n//msgHTML also sets AltBody, but if you want a custom one, set it afterwards\n$mail->AltBody = 'To view the message, please use an HTML compatible email viewer!';\n\n//Connect to the database and select the recipients from your mailing list that have not yet been sent to\n//You'll need to alter this to match your database\n$mysql = mysqli_connect('localhost', 'username', 'password');\nmysqli_select_db($mysql, 'mydb');\n$result = mysqli_query($mysql, 'SELECT full_name, email, photo FROM mailinglist WHERE sent = false');\n\nforeach ($result as $row) { //This iterator syntax only works in PHP 5.4+\n    $mail->addAddress($row['email'], $row['full_name']);\n    if (!empty($row['photo'])) {\n        $mail->addStringAttachment($row['photo'], 'YourPhoto.jpg'); //Assumes the image data is stored in the DB\n    }\n\n    if (!$mail->send()) {\n        echo \"Mailer Error (\" . str_replace(\"@\", \"&#64;\", $row[\"email\"]) . ') ' . $mail->ErrorInfo . '<br />';\n        break; //Abandon sending\n    } else {\n        echo \"Message sent to :\" . $row['full_name'] . ' (' . str_replace(\"@\", \"&#64;\", $row['email']) . ')<br />';\n        //Mark it as sent in the DB\n        mysqli_query(\n            $mysql,\n            \"UPDATE mailinglist SET sent = true WHERE email = '\" .\n            mysqli_real_escape_string($mysql, $row['email']) . \"'\"\n        );\n    }\n    // Clear all addresses and attachments for next loop\n    $mail->clearAddresses();\n    $mail->clearAttachments();\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/pop_before_smtp.phps",
    "content": "<?php\n/**\n * This example shows how to use POP-before-SMTP for authentication.\n */\n\nrequire '../PHPMailerAutoload.php';\n\n//Authenticate via POP3.\n//After this you should be allowed to submit messages over SMTP for a while.\n//Only applies if your host supports POP-before-SMTP.\n$pop = POP3::popBeforeSmtp('pop3.example.com', 110, 30, 'username', 'password', 1);\n\n//Create a new PHPMailer instance\n//Passing true to the constructor enables the use of exceptions for error handling\n$mail = new PHPMailer(true);\ntry {\n    $mail->isSMTP();\n    //Enable SMTP debugging\n    // 0 = off (for production use)\n    // 1 = client messages\n    // 2 = client and server messages\n    $mail->SMTPDebug = 2;\n    //Ask for HTML-friendly debug output\n    $mail->Debugoutput = 'html';\n    //Set the hostname of the mail server\n    $mail->Host = \"mail.example.com\";\n    //Set the SMTP port number - likely to be 25, 465 or 587\n    $mail->Port = 25;\n    //Whether to use SMTP authentication\n    $mail->SMTPAuth = false;\n    //Set who the message is to be sent from\n    $mail->setFrom('from@example.com', 'First Last');\n    //Set an alternative reply-to address\n    $mail->addReplyTo('replyto@example.com', 'First Last');\n    //Set who the message is to be sent to\n    $mail->addAddress('whoto@example.com', 'John Doe');\n    //Set the subject line\n    $mail->Subject = 'PHPMailer POP-before-SMTP test';\n    //Read an HTML message body from an external file, convert referenced images to embedded,\n    //and convert the HTML into a basic plain-text alternative body\n    $mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));\n    //Replace the plain text body with one created manually\n    $mail->AltBody = 'This is a plain-text message body';\n    //Attach an image file\n    $mail->addAttachment('images/phpmailer_mini.png');\n    //send the message\n    //Note that we don't need check the response from this because it will throw an exception if it has trouble\n    $mail->send();\n    echo \"Message sent!\";\n} catch (phpmailerException $e) {\n    echo $e->errorMessage(); //Pretty error messages from PHPMailer\n} catch (Exception $e) {\n    echo $e->getMessage(); //Boring error messages from anything else!\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/scripts/XRegExp.js",
    "content": "// XRegExp 1.5.1\n// (c) 2007-2012 Steven Levithan\n// MIT License\n// <http://xregexp.com>\n// Provides an augmented, extensible, cross-browser implementation of regular expressions,\n// including support for additional syntax, flags, and methods\n\nvar XRegExp;\n\nif (XRegExp) {\n    // Avoid running twice, since that would break references to native globals\n    throw Error(\"can't load XRegExp twice in the same frame\");\n}\n\n// Run within an anonymous function to protect variables and avoid new globals\n(function (undefined) {\n\n    //---------------------------------\n    //  Constructor\n    //---------------------------------\n\n    // Accepts a pattern and flags; returns a new, extended `RegExp` object. Differs from a native\n    // regular expression in that additional syntax and flags are supported and cross-browser\n    // syntax inconsistencies are ameliorated. `XRegExp(/regex/)` clones an existing regex and\n    // converts to type XRegExp\n    XRegExp = function (pattern, flags) {\n        var output = [],\n            currScope = XRegExp.OUTSIDE_CLASS,\n            pos = 0,\n            context, tokenResult, match, chr, regex;\n\n        if (XRegExp.isRegExp(pattern)) {\n            if (flags !== undefined)\n                throw TypeError(\"can't supply flags when constructing one RegExp from another\");\n            return clone(pattern);\n        }\n        // Tokens become part of the regex construction process, so protect against infinite\n        // recursion when an XRegExp is constructed within a token handler or trigger\n        if (isInsideConstructor)\n            throw Error(\"can't call the XRegExp constructor within token definition functions\");\n\n        flags = flags || \"\";\n        context = { // `this` object for custom tokens\n            hasNamedCapture: false,\n            captureNames: [],\n            hasFlag: function (flag) {return flags.indexOf(flag) > -1;},\n            setFlag: function (flag) {flags += flag;}\n        };\n\n        while (pos < pattern.length) {\n            // Check for custom tokens at the current position\n            tokenResult = runTokens(pattern, pos, currScope, context);\n\n            if (tokenResult) {\n                output.push(tokenResult.output);\n                pos += (tokenResult.match[0].length || 1);\n            } else {\n                // Check for native multicharacter metasequences (excluding character classes) at\n                // the current position\n                if (match = nativ.exec.call(nativeTokens[currScope], pattern.slice(pos))) {\n                    output.push(match[0]);\n                    pos += match[0].length;\n                } else {\n                    chr = pattern.charAt(pos);\n                    if (chr === \"[\")\n                        currScope = XRegExp.INSIDE_CLASS;\n                    else if (chr === \"]\")\n                        currScope = XRegExp.OUTSIDE_CLASS;\n                    // Advance position one character\n                    output.push(chr);\n                    pos++;\n                }\n            }\n        }\n\n        regex = RegExp(output.join(\"\"), nativ.replace.call(flags, flagClip, \"\"));\n        regex._xregexp = {\n            source: pattern,\n            captureNames: context.hasNamedCapture ? context.captureNames : null\n        };\n        return regex;\n    };\n\n\n    //---------------------------------\n    //  Public properties\n    //---------------------------------\n\n    XRegExp.version = \"1.5.1\";\n\n    // Token scope bitflags\n    XRegExp.INSIDE_CLASS = 1;\n    XRegExp.OUTSIDE_CLASS = 2;\n\n\n    //---------------------------------\n    //  Private variables\n    //---------------------------------\n\n    var replacementToken = /\\$(?:(\\d\\d?|[$&`'])|{([$\\w]+)})/g,\n        flagClip = /[^gimy]+|([\\s\\S])(?=[\\s\\S]*\\1)/g, // Nonnative and duplicate flags\n        quantifier = /^(?:[?*+]|{\\d+(?:,\\d*)?})\\??/,\n        isInsideConstructor = false,\n        tokens = [],\n        // Copy native globals for reference (\"native\" is an ES3 reserved keyword)\n        nativ = {\n            exec: RegExp.prototype.exec,\n            test: RegExp.prototype.test,\n            match: String.prototype.match,\n            replace: String.prototype.replace,\n            split: String.prototype.split\n        },\n        compliantExecNpcg = nativ.exec.call(/()??/, \"\")[1] === undefined, // check `exec` handling of nonparticipating capturing groups\n        compliantLastIndexIncrement = function () {\n            var x = /^/g;\n            nativ.test.call(x, \"\");\n            return !x.lastIndex;\n        }(),\n        hasNativeY = RegExp.prototype.sticky !== undefined,\n        nativeTokens = {};\n\n    // `nativeTokens` match native multicharacter metasequences only (including deprecated octals,\n    // excluding character classes)\n    nativeTokens[XRegExp.INSIDE_CLASS] = /^(?:\\\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\\dA-Fa-f]{2}|u[\\dA-Fa-f]{4}|c[A-Za-z]|[\\s\\S]))/;\n    nativeTokens[XRegExp.OUTSIDE_CLASS] = /^(?:\\\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\\d*|x[\\dA-Fa-f]{2}|u[\\dA-Fa-f]{4}|c[A-Za-z]|[\\s\\S])|\\(\\?[:=!]|[?*+]\\?|{\\d+(?:,\\d*)?}\\??)/;\n\n\n    //---------------------------------\n    //  Public methods\n    //---------------------------------\n\n    // Lets you extend or change XRegExp syntax and create custom flags. This is used internally by\n    // the XRegExp library and can be used to create XRegExp plugins. This function is intended for\n    // users with advanced knowledge of JavaScript's regular expression syntax and behavior. It can\n    // be disabled by `XRegExp.freezeTokens`\n    XRegExp.addToken = function (regex, handler, scope, trigger) {\n        tokens.push({\n            pattern: clone(regex, \"g\" + (hasNativeY ? \"y\" : \"\")),\n            handler: handler,\n            scope: scope || XRegExp.OUTSIDE_CLASS,\n            trigger: trigger || null\n        });\n    };\n\n    // Accepts a pattern and flags; returns an extended `RegExp` object. If the pattern and flag\n    // combination has previously been cached, the cached copy is returned; otherwise the newly\n    // created regex is cached\n    XRegExp.cache = function (pattern, flags) {\n        var key = pattern + \"/\" + (flags || \"\");\n        return XRegExp.cache[key] || (XRegExp.cache[key] = XRegExp(pattern, flags));\n    };\n\n    // Accepts a `RegExp` instance; returns a copy with the `/g` flag set. The copy has a fresh\n    // `lastIndex` (set to zero). If you want to copy a regex without forcing the `global`\n    // property, use `XRegExp(regex)`. Do not use `RegExp(regex)` because it will not preserve\n    // special properties required for named capture\n    XRegExp.copyAsGlobal = function (regex) {\n        return clone(regex, \"g\");\n    };\n\n    // Accepts a string; returns the string with regex metacharacters escaped. The returned string\n    // can safely be used at any point within a regex to match the provided literal string. Escaped\n    // characters are [ ] { } ( ) * + ? - . , \\ ^ $ | # and whitespace\n    XRegExp.escape = function (str) {\n        return str.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g, \"\\\\$&\");\n    };\n\n    // Accepts a string to search, regex to search with, position to start the search within the\n    // string (default: 0), and an optional Boolean indicating whether matches must start at-or-\n    // after the position or at the specified position only. This function ignores the `lastIndex`\n    // of the provided regex in its own handling, but updates the property for compatibility\n    XRegExp.execAt = function (str, regex, pos, anchored) {\n        var r2 = clone(regex, \"g\" + ((anchored && hasNativeY) ? \"y\" : \"\")),\n            match;\n        r2.lastIndex = pos = pos || 0;\n        match = r2.exec(str); // Run the altered `exec` (required for `lastIndex` fix, etc.)\n        if (anchored && match && match.index !== pos)\n            match = null;\n        if (regex.global)\n            regex.lastIndex = match ? r2.lastIndex : 0;\n        return match;\n    };\n\n    // Breaks the unrestorable link to XRegExp's private list of tokens, thereby preventing\n    // syntax and flag changes. Should be run after XRegExp and any plugins are loaded\n    XRegExp.freezeTokens = function () {\n        XRegExp.addToken = function () {\n            throw Error(\"can't run addToken after freezeTokens\");\n        };\n    };\n\n    // Accepts any value; returns a Boolean indicating whether the argument is a `RegExp` object.\n    // Note that this is also `true` for regex literals and regexes created by the `XRegExp`\n    // constructor. This works correctly for variables created in another frame, when `instanceof`\n    // and `constructor` checks would fail to work as intended\n    XRegExp.isRegExp = function (o) {\n        return Object.prototype.toString.call(o) === \"[object RegExp]\";\n    };\n\n    // Executes `callback` once per match within `str`. Provides a simpler and cleaner way to\n    // iterate over regex matches compared to the traditional approaches of subverting\n    // `String.prototype.replace` or repeatedly calling `exec` within a `while` loop\n    XRegExp.iterate = function (str, regex, callback, context) {\n        var r2 = clone(regex, \"g\"),\n            i = -1, match;\n        while (match = r2.exec(str)) { // Run the altered `exec` (required for `lastIndex` fix, etc.)\n            if (regex.global)\n                regex.lastIndex = r2.lastIndex; // Doing this to follow expectations if `lastIndex` is checked within `callback`\n            callback.call(context, match, ++i, str, regex);\n            if (r2.lastIndex === match.index)\n                r2.lastIndex++;\n        }\n        if (regex.global)\n            regex.lastIndex = 0;\n    };\n\n    // Accepts a string and an array of regexes; returns the result of using each successive regex\n    // to search within the matches of the previous regex. The array of regexes can also contain\n    // objects with `regex` and `backref` properties, in which case the named or numbered back-\n    // references specified are passed forward to the next regex or returned. E.g.:\n    // var xregexpImgFileNames = XRegExp.matchChain(html, [\n    //     {regex: /<img\\b([^>]+)>/i, backref: 1}, // <img> tag attributes\n    //     {regex: XRegExp('(?ix) \\\\s src=\" (?<src> [^\"]+ )'), backref: \"src\"}, // src attribute values\n    //     {regex: XRegExp(\"^http://xregexp\\\\.com(/[^#?]+)\", \"i\"), backref: 1}, // xregexp.com paths\n    //     /[^\\/]+$/ // filenames (strip directory paths)\n    // ]);\n    XRegExp.matchChain = function (str, chain) {\n        return function recurseChain (values, level) {\n            var item = chain[level].regex ? chain[level] : {regex: chain[level]},\n                regex = clone(item.regex, \"g\"),\n                matches = [], i;\n            for (i = 0; i < values.length; i++) {\n                XRegExp.iterate(values[i], regex, function (match) {\n                    matches.push(item.backref ? (match[item.backref] || \"\") : match[0]);\n                });\n            }\n            return ((level === chain.length - 1) || !matches.length) ?\n                matches : recurseChain(matches, level + 1);\n        }([str], 0);\n    };\n\n\n    //---------------------------------\n    //  New RegExp prototype methods\n    //---------------------------------\n\n    // Accepts a context object and arguments array; returns the result of calling `exec` with the\n    // first value in the arguments array. the context is ignored but is accepted for congruity\n    // with `Function.prototype.apply`\n    RegExp.prototype.apply = function (context, args) {\n        return this.exec(args[0]);\n    };\n\n    // Accepts a context object and string; returns the result of calling `exec` with the provided\n    // string. the context is ignored but is accepted for congruity with `Function.prototype.call`\n    RegExp.prototype.call = function (context, str) {\n        return this.exec(str);\n    };\n\n\n    //---------------------------------\n    //  Overridden native methods\n    //---------------------------------\n\n    // Adds named capture support (with backreferences returned as `result.name`), and fixes two\n    // cross-browser issues per ES3:\n    // - Captured values for nonparticipating capturing groups should be returned as `undefined`,\n    //   rather than the empty string.\n    // - `lastIndex` should not be incremented after zero-length matches.\n    RegExp.prototype.exec = function (str) {\n        var match, name, r2, origLastIndex;\n        if (!this.global)\n            origLastIndex = this.lastIndex;\n        match = nativ.exec.apply(this, arguments);\n        if (match) {\n            // Fix browsers whose `exec` methods don't consistently return `undefined` for\n            // nonparticipating capturing groups\n            if (!compliantExecNpcg && match.length > 1 && indexOf(match, \"\") > -1) {\n                r2 = RegExp(this.source, nativ.replace.call(getNativeFlags(this), \"g\", \"\"));\n                // Using `str.slice(match.index)` rather than `match[0]` in case lookahead allowed\n                // matching due to characters outside the match\n                nativ.replace.call((str + \"\").slice(match.index), r2, function () {\n                    for (var i = 1; i < arguments.length - 2; i++) {\n                        if (arguments[i] === undefined)\n                            match[i] = undefined;\n                    }\n                });\n            }\n            // Attach named capture properties\n            if (this._xregexp && this._xregexp.captureNames) {\n                for (var i = 1; i < match.length; i++) {\n                    name = this._xregexp.captureNames[i - 1];\n                    if (name)\n                       match[name] = match[i];\n                }\n            }\n            // Fix browsers that increment `lastIndex` after zero-length matches\n            if (!compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))\n                this.lastIndex--;\n        }\n        if (!this.global)\n            this.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows)\n        return match;\n    };\n\n    // Fix browser bugs in native method\n    RegExp.prototype.test = function (str) {\n        // Use the native `exec` to skip some processing overhead, even though the altered\n        // `exec` would take care of the `lastIndex` fixes\n        var match, origLastIndex;\n        if (!this.global)\n            origLastIndex = this.lastIndex;\n        match = nativ.exec.call(this, str);\n        // Fix browsers that increment `lastIndex` after zero-length matches\n        if (match && !compliantLastIndexIncrement && this.global && !match[0].length && (this.lastIndex > match.index))\n            this.lastIndex--;\n        if (!this.global)\n            this.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows)\n        return !!match;\n    };\n\n    // Adds named capture support and fixes browser bugs in native method\n    String.prototype.match = function (regex) {\n        if (!XRegExp.isRegExp(regex))\n            regex = RegExp(regex); // Native `RegExp`\n        if (regex.global) {\n            var result = nativ.match.apply(this, arguments);\n            regex.lastIndex = 0; // Fix IE bug\n            return result;\n        }\n        return regex.exec(this); // Run the altered `exec`\n    };\n\n    // Adds support for `${n}` tokens for named and numbered backreferences in replacement text,\n    // and provides named backreferences to replacement functions as `arguments[0].name`. Also\n    // fixes cross-browser differences in replacement text syntax when performing a replacement\n    // using a nonregex search value, and the value of replacement regexes' `lastIndex` property\n    // during replacement iterations. Note that this doesn't support SpiderMonkey's proprietary\n    // third (`flags`) parameter\n    String.prototype.replace = function (search, replacement) {\n        var isRegex = XRegExp.isRegExp(search),\n            captureNames, result, str, origLastIndex;\n\n        // There are too many combinations of search/replacement types/values and browser bugs that\n        // preclude passing to native `replace`, so don't try\n        //if (...)\n        //    return nativ.replace.apply(this, arguments);\n\n        if (isRegex) {\n            if (search._xregexp)\n                captureNames = search._xregexp.captureNames; // Array or `null`\n            if (!search.global)\n                origLastIndex = search.lastIndex;\n        } else {\n            search = search + \"\"; // Type conversion\n        }\n\n        if (Object.prototype.toString.call(replacement) === \"[object Function]\") {\n            result = nativ.replace.call(this + \"\", search, function () {\n                if (captureNames) {\n                    // Change the `arguments[0]` string primitive to a String object which can store properties\n                    arguments[0] = new String(arguments[0]);\n                    // Store named backreferences on `arguments[0]`\n                    for (var i = 0; i < captureNames.length; i++) {\n                        if (captureNames[i])\n                            arguments[0][captureNames[i]] = arguments[i + 1];\n                    }\n                }\n                // Update `lastIndex` before calling `replacement` (fix browsers)\n                if (isRegex && search.global)\n                    search.lastIndex = arguments[arguments.length - 2] + arguments[0].length;\n                return replacement.apply(null, arguments);\n            });\n        } else {\n            str = this + \"\"; // Type conversion, so `args[args.length - 1]` will be a string (given nonstring `this`)\n            result = nativ.replace.call(str, search, function () {\n                var args = arguments; // Keep this function's `arguments` available through closure\n                return nativ.replace.call(replacement + \"\", replacementToken, function ($0, $1, $2) {\n                    // Numbered backreference (without delimiters) or special variable\n                    if ($1) {\n                        switch ($1) {\n                            case \"$\": return \"$\";\n                            case \"&\": return args[0];\n                            case \"`\": return args[args.length - 1].slice(0, args[args.length - 2]);\n                            case \"'\": return args[args.length - 1].slice(args[args.length - 2] + args[0].length);\n                            // Numbered backreference\n                            default:\n                                // What does \"$10\" mean?\n                                // - Backreference 10, if 10 or more capturing groups exist\n                                // - Backreference 1 followed by \"0\", if 1-9 capturing groups exist\n                                // - Otherwise, it's the string \"$10\"\n                                // Also note:\n                                // - Backreferences cannot be more than two digits (enforced by `replacementToken`)\n                                // - \"$01\" is equivalent to \"$1\" if a capturing group exists, otherwise it's the string \"$01\"\n                                // - There is no \"$0\" token (\"$&\" is the entire match)\n                                var literalNumbers = \"\";\n                                $1 = +$1; // Type conversion; drop leading zero\n                                if (!$1) // `$1` was \"0\" or \"00\"\n                                    return $0;\n                                while ($1 > args.length - 3) {\n                                    literalNumbers = String.prototype.slice.call($1, -1) + literalNumbers;\n                                    $1 = Math.floor($1 / 10); // Drop the last digit\n                                }\n                                return ($1 ? args[$1] || \"\" : \"$\") + literalNumbers;\n                        }\n                    // Named backreference or delimited numbered backreference\n                    } else {\n                        // What does \"${n}\" mean?\n                        // - Backreference to numbered capture n. Two differences from \"$n\":\n                        //   - n can be more than two digits\n                        //   - Backreference 0 is allowed, and is the entire match\n                        // - Backreference to named capture n, if it exists and is not a number overridden by numbered capture\n                        // - Otherwise, it's the string \"${n}\"\n                        var n = +$2; // Type conversion; drop leading zeros\n                        if (n <= args.length - 3)\n                            return args[n];\n                        n = captureNames ? indexOf(captureNames, $2) : -1;\n                        return n > -1 ? args[n + 1] : $0;\n                    }\n                });\n            });\n        }\n\n        if (isRegex) {\n            if (search.global)\n                search.lastIndex = 0; // Fix IE, Safari bug (last tested IE 9.0.5, Safari 5.1.2 on Windows)\n            else\n                search.lastIndex = origLastIndex; // Fix IE, Opera bug (last tested IE 9.0.5, Opera 11.61 on Windows)\n        }\n\n        return result;\n    };\n\n    // A consistent cross-browser, ES3 compliant `split`\n    String.prototype.split = function (s /* separator */, limit) {\n        // If separator `s` is not a regex, use the native `split`\n        if (!XRegExp.isRegExp(s))\n            return nativ.split.apply(this, arguments);\n\n        var str = this + \"\", // Type conversion\n            output = [],\n            lastLastIndex = 0,\n            match, lastLength;\n\n        // Behavior for `limit`: if it's...\n        // - `undefined`: No limit\n        // - `NaN` or zero: Return an empty array\n        // - A positive number: Use `Math.floor(limit)`\n        // - A negative number: No limit\n        // - Other: Type-convert, then use the above rules\n        if (limit === undefined || +limit < 0) {\n            limit = Infinity;\n        } else {\n            limit = Math.floor(+limit);\n            if (!limit)\n                return [];\n        }\n\n        // This is required if not `s.global`, and it avoids needing to set `s.lastIndex` to zero\n        // and restore it to its original value when we're done using the regex\n        s = XRegExp.copyAsGlobal(s);\n\n        while (match = s.exec(str)) { // Run the altered `exec` (required for `lastIndex` fix, etc.)\n            if (s.lastIndex > lastLastIndex) {\n                output.push(str.slice(lastLastIndex, match.index));\n\n                if (match.length > 1 && match.index < str.length)\n                    Array.prototype.push.apply(output, match.slice(1));\n\n                lastLength = match[0].length;\n                lastLastIndex = s.lastIndex;\n\n                if (output.length >= limit)\n                    break;\n            }\n\n            if (s.lastIndex === match.index)\n                s.lastIndex++;\n        }\n\n        if (lastLastIndex === str.length) {\n            if (!nativ.test.call(s, \"\") || lastLength)\n                output.push(\"\");\n        } else {\n            output.push(str.slice(lastLastIndex));\n        }\n\n        return output.length > limit ? output.slice(0, limit) : output;\n    };\n\n\n    //---------------------------------\n    //  Private helper functions\n    //---------------------------------\n\n    // Supporting function for `XRegExp`, `XRegExp.copyAsGlobal`, etc. Returns a copy of a `RegExp`\n    // instance with a fresh `lastIndex` (set to zero), preserving properties required for named\n    // capture. Also allows adding new flags in the process of copying the regex\n    function clone (regex, additionalFlags) {\n        if (!XRegExp.isRegExp(regex))\n            throw TypeError(\"type RegExp expected\");\n        var x = regex._xregexp;\n        regex = XRegExp(regex.source, getNativeFlags(regex) + (additionalFlags || \"\"));\n        if (x) {\n            regex._xregexp = {\n                source: x.source,\n                captureNames: x.captureNames ? x.captureNames.slice(0) : null\n            };\n        }\n        return regex;\n    }\n\n    function getNativeFlags (regex) {\n        return (regex.global     ? \"g\" : \"\") +\n               (regex.ignoreCase ? \"i\" : \"\") +\n               (regex.multiline  ? \"m\" : \"\") +\n               (regex.extended   ? \"x\" : \"\") + // Proposed for ES4; included in AS3\n               (regex.sticky     ? \"y\" : \"\");\n    }\n\n    function runTokens (pattern, index, scope, context) {\n        var i = tokens.length,\n            result, match, t;\n        // Protect against constructing XRegExps within token handler and trigger functions\n        isInsideConstructor = true;\n        // Must reset `isInsideConstructor`, even if a `trigger` or `handler` throws\n        try {\n            while (i--) { // Run in reverse order\n                t = tokens[i];\n                if ((scope & t.scope) && (!t.trigger || t.trigger.call(context))) {\n                    t.pattern.lastIndex = index;\n                    match = t.pattern.exec(pattern); // Running the altered `exec` here allows use of named backreferences, etc.\n                    if (match && match.index === index) {\n                        result = {\n                            output: t.handler.call(context, match, scope),\n                            match: match\n                        };\n                        break;\n                    }\n                }\n            }\n        } catch (err) {\n            throw err;\n        } finally {\n            isInsideConstructor = false;\n        }\n        return result;\n    }\n\n    function indexOf (array, item, from) {\n        if (Array.prototype.indexOf) // Use the native array method if available\n            return array.indexOf(item, from);\n        for (var i = from || 0; i < array.length; i++) {\n            if (array[i] === item)\n                return i;\n        }\n        return -1;\n    }\n\n\n    //---------------------------------\n    //  Built-in tokens\n    //---------------------------------\n\n    // Augment XRegExp's regular expression syntax and flags. Note that when adding tokens, the\n    // third (`scope`) argument defaults to `XRegExp.OUTSIDE_CLASS`\n\n    // Comment pattern: (?# )\n    XRegExp.addToken(\n        /\\(\\?#[^)]*\\)/,\n        function (match) {\n            // Keep tokens separated unless the following token is a quantifier\n            return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? \"\" : \"(?:)\";\n        }\n    );\n\n    // Capturing group (match the opening parenthesis only).\n    // Required for support of named capturing groups\n    XRegExp.addToken(\n        /\\((?!\\?)/,\n        function () {\n            this.captureNames.push(null);\n            return \"(\";\n        }\n    );\n\n    // Named capturing group (match the opening delimiter only): (?<name>\n    XRegExp.addToken(\n        /\\(\\?<([$\\w]+)>/,\n        function (match) {\n            this.captureNames.push(match[1]);\n            this.hasNamedCapture = true;\n            return \"(\";\n        }\n    );\n\n    // Named backreference: \\k<name>\n    XRegExp.addToken(\n        /\\\\k<([\\w$]+)>/,\n        function (match) {\n            var index = indexOf(this.captureNames, match[1]);\n            // Keep backreferences separate from subsequent literal numbers. Preserve back-\n            // references to named groups that are undefined at this point as literal strings\n            return index > -1 ?\n                \"\\\\\" + (index + 1) + (isNaN(match.input.charAt(match.index + match[0].length)) ? \"\" : \"(?:)\") :\n                match[0];\n        }\n    );\n\n    // Empty character class: [] or [^]\n    XRegExp.addToken(\n        /\\[\\^?]/,\n        function (match) {\n            // For cross-browser compatibility with ES3, convert [] to \\b\\B and [^] to [\\s\\S].\n            // (?!) should work like \\b\\B, but is unreliable in Firefox\n            return match[0] === \"[]\" ? \"\\\\b\\\\B\" : \"[\\\\s\\\\S]\";\n        }\n    );\n\n    // Mode modifier at the start of the pattern only, with any combination of flags imsx: (?imsx)\n    // Does not support x(?i), (?-i), (?i-m), (?i: ), (?i)(?m), etc.\n    XRegExp.addToken(\n        /^\\(\\?([imsx]+)\\)/,\n        function (match) {\n            this.setFlag(match[1]);\n            return \"\";\n        }\n    );\n\n    // Whitespace and comments, in free-spacing (aka extended) mode only\n    XRegExp.addToken(\n        /(?:\\s+|#.*)+/,\n        function (match) {\n            // Keep tokens separated unless the following token is a quantifier\n            return nativ.test.call(quantifier, match.input.slice(match.index + match[0].length)) ? \"\" : \"(?:)\";\n        },\n        XRegExp.OUTSIDE_CLASS,\n        function () {return this.hasFlag(\"x\");}\n    );\n\n    // Dot, in dotall (aka singleline) mode only\n    XRegExp.addToken(\n        /\\./,\n        function () {return \"[\\\\s\\\\S]\";},\n        XRegExp.OUTSIDE_CLASS,\n        function () {return this.hasFlag(\"s\");}\n    );\n\n\n    //---------------------------------\n    //  Backward compatibility\n    //---------------------------------\n\n    // Uncomment the following block for compatibility with XRegExp 1.0-1.2:\n    /*\n    XRegExp.matchWithinChain = XRegExp.matchChain;\n    RegExp.prototype.addFlags = function (s) {return clone(this, s);};\n    RegExp.prototype.execAll = function (s) {var r = []; XRegExp.iterate(s, this, function (m) {r.push(m);}); return r;};\n    RegExp.prototype.forEachExec = function (s, f, c) {return XRegExp.iterate(s, this, f, c);};\n    RegExp.prototype.validate = function (s) {var r = RegExp(\"^(?:\" + this.source + \")$(?!\\\\s)\", getNativeFlags(this)); if (this.global) this.lastIndex = 0; return s.search(r) === 0;};\n    */\n\n})();\n\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/scripts/shAutoloader.js",
    "content": "(function() {\n\nvar sh = SyntaxHighlighter;\n\n/**\n * Provides functionality to dynamically load only the brushes that a needed to render the current page.\n *\n * There are two syntaxes that autoload understands. For example:\n *\n * SyntaxHighlighter.autoloader(\n *     [ 'applescript',          'Scripts/shBrushAppleScript.js' ],\n *     [ 'actionscript3', 'as3', 'Scripts/shBrushAS3.js' ]\n * );\n *\n * or a more easily comprehendable one:\n *\n * SyntaxHighlighter.autoloader(\n *     'applescript       Scripts/shBrushAppleScript.js',\n *     'actionscript3 as3 Scripts/shBrushAS3.js'\n * );\n */\nsh.autoloader = function()\n{\n\tvar list = arguments,\n\t\telements = sh.findElements(),\n\t\tbrushes = {},\n\t\tscripts = {},\n\t\tall = SyntaxHighlighter.all,\n\t\tallCalled = false,\n\t\tallParams = null,\n\t\ti\n\t\t;\n\n\tSyntaxHighlighter.all = function(params)\n\t{\n\t\tallParams = params;\n\t\tallCalled = true;\n\t};\n\n\tfunction addBrush(aliases, url)\n\t{\n\t\tfor (var i = 0; i < aliases.length; i++)\n\t\t\tbrushes[aliases[i]] = url;\n\t};\n\n\tfunction getAliases(item)\n\t{\n\t\treturn item.pop\n\t\t\t? item\n\t\t\t: item.split(/\\s+/)\n\t\t\t;\n\t}\n\n\t// create table of aliases and script urls\n\tfor (i = 0; i < list.length; i++)\n\t{\n\t\tvar aliases = getAliases(list[i]),\n\t\t\turl = aliases.pop()\n\t\t\t;\n\n\t\taddBrush(aliases, url);\n\t}\n\n\t// dynamically add <script /> tags to the document body\n\tfor (i = 0; i < elements.length; i++)\n\t{\n\t\tvar url = brushes[elements[i].params.brush];\n\n\t\tif(url && scripts[url] === undefined)\n\t\t{\n\t\t\tif(elements[i].params['html-script'] === 'true')\n\t\t\t{\n\t\t\t\tif(scripts[brushes['xml']] === undefined) {\n\t\t\t\t\tloadScript(brushes['xml']);\n\t\t\t\t\tscripts[url] = false;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tscripts[url] = false;\n\t\t\tloadScript(url);\n\t\t}\n\t}\n\n\tfunction loadScript(url)\n\t{\n\t\tvar script = document.createElement('script'),\n\t\t\tdone = false\n\t\t\t;\n\n\t\tscript.src = url;\n\t\tscript.type = 'text/javascript';\n\t\tscript.language = 'javascript';\n\t\tscript.onload = script.onreadystatechange = function()\n\t\t{\n\t\t\tif (!done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete'))\n\t\t\t{\n\t\t\t\tdone = true;\n\t\t\t\tscripts[url] = true;\n\t\t\t\tcheckAll();\n\n\t\t\t\t// Handle memory leak in IE\n\t\t\t\tscript.onload = script.onreadystatechange = null;\n\t\t\t\tscript.parentNode.removeChild(script);\n\t\t\t}\n\t\t};\n\n\t\t// sync way of adding script tags to the page\n\t\tdocument.body.appendChild(script);\n\t};\n\n\tfunction checkAll()\n\t{\n\t\tfor(var url in scripts)\n\t\t\tif (scripts[url] == false)\n\t\t\t\treturn;\n\n\t\tif (allCalled)\n\t\t\tSyntaxHighlighter.highlight(allParams);\n\t};\n};\n\n})();\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/scripts/shBrushPhp.js",
    "content": ";(function()\n{\n\t// CommonJS\n\tSyntaxHighlighter = SyntaxHighlighter || (typeof require !== 'undefined'? require('shCore').SyntaxHighlighter : null);\n\n\tfunction Brush()\n\t{\n\t\tvar funcs\t=\t'abs acos acosh addcslashes addslashes ' +\n\t\t\t\t\t\t'array_change_key_case array_chunk array_combine array_count_values array_diff '+\n\t\t\t\t\t\t'array_diff_assoc array_diff_key array_diff_uassoc array_diff_ukey array_fill '+\n\t\t\t\t\t\t'array_filter array_flip array_intersect array_intersect_assoc array_intersect_key '+\n\t\t\t\t\t\t'array_intersect_uassoc array_intersect_ukey array_key_exists array_keys array_map '+\n\t\t\t\t\t\t'array_merge array_merge_recursive array_multisort array_pad array_pop array_product '+\n\t\t\t\t\t\t'array_push array_rand array_reduce array_reverse array_search array_shift '+\n\t\t\t\t\t\t'array_slice array_splice array_sum array_udiff array_udiff_assoc '+\n\t\t\t\t\t\t'array_udiff_uassoc array_uintersect array_uintersect_assoc '+\n\t\t\t\t\t\t'array_uintersect_uassoc array_unique array_unshift array_values array_walk '+\n\t\t\t\t\t\t'array_walk_recursive atan atan2 atanh base64_decode base64_encode base_convert '+\n\t\t\t\t\t\t'basename bcadd bccomp bcdiv bcmod bcmul bindec bindtextdomain bzclose bzcompress '+\n\t\t\t\t\t\t'bzdecompress bzerrno bzerror bzerrstr bzflush bzopen bzread bzwrite ceil chdir '+\n\t\t\t\t\t\t'checkdate checkdnsrr chgrp chmod chop chown chr chroot chunk_split class_exists '+\n\t\t\t\t\t\t'closedir closelog copy cos cosh count count_chars date decbin dechex decoct '+\n\t\t\t\t\t\t'deg2rad delete ebcdic2ascii echo empty end ereg ereg_replace eregi eregi_replace error_log '+\n\t\t\t\t\t\t'error_reporting escapeshellarg escapeshellcmd eval exec exit exp explode extension_loaded '+\n\t\t\t\t\t\t'feof fflush fgetc fgetcsv fgets fgetss file_exists file_get_contents file_put_contents '+\n\t\t\t\t\t\t'fileatime filectime filegroup fileinode filemtime fileowner fileperms filesize filetype '+\n\t\t\t\t\t\t'floatval flock floor flush fmod fnmatch fopen fpassthru fprintf fputcsv fputs fread fscanf '+\n\t\t\t\t\t\t'fseek fsockopen fstat ftell ftok getallheaders getcwd getdate getenv gethostbyaddr gethostbyname '+\n\t\t\t\t\t\t'gethostbynamel getimagesize getlastmod getmxrr getmygid getmyinode getmypid getmyuid getopt '+\n\t\t\t\t\t\t'getprotobyname getprotobynumber getrandmax getrusage getservbyname getservbyport gettext '+\n\t\t\t\t\t\t'gettimeofday gettype glob gmdate gmmktime ini_alter ini_get ini_get_all ini_restore ini_set '+\n\t\t\t\t\t\t'interface_exists intval ip2long is_a is_array is_bool is_callable is_dir is_double '+\n\t\t\t\t\t\t'is_executable is_file is_finite is_float is_infinite is_int is_integer is_link is_long '+\n\t\t\t\t\t\t'is_nan is_null is_numeric is_object is_readable is_real is_resource is_scalar is_soap_fault '+\n\t\t\t\t\t\t'is_string is_subclass_of is_uploaded_file is_writable is_writeable mkdir mktime nl2br '+\n\t\t\t\t\t\t'parse_ini_file parse_str parse_url passthru pathinfo print readlink realpath rewind rewinddir rmdir '+\n\t\t\t\t\t\t'round str_ireplace str_pad str_repeat str_replace str_rot13 str_shuffle str_split '+\n\t\t\t\t\t\t'str_word_count strcasecmp strchr strcmp strcoll strcspn strftime strip_tags stripcslashes '+\n\t\t\t\t\t\t'stripos stripslashes stristr strlen strnatcasecmp strnatcmp strncasecmp strncmp strpbrk '+\n\t\t\t\t\t\t'strpos strptime strrchr strrev strripos strrpos strspn strstr strtok strtolower strtotime '+\n\t\t\t\t\t\t'strtoupper strtr strval substr substr_compare';\n\n\t\tvar keywords =\t'abstract and array as break case catch cfunction class clone const continue declare default die do ' +\n\t\t\t\t\t\t'else elseif enddeclare endfor endforeach endif endswitch endwhile extends final for foreach ' +\n\t\t\t\t\t\t'function global goto if implements include include_once interface instanceof insteadof namespace new ' +\n\t\t\t\t\t\t'old_function or private protected public return require require_once static switch ' +\n\t\t\t\t\t\t'trait throw try use var while xor ';\n\t\t\n\t\tvar constants\t= '__FILE__ __LINE__ __METHOD__ __FUNCTION__ __CLASS__';\n\n\t\tthis.regexList = [\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleLineCComments,\tcss: 'comments' },\t\t\t// one line comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.multiLineCComments,\t\tcss: 'comments' },\t\t\t// multiline comments\n\t\t\t{ regex: SyntaxHighlighter.regexLib.doubleQuotedString,\t\tcss: 'string' },\t\t\t// double quoted strings\n\t\t\t{ regex: SyntaxHighlighter.regexLib.singleQuotedString,\t\tcss: 'string' },\t\t\t// single quoted strings\n\t\t\t{ regex: /\\$\\w+/g,\t\t\t\t\t\t\t\t\t\t\tcss: 'variable' },\t\t\t// variables\n\t\t\t{ regex: new RegExp(this.getKeywords(funcs), 'gmi'),\t\tcss: 'functions' },\t\t\t// common functions\n\t\t\t{ regex: new RegExp(this.getKeywords(constants), 'gmi'),\tcss: 'constants' },\t\t\t// constants\n\t\t\t{ regex: new RegExp(this.getKeywords(keywords), 'gm'),\t\tcss: 'keyword' }\t\t\t// keyword\n\t\t\t];\n\n\t\tthis.forHtmlScript(SyntaxHighlighter.regexLib.phpScriptTags);\n\t};\n\n\tBrush.prototype\t= new SyntaxHighlighter.Highlighter();\n\tBrush.aliases\t= ['php'];\n\n\tSyntaxHighlighter.brushes.Php = Brush;\n\n\t// CommonJS\n\ttypeof(exports) != 'undefined' ? exports.Brush = Brush : null;\n})();\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/scripts/shCore.js",
    "content": "var XRegExp;if(XRegExp)throw Error(\"can't load XRegExp twice in the same frame\");(function(e){function c(e,t){if(!XRegExp.isRegExp(e))throw TypeError(\"type RegExp expected\");var n=e._xregexp;return e=XRegExp(e.source,h(e)+(t||\"\")),n&&(e._xregexp={source:n.source,captureNames:n.captureNames?n.captureNames.slice(0):null}),e}function h(e){return(e.global?\"g\":\"\")+(e.ignoreCase?\"i\":\"\")+(e.multiline?\"m\":\"\")+(e.extended?\"x\":\"\")+(e.sticky?\"y\":\"\")}function p(e,t,n,r){var o=s.length,u,a,f;i=!0;try{while(o--){f=s[o];if(n&f.scope&&(!f.trigger||f.trigger.call(r))){f.pattern.lastIndex=t,a=f.pattern.exec(e);if(a&&a.index===t){u={output:f.handler.call(r,a,n),match:a};break}}}}catch(l){throw l}finally{i=!1}return u}function d(e,t,n){if(Array.prototype.indexOf)return e.indexOf(t,n);for(var r=n||0;r<e.length;r++)if(e[r]===t)return r;return-1}XRegExp=function(t,r){var s=[],u=XRegExp.OUTSIDE_CLASS,a=0,f,h,d,v,m;if(XRegExp.isRegExp(t)){if(r!==e)throw TypeError(\"can't supply flags when constructing one RegExp from another\");return c(t)}if(i)throw Error(\"can't call the XRegExp constructor within token definition functions\");r=r||\"\",f={hasNamedCapture:!1,captureNames:[],hasFlag:function(e){return r.indexOf(e)>-1},setFlag:function(e){r+=e}};while(a<t.length)h=p(t,a,u,f),h?(s.push(h.output),a+=h.match[0].length||1):(d=o.exec.call(l[u],t.slice(a)))?(s.push(d[0]),a+=d[0].length):(v=t.charAt(a),v===\"[\"?u=XRegExp.INSIDE_CLASS:v===\"]\"&&(u=XRegExp.OUTSIDE_CLASS),s.push(v),a++);return m=RegExp(s.join(\"\"),o.replace.call(r,n,\"\")),m._xregexp={source:t,captureNames:f.hasNamedCapture?f.captureNames:null},m},XRegExp.version=\"1.5.1\",XRegExp.INSIDE_CLASS=1,XRegExp.OUTSIDE_CLASS=2;var t=/\\$(?:(\\d\\d?|[$&`'])|{([$\\w]+)})/g,n=/[^gimy]+|([\\s\\S])(?=[\\s\\S]*\\1)/g,r=/^(?:[?*+]|{\\d+(?:,\\d*)?})\\??/,i=!1,s=[],o={exec:RegExp.prototype.exec,test:RegExp.prototype.test,match:String.prototype.match,replace:String.prototype.replace,split:String.prototype.split},u=o.exec.call(/()??/,\"\")[1]===e,a=function(){var e=/^/g;return o.test.call(e,\"\"),!e.lastIndex}(),f=RegExp.prototype.sticky!==e,l={};l[XRegExp.INSIDE_CLASS]=/^(?:\\\\(?:[0-3][0-7]{0,2}|[4-7][0-7]?|x[\\dA-Fa-f]{2}|u[\\dA-Fa-f]{4}|c[A-Za-z]|[\\s\\S]))/,l[XRegExp.OUTSIDE_CLASS]=/^(?:\\\\(?:0(?:[0-3][0-7]{0,2}|[4-7][0-7]?)?|[1-9]\\d*|x[\\dA-Fa-f]{2}|u[\\dA-Fa-f]{4}|c[A-Za-z]|[\\s\\S])|\\(\\?[:=!]|[?*+]\\?|{\\d+(?:,\\d*)?}\\??)/,XRegExp.addToken=function(e,t,n,r){s.push({pattern:c(e,\"g\"+(f?\"y\":\"\")),handler:t,scope:n||XRegExp.OUTSIDE_CLASS,trigger:r||null})},XRegExp.cache=function(e,t){var n=e+\"/\"+(t||\"\");return XRegExp.cache[n]||(XRegExp.cache[n]=XRegExp(e,t))},XRegExp.copyAsGlobal=function(e){return c(e,\"g\")},XRegExp.escape=function(e){return e.replace(/[-[\\]{}()*+?.,\\\\^$|#\\s]/g,\"\\\\$&\")},XRegExp.execAt=function(e,t,n,r){var i=c(t,\"g\"+(r&&f?\"y\":\"\")),s;return i.lastIndex=n=n||0,s=i.exec(e),r&&s&&s.index!==n&&(s=null),t.global&&(t.lastIndex=s?i.lastIndex:0),s},XRegExp.freezeTokens=function(){XRegExp.addToken=function(){throw Error(\"can't run addToken after freezeTokens\")}},XRegExp.isRegExp=function(e){return Object.prototype.toString.call(e)===\"[object RegExp]\"},XRegExp.iterate=function(e,t,n,r){var i=c(t,\"g\"),s=-1,o;while(o=i.exec(e))t.global&&(t.lastIndex=i.lastIndex),n.call(r,o,++s,e,t),i.lastIndex===o.index&&i.lastIndex++;t.global&&(t.lastIndex=0)},XRegExp.matchChain=function(e,t){return function n(e,r){var i=t[r].regex?t[r]:{regex:t[r]},s=c(i.regex,\"g\"),o=[],u;for(u=0;u<e.length;u++)XRegExp.iterate(e[u],s,function(e){o.push(i.backref?e[i.backref]||\"\":e[0])});return r===t.length-1||!o.length?o:n(o,r+1)}([e],0)},RegExp.prototype.apply=function(e,t){return this.exec(t[0])},RegExp.prototype.call=function(e,t){return this.exec(t)},RegExp.prototype.exec=function(t){var n,r,i,s;this.global||(s=this.lastIndex),n=o.exec.apply(this,arguments);if(n){!u&&n.length>1&&d(n,\"\")>-1&&(i=RegExp(this.source,o.replace.call(h(this),\"g\",\"\")),o.replace.call((t+\"\").slice(n.index),i,function(){for(var t=1;t<arguments.length-2;t++)arguments[t]===e&&(n[t]=e)}));if(this._xregexp&&this._xregexp.captureNames)for(var f=1;f<n.length;f++)r=this._xregexp.captureNames[f-1],r&&(n[r]=n[f]);!a&&this.global&&!n[0].length&&this.lastIndex>n.index&&this.lastIndex--}return this.global||(this.lastIndex=s),n},RegExp.prototype.test=function(e){var t,n;return this.global||(n=this.lastIndex),t=o.exec.call(this,e),t&&!a&&this.global&&!t[0].length&&this.lastIndex>t.index&&this.lastIndex--,this.global||(this.lastIndex=n),!!t},String.prototype.match=function(e){XRegExp.isRegExp(e)||(e=RegExp(e));if(e.global){var t=o.match.apply(this,arguments);return e.lastIndex=0,t}return e.exec(this)},String.prototype.replace=function(e,n){var r=XRegExp.isRegExp(e),i,s,u,a;return r?(e._xregexp&&(i=e._xregexp.captureNames),e.global||(a=e.lastIndex)):e+=\"\",Object.prototype.toString.call(n)===\"[object Function]\"?s=o.replace.call(this+\"\",e,function(){if(i){arguments[0]=new String(arguments[0]);for(var t=0;t<i.length;t++)i[t]&&(arguments[0][i[t]]=arguments[t+1])}return r&&e.global&&(e.lastIndex=arguments[arguments.length-2]+arguments[0].length),n.apply(null,arguments)}):(u=this+\"\",s=o.replace.call(u,e,function(){var e=arguments;return o.replace.call(n+\"\",t,function(t,n,r){if(!n){var o=+r;return o<=e.length-3?e[o]:(o=i?d(i,r):-1,o>-1?e[o+1]:t)}switch(n){case\"$\":return\"$\";case\"&\":return e[0];case\"`\":return e[e.length-1].slice(0,e[e.length-2]);case\"'\":return e[e.length-1].slice(e[e.length-2]+e[0].length);default:var s=\"\";n=+n;if(!n)return t;while(n>e.length-3)s=String.prototype.slice.call(n,-1)+s,n=Math.floor(n/10);return(n?e[n]||\"\":\"$\")+s}})})),r&&(e.global?e.lastIndex=0:e.lastIndex=a),s},String.prototype.split=function(t,n){if(!XRegExp.isRegExp(t))return o.split.apply(this,arguments);var r=this+\"\",i=[],s=0,u,a;if(n===e||+n<0)n=Infinity;else{n=Math.floor(+n);if(!n)return[]}t=XRegExp.copyAsGlobal(t);while(u=t.exec(r)){if(t.lastIndex>s){i.push(r.slice(s,u.index)),u.length>1&&u.index<r.length&&Array.prototype.push.apply(i,u.slice(1)),a=u[0].length,s=t.lastIndex;if(i.length>=n)break}t.lastIndex===u.index&&t.lastIndex++}return s===r.length?(!o.test.call(t,\"\")||a)&&i.push(\"\"):i.push(r.slice(s)),i.length>n?i.slice(0,n):i},XRegExp.addToken(/\\(\\?#[^)]*\\)/,function(e){return o.test.call(r,e.input.slice(e.index+e[0].length))?\"\":\"(?:)\"}),XRegExp.addToken(/\\((?!\\?)/,function(){return this.captureNames.push(null),\"(\"}),XRegExp.addToken(/\\(\\?<([$\\w]+)>/,function(e){return this.captureNames.push(e[1]),this.hasNamedCapture=!0,\"(\"}),XRegExp.addToken(/\\\\k<([\\w$]+)>/,function(e){var t=d(this.captureNames,e[1]);return t>-1?\"\\\\\"+(t+1)+(isNaN(e.input.charAt(e.index+e[0].length))?\"\":\"(?:)\"):e[0]}),XRegExp.addToken(/\\[\\^?]/,function(e){return e[0]===\"[]\"?\"\\\\b\\\\B\":\"[\\\\s\\\\S]\"}),XRegExp.addToken(/^\\(\\?([imsx]+)\\)/,function(e){return this.setFlag(e[1]),\"\"}),XRegExp.addToken(/(?:\\s+|#.*)+/,function(e){return o.test.call(r,e.input.slice(e.index+e[0].length))?\"\":\"(?:)\"},XRegExp.OUTSIDE_CLASS,function(){return this.hasFlag(\"x\")}),XRegExp.addToken(/\\./,function(){return\"[\\\\s\\\\S]\"},XRegExp.OUTSIDE_CLASS,function(){return this.hasFlag(\"s\")})})();if(typeof SyntaxHighlighter==\"undefined\")var SyntaxHighlighter=function(){function t(e,t){return e.className.indexOf(t)!=-1}function n(e,n){t(e,n)||(e.className+=\" \"+n)}function r(e,t){e.className=e.className.replace(t,\"\")}function i(e){var t=[];for(var n=0;n<e.length;n++)t.push(e[n]);return t}function s(e){return e.split(/\\r?\\n/)}function o(e){var t=\"highlighter_\";return e.indexOf(t)==0?e:t+e}function u(t){return e.vars.highlighters[o(t)]}function a(e){return document.getElementById(o(e))}function f(t){e.vars.highlighters[o(t.id)]=t}function l(e,t,n){if(e==null)return null;var r=n!=1?e.childNodes:[e.parentNode],i={\"#\":\"id\",\".\":\"className\"}[t.substr(0,1)]||\"nodeName\",s,o;s=i!=\"nodeName\"?t.substr(1):t.toUpperCase();if((e[i]||\"\").indexOf(s)!=-1)return e;for(var u=0;r&&u<r.length&&o==null;u++)o=l(r[u],t,n);return o}function c(e,t){return l(e,t,!0)}function h(e,t,n){n=Math.max(n||0,0);for(var r=n;r<e.length;r++)if(e[r]==t)return r;return-1}function p(e){return(e||\"\")+Math.round(Math.random()*1e6).toString()}function d(e,t){var n={},r;for(r in e)n[r]=e[r];for(r in t)n[r]=t[r];return n}function v(e){var t={\"true\":!0,\"false\":!1}[e];return t==null?e:t}function m(e,t,n,r,i){var s=(screen.width-n)/2,o=(screen.height-r)/2;i+=\", left=\"+s+\", top=\"+o+\", width=\"+n+\", height=\"+r,i=i.replace(/^,/,\"\");var u=window.open(e,t,i);return u.focus(),u}function g(e,t,n,r){function i(e){e=e||window.event,e.target||(e.target=e.srcElement,e.preventDefault=function(){this.returnValue=!1}),n.call(r||window,e)}e.attachEvent?e.attachEvent(\"on\"+t,i):e.addEventListener(t,i,!1)}function y(t){window.alert(e.config.strings.alert+t)}function b(t,n){var r=e.vars.discoveredBrushes,i=null;if(r==null){r={};for(var s in e.brushes){var o=e.brushes[s],u=o.aliases;if(u==null)continue;o.brushName=s.toLowerCase();for(var a=0;a<u.length;a++)r[u[a]]=s}e.vars.discoveredBrushes=r}return i=e.brushes[r[t]],i==null&&n&&y(e.config.strings.noBrush+t),i}function w(e,t){var n=s(e);for(var r=0;r<n.length;r++)n[r]=t(n[r],r);return n.join(\"\\r\\n\")}function E(e){return e.replace(/^[ ]*[\\n]+|[\\n]*[ ]*$/g,\"\")}function S(e){var t,n={},r=new XRegExp(\"^\\\\[(?<values>(.*?))\\\\]$\"),i=new XRegExp(\"(?<name>[\\\\w-]+)\\\\s*:\\\\s*(?<value>[\\\\w-%#]+|\\\\[.*?\\\\]|\\\".*?\\\"|'.*?')\\\\s*;?\",\"g\");while((t=i.exec(e))!=null){var s=t.value.replace(/^['\"]|['\"]$/g,\"\");if(s!=null&&r.test(s)){var o=r.exec(s);s=o.values.length>0?o.values.split(/\\s*,\\s*/):[]}n[t.name]=s}return n}function x(t,n){return t==null||t.length==0||t==\"\\n\"?t:(t=t.replace(/</g,\"&lt;\"),t=t.replace(/ {2,}/g,function(t){var n=\"\";for(var r=0;r<t.length-1;r++)n+=e.config.space;return n+\" \"}),n!=null&&(t=w(t,function(e){if(e.length==0)return\"\";var t=\"\";return e=e.replace(/^(&nbsp;| )+/,function(e){return t=e,\"\"}),e.length==0?t:t+'<code class=\"'+n+'\">'+e+\"</code>\"})),t)}function T(e,t){var n=e.toString();while(n.length<t)n=\"0\"+n;return n}function N(e,t){var n=\"\";for(var r=0;r<t;r++)n+=\" \";return e.replace(/\\t/g,n)}function C(e,t){function u(e,t,n){return e.substr(0,t)+i.substr(0,n)+e.substr(t+1,e.length)}var n=s(e),r=\"\t\",i=\"\";for(var o=0;o<50;o++)i+=\"                    \";return e=w(e,function(e){if(e.indexOf(r)==-1)return e;var n=0;while((n=e.indexOf(r))!=-1){var i=t-n%t;e=u(e,n,i)}return e}),e}function k(t){var n=/<br\\s*\\/?>|&lt;br\\s*\\/?&gt;/gi;return e.config.bloggerMode==1&&(t=t.replace(n,\"\\n\")),e.config.stripBrs==1&&(t=t.replace(n,\"\")),t}function L(e){return e.replace(/^\\s+|\\s+$/g,\"\")}function A(e){var t=s(k(e)),n=new Array,r=/^\\s*/,i=1e3;for(var o=0;o<t.length&&i>0;o++){var u=t[o];if(L(u).length==0)continue;var a=r.exec(u);if(a==null)return e;i=Math.min(a[0].length,i)}if(i>0)for(var o=0;o<t.length;o++)t[o]=t[o].substr(i);return t.join(\"\\n\")}function O(e,t){return e.index<t.index?-1:e.index>t.index?1:e.length<t.length?-1:e.length>t.length?1:0}function M(t,n){function r(e,t){return e[0]}var i=0,s=null,o=[],u=n.func?n.func:r;while((s=n.regex.exec(t))!=null){var a=u(s,n);typeof a==\"string\"&&(a=[new e.Match(a,s.index,n.css)]),o=o.concat(a)}return o}function _(t){var n=/(.*)((&gt;|&lt;).*)/;return t.replace(e.regexLib.url,function(e){var t=\"\",r=null;if(r=n.exec(e))e=r[1],t=r[2];return'<a href=\"'+e+'\">'+e+\"</a>\"+t})}function D(){var e=document.getElementsByTagName(\"script\"),t=[];for(var n=0;n<e.length;n++)e[n].type==\"syntaxhighlighter\"&&t.push(e[n]);return t}function P(e){var t=\"<![CDATA[\",n=\"]]>\",r=L(e),i=!1,s=t.length,o=n.length;r.indexOf(t)==0&&(r=r.substring(s),i=!0);var u=r.length;return r.indexOf(n)==u-o&&(r=r.substring(0,u-o),i=!0),i?r:e}function H(e){var t=e.target,i=c(t,\".syntaxhighlighter\"),s=c(t,\".container\"),o=document.createElement(\"textarea\"),a;if(!s||!i||l(s,\"textarea\"))return;a=u(i.id),n(i,\"source\");var f=s.childNodes,h=[];for(var p=0;p<f.length;p++)h.push(f[p].innerText||f[p].textContent);h=h.join(\"\\r\"),h=h.replace(/\\u00a0/g,\" \"),o.appendChild(document.createTextNode(h)),s.appendChild(o),o.focus(),o.select(),g(o,\"blur\",function(e){o.parentNode.removeChild(o),r(i,\"source\")})}typeof require!=\"undefined\"&&typeof XRegExp==\"undefined\"&&(XRegExp=require(\"XRegExp\").XRegExp);var e={defaults:{\"class-name\":\"\",\"first-line\":1,\"pad-line-numbers\":!1,highlight:null,title:null,\"smart-tabs\":!0,\"tab-size\":4,gutter:!0,toolbar:!0,\"quick-code\":!0,collapse:!1,\"auto-links\":!0,light:!1,unindent:!0,\"html-script\":!1},config:{space:\"&nbsp;\",useScriptTags:!0,bloggerMode:!1,stripBrs:!1,tagName:\"pre\",strings:{expandSource:\"expand source\",help:\"?\",alert:\"SyntaxHighlighter\\n\\n\",noBrush:\"Can't find brush for: \",brushNotHtmlScript:\"Brush wasn't configured for html-script option: \",aboutDialog:\"@ABOUT@\"}},vars:{discoveredBrushes:null,highlighters:{}},brushes:{},regexLib:{multiLineCComments:/\\/\\*[\\s\\S]*?\\*\\//gm,singleLineCComments:/\\/\\/.*$/gm,singleLinePerlComments:/#.*$/gm,doubleQuotedString:/\"([^\\\\\"\\n]|\\\\.)*\"/g,singleQuotedString:/'([^\\\\'\\n]|\\\\.)*'/g,multiLineDoubleQuotedString:new XRegExp('\"([^\\\\\\\\\"]|\\\\\\\\.)*\"',\"gs\"),multiLineSingleQuotedString:new XRegExp(\"'([^\\\\\\\\']|\\\\\\\\.)*'\",\"gs\"),xmlComments:/(&lt;|<)!--[\\s\\S]*?--(&gt;|>)/gm,url:/\\w+:\\/\\/[\\w-.\\/?%&=:@;#]*/g,phpScriptTags:{left:/(&lt;|<)\\?(?:=|php)?/g,right:/\\?(&gt;|>)/g,eof:!0},aspScriptTags:{left:/(&lt;|<)%=?/g,right:/%(&gt;|>)/g},scriptScriptTags:{left:/(&lt;|<)\\s*script.*?(&gt;|>)/gi,right:/(&lt;|<)\\/\\s*script\\s*(&gt;|>)/gi}},toolbar:{getHtml:function(t){function s(t,n){return e.toolbar.getButtonHtml(t,n,e.config.strings[n])}var n='<div class=\"toolbar\">',r=e.toolbar.items,i=r.list;for(var o=0;o<i.length;o++)n+=(r[i[o]].getHtml||s)(t,i[o]);return n+=\"</div>\",n},getButtonHtml:function(e,t,n){return'<span><a href=\"#\" class=\"toolbar_item command_'+t+\" \"+t+'\">'+n+\"</a></span>\"},handler:function(t){function i(e){var t=new RegExp(e+\"_(\\\\w+)\"),n=t.exec(r);return n?n[1]:null}var n=t.target,r=n.className||\"\",s=u(c(n,\".syntaxhighlighter\").id),o=i(\"command\");s&&o&&e.toolbar.items[o].execute(s),t.preventDefault()},items:{list:[\"expandSource\",\"help\"],expandSource:{getHtml:function(t){if(t.getParam(\"collapse\")!=1)return\"\";var n=t.getParam(\"title\");return e.toolbar.getButtonHtml(t,\"expandSource\",n?n:e.config.strings.expandSource)},execute:function(e){var t=a(e.id);r(t,\"collapsed\")}},help:{execute:function(t){var n=m(\"\",\"_blank\",500,250,\"scrollbars=0\"),r=n.document;r.write(e.config.strings.aboutDialog),r.close(),n.focus()}}}},findElements:function(t,n){var r=n?[n]:i(document.getElementsByTagName(e.config.tagName)),s=e.config,o=[];s.useScriptTags&&(r=r.concat(D()));if(r.length===0)return o;for(var u=0;u<r.length;u++){var a={target:r[u],params:d(t,S(r[u].className))};if(a.params[\"brush\"]==null)continue;o.push(a)}return o},highlight:function(t,n){var r=this.findElements(t,n),i=\"innerHTML\",s=null,o=e.config;if(r.length===0)return;for(var u=0;u<r.length;u++){var n=r[u],a=n.target,f=n.params,l=f.brush,c;if(l==null)continue;if(f[\"html-script\"]==\"true\"||e.defaults[\"html-script\"]==1)s=new e.HtmlScript(l),l=\"htmlscript\";else{var h=b(l);if(!h)continue;s=new h}c=a[i],o.useScriptTags&&(c=P(c)),(a.title||\"\")!=\"\"&&(f.title=a.title),f.brush=l,s.init(f),n=s.getDiv(c),(a.id||\"\")!=\"\"&&(n.id=a.id),a.parentNode.replaceChild(n,a)}},all:function(t){g(window,\"load\",function(){e.highlight(t)})}};return e.Match=function(e,t,n){this.value=e,this.index=t,this.length=e.length,this.css=n,this.brushName=null},e.Match.prototype.toString=function(){return this.value},e.HtmlScript=function(t){function f(e,t){for(var n=0;n<e.length;n++)e[n].index+=t}function l(e,t){var i=e.code,s=[],o=r.regexList,u=e.index+e.left.length,a=r.htmlScript,l;for(var c=0;c<o.length;c++)l=M(i,o[c]),f(l,u),s=s.concat(l);a.left!=null&&e.left!=null&&(l=M(e.left,a.left),f(l,e.index),s=s.concat(l)),a.right!=null&&e.right!=null&&(l=M(e.right,a.right),f(l,e.index+e[0].lastIndexOf(e.right)),s=s.concat(l));for(var h=0;h<s.length;h++)s[h].brushName=n.brushName;return s}var n=b(t),r,i=new e.brushes.Xml,s=null,o=this,u=\"getDiv getHtml init\".split(\" \");if(n==null)return;r=new n;for(var a=0;a<u.length;a++)(function(){var e=u[a];o[e]=function(){return i[e].apply(i,arguments)}})();if(r.htmlScript==null){y(e.config.strings.brushNotHtmlScript+t);return}i.regexList.push({regex:r.htmlScript.code,func:l})},e.Highlighter=function(){},e.Highlighter.prototype={getParam:function(e,t){var n=this.params[e];return v(n==null?t:n)},create:function(e){return document.createElement(e)},findMatches:function(e,t){var n=[];if(e!=null)for(var r=0;r<e.length;r++)typeof e[r]==\"object\"&&(n=n.concat(M(t,e[r])));return this.removeNestedMatches(n.sort(O))},removeNestedMatches:function(e){for(var t=0;t<e.length;t++){if(e[t]===null)continue;var n=e[t],r=n.index+n.length;for(var i=t+1;i<e.length&&e[t]!==null;i++){var s=e[i];if(s===null)continue;if(s.index>r)break;s.index==n.index&&s.length>n.length?e[t]=null:s.index>=n.index&&s.index<r&&(e[i]=null)}}return e},figureOutLineNumbers:function(e){var t=[],n=parseInt(this.getParam(\"first-line\"));return w(e,function(e,r){t.push(r+n)}),t},isLineHighlighted:function(e){var t=this.getParam(\"highlight\",[]);return typeof t!=\"object\"&&t.push==null&&(t=[t]),h(t,e.toString())!=-1},getLineHtml:function(e,t,n){var r=[\"line\",\"number\"+t,\"index\"+e,\"alt\"+(t%2==0?1:2).toString()];return this.isLineHighlighted(t)&&r.push(\"highlighted\"),t==0&&r.push(\"break\"),'<div class=\"'+r.join(\" \")+'\">'+n+\"</div>\"},getLineNumbersHtml:function(t,n){var r=\"\",i=s(t).length,o=parseInt(this.getParam(\"first-line\")),u=this.getParam(\"pad-line-numbers\");u==1?u=(o+i-1).toString().length:isNaN(u)==1&&(u=0);for(var a=0;a<i;a++){var f=n?n[a]:o+a,t=f==0?e.config.space:T(f,u);r+=this.getLineHtml(a,f,t)}return r},getCodeLinesHtml:function(t,n){t=L(t);var r=s(t),i=this.getParam(\"pad-line-numbers\"),o=parseInt(this.getParam(\"first-line\")),t=\"\",u=this.getParam(\"brush\");for(var a=0;a<r.length;a++){var f=r[a],l=/^(&nbsp;|\\s)+/.exec(f),c=null,h=n?n[a]:o+a;l!=null&&(c=l[0].toString(),f=f.substr(c.length),c=c.replace(\" \",e.config.space)),f=L(f),f.length==0&&(f=e.config.space),t+=this.getLineHtml(a,h,(c!=null?'<code class=\"'+u+' spaces\">'+c+\"</code>\":\"\")+f)}return t},getTitleHtml:function(e){return e?\"<caption>\"+e+\"</caption>\":\"\"},getMatchesHtml:function(e,t){function s(e){var t=e?e.brushName||i:i;return t?t+\" \":\"\"}var n=0,r=\"\",i=this.getParam(\"brush\",\"\");for(var o=0;o<t.length;o++){var u=t[o],a;if(u===null||u.length===0)continue;a=s(u),r+=x(e.substr(n,u.index-n),a+\"plain\")+x(u.value,a+u.css),n=u.index+u.length+(u.offset||0)}return r+=x(e.substr(n),s()+\"plain\"),r},getHtml:function(t){var n=\"\",r=[\"syntaxhighlighter\"],i,s,u;return this.getParam(\"light\")==1&&(this.params.toolbar=this.params.gutter=!1),className=\"syntaxhighlighter\",this.getParam(\"collapse\")==1&&r.push(\"collapsed\"),(gutter=this.getParam(\"gutter\"))==0&&r.push(\"nogutter\"),r.push(this.getParam(\"class-name\")),r.push(this.getParam(\"brush\")),t=E(t).replace(/\\r/g,\" \"),i=this.getParam(\"tab-size\"),t=this.getParam(\"smart-tabs\")==1?C(t,i):N(t,i),this.getParam(\"unindent\")&&(t=A(t)),gutter&&(u=this.figureOutLineNumbers(t)),s=this.findMatches(this.regexList,t),n=this.getMatchesHtml(t,s),n=this.getCodeLinesHtml(n,u),this.getParam(\"auto-links\")&&(n=_(n)),typeof navigator!=\"undefined\"&&navigator.userAgent&&navigator.userAgent.match(/MSIE/)&&r.push(\"ie\"),n='<div id=\"'+o(this.id)+'\" class=\"'+r.join(\" \")+'\">'+(this.getParam(\"toolbar\")?e.toolbar.getHtml(this):\"\")+'<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">'+this.getTitleHtml(this.getParam(\"title\"))+\"<tbody>\"+\"<tr>\"+(gutter?'<td class=\"gutter\">'+this.getLineNumbersHtml(t)+\"</td>\":\"\")+'<td class=\"code\">'+'<div class=\"container\">'+n+\"</div>\"+\"</td>\"+\"</tr>\"+\"</tbody>\"+\"</table>\"+\"</div>\",n},getDiv:function(t){t===null&&(t=\"\"),this.code=t;var n=this.create(\"div\");return n.innerHTML=this.getHtml(t),this.getParam(\"toolbar\")&&g(l(n,\".toolbar\"),\"click\",e.toolbar.handler),this.getParam(\"quick-code\")&&g(l(n,\".code\"),\"dblclick\",H),n},init:function(t){this.id=p(),f(this),this.params=d(e.defaults,t||{}),this.getParam(\"light\")==1&&(this.params.toolbar=this.params.gutter=!1)},getKeywords:function(e){return e=e.replace(/^\\s+|\\s+$/g,\"\").replace(/\\s+/g,\"|\"),\"\\\\b(?:\"+e+\")\\\\b\"},forHtmlScript:function(e){var t={end:e.right.source};e.eof&&(t.end=\"(?:(?:\"+t.end+\")|$)\"),this.htmlScript={left:{regex:e.left,css:\"script\"},right:{regex:e.right,css:\"script\"},code:new XRegExp(\"(?<left>\"+e.left.source+\")\"+\"(?<code>.*?)\"+\"(?<right>\"+t.end+\")\",\"sgi\")}}},e}();typeof exports!=\"undefined\"?exports.SyntaxHighlighter=SyntaxHighlighter:null"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/scripts/shLegacy.js",
    "content": "var dp = {\n\tSyntaxHighlighter : {}\n};\n\ndp.SyntaxHighlighter = {\n\tparseParams: function(\n\t\t\t\t\t\tinput,\n\t\t\t\t\t\tshowGutter, \n\t\t\t\t\t\tshowControls, \n\t\t\t\t\t\tcollapseAll, \n\t\t\t\t\t\tfirstLine, \n\t\t\t\t\t\tshowColumns\n\t\t\t\t\t\t)\n\t{\n\t\tfunction getValue(list, name)\n\t\t{\n\t\t\tvar regex = new XRegExp('^' + name + '\\\\[(?<value>\\\\w+)\\\\]$', 'gi'),\n\t\t\t\tmatch = null\n\t\t\t\t;\n\t\t\t\n\t\t\tfor (var i = 0; i < list.length; i++) \n\t\t\t\tif ((match = regex.exec(list[i])) != null)\n\t\t\t\t\treturn match.value;\n\t\t\t\n\t\t\treturn null;\n\t\t}\n\t\t\n\t\tfunction defaultValue(value, def)\n\t\t{\n\t\t\treturn value != null ? value : def;\n\t\t}\n\t\t\n\t\tfunction asString(value)\n\t\t{\n\t\t\treturn value != null ? value.toString() : null;\n\t\t}\n\n\t\tvar parts = input.split(':'),\n\t\t\tbrushName = parts[0],\n\t\t\toptions = {},\n\t\t\tstraight = { 'true' : true },\n\t\t\treverse = { 'true' : false },\n\t\t\tdefaults = SyntaxHighlighter.defaults\n\t\t\t;\n\t\t\n\t\tfor (var i in parts)\n\t\t\toptions[parts[i]] = 'true';\n\n\t\tshowGutter = asString(defaultValue(showGutter, defaults.gutter));\n\t\tshowControls = asString(defaultValue(showControls, defaults.toolbar));\n\t\tcollapseAll = asString(defaultValue(collapseAll, defaults.collapse)); \n\t\tshowColumns = asString(defaultValue(showColumns, defaults.ruler));\n\t\tfirstLine = asString(defaultValue(firstLine, defaults['first-line'])); \n\n\t\treturn {\n\t\t\tbrush\t\t\t: brushName,\n\t\t\tgutter\t\t\t: defaultValue(reverse[options.nogutter], showGutter),\n\t\t\ttoolbar\t\t\t: defaultValue(reverse[options.nocontrols], showControls),\n\t\t\tcollapse\t\t: defaultValue(straight[options.collapse], collapseAll),\n\t\t\t// ruler\t\t\t: defaultValue(straight[options.showcolumns], showColumns),\n\t\t\t'first-line'\t: defaultValue(getValue(parts, 'firstline'), firstLine)\n\t\t};\n\t},\n\t\n\tHighlightAll: function(\n\t\t\t\t\t\tname, \n\t\t\t\t\t\tshowGutter /* optional */, \n\t\t\t\t\t\tshowControls /* optional */, \n\t\t\t\t\t\tcollapseAll /* optional */, \n\t\t\t\t\t\tfirstLine /* optional */, \n\t\t\t\t\t\tshowColumns /* optional */\n\t\t\t\t\t\t)\n\t{\n\t\tfunction findValue()\n\t\t{\n\t\t\tvar a = arguments;\n\t\t\t\n\t\t\tfor (var i = 0; i < a.length; i++) \n\t\t\t{\n\t\t\t\tif (a[i] === null) \n\t\t\t\t\tcontinue;\n\t\t\t\t\n\t\t\t\tif (typeof(a[i]) == 'string' && a[i] != '') \n\t\t\t\t\treturn a[i] + '';\n\t\t\t\t\n\t\t\t\tif (typeof(a[i]) == 'object' && a[i].value != '') \n\t\t\t\t\treturn a[i].value + '';\n\t\t\t}\n\t\t\t\n\t\t\treturn null;\n\t\t}\n\n\t\tfunction findTagsByName(list, name, tagName)\n\t\t{\n\t\t\tvar tags = document.getElementsByTagName(tagName);\n\t\t\t\n\t\t\tfor (var i = 0; i < tags.length; i++) \n\t\t\t\tif (tags[i].getAttribute('name') == name) \n\t\t\t\t\tlist.push(tags[i]);\n\t\t}\n\t\t\n\t\tvar elements = [],\n\t\t\thighlighter = null,\n\t\t\tregistered = {},\n\t\t\tpropertyName = 'innerHTML'\n\t\t\t;\n\t\t\n\t\t// for some reason IE doesn't find <pre/> by name, however it does see them just fine by tag name... \n\t\tfindTagsByName(elements, name, 'pre');\n\t\tfindTagsByName(elements, name, 'textarea');\n\n\t\tif (elements.length === 0)\n\t\t\treturn;\n\t\t\n\t\tfor (var i = 0; i < elements.length; i++)\n\t\t{\n\t\t\tvar element = elements[i],\n\t\t\t\tparams = findValue(\n\t\t\t\t\telement.attributes['class'], element.className, \n\t\t\t\t\telement.attributes['language'], element.language\n\t\t\t\t\t),\n\t\t\t\tlanguage = ''\n\t\t\t\t;\n\t\t\t\n\t\t\tif (params === null) \n\t\t\t\tcontinue;\n\n\t\t\tparams = dp.SyntaxHighlighter.parseParams(\n\t\t\t\tparams,\n\t\t\t\tshowGutter, \n\t\t\t\tshowControls, \n\t\t\t\tcollapseAll, \n\t\t\t\tfirstLine, \n\t\t\t\tshowColumns\n\t\t\t\t);\n\n\t\t\tSyntaxHighlighter.highlight(params, element);\n\t\t}\n\t}\n};\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/send_file_upload.phps",
    "content": "<?php\n/**\n * PHPMailer simple file upload and send example\n */\n$msg = '';\nif (array_key_exists('userfile', $_FILES)) {\n    // First handle the upload\n    // Don't trust provided filename - same goes for MIME types\n    // See http://php.net/manual/en/features.file-upload.php#114004 for more thorough upload validation\n    $uploadfile = tempnam(sys_get_temp_dir(), sha1($_FILES['userfile']['name']));\n    if (move_uploaded_file($_FILES['userfile']['tmp_name'], $uploadfile)) {\n        // Upload handled successfully\n        // Now create a message\n        // This should be somewhere in your include_path\n        require '../PHPMailerAutoload.php';\n        $mail = new PHPMailer;\n        $mail->setFrom('from@example.com', 'First Last');\n        $mail->addAddress('whoto@example.com', 'John Doe');\n        $mail->Subject = 'PHPMailer file sender';\n        $mail->Body = 'My message body';\n        // Attach the uploaded file\n        $mail->addAttachment($uploadfile, 'My uploaded file');\n        if (!$mail->send()) {\n            $msg .= \"Mailer Error: \" . $mail->ErrorInfo;\n        } else {\n            $msg .= \"Message sent!\";\n        }\n    } else {\n        $msg .= 'Failed to move file to ' . $uploadfile;\n    }\n}\n?>\n<!DOCTYPE html>\n<html>\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <title>PHPMailer Upload</title>\n</head>\n<body>\n<?php if (empty($msg)) { ?>\n    <form method=\"post\" enctype=\"multipart/form-data\">\n        <input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"100000\"> Send this file: <input name=\"userfile\" type=\"file\">\n        <input type=\"submit\" value=\"Send File\">\n    </form>\n<?php } else {\n    echo $msg;\n} ?>\n</body>\n</html>"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/send_multiple_file_upload.phps",
    "content": "<?php\n/**\n * PHPMailer multiple files upload and send example\n */\n$msg = '';\nif (array_key_exists('userfile', $_FILES)) {\n\n    // Create a message\n    // This should be somewhere in your include_path\n    require '../PHPMailerAutoload.php';\n    $mail = new PHPMailer;\n    $mail->setFrom('from@example.com', 'First Last');\n    $mail->addAddress('whoto@example.com', 'John Doe');\n    $mail->Subject = 'PHPMailer file sender';\n    $mail->Body = 'My message body';\n    //Attach multiple files one by one\n    for ($ct = 0; $ct < count($_FILES['userfile']['tmp_name']); $ct++) {\n        $uploadfile = tempnam(sys_get_temp_dir(), sha1($_FILES['userfile']['name'][$ct]));\n        $filename = $_FILES['userfile']['name'][$ct];\n        if (move_uploaded_file($_FILES['userfile']['tmp_name'][$ct], $uploadfile)) {\n            $mail->addAttachment($uploadfile, $filename);\n        } else {\n            $msg .= 'Failed to move file to ' . $uploadfile;\n        }\n    }\n    if (!$mail->send()) {\n        $msg .= \"Mailer Error: \" . $mail->ErrorInfo;\n    } else {\n        $msg .= \"Message sent!\";\n    }\n}\n?>\n<!DOCTYPE html>\n<html>\n<head>\n    <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">\n    <title>PHPMailer Upload</title>\n</head>\n<body>\n<?php if (empty($msg)) { ?>\n    <form method=\"post\" enctype=\"multipart/form-data\">\n        <input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"100000\">\n        Select one or more files:\n        <input name=\"userfile[]\" type=\"file\" multiple=\"multiple\">\n        <input type=\"submit\" value=\"Send Files\">\n    </form>\n<?php } else {\n    echo $msg;\n} ?>\n</body>\n</html>\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/sendmail.phps",
    "content": "<?php\n/**\n * This example shows sending a message using a local sendmail binary.\n */\n\nrequire '../PHPMailerAutoload.php';\n\n//Create a new PHPMailer instance\n$mail = new PHPMailer;\n// Set PHPMailer to use the sendmail transport\n$mail->isSendmail();\n//Set who the message is to be sent from\n$mail->setFrom('from@example.com', 'First Last');\n//Set an alternative reply-to address\n$mail->addReplyTo('replyto@example.com', 'First Last');\n//Set who the message is to be sent to\n$mail->addAddress('whoto@example.com', 'John Doe');\n//Set the subject line\n$mail->Subject = 'PHPMailer sendmail test';\n//Read an HTML message body from an external file, convert referenced images to embedded,\n//convert HTML into a basic plain-text alternative body\n$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));\n//Replace the plain text body with one created manually\n$mail->AltBody = 'This is a plain-text message body';\n//Attach an image file\n$mail->addAttachment('images/phpmailer_mini.png');\n\n//send the message, check for errors\nif (!$mail->send()) {\n    echo \"Mailer Error: \" . $mail->ErrorInfo;\n} else {\n    echo \"Message sent!\";\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/signed-mail.phps",
    "content": "<?php\n/**\n * This example shows signing a message and then sending it via the mail() function of PHP.\n * \n * Before you can sign the mail certificates are needed.\n *\n *\n * STEP 1 - Creating a certificate:\n * You can either use a self signed certificate, pay for a signed one or use free alternatives such as StartSSL/Comodo etc.\n * Check out this link for more providers: http://kb.mozillazine.org/Getting_an_SMIME_certificate\n * In this example I am using Comodo.\n * The form is directly available via https://secure.comodo.com/products/frontpage?area=SecureEmailCertificate\n * Fill it out and you'll get an email with a link to download your certificate.\n * Usually the certificate will be directly installed into your browser (FireFox/Chrome).\n * \n *\n * STEP 2 - Exporting the certificate\n * This is specific to your browser, however, most browsers will give you the option to export your recently added certificate in PKCS12 (.pfx)\n * Include your private key if you are asked for it.\n * Set up a password to protect your exported file.\n * \n * STEP 3 - Splitting the .pfx into a private key and the certificate.\n * I use openssl for this. You only need two commands. In my case the certificate file is called 'exported-cert.pfx'\n * To create the private key do the following:\n *\n * openssl pkcs12 -in exported-cert.pfx -nocerts -out cert.key\n * \n * Of course the way you name your file (-out) is up to you.\n * You will be asked for a password for the Import password. This is the password you just set while exporting the certificate into the pfx file.\n * Afterwards, you can password protect your private key (recommended)\n * Also make sure to set the permissions to a minimum level and suitable for your application.\n * To create the certificate file use the following command:\n * \n * openssl pkcs12 -in exported-cert.pfx -clcerts -nokeys -out cert.crt\n *\n * Again, the way you name your certificate is up to you. You will be also asked for the Import Password.\n * To create the certificate-chain file use the following command:\n *\n * openssl pkcs12 -in exported-cert.pfx -cacerts -out certchain.pem\n *\n * Again, the way you name your chain file is up to you. You will be also asked for the Import Password.\n *\n *\n * STEP 3 - Code\n */\n\nrequire '../PHPMailerAutoload.php';\n\n//Create a new PHPMailer instance\n$mail = new PHPMailer();\n//Set who the message is to be sent from\n//IMPORTANT: This must match the email address of your certificate.\n//Although the certificate will be valid, an error will be thrown since it cannot be verified that the sender and the signer are the same person.\n$mail->setFrom('from@example.com', 'First Last');\n//Set an alternative reply-to address\n$mail->addReplyTo('replyto@example.com', 'First Last');\n//Set who the message is to be sent to\n$mail->addAddress('whoto@example.com', 'John Doe');\n//Set the subject line\n$mail->Subject = 'PHPMailer mail() test';\n//Read an HTML message body from an external file, convert referenced images to embedded,\n//Convert HTML into a basic plain-text alternative body\n$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));\n//Replace the plain text body with one created manually\n$mail->AltBody = 'This is a plain-text message body';\n//Attach an image file\n$mail->addAttachment('images/phpmailer_mini.png');\n\n//Configure message signing (the actual signing does not occur until sending)\n$mail->sign(\n    '/path/to/cert.crt', //The location of your certificate file\n    '/path/to/cert.key', //The location of your private key file\n    'yourSecretPrivateKeyPassword', //The password you protected your private key with (not the Import Password! may be empty but parameter must not be omitted!)\n    '/path/to/certchain.pem' //The location of your chain file\n);\n\n//Send the message, check for errors\nif (!$mail->send()) {\n    echo \"Mailer Error: \" . $mail->ErrorInfo;\n} else {\n    echo \"Message sent!\";\n}\n\n/**\n * REMARKS:\n * If your email client does not support S/MIME it will most likely just show an attachment smime.p7s which is the signature contained in the email.\n * Other clients, such as Thunderbird support S/MIME natively and will validate the signature automatically and report the result in some way.\n */\n?>\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/smtp.phps",
    "content": "<?php\n/**\n * This example shows making an SMTP connection with authentication.\n */\n\n//SMTP needs accurate times, and the PHP time zone MUST be set\n//This should be done in your php.ini, but this is how to do it if you don't have access to that\ndate_default_timezone_set('Etc/UTC');\n\nrequire '../PHPMailerAutoload.php';\n\n//Create a new PHPMailer instance\n$mail = new PHPMailer;\n//Tell PHPMailer to use SMTP\n$mail->isSMTP();\n//Enable SMTP debugging\n// 0 = off (for production use)\n// 1 = client messages\n// 2 = client and server messages\n$mail->SMTPDebug = 2;\n//Ask for HTML-friendly debug output\n$mail->Debugoutput = 'html';\n//Set the hostname of the mail server\n$mail->Host = \"mail.example.com\";\n//Set the SMTP port number - likely to be 25, 465 or 587\n$mail->Port = 25;\n//Whether to use SMTP authentication\n$mail->SMTPAuth = true;\n//Username to use for SMTP authentication\n$mail->Username = \"yourname@example.com\";\n//Password to use for SMTP authentication\n$mail->Password = \"yourpassword\";\n//Set who the message is to be sent from\n$mail->setFrom('from@example.com', 'First Last');\n//Set an alternative reply-to address\n$mail->addReplyTo('replyto@example.com', 'First Last');\n//Set who the message is to be sent to\n$mail->addAddress('whoto@example.com', 'John Doe');\n//Set the subject line\n$mail->Subject = 'PHPMailer SMTP test';\n//Read an HTML message body from an external file, convert referenced images to embedded,\n//convert HTML into a basic plain-text alternative body\n$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));\n//Replace the plain text body with one created manually\n$mail->AltBody = 'This is a plain-text message body';\n//Attach an image file\n$mail->addAttachment('images/phpmailer_mini.png');\n\n//send the message, check for errors\nif (!$mail->send()) {\n    echo \"Mailer Error: \" . $mail->ErrorInfo;\n} else {\n    echo \"Message sent!\";\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/smtp_check.phps",
    "content": "<?php\n/**\n * This uses the SMTP class alone to check that a connection can be made to an SMTP server,\n * authenticate, then disconnect\n */\n\n//SMTP needs accurate times, and the PHP time zone MUST be set\n//This should be done in your php.ini, but this is how to do it if you don't have access to that\ndate_default_timezone_set('Etc/UTC');\n\nrequire '../PHPMailerAutoload.php';\n\n//Create a new SMTP instance\n$smtp = new SMTP;\n\n//Enable connection-level debug output\n$smtp->do_debug = SMTP::DEBUG_CONNECTION;\n\ntry {\n    //Connect to an SMTP server\n    if (!$smtp->connect('mail.example.com', 25)) {\n        throw new Exception('Connect failed');\n    }\n    //Say hello\n    if (!$smtp->hello(gethostname())) {\n        throw new Exception('EHLO failed: ' . $smtp->getError()['error']);\n    }\n    //Get the list of ESMTP services the server offers\n    $e = $smtp->getServerExtList();\n    //If server can do TLS encryption, use it\n    if (is_array($e) && array_key_exists('STARTTLS', $e)) {\n        $tlsok = $smtp->startTLS();\n        if (!$tlsok) {\n            throw new Exception('Failed to start encryption: ' . $smtp->getError()['error']);\n        }\n        //Repeat EHLO after STARTTLS\n        if (!$smtp->hello(gethostname())) {\n            throw new Exception('EHLO (2) failed: ' . $smtp->getError()['error']);\n        }\n        //Get new capabilities list, which will usually now include AUTH if it didn't before\n        $e = $smtp->getServerExtList();\n    }\n    //If server supports authentication, do it (even if no encryption)\n    if (is_array($e) && array_key_exists('AUTH', $e)) {\n        if ($smtp->authenticate('username', 'password')) {\n            echo \"Connected ok!\";\n        } else {\n            throw new Exception('Authentication failed: ' . $smtp->getError()['error']);\n        }\n    }\n} catch (Exception $e) {\n    echo 'SMTP error: ' . $e->getMessage(), \"\\n\";\n}\n//Whatever happened, close the connection.\n$smtp->quit(true);\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/smtp_no_auth.phps",
    "content": "<?php\n/**\n * This example shows making an SMTP connection without using authentication.\n */\n\n//SMTP needs accurate times, and the PHP time zone MUST be set\n//This should be done in your php.ini, but this is how to do it if you don't have access to that\ndate_default_timezone_set('Etc/UTC');\n\nrequire_once '../PHPMailerAutoload.php';\n\n//Create a new PHPMailer instance\n$mail = new PHPMailer;\n//Tell PHPMailer to use SMTP\n$mail->isSMTP();\n//Enable SMTP debugging\n// 0 = off (for production use)\n// 1 = client messages\n// 2 = client and server messages\n$mail->SMTPDebug = 2;\n//Ask for HTML-friendly debug output\n$mail->Debugoutput = 'html';\n//Set the hostname of the mail server\n$mail->Host = \"mail.example.com\";\n//Set the SMTP port number - likely to be 25, 465 or 587\n$mail->Port = 25;\n//Whether to use SMTP authentication\n$mail->SMTPAuth = false;\n//Set who the message is to be sent from\n$mail->setFrom('from@example.com', 'First Last');\n//Set an alternative reply-to address\n$mail->addReplyTo('replyto@example.com', 'First Last');\n//Set who the message is to be sent to\n$mail->addAddress('whoto@example.com', 'John Doe');\n//Set the subject line\n$mail->Subject = 'PHPMailer SMTP without auth test';\n//Read an HTML message body from an external file, convert referenced images to embedded,\n//convert HTML into a basic plain-text alternative body\n$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));\n//Replace the plain text body with one created manually\n$mail->AltBody = 'This is a plain-text message body';\n//Attach an image file\n$mail->addAttachment('images/phpmailer_mini.png');\n\n//send the message, check for errors\nif (!$mail->send()) {\n    echo \"Mailer Error: \" . $mail->ErrorInfo;\n} else {\n    echo \"Message sent!\";\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/ssl_options.phps",
    "content": "<?php\n/**\n * This example shows settings to use when sending over SMTP with TLS and custom connection options.\n */\n\n//SMTP needs accurate times, and the PHP time zone MUST be set\n//This should be done in your php.ini, but this is how to do it if you don't have access to that\ndate_default_timezone_set('Etc/UTC');\n\nrequire '../PHPMailerAutoload.php';\n\n//Create a new PHPMailer instance\n$mail = new PHPMailer;\n\n//Tell PHPMailer to use SMTP\n$mail->isSMTP();\n\n//Enable SMTP debugging\n// 0 = off (for production use)\n// 1 = client messages\n// 2 = client and server messages\n$mail->SMTPDebug = 2;\n\n//Ask for HTML-friendly debug output\n$mail->Debugoutput = 'html';\n\n//Set the hostname of the mail server\n$mail->Host = 'smtp.example.com';\n\n//Set the SMTP port number - 587 for authenticated TLS, a.k.a. RFC4409 SMTP submission\n$mail->Port = 587;\n\n//Set the encryption system to use - ssl (deprecated) or tls\n$mail->SMTPSecure = 'tls';\n\n//Custom connection options\n$mail->SMTPOptions = array (\n    'ssl' => array(\n        'verify_peer'  => true,\n        'verify_depth' => 3,\n        'allow_self_signed' => true,\n        'peer_name' => 'smtp.example.com',\n        'cafile' => '/etc/ssl/ca_cert.pem',\n    )\n);\n\n//Whether to use SMTP authentication\n$mail->SMTPAuth = true;\n\n//Username to use for SMTP authentication - use full email address for gmail\n$mail->Username = \"username@example.com\";\n\n//Password to use for SMTP authentication\n$mail->Password = \"yourpassword\";\n\n//Set who the message is to be sent from\n$mail->setFrom('from@example.com', 'First Last');\n\n//Set who the message is to be sent to\n$mail->addAddress('whoto@example.com', 'John Doe');\n\n//Set the subject line\n$mail->Subject = 'PHPMailer SMTP options test';\n\n//Read an HTML message body from an external file, convert referenced images to embedded,\n//convert HTML into a basic plain-text alternative body\n$mail->msgHTML(file_get_contents('contents.html'), dirname(__FILE__));\n\n//send the message, check for errors\nif (!$mail->send()) {\n    echo \"Mailer Error: \" . $mail->ErrorInfo;\n} else {\n    echo \"Message sent!\";\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shCore.css",
    "content": ".syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:\"Consolas\",\"Bitstream Vera Sans Mono\",\"Courier New\",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}\n.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}\n.syntaxhighlighter.source{overflow:hidden !important;}\n.syntaxhighlighter .bold{font-weight:bold !important;}\n.syntaxhighlighter .italic{font-style:italic !important;}\n.syntaxhighlighter .line{white-space:pre !important;}\n.syntaxhighlighter table{width:100% !important;}\n.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}\n.syntaxhighlighter table td.code{width:100% !important;}\n.syntaxhighlighter table td.code .container{position:relative !important;}\n.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}\n.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}\n.syntaxhighlighter table td.code .line{padding:0 1em !important;}\n.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}\n.syntaxhighlighter.show{display:block !important;}\n.syntaxhighlighter.collapsed table{display:none !important;}\n.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}\n.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}\n.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}\n.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}\n.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}\n.syntaxhighlighter .toolbar span.title{display:inline !important;}\n.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}\n.syntaxhighlighter .toolbar a.expandSource{display:none !important;}\n.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}\n.syntaxhighlighter.ie .toolbar{line-height:8px !important;}\n.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}\n.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}\n.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}\n.syntaxhighlighter.printing .line .content{color:black !important;}\n.syntaxhighlighter.printing .toolbar{display:none !important;}\n.syntaxhighlighter.printing a{text-decoration:none !important;}\n.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}\n.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}\n.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}\n.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}\n.syntaxhighlighter.printing .preprocessor{color:gray !important;}\n.syntaxhighlighter.printing .variable{color:#aa7700 !important;}\n.syntaxhighlighter.printing .value{color:#009900 !important;}\n.syntaxhighlighter.printing .functions{color:#ff1493 !important;}\n.syntaxhighlighter.printing .constants{color:#0066cc !important;}\n.syntaxhighlighter.printing .script{font-weight:bold !important;}\n.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}\n.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}\n.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shCoreDefault.css",
    "content": ".syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:\"Consolas\",\"Bitstream Vera Sans Mono\",\"Courier New\",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}\n.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}\n.syntaxhighlighter.source{overflow:hidden !important;}\n.syntaxhighlighter .bold{font-weight:bold !important;}\n.syntaxhighlighter .italic{font-style:italic !important;}\n.syntaxhighlighter .line{white-space:pre !important;}\n.syntaxhighlighter table{width:100% !important;}\n.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}\n.syntaxhighlighter table td.code{width:100% !important;}\n.syntaxhighlighter table td.code .container{position:relative !important;}\n.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}\n.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}\n.syntaxhighlighter table td.code .line{padding:0 1em !important;}\n.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}\n.syntaxhighlighter.show{display:block !important;}\n.syntaxhighlighter.collapsed table{display:none !important;}\n.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}\n.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}\n.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}\n.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}\n.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}\n.syntaxhighlighter .toolbar span.title{display:inline !important;}\n.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}\n.syntaxhighlighter .toolbar a.expandSource{display:none !important;}\n.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}\n.syntaxhighlighter.ie .toolbar{line-height:8px !important;}\n.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}\n.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}\n.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}\n.syntaxhighlighter.printing .line .content{color:black !important;}\n.syntaxhighlighter.printing .toolbar{display:none !important;}\n.syntaxhighlighter.printing a{text-decoration:none !important;}\n.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}\n.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}\n.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}\n.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}\n.syntaxhighlighter.printing .preprocessor{color:gray !important;}\n.syntaxhighlighter.printing .variable{color:#aa7700 !important;}\n.syntaxhighlighter.printing .value{color:#009900 !important;}\n.syntaxhighlighter.printing .functions{color:#ff1493 !important;}\n.syntaxhighlighter.printing .constants{color:#0066cc !important;}\n.syntaxhighlighter.printing .script{font-weight:bold !important;}\n.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}\n.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}\n.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}\n.syntaxhighlighter{background-color:white !important;}\n.syntaxhighlighter .line.alt1{background-color:white !important;}\n.syntaxhighlighter .line.alt2{background-color:white !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#e0e0e0 !important;}\n.syntaxhighlighter .line.highlighted.number{color:black !important;}\n.syntaxhighlighter table caption{color:black !important;}\n.syntaxhighlighter .gutter{color:#afafaf !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #6ce26c !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#6ce26c !important;color:white !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:blue !important;background:white !important;border:1px solid #6ce26c !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:blue !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:red !important;}\n.syntaxhighlighter .toolbar{color:white !important;background:#6ce26c !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:white !important;}\n.syntaxhighlighter .toolbar a:hover{color:black !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:black !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#008200 !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:blue !important;}\n.syntaxhighlighter .keyword{color:#006699 !important;}\n.syntaxhighlighter .preprocessor{color:gray !important;}\n.syntaxhighlighter .variable{color:#aa7700 !important;}\n.syntaxhighlighter .value{color:#009900 !important;}\n.syntaxhighlighter .functions{color:#ff1493 !important;}\n.syntaxhighlighter .constants{color:#0066cc !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#006699 !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:gray !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:red !important;}\n.syntaxhighlighter .keyword{font-weight:bold !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shCoreDjango.css",
    "content": ".syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:\"Consolas\",\"Bitstream Vera Sans Mono\",\"Courier New\",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}\n.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}\n.syntaxhighlighter.source{overflow:hidden !important;}\n.syntaxhighlighter .bold{font-weight:bold !important;}\n.syntaxhighlighter .italic{font-style:italic !important;}\n.syntaxhighlighter .line{white-space:pre !important;}\n.syntaxhighlighter table{width:100% !important;}\n.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}\n.syntaxhighlighter table td.code{width:100% !important;}\n.syntaxhighlighter table td.code .container{position:relative !important;}\n.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}\n.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}\n.syntaxhighlighter table td.code .line{padding:0 1em !important;}\n.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}\n.syntaxhighlighter.show{display:block !important;}\n.syntaxhighlighter.collapsed table{display:none !important;}\n.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}\n.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}\n.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}\n.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}\n.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}\n.syntaxhighlighter .toolbar span.title{display:inline !important;}\n.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}\n.syntaxhighlighter .toolbar a.expandSource{display:none !important;}\n.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}\n.syntaxhighlighter.ie .toolbar{line-height:8px !important;}\n.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}\n.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}\n.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}\n.syntaxhighlighter.printing .line .content{color:black !important;}\n.syntaxhighlighter.printing .toolbar{display:none !important;}\n.syntaxhighlighter.printing a{text-decoration:none !important;}\n.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}\n.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}\n.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}\n.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}\n.syntaxhighlighter.printing .preprocessor{color:gray !important;}\n.syntaxhighlighter.printing .variable{color:#aa7700 !important;}\n.syntaxhighlighter.printing .value{color:#009900 !important;}\n.syntaxhighlighter.printing .functions{color:#ff1493 !important;}\n.syntaxhighlighter.printing .constants{color:#0066cc !important;}\n.syntaxhighlighter.printing .script{font-weight:bold !important;}\n.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}\n.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}\n.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}\n.syntaxhighlighter{background-color:#0a2b1d !important;}\n.syntaxhighlighter .line.alt1{background-color:#0a2b1d !important;}\n.syntaxhighlighter .line.alt2{background-color:#0a2b1d !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#233729 !important;}\n.syntaxhighlighter .line.highlighted.number{color:white !important;}\n.syntaxhighlighter table caption{color:#f8f8f8 !important;}\n.syntaxhighlighter .gutter{color:#497958 !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #41a83e !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#41a83e !important;color:#0a2b1d !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#96dd3b !important;background:black !important;border:1px solid #41a83e !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#96dd3b !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:white !important;}\n.syntaxhighlighter .toolbar{color:white !important;background:#41a83e !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:white !important;}\n.syntaxhighlighter .toolbar a:hover{color:#ffe862 !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#f8f8f8 !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#336442 !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#9df39f !important;}\n.syntaxhighlighter .keyword{color:#96dd3b !important;}\n.syntaxhighlighter .preprocessor{color:#91bb9e !important;}\n.syntaxhighlighter .variable{color:#ffaa3e !important;}\n.syntaxhighlighter .value{color:#f7e741 !important;}\n.syntaxhighlighter .functions{color:#ffaa3e !important;}\n.syntaxhighlighter .constants{color:#e0e8ff !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#96dd3b !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#eb939a !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#91bb9e !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#edef7d !important;}\n.syntaxhighlighter .comments{font-style:italic !important;}\n.syntaxhighlighter .keyword{font-weight:bold !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shCoreEclipse.css",
    "content": ".syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:\"Consolas\",\"Bitstream Vera Sans Mono\",\"Courier New\",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}\n.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}\n.syntaxhighlighter.source{overflow:hidden !important;}\n.syntaxhighlighter .bold{font-weight:bold !important;}\n.syntaxhighlighter .italic{font-style:italic !important;}\n.syntaxhighlighter .line{white-space:pre !important;}\n.syntaxhighlighter table{width:100% !important;}\n.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}\n.syntaxhighlighter table td.code{width:100% !important;}\n.syntaxhighlighter table td.code .container{position:relative !important;}\n.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}\n.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}\n.syntaxhighlighter table td.code .line{padding:0 1em !important;}\n.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}\n.syntaxhighlighter.show{display:block !important;}\n.syntaxhighlighter.collapsed table{display:none !important;}\n.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}\n.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}\n.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}\n.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}\n.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}\n.syntaxhighlighter .toolbar span.title{display:inline !important;}\n.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}\n.syntaxhighlighter .toolbar a.expandSource{display:none !important;}\n.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}\n.syntaxhighlighter.ie .toolbar{line-height:8px !important;}\n.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}\n.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}\n.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}\n.syntaxhighlighter.printing .line .content{color:black !important;}\n.syntaxhighlighter.printing .toolbar{display:none !important;}\n.syntaxhighlighter.printing a{text-decoration:none !important;}\n.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}\n.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}\n.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}\n.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}\n.syntaxhighlighter.printing .preprocessor{color:gray !important;}\n.syntaxhighlighter.printing .variable{color:#aa7700 !important;}\n.syntaxhighlighter.printing .value{color:#009900 !important;}\n.syntaxhighlighter.printing .functions{color:#ff1493 !important;}\n.syntaxhighlighter.printing .constants{color:#0066cc !important;}\n.syntaxhighlighter.printing .script{font-weight:bold !important;}\n.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}\n.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}\n.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}\n.syntaxhighlighter{background-color:white !important;}\n.syntaxhighlighter .line.alt1{background-color:white !important;}\n.syntaxhighlighter .line.alt2{background-color:white !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#c3defe !important;}\n.syntaxhighlighter .line.highlighted.number{color:white !important;}\n.syntaxhighlighter table caption{color:black !important;}\n.syntaxhighlighter .gutter{color:#787878 !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #d4d0c8 !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#d4d0c8 !important;color:white !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#3f5fbf !important;background:white !important;border:1px solid #d4d0c8 !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#3f5fbf !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:#aa7700 !important;}\n.syntaxhighlighter .toolbar{color:#a0a0a0 !important;background:#d4d0c8 !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:#a0a0a0 !important;}\n.syntaxhighlighter .toolbar a:hover{color:red !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:black !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#3f5fbf !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#2a00ff !important;}\n.syntaxhighlighter .keyword{color:#7f0055 !important;}\n.syntaxhighlighter .preprocessor{color:#646464 !important;}\n.syntaxhighlighter .variable{color:#aa7700 !important;}\n.syntaxhighlighter .value{color:#009900 !important;}\n.syntaxhighlighter .functions{color:#ff1493 !important;}\n.syntaxhighlighter .constants{color:#0066cc !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#7f0055 !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:gray !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:red !important;}\n.syntaxhighlighter .keyword{font-weight:bold !important;}\n.syntaxhighlighter .xml .keyword{color:#3f7f7f !important;font-weight:normal !important;}\n.syntaxhighlighter .xml .color1,.syntaxhighlighter .xml .color1 a{color:#7f007f !important;}\n.syntaxhighlighter .xml .string{font-style:italic !important;color:#2a00ff !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shCoreEmacs.css",
    "content": ".syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:\"Consolas\",\"Bitstream Vera Sans Mono\",\"Courier New\",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}\n.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}\n.syntaxhighlighter.source{overflow:hidden !important;}\n.syntaxhighlighter .bold{font-weight:bold !important;}\n.syntaxhighlighter .italic{font-style:italic !important;}\n.syntaxhighlighter .line{white-space:pre !important;}\n.syntaxhighlighter table{width:100% !important;}\n.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}\n.syntaxhighlighter table td.code{width:100% !important;}\n.syntaxhighlighter table td.code .container{position:relative !important;}\n.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}\n.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}\n.syntaxhighlighter table td.code .line{padding:0 1em !important;}\n.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}\n.syntaxhighlighter.show{display:block !important;}\n.syntaxhighlighter.collapsed table{display:none !important;}\n.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}\n.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}\n.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}\n.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}\n.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}\n.syntaxhighlighter .toolbar span.title{display:inline !important;}\n.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}\n.syntaxhighlighter .toolbar a.expandSource{display:none !important;}\n.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}\n.syntaxhighlighter.ie .toolbar{line-height:8px !important;}\n.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}\n.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}\n.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}\n.syntaxhighlighter.printing .line .content{color:black !important;}\n.syntaxhighlighter.printing .toolbar{display:none !important;}\n.syntaxhighlighter.printing a{text-decoration:none !important;}\n.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}\n.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}\n.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}\n.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}\n.syntaxhighlighter.printing .preprocessor{color:gray !important;}\n.syntaxhighlighter.printing .variable{color:#aa7700 !important;}\n.syntaxhighlighter.printing .value{color:#009900 !important;}\n.syntaxhighlighter.printing .functions{color:#ff1493 !important;}\n.syntaxhighlighter.printing .constants{color:#0066cc !important;}\n.syntaxhighlighter.printing .script{font-weight:bold !important;}\n.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}\n.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}\n.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}\n.syntaxhighlighter{background-color:black !important;}\n.syntaxhighlighter .line.alt1{background-color:black !important;}\n.syntaxhighlighter .line.alt2{background-color:black !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#2a3133 !important;}\n.syntaxhighlighter .line.highlighted.number{color:white !important;}\n.syntaxhighlighter table caption{color:#d3d3d3 !important;}\n.syntaxhighlighter .gutter{color:#d3d3d3 !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #990000 !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#990000 !important;color:black !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#ebdb8d !important;background:black !important;border:1px solid #990000 !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#ebdb8d !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:#ff7d27 !important;}\n.syntaxhighlighter .toolbar{color:white !important;background:#990000 !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:white !important;}\n.syntaxhighlighter .toolbar a:hover{color:#9ccff4 !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#d3d3d3 !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#ff7d27 !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#ff9e7b !important;}\n.syntaxhighlighter .keyword{color:aqua !important;}\n.syntaxhighlighter .preprocessor{color:#aec4de !important;}\n.syntaxhighlighter .variable{color:#ffaa3e !important;}\n.syntaxhighlighter .value{color:#009900 !important;}\n.syntaxhighlighter .functions{color:#81cef9 !important;}\n.syntaxhighlighter .constants{color:#ff9e7b !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:aqua !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#ebdb8d !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff7d27 !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#aec4de !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shCoreFadeToGrey.css",
    "content": ".syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:\"Consolas\",\"Bitstream Vera Sans Mono\",\"Courier New\",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}\n.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}\n.syntaxhighlighter.source{overflow:hidden !important;}\n.syntaxhighlighter .bold{font-weight:bold !important;}\n.syntaxhighlighter .italic{font-style:italic !important;}\n.syntaxhighlighter .line{white-space:pre !important;}\n.syntaxhighlighter table{width:100% !important;}\n.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}\n.syntaxhighlighter table td.code{width:100% !important;}\n.syntaxhighlighter table td.code .container{position:relative !important;}\n.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}\n.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}\n.syntaxhighlighter table td.code .line{padding:0 1em !important;}\n.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}\n.syntaxhighlighter.show{display:block !important;}\n.syntaxhighlighter.collapsed table{display:none !important;}\n.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}\n.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}\n.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}\n.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}\n.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}\n.syntaxhighlighter .toolbar span.title{display:inline !important;}\n.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}\n.syntaxhighlighter .toolbar a.expandSource{display:none !important;}\n.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}\n.syntaxhighlighter.ie .toolbar{line-height:8px !important;}\n.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}\n.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}\n.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}\n.syntaxhighlighter.printing .line .content{color:black !important;}\n.syntaxhighlighter.printing .toolbar{display:none !important;}\n.syntaxhighlighter.printing a{text-decoration:none !important;}\n.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}\n.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}\n.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}\n.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}\n.syntaxhighlighter.printing .preprocessor{color:gray !important;}\n.syntaxhighlighter.printing .variable{color:#aa7700 !important;}\n.syntaxhighlighter.printing .value{color:#009900 !important;}\n.syntaxhighlighter.printing .functions{color:#ff1493 !important;}\n.syntaxhighlighter.printing .constants{color:#0066cc !important;}\n.syntaxhighlighter.printing .script{font-weight:bold !important;}\n.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}\n.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}\n.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}\n.syntaxhighlighter{background-color:#121212 !important;}\n.syntaxhighlighter .line.alt1{background-color:#121212 !important;}\n.syntaxhighlighter .line.alt2{background-color:#121212 !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#2c2c29 !important;}\n.syntaxhighlighter .line.highlighted.number{color:white !important;}\n.syntaxhighlighter table caption{color:white !important;}\n.syntaxhighlighter .gutter{color:#afafaf !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #3185b9 !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#3185b9 !important;color:#121212 !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#3185b9 !important;background:black !important;border:1px solid #3185b9 !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#3185b9 !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:#d01d33 !important;}\n.syntaxhighlighter .toolbar{color:white !important;background:#3185b9 !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:white !important;}\n.syntaxhighlighter .toolbar a:hover{color:#96daff !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:white !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#696854 !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#e3e658 !important;}\n.syntaxhighlighter .keyword{color:#d01d33 !important;}\n.syntaxhighlighter .preprocessor{color:#435a5f !important;}\n.syntaxhighlighter .variable{color:#898989 !important;}\n.syntaxhighlighter .value{color:#009900 !important;}\n.syntaxhighlighter .functions{color:#aaaaaa !important;}\n.syntaxhighlighter .constants{color:#96daff !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#d01d33 !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#ffc074 !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#4a8cdb !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#96daff !important;}\n.syntaxhighlighter .functions{font-weight:bold !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shCoreMDUltra.css",
    "content": ".syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:\"Consolas\",\"Bitstream Vera Sans Mono\",\"Courier New\",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}\n.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}\n.syntaxhighlighter.source{overflow:hidden !important;}\n.syntaxhighlighter .bold{font-weight:bold !important;}\n.syntaxhighlighter .italic{font-style:italic !important;}\n.syntaxhighlighter .line{white-space:pre !important;}\n.syntaxhighlighter table{width:100% !important;}\n.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}\n.syntaxhighlighter table td.code{width:100% !important;}\n.syntaxhighlighter table td.code .container{position:relative !important;}\n.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}\n.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}\n.syntaxhighlighter table td.code .line{padding:0 1em !important;}\n.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}\n.syntaxhighlighter.show{display:block !important;}\n.syntaxhighlighter.collapsed table{display:none !important;}\n.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}\n.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}\n.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}\n.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}\n.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}\n.syntaxhighlighter .toolbar span.title{display:inline !important;}\n.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}\n.syntaxhighlighter .toolbar a.expandSource{display:none !important;}\n.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}\n.syntaxhighlighter.ie .toolbar{line-height:8px !important;}\n.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}\n.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}\n.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}\n.syntaxhighlighter.printing .line .content{color:black !important;}\n.syntaxhighlighter.printing .toolbar{display:none !important;}\n.syntaxhighlighter.printing a{text-decoration:none !important;}\n.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}\n.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}\n.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}\n.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}\n.syntaxhighlighter.printing .preprocessor{color:gray !important;}\n.syntaxhighlighter.printing .variable{color:#aa7700 !important;}\n.syntaxhighlighter.printing .value{color:#009900 !important;}\n.syntaxhighlighter.printing .functions{color:#ff1493 !important;}\n.syntaxhighlighter.printing .constants{color:#0066cc !important;}\n.syntaxhighlighter.printing .script{font-weight:bold !important;}\n.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}\n.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}\n.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}\n.syntaxhighlighter{background-color:#222222 !important;}\n.syntaxhighlighter .line.alt1{background-color:#222222 !important;}\n.syntaxhighlighter .line.alt2{background-color:#222222 !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#253e5a !important;}\n.syntaxhighlighter .line.highlighted.number{color:white !important;}\n.syntaxhighlighter table caption{color:lime !important;}\n.syntaxhighlighter .gutter{color:#38566f !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #435a5f !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#435a5f !important;color:#222222 !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#428bdd !important;background:black !important;border:1px solid #435a5f !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#428bdd !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:lime !important;}\n.syntaxhighlighter .toolbar{color:#aaaaff !important;background:#435a5f !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:#aaaaff !important;}\n.syntaxhighlighter .toolbar a:hover{color:#9ccff4 !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:lime !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#428bdd !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:lime !important;}\n.syntaxhighlighter .keyword{color:#aaaaff !important;}\n.syntaxhighlighter .preprocessor{color:#8aa6c1 !important;}\n.syntaxhighlighter .variable{color:aqua !important;}\n.syntaxhighlighter .value{color:#f7e741 !important;}\n.syntaxhighlighter .functions{color:#ff8000 !important;}\n.syntaxhighlighter .constants{color:yellow !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#aaaaff !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:red !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:yellow !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#ffaa3e !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shCoreMidnight.css",
    "content": ".syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:\"Consolas\",\"Bitstream Vera Sans Mono\",\"Courier New\",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}\n.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}\n.syntaxhighlighter.source{overflow:hidden !important;}\n.syntaxhighlighter .bold{font-weight:bold !important;}\n.syntaxhighlighter .italic{font-style:italic !important;}\n.syntaxhighlighter .line{white-space:pre !important;}\n.syntaxhighlighter table{width:100% !important;}\n.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}\n.syntaxhighlighter table td.code{width:100% !important;}\n.syntaxhighlighter table td.code .container{position:relative !important;}\n.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}\n.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}\n.syntaxhighlighter table td.code .line{padding:0 1em !important;}\n.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}\n.syntaxhighlighter.show{display:block !important;}\n.syntaxhighlighter.collapsed table{display:none !important;}\n.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}\n.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}\n.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}\n.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}\n.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}\n.syntaxhighlighter .toolbar span.title{display:inline !important;}\n.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}\n.syntaxhighlighter .toolbar a.expandSource{display:none !important;}\n.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}\n.syntaxhighlighter.ie .toolbar{line-height:8px !important;}\n.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}\n.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}\n.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}\n.syntaxhighlighter.printing .line .content{color:black !important;}\n.syntaxhighlighter.printing .toolbar{display:none !important;}\n.syntaxhighlighter.printing a{text-decoration:none !important;}\n.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}\n.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}\n.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}\n.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}\n.syntaxhighlighter.printing .preprocessor{color:gray !important;}\n.syntaxhighlighter.printing .variable{color:#aa7700 !important;}\n.syntaxhighlighter.printing .value{color:#009900 !important;}\n.syntaxhighlighter.printing .functions{color:#ff1493 !important;}\n.syntaxhighlighter.printing .constants{color:#0066cc !important;}\n.syntaxhighlighter.printing .script{font-weight:bold !important;}\n.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}\n.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}\n.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}\n.syntaxhighlighter{background-color:#0f192a !important;}\n.syntaxhighlighter .line.alt1{background-color:#0f192a !important;}\n.syntaxhighlighter .line.alt2{background-color:#0f192a !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#253e5a !important;}\n.syntaxhighlighter .line.highlighted.number{color:#38566f !important;}\n.syntaxhighlighter table caption{color:#d1edff !important;}\n.syntaxhighlighter .gutter{color:#afafaf !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #435a5f !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#435a5f !important;color:#0f192a !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#428bdd !important;background:black !important;border:1px solid #435a5f !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#428bdd !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:#1dc116 !important;}\n.syntaxhighlighter .toolbar{color:#d1edff !important;background:#435a5f !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:#d1edff !important;}\n.syntaxhighlighter .toolbar a:hover{color:#8aa6c1 !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#d1edff !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#428bdd !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#1dc116 !important;}\n.syntaxhighlighter .keyword{color:#b43d3d !important;}\n.syntaxhighlighter .preprocessor{color:#8aa6c1 !important;}\n.syntaxhighlighter .variable{color:#ffaa3e !important;}\n.syntaxhighlighter .value{color:#f7e741 !important;}\n.syntaxhighlighter .functions{color:#ffaa3e !important;}\n.syntaxhighlighter .constants{color:#e0e8ff !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#b43d3d !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#f8bb00 !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:white !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#ffaa3e !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shCoreRDark.css",
    "content": ".syntaxhighlighter a,.syntaxhighlighter div,.syntaxhighlighter code,.syntaxhighlighter table,.syntaxhighlighter table td,.syntaxhighlighter table tr,.syntaxhighlighter table tbody,.syntaxhighlighter table thead,.syntaxhighlighter table caption,.syntaxhighlighter textarea{-moz-border-radius:0 0 0 0 !important;-webkit-border-radius:0 0 0 0 !important;background:none !important;border:0 !important;bottom:auto !important;float:none !important;height:auto !important;left:auto !important;line-height:1.1em !important;margin:0 !important;outline:0 !important;overflow:visible !important;padding:0 !important;position:static !important;right:auto !important;text-align:left !important;top:auto !important;vertical-align:baseline !important;width:auto !important;box-sizing:content-box !important;font-family:\"Consolas\",\"Bitstream Vera Sans Mono\",\"Courier New\",Courier,monospace !important;font-weight:normal !important;font-style:normal !important;font-size:1em !important;min-height:inherit !important;min-height:auto !important;}\n.syntaxhighlighter{width:100% !important;margin:1em 0 1em 0 !important;position:relative !important;overflow:auto !important;font-size:1em !important;}\n.syntaxhighlighter.source{overflow:hidden !important;}\n.syntaxhighlighter .bold{font-weight:bold !important;}\n.syntaxhighlighter .italic{font-style:italic !important;}\n.syntaxhighlighter .line{white-space:pre !important;}\n.syntaxhighlighter table{width:100% !important;}\n.syntaxhighlighter table caption{text-align:left !important;padding:.5em 0 0.5em 1em !important;}\n.syntaxhighlighter table td.code{width:100% !important;}\n.syntaxhighlighter table td.code .container{position:relative !important;}\n.syntaxhighlighter table td.code .container textarea{box-sizing:border-box !important;position:absolute !important;left:0 !important;top:0 !important;width:100% !important;height:100% !important;border:none !important;background:white !important;padding-left:1em !important;overflow:hidden !important;white-space:pre !important;}\n.syntaxhighlighter table td.gutter .line{text-align:right !important;padding:0 0.5em 0 1em !important;}\n.syntaxhighlighter table td.code .line{padding:0 1em !important;}\n.syntaxhighlighter.nogutter td.code .container textarea,.syntaxhighlighter.nogutter td.code .line{padding-left:0em !important;}\n.syntaxhighlighter.show{display:block !important;}\n.syntaxhighlighter.collapsed table{display:none !important;}\n.syntaxhighlighter.collapsed .toolbar{padding:0.1em 0.8em 0em 0.8em !important;font-size:1em !important;position:static !important;width:auto !important;height:auto !important;}\n.syntaxhighlighter.collapsed .toolbar span{display:inline !important;margin-right:1em !important;}\n.syntaxhighlighter.collapsed .toolbar span a{padding:0 !important;display:none !important;}\n.syntaxhighlighter.collapsed .toolbar span a.expandSource{display:inline !important;}\n.syntaxhighlighter .toolbar{position:absolute !important;right:1px !important;top:1px !important;width:11px !important;height:11px !important;font-size:10px !important;z-index:10 !important;}\n.syntaxhighlighter .toolbar span.title{display:inline !important;}\n.syntaxhighlighter .toolbar a{display:block !important;text-align:center !important;text-decoration:none !important;padding-top:1px !important;}\n.syntaxhighlighter .toolbar a.expandSource{display:none !important;}\n.syntaxhighlighter.ie{font-size:.9em !important;padding:1px 0 1px 0 !important;}\n.syntaxhighlighter.ie .toolbar{line-height:8px !important;}\n.syntaxhighlighter.ie .toolbar a{padding-top:0px !important;}\n.syntaxhighlighter.printing .line.alt1 .content,.syntaxhighlighter.printing .line.alt2 .content,.syntaxhighlighter.printing .line.highlighted .number,.syntaxhighlighter.printing .line.highlighted.alt1 .content,.syntaxhighlighter.printing .line.highlighted.alt2 .content{background:none !important;}\n.syntaxhighlighter.printing .line .number{color:#bbbbbb !important;}\n.syntaxhighlighter.printing .line .content{color:black !important;}\n.syntaxhighlighter.printing .toolbar{display:none !important;}\n.syntaxhighlighter.printing a{text-decoration:none !important;}\n.syntaxhighlighter.printing .plain,.syntaxhighlighter.printing .plain a{color:black !important;}\n.syntaxhighlighter.printing .comments,.syntaxhighlighter.printing .comments a{color:#008200 !important;}\n.syntaxhighlighter.printing .string,.syntaxhighlighter.printing .string a{color:blue !important;}\n.syntaxhighlighter.printing .keyword{color:#006699 !important;font-weight:bold !important;}\n.syntaxhighlighter.printing .preprocessor{color:gray !important;}\n.syntaxhighlighter.printing .variable{color:#aa7700 !important;}\n.syntaxhighlighter.printing .value{color:#009900 !important;}\n.syntaxhighlighter.printing .functions{color:#ff1493 !important;}\n.syntaxhighlighter.printing .constants{color:#0066cc !important;}\n.syntaxhighlighter.printing .script{font-weight:bold !important;}\n.syntaxhighlighter.printing .color1,.syntaxhighlighter.printing .color1 a{color:gray !important;}\n.syntaxhighlighter.printing .color2,.syntaxhighlighter.printing .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter.printing .color3,.syntaxhighlighter.printing .color3 a{color:red !important;}\n.syntaxhighlighter.printing .break,.syntaxhighlighter.printing .break a{color:black !important;}\n.syntaxhighlighter{background-color:#1b2426 !important;}\n.syntaxhighlighter .line.alt1{background-color:#1b2426 !important;}\n.syntaxhighlighter .line.alt2{background-color:#1b2426 !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#323e41 !important;}\n.syntaxhighlighter .line.highlighted.number{color:#b9bdb6 !important;}\n.syntaxhighlighter table caption{color:#b9bdb6 !important;}\n.syntaxhighlighter .gutter{color:#afafaf !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #435a5f !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#435a5f !important;color:#1b2426 !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#5ba1cf !important;background:black !important;border:1px solid #435a5f !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#5ba1cf !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:#5ce638 !important;}\n.syntaxhighlighter .toolbar{color:white !important;background:#435a5f !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:white !important;}\n.syntaxhighlighter .toolbar a:hover{color:#e0e8ff !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#b9bdb6 !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#878a85 !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#5ce638 !important;}\n.syntaxhighlighter .keyword{color:#5ba1cf !important;}\n.syntaxhighlighter .preprocessor{color:#435a5f !important;}\n.syntaxhighlighter .variable{color:#ffaa3e !important;}\n.syntaxhighlighter .value{color:#009900 !important;}\n.syntaxhighlighter .functions{color:#ffaa3e !important;}\n.syntaxhighlighter .constants{color:#e0e8ff !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#5ba1cf !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#e0e8ff !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:white !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#ffaa3e !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shThemeAppleScript.css",
    "content": ".syntaxhighlighter.applescript{background:white;font-size:1em;color:black;}\n.syntaxhighlighter.applescript div,.syntaxhighlighter.applescript code{font:1em/1.25 Verdana,sans-serif !important;}\n.syntaxhighlighter.applescript .code .line{overflow:hidden !important;}\n.syntaxhighlighter.applescript .code .line.highlighted{background:#b5d5ff !important;}\n.syntaxhighlighter.applescript .color1{color:#000000 !important;}\n.syntaxhighlighter.applescript .color2{color:#000000 !important;}\n.syntaxhighlighter.applescript .color3{color:#000000 !important;font-weight:bold !important;}\n.syntaxhighlighter.applescript .keyword{color:#000000 !important;font-weight:bold !important;}\n.syntaxhighlighter.applescript .color4{color:#0000ff !important;font-style:italic !important;}\n.syntaxhighlighter.applescript .comments{color:#4c4d4d !important;}\n.syntaxhighlighter.applescript .plain{color:#408000 !important;}\n.syntaxhighlighter.applescript .string{color:#000000 !important;}\n.syntaxhighlighter.applescript .commandNames{color:#0000ff !important;font-weight:bold !important;}\n.syntaxhighlighter.applescript .parameterNames{color:#0000ff !important;}\n.syntaxhighlighter.applescript .classes{color:#0000ff !important;font-style:italic !important;}\n.syntaxhighlighter.applescript .properties{color:#6c04d4 !important;}\n.syntaxhighlighter.applescript .enumeratedValues{color:#4a1e7f !important;}\n.syntaxhighlighter.applescript .additionCommandNames{color:#0016b0 !important;font-weight:bold !important;}\n.syntaxhighlighter.applescript .additionParameterNames{color:#0016b0 !important;}\n.syntaxhighlighter.applescript .additionClasses{color:#0016b0 !important;font-style:italic !important;}\n.syntaxhighlighter.applescript .spaces{display:inline-block;height:0 !important;font-size:1.75em !important;line-height:0 !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shThemeDefault.css",
    "content": ".syntaxhighlighter{background-color:white !important;}\n.syntaxhighlighter .line.alt1{background-color:white !important;}\n.syntaxhighlighter .line.alt2{background-color:white !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#e0e0e0 !important;}\n.syntaxhighlighter .line.highlighted.number{color:black !important;}\n.syntaxhighlighter table caption{color:black !important;}\n.syntaxhighlighter .gutter{color:#afafaf !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #6ce26c !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#6ce26c !important;color:white !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:blue !important;background:white !important;border:1px solid #6ce26c !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:blue !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:red !important;}\n.syntaxhighlighter .toolbar{color:white !important;background:#6ce26c !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:white !important;}\n.syntaxhighlighter .toolbar a:hover{color:black !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:black !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#008200 !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:blue !important;}\n.syntaxhighlighter .keyword{color:#006699 !important;}\n.syntaxhighlighter .preprocessor{color:gray !important;}\n.syntaxhighlighter .variable{color:#aa7700 !important;}\n.syntaxhighlighter .value{color:#009900 !important;}\n.syntaxhighlighter .functions{color:#ff1493 !important;}\n.syntaxhighlighter .constants{color:#0066cc !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#006699 !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:gray !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:red !important;}\n.syntaxhighlighter .keyword{font-weight:bold !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shThemeDjango.css",
    "content": ".syntaxhighlighter{background-color:#0a2b1d !important;}\n.syntaxhighlighter .line.alt1{background-color:#0a2b1d !important;}\n.syntaxhighlighter .line.alt2{background-color:#0a2b1d !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#233729 !important;}\n.syntaxhighlighter .line.highlighted.number{color:white !important;}\n.syntaxhighlighter table caption{color:#f8f8f8 !important;}\n.syntaxhighlighter .gutter{color:#497958 !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #41a83e !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#41a83e !important;color:#0a2b1d !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#96dd3b !important;background:black !important;border:1px solid #41a83e !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#96dd3b !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:white !important;}\n.syntaxhighlighter .toolbar{color:white !important;background:#41a83e !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:white !important;}\n.syntaxhighlighter .toolbar a:hover{color:#ffe862 !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#f8f8f8 !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#336442 !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#9df39f !important;}\n.syntaxhighlighter .keyword{color:#96dd3b !important;}\n.syntaxhighlighter .preprocessor{color:#91bb9e !important;}\n.syntaxhighlighter .variable{color:#ffaa3e !important;}\n.syntaxhighlighter .value{color:#f7e741 !important;}\n.syntaxhighlighter .functions{color:#ffaa3e !important;}\n.syntaxhighlighter .constants{color:#e0e8ff !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#96dd3b !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#eb939a !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#91bb9e !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#edef7d !important;}\n.syntaxhighlighter .comments{font-style:italic !important;}\n.syntaxhighlighter .keyword{font-weight:bold !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shThemeEclipse.css",
    "content": ".syntaxhighlighter{background-color:white !important;}\n.syntaxhighlighter .line.alt1{background-color:white !important;}\n.syntaxhighlighter .line.alt2{background-color:white !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#c3defe !important;}\n.syntaxhighlighter .line.highlighted.number{color:white !important;}\n.syntaxhighlighter table caption{color:black !important;}\n.syntaxhighlighter .gutter{color:#787878 !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #d4d0c8 !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#d4d0c8 !important;color:white !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#3f5fbf !important;background:white !important;border:1px solid #d4d0c8 !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#3f5fbf !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:#aa7700 !important;}\n.syntaxhighlighter .toolbar{color:#a0a0a0 !important;background:#d4d0c8 !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:#a0a0a0 !important;}\n.syntaxhighlighter .toolbar a:hover{color:red !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:black !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#3f5fbf !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#2a00ff !important;}\n.syntaxhighlighter .keyword{color:#7f0055 !important;}\n.syntaxhighlighter .preprocessor{color:#646464 !important;}\n.syntaxhighlighter .variable{color:#aa7700 !important;}\n.syntaxhighlighter .value{color:#009900 !important;}\n.syntaxhighlighter .functions{color:#ff1493 !important;}\n.syntaxhighlighter .constants{color:#0066cc !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#7f0055 !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:gray !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:red !important;}\n.syntaxhighlighter .keyword{font-weight:bold !important;}\n.syntaxhighlighter .xml .keyword{color:#3f7f7f !important;font-weight:normal !important;}\n.syntaxhighlighter .xml .color1,.syntaxhighlighter .xml .color1 a{color:#7f007f !important;}\n.syntaxhighlighter .xml .string{font-style:italic !important;color:#2a00ff !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shThemeEmacs.css",
    "content": ".syntaxhighlighter{background-color:black !important;}\n.syntaxhighlighter .line.alt1{background-color:black !important;}\n.syntaxhighlighter .line.alt2{background-color:black !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#2a3133 !important;}\n.syntaxhighlighter .line.highlighted.number{color:white !important;}\n.syntaxhighlighter table caption{color:#d3d3d3 !important;}\n.syntaxhighlighter .gutter{color:#d3d3d3 !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #990000 !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#990000 !important;color:black !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#ebdb8d !important;background:black !important;border:1px solid #990000 !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#ebdb8d !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:#ff7d27 !important;}\n.syntaxhighlighter .toolbar{color:white !important;background:#990000 !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:white !important;}\n.syntaxhighlighter .toolbar a:hover{color:#9ccff4 !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#d3d3d3 !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#ff7d27 !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#ff9e7b !important;}\n.syntaxhighlighter .keyword{color:aqua !important;}\n.syntaxhighlighter .preprocessor{color:#aec4de !important;}\n.syntaxhighlighter .variable{color:#ffaa3e !important;}\n.syntaxhighlighter .value{color:#009900 !important;}\n.syntaxhighlighter .functions{color:#81cef9 !important;}\n.syntaxhighlighter .constants{color:#ff9e7b !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:aqua !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#ebdb8d !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff7d27 !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#aec4de !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shThemeFadeToGrey.css",
    "content": ".syntaxhighlighter{background-color:#121212 !important;}\n.syntaxhighlighter .line.alt1{background-color:#121212 !important;}\n.syntaxhighlighter .line.alt2{background-color:#121212 !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#2c2c29 !important;}\n.syntaxhighlighter .line.highlighted.number{color:white !important;}\n.syntaxhighlighter table caption{color:white !important;}\n.syntaxhighlighter .gutter{color:#afafaf !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #3185b9 !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#3185b9 !important;color:#121212 !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#3185b9 !important;background:black !important;border:1px solid #3185b9 !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#3185b9 !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:#d01d33 !important;}\n.syntaxhighlighter .toolbar{color:white !important;background:#3185b9 !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:white !important;}\n.syntaxhighlighter .toolbar a:hover{color:#96daff !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:white !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#696854 !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#e3e658 !important;}\n.syntaxhighlighter .keyword{color:#d01d33 !important;}\n.syntaxhighlighter .preprocessor{color:#435a5f !important;}\n.syntaxhighlighter .variable{color:#898989 !important;}\n.syntaxhighlighter .value{color:#009900 !important;}\n.syntaxhighlighter .functions{color:#aaaaaa !important;}\n.syntaxhighlighter .constants{color:#96daff !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#d01d33 !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#ffc074 !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#4a8cdb !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#96daff !important;}\n.syntaxhighlighter .functions{font-weight:bold !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shThemeMDUltra.css",
    "content": ".syntaxhighlighter{background-color:#222222 !important;}\n.syntaxhighlighter .line.alt1{background-color:#222222 !important;}\n.syntaxhighlighter .line.alt2{background-color:#222222 !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#253e5a !important;}\n.syntaxhighlighter .line.highlighted.number{color:white !important;}\n.syntaxhighlighter table caption{color:lime !important;}\n.syntaxhighlighter .gutter{color:#38566f !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #435a5f !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#435a5f !important;color:#222222 !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#428bdd !important;background:black !important;border:1px solid #435a5f !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#428bdd !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:lime !important;}\n.syntaxhighlighter .toolbar{color:#aaaaff !important;background:#435a5f !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:#aaaaff !important;}\n.syntaxhighlighter .toolbar a:hover{color:#9ccff4 !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:lime !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#428bdd !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:lime !important;}\n.syntaxhighlighter .keyword{color:#aaaaff !important;}\n.syntaxhighlighter .preprocessor{color:#8aa6c1 !important;}\n.syntaxhighlighter .variable{color:aqua !important;}\n.syntaxhighlighter .value{color:#f7e741 !important;}\n.syntaxhighlighter .functions{color:#ff8000 !important;}\n.syntaxhighlighter .constants{color:yellow !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#aaaaff !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:red !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:yellow !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#ffaa3e !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shThemeMidnight.css",
    "content": ".syntaxhighlighter{background-color:#0f192a !important;}\n.syntaxhighlighter .line.alt1{background-color:#0f192a !important;}\n.syntaxhighlighter .line.alt2{background-color:#0f192a !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#253e5a !important;}\n.syntaxhighlighter .line.highlighted.number{color:#38566f !important;}\n.syntaxhighlighter table caption{color:#d1edff !important;}\n.syntaxhighlighter .gutter{color:#afafaf !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #435a5f !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#435a5f !important;color:#0f192a !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#428bdd !important;background:black !important;border:1px solid #435a5f !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#428bdd !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:#1dc116 !important;}\n.syntaxhighlighter .toolbar{color:#d1edff !important;background:#435a5f !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:#d1edff !important;}\n.syntaxhighlighter .toolbar a:hover{color:#8aa6c1 !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#d1edff !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#428bdd !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#1dc116 !important;}\n.syntaxhighlighter .keyword{color:#b43d3d !important;}\n.syntaxhighlighter .preprocessor{color:#8aa6c1 !important;}\n.syntaxhighlighter .variable{color:#ffaa3e !important;}\n.syntaxhighlighter .value{color:#f7e741 !important;}\n.syntaxhighlighter .functions{color:#ffaa3e !important;}\n.syntaxhighlighter .constants{color:#e0e8ff !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#b43d3d !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#f8bb00 !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:white !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#ffaa3e !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shThemeRDark.css",
    "content": ".syntaxhighlighter{background-color:#1b2426 !important;}\n.syntaxhighlighter .line.alt1{background-color:#1b2426 !important;}\n.syntaxhighlighter .line.alt2{background-color:#1b2426 !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#323e41 !important;}\n.syntaxhighlighter .line.highlighted.number{color:#b9bdb6 !important;}\n.syntaxhighlighter table caption{color:#b9bdb6 !important;}\n.syntaxhighlighter .gutter{color:#afafaf !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #435a5f !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#435a5f !important;color:#1b2426 !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:#5ba1cf !important;background:black !important;border:1px solid #435a5f !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:#5ba1cf !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:#5ce638 !important;}\n.syntaxhighlighter .toolbar{color:white !important;background:#435a5f !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:white !important;}\n.syntaxhighlighter .toolbar a:hover{color:#e0e8ff !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:#b9bdb6 !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#878a85 !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#5ce638 !important;}\n.syntaxhighlighter .keyword{color:#5ba1cf !important;}\n.syntaxhighlighter .preprocessor{color:#435a5f !important;}\n.syntaxhighlighter .variable{color:#ffaa3e !important;}\n.syntaxhighlighter .value{color:#009900 !important;}\n.syntaxhighlighter .functions{color:#ffaa3e !important;}\n.syntaxhighlighter .constants{color:#e0e8ff !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#5ba1cf !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:#e0e8ff !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:white !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:#ffaa3e !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/examples/styles/shThemeVisualStudio.css",
    "content": ".syntaxhighlighter{background-color:white !important;}\n.syntaxhighlighter .line.alt1{background-color:white !important;}\n.syntaxhighlighter .line.alt2{background-color:white !important;}\n.syntaxhighlighter .line.highlighted.alt1,.syntaxhighlighter .line.highlighted.alt2{background-color:#e0e0e0 !important;}\n.syntaxhighlighter .line.highlighted.number{color:black !important;}\n.syntaxhighlighter table caption{color:black !important;}\n.syntaxhighlighter .gutter{color:#afafaf !important;}\n.syntaxhighlighter .gutter .line{border-right:3px solid #6ce26c !important;}\n.syntaxhighlighter .gutter .line.highlighted{background-color:#6ce26c !important;color:white !important;}\n.syntaxhighlighter.printing .line .content{border:none !important;}\n.syntaxhighlighter.collapsed{overflow:visible !important;}\n.syntaxhighlighter.collapsed .toolbar{color:blue !important;background:white !important;border:1px solid #6ce26c !important;}\n.syntaxhighlighter.collapsed .toolbar a{color:blue !important;}\n.syntaxhighlighter.collapsed .toolbar a:hover{color:red !important;}\n.syntaxhighlighter .toolbar{color:white !important;background:#6ce26c !important;border:none !important;}\n.syntaxhighlighter .toolbar a{color:white !important;}\n.syntaxhighlighter .toolbar a:hover{color:black !important;}\n.syntaxhighlighter .plain,.syntaxhighlighter .plain a{color:black !important;}\n.syntaxhighlighter .comments,.syntaxhighlighter .comments a{color:#008200 !important;}\n.syntaxhighlighter .string,.syntaxhighlighter .string a{color:#d11010 !important;}\n.syntaxhighlighter .keyword{color:#006699 !important;}\n.syntaxhighlighter .preprocessor{color:gray !important;}\n.syntaxhighlighter .variable{color:#aa7700 !important;}\n.syntaxhighlighter .value{color:#009900 !important;}\n.syntaxhighlighter .functions{color:#ff1493 !important;}\n.syntaxhighlighter .constants{color:#0066cc !important;}\n.syntaxhighlighter .script{font-weight:bold !important;color:#006699 !important;background-color:none !important;}\n.syntaxhighlighter .color1,.syntaxhighlighter .color1 a{color:gray !important;}\n.syntaxhighlighter .color2,.syntaxhighlighter .color2 a{color:#ff1493 !important;}\n.syntaxhighlighter .color3,.syntaxhighlighter .color3 a{color:red !important;}\n.syntaxhighlighter .keyword{font-weight:bold !important;}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/extras/EasyPeasyICS.php",
    "content": "<?php\n/**\n * EasyPeasyICS Simple ICS/vCal data generator.\n * @author Marcus Bointon <phpmailer@synchromedia.co.uk>\n * @author Manuel Reinhard <manu@sprain.ch>\n *\n * Built with inspiration from\n * http://stackoverflow.com/questions/1463480/how-can-i-use-php-to-dynamically-publish-an-ical-file-to-be-read-by-google-calend/1464355#1464355\n * History:\n * 2010/12/17 - Manuel Reinhard - when it all started\n * 2014 PHPMailer project becomes maintainer\n */\n\n/**\n * Class EasyPeasyICS.\n * Simple ICS data generator\n * @package phpmailer\n * @subpackage easypeasyics\n */\nclass EasyPeasyICS\n{\n    /**\n     * The name of the calendar\n     * @var string\n     */\n    protected $calendarName;\n    /**\n     * The array of events to add to this calendar\n     * @var array\n     */\n    protected $events = array();\n\n    /**\n     * Constructor\n     * @param string $calendarName\n     */\n    public function __construct($calendarName = \"\")\n    {\n        $this->calendarName = $calendarName;\n    }\n\n    /**\n     * Add an event to this calendar.\n     * @param string $start The start date and time as a unix timestamp\n     * @param string $end The end date and time as a unix timestamp\n     * @param string $summary A summary or title for the event\n     * @param string $description A description of the event\n     * @param string $url A URL for the event\n     * @param string $uid A unique identifier for the event - generated automatically if not provided\n     * @return array An array of event details, including any generated UID\n     */\n    public function addEvent($start, $end, $summary = '', $description = '', $url = '', $uid = '')\n    {\n        if (empty($uid)) {\n            $uid = md5(uniqid(mt_rand(), true)) . '@EasyPeasyICS';\n        }\n        $event = array(\n            'start' => gmdate('Ymd', $start) . 'T' . gmdate('His', $start) . 'Z',\n            'end' => gmdate('Ymd', $end) . 'T' . gmdate('His', $end) . 'Z',\n            'summary' => $summary,\n            'description' => $description,\n            'url' => $url,\n            'uid' => $uid\n        );\n        $this->events[] = $event;\n        return $event;\n    }\n\n    /**\n     * @return array Get the array of events.\n     */\n    public function getEvents()\n    {\n        return $this->events;\n    }\n\n    /**\n     * Clear all events.\n     */\n    public function clearEvents()\n    {\n        $this->events = array();\n    }\n\n    /**\n     * Get the name of the calendar.\n     * @return string\n     */\n    public function getName()\n    {\n        return $this->calendarName;\n    }\n\n    /**\n     * Set the name of the calendar.\n     * @param $name\n     */\n    public function setName($name)\n    {\n        $this->calendarName = $name;\n    }\n\n    /**\n     * Render and optionally output a vcal string.\n     * @param bool $output Whether to output the calendar data directly (the default).\n     * @return string The complete rendered vlal\n     */\n    public function render($output = true)\n    {\n        //Add header\n        $ics = 'BEGIN:VCALENDAR\nMETHOD:PUBLISH\nVERSION:2.0\nX-WR-CALNAME:' . $this->calendarName . '\nPRODID:-//hacksw/handcal//NONSGML v1.0//EN';\n\n        //Add events\n        foreach ($this->events as $event) {\n            $ics .= '\nBEGIN:VEVENT\nUID:' . $event['uid'] . '\nDTSTAMP:' . gmdate('Ymd') . 'T' . gmdate('His') . 'Z\nDTSTART:' . $event['start'] . '\nDTEND:' . $event['end'] . '\nSUMMARY:' . str_replace(\"\\n\", \"\\\\n\", $event['summary']) . '\nDESCRIPTION:' . str_replace(\"\\n\", \"\\\\n\", $event['description']) . '\nURL;VALUE=URI:' . $event['url'] . '\nEND:VEVENT';\n        }\n\n        //Add footer\n        $ics .= '\nEND:VCALENDAR';\n\n        if ($output) {\n            //Output\n            $filename = $this->calendarName;\n            //Filename needs quoting if it contains spaces\n            if (strpos($filename, ' ') !== false) {\n                $filename = '\"'.$filename.'\"';\n            }\n            header('Content-type: text/calendar; charset=utf-8');\n            header('Content-Disposition: inline; filename=' . $filename . '.ics');\n            echo $ics;\n        }\n        return $ics;\n    }\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/extras/README.md",
    "content": "#PHPMailer Extras\n\nThese classes provide optional additional functions to PHPMailer.\n\nThese are not loaded by the PHPMailer autoloader, so in some cases you may need to `require` them yourself before using them.\n\n##EasyPeasyICS\n\nThis class was originally written by Manuel Reinhard and provides a simple means of generating ICS/vCal files that are used in sending calendar events. PHPMailer does not use it directly, but you can use it to generate content appropriate for placing in the `Ical` property of PHPMailer. The PHPMailer project is now its official home as Manuel has given permission for that and is no longer maintaining it himself.\n\n##htmlfilter\n\nThis class by Konstantin Riabitsev and Jim Jagielski implements HTML filtering to remove potentially malicious tags, such as `<script>` or `onclick=` attributes that can result in XSS attacks. This is a simple filter and is not as comprehensive as [HTMLawed](http://www.bioinformatics.org/phplabware/internal_utilities/htmLawed/) or [HTMLPurifier](http://htmlpurifier.org), but it's easier to use and considerably better than nothing! PHPMailer does not use it directly, but you may want to apply it to user-supplied HTML before using it as a message body.\n\n##NTLM_SASL_client\n\nThis class by Manuel Lemos (bundled with permission) adds the ability to authenticate with Microsoft Windows mail servers that use NTLM-based authentication. It is used by PHPMailer if you send via SMTP and set the `AuthType` property to `NTLM`; you will also need to use the `Realm` and `Workstation` properties. The original source is [here](http://www.phpclasses.org/browse/file/7495.html).\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/extras/htmlfilter.php",
    "content": "<?php\n/**\n * htmlfilter.inc\n * ---------------\n * This set of functions allows you to filter html in order to remove\n * any malicious tags from it. Useful in cases when you need to filter\n * user input for any cross-site-scripting attempts.\n *\n * Copyright (C) 2002-2004 by Duke University\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\t See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA\n * 02110-1301  USA\n *\n * @Author\tKonstantin Riabitsev <icon@linux.duke.edu>\n * @Author  Jim Jagielski <jim@jaguNET.com / jimjag@gmail.com>\n * @Version 1.1 ($Date$)\n */\n\n/**\n * This function returns the final tag out of the tag name, an array\n * of attributes, and the type of the tag. This function is called by\n * tln_sanitize internally.\n *\n * @param string $tagname the name of the tag.\n * @param array $attary the array of attributes and their values\n * @param integer $tagtype The type of the tag (see in comments).\n * @return string A string with the final tag representation.\n */\nfunction tln_tagprint($tagname, $attary, $tagtype)\n{\n    if ($tagtype == 2) {\n        $fulltag = '</' . $tagname . '>';\n    } else {\n        $fulltag = '<' . $tagname;\n        if (is_array($attary) && sizeof($attary)) {\n            $atts = array();\n            foreach($attary as $attname => $attvalue) {\n                array_push($atts, \"$attname=$attvalue\");\n            }\n            $fulltag .= ' ' . join(' ', $atts);\n        }\n        if ($tagtype == 3) {\n            $fulltag .= ' /';\n        }\n        $fulltag .= '>';\n    }\n    return $fulltag;\n}\n\n/**\n * A small helper function to use with array_walk. Modifies a by-ref\n * value and makes it lowercase.\n *\n * @param string $val a value passed by-ref.\n * @return\t\tvoid since it modifies a by-ref value.\n */\nfunction tln_casenormalize(&$val)\n{\n    $val = strtolower($val);\n}\n\n/**\n * This function skips any whitespace from the current position within\n * a string and to the next non-whitespace value.\n *\n * @param string $body the string\n * @param integer $offset the offset within the string where we should start\n *\t\t\t\t   looking for the next non-whitespace character.\n * @return integer          the location within the $body where the next\n *\t\t\t\t   non-whitespace char is located.\n */\nfunction tln_skipspace($body, $offset)\n{\n    preg_match('/^(\\s*)/s', substr($body, $offset), $matches);\n    if (sizeof($matches[1])) {\n        $count = strlen($matches[1]);\n        $offset += $count;\n    }\n    return $offset;\n}\n\n/**\n * This function looks for the next character within a string.\tIt's\n * really just a glorified \"strpos\", except it catches the failures\n * nicely.\n *\n * @param string $body   The string to look for needle in.\n * @param integer $offset Start looking from this position.\n * @param string $needle The character/string to look for.\n * @return integer           location of the next occurrence of the needle, or\n *\t\t\t\t   strlen($body) if needle wasn't found.\n */\nfunction tln_findnxstr($body, $offset, $needle)\n{\n    $pos = strpos($body, $needle, $offset);\n    if ($pos === false) {\n        $pos = strlen($body);\n    }\n    return $pos;\n}\n\n/**\n * This function takes a PCRE-style regexp and tries to match it\n * within the string.\n *\n * @param string $body   The string to look for needle in.\n * @param integer $offset Start looking from here.\n * @param string $reg       A PCRE-style regex to match.\n * @return array|boolean  Returns a false if no matches found, or an array\n *\t\t\t\t   with the following members:\n *\t\t\t\t   - integer with the location of the match within $body\n *\t\t\t\t   - string with whatever content between offset and the match\n *\t\t\t\t   - string with whatever it is we matched\n */\nfunction tln_findnxreg($body, $offset, $reg)\n{\n    $matches = array();\n    $retarr = array();\n    $preg_rule = '%^(.*?)(' . $reg . ')%s';\n    preg_match($preg_rule, substr($body, $offset), $matches);\n    if (!isset($matches[0]) || !$matches[0]) {\n        $retarr = false;\n    } else {\n        $retarr[0] = $offset + strlen($matches[1]);\n        $retarr[1] = $matches[1];\n        $retarr[2] = $matches[2];\n    }\n    return $retarr;\n}\n\n/**\n * This function looks for the next tag.\n *\n * @param string $body   String where to look for the next tag.\n * @param integer $offset Start looking from here.\n * @return array|boolean false if no more tags exist in the body, or\n *\t\t\t\t   an array with the following members:\n *\t\t\t\t   - string with the name of the tag\n *\t\t\t\t   - array with attributes and their values\n *\t\t\t\t   - integer with tag type (1, 2, or 3)\n *\t\t\t\t   - integer where the tag starts (starting \"<\")\n *\t\t\t\t   - integer where the tag ends (ending \">\")\n *\t\t\t\t   first three members will be false, if the tag is invalid.\n */\nfunction tln_getnxtag($body, $offset)\n{\n    if ($offset > strlen($body)) {\n        return false;\n    }\n    $lt = tln_findnxstr($body, $offset, '<');\n    if ($lt == strlen($body)) {\n        return false;\n    }\n    /**\n     * We are here:\n     * blah blah <tag attribute=\"value\">\n     * \\---------^\n     */\n    $pos = tln_skipspace($body, $lt + 1);\n    if ($pos >= strlen($body)) {\n        return array(false, false, false, $lt, strlen($body));\n    }\n    /**\n     * There are 3 kinds of tags:\n     * 1. Opening tag, e.g.:\n     *\t  <a href=\"blah\">\n     * 2. Closing tag, e.g.:\n     *\t  </a>\n     * 3. XHTML-style content-less tag, e.g.:\n     *\t  <img src=\"blah\"/>\n     */\n    switch (substr($body, $pos, 1)) {\n    case '/':\n        $tagtype = 2;\n        $pos++;\n        break;\n    case '!':\n        /**\n         * A comment or an SGML declaration.\n         */\n            if (substr($body, $pos + 1, 2) == '--') {\n            $gt = strpos($body, '-->', $pos);\n            if ($gt === false) {\n                $gt = strlen($body);\n            } else {\n                $gt += 2;\n            }\n            return array(false, false, false, $lt, $gt);\n        } else {\n            $gt = tln_findnxstr($body, $pos, '>');\n            return array(false, false, false, $lt, $gt);\n        }\n        break;\n    default:\n        /**\n         * Assume tagtype 1 for now. If it's type 3, we'll switch values\n         * later.\n         */\n        $tagtype = 1;\n        break;\n    }\n\n    /**\n     * Look for next [\\W-_], which will indicate the end of the tag name.\n     */\n    $regary = tln_findnxreg($body, $pos, '[^\\w\\-_]');\n    if ($regary == false) {\n        return array(false, false, false, $lt, strlen($body));\n    }\n    list($pos, $tagname, $match) = $regary;\n    $tagname = strtolower($tagname);\n\n    /**\n     * $match can be either of these:\n     * '>'\tindicating the end of the tag entirely.\n     * '\\s' indicating the end of the tag name.\n     * '/'\tindicating that this is type-3 xhtml tag.\n     *\n     * Whatever else we find there indicates an invalid tag.\n     */\n    switch ($match) {\n    case '/':\n        /**\n         * This is an xhtml-style tag with a closing / at the\n         * end, like so: <img src=\"blah\"/>. Check if it's followed\n         * by the closing bracket. If not, then this tag is invalid\n         */\n        if (substr($body, $pos, 2) == '/>') {\n            $pos++;\n            $tagtype = 3;\n        } else {\n            $gt = tln_findnxstr($body, $pos, '>');\n            $retary = array(false, false, false, $lt, $gt);\n            return $retary;\n        }\n            //intentional fall-through\n    case '>':\n        return array($tagname, false, $tagtype, $lt, $pos);\n        break;\n    default:\n        /**\n         * Check if it's whitespace\n         */\n        if (!preg_match('/\\s/', $match)) {\n            /**\n             * This is an invalid tag! Look for the next closing \">\".\n             */\n            $gt = tln_findnxstr($body, $lt, '>');\n            return array(false, false, false, $lt, $gt);\n        }\n        break;\n    }\n\n    /**\n     * At this point we're here:\n     * <tagname\t attribute='blah'>\n     * \\-------^\n     *\n     * At this point we loop in order to find all attributes.\n     */\n    $attary = array();\n\n    while ($pos <= strlen($body)) {\n        $pos = tln_skipspace($body, $pos);\n        if ($pos == strlen($body)) {\n            /**\n             * Non-closed tag.\n             */\n            return array(false, false, false, $lt, $pos);\n        }\n        /**\n         * See if we arrived at a \">\" or \"/>\", which means that we reached\n         * the end of the tag.\n         */\n        $matches = array();\n        if (preg_match('%^(\\s*)(>|/>)%s', substr($body, $pos), $matches)) {\n            /**\n             * Yep. So we did.\n             */\n            $pos += strlen($matches[1]);\n            if ($matches[2] == '/>') {\n                $tagtype = 3;\n                $pos++;\n            }\n            return array($tagname, $attary, $tagtype, $lt, $pos);\n        }\n\n        /**\n         * There are several types of attributes, with optional\n         * [:space:] between members.\n         * Type 1:\n         *\t attrname[:space:]=[:space:]'CDATA'\n         * Type 2:\n         *\t attrname[:space:]=[:space:]\"CDATA\"\n         * Type 3:\n         *\t attr[:space:]=[:space:]CDATA\n         * Type 4:\n         *\t attrname\n         *\n         * We leave types 1 and 2 the same, type 3 we check for\n         * '\"' and convert to \"&quot\" if needed, then wrap in\n         * double quotes. Type 4 we convert into:\n         * attrname=\"yes\".\n         */\n        $regary = tln_findnxreg($body, $pos, '[^\\w\\-_]');\n        if ($regary == false) {\n            /**\n             * Looks like body ended before the end of tag.\n             */\n            return array(false, false, false, $lt, strlen($body));\n        }\n        list($pos, $attname, $match) = $regary;\n        $attname = strtolower($attname);\n        /**\n         * We arrived at the end of attribute name. Several things possible\n         * here:\n         * '>'\tmeans the end of the tag and this is attribute type 4\n         * '/'\tif followed by '>' means the same thing as above\n         * '\\s' means a lot of things -- look what it's followed by.\n         *\t\tanything else means the attribute is invalid.\n         */\n        switch ($match) {\n        case '/':\n            /**\n             * This is an xhtml-style tag with a closing / at the\n             * end, like so: <img src=\"blah\"/>. Check if it's followed\n             * by the closing bracket. If not, then this tag is invalid\n             */\n            if (substr($body, $pos, 2) == '/>') {\n                $pos++;\n                $tagtype = 3;\n            } else {\n                $gt = tln_findnxstr($body, $pos, '>');\n                $retary = array(false, false, false, $lt, $gt);\n                return $retary;\n            }\n                //intentional fall-through\n        case '>':\n            $attary{$attname} = '\"yes\"';\n            return array($tagname, $attary, $tagtype, $lt, $pos);\n            break;\n        default:\n            /**\n             * Skip whitespace and see what we arrive at.\n             */\n            $pos = tln_skipspace($body, $pos);\n            $char = substr($body, $pos, 1);\n            /**\n             * Two things are valid here:\n             * '=' means this is attribute type 1 2 or 3.\n             * \\w means this was attribute type 4.\n             * anything else we ignore and re-loop. End of tag and\n             * invalid stuff will be caught by our checks at the beginning\n             * of the loop.\n             */\n            if ($char == '=') {\n                $pos++;\n                $pos = tln_skipspace($body, $pos);\n                /**\n                 * Here are 3 possibilities:\n                 * \"'\"\tattribute type 1\n                 * '\"'\tattribute type 2\n                 * everything else is the content of tag type 3\n                 */\n                $quot = substr($body, $pos, 1);\n                if ($quot == '\\'') {\n                        $regary = tln_findnxreg($body, $pos + 1, '\\'');\n                    if ($regary == false) {\n                        return array(false, false, false, $lt, strlen($body));\n                    }\n                    list($pos, $attval, $match) = $regary;\n                    $pos++;\n                    $attary{$attname} = '\\'' . $attval . '\\'';\n                } elseif ($quot == '\"') {\n                    $regary = tln_findnxreg($body, $pos + 1, '\\\"');\n                    if ($regary == false) {\n                        return array(false, false, false, $lt, strlen($body));\n                    }\n                    list($pos, $attval, $match) = $regary;\n                    $pos++;\n                            $attary{$attname} = '\"' . $attval . '\"';\n                } else {\n                    /**\n                     * These are hateful. Look for \\s, or >.\n                     */\n                    $regary = tln_findnxreg($body, $pos, '[\\s>]');\n                    if ($regary == false) {\n                        return array(false, false, false, $lt, strlen($body));\n                    }\n                    list($pos, $attval, $match) = $regary;\n                    /**\n                     * If it's \">\" it will be caught at the top.\n                     */\n                    $attval = preg_replace('/\\\"/s', '&quot;', $attval);\n                    $attary{$attname} = '\"' . $attval . '\"';\n                }\n            } elseif (preg_match('|[\\w/>]|', $char)) {\n                /**\n                 * That was attribute type 4.\n                 */\n                $attary{$attname} = '\"yes\"';\n            } else {\n                /**\n                 * An illegal character. Find next '>' and return.\n                 */\n                $gt = tln_findnxstr($body, $pos, '>');\n                return array(false, false, false, $lt, $gt);\n            }\n            break;\n        }\n    }\n    /**\n     * The fact that we got here indicates that the tag end was never\n     * found. Return invalid tag indication so it gets stripped.\n     */\n    return array(false, false, false, $lt, strlen($body));\n}\n\n/**\n * Translates entities into literal values so they can be checked.\n *\n * @param string $attvalue the by-ref value to check.\n * @param string $regex    the regular expression to check against.\n * @param boolean $hex        whether the entities are hexadecimal.\n * @return boolean            True or False depending on whether there were matches.\n */\nfunction tln_deent(&$attvalue, $regex, $hex = false)\n{\n    preg_match_all($regex, $attvalue, $matches);\n    if (is_array($matches) && sizeof($matches[0]) > 0) {\n        $repl = array();\n        for ($i = 0; $i < sizeof($matches[0]); $i++) {\n            $numval = $matches[1][$i];\n            if ($hex) {\n                $numval = hexdec($numval);\n            }\n            $repl{$matches[0][$i]} = chr($numval);\n        }\n        $attvalue = strtr($attvalue, $repl);\n        return true;\n    } else {\n        return false;\n    }\n}\n\n/**\n * This function checks attribute values for entity-encoded values\n * and returns them translated into 8-bit strings so we can run\n * checks on them.\n *\n * @param string $attvalue A string to run entity check against.\n */\nfunction tln_defang(&$attvalue)\n{\n    /**\n     * Skip this if there aren't ampersands or backslashes.\n     */\n    if (strpos($attvalue, '&') === false\n        && strpos($attvalue, '\\\\') === false\n    ) {\n        return;\n    }\n    do {\n        $m = false;\n        $m = $m || tln_deent($attvalue, '/\\&#0*(\\d+);*/s');\n        $m = $m || tln_deent($attvalue, '/\\&#x0*((\\d|[a-f])+);*/si', true);\n        $m = $m || tln_deent($attvalue, '/\\\\\\\\(\\d+)/s', true);\n    } while ($m == true);\n    $attvalue = stripslashes($attvalue);\n}\n\n/**\n * Kill any tabs, newlines, or carriage returns. Our friends the\n * makers of the browser with 95% market value decided that it'd\n * be funny to make \"java[tab]script\" be just as good as \"javascript\".\n *\n * @param string $attvalue     The attribute value before extraneous spaces removed.\n */\nfunction tln_unspace(&$attvalue)\n{\n    if (strcspn($attvalue, \"\\t\\r\\n\\0 \") != strlen($attvalue)) {\n        $attvalue = str_replace(\n            array(\"\\t\", \"\\r\", \"\\n\", \"\\0\", \" \"),\n            array('', '', '', '', ''),\n            $attvalue\n        );\n    }\n}\n\n/**\n * This function runs various checks against the attributes.\n *\n * @param string $tagname            String with the name of the tag.\n * @param array $attary            Array with all tag attributes.\n * @param array $rm_attnames        See description for tln_sanitize\n * @param array $bad_attvals        See description for tln_sanitize\n * @param array $add_attr_to_tag See description for tln_sanitize\n * @param string $trans_image_path\n * @param boolean $block_external_images\n * @return array with modified attributes.\n */\nfunction tln_fixatts(\n    $tagname,\n    $attary,\n    $rm_attnames,\n    $bad_attvals,\n    $add_attr_to_tag,\n    $trans_image_path,\n    $block_external_images\n) {\n    foreach($attary as $attname => $attvalue) {\n        /**\n         * See if this attribute should be removed.\n         */\n        foreach ($rm_attnames as $matchtag => $matchattrs) {\n            if (preg_match($matchtag, $tagname)) {\n                foreach ($matchattrs as $matchattr) {\n                    if (preg_match($matchattr, $attname)) {\n                        unset($attary{$attname});\n                        continue;\n                    }\n                }\n            }\n        }\n        /**\n         * Remove any backslashes, entities, or extraneous whitespace.\n         */\n        $oldattvalue = $attvalue;\n        tln_defang($attvalue);\n        if ($attname == 'style' && $attvalue !== $oldattvalue) {\n            $attvalue = \"idiocy\";\n            $attary{$attname} = $attvalue;\n        }\n        tln_unspace($attvalue);\n\n        /**\n         * Now let's run checks on the attvalues.\n         * I don't expect anyone to comprehend this. If you do,\n         * get in touch with me so I can drive to where you live and\n         * shake your hand personally. :)\n         */\n        foreach ($bad_attvals as $matchtag => $matchattrs) {\n            if (preg_match($matchtag, $tagname)) {\n                foreach ($matchattrs as $matchattr => $valary) {\n                    if (preg_match($matchattr, $attname)) {\n                        /**\n                         * There are two arrays in valary.\n                         * First is matches.\n                         * Second one is replacements\n                         */\n                        list($valmatch, $valrepl) = $valary;\n                        $newvalue = preg_replace($valmatch, $valrepl, $attvalue);\n                        if ($newvalue != $attvalue) {\n                            $attary{$attname} = $newvalue;\n                            $attvalue = $newvalue;\n                        }\n                    }\n                }\n            }\n        }\n        if ($attname == 'style') {\n            if (preg_match('/[\\0-\\37\\200-\\377]+/', $attvalue)) {\n                $attary{$attname} = '\"disallowed character\"';\n            }\n            preg_match_all(\"/url\\s*\\((.+)\\)/si\", $attvalue, $aMatch);\n            if (count($aMatch)) {\n                foreach($aMatch[1] as $sMatch) {\n                    $urlvalue = $sMatch;\n                    tln_fixurl($attname, $urlvalue, $trans_image_path, $block_external_images);\n                    $attary{$attname} = str_replace($sMatch, $urlvalue, $attvalue);\n                }\n            }\n        }\n     }\n    /**\n     * See if we need to append any attributes to this tag.\n     */\n    foreach ($add_attr_to_tag as $matchtag => $addattary) {\n        if (preg_match($matchtag, $tagname)) {\n            $attary = array_merge($attary, $addattary);\n        }\n    }\n    return $attary;\n}\n\nfunction tln_fixurl($attname, &$attvalue, $trans_image_path, $block_external_images)\n{\n    $sQuote = '\"';\n    $attvalue = trim($attvalue);\n    if ($attvalue && ($attvalue[0] =='\"'|| $attvalue[0] == \"'\")) {\n        // remove the double quotes\n        $sQuote = $attvalue[0];\n        $attvalue = trim(substr($attvalue,1,-1));\n    }\n\n    /**\n     * Replace empty src tags with the blank image.  src is only used\n     * for frames, images, and image inputs.  Doing a replace should\n     * not affect them working as should be, however it will stop\n     * IE from being kicked off when src for img tags are not set\n     */\n    if ($attvalue == '') {\n        $attvalue = $sQuote . $trans_image_path . $sQuote;\n    } else {\n        // first, disallow 8 bit characters and control characters\n        if (preg_match('/[\\0-\\37\\200-\\377]+/',$attvalue)) {\n            switch ($attname) {\n                case 'href':\n                    $attvalue = $sQuote . 'http://invalid-stuff-detected.example.com' . $sQuote;\n                    break;\n                default:\n                    $attvalue = $sQuote . $trans_image_path . $sQuote;\n                    break;\n            }\n        } else {\n            $aUrl = parse_url($attvalue);\n            if (isset($aUrl['scheme'])) {\n                switch(strtolower($aUrl['scheme'])) {\n                    case 'mailto':\n                    case 'http':\n                    case 'https':\n                    case 'ftp':\n                        if ($attname != 'href') {\n                            if ($block_external_images == true) {\n                                $attvalue = $sQuote . $trans_image_path . $sQuote;\n                            } else {\n                                if (!isset($aUrl['path'])) {\n                                    $attvalue = $sQuote . $trans_image_path . $sQuote;\n                                }\n                            }\n                        } else {\n                            $attvalue = $sQuote . $attvalue . $sQuote;\n                        }\n                        break;\n                    case 'outbind':\n                        $attvalue = $sQuote . $attvalue . $sQuote;\n                        break;\n                    case 'cid':\n                        $attvalue = $sQuote . $attvalue . $sQuote;\n                        break;\n                    default:\n                        $attvalue = $sQuote . $trans_image_path . $sQuote;\n                        break;\n                }\n            } else {\n                if (!isset($aUrl['path']) || $aUrl['path'] != $trans_image_path) {\n                    $$attvalue = $sQuote . $trans_image_path . $sQuote;\n                }\n            }\n        }\n    }\n}\n\nfunction tln_fixstyle($body, $pos, $trans_image_path, $block_external_images)\n{\n    // workaround for </style> in between comments\n    $content = '';\n    $sToken = '';\n    $bSucces = false;\n    $bEndTag = false;\n    for ($i=$pos,$iCount=strlen($body);$i<$iCount;++$i) {\n        $char = $body{$i};\n        switch ($char) {\n            case '<':\n                $sToken = $char;\n                break;\n            case '/':\n                 if ($sToken == '<') {\n                    $sToken .= $char;\n                    $bEndTag = true;\n                 } else {\n                    $content .= $char;\n                 }\n                 break;\n            case '>':\n                 if ($bEndTag) {\n                    $sToken .= $char;\n                    if (preg_match('/\\<\\/\\s*style\\s*\\>/i',$sToken,$aMatch)) {\n                        $newpos = $i + 1;\n                        $bSucces = true;\n                        break 2;\n                    } else {\n                        $content .= $sToken;\n                    }\n                    $bEndTag = false;\n                 } else {\n                    $content .= $char;\n                 }\n                 break;\n            case '!':\n                if ($sToken == '<') {\n                    // possible comment\n                    if (isset($body{$i+2}) && substr($body,$i,3) == '!--') {\n                        $i = strpos($body,'-->',$i+3);\n                        if ($i === false) { // no end comment\n                            $i = strlen($body);\n                        }\n                        $sToken = '';\n                    }\n                } else {\n                    $content .= $char;\n                }\n                break;\n            default:\n                if ($bEndTag) {\n                    $sToken .= $char;\n                } else {\n                    $content .= $char;\n                }\n                break;\n        }\n    }\n    if ($bSucces == FALSE){\n        return array(FALSE, strlen($body));\n    }\n\n\n\n    /**\n     * First look for general BODY style declaration, which would be\n     * like so:\n     * body {background: blah-blah}\n     * and change it to .bodyclass so we can just assign it to a <div>\n     */\n    $content = preg_replace(\"|body(\\s*\\{.*?\\})|si\", \".bodyclass\\\\1\", $content);\n\n    /**\n    * Fix url('blah') declarations.\n    */\n    //   $content = preg_replace(\"|url\\s*\\(\\s*([\\'\\\"])\\s*\\S+script\\s*:.*?([\\'\\\"])\\s*\\)|si\",\n    //                           \"url(\\\\1$trans_image_path\\\\2)\", $content);\n\n    // first check for 8bit sequences and disallowed control characters\n    if (preg_match('/[\\16-\\37\\200-\\377]+/',$content)) {\n        $content = '<!-- style block removed by html filter due to presence of 8bit characters -->';\n        return array($content, $newpos);\n    }\n\n    // remove @import line\n    $content = preg_replace(\"/^\\s*(@import.*)$/mi\",\"\\n<!-- @import rules forbidden -->\\n\",$content);\n\n    $content = preg_replace(\"/(\\\\\\\\)?u(\\\\\\\\)?r(\\\\\\\\)?l(\\\\\\\\)?/i\", 'url', $content);\n    preg_match_all(\"/url\\s*\\((.+)\\)/si\",$content,$aMatch);\n    if (count($aMatch)) {\n        $aValue = $aReplace = array();\n        foreach($aMatch[1] as $sMatch) {\n            // url value\n            $urlvalue = $sMatch;\n            tln_fixurl('style',$urlvalue, $trans_image_path, $block_external_images);\n            $aValue[] = $sMatch;\n            $aReplace[] = $urlvalue;\n        }\n        $content = str_replace($aValue,$aReplace,$content);\n    }\n\n    /**\n     * Remove any backslashes, entities, and extraneous whitespace.\n     */\n    $contentTemp = $content;\n    tln_defang($contentTemp);\n    tln_unspace($contentTemp);\n\n    $match   = array('/\\/\\*.*\\*\\//',\n                    '/expression/i',\n                    '/behaviou*r/i',\n                    '/binding/i',\n                    '/include-source/i',\n                    '/javascript/i',\n                    '/script/i',\n                    '/position/i');\n    $replace = array('','idiocy', 'idiocy', 'idiocy', 'idiocy', 'idiocy', 'idiocy', '');\n    $contentNew = preg_replace($match, $replace, $contentTemp);\n    if ($contentNew !== $contentTemp) {\n        $content = $contentNew;\n    }\n    return array($content, $newpos);\n}\n\nfunction tln_body2div($attary, $trans_image_path)\n{\n    $divattary = array('class' => \"'bodyclass'\");\n    $text = '#000000';\n    $has_bgc_stl = $has_txt_stl = false;\n    $styledef = '';\n    if (is_array($attary) && sizeof($attary) > 0){\n        foreach ($attary as $attname=>$attvalue){\n            $quotchar = substr($attvalue, 0, 1);\n            $attvalue = str_replace($quotchar, \"\", $attvalue);\n            switch ($attname){\n                case 'background':\n                    $styledef .= \"background-image: url('$trans_image_path'); \";\n                    break;\n                case 'bgcolor':\n                    $has_bgc_stl = true;\n                    $styledef .= \"background-color: $attvalue; \";\n                    break;\n                case 'text':\n                    $has_txt_stl = true;\n                    $styledef .= \"color: $attvalue; \";\n                    break;\n            }\n        }\n        // Outlook defines a white bgcolor and no text color. This can lead to\n        // white text on a white bg with certain themes.\n        if ($has_bgc_stl && !$has_txt_stl) {\n            $styledef .= \"color: $text; \";\n        }\n        if (strlen($styledef) > 0){\n            $divattary{\"style\"} = \"\\\"$styledef\\\"\";\n        }\n    }\n    return $divattary;\n}\n\n/**\n *\n * @param string $body                    The HTML you wish to filter\n * @param array $tag_list                see description above\n * @param array $rm_tags_with_content see description above\n * @param array $self_closing_tags    see description above\n * @param boolean $force_tag_closing    see description above\n * @param array $rm_attnames            see description above\n * @param array $bad_attvals            see description above\n * @param array $add_attr_to_tag        see description above\n * @param string $trans_image_path\n * @param boolean $block_external_images\n\n * @return string                       Sanitized html safe to show on your pages.\n */\nfunction tln_sanitize(\n    $body,\n    $tag_list,\n    $rm_tags_with_content,\n    $self_closing_tags,\n    $force_tag_closing,\n    $rm_attnames,\n    $bad_attvals,\n    $add_attr_to_tag,\n    $trans_image_path,\n    $block_external_images\n) {\n    /**\n     * Normalize rm_tags and rm_tags_with_content.\n     */\n    $rm_tags = array_shift($tag_list);\n    @array_walk($tag_list, 'tln_casenormalize');\n    @array_walk($rm_tags_with_content, 'tln_casenormalize');\n    @array_walk($self_closing_tags, 'tln_casenormalize');\n    /**\n     * See if tag_list is of tags to remove or tags to allow.\n     * false  means remove these tags\n     * true\t  means allow these tags\n     */\n    $curpos = 0;\n    $open_tags = array();\n    $trusted = \"<!-- begin tln_sanitized html -->\\n\";\n    $skip_content = false;\n    /**\n     * Take care of netscape's stupid javascript entities like\n     * &{alert('boo')};\n     */\n    $body = preg_replace('/&(\\{.*?\\};)/si', '&amp;\\\\1', $body);\n    while (($curtag = tln_getnxtag($body, $curpos)) != false) {\n        list($tagname, $attary, $tagtype, $lt, $gt) = $curtag;\n        $free_content = substr($body, $curpos, $lt-$curpos);\n        /**\n         * Take care of <style>\n         */\n        if ($tagname == \"style\" && $tagtype == 1){\n            list($free_content, $curpos) =\n                tln_fixstyle($body, $gt+1, $trans_image_path, $block_external_images);\n            if ($free_content != FALSE){\n                if ( !empty($attary) ) {\n                    $attary = tln_fixatts($tagname,\n                                         $attary,\n                                         $rm_attnames,\n                                         $bad_attvals,\n                                         $add_attr_to_tag,\n                                         $trans_image_path,\n                                         $block_external_images\n                                         );\n                }\n                $trusted .= tln_tagprint($tagname, $attary, $tagtype);\n                $trusted .= $free_content;\n                $trusted .= tln_tagprint($tagname, null, 2);\n            }\n            continue;\n        }\n        if ($skip_content == false){\n            $trusted .= $free_content;\n        }\n        if ($tagname != false) {\n            if ($tagtype == 2) {\n                if ($skip_content == $tagname) {\n                    /**\n                     * Got to the end of tag we needed to remove.\n                     */\n                    $tagname = false;\n                    $skip_content = false;\n                } else {\n                    if ($skip_content == false) {\n                        if ($tagname == \"body\") {\n                            $tagname = \"div\";\n                        }\n                        if (isset($open_tags{$tagname}) &&\n                            $open_tags{$tagname} > 0\n                        ) {\n                            $open_tags{$tagname}--;\n                        } else {\n                            $tagname = false;\n                        }\n                    }\n                }\n            } else {\n                /**\n                 * $rm_tags_with_content\n                 */\n                if ($skip_content == false) {\n                    /**\n                     * See if this is a self-closing type and change\n                     * tagtype appropriately.\n                     */\n                    if ($tagtype == 1\n                        && in_array($tagname, $self_closing_tags)\n                    ) {\n                        $tagtype = 3;\n                    }\n                    /**\n                     * See if we should skip this tag and any content\n                     * inside it.\n                     */\n                    if ($tagtype == 1\n                        && in_array($tagname, $rm_tags_with_content)\n                    ) {\n                        $skip_content = $tagname;\n                    } else {\n                        if (($rm_tags == false\n                             && in_array($tagname, $tag_list)) ||\n                            ($rm_tags == true\n                                && !in_array($tagname, $tag_list))\n                        ) {\n                            $tagname = false;\n                        } else {\n                            /**\n                             * Convert body into div.\n                             */\n                            if ($tagname == \"body\"){\n                                $tagname = \"div\";\n                                $attary = tln_body2div($attary, $trans_image_path);\n                            }\n                            if ($tagtype == 1) {\n                                if (isset($open_tags{$tagname})) {\n                                    $open_tags{$tagname}++;\n                                } else {\n                                    $open_tags{$tagname} = 1;\n                                }\n                            }\n                            /**\n                             * This is where we run other checks.\n                             */\n                            if (is_array($attary) && sizeof($attary) > 0) {\n                                $attary = tln_fixatts(\n                                    $tagname,\n                                    $attary,\n                                    $rm_attnames,\n                                    $bad_attvals,\n                                    $add_attr_to_tag,\n                                    $trans_image_path,\n                                    $block_external_images\n                                );\n                            }\n                        }\n                    }\n                }\n            }\n            if ($tagname != false && $skip_content == false) {\n                $trusted .= tln_tagprint($tagname, $attary, $tagtype);\n            }\n        }\n        $curpos = $gt + 1;\n    }\n    $trusted .= substr($body, $curpos, strlen($body) - $curpos);\n    if ($force_tag_closing == true) {\n        foreach ($open_tags as $tagname => $opentimes) {\n            while ($opentimes > 0) {\n                $trusted .= '</' . $tagname . '>';\n                $opentimes--;\n            }\n        }\n        $trusted .= \"\\n\";\n    }\n    $trusted .= \"<!-- end tln_sanitized html -->\\n\";\n    return $trusted;\n}\n\n//\n// Use the nifty htmlfilter library\n//\n\n\nfunction HTMLFilter($body, $trans_image_path, $block_external_images = false)\n{\n\n    $tag_list = array(\n        false,\n        \"object\",\n        \"meta\",\n        \"html\",\n        \"head\",\n        \"base\",\n        \"link\",\n        \"frame\",\n        \"iframe\",\n        \"plaintext\",\n        \"marquee\"\n    );\n\n    $rm_tags_with_content = array(\n        \"script\",\n        \"applet\",\n        \"embed\",\n        \"title\",\n        \"frameset\",\n        \"xmp\",\n        \"xml\"\n    );\n\n    $self_closing_tags =  array(\n        \"img\",\n        \"br\",\n        \"hr\",\n        \"input\",\n        \"outbind\"\n    );\n\n    $force_tag_closing = true;\n\n    $rm_attnames = array(\n        \"/.*/\" =>\n            array(\n                // \"/target/i\",\n                \"/^on.*/i\",\n                \"/^dynsrc/i\",\n                \"/^data.*/i\",\n                \"/^lowsrc.*/i\"\n            )\n    );\n\n    $bad_attvals = array(\n        \"/.*/\" =>\n        array(\n            \"/^src|background/i\" =>\n            array(\n                array(\n                    '/^([\\'\"])\\s*\\S+script\\s*:.*([\\'\"])/si',\n                    '/^([\\'\"])\\s*mocha\\s*:*.*([\\'\"])/si',\n                    '/^([\\'\"])\\s*about\\s*:.*([\\'\"])/si'\n                ),\n                array(\n                    \"\\\\1$trans_image_path\\\\2\",\n                    \"\\\\1$trans_image_path\\\\2\",\n                    \"\\\\1$trans_image_path\\\\2\"\n                )\n            ),\n            \"/^href|action/i\" =>\n            array(\n                array(\n                    '/^([\\'\"])\\s*\\S+script\\s*:.*([\\'\"])/si',\n                    '/^([\\'\"])\\s*mocha\\s*:*.*([\\'\"])/si',\n                    '/^([\\'\"])\\s*about\\s*:.*([\\'\"])/si'\n                ),\n                array(\n                    \"\\\\1#\\\\1\",\n                    \"\\\\1#\\\\1\",\n                    \"\\\\1#\\\\1\"\n                )\n            ),\n            \"/^style/i\" =>\n            array(\n                array(\n                    \"/\\/\\*.*\\*\\//\",\n                    \"/expression/i\",\n                    \"/binding/i\",\n                    \"/behaviou*r/i\",\n                    \"/include-source/i\",\n                    '/position\\s*:/i',\n                    '/(\\\\\\\\)?u(\\\\\\\\)?r(\\\\\\\\)?l(\\\\\\\\)?/i',\n                    '/url\\s*\\(\\s*([\\'\"])\\s*\\S+script\\s*:.*([\\'\"])\\s*\\)/si',\n                    '/url\\s*\\(\\s*([\\'\"])\\s*mocha\\s*:.*([\\'\"])\\s*\\)/si',\n                    '/url\\s*\\(\\s*([\\'\"])\\s*about\\s*:.*([\\'\"])\\s*\\)/si',\n                    '/(.*)\\s*:\\s*url\\s*\\(\\s*([\\'\"]*)\\s*\\S+script\\s*:.*([\\'\"]*)\\s*\\)/si'\n                ),\n                array(\n                    \"\",\n                    \"idiocy\",\n                    \"idiocy\",\n                    \"idiocy\",\n                    \"idiocy\",\n                    \"idiocy\",\n                    \"url\",\n                    \"url(\\\\1#\\\\1)\",\n                    \"url(\\\\1#\\\\1)\",\n                    \"url(\\\\1#\\\\1)\",\n                    \"\\\\1:url(\\\\2#\\\\3)\"\n                )\n            )\n        )\n    );\n\n    if ($block_external_images) {\n        array_push(\n            $bad_attvals{'/.*/'}{'/^src|background/i'}[0],\n            '/^([\\'\\\"])\\s*https*:.*([\\'\\\"])/si'\n        );\n        array_push(\n            $bad_attvals{'/.*/'}{'/^src|background/i'}[1],\n            \"\\\\1$trans_image_path\\\\1\"\n        );\n        array_push(\n            $bad_attvals{'/.*/'}{'/^style/i'}[0],\n            '/url\\(([\\'\\\"])\\s*https*:.*([\\'\\\"])\\)/si'\n        );\n        array_push(\n            $bad_attvals{'/.*/'}{'/^style/i'}[1],\n            \"url(\\\\1$trans_image_path\\\\1)\"\n        );\n    }\n\n    $add_attr_to_tag = array(\n        \"/^a$/i\" =>\n            array('target' => '\"_blank\"')\n    );\n\n    $trusted = tln_sanitize(\n        $body,\n        $tag_list,\n        $rm_tags_with_content,\n        $self_closing_tags,\n        $force_tag_closing,\n        $rm_attnames,\n        $bad_attvals,\n        $add_attr_to_tag,\n        $trans_image_path,\n        $block_external_images\n    );\n    return $trusted;\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/extras/ntlm_sasl_client.php",
    "content": "<?php\n/*\n * ntlm_sasl_client.php\n *\n * @(#) $Id: ntlm_sasl_client.php,v 1.3 2004/11/17 08:00:37 mlemos Exp $\n *\n */\n\ndefine(\"SASL_NTLM_STATE_START\", 0);\ndefine(\"SASL_NTLM_STATE_IDENTIFY_DOMAIN\", 1);\ndefine(\"SASL_NTLM_STATE_RESPOND_CHALLENGE\", 2);\ndefine(\"SASL_NTLM_STATE_DONE\", 3);\ndefine(\"SASL_FAIL\", -1);\ndefine(\"SASL_CONTINUE\", 1);\n\nclass ntlm_sasl_client_class\n{\n    public $credentials = array();\n    public $state = SASL_NTLM_STATE_START;\n\n    public function initialize(&$client)\n    {\n        if (!function_exists($function = \"mcrypt_encrypt\")\n            || !function_exists($function = \"mhash\")\n        ) {\n            $extensions = array(\n                \"mcrypt_encrypt\" => \"mcrypt\",\n                \"mhash\" => \"mhash\"\n            );\n            $client->error = \"the extension \" . $extensions[$function] .\n                \" required by the NTLM SASL client class is not available in this PHP configuration\";\n            return (0);\n        }\n        return (1);\n    }\n\n    public function ASCIIToUnicode($ascii)\n    {\n        for ($unicode = \"\", $a = 0; $a < strlen($ascii); $a++) {\n            $unicode .= substr($ascii, $a, 1) . chr(0);\n        }\n        return ($unicode);\n    }\n\n    public function typeMsg1($domain, $workstation)\n    {\n        $domain_length = strlen($domain);\n        $workstation_length = strlen($workstation);\n        $workstation_offset = 32;\n        $domain_offset = $workstation_offset + $workstation_length;\n        return (\n            \"NTLMSSP\\0\" .\n            \"\\x01\\x00\\x00\\x00\" .\n            \"\\x07\\x32\\x00\\x00\" .\n            pack(\"v\", $domain_length) .\n            pack(\"v\", $domain_length) .\n            pack(\"V\", $domain_offset) .\n            pack(\"v\", $workstation_length) .\n            pack(\"v\", $workstation_length) .\n            pack(\"V\", $workstation_offset) .\n            $workstation .\n            $domain\n        );\n    }\n\n    public function NTLMResponse($challenge, $password)\n    {\n        $unicode = $this->ASCIIToUnicode($password);\n        $md4 = mhash(MHASH_MD4, $unicode);\n        $padded = $md4 . str_repeat(chr(0), 21 - strlen($md4));\n        $iv_size = mcrypt_get_iv_size(MCRYPT_DES, MCRYPT_MODE_ECB);\n        $iv = mcrypt_create_iv($iv_size, MCRYPT_RAND);\n        for ($response = \"\", $third = 0; $third < 21; $third += 7) {\n            for ($packed = \"\", $p = $third; $p < $third + 7; $p++) {\n                $packed .= str_pad(decbin(ord(substr($padded, $p, 1))), 8, \"0\", STR_PAD_LEFT);\n            }\n            for ($key = \"\", $p = 0; $p < strlen($packed); $p += 7) {\n                $s = substr($packed, $p, 7);\n                $b = $s . ((substr_count($s, \"1\") % 2) ? \"0\" : \"1\");\n                $key .= chr(bindec($b));\n            }\n            $ciphertext = mcrypt_encrypt(MCRYPT_DES, $key, $challenge, MCRYPT_MODE_ECB, $iv);\n            $response .= $ciphertext;\n        }\n        return $response;\n    }\n\n    public function typeMsg3($ntlm_response, $user, $domain, $workstation)\n    {\n        $domain_unicode = $this->ASCIIToUnicode($domain);\n        $domain_length = strlen($domain_unicode);\n        $domain_offset = 64;\n        $user_unicode = $this->ASCIIToUnicode($user);\n        $user_length = strlen($user_unicode);\n        $user_offset = $domain_offset + $domain_length;\n        $workstation_unicode = $this->ASCIIToUnicode($workstation);\n        $workstation_length = strlen($workstation_unicode);\n        $workstation_offset = $user_offset + $user_length;\n        $lm = \"\";\n        $lm_length = strlen($lm);\n        $lm_offset = $workstation_offset + $workstation_length;\n        $ntlm = $ntlm_response;\n        $ntlm_length = strlen($ntlm);\n        $ntlm_offset = $lm_offset + $lm_length;\n        $session = \"\";\n        $session_length = strlen($session);\n        $session_offset = $ntlm_offset + $ntlm_length;\n        return (\n            \"NTLMSSP\\0\" .\n            \"\\x03\\x00\\x00\\x00\" .\n            pack(\"v\", $lm_length) .\n            pack(\"v\", $lm_length) .\n            pack(\"V\", $lm_offset) .\n            pack(\"v\", $ntlm_length) .\n            pack(\"v\", $ntlm_length) .\n            pack(\"V\", $ntlm_offset) .\n            pack(\"v\", $domain_length) .\n            pack(\"v\", $domain_length) .\n            pack(\"V\", $domain_offset) .\n            pack(\"v\", $user_length) .\n            pack(\"v\", $user_length) .\n            pack(\"V\", $user_offset) .\n            pack(\"v\", $workstation_length) .\n            pack(\"v\", $workstation_length) .\n            pack(\"V\", $workstation_offset) .\n            pack(\"v\", $session_length) .\n            pack(\"v\", $session_length) .\n            pack(\"V\", $session_offset) .\n            \"\\x01\\x02\\x00\\x00\" .\n            $domain_unicode .\n            $user_unicode .\n            $workstation_unicode .\n            $lm .\n            $ntlm\n        );\n    }\n\n    public function start(&$client, &$message, &$interactions)\n    {\n        if ($this->state != SASL_NTLM_STATE_START) {\n            $client->error = \"NTLM authentication state is not at the start\";\n            return (SASL_FAIL);\n        }\n        $this->credentials = array(\n            \"user\" => \"\",\n            \"password\" => \"\",\n            \"realm\" => \"\",\n            \"workstation\" => \"\"\n        );\n        $defaults = array();\n        $status = $client->GetCredentials($this->credentials, $defaults, $interactions);\n        if ($status == SASL_CONTINUE) {\n            $this->state = SASL_NTLM_STATE_IDENTIFY_DOMAIN;\n        }\n        unset($message);\n        return ($status);\n    }\n\n    public function step(&$client, $response, &$message, &$interactions)\n    {\n        switch ($this->state) {\n            case SASL_NTLM_STATE_IDENTIFY_DOMAIN:\n                $message = $this->typeMsg1($this->credentials[\"realm\"], $this->credentials[\"workstation\"]);\n                $this->state = SASL_NTLM_STATE_RESPOND_CHALLENGE;\n                break;\n            case SASL_NTLM_STATE_RESPOND_CHALLENGE:\n                $ntlm_response = $this->NTLMResponse(substr($response, 24, 8), $this->credentials[\"password\"]);\n                $message = $this->typeMsg3(\n                    $ntlm_response,\n                    $this->credentials[\"user\"],\n                    $this->credentials[\"realm\"],\n                    $this->credentials[\"workstation\"]\n                );\n                $this->state = SASL_NTLM_STATE_DONE;\n                break;\n            case SASL_NTLM_STATE_DONE:\n                $client->error = \"NTLM authentication was finished without success\";\n                return (SASL_FAIL);\n            default:\n                $client->error = \"invalid NTLM authentication step state\";\n                return (SASL_FAIL);\n        }\n        return (SASL_CONTINUE);\n    }\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/get_oauth_token.php",
    "content": "<?php\n/**\n * Get an OAuth2 token from Google.\n * * Install this script on your server so that it's accessible\n * as [https/http]://<yourdomain>/<folder>/get_oauth_token.php\n * e.g.: http://localhost/phpmail/get_oauth_token.php\n * * Ensure dependencies are installed with 'composer install'\n * * Set up an app in your Google developer console\n * * Set the script address as the app's redirect URL\n * If no refresh token is obtained when running this file, revoke access to your app\n * using link: https://accounts.google.com/b/0/IssuedAuthSubTokens and run the script again.\n * This script requires PHP 5.4 or later\n * PHP Version 5.4\n */\n\nnamespace League\\OAuth2\\Client\\Provider;\n\nrequire 'vendor/autoload.php';\n\nuse League\\OAuth2\\Client\\Provider\\Exception\\IdentityProviderException;\nuse League\\OAuth2\\Client\\Token\\AccessToken;\nuse League\\OAuth2\\Client\\Tool\\BearerAuthorizationTrait;\nuse Psr\\Http\\Message\\ResponseInterface;\n\nsession_start();\n\n//If this automatic URL doesn't work, set it yourself manually\n$redirectUri = isset($_SERVER['HTTPS']) ? 'https://' : 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];\n//$redirectUri = 'http://localhost/phpmailer/get_oauth_token.php';\n\n//These details obtained are by setting up app in Google developer console.\n$clientId = 'RANDOMCHARS-----duv1n2.apps.googleusercontent.com';\n$clientSecret = 'RANDOMCHARS-----lGyjPcRtvP';\n\nclass Google extends AbstractProvider\n{\n    use BearerAuthorizationTrait;\n\n    const ACCESS_TOKEN_RESOURCE_OWNER_ID = 'id';\n\n    /**\n     * @var string If set, this will be sent to google as the \"access_type\" parameter.\n     * @link https://developers.google.com/accounts/docs/OAuth2WebServer#offline\n     */\n    protected $accessType;\n\n    /**\n     * @var string If set, this will be sent to google as the \"hd\" parameter.\n     * @link https://developers.google.com/accounts/docs/OAuth2Login#hd-param\n     */\n    protected $hostedDomain;\n\n    /**\n     * @var string If set, this will be sent to google as the \"scope\" parameter.\n     * @link https://developers.google.com/gmail/api/auth/scopes\n     */\n    protected $scope;\n\n    public function getBaseAuthorizationUrl()\n    {\n        return 'https://accounts.google.com/o/oauth2/auth';\n    }\n\n    public function getBaseAccessTokenUrl(array $params)\n    {\n        return 'https://accounts.google.com/o/oauth2/token';\n    }\n\n    public function getResourceOwnerDetailsUrl(AccessToken $token)\n    {\n\treturn ' ';\n    }\n\n    protected function getAuthorizationParameters(array $options)\n    {\n\tif (is_array($this->scope)) {\n            $separator = $this->getScopeSeparator();\n            $this->scope = implode($separator, $this->scope);\n        }\n\n        $params = array_merge(\n            parent::getAuthorizationParameters($options),\n            array_filter([\n                'hd'          => $this->hostedDomain,\n                'access_type' => $this->accessType,\n\t\t'scope'       => $this->scope,\n                // if the user is logged in with more than one account ask which one to use for the login!\n                'authuser'    => '-1'\n            ])\n        );\n        return $params;\n    }\n\n    protected function getDefaultScopes()\n    {\n        return [\n            'email',\n            'openid',\n            'profile',\n        ];\n    }\n\n    protected function getScopeSeparator()\n    {\n        return ' ';\n    }\n\n    protected function checkResponse(ResponseInterface $response, $data)\n    {\n        if (!empty($data['error'])) {\n            $code  = 0;\n            $error = $data['error'];\n\n            if (is_array($error)) {\n                $code  = $error['code'];\n                $error = $error['message'];\n            }\n\n            throw new IdentityProviderException($error, $code, $data);\n        }\n    }\n\n    protected function createResourceOwner(array $response, AccessToken $token)\n    {\n        return new GoogleUser($response);\n    }\n}\n\n\n//Set Redirect URI in Developer Console as [https/http]://<yourdomain>/<folder>/get_oauth_token.php\n$provider = new Google(\n    array(\n        'clientId' => $clientId,\n        'clientSecret' => $clientSecret,\n        'redirectUri' => $redirectUri,\n        'scope' => array('https://mail.google.com/'),\n\t'accessType' => 'offline'\n    )\n);\n\nif (!isset($_GET['code'])) {\n    // If we don't have an authorization code then get one\n    $authUrl = $provider->getAuthorizationUrl();\n    $_SESSION['oauth2state'] = $provider->getState();\n    header('Location: ' . $authUrl);\n    exit;\n// Check given state against previously stored one to mitigate CSRF attack\n} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {\n    unset($_SESSION['oauth2state']);\n    exit('Invalid state');\n} else {\n    // Try to get an access token (using the authorization code grant)\n    $token = $provider->getAccessToken(\n        'authorization_code',\n        array(\n            'code' => $_GET['code']\n        )\n    );\n\n    // Use this to get a new access token if the old one expires\n    echo 'Refresh Token: ' . $token->getRefreshToken();\n}\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-am.php",
    "content": "<?php\n/**\n * Armenian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Hrayr Grigoryan <hrayr@bits.am>\n */\n \n$PHPMAILER_LANG['authenticate']         = 'SMTP -ի սխալ: չհաջողվեց ստուգել իսկությունը.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP -ի սխալ: չհաջողվեց կապ հաստատել SMTP սերվերի հետ.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP -ի սխալ: տվյալները ընդունված չեն.';\n$PHPMAILER_LANG['empty_message']        = 'Հաղորդագրությունը դատարկ է';\n$PHPMAILER_LANG['encoding']             = 'Կոդավորման անհայտ տեսակ: ';\n$PHPMAILER_LANG['execute']              = 'Չհաջողվեց իրականացնել հրամանը: ';\n$PHPMAILER_LANG['file_access']          = 'Ֆայլը հասանելի չէ: ';\n$PHPMAILER_LANG['file_open']            = 'Ֆայլի սխալ: ֆայլը չհաջողվեց բացել: ';\n$PHPMAILER_LANG['from_failed']          = 'Ուղարկողի հետևյալ հասցեն սխալ է: ';\n$PHPMAILER_LANG['instantiate']          = 'Հնարավոր չէ կանչել mail ֆունկցիան.';\n$PHPMAILER_LANG['invalid_address']      = 'Հասցեն սխալ է: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' փոստային սերվերի հետ չի աշխատում.';\n$PHPMAILER_LANG['provide_address']      = 'Անհրաժեշտ է տրամադրել գոնե մեկ ստացողի e-mail հասցե.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP -ի սխալ: չի հաջողվել ուղարկել հետևյալ ստացողների հասցեներին: ';\n$PHPMAILER_LANG['signing']              = 'Ստորագրման սխալ: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP -ի connect() ֆունկցիան չի հաջողվել';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP սերվերի սխալ: ';\n$PHPMAILER_LANG['variable_set']         = 'Չի հաջողվում ստեղծել կամ վերափոխել փոփոխականը: ';\n$PHPMAILER_LANG['extension_missing']    = 'Հավելվածը բացակայում է: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-ar.php",
    "content": "<?php\n/**\n * Arabic PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author bahjat al mostafa <bahjat983@hotmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'خطأ SMTP : لا يمكن تأكيد الهوية.';\n$PHPMAILER_LANG['connect_host']         = 'خطأ SMTP: لا يمكن الاتصال بالخادم SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'خطأ SMTP: لم يتم قبول المعلومات .';\n$PHPMAILER_LANG['empty_message']        = 'نص الرسالة فارغ';\n$PHPMAILER_LANG['encoding']             = 'ترميز غير معروف: ';\n$PHPMAILER_LANG['execute']              = 'لا يمكن تنفيذ : ';\n$PHPMAILER_LANG['file_access']          = 'لا يمكن الوصول للملف: ';\n$PHPMAILER_LANG['file_open']            = 'خطأ في الملف: لا يمكن فتحه: ';\n$PHPMAILER_LANG['from_failed']          = 'خطأ على مستوى عنوان المرسل : ';\n$PHPMAILER_LANG['instantiate']          = 'لا يمكن توفير خدمة البريد.';\n$PHPMAILER_LANG['invalid_address']      = 'الإرسال غير ممكن لأن عنوان البريد الإلكتروني غير صالح: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' برنامج الإرسال غير مدعوم.';\n$PHPMAILER_LANG['provide_address']      = 'يجب توفير عنوان البريد الإلكتروني لمستلم واحد على الأقل.';\n$PHPMAILER_LANG['recipients_failed']    = 'خطأ SMTP: الأخطاء التالية ' .\n                                          'فشل في الارسال لكل من : ';\n$PHPMAILER_LANG['signing']              = 'خطأ في التوقيع: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() غير ممكن.';\n$PHPMAILER_LANG['smtp_error']           = 'خطأ على مستوى الخادم SMTP: ';\n$PHPMAILER_LANG['variable_set']         = 'لا يمكن تعيين أو إعادة تعيين متغير: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-az.php",
    "content": "<?php\n/**\n * Azerbaijani PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author @mirjalal\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP xətası: Giriş uğursuz oldu.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP xətası: SMTP serverinə qoşulma uğursuz oldu.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP xətası: Verilənlər qəbul edilməyib.';\n$PHPMAILER_LANG['empty_message']        = 'Boş mesaj göndərilə bilməz.';\n$PHPMAILER_LANG['encoding']             = 'Qeyri-müəyyən kodlaşdırma: ';\n$PHPMAILER_LANG['execute']              = 'Əmr yerinə yetirilmədi: ';\n$PHPMAILER_LANG['file_access']          = 'Fayla giriş yoxdur: ';\n$PHPMAILER_LANG['file_open']            = 'Fayl xətası: Fayl açıla bilmədi: ';\n$PHPMAILER_LANG['from_failed']          = 'Göstərilən poçtlara göndərmə uğursuz oldu: ';\n$PHPMAILER_LANG['instantiate']          = 'Mail funksiyası işə salına bilmədi.';\n$PHPMAILER_LANG['invalid_address']      = 'Düzgün olmayan e-mail adresi: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' - e-mail kitabxanası dəstəklənmir.';\n$PHPMAILER_LANG['provide_address']      = 'Ən azı bir e-mail adresi daxil edilməlidir.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP xətası: Aşağıdakı ünvanlar üzrə alıcılara göndərmə uğursuzdur: ';\n$PHPMAILER_LANG['signing']              = 'İmzalama xətası: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP serverinə qoşulma uğursuz oldu.';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP serveri xətası: ';\n$PHPMAILER_LANG['variable_set']         = 'Dəyişənin quraşdırılması uğursuz oldu: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-be.php",
    "content": "<?php\n/**\n * Belarusian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Aleksander Maksymiuk <info@setpro.pl>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Памылка SMTP: памылка ідэнтыфікацыі.';\n$PHPMAILER_LANG['connect_host']         = 'Памылка SMTP: нельга ўстанавіць сувязь з SMTP-серверам.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Памылка SMTP: звесткі непрынятыя.';\n$PHPMAILER_LANG['empty_message']        = 'Пустое паведамленне.';\n$PHPMAILER_LANG['encoding']             = 'Невядомая кадыроўка тэксту: ';\n$PHPMAILER_LANG['execute']              = 'Нельга выканаць каманду: ';\n$PHPMAILER_LANG['file_access']          = 'Няма доступу да файла: ';\n$PHPMAILER_LANG['file_open']            = 'Нельга адкрыць файл: ';\n$PHPMAILER_LANG['from_failed']          = 'Няправільны адрас адпраўніка: ';\n$PHPMAILER_LANG['instantiate']          = 'Нельга прымяніць функцыю mail().';\n$PHPMAILER_LANG['invalid_address']      = 'Нельга даслаць паведамленне, няправільны email атрымальніка: ';\n$PHPMAILER_LANG['provide_address']      = 'Запоўніце, калі ласка, правільны email атрымальніка.';\n$PHPMAILER_LANG['mailer_not_supported'] = ' - паштовы сервер не падтрымліваецца.';\n$PHPMAILER_LANG['recipients_failed']    = 'Памылка SMTP: няправільныя атрымальнікі: ';\n$PHPMAILER_LANG['signing']              = 'Памылка подпісу паведамлення: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'Памылка сувязі з SMTP-серверам.';\n$PHPMAILER_LANG['smtp_error']           = 'Памылка SMTP: ';\n$PHPMAILER_LANG['variable_set']         = 'Нельга ўстанавіць або перамяніць значэнне пераменнай: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-bg.php",
    "content": "<?php\n/**\n * Bulgarian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Mikhail Kyosev <mialygk@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP грешка: Не може да се удостовери пред сървъра.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP грешка: Не може да се свърже с SMTP хоста.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP грешка: данните не са приети.';\n$PHPMAILER_LANG['empty_message']        = 'Съдържанието на съобщението е празно';\n$PHPMAILER_LANG['encoding']             = 'Неизвестно кодиране: ';\n$PHPMAILER_LANG['execute']              = 'Не може да се изпълни: ';\n$PHPMAILER_LANG['file_access']          = 'Няма достъп до файл: ';\n$PHPMAILER_LANG['file_open']            = 'Файлова грешка: Не може да се отвори файл: ';\n$PHPMAILER_LANG['from_failed']          = 'Следните адреси за подател са невалидни: ';\n$PHPMAILER_LANG['instantiate']          = 'Не може да се инстанцира функцията mail.';\n$PHPMAILER_LANG['invalid_address']      = 'Невалиден адрес: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' - пощенски сървър не се поддържа.';\n$PHPMAILER_LANG['provide_address']      = 'Трябва да предоставите поне един email адрес за получател.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP грешка: Следните адреси за Получател са невалидни: ';\n$PHPMAILER_LANG['signing']              = 'Грешка при подписване: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP провален connect().';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP сървърна грешка: ';\n$PHPMAILER_LANG['variable_set']         = 'Не може да се установи или възстанови променлива: ';\n$PHPMAILER_LANG['extension_missing']    = 'Липсва разширение: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-ca.php",
    "content": "<?php\n/**\n * Catalan PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Ivan <web AT microstudi DOT com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Error SMTP: No s’ha pogut autenticar.';\n$PHPMAILER_LANG['connect_host']         = 'Error SMTP: No es pot connectar al servidor SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Error SMTP: Dades no acceptades.';\n$PHPMAILER_LANG['empty_message']        = 'El cos del missatge està buit.';\n$PHPMAILER_LANG['encoding']             = 'Codificació desconeguda: ';\n$PHPMAILER_LANG['execute']              = 'No es pot executar: ';\n$PHPMAILER_LANG['file_access']          = 'No es pot accedir a l’arxiu: ';\n$PHPMAILER_LANG['file_open']            = 'Error d’Arxiu: No es pot obrir l’arxiu: ';\n$PHPMAILER_LANG['from_failed']          = 'La(s) següent(s) adreces de remitent han fallat: ';\n$PHPMAILER_LANG['instantiate']          = 'No s’ha pogut crear una instància de la funció Mail.';\n$PHPMAILER_LANG['invalid_address']      = 'Adreça d’email invalida: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer no està suportat';\n$PHPMAILER_LANG['provide_address']      = 'S’ha de proveir almenys una adreça d’email com a destinatari.';\n$PHPMAILER_LANG['recipients_failed']    = 'Error SMTP: Els següents destinataris han fallat: ';\n$PHPMAILER_LANG['signing']              = 'Error al signar: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'Ha fallat el SMTP Connect().';\n$PHPMAILER_LANG['smtp_error']           = 'Error del servidor SMTP: ';\n$PHPMAILER_LANG['variable_set']         = 'No s’ha pogut establir o restablir la variable: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-ch.php",
    "content": "<?php\n/**\n * Chinese PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author LiuXin <http://www.80x86.cn/blog/>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP 错误：身份验证失败。';\n$PHPMAILER_LANG['connect_host']         = 'SMTP 错误: 不能连接SMTP主机。';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP 错误: 数据不可接受。';\n//$PHPMAILER_LANG['empty_message']        = 'Message body empty';\n$PHPMAILER_LANG['encoding']             = '未知编码：';\n$PHPMAILER_LANG['execute']              = '不能执行: ';\n$PHPMAILER_LANG['file_access']          = '不能访问文件：';\n$PHPMAILER_LANG['file_open']            = '文件错误：不能打开文件：';\n$PHPMAILER_LANG['from_failed']          = '下面的发送地址邮件发送失败了： ';\n$PHPMAILER_LANG['instantiate']          = '不能实现mail方法。';\n//$PHPMAILER_LANG['invalid_address']      = 'Invalid address: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' 您所选择的发送邮件的方法并不支持。';\n$PHPMAILER_LANG['provide_address']      = '您必须提供至少一个 收信人的email地址。';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP 错误： 下面的 收件人失败了： ';\n//$PHPMAILER_LANG['signing']              = 'Signing Error: ';\n//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';\n//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';\n//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-cs.php",
    "content": "<?php\n/**\n * Czech PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Chyba SMTP: Autentizace selhala.';\n$PHPMAILER_LANG['connect_host']         = 'Chyba SMTP: Nelze navázat spojení se SMTP serverem.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Chyba SMTP: Data nebyla přijata.';\n$PHPMAILER_LANG['empty_message']        = 'Prázdné tělo zprávy';\n$PHPMAILER_LANG['encoding']             = 'Neznámé kódování: ';\n$PHPMAILER_LANG['execute']              = 'Nelze provést: ';\n$PHPMAILER_LANG['file_access']          = 'Nelze získat přístup k souboru: ';\n$PHPMAILER_LANG['file_open']            = 'Chyba souboru: Nelze otevřít soubor pro čtení: ';\n$PHPMAILER_LANG['from_failed']          = 'Následující adresa odesílatele je nesprávná: ';\n$PHPMAILER_LANG['instantiate']          = 'Nelze vytvořit instanci emailové funkce.';\n$PHPMAILER_LANG['invalid_address']      = 'Neplatná adresa: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer není podporován.';\n$PHPMAILER_LANG['provide_address']      = 'Musíte zadat alespoň jednu emailovou adresu příjemce.';\n$PHPMAILER_LANG['recipients_failed']    = 'Chyba SMTP: Následující adresy příjemců nejsou správně: ';\n$PHPMAILER_LANG['signing']              = 'Chyba přihlašování: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() selhal.';\n$PHPMAILER_LANG['smtp_error']           = 'Chyba SMTP serveru: ';\n$PHPMAILER_LANG['variable_set']         = 'Nelze nastavit nebo změnit proměnnou: ';\n$PHPMAILER_LANG['extension_missing']    = 'Chybí rozšíření: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-da.php",
    "content": "<?php\n/**\n * Danish PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Mikael Stokkebro <info@stokkebro.dk>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP fejl: Kunne ikke logge på.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP fejl: Kunne ikke tilslutte SMTP serveren.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP fejl: Data kunne ikke accepteres.';\n//$PHPMAILER_LANG['empty_message']        = 'Message body empty';\n$PHPMAILER_LANG['encoding']             = 'Ukendt encode-format: ';\n$PHPMAILER_LANG['execute']              = 'Kunne ikke køre: ';\n$PHPMAILER_LANG['file_access']          = 'Ingen adgang til fil: ';\n$PHPMAILER_LANG['file_open']            = 'Fil fejl: Kunne ikke åbne filen: ';\n$PHPMAILER_LANG['from_failed']          = 'Følgende afsenderadresse er forkert: ';\n$PHPMAILER_LANG['instantiate']          = 'Kunne ikke initialisere email funktionen.';\n//$PHPMAILER_LANG['invalid_address']        = 'Invalid address: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer understøttes ikke.';\n$PHPMAILER_LANG['provide_address']      = 'Du skal indtaste mindst en modtagers emailadresse.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP fejl: Følgende modtagere er forkerte: ';\n//$PHPMAILER_LANG['signing']              = 'Signing Error: ';\n//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';\n//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';\n//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-de.php",
    "content": "<?php\n/**\n * German PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP-Fehler: Authentifizierung fehlgeschlagen.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP-Fehler: Konnte keine Verbindung zum SMTP-Host herstellen.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP-Fehler: Daten werden nicht akzeptiert.';\n$PHPMAILER_LANG['empty_message']        = 'E-Mail-Inhalt ist leer.';\n$PHPMAILER_LANG['encoding']             = 'Unbekannte Kodierung: ';\n$PHPMAILER_LANG['execute']              = 'Konnte folgenden Befehl nicht ausführen: ';\n$PHPMAILER_LANG['file_access']          = 'Zugriff auf folgende Datei fehlgeschlagen: ';\n$PHPMAILER_LANG['file_open']            = 'Dateifehler: Konnte folgende Datei nicht öffnen: ';\n$PHPMAILER_LANG['from_failed']          = 'Die folgende Absenderadresse ist nicht korrekt: ';\n$PHPMAILER_LANG['instantiate']          = 'Mail-Funktion konnte nicht initialisiert werden.';\n$PHPMAILER_LANG['invalid_address']      = 'Die Adresse ist ungültig: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer wird nicht unterstützt.';\n$PHPMAILER_LANG['provide_address']      = 'Bitte geben Sie mindestens eine Empfängeradresse an.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP-Fehler: Die folgenden Empfänger sind nicht korrekt: ';\n$PHPMAILER_LANG['signing']              = 'Fehler beim Signieren: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'Verbindung zum SMTP-Server fehlgeschlagen.';\n$PHPMAILER_LANG['smtp_error']           = 'Fehler vom SMTP-Server: ';\n$PHPMAILER_LANG['variable_set']         = 'Kann Variable nicht setzen oder zurücksetzen: ';\n$PHPMAILER_LANG['extension_missing']    = 'Fehlende Erweiterung: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-el.php",
    "content": "<?php\n/**\n * Greek PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP Σφάλμα: Αδυναμία πιστοποίησης (authentication).';\n$PHPMAILER_LANG['connect_host']         = 'SMTP Σφάλμα: Αδυναμία σύνδεσης στον SMTP-Host.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Σφάλμα: Τα δεδομένα δεν έγιναν αποδεκτά.';\n$PHPMAILER_LANG['empty_message']        = 'Το E-Mail δεν έχει περιεχόμενο .';\n$PHPMAILER_LANG['encoding']             = 'Αγνωστο Encoding-Format: ';\n$PHPMAILER_LANG['execute']              = 'Αδυναμία εκτέλεσης ακόλουθης εντολής: ';\n$PHPMAILER_LANG['file_access']          = 'Αδυναμία προσπέλασης του αρχείου: ';\n$PHPMAILER_LANG['file_open']            = 'Σφάλμα Αρχείου: Δεν είναι δυνατό το άνοιγμα του ακόλουθου αρχείου: ';\n$PHPMAILER_LANG['from_failed']          = 'Η παρακάτω διεύθυνση αποστολέα δεν είναι σωστή: ';\n$PHPMAILER_LANG['instantiate']          = 'Αδυναμία εκκίνησης Mail function.';\n$PHPMAILER_LANG['invalid_address']      = 'Το μήνυμα δεν εστάλη, η διεύθυνση δεν είναι έγκυρη: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer δεν υποστηρίζεται.';\n$PHPMAILER_LANG['provide_address']      = 'Παρακαλούμε δώστε τουλάχιστον μια e-mail διεύθυνση παραλήπτη.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP Σφάλμα: Οι παρακάτω διευθύνσεις παραλήπτη δεν είναι έγκυρες: ';\n$PHPMAILER_LANG['signing']              = 'Σφάλμα υπογραφής: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'Αποτυχία σύνδεσης στον SMTP Server.';\n$PHPMAILER_LANG['smtp_error']           = 'Σφάλμα από τον SMTP Server: ';\n$PHPMAILER_LANG['variable_set']         = 'Αδυναμία ορισμού ή αρχικοποίησης μεταβλητής: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-eo.php",
    "content": "<?php\n/**\n * Esperanto PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Eraro de servilo SMTP : aŭtentigo malsukcesis.';\n$PHPMAILER_LANG['connect_host']         = 'Eraro de servilo SMTP : konektado al servilo malsukcesis.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Eraro de servilo SMTP : neĝustaj datumoj.';\n$PHPMAILER_LANG['empty_message']        = 'Teksto de mesaĝo mankas.';\n$PHPMAILER_LANG['encoding']             = 'Nekonata kodoprezento: ';\n$PHPMAILER_LANG['execute']              = 'Lanĉi rulumadon ne eblis: ';\n$PHPMAILER_LANG['file_access']          = 'Aliro al dosiero ne sukcesis: ';\n$PHPMAILER_LANG['file_open']            = 'Eraro de dosiero: malfermo neeblas: ';\n$PHPMAILER_LANG['from_failed']          = 'Jena adreso de sendinto malsukcesis: ';\n$PHPMAILER_LANG['instantiate']          = 'Genero de retmesaĝa funkcio neeblis.';\n$PHPMAILER_LANG['invalid_address']      = 'Retadreso ne validas: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mesaĝilo ne subtenata.';\n$PHPMAILER_LANG['provide_address']      = 'Vi devas tajpi almenaŭ unu recevontan retadreson.';\n$PHPMAILER_LANG['recipients_failed']    = 'Eraro de servilo SMTP : la jenaj poŝtrecivuloj kaŭzis eraron: ';\n$PHPMAILER_LANG['signing']              = 'Eraro de subskribo: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP konektado malsukcesis.';\n$PHPMAILER_LANG['smtp_error']           = 'Eraro de servilo SMTP : ';\n$PHPMAILER_LANG['variable_set']         = 'Variablo ne pravalorizeblas aŭ ne repravalorizeblas: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-es.php",
    "content": "<?php\n/**\n * Spanish PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Matt Sturdy <matt.sturdy@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Error SMTP: Imposible autentificar.';\n$PHPMAILER_LANG['connect_host']         = 'Error SMTP: Imposible conectar al servidor SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Error SMTP: Datos no aceptados.';\n$PHPMAILER_LANG['empty_message']        = 'El cuerpo del mensaje está vacío';\n$PHPMAILER_LANG['encoding']             = 'Codificación desconocida: ';\n$PHPMAILER_LANG['execute']              = 'Imposible ejecutar: ';\n$PHPMAILER_LANG['file_access']          = 'Imposible acceder al archivo: ';\n$PHPMAILER_LANG['file_open']            = 'Error de Archivo: Imposible abrir el archivo: ';\n$PHPMAILER_LANG['from_failed']          = 'La(s) siguiente(s) direcciones de remitente fallaron: ';\n$PHPMAILER_LANG['instantiate']          = 'Imposible crear una instancia de la función Mail.';\n$PHPMAILER_LANG['invalid_address']      = 'Imposible enviar: dirección de email inválido: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer no está soportado.';\n$PHPMAILER_LANG['provide_address']      = 'Debe proporcionar al menos una dirección de email de destino.';\n$PHPMAILER_LANG['recipients_failed']    = 'Error SMTP: Los siguientes destinos fallaron: ';\n$PHPMAILER_LANG['signing']              = 'Error al firmar: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() falló.';\n$PHPMAILER_LANG['smtp_error']           = 'Error del servidor SMTP: ';\n$PHPMAILER_LANG['variable_set']         = 'No se pudo configurar la variable: ';\n$PHPMAILER_LANG['extension_missing']    = 'Extensión faltante: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-et.php",
    "content": "<?php\n/**\n * Estonian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Indrek Päri\n * @author Elan Ruusamäe <glen@delfi.ee>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP Viga: Autoriseerimise viga.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP Viga: Ei õnnestunud luua ühendust SMTP serveriga.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Viga: Vigased andmed.';\n$PHPMAILER_LANG['empty_message']        = 'Tühi kirja sisu';\n$PHPMAILER_LANG[\"encoding\"]             = 'Tundmatu kodeering: ';\n$PHPMAILER_LANG['execute']              = 'Tegevus ebaõnnestus: ';\n$PHPMAILER_LANG['file_access']          = 'Pole piisavalt õiguseid järgneva faili avamiseks: ';\n$PHPMAILER_LANG['file_open']            = 'Faili Viga: Faili avamine ebaõnnestus: ';\n$PHPMAILER_LANG['from_failed']          = 'Järgnev saatja e-posti aadress on vigane: ';\n$PHPMAILER_LANG['instantiate']          = 'mail funktiooni käivitamine ebaõnnestus.';\n$PHPMAILER_LANG['invalid_address']      = 'Saatmine peatatud, e-posti address vigane: ';\n$PHPMAILER_LANG['provide_address']      = 'Te peate määrama vähemalt ühe saaja e-posti aadressi.';\n$PHPMAILER_LANG['mailer_not_supported'] = ' maileri tugi puudub.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP Viga: Järgnevate saajate e-posti aadressid on vigased: ';\n$PHPMAILER_LANG[\"signing\"]              = 'Viga allkirjastamisel: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() ebaõnnestus.';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP serveri viga: ';\n$PHPMAILER_LANG['variable_set']         = 'Ei õnnestunud määrata või lähtestada muutujat: ';\n$PHPMAILER_LANG['extension_missing']    = 'Nõutud laiendus on puudu: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-fa.php",
    "content": "<?php\n/**\n * Persian/Farsi PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Ali Jazayeri <jaza.ali@gmail.com>\n * @author Mohammad Hossein Mojtahedi <mhm5000@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'خطای SMTP: احراز هویت با شکست مواجه شد.';\n$PHPMAILER_LANG['connect_host']         = 'خطای SMTP: اتصال به سرور SMTP برقرار نشد.';\n$PHPMAILER_LANG['data_not_accepted']    = 'خطای SMTP: داده‌ها نا‌درست هستند.';\n$PHPMAILER_LANG['empty_message']        = 'بخش متن پیام خالی است.';\n$PHPMAILER_LANG['encoding']             = 'کد‌گذاری نا‌شناخته: ';\n$PHPMAILER_LANG['execute']              = 'امکان اجرا وجود ندارد: ';\n$PHPMAILER_LANG['file_access']          = 'امکان دسترسی به فایل وجود ندارد: ';\n$PHPMAILER_LANG['file_open']            = 'خطای File: امکان بازکردن فایل وجود ندارد: ';\n$PHPMAILER_LANG['from_failed']          = 'آدرس فرستنده اشتباه است: ';\n$PHPMAILER_LANG['instantiate']          = 'امکان معرفی تابع ایمیل وجود ندارد.';\n$PHPMAILER_LANG['invalid_address']      = 'آدرس ایمیل معتبر نیست: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer پشتیبانی نمی‌شود.';\n$PHPMAILER_LANG['provide_address']      = 'باید حداقل یک آدرس گیرنده وارد کنید.';\n$PHPMAILER_LANG['recipients_failed']    = 'خطای SMTP: ارسال به آدرس گیرنده با خطا مواجه شد: ';\n$PHPMAILER_LANG['signing']              = 'خطا در امضا: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'خطا در اتصال به SMTP.';\n$PHPMAILER_LANG['smtp_error']           = 'خطا در SMTP Server: ';\n$PHPMAILER_LANG['variable_set']         = 'امکان ارسال یا ارسال مجدد متغیر‌ها وجود ندارد: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-fi.php",
    "content": "<?php\n/**\n * Finnish PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Jyry Kuukanen\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP-virhe: käyttäjätunnistus epäonnistui.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP-virhe: yhteys palvelimeen ei onnistu.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP-virhe: data on virheellinen.';\n//$PHPMAILER_LANG['empty_message']        = 'Message body empty';\n$PHPMAILER_LANG['encoding']             = 'Tuntematon koodaustyyppi: ';\n$PHPMAILER_LANG['execute']              = 'Suoritus epäonnistui: ';\n$PHPMAILER_LANG['file_access']          = 'Seuraavaan tiedostoon ei ole oikeuksia: ';\n$PHPMAILER_LANG['file_open']            = 'Tiedostovirhe: Ei voida avata tiedostoa: ';\n$PHPMAILER_LANG['from_failed']          = 'Seuraava lähettäjän osoite on virheellinen: ';\n$PHPMAILER_LANG['instantiate']          = 'mail-funktion luonti epäonnistui.';\n//$PHPMAILER_LANG['invalid_address']      = 'Invalid address: ';\n$PHPMAILER_LANG['mailer_not_supported'] = 'postivälitintyyppiä ei tueta.';\n$PHPMAILER_LANG['provide_address']      = 'Aseta vähintään yksi vastaanottajan sähk&ouml;postiosoite.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP-virhe: seuraava vastaanottaja osoite on virheellinen.';\n$PHPMAILER_LANG['encoding']             = 'Tuntematon koodaustyyppi: ';\n//$PHPMAILER_LANG['signing']              = 'Signing Error: ';\n//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';\n//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';\n//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-fo.php",
    "content": "<?php\n/**\n * Faroese PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Dávur Sørensen <http://www.profo-webdesign.dk>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP feilur: Kundi ikki góðkenna.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP feilur: Kundi ikki knýta samband við SMTP vert.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP feilur: Data ikki góðkent.';\n//$PHPMAILER_LANG['empty_message']        = 'Message body empty';\n$PHPMAILER_LANG['encoding']             = 'Ókend encoding: ';\n$PHPMAILER_LANG['execute']              = 'Kundi ikki útføra: ';\n$PHPMAILER_LANG['file_access']          = 'Kundi ikki tilganga fílu: ';\n$PHPMAILER_LANG['file_open']            = 'Fílu feilur: Kundi ikki opna fílu: ';\n$PHPMAILER_LANG['from_failed']          = 'fylgjandi Frá/From adressa miseydnaðist: ';\n$PHPMAILER_LANG['instantiate']          = 'Kuni ikki instantiera mail funktión.';\n//$PHPMAILER_LANG['invalid_address']      = 'Invalid address: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' er ikki supporterað.';\n$PHPMAILER_LANG['provide_address']      = 'Tú skal uppgeva minst móttakara-emailadressu(r).';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP Feilur: Fylgjandi móttakarar miseydnaðust: ';\n//$PHPMAILER_LANG['signing']              = 'Signing Error: ';\n//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';\n//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';\n//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-fr.php",
    "content": "<?php\n/**\n * French PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * Some French punctuation requires a thin non-breaking space (U+202F) character before it,\n * for example before a colon or exclamation mark.\n * There is one of these characters between these quotes: \" \"\n * @link http://unicode.org/udhr/n/notes_fra.html\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Erreur SMTP : échec de l\\'authentification.';\n$PHPMAILER_LANG['connect_host']         = 'Erreur SMTP : impossible de se connecter au serveur SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Erreur SMTP : données incorrectes.';\n$PHPMAILER_LANG['empty_message']        = 'Corps du message vide.';\n$PHPMAILER_LANG['encoding']             = 'Encodage inconnu : ';\n$PHPMAILER_LANG['execute']              = 'Impossible de lancer l\\'exécution : ';\n$PHPMAILER_LANG['file_access']          = 'Impossible d\\'accéder au fichier : ';\n$PHPMAILER_LANG['file_open']            = 'Ouverture du fichier impossible : ';\n$PHPMAILER_LANG['from_failed']          = 'L\\'adresse d\\'expéditeur suivante a échoué : ';\n$PHPMAILER_LANG['instantiate']          = 'Impossible d\\'instancier la fonction mail.';\n$PHPMAILER_LANG['invalid_address']      = 'L\\'adresse courriel n\\'est pas valide : ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' client de messagerie non supporté.';\n$PHPMAILER_LANG['provide_address']      = 'Vous devez fournir au moins une adresse de destinataire.';\n$PHPMAILER_LANG['recipients_failed']    = 'Erreur SMTP : les destinataires suivants sont en erreur : ';\n$PHPMAILER_LANG['signing']              = 'Erreur de signature : ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'Échec de la connexion SMTP.';\n$PHPMAILER_LANG['smtp_error']           = 'Erreur du serveur SMTP : ';\n$PHPMAILER_LANG['variable_set']         = 'Impossible d\\'initialiser ou de réinitialiser une variable : ';\n$PHPMAILER_LANG['extension_missing']    = 'Extension manquante : ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-gl.php",
    "content": "<?php\n/**\n * Galician PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author by Donato Rouco <donatorouco@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Erro SMTP: Non puido ser autentificado.';\n$PHPMAILER_LANG['connect_host']         = 'Erro SMTP: Non puido conectar co servidor SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Erro SMTP: Datos non aceptados.';\n$PHPMAILER_LANG['empty_message']        = 'Corpo da mensaxe vacía';\n$PHPMAILER_LANG['encoding']             = 'Codificación descoñecida: ';\n$PHPMAILER_LANG['execute']              = 'Non puido ser executado: ';\n$PHPMAILER_LANG['file_access']          = 'Nob puido acceder ó arquivo: ';\n$PHPMAILER_LANG['file_open']            = 'Erro de Arquivo: No puido abrir o arquivo: ';\n$PHPMAILER_LANG['from_failed']          = 'A(s) seguinte(s) dirección(s) de remitente(s) deron erro: ';\n$PHPMAILER_LANG['instantiate']          = 'Non puido crear unha instancia da función Mail.';\n$PHPMAILER_LANG['invalid_address']      = 'Non puido envia-lo correo: dirección de email inválida: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer non está soportado.';\n$PHPMAILER_LANG['provide_address']      = 'Debe engadir polo menos unha dirección de email coma destino.';\n$PHPMAILER_LANG['recipients_failed']    = 'Erro SMTP: Os seguintes destinos fallaron: ';\n$PHPMAILER_LANG['signing']              = 'Erro ó firmar: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() fallou.';\n$PHPMAILER_LANG['smtp_error']           = 'Erro do servidor SMTP: ';\n$PHPMAILER_LANG['variable_set']         = 'Non puidemos axustar ou reaxustar a variábel: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-he.php",
    "content": "<?php\n/**\n * Hebrew PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Ronny Sherer <ronny@hoojima.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'שגיאת SMTP: פעולת האימות נכשלה.';\n$PHPMAILER_LANG['connect_host']         = 'שגיאת SMTP: לא הצלחתי להתחבר לשרת SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'שגיאת SMTP: מידע לא התקבל.';\n$PHPMAILER_LANG['empty_message']        = 'גוף ההודעה ריק';\n$PHPMAILER_LANG['invalid_address']      = 'כתובת שגויה: ';\n$PHPMAILER_LANG['encoding']             = 'קידוד לא מוכר: ';\n$PHPMAILER_LANG['execute']              = 'לא הצלחתי להפעיל את: ';\n$PHPMAILER_LANG['file_access']          = 'לא ניתן לגשת לקובץ: ';\n$PHPMAILER_LANG['file_open']            = 'שגיאת קובץ: לא ניתן לגשת לקובץ: ';\n$PHPMAILER_LANG['from_failed']          = 'כתובות הנמענים הבאות נכשלו: ';\n$PHPMAILER_LANG['instantiate']          = 'לא הצלחתי להפעיל את פונקציית המייל.';\n$PHPMAILER_LANG['mailer_not_supported'] = ' אינה נתמכת.';\n$PHPMAILER_LANG['provide_address']      = 'חובה לספק לפחות כתובת אחת של מקבל המייל.';\n$PHPMAILER_LANG['recipients_failed']    = 'שגיאת SMTP: הנמענים הבאים נכשלו: ';\n$PHPMAILER_LANG['signing']              = 'שגיאת חתימה: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';\n$PHPMAILER_LANG['smtp_error']           = 'שגיאת שרת SMTP: ';\n$PHPMAILER_LANG['variable_set']         = 'לא ניתן לקבוע או לשנות את המשתנה: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-hr.php",
    "content": "<?php\n/**\n * Croatian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Hrvoj3e <hrvoj3e@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP Greška: Neuspjela autentikacija.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP Greška: Ne mogu se spojiti na SMTP poslužitelj.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Greška: Podatci nisu prihvaćeni.';\n$PHPMAILER_LANG['empty_message']        = 'Sadržaj poruke je prazan.';\n$PHPMAILER_LANG['encoding']             = 'Nepoznati encoding: ';\n$PHPMAILER_LANG['execute']              = 'Nije moguće izvršiti naredbu: ';\n$PHPMAILER_LANG['file_access']          = 'Nije moguće pristupiti datoteci: ';\n$PHPMAILER_LANG['file_open']            = 'Nije moguće otvoriti datoteku: ';\n$PHPMAILER_LANG['from_failed']          = 'SMTP Greška: Slanje s navedenih e-mail adresa nije uspjelo: ';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP Greška: Slanje na navedenih e-mail adresa nije uspjelo: ';\n$PHPMAILER_LANG['instantiate']          = 'Ne mogu pokrenuti mail funkcionalnost.';\n$PHPMAILER_LANG['invalid_address']      = 'E-mail nije poslan. Neispravna e-mail adresa: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer nije podržan.';\n$PHPMAILER_LANG['provide_address']      = 'Definirajte barem jednu adresu primatelja.';\n$PHPMAILER_LANG['signing']              = 'Greška prilikom prijave: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'Spajanje na SMTP poslužitelj nije uspjelo.';\n$PHPMAILER_LANG['smtp_error']           = 'Greška SMTP poslužitelja: ';\n$PHPMAILER_LANG['variable_set']         = 'Ne mogu postaviti varijablu niti ju vratiti nazad: ';\n$PHPMAILER_LANG['extension_missing']    = 'Nedostaje proširenje: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-hu.php",
    "content": "<?php\n/**\n * Hungarian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author @dominicus-75\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP hiba: az azonosítás sikertelen.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP hiba: nem lehet kapcsolódni az SMTP-szerverhez.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP hiba: adatok visszautasítva.';\n$PHPMAILER_LANG['empty_message']        = 'Üres az üzenettörzs.';\n$PHPMAILER_LANG['encoding']             = 'Ismeretlen kódolás: ';\n$PHPMAILER_LANG['execute']              = 'Nem lehet végrehajtani: ';\n$PHPMAILER_LANG['file_access']          = 'A következő fájl nem elérhető: ';\n$PHPMAILER_LANG['file_open']            = 'Fájl hiba: a következő fájlt nem lehet megnyitni: ';\n$PHPMAILER_LANG['from_failed']          = 'A feladóként megadott következő cím hibás: ';\n$PHPMAILER_LANG['instantiate']          = 'A PHP mail() függvényt nem sikerült végrehajtani.';\n$PHPMAILER_LANG['invalid_address']      = 'Érvénytelen cím: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' a mailer-osztály nem támogatott.';\n$PHPMAILER_LANG['provide_address']      = 'Legalább egy címzettet fel kell tüntetni.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP hiba: a címzettként megadott következő címek hibásak: ';\n$PHPMAILER_LANG['signing']              = 'Hibás aláírás: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'Hiba az SMTP-kapcsolatban.';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP-szerver hiba: ';\n$PHPMAILER_LANG['variable_set']         = 'A következő változók beállítása nem sikerült: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-id.php",
    "content": "<?php\n/**\n * Indonesian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Cecep Prawiro <cecep.prawiro@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Kesalahan SMTP: Tidak dapat mengautentikasi.';\n$PHPMAILER_LANG['connect_host']         = 'Kesalahan SMTP: Tidak dapat terhubung ke host SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Kesalahan SMTP: Data tidak diterima peladen.';\n$PHPMAILER_LANG['empty_message']        = 'Isi pesan kosong';\n$PHPMAILER_LANG['encoding']             = 'Pengkodean karakter tidak dikenali: ';\n$PHPMAILER_LANG['execute']              = 'Tidak dapat menjalankan proses : ';\n$PHPMAILER_LANG['file_access']          = 'Tidak dapat mengakses berkas : ';\n$PHPMAILER_LANG['file_open']            = 'Kesalahan File: Berkas tidak bisa dibuka : ';\n$PHPMAILER_LANG['from_failed']          = 'Alamat pengirim berikut mengakibatkan error : ';\n$PHPMAILER_LANG['instantiate']          = 'Tidak dapat menginisialisasi fungsi email';\n$PHPMAILER_LANG['invalid_address']      = 'Gagal terkirim, alamat email tidak valid : ';\n$PHPMAILER_LANG['provide_address']      = 'Harus disediakan minimal satu alamat tujuan';\n$PHPMAILER_LANG['mailer_not_supported'] = 'Mailer tidak didukung';\n$PHPMAILER_LANG['recipients_failed']    = 'Kesalahan SMTP: Alamat tujuan berikut menghasilkan error : ';\n$PHPMAILER_LANG['signing']              = 'Kesalahan dalam tanda tangan : ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() gagal.';\n$PHPMAILER_LANG['smtp_error']           = 'Kesalahan peladen SMTP : ';\n$PHPMAILER_LANG['variable_set']         = 'Tidak berhasil mengatur atau mengatur ulang variable : ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-it.php",
    "content": "<?php\n/**\n * Italian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Ilias Bartolini <brain79@inwind.it>\n * @author Stefano Sabatini <sabas88@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP Error: Impossibile autenticarsi.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP Error: Impossibile connettersi all\\'host SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Error: Dati non accettati dal server.';\n$PHPMAILER_LANG['empty_message']        = 'Il corpo del messaggio è vuoto';\n$PHPMAILER_LANG['encoding']             = 'Codifica dei caratteri sconosciuta: ';\n$PHPMAILER_LANG['execute']              = 'Impossibile eseguire l\\'operazione: ';\n$PHPMAILER_LANG['file_access']          = 'Impossibile accedere al file: ';\n$PHPMAILER_LANG['file_open']            = 'File Error: Impossibile aprire il file: ';\n$PHPMAILER_LANG['from_failed']          = 'I seguenti indirizzi mittenti hanno generato errore: ';\n$PHPMAILER_LANG['instantiate']          = 'Impossibile istanziare la funzione mail';\n$PHPMAILER_LANG['invalid_address']      = 'Impossibile inviare, l\\'indirizzo email non è valido: ';\n$PHPMAILER_LANG['provide_address']      = 'Deve essere fornito almeno un indirizzo ricevente';\n$PHPMAILER_LANG['mailer_not_supported'] = 'Mailer non supportato';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP Error: I seguenti indirizzi destinatari hanno generato un errore: ';\n$PHPMAILER_LANG['signing']              = 'Errore nella firma: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() fallita.';\n$PHPMAILER_LANG['smtp_error']           = 'Errore del server SMTP: ';\n$PHPMAILER_LANG['variable_set']         = 'Impossibile impostare o resettare la variabile: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-ja.php",
    "content": "<?php\n/**\n * Japanese PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Mitsuhiro Yoshida <http://mitstek.com/>\n * @author Yoshi Sakai <http://bluemooninc.jp/>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTPエラー: 認証できませんでした。';\n$PHPMAILER_LANG['connect_host']         = 'SMTPエラー: SMTPホストに接続できませんでした。';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTPエラー: データが受け付けられませんでした。';\n//$PHPMAILER_LANG['empty_message']        = 'Message body empty';\n$PHPMAILER_LANG['encoding']             = '不明なエンコーディング: ';\n$PHPMAILER_LANG['execute']              = '実行できませんでした: ';\n$PHPMAILER_LANG['file_access']          = 'ファイルにアクセスできません: ';\n$PHPMAILER_LANG['file_open']            = 'ファイルエラー: ファイルを開けません: ';\n$PHPMAILER_LANG['from_failed']          = 'Fromアドレスを登録する際にエラーが発生しました: ';\n$PHPMAILER_LANG['instantiate']          = 'メール関数が正常に動作しませんでした。';\n//$PHPMAILER_LANG['invalid_address']      = 'Invalid address: ';\n$PHPMAILER_LANG['provide_address']      = '少なくとも1つメールアドレスを 指定する必要があります。';\n$PHPMAILER_LANG['mailer_not_supported'] = ' メーラーがサポートされていません。';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTPエラー: 次の受信者アドレスに 間違いがあります: ';\n//$PHPMAILER_LANG['signing']              = 'Signing Error: ';\n//$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() failed.';\n//$PHPMAILER_LANG['smtp_error']           = 'SMTP server error: ';\n//$PHPMAILER_LANG['variable_set']         = 'Cannot set or reset variable: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-ka.php",
    "content": "<?php\n/**\n * Georgian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Avtandil Kikabidze aka LONGMAN <akalongman@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP შეცდომა: ავტორიზაცია შეუძლებელია.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP შეცდომა: SMTP სერვერთან დაკავშირება შეუძლებელია.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP შეცდომა: მონაცემები არ იქნა მიღებული.';\n$PHPMAILER_LANG['encoding']             = 'კოდირების უცნობი ტიპი: ';\n$PHPMAILER_LANG['execute']              = 'შეუძლებელია შემდეგი ბრძანების შესრულება: ';\n$PHPMAILER_LANG['file_access']          = 'შეუძლებელია წვდომა ფაილთან: ';\n$PHPMAILER_LANG['file_open']            = 'ფაილური სისტემის შეცდომა: არ იხსნება ფაილი: ';\n$PHPMAILER_LANG['from_failed']          = 'გამგზავნის არასწორი მისამართი: ';\n$PHPMAILER_LANG['instantiate']          = 'mail ფუნქციის გაშვება ვერ ხერხდება.';\n$PHPMAILER_LANG['provide_address']      = 'გთხოვთ მიუთითოთ ერთი ადრესატის e-mail მისამართი მაინც.';\n$PHPMAILER_LANG['mailer_not_supported'] = ' - საფოსტო სერვერის მხარდაჭერა არ არის.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP შეცდომა: შემდეგ მისამართებზე გაგზავნა ვერ მოხერხდა: ';\n$PHPMAILER_LANG['empty_message']        = 'შეტყობინება ცარიელია';\n$PHPMAILER_LANG['invalid_address']      = 'არ გაიგზავნა, e-mail მისამართის არასწორი ფორმატი: ';\n$PHPMAILER_LANG['signing']              = 'ხელმოწერის შეცდომა: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'შეცდომა SMTP სერვერთან დაკავშირებისას';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP სერვერის შეცდომა: ';\n$PHPMAILER_LANG['variable_set']         = 'შეუძლებელია შემდეგი ცვლადის შექმნა ან შეცვლა: ';\n$PHPMAILER_LANG['extension_missing']    = 'ბიბლიოთეკა არ არსებობს: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-ko.php",
    "content": "<?php\n/**\n * Korean PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author ChalkPE <amato0617@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP 오류: 인증할 수 없습니다.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP 오류: SMTP 호스트에 접속할 수 없습니다.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP 오류: 데이터가 받아들여지지 않았습니다.';\n$PHPMAILER_LANG['empty_message']        = '메세지 내용이 없습니다';\n$PHPMAILER_LANG['encoding']             = '알 수 없는 인코딩: ';\n$PHPMAILER_LANG['execute']              = '실행 불가: ';\n$PHPMAILER_LANG['file_access']          = '파일 접근 불가: ';\n$PHPMAILER_LANG['file_open']            = '파일 오류: 파일을 열 수 없습니다: ';\n$PHPMAILER_LANG['from_failed']          = '다음 From 주소에서 오류가 발생했습니다: ';\n$PHPMAILER_LANG['instantiate']          = 'mail 함수를 인스턴스화할 수 없습니다';\n$PHPMAILER_LANG['invalid_address']      = '잘못된 주소: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' 메일러는 지원되지 않습니다.';\n$PHPMAILER_LANG['provide_address']      = '적어도 한 개 이상의 수신자 메일 주소를 제공해야 합니다.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP 오류: 다음 수신자에서 오류가 발생했습니다: ';\n$PHPMAILER_LANG['signing']              = '서명 오류: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP 연결을 실패하였습니다.';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP 서버 오류: ';\n$PHPMAILER_LANG['variable_set']         = '변수 설정 및 초기화 불가: ';\n$PHPMAILER_LANG['extension_missing']    = '확장자 없음: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-lt.php",
    "content": "<?php\n/**\n * Lithuanian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Dainius Kaupaitis <dk@sum.lt>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP klaida: autentifikacija nepavyko.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP klaida: nepavyksta prisijungti prie SMTP stoties.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP klaida: duomenys nepriimti.';\n$PHPMAILER_LANG['empty_message']        = 'Laiško turinys tuščias';\n$PHPMAILER_LANG['encoding']             = 'Neatpažinta koduotė: ';\n$PHPMAILER_LANG['execute']              = 'Nepavyko įvykdyti komandos: ';\n$PHPMAILER_LANG['file_access']          = 'Byla nepasiekiama: ';\n$PHPMAILER_LANG['file_open']            = 'Bylos klaida: Nepavyksta atidaryti: ';\n$PHPMAILER_LANG['from_failed']          = 'Neteisingas siuntėjo adresas: ';\n$PHPMAILER_LANG['instantiate']          = 'Nepavyko paleisti mail funkcijos.';\n$PHPMAILER_LANG['invalid_address']      = 'Neteisingas adresas: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' pašto stotis nepalaikoma.';\n$PHPMAILER_LANG['provide_address']      = 'Nurodykite bent vieną gavėjo adresą.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP klaida: nepavyko išsiųsti šiems gavėjams: ';\n$PHPMAILER_LANG['signing']              = 'Prisijungimo klaida: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP susijungimo klaida';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP stoties klaida: ';\n$PHPMAILER_LANG['variable_set']         = 'Nepavyko priskirti reikšmės kintamajam: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-lv.php",
    "content": "<?php\n/**\n * Latvian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Eduards M. <e@npd.lv>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP kļūda: Autorizācija neizdevās.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP Kļūda: Nevar izveidot savienojumu ar SMTP serveri.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Kļūda: Nepieņem informāciju.';\n$PHPMAILER_LANG['empty_message']        = 'Ziņojuma teksts ir tukšs';\n$PHPMAILER_LANG['encoding']             = 'Neatpazīts kodējums: ';\n$PHPMAILER_LANG['execute']              = 'Neizdevās izpildīt komandu: ';\n$PHPMAILER_LANG['file_access']          = 'Fails nav pieejams: ';\n$PHPMAILER_LANG['file_open']            = 'Faila kļūda: Nevar atvērt failu: ';\n$PHPMAILER_LANG['from_failed']          = 'Nepareiza sūtītāja adrese: ';\n$PHPMAILER_LANG['instantiate']          = 'Nevar palaist sūtīšanas funkciju.';\n$PHPMAILER_LANG['invalid_address']      = 'Nepareiza adrese: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' sūtītājs netiek atbalstīts.';\n$PHPMAILER_LANG['provide_address']      = 'Lūdzu, norādiet vismaz vienu adresātu.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP kļūda: neizdevās nosūtīt šādiem saņēmējiem: ';\n$PHPMAILER_LANG['signing']              = 'Autorizācijas kļūda: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP savienojuma kļūda';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP servera kļūda: ';\n$PHPMAILER_LANG['variable_set']         = 'Nevar piešķirt mainīgā vērtību: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-ms.php",
    "content": "<?php\n/**\n * Malaysian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Nawawi Jamili <nawawi@rutweb.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Ralat SMTP: Tidak dapat pengesahan.';\n$PHPMAILER_LANG['connect_host']         = 'Ralat SMTP: Tidak dapat menghubungi hos pelayan SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Ralat SMTP: Data tidak diterima oleh pelayan.';\n$PHPMAILER_LANG['empty_message']        = 'Tiada isi untuk mesej';\n$PHPMAILER_LANG['encoding']             = 'Pengekodan tidak diketahui: ';\n$PHPMAILER_LANG['execute']              = 'Tidak dapat melaksanakan: ';\n$PHPMAILER_LANG['file_access']          = 'Tidak dapat mengakses fail: ';\n$PHPMAILER_LANG['file_open']            = 'Ralat Fail: Tidak dapat membuka fail: ';\n$PHPMAILER_LANG['from_failed']          = 'Berikut merupakan ralat dari alamat e-mel: ';\n$PHPMAILER_LANG['instantiate']          = 'Tidak dapat memberi contoh fungsi e-mel.';\n$PHPMAILER_LANG['invalid_address']      = 'Alamat emel tidak sah: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' jenis penghantar emel tidak disokong.';\n$PHPMAILER_LANG['provide_address']      = 'Anda perlu menyediakan sekurang-kurangnya satu alamat e-mel penerima.';\n$PHPMAILER_LANG['recipients_failed']    = 'Ralat SMTP: Penerima e-mel berikut telah gagal: ';\n$PHPMAILER_LANG['signing']              = 'Ralat pada tanda tangan: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() telah gagal.';\n$PHPMAILER_LANG['smtp_error']           = 'Ralat pada pelayan SMTP: ';\n$PHPMAILER_LANG['variable_set']         = 'Tidak boleh menetapkan atau menetapkan semula pembolehubah: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-nb.php",
    "content": "<?php\n/**\n * Norwegian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP Feil: Kunne ikke autentisere.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP Feil: Kunne ikke koble til SMTP tjener.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Feil: Data ble ikke akseptert.';\n$PHPMAILER_LANG['empty_message']        = 'Meldingsinnholdet er tomt';\n$PHPMAILER_LANG['encoding']             = 'Ukjent tegnkoding: ';\n$PHPMAILER_LANG['execute']              = 'Kunne ikke utføre: ';\n$PHPMAILER_LANG['file_access']          = 'Får ikke tilgang til filen: ';\n$PHPMAILER_LANG['file_open']            = 'Fil feil: Kunne ikke åpne filen: ';\n$PHPMAILER_LANG['from_failed']          = 'Følgende avsenderadresse feilet: ';\n$PHPMAILER_LANG['instantiate']          = 'Kunne ikke initialisere mailfunksjonen.';\n$PHPMAILER_LANG['invalid_address']      = 'Meldingen ble ikke sendt, følgende adresse er ugyldig: ';\n$PHPMAILER_LANG['provide_address']      = 'Du må angi minst en mottakeradresse.';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer er ikke supportert.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP Feil: Følgende mottagere feilet: ';\n$PHPMAILER_LANG['signing']              = 'Signeringsfeil: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() feilet.';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP-serverfeil: ';\n$PHPMAILER_LANG['variable_set']         = 'Kan ikke sette eller resette variabelen: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-nl.php",
    "content": "<?php\n/**\n * Dutch PHPMailer language file: refer to class.phpmailer.php for definitive list.\n * @package PHPMailer\n * @author Tuxion <team@tuxion.nl>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP-fout: authenticatie mislukt.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP-fout: kon niet verbinden met SMTP-host.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP-fout: data niet geaccepteerd.';\n$PHPMAILER_LANG['empty_message']        = 'Berichttekst is leeg';\n$PHPMAILER_LANG['encoding']             = 'Onbekende codering: ';\n$PHPMAILER_LANG['execute']              = 'Kon niet uitvoeren: ';\n$PHPMAILER_LANG['file_access']          = 'Kreeg geen toegang tot bestand: ';\n$PHPMAILER_LANG['file_open']            = 'Bestandsfout: kon bestand niet openen: ';\n$PHPMAILER_LANG['from_failed']          = 'Het volgende afzendersadres is mislukt: ';\n$PHPMAILER_LANG['instantiate']          = 'Kon mailfunctie niet initialiseren.';\n$PHPMAILER_LANG['invalid_address']      = 'Ongeldig adres: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer wordt niet ondersteund.';\n$PHPMAILER_LANG['provide_address']      = 'Er moet minstens één ontvanger worden opgegeven.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP-fout: de volgende ontvangers zijn mislukt: ';\n$PHPMAILER_LANG['signing']              = 'Signeerfout: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Verbinding mislukt.';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP-serverfout: ';\n$PHPMAILER_LANG['variable_set']         = 'Kan de volgende variabele niet instellen of resetten: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-pl.php",
    "content": "<?php\n/**\n * Polish PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Błąd SMTP: Nie można przeprowadzić uwierzytelnienia.';\n$PHPMAILER_LANG['connect_host']         = 'Błąd SMTP: Nie można połączyć się z wybranym hostem.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Błąd SMTP: Dane nie zostały przyjęte.';\n$PHPMAILER_LANG['empty_message']        = 'Wiadomość jest pusta.';\n$PHPMAILER_LANG['encoding']             = 'Nieznany sposób kodowania znaków: ';\n$PHPMAILER_LANG['execute']              = 'Nie można uruchomić: ';\n$PHPMAILER_LANG['file_access']          = 'Brak dostępu do pliku: ';\n$PHPMAILER_LANG['file_open']            = 'Nie można otworzyć pliku: ';\n$PHPMAILER_LANG['from_failed']          = 'Następujący adres Nadawcy jest nieprawidłowy: ';\n$PHPMAILER_LANG['instantiate']          = 'Nie można wywołać funkcji mail(). Sprawdź konfigurację serwera.';\n$PHPMAILER_LANG['invalid_address']      = 'Nie można wysłać wiadomości, '.\n    'następujący adres Odbiorcy jest nieprawidłowy: ';\n$PHPMAILER_LANG['provide_address']      = 'Należy podać prawidłowy adres email Odbiorcy.';\n$PHPMAILER_LANG['mailer_not_supported'] = 'Wybrana metoda wysyłki wiadomości nie jest obsługiwana.';\n$PHPMAILER_LANG['recipients_failed']    = 'Błąd SMTP: Następujący odbiorcy są nieprawidłowi: ';\n$PHPMAILER_LANG['signing']              = 'Błąd podpisywania wiadomości: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() zakończone niepowodzeniem.';\n$PHPMAILER_LANG['smtp_error']           = 'Błąd SMTP: ';\n$PHPMAILER_LANG['variable_set']         = 'Nie można ustawić lub zmodyfikować zmiennej: ';\n$PHPMAILER_LANG['extension_missing']    = 'Brakujące rozszerzenie: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-pt.php",
    "content": "<?php\n/**\n * Portuguese (European) PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Jonadabe <jonadabe@hotmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Erro do SMTP: Não foi possível realizar a autenticação.';\n$PHPMAILER_LANG['connect_host']         = 'Erro do SMTP: Não foi possível realizar ligação com o servidor SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Erro do SMTP: Os dados foram rejeitados.';\n$PHPMAILER_LANG['empty_message']        = 'A mensagem no e-mail está vazia.';\n$PHPMAILER_LANG['encoding']             = 'Codificação desconhecida: ';\n$PHPMAILER_LANG['execute']              = 'Não foi possível executar: ';\n$PHPMAILER_LANG['file_access']          = 'Não foi possível aceder o ficheiro: ';\n$PHPMAILER_LANG['file_open']            = 'Abertura do ficheiro: Não foi possível abrir o ficheiro: ';\n$PHPMAILER_LANG['from_failed']          = 'Ocorreram falhas nos endereços dos seguintes remententes: ';\n$PHPMAILER_LANG['instantiate']          = 'Não foi possível iniciar uma instância da função mail.';\n$PHPMAILER_LANG['invalid_address']      = 'Não foi enviado nenhum e-mail para o endereço de e-mail inválido: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer não é suportado.';\n$PHPMAILER_LANG['provide_address']      = 'Tem de fornecer pelo menos um endereço como destinatário do e-mail.';\n$PHPMAILER_LANG['recipients_failed']    = 'Erro do SMTP: O endereço do seguinte destinatário falhou: ';\n$PHPMAILER_LANG['signing']              = 'Erro ao assinar: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() falhou.';\n$PHPMAILER_LANG['smtp_error']           = 'Erro de servidor SMTP: ';\n$PHPMAILER_LANG['variable_set']         = 'Não foi possível definir ou redefinir a variável: ';\n$PHPMAILER_LANG['extension_missing']    = 'Extensão em falta: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-pt_br.php",
    "content": "<?php\n/**\n * Brazilian Portuguese PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Paulo Henrique Garcia <paulo@controllerweb.com.br>\n * @author Lucas Guimarães <lucas@lucasguimaraes.com>\n * @author Phelipe Alves <phelipealvesdesouza@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Erro de SMTP: Não foi possível autenticar.';\n$PHPMAILER_LANG['connect_host']         = 'Erro de SMTP: Não foi possível conectar ao servidor SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Erro de SMTP: Dados rejeitados.';\n$PHPMAILER_LANG['empty_message']        = 'Mensagem vazia';\n$PHPMAILER_LANG['encoding']             = 'Codificação desconhecida: ';\n$PHPMAILER_LANG['execute']              = 'Não foi possível executar: ';\n$PHPMAILER_LANG['file_access']          = 'Não foi possível acessar o arquivo: ';\n$PHPMAILER_LANG['file_open']            = 'Erro de Arquivo: Não foi possível abrir o arquivo: ';\n$PHPMAILER_LANG['from_failed']          = 'Os seguintes remententes falharam: ';\n$PHPMAILER_LANG['instantiate']          = 'Não foi possível instanciar a função mail.';\n$PHPMAILER_LANG['invalid_address']      = 'Endereço de e-mail inválido: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer não é suportado.';\n$PHPMAILER_LANG['provide_address']      = 'Você deve informar pelo menos um destinatário.';\n$PHPMAILER_LANG['recipients_failed']    = 'Erro de SMTP: Os seguintes destinatários falharam: ';\n$PHPMAILER_LANG['signing']              = 'Erro de Assinatura: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() falhou.';\n$PHPMAILER_LANG['smtp_error']           = 'Erro de servidor SMTP: ';\n$PHPMAILER_LANG['variable_set']         = 'Não foi possível definir ou redefinir a variável: ';\n$PHPMAILER_LANG['extension_missing']    = 'Extensão ausente: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-ro.php",
    "content": "<?php\n/**\n * Romanian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Alex Florea <alecz.fia@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Eroare SMTP: Autentificarea a eșuat.';\n$PHPMAILER_LANG['connect_host']         = 'Eroare SMTP: Conectarea la serverul SMTP a eșuat.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Eroare SMTP: Datele nu au fost acceptate.';\n$PHPMAILER_LANG['empty_message']        = 'Mesajul este gol.';\n$PHPMAILER_LANG['encoding']             = 'Encodare necunoscută: ';\n$PHPMAILER_LANG['execute']              = 'Nu se poate executa următoarea comandă:  ';\n$PHPMAILER_LANG['file_access']          = 'Nu se poate accesa următorul fișier: ';\n$PHPMAILER_LANG['file_open']            = 'Eroare fișier: Nu se poate deschide următorul fișier: ';\n$PHPMAILER_LANG['from_failed']          = 'Următoarele adrese From au dat eroare: ';\n$PHPMAILER_LANG['instantiate']          = 'Funcția mail nu a putut fi inițializată.';\n$PHPMAILER_LANG['invalid_address']      = 'Adresa de email nu este validă: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer nu este suportat.';\n$PHPMAILER_LANG['provide_address']      = 'Trebuie să adăugați cel puțin o adresă de email.';\n$PHPMAILER_LANG['recipients_failed']    = 'Eroare SMTP: Următoarele adrese de email au eșuat: ';\n$PHPMAILER_LANG['signing']              = 'A aparut o problemă la semnarea emailului. ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'Conectarea la serverul SMTP a eșuat.';\n$PHPMAILER_LANG['smtp_error']           = 'Eroare server SMTP: ';\n$PHPMAILER_LANG['variable_set']         = 'Nu se poate seta/reseta variabila. ';\n$PHPMAILER_LANG['extension_missing']    = 'Lipsește extensia: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-ru.php",
    "content": "<?php\n/**\n * Russian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Alexey Chumakov <alex@chumakov.ru>\n * @author Foster Snowhill <i18n@forstwoof.ru>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Ошибка SMTP: ошибка авторизации.';\n$PHPMAILER_LANG['connect_host']         = 'Ошибка SMTP: не удается подключиться к серверу SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Ошибка SMTP: данные не приняты.';\n$PHPMAILER_LANG['encoding']             = 'Неизвестный вид кодировки: ';\n$PHPMAILER_LANG['execute']              = 'Невозможно выполнить команду: ';\n$PHPMAILER_LANG['file_access']          = 'Нет доступа к файлу: ';\n$PHPMAILER_LANG['file_open']            = 'Файловая ошибка: не удается открыть файл: ';\n$PHPMAILER_LANG['from_failed']          = 'Неверный адрес отправителя: ';\n$PHPMAILER_LANG['instantiate']          = 'Невозможно запустить функцию mail.';\n$PHPMAILER_LANG['provide_address']      = 'Пожалуйста, введите хотя бы один адрес e-mail получателя.';\n$PHPMAILER_LANG['mailer_not_supported'] = ' — почтовый сервер не поддерживается.';\n$PHPMAILER_LANG['recipients_failed']    = 'Ошибка SMTP: отправка по следующим адресам получателей не удалась: ';\n$PHPMAILER_LANG['empty_message']        = 'Пустое сообщение';\n$PHPMAILER_LANG['invalid_address']      = 'Не отослано, неправильный формат email адреса: ';\n$PHPMAILER_LANG['signing']              = 'Ошибка подписи: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'Ошибка соединения с SMTP-сервером';\n$PHPMAILER_LANG['smtp_error']           = 'Ошибка SMTP-сервера: ';\n$PHPMAILER_LANG['variable_set']         = 'Невозможно установить или переустановить переменную: ';\n$PHPMAILER_LANG['extension_missing']    = 'Расширение отсутствует: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-sk.php",
    "content": "<?php\n/**\n * Slovak PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Michal Tinka <michaltinka@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP Error: Chyba autentifikácie.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP Error: Nebolo možné nadviazať spojenie so SMTP serverom.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Error: Dáta neboli prijaté';\n$PHPMAILER_LANG['empty_message']        = 'Prázdne telo správy.';\n$PHPMAILER_LANG['encoding']             = 'Neznáme kódovanie: ';\n$PHPMAILER_LANG['execute']              = 'Nedá sa vykonať: ';\n$PHPMAILER_LANG['file_access']          = 'Súbor nebol nájdený: ';\n$PHPMAILER_LANG['file_open']            = 'File Error: Súbor sa otvoriť pre čítanie: ';\n$PHPMAILER_LANG['from_failed']          = 'Následujúca adresa From je nesprávna: ';\n$PHPMAILER_LANG['instantiate']          = 'Nedá sa vytvoriť inštancia emailovej funkcie.';\n$PHPMAILER_LANG['invalid_address']      = 'Neodoslané, emailová adresa je nesprávna: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' emailový klient nieje podporovaný.';\n$PHPMAILER_LANG['provide_address']      = 'Musíte zadať aspoň jednu emailovú adresu príjemcu.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP Error: Adresy príjemcov niesu správne ';\n$PHPMAILER_LANG['signing']              = 'Chyba prihlasovania: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() zlyhalo.';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP chyba serveru: ';\n$PHPMAILER_LANG['variable_set']         = 'Nemožno nastaviť alebo resetovať premennú: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-sl.php",
    "content": "<?php\n/**\n * Slovene PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Klemen Tušar <techouse@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP napaka: Avtentikacija ni uspela.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP napaka: Ne morem vzpostaviti povezave s SMTP gostiteljem.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP napaka: Strežnik zavrača podatke.';\n$PHPMAILER_LANG['empty_message']        = 'E-poštno sporočilo nima vsebine.';\n$PHPMAILER_LANG['encoding']             = 'Nepoznan tip kodiranja: ';\n$PHPMAILER_LANG['execute']              = 'Operacija ni uspela: ';\n$PHPMAILER_LANG['file_access']          = 'Nimam dostopa do datoteke: ';\n$PHPMAILER_LANG['file_open']            = 'Ne morem odpreti datoteke: ';\n$PHPMAILER_LANG['from_failed']          = 'Neveljaven e-naslov pošiljatelja: ';\n$PHPMAILER_LANG['instantiate']          = 'Ne morem inicializirati mail funkcije.';\n$PHPMAILER_LANG['invalid_address']      = 'E-poštno sporočilo ni bilo poslano. E-naslov je neveljaven: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer ni podprt.';\n$PHPMAILER_LANG['provide_address']      = 'Prosim vnesite vsaj enega naslovnika.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP napaka: Sledeči naslovniki so neveljavni: ';\n$PHPMAILER_LANG['signing']              = 'Napaka pri podpisovanju: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'Ne morem vzpostaviti povezave s SMTP strežnikom.';\n$PHPMAILER_LANG['smtp_error']           = 'Napaka SMTP strežnika: ';\n$PHPMAILER_LANG['variable_set']         = 'Ne morem nastaviti oz. ponastaviti spremenljivke: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-sr.php",
    "content": "<?php\n/**\n * Serbian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Александар Јевремовић <ajevremovic@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP грешка: аутентификација није успела.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP грешка: није могуће повезивање са SMTP сервером.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP грешка: подаци нису прихваћени.';\n$PHPMAILER_LANG['empty_message']        = 'Садржај поруке је празан.';\n$PHPMAILER_LANG['encoding']             = 'Непознато кодовање: ';\n$PHPMAILER_LANG['execute']              = 'Није могуће извршити наредбу: ';\n$PHPMAILER_LANG['file_access']          = 'Није могуће приступити датотеци: ';\n$PHPMAILER_LANG['file_open']            = 'Није могуће отворити датотеку: ';\n$PHPMAILER_LANG['from_failed']          = 'SMTP грешка: слање са следећих адреса није успело: ';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP грешка: слање на следеће адресе није успело: ';\n$PHPMAILER_LANG['instantiate']          = 'Није могуће покренути mail функцију.';\n$PHPMAILER_LANG['invalid_address']      = 'Порука није послата због неисправне адресе: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' мејлер није подржан.';\n$PHPMAILER_LANG['provide_address']      = 'Потребно је задати најмање једну адресу.';\n$PHPMAILER_LANG['signing']              = 'Грешка приликом пријављивања: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'Повезивање са SMTP сервером није успело.';\n$PHPMAILER_LANG['smtp_error']           = 'Грешка SMTP сервера: ';\n$PHPMAILER_LANG['variable_set']         = 'Није могуће задати променљиву, нити је вратити уназад: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-sv.php",
    "content": "<?php\n/**\n * Swedish PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Johan Linnér <johan@linner.biz>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP fel: Kunde inte autentisera.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP fel: Kunde inte ansluta till SMTP-server.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP fel: Data accepterades inte.';\n//$PHPMAILER_LANG['empty_message']        = 'Message body empty';\n$PHPMAILER_LANG['encoding']             = 'Okänt encode-format: ';\n$PHPMAILER_LANG['execute']              = 'Kunde inte köra: ';\n$PHPMAILER_LANG['file_access']          = 'Ingen åtkomst till fil: ';\n$PHPMAILER_LANG['file_open']            = 'Fil fel: Kunde inte öppna fil: ';\n$PHPMAILER_LANG['from_failed']          = 'Följande avsändaradress är felaktig: ';\n$PHPMAILER_LANG['instantiate']          = 'Kunde inte initiera e-postfunktion.';\n$PHPMAILER_LANG['invalid_address']      = 'Felaktig adress: ';\n$PHPMAILER_LANG['provide_address']      = 'Du måste ange minst en mottagares e-postadress.';\n$PHPMAILER_LANG['mailer_not_supported'] = ' mailer stöds inte.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP fel: Följande mottagare är felaktig: ';\n$PHPMAILER_LANG['signing']              = 'Signerings fel: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP Connect() misslyckades.';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP server fel: ';\n$PHPMAILER_LANG['variable_set']         = 'Kunde inte definiera eller återställa variabel: ';\n$PHPMAILER_LANG['extension_missing']    = 'Tillägg ej tillgängligt: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-tr.php",
    "content": "<?php\n/**\n * Turkish PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Elçin Özel\n * @author Can Yılmaz\n * @author Mehmet Benlioğlu\n * @author @yasinaydin\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP Hatası: Oturum açılamadı.';\n$PHPMAILER_LANG['connect_host']         = 'SMTP Hatası: SMTP sunucusuna bağlanılamadı.';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP Hatası: Veri kabul edilmedi.';\n$PHPMAILER_LANG['empty_message']        = 'Mesajın içeriği boş';\n$PHPMAILER_LANG['encoding']             = 'Bilinmeyen karakter kodlama: ';\n$PHPMAILER_LANG['execute']              = 'Çalıştırılamadı: ';\n$PHPMAILER_LANG['file_access']          = 'Dosyaya erişilemedi: ';\n$PHPMAILER_LANG['file_open']            = 'Dosya Hatası: Dosya açılamadı: ';\n$PHPMAILER_LANG['from_failed']          = 'Belirtilen adreslere gönderme başarısız: ';\n$PHPMAILER_LANG['instantiate']          = 'Örnek e-posta fonksiyonu oluşturulamadı.';\n$PHPMAILER_LANG['invalid_address']      = 'Geçersiz e-posta adresi: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' e-posta kütüphanesi desteklenmiyor.';\n$PHPMAILER_LANG['provide_address']      = 'En az bir alıcı e-posta adresi belirtmelisiniz.';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP Hatası: Belirtilen alıcılara ulaşılamadı: ';\n$PHPMAILER_LANG['signing']              = 'İmzalama hatası: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP connect() fonksiyonu başarısız.';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP sunucu hatası: ';\n$PHPMAILER_LANG['variable_set']         = 'Değişken ayarlanamadı ya da sıfırlanamadı: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-uk.php",
    "content": "<?php\n/**\n * Ukrainian PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author Yuriy Rudyy <yrudyy@prs.net.ua>\n * @fixed by Boris Yurchenko <boris@yurchenko.pp.ua>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Помилка SMTP: помилка авторизації.';\n$PHPMAILER_LANG['connect_host']         = 'Помилка SMTP: не вдається під\\'єднатися до серверу SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Помилка SMTP: дані не прийняті.';\n$PHPMAILER_LANG['encoding']             = 'Невідомий тип кодування: ';\n$PHPMAILER_LANG['execute']              = 'Неможливо виконати команду: ';\n$PHPMAILER_LANG['file_access']          = 'Немає доступу до файлу: ';\n$PHPMAILER_LANG['file_open']            = 'Помилка файлової системи: не вдається відкрити файл: ';\n$PHPMAILER_LANG['from_failed']          = 'Невірна адреса відправника: ';\n$PHPMAILER_LANG['instantiate']          = 'Неможливо запустити функцію mail.';\n$PHPMAILER_LANG['provide_address']      = 'Будь-ласка, введіть хоча б одну адресу e-mail отримувача.';\n$PHPMAILER_LANG['mailer_not_supported'] = ' - поштовий сервер не підтримується.';\n$PHPMAILER_LANG['recipients_failed']    = 'Помилка SMTP: відправлення наступним отримувачам не вдалося: ';\n$PHPMAILER_LANG['empty_message']        = 'Пусте тіло повідомлення';\n$PHPMAILER_LANG['invalid_address']      = 'Не відправлено, невірний формат адреси e-mail: ';\n$PHPMAILER_LANG['signing']              = 'Помилка підпису: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'Помилка з\\'єднання із SMTP-сервером';\n$PHPMAILER_LANG['smtp_error']           = 'Помилка SMTP-сервера: ';\n$PHPMAILER_LANG['variable_set']         = 'Неможливо встановити або перевстановити змінну: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-vi.php",
    "content": "<?php\n/**\n * Vietnamese (Tiếng Việt) PHPMailer language file: refer to English translation for definitive list.\n * @package PHPMailer\n * @author VINADES.,JSC <contact@vinades.vn>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'Lỗi SMTP: Không thể xác thực.';\n$PHPMAILER_LANG['connect_host']         = 'Lỗi SMTP: Không thể kết nối máy chủ SMTP.';\n$PHPMAILER_LANG['data_not_accepted']    = 'Lỗi SMTP: Dữ liệu không được chấp nhận.';\n$PHPMAILER_LANG['empty_message']        = 'Không có nội dung';\n$PHPMAILER_LANG['encoding']             = 'Mã hóa không xác định: ';\n$PHPMAILER_LANG['execute']              = 'Không thực hiện được: ';\n$PHPMAILER_LANG['file_access']          = 'Không thể truy cập tệp tin ';\n$PHPMAILER_LANG['file_open']            = 'Lỗi Tập tin: Không thể mở tệp tin: ';\n$PHPMAILER_LANG['from_failed']          = 'Lỗi địa chỉ gửi đi: ';\n$PHPMAILER_LANG['instantiate']          = 'Không dùng được các hàm gửi thư.';\n$PHPMAILER_LANG['invalid_address']      = 'Đại chỉ emai không đúng: ';\n$PHPMAILER_LANG['mailer_not_supported'] = ' trình gửi thư không được hỗ trợ.';\n$PHPMAILER_LANG['provide_address']      = 'Bạn phải cung cấp ít nhất một địa chỉ người nhận.';\n$PHPMAILER_LANG['recipients_failed']    = 'Lỗi SMTP: lỗi địa chỉ người nhận: ';\n$PHPMAILER_LANG['signing']              = 'Lỗi đăng nhập: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'Lỗi kết nối với SMTP';\n$PHPMAILER_LANG['smtp_error']           = 'Lỗi máy chủ smtp ';\n$PHPMAILER_LANG['variable_set']         = 'Không thể thiết lập hoặc thiết lập lại biến: ';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-zh.php",
    "content": "<?php\n/**\n * Traditional Chinese PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author liqwei <liqwei@liqwei.com>\n * @author Peter Dave Hello <@PeterDaveHello/>\n * @author Jason Chiang <xcojad@gmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP 錯誤：登入失敗。';\n$PHPMAILER_LANG['connect_host']         = 'SMTP 錯誤：無法連線到 SMTP 主機。';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP 錯誤：無法接受的資料。';\n$PHPMAILER_LANG['empty_message']        = '郵件內容為空';\n$PHPMAILER_LANG['encoding']             = '未知編碼: ';\n$PHPMAILER_LANG['execute']              = '無法執行：';\n$PHPMAILER_LANG['file_access']          = '無法存取檔案：';\n$PHPMAILER_LANG['file_open']            = '檔案錯誤：無法開啟檔案：';\n$PHPMAILER_LANG['from_failed']          = '發送地址錯誤：';\n$PHPMAILER_LANG['instantiate']          = '未知函數呼叫。';\n$PHPMAILER_LANG['invalid_address']      = '因為電子郵件地址無效，無法傳送: ';\n$PHPMAILER_LANG['mailer_not_supported'] = '不支援的發信客戶端。';\n$PHPMAILER_LANG['provide_address']      = '必須提供至少一個收件人地址。';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP 錯誤：以下收件人地址錯誤：';\n$PHPMAILER_LANG['signing']              = '電子簽章錯誤: ';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP 連線失敗';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP 伺服器錯誤: ';\n$PHPMAILER_LANG['variable_set']         = '無法設定或重設變數: ';\n$PHPMAILER_LANG['extension_missing']    = '遺失模組 Extension: ';\n"
  },
  {
    "path": "vendor/phpmailer/phpmailer/language/phpmailer.lang-zh_cn.php",
    "content": "<?php\n/**\n * Simplified Chinese PHPMailer language file: refer to English translation for definitive list\n * @package PHPMailer\n * @author liqwei <liqwei@liqwei.com>\n * @author young <masxy@foxmail.com>\n */\n\n$PHPMAILER_LANG['authenticate']         = 'SMTP 错误：登录失败。';\n$PHPMAILER_LANG['connect_host']         = 'SMTP 错误：无法连接到 SMTP 主机。';\n$PHPMAILER_LANG['data_not_accepted']    = 'SMTP 错误：数据不被接受。';\n$PHPMAILER_LANG['empty_message']        = '邮件正文为空。';\n$PHPMAILER_LANG['encoding']             = '未知编码: ';\n$PHPMAILER_LANG['execute']              = '无法执行：';\n$PHPMAILER_LANG['file_access']          = '无法访问文件：';\n$PHPMAILER_LANG['file_open']            = '文件错误：无法打开文件：';\n$PHPMAILER_LANG['from_failed']          = '发送地址错误：';\n$PHPMAILER_LANG['instantiate']          = '未知函数调用。';\n$PHPMAILER_LANG['invalid_address']      = '发送失败，电子邮箱地址是无效的：';\n$PHPMAILER_LANG['mailer_not_supported'] = '发信客户端不被支持。';\n$PHPMAILER_LANG['provide_address']      = '必须提供至少一个收件人地址。';\n$PHPMAILER_LANG['recipients_failed']    = 'SMTP 错误：收件人地址错误：';\n$PHPMAILER_LANG['signing']              = '登录失败：';\n$PHPMAILER_LANG['smtp_connect_failed']  = 'SMTP服务器连接失败。';\n$PHPMAILER_LANG['smtp_error']           = 'SMTP服务器出错: ';\n$PHPMAILER_LANG['variable_set']         = '无法设置或重置变量：';\n//$PHPMAILER_LANG['extension_missing']    = 'Extension missing: ';\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/.gitattributes",
    "content": "/Build export-ignore\n/Documentation export-ignore\n/Tests export-ignore\nREADME.md export-ignore\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/.gitignore",
    "content": "build/PHPExcel.phar\nunitTests/codeCoverage\nanalysis\n\n## IDE support\n*.buildpath\n*.project\n/.settings\n/.idea\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/.travis.yml",
    "content": "language: php\n\nphp:\n  - 5.2\n  - 5.3.3\n  - 5.3\n  - 5.4\n  - 5.5\n  - 5.6\n  - hhvm\n \nmatrix:\n    allow_failures:\n        - php: hhvm\n\nscript:\n - phpunit -c ./unitTests/\n\nnotifications:\n  email: false\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Autoloader.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\nPHPExcel_Autoloader::Register();\n//    As we always try to run the autoloader before anything else, we can use it to do a few\n//        simple checks and initialisations\n//PHPExcel_Shared_ZipStreamWrapper::register();\n// check mbstring.func_overload\nif (ini_get('mbstring.func_overload') & 2) {\n    throw new PHPExcel_Exception('Multibyte function overloading in PHP must be disabled for string functions (2).');\n}\nPHPExcel_Shared_String::buildCharacterSets();\n\n\n/**\n * PHPExcel_Autoloader\n *\n * @category    PHPExcel\n * @package     PHPExcel\n * @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Autoloader\n{\n    /**\n     * Register the Autoloader with SPL\n     *\n     */\n    public static function Register() {\n        if (function_exists('__autoload')) {\n            //    Register any existing autoloader function with SPL, so we don't get any clashes\n            spl_autoload_register('__autoload');\n        }\n        //    Register ourselves with SPL\n        if (version_compare(PHP_VERSION, '5.3.0') >= 0) {\n            return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'), true, true);\n        } else {\n            return spl_autoload_register(array('PHPExcel_Autoloader', 'Load'));\n        }\n    }   //    function Register()\n\n\n    /**\n     * Autoload a class identified by name\n     *\n     * @param    string    $pClassName        Name of the object to load\n     */\n    public static function Load($pClassName){\n        if ((class_exists($pClassName,FALSE)) || (strpos($pClassName, 'PHPExcel') !== 0)) {\n            //    Either already loaded, or not a PHPExcel class request\n            return FALSE;\n        }\n\n        $pClassFilePath = PHPEXCEL_ROOT .\n                          str_replace('_',DIRECTORY_SEPARATOR,$pClassName) .\n                          '.php';\n\n        if ((file_exists($pClassFilePath) === FALSE) || (is_readable($pClassFilePath) === FALSE)) {\n            //    Can't load\n            return FALSE;\n        }\n\n        require($pClassFilePath);\n    }   //    function Load()\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorage/APC.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_CachedObjectStorage\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_CachedObjectStorage_APC\n *\n * @category   PHPExcel\n * @package    PHPExcel_CachedObjectStorage\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_CachedObjectStorage_APC extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {\n\n    /**\n     * Prefix used to uniquely identify cache data for this worksheet\n     *\n     * @access    private\n     * @var string\n     */\n    private $_cachePrefix = null;\n\n    /**\n     * Cache timeout\n     *\n     * @access    private\n     * @var integer\n     */\n    private $_cacheTime = 600;\n\n\n    /**\n     * Store cell data in cache for the current cell object if it's \"dirty\",\n     *     and the 'nullify' the current cell object\n     *\n     * @access  private\n     * @return  void\n     * @throws  PHPExcel_Exception\n     */\n    protected function _storeData() {\n        if ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) {\n            $this->_currentObject->detach();\n\n            if (!apc_store($this->_cachePrefix.$this->_currentObjectID.'.cache',serialize($this->_currentObject),$this->_cacheTime)) {\n                $this->__destruct();\n                throw new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in APC');\n            }\n            $this->_currentCellIsDirty = false;\n        }\n        $this->_currentObjectID = $this->_currentObject = null;\n    }    //    function _storeData()\n\n\n    /**\n     * Add or Update a cell in cache identified by coordinate address\n     *\n     * @access  public\n     * @param   string         $pCoord  Coordinate address of the cell to update\n     * @param   PHPExcel_Cell  $cell    Cell to update\n     * @return  PHPExcel_Cell\n     * @throws  PHPExcel_Exception\n     */\n    public function addCacheData($pCoord, PHPExcel_Cell $cell) {\n        if (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {\n            $this->_storeData();\n        }\n        $this->_cellCache[$pCoord] = true;\n\n        $this->_currentObjectID = $pCoord;\n        $this->_currentObject = $cell;\n        $this->_currentCellIsDirty = true;\n\n        return $cell;\n    }    //    function addCacheData()\n\n\n    /**\n     * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?\n     *\n     * @access  public\n     * @param   string  $pCoord  Coordinate address of the cell to check\n     * @throws  PHPExcel_Exception\n     * @return  boolean\n     */\n    public function isDataSet($pCoord) {\n        //    Check if the requested entry is the current object, or exists in the cache\n        if (parent::isDataSet($pCoord)) {\n            if ($this->_currentObjectID == $pCoord) {\n                return true;\n            }\n            //    Check if the requested entry still exists in apc\n            $success = apc_fetch($this->_cachePrefix.$pCoord.'.cache');\n            if ($success === FALSE) {\n                //    Entry no longer exists in APC, so clear it from the cache array\n                parent::deleteCacheData($pCoord);\n                throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache');\n            }\n            return true;\n        }\n        return false;\n    }    //    function isDataSet()\n\n\n    /**\n     * Get cell at a specific coordinate\n     *\n     * @access  public\n     * @param   string         $pCoord  Coordinate of the cell\n     * @throws  PHPExcel_Exception\n     * @return  PHPExcel_Cell  Cell that was found, or null if not found\n     */\n    public function getCacheData($pCoord) {\n        if ($pCoord === $this->_currentObjectID) {\n            return $this->_currentObject;\n        }\n        $this->_storeData();\n\n        //    Check if the entry that has been requested actually exists\n        if (parent::isDataSet($pCoord)) {\n            $obj = apc_fetch($this->_cachePrefix.$pCoord.'.cache');\n            if ($obj === FALSE) {\n                //    Entry no longer exists in APC, so clear it from the cache array\n                parent::deleteCacheData($pCoord);\n                throw new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in APC cache');\n            }\n        } else {\n            //    Return null if requested entry doesn't exist in cache\n            return null;\n        }\n\n        //    Set current entry to the requested entry\n        $this->_currentObjectID = $pCoord;\n        $this->_currentObject = unserialize($obj);\n        //    Re-attach this as the cell's parent\n        $this->_currentObject->attach($this);\n\n        //    Return requested entry\n        return $this->_currentObject;\n    }    //    function getCacheData()\n\n\n\t/**\n\t * Get a list of all cell addresses currently held in cache\n\t *\n\t * @return  string[]\n\t */\n\tpublic function getCellList() {\n\t\tif ($this->_currentObjectID !== null) {\n\t\t\t$this->_storeData();\n\t\t}\n\n\t\treturn parent::getCellList();\n\t}\n\n\n    /**\n     * Delete a cell in cache identified by coordinate address\n     *\n     * @access  public\n     * @param   string  $pCoord  Coordinate address of the cell to delete\n     * @throws  PHPExcel_Exception\n     */\n    public function deleteCacheData($pCoord) {\n        //    Delete the entry from APC\n        apc_delete($this->_cachePrefix.$pCoord.'.cache');\n\n        //    Delete the entry from our cell address array\n        parent::deleteCacheData($pCoord);\n    }    //    function deleteCacheData()\n\n\n    /**\n     * Clone the cell collection\n     *\n     * @access  public\n     * @param   PHPExcel_Worksheet  $parent  The new worksheet\n     * @throws  PHPExcel_Exception\n     * @return  void\n     */\n    public function copyCellCollection(PHPExcel_Worksheet $parent) {\n        parent::copyCellCollection($parent);\n        //    Get a new id for the new file name\n        $baseUnique = $this->_getUniqueID();\n        $newCachePrefix = substr(md5($baseUnique),0,8).'.';\n        $cacheList = $this->getCellList();\n        foreach($cacheList as $cellID) {\n            if ($cellID != $this->_currentObjectID) {\n                $obj = apc_fetch($this->_cachePrefix.$cellID.'.cache');\n                if ($obj === FALSE) {\n                    //    Entry no longer exists in APC, so clear it from the cache array\n                    parent::deleteCacheData($cellID);\n                    throw new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in APC');\n                }\n                if (!apc_store($newCachePrefix.$cellID.'.cache',$obj,$this->_cacheTime)) {\n                    $this->__destruct();\n                    throw new PHPExcel_Exception('Failed to store cell '.$cellID.' in APC');\n                }\n            }\n        }\n        $this->_cachePrefix = $newCachePrefix;\n    }    //    function copyCellCollection()\n\n\n    /**\n     * Clear the cell collection and disconnect from our parent\n     *\n     * @return  void\n     */\n    public function unsetWorksheetCells() {\n        if ($this->_currentObject !== NULL) {\n            $this->_currentObject->detach();\n            $this->_currentObject = $this->_currentObjectID = null;\n        }\n\n        //    Flush the APC cache\n        $this->__destruct();\n\n        $this->_cellCache = array();\n\n        //    detach ourself from the worksheet, so that it can then delete this object successfully\n        $this->_parent = null;\n    }    //    function unsetWorksheetCells()\n\n\n    /**\n     * Initialise this new cell collection\n     *\n     * @param  PHPExcel_Worksheet  $parent     The worksheet for this cell collection\n     * @param  array of mixed      $arguments  Additional initialisation arguments\n     */\n    public function __construct(PHPExcel_Worksheet $parent, $arguments) {\n        $cacheTime = (isset($arguments['cacheTime'])) ? $arguments['cacheTime'] : 600;\n\n        if ($this->_cachePrefix === NULL) {\n            $baseUnique = $this->_getUniqueID();\n            $this->_cachePrefix = substr(md5($baseUnique),0,8).'.';\n            $this->_cacheTime = $cacheTime;\n\n            parent::__construct($parent);\n        }\n    }    //    function __construct()\n\n\n    /**\n     * Destroy this cell collection\n     */\n    public function __destruct() {\n        $cacheList = $this->getCellList();\n        foreach($cacheList as $cellID) {\n            apc_delete($this->_cachePrefix.$cellID.'.cache');\n        }\n    }    //    function __destruct()\n\n\n    /**\n     * Identify whether the caching method is currently available\n     * Some methods are dependent on the availability of certain extensions being enabled in the PHP build\n     *\n     * @return  boolean\n     */\n    public static function cacheMethodIsAvailable() {\n        if (!function_exists('apc_store')) {\n            return FALSE;\n        }\n        if (apc_sma_info() === FALSE) {\n            return FALSE;\n        }\n\n        return TRUE;\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorage/CacheBase.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (c) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n\r\n/**\r\n * PHPExcel_CachedObjectStorage_CacheBase\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n */\r\nabstract class PHPExcel_CachedObjectStorage_CacheBase {\r\n\r\n\t/**\r\n\t * Parent worksheet\r\n\t *\r\n\t * @var PHPExcel_Worksheet\r\n\t */\r\n\tprotected $_parent;\r\n\r\n\t/**\r\n\t * The currently active Cell\r\n\t *\r\n\t * @var PHPExcel_Cell\r\n\t */\r\n\tprotected $_currentObject = null;\r\n\r\n\t/**\r\n\t * Coordinate address of the currently active Cell\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprotected $_currentObjectID = null;\r\n\r\n\r\n\t/**\r\n\t * Flag indicating whether the currently active Cell requires saving\r\n\t *\r\n\t * @var boolean\r\n\t */\r\n\tprotected $_currentCellIsDirty = true;\r\n\r\n\t/**\r\n\t * An array of cells or cell pointers for the worksheet cells held in this cache,\r\n\t *\t\tand indexed by their coordinate address within the worksheet\r\n\t *\r\n\t * @var array of mixed\r\n\t */\r\n\tprotected $_cellCache = array();\r\n\r\n\r\n\t/**\r\n\t * Initialise this new cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe worksheet for this cell collection\r\n\t */\r\n\tpublic function __construct(PHPExcel_Worksheet $parent) {\r\n\t\t//\tSet our parent worksheet.\r\n\t\t//\tThis is maintained within the cache controller to facilitate re-attaching it to PHPExcel_Cell objects when\r\n\t\t//\t\tthey are woken from a serialized state\r\n\t\t$this->_parent = $parent;\r\n\t}\t//\tfunction __construct()\r\n\r\n\r\n\t/**\r\n\t * Return the parent worksheet for this cell collection\r\n\t *\r\n\t * @return\tPHPExcel_Worksheet\r\n\t */\r\n\tpublic function getParent()\r\n\t{\r\n\t\treturn $this->_parent;\r\n\t}\r\n\r\n\t/**\r\n\t * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?\r\n\t *\r\n\t * @param\tstring\t\t$pCoord\t\tCoordinate address of the cell to check\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic function isDataSet($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\t//\tCheck if the requested entry exists in the cache\r\n\t\treturn isset($this->_cellCache[$pCoord]);\r\n\t}\t//\tfunction isDataSet()\r\n\r\n\r\n\t/**\r\n\t * Move a cell object from one address to another\r\n\t *\r\n\t * @param\tstring\t\t$fromAddress\tCurrent address of the cell to move\r\n\t * @param\tstring\t\t$toAddress\t\tDestination address of the cell to move\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic function moveCell($fromAddress, $toAddress) {\r\n\t\tif ($fromAddress === $this->_currentObjectID) {\r\n\t\t\t$this->_currentObjectID = $toAddress;\r\n\t\t}\r\n\t\t$this->_currentCellIsDirty = true;\r\n\t\tif (isset($this->_cellCache[$fromAddress])) {\r\n\t\t\t$this->_cellCache[$toAddress] = &$this->_cellCache[$fromAddress];\r\n\t\t\tunset($this->_cellCache[$fromAddress]);\r\n\t\t}\r\n\r\n\t\treturn TRUE;\r\n\t}\t//\tfunction moveCell()\r\n\r\n\r\n    /**\r\n     * Add or Update a cell in cache\r\n     *\r\n     * @param\tPHPExcel_Cell\t$cell\t\tCell to update\r\n\t * @return\tPHPExcel_Cell\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function updateCacheData(PHPExcel_Cell $cell) {\r\n\t\treturn $this->addCacheData($cell->getCoordinate(),$cell);\r\n\t}\t//\tfunction updateCacheData()\r\n\r\n\r\n    /**\r\n     * Delete a cell in cache identified by coordinate address\r\n     *\r\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to delete\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function deleteCacheData($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID && !is_null($this->_currentObject)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\t\t\t$this->_currentObjectID = $this->_currentObject = null;\r\n\t\t}\r\n\r\n\t\tif (is_object($this->_cellCache[$pCoord])) {\r\n\t\t\t$this->_cellCache[$pCoord]->detach();\r\n\t\t\tunset($this->_cellCache[$pCoord]);\r\n\t\t}\r\n\t\t$this->_currentCellIsDirty = false;\r\n\t}\t//\tfunction deleteCacheData()\r\n\r\n\r\n\t/**\r\n\t * Get a list of all cell addresses currently held in cache\r\n\t *\r\n\t * @return\tstring[]\r\n\t */\r\n\tpublic function getCellList() {\r\n\t\treturn array_keys($this->_cellCache);\r\n\t}\t//\tfunction getCellList()\r\n\r\n\r\n\t/**\r\n\t * Sort the list of all cell addresses currently held in cache by row and column\r\n\t *\r\n\t * @return\tstring[]\r\n\t */\r\n\tpublic function getSortedCellList() {\r\n\t\t$sortKeys = array();\r\n\t\tforeach ($this->getCellList() as $coord) {\r\n\t\t\tsscanf($coord,'%[A-Z]%d', $column, $row);\r\n\t\t\t$sortKeys[sprintf('%09d%3s',$row,$column)] = $coord;\r\n\t\t}\r\n\t\tksort($sortKeys);\r\n\r\n\t\treturn array_values($sortKeys);\r\n\t}\t//\tfunction sortCellList()\r\n\r\n\r\n\r\n\t/**\r\n\t * Get highest worksheet column and highest row that have cell records\r\n\t *\r\n\t * @return array Highest column name and highest row number\r\n\t */\r\n\tpublic function getHighestRowAndColumn()\r\n\t{\r\n\t\t// Lookup highest column and highest row\r\n\t\t$col = array('A' => '1A');\r\n\t\t$row = array(1);\r\n\t\tforeach ($this->getCellList() as $coord) {\r\n\t\t\tsscanf($coord,'%[A-Z]%d', $c, $r);\r\n\t\t\t$row[$r] = $r;\r\n\t\t\t$col[$c] = strlen($c).$c;\r\n \t\t}\r\n\t\tif (!empty($row)) {\r\n\t\t\t// Determine highest column and row\r\n\t\t\t$highestRow = max($row);\r\n\t\t\t$highestColumn = substr(max($col),1);\r\n\t\t}\r\n\r\n\t\treturn array( 'row'\t   => $highestRow,\r\n\t\t\t\t\t  'column' => $highestColumn\r\n\t\t\t\t\t);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Return the cell address of the currently active cell object\r\n\t *\r\n\t * @return\tstring\r\n\t */\r\n\tpublic function getCurrentAddress()\r\n\t{\r\n\t\treturn $this->_currentObjectID;\r\n\t}\r\n\r\n\t/**\r\n\t * Return the column address of the currently active cell object\r\n\t *\r\n\t * @return\tstring\r\n\t */\r\n\tpublic function getCurrentColumn()\r\n\t{\r\n\t\tsscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row);\r\n\t\treturn $column;\r\n\t}\r\n\r\n\t/**\r\n\t * Return the row address of the currently active cell object\r\n\t *\r\n\t * @return\tinteger\r\n\t */\r\n\tpublic function getCurrentRow()\r\n\t{\r\n\t\tsscanf($this->_currentObjectID, '%[A-Z]%d', $column, $row);\r\n\t\treturn (integer) $row;\r\n\t}\r\n\r\n\t/**\r\n\t * Get highest worksheet column\r\n\t *\r\n     * @param   string     $row        Return the highest column for the specified row,\r\n     *                                     or the highest column of any row if no row number is passed\r\n\t * @return  string     Highest column name\r\n\t */\r\n\tpublic function getHighestColumn($row = null)\r\n\t{\r\n        if ($row == null) {\r\n    \t\t$colRow = $this->getHighestRowAndColumn();\r\n\t    \treturn $colRow['column'];\r\n        }\r\n\r\n        $columnList = array(1);\r\n        foreach ($this->getCellList() as $coord) {\r\n            sscanf($coord,'%[A-Z]%d', $c, $r);\r\n            if ($r != $row) {\r\n                continue;\r\n            }\r\n            $columnList[] = PHPExcel_Cell::columnIndexFromString($c);\r\n        }\r\n        return PHPExcel_Cell::stringFromColumnIndex(max($columnList) - 1);\r\n    }\r\n\r\n\t/**\r\n\t * Get highest worksheet row\r\n\t *\r\n     * @param   string     $column     Return the highest row for the specified column,\r\n     *                                     or the highest row of any column if no column letter is passed\r\n\t * @return  int        Highest row number\r\n\t */\r\n\tpublic function getHighestRow($column = null)\r\n\t{\r\n        if ($column == null) {\r\n\t    \t$colRow = $this->getHighestRowAndColumn();\r\n    \t\treturn $colRow['row'];\r\n        }\r\n\r\n        $rowList = array(0);\r\n        foreach ($this->getCellList() as $coord) {\r\n            sscanf($coord,'%[A-Z]%d', $c, $r);\r\n            if ($c != $column) {\r\n                continue;\r\n            }\r\n            $rowList[] = $r;\r\n        }\r\n\r\n        return max($rowList);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Generate a unique ID for cache referencing\r\n\t *\r\n\t * @return string Unique Reference\r\n\t */\r\n\tprotected function _getUniqueID() {\r\n\t\tif (function_exists('posix_getpid')) {\r\n\t\t\t$baseUnique = posix_getpid();\r\n\t\t} else {\r\n\t\t\t$baseUnique = mt_rand();\r\n\t\t}\r\n\t\treturn uniqid($baseUnique,true);\r\n\t}\r\n\r\n\t/**\r\n\t * Clone the cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe new worksheet\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function copyCellCollection(PHPExcel_Worksheet $parent) {\r\n\t\t$this->_currentCellIsDirty;\r\n        $this->_storeData();\r\n\r\n\t\t$this->_parent = $parent;\r\n\t\tif (($this->_currentObject !== NULL) && (is_object($this->_currentObject))) {\r\n\t\t\t$this->_currentObject->attach($this);\r\n\t\t}\r\n\t}\t//\tfunction copyCellCollection()\r\n\r\n    /**\r\n     * Remove a row, deleting all cells in that row\r\n     *\r\n     * @param string    $row    Row number to remove\r\n     * @return void\r\n     */\r\n    public function removeRow($row) {\r\n        foreach ($this->getCellList() as $coord) {\r\n            sscanf($coord,'%[A-Z]%d', $c, $r);\r\n            if ($r == $row) {\r\n                $this->deleteCacheData($coord);\r\n            }\r\n        }\r\n    }\r\n\r\n    /**\r\n     * Remove a column, deleting all cells in that column\r\n     *\r\n     * @param string    $column    Column ID to remove\r\n     * @return void\r\n     */\r\n    public function removeColumn($column) {\r\n        foreach ($this->getCellList() as $coord) {\r\n            sscanf($coord,'%[A-Z]%d', $c, $r);\r\n            if ($c == $column) {\r\n                $this->deleteCacheData($coord);\r\n            }\r\n        }\r\n    }\r\n\r\n\t/**\r\n\t * Identify whether the caching method is currently available\r\n\t * Some methods are dependent on the availability of certain extensions being enabled in the PHP build\r\n\t *\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic static function cacheMethodIsAvailable() {\r\n\t\treturn true;\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorage/DiscISAM.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (c) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n\r\n/**\r\n * PHPExcel_CachedObjectStorage_DiscISAM\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n */\r\nclass PHPExcel_CachedObjectStorage_DiscISAM extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {\r\n\r\n\t/**\r\n\t * Name of the file for this cache\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_fileName = NULL;\r\n\r\n\t/**\r\n\t * File handle for this cache file\r\n\t *\r\n\t * @var resource\r\n\t */\r\n\tprivate $_fileHandle = NULL;\r\n\r\n\t/**\r\n\t * Directory/Folder where the cache file is located\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_cacheDirectory = NULL;\r\n\r\n\r\n    /**\r\n     * Store cell data in cache for the current cell object if it's \"dirty\",\r\n     *     and the 'nullify' the current cell object\r\n     *\r\n\t * @return\tvoid\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tprotected function _storeData() {\r\n\t\tif ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\r\n\t\t\tfseek($this->_fileHandle,0,SEEK_END);\r\n\r\n\t\t\t$this->_cellCache[$this->_currentObjectID] = array(\r\n                'ptr' => ftell($this->_fileHandle),\r\n\t\t\t\t'sz'  => fwrite($this->_fileHandle, serialize($this->_currentObject))\r\n\t\t\t);\r\n\t\t\t$this->_currentCellIsDirty = false;\r\n\t\t}\r\n\t\t$this->_currentObjectID = $this->_currentObject = null;\r\n\t}\t//\tfunction _storeData()\r\n\r\n\r\n    /**\r\n     * Add or Update a cell in cache identified by coordinate address\r\n     *\r\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to update\r\n     * @param\tPHPExcel_Cell\t$cell\t\tCell to update\r\n\t * @return\tPHPExcel_Cell\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function addCacheData($pCoord, PHPExcel_Cell $cell) {\r\n\t\tif (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = $cell;\r\n\t\t$this->_currentCellIsDirty = true;\r\n\r\n\t\treturn $cell;\r\n\t}\t//\tfunction addCacheData()\r\n\r\n\r\n    /**\r\n     * Get cell at a specific coordinate\r\n     *\r\n     * @param \tstring \t\t\t$pCoord\t\tCoordinate of the cell\r\n     * @throws \tPHPExcel_Exception\r\n     * @return \tPHPExcel_Cell \tCell that was found, or null if not found\r\n     */\r\n\tpublic function getCacheData($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\treturn $this->_currentObject;\r\n\t\t}\r\n\t\t$this->_storeData();\r\n\r\n\t\t//\tCheck if the entry that has been requested actually exists\r\n\t\tif (!isset($this->_cellCache[$pCoord])) {\r\n\t\t\t//\tReturn null if requested entry doesn't exist in cache\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t//\tSet current entry to the requested entry\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\tfseek($this->_fileHandle, $this->_cellCache[$pCoord]['ptr']);\r\n\t\t$this->_currentObject = unserialize(fread($this->_fileHandle, $this->_cellCache[$pCoord]['sz']));\r\n        //    Re-attach this as the cell's parent\r\n        $this->_currentObject->attach($this);\r\n\r\n\t\t//\tReturn requested entry\r\n\t\treturn $this->_currentObject;\r\n\t}\t//\tfunction getCacheData()\r\n\r\n\r\n\t/**\r\n\t * Get a list of all cell addresses currently held in cache\r\n\t *\r\n\t * @return  string[]\r\n\t */\r\n\tpublic function getCellList() {\r\n\t\tif ($this->_currentObjectID !== null) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\treturn parent::getCellList();\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Clone the cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe new worksheet\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function copyCellCollection(PHPExcel_Worksheet $parent) {\r\n\t\tparent::copyCellCollection($parent);\r\n\t\t//\tGet a new id for the new file name\r\n\t\t$baseUnique = $this->_getUniqueID();\r\n\t\t$newFileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache';\r\n\t\t//\tCopy the existing cell cache file\r\n\t\tcopy ($this->_fileName,$newFileName);\r\n\t\t$this->_fileName = $newFileName;\r\n\t\t//\tOpen the copied cell cache file\r\n\t\t$this->_fileHandle = fopen($this->_fileName,'a+');\r\n\t}\t//\tfunction copyCellCollection()\r\n\r\n\r\n\t/**\r\n\t * Clear the cell collection and disconnect from our parent\r\n\t *\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function unsetWorksheetCells() {\r\n\t\tif(!is_null($this->_currentObject)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\t\t\t$this->_currentObject = $this->_currentObjectID = null;\r\n\t\t}\r\n\t\t$this->_cellCache = array();\r\n\r\n\t\t//\tdetach ourself from the worksheet, so that it can then delete this object successfully\r\n\t\t$this->_parent = null;\r\n\r\n\t\t//\tClose down the temporary cache file\r\n\t\t$this->__destruct();\r\n\t}\t//\tfunction unsetWorksheetCells()\r\n\r\n\r\n\t/**\r\n\t * Initialise this new cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe worksheet for this cell collection\r\n\t * @param\tarray of mixed\t\t$arguments\tAdditional initialisation arguments\r\n\t */\r\n\tpublic function __construct(PHPExcel_Worksheet $parent, $arguments) {\r\n\t\t$this->_cacheDirectory\t= ((isset($arguments['dir'])) && ($arguments['dir'] !== NULL))\r\n\t\t\t\t\t\t\t\t\t? $arguments['dir']\r\n\t\t\t\t\t\t\t\t\t: PHPExcel_Shared_File::sys_get_temp_dir();\r\n\r\n\t\tparent::__construct($parent);\r\n\t\tif (is_null($this->_fileHandle)) {\r\n\t\t\t$baseUnique = $this->_getUniqueID();\r\n\t\t\t$this->_fileName = $this->_cacheDirectory.'/PHPExcel.'.$baseUnique.'.cache';\r\n\t\t\t$this->_fileHandle = fopen($this->_fileName,'a+');\r\n\t\t}\r\n\t}\t//\tfunction __construct()\r\n\r\n\r\n\t/**\r\n\t * Destroy this cell collection\r\n\t */\r\n\tpublic function __destruct() {\r\n\t\tif (!is_null($this->_fileHandle)) {\r\n\t\t\tfclose($this->_fileHandle);\r\n\t\t\tunlink($this->_fileName);\r\n\t\t}\r\n\t\t$this->_fileHandle = null;\r\n\t}\t//\tfunction __destruct()\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorage/ICache.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_CachedObjectStorage\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_CachedObjectStorage_ICache\n *\n * @category   PHPExcel\n * @package    PHPExcel_CachedObjectStorage\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\ninterface PHPExcel_CachedObjectStorage_ICache\n{\n    /**\n     * Add or Update a cell in cache identified by coordinate address\n     *\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to update\n     * @param\tPHPExcel_Cell\t$cell\t\tCell to update\n\t * @return\tPHPExcel_Cell\n     * @throws\tPHPExcel_Exception\n     */\n\tpublic function addCacheData($pCoord, PHPExcel_Cell $cell);\n\n    /**\n     * Add or Update a cell in cache\n     *\n     * @param\tPHPExcel_Cell\t$cell\t\tCell to update\n\t * @return\tPHPExcel_Cell\n     * @throws\tPHPExcel_Exception\n     */\n\tpublic function updateCacheData(PHPExcel_Cell $cell);\n\n    /**\n     * Fetch a cell from cache identified by coordinate address\n     *\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to retrieve\n     * @return PHPExcel_Cell \tCell that was found, or null if not found\n     * @throws\tPHPExcel_Exception\n     */\n\tpublic function getCacheData($pCoord);\n\n    /**\n     * Delete a cell in cache identified by coordinate address\n     *\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to delete\n     * @throws\tPHPExcel_Exception\n     */\n\tpublic function deleteCacheData($pCoord);\n\n\t/**\n\t * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?\n\t *\n\t * @param\tstring\t\t$pCoord\t\tCoordinate address of the cell to check\n\t * @return\tboolean\n\t */\n\tpublic function isDataSet($pCoord);\n\n\t/**\n\t * Get a list of all cell addresses currently held in cache\n\t *\n\t * @return\tstring[]\n\t */\n\tpublic function getCellList();\n\n\t/**\n\t * Get the list of all cell addresses currently held in cache sorted by column and row\n\t *\n\t * @return\tstring[]\n\t */\n\tpublic function getSortedCellList();\n\n\t/**\n\t * Clone the cell collection\n\t *\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe new worksheet\n\t * @return\tvoid\n\t */\n\tpublic function copyCellCollection(PHPExcel_Worksheet $parent);\n\n\t/**\n\t * Identify whether the caching method is currently available\n\t * Some methods are dependent on the availability of certain extensions being enabled in the PHP build\n\t *\n\t * @return\tboolean\n\t */\n\tpublic static function cacheMethodIsAvailable();\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorage/Igbinary.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (c) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n\r\n/**\r\n * PHPExcel_CachedObjectStorage_Igbinary\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n */\r\nclass PHPExcel_CachedObjectStorage_Igbinary extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {\r\n\r\n    /**\r\n     * Store cell data in cache for the current cell object if it's \"dirty\",\r\n     *     and the 'nullify' the current cell object\r\n     *\r\n\t * @return\tvoid\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tprotected function _storeData() {\r\n\t\tif ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\r\n\t\t\t$this->_cellCache[$this->_currentObjectID] = igbinary_serialize($this->_currentObject);\r\n\t\t\t$this->_currentCellIsDirty = false;\r\n\t\t}\r\n\t\t$this->_currentObjectID = $this->_currentObject = null;\r\n\t}\t//\tfunction _storeData()\r\n\r\n\r\n    /**\r\n     * Add or Update a cell in cache identified by coordinate address\r\n     *\r\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to update\r\n     * @param\tPHPExcel_Cell\t$cell\t\tCell to update\r\n\t * @return\tPHPExcel_Cell\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function addCacheData($pCoord, PHPExcel_Cell $cell) {\r\n\t\tif (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = $cell;\r\n\t\t$this->_currentCellIsDirty = true;\r\n\r\n\t\treturn $cell;\r\n\t}\t//\tfunction addCacheData()\r\n\r\n\r\n    /**\r\n     * Get cell at a specific coordinate\r\n     *\r\n     * @param \tstring \t\t\t$pCoord\t\tCoordinate of the cell\r\n     * @throws \tPHPExcel_Exception\r\n     * @return \tPHPExcel_Cell \tCell that was found, or null if not found\r\n     */\r\n\tpublic function getCacheData($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\treturn $this->_currentObject;\r\n\t\t}\r\n\t\t$this->_storeData();\r\n\r\n\t\t//\tCheck if the entry that has been requested actually exists\r\n\t\tif (!isset($this->_cellCache[$pCoord])) {\r\n\t\t\t//\tReturn null if requested entry doesn't exist in cache\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t//\tSet current entry to the requested entry\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = igbinary_unserialize($this->_cellCache[$pCoord]);\r\n        //    Re-attach this as the cell's parent\r\n        $this->_currentObject->attach($this);\r\n\r\n\t\t//\tReturn requested entry\r\n\t\treturn $this->_currentObject;\r\n\t}\t//\tfunction getCacheData()\r\n\r\n\r\n\t/**\r\n\t * Get a list of all cell addresses currently held in cache\r\n\t *\r\n\t * @return  string[]\r\n\t */\r\n\tpublic function getCellList() {\r\n\t\tif ($this->_currentObjectID !== null) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\treturn parent::getCellList();\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Clear the cell collection and disconnect from our parent\r\n\t *\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function unsetWorksheetCells() {\r\n\t\tif(!is_null($this->_currentObject)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\t\t\t$this->_currentObject = $this->_currentObjectID = null;\r\n\t\t}\r\n\t\t$this->_cellCache = array();\r\n\r\n\t\t//\tdetach ourself from the worksheet, so that it can then delete this object successfully\r\n\t\t$this->_parent = null;\r\n\t}\t//\tfunction unsetWorksheetCells()\r\n\r\n\r\n\t/**\r\n\t * Identify whether the caching method is currently available\r\n\t * Some methods are dependent on the availability of certain extensions being enabled in the PHP build\r\n\t *\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic static function cacheMethodIsAvailable() {\r\n\t\tif (!function_exists('igbinary_serialize')) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorage/Memcache.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (c) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n\r\n/**\r\n * PHPExcel_CachedObjectStorage_Memcache\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n */\r\nclass PHPExcel_CachedObjectStorage_Memcache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {\r\n\r\n\t/**\r\n\t * Prefix used to uniquely identify cache data for this worksheet\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_cachePrefix = null;\r\n\r\n\t/**\r\n\t * Cache timeout\r\n\t *\r\n\t * @var integer\r\n\t */\r\n\tprivate $_cacheTime = 600;\r\n\r\n\t/**\r\n\t * Memcache interface\r\n\t *\r\n\t * @var resource\r\n\t */\r\n\tprivate $_memcache = null;\r\n\r\n\r\n    /**\r\n     * Store cell data in cache for the current cell object if it's \"dirty\",\r\n     *     and the 'nullify' the current cell object\r\n     *\r\n\t * @return\tvoid\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tprotected function _storeData() {\r\n\t\tif ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\r\n\t\t\t$obj = serialize($this->_currentObject);\r\n\t\t\tif (!$this->_memcache->replace($this->_cachePrefix.$this->_currentObjectID.'.cache',$obj,NULL,$this->_cacheTime)) {\r\n\t\t\t\tif (!$this->_memcache->add($this->_cachePrefix.$this->_currentObjectID.'.cache',$obj,NULL,$this->_cacheTime)) {\r\n\t\t\t\t\t$this->__destruct();\r\n\t\t\t\t\tthrow new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in MemCache');\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t$this->_currentCellIsDirty = false;\r\n\t\t}\r\n\t\t$this->_currentObjectID = $this->_currentObject = null;\r\n\t}\t//\tfunction _storeData()\r\n\r\n\r\n    /**\r\n     * Add or Update a cell in cache identified by coordinate address\r\n     *\r\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to update\r\n     * @param\tPHPExcel_Cell\t$cell\t\tCell to update\r\n\t * @return\tPHPExcel_Cell\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function addCacheData($pCoord, PHPExcel_Cell $cell) {\r\n\t\tif (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\t\t$this->_cellCache[$pCoord] = true;\r\n\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = $cell;\r\n\t\t$this->_currentCellIsDirty = true;\r\n\r\n\t\treturn $cell;\r\n\t}\t//\tfunction addCacheData()\r\n\r\n\r\n\t/**\r\n\t * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?\r\n\t *\r\n\t * @param\tstring\t\t$pCoord\t\tCoordinate address of the cell to check\r\n\t * @return\tboolean\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic function isDataSet($pCoord) {\r\n\t\t//\tCheck if the requested entry is the current object, or exists in the cache\r\n\t\tif (parent::isDataSet($pCoord)) {\r\n\t\t\tif ($this->_currentObjectID == $pCoord) {\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t\t//\tCheck if the requested entry still exists in Memcache\r\n\t\t\t$success = $this->_memcache->get($this->_cachePrefix.$pCoord.'.cache');\r\n\t\t\tif ($success === false) {\r\n\t\t\t\t//\tEntry no longer exists in Memcache, so clear it from the cache array\r\n\t\t\t\tparent::deleteCacheData($pCoord);\r\n\t\t\t\tthrow new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache');\r\n\t\t\t}\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t}\t//\tfunction isDataSet()\r\n\r\n\r\n\t/**\r\n     * Get cell at a specific coordinate\r\n     *\r\n     * @param \tstring \t\t\t$pCoord\t\tCoordinate of the cell\r\n     * @throws \tPHPExcel_Exception\r\n     * @return \tPHPExcel_Cell \tCell that was found, or null if not found\r\n     */\r\n\tpublic function getCacheData($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\treturn $this->_currentObject;\r\n\t\t}\r\n\t\t$this->_storeData();\r\n\r\n\t\t//\tCheck if the entry that has been requested actually exists\r\n\t\tif (parent::isDataSet($pCoord)) {\r\n\t\t\t$obj = $this->_memcache->get($this->_cachePrefix.$pCoord.'.cache');\r\n\t\t\tif ($obj === false) {\r\n\t\t\t\t//\tEntry no longer exists in Memcache, so clear it from the cache array\r\n\t\t\t\tparent::deleteCacheData($pCoord);\r\n\t\t\t\tthrow new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in MemCache');\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t//\tReturn null if requested entry doesn't exist in cache\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t//\tSet current entry to the requested entry\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = unserialize($obj);\r\n        //    Re-attach this as the cell's parent\r\n        $this->_currentObject->attach($this);\r\n\r\n\t\t//\tReturn requested entry\r\n\t\treturn $this->_currentObject;\r\n\t}\t//\tfunction getCacheData()\r\n\r\n\r\n\t/**\r\n\t * Get a list of all cell addresses currently held in cache\r\n\t *\r\n\t * @return  string[]\r\n\t */\r\n\tpublic function getCellList() {\r\n\t\tif ($this->_currentObjectID !== null) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\treturn parent::getCellList();\r\n\t}\r\n\r\n\r\n    /**\r\n     * Delete a cell in cache identified by coordinate address\r\n     *\r\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to delete\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function deleteCacheData($pCoord) {\r\n\t\t//\tDelete the entry from Memcache\r\n\t\t$this->_memcache->delete($this->_cachePrefix.$pCoord.'.cache');\r\n\r\n\t\t//\tDelete the entry from our cell address array\r\n\t\tparent::deleteCacheData($pCoord);\r\n\t}\t//\tfunction deleteCacheData()\r\n\r\n\r\n\t/**\r\n\t * Clone the cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe new worksheet\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function copyCellCollection(PHPExcel_Worksheet $parent) {\r\n\t\tparent::copyCellCollection($parent);\r\n\t\t//\tGet a new id for the new file name\r\n\t\t$baseUnique = $this->_getUniqueID();\r\n\t\t$newCachePrefix = substr(md5($baseUnique),0,8).'.';\r\n\t\t$cacheList = $this->getCellList();\r\n\t\tforeach($cacheList as $cellID) {\r\n\t\t\tif ($cellID != $this->_currentObjectID) {\r\n\t\t\t\t$obj = $this->_memcache->get($this->_cachePrefix.$cellID.'.cache');\r\n\t\t\t\tif ($obj === false) {\r\n\t\t\t\t\t//\tEntry no longer exists in Memcache, so clear it from the cache array\r\n\t\t\t\t\tparent::deleteCacheData($cellID);\r\n\t\t\t\t\tthrow new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in MemCache');\r\n\t\t\t\t}\r\n\t\t\t\tif (!$this->_memcache->add($newCachePrefix.$cellID.'.cache',$obj,NULL,$this->_cacheTime)) {\r\n\t\t\t\t\t$this->__destruct();\r\n\t\t\t\t\tthrow new PHPExcel_Exception('Failed to store cell '.$cellID.' in MemCache');\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t$this->_cachePrefix = $newCachePrefix;\r\n\t}\t//\tfunction copyCellCollection()\r\n\r\n\r\n\t/**\r\n\t * Clear the cell collection and disconnect from our parent\r\n\t *\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function unsetWorksheetCells() {\r\n\t\tif(!is_null($this->_currentObject)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\t\t\t$this->_currentObject = $this->_currentObjectID = null;\r\n\t\t}\r\n\r\n\t\t//\tFlush the Memcache cache\r\n\t\t$this->__destruct();\r\n\r\n\t\t$this->_cellCache = array();\r\n\r\n\t\t//\tdetach ourself from the worksheet, so that it can then delete this object successfully\r\n\t\t$this->_parent = null;\r\n\t}\t//\tfunction unsetWorksheetCells()\r\n\r\n\r\n\t/**\r\n\t * Initialise this new cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe worksheet for this cell collection\r\n\t * @param\tarray of mixed\t\t$arguments\tAdditional initialisation arguments\r\n\t */\r\n\tpublic function __construct(PHPExcel_Worksheet $parent, $arguments) {\r\n\t\t$memcacheServer\t= (isset($arguments['memcacheServer']))\t? $arguments['memcacheServer']\t: 'localhost';\r\n\t\t$memcachePort\t= (isset($arguments['memcachePort']))\t? $arguments['memcachePort']\t: 11211;\r\n\t\t$cacheTime\t\t= (isset($arguments['cacheTime']))\t\t? $arguments['cacheTime']\t\t: 600;\r\n\r\n\t\tif (is_null($this->_cachePrefix)) {\r\n\t\t\t$baseUnique = $this->_getUniqueID();\r\n\t\t\t$this->_cachePrefix = substr(md5($baseUnique),0,8).'.';\r\n\r\n\t\t\t//\tSet a new Memcache object and connect to the Memcache server\r\n\t\t\t$this->_memcache = new Memcache();\r\n\t\t\tif (!$this->_memcache->addServer($memcacheServer, $memcachePort, false, 50, 5, 5, true, array($this, 'failureCallback'))) {\r\n\t\t\t\tthrow new PHPExcel_Exception('Could not connect to MemCache server at '.$memcacheServer.':'.$memcachePort);\r\n\t\t\t}\r\n\t\t\t$this->_cacheTime = $cacheTime;\r\n\r\n\t\t\tparent::__construct($parent);\r\n\t\t}\r\n\t}\t//\tfunction __construct()\r\n\r\n\r\n\t/**\r\n\t * Memcache error handler\r\n\t *\r\n\t * @param\tstring\t$host\t\tMemcache server\r\n\t * @param\tinteger\t$port\t\tMemcache port\r\n     * @throws\tPHPExcel_Exception\r\n\t */\r\n\tpublic function failureCallback($host, $port) {\r\n\t\tthrow new PHPExcel_Exception('memcache '.$host.':'.$port.' failed');\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Destroy this cell collection\r\n\t */\r\n\tpublic function __destruct() {\r\n\t\t$cacheList = $this->getCellList();\r\n\t\tforeach($cacheList as $cellID) {\r\n\t\t\t$this->_memcache->delete($this->_cachePrefix.$cellID.'.cache');\r\n\t\t}\r\n\t}\t//\tfunction __destruct()\r\n\r\n\t/**\r\n\t * Identify whether the caching method is currently available\r\n\t * Some methods are dependent on the availability of certain extensions being enabled in the PHP build\r\n\t *\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic static function cacheMethodIsAvailable() {\r\n\t\tif (!function_exists('memcache_add')) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorage/Memory.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (c) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n\r\n/**\r\n * PHPExcel_CachedObjectStorage_Memory\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n */\r\nclass PHPExcel_CachedObjectStorage_Memory extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {\r\n\r\n    /**\r\n     * Dummy method callable from CacheBase, but unused by Memory cache\r\n     *\r\n\t * @return\tvoid\r\n     */\r\n\tprotected function _storeData() {\r\n\t}\t//\tfunction _storeData()\r\n\r\n    /**\r\n     * Add or Update a cell in cache identified by coordinate address\r\n     *\r\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to update\r\n     * @param\tPHPExcel_Cell\t$cell\t\tCell to update\r\n\t * @return\tPHPExcel_Cell\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function addCacheData($pCoord, PHPExcel_Cell $cell) {\r\n\t\t$this->_cellCache[$pCoord] = $cell;\r\n\r\n\t\t//\tSet current entry to the new/updated entry\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\r\n\t\treturn $cell;\r\n\t}\t//\tfunction addCacheData()\r\n\r\n\r\n    /**\r\n     * Get cell at a specific coordinate\r\n     *\r\n     * @param \tstring \t\t\t$pCoord\t\tCoordinate of the cell\r\n     * @throws \tPHPExcel_Exception\r\n     * @return \tPHPExcel_Cell \tCell that was found, or null if not found\r\n     */\r\n\tpublic function getCacheData($pCoord) {\r\n\t\t//\tCheck if the entry that has been requested actually exists\r\n\t\tif (!isset($this->_cellCache[$pCoord])) {\r\n\t\t\t$this->_currentObjectID = NULL;\r\n\t\t\t//\tReturn null if requested entry doesn't exist in cache\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t//\tSet current entry to the requested entry\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\r\n\t\t//\tReturn requested entry\r\n\t\treturn $this->_cellCache[$pCoord];\r\n\t}\t//\tfunction getCacheData()\r\n\r\n\r\n\t/**\r\n\t * Clone the cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe new worksheet\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function copyCellCollection(PHPExcel_Worksheet $parent) {\r\n\t\tparent::copyCellCollection($parent);\r\n\r\n\t\t$newCollection = array();\r\n\t\tforeach($this->_cellCache as $k => &$cell) {\r\n\t\t\t$newCollection[$k] = clone $cell;\r\n\t\t\t$newCollection[$k]->attach($this);\r\n\t\t}\r\n\r\n\t\t$this->_cellCache = $newCollection;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Clear the cell collection and disconnect from our parent\r\n\t *\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function unsetWorksheetCells() {\r\n\t\t//\tBecause cells are all stored as intact objects in memory, we need to detach each one from the parent\r\n\t\tforeach($this->_cellCache as $k => &$cell) {\r\n\t\t\t$cell->detach();\r\n\t\t\t$this->_cellCache[$k] = null;\r\n\t\t}\r\n\t\tunset($cell);\r\n\r\n\t\t$this->_cellCache = array();\r\n\r\n\t\t//\tdetach ourself from the worksheet, so that it can then delete this object successfully\r\n\t\t$this->_parent = null;\r\n\t}\t//\tfunction unsetWorksheetCells()\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorage/MemoryGZip.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (c) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n\r\n/**\r\n * PHPExcel_CachedObjectStorage_MemoryGZip\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n */\r\nclass PHPExcel_CachedObjectStorage_MemoryGZip extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {\r\n\r\n    /**\r\n     * Store cell data in cache for the current cell object if it's \"dirty\",\r\n     *     and the 'nullify' the current cell object\r\n     *\r\n\t * @return\tvoid\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tprotected function _storeData() {\r\n\t\tif ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\r\n\t\t\t$this->_cellCache[$this->_currentObjectID] = gzdeflate(serialize($this->_currentObject));\r\n\t\t\t$this->_currentCellIsDirty = false;\r\n\t\t}\r\n\t\t$this->_currentObjectID = $this->_currentObject = null;\r\n\t}\t//\tfunction _storeData()\r\n\r\n\r\n    /**\r\n     * Add or Update a cell in cache identified by coordinate address\r\n     *\r\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to update\r\n     * @param\tPHPExcel_Cell\t$cell\t\tCell to update\r\n\t * @return\tPHPExcel_Cell\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function addCacheData($pCoord, PHPExcel_Cell $cell) {\r\n\t\tif (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = $cell;\r\n\t\t$this->_currentCellIsDirty = true;\r\n\r\n\t\treturn $cell;\r\n\t}\t//\tfunction addCacheData()\r\n\r\n\r\n    /**\r\n     * Get cell at a specific coordinate\r\n     *\r\n     * @param \tstring \t\t\t$pCoord\t\tCoordinate of the cell\r\n     * @throws \tPHPExcel_Exception\r\n     * @return \tPHPExcel_Cell \tCell that was found, or null if not found\r\n     */\r\n\tpublic function getCacheData($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\treturn $this->_currentObject;\r\n\t\t}\r\n\t\t$this->_storeData();\r\n\r\n\t\t//\tCheck if the entry that has been requested actually exists\r\n\t\tif (!isset($this->_cellCache[$pCoord])) {\r\n\t\t\t//\tReturn null if requested entry doesn't exist in cache\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t//\tSet current entry to the requested entry\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = unserialize(gzinflate($this->_cellCache[$pCoord]));\r\n        //    Re-attach this as the cell's parent\r\n        $this->_currentObject->attach($this);\r\n\r\n\t\t//\tReturn requested entry\r\n\t\treturn $this->_currentObject;\r\n\t}\t//\tfunction getCacheData()\r\n\r\n\r\n\t/**\r\n\t * Get a list of all cell addresses currently held in cache\r\n\t *\r\n\t * @return  string[]\r\n\t */\r\n\tpublic function getCellList() {\r\n\t\tif ($this->_currentObjectID !== null) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\treturn parent::getCellList();\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Clear the cell collection and disconnect from our parent\r\n\t *\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function unsetWorksheetCells() {\r\n\t\tif(!is_null($this->_currentObject)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\t\t\t$this->_currentObject = $this->_currentObjectID = null;\r\n\t\t}\r\n\t\t$this->_cellCache = array();\r\n\r\n\t\t//\tdetach ourself from the worksheet, so that it can then delete this object successfully\r\n\t\t$this->_parent = null;\r\n\t}\t//\tfunction unsetWorksheetCells()\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorage/MemorySerialized.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (c) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n\r\n/**\r\n * PHPExcel_CachedObjectStorage_MemorySerialized\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n */\r\nclass PHPExcel_CachedObjectStorage_MemorySerialized extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {\r\n\r\n    /**\r\n     * Store cell data in cache for the current cell object if it's \"dirty\",\r\n     *     and the 'nullify' the current cell object\r\n     *\r\n\t * @return\tvoid\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tprotected function _storeData() {\r\n\t\tif ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\r\n\t\t\t$this->_cellCache[$this->_currentObjectID] = serialize($this->_currentObject);\r\n\t\t\t$this->_currentCellIsDirty = false;\r\n\t\t}\r\n\t\t$this->_currentObjectID = $this->_currentObject = null;\r\n\t}\t//\tfunction _storeData()\r\n\r\n\r\n    /**\r\n     * Add or Update a cell in cache identified by coordinate address\r\n     *\r\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to update\r\n     * @param\tPHPExcel_Cell\t$cell\t\tCell to update\r\n\t * @return\tPHPExcel_Cell\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function addCacheData($pCoord, PHPExcel_Cell $cell) {\r\n\t\tif (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = $cell;\r\n\t\t$this->_currentCellIsDirty = true;\r\n\r\n\t\treturn $cell;\r\n\t}\t//\tfunction addCacheData()\r\n\r\n\r\n    /**\r\n     * Get cell at a specific coordinate\r\n     *\r\n     * @param \tstring \t\t\t$pCoord\t\tCoordinate of the cell\r\n     * @throws \tPHPExcel_Exception\r\n     * @return \tPHPExcel_Cell \tCell that was found, or null if not found\r\n     */\r\n\tpublic function getCacheData($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\treturn $this->_currentObject;\r\n\t\t}\r\n\t\t$this->_storeData();\r\n\r\n\t\t//\tCheck if the entry that has been requested actually exists\r\n\t\tif (!isset($this->_cellCache[$pCoord])) {\r\n\t\t\t//\tReturn null if requested entry doesn't exist in cache\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t//\tSet current entry to the requested entry\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = unserialize($this->_cellCache[$pCoord]);\r\n        //    Re-attach this as the cell's parent\r\n        $this->_currentObject->attach($this);\r\n\r\n\t\t//\tReturn requested entry\r\n\t\treturn $this->_currentObject;\r\n\t}\t//\tfunction getCacheData()\r\n\r\n\r\n\t/**\r\n\t * Get a list of all cell addresses currently held in cache\r\n\t *\r\n\t * @return  string[]\r\n\t */\r\n\tpublic function getCellList() {\r\n\t\tif ($this->_currentObjectID !== null) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\treturn parent::getCellList();\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Clear the cell collection and disconnect from our parent\r\n\t *\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function unsetWorksheetCells() {\r\n\t\tif(!is_null($this->_currentObject)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\t\t\t$this->_currentObject = $this->_currentObjectID = null;\r\n\t\t}\r\n\t\t$this->_cellCache = array();\r\n\r\n\t\t//\tdetach ourself from the worksheet, so that it can then delete this object successfully\r\n\t\t$this->_parent = null;\r\n\t}\t//\tfunction unsetWorksheetCells()\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorage/PHPTemp.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (c) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n\r\n/**\r\n * PHPExcel_CachedObjectStorage_PHPTemp\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n */\r\nclass PHPExcel_CachedObjectStorage_PHPTemp extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {\r\n\r\n\t/**\r\n\t * Name of the file for this cache\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_fileHandle = null;\r\n\r\n\t/**\r\n\t * Memory limit to use before reverting to file cache\r\n\t *\r\n\t * @var integer\r\n\t */\r\n\tprivate $_memoryCacheSize = null;\r\n\r\n    /**\r\n     * Store cell data in cache for the current cell object if it's \"dirty\",\r\n     *     and the 'nullify' the current cell object\r\n     *\r\n\t * @return\tvoid\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tprotected function _storeData() {\r\n\t\tif ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\r\n\t\t\tfseek($this->_fileHandle,0,SEEK_END);\r\n\r\n\t\t\t$this->_cellCache[$this->_currentObjectID] = array(\r\n                'ptr' => ftell($this->_fileHandle),\r\n\t\t\t\t'sz'  => fwrite($this->_fileHandle, serialize($this->_currentObject))\r\n\t\t\t);\r\n\t\t\t$this->_currentCellIsDirty = false;\r\n\t\t}\r\n\t\t$this->_currentObjectID = $this->_currentObject = null;\r\n\t}\t//\tfunction _storeData()\r\n\r\n\r\n    /**\r\n     * Add or Update a cell in cache identified by coordinate address\r\n     *\r\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to update\r\n     * @param\tPHPExcel_Cell\t$cell\t\tCell to update\r\n\t * @return\tPHPExcel_Cell\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function addCacheData($pCoord, PHPExcel_Cell $cell) {\r\n\t\tif (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = $cell;\r\n\t\t$this->_currentCellIsDirty = true;\r\n\r\n\t\treturn $cell;\r\n\t}\t//\tfunction addCacheData()\r\n\r\n\r\n    /**\r\n     * Get cell at a specific coordinate\r\n     *\r\n     * @param \tstring \t\t\t$pCoord\t\tCoordinate of the cell\r\n     * @throws \tPHPExcel_Exception\r\n     * @return \tPHPExcel_Cell \tCell that was found, or null if not found\r\n     */\r\n\tpublic function getCacheData($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\treturn $this->_currentObject;\r\n\t\t}\r\n\t\t$this->_storeData();\r\n\r\n\t\t//\tCheck if the entry that has been requested actually exists\r\n\t\tif (!isset($this->_cellCache[$pCoord])) {\r\n\t\t\t//\tReturn null if requested entry doesn't exist in cache\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t//\tSet current entry to the requested entry\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\tfseek($this->_fileHandle,$this->_cellCache[$pCoord]['ptr']);\r\n\t\t$this->_currentObject = unserialize(fread($this->_fileHandle,$this->_cellCache[$pCoord]['sz']));\r\n        //    Re-attach this as the cell's parent\r\n        $this->_currentObject->attach($this);\r\n\r\n\t\t//\tReturn requested entry\r\n\t\treturn $this->_currentObject;\r\n\t}\t//\tfunction getCacheData()\r\n\r\n\r\n\t/**\r\n\t * Get a list of all cell addresses currently held in cache\r\n\t *\r\n\t * @return  string[]\r\n\t */\r\n\tpublic function getCellList() {\r\n\t\tif ($this->_currentObjectID !== null) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\treturn parent::getCellList();\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Clone the cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe new worksheet\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function copyCellCollection(PHPExcel_Worksheet $parent) {\r\n\t\tparent::copyCellCollection($parent);\r\n\t\t//\tOpen a new stream for the cell cache data\r\n\t\t$newFileHandle = fopen('php://temp/maxmemory:'.$this->_memoryCacheSize,'a+');\r\n\t\t//\tCopy the existing cell cache data to the new stream\r\n\t\tfseek($this->_fileHandle,0);\r\n\t\twhile (!feof($this->_fileHandle)) {\r\n\t\t\tfwrite($newFileHandle,fread($this->_fileHandle, 1024));\r\n\t\t}\r\n\t\t$this->_fileHandle = $newFileHandle;\r\n\t}\t//\tfunction copyCellCollection()\r\n\r\n\r\n\t/**\r\n\t * Clear the cell collection and disconnect from our parent\r\n\t *\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function unsetWorksheetCells() {\r\n\t\tif(!is_null($this->_currentObject)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\t\t\t$this->_currentObject = $this->_currentObjectID = null;\r\n\t\t}\r\n\t\t$this->_cellCache = array();\r\n\r\n\t\t//\tdetach ourself from the worksheet, so that it can then delete this object successfully\r\n\t\t$this->_parent = null;\r\n\r\n\t\t//\tClose down the php://temp file\r\n\t\t$this->__destruct();\r\n\t}\t//\tfunction unsetWorksheetCells()\r\n\r\n\r\n\t/**\r\n\t * Initialise this new cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe worksheet for this cell collection\r\n\t * @param\tarray of mixed\t\t$arguments\tAdditional initialisation arguments\r\n\t */\r\n\tpublic function __construct(PHPExcel_Worksheet $parent, $arguments) {\r\n\t\t$this->_memoryCacheSize\t= (isset($arguments['memoryCacheSize']))\t? $arguments['memoryCacheSize']\t: '1MB';\r\n\r\n\t\tparent::__construct($parent);\r\n\t\tif (is_null($this->_fileHandle)) {\r\n\t\t\t$this->_fileHandle = fopen('php://temp/maxmemory:'.$this->_memoryCacheSize,'a+');\r\n\t\t}\r\n\t}\t//\tfunction __construct()\r\n\r\n\r\n\t/**\r\n\t * Destroy this cell collection\r\n\t */\r\n\tpublic function __destruct() {\r\n\t\tif (!is_null($this->_fileHandle)) {\r\n\t\t\tfclose($this->_fileHandle);\r\n\t\t}\r\n\t\t$this->_fileHandle = null;\r\n\t}\t//\tfunction __destruct()\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorage/SQLite.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (c) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n\r\n/**\r\n * PHPExcel_CachedObjectStorage_SQLite\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n */\r\nclass PHPExcel_CachedObjectStorage_SQLite extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {\r\n\r\n\t/**\r\n\t * Database table name\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_TableName = null;\r\n\r\n\t/**\r\n\t * Database handle\r\n\t *\r\n\t * @var resource\r\n\t */\r\n\tprivate $_DBHandle = null;\r\n\r\n    /**\r\n     * Store cell data in cache for the current cell object if it's \"dirty\",\r\n     *     and the 'nullify' the current cell object\r\n     *\r\n\t * @return\tvoid\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tprotected function _storeData() {\r\n\t\tif ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\r\n\t\t\tif (!$this->_DBHandle->queryExec(\"INSERT OR REPLACE INTO kvp_\".$this->_TableName.\" VALUES('\".$this->_currentObjectID.\"','\".sqlite_escape_string(serialize($this->_currentObject)).\"')\"))\r\n\t\t\t\tthrow new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));\r\n\t\t\t$this->_currentCellIsDirty = false;\r\n\t\t}\r\n\t\t$this->_currentObjectID = $this->_currentObject = null;\r\n\t}\t//\tfunction _storeData()\r\n\r\n\r\n    /**\r\n     * Add or Update a cell in cache identified by coordinate address\r\n     *\r\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to update\r\n     * @param\tPHPExcel_Cell\t$cell\t\tCell to update\r\n\t * @return\tPHPExcel_Cell\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function addCacheData($pCoord, PHPExcel_Cell $cell) {\r\n\t\tif (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = $cell;\r\n\t\t$this->_currentCellIsDirty = true;\r\n\r\n\t\treturn $cell;\r\n\t}\t//\tfunction addCacheData()\r\n\r\n\r\n    /**\r\n     * Get cell at a specific coordinate\r\n     *\r\n     * @param \tstring \t\t\t$pCoord\t\tCoordinate of the cell\r\n     * @throws \tPHPExcel_Exception\r\n     * @return \tPHPExcel_Cell \tCell that was found, or null if not found\r\n     */\r\n\tpublic function getCacheData($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\treturn $this->_currentObject;\r\n\t\t}\r\n\t\t$this->_storeData();\r\n\r\n\t\t$query = \"SELECT value FROM kvp_\".$this->_TableName.\" WHERE id='\".$pCoord.\"'\";\r\n\t\t$cellResultSet = $this->_DBHandle->query($query,SQLITE_ASSOC);\r\n\t\tif ($cellResultSet === false) {\r\n\t\t\tthrow new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));\r\n\t\t} elseif ($cellResultSet->numRows() == 0) {\r\n\t\t\t//\tReturn null if requested entry doesn't exist in cache\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t//\tSet current entry to the requested entry\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\r\n\t\t$cellResult = $cellResultSet->fetchSingle();\r\n\t\t$this->_currentObject = unserialize($cellResult);\r\n        //    Re-attach this as the cell's parent\r\n        $this->_currentObject->attach($this);\r\n\r\n\t\t//\tReturn requested entry\r\n\t\treturn $this->_currentObject;\r\n\t}\t//\tfunction getCacheData()\r\n\r\n\r\n\t/**\r\n\t * Is a value set for an indexed cell?\r\n\t *\r\n\t * @param\tstring\t\t$pCoord\t\tCoordinate address of the cell to check\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic function isDataSet($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\treturn true;\r\n\t\t}\r\n\r\n\t\t//\tCheck if the requested entry exists in the cache\r\n\t\t$query = \"SELECT id FROM kvp_\".$this->_TableName.\" WHERE id='\".$pCoord.\"'\";\r\n\t\t$cellResultSet = $this->_DBHandle->query($query,SQLITE_ASSOC);\r\n\t\tif ($cellResultSet === false) {\r\n\t\t\tthrow new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));\r\n\t\t} elseif ($cellResultSet->numRows() == 0) {\r\n\t\t\t//\tReturn null if requested entry doesn't exist in cache\r\n\t\t\treturn false;\r\n\t\t}\r\n\t\treturn true;\r\n\t}\t//\tfunction isDataSet()\r\n\r\n\r\n    /**\r\n     * Delete a cell in cache identified by coordinate address\r\n     *\r\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to delete\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function deleteCacheData($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\t$this->_currentObject->detach();\r\n\t\t\t$this->_currentObjectID = $this->_currentObject = null;\r\n\t\t}\r\n\r\n\t\t//\tCheck if the requested entry exists in the cache\r\n\t\t$query = \"DELETE FROM kvp_\".$this->_TableName.\" WHERE id='\".$pCoord.\"'\";\r\n\t\tif (!$this->_DBHandle->queryExec($query))\r\n\t\t\tthrow new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));\r\n\r\n\t\t$this->_currentCellIsDirty = false;\r\n\t}\t//\tfunction deleteCacheData()\r\n\r\n\r\n\t/**\r\n\t * Move a cell object from one address to another\r\n\t *\r\n\t * @param\tstring\t\t$fromAddress\tCurrent address of the cell to move\r\n\t * @param\tstring\t\t$toAddress\t\tDestination address of the cell to move\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic function moveCell($fromAddress, $toAddress) {\r\n\t\tif ($fromAddress === $this->_currentObjectID) {\r\n\t\t\t$this->_currentObjectID = $toAddress;\r\n\t\t}\r\n\r\n\t\t$query = \"DELETE FROM kvp_\".$this->_TableName.\" WHERE id='\".$toAddress.\"'\";\r\n\t\t$result = $this->_DBHandle->exec($query);\r\n\t\tif ($result === false)\r\n\t\t\tthrow new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());\r\n\r\n\t\t$query = \"UPDATE kvp_\".$this->_TableName.\" SET id='\".$toAddress.\"' WHERE id='\".$fromAddress.\"'\";\r\n\t\t$result = $this->_DBHandle->exec($query);\r\n\t\tif ($result === false)\r\n\t\t\tthrow new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());\r\n\r\n\t\treturn TRUE;\r\n\t}\t//\tfunction moveCell()\r\n\r\n\r\n\t/**\r\n\t * Get a list of all cell addresses currently held in cache\r\n\t *\r\n\t * @return\tstring[]\r\n\t */\r\n\tpublic function getCellList() {\r\n\t\tif ($this->_currentObjectID !== null) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\t$query = \"SELECT id FROM kvp_\".$this->_TableName;\r\n\t\t$cellIdsResult = $this->_DBHandle->unbufferedQuery($query,SQLITE_ASSOC);\r\n\t\tif ($cellIdsResult === false)\r\n\t\t\tthrow new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));\r\n\r\n\t\t$cellKeys = array();\r\n\t\tforeach($cellIdsResult as $row) {\r\n\t\t\t$cellKeys[] = $row['id'];\r\n\t\t}\r\n\r\n\t\treturn $cellKeys;\r\n\t}\t//\tfunction getCellList()\r\n\r\n\r\n\t/**\r\n\t * Clone the cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe new worksheet\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function copyCellCollection(PHPExcel_Worksheet $parent) {\r\n\t\t$this->_currentCellIsDirty;\r\n        $this->_storeData();\r\n\r\n\t\t//\tGet a new id for the new table name\r\n\t\t$tableName = str_replace('.','_',$this->_getUniqueID());\r\n\t\tif (!$this->_DBHandle->queryExec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)\r\n\t\t\t\t\t\t\t\t\t\t\t\t\tAS SELECT * FROM kvp_'.$this->_TableName))\r\n\t\t\tthrow new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));\r\n\r\n\t\t//\tCopy the existing cell cache file\r\n\t\t$this->_TableName = $tableName;\r\n\t}\t//\tfunction copyCellCollection()\r\n\r\n\r\n\t/**\r\n\t * Clear the cell collection and disconnect from our parent\r\n\t *\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function unsetWorksheetCells() {\r\n\t\tif(!is_null($this->_currentObject)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\t\t\t$this->_currentObject = $this->_currentObjectID = null;\r\n\t\t}\r\n\t\t//\tdetach ourself from the worksheet, so that it can then delete this object successfully\r\n\t\t$this->_parent = null;\r\n\r\n\t\t//\tClose down the temporary cache file\r\n\t\t$this->__destruct();\r\n\t}\t//\tfunction unsetWorksheetCells()\r\n\r\n\r\n\t/**\r\n\t * Initialise this new cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe worksheet for this cell collection\r\n\t */\r\n\tpublic function __construct(PHPExcel_Worksheet $parent) {\r\n\t\tparent::__construct($parent);\r\n\t\tif (is_null($this->_DBHandle)) {\r\n\t\t\t$this->_TableName = str_replace('.','_',$this->_getUniqueID());\r\n\t\t\t$_DBName = ':memory:';\r\n\r\n\t\t\t$this->_DBHandle = new SQLiteDatabase($_DBName);\r\n\t\t\tif ($this->_DBHandle === false)\r\n\t\t\t\tthrow new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));\r\n\t\t\tif (!$this->_DBHandle->queryExec('CREATE TABLE kvp_'.$this->_TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)'))\r\n\t\t\t\tthrow new PHPExcel_Exception(sqlite_error_string($this->_DBHandle->lastError()));\r\n\t\t}\r\n\t}\t//\tfunction __construct()\r\n\r\n\r\n\t/**\r\n\t * Destroy this cell collection\r\n\t */\r\n\tpublic function __destruct() {\r\n\t\tif (!is_null($this->_DBHandle)) {\r\n\t\t\t$this->_DBHandle->queryExec('DROP TABLE kvp_'.$this->_TableName);\r\n\t\t}\r\n\t\t$this->_DBHandle = null;\r\n\t}\t//\tfunction __destruct()\r\n\r\n\r\n\t/**\r\n\t * Identify whether the caching method is currently available\r\n\t * Some methods are dependent on the availability of certain extensions being enabled in the PHP build\r\n\t *\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic static function cacheMethodIsAvailable() {\r\n\t\tif (!function_exists('sqlite_open')) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorage/SQLite3.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (c) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n\r\n/**\r\n * PHPExcel_CachedObjectStorage_SQLite3\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n */\r\nclass PHPExcel_CachedObjectStorage_SQLite3 extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {\r\n\r\n\t/**\r\n\t * Database table name\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_TableName = null;\r\n\r\n\t/**\r\n\t * Database handle\r\n\t *\r\n\t * @var resource\r\n\t */\r\n\tprivate $_DBHandle = null;\r\n\r\n\t/**\r\n\t * Prepared statement for a SQLite3 select query\r\n\t *\r\n\t * @var SQLite3Stmt\r\n\t */\r\n\tprivate $_selectQuery;\r\n\r\n\t/**\r\n\t * Prepared statement for a SQLite3 insert query\r\n\t *\r\n\t * @var SQLite3Stmt\r\n\t */\r\n\tprivate $_insertQuery;\r\n\r\n\t/**\r\n\t * Prepared statement for a SQLite3 update query\r\n\t *\r\n\t * @var SQLite3Stmt\r\n\t */\r\n\tprivate $_updateQuery;\r\n\r\n\t/**\r\n\t * Prepared statement for a SQLite3 delete query\r\n\t *\r\n\t * @var SQLite3Stmt\r\n\t */\r\n\tprivate $_deleteQuery;\r\n\r\n    /**\r\n     * Store cell data in cache for the current cell object if it's \"dirty\",\r\n     *     and the 'nullify' the current cell object\r\n     *\r\n\t * @return\tvoid\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tprotected function _storeData() {\r\n\t\tif ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\r\n\t\t\t$this->_insertQuery->bindValue('id',$this->_currentObjectID,SQLITE3_TEXT);\r\n\t\t\t$this->_insertQuery->bindValue('data',serialize($this->_currentObject),SQLITE3_BLOB);\r\n\t\t\t$result = $this->_insertQuery->execute();\r\n\t\t\tif ($result === false)\r\n\t\t\t\tthrow new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());\r\n\t\t\t$this->_currentCellIsDirty = false;\r\n\t\t}\r\n\t\t$this->_currentObjectID = $this->_currentObject = null;\r\n\t}\t//\tfunction _storeData()\r\n\r\n\r\n    /**\r\n     * Add or Update a cell in cache identified by coordinate address\r\n     *\r\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to update\r\n     * @param\tPHPExcel_Cell\t$cell\t\tCell to update\r\n\t * @return\tPHPExcel_Cell\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function addCacheData($pCoord, PHPExcel_Cell $cell) {\r\n\t\tif (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = $cell;\r\n\t\t$this->_currentCellIsDirty = true;\r\n\r\n\t\treturn $cell;\r\n\t}\t//\tfunction addCacheData()\r\n\r\n\r\n    /**\r\n     * Get cell at a specific coordinate\r\n     *\r\n     * @param \tstring \t\t\t$pCoord\t\tCoordinate of the cell\r\n     * @throws \tPHPExcel_Exception\r\n     * @return \tPHPExcel_Cell \tCell that was found, or null if not found\r\n     */\r\n\tpublic function getCacheData($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\treturn $this->_currentObject;\r\n\t\t}\r\n\t\t$this->_storeData();\r\n\r\n\t\t$this->_selectQuery->bindValue('id',$pCoord,SQLITE3_TEXT);\r\n\t\t$cellResult = $this->_selectQuery->execute();\r\n\t\tif ($cellResult === FALSE) {\r\n\t\t\tthrow new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());\r\n\t\t}\r\n\t\t$cellData = $cellResult->fetchArray(SQLITE3_ASSOC);\r\n\t\tif ($cellData === FALSE) {\r\n\t\t\t//\tReturn null if requested entry doesn't exist in cache\r\n\t\t\treturn NULL;\r\n\t\t}\r\n\r\n\t\t//\tSet current entry to the requested entry\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\r\n\t\t$this->_currentObject = unserialize($cellData['value']);\r\n        //    Re-attach this as the cell's parent\r\n        $this->_currentObject->attach($this);\r\n\r\n\t\t//\tReturn requested entry\r\n\t\treturn $this->_currentObject;\r\n\t}\t//\tfunction getCacheData()\r\n\r\n\r\n\t/**\r\n\t *\tIs a value set for an indexed cell?\r\n\t *\r\n\t * @param\tstring\t\t$pCoord\t\tCoordinate address of the cell to check\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic function isDataSet($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\treturn TRUE;\r\n\t\t}\r\n\r\n\t\t//\tCheck if the requested entry exists in the cache\r\n\t\t$this->_selectQuery->bindValue('id',$pCoord,SQLITE3_TEXT);\r\n\t\t$cellResult = $this->_selectQuery->execute();\r\n\t\tif ($cellResult === FALSE) {\r\n\t\t\tthrow new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());\r\n\t\t}\r\n\t\t$cellData = $cellResult->fetchArray(SQLITE3_ASSOC);\r\n\r\n\t\treturn ($cellData === FALSE) ? FALSE : TRUE;\r\n\t}\t//\tfunction isDataSet()\r\n\r\n\r\n    /**\r\n     *\tDelete a cell in cache identified by coordinate address\r\n     *\r\n     * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to delete\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tpublic function deleteCacheData($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\t$this->_currentObject->detach();\r\n\t\t\t$this->_currentObjectID = $this->_currentObject = NULL;\r\n\t\t}\r\n\r\n\t\t//\tCheck if the requested entry exists in the cache\r\n\t\t$this->_deleteQuery->bindValue('id',$pCoord,SQLITE3_TEXT);\r\n\t\t$result = $this->_deleteQuery->execute();\r\n\t\tif ($result === FALSE)\r\n\t\t\tthrow new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());\r\n\r\n\t\t$this->_currentCellIsDirty = FALSE;\r\n\t}\t//\tfunction deleteCacheData()\r\n\r\n\r\n\t/**\r\n\t * Move a cell object from one address to another\r\n\t *\r\n\t * @param\tstring\t\t$fromAddress\tCurrent address of the cell to move\r\n\t * @param\tstring\t\t$toAddress\t\tDestination address of the cell to move\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic function moveCell($fromAddress, $toAddress) {\r\n\t\tif ($fromAddress === $this->_currentObjectID) {\r\n\t\t\t$this->_currentObjectID = $toAddress;\r\n\t\t}\r\n\r\n\t\t$this->_deleteQuery->bindValue('id',$toAddress,SQLITE3_TEXT);\r\n\t\t$result = $this->_deleteQuery->execute();\r\n\t\tif ($result === false)\r\n\t\t\tthrow new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());\r\n\r\n\t\t$this->_updateQuery->bindValue('toid',$toAddress,SQLITE3_TEXT);\r\n\t\t$this->_updateQuery->bindValue('fromid',$fromAddress,SQLITE3_TEXT);\r\n\t\t$result = $this->_updateQuery->execute();\r\n\t\tif ($result === false)\r\n\t\t\tthrow new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());\r\n\r\n\t\treturn TRUE;\r\n\t}\t//\tfunction moveCell()\r\n\r\n\r\n\t/**\r\n\t * Get a list of all cell addresses currently held in cache\r\n\t *\r\n\t * @return\tstring[]\r\n\t */\r\n\tpublic function getCellList() {\r\n\t\tif ($this->_currentObjectID !== null) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\t$query = \"SELECT id FROM kvp_\".$this->_TableName;\r\n\t\t$cellIdsResult = $this->_DBHandle->query($query);\r\n\t\tif ($cellIdsResult === false)\r\n\t\t\tthrow new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());\r\n\r\n\t\t$cellKeys = array();\r\n\t\twhile ($row = $cellIdsResult->fetchArray(SQLITE3_ASSOC)) {\r\n\t\t\t$cellKeys[] = $row['id'];\r\n\t\t}\r\n\r\n\t\treturn $cellKeys;\r\n\t}\t//\tfunction getCellList()\r\n\r\n\r\n\t/**\r\n\t * Clone the cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe new worksheet\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function copyCellCollection(PHPExcel_Worksheet $parent) {\r\n\t\t$this->_currentCellIsDirty;\r\n        $this->_storeData();\r\n\r\n\t\t//\tGet a new id for the new table name\r\n\t\t$tableName = str_replace('.','_',$this->_getUniqueID());\r\n\t\tif (!$this->_DBHandle->exec('CREATE TABLE kvp_'.$tableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)\r\n\t\t                                       AS SELECT * FROM kvp_'.$this->_TableName))\r\n\t\t\tthrow new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());\r\n\r\n\t\t//\tCopy the existing cell cache file\r\n\t\t$this->_TableName = $tableName;\r\n\t}\t//\tfunction copyCellCollection()\r\n\r\n\r\n\t/**\r\n\t * Clear the cell collection and disconnect from our parent\r\n\t *\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function unsetWorksheetCells() {\r\n\t\tif(!is_null($this->_currentObject)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\t\t\t$this->_currentObject = $this->_currentObjectID = null;\r\n\t\t}\r\n\t\t//\tdetach ourself from the worksheet, so that it can then delete this object successfully\r\n\t\t$this->_parent = null;\r\n\r\n\t\t//\tClose down the temporary cache file\r\n\t\t$this->__destruct();\r\n\t}\t//\tfunction unsetWorksheetCells()\r\n\r\n\r\n\t/**\r\n\t * Initialise this new cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe worksheet for this cell collection\r\n\t */\r\n\tpublic function __construct(PHPExcel_Worksheet $parent) {\r\n\t\tparent::__construct($parent);\r\n\t\tif (is_null($this->_DBHandle)) {\r\n\t\t\t$this->_TableName = str_replace('.','_',$this->_getUniqueID());\r\n\t\t\t$_DBName = ':memory:';\r\n\r\n\t\t\t$this->_DBHandle = new SQLite3($_DBName);\r\n\t\t\tif ($this->_DBHandle === false)\r\n\t\t\t\tthrow new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());\r\n\t\t\tif (!$this->_DBHandle->exec('CREATE TABLE kvp_'.$this->_TableName.' (id VARCHAR(12) PRIMARY KEY, value BLOB)'))\r\n\t\t\t\tthrow new PHPExcel_Exception($this->_DBHandle->lastErrorMsg());\r\n\t\t}\r\n\r\n\t\t$this->_selectQuery = $this->_DBHandle->prepare(\"SELECT value FROM kvp_\".$this->_TableName.\" WHERE id = :id\");\r\n\t\t$this->_insertQuery = $this->_DBHandle->prepare(\"INSERT OR REPLACE INTO kvp_\".$this->_TableName.\" VALUES(:id,:data)\");\r\n\t\t$this->_updateQuery = $this->_DBHandle->prepare(\"UPDATE kvp_\".$this->_TableName.\" SET id=:toId WHERE id=:fromId\");\r\n\t\t$this->_deleteQuery = $this->_DBHandle->prepare(\"DELETE FROM kvp_\".$this->_TableName.\" WHERE id = :id\");\r\n\t}\t//\tfunction __construct()\r\n\r\n\r\n\t/**\r\n\t * Destroy this cell collection\r\n\t */\r\n\tpublic function __destruct() {\r\n\t\tif (!is_null($this->_DBHandle)) {\r\n\t\t\t$this->_DBHandle->exec('DROP TABLE kvp_'.$this->_TableName);\r\n\t\t\t$this->_DBHandle->close();\r\n\t\t}\r\n\t\t$this->_DBHandle = null;\r\n\t}\t//\tfunction __destruct()\r\n\r\n\r\n\t/**\r\n\t * Identify whether the caching method is currently available\r\n\t * Some methods are dependent on the availability of certain extensions being enabled in the PHP build\r\n\t *\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic static function cacheMethodIsAvailable() {\r\n\t\tif (!class_exists('SQLite3',FALSE)) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorage/Wincache.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (c) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package\tPHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version\t##VERSION##, ##DATE##\r\n */\r\n\r\n\r\n/**\r\n * PHPExcel_CachedObjectStorage_Wincache\r\n *\r\n * @category   PHPExcel\r\n * @package\tPHPExcel_CachedObjectStorage\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n */\r\nclass PHPExcel_CachedObjectStorage_Wincache extends PHPExcel_CachedObjectStorage_CacheBase implements PHPExcel_CachedObjectStorage_ICache {\r\n\r\n\t/**\r\n\t * Prefix used to uniquely identify cache data for this worksheet\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_cachePrefix = null;\r\n\r\n\t/**\r\n\t * Cache timeout\r\n\t *\r\n\t * @var integer\r\n\t */\r\n\tprivate $_cacheTime = 600;\r\n\r\n\r\n    /**\r\n     * Store cell data in cache for the current cell object if it's \"dirty\",\r\n     *     and the 'nullify' the current cell object\r\n     *\r\n\t * @return\tvoid\r\n     * @throws\tPHPExcel_Exception\r\n     */\r\n\tprotected function _storeData() {\r\n\t\tif ($this->_currentCellIsDirty && !empty($this->_currentObjectID)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\r\n\t\t\t$obj = serialize($this->_currentObject);\r\n\t\t\tif (wincache_ucache_exists($this->_cachePrefix.$this->_currentObjectID.'.cache')) {\r\n\t\t\t\tif (!wincache_ucache_set($this->_cachePrefix.$this->_currentObjectID.'.cache', $obj, $this->_cacheTime)) {\r\n\t\t\t\t\t$this->__destruct();\r\n\t\t\t\t\tthrow new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in WinCache');\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif (!wincache_ucache_add($this->_cachePrefix.$this->_currentObjectID.'.cache', $obj, $this->_cacheTime)) {\r\n\t\t\t\t\t$this->__destruct();\r\n\t\t\t\t\tthrow new PHPExcel_Exception('Failed to store cell '.$this->_currentObjectID.' in WinCache');\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t$this->_currentCellIsDirty = false;\r\n\t\t}\r\n\r\n\t\t$this->_currentObjectID = $this->_currentObject = null;\r\n\t}\t//\tfunction _storeData()\r\n\r\n\r\n\t/**\r\n\t * Add or Update a cell in cache identified by coordinate address\r\n\t *\r\n\t * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to update\r\n\t * @param\tPHPExcel_Cell\t$cell\t\tCell to update\r\n\t * @return\tPHPExcel_Cell\r\n\t * @throws\tPHPExcel_Exception\r\n\t */\r\n\tpublic function addCacheData($pCoord, PHPExcel_Cell $cell) {\r\n\t\tif (($pCoord !== $this->_currentObjectID) && ($this->_currentObjectID !== null)) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\t\t$this->_cellCache[$pCoord] = true;\r\n\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = $cell;\r\n\t\t$this->_currentCellIsDirty = true;\r\n\r\n\t\treturn $cell;\r\n\t}\t//\tfunction addCacheData()\r\n\r\n\r\n\t/**\r\n\t * Is a value set in the current PHPExcel_CachedObjectStorage_ICache for an indexed cell?\r\n\t *\r\n\t * @param\tstring\t\t$pCoord\t\tCoordinate address of the cell to check\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic function isDataSet($pCoord) {\r\n\t\t//\tCheck if the requested entry is the current object, or exists in the cache\r\n\t\tif (parent::isDataSet($pCoord)) {\r\n\t\t\tif ($this->_currentObjectID == $pCoord) {\r\n\t\t\t\treturn true;\r\n\t\t\t}\r\n\t\t\t//\tCheck if the requested entry still exists in cache\r\n\t\t\t$success = wincache_ucache_exists($this->_cachePrefix.$pCoord.'.cache');\r\n\t\t\tif ($success === false) {\r\n\t\t\t\t//\tEntry no longer exists in Wincache, so clear it from the cache array\r\n\t\t\t\tparent::deleteCacheData($pCoord);\r\n\t\t\t\tthrow new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache');\r\n\t\t\t}\r\n\t\t\treturn true;\r\n\t\t}\r\n\t\treturn false;\r\n\t}\t//\tfunction isDataSet()\r\n\r\n\r\n\t/**\r\n\t * Get cell at a specific coordinate\r\n\t *\r\n\t * @param\tstring\t\t\t$pCoord\t\tCoordinate of the cell\r\n\t * @throws\tPHPExcel_Exception\r\n\t * @return\tPHPExcel_Cell\tCell that was found, or null if not found\r\n\t */\r\n\tpublic function getCacheData($pCoord) {\r\n\t\tif ($pCoord === $this->_currentObjectID) {\r\n\t\t\treturn $this->_currentObject;\r\n\t\t}\r\n\t\t$this->_storeData();\r\n\r\n\t\t//\tCheck if the entry that has been requested actually exists\r\n\t\t$obj = null;\r\n\t\tif (parent::isDataSet($pCoord)) {\r\n\t\t\t$success = false;\r\n\t\t\t$obj = wincache_ucache_get($this->_cachePrefix.$pCoord.'.cache', $success);\r\n\t\t\tif ($success === false) {\r\n\t\t\t\t//\tEntry no longer exists in WinCache, so clear it from the cache array\r\n\t\t\t\tparent::deleteCacheData($pCoord);\r\n\t\t\t\tthrow new PHPExcel_Exception('Cell entry '.$pCoord.' no longer exists in WinCache');\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t//\tReturn null if requested entry doesn't exist in cache\r\n\t\t\treturn null;\r\n\t\t}\r\n\r\n\t\t//\tSet current entry to the requested entry\r\n\t\t$this->_currentObjectID = $pCoord;\r\n\t\t$this->_currentObject = unserialize($obj);\r\n        //    Re-attach this as the cell's parent\r\n        $this->_currentObject->attach($this);\r\n\r\n\t\t//\tReturn requested entry\r\n\t\treturn $this->_currentObject;\r\n\t}\t//\tfunction getCacheData()\r\n\r\n\r\n\t/**\r\n\t * Get a list of all cell addresses currently held in cache\r\n\t *\r\n\t * @return  string[]\r\n\t */\r\n\tpublic function getCellList() {\r\n\t\tif ($this->_currentObjectID !== null) {\r\n\t\t\t$this->_storeData();\r\n\t\t}\r\n\r\n\t\treturn parent::getCellList();\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Delete a cell in cache identified by coordinate address\r\n\t *\r\n\t * @param\tstring\t\t\t$pCoord\t\tCoordinate address of the cell to delete\r\n\t * @throws\tPHPExcel_Exception\r\n\t */\r\n\tpublic function deleteCacheData($pCoord) {\r\n\t\t//\tDelete the entry from Wincache\r\n\t\twincache_ucache_delete($this->_cachePrefix.$pCoord.'.cache');\r\n\r\n\t\t//\tDelete the entry from our cell address array\r\n\t\tparent::deleteCacheData($pCoord);\r\n\t}\t//\tfunction deleteCacheData()\r\n\r\n\r\n\t/**\r\n\t * Clone the cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe new worksheet\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function copyCellCollection(PHPExcel_Worksheet $parent) {\r\n\t\tparent::copyCellCollection($parent);\r\n\t\t//\tGet a new id for the new file name\r\n\t\t$baseUnique = $this->_getUniqueID();\r\n\t\t$newCachePrefix = substr(md5($baseUnique),0,8).'.';\r\n\t\t$cacheList = $this->getCellList();\r\n\t\tforeach($cacheList as $cellID) {\r\n\t\t\tif ($cellID != $this->_currentObjectID) {\r\n\t\t\t\t$success = false;\r\n\t\t\t\t$obj = wincache_ucache_get($this->_cachePrefix.$cellID.'.cache', $success);\r\n\t\t\t\tif ($success === false) {\r\n\t\t\t\t\t//\tEntry no longer exists in WinCache, so clear it from the cache array\r\n\t\t\t\t\tparent::deleteCacheData($cellID);\r\n\t\t\t\t\tthrow new PHPExcel_Exception('Cell entry '.$cellID.' no longer exists in Wincache');\r\n\t\t\t\t}\r\n\t\t\t\tif (!wincache_ucache_add($newCachePrefix.$cellID.'.cache', $obj, $this->_cacheTime)) {\r\n\t\t\t\t\t$this->__destruct();\r\n\t\t\t\t\tthrow new PHPExcel_Exception('Failed to store cell '.$cellID.' in Wincache');\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\t$this->_cachePrefix = $newCachePrefix;\r\n\t}\t//\tfunction copyCellCollection()\r\n\r\n\r\n\t/**\r\n\t * Clear the cell collection and disconnect from our parent\r\n\t *\r\n\t * @return\tvoid\r\n\t */\r\n\tpublic function unsetWorksheetCells() {\r\n\t\tif(!is_null($this->_currentObject)) {\r\n\t\t\t$this->_currentObject->detach();\r\n\t\t\t$this->_currentObject = $this->_currentObjectID = null;\r\n\t\t}\r\n\r\n\t\t//\tFlush the WinCache cache\r\n\t\t$this->__destruct();\r\n\r\n\t\t$this->_cellCache = array();\r\n\r\n\t\t//\tdetach ourself from the worksheet, so that it can then delete this object successfully\r\n\t\t$this->_parent = null;\r\n\t}\t//\tfunction unsetWorksheetCells()\r\n\r\n\r\n\t/**\r\n\t * Initialise this new cell collection\r\n\t *\r\n\t * @param\tPHPExcel_Worksheet\t$parent\t\tThe worksheet for this cell collection\r\n\t * @param\tarray of mixed\t\t$arguments\tAdditional initialisation arguments\r\n\t */\r\n\tpublic function __construct(PHPExcel_Worksheet $parent, $arguments) {\r\n\t\t$cacheTime\t= (isset($arguments['cacheTime']))\t? $arguments['cacheTime']\t: 600;\r\n\r\n\t\tif (is_null($this->_cachePrefix)) {\r\n\t\t\t$baseUnique = $this->_getUniqueID();\r\n\t\t\t$this->_cachePrefix = substr(md5($baseUnique),0,8).'.';\r\n\t\t\t$this->_cacheTime = $cacheTime;\r\n\r\n\t\t\tparent::__construct($parent);\r\n\t\t}\r\n\t}\t//\tfunction __construct()\r\n\r\n\r\n\t/**\r\n\t * Destroy this cell collection\r\n\t */\r\n\tpublic function __destruct() {\r\n\t\t$cacheList = $this->getCellList();\r\n\t\tforeach($cacheList as $cellID) {\r\n\t\t\twincache_ucache_delete($this->_cachePrefix.$cellID.'.cache');\r\n\t\t}\r\n\t}\t//\tfunction __destruct()\r\n\r\n\r\n\t/**\r\n\t * Identify whether the caching method is currently available\r\n\t * Some methods are dependent on the availability of certain extensions being enabled in the PHP build\r\n\t *\r\n\t * @return\tboolean\r\n\t */\r\n\tpublic static function cacheMethodIsAvailable() {\r\n\t\tif (!function_exists('wincache_ucache_add')) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\r\n\t\treturn true;\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CachedObjectStorageFactory.php",
    "content": "<?php\n\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_CachedObjectStorage\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_CachedObjectStorageFactory\n *\n * @category    PHPExcel\n * @package        PHPExcel_CachedObjectStorage\n * @copyright    Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_CachedObjectStorageFactory\n{\n    const cache_in_memory               = 'Memory';\n    const cache_in_memory_gzip          = 'MemoryGZip';\n    const cache_in_memory_serialized    = 'MemorySerialized';\n    const cache_igbinary                = 'Igbinary';\n    const cache_to_discISAM             = 'DiscISAM';\n    const cache_to_apc                  = 'APC';\n    const cache_to_memcache             = 'Memcache';\n    const cache_to_phpTemp              = 'PHPTemp';\n    const cache_to_wincache             = 'Wincache';\n    const cache_to_sqlite               = 'SQLite';\n    const cache_to_sqlite3              = 'SQLite3';\n\n\n    /**\n     * Name of the method used for cell cacheing\n     *\n     * @var string\n     */\n    private static $_cacheStorageMethod = NULL;\n\n    /**\n     * Name of the class used for cell cacheing\n     *\n     * @var string\n     */\n    private static $_cacheStorageClass = NULL;\n\n\n    /**\n     * List of all possible cache storage methods\n     *\n     * @var string[]\n     */\n    private static $_storageMethods = array(\n        self::cache_in_memory,\n        self::cache_in_memory_gzip,\n        self::cache_in_memory_serialized,\n        self::cache_igbinary,\n        self::cache_to_phpTemp,\n        self::cache_to_discISAM,\n        self::cache_to_apc,\n        self::cache_to_memcache,\n        self::cache_to_wincache,\n        self::cache_to_sqlite,\n        self::cache_to_sqlite3,\n    );\n\n\n    /**\n     * Default arguments for each cache storage method\n     *\n     * @var array of mixed array\n     */\n    private static $_storageMethodDefaultParameters = array(\n        self::cache_in_memory               => array(\n                                                    ),\n        self::cache_in_memory_gzip          => array(\n                                                    ),\n        self::cache_in_memory_serialized    => array(\n                                                    ),\n        self::cache_igbinary                => array(\n                                                    ),\n        self::cache_to_phpTemp              => array( 'memoryCacheSize' => '1MB'\n                                                    ),\n        self::cache_to_discISAM             => array( 'dir'             => NULL\n                                                    ),\n        self::cache_to_apc                  => array( 'cacheTime'       => 600\n                                                    ),\n        self::cache_to_memcache             => array( 'memcacheServer'  => 'localhost',\n                                                      'memcachePort'    => 11211,\n                                                      'cacheTime'       => 600\n                                                    ),\n        self::cache_to_wincache             => array( 'cacheTime'       => 600\n                                                    ),\n        self::cache_to_sqlite               => array(\n                                                    ),\n        self::cache_to_sqlite3              => array(\n                                                    ),\n    );\n\n\n    /**\n     * Arguments for the active cache storage method\n     *\n     * @var array of mixed array\n     */\n    private static $_storageMethodParameters = array();\n\n\n    /**\n     * Return the current cache storage method\n     *\n     * @return string|NULL\n     **/\n    public static function getCacheStorageMethod()\n    {\n        return self::$_cacheStorageMethod;\n    }   //    function getCacheStorageMethod()\n\n\n    /**\n     * Return the current cache storage class\n     *\n     * @return PHPExcel_CachedObjectStorage_ICache|NULL\n     **/\n    public static function getCacheStorageClass()\n    {\n        return self::$_cacheStorageClass;\n    }   //    function getCacheStorageClass()\n\n\n    /**\n     * Return the list of all possible cache storage methods\n     *\n     * @return string[]\n     **/\n    public static function getAllCacheStorageMethods()\n    {\n        return self::$_storageMethods;\n    }   //    function getCacheStorageMethods()\n\n\n    /**\n     * Return the list of all available cache storage methods\n     *\n     * @return string[]\n     **/\n    public static function getCacheStorageMethods()\n    {\n        $activeMethods = array();\n        foreach(self::$_storageMethods as $storageMethod) {\n            $cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $storageMethod;\n            if (call_user_func(array($cacheStorageClass, 'cacheMethodIsAvailable'))) {\n                $activeMethods[] = $storageMethod;\n            }\n        }\n        return $activeMethods;\n    }   //    function getCacheStorageMethods()\n\n\n    /**\n     * Identify the cache storage method to use\n     *\n     * @param    string            $method        Name of the method to use for cell cacheing\n     * @param    array of mixed    $arguments    Additional arguments to pass to the cell caching class\n     *                                        when instantiating\n     * @return boolean\n     **/\n    public static function initialize($method = self::cache_in_memory, $arguments = array())\n    {\n        if (!in_array($method,self::$_storageMethods)) {\n            return FALSE;\n        }\n\n        $cacheStorageClass = 'PHPExcel_CachedObjectStorage_'.$method;\n        if (!call_user_func(array( $cacheStorageClass,\n                                   'cacheMethodIsAvailable'))) {\n            return FALSE;\n        }\n\n        self::$_storageMethodParameters[$method] = self::$_storageMethodDefaultParameters[$method];\n        foreach($arguments as $k => $v) {\n            if (array_key_exists($k, self::$_storageMethodParameters[$method])) {\n                self::$_storageMethodParameters[$method][$k] = $v;\n            }\n        }\n\n        if (self::$_cacheStorageMethod === NULL) {\n            self::$_cacheStorageClass = 'PHPExcel_CachedObjectStorage_' . $method;\n            self::$_cacheStorageMethod = $method;\n        }\n        return TRUE;\n    }   //    function initialize()\n\n\n    /**\n     * Initialise the cache storage\n     *\n     * @param    PHPExcel_Worksheet     $parent        Enable cell caching for this worksheet\n     * @return    PHPExcel_CachedObjectStorage_ICache\n     **/\n    public static function getInstance(PHPExcel_Worksheet $parent)\n    {\n        $cacheMethodIsAvailable = TRUE;\n        if (self::$_cacheStorageMethod === NULL) {\n            $cacheMethodIsAvailable = self::initialize();\n        }\n\n        if ($cacheMethodIsAvailable) {\n            $instance = new self::$_cacheStorageClass( $parent,\n                                                       self::$_storageMethodParameters[self::$_cacheStorageMethod]\n                                                     );\n            if ($instance !== NULL) {\n                return $instance;\n            }\n        }\n\n        return FALSE;\n    }   //    function getInstance()\n\n\n    /**\n     * Clear the cache storage\n     *\n     **/\n\tpublic static function finalize()\n\t{\n\t\tself::$_cacheStorageMethod = NULL;\n\t\tself::$_cacheStorageClass = NULL;\n\t\tself::$_storageMethodParameters = array();\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CalcEngine/CyclicReferenceStack.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_CalcEngine_CyclicReferenceStack\n *\n * @category\tPHPExcel_CalcEngine_CyclicReferenceStack\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_CalcEngine_CyclicReferenceStack {\n\n\t/**\n\t *  The call stack for calculated cells\n\t *\n\t *  @var mixed[]\n\t */\n\tprivate $_stack = array();\n\n\n\t/**\n\t * Return the number of entries on the stack\n\t *\n\t * @return  integer\n\t */\n\tpublic function count() {\n\t\treturn count($this->_stack);\n\t}\n\n\t/**\n\t * Push a new entry onto the stack\n\t *\n\t * @param  mixed  $value\n\t */\n\tpublic function push($value) {\n\t\t$this->_stack[$value] = $value;\n\t}\n\n\t/**\n\t * Pop the last entry from the stack\n\t *\n\t * @return  mixed\n\t */\n\tpublic function pop() {\n\t\treturn array_pop($this->_stack);\n\t}\n\n\t/**\n\t * Test to see if a specified entry exists on the stack\n\t *\n\t * @param  mixed  $value  The value to test\n\t */\n\tpublic function onStack($value) {\n\t\treturn isset($this->_stack[$value]);\n\t}\n\n\t/**\n\t * Clear the stack\n\t */\n\tpublic function clear() {\n\t\t$this->_stack = array();\n\t}\n\n\t/**\n\t * Return an array of all entries on the stack\n\t *\n\t * @return  mixed[]\n\t */\n\tpublic function showStack() {\n\t\treturn $this->_stack;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/CalcEngine/Logger.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_CalcEngine_Logger\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_CalcEngine_Logger {\n\n\t/**\n\t * Flag to determine whether a debug log should be generated by the calculation engine\n\t *\t\tIf true, then a debug log will be generated\n\t *\t\tIf false, then a debug log will not be generated\n\t *\n\t * @var boolean\n\t */\n\tprivate $_writeDebugLog = FALSE;\n\n\t/**\n\t * Flag to determine whether a debug log should be echoed by the calculation engine\n\t *\t\tIf true, then a debug log will be echoed\n\t *\t\tIf false, then a debug log will not be echoed\n\t * A debug log can only be echoed if it is generated\n\t *\n\t * @var boolean\n\t */\n\tprivate $_echoDebugLog = FALSE;\n\n\t/**\n\t * The debug log generated by the calculation engine\n\t *\n\t * @var string[]\n\t */\n\tprivate $_debugLog = array();\n\n\t/**\n\t * The calculation engine cell reference stack\n\t *\n\t * @var PHPExcel_CalcEngine_CyclicReferenceStack\n\t */\n\tprivate $_cellStack;\n\n\t\n\t/**\n\t * Instantiate a Calculation engine logger\n\t *\n\t * @param  PHPExcel_CalcEngine_CyclicReferenceStack $stack\n\t */\n\tpublic function __construct(PHPExcel_CalcEngine_CyclicReferenceStack $stack) {\n\t\t$this->_cellStack = $stack;\n\t}\n\n\t/**\n\t * Enable/Disable Calculation engine logging\n\t *\n\t * @param  boolean $pValue\n\t */\n\tpublic function setWriteDebugLog($pValue = FALSE) {\n\t\t$this->_writeDebugLog = $pValue;\n\t}\n\n\t/**\n\t * Return whether calculation engine logging is enabled or disabled\n\t *\n\t * @return  boolean\n\t */\n\tpublic function getWriteDebugLog() {\n\t\treturn $this->_writeDebugLog;\n\t}\n\n\t/**\n\t * Enable/Disable echoing of debug log information\n\t *\n\t * @param  boolean $pValue\n\t */\n\tpublic function setEchoDebugLog($pValue = FALSE) {\n\t\t$this->_echoDebugLog = $pValue;\n\t}\n\n\t/**\n\t * Return whether echoing of debug log information is enabled or disabled\n\t *\n\t * @return  boolean\n\t */\n\tpublic function getEchoDebugLog() {\n\t\treturn $this->_echoDebugLog;\n\t}\n\n\t/**\n\t * Write an entry to the calculation engine debug log\n\t */\n\tpublic function writeDebugLog() {\n\t\t//\tOnly write the debug log if logging is enabled\n\t\tif ($this->_writeDebugLog) {\n\t\t\t$message = implode(func_get_args());\n\t\t\t$cellReference = implode(' -> ', $this->_cellStack->showStack());\n\t\t\tif ($this->_echoDebugLog) {\n\t\t\t\techo $cellReference, \n\t\t\t\t\t($this->_cellStack->count() > 0 ? ' => ' : ''), \n\t\t\t\t\t$message, \n\t\t\t\t\tPHP_EOL;\n\t\t\t}\n\t\t\t$this->_debugLog[] = $cellReference . \n\t\t\t\t($this->_cellStack->count() > 0 ? ' => ' : '') . \n\t\t\t\t$message;\n\t\t}\n\t}\t//\tfunction _writeDebug()\n\n\t/**\n\t * Clear the calculation engine debug log\n\t */\n\tpublic function clearLog() {\n\t\t$this->_debugLog = array();\n\t}\t//\tfunction flushLogger()\n\n\t/**\n\t * Return the calculation engine debug log\n\t *\n\t * @return  string[]\n\t */\n\tpublic function getLog() {\n\t\treturn $this->_debugLog;\n\t}\t//\tfunction flushLogger()\n\n}\t//\tclass PHPExcel_CalcEngine_Logger\n\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Database.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\n/**\n * PHPExcel_Calculation_Database\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_Database {\n\n\n\t/**\n\t * __fieldExtract\n\t *\n\t * Extracts the column ID to use for the data field.\n\t *\n\t * @access\tprivate\n\t * @param\tmixed[]\t\t$database\t\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tmixed\t\t$field\t\t\tIndicates which column is used in the function. Enter the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn label enclosed between double quotation marks, such as\n\t *\t\t\t\t\t\t\t\t\t\t\"Age\" or \"Yield,\" or a number (without quotation marks) that\n\t *\t\t\t\t\t\t\t\t\t\trepresents the position of the column within the list: 1 for\n\t *\t\t\t\t\t\t\t\t\t\tthe first column, 2 for the second column, and so on.\n\t * @return\tstring|NULL\n\t *\n\t */\n\tprivate static function __fieldExtract($database,$field) {\n\t\t$field = strtoupper(PHPExcel_Calculation_Functions::flattenSingleValue($field));\n\t\t$fieldNames = array_map('strtoupper',array_shift($database));\n\n\t\tif (is_numeric($field)) {\n\t\t\t$keys = array_keys($fieldNames);\n\t\t\treturn $keys[$field-1];\n\t\t}\n\t\t$key = array_search($field,$fieldNames);\n\t\treturn ($key) ? $key : NULL;\n\t}\n\n\t/**\n\t * __filter\n\t *\n\t * Parses the selection criteria, extracts the database rows that match those criteria, and\n\t * returns that subset of rows.\n\t *\n\t * @access\tprivate\n\t * @param\tmixed[]\t\t$database\t\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tmixed[]\t\t$criteria\t\tThe range of cells that contains the conditions you specify.\n\t *\t\t\t\t\t\t\t\t\t\tYou can use any range for the criteria argument, as long as it\n\t *\t\t\t\t\t\t\t\t\t\tincludes at least one column label and at least one cell below\n\t *\t\t\t\t\t\t\t\t\t\tthe column label in which you specify a condition for the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn.\n\t * @return\tarray of mixed\n\t *\n\t */\n\tprivate static function __filter($database,$criteria) {\n\t\t$fieldNames = array_shift($database);\n\t\t$criteriaNames = array_shift($criteria);\n\n\t\t//\tConvert the criteria into a set of AND/OR conditions with [:placeholders]\n\t\t$testConditions = $testValues = array();\n\t\t$testConditionsCount = 0;\n\t\tforeach($criteriaNames as $key => $criteriaName) {\n\t\t\t$testCondition = array();\n\t\t\t$testConditionCount = 0;\n\t\t\tforeach($criteria as $row => $criterion) {\n\t\t\t\tif ($criterion[$key] > '') {\n\t\t\t\t\t$testCondition[] = '[:'.$criteriaName.']'.PHPExcel_Calculation_Functions::_ifCondition($criterion[$key]);\n\t\t\t\t\t$testConditionCount++;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ($testConditionCount > 1) {\n\t\t\t\t$testConditions[] = 'OR('.implode(',',$testCondition).')';\n\t\t\t\t$testConditionsCount++;\n\t\t\t} elseif($testConditionCount == 1) {\n\t\t\t\t$testConditions[] = $testCondition[0];\n\t\t\t\t$testConditionsCount++;\n\t\t\t}\n\t\t}\n\n\t\tif ($testConditionsCount > 1) {\n\t\t\t$testConditionSet = 'AND('.implode(',',$testConditions).')';\n\t\t} elseif($testConditionsCount == 1) {\n\t\t\t$testConditionSet = $testConditions[0];\n\t\t}\n\n\t\t//\tLoop through each row of the database\n\t\tforeach($database as $dataRow => $dataValues) {\n\t\t\t//\tSubstitute actual values from the database row for our [:placeholders]\n\t\t\t$testConditionList = $testConditionSet;\n\t\t\tforeach($criteriaNames as $key => $criteriaName) {\n\t\t\t\t$k = array_search($criteriaName,$fieldNames);\n\t\t\t\tif (isset($dataValues[$k])) {\n\t\t\t\t\t$dataValue = $dataValues[$k];\n\t\t\t\t\t$dataValue = (is_string($dataValue)) ? PHPExcel_Calculation::_wrapResult(strtoupper($dataValue)) : $dataValue;\n\t\t\t\t\t$testConditionList = str_replace('[:'.$criteriaName.']',$dataValue,$testConditionList);\n\t\t\t\t}\n\t\t\t}\n\t\t\t//\tevaluate the criteria against the row data\n\t\t\t$result = PHPExcel_Calculation::getInstance()->_calculateFormulaValue('='.$testConditionList);\n\t\t\t//\tIf the row failed to meet the criteria, remove it from the database\n\t\t\tif (!$result) {\n\t\t\t\tunset($database[$dataRow]);\n\t\t\t}\n\t\t}\n\n\t\treturn $database;\n\t}\n\n\n\t/**\n\t * DAVERAGE\n\t *\n\t * Averages the values in a column of a list or database that match conditions you specify.\n\t *\n\t * Excel Function:\n\t *\t\tDAVERAGE(database,field,criteria)\n\t *\n\t * @access\tpublic\n\t * @category Database Functions\n\t * @param\tmixed[]\t\t\t$database\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tstring|integer\t$field\t\tIndicates which column is used in the function. Enter the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn label enclosed between double quotation marks, such as\n\t *\t\t\t\t\t\t\t\t\t\t\"Age\" or \"Yield,\" or a number (without quotation marks) that\n\t *\t\t\t\t\t\t\t\t\t\trepresents the position of the column within the list: 1 for\n\t *\t\t\t\t\t\t\t\t\t\tthe first column, 2 for the second column, and so on.\n\t * @param\tmixed[]\t\t\t$criteria\tThe range of cells that contains the conditions you specify.\n\t *\t\t\t\t\t\t\t\t\t\tYou can use any range for the criteria argument, as long as it\n\t *\t\t\t\t\t\t\t\t\t\tincludes at least one column label and at least one cell below\n\t *\t\t\t\t\t\t\t\t\t\tthe column label in which you specify a condition for the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn.\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function DAVERAGE($database,$field,$criteria) {\n\t\t$field = self::__fieldExtract($database,$field);\n\t\tif (is_null($field)) {\n\t\t\treturn NULL;\n\t\t}\n\t\t//\treduce the database to a set of rows that match all the criteria\n\t\t$database = self::__filter($database,$criteria);\n\t\t//\textract an array of values for the requested column\n\t\t$colData = array();\n\t\tforeach($database as $row) {\n\t\t\t$colData[] = $row[$field];\n\t\t}\n\n\t\t// Return\n\t\treturn PHPExcel_Calculation_Statistical::AVERAGE($colData);\n\t}\t//\tfunction DAVERAGE()\n\n\n\t/**\n\t * DCOUNT\n\t *\n\t * Counts the cells that contain numbers in a column of a list or database that match conditions\n\t * that you specify.\n\t *\n\t * Excel Function:\n\t *\t\tDCOUNT(database,[field],criteria)\n\t *\n\t * Excel Function:\n\t *\t\tDAVERAGE(database,field,criteria)\n\t *\n\t * @access\tpublic\n\t * @category Database Functions\n\t * @param\tmixed[]\t\t\t$database\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tstring|integer\t$field\t\tIndicates which column is used in the function. Enter the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn label enclosed between double quotation marks, such as\n\t *\t\t\t\t\t\t\t\t\t\t\"Age\" or \"Yield,\" or a number (without quotation marks) that\n\t *\t\t\t\t\t\t\t\t\t\trepresents the position of the column within the list: 1 for\n\t *\t\t\t\t\t\t\t\t\t\tthe first column, 2 for the second column, and so on.\n\t * @param\tmixed[]\t\t\t$criteria\tThe range of cells that contains the conditions you specify.\n\t *\t\t\t\t\t\t\t\t\t\tYou can use any range for the criteria argument, as long as it\n\t *\t\t\t\t\t\t\t\t\t\tincludes at least one column label and at least one cell below\n\t *\t\t\t\t\t\t\t\t\t\tthe column label in which you specify a condition for the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn.\n\t * @return\tinteger\n\t *\n\t * @TODO\tThe field argument is optional. If field is omitted, DCOUNT counts all records in the\n\t *\t\t\tdatabase that match the criteria.\n\t *\n\t */\n\tpublic static function DCOUNT($database,$field,$criteria) {\n\t\t$field = self::__fieldExtract($database,$field);\n\t\tif (is_null($field)) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\t//\treduce the database to a set of rows that match all the criteria\n\t\t$database = self::__filter($database,$criteria);\n\t\t//\textract an array of values for the requested column\n\t\t$colData = array();\n\t\tforeach($database as $row) {\n\t\t\t$colData[] = $row[$field];\n\t\t}\n\n\t\t// Return\n\t\treturn PHPExcel_Calculation_Statistical::COUNT($colData);\n\t}\t//\tfunction DCOUNT()\n\n\n\t/**\n\t * DCOUNTA\n\t *\n\t * Counts the nonblank cells in a column of a list or database that match conditions that you specify.\n\t *\n\t * Excel Function:\n\t *\t\tDCOUNTA(database,[field],criteria)\n\t *\n\t * @access\tpublic\n\t * @category Database Functions\n\t * @param\tmixed[]\t\t\t$database\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tstring|integer\t$field\t\tIndicates which column is used in the function. Enter the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn label enclosed between double quotation marks, such as\n\t *\t\t\t\t\t\t\t\t\t\t\"Age\" or \"Yield,\" or a number (without quotation marks) that\n\t *\t\t\t\t\t\t\t\t\t\trepresents the position of the column within the list: 1 for\n\t *\t\t\t\t\t\t\t\t\t\tthe first column, 2 for the second column, and so on.\n\t * @param\tmixed[]\t\t\t$criteria\tThe range of cells that contains the conditions you specify.\n\t *\t\t\t\t\t\t\t\t\t\tYou can use any range for the criteria argument, as long as it\n\t *\t\t\t\t\t\t\t\t\t\tincludes at least one column label and at least one cell below\n\t *\t\t\t\t\t\t\t\t\t\tthe column label in which you specify a condition for the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn.\n\t * @return\tinteger\n\t *\n\t * @TODO\tThe field argument is optional. If field is omitted, DCOUNTA counts all records in the\n\t *\t\t\tdatabase that match the criteria.\n\t *\n\t */\n\tpublic static function DCOUNTA($database,$field,$criteria) {\n\t\t$field = self::__fieldExtract($database,$field);\n\t\tif (is_null($field)) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\t//\treduce the database to a set of rows that match all the criteria\n\t\t$database = self::__filter($database,$criteria);\n\t\t//\textract an array of values for the requested column\n\t\t$colData = array();\n\t\tforeach($database as $row) {\n\t\t\t$colData[] = $row[$field];\n\t\t}\n\n\t\t// Return\n\t\treturn PHPExcel_Calculation_Statistical::COUNTA($colData);\n\t}\t//\tfunction DCOUNTA()\n\n\n\t/**\n\t * DGET\n\t *\n\t * Extracts a single value from a column of a list or database that matches conditions that you\n\t * specify.\n\t *\n\t * Excel Function:\n\t *\t\tDGET(database,field,criteria)\n\t *\n\t * @access\tpublic\n\t * @category Database Functions\n\t * @param\tmixed[]\t\t\t$database\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tstring|integer\t$field\t\tIndicates which column is used in the function. Enter the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn label enclosed between double quotation marks, such as\n\t *\t\t\t\t\t\t\t\t\t\t\"Age\" or \"Yield,\" or a number (without quotation marks) that\n\t *\t\t\t\t\t\t\t\t\t\trepresents the position of the column within the list: 1 for\n\t *\t\t\t\t\t\t\t\t\t\tthe first column, 2 for the second column, and so on.\n\t * @param\tmixed[]\t\t\t$criteria\tThe range of cells that contains the conditions you specify.\n\t *\t\t\t\t\t\t\t\t\t\tYou can use any range for the criteria argument, as long as it\n\t *\t\t\t\t\t\t\t\t\t\tincludes at least one column label and at least one cell below\n\t *\t\t\t\t\t\t\t\t\t\tthe column label in which you specify a condition for the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn.\n\t * @return\tmixed\n\t *\n\t */\n\tpublic static function DGET($database,$field,$criteria) {\n\t\t$field = self::__fieldExtract($database,$field);\n\t\tif (is_null($field)) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\t//\treduce the database to a set of rows that match all the criteria\n\t\t$database = self::__filter($database,$criteria);\n\t\t//\textract an array of values for the requested column\n\t\t$colData = array();\n\t\tforeach($database as $row) {\n\t\t\t$colData[] = $row[$field];\n\t\t}\n\n\t\t// Return\n\t\tif (count($colData) > 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\treturn $colData[0];\n\t}\t//\tfunction DGET()\n\n\n\t/**\n\t * DMAX\n\t *\n\t * Returns the largest number in a column of a list or database that matches conditions you that\n\t * specify.\n\t *\n\t * Excel Function:\n\t *\t\tDMAX(database,field,criteria)\n\t *\n\t * @access\tpublic\n\t * @category Database Functions\n\t * @param\tmixed[]\t\t\t$database\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tstring|integer\t$field\t\tIndicates which column is used in the function. Enter the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn label enclosed between double quotation marks, such as\n\t *\t\t\t\t\t\t\t\t\t\t\"Age\" or \"Yield,\" or a number (without quotation marks) that\n\t *\t\t\t\t\t\t\t\t\t\trepresents the position of the column within the list: 1 for\n\t *\t\t\t\t\t\t\t\t\t\tthe first column, 2 for the second column, and so on.\n\t * @param\tmixed[]\t\t\t$criteria\tThe range of cells that contains the conditions you specify.\n\t *\t\t\t\t\t\t\t\t\t\tYou can use any range for the criteria argument, as long as it\n\t *\t\t\t\t\t\t\t\t\t\tincludes at least one column label and at least one cell below\n\t *\t\t\t\t\t\t\t\t\t\tthe column label in which you specify a condition for the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn.\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function DMAX($database,$field,$criteria) {\n\t\t$field = self::__fieldExtract($database,$field);\n\t\tif (is_null($field)) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\t//\treduce the database to a set of rows that match all the criteria\n\t\t$database = self::__filter($database,$criteria);\n\t\t//\textract an array of values for the requested column\n\t\t$colData = array();\n\t\tforeach($database as $row) {\n\t\t\t$colData[] = $row[$field];\n\t\t}\n\n\t\t// Return\n\t\treturn PHPExcel_Calculation_Statistical::MAX($colData);\n\t}\t//\tfunction DMAX()\n\n\n\t/**\n\t * DMIN\n\t *\n\t * Returns the smallest number in a column of a list or database that matches conditions you that\n\t * specify.\n\t *\n\t * Excel Function:\n\t *\t\tDMIN(database,field,criteria)\n\t *\n\t * @access\tpublic\n\t * @category Database Functions\n\t * @param\tmixed[]\t\t\t$database\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tstring|integer\t$field\t\tIndicates which column is used in the function. Enter the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn label enclosed between double quotation marks, such as\n\t *\t\t\t\t\t\t\t\t\t\t\"Age\" or \"Yield,\" or a number (without quotation marks) that\n\t *\t\t\t\t\t\t\t\t\t\trepresents the position of the column within the list: 1 for\n\t *\t\t\t\t\t\t\t\t\t\tthe first column, 2 for the second column, and so on.\n\t * @param\tmixed[]\t\t\t$criteria\tThe range of cells that contains the conditions you specify.\n\t *\t\t\t\t\t\t\t\t\t\tYou can use any range for the criteria argument, as long as it\n\t *\t\t\t\t\t\t\t\t\t\tincludes at least one column label and at least one cell below\n\t *\t\t\t\t\t\t\t\t\t\tthe column label in which you specify a condition for the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn.\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function DMIN($database,$field,$criteria) {\n\t\t$field = self::__fieldExtract($database,$field);\n\t\tif (is_null($field)) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\t//\treduce the database to a set of rows that match all the criteria\n\t\t$database = self::__filter($database,$criteria);\n\t\t//\textract an array of values for the requested column\n\t\t$colData = array();\n\t\tforeach($database as $row) {\n\t\t\t$colData[] = $row[$field];\n\t\t}\n\n\t\t// Return\n\t\treturn PHPExcel_Calculation_Statistical::MIN($colData);\n\t}\t//\tfunction DMIN()\n\n\n\t/**\n\t * DPRODUCT\n\t *\n\t * Multiplies the values in a column of a list or database that match conditions that you specify.\n\t *\n\t * Excel Function:\n\t *\t\tDPRODUCT(database,field,criteria)\n\t *\n\t * @access\tpublic\n\t * @category Database Functions\n\t * @param\tmixed[]\t\t\t$database\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tstring|integer\t$field\t\tIndicates which column is used in the function. Enter the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn label enclosed between double quotation marks, such as\n\t *\t\t\t\t\t\t\t\t\t\t\"Age\" or \"Yield,\" or a number (without quotation marks) that\n\t *\t\t\t\t\t\t\t\t\t\trepresents the position of the column within the list: 1 for\n\t *\t\t\t\t\t\t\t\t\t\tthe first column, 2 for the second column, and so on.\n\t * @param\tmixed[]\t\t\t$criteria\tThe range of cells that contains the conditions you specify.\n\t *\t\t\t\t\t\t\t\t\t\tYou can use any range for the criteria argument, as long as it\n\t *\t\t\t\t\t\t\t\t\t\tincludes at least one column label and at least one cell below\n\t *\t\t\t\t\t\t\t\t\t\tthe column label in which you specify a condition for the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn.\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function DPRODUCT($database,$field,$criteria) {\n\t\t$field = self::__fieldExtract($database,$field);\n\t\tif (is_null($field)) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\t//\treduce the database to a set of rows that match all the criteria\n\t\t$database = self::__filter($database,$criteria);\n\t\t//\textract an array of values for the requested column\n\t\t$colData = array();\n\t\tforeach($database as $row) {\n\t\t\t$colData[] = $row[$field];\n\t\t}\n\n\t\t// Return\n\t\treturn PHPExcel_Calculation_MathTrig::PRODUCT($colData);\n\t}\t//\tfunction DPRODUCT()\n\n\n\t/**\n\t * DSTDEV\n\t *\n\t * Estimates the standard deviation of a population based on a sample by using the numbers in a\n\t * column of a list or database that match conditions that you specify.\n\t *\n\t * Excel Function:\n\t *\t\tDSTDEV(database,field,criteria)\n\t *\n\t * @access\tpublic\n\t * @category Database Functions\n\t * @param\tmixed[]\t\t\t$database\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tstring|integer\t$field\t\tIndicates which column is used in the function. Enter the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn label enclosed between double quotation marks, such as\n\t *\t\t\t\t\t\t\t\t\t\t\"Age\" or \"Yield,\" or a number (without quotation marks) that\n\t *\t\t\t\t\t\t\t\t\t\trepresents the position of the column within the list: 1 for\n\t *\t\t\t\t\t\t\t\t\t\tthe first column, 2 for the second column, and so on.\n\t * @param\tmixed[]\t\t\t$criteria\tThe range of cells that contains the conditions you specify.\n\t *\t\t\t\t\t\t\t\t\t\tYou can use any range for the criteria argument, as long as it\n\t *\t\t\t\t\t\t\t\t\t\tincludes at least one column label and at least one cell below\n\t *\t\t\t\t\t\t\t\t\t\tthe column label in which you specify a condition for the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn.\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function DSTDEV($database,$field,$criteria) {\n\t\t$field = self::__fieldExtract($database,$field);\n\t\tif (is_null($field)) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\t//\treduce the database to a set of rows that match all the criteria\n\t\t$database = self::__filter($database,$criteria);\n\t\t//\textract an array of values for the requested column\n\t\t$colData = array();\n\t\tforeach($database as $row) {\n\t\t\t$colData[] = $row[$field];\n\t\t}\n\n\t\t// Return\n\t\treturn PHPExcel_Calculation_Statistical::STDEV($colData);\n\t}\t//\tfunction DSTDEV()\n\n\n\t/**\n\t * DSTDEVP\n\t *\n\t * Calculates the standard deviation of a population based on the entire population by using the\n\t * numbers in a column of a list or database that match conditions that you specify.\n\t *\n\t * Excel Function:\n\t *\t\tDSTDEVP(database,field,criteria)\n\t *\n\t * @access\tpublic\n\t * @category Database Functions\n\t * @param\tmixed[]\t\t\t$database\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tstring|integer\t$field\t\tIndicates which column is used in the function. Enter the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn label enclosed between double quotation marks, such as\n\t *\t\t\t\t\t\t\t\t\t\t\"Age\" or \"Yield,\" or a number (without quotation marks) that\n\t *\t\t\t\t\t\t\t\t\t\trepresents the position of the column within the list: 1 for\n\t *\t\t\t\t\t\t\t\t\t\tthe first column, 2 for the second column, and so on.\n\t * @param\tmixed[]\t\t\t$criteria\tThe range of cells that contains the conditions you specify.\n\t *\t\t\t\t\t\t\t\t\t\tYou can use any range for the criteria argument, as long as it\n\t *\t\t\t\t\t\t\t\t\t\tincludes at least one column label and at least one cell below\n\t *\t\t\t\t\t\t\t\t\t\tthe column label in which you specify a condition for the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn.\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function DSTDEVP($database,$field,$criteria) {\n\t\t$field = self::__fieldExtract($database,$field);\n\t\tif (is_null($field)) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\t//\treduce the database to a set of rows that match all the criteria\n\t\t$database = self::__filter($database,$criteria);\n\t\t//\textract an array of values for the requested column\n\t\t$colData = array();\n\t\tforeach($database as $row) {\n\t\t\t$colData[] = $row[$field];\n\t\t}\n\n\t\t// Return\n\t\treturn PHPExcel_Calculation_Statistical::STDEVP($colData);\n\t}\t//\tfunction DSTDEVP()\n\n\n\t/**\n\t * DSUM\n\t *\n\t * Adds the numbers in a column of a list or database that match conditions that you specify.\n\t *\n\t * Excel Function:\n\t *\t\tDSUM(database,field,criteria)\n\t *\n\t * @access\tpublic\n\t * @category Database Functions\n\t * @param\tmixed[]\t\t\t$database\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tstring|integer\t$field\t\tIndicates which column is used in the function. Enter the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn label enclosed between double quotation marks, such as\n\t *\t\t\t\t\t\t\t\t\t\t\"Age\" or \"Yield,\" or a number (without quotation marks) that\n\t *\t\t\t\t\t\t\t\t\t\trepresents the position of the column within the list: 1 for\n\t *\t\t\t\t\t\t\t\t\t\tthe first column, 2 for the second column, and so on.\n\t * @param\tmixed[]\t\t\t$criteria\tThe range of cells that contains the conditions you specify.\n\t *\t\t\t\t\t\t\t\t\t\tYou can use any range for the criteria argument, as long as it\n\t *\t\t\t\t\t\t\t\t\t\tincludes at least one column label and at least one cell below\n\t *\t\t\t\t\t\t\t\t\t\tthe column label in which you specify a condition for the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn.\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function DSUM($database,$field,$criteria) {\n\t\t$field = self::__fieldExtract($database,$field);\n\t\tif (is_null($field)) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\t//\treduce the database to a set of rows that match all the criteria\n\t\t$database = self::__filter($database,$criteria);\n\t\t//\textract an array of values for the requested column\n\t\t$colData = array();\n\t\tforeach($database as $row) {\n\t\t\t$colData[] = $row[$field];\n\t\t}\n\n\t\t// Return\n\t\treturn PHPExcel_Calculation_MathTrig::SUM($colData);\n\t}\t//\tfunction DSUM()\n\n\n\t/**\n\t * DVAR\n\t *\n\t * Estimates the variance of a population based on a sample by using the numbers in a column\n\t * of a list or database that match conditions that you specify.\n\t *\n\t * Excel Function:\n\t *\t\tDVAR(database,field,criteria)\n\t *\n\t * @access\tpublic\n\t * @category Database Functions\n\t * @param\tmixed[]\t\t\t$database\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tstring|integer\t$field\t\tIndicates which column is used in the function. Enter the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn label enclosed between double quotation marks, such as\n\t *\t\t\t\t\t\t\t\t\t\t\"Age\" or \"Yield,\" or a number (without quotation marks) that\n\t *\t\t\t\t\t\t\t\t\t\trepresents the position of the column within the list: 1 for\n\t *\t\t\t\t\t\t\t\t\t\tthe first column, 2 for the second column, and so on.\n\t * @param\tmixed[]\t\t\t$criteria\tThe range of cells that contains the conditions you specify.\n\t *\t\t\t\t\t\t\t\t\t\tYou can use any range for the criteria argument, as long as it\n\t *\t\t\t\t\t\t\t\t\t\tincludes at least one column label and at least one cell below\n\t *\t\t\t\t\t\t\t\t\t\tthe column label in which you specify a condition for the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn.\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function DVAR($database,$field,$criteria) {\n\t\t$field = self::__fieldExtract($database,$field);\n\t\tif (is_null($field)) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\t//\treduce the database to a set of rows that match all the criteria\n\t\t$database = self::__filter($database,$criteria);\n\t\t//\textract an array of values for the requested column\n\t\t$colData = array();\n\t\tforeach($database as $row) {\n\t\t\t$colData[] = $row[$field];\n\t\t}\n\n\t\t// Return\n\t\treturn PHPExcel_Calculation_Statistical::VARFunc($colData);\n\t}\t//\tfunction DVAR()\n\n\n\t/**\n\t * DVARP\n\t *\n\t * Calculates the variance of a population based on the entire population by using the numbers\n\t * in a column of a list or database that match conditions that you specify.\n\t *\n\t * Excel Function:\n\t *\t\tDVARP(database,field,criteria)\n\t *\n\t * @access\tpublic\n\t * @category Database Functions\n\t * @param\tmixed[]\t\t\t$database\tThe range of cells that makes up the list or database.\n\t *\t\t\t\t\t\t\t\t\t\tA database is a list of related data in which rows of related\n\t *\t\t\t\t\t\t\t\t\t\tinformation are records, and columns of data are fields. The\n\t *\t\t\t\t\t\t\t\t\t\tfirst row of the list contains labels for each column.\n\t * @param\tstring|integer\t$field\t\tIndicates which column is used in the function. Enter the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn label enclosed between double quotation marks, such as\n\t *\t\t\t\t\t\t\t\t\t\t\"Age\" or \"Yield,\" or a number (without quotation marks) that\n\t *\t\t\t\t\t\t\t\t\t\trepresents the position of the column within the list: 1 for\n\t *\t\t\t\t\t\t\t\t\t\tthe first column, 2 for the second column, and so on.\n\t * @param\tmixed[]\t\t\t$criteria\tThe range of cells that contains the conditions you specify.\n\t *\t\t\t\t\t\t\t\t\t\tYou can use any range for the criteria argument, as long as it\n\t *\t\t\t\t\t\t\t\t\t\tincludes at least one column label and at least one cell below\n\t *\t\t\t\t\t\t\t\t\t\tthe column label in which you specify a condition for the\n\t *\t\t\t\t\t\t\t\t\t\tcolumn.\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function DVARP($database,$field,$criteria) {\n\t\t$field = self::__fieldExtract($database,$field);\n\t\tif (is_null($field)) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\t//\treduce the database to a set of rows that match all the criteria\n\t\t$database = self::__filter($database,$criteria);\n\t\t//\textract an array of values for the requested column\n\t\t$colData = array();\n\t\tforeach($database as $row) {\n\t\t\t$colData[] = $row[$field];\n\t\t}\n\n\t\t// Return\n\t\treturn PHPExcel_Calculation_Statistical::VARP($colData);\n\t}\t//\tfunction DVARP()\n\n\n}\t//\tclass PHPExcel_Calculation_Database\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/DateTime.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\n/**\n * PHPExcel_Calculation_DateTime\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_DateTime {\n\n\t/**\n\t * Identify if a year is a leap year or not\n\t *\n\t * @param\tinteger\t$year\tThe year to test\n\t * @return\tboolean\t\t\tTRUE if the year is a leap year, otherwise FALSE\n\t */\n\tpublic static function _isLeapYear($year) {\n\t\treturn ((($year % 4) == 0) && (($year % 100) != 0) || (($year % 400) == 0));\n\t}\t//\tfunction _isLeapYear()\n\n\n\t/**\n\t * Return the number of days between two dates based on a 360 day calendar\n\t *\n\t * @param\tinteger\t$startDay\t\tDay of month of the start date\n\t * @param\tinteger\t$startMonth\t\tMonth of the start date\n\t * @param\tinteger\t$startYear\t\tYear of the start date\n\t * @param\tinteger\t$endDay\t\t\tDay of month of the start date\n\t * @param\tinteger\t$endMonth\t\tMonth of the start date\n\t * @param\tinteger\t$endYear\t\tYear of the start date\n\t * @param\tboolean $methodUS\t\tWhether to use the US method or the European method of calculation\n\t * @return\tinteger\tNumber of days between the start date and the end date\n\t */\n\tprivate static function _dateDiff360($startDay, $startMonth, $startYear, $endDay, $endMonth, $endYear, $methodUS) {\n\t\tif ($startDay == 31) {\n\t\t\t--$startDay;\n\t\t} elseif ($methodUS && ($startMonth == 2 && ($startDay == 29 || ($startDay == 28 && !self::_isLeapYear($startYear))))) {\n\t\t\t$startDay = 30;\n\t\t}\n\t\tif ($endDay == 31) {\n\t\t\tif ($methodUS && $startDay != 30) {\n\t\t\t\t$endDay = 1;\n\t\t\t\tif ($endMonth == 12) {\n\t\t\t\t\t++$endYear;\n\t\t\t\t\t$endMonth = 1;\n\t\t\t\t} else {\n\t\t\t\t\t++$endMonth;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$endDay = 30;\n\t\t\t}\n\t\t}\n\n\t\treturn $endDay + $endMonth * 30 + $endYear * 360 - $startDay - $startMonth * 30 - $startYear * 360;\n\t}\t//\tfunction _dateDiff360()\n\n\n\t/**\n\t * _getDateValue\n\t *\n\t * @param\tstring\t$dateValue\n\t * @return\tmixed\tExcel date/time serial value, or string if error\n\t */\n\tpublic static function _getDateValue($dateValue) {\n\t\tif (!is_numeric($dateValue)) {\n\t\t\tif ((is_string($dateValue)) &&\n\t\t\t\t(PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t\tif ((is_object($dateValue)) && ($dateValue instanceof DateTime)) {\n\t\t\t\t$dateValue = PHPExcel_Shared_Date::PHPToExcel($dateValue);\n\t\t\t} else {\n\t\t\t\t$saveReturnDateType = PHPExcel_Calculation_Functions::getReturnDateType();\n\t\t\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n\t\t\t\t$dateValue = self::DATEVALUE($dateValue);\n\t\t\t\tPHPExcel_Calculation_Functions::setReturnDateType($saveReturnDateType);\n\t\t\t}\n\t\t}\n\t\treturn $dateValue;\n\t}\t//\tfunction _getDateValue()\n\n\n\t/**\n\t * _getTimeValue\n\t *\n\t * @param\tstring\t$timeValue\n\t * @return\tmixed\tExcel date/time serial value, or string if error\n\t */\n\tprivate static function _getTimeValue($timeValue) {\n\t\t$saveReturnDateType = PHPExcel_Calculation_Functions::getReturnDateType();\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n\t\t$timeValue = self::TIMEVALUE($timeValue);\n\t\tPHPExcel_Calculation_Functions::setReturnDateType($saveReturnDateType);\n\t\treturn $timeValue;\n\t}\t//\tfunction _getTimeValue()\n\n\n\tprivate static function _adjustDateByMonths($dateValue = 0, $adjustmentMonths = 0) {\n\t\t// Execute function\n\t\t$PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue);\n\t\t$oMonth = (int) $PHPDateObject->format('m');\n\t\t$oYear = (int) $PHPDateObject->format('Y');\n\n\t\t$adjustmentMonthsString = (string) $adjustmentMonths;\n\t\tif ($adjustmentMonths > 0) {\n\t\t\t$adjustmentMonthsString = '+'.$adjustmentMonths;\n\t\t}\n\t\tif ($adjustmentMonths != 0) {\n\t\t\t$PHPDateObject->modify($adjustmentMonthsString.' months');\n\t\t}\n\t\t$nMonth = (int) $PHPDateObject->format('m');\n\t\t$nYear = (int) $PHPDateObject->format('Y');\n\n\t\t$monthDiff = ($nMonth - $oMonth) + (($nYear - $oYear) * 12);\n\t\tif ($monthDiff != $adjustmentMonths) {\n\t\t\t$adjustDays = (int) $PHPDateObject->format('d');\n\t\t\t$adjustDaysString = '-'.$adjustDays.' days';\n\t\t\t$PHPDateObject->modify($adjustDaysString);\n\t\t}\n\t\treturn $PHPDateObject;\n\t}\t//\tfunction _adjustDateByMonths()\n\n\n\t/**\n\t * DATETIMENOW\n\t *\n\t * Returns the current date and time.\n\t * The NOW function is useful when you need to display the current date and time on a worksheet or\n\t * calculate a value based on the current date and time, and have that value updated each time you\n\t * open the worksheet.\n\t *\n\t * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date\n\t * and time format of your regional settings. PHPExcel does not change cell formatting in this way.\n\t *\n\t * Excel Function:\n\t *\t\tNOW()\n\t *\n\t * @access\tpublic\n\t * @category Date/Time Functions\n\t * @return\tmixed\tExcel date/time serial value, PHP date/time serial value or PHP date/time object,\n\t *\t\t\t\t\t\tdepending on the value of the ReturnDateType flag\n\t */\n\tpublic static function DATETIMENOW() {\n\t\t$saveTimeZone = date_default_timezone_get();\n\t\tdate_default_timezone_set('UTC');\n\t\t$retValue = False;\n\t\tswitch (PHPExcel_Calculation_Functions::getReturnDateType()) {\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_EXCEL :\n\t\t\t\t\t$retValue = (float) PHPExcel_Shared_Date::PHPToExcel(time());\n\t\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC :\n\t\t\t\t\t$retValue = (integer) time();\n\t\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT :\n\t\t\t\t\t$retValue = new DateTime();\n\t\t\t\t\tbreak;\n\t\t}\n\t\tdate_default_timezone_set($saveTimeZone);\n\n\t\treturn $retValue;\n\t}\t//\tfunction DATETIMENOW()\n\n\n\t/**\n\t * DATENOW\n\t *\n\t * Returns the current date.\n\t * The NOW function is useful when you need to display the current date and time on a worksheet or\n\t * calculate a value based on the current date and time, and have that value updated each time you\n\t * open the worksheet.\n\t *\n\t * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date\n\t * and time format of your regional settings. PHPExcel does not change cell formatting in this way.\n\t *\n\t * Excel Function:\n\t *\t\tTODAY()\n\t *\n\t * @access\tpublic\n\t * @category Date/Time Functions\n\t * @return\tmixed\tExcel date/time serial value, PHP date/time serial value or PHP date/time object,\n\t *\t\t\t\t\t\tdepending on the value of the ReturnDateType flag\n\t */\n\tpublic static function DATENOW() {\n\t\t$saveTimeZone = date_default_timezone_get();\n\t\tdate_default_timezone_set('UTC');\n\t\t$retValue = False;\n\t\t$excelDateTime = floor(PHPExcel_Shared_Date::PHPToExcel(time()));\n\t\tswitch (PHPExcel_Calculation_Functions::getReturnDateType()) {\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_EXCEL :\n\t\t\t\t\t$retValue = (float) $excelDateTime;\n\t\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC :\n\t\t\t\t\t$retValue = (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateTime);\n\t\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT :\n\t\t\t\t\t$retValue = PHPExcel_Shared_Date::ExcelToPHPObject($excelDateTime);\n\t\t\t\t\tbreak;\n\t\t}\n\t\tdate_default_timezone_set($saveTimeZone);\n\n\t\treturn $retValue;\n\t}\t//\tfunction DATENOW()\n\n\n\t/**\n\t * DATE\n\t *\n\t * The DATE function returns a value that represents a particular date.\n\t *\n\t * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date\n\t * format of your regional settings. PHPExcel does not change cell formatting in this way.\n\t *\n\t * Excel Function:\n\t *\t\tDATE(year,month,day)\n\t *\n\t * PHPExcel is a lot more forgiving than MS Excel when passing non numeric values to this function.\n\t * A Month name or abbreviation (English only at this point) such as 'January' or 'Jan' will still be accepted,\n\t *     as will a day value with a suffix (e.g. '21st' rather than simply 21); again only English language.\n\t *\n\t * @access\tpublic\n\t * @category Date/Time Functions\n\t * @param\tinteger\t\t$year\tThe value of the year argument can include one to four digits.\n\t *\t\t\t\t\t\t\t\tExcel interprets the year argument according to the configured\n\t *\t\t\t\t\t\t\t\tdate system: 1900 or 1904.\n\t *\t\t\t\t\t\t\t\tIf year is between 0 (zero) and 1899 (inclusive), Excel adds that\n\t *\t\t\t\t\t\t\t\tvalue to 1900 to calculate the year. For example, DATE(108,1,2)\n\t *\t\t\t\t\t\t\t\treturns January 2, 2008 (1900+108).\n\t *\t\t\t\t\t\t\t\tIf year is between 1900 and 9999 (inclusive), Excel uses that\n\t *\t\t\t\t\t\t\t\tvalue as the year. For example, DATE(2008,1,2) returns January 2,\n\t *\t\t\t\t\t\t\t\t2008.\n\t *\t\t\t\t\t\t\t\tIf year is less than 0 or is 10000 or greater, Excel returns the\n\t *\t\t\t\t\t\t\t\t#NUM! error value.\n\t * @param\tinteger\t\t$month\tA positive or negative integer representing the month of the year\n\t *\t\t\t\t\t\t\t\tfrom 1 to 12 (January to December).\n\t *\t\t\t\t\t\t\t\tIf month is greater than 12, month adds that number of months to\n\t *\t\t\t\t\t\t\t\tthe first month in the year specified. For example, DATE(2008,14,2)\n\t *\t\t\t\t\t\t\t\treturns the serial number representing February 2, 2009.\n\t *\t\t\t\t\t\t\t\tIf month is less than 1, month subtracts the magnitude of that\n\t *\t\t\t\t\t\t\t\tnumber of months, plus 1, from the first month in the year\n\t *\t\t\t\t\t\t\t\tspecified. For example, DATE(2008,-3,2) returns the serial number\n\t *\t\t\t\t\t\t\t\trepresenting September 2, 2007.\n\t * @param\tinteger\t\t$day\tA positive or negative integer representing the day of the month\n\t *\t\t\t\t\t\t\t\tfrom 1 to 31.\n\t *\t\t\t\t\t\t\t\tIf day is greater than the number of days in the month specified,\n\t *\t\t\t\t\t\t\t\tday adds that number of days to the first day in the month. For\n\t *\t\t\t\t\t\t\t\texample, DATE(2008,1,35) returns the serial number representing\n\t *\t\t\t\t\t\t\t\tFebruary 4, 2008.\n\t *\t\t\t\t\t\t\t\tIf day is less than 1, day subtracts the magnitude that number of\n\t *\t\t\t\t\t\t\t\tdays, plus one, from the first day of the month specified. For\n\t *\t\t\t\t\t\t\t\texample, DATE(2008,1,-15) returns the serial number representing\n\t *\t\t\t\t\t\t\t\tDecember 16, 2007.\n\t * @return\tmixed\tExcel date/time serial value, PHP date/time serial value or PHP date/time object,\n\t *\t\t\t\t\t\tdepending on the value of the ReturnDateType flag\n\t */\n\tpublic static function DATE($year = 0, $month = 1, $day = 1) {\n\t\t$year\t= PHPExcel_Calculation_Functions::flattenSingleValue($year);\n\t\t$month\t= PHPExcel_Calculation_Functions::flattenSingleValue($month);\n\t\t$day\t= PHPExcel_Calculation_Functions::flattenSingleValue($day);\n\n\t\tif (($month !== NULL) && (!is_numeric($month))) {\n            $month = PHPExcel_Shared_Date::monthStringToNumber($month);\n\t\t}\n\n\t\tif (($day !== NULL) && (!is_numeric($day))) {\n            $day = PHPExcel_Shared_Date::dayStringToNumber($day);\n\t\t}\n\n\t\t$year\t= ($year !== NULL)\t? PHPExcel_Shared_String::testStringAsNumeric($year) : 0;\n\t\t$month\t= ($month !== NULL)\t? PHPExcel_Shared_String::testStringAsNumeric($month) : 0;\n\t\t$day\t= ($day !== NULL)\t? PHPExcel_Shared_String::testStringAsNumeric($day) : 0;\n\t\tif ((!is_numeric($year)) ||\n\t\t\t(!is_numeric($month)) ||\n\t\t\t(!is_numeric($day))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$year\t= (integer) $year;\n\t\t$month\t= (integer) $month;\n\t\t$day\t= (integer) $day;\n\n\t\t$baseYear = PHPExcel_Shared_Date::getExcelCalendar();\n\t\t// Validate parameters\n\t\tif ($year < ($baseYear-1900)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\tif ((($baseYear-1900) != 0) && ($year < $baseYear) && ($year >= 1900)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\tif (($year < $baseYear) && ($year >= ($baseYear-1900))) {\n\t\t\t$year += 1900;\n\t\t}\n\n\t\tif ($month < 1) {\n\t\t\t//\tHandle year/month adjustment if month < 1\n\t\t\t--$month;\n\t\t\t$year += ceil($month / 12) - 1;\n\t\t\t$month = 13 - abs($month % 12);\n\t\t} elseif ($month > 12) {\n\t\t\t//\tHandle year/month adjustment if month > 12\n\t\t\t$year += floor($month / 12);\n\t\t\t$month = ($month % 12);\n\t\t}\n\n\t\t// Re-validate the year parameter after adjustments\n\t\tif (($year < $baseYear) || ($year >= 10000)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t// Execute function\n\t\t$excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year, $month, $day);\n\t\tswitch (PHPExcel_Calculation_Functions::getReturnDateType()) {\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_EXCEL :\n\t\t\t\t\treturn (float) $excelDateValue;\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC :\n\t\t\t\t\treturn (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateValue);\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT :\n\t\t\t\t\treturn PHPExcel_Shared_Date::ExcelToPHPObject($excelDateValue);\n\t\t}\n\t}\t//\tfunction DATE()\n\n\n\t/**\n\t * TIME\n\t *\n\t * The TIME function returns a value that represents a particular time.\n\t *\n\t * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time\n\t * format of your regional settings. PHPExcel does not change cell formatting in this way.\n\t *\n\t * Excel Function:\n\t *\t\tTIME(hour,minute,second)\n\t *\n\t * @access\tpublic\n\t * @category Date/Time Functions\n\t * @param\tinteger\t\t$hour\t\tA number from 0 (zero) to 32767 representing the hour.\n\t *\t\t\t\t\t\t\t\t\tAny value greater than 23 will be divided by 24 and the remainder\n\t *\t\t\t\t\t\t\t\t\twill be treated as the hour value. For example, TIME(27,0,0) =\n\t *\t\t\t\t\t\t\t\t\tTIME(3,0,0) = .125 or 3:00 AM.\n\t * @param\tinteger\t\t$minute\t\tA number from 0 to 32767 representing the minute.\n\t *\t\t\t\t\t\t\t\t\tAny value greater than 59 will be converted to hours and minutes.\n\t *\t\t\t\t\t\t\t\t\tFor example, TIME(0,750,0) = TIME(12,30,0) = .520833 or 12:30 PM.\n\t * @param\tinteger\t\t$second\t\tA number from 0 to 32767 representing the second.\n\t *\t\t\t\t\t\t\t\t\tAny value greater than 59 will be converted to hours, minutes,\n\t *\t\t\t\t\t\t\t\t\tand seconds. For example, TIME(0,0,2000) = TIME(0,33,22) = .023148\n\t *\t\t\t\t\t\t\t\t\tor 12:33:20 AM\n\t * @return\tmixed\tExcel date/time serial value, PHP date/time serial value or PHP date/time object,\n\t *\t\t\t\t\t\tdepending on the value of the ReturnDateType flag\n\t */\n\tpublic static function TIME($hour = 0, $minute = 0, $second = 0) {\n\t\t$hour\t= PHPExcel_Calculation_Functions::flattenSingleValue($hour);\n\t\t$minute\t= PHPExcel_Calculation_Functions::flattenSingleValue($minute);\n\t\t$second\t= PHPExcel_Calculation_Functions::flattenSingleValue($second);\n\n\t\tif ($hour == '') { $hour = 0; }\n\t\tif ($minute == '') { $minute = 0; }\n\t\tif ($second == '') { $second = 0; }\n\n\t\tif ((!is_numeric($hour)) || (!is_numeric($minute)) || (!is_numeric($second))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$hour\t= (integer) $hour;\n\t\t$minute\t= (integer) $minute;\n\t\t$second\t= (integer) $second;\n\n\t\tif ($second < 0) {\n\t\t\t$minute += floor($second / 60);\n\t\t\t$second = 60 - abs($second % 60);\n\t\t\tif ($second == 60) { $second = 0; }\n\t\t} elseif ($second >= 60) {\n\t\t\t$minute += floor($second / 60);\n\t\t\t$second = $second % 60;\n\t\t}\n\t\tif ($minute < 0) {\n\t\t\t$hour += floor($minute / 60);\n\t\t\t$minute = 60 - abs($minute % 60);\n\t\t\tif ($minute == 60) { $minute = 0; }\n\t\t} elseif ($minute >= 60) {\n\t\t\t$hour += floor($minute / 60);\n\t\t\t$minute = $minute % 60;\n\t\t}\n\n\t\tif ($hour > 23) {\n\t\t\t$hour = $hour % 24;\n\t\t} elseif ($hour < 0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t// Execute function\n\t\tswitch (PHPExcel_Calculation_Functions::getReturnDateType()) {\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_EXCEL :\n\t\t\t\t\t$date = 0;\n\t\t\t\t\t$calendar = PHPExcel_Shared_Date::getExcelCalendar();\n\t\t\t\t\tif ($calendar != PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900) {\n\t\t\t\t\t\t$date = 1;\n\t\t\t\t\t}\n\t\t\t\t\treturn (float) PHPExcel_Shared_Date::FormattedPHPToExcel($calendar, 1, $date, $hour, $minute, $second);\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC :\n\t\t\t\t\treturn (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::FormattedPHPToExcel(1970, 1, 1, $hour, $minute, $second));\t// -2147468400; //\t-2147472000 + 3600\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT :\n\t\t\t\t\t$dayAdjust = 0;\n\t\t\t\t\tif ($hour < 0) {\n\t\t\t\t\t\t$dayAdjust = floor($hour / 24);\n\t\t\t\t\t\t$hour = 24 - abs($hour % 24);\n\t\t\t\t\t\tif ($hour == 24) { $hour = 0; }\n\t\t\t\t\t} elseif ($hour >= 24) {\n\t\t\t\t\t\t$dayAdjust = floor($hour / 24);\n\t\t\t\t\t\t$hour = $hour % 24;\n\t\t\t\t\t}\n\t\t\t\t\t$phpDateObject = new DateTime('1900-01-01 '.$hour.':'.$minute.':'.$second);\n\t\t\t\t\tif ($dayAdjust != 0) {\n\t\t\t\t\t\t$phpDateObject->modify($dayAdjust.' days');\n\t\t\t\t\t}\n\t\t\t\t\treturn $phpDateObject;\n\t\t}\n\t}\t//\tfunction TIME()\n\n\n\t/**\n\t * DATEVALUE\n\t *\n\t * Returns a value that represents a particular date.\n\t * Use DATEVALUE to convert a date represented by a text string to an Excel or PHP date/time stamp\n\t * value.\n\t *\n\t * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date\n\t * format of your regional settings. PHPExcel does not change cell formatting in this way.\n\t *\n\t * Excel Function:\n\t *\t\tDATEVALUE(dateValue)\n\t *\n\t * @access\tpublic\n\t * @category Date/Time Functions\n\t * @param\tstring\t$dateValue\t\tText that represents a date in a Microsoft Excel date format.\n\t *\t\t\t\t\t\t\t\t\tFor example, \"1/30/2008\" or \"30-Jan-2008\" are text strings within\n\t *\t\t\t\t\t\t\t\t\tquotation marks that represent dates. Using the default date\n\t *\t\t\t\t\t\t\t\t\tsystem in Excel for Windows, date_text must represent a date from\n\t *\t\t\t\t\t\t\t\t\tJanuary 1, 1900, to December 31, 9999. Using the default date\n\t *\t\t\t\t\t\t\t\t\tsystem in Excel for the Macintosh, date_text must represent a date\n\t *\t\t\t\t\t\t\t\t\tfrom January 1, 1904, to December 31, 9999. DATEVALUE returns the\n\t *\t\t\t\t\t\t\t\t\t#VALUE! error value if date_text is out of this range.\n\t * @return\tmixed\tExcel date/time serial value, PHP date/time serial value or PHP date/time object,\n\t *\t\t\t\t\t\tdepending on the value of the ReturnDateType flag\n\t */\n\tpublic static function DATEVALUE($dateValue = 1) {\n\t\t$dateValue = trim(PHPExcel_Calculation_Functions::flattenSingleValue($dateValue),'\"');\n\t\t//\tStrip any ordinals because they're allowed in Excel (English only)\n\t\t$dateValue = preg_replace('/(\\d)(st|nd|rd|th)([ -\\/])/Ui','$1$3',$dateValue);\n\t\t//\tConvert separators (/ . or space) to hyphens (should also handle dot used for ordinals in some countries, e.g. Denmark, Germany)\n\t\t$dateValue\t= str_replace(array('/','.','-','  '),array(' ',' ',' ',' '),$dateValue);\n\n\t\t$yearFound = false;\n\t\t$t1 = explode(' ',$dateValue);\n\t\tforeach($t1 as &$t) {\n\t\t\tif ((is_numeric($t)) && ($t > 31)) {\n\t\t\t\tif ($yearFound) {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t} else {\n\t\t\t\t\tif ($t < 100) { $t += 1900; }\n\t\t\t\t\t$yearFound = true;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ((count($t1) == 1) && (strpos($t,':') != false)) {\n\t\t\t//\tWe've been fed a time value without any date\n\t\t\treturn 0.0;\n\t\t} elseif (count($t1) == 2) {\n\t\t\t//\tWe only have two parts of the date: either day/month or month/year\n\t\t\tif ($yearFound) {\n\t\t\t\tarray_unshift($t1,1);\n\t\t\t} else {\n\t\t\t\tarray_push($t1,date('Y'));\n\t\t\t}\n\t\t}\n\t\tunset($t);\n\t\t$dateValue = implode(' ',$t1);\n\n\t\t$PHPDateArray = date_parse($dateValue);\n\t\tif (($PHPDateArray === False) || ($PHPDateArray['error_count'] > 0)) {\n\t\t\t$testVal1 = strtok($dateValue,'- ');\n\t\t\tif ($testVal1 !== False) {\n\t\t\t\t$testVal2 = strtok('- ');\n\t\t\t\tif ($testVal2 !== False) {\n\t\t\t\t\t$testVal3 = strtok('- ');\n\t\t\t\t\tif ($testVal3 === False) {\n\t\t\t\t\t\t$testVal3 = strftime('%Y');\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t\t$PHPDateArray = date_parse($testVal1.'-'.$testVal2.'-'.$testVal3);\n\t\t\tif (($PHPDateArray === False) || ($PHPDateArray['error_count'] > 0)) {\n\t\t\t\t$PHPDateArray = date_parse($testVal2.'-'.$testVal1.'-'.$testVal3);\n\t\t\t\tif (($PHPDateArray === False) || ($PHPDateArray['error_count'] > 0)) {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (($PHPDateArray !== False) && ($PHPDateArray['error_count'] == 0)) {\n\t\t\t// Execute function\n\t\t\tif ($PHPDateArray['year'] == '')\t{ $PHPDateArray['year'] = strftime('%Y'); }\n\t\t\tif ($PHPDateArray['year'] < 1900)\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\tif ($PHPDateArray['month'] == '')\t{ $PHPDateArray['month'] = strftime('%m'); }\n\t\t\tif ($PHPDateArray['day'] == '')\t\t{ $PHPDateArray['day'] = strftime('%d'); }\n\t\t\t$excelDateValue = floor(PHPExcel_Shared_Date::FormattedPHPToExcel($PHPDateArray['year'],$PHPDateArray['month'],$PHPDateArray['day'],$PHPDateArray['hour'],$PHPDateArray['minute'],$PHPDateArray['second']));\n\n\t\t\tswitch (PHPExcel_Calculation_Functions::getReturnDateType()) {\n\t\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_EXCEL :\n\t\t\t\t\t\treturn (float) $excelDateValue;\n\t\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC :\n\t\t\t\t\t\treturn (integer) PHPExcel_Shared_Date::ExcelToPHP($excelDateValue);\n\t\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT :\n\t\t\t\t\t\treturn new DateTime($PHPDateArray['year'].'-'.$PHPDateArray['month'].'-'.$PHPDateArray['day'].' 00:00:00');\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction DATEVALUE()\n\n\n\t/**\n\t * TIMEVALUE\n\t *\n\t * Returns a value that represents a particular time.\n\t * Use TIMEVALUE to convert a time represented by a text string to an Excel or PHP date/time stamp\n\t * value.\n\t *\n\t * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time\n\t * format of your regional settings. PHPExcel does not change cell formatting in this way.\n\t *\n\t * Excel Function:\n\t *\t\tTIMEVALUE(timeValue)\n\t *\n\t * @access\tpublic\n\t * @category Date/Time Functions\n\t * @param\tstring\t$timeValue\t\tA text string that represents a time in any one of the Microsoft\n\t *\t\t\t\t\t\t\t\t\tExcel time formats; for example, \"6:45 PM\" and \"18:45\" text strings\n\t *\t\t\t\t\t\t\t\t\twithin quotation marks that represent time.\n\t *\t\t\t\t\t\t\t\t\tDate information in time_text is ignored.\n\t * @return\tmixed\tExcel date/time serial value, PHP date/time serial value or PHP date/time object,\n\t *\t\t\t\t\t\tdepending on the value of the ReturnDateType flag\n\t */\n\tpublic static function TIMEVALUE($timeValue) {\n\t\t$timeValue = trim(PHPExcel_Calculation_Functions::flattenSingleValue($timeValue),'\"');\n\t\t$timeValue\t= str_replace(array('/','.'),array('-','-'),$timeValue);\n\n\t\t$PHPDateArray = date_parse($timeValue);\n\t\tif (($PHPDateArray !== False) && ($PHPDateArray['error_count'] == 0)) {\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {\n\t\t\t\t$excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel($PHPDateArray['year'],$PHPDateArray['month'],$PHPDateArray['day'],$PHPDateArray['hour'],$PHPDateArray['minute'],$PHPDateArray['second']);\n\t\t\t} else {\n\t\t\t\t$excelDateValue = PHPExcel_Shared_Date::FormattedPHPToExcel(1900,1,1,$PHPDateArray['hour'],$PHPDateArray['minute'],$PHPDateArray['second']) - 1;\n\t\t\t}\n\n\t\t\tswitch (PHPExcel_Calculation_Functions::getReturnDateType()) {\n\t\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_EXCEL :\n\t\t\t\t\t\treturn (float) $excelDateValue;\n\t\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC :\n\t\t\t\t\t\treturn (integer) $phpDateValue = PHPExcel_Shared_Date::ExcelToPHP($excelDateValue+25569) - 3600;;\n\t\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT :\n\t\t\t\t\t\treturn new DateTime('1900-01-01 '.$PHPDateArray['hour'].':'.$PHPDateArray['minute'].':'.$PHPDateArray['second']);\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction TIMEVALUE()\n\n\n\t/**\n\t * DATEDIF\n\t *\n\t * @param\tmixed\t$startDate\t\tExcel date serial value, PHP date/time stamp, PHP DateTime object\n\t *\t\t\t\t\t\t\t\t\tor a standard date string\n\t * @param\tmixed\t$endDate\t\tExcel date serial value, PHP date/time stamp, PHP DateTime object\n\t *\t\t\t\t\t\t\t\t\tor a standard date string\n\t * @param\tstring\t$unit\n\t * @return\tinteger\tInterval between the dates\n\t */\n\tpublic static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D') {\n\t\t$startDate\t= PHPExcel_Calculation_Functions::flattenSingleValue($startDate);\n\t\t$endDate\t= PHPExcel_Calculation_Functions::flattenSingleValue($endDate);\n\t\t$unit\t\t= strtoupper(PHPExcel_Calculation_Functions::flattenSingleValue($unit));\n\n\t\tif (is_string($startDate = self::_getDateValue($startDate))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\tif (is_string($endDate = self::_getDateValue($endDate))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t// Validate parameters\n\t\tif ($startDate >= $endDate) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t// Execute function\n\t\t$difference = $endDate - $startDate;\n\n\t\t$PHPStartDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($startDate);\n\t\t$startDays = $PHPStartDateObject->format('j');\n\t\t$startMonths = $PHPStartDateObject->format('n');\n\t\t$startYears = $PHPStartDateObject->format('Y');\n\n\t\t$PHPEndDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($endDate);\n\t\t$endDays = $PHPEndDateObject->format('j');\n\t\t$endMonths = $PHPEndDateObject->format('n');\n\t\t$endYears = $PHPEndDateObject->format('Y');\n\n\t\t$retVal = PHPExcel_Calculation_Functions::NaN();\n\t\tswitch ($unit) {\n\t\t\tcase 'D':\n\t\t\t\t$retVal = intval($difference);\n\t\t\t\tbreak;\n\t\t\tcase 'M':\n\t\t\t\t$retVal = intval($endMonths - $startMonths) + (intval($endYears - $startYears) * 12);\n\t\t\t\t//\tWe're only interested in full months\n\t\t\t\tif ($endDays < $startDays) {\n\t\t\t\t\t--$retVal;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'Y':\n\t\t\t\t$retVal = intval($endYears - $startYears);\n\t\t\t\t//\tWe're only interested in full months\n\t\t\t\tif ($endMonths < $startMonths) {\n\t\t\t\t\t--$retVal;\n\t\t\t\t} elseif (($endMonths == $startMonths) && ($endDays < $startDays)) {\n\t\t\t\t\t--$retVal;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'MD':\n\t\t\t\tif ($endDays < $startDays) {\n\t\t\t\t\t$retVal = $endDays;\n\t\t\t\t\t$PHPEndDateObject->modify('-'.$endDays.' days');\n\t\t\t\t\t$adjustDays = $PHPEndDateObject->format('j');\n\t\t\t\t\tif ($adjustDays > $startDays) {\n\t\t\t\t\t\t$retVal += ($adjustDays - $startDays);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t$retVal = $endDays - $startDays;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'YM':\n\t\t\t\t$retVal = intval($endMonths - $startMonths);\n\t\t\t\tif ($retVal < 0) $retVal = 12 + $retVal;\n\t\t\t\t//\tWe're only interested in full months\n\t\t\t\tif ($endDays < $startDays) {\n\t\t\t\t\t--$retVal;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tcase 'YD':\n\t\t\t\t$retVal = intval($difference);\n\t\t\t\tif ($endYears > $startYears) {\n\t\t\t\t\twhile ($endYears > $startYears) {\n\t\t\t\t\t\t$PHPEndDateObject->modify('-1 year');\n\t\t\t\t\t\t$endYears = $PHPEndDateObject->format('Y');\n\t\t\t\t\t}\n\t\t\t\t\t$retVal = $PHPEndDateObject->format('z') - $PHPStartDateObject->format('z');\n\t\t\t\t\tif ($retVal < 0) { $retVal += 365; }\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t$retVal = PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\treturn $retVal;\n\t}\t//\tfunction DATEDIF()\n\n\n\t/**\n\t * DAYS360\n\t *\n\t * Returns the number of days between two dates based on a 360-day year (twelve 30-day months),\n\t * which is used in some accounting calculations. Use this function to help compute payments if\n\t * your accounting system is based on twelve 30-day months.\n\t *\n\t * Excel Function:\n\t *\t\tDAYS360(startDate,endDate[,method])\n\t *\n\t * @access\tpublic\n\t * @category Date/Time Functions\n\t * @param\tmixed\t\t$startDate\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @param\tmixed\t\t$endDate\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @param\tboolean\t\t$method\t\t\tUS or European Method\n\t *\t\t\t\t\t\t\t\t\t\tFALSE or omitted: U.S. (NASD) method. If the starting date is\n\t *\t\t\t\t\t\t\t\t\t\tthe last day of a month, it becomes equal to the 30th of the\n\t *\t\t\t\t\t\t\t\t\t\tsame month. If the ending date is the last day of a month and\n\t *\t\t\t\t\t\t\t\t\t\tthe starting date is earlier than the 30th of a month, the\n\t *\t\t\t\t\t\t\t\t\t\tending date becomes equal to the 1st of the next month;\n\t *\t\t\t\t\t\t\t\t\t\totherwise the ending date becomes equal to the 30th of the\n\t *\t\t\t\t\t\t\t\t\t\tsame month.\n\t *\t\t\t\t\t\t\t\t\t\tTRUE: European method. Starting dates and ending dates that\n\t *\t\t\t\t\t\t\t\t\t\toccur on the 31st of a month become equal to the 30th of the\n\t *\t\t\t\t\t\t\t\t\t\tsame month.\n\t * @return\tinteger\t\tNumber of days between start date and end date\n\t */\n\tpublic static function DAYS360($startDate = 0, $endDate = 0, $method = false) {\n\t\t$startDate\t= PHPExcel_Calculation_Functions::flattenSingleValue($startDate);\n\t\t$endDate\t= PHPExcel_Calculation_Functions::flattenSingleValue($endDate);\n\n\t\tif (is_string($startDate = self::_getDateValue($startDate))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\tif (is_string($endDate = self::_getDateValue($endDate))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (!is_bool($method)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t// Execute function\n\t\t$PHPStartDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($startDate);\n\t\t$startDay = $PHPStartDateObject->format('j');\n\t\t$startMonth = $PHPStartDateObject->format('n');\n\t\t$startYear = $PHPStartDateObject->format('Y');\n\n\t\t$PHPEndDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($endDate);\n\t\t$endDay = $PHPEndDateObject->format('j');\n\t\t$endMonth = $PHPEndDateObject->format('n');\n\t\t$endYear = $PHPEndDateObject->format('Y');\n\n\t\treturn self::_dateDiff360($startDay, $startMonth, $startYear, $endDay, $endMonth, $endYear, !$method);\n\t}\t//\tfunction DAYS360()\n\n\n\t/**\n\t * YEARFRAC\n\t *\n\t * Calculates the fraction of the year represented by the number of whole days between two dates\n\t * (the start_date and the end_date).\n\t * Use the YEARFRAC worksheet function to identify the proportion of a whole year's benefits or\n\t * obligations to assign to a specific term.\n\t *\n\t * Excel Function:\n\t *\t\tYEARFRAC(startDate,endDate[,method])\n\t *\n\t * @access\tpublic\n\t * @category Date/Time Functions\n\t * @param\tmixed\t$startDate\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @param\tmixed\t$endDate\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @param\tinteger\t$method\t\t\tMethod used for the calculation\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\tfraction of the year\n\t */\n\tpublic static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) {\n\t\t$startDate\t= PHPExcel_Calculation_Functions::flattenSingleValue($startDate);\n\t\t$endDate\t= PHPExcel_Calculation_Functions::flattenSingleValue($endDate);\n\t\t$method\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($method);\n\n\t\tif (is_string($startDate = self::_getDateValue($startDate))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\tif (is_string($endDate = self::_getDateValue($endDate))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (((is_numeric($method)) && (!is_string($method))) || ($method == '')) {\n\t\t\tswitch($method) {\n\t\t\t\tcase 0\t:\n\t\t\t\t\treturn self::DAYS360($startDate,$endDate) / 360;\n\t\t\t\tcase 1\t:\n\t\t\t\t\t$days = self::DATEDIF($startDate,$endDate);\n\t\t\t\t\t$startYear = self::YEAR($startDate);\n\t\t\t\t\t$endYear = self::YEAR($endDate);\n\t\t\t\t\t$years = $endYear - $startYear + 1;\n\t\t\t\t\t$leapDays = 0;\n\t\t\t\t\tif ($years == 1) {\n\t\t\t\t\t\tif (self::_isLeapYear($endYear)) {\n\t\t\t\t\t\t\t$startMonth = self::MONTHOFYEAR($startDate);\n\t\t\t\t\t\t\t$endMonth = self::MONTHOFYEAR($endDate);\n\t\t\t\t\t\t\t$endDay = self::DAYOFMONTH($endDate);\n\t\t\t\t\t\t\tif (($startMonth < 3) ||\n\t\t\t\t\t\t\t\t(($endMonth * 100 + $endDay) >= (2 * 100 + 29))) {\n\t\t\t\t     \t\t\t$leapDays += 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tfor($year = $startYear; $year <= $endYear; ++$year) {\n\t\t\t\t\t\t\tif ($year == $startYear) {\n\t\t\t\t\t\t\t\t$startMonth = self::MONTHOFYEAR($startDate);\n\t\t\t\t\t\t\t\t$startDay = self::DAYOFMONTH($startDate);\n\t\t\t\t\t\t\t\tif ($startMonth < 3) {\n\t\t\t\t\t\t\t\t\t$leapDays += (self::_isLeapYear($year)) ? 1 : 0;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} elseif($year == $endYear) {\n\t\t\t\t\t\t\t\t$endMonth = self::MONTHOFYEAR($endDate);\n\t\t\t\t\t\t\t\t$endDay = self::DAYOFMONTH($endDate);\n\t\t\t\t\t\t\t\tif (($endMonth * 100 + $endDay) >= (2 * 100 + 29)) {\n\t\t\t\t\t\t\t\t\t$leapDays += (self::_isLeapYear($year)) ? 1 : 0;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t$leapDays += (self::_isLeapYear($year)) ? 1 : 0;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ($years == 2) {\n\t\t\t\t\t\t\tif (($leapDays == 0) && (self::_isLeapYear($startYear)) && ($days > 365)) {\n\t\t\t\t\t\t\t\t$leapDays = 1;\n\t\t\t\t\t\t\t} elseif ($days < 366) {\n\t\t\t\t\t\t\t\t$years = 1;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$leapDays /= $years;\n\t\t\t\t\t}\n\t\t\t\t\treturn $days / (365 + $leapDays);\n\t\t\t\tcase 2\t:\n\t\t\t\t\treturn self::DATEDIF($startDate,$endDate) / 360;\n\t\t\t\tcase 3\t:\n\t\t\t\t\treturn self::DATEDIF($startDate,$endDate) / 365;\n\t\t\t\tcase 4\t:\n\t\t\t\t\treturn self::DAYS360($startDate,$endDate,True) / 360;\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction YEARFRAC()\n\n\n\t/**\n\t * NETWORKDAYS\n\t *\n\t * Returns the number of whole working days between start_date and end_date. Working days\n\t * exclude weekends and any dates identified in holidays.\n\t * Use NETWORKDAYS to calculate employee benefits that accrue based on the number of days\n\t * worked during a specific term.\n\t *\n\t * Excel Function:\n\t *\t\tNETWORKDAYS(startDate,endDate[,holidays[,holiday[,...]]])\n\t *\n\t * @access\tpublic\n\t * @category Date/Time Functions\n\t * @param\tmixed\t\t\t$startDate\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @param\tmixed\t\t\t$endDate\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @param\tmixed\t\t\t$holidays,...\tOptional series of Excel date serial value (float), PHP date\n\t *\t\t\t\t\t\t\t\t\t\t\ttimestamp (integer), PHP DateTime object, or a standard date\n\t *\t\t\t\t\t\t\t\t\t\t\tstrings that will be excluded from the working calendar, such\n\t *\t\t\t\t\t\t\t\t\t\t\tas state and federal holidays and floating holidays.\n\t * @return\tinteger\t\t\tInterval between the dates\n\t */\n\tpublic static function NETWORKDAYS($startDate,$endDate) {\n\t\t//\tRetrieve the mandatory start and end date that are referenced in the function definition\n\t\t$startDate\t= PHPExcel_Calculation_Functions::flattenSingleValue($startDate);\n\t\t$endDate\t= PHPExcel_Calculation_Functions::flattenSingleValue($endDate);\n\t\t//\tFlush the mandatory start and end date that are referenced in the function definition, and get the optional days\n\t\t$dateArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\tarray_shift($dateArgs);\n\t\tarray_shift($dateArgs);\n\n\t\t//\tValidate the start and end dates\n\t\tif (is_string($startDate = $sDate = self::_getDateValue($startDate))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$startDate = (float) floor($startDate);\n\t\tif (is_string($endDate = $eDate = self::_getDateValue($endDate))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$endDate = (float) floor($endDate);\n\n\t\tif ($sDate > $eDate) {\n\t\t\t$startDate = $eDate;\n\t\t\t$endDate = $sDate;\n\t\t}\n\n\t\t// Execute function\n\t\t$startDoW = 6 - self::DAYOFWEEK($startDate,2);\n\t\tif ($startDoW < 0) { $startDoW = 0; }\n\t\t$endDoW = self::DAYOFWEEK($endDate,2);\n\t\tif ($endDoW >= 6) { $endDoW = 0; }\n\n\t\t$wholeWeekDays = floor(($endDate - $startDate) / 7) * 5;\n\t\t$partWeekDays = $endDoW + $startDoW;\n\t\tif ($partWeekDays > 5) {\n\t\t\t$partWeekDays -= 5;\n\t\t}\n\n\t\t//\tTest any extra holiday parameters\n\t\t$holidayCountedArray = array();\n\t\tforeach ($dateArgs as $holidayDate) {\n\t\t\tif (is_string($holidayDate = self::_getDateValue($holidayDate))) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t\tif (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) {\n\t\t\t\tif ((self::DAYOFWEEK($holidayDate,2) < 6) && (!in_array($holidayDate,$holidayCountedArray))) {\n\t\t\t\t\t--$partWeekDays;\n\t\t\t\t\t$holidayCountedArray[] = $holidayDate;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif ($sDate > $eDate) {\n\t\t\treturn 0 - ($wholeWeekDays + $partWeekDays);\n\t\t}\n\t\treturn $wholeWeekDays + $partWeekDays;\n\t}\t//\tfunction NETWORKDAYS()\n\n\n\t/**\n\t * WORKDAY\n\t *\n\t * Returns the date that is the indicated number of working days before or after a date (the\n\t * starting date). Working days exclude weekends and any dates identified as holidays.\n\t * Use WORKDAY to exclude weekends or holidays when you calculate invoice due dates, expected\n\t * delivery times, or the number of days of work performed.\n\t *\n\t * Excel Function:\n\t *\t\tWORKDAY(startDate,endDays[,holidays[,holiday[,...]]])\n\t *\n\t * @access\tpublic\n\t * @category Date/Time Functions\n\t * @param\tmixed\t\t$startDate\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @param\tinteger\t\t$endDays\t\tThe number of nonweekend and nonholiday days before or after\n\t *\t\t\t\t\t\t\t\t\t\tstartDate. A positive value for days yields a future date; a\n\t *\t\t\t\t\t\t\t\t\t\tnegative value yields a past date.\n\t * @param\tmixed\t\t$holidays,...\tOptional series of Excel date serial value (float), PHP date\n\t *\t\t\t\t\t\t\t\t\t\ttimestamp (integer), PHP DateTime object, or a standard date\n\t *\t\t\t\t\t\t\t\t\t\tstrings that will be excluded from the working calendar, such\n\t *\t\t\t\t\t\t\t\t\t\tas state and federal holidays and floating holidays.\n\t * @return\tmixed\tExcel date/time serial value, PHP date/time serial value or PHP date/time object,\n\t *\t\t\t\t\t\tdepending on the value of the ReturnDateType flag\n\t */\n\tpublic static function WORKDAY($startDate,$endDays) {\n\t\t//\tRetrieve the mandatory start date and days that are referenced in the function definition\n\t\t$startDate\t= PHPExcel_Calculation_Functions::flattenSingleValue($startDate);\n\t\t$endDays\t= PHPExcel_Calculation_Functions::flattenSingleValue($endDays);\n\t\t//\tFlush the mandatory start date and days that are referenced in the function definition, and get the optional days\n\t\t$dateArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\tarray_shift($dateArgs);\n\t\tarray_shift($dateArgs);\n\n\t\tif ((is_string($startDate = self::_getDateValue($startDate))) || (!is_numeric($endDays))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$startDate = (float) floor($startDate);\n\t\t$endDays = (int) floor($endDays);\n\t\t//\tIf endDays is 0, we always return startDate\n\t\tif ($endDays == 0) { return $startDate; }\n\n\t\t$decrementing = ($endDays < 0) ? True : False;\n\n\t\t//\tAdjust the start date if it falls over a weekend\n\n\t\t$startDoW = self::DAYOFWEEK($startDate,3);\n\t\tif (self::DAYOFWEEK($startDate,3) >= 5) {\n\t\t\t$startDate += ($decrementing) ? -$startDoW + 4: 7 - $startDoW;\n\t\t\t($decrementing) ? $endDays++ : $endDays--;\n\t\t}\n\n\t\t//\tAdd endDays\n\t\t$endDate = (float) $startDate + (intval($endDays / 5) * 7) + ($endDays % 5);\n\n\t\t//\tAdjust the calculated end date if it falls over a weekend\n\t\t$endDoW = self::DAYOFWEEK($endDate,3);\n\t\tif ($endDoW >= 5) {\n\t\t\t$endDate += ($decrementing) ? -$endDoW + 4: 7 - $endDoW;\n\t\t}\n\n\t\t//\tTest any extra holiday parameters\n\t\tif (!empty($dateArgs)) {\n\t\t\t$holidayCountedArray = $holidayDates = array();\n\t\t\tforeach ($dateArgs as $holidayDate) {\n\t\t\t\tif (($holidayDate !== NULL) && (trim($holidayDate) > '')) {\n\t\t\t\t\tif (is_string($holidayDate = self::_getDateValue($holidayDate))) {\n\t\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t\t}\n\t\t\t\t\tif (self::DAYOFWEEK($holidayDate,3) < 5) {\n\t\t\t\t\t\t$holidayDates[] = $holidayDate;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ($decrementing) {\n\t\t\t\trsort($holidayDates, SORT_NUMERIC);\n\t\t\t} else {\n\t\t\t\tsort($holidayDates, SORT_NUMERIC);\n\t\t\t}\n\t\t\tforeach ($holidayDates as $holidayDate) {\n\t\t\t\tif ($decrementing) {\n\t\t\t\t\tif (($holidayDate <= $startDate) && ($holidayDate >= $endDate)) {\n\t\t\t\t\t\tif (!in_array($holidayDate,$holidayCountedArray)) {\n\t\t\t\t\t\t\t--$endDate;\n\t\t\t\t\t\t\t$holidayCountedArray[] = $holidayDate;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tif (($holidayDate >= $startDate) && ($holidayDate <= $endDate)) {\n\t\t\t\t\t\tif (!in_array($holidayDate,$holidayCountedArray)) {\n\t\t\t\t\t\t\t++$endDate;\n\t\t\t\t\t\t\t$holidayCountedArray[] = $holidayDate;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//\tAdjust the calculated end date if it falls over a weekend\n\t\t\t\t$endDoW = self::DAYOFWEEK($endDate,3);\n\t\t\t\tif ($endDoW >= 5) {\n\t\t\t\t\t$endDate += ($decrementing) ? -$endDoW + 4: 7 - $endDoW;\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t\tswitch (PHPExcel_Calculation_Functions::getReturnDateType()) {\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_EXCEL :\n\t\t\t\t\treturn (float) $endDate;\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC :\n\t\t\t\t\treturn (integer) PHPExcel_Shared_Date::ExcelToPHP($endDate);\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT :\n\t\t\t\t\treturn PHPExcel_Shared_Date::ExcelToPHPObject($endDate);\n\t\t}\n\t}\t//\tfunction WORKDAY()\n\n\n\t/**\n\t * DAYOFMONTH\n\t *\n\t * Returns the day of the month, for a specified date. The day is given as an integer\n\t * ranging from 1 to 31.\n\t *\n\t * Excel Function:\n\t *\t\tDAY(dateValue)\n\t *\n\t * @param\tmixed\t$dateValue\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @return\tint\t\tDay of the month\n\t */\n\tpublic static function DAYOFMONTH($dateValue = 1) {\n\t\t$dateValue\t= PHPExcel_Calculation_Functions::flattenSingleValue($dateValue);\n\n\t\tif ($dateValue === null) {\n            $dateValue = 1;\n\t\t} elseif (is_string($dateValue = self::_getDateValue($dateValue))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t} elseif ($dateValue == 0.0) {\n\t\t\treturn 0;\n\t\t} elseif ($dateValue < 0.0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t// Execute function\n\t\t$PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue);\n\n\t\treturn (int) $PHPDateObject->format('j');\n\t}\t//\tfunction DAYOFMONTH()\n\n\n\t/**\n\t * DAYOFWEEK\n\t *\n\t * Returns the day of the week for a specified date. The day is given as an integer\n\t * ranging from 0 to 7 (dependent on the requested style).\n\t *\n\t * Excel Function:\n\t *\t\tWEEKDAY(dateValue[,style])\n\t *\n\t * @param\tmixed\t$dateValue\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @param\tint\t\t$style\t\t\tA number that determines the type of return value\n\t *\t\t\t\t\t\t\t\t\t\t1 or omitted\tNumbers 1 (Sunday) through 7 (Saturday).\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tNumbers 1 (Monday) through 7 (Sunday).\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tNumbers 0 (Monday) through 6 (Sunday).\n\t * @return\tint\t\tDay of the week value\n\t */\n\tpublic static function DAYOFWEEK($dateValue = 1, $style = 1) {\n\t\t$dateValue\t= PHPExcel_Calculation_Functions::flattenSingleValue($dateValue);\n\t\t$style\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($style);\n\n\t\tif (!is_numeric($style)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t} elseif (($style < 1) || ($style > 3)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\t$style = floor($style);\n\n\t\tif ($dateValue === null) {\n            $dateValue = 1;\n\t\t} elseif (is_string($dateValue = self::_getDateValue($dateValue))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t} elseif ($dateValue < 0.0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t// Execute function\n\t\t$PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue);\n\t\t$DoW = $PHPDateObject->format('w');\n\n\t\t$firstDay = 1;\n\t\tswitch ($style) {\n\t\t\tcase 1: ++$DoW;\n\t\t\t\t\tbreak;\n\t\t\tcase 2: if ($DoW == 0) { $DoW = 7; }\n\t\t\t\t\tbreak;\n\t\t\tcase 3: if ($DoW == 0) { $DoW = 7; }\n\t\t\t\t\t$firstDay = 0;\n\t\t\t\t\t--$DoW;\n\t\t\t\t\tbreak;\n\t\t}\n\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL) {\n\t\t\t//\tTest for Excel's 1900 leap year, and introduce the error as required\n\t\t\tif (($PHPDateObject->format('Y') == 1900) && ($PHPDateObject->format('n') <= 2)) {\n\t\t\t\t--$DoW;\n\t\t\t\tif ($DoW < $firstDay) {\n\t\t\t\t\t$DoW += 7;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn (int) $DoW;\n\t}\t//\tfunction DAYOFWEEK()\n\n\n\t/**\n\t * WEEKOFYEAR\n\t *\n\t * Returns the week of the year for a specified date.\n\t * The WEEKNUM function considers the week containing January 1 to be the first week of the year.\n\t * However, there is a European standard that defines the first week as the one with the majority\n\t * of days (four or more) falling in the new year. This means that for years in which there are\n\t * three days or less in the first week of January, the WEEKNUM function returns week numbers\n\t * that are incorrect according to the European standard.\n\t *\n\t * Excel Function:\n\t *\t\tWEEKNUM(dateValue[,style])\n\t *\n\t * @param\tmixed\t$dateValue\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @param\tboolean\t$method\t\t\tWeek begins on Sunday or Monday\n\t *\t\t\t\t\t\t\t\t\t\t1 or omitted\tWeek begins on Sunday.\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tWeek begins on Monday.\n\t * @return\tint\t\tWeek Number\n\t */\n\tpublic static function WEEKOFYEAR($dateValue = 1, $method = 1) {\n\t\t$dateValue\t= PHPExcel_Calculation_Functions::flattenSingleValue($dateValue);\n\t\t$method\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($method);\n\n\t\tif (!is_numeric($method)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t} elseif (($method < 1) || ($method > 2)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\t$method = floor($method);\n\n\t\tif ($dateValue === null) {\n            $dateValue = 1;\n\t\t} elseif (is_string($dateValue = self::_getDateValue($dateValue))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t} elseif ($dateValue < 0.0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t// Execute function\n\t\t$PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue);\n\t\t$dayOfYear = $PHPDateObject->format('z');\n\t\t$dow = $PHPDateObject->format('w');\n\t\t$PHPDateObject->modify('-'.$dayOfYear.' days');\n\t\t$dow = $PHPDateObject->format('w');\n\t\t$daysInFirstWeek = 7 - (($dow + (2 - $method)) % 7);\n\t\t$dayOfYear -= $daysInFirstWeek;\n\t\t$weekOfYear = ceil($dayOfYear / 7) + 1;\n\n\t\treturn (int) $weekOfYear;\n\t}\t//\tfunction WEEKOFYEAR()\n\n\n\t/**\n\t * MONTHOFYEAR\n\t *\n\t * Returns the month of a date represented by a serial number.\n\t * The month is given as an integer, ranging from 1 (January) to 12 (December).\n\t *\n\t * Excel Function:\n\t *\t\tMONTH(dateValue)\n\t *\n\t * @param\tmixed\t$dateValue\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @return\tint\t\tMonth of the year\n\t */\n\tpublic static function MONTHOFYEAR($dateValue = 1) {\n\t\t$dateValue\t= PHPExcel_Calculation_Functions::flattenSingleValue($dateValue);\n\n\t\tif ($dateValue === null) {\n            $dateValue = 1;\n\t\t} elseif (is_string($dateValue = self::_getDateValue($dateValue))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t} elseif ($dateValue < 0.0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t// Execute function\n\t\t$PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue);\n\n\t\treturn (int) $PHPDateObject->format('n');\n\t}\t//\tfunction MONTHOFYEAR()\n\n\n\t/**\n\t * YEAR\n\t *\n\t * Returns the year corresponding to a date.\n\t * The year is returned as an integer in the range 1900-9999.\n\t *\n\t * Excel Function:\n\t *\t\tYEAR(dateValue)\n\t *\n\t * @param\tmixed\t$dateValue\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @return\tint\t\tYear\n\t */\n\tpublic static function YEAR($dateValue = 1) {\n\t\t$dateValue\t= PHPExcel_Calculation_Functions::flattenSingleValue($dateValue);\n\n\t\tif ($dateValue === null) {\n            $dateValue = 1;\n\t\t} elseif (is_string($dateValue = self::_getDateValue($dateValue))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t} elseif ($dateValue < 0.0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t// Execute function\n\t\t$PHPDateObject = PHPExcel_Shared_Date::ExcelToPHPObject($dateValue);\n\n\t\treturn (int) $PHPDateObject->format('Y');\n\t}\t//\tfunction YEAR()\n\n\n\t/**\n\t * HOUROFDAY\n\t *\n\t * Returns the hour of a time value.\n\t * The hour is given as an integer, ranging from 0 (12:00 A.M.) to 23 (11:00 P.M.).\n\t *\n\t * Excel Function:\n\t *\t\tHOUR(timeValue)\n\t *\n\t * @param\tmixed\t$timeValue\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard time string\n\t * @return\tint\t\tHour\n\t */\n\tpublic static function HOUROFDAY($timeValue = 0) {\n\t\t$timeValue\t= PHPExcel_Calculation_Functions::flattenSingleValue($timeValue);\n\n\t\tif (!is_numeric($timeValue)) {\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {\n\t\t\t\t$testVal = strtok($timeValue,'/-: ');\n\t\t\t\tif (strlen($testVal) < strlen($timeValue)) {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t}\n\t\t\t}\n\t\t\t$timeValue = self::_getTimeValue($timeValue);\n\t\t\tif (is_string($timeValue)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t}\n\t\t// Execute function\n\t\tif ($timeValue >= 1) {\n\t\t\t$timeValue = fmod($timeValue,1);\n\t\t} elseif ($timeValue < 0.0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\t$timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue);\n\n\t\treturn (int) gmdate('G',$timeValue);\n\t}\t//\tfunction HOUROFDAY()\n\n\n\t/**\n\t * MINUTEOFHOUR\n\t *\n\t * Returns the minutes of a time value.\n\t * The minute is given as an integer, ranging from 0 to 59.\n\t *\n\t * Excel Function:\n\t *\t\tMINUTE(timeValue)\n\t *\n\t * @param\tmixed\t$timeValue\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard time string\n\t * @return\tint\t\tMinute\n\t */\n\tpublic static function MINUTEOFHOUR($timeValue = 0) {\n\t\t$timeValue = $timeTester\t= PHPExcel_Calculation_Functions::flattenSingleValue($timeValue);\n\n\t\tif (!is_numeric($timeValue)) {\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {\n\t\t\t\t$testVal = strtok($timeValue,'/-: ');\n\t\t\t\tif (strlen($testVal) < strlen($timeValue)) {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t}\n\t\t\t}\n\t\t\t$timeValue = self::_getTimeValue($timeValue);\n\t\t\tif (is_string($timeValue)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t}\n\t\t// Execute function\n\t\tif ($timeValue >= 1) {\n\t\t\t$timeValue = fmod($timeValue,1);\n\t\t} elseif ($timeValue < 0.0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\t$timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue);\n\n\t\treturn (int) gmdate('i',$timeValue);\n\t}\t//\tfunction MINUTEOFHOUR()\n\n\n\t/**\n\t * SECONDOFMINUTE\n\t *\n\t * Returns the seconds of a time value.\n\t * The second is given as an integer in the range 0 (zero) to 59.\n\t *\n\t * Excel Function:\n\t *\t\tSECOND(timeValue)\n\t *\n\t * @param\tmixed\t$timeValue\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard time string\n\t * @return\tint\t\tSecond\n\t */\n\tpublic static function SECONDOFMINUTE($timeValue = 0) {\n\t\t$timeValue\t= PHPExcel_Calculation_Functions::flattenSingleValue($timeValue);\n\n\t\tif (!is_numeric($timeValue)) {\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {\n\t\t\t\t$testVal = strtok($timeValue,'/-: ');\n\t\t\t\tif (strlen($testVal) < strlen($timeValue)) {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t}\n\t\t\t}\n\t\t\t$timeValue = self::_getTimeValue($timeValue);\n\t\t\tif (is_string($timeValue)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t}\n\t\t// Execute function\n\t\tif ($timeValue >= 1) {\n\t\t\t$timeValue = fmod($timeValue,1);\n\t\t} elseif ($timeValue < 0.0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\t$timeValue = PHPExcel_Shared_Date::ExcelToPHP($timeValue);\n\n\t\treturn (int) gmdate('s',$timeValue);\n\t}\t//\tfunction SECONDOFMINUTE()\n\n\n\t/**\n\t * EDATE\n\t *\n\t * Returns the serial number that represents the date that is the indicated number of months\n\t * before or after a specified date (the start_date).\n\t * Use EDATE to calculate maturity dates or due dates that fall on the same day of the month\n\t * as the date of issue.\n\t *\n\t * Excel Function:\n\t *\t\tEDATE(dateValue,adjustmentMonths)\n\t *\n\t * @param\tmixed\t$dateValue\t\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @param\tint\t\t$adjustmentMonths\tThe number of months before or after start_date.\n\t *\t\t\t\t\t\t\t\t\t\tA positive value for months yields a future date;\n\t *\t\t\t\t\t\t\t\t\t\ta negative value yields a past date.\n\t * @return\tmixed\tExcel date/time serial value, PHP date/time serial value or PHP date/time object,\n\t *\t\t\t\t\t\tdepending on the value of the ReturnDateType flag\n\t */\n\tpublic static function EDATE($dateValue = 1, $adjustmentMonths = 0) {\n\t\t$dateValue\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($dateValue);\n\t\t$adjustmentMonths\t= PHPExcel_Calculation_Functions::flattenSingleValue($adjustmentMonths);\n\n\t\tif (!is_numeric($adjustmentMonths)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$adjustmentMonths = floor($adjustmentMonths);\n\n\t\tif (is_string($dateValue = self::_getDateValue($dateValue))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t// Execute function\n\t\t$PHPDateObject = self::_adjustDateByMonths($dateValue,$adjustmentMonths);\n\n\t\tswitch (PHPExcel_Calculation_Functions::getReturnDateType()) {\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_EXCEL :\n\t\t\t\t\treturn (float) PHPExcel_Shared_Date::PHPToExcel($PHPDateObject);\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC :\n\t\t\t\t\treturn (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::PHPToExcel($PHPDateObject));\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT :\n\t\t\t\t\treturn $PHPDateObject;\n\t\t}\n\t}\t//\tfunction EDATE()\n\n\n\t/**\n\t * EOMONTH\n\t *\n\t * Returns the date value for the last day of the month that is the indicated number of months\n\t * before or after start_date.\n\t * Use EOMONTH to calculate maturity dates or due dates that fall on the last day of the month.\n\t *\n\t * Excel Function:\n\t *\t\tEOMONTH(dateValue,adjustmentMonths)\n\t *\n\t * @param\tmixed\t$dateValue\t\t\tExcel date serial value (float), PHP date timestamp (integer),\n\t *\t\t\t\t\t\t\t\t\t\tPHP DateTime object, or a standard date string\n\t * @param\tint\t\t$adjustmentMonths\tThe number of months before or after start_date.\n\t *\t\t\t\t\t\t\t\t\t\tA positive value for months yields a future date;\n\t *\t\t\t\t\t\t\t\t\t\ta negative value yields a past date.\n\t * @return\tmixed\tExcel date/time serial value, PHP date/time serial value or PHP date/time object,\n\t *\t\t\t\t\t\tdepending on the value of the ReturnDateType flag\n\t */\n\tpublic static function EOMONTH($dateValue = 1, $adjustmentMonths = 0) {\n\t\t$dateValue\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($dateValue);\n\t\t$adjustmentMonths\t= PHPExcel_Calculation_Functions::flattenSingleValue($adjustmentMonths);\n\n\t\tif (!is_numeric($adjustmentMonths)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$adjustmentMonths = floor($adjustmentMonths);\n\n\t\tif (is_string($dateValue = self::_getDateValue($dateValue))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t// Execute function\n\t\t$PHPDateObject = self::_adjustDateByMonths($dateValue,$adjustmentMonths+1);\n\t\t$adjustDays = (int) $PHPDateObject->format('d');\n\t\t$adjustDaysString = '-'.$adjustDays.' days';\n\t\t$PHPDateObject->modify($adjustDaysString);\n\n\t\tswitch (PHPExcel_Calculation_Functions::getReturnDateType()) {\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_EXCEL :\n\t\t\t\t\treturn (float) PHPExcel_Shared_Date::PHPToExcel($PHPDateObject);\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC :\n\t\t\t\t\treturn (integer) PHPExcel_Shared_Date::ExcelToPHP(PHPExcel_Shared_Date::PHPToExcel($PHPDateObject));\n\t\t\tcase PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT :\n\t\t\t\t\treturn $PHPDateObject;\n\t\t}\n\t}\t//\tfunction EOMONTH()\n\n}\t//\tclass PHPExcel_Calculation_DateTime\n\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Engineering.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\n/** EULER */\ndefine('EULER', 2.71828182845904523536);\n\n\n/**\n * PHPExcel_Calculation_Engineering\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_Engineering {\n\n\t/**\n\t * Details of the Units of measure that can be used in CONVERTUOM()\n\t *\n\t * @var mixed[]\n\t */\n\tprivate static $_conversionUnits = array( 'g'\t\t=> array(\t'Group'\t=> 'Mass',\t\t\t'Unit Name'\t=> 'Gram',\t\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'sg'\t\t=> array(\t'Group'\t=> 'Mass',\t\t\t'Unit Name'\t=> 'Slug',\t\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'lbm'\t\t=> array(\t'Group'\t=> 'Mass',\t\t\t'Unit Name'\t=> 'Pound mass (avoirdupois)',\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'u'\t\t=> array(\t'Group'\t=> 'Mass',\t\t\t'Unit Name'\t=> 'U (atomic mass unit)',\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'ozm'\t\t=> array(\t'Group'\t=> 'Mass',\t\t\t'Unit Name'\t=> 'Ounce mass (avoirdupois)',\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'm'\t\t=> array(\t'Group'\t=> 'Distance',\t\t'Unit Name'\t=> 'Meter',\t\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'mi'\t\t=> array(\t'Group'\t=> 'Distance',\t\t'Unit Name'\t=> 'Statute mile',\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'Nmi'\t\t=> array(\t'Group'\t=> 'Distance',\t\t'Unit Name'\t=> 'Nautical mile',\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'in'\t\t=> array(\t'Group'\t=> 'Distance',\t\t'Unit Name'\t=> 'Inch',\t\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'ft'\t\t=> array(\t'Group'\t=> 'Distance',\t\t'Unit Name'\t=> 'Foot',\t\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'yd'\t\t=> array(\t'Group'\t=> 'Distance',\t\t'Unit Name'\t=> 'Yard',\t\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'ang'\t\t=> array(\t'Group'\t=> 'Distance',\t\t'Unit Name'\t=> 'Angstrom',\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'Pica'\t=> array(\t'Group'\t=> 'Distance',\t\t'Unit Name'\t=> 'Pica (1/72 in)',\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'yr'\t\t=> array(\t'Group'\t=> 'Time',\t\t\t'Unit Name'\t=> 'Year',\t\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'day'\t\t=> array(\t'Group'\t=> 'Time',\t\t\t'Unit Name'\t=> 'Day',\t\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'hr'\t\t=> array(\t'Group'\t=> 'Time',\t\t\t'Unit Name'\t=> 'Hour',\t\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'mn'\t\t=> array(\t'Group'\t=> 'Time',\t\t\t'Unit Name'\t=> 'Minute',\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'sec'\t\t=> array(\t'Group'\t=> 'Time',\t\t\t'Unit Name'\t=> 'Second',\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'Pa'\t\t=> array(\t'Group'\t=> 'Pressure',\t\t'Unit Name'\t=> 'Pascal',\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'p'\t\t=> array(\t'Group'\t=> 'Pressure',\t\t'Unit Name'\t=> 'Pascal',\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'atm'\t\t=> array(\t'Group'\t=> 'Pressure',\t\t'Unit Name'\t=> 'Atmosphere',\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'at'\t\t=> array(\t'Group'\t=> 'Pressure',\t\t'Unit Name'\t=> 'Atmosphere',\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'mmHg'\t=> array(\t'Group'\t=> 'Pressure',\t\t'Unit Name'\t=> 'mm of Mercury',\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'N'\t\t=> array(\t'Group'\t=> 'Force',\t\t\t'Unit Name'\t=> 'Newton',\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'dyn'\t\t=> array(\t'Group'\t=> 'Force',\t\t\t'Unit Name'\t=> 'Dyne',\t\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'dy'\t\t=> array(\t'Group'\t=> 'Force',\t\t\t'Unit Name'\t=> 'Dyne',\t\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'lbf'\t\t=> array(\t'Group'\t=> 'Force',\t\t\t'Unit Name'\t=> 'Pound force',\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'J'\t\t=> array(\t'Group'\t=> 'Energy',\t\t'Unit Name'\t=> 'Joule',\t\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'e'\t\t=> array(\t'Group'\t=> 'Energy',\t\t'Unit Name'\t=> 'Erg',\t\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'c'\t\t=> array(\t'Group'\t=> 'Energy',\t\t'Unit Name'\t=> 'Thermodynamic calorie',\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'cal'\t\t=> array(\t'Group'\t=> 'Energy',\t\t'Unit Name'\t=> 'IT calorie',\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'eV'\t\t=> array(\t'Group'\t=> 'Energy',\t\t'Unit Name'\t=> 'Electron volt',\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'ev'\t\t=> array(\t'Group'\t=> 'Energy',\t\t'Unit Name'\t=> 'Electron volt',\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'HPh'\t\t=> array(\t'Group'\t=> 'Energy',\t\t'Unit Name'\t=> 'Horsepower-hour',\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'hh'\t\t=> array(\t'Group'\t=> 'Energy',\t\t'Unit Name'\t=> 'Horsepower-hour',\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'Wh'\t\t=> array(\t'Group'\t=> 'Energy',\t\t'Unit Name'\t=> 'Watt-hour',\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'wh'\t\t=> array(\t'Group'\t=> 'Energy',\t\t'Unit Name'\t=> 'Watt-hour',\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'flb'\t\t=> array(\t'Group'\t=> 'Energy',\t\t'Unit Name'\t=> 'Foot-pound',\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'BTU'\t\t=> array(\t'Group'\t=> 'Energy',\t\t'Unit Name'\t=> 'BTU',\t\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'btu'\t\t=> array(\t'Group'\t=> 'Energy',\t\t'Unit Name'\t=> 'BTU',\t\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'HP'\t\t=> array(\t'Group'\t=> 'Power',\t\t\t'Unit Name'\t=> 'Horsepower',\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'h'\t\t=> array(\t'Group'\t=> 'Power',\t\t\t'Unit Name'\t=> 'Horsepower',\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'W'\t\t=> array(\t'Group'\t=> 'Power',\t\t\t'Unit Name'\t=> 'Watt',\t\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'w'\t\t=> array(\t'Group'\t=> 'Power',\t\t\t'Unit Name'\t=> 'Watt',\t\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'T'\t\t=> array(\t'Group'\t=> 'Magnetism',\t\t'Unit Name'\t=> 'Tesla',\t\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'ga'\t\t=> array(\t'Group'\t=> 'Magnetism',\t\t'Unit Name'\t=> 'Gauss',\t\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'C'\t\t=> array(\t'Group'\t=> 'Temperature',\t'Unit Name'\t=> 'Celsius',\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'cel'\t\t=> array(\t'Group'\t=> 'Temperature',\t'Unit Name'\t=> 'Celsius',\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'F'\t\t=> array(\t'Group'\t=> 'Temperature',\t'Unit Name'\t=> 'Fahrenheit',\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'fah'\t\t=> array(\t'Group'\t=> 'Temperature',\t'Unit Name'\t=> 'Fahrenheit',\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'K'\t\t=> array(\t'Group'\t=> 'Temperature',\t'Unit Name'\t=> 'Kelvin',\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'kel'\t\t=> array(\t'Group'\t=> 'Temperature',\t'Unit Name'\t=> 'Kelvin',\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'tsp'\t\t=> array(\t'Group'\t=> 'Liquid',\t\t'Unit Name'\t=> 'Teaspoon',\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'tbs'\t\t=> array(\t'Group'\t=> 'Liquid',\t\t'Unit Name'\t=> 'Tablespoon',\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'oz'\t\t=> array(\t'Group'\t=> 'Liquid',\t\t'Unit Name'\t=> 'Fluid Ounce',\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'cup'\t\t=> array(\t'Group'\t=> 'Liquid',\t\t'Unit Name'\t=> 'Cup',\t\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'pt'\t\t=> array(\t'Group'\t=> 'Liquid',\t\t'Unit Name'\t=> 'U.S. Pint',\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'us_pt'\t=> array(\t'Group'\t=> 'Liquid',\t\t'Unit Name'\t=> 'U.S. Pint',\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'uk_pt'\t=> array(\t'Group'\t=> 'Liquid',\t\t'Unit Name'\t=> 'U.K. Pint',\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'qt'\t\t=> array(\t'Group'\t=> 'Liquid',\t\t'Unit Name'\t=> 'Quart',\t\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'gal'\t\t=> array(\t'Group'\t=> 'Liquid',\t\t'Unit Name'\t=> 'Gallon',\t\t\t\t\t'AllowPrefix'\t=> False\t),\n\t\t\t\t\t\t\t\t\t\t\t  'l'\t\t=> array(\t'Group'\t=> 'Liquid',\t\t'Unit Name'\t=> 'Litre',\t\t\t\t\t\t'AllowPrefix'\t=> True\t\t),\n\t\t\t\t\t\t\t\t\t\t\t  'lt'\t\t=> array(\t'Group'\t=> 'Liquid',\t\t'Unit Name'\t=> 'Litre',\t\t\t\t\t\t'AllowPrefix'\t=> True\t\t)\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t/**\n\t * Details of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM()\n\t *\n\t * @var mixed[]\n\t */\n\tprivate static $_conversionMultipliers = array(\t'Y'\t=> array(\t'multiplier'\t=> 1E24,\t'name'\t=> 'yotta'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'Z'\t=> array(\t'multiplier'\t=> 1E21,\t'name'\t=> 'zetta'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'E'\t=> array(\t'multiplier'\t=> 1E18,\t'name'\t=> 'exa'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'P'\t=> array(\t'multiplier'\t=> 1E15,\t'name'\t=> 'peta'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'T'\t=> array(\t'multiplier'\t=> 1E12,\t'name'\t=> 'tera'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'G'\t=> array(\t'multiplier'\t=> 1E9,\t\t'name'\t=> 'giga'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'M'\t=> array(\t'multiplier'\t=> 1E6,\t\t'name'\t=> 'mega'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'k'\t=> array(\t'multiplier'\t=> 1E3,\t\t'name'\t=> 'kilo'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'h'\t=> array(\t'multiplier'\t=> 1E2,\t\t'name'\t=> 'hecto'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t=> array(\t'multiplier'\t=> 1E1,\t\t'name'\t=> 'deka'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'd'\t=> array(\t'multiplier'\t=> 1E-1,\t'name'\t=> 'deci'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t=> array(\t'multiplier'\t=> 1E-2,\t'name'\t=> 'centi'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'm'\t=> array(\t'multiplier'\t=> 1E-3,\t'name'\t=> 'milli'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'u'\t=> array(\t'multiplier'\t=> 1E-6,\t'name'\t=> 'micro'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'n'\t=> array(\t'multiplier'\t=> 1E-9,\t'name'\t=> 'nano'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'p'\t=> array(\t'multiplier'\t=> 1E-12,\t'name'\t=> 'pico'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'f'\t=> array(\t'multiplier'\t=> 1E-15,\t'name'\t=> 'femto'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'a'\t=> array(\t'multiplier'\t=> 1E-18,\t'name'\t=> 'atto'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'z'\t=> array(\t'multiplier'\t=> 1E-21,\t'name'\t=> 'zepto'\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t'y'\t=> array(\t'multiplier'\t=> 1E-24,\t'name'\t=> 'yocto'\t)\n\t\t\t\t\t\t\t\t\t\t\t\t );\n\n\t/**\n\t * Details of the Units of measure conversion factors, organised by group\n\t *\n\t * @var mixed[]\n\t */\n\tprivate static $_unitConversions = array(\t'Mass'\t\t=> array(\t'g'\t\t=> array(\t'g'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'sg'\t=> 6.85220500053478E-05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lbm'\t=> 2.20462291469134E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'u'\t\t=> 6.02217000000000E+23,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ozm'\t=> 3.52739718003627E-02\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'sg'\t=> array(\t'g'\t\t=> 1.45938424189287E+04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'sg'\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lbm'\t=> 3.21739194101647E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'u'\t\t=> 8.78866000000000E+27,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ozm'\t=> 5.14782785944229E+02\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lbm'\t=> array(\t'g'\t\t=> 4.5359230974881148E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'sg'\t=> 3.10810749306493E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lbm'\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'u'\t\t=> 2.73161000000000E+26,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ozm'\t=> 1.60000023429410E+01\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'u'\t\t=> array(\t'g'\t\t=> 1.66053100460465E-24,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'sg'\t=> 1.13782988532950E-28,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lbm'\t=> 3.66084470330684E-27,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'u'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ozm'\t=> 5.85735238300524E-26\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ozm'\t=> array(\t'g'\t\t=> 2.83495152079732E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'sg'\t=> 1.94256689870811E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lbm'\t=> 6.24999908478882E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'u'\t\t=> 1.70725600000000E+25,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ozm'\t=> 1.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t'Distance'\t=> array(\t'm'\t\t=> array(\t'm'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mi'\t=> 6.21371192237334E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Nmi'\t=> 5.39956803455724E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'in'\t=> 3.93700787401575E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ft'\t=> 3.28083989501312E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'yd'\t=> 1.09361329797891E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ang'\t=> 1.00000000000000E+10,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Pica'\t=> 2.83464566929116E+03\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mi'\t=> array(\t'm'\t\t=> 1.60934400000000E+03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mi'\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Nmi'\t=> 8.68976241900648E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'in'\t=> 6.33600000000000E+04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ft'\t=> 5.28000000000000E+03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'yd'\t=> 1.76000000000000E+03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ang'\t=> 1.60934400000000E+13,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Pica'\t=> 4.56191999999971E+06\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Nmi'\t=> array(\t'm'\t\t=> 1.85200000000000E+03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mi'\t=> 1.15077944802354E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Nmi'\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'in'\t=> 7.29133858267717E+04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ft'\t=> 6.07611548556430E+03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'yd'\t=> 2.02537182785694E+03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ang'\t=> 1.85200000000000E+13,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Pica'\t=> 5.24976377952723E+06\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'in'\t=> array(\t'm'\t\t=> 2.54000000000000E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mi'\t=> 1.57828282828283E-05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Nmi'\t=> 1.37149028077754E-05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'in'\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ft'\t=> 8.33333333333333E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'yd'\t=> 2.77777777686643E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ang'\t=> 2.54000000000000E+08,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Pica'\t=> 7.19999999999955E+01\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ft'\t=> array(\t'm'\t\t=> 3.04800000000000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mi'\t=> 1.89393939393939E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Nmi'\t=> 1.64578833693305E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'in'\t=> 1.20000000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ft'\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'yd'\t=> 3.33333333223972E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ang'\t=> 3.04800000000000E+09,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Pica'\t=> 8.63999999999946E+02\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'yd'\t=> array(\t'm'\t\t=> 9.14400000300000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mi'\t=> 5.68181818368230E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Nmi'\t=> 4.93736501241901E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'in'\t=> 3.60000000118110E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ft'\t=> 3.00000000000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'yd'\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ang'\t=> 9.14400000300000E+09,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Pica'\t=> 2.59200000085023E+03\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ang'\t=> array(\t'm'\t\t=> 1.00000000000000E-10,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mi'\t=> 6.21371192237334E-14,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Nmi'\t=> 5.39956803455724E-14,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'in'\t=> 3.93700787401575E-09,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ft'\t=> 3.28083989501312E-10,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'yd'\t=> 1.09361329797891E-10,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ang'\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Pica'\t=> 2.83464566929116E-07\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Pica'\t=> array(\t'm'\t\t=> 3.52777777777800E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mi'\t=> 2.19205948372629E-07,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Nmi'\t=> 1.90484761219114E-07,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'in'\t=> 1.38888888888898E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ft'\t=> 1.15740740740748E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'yd'\t=> 3.85802469009251E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ang'\t=> 3.52777777777800E+06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Pica'\t=> 1.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t'Time'\t\t=> array(\t'yr'\t=> array(\t'yr'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'day'\t\t=> 365.25,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hr'\t\t=> 8766.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mn'\t\t=> 525960.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'sec'\t\t=> 31557600.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'day'\t=> array(\t'yr'\t\t=> 2.73785078713210E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'day'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hr'\t\t=> 24.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mn'\t\t=> 1440.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'sec'\t\t=> 86400.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hr'\t=> array(\t'yr'\t\t=> 1.14077116130504E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'day'\t\t=> 4.16666666666667E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hr'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mn'\t\t=> 60.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'sec'\t\t=> 3600.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mn'\t=> array(\t'yr'\t\t=> 1.90128526884174E-06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'day'\t\t=> 6.94444444444444E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hr'\t\t=> 1.66666666666667E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mn'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'sec'\t\t=> 60.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'sec'\t=> array(\t'yr'\t\t=> 3.16880878140289E-08,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'day'\t\t=> 1.15740740740741E-05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hr'\t\t=> 2.77777777777778E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mn'\t\t=> 1.66666666666667E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'sec'\t\t=> 1.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t'Pressure'\t=> array(\t'Pa'\t=> array(\t'Pa'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'p'\t\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'atm'\t\t=> 9.86923299998193E-06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'at'\t\t=> 9.86923299998193E-06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mmHg'\t\t=> 7.50061707998627E-03\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'p'\t\t=> array(\t'Pa'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'p'\t\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'atm'\t\t=> 9.86923299998193E-06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'at'\t\t=> 9.86923299998193E-06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mmHg'\t\t=> 7.50061707998627E-03\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'atm'\t=> array(\t'Pa'\t\t=> 1.01324996583000E+05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'p'\t\t\t=> 1.01324996583000E+05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'atm'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'at'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mmHg'\t\t=> 760.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'at'\t=> array(\t'Pa'\t\t=> 1.01324996583000E+05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'p'\t\t\t=> 1.01324996583000E+05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'atm'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'at'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mmHg'\t\t=> 760.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mmHg'\t=> array(\t'Pa'\t\t=> 1.33322363925000E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'p'\t\t\t=> 1.33322363925000E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'atm'\t\t=> 1.31578947368421E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'at'\t\t=> 1.31578947368421E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'mmHg'\t\t=> 1.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t'Force'\t\t=> array(\t'N'\t\t=> array(\t'N'\t\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'dyn'\t\t=> 1.0E+5,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'dy'\t\t=> 1.0E+5,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lbf'\t\t=> 2.24808923655339E-01\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'dyn'\t=> array(\t'N'\t\t\t=> 1.0E-5,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'dyn'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'dy'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lbf'\t\t=> 2.24808923655339E-06\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'dy'\t=> array(\t'N'\t\t\t=> 1.0E-5,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'dyn'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'dy'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lbf'\t\t=> 2.24808923655339E-06\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lbf'\t=> array(\t'N'\t\t\t=> 4.448222,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'dyn'\t\t=> 4.448222E+5,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'dy'\t\t=> 4.448222E+5,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lbf'\t\t=> 1.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t'Energy'\t=> array(\t'J'\t\t=> array(\t'J'\t\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t\t=> 9.99999519343231E+06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t\t=> 2.39006249473467E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t\t=> 2.38846190642017E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t\t=> 6.24145700000000E+18,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t\t=> 6.24145700000000E+18,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t\t=> 3.72506430801000E-07,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t\t=> 3.72506430801000E-07,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t\t=> 2.77777916238711E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t\t=> 2.77777916238711E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t\t=> 2.37304222192651E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t\t=> 9.47815067349015E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t\t=> 9.47815067349015E-04\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t=> array(\t'J'\t\t\t=> 1.00000048065700E-07,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t\t=> 2.39006364353494E-08,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t\t=> 2.38846305445111E-08,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t\t=> 6.24146000000000E+11,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t\t=> 6.24146000000000E+11,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t\t=> 3.72506609848824E-14,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t\t=> 3.72506609848824E-14,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t\t=> 2.77778049754611E-11,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t\t=> 2.77778049754611E-11,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t\t=> 2.37304336254586E-06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t\t=> 9.47815522922962E-11,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t\t=> 9.47815522922962E-11\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t=> array(\t'J'\t\t\t=> 4.18399101363672E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t\t=> 4.18398900257312E+07,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t\t=> 9.99330315287563E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t\t=> 2.61142000000000E+19,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t\t=> 2.61142000000000E+19,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t\t=> 1.55856355899327E-06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t\t=> 1.55856355899327E-06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t\t=> 1.16222030532950E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t\t=> 1.16222030532950E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t\t=> 9.92878733152102E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t\t=> 3.96564972437776E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t\t=> 3.96564972437776E-03\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t=> array(\t'J'\t\t\t=> 4.18679484613929E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t\t=> 4.18679283372801E+07,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t\t=> 1.00067013349059E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t\t=> 2.61317000000000E+19,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t\t=> 2.61317000000000E+19,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t\t=> 1.55960800463137E-06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t\t=> 1.55960800463137E-06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t\t=> 1.16299914807955E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t\t=> 1.16299914807955E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t\t=> 9.93544094443283E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t\t=> 3.96830723907002E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t\t=> 3.96830723907002E-03\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t=> array(\t'J'\t\t\t=> 1.60219000146921E-19,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t\t=> 1.60218923136574E-12,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t\t=> 3.82933423195043E-20,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t\t=> 3.82676978535648E-20,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t\t=> 5.96826078912344E-26,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t\t=> 5.96826078912344E-26,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t\t=> 4.45053000026614E-23,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t\t=> 4.45053000026614E-23,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t\t=> 3.80206452103492E-18,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t\t=> 1.51857982414846E-22,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t\t=> 1.51857982414846E-22\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t=> array(\t'J'\t\t\t=> 1.60219000146921E-19,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t\t=> 1.60218923136574E-12,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t\t=> 3.82933423195043E-20,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t\t=> 3.82676978535648E-20,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t\t=> 5.96826078912344E-26,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t\t=> 5.96826078912344E-26,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t\t=> 4.45053000026614E-23,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t\t=> 4.45053000026614E-23,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t\t=> 3.80206452103492E-18,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t\t=> 1.51857982414846E-22,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t\t=> 1.51857982414846E-22\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t=> array(\t'J'\t\t\t=> 2.68451741316170E+06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t\t=> 2.68451612283024E+13,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t\t=> 6.41616438565991E+05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t\t=> 6.41186757845835E+05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t\t=> 1.67553000000000E+25,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t\t=> 1.67553000000000E+25,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t\t=> 7.45699653134593E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t\t=> 7.45699653134593E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t\t=> 6.37047316692964E+07,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t\t=> 2.54442605275546E+03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t\t=> 2.54442605275546E+03\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t=> array(\t'J'\t\t\t=> 2.68451741316170E+06,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t\t=> 2.68451612283024E+13,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t\t=> 6.41616438565991E+05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t\t=> 6.41186757845835E+05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t\t=> 1.67553000000000E+25,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t\t=> 1.67553000000000E+25,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t\t=> 7.45699653134593E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t\t=> 7.45699653134593E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t\t=> 6.37047316692964E+07,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t\t=> 2.54442605275546E+03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t\t=> 2.54442605275546E+03\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t=> array(\t'J'\t\t\t=> 3.59999820554720E+03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t\t=> 3.59999647518369E+10,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t\t=> 8.60422069219046E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t\t=> 8.59845857713046E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t\t=> 2.24692340000000E+22,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t\t=> 2.24692340000000E+22,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t\t=> 1.34102248243839E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t\t=> 1.34102248243839E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t\t=> 8.54294774062316E+04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t\t=> 3.41213254164705E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t\t=> 3.41213254164705E+00\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t=> array(\t'J'\t\t\t=> 3.59999820554720E+03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t\t=> 3.59999647518369E+10,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t\t=> 8.60422069219046E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t\t=> 8.59845857713046E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t\t=> 2.24692340000000E+22,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t\t=> 2.24692340000000E+22,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t\t=> 1.34102248243839E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t\t=> 1.34102248243839E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t\t=> 8.54294774062316E+04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t\t=> 3.41213254164705E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t\t=> 3.41213254164705E+00\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t=> array(\t'J'\t\t\t=> 4.21400003236424E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t\t=> 4.21399800687660E+05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t\t=> 1.00717234301644E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t\t=> 1.00649785509554E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t\t=> 2.63015000000000E+17,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t\t=> 2.63015000000000E+17,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t\t=> 1.56974211145130E-08,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t\t=> 1.56974211145130E-08,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t\t=> 1.17055614802000E-05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t\t=> 1.17055614802000E-05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t\t=> 3.99409272448406E-05,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t\t=> 3.99409272448406E-05\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t=> array(\t'J'\t\t\t=> 1.05505813786749E+03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t\t=> 1.05505763074665E+10,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t\t=> 2.52165488508168E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t\t=> 2.51996617135510E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t\t=> 6.58510000000000E+21,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t\t=> 6.58510000000000E+21,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t\t=> 3.93015941224568E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t\t=> 3.93015941224568E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t\t=> 2.93071851047526E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t\t=> 2.93071851047526E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t\t=> 2.50369750774671E+04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t=> array(\t'J'\t\t\t=> 1.05505813786749E+03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'e'\t\t\t=> 1.05505763074665E+10,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'c'\t\t\t=> 2.52165488508168E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cal'\t\t=> 2.51996617135510E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'eV'\t\t=> 6.58510000000000E+21,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ev'\t\t=> 6.58510000000000E+21,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'HPh'\t\t=> 3.93015941224568E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'hh'\t\t=> 3.93015941224568E-04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'Wh'\t\t=> 2.93071851047526E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'wh'\t\t=> 2.93071851047526E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'flb'\t\t=> 2.50369750774671E+04,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'BTU'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'btu'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t'Power'\t\t=> array(\t'HP'\t=> array(\t'HP'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'h'\t\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'W'\t\t\t=> 7.45701000000000E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'w'\t\t\t=> 7.45701000000000E+02\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'h'\t\t=> array(\t'HP'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'h'\t\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'W'\t\t\t=> 7.45701000000000E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'w'\t\t\t=> 7.45701000000000E+02\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'W'\t\t=> array(\t'HP'\t\t=> 1.34102006031908E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'h'\t\t\t=> 1.34102006031908E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'W'\t\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'w'\t\t\t=> 1.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'w'\t\t=> array(\t'HP'\t\t=> 1.34102006031908E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'h'\t\t\t=> 1.34102006031908E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'W'\t\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'w'\t\t\t=> 1.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t'Magnetism'\t=> array(\t'T'\t\t=> array(\t'T'\t\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ga'\t\t=> 10000.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ga'\t=> array(\t'T'\t\t\t=> 0.0001,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'ga'\t\t=> 1.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t'Liquid'\t=> array(\t'tsp'\t=> array(\t'tsp'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'tbs'\t\t=> 3.33333333333333E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'oz'\t\t=> 1.66666666666667E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cup'\t\t=> 2.08333333333333E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'pt'\t\t=> 1.04166666666667E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'us_pt'\t\t=> 1.04166666666667E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'uk_pt'\t\t=> 8.67558516821960E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'qt'\t\t=> 5.20833333333333E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'gal'\t\t=> 1.30208333333333E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'l'\t\t\t=> 4.92999408400710E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lt'\t\t=> 4.92999408400710E-03\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'tbs'\t=> array(\t'tsp'\t\t=> 3.00000000000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'tbs'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'oz'\t\t=> 5.00000000000000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cup'\t\t=> 6.25000000000000E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'pt'\t\t=> 3.12500000000000E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'us_pt'\t\t=> 3.12500000000000E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'uk_pt'\t\t=> 2.60267555046588E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'qt'\t\t=> 1.56250000000000E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'gal'\t\t=> 3.90625000000000E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'l'\t\t\t=> 1.47899822520213E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lt'\t\t=> 1.47899822520213E-02\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'oz'\t=> array(\t'tsp'\t\t=> 6.00000000000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'tbs'\t\t=> 2.00000000000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'oz'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cup'\t\t=> 1.25000000000000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'pt'\t\t=> 6.25000000000000E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'us_pt'\t\t=> 6.25000000000000E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'uk_pt'\t\t=> 5.20535110093176E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'qt'\t\t=> 3.12500000000000E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'gal'\t\t=> 7.81250000000000E-03,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'l'\t\t\t=> 2.95799645040426E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lt'\t\t=> 2.95799645040426E-02\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cup'\t=> array(\t'tsp'\t\t=> 4.80000000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'tbs'\t\t=> 1.60000000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'oz'\t\t=> 8.00000000000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cup'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'pt'\t\t=> 5.00000000000000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'us_pt'\t\t=> 5.00000000000000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'uk_pt'\t\t=> 4.16428088074541E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'qt'\t\t=> 2.50000000000000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'gal'\t\t=> 6.25000000000000E-02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'l'\t\t\t=> 2.36639716032341E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lt'\t\t=> 2.36639716032341E-01\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'pt'\t=> array(\t'tsp'\t\t=> 9.60000000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'tbs'\t\t=> 3.20000000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'oz'\t\t=> 1.60000000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cup'\t\t=> 2.00000000000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'pt'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'us_pt'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'uk_pt'\t\t=> 8.32856176149081E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'qt'\t\t=> 5.00000000000000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'gal'\t\t=> 1.25000000000000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'l'\t\t\t=> 4.73279432064682E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lt'\t\t=> 4.73279432064682E-01\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'us_pt'\t=> array(\t'tsp'\t\t=> 9.60000000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'tbs'\t\t=> 3.20000000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'oz'\t\t=> 1.60000000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cup'\t\t=> 2.00000000000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'pt'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'us_pt'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'uk_pt'\t\t=> 8.32856176149081E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'qt'\t\t=> 5.00000000000000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'gal'\t\t=> 1.25000000000000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'l'\t\t\t=> 4.73279432064682E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lt'\t\t=> 4.73279432064682E-01\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'uk_pt'\t=> array(\t'tsp'\t\t=> 1.15266000000000E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'tbs'\t\t=> 3.84220000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'oz'\t\t=> 1.92110000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cup'\t\t=> 2.40137500000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'pt'\t\t=> 1.20068750000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'us_pt'\t\t=> 1.20068750000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'uk_pt'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'qt'\t\t=> 6.00343750000000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'gal'\t\t=> 1.50085937500000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'l'\t\t\t=> 5.68260698087162E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lt'\t\t=> 5.68260698087162E-01\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'qt'\t=> array(\t'tsp'\t\t=> 1.92000000000000E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'tbs'\t\t=> 6.40000000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'oz'\t\t=> 3.20000000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cup'\t\t=> 4.00000000000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'pt'\t\t=> 2.00000000000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'us_pt'\t\t=> 2.00000000000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'uk_pt'\t\t=> 1.66571235229816E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'qt'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'gal'\t\t=> 2.50000000000000E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'l'\t\t\t=> 9.46558864129363E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lt'\t\t=> 9.46558864129363E-01\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'gal'\t=> array(\t'tsp'\t\t=> 7.68000000000000E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'tbs'\t\t=> 2.56000000000000E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'oz'\t\t=> 1.28000000000000E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cup'\t\t=> 1.60000000000000E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'pt'\t\t=> 8.00000000000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'us_pt'\t\t=> 8.00000000000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'uk_pt'\t\t=> 6.66284940919265E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'qt'\t\t=> 4.00000000000000E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'gal'\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'l'\t\t\t=> 3.78623545651745E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lt'\t\t=> 3.78623545651745E+00\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'l'\t\t=> array(\t'tsp'\t\t=> 2.02840000000000E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'tbs'\t\t=> 6.76133333333333E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'oz'\t\t=> 3.38066666666667E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cup'\t\t=> 4.22583333333333E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'pt'\t\t=> 2.11291666666667E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'us_pt'\t\t=> 2.11291666666667E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'uk_pt'\t\t=> 1.75975569552166E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'qt'\t\t=> 1.05645833333333E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'gal'\t\t=> 2.64114583333333E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'l'\t\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lt'\t\t=> 1.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lt'\t=> array(\t'tsp'\t\t=> 2.02840000000000E+02,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'tbs'\t\t=> 6.76133333333333E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'oz'\t\t=> 3.38066666666667E+01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'cup'\t\t=> 4.22583333333333E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'pt'\t\t=> 2.11291666666667E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'us_pt'\t\t=> 2.11291666666667E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'uk_pt'\t\t=> 1.75975569552166E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'qt'\t\t=> 1.05645833333333E+00,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'gal'\t\t=> 2.64114583333333E-01,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'l'\t\t\t=> 1.0,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'lt'\t\t=> 1.0\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\n\t/**\n\t * _parseComplex\n\t *\n\t * Parses a complex number into its real and imaginary parts, and an I or J suffix\n\t *\n\t * @param\tstring\t\t$complexNumber\tThe complex number\n\t * @return\tstring[]\tIndexed on \"real\", \"imaginary\" and \"suffix\"\n\t */\n\tpublic static function _parseComplex($complexNumber) {\n\t\t$workString = (string) $complexNumber;\n\n\t\t$realNumber = $imaginary = 0;\n\t\t//\tExtract the suffix, if there is one\n\t\t$suffix = substr($workString,-1);\n\t\tif (!is_numeric($suffix)) {\n\t\t\t$workString = substr($workString,0,-1);\n\t\t} else {\n\t\t\t$suffix = '';\n\t\t}\n\n\t\t//\tSplit the input into its Real and Imaginary components\n\t\t$leadingSign = 0;\n\t\tif (strlen($workString) > 0) {\n\t\t\t$leadingSign = (($workString{0} == '+') || ($workString{0} == '-')) ? 1 : 0;\n\t\t}\n\t\t$power = '';\n\t\t$realNumber = strtok($workString, '+-');\n\t\tif (strtoupper(substr($realNumber,-1)) == 'E') {\n\t\t\t$power = strtok('+-');\n\t\t\t++$leadingSign;\n\t\t}\n\n\t\t$realNumber = substr($workString,0,strlen($realNumber)+strlen($power)+$leadingSign);\n\n\t\tif ($suffix != '') {\n\t\t\t$imaginary = substr($workString,strlen($realNumber));\n\n\t\t\tif (($imaginary == '') && (($realNumber == '') || ($realNumber == '+') || ($realNumber == '-'))) {\n\t\t\t\t$imaginary = $realNumber.'1';\n\t\t\t\t$realNumber = '0';\n\t\t\t} else if ($imaginary == '') {\n\t\t\t\t$imaginary = $realNumber;\n\t\t\t\t$realNumber = '0';\n\t\t\t} elseif (($imaginary == '+') || ($imaginary == '-')) {\n\t\t\t\t$imaginary .= '1';\n\t\t\t}\n\t\t}\n\n\t\treturn array( 'real'\t\t=> $realNumber,\n\t\t\t\t\t  'imaginary'\t=> $imaginary,\n\t\t\t\t\t  'suffix'\t\t=> $suffix\n\t\t\t\t\t);\n\t}\t//\tfunction _parseComplex()\n\n\n\t/**\n\t * Cleans the leading characters in a complex number string\n\t *\n\t * @param\tstring\t\t$complexNumber\tThe complex number to clean\n\t * @return\tstring\t\tThe \"cleaned\" complex number\n\t */\n\tprivate static function _cleanComplex($complexNumber) {\n\t\tif ($complexNumber{0} == '+') $complexNumber = substr($complexNumber,1);\n\t\tif ($complexNumber{0} == '0') $complexNumber = substr($complexNumber,1);\n\t\tif ($complexNumber{0} == '.') $complexNumber = '0'.$complexNumber;\n\t\tif ($complexNumber{0} == '+') $complexNumber = substr($complexNumber,1);\n\t\treturn $complexNumber;\n\t}\n\n\t/**\n\t * Formats a number base string value with leading zeroes\n\t *\n\t * @param\tstring\t\t$xVal\t\tThe \"number\" to pad\n\t * @param\tinteger\t\t$places\t\tThe length that we want to pad this value\n\t * @return\tstring\t\tThe padded \"number\"\n\t */\n\tprivate static function _nbrConversionFormat($xVal, $places) {\n\t\tif (!is_null($places)) {\n\t\t\tif (strlen($xVal) <= $places) {\n\t\t\t\treturn substr(str_pad($xVal, $places, '0', STR_PAD_LEFT), -10);\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t}\n\n\t\treturn substr($xVal, -10);\n\t}\t//\tfunction _nbrConversionFormat()\n\n\t/**\n\t *\tBESSELI\n\t *\n\t *\tReturns the modified Bessel function In(x), which is equivalent to the Bessel function evaluated\n\t *\t\tfor purely imaginary arguments\n\t *\n\t *\tExcel Function:\n\t *\t\tBESSELI(x,ord)\n\t *\n\t *\t@access\tpublic\n\t *\t@category Engineering Functions\n\t *\t@param\tfloat\t\t$x\t\tThe value at which to evaluate the function.\n\t *\t\t\t\t\t\t\t\tIf x is nonnumeric, BESSELI returns the #VALUE! error value.\n\t *\t@param\tinteger\t\t$ord\tThe order of the Bessel function.\n\t *\t\t\t\t\t\t\t\tIf ord is not an integer, it is truncated.\n\t *\t\t\t\t\t\t\t\tIf $ord is nonnumeric, BESSELI returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\tIf $ord < 0, BESSELI returns the #NUM! error value.\n\t *\t@return\tfloat\n\t *\n\t */\n\tpublic static function BESSELI($x, $ord) {\n\t\t$x\t= (is_null($x))\t? 0.0 :\tPHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$ord\t= (is_null($ord))\t? 0.0 :\tPHPExcel_Calculation_Functions::flattenSingleValue($ord);\n\n\t\tif ((is_numeric($x)) && (is_numeric($ord))) {\n\t\t\t$ord\t= floor($ord);\n\t\t\tif ($ord < 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\n\t\t\tif (abs($x) <= 30) {\n\t\t\t\t$fResult = $fTerm = pow($x / 2, $ord) / PHPExcel_Calculation_MathTrig::FACT($ord);\n\t\t\t\t$ordK = 1;\n\t\t\t\t$fSqrX = ($x * $x) / 4;\n\t\t\t\tdo {\n\t\t\t\t\t$fTerm *= $fSqrX;\n\t\t\t\t\t$fTerm /= ($ordK * ($ordK + $ord));\n\t\t\t\t\t$fResult += $fTerm;\n\t\t\t\t} while ((abs($fTerm) > 1e-12) && (++$ordK < 100));\n\t\t\t} else {\n\t\t\t\t$f_2_PI = 2 * M_PI;\n\n\t\t\t\t$fXAbs = abs($x);\n\t\t\t\t$fResult = exp($fXAbs) / sqrt($f_2_PI * $fXAbs);\n\t\t\t\tif (($ord & 1) && ($x < 0)) {\n\t\t\t\t\t$fResult = -$fResult;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn (is_nan($fResult)) ? PHPExcel_Calculation_Functions::NaN() : $fResult;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction BESSELI()\n\n\n\t/**\n\t *\tBESSELJ\n\t *\n\t *\tReturns the Bessel function\n\t *\n\t *\tExcel Function:\n\t *\t\tBESSELJ(x,ord)\n\t *\n\t *\t@access\tpublic\n\t *\t@category Engineering Functions\n\t *\t@param\tfloat\t\t$x\t\tThe value at which to evaluate the function.\n\t *\t\t\t\t\t\t\t\tIf x is nonnumeric, BESSELJ returns the #VALUE! error value.\n\t *\t@param\tinteger\t\t$ord\tThe order of the Bessel function. If n is not an integer, it is truncated.\n\t *\t\t\t\t\t\t\t\tIf $ord is nonnumeric, BESSELJ returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\tIf $ord < 0, BESSELJ returns the #NUM! error value.\n\t *\t@return\tfloat\n\t *\n\t */\n\tpublic static function BESSELJ($x, $ord) {\n\t\t$x\t= (is_null($x))\t? 0.0 :\tPHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$ord\t= (is_null($ord))\t? 0.0 :\tPHPExcel_Calculation_Functions::flattenSingleValue($ord);\n\n\t\tif ((is_numeric($x)) && (is_numeric($ord))) {\n\t\t\t$ord\t= floor($ord);\n\t\t\tif ($ord < 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\n\t\t\t$fResult = 0;\n\t\t\tif (abs($x) <= 30) {\n\t\t\t\t$fResult = $fTerm = pow($x / 2, $ord) / PHPExcel_Calculation_MathTrig::FACT($ord);\n\t\t\t\t$ordK = 1;\n\t\t\t\t$fSqrX = ($x * $x) / -4;\n\t\t\t\tdo {\n\t\t\t\t\t$fTerm *= $fSqrX;\n\t\t\t\t\t$fTerm /= ($ordK * ($ordK + $ord));\n\t\t\t\t\t$fResult += $fTerm;\n\t\t\t\t} while ((abs($fTerm) > 1e-12) && (++$ordK < 100));\n\t\t\t} else {\n\t\t\t\t$f_PI_DIV_2 = M_PI / 2;\n\t\t\t\t$f_PI_DIV_4 = M_PI / 4;\n\n\t\t\t\t$fXAbs = abs($x);\n\t\t\t\t$fResult = sqrt(M_2DIVPI / $fXAbs) * cos($fXAbs - $ord * $f_PI_DIV_2 - $f_PI_DIV_4);\n\t\t\t\tif (($ord & 1) && ($x < 0)) {\n\t\t\t\t\t$fResult = -$fResult;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn (is_nan($fResult)) ? PHPExcel_Calculation_Functions::NaN() : $fResult;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction BESSELJ()\n\n\n\tprivate static function _Besselk0($fNum) {\n\t\tif ($fNum <= 2) {\n\t\t\t$fNum2 = $fNum * 0.5;\n\t\t\t$y = ($fNum2 * $fNum2);\n\t\t\t$fRet = -log($fNum2) * self::BESSELI($fNum, 0) +\n\t\t\t\t\t(-0.57721566 + $y * (0.42278420 + $y * (0.23069756 + $y * (0.3488590e-1 + $y * (0.262698e-2 + $y *\n\t\t\t\t\t(0.10750e-3 + $y * 0.74e-5))))));\n\t\t} else {\n\t\t\t$y = 2 / $fNum;\n\t\t\t$fRet = exp(-$fNum) / sqrt($fNum) *\n\t\t\t\t\t(1.25331414 + $y * (-0.7832358e-1 + $y * (0.2189568e-1 + $y * (-0.1062446e-1 + $y *\n\t\t\t\t\t(0.587872e-2 + $y * (-0.251540e-2 + $y * 0.53208e-3))))));\n\t\t}\n\t\treturn $fRet;\n\t}\t//\tfunction _Besselk0()\n\n\n\tprivate static function _Besselk1($fNum) {\n\t\tif ($fNum <= 2) {\n\t\t\t$fNum2 = $fNum * 0.5;\n\t\t\t$y = ($fNum2 * $fNum2);\n\t\t\t$fRet = log($fNum2) * self::BESSELI($fNum, 1) +\n\t\t\t\t\t(1 + $y * (0.15443144 + $y * (-0.67278579 + $y * (-0.18156897 + $y * (-0.1919402e-1 + $y *\n\t\t\t\t\t(-0.110404e-2 + $y * (-0.4686e-4))))))) / $fNum;\n\t\t} else {\n\t\t\t$y = 2 / $fNum;\n\t\t\t$fRet = exp(-$fNum) / sqrt($fNum) *\n\t\t\t\t\t(1.25331414 + $y * (0.23498619 + $y * (-0.3655620e-1 + $y * (0.1504268e-1 + $y * (-0.780353e-2 + $y *\n\t\t\t\t\t(0.325614e-2 + $y * (-0.68245e-3)))))));\n\t\t}\n\t\treturn $fRet;\n\t}\t//\tfunction _Besselk1()\n\n\n\t/**\n\t *\tBESSELK\n\t *\n\t *\tReturns the modified Bessel function Kn(x), which is equivalent to the Bessel functions evaluated\n\t *\t\tfor purely imaginary arguments.\n\t *\n\t *\tExcel Function:\n\t *\t\tBESSELK(x,ord)\n\t *\n\t *\t@access\tpublic\n\t *\t@category Engineering Functions\n\t *\t@param\tfloat\t\t$x\t\tThe value at which to evaluate the function.\n\t *\t\t\t\t\t\t\t\tIf x is nonnumeric, BESSELK returns the #VALUE! error value.\n\t *\t@param\tinteger\t\t$ord\tThe order of the Bessel function. If n is not an integer, it is truncated.\n\t *\t\t\t\t\t\t\t\tIf $ord is nonnumeric, BESSELK returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\tIf $ord < 0, BESSELK returns the #NUM! error value.\n\t *\t@return\tfloat\n\t *\n\t */\n\tpublic static function BESSELK($x, $ord) {\n\t\t$x\t\t= (is_null($x))\t\t? 0.0 :\tPHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$ord\t= (is_null($ord))\t? 0.0 :\tPHPExcel_Calculation_Functions::flattenSingleValue($ord);\n\n\t\tif ((is_numeric($x)) && (is_numeric($ord))) {\n\t\t\tif (($ord < 0) || ($x == 0.0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\n\t\t\tswitch(floor($ord)) {\n\t\t\t\tcase 0 :\treturn self::_Besselk0($x);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\tcase 1 :\treturn self::_Besselk1($x);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\tdefault :\t$fTox\t= 2 / $x;\n\t\t\t\t\t\t\t$fBkm\t= self::_Besselk0($x);\n\t\t\t\t\t\t\t$fBk\t= self::_Besselk1($x);\n\t\t\t\t\t\t\tfor ($n = 1; $n < $ord; ++$n) {\n\t\t\t\t\t\t\t\t$fBkp\t= $fBkm + $n * $fTox * $fBk;\n\t\t\t\t\t\t\t\t$fBkm\t= $fBk;\n\t\t\t\t\t\t\t\t$fBk\t= $fBkp;\n\t\t\t\t\t\t\t}\n\t\t\t}\n\t\t\treturn (is_nan($fBk)) ? PHPExcel_Calculation_Functions::NaN() : $fBk;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction BESSELK()\n\n\n\tprivate static function _Bessely0($fNum) {\n\t\tif ($fNum < 8.0) {\n\t\t\t$y = ($fNum * $fNum);\n\t\t\t$f1 = -2957821389.0 + $y * (7062834065.0 + $y * (-512359803.6 + $y * (10879881.29 + $y * (-86327.92757 + $y * 228.4622733))));\n\t\t\t$f2 = 40076544269.0 + $y * (745249964.8 + $y * (7189466.438 + $y * (47447.26470 + $y * (226.1030244 + $y))));\n\t\t\t$fRet = $f1 / $f2 + 0.636619772 * self::BESSELJ($fNum, 0) * log($fNum);\n\t\t} else {\n\t\t\t$z = 8.0 / $fNum;\n\t\t\t$y = ($z * $z);\n\t\t\t$xx = $fNum - 0.785398164;\n\t\t\t$f1 = 1 + $y * (-0.1098628627e-2 + $y * (0.2734510407e-4 + $y * (-0.2073370639e-5 + $y * 0.2093887211e-6)));\n\t\t\t$f2 = -0.1562499995e-1 + $y * (0.1430488765e-3 + $y * (-0.6911147651e-5 + $y * (0.7621095161e-6 + $y * (-0.934945152e-7))));\n\t\t\t$fRet = sqrt(0.636619772 / $fNum) * (sin($xx) * $f1 + $z * cos($xx) * $f2);\n\t\t}\n\t\treturn $fRet;\n\t}\t//\tfunction _Bessely0()\n\n\n\tprivate static function _Bessely1($fNum) {\n\t\tif ($fNum < 8.0) {\n\t\t\t$y = ($fNum * $fNum);\n\t\t\t$f1 = $fNum * (-0.4900604943e13 + $y * (0.1275274390e13 + $y * (-0.5153438139e11 + $y * (0.7349264551e9 + $y *\n\t\t\t\t(-0.4237922726e7 + $y * 0.8511937935e4)))));\n\t\t\t$f2 = 0.2499580570e14 + $y * (0.4244419664e12 + $y * (0.3733650367e10 + $y * (0.2245904002e8 + $y *\n\t\t\t\t(0.1020426050e6 + $y * (0.3549632885e3 + $y)))));\n\t\t\t$fRet = $f1 / $f2 + 0.636619772 * ( self::BESSELJ($fNum, 1) * log($fNum) - 1 / $fNum);\n\t\t} else {\n\t\t\t$fRet = sqrt(0.636619772 / $fNum) * sin($fNum - 2.356194491);\n\t\t}\n\t\treturn $fRet;\n\t}\t//\tfunction _Bessely1()\n\n\n\t/**\n\t *\tBESSELY\n\t *\n\t *\tReturns the Bessel function, which is also called the Weber function or the Neumann function.\n\t *\n\t *\tExcel Function:\n\t *\t\tBESSELY(x,ord)\n\t *\n\t *\t@access\tpublic\n\t *\t@category Engineering Functions\n\t *\t@param\tfloat\t\t$x\t\tThe value at which to evaluate the function.\n\t *\t\t\t\t\t\t\t\tIf x is nonnumeric, BESSELK returns the #VALUE! error value.\n\t *\t@param\tinteger\t\t$ord\tThe order of the Bessel function. If n is not an integer, it is truncated.\n\t *\t\t\t\t\t\t\t\tIf $ord is nonnumeric, BESSELK returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\tIf $ord < 0, BESSELK returns the #NUM! error value.\n\t *\n\t *\t@return\tfloat\n\t */\n\tpublic static function BESSELY($x, $ord) {\n\t\t$x\t\t= (is_null($x))\t\t? 0.0 :\tPHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$ord\t= (is_null($ord))\t? 0.0 :\tPHPExcel_Calculation_Functions::flattenSingleValue($ord);\n\n\t\tif ((is_numeric($x)) && (is_numeric($ord))) {\n\t\t\tif (($ord < 0) || ($x == 0.0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\n\t\t\tswitch(floor($ord)) {\n\t\t\t\tcase 0 :\treturn self::_Bessely0($x);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\tcase 1 :\treturn self::_Bessely1($x);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\t$fTox\t= 2 / $x;\n\t\t\t\t\t\t\t$fBym\t= self::_Bessely0($x);\n\t\t\t\t\t\t\t$fBy\t= self::_Bessely1($x);\n\t\t\t\t\t\t\tfor ($n = 1; $n < $ord; ++$n) {\n\t\t\t\t\t\t\t\t$fByp\t= $n * $fTox * $fBy - $fBym;\n\t\t\t\t\t\t\t\t$fBym\t= $fBy;\n\t\t\t\t\t\t\t\t$fBy\t= $fByp;\n\t\t\t\t\t\t\t}\n\t\t\t}\n\t\t\treturn (is_nan($fBy)) ? PHPExcel_Calculation_Functions::NaN() : $fBy;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction BESSELY()\n\n\n\t/**\n\t * BINTODEC\n\t *\n\t * Return a binary value as decimal.\n\t *\n\t * Excel Function:\n\t *\t\tBIN2DEC(x)\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$x\t\tThe binary number (as a string) that you want to convert. The number\n\t *\t\t\t\t\t\t\t\tcannot contain more than 10 characters (10 bits). The most significant\n\t *\t\t\t\t\t\t\t\tbit of number is the sign bit. The remaining 9 bits are magnitude bits.\n\t *\t\t\t\t\t\t\t\tNegative numbers are represented using two's-complement notation.\n\t *\t\t\t\t\t\t\t\tIf number is not a valid binary number, or if number contains more than\n\t *\t\t\t\t\t\t\t\t10 characters (10 bits), BIN2DEC returns the #NUM! error value.\n\t * @return\tstring\n\t */\n\tpublic static function BINTODEC($x) {\n\t\t$x\t= PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\n\t\tif (is_bool($x)) {\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {\n\t\t\t\t$x = (int) $x;\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t}\n\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {\n\t\t\t$x = floor($x);\n\t\t}\n\t\t$x = (string) $x;\n\t\tif (strlen($x) > preg_match_all('/[01]/',$x,$out)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\tif (strlen($x) > 10) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t} elseif (strlen($x) == 10) {\n\t\t\t//\tTwo's Complement\n\t\t\t$x = substr($x,-9);\n\t\t\treturn '-'.(512-bindec($x));\n\t\t}\n\t\treturn bindec($x);\n\t}\t//\tfunction BINTODEC()\n\n\n\t/**\n\t * BINTOHEX\n\t *\n\t * Return a binary value as hex.\n\t *\n\t * Excel Function:\n\t *\t\tBIN2HEX(x[,places])\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$x\t\tThe binary number (as a string) that you want to convert. The number\n\t *\t\t\t\t\t\t\t\tcannot contain more than 10 characters (10 bits). The most significant\n\t *\t\t\t\t\t\t\t\tbit of number is the sign bit. The remaining 9 bits are magnitude bits.\n\t *\t\t\t\t\t\t\t\tNegative numbers are represented using two's-complement notation.\n\t *\t\t\t\t\t\t\t\tIf number is not a valid binary number, or if number contains more than\n\t *\t\t\t\t\t\t\t\t10 characters (10 bits), BIN2HEX returns the #NUM! error value.\n\t * @param\tinteger\t\t$places\tThe number of characters to use. If places is omitted, BIN2HEX uses the\n\t *\t\t\t\t\t\t\t\tminimum number of characters necessary. Places is useful for padding the\n\t *\t\t\t\t\t\t\t\treturn value with leading 0s (zeros).\n\t *\t\t\t\t\t\t\t\tIf places is not an integer, it is truncated.\n\t *\t\t\t\t\t\t\t\tIf places is nonnumeric, BIN2HEX returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\tIf places is negative, BIN2HEX returns the #NUM! error value.\n\t * @return\tstring\n\t */\n\tpublic static function BINTOHEX($x, $places=NULL) {\n\t\t$x\t= PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$places\t= PHPExcel_Calculation_Functions::flattenSingleValue($places);\n\n\t\tif (is_bool($x)) {\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {\n\t\t\t\t$x = (int) $x;\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t}\n\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {\n\t\t\t$x = floor($x);\n\t\t}\n\t\t$x = (string) $x;\n\t\tif (strlen($x) > preg_match_all('/[01]/',$x,$out)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\tif (strlen($x) > 10) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t} elseif (strlen($x) == 10) {\n\t\t\t//\tTwo's Complement\n\t\t\treturn str_repeat('F',8).substr(strtoupper(dechex(bindec(substr($x,-9)))),-2);\n\t\t}\n\t\t$hexVal = (string) strtoupper(dechex(bindec($x)));\n\n\t\treturn self::_nbrConversionFormat($hexVal,$places);\n\t}\t//\tfunction BINTOHEX()\n\n\n\t/**\n\t * BINTOOCT\n\t *\n\t * Return a binary value as octal.\n\t *\n\t * Excel Function:\n\t *\t\tBIN2OCT(x[,places])\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$x\t\tThe binary number (as a string) that you want to convert. The number\n\t *\t\t\t\t\t\t\t\tcannot contain more than 10 characters (10 bits). The most significant\n\t *\t\t\t\t\t\t\t\tbit of number is the sign bit. The remaining 9 bits are magnitude bits.\n\t *\t\t\t\t\t\t\t\tNegative numbers are represented using two's-complement notation.\n\t *\t\t\t\t\t\t\t\tIf number is not a valid binary number, or if number contains more than\n\t *\t\t\t\t\t\t\t\t10 characters (10 bits), BIN2OCT returns the #NUM! error value.\n\t * @param\tinteger\t\t$places\tThe number of characters to use. If places is omitted, BIN2OCT uses the\n\t *\t\t\t\t\t\t\t\tminimum number of characters necessary. Places is useful for padding the\n\t *\t\t\t\t\t\t\t\treturn value with leading 0s (zeros).\n\t *\t\t\t\t\t\t\t\tIf places is not an integer, it is truncated.\n\t *\t\t\t\t\t\t\t\tIf places is nonnumeric, BIN2OCT returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\tIf places is negative, BIN2OCT returns the #NUM! error value.\n\t * @return\tstring\n\t */\n\tpublic static function BINTOOCT($x, $places=NULL) {\n\t\t$x\t= PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$places\t= PHPExcel_Calculation_Functions::flattenSingleValue($places);\n\n\t\tif (is_bool($x)) {\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {\n\t\t\t\t$x = (int) $x;\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t}\n\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {\n\t\t\t$x = floor($x);\n\t\t}\n\t\t$x = (string) $x;\n\t\tif (strlen($x) > preg_match_all('/[01]/',$x,$out)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\tif (strlen($x) > 10) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t} elseif (strlen($x) == 10) {\n\t\t\t//\tTwo's Complement\n\t\t\treturn str_repeat('7',7).substr(strtoupper(decoct(bindec(substr($x,-9)))),-3);\n\t\t}\n\t\t$octVal = (string) decoct(bindec($x));\n\n\t\treturn self::_nbrConversionFormat($octVal,$places);\n\t}\t//\tfunction BINTOOCT()\n\n\n\t/**\n\t * DECTOBIN\n\t *\n\t * Return a decimal value as binary.\n\t *\n\t * Excel Function:\n\t *\t\tDEC2BIN(x[,places])\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$x\t\tThe decimal integer you want to convert. If number is negative,\n\t *\t\t\t\t\t\t\t\tvalid place values are ignored and DEC2BIN returns a 10-character\n\t *\t\t\t\t\t\t\t\t(10-bit) binary number in which the most significant bit is the sign\n\t *\t\t\t\t\t\t\t\tbit. The remaining 9 bits are magnitude bits. Negative numbers are\n\t *\t\t\t\t\t\t\t\trepresented using two's-complement notation.\n\t *\t\t\t\t\t\t\t\tIf number < -512 or if number > 511, DEC2BIN returns the #NUM! error\n\t *\t\t\t\t\t\t\t\tvalue.\n\t *\t\t\t\t\t\t\t\tIf number is nonnumeric, DEC2BIN returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\tIf DEC2BIN requires more than places characters, it returns the #NUM!\n\t *\t\t\t\t\t\t\t\terror value.\n\t * @param\tinteger\t\t$places\tThe number of characters to use. If places is omitted, DEC2BIN uses\n\t *\t\t\t\t\t\t\t\tthe minimum number of characters necessary. Places is useful for\n\t *\t\t\t\t\t\t\t\tpadding the return value with leading 0s (zeros).\n\t *\t\t\t\t\t\t\t\tIf places is not an integer, it is truncated.\n\t *\t\t\t\t\t\t\t\tIf places is nonnumeric, DEC2BIN returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\tIf places is zero or negative, DEC2BIN returns the #NUM! error value.\n\t * @return\tstring\n\t */\n\tpublic static function DECTOBIN($x, $places=NULL) {\n\t\t$x\t= PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$places\t= PHPExcel_Calculation_Functions::flattenSingleValue($places);\n\n\t\tif (is_bool($x)) {\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {\n\t\t\t\t$x = (int) $x;\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t}\n\t\t$x = (string) $x;\n\t\tif (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$x = (string) floor($x);\n\t\t$r = decbin($x);\n\t\tif (strlen($r) == 32) {\n\t\t\t//\tTwo's Complement\n\t\t\t$r = substr($r,-10);\n\t\t} elseif (strlen($r) > 11) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\treturn self::_nbrConversionFormat($r,$places);\n\t}\t//\tfunction DECTOBIN()\n\n\n\t/**\n\t * DECTOHEX\n\t *\n\t * Return a decimal value as hex.\n\t *\n\t * Excel Function:\n\t *\t\tDEC2HEX(x[,places])\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$x\t\tThe decimal integer you want to convert. If number is negative,\n\t *\t\t\t\t\t\t\t\tplaces is ignored and DEC2HEX returns a 10-character (40-bit)\n\t *\t\t\t\t\t\t\t\thexadecimal number in which the most significant bit is the sign\n\t *\t\t\t\t\t\t\t\tbit. The remaining 39 bits are magnitude bits. Negative numbers\n\t *\t\t\t\t\t\t\t\tare represented using two's-complement notation.\n\t *\t\t\t\t\t\t\t\tIf number < -549,755,813,888 or if number > 549,755,813,887,\n\t *\t\t\t\t\t\t\t\tDEC2HEX returns the #NUM! error value.\n\t *\t\t\t\t\t\t\t\tIf number is nonnumeric, DEC2HEX returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\tIf DEC2HEX requires more than places characters, it returns the\n\t *\t\t\t\t\t\t\t\t#NUM! error value.\n\t * @param\tinteger\t\t$places\tThe number of characters to use. If places is omitted, DEC2HEX uses\n\t *\t\t\t\t\t\t\t\tthe minimum number of characters necessary. Places is useful for\n\t *\t\t\t\t\t\t\t\tpadding the return value with leading 0s (zeros).\n\t *\t\t\t\t\t\t\t\tIf places is not an integer, it is truncated.\n\t *\t\t\t\t\t\t\t\tIf places is nonnumeric, DEC2HEX returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\tIf places is zero or negative, DEC2HEX returns the #NUM! error value.\n\t * @return\tstring\n\t */\n\tpublic static function DECTOHEX($x, $places=null) {\n\t\t$x\t= PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$places\t= PHPExcel_Calculation_Functions::flattenSingleValue($places);\n\n\t\tif (is_bool($x)) {\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {\n\t\t\t\t$x = (int) $x;\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t}\n\t\t$x = (string) $x;\n\t\tif (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$x = (string) floor($x);\n\t\t$r = strtoupper(dechex($x));\n\t\tif (strlen($r) == 8) {\n\t\t\t//\tTwo's Complement\n\t\t\t$r = 'FF'.$r;\n\t\t}\n\n\t\treturn self::_nbrConversionFormat($r,$places);\n\t}\t//\tfunction DECTOHEX()\n\n\n\t/**\n\t * DECTOOCT\n\t *\n\t * Return an decimal value as octal.\n\t *\n\t * Excel Function:\n\t *\t\tDEC2OCT(x[,places])\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$x\t\tThe decimal integer you want to convert. If number is negative,\n\t *\t\t\t\t\t\t\t\tplaces is ignored and DEC2OCT returns a 10-character (30-bit)\n\t *\t\t\t\t\t\t\t\toctal number in which the most significant bit is the sign bit.\n\t *\t\t\t\t\t\t\t\tThe remaining 29 bits are magnitude bits. Negative numbers are\n\t *\t\t\t\t\t\t\t\trepresented using two's-complement notation.\n\t *\t\t\t\t\t\t\t\tIf number < -536,870,912 or if number > 536,870,911, DEC2OCT\n\t *\t\t\t\t\t\t\t\treturns the #NUM! error value.\n\t *\t\t\t\t\t\t\t\tIf number is nonnumeric, DEC2OCT returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\tIf DEC2OCT requires more than places characters, it returns the\n\t *\t\t\t\t\t\t\t\t#NUM! error value.\n\t * @param\tinteger\t\t$places\tThe number of characters to use. If places is omitted, DEC2OCT uses\n\t *\t\t\t\t\t\t\t\tthe minimum number of characters necessary. Places is useful for\n\t *\t\t\t\t\t\t\t\tpadding the return value with leading 0s (zeros).\n\t *\t\t\t\t\t\t\t\tIf places is not an integer, it is truncated.\n\t *\t\t\t\t\t\t\t\tIf places is nonnumeric, DEC2OCT returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\tIf places is zero or negative, DEC2OCT returns the #NUM! error value.\n\t * @return\tstring\n\t */\n\tpublic static function DECTOOCT($x, $places=null) {\n\t\t$x\t= PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$places\t= PHPExcel_Calculation_Functions::flattenSingleValue($places);\n\n\t\tif (is_bool($x)) {\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {\n\t\t\t\t$x = (int) $x;\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t}\n\t\t$x = (string) $x;\n\t\tif (strlen($x) > preg_match_all('/[-0123456789.]/',$x,$out)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$x = (string) floor($x);\n\t\t$r = decoct($x);\n\t\tif (strlen($r) == 11) {\n\t\t\t//\tTwo's Complement\n\t\t\t$r = substr($r,-10);\n\t\t}\n\n\t\treturn self::_nbrConversionFormat($r,$places);\n\t}\t//\tfunction DECTOOCT()\n\n\n\t/**\n\t * HEXTOBIN\n\t *\n\t * Return a hex value as binary.\n\t *\n\t * Excel Function:\n\t *\t\tHEX2BIN(x[,places])\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$x\t\t\tthe hexadecimal number you want to convert. Number cannot\n\t *\t\t\t\t\t\t\t\t\tcontain more than 10 characters. The most significant bit of\n\t *\t\t\t\t\t\t\t\t\tnumber is the sign bit (40th bit from the right). The remaining\n\t *\t\t\t\t\t\t\t\t\t9 bits are magnitude bits. Negative numbers are represented\n\t *\t\t\t\t\t\t\t\t\tusing two's-complement notation.\n\t *\t\t\t\t\t\t\t\t\tIf number is negative, HEX2BIN ignores places and returns a\n\t *\t\t\t\t\t\t\t\t\t10-character binary number.\n\t *\t\t\t\t\t\t\t\t\tIf number is negative, it cannot be less than FFFFFFFE00, and\n\t *\t\t\t\t\t\t\t\t\tif number is positive, it cannot be greater than 1FF.\n\t *\t\t\t\t\t\t\t\t\tIf number is not a valid hexadecimal number, HEX2BIN returns\n\t *\t\t\t\t\t\t\t\t\tthe #NUM! error value.\n\t *\t\t\t\t\t\t\t\t\tIf HEX2BIN requires more than places characters, it returns\n\t *\t\t\t\t\t\t\t\t\tthe #NUM! error value.\n\t * @param\tinteger\t\t$places\t\tThe number of characters to use. If places is omitted,\n\t *\t\t\t\t\t\t\t\t\tHEX2BIN uses the minimum number of characters necessary. Places\n\t *\t\t\t\t\t\t\t\t\tis useful for padding the return value with leading 0s (zeros).\n\t *\t\t\t\t\t\t\t\t\tIf places is not an integer, it is truncated.\n\t *\t\t\t\t\t\t\t\t\tIf places is nonnumeric, HEX2BIN returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\t\tIf places is negative, HEX2BIN returns the #NUM! error value.\n\t * @return\tstring\n\t */\n\tpublic static function HEXTOBIN($x, $places=null) {\n\t\t$x\t= PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$places\t= PHPExcel_Calculation_Functions::flattenSingleValue($places);\n\n\t\tif (is_bool($x)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$x = (string) $x;\n\t\tif (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\t$binVal = decbin(hexdec($x));\n\n\t\treturn substr(self::_nbrConversionFormat($binVal,$places),-10);\n\t}\t//\tfunction HEXTOBIN()\n\n\n\t/**\n\t * HEXTODEC\n\t *\n\t * Return a hex value as decimal.\n\t *\n\t * Excel Function:\n\t *\t\tHEX2DEC(x)\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$x\t\tThe hexadecimal number you want to convert. This number cannot\n\t *\t\t\t\t\t\t\t\tcontain more than 10 characters (40 bits). The most significant\n\t *\t\t\t\t\t\t\t\tbit of number is the sign bit. The remaining 39 bits are magnitude\n\t *\t\t\t\t\t\t\t\tbits. Negative numbers are represented using two's-complement\n\t *\t\t\t\t\t\t\t\tnotation.\n\t *\t\t\t\t\t\t\t\tIf number is not a valid hexadecimal number, HEX2DEC returns the\n\t *\t\t\t\t\t\t\t\t#NUM! error value.\n\t * @return\tstring\n\t */\n\tpublic static function HEXTODEC($x) {\n\t\t$x\t= PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\n\t\tif (is_bool($x)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$x = (string) $x;\n\t\tif (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\treturn hexdec($x);\n\t}\t//\tfunction HEXTODEC()\n\n\n\t/**\n\t * HEXTOOCT\n\t *\n\t * Return a hex value as octal.\n\t *\n\t * Excel Function:\n\t *\t\tHEX2OCT(x[,places])\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$x\t\t\tThe hexadecimal number you want to convert. Number cannot\n\t *\t\t\t\t\t\t\t\t\tcontain more than 10 characters. The most significant bit of\n\t *\t\t\t\t\t\t\t\t\tnumber is the sign bit. The remaining 39 bits are magnitude\n\t *\t\t\t\t\t\t\t\t\tbits. Negative numbers are represented using two's-complement\n\t *\t\t\t\t\t\t\t\t\tnotation.\n\t *\t\t\t\t\t\t\t\t\tIf number is negative, HEX2OCT ignores places and returns a\n\t *\t\t\t\t\t\t\t\t\t10-character octal number.\n\t *\t\t\t\t\t\t\t\t\tIf number is negative, it cannot be less than FFE0000000, and\n\t *\t\t\t\t\t\t\t\t\tif number is positive, it cannot be greater than 1FFFFFFF.\n\t *\t\t\t\t\t\t\t\t\tIf number is not a valid hexadecimal number, HEX2OCT returns\n\t *\t\t\t\t\t\t\t\t\tthe #NUM! error value.\n\t *\t\t\t\t\t\t\t\t\tIf HEX2OCT requires more than places characters, it returns\n\t *\t\t\t\t\t\t\t\t\tthe #NUM! error value.\n\t * @param\tinteger\t\t$places\t\tThe number of characters to use. If places is omitted, HEX2OCT\n\t *\t\t\t\t\t\t\t\t\tuses the minimum number of characters necessary. Places is\n\t *\t\t\t\t\t\t\t\t\tuseful for padding the return value with leading 0s (zeros).\n\t *\t\t\t\t\t\t\t\t\tIf places is not an integer, it is truncated.\n\t *\t\t\t\t\t\t\t\t\tIf places is nonnumeric, HEX2OCT returns the #VALUE! error\n\t *\t\t\t\t\t\t\t\t\tvalue.\n\t *\t\t\t\t\t\t\t\t\tIf places is negative, HEX2OCT returns the #NUM! error value.\n\t * @return\tstring\n\t */\n\tpublic static function HEXTOOCT($x, $places=null) {\n\t\t$x\t= PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$places\t= PHPExcel_Calculation_Functions::flattenSingleValue($places);\n\n\t\tif (is_bool($x)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$x = (string) $x;\n\t\tif (strlen($x) > preg_match_all('/[0123456789ABCDEF]/',strtoupper($x),$out)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\t$octVal = decoct(hexdec($x));\n\n\t\treturn self::_nbrConversionFormat($octVal,$places);\n\t}\t//\tfunction HEXTOOCT()\n\n\n\t/**\n\t * OCTTOBIN\n\t *\n\t * Return an octal value as binary.\n\t *\n\t * Excel Function:\n\t *\t\tOCT2BIN(x[,places])\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$x\t\t\tThe octal number you want to convert. Number may not\n\t *\t\t\t\t\t\t\t\t\tcontain more than 10 characters. The most significant\n\t *\t\t\t\t\t\t\t\t\tbit of number is the sign bit. The remaining 29 bits\n\t *\t\t\t\t\t\t\t\t\tare magnitude bits. Negative numbers are represented\n\t *\t\t\t\t\t\t\t\t\tusing two's-complement notation.\n\t *\t\t\t\t\t\t\t\t\tIf number is negative, OCT2BIN ignores places and returns\n\t *\t\t\t\t\t\t\t\t\ta 10-character binary number.\n\t *\t\t\t\t\t\t\t\t\tIf number is negative, it cannot be less than 7777777000,\n\t *\t\t\t\t\t\t\t\t\tand if number is positive, it cannot be greater than 777.\n\t *\t\t\t\t\t\t\t\t\tIf number is not a valid octal number, OCT2BIN returns\n\t *\t\t\t\t\t\t\t\t\tthe #NUM! error value.\n\t *\t\t\t\t\t\t\t\t\tIf OCT2BIN requires more than places characters, it\n\t *\t\t\t\t\t\t\t\t\treturns the #NUM! error value.\n\t * @param\tinteger\t\t$places\t\tThe number of characters to use. If places is omitted,\n\t *\t\t\t\t\t\t\t\t\tOCT2BIN uses the minimum number of characters necessary.\n\t *\t\t\t\t\t\t\t\t\tPlaces is useful for padding the return value with\n\t *\t\t\t\t\t\t\t\t\tleading 0s (zeros).\n\t *\t\t\t\t\t\t\t\t\tIf places is not an integer, it is truncated.\n\t *\t\t\t\t\t\t\t\t\tIf places is nonnumeric, OCT2BIN returns the #VALUE!\n\t *\t\t\t\t\t\t\t\t\terror value.\n\t *\t\t\t\t\t\t\t\t\tIf places is negative, OCT2BIN returns the #NUM! error\n\t *\t\t\t\t\t\t\t\t\tvalue.\n\t * @return\tstring\n\t */\n\tpublic static function OCTTOBIN($x, $places=null) {\n\t\t$x\t= PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$places\t= PHPExcel_Calculation_Functions::flattenSingleValue($places);\n\n\t\tif (is_bool($x)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$x = (string) $x;\n\t\tif (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\t$r = decbin(octdec($x));\n\n\t\treturn self::_nbrConversionFormat($r,$places);\n\t}\t//\tfunction OCTTOBIN()\n\n\n\t/**\n\t * OCTTODEC\n\t *\n\t * Return an octal value as decimal.\n\t *\n\t * Excel Function:\n\t *\t\tOCT2DEC(x)\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$x\t\tThe octal number you want to convert. Number may not contain\n\t *\t\t\t\t\t\t\t\tmore than 10 octal characters (30 bits). The most significant\n\t *\t\t\t\t\t\t\t\tbit of number is the sign bit. The remaining 29 bits are\n\t *\t\t\t\t\t\t\t\tmagnitude bits. Negative numbers are represented using\n\t *\t\t\t\t\t\t\t\ttwo's-complement notation.\n\t *\t\t\t\t\t\t\t\tIf number is not a valid octal number, OCT2DEC returns the\n\t *\t\t\t\t\t\t\t\t#NUM! error value.\n\t * @return\tstring\n\t */\n\tpublic static function OCTTODEC($x) {\n\t\t$x\t= PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\n\t\tif (is_bool($x)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$x = (string) $x;\n\t\tif (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\treturn octdec($x);\n\t}\t//\tfunction OCTTODEC()\n\n\n\t/**\n\t * OCTTOHEX\n\t *\n\t * Return an octal value as hex.\n\t *\n\t * Excel Function:\n\t *\t\tOCT2HEX(x[,places])\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$x\t\t\tThe octal number you want to convert. Number may not contain\n\t *\t\t\t\t\t\t\t\t\tmore than 10 octal characters (30 bits). The most significant\n\t *\t\t\t\t\t\t\t\t\tbit of number is the sign bit. The remaining 29 bits are\n\t *\t\t\t\t\t\t\t\t\tmagnitude bits. Negative numbers are represented using\n\t *\t\t\t\t\t\t\t\t\ttwo's-complement notation.\n\t *\t\t\t\t\t\t\t\t\tIf number is negative, OCT2HEX ignores places and returns a\n\t *\t\t\t\t\t\t\t\t\t10-character hexadecimal number.\n\t *\t\t\t\t\t\t\t\t\tIf number is not a valid octal number, OCT2HEX returns the\n\t *\t\t\t\t\t\t\t\t\t#NUM! error value.\n\t *\t\t\t\t\t\t\t\t\tIf OCT2HEX requires more than places characters, it returns\n\t *\t\t\t\t\t\t\t\t\tthe #NUM! error value.\n\t * @param\tinteger\t\t$places\t\tThe number of characters to use. If places is omitted, OCT2HEX\n\t *\t\t\t\t\t\t\t\t\tuses the minimum number of characters necessary. Places is useful\n\t *\t\t\t\t\t\t\t\t\tfor padding the return value with leading 0s (zeros).\n\t *\t\t\t\t\t\t\t\t\tIf places is not an integer, it is truncated.\n\t *\t\t\t\t\t\t\t\t\tIf places is nonnumeric, OCT2HEX returns the #VALUE! error value.\n\t *\t\t\t\t\t\t\t\t\tIf places is negative, OCT2HEX returns the #NUM! error value.\n\t * @return\tstring\n\t */\n\tpublic static function OCTTOHEX($x, $places=null) {\n\t\t$x\t= PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$places\t= PHPExcel_Calculation_Functions::flattenSingleValue($places);\n\n\t\tif (is_bool($x)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$x = (string) $x;\n\t\tif (preg_match_all('/[01234567]/',$x,$out) != strlen($x)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\t$hexVal = strtoupper(dechex(octdec($x)));\n\n\t\treturn self::_nbrConversionFormat($hexVal,$places);\n\t}\t//\tfunction OCTTOHEX()\n\n\n\t/**\n\t * COMPLEX\n\t *\n\t * Converts real and imaginary coefficients into a complex number of the form x + yi or x + yj.\n\t *\n\t * Excel Function:\n\t *\t\tCOMPLEX(realNumber,imaginary[,places])\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tfloat\t\t$realNumber\t\tThe real coefficient of the complex number.\n\t * @param\tfloat\t\t$imaginary\t\tThe imaginary coefficient of the complex number.\n\t * @param\tstring\t\t$suffix\t\t\tThe suffix for the imaginary component of the complex number.\n\t *\t\t\t\t\t\t\t\t\t\tIf omitted, the suffix is assumed to be \"i\".\n\t * @return\tstring\n\t */\n\tpublic static function COMPLEX($realNumber=0.0, $imaginary=0.0, $suffix='i') {\n\t\t$realNumber\t= (is_null($realNumber))\t? 0.0 :\tPHPExcel_Calculation_Functions::flattenSingleValue($realNumber);\n\t\t$imaginary\t= (is_null($imaginary))\t\t? 0.0 :\tPHPExcel_Calculation_Functions::flattenSingleValue($imaginary);\n\t\t$suffix\t\t= (is_null($suffix))\t\t? 'i' :\tPHPExcel_Calculation_Functions::flattenSingleValue($suffix);\n\n\t\tif (((is_numeric($realNumber)) && (is_numeric($imaginary))) &&\n\t\t\t(($suffix == 'i') || ($suffix == 'j') || ($suffix == ''))) {\n\t\t\t$realNumber\t= (float) $realNumber;\n\t\t\t$imaginary\t= (float) $imaginary;\n\n\t\t\tif ($suffix == '') $suffix = 'i';\n\t\t\tif ($realNumber == 0.0) {\n\t\t\t\tif ($imaginary == 0.0) {\n\t\t\t\t\treturn (string) '0';\n\t\t\t\t} elseif ($imaginary == 1.0) {\n\t\t\t\t\treturn (string) $suffix;\n\t\t\t\t} elseif ($imaginary == -1.0) {\n\t\t\t\t\treturn (string) '-'.$suffix;\n\t\t\t\t}\n\t\t\t\treturn (string) $imaginary.$suffix;\n\t\t\t} elseif ($imaginary == 0.0) {\n\t\t\t\treturn (string) $realNumber;\n\t\t\t} elseif ($imaginary == 1.0) {\n\t\t\t\treturn (string) $realNumber.'+'.$suffix;\n\t\t\t} elseif ($imaginary == -1.0) {\n\t\t\t\treturn (string) $realNumber.'-'.$suffix;\n\t\t\t}\n\t\t\tif ($imaginary > 0) { $imaginary = (string) '+'.$imaginary; }\n\t\t\treturn (string) $realNumber.$imaginary.$suffix;\n\t\t}\n\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction COMPLEX()\n\n\n\t/**\n\t * IMAGINARY\n\t *\n\t * Returns the imaginary coefficient of a complex number in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMAGINARY(complexNumber)\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$complexNumber\tThe complex number for which you want the imaginary\n\t * \t\t\t\t\t\t\t\t\t\tcoefficient.\n\t * @return\tfloat\n\t */\n\tpublic static function IMAGINARY($complexNumber) {\n\t\t$complexNumber\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);\n\n\t\t$parsedComplex = self::_parseComplex($complexNumber);\n\t\treturn $parsedComplex['imaginary'];\n\t}\t//\tfunction IMAGINARY()\n\n\n\t/**\n\t * IMREAL\n\t *\n\t * Returns the real coefficient of a complex number in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMREAL(complexNumber)\n\t *\n\t * @access\tpublic\n\t * @category Engineering Functions\n\t * @param\tstring\t\t$complexNumber\tThe complex number for which you want the real coefficient.\n\t * @return\tfloat\n\t */\n\tpublic static function IMREAL($complexNumber) {\n\t\t$complexNumber\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);\n\n\t\t$parsedComplex = self::_parseComplex($complexNumber);\n\t\treturn $parsedComplex['real'];\n\t}\t//\tfunction IMREAL()\n\n\n\t/**\n\t * IMABS\n\t *\n\t * Returns the absolute value (modulus) of a complex number in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMABS(complexNumber)\n\t *\n\t * @param\tstring\t\t$complexNumber\tThe complex number for which you want the absolute value.\n\t * @return\tfloat\n\t */\n\tpublic static function IMABS($complexNumber) {\n\t\t$complexNumber\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);\n\n\t\t$parsedComplex = self::_parseComplex($complexNumber);\n\n\t\treturn sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']));\n\t}\t//\tfunction IMABS()\n\n\n\t/**\n\t * IMARGUMENT\n\t *\n\t * Returns the argument theta of a complex number, i.e. the angle in radians from the real\n\t * axis to the representation of the number in polar coordinates.\n\t *\n\t * Excel Function:\n\t *\t\tIMARGUMENT(complexNumber)\n\t *\n\t * @param\tstring\t\t$complexNumber\tThe complex number for which you want the argument theta.\n\t * @return\tfloat\n\t */\n\tpublic static function IMARGUMENT($complexNumber) {\n\t\t$complexNumber\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);\n\n\t\t$parsedComplex = self::_parseComplex($complexNumber);\n\n\t\tif ($parsedComplex['real'] == 0.0) {\n\t\t\tif ($parsedComplex['imaginary'] == 0.0) {\n\t\t\t\treturn 0.0;\n\t\t\t} elseif($parsedComplex['imaginary'] < 0.0) {\n\t\t\t\treturn M_PI / -2;\n\t\t\t} else {\n\t\t\t\treturn M_PI / 2;\n\t\t\t}\n\t\t} elseif ($parsedComplex['real'] > 0.0) {\n\t\t\treturn atan($parsedComplex['imaginary'] / $parsedComplex['real']);\n\t\t} elseif ($parsedComplex['imaginary'] < 0.0) {\n\t\t\treturn 0 - (M_PI - atan(abs($parsedComplex['imaginary']) / abs($parsedComplex['real'])));\n\t\t} else {\n\t\t\treturn M_PI - atan($parsedComplex['imaginary'] / abs($parsedComplex['real']));\n\t\t}\n\t}\t//\tfunction IMARGUMENT()\n\n\n\t/**\n\t * IMCONJUGATE\n\t *\n\t * Returns the complex conjugate of a complex number in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMCONJUGATE(complexNumber)\n\t *\n\t * @param\tstring\t\t$complexNumber\tThe complex number for which you want the conjugate.\n\t * @return\tstring\n\t */\n\tpublic static function IMCONJUGATE($complexNumber) {\n\t\t$complexNumber\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);\n\n\t\t$parsedComplex = self::_parseComplex($complexNumber);\n\n\t\tif ($parsedComplex['imaginary'] == 0.0) {\n\t\t\treturn $parsedComplex['real'];\n\t\t} else {\n\t\t\treturn self::_cleanComplex( self::COMPLEX( $parsedComplex['real'],\n\t\t\t\t\t\t\t\t\t\t\t\t\t   0 - $parsedComplex['imaginary'],\n\t\t\t\t\t\t\t\t\t\t\t\t\t   $parsedComplex['suffix']\n\t\t\t\t\t\t\t\t\t\t\t\t\t )\n\t\t\t\t\t\t\t\t\t  );\n\t\t}\n\t}\t//\tfunction IMCONJUGATE()\n\n\n\t/**\n\t * IMCOS\n\t *\n\t * Returns the cosine of a complex number in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMCOS(complexNumber)\n\t *\n\t * @param\tstring\t\t$complexNumber\tThe complex number for which you want the cosine.\n\t * @return\tstring|float\n\t */\n\tpublic static function IMCOS($complexNumber) {\n\t\t$complexNumber\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);\n\n\t\t$parsedComplex = self::_parseComplex($complexNumber);\n\n\t\tif ($parsedComplex['imaginary'] == 0.0) {\n\t\t\treturn cos($parsedComplex['real']);\n\t\t} else {\n\t\t\treturn self::IMCONJUGATE(self::COMPLEX(cos($parsedComplex['real']) * cosh($parsedComplex['imaginary']),sin($parsedComplex['real']) * sinh($parsedComplex['imaginary']),$parsedComplex['suffix']));\n\t\t}\n\t}\t//\tfunction IMCOS()\n\n\n\t/**\n\t * IMSIN\n\t *\n\t * Returns the sine of a complex number in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMSIN(complexNumber)\n\t *\n\t * @param\tstring\t\t$complexNumber\tThe complex number for which you want the sine.\n\t * @return\tstring|float\n\t */\n\tpublic static function IMSIN($complexNumber) {\n\t\t$complexNumber\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);\n\n\t\t$parsedComplex = self::_parseComplex($complexNumber);\n\n\t\tif ($parsedComplex['imaginary'] == 0.0) {\n\t\t\treturn sin($parsedComplex['real']);\n\t\t} else {\n\t\t\treturn self::COMPLEX(sin($parsedComplex['real']) * cosh($parsedComplex['imaginary']),cos($parsedComplex['real']) * sinh($parsedComplex['imaginary']),$parsedComplex['suffix']);\n\t\t}\n\t}\t//\tfunction IMSIN()\n\n\n\t/**\n\t * IMSQRT\n\t *\n\t * Returns the square root of a complex number in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMSQRT(complexNumber)\n\t *\n\t * @param\tstring\t\t$complexNumber\tThe complex number for which you want the square root.\n\t * @return\tstring\n\t */\n\tpublic static function IMSQRT($complexNumber) {\n\t\t$complexNumber\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);\n\n\t\t$parsedComplex = self::_parseComplex($complexNumber);\n\n\t\t$theta = self::IMARGUMENT($complexNumber);\n\t\t$d1 = cos($theta / 2);\n\t\t$d2 = sin($theta / 2);\n\t\t$r = sqrt(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])));\n\n\t\tif ($parsedComplex['suffix'] == '') {\n\t\t\treturn self::COMPLEX($d1 * $r,$d2 * $r);\n\t\t} else {\n\t\t\treturn self::COMPLEX($d1 * $r,$d2 * $r,$parsedComplex['suffix']);\n\t\t}\n\t}\t//\tfunction IMSQRT()\n\n\n\t/**\n\t * IMLN\n\t *\n\t * Returns the natural logarithm of a complex number in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMLN(complexNumber)\n\t *\n\t * @param\tstring\t\t$complexNumber\tThe complex number for which you want the natural logarithm.\n\t * @return\tstring\n\t */\n\tpublic static function IMLN($complexNumber) {\n\t\t$complexNumber\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);\n\n\t\t$parsedComplex = self::_parseComplex($complexNumber);\n\n\t\tif (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t$logR = log(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])));\n\t\t$t = self::IMARGUMENT($complexNumber);\n\n\t\tif ($parsedComplex['suffix'] == '') {\n\t\t\treturn self::COMPLEX($logR,$t);\n\t\t} else {\n\t\t\treturn self::COMPLEX($logR,$t,$parsedComplex['suffix']);\n\t\t}\n\t}\t//\tfunction IMLN()\n\n\n\t/**\n\t * IMLOG10\n\t *\n\t * Returns the common logarithm (base 10) of a complex number in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMLOG10(complexNumber)\n\t *\n\t * @param\tstring\t\t$complexNumber\tThe complex number for which you want the common logarithm.\n\t * @return\tstring\n\t */\n\tpublic static function IMLOG10($complexNumber) {\n\t\t$complexNumber\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);\n\n\t\t$parsedComplex = self::_parseComplex($complexNumber);\n\n\t\tif (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t} elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) {\n\t\t\treturn log10($parsedComplex['real']);\n\t\t}\n\n\t\treturn self::IMPRODUCT(log10(EULER),self::IMLN($complexNumber));\n\t}\t//\tfunction IMLOG10()\n\n\n\t/**\n\t * IMLOG2\n\t *\n\t * Returns the base-2 logarithm of a complex number in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMLOG2(complexNumber)\n\t *\n\t * @param\tstring\t\t$complexNumber\tThe complex number for which you want the base-2 logarithm.\n\t * @return\tstring\n\t */\n\tpublic static function IMLOG2($complexNumber) {\n\t\t$complexNumber\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);\n\n\t\t$parsedComplex = self::_parseComplex($complexNumber);\n\n\t\tif (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t} elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) {\n\t\t\treturn log($parsedComplex['real'],2);\n\t\t}\n\n\t\treturn self::IMPRODUCT(log(EULER,2),self::IMLN($complexNumber));\n\t}\t//\tfunction IMLOG2()\n\n\n\t/**\n\t * IMEXP\n\t *\n\t * Returns the exponential of a complex number in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMEXP(complexNumber)\n\t *\n\t * @param\tstring\t\t$complexNumber\tThe complex number for which you want the exponential.\n\t * @return\tstring\n\t */\n\tpublic static function IMEXP($complexNumber) {\n\t\t$complexNumber\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);\n\n\t\t$parsedComplex = self::_parseComplex($complexNumber);\n\n\t\tif (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) {\n\t\t\treturn '1';\n\t\t}\n\n\t\t$e = exp($parsedComplex['real']);\n\t\t$eX = $e * cos($parsedComplex['imaginary']);\n\t\t$eY = $e * sin($parsedComplex['imaginary']);\n\n\t\tif ($parsedComplex['suffix'] == '') {\n\t\t\treturn self::COMPLEX($eX,$eY);\n\t\t} else {\n\t\t\treturn self::COMPLEX($eX,$eY,$parsedComplex['suffix']);\n\t\t}\n\t}\t//\tfunction IMEXP()\n\n\n\t/**\n\t * IMPOWER\n\t *\n\t * Returns a complex number in x + yi or x + yj text format raised to a power.\n\t *\n\t * Excel Function:\n\t *\t\tIMPOWER(complexNumber,realNumber)\n\t *\n\t * @param\tstring\t\t$complexNumber\tThe complex number you want to raise to a power.\n\t * @param\tfloat\t\t$realNumber\t\tThe power to which you want to raise the complex number.\n\t * @return\tstring\n\t */\n\tpublic static function IMPOWER($complexNumber,$realNumber) {\n\t\t$complexNumber\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber);\n\t\t$realNumber\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($realNumber);\n\n\t\tif (!is_numeric($realNumber)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t$parsedComplex = self::_parseComplex($complexNumber);\n\n\t\t$r = sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']));\n\t\t$rPower = pow($r,$realNumber);\n\t\t$theta = self::IMARGUMENT($complexNumber) * $realNumber;\n\t\tif ($theta == 0) {\n\t\t\treturn 1;\n\t\t} elseif ($parsedComplex['imaginary'] == 0.0) {\n\t\t\treturn self::COMPLEX($rPower * cos($theta),$rPower * sin($theta),$parsedComplex['suffix']);\n\t\t} else {\n\t\t\treturn self::COMPLEX($rPower * cos($theta),$rPower * sin($theta),$parsedComplex['suffix']);\n\t\t}\n\t}\t//\tfunction IMPOWER()\n\n\n\t/**\n\t * IMDIV\n\t *\n\t * Returns the quotient of two complex numbers in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMDIV(complexDividend,complexDivisor)\n\t *\n\t * @param\tstring\t\t$complexDividend\tThe complex numerator or dividend.\n\t * @param\tstring\t\t$complexDivisor\t\tThe complex denominator or divisor.\n\t * @return\tstring\n\t */\n\tpublic static function IMDIV($complexDividend,$complexDivisor) {\n\t\t$complexDividend\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexDividend);\n\t\t$complexDivisor\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexDivisor);\n\n\t\t$parsedComplexDividend = self::_parseComplex($complexDividend);\n\t\t$parsedComplexDivisor = self::_parseComplex($complexDivisor);\n\n\t\tif (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] != '') &&\n\t\t\t($parsedComplexDividend['suffix'] != $parsedComplexDivisor['suffix'])) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\tif (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] == '')) {\n\t\t\t$parsedComplexDivisor['suffix'] = $parsedComplexDividend['suffix'];\n\t\t}\n\n\t\t$d1 = ($parsedComplexDividend['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['imaginary']);\n\t\t$d2 = ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['real']) - ($parsedComplexDividend['real'] * $parsedComplexDivisor['imaginary']);\n\t\t$d3 = ($parsedComplexDivisor['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDivisor['imaginary'] * $parsedComplexDivisor['imaginary']);\n\n\t\t$r = $d1/$d3;\n\t\t$i = $d2/$d3;\n\n\t\tif ($i > 0.0) {\n\t\t\treturn self::_cleanComplex($r.'+'.$i.$parsedComplexDivisor['suffix']);\n\t\t} elseif ($i < 0.0) {\n\t\t\treturn self::_cleanComplex($r.$i.$parsedComplexDivisor['suffix']);\n\t\t} else {\n\t\t\treturn $r;\n\t\t}\n\t}\t//\tfunction IMDIV()\n\n\n\t/**\n\t * IMSUB\n\t *\n\t * Returns the difference of two complex numbers in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMSUB(complexNumber1,complexNumber2)\n\t *\n\t * @param\tstring\t\t$complexNumber1\t\tThe complex number from which to subtract complexNumber2.\n\t * @param\tstring\t\t$complexNumber2\t\tThe complex number to subtract from complexNumber1.\n\t * @return\tstring\n\t */\n\tpublic static function IMSUB($complexNumber1,$complexNumber2) {\n\t\t$complexNumber1\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber1);\n\t\t$complexNumber2\t= PHPExcel_Calculation_Functions::flattenSingleValue($complexNumber2);\n\n\t\t$parsedComplex1 = self::_parseComplex($complexNumber1);\n\t\t$parsedComplex2 = self::_parseComplex($complexNumber2);\n\n\t\tif ((($parsedComplex1['suffix'] != '') && ($parsedComplex2['suffix'] != '')) &&\n\t\t\t($parsedComplex1['suffix'] != $parsedComplex2['suffix'])) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t} elseif (($parsedComplex1['suffix'] == '') && ($parsedComplex2['suffix'] != '')) {\n\t\t\t$parsedComplex1['suffix'] = $parsedComplex2['suffix'];\n\t\t}\n\n\t\t$d1 = $parsedComplex1['real'] - $parsedComplex2['real'];\n\t\t$d2 = $parsedComplex1['imaginary'] - $parsedComplex2['imaginary'];\n\n\t\treturn self::COMPLEX($d1,$d2,$parsedComplex1['suffix']);\n\t}\t//\tfunction IMSUB()\n\n\n\t/**\n\t * IMSUM\n\t *\n\t * Returns the sum of two or more complex numbers in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMSUM(complexNumber[,complexNumber[,...]])\n\t *\n\t * @param\tstring\t\t$complexNumber,...\tSeries of complex numbers to add\n\t * @return\tstring\n\t */\n\tpublic static function IMSUM() {\n\t\t// Return value\n\t\t$returnValue = self::_parseComplex('0');\n\t\t$activeSuffix = '';\n\n\t\t// Loop through the arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\tforeach ($aArgs as $arg) {\n\t\t\t$parsedComplex = self::_parseComplex($arg);\n\n\t\t\tif ($activeSuffix == '') {\n\t\t\t\t$activeSuffix = $parsedComplex['suffix'];\n\t\t\t} elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\n\t\t\t$returnValue['real'] += $parsedComplex['real'];\n\t\t\t$returnValue['imaginary'] += $parsedComplex['imaginary'];\n\t\t}\n\n\t\tif ($returnValue['imaginary'] == 0.0) { $activeSuffix = ''; }\n\t\treturn self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix);\n\t}\t//\tfunction IMSUM()\n\n\n\t/**\n\t * IMPRODUCT\n\t *\n\t * Returns the product of two or more complex numbers in x + yi or x + yj text format.\n\t *\n\t * Excel Function:\n\t *\t\tIMPRODUCT(complexNumber[,complexNumber[,...]])\n\t *\n\t * @param\tstring\t\t$complexNumber,...\tSeries of complex numbers to multiply\n\t * @return\tstring\n\t */\n\tpublic static function IMPRODUCT() {\n\t\t// Return value\n\t\t$returnValue = self::_parseComplex('1');\n\t\t$activeSuffix = '';\n\n\t\t// Loop through the arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\tforeach ($aArgs as $arg) {\n\t\t\t$parsedComplex = self::_parseComplex($arg);\n\n\t\t\t$workValue = $returnValue;\n\t\t\tif (($parsedComplex['suffix'] != '') && ($activeSuffix == '')) {\n\t\t\t\t$activeSuffix = $parsedComplex['suffix'];\n\t\t\t} elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$returnValue['real'] = ($workValue['real'] * $parsedComplex['real']) - ($workValue['imaginary'] * $parsedComplex['imaginary']);\n\t\t\t$returnValue['imaginary'] = ($workValue['real'] * $parsedComplex['imaginary']) + ($workValue['imaginary'] * $parsedComplex['real']);\n\t\t}\n\n\t\tif ($returnValue['imaginary'] == 0.0) { $activeSuffix = ''; }\n\t\treturn self::COMPLEX($returnValue['real'],$returnValue['imaginary'],$activeSuffix);\n\t}\t//\tfunction IMPRODUCT()\n\n\n\t/**\n\t *\tDELTA\n\t *\n\t *\tTests whether two values are equal. Returns 1 if number1 = number2; returns 0 otherwise.\n\t *\tUse this function to filter a set of values. For example, by summing several DELTA\n\t *\tfunctions you calculate the count of equal pairs. This function is also known as the\n\t *\tKronecker Delta function.\n\t *\n\t *\tExcel Function:\n\t *\t\tDELTA(a[,b])\n\t *\n\t *\t@param\tfloat\t\t$a\tThe first number.\n\t *\t@param\tfloat\t\t$b\tThe second number. If omitted, b is assumed to be zero.\n\t *\t@return\tint\n\t */\n\tpublic static function DELTA($a, $b=0) {\n\t\t$a\t= PHPExcel_Calculation_Functions::flattenSingleValue($a);\n\t\t$b\t= PHPExcel_Calculation_Functions::flattenSingleValue($b);\n\n\t\treturn (int) ($a == $b);\n\t}\t//\tfunction DELTA()\n\n\n\t/**\n\t *\tGESTEP\n\t *\n\t *\tExcel Function:\n\t *\t\tGESTEP(number[,step])\n\t *\n\t *\tReturns 1 if number >= step; returns 0 (zero) otherwise\n\t *\tUse this function to filter a set of values. For example, by summing several GESTEP\n\t *\tfunctions you calculate the count of values that exceed a threshold.\n\t *\n\t *\t@param\tfloat\t\t$number\t\tThe value to test against step.\n\t *\t@param\tfloat\t\t$step\t\tThe threshold value.\n\t *\t\t\t\t\t\t\t\t\tIf you omit a value for step, GESTEP uses zero.\n\t *\t@return\tint\n\t */\n\tpublic static function GESTEP($number, $step=0) {\n\t\t$number\t= PHPExcel_Calculation_Functions::flattenSingleValue($number);\n\t\t$step\t= PHPExcel_Calculation_Functions::flattenSingleValue($step);\n\n\t\treturn (int) ($number >= $step);\n\t}\t//\tfunction GESTEP()\n\n\n\t//\n\t//\tPrivate method to calculate the erf value\n\t//\n\tprivate static $_two_sqrtpi = 1.128379167095512574;\n\n\tpublic static function _erfVal($x) {\n\t\tif (abs($x) > 2.2) {\n\t\t\treturn 1 - self::_erfcVal($x);\n\t\t}\n\t\t$sum = $term = $x;\n\t\t$xsqr = ($x * $x);\n\t\t$j = 1;\n\t\tdo {\n\t\t\t$term *= $xsqr / $j;\n\t\t\t$sum -= $term / (2 * $j + 1);\n\t\t\t++$j;\n\t\t\t$term *= $xsqr / $j;\n\t\t\t$sum += $term / (2 * $j + 1);\n\t\t\t++$j;\n\t\t\tif ($sum == 0.0) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t} while (abs($term / $sum) > PRECISION);\n\t\treturn self::$_two_sqrtpi * $sum;\n\t}\t//\tfunction _erfVal()\n\n\n\t/**\n\t *\tERF\n\t *\n\t *\tReturns the error function integrated between the lower and upper bound arguments.\n\t *\n\t *\tNote: In Excel 2007 or earlier, if you input a negative value for the upper or lower bound arguments,\n\t *\t\t\tthe function would return a #NUM! error. However, in Excel 2010, the function algorithm was\n\t *\t\t\timproved, so that it can now calculate the function for both positive and negative ranges.\n\t *\t\t\tPHPExcel follows Excel 2010 behaviour, and accepts nagative arguments.\n\t *\n\t *\tExcel Function:\n\t *\t\tERF(lower[,upper])\n\t *\n\t *\t@param\tfloat\t\t$lower\tlower bound for integrating ERF\n\t *\t@param\tfloat\t\t$upper\tupper bound for integrating ERF.\n\t *\t\t\t\t\t\t\t\tIf omitted, ERF integrates between zero and lower_limit\n\t *\t@return\tfloat\n\t */\n\tpublic static function ERF($lower, $upper = NULL) {\n\t\t$lower\t= PHPExcel_Calculation_Functions::flattenSingleValue($lower);\n\t\t$upper\t= PHPExcel_Calculation_Functions::flattenSingleValue($upper);\n\n\t\tif (is_numeric($lower)) {\n\t\t\tif (is_null($upper)) {\n\t\t\t\treturn self::_erfVal($lower);\n\t\t\t}\n\t\t\tif (is_numeric($upper)) {\n\t\t\t\treturn self::_erfVal($upper) - self::_erfVal($lower);\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction ERF()\n\n\n\t//\n\t//\tPrivate method to calculate the erfc value\n\t//\n\tprivate static $_one_sqrtpi = 0.564189583547756287;\n\n\tprivate static function _erfcVal($x) {\n\t\tif (abs($x) < 2.2) {\n\t\t\treturn 1 - self::_erfVal($x);\n\t\t}\n\t\tif ($x < 0) {\n\t\t\treturn 2 - self::ERFC(-$x);\n\t\t}\n\t\t$a = $n = 1;\n\t\t$b = $c = $x;\n\t\t$d = ($x * $x) + 0.5;\n\t\t$q1 = $q2 = $b / $d;\n\t\t$t = 0;\n\t\tdo {\n\t\t\t$t = $a * $n + $b * $x;\n\t\t\t$a = $b;\n\t\t\t$b = $t;\n\t\t\t$t = $c * $n + $d * $x;\n\t\t\t$c = $d;\n\t\t\t$d = $t;\n\t\t\t$n += 0.5;\n\t\t\t$q1 = $q2;\n\t\t\t$q2 = $b / $d;\n\t\t} while ((abs($q1 - $q2) / $q2) > PRECISION);\n\t\treturn self::$_one_sqrtpi * exp(-$x * $x) * $q2;\n\t}\t//\tfunction _erfcVal()\n\n\n\t/**\n\t *\tERFC\n\t *\n\t *\tReturns the complementary ERF function integrated between x and infinity\n\t *\n\t *\tNote: In Excel 2007 or earlier, if you input a negative value for the lower bound argument,\n\t *\t\tthe function would return a #NUM! error. However, in Excel 2010, the function algorithm was\n\t *\t\timproved, so that it can now calculate the function for both positive and negative x values.\n\t *\t\t\tPHPExcel follows Excel 2010 behaviour, and accepts nagative arguments.\n\t *\n\t *\tExcel Function:\n\t *\t\tERFC(x)\n\t *\n\t *\t@param\tfloat\t$x\tThe lower bound for integrating ERFC\n\t *\t@return\tfloat\n\t */\n\tpublic static function ERFC($x) {\n\t\t$x = PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\n\t\tif (is_numeric($x)) {\n\t\t\treturn self::_erfcVal($x);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction ERFC()\n\n\n\t/**\n\t *\tgetConversionGroups\n\t *\tReturns a list of the different conversion groups for UOM conversions\n\t *\n\t *\t@return\tarray\n\t */\n\tpublic static function getConversionGroups() {\n\t\t$conversionGroups = array();\n\t\tforeach(self::$_conversionUnits as $conversionUnit) {\n\t\t\t$conversionGroups[] = $conversionUnit['Group'];\n\t\t}\n\t\treturn array_merge(array_unique($conversionGroups));\n\t}\t//\tfunction getConversionGroups()\n\n\n\t/**\n\t *\tgetConversionGroupUnits\n\t *\tReturns an array of units of measure, for a specified conversion group, or for all groups\n\t *\n\t *\t@param\tstring\t$group\tThe group whose units of measure you want to retrieve\n\t *\t@return\tarray\n\t */\n\tpublic static function getConversionGroupUnits($group = NULL) {\n\t\t$conversionGroups = array();\n\t\tforeach(self::$_conversionUnits as $conversionUnit => $conversionGroup) {\n\t\t\tif ((is_null($group)) || ($conversionGroup['Group'] == $group)) {\n\t\t\t\t$conversionGroups[$conversionGroup['Group']][] = $conversionUnit;\n\t\t\t}\n\t\t}\n\t\treturn $conversionGroups;\n\t}\t//\tfunction getConversionGroupUnits()\n\n\n\t/**\n\t *\tgetConversionGroupUnitDetails\n\t *\n\t *\t@param\tstring\t$group\tThe group whose units of measure you want to retrieve\n\t *\t@return\tarray\n\t */\n\tpublic static function getConversionGroupUnitDetails($group = NULL) {\n\t\t$conversionGroups = array();\n\t\tforeach(self::$_conversionUnits as $conversionUnit => $conversionGroup) {\n\t\t\tif ((is_null($group)) || ($conversionGroup['Group'] == $group)) {\n\t\t\t\t$conversionGroups[$conversionGroup['Group']][] = array(\t'unit'\t\t\t=> $conversionUnit,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'description'\t=> $conversionGroup['Unit Name']\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  );\n\t\t\t}\n\t\t}\n\t\treturn $conversionGroups;\n\t}\t//\tfunction getConversionGroupUnitDetails()\n\n\n\t/**\n\t *\tgetConversionMultipliers\n\t *\tReturns an array of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM()\n\t *\n\t *\t@return\tarray of mixed\n\t */\n\tpublic static function getConversionMultipliers() {\n\t\treturn self::$_conversionMultipliers;\n\t}\t//\tfunction getConversionGroups()\n\n\n\t/**\n\t *\tCONVERTUOM\n\t *\n\t *\tConverts a number from one measurement system to another.\n\t *\tFor example, CONVERT can translate a table of distances in miles to a table of distances\n\t *\tin kilometers.\n\t *\n\t *\tExcel Function:\n\t *\t\tCONVERT(value,fromUOM,toUOM)\n\t *\n\t *\t@param\tfloat\t\t$value\t\tThe value in fromUOM to convert.\n\t *\t@param\tstring\t\t$fromUOM\tThe units for value.\n\t *\t@param\tstring\t\t$toUOM\t\tThe units for the result.\n\t *\n\t *\t@return\tfloat\n\t */\n\tpublic static function CONVERTUOM($value, $fromUOM, $toUOM) {\n\t\t$value\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$fromUOM\t= PHPExcel_Calculation_Functions::flattenSingleValue($fromUOM);\n\t\t$toUOM\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($toUOM);\n\n\t\tif (!is_numeric($value)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$fromMultiplier = 1.0;\n\t\tif (isset(self::$_conversionUnits[$fromUOM])) {\n\t\t\t$unitGroup1 = self::$_conversionUnits[$fromUOM]['Group'];\n\t\t} else {\n\t\t\t$fromMultiplier = substr($fromUOM,0,1);\n\t\t\t$fromUOM = substr($fromUOM,1);\n\t\t\tif (isset(self::$_conversionMultipliers[$fromMultiplier])) {\n\t\t\t\t$fromMultiplier = self::$_conversionMultipliers[$fromMultiplier]['multiplier'];\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t\t}\n\t\t\tif ((isset(self::$_conversionUnits[$fromUOM])) && (self::$_conversionUnits[$fromUOM]['AllowPrefix'])) {\n\t\t\t\t$unitGroup1 = self::$_conversionUnits[$fromUOM]['Group'];\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t\t}\n\t\t}\n\t\t$value *= $fromMultiplier;\n\n\t\t$toMultiplier = 1.0;\n\t\tif (isset(self::$_conversionUnits[$toUOM])) {\n\t\t\t$unitGroup2 = self::$_conversionUnits[$toUOM]['Group'];\n\t\t} else {\n\t\t\t$toMultiplier = substr($toUOM,0,1);\n\t\t\t$toUOM = substr($toUOM,1);\n\t\t\tif (isset(self::$_conversionMultipliers[$toMultiplier])) {\n\t\t\t\t$toMultiplier = self::$_conversionMultipliers[$toMultiplier]['multiplier'];\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t\t}\n\t\t\tif ((isset(self::$_conversionUnits[$toUOM])) && (self::$_conversionUnits[$toUOM]['AllowPrefix'])) {\n\t\t\t\t$unitGroup2 = self::$_conversionUnits[$toUOM]['Group'];\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t\t}\n\t\t}\n\t\tif ($unitGroup1 != $unitGroup2) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t}\n\n\t\tif (($fromUOM == $toUOM) && ($fromMultiplier == $toMultiplier)) {\n\t\t\t//\tWe've already factored $fromMultiplier into the value, so we need\n\t\t\t//\t\tto reverse it again\n\t\t\treturn $value / $fromMultiplier;\n\t\t} elseif ($unitGroup1 == 'Temperature') {\n\t\t\tif (($fromUOM == 'F') || ($fromUOM == 'fah')) {\n\t\t\t\tif (($toUOM == 'F') || ($toUOM == 'fah')) {\n\t\t\t\t\treturn $value;\n\t\t\t\t} else {\n\t\t\t\t\t$value = (($value - 32) / 1.8);\n\t\t\t\t\tif (($toUOM == 'K') || ($toUOM == 'kel')) {\n\t\t\t\t\t\t$value += 273.15;\n\t\t\t\t\t}\n\t\t\t\t\treturn $value;\n\t\t\t\t}\n\t\t\t} elseif ((($fromUOM == 'K') || ($fromUOM == 'kel')) &&\n\t\t\t\t\t  (($toUOM == 'K') || ($toUOM == 'kel'))) {\n\t\t\t\t\t\treturn $value;\n\t\t\t} elseif ((($fromUOM == 'C') || ($fromUOM == 'cel')) &&\n\t\t\t\t\t  (($toUOM == 'C') || ($toUOM == 'cel'))) {\n\t\t\t\t\treturn $value;\n\t\t\t}\n\t\t\tif (($toUOM == 'F') || ($toUOM == 'fah')) {\n\t\t\t\tif (($fromUOM == 'K') || ($fromUOM == 'kel')) {\n\t\t\t\t\t$value -= 273.15;\n\t\t\t\t}\n\t\t\t\treturn ($value * 1.8) + 32;\n\t\t\t}\n\t\t\tif (($toUOM == 'C') || ($toUOM == 'cel')) {\n\t\t\t\treturn $value - 273.15;\n\t\t\t}\n\t\t\treturn $value + 273.15;\n\t\t}\n\t\treturn ($value * self::$_unitConversions[$unitGroup1][$fromUOM][$toUOM]) / $toMultiplier;\n\t}\t//\tfunction CONVERTUOM()\n\n}\t//\tclass PHPExcel_Calculation_Engineering\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Exception.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Calculation_Exception\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_Exception extends PHPExcel_Exception {\n\t/**\n\t * Error handler callback\n\t *\n\t * @param mixed $code\n\t * @param mixed $string\n\t * @param mixed $file\n\t * @param mixed $line\n\t * @param mixed $context\n\t */\n\tpublic static function errorHandlerCallback($code, $string, $file, $line, $context) {\n\t\t$e = new self($string, $code);\n\t\t$e->line = $line;\n\t\t$e->file = $file;\n\t\tthrow $e;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/ExceptionHandler.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Calculation_ExceptionHandler\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_ExceptionHandler {\n\t/**\n\t * Register errorhandler\n\t */\n\tpublic function __construct() {\n\t\tset_error_handler(array('PHPExcel_Calculation_Exception', 'errorHandlerCallback'), E_ALL);\n\t}\n\n\t/**\n\t * Unregister errorhandler\n\t */\n\tpublic function __destruct() {\n\t\trestore_error_handler();\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Financial.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\n/** FINANCIAL_MAX_ITERATIONS */\ndefine('FINANCIAL_MAX_ITERATIONS', 128);\n\n/** FINANCIAL_PRECISION */\ndefine('FINANCIAL_PRECISION', 1.0e-08);\n\n\n/**\n * PHPExcel_Calculation_Financial\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_Financial {\n\n\t/**\n\t * _lastDayOfMonth\n\t *\n\t * Returns a boolean TRUE/FALSE indicating if this date is the last date of the month\n\t *\n\t * @param\tDateTime\t$testDate\tThe date for testing\n\t * @return\tboolean\n\t */\n\tprivate static function _lastDayOfMonth($testDate)\n\t{\n\t\treturn ($testDate->format('d') == $testDate->format('t'));\n\t}\t//\tfunction _lastDayOfMonth()\n\n\n\t/**\n\t * _firstDayOfMonth\n\t *\n\t * Returns a boolean TRUE/FALSE indicating if this date is the first date of the month\n\t *\n\t * @param\tDateTime\t$testDate\tThe date for testing\n\t * @return\tboolean\n\t */\n\tprivate static function _firstDayOfMonth($testDate)\n\t{\n\t\treturn ($testDate->format('d') == 1);\n\t}\t//\tfunction _firstDayOfMonth()\n\n\n\tprivate static function _coupFirstPeriodDate($settlement, $maturity, $frequency, $next)\n\t{\n\t\t$months = 12 / $frequency;\n\n\t\t$result = PHPExcel_Shared_Date::ExcelToPHPObject($maturity);\n\t\t$eom = self::_lastDayOfMonth($result);\n\n\t\twhile ($settlement < PHPExcel_Shared_Date::PHPToExcel($result)) {\n\t\t\t$result->modify('-'.$months.' months');\n\t\t}\n\t\tif ($next) {\n\t\t\t$result->modify('+'.$months.' months');\n\t\t}\n\n\t\tif ($eom) {\n\t\t\t$result->modify('-1 day');\n\t\t}\n\n\t\treturn PHPExcel_Shared_Date::PHPToExcel($result);\n\t}\t//\tfunction _coupFirstPeriodDate()\n\n\n\tprivate static function _validFrequency($frequency)\n\t{\n\t\tif (($frequency == 1) || ($frequency == 2) || ($frequency == 4)) {\n\t\t\treturn true;\n\t\t}\n\t\tif ((PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) &&\n\t\t\t(($frequency == 6) || ($frequency == 12))) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\t//\tfunction _validFrequency()\n\n\n\t/**\n\t * _daysPerYear\n\t *\n\t * Returns the number of days in a specified year, as defined by the \"basis\" value\n\t *\n\t * @param\tinteger\t\t$year\tThe year against which we're testing\n\t * @param   integer\t\t$basis\tThe type of day count:\n\t *\t\t\t\t\t\t\t\t\t0 or omitted US (NASD)\t360\n\t *\t\t\t\t\t\t\t\t\t1\t\t\t\t\t\tActual (365 or 366 in a leap year)\n\t *\t\t\t\t\t\t\t\t\t2\t\t\t\t\t\t360\n\t *\t\t\t\t\t\t\t\t\t3\t\t\t\t\t\t365\n\t *\t\t\t\t\t\t\t\t\t4\t\t\t\t\t\tEuropean 360\n\t * @return\tinteger\n\t */\n\tprivate static function _daysPerYear($year, $basis=0)\n\t{\n\t\tswitch ($basis) {\n\t\t\tcase 0 :\n\t\t\tcase 2 :\n\t\t\tcase 4 :\n\t\t\t\t$daysPerYear = 360;\n\t\t\t\tbreak;\n\t\t\tcase 3 :\n\t\t\t\t$daysPerYear = 365;\n\t\t\t\tbreak;\n\t\t\tcase 1 :\n\t\t\t\t$daysPerYear = (PHPExcel_Calculation_DateTime::_isLeapYear($year)) ? 366 : 365;\n\t\t\t\tbreak;\n\t\t\tdefault\t:\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\treturn $daysPerYear;\n\t}\t//\tfunction _daysPerYear()\n\n\n\tprivate static function _interestAndPrincipal($rate=0, $per=0, $nper=0, $pv=0, $fv=0, $type=0)\n\t{\n\t\t$pmt = self::PMT($rate, $nper, $pv, $fv, $type);\n\t\t$capital = $pv;\n\t\tfor ($i = 1; $i<= $per; ++$i) {\n\t\t\t$interest = ($type && $i == 1) ? 0 : -$capital * $rate;\n\t\t\t$principal = $pmt - $interest;\n\t\t\t$capital += $principal;\n\t\t}\n\t\treturn array($interest, $principal);\n\t}\t//\tfunction _interestAndPrincipal()\n\n\n\t/**\n\t * ACCRINT\n\t *\n\t * Returns the accrued interest for a security that pays periodic interest.\n\t *\n\t * Excel Function:\n\t *\t\tACCRINT(issue,firstinterest,settlement,rate,par,frequency[,basis])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tmixed\t$issue\t\t\tThe security's issue date.\n\t * @param\tmixed\t$firstinterest\tThe security's first interest date.\n\t * @param\tmixed\t$settlement\t\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\t\tThe security settlement date is the date after the issue date\n\t *\t\t\t\t\t\t\t\t\twhen the security is traded to the buyer.\n\t * @param\tfloat\t$rate\t\t\tThe security's annual coupon rate.\n\t * @param\tfloat\t$par\t\t\tThe security's par value.\n\t *\t\t\t\t\t\t\t\t\tIf you omit par, ACCRINT uses $1,000.\n\t * @param\tinteger\t$frequency\t\tthe number of coupon payments per year.\n\t *\t\t\t\t\t\t\t\t\tValid frequency values are:\n\t *\t\t\t\t\t\t\t\t\t\t1\tAnnual\n\t *\t\t\t\t\t\t\t\t\t\t2\tSemi-Annual\n\t *\t\t\t\t\t\t\t\t\t\t4\tQuarterly\n\t *\t\t\t\t\t\t\t\t\tIf working in Gnumeric Mode, the following frequency options are\n\t *\t\t\t\t\t\t\t\t\talso available\n\t *\t\t\t\t\t\t\t\t\t\t6\tBimonthly\n\t *\t\t\t\t\t\t\t\t\t\t12\tMonthly\n\t * @param\tinteger\t$basis\t\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function ACCRINT($issue, $firstinterest, $settlement, $rate, $par=1000, $frequency=1, $basis=0)\n\t{\n\t\t$issue\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($issue);\n\t\t$firstinterest\t= PHPExcel_Calculation_Functions::flattenSingleValue($firstinterest);\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$rate\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$par\t\t= (is_null($par))\t\t? 1000 :\tPHPExcel_Calculation_Functions::flattenSingleValue($par);\n\t\t$frequency\t= (is_null($frequency))\t? 1\t: \t\tPHPExcel_Calculation_Functions::flattenSingleValue($frequency);\n\t\t$basis\t\t= (is_null($basis))\t\t? 0\t:\t\tPHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\t//\tValidate\n\t\tif ((is_numeric($rate)) && (is_numeric($par))) {\n\t\t\t$rate\t= (float) $rate;\n\t\t\t$par\t= (float) $par;\n\t\t\tif (($rate <= 0) || ($par <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis);\n\t\t\tif (!is_numeric($daysBetweenIssueAndSettlement)) {\n\t\t\t\t//\treturn date error\n\t\t\t\treturn $daysBetweenIssueAndSettlement;\n\t\t\t}\n\n\t\t\treturn $par * $rate * $daysBetweenIssueAndSettlement;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction ACCRINT()\n\n\n\t/**\n\t * ACCRINTM\n\t *\n\t * Returns the accrued interest for a security that pays interest at maturity.\n\t *\n\t * Excel Function:\n\t *\t\tACCRINTM(issue,settlement,rate[,par[,basis]])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tmixed\tissue\t\tThe security's issue date.\n\t * @param\tmixed\tsettlement\tThe security's settlement (or maturity) date.\n\t * @param\tfloat\trate\t\tThe security's annual coupon rate.\n\t * @param\tfloat\tpar\t\t\tThe security's par value.\n\t *\t\t\t\t\t\t\t\t\tIf you omit par, ACCRINT uses $1,000.\n\t * @param\tinteger\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function ACCRINTM($issue, $settlement, $rate, $par=1000, $basis=0) {\n\t\t$issue\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($issue);\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$rate\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$par\t\t= (is_null($par))\t? 1000 :\tPHPExcel_Calculation_Functions::flattenSingleValue($par);\n\t\t$basis\t\t= (is_null($basis))\t? 0 :\t\tPHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\t//\tValidate\n\t\tif ((is_numeric($rate)) && (is_numeric($par))) {\n\t\t\t$rate\t= (float) $rate;\n\t\t\t$par\t= (float) $par;\n\t\t\tif (($rate <= 0) || ($par <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis);\n\t\t\tif (!is_numeric($daysBetweenIssueAndSettlement)) {\n\t\t\t\t//\treturn date error\n\t\t\t\treturn $daysBetweenIssueAndSettlement;\n\t\t\t}\n\t\t\treturn $par * $rate * $daysBetweenIssueAndSettlement;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction ACCRINTM()\n\n\n\t/**\n\t * AMORDEGRC\n\t *\n\t * Returns the depreciation for each accounting period.\n\t * This function is provided for the French accounting system. If an asset is purchased in\n\t * the middle of the accounting period, the prorated depreciation is taken into account.\n\t * The function is similar to AMORLINC, except that a depreciation coefficient is applied in\n\t * the calculation depending on the life of the assets.\n\t * This function will return the depreciation until the last period of the life of the assets\n\t * or until the cumulated value of depreciation is greater than the cost of the assets minus\n\t * the salvage value.\n\t *\n\t * Excel Function:\n\t *\t\tAMORDEGRC(cost,purchased,firstPeriod,salvage,period,rate[,basis])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tfloat\tcost\t\tThe cost of the asset.\n\t * @param\tmixed\tpurchased\tDate of the purchase of the asset.\n\t * @param\tmixed\tfirstPeriod\tDate of the end of the first period.\n\t * @param\tmixed\tsalvage\t\tThe salvage value at the end of the life of the asset.\n\t * @param\tfloat\tperiod\t\tThe period.\n\t * @param\tfloat\trate\t\tRate of depreciation.\n\t * @param\tinteger\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function AMORDEGRC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis=0) {\n\t\t$cost\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($cost);\n\t\t$purchased\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($purchased);\n\t\t$firstPeriod\t= PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod);\n\t\t$salvage\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($salvage);\n\t\t$period\t\t\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($period));\n\t\t$rate\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$basis\t\t\t= (is_null($basis))\t? 0 :\t(int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\t//\tThe depreciation coefficients are:\n\t\t//\tLife of assets (1/rate)\t\tDepreciation coefficient\n\t\t//\tLess than 3 years\t\t\t1\n\t\t//\tBetween 3 and 4 years\t\t1.5\n\t\t//\tBetween 5 and 6 years\t\t2\n\t\t//\tMore than 6 years\t\t\t2.5\n\t\t$fUsePer = 1.0 / $rate;\n\t\tif ($fUsePer < 3.0) {\n\t\t\t$amortiseCoeff = 1.0;\n\t\t} elseif ($fUsePer < 5.0) {\n\t\t\t$amortiseCoeff = 1.5;\n\t\t} elseif ($fUsePer <= 6.0) {\n\t\t\t$amortiseCoeff = 2.0;\n\t\t} else {\n\t\t\t$amortiseCoeff = 2.5;\n\t\t}\n\n\t\t$rate *= $amortiseCoeff;\n\t\t$fNRate = round(PHPExcel_Calculation_DateTime::YEARFRAC($purchased, $firstPeriod, $basis) * $rate * $cost,0);\n\t\t$cost -= $fNRate;\n\t\t$fRest = $cost - $salvage;\n\n\t\tfor ($n = 0; $n < $period; ++$n) {\n\t\t\t$fNRate = round($rate * $cost,0);\n\t\t\t$fRest -= $fNRate;\n\n\t\t\tif ($fRest < 0.0) {\n\t\t\t\tswitch ($period - $n) {\n\t\t\t\t\tcase 0\t:\n\t\t\t\t\tcase 1\t: return round($cost * 0.5, 0);\n\t\t\t\t\t\t\t  break;\n\t\t\t\t\tdefault\t: return 0.0;\n\t\t\t\t\t\t\t  break;\n\t\t\t\t}\n\t\t\t}\n\t\t\t$cost -= $fNRate;\n\t\t}\n\t\treturn $fNRate;\n\t}\t//\tfunction AMORDEGRC()\n\n\n\t/**\n\t * AMORLINC\n\t *\n\t * Returns the depreciation for each accounting period.\n\t * This function is provided for the French accounting system. If an asset is purchased in\n\t * the middle of the accounting period, the prorated depreciation is taken into account.\n\t *\n\t * Excel Function:\n\t *\t\tAMORLINC(cost,purchased,firstPeriod,salvage,period,rate[,basis])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tfloat\tcost\t\tThe cost of the asset.\n\t * @param\tmixed\tpurchased\tDate of the purchase of the asset.\n\t * @param\tmixed\tfirstPeriod\tDate of the end of the first period.\n\t * @param\tmixed\tsalvage\t\tThe salvage value at the end of the life of the asset.\n\t * @param\tfloat\tperiod\t\tThe period.\n\t * @param\tfloat\trate\t\tRate of depreciation.\n\t * @param\tinteger\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function AMORLINC($cost, $purchased, $firstPeriod, $salvage, $period, $rate, $basis=0) {\n\t\t$cost\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($cost);\n\t\t$purchased\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($purchased);\n\t\t$firstPeriod\t= PHPExcel_Calculation_Functions::flattenSingleValue($firstPeriod);\n\t\t$salvage\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($salvage);\n\t\t$period\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($period);\n\t\t$rate\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$basis\t\t\t= (is_null($basis))\t? 0 :\t(int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\t$fOneRate = $cost * $rate;\n\t\t$fCostDelta = $cost - $salvage;\n\t\t//\tNote, quirky variation for leap years on the YEARFRAC for this function\n\t\t$purchasedYear = PHPExcel_Calculation_DateTime::YEAR($purchased);\n\t\t$yearFrac = PHPExcel_Calculation_DateTime::YEARFRAC($purchased, $firstPeriod, $basis);\n\n\t\tif (($basis == 1) && ($yearFrac < 1) && (PHPExcel_Calculation_DateTime::_isLeapYear($purchasedYear))) {\n\t\t\t$yearFrac *= 365 / 366;\n\t\t}\n\n\t\t$f0Rate = $yearFrac * $rate * $cost;\n\t\t$nNumOfFullPeriods = intval(($cost - $salvage - $f0Rate) / $fOneRate);\n\n\t\tif ($period == 0) {\n\t\t\treturn $f0Rate;\n\t\t} elseif ($period <= $nNumOfFullPeriods) {\n\t\t\treturn $fOneRate;\n\t\t} elseif ($period == ($nNumOfFullPeriods + 1)) {\n            return ($fCostDelta - $fOneRate * $nNumOfFullPeriods - $f0Rate);\n\t\t} else {\n\t\t\treturn 0.0;\n\t\t}\n\t}\t//\tfunction AMORLINC()\n\n\n\t/**\n\t * COUPDAYBS\n\t *\n\t * Returns the number of days from the beginning of the coupon period to the settlement date.\n\t *\n\t * Excel Function:\n\t *\t\tCOUPDAYBS(settlement,maturity,frequency[,basis])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tmixed\tsettlement\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\tThe security settlement date is the date after the issue\n\t *\t\t\t\t\t\t\t\tdate when the security is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe security's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the security expires.\n\t * @param\tmixed\tfrequency\tthe number of coupon payments per year.\n\t *\t\t\t\t\t\t\t\t\tValid frequency values are:\n\t *\t\t\t\t\t\t\t\t\t\t1\tAnnual\n\t *\t\t\t\t\t\t\t\t\t\t2\tSemi-Annual\n\t *\t\t\t\t\t\t\t\t\t\t4\tQuarterly\n\t *\t\t\t\t\t\t\t\t\tIf working in Gnumeric Mode, the following frequency options are\n\t *\t\t\t\t\t\t\t\t\talso available\n\t *\t\t\t\t\t\t\t\t\t\t6\tBimonthly\n\t *\t\t\t\t\t\t\t\t\t\t12\tMonthly\n\t * @param\tinteger\t\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function COUPDAYBS($settlement, $maturity, $frequency, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$frequency\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);\n\t\t$basis\t\t= (is_null($basis))\t? 0 :\t(int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\tif (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\tif (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (($settlement > $maturity) ||\n\t\t\t(!self::_validFrequency($frequency)) ||\n\t\t\t(($basis < 0) || ($basis > 4))) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t$daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis);\n\t\t$prev = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False);\n\n\t\treturn PHPExcel_Calculation_DateTime::YEARFRAC($prev, $settlement, $basis) * $daysPerYear;\n\t}\t//\tfunction COUPDAYBS()\n\n\n\t/**\n\t * COUPDAYS\n\t *\n\t * Returns the number of days in the coupon period that contains the settlement date.\n\t *\n\t * Excel Function:\n\t *\t\tCOUPDAYS(settlement,maturity,frequency[,basis])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tmixed\tsettlement\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\tThe security settlement date is the date after the issue\n\t *\t\t\t\t\t\t\t\tdate when the security is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe security's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the security expires.\n\t * @param\tmixed\tfrequency\tthe number of coupon payments per year.\n\t *\t\t\t\t\t\t\t\t\tValid frequency values are:\n\t *\t\t\t\t\t\t\t\t\t\t1\tAnnual\n\t *\t\t\t\t\t\t\t\t\t\t2\tSemi-Annual\n\t *\t\t\t\t\t\t\t\t\t\t4\tQuarterly\n\t *\t\t\t\t\t\t\t\t\tIf working in Gnumeric Mode, the following frequency options are\n\t *\t\t\t\t\t\t\t\t\talso available\n\t *\t\t\t\t\t\t\t\t\t\t6\tBimonthly\n\t *\t\t\t\t\t\t\t\t\t\t12\tMonthly\n\t * @param\tinteger\t\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function COUPDAYS($settlement, $maturity, $frequency, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$frequency\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);\n\t\t$basis\t\t= (is_null($basis))\t? 0 :\t(int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\tif (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\tif (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (($settlement > $maturity) ||\n\t\t\t(!self::_validFrequency($frequency)) ||\n\t\t\t(($basis < 0) || ($basis > 4))) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\tswitch ($basis) {\n\t\t\tcase 3: // Actual/365\n\t\t\t\t\treturn 365 / $frequency;\n\t\t\tcase 1: // Actual/actual\n\t\t\t\t\tif ($frequency == 1) {\n\t\t\t\t\t\t$daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($maturity),$basis);\n\t\t\t\t\t\treturn ($daysPerYear / $frequency);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$prev = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False);\n\t\t\t\t\t\t$next = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True);\n\t\t\t\t\t\treturn ($next - $prev);\n\t\t\t\t\t}\n\t\t\tdefault: // US (NASD) 30/360, Actual/360 or European 30/360\n\t\t\t\t\treturn 360 / $frequency;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction COUPDAYS()\n\n\n\t/**\n\t * COUPDAYSNC\n\t *\n\t * Returns the number of days from the settlement date to the next coupon date.\n\t *\n\t * Excel Function:\n\t *\t\tCOUPDAYSNC(settlement,maturity,frequency[,basis])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tmixed\tsettlement\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\tThe security settlement date is the date after the issue\n\t *\t\t\t\t\t\t\t\tdate when the security is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe security's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the security expires.\n\t * @param\tmixed\tfrequency\tthe number of coupon payments per year.\n\t *\t\t\t\t\t\t\t\t\tValid frequency values are:\n\t *\t\t\t\t\t\t\t\t\t\t1\tAnnual\n\t *\t\t\t\t\t\t\t\t\t\t2\tSemi-Annual\n\t *\t\t\t\t\t\t\t\t\t\t4\tQuarterly\n\t *\t\t\t\t\t\t\t\t\tIf working in Gnumeric Mode, the following frequency options are\n\t *\t\t\t\t\t\t\t\t\talso available\n\t *\t\t\t\t\t\t\t\t\t\t6\tBimonthly\n\t *\t\t\t\t\t\t\t\t\t\t12\tMonthly\n\t * @param\tinteger\t\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function COUPDAYSNC($settlement, $maturity, $frequency, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$frequency\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);\n\t\t$basis\t\t= (is_null($basis))\t? 0 :\t(int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\tif (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\tif (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (($settlement > $maturity) ||\n\t\t\t(!self::_validFrequency($frequency)) ||\n\t\t\t(($basis < 0) || ($basis > 4))) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t$daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis);\n\t\t$next = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True);\n\n\t\treturn PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $next, $basis) * $daysPerYear;\n\t}\t//\tfunction COUPDAYSNC()\n\n\n\t/**\n\t * COUPNCD\n\t *\n\t * Returns the next coupon date after the settlement date.\n\t *\n\t * Excel Function:\n\t *\t\tCOUPNCD(settlement,maturity,frequency[,basis])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tmixed\tsettlement\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\tThe security settlement date is the date after the issue\n\t *\t\t\t\t\t\t\t\tdate when the security is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe security's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the security expires.\n\t * @param\tmixed\tfrequency\tthe number of coupon payments per year.\n\t *\t\t\t\t\t\t\t\t\tValid frequency values are:\n\t *\t\t\t\t\t\t\t\t\t\t1\tAnnual\n\t *\t\t\t\t\t\t\t\t\t\t2\tSemi-Annual\n\t *\t\t\t\t\t\t\t\t\t\t4\tQuarterly\n\t *\t\t\t\t\t\t\t\t\tIf working in Gnumeric Mode, the following frequency options are\n\t *\t\t\t\t\t\t\t\t\talso available\n\t *\t\t\t\t\t\t\t\t\t\t6\tBimonthly\n\t *\t\t\t\t\t\t\t\t\t\t12\tMonthly\n\t * @param\tinteger\t\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tmixed\tExcel date/time serial value, PHP date/time serial value or PHP date/time object,\n\t *\t\t\t\t\t\tdepending on the value of the ReturnDateType flag\n\t */\n\tpublic static function COUPNCD($settlement, $maturity, $frequency, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$frequency\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);\n\t\t$basis\t\t= (is_null($basis))\t? 0 :\t(int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\tif (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\tif (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (($settlement > $maturity) ||\n\t\t\t(!self::_validFrequency($frequency)) ||\n\t\t\t(($basis < 0) || ($basis > 4))) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\treturn self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True);\n\t}\t//\tfunction COUPNCD()\n\n\n\t/**\n\t * COUPNUM\n\t *\n\t * Returns the number of coupons payable between the settlement date and maturity date,\n\t * rounded up to the nearest whole coupon.\n\t *\n\t * Excel Function:\n\t *\t\tCOUPNUM(settlement,maturity,frequency[,basis])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tmixed\tsettlement\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\tThe security settlement date is the date after the issue\n\t *\t\t\t\t\t\t\t\tdate when the security is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe security's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the security expires.\n\t * @param\tmixed\tfrequency\tthe number of coupon payments per year.\n\t *\t\t\t\t\t\t\t\t\tValid frequency values are:\n\t *\t\t\t\t\t\t\t\t\t\t1\tAnnual\n\t *\t\t\t\t\t\t\t\t\t\t2\tSemi-Annual\n\t *\t\t\t\t\t\t\t\t\t\t4\tQuarterly\n\t *\t\t\t\t\t\t\t\t\tIf working in Gnumeric Mode, the following frequency options are\n\t *\t\t\t\t\t\t\t\t\talso available\n\t *\t\t\t\t\t\t\t\t\t\t6\tBimonthly\n\t *\t\t\t\t\t\t\t\t\t\t12\tMonthly\n\t * @param\tinteger\t\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tinteger\n\t */\n\tpublic static function COUPNUM($settlement, $maturity, $frequency, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$frequency\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);\n\t\t$basis\t\t= (is_null($basis))\t? 0 :\t(int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\tif (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\tif (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (($settlement > $maturity) ||\n\t\t\t(!self::_validFrequency($frequency)) ||\n\t\t\t(($basis < 0) || ($basis > 4))) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t$settlement = self::_coupFirstPeriodDate($settlement, $maturity, $frequency, True);\n\t\t$daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis) * 365;\n\n\t\tswitch ($frequency) {\n\t\t\tcase 1: // annual payments\n\t\t\t\t\treturn ceil($daysBetweenSettlementAndMaturity / 360);\n\t\t\tcase 2: // half-yearly\n\t\t\t\t\treturn ceil($daysBetweenSettlementAndMaturity / 180);\n\t\t\tcase 4: // quarterly\n\t\t\t\t\treturn ceil($daysBetweenSettlementAndMaturity / 90);\n\t\t\tcase 6: // bimonthly\n\t\t\t\t\treturn ceil($daysBetweenSettlementAndMaturity / 60);\n\t\t\tcase 12: // monthly\n\t\t\t\t\treturn ceil($daysBetweenSettlementAndMaturity / 30);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction COUPNUM()\n\n\n\t/**\n\t * COUPPCD\n\t *\n\t * Returns the previous coupon date before the settlement date.\n\t *\n\t * Excel Function:\n\t *\t\tCOUPPCD(settlement,maturity,frequency[,basis])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tmixed\tsettlement\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\tThe security settlement date is the date after the issue\n\t *\t\t\t\t\t\t\t\tdate when the security is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe security's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the security expires.\n\t * @param\tmixed\tfrequency\tthe number of coupon payments per year.\n\t *\t\t\t\t\t\t\t\t\tValid frequency values are:\n\t *\t\t\t\t\t\t\t\t\t\t1\tAnnual\n\t *\t\t\t\t\t\t\t\t\t\t2\tSemi-Annual\n\t *\t\t\t\t\t\t\t\t\t\t4\tQuarterly\n\t *\t\t\t\t\t\t\t\t\tIf working in Gnumeric Mode, the following frequency options are\n\t *\t\t\t\t\t\t\t\t\talso available\n\t *\t\t\t\t\t\t\t\t\t\t6\tBimonthly\n\t *\t\t\t\t\t\t\t\t\t\t12\tMonthly\n\t * @param\tinteger\t\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tmixed\tExcel date/time serial value, PHP date/time serial value or PHP date/time object,\n\t *\t\t\t\t\t\tdepending on the value of the ReturnDateType flag\n\t */\n\tpublic static function COUPPCD($settlement, $maturity, $frequency, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$frequency\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);\n\t\t$basis\t\t= (is_null($basis))\t? 0 :\t(int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\tif (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\tif (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (($settlement > $maturity) ||\n\t\t\t(!self::_validFrequency($frequency)) ||\n\t\t\t(($basis < 0) || ($basis > 4))) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\treturn self::_coupFirstPeriodDate($settlement, $maturity, $frequency, False);\n\t}\t//\tfunction COUPPCD()\n\n\n\t/**\n\t * CUMIPMT\n\t *\n\t * Returns the cumulative interest paid on a loan between the start and end periods.\n\t *\n\t * Excel Function:\n\t *\t\tCUMIPMT(rate,nper,pv,start,end[,type])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tfloat\t$rate\tThe Interest rate\n\t * @param\tinteger\t$nper\tThe total number of payment periods\n\t * @param\tfloat\t$pv\t\tPresent Value\n\t * @param\tinteger\t$start\tThe first period in the calculation.\n\t *\t\t\t\t\t\t\tPayment periods are numbered beginning with 1.\n\t * @param\tinteger\t$end\tThe last period in the calculation.\n\t * @param\tinteger\t$type\tA number 0 or 1 and indicates when payments are due:\n\t *\t\t\t\t\t\t\t\t0 or omitted\tAt the end of the period.\n\t *\t\t\t\t\t\t\t\t1\t\t\t\tAt the beginning of the period.\n\t * @return\tfloat\n\t */\n\tpublic static function CUMIPMT($rate, $nper, $pv, $start, $end, $type = 0) {\n\t\t$rate\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$nper\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper);\n\t\t$pv\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($pv);\n\t\t$start\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($start);\n\t\t$end\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($end);\n\t\t$type\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($type);\n\n\t\t// Validate parameters\n\t\tif ($type != 0 && $type != 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\tif ($start < 1 || $start > $end) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t// Calculate\n\t\t$interest = 0;\n\t\tfor ($per = $start; $per <= $end; ++$per) {\n\t\t\t$interest += self::IPMT($rate, $per, $nper, $pv, 0, $type);\n\t\t}\n\n\t\treturn $interest;\n\t}\t//\tfunction CUMIPMT()\n\n\n\t/**\n\t * CUMPRINC\n\t *\n\t * Returns the cumulative principal paid on a loan between the start and end periods.\n\t *\n\t * Excel Function:\n\t *\t\tCUMPRINC(rate,nper,pv,start,end[,type])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tfloat\t$rate\tThe Interest rate\n\t * @param\tinteger\t$nper\tThe total number of payment periods\n\t * @param\tfloat\t$pv\t\tPresent Value\n\t * @param\tinteger\t$start\tThe first period in the calculation.\n\t *\t\t\t\t\t\t\tPayment periods are numbered beginning with 1.\n\t * @param\tinteger\t$end\tThe last period in the calculation.\n\t * @param\tinteger\t$type\tA number 0 or 1 and indicates when payments are due:\n\t *\t\t\t\t\t\t\t\t0 or omitted\tAt the end of the period.\n\t *\t\t\t\t\t\t\t\t1\t\t\t\tAt the beginning of the period.\n\t * @return\tfloat\n\t */\n\tpublic static function CUMPRINC($rate, $nper, $pv, $start, $end, $type = 0) {\n\t\t$rate\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$nper\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper);\n\t\t$pv\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($pv);\n\t\t$start\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($start);\n\t\t$end\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($end);\n\t\t$type\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($type);\n\n\t\t// Validate parameters\n\t\tif ($type != 0 && $type != 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\tif ($start < 1 || $start > $end) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t// Calculate\n\t\t$principal = 0;\n\t\tfor ($per = $start; $per <= $end; ++$per) {\n\t\t\t$principal += self::PPMT($rate, $per, $nper, $pv, 0, $type);\n\t\t}\n\n\t\treturn $principal;\n\t}\t//\tfunction CUMPRINC()\n\n\n\t/**\n\t * DB\n\t *\n\t * Returns the depreciation of an asset for a specified period using the\n\t * fixed-declining balance method.\n\t * This form of depreciation is used if you want to get a higher depreciation value\n\t * at the beginning of the depreciation (as opposed to linear depreciation). The\n\t * depreciation value is reduced with every depreciation period by the depreciation\n\t * already deducted from the initial cost.\n\t *\n\t * Excel Function:\n\t *\t\tDB(cost,salvage,life,period[,month])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tfloat\tcost\t\tInitial cost of the asset.\n\t * @param\tfloat\tsalvage\t\tValue at the end of the depreciation.\n\t *\t\t\t\t\t\t\t\t(Sometimes called the salvage value of the asset)\n\t * @param\tinteger\tlife\t\tNumber of periods over which the asset is depreciated.\n\t *\t\t\t\t\t\t\t\t(Sometimes called the useful life of the asset)\n\t * @param\tinteger\tperiod\t\tThe period for which you want to calculate the\n\t *\t\t\t\t\t\t\t\tdepreciation. Period must use the same units as life.\n\t * @param\tinteger\tmonth\t\tNumber of months in the first year. If month is omitted,\n\t *\t\t\t\t\t\t\t\tit defaults to 12.\n\t * @return\tfloat\n\t */\n\tpublic static function DB($cost, $salvage, $life, $period, $month=12) {\n\t\t$cost\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($cost);\n\t\t$salvage\t= PHPExcel_Calculation_Functions::flattenSingleValue($salvage);\n\t\t$life\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($life);\n\t\t$period\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($period);\n\t\t$month\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($month);\n\n\t\t//\tValidate\n\t\tif ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($month))) {\n\t\t\t$cost\t\t= (float) $cost;\n\t\t\t$salvage\t= (float) $salvage;\n\t\t\t$life\t\t= (int) $life;\n\t\t\t$period\t\t= (int) $period;\n\t\t\t$month\t\t= (int) $month;\n\t\t\tif ($cost == 0) {\n\t\t\t\treturn 0.0;\n\t\t\t} elseif (($cost < 0) || (($salvage / $cost) < 0) || ($life <= 0) || ($period < 1) || ($month < 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t//\tSet Fixed Depreciation Rate\n\t\t\t$fixedDepreciationRate = 1 - pow(($salvage / $cost), (1 / $life));\n\t\t\t$fixedDepreciationRate = round($fixedDepreciationRate, 3);\n\n\t\t\t//\tLoop through each period calculating the depreciation\n\t\t\t$previousDepreciation = 0;\n\t\t\tfor ($per = 1; $per <= $period; ++$per) {\n\t\t\t\tif ($per == 1) {\n\t\t\t\t\t$depreciation = $cost * $fixedDepreciationRate * $month / 12;\n\t\t\t\t} elseif ($per == ($life + 1)) {\n\t\t\t\t\t$depreciation = ($cost - $previousDepreciation) * $fixedDepreciationRate * (12 - $month) / 12;\n\t\t\t\t} else {\n\t\t\t\t\t$depreciation = ($cost - $previousDepreciation) * $fixedDepreciationRate;\n\t\t\t\t}\n\t\t\t\t$previousDepreciation += $depreciation;\n\t\t\t}\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {\n\t\t\t\t$depreciation = round($depreciation,2);\n\t\t\t}\n\t\t\treturn $depreciation;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction DB()\n\n\n\t/**\n\t * DDB\n\t *\n\t * Returns the depreciation of an asset for a specified period using the\n\t * double-declining balance method or some other method you specify.\n\t *\n\t * Excel Function:\n\t *\t\tDDB(cost,salvage,life,period[,factor])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tfloat\tcost\t\tInitial cost of the asset.\n\t * @param\tfloat\tsalvage\t\tValue at the end of the depreciation.\n\t *\t\t\t\t\t\t\t\t(Sometimes called the salvage value of the asset)\n\t * @param\tinteger\tlife\t\tNumber of periods over which the asset is depreciated.\n\t *\t\t\t\t\t\t\t\t(Sometimes called the useful life of the asset)\n\t * @param\tinteger\tperiod\t\tThe period for which you want to calculate the\n\t *\t\t\t\t\t\t\t\tdepreciation. Period must use the same units as life.\n\t * @param\tfloat\tfactor\t\tThe rate at which the balance declines.\n\t *\t\t\t\t\t\t\t\tIf factor is omitted, it is assumed to be 2 (the\n\t *\t\t\t\t\t\t\t\tdouble-declining balance method).\n\t * @return\tfloat\n\t */\n\tpublic static function DDB($cost, $salvage, $life, $period, $factor=2.0) {\n\t\t$cost\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($cost);\n\t\t$salvage\t= PHPExcel_Calculation_Functions::flattenSingleValue($salvage);\n\t\t$life\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($life);\n\t\t$period\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($period);\n\t\t$factor\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($factor);\n\n\t\t//\tValidate\n\t\tif ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period)) && (is_numeric($factor))) {\n\t\t\t$cost\t\t= (float) $cost;\n\t\t\t$salvage\t= (float) $salvage;\n\t\t\t$life\t\t= (int) $life;\n\t\t\t$period\t\t= (int) $period;\n\t\t\t$factor\t\t= (float) $factor;\n\t\t\tif (($cost <= 0) || (($salvage / $cost) < 0) || ($life <= 0) || ($period < 1) || ($factor <= 0.0) || ($period > $life)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t//\tSet Fixed Depreciation Rate\n\t\t\t$fixedDepreciationRate = 1 - pow(($salvage / $cost), (1 / $life));\n\t\t\t$fixedDepreciationRate = round($fixedDepreciationRate, 3);\n\n\t\t\t//\tLoop through each period calculating the depreciation\n\t\t\t$previousDepreciation = 0;\n\t\t\tfor ($per = 1; $per <= $period; ++$per) {\n\t\t\t\t$depreciation = min( ($cost - $previousDepreciation) * ($factor / $life), ($cost - $salvage - $previousDepreciation) );\n\t\t\t\t$previousDepreciation += $depreciation;\n\t\t\t}\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {\n\t\t\t\t$depreciation = round($depreciation,2);\n\t\t\t}\n\t\t\treturn $depreciation;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction DDB()\n\n\n\t/**\n\t * DISC\n\t *\n\t * Returns the discount rate for a security.\n\t *\n\t * Excel Function:\n\t *\t\tDISC(settlement,maturity,price,redemption[,basis])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tmixed\tsettlement\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\tThe security settlement date is the date after the issue\n\t *\t\t\t\t\t\t\t\tdate when the security is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe security's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the security expires.\n\t * @param\tinteger\tprice\t\tThe security's price per $100 face value.\n\t * @param\tinteger\tredemption\tThe security's redemption value per $100 face value.\n\t * @param\tinteger\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function DISC($settlement, $maturity, $price, $redemption, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$price\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($price);\n\t\t$redemption\t= PHPExcel_Calculation_Functions::flattenSingleValue($redemption);\n\t\t$basis\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\t//\tValidate\n\t\tif ((is_numeric($price)) && (is_numeric($redemption)) && (is_numeric($basis))) {\n\t\t\t$price\t\t= (float) $price;\n\t\t\t$redemption\t= (float) $redemption;\n\t\t\t$basis\t\t= (int) $basis;\n\t\t\tif (($price <= 0) || ($redemption <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis);\n\t\t\tif (!is_numeric($daysBetweenSettlementAndMaturity)) {\n\t\t\t\t//\treturn date error\n\t\t\t\treturn $daysBetweenSettlementAndMaturity;\n\t\t\t}\n\n\t\t\treturn ((1 - $price / $redemption) / $daysBetweenSettlementAndMaturity);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction DISC()\n\n\n\t/**\n\t * DOLLARDE\n\t *\n\t * Converts a dollar price expressed as an integer part and a fraction\n\t *\t\tpart into a dollar price expressed as a decimal number.\n\t * Fractional dollar numbers are sometimes used for security prices.\n\t *\n\t * Excel Function:\n\t *\t\tDOLLARDE(fractional_dollar,fraction)\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tfloat\t$fractional_dollar\tFractional Dollar\n\t * @param\tinteger\t$fraction\t\t\tFraction\n\t * @return\tfloat\n\t */\n\tpublic static function DOLLARDE($fractional_dollar = Null, $fraction = 0) {\n\t\t$fractional_dollar\t= PHPExcel_Calculation_Functions::flattenSingleValue($fractional_dollar);\n\t\t$fraction\t\t\t= (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction);\n\n\t\t// Validate parameters\n\t\tif (is_null($fractional_dollar) || $fraction < 0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\tif ($fraction == 0) {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t}\n\n\t\t$dollars = floor($fractional_dollar);\n\t\t$cents = fmod($fractional_dollar,1);\n\t\t$cents /= $fraction;\n\t\t$cents *= pow(10,ceil(log10($fraction)));\n\t\treturn $dollars + $cents;\n\t}\t//\tfunction DOLLARDE()\n\n\n\t/**\n\t * DOLLARFR\n\t *\n\t * Converts a dollar price expressed as a decimal number into a dollar price\n\t *\t\texpressed as a fraction.\n\t * Fractional dollar numbers are sometimes used for security prices.\n\t *\n\t * Excel Function:\n\t *\t\tDOLLARFR(decimal_dollar,fraction)\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tfloat\t$decimal_dollar\t\tDecimal Dollar\n\t * @param\tinteger\t$fraction\t\t\tFraction\n\t * @return\tfloat\n\t */\n\tpublic static function DOLLARFR($decimal_dollar = Null, $fraction = 0) {\n\t\t$decimal_dollar\t= PHPExcel_Calculation_Functions::flattenSingleValue($decimal_dollar);\n\t\t$fraction\t\t= (int)PHPExcel_Calculation_Functions::flattenSingleValue($fraction);\n\n\t\t// Validate parameters\n\t\tif (is_null($decimal_dollar) || $fraction < 0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\tif ($fraction == 0) {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t}\n\n\t\t$dollars = floor($decimal_dollar);\n\t\t$cents = fmod($decimal_dollar,1);\n\t\t$cents *= $fraction;\n\t\t$cents *= pow(10,-ceil(log10($fraction)));\n\t\treturn $dollars + $cents;\n\t}\t//\tfunction DOLLARFR()\n\n\n\t/**\n\t * EFFECT\n\t *\n\t * Returns the effective interest rate given the nominal rate and the number of\n\t *\t\tcompounding payments per year.\n\t *\n\t * Excel Function:\n\t *\t\tEFFECT(nominal_rate,npery)\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tfloat\t$nominal_rate\t\tNominal interest rate\n\t * @param\tinteger\t$npery\t\t\t\tNumber of compounding payments per year\n\t * @return\tfloat\n\t */\n\tpublic static function EFFECT($nominal_rate = 0, $npery = 0) {\n\t\t$nominal_rate\t= PHPExcel_Calculation_Functions::flattenSingleValue($nominal_rate);\n\t\t$npery\t\t\t= (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery);\n\n\t\t// Validate parameters\n\t\tif ($nominal_rate <= 0 || $npery < 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\treturn pow((1 + $nominal_rate / $npery), $npery) - 1;\n\t}\t//\tfunction EFFECT()\n\n\n\t/**\n\t * FV\n\t *\n\t * Returns the Future Value of a cash flow with constant payments and interest rate (annuities).\n\t *\n\t * Excel Function:\n\t *\t\tFV(rate,nper,pmt[,pv[,type]])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tfloat\t$rate\tThe interest rate per period\n\t * @param\tint\t\t$nper\tTotal number of payment periods in an annuity\n\t * @param\tfloat\t$pmt\tThe payment made each period: it cannot change over the\n\t *\t\t\t\t\t\t\tlife of the annuity. Typically, pmt contains principal\n\t *\t\t\t\t\t\t\tand interest but no other fees or taxes.\n\t * @param\tfloat\t$pv\t\tPresent Value, or the lump-sum amount that a series of\n\t *\t\t\t\t\t\t\tfuture payments is worth right now.\n\t * @param\tinteger\t$type\tA number 0 or 1 and indicates when payments are due:\n\t *\t\t\t\t\t\t\t\t0 or omitted\tAt the end of the period.\n\t *\t\t\t\t\t\t\t\t1\t\t\t\tAt the beginning of the period.\n\t * @return\tfloat\n\t */\n\tpublic static function FV($rate = 0, $nper = 0, $pmt = 0, $pv = 0, $type = 0) {\n\t\t$rate\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$nper\t= PHPExcel_Calculation_Functions::flattenSingleValue($nper);\n\t\t$pmt\t= PHPExcel_Calculation_Functions::flattenSingleValue($pmt);\n\t\t$pv\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($pv);\n\t\t$type\t= PHPExcel_Calculation_Functions::flattenSingleValue($type);\n\n\t\t// Validate parameters\n\t\tif ($type != 0 && $type != 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t// Calculate\n\t\tif (!is_null($rate) && $rate != 0) {\n\t\t\treturn -$pv * pow(1 + $rate, $nper) - $pmt * (1 + $rate * $type) * (pow(1 + $rate, $nper) - 1) / $rate;\n\t\t} else {\n\t\t\treturn -$pv - $pmt * $nper;\n\t\t}\n\t}\t//\tfunction FV()\n\n\n\t/**\n\t * FVSCHEDULE\n\t *\n\t * Returns the future value of an initial principal after applying a series of compound interest rates.\n\t * Use FVSCHEDULE to calculate the future value of an investment with a variable or adjustable rate.\n\t *\n\t * Excel Function:\n\t *\t\tFVSCHEDULE(principal,schedule)\n\t *\n\t * @param\tfloat\t$principal\tThe present value.\n\t * @param\tfloat[]\t$schedule\tAn array of interest rates to apply.\n\t * @return\tfloat\n\t */\n\tpublic static function FVSCHEDULE($principal, $schedule) {\n\t\t$principal\t= PHPExcel_Calculation_Functions::flattenSingleValue($principal);\n\t\t$schedule\t= PHPExcel_Calculation_Functions::flattenArray($schedule);\n\n\t\tforeach($schedule as $rate) {\n\t\t\t$principal *= 1 + $rate;\n\t\t}\n\n\t\treturn $principal;\n\t}\t//\tfunction FVSCHEDULE()\n\n\n\t/**\n\t * INTRATE\n\t *\n\t * Returns the interest rate for a fully invested security.\n\t *\n\t * Excel Function:\n\t *\t\tINTRATE(settlement,maturity,investment,redemption[,basis])\n\t *\n\t * @param\tmixed\t$settlement\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\tThe security settlement date is the date after the issue date when the security is traded to the buyer.\n\t * @param\tmixed\t$maturity\tThe security's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the security expires.\n\t * @param\tinteger\t$investment\tThe amount invested in the security.\n\t * @param\tinteger\t$redemption\tThe amount to be received at maturity.\n\t * @param\tinteger\t$basis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function INTRATE($settlement, $maturity, $investment, $redemption, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$investment\t= PHPExcel_Calculation_Functions::flattenSingleValue($investment);\n\t\t$redemption\t= PHPExcel_Calculation_Functions::flattenSingleValue($redemption);\n\t\t$basis\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\t//\tValidate\n\t\tif ((is_numeric($investment)) && (is_numeric($redemption)) && (is_numeric($basis))) {\n\t\t\t$investment\t= (float) $investment;\n\t\t\t$redemption\t= (float) $redemption;\n\t\t\t$basis\t\t= (int) $basis;\n\t\t\tif (($investment <= 0) || ($redemption <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis);\n\t\t\tif (!is_numeric($daysBetweenSettlementAndMaturity)) {\n\t\t\t\t//\treturn date error\n\t\t\t\treturn $daysBetweenSettlementAndMaturity;\n\t\t\t}\n\n\t\t\treturn (($redemption / $investment) - 1) / ($daysBetweenSettlementAndMaturity);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction INTRATE()\n\n\n\t/**\n\t * IPMT\n\t *\n\t * Returns the interest payment for a given period for an investment based on periodic, constant payments and a constant interest rate.\n\t *\n\t * Excel Function:\n\t *\t\tIPMT(rate,per,nper,pv[,fv][,type])\n\t *\n\t * @param\tfloat\t$rate\tInterest rate per period\n\t * @param\tint\t\t$per\tPeriod for which we want to find the interest\n\t * @param\tint\t\t$nper\tNumber of periods\n\t * @param\tfloat\t$pv\t\tPresent Value\n\t * @param\tfloat\t$fv\t\tFuture Value\n\t * @param\tint\t\t$type\tPayment type: 0 = at the end of each period, 1 = at the beginning of each period\n\t * @return\tfloat\n\t */\n\tpublic static function IPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) {\n\t\t$rate\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$per\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($per);\n\t\t$nper\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper);\n\t\t$pv\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($pv);\n\t\t$fv\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($fv);\n\t\t$type\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($type);\n\n\t\t// Validate parameters\n\t\tif ($type != 0 && $type != 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\tif ($per <= 0 || $per > $nper) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t// Calculate\n\t\t$interestAndPrincipal = self::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type);\n\t\treturn $interestAndPrincipal[0];\n\t}\t//\tfunction IPMT()\n\n\t/**\n\t * IRR\n\t *\n\t * Returns the internal rate of return for a series of cash flows represented by the numbers in values. \n\t * These cash flows do not have to be even, as they would be for an annuity. However, the cash flows must occur \n\t * at regular intervals, such as monthly or annually. The internal rate of return is the interest rate received\n\t * for an investment consisting of payments (negative values) and income (positive values) that occur at regular \n\t * periods.\n\t *\n\t * Excel Function:\n\t *\t\tIRR(values[,guess])\n\t *\n\t * @param\tfloat[]\t$values\t\tAn array or a reference to cells that contain numbers for which you want\n\t *\t\t\t\t\t\t\t\t\tto calculate the internal rate of return.\n\t *\t\t\t\t\t\t\t\tValues must contain at least one positive value and one negative value to \n\t *\t\t\t\t\t\t\t\t\tcalculate the internal rate of return.\n\t * @param\tfloat\t$guess\t\tA number that you guess is close to the result of IRR\n\t * @return\tfloat\n\t */\n\tpublic static function IRR($values, $guess = 0.1) {\n\t\tif (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE();\n\t\t$values = PHPExcel_Calculation_Functions::flattenArray($values);\n\t\t$guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess);\n\n\t\t// create an initial range, with a root somewhere between 0 and guess\n\t\t$x1 = 0.0;\n\t\t$x2 = $guess;\n\t\t$f1 = self::NPV($x1, $values);\n\t\t$f2 = self::NPV($x2, $values);\n\t\tfor ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) {\n\t\t\tif (($f1 * $f2) < 0.0) break;\n\t\t\tif (abs($f1) < abs($f2)) {\n\t\t\t\t$f1 = self::NPV($x1 += 1.6 * ($x1 - $x2), $values);\n\t\t\t} else {\n\t\t\t\t$f2 = self::NPV($x2 += 1.6 * ($x2 - $x1), $values);\n\t\t\t}\n\t\t}\n\t\tif (($f1 * $f2) > 0.0) return PHPExcel_Calculation_Functions::VALUE();\n\n\t\t$f = self::NPV($x1, $values);\n\t\tif ($f < 0.0) {\n\t\t\t$rtb = $x1;\n\t\t\t$dx = $x2 - $x1;\n\t\t} else {\n\t\t\t$rtb = $x2;\n\t\t\t$dx = $x1 - $x2;\n\t\t}\n\n\t\tfor ($i = 0;  $i < FINANCIAL_MAX_ITERATIONS; ++$i) {\n\t\t\t$dx *= 0.5;\n\t\t\t$x_mid = $rtb + $dx;\n\t\t\t$f_mid = self::NPV($x_mid, $values);\n\t\t\tif ($f_mid <= 0.0) \n\t\t\t\t$rtb = $x_mid;\n\t\t\tif ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) \n\t\t\t\treturn $x_mid;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction IRR()\n\n\n\t/**\n\t * ISPMT\n\t *\n\t * Returns the interest payment for an investment based on an interest rate and a constant payment schedule.\n\t *\n\t * Excel Function:\n\t *     =ISPMT(interest_rate, period, number_payments, PV)\n\t *\n\t * interest_rate is the interest rate for the investment\n\t *\n\t * period is the period to calculate the interest rate.  It must be betweeen 1 and number_payments.\n\t *\n\t * number_payments is the number of payments for the annuity\n\t *\n\t * PV is the loan amount or present value of the payments\n\t */\n\tpublic static function ISPMT() {\n\t\t// Return value\n\t\t$returnValue = 0;\n\n\t\t// Get the parameters\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\t$interestRate = array_shift($aArgs);\n\t\t$period = array_shift($aArgs);\n\t\t$numberPeriods = array_shift($aArgs);\n\t\t$principleRemaining = array_shift($aArgs);\n\n\t\t// Calculate\n\t\t$principlePayment = ($principleRemaining * 1.0) / ($numberPeriods * 1.0);\n\t\tfor($i=0; $i <= $period; ++$i) {\n\t\t\t$returnValue = $interestRate * $principleRemaining * -1;\n\t\t\t$principleRemaining -= $principlePayment;\n\t\t\t// principle needs to be 0 after the last payment, don't let floating point screw it up\n\t\t\tif($i == $numberPeriods) {\n\t\t\t\t$returnValue = 0;\n\t\t\t}\n\t\t}\n\t\treturn($returnValue);\n\t}\t//\tfunction ISPMT()\n\n\n\t/**\n\t * MIRR\n\t *\n\t * Returns the modified internal rate of return for a series of periodic cash flows. MIRR considers both \n\t *\t\tthe cost of the investment and the interest received on reinvestment of cash.\n\t *\n\t * Excel Function:\n\t *\t\tMIRR(values,finance_rate, reinvestment_rate)\n\t *\n\t * @param\tfloat[]\t$values\t\t\t\tAn array or a reference to cells that contain a series of payments and\n\t *\t\t\t\t\t\t\t\t\t\t\tincome occurring at regular intervals.\n\t *\t\t\t\t\t\t\t\t\t\tPayments are negative value, income is positive values.\n\t * @param\tfloat\t$finance_rate\t\tThe interest rate you pay on the money used in the cash flows\n\t * @param\tfloat\t$reinvestment_rate\tThe interest rate you receive on the cash flows as you reinvest them\n\t * @return\tfloat\n\t */\n\tpublic static function MIRR($values, $finance_rate, $reinvestment_rate) {\n\t\tif (!is_array($values)) return PHPExcel_Calculation_Functions::VALUE();\n\t\t$values\t\t\t\t= PHPExcel_Calculation_Functions::flattenArray($values);\n\t\t$finance_rate\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($finance_rate);\n\t\t$reinvestment_rate\t= PHPExcel_Calculation_Functions::flattenSingleValue($reinvestment_rate);\n\t\t$n = count($values);\n\n\t\t$rr = 1.0 + $reinvestment_rate;\n\t\t$fr = 1.0 + $finance_rate;\n\n\t\t$npv_pos = $npv_neg = 0.0;\n\t\tforeach($values as $i => $v) {\n\t\t\tif ($v >= 0) {\n\t\t\t\t$npv_pos += $v / pow($rr, $i);\n\t\t\t} else {\n\t\t\t\t$npv_neg += $v / pow($fr, $i);\n\t\t\t}\n\t\t}\n\n\t\tif (($npv_neg == 0) || ($npv_pos == 0) || ($reinvestment_rate <= -1)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t$mirr = pow((-$npv_pos * pow($rr, $n))\n\t\t\t\t/ ($npv_neg * ($rr)), (1.0 / ($n - 1))) - 1.0;\n\n\t\treturn (is_finite($mirr) ? $mirr : PHPExcel_Calculation_Functions::VALUE());\n\t}\t//\tfunction MIRR()\n\n\n\t/**\n\t * NOMINAL\n\t *\n\t * Returns the nominal interest rate given the effective rate and the number of compounding payments per year.\n\t *\n\t * @param\tfloat\t$effect_rate\tEffective interest rate\n\t * @param\tint\t\t$npery\t\t\tNumber of compounding payments per year\n\t * @return\tfloat\n\t */\n\tpublic static function NOMINAL($effect_rate = 0, $npery = 0) {\n\t\t$effect_rate\t= PHPExcel_Calculation_Functions::flattenSingleValue($effect_rate);\n\t\t$npery\t\t\t= (int)PHPExcel_Calculation_Functions::flattenSingleValue($npery);\n\n\t\t// Validate parameters\n\t\tif ($effect_rate <= 0 || $npery < 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t// Calculate\n\t\treturn $npery * (pow($effect_rate + 1, 1 / $npery) - 1);\n\t}\t//\tfunction NOMINAL()\n\n\n\t/**\n\t * NPER\n\t *\n\t * Returns the number of periods for a cash flow with constant periodic payments (annuities), and interest rate.\n\t *\n\t * @param\tfloat\t$rate\tInterest rate per period\n\t * @param\tint\t\t$pmt\tPeriodic payment (annuity)\n\t * @param\tfloat\t$pv\t\tPresent Value\n\t * @param\tfloat\t$fv\t\tFuture Value\n\t * @param\tint\t\t$type\tPayment type: 0 = at the end of each period, 1 = at the beginning of each period\n\t * @return\tfloat\n\t */\n\tpublic static function NPER($rate = 0, $pmt = 0, $pv = 0, $fv = 0, $type = 0) {\n\t\t$rate\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$pmt\t= PHPExcel_Calculation_Functions::flattenSingleValue($pmt);\n\t\t$pv\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($pv);\n\t\t$fv\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($fv);\n\t\t$type\t= PHPExcel_Calculation_Functions::flattenSingleValue($type);\n\n\t\t// Validate parameters\n\t\tif ($type != 0 && $type != 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t// Calculate\n\t\tif (!is_null($rate) && $rate != 0) {\n\t\t\tif ($pmt == 0 && $pv == 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn log(($pmt * (1 + $rate * $type) / $rate - $fv) / ($pv + $pmt * (1 + $rate * $type) / $rate)) / log(1 + $rate);\n\t\t} else {\n\t\t\tif ($pmt == 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn (-$pv -$fv) / $pmt;\n\t\t}\n\t}\t//\tfunction NPER()\n\n\t/**\n\t * NPV\n\t *\n\t * Returns the Net Present Value of a cash flow series given a discount rate.\n\t *\n\t * @return\tfloat\n\t */\n\tpublic static function NPV() {\n\t\t// Return value\n\t\t$returnValue = 0;\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\n\t\t// Calculate\n\t\t$rate = array_shift($aArgs);\n\t\tfor ($i = 1; $i <= count($aArgs); ++$i) {\n\t\t\t// Is it a numeric value?\n\t\t\tif (is_numeric($aArgs[$i - 1])) {\n\t\t\t\t$returnValue += $aArgs[$i - 1] / pow(1 + $rate, $i);\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction NPV()\n\n\t/**\n\t * PMT\n\t *\n\t * Returns the constant payment (annuity) for a cash flow with a constant interest rate.\n\t *\n\t * @param\tfloat\t$rate\tInterest rate per period\n\t * @param\tint\t\t$nper\tNumber of periods\n\t * @param\tfloat\t$pv\t\tPresent Value\n\t * @param\tfloat\t$fv\t\tFuture Value\n\t * @param\tint\t\t$type\tPayment type: 0 = at the end of each period, 1 = at the beginning of each period\n\t * @return\tfloat\n\t */\n\tpublic static function PMT($rate = 0, $nper = 0, $pv = 0, $fv = 0, $type = 0) {\n\t\t$rate\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$nper\t= PHPExcel_Calculation_Functions::flattenSingleValue($nper);\n\t\t$pv\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($pv);\n\t\t$fv\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($fv);\n\t\t$type\t= PHPExcel_Calculation_Functions::flattenSingleValue($type);\n\n\t\t// Validate parameters\n\t\tif ($type != 0 && $type != 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t// Calculate\n\t\tif (!is_null($rate) && $rate != 0) {\n\t\t\treturn (-$fv - $pv * pow(1 + $rate, $nper)) / (1 + $rate * $type) / ((pow(1 + $rate, $nper) - 1) / $rate);\n\t\t} else {\n\t\t\treturn (-$pv - $fv) / $nper;\n\t\t}\n\t}\t//\tfunction PMT()\n\n\n\t/**\n\t * PPMT\n\t *\n\t * Returns the interest payment for a given period for an investment based on periodic, constant payments and a constant interest rate.\n\t *\n\t * @param\tfloat\t$rate\tInterest rate per period\n\t * @param\tint\t\t$per\tPeriod for which we want to find the interest\n\t * @param\tint\t\t$nper\tNumber of periods\n\t * @param\tfloat\t$pv\t\tPresent Value\n\t * @param\tfloat\t$fv\t\tFuture Value\n\t * @param\tint\t\t$type\tPayment type: 0 = at the end of each period, 1 = at the beginning of each period\n\t * @return\tfloat\n\t */\n\tpublic static function PPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) {\n\t\t$rate\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$per\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($per);\n\t\t$nper\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper);\n\t\t$pv\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($pv);\n\t\t$fv\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($fv);\n\t\t$type\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($type);\n\n\t\t// Validate parameters\n\t\tif ($type != 0 && $type != 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\tif ($per <= 0 || $per > $nper) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t// Calculate\n\t\t$interestAndPrincipal = self::_interestAndPrincipal($rate, $per, $nper, $pv, $fv, $type);\n\t\treturn $interestAndPrincipal[1];\n\t}\t//\tfunction PPMT()\n\n\n\tpublic static function PRICE($settlement, $maturity, $rate, $yield, $redemption, $frequency, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$rate\t\t= (float) PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$yield\t\t= (float) PHPExcel_Calculation_Functions::flattenSingleValue($yield);\n\t\t$redemption\t= (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption);\n\t\t$frequency\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($frequency);\n\t\t$basis\t\t= (is_null($basis))\t? 0 :\t(int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\tif (is_string($settlement = PHPExcel_Calculation_DateTime::_getDateValue($settlement))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\tif (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (($settlement > $maturity) ||\n\t\t\t(!self::_validFrequency($frequency)) ||\n\t\t\t(($basis < 0) || ($basis > 4))) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t$dsc = self::COUPDAYSNC($settlement, $maturity, $frequency, $basis);\n\t\t$e = self::COUPDAYS($settlement, $maturity, $frequency, $basis);\n\t\t$n = self::COUPNUM($settlement, $maturity, $frequency, $basis);\n\t\t$a = self::COUPDAYBS($settlement, $maturity, $frequency, $basis);\n\n\t\t$baseYF\t= 1.0 + ($yield / $frequency);\n\t\t$rfp\t= 100 * ($rate / $frequency);\n\t\t$de\t= $dsc / $e;\n\n\t\t$result = $redemption / pow($baseYF, (--$n + $de));\n\t\tfor($k = 0; $k <= $n; ++$k) {\n\t\t\t$result += $rfp / (pow($baseYF, ($k + $de)));\n\t\t}\n\t\t$result -= $rfp * ($a / $e);\n\n\t\treturn $result;\n\t}\t//\tfunction PRICE()\n\n\n\t/**\n\t * PRICEDISC\n\t *\n\t * Returns the price per $100 face value of a discounted security.\n\t *\n\t * @param\tmixed\tsettlement\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\tThe security settlement date is the date after the issue date when the security is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe security's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the security expires.\n\t * @param\tint\t\tdiscount\tThe security's discount rate.\n\t * @param\tint\t\tredemption\tThe security's redemption value per $100 face value.\n\t * @param\tint\t\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function PRICEDISC($settlement, $maturity, $discount, $redemption, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$discount\t= (float) PHPExcel_Calculation_Functions::flattenSingleValue($discount);\n\t\t$redemption\t= (float) PHPExcel_Calculation_Functions::flattenSingleValue($redemption);\n\t\t$basis\t\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\t//\tValidate\n\t\tif ((is_numeric($discount)) && (is_numeric($redemption)) && (is_numeric($basis))) {\n\t\t\tif (($discount <= 0) || ($redemption <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis);\n\t\t\tif (!is_numeric($daysBetweenSettlementAndMaturity)) {\n\t\t\t\t//\treturn date error\n\t\t\t\treturn $daysBetweenSettlementAndMaturity;\n\t\t\t}\n\n\t\t\treturn $redemption * (1 - $discount * $daysBetweenSettlementAndMaturity);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction PRICEDISC()\n\n\n\t/**\n\t * PRICEMAT\n\t *\n\t * Returns the price per $100 face value of a security that pays interest at maturity.\n\t *\n\t * @param\tmixed\tsettlement\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\tThe security's settlement date is the date after the issue date when the security is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe security's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the security expires.\n\t * @param\tmixed\tissue\t\tThe security's issue date.\n\t * @param\tint\t\trate\t\tThe security's interest rate at date of issue.\n\t * @param\tint\t\tyield\t\tThe security's annual yield.\n\t * @param\tint\t\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function PRICEMAT($settlement, $maturity, $issue, $rate, $yield, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$issue\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($issue);\n\t\t$rate\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$yield\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($yield);\n\t\t$basis\t\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\t//\tValidate\n\t\tif (is_numeric($rate) && is_numeric($yield)) {\n\t\t\tif (($rate <= 0) || ($yield <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis);\n\t\t\tif (!is_numeric($daysPerYear)) {\n\t\t\t\treturn $daysPerYear;\n\t\t\t}\n\t\t\t$daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis);\n\t\t\tif (!is_numeric($daysBetweenIssueAndSettlement)) {\n\t\t\t\t//\treturn date error\n\t\t\t\treturn $daysBetweenIssueAndSettlement;\n\t\t\t}\n\t\t\t$daysBetweenIssueAndSettlement *= $daysPerYear;\n\t\t\t$daysBetweenIssueAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $maturity, $basis);\n\t\t\tif (!is_numeric($daysBetweenIssueAndMaturity)) {\n\t\t\t\t//\treturn date error\n\t\t\t\treturn $daysBetweenIssueAndMaturity;\n\t\t\t}\n\t\t\t$daysBetweenIssueAndMaturity *= $daysPerYear;\n\t\t\t$daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis);\n\t\t\tif (!is_numeric($daysBetweenSettlementAndMaturity)) {\n\t\t\t\t//\treturn date error\n\t\t\t\treturn $daysBetweenSettlementAndMaturity;\n\t\t\t}\n\t\t\t$daysBetweenSettlementAndMaturity *= $daysPerYear;\n\n\t\t\treturn ((100 + (($daysBetweenIssueAndMaturity / $daysPerYear) * $rate * 100)) /\n\t\t\t\t   (1 + (($daysBetweenSettlementAndMaturity / $daysPerYear) * $yield)) -\n\t\t\t\t   (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate * 100));\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction PRICEMAT()\n\n\n\t/**\n\t * PV\n\t *\n\t * Returns the Present Value of a cash flow with constant payments and interest rate (annuities).\n\t *\n\t * @param\tfloat\t$rate\tInterest rate per period\n\t * @param\tint\t\t$nper\tNumber of periods\n\t * @param\tfloat\t$pmt\tPeriodic payment (annuity)\n\t * @param\tfloat\t$fv\t\tFuture Value\n\t * @param\tint\t\t$type\tPayment type: 0 = at the end of each period, 1 = at the beginning of each period\n\t * @return\tfloat\n\t */\n\tpublic static function PV($rate = 0, $nper = 0, $pmt = 0, $fv = 0, $type = 0) {\n\t\t$rate\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$nper\t= PHPExcel_Calculation_Functions::flattenSingleValue($nper);\n\t\t$pmt\t= PHPExcel_Calculation_Functions::flattenSingleValue($pmt);\n\t\t$fv\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($fv);\n\t\t$type\t= PHPExcel_Calculation_Functions::flattenSingleValue($type);\n\n\t\t// Validate parameters\n\t\tif ($type != 0 && $type != 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t// Calculate\n\t\tif (!is_null($rate) && $rate != 0) {\n\t\t\treturn (-$pmt * (1 + $rate * $type) * ((pow(1 + $rate, $nper) - 1) / $rate) - $fv) / pow(1 + $rate, $nper);\n\t\t} else {\n\t\t\treturn -$fv - $pmt * $nper;\n\t\t}\n\t}\t//\tfunction PV()\n\n\n\t/**\n\t * RATE\n\t *\n\t * Returns the interest rate per period of an annuity.\n\t * RATE is calculated by iteration and can have zero or more solutions.\n\t * If the successive results of RATE do not converge to within 0.0000001 after 20 iterations,\n\t * RATE returns the #NUM! error value.\n\t *\n\t * Excel Function:\n\t *\t\tRATE(nper,pmt,pv[,fv[,type[,guess]]])\n\t *\n\t * @access\tpublic\n\t * @category Financial Functions\n\t * @param\tfloat\tnper\t\tThe total number of payment periods in an annuity.\n\t * @param\tfloat\tpmt\t\t\tThe payment made each period and cannot change over the life\n\t *\t\t\t\t\t\t\t\t\tof the annuity.\n\t *\t\t\t\t\t\t\t\tTypically, pmt includes principal and interest but no other\n\t *\t\t\t\t\t\t\t\t\tfees or taxes.\n\t * @param\tfloat\tpv\t\t\tThe present value - the total amount that a series of future\n\t *\t\t\t\t\t\t\t\t\tpayments is worth now.\n\t * @param\tfloat\tfv\t\t\tThe future value, or a cash balance you want to attain after\n\t *\t\t\t\t\t\t\t\t\tthe last payment is made. If fv is omitted, it is assumed\n\t *\t\t\t\t\t\t\t\t\tto be 0 (the future value of a loan, for example, is 0).\n\t * @param\tinteger\ttype\t\tA number 0 or 1 and indicates when payments are due:\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tAt the end of the period.\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tAt the beginning of the period.\n\t * @param\tfloat\tguess\t\tYour guess for what the rate will be.\n\t *\t\t\t\t\t\t\t\t\tIf you omit guess, it is assumed to be 10 percent.\n\t * @return\tfloat\n\t **/\n\tpublic static function RATE($nper, $pmt, $pv, $fv = 0.0, $type = 0, $guess = 0.1) {\n\t\t$nper\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($nper);\n\t\t$pmt\t= PHPExcel_Calculation_Functions::flattenSingleValue($pmt);\n\t\t$pv\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($pv);\n\t\t$fv\t\t= (is_null($fv))\t? 0.0\t:\tPHPExcel_Calculation_Functions::flattenSingleValue($fv);\n\t\t$type\t= (is_null($type))\t? 0\t\t:\t(int) PHPExcel_Calculation_Functions::flattenSingleValue($type);\n\t\t$guess\t= (is_null($guess))\t? 0.1\t:\tPHPExcel_Calculation_Functions::flattenSingleValue($guess);\n\n\t\t$rate = $guess;\n\t\tif (abs($rate) < FINANCIAL_PRECISION) {\n\t\t\t$y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv;\n\t\t} else {\n\t\t\t$f = exp($nper * log(1 + $rate));\n\t\t\t$y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv;\n\t\t}\n\t\t$y0 = $pv + $pmt * $nper + $fv;\n\t\t$y1 = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv;\n\n\t\t// find root by secant method\n\t\t$i  = $x0 = 0.0;\n\t\t$x1 = $rate;\n\t\twhile ((abs($y0 - $y1) > FINANCIAL_PRECISION) && ($i < FINANCIAL_MAX_ITERATIONS)) {\n\t\t\t$rate = ($y1 * $x0 - $y0 * $x1) / ($y1 - $y0);\n\t\t\t$x0 = $x1;\n\t\t\t$x1 = $rate;\n\t\t\tif (($nper * abs($pmt)) > ($pv - $fv))\n\t\t\t\t$x1 = abs($x1);\n\n\t\t\tif (abs($rate) < FINANCIAL_PRECISION) {\n\t\t\t\t$y = $pv * (1 + $nper * $rate) + $pmt * (1 + $rate * $type) * $nper + $fv;\n\t\t\t} else {\n\t\t\t\t$f = exp($nper * log(1 + $rate));\n\t\t\t\t$y = $pv * $f + $pmt * (1 / $rate + $type) * ($f - 1) + $fv;\n\t\t\t}\n\n\t\t\t$y0 = $y1;\n\t\t\t$y1 = $y;\n\t\t\t++$i;\n\t\t}\n\t\treturn $rate;\n\t}\t//\tfunction RATE()\n\n\n\t/**\n\t * RECEIVED\n\t *\n\t * Returns the price per $100 face value of a discounted security.\n\t *\n\t * @param\tmixed\tsettlement\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\tThe security settlement date is the date after the issue date when the security is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe security's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the security expires.\n\t * @param\tint\t\tinvestment\tThe amount invested in the security.\n\t * @param\tint\t\tdiscount\tThe security's discount rate.\n\t * @param\tint\t\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function RECEIVED($settlement, $maturity, $investment, $discount, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$investment\t= (float) PHPExcel_Calculation_Functions::flattenSingleValue($investment);\n\t\t$discount\t= (float) PHPExcel_Calculation_Functions::flattenSingleValue($discount);\n\t\t$basis\t\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\t//\tValidate\n\t\tif ((is_numeric($investment)) && (is_numeric($discount)) && (is_numeric($basis))) {\n\t\t\tif (($investment <= 0) || ($discount <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis);\n\t\t\tif (!is_numeric($daysBetweenSettlementAndMaturity)) {\n\t\t\t\t//\treturn date error\n\t\t\t\treturn $daysBetweenSettlementAndMaturity;\n\t\t\t}\n\n\t\t\treturn $investment / ( 1 - ($discount * $daysBetweenSettlementAndMaturity));\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction RECEIVED()\n\n\n\t/**\n\t * SLN\n\t *\n\t * Returns the straight-line depreciation of an asset for one period\n\t *\n\t * @param\tcost\t\tInitial cost of the asset\n\t * @param\tsalvage\t\tValue at the end of the depreciation\n\t * @param\tlife\t\tNumber of periods over which the asset is depreciated\n\t * @return\tfloat\n\t */\n\tpublic static function SLN($cost, $salvage, $life) {\n\t\t$cost\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($cost);\n\t\t$salvage\t= PHPExcel_Calculation_Functions::flattenSingleValue($salvage);\n\t\t$life\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($life);\n\n\t\t// Calculate\n\t\tif ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life))) {\n\t\t\tif ($life < 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn ($cost - $salvage) / $life;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction SLN()\n\n\n\t/**\n\t * SYD\n\t *\n\t * Returns the sum-of-years' digits depreciation of an asset for a specified period.\n\t *\n\t * @param\tcost\t\tInitial cost of the asset\n\t * @param\tsalvage\t\tValue at the end of the depreciation\n\t * @param\tlife\t\tNumber of periods over which the asset is depreciated\n\t * @param\tperiod\t\tPeriod\n\t * @return\tfloat\n\t */\n\tpublic static function SYD($cost, $salvage, $life, $period) {\n\t\t$cost\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($cost);\n\t\t$salvage\t= PHPExcel_Calculation_Functions::flattenSingleValue($salvage);\n\t\t$life\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($life);\n\t\t$period\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($period);\n\n\t\t// Calculate\n\t\tif ((is_numeric($cost)) && (is_numeric($salvage)) && (is_numeric($life)) && (is_numeric($period))) {\n\t\t\tif (($life < 1) || ($period > $life)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn (($cost - $salvage) * ($life - $period + 1) * 2) / ($life * ($life + 1));\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction SYD()\n\n\n\t/**\n\t * TBILLEQ\n\t *\n\t * Returns the bond-equivalent yield for a Treasury bill.\n\t *\n\t * @param\tmixed\tsettlement\tThe Treasury bill's settlement date.\n\t *\t\t\t\t\t\t\t\tThe Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe Treasury bill's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the Treasury bill expires.\n\t * @param\tint\t\tdiscount\tThe Treasury bill's discount rate.\n\t * @return\tfloat\n\t */\n\tpublic static function TBILLEQ($settlement, $maturity, $discount) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$discount\t= PHPExcel_Calculation_Functions::flattenSingleValue($discount);\n\n\t\t//\tUse TBILLPRICE for validation\n\t\t$testValue = self::TBILLPRICE($settlement, $maturity, $discount);\n\t\tif (is_string($testValue)) {\n\t\t\treturn $testValue;\n\t\t}\n\n\t\tif (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {\n\t\t\t++$maturity;\n\t\t\t$daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360;\n\t\t} else {\n\t\t\t$daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement));\n\t\t}\n\n\t\treturn (365 * $discount) / (360 - $discount * $daysBetweenSettlementAndMaturity);\n\t}\t//\tfunction TBILLEQ()\n\n\n\t/**\n\t * TBILLPRICE\n\t *\n\t * Returns the yield for a Treasury bill.\n\t *\n\t * @param\tmixed\tsettlement\tThe Treasury bill's settlement date.\n\t *\t\t\t\t\t\t\t\tThe Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe Treasury bill's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the Treasury bill expires.\n\t * @param\tint\t\tdiscount\tThe Treasury bill's discount rate.\n\t * @return\tfloat\n\t */\n\tpublic static function TBILLPRICE($settlement, $maturity, $discount) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$discount\t= PHPExcel_Calculation_Functions::flattenSingleValue($discount);\n\n\t\tif (is_string($maturity = PHPExcel_Calculation_DateTime::_getDateValue($maturity))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t//\tValidate\n\t\tif (is_numeric($discount)) {\n\t\t\tif ($discount <= 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {\n\t\t\t\t++$maturity;\n\t\t\t\t$daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360;\n\t\t\t\tif (!is_numeric($daysBetweenSettlementAndMaturity)) {\n\t\t\t\t\t//\treturn date error\n\t\t\t\t\treturn $daysBetweenSettlementAndMaturity;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement));\n\t\t\t}\n\n\t\t\tif ($daysBetweenSettlementAndMaturity > 360) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\n\t\t\t$price = 100 * (1 - (($discount * $daysBetweenSettlementAndMaturity) / 360));\n\t\t\tif ($price <= 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn $price;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction TBILLPRICE()\n\n\n\t/**\n\t * TBILLYIELD\n\t *\n\t * Returns the yield for a Treasury bill.\n\t *\n\t * @param\tmixed\tsettlement\tThe Treasury bill's settlement date.\n\t *\t\t\t\t\t\t\t\tThe Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe Treasury bill's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the Treasury bill expires.\n\t * @param\tint\t\tprice\t\tThe Treasury bill's price per $100 face value.\n\t * @return\tfloat\n\t */\n\tpublic static function TBILLYIELD($settlement, $maturity, $price) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$price\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($price);\n\n\t\t//\tValidate\n\t\tif (is_numeric($price)) {\n\t\t\tif ($price <= 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {\n\t\t\t\t++$maturity;\n\t\t\t\t$daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity) * 360;\n\t\t\t\tif (!is_numeric($daysBetweenSettlementAndMaturity)) {\n\t\t\t\t\t//\treturn date error\n\t\t\t\t\treturn $daysBetweenSettlementAndMaturity;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$daysBetweenSettlementAndMaturity = (PHPExcel_Calculation_DateTime::_getDateValue($maturity) - PHPExcel_Calculation_DateTime::_getDateValue($settlement));\n\t\t\t}\n\n\t\t\tif ($daysBetweenSettlementAndMaturity > 360) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\n\t\t\treturn ((100 - $price) / $price) * (360 / $daysBetweenSettlementAndMaturity);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction TBILLYIELD()\n\n\n\tpublic static function XIRR($values, $dates, $guess = 0.1) {\n\t\tif ((!is_array($values)) && (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE();\n\t\t$values\t= PHPExcel_Calculation_Functions::flattenArray($values);\n\t\t$dates\t= PHPExcel_Calculation_Functions::flattenArray($dates);\n\t\t$guess = PHPExcel_Calculation_Functions::flattenSingleValue($guess);\n\t\tif (count($values) != count($dates)) return PHPExcel_Calculation_Functions::NaN();\n\n\t\t// create an initial range, with a root somewhere between 0 and guess\n\t\t$x1 = 0.0;\n\t\t$x2 = $guess;\n\t\t$f1 = self::XNPV($x1, $values, $dates);\n\t\t$f2 = self::XNPV($x2, $values, $dates);\n\t\tfor ($i = 0; $i < FINANCIAL_MAX_ITERATIONS; ++$i) {\n\t\t\tif (($f1 * $f2) < 0.0) break;\n\t\t\tif (abs($f1) < abs($f2)) {\n\t\t\t\t$f1 = self::XNPV($x1 += 1.6 * ($x1 - $x2), $values, $dates);\n\t\t\t} else {\n\t\t\t\t$f2 = self::XNPV($x2 += 1.6 * ($x2 - $x1), $values, $dates);\n\t\t\t}\n\t\t}\n\t\tif (($f1 * $f2) > 0.0) return PHPExcel_Calculation_Functions::VALUE();\n\n\t\t$f = self::XNPV($x1, $values, $dates);\n\t\tif ($f < 0.0) {\n\t\t\t$rtb = $x1;\n\t\t\t$dx = $x2 - $x1;\n\t\t} else {\n\t\t\t$rtb = $x2;\n\t\t\t$dx = $x1 - $x2;\n\t\t}\n\n\t\tfor ($i = 0;  $i < FINANCIAL_MAX_ITERATIONS; ++$i) {\n\t\t\t$dx *= 0.5;\n\t\t\t$x_mid = $rtb + $dx;\n\t\t\t$f_mid = self::XNPV($x_mid, $values, $dates);\n\t\t\tif ($f_mid <= 0.0) $rtb = $x_mid;\n\t\t\tif ((abs($f_mid) < FINANCIAL_PRECISION) || (abs($dx) < FINANCIAL_PRECISION)) return $x_mid;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\n\n\n\t/**\n\t * XNPV\n\t *\n\t * Returns the net present value for a schedule of cash flows that is not necessarily periodic.\n\t * To calculate the net present value for a series of cash flows that is periodic, use the NPV function.\n\t *\n\t * Excel Function:\n\t *\t\t=XNPV(rate,values,dates)\n\t *\n\t * @param\tfloat\t\t\t$rate\t\tThe discount rate to apply to the cash flows.\n\t * @param\tarray of float\t$values\t\tA series of cash flows that corresponds to a schedule of payments in dates. The first payment is optional and corresponds to a cost or payment that occurs at the beginning of the investment. If the first value is a cost or payment, it must be a negative value. All succeeding payments are discounted based on a 365-day year. The series of values must contain at least one positive value and one negative value.\n\t * @param\tarray of mixed\t$dates\t\tA schedule of payment dates that corresponds to the cash flow payments. The first payment date indicates the beginning of the schedule of payments. All other dates must be later than this date, but they may occur in any order.\n\t * @return\tfloat\n\t */\n\tpublic static function XNPV($rate, $values, $dates) {\n\t\t$rate = PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\tif (!is_numeric($rate)) return PHPExcel_Calculation_Functions::VALUE();\n\t\tif ((!is_array($values)) || (!is_array($dates))) return PHPExcel_Calculation_Functions::VALUE();\n\t\t$values\t= PHPExcel_Calculation_Functions::flattenArray($values);\n\t\t$dates\t= PHPExcel_Calculation_Functions::flattenArray($dates);\n\t\t$valCount = count($values);\n\t\tif ($valCount != count($dates)) return PHPExcel_Calculation_Functions::NaN();\n\t\tif ((min($values) > 0) || (max($values) < 0)) return PHPExcel_Calculation_Functions::VALUE();\n\n\t\t$xnpv = 0.0;\n\t\tfor ($i = 0; $i < $valCount; ++$i) {\n\t\t\tif (!is_numeric($values[$i])) return PHPExcel_Calculation_Functions::VALUE();\n\t\t\t$xnpv += $values[$i] / pow(1 + $rate, PHPExcel_Calculation_DateTime::DATEDIF($dates[0],$dates[$i],'d') / 365);\n\t\t}\n\t\treturn (is_finite($xnpv)) ? $xnpv : PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction XNPV()\n\n\n\t/**\n\t * YIELDDISC\n\t *\n\t * Returns the annual yield of a security that pays interest at maturity.\n\t *\n\t * @param\tmixed\tsettlement\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\tThe security's settlement date is the date after the issue date when the security is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe security's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the security expires.\n\t * @param\tint\t\tprice\t\tThe security's price per $100 face value.\n\t * @param\tint\t\tredemption\tThe security's redemption value per $100 face value.\n\t * @param\tint\t\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function YIELDDISC($settlement, $maturity, $price, $redemption, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$price\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($price);\n\t\t$redemption\t= PHPExcel_Calculation_Functions::flattenSingleValue($redemption);\n\t\t$basis\t\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\t//\tValidate\n\t\tif (is_numeric($price) && is_numeric($redemption)) {\n\t\t\tif (($price <= 0) || ($redemption <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis);\n\t\t\tif (!is_numeric($daysPerYear)) {\n\t\t\t\treturn $daysPerYear;\n\t\t\t}\n\t\t\t$daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity,$basis);\n\t\t\tif (!is_numeric($daysBetweenSettlementAndMaturity)) {\n\t\t\t\t//\treturn date error\n\t\t\t\treturn $daysBetweenSettlementAndMaturity;\n\t\t\t}\n\t\t\t$daysBetweenSettlementAndMaturity *= $daysPerYear;\n\n\t\t\treturn (($redemption - $price) / $price) * ($daysPerYear / $daysBetweenSettlementAndMaturity);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction YIELDDISC()\n\n\n\t/**\n\t * YIELDMAT\n\t *\n\t * Returns the annual yield of a security that pays interest at maturity.\n\t *\n\t * @param\tmixed\tsettlement\tThe security's settlement date.\n\t *\t\t\t\t\t\t\t\tThe security's settlement date is the date after the issue date when the security is traded to the buyer.\n\t * @param\tmixed\tmaturity\tThe security's maturity date.\n\t *\t\t\t\t\t\t\t\tThe maturity date is the date when the security expires.\n\t * @param\tmixed\tissue\t\tThe security's issue date.\n\t * @param\tint\t\trate\t\tThe security's interest rate at date of issue.\n\t * @param\tint\t\tprice\t\tThe security's price per $100 face value.\n\t * @param\tint\t\tbasis\t\tThe type of day count to use.\n\t *\t\t\t\t\t\t\t\t\t\t0 or omitted\tUS (NASD) 30/360\n\t *\t\t\t\t\t\t\t\t\t\t1\t\t\t\tActual/actual\n\t *\t\t\t\t\t\t\t\t\t\t2\t\t\t\tActual/360\n\t *\t\t\t\t\t\t\t\t\t\t3\t\t\t\tActual/365\n\t *\t\t\t\t\t\t\t\t\t\t4\t\t\t\tEuropean 30/360\n\t * @return\tfloat\n\t */\n\tpublic static function YIELDMAT($settlement, $maturity, $issue, $rate, $price, $basis=0) {\n\t\t$settlement\t= PHPExcel_Calculation_Functions::flattenSingleValue($settlement);\n\t\t$maturity\t= PHPExcel_Calculation_Functions::flattenSingleValue($maturity);\n\t\t$issue\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($issue);\n\t\t$rate\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($rate);\n\t\t$price\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($price);\n\t\t$basis\t\t= (int) PHPExcel_Calculation_Functions::flattenSingleValue($basis);\n\n\t\t//\tValidate\n\t\tif (is_numeric($rate) && is_numeric($price)) {\n\t\t\tif (($rate <= 0) || ($price <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$daysPerYear = self::_daysPerYear(PHPExcel_Calculation_DateTime::YEAR($settlement),$basis);\n\t\t\tif (!is_numeric($daysPerYear)) {\n\t\t\t\treturn $daysPerYear;\n\t\t\t}\n\t\t\t$daysBetweenIssueAndSettlement = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $settlement, $basis);\n\t\t\tif (!is_numeric($daysBetweenIssueAndSettlement)) {\n\t\t\t\t//\treturn date error\n\t\t\t\treturn $daysBetweenIssueAndSettlement;\n\t\t\t}\n\t\t\t$daysBetweenIssueAndSettlement *= $daysPerYear;\n\t\t\t$daysBetweenIssueAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($issue, $maturity, $basis);\n\t\t\tif (!is_numeric($daysBetweenIssueAndMaturity)) {\n\t\t\t\t//\treturn date error\n\t\t\t\treturn $daysBetweenIssueAndMaturity;\n\t\t\t}\n\t\t\t$daysBetweenIssueAndMaturity *= $daysPerYear;\n\t\t\t$daysBetweenSettlementAndMaturity = PHPExcel_Calculation_DateTime::YEARFRAC($settlement, $maturity, $basis);\n\t\t\tif (!is_numeric($daysBetweenSettlementAndMaturity)) {\n\t\t\t\t//\treturn date error\n\t\t\t\treturn $daysBetweenSettlementAndMaturity;\n\t\t\t}\n\t\t\t$daysBetweenSettlementAndMaturity *= $daysPerYear;\n\n\t\t\treturn ((1 + (($daysBetweenIssueAndMaturity / $daysPerYear) * $rate) - (($price / 100) + (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate))) /\n\t\t\t\t   (($price / 100) + (($daysBetweenIssueAndSettlement / $daysPerYear) * $rate))) *\n\t\t\t\t   ($daysPerYear / $daysBetweenSettlementAndMaturity);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction YIELDMAT()\n\n}\t//\tclass PHPExcel_Calculation_Financial\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/FormulaParser.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/*\nPARTLY BASED ON:\n\tCopyright (c) 2007 E. W. Bachtal, Inc.\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy of this software\n\tand associated documentation files (the \"Software\"), to deal in the Software without restriction,\n\tincluding without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,\n\tand/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,\n\tsubject to the following conditions:\n\n\t  The above copyright notice and this permission notice shall be included in all copies or substantial\n\t  portions of the Software.\n\n\tThe software is provided \"as is\", without warranty of any kind, express or implied, including but not\n\tlimited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In\n\tno event shall the authors or copyright holders be liable for any claim, damages or other liability,\n\twhether in an action of contract, tort or otherwise, arising from, out of or in connection with the\n\tsoftware or the use or other dealings in the software.\n\n\thttp://ewbi.blogs.com/develops/2007/03/excel_formula_p.html\n\thttp://ewbi.blogs.com/develops/2004/12/excel_formula_p.html\n*/\n\n/**\n * PHPExcel_Calculation_FormulaParser\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_FormulaParser {\n\t/* Character constants */\n\tconst QUOTE_DOUBLE  = '\"';\n\tconst QUOTE_SINGLE  = '\\'';\n\tconst BRACKET_CLOSE = ']';\n\tconst BRACKET_OPEN  = '[';\n\tconst BRACE_OPEN    = '{';\n\tconst BRACE_CLOSE   = '}';\n\tconst PAREN_OPEN    = '(';\n\tconst PAREN_CLOSE   = ')';\n\tconst SEMICOLON     = ';';\n\tconst WHITESPACE    = ' ';\n\tconst COMMA         = ',';\n\tconst ERROR_START   = '#';\n\n\tconst OPERATORS_SN \t\t\t= \"+-\";\n\tconst OPERATORS_INFIX \t\t= \"+-*/^&=><\";\n\tconst OPERATORS_POSTFIX \t= \"%\";\n\n\t/**\n\t * Formula\n\t *\n\t * @var string\n\t */\n\tprivate $_formula;\n\n\t/**\n\t * Tokens\n\t *\n\t * @var PHPExcel_Calculation_FormulaToken[]\n\t */\n\tprivate $_tokens = array();\n\n    /**\n     * Create a new PHPExcel_Calculation_FormulaParser\n     *\n     * @param \tstring\t\t$pFormula\tFormula to parse\n     * @throws \tPHPExcel_Calculation_Exception\n     */\n    public function __construct($pFormula = '')\n    {\n    \t// Check parameters\n    \tif (is_null($pFormula)) {\n    \t\tthrow new PHPExcel_Calculation_Exception(\"Invalid parameter passed: formula\");\n    \t}\n\n    \t// Initialise values\n    \t$this->_formula = trim($pFormula);\n    \t// Parse!\n    \t$this->_parseToTokens();\n    }\n\n    /**\n     * Get Formula\n     *\n     * @return string\n     */\n    public function getFormula() {\n    \treturn $this->_formula;\n    }\n\n    /**\n     * Get Token\n     *\n     * @param \tint\t\t$pId\tToken id\n     * @return\tstring\n     * @throws  PHPExcel_Calculation_Exception\n     */\n    public function getToken($pId = 0) {\n    \tif (isset($this->_tokens[$pId])) {\n    \t\treturn $this->_tokens[$pId];\n    \t} else {\n    \t\tthrow new PHPExcel_Calculation_Exception(\"Token with id $pId does not exist.\");\n    \t}\n    }\n\n    /**\n     * Get Token count\n     *\n     * @return string\n     */\n    public function getTokenCount() {\n    \treturn count($this->_tokens);\n    }\n\n    /**\n     * Get Tokens\n     *\n     * @return PHPExcel_Calculation_FormulaToken[]\n     */\n    public function getTokens() {\n    \treturn $this->_tokens;\n    }\n\n    /**\n     * Parse to tokens\n     */\n    private function _parseToTokens() {\n\t\t// No attempt is made to verify formulas; assumes formulas are derived from Excel, where\n\t\t// they can only exist if valid; stack overflows/underflows sunk as nulls without exceptions.\n\n\t\t// Check if the formula has a valid starting =\n\t\t$formulaLength = strlen($this->_formula);\n\t\tif ($formulaLength < 2 || $this->_formula{0} != '=') return;\n\n\t\t// Helper variables\n\t\t$tokens1\t= $tokens2 \t= $stack = array();\n\t\t$inString\t= $inPath \t= $inRange \t= $inError = false;\n\t\t$token\t\t= $previousToken\t= $nextToken\t= null;\n\n\t\t$index\t= 1;\n\t\t$value\t= '';\n\n\t\t$ERRORS \t\t\t= array(\"#NULL!\", \"#DIV/0!\", \"#VALUE!\", \"#REF!\", \"#NAME?\", \"#NUM!\", \"#N/A\");\n\t\t$COMPARATORS_MULTI \t= array(\">=\", \"<=\", \"<>\");\n\n\t\twhile ($index < $formulaLength) {\n\t\t\t// state-dependent character evaluation (order is important)\n\n\t\t\t// double-quoted strings\n\t\t\t// embeds are doubled\n\t\t\t// end marks token\n\t\t\tif ($inString) {\n\t\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) {\n\t\t\t\t\tif ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE)) {\n\t\t\t\t\t\t$value .= PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE;\n\t\t\t\t\t\t++$index;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$inString = false;\n\t\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_TEXT);\n\t\t\t\t\t\t$value = \"\";\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t$value .= $this->_formula{$index};\n\t\t\t\t}\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// single-quoted strings (links)\n\t\t\t// embeds are double\n\t\t\t// end does not mark a token\n\t\t\tif ($inPath) {\n\t\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) {\n\t\t\t\t\tif ((($index + 2) <= $formulaLength) && ($this->_formula{$index + 1} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE)) {\n\t\t\t\t\t\t$value .= PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE;\n\t\t\t\t\t\t++$index;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$inPath = false;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t$value .= $this->_formula{$index};\n\t\t\t\t}\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// bracked strings (R1C1 range index or linked workbook name)\n\t\t\t// no embeds (changed to \"()\" by Excel)\n\t\t\t// end does not mark a token\n\t\t\tif ($inRange) {\n\t\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_CLOSE) {\n\t\t\t\t\t$inRange = false;\n\t\t\t\t}\n\t\t\t\t$value .= $this->_formula{$index};\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// error values\n\t\t\t// end marks a token, determined from absolute list of values\n\t\t\tif ($inError) {\n\t\t\t\t$value .= $this->_formula{$index};\n\t\t\t\t++$index;\n\t\t\t\tif (in_array($value, $ERRORS)) {\n\t\t\t\t\t$inError = false;\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_ERROR);\n\t\t\t\t\t$value = \"\";\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// scientific notation check\n\t\t\tif (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_SN, $this->_formula{$index}) !== false) {\n\t\t\t\tif (strlen($value) > 1) {\n\t\t\t\t\tif (preg_match(\"/^[1-9]{1}(\\.[0-9]+)?E{1}$/\", $this->_formula{$index}) != 0) {\n\t\t\t\t\t\t$value .= $this->_formula{$index};\n\t\t\t\t\t\t++$index;\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// independent character evaluation (order not important)\n\n\t\t\t// establish state-dependent character evaluations\n\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_DOUBLE) {\n\t\t\t\tif (strlen($value > 0)) {  // unexpected\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN);\n\t\t\t\t\t$value = \"\";\n\t\t\t\t}\n\t\t\t\t$inString = true;\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n \t\t\t}\n\n\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::QUOTE_SINGLE) {\n\t\t\t\tif (strlen($value) > 0) { // unexpected\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN);\n\t\t\t\t\t$value = \"\";\n\t\t\t\t}\n\t\t\t\t$inPath = true;\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACKET_OPEN) {\n\t\t\t\t$inRange = true;\n\t\t\t\t$value .= PHPExcel_Calculation_FormulaParser::BRACKET_OPEN;\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::ERROR_START) {\n\t\t\t\tif (strlen($value) > 0) { // unexpected\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN);\n\t\t\t\t\t$value = \"\";\n\t\t\t\t}\n\t\t\t\t$inError = true;\n\t\t\t\t$value .= PHPExcel_Calculation_FormulaParser::ERROR_START;\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// mark start and end of arrays and array rows\n\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_OPEN) {\n\t\t\t\tif (strlen($value) > 0) { // unexpected\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN);\n\t\t\t\t\t$value = \"\";\n\t\t\t\t}\n\n\t\t\t\t$tmp = new PHPExcel_Calculation_FormulaToken(\"ARRAY\", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START);\n\t\t\t\t$tokens1[] = $tmp;\n\t\t\t\t$stack[] = clone $tmp;\n\n\t\t\t\t$tmp = new PHPExcel_Calculation_FormulaToken(\"ARRAYROW\", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START);\n\t\t\t\t$tokens1[] = $tmp;\n\t\t\t\t$stack[] = clone $tmp;\n\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::SEMICOLON) {\n\t\t\t\tif (strlen($value) > 0) {\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);\n\t\t\t\t\t$value = \"\";\n\t\t\t\t}\n\n\t\t\t\t$tmp = array_pop($stack);\n\t\t\t\t$tmp->setValue(\"\");\n\t\t\t\t$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP);\n\t\t\t\t$tokens1[] = $tmp;\n\n\t\t\t\t$tmp = new PHPExcel_Calculation_FormulaToken(\",\", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT);\n\t\t\t\t$tokens1[] = $tmp;\n\n\t\t\t\t$tmp = new PHPExcel_Calculation_FormulaToken(\"ARRAYROW\", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START);\n\t\t\t\t$tokens1[] = $tmp;\n\t\t\t\t$stack[] = clone $tmp;\n\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::BRACE_CLOSE) {\n\t\t\t\tif (strlen($value) > 0) {\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);\n\t\t\t\t\t$value = \"\";\n\t\t\t\t}\n\n\t\t\t\t$tmp = array_pop($stack);\n\t\t\t\t$tmp->setValue(\"\");\n\t\t\t\t$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP);\n\t\t\t\t$tokens1[] = $tmp;\n\n\t\t\t\t$tmp = array_pop($stack);\n\t\t\t\t$tmp->setValue(\"\");\n\t\t\t\t$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP);\n\t\t\t\t$tokens1[] = $tmp;\n\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// trim white-space\n\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) {\n\t\t\t\tif (strlen($value) > 0) {\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);\n\t\t\t\t\t$value = \"\";\n\t\t\t\t}\n\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken(\"\", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE);\n\t\t\t\t++$index;\n\t\t\t\twhile (($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::WHITESPACE) && ($index < $formulaLength)) {\n\t\t\t\t\t++$index;\n\t\t\t\t}\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// multi-character comparators\n\t\t\tif (($index + 2) <= $formulaLength) {\n\t\t\t\tif (in_array(substr($this->_formula, $index, 2), $COMPARATORS_MULTI)) {\n\t\t\t\t\tif (strlen($value) > 0) {\n\t\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);\n\t\t\t\t\t\t$value = \"\";\n\t\t\t\t\t}\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken(substr($this->_formula, $index, 2), PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL);\n\t\t\t\t\t$index += 2;\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// standard infix operators\n\t\t\tif (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_INFIX, $this->_formula{$index}) !== false) {\n\t\t\t\tif (strlen($value) > 0) {\n\t\t\t\t\t$tokens1[] =new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);\n\t\t\t\t\t$value = \"\";\n\t\t\t\t}\n\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($this->_formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX);\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// standard postfix operators (only one)\n\t\t\tif (strpos(PHPExcel_Calculation_FormulaParser::OPERATORS_POSTFIX, $this->_formula{$index}) !== false) {\n\t\t\t\tif (strlen($value) > 0) {\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);\n\t\t\t\t\t$value = \"\";\n\t\t\t\t}\n\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($this->_formula{$index}, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX);\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// start subexpression or function\n\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_OPEN) {\n\t\t\t\tif (strlen($value) > 0) {\n\t\t\t\t\t$tmp = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START);\n\t\t\t\t\t$tokens1[] = $tmp;\n\t\t\t\t\t$stack[] = clone $tmp;\n\t\t\t\t\t$value = \"\";\n\t\t\t\t} else {\n\t\t\t\t\t$tmp = new PHPExcel_Calculation_FormulaToken(\"\", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START);\n\t\t\t\t\t$tokens1[] = $tmp;\n\t\t\t\t\t$stack[] = clone $tmp;\n\t\t\t\t}\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// function, subexpression, or array parameters, or operand unions\n\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::COMMA) {\n\t\t\t\tif (strlen($value) > 0) {\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);\n\t\t\t\t\t$value = \"\";\n\t\t\t\t}\n\n\t\t\t\t$tmp = array_pop($stack);\n\t\t\t\t$tmp->setValue(\"\");\n\t\t\t\t$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP);\n\t\t\t\t$stack[] = $tmp;\n\n\t\t\t\tif ($tmp->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) {\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken(\",\", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_UNION);\n\t\t\t\t} else {\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken(\",\", PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_ARGUMENT);\n\t\t\t\t}\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// stop subexpression\n\t\t\tif ($this->_formula{$index} == PHPExcel_Calculation_FormulaParser::PAREN_CLOSE) {\n\t\t\t\tif (strlen($value) > 0) {\n\t\t\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);\n\t\t\t\t\t$value = \"\";\n\t\t\t\t}\n\n\t\t\t\t$tmp = array_pop($stack);\n\t\t\t\t$tmp->setValue(\"\");\n\t\t\t\t$tmp->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP);\n\t\t\t\t$tokens1[] = $tmp;\n\n\t\t\t\t++$index;\n\t\t\t\tcontinue;\n\t\t\t}\n\n        \t// token accumulation\n\t\t\t$value .= $this->_formula{$index};\n\t\t\t++$index;\n\t\t}\n\n\t\t// dump remaining accumulation\n\t\tif (strlen($value) > 0) {\n\t\t\t$tokens1[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND);\n\t\t}\n\n\t\t// move tokenList to new set, excluding unnecessary white-space tokens and converting necessary ones to intersections\n\t\t$tokenCount = count($tokens1);\n\t\tfor ($i = 0; $i < $tokenCount; ++$i) {\n\t\t\t$token = $tokens1[$i];\n\t\t\tif (isset($tokens1[$i - 1])) {\n\t\t\t\t$previousToken = $tokens1[$i - 1];\n\t\t\t} else {\n\t\t\t\t$previousToken = null;\n\t\t\t}\n\t\t\tif (isset($tokens1[$i + 1])) {\n\t\t\t\t$nextToken = $tokens1[$i + 1];\n\t\t\t} else {\n\t\t\t\t$nextToken = null;\n\t\t\t}\n\n\t\t\tif (is_null($token)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ($token->getTokenType() != PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_WHITESPACE) {\n\t\t\t\t$tokens2[] = $token;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (is_null($previousToken)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (! (\n\t\t\t\t\t(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||\n\t\t\t\t\t(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||\n\t\t\t\t\t($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)\n\t\t\t\t  ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (is_null($nextToken)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif (! (\n\t\t\t\t\t(($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) ||\n\t\t\t\t\t(($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($nextToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_START)) ||\n\t\t\t\t\t($nextToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)\n\t\t\t\t  ) ) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t$tokens2[] = new PHPExcel_Calculation_FormulaToken($value, PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX, PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_INTERSECTION);\n\t\t}\n\n\t\t// move tokens to final list, switching infix \"-\" operators to prefix when appropriate, switching infix \"+\" operators\n\t\t// to noop when appropriate, identifying operand and infix-operator subtypes, and pulling \"@\" from function names\n\t\t$this->_tokens = array();\n\n\t\t$tokenCount = count($tokens2);\n\t\tfor ($i = 0; $i < $tokenCount; ++$i) {\n\t\t\t$token = $tokens2[$i];\n\t\t\tif (isset($tokens2[$i - 1])) {\n\t\t\t\t$previousToken = $tokens2[$i - 1];\n\t\t\t} else {\n\t\t\t\t$previousToken = null;\n\t\t\t}\n\t\t\tif (isset($tokens2[$i + 1])) {\n\t\t\t\t$nextToken = $tokens2[$i + 1];\n\t\t\t} else {\n\t\t\t\t$nextToken = null;\n\t\t\t}\n\n\t\t\tif (is_null($token)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == \"-\") {\n\t\t\t\tif ($i == 0) {\n\t\t\t\t\t$token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX);\n\t\t\t\t} else if (\n\t\t\t\t\t\t\t(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||\n\t\t\t\t\t\t\t(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||\n\t\t\t\t\t\t\t($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) ||\n\t\t\t\t\t\t\t($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)\n\t\t\t\t\t\t) {\n\t\t\t\t\t$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH);\n\t\t\t\t} else {\n\t\t\t\t\t$token->setTokenType(PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPREFIX);\n\t\t\t\t}\n\n\t\t\t\t$this->_tokens[] = $token;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getValue() == \"+\") {\n\t\t\t\tif ($i == 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t} else if (\n\t\t\t\t\t\t\t(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||\n\t\t\t\t\t\t\t(($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_SUBEXPRESSION) && ($previousToken->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_STOP)) ||\n\t\t\t\t\t\t\t($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORPOSTFIX) ||\n\t\t\t\t\t\t\t($previousToken->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND)\n\t\t\t\t\t\t) {\n\t\t\t\t\t$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH);\n\t\t\t\t} else {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t$this->_tokens[] = $token;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERATORINFIX && $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) {\n\t\t\t\tif (strpos(\"<>=\", substr($token->getValue(), 0, 1)) !== false) {\n\t\t\t\t\t$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL);\n\t\t\t\t} else if ($token->getValue() == \"&\") {\n\t\t\t\t\t$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_CONCATENATION);\n\t\t\t\t} else {\n\t\t\t\t\t$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_MATH);\n\t\t\t\t}\n\n\t\t\t\t$this->_tokens[] = $token;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_OPERAND && $token->getTokenSubType() == PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) {\n\t\t\t\tif (!is_numeric($token->getValue())) {\n\t\t\t\t\tif (strtoupper($token->getValue()) == \"TRUE\" || strtoupper($token->getValue() == \"FALSE\")) {\n\t\t\t\t\t\t$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_LOGICAL);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_RANGE);\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t$token->setTokenSubType(PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NUMBER);\n\t\t\t\t}\n\n\t\t\t\t$this->_tokens[] = $token;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\tif ($token->getTokenType() == PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_FUNCTION) {\n\t\t\t\tif (strlen($token->getValue() > 0)) {\n\t\t\t\t\tif (substr($token->getValue(), 0, 1) == \"@\") {\n\t\t\t\t\t\t$token->setValue(substr($token->getValue(), 1));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n        \t$this->_tokens[] = $token;\n\t\t}\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/FormulaToken.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/*\nPARTLY BASED ON:\n\tCopyright (c) 2007 E. W. Bachtal, Inc.\n\n\tPermission is hereby granted, free of charge, to any person obtaining a copy of this software\n\tand associated documentation files (the \"Software\"), to deal in the Software without restriction,\n\tincluding without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,\n\tand/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,\n\tsubject to the following conditions:\n\n\t  The above copyright notice and this permission notice shall be included in all copies or substantial\n\t  portions of the Software.\n\n\tThe software is provided \"as is\", without warranty of any kind, express or implied, including but not\n\tlimited to the warranties of merchantability, fitness for a particular purpose and noninfringement. In\n\tno event shall the authors or copyright holders be liable for any claim, damages or other liability,\n\twhether in an action of contract, tort or otherwise, arising from, out of or in connection with the\n\tsoftware or the use or other dealings in the software.\n\n\thttp://ewbi.blogs.com/develops/2007/03/excel_formula_p.html\n\thttp://ewbi.blogs.com/develops/2004/12/excel_formula_p.html\n*/\n\n\n/**\n * PHPExcel_Calculation_FormulaToken\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_FormulaToken {\n\t/* Token types */\n\tconst TOKEN_TYPE_NOOP\t\t\t\t\t= 'Noop';\n\tconst TOKEN_TYPE_OPERAND\t\t\t\t= 'Operand';\n\tconst TOKEN_TYPE_FUNCTION\t\t\t\t= 'Function';\n\tconst TOKEN_TYPE_SUBEXPRESSION\t\t\t= 'Subexpression';\n\tconst TOKEN_TYPE_ARGUMENT\t\t\t\t= 'Argument';\n\tconst TOKEN_TYPE_OPERATORPREFIX\t\t\t= 'OperatorPrefix';\n\tconst TOKEN_TYPE_OPERATORINFIX\t\t\t= 'OperatorInfix';\n\tconst TOKEN_TYPE_OPERATORPOSTFIX\t\t= 'OperatorPostfix';\n\tconst TOKEN_TYPE_WHITESPACE\t\t\t\t= 'Whitespace';\n\tconst TOKEN_TYPE_UNKNOWN\t\t\t\t= 'Unknown';\n\n\t/* Token subtypes */\n\tconst TOKEN_SUBTYPE_NOTHING\t\t\t\t= 'Nothing';\n\tconst TOKEN_SUBTYPE_START\t\t\t\t= 'Start';\n\tconst TOKEN_SUBTYPE_STOP\t\t\t\t= 'Stop';\n\tconst TOKEN_SUBTYPE_TEXT\t\t\t\t= 'Text';\n\tconst TOKEN_SUBTYPE_NUMBER\t\t\t\t= 'Number';\n\tconst TOKEN_SUBTYPE_LOGICAL\t\t\t\t= 'Logical';\n\tconst TOKEN_SUBTYPE_ERROR\t\t\t\t= 'Error';\n\tconst TOKEN_SUBTYPE_RANGE\t\t\t\t= 'Range';\n\tconst TOKEN_SUBTYPE_MATH\t\t\t\t= 'Math';\n\tconst TOKEN_SUBTYPE_CONCATENATION\t\t= 'Concatenation';\n\tconst TOKEN_SUBTYPE_INTERSECTION\t\t= 'Intersection';\n\tconst TOKEN_SUBTYPE_UNION\t\t\t\t= 'Union';\n\n\t/**\n\t * Value\n\t *\n\t * @var string\n\t */\n\tprivate $_value;\n\n\t/**\n\t * Token Type (represented by TOKEN_TYPE_*)\n\t *\n\t * @var string\n\t */\n\tprivate $_tokenType;\n\n\t/**\n\t * Token SubType (represented by TOKEN_SUBTYPE_*)\n\t *\n\t * @var string\n\t */\n\tprivate $_tokenSubType;\n\n    /**\n     * Create a new PHPExcel_Calculation_FormulaToken\n     *\n     * @param string\t$pValue\n     * @param string\t$pTokenType \tToken type (represented by TOKEN_TYPE_*)\n     * @param string\t$pTokenSubType \tToken Subtype (represented by TOKEN_SUBTYPE_*)\n     */\n    public function __construct($pValue, $pTokenType = PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN, $pTokenSubType = PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING)\n    {\n    \t// Initialise values\n    \t$this->_value\t\t\t\t= $pValue;\n    \t$this->_tokenType\t\t\t= $pTokenType;\n    \t$this->_tokenSubType \t\t= $pTokenSubType;\n    }\n\n    /**\n     * Get Value\n     *\n     * @return string\n     */\n    public function getValue() {\n    \treturn $this->_value;\n    }\n\n    /**\n     * Set Value\n     *\n     * @param string\t$value\n     */\n    public function setValue($value) {\n    \t$this->_value = $value;\n    }\n\n    /**\n     * Get Token Type (represented by TOKEN_TYPE_*)\n     *\n     * @return string\n     */\n    public function getTokenType() {\n    \treturn $this->_tokenType;\n    }\n\n    /**\n     * Set Token Type\n     *\n     * @param string\t$value\n     */\n    public function setTokenType($value = PHPExcel_Calculation_FormulaToken::TOKEN_TYPE_UNKNOWN) {\n    \t$this->_tokenType = $value;\n    }\n\n    /**\n     * Get Token SubType (represented by TOKEN_SUBTYPE_*)\n     *\n     * @return string\n     */\n    public function getTokenSubType() {\n    \treturn $this->_tokenSubType;\n    }\n\n    /**\n     * Set Token SubType\n     *\n     * @param string\t$value\n     */\n    public function setTokenSubType($value = PHPExcel_Calculation_FormulaToken::TOKEN_SUBTYPE_NOTHING) {\n    \t$this->_tokenSubType = $value;\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Function.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Calculation_Function\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_Function {\n\t/* Function categories */\n\tconst CATEGORY_CUBE\t\t\t\t\t\t= 'Cube';\n\tconst CATEGORY_DATABASE\t\t\t\t\t= 'Database';\n\tconst CATEGORY_DATE_AND_TIME\t\t\t= 'Date and Time';\n\tconst CATEGORY_ENGINEERING\t\t\t\t= 'Engineering';\n\tconst CATEGORY_FINANCIAL\t\t\t\t= 'Financial';\n\tconst CATEGORY_INFORMATION\t\t\t\t= 'Information';\n\tconst CATEGORY_LOGICAL\t\t\t\t\t= 'Logical';\n\tconst CATEGORY_LOOKUP_AND_REFERENCE\t\t= 'Lookup and Reference';\n\tconst CATEGORY_MATH_AND_TRIG\t\t\t= 'Math and Trig';\n\tconst CATEGORY_STATISTICAL\t\t\t\t= 'Statistical';\n\tconst CATEGORY_TEXT_AND_DATA\t\t\t= 'Text and Data';\n\n\t/**\n\t * Category (represented by CATEGORY_*)\n\t *\n\t * @var string\n\t */\n\tprivate $_category;\n\n\t/**\n\t * Excel name\n\t *\n\t * @var string\n\t */\n\tprivate $_excelName;\n\n\t/**\n\t * PHPExcel name\n\t *\n\t * @var string\n\t */\n\tprivate $_phpExcelName;\n\n    /**\n     * Create a new PHPExcel_Calculation_Function\n     *\n     * @param \tstring\t\t$pCategory \t\tCategory (represented by CATEGORY_*)\n     * @param \tstring\t\t$pExcelName\t\tExcel function name\n     * @param \tstring\t\t$pPHPExcelName\tPHPExcel function mapping\n     * @throws \tPHPExcel_Calculation_Exception\n     */\n    public function __construct($pCategory = NULL, $pExcelName = NULL, $pPHPExcelName = NULL)\n    {\n    \tif (($pCategory !== NULL) && ($pExcelName !== NULL) && ($pPHPExcelName !== NULL)) {\n    \t\t// Initialise values\n    \t\t$this->_category \t\t= $pCategory;\n    \t\t$this->_excelName \t\t= $pExcelName;\n    \t\t$this->_phpExcelName \t= $pPHPExcelName;\n    \t} else {\n    \t\tthrow new PHPExcel_Calculation_Exception(\"Invalid parameters passed.\");\n    \t}\n    }\n\n    /**\n     * Get Category (represented by CATEGORY_*)\n     *\n     * @return string\n     */\n    public function getCategory() {\n    \treturn $this->_category;\n    }\n\n    /**\n     * Set Category (represented by CATEGORY_*)\n     *\n     * @param \tstring\t\t$value\n     * @throws \tPHPExcel_Calculation_Exception\n     */\n    public function setCategory($value = null) {\n    \tif (!is_null($value)) {\n    \t\t$this->_category = $value;\n    \t} else {\n    \t\tthrow new PHPExcel_Calculation_Exception(\"Invalid parameter passed.\");\n    \t}\n    }\n\n    /**\n     * Get Excel name\n     *\n     * @return string\n     */\n    public function getExcelName() {\n    \treturn $this->_excelName;\n    }\n\n    /**\n     * Set Excel name\n     *\n     * @param string\t$value\n     */\n    public function setExcelName($value) {\n    \t$this->_excelName = $value;\n    }\n\n    /**\n     * Get PHPExcel name\n     *\n     * @return string\n     */\n    public function getPHPExcelName() {\n    \treturn $this->_phpExcelName;\n    }\n\n    /**\n     * Set PHPExcel name\n     *\n     * @param string\t$value\n     */\n    public function setPHPExcelName($value) {\n    \t$this->_phpExcelName = $value;\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Functions.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\n/** MAX_VALUE */\ndefine('MAX_VALUE', 1.2e308);\n\n/** 2 / PI */\ndefine('M_2DIVPI', 0.63661977236758134307553505349006);\n\n/** MAX_ITERATIONS */\ndefine('MAX_ITERATIONS', 256);\n\n/** PRECISION */\ndefine('PRECISION', 8.88E-016);\n\n\n/**\n * PHPExcel_Calculation_Functions\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_Functions {\n\n\t/** constants */\n\tconst COMPATIBILITY_EXCEL\t\t= 'Excel';\n\tconst COMPATIBILITY_GNUMERIC\t= 'Gnumeric';\n\tconst COMPATIBILITY_OPENOFFICE\t= 'OpenOfficeCalc';\n\n\tconst RETURNDATE_PHP_NUMERIC\t= 'P';\n\tconst RETURNDATE_PHP_OBJECT\t\t= 'O';\n\tconst RETURNDATE_EXCEL\t\t\t= 'E';\n\n\n\t/**\n\t * Compatibility mode to use for error checking and responses\n\t *\n\t * @access\tprivate\n\t * @var string\n\t */\n\tprotected static $compatibilityMode\t= self::COMPATIBILITY_EXCEL;\n\n\t/**\n\t * Data Type to use when returning date values\n\t *\n\t * @access\tprivate\n\t * @var string\n\t */\n\tprotected static $ReturnDateType\t= self::RETURNDATE_EXCEL;\n\n\t/**\n\t * List of error codes\n\t *\n\t * @access\tprivate\n\t * @var array\n\t */\n\tprotected static $_errorCodes\t= array( 'null'\t\t\t\t=> '#NULL!',\n\t\t\t\t\t\t\t\t\t\t\t 'divisionbyzero'\t=> '#DIV/0!',\n\t\t\t\t\t\t\t\t\t\t\t 'value'\t\t\t=> '#VALUE!',\n\t\t\t\t\t\t\t\t\t\t\t 'reference'\t\t=> '#REF!',\n\t\t\t\t\t\t\t\t\t\t\t 'name'\t\t\t\t=> '#NAME?',\n\t\t\t\t\t\t\t\t\t\t\t 'num'\t\t\t\t=> '#NUM!',\n\t\t\t\t\t\t\t\t\t\t\t 'na'\t\t\t\t=> '#N/A',\n\t\t\t\t\t\t\t\t\t\t\t 'gettingdata'\t\t=> '#GETTING_DATA'\n\t\t\t\t\t\t\t\t\t\t   );\n\n\n\t/**\n\t * Set the Compatibility Mode\n\t *\n\t * @access\tpublic\n\t * @category Function Configuration\n\t * @param\t string\t\t$compatibilityMode\t\tCompatibility Mode\n\t *\t\t\t\t\t\t\t\t\t\t\t\tPermitted values are:\n\t *\t\t\t\t\t\t\t\t\t\t\t\t\tPHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL\t\t\t'Excel'\n\t *\t\t\t\t\t\t\t\t\t\t\t\t\tPHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC\t\t'Gnumeric'\n\t *\t\t\t\t\t\t\t\t\t\t\t\t\tPHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE\t'OpenOfficeCalc'\n\t * @return\t boolean\t(Success or Failure)\n\t */\n\tpublic static function setCompatibilityMode($compatibilityMode) {\n\t\tif (($compatibilityMode == self::COMPATIBILITY_EXCEL) ||\n\t\t\t($compatibilityMode == self::COMPATIBILITY_GNUMERIC) ||\n\t\t\t($compatibilityMode == self::COMPATIBILITY_OPENOFFICE)) {\n\t\t\tself::$compatibilityMode = $compatibilityMode;\n\t\t\treturn True;\n\t\t}\n\t\treturn False;\n\t}\t//\tfunction setCompatibilityMode()\n\n\n\t/**\n\t * Return the current Compatibility Mode\n\t *\n\t * @access\tpublic\n\t * @category Function Configuration\n\t * @return\t string\t\tCompatibility Mode\n\t *\t\t\t\t\t\t\tPossible Return values are:\n\t *\t\t\t\t\t\t\t\tPHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL\t\t\t'Excel'\n\t *\t\t\t\t\t\t\t\tPHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC\t\t'Gnumeric'\n\t *\t\t\t\t\t\t\t\tPHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE\t'OpenOfficeCalc'\n\t */\n\tpublic static function getCompatibilityMode() {\n\t\treturn self::$compatibilityMode;\n\t}\t//\tfunction getCompatibilityMode()\n\n\n\t/**\n\t * Set the Return Date Format used by functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object)\n\t *\n\t * @access\tpublic\n\t * @category Function Configuration\n\t * @param\t string\t$returnDateType\t\t\tReturn Date Format\n\t *\t\t\t\t\t\t\t\t\t\t\t\tPermitted values are:\n\t *\t\t\t\t\t\t\t\t\t\t\t\t\tPHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC\t\t'P'\n\t *\t\t\t\t\t\t\t\t\t\t\t\t\tPHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT\t\t'O'\n\t *\t\t\t\t\t\t\t\t\t\t\t\t\tPHPExcel_Calculation_Functions::RETURNDATE_EXCEL\t\t\t'E'\n\t * @return\t boolean\t\t\t\t\t\t\tSuccess or failure\n\t */\n\tpublic static function setReturnDateType($returnDateType) {\n\t\tif (($returnDateType == self::RETURNDATE_PHP_NUMERIC) ||\n\t\t\t($returnDateType == self::RETURNDATE_PHP_OBJECT) ||\n\t\t\t($returnDateType == self::RETURNDATE_EXCEL)) {\n\t\t\tself::$ReturnDateType = $returnDateType;\n\t\t\treturn True;\n\t\t}\n\t\treturn False;\n\t}\t//\tfunction setReturnDateType()\n\n\n\t/**\n\t * Return the current Return Date Format for functions that return a date/time (Excel, PHP Serialized Numeric or PHP Object)\n\t *\n\t * @access\tpublic\n\t * @category Function Configuration\n\t * @return\t string\t\tReturn Date Format\n\t *\t\t\t\t\t\t\tPossible Return values are:\n\t *\t\t\t\t\t\t\t\tPHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC\t\t'P'\n\t *\t\t\t\t\t\t\t\tPHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT\t\t'O'\n\t *\t\t\t\t\t\t\t\tPHPExcel_Calculation_Functions::RETURNDATE_EXCEL\t\t\t'E'\n\t */\n\tpublic static function getReturnDateType() {\n\t\treturn self::$ReturnDateType;\n\t}\t//\tfunction getReturnDateType()\n\n\n\t/**\n\t * DUMMY\n\t *\n\t * @access\tpublic\n\t * @category Error Returns\n\t * @return\tstring\t#Not Yet Implemented\n\t */\n\tpublic static function DUMMY() {\n\t\treturn '#Not Yet Implemented';\n\t}\t//\tfunction DUMMY()\n\n\n\t/**\n\t * DIV0\n\t *\n\t * @access\tpublic\n\t * @category Error Returns\n\t * @return\tstring\t#Not Yet Implemented\n\t */\n\tpublic static function DIV0() {\n\t\treturn self::$_errorCodes['divisionbyzero'];\n\t}\t//\tfunction DIV0()\n\n\n\t/**\n\t * NA\n\t *\n\t * Excel Function:\n\t *\t\t=NA()\n\t *\n\t * Returns the error value #N/A\n\t *\t\t#N/A is the error value that means \"no value is available.\"\n\t *\n\t * @access\tpublic\n\t * @category Logical Functions\n\t * @return\tstring\t#N/A!\n\t */\n\tpublic static function NA() {\n\t\treturn self::$_errorCodes['na'];\n\t}\t//\tfunction NA()\n\n\n\t/**\n\t * NaN\n\t *\n\t * Returns the error value #NUM!\n\t *\n\t * @access\tpublic\n\t * @category Error Returns\n\t * @return\tstring\t#NUM!\n\t */\n\tpublic static function NaN() {\n\t\treturn self::$_errorCodes['num'];\n\t}\t//\tfunction NaN()\n\n\n\t/**\n\t * NAME\n\t *\n\t * Returns the error value #NAME?\n\t *\n\t * @access\tpublic\n\t * @category Error Returns\n\t * @return\tstring\t#NAME?\n\t */\n\tpublic static function NAME() {\n\t\treturn self::$_errorCodes['name'];\n\t}\t//\tfunction NAME()\n\n\n\t/**\n\t * REF\n\t *\n\t * Returns the error value #REF!\n\t *\n\t * @access\tpublic\n\t * @category Error Returns\n\t * @return\tstring\t#REF!\n\t */\n\tpublic static function REF() {\n\t\treturn self::$_errorCodes['reference'];\n\t}\t//\tfunction REF()\n\n\n\t/**\n\t * NULL\n\t *\n\t * Returns the error value #NULL!\n\t *\n\t * @access\tpublic\n\t * @category Error Returns\n\t * @return\tstring\t#NULL!\n\t */\n\tpublic static function NULL() {\n\t\treturn self::$_errorCodes['null'];\n\t}\t//\tfunction NULL()\n\n\n\t/**\n\t * VALUE\n\t *\n\t * Returns the error value #VALUE!\n\t *\n\t * @access\tpublic\n\t * @category Error Returns\n\t * @return\tstring\t#VALUE!\n\t */\n\tpublic static function VALUE() {\n\t\treturn self::$_errorCodes['value'];\n\t}\t//\tfunction VALUE()\n\n\n\tpublic static function isMatrixValue($idx) {\n\t\treturn ((substr_count($idx,'.') <= 1) || (preg_match('/\\.[A-Z]/',$idx) > 0));\n\t}\n\n\n\tpublic static function isValue($idx) {\n\t\treturn (substr_count($idx,'.') == 0);\n\t}\n\n\n\tpublic static function isCellValue($idx) {\n\t\treturn (substr_count($idx,'.') > 1);\n\t}\n\n\n\tpublic static function _ifCondition($condition) {\n\t\t$condition\t= PHPExcel_Calculation_Functions::flattenSingleValue($condition);\n\t\tif (!isset($condition{0}))\n\t\t\t$condition = '=\"\"';\n\t\tif (!in_array($condition{0},array('>', '<', '='))) {\n\t\t\tif (!is_numeric($condition)) { $condition = PHPExcel_Calculation::_wrapResult(strtoupper($condition)); }\n\t\t\treturn '='.$condition;\n\t\t} else {\n\t\t\tpreg_match('/([<>=]+)(.*)/',$condition,$matches);\n\t\t\tlist(,$operator,$operand) = $matches;\n\n\t\t\tif (!is_numeric($operand)) {\n\t\t\t\t$operand = str_replace('\"', '\"\"', $operand);\n\t\t\t\t$operand = PHPExcel_Calculation::_wrapResult(strtoupper($operand));\n\t\t\t}\n\n\t\t\treturn $operator.$operand;\n\t\t}\n\t}\t//\tfunction _ifCondition()\n\n\n\t/**\n\t * ERROR_TYPE\n\t *\n\t * @param\tmixed\t$value\tValue to check\n\t * @return\tboolean\n\t */\n\tpublic static function ERROR_TYPE($value = '') {\n\t\t$value\t= self::flattenSingleValue($value);\n\n\t\t$i = 1;\n\t\tforeach(self::$_errorCodes as $errorCode) {\n\t\t\tif ($value === $errorCode) {\n\t\t\t\treturn $i;\n\t\t\t}\n\t\t\t++$i;\n\t\t}\n\t\treturn self::NA();\n\t}\t//\tfunction ERROR_TYPE()\n\n\n\t/**\n\t * IS_BLANK\n\t *\n\t * @param\tmixed\t$value\tValue to check\n\t * @return\tboolean\n\t */\n\tpublic static function IS_BLANK($value = NULL) {\n\t\tif (!is_null($value)) {\n\t\t\t$value\t= self::flattenSingleValue($value);\n\t\t}\n\n\t\treturn is_null($value);\n\t}\t//\tfunction IS_BLANK()\n\n\n\t/**\n\t * IS_ERR\n\t *\n\t * @param\tmixed\t$value\tValue to check\n\t * @return\tboolean\n\t */\n\tpublic static function IS_ERR($value = '') {\n\t\t$value\t\t= self::flattenSingleValue($value);\n\n\t\treturn self::IS_ERROR($value) && (!self::IS_NA($value));\n\t}\t//\tfunction IS_ERR()\n\n\n\t/**\n\t * IS_ERROR\n\t *\n\t * @param\tmixed\t$value\tValue to check\n\t * @return\tboolean\n\t */\n\tpublic static function IS_ERROR($value = '') {\n\t\t$value\t\t= self::flattenSingleValue($value);\n\n\t\tif (!is_string($value))\n\t\t\treturn false;\n\t\treturn in_array($value, array_values(self::$_errorCodes));\n\t}\t//\tfunction IS_ERROR()\n\n\n\t/**\n\t * IS_NA\n\t *\n\t * @param\tmixed\t$value\tValue to check\n\t * @return\tboolean\n\t */\n\tpublic static function IS_NA($value = '') {\n\t\t$value\t\t= self::flattenSingleValue($value);\n\n\t\treturn ($value === self::NA());\n\t}\t//\tfunction IS_NA()\n\n\n\t/**\n\t * IS_EVEN\n\t *\n\t * @param\tmixed\t$value\tValue to check\n\t * @return\tboolean\n\t */\n\tpublic static function IS_EVEN($value = NULL) {\n\t\t$value = self::flattenSingleValue($value);\n\n\t\tif ($value === NULL)\n\t\t\treturn self::NAME();\n\t\tif ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value))))\n\t\t\treturn self::VALUE();\n\t\treturn ($value % 2 == 0);\n\t}\t//\tfunction IS_EVEN()\n\n\n\t/**\n\t * IS_ODD\n\t *\n\t * @param\tmixed\t$value\tValue to check\n\t * @return\tboolean\n\t */\n\tpublic static function IS_ODD($value = NULL) {\n\t\t$value = self::flattenSingleValue($value);\n\n\t\tif ($value === NULL)\n\t\t\treturn self::NAME();\n\t\tif ((is_bool($value)) || ((is_string($value)) && (!is_numeric($value))))\n\t\t\treturn self::VALUE();\n\t\treturn (abs($value) % 2 == 1);\n\t}\t//\tfunction IS_ODD()\n\n\n\t/**\n\t * IS_NUMBER\n\t *\n\t * @param\tmixed\t$value\t\tValue to check\n\t * @return\tboolean\n\t */\n\tpublic static function IS_NUMBER($value = NULL) {\n\t\t$value\t\t= self::flattenSingleValue($value);\n\n\t\tif (is_string($value)) {\n\t\t\treturn False;\n\t\t}\n\t\treturn is_numeric($value);\n\t}\t//\tfunction IS_NUMBER()\n\n\n\t/**\n\t * IS_LOGICAL\n\t *\n\t * @param\tmixed\t$value\t\tValue to check\n\t * @return\tboolean\n\t */\n\tpublic static function IS_LOGICAL($value = NULL) {\n\t\t$value\t\t= self::flattenSingleValue($value);\n\n\t\treturn is_bool($value);\n\t}\t//\tfunction IS_LOGICAL()\n\n\n\t/**\n\t * IS_TEXT\n\t *\n\t * @param\tmixed\t$value\t\tValue to check\n\t * @return\tboolean\n\t */\n\tpublic static function IS_TEXT($value = NULL) {\n\t\t$value\t\t= self::flattenSingleValue($value);\n\n\t\treturn (is_string($value) && !self::IS_ERROR($value));\n\t}\t//\tfunction IS_TEXT()\n\n\n\t/**\n\t * IS_NONTEXT\n\t *\n\t * @param\tmixed\t$value\t\tValue to check\n\t * @return\tboolean\n\t */\n\tpublic static function IS_NONTEXT($value = NULL) {\n\t\treturn !self::IS_TEXT($value);\n\t}\t//\tfunction IS_NONTEXT()\n\n\n\t/**\n\t * VERSION\n\t *\n\t * @return\tstring\tVersion information\n\t */\n\tpublic static function VERSION() {\n\t\treturn 'PHPExcel 1.8.1, 2015-04-30';\n\t}\t//\tfunction VERSION()\n\n\n\t/**\n\t * N\n\t *\n\t * Returns a value converted to a number\n\t *\n\t * @param\tvalue\t\tThe value you want converted\n\t * @return\tnumber\t\tN converts values listed in the following table\n\t *\t\tIf value is or refers to N returns\n\t *\t\tA number\t\t\tThat number\n\t *\t\tA date\t\t\t\tThe serial number of that date\n\t *\t\tTRUE\t\t\t\t1\n\t *\t\tFALSE\t\t\t\t0\n\t *\t\tAn error value\t\tThe error value\n\t *\t\tAnything else\t\t0\n\t */\n\tpublic static function N($value = NULL) {\n\t\twhile (is_array($value)) {\n\t\t\t$value = array_shift($value);\n\t\t}\n\n\t\tswitch (gettype($value)) {\n\t\t\tcase 'double'\t:\n\t\t\tcase 'float'\t:\n\t\t\tcase 'integer'\t:\n\t\t\t\treturn $value;\n\t\t\t\tbreak;\n\t\t\tcase 'boolean'\t:\n\t\t\t\treturn (integer) $value;\n\t\t\t\tbreak;\n\t\t\tcase 'string'\t:\n\t\t\t\t//\tErrors\n\t\t\t\tif ((strlen($value) > 0) && ($value{0} == '#')) {\n\t\t\t\t\treturn $value;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t}\n\t\treturn 0;\n\t}\t//\tfunction N()\n\n\n\t/**\n\t * TYPE\n\t *\n\t * Returns a number that identifies the type of a value\n\t *\n\t * @param\tvalue\t\tThe value you want tested\n\t * @return\tnumber\t\tN converts values listed in the following table\n\t *\t\tIf value is or refers to N returns\n\t *\t\tA number\t\t\t1\n\t *\t\tText\t\t\t\t2\n\t *\t\tLogical Value\t\t4\n\t *\t\tAn error value\t\t16\n\t *\t\tArray or Matrix\t\t64\n\t */\n\tpublic static function TYPE($value = NULL) {\n\t\t$value\t= self::flattenArrayIndexed($value);\n\t\tif (is_array($value) && (count($value) > 1)) {\n\t\t\t$a = array_keys($value);\n\t\t\t$a = array_pop($a);\n\t\t\t//\tRange of cells is an error\n\t\t\tif (self::isCellValue($a)) {\n\t\t\t\treturn 16;\n\t\t\t//\tTest for Matrix\n\t\t\t} elseif (self::isMatrixValue($a)) {\n\t\t\t\treturn 64;\n\t\t\t}\n\t\t} elseif(empty($value)) {\n\t\t\t//\tEmpty Cell\n\t\t\treturn 1;\n\t\t}\n\t\t$value\t= self::flattenSingleValue($value);\n\n\t\tif (($value === NULL) || (is_float($value)) || (is_int($value))) {\n\t\t\t\treturn 1;\n\t\t} elseif(is_bool($value)) {\n\t\t\t\treturn 4;\n\t\t} elseif(is_array($value)) {\n\t\t\t\treturn 64;\n\t\t} elseif(is_string($value)) {\n\t\t\t//\tErrors\n\t\t\tif ((strlen($value) > 0) && ($value{0} == '#')) {\n\t\t\t\treturn 16;\n\t\t\t}\n\t\t\treturn 2;\n\t\t}\n\t\treturn 0;\n\t}\t//\tfunction TYPE()\n\n\n\t/**\n\t * Convert a multi-dimensional array to a simple 1-dimensional array\n\t *\n\t * @param\tarray\t$array\tArray to be flattened\n\t * @return\tarray\tFlattened array\n\t */\n\tpublic static function flattenArray($array) {\n\t\tif (!is_array($array)) {\n\t\t\treturn (array) $array;\n\t\t}\n\n\t\t$arrayValues = array();\n\t\tforeach ($array as $value) {\n\t\t\tif (is_array($value)) {\n\t\t\t\tforeach ($value as $val) {\n\t\t\t\t\tif (is_array($val)) {\n\t\t\t\t\t\tforeach ($val as $v) {\n\t\t\t\t\t\t\t$arrayValues[] = $v;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$arrayValues[] = $val;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$arrayValues[] = $value;\n\t\t\t}\n\t\t}\n\n\t\treturn $arrayValues;\n\t}\t//\tfunction flattenArray()\n\n\n\t/**\n\t * Convert a multi-dimensional array to a simple 1-dimensional array, but retain an element of indexing\n\t *\n\t * @param\tarray\t$array\tArray to be flattened\n\t * @return\tarray\tFlattened array\n\t */\n\tpublic static function flattenArrayIndexed($array) {\n\t\tif (!is_array($array)) {\n\t\t\treturn (array) $array;\n\t\t}\n\n\t\t$arrayValues = array();\n\t\tforeach ($array as $k1 => $value) {\n\t\t\tif (is_array($value)) {\n\t\t\t\tforeach ($value as $k2 => $val) {\n\t\t\t\t\tif (is_array($val)) {\n\t\t\t\t\t\tforeach ($val as $k3 => $v) {\n\t\t\t\t\t\t\t$arrayValues[$k1.'.'.$k2.'.'.$k3] = $v;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$arrayValues[$k1.'.'.$k2] = $val;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$arrayValues[$k1] = $value;\n\t\t\t}\n\t\t}\n\n\t\treturn $arrayValues;\n\t}\t//\tfunction flattenArrayIndexed()\n\n\n\t/**\n\t * Convert an array to a single scalar value by extracting the first element\n\t *\n\t * @param\tmixed\t\t$value\t\tArray or scalar value\n\t * @return\tmixed\n\t */\n\tpublic static function flattenSingleValue($value = '') {\n\t\twhile (is_array($value)) {\n\t\t\t$value = array_pop($value);\n\t\t}\n\n\t\treturn $value;\n\t}\t//\tfunction flattenSingleValue()\n\n}\t//\tclass PHPExcel_Calculation_Functions\n\n\n//\n//\tThere are a few mathematical functions that aren't available on all versions of PHP for all platforms\n//\tThese functions aren't available in Windows implementations of PHP prior to version 5.3.0\n//\tSo we test if they do exist for this version of PHP/operating platform; and if not we create them\n//\nif (!function_exists('acosh')) {\n\tfunction acosh($x) {\n\t\treturn 2 * log(sqrt(($x + 1) / 2) + sqrt(($x - 1) / 2));\n\t}\t//\tfunction acosh()\n}\n\nif (!function_exists('asinh')) {\n\tfunction asinh($x) {\n\t\treturn log($x + sqrt(1 + $x * $x));\n\t}\t//\tfunction asinh()\n}\n\nif (!function_exists('atanh')) {\n\tfunction atanh($x) {\n\t\treturn (log(1 + $x) - log(1 - $x)) / 2;\n\t}\t//\tfunction atanh()\n}\n\n\n//\n//\tStrangely, PHP doesn't have a mb_str_replace multibyte function\n//\tAs we'll only ever use this function with UTF-8 characters, we can simply \"hard-code\" the character set\n//\nif ((!function_exists('mb_str_replace')) &&\n\t(function_exists('mb_substr')) && (function_exists('mb_strlen')) && (function_exists('mb_strpos'))) {\n\tfunction mb_str_replace($search, $replace, $subject) {\n\t\tif(is_array($subject)) {\n\t\t\t$ret = array();\n\t\t\tforeach($subject as $key => $val) {\n\t\t\t\t$ret[$key] = mb_str_replace($search, $replace, $val);\n\t\t\t}\n\t\t\treturn $ret;\n\t\t}\n\n\t\tforeach((array) $search as $key => $s) {\n\t\t\tif($s == '' && $s !== 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t$r = !is_array($replace) ? $replace : (array_key_exists($key, $replace) ? $replace[$key] : '');\n\t\t\t$pos = mb_strpos($subject, $s, 0, 'UTF-8');\n\t\t\twhile($pos !== false) {\n\t\t\t\t$subject = mb_substr($subject, 0, $pos, 'UTF-8') . $r . mb_substr($subject, $pos + mb_strlen($s, 'UTF-8'), 65535, 'UTF-8');\n\t\t\t\t$pos = mb_strpos($subject, $s, $pos + mb_strlen($r, 'UTF-8'), 'UTF-8');\n\t\t\t}\n\t\t}\n\t\treturn $subject;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Logical.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\n/**\n * PHPExcel_Calculation_Logical\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_Logical {\n\n\t/**\n\t * TRUE\n\t *\n\t * Returns the boolean TRUE.\n\t *\n\t * Excel Function:\n\t *\t\t=TRUE()\n\t *\n\t * @access\tpublic\n\t * @category Logical Functions\n\t * @return\tboolean\t\tTrue\n\t */\n\tpublic static function TRUE() {\n\t\treturn TRUE;\n\t}\t//\tfunction TRUE()\n\n\n\t/**\n\t * FALSE\n\t *\n\t * Returns the boolean FALSE.\n\t *\n\t * Excel Function:\n\t *\t\t=FALSE()\n\t *\n\t * @access\tpublic\n\t * @category Logical Functions\n\t * @return\tboolean\t\tFalse\n\t */\n\tpublic static function FALSE() {\n\t\treturn FALSE;\n\t}\t//\tfunction FALSE()\n\n\n\t/**\n\t * LOGICAL_AND\n\t *\n\t * Returns boolean TRUE if all its arguments are TRUE; returns FALSE if one or more argument is FALSE.\n\t *\n\t * Excel Function:\n\t *\t\t=AND(logical1[,logical2[, ...]])\n\t *\n\t *\t\tThe arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays\n\t *\t\t\tor references that contain logical values.\n\t *\n\t *\t\tBoolean arguments are treated as True or False as appropriate\n\t *\t\tInteger or floating point arguments are treated as True, except for 0 or 0.0 which are False\n\t *\t\tIf any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds\n\t *\t\t\tthe value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value\n\t *\n\t * @access\tpublic\n\t * @category Logical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tboolean\t\tThe logical AND of the arguments.\n\t */\n\tpublic static function LOGICAL_AND() {\n\t\t// Return value\n\t\t$returnValue = TRUE;\n\n\t\t// Loop through the arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\t$argCount = -1;\n\t\tforeach ($aArgs as $argCount => $arg) {\n\t\t\t// Is it a boolean value?\n\t\t\tif (is_bool($arg)) {\n\t\t\t\t$returnValue = $returnValue && $arg;\n\t\t\t} elseif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t$returnValue = $returnValue && ($arg != 0);\n\t\t\t} elseif (is_string($arg)) {\n\t\t\t\t$arg = strtoupper($arg);\n\t\t\t\tif (($arg == 'TRUE') || ($arg == PHPExcel_Calculation::getTRUE())) {\n\t\t\t\t\t$arg = TRUE;\n\t\t\t\t} elseif (($arg == 'FALSE') || ($arg == PHPExcel_Calculation::getFALSE())) {\n\t\t\t\t\t$arg = FALSE;\n\t\t\t\t} else {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t}\n\t\t\t\t$returnValue = $returnValue && ($arg != 0);\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif ($argCount < 0) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\treturn $returnValue;\n\t}\t//\tfunction LOGICAL_AND()\n\n\n\t/**\n\t * LOGICAL_OR\n\t *\n\t * Returns boolean TRUE if any argument is TRUE; returns FALSE if all arguments are FALSE.\n\t *\n\t * Excel Function:\n\t *\t\t=OR(logical1[,logical2[, ...]])\n\t *\n\t *\t\tThe arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays\n\t *\t\t\tor references that contain logical values.\n\t *\n\t *\t\tBoolean arguments are treated as True or False as appropriate\n\t *\t\tInteger or floating point arguments are treated as True, except for 0 or 0.0 which are False\n\t *\t\tIf any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds\n\t *\t\t\tthe value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value\n\t *\n\t * @access\tpublic\n\t * @category Logical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tboolean\t\tThe logical OR of the arguments.\n\t */\n\tpublic static function LOGICAL_OR() {\n\t\t// Return value\n\t\t$returnValue = FALSE;\n\n\t\t// Loop through the arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\t$argCount = -1;\n\t\tforeach ($aArgs as $argCount => $arg) {\n\t\t\t// Is it a boolean value?\n\t\t\tif (is_bool($arg)) {\n\t\t\t\t$returnValue = $returnValue || $arg;\n\t\t\t} elseif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t$returnValue = $returnValue || ($arg != 0);\n\t\t\t} elseif (is_string($arg)) {\n\t\t\t\t$arg = strtoupper($arg);\n\t\t\t\tif (($arg == 'TRUE') || ($arg == PHPExcel_Calculation::getTRUE())) {\n\t\t\t\t\t$arg = TRUE;\n\t\t\t\t} elseif (($arg == 'FALSE') || ($arg == PHPExcel_Calculation::getFALSE())) {\n\t\t\t\t\t$arg = FALSE;\n\t\t\t\t} else {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t}\n\t\t\t\t$returnValue = $returnValue || ($arg != 0);\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif ($argCount < 0) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\treturn $returnValue;\n\t}\t//\tfunction LOGICAL_OR()\n\n\n\t/**\n\t * NOT\n\t *\n\t * Returns the boolean inverse of the argument.\n\t *\n\t * Excel Function:\n\t *\t\t=NOT(logical)\n\t *\n\t *\t\tThe argument must evaluate to a logical value such as TRUE or FALSE\n\t *\n\t *\t\tBoolean arguments are treated as True or False as appropriate\n\t *\t\tInteger or floating point arguments are treated as True, except for 0 or 0.0 which are False\n\t *\t\tIf any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds\n\t *\t\t\tthe value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value\n\t *\n\t * @access\tpublic\n\t * @category Logical Functions\n\t * @param\tmixed\t\t$logical\tA value or expression that can be evaluated to TRUE or FALSE\n\t * @return\tboolean\t\tThe boolean inverse of the argument.\n\t */\n\tpublic static function NOT($logical=FALSE) {\n\t\t$logical = PHPExcel_Calculation_Functions::flattenSingleValue($logical);\n\t\tif (is_string($logical)) {\n\t\t\t$logical = strtoupper($logical);\n\t\t\tif (($logical == 'TRUE') || ($logical == PHPExcel_Calculation::getTRUE())) {\n\t\t\t\treturn FALSE;\n\t\t\t} elseif (($logical == 'FALSE') || ($logical == PHPExcel_Calculation::getFALSE())) {\n\t\t\t\treturn TRUE;\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t}\n\n\t\treturn !$logical;\n\t}\t//\tfunction NOT()\n\n\t/**\n\t * STATEMENT_IF\n\t *\n\t * Returns one value if a condition you specify evaluates to TRUE and another value if it evaluates to FALSE.\n\t *\n\t * Excel Function:\n\t *\t\t=IF(condition[,returnIfTrue[,returnIfFalse]])\n\t *\n\t *\t\tCondition is any value or expression that can be evaluated to TRUE or FALSE.\n\t *\t\t\tFor example, A10=100 is a logical expression; if the value in cell A10 is equal to 100,\n\t *\t\t\tthe expression evaluates to TRUE. Otherwise, the expression evaluates to FALSE.\n\t *\t\t\tThis argument can use any comparison calculation operator.\n\t *\t\tReturnIfTrue is the value that is returned if condition evaluates to TRUE.\n\t *\t\t\tFor example, if this argument is the text string \"Within budget\" and the condition argument evaluates to TRUE,\n\t *\t\t\tthen the IF function returns the text \"Within budget\"\n\t *\t\t\tIf condition is TRUE and ReturnIfTrue is blank, this argument returns 0 (zero). To display the word TRUE, use\n\t *\t\t\tthe logical value TRUE for this argument.\n\t *\t\t\tReturnIfTrue can be another formula.\n\t *\t\tReturnIfFalse is the value that is returned if condition evaluates to FALSE.\n\t *\t\t\tFor example, if this argument is the text string \"Over budget\" and the condition argument evaluates to FALSE,\n\t *\t\t\tthen the IF function returns the text \"Over budget\".\n\t *\t\t\tIf condition is FALSE and ReturnIfFalse is omitted, then the logical value FALSE is returned.\n\t *\t\t\tIf condition is FALSE and ReturnIfFalse is blank, then the value 0 (zero) is returned.\n\t *\t\t\tReturnIfFalse can be another formula.\n\t *\n\t * @access\tpublic\n\t * @category Logical Functions\n\t * @param\tmixed\t$condition\t\tCondition to evaluate\n\t * @param\tmixed\t$returnIfTrue\tValue to return when condition is true\n\t * @param\tmixed\t$returnIfFalse\tOptional value to return when condition is false\n\t * @return\tmixed\tThe value of returnIfTrue or returnIfFalse determined by condition\n\t */\n\tpublic static function STATEMENT_IF($condition = TRUE, $returnIfTrue = 0, $returnIfFalse = FALSE) {\n\t\t$condition\t\t= (is_null($condition))\t\t? TRUE :\t(boolean) PHPExcel_Calculation_Functions::flattenSingleValue($condition);\n\t\t$returnIfTrue\t= (is_null($returnIfTrue))\t? 0 :\t\tPHPExcel_Calculation_Functions::flattenSingleValue($returnIfTrue);\n\t\t$returnIfFalse\t= (is_null($returnIfFalse))\t? FALSE :\tPHPExcel_Calculation_Functions::flattenSingleValue($returnIfFalse);\n\n\t\treturn ($condition) ? $returnIfTrue : $returnIfFalse;\n\t}\t//\tfunction STATEMENT_IF()\n\n\n\t/**\n\t * IFERROR\n\t *\n\t * Excel Function:\n\t *\t\t=IFERROR(testValue,errorpart)\n\t *\n\t * @access\tpublic\n\t * @category Logical Functions\n\t * @param\tmixed\t$testValue\tValue to check, is also the value returned when no error\n\t * @param\tmixed\t$errorpart\tValue to return when testValue is an error condition\n\t * @return\tmixed\tThe value of errorpart or testValue determined by error condition\n\t */\n\tpublic static function IFERROR($testValue = '', $errorpart = '') {\n\t\t$testValue\t= (is_null($testValue))\t? '' :\tPHPExcel_Calculation_Functions::flattenSingleValue($testValue);\n\t\t$errorpart\t= (is_null($errorpart))\t? '' :\tPHPExcel_Calculation_Functions::flattenSingleValue($errorpart);\n\n\t\treturn self::STATEMENT_IF(PHPExcel_Calculation_Functions::IS_ERROR($testValue), $errorpart, $testValue);\n\t}\t//\tfunction IFERROR()\n\n}\t//\tclass PHPExcel_Calculation_Logical\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/LookupRef.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\n/**\n * PHPExcel_Calculation_LookupRef\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_LookupRef {\n\n\n\t/**\n\t * CELL_ADDRESS\n\t *\n\t * Creates a cell address as text, given specified row and column numbers.\n\t *\n\t * Excel Function:\n\t *\t\t=ADDRESS(row, column, [relativity], [referenceStyle], [sheetText])\n\t *\n\t * @param\trow\t\t\t\tRow number to use in the cell reference\n\t * @param\tcolumn\t\t\tColumn number to use in the cell reference\n\t * @param\trelativity\t\tFlag indicating the type of reference to return\n\t *\t\t\t\t\t\t\t\t1 or omitted\tAbsolute\n\t *\t\t\t\t\t\t\t\t2\t\t\t\tAbsolute row; relative column\n\t *\t\t\t\t\t\t\t\t3\t\t\t\tRelative row; absolute column\n\t *\t\t\t\t\t\t\t\t4\t\t\t\tRelative\n\t * @param\treferenceStyle\tA logical value that specifies the A1 or R1C1 reference style.\n\t *\t\t\t\t\t\t\t\tTRUE or omitted\t\tCELL_ADDRESS returns an A1-style reference\n\t *\t\t\t\t\t\t\t\tFALSE\t\t\t\tCELL_ADDRESS returns an R1C1-style reference\n\t * @param\tsheetText\t\tOptional Name of worksheet to use\n\t * @return\tstring\n\t */\n\tpublic static function CELL_ADDRESS($row, $column, $relativity=1, $referenceStyle=True, $sheetText='') {\n\t\t$row\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($row);\n\t\t$column\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($column);\n\t\t$relativity\t= PHPExcel_Calculation_Functions::flattenSingleValue($relativity);\n\t\t$sheetText\t= PHPExcel_Calculation_Functions::flattenSingleValue($sheetText);\n\n\t\tif (($row < 1) || ($column < 1)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif ($sheetText > '') {\n\t\t\tif (strpos($sheetText,' ') !== False) { $sheetText = \"'\".$sheetText.\"'\"; }\n\t\t\t$sheetText .='!';\n\t\t}\n\t\tif ((!is_bool($referenceStyle)) || $referenceStyle) {\n\t\t\t$rowRelative = $columnRelative = '$';\n\t\t\t$column = PHPExcel_Cell::stringFromColumnIndex($column-1);\n\t\t\tif (($relativity == 2) || ($relativity == 4)) { $columnRelative = ''; }\n\t\t\tif (($relativity == 3) || ($relativity == 4)) { $rowRelative = ''; }\n\t\t\treturn $sheetText.$columnRelative.$column.$rowRelative.$row;\n\t\t} else {\n\t\t\tif (($relativity == 2) || ($relativity == 4)) { $column = '['.$column.']'; }\n\t\t\tif (($relativity == 3) || ($relativity == 4)) { $row = '['.$row.']'; }\n\t\t\treturn $sheetText.'R'.$row.'C'.$column;\n\t\t}\n\t}\t//\tfunction CELL_ADDRESS()\n\n\n\t/**\n\t * COLUMN\n\t *\n\t * Returns the column number of the given cell reference\n\t * If the cell reference is a range of cells, COLUMN returns the column numbers of each column in the reference as a horizontal array.\n\t * If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the\n\t *\t\treference of the cell in which the COLUMN function appears; otherwise this function returns 0.\n\t *\n\t * Excel Function:\n\t *\t\t=COLUMN([cellAddress])\n\t *\n\t * @param\tcellAddress\t\tA reference to a range of cells for which you want the column numbers\n\t * @return\tinteger or array of integer\n\t */\n\tpublic static function COLUMN($cellAddress=Null) {\n\t\tif (is_null($cellAddress) || trim($cellAddress) === '') { return 0; }\n\n\t\tif (is_array($cellAddress)) {\n\t\t\tforeach($cellAddress as $columnKey => $value) {\n\t\t\t\t$columnKey = preg_replace('/[^a-z]/i','',$columnKey);\n\t\t\t\treturn (integer) PHPExcel_Cell::columnIndexFromString($columnKey);\n\t\t\t}\n\t\t} else {\n\t\t\tif (strpos($cellAddress,'!') !== false) {\n\t\t\t\tlist($sheet,$cellAddress) = explode('!',$cellAddress);\n\t\t\t}\n\t\t\tif (strpos($cellAddress,':') !== false) {\n\t\t\t\tlist($startAddress,$endAddress) = explode(':',$cellAddress);\n\t\t\t\t$startAddress = preg_replace('/[^a-z]/i','',$startAddress);\n\t\t\t\t$endAddress = preg_replace('/[^a-z]/i','',$endAddress);\n\t\t\t\t$returnValue = array();\n\t\t\t\tdo {\n\t\t\t\t\t$returnValue[] = (integer) PHPExcel_Cell::columnIndexFromString($startAddress);\n\t\t\t\t} while ($startAddress++ != $endAddress);\n\t\t\t\treturn $returnValue;\n\t\t\t} else {\n\t\t\t\t$cellAddress = preg_replace('/[^a-z]/i','',$cellAddress);\n\t\t\t\treturn (integer) PHPExcel_Cell::columnIndexFromString($cellAddress);\n\t\t\t}\n\t\t}\n\t}\t//\tfunction COLUMN()\n\n\n\t/**\n\t * COLUMNS\n\t *\n\t * Returns the number of columns in an array or reference.\n\t *\n\t * Excel Function:\n\t *\t\t=COLUMNS(cellAddress)\n\t *\n\t * @param\tcellAddress\t\tAn array or array formula, or a reference to a range of cells for which you want the number of columns\n\t * @return\tinteger\t\t\tThe number of columns in cellAddress\n\t */\n\tpublic static function COLUMNS($cellAddress=Null) {\n\t\tif (is_null($cellAddress) || $cellAddress === '') {\n\t\t\treturn 1;\n\t\t} elseif (!is_array($cellAddress)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t$x = array_keys($cellAddress);\n\t\t$x = array_shift($x);\n\t\t$isMatrix = (is_numeric($x));\n\t\tlist($columns,$rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress);\n\n\t\tif ($isMatrix) {\n\t\t\treturn $rows;\n\t\t} else {\n\t\t\treturn $columns;\n\t\t}\n\t}\t//\tfunction COLUMNS()\n\n\n\t/**\n\t * ROW\n\t *\n\t * Returns the row number of the given cell reference\n\t * If the cell reference is a range of cells, ROW returns the row numbers of each row in the reference as a vertical array.\n\t * If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the\n\t *\t\treference of the cell in which the ROW function appears; otherwise this function returns 0.\n\t *\n\t * Excel Function:\n\t *\t\t=ROW([cellAddress])\n\t *\n\t * @param\tcellAddress\t\tA reference to a range of cells for which you want the row numbers\n\t * @return\tinteger or array of integer\n\t */\n\tpublic static function ROW($cellAddress=Null) {\n\t\tif (is_null($cellAddress) || trim($cellAddress) === '') { return 0; }\n\n\t\tif (is_array($cellAddress)) {\n\t\t\tforeach($cellAddress as $columnKey => $rowValue) {\n\t\t\t\tforeach($rowValue as $rowKey => $cellValue) {\n\t\t\t\t\treturn (integer) preg_replace('/[^0-9]/i','',$rowKey);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tif (strpos($cellAddress,'!') !== false) {\n\t\t\t\tlist($sheet,$cellAddress) = explode('!',$cellAddress);\n\t\t\t}\n\t\t\tif (strpos($cellAddress,':') !== false) {\n\t\t\t\tlist($startAddress,$endAddress) = explode(':',$cellAddress);\n\t\t\t\t$startAddress = preg_replace('/[^0-9]/','',$startAddress);\n\t\t\t\t$endAddress = preg_replace('/[^0-9]/','',$endAddress);\n\t\t\t\t$returnValue = array();\n\t\t\t\tdo {\n\t\t\t\t\t$returnValue[][] = (integer) $startAddress;\n\t\t\t\t} while ($startAddress++ != $endAddress);\n\t\t\t\treturn $returnValue;\n\t\t\t} else {\n\t\t\t\tlist($cellAddress) = explode(':',$cellAddress);\n\t\t\t\treturn (integer) preg_replace('/[^0-9]/','',$cellAddress);\n\t\t\t}\n\t\t}\n\t}\t//\tfunction ROW()\n\n\n\t/**\n\t * ROWS\n\t *\n\t * Returns the number of rows in an array or reference.\n\t *\n\t * Excel Function:\n\t *\t\t=ROWS(cellAddress)\n\t *\n\t * @param\tcellAddress\t\tAn array or array formula, or a reference to a range of cells for which you want the number of rows\n\t * @return\tinteger\t\t\tThe number of rows in cellAddress\n\t */\n\tpublic static function ROWS($cellAddress=Null) {\n\t\tif (is_null($cellAddress) || $cellAddress === '') {\n\t\t\treturn 1;\n\t\t} elseif (!is_array($cellAddress)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t$i = array_keys($cellAddress);\n\t\t$isMatrix = (is_numeric(array_shift($i)));\n\t\tlist($columns,$rows) = PHPExcel_Calculation::_getMatrixDimensions($cellAddress);\n\n\t\tif ($isMatrix) {\n\t\t\treturn $columns;\n\t\t} else {\n\t\t\treturn $rows;\n\t\t}\n\t}\t//\tfunction ROWS()\n\n\n\t/**\n\t * HYPERLINK\n\t *\n\t * Excel Function:\n\t *\t\t=HYPERLINK(linkURL,displayName)\n\t *\n\t * @access\tpublic\n\t * @category Logical Functions\n\t * @param\tstring\t\t\t$linkURL\t\tValue to check, is also the value returned when no error\n\t * @param\tstring\t\t\t$displayName\tValue to return when testValue is an error condition\n\t * @param\tPHPExcel_Cell\t$pCell\t\t\tThe cell to set the hyperlink in\n\t * @return\tmixed\tThe value of $displayName (or $linkURL if $displayName was blank)\n\t */\n\tpublic static function HYPERLINK($linkURL = '', $displayName = null, PHPExcel_Cell $pCell = null) {\n\t\t$args = func_get_args();\n\t\t$pCell = array_pop($args);\n\n\t\t$linkURL\t\t= (is_null($linkURL))\t\t? '' :\tPHPExcel_Calculation_Functions::flattenSingleValue($linkURL);\n\t\t$displayName\t= (is_null($displayName))\t? '' :\tPHPExcel_Calculation_Functions::flattenSingleValue($displayName);\n\n\t\tif ((!is_object($pCell)) || (trim($linkURL) == '')) {\n\t\t\treturn PHPExcel_Calculation_Functions::REF();\n\t\t}\n\n\t\tif ((is_object($displayName)) || trim($displayName) == '') {\n\t\t\t$displayName = $linkURL;\n\t\t}\n\n\t\t$pCell->getHyperlink()->setUrl($linkURL);\n\n\t\treturn $displayName;\n\t}\t//\tfunction HYPERLINK()\n\n\n\t/**\n\t * INDIRECT\n\t *\n\t * Returns the reference specified by a text string.\n\t * References are immediately evaluated to display their contents.\n\t *\n\t * Excel Function:\n\t *\t\t=INDIRECT(cellAddress)\n\t *\n\t * NOTE - INDIRECT() does not yet support the optional a1 parameter introduced in Excel 2010\n\t *\n\t * @param\tcellAddress\t\t$cellAddress\tThe cell address of the current cell (containing this formula)\n\t * @param\tPHPExcel_Cell\t$pCell\t\t\tThe current cell (containing this formula)\n\t * @return\tmixed\t\t\tThe cells referenced by cellAddress\n\t *\n\t * @todo\tSupport for the optional a1 parameter introduced in Excel 2010\n\t *\n\t */\n\tpublic static function INDIRECT($cellAddress = NULL, PHPExcel_Cell $pCell = NULL) {\n\t\t$cellAddress\t= PHPExcel_Calculation_Functions::flattenSingleValue($cellAddress);\n\t\tif (is_null($cellAddress) || $cellAddress === '') {\n\t\t\treturn PHPExcel_Calculation_Functions::REF();\n\t\t}\n\n\t\t$cellAddress1 = $cellAddress;\n\t\t$cellAddress2 = NULL;\n\t\tif (strpos($cellAddress,':') !== false) {\n\t\t\tlist($cellAddress1,$cellAddress2) = explode(':',$cellAddress);\n\t\t}\n\n\t\tif ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress1, $matches)) ||\n\t\t\t((!is_null($cellAddress2)) && (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $cellAddress2, $matches)))) {\n\t\t\tif (!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $cellAddress1, $matches)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::REF();\n\t\t\t}\n\n\t\t\tif (strpos($cellAddress,'!') !== FALSE) {\n\t\t\t\tlist($sheetName, $cellAddress) = explode('!',$cellAddress);\n\t\t\t\t$sheetName = trim($sheetName, \"'\");\n\t\t\t\t$pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName);\n\t\t\t} else {\n\t\t\t\t$pSheet = $pCell->getWorksheet();\n\t\t\t}\n\n\t\t\treturn PHPExcel_Calculation::getInstance()->extractNamedRange($cellAddress, $pSheet, FALSE);\n\t\t}\n\n\t\tif (strpos($cellAddress,'!') !== FALSE) {\n\t\t\tlist($sheetName,$cellAddress) = explode('!',$cellAddress);\n\t\t\t$sheetName = trim($sheetName, \"'\");\n\t\t\t$pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName);\n\t\t} else {\n\t\t\t$pSheet = $pCell->getWorksheet();\n\t\t}\n\n\t\treturn PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, FALSE);\n\t}\t//\tfunction INDIRECT()\n\n\n\t/**\n\t * OFFSET\n\t *\n\t * Returns a reference to a range that is a specified number of rows and columns from a cell or range of cells.\n\t * The reference that is returned can be a single cell or a range of cells. You can specify the number of rows and\n\t * the number of columns to be returned.\n\t *\n\t * Excel Function:\n\t *\t\t=OFFSET(cellAddress, rows, cols, [height], [width])\n\t *\n\t * @param\tcellAddress\t\tThe reference from which you want to base the offset. Reference must refer to a cell or\n\t *\t\t\t\t\t\t\t\trange of adjacent cells; otherwise, OFFSET returns the #VALUE! error value.\n\t * @param\trows\t\t\tThe number of rows, up or down, that you want the upper-left cell to refer to.\n\t *\t\t\t\t\t\t\t\tUsing 5 as the rows argument specifies that the upper-left cell in the reference is\n\t *\t\t\t\t\t\t\t\tfive rows below reference. Rows can be positive (which means below the starting reference)\n\t *\t\t\t\t\t\t\t\tor negative (which means above the starting reference).\n\t * @param\tcols\t\t\tThe number of columns, to the left or right, that you want the upper-left cell of the result\n\t *\t\t\t\t\t\t\t\tto refer to. Using 5 as the cols argument specifies that the upper-left cell in the\n\t *\t\t\t\t\t\t\t\treference is five columns to the right of reference. Cols can be positive (which means\n\t *\t\t\t\t\t\t\t\tto the right of the starting reference) or negative (which means to the left of the\n\t *\t\t\t\t\t\t\t\tstarting reference).\n\t * @param\theight\t\t\tThe height, in number of rows, that you want the returned reference to be. Height must be a positive number.\n\t * @param\twidth\t\t\tThe width, in number of columns, that you want the returned reference to be. Width must be a positive number.\n\t * @return\tstring\t\t\tA reference to a cell or range of cells\n\t */\n\tpublic static function OFFSET($cellAddress=Null,$rows=0,$columns=0,$height=null,$width=null) {\n\t\t$rows\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($rows);\n\t\t$columns\t= PHPExcel_Calculation_Functions::flattenSingleValue($columns);\n\t\t$height\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($height);\n\t\t$width\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($width);\n\t\tif ($cellAddress == Null) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t$args = func_get_args();\n\t\t$pCell = array_pop($args);\n\t\tif (!is_object($pCell)) {\n\t\t\treturn PHPExcel_Calculation_Functions::REF();\n\t\t}\n\n\t\t$sheetName = NULL;\n\t\tif (strpos($cellAddress,\"!\")) {\n\t\t\tlist($sheetName,$cellAddress) = explode(\"!\",$cellAddress);\n\t\t\t$sheetName = trim($sheetName, \"'\");\n\t\t}\n\t\tif (strpos($cellAddress,\":\")) {\n\t\t\tlist($startCell,$endCell) = explode(\":\",$cellAddress);\n\t\t} else {\n\t\t\t$startCell = $endCell = $cellAddress;\n\t\t}\n\t\tlist($startCellColumn,$startCellRow) = PHPExcel_Cell::coordinateFromString($startCell);\n\t\tlist($endCellColumn,$endCellRow) = PHPExcel_Cell::coordinateFromString($endCell);\n\n\t\t$startCellRow += $rows;\n\t\t$startCellColumn = PHPExcel_Cell::columnIndexFromString($startCellColumn) - 1;\n\t\t$startCellColumn += $columns;\n\n\t\tif (($startCellRow <= 0) || ($startCellColumn < 0)) {\n\t\t\treturn PHPExcel_Calculation_Functions::REF();\n\t\t}\n\t\t$endCellColumn = PHPExcel_Cell::columnIndexFromString($endCellColumn) - 1;\n\t\tif (($width != null) && (!is_object($width))) {\n\t\t\t$endCellColumn = $startCellColumn + $width - 1;\n\t\t} else {\n\t\t\t$endCellColumn += $columns;\n\t\t}\n\t\t$startCellColumn = PHPExcel_Cell::stringFromColumnIndex($startCellColumn);\n\n\t\tif (($height != null) && (!is_object($height))) {\n\t\t\t$endCellRow = $startCellRow + $height - 1;\n\t\t} else {\n\t\t\t$endCellRow += $rows;\n\t\t}\n\n\t\tif (($endCellRow <= 0) || ($endCellColumn < 0)) {\n\t\t\treturn PHPExcel_Calculation_Functions::REF();\n\t\t}\n\t\t$endCellColumn = PHPExcel_Cell::stringFromColumnIndex($endCellColumn);\n\n\t\t$cellAddress = $startCellColumn.$startCellRow;\n\t\tif (($startCellColumn != $endCellColumn) || ($startCellRow != $endCellRow)) {\n\t\t\t$cellAddress .= ':'.$endCellColumn.$endCellRow;\n\t\t}\n\n\t\tif ($sheetName !== NULL) {\n\t\t\t$pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName);\n\t\t} else {\n\t\t\t$pSheet = $pCell->getWorksheet();\n\t\t}\n\n\t\treturn PHPExcel_Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, False);\n\t}\t//\tfunction OFFSET()\n\n\n\t/**\n\t * CHOOSE\n\t *\n\t * Uses lookup_value to return a value from the list of value arguments.\n\t * Use CHOOSE to select one of up to 254 values based on the lookup_value.\n\t *\n\t * Excel Function:\n\t *\t\t=CHOOSE(index_num, value1, [value2], ...)\n\t *\n\t * @param\tindex_num\t\tSpecifies which value argument is selected.\n\t *\t\t\t\t\t\t\tIndex_num must be a number between 1 and 254, or a formula or reference to a cell containing a number\n\t *\t\t\t\t\t\t\t\tbetween 1 and 254.\n\t * @param\tvalue1...\t\tValue1 is required, subsequent values are optional.\n\t *\t\t\t\t\t\t\tBetween 1 to 254 value arguments from which CHOOSE selects a value or an action to perform based on\n\t *\t\t\t\t\t\t\t\tindex_num. The arguments can be numbers, cell references, defined names, formulas, functions, or\n\t *\t\t\t\t\t\t\t\ttext.\n\t * @return\tmixed\t\t\tThe selected value\n\t */\n\tpublic static function CHOOSE() {\n\t\t$chooseArgs = func_get_args();\n\t\t$chosenEntry = PHPExcel_Calculation_Functions::flattenArray(array_shift($chooseArgs));\n\t\t$entryCount = count($chooseArgs) - 1;\n\n\t\tif(is_array($chosenEntry)) {\n\t\t\t$chosenEntry = array_shift($chosenEntry);\n\t\t}\n\t\tif ((is_numeric($chosenEntry)) && (!is_bool($chosenEntry))) {\n\t\t\t--$chosenEntry;\n\t\t} else {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$chosenEntry = floor($chosenEntry);\n\t\tif (($chosenEntry < 0) || ($chosenEntry > $entryCount)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (is_array($chooseArgs[$chosenEntry])) {\n\t\t\treturn PHPExcel_Calculation_Functions::flattenArray($chooseArgs[$chosenEntry]);\n\t\t} else {\n\t\t\treturn $chooseArgs[$chosenEntry];\n\t\t}\n\t}\t//\tfunction CHOOSE()\n\n\n\t/**\n\t * MATCH\n\t *\n\t * The MATCH function searches for a specified item in a range of cells\n\t *\n\t * Excel Function:\n\t *\t\t=MATCH(lookup_value, lookup_array, [match_type])\n\t *\n\t * @param\tlookup_value\tThe value that you want to match in lookup_array\n\t * @param\tlookup_array\tThe range of cells being searched\n\t * @param\tmatch_type\t\tThe number -1, 0, or 1. -1 means above, 0 means exact match, 1 means below. If match_type is 1 or -1, the list has to be ordered.\n\t * @return\tinteger\t\t\tThe relative position of the found item\n\t */\n\tpublic static function MATCH($lookup_value, $lookup_array, $match_type=1) {\n\t\t$lookup_array = PHPExcel_Calculation_Functions::flattenArray($lookup_array);\n\t\t$lookup_value = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value);\n\t\t$match_type\t= (is_null($match_type)) ? 1 : (int) PHPExcel_Calculation_Functions::flattenSingleValue($match_type);\n\t\t//\tMATCH is not case sensitive\n\t\t$lookup_value = strtolower($lookup_value);\n\n\t\t//\tlookup_value type has to be number, text, or logical values\n\t\tif ((!is_numeric($lookup_value)) && (!is_string($lookup_value)) && (!is_bool($lookup_value))) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t}\n\n\t\t//\tmatch_type is 0, 1 or -1\n\t\tif (($match_type !== 0) && ($match_type !== -1) && ($match_type !== 1)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t}\n\n\t\t//\tlookup_array should not be empty\n\t\t$lookupArraySize = count($lookup_array);\n\t\tif ($lookupArraySize <= 0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t}\n\n\t\t//\tlookup_array should contain only number, text, or logical values, or empty (null) cells\n\t\tforeach($lookup_array as $i => $lookupArrayValue) {\n\t\t\t//\tcheck the type of the value\n\t\t\tif ((!is_numeric($lookupArrayValue)) && (!is_string($lookupArrayValue)) &&\n\t\t\t\t(!is_bool($lookupArrayValue)) && (!is_null($lookupArrayValue))) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t\t}\n\t\t\t//\tconvert strings to lowercase for case-insensitive testing\n\t\t\tif (is_string($lookupArrayValue)) {\n\t\t\t\t$lookup_array[$i] = strtolower($lookupArrayValue);\n\t\t\t}\n\t\t\tif ((is_null($lookupArrayValue)) && (($match_type == 1) || ($match_type == -1))) {\n\t\t\t\t$lookup_array = array_slice($lookup_array,0,$i-1);\n\t\t\t}\n\t\t}\n\n\t\t// if match_type is 1 or -1, the list has to be ordered\n\t\tif ($match_type == 1) {\n\t\t\tasort($lookup_array);\n\t\t\t$keySet = array_keys($lookup_array);\n\t\t} elseif($match_type == -1) {\n\t\t\tarsort($lookup_array);\n\t\t\t$keySet = array_keys($lookup_array);\n\t\t}\n\n\t\t// **\n\t\t// find the match\n\t\t// **\n\t\t// loop on the cells\n//\t\tvar_dump($lookup_array);\n//\t\techo '<br />';\n\t\tforeach($lookup_array as $i => $lookupArrayValue) {\n\t\t\tif (($match_type == 0) && ($lookupArrayValue == $lookup_value)) {\n\t\t\t\t//\texact match\n\t\t\t\treturn ++$i;\n\t\t\t} elseif (($match_type == -1) && ($lookupArrayValue <= $lookup_value)) {\n//\t\t\t\techo '$i = '.$i.' => ';\n//\t\t\t\tvar_dump($lookupArrayValue);\n//\t\t\t\techo '<br />';\n//\t\t\t\techo 'Keyset = ';\n//\t\t\t\tvar_dump($keySet);\n//\t\t\t\techo '<br />';\n\t\t\t\t$i = array_search($i,$keySet);\n//\t\t\t\techo '$i='.$i.'<br />';\n\t\t\t\t// if match_type is -1 <=> find the smallest value that is greater than or equal to lookup_value\n\t\t\t\tif ($i < 1){\n\t\t\t\t\t// 1st cell was allready smaller than the lookup_value\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\t// the previous cell was the match\n\t\t\t\t\treturn $keySet[$i-1]+1;\n\t\t\t\t}\n\t\t\t} elseif (($match_type == 1) && ($lookupArrayValue >= $lookup_value)) {\n//\t\t\t\techo '$i = '.$i.' => ';\n//\t\t\t\tvar_dump($lookupArrayValue);\n//\t\t\t\techo '<br />';\n//\t\t\t\techo 'Keyset = ';\n//\t\t\t\tvar_dump($keySet);\n//\t\t\t\techo '<br />';\n\t\t\t\t$i = array_search($i,$keySet);\n//\t\t\t\techo '$i='.$i.'<br />';\n\t\t\t\t// if match_type is 1 <=> find the largest value that is less than or equal to lookup_value\n\t\t\t\tif ($i < 1){\n\t\t\t\t\t// 1st cell was allready bigger than the lookup_value\n\t\t\t\t\tbreak;\n\t\t\t\t} else {\n\t\t\t\t\t// the previous cell was the match\n\t\t\t\t\treturn $keySet[$i-1]+1;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//\tunsuccessful in finding a match, return #N/A error value\n\t\treturn PHPExcel_Calculation_Functions::NA();\n\t}\t//\tfunction MATCH()\n\n\n\t/**\n\t * INDEX\n\t *\n\t * Uses an index to choose a value from a reference or array\n\t *\n\t * Excel Function:\n\t *\t\t=INDEX(range_array, row_num, [column_num])\n\t *\n\t * @param\trange_array\t\tA range of cells or an array constant\n\t * @param\trow_num\t\t\tThe row in array from which to return a value. If row_num is omitted, column_num is required.\n\t * @param\tcolumn_num\t\tThe column in array from which to return a value. If column_num is omitted, row_num is required.\n\t * @return\tmixed\t\t\tthe value of a specified cell or array of cells\n\t */\n\tpublic static function INDEX($arrayValues,$rowNum = 0,$columnNum = 0) {\n\n\t\tif (($rowNum < 0) || ($columnNum < 0)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (!is_array($arrayValues)) {\n\t\t\treturn PHPExcel_Calculation_Functions::REF();\n\t\t}\n\n\t\t$rowKeys = array_keys($arrayValues);\n\t\t$columnKeys = @array_keys($arrayValues[$rowKeys[0]]);\n\n\t\tif ($columnNum > count($columnKeys)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t} elseif ($columnNum == 0) {\n\t\t\tif ($rowNum == 0) {\n\t\t\t\treturn $arrayValues;\n\t\t\t}\n\t\t\t$rowNum = $rowKeys[--$rowNum];\n\t\t\t$returnArray = array();\n\t\t\tforeach($arrayValues as $arrayColumn) {\n\t\t\t\tif (is_array($arrayColumn)) {\n\t\t\t\t\tif (isset($arrayColumn[$rowNum])) {\n\t\t\t\t\t\t$returnArray[] = $arrayColumn[$rowNum];\n\t\t\t\t\t} else {\n\t\t\t\t\t\treturn $arrayValues[$rowNum];\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\treturn $arrayValues[$rowNum];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $returnArray;\n\t\t}\n\t\t$columnNum = $columnKeys[--$columnNum];\n\t\tif ($rowNum > count($rowKeys)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t} elseif ($rowNum == 0) {\n\t\t\treturn $arrayValues[$columnNum];\n\t\t}\n\t\t$rowNum = $rowKeys[--$rowNum];\n\n\t\treturn $arrayValues[$rowNum][$columnNum];\n\t}\t//\tfunction INDEX()\n\n\n\t/**\n\t * TRANSPOSE\n\t *\n\t * @param\tarray\t$matrixData\tA matrix of values\n\t * @return\tarray\n\t *\n\t * Unlike the Excel TRANSPOSE function, which will only work on a single row or column, this function will transpose a full matrix.\n\t */\n\tpublic static function TRANSPOSE($matrixData) {\n\t\t$returnMatrix = array();\n\t\tif (!is_array($matrixData)) { $matrixData = array(array($matrixData)); }\n\n\t\t$column = 0;\n\t\tforeach($matrixData as $matrixRow) {\n\t\t\t$row = 0;\n\t\t\tforeach($matrixRow as $matrixCell) {\n\t\t\t\t$returnMatrix[$row][$column] = $matrixCell;\n\t\t\t\t++$row;\n\t\t\t}\n\t\t\t++$column;\n\t\t}\n\t\treturn $returnMatrix;\n\t}\t//\tfunction TRANSPOSE()\n\n\n\tprivate static function _vlookupSort($a,$b) {\n\t\t$f = array_keys($a);\n\t\t$firstColumn = array_shift($f);\n\t\tif (strtolower($a[$firstColumn]) == strtolower($b[$firstColumn])) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn (strtolower($a[$firstColumn]) < strtolower($b[$firstColumn])) ? -1 : 1;\n\t}\t//\tfunction _vlookupSort()\n\n\n\t/**\n\t* VLOOKUP\n\t* The VLOOKUP function searches for value in the left-most column of lookup_array and returns the value in the same row based on the index_number.\n\t* @param\tlookup_value\tThe value that you want to match in lookup_array\n\t* @param\tlookup_array\tThe range of cells being searched\n\t* @param\tindex_number\tThe column number in table_array from which the matching value must be returned. The first column is 1.\n\t* @param\tnot_exact_match\tDetermines if you are looking for an exact match based on lookup_value.\n\t* @return\tmixed\t\t\tThe value of the found cell\n\t*/\n\tpublic static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match=true) {\n\t\t$lookup_value\t= PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value);\n\t\t$index_number\t= PHPExcel_Calculation_Functions::flattenSingleValue($index_number);\n\t\t$not_exact_match\t= PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match);\n\n\t\t// index_number must be greater than or equal to 1\n\t\tif ($index_number < 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\t// index_number must be less than or equal to the number of columns in lookup_array\n\t\tif ((!is_array($lookup_array)) || (empty($lookup_array))) {\n\t\t\treturn PHPExcel_Calculation_Functions::REF();\n\t\t} else {\n\t\t\t$f = array_keys($lookup_array);\n\t\t\t$firstRow = array_pop($f);\n\t\t\tif ((!is_array($lookup_array[$firstRow])) || ($index_number > count($lookup_array[$firstRow]))) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::REF();\n\t\t\t} else {\n\t\t\t\t$columnKeys = array_keys($lookup_array[$firstRow]);\n\t\t\t\t$returnColumn = $columnKeys[--$index_number];\n\t\t\t\t$firstColumn = array_shift($columnKeys);\n\t\t\t}\n\t\t}\n\n\t\tif (!$not_exact_match) {\n\t\t\tuasort($lookup_array,array('self','_vlookupSort'));\n\t\t}\n\n\t\t$rowNumber = $rowValue = False;\n\t\tforeach($lookup_array as $rowKey => $rowData) {\n\t\t\tif ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn]) && ($rowData[$firstColumn] > $lookup_value)) ||\n\t\t\t\t(!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)))) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$rowNumber = $rowKey;\n\t\t\t$rowValue = $rowData[$firstColumn];\n\t\t}\n\n\t\tif ($rowNumber !== false) {\n\t\t\tif ((!$not_exact_match) && ($rowValue != $lookup_value)) {\n\t\t\t\t//\tif an exact match is required, we have what we need to return an appropriate response\n\t\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t\t} else {\n\t\t\t\t//\totherwise return the appropriate value\n\t\t\t\treturn $lookup_array[$rowNumber][$returnColumn];\n\t\t\t}\n\t\t}\n\n\t\treturn PHPExcel_Calculation_Functions::NA();\n\t}\t//\tfunction VLOOKUP()\n\n\n/**\n    * HLOOKUP\n    * The HLOOKUP function searches for value in the top-most row of lookup_array and returns the value in the same column based on the index_number.\n    * @param    lookup_value    The value that you want to match in lookup_array\n    * @param    lookup_array    The range of cells being searched\n    * @param    index_number    The row number in table_array from which the matching value must be returned. The first row is 1.\n    * @param    not_exact_match Determines if you are looking for an exact match based on lookup_value.\n    * @return   mixed           The value of the found cell\n    */\n    public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match=true) {\n        $lookup_value   = PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value);\n        $index_number   = PHPExcel_Calculation_Functions::flattenSingleValue($index_number);\n        $not_exact_match    = PHPExcel_Calculation_Functions::flattenSingleValue($not_exact_match);\n\n        // index_number must be greater than or equal to 1\n        if ($index_number < 1) {\n            return PHPExcel_Calculation_Functions::VALUE();\n        }\n\n        // index_number must be less than or equal to the number of columns in lookup_array\n        if ((!is_array($lookup_array)) || (empty($lookup_array))) {\n            return PHPExcel_Calculation_Functions::REF();\n        } else {\n            $f = array_keys($lookup_array);\n            $firstRow = array_pop($f);\n            if ((!is_array($lookup_array[$firstRow])) || ($index_number > count($lookup_array[$firstRow]))) {\n                return PHPExcel_Calculation_Functions::REF();\n            } else {\n                $columnKeys = array_keys($lookup_array[$firstRow]);\n                                $firstkey = $f[0] - 1;\n                $returnColumn = $firstkey + $index_number;\n                $firstColumn = array_shift($f);\n            }\n        }\n\n        if (!$not_exact_match) {\n            $firstRowH = asort($lookup_array[$firstColumn]);\n        }\n\n        $rowNumber = $rowValue = False;\n        foreach($lookup_array[$firstColumn] as $rowKey => $rowData) {\n\t\t\tif ((is_numeric($lookup_value) && is_numeric($rowData) && ($rowData > $lookup_value)) ||\n\t\t\t\t(!is_numeric($lookup_value) && !is_numeric($rowData) && (strtolower($rowData) > strtolower($lookup_value)))) {\n                break;\n            }\n            $rowNumber = $rowKey;\n            $rowValue = $rowData;\n        }\n\n        if ($rowNumber !== false) {\n            if ((!$not_exact_match) && ($rowValue != $lookup_value)) {\n                //  if an exact match is required, we have what we need to return an appropriate response\n                return PHPExcel_Calculation_Functions::NA();\n            } else {\n                //  otherwise return the appropriate value\n                return $lookup_array[$returnColumn][$rowNumber];\n            }\n        }\n\n        return PHPExcel_Calculation_Functions::NA();\n    }   //  function HLOOKUP()\n\n\n\t/**\n\t * LOOKUP\n\t * The LOOKUP function searches for value either from a one-row or one-column range or from an array.\n\t * @param\tlookup_value\tThe value that you want to match in lookup_array\n\t * @param\tlookup_vector\tThe range of cells being searched\n\t * @param\tresult_vector\tThe column from which the matching value must be returned\n\t * @return\tmixed\t\t\tThe value of the found cell\n\t */\n\tpublic static function LOOKUP($lookup_value, $lookup_vector, $result_vector=null) {\n\t\t$lookup_value\t= PHPExcel_Calculation_Functions::flattenSingleValue($lookup_value);\n\n\t\tif (!is_array($lookup_vector)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t}\n\t\t$lookupRows = count($lookup_vector);\n\t\t$l = array_keys($lookup_vector);\n\t\t$l = array_shift($l);\n\t\t$lookupColumns = count($lookup_vector[$l]);\n\t\tif ((($lookupRows == 1) && ($lookupColumns > 1)) || (($lookupRows == 2) && ($lookupColumns != 2))) {\n\t\t\t$lookup_vector = self::TRANSPOSE($lookup_vector);\n\t\t\t$lookupRows = count($lookup_vector);\n\t\t\t$l = array_keys($lookup_vector);\n\t\t\t$lookupColumns = count($lookup_vector[array_shift($l)]);\n\t\t}\n\n\t\tif (is_null($result_vector)) {\n\t\t\t$result_vector = $lookup_vector;\n\t\t}\n\t\t$resultRows = count($result_vector);\n\t\t$l = array_keys($result_vector);\n\t\t$l = array_shift($l);\n\t\t$resultColumns = count($result_vector[$l]);\n\t\tif ((($resultRows == 1) && ($resultColumns > 1)) || (($resultRows == 2) && ($resultColumns != 2))) {\n\t\t\t$result_vector = self::TRANSPOSE($result_vector);\n\t\t\t$resultRows = count($result_vector);\n\t\t\t$r = array_keys($result_vector);\n\t\t\t$resultColumns = count($result_vector[array_shift($r)]);\n\t\t}\n\n\t\tif ($lookupRows == 2) {\n\t\t\t$result_vector = array_pop($lookup_vector);\n\t\t\t$lookup_vector = array_shift($lookup_vector);\n\t\t}\n\t\tif ($lookupColumns != 2) {\n\t\t\tforeach($lookup_vector as &$value) {\n\t\t\t\tif (is_array($value)) {\n\t\t\t\t\t$k = array_keys($value);\n\t\t\t\t\t$key1 = $key2 = array_shift($k);\n\t\t\t\t\t$key2++;\n\t\t\t\t\t$dataValue1 = $value[$key1];\n\t\t\t\t} else {\n\t\t\t\t\t$key1 = 0;\n\t\t\t\t\t$key2 = 1;\n\t\t\t\t\t$dataValue1 = $value;\n\t\t\t\t}\n\t\t\t\t$dataValue2 = array_shift($result_vector);\n\t\t\t\tif (is_array($dataValue2)) {\n\t\t\t\t\t$dataValue2 = array_shift($dataValue2);\n\t\t\t\t}\n\t\t\t\t$value = array($key1 => $dataValue1, $key2 => $dataValue2);\n\t\t\t}\n\t\t\tunset($value);\n\t\t}\n\n\t\treturn self::VLOOKUP($lookup_value,$lookup_vector,2);\n \t}\t//\tfunction LOOKUP()\n\n}\t//\tclass PHPExcel_Calculation_LookupRef\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/MathTrig.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\n/**\n * PHPExcel_Calculation_MathTrig\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_MathTrig {\n\n\t//\n\t//\tPrivate method to return an array of the factors of the input value\n\t//\n\tprivate static function _factors($value) {\n\t\t$startVal = floor(sqrt($value));\n\n\t\t$factorArray = array();\n\t\tfor ($i = $startVal; $i > 1; --$i) {\n\t\t\tif (($value % $i) == 0) {\n\t\t\t\t$factorArray = array_merge($factorArray,self::_factors($value / $i));\n\t\t\t\t$factorArray = array_merge($factorArray,self::_factors($i));\n\t\t\t\tif ($i <= sqrt($value)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (!empty($factorArray)) {\n\t\t\trsort($factorArray);\n\t\t\treturn $factorArray;\n\t\t} else {\n\t\t\treturn array((integer) $value);\n\t\t}\n\t}\t//\tfunction _factors()\n\n\n\tprivate static function _romanCut($num, $n) {\n\t\treturn ($num - ($num % $n ) ) / $n;\n\t}\t//\tfunction _romanCut()\n\n\n\t/**\n\t * ATAN2\n\t *\n\t * This function calculates the arc tangent of the two variables x and y. It is similar to\n\t *\t\tcalculating the arc tangent of y ÷ x, except that the signs of both arguments are used\n\t *\t\tto determine the quadrant of the result.\n\t * The arctangent is the angle from the x-axis to a line containing the origin (0, 0) and a\n\t *\t\tpoint with coordinates (xCoordinate, yCoordinate). The angle is given in radians between\n\t *\t\t-pi and pi, excluding -pi.\n\t *\n\t * Note that the Excel ATAN2() function accepts its arguments in the reverse order to the standard\n\t *\t\tPHP atan2() function, so we need to reverse them here before calling the PHP atan() function.\n\t *\n\t * Excel Function:\n\t *\t\tATAN2(xCoordinate,yCoordinate)\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tfloat\t$xCoordinate\t\tThe x-coordinate of the point.\n\t * @param\tfloat\t$yCoordinate\t\tThe y-coordinate of the point.\n\t * @return\tfloat\tThe inverse tangent of the specified x- and y-coordinates.\n\t */\n\tpublic static function ATAN2($xCoordinate = NULL, $yCoordinate = NULL) {\n\t\t$xCoordinate\t= PHPExcel_Calculation_Functions::flattenSingleValue($xCoordinate);\n\t\t$yCoordinate\t= PHPExcel_Calculation_Functions::flattenSingleValue($yCoordinate);\n\n\t\t$xCoordinate\t= ($xCoordinate !== NULL)\t? $xCoordinate : 0.0;\n\t\t$yCoordinate\t= ($yCoordinate !== NULL)\t? $yCoordinate : 0.0;\n\n\t\tif (((is_numeric($xCoordinate)) || (is_bool($xCoordinate))) &&\n\t\t\t((is_numeric($yCoordinate)))  || (is_bool($yCoordinate))) {\n\t\t\t$xCoordinate\t= (float) $xCoordinate;\n\t\t\t$yCoordinate\t= (float) $yCoordinate;\n\n\t\t\tif (($xCoordinate == 0) && ($yCoordinate == 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t\t}\n\n\t\t\treturn atan2($yCoordinate, $xCoordinate);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction ATAN2()\n\n\n\t/**\n\t * CEILING\n\t *\n\t * Returns number rounded up, away from zero, to the nearest multiple of significance.\n\t *\t\tFor example, if you want to avoid using pennies in your prices and your product is\n\t *\t\tpriced at $4.42, use the formula =CEILING(4.42,0.05) to round prices up to the\n\t *\t\tnearest nickel.\n\t *\n\t * Excel Function:\n\t *\t\tCEILING(number[,significance])\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tfloat\t$number\t\t\tThe number you want to round.\n\t * @param\tfloat\t$significance\tThe multiple to which you want to round.\n\t * @return\tfloat\tRounded Number\n\t */\n\tpublic static function CEILING($number, $significance = NULL) {\n\t\t$number\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($number);\n\t\t$significance\t= PHPExcel_Calculation_Functions::flattenSingleValue($significance);\n\n\t\tif ((is_null($significance)) &&\n\t\t\t(PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) {\n\t\t\t$significance = $number/abs($number);\n\t\t}\n\n        if ((is_numeric($number)) && (is_numeric($significance))) {\n            if (($number == 0.0 ) || ($significance == 0.0)) {\n\t\t\t\treturn 0.0;\n\t\t\t} elseif (self::SIGN($number) == self::SIGN($significance)) {\n\t\t\t\treturn ceil($number / $significance) * $significance;\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction CEILING()\n\n\n\t/**\n\t * COMBIN\n\t *\n\t * Returns the number of combinations for a given number of items. Use COMBIN to\n\t *\t\tdetermine the total possible number of groups for a given number of items.\n\t *\n\t * Excel Function:\n\t *\t\tCOMBIN(numObjs,numInSet)\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tint\t\t$numObjs\tNumber of different objects\n\t * @param\tint\t\t$numInSet\tNumber of objects in each combination\n\t * @return\tint\t\tNumber of combinations\n\t */\n\tpublic static function COMBIN($numObjs, $numInSet) {\n\t\t$numObjs\t= PHPExcel_Calculation_Functions::flattenSingleValue($numObjs);\n\t\t$numInSet\t= PHPExcel_Calculation_Functions::flattenSingleValue($numInSet);\n\n\t\tif ((is_numeric($numObjs)) && (is_numeric($numInSet))) {\n\t\t\tif ($numObjs < $numInSet) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t} elseif ($numInSet < 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn round(self::FACT($numObjs) / self::FACT($numObjs - $numInSet)) / self::FACT($numInSet);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction COMBIN()\n\n\n\t/**\n\t * EVEN\n\t *\n\t * Returns number rounded up to the nearest even integer.\n\t * You can use this function for processing items that come in twos. For example,\n\t *\t\ta packing crate accepts rows of one or two items. The crate is full when\n\t *\t\tthe number of items, rounded up to the nearest two, matches the crate's\n\t *\t\tcapacity.\n\t *\n\t * Excel Function:\n\t *\t\tEVEN(number)\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tfloat\t$number\t\t\tNumber to round\n\t * @return\tint\t\tRounded Number\n\t */\n\tpublic static function EVEN($number) {\n\t\t$number\t= PHPExcel_Calculation_Functions::flattenSingleValue($number);\n\n\t\tif (is_null($number)) {\n\t\t\treturn 0;\n\t\t} elseif (is_bool($number)) {\n\t\t\t$number = (int) $number;\n\t\t}\n\n\t\tif (is_numeric($number)) {\n\t\t\t$significance = 2 * self::SIGN($number);\n\t\t\treturn (int) self::CEILING($number,$significance);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction EVEN()\n\n\n\t/**\n\t * FACT\n\t *\n\t * Returns the factorial of a number.\n\t * The factorial of a number is equal to 1*2*3*...* number.\n\t *\n\t * Excel Function:\n\t *\t\tFACT(factVal)\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tfloat\t$factVal\tFactorial Value\n\t * @return\tint\t\tFactorial\n\t */\n\tpublic static function FACT($factVal) {\n\t\t$factVal\t= PHPExcel_Calculation_Functions::flattenSingleValue($factVal);\n\n\t\tif (is_numeric($factVal)) {\n\t\t\tif ($factVal < 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$factLoop = floor($factVal);\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {\n\t\t\t\tif ($factVal > $factLoop) {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$factorial = 1;\n\t\t\twhile ($factLoop > 1) {\n\t\t\t\t$factorial *= $factLoop--;\n\t\t\t}\n\t\t\treturn $factorial ;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction FACT()\n\n\n\t/**\n\t * FACTDOUBLE\n\t *\n\t * Returns the double factorial of a number.\n\t *\n\t * Excel Function:\n\t *\t\tFACTDOUBLE(factVal)\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tfloat\t$factVal\tFactorial Value\n\t * @return\tint\t\tDouble Factorial\n\t */\n\tpublic static function FACTDOUBLE($factVal) {\n\t\t$factLoop\t= PHPExcel_Calculation_Functions::flattenSingleValue($factVal);\n\n\t\tif (is_numeric($factLoop)) {\n\t\t\t$factLoop\t= floor($factLoop);\n\t\t\tif ($factVal < 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$factorial = 1;\n\t\t\twhile ($factLoop > 1) {\n\t\t\t\t$factorial *= $factLoop--;\n\t\t\t\t--$factLoop;\n\t\t\t}\n\t\t\treturn $factorial ;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction FACTDOUBLE()\n\n\n\t/**\n\t * FLOOR\n\t *\n\t * Rounds number down, toward zero, to the nearest multiple of significance.\n\t *\n\t * Excel Function:\n\t *\t\tFLOOR(number[,significance])\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tfloat\t$number\t\t\tNumber to round\n\t * @param\tfloat\t$significance\tSignificance\n\t * @return\tfloat\tRounded Number\n\t */\n\tpublic static function FLOOR($number, $significance = NULL) {\n\t\t$number\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($number);\n\t\t$significance\t= PHPExcel_Calculation_Functions::flattenSingleValue($significance);\n\n\t\tif ((is_null($significance)) && (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC)) {\n\t\t\t$significance = $number/abs($number);\n\t\t}\n\n\t\tif ((is_numeric($number)) && (is_numeric($significance))) {\n            if ($significance == 0.0) {\n                return PHPExcel_Calculation_Functions::DIV0();\n            } elseif ($number == 0.0) {\n\t\t\t\treturn 0.0;\n\t\t\t} elseif (self::SIGN($number) == self::SIGN($significance)) {\n\t\t\t\treturn floor($number / $significance) * $significance;\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t} else\n\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction FLOOR()\n\n\n\t/**\n\t * GCD\n\t *\n\t * Returns the greatest common divisor of a series of numbers.\n\t * The greatest common divisor is the largest integer that divides both\n\t *\t\tnumber1 and number2 without a remainder.\n\t *\n\t * Excel Function:\n\t *\t\tGCD(number1[,number2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tmixed\t$arg,...\t\tData values\n\t * @return\tinteger\t\t\t\t\tGreatest Common Divisor\n\t */\n\tpublic static function GCD() {\n\t\t$returnValue = 1;\n\t\t$allValuesFactors = array();\n\t\t// Loop through arguments\n\t\tforeach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) {\n\t\t\tif (!is_numeric($value)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t} elseif ($value == 0) {\n\t\t\t\tcontinue;\n\t\t\t} elseif($value < 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$myFactors = self::_factors($value);\n\t\t\t$myCountedFactors = array_count_values($myFactors);\n\t\t\t$allValuesFactors[] = $myCountedFactors;\n\t\t}\n\t\t$allValuesCount = count($allValuesFactors);\n\t\tif ($allValuesCount == 0) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t$mergedArray = $allValuesFactors[0];\n\t\tfor ($i=1;$i < $allValuesCount; ++$i) {\n\t\t\t$mergedArray = array_intersect_key($mergedArray,$allValuesFactors[$i]);\n\t\t}\n\t\t$mergedArrayValues = count($mergedArray);\n\t\tif ($mergedArrayValues == 0) {\n\t\t\treturn $returnValue;\n\t\t} elseif ($mergedArrayValues > 1) {\n\t\t\tforeach($mergedArray as $mergedKey => $mergedValue) {\n\t\t\t\tforeach($allValuesFactors as $highestPowerTest) {\n\t\t\t\t\tforeach($highestPowerTest as $testKey => $testValue) {\n\t\t\t\t\t\tif (($testKey == $mergedKey) && ($testValue < $mergedValue)) {\n\t\t\t\t\t\t\t$mergedArray[$mergedKey] = $testValue;\n\t\t\t\t\t\t\t$mergedValue = $testValue;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$returnValue = 1;\n\t\t\tforeach($mergedArray as $key => $value) {\n\t\t\t\t$returnValue *= pow($key,$value);\n\t\t\t}\n\t\t\treturn $returnValue;\n\t\t} else {\n\t\t\t$keys = array_keys($mergedArray);\n\t\t\t$key = $keys[0];\n\t\t\t$value = $mergedArray[$key];\n\t\t\tforeach($allValuesFactors as $testValue) {\n\t\t\t\tforeach($testValue as $mergedKey => $mergedValue) {\n\t\t\t\t\tif (($mergedKey == $key) && ($mergedValue < $value)) {\n\t\t\t\t\t\t$value = $mergedValue;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn pow($key,$value);\n\t\t}\n\t}\t//\tfunction GCD()\n\n\n\t/**\n\t * INT\n\t *\n\t * Casts a floating point value to an integer\n\t *\n\t * Excel Function:\n\t *\t\tINT(number)\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tfloat\t$number\t\t\tNumber to cast to an integer\n\t * @return\tinteger\tInteger value\n\t */\n\tpublic static function INT($number) {\n\t\t$number\t= PHPExcel_Calculation_Functions::flattenSingleValue($number);\n\n\t\tif (is_null($number)) {\n\t\t\treturn 0;\n\t\t} elseif (is_bool($number)) {\n\t\t\treturn (int) $number;\n\t\t}\n\t\tif (is_numeric($number)) {\n\t\t\treturn (int) floor($number);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction INT()\n\n\n\t/**\n\t * LCM\n\t *\n\t * Returns the lowest common multiplier of a series of numbers\n\t * The least common multiple is the smallest positive integer that is a multiple\n\t * of all integer arguments number1, number2, and so on. Use LCM to add fractions\n\t * with different denominators.\n\t *\n\t * Excel Function:\n\t *\t\tLCM(number1[,number2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tmixed\t$arg,...\t\tData values\n\t * @return\tint\t\tLowest Common Multiplier\n\t */\n\tpublic static function LCM() {\n\t\t$returnValue = 1;\n\t\t$allPoweredFactors = array();\n\t\t// Loop through arguments\n\t\tforeach(PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $value) {\n\t\t\tif (!is_numeric($value)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t\tif ($value == 0) {\n\t\t\t\treturn 0;\n\t\t\t} elseif ($value < 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$myFactors = self::_factors(floor($value));\n\t\t\t$myCountedFactors = array_count_values($myFactors);\n\t\t\t$myPoweredFactors = array();\n\t\t\tforeach($myCountedFactors as $myCountedFactor => $myCountedPower) {\n\t\t\t\t$myPoweredFactors[$myCountedFactor] = pow($myCountedFactor,$myCountedPower);\n\t\t\t}\n\t\t\tforeach($myPoweredFactors as $myPoweredValue => $myPoweredFactor) {\n\t\t\t\tif (array_key_exists($myPoweredValue,$allPoweredFactors)) {\n\t\t\t\t\tif ($allPoweredFactors[$myPoweredValue] < $myPoweredFactor) {\n\t\t\t\t\t\t$allPoweredFactors[$myPoweredValue] = $myPoweredFactor;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t$allPoweredFactors[$myPoweredValue] = $myPoweredFactor;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tforeach($allPoweredFactors as $allPoweredFactor) {\n\t\t\t$returnValue *= (integer) $allPoweredFactor;\n\t\t}\n\t\treturn $returnValue;\n\t}\t//\tfunction LCM()\n\n\n\t/**\n\t * LOG_BASE\n\t *\n\t * Returns the logarithm of a number to a specified base. The default base is 10.\n\t *\n\t * Excel Function:\n\t *\t\tLOG(number[,base])\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tfloat\t$number\t\tThe positive real number for which you want the logarithm\n\t * @param\tfloat\t$base\t\tThe base of the logarithm. If base is omitted, it is assumed to be 10.\n\t * @return\tfloat\n\t */\n\tpublic static function LOG_BASE($number = NULL, $base = 10) {\n\t\t$number\t= PHPExcel_Calculation_Functions::flattenSingleValue($number);\n\t\t$base\t= (is_null($base)) ? 10 : (float) PHPExcel_Calculation_Functions::flattenSingleValue($base);\n\n\t\tif ((!is_numeric($base)) || (!is_numeric($number)))\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\tif (($base <= 0) || ($number <= 0))\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\treturn log($number, $base);\n\t}\t//\tfunction LOG_BASE()\n\n\n\t/**\n\t * MDETERM\n\t *\n\t * Returns the matrix determinant of an array.\n\t *\n\t * Excel Function:\n\t *\t\tMDETERM(array)\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tarray\t$matrixValues\tA matrix of values\n\t * @return\tfloat\n\t */\n\tpublic static function MDETERM($matrixValues) {\n\t\t$matrixData = array();\n\t\tif (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); }\n\n\t\t$row = $maxColumn = 0;\n\t\tforeach($matrixValues as $matrixRow) {\n\t\t\tif (!is_array($matrixRow)) { $matrixRow = array($matrixRow); }\n\t\t\t$column = 0;\n\t\t\tforeach($matrixRow as $matrixCell) {\n\t\t\t\tif ((is_string($matrixCell)) || ($matrixCell === null)) {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t}\n\t\t\t\t$matrixData[$column][$row] = $matrixCell;\n\t\t\t\t++$column;\n\t\t\t}\n\t\t\tif ($column > $maxColumn) { $maxColumn = $column; }\n\t\t\t++$row;\n\t\t}\n\t\tif ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); }\n\n\t\ttry {\n\t\t\t$matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData);\n\t\t\treturn $matrix->det();\n\t\t} catch (PHPExcel_Exception $ex) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t}\t//\tfunction MDETERM()\n\n\n\t/**\n\t * MINVERSE\n\t *\n\t * Returns the inverse matrix for the matrix stored in an array.\n\t *\n\t * Excel Function:\n\t *\t\tMINVERSE(array)\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tarray\t$matrixValues\tA matrix of values\n\t * @return\tarray\n\t */\n\tpublic static function MINVERSE($matrixValues) {\n\t\t$matrixData = array();\n\t\tif (!is_array($matrixValues)) { $matrixValues = array(array($matrixValues)); }\n\n\t\t$row = $maxColumn = 0;\n\t\tforeach($matrixValues as $matrixRow) {\n\t\t\tif (!is_array($matrixRow)) { $matrixRow = array($matrixRow); }\n\t\t\t$column = 0;\n\t\t\tforeach($matrixRow as $matrixCell) {\n\t\t\t\tif ((is_string($matrixCell)) || ($matrixCell === null)) {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t}\n\t\t\t\t$matrixData[$column][$row] = $matrixCell;\n\t\t\t\t++$column;\n\t\t\t}\n\t\t\tif ($column > $maxColumn) { $maxColumn = $column; }\n\t\t\t++$row;\n\t\t}\n\t\tif ($row != $maxColumn) { return PHPExcel_Calculation_Functions::VALUE(); }\n\n\t\ttry {\n\t\t\t$matrix = new PHPExcel_Shared_JAMA_Matrix($matrixData);\n\t\t\treturn $matrix->inverse()->getArray();\n\t\t} catch (PHPExcel_Exception $ex) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t}\t//\tfunction MINVERSE()\n\n\n\t/**\n\t * MMULT\n\t *\n\t * @param\tarray\t$matrixData1\tA matrix of values\n\t * @param\tarray\t$matrixData2\tA matrix of values\n\t * @return\tarray\n\t */\n\tpublic static function MMULT($matrixData1,$matrixData2) {\n\t\t$matrixAData = $matrixBData = array();\n\t\tif (!is_array($matrixData1)) { $matrixData1 = array(array($matrixData1)); }\n\t\tif (!is_array($matrixData2)) { $matrixData2 = array(array($matrixData2)); }\n\n\t\ttry {\n            $rowA = 0;\n            foreach($matrixData1 as $matrixRow) {\n                if (!is_array($matrixRow)) { $matrixRow = array($matrixRow); }\n                $columnA = 0;\n                foreach($matrixRow as $matrixCell) {\n                    if ((!is_numeric($matrixCell)) || ($matrixCell === null)) {\n                        return PHPExcel_Calculation_Functions::VALUE();\n                    }\n                    $matrixAData[$rowA][$columnA] = $matrixCell;\n                    ++$columnA;\n                }\n                ++$rowA;\n            }\n\t\t\t$matrixA = new PHPExcel_Shared_JAMA_Matrix($matrixAData);\n\t\t\t$rowB = 0;\n\t\t\tforeach($matrixData2 as $matrixRow) {\n\t\t\t\tif (!is_array($matrixRow)) { $matrixRow = array($matrixRow); }\n\t\t\t\t$columnB = 0;\n\t\t\t\tforeach($matrixRow as $matrixCell) {\n\t\t\t\t\tif ((!is_numeric($matrixCell)) || ($matrixCell === null)) {\n\t\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t\t}\n\t\t\t\t\t$matrixBData[$rowB][$columnB] = $matrixCell;\n\t\t\t\t\t++$columnB;\n\t\t\t\t}\n\t\t\t\t++$rowB;\n\t\t\t}\n\t\t\t$matrixB = new PHPExcel_Shared_JAMA_Matrix($matrixBData);\n\n\t\t\tif ($columnA != $rowB) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\n\t\t\treturn $matrixA->times($matrixB)->getArray();\n\t\t} catch (PHPExcel_Exception $ex) {\n            var_dump($ex->getMessage());\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t}\t//\tfunction MMULT()\n\n\n\t/**\n\t * MOD\n\t *\n\t * @param\tint\t\t$a\t\tDividend\n\t * @param\tint\t\t$b\t\tDivisor\n\t * @return\tint\t\tRemainder\n\t */\n\tpublic static function MOD($a = 1, $b = 1) {\n\t\t$a\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($a);\n\t\t$b\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($b);\n\n\t\tif ($b == 0.0) {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t} elseif (($a < 0.0) && ($b > 0.0)) {\n\t\t\treturn $b - fmod(abs($a),$b);\n\t\t} elseif (($a > 0.0) && ($b < 0.0)) {\n\t\t\treturn $b + fmod($a,abs($b));\n\t\t}\n\n\t\treturn fmod($a,$b);\n\t}\t//\tfunction MOD()\n\n\n\t/**\n\t * MROUND\n\t *\n\t * Rounds a number to the nearest multiple of a specified value\n\t *\n\t * @param\tfloat\t$number\t\t\tNumber to round\n\t * @param\tint\t\t$multiple\t\tMultiple to which you want to round $number\n\t * @return\tfloat\tRounded Number\n\t */\n\tpublic static function MROUND($number,$multiple) {\n\t\t$number\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($number);\n\t\t$multiple\t= PHPExcel_Calculation_Functions::flattenSingleValue($multiple);\n\n\t\tif ((is_numeric($number)) && (is_numeric($multiple))) {\n\t\t\tif ($multiple == 0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\tif ((self::SIGN($number)) == (self::SIGN($multiple))) {\n\t\t\t\t$multiplier = 1 / $multiple;\n\t\t\t\treturn round($number * $multiplier) / $multiplier;\n\t\t\t}\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction MROUND()\n\n\n\t/**\n\t * MULTINOMIAL\n\t *\n\t * Returns the ratio of the factorial of a sum of values to the product of factorials.\n\t *\n\t * @param\tarray of mixed\t\tData Series\n\t * @return\tfloat\n\t */\n\tpublic static function MULTINOMIAL() {\n\t\t$summer = 0;\n\t\t$divisor = 1;\n\t\t// Loop through arguments\n\t\tforeach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) {\n\t\t\t// Is it a numeric value?\n\t\t\tif (is_numeric($arg)) {\n\t\t\t\tif ($arg < 1) {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t\t}\n\t\t\t\t$summer += floor($arg);\n\t\t\t\t$divisor *= self::FACT($arg);\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif ($summer > 0) {\n\t\t\t$summer = self::FACT($summer);\n\t\t\treturn $summer / $divisor;\n\t\t}\n\t\treturn 0;\n\t}\t//\tfunction MULTINOMIAL()\n\n\n\t/**\n\t * ODD\n\t *\n\t * Returns number rounded up to the nearest odd integer.\n\t *\n\t * @param\tfloat\t$number\t\t\tNumber to round\n\t * @return\tint\t\tRounded Number\n\t */\n\tpublic static function ODD($number) {\n\t\t$number\t= PHPExcel_Calculation_Functions::flattenSingleValue($number);\n\n\t\tif (is_null($number)) {\n\t\t\treturn 1;\n\t\t} elseif (is_bool($number)) {\n\t\t\t$number = (int) $number;\n\t\t}\n\n\t\tif (is_numeric($number)) {\n\t\t\t$significance = self::SIGN($number);\n\t\t\tif ($significance == 0) {\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\t$result = self::CEILING($number,$significance);\n\t\t\tif ($result == self::EVEN($result)) {\n\t\t\t\t$result += $significance;\n\t\t\t}\n\n\t\t\treturn (int) $result;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction ODD()\n\n\n\t/**\n\t * POWER\n\t *\n\t * Computes x raised to the power y.\n\t *\n\t * @param\tfloat\t\t$x\n\t * @param\tfloat\t\t$y\n\t * @return\tfloat\n\t */\n\tpublic static function POWER($x = 0, $y = 2) {\n\t\t$x\t= PHPExcel_Calculation_Functions::flattenSingleValue($x);\n\t\t$y\t= PHPExcel_Calculation_Functions::flattenSingleValue($y);\n\n\t\t// Validate parameters\n\t\tif ($x == 0.0 && $y == 0.0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t} elseif ($x == 0.0 && $y < 0.0) {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t}\n\n\t\t// Return\n\t\t$result = pow($x, $y);\n\t\treturn (!is_nan($result) && !is_infinite($result)) ? $result : PHPExcel_Calculation_Functions::NaN();\n\t}\t//\tfunction POWER()\n\n\n\t/**\n\t * PRODUCT\n\t *\n\t * PRODUCT returns the product of all the values and cells referenced in the argument list.\n\t *\n\t * Excel Function:\n\t *\t\tPRODUCT(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function PRODUCT() {\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t// Loop through arguments\n\t\tforeach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) {\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\tif (is_null($returnValue)) {\n\t\t\t\t\t$returnValue = $arg;\n\t\t\t\t} else {\n\t\t\t\t\t$returnValue *= $arg;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif (is_null($returnValue)) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn $returnValue;\n\t}\t//\tfunction PRODUCT()\n\n\n\t/**\n\t * QUOTIENT\n\t *\n\t * QUOTIENT function returns the integer portion of a division. Numerator is the divided number\n\t *\t\tand denominator is the divisor.\n\t *\n\t * Excel Function:\n\t *\t\tQUOTIENT(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function QUOTIENT() {\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t// Loop through arguments\n\t\tforeach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) {\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\tif (is_null($returnValue)) {\n\t\t\t\t\t$returnValue = ($arg == 0) ? 0 : $arg;\n\t\t\t\t} else {\n\t\t\t\t\tif (($returnValue == 0) || ($arg == 0)) {\n\t\t\t\t\t\t$returnValue = 0;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$returnValue /= $arg;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn intval($returnValue);\n\t}\t//\tfunction QUOTIENT()\n\n\n\t/**\n\t * RAND\n\t *\n\t * @param\tint\t\t$min\tMinimal value\n\t * @param\tint\t\t$max\tMaximal value\n\t * @return\tint\t\tRandom number\n\t */\n\tpublic static function RAND($min = 0, $max = 0) {\n\t\t$min\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($min);\n\t\t$max\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($max);\n\n\t\tif ($min == 0 && $max == 0) {\n\t\t\treturn (mt_rand(0,10000000)) / 10000000;\n\t\t} else {\n\t\t\treturn mt_rand($min, $max);\n\t\t}\n\t}\t//\tfunction RAND()\n\n\n\tpublic static function ROMAN($aValue, $style=0) {\n\t\t$aValue\t= PHPExcel_Calculation_Functions::flattenSingleValue($aValue);\n\t\t$style\t= (is_null($style))\t? 0 :\t(integer) PHPExcel_Calculation_Functions::flattenSingleValue($style);\n\t\tif ((!is_numeric($aValue)) || ($aValue < 0) || ($aValue >= 4000)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$aValue = (integer) $aValue;\n\t\tif ($aValue == 0) {\n\t\t\treturn '';\n\t\t}\n\n\t\t$mill = Array('', 'M', 'MM', 'MMM', 'MMMM', 'MMMMM');\n\t\t$cent = Array('', 'C', 'CC', 'CCC', 'CD', 'D', 'DC', 'DCC', 'DCCC', 'CM');\n\t\t$tens = Array('', 'X', 'XX', 'XXX', 'XL', 'L', 'LX', 'LXX', 'LXXX', 'XC');\n\t\t$ones = Array('', 'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'IX');\n\n\t\t$roman = '';\n\t\twhile ($aValue > 5999) {\n\t\t\t$roman .= 'M';\n\t\t\t$aValue -= 1000;\n\t\t}\n\t\t$m = self::_romanCut($aValue, 1000);\t$aValue %= 1000;\n\t\t$c = self::_romanCut($aValue, 100);\t\t$aValue %= 100;\n\t\t$t = self::_romanCut($aValue, 10);\t\t$aValue %= 10;\n\n\t\treturn $roman.$mill[$m].$cent[$c].$tens[$t].$ones[$aValue];\n\t}\t//\tfunction ROMAN()\n\n\n\t/**\n\t * ROUNDUP\n\t *\n\t * Rounds a number up to a specified number of decimal places\n\t *\n\t * @param\tfloat\t$number\t\t\tNumber to round\n\t * @param\tint\t\t$digits\t\t\tNumber of digits to which you want to round $number\n\t * @return\tfloat\tRounded Number\n\t */\n\tpublic static function ROUNDUP($number,$digits) {\n\t\t$number\t= PHPExcel_Calculation_Functions::flattenSingleValue($number);\n\t\t$digits\t= PHPExcel_Calculation_Functions::flattenSingleValue($digits);\n\n\t\tif ((is_numeric($number)) && (is_numeric($digits))) {\n\t\t\t$significance = pow(10,(int) $digits);\n\t\t\tif ($number < 0.0) {\n\t\t\t\treturn floor($number * $significance) / $significance;\n\t\t\t} else {\n\t\t\t\treturn ceil($number * $significance) / $significance;\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction ROUNDUP()\n\n\n\t/**\n\t * ROUNDDOWN\n\t *\n\t * Rounds a number down to a specified number of decimal places\n\t *\n\t * @param\tfloat\t$number\t\t\tNumber to round\n\t * @param\tint\t\t$digits\t\t\tNumber of digits to which you want to round $number\n\t * @return\tfloat\tRounded Number\n\t */\n\tpublic static function ROUNDDOWN($number,$digits) {\n\t\t$number\t= PHPExcel_Calculation_Functions::flattenSingleValue($number);\n\t\t$digits\t= PHPExcel_Calculation_Functions::flattenSingleValue($digits);\n\n\t\tif ((is_numeric($number)) && (is_numeric($digits))) {\n\t\t\t$significance = pow(10,(int) $digits);\n\t\t\tif ($number < 0.0) {\n\t\t\t\treturn ceil($number * $significance) / $significance;\n\t\t\t} else {\n\t\t\t\treturn floor($number * $significance) / $significance;\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction ROUNDDOWN()\n\n\n\t/**\n\t * SERIESSUM\n\t *\n\t * Returns the sum of a power series\n\t *\n\t * @param\tfloat\t\t\t$x\tInput value to the power series\n\t * @param\tfloat\t\t\t$n\tInitial power to which you want to raise $x\n\t * @param\tfloat\t\t\t$m\tStep by which to increase $n for each term in the series\n\t * @param\tarray of mixed\t\tData Series\n\t * @return\tfloat\n\t */\n\tpublic static function SERIESSUM() {\n\t\t// Return value\n\t\t$returnValue = 0;\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\n\t\t$x = array_shift($aArgs);\n\t\t$n = array_shift($aArgs);\n\t\t$m = array_shift($aArgs);\n\n\t\tif ((is_numeric($x)) && (is_numeric($n)) && (is_numeric($m))) {\n\t\t\t// Calculate\n\t\t\t$i = 0;\n\t\t\tforeach($aArgs as $arg) {\n\t\t\t\t// Is it a numeric value?\n\t\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t\t$returnValue += $arg * pow($x,$n + ($m * $i++));\n\t\t\t\t} else {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Return\n\t\t\treturn $returnValue;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction SERIESSUM()\n\n\n\t/**\n\t * SIGN\n\t *\n\t * Determines the sign of a number. Returns 1 if the number is positive, zero (0)\n\t *\t\tif the number is 0, and -1 if the number is negative.\n\t *\n\t * @param\tfloat\t$number\t\t\tNumber to round\n\t * @return\tint\t\tsign value\n\t */\n\tpublic static function SIGN($number) {\n\t\t$number\t= PHPExcel_Calculation_Functions::flattenSingleValue($number);\n\n\t\tif (is_bool($number))\n\t\t\treturn (int) $number;\n\t\tif (is_numeric($number)) {\n\t\t\tif ($number == 0.0) {\n\t\t\t\treturn 0;\n\t\t\t}\n\t\t\treturn $number / abs($number);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction SIGN()\n\n\n\t/**\n\t * SQRTPI\n\t *\n\t * Returns the square root of (number * pi).\n\t *\n\t * @param\tfloat\t$number\t\tNumber\n\t * @return\tfloat\tSquare Root of Number * Pi\n\t */\n\tpublic static function SQRTPI($number) {\n\t\t$number\t= PHPExcel_Calculation_Functions::flattenSingleValue($number);\n\n\t\tif (is_numeric($number)) {\n\t\t\tif ($number < 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn sqrt($number * M_PI) ;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction SQRTPI()\n\n\n\t/**\n\t * SUBTOTAL\n\t *\n\t * Returns a subtotal in a list or database.\n\t *\n\t * @param\tint\t\tthe number 1 to 11 that specifies which function to\n\t *\t\t\t\t\tuse in calculating subtotals within a list.\n\t * @param\tarray of mixed\t\tData Series\n\t * @return\tfloat\n\t */\n\tpublic static function SUBTOTAL() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\n\t\t// Calculate\n\t\t$subtotal = array_shift($aArgs);\n\n\t\tif ((is_numeric($subtotal)) && (!is_string($subtotal))) {\n\t\t\tswitch($subtotal) {\n\t\t\t\tcase 1\t:\n\t\t\t\t\treturn PHPExcel_Calculation_Statistical::AVERAGE($aArgs);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 2\t:\n\t\t\t\t\treturn PHPExcel_Calculation_Statistical::COUNT($aArgs);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 3\t:\n\t\t\t\t\treturn PHPExcel_Calculation_Statistical::COUNTA($aArgs);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 4\t:\n\t\t\t\t\treturn PHPExcel_Calculation_Statistical::MAX($aArgs);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 5\t:\n\t\t\t\t\treturn PHPExcel_Calculation_Statistical::MIN($aArgs);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 6\t:\n\t\t\t\t\treturn self::PRODUCT($aArgs);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 7\t:\n\t\t\t\t\treturn PHPExcel_Calculation_Statistical::STDEV($aArgs);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 8\t:\n\t\t\t\t\treturn PHPExcel_Calculation_Statistical::STDEVP($aArgs);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 9\t:\n\t\t\t\t\treturn self::SUM($aArgs);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 10\t:\n\t\t\t\t\treturn PHPExcel_Calculation_Statistical::VARFunc($aArgs);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 11\t:\n\t\t\t\t\treturn PHPExcel_Calculation_Statistical::VARP($aArgs);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction SUBTOTAL()\n\n\n\t/**\n\t * SUM\n\t *\n\t * SUM computes the sum of all the values and cells referenced in the argument list.\n\t *\n\t * Excel Function:\n\t *\t\tSUM(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function SUM() {\n\t\t// Return value\n\t\t$returnValue = 0;\n\n\t\t// Loop through the arguments\n\t\tforeach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) {\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t$returnValue += $arg;\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction SUM()\n\n\n\t/**\n\t * SUMIF\n\t *\n\t * Counts the number of cells that contain numbers within the list of arguments\n\t *\n\t * Excel Function:\n\t *\t\tSUMIF(value1[,value2[, ...]],condition)\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @param\tstring\t\t$condition\t\tThe criteria that defines which cells will be summed.\n\t * @return\tfloat\n\t */\n\tpublic static function SUMIF($aArgs,$condition,$sumArgs = array()) {\n\t\t// Return value\n\t\t$returnValue = 0;\n\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs);\n\t\t$sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs);\n\t\tif (empty($sumArgs)) {\n\t\t\t$sumArgs = $aArgs;\n\t\t}\n\t\t$condition = PHPExcel_Calculation_Functions::_ifCondition($condition);\n\t\t// Loop through arguments\n\t\tforeach ($aArgs as $key => $arg) {\n\t\t\tif (!is_numeric($arg)) {\n\t\t\t\t$arg = str_replace('\"', '\"\"', $arg);\n\t\t\t\t$arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg));\n\t\t\t}\n\n\t\t\t$testCondition = '='.$arg.$condition;\n\t\t\tif (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) {\n\t\t\t\t// Is it a value within our criteria\n\t\t\t\t$returnValue += $sumArgs[$key];\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction SUMIF()\n\n\n\t/**\n\t * SUMPRODUCT\n\t *\n\t * Excel Function:\n\t *\t\tSUMPRODUCT(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function SUMPRODUCT() {\n\t\t$arrayList = func_get_args();\n\n\t\t$wrkArray = PHPExcel_Calculation_Functions::flattenArray(array_shift($arrayList));\n\t\t$wrkCellCount = count($wrkArray);\n\n\t\tfor ($i=0; $i< $wrkCellCount; ++$i) {\n\t\t\tif ((!is_numeric($wrkArray[$i])) || (is_string($wrkArray[$i]))) {\n\t\t\t\t$wrkArray[$i] = 0;\n\t\t\t}\n\t\t}\n\n\t\tforeach($arrayList as $matrixData) {\n\t\t\t$array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData);\n\t\t\t$count = count($array2);\n\t\t\tif ($wrkCellCount != $count) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\n\t\t\tforeach ($array2 as $i => $val) {\n\t\t\t\tif ((!is_numeric($val)) || (is_string($val))) {\n\t\t\t\t\t$val = 0;\n\t\t\t\t}\n\t\t\t\t$wrkArray[$i] *= $val;\n\t\t\t}\n\t\t}\n\n\t\treturn array_sum($wrkArray);\n\t}\t//\tfunction SUMPRODUCT()\n\n\n\t/**\n\t * SUMSQ\n\t *\n\t * SUMSQ returns the sum of the squares of the arguments\n\t *\n\t * Excel Function:\n\t *\t\tSUMSQ(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function SUMSQ() {\n\t\t// Return value\n\t\t$returnValue = 0;\n\n\t\t// Loop through arguments\n\t\tforeach (PHPExcel_Calculation_Functions::flattenArray(func_get_args()) as $arg) {\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t$returnValue += ($arg * $arg);\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction SUMSQ()\n\n\n\t/**\n\t * SUMX2MY2\n\t *\n\t * @param\tmixed[]\t$matrixData1\tMatrix #1\n\t * @param\tmixed[]\t$matrixData2\tMatrix #2\n\t * @return\tfloat\n\t */\n\tpublic static function SUMX2MY2($matrixData1,$matrixData2) {\n\t\t$array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1);\n\t\t$array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2);\n\t\t$count1 = count($array1);\n\t\t$count2 = count($array2);\n\t\tif ($count1 < $count2) {\n\t\t\t$count = $count1;\n\t\t} else {\n\t\t\t$count = $count2;\n\t\t}\n\n\t\t$result = 0;\n\t\tfor ($i = 0; $i < $count; ++$i) {\n\t\t\tif (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) &&\n\t\t\t\t((is_numeric($array2[$i])) && (!is_string($array2[$i])))) {\n\t\t\t\t$result += ($array1[$i] * $array1[$i]) - ($array2[$i] * $array2[$i]);\n\t\t\t}\n\t\t}\n\n\t\treturn $result;\n\t}\t//\tfunction SUMX2MY2()\n\n\n\t/**\n\t * SUMX2PY2\n\t *\n\t * @param\tmixed[]\t$matrixData1\tMatrix #1\n\t * @param\tmixed[]\t$matrixData2\tMatrix #2\n\t * @return\tfloat\n\t */\n\tpublic static function SUMX2PY2($matrixData1,$matrixData2) {\n\t\t$array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1);\n\t\t$array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2);\n\t\t$count1 = count($array1);\n\t\t$count2 = count($array2);\n\t\tif ($count1 < $count2) {\n\t\t\t$count = $count1;\n\t\t} else {\n\t\t\t$count = $count2;\n\t\t}\n\n\t\t$result = 0;\n\t\tfor ($i = 0; $i < $count; ++$i) {\n\t\t\tif (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) &&\n\t\t\t\t((is_numeric($array2[$i])) && (!is_string($array2[$i])))) {\n\t\t\t\t$result += ($array1[$i] * $array1[$i]) + ($array2[$i] * $array2[$i]);\n\t\t\t}\n\t\t}\n\n\t\treturn $result;\n\t}\t//\tfunction SUMX2PY2()\n\n\n\t/**\n\t * SUMXMY2\n\t *\n\t * @param\tmixed[]\t$matrixData1\tMatrix #1\n\t * @param\tmixed[]\t$matrixData2\tMatrix #2\n\t * @return\tfloat\n\t */\n\tpublic static function SUMXMY2($matrixData1,$matrixData2) {\n\t\t$array1 = PHPExcel_Calculation_Functions::flattenArray($matrixData1);\n\t\t$array2 = PHPExcel_Calculation_Functions::flattenArray($matrixData2);\n\t\t$count1 = count($array1);\n\t\t$count2 = count($array2);\n\t\tif ($count1 < $count2) {\n\t\t\t$count = $count1;\n\t\t} else {\n\t\t\t$count = $count2;\n\t\t}\n\n\t\t$result = 0;\n\t\tfor ($i = 0; $i < $count; ++$i) {\n\t\t\tif (((is_numeric($array1[$i])) && (!is_string($array1[$i]))) &&\n\t\t\t\t((is_numeric($array2[$i])) && (!is_string($array2[$i])))) {\n\t\t\t\t$result += ($array1[$i] - $array2[$i]) * ($array1[$i] - $array2[$i]);\n\t\t\t}\n\t\t}\n\n\t\treturn $result;\n\t}\t//\tfunction SUMXMY2()\n\n\n\t/**\n\t * TRUNC\n\t *\n\t * Truncates value to the number of fractional digits by number_digits.\n\t *\n\t * @param\tfloat\t\t$value\n\t * @param\tint\t\t\t$digits\n\t * @return\tfloat\t\tTruncated value\n\t */\n\tpublic static function TRUNC($value = 0, $digits = 0) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$digits\t= PHPExcel_Calculation_Functions::flattenSingleValue($digits);\n\n\t\t// Validate parameters\n\t\tif ((!is_numeric($value)) || (!is_numeric($digits)))\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t$digits\t= floor($digits);\n\n\t\t// Truncate\n\t\t$adjust = pow(10, $digits);\n\n\t\tif (($digits > 0) && (rtrim(intval((abs($value) - abs(intval($value))) * $adjust),'0') < $adjust/10))\n\t\t\treturn $value;\n\n\t\treturn (intval($value * $adjust)) / $adjust;\n\t}\t//\tfunction TRUNC()\n\n}\t//\tclass PHPExcel_Calculation_MathTrig\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Statistical.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\nrequire_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/trendClass.php';\n\n\n/** LOG_GAMMA_X_MAX_VALUE */\ndefine('LOG_GAMMA_X_MAX_VALUE', 2.55e305);\n\n/** XMININ */\ndefine('XMININ', 2.23e-308);\n\n/** EPS */\ndefine('EPS', 2.22e-16);\n\n/** SQRT2PI */\ndefine('SQRT2PI', 2.5066282746310005024157652848110452530069867406099);\n\n\n/**\n * PHPExcel_Calculation_Statistical\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_Statistical {\n\n\n\tprivate static function _checkTrendArrays(&$array1,&$array2) {\n\t\tif (!is_array($array1)) { $array1 = array($array1); }\n\t\tif (!is_array($array2)) { $array2 = array($array2); }\n\n\t\t$array1 = PHPExcel_Calculation_Functions::flattenArray($array1);\n\t\t$array2 = PHPExcel_Calculation_Functions::flattenArray($array2);\n\t\tforeach($array1 as $key => $value) {\n\t\t\tif ((is_bool($value)) || (is_string($value)) || (is_null($value))) {\n\t\t\t\tunset($array1[$key]);\n\t\t\t\tunset($array2[$key]);\n\t\t\t}\n\t\t}\n\t\tforeach($array2 as $key => $value) {\n\t\t\tif ((is_bool($value)) || (is_string($value)) || (is_null($value))) {\n\t\t\t\tunset($array1[$key]);\n\t\t\t\tunset($array2[$key]);\n\t\t\t}\n\t\t}\n\t\t$array1 = array_merge($array1);\n\t\t$array2 = array_merge($array2);\n\n\t\treturn True;\n\t}\t//\tfunction _checkTrendArrays()\n\n\n\t/**\n\t * Beta function.\n\t *\n\t * @author Jaco van Kooten\n\t *\n\t * @param p require p>0\n\t * @param q require q>0\n\t * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow\n\t */\n\tprivate static function _beta($p, $q) {\n\t\tif ($p <= 0.0 || $q <= 0.0 || ($p + $q) > LOG_GAMMA_X_MAX_VALUE) {\n\t\t\treturn 0.0;\n\t\t} else {\n\t\t\treturn exp(self::_logBeta($p, $q));\n\t\t}\n\t}\t//\tfunction _beta()\n\n\n\t/**\n\t * Incomplete beta function\n\t *\n\t * @author Jaco van Kooten\n\t * @author Paul Meagher\n\t *\n\t * The computation is based on formulas from Numerical Recipes, Chapter 6.4 (W.H. Press et al, 1992).\n\t * @param x require 0<=x<=1\n\t * @param p require p>0\n\t * @param q require q>0\n\t * @return 0 if x<0, p<=0, q<=0 or p+q>2.55E305 and 1 if x>1 to avoid errors and over/underflow\n\t */\n\tprivate static function _incompleteBeta($x, $p, $q) {\n\t\tif ($x <= 0.0) {\n\t\t\treturn 0.0;\n\t\t} elseif ($x >= 1.0) {\n\t\t\treturn 1.0;\n\t\t} elseif (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > LOG_GAMMA_X_MAX_VALUE)) {\n\t\t\treturn 0.0;\n\t\t}\n\t\t$beta_gam = exp((0 - self::_logBeta($p, $q)) + $p * log($x) + $q * log(1.0 - $x));\n\t\tif ($x < ($p + 1.0) / ($p + $q + 2.0)) {\n\t\t\treturn $beta_gam * self::_betaFraction($x, $p, $q) / $p;\n\t\t} else {\n\t\t\treturn 1.0 - ($beta_gam * self::_betaFraction(1 - $x, $q, $p) / $q);\n\t\t}\n\t}\t//\tfunction _incompleteBeta()\n\n\n\t// Function cache for _logBeta function\n\tprivate static $_logBetaCache_p\t\t\t= 0.0;\n\tprivate static $_logBetaCache_q\t\t\t= 0.0;\n\tprivate static $_logBetaCache_result\t= 0.0;\n\n\t/**\n\t * The natural logarithm of the beta function.\n\t *\n\t * @param p require p>0\n\t * @param q require q>0\n\t * @return 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow\n\t * @author Jaco van Kooten\n\t */\n\tprivate static function _logBeta($p, $q) {\n\t\tif ($p != self::$_logBetaCache_p || $q != self::$_logBetaCache_q) {\n\t\t\tself::$_logBetaCache_p = $p;\n\t\t\tself::$_logBetaCache_q = $q;\n\t\t\tif (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > LOG_GAMMA_X_MAX_VALUE)) {\n\t\t\t\tself::$_logBetaCache_result = 0.0;\n\t\t\t} else {\n\t\t\t\tself::$_logBetaCache_result = self::_logGamma($p) + self::_logGamma($q) - self::_logGamma($p + $q);\n\t\t\t}\n\t\t}\n\t\treturn self::$_logBetaCache_result;\n\t}\t//\tfunction _logBeta()\n\n\n\t/**\n\t * Evaluates of continued fraction part of incomplete beta function.\n\t * Based on an idea from Numerical Recipes (W.H. Press et al, 1992).\n\t * @author Jaco van Kooten\n\t */\n\tprivate static function _betaFraction($x, $p, $q) {\n\t\t$c = 1.0;\n\t\t$sum_pq = $p + $q;\n\t\t$p_plus = $p + 1.0;\n\t\t$p_minus = $p - 1.0;\n\t\t$h = 1.0 - $sum_pq * $x / $p_plus;\n\t\tif (abs($h) < XMININ) {\n\t\t\t$h = XMININ;\n\t\t}\n\t\t$h = 1.0 / $h;\n\t\t$frac = $h;\n\t\t$m\t = 1;\n\t\t$delta = 0.0;\n\t\twhile ($m <= MAX_ITERATIONS && abs($delta-1.0) > PRECISION ) {\n\t\t\t$m2 = 2 * $m;\n\t\t\t// even index for d\n\t\t\t$d = $m * ($q - $m) * $x / ( ($p_minus + $m2) * ($p + $m2));\n\t\t\t$h = 1.0 + $d * $h;\n\t\t\tif (abs($h) < XMININ) {\n\t\t\t\t$h = XMININ;\n\t\t\t}\n\t\t\t$h = 1.0 / $h;\n\t\t\t$c = 1.0 + $d / $c;\n\t\t\tif (abs($c) < XMININ) {\n\t\t\t\t$c = XMININ;\n\t\t\t}\n\t\t\t$frac *= $h * $c;\n\t\t\t// odd index for d\n\t\t\t$d = -($p + $m) * ($sum_pq + $m) * $x / (($p + $m2) * ($p_plus + $m2));\n\t\t\t$h = 1.0 + $d * $h;\n\t\t\tif (abs($h) < XMININ) {\n\t\t\t\t$h = XMININ;\n\t\t\t}\n\t\t\t$h = 1.0 / $h;\n\t\t\t$c = 1.0 + $d / $c;\n\t\t\tif (abs($c) < XMININ) {\n\t\t\t\t$c = XMININ;\n\t\t\t}\n\t\t\t$delta = $h * $c;\n\t\t\t$frac *= $delta;\n\t\t\t++$m;\n\t\t}\n\t\treturn $frac;\n\t}\t//\tfunction _betaFraction()\n\n\n\t/**\n\t * logGamma function\n\t *\n\t * @version 1.1\n\t * @author Jaco van Kooten\n\t *\n\t * Original author was Jaco van Kooten. Ported to PHP by Paul Meagher.\n\t *\n\t * The natural logarithm of the gamma function. <br />\n\t * Based on public domain NETLIB (Fortran) code by W. J. Cody and L. Stoltz <br />\n\t * Applied Mathematics Division <br />\n\t * Argonne National Laboratory <br />\n\t * Argonne, IL 60439 <br />\n\t * <p>\n\t * References:\n\t * <ol>\n\t * <li>W. J. Cody and K. E. Hillstrom, 'Chebyshev Approximations for the Natural\n\t *\t Logarithm of the Gamma Function,' Math. Comp. 21, 1967, pp. 198-203.</li>\n\t * <li>K. E. Hillstrom, ANL/AMD Program ANLC366S, DGAMMA/DLGAMA, May, 1969.</li>\n\t * <li>Hart, Et. Al., Computer Approximations, Wiley and sons, New York, 1968.</li>\n\t * </ol>\n\t * </p>\n\t * <p>\n\t * From the original documentation:\n\t * </p>\n\t * <p>\n\t * This routine calculates the LOG(GAMMA) function for a positive real argument X.\n\t * Computation is based on an algorithm outlined in references 1 and 2.\n\t * The program uses rational functions that theoretically approximate LOG(GAMMA)\n\t * to at least 18 significant decimal digits. The approximation for X > 12 is from\n\t * reference 3, while approximations for X < 12.0 are similar to those in reference\n\t * 1, but are unpublished. The accuracy achieved depends on the arithmetic system,\n\t * the compiler, the intrinsic functions, and proper selection of the\n\t * machine-dependent constants.\n\t * </p>\n\t * <p>\n\t * Error returns: <br />\n\t * The program returns the value XINF for X .LE. 0.0 or when overflow would occur.\n\t * The computation is believed to be free of underflow and overflow.\n\t * </p>\n\t * @return MAX_VALUE for x < 0.0 or when overflow would occur, i.e. x > 2.55E305\n\t */\n\n\t// Function cache for logGamma\n\tprivate static $_logGammaCache_result\t= 0.0;\n\tprivate static $_logGammaCache_x\t\t= 0.0;\n\n\tprivate static function _logGamma($x) {\n\t\t// Log Gamma related constants\n\t\tstatic $lg_d1 = -0.5772156649015328605195174;\n\t\tstatic $lg_d2 = 0.4227843350984671393993777;\n\t\tstatic $lg_d4 = 1.791759469228055000094023;\n\n\t\tstatic $lg_p1 = array(\t4.945235359296727046734888,\n\t\t\t\t\t\t\t\t201.8112620856775083915565,\n\t\t\t\t\t\t\t\t2290.838373831346393026739,\n\t\t\t\t\t\t\t\t11319.67205903380828685045,\n\t\t\t\t\t\t\t\t28557.24635671635335736389,\n\t\t\t\t\t\t\t\t38484.96228443793359990269,\n\t\t\t\t\t\t\t\t26377.48787624195437963534,\n\t\t\t\t\t\t\t\t7225.813979700288197698961 );\n\t\tstatic $lg_p2 = array(\t4.974607845568932035012064,\n\t\t\t\t\t\t\t\t542.4138599891070494101986,\n\t\t\t\t\t\t\t\t15506.93864978364947665077,\n\t\t\t\t\t\t\t\t184793.2904445632425417223,\n\t\t\t\t\t\t\t\t1088204.76946882876749847,\n\t\t\t\t\t\t\t\t3338152.967987029735917223,\n\t\t\t\t\t\t\t\t5106661.678927352456275255,\n\t\t\t\t\t\t\t\t3074109.054850539556250927 );\n\t\tstatic $lg_p4 = array(\t14745.02166059939948905062,\n\t\t\t\t\t\t\t\t2426813.369486704502836312,\n\t\t\t\t\t\t\t\t121475557.4045093227939592,\n\t\t\t\t\t\t\t\t2663432449.630976949898078,\n\t\t\t\t\t\t\t\t29403789566.34553899906876,\n\t\t\t\t\t\t\t\t170266573776.5398868392998,\n\t\t\t\t\t\t\t\t492612579337.743088758812,\n\t\t\t\t\t\t\t\t560625185622.3951465078242 );\n\n\t\tstatic $lg_q1 = array(\t67.48212550303777196073036,\n\t\t\t\t\t\t\t\t1113.332393857199323513008,\n\t\t\t\t\t\t\t\t7738.757056935398733233834,\n\t\t\t\t\t\t\t\t27639.87074403340708898585,\n\t\t\t\t\t\t\t\t54993.10206226157329794414,\n\t\t\t\t\t\t\t\t61611.22180066002127833352,\n\t\t\t\t\t\t\t\t36351.27591501940507276287,\n\t\t\t\t\t\t\t\t8785.536302431013170870835 );\n\t\tstatic $lg_q2 = array(\t183.0328399370592604055942,\n\t\t\t\t\t\t\t\t7765.049321445005871323047,\n\t\t\t\t\t\t\t\t133190.3827966074194402448,\n\t\t\t\t\t\t\t\t1136705.821321969608938755,\n\t\t\t\t\t\t\t\t5267964.117437946917577538,\n\t\t\t\t\t\t\t\t13467014.54311101692290052,\n\t\t\t\t\t\t\t\t17827365.30353274213975932,\n\t\t\t\t\t\t\t\t9533095.591844353613395747 );\n\t\tstatic $lg_q4 = array(\t2690.530175870899333379843,\n\t\t\t\t\t\t\t\t639388.5654300092398984238,\n\t\t\t\t\t\t\t\t41355999.30241388052042842,\n\t\t\t\t\t\t\t\t1120872109.61614794137657,\n\t\t\t\t\t\t\t\t14886137286.78813811542398,\n\t\t\t\t\t\t\t\t101680358627.2438228077304,\n\t\t\t\t\t\t\t\t341747634550.7377132798597,\n\t\t\t\t\t\t\t\t446315818741.9713286462081 );\n\n\t\tstatic $lg_c  = array(\t-0.001910444077728,\n\t\t\t\t\t\t\t\t8.4171387781295e-4,\n\t\t\t\t\t\t\t\t-5.952379913043012e-4,\n\t\t\t\t\t\t\t\t7.93650793500350248e-4,\n\t\t\t\t\t\t\t\t-0.002777777777777681622553,\n\t\t\t\t\t\t\t\t0.08333333333333333331554247,\n\t\t\t\t\t\t\t\t0.0057083835261 );\n\n\t// Rough estimate of the fourth root of logGamma_xBig\n\tstatic $lg_frtbig = 2.25e76;\n\tstatic $pnt68\t = 0.6796875;\n\n\n\tif ($x == self::$_logGammaCache_x) {\n\t\treturn self::$_logGammaCache_result;\n\t}\n\t$y = $x;\n\tif ($y > 0.0 && $y <= LOG_GAMMA_X_MAX_VALUE) {\n\t\tif ($y <= EPS) {\n\t\t\t$res = -log(y);\n\t\t} elseif ($y <= 1.5) {\n\t\t\t// ---------------------\n\t\t\t//\tEPS .LT. X .LE. 1.5\n\t\t\t// ---------------------\n\t\t\tif ($y < $pnt68) {\n\t\t\t\t$corr = -log($y);\n\t\t\t\t$xm1 = $y;\n\t\t\t} else {\n\t\t\t\t$corr = 0.0;\n\t\t\t\t$xm1 = $y - 1.0;\n\t\t\t}\n\t\t\tif ($y <= 0.5 || $y >= $pnt68) {\n\t\t\t\t$xden = 1.0;\n\t\t\t\t$xnum = 0.0;\n\t\t\t\tfor ($i = 0; $i < 8; ++$i) {\n\t\t\t\t\t$xnum = $xnum * $xm1 + $lg_p1[$i];\n\t\t\t\t\t$xden = $xden * $xm1 + $lg_q1[$i];\n\t\t\t\t}\n\t\t\t\t$res = $corr + $xm1 * ($lg_d1 + $xm1 * ($xnum / $xden));\n\t\t\t} else {\n\t\t\t\t$xm2 = $y - 1.0;\n\t\t\t\t$xden = 1.0;\n\t\t\t\t$xnum = 0.0;\n\t\t\t\tfor ($i = 0; $i < 8; ++$i) {\n\t\t\t\t\t$xnum = $xnum * $xm2 + $lg_p2[$i];\n\t\t\t\t\t$xden = $xden * $xm2 + $lg_q2[$i];\n\t\t\t\t}\n\t\t\t\t$res = $corr + $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden));\n\t\t\t}\n\t\t} elseif ($y <= 4.0) {\n\t\t\t// ---------------------\n\t\t\t//\t1.5 .LT. X .LE. 4.0\n\t\t\t// ---------------------\n\t\t\t$xm2 = $y - 2.0;\n\t\t\t$xden = 1.0;\n\t\t\t$xnum = 0.0;\n\t\t\tfor ($i = 0; $i < 8; ++$i) {\n\t\t\t\t$xnum = $xnum * $xm2 + $lg_p2[$i];\n\t\t\t\t$xden = $xden * $xm2 + $lg_q2[$i];\n\t\t\t}\n\t\t\t$res = $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden));\n\t\t} elseif ($y <= 12.0) {\n\t\t\t// ----------------------\n\t\t\t//\t4.0 .LT. X .LE. 12.0\n\t\t\t// ----------------------\n\t\t\t$xm4 = $y - 4.0;\n\t\t\t$xden = -1.0;\n\t\t\t$xnum = 0.0;\n\t\t\tfor ($i = 0; $i < 8; ++$i) {\n\t\t\t\t$xnum = $xnum * $xm4 + $lg_p4[$i];\n\t\t\t\t$xden = $xden * $xm4 + $lg_q4[$i];\n\t\t\t}\n\t\t\t$res = $lg_d4 + $xm4 * ($xnum / $xden);\n\t\t} else {\n\t\t\t// ---------------------------------\n\t\t\t//\tEvaluate for argument .GE. 12.0\n\t\t\t// ---------------------------------\n\t\t\t$res = 0.0;\n\t\t\tif ($y <= $lg_frtbig) {\n\t\t\t\t$res = $lg_c[6];\n\t\t\t\t$ysq = $y * $y;\n\t\t\t\tfor ($i = 0; $i < 6; ++$i)\n\t\t\t\t\t$res = $res / $ysq + $lg_c[$i];\n\t\t\t\t}\n\t\t\t\t$res /= $y;\n\t\t\t\t$corr = log($y);\n\t\t\t\t$res = $res + log(SQRT2PI) - 0.5 * $corr;\n\t\t\t\t$res += $y * ($corr - 1.0);\n\t\t\t}\n\t\t} else {\n\t\t\t// --------------------------\n\t\t\t//\tReturn for bad arguments\n\t\t\t// --------------------------\n\t\t\t$res = MAX_VALUE;\n\t\t}\n\t\t// ------------------------------\n\t\t//\tFinal adjustments and return\n\t\t// ------------------------------\n\t\tself::$_logGammaCache_x = $x;\n\t\tself::$_logGammaCache_result = $res;\n\t\treturn $res;\n\t}\t//\tfunction _logGamma()\n\n\n\t//\n\t//\tPrivate implementation of the incomplete Gamma function\n\t//\n\tprivate static function _incompleteGamma($a,$x) {\n\t\tstatic $max = 32;\n\t\t$summer = 0;\n\t\tfor ($n=0; $n<=$max; ++$n) {\n\t\t\t$divisor = $a;\n\t\t\tfor ($i=1; $i<=$n; ++$i) {\n\t\t\t\t$divisor *= ($a + $i);\n\t\t\t}\n\t\t\t$summer += (pow($x,$n) / $divisor);\n\t\t}\n\t\treturn pow($x,$a) * exp(0-$x) * $summer;\n\t}\t//\tfunction _incompleteGamma()\n\n\n\t//\n\t//\tPrivate implementation of the Gamma function\n\t//\n\tprivate static function _gamma($data) {\n\t\tif ($data == 0.0) return 0;\n\n\t\tstatic $p0 = 1.000000000190015;\n\t\tstatic $p = array ( 1 => 76.18009172947146,\n\t\t\t\t\t\t\t2 => -86.50532032941677,\n\t\t\t\t\t\t\t3 => 24.01409824083091,\n\t\t\t\t\t\t\t4 => -1.231739572450155,\n\t\t\t\t\t\t\t5 => 1.208650973866179e-3,\n\t\t\t\t\t\t\t6 => -5.395239384953e-6\n\t\t\t\t\t\t  );\n\n\t\t$y = $x = $data;\n\t\t$tmp = $x + 5.5;\n\t\t$tmp -= ($x + 0.5) * log($tmp);\n\n\t\t$summer = $p0;\n\t\tfor ($j=1;$j<=6;++$j) {\n\t\t\t$summer += ($p[$j] / ++$y);\n\t\t}\n\t\treturn exp(0 - $tmp + log(SQRT2PI * $summer / $x));\n\t}\t//\tfunction _gamma()\n\n\n\t/***************************************************************************\n\t *\t\t\t\t\t\t\t\tinverse_ncdf.php\n\t *\t\t\t\t\t\t\t-------------------\n\t *\tbegin\t\t\t\t: Friday, January 16, 2004\n\t *\tcopyright\t\t\t: (C) 2004 Michael Nickerson\n\t *\temail\t\t\t\t: nickersonm@yahoo.com\n\t *\n\t ***************************************************************************/\n\tprivate static function _inverse_ncdf($p) {\n\t\t//\tInverse ncdf approximation by Peter J. Acklam, implementation adapted to\n\t\t//\tPHP by Michael Nickerson, using Dr. Thomas Ziegler's C implementation as\n\t\t//\ta guide. http://home.online.no/~pjacklam/notes/invnorm/index.html\n\t\t//\tI have not checked the accuracy of this implementation. Be aware that PHP\n\t\t//\twill truncate the coeficcients to 14 digits.\n\n\t\t//\tYou have permission to use and distribute this function freely for\n\t\t//\twhatever purpose you want, but please show common courtesy and give credit\n\t\t//\twhere credit is due.\n\n\t\t//\tInput paramater is $p - probability - where 0 < p < 1.\n\n\t\t//\tCoefficients in rational approximations\n\t\tstatic $a = array(\t1 => -3.969683028665376e+01,\n\t\t\t\t\t\t\t2 => 2.209460984245205e+02,\n\t\t\t\t\t\t\t3 => -2.759285104469687e+02,\n\t\t\t\t\t\t\t4 => 1.383577518672690e+02,\n\t\t\t\t\t\t\t5 => -3.066479806614716e+01,\n\t\t\t\t\t\t\t6 => 2.506628277459239e+00\n\t\t\t\t\t\t );\n\n\t\tstatic $b = array(\t1 => -5.447609879822406e+01,\n\t\t\t\t\t\t\t2 => 1.615858368580409e+02,\n\t\t\t\t\t\t\t3 => -1.556989798598866e+02,\n\t\t\t\t\t\t\t4 => 6.680131188771972e+01,\n\t\t\t\t\t\t\t5 => -1.328068155288572e+01\n\t\t\t\t\t\t );\n\n\t\tstatic $c = array(\t1 => -7.784894002430293e-03,\n\t\t\t\t\t\t\t2 => -3.223964580411365e-01,\n\t\t\t\t\t\t\t3 => -2.400758277161838e+00,\n\t\t\t\t\t\t\t4 => -2.549732539343734e+00,\n\t\t\t\t\t\t\t5 => 4.374664141464968e+00,\n\t\t\t\t\t\t\t6 => 2.938163982698783e+00\n\t\t\t\t\t\t );\n\n\t\tstatic $d = array(\t1 => 7.784695709041462e-03,\n\t\t\t\t\t\t\t2 => 3.224671290700398e-01,\n\t\t\t\t\t\t\t3 => 2.445134137142996e+00,\n\t\t\t\t\t\t\t4 => 3.754408661907416e+00\n\t\t\t\t\t\t );\n\n\t\t//\tDefine lower and upper region break-points.\n\t\t$p_low = 0.02425;\t\t\t//Use lower region approx. below this\n\t\t$p_high = 1 - $p_low;\t\t//Use upper region approx. above this\n\n\t\tif (0 < $p && $p < $p_low) {\n\t\t\t//\tRational approximation for lower region.\n\t\t\t$q = sqrt(-2 * log($p));\n\t\t\treturn ((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) /\n\t\t\t\t\t(((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1);\n\t\t} elseif ($p_low <= $p && $p <= $p_high) {\n\t\t\t//\tRational approximation for central region.\n\t\t\t$q = $p - 0.5;\n\t\t\t$r = $q * $q;\n\t\t\treturn ((((($a[1] * $r + $a[2]) * $r + $a[3]) * $r + $a[4]) * $r + $a[5]) * $r + $a[6]) * $q /\n\t\t\t\t   ((((($b[1] * $r + $b[2]) * $r + $b[3]) * $r + $b[4]) * $r + $b[5]) * $r + 1);\n\t\t} elseif ($p_high < $p && $p < 1) {\n\t\t\t//\tRational approximation for upper region.\n\t\t\t$q = sqrt(-2 * log(1 - $p));\n\t\t\treturn -((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) /\n\t\t\t\t\t (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1);\n\t\t}\n\t\t//\tIf 0 < p < 1, return a null value\n\t\treturn PHPExcel_Calculation_Functions::NULL();\n\t}\t//\tfunction _inverse_ncdf()\n\n\n\tprivate static function _inverse_ncdf2($prob) {\n\t\t//\tApproximation of inverse standard normal CDF developed by\n\t\t//\tB. Moro, \"The Full Monte,\" Risk 8(2), Feb 1995, 57-58.\n\n\t\t$a1 = 2.50662823884;\n\t\t$a2 = -18.61500062529;\n\t\t$a3 = 41.39119773534;\n\t\t$a4 = -25.44106049637;\n\n\t\t$b1 = -8.4735109309;\n\t\t$b2 = 23.08336743743;\n\t\t$b3 = -21.06224101826;\n\t\t$b4 = 3.13082909833;\n\n\t\t$c1 = 0.337475482272615;\n\t\t$c2 = 0.976169019091719;\n\t\t$c3 = 0.160797971491821;\n\t\t$c4 = 2.76438810333863E-02;\n\t\t$c5 = 3.8405729373609E-03;\n\t\t$c6 = 3.951896511919E-04;\n\t\t$c7 = 3.21767881768E-05;\n\t\t$c8 = 2.888167364E-07;\n\t\t$c9 = 3.960315187E-07;\n\n\t\t$y = $prob - 0.5;\n\t\tif (abs($y) < 0.42) {\n\t\t\t$z = ($y * $y);\n\t\t\t$z = $y * ((($a4 * $z + $a3) * $z + $a2) * $z + $a1) / (((($b4 * $z + $b3) * $z + $b2) * $z + $b1) * $z + 1);\n\t\t} else {\n\t\t\tif ($y > 0) {\n\t\t\t\t$z = log(-log(1 - $prob));\n\t\t\t} else {\n\t\t\t\t$z = log(-log($prob));\n\t\t\t}\n\t\t\t$z = $c1 + $z * ($c2 + $z * ($c3 + $z * ($c4 + $z * ($c5 + $z * ($c6 + $z * ($c7 + $z * ($c8 + $z * $c9)))))));\n\t\t\tif ($y < 0) {\n\t\t\t\t$z = -$z;\n\t\t\t}\n\t\t}\n\t\treturn $z;\n\t}\t//\tfunction _inverse_ncdf2()\n\n\n\tprivate static function _inverse_ncdf3($p) {\n\t\t//\tALGORITHM AS241 APPL. STATIST. (1988) VOL. 37, NO. 3.\n\t\t//\tProduces the normal deviate Z corresponding to a given lower\n\t\t//\ttail area of P; Z is accurate to about 1 part in 10**16.\n\t\t//\n\t\t//\tThis is a PHP version of the original FORTRAN code that can\n\t\t//\tbe found at http://lib.stat.cmu.edu/apstat/\n\t\t$split1 = 0.425;\n\t\t$split2 = 5;\n\t\t$const1 = 0.180625;\n\t\t$const2 = 1.6;\n\n\t\t//\tcoefficients for p close to 0.5\n\t\t$a0 = 3.3871328727963666080;\n\t\t$a1 = 1.3314166789178437745E+2;\n\t\t$a2 = 1.9715909503065514427E+3;\n\t\t$a3 = 1.3731693765509461125E+4;\n\t\t$a4 = 4.5921953931549871457E+4;\n\t\t$a5 = 6.7265770927008700853E+4;\n\t\t$a6 = 3.3430575583588128105E+4;\n\t\t$a7 = 2.5090809287301226727E+3;\n\n\t\t$b1 = 4.2313330701600911252E+1;\n\t\t$b2 = 6.8718700749205790830E+2;\n\t\t$b3 = 5.3941960214247511077E+3;\n\t\t$b4 = 2.1213794301586595867E+4;\n\t\t$b5 = 3.9307895800092710610E+4;\n\t\t$b6 = 2.8729085735721942674E+4;\n\t\t$b7 = 5.2264952788528545610E+3;\n\n\t\t//\tcoefficients for p not close to 0, 0.5 or 1.\n\t\t$c0 = 1.42343711074968357734;\n\t\t$c1 = 4.63033784615654529590;\n\t\t$c2 = 5.76949722146069140550;\n\t\t$c3 = 3.64784832476320460504;\n\t\t$c4 = 1.27045825245236838258;\n\t\t$c5 = 2.41780725177450611770E-1;\n\t\t$c6 = 2.27238449892691845833E-2;\n\t\t$c7 = 7.74545014278341407640E-4;\n\n\t\t$d1 = 2.05319162663775882187;\n\t\t$d2 = 1.67638483018380384940;\n\t\t$d3 = 6.89767334985100004550E-1;\n\t\t$d4 = 1.48103976427480074590E-1;\n\t\t$d5 = 1.51986665636164571966E-2;\n\t\t$d6 = 5.47593808499534494600E-4;\n\t\t$d7 = 1.05075007164441684324E-9;\n\n\t\t//\tcoefficients for p near 0 or 1.\n\t\t$e0 = 6.65790464350110377720;\n\t\t$e1 = 5.46378491116411436990;\n\t\t$e2 = 1.78482653991729133580;\n\t\t$e3 = 2.96560571828504891230E-1;\n\t\t$e4 = 2.65321895265761230930E-2;\n\t\t$e5 = 1.24266094738807843860E-3;\n\t\t$e6 = 2.71155556874348757815E-5;\n\t\t$e7 = 2.01033439929228813265E-7;\n\n\t\t$f1 = 5.99832206555887937690E-1;\n\t\t$f2 = 1.36929880922735805310E-1;\n\t\t$f3 = 1.48753612908506148525E-2;\n\t\t$f4 = 7.86869131145613259100E-4;\n\t\t$f5 = 1.84631831751005468180E-5;\n\t\t$f6 = 1.42151175831644588870E-7;\n\t\t$f7 = 2.04426310338993978564E-15;\n\n\t\t$q = $p - 0.5;\n\n\t\t//\tcomputation for p close to 0.5\n\t\tif (abs($q) <= split1) {\n\t\t\t$R = $const1 - $q * $q;\n\t\t\t$z = $q * ((((((($a7 * $R + $a6) * $R + $a5) * $R + $a4) * $R + $a3) * $R + $a2) * $R + $a1) * $R + $a0) /\n\t\t\t\t\t  ((((((($b7 * $R + $b6) * $R + $b5) * $R + $b4) * $R + $b3) * $R + $b2) * $R + $b1) * $R + 1);\n\t\t} else {\n\t\t\tif ($q < 0) {\n\t\t\t\t$R = $p;\n\t\t\t} else {\n\t\t\t\t$R = 1 - $p;\n\t\t\t}\n\t\t\t$R = pow(-log($R),2);\n\n\t\t\t//\tcomputation for p not close to 0, 0.5 or 1.\n\t\t\tIf ($R <= $split2) {\n\t\t\t\t$R = $R - $const2;\n\t\t\t\t$z = ((((((($c7 * $R + $c6) * $R + $c5) * $R + $c4) * $R + $c3) * $R + $c2) * $R + $c1) * $R + $c0) /\n\t\t\t\t\t ((((((($d7 * $R + $d6) * $R + $d5) * $R + $d4) * $R + $d3) * $R + $d2) * $R + $d1) * $R + 1);\n\t\t\t} else {\n\t\t\t//\tcomputation for p near 0 or 1.\n\t\t\t\t$R = $R - $split2;\n\t\t\t\t$z = ((((((($e7 * $R + $e6) * $R + $e5) * $R + $e4) * $R + $e3) * $R + $e2) * $R + $e1) * $R + $e0) /\n\t\t\t\t\t ((((((($f7 * $R + $f6) * $R + $f5) * $R + $f4) * $R + $f3) * $R + $f2) * $R + $f1) * $R + 1);\n\t\t\t}\n\t\t\tif ($q < 0) {\n\t\t\t\t$z = -$z;\n\t\t\t}\n\t\t}\n\t\treturn $z;\n\t}\t//\tfunction _inverse_ncdf3()\n\n\n\t/**\n\t * AVEDEV\n\t *\n\t * Returns the average of the absolute deviations of data points from their mean.\n\t * AVEDEV is a measure of the variability in a data set.\n\t *\n\t * Excel Function:\n\t *\t\tAVEDEV(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function AVEDEV() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args());\n\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t$aMean = self::AVERAGE($aArgs);\n\t\tif ($aMean != PHPExcel_Calculation_Functions::DIV0()) {\n\t\t\t$aCount = 0;\n\t\t\tforeach ($aArgs as $k => $arg) {\n\t\t\t\tif ((is_bool($arg)) &&\n\t\t\t\t\t((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) {\n\t\t\t\t\t$arg = (integer) $arg;\n\t\t\t\t}\n\t\t\t\t// Is it a numeric value?\n\t\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t\tif (is_null($returnValue)) {\n\t\t\t\t\t\t$returnValue = abs($arg - $aMean);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$returnValue += abs($arg - $aMean);\n\t\t\t\t\t}\n\t\t\t\t\t++$aCount;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Return\n\t\t\tif ($aCount == 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t\t}\n\t\t\treturn $returnValue / $aCount;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t}\t//\tfunction AVEDEV()\n\n\n\t/**\n\t * AVERAGE\n\t *\n\t * Returns the average (arithmetic mean) of the arguments\n\t *\n\t * Excel Function:\n\t *\t\tAVERAGE(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function AVERAGE() {\n\t\t$returnValue = $aCount = 0;\n\n\t\t// Loop through arguments\n\t\tforeach (PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()) as $k => $arg) {\n\t\t\tif ((is_bool($arg)) &&\n\t\t\t\t((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) {\n\t\t\t\t$arg = (integer) $arg;\n\t\t\t}\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\tif (is_null($returnValue)) {\n\t\t\t\t\t$returnValue = $arg;\n\t\t\t\t} else {\n\t\t\t\t\t$returnValue += $arg;\n\t\t\t\t}\n\t\t\t\t++$aCount;\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif ($aCount > 0) {\n\t\t\treturn $returnValue / $aCount;\n\t\t} else {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t}\n\t}\t//\tfunction AVERAGE()\n\n\n\t/**\n\t * AVERAGEA\n\t *\n\t * Returns the average of its arguments, including numbers, text, and logical values\n\t *\n\t * Excel Function:\n\t *\t\tAVERAGEA(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function AVERAGEA() {\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t$aCount = 0;\n\t\t// Loop through arguments\n\t\tforeach (PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args()) as $k => $arg) {\n\t\t\tif ((is_bool($arg)) &&\n\t\t\t\t(!PHPExcel_Calculation_Functions::isMatrixValue($k))) {\n\t\t\t} else {\n\t\t\t\tif ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {\n\t\t\t\t\tif (is_bool($arg)) {\n\t\t\t\t\t\t$arg = (integer) $arg;\n\t\t\t\t\t} elseif (is_string($arg)) {\n\t\t\t\t\t\t$arg = 0;\n\t\t\t\t\t}\n\t\t\t\t\tif (is_null($returnValue)) {\n\t\t\t\t\t\t$returnValue = $arg;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$returnValue += $arg;\n\t\t\t\t\t}\n\t\t\t\t\t++$aCount;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif ($aCount > 0) {\n\t\t\treturn $returnValue / $aCount;\n\t\t} else {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t}\n\t}\t//\tfunction AVERAGEA()\n\n\n\t/**\n\t * AVERAGEIF\n\t *\n\t * Returns the average value from a range of cells that contain numbers within the list of arguments\n\t *\n\t * Excel Function:\n\t *\t\tAVERAGEIF(value1[,value2[, ...]],condition)\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @param\tstring\t\t$condition\t\tThe criteria that defines which cells will be checked.\n\t * @param\tmixed[]\t\t$averageArgs\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function AVERAGEIF($aArgs,$condition,$averageArgs = array()) {\n\t\t// Return value\n\t\t$returnValue = 0;\n\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs);\n\t\t$averageArgs = PHPExcel_Calculation_Functions::flattenArray($averageArgs);\n\t\tif (empty($averageArgs)) {\n\t\t\t$averageArgs = $aArgs;\n\t\t}\n\t\t$condition = PHPExcel_Calculation_Functions::_ifCondition($condition);\n\t\t// Loop through arguments\n\t\t$aCount = 0;\n\t\tforeach ($aArgs as $key => $arg) {\n\t\t\tif (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); }\n\t\t\t$testCondition = '='.$arg.$condition;\n\t\t\tif (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) {\n\t\t\t\tif ((is_null($returnValue)) || ($arg > $returnValue)) {\n\t\t\t\t\t$returnValue += $arg;\n\t\t\t\t\t++$aCount;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif ($aCount > 0) {\n\t\t\treturn $returnValue / $aCount;\n\t\t} else {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t}\n\t}\t//\tfunction AVERAGEIF()\n\n\n\t/**\n\t * BETADIST\n\t *\n\t * Returns the beta distribution.\n\t *\n\t * @param\tfloat\t\t$value\t\t\tValue at which you want to evaluate the distribution\n\t * @param\tfloat\t\t$alpha\t\t\tParameter to the distribution\n\t * @param\tfloat\t\t$beta\t\t\tParameter to the distribution\n\t * @param\tboolean\t\t$cumulative\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function BETADIST($value,$alpha,$beta,$rMin=0,$rMax=1) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$alpha\t= PHPExcel_Calculation_Functions::flattenSingleValue($alpha);\n\t\t$beta\t= PHPExcel_Calculation_Functions::flattenSingleValue($beta);\n\t\t$rMin\t= PHPExcel_Calculation_Functions::flattenSingleValue($rMin);\n\t\t$rMax\t= PHPExcel_Calculation_Functions::flattenSingleValue($rMax);\n\n\t\tif ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) {\n\t\t\tif (($value < $rMin) || ($value > $rMax) || ($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif ($rMin > $rMax) {\n\t\t\t\t$tmp = $rMin;\n\t\t\t\t$rMin = $rMax;\n\t\t\t\t$rMax = $tmp;\n\t\t\t}\n\t\t\t$value -= $rMin;\n\t\t\t$value /= ($rMax - $rMin);\n\t\t\treturn self::_incompleteBeta($value,$alpha,$beta);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction BETADIST()\n\n\n\t/**\n\t * BETAINV\n\t *\n\t * Returns the inverse of the beta distribution.\n\t *\n\t * @param\tfloat\t\t$probability\tProbability at which you want to evaluate the distribution\n\t * @param\tfloat\t\t$alpha\t\t\tParameter to the distribution\n\t * @param\tfloat\t\t$beta\t\t\tParameter to the distribution\n\t * @param\tfloat\t\t$rMin\t\t\tMinimum value\n\t * @param\tfloat\t\t$rMax\t\t\tMaximum value\n\t * @param\tboolean\t\t$cumulative\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function BETAINV($probability,$alpha,$beta,$rMin=0,$rMax=1) {\n\t\t$probability\t= PHPExcel_Calculation_Functions::flattenSingleValue($probability);\n\t\t$alpha\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($alpha);\n\t\t$beta\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($beta);\n\t\t$rMin\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($rMin);\n\t\t$rMax\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($rMax);\n\n\t\tif ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) {\n\t\t\tif (($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax) || ($probability <= 0) || ($probability > 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif ($rMin > $rMax) {\n\t\t\t\t$tmp = $rMin;\n\t\t\t\t$rMin = $rMax;\n\t\t\t\t$rMax = $tmp;\n\t\t\t}\n\t\t\t$a = 0;\n\t\t\t$b = 2;\n\n\t\t\t$i = 0;\n\t\t\twhile ((($b - $a) > PRECISION) && ($i++ < MAX_ITERATIONS)) {\n\t\t\t\t$guess = ($a + $b) / 2;\n\t\t\t\t$result = self::BETADIST($guess, $alpha, $beta);\n\t\t\t\tif (($result == $probability) || ($result == 0)) {\n\t\t\t\t\t$b = $a;\n\t\t\t\t} elseif ($result > $probability) {\n\t\t\t\t\t$b = $guess;\n\t\t\t\t} else {\n\t\t\t\t\t$a = $guess;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ($i == MAX_ITERATIONS) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t\t}\n\t\t\treturn round($rMin + $guess * ($rMax - $rMin),12);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction BETAINV()\n\n\n\t/**\n\t * BINOMDIST\n\t *\n\t * Returns the individual term binomial distribution probability. Use BINOMDIST in problems with\n\t *\t\ta fixed number of tests or trials, when the outcomes of any trial are only success or failure,\n\t *\t\twhen trials are independent, and when the probability of success is constant throughout the\n\t *\t\texperiment. For example, BINOMDIST can calculate the probability that two of the next three\n\t *\t\tbabies born are male.\n\t *\n\t * @param\tfloat\t\t$value\t\t\tNumber of successes in trials\n\t * @param\tfloat\t\t$trials\t\t\tNumber of trials\n\t * @param\tfloat\t\t$probability\tProbability of success on each trial\n\t * @param\tboolean\t\t$cumulative\n\t * @return\tfloat\n\t *\n\t * @todo\tCumulative distribution function\n\t *\n\t */\n\tpublic static function BINOMDIST($value, $trials, $probability, $cumulative) {\n\t\t$value\t\t\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($value));\n\t\t$trials\t\t\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials));\n\t\t$probability\t= PHPExcel_Calculation_Functions::flattenSingleValue($probability);\n\n\t\tif ((is_numeric($value)) && (is_numeric($trials)) && (is_numeric($probability))) {\n\t\t\tif (($value < 0) || ($value > $trials)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif (($probability < 0) || ($probability > 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif ((is_numeric($cumulative)) || (is_bool($cumulative))) {\n\t\t\t\tif ($cumulative) {\n\t\t\t\t\t$summer = 0;\n\t\t\t\t\tfor ($i = 0; $i <= $value; ++$i) {\n\t\t\t\t\t\t$summer += PHPExcel_Calculation_MathTrig::COMBIN($trials,$i) * pow($probability,$i) * pow(1 - $probability,$trials - $i);\n\t\t\t\t\t}\n\t\t\t\t\treturn $summer;\n\t\t\t\t} else {\n\t\t\t\t\treturn PHPExcel_Calculation_MathTrig::COMBIN($trials,$value) * pow($probability,$value) * pow(1 - $probability,$trials - $value) ;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction BINOMDIST()\n\n\n\t/**\n\t * CHIDIST\n\t *\n\t * Returns the one-tailed probability of the chi-squared distribution.\n\t *\n\t * @param\tfloat\t\t$value\t\t\tValue for the function\n\t * @param\tfloat\t\t$degrees\t\tdegrees of freedom\n\t * @return\tfloat\n\t */\n\tpublic static function CHIDIST($value, $degrees) {\n\t\t$value\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$degrees\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees));\n\n\t\tif ((is_numeric($value)) && (is_numeric($degrees))) {\n\t\t\tif ($degrees < 1) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif ($value < 0) {\n\t\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {\n\t\t\t\t\treturn 1;\n\t\t\t\t}\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn 1 - (self::_incompleteGamma($degrees/2,$value/2) / self::_gamma($degrees/2));\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction CHIDIST()\n\n\n\t/**\n\t * CHIINV\n\t *\n\t * Returns the one-tailed probability of the chi-squared distribution.\n\t *\n\t * @param\tfloat\t\t$probability\tProbability for the function\n\t * @param\tfloat\t\t$degrees\t\tdegrees of freedom\n\t * @return\tfloat\n\t */\n\tpublic static function CHIINV($probability, $degrees) {\n\t\t$probability\t= PHPExcel_Calculation_Functions::flattenSingleValue($probability);\n\t\t$degrees\t\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees));\n\n\t\tif ((is_numeric($probability)) && (is_numeric($degrees))) {\n\n\t\t\t$xLo = 100;\n\t\t\t$xHi = 0;\n\n\t\t\t$x = $xNew = 1;\n\t\t\t$dx\t= 1;\n\t\t\t$i = 0;\n\n\t\t\twhile ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) {\n\t\t\t\t// Apply Newton-Raphson step\n\t\t\t\t$result = self::CHIDIST($x, $degrees);\n\t\t\t\t$error = $result - $probability;\n\t\t\t\tif ($error == 0.0) {\n\t\t\t\t\t$dx = 0;\n\t\t\t\t} elseif ($error < 0.0) {\n\t\t\t\t\t$xLo = $x;\n\t\t\t\t} else {\n\t\t\t\t\t$xHi = $x;\n\t\t\t\t}\n\t\t\t\t// Avoid division by zero\n\t\t\t\tif ($result != 0.0) {\n\t\t\t\t\t$dx = $error / $result;\n\t\t\t\t\t$xNew = $x - $dx;\n\t\t\t\t}\n\t\t\t\t// If the NR fails to converge (which for example may be the\n\t\t\t\t// case if the initial guess is too rough) we apply a bisection\n\t\t\t\t// step to determine a more narrow interval around the root.\n\t\t\t\tif (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) {\n\t\t\t\t\t$xNew = ($xLo + $xHi) / 2;\n\t\t\t\t\t$dx = $xNew - $x;\n\t\t\t\t}\n\t\t\t\t$x = $xNew;\n\t\t\t}\n\t\t\tif ($i == MAX_ITERATIONS) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t\t}\n\t\t\treturn round($x,12);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction CHIINV()\n\n\n\t/**\n\t * CONFIDENCE\n\t *\n\t * Returns the confidence interval for a population mean\n\t *\n\t * @param\tfloat\t\t$alpha\n\t * @param\tfloat\t\t$stdDev\t\tStandard Deviation\n\t * @param\tfloat\t\t$size\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function CONFIDENCE($alpha,$stdDev,$size) {\n\t\t$alpha\t= PHPExcel_Calculation_Functions::flattenSingleValue($alpha);\n\t\t$stdDev\t= PHPExcel_Calculation_Functions::flattenSingleValue($stdDev);\n\t\t$size\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($size));\n\n\t\tif ((is_numeric($alpha)) && (is_numeric($stdDev)) && (is_numeric($size))) {\n\t\t\tif (($alpha <= 0) || ($alpha >= 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif (($stdDev <= 0) || ($size < 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn self::NORMSINV(1 - $alpha / 2) * $stdDev / sqrt($size);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction CONFIDENCE()\n\n\n\t/**\n\t * CORREL\n\t *\n\t * Returns covariance, the average of the products of deviations for each data point pair.\n\t *\n\t * @param\tarray of mixed\t\tData Series Y\n\t * @param\tarray of mixed\t\tData Series X\n\t * @return\tfloat\n\t */\n\tpublic static function CORREL($yValues,$xValues=null) {\n\t\tif ((is_null($xValues)) || (!is_array($yValues)) || (!is_array($xValues))) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\tif (!self::_checkTrendArrays($yValues,$xValues)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$yValueCount = count($yValues);\n\t\t$xValueCount = count($xValues);\n\n\t\tif (($yValueCount == 0) || ($yValueCount != $xValueCount)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t} elseif ($yValueCount == 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t}\n\n\t\t$bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues);\n\t\treturn $bestFitLinear->getCorrelation();\n\t}\t//\tfunction CORREL()\n\n\n\t/**\n\t * COUNT\n\t *\n\t * Counts the number of cells that contain numbers within the list of arguments\n\t *\n\t * Excel Function:\n\t *\t\tCOUNT(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tint\n\t */\n\tpublic static function COUNT() {\n\t\t// Return value\n\t\t$returnValue = 0;\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args());\n\t\tforeach ($aArgs as $k => $arg) {\n\t\t\tif ((is_bool($arg)) &&\n\t\t\t\t((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) {\n\t\t\t\t$arg = (integer) $arg;\n\t\t\t}\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t++$returnValue;\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction COUNT()\n\n\n\t/**\n\t * COUNTA\n\t *\n\t * Counts the number of cells that are not empty within the list of arguments\n\t *\n\t * Excel Function:\n\t *\t\tCOUNTA(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tint\n\t */\n\tpublic static function COUNTA() {\n\t\t// Return value\n\t\t$returnValue = 0;\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\tforeach ($aArgs as $arg) {\n\t\t\t// Is it a numeric, boolean or string value?\n\t\t\tif ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {\n\t\t\t\t++$returnValue;\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction COUNTA()\n\n\n\t/**\n\t * COUNTBLANK\n\t *\n\t * Counts the number of empty cells within the list of arguments\n\t *\n\t * Excel Function:\n\t *\t\tCOUNTBLANK(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tint\n\t */\n\tpublic static function COUNTBLANK() {\n\t\t// Return value\n\t\t$returnValue = 0;\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\tforeach ($aArgs as $arg) {\n\t\t\t// Is it a blank cell?\n\t\t\tif ((is_null($arg)) || ((is_string($arg)) && ($arg == ''))) {\n\t\t\t\t++$returnValue;\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction COUNTBLANK()\n\n\n\t/**\n\t * COUNTIF\n\t *\n\t * Counts the number of cells that contain numbers within the list of arguments\n\t *\n\t * Excel Function:\n\t *\t\tCOUNTIF(value1[,value2[, ...]],condition)\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @param\tstring\t\t$condition\t\tThe criteria that defines which cells will be counted.\n\t * @return\tint\n\t */\n\tpublic static function COUNTIF($aArgs,$condition) {\n\t\t// Return value\n\t\t$returnValue = 0;\n\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs);\n\t\t$condition = PHPExcel_Calculation_Functions::_ifCondition($condition);\n\t\t// Loop through arguments\n\t\tforeach ($aArgs as $arg) {\n\t\t\tif (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); }\n\t\t\t$testCondition = '='.$arg.$condition;\n\t\t\tif (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) {\n\t\t\t\t// Is it a value within our criteria\n\t\t\t\t++$returnValue;\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction COUNTIF()\n\n\n\t/**\n\t * COVAR\n\t *\n\t * Returns covariance, the average of the products of deviations for each data point pair.\n\t *\n\t * @param\tarray of mixed\t\tData Series Y\n\t * @param\tarray of mixed\t\tData Series X\n\t * @return\tfloat\n\t */\n\tpublic static function COVAR($yValues,$xValues) {\n\t\tif (!self::_checkTrendArrays($yValues,$xValues)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$yValueCount = count($yValues);\n\t\t$xValueCount = count($xValues);\n\n\t\tif (($yValueCount == 0) || ($yValueCount != $xValueCount)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t} elseif ($yValueCount == 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t}\n\n\t\t$bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues);\n\t\treturn $bestFitLinear->getCovariance();\n\t}\t//\tfunction COVAR()\n\n\n\t/**\n\t * CRITBINOM\n\t *\n\t * Returns the smallest value for which the cumulative binomial distribution is greater\n\t *\t\tthan or equal to a criterion value\n\t *\n\t * See http://support.microsoft.com/kb/828117/ for details of the algorithm used\n\t *\n\t * @param\tfloat\t\t$trials\t\t\tnumber of Bernoulli trials\n\t * @param\tfloat\t\t$probability\tprobability of a success on each trial\n\t * @param\tfloat\t\t$alpha\t\t\tcriterion value\n\t * @return\tint\n\t *\n\t * @todo\tWarning. This implementation differs from the algorithm detailed on the MS\n\t *\t\t\tweb site in that $CumPGuessMinus1 = $CumPGuess - 1 rather than $CumPGuess - $PGuess\n\t *\t\t\tThis eliminates a potential endless loop error, but may have an adverse affect on the\n\t *\t\t\taccuracy of the function (although all my tests have so far returned correct results).\n\t *\n\t */\n\tpublic static function CRITBINOM($trials, $probability, $alpha) {\n\t\t$trials\t\t\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($trials));\n\t\t$probability\t= PHPExcel_Calculation_Functions::flattenSingleValue($probability);\n\t\t$alpha\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($alpha);\n\n\t\tif ((is_numeric($trials)) && (is_numeric($probability)) && (is_numeric($alpha))) {\n\t\t\tif ($trials < 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif (($probability < 0) || ($probability > 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif (($alpha < 0) || ($alpha > 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif ($alpha <= 0.5) {\n\t\t\t\t$t = sqrt(log(1 / ($alpha * $alpha)));\n\t\t\t\t$trialsApprox = 0 - ($t + (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t));\n\t\t\t} else {\n\t\t\t\t$t = sqrt(log(1 / pow(1 - $alpha,2)));\n\t\t\t\t$trialsApprox = $t - (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t);\n\t\t\t}\n\t\t\t$Guess = floor($trials * $probability + $trialsApprox * sqrt($trials * $probability * (1 - $probability)));\n\t\t\tif ($Guess < 0) {\n\t\t\t\t$Guess = 0;\n\t\t\t} elseif ($Guess > $trials) {\n\t\t\t\t$Guess = $trials;\n\t\t\t}\n\n\t\t\t$TotalUnscaledProbability = $UnscaledPGuess = $UnscaledCumPGuess = 0.0;\n\t\t\t$EssentiallyZero = 10e-12;\n\n\t\t\t$m = floor($trials * $probability);\n\t\t\t++$TotalUnscaledProbability;\n\t\t\tif ($m == $Guess) { ++$UnscaledPGuess; }\n\t\t\tif ($m <= $Guess) { ++$UnscaledCumPGuess; }\n\n\t\t\t$PreviousValue = 1;\n\t\t\t$Done = False;\n\t\t\t$k = $m + 1;\n\t\t\twhile ((!$Done) && ($k <= $trials)) {\n\t\t\t\t$CurrentValue = $PreviousValue * ($trials - $k + 1) * $probability / ($k * (1 - $probability));\n\t\t\t\t$TotalUnscaledProbability += $CurrentValue;\n\t\t\t\tif ($k == $Guess) { $UnscaledPGuess += $CurrentValue; }\n\t\t\t\tif ($k <= $Guess) { $UnscaledCumPGuess += $CurrentValue; }\n\t\t\t\tif ($CurrentValue <= $EssentiallyZero) { $Done = True; }\n\t\t\t\t$PreviousValue = $CurrentValue;\n\t\t\t\t++$k;\n\t\t\t}\n\n\t\t\t$PreviousValue = 1;\n\t\t\t$Done = False;\n\t\t\t$k = $m - 1;\n\t\t\twhile ((!$Done) && ($k >= 0)) {\n\t\t\t\t$CurrentValue = $PreviousValue * $k + 1 * (1 - $probability) / (($trials - $k) * $probability);\n\t\t\t\t$TotalUnscaledProbability += $CurrentValue;\n\t\t\t\tif ($k == $Guess) { $UnscaledPGuess += $CurrentValue; }\n\t\t\t\tif ($k <= $Guess) { $UnscaledCumPGuess += $CurrentValue; }\n\t\t\t\tif ($CurrentValue <= $EssentiallyZero) { $Done = True; }\n\t\t\t\t$PreviousValue = $CurrentValue;\n\t\t\t\t--$k;\n\t\t\t}\n\n\t\t\t$PGuess = $UnscaledPGuess / $TotalUnscaledProbability;\n\t\t\t$CumPGuess = $UnscaledCumPGuess / $TotalUnscaledProbability;\n\n//\t\t\t$CumPGuessMinus1 = $CumPGuess - $PGuess;\n\t\t\t$CumPGuessMinus1 = $CumPGuess - 1;\n\n\t\t\twhile (True) {\n\t\t\t\tif (($CumPGuessMinus1 < $alpha) && ($CumPGuess >= $alpha)) {\n\t\t\t\t\treturn $Guess;\n\t\t\t\t} elseif (($CumPGuessMinus1 < $alpha) && ($CumPGuess < $alpha)) {\n\t\t\t\t\t$PGuessPlus1 = $PGuess * ($trials - $Guess) * $probability / $Guess / (1 - $probability);\n\t\t\t\t\t$CumPGuessMinus1 = $CumPGuess;\n\t\t\t\t\t$CumPGuess = $CumPGuess + $PGuessPlus1;\n\t\t\t\t\t$PGuess = $PGuessPlus1;\n\t\t\t\t\t++$Guess;\n\t\t\t\t} elseif (($CumPGuessMinus1 >= $alpha) && ($CumPGuess >= $alpha)) {\n\t\t\t\t\t$PGuessMinus1 = $PGuess * $Guess * (1 - $probability) / ($trials - $Guess + 1) / $probability;\n\t\t\t\t\t$CumPGuess = $CumPGuessMinus1;\n\t\t\t\t\t$CumPGuessMinus1 = $CumPGuessMinus1 - $PGuess;\n\t\t\t\t\t$PGuess = $PGuessMinus1;\n\t\t\t\t\t--$Guess;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction CRITBINOM()\n\n\n\t/**\n\t * DEVSQ\n\t *\n\t * Returns the sum of squares of deviations of data points from their sample mean.\n\t *\n\t * Excel Function:\n\t *\t\tDEVSQ(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function DEVSQ() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args());\n\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t$aMean = self::AVERAGE($aArgs);\n\t\tif ($aMean != PHPExcel_Calculation_Functions::DIV0()) {\n\t\t\t$aCount = -1;\n\t\t\tforeach ($aArgs as $k => $arg) {\n\t\t\t\t// Is it a numeric value?\n\t\t\t\tif ((is_bool($arg)) &&\n\t\t\t\t\t((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) {\n\t\t\t\t\t$arg = (integer) $arg;\n\t\t\t\t}\n\t\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t\tif (is_null($returnValue)) {\n\t\t\t\t\t\t$returnValue = pow(($arg - $aMean),2);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$returnValue += pow(($arg - $aMean),2);\n\t\t\t\t\t}\n\t\t\t\t\t++$aCount;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Return\n\t\t\tif (is_null($returnValue)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t} else {\n\t\t\t\treturn $returnValue;\n\t\t\t}\n\t\t}\n\t\treturn self::NA();\n\t}\t//\tfunction DEVSQ()\n\n\n\t/**\n\t * EXPONDIST\n\t *\n\t *\tReturns the exponential distribution. Use EXPONDIST to model the time between events,\n\t *\t\tsuch as how long an automated bank teller takes to deliver cash. For example, you can\n\t *\t\tuse EXPONDIST to determine the probability that the process takes at most 1 minute.\n\t *\n\t * @param\tfloat\t\t$value\t\t\tValue of the function\n\t * @param\tfloat\t\t$lambda\t\t\tThe parameter value\n\t * @param\tboolean\t\t$cumulative\n\t * @return\tfloat\n\t */\n\tpublic static function EXPONDIST($value, $lambda, $cumulative) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$lambda\t= PHPExcel_Calculation_Functions::flattenSingleValue($lambda);\n\t\t$cumulative\t= PHPExcel_Calculation_Functions::flattenSingleValue($cumulative);\n\n\t\tif ((is_numeric($value)) && (is_numeric($lambda))) {\n\t\t\tif (($value < 0) || ($lambda < 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif ((is_numeric($cumulative)) || (is_bool($cumulative))) {\n\t\t\t\tif ($cumulative) {\n\t\t\t\t\treturn 1 - exp(0-$value*$lambda);\n\t\t\t\t} else {\n\t\t\t\t\treturn $lambda * exp(0-$value*$lambda);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction EXPONDIST()\n\n\n\t/**\n\t * FISHER\n\t *\n\t * Returns the Fisher transformation at x. This transformation produces a function that\n\t *\t\tis normally distributed rather than skewed. Use this function to perform hypothesis\n\t *\t\ttesting on the correlation coefficient.\n\t *\n\t * @param\tfloat\t\t$value\n\t * @return\tfloat\n\t */\n\tpublic static function FISHER($value) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\n\t\tif (is_numeric($value)) {\n\t\t\tif (($value <= -1) || ($value >= 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn 0.5 * log((1+$value)/(1-$value));\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction FISHER()\n\n\n\t/**\n\t * FISHERINV\n\t *\n\t * Returns the inverse of the Fisher transformation. Use this transformation when\n\t *\t\tanalyzing correlations between ranges or arrays of data. If y = FISHER(x), then\n\t *\t\tFISHERINV(y) = x.\n\t *\n\t * @param\tfloat\t\t$value\n\t * @return\tfloat\n\t */\n\tpublic static function FISHERINV($value) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\n\t\tif (is_numeric($value)) {\n\t\t\treturn (exp(2 * $value) - 1) / (exp(2 * $value) + 1);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction FISHERINV()\n\n\n\t/**\n\t * FORECAST\n\t *\n\t * Calculates, or predicts, a future value by using existing values. The predicted value is a y-value for a given x-value.\n\t *\n\t * @param\tfloat\t\t\t\tValue of X for which we want to find Y\n\t * @param\tarray of mixed\t\tData Series Y\n\t * @param\tarray of mixed\t\tData Series X\n\t * @return\tfloat\n\t */\n\tpublic static function FORECAST($xValue,$yValues,$xValues) {\n\t\t$xValue\t= PHPExcel_Calculation_Functions::flattenSingleValue($xValue);\n\t\tif (!is_numeric($xValue)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (!self::_checkTrendArrays($yValues,$xValues)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$yValueCount = count($yValues);\n\t\t$xValueCount = count($xValues);\n\n\t\tif (($yValueCount == 0) || ($yValueCount != $xValueCount)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t} elseif ($yValueCount == 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t}\n\n\t\t$bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues);\n\t\treturn $bestFitLinear->getValueOfYForX($xValue);\n\t}\t//\tfunction FORECAST()\n\n\n\t/**\n\t * GAMMADIST\n\t *\n\t * Returns the gamma distribution.\n\t *\n\t * @param\tfloat\t\t$value\t\t\tValue at which you want to evaluate the distribution\n\t * @param\tfloat\t\t$a\t\t\t\tParameter to the distribution\n\t * @param\tfloat\t\t$b\t\t\t\tParameter to the distribution\n\t * @param\tboolean\t\t$cumulative\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function GAMMADIST($value,$a,$b,$cumulative) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$a\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($a);\n\t\t$b\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($b);\n\n\t\tif ((is_numeric($value)) && (is_numeric($a)) && (is_numeric($b))) {\n\t\t\tif (($value < 0) || ($a <= 0) || ($b <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif ((is_numeric($cumulative)) || (is_bool($cumulative))) {\n\t\t\t\tif ($cumulative) {\n\t\t\t\t\treturn self::_incompleteGamma($a,$value / $b) / self::_gamma($a);\n\t\t\t\t} else {\n\t\t\t\t\treturn (1 / (pow($b,$a) * self::_gamma($a))) * pow($value,$a-1) * exp(0-($value / $b));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction GAMMADIST()\n\n\n\t/**\n\t * GAMMAINV\n\t *\n\t * Returns the inverse of the beta distribution.\n\t *\n\t * @param\tfloat\t\t$probability\tProbability at which you want to evaluate the distribution\n\t * @param\tfloat\t\t$alpha\t\t\tParameter to the distribution\n\t * @param\tfloat\t\t$beta\t\t\tParameter to the distribution\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function GAMMAINV($probability,$alpha,$beta) {\n\t\t$probability\t= PHPExcel_Calculation_Functions::flattenSingleValue($probability);\n\t\t$alpha\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($alpha);\n\t\t$beta\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($beta);\n\n\t\tif ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta))) {\n\t\t\tif (($alpha <= 0) || ($beta <= 0) || ($probability < 0) || ($probability > 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\n\t\t\t$xLo = 0;\n\t\t\t$xHi = $alpha * $beta * 5;\n\n\t\t\t$x = $xNew = 1;\n\t\t\t$error = $pdf = 0;\n\t\t\t$dx\t= 1024;\n\t\t\t$i = 0;\n\n\t\t\twhile ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) {\n\t\t\t\t// Apply Newton-Raphson step\n\t\t\t\t$error = self::GAMMADIST($x, $alpha, $beta, True) - $probability;\n\t\t\t\tif ($error < 0.0) {\n\t\t\t\t\t$xLo = $x;\n\t\t\t\t} else {\n\t\t\t\t\t$xHi = $x;\n\t\t\t\t}\n\t\t\t\t$pdf = self::GAMMADIST($x, $alpha, $beta, False);\n\t\t\t\t// Avoid division by zero\n\t\t\t\tif ($pdf != 0.0) {\n\t\t\t\t\t$dx = $error / $pdf;\n\t\t\t\t\t$xNew = $x - $dx;\n\t\t\t\t}\n\t\t\t\t// If the NR fails to converge (which for example may be the\n\t\t\t\t// case if the initial guess is too rough) we apply a bisection\n\t\t\t\t// step to determine a more narrow interval around the root.\n\t\t\t\tif (($xNew < $xLo) || ($xNew > $xHi) || ($pdf == 0.0)) {\n\t\t\t\t\t$xNew = ($xLo + $xHi) / 2;\n\t\t\t\t\t$dx = $xNew - $x;\n\t\t\t\t}\n\t\t\t\t$x = $xNew;\n\t\t\t}\n\t\t\tif ($i == MAX_ITERATIONS) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t\t}\n\t\t\treturn $x;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction GAMMAINV()\n\n\n\t/**\n\t * GAMMALN\n\t *\n\t * Returns the natural logarithm of the gamma function.\n\t *\n\t * @param\tfloat\t\t$value\n\t * @return\tfloat\n\t */\n\tpublic static function GAMMALN($value) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\n\t\tif (is_numeric($value)) {\n\t\t\tif ($value <= 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn log(self::_gamma($value));\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction GAMMALN()\n\n\n\t/**\n\t * GEOMEAN\n\t *\n\t * Returns the geometric mean of an array or range of positive data. For example, you\n\t *\t\tcan use GEOMEAN to calculate average growth rate given compound interest with\n\t *\t\tvariable rates.\n\t *\n\t * Excel Function:\n\t *\t\tGEOMEAN(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function GEOMEAN() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\n\t\t$aMean = PHPExcel_Calculation_MathTrig::PRODUCT($aArgs);\n\t\tif (is_numeric($aMean) && ($aMean > 0)) {\n\t\t\t$aCount = self::COUNT($aArgs) ;\n\t\t\tif (self::MIN($aArgs) > 0) {\n\t\t\t\treturn pow($aMean, (1 / $aCount));\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t}\t//\tGEOMEAN()\n\n\n\t/**\n\t * GROWTH\n\t *\n\t * Returns values along a predicted emponential trend\n\t *\n\t * @param\tarray of mixed\t\tData Series Y\n\t * @param\tarray of mixed\t\tData Series X\n\t * @param\tarray of mixed\t\tValues of X for which we want to find Y\n\t * @param\tboolean\t\t\t\tA logical value specifying whether to force the intersect to equal 0.\n\t * @return\tarray of float\n\t */\n\tpublic static function GROWTH($yValues,$xValues=array(),$newValues=array(),$const=True) {\n\t\t$yValues = PHPExcel_Calculation_Functions::flattenArray($yValues);\n\t\t$xValues = PHPExcel_Calculation_Functions::flattenArray($xValues);\n\t\t$newValues = PHPExcel_Calculation_Functions::flattenArray($newValues);\n\t\t$const\t= (is_null($const))\t? True :\t(boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const);\n\n\t\t$bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL,$yValues,$xValues,$const);\n\t\tif (empty($newValues)) {\n\t\t\t$newValues = $bestFitExponential->getXValues();\n\t\t}\n\n\t\t$returnArray = array();\n\t\tforeach($newValues as $xValue) {\n\t\t\t$returnArray[0][] = $bestFitExponential->getValueOfYForX($xValue);\n\t\t}\n\n\t\treturn $returnArray;\n\t}\t//\tfunction GROWTH()\n\n\n\t/**\n\t * HARMEAN\n\t *\n\t * Returns the harmonic mean of a data set. The harmonic mean is the reciprocal of the\n\t *\t\tarithmetic mean of reciprocals.\n\t *\n\t * Excel Function:\n\t *\t\tHARMEAN(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function HARMEAN() {\n\t\t// Return value\n\t\t$returnValue = PHPExcel_Calculation_Functions::NA();\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\tif (self::MIN($aArgs) < 0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\t$aCount = 0;\n\t\tforeach ($aArgs as $arg) {\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\tif ($arg <= 0) {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t\t}\n\t\t\t\tif (is_null($returnValue)) {\n\t\t\t\t\t$returnValue = (1 / $arg);\n\t\t\t\t} else {\n\t\t\t\t\t$returnValue += (1 / $arg);\n\t\t\t\t}\n\t\t\t\t++$aCount;\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif ($aCount > 0) {\n\t\t\treturn 1 / ($returnValue / $aCount);\n\t\t} else {\n\t\t\treturn $returnValue;\n\t\t}\n\t}\t//\tfunction HARMEAN()\n\n\n\t/**\n\t * HYPGEOMDIST\n\t *\n\t * Returns the hypergeometric distribution. HYPGEOMDIST returns the probability of a given number of\n\t * sample successes, given the sample size, population successes, and population size.\n\t *\n\t * @param\tfloat\t\t$sampleSuccesses\t\tNumber of successes in the sample\n\t * @param\tfloat\t\t$sampleNumber\t\t\tSize of the sample\n\t * @param\tfloat\t\t$populationSuccesses\tNumber of successes in the population\n\t * @param\tfloat\t\t$populationNumber\t\tPopulation size\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function HYPGEOMDIST($sampleSuccesses, $sampleNumber, $populationSuccesses, $populationNumber) {\n\t\t$sampleSuccesses\t\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleSuccesses));\n\t\t$sampleNumber\t\t\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($sampleNumber));\n\t\t$populationSuccesses\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationSuccesses));\n\t\t$populationNumber\t\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($populationNumber));\n\n\t\tif ((is_numeric($sampleSuccesses)) && (is_numeric($sampleNumber)) && (is_numeric($populationSuccesses)) && (is_numeric($populationNumber))) {\n\t\t\tif (($sampleSuccesses < 0) || ($sampleSuccesses > $sampleNumber) || ($sampleSuccesses > $populationSuccesses)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif (($sampleNumber <= 0) || ($sampleNumber > $populationNumber)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif (($populationSuccesses <= 0) || ($populationSuccesses > $populationNumber)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn PHPExcel_Calculation_MathTrig::COMBIN($populationSuccesses,$sampleSuccesses) *\n\t\t\t\t   PHPExcel_Calculation_MathTrig::COMBIN($populationNumber - $populationSuccesses,$sampleNumber - $sampleSuccesses) /\n\t\t\t\t   PHPExcel_Calculation_MathTrig::COMBIN($populationNumber,$sampleNumber);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction HYPGEOMDIST()\n\n\n\t/**\n\t * INTERCEPT\n\t *\n\t * Calculates the point at which a line will intersect the y-axis by using existing x-values and y-values.\n\t *\n\t * @param\tarray of mixed\t\tData Series Y\n\t * @param\tarray of mixed\t\tData Series X\n\t * @return\tfloat\n\t */\n\tpublic static function INTERCEPT($yValues,$xValues) {\n\t\tif (!self::_checkTrendArrays($yValues,$xValues)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$yValueCount = count($yValues);\n\t\t$xValueCount = count($xValues);\n\n\t\tif (($yValueCount == 0) || ($yValueCount != $xValueCount)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t} elseif ($yValueCount == 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t}\n\n\t\t$bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues);\n\t\treturn $bestFitLinear->getIntersect();\n\t}\t//\tfunction INTERCEPT()\n\n\n\t/**\n\t * KURT\n\t *\n\t * Returns the kurtosis of a data set. Kurtosis characterizes the relative peakedness\n\t * or flatness of a distribution compared with the normal distribution. Positive\n\t * kurtosis indicates a relatively peaked distribution. Negative kurtosis indicates a\n\t * relatively flat distribution.\n\t *\n\t * @param\tarray\tData Series\n\t * @return\tfloat\n\t */\n\tpublic static function KURT() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args());\n\t\t$mean = self::AVERAGE($aArgs);\n\t\t$stdDev = self::STDEV($aArgs);\n\n\t\tif ($stdDev > 0) {\n\t\t\t$count = $summer = 0;\n\t\t\t// Loop through arguments\n\t\t\tforeach ($aArgs as $k => $arg) {\n\t\t\t\tif ((is_bool($arg)) &&\n\t\t\t\t\t(!PHPExcel_Calculation_Functions::isMatrixValue($k))) {\n\t\t\t\t} else {\n\t\t\t\t\t// Is it a numeric value?\n\t\t\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t\t\t$summer += pow((($arg - $mean) / $stdDev),4) ;\n\t\t\t\t\t\t++$count;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Return\n\t\t\tif ($count > 3) {\n\t\t\t\treturn $summer * ($count * ($count+1) / (($count-1) * ($count-2) * ($count-3))) - (3 * pow($count-1,2) / (($count-2) * ($count-3)));\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t}\t//\tfunction KURT()\n\n\n\t/**\n\t * LARGE\n\t *\n\t * Returns the nth largest value in a data set. You can use this function to\n\t *\t\tselect a value based on its relative standing.\n\t *\n\t * Excel Function:\n\t *\t\tLARGE(value1[,value2[, ...]],entry)\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @param\tint\t\t\t$entry\t\t\tPosition (ordered from the largest) in the array or range of data to return\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function LARGE() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\n\t\t// Calculate\n\t\t$entry = floor(array_pop($aArgs));\n\n\t\tif ((is_numeric($entry)) && (!is_string($entry))) {\n\t\t\t$mArgs = array();\n\t\t\tforeach ($aArgs as $arg) {\n\t\t\t\t// Is it a numeric value?\n\t\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t\t$mArgs[] = $arg;\n\t\t\t\t}\n\t\t\t}\n\t\t\t$count = self::COUNT($mArgs);\n\t\t\t$entry = floor(--$entry);\n\t\t\tif (($entry < 0) || ($entry >= $count) || ($count == 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\trsort($mArgs);\n\t\t\treturn $mArgs[$entry];\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction LARGE()\n\n\n\t/**\n\t * LINEST\n\t *\n\t * Calculates the statistics for a line by using the \"least squares\" method to calculate a straight line that best fits your data,\n\t *\t\tand then returns an array that describes the line.\n\t *\n\t * @param\tarray of mixed\t\tData Series Y\n\t * @param\tarray of mixed\t\tData Series X\n\t * @param\tboolean\t\t\t\tA logical value specifying whether to force the intersect to equal 0.\n\t * @param\tboolean\t\t\t\tA logical value specifying whether to return additional regression statistics.\n\t * @return\tarray\n\t */\n\tpublic static function LINEST($yValues, $xValues = NULL, $const = TRUE, $stats = FALSE) {\n\t\t$const\t= (is_null($const))\t? TRUE :\t(boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const);\n\t\t$stats\t= (is_null($stats))\t? FALSE :\t(boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats);\n\t\tif (is_null($xValues)) $xValues = range(1,count(PHPExcel_Calculation_Functions::flattenArray($yValues)));\n\n\t\tif (!self::_checkTrendArrays($yValues,$xValues)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$yValueCount = count($yValues);\n\t\t$xValueCount = count($xValues);\n\n\n\t\tif (($yValueCount == 0) || ($yValueCount != $xValueCount)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t} elseif ($yValueCount == 1) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t$bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues,$const);\n\t\tif ($stats) {\n\t\t\treturn array( array( $bestFitLinear->getSlope(),\n\t\t\t\t\t\t \t\t $bestFitLinear->getSlopeSE(),\n\t\t\t\t\t\t \t\t $bestFitLinear->getGoodnessOfFit(),\n\t\t\t\t\t\t \t\t $bestFitLinear->getF(),\n\t\t\t\t\t\t \t\t $bestFitLinear->getSSRegression(),\n\t\t\t\t\t\t\t   ),\n\t\t\t\t\t\t  array( $bestFitLinear->getIntersect(),\n\t\t\t\t\t\t\t\t $bestFitLinear->getIntersectSE(),\n\t\t\t\t\t\t\t\t $bestFitLinear->getStdevOfResiduals(),\n\t\t\t\t\t\t\t\t $bestFitLinear->getDFResiduals(),\n\t\t\t\t\t\t\t\t $bestFitLinear->getSSResiduals()\n\t\t\t\t\t\t\t   )\n\t\t\t\t\t\t);\n\t\t} else {\n\t\t\treturn array( $bestFitLinear->getSlope(),\n\t\t\t\t\t\t  $bestFitLinear->getIntersect()\n\t\t\t\t\t\t);\n\t\t}\n\t}\t//\tfunction LINEST()\n\n\n\t/**\n\t * LOGEST\n\t *\n\t * Calculates an exponential curve that best fits the X and Y data series,\n\t *\t\tand then returns an array that describes the line.\n\t *\n\t * @param\tarray of mixed\t\tData Series Y\n\t * @param\tarray of mixed\t\tData Series X\n\t * @param\tboolean\t\t\t\tA logical value specifying whether to force the intersect to equal 0.\n\t * @param\tboolean\t\t\t\tA logical value specifying whether to return additional regression statistics.\n\t * @return\tarray\n\t */\n\tpublic static function LOGEST($yValues,$xValues=null,$const=True,$stats=False) {\n\t\t$const\t= (is_null($const))\t? True :\t(boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const);\n\t\t$stats\t= (is_null($stats))\t? False :\t(boolean) PHPExcel_Calculation_Functions::flattenSingleValue($stats);\n\t\tif (is_null($xValues)) $xValues = range(1,count(PHPExcel_Calculation_Functions::flattenArray($yValues)));\n\n\t\tif (!self::_checkTrendArrays($yValues,$xValues)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$yValueCount = count($yValues);\n\t\t$xValueCount = count($xValues);\n\n\t\tforeach($yValues as $value) {\n\t\t\tif ($value <= 0.0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t}\n\n\n\t\tif (($yValueCount == 0) || ($yValueCount != $xValueCount)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t} elseif ($yValueCount == 1) {\n\t\t\treturn 1;\n\t\t}\n\n\t\t$bestFitExponential = trendClass::calculate(trendClass::TREND_EXPONENTIAL,$yValues,$xValues,$const);\n\t\tif ($stats) {\n\t\t\treturn array( array( $bestFitExponential->getSlope(),\n\t\t\t\t\t\t \t\t $bestFitExponential->getSlopeSE(),\n\t\t\t\t\t\t \t\t $bestFitExponential->getGoodnessOfFit(),\n\t\t\t\t\t\t \t\t $bestFitExponential->getF(),\n\t\t\t\t\t\t \t\t $bestFitExponential->getSSRegression(),\n\t\t\t\t\t\t\t   ),\n\t\t\t\t\t\t  array( $bestFitExponential->getIntersect(),\n\t\t\t\t\t\t\t\t $bestFitExponential->getIntersectSE(),\n\t\t\t\t\t\t\t\t $bestFitExponential->getStdevOfResiduals(),\n\t\t\t\t\t\t\t\t $bestFitExponential->getDFResiduals(),\n\t\t\t\t\t\t\t\t $bestFitExponential->getSSResiduals()\n\t\t\t\t\t\t\t   )\n\t\t\t\t\t\t);\n\t\t} else {\n\t\t\treturn array( $bestFitExponential->getSlope(),\n\t\t\t\t\t\t  $bestFitExponential->getIntersect()\n\t\t\t\t\t\t);\n\t\t}\n\t}\t//\tfunction LOGEST()\n\n\n\t/**\n\t * LOGINV\n\t *\n\t * Returns the inverse of the normal cumulative distribution\n\t *\n\t * @param\tfloat\t\t$probability\n\t * @param\tfloat\t\t$mean\n\t * @param\tfloat\t\t$stdDev\n\t * @return\tfloat\n\t *\n\t * @todo\tTry implementing P J Acklam's refinement algorithm for greater\n\t *\t\t\taccuracy if I can get my head round the mathematics\n\t *\t\t\t(as described at) http://home.online.no/~pjacklam/notes/invnorm/\n\t */\n\tpublic static function LOGINV($probability, $mean, $stdDev) {\n\t\t$probability\t= PHPExcel_Calculation_Functions::flattenSingleValue($probability);\n\t\t$mean\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($mean);\n\t\t$stdDev\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($stdDev);\n\n\t\tif ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) {\n\t\t\tif (($probability < 0) || ($probability > 1) || ($stdDev <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn exp($mean + $stdDev * self::NORMSINV($probability));\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction LOGINV()\n\n\n\t/**\n\t * LOGNORMDIST\n\t *\n\t * Returns the cumulative lognormal distribution of x, where ln(x) is normally distributed\n\t * with parameters mean and standard_dev.\n\t *\n\t * @param\tfloat\t\t$value\n\t * @param\tfloat\t\t$mean\n\t * @param\tfloat\t\t$stdDev\n\t * @return\tfloat\n\t */\n\tpublic static function LOGNORMDIST($value, $mean, $stdDev) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$mean\t= PHPExcel_Calculation_Functions::flattenSingleValue($mean);\n\t\t$stdDev\t= PHPExcel_Calculation_Functions::flattenSingleValue($stdDev);\n\n\t\tif ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) {\n\t\t\tif (($value <= 0) || ($stdDev <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn self::NORMSDIST((log($value) - $mean) / $stdDev);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction LOGNORMDIST()\n\n\n\t/**\n\t * MAX\n\t *\n\t * MAX returns the value of the element of the values passed that has the highest value,\n\t *\t\twith negative numbers considered smaller than positive numbers.\n\t *\n\t * Excel Function:\n\t *\t\tMAX(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function MAX() {\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\tforeach ($aArgs as $arg) {\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\tif ((is_null($returnValue)) || ($arg > $returnValue)) {\n\t\t\t\t\t$returnValue = $arg;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif(is_null($returnValue)) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn $returnValue;\n\t}\t//\tfunction MAX()\n\n\n\t/**\n\t * MAXA\n\t *\n\t * Returns the greatest value in a list of arguments, including numbers, text, and logical values\n\t *\n\t * Excel Function:\n\t *\t\tMAXA(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function MAXA() {\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\tforeach ($aArgs as $arg) {\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {\n\t\t\t\tif (is_bool($arg)) {\n\t\t\t\t\t$arg = (integer) $arg;\n\t\t\t\t} elseif (is_string($arg)) {\n\t\t\t\t\t$arg = 0;\n\t\t\t\t}\n\t\t\t\tif ((is_null($returnValue)) || ($arg > $returnValue)) {\n\t\t\t\t\t$returnValue = $arg;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif(is_null($returnValue)) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn $returnValue;\n\t}\t//\tfunction MAXA()\n\n\n\t/**\n\t * MAXIF\n\t *\n\t * Counts the maximum value within a range of cells that contain numbers within the list of arguments\n\t *\n\t * Excel Function:\n\t *\t\tMAXIF(value1[,value2[, ...]],condition)\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @param\tstring\t\t$condition\t\tThe criteria that defines which cells will be checked.\n\t * @return\tfloat\n\t */\n\tpublic static function MAXIF($aArgs,$condition,$sumArgs = array()) {\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs);\n\t\t$sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs);\n\t\tif (empty($sumArgs)) {\n\t\t\t$sumArgs = $aArgs;\n\t\t}\n\t\t$condition = PHPExcel_Calculation_Functions::_ifCondition($condition);\n\t\t// Loop through arguments\n\t\tforeach ($aArgs as $key => $arg) {\n\t\t\tif (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); }\n\t\t\t$testCondition = '='.$arg.$condition;\n\t\t\tif (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) {\n\t\t\t\tif ((is_null($returnValue)) || ($arg > $returnValue)) {\n\t\t\t\t\t$returnValue = $arg;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction MAXIF()\n\n\n\t/**\n\t * MEDIAN\n\t *\n\t * Returns the median of the given numbers. The median is the number in the middle of a set of numbers.\n\t *\n\t * Excel Function:\n\t *\t\tMEDIAN(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function MEDIAN() {\n\t\t// Return value\n\t\t$returnValue = PHPExcel_Calculation_Functions::NaN();\n\n\t\t$mArgs = array();\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\tforeach ($aArgs as $arg) {\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t$mArgs[] = $arg;\n\t\t\t}\n\t\t}\n\n\t\t$mValueCount = count($mArgs);\n\t\tif ($mValueCount > 0) {\n\t\t\tsort($mArgs,SORT_NUMERIC);\n\t\t\t$mValueCount = $mValueCount / 2;\n\t\t\tif ($mValueCount == floor($mValueCount)) {\n\t\t\t\t$returnValue = ($mArgs[$mValueCount--] + $mArgs[$mValueCount]) / 2;\n\t\t\t} else {\n\t\t\t\t$mValueCount == floor($mValueCount);\n\t\t\t\t$returnValue = $mArgs[$mValueCount];\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction MEDIAN()\n\n\n\t/**\n\t * MIN\n\t *\n\t * MIN returns the value of the element of the values passed that has the smallest value,\n\t *\t\twith negative numbers considered smaller than positive numbers.\n\t *\n\t * Excel Function:\n\t *\t\tMIN(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function MIN() {\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\tforeach ($aArgs as $arg) {\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\tif ((is_null($returnValue)) || ($arg < $returnValue)) {\n\t\t\t\t\t$returnValue = $arg;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif(is_null($returnValue)) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn $returnValue;\n\t}\t//\tfunction MIN()\n\n\n\t/**\n\t * MINA\n\t *\n\t * Returns the smallest value in a list of arguments, including numbers, text, and logical values\n\t *\n\t * Excel Function:\n\t *\t\tMINA(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function MINA() {\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\tforeach ($aArgs as $arg) {\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {\n\t\t\t\tif (is_bool($arg)) {\n\t\t\t\t\t$arg = (integer) $arg;\n\t\t\t\t} elseif (is_string($arg)) {\n\t\t\t\t\t$arg = 0;\n\t\t\t\t}\n\t\t\t\tif ((is_null($returnValue)) || ($arg < $returnValue)) {\n\t\t\t\t\t$returnValue = $arg;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif(is_null($returnValue)) {\n\t\t\treturn 0;\n\t\t}\n\t\treturn $returnValue;\n\t}\t//\tfunction MINA()\n\n\n\t/**\n\t * MINIF\n\t *\n\t * Returns the minimum value within a range of cells that contain numbers within the list of arguments\n\t *\n\t * Excel Function:\n\t *\t\tMINIF(value1[,value2[, ...]],condition)\n\t *\n\t * @access\tpublic\n\t * @category Mathematical and Trigonometric Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @param\tstring\t\t$condition\t\tThe criteria that defines which cells will be checked.\n\t * @return\tfloat\n\t */\n\tpublic static function MINIF($aArgs,$condition,$sumArgs = array()) {\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray($aArgs);\n\t\t$sumArgs = PHPExcel_Calculation_Functions::flattenArray($sumArgs);\n\t\tif (empty($sumArgs)) {\n\t\t\t$sumArgs = $aArgs;\n\t\t}\n\t\t$condition = PHPExcel_Calculation_Functions::_ifCondition($condition);\n\t\t// Loop through arguments\n\t\tforeach ($aArgs as $key => $arg) {\n\t\t\tif (!is_numeric($arg)) { $arg = PHPExcel_Calculation::_wrapResult(strtoupper($arg)); }\n\t\t\t$testCondition = '='.$arg.$condition;\n\t\t\tif (PHPExcel_Calculation::getInstance()->_calculateFormulaValue($testCondition)) {\n\t\t\t\tif ((is_null($returnValue)) || ($arg < $returnValue)) {\n\t\t\t\t\t$returnValue = $arg;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction MINIF()\n\n\n\t//\n\t//\tSpecial variant of array_count_values that isn't limited to strings and integers,\n\t//\t\tbut can work with floating point numbers as values\n\t//\n\tprivate static function _modeCalc($data) {\n\t\t$frequencyArray = array();\n\t\tforeach($data as $datum) {\n\t\t\t$found = False;\n\t\t\tforeach($frequencyArray as $key => $value) {\n\t\t\t\tif ((string) $value['value'] == (string) $datum) {\n\t\t\t\t\t++$frequencyArray[$key]['frequency'];\n\t\t\t\t\t$found = True;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (!$found) {\n\t\t\t\t$frequencyArray[] = array('value'\t\t=> $datum,\n\t\t\t\t\t\t\t\t\t\t  'frequency'\t=>\t1 );\n\t\t\t}\n\t\t}\n\n\t\tforeach($frequencyArray as $key => $value) {\n\t\t\t$frequencyList[$key] = $value['frequency'];\n\t\t\t$valueList[$key] = $value['value'];\n\t\t}\n\t\tarray_multisort($frequencyList, SORT_DESC, $valueList, SORT_ASC, SORT_NUMERIC, $frequencyArray);\n\n\t\tif ($frequencyArray[0]['frequency'] == 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t}\n\t\treturn $frequencyArray[0]['value'];\n\t}\t//\tfunction _modeCalc()\n\n\n\t/**\n\t * MODE\n\t *\n\t * Returns the most frequently occurring, or repetitive, value in an array or range of data\n\t *\n\t * Excel Function:\n\t *\t\tMODE(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function MODE() {\n\t\t// Return value\n\t\t$returnValue = PHPExcel_Calculation_Functions::NA();\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\n\t\t$mArgs = array();\n\t\tforeach ($aArgs as $arg) {\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t$mArgs[] = $arg;\n\t\t\t}\n\t\t}\n\n\t\tif (!empty($mArgs)) {\n\t\t\treturn self::_modeCalc($mArgs);\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction MODE()\n\n\n\t/**\n\t * NEGBINOMDIST\n\t *\n\t * Returns the negative binomial distribution. NEGBINOMDIST returns the probability that\n\t *\t\tthere will be number_f failures before the number_s-th success, when the constant\n\t *\t\tprobability of a success is probability_s. This function is similar to the binomial\n\t *\t\tdistribution, except that the number of successes is fixed, and the number of trials is\n\t *\t\tvariable. Like the binomial, trials are assumed to be independent.\n\t *\n\t * @param\tfloat\t\t$failures\t\tNumber of Failures\n\t * @param\tfloat\t\t$successes\t\tThreshold number of Successes\n\t * @param\tfloat\t\t$probability\tProbability of success on each trial\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function NEGBINOMDIST($failures, $successes, $probability) {\n\t\t$failures\t\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($failures));\n\t\t$successes\t\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($successes));\n\t\t$probability\t= PHPExcel_Calculation_Functions::flattenSingleValue($probability);\n\n\t\tif ((is_numeric($failures)) && (is_numeric($successes)) && (is_numeric($probability))) {\n\t\t\tif (($failures < 0) || ($successes < 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif (($probability < 0) || ($probability > 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_GNUMERIC) {\n\t\t\t\tif (($failures + $successes - 1) <= 0) {\n\t\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn (PHPExcel_Calculation_MathTrig::COMBIN($failures + $successes - 1,$successes - 1)) * (pow($probability,$successes)) * (pow(1 - $probability,$failures)) ;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction NEGBINOMDIST()\n\n\n\t/**\n\t * NORMDIST\n\t *\n\t * Returns the normal distribution for the specified mean and standard deviation. This\n\t * function has a very wide range of applications in statistics, including hypothesis\n\t * testing.\n\t *\n\t * @param\tfloat\t\t$value\n\t * @param\tfloat\t\t$mean\t\tMean Value\n\t * @param\tfloat\t\t$stdDev\t\tStandard Deviation\n\t * @param\tboolean\t\t$cumulative\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function NORMDIST($value, $mean, $stdDev, $cumulative) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$mean\t= PHPExcel_Calculation_Functions::flattenSingleValue($mean);\n\t\t$stdDev\t= PHPExcel_Calculation_Functions::flattenSingleValue($stdDev);\n\n\t\tif ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) {\n\t\t\tif ($stdDev < 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif ((is_numeric($cumulative)) || (is_bool($cumulative))) {\n\t\t\t\tif ($cumulative) {\n\t\t\t\t\treturn 0.5 * (1 + PHPExcel_Calculation_Engineering::_erfVal(($value - $mean) / ($stdDev * sqrt(2))));\n\t\t\t\t} else {\n\t\t\t\t\treturn (1 / (SQRT2PI * $stdDev)) * exp(0 - (pow($value - $mean,2) / (2 * ($stdDev * $stdDev))));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction NORMDIST()\n\n\n\t/**\n\t * NORMINV\n\t *\n\t * Returns the inverse of the normal cumulative distribution for the specified mean and standard deviation.\n\t *\n\t * @param\tfloat\t\t$value\n\t * @param\tfloat\t\t$mean\t\tMean Value\n\t * @param\tfloat\t\t$stdDev\t\tStandard Deviation\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function NORMINV($probability,$mean,$stdDev) {\n\t\t$probability\t= PHPExcel_Calculation_Functions::flattenSingleValue($probability);\n\t\t$mean\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($mean);\n\t\t$stdDev\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($stdDev);\n\n\t\tif ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) {\n\t\t\tif (($probability < 0) || ($probability > 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif ($stdDev < 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn (self::_inverse_ncdf($probability) * $stdDev) + $mean;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction NORMINV()\n\n\n\t/**\n\t * NORMSDIST\n\t *\n\t * Returns the standard normal cumulative distribution function. The distribution has\n\t * a mean of 0 (zero) and a standard deviation of one. Use this function in place of a\n\t * table of standard normal curve areas.\n\t *\n\t * @param\tfloat\t\t$value\n\t * @return\tfloat\n\t */\n\tpublic static function NORMSDIST($value) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\n\t\treturn self::NORMDIST($value, 0, 1, True);\n\t}\t//\tfunction NORMSDIST()\n\n\n\t/**\n\t * NORMSINV\n\t *\n\t * Returns the inverse of the standard normal cumulative distribution\n\t *\n\t * @param\tfloat\t\t$value\n\t * @return\tfloat\n\t */\n\tpublic static function NORMSINV($value) {\n\t\treturn self::NORMINV($value, 0, 1);\n\t}\t//\tfunction NORMSINV()\n\n\n\t/**\n\t * PERCENTILE\n\t *\n\t * Returns the nth percentile of values in a range..\n\t *\n\t * Excel Function:\n\t *\t\tPERCENTILE(value1[,value2[, ...]],entry)\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @param\tfloat\t\t$entry\t\t\tPercentile value in the range 0..1, inclusive.\n\t * @return\tfloat\n\t */\n\tpublic static function PERCENTILE() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\n\t\t// Calculate\n\t\t$entry = array_pop($aArgs);\n\n\t\tif ((is_numeric($entry)) && (!is_string($entry))) {\n\t\t\tif (($entry < 0) || ($entry > 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$mArgs = array();\n\t\t\tforeach ($aArgs as $arg) {\n\t\t\t\t// Is it a numeric value?\n\t\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t\t$mArgs[] = $arg;\n\t\t\t\t}\n\t\t\t}\n\t\t\t$mValueCount = count($mArgs);\n\t\t\tif ($mValueCount > 0) {\n\t\t\t\tsort($mArgs);\n\t\t\t\t$count = self::COUNT($mArgs);\n\t\t\t\t$index = $entry * ($count-1);\n\t\t\t\t$iBase = floor($index);\n\t\t\t\tif ($index == $iBase) {\n\t\t\t\t\treturn $mArgs[$index];\n\t\t\t\t} else {\n\t\t\t\t\t$iNext = $iBase + 1;\n\t\t\t\t\t$iProportion = $index - $iBase;\n\t\t\t\t\treturn $mArgs[$iBase] + (($mArgs[$iNext] - $mArgs[$iBase]) * $iProportion) ;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction PERCENTILE()\n\n\n\t/**\n\t * PERCENTRANK\n\t *\n\t * Returns the rank of a value in a data set as a percentage of the data set.\n\t *\n\t * @param\tarray of number\t\tAn array of, or a reference to, a list of numbers.\n\t * @param\tnumber\t\t\t\tThe number whose rank you want to find.\n\t * @param\tnumber\t\t\t\tThe number of significant digits for the returned percentage value.\n\t * @return\tfloat\n\t */\n\tpublic static function PERCENTRANK($valueSet,$value,$significance=3) {\n\t\t$valueSet\t= PHPExcel_Calculation_Functions::flattenArray($valueSet);\n\t\t$value\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$significance\t= (is_null($significance))\t? 3 :\t(integer) PHPExcel_Calculation_Functions::flattenSingleValue($significance);\n\n\t\tforeach($valueSet as $key => $valueEntry) {\n\t\t\tif (!is_numeric($valueEntry)) {\n\t\t\t\tunset($valueSet[$key]);\n\t\t\t}\n\t\t}\n\t\tsort($valueSet,SORT_NUMERIC);\n\t\t$valueCount = count($valueSet);\n\t\tif ($valueCount == 0) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\t$valueAdjustor = $valueCount - 1;\n\t\tif (($value < $valueSet[0]) || ($value > $valueSet[$valueAdjustor])) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t}\n\n\t\t$pos = array_search($value,$valueSet);\n\t\tif ($pos === False) {\n\t\t\t$pos = 0;\n\t\t\t$testValue = $valueSet[0];\n\t\t\twhile ($testValue < $value) {\n\t\t\t\t$testValue = $valueSet[++$pos];\n\t\t\t}\n\t\t\t--$pos;\n\t\t\t$pos += (($value - $valueSet[$pos]) / ($testValue - $valueSet[$pos]));\n\t\t}\n\n\t\treturn round($pos / $valueAdjustor,$significance);\n\t}\t//\tfunction PERCENTRANK()\n\n\n\t/**\n\t * PERMUT\n\t *\n\t * Returns the number of permutations for a given number of objects that can be\n\t *\t\tselected from number objects. A permutation is any set or subset of objects or\n\t *\t\tevents where internal order is significant. Permutations are different from\n\t *\t\tcombinations, for which the internal order is not significant. Use this function\n\t *\t\tfor lottery-style probability calculations.\n\t *\n\t * @param\tint\t\t$numObjs\tNumber of different objects\n\t * @param\tint\t\t$numInSet\tNumber of objects in each permutation\n\t * @return\tint\t\tNumber of permutations\n\t */\n\tpublic static function PERMUT($numObjs,$numInSet) {\n\t\t$numObjs\t= PHPExcel_Calculation_Functions::flattenSingleValue($numObjs);\n\t\t$numInSet\t= PHPExcel_Calculation_Functions::flattenSingleValue($numInSet);\n\n\t\tif ((is_numeric($numObjs)) && (is_numeric($numInSet))) {\n\t\t\t$numInSet = floor($numInSet);\n\t\t\tif ($numObjs < $numInSet) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn round(PHPExcel_Calculation_MathTrig::FACT($numObjs) / PHPExcel_Calculation_MathTrig::FACT($numObjs - $numInSet));\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction PERMUT()\n\n\n\t/**\n\t * POISSON\n\t *\n\t * Returns the Poisson distribution. A common application of the Poisson distribution\n\t * is predicting the number of events over a specific time, such as the number of\n\t * cars arriving at a toll plaza in 1 minute.\n\t *\n\t * @param\tfloat\t\t$value\n\t * @param\tfloat\t\t$mean\t\tMean Value\n\t * @param\tboolean\t\t$cumulative\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function POISSON($value, $mean, $cumulative) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$mean\t= PHPExcel_Calculation_Functions::flattenSingleValue($mean);\n\n\t\tif ((is_numeric($value)) && (is_numeric($mean))) {\n\t\t\tif (($value < 0) || ($mean <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif ((is_numeric($cumulative)) || (is_bool($cumulative))) {\n\t\t\t\tif ($cumulative) {\n\t\t\t\t\t$summer = 0;\n\t\t\t\t\tfor ($i = 0; $i <= floor($value); ++$i) {\n\t\t\t\t\t\t$summer += pow($mean,$i) / PHPExcel_Calculation_MathTrig::FACT($i);\n\t\t\t\t\t}\n\t\t\t\t\treturn exp(0-$mean) * $summer;\n\t\t\t\t} else {\n\t\t\t\t\treturn (exp(0-$mean) * pow($mean,$value)) / PHPExcel_Calculation_MathTrig::FACT($value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction POISSON()\n\n\n\t/**\n\t * QUARTILE\n\t *\n\t * Returns the quartile of a data set.\n\t *\n\t * Excel Function:\n\t *\t\tQUARTILE(value1[,value2[, ...]],entry)\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @param\tint\t\t\t$entry\t\t\tQuartile value in the range 1..3, inclusive.\n\t * @return\tfloat\n\t */\n\tpublic static function QUARTILE() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\n\t\t// Calculate\n\t\t$entry = floor(array_pop($aArgs));\n\n\t\tif ((is_numeric($entry)) && (!is_string($entry))) {\n\t\t\t$entry /= 4;\n\t\t\tif (($entry < 0) || ($entry > 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn self::PERCENTILE($aArgs,$entry);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction QUARTILE()\n\n\n\t/**\n\t * RANK\n\t *\n\t * Returns the rank of a number in a list of numbers.\n\t *\n\t * @param\tnumber\t\t\t\tThe number whose rank you want to find.\n\t * @param\tarray of number\t\tAn array of, or a reference to, a list of numbers.\n\t * @param\tmixed\t\t\t\tOrder to sort the values in the value set\n\t * @return\tfloat\n\t */\n\tpublic static function RANK($value,$valueSet,$order=0) {\n\t\t$value = PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$valueSet = PHPExcel_Calculation_Functions::flattenArray($valueSet);\n\t\t$order\t= (is_null($order))\t? 0 :\t(integer) PHPExcel_Calculation_Functions::flattenSingleValue($order);\n\n\t\tforeach($valueSet as $key => $valueEntry) {\n\t\t\tif (!is_numeric($valueEntry)) {\n\t\t\t\tunset($valueSet[$key]);\n\t\t\t}\n\t\t}\n\n\t\tif ($order == 0) {\n\t\t\trsort($valueSet,SORT_NUMERIC);\n\t\t} else {\n\t\t\tsort($valueSet,SORT_NUMERIC);\n\t\t}\n\t\t$pos = array_search($value,$valueSet);\n\t\tif ($pos === False) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t}\n\n\t\treturn ++$pos;\n\t}\t//\tfunction RANK()\n\n\n\t/**\n\t * RSQ\n\t *\n\t * Returns the square of the Pearson product moment correlation coefficient through data points in known_y's and known_x's.\n\t *\n\t * @param\tarray of mixed\t\tData Series Y\n\t * @param\tarray of mixed\t\tData Series X\n\t * @return\tfloat\n\t */\n\tpublic static function RSQ($yValues,$xValues) {\n\t\tif (!self::_checkTrendArrays($yValues,$xValues)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$yValueCount = count($yValues);\n\t\t$xValueCount = count($xValues);\n\n\t\tif (($yValueCount == 0) || ($yValueCount != $xValueCount)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t} elseif ($yValueCount == 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t}\n\n\t\t$bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues);\n\t\treturn $bestFitLinear->getGoodnessOfFit();\n\t}\t//\tfunction RSQ()\n\n\n\t/**\n\t * SKEW\n\t *\n\t * Returns the skewness of a distribution. Skewness characterizes the degree of asymmetry\n\t * of a distribution around its mean. Positive skewness indicates a distribution with an\n\t * asymmetric tail extending toward more positive values. Negative skewness indicates a\n\t * distribution with an asymmetric tail extending toward more negative values.\n\t *\n\t * @param\tarray\tData Series\n\t * @return\tfloat\n\t */\n\tpublic static function SKEW() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args());\n\t\t$mean = self::AVERAGE($aArgs);\n\t\t$stdDev = self::STDEV($aArgs);\n\n\t\t$count = $summer = 0;\n\t\t// Loop through arguments\n\t\tforeach ($aArgs as $k => $arg) {\n\t\t\tif ((is_bool($arg)) &&\n\t\t\t\t(!PHPExcel_Calculation_Functions::isMatrixValue($k))) {\n\t\t\t} else {\n\t\t\t\t// Is it a numeric value?\n\t\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t\t$summer += pow((($arg - $mean) / $stdDev),3) ;\n\t\t\t\t\t++$count;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif ($count > 2) {\n\t\t\treturn $summer * ($count / (($count-1) * ($count-2)));\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t}\t//\tfunction SKEW()\n\n\n\t/**\n\t * SLOPE\n\t *\n\t * Returns the slope of the linear regression line through data points in known_y's and known_x's.\n\t *\n\t * @param\tarray of mixed\t\tData Series Y\n\t * @param\tarray of mixed\t\tData Series X\n\t * @return\tfloat\n\t */\n\tpublic static function SLOPE($yValues,$xValues) {\n\t\tif (!self::_checkTrendArrays($yValues,$xValues)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$yValueCount = count($yValues);\n\t\t$xValueCount = count($xValues);\n\n\t\tif (($yValueCount == 0) || ($yValueCount != $xValueCount)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t} elseif ($yValueCount == 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t}\n\n\t\t$bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues);\n\t\treturn $bestFitLinear->getSlope();\n\t}\t//\tfunction SLOPE()\n\n\n\t/**\n\t * SMALL\n\t *\n\t * Returns the nth smallest value in a data set. You can use this function to\n\t *\t\tselect a value based on its relative standing.\n\t *\n\t * Excel Function:\n\t *\t\tSMALL(value1[,value2[, ...]],entry)\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @param\tint\t\t\t$entry\t\t\tPosition (ordered from the smallest) in the array or range of data to return\n\t * @return\tfloat\n\t */\n\tpublic static function SMALL() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\n\t\t// Calculate\n\t\t$entry = array_pop($aArgs);\n\n\t\tif ((is_numeric($entry)) && (!is_string($entry))) {\n\t\t\t$mArgs = array();\n\t\t\tforeach ($aArgs as $arg) {\n\t\t\t\t// Is it a numeric value?\n\t\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t\t$mArgs[] = $arg;\n\t\t\t\t}\n\t\t\t}\n\t\t\t$count = self::COUNT($mArgs);\n\t\t\t$entry = floor(--$entry);\n\t\t\tif (($entry < 0) || ($entry >= $count) || ($count == 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tsort($mArgs);\n\t\t\treturn $mArgs[$entry];\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction SMALL()\n\n\n\t/**\n\t * STANDARDIZE\n\t *\n\t * Returns a normalized value from a distribution characterized by mean and standard_dev.\n\t *\n\t * @param\tfloat\t$value\t\tValue to normalize\n\t * @param\tfloat\t$mean\t\tMean Value\n\t * @param\tfloat\t$stdDev\t\tStandard Deviation\n\t * @return\tfloat\tStandardized value\n\t */\n\tpublic static function STANDARDIZE($value,$mean,$stdDev) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$mean\t= PHPExcel_Calculation_Functions::flattenSingleValue($mean);\n\t\t$stdDev\t= PHPExcel_Calculation_Functions::flattenSingleValue($stdDev);\n\n\t\tif ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) {\n\t\t\tif ($stdDev <= 0) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\treturn ($value - $mean) / $stdDev ;\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction STANDARDIZE()\n\n\n\t/**\n\t * STDEV\n\t *\n\t * Estimates standard deviation based on a sample. The standard deviation is a measure of how\n\t *\t\twidely values are dispersed from the average value (the mean).\n\t *\n\t * Excel Function:\n\t *\t\tSTDEV(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function STDEV() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args());\n\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t$aMean = self::AVERAGE($aArgs);\n\t\tif (!is_null($aMean)) {\n\t\t\t$aCount = -1;\n\t\t\tforeach ($aArgs as $k => $arg) {\n\t\t\t\tif ((is_bool($arg)) &&\n\t\t\t\t\t((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) {\n\t\t\t\t\t$arg = (integer) $arg;\n\t\t\t\t}\n\t\t\t\t// Is it a numeric value?\n\t\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t\tif (is_null($returnValue)) {\n\t\t\t\t\t\t$returnValue = pow(($arg - $aMean),2);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$returnValue += pow(($arg - $aMean),2);\n\t\t\t\t\t}\n\t\t\t\t\t++$aCount;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Return\n\t\t\tif (($aCount > 0) && ($returnValue >= 0)) {\n\t\t\t\treturn sqrt($returnValue / $aCount);\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t}\t//\tfunction STDEV()\n\n\n\t/**\n\t * STDEVA\n\t *\n\t * Estimates standard deviation based on a sample, including numbers, text, and logical values\n\t *\n\t * Excel Function:\n\t *\t\tSTDEVA(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function STDEVA() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args());\n\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t$aMean = self::AVERAGEA($aArgs);\n\t\tif (!is_null($aMean)) {\n\t\t\t$aCount = -1;\n\t\t\tforeach ($aArgs as $k => $arg) {\n\t\t\t\tif ((is_bool($arg)) &&\n\t\t\t\t\t(!PHPExcel_Calculation_Functions::isMatrixValue($k))) {\n\t\t\t\t} else {\n\t\t\t\t\t// Is it a numeric value?\n\t\t\t\t\tif ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {\n\t\t\t\t\t\tif (is_bool($arg)) {\n\t\t\t\t\t\t\t$arg = (integer) $arg;\n\t\t\t\t\t\t} elseif (is_string($arg)) {\n\t\t\t\t\t\t\t$arg = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (is_null($returnValue)) {\n\t\t\t\t\t\t\t$returnValue = pow(($arg - $aMean),2);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$returnValue += pow(($arg - $aMean),2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t++$aCount;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Return\n\t\t\tif (($aCount > 0) && ($returnValue >= 0)) {\n\t\t\t\treturn sqrt($returnValue / $aCount);\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t}\t//\tfunction STDEVA()\n\n\n\t/**\n\t * STDEVP\n\t *\n\t * Calculates standard deviation based on the entire population\n\t *\n\t * Excel Function:\n\t *\t\tSTDEVP(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function STDEVP() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args());\n\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t$aMean = self::AVERAGE($aArgs);\n\t\tif (!is_null($aMean)) {\n\t\t\t$aCount = 0;\n\t\t\tforeach ($aArgs as $k => $arg) {\n\t\t\t\tif ((is_bool($arg)) &&\n\t\t\t\t\t((!PHPExcel_Calculation_Functions::isCellValue($k)) || (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE))) {\n\t\t\t\t\t$arg = (integer) $arg;\n\t\t\t\t}\n\t\t\t\t// Is it a numeric value?\n\t\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t\tif (is_null($returnValue)) {\n\t\t\t\t\t\t$returnValue = pow(($arg - $aMean),2);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$returnValue += pow(($arg - $aMean),2);\n\t\t\t\t\t}\n\t\t\t\t\t++$aCount;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Return\n\t\t\tif (($aCount > 0) && ($returnValue >= 0)) {\n\t\t\t\treturn sqrt($returnValue / $aCount);\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t}\t//\tfunction STDEVP()\n\n\n\t/**\n\t * STDEVPA\n\t *\n\t * Calculates standard deviation based on the entire population, including numbers, text, and logical values\n\t *\n\t * Excel Function:\n\t *\t\tSTDEVPA(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function STDEVPA() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args());\n\n\t\t// Return value\n\t\t$returnValue = null;\n\n\t\t$aMean = self::AVERAGEA($aArgs);\n\t\tif (!is_null($aMean)) {\n\t\t\t$aCount = 0;\n\t\t\tforeach ($aArgs as $k => $arg) {\n\t\t\t\tif ((is_bool($arg)) &&\n\t\t\t\t\t(!PHPExcel_Calculation_Functions::isMatrixValue($k))) {\n\t\t\t\t} else {\n\t\t\t\t\t// Is it a numeric value?\n\t\t\t\t\tif ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {\n\t\t\t\t\t\tif (is_bool($arg)) {\n\t\t\t\t\t\t\t$arg = (integer) $arg;\n\t\t\t\t\t\t} elseif (is_string($arg)) {\n\t\t\t\t\t\t\t$arg = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (is_null($returnValue)) {\n\t\t\t\t\t\t\t$returnValue = pow(($arg - $aMean),2);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$returnValue += pow(($arg - $aMean),2);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t++$aCount;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Return\n\t\t\tif (($aCount > 0) && ($returnValue >= 0)) {\n\t\t\t\treturn sqrt($returnValue / $aCount);\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t}\t//\tfunction STDEVPA()\n\n\n\t/**\n\t * STEYX\n\t *\n\t * Returns the standard error of the predicted y-value for each x in the regression.\n\t *\n\t * @param\tarray of mixed\t\tData Series Y\n\t * @param\tarray of mixed\t\tData Series X\n\t * @return\tfloat\n\t */\n\tpublic static function STEYX($yValues,$xValues) {\n\t\tif (!self::_checkTrendArrays($yValues,$xValues)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\t$yValueCount = count($yValues);\n\t\t$xValueCount = count($xValues);\n\n\t\tif (($yValueCount == 0) || ($yValueCount != $xValueCount)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t} elseif ($yValueCount == 1) {\n\t\t\treturn PHPExcel_Calculation_Functions::DIV0();\n\t\t}\n\n\t\t$bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues);\n\t\treturn $bestFitLinear->getStdevOfResiduals();\n\t}\t//\tfunction STEYX()\n\n\n\t/**\n\t * TDIST\n\t *\n\t * Returns the probability of Student's T distribution.\n\t *\n\t * @param\tfloat\t\t$value\t\t\tValue for the function\n\t * @param\tfloat\t\t$degrees\t\tdegrees of freedom\n\t * @param\tfloat\t\t$tails\t\t\tnumber of tails (1 or 2)\n\t * @return\tfloat\n\t */\n\tpublic static function TDIST($value, $degrees, $tails) {\n\t\t$value\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$degrees\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees));\n\t\t$tails\t\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($tails));\n\n\t\tif ((is_numeric($value)) && (is_numeric($degrees)) && (is_numeric($tails))) {\n\t\t\tif (($value < 0) || ($degrees < 1) || ($tails < 1) || ($tails > 2)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t//\ttdist, which finds the probability that corresponds to a given value\n\t\t\t//\tof t with k degrees of freedom. This algorithm is translated from a\n\t\t\t//\tpascal function on p81 of \"Statistical Computing in Pascal\" by D\n\t\t\t//\tCooke, A H Craven & G M Clark (1985: Edward Arnold (Pubs.) Ltd:\n\t\t\t//\tLondon). The above Pascal algorithm is itself a translation of the\n\t\t\t//\tfortran algoritm \"AS 3\" by B E Cooper of the Atlas Computer\n\t\t\t//\tLaboratory as reported in (among other places) \"Applied Statistics\n\t\t\t//\tAlgorithms\", editied by P Griffiths and I D Hill (1985; Ellis\n\t\t\t//\tHorwood Ltd.; W. Sussex, England).\n\t\t\t$tterm = $degrees;\n\t\t\t$ttheta = atan2($value,sqrt($tterm));\n\t\t\t$tc = cos($ttheta);\n\t\t\t$ts = sin($ttheta);\n\t\t\t$tsum = 0;\n\n\t\t\tif (($degrees % 2) == 1) {\n\t\t\t\t$ti = 3;\n\t\t\t\t$tterm = $tc;\n\t\t\t} else {\n\t\t\t\t$ti = 2;\n\t\t\t\t$tterm = 1;\n\t\t\t}\n\n\t\t\t$tsum = $tterm;\n\t\t\twhile ($ti < $degrees) {\n\t\t\t\t$tterm *= $tc * $tc * ($ti - 1) / $ti;\n\t\t\t\t$tsum += $tterm;\n\t\t\t\t$ti += 2;\n\t\t\t}\n\t\t\t$tsum *= $ts;\n\t\t\tif (($degrees % 2) == 1) { $tsum = M_2DIVPI * ($tsum + $ttheta); }\n\t\t\t$tValue = 0.5 * (1 + $tsum);\n\t\t\tif ($tails == 1) {\n\t\t\t\treturn 1 - abs($tValue);\n\t\t\t} else {\n\t\t\t\treturn 1 - abs((1 - $tValue) - $tValue);\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction TDIST()\n\n\n\t/**\n\t * TINV\n\t *\n\t * Returns the one-tailed probability of the chi-squared distribution.\n\t *\n\t * @param\tfloat\t\t$probability\tProbability for the function\n\t * @param\tfloat\t\t$degrees\t\tdegrees of freedom\n\t * @return\tfloat\n\t */\n\tpublic static function TINV($probability, $degrees) {\n\t\t$probability\t= PHPExcel_Calculation_Functions::flattenSingleValue($probability);\n\t\t$degrees\t\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($degrees));\n\n\t\tif ((is_numeric($probability)) && (is_numeric($degrees))) {\n\t\t\t$xLo = 100;\n\t\t\t$xHi = 0;\n\n\t\t\t$x = $xNew = 1;\n\t\t\t$dx\t= 1;\n\t\t\t$i = 0;\n\n\t\t\twhile ((abs($dx) > PRECISION) && ($i++ < MAX_ITERATIONS)) {\n\t\t\t\t// Apply Newton-Raphson step\n\t\t\t\t$result = self::TDIST($x, $degrees, 2);\n\t\t\t\t$error = $result - $probability;\n\t\t\t\tif ($error == 0.0) {\n\t\t\t\t\t$dx = 0;\n\t\t\t\t} elseif ($error < 0.0) {\n\t\t\t\t\t$xLo = $x;\n\t\t\t\t} else {\n\t\t\t\t\t$xHi = $x;\n\t\t\t\t}\n\t\t\t\t// Avoid division by zero\n\t\t\t\tif ($result != 0.0) {\n\t\t\t\t\t$dx = $error / $result;\n\t\t\t\t\t$xNew = $x - $dx;\n\t\t\t\t}\n\t\t\t\t// If the NR fails to converge (which for example may be the\n\t\t\t\t// case if the initial guess is too rough) we apply a bisection\n\t\t\t\t// step to determine a more narrow interval around the root.\n\t\t\t\tif (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) {\n\t\t\t\t\t$xNew = ($xLo + $xHi) / 2;\n\t\t\t\t\t$dx = $xNew - $x;\n\t\t\t\t}\n\t\t\t\t$x = $xNew;\n\t\t\t}\n\t\t\tif ($i == MAX_ITERATIONS) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NA();\n\t\t\t}\n\t\t\treturn round($x,12);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction TINV()\n\n\n\t/**\n\t * TREND\n\t *\n\t * Returns values along a linear trend\n\t *\n\t * @param\tarray of mixed\t\tData Series Y\n\t * @param\tarray of mixed\t\tData Series X\n\t * @param\tarray of mixed\t\tValues of X for which we want to find Y\n\t * @param\tboolean\t\t\t\tA logical value specifying whether to force the intersect to equal 0.\n\t * @return\tarray of float\n\t */\n\tpublic static function TREND($yValues,$xValues=array(),$newValues=array(),$const=True) {\n\t\t$yValues = PHPExcel_Calculation_Functions::flattenArray($yValues);\n\t\t$xValues = PHPExcel_Calculation_Functions::flattenArray($xValues);\n\t\t$newValues = PHPExcel_Calculation_Functions::flattenArray($newValues);\n\t\t$const\t= (is_null($const))\t? True :\t(boolean) PHPExcel_Calculation_Functions::flattenSingleValue($const);\n\n\t\t$bestFitLinear = trendClass::calculate(trendClass::TREND_LINEAR,$yValues,$xValues,$const);\n\t\tif (empty($newValues)) {\n\t\t\t$newValues = $bestFitLinear->getXValues();\n\t\t}\n\n\t\t$returnArray = array();\n\t\tforeach($newValues as $xValue) {\n\t\t\t$returnArray[0][] = $bestFitLinear->getValueOfYForX($xValue);\n\t\t}\n\n\t\treturn $returnArray;\n\t}\t//\tfunction TREND()\n\n\n\t/**\n\t * TRIMMEAN\n\t *\n\t * Returns the mean of the interior of a data set. TRIMMEAN calculates the mean\n\t *\t\ttaken by excluding a percentage of data points from the top and bottom tails\n\t *\t\tof a data set.\n\t *\n\t * Excel Function:\n\t *\t\tTRIMEAN(value1[,value2[, ...]],$discard)\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @param\tfloat\t\t$discard\t\tPercentage to discard\n\t * @return\tfloat\n\t */\n\tpublic static function TRIMMEAN() {\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\n\t\t// Calculate\n\t\t$percent = array_pop($aArgs);\n\n\t\tif ((is_numeric($percent)) && (!is_string($percent))) {\n\t\t\tif (($percent < 0) || ($percent > 1)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\t$mArgs = array();\n\t\t\tforeach ($aArgs as $arg) {\n\t\t\t\t// Is it a numeric value?\n\t\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t\t$mArgs[] = $arg;\n\t\t\t\t}\n\t\t\t}\n\t\t\t$discard = floor(self::COUNT($mArgs) * $percent / 2);\n\t\t\tsort($mArgs);\n\t\t\tfor ($i=0; $i < $discard; ++$i) {\n\t\t\t\tarray_pop($mArgs);\n\t\t\t\tarray_shift($mArgs);\n\t\t\t}\n\t\t\treturn self::AVERAGE($mArgs);\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction TRIMMEAN()\n\n\n\t/**\n\t * VARFunc\n\t *\n\t * Estimates variance based on a sample.\n\t *\n\t * Excel Function:\n\t *\t\tVAR(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function VARFunc() {\n\t\t// Return value\n\t\t$returnValue = PHPExcel_Calculation_Functions::DIV0();\n\n\t\t$summerA = $summerB = 0;\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\t$aCount = 0;\n\t\tforeach ($aArgs as $arg) {\n\t\t\tif (is_bool($arg)) { $arg = (integer) $arg; }\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t$summerA += ($arg * $arg);\n\t\t\t\t$summerB += $arg;\n\t\t\t\t++$aCount;\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif ($aCount > 1) {\n\t\t\t$summerA *= $aCount;\n\t\t\t$summerB *= $summerB;\n\t\t\t$returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1));\n\t\t}\n\t\treturn $returnValue;\n\t}\t//\tfunction VARFunc()\n\n\n\t/**\n\t * VARA\n\t *\n\t * Estimates variance based on a sample, including numbers, text, and logical values\n\t *\n\t * Excel Function:\n\t *\t\tVARA(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function VARA() {\n\t\t// Return value\n\t\t$returnValue = PHPExcel_Calculation_Functions::DIV0();\n\n\t\t$summerA = $summerB = 0;\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args());\n\t\t$aCount = 0;\n\t\tforeach ($aArgs as $k => $arg) {\n\t\t\tif ((is_string($arg)) &&\n\t\t\t\t(PHPExcel_Calculation_Functions::isValue($k))) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t} elseif ((is_string($arg)) &&\n\t\t\t\t(!PHPExcel_Calculation_Functions::isMatrixValue($k))) {\n\t\t\t} else {\n\t\t\t\t// Is it a numeric value?\n\t\t\t\tif ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {\n\t\t\t\t\tif (is_bool($arg)) {\n\t\t\t\t\t\t$arg = (integer) $arg;\n\t\t\t\t\t} elseif (is_string($arg)) {\n\t\t\t\t\t\t$arg = 0;\n\t\t\t\t\t}\n\t\t\t\t\t$summerA += ($arg * $arg);\n\t\t\t\t\t$summerB += $arg;\n\t\t\t\t\t++$aCount;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif ($aCount > 1) {\n\t\t\t$summerA *= $aCount;\n\t\t\t$summerB *= $summerB;\n\t\t\t$returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1));\n\t\t}\n\t\treturn $returnValue;\n\t}\t//\tfunction VARA()\n\n\n\t/**\n\t * VARP\n\t *\n\t * Calculates variance based on the entire population\n\t *\n\t * Excel Function:\n\t *\t\tVARP(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function VARP() {\n\t\t// Return value\n\t\t$returnValue = PHPExcel_Calculation_Functions::DIV0();\n\n\t\t$summerA = $summerB = 0;\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\t$aCount = 0;\n\t\tforeach ($aArgs as $arg) {\n\t\t\tif (is_bool($arg)) { $arg = (integer) $arg; }\n\t\t\t// Is it a numeric value?\n\t\t\tif ((is_numeric($arg)) && (!is_string($arg))) {\n\t\t\t\t$summerA += ($arg * $arg);\n\t\t\t\t$summerB += $arg;\n\t\t\t\t++$aCount;\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif ($aCount > 0) {\n\t\t\t$summerA *= $aCount;\n\t\t\t$summerB *= $summerB;\n\t\t\t$returnValue = ($summerA - $summerB) / ($aCount * $aCount);\n\t\t}\n\t\treturn $returnValue;\n\t}\t//\tfunction VARP()\n\n\n\t/**\n\t * VARPA\n\t *\n\t * Calculates variance based on the entire population, including numbers, text, and logical values\n\t *\n\t * Excel Function:\n\t *\t\tVARPA(value1[,value2[, ...]])\n\t *\n\t * @access\tpublic\n\t * @category Statistical Functions\n\t * @param\tmixed\t\t$arg,...\t\tData values\n\t * @return\tfloat\n\t */\n\tpublic static function VARPA() {\n\t\t// Return value\n\t\t$returnValue = PHPExcel_Calculation_Functions::DIV0();\n\n\t\t$summerA = $summerB = 0;\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArrayIndexed(func_get_args());\n\t\t$aCount = 0;\n\t\tforeach ($aArgs as $k => $arg) {\n\t\t\tif ((is_string($arg)) &&\n\t\t\t\t(PHPExcel_Calculation_Functions::isValue($k))) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t} elseif ((is_string($arg)) &&\n\t\t\t\t(!PHPExcel_Calculation_Functions::isMatrixValue($k))) {\n\t\t\t} else {\n\t\t\t\t// Is it a numeric value?\n\t\t\t\tif ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {\n\t\t\t\t\tif (is_bool($arg)) {\n\t\t\t\t\t\t$arg = (integer) $arg;\n\t\t\t\t\t} elseif (is_string($arg)) {\n\t\t\t\t\t\t$arg = 0;\n\t\t\t\t\t}\n\t\t\t\t\t$summerA += ($arg * $arg);\n\t\t\t\t\t$summerB += $arg;\n\t\t\t\t\t++$aCount;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\tif ($aCount > 0) {\n\t\t\t$summerA *= $aCount;\n\t\t\t$summerB *= $summerB;\n\t\t\t$returnValue = ($summerA - $summerB) / ($aCount * $aCount);\n\t\t}\n\t\treturn $returnValue;\n\t}\t//\tfunction VARPA()\n\n\n\t/**\n\t * WEIBULL\n\t *\n\t * Returns the Weibull distribution. Use this distribution in reliability\n\t * analysis, such as calculating a device's mean time to failure.\n\t *\n\t * @param\tfloat\t\t$value\n\t * @param\tfloat\t\t$alpha\t\tAlpha Parameter\n\t * @param\tfloat\t\t$beta\t\tBeta Parameter\n\t * @param\tboolean\t\t$cumulative\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function WEIBULL($value, $alpha, $beta, $cumulative) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$alpha\t= PHPExcel_Calculation_Functions::flattenSingleValue($alpha);\n\t\t$beta\t= PHPExcel_Calculation_Functions::flattenSingleValue($beta);\n\n\t\tif ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta))) {\n\t\t\tif (($value < 0) || ($alpha <= 0) || ($beta <= 0)) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t\t}\n\t\t\tif ((is_numeric($cumulative)) || (is_bool($cumulative))) {\n\t\t\t\tif ($cumulative) {\n\t\t\t\t\treturn 1 - exp(0 - pow($value / $beta,$alpha));\n\t\t\t\t} else {\n\t\t\t\t\treturn ($alpha / pow($beta,$alpha)) * pow($value,$alpha - 1) * exp(0 - pow($value / $beta,$alpha));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction WEIBULL()\n\n\n\t/**\n\t * ZTEST\n\t *\n\t * Returns the Weibull distribution. Use this distribution in reliability\n\t * analysis, such as calculating a device's mean time to failure.\n\t *\n\t * @param\tfloat\t\t$dataSet\n\t * @param\tfloat\t\t$m0\t\tAlpha Parameter\n\t * @param\tfloat\t\t$sigma\tBeta Parameter\n\t * @param\tboolean\t\t$cumulative\n\t * @return\tfloat\n\t *\n\t */\n\tpublic static function ZTEST($dataSet, $m0, $sigma = NULL) {\n\t\t$dataSet\t= PHPExcel_Calculation_Functions::flattenArrayIndexed($dataSet);\n\t\t$m0\t\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($m0);\n\t\t$sigma\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($sigma);\n\n\t\tif (is_null($sigma)) {\n\t\t\t$sigma = self::STDEV($dataSet);\n\t\t}\n\t\t$n = count($dataSet);\n\n\t\treturn 1 - self::NORMSDIST((self::AVERAGE($dataSet) - $m0)/($sigma/SQRT($n)));\n\t}\t//\tfunction ZTEST()\n\n}\t//\tclass PHPExcel_Calculation_Statistical\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/TextData.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\n/**\n * PHPExcel_Calculation_TextData\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_TextData {\n\n\tprivate static $_invalidChars = Null;\n\n\tprivate static function _uniord($c) {\n\t\tif (ord($c{0}) >=0 && ord($c{0}) <= 127)\n\t\t\treturn ord($c{0});\n\t\tif (ord($c{0}) >= 192 && ord($c{0}) <= 223)\n\t\t\treturn (ord($c{0})-192)*64 + (ord($c{1})-128);\n\t\tif (ord($c{0}) >= 224 && ord($c{0}) <= 239)\n\t\t\treturn (ord($c{0})-224)*4096 + (ord($c{1})-128)*64 + (ord($c{2})-128);\n\t\tif (ord($c{0}) >= 240 && ord($c{0}) <= 247)\n\t\t\treturn (ord($c{0})-240)*262144 + (ord($c{1})-128)*4096 + (ord($c{2})-128)*64 + (ord($c{3})-128);\n\t\tif (ord($c{0}) >= 248 && ord($c{0}) <= 251)\n\t\t\treturn (ord($c{0})-248)*16777216 + (ord($c{1})-128)*262144 + (ord($c{2})-128)*4096 + (ord($c{3})-128)*64 + (ord($c{4})-128);\n\t\tif (ord($c{0}) >= 252 && ord($c{0}) <= 253)\n\t\t\treturn (ord($c{0})-252)*1073741824 + (ord($c{1})-128)*16777216 + (ord($c{2})-128)*262144 + (ord($c{3})-128)*4096 + (ord($c{4})-128)*64 + (ord($c{5})-128);\n\t\tif (ord($c{0}) >= 254 && ord($c{0}) <= 255) //error\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\treturn 0;\n\t}\t//\tfunction _uniord()\n\n\t/**\n\t * CHARACTER\n\t *\n\t * @param\tstring\t$character\tValue\n\t * @return\tint\n\t */\n\tpublic static function CHARACTER($character) {\n\t\t$character\t= PHPExcel_Calculation_Functions::flattenSingleValue($character);\n\n\t\tif ((!is_numeric($character)) || ($character < 0)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (function_exists('mb_convert_encoding')) {\n\t\t\treturn mb_convert_encoding('&#'.intval($character).';', 'UTF-8', 'HTML-ENTITIES');\n\t\t} else {\n\t\t\treturn chr(intval($character));\n\t\t}\n\t}\n\n\n\t/**\n\t * TRIMNONPRINTABLE\n\t *\n\t * @param\tmixed\t$stringValue\tValue to check\n\t * @return\tstring\n\t */\n\tpublic static function TRIMNONPRINTABLE($stringValue = '') {\n\t\t$stringValue\t= PHPExcel_Calculation_Functions::flattenSingleValue($stringValue);\n\n\t\tif (is_bool($stringValue)) {\n\t\t\treturn ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();\n\t\t}\n\n\t\tif (self::$_invalidChars == Null) {\n\t\t\tself::$_invalidChars = range(chr(0),chr(31));\n\t\t}\n\n\t\tif (is_string($stringValue) || is_numeric($stringValue)) {\n\t\t\treturn str_replace(self::$_invalidChars, '', trim($stringValue, \"\\x00..\\x1F\"));\n\t\t}\n\t\treturn NULL;\n\t}\t//\tfunction TRIMNONPRINTABLE()\n\n\n\t/**\n\t * TRIMSPACES\n\t *\n\t * @param\tmixed\t$stringValue\tValue to check\n\t * @return\tstring\n\t */\n\tpublic static function TRIMSPACES($stringValue = '') {\n\t\t$stringValue\t= PHPExcel_Calculation_Functions::flattenSingleValue($stringValue);\n\t\tif (is_bool($stringValue)) {\n\t\t\treturn ($stringValue) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();\n\t\t}\n\n\t\tif (is_string($stringValue) || is_numeric($stringValue)) {\n\t\t\treturn trim(preg_replace('/ +/',' ',trim($stringValue, ' ')), ' ');\n\t\t}\n\t\treturn NULL;\n\t}\t//\tfunction TRIMSPACES()\n\n\n\t/**\n\t * ASCIICODE\n\t *\n\t * @param\tstring\t$characters\t\tValue\n\t * @return\tint\n\t */\n\tpublic static function ASCIICODE($characters) {\n\t\tif (($characters === NULL) || ($characters === ''))\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t$characters\t= PHPExcel_Calculation_Functions::flattenSingleValue($characters);\n\t\tif (is_bool($characters)) {\n\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {\n\t\t\t\t$characters = (int) $characters;\n\t\t\t} else {\n\t\t\t\t$characters = ($characters) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();\n\t\t\t}\n\t\t}\n\n\t\t$character = $characters;\n\t\tif ((function_exists('mb_strlen')) && (function_exists('mb_substr'))) {\n\t\t\tif (mb_strlen($characters, 'UTF-8') > 1) { $character = mb_substr($characters, 0, 1, 'UTF-8'); }\n\t\t\treturn self::_uniord($character);\n\t\t} else {\n\t\t\tif (strlen($characters) > 0) { $character = substr($characters, 0, 1); }\n\t\t\treturn ord($character);\n\t\t}\n\t}\t//\tfunction ASCIICODE()\n\n\n\t/**\n\t * CONCATENATE\n\t *\n\t * @return\tstring\n\t */\n\tpublic static function CONCATENATE() {\n\t\t// Return value\n\t\t$returnValue = '';\n\n\t\t// Loop through arguments\n\t\t$aArgs = PHPExcel_Calculation_Functions::flattenArray(func_get_args());\n\t\tforeach ($aArgs as $arg) {\n\t\t\tif (is_bool($arg)) {\n\t\t\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) {\n\t\t\t\t\t$arg = (int) $arg;\n\t\t\t\t} else {\n\t\t\t\t\t$arg = ($arg) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();\n\t\t\t\t}\n\t\t\t}\n\t\t\t$returnValue .= $arg;\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction CONCATENATE()\n\n\n\t/**\n\t * DOLLAR\n\t *\n\t * This function converts a number to text using currency format, with the decimals rounded to the specified place.\n\t * The format used is $#,##0.00_);($#,##0.00)..\n\t *\n\t * @param\tfloat\t$value\t\t\tThe value to format\n\t * @param\tint\t\t$decimals\t\tThe number of digits to display to the right of the decimal point.\n\t *\t\t\t\t\t\t\t\t\tIf decimals is negative, number is rounded to the left of the decimal point.\n\t *\t\t\t\t\t\t\t\t\tIf you omit decimals, it is assumed to be 2\n\t * @return\tstring\n\t */\n\tpublic static function DOLLAR($value = 0, $decimals = 2) {\n\t\t$value\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$decimals\t= is_null($decimals) ? 0 : PHPExcel_Calculation_Functions::flattenSingleValue($decimals);\n\n\t\t// Validate parameters\n\t\tif (!is_numeric($value) || !is_numeric($decimals)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\t$decimals = floor($decimals);\n\n\t\t$mask = '$#,##0';\n\t\tif ($decimals > 0) {\n\t\t\t$mask .= '.' . str_repeat('0',$decimals);\n\t\t} else {\n\t\t\t$round = pow(10,abs($decimals));\n\t\t\tif ($value < 0) { $round = 0-$round; }\n\t\t\t$value = PHPExcel_Calculation_MathTrig::MROUND($value, $round);\n\t\t}\n\n\t\treturn PHPExcel_Style_NumberFormat::toFormattedString($value, $mask);\n\n\t}\t//\tfunction DOLLAR()\n\n\n\t/**\n\t * SEARCHSENSITIVE\n\t *\n\t * @param\tstring\t$needle\t\tThe string to look for\n\t * @param\tstring\t$haystack\tThe string in which to look\n\t * @param\tint\t\t$offset\t\tOffset within $haystack\n\t * @return\tstring\n\t */\n\tpublic static function SEARCHSENSITIVE($needle,$haystack,$offset=1) {\n\t\t$needle\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($needle);\n\t\t$haystack\t= PHPExcel_Calculation_Functions::flattenSingleValue($haystack);\n\t\t$offset\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($offset);\n\n\t\tif (!is_bool($needle)) {\n\t\t\tif (is_bool($haystack)) {\n\t\t\t\t$haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();\n\t\t\t}\n\n\t\t\tif (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) {\n\t\t\t\tif (PHPExcel_Shared_String::CountCharacters($needle) == 0) {\n\t\t\t\t\treturn $offset;\n\t\t\t\t}\n\t\t\t\tif (function_exists('mb_strpos')) {\n\t\t\t\t\t$pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8');\n\t\t\t\t} else {\n\t\t\t\t\t$pos = strpos($haystack, $needle, --$offset);\n\t\t\t\t}\n\t\t\t\tif ($pos !== false) {\n\t\t\t\t\treturn ++$pos;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction SEARCHSENSITIVE()\n\n\n\t/**\n\t * SEARCHINSENSITIVE\n\t *\n\t * @param\tstring\t$needle\t\tThe string to look for\n\t * @param\tstring\t$haystack\tThe string in which to look\n\t * @param\tint\t\t$offset\t\tOffset within $haystack\n\t * @return\tstring\n\t */\n\tpublic static function SEARCHINSENSITIVE($needle,$haystack,$offset=1) {\n\t\t$needle\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($needle);\n\t\t$haystack\t= PHPExcel_Calculation_Functions::flattenSingleValue($haystack);\n\t\t$offset\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($offset);\n\n\t\tif (!is_bool($needle)) {\n\t\t\tif (is_bool($haystack)) {\n\t\t\t\t$haystack = ($haystack) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();\n\t\t\t}\n\n\t\t\tif (($offset > 0) && (PHPExcel_Shared_String::CountCharacters($haystack) > $offset)) {\n\t\t\t\tif (PHPExcel_Shared_String::CountCharacters($needle) == 0) {\n\t\t\t\t\treturn $offset;\n\t\t\t\t}\n\t\t\t\tif (function_exists('mb_stripos')) {\n\t\t\t\t\t$pos = mb_stripos($haystack, $needle, --$offset,'UTF-8');\n\t\t\t\t} else {\n\t\t\t\t\t$pos = stripos($haystack, $needle, --$offset);\n\t\t\t\t}\n\t\t\t\tif ($pos !== false) {\n\t\t\t\t\treturn ++$pos;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t}\t//\tfunction SEARCHINSENSITIVE()\n\n\n\t/**\n\t * FIXEDFORMAT\n\t *\n\t * @param\tmixed\t\t$value\tValue to check\n\t * @param\tinteger\t\t$decimals\n\t * @param\tboolean\t\t$no_commas\n\t * @return\tboolean\n\t */\n\tpublic static function FIXEDFORMAT($value, $decimals = 2, $no_commas = FALSE) {\n\t\t$value\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$decimals\t= PHPExcel_Calculation_Functions::flattenSingleValue($decimals);\n\t\t$no_commas\t= PHPExcel_Calculation_Functions::flattenSingleValue($no_commas);\n\n\t\t// Validate parameters\n\t\tif (!is_numeric($value) || !is_numeric($decimals)) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\t$decimals = floor($decimals);\n\n\t\t$valueResult = round($value,$decimals);\n\t\tif ($decimals < 0) { $decimals = 0; }\n\t\tif (!$no_commas) {\n\t\t\t$valueResult = number_format($valueResult,$decimals);\n\t\t}\n\n\t\treturn (string) $valueResult;\n\t}\t//\tfunction FIXEDFORMAT()\n\n\n\t/**\n\t * LEFT\n\t *\n\t * @param\tstring\t$value\tValue\n\t * @param\tint\t\t$chars\tNumber of characters\n\t * @return\tstring\n\t */\n\tpublic static function LEFT($value = '', $chars = 1) {\n\t\t$value\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$chars\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($chars);\n\n\t\tif ($chars < 0) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (is_bool($value)) {\n\t\t\t$value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();\n\t\t}\n\n\t\tif (function_exists('mb_substr')) {\n\t\t\treturn mb_substr($value, 0, $chars, 'UTF-8');\n\t\t} else {\n\t\t\treturn substr($value, 0, $chars);\n\t\t}\n\t}\t//\tfunction LEFT()\n\n\n\t/**\n\t * MID\n\t *\n\t * @param\tstring\t$value\tValue\n\t * @param\tint\t\t$start\tStart character\n\t * @param\tint\t\t$chars\tNumber of characters\n\t * @return\tstring\n\t */\n\tpublic static function MID($value = '', $start = 1, $chars = null) {\n\t\t$value\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$start\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($start);\n\t\t$chars\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($chars);\n\n\t\tif (($start < 1) || ($chars < 0)) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (is_bool($value)) {\n\t\t\t$value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();\n\t\t}\n\n\t\tif (function_exists('mb_substr')) {\n\t\t\treturn mb_substr($value, --$start, $chars, 'UTF-8');\n\t\t} else {\n\t\t\treturn substr($value, --$start, $chars);\n\t\t}\n\t}\t//\tfunction MID()\n\n\n\t/**\n\t * RIGHT\n\t *\n\t * @param\tstring\t$value\tValue\n\t * @param\tint\t\t$chars\tNumber of characters\n\t * @return\tstring\n\t */\n\tpublic static function RIGHT($value = '', $chars = 1) {\n\t\t$value\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$chars\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($chars);\n\n\t\tif ($chars < 0) {\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\n\t\tif (is_bool($value)) {\n\t\t\t$value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();\n\t\t}\n\n\t\tif ((function_exists('mb_substr')) && (function_exists('mb_strlen'))) {\n\t\t\treturn mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8');\n\t\t} else {\n\t\t\treturn substr($value, strlen($value) - $chars);\n\t\t}\n\t}\t//\tfunction RIGHT()\n\n\n\t/**\n\t * STRINGLENGTH\n\t *\n\t * @param\tstring\t$value\tValue\n\t * @return\tstring\n\t */\n\tpublic static function STRINGLENGTH($value = '') {\n\t\t$value\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\n\t\tif (is_bool($value)) {\n\t\t\t$value = ($value) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();\n\t\t}\n\n\t\tif (function_exists('mb_strlen')) {\n\t\t\treturn mb_strlen($value, 'UTF-8');\n\t\t} else {\n\t\t\treturn strlen($value);\n\t\t}\n\t}\t//\tfunction STRINGLENGTH()\n\n\n\t/**\n\t * LOWERCASE\n\t *\n\t * Converts a string value to upper case.\n\t *\n\t * @param\tstring\t\t$mixedCaseString\n\t * @return\tstring\n\t */\n\tpublic static function LOWERCASE($mixedCaseString) {\n\t\t$mixedCaseString\t= PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString);\n\n\t\tif (is_bool($mixedCaseString)) {\n\t\t\t$mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();\n\t\t}\n\n\t\treturn PHPExcel_Shared_String::StrToLower($mixedCaseString);\n\t}\t//\tfunction LOWERCASE()\n\n\n\t/**\n\t * UPPERCASE\n\t *\n\t * Converts a string value to upper case.\n\t *\n\t * @param\tstring\t\t$mixedCaseString\n\t * @return\tstring\n\t */\n\tpublic static function UPPERCASE($mixedCaseString) {\n\t\t$mixedCaseString\t= PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString);\n\n\t\tif (is_bool($mixedCaseString)) {\n\t\t\t$mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();\n\t\t}\n\n\t\treturn PHPExcel_Shared_String::StrToUpper($mixedCaseString);\n\t}\t//\tfunction UPPERCASE()\n\n\n\t/**\n\t * PROPERCASE\n\t *\n\t * Converts a string value to upper case.\n\t *\n\t * @param\tstring\t\t$mixedCaseString\n\t * @return\tstring\n\t */\n\tpublic static function PROPERCASE($mixedCaseString) {\n\t\t$mixedCaseString\t= PHPExcel_Calculation_Functions::flattenSingleValue($mixedCaseString);\n\n\t\tif (is_bool($mixedCaseString)) {\n\t\t\t$mixedCaseString = ($mixedCaseString) ? PHPExcel_Calculation::getTRUE() : PHPExcel_Calculation::getFALSE();\n\t\t}\n\n\t\treturn PHPExcel_Shared_String::StrToTitle($mixedCaseString);\n\t}\t//\tfunction PROPERCASE()\n\n\n\t/**\n\t * REPLACE\n\t *\n\t * @param\tstring\t$oldText\tString to modify\n\t * @param\tint\t\t$start\t\tStart character\n\t * @param\tint\t\t$chars\t\tNumber of characters\n\t * @param\tstring\t$newText\tString to replace in defined position \n\t * @return\tstring\n\t */\n\tpublic static function REPLACE($oldText = '', $start = 1, $chars = null, $newText) {\n\t\t$oldText\t= PHPExcel_Calculation_Functions::flattenSingleValue($oldText);\n\t\t$start\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($start);\n\t\t$chars\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($chars);\n\t\t$newText\t= PHPExcel_Calculation_Functions::flattenSingleValue($newText);\n\n\t\t$left = self::LEFT($oldText,$start-1);\n\t\t$right = self::RIGHT($oldText,self::STRINGLENGTH($oldText)-($start+$chars)+1);\n\n\t\treturn $left.$newText.$right;\n\t}\t//\tfunction REPLACE()\n\n\n\t/**\n\t * SUBSTITUTE\n\t *\n\t * @param\tstring\t$text\t\tValue\n\t * @param\tstring\t$fromText\tFrom Value\n\t * @param\tstring\t$toText\t\tTo Value\n\t * @param\tinteger\t$instance\tInstance Number\n\t * @return\tstring\n\t */\n\tpublic static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0) {\n\t\t$text\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($text);\n\t\t$fromText\t= PHPExcel_Calculation_Functions::flattenSingleValue($fromText);\n\t\t$toText\t\t= PHPExcel_Calculation_Functions::flattenSingleValue($toText);\n\t\t$instance\t= floor(PHPExcel_Calculation_Functions::flattenSingleValue($instance));\n\n\t\tif ($instance == 0) {\n\t\t\tif(function_exists('mb_str_replace')) {\n\t\t\t\treturn mb_str_replace($fromText,$toText,$text);\n\t\t\t} else {\n\t\t\t\treturn str_replace($fromText,$toText,$text);\n\t\t\t}\n\t\t} else {\n\t\t\t$pos = -1;\n\t\t\twhile($instance > 0) {\n\t\t\t\tif (function_exists('mb_strpos')) {\n\t\t\t\t\t$pos = mb_strpos($text, $fromText, $pos+1, 'UTF-8');\n\t\t\t\t} else {\n\t\t\t\t\t$pos = strpos($text, $fromText, $pos+1);\n\t\t\t\t}\n\t\t\t\tif ($pos === false) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t--$instance;\n\t\t\t}\n\t\t\tif ($pos !== false) {\n\t\t\t\tif (function_exists('mb_strlen')) {\n\t\t\t\t\treturn self::REPLACE($text,++$pos,mb_strlen($fromText, 'UTF-8'),$toText);\n\t\t\t\t} else {\n\t\t\t\t\treturn self::REPLACE($text,++$pos,strlen($fromText),$toText);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn $text;\n\t}\t//\tfunction SUBSTITUTE()\n\n\n\t/**\n\t * RETURNSTRING\n\t *\n\t * @param\tmixed\t$testValue\tValue to check\n\t * @return\tboolean\n\t */\n\tpublic static function RETURNSTRING($testValue = '') {\n\t\t$testValue\t= PHPExcel_Calculation_Functions::flattenSingleValue($testValue);\n\n\t\tif (is_string($testValue)) {\n\t\t\treturn $testValue;\n\t\t}\n\t\treturn Null;\n\t}\t//\tfunction RETURNSTRING()\n\n\n\t/**\n\t * TEXTFORMAT\n\t *\n\t * @param\tmixed\t$value\tValue to check\n\t * @param\tstring\t$format\tFormat mask to use\n\t * @return\tboolean\n\t */\n\tpublic static function TEXTFORMAT($value,$format) {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t\t$format\t= PHPExcel_Calculation_Functions::flattenSingleValue($format);\n\n\t\tif ((is_string($value)) && (!is_numeric($value)) && PHPExcel_Shared_Date::isDateTimeFormatCode($format)) {\n\t\t\t$value = PHPExcel_Calculation_DateTime::DATEVALUE($value);\n\t\t}\n\n\t\treturn (string) PHPExcel_Style_NumberFormat::toFormattedString($value,$format);\n\t}\t//\tfunction TEXTFORMAT()\n\n\t/**\n\t * VALUE\n\t *\n\t * @param\tmixed\t$value\tValue to check\n\t * @return\tboolean\n\t */\n\tpublic static function VALUE($value = '') {\n\t\t$value\t= PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\n\t\tif (!is_numeric($value)) {\n            $numberValue = str_replace(\n                PHPExcel_Shared_String::getThousandsSeparator(), \n                '', \n                trim($value, \" \\t\\n\\r\\0\\x0B\" . PHPExcel_Shared_String::getCurrencyCode())\n            );\n            if (is_numeric($numberValue)) {\n                return (float) $numberValue;\n            }\n\n            $dateSetting = PHPExcel_Calculation_Functions::getReturnDateType();\n            PHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n\n            if (strpos($value, ':') !== false) {\n                $timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($value);\n                if ($timeValue !== PHPExcel_Calculation_Functions::VALUE()) {\n                    PHPExcel_Calculation_Functions::setReturnDateType($dateSetting);\n                    return $timeValue;\n                }\n            }\n\t\t\t$dateValue = PHPExcel_Calculation_DateTime::DATEVALUE($value);\n            if ($dateValue !== PHPExcel_Calculation_Functions::VALUE()) {\n                PHPExcel_Calculation_Functions::setReturnDateType($dateSetting);\n                return $dateValue;\n            }\n            PHPExcel_Calculation_Functions::setReturnDateType($dateSetting);\n\n\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t}\n\t\treturn (float) $value;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/Token/Stack.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Calculation_Token_Stack\n *\n * @category\tPHPExcel_Calculation_Token_Stack\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation_Token_Stack {\n\n\t/**\n\t *  The parser stack for formulae\n\t *\n\t *  @var mixed[]\n\t */\n\tprivate $_stack = array();\n\n\t/**\n\t *  Count of entries in the parser stack\n\t *\n\t *  @var integer\n\t */\n\tprivate $_count = 0;\n\n\n\t/**\n\t * Return the number of entries on the stack\n\t *\n\t * @return  integer\n\t */\n\tpublic function count() {\n\t\treturn $this->_count;\n\t}\t//\tfunction count()\n\n\t/**\n\t * Push a new entry onto the stack\n\t *\n\t * @param  mixed  $type\n\t * @param  mixed  $value\n\t * @param  mixed  $reference\n\t */\n\tpublic function push($type, $value, $reference = NULL) {\n\t\t$this->_stack[$this->_count++] = array('type'\t\t=> $type,\n\t\t\t\t\t\t\t\t\t\t\t   'value'\t\t=> $value,\n\t\t\t\t\t\t\t\t\t\t\t   'reference'\t=> $reference\n\t\t\t\t\t\t\t\t\t\t\t  );\n\t\tif ($type == 'Function') {\n\t\t\t$localeFunction = PHPExcel_Calculation::_localeFunc($value);\n\t\t\tif ($localeFunction != $value) {\n\t\t\t\t$this->_stack[($this->_count - 1)]['localeValue'] = $localeFunction;\n\t\t\t}\n\t\t}\n\t}\t//\tfunction push()\n\n\t/**\n\t * Pop the last entry from the stack\n\t *\n\t * @return  mixed\n\t */\n\tpublic function pop() {\n\t\tif ($this->_count > 0) {\n\t\t\treturn $this->_stack[--$this->_count];\n\t\t}\n\t\treturn NULL;\n\t}\t//\tfunction pop()\n\n\t/**\n\t * Return an entry from the stack without removing it\n\t *\n\t * @param   integer  $n  number indicating how far back in the stack we want to look\n\t * @return  mixed\n\t */\n\tpublic function last($n = 1) {\n\t\tif ($this->_count - $n < 0) {\n\t\t\treturn NULL;\n\t\t}\n\t\treturn $this->_stack[$this->_count - $n];\n\t}\t//\tfunction last()\n\n\t/**\n\t * Clear the stack\n\t */\n\tfunction clear() {\n\t\t$this->_stack = array();\n\t\t$this->_count = 0;\n\t}\n\n}\t//\tclass PHPExcel_Calculation_Token_Stack\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation/functionlist.txt",
    "content": "ABS\nACCRINT\nACCRINTM\nACOS\nACOSH\nADDRESS\nAMORDEGRC\nAMORLINC\nAND\nAREAS\nASC\nASIN\nASINH\nATAN\nATAN2\nATANH\nAVEDEV\nAVERAGE\nAVERAGEA\nAVERAGEIF\nAVERAGEIFS\nBAHTTEXT\nBESSELI\nBESSELJ\nBESSELK\nBESSELY\nBETADIST\nBETAINV\nBIN2DEC\nBIN2HEX\nBIN2OCT\nBINOMDIST\nCEILING\nCELL\nCHAR\nCHIDIST\nCHIINV\nCHITEST\nCHOOSE\nCLEAN\nCODE\nCOLUMN\nCOLUMNS\nCOMBIN\nCOMPLEX\nCONCATENATE\nCONFIDENCE\nCONVERT\nCORREL\nCOS\nCOSH\nCOUNT\nCOUNTA\nCOUNTBLANK\nCOUNTIF\nCOUNTIFS\nCOUPDAYBS\nCOUPDAYBS\nCOUPDAYSNC\nCOUPNCD\nCOUPNUM\nCOUPPCD\nCOVAR\nCRITBINOM\nCUBEKPIMEMBER\nCUBEMEMBER\nCUBEMEMBERPROPERTY\nCUBERANKEDMEMBER\nCUBESET\nCUBESETCOUNT\nCUBEVALUE\nCUMIPMT\nCUMPRINC\nDATE\nDATEDIF\nDATEVALUE\nDAVERAGE\nDAY\nDAYS360\nDB\nDCOUNT\nDCOUNTA\nDDB\nDEC2BIN\nDEC2HEX\nDEC2OCT\nDEGREES\nDELTA\nDEVSQ\nDGET\nDISC\nDMAX\nDMIN\nDOLLAR\nDOLLARDE\nDOLLARFR\nDPRODUCT\nDSTDEV\nDSTDEVP\nDSUM\nDURATION\nDVAR\nDVARP\nEDATE\nEFFECT\nEOMONTH\nERF\nERFC\nERROR.TYPE\nEVEN\nEXACT\nEXP\nEXPONDIST\nFACT\nFACTDOUBLE\nFALSE\nFDIST\nFIND\nFINDB\nFINV\nFISHER\nFISHERINV\nFIXED\nFLOOR\nFORECAST\nFREQUENCY\nFTEST\nFV\nFVSCHEDULE\nGAMAMDIST\nGAMMAINV\nGAMMALN\nGCD\nGEOMEAN\nGESTEP\nGETPIVOTDATA\nGROWTH\nHARMEAN\nHEX2BIN\nHEX2OCT\nHLOOKUP\nHOUR\nHYPERLINK\nHYPGEOMDIST\nIF\nIFERROR\nIMABS\nIMAGINARY\nIMARGUMENT\nIMCONJUGATE\nIMCOS\nIMEXP\nIMLN\nIMLOG10\nIMLOG2\nIMPOWER\nIMPRODUCT\nIMREAL\nIMSIN\nIMSQRT\nIMSUB\nIMSUM\nINDEX\nINDIRECT\nINFO\nINT\nINTERCEPT\nINTRATE\nIPMT\nIRR\nISBLANK\nISERR\nISERROR\nISEVEN\nISLOGICAL\nISNA\nISNONTEXT\nISNUMBER\nISODD\nISPMT\nISREF\nISTEXT\nJIS\nKURT\nLARGE\nLCM\nLEFT\nLEFTB\nLEN\nLENB\nLINEST\nLN\nLOG\nLOG10\nLOGEST\nLOGINV\nLOGNORMDIST\nLOOKUP\nLOWER\nMATCH\nMAX\nMAXA\nMDETERM\nMDURATION\nMEDIAN\nMID\nMIDB\nMIN\nMINA\nMINUTE\nMINVERSE\nMIRR\nMMULT\nMOD\nMODE\nMONTH\nMROUND\nMULTINOMIAL\nN\nNA\nNEGBINOMDIST\nNETWORKDAYS\nNOMINAL\nNORMDIST\nNORMINV\nNORMSDIST\nNORMSINV\nNOT\nNOW\nNPER\nNPV\nOCT2BIN\nOCT2DEC\nOCT2HEX\nODD\nODDFPRICE\nODDFYIELD\nODDLPRICE\nODDLYIELD\nOFFSET\nOR\nPEARSON\nPERCENTILE\nPERCENTRANK\nPERMUT\nPHONETIC\nPI\nPMT\nPOISSON\nPOWER\nPPMT\nPRICE\nPRICEDISC\nPRICEMAT\nPROB\nPRODUCT\nPROPER\nPV\nQUARTILE\nQUOTIENT\nRADIANS\nRAND\nRANDBETWEEN\nRANK\nRATE\nRECEIVED\nREPLACE\nREPLACEB\nREPT\nRIGHT\nRIGHTB\nROMAN\nROUND\nROUNDDOWN\nROUNDUP\nROW\nROWS\nRSQ\nRTD\nSEARCH\nSEARCHB\nSECOND\nSERIESSUM\nSIGN\nSIN\nSINH\nSKEW\nSLN\nSLOPE\nSMALL\nSQRT\nSQRTPI\nSTANDARDIZE\nSTDEV\nSTDEVA\nSTDEVP\nSTDEVPA\nSTEYX\nSUBSTITUTE\nSUBTOTAL\nSUM\nSUMIF\nSUMIFS\nSUMPRODUCT\nSUMSQ\nSUMX2MY2\nSUMX2PY2\nSUMXMY2\nSYD\nT\nTAN\nTANH\nTBILLEQ\nTBILLPRICE\nTBILLYIELD\nTDIST\nTEXT\nTIME\nTIMEVALUE\nTINV\nTODAY\nTRANSPOSE\nTREND\nTRIM\nTRIMMEAN\nTRUE\nTRUNC\nTTEST\nTYPE\nUPPER\nUSDOLLAR\nVALUE\nVAR\nVARA\nVARP\nVARPA\nVDB\nVERSION\nVLOOKUP\nWEEKDAY\nWEEKNUM\nWEIBULL\nWORKDAY\nXIRR\nXNPV\nYEAR\nYEARFRAC\nYIELD\nYIELDDISC\nYIELDMAT\nZTEST\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Calculation.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Calculation\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\nif (!defined('CALCULATION_REGEXP_CELLREF')) {\n\t//\tTest for support of \\P (multibyte options) in PCRE\n\tif(defined('PREG_BAD_UTF8_ERROR')) {\n\t\t//\tCell reference (cell or range of cells, with or without a sheet reference)\n\t\tdefine('CALCULATION_REGEXP_CELLREF','((([^\\s,!&%^\\/\\*\\+<>=-]*)|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\"))!)?\\$?([a-z]{1,3})\\$?(\\d{1,7})');\n\t\t//\tNamed Range of cells\n\t\tdefine('CALCULATION_REGEXP_NAMEDRANGE','((([^\\s,!&%^\\/\\*\\+<>=-]*)|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\"))!)?([_A-Z][_A-Z0-9\\.]*)');\n\t} else {\n\t\t//\tCell reference (cell or range of cells, with or without a sheet reference)\n\t\tdefine('CALCULATION_REGEXP_CELLREF','(((\\w*)|(\\'[^\\']*\\')|(\\\"[^\\\"]*\\\"))!)?\\$?([a-z]{1,3})\\$?(\\d+)');\n\t\t//\tNamed Range of cells\n\t\tdefine('CALCULATION_REGEXP_NAMEDRANGE','(((\\w*)|(\\'.*\\')|(\\\".*\\\"))!)?([_A-Z][_A-Z0-9\\.]*)');\n\t}\n}\n\n\n/**\n * PHPExcel_Calculation (Multiton)\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Calculation\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Calculation {\n\n\t/** Constants\t\t\t\t*/\n\t/** Regular Expressions\t\t*/\n\t//\tNumeric operand\n\tconst CALCULATION_REGEXP_NUMBER\t\t= '[-+]?\\d*\\.?\\d+(e[-+]?\\d+)?';\n\t//\tString operand\n\tconst CALCULATION_REGEXP_STRING\t\t= '\"(?:[^\"]|\"\")*\"';\n\t//\tOpening bracket\n\tconst CALCULATION_REGEXP_OPENBRACE\t= '\\(';\n\t//\tFunction (allow for the old @ symbol that could be used to prefix a function, but we'll ignore it)\n\tconst CALCULATION_REGEXP_FUNCTION\t= '@?([A-Z][A-Z0-9\\.]*)[\\s]*\\(';\n\t//\tCell reference (cell or range of cells, with or without a sheet reference)\n\tconst CALCULATION_REGEXP_CELLREF\t= CALCULATION_REGEXP_CELLREF;\n\t//\tNamed Range of cells\n\tconst CALCULATION_REGEXP_NAMEDRANGE\t= CALCULATION_REGEXP_NAMEDRANGE;\n\t//\tError\n\tconst CALCULATION_REGEXP_ERROR\t\t= '\\#[A-Z][A-Z0_\\/]*[!\\?]?';\n\n\n\t/** constants */\n\tconst RETURN_ARRAY_AS_ERROR = 'error';\n\tconst RETURN_ARRAY_AS_VALUE = 'value';\n\tconst RETURN_ARRAY_AS_ARRAY = 'array';\n\n\tprivate static $returnArrayAsType\t= self::RETURN_ARRAY_AS_VALUE;\n\n\n\t/**\n\t * Instance of this class\n\t *\n\t * @access\tprivate\n\t * @var PHPExcel_Calculation\n\t */\n\tprivate static $_instance;\n\n\n\t/**\n\t * Instance of the workbook this Calculation Engine is using\n\t *\n\t * @access\tprivate\n\t * @var PHPExcel\n\t */\n    private $_workbook;\n\n\t/**\n\t * List of instances of the calculation engine that we've instantiated for individual workbooks\n\t *\n\t * @access\tprivate\n\t * @var PHPExcel_Calculation[]\n\t */\n    private static $_workbookSets;\n\n\t/**\n\t * Calculation cache\n\t *\n\t * @access\tprivate\n\t * @var array\n\t */\n\tprivate $_calculationCache = array ();\n\n\n\t/**\n\t * Calculation cache enabled\n\t *\n\t * @access\tprivate\n\t * @var boolean\n\t */\n\tprivate $_calculationCacheEnabled = TRUE;\n\n\n\t/**\n\t * List of operators that can be used within formulae\n\t * The true/false value indicates whether it is a binary operator or a unary operator\n\t *\n\t * @access\tprivate\n\t * @var array\n\t */\n\tprivate static $_operators\t\t\t= array('+' => TRUE,\t'-' => TRUE,\t'*' => TRUE,\t'/' => TRUE,\n\t\t\t\t\t\t\t\t\t\t\t\t'^' => TRUE,\t'&' => TRUE,\t'%' => FALSE,\t'~' => FALSE,\n\t\t\t\t\t\t\t\t\t\t\t\t'>' => TRUE,\t'<' => TRUE,\t'=' => TRUE,\t'>=' => TRUE,\n\t\t\t\t\t\t\t\t\t\t\t\t'<=' => TRUE,\t'<>' => TRUE,\t'|' => TRUE,\t':' => TRUE\n\t\t\t\t\t\t\t\t\t\t\t   );\n\n\n\t/**\n\t * List of binary operators (those that expect two operands)\n\t *\n\t * @access\tprivate\n\t * @var array\n\t */\n\tprivate static $_binaryOperators\t= array('+' => TRUE,\t'-' => TRUE,\t'*' => TRUE,\t'/' => TRUE,\n\t\t\t\t\t\t\t\t\t\t\t\t'^' => TRUE,\t'&' => TRUE,\t'>' => TRUE,\t'<' => TRUE,\n\t\t\t\t\t\t\t\t\t\t\t\t'=' => TRUE,\t'>=' => TRUE,\t'<=' => TRUE,\t'<>' => TRUE,\n\t\t\t\t\t\t\t\t\t\t\t\t'|' => TRUE,\t':' => TRUE\n\t\t\t\t\t\t\t\t\t\t\t   );\n\n\t/**\n\t * The debug log generated by the calculation engine\n\t *\n\t * @access\tprivate\n\t * @var PHPExcel_CalcEngine_Logger\n\t *\n\t */\n\tprivate $debugLog;\n\n\t/**\n\t * Flag to determine how formula errors should be handled\n\t *\t\tIf true, then a user error will be triggered\n\t *\t\tIf false, then an exception will be thrown\n\t *\n\t * @access\tpublic\n\t * @var boolean\n\t *\n\t */\n\tpublic $suppressFormulaErrors = FALSE;\n\n\t/**\n\t * Error message for any error that was raised/thrown by the calculation engine\n\t *\n\t * @access\tpublic\n\t * @var string\n\t *\n\t */\n\tpublic $formulaError = NULL;\n\n\t/**\n\t * An array of the nested cell references accessed by the calculation engine, used for the debug log\n\t *\n\t * @access\tprivate\n\t * @var array of string\n\t *\n\t */\n\tprivate $_cyclicReferenceStack;\n\n\tprivate $_cellStack = array();\n\n\t/**\n\t * Current iteration counter for cyclic formulae\n\t * If the value is 0 (or less) then cyclic formulae will throw an exception,\n\t *    otherwise they will iterate to the limit defined here before returning a result\n\t *\n\t * @var integer\n\t *\n\t */\n\tprivate $_cyclicFormulaCount = 1;\n\n\tprivate $_cyclicFormulaCell = '';\n\n\t/**\n\t * Number of iterations for cyclic formulae\n\t *\n\t * @var integer\n\t *\n\t */\n\tpublic $cyclicFormulaCount = 1;\n\n\t/**\n\t * Precision used for calculations\n\t *\n\t * @var integer\n\t *\n\t */\n\tprivate $_savedPrecision\t= 14;\n\n\n\t/**\n\t * The current locale setting\n\t *\n\t * @var string\n\t *\n\t */\n\tprivate static $_localeLanguage = 'en_us';\t\t\t\t\t//\tUS English\t(default locale)\n\n\t/**\n\t * List of available locale settings\n\t * Note that this is read for the locale subdirectory only when requested\n\t *\n\t * @var string[]\n\t *\n\t */\n\tprivate static $_validLocaleLanguages = array(\t'en'\t\t//\tEnglish\t\t(default language)\n\t\t\t\t\t\t\t\t\t\t\t\t );\n\t/**\n\t * Locale-specific argument separator for function arguments\n\t *\n\t * @var string\n\t *\n\t */\n\tprivate static $_localeArgumentSeparator = ',';\n\tprivate static $_localeFunctions = array();\n\n\t/**\n\t * Locale-specific translations for Excel constants (True, False and Null)\n\t *\n\t * @var string[]\n\t *\n\t */\n\tpublic static $_localeBoolean = array(\t'TRUE'\t=> 'TRUE',\n\t\t\t\t\t\t\t\t\t\t\t'FALSE'\t=> 'FALSE',\n\t\t\t\t\t\t\t\t\t\t\t'NULL'\t=> 'NULL'\n\t\t\t\t\t\t\t\t\t\t  );\n\n\n\t/**\n\t * Excel constant string translations to their PHP equivalents\n\t * Constant conversion from text name/value to actual (datatyped) value\n\t *\n\t * @var string[]\n\t *\n\t */\n\tprivate static $_ExcelConstants = array('TRUE'\t=> TRUE,\n\t\t\t\t\t\t\t\t\t\t\t'FALSE'\t=> FALSE,\n\t\t\t\t\t\t\t\t\t\t\t'NULL'\t=> NULL\n\t\t\t\t\t\t\t\t\t\t   );\n\n\t//\tPHPExcel functions\n\tprivate static $_PHPExcelFunctions = array(\t// PHPExcel functions\n\t\t\t\t'ABS'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'abs',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ACCRINT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::ACCRINT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4-7'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ACCRINTM'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::ACCRINTM',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3-5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ACOS'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'acos',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ACOSH'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'acosh',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ADDRESS'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::CELL_ADDRESS',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2-5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'AMORDEGRC'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::AMORDEGRC',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'6,7'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'AMORLINC'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::AMORLINC',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'6,7'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'AND'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOGICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Logical::LOGICAL_AND',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'AREAS'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ASC'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ASIN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'asin',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ASINH'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'asinh',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ATAN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'atan',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ATAN2'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::ATAN2',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ATANH'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'atanh',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'AVEDEV'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::AVEDEV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'AVERAGE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::AVERAGE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'AVERAGEA'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::AVERAGEA',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'AVERAGEIF'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::AVERAGEIF',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'AVERAGEIFS'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'BAHTTEXT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'BESSELI'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::BESSELI',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'BESSELJ'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::BESSELJ',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'BESSELK'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::BESSELK',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'BESSELY'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::BESSELY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'BETADIST'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::BETADIST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3-5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'BETAINV'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::BETAINV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3-5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'BIN2DEC'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::BINTODEC',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'BIN2HEX'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::BINTOHEX',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'BIN2OCT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::BINTOOCT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'BINOMDIST'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::BINOMDIST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CEILING'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::CEILING',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CELL'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CHAR'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::CHARACTER',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CHIDIST'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::CHIDIST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CHIINV'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::CHIINV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CHITEST'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CHOOSE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::CHOOSE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CLEAN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::TRIMNONPRINTABLE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CODE'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::ASCIICODE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COLUMN'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::COLUMN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'-1',\n\t\t\t\t\t\t\t\t\t\t\t\t 'passByReference'\t=>\tarray(TRUE)\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COLUMNS'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::COLUMNS',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COMBIN'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::COMBIN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COMPLEX'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::COMPLEX',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CONCATENATE'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::CONCATENATE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CONFIDENCE'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::CONFIDENCE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CONVERT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::CONVERTUOM',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CORREL'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::CORREL',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COS'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'cos',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COSH'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'cosh',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COUNT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::COUNT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COUNTA'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::COUNTA',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COUNTBLANK'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::COUNTBLANK',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COUNTIF'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::COUNTIF',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COUNTIFS'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COUPDAYBS'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::COUPDAYBS',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3,4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COUPDAYS'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::COUPDAYS',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3,4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COUPDAYSNC'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::COUPDAYSNC',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3,4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COUPNCD'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::COUPNCD',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3,4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COUPNUM'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::COUPNUM',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3,4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COUPPCD'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::COUPPCD',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3,4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'COVAR'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::COVAR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CRITBINOM'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::CRITBINOM',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CUBEKPIMEMBER'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_CUBE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'?'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CUBEMEMBER'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_CUBE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'?'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CUBEMEMBERPROPERTY'\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_CUBE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'?'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CUBERANKEDMEMBER'\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_CUBE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'?'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CUBESET'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_CUBE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'?'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CUBESETCOUNT'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_CUBE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'?'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CUBEVALUE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_CUBE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'?'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CUMIPMT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::CUMIPMT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'6'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'CUMPRINC'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::CUMPRINC',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'6'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DATE'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::DATE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DATEDIF'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::DATEDIF',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DATEVALUE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::DATEVALUE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DAVERAGE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATABASE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Database::DAVERAGE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DAY'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::DAYOFMONTH',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DAYS360'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::DAYS360',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DB'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::DB',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4,5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DCOUNT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATABASE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Database::DCOUNT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DCOUNTA'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATABASE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Database::DCOUNTA',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DDB'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::DDB',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4,5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DEC2BIN'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::DECTOBIN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DEC2HEX'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::DECTOHEX',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DEC2OCT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::DECTOOCT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DEGREES'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'rad2deg',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DELTA'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::DELTA',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DEVSQ'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::DEVSQ',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DGET'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATABASE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Database::DGET',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DISC'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::DISC',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4,5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DMAX'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATABASE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Database::DMAX',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DMIN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATABASE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Database::DMIN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DOLLAR'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::DOLLAR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DOLLARDE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::DOLLARDE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DOLLARFR'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::DOLLARFR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DPRODUCT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATABASE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Database::DPRODUCT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DSTDEV'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATABASE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Database::DSTDEV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DSTDEVP'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATABASE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Database::DSTDEVP',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DSUM'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATABASE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Database::DSUM',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DURATION'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'5,6'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DVAR'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATABASE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Database::DVAR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'DVARP'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATABASE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Database::DVARP',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'EDATE'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::EDATE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'EFFECT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::EFFECT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'EOMONTH'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::EOMONTH',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ERF'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::ERF',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ERFC'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::ERFC',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ERROR.TYPE'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::ERROR_TYPE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'EVEN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::EVEN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'EXACT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'EXP'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'exp',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'EXPONDIST'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::EXPONDIST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FACT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::FACT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FACTDOUBLE'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::FACTDOUBLE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FALSE'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOGICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Logical::FALSE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'0'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FDIST'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FIND'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::SEARCHSENSITIVE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FINDB'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::SEARCHSENSITIVE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FINV'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FISHER'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::FISHER',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FISHERINV'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::FISHERINV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FIXED'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::FIXEDFORMAT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1-3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FLOOR'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::FLOOR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FORECAST'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::FORECAST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FREQUENCY'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FTEST'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FV'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::FV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3-5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'FVSCHEDULE'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::FVSCHEDULE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'GAMMADIST'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::GAMMADIST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'GAMMAINV'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::GAMMAINV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'GAMMALN'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::GAMMALN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'GCD'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::GCD',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'GEOMEAN'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::GEOMEAN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'GESTEP'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::GESTEP',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'GETPIVOTDATA'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'GROWTH'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::GROWTH',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1-4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'HARMEAN'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::HARMEAN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'HEX2BIN'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::HEXTOBIN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'HEX2DEC'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::HEXTODEC',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'HEX2OCT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::HEXTOOCT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'HLOOKUP'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::HLOOKUP',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3,4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'HOUR'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::HOUROFDAY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'HYPERLINK'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::HYPERLINK',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2',\n\t\t\t\t\t\t\t\t\t\t\t\t 'passCellReference'=>\tTRUE\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'HYPGEOMDIST'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::HYPGEOMDIST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IF'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOGICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Logical::STATEMENT_IF',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1-3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IFERROR'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOGICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Logical::IFERROR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMABS'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMABS',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMAGINARY'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMAGINARY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMARGUMENT'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMARGUMENT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMCONJUGATE'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMCONJUGATE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMCOS'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMCOS',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMDIV'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMDIV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMEXP'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMEXP',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMLN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMLN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMLOG10'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMLOG10',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMLOG2'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMLOG2',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMPOWER'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMPOWER',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMPRODUCT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMPRODUCT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMREAL'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMREAL',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMSIN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMSIN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMSQRT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMSQRT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMSUB'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMSUB',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IMSUM'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::IMSUM',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'INDEX'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::INDEX',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1-4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'INDIRECT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::INDIRECT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2',\n\t\t\t\t\t\t\t\t\t\t\t\t 'passCellReference'=>\tTRUE\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'INFO'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'INT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::INT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'INTERCEPT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::INTERCEPT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'INTRATE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::INTRATE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4,5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IPMT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::IPMT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4-6'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'IRR'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::IRR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ISBLANK'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::IS_BLANK',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ISERR'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::IS_ERR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ISERROR'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::IS_ERROR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ISEVEN'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::IS_EVEN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ISLOGICAL'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::IS_LOGICAL',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ISNA'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::IS_NA',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ISNONTEXT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::IS_NONTEXT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ISNUMBER'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::IS_NUMBER',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ISODD'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::IS_ODD',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ISPMT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::ISPMT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ISREF'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ISTEXT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::IS_TEXT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'JIS'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'KURT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::KURT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LARGE'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::LARGE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LCM'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::LCM',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LEFT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::LEFT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LEFTB'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::LEFT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LEN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::STRINGLENGTH',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LENB'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::STRINGLENGTH',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LINEST'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::LINEST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1-4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'log',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LOG'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::LOG_BASE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LOG10'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'log10',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LOGEST'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::LOGEST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1-4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LOGINV'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::LOGINV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LOGNORMDIST'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::LOGNORMDIST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LOOKUP'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::LOOKUP',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'LOWER'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::LOWERCASE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MATCH'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::MATCH',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MAX'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::MAX',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MAXA'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::MAXA',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MAXIF'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::MAXIF',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MDETERM'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::MDETERM',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MDURATION'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'5,6'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MEDIAN'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::MEDIAN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MEDIANIF'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MID'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::MID',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MIDB'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::MID',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MIN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::MIN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MINA'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::MINA',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MINIF'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::MINIF',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MINUTE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::MINUTEOFHOUR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MINVERSE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::MINVERSE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MIRR'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::MIRR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MMULT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::MMULT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MOD'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::MOD',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MODE'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::MODE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MONTH'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::MONTHOFYEAR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MROUND'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::MROUND',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'MULTINOMIAL'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::MULTINOMIAL',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'N'\t\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::N',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'NA'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::NA',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'0'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'NEGBINOMDIST'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::NEGBINOMDIST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'NETWORKDAYS'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::NETWORKDAYS',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'NOMINAL'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::NOMINAL',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'NORMDIST'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::NORMDIST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'NORMINV'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::NORMINV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'NORMSDIST'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::NORMSDIST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'NORMSINV'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::NORMSINV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'NOT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOGICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Logical::NOT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'NOW'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::DATETIMENOW',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'0'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'NPER'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::NPER',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3-5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'NPV'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::NPV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'OCT2BIN'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::OCTTOBIN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'OCT2DEC'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::OCTTODEC',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'OCT2HEX'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_ENGINEERING,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Engineering::OCTTOHEX',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ODD'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::ODD',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ODDFPRICE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'8,9'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ODDFYIELD'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'8,9'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ODDLPRICE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'7,8'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ODDLYIELD'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'7,8'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'OFFSET'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::OFFSET',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3,5',\n\t\t\t\t\t\t\t\t\t\t\t\t 'passCellReference'=>\tTRUE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'passByReference'\t=>\tarray(TRUE)\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'OR'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOGICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Logical::LOGICAL_OR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PEARSON'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::CORREL',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PERCENTILE'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::PERCENTILE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PERCENTRANK'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::PERCENTRANK',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PERMUT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::PERMUT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PHONETIC'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PI'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'pi',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'0'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PMT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::PMT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3-5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'POISSON'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::POISSON',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'POWER'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::POWER',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PPMT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::PPMT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4-6'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PRICE'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::PRICE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'6,7'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PRICEDISC'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::PRICEDISC',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4,5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PRICEMAT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::PRICEMAT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'5,6'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PROB'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3,4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PRODUCT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::PRODUCT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PROPER'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::PROPERCASE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'PV'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::PV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3-5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'QUARTILE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::QUARTILE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'QUOTIENT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::QUOTIENT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'RADIANS'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'deg2rad',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'RAND'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::RAND',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'0'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'RANDBETWEEN'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::RAND',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'RANK'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::RANK',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'RATE'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::RATE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3-6'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'RECEIVED'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::RECEIVED',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4-5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'REPLACE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::REPLACE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'REPLACEB'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::REPLACE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'REPT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'str_repeat',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'RIGHT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::RIGHT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'RIGHTB'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::RIGHT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ROMAN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::ROMAN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ROUND'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'round',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ROUNDDOWN'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::ROUNDDOWN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ROUNDUP'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::ROUNDUP',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ROW'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::ROW',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'-1',\n\t\t\t\t\t\t\t\t\t\t\t\t 'passByReference'\t=>\tarray(TRUE)\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ROWS'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::ROWS',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'RSQ'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::RSQ',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'RTD'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SEARCH'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SEARCHB'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::SEARCHINSENSITIVE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SECOND'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::SECONDOFMINUTE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SERIESSUM'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::SERIESSUM',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SIGN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::SIGN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SIN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'sin',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SINH'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'sinh',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SKEW'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::SKEW',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SLN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::SLN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SLOPE'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::SLOPE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SMALL'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::SMALL',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SQRT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'sqrt',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SQRTPI'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::SQRTPI',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'STANDARDIZE'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::STANDARDIZE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'STDEV'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::STDEV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'STDEVA'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::STDEVA',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'STDEVP'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::STDEVP',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'STDEVPA'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::STDEVPA',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'STEYX'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::STEYX',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SUBSTITUTE'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::SUBSTITUTE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3,4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SUBTOTAL'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::SUBTOTAL',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SUM'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::SUM',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SUMIF'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::SUMIF',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SUMIFS'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'?'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SUMPRODUCT'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::SUMPRODUCT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SUMSQ'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::SUMSQ',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SUMX2MY2'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::SUMX2MY2',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SUMX2PY2'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::SUMX2PY2',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SUMXMY2'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::SUMXMY2',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'SYD'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::SYD',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'T'\t\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::RETURNSTRING',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TAN'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'tan',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TANH'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'tanh',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TBILLEQ'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::TBILLEQ',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TBILLPRICE'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::TBILLPRICE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TBILLYIELD'\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::TBILLYIELD',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TDIST'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::TDIST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TEXT'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::TEXTFORMAT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TIME'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::TIME',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TIMEVALUE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::TIMEVALUE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TINV'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::TINV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TODAY'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::DATENOW',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'0'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TRANSPOSE'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::TRANSPOSE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TREND'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::TREND',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1-4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TRIM'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::TRIMSPACES',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TRIMMEAN'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::TRIMMEAN',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TRUE'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOGICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Logical::TRUE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'0'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TRUNC'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_MATH_AND_TRIG,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_MathTrig::TRUNC',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TTEST'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'TYPE'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::TYPE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'UPPER'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::UPPERCASE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'USDOLLAR'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'VALUE'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_TEXT_AND_DATA,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_TextData::VALUE',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'VAR'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::VARFunc',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'VARA'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::VARA',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'VARP'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::VARP',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'VARPA'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::VARPA',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'VDB'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'5-7'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'VERSION'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_INFORMATION,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::VERSION',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'0'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'VLOOKUP'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_LOOKUP_AND_REFERENCE,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_LookupRef::VLOOKUP',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3,4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'WEEKDAY'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::DAYOFWEEK',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'WEEKNUM'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::WEEKOFYEAR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1,2'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'WEIBULL'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::WEIBULL',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'WORKDAY'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::WORKDAY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2+'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'XIRR'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::XIRR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'XNPV'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::XNPV',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'YEAR'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::YEAR',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'1'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'YEARFRAC'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_DATE_AND_TIME,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_DateTime::YEARFRAC',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2,3'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'YIELD'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Functions::DUMMY',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'6,7'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'YIELDDISC'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::YIELDDISC',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'4,5'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'YIELDMAT'\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_FINANCIAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Financial::YIELDMAT',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'5,6'\n\t\t\t\t\t\t\t\t\t\t\t\t),\n\t\t\t\t'ZTEST'\t\t\t\t\t=> array('category'\t\t\t=>\tPHPExcel_Calculation_Function::CATEGORY_STATISTICAL,\n\t\t\t\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'PHPExcel_Calculation_Statistical::ZTEST',\n\t\t\t\t\t\t\t\t\t\t\t\t 'argumentCount'\t=>\t'2-3'\n\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t);\n\n\n\t//\tInternal functions used for special control purposes\n\tprivate static $_controlFunctions = array(\n\t\t\t\t'MKMATRIX'\t=> array('argumentCount'\t=>\t'*',\n\t\t\t\t\t\t\t\t\t 'functionCall'\t\t=>\t'self::_mkMatrix'\n\t\t\t\t\t\t\t\t\t)\n\t\t\t);\n\n\n\n\n\tprivate function __construct(PHPExcel $workbook = NULL) {\n\t\t$setPrecision = (PHP_INT_SIZE == 4) ? 14 : 16;\n\t\t$this->_savedPrecision = ini_get('precision');\n\t\tif ($this->_savedPrecision < $setPrecision) {\n\t\t\tini_set('precision',$setPrecision);\n\t\t}\n\t\t$this->delta = 1 * pow(10, -$setPrecision);\n\n\t\tif ($workbook !== NULL) {\n\t\t\tself::$_workbookSets[$workbook->getID()] = $this;\n\t\t}\n\n\t\t$this->_workbook = $workbook;\n\t\t$this->_cyclicReferenceStack = new PHPExcel_CalcEngine_CyclicReferenceStack();\n\t    $this->_debugLog = new PHPExcel_CalcEngine_Logger($this->_cyclicReferenceStack);\n\t}\t//\tfunction __construct()\n\n\n\tpublic function __destruct() {\n\t\tif ($this->_savedPrecision != ini_get('precision')) {\n\t\t\tini_set('precision',$this->_savedPrecision);\n\t\t}\n\t}\n\n\tprivate static function _loadLocales() {\n\t\t$localeFileDirectory = PHPEXCEL_ROOT.'PHPExcel/locale/';\n\t\tforeach (glob($localeFileDirectory.'/*',GLOB_ONLYDIR) as $filename) {\n\t\t\t$filename = substr($filename,strlen($localeFileDirectory)+1);\n\t\t\tif ($filename != 'en') {\n\t\t\t\tself::$_validLocaleLanguages[] = $filename;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get an instance of this class\n\t *\n\t * @access\tpublic\n\t * @param   PHPExcel $workbook  Injected workbook for working with a PHPExcel object,\n\t *\t\t\t\t\t\t\t\t\tor NULL to create a standalone claculation engine\n\t * @return PHPExcel_Calculation\n\t */\n\tpublic static function getInstance(PHPExcel $workbook = NULL) {\n\t\tif ($workbook !== NULL) {\n    \t\tif (isset(self::$_workbookSets[$workbook->getID()])) {\n    \t\t\treturn self::$_workbookSets[$workbook->getID()];\n    \t\t}\n\t\t\treturn new PHPExcel_Calculation($workbook);\n\t\t}\n\n\t\tif (!isset(self::$_instance) || (self::$_instance === NULL)) {\n\t\t\tself::$_instance = new PHPExcel_Calculation();\n\t\t}\n\n\t\treturn self::$_instance;\n\t}\t//\tfunction getInstance()\n\n\t/**\n\t * Unset an instance of this class\n\t *\n\t * @access\tpublic\n\t * @param   PHPExcel $workbook  Injected workbook identifying the instance to unset\n\t */\n\tpublic static function unsetInstance(PHPExcel $workbook = NULL) {\n\t\tif ($workbook !== NULL) {\n    \t\tif (isset(self::$_workbookSets[$workbook->getID()])) {\n    \t\t\tunset(self::$_workbookSets[$workbook->getID()]);\n    \t\t}\n\t\t}\n    }\n\n\t/**\n\t * Flush the calculation cache for any existing instance of this class\n\t *\t\tbut only if a PHPExcel_Calculation instance exists\n\t *\n\t * @access\tpublic\n\t * @return null\n\t */\n\tpublic function flushInstance() {\n\t\t$this->clearCalculationCache();\n\t}\t//\tfunction flushInstance()\n\n\n\t/**\n\t * Get the debuglog for this claculation engine instance\n\t *\n\t * @access\tpublic\n\t * @return PHPExcel_CalcEngine_Logger\n\t */\n\tpublic function getDebugLog() {\n\t\treturn $this->_debugLog;\n\t}\n\n\t/**\n\t * __clone implementation. Cloning should not be allowed in a Singleton!\n\t *\n\t * @access\tpublic\n\t * @throws\tPHPExcel_Calculation_Exception\n\t */\n\tpublic final function __clone() {\n\t\tthrow new PHPExcel_Calculation_Exception ('Cloning the calculation engine is not allowed!');\n\t}\t//\tfunction __clone()\n\n\n\t/**\n\t * Return the locale-specific translation of TRUE\n\t *\n\t * @access\tpublic\n\t * @return\t string\t\tlocale-specific translation of TRUE\n\t */\n\tpublic static function getTRUE() {\n\t\treturn self::$_localeBoolean['TRUE'];\n\t}\n\n\t/**\n\t * Return the locale-specific translation of FALSE\n\t *\n\t * @access\tpublic\n\t * @return\t string\t\tlocale-specific translation of FALSE\n\t */\n\tpublic static function getFALSE() {\n\t\treturn self::$_localeBoolean['FALSE'];\n\t}\n\n\t/**\n\t * Set the Array Return Type (Array or Value of first element in the array)\n\t *\n\t * @access\tpublic\n\t * @param\t string\t$returnType\t\t\tArray return type\n\t * @return\t boolean\t\t\t\t\tSuccess or failure\n\t */\n\tpublic static function setArrayReturnType($returnType) {\n\t\tif (($returnType == self::RETURN_ARRAY_AS_VALUE) ||\n\t\t\t($returnType == self::RETURN_ARRAY_AS_ERROR) ||\n\t\t\t($returnType == self::RETURN_ARRAY_AS_ARRAY)) {\n\t\t\tself::$returnArrayAsType = $returnType;\n\t\t\treturn TRUE;\n\t\t}\n\t\treturn FALSE;\n\t}\t//\tfunction setArrayReturnType()\n\n\n\t/**\n\t * Return the Array Return Type (Array or Value of first element in the array)\n\t *\n\t * @access\tpublic\n\t * @return\t string\t\t$returnType\t\t\tArray return type\n\t */\n\tpublic static function getArrayReturnType() {\n\t\treturn self::$returnArrayAsType;\n\t}\t//\tfunction getArrayReturnType()\n\n\n\t/**\n\t * Is calculation caching enabled?\n\t *\n\t * @access\tpublic\n\t * @return boolean\n\t */\n\tpublic function getCalculationCacheEnabled() {\n\t\treturn $this->_calculationCacheEnabled;\n\t}\t//\tfunction getCalculationCacheEnabled()\n\n\t/**\n\t * Enable/disable calculation cache\n\t *\n\t * @access\tpublic\n\t * @param boolean $pValue\n\t */\n\tpublic function setCalculationCacheEnabled($pValue = TRUE) {\n\t\t$this->_calculationCacheEnabled = $pValue;\n\t\t$this->clearCalculationCache();\n\t}\t//\tfunction setCalculationCacheEnabled()\n\n\n\t/**\n\t * Enable calculation cache\n\t */\n\tpublic function enableCalculationCache() {\n\t\t$this->setCalculationCacheEnabled(TRUE);\n\t}\t//\tfunction enableCalculationCache()\n\n\n\t/**\n\t * Disable calculation cache\n\t */\n\tpublic function disableCalculationCache() {\n\t\t$this->setCalculationCacheEnabled(FALSE);\n\t}\t//\tfunction disableCalculationCache()\n\n\n\t/**\n\t * Clear calculation cache\n\t */\n\tpublic function clearCalculationCache() {\n\t\t$this->_calculationCache = array();\n\t}\t//\tfunction clearCalculationCache()\n\n\t/**\n\t * Clear calculation cache for a specified worksheet\n\t *\n\t * @param string $worksheetName\n\t */\n\tpublic function clearCalculationCacheForWorksheet($worksheetName) {\n\t\tif (isset($this->_calculationCache[$worksheetName])) {\n\t\t\tunset($this->_calculationCache[$worksheetName]);\n\t\t}\n\t}\t//\tfunction clearCalculationCacheForWorksheet()\n\n\t/**\n\t * Rename calculation cache for a specified worksheet\n\t *\n\t * @param string $fromWorksheetName\n\t * @param string $toWorksheetName\n\t */\n\tpublic function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName) {\n\t\tif (isset($this->_calculationCache[$fromWorksheetName])) {\n\t\t\t$this->_calculationCache[$toWorksheetName] = &$this->_calculationCache[$fromWorksheetName];\n\t\t\tunset($this->_calculationCache[$fromWorksheetName]);\n\t\t}\n\t}\t//\tfunction renameCalculationCacheForWorksheet()\n\n\n\t/**\n\t * Get the currently defined locale code\n\t *\n\t * @return string\n\t */\n\tpublic function getLocale() {\n\t\treturn self::$_localeLanguage;\n\t}\t//\tfunction getLocale()\n\n\n\t/**\n\t * Set the locale code\n\t *\n\t * @param string $locale  The locale to use for formula translation\n\t * @return boolean\n\t */\n\tpublic function setLocale($locale = 'en_us') {\n\t\t//\tIdentify our locale and language\n\t\t$language = $locale = strtolower($locale);\n\t\tif (strpos($locale,'_') !== FALSE) {\n\t\t\tlist($language) = explode('_',$locale);\n\t\t}\n\n\t\tif (count(self::$_validLocaleLanguages) == 1)\n\t\t\tself::_loadLocales();\n\n\t\t//\tTest whether we have any language data for this language (any locale)\n\t\tif (in_array($language,self::$_validLocaleLanguages)) {\n\t\t\t//\tinitialise language/locale settings\n\t\t\tself::$_localeFunctions = array();\n\t\t\tself::$_localeArgumentSeparator = ',';\n\t\t\tself::$_localeBoolean = array('TRUE' => 'TRUE', 'FALSE' => 'FALSE', 'NULL' => 'NULL');\n\t\t\t//\tDefault is English, if user isn't requesting english, then read the necessary data from the locale files\n\t\t\tif ($locale != 'en_us') {\n\t\t\t\t//\tSearch for a file with a list of function names for locale\n\t\t\t\t$functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'functions';\n\t\t\t\tif (!file_exists($functionNamesFile)) {\n\t\t\t\t\t//\tIf there isn't a locale specific function file, look for a language specific function file\n\t\t\t\t\t$functionNamesFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'functions';\n\t\t\t\t\tif (!file_exists($functionNamesFile)) {\n\t\t\t\t\t\treturn FALSE;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//\tRetrieve the list of locale or language specific function names\n\t\t\t\t$localeFunctions = file($functionNamesFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);\n\t\t\t\tforeach ($localeFunctions as $localeFunction) {\n\t\t\t\t\tlist($localeFunction) = explode('##',$localeFunction);\t//\tStrip out comments\n\t\t\t\t\tif (strpos($localeFunction,'=') !== FALSE) {\n\t\t\t\t\t\tlist($fName,$lfName) = explode('=',$localeFunction);\n\t\t\t\t\t\t$fName = trim($fName);\n\t\t\t\t\t\t$lfName = trim($lfName);\n\t\t\t\t\t\tif ((isset(self::$_PHPExcelFunctions[$fName])) && ($lfName != '') && ($fName != $lfName)) {\n\t\t\t\t\t\t\tself::$_localeFunctions[$fName] = $lfName;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//\tDefault the TRUE and FALSE constants to the locale names of the TRUE() and FALSE() functions\n\t\t\t\tif (isset(self::$_localeFunctions['TRUE'])) { self::$_localeBoolean['TRUE'] = self::$_localeFunctions['TRUE']; }\n\t\t\t\tif (isset(self::$_localeFunctions['FALSE'])) { self::$_localeBoolean['FALSE'] = self::$_localeFunctions['FALSE']; }\n\n\t\t\t\t$configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.str_replace('_',DIRECTORY_SEPARATOR,$locale).DIRECTORY_SEPARATOR.'config';\n\t\t\t\tif (!file_exists($configFile)) {\n\t\t\t\t\t$configFile = PHPEXCEL_ROOT . 'PHPExcel'.DIRECTORY_SEPARATOR.'locale'.DIRECTORY_SEPARATOR.$language.DIRECTORY_SEPARATOR.'config';\n\t\t\t\t}\n\t\t\t\tif (file_exists($configFile)) {\n\t\t\t\t\t$localeSettings = file($configFile,FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);\n\t\t\t\t\tforeach ($localeSettings as $localeSetting) {\n\t\t\t\t\t\tlist($localeSetting) = explode('##',$localeSetting);\t//\tStrip out comments\n\t\t\t\t\t\tif (strpos($localeSetting,'=') !== FALSE) {\n\t\t\t\t\t\t\tlist($settingName,$settingValue) = explode('=',$localeSetting);\n\t\t\t\t\t\t\t$settingName = strtoupper(trim($settingName));\n\t\t\t\t\t\t\tswitch ($settingName) {\n\t\t\t\t\t\t\t\tcase 'ARGUMENTSEPARATOR' :\n\t\t\t\t\t\t\t\t\tself::$_localeArgumentSeparator = trim($settingValue);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tself::$functionReplaceFromExcel = self::$functionReplaceToExcel =\n\t\t\tself::$functionReplaceFromLocale = self::$functionReplaceToLocale = NULL;\n\t\t\tself::$_localeLanguage = $locale;\n\t\t\treturn TRUE;\n\t\t}\n\t\treturn FALSE;\n\t}\t//\tfunction setLocale()\n\n\n\n\tpublic static function _translateSeparator($fromSeparator,$toSeparator,$formula,&$inBraces) {\n\t\t$strlen = mb_strlen($formula);\n\t\tfor ($i = 0; $i < $strlen; ++$i) {\n\t\t\t$chr = mb_substr($formula,$i,1);\n\t\t\tswitch ($chr) {\n\t\t\t\tcase '{' :\t$inBraces = TRUE;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\tcase '}' :\t$inBraces = FALSE;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\tcase $fromSeparator :\n\t\t\t\t\t\t\tif (!$inBraces) {\n\t\t\t\t\t\t\t\t$formula = mb_substr($formula,0,$i).$toSeparator.mb_substr($formula,$i+1);\n\t\t\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn $formula;\n\t}\n\n\tprivate static function _translateFormula($from,$to,$formula,$fromSeparator,$toSeparator) {\n\t\t//\tConvert any Excel function names to the required language\n\t\tif (self::$_localeLanguage !== 'en_us') {\n\t\t\t$inBraces = FALSE;\n\t\t\t//\tIf there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators\n\t\t\tif (strpos($formula,'\"') !== FALSE) {\n\t\t\t\t//\tSo instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded\n\t\t\t\t//\t\tthe formula\n\t\t\t\t$temp = explode('\"',$formula);\n\t\t\t\t$i = FALSE;\n\t\t\t\tforeach($temp as &$value) {\n\t\t\t\t\t//\tOnly count/replace in alternating array entries\n\t\t\t\t\tif ($i = !$i) {\n\t\t\t\t\t\t$value = preg_replace($from,$to,$value);\n\t\t\t\t\t\t$value = self::_translateSeparator($fromSeparator,$toSeparator,$value,$inBraces);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tunset($value);\n\t\t\t\t//\tThen rebuild the formula string\n\t\t\t\t$formula = implode('\"',$temp);\n\t\t\t} else {\n\t\t\t\t//\tIf there's no quoted strings, then we do a simple count/replace\n\t\t\t\t$formula = preg_replace($from,$to,$formula);\n\t\t\t\t$formula = self::_translateSeparator($fromSeparator,$toSeparator,$formula,$inBraces);\n\t\t\t}\n\t\t}\n\n\t\treturn $formula;\n\t}\n\n\tprivate static $functionReplaceFromExcel\t= NULL;\n\tprivate static $functionReplaceToLocale\t\t= NULL;\n\n\tpublic function _translateFormulaToLocale($formula) {\n\t\tif (self::$functionReplaceFromExcel === NULL) {\n\t\t\tself::$functionReplaceFromExcel = array();\n\t\t\tforeach(array_keys(self::$_localeFunctions) as $excelFunctionName) {\n\t\t\t\tself::$functionReplaceFromExcel[] = '/(@?[^\\w\\.])'.preg_quote($excelFunctionName).'([\\s]*\\()/Ui';\n\t\t\t}\n\t\t\tforeach(array_keys(self::$_localeBoolean) as $excelBoolean) {\n\t\t\t\tself::$functionReplaceFromExcel[] = '/(@?[^\\w\\.])'.preg_quote($excelBoolean).'([^\\w\\.])/Ui';\n\t\t\t}\n\n\t\t}\n\n\t\tif (self::$functionReplaceToLocale === NULL) {\n\t\t\tself::$functionReplaceToLocale = array();\n\t\t\tforeach(array_values(self::$_localeFunctions) as $localeFunctionName) {\n\t\t\t\tself::$functionReplaceToLocale[] = '$1'.trim($localeFunctionName).'$2';\n\t\t\t}\n\t\t\tforeach(array_values(self::$_localeBoolean) as $localeBoolean) {\n\t\t\t\tself::$functionReplaceToLocale[] = '$1'.trim($localeBoolean).'$2';\n\t\t\t}\n\t\t}\n\n\t\treturn self::_translateFormula(self::$functionReplaceFromExcel,self::$functionReplaceToLocale,$formula,',',self::$_localeArgumentSeparator);\n\t}\t//\tfunction _translateFormulaToLocale()\n\n\n\tprivate static $functionReplaceFromLocale\t= NULL;\n\tprivate static $functionReplaceToExcel\t\t= NULL;\n\n\tpublic function _translateFormulaToEnglish($formula) {\n\t\tif (self::$functionReplaceFromLocale === NULL) {\n\t\t\tself::$functionReplaceFromLocale = array();\n\t\t\tforeach(array_values(self::$_localeFunctions) as $localeFunctionName) {\n\t\t\t\tself::$functionReplaceFromLocale[] = '/(@?[^\\w\\.])'.preg_quote($localeFunctionName).'([\\s]*\\()/Ui';\n\t\t\t}\n\t\t\tforeach(array_values(self::$_localeBoolean) as $excelBoolean) {\n\t\t\t\tself::$functionReplaceFromLocale[] = '/(@?[^\\w\\.])'.preg_quote($excelBoolean).'([^\\w\\.])/Ui';\n\t\t\t}\n\t\t}\n\n\t\tif (self::$functionReplaceToExcel === NULL) {\n\t\t\tself::$functionReplaceToExcel = array();\n\t\t\tforeach(array_keys(self::$_localeFunctions) as $excelFunctionName) {\n\t\t\t\tself::$functionReplaceToExcel[] = '$1'.trim($excelFunctionName).'$2';\n\t\t\t}\n\t\t\tforeach(array_keys(self::$_localeBoolean) as $excelBoolean) {\n\t\t\t\tself::$functionReplaceToExcel[] = '$1'.trim($excelBoolean).'$2';\n\t\t\t}\n\t\t}\n\n\t\treturn self::_translateFormula(self::$functionReplaceFromLocale,self::$functionReplaceToExcel,$formula,self::$_localeArgumentSeparator,',');\n\t}\t//\tfunction _translateFormulaToEnglish()\n\n\n\tpublic static function _localeFunc($function) {\n\t\tif (self::$_localeLanguage !== 'en_us') {\n\t\t\t$functionName = trim($function,'(');\n\t\t\tif (isset(self::$_localeFunctions[$functionName])) {\n\t\t\t\t$brace = ($functionName != $function);\n\t\t\t\t$function = self::$_localeFunctions[$functionName];\n\t\t\t\tif ($brace) { $function .= '('; }\n\t\t\t}\n\t\t}\n\t\treturn $function;\n\t}\n\n\n\n\n\t/**\n\t * Wrap string values in quotes\n\t *\n\t * @param mixed $value\n\t * @return mixed\n\t */\n\tpublic static function _wrapResult($value) {\n\t\tif (is_string($value)) {\n\t\t\t//\tError values cannot be \"wrapped\"\n\t\t\tif (preg_match('/^'.self::CALCULATION_REGEXP_ERROR.'$/i', $value, $match)) {\n\t\t\t\t//\tReturn Excel errors \"as is\"\n\t\t\t\treturn $value;\n\t\t\t}\n\t\t\t//\tReturn strings wrapped in quotes\n\t\t\treturn '\"'.$value.'\"';\n\t\t//\tConvert numeric errors to NaN error\n\t\t} else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\n\t\treturn $value;\n\t}\t//\tfunction _wrapResult()\n\n\n\t/**\n\t * Remove quotes used as a wrapper to identify string values\n\t *\n\t * @param mixed $value\n\t * @return mixed\n\t */\n\tpublic static function _unwrapResult($value) {\n\t\tif (is_string($value)) {\n\t\t\tif ((isset($value{0})) && ($value{0} == '\"') && (substr($value,-1) == '\"')) {\n\t\t\t\treturn substr($value,1,-1);\n\t\t\t}\n\t\t//\tConvert numeric errors to NaN error\n\t\t} else if((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\treturn $value;\n\t}\t//\tfunction _unwrapResult()\n\n\n\n\n\t/**\n\t * Calculate cell value (using formula from a cell ID)\n\t * Retained for backward compatibility\n\t *\n\t * @access\tpublic\n\t * @param\tPHPExcel_Cell\t$pCell\tCell to calculate\n\t * @return\tmixed\n\t * @throws\tPHPExcel_Calculation_Exception\n\t */\n\tpublic function calculate(PHPExcel_Cell $pCell = NULL) {\n\t\ttry {\n\t\t\treturn $this->calculateCellValue($pCell);\n\t\t} catch (PHPExcel_Exception $e) {\n\t\t\tthrow new PHPExcel_Calculation_Exception($e->getMessage());\n\t\t}\n\t}\t//\tfunction calculate()\n\n\n\t/**\n\t * Calculate the value of a cell formula\n\t *\n\t * @access\tpublic\n\t * @param\tPHPExcel_Cell\t$pCell\t\tCell to calculate\n\t * @param\tBoolean\t\t\t$resetLog\tFlag indicating whether the debug log should be reset or not\n\t * @return\tmixed\n\t * @throws\tPHPExcel_Calculation_Exception\n\t */\n\tpublic function calculateCellValue(PHPExcel_Cell $pCell = NULL, $resetLog = TRUE) {\n\t\tif ($pCell === NULL) {\n\t\t\treturn NULL;\n\t\t}\n\n\t\t$returnArrayAsType = self::$returnArrayAsType;\n\t\tif ($resetLog) {\n\t\t\t//\tInitialise the logging settings if requested\n\t\t\t$this->formulaError = null;\n\t\t\t$this->_debugLog->clearLog();\n\t\t\t$this->_cyclicReferenceStack->clear();\n\t\t\t$this->_cyclicFormulaCount = 1;\n\n\t\t\tself::$returnArrayAsType = self::RETURN_ARRAY_AS_ARRAY;\n\t\t}\n\n\t\t//\tExecute the calculation for the cell formula\n        $this->_cellStack[] = array(\n            'sheet' => $pCell->getWorksheet()->getTitle(),\n            'cell' => $pCell->getCoordinate(),\n        );\n\t\ttry {\n\t\t\t$result = self::_unwrapResult($this->_calculateFormulaValue($pCell->getValue(), $pCell->getCoordinate(), $pCell));\n            $cellAddress = array_pop($this->_cellStack);\n            $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']);\n\t\t} catch (PHPExcel_Exception $e) {\n            $cellAddress = array_pop($this->_cellStack);\n            $this->_workbook->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']);\n\t\t\tthrow new PHPExcel_Calculation_Exception($e->getMessage());\n\t\t}\n\n\t\tif ((is_array($result)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) {\n\t\t\tself::$returnArrayAsType = $returnArrayAsType;\n\t\t\t$testResult = PHPExcel_Calculation_Functions::flattenArray($result);\n\t\t\tif (self::$returnArrayAsType == self::RETURN_ARRAY_AS_ERROR) {\n\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t}\n\t\t\t//\tIf there's only a single cell in the array, then we allow it\n\t\t\tif (count($testResult) != 1) {\n\t\t\t\t//\tIf keys are numeric, then it's a matrix result rather than a cell range result, so we permit it\n\t\t\t\t$r = array_keys($result);\n\t\t\t\t$r = array_shift($r);\n\t\t\t\tif (!is_numeric($r)) { return PHPExcel_Calculation_Functions::VALUE(); }\n\t\t\t\tif (is_array($result[$r])) {\n\t\t\t\t\t$c = array_keys($result[$r]);\n\t\t\t\t\t$c = array_shift($c);\n\t\t\t\t\tif (!is_numeric($c)) {\n\t\t\t\t\t\treturn PHPExcel_Calculation_Functions::VALUE();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t$result = array_shift($testResult);\n\t\t}\n\t\tself::$returnArrayAsType = $returnArrayAsType;\n\n\n\t\tif ($result === NULL) {\n\t\t\treturn 0;\n\t\t} elseif((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) {\n\t\t\treturn PHPExcel_Calculation_Functions::NaN();\n\t\t}\n\t\treturn $result;\n\t}\t//\tfunction calculateCellValue(\n\n\n\t/**\n\t * Validate and parse a formula string\n\t *\n\t * @param\tstring\t\t$formula\t\tFormula to parse\n\t * @return\tarray\n\t * @throws\tPHPExcel_Calculation_Exception\n\t */\n\tpublic function parseFormula($formula) {\n\t\t//\tBasic validation that this is indeed a formula\n\t\t//\tWe return an empty array if not\n\t\t$formula = trim($formula);\n\t\tif ((!isset($formula{0})) || ($formula{0} != '=')) return array();\n\t\t$formula = ltrim(substr($formula,1));\n\t\tif (!isset($formula{0})) return array();\n\n\t\t//\tParse the formula and return the token stack\n\t\treturn $this->_parseFormula($formula);\n\t}\t//\tfunction parseFormula()\n\n\n\t/**\n\t * Calculate the value of a formula\n\t *\n\t * @param\tstring\t\t\t$formula\tFormula to parse\n\t * @param\tstring\t\t\t$cellID\t\tAddress of the cell to calculate\n\t * @param\tPHPExcel_Cell\t$pCell\t\tCell to calculate\n\t * @return\tmixed\n\t * @throws\tPHPExcel_Calculation_Exception\n\t */\n\tpublic function calculateFormula($formula, $cellID=NULL, PHPExcel_Cell $pCell = NULL) {\n\t\t//\tInitialise the logging settings\n\t\t$this->formulaError = null;\n\t\t$this->_debugLog->clearLog();\n\t\t$this->_cyclicReferenceStack->clear();\n\n\t\t//\tDisable calculation cacheing because it only applies to cell calculations, not straight formulae\n\t\t//\tBut don't actually flush any cache\n\t\t$resetCache = $this->getCalculationCacheEnabled();\n\t\t$this->_calculationCacheEnabled = FALSE;\n\t\t//\tExecute the calculation\n\t\ttry {\n\t\t\t$result = self::_unwrapResult($this->_calculateFormulaValue($formula, $cellID, $pCell));\n\t\t} catch (PHPExcel_Exception $e) {\n\t\t\tthrow new PHPExcel_Calculation_Exception($e->getMessage());\n\t\t}\n\n\t\t//\tReset calculation cacheing to its previous state\n\t\t$this->_calculationCacheEnabled = $resetCache;\n\n\t\treturn $result;\n\t}\t//\tfunction calculateFormula()\n\n\n    public function getValueFromCache($cellReference, &$cellValue) {\n\t\t// Is calculation cacheing enabled?\n\t\t// Is the value present in calculation cache?\n\t\t$this->_debugLog->writeDebugLog('Testing cache value for cell ', $cellReference);\n\t\tif (($this->_calculationCacheEnabled) && (isset($this->_calculationCache[$cellReference]))) {\n\t\t\t$this->_debugLog->writeDebugLog('Retrieving value for cell ', $cellReference, ' from cache');\n\t\t\t// Return the cached result\n\t\t\t$cellValue = $this->_calculationCache[$cellReference];\n\t\t\treturn TRUE;\n\t\t}\n\t\treturn FALSE;\n    }\n\n    public function saveValueToCache($cellReference, $cellValue) {\n\t\tif ($this->_calculationCacheEnabled) {\n\t\t\t$this->_calculationCache[$cellReference] = $cellValue;\n\t\t}\n\t}\n\n\t/**\n\t * Parse a cell formula and calculate its value\n\t *\n\t * @param\tstring\t\t\t$formula\tThe formula to parse and calculate\n\t * @param\tstring\t\t\t$cellID\t\tThe ID (e.g. A3) of the cell that we are calculating\n\t * @param\tPHPExcel_Cell\t$pCell\t\tCell to calculate\n\t * @return\tmixed\n\t * @throws\tPHPExcel_Calculation_Exception\n\t */\n\tpublic function _calculateFormulaValue($formula, $cellID=null, PHPExcel_Cell $pCell = null) {\n\t\t$cellValue = null;\n\n\t\t//\tBasic validation that this is indeed a formula\n\t\t//\tWe simply return the cell value if not\n\t\t$formula = trim($formula);\n\t\tif ($formula{0} != '=') return self::_wrapResult($formula);\n\t\t$formula = ltrim(substr($formula, 1));\n\t\tif (!isset($formula{0})) return self::_wrapResult($formula);\n\n\t\t$pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;\n\t\t$wsTitle = ($pCellParent !== NULL) ? $pCellParent->getTitle() : \"\\x00Wrk\";\n        $wsCellReference = $wsTitle . '!' . $cellID;\n\n\t\tif (($cellID !== NULL) && ($this->getValueFromCache($wsCellReference, $cellValue))) {\n\t\t\treturn $cellValue;\n\t\t}\n\n\t\tif (($wsTitle{0} !== \"\\x00\") && ($this->_cyclicReferenceStack->onStack($wsCellReference))) {\n            if ($this->cyclicFormulaCount <= 0) {\n                $this->_cyclicFormulaCell = '';\n\t\t\t\treturn $this->_raiseFormulaError('Cyclic Reference in Formula');\n\t\t\t} elseif ($this->_cyclicFormulaCell === $wsCellReference) {\n\t\t\t\t++$this->_cyclicFormulaCount;\n\t\t\t\tif ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) {\n                    $this->_cyclicFormulaCell = '';\n\t\t\t\t\treturn $cellValue;\n\t\t\t\t}\n\t\t\t} elseif ($this->_cyclicFormulaCell == '') {\n\t\t\t\tif ($this->_cyclicFormulaCount >= $this->cyclicFormulaCount) {\n\t\t\t\t\treturn $cellValue;\n\t\t\t\t}\n\t\t\t\t$this->_cyclicFormulaCell = $wsCellReference;\n\t\t\t}\n\t\t}\n\n\t\t//\tParse the formula onto the token stack and calculate the value\n\t\t$this->_cyclicReferenceStack->push($wsCellReference);\n\t\t$cellValue = $this->_processTokenStack($this->_parseFormula($formula, $pCell), $cellID, $pCell);\n\t\t$this->_cyclicReferenceStack->pop();\n\n\t\t// Save to calculation cache\n\t\tif ($cellID !== NULL) {\n\t\t\t$this->saveValueToCache($wsCellReference, $cellValue);\n\t\t}\n\n\t\t//\tReturn the calculated value\n\t\treturn $cellValue;\n\t}\t//\tfunction _calculateFormulaValue()\n\n\n\t/**\n\t * Ensure that paired matrix operands are both matrices and of the same size\n\t *\n\t * @param\tmixed\t\t&$operand1\tFirst matrix operand\n\t * @param\tmixed\t\t&$operand2\tSecond matrix operand\n\t * @param\tinteger\t\t$resize\t\tFlag indicating whether the matrices should be resized to match\n\t *\t\t\t\t\t\t\t\t\t\tand (if so), whether the smaller dimension should grow or the\n\t *\t\t\t\t\t\t\t\t\t\tlarger should shrink.\n\t *\t\t\t\t\t\t\t\t\t\t\t0 = no resize\n\t *\t\t\t\t\t\t\t\t\t\t\t1 = shrink to fit\n\t *\t\t\t\t\t\t\t\t\t\t\t2 = extend to fit\n\t */\n\tprivate static function _checkMatrixOperands(&$operand1,&$operand2,$resize = 1) {\n\t\t//\tExamine each of the two operands, and turn them into an array if they aren't one already\n\t\t//\tNote that this function should only be called if one or both of the operand is already an array\n\t\tif (!is_array($operand1)) {\n\t\t\tlist($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand2);\n\t\t\t$operand1 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand1));\n\t\t\t$resize = 0;\n\t\t} elseif (!is_array($operand2)) {\n\t\t\tlist($matrixRows,$matrixColumns) = self::_getMatrixDimensions($operand1);\n\t\t\t$operand2 = array_fill(0,$matrixRows,array_fill(0,$matrixColumns,$operand2));\n\t\t\t$resize = 0;\n\t\t}\n\n\t\tlist($matrix1Rows,$matrix1Columns) = self::_getMatrixDimensions($operand1);\n\t\tlist($matrix2Rows,$matrix2Columns) = self::_getMatrixDimensions($operand2);\n\t\tif (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) {\n\t\t\t$resize = 1;\n\t\t}\n\n\t\tif ($resize == 2) {\n\t\t\t//\tGiven two matrices of (potentially) unequal size, convert the smaller in each dimension to match the larger\n\t\t\tself::_resizeMatricesExtend($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns);\n\t\t} elseif ($resize == 1) {\n\t\t\t//\tGiven two matrices of (potentially) unequal size, convert the larger in each dimension to match the smaller\n\t\t\tself::_resizeMatricesShrink($operand1,$operand2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns);\n\t\t}\n\t\treturn array( $matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns);\n\t}\t//\tfunction _checkMatrixOperands()\n\n\n\t/**\n\t * Read the dimensions of a matrix, and re-index it with straight numeric keys starting from row 0, column 0\n\t *\n\t * @param\tmixed\t\t&$matrix\t\tmatrix operand\n\t * @return\tarray\t\tAn array comprising the number of rows, and number of columns\n\t */\n\tpublic static function _getMatrixDimensions(&$matrix) {\n\t\t$matrixRows = count($matrix);\n\t\t$matrixColumns = 0;\n\t\tforeach($matrix as $rowKey => $rowValue) {\n\t\t\t$matrixColumns = max(count($rowValue),$matrixColumns);\n\t\t\tif (!is_array($rowValue)) {\n\t\t\t\t$matrix[$rowKey] = array($rowValue);\n\t\t\t} else {\n\t\t\t\t$matrix[$rowKey] = array_values($rowValue);\n\t\t\t}\n\t\t}\n\t\t$matrix = array_values($matrix);\n\t\treturn array($matrixRows,$matrixColumns);\n\t}\t//\tfunction _getMatrixDimensions()\n\n\n\t/**\n\t * Ensure that paired matrix operands are both matrices of the same size\n\t *\n\t * @param\tmixed\t\t&$matrix1\t\tFirst matrix operand\n\t * @param\tmixed\t\t&$matrix2\t\tSecond matrix operand\n\t * @param\tinteger\t\t$matrix1Rows\tRow size of first matrix operand\n\t * @param\tinteger\t\t$matrix1Columns\tColumn size of first matrix operand\n\t * @param\tinteger\t\t$matrix2Rows\tRow size of second matrix operand\n\t * @param\tinteger\t\t$matrix2Columns\tColumn size of second matrix operand\n\t */\n\tprivate static function _resizeMatricesShrink(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) {\n\t\tif (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) {\n\t\t\tif ($matrix2Rows < $matrix1Rows) {\n\t\t\t\tfor ($i = $matrix2Rows; $i < $matrix1Rows; ++$i) {\n\t\t\t\t\tunset($matrix1[$i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ($matrix2Columns < $matrix1Columns) {\n\t\t\t\tfor ($i = 0; $i < $matrix1Rows; ++$i) {\n\t\t\t\t\tfor ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) {\n\t\t\t\t\t\tunset($matrix1[$i][$j]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) {\n\t\t\tif ($matrix1Rows < $matrix2Rows) {\n\t\t\t\tfor ($i = $matrix1Rows; $i < $matrix2Rows; ++$i) {\n\t\t\t\t\tunset($matrix2[$i]);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ($matrix1Columns < $matrix2Columns) {\n\t\t\t\tfor ($i = 0; $i < $matrix2Rows; ++$i) {\n\t\t\t\t\tfor ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) {\n\t\t\t\t\t\tunset($matrix2[$i][$j]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\t//\tfunction _resizeMatricesShrink()\n\n\n\t/**\n\t * Ensure that paired matrix operands are both matrices of the same size\n\t *\n\t * @param\tmixed\t\t&$matrix1\tFirst matrix operand\n\t * @param\tmixed\t\t&$matrix2\tSecond matrix operand\n\t * @param\tinteger\t\t$matrix1Rows\tRow size of first matrix operand\n\t * @param\tinteger\t\t$matrix1Columns\tColumn size of first matrix operand\n\t * @param\tinteger\t\t$matrix2Rows\tRow size of second matrix operand\n\t * @param\tinteger\t\t$matrix2Columns\tColumn size of second matrix operand\n\t */\n\tprivate static function _resizeMatricesExtend(&$matrix1,&$matrix2,$matrix1Rows,$matrix1Columns,$matrix2Rows,$matrix2Columns) {\n\t\tif (($matrix2Columns < $matrix1Columns) || ($matrix2Rows < $matrix1Rows)) {\n\t\t\tif ($matrix2Columns < $matrix1Columns) {\n\t\t\t\tfor ($i = 0; $i < $matrix2Rows; ++$i) {\n\t\t\t\t\t$x = $matrix2[$i][$matrix2Columns-1];\n\t\t\t\t\tfor ($j = $matrix2Columns; $j < $matrix1Columns; ++$j) {\n\t\t\t\t\t\t$matrix2[$i][$j] = $x;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ($matrix2Rows < $matrix1Rows) {\n\t\t\t\t$x = $matrix2[$matrix2Rows-1];\n\t\t\t\tfor ($i = 0; $i < $matrix1Rows; ++$i) {\n\t\t\t\t\t$matrix2[$i] = $x;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (($matrix1Columns < $matrix2Columns) || ($matrix1Rows < $matrix2Rows)) {\n\t\t\tif ($matrix1Columns < $matrix2Columns) {\n\t\t\t\tfor ($i = 0; $i < $matrix1Rows; ++$i) {\n\t\t\t\t\t$x = $matrix1[$i][$matrix1Columns-1];\n\t\t\t\t\tfor ($j = $matrix1Columns; $j < $matrix2Columns; ++$j) {\n\t\t\t\t\t\t$matrix1[$i][$j] = $x;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ($matrix1Rows < $matrix2Rows) {\n\t\t\t\t$x = $matrix1[$matrix1Rows-1];\n\t\t\t\tfor ($i = 0; $i < $matrix2Rows; ++$i) {\n\t\t\t\t\t$matrix1[$i] = $x;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\t//\tfunction _resizeMatricesExtend()\n\n\n\t/**\n\t * Format details of an operand for display in the log (based on operand type)\n\t *\n\t * @param\tmixed\t\t$value\tFirst matrix operand\n\t * @return\tmixed\n\t */\n\tprivate function _showValue($value) {\n\t\tif ($this->_debugLog->getWriteDebugLog()) {\n\t\t\t$testArray = PHPExcel_Calculation_Functions::flattenArray($value);\n\t\t\tif (count($testArray) == 1) {\n\t\t\t\t$value = array_pop($testArray);\n\t\t\t}\n\n\t\t\tif (is_array($value)) {\n\t\t\t\t$returnMatrix = array();\n\t\t\t\t$pad = $rpad = ', ';\n\t\t\t\tforeach($value as $row) {\n\t\t\t\t\tif (is_array($row)) {\n\t\t\t\t\t\t$returnMatrix[] = implode($pad,array_map(array($this,'_showValue'),$row));\n\t\t\t\t\t\t$rpad = '; ';\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$returnMatrix[] = $this->_showValue($row);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn '{ '.implode($rpad,$returnMatrix).' }';\n\t\t\t} elseif(is_string($value) && (trim($value,'\"') == $value)) {\n\t\t\t\treturn '\"'.$value.'\"';\n\t\t\t} elseif(is_bool($value)) {\n\t\t\t\treturn ($value) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE'];\n\t\t\t}\n\t\t}\n\t\treturn PHPExcel_Calculation_Functions::flattenSingleValue($value);\n\t}\t//\tfunction _showValue()\n\n\n\t/**\n\t * Format type and details of an operand for display in the log (based on operand type)\n\t *\n\t * @param\tmixed\t\t$value\tFirst matrix operand\n\t * @return\tmixed\n\t */\n\tprivate function _showTypeDetails($value) {\n\t\tif ($this->_debugLog->getWriteDebugLog()) {\n\t\t\t$testArray = PHPExcel_Calculation_Functions::flattenArray($value);\n\t\t\tif (count($testArray) == 1) {\n\t\t\t\t$value = array_pop($testArray);\n\t\t\t}\n\n\t\t\tif ($value === NULL) {\n\t\t\t\treturn 'a NULL value';\n\t\t\t} elseif (is_float($value)) {\n\t\t\t\t$typeString = 'a floating point number';\n\t\t\t} elseif(is_int($value)) {\n\t\t\t\t$typeString = 'an integer number';\n\t\t\t} elseif(is_bool($value)) {\n\t\t\t\t$typeString = 'a boolean';\n\t\t\t} elseif(is_array($value)) {\n\t\t\t\t$typeString = 'a matrix';\n\t\t\t} else {\n\t\t\t\tif ($value == '') {\n\t\t\t\t\treturn 'an empty string';\n\t\t\t\t} elseif ($value{0} == '#') {\n\t\t\t\t\treturn 'a '.$value.' error';\n\t\t\t\t} else {\n\t\t\t\t\t$typeString = 'a string';\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $typeString.' with a value of '.$this->_showValue($value);\n\t\t}\n\t}\t//\tfunction _showTypeDetails()\n\n\n\tprivate function _convertMatrixReferences($formula) {\n\t\tstatic $matrixReplaceFrom = array('{',';','}');\n\t\tstatic $matrixReplaceTo = array('MKMATRIX(MKMATRIX(','),MKMATRIX(','))');\n\n\t\t//\tConvert any Excel matrix references to the MKMATRIX() function\n\t\tif (strpos($formula,'{') !== FALSE) {\n\t\t\t//\tIf there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators\n\t\t\tif (strpos($formula,'\"') !== FALSE) {\n\t\t\t\t//\tSo instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded\n\t\t\t\t//\t\tthe formula\n\t\t\t\t$temp = explode('\"',$formula);\n\t\t\t\t//\tOpen and Closed counts used for trapping mismatched braces in the formula\n\t\t\t\t$openCount = $closeCount = 0;\n\t\t\t\t$i = FALSE;\n\t\t\t\tforeach($temp as &$value) {\n\t\t\t\t\t//\tOnly count/replace in alternating array entries\n\t\t\t\t\tif ($i = !$i) {\n\t\t\t\t\t\t$openCount += substr_count($value,'{');\n\t\t\t\t\t\t$closeCount += substr_count($value,'}');\n\t\t\t\t\t\t$value = str_replace($matrixReplaceFrom,$matrixReplaceTo,$value);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tunset($value);\n\t\t\t\t//\tThen rebuild the formula string\n\t\t\t\t$formula = implode('\"',$temp);\n\t\t\t} else {\n\t\t\t\t//\tIf there's no quoted strings, then we do a simple count/replace\n\t\t\t\t$openCount = substr_count($formula,'{');\n\t\t\t\t$closeCount = substr_count($formula,'}');\n\t\t\t\t$formula = str_replace($matrixReplaceFrom,$matrixReplaceTo,$formula);\n\t\t\t}\n\t\t\t//\tTrap for mismatched braces and trigger an appropriate error\n\t\t\tif ($openCount < $closeCount) {\n\t\t\t\tif ($openCount > 0) {\n\t\t\t\t\treturn $this->_raiseFormulaError(\"Formula Error: Mismatched matrix braces '}'\");\n\t\t\t\t} else {\n\t\t\t\t\treturn $this->_raiseFormulaError(\"Formula Error: Unexpected '}' encountered\");\n\t\t\t\t}\n\t\t\t} elseif ($openCount > $closeCount) {\n\t\t\t\tif ($closeCount > 0) {\n\t\t\t\t\treturn $this->_raiseFormulaError(\"Formula Error: Mismatched matrix braces '{'\");\n\t\t\t\t} else {\n\t\t\t\t\treturn $this->_raiseFormulaError(\"Formula Error: Unexpected '{' encountered\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn $formula;\n\t}\t//\tfunction _convertMatrixReferences()\n\n\n\tprivate static function _mkMatrix() {\n\t\treturn func_get_args();\n\t}\t//\tfunction _mkMatrix()\n\n\n\t//\tBinary Operators\n\t//\tThese operators always work on two values\n\t//\tArray key is the operator, the value indicates whether this is a left or right associative operator\n\tprivate static $_operatorAssociativity\t= array(\n\t\t'^' => 0,\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//\tExponentiation\n\t\t'*' => 0, '/' => 0, \t\t\t\t\t\t\t\t\t\t\t\t//\tMultiplication and Division\n\t\t'+' => 0, '-' => 0,\t\t\t\t\t\t\t\t\t\t\t\t\t//\tAddition and Subtraction\n\t\t'&' => 0,\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//\tConcatenation\n\t\t'|' => 0, ':' => 0,\t\t\t\t\t\t\t\t\t\t\t\t\t//\tIntersect and Range\n\t\t'>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0\t\t//\tComparison\n\t);\n\n\t//\tComparison (Boolean) Operators\n\t//\tThese operators work on two values, but always return a boolean result\n\tprivate static $_comparisonOperators\t= array('>' => TRUE, '<' => TRUE, '=' => TRUE, '>=' => TRUE, '<=' => TRUE, '<>' => TRUE);\n\n\t//\tOperator Precedence\n\t//\tThis list includes all valid operators, whether binary (including boolean) or unary (such as %)\n\t//\tArray key is the operator, the value is its precedence\n\tprivate static $_operatorPrecedence\t= array(\n\t\t':' => 8,\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//\tRange\n\t\t'|' => 7,\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//\tIntersect\n\t\t'~' => 6,\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//\tNegation\n\t\t'%' => 5,\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//\tPercentage\n\t\t'^' => 4,\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//\tExponentiation\n\t\t'*' => 3, '/' => 3, \t\t\t\t\t\t\t\t\t\t\t\t\t//\tMultiplication and Division\n\t\t'+' => 2, '-' => 2,\t\t\t\t\t\t\t\t\t\t\t\t\t\t//\tAddition and Subtraction\n\t\t'&' => 1,\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t//\tConcatenation\n\t\t'>' => 0, '<' => 0, '=' => 0, '>=' => 0, '<=' => 0, '<>' => 0\t\t\t//\tComparison\n\t);\n\n\t// Convert infix to postfix notation\n\tprivate function _parseFormula($formula, PHPExcel_Cell $pCell = NULL) {\n\t\tif (($formula = $this->_convertMatrixReferences(trim($formula))) === FALSE) {\n\t\t\treturn FALSE;\n\t\t}\n\n\t\t//\tIf we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent worksheet),\n\t\t//\t\tso we store the parent worksheet so that we can re-attach it when necessary\n\t\t$pCellParent = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;\n\n\t\t$regexpMatchString = '/^('.self::CALCULATION_REGEXP_FUNCTION.\n\t\t\t\t\t\t\t   '|'.self::CALCULATION_REGEXP_CELLREF.\n\t\t\t\t\t\t\t   '|'.self::CALCULATION_REGEXP_NUMBER.\n\t\t\t\t\t\t\t   '|'.self::CALCULATION_REGEXP_STRING.\n\t\t\t\t\t\t\t   '|'.self::CALCULATION_REGEXP_OPENBRACE.\n\t\t\t\t\t\t\t   '|'.self::CALCULATION_REGEXP_NAMEDRANGE.\n\t\t\t\t\t\t\t   '|'.self::CALCULATION_REGEXP_ERROR.\n\t\t\t\t\t\t\t ')/si';\n\n\t\t//\tStart with initialisation\n\t\t$index = 0;\n\t\t$stack = new PHPExcel_Calculation_Token_Stack;\n\t\t$output = array();\n\t\t$expectingOperator = FALSE;\t\t\t\t\t//\tWe use this test in syntax-checking the expression to determine when a\n\t\t\t\t\t\t\t\t\t\t\t\t\t//\t\t- is a negation or + is a positive operator rather than an operation\n\t\t$expectingOperand = FALSE;\t\t\t\t\t//\tWe use this test in syntax-checking the expression to determine whether an operand\n\t\t\t\t\t\t\t\t\t\t\t\t\t//\t\tshould be null in a function call\n\t\t//\tThe guts of the lexical parser\n\t\t//\tLoop through the formula extracting each operator and operand in turn\n\t\twhile(TRUE) {\n//echo 'Assessing Expression '.substr($formula, $index),PHP_EOL;\n\t\t\t$opCharacter = $formula{$index};\t//\tGet the first character of the value at the current index position\n//echo 'Initial character of expression block is '.$opCharacter,PHP_EOL;\n\t\t\tif ((isset(self::$_comparisonOperators[$opCharacter])) && (strlen($formula) > $index) && (isset(self::$_comparisonOperators[$formula{$index+1}]))) {\n\t\t\t\t$opCharacter .= $formula{++$index};\n//echo 'Initial character of expression block is comparison operator '.$opCharacter.PHP_EOL;\n\t\t\t}\n\n\t\t\t//\tFind out if we're currently at the beginning of a number, variable, cell reference, function, parenthesis or operand\n\t\t\t$isOperandOrFunction = preg_match($regexpMatchString, substr($formula, $index), $match);\n//echo '$isOperandOrFunction is '.(($isOperandOrFunction) ? 'True' : 'False').PHP_EOL;\n//var_dump($match);\n\n\t\t\tif ($opCharacter == '-' && !$expectingOperator) {\t\t\t\t//\tIs it a negation instead of a minus?\n//echo 'Element is a Negation operator',PHP_EOL;\n\t\t\t\t$stack->push('Unary Operator','~');\t\t\t\t\t\t\t//\tPut a negation on the stack\n\t\t\t\t++$index;\t\t\t\t\t\t\t\t\t\t\t\t\t//\t\tand drop the negation symbol\n\t\t\t} elseif ($opCharacter == '%' && $expectingOperator) {\n//echo 'Element is a Percentage operator',PHP_EOL;\n\t\t\t\t$stack->push('Unary Operator','%');\t\t\t\t\t\t\t//\tPut a percentage on the stack\n\t\t\t\t++$index;\n\t\t\t} elseif ($opCharacter == '+' && !$expectingOperator) {\t\t\t//\tPositive (unary plus rather than binary operator plus) can be discarded?\n//echo 'Element is a Positive number, not Plus operator',PHP_EOL;\n\t\t\t\t++$index;\t\t\t\t\t\t\t\t\t\t\t\t\t//\tDrop the redundant plus symbol\n\t\t\t} elseif ((($opCharacter == '~') || ($opCharacter == '|')) && (!$isOperandOrFunction)) {\t//\tWe have to explicitly deny a tilde or pipe, because they are legal\n\t\t\t\treturn $this->_raiseFormulaError(\"Formula Error: Illegal character '~'\");\t\t\t\t//\t\ton the stack but not in the input expression\n\n\t\t\t} elseif ((isset(self::$_operators[$opCharacter]) or $isOperandOrFunction) && $expectingOperator) {\t//\tAre we putting an operator on the stack?\n//echo 'Element with value '.$opCharacter.' is an Operator',PHP_EOL;\n\t\t\t\twhile($stack->count() > 0 &&\n\t\t\t\t\t($o2 = $stack->last()) &&\n\t\t\t\t\tisset(self::$_operators[$o2['value']]) &&\n\t\t\t\t\t@(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) {\n\t\t\t\t\t$output[] = $stack->pop();\t\t\t\t\t\t\t\t//\tSwap operands and higher precedence operators from the stack to the output\n\t\t\t\t}\n\t\t\t\t$stack->push('Binary Operator',$opCharacter);\t//\tFinally put our current operator onto the stack\n\t\t\t\t++$index;\n\t\t\t\t$expectingOperator = FALSE;\n\n\t\t\t} elseif ($opCharacter == ')' && $expectingOperator) {\t\t\t//\tAre we expecting to close a parenthesis?\n//echo 'Element is a Closing bracket',PHP_EOL;\n\t\t\t\t$expectingOperand = FALSE;\n\t\t\t\twhile (($o2 = $stack->pop()) && $o2['value'] != '(') {\t\t//\tPop off the stack back to the last (\n\t\t\t\t\tif ($o2 === NULL) return $this->_raiseFormulaError('Formula Error: Unexpected closing brace \")\"');\n\t\t\t\t\telse $output[] = $o2;\n\t\t\t\t}\n\t\t\t\t$d = $stack->last(2);\n\t\t\t\tif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches)) {\t//\tDid this parenthesis just close a function?\n\t\t\t\t\t$functionName = $matches[1];\t\t\t\t\t\t\t\t\t\t//\tGet the function name\n//echo 'Closed Function is '.$functionName,PHP_EOL;\n\t\t\t\t\t$d = $stack->pop();\n\t\t\t\t\t$argumentCount = $d['value'];\t\t//\tSee how many arguments there were (argument count is the next value stored on the stack)\n//if ($argumentCount == 0) {\n//\techo 'With no arguments',PHP_EOL;\n//} elseif ($argumentCount == 1) {\n//\techo 'With 1 argument',PHP_EOL;\n//} else {\n//\techo 'With '.$argumentCount.' arguments',PHP_EOL;\n//}\n\t\t\t\t\t$output[] = $d;\t\t\t\t\t\t//\tDump the argument count on the output\n\t\t\t\t\t$output[] = $stack->pop();\t\t\t//\tPop the function and push onto the output\n\t\t\t\t\tif (isset(self::$_controlFunctions[$functionName])) {\n//echo 'Built-in function '.$functionName,PHP_EOL;\n\t\t\t\t\t\t$expectedArgumentCount = self::$_controlFunctions[$functionName]['argumentCount'];\n\t\t\t\t\t\t$functionCall = self::$_controlFunctions[$functionName]['functionCall'];\n\t\t\t\t\t} elseif (isset(self::$_PHPExcelFunctions[$functionName])) {\n//echo 'PHPExcel function '.$functionName,PHP_EOL;\n\t\t\t\t\t\t$expectedArgumentCount = self::$_PHPExcelFunctions[$functionName]['argumentCount'];\n\t\t\t\t\t\t$functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall'];\n\t\t\t\t\t} else {\t// did we somehow push a non-function on the stack? this should never happen\n\t\t\t\t\t\treturn $this->_raiseFormulaError(\"Formula Error: Internal error, non-function on stack\");\n\t\t\t\t\t}\n\t\t\t\t\t//\tCheck the argument count\n\t\t\t\t\t$argumentCountError = FALSE;\n\t\t\t\t\tif (is_numeric($expectedArgumentCount)) {\n\t\t\t\t\t\tif ($expectedArgumentCount < 0) {\n//echo '$expectedArgumentCount is between 0 and '.abs($expectedArgumentCount),PHP_EOL;\n\t\t\t\t\t\t\tif ($argumentCount > abs($expectedArgumentCount)) {\n\t\t\t\t\t\t\t\t$argumentCountError = TRUE;\n\t\t\t\t\t\t\t\t$expectedArgumentCountString = 'no more than '.abs($expectedArgumentCount);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n//echo '$expectedArgumentCount is numeric '.$expectedArgumentCount,PHP_EOL;\n\t\t\t\t\t\t\tif ($argumentCount != $expectedArgumentCount) {\n\t\t\t\t\t\t\t\t$argumentCountError = TRUE;\n\t\t\t\t\t\t\t\t$expectedArgumentCountString = $expectedArgumentCount;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} elseif ($expectedArgumentCount != '*') {\n\t\t\t\t\t\t$isOperandOrFunction = preg_match('/(\\d*)([-+,])(\\d*)/',$expectedArgumentCount,$argMatch);\n//print_r($argMatch);\n//echo PHP_EOL;\n\t\t\t\t\t\tswitch ($argMatch[2]) {\n\t\t\t\t\t\t\tcase '+' :\n\t\t\t\t\t\t\t\tif ($argumentCount < $argMatch[1]) {\n\t\t\t\t\t\t\t\t\t$argumentCountError = TRUE;\n\t\t\t\t\t\t\t\t\t$expectedArgumentCountString = $argMatch[1].' or more ';\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase '-' :\n\t\t\t\t\t\t\t\tif (($argumentCount < $argMatch[1]) || ($argumentCount > $argMatch[3])) {\n\t\t\t\t\t\t\t\t\t$argumentCountError = TRUE;\n\t\t\t\t\t\t\t\t\t$expectedArgumentCountString = 'between '.$argMatch[1].' and '.$argMatch[3];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase ',' :\n\t\t\t\t\t\t\t\tif (($argumentCount != $argMatch[1]) && ($argumentCount != $argMatch[3])) {\n\t\t\t\t\t\t\t\t\t$argumentCountError = TRUE;\n\t\t\t\t\t\t\t\t\t$expectedArgumentCountString = 'either '.$argMatch[1].' or '.$argMatch[3];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ($argumentCountError) {\n\t\t\t\t\t\treturn $this->_raiseFormulaError(\"Formula Error: Wrong number of arguments for $functionName() function: $argumentCount given, \".$expectedArgumentCountString.\" expected\");\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t++$index;\n\n\t\t\t} elseif ($opCharacter == ',') {\t\t\t//\tIs this the separator for function arguments?\n//echo 'Element is a Function argument separator',PHP_EOL;\n\t\t\t\twhile (($o2 = $stack->pop()) && $o2['value'] != '(') {\t\t//\tPop off the stack back to the last (\n\t\t\t\t\tif ($o2 === NULL) return $this->_raiseFormulaError(\"Formula Error: Unexpected ,\");\n\t\t\t\t\telse $output[] = $o2;\t// pop the argument expression stuff and push onto the output\n\t\t\t\t}\n\t\t\t\t//\tIf we've a comma when we're expecting an operand, then what we actually have is a null operand;\n\t\t\t\t//\t\tso push a null onto the stack\n\t\t\t\tif (($expectingOperand) || (!$expectingOperator)) {\n\t\t\t\t\t$output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL);\n\t\t\t\t}\n\t\t\t\t// make sure there was a function\n\t\t\t\t$d = $stack->last(2);\n\t\t\t\tif (!preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $d['value'], $matches))\n\t\t\t\t\treturn $this->_raiseFormulaError(\"Formula Error: Unexpected ,\");\n\t\t\t\t$d = $stack->pop();\n\t\t\t\t$stack->push($d['type'],++$d['value'],$d['reference']);\t// increment the argument count\n\t\t\t\t$stack->push('Brace', '(');\t// put the ( back on, we'll need to pop back to it again\n\t\t\t\t$expectingOperator = FALSE;\n\t\t\t\t$expectingOperand = TRUE;\n\t\t\t\t++$index;\n\n\t\t\t} elseif ($opCharacter == '(' && !$expectingOperator) {\n//\t\t\t\techo 'Element is an Opening Bracket<br />';\n\t\t\t\t$stack->push('Brace', '(');\n\t\t\t\t++$index;\n\n\t\t\t} elseif ($isOperandOrFunction && !$expectingOperator) {\t// do we now have a function/variable/number?\n\t\t\t\t$expectingOperator = TRUE;\n\t\t\t\t$expectingOperand = FALSE;\n\t\t\t\t$val = $match[1];\n\t\t\t\t$length = strlen($val);\n//\t\t\t\techo 'Element with value '.$val.' is an Operand, Variable, Constant, String, Number, Cell Reference or Function<br />';\n\n\t\t\t\tif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $val, $matches)) {\n\t\t\t\t\t$val = preg_replace('/\\s/u','',$val);\n//\t\t\t\t\techo 'Element '.$val.' is a Function<br />';\n\t\t\t\t\tif (isset(self::$_PHPExcelFunctions[strtoupper($matches[1])]) || isset(self::$_controlFunctions[strtoupper($matches[1])])) {\t// it's a function\n\t\t\t\t\t\t$stack->push('Function', strtoupper($val));\n\t\t\t\t\t\t$ax = preg_match('/^\\s*(\\s*\\))/ui', substr($formula, $index+$length), $amatch);\n\t\t\t\t\t\tif ($ax) {\n\t\t\t\t\t\t\t$stack->push('Operand Count for Function '.strtoupper($val).')', 0);\n\t\t\t\t\t\t\t$expectingOperator = TRUE;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$stack->push('Operand Count for Function '.strtoupper($val).')', 1);\n\t\t\t\t\t\t\t$expectingOperator = FALSE;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$stack->push('Brace', '(');\n\t\t\t\t\t} else {\t// it's a var w/ implicit multiplication\n\t\t\t\t\t\t$output[] = array('type' => 'Value', 'value' => $matches[1], 'reference' => NULL);\n\t\t\t\t\t}\n\t\t\t\t} elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $val, $matches)) {\n//\t\t\t\t\techo 'Element '.$val.' is a Cell reference<br />';\n\t\t\t\t\t//\tWatch for this case-change when modifying to allow cell references in different worksheets...\n\t\t\t\t\t//\tShould only be applied to the actual cell column, not the worksheet name\n\n\t\t\t\t\t//\tIf the last entry on the stack was a : operator, then we have a cell range reference\n\t\t\t\t\t$testPrevOp = $stack->last(1);\n\t\t\t\t\tif ($testPrevOp['value'] == ':') {\n\t\t\t\t\t\t//\tIf we have a worksheet reference, then we're playing with a 3D reference\n\t\t\t\t\t\tif ($matches[2] == '') {\n\t\t\t\t\t\t\t//\tOtherwise, we 'inherit' the worksheet reference from the start cell reference\n\t\t\t\t\t\t\t//\tThe start of the cell range reference should be the last entry in $output\n\t\t\t\t\t\t\t$startCellRef = $output[count($output)-1]['value'];\n\t\t\t\t\t\t\tpreg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $startCellRef, $startMatches);\n\t\t\t\t\t\t\tif ($startMatches[2] > '') {\n\t\t\t\t\t\t\t\t$val = $startMatches[2].'!'.$val;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\treturn $this->_raiseFormulaError(\"3D Range references are not yet supported\");\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$output[] = array('type' => 'Cell Reference', 'value' => $val, 'reference' => $val);\n//\t\t\t\t\t$expectingOperator = FALSE;\n\t\t\t\t} else {\t// it's a variable, constant, string, number or boolean\n//\t\t\t\t\techo 'Element is a Variable, Constant, String, Number or Boolean<br />';\n\t\t\t\t\t//\tIf the last entry on the stack was a : operator, then we may have a row or column range reference\n\t\t\t\t\t$testPrevOp = $stack->last(1);\n\t\t\t\t\tif ($testPrevOp['value'] == ':') {\n\t\t\t\t\t\t$startRowColRef = $output[count($output)-1]['value'];\n\t\t\t\t\t\t$rangeWS1 = '';\n\t\t\t\t\t\tif (strpos('!',$startRowColRef) !== FALSE) {\n\t\t\t\t\t\t\tlist($rangeWS1,$startRowColRef) = explode('!',$startRowColRef);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ($rangeWS1 != '') $rangeWS1 .= '!';\n\t\t\t\t\t\t$rangeWS2 = $rangeWS1;\n\t\t\t\t\t\tif (strpos('!',$val) !== FALSE) {\n\t\t\t\t\t\t\tlist($rangeWS2,$val) = explode('!',$val);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ($rangeWS2 != '') $rangeWS2 .= '!';\n\t\t\t\t\t\tif ((is_integer($startRowColRef)) && (ctype_digit($val)) &&\n\t\t\t\t\t\t\t($startRowColRef <= 1048576) && ($val <= 1048576)) {\n\t\t\t\t\t\t\t//\tRow range\n\t\t\t\t\t\t\t$endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestColumn() : 'XFD';\t//\tMax 16,384 columns for Excel2007\n\t\t\t\t\t\t\t$output[count($output)-1]['value'] = $rangeWS1.'A'.$startRowColRef;\n\t\t\t\t\t\t\t$val = $rangeWS2.$endRowColRef.$val;\n\t\t\t\t\t\t} elseif ((ctype_alpha($startRowColRef)) && (ctype_alpha($val)) &&\n\t\t\t\t\t\t\t(strlen($startRowColRef) <= 3) && (strlen($val) <= 3)) {\n\t\t\t\t\t\t\t//\tColumn range\n\t\t\t\t\t\t\t$endRowColRef = ($pCellParent !== NULL) ? $pCellParent->getHighestRow() : 1048576;\t\t//\tMax 1,048,576 rows for Excel2007\n\t\t\t\t\t\t\t$output[count($output)-1]['value'] = $rangeWS1.strtoupper($startRowColRef).'1';\n\t\t\t\t\t\t\t$val = $rangeWS2.$val.$endRowColRef;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$localeConstant = FALSE;\n\t\t\t\t\tif ($opCharacter == '\"') {\n//\t\t\t\t\t\techo 'Element is a String<br />';\n\t\t\t\t\t\t//\tUnEscape any quotes within the string\n\t\t\t\t\t\t$val = self::_wrapResult(str_replace('\"\"','\"',self::_unwrapResult($val)));\n\t\t\t\t\t} elseif (is_numeric($val)) {\n//\t\t\t\t\t\techo 'Element is a Number<br />';\n\t\t\t\t\t\tif ((strpos($val,'.') !== FALSE) || (stripos($val,'e') !== FALSE) || ($val > PHP_INT_MAX) || ($val < -PHP_INT_MAX)) {\n//\t\t\t\t\t\t\techo 'Casting '.$val.' to float<br />';\n\t\t\t\t\t\t\t$val = (float) $val;\n\t\t\t\t\t\t} else {\n//\t\t\t\t\t\t\techo 'Casting '.$val.' to integer<br />';\n\t\t\t\t\t\t\t$val = (integer) $val;\n\t\t\t\t\t\t}\n\t\t\t\t\t} elseif (isset(self::$_ExcelConstants[trim(strtoupper($val))])) {\n\t\t\t\t\t\t$excelConstant = trim(strtoupper($val));\n//\t\t\t\t\t\techo 'Element '.$excelConstant.' is an Excel Constant<br />';\n\t\t\t\t\t\t$val = self::$_ExcelConstants[$excelConstant];\n\t\t\t\t\t} elseif (($localeConstant = array_search(trim(strtoupper($val)), self::$_localeBoolean)) !== FALSE) {\n//\t\t\t\t\t\techo 'Element '.$localeConstant.' is an Excel Constant<br />';\n\t\t\t\t\t\t$val = self::$_ExcelConstants[$localeConstant];\n\t\t\t\t\t}\n\t\t\t\t\t$details = array('type' => 'Value', 'value' => $val, 'reference' => NULL);\n\t\t\t\t\tif ($localeConstant) { $details['localeValue'] = $localeConstant; }\n\t\t\t\t\t$output[] = $details;\n\t\t\t\t}\n\t\t\t\t$index += $length;\n\n\t\t\t} elseif ($opCharacter == '$') {\t// absolute row or column range\n\t\t\t\t++$index;\n\t\t\t} elseif ($opCharacter == ')') {\t// miscellaneous error checking\n\t\t\t\tif ($expectingOperand) {\n\t\t\t\t\t$output[] = array('type' => 'NULL Value', 'value' => self::$_ExcelConstants['NULL'], 'reference' => NULL);\n\t\t\t\t\t$expectingOperand = FALSE;\n\t\t\t\t\t$expectingOperator = TRUE;\n\t\t\t\t} else {\n\t\t\t\t\treturn $this->_raiseFormulaError(\"Formula Error: Unexpected ')'\");\n\t\t\t\t}\n\t\t\t} elseif (isset(self::$_operators[$opCharacter]) && !$expectingOperator) {\n\t\t\t\treturn $this->_raiseFormulaError(\"Formula Error: Unexpected operator '$opCharacter'\");\n\t\t\t} else {\t// I don't even want to know what you did to get here\n\t\t\t\treturn $this->_raiseFormulaError(\"Formula Error: An unexpected error occured\");\n\t\t\t}\n\t\t\t//\tTest for end of formula string\n\t\t\tif ($index == strlen($formula)) {\n\t\t\t\t//\tDid we end with an operator?.\n\t\t\t\t//\tOnly valid for the % unary operator\n\t\t\t\tif ((isset(self::$_operators[$opCharacter])) && ($opCharacter != '%')) {\n\t\t\t\t\treturn $this->_raiseFormulaError(\"Formula Error: Operator '$opCharacter' has no operands\");\n\t\t\t\t} else {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t//\tIgnore white space\n\t\t\twhile (($formula{$index} == \"\\n\") || ($formula{$index} == \"\\r\")) {\n\t\t\t\t++$index;\n\t\t\t}\n\t\t\tif ($formula{$index} == ' ') {\n\t\t\t\twhile ($formula{$index} == ' ') {\n\t\t\t\t\t++$index;\n\t\t\t\t}\n\t\t\t\t//\tIf we're expecting an operator, but only have a space between the previous and next operands (and both are\n\t\t\t\t//\t\tCell References) then we have an INTERSECTION operator\n//\t\t\t\techo 'Possible Intersect Operator<br />';\n\t\t\t\tif (($expectingOperator) && (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'.*/Ui', substr($formula, $index), $match)) &&\n\t\t\t\t\t($output[count($output)-1]['type'] == 'Cell Reference')) {\n//\t\t\t\t\techo 'Element is an Intersect Operator<br />';\n\t\t\t\t\twhile($stack->count() > 0 &&\n\t\t\t\t\t\t($o2 = $stack->last()) &&\n\t\t\t\t\t\tisset(self::$_operators[$o2['value']]) &&\n\t\t\t\t\t\t@(self::$_operatorAssociativity[$opCharacter] ? self::$_operatorPrecedence[$opCharacter] < self::$_operatorPrecedence[$o2['value']] : self::$_operatorPrecedence[$opCharacter] <= self::$_operatorPrecedence[$o2['value']])) {\n\t\t\t\t\t\t$output[] = $stack->pop();\t\t\t\t\t\t\t\t//\tSwap operands and higher precedence operators from the stack to the output\n\t\t\t\t\t}\n\t\t\t\t\t$stack->push('Binary Operator','|');\t//\tPut an Intersect Operator on the stack\n\t\t\t\t\t$expectingOperator = FALSE;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\twhile (($op = $stack->pop()) !== NULL) {\t// pop everything off the stack and push onto output\n\t\t\tif ((is_array($op) && $op['value'] == '(') || ($op === '('))\n\t\t\t\treturn $this->_raiseFormulaError(\"Formula Error: Expecting ')'\");\t// if there are any opening braces on the stack, then braces were unbalanced\n\t\t\t$output[] = $op;\n\t\t}\n\t\treturn $output;\n\t}\t//\tfunction _parseFormula()\n\n\n\tprivate static function _dataTestReference(&$operandData)\n\t{\n\t\t$operand = $operandData['value'];\n\t\tif (($operandData['reference'] === NULL) && (is_array($operand))) {\n\t\t\t$rKeys = array_keys($operand);\n\t\t\t$rowKey = array_shift($rKeys);\n\t\t\t$cKeys = array_keys(array_keys($operand[$rowKey]));\n\t\t\t$colKey = array_shift($cKeys);\n\t\t\tif (ctype_upper($colKey)) {\n\t\t\t\t$operandData['reference'] = $colKey.$rowKey;\n\t\t\t}\n\t\t}\n\t\treturn $operand;\n\t}\n\n\t// evaluate postfix notation\n\tprivate function _processTokenStack($tokens, $cellID = NULL, PHPExcel_Cell $pCell = NULL) {\n\t\tif ($tokens == FALSE) return FALSE;\n\n\t\t//\tIf we're using cell caching, then $pCell may well be flushed back to the cache (which detaches the parent cell collection),\n\t\t//\t\tso we store the parent cell collection so that we can re-attach it when necessary\n\t\t$pCellWorksheet = ($pCell !== NULL) ? $pCell->getWorksheet() : NULL;\n\t\t$pCellParent = ($pCell !== NULL) ? $pCell->getParent() : null;\n\t\t$stack = new PHPExcel_Calculation_Token_Stack;\n\n\t\t//\tLoop through each token in turn\n\t\tforeach ($tokens as $tokenData) {\n//\t\t\tprint_r($tokenData);\n//\t\t\techo '<br />';\n\t\t\t$token = $tokenData['value'];\n//\t\t\techo '<b>Token is '.$token.'</b><br />';\n\t\t\t// if the token is a binary operator, pop the top two values off the stack, do the operation, and push the result back on the stack\n\t\t\tif (isset(self::$_binaryOperators[$token])) {\n//\t\t\t\techo 'Token is a binary operator<br />';\n\t\t\t\t//\tWe must have two operands, error if we don't\n\t\t\t\tif (($operand2Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack');\n\t\t\t\tif (($operand1Data = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack');\n\n\t\t\t\t$operand1 = self::_dataTestReference($operand1Data);\n\t\t\t\t$operand2 = self::_dataTestReference($operand2Data);\n\n\t\t\t\t//\tLog what we're doing\n\t\t\t\tif ($token == ':') {\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating Range ', $this->_showValue($operand1Data['reference']), ' ', $token, ' ', $this->_showValue($operand2Data['reference']));\n\t\t\t\t} else {\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating ', $this->_showValue($operand1), ' ', $token, ' ', $this->_showValue($operand2));\n\t\t\t\t}\n\n\t\t\t\t//\tProcess the operation in the appropriate manner\n\t\t\t\tswitch ($token) {\n\t\t\t\t\t//\tComparison (Boolean) Operators\n\t\t\t\t\tcase '>'\t:\t\t\t//\tGreater than\n\t\t\t\t\tcase '<'\t:\t\t\t//\tLess than\n\t\t\t\t\tcase '>='\t:\t\t\t//\tGreater than or Equal to\n\t\t\t\t\tcase '<='\t:\t\t\t//\tLess than or Equal to\n\t\t\t\t\tcase '='\t:\t\t\t//\tEquality\n\t\t\t\t\tcase '<>'\t:\t\t\t//\tInequality\n\t\t\t\t\t\t$this->_executeBinaryComparisonOperation($cellID,$operand1,$operand2,$token,$stack);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t//\tBinary Operators\n\t\t\t\t\tcase ':'\t:\t\t\t//\tRange\n\t\t\t\t\t\t$sheet1 = $sheet2 = '';\n\t\t\t\t\t\tif (strpos($operand1Data['reference'],'!') !== FALSE) {\n\t\t\t\t\t\t\tlist($sheet1,$operand1Data['reference']) = explode('!',$operand1Data['reference']);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$sheet1 = ($pCellParent !== NULL) ? $pCellWorksheet->getTitle() : '';\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (strpos($operand2Data['reference'],'!') !== FALSE) {\n\t\t\t\t\t\t\tlist($sheet2,$operand2Data['reference']) = explode('!',$operand2Data['reference']);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$sheet2 = $sheet1;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ($sheet1 == $sheet2) {\n\t\t\t\t\t\t\tif ($operand1Data['reference'] === NULL) {\n\t\t\t\t\t\t\t\tif ((trim($operand1Data['value']) != '') && (is_numeric($operand1Data['value']))) {\n\t\t\t\t\t\t\t\t\t$operand1Data['reference'] = $pCell->getColumn().$operand1Data['value'];\n\t\t\t\t\t\t\t\t} elseif (trim($operand1Data['reference']) == '') {\n\t\t\t\t\t\t\t\t\t$operand1Data['reference'] = $pCell->getCoordinate();\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$operand1Data['reference'] = $operand1Data['value'].$pCell->getRow();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ($operand2Data['reference'] === NULL) {\n\t\t\t\t\t\t\t\tif ((trim($operand2Data['value']) != '') && (is_numeric($operand2Data['value']))) {\n\t\t\t\t\t\t\t\t\t$operand2Data['reference'] = $pCell->getColumn().$operand2Data['value'];\n\t\t\t\t\t\t\t\t} elseif (trim($operand2Data['reference']) == '') {\n\t\t\t\t\t\t\t\t\t$operand2Data['reference'] = $pCell->getCoordinate();\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$operand2Data['reference'] = $operand2Data['value'].$pCell->getRow();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t$oData = array_merge(explode(':',$operand1Data['reference']),explode(':',$operand2Data['reference']));\n\t\t\t\t\t\t\t$oCol = $oRow = array();\n\t\t\t\t\t\t\tforeach($oData as $oDatum) {\n\t\t\t\t\t\t\t\t$oCR = PHPExcel_Cell::coordinateFromString($oDatum);\n\t\t\t\t\t\t\t\t$oCol[] = PHPExcel_Cell::columnIndexFromString($oCR[0]) - 1;\n\t\t\t\t\t\t\t\t$oRow[] = $oCR[1];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow);\n\t\t\t\t\t\t\tif ($pCellParent !== NULL) {\n\t\t\t\t\t\t\t\t$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($sheet1), FALSE);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn $this->_raiseFormulaError('Unable to access Cell Reference');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$stack->push('Cell Reference',$cellValue,$cellRef);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$stack->push('Error',PHPExcel_Calculation_Functions::REF(),NULL);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '+'\t:\t\t\t//\tAddition\n\t\t\t\t\t\t$this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'plusEquals',$stack);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '-'\t:\t\t\t//\tSubtraction\n\t\t\t\t\t\t$this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'minusEquals',$stack);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '*'\t:\t\t\t//\tMultiplication\n\t\t\t\t\t\t$this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayTimesEquals',$stack);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '/'\t:\t\t\t//\tDivision\n\t\t\t\t\t\t$this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'arrayRightDivide',$stack);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '^'\t:\t\t\t//\tExponential\n\t\t\t\t\t\t$this->_executeNumericBinaryOperation($cellID,$operand1,$operand2,$token,'power',$stack);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '&'\t:\t\t\t//\tConcatenation\n\t\t\t\t\t\t//\tIf either of the operands is a matrix, we need to treat them both as matrices\n\t\t\t\t\t\t//\t\t(converting the other operand to a matrix if need be); then perform the required\n\t\t\t\t\t\t//\t\tmatrix operation\n\t\t\t\t\t\tif (is_bool($operand1)) {\n\t\t\t\t\t\t\t$operand1 = ($operand1) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE'];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (is_bool($operand2)) {\n\t\t\t\t\t\t\t$operand2 = ($operand2) ? self::$_localeBoolean['TRUE'] : self::$_localeBoolean['FALSE'];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ((is_array($operand1)) || (is_array($operand2))) {\n\t\t\t\t\t\t\t//\tEnsure that both operands are arrays/matrices\n\t\t\t\t\t\t\tself::_checkMatrixOperands($operand1,$operand2,2);\n\t\t\t\t\t\t\ttry {\n\t\t\t\t\t\t\t\t//\tConvert operand 1 from a PHP array to a matrix\n\t\t\t\t\t\t\t\t$matrix = new PHPExcel_Shared_JAMA_Matrix($operand1);\n\t\t\t\t\t\t\t\t//\tPerform the required operation against the operand 1 matrix, passing in operand 2\n\t\t\t\t\t\t\t\t$matrixResult = $matrix->concat($operand2);\n\t\t\t\t\t\t\t\t$result = $matrixResult->getArray();\n\t\t\t\t\t\t\t} catch (PHPExcel_Exception $ex) {\n\t\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage());\n\t\t\t\t\t\t\t\t$result = '#VALUE!';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$result = '\"'.str_replace('\"\"','\"',self::_unwrapResult($operand1,'\"').self::_unwrapResult($operand2,'\"')).'\"';\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result));\n\t\t\t\t\t\t$stack->push('Value',$result);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase '|'\t:\t\t\t//\tIntersect\n\t\t\t\t\t\t$rowIntersect = array_intersect_key($operand1,$operand2);\n\t\t\t\t\t\t$cellIntersect = $oCol = $oRow = array();\n\t\t\t\t\t\tforeach(array_keys($rowIntersect) as $row) {\n\t\t\t\t\t\t\t$oRow[] = $row;\n\t\t\t\t\t\t\tforeach($rowIntersect[$row] as $col => $data) {\n\t\t\t\t\t\t\t\t$oCol[] = PHPExcel_Cell::columnIndexFromString($col) - 1;\n\t\t\t\t\t\t\t\t$cellIntersect[$row] = array_intersect_key($operand1[$row],$operand2[$row]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$cellRef = PHPExcel_Cell::stringFromColumnIndex(min($oCol)).min($oRow).':'.PHPExcel_Cell::stringFromColumnIndex(max($oCol)).max($oRow);\n\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($cellIntersect));\n\t\t\t\t\t\t$stack->push('Value',$cellIntersect,$cellRef);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\n\t\t\t// if the token is a unary operator, pop one value off the stack, do the operation, and push it back on\n\t\t\t} elseif (($token === '~') || ($token === '%')) {\n//\t\t\t\techo 'Token is a unary operator<br />';\n\t\t\t\tif (($arg = $stack->pop()) === NULL) return $this->_raiseFormulaError('Internal error - Operand value missing from stack');\n\t\t\t\t$arg = $arg['value'];\n\t\t\t\tif ($token === '~') {\n//\t\t\t\t\techo 'Token is a negation operator<br />';\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating Negation of ', $this->_showValue($arg));\n\t\t\t\t\t$multiplier = -1;\n\t\t\t\t} else {\n//\t\t\t\t\techo 'Token is a percentile operator<br />';\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating Percentile of ', $this->_showValue($arg));\n\t\t\t\t\t$multiplier = 0.01;\n\t\t\t\t}\n\t\t\t\tif (is_array($arg)) {\n\t\t\t\t\tself::_checkMatrixOperands($arg,$multiplier,2);\n\t\t\t\t\ttry {\n\t\t\t\t\t\t$matrix1 = new PHPExcel_Shared_JAMA_Matrix($arg);\n\t\t\t\t\t\t$matrixResult = $matrix1->arrayTimesEquals($multiplier);\n\t\t\t\t\t\t$result = $matrixResult->getArray();\n\t\t\t\t\t} catch (PHPExcel_Exception $ex) {\n\t\t\t\t\t\t$this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage());\n\t\t\t\t\t\t$result = '#VALUE!';\n\t\t\t\t\t}\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result));\n\t\t\t\t\t$stack->push('Value',$result);\n\t\t\t\t} else {\n\t\t\t\t\t$this->_executeNumericBinaryOperation($cellID,$multiplier,$arg,'*','arrayTimesEquals',$stack);\n\t\t\t\t}\n\n\t\t\t} elseif (preg_match('/^'.self::CALCULATION_REGEXP_CELLREF.'$/i', $token, $matches)) {\n\t\t\t\t$cellRef = NULL;\n//\t\t\t\techo 'Element '.$token.' is a Cell reference<br />';\n\t\t\t\tif (isset($matches[8])) {\n//\t\t\t\t\techo 'Reference is a Range of cells<br />';\n\t\t\t\t\tif ($pCell === NULL) {\n//\t\t\t\t\t\tWe can't access the range, so return a REF error\n\t\t\t\t\t\t$cellValue = PHPExcel_Calculation_Functions::REF();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$cellRef = $matches[6].$matches[7].':'.$matches[9].$matches[10];\n\t\t\t\t\t\tif ($matches[2] > '') {\n\t\t\t\t\t\t\t$matches[2] = trim($matches[2],\"\\\"'\");\n\t\t\t\t\t\t\tif ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) {\n\t\t\t\t\t\t\t\t//\tIt's a Reference to an external workbook (not currently supported)\n\t\t\t\t\t\t\t\treturn $this->_raiseFormulaError('Unable to access External Workbook');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$matches[2] = trim($matches[2],\"\\\"'\");\n//\t\t\t\t\t\t\techo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />';\n\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in worksheet ', $matches[2]);\n\t\t\t\t\t\t\tif ($pCellParent !== NULL) {\n\t\t\t\t\t\t\t\t$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn $this->_raiseFormulaError('Unable to access Cell Reference');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue));\n//\t\t\t\t\t\t\t$cellRef = $matches[2].'!'.$cellRef;\n\t\t\t\t\t\t} else {\n//\t\t\t\t\t\t\techo '$cellRef='.$cellRef.' in current worksheet<br />';\n\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating Cell Range ', $cellRef, ' in current worksheet');\n\t\t\t\t\t\t\tif ($pCellParent !== NULL) {\n\t\t\t\t\t\t\t\t$cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn $this->_raiseFormulaError('Unable to access Cell Reference');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result for cells ', $cellRef, ' is ', $this->_showTypeDetails($cellValue));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t} else {\n//\t\t\t\t\techo 'Reference is a single Cell<br />';\n\t\t\t\t\tif ($pCell === NULL) {\n//\t\t\t\t\t\tWe can't access the cell, so return a REF error\n\t\t\t\t\t\t$cellValue = PHPExcel_Calculation_Functions::REF();\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$cellRef = $matches[6].$matches[7];\n\t\t\t\t\t\tif ($matches[2] > '') {\n\t\t\t\t\t\t\t$matches[2] = trim($matches[2],\"\\\"'\");\n\t\t\t\t\t\t\tif ((strpos($matches[2],'[') !== FALSE) || (strpos($matches[2],']') !== FALSE)) {\n\t\t\t\t\t\t\t\t//\tIt's a Reference to an external workbook (not currently supported)\n\t\t\t\t\t\t\t\treturn $this->_raiseFormulaError('Unable to access External Workbook');\n\t\t\t\t\t\t\t}\n//\t\t\t\t\t\t\techo '$cellRef='.$cellRef.' in worksheet '.$matches[2].'<br />';\n\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in worksheet ', $matches[2]);\n\t\t\t\t\t\t\tif ($pCellParent !== NULL) {\n\t\t\t\t\t\t\t\t$cellSheet = $this->_workbook->getSheetByName($matches[2]);\n\t\t\t\t\t\t\t\tif ($cellSheet && $cellSheet->cellExists($cellRef)) {\n\t\t\t\t\t\t\t\t\t$cellValue = $this->extractCellRange($cellRef, $this->_workbook->getSheetByName($matches[2]), FALSE);\n\t\t\t\t\t\t\t\t\t$pCell->attach($pCellParent);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$cellValue = NULL;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\treturn $this->_raiseFormulaError('Unable to access Cell Reference');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' in worksheet ', $matches[2], ' is ', $this->_showTypeDetails($cellValue));\n//\t\t\t\t\t\t\t$cellRef = $matches[2].'!'.$cellRef;\n\t\t\t\t\t\t} else {\n//\t\t\t\t\t\t\techo '$cellRef='.$cellRef.' in current worksheet<br />';\n\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating Cell ', $cellRef, ' in current worksheet');\n\t\t\t\t\t\t\tif ($pCellParent->isDataSet($cellRef)) {\n\t\t\t\t\t\t\t\t$cellValue = $this->extractCellRange($cellRef, $pCellWorksheet, FALSE);\n\t\t\t\t\t\t\t\t$pCell->attach($pCellParent);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t$cellValue = NULL;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result for cell ', $cellRef, ' is ', $this->_showTypeDetails($cellValue));\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$stack->push('Value',$cellValue,$cellRef);\n\n\t\t\t// if the token is a function, pop arguments off the stack, hand them to the function, and push the result back on\n\t\t\t} elseif (preg_match('/^'.self::CALCULATION_REGEXP_FUNCTION.'$/i', $token, $matches)) {\n//\t\t\t\techo 'Token is a function<br />';\n\t\t\t\t$functionName = $matches[1];\n\t\t\t\t$argCount = $stack->pop();\n\t\t\t\t$argCount = $argCount['value'];\n\t\t\t\tif ($functionName != 'MKMATRIX') {\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating Function ', self::_localeFunc($functionName), '() with ', (($argCount == 0) ? 'no' : $argCount), ' argument', (($argCount == 1) ? '' : 's'));\n\t\t\t\t}\n\t\t\t\tif ((isset(self::$_PHPExcelFunctions[$functionName])) || (isset(self::$_controlFunctions[$functionName]))) {\t// function\n\t\t\t\t\tif (isset(self::$_PHPExcelFunctions[$functionName])) {\n\t\t\t\t\t\t$functionCall = self::$_PHPExcelFunctions[$functionName]['functionCall'];\n\t\t\t\t\t\t$passByReference = isset(self::$_PHPExcelFunctions[$functionName]['passByReference']);\n\t\t\t\t\t\t$passCellReference = isset(self::$_PHPExcelFunctions[$functionName]['passCellReference']);\n\t\t\t\t\t} elseif (isset(self::$_controlFunctions[$functionName])) {\n\t\t\t\t\t\t$functionCall = self::$_controlFunctions[$functionName]['functionCall'];\n\t\t\t\t\t\t$passByReference = isset(self::$_controlFunctions[$functionName]['passByReference']);\n\t\t\t\t\t\t$passCellReference = isset(self::$_controlFunctions[$functionName]['passCellReference']);\n\t\t\t\t\t}\n\t\t\t\t\t// get the arguments for this function\n//\t\t\t\t\techo 'Function '.$functionName.' expects '.$argCount.' arguments<br />';\n\t\t\t\t\t$args = $argArrayVals = array();\n\t\t\t\t\tfor ($i = 0; $i < $argCount; ++$i) {\n\t\t\t\t\t\t$arg = $stack->pop();\n\t\t\t\t\t\t$a = $argCount - $i - 1;\n\t\t\t\t\t\tif (($passByReference) &&\n\t\t\t\t\t\t\t(isset(self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) &&\n\t\t\t\t\t\t\t(self::$_PHPExcelFunctions[$functionName]['passByReference'][$a])) {\n\t\t\t\t\t\t\tif ($arg['reference'] === NULL) {\n\t\t\t\t\t\t\t\t$args[] = $cellID;\n\t\t\t\t\t\t\t\tif ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($cellID); }\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t$args[] = $arg['reference'];\n\t\t\t\t\t\t\t\tif ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['reference']); }\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$args[] = self::_unwrapResult($arg['value']);\n\t\t\t\t\t\t\tif ($functionName != 'MKMATRIX') { $argArrayVals[] = $this->_showValue($arg['value']); }\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t//\tReverse the order of the arguments\n\t\t\t\t\tkrsort($args);\n\t\t\t\t\tif (($passByReference) && ($argCount == 0)) {\n\t\t\t\t\t\t$args[] = $cellID;\n\t\t\t\t\t\t$argArrayVals[] = $this->_showValue($cellID);\n\t\t\t\t\t}\n//\t\t\t\t\techo 'Arguments are: ';\n//\t\t\t\t\tprint_r($args);\n//\t\t\t\t\techo '<br />';\n\t\t\t\t\tif ($functionName != 'MKMATRIX') {\n\t\t\t\t\t\tif ($this->_debugLog->getWriteDebugLog()) {\n\t\t\t\t\t\t\tkrsort($argArrayVals);\n\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', implode(self::$_localeArgumentSeparator.' ',PHPExcel_Calculation_Functions::flattenArray($argArrayVals)), ' )');\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t//\tProcess each argument in turn, building the return value as an array\n//\t\t\t\t\tif (($argCount == 1) && (is_array($args[1])) && ($functionName != 'MKMATRIX')) {\n//\t\t\t\t\t\t$operand1 = $args[1];\n//\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Argument is a matrix: ', $this->_showValue($operand1));\n//\t\t\t\t\t\t$result = array();\n//\t\t\t\t\t\t$row = 0;\n//\t\t\t\t\t\tforeach($operand1 as $args) {\n//\t\t\t\t\t\t\tif (is_array($args)) {\n//\t\t\t\t\t\t\t\tforeach($args as $arg) {\n//\t\t\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($arg), ' )');\n//\t\t\t\t\t\t\t\t\t$r = call_user_func_array($functionCall,$arg);\n//\t\t\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r));\n//\t\t\t\t\t\t\t\t\t$result[$row][] = $r;\n//\t\t\t\t\t\t\t\t}\n//\t\t\t\t\t\t\t\t++$row;\n//\t\t\t\t\t\t\t} else {\n//\t\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating ', self::_localeFunc($functionName), '( ', $this->_showValue($args), ' )');\n//\t\t\t\t\t\t\t\t$r = call_user_func_array($functionCall,$args);\n//\t\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($r));\n//\t\t\t\t\t\t\t\t$result[] = $r;\n//\t\t\t\t\t\t\t}\n//\t\t\t\t\t\t}\n//\t\t\t\t\t} else {\n\t\t\t\t\t//\tProcess the argument with the appropriate function call\n\t\t\t\t\t\tif ($passCellReference) {\n\t\t\t\t\t\t\t$args[] = $pCell;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (strpos($functionCall,'::') !== FALSE) {\n\t\t\t\t\t\t\t$result = call_user_func_array(explode('::',$functionCall),$args);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tforeach($args as &$arg) {\n\t\t\t\t\t\t\t\t$arg = PHPExcel_Calculation_Functions::flattenSingleValue($arg);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tunset($arg);\n\t\t\t\t\t\t\t$result = call_user_func_array($functionCall,$args);\n\t\t\t\t\t\t}\n//\t\t\t\t\t}\n\t\t\t\t\tif ($functionName != 'MKMATRIX') {\n\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result for ', self::_localeFunc($functionName), '() function call is ', $this->_showTypeDetails($result));\n\t\t\t\t\t}\n\t\t\t\t\t$stack->push('Value',self::_wrapResult($result));\n\t\t\t\t}\n\n\t\t\t} else {\n\t\t\t\t// if the token is a number, boolean, string or an Excel error, push it onto the stack\n\t\t\t\tif (isset(self::$_ExcelConstants[strtoupper($token)])) {\n\t\t\t\t\t$excelConstant = strtoupper($token);\n//\t\t\t\t\techo 'Token is a PHPExcel constant: '.$excelConstant.'<br />';\n\t\t\t\t\t$stack->push('Constant Value',self::$_ExcelConstants[$excelConstant]);\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating Constant ', $excelConstant, ' as ', $this->_showTypeDetails(self::$_ExcelConstants[$excelConstant]));\n\t\t\t\t} elseif ((is_numeric($token)) || ($token === NULL) || (is_bool($token)) || ($token == '') || ($token{0} == '\"') || ($token{0} == '#')) {\n//\t\t\t\t\techo 'Token is a number, boolean, string, null or an Excel error<br />';\n\t\t\t\t\t$stack->push('Value',$token);\n\t\t\t\t// if the token is a named range, push the named range name onto the stack\n\t\t\t\t} elseif (preg_match('/^'.self::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $token, $matches)) {\n//\t\t\t\t\techo 'Token is a named range<br />';\n\t\t\t\t\t$namedRange = $matches[6];\n//\t\t\t\t\techo 'Named Range is '.$namedRange.'<br />';\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating Named Range ', $namedRange);\n\t\t\t\t\t$cellValue = $this->extractNamedRange($namedRange, ((NULL !== $pCell) ? $pCellWorksheet : NULL), FALSE);\n\t\t\t\t\t$pCell->attach($pCellParent);\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result for named range ', $namedRange, ' is ', $this->_showTypeDetails($cellValue));\n\t\t\t\t\t$stack->push('Named Range',$cellValue,$namedRange);\n\t\t\t\t} else {\n\t\t\t\t\treturn $this->_raiseFormulaError(\"undefined variable '$token'\");\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// when we're out of tokens, the stack should have a single element, the final result\n\t\tif ($stack->count() != 1) return $this->_raiseFormulaError(\"internal error\");\n\t\t$output = $stack->pop();\n\t\t$output = $output['value'];\n\n//\t\tif ((is_array($output)) && (self::$returnArrayAsType != self::RETURN_ARRAY_AS_ARRAY)) {\n//\t\t\treturn array_shift(PHPExcel_Calculation_Functions::flattenArray($output));\n//\t\t}\n\t\treturn $output;\n\t}\t//\tfunction _processTokenStack()\n\n\n\tprivate function _validateBinaryOperand($cellID, &$operand, &$stack) {\n\t\tif (is_array($operand)) {\n\t\t\tif ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) {\n\t\t\t\tdo {\n\t\t\t\t\t$operand = array_pop($operand);\n\t\t\t\t} while (is_array($operand));\n\t\t\t}\n\t\t}\n\t\t//\tNumbers, matrices and booleans can pass straight through, as they're already valid\n\t\tif (is_string($operand)) {\n\t\t\t//\tWe only need special validations for the operand if it is a string\n\t\t\t//\tStart by stripping off the quotation marks we use to identify true excel string values internally\n\t\t\tif ($operand > '' && $operand{0} == '\"') { $operand = self::_unwrapResult($operand); }\n\t\t\t//\tIf the string is a numeric value, we treat it as a numeric, so no further testing\n\t\t\tif (!is_numeric($operand)) {\n\t\t\t\t//\tIf not a numeric, test to see if the value is an Excel error, and so can't be used in normal binary operations\n\t\t\t\tif ($operand > '' && $operand{0} == '#') {\n\t\t\t\t\t$stack->push('Value', $operand);\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($operand));\n\t\t\t\t\treturn FALSE;\n\t\t\t\t} elseif (!PHPExcel_Shared_String::convertToNumberIfFraction($operand)) {\n\t\t\t\t\t//\tIf not a numeric or a fraction, then it's a text string, and so can't be used in mathematical binary operations\n\t\t\t\t\t$stack->push('Value', '#VALUE!');\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result is a ', $this->_showTypeDetails('#VALUE!'));\n\t\t\t\t\treturn FALSE;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//\treturn a true if the value of the operand is one that we can use in normal binary operations\n\t\treturn TRUE;\n\t}\t//\tfunction _validateBinaryOperand()\n\n\n\tprivate function _executeBinaryComparisonOperation($cellID, $operand1, $operand2, $operation, &$stack, $recursingArrays=FALSE) {\n\t\t//\tIf we're dealing with matrix operations, we want a matrix result\n\t\tif ((is_array($operand1)) || (is_array($operand2))) {\n\t\t\t$result = array();\n\t\t\tif ((is_array($operand1)) && (!is_array($operand2))) {\n\t\t\t\tforeach($operand1 as $x => $operandData) {\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2));\n\t\t\t\t\t$this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2,$operation,$stack);\n\t\t\t\t\t$r = $stack->pop();\n\t\t\t\t\t$result[$x] = $r['value'];\n\t\t\t\t}\n\t\t\t} elseif ((!is_array($operand1)) && (is_array($operand2))) {\n\t\t\t\tforeach($operand2 as $x => $operandData) {\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operand1), ' ', $operation, ' ', $this->_showValue($operandData));\n\t\t\t\t\t$this->_executeBinaryComparisonOperation($cellID,$operand1,$operandData,$operation,$stack);\n\t\t\t\t\t$r = $stack->pop();\n\t\t\t\t\t$result[$x] = $r['value'];\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif (!$recursingArrays) { self::_checkMatrixOperands($operand1,$operand2,2); }\n\t\t\t\tforeach($operand1 as $x => $operandData) {\n\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluating Comparison ', $this->_showValue($operandData), ' ', $operation, ' ', $this->_showValue($operand2[$x]));\n\t\t\t\t\t$this->_executeBinaryComparisonOperation($cellID,$operandData,$operand2[$x],$operation,$stack,TRUE);\n\t\t\t\t\t$r = $stack->pop();\n\t\t\t\t\t$result[$x] = $r['value'];\n\t\t\t\t}\n\t\t\t}\n\t\t\t//\tLog the result details\n\t\t\t$this->_debugLog->writeDebugLog('Comparison Evaluation Result is ', $this->_showTypeDetails($result));\n\t\t\t//\tAnd push the result onto the stack\n\t\t\t$stack->push('Array',$result);\n\t\t\treturn TRUE;\n\t\t}\n\n\t\t//\tSimple validate the two operands if they are string values\n\t\tif (is_string($operand1) && $operand1 > '' && $operand1{0} == '\"') { $operand1 = self::_unwrapResult($operand1); }\n\t\tif (is_string($operand2) && $operand2 > '' && $operand2{0} == '\"') { $operand2 = self::_unwrapResult($operand2); }\n\n\t\t// Use case insensitive comparaison if not OpenOffice mode\n\t\tif (PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE)\n\t\t{\n\t\t\tif (is_string($operand1)) {\n\t\t\t\t$operand1 = strtoupper($operand1);\n\t\t\t}\n\n\t\t\tif (is_string($operand2)) {\n\t\t\t\t$operand2 = strtoupper($operand2);\n\t\t\t}\n\t\t}\n\n\t\t$useLowercaseFirstComparison = is_string($operand1) && is_string($operand2) && PHPExcel_Calculation_Functions::getCompatibilityMode() == PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE;\n\n\t\t//\texecute the necessary operation\n\t\tswitch ($operation) {\n\t\t\t//\tGreater than\n\t\t\tcase '>':\n\t\t\t\tif ($useLowercaseFirstComparison) {\n\t\t\t\t\t$result = $this->strcmpLowercaseFirst($operand1, $operand2) > 0;\n\t\t\t\t} else {\n\t\t\t\t\t$result = ($operand1 > $operand2);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t//\tLess than\n\t\t\tcase '<':\n\t\t\t\tif ($useLowercaseFirstComparison) {\n\t\t\t\t\t$result = $this->strcmpLowercaseFirst($operand1, $operand2) < 0;\n\t\t\t\t} else {\n\t\t\t\t\t$result = ($operand1 < $operand2);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t//\tEquality\n\t\t\tcase '=':\n                if (is_numeric($operand1) && is_numeric($operand2)) {\n                    $result = (abs($operand1 - $operand2) < $this->delta);\n                } else {\n                    $result = strcmp($operand1, $operand2) == 0;\n                }\n\t\t\t\tbreak;\n\t\t\t//\tGreater than or equal\n\t\t\tcase '>=':\n                if (is_numeric($operand1) && is_numeric($operand2)) {\n                    $result = ((abs($operand1 - $operand2) < $this->delta) || ($operand1 > $operand2));\n\t\t\t\t} elseif ($useLowercaseFirstComparison) {\n\t\t\t\t\t$result = $this->strcmpLowercaseFirst($operand1, $operand2) >= 0;\n\t\t\t\t} else {\n\t\t\t\t\t$result = strcmp($operand1, $operand2) >= 0;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t//\tLess than or equal\n\t\t\tcase '<=':\n                if (is_numeric($operand1) && is_numeric($operand2)) {\n                    $result = ((abs($operand1 - $operand2) < $this->delta) || ($operand1 < $operand2));\n                } elseif ($useLowercaseFirstComparison) {\n\t\t\t\t\t$result = $this->strcmpLowercaseFirst($operand1, $operand2) <= 0;\n\t\t\t\t} else {\n\t\t\t\t\t$result = strcmp($operand1, $operand2) <= 0;\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t//\tInequality\n\t\t\tcase '<>':\n                if (is_numeric($operand1) && is_numeric($operand2)) {\n                    $result = (abs($operand1 - $operand2) > 1E-14);\n                } else {\n                    $result = strcmp($operand1, $operand2) != 0;\n                }\n\t\t\t\tbreak;\n\t\t}\n\n\t\t//\tLog the result details\n\t\t$this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result));\n\t\t//\tAnd push the result onto the stack\n\t\t$stack->push('Value',$result);\n\t\treturn true;\n\t}\n\n\t/**\n\t * Compare two strings in the same way as strcmp() except that lowercase come before uppercase letters\n\t * @param    string    $str1    First string value for the comparison\n\t * @param    string    $str2    Second string value for the comparison\n\t * @return   integer\n\t */\n\tprivate function strcmpLowercaseFirst($str1, $str2)\n\t{\n        $inversedStr1 = PHPExcel_Shared_String::StrCaseReverse($str1);\n        $inversedStr2 = PHPExcel_Shared_String::StrCaseReverse($str2);\n\n\t\treturn strcmp($inversedStr1, $inversedStr2);\n\t}\n\n\tprivate function _executeNumericBinaryOperation($cellID,$operand1,$operand2,$operation,$matrixFunction,&$stack) {\n\t\t//\tValidate the two operands\n\t\tif (!$this->_validateBinaryOperand($cellID,$operand1,$stack)) return FALSE;\n\t\tif (!$this->_validateBinaryOperand($cellID,$operand2,$stack)) return FALSE;\n\n\t\t//\tIf either of the operands is a matrix, we need to treat them both as matrices\n\t\t//\t\t(converting the other operand to a matrix if need be); then perform the required\n\t\t//\t\tmatrix operation\n\t\tif ((is_array($operand1)) || (is_array($operand2))) {\n\t\t\t//\tEnsure that both operands are arrays/matrices of the same size\n\t\t\tself::_checkMatrixOperands($operand1, $operand2, 2);\n\n\t\t\ttry {\n\t\t\t\t//\tConvert operand 1 from a PHP array to a matrix\n\t\t\t\t$matrix = new PHPExcel_Shared_JAMA_Matrix($operand1);\n\t\t\t\t//\tPerform the required operation against the operand 1 matrix, passing in operand 2\n\t\t\t\t$matrixResult = $matrix->$matrixFunction($operand2);\n\t\t\t\t$result = $matrixResult->getArray();\n\t\t\t} catch (PHPExcel_Exception $ex) {\n\t\t\t\t$this->_debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage());\n\t\t\t\t$result = '#VALUE!';\n\t\t\t}\n\t\t} else {\n\t\t\tif ((PHPExcel_Calculation_Functions::getCompatibilityMode() != PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE) &&\n\t\t\t\t((is_string($operand1) && !is_numeric($operand1) && strlen($operand1)>0) || \n                 (is_string($operand2) && !is_numeric($operand2) && strlen($operand2)>0))) {\n\t\t\t\t$result = PHPExcel_Calculation_Functions::VALUE();\n\t\t\t} else {\n\t\t\t\t//\tIf we're dealing with non-matrix operations, execute the necessary operation\n\t\t\t\tswitch ($operation) {\n\t\t\t\t\t//\tAddition\n\t\t\t\t\tcase '+':\n\t\t\t\t\t\t$result = $operand1 + $operand2;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t//\tSubtraction\n\t\t\t\t\tcase '-':\n\t\t\t\t\t\t$result = $operand1 - $operand2;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t//\tMultiplication\n\t\t\t\t\tcase '*':\n\t\t\t\t\t\t$result = $operand1 * $operand2;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t//\tDivision\n\t\t\t\t\tcase '/':\n\t\t\t\t\t\tif ($operand2 == 0) {\n\t\t\t\t\t\t\t//\tTrap for Divide by Zero error\n\t\t\t\t\t\t\t$stack->push('Value','#DIV/0!');\n\t\t\t\t\t\t\t$this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails('#DIV/0!'));\n\t\t\t\t\t\t\treturn FALSE;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$result = $operand1 / $operand2;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t//\tPower\n\t\t\t\t\tcase '^':\n\t\t\t\t\t\t$result = pow($operand1, $operand2);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//\tLog the result details\n\t\t$this->_debugLog->writeDebugLog('Evaluation Result is ', $this->_showTypeDetails($result));\n\t\t//\tAnd push the result onto the stack\n\t\t$stack->push('Value',$result);\n\t\treturn TRUE;\n\t}\t//\tfunction _executeNumericBinaryOperation()\n\n\n\t// trigger an error, but nicely, if need be\n\tprotected function _raiseFormulaError($errorMessage) {\n\t\t$this->formulaError = $errorMessage;\n\t\t$this->_cyclicReferenceStack->clear();\n\t\tif (!$this->suppressFormulaErrors) throw new PHPExcel_Calculation_Exception($errorMessage);\n\t\ttrigger_error($errorMessage, E_USER_ERROR);\n\t}\t//\tfunction _raiseFormulaError()\n\n\n\t/**\n\t * Extract range values\n\t *\n\t * @param\tstring\t\t\t\t&$pRange\tString based range representation\n\t * @param\tPHPExcel_Worksheet\t$pSheet\t\tWorksheet\n\t * @param\tboolean\t\t\t\t$resetLog\tFlag indicating whether calculation log should be reset or not\n\t * @return  mixed\t\t\t\tArray of values in range if range contains more than one element. Otherwise, a single value is returned.\n\t * @throws\tPHPExcel_Calculation_Exception\n\t */\n\tpublic function extractCellRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) {\n\t\t// Return value\n\t\t$returnValue = array ();\n\n//\t\techo 'extractCellRange('.$pRange.')',PHP_EOL;\n\t\tif ($pSheet !== NULL) {\n\t\t\t$pSheetName = $pSheet->getTitle();\n//\t\t\techo 'Passed sheet name is '.$pSheetName.PHP_EOL;\n//\t\t\techo 'Range reference is '.$pRange.PHP_EOL;\n\t\t\tif (strpos ($pRange, '!') !== false) {\n//\t\t\t\techo '$pRange reference includes sheet reference',PHP_EOL;\n\t\t\t\tlist($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true);\n//\t\t\t\techo 'New sheet name is '.$pSheetName,PHP_EOL;\n//\t\t\t\techo 'Adjusted Range reference is '.$pRange,PHP_EOL;\n\t\t\t\t$pSheet = $this->_workbook->getSheetByName($pSheetName);\n\t\t\t}\n\n\t\t\t// Extract range\n\t\t\t$aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);\n\t\t\t$pRange = $pSheetName.'!'.$pRange;\n\t\t\tif (!isset($aReferences[1])) {\n\t\t\t\t//\tSingle cell in range\n\t\t\t\tsscanf($aReferences[0],'%[A-Z]%d', $currentCol, $currentRow);\n\t\t\t\t$cellValue = NULL;\n\t\t\t\tif ($pSheet->cellExists($aReferences[0])) {\n\t\t\t\t\t$returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);\n\t\t\t\t} else {\n\t\t\t\t\t$returnValue[$currentRow][$currentCol] = NULL;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Extract cell data for all cells in the range\n\t\t\t\tforeach ($aReferences as $reference) {\n\t\t\t\t\t// Extract range\n\t\t\t\t\tsscanf($reference,'%[A-Z]%d', $currentCol, $currentRow);\n\t\t\t\t\t$cellValue = NULL;\n\t\t\t\t\tif ($pSheet->cellExists($reference)) {\n\t\t\t\t\t\t$returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$returnValue[$currentRow][$currentCol] = NULL;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction extractCellRange()\n\n\n\t/**\n\t * Extract range values\n\t *\n\t * @param\tstring\t\t\t\t&$pRange\tString based range representation\n\t * @param\tPHPExcel_Worksheet\t$pSheet\t\tWorksheet\n\t * @return  mixed\t\t\t\tArray of values in range if range contains more than one element. Otherwise, a single value is returned.\n\t * @param\tboolean\t\t\t\t$resetLog\tFlag indicating whether calculation log should be reset or not\n\t * @throws\tPHPExcel_Calculation_Exception\n\t */\n\tpublic function extractNamedRange(&$pRange = 'A1', PHPExcel_Worksheet $pSheet = NULL, $resetLog = TRUE) {\n\t\t// Return value\n\t\t$returnValue = array ();\n\n//\t\techo 'extractNamedRange('.$pRange.')<br />';\n\t\tif ($pSheet !== NULL) {\n\t\t\t$pSheetName = $pSheet->getTitle();\n//\t\t\techo 'Current sheet name is '.$pSheetName.'<br />';\n//\t\t\techo 'Range reference is '.$pRange.'<br />';\n\t\t\tif (strpos ($pRange, '!') !== false) {\n//\t\t\t\techo '$pRange reference includes sheet reference',PHP_EOL;\n\t\t\t\tlist($pSheetName,$pRange) = PHPExcel_Worksheet::extractSheetTitle($pRange, true);\n//\t\t\t\techo 'New sheet name is '.$pSheetName,PHP_EOL;\n//\t\t\t\techo 'Adjusted Range reference is '.$pRange,PHP_EOL;\n\t\t\t\t$pSheet = $this->_workbook->getSheetByName($pSheetName);\n\t\t\t}\n\n\t\t\t// Named range?\n\t\t\t$namedRange = PHPExcel_NamedRange::resolveRange($pRange, $pSheet);\n\t\t\tif ($namedRange !== NULL) {\n\t\t\t\t$pSheet = $namedRange->getWorksheet();\n//\t\t\t\techo 'Named Range '.$pRange.' (';\n\t\t\t\t$pRange = $namedRange->getRange();\n\t\t\t\t$splitRange = PHPExcel_Cell::splitRange($pRange);\n\t\t\t\t//\tConvert row and column references\n\t\t\t\tif (ctype_alpha($splitRange[0][0])) {\n\t\t\t\t\t$pRange = $splitRange[0][0] . '1:' . $splitRange[0][1] . $namedRange->getWorksheet()->getHighestRow();\n\t\t\t\t} elseif(ctype_digit($splitRange[0][0])) {\n\t\t\t\t\t$pRange = 'A' . $splitRange[0][0] . ':' . $namedRange->getWorksheet()->getHighestColumn() . $splitRange[0][1];\n\t\t\t\t}\n//\t\t\t\techo $pRange.') is in sheet '.$namedRange->getWorksheet()->getTitle().'<br />';\n\n//\t\t\t\tif ($pSheet->getTitle() != $namedRange->getWorksheet()->getTitle()) {\n//\t\t\t\t\tif (!$namedRange->getLocalOnly()) {\n//\t\t\t\t\t\t$pSheet = $namedRange->getWorksheet();\n//\t\t\t\t\t} else {\n//\t\t\t\t\t\treturn $returnValue;\n//\t\t\t\t\t}\n//\t\t\t\t}\n\t\t\t} else {\n\t\t\t\treturn PHPExcel_Calculation_Functions::REF();\n\t\t\t}\n\n\t\t\t// Extract range\n\t\t\t$aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);\n//\t\t\tvar_dump($aReferences);\n\t\t\tif (!isset($aReferences[1])) {\n\t\t\t\t//\tSingle cell (or single column or row) in range\n\t\t\t\tlist($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($aReferences[0]);\n\t\t\t\t$cellValue = NULL;\n\t\t\t\tif ($pSheet->cellExists($aReferences[0])) {\n\t\t\t\t\t$returnValue[$currentRow][$currentCol] = $pSheet->getCell($aReferences[0])->getCalculatedValue($resetLog);\n\t\t\t\t} else {\n\t\t\t\t\t$returnValue[$currentRow][$currentCol] = NULL;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Extract cell data for all cells in the range\n\t\t\t\tforeach ($aReferences as $reference) {\n\t\t\t\t\t// Extract range\n\t\t\t\t\tlist($currentCol,$currentRow) = PHPExcel_Cell::coordinateFromString($reference);\n//\t\t\t\t\techo 'NAMED RANGE: $currentCol='.$currentCol.' $currentRow='.$currentRow.'<br />';\n\t\t\t\t\t$cellValue = NULL;\n\t\t\t\t\tif ($pSheet->cellExists($reference)) {\n\t\t\t\t\t\t$returnValue[$currentRow][$currentCol] = $pSheet->getCell($reference)->getCalculatedValue($resetLog);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$returnValue[$currentRow][$currentCol] = NULL;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n//\t\t\t\tprint_r($returnValue);\n//\t\t\techo '<br />';\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction extractNamedRange()\n\n\n\t/**\n\t * Is a specific function implemented?\n\t *\n\t * @param\tstring\t$pFunction\tFunction Name\n\t * @return\tboolean\n\t */\n\tpublic function isImplemented($pFunction = '') {\n\t\t$pFunction = strtoupper ($pFunction);\n\t\tif (isset(self::$_PHPExcelFunctions[$pFunction])) {\n\t\t\treturn (self::$_PHPExcelFunctions[$pFunction]['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY');\n\t\t} else {\n\t\t\treturn FALSE;\n\t\t}\n\t}\t//\tfunction isImplemented()\n\n\n\t/**\n\t * Get a list of all implemented functions as an array of function objects\n\t *\n\t * @return\tarray of PHPExcel_Calculation_Function\n\t */\n\tpublic function listFunctions() {\n\t\t// Return value\n\t\t$returnValue = array();\n\t\t// Loop functions\n\t\tforeach(self::$_PHPExcelFunctions as $functionName => $function) {\n\t\t\tif ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') {\n\t\t\t\t$returnValue[$functionName] = new PHPExcel_Calculation_Function($function['category'],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$functionName,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$function['functionCall']\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   );\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction listFunctions()\n\n\n\t/**\n\t * Get a list of all Excel function names\n\t *\n\t * @return\tarray\n\t */\n\tpublic function listAllFunctionNames() {\n\t\treturn array_keys(self::$_PHPExcelFunctions);\n\t}\t//\tfunction listAllFunctionNames()\n\n\t/**\n\t * Get a list of implemented Excel function names\n\t *\n\t * @return\tarray\n\t */\n\tpublic function listFunctionNames() {\n\t\t// Return value\n\t\t$returnValue = array();\n\t\t// Loop functions\n\t\tforeach(self::$_PHPExcelFunctions as $functionName => $function) {\n\t\t\tif ($function['functionCall'] != 'PHPExcel_Calculation_Functions::DUMMY') {\n\t\t\t\t$returnValue[] = $functionName;\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\t//\tfunction listFunctionNames()\n\n}\t//\tclass PHPExcel_Calculation\n\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Cell/AdvancedValueBinder.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Cell\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n    /**\n     * @ignore\n     */\n    define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n    require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\n/**\n * PHPExcel_Cell_AdvancedValueBinder\n *\n * @category   PHPExcel\n * @package    PHPExcel_Cell\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Cell_AdvancedValueBinder extends PHPExcel_Cell_DefaultValueBinder implements PHPExcel_Cell_IValueBinder\n{\n    /**\n     * Bind value to a cell\n     *\n     * @param  PHPExcel_Cell  $cell  Cell to bind value to\n     * @param  mixed $value          Value to bind in cell\n     * @return boolean\n     */\n    public function bindValue(PHPExcel_Cell $cell, $value = null)\n    {\n        // sanitize UTF-8 strings\n        if (is_string($value)) {\n            $value = PHPExcel_Shared_String::SanitizeUTF8($value);\n        }\n\n        // Find out data type\n        $dataType = parent::dataTypeForValue($value);\n\n        // Style logic - strings\n        if ($dataType === PHPExcel_Cell_DataType::TYPE_STRING && !$value instanceof PHPExcel_RichText) {\n            //    Test for booleans using locale-setting\n            if ($value == PHPExcel_Calculation::getTRUE()) {\n                $cell->setValueExplicit( TRUE, PHPExcel_Cell_DataType::TYPE_BOOL);\n                return true;\n            } elseif($value == PHPExcel_Calculation::getFALSE()) {\n                $cell->setValueExplicit( FALSE, PHPExcel_Cell_DataType::TYPE_BOOL);\n                return true;\n            }\n\n            // Check for number in scientific format\n            if (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NUMBER.'$/', $value)) {\n                $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC);\n                return true;\n            }\n\n            // Check for fraction\n            if (preg_match('/^([+-]?)\\s*([0-9]+)\\s?\\/\\s*([0-9]+)$/', $value, $matches)) {\n                // Convert value to number\n                $value = $matches[2] / $matches[3];\n                if ($matches[1] == '-') $value = 0 - $value;\n                $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC);\n                // Set style\n                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )\n                    ->getNumberFormat()->setFormatCode( '??/??' );\n                return true;\n            } elseif (preg_match('/^([+-]?)([0-9]*) +([0-9]*)\\s?\\/\\s*([0-9]*)$/', $value, $matches)) {\n                // Convert value to number\n                $value = $matches[2] + ($matches[3] / $matches[4]);\n                if ($matches[1] == '-') $value = 0 - $value;\n                $cell->setValueExplicit( (float) $value, PHPExcel_Cell_DataType::TYPE_NUMERIC);\n                // Set style\n                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )\n                    ->getNumberFormat()->setFormatCode( '# ??/??' );\n                return true;\n            }\n\n            // Check for percentage\n            if (preg_match('/^\\-?[0-9]*\\.?[0-9]*\\s?\\%$/', $value)) {\n                // Convert value to number\n                $value = (float) str_replace('%', '', $value) / 100;\n                $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC);\n                // Set style\n                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )\n                    ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00 );\n                return true;\n            }\n\n            // Check for currency\n            $currencyCode = PHPExcel_Shared_String::getCurrencyCode();\n            $decimalSeparator = PHPExcel_Shared_String::getDecimalSeparator();\n            $thousandsSeparator = PHPExcel_Shared_String::getThousandsSeparator();\n            if (preg_match('/^'.preg_quote($currencyCode).' *(\\d{1,3}('.preg_quote($thousandsSeparator).'\\d{3})*|(\\d+))('.preg_quote($decimalSeparator).'\\d{2})?$/', $value)) {\n                // Convert value to number\n                $value = (float) trim(str_replace(array($currencyCode, $thousandsSeparator, $decimalSeparator), array('', '', '.'), $value));\n                $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC);\n                // Set style\n                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )\n                    ->getNumberFormat()->setFormatCode(\n                        str_replace('$', $currencyCode, PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE )\n                    );\n                return true;\n            } elseif (preg_match('/^\\$ *(\\d{1,3}(\\,\\d{3})*|(\\d+))(\\.\\d{2})?$/', $value)) {\n                // Convert value to number\n                $value = (float) trim(str_replace(array('$',','), '', $value));\n                $cell->setValueExplicit( $value, PHPExcel_Cell_DataType::TYPE_NUMERIC);\n                // Set style\n                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )\n                    ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE );\n                return true;\n            }\n\n            // Check for time without seconds e.g. '9:45', '09:45'\n            if (preg_match('/^(\\d|[0-1]\\d|2[0-3]):[0-5]\\d$/', $value)) {\n                // Convert value to number\n                list($h, $m) = explode(':', $value);\n                $days = $h / 24 + $m / 1440;\n                $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC);\n                // Set style\n                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )\n                    ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3 );\n                return true;\n            }\n\n            // Check for time with seconds '9:45:59', '09:45:59'\n            if (preg_match('/^(\\d|[0-1]\\d|2[0-3]):[0-5]\\d:[0-5]\\d$/', $value)) {\n                // Convert value to number\n                list($h, $m, $s) = explode(':', $value);\n                $days = $h / 24 + $m / 1440 + $s / 86400;\n                // Convert value to number\n                $cell->setValueExplicit($days, PHPExcel_Cell_DataType::TYPE_NUMERIC);\n                // Set style\n                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )\n                    ->getNumberFormat()->setFormatCode( PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4 );\n                return true;\n            }\n\n            // Check for datetime, e.g. '2008-12-31', '2008-12-31 15:59', '2008-12-31 15:59:10'\n            if (($d = PHPExcel_Shared_Date::stringToExcel($value)) !== false) {\n                // Convert value to number\n                $cell->setValueExplicit($d, PHPExcel_Cell_DataType::TYPE_NUMERIC);\n                // Determine style. Either there is a time part or not. Look for ':'\n                if (strpos($value, ':') !== false) {\n                    $formatCode = 'yyyy-mm-dd h:mm';\n                } else {\n                    $formatCode = 'yyyy-mm-dd';\n                }\n                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )\n                    ->getNumberFormat()->setFormatCode($formatCode);\n                return true;\n            }\n\n            // Check for newline character \"\\n\"\n            if (strpos($value, \"\\n\") !== FALSE) {\n                $value = PHPExcel_Shared_String::SanitizeUTF8($value);\n                $cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING);\n                // Set style\n                $cell->getWorksheet()->getStyle( $cell->getCoordinate() )\n                    ->getAlignment()->setWrapText(TRUE);\n                return true;\n            }\n        }\n\n        // Not bound yet? Use parent...\n        return parent::bindValue($cell, $value);\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Cell/DataType.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Cell\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Cell_DataType\n *\n * @category   PHPExcel\n * @package    PHPExcel_Cell\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Cell_DataType\n{\n    /* Data types */\n    const TYPE_STRING2  = 'str';\n    const TYPE_STRING   = 's';\n    const TYPE_FORMULA  = 'f';\n    const TYPE_NUMERIC  = 'n';\n    const TYPE_BOOL     = 'b';\n    const TYPE_NULL     = 'null';\n    const TYPE_INLINE   = 'inlineStr';\n    const TYPE_ERROR    = 'e';\n\n    /**\n     * List of error codes\n     *\n     * @var array\n     */\n    private static $_errorCodes = array(\n        '#NULL!'  => 0,\n        '#DIV/0!' => 1,\n        '#VALUE!' => 2,\n        '#REF!'   => 3,\n        '#NAME?'  => 4,\n        '#NUM!'   => 5,\n        '#N/A'    => 6\n    );\n\n    /**\n     * Get list of error codes\n     *\n     * @return array\n     */\n    public static function getErrorCodes() {\n        return self::$_errorCodes;\n    }\n\n    /**\n     * DataType for value\n     *\n     * @deprecated  Replaced by PHPExcel_Cell_IValueBinder infrastructure, will be removed in version 1.8.0\n     * @param       mixed  $pValue\n     * @return      string\n     */\n    public static function dataTypeForValue($pValue = null) {\n        return PHPExcel_Cell_DefaultValueBinder::dataTypeForValue($pValue);\n    }\n\n    /**\n     * Check a string that it satisfies Excel requirements\n     *\n     * @param  mixed  Value to sanitize to an Excel string\n     * @return mixed  Sanitized value\n     */\n    public static function checkString($pValue = null)\n    {\n        if ($pValue instanceof PHPExcel_RichText) {\n            // TODO: Sanitize Rich-Text string (max. character count is 32,767)\n            return $pValue;\n        }\n\n        // string must never be longer than 32,767 characters, truncate if necessary\n        $pValue = PHPExcel_Shared_String::Substring($pValue, 0, 32767);\n\n        // we require that newline is represented as \"\\n\" in core, not as \"\\r\\n\" or \"\\r\"\n        $pValue = str_replace(array(\"\\r\\n\", \"\\r\"), \"\\n\", $pValue);\n\n        return $pValue;\n    }\n\n    /**\n     * Check a value that it is a valid error code\n     *\n     * @param  mixed   Value to sanitize to an Excel error code\n     * @return string  Sanitized value\n     */\n    public static function checkErrorCode($pValue = null)\n    {\n        $pValue = (string) $pValue;\n\n        if ( !array_key_exists($pValue, self::$_errorCodes) ) {\n            $pValue = '#NULL!';\n        }\n\n        return $pValue;\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Cell/DataValidation.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Cell\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Cell_DataValidation\n *\n * @category   PHPExcel\n * @package    PHPExcel_Cell\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Cell_DataValidation\n{\n    /* Data validation types */\n    const TYPE_NONE        = 'none';\n    const TYPE_CUSTOM      = 'custom';\n    const TYPE_DATE        = 'date';\n    const TYPE_DECIMAL     = 'decimal';\n    const TYPE_LIST        = 'list';\n    const TYPE_TEXTLENGTH  = 'textLength';\n    const TYPE_TIME        = 'time';\n    const TYPE_WHOLE       = 'whole';\n\n    /* Data validation error styles */\n    const STYLE_STOP         = 'stop';\n    const STYLE_WARNING      = 'warning';\n    const STYLE_INFORMATION  = 'information';\n\n    /* Data validation operators */\n    const OPERATOR_BETWEEN             = 'between';\n    const OPERATOR_EQUAL               = 'equal';\n    const OPERATOR_GREATERTHAN         = 'greaterThan';\n    const OPERATOR_GREATERTHANOREQUAL  = 'greaterThanOrEqual';\n    const OPERATOR_LESSTHAN            = 'lessThan';\n    const OPERATOR_LESSTHANOREQUAL     = 'lessThanOrEqual';\n    const OPERATOR_NOTBETWEEN          = 'notBetween';\n    const OPERATOR_NOTEQUAL            = 'notEqual';\n\n    /**\n     * Formula 1\n     *\n     * @var string\n     */\n    private $_formula1;\n\n    /**\n     * Formula 2\n     *\n     * @var string\n     */\n    private $_formula2;\n\n    /**\n     * Type\n     *\n     * @var string\n     */\n    private $_type = PHPExcel_Cell_DataValidation::TYPE_NONE;\n\n    /**\n     * Error style\n     *\n     * @var string\n     */\n    private $_errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP;\n\n    /**\n     * Operator\n     *\n     * @var string\n     */\n    private $_operator;\n\n    /**\n     * Allow Blank\n     *\n     * @var boolean\n     */\n    private $_allowBlank;\n\n    /**\n     * Show DropDown\n     *\n     * @var boolean\n     */\n    private $_showDropDown;\n\n    /**\n     * Show InputMessage\n     *\n     * @var boolean\n     */\n    private $_showInputMessage;\n\n    /**\n     * Show ErrorMessage\n     *\n     * @var boolean\n     */\n    private $_showErrorMessage;\n\n    /**\n     * Error title\n     *\n     * @var string\n     */\n    private $_errorTitle;\n\n    /**\n     * Error\n     *\n     * @var string\n     */\n    private $_error;\n\n    /**\n     * Prompt title\n     *\n     * @var string\n     */\n    private $_promptTitle;\n\n    /**\n     * Prompt\n     *\n     * @var string\n     */\n    private $_prompt;\n\n    /**\n     * Create a new PHPExcel_Cell_DataValidation\n     */\n    public function __construct()\n    {\n        // Initialise member variables\n        $this->_formula1          = '';\n        $this->_formula2          = '';\n        $this->_type              = PHPExcel_Cell_DataValidation::TYPE_NONE;\n        $this->_errorStyle        = PHPExcel_Cell_DataValidation::STYLE_STOP;\n        $this->_operator          = '';\n        $this->_allowBlank        = FALSE;\n        $this->_showDropDown      = FALSE;\n        $this->_showInputMessage  = FALSE;\n        $this->_showErrorMessage  = FALSE;\n        $this->_errorTitle        = '';\n        $this->_error             = '';\n        $this->_promptTitle       = '';\n        $this->_prompt            = '';\n    }\n\n    /**\n     * Get Formula 1\n     *\n     * @return string\n     */\n    public function getFormula1() {\n        return $this->_formula1;\n    }\n\n    /**\n     * Set Formula 1\n     *\n     * @param  string    $value\n     * @return PHPExcel_Cell_DataValidation\n     */\n    public function setFormula1($value = '') {\n        $this->_formula1 = $value;\n        return $this;\n    }\n\n    /**\n     * Get Formula 2\n     *\n     * @return string\n     */\n    public function getFormula2() {\n        return $this->_formula2;\n    }\n\n    /**\n     * Set Formula 2\n     *\n     * @param  string    $value\n     * @return PHPExcel_Cell_DataValidation\n     */\n    public function setFormula2($value = '') {\n        $this->_formula2 = $value;\n        return $this;\n    }\n\n    /**\n     * Get Type\n     *\n     * @return string\n     */\n    public function getType() {\n        return $this->_type;\n    }\n\n    /**\n     * Set Type\n     *\n     * @param  string    $value\n     * @return PHPExcel_Cell_DataValidation\n     */\n    public function setType($value = PHPExcel_Cell_DataValidation::TYPE_NONE) {\n        $this->_type = $value;\n        return $this;\n    }\n\n    /**\n     * Get Error style\n     *\n     * @return string\n     */\n    public function getErrorStyle() {\n        return $this->_errorStyle;\n    }\n\n    /**\n     * Set Error style\n     *\n     * @param  string    $value\n     * @return PHPExcel_Cell_DataValidation\n     */\n    public function setErrorStyle($value = PHPExcel_Cell_DataValidation::STYLE_STOP) {\n        $this->_errorStyle = $value;\n        return $this;\n    }\n\n    /**\n     * Get Operator\n     *\n     * @return string\n     */\n    public function getOperator() {\n        return $this->_operator;\n    }\n\n    /**\n     * Set Operator\n     *\n     * @param  string    $value\n     * @return PHPExcel_Cell_DataValidation\n     */\n    public function setOperator($value = '') {\n        $this->_operator = $value;\n        return $this;\n    }\n\n    /**\n     * Get Allow Blank\n     *\n     * @return boolean\n     */\n    public function getAllowBlank() {\n        return $this->_allowBlank;\n    }\n\n    /**\n     * Set Allow Blank\n     *\n     * @param  boolean    $value\n     * @return PHPExcel_Cell_DataValidation\n     */\n    public function setAllowBlank($value = false) {\n        $this->_allowBlank = $value;\n        return $this;\n    }\n\n    /**\n     * Get Show DropDown\n     *\n     * @return boolean\n     */\n    public function getShowDropDown() {\n        return $this->_showDropDown;\n    }\n\n    /**\n     * Set Show DropDown\n     *\n     * @param  boolean    $value\n     * @return PHPExcel_Cell_DataValidation\n     */\n    public function setShowDropDown($value = false) {\n        $this->_showDropDown = $value;\n        return $this;\n    }\n\n    /**\n     * Get Show InputMessage\n     *\n     * @return boolean\n     */\n    public function getShowInputMessage() {\n        return $this->_showInputMessage;\n    }\n\n    /**\n     * Set Show InputMessage\n     *\n     * @param  boolean    $value\n     * @return PHPExcel_Cell_DataValidation\n     */\n    public function setShowInputMessage($value = false) {\n        $this->_showInputMessage = $value;\n        return $this;\n    }\n\n    /**\n     * Get Show ErrorMessage\n     *\n     * @return boolean\n     */\n    public function getShowErrorMessage() {\n        return $this->_showErrorMessage;\n    }\n\n    /**\n     * Set Show ErrorMessage\n     *\n     * @param  boolean    $value\n     * @return PHPExcel_Cell_DataValidation\n     */\n    public function setShowErrorMessage($value = false) {\n        $this->_showErrorMessage = $value;\n        return $this;\n    }\n\n    /**\n     * Get Error title\n     *\n     * @return string\n     */\n    public function getErrorTitle() {\n        return $this->_errorTitle;\n    }\n\n    /**\n     * Set Error title\n     *\n     * @param  string    $value\n     * @return PHPExcel_Cell_DataValidation\n     */\n    public function setErrorTitle($value = '') {\n        $this->_errorTitle = $value;\n        return $this;\n    }\n\n    /**\n     * Get Error\n     *\n     * @return string\n     */\n    public function getError() {\n        return $this->_error;\n    }\n\n    /**\n     * Set Error\n     *\n     * @param  string    $value\n     * @return PHPExcel_Cell_DataValidation\n     */\n    public function setError($value = '') {\n        $this->_error = $value;\n        return $this;\n    }\n\n    /**\n     * Get Prompt title\n     *\n     * @return string\n     */\n    public function getPromptTitle() {\n        return $this->_promptTitle;\n    }\n\n    /**\n     * Set Prompt title\n     *\n     * @param  string    $value\n     * @return PHPExcel_Cell_DataValidation\n     */\n    public function setPromptTitle($value = '') {\n        $this->_promptTitle = $value;\n        return $this;\n    }\n\n    /**\n     * Get Prompt\n     *\n     * @return string\n     */\n    public function getPrompt() {\n        return $this->_prompt;\n    }\n\n    /**\n     * Set Prompt\n     *\n     * @param  string    $value\n     * @return PHPExcel_Cell_DataValidation\n     */\n    public function setPrompt($value = '') {\n        $this->_prompt = $value;\n        return $this;\n    }\n\n    /**\n     * Get hash code\n     *\n     * @return string    Hash code\n     */\n    public function getHashCode() {\n        return md5(\n              $this->_formula1\n            . $this->_formula2\n            . $this->_type = PHPExcel_Cell_DataValidation::TYPE_NONE\n            . $this->_errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP\n            . $this->_operator\n            . ($this->_allowBlank ? 't' : 'f')\n            . ($this->_showDropDown ? 't' : 'f')\n            . ($this->_showInputMessage ? 't' : 'f')\n            . ($this->_showErrorMessage ? 't' : 'f')\n            . $this->_errorTitle\n            . $this->_error\n            . $this->_promptTitle\n            . $this->_prompt\n            . __CLASS__\n        );\n    }\n\n    /**\n     * Implement PHP __clone to create a deep clone, not just a shallow copy.\n     */\n    public function __clone() {\n        $vars = get_object_vars($this);\n        foreach ($vars as $key => $value) {\n            if (is_object($value)) {\n                $this->$key = clone $value;\n            } else {\n                $this->$key = $value;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Cell/DefaultValueBinder.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Cell\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n    /**\n     * @ignore\n     */\n    define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n    require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\n/**\n * PHPExcel_Cell_DefaultValueBinder\n *\n * @category   PHPExcel\n * @package    PHPExcel_Cell\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Cell_DefaultValueBinder implements PHPExcel_Cell_IValueBinder\n{\n    /**\n     * Bind value to a cell\n     *\n     * @param  PHPExcel_Cell  $cell   Cell to bind value to\n     * @param  mixed          $value  Value to bind in cell\n     * @return boolean\n     */\n    public function bindValue(PHPExcel_Cell $cell, $value = null)\n    {\n        // sanitize UTF-8 strings\n        if (is_string($value)) {\n            $value = PHPExcel_Shared_String::SanitizeUTF8($value);\n        } elseif (is_object($value)) {\n            // Handle any objects that might be injected\n            if ($value instanceof DateTime) {\n                $value = $value->format('Y-m-d H:i:s');\n            } elseif (!($value instanceof PHPExcel_RichText)) {\n                $value = (string) $value;\n            }\n        }\n\n        // Set value explicit\n        $cell->setValueExplicit( $value, self::dataTypeForValue($value) );\n\n        // Done!\n        return true;\n    }\n\n    /**\n     * DataType for value\n     *\n     * @param   mixed  $pValue\n     * @return  string\n     */\n    public static function dataTypeForValue($pValue = null) {\n        // Match the value against a few data types\n        if ($pValue === null) {\n            return PHPExcel_Cell_DataType::TYPE_NULL;\n        } elseif ($pValue === '') {\n            return PHPExcel_Cell_DataType::TYPE_STRING;\n        } elseif ($pValue instanceof PHPExcel_RichText) {\n            return PHPExcel_Cell_DataType::TYPE_INLINE;\n        } elseif ($pValue{0} === '=' && strlen($pValue) > 1) {\n            return PHPExcel_Cell_DataType::TYPE_FORMULA;\n        } elseif (is_bool($pValue)) {\n            return PHPExcel_Cell_DataType::TYPE_BOOL;\n        } elseif (is_float($pValue) || is_int($pValue)) {\n            return PHPExcel_Cell_DataType::TYPE_NUMERIC;\n        } elseif (preg_match('/^[\\+\\-]?([0-9]+\\\\.?[0-9]*|[0-9]*\\\\.?[0-9]+)([Ee][\\-\\+]?[0-2]?\\d{1,3})?$/', $pValue)) {\n            $tValue = ltrim($pValue, '+-');\n            if (is_string($pValue) && $tValue{0} === '0' && strlen($tValue) > 1 && $tValue{1} !== '.' ) {\n                return PHPExcel_Cell_DataType::TYPE_STRING;\n            } elseif((strpos($pValue, '.') === false) && ($pValue > PHP_INT_MAX)) {\n                return PHPExcel_Cell_DataType::TYPE_STRING;\n            }\n            return PHPExcel_Cell_DataType::TYPE_NUMERIC;\n        } elseif (is_string($pValue) && array_key_exists($pValue, PHPExcel_Cell_DataType::getErrorCodes())) {\n            return PHPExcel_Cell_DataType::TYPE_ERROR;\n        }\n\n        return PHPExcel_Cell_DataType::TYPE_STRING;\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Cell/Hyperlink.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Cell\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Cell_Hyperlink\n *\n * @category   PHPExcel\n * @package    PHPExcel_Cell\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Cell_Hyperlink\n{\n    /**\n     * URL to link the cell to\n     *\n     * @var string\n     */\n    private $_url;\n\n    /**\n     * Tooltip to display on the hyperlink\n     *\n     * @var string\n     */\n    private $_tooltip;\n\n    /**\n     * Create a new PHPExcel_Cell_Hyperlink\n     *\n     * @param  string  $pUrl      Url to link the cell to\n     * @param  string  $pTooltip  Tooltip to display on the hyperlink\n     */\n    public function __construct($pUrl = '', $pTooltip = '')\n    {\n        // Initialise member variables\n        $this->_url         = $pUrl;\n        $this->_tooltip     = $pTooltip;\n    }\n\n    /**\n     * Get URL\n     *\n     * @return string\n     */\n    public function getUrl() {\n        return $this->_url;\n    }\n\n    /**\n     * Set URL\n     *\n     * @param  string    $value\n     * @return PHPExcel_Cell_Hyperlink\n     */\n    public function setUrl($value = '') {\n        $this->_url = $value;\n        return $this;\n    }\n\n    /**\n     * Get tooltip\n     *\n     * @return string\n     */\n    public function getTooltip() {\n        return $this->_tooltip;\n    }\n\n    /**\n     * Set tooltip\n     *\n     * @param  string    $value\n     * @return PHPExcel_Cell_Hyperlink\n     */\n    public function setTooltip($value = '') {\n        $this->_tooltip = $value;\n        return $this;\n    }\n\n    /**\n     * Is this hyperlink internal? (to another worksheet)\n     *\n     * @return boolean\n     */\n    public function isInternal() {\n        return strpos($this->_url, 'sheet://') !== false;\n    }\n\n    /**\n     * Get hash code\n     *\n     * @return string    Hash code\n     */\n    public function getHashCode() {\n        return md5(\n              $this->_url\n            . $this->_tooltip\n            . __CLASS__\n        );\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Cell/IValueBinder.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Cell\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Cell_IValueBinder\n *\n * @category   PHPExcel\n * @package    PHPExcel_Cell\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\ninterface PHPExcel_Cell_IValueBinder\n{\n    /**\n     * Bind value to a cell\n     *\n     * @param  PHPExcel_Cell $cell    Cell to bind value to\n     * @param  mixed $value           Value to bind in cell\n     * @return boolean\n     */\n    public function bindValue(PHPExcel_Cell $cell, $value = NULL);\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Cell.php",
    "content": "<?php\n/**\n *\tPHPExcel\n *\n *\tCopyright (c) 2006 - 2014 PHPExcel\n *\n *\tThis library is free software; you can redistribute it and/or\n *\tmodify it under the terms of the GNU Lesser General Public\n *\tLicense as published by the Free Software Foundation; either\n *\tversion 2.1 of the License, or (at your option) any later version.\n *\n *\tThis library is distributed in the hope that it will be useful,\n *\tbut WITHOUT ANY WARRANTY; without even the implied warranty of\n *\tMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n *\tLesser General Public License for more details.\n *\n *\tYou should have received a copy of the GNU Lesser General Public\n *\tLicense along with this library; if not, write to the Free Software\n *\tFoundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n *\t@category\tPHPExcel\n *\t@package\tPHPExcel_Cell\n *\t@copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n *\t@license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n *\t@version\t##VERSION##, ##DATE##\n */\n\n\n/**\n *\tPHPExcel_Cell\n *\n *\t@category   PHPExcel\n *\t@package\tPHPExcel_Cell\n *\t@copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Cell\n{\n\n\t/**\n\t *  Default range variable constant\n\t *\n\t *  @var  string\n\t */\n\tconst DEFAULT_RANGE = 'A1:A1';\n\n\t/**\n\t *\tValue binder to use\n\t *\n\t *\t@var\tPHPExcel_Cell_IValueBinder\n\t */\n\tprivate static $_valueBinder = NULL;\n\n\t/**\n\t *\tValue of the cell\n\t *\n\t *\t@var\tmixed\n\t */\n\tprivate $_value;\n\n\t/**\n\t *\tCalculated value of the cell (used for caching)\n\t *\tThis returns the value last calculated by MS Excel or whichever spreadsheet program was used to\n\t *\t\tcreate the original spreadsheet file.\n\t *\tNote that this value is not guaranteed to reflect the actual calculated value because it is\n\t *\t\tpossible that auto-calculation was disabled in the original spreadsheet, and underlying data\n\t *\t\tvalues used by the formula have changed since it was last calculated.\n\t *\n\t *\t@var mixed\n\t */\n\tprivate $_calculatedValue = NULL;\n\n\t/**\n\t *\tType of the cell data\n\t *\n\t *\t@var\tstring\n\t */\n\tprivate $_dataType;\n\n\t/**\n\t *\tParent worksheet\n\t *\n\t *\t@var\tPHPExcel_CachedObjectStorage_CacheBase\n\t */\n\tprivate $_parent;\n\n\t/**\n\t *\tIndex to cellXf\n\t *\n\t *\t@var\tint\n\t */\n\tprivate $_xfIndex = 0;\n\n\t/**\n\t *\tAttributes of the formula\n\t *\n\t */\n\tprivate $_formulaAttributes;\n\n\n\t/**\n\t *\tSend notification to the cache controller\n\t *\n\t *\t@return void\n\t **/\n\tpublic function notifyCacheController() {\n\t\t$this->_parent->updateCacheData($this);\n\n\t\treturn $this;\n\t}\n\n\tpublic function detach() {\n\t\t$this->_parent = NULL;\n\t}\n\n\tpublic function attach(PHPExcel_CachedObjectStorage_CacheBase $parent) {\n\t\t$this->_parent = $parent;\n\t}\n\n\n\t/**\n\t *\tCreate a new Cell\n\t *\n\t *\t@param\tmixed\t\t\t\t$pValue\n\t *\t@param\tstring\t\t\t\t$pDataType\n\t *\t@param\tPHPExcel_Worksheet\t$pSheet\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic function __construct($pValue = NULL, $pDataType = NULL, PHPExcel_Worksheet $pSheet = NULL)\n\t{\n\t\t// Initialise cell value\n\t\t$this->_value = $pValue;\n\n\t\t// Set worksheet cache\n\t\t$this->_parent = $pSheet->getCellCacheController();\n\n\t\t// Set datatype?\n\t\tif ($pDataType !== NULL) {\n\t\t\tif ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2)\n\t\t\t\t$pDataType = PHPExcel_Cell_DataType::TYPE_STRING;\n\t\t\t$this->_dataType = $pDataType;\n\t\t} elseif (!self::getValueBinder()->bindValue($this, $pValue)) {\n            throw new PHPExcel_Exception(\"Value could not be bound to cell.\");\n\t\t}\n\t}\n\n\t/**\n\t *\tGet cell coordinate column\n\t *\n\t *\t@return\tstring\n\t */\n\tpublic function getColumn()\n\t{\n\t\treturn $this->_parent->getCurrentColumn();\n\t}\n\n\t/**\n\t *\tGet cell coordinate row\n\t *\n\t *\t@return\tint\n\t */\n\tpublic function getRow()\n\t{\n\t\treturn $this->_parent->getCurrentRow();\n\t}\n\n\t/**\n\t *\tGet cell coordinate\n\t *\n\t *\t@return\tstring\n\t */\n\tpublic function getCoordinate()\n\t{\n\t\treturn $this->_parent->getCurrentAddress();\n\t}\n\n\t/**\n\t *\tGet cell value\n\t *\n\t *\t@return\tmixed\n\t */\n\tpublic function getValue()\n\t{\n\t\treturn $this->_value;\n\t}\n\n\t/**\n\t *\tGet cell value with formatting\n\t *\n\t *\t@return\tstring\n\t */\n\tpublic function getFormattedValue()\n\t{\n\t\treturn (string) PHPExcel_Style_NumberFormat::toFormattedString(\n\t\t\t\t$this->getCalculatedValue(),\n\t\t\t\t$this->getStyle()\n\t\t\t\t\t->getNumberFormat()->getFormatCode()\n\t\t\t);\n\t}\n\n\t/**\n\t *\tSet cell value\n\t *\n\t *\tSets the value for a cell, automatically determining the datatype using the value binder\n\t *\n\t *\t@param\tmixed\t$pValue\t\t\t\t\tValue\n\t *\t@return\tPHPExcel_Cell\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic function setValue($pValue = NULL)\n\t{\n\t\tif (!self::getValueBinder()->bindValue($this, $pValue)) {\n\t\t\tthrow new PHPExcel_Exception(\"Value could not be bound to cell.\");\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t *\tSet the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder)\n\t *\n\t *\t@param\tmixed\t$pValue\t\t\tValue\n\t *\t@param\tstring\t$pDataType\t\tExplicit data type\n\t *\t@return\tPHPExcel_Cell\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic function setValueExplicit($pValue = NULL, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING)\n\t{\n\t\t// set the value according to data type\n\t\tswitch ($pDataType) {\n\t\t\tcase PHPExcel_Cell_DataType::TYPE_NULL:\n\t\t\t\t$this->_value = $pValue;\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Cell_DataType::TYPE_STRING2:\n\t\t\t\t$pDataType = PHPExcel_Cell_DataType::TYPE_STRING;\n\t\t\tcase PHPExcel_Cell_DataType::TYPE_STRING:\n\t\t\tcase PHPExcel_Cell_DataType::TYPE_INLINE:\n\t\t\t\t$this->_value = PHPExcel_Cell_DataType::checkString($pValue);\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Cell_DataType::TYPE_NUMERIC:\n\t\t\t\t$this->_value = (float)$pValue;\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Cell_DataType::TYPE_FORMULA:\n\t\t\t\t$this->_value = (string)$pValue;\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Cell_DataType::TYPE_BOOL:\n\t\t\t\t$this->_value = (bool)$pValue;\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Cell_DataType::TYPE_ERROR:\n\t\t\t\t$this->_value = PHPExcel_Cell_DataType::checkErrorCode($pValue);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tthrow new PHPExcel_Exception('Invalid datatype: ' . $pDataType);\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// set the datatype\n\t\t$this->_dataType = $pDataType;\n\n\t\treturn $this->notifyCacheController();\n\t}\n\n\t/**\n\t *\tGet calculated cell value\n\t *\n\t *\t@deprecated\t\tSince version 1.7.8 for planned changes to cell for array formula handling\n\t *\n\t *\t@param\tboolean $resetLog  Whether the calculation engine logger should be reset or not\n\t *\t@return\tmixed\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic function getCalculatedValue($resetLog = TRUE)\n\t{\n//echo 'Cell '.$this->getCoordinate().' value is a '.$this->_dataType.' with a value of '.$this->getValue().PHP_EOL;\n\t\tif ($this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA) {\n\t\t\ttry {\n//echo 'Cell value for '.$this->getCoordinate().' is a formula: Calculating value'.PHP_EOL;\n\t\t\t\t$result = PHPExcel_Calculation::getInstance(\n\t\t\t\t\t$this->getWorksheet()->getParent()\n\t\t\t\t)->calculateCellValue($this,$resetLog);\n//echo $this->getCoordinate().' calculation result is '.$result.PHP_EOL;\n\t\t\t\t//\tWe don't yet handle array returns\n\t\t\t\tif (is_array($result)) {\n\t\t\t\t\twhile (is_array($result)) {\n\t\t\t\t\t\t$result = array_pop($result);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} catch ( PHPExcel_Exception $ex ) {\n\t\t\t\tif (($ex->getMessage() === 'Unable to access External Workbook') && ($this->_calculatedValue !== NULL)) {\n//echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL;\n\t\t\t\t\treturn $this->_calculatedValue; // Fallback for calculations referencing external files.\n\t\t\t\t}\n//echo 'Calculation Exception: '.$ex->getMessage().PHP_EOL;\n\t\t\t\t$result = '#N/A';\n\t\t\t\tthrow new PHPExcel_Calculation_Exception(\n\t\t\t\t\t$this->getWorksheet()->getTitle().'!'.$this->getCoordinate().' -> '.$ex->getMessage()\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tif ($result === '#Not Yet Implemented') {\n//echo 'Returning fallback value of '.$this->_calculatedValue.' for cell '.$this->getCoordinate().PHP_EOL;\n\t\t\t\treturn $this->_calculatedValue; // Fallback if calculation engine does not support the formula.\n\t\t\t}\n//echo 'Returning calculated value of '.$result.' for cell '.$this->getCoordinate().PHP_EOL;\n\t\t\treturn $result;\n\t\t} elseif($this->_value instanceof PHPExcel_RichText) {\n//\t\techo 'Cell value for '.$this->getCoordinate().' is rich text: Returning data value of '.$this->_value.'<br />';\n\t\t\treturn $this->_value->getPlainText();\n\t\t}\n//\t\techo 'Cell value for '.$this->getCoordinate().' is not a formula: Returning data value of '.$this->_value.'<br />';\n\t\treturn $this->_value;\n\t}\n\n\t/**\n\t *\tSet old calculated value (cached)\n\t *\n\t *\t@param\tmixed $pValue\tValue\n\t *\t@return\tPHPExcel_Cell\n\t */\n\tpublic function setCalculatedValue($pValue = NULL)\n\t{\n\t\tif ($pValue !== NULL) {\n\t\t\t$this->_calculatedValue = (is_numeric($pValue)) ? (float) $pValue : $pValue;\n\t\t}\n\n\t\treturn $this->notifyCacheController();\n\t}\n\n\t/**\n\t *\tGet old calculated value (cached)\n\t *\tThis returns the value last calculated by MS Excel or whichever spreadsheet program was used to\n\t *\t\tcreate the original spreadsheet file.\n\t *\tNote that this value is not guaranteed to refelect the actual calculated value because it is\n\t *\t\tpossible that auto-calculation was disabled in the original spreadsheet, and underlying data\n\t *\t\tvalues used by the formula have changed since it was last calculated.\n\t *\n\t *\t@return\tmixed\n\t */\n\tpublic function getOldCalculatedValue()\n\t{\n\t\treturn $this->_calculatedValue;\n\t}\n\n\t/**\n\t *\tGet cell data type\n\t *\n\t *\t@return string\n\t */\n\tpublic function getDataType()\n\t{\n\t\treturn $this->_dataType;\n\t}\n\n\t/**\n\t *\tSet cell data type\n\t *\n\t *\t@param\tstring $pDataType\n\t *\t@return\tPHPExcel_Cell\n\t */\n\tpublic function setDataType($pDataType = PHPExcel_Cell_DataType::TYPE_STRING)\n\t{\n\t\tif ($pDataType == PHPExcel_Cell_DataType::TYPE_STRING2)\n\t\t\t$pDataType = PHPExcel_Cell_DataType::TYPE_STRING;\n\n\t\t$this->_dataType = $pDataType;\n\n\t\treturn $this->notifyCacheController();\n\t}\n\n    /**\n     *  Identify if the cell contains a formula\n     *\n     *  @return boolean\n     */\n    public function isFormula()\n    {\n        return $this->_dataType == PHPExcel_Cell_DataType::TYPE_FORMULA;\n    }\n\n\t/**\n\t *\tDoes this cell contain Data validation rules?\n\t *\n\t *\t@return\tboolean\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic function hasDataValidation()\n\t{\n\t\tif (!isset($this->_parent)) {\n\t\t\tthrow new PHPExcel_Exception('Cannot check for data validation when cell is not bound to a worksheet');\n\t\t}\n\n\t\treturn $this->getWorksheet()->dataValidationExists($this->getCoordinate());\n\t}\n\n\t/**\n\t *\tGet Data validation rules\n\t *\n\t *\t@return\tPHPExcel_Cell_DataValidation\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic function getDataValidation()\n\t{\n\t\tif (!isset($this->_parent)) {\n\t\t\tthrow new PHPExcel_Exception('Cannot get data validation for cell that is not bound to a worksheet');\n\t\t}\n\n\t\treturn $this->getWorksheet()->getDataValidation($this->getCoordinate());\n\t}\n\n\t/**\n\t *\tSet Data validation rules\n\t *\n\t *\t@param\tPHPExcel_Cell_DataValidation\t$pDataValidation\n\t *\t@return\tPHPExcel_Cell\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic function setDataValidation(PHPExcel_Cell_DataValidation $pDataValidation = NULL)\n\t{\n\t\tif (!isset($this->_parent)) {\n\t\t\tthrow new PHPExcel_Exception('Cannot set data validation for cell that is not bound to a worksheet');\n\t\t}\n\n\t\t$this->getWorksheet()->setDataValidation($this->getCoordinate(), $pDataValidation);\n\n\t\treturn $this->notifyCacheController();\n\t}\n\n\t/**\n\t *\tDoes this cell contain a Hyperlink?\n\t *\n\t *\t@return boolean\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic function hasHyperlink()\n\t{\n\t\tif (!isset($this->_parent)) {\n\t\t\tthrow new PHPExcel_Exception('Cannot check for hyperlink when cell is not bound to a worksheet');\n\t\t}\n\n\t\treturn $this->getWorksheet()->hyperlinkExists($this->getCoordinate());\n\t}\n\n\t/**\n\t *\tGet Hyperlink\n\t *\n\t *\t@return\tPHPExcel_Cell_Hyperlink\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic function getHyperlink()\n\t{\n\t\tif (!isset($this->_parent)) {\n\t\t\tthrow new PHPExcel_Exception('Cannot get hyperlink for cell that is not bound to a worksheet');\n\t\t}\n\n\t\treturn $this->getWorksheet()->getHyperlink($this->getCoordinate());\n\t}\n\n\t/**\n\t *\tSet Hyperlink\n\t *\n\t *\t@param\tPHPExcel_Cell_Hyperlink\t$pHyperlink\n\t *\t@return\tPHPExcel_Cell\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic function setHyperlink(PHPExcel_Cell_Hyperlink $pHyperlink = NULL)\n\t{\n\t\tif (!isset($this->_parent)) {\n\t\t\tthrow new PHPExcel_Exception('Cannot set hyperlink for cell that is not bound to a worksheet');\n\t\t}\n\n\t\t$this->getWorksheet()->setHyperlink($this->getCoordinate(), $pHyperlink);\n\n\t\treturn $this->notifyCacheController();\n\t}\n\n\t/**\n\t *\tGet parent worksheet\n\t *\n\t *\t@return PHPExcel_CachedObjectStorage_CacheBase\n\t */\n\tpublic function getParent() {\n\t\treturn $this->_parent;\n\t}\n\n\t/**\n\t *\tGet parent worksheet\n\t *\n\t *\t@return PHPExcel_Worksheet\n\t */\n\tpublic function getWorksheet() {\n\t\treturn $this->_parent->getParent();\n\t}\n\n\t/**\n\t *\tIs this cell in a merge range\n\t *\n\t *\t@return boolean\n\t */\n    public function isInMergeRange() {\n        return (boolean) $this->getMergeRange();\n    }\n\n\t/**\n\t *\tIs this cell the master (top left cell) in a merge range (that holds the actual data value)\n\t *\n\t *\t@return boolean\n\t */\n    public function isMergeRangeValueCell() {\n        if ($mergeRange = $this->getMergeRange()) {\n            $mergeRange = PHPExcel_Cell::splitRange($mergeRange);\n            list($startCell) = $mergeRange[0];\n            if ($this->getCoordinate() === $startCell) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n\t/**\n\t *\tIf this cell is in a merge range, then return the range\n\t *\n\t *\t@return string\n\t */\n    public function getMergeRange() {\n        foreach($this->getWorksheet()->getMergeCells() as $mergeRange) {\n            if ($this->isInRange($mergeRange)) {\n                return $mergeRange;\n            }\n        }\n        return false;\n    }\n\n\t/**\n\t *\tGet cell style\n\t *\n\t *\t@return\tPHPExcel_Style\n\t */\n\tpublic function getStyle()\n\t{\n\t\treturn $this->getWorksheet()->getStyle($this->getCoordinate());\n\t}\n\n\t/**\n\t *\tRe-bind parent\n\t *\n\t *\t@param\tPHPExcel_Worksheet $parent\n\t *\t@return\tPHPExcel_Cell\n\t */\n\tpublic function rebindParent(PHPExcel_Worksheet $parent) {\n\t\t$this->_parent = $parent->getCellCacheController();\n\n\t\treturn $this->notifyCacheController();\n\t}\n\n\t/**\n\t *\tIs cell in a specific range?\n\t *\n\t *\t@param\tstring\t$pRange\t\tCell range (e.g. A1:A1)\n\t *\t@return\tboolean\n\t */\n\tpublic function isInRange($pRange = 'A1:A1')\n\t{\n\t\tlist($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange);\n\n\t\t// Translate properties\n\t\t$myColumn\t= self::columnIndexFromString($this->getColumn());\n\t\t$myRow\t\t= $this->getRow();\n\n\t\t// Verify if cell is in range\n\t\treturn (($rangeStart[0] <= $myColumn) && ($rangeEnd[0] >= $myColumn) &&\n\t\t\t\t($rangeStart[1] <= $myRow) && ($rangeEnd[1] >= $myRow)\n\t\t\t   );\n\t}\n\n\t/**\n\t *\tCoordinate from string\n\t *\n\t *\t@param\tstring\t$pCoordinateString\n\t *\t@return\tarray\tArray containing column and row (indexes 0 and 1)\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic static function coordinateFromString($pCoordinateString = 'A1')\n\t{\n\t\tif (preg_match(\"/^([$]?[A-Z]{1,3})([$]?\\d{1,7})$/\", $pCoordinateString, $matches)) {\n\t\t\treturn array($matches[1],$matches[2]);\n\t\t} elseif ((strpos($pCoordinateString,':') !== FALSE) || (strpos($pCoordinateString,',') !== FALSE)) {\n\t\t\tthrow new PHPExcel_Exception('Cell coordinate string can not be a range of cells');\n\t\t} elseif ($pCoordinateString == '') {\n\t\t\tthrow new PHPExcel_Exception('Cell coordinate can not be zero-length string');\n\t\t}\n\n\t\tthrow new PHPExcel_Exception('Invalid cell coordinate '.$pCoordinateString);\n\t}\n\n\t/**\n\t *\tMake string row, column or cell coordinate absolute\n\t *\n\t *\t@param\tstring\t$pCoordinateString\t\te.g. 'A' or '1' or 'A1'\n\t *\t\t\t\t\tNote that this value can be a row or column reference as well as a cell reference\n\t *\t@return\tstring\tAbsolute coordinate\t\te.g. '$A' or '$1' or '$A$1'\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic static function absoluteReference($pCoordinateString = 'A1')\n\t{\n\t\tif (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) {\n\t\t\t// Split out any worksheet name from the reference\n\t\t\t$worksheet = '';\n\t\t\t$cellAddress = explode('!',$pCoordinateString);\n\t\t\tif (count($cellAddress) > 1) {\n\t\t\t\tlist($worksheet,$pCoordinateString) = $cellAddress;\n\t\t\t}\n\t\t\tif ($worksheet > '')\t$worksheet .= '!';\n\n\t\t\t// Create absolute coordinate\n\t\t\tif (ctype_digit($pCoordinateString)) {\n\t\t\t\treturn $worksheet . '$' . $pCoordinateString;\n\t\t\t} elseif (ctype_alpha($pCoordinateString)) {\n\t\t\t\treturn $worksheet . '$' . strtoupper($pCoordinateString);\n\t\t\t}\n\t\t\treturn $worksheet . self::absoluteCoordinate($pCoordinateString);\n\t\t}\n\n\t\tthrow new PHPExcel_Exception('Cell coordinate string can not be a range of cells');\n\t}\n\n\t/**\n\t *\tMake string coordinate absolute\n\t *\n\t *\t@param\tstring\t$pCoordinateString\t\te.g. 'A1'\n\t *\t@return\tstring\tAbsolute coordinate\t\te.g. '$A$1'\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic static function absoluteCoordinate($pCoordinateString = 'A1')\n\t{\n\t\tif (strpos($pCoordinateString,':') === FALSE && strpos($pCoordinateString,',') === FALSE) {\n\t\t\t// Split out any worksheet name from the coordinate\n\t\t\t$worksheet = '';\n\t\t\t$cellAddress = explode('!',$pCoordinateString);\n\t\t\tif (count($cellAddress) > 1) {\n\t\t\t\tlist($worksheet,$pCoordinateString) = $cellAddress;\n\t\t\t}\n\t\t\tif ($worksheet > '')\t$worksheet .= '!';\n\n\t\t\t// Create absolute coordinate\n\t\t\tlist($column, $row) = self::coordinateFromString($pCoordinateString);\n\t\t\t$column = ltrim($column,'$');\n\t\t\t$row = ltrim($row,'$');\n\t\t\treturn $worksheet . '$' . $column . '$' . $row;\n\t\t}\n\n\t\tthrow new PHPExcel_Exception('Cell coordinate string can not be a range of cells');\n\t}\n\n\t/**\n\t *\tSplit range into coordinate strings\n\t *\n\t *\t@param\tstring\t$pRange\t\te.g. 'B4:D9' or 'B4:D9,H2:O11' or 'B4'\n\t *\t@return\tarray\tArray containg one or more arrays containing one or two coordinate strings\n\t *\t\t\t\t\t\t\t\te.g. array('B4','D9') or array(array('B4','D9'),array('H2','O11'))\n\t *\t\t\t\t\t\t\t\t\t\tor array('B4')\n\t */\n\tpublic static function splitRange($pRange = 'A1:A1')\n\t{\n\t\t// Ensure $pRange is a valid range\n\t\tif(empty($pRange)) {\n\t\t\t$pRange = self::DEFAULT_RANGE;\n\t\t}\n\n\t\t$exploded = explode(',', $pRange);\n\t\t$counter = count($exploded);\n\t\tfor ($i = 0; $i < $counter; ++$i) {\n\t\t\t$exploded[$i] = explode(':', $exploded[$i]);\n\t\t}\n\t\treturn $exploded;\n\t}\n\n\t/**\n\t *\tBuild range from coordinate strings\n\t *\n\t *\t@param\tarray\t$pRange\tArray containg one or more arrays containing one or two coordinate strings\n\t *\t@return\tstring\tString representation of $pRange\n\t *\t@throws\tPHPExcel_Exception\n\t */\n\tpublic static function buildRange($pRange)\n\t{\n\t\t// Verify range\n\t\tif (!is_array($pRange) || empty($pRange) || !is_array($pRange[0])) {\n\t\t\tthrow new PHPExcel_Exception('Range does not contain any information');\n\t\t}\n\n\t\t// Build range\n\t\t$imploded = array();\n\t\t$counter = count($pRange);\n\t\tfor ($i = 0; $i < $counter; ++$i) {\n\t\t\t$pRange[$i] = implode(':', $pRange[$i]);\n\t\t}\n\t\t$imploded = implode(',', $pRange);\n\n\t\treturn $imploded;\n\t}\n\n\t/**\n\t *\tCalculate range boundaries\n\t *\n\t *\t@param\tstring\t$pRange\t\tCell range (e.g. A1:A1)\n\t *\t@return\tarray\tRange coordinates array(Start Cell, End Cell)\n\t *\t\t\t\t\twhere Start Cell and End Cell are arrays (Column Number, Row Number)\n\t */\n\tpublic static function rangeBoundaries($pRange = 'A1:A1')\n\t{\n\t\t// Ensure $pRange is a valid range\n\t\tif(empty($pRange)) {\n\t\t\t$pRange = self::DEFAULT_RANGE;\n\t\t}\n\n\t\t// Uppercase coordinate\n\t\t$pRange = strtoupper($pRange);\n\n\t\t// Extract range\n\t\tif (strpos($pRange, ':') === FALSE) {\n\t\t\t$rangeA = $rangeB = $pRange;\n\t\t} else {\n\t\t\tlist($rangeA, $rangeB) = explode(':', $pRange);\n\t\t}\n\n\t\t// Calculate range outer borders\n\t\t$rangeStart = self::coordinateFromString($rangeA);\n\t\t$rangeEnd\t= self::coordinateFromString($rangeB);\n\n\t\t// Translate column into index\n\t\t$rangeStart[0]\t= self::columnIndexFromString($rangeStart[0]);\n\t\t$rangeEnd[0]\t= self::columnIndexFromString($rangeEnd[0]);\n\n\t\treturn array($rangeStart, $rangeEnd);\n\t}\n\n\t/**\n\t *\tCalculate range dimension\n\t *\n\t *\t@param\tstring\t$pRange\t\tCell range (e.g. A1:A1)\n\t *\t@return\tarray\tRange dimension (width, height)\n\t */\n\tpublic static function rangeDimension($pRange = 'A1:A1')\n\t{\n\t\t// Calculate range outer borders\n\t\tlist($rangeStart,$rangeEnd) = self::rangeBoundaries($pRange);\n\n\t\treturn array( ($rangeEnd[0] - $rangeStart[0] + 1), ($rangeEnd[1] - $rangeStart[1] + 1) );\n\t}\n\n\t/**\n\t *\tCalculate range boundaries\n\t *\n\t *\t@param\tstring\t$pRange\t\tCell range (e.g. A1:A1)\n\t *\t@return\tarray\tRange coordinates array(Start Cell, End Cell)\n\t *\t\t\t\t\twhere Start Cell and End Cell are arrays (Column ID, Row Number)\n\t */\n\tpublic static function getRangeBoundaries($pRange = 'A1:A1')\n\t{\n\t\t// Ensure $pRange is a valid range\n\t\tif(empty($pRange)) {\n\t\t\t$pRange = self::DEFAULT_RANGE;\n\t\t}\n\n\t\t// Uppercase coordinate\n\t\t$pRange = strtoupper($pRange);\n\n\t\t// Extract range\n\t\tif (strpos($pRange, ':') === FALSE) {\n\t\t\t$rangeA = $rangeB = $pRange;\n\t\t} else {\n\t\t\tlist($rangeA, $rangeB) = explode(':', $pRange);\n\t\t}\n\n\t\treturn array( self::coordinateFromString($rangeA), self::coordinateFromString($rangeB));\n\t}\n\n\t/**\n\t *\tColumn index from string\n\t *\n\t *\t@param\tstring $pString\n\t *\t@return\tint Column index (base 1 !!!)\n\t */\n\tpublic static function columnIndexFromString($pString = 'A')\n\t{\n\t\t//\tUsing a lookup cache adds a slight memory overhead, but boosts speed\n\t\t//\tcaching using a static within the method is faster than a class static,\n\t\t//\t\tthough it's additional memory overhead\n\t\tstatic $_indexCache = array();\n\n\t\tif (isset($_indexCache[$pString]))\n\t\t\treturn $_indexCache[$pString];\n\n\t\t//\tIt's surprising how costly the strtoupper() and ord() calls actually are, so we use a lookup array rather than use ord()\n\t\t//\t\tand make it case insensitive to get rid of the strtoupper() as well. Because it's a static, there's no significant\n\t\t//\t\tmemory overhead either\n\t\tstatic $_columnLookup = array(\n\t\t\t'A' => 1, 'B' => 2, 'C' => 3, 'D' => 4, 'E' => 5, 'F' => 6, 'G' => 7, 'H' => 8, 'I' => 9, 'J' => 10, 'K' => 11, 'L' => 12, 'M' => 13,\n\t\t\t'N' => 14, 'O' => 15, 'P' => 16, 'Q' => 17, 'R' => 18, 'S' => 19, 'T' => 20, 'U' => 21, 'V' => 22, 'W' => 23, 'X' => 24, 'Y' => 25, 'Z' => 26,\n\t\t\t'a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5, 'f' => 6, 'g' => 7, 'h' => 8, 'i' => 9, 'j' => 10, 'k' => 11, 'l' => 12, 'm' => 13,\n\t\t\t'n' => 14, 'o' => 15, 'p' => 16, 'q' => 17, 'r' => 18, 's' => 19, 't' => 20, 'u' => 21, 'v' => 22, 'w' => 23, 'x' => 24, 'y' => 25, 'z' => 26\n\t\t);\n\n\t\t//\tWe also use the language construct isset() rather than the more costly strlen() function to match the length of $pString\n\t\t//\t\tfor improved performance\n\t\tif (isset($pString{0})) {\n\t\t\tif (!isset($pString{1})) {\n\t\t\t\t$_indexCache[$pString] = $_columnLookup[$pString];\n\t\t\t\treturn $_indexCache[$pString];\n\t\t\t} elseif(!isset($pString{2})) {\n\t\t\t\t$_indexCache[$pString] = $_columnLookup[$pString{0}] * 26 + $_columnLookup[$pString{1}];\n\t\t\t\treturn $_indexCache[$pString];\n\t\t\t} elseif(!isset($pString{3})) {\n\t\t\t\t$_indexCache[$pString] = $_columnLookup[$pString{0}] * 676 + $_columnLookup[$pString{1}] * 26 + $_columnLookup[$pString{2}];\n\t\t\t\treturn $_indexCache[$pString];\n\t\t\t}\n\t\t}\n\t\tthrow new PHPExcel_Exception(\"Column string index can not be \" . ((isset($pString{0})) ? \"longer than 3 characters\" : \"empty\"));\n\t}\n\n\t/**\n\t *\tString from columnindex\n\t *\n\t *\t@param\tint $pColumnIndex Column index (base 0 !!!)\n\t *\t@return\tstring\n\t */\n\tpublic static function stringFromColumnIndex($pColumnIndex = 0)\n\t{\n\t\t//\tUsing a lookup cache adds a slight memory overhead, but boosts speed\n\t\t//\tcaching using a static within the method is faster than a class static,\n\t\t//\t\tthough it's additional memory overhead\n\t\tstatic $_indexCache = array();\n\n\t\tif (!isset($_indexCache[$pColumnIndex])) {\n\t\t\t// Determine column string\n\t\t\tif ($pColumnIndex < 26) {\n\t\t\t\t$_indexCache[$pColumnIndex] = chr(65 + $pColumnIndex);\n\t\t\t} elseif ($pColumnIndex < 702) {\n\t\t\t\t$_indexCache[$pColumnIndex] = chr(64 + ($pColumnIndex / 26)) .\n\t\t\t\t\t\t\t\t\t\t\t  chr(65 + $pColumnIndex % 26);\n\t\t\t} else {\n\t\t\t\t$_indexCache[$pColumnIndex] = chr(64 + (($pColumnIndex - 26) / 676)) .\n\t\t\t\t\t\t\t\t\t\t\t  chr(65 + ((($pColumnIndex - 26) % 676) / 26)) .\n\t\t\t\t\t\t\t\t\t\t\t  chr(65 + $pColumnIndex % 26);\n\t\t\t}\n\t\t}\n\t\treturn $_indexCache[$pColumnIndex];\n\t}\n\n\t/**\n\t *\tExtract all cell references in range\n\t *\n\t *\t@param\tstring\t$pRange\t\tRange (e.g. A1 or A1:C10 or A1:E10 A20:E25)\n\t *\t@return\tarray\tArray containing single cell references\n\t */\n\tpublic static function extractAllCellReferencesInRange($pRange = 'A1') {\n\t\t// Returnvalue\n\t\t$returnValue = array();\n\n\t\t// Explode spaces\n\t\t$cellBlocks = explode(' ', str_replace('$', '', strtoupper($pRange)));\n\t\tforeach ($cellBlocks as $cellBlock) {\n\t\t\t// Single cell?\n\t\t\tif (strpos($cellBlock,':') === FALSE && strpos($cellBlock,',') === FALSE) {\n\t\t\t\t$returnValue[] = $cellBlock;\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// Range...\n\t\t\t$ranges = self::splitRange($cellBlock);\n\t\t\tforeach($ranges as $range) {\n\t\t\t\t// Single cell?\n\t\t\t\tif (!isset($range[1])) {\n\t\t\t\t\t$returnValue[] = $range[0];\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t// Range...\n\t\t\t\tlist($rangeStart, $rangeEnd)\t= $range;\n\t\t\t\tsscanf($rangeStart,'%[A-Z]%d', $startCol, $startRow);\n\t\t\t\tsscanf($rangeEnd,'%[A-Z]%d', $endCol, $endRow);\n\t\t\t\t$endCol++;\n\n\t\t\t\t// Current data\n\t\t\t\t$currentCol\t= $startCol;\n\t\t\t\t$currentRow\t= $startRow;\n\n\t\t\t\t// Loop cells\n\t\t\t\twhile ($currentCol != $endCol) {\n\t\t\t\t\twhile ($currentRow <= $endRow) {\n\t\t\t\t\t\t$returnValue[] = $currentCol.$currentRow;\n\t\t\t\t\t\t++$currentRow;\n\t\t\t\t\t}\n\t\t\t\t\t++$currentCol;\n\t\t\t\t\t$currentRow = $startRow;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t//\tSort the result by column and row\n\t\t$sortKeys = array();\n\t\tforeach (array_unique($returnValue) as $coord) {\n\t\t\tsscanf($coord,'%[A-Z]%d', $column, $row);\n\t\t\t$sortKeys[sprintf('%3s%09d',$column,$row)] = $coord;\n\t\t}\n\t\tksort($sortKeys);\n\n\t\t// Return value\n\t\treturn array_values($sortKeys);\n\t}\n\n\t/**\n\t * Compare 2 cells\n\t *\n\t * @param\tPHPExcel_Cell\t$a\tCell a\n\t * @param\tPHPExcel_Cell\t$b\tCell b\n\t * @return\tint\t\tResult of comparison (always -1 or 1, never zero!)\n\t */\n\tpublic static function compareCells(PHPExcel_Cell $a, PHPExcel_Cell $b)\n\t{\n\t\tif ($a->getRow() < $b->getRow()) {\n\t\t\treturn -1;\n\t\t} elseif ($a->getRow() > $b->getRow()) {\n\t\t\treturn 1;\n\t\t} elseif (self::columnIndexFromString($a->getColumn()) < self::columnIndexFromString($b->getColumn())) {\n\t\t\treturn -1;\n\t\t} else {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\t/**\n\t * Get value binder to use\n\t *\n\t * @return PHPExcel_Cell_IValueBinder\n\t */\n\tpublic static function getValueBinder() {\n\t\tif (self::$_valueBinder === NULL) {\n\t\t\tself::$_valueBinder = new PHPExcel_Cell_DefaultValueBinder();\n\t\t}\n\n\t\treturn self::$_valueBinder;\n\t}\n\n\t/**\n\t * Set value binder to use\n\t *\n\t * @param PHPExcel_Cell_IValueBinder $binder\n\t * @throws PHPExcel_Exception\n\t */\n\tpublic static function setValueBinder(PHPExcel_Cell_IValueBinder $binder = NULL) {\n\t\tif ($binder === NULL) {\n\t\t\tthrow new PHPExcel_Exception(\"A PHPExcel_Cell_IValueBinder is required for PHPExcel to function correctly.\");\n\t\t}\n\n\t\tself::$_valueBinder = $binder;\n\t}\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif ((is_object($value)) && ($key != '_parent')) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Get index to cellXf\n\t *\n\t * @return int\n\t */\n\tpublic function getXfIndex()\n\t{\n\t\treturn $this->_xfIndex;\n\t}\n\n\t/**\n\t * Set index to cellXf\n\t *\n\t * @param int $pValue\n\t * @return PHPExcel_Cell\n\t */\n\tpublic function setXfIndex($pValue = 0)\n\t{\n\t\t$this->_xfIndex = $pValue;\n\n\t\treturn $this->notifyCacheController();\n\t}\n\n\t/**\n\t *\t@deprecated\t\tSince version 1.7.8 for planned changes to cell for array formula handling\n\t */\n\tpublic function setFormulaAttributes($pAttributes)\n\t{\n\t\t$this->_formulaAttributes = $pAttributes;\n\t\treturn $this;\n\t}\n\n\t/**\n\t *\t@deprecated\t\tSince version 1.7.8 for planned changes to cell for array formula handling\n\t */\n\tpublic function getFormulaAttributes()\n\t{\n\t\treturn $this->_formulaAttributes;\n\t}\n\n    /**\n     * Convert to string\n     *\n     * @return string\n     */\n\tpublic function __toString()\n\t{\n\t\treturn (string) $this->getValue();\n\t}\n\n}\n\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Chart/Axis.php",
    "content": "<?php\nrequire_once 'Properties.php';\n\n/**\n * Created by PhpStorm.\n * User: Wiktor Trzonkowski\n * Date: 6/17/14\n * Time: 12:11 PM\n */\n\nclass PHPExcel_Chart_Axis extends\n  PHPExcel_Properties {\n\n  /**\n   * Axis Number\n   *\n   * @var  array of mixed\n   */\n\n  private\n      $_axis_number = array(\n      'format' => self::FORMAT_CODE_GENERAL,\n      'source_linked' => 1\n  );\n\n  /**\n   * Axis Options\n   *\n   * @var  array of mixed\n   */\n\n  private $_axis_options = array(\n      'minimum' => NULL,\n      'maximum' => NULL,\n      'major_unit' => NULL,\n      'minor_unit' => NULL,\n      'orientation' => self::ORIENTATION_NORMAL,\n      'minor_tick_mark' => self::TICK_MARK_NONE,\n      'major_tick_mark' => self::TICK_MARK_NONE,\n      'axis_labels' => self::AXIS_LABELS_NEXT_TO,\n      'horizontal_crosses' => self::HORIZONTAL_CROSSES_AUTOZERO,\n      'horizontal_crosses_value' => NULL\n  );\n\n  /**\n   * Fill Properties\n   *\n   * @var  array of mixed\n   */\n\n  private $_fill_properties = array(\n      'type' => self::EXCEL_COLOR_TYPE_ARGB,\n      'value' => NULL,\n      'alpha' => 0\n  );\n\n  /**\n   * Line Properties\n   *\n   * @var  array of mixed\n   */\n\n  private $_line_properties = array(\n      'type' => self::EXCEL_COLOR_TYPE_ARGB,\n      'value' => NULL,\n      'alpha' => 0\n  );\n\n  /**\n   * Line Style Properties\n   *\n   * @var  array of mixed\n   */\n\n  private $_line_style_properties = array(\n      'width' => '9525',\n      'compound' => self::LINE_STYLE_COMPOUND_SIMPLE,\n      'dash' => self::LINE_STYLE_DASH_SOLID,\n      'cap' => self::LINE_STYLE_CAP_FLAT,\n      'join' => self::LINE_STYLE_JOIN_BEVEL,\n      'arrow' => array(\n          'head' => array(\n              'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW,\n              'size' => self::LINE_STYLE_ARROW_SIZE_5\n          ),\n          'end' => array(\n              'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW,\n              'size' => self::LINE_STYLE_ARROW_SIZE_8\n          ),\n      )\n  );\n\n  /**\n   * Shadow Properties\n   *\n   * @var  array of mixed\n   */\n\n  private $_shadow_properties = array(\n      'presets' => self::SHADOW_PRESETS_NOSHADOW,\n      'effect' => NULL,\n      'color' => array(\n          'type' => self::EXCEL_COLOR_TYPE_STANDARD,\n          'value' => 'black',\n          'alpha' => 40,\n      ),\n      'size' => array(\n          'sx' => NULL,\n          'sy' => NULL,\n          'kx' => NULL\n      ),\n      'blur' => NULL,\n      'direction' => NULL,\n      'distance' => NULL,\n      'algn' => NULL,\n      'rotWithShape' => NULL\n  );\n\n  /**\n   * Glow Properties\n   *\n   * @var  array of mixed\n   */\n\n  private $_glow_properties = array(\n      'size' => NULL,\n      'color' => array(\n          'type' => self::EXCEL_COLOR_TYPE_STANDARD,\n          'value' => 'black',\n          'alpha' => 40\n      )\n  );\n\n  /**\n   * Soft Edge Properties\n   *\n   * @var  array of mixed\n   */\n\n  private $_soft_edges = array(\n      'size' => NULL\n  );\n\n  /**\n   * Get Series Data Type\n   *\n   * @return  string\n   */\n\n  public function setAxisNumberProperties($format_code) {\n    $this->_axis_number['format'] = (string) $format_code;\n    $this->_axis_number['source_linked'] = 0;\n  }\n\n  /**\n   * Get Axis Number Format Data Type\n   *\n   * @return  string\n   */\n\n  public function getAxisNumberFormat() {\n    return $this->_axis_number['format'];\n  }\n\n  /**\n   * Get Axis Number Source Linked\n   *\n   * @return  string\n   */\n\n  public function getAxisNumberSourceLinked() {\n    return (string) $this->_axis_number['source_linked'];\n  }\n\n  /**\n   * Set Axis Options Properties\n   *\n   * @param string $axis_labels\n   * @param string $horizontal_crosses_value\n   * @param string $horizontal_crosses\n   * @param string $axis_orientation\n   * @param string $major_tmt\n   * @param string $minor_tmt\n   * @param string $minimum\n   * @param string $maximum\n   * @param string $major_unit\n   * @param string $minor_unit\n   *\n   */\n\n  public function setAxisOptionsProperties($axis_labels, $horizontal_crosses_value = NULL, $horizontal_crosses = NULL,\n      $axis_orientation = NULL, $major_tmt = NULL, $minor_tmt = NULL, $minimum = NULL, $maximum = NULL, $major_unit = NULL,\n      $minor_unit = NULL) {\n\n    $this->_axis_options['axis_labels'] = (string) $axis_labels;\n    ($horizontal_crosses_value !== NULL)\n        ? $this->_axis_options['horizontal_crosses_value'] = (string) $horizontal_crosses_value : NULL;\n    ($horizontal_crosses !== NULL) ? $this->_axis_options['horizontal_crosses'] = (string) $horizontal_crosses : NULL;\n    ($axis_orientation !== NULL) ? $this->_axis_options['orientation'] = (string) $axis_orientation : NULL;\n    ($major_tmt !== NULL) ? $this->_axis_options['major_tick_mark'] = (string) $major_tmt : NULL;\n    ($minor_tmt !== NULL) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : NULL;\n    ($minor_tmt !== NULL) ? $this->_axis_options['minor_tick_mark'] = (string) $minor_tmt : NULL;\n    ($minimum !== NULL) ? $this->_axis_options['minimum'] = (string) $minimum : NULL;\n    ($maximum !== NULL) ? $this->_axis_options['maximum'] = (string) $maximum : NULL;\n    ($major_unit !== NULL) ? $this->_axis_options['major_unit'] = (string) $major_unit : NULL;\n    ($minor_unit !== NULL) ? $this->_axis_options['minor_unit'] = (string) $minor_unit : NULL;\n  }\n\n  /**\n   * Get Axis Options Property\n   *\n   * @param string $property\n   *\n   * @return string\n   */\n\n  public function getAxisOptionsProperty($property) {\n    return $this->_axis_options[$property];\n  }\n\n  /**\n   * Set Axis Orientation Property\n   *\n   * @param string $orientation\n   *\n   */\n\n  public function setAxisOrientation($orientation) {\n    $this->orientation = (string) $orientation;\n  }\n\n  /**\n   * Set Fill Property\n   *\n   * @param string $color\n   * @param int $alpha\n   * @param string $type\n   *\n   */\n\n  public function setFillParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) {\n    $this->_fill_properties = $this->setColorProperties($color, $alpha, $type);\n  }\n\n  /**\n   * Set Line Property\n   *\n   * @param string $color\n   * @param int $alpha\n   * @param string $type\n   *\n   */\n\n  public function setLineParameters($color, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_ARGB) {\n    $this->_line_properties = $this->setColorProperties($color, $alpha, $type);\n  }\n\n  /**\n   * Get Fill Property\n   *\n   * @param string $property\n   *\n   * @return string\n   */\n\n  public function getFillProperty($property) {\n    return $this->_fill_properties[$property];\n  }\n\n  /**\n   * Get Line Property\n   *\n   * @param string $property\n   *\n   * @return string\n   */\n\n  public function getLineProperty($property) {\n    return $this->_line_properties[$property];\n  }\n\n  /**\n   * Set Line Style Properties\n   *\n   * @param float $line_width\n   * @param string $compound_type\n   * @param string $dash_type\n   * @param string $cap_type\n   * @param string $join_type\n   * @param string $head_arrow_type\n   * @param string $head_arrow_size\n   * @param string $end_arrow_type\n   * @param string $end_arrow_size\n   *\n   */\n\n  public function setLineStyleProperties($line_width = NULL, $compound_type = NULL,\n      $dash_type = NULL, $cap_type = NULL, $join_type = NULL, $head_arrow_type = NULL,\n      $head_arrow_size = NULL, $end_arrow_type = NULL, $end_arrow_size = NULL) {\n\n    (!is_null($line_width)) ? $this->_line_style_properties['width'] = $this->getExcelPointsWidth((float) $line_width)\n        : NULL;\n    (!is_null($compound_type)) ? $this->_line_style_properties['compound'] = (string) $compound_type : NULL;\n    (!is_null($dash_type)) ? $this->_line_style_properties['dash'] = (string) $dash_type : NULL;\n    (!is_null($cap_type)) ? $this->_line_style_properties['cap'] = (string) $cap_type : NULL;\n    (!is_null($join_type)) ? $this->_line_style_properties['join'] = (string) $join_type : NULL;\n    (!is_null($head_arrow_type)) ? $this->_line_style_properties['arrow']['head']['type'] = (string) $head_arrow_type\n        : NULL;\n    (!is_null($head_arrow_size)) ? $this->_line_style_properties['arrow']['head']['size'] = (string) $head_arrow_size\n        : NULL;\n    (!is_null($end_arrow_type)) ? $this->_line_style_properties['arrow']['end']['type'] = (string) $end_arrow_type\n        : NULL;\n    (!is_null($end_arrow_size)) ? $this->_line_style_properties['arrow']['end']['size'] = (string) $end_arrow_size\n        : NULL;\n  }\n\n  /**\n   * Get Line Style Property\n   *\n   * @param array|string $elements\n   *\n   * @return string\n   */\n\n  public function getLineStyleProperty($elements) {\n    return $this->getArrayElementsValue($this->_line_style_properties, $elements);\n  }\n\n  /**\n   * Get Line Style Arrow Excel Width\n   *\n   * @param string $arrow\n   *\n   * @return string\n   */\n\n  public function getLineStyleArrowWidth($arrow) {\n    return $this->getLineStyleArrowSize($this->_line_style_properties['arrow'][$arrow]['size'], 'w');\n  }\n\n  /**\n   * Get Line Style Arrow Excel Length\n   *\n   * @param string $arrow\n   *\n   * @return string\n   */\n\n  public function getLineStyleArrowLength($arrow) {\n    return $this->getLineStyleArrowSize($this->_line_style_properties['arrow'][$arrow]['size'], 'len');\n  }\n\n  /**\n   * Set Shadow Properties\n   *\n   * @param int $shadow_presets\n   * @param string $sh_color_value\n   * @param string $sh_color_type\n   * @param string $sh_color_alpha\n   * @param float $sh_blur\n   * @param int $sh_angle\n   * @param float $sh_distance\n   *\n   */\n\n  public function setShadowProperties($sh_presets, $sh_color_value = NULL, $sh_color_type = NULL, $sh_color_alpha = NULL, $sh_blur = NULL, $sh_angle = NULL, $sh_distance = NULL) {\n    $this\n        ->_setShadowPresetsProperties((int) $sh_presets)\n        ->_setShadowColor(\n            is_null($sh_color_value) ? $this->_shadow_properties['color']['value'] : $sh_color_value\n            , is_null($sh_color_alpha) ? (int) $this->_shadow_properties['color']['alpha'] : $sh_color_alpha\n            , is_null($sh_color_type) ? $this->_shadow_properties['color']['type'] : $sh_color_type)\n        ->_setShadowBlur($sh_blur)\n        ->_setShadowAngle($sh_angle)\n        ->_setShadowDistance($sh_distance);\n  }\n\n  /**\n   * Set Shadow Color\n   *\n   * @param int $shadow_presets\n   *\n   * @return PHPExcel_Chart_Axis\n   */\n\n  private function _setShadowPresetsProperties($shadow_presets) {\n    $this->_shadow_properties['presets'] = $shadow_presets;\n    $this->_setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets));\n\n    return $this;\n  }\n\n  /**\n   * Set Shadow Properties from Maped Values\n   *\n   * @param array $properties_map\n   * @param * $reference\n   *\n   * @return PHPExcel_Chart_Axis\n   */\n\n  private function _setShadowProperiesMapValues(array $properties_map, &$reference = NULL) {\n    $base_reference = $reference;\n    foreach ($properties_map as $property_key => $property_val) {\n      if (is_array($property_val)) {\n        if ($reference === NULL) {\n          $reference = & $this->_shadow_properties[$property_key];\n        } else {\n          $reference = & $reference[$property_key];\n        }\n        $this->_setShadowProperiesMapValues($property_val, $reference);\n      } else {\n        if ($base_reference === NULL) {\n          $this->_shadow_properties[$property_key] = $property_val;\n        } else {\n          $reference[$property_key] = $property_val;\n        }\n      }\n    }\n\n    return $this;\n  }\n\n  /**\n   * Set Shadow Color\n   *\n   * @param string $color\n   * @param int $alpha\n   * @param string $type\n   *\n   * @return PHPExcel_Chart_Axis\n   */\n\n  private function _setShadowColor($color, $alpha, $type) {\n    $this->_shadow_properties['color'] = $this->setColorProperties($color, $alpha, $type);\n\n    return $this;\n  }\n\n  /**\n   * Set Shadow Blur\n   *\n   * @param float $blur\n   *\n   * @return PHPExcel_Chart_Axis\n   */\n\n  private function _setShadowBlur($blur) {\n    if ($blur !== NULL) {\n      $this->_shadow_properties['blur'] = (string) $this->getExcelPointsWidth($blur);\n    }\n\n    return $this;\n  }\n\n  /**\n   * Set Shadow Angle\n   *\n   * @param int $angle\n   *\n   * @return PHPExcel_Chart_Axis\n   */\n\n  private function _setShadowAngle($angle) {\n    if ($angle !== NULL) {\n      $this->_shadow_properties['direction'] = (string) $this->getExcelPointsAngle($angle);\n    }\n\n    return $this;\n  }\n\n  /**\n   * Set Shadow Distance\n   *\n   * @param float $distance\n   *\n   * @return PHPExcel_Chart_Axis\n   */\n\n  private function _setShadowDistance($distance) {\n    if ($distance !== NULL) {\n      $this->_shadow_properties['distance'] = (string) $this->getExcelPointsWidth($distance);\n    }\n\n    return $this;\n  }\n\n  /**\n   * Get Glow Property\n   *\n   * @param float $size\n   * @param string $color_value\n   * @param int $color_alpha\n   * @param string $color_type\n   */\n\n  public function getShadowProperty($elements) {\n    return $this->getArrayElementsValue($this->_shadow_properties, $elements);\n  }\n\n  /**\n   * Set Glow Properties\n   *\n   * @param float $size\n   * @param string $color_value\n   * @param int $color_alpha\n   * @param string $color_type\n   */\n\n  public function setGlowProperties($size, $color_value = NULL, $color_alpha = NULL, $color_type = NULL) {\n    $this\n        ->_setGlowSize($size)\n        ->_setGlowColor(\n            is_null($color_value) ? $this->_glow_properties['color']['value'] : $color_value\n            , is_null($color_alpha) ? (int) $this->_glow_properties['color']['alpha'] : $color_alpha\n            , is_null($color_type) ? $this->_glow_properties['color']['type'] : $color_type);\n  }\n\n  /**\n   * Get Glow Property\n   *\n   * @param array|string $property\n   *\n   * @return string\n   */\n\n  public function getGlowProperty($property) {\n    return $this->getArrayElementsValue($this->_glow_properties, $property);\n  }\n\n  /**\n   * Set Glow Color\n   *\n   * @param float $size\n   *\n   * @return PHPExcel_Chart_Axis\n   */\n\n  private function _setGlowSize($size) {\n    if (!is_null($size)) {\n      $this->_glow_properties['size'] = $this->getExcelPointsWidth($size);\n    }\n\n    return $this;\n  }\n\n  /**\n   * Set Glow Color\n   *\n   * @param string $color\n   * @param int $alpha\n   * @param string $type\n   *\n   * @return PHPExcel_Chart_Axis\n   */\n\n  private function _setGlowColor($color, $alpha, $type) {\n    $this->_glow_properties['color'] = $this->setColorProperties($color, $alpha, $type);\n\n    return $this;\n  }\n\n  /**\n   * Set Soft Edges Size\n   *\n   * @param float $size\n   */\n\n  public function setSoftEdges($size) {\n    if (!is_null($size)) {\n      $_soft_edges['size'] = (string) $this->getExcelPointsWidth($size);\n    }\n  }\n\n  /**\n   * Get Soft Edges Size\n   *\n   * @return string\n   */\n\n  public function getSoftEdgesSize() {\n    return $this->_soft_edges['size'];\n  }\n}"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Chart/DataSeries.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Chart_DataSeries\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Chart_DataSeries\n{\n\n\tconst TYPE_BARCHART\t\t\t= 'barChart';\n\tconst TYPE_BARCHART_3D\t\t= 'bar3DChart';\n\tconst TYPE_LINECHART\t\t= 'lineChart';\n\tconst TYPE_LINECHART_3D\t\t= 'line3DChart';\n\tconst TYPE_AREACHART\t\t= 'areaChart';\n\tconst TYPE_AREACHART_3D\t\t= 'area3DChart';\n\tconst TYPE_PIECHART\t\t\t= 'pieChart';\n\tconst TYPE_PIECHART_3D\t\t= 'pie3DChart';\n\tconst TYPE_DOUGHTNUTCHART\t= 'doughnutChart';\n\tconst TYPE_DONUTCHART\t\t= self::TYPE_DOUGHTNUTCHART;\t//\tSynonym\n\tconst TYPE_SCATTERCHART\t\t= 'scatterChart';\n\tconst TYPE_SURFACECHART\t\t= 'surfaceChart';\n\tconst TYPE_SURFACECHART_3D\t= 'surface3DChart';\n\tconst TYPE_RADARCHART\t\t= 'radarChart';\n\tconst TYPE_BUBBLECHART\t\t= 'bubbleChart';\n\tconst TYPE_STOCKCHART\t\t= 'stockChart';\n\tconst TYPE_CANDLECHART\t\t= self::TYPE_STOCKCHART;\t   //\tSynonym\n\n\tconst GROUPING_CLUSTERED\t\t\t= 'clustered';\n\tconst GROUPING_STACKED\t\t\t\t= 'stacked';\n\tconst GROUPING_PERCENT_STACKED\t\t= 'percentStacked';\n\tconst GROUPING_STANDARD\t\t\t\t= 'standard';\n\n\tconst DIRECTION_BAR\t\t\t= 'bar';\n\tconst DIRECTION_HORIZONTAL\t= self::DIRECTION_BAR;\n\tconst DIRECTION_COL\t\t\t= 'col';\n\tconst DIRECTION_COLUMN\t\t= self::DIRECTION_COL;\n\tconst DIRECTION_VERTICAL\t= self::DIRECTION_COL;\n\n\tconst STYLE_LINEMARKER\t\t= 'lineMarker';\n\tconst STYLE_SMOOTHMARKER\t= 'smoothMarker';\n\tconst STYLE_MARKER\t\t\t= 'marker';\n\tconst STYLE_FILLED\t\t\t= 'filled';\n\n\n\t/**\n\t * Series Plot Type\n\t *\n\t * @var string\n\t */\n\tprivate $_plotType = null;\n\n\t/**\n\t * Plot Grouping Type\n\t *\n\t * @var boolean\n\t */\n\tprivate $_plotGrouping = null;\n\n\t/**\n\t * Plot Direction\n\t *\n\t * @var boolean\n\t */\n\tprivate $_plotDirection = null;\n\n\t/**\n\t * Plot Style\n\t *\n\t * @var string\n\t */\n\tprivate $_plotStyle = null;\n\n\t/**\n\t * Order of plots in Series\n\t *\n\t * @var array of integer\n\t */\n\tprivate $_plotOrder = array();\n\n\t/**\n\t * Plot Label\n\t *\n\t * @var array of PHPExcel_Chart_DataSeriesValues\n\t */\n\tprivate $_plotLabel = array();\n\n\t/**\n\t * Plot Category\n\t *\n\t * @var array of PHPExcel_Chart_DataSeriesValues\n\t */\n\tprivate $_plotCategory = array();\n\n\t/**\n\t * Smooth Line\n\t *\n\t * @var string\n\t */\n\tprivate $_smoothLine = null;\n\n\t/**\n\t * Plot Values\n\t *\n\t * @var array of PHPExcel_Chart_DataSeriesValues\n\t */\n\tprivate $_plotValues = array();\n\n\t/**\n\t * Create a new PHPExcel_Chart_DataSeries\n\t */\n\tpublic function __construct($plotType = null, $plotGrouping = null, $plotOrder = array(), $plotLabel = array(), $plotCategory = array(), $plotValues = array(), $plotDirection = null, $smoothLine = null, $plotStyle = null)\n\t{\n\t\t$this->_plotType = $plotType;\n\t\t$this->_plotGrouping = $plotGrouping;\n\t\t$this->_plotOrder = $plotOrder;\n\t\t$keys = array_keys($plotValues);\n\t\t$this->_plotValues = $plotValues;\n\t\tif ((count($plotLabel) == 0) || (is_null($plotLabel[$keys[0]]))) {\n\t\t\t$plotLabel[$keys[0]] = new PHPExcel_Chart_DataSeriesValues();\n\t\t}\n\n\t\t$this->_plotLabel = $plotLabel;\n\t\tif ((count($plotCategory) == 0) || (is_null($plotCategory[$keys[0]]))) {\n\t\t\t$plotCategory[$keys[0]] = new PHPExcel_Chart_DataSeriesValues();\n\t\t}\n\t\t$this->_plotCategory = $plotCategory;\n\t\t$this->_smoothLine = $smoothLine;\n\t\t$this->_plotStyle = $plotStyle;\n\t\t\n\t\tif (is_null($plotDirection)) {\n\t\t\t$plotDirection = self::DIRECTION_COL;\n\t\t}\n\t\t$this->_plotDirection = $plotDirection;\n\t}\n\n\t/**\n\t * Get Plot Type\n\t *\n\t * @return string\n\t */\n\tpublic function getPlotType() {\n\t\treturn $this->_plotType;\n\t}\n\n\t/**\n\t * Set Plot Type\n\t *\n\t * @param string $plotType\n     * @return PHPExcel_Chart_DataSeries\n\t */\n\tpublic function setPlotType($plotType = '') {\n\t\t$this->_plotType = $plotType;\n        return $this;\n\t}\n\n\t/**\n\t * Get Plot Grouping Type\n\t *\n\t * @return string\n\t */\n\tpublic function getPlotGrouping() {\n\t\treturn $this->_plotGrouping;\n\t}\n\n\t/**\n\t * Set Plot Grouping Type\n\t *\n\t * @param string $groupingType\n     * @return PHPExcel_Chart_DataSeries\n\t */\n\tpublic function setPlotGrouping($groupingType = null) {\n\t\t$this->_plotGrouping = $groupingType;\n        return $this;\n\t}\n\n\t/**\n\t * Get Plot Direction\n\t *\n\t * @return string\n\t */\n\tpublic function getPlotDirection() {\n\t\treturn $this->_plotDirection;\n\t}\n\n\t/**\n\t * Set Plot Direction\n\t *\n\t * @param string $plotDirection\n     * @return PHPExcel_Chart_DataSeries\n\t */\n\tpublic function setPlotDirection($plotDirection = null) {\n\t\t$this->_plotDirection = $plotDirection;\n        return $this;\n\t}\n\n\t/**\n\t * Get Plot Order\n\t *\n\t * @return string\n\t */\n\tpublic function getPlotOrder() {\n\t\treturn $this->_plotOrder;\n\t}\n\n\t/**\n\t * Get Plot Labels\n\t *\n\t * @return array of PHPExcel_Chart_DataSeriesValues\n\t */\n\tpublic function getPlotLabels() {\n\t\treturn $this->_plotLabel;\n\t}\n\n\t/**\n\t * Get Plot Label by Index\n\t *\n\t * @return PHPExcel_Chart_DataSeriesValues\n\t */\n\tpublic function getPlotLabelByIndex($index) {\n\t\t$keys = array_keys($this->_plotLabel);\n\t\tif (in_array($index,$keys)) {\n\t\t\treturn $this->_plotLabel[$index];\n\t\t} elseif(isset($keys[$index])) {\n\t\t\treturn $this->_plotLabel[$keys[$index]];\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Get Plot Categories\n\t *\n\t * @return array of PHPExcel_Chart_DataSeriesValues\n\t */\n\tpublic function getPlotCategories() {\n\t\treturn $this->_plotCategory;\n\t}\n\n\t/**\n\t * Get Plot Category by Index\n\t *\n\t * @return PHPExcel_Chart_DataSeriesValues\n\t */\n\tpublic function getPlotCategoryByIndex($index) {\n\t\t$keys = array_keys($this->_plotCategory);\n\t\tif (in_array($index,$keys)) {\n\t\t\treturn $this->_plotCategory[$index];\n\t\t} elseif(isset($keys[$index])) {\n\t\t\treturn $this->_plotCategory[$keys[$index]];\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Get Plot Style\n\t *\n\t * @return string\n\t */\n\tpublic function getPlotStyle() {\n\t\treturn $this->_plotStyle;\n\t}\n\n\t/**\n\t * Set Plot Style\n\t *\n\t * @param string $plotStyle\n     * @return PHPExcel_Chart_DataSeries\n\t */\n\tpublic function setPlotStyle($plotStyle = null) {\n\t\t$this->_plotStyle = $plotStyle;\n        return $this;\n\t}\n\n\t/**\n\t * Get Plot Values\n\t *\n\t * @return array of PHPExcel_Chart_DataSeriesValues\n\t */\n\tpublic function getPlotValues() {\n\t\treturn $this->_plotValues;\n\t}\n\n\t/**\n\t * Get Plot Values by Index\n\t *\n\t * @return PHPExcel_Chart_DataSeriesValues\n\t */\n\tpublic function getPlotValuesByIndex($index) {\n\t\t$keys = array_keys($this->_plotValues);\n\t\tif (in_array($index,$keys)) {\n\t\t\treturn $this->_plotValues[$index];\n\t\t} elseif(isset($keys[$index])) {\n\t\t\treturn $this->_plotValues[$keys[$index]];\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Get Number of Plot Series\n\t *\n\t * @return integer\n\t */\n\tpublic function getPlotSeriesCount() {\n\t\treturn count($this->_plotValues);\n\t}\n\n\t/**\n\t * Get Smooth Line\n\t *\n\t * @return boolean\n\t */\n\tpublic function getSmoothLine() {\n\t\treturn $this->_smoothLine;\n\t}\n\n\t/**\n\t * Set Smooth Line\n\t *\n\t * @param boolean $smoothLine\n     * @return PHPExcel_Chart_DataSeries\n\t */\n\tpublic function setSmoothLine($smoothLine = TRUE) {\n\t\t$this->_smoothLine = $smoothLine;\n        return $this;\n\t}\n\n\tpublic function refresh(PHPExcel_Worksheet $worksheet) {\n\t    foreach($this->_plotValues as $plotValues) {\n\t\t\tif ($plotValues !== NULL)\n\t\t\t\t$plotValues->refresh($worksheet, TRUE);\n\t\t}\n\t\tforeach($this->_plotLabel as $plotValues) {\n\t\t\tif ($plotValues !== NULL)\n\t\t\t\t$plotValues->refresh($worksheet, TRUE);\n\t\t}\n\t\tforeach($this->_plotCategory as $plotValues) {\n\t\t\tif ($plotValues !== NULL)\n\t\t\t\t$plotValues->refresh($worksheet, FALSE);\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Chart/DataSeriesValues.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Chart_DataSeriesValues\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Chart_DataSeriesValues\n{\n\n\tconst DATASERIES_TYPE_STRING\t= 'String';\n\tconst DATASERIES_TYPE_NUMBER\t= 'Number';\n\n\tprivate static $_dataTypeValues = array(\n\t\tself::DATASERIES_TYPE_STRING,\n\t\tself::DATASERIES_TYPE_NUMBER,\n\t);\n\n\t/**\n\t * Series Data Type\n\t *\n\t * @var\tstring\n\t */\n\tprivate $_dataType = null;\n\n\t/**\n\t * Series Data Source\n\t *\n\t * @var\tstring\n\t */\n\tprivate $_dataSource = null;\n\n\t/**\n\t * Format Code\n\t *\n\t * @var\tstring\n\t */\n\tprivate $_formatCode = null;\n\n\t/**\n\t * Series Point Marker\n\t *\n\t * @var\tstring\n\t */\n\tprivate $_marker = null;\n\n\t/**\n\t * Point Count (The number of datapoints in the dataseries)\n\t *\n\t * @var\tinteger\n\t */\n\tprivate $_pointCount = 0;\n\n\t/**\n\t * Data Values\n\t *\n\t * @var\tarray of mixed\n\t */\n\tprivate $_dataValues = array();\n\n\t/**\n\t * Create a new PHPExcel_Chart_DataSeriesValues object\n\t */\n\tpublic function __construct($dataType = self::DATASERIES_TYPE_NUMBER, $dataSource = null, $formatCode = null, $pointCount = 0, $dataValues = array(), $marker = null)\n\t{\n\t\t$this->setDataType($dataType);\n\t\t$this->_dataSource = $dataSource;\n\t\t$this->_formatCode = $formatCode;\n\t\t$this->_pointCount = $pointCount;\n\t\t$this->_dataValues = $dataValues;\n\t\t$this->_marker = $marker;\n\t}\n\n\t/**\n\t * Get Series Data Type\n\t *\n\t * @return\tstring\n\t */\n\tpublic function getDataType() {\n\t\treturn $this->_dataType;\n\t}\n\n\t/**\n\t * Set Series Data Type\n\t *\n\t * @param\tstring\t$dataType\tDatatype of this data series\n\t *\t\t\t\t\t\t\t\tTypical values are:\n\t *\t\t\t\t\t\t\t\t\tPHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_STRING\n\t *\t\t\t\t\t\t\t\t\t\tNormally used for axis point values\n\t *\t\t\t\t\t\t\t\t\tPHPExcel_Chart_DataSeriesValues::DATASERIES_TYPE_NUMBER\n\t *\t\t\t\t\t\t\t\t\t\tNormally used for chart data values\n\t * @return\tPHPExcel_Chart_DataSeriesValues\n\t */\n\tpublic function setDataType($dataType = self::DATASERIES_TYPE_NUMBER) {\n\t\tif (!in_array($dataType, self::$_dataTypeValues)) {\n    \t\tthrow new PHPExcel_Chart_Exception('Invalid datatype for chart data series values');\n\t\t}\n\t\t$this->_dataType = $dataType;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Series Data Source (formula)\n\t *\n\t * @return\tstring\n\t */\n\tpublic function getDataSource() {\n\t\treturn $this->_dataSource;\n\t}\n\n\t/**\n\t * Set Series Data Source (formula)\n\t *\n\t * @param\tstring\t$dataSource\n\t * @return\tPHPExcel_Chart_DataSeriesValues\n\t */\n\tpublic function setDataSource($dataSource = null, $refreshDataValues = true) {\n\t\t$this->_dataSource = $dataSource;\n\n\t\tif ($refreshDataValues) {\n\t\t\t//\tTO DO\n\t\t}\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Point Marker\n\t *\n\t * @return string\n\t */\n\tpublic function getPointMarker() {\n\t\treturn $this->_marker;\n\t}\n\n\t/**\n\t * Set Point Marker\n\t *\n\t * @param\tstring\t$marker\n\t * @return\tPHPExcel_Chart_DataSeriesValues\n\t */\n\tpublic function setPointMarker($marker = null) {\n\t\t$this->_marker = $marker;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Series Format Code\n\t *\n\t * @return\tstring\n\t */\n\tpublic function getFormatCode() {\n\t\treturn $this->_formatCode;\n\t}\n\n\t/**\n\t * Set Series Format Code\n\t *\n\t * @param\tstring\t$formatCode\n\t * @return\tPHPExcel_Chart_DataSeriesValues\n\t */\n\tpublic function setFormatCode($formatCode = null) {\n\t\t$this->_formatCode = $formatCode;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Series Point Count\n\t *\n\t * @return\tinteger\n\t */\n\tpublic function getPointCount() {\n\t\treturn $this->_pointCount;\n\t}\n\n\t/**\n\t * Identify if the Data Series is a multi-level or a simple series\n\t *\n\t * @return\tboolean\n\t */\n\tpublic function isMultiLevelSeries() {\n\t\tif (count($this->_dataValues) > 0) {\n\t\t\treturn is_array($this->_dataValues[0]);\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * Return the level count of a multi-level Data Series\n\t *\n\t * @return\tboolean\n\t */\n\tpublic function multiLevelCount() {\n\t\t$levelCount = 0;\n\t\tforeach($this->_dataValues as $dataValueSet) {\n\t\t\t$levelCount = max($levelCount,count($dataValueSet));\n\t\t}\n\t\treturn $levelCount;\n\t}\n\n\t/**\n\t * Get Series Data Values\n\t *\n\t * @return\tarray of mixed\n\t */\n\tpublic function getDataValues() {\n\t\treturn $this->_dataValues;\n\t}\n\n\t/**\n\t * Get the first Series Data value\n\t *\n\t * @return\tmixed\n\t */\n\tpublic function getDataValue() {\n\t\t$count = count($this->_dataValues);\n\t\tif ($count == 0) {\n\t\t\treturn null;\n\t\t} elseif ($count == 1) {\n\t\t\treturn $this->_dataValues[0];\n\t\t}\n\t\treturn $this->_dataValues;\n\t}\n\n\t/**\n\t * Set Series Data Values\n\t *\n\t * @param\tarray\t$dataValues\n\t * @param\tboolean\t$refreshDataSource\n\t *\t\t\t\t\tTRUE - refresh the value of _dataSource based on the values of $dataValues\n\t *\t\t\t\t\tFALSE - don't change the value of _dataSource\n\t * @return\tPHPExcel_Chart_DataSeriesValues\n\t */\n\tpublic function setDataValues($dataValues = array(), $refreshDataSource = TRUE) {\n\t\t$this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($dataValues);\n\t\t$this->_pointCount = count($dataValues);\n\n\t\tif ($refreshDataSource) {\n\t\t\t//\tTO DO\n\t\t}\n\n\t\treturn $this;\n\t}\n\n\tprivate function _stripNulls($var) {\n\t\treturn $var !== NULL;\n\t}\n\n\tpublic function refresh(PHPExcel_Worksheet $worksheet, $flatten = TRUE) {\n        if ($this->_dataSource !== NULL) {\n        \t$calcEngine = PHPExcel_Calculation::getInstance($worksheet->getParent());\n\t\t\t$newDataValues = PHPExcel_Calculation::_unwrapResult(\n\t\t\t    $calcEngine->_calculateFormulaValue(\n\t\t\t        '='.$this->_dataSource,\n\t\t\t        NULL,\n\t\t\t        $worksheet->getCell('A1')\n\t\t\t    )\n\t\t\t);\n\t\t\tif ($flatten) {\n\t\t\t\t$this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues);\n\t\t\t\tforeach($this->_dataValues as &$dataValue) {\n\t\t\t\t\tif ((!empty($dataValue)) && ($dataValue[0] == '#')) {\n\t\t\t\t\t\t$dataValue = 0.0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tunset($dataValue);\n\t\t\t} else {\n\t\t\t\t$cellRange = explode('!',$this->_dataSource);\n\t\t\t\tif (count($cellRange) > 1) {\n\t\t\t\t\tlist(,$cellRange) = $cellRange;\n\t\t\t\t}\n\n\t\t\t\t$dimensions = PHPExcel_Cell::rangeDimension(str_replace('$','',$cellRange));\n\t\t\t\tif (($dimensions[0] == 1) || ($dimensions[1] == 1)) {\n\t\t\t\t\t$this->_dataValues = PHPExcel_Calculation_Functions::flattenArray($newDataValues);\n\t\t\t\t} else {\n\t\t\t\t\t$newArray = array_values(array_shift($newDataValues));\n\t\t\t\t\tforeach($newArray as $i => $newDataSet) {\n\t\t\t\t\t\t$newArray[$i] = array($newDataSet);\n\t\t\t\t\t}\n\n\t\t\t\t\tforeach($newDataValues as $newDataSet) {\n\t\t\t\t\t\t$i = 0;\n\t\t\t\t\t\tforeach($newDataSet as $newDataVal) {\n\t\t\t\t\t\t\tarray_unshift($newArray[$i++],$newDataVal);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t$this->_dataValues = $newArray;\n\t\t\t\t}\n\t\t\t}\n\t\t\t$this->_pointCount = count($this->_dataValues);\n\t\t}\n\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Chart/Exception.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Chart\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Chart_Exception\n *\n * @category   PHPExcel\n * @package    PHPExcel_Chart\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Chart_Exception extends PHPExcel_Exception {\n\t/**\n\t * Error handler callback\n\t *\n\t * @param mixed $code\n\t * @param mixed $string\n\t * @param mixed $file\n\t * @param mixed $line\n\t * @param mixed $context\n\t */\n\tpublic static function errorHandlerCallback($code, $string, $file, $line, $context) {\n\t\t$e = new self($string, $code);\n\t\t$e->line = $line;\n\t\t$e->file = $file;\n\t\tthrow $e;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Chart/GridLines.php",
    "content": "<?php\nrequire_once 'Properties.php';\n/**\n * Created by PhpStorm.\n * User: Wiktor Trzonkowski\n * Date: 7/2/14\n * Time: 2:36 PM\n */\n\nclass PHPExcel_Chart_GridLines extends\n  PHPExcel_Properties {\n\n  /**\n   * Properties of Class:\n   * Object State (State for Minor Tick Mark) @var bool\n   * Line Properties @var  array of mixed\n   * Shadow Properties @var  array of mixed\n   * Glow Properties @var  array of mixed\n   * Soft Properties @var  array of mixed\n   *\n   */\n\n  private\n      $_object_state = FALSE,\n      $_line_properties = array(\n          'color' => array(\n              'type' => self::EXCEL_COLOR_TYPE_STANDARD,\n              'value' => NULL,\n              'alpha' => 0\n          ),\n          'style' => array(\n              'width' => '9525',\n              'compound' => self::LINE_STYLE_COMPOUND_SIMPLE,\n              'dash' => self::LINE_STYLE_DASH_SOLID,\n              'cap' => self::LINE_STYLE_CAP_FLAT,\n              'join' => self::LINE_STYLE_JOIN_BEVEL,\n              'arrow' => array(\n                  'head' => array(\n                      'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW,\n                      'size' => self::LINE_STYLE_ARROW_SIZE_5\n                  ),\n                  'end' => array(\n                      'type' => self::LINE_STYLE_ARROW_TYPE_NOARROW,\n                      'size' => self::LINE_STYLE_ARROW_SIZE_8\n                  ),\n              )\n          )\n      ),\n      $_shadow_properties = array(\n          'presets' => self::SHADOW_PRESETS_NOSHADOW,\n          'effect' => NULL,\n          'color' => array(\n              'type' => self::EXCEL_COLOR_TYPE_STANDARD,\n              'value' => 'black',\n              'alpha' => 85,\n          ),\n          'size' => array(\n              'sx' => NULL,\n              'sy' => NULL,\n              'kx' => NULL\n          ),\n          'blur' => NULL,\n          'direction' => NULL,\n          'distance' => NULL,\n          'algn' => NULL,\n          'rotWithShape' => NULL\n      ),\n      $_glow_properties = array(\n          'size' => NULL,\n          'color' => array(\n              'type' => self::EXCEL_COLOR_TYPE_STANDARD,\n              'value' => 'black',\n              'alpha' => 40\n          )\n      ),\n      $_soft_edges = array(\n          'size' => NULL\n      );\n\n  /**\n   * Get Object State\n   *\n   * @return bool\n   */\n\n  public function getObjectState() {\n    return $this->_object_state;\n  }\n\n  /**\n   * Change Object State to True\n   *\n   * @return PHPExcel_Chart_GridLines\n   */\n\n  private function _activateObject() {\n    $this->_object_state = TRUE;\n\n    return $this;\n  }\n\n  /**\n   * Set Line Color Properties\n   *\n   * @param string $value\n   * @param int $alpha\n   * @param string $type\n   */\n\n  public function setLineColorProperties($value, $alpha = 0, $type = self::EXCEL_COLOR_TYPE_STANDARD) {\n    $this\n        ->_activateObject()\n        ->_line_properties['color'] = $this->setColorProperties(\n        $value,\n        $alpha,\n        $type);\n  }\n\n  /**\n   * Set Line Color Properties\n   *\n   * @param float $line_width\n   * @param string $compound_type\n   * @param string $dash_type\n   * @param string $cap_type\n   * @param string $join_type\n   * @param string $head_arrow_type\n   * @param string $head_arrow_size\n   * @param string $end_arrow_type\n   * @param string $end_arrow_size\n   */\n\n  public function setLineStyleProperties($line_width = NULL, $compound_type = NULL, $dash_type = NULL, $cap_type = NULL, $join_type = NULL, $head_arrow_type = NULL, $head_arrow_size = NULL, $end_arrow_type = NULL, $end_arrow_size = NULL) {\n    $this->_activateObject();\n    (!is_null($line_width))\n        ? $this->_line_properties['style']['width'] = $this->getExcelPointsWidth((float) $line_width)\n        : NULL;\n    (!is_null($compound_type))\n        ? $this->_line_properties['style']['compound'] = (string) $compound_type\n        : NULL;\n    (!is_null($dash_type))\n        ? $this->_line_properties['style']['dash'] = (string) $dash_type\n        : NULL;\n    (!is_null($cap_type))\n        ? $this->_line_properties['style']['cap'] = (string) $cap_type\n        : NULL;\n    (!is_null($join_type))\n        ? $this->_line_properties['style']['join'] = (string) $join_type\n        : NULL;\n    (!is_null($head_arrow_type))\n        ? $this->_line_properties['style']['arrow']['head']['type'] = (string) $head_arrow_type\n        : NULL;\n    (!is_null($head_arrow_size))\n        ? $this->_line_properties['style']['arrow']['head']['size'] = (string) $head_arrow_size\n        : NULL;\n    (!is_null($end_arrow_type))\n        ? $this->_line_properties['style']['arrow']['end']['type'] = (string) $end_arrow_type\n        : NULL;\n    (!is_null($end_arrow_size))\n        ? $this->_line_properties['style']['arrow']['end']['size'] = (string) $end_arrow_size\n        : NULL;\n  }\n\n  /**\n   * Get Line Color Property\n   *\n   * @param string $parameter\n   *\n   * @return string\n   */\n\n  public function getLineColorProperty($parameter) {\n    return $this->_line_properties['color'][$parameter];\n  }\n\n  /**\n   * Get Line Style Property\n   *\n   * @param  array|string $elements\n   *\n   * @return string\n   */\n\n  public function getLineStyleProperty($elements) {\n    return $this->getArrayElementsValue($this->_line_properties['style'], $elements);\n  }\n\n  /**\n   * Set Glow Properties\n   *\n   * @param  float $size\n   * @param  string $color_value\n   * @param  int $color_alpha\n   * @param  string $color_type\n   *\n   */\n\n  public function setGlowProperties($size, $color_value = NULL, $color_alpha = NULL, $color_type = NULL) {\n    $this\n        ->_activateObject()\n        ->_setGlowSize($size)\n        ->_setGlowColor($color_value, $color_alpha, $color_type);\n  }\n\n  /**\n   * Get Glow Color Property\n   *\n   * @param string $property\n   *\n   * @return string\n   */\n\n  public function getGlowColor($property) {\n    return $this->_glow_properties['color'][$property];\n  }\n\n  /**\n   * Get Glow Size\n   *\n   * @return string\n   */\n\n  public function getGlowSize() {\n    return $this->_glow_properties['size'];\n  }\n\n  /**\n   * Set Glow Size\n   *\n   * @param float $size\n   *\n   * @return PHPExcel_Chart_GridLines\n   */\n\n  private function _setGlowSize($size) {\n    $this->_glow_properties['size'] = $this->getExcelPointsWidth((float) $size);\n\n    return $this;\n  }\n\n  /**\n   * Set Glow Color\n   *\n   * @param string $color\n   * @param int $alpha\n   * @param string $type\n   *\n   * @return PHPExcel_Chart_GridLines\n   */\n\n  private function _setGlowColor($color, $alpha, $type) {\n    if (!is_null($color)) {\n      $this->_glow_properties['color']['value'] = (string) $color;\n    }\n    if (!is_null($alpha)) {\n      $this->_glow_properties['color']['alpha'] = $this->getTrueAlpha((int) $alpha);\n    }\n    if (!is_null($type)) {\n      $this->_glow_properties['color']['type'] = (string) $type;\n    }\n\n    return $this;\n  }\n\n  /**\n   * Get Line Style Arrow Parameters\n   *\n   * @param string $arrow_selector\n   * @param string $property_selector\n   *\n   * @return string\n   */\n\n  public function getLineStyleArrowParameters($arrow_selector, $property_selector) {\n    return $this->getLineStyleArrowSize($this->_line_properties['style']['arrow'][$arrow_selector]['size'], $property_selector);\n  }\n\n  /**\n   * Set Shadow Properties\n   *\n   * @param int $sh_presets\n   * @param string $sh_color_value\n   * @param string $sh_color_type\n   * @param int $sh_color_alpha\n   * @param string $sh_blur\n   * @param int $sh_angle\n   * @param float $sh_distance\n   *\n   */\n\n  public function setShadowProperties($sh_presets, $sh_color_value = NULL, $sh_color_type = NULL, $sh_color_alpha = NULL, $sh_blur = NULL, $sh_angle = NULL, $sh_distance = NULL) {\n    $this\n        ->_activateObject()\n        ->_setShadowPresetsProperties((int) $sh_presets)\n        ->_setShadowColor(\n            is_null($sh_color_value) ? $this->_shadow_properties['color']['value'] : $sh_color_value\n            , is_null($sh_color_alpha) ? (int) $this->_shadow_properties['color']['alpha']\n                : $this->getTrueAlpha($sh_color_alpha)\n            , is_null($sh_color_type) ? $this->_shadow_properties['color']['type'] : $sh_color_type)\n        ->_setShadowBlur($sh_blur)\n        ->_setShadowAngle($sh_angle)\n        ->_setShadowDistance($sh_distance);\n  }\n\n  /**\n   * Set Shadow Presets Properties\n   *\n   * @param int $shadow_presets\n   *\n   * @return PHPExcel_Chart_GridLines\n   */\n\n  private function _setShadowPresetsProperties($shadow_presets) {\n    $this->_shadow_properties['presets'] = $shadow_presets;\n    $this->_setShadowProperiesMapValues($this->getShadowPresetsMap($shadow_presets));\n\n    return $this;\n  }\n\n  /**\n   * Set Shadow Properties Values\n   *\n   * @param array $properties_map\n   * @param * $reference\n   *\n   * @return PHPExcel_Chart_GridLines\n   */\n\n  private function _setShadowProperiesMapValues(array $properties_map, &$reference = NULL) {\n    $base_reference = $reference;\n    foreach ($properties_map as $property_key => $property_val) {\n      if (is_array($property_val)) {\n        if ($reference === NULL) {\n          $reference = & $this->_shadow_properties[$property_key];\n        } else {\n          $reference = & $reference[$property_key];\n        }\n        $this->_setShadowProperiesMapValues($property_val, $reference);\n      } else {\n        if ($base_reference === NULL) {\n          $this->_shadow_properties[$property_key] = $property_val;\n        } else {\n          $reference[$property_key] = $property_val;\n        }\n      }\n    }\n\n    return $this;\n  }\n\n  /**\n   * Set Shadow Color\n   *\n   * @param string $color\n   * @param int $alpha\n   * @param string $type\n   *\n   * @return PHPExcel_Chart_GridLines\n   */\n\n  private function _setShadowColor($color, $alpha, $type) {\n    if (!is_null($color)) {\n      $this->_shadow_properties['color']['value'] = (string) $color;\n    }\n    if (!is_null($alpha)) {\n      $this->_shadow_properties['color']['alpha'] = $this->getTrueAlpha((int) $alpha);\n    }\n    if (!is_null($type)) {\n      $this->_shadow_properties['color']['type'] = (string) $type;\n    }\n\n    return $this;\n  }\n\n  /**\n   * Set Shadow Blur\n   *\n   * @param float $blur\n   *\n   * @return PHPExcel_Chart_GridLines\n   */\n\n  private function _setShadowBlur($blur) {\n    if ($blur !== NULL) {\n      $this->_shadow_properties['blur'] = (string) $this->getExcelPointsWidth($blur);\n    }\n\n    return $this;\n  }\n\n  /**\n   * Set Shadow Angle\n   *\n   * @param int $angle\n   *\n   * @return PHPExcel_Chart_GridLines\n   */\n\n  private function _setShadowAngle($angle) {\n    if ($angle !== NULL) {\n      $this->_shadow_properties['direction'] = (string) $this->getExcelPointsAngle($angle);\n    }\n\n    return $this;\n  }\n\n  /**\n   * Set Shadow Distance\n   *\n   * @param float $distance\n   *\n   * @return PHPExcel_Chart_GridLines\n   */\n\n  private function _setShadowDistance($distance) {\n    if ($distance !== NULL) {\n      $this->_shadow_properties['distance'] = (string) $this->getExcelPointsWidth($distance);\n    }\n\n    return $this;\n  }\n\n  /**\n   * Get Shadow Property\n   *\n   * @param string $elements\n   * @param array $elements\n   *\n   * @return string\n   */\n\n  public function getShadowProperty($elements) {\n    return $this->getArrayElementsValue($this->_shadow_properties, $elements);\n  }\n\n  /**\n   * Set Soft Edges Size\n   *\n   * @param float $size\n   */\n\n  public function setSoftEdgesSize($size) {\n    if (!is_null($size)) {\n      $this->_activateObject();\n      $_soft_edges['size'] = (string) $this->getExcelPointsWidth($size);\n    }\n  }\n\n  /**\n   * Get Soft Edges Size\n   *\n   * @return string\n   */\n\n  public function getSoftEdgesSize() {\n    return $this->_soft_edges['size'];\n  }\n}"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Chart/Layout.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Chart_Layout\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Chart_Layout\n{\n\t/**\n\t * layoutTarget\n\t *\n\t * @var string\n\t */\n\tprivate $_layoutTarget = NULL;\n\n\t/**\n\t * X Mode\n\t *\n\t * @var string\n\t */\n\tprivate $_xMode\t\t= NULL;\n\n\t/**\n\t * Y Mode\n\t *\n\t * @var string\n\t */\n\tprivate $_yMode\t\t= NULL;\n\n\t/**\n\t * X-Position\n\t *\n\t * @var float\n\t */\n\tprivate $_xPos\t\t= NULL;\n\n\t/**\n\t * Y-Position\n\t *\n\t * @var float\n\t */\n\tprivate $_yPos\t\t= NULL;\n\n\t/**\n\t * width\n\t *\n\t * @var float\n\t */\n\tprivate $_width\t\t= NULL;\n\n\t/**\n\t * height\n\t *\n\t * @var float\n\t */\n\tprivate $_height\t= NULL;\n\n\t/**\n\t * show legend key\n\t * Specifies that legend keys should be shown in data labels\n\t *\n\t * @var boolean\n\t */\n\tprivate $_showLegendKey\t= NULL;\n\n\t/**\n\t * show value\n\t * Specifies that the value should be shown in a data label.\n\t *\n\t * @var boolean\n\t */\n\tprivate $_showVal\t= NULL;\n\n\t/**\n\t * show category name\n\t * Specifies that the category name should be shown in the data label.\n\t *\n\t * @var boolean\n\t */\n\tprivate $_showCatName\t= NULL;\n\n\t/**\n\t * show data series name\n\t * Specifies that the series name should be shown in the data label.\n\t *\n\t * @var boolean\n\t */\n\tprivate $_showSerName\t= NULL;\n\n\t/**\n\t * show percentage\n\t * Specifies that the percentage should be shown in the data label.\n\t *\n\t * @var boolean\n\t */\n\tprivate $_showPercent\t= NULL;\n\n\t/**\n\t * show bubble size\n\t *\n\t * @var boolean\n\t */\n\tprivate $_showBubbleSize\t= NULL;\n\n\t/**\n\t * show leader lines\n\t * Specifies that leader lines should be shown for the data label.\n\t *\n\t * @var boolean\n\t */\n\tprivate $_showLeaderLines\t= NULL;\n\n\n\t/**\n\t * Create a new PHPExcel_Chart_Layout\n\t */\n\tpublic function __construct($layout=array())\n\t{\n\t\tif (isset($layout['layoutTarget']))\t{ $this->_layoutTarget\t= $layout['layoutTarget'];\t}\n\t\tif (isset($layout['xMode']))\t\t{ $this->_xMode\t\t\t= $layout['xMode'];\t\t\t}\n\t\tif (isset($layout['yMode']))\t\t{ $this->_yMode\t\t\t= $layout['yMode'];\t\t\t}\n\t\tif (isset($layout['x']))\t\t\t{ $this->_xPos\t\t\t= (float) $layout['x'];\t\t}\n\t\tif (isset($layout['y']))\t\t\t{ $this->_yPos\t\t\t= (float) $layout['y'];\t\t}\n\t\tif (isset($layout['w']))\t\t\t{ $this->_width\t\t\t= (float) $layout['w'];\t\t}\n\t\tif (isset($layout['h']))\t\t\t{ $this->_height\t\t= (float) $layout['h'];\t\t}\n\t}\n\n\t/**\n\t * Get Layout Target\n\t *\n\t * @return string\n\t */\n\tpublic function getLayoutTarget() {\n\t\treturn $this->_layoutTarget;\n\t}\n\n\t/**\n\t * Set Layout Target\n\t *\n\t * @param Layout Target $value\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setLayoutTarget($value) {\n\t\t$this->_layoutTarget = $value;\n        return $this;\n\t}\n\n\t/**\n\t * Get X-Mode\n\t *\n\t * @return string\n\t */\n\tpublic function getXMode() {\n\t\treturn $this->_xMode;\n\t}\n\n\t/**\n\t * Set X-Mode\n\t *\n\t * @param X-Mode $value\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setXMode($value) {\n\t\t$this->_xMode = $value;\n        return $this;\n\t}\n\n\t/**\n\t * Get Y-Mode\n\t *\n\t * @return string\n\t */\n\tpublic function getYMode() {\n\t\treturn $this->_yMode;\n\t}\n\n\t/**\n\t * Set Y-Mode\n\t *\n\t * @param Y-Mode $value\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setYMode($value) {\n\t\t$this->_yMode = $value;\n        return $this;\n\t}\n\n\t/**\n\t * Get X-Position\n\t *\n\t * @return number\n\t */\n\tpublic function getXPosition() {\n\t\treturn $this->_xPos;\n\t}\n\n\t/**\n\t * Set X-Position\n\t *\n\t * @param X-Position $value\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setXPosition($value) {\n\t\t$this->_xPos = $value;\n        return $this;\n\t}\n\n\t/**\n\t * Get Y-Position\n\t *\n\t * @return number\n\t */\n\tpublic function getYPosition() {\n\t\treturn $this->_yPos;\n\t}\n\n\t/**\n\t * Set Y-Position\n\t *\n\t * @param Y-Position $value\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setYPosition($value) {\n\t\t$this->_yPos = $value;\n        return $this;\n\t}\n\n\t/**\n\t * Get Width\n\t *\n\t * @return number\n\t */\n\tpublic function getWidth() {\n\t\treturn $this->_width;\n\t}\n\n\t/**\n\t * Set Width\n\t *\n\t * @param Width $value\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setWidth($value) {\n\t\t$this->_width = $value;\n        return $this;\n\t}\n\n\t/**\n\t * Get Height\n\t *\n\t * @return number\n\t */\n\tpublic function getHeight() {\n\t\treturn $this->_height;\n\t}\n\n\t/**\n\t * Set Height\n\t *\n\t * @param Height $value\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setHeight($value) {\n\t\t$this->_height = $value;\n        return $this;\n\t}\n\n\n\t/**\n\t * Get show legend key\n\t *\n\t * @return boolean\n\t */\n\tpublic function getShowLegendKey() {\n\t\treturn $this->_showLegendKey;\n\t}\n\n\t/**\n\t * Set show legend key\n\t * Specifies that legend keys should be shown in data labels.\n\t *\n\t * @param boolean $value\t\tShow legend key\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setShowLegendKey($value) {\n\t\t$this->_showLegendKey = $value;\n        return $this;\n\t}\n\n\t/**\n\t * Get show value\n\t *\n\t * @return boolean\n\t */\n\tpublic function getShowVal() {\n\t\treturn $this->_showVal;\n\t}\n\n\t/**\n\t * Set show val\n\t * Specifies that the value should be shown in data labels.\n\t *\n\t * @param boolean $value\t\tShow val\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setShowVal($value) {\n\t\t$this->_showVal = $value;\n        return $this;\n\t}\n\n\t/**\n\t * Get show category name\n\t *\n\t * @return boolean\n\t */\n\tpublic function getShowCatName() {\n\t\treturn $this->_showCatName;\n\t}\n\n\t/**\n\t * Set show cat name\n\t * Specifies that the category name should be shown in data labels.\n\t *\n\t * @param boolean $value\t\tShow cat name\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setShowCatName($value) {\n\t\t$this->_showCatName = $value;\n        return $this;\n\t}\n\n\t/**\n\t * Get show data series name\n\t *\n\t * @return boolean\n\t */\n\tpublic function getShowSerName() {\n\t\treturn $this->_showSerName;\n\t}\n\n\t/**\n\t * Set show ser name\n\t * Specifies that the series name should be shown in data labels.\n\t *\n\t * @param boolean $value\t\tShow series name\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setShowSerName($value) {\n\t\t$this->_showSerName = $value;\n        return $this;\n\t}\n\n\t/**\n\t * Get show percentage\n\t *\n\t * @return boolean\n\t */\n\tpublic function getShowPercent() {\n\t\treturn $this->_showPercent;\n\t}\n\n\t/**\n\t * Set show percentage\n\t * Specifies that the percentage should be shown in data labels.\n\t *\n\t * @param boolean $value\t\tShow percentage\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setShowPercent($value) {\n\t\t$this->_showPercent = $value;\n        return $this;\n\t}\n\n\t/**\n\t * Get show bubble size\n\t *\n\t * @return boolean\n\t */\n\tpublic function getShowBubbleSize() {\n\t\treturn $this->_showBubbleSize;\n\t}\n\n\t/**\n\t * Set show bubble size\n\t * Specifies that the bubble size should be shown in data labels.\n\t *\n\t * @param boolean $value\t\tShow bubble size\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setShowBubbleSize($value) {\n\t\t$this->_showBubbleSize = $value;\n        return $this;\n\t}\n\n\t/**\n\t * Get show leader lines\n\t *\n\t * @return boolean\n\t */\n\tpublic function getShowLeaderLines() {\n\t\treturn $this->_showLeaderLines;\n\t}\n\n\t/**\n\t * Set show leader lines\n\t * Specifies that leader lines should be shown in data labels.\n\t *\n\t * @param boolean $value\t\tShow leader lines\n     * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function setShowLeaderLines($value) {\n\t\t$this->_showLeaderLines = $value;\n        return $this;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Chart/Legend.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Chart_Legend\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Chart_Legend\n{\n\t/** Legend positions */\n\tconst xlLegendPositionBottom\t= -4107;\t//\tBelow the chart.\n\tconst xlLegendPositionCorner\t= 2;\t\t//\tIn the upper right-hand corner of the chart border.\n\tconst xlLegendPositionCustom\t= -4161;\t//\tA custom position.\n\tconst xlLegendPositionLeft\t\t= -4131;\t//\tLeft of the chart.\n\tconst xlLegendPositionRight\t\t= -4152;\t//\tRight of the chart.\n\tconst xlLegendPositionTop\t\t= -4160;\t//\tAbove the chart.\n\n\tconst POSITION_RIGHT\t= 'r';\n\tconst POSITION_LEFT\t\t= 'l';\n\tconst POSITION_BOTTOM\t= 'b';\n\tconst POSITION_TOP\t\t= 't';\n\tconst POSITION_TOPRIGHT\t= 'tr';\n\n\tprivate static $_positionXLref = array( self::xlLegendPositionBottom\t=> self::POSITION_BOTTOM,\n\t\t\t\t\t\t\t\t\t\t\tself::xlLegendPositionCorner\t=> self::POSITION_TOPRIGHT,\n\t\t\t\t\t\t\t\t\t\t\tself::xlLegendPositionCustom\t=> '??',\n\t\t\t\t\t\t\t\t\t\t\tself::xlLegendPositionLeft\t\t=> self::POSITION_LEFT,\n\t\t\t\t\t\t\t\t\t\t\tself::xlLegendPositionRight\t\t=> self::POSITION_RIGHT,\n\t\t\t\t\t\t\t\t\t\t\tself::xlLegendPositionTop\t\t=> self::POSITION_TOP\n\t\t\t\t\t\t\t\t\t\t  );\n\n\t/**\n\t * Legend position\n\t *\n\t * @var\tstring\n\t */\n\tprivate $_position = self::POSITION_RIGHT;\n\n\t/**\n\t * Allow overlay of other elements?\n\t *\n\t * @var\tboolean\n\t */\n\tprivate $_overlay = TRUE;\n\n\t/**\n\t * Legend Layout\n\t *\n\t * @var\tPHPExcel_Chart_Layout\n\t */\n\tprivate $_layout = NULL;\n\n\n\t/**\n\t *\tCreate a new PHPExcel_Chart_Legend\n\t */\n\tpublic function __construct($position = self::POSITION_RIGHT, PHPExcel_Chart_Layout $layout = NULL, $overlay = FALSE)\n\t{\n\t\t$this->setPosition($position);\n\t\t$this->_layout = $layout;\n\t\t$this->setOverlay($overlay);\n\t}\n\n\t/**\n\t * Get legend position as an excel string value\n\t *\n\t * @return\tstring\n\t */\n\tpublic function getPosition() {\n\t\treturn $this->_position;\n\t}\n\n\t/**\n\t * Get legend position using an excel string value\n\t *\n\t * @param\tstring\t$position\n\t */\n\tpublic function setPosition($position = self::POSITION_RIGHT) {\n\t\tif (!in_array($position,self::$_positionXLref)) {\n\t\t\treturn false;\n\t\t}\n\n\t\t$this->_position = $position;\n\t\treturn true;\n\t}\n\n\t/**\n\t * Get legend position as an Excel internal numeric value\n\t *\n\t * @return\tnumber\n\t */\n\tpublic function getPositionXL() {\n\t\treturn array_search($this->_position,self::$_positionXLref);\n\t}\n\n\t/**\n\t * Set legend position using an Excel internal numeric value\n\t *\n\t * @param\tnumber\t$positionXL\n\t */\n\tpublic function setPositionXL($positionXL = self::xlLegendPositionRight) {\n\t\tif (!array_key_exists($positionXL,self::$_positionXLref)) {\n\t\t\treturn false;\n\t\t}\n\n\t\t$this->_position = self::$_positionXLref[$positionXL];\n\t\treturn true;\n\t}\n\n\t/**\n\t * Get allow overlay of other elements?\n\t *\n\t * @return\tboolean\n\t */\n\tpublic function getOverlay() {\n\t\treturn $this->_overlay;\n\t}\n\n\t/**\n\t * Set allow overlay of other elements?\n\t *\n\t * @param\tboolean\t$overlay\n\t * @return\tboolean\n\t */\n\tpublic function setOverlay($overlay = FALSE) {\n\t\tif (!is_bool($overlay)) {\n\t\t\treturn false;\n\t\t}\n\n\t\t$this->_overlay = $overlay;\n\t\treturn true;\n\t}\n\n\t/**\n\t * Get Layout\n\t *\n\t * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function getLayout() {\n\t\treturn $this->_layout;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Chart/PlotArea.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Chart_PlotArea\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Chart_PlotArea\n{\n\t/**\n\t * PlotArea Layout\n\t *\n\t * @var PHPExcel_Chart_Layout\n\t */\n\tprivate $_layout = null;\n\n\t/**\n\t * Plot Series\n\t *\n\t * @var array of PHPExcel_Chart_DataSeries\n\t */\n\tprivate $_plotSeries = array();\n\n\t/**\n\t * Create a new PHPExcel_Chart_PlotArea\n\t */\n\tpublic function __construct(PHPExcel_Chart_Layout $layout = null, $plotSeries = array())\n\t{\n\t\t$this->_layout = $layout;\n\t\t$this->_plotSeries = $plotSeries;\n\t}\n\n\t/**\n\t * Get Layout\n\t *\n\t * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function getLayout() {\n\t\treturn $this->_layout;\n\t}\n\n\t/**\n\t * Get Number of Plot Groups\n\t *\n\t * @return array of PHPExcel_Chart_DataSeries\n\t */\n\tpublic function getPlotGroupCount() {\n\t\treturn count($this->_plotSeries);\n\t}\n\n\t/**\n\t * Get Number of Plot Series\n\t *\n\t * @return integer\n\t */\n\tpublic function getPlotSeriesCount() {\n\t\t$seriesCount = 0;\n\t\tforeach($this->_plotSeries as $plot) {\n\t\t\t$seriesCount += $plot->getPlotSeriesCount();\n\t\t}\n\t\treturn $seriesCount;\n\t}\n\n\t/**\n\t * Get Plot Series\n\t *\n\t * @return array of PHPExcel_Chart_DataSeries\n\t */\n\tpublic function getPlotGroup() {\n\t\treturn $this->_plotSeries;\n\t}\n\n\t/**\n\t * Get Plot Series by Index\n\t *\n\t * @return PHPExcel_Chart_DataSeries\n\t */\n\tpublic function getPlotGroupByIndex($index) {\n\t\treturn $this->_plotSeries[$index];\n\t}\n\n\t/**\n\t * Set Plot Series\n\t *\n\t * @param [PHPExcel_Chart_DataSeries]\n     * @return PHPExcel_Chart_PlotArea\n\t */\n\tpublic function setPlotSeries($plotSeries = array()) {\n\t\t$this->_plotSeries = $plotSeries;\n        \n        return $this;\n\t}\n\n\tpublic function refresh(PHPExcel_Worksheet $worksheet) {\n\t    foreach($this->_plotSeries as $plotSeries) {\n\t\t\t$plotSeries->refresh($worksheet);\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Chart/Properties.php",
    "content": "<?php\n/**\n * Created by PhpStorm.\n * User: nhw2h8s\n * Date: 7/2/14\n * Time: 5:45 PM\n */\n\nabstract class PHPExcel_Properties {\n\n  const\n      EXCEL_COLOR_TYPE_STANDARD = 'prstClr',\n      EXCEL_COLOR_TYPE_SCHEME = 'schemeClr',\n      EXCEL_COLOR_TYPE_ARGB = 'srgbClr';\n\n  const\n      AXIS_LABELS_LOW = 'low',\n      AXIS_LABELS_HIGH = 'high',\n      AXIS_LABELS_NEXT_TO = 'nextTo',\n      AXIS_LABELS_NONE = 'none';\n\n  const\n      TICK_MARK_NONE = 'none',\n      TICK_MARK_INSIDE = 'in',\n      TICK_MARK_OUTSIDE = 'out',\n      TICK_MARK_CROSS = 'cross';\n\n  const\n      HORIZONTAL_CROSSES_AUTOZERO = 'autoZero',\n      HORIZONTAL_CROSSES_MAXIMUM = 'max';\n\n  const\n      FORMAT_CODE_GENERAL = 'General',\n      FORMAT_CODE_NUMBER = '#,##0.00',\n      FORMAT_CODE_CURRENCY = '$#,##0.00',\n      FORMAT_CODE_ACCOUNTING = '_($* #,##0.00_);_($* (#,##0.00);_($* \"-\"??_);_(@_)',\n      FORMAT_CODE_DATE = 'm/d/yyyy',\n      FORMAT_CODE_TIME = '[$-F400]h:mm:ss AM/PM',\n      FORMAT_CODE_PERCENTAGE = '0.00%',\n      FORMAT_CODE_FRACTION = '# ?/?',\n      FORMAT_CODE_SCIENTIFIC = '0.00E+00',\n      FORMAT_CODE_TEXT = '@',\n      FORMAT_CODE_SPECIAL = '00000';\n\n  const\n      ORIENTATION_NORMAL = 'minMax',\n      ORIENTATION_REVERSED = 'maxMin';\n\n  const\n      LINE_STYLE_COMPOUND_SIMPLE = 'sng',\n      LINE_STYLE_COMPOUND_DOUBLE = 'dbl',\n      LINE_STYLE_COMPOUND_THICKTHIN = 'thickThin',\n      LINE_STYLE_COMPOUND_THINTHICK = 'thinThick',\n      LINE_STYLE_COMPOUND_TRIPLE = 'tri',\n\n      LINE_STYLE_DASH_SOLID = 'solid',\n      LINE_STYLE_DASH_ROUND_DOT = 'sysDot',\n      LINE_STYLE_DASH_SQUERE_DOT = 'sysDash',\n      LINE_STYPE_DASH_DASH = 'dash',\n      LINE_STYLE_DASH_DASH_DOT = 'dashDot',\n      LINE_STYLE_DASH_LONG_DASH = 'lgDash',\n      LINE_STYLE_DASH_LONG_DASH_DOT = 'lgDashDot',\n      LINE_STYLE_DASH_LONG_DASH_DOT_DOT = 'lgDashDotDot',\n\n      LINE_STYLE_CAP_SQUARE = 'sq',\n      LINE_STYLE_CAP_ROUND = 'rnd',\n      LINE_STYLE_CAP_FLAT = 'flat',\n\n      LINE_STYLE_JOIN_ROUND = 'bevel',\n      LINE_STYLE_JOIN_MITER = 'miter',\n      LINE_STYLE_JOIN_BEVEL = 'bevel',\n\n      LINE_STYLE_ARROW_TYPE_NOARROW = NULL,\n      LINE_STYLE_ARROW_TYPE_ARROW = 'triangle',\n      LINE_STYLE_ARROW_TYPE_OPEN = 'arrow',\n      LINE_STYLE_ARROW_TYPE_STEALTH = 'stealth',\n      LINE_STYLE_ARROW_TYPE_DIAMOND = 'diamond',\n      LINE_STYLE_ARROW_TYPE_OVAL = 'oval',\n\n      LINE_STYLE_ARROW_SIZE_1 = 1,\n      LINE_STYLE_ARROW_SIZE_2 = 2,\n      LINE_STYLE_ARROW_SIZE_3 = 3,\n      LINE_STYLE_ARROW_SIZE_4 = 4,\n      LINE_STYLE_ARROW_SIZE_5 = 5,\n      LINE_STYLE_ARROW_SIZE_6 = 6,\n      LINE_STYLE_ARROW_SIZE_7 = 7,\n      LINE_STYLE_ARROW_SIZE_8 = 8,\n      LINE_STYLE_ARROW_SIZE_9 = 9;\n\n  const\n      SHADOW_PRESETS_NOSHADOW = NULL,\n      SHADOW_PRESETS_OUTER_BOTTTOM_RIGHT = 1,\n      SHADOW_PRESETS_OUTER_BOTTOM = 2,\n      SHADOW_PRESETS_OUTER_BOTTOM_LEFT = 3,\n      SHADOW_PRESETS_OUTER_RIGHT = 4,\n      SHADOW_PRESETS_OUTER_CENTER = 5,\n      SHADOW_PRESETS_OUTER_LEFT = 6,\n      SHADOW_PRESETS_OUTER_TOP_RIGHT = 7,\n      SHADOW_PRESETS_OUTER_TOP = 8,\n      SHADOW_PRESETS_OUTER_TOP_LEFT = 9,\n      SHADOW_PRESETS_INNER_BOTTTOM_RIGHT = 10,\n      SHADOW_PRESETS_INNER_BOTTOM = 11,\n      SHADOW_PRESETS_INNER_BOTTOM_LEFT = 12,\n      SHADOW_PRESETS_INNER_RIGHT = 13,\n      SHADOW_PRESETS_INNER_CENTER = 14,\n      SHADOW_PRESETS_INNER_LEFT = 15,\n      SHADOW_PRESETS_INNER_TOP_RIGHT = 16,\n      SHADOW_PRESETS_INNER_TOP = 17,\n      SHADOW_PRESETS_INNER_TOP_LEFT = 18,\n      SHADOW_PRESETS_PERSPECTIVE_BELOW = 19,\n      SHADOW_PRESETS_PERSPECTIVE_UPPER_RIGHT = 20,\n      SHADOW_PRESETS_PERSPECTIVE_UPPER_LEFT = 21,\n      SHADOW_PRESETS_PERSPECTIVE_LOWER_RIGHT = 22,\n      SHADOW_PRESETS_PERSPECTIVE_LOWER_LEFT = 23;\n\n  protected function  getExcelPointsWidth($width) {\n    return $width * 12700;\n  }\n\n  protected function getExcelPointsAngle($angle) {\n    return $angle * 60000;\n  }\n\n  protected function getTrueAlpha($alpha) {\n    return (string) 100 - $alpha . '000';\n  }\n\n  protected function setColorProperties($color, $alpha, $type) {\n    return array(\n        'type' => (string) $type,\n        'value' => (string) $color,\n        'alpha' => (string) $this->getTrueAlpha($alpha)\n    );\n  }\n\n  protected function getLineStyleArrowSize($array_selector, $array_kay_selector) {\n    $sizes = array(\n        1 => array('w' => 'sm', 'len' => 'sm'),\n        2 => array('w' => 'sm', 'len' => 'med'),\n        3 => array('w' => 'sm', 'len' => 'lg'),\n        4 => array('w' => 'med', 'len' => 'sm'),\n        5 => array('w' => 'med', 'len' => 'med'),\n        6 => array('w' => 'med', 'len' => 'lg'),\n        7 => array('w' => 'lg', 'len' => 'sm'),\n        8 => array('w' => 'lg', 'len' => 'med'),\n        9 => array('w' => 'lg', 'len' => 'lg')\n    );\n\n    return $sizes[$array_selector][$array_kay_selector];\n  }\n\n  protected function getShadowPresetsMap($shadow_presets_option) {\n    $presets_options = array(\n      //OUTER\n      1 => array(\n          'effect' => 'outerShdw',\n          'blur' => '50800',\n          'distance' => '38100',\n          'direction' => '2700000',\n          'algn' => 'tl',\n          'rotWithShape' => '0'\n      ),\n      2 => array(\n          'effect' => 'outerShdw',\n          'blur' => '50800',\n          'distance' => '38100',\n          'direction' => '5400000',\n          'algn' => 't',\n          'rotWithShape' => '0'\n      ),\n      3 => array(\n          'effect' => 'outerShdw',\n          'blur' => '50800',\n          'distance' => '38100',\n          'direction' => '8100000',\n          'algn' => 'tr',\n          'rotWithShape' => '0'\n      ),\n      4 => array(\n          'effect' => 'outerShdw',\n          'blur' => '50800',\n          'distance' => '38100',\n          'algn' => 'l',\n          'rotWithShape' => '0'\n      ),\n      5 => array(\n          'effect' => 'outerShdw',\n          'size' => array(\n              'sx' => '102000',\n              'sy' => '102000'\n          )\n          ,\n          'blur' => '63500',\n          'distance' => '38100',\n          'algn' => 'ctr',\n          'rotWithShape' => '0'\n      ),\n      6 => array(\n          'effect' => 'outerShdw',\n          'blur' => '50800',\n          'distance' => '38100',\n          'direction' => '10800000',\n          'algn' => 'r',\n          'rotWithShape' => '0'\n      ),\n      7 => array(\n          'effect' => 'outerShdw',\n          'blur' => '50800',\n          'distance' => '38100',\n          'direction' => '18900000',\n          'algn' => 'bl',\n          'rotWithShape' => '0'\n      ),\n      8 => array(\n          'effect' => 'outerShdw',\n          'blur' => '50800',\n          'distance' => '38100',\n          'direction' => '16200000',\n          'rotWithShape' => '0'\n      ),\n      9 => array(\n          'effect' => 'outerShdw',\n          'blur' => '50800',\n          'distance' => '38100',\n          'direction' => '13500000',\n          'algn' => 'br',\n          'rotWithShape' => '0'\n      ),\n      //INNER\n      10 => array(\n          'effect' => 'innerShdw',\n          'blur' => '63500',\n          'distance' => '50800',\n          'direction' => '2700000',\n      ),\n      11 => array(\n          'effect' => 'innerShdw',\n          'blur' => '63500',\n          'distance' => '50800',\n          'direction' => '5400000',\n      ),\n      12 => array(\n          'effect' => 'innerShdw',\n          'blur' => '63500',\n          'distance' => '50800',\n          'direction' => '8100000',\n      ),\n      13 => array(\n          'effect' => 'innerShdw',\n          'blur' => '63500',\n          'distance' => '50800',\n      ),\n      14 => array(\n          'effect' => 'innerShdw',\n          'blur' => '114300',\n      ),\n      15 => array(\n          'effect' => 'innerShdw',\n          'blur' => '63500',\n          'distance' => '50800',\n          'direction' => '10800000',\n      ),\n      16 => array(\n          'effect' => 'innerShdw',\n          'blur' => '63500',\n          'distance' => '50800',\n          'direction' => '18900000',\n      ),\n      17 => array(\n          'effect' => 'innerShdw',\n          'blur' => '63500',\n          'distance' => '50800',\n          'direction' => '16200000',\n      ),\n      18 => array(\n          'effect' => 'innerShdw',\n          'blur' => '63500',\n          'distance' => '50800',\n          'direction' => '13500000',\n      ),\n      //perspective\n      19 => array(\n          'effect' => 'outerShdw',\n          'blur' => '152400',\n          'distance' => '317500',\n          'size' => array(\n              'sx' => '90000',\n              'sy' => '-19000',\n          ),\n          'direction' => '5400000',\n          'rotWithShape' => '0',\n      ),\n      20 => array(\n          'effect' => 'outerShdw',\n          'blur' => '76200',\n          'direction' => '18900000',\n          'size' => array(\n              'sy' => '23000',\n              'kx' => '-1200000',\n          ),\n          'algn' => 'bl',\n          'rotWithShape' => '0',\n      ),\n      21 => array(\n          'effect' => 'outerShdw',\n          'blur' => '76200',\n          'direction' => '13500000',\n          'size' => array(\n              'sy' => '23000',\n              'kx' => '1200000',\n          ),\n          'algn' => 'br',\n          'rotWithShape' => '0',\n      ),\n      22 => array(\n          'effect' => 'outerShdw',\n          'blur' => '76200',\n          'distance' => '12700',\n          'direction' => '2700000',\n          'size' => array(\n              'sy' => '-23000',\n              'kx' => '-800400',\n          ),\n          'algn' => 'bl',\n          'rotWithShape' => '0',\n      ),\n      23 => array(\n          'effect' => 'outerShdw',\n          'blur' => '76200',\n          'distance' => '12700',\n          'direction' => '8100000',\n          'size' => array(\n              'sy' => '-23000',\n              'kx' => '800400',\n          ),\n          'algn' => 'br',\n          'rotWithShape' => '0',\n      ),\n    );\n\n    return $presets_options[$shadow_presets_option];\n  }\n\n  protected function getArrayElementsValue($properties, $elements) {\n    $reference = & $properties;\n    if (!is_array($elements)) {\n      return $reference[$elements];\n    } else {\n      foreach ($elements as $keys) {\n        $reference = & $reference[$keys];\n      }\n\n      return $reference;\n    }\n\n    return $this;\n  }\n\n} "
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Chart/Renderer/PHP Charting Libraries.txt",
    "content": "ChartDirector\r\n\thttp://www.advsofteng.com/cdphp.html\r\n\r\nGraPHPite\r\n\thttp://graphpite.sourceforge.net/\r\n\r\nJpGraph\r\n\thttp://www.aditus.nu/jpgraph/\r\n\r\nLibChart\r\n\thttp://naku.dohcrew.com/libchart/pages/introduction/\r\n\r\npChart\r\n\thttp://pchart.sourceforge.net/\r\n\r\nTeeChart\r\n\thttp://www.steema.com/products/teechart/overview.html\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Chart/Renderer/jpgraph.php",
    "content": "<?php\r\n\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (c) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category\tPHPExcel\r\n * @package\t\tPHPExcel_Chart_Renderer\r\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version\t\t##VERSION##, ##DATE##\r\n */\r\n\r\n\r\nrequire_once(PHPExcel_Settings::getChartRendererPath().'/jpgraph.php');\r\n\r\n\r\n/**\r\n * PHPExcel_Chart_Renderer_jpgraph\r\n *\r\n * @category\tPHPExcel\r\n * @package\t\tPHPExcel_Chart_Renderer\r\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n */\r\nclass PHPExcel_Chart_Renderer_jpgraph\r\n{\r\n\tprivate static $_width\t= 640;\r\n\r\n\tprivate static $_height\t= 480;\r\n\r\n\tprivate static $_colourSet = array( 'mediumpurple1',\t'palegreen3',\t'gold1',\t\t'cadetblue1',\r\n\t\t\t\t\t\t\t\t\t\t'darkmagenta',\t\t'coral',\t\t'dodgerblue3',\t'eggplant',\r\n\t\t\t\t\t\t\t\t\t\t'mediumblue',\t\t'magenta',\t\t'sandybrown',\t'cyan',\r\n\t\t\t\t\t\t\t\t\t\t'firebrick1',\t\t'forestgreen',\t'deeppink4',\t'darkolivegreen',\r\n\t\t\t\t\t\t\t\t\t\t'goldenrod2'\r\n\t\t\t\t\t\t\t\t\t  );\r\n\r\n\tprivate static $_markSet = array(\t'diamond'\t=> MARK_DIAMOND,\r\n\t\t\t\t\t\t\t\t\t\t'square'\t=> MARK_SQUARE,\r\n\t\t\t\t\t\t\t\t\t\t'triangle'\t=> MARK_UTRIANGLE,\r\n\t\t\t\t\t\t\t\t\t\t'x'\t\t\t=> MARK_X,\r\n\t\t\t\t\t\t\t\t\t\t'star'\t\t=> MARK_STAR,\r\n\t\t\t\t\t\t\t\t\t\t'dot'\t\t=> MARK_FILLEDCIRCLE,\r\n\t\t\t\t\t\t\t\t\t\t'dash'\t\t=> MARK_DTRIANGLE,\r\n\t\t\t\t\t\t\t\t\t\t'circle'\t=> MARK_CIRCLE,\r\n\t\t\t\t\t\t\t\t\t\t'plus'\t\t=> MARK_CROSS\r\n\t\t\t\t\t\t\t\t\t);\r\n\r\n\r\n\tprivate $_chart\t= null;\r\n\r\n\tprivate $_graph\t= null;\r\n\r\n\tprivate static $_plotColour\t= 0;\r\n\r\n\tprivate static $_plotMark\t= 0;\r\n\r\n\r\n\tprivate function _formatPointMarker($seriesPlot,$markerID) {\r\n\t\t$plotMarkKeys = array_keys(self::$_markSet);\r\n\t\tif (is_null($markerID)) {\r\n\t\t\t//\tUse default plot marker (next marker in the series)\r\n\t\t\tself::$_plotMark %= count(self::$_markSet);\r\n\t\t\t$seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]);\r\n\t\t} elseif ($markerID !== 'none') {\r\n\t\t\t//\tUse specified plot marker (if it exists)\r\n\t\t\tif (isset(self::$_markSet[$markerID])) {\r\n\t\t\t\t$seriesPlot->mark->SetType(self::$_markSet[$markerID]);\r\n\t\t\t} else {\r\n\t\t\t\t//\tIf the specified plot marker doesn't exist, use default plot marker (next marker in the series)\r\n\t\t\t\tself::$_plotMark %= count(self::$_markSet);\r\n\t\t\t\t$seriesPlot->mark->SetType(self::$_markSet[$plotMarkKeys[self::$_plotMark++]]);\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t//\tHide plot marker\r\n\t\t\t$seriesPlot->mark->Hide();\r\n\t\t}\r\n\t\t$seriesPlot->mark->SetColor(self::$_colourSet[self::$_plotColour]);\r\n\t\t$seriesPlot->mark->SetFillColor(self::$_colourSet[self::$_plotColour]);\r\n\t\t$seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]);\r\n\r\n\t\treturn $seriesPlot;\r\n\t}\t//\tfunction _formatPointMarker()\r\n\r\n\r\n\tprivate function _formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation = '') {\r\n\t\t$datasetLabelFormatCode = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getFormatCode();\r\n\t\tif (!is_null($datasetLabelFormatCode)) {\r\n\t\t\t//\tRetrieve any label formatting code\r\n\t\t\t$datasetLabelFormatCode = stripslashes($datasetLabelFormatCode);\r\n\t\t}\r\n\r\n\t\t$testCurrentIndex = 0;\r\n\t\tforeach($datasetLabels as $i => $datasetLabel) {\r\n\t\t\tif (is_array($datasetLabel)) {\r\n\t\t\t\tif ($rotation == 'bar') {\r\n\t\t\t\t\t$datasetLabels[$i] = implode(\" \",$datasetLabel);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t$datasetLabel = array_reverse($datasetLabel);\r\n\t\t\t\t\t$datasetLabels[$i] = implode(\"\\n\",$datasetLabel);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t//\tFormat labels according to any formatting code\r\n\t\t\t\tif (!is_null($datasetLabelFormatCode)) {\r\n\t\t\t\t\t$datasetLabels[$i] = PHPExcel_Style_NumberFormat::toFormattedString($datasetLabel,$datasetLabelFormatCode);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\t++$testCurrentIndex;\r\n\t\t}\r\n\r\n\t\treturn $datasetLabels;\r\n\t}\t//\tfunction _formatDataSetLabels()\r\n\r\n\r\n\tprivate function _percentageSumCalculation($groupID,$seriesCount) {\r\n\t\t//\tAdjust our values to a percentage value across all series in the group\r\n\t\tfor($i = 0; $i < $seriesCount; ++$i) {\r\n\t\t\tif ($i == 0) {\r\n\t\t\t\t$sumValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues();\r\n\t\t\t} else {\r\n\t\t\t\t$nextValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues();\r\n\t\t\t\tforeach($nextValues as $k => $value) {\r\n\t\t\t\t\tif (isset($sumValues[$k])) {\r\n\t\t\t\t\t\t$sumValues[$k] += $value;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t$sumValues[$k] = $value;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn $sumValues;\r\n\t}\t//\tfunction _percentageSumCalculation()\r\n\r\n\r\n\tprivate function _percentageAdjustValues($dataValues,$sumValues) {\r\n\t\tforeach($dataValues as $k => $dataValue) {\r\n\t\t\t$dataValues[$k] = $dataValue / $sumValues[$k] * 100;\r\n\t\t}\r\n\r\n\t\treturn $dataValues;\r\n\t}\t//\tfunction _percentageAdjustValues()\r\n\r\n\r\n\tprivate function _getCaption($captionElement) {\r\n\t\t//\tRead any caption\r\n\t\t$caption = (!is_null($captionElement)) ? $captionElement->getCaption() : NULL;\r\n\t\t//\tTest if we have a title caption to display\r\n\t\tif (!is_null($caption)) {\r\n\t\t\t//\tIf we do, it could be a plain string or an array\r\n\t\t\tif (is_array($caption)) {\r\n\t\t\t\t//\tImplode an array to a plain string\r\n\t\t\t\t$caption = implode('',$caption);\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn $caption;\r\n\t}\t//\tfunction _getCaption()\r\n\r\n\r\n\tprivate function _renderTitle() {\r\n\t\t$title = $this->_getCaption($this->_chart->getTitle());\r\n\t\tif (!is_null($title)) {\r\n\t\t\t$this->_graph->title->Set($title);\r\n\t\t}\r\n\t}\t//\tfunction _renderTitle()\r\n\r\n\r\n\tprivate function _renderLegend() {\r\n\t\t$legend = $this->_chart->getLegend();\r\n\t\tif (!is_null($legend)) {\r\n\t\t\t$legendPosition = $legend->getPosition();\r\n\t\t\t$legendOverlay = $legend->getOverlay();\r\n\t\t\tswitch ($legendPosition) {\r\n\t\t\t\tcase 'r'\t:\r\n\t\t\t\t\t$this->_graph->legend->SetPos(0.01,0.5,'right','center');\t//\tright\r\n\t\t\t\t\t$this->_graph->legend->SetColumns(1);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'l'\t:\r\n\t\t\t\t\t$this->_graph->legend->SetPos(0.01,0.5,'left','center');\t//\tleft\r\n\t\t\t\t\t$this->_graph->legend->SetColumns(1);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 't'\t:\r\n\t\t\t\t\t$this->_graph->legend->SetPos(0.5,0.01,'center','top');\t//\ttop\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'b'\t:\r\n\t\t\t\t\t$this->_graph->legend->SetPos(0.5,0.99,'center','bottom');\t//\tbottom\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tdefault\t\t:\r\n\t\t\t\t\t$this->_graph->legend->SetPos(0.01,0.01,'right','top');\t//\ttop-right\r\n\t\t\t\t\t$this->_graph->legend->SetColumns(1);\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t} else {\r\n\t\t\t$this->_graph->legend->Hide();\r\n\t\t}\r\n\t}\t//\tfunction _renderLegend()\r\n\r\n\r\n\tprivate function _renderCartesianPlotArea($type='textlin') {\r\n\t\t$this->_graph = new Graph(self::$_width,self::$_height);\r\n\t\t$this->_graph->SetScale($type);\r\n\r\n\t\t$this->_renderTitle();\r\n\r\n\t\t//\tRotate for bar rather than column chart\r\n\t\t$rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotDirection();\r\n\t\t$reverse = ($rotation == 'bar') ? true : false;\r\n\r\n\t\t$xAxisLabel = $this->_chart->getXAxisLabel();\r\n\t\tif (!is_null($xAxisLabel)) {\r\n\t\t\t$title = $this->_getCaption($xAxisLabel);\r\n\t\t\tif (!is_null($title)) {\r\n\t\t\t\t$this->_graph->xaxis->SetTitle($title,'center');\r\n\t\t\t\t$this->_graph->xaxis->title->SetMargin(35);\r\n\t\t\t\tif ($reverse) {\r\n\t\t\t\t\t$this->_graph->xaxis->title->SetAngle(90);\r\n\t\t\t\t\t$this->_graph->xaxis->title->SetMargin(90);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t$yAxisLabel = $this->_chart->getYAxisLabel();\r\n\t\tif (!is_null($yAxisLabel)) {\r\n\t\t\t$title = $this->_getCaption($yAxisLabel);\r\n\t\t\tif (!is_null($title)) {\r\n\t\t\t\t$this->_graph->yaxis->SetTitle($title,'center');\r\n\t\t\t\tif ($reverse) {\r\n\t\t\t\t\t$this->_graph->yaxis->title->SetAngle(0);\r\n\t\t\t\t\t$this->_graph->yaxis->title->SetMargin(-55);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\t//\tfunction _renderCartesianPlotArea()\r\n\r\n\r\n\tprivate function _renderPiePlotArea($doughnut = False) {\r\n\t\t$this->_graph = new PieGraph(self::$_width,self::$_height);\r\n\r\n\t\t$this->_renderTitle();\r\n\t}\t//\tfunction _renderPiePlotArea()\r\n\r\n\r\n\tprivate function _renderRadarPlotArea() {\r\n\t\t$this->_graph = new RadarGraph(self::$_width,self::$_height);\r\n\t\t$this->_graph->SetScale('lin');\r\n\r\n\t\t$this->_renderTitle();\r\n\t}\t//\tfunction _renderRadarPlotArea()\r\n\r\n\r\n\tprivate function _renderPlotLine($groupID, $filled = false, $combination = false, $dimensions = '2d') {\r\n\t\t$grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();\r\n\r\n        $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount());\r\n\t\tif ($labelCount > 0) {\r\n\t\t\t$datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues();\r\n\t\t\t$datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount);\r\n\t\t\t$this->_graph->xaxis->SetTickLabels($datasetLabels);\r\n\t\t}\r\n\r\n\t\t$seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();\r\n\t\t$seriesPlots = array();\r\n\t\tif ($grouping == 'percentStacked') {\r\n\t\t\t$sumValues = $this->_percentageSumCalculation($groupID,$seriesCount);\r\n\t\t}\r\n\r\n\t\t//\tLoop through each data series in turn\r\n\t\tfor($i = 0; $i < $seriesCount; ++$i) {\r\n\t\t\t$dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues();\r\n\t\t\t$marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker();\r\n\r\n\t\t\tif ($grouping == 'percentStacked') {\r\n\t\t\t\t$dataValues = $this->_percentageAdjustValues($dataValues,$sumValues);\r\n\t\t\t}\r\n\r\n\t\t\t//\tFill in any missing values in the $dataValues array\r\n\t\t\t$testCurrentIndex = 0;\r\n\t\t\tforeach($dataValues as $k => $dataValue) {\r\n\t\t\t\twhile($k != $testCurrentIndex) {\r\n\t\t\t\t\t$dataValues[$testCurrentIndex] = null;\r\n\t\t\t\t\t++$testCurrentIndex;\r\n\t\t\t\t}\r\n\t\t\t\t++$testCurrentIndex;\r\n\t\t\t}\r\n\r\n\t\t\t$seriesPlot = new LinePlot($dataValues);\r\n\t\t\tif ($combination) {\r\n\t\t\t\t$seriesPlot->SetBarCenter();\r\n\t\t\t}\r\n\r\n\t\t\tif ($filled) {\r\n\t\t\t\t$seriesPlot->SetFilled(true);\r\n\t\t\t\t$seriesPlot->SetColor('black');\r\n\t\t\t\t$seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]);\r\n\t\t\t} else {\r\n\t\t\t\t//\tSet the appropriate plot marker\r\n\t\t\t\t$this->_formatPointMarker($seriesPlot,$marker);\r\n\t\t\t}\r\n\t\t\t$dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue();\r\n\t\t\t$seriesPlot->SetLegend($dataLabel);\r\n\r\n\t\t\t$seriesPlots[] = $seriesPlot;\r\n\t\t}\r\n\r\n\t\tif ($grouping == 'standard') {\r\n\t\t\t$groupPlot = $seriesPlots;\r\n\t\t} else {\r\n\t\t\t$groupPlot = new AccLinePlot($seriesPlots);\r\n\t\t}\r\n\t\t$this->_graph->Add($groupPlot);\r\n\t}\t//\tfunction _renderPlotLine()\r\n\r\n\r\n\tprivate function _renderPlotBar($groupID, $dimensions = '2d') {\r\n\t\t$rotation = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotDirection();\r\n\t\t//\tRotate for bar rather than column chart\r\n\t\tif (($groupID == 0) && ($rotation == 'bar')) {\r\n\t\t\t$this->_graph->Set90AndMargin();\r\n\t\t}\r\n\t\t$grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();\r\n\r\n        $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount());\r\n\t\tif ($labelCount > 0) {\r\n\t\t\t$datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues();\r\n\t\t\t$datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount, $rotation);\r\n\t\t\t//\tRotate for bar rather than column chart\r\n\t\t\tif ($rotation == 'bar') {\r\n\t\t\t\t$datasetLabels = array_reverse($datasetLabels);\r\n\t\t\t\t$this->_graph->yaxis->SetPos('max');\r\n\t\t\t\t$this->_graph->yaxis->SetLabelAlign('center','top');\r\n\t\t\t\t$this->_graph->yaxis->SetLabelSide(SIDE_RIGHT);\r\n\t\t\t}\r\n\t\t\t$this->_graph->xaxis->SetTickLabels($datasetLabels);\r\n\t\t}\r\n\r\n\r\n\t\t$seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();\r\n\t\t$seriesPlots = array();\r\n\t\tif ($grouping == 'percentStacked') {\r\n\t\t\t$sumValues = $this->_percentageSumCalculation($groupID,$seriesCount);\r\n\t\t}\r\n\r\n\t\t//\tLoop through each data series in turn\r\n\t\tfor($j = 0; $j < $seriesCount; ++$j) {\r\n\t\t\t$dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues();\r\n\t\t\tif ($grouping == 'percentStacked') {\r\n\t\t\t\t$dataValues = $this->_percentageAdjustValues($dataValues,$sumValues);\r\n\t\t\t}\r\n\r\n\t\t\t//\tFill in any missing values in the $dataValues array\r\n\t\t\t$testCurrentIndex = 0;\r\n\t\t\tforeach($dataValues as $k => $dataValue) {\r\n\t\t\t\twhile($k != $testCurrentIndex) {\r\n\t\t\t\t\t$dataValues[$testCurrentIndex] = null;\r\n\t\t\t\t\t++$testCurrentIndex;\r\n\t\t\t\t}\r\n\t\t\t\t++$testCurrentIndex;\r\n\t\t\t}\r\n\r\n\t\t\t//\tReverse the $dataValues order for bar rather than column chart\r\n\t\t\tif ($rotation == 'bar') {\r\n\t\t\t\t$dataValues = array_reverse($dataValues);\r\n\t\t\t}\r\n\t\t\t$seriesPlot = new BarPlot($dataValues);\r\n\t\t\t$seriesPlot->SetColor('black');\r\n\t\t\t$seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour++]);\r\n\t\t\tif ($dimensions == '3d') {\r\n\t\t\t\t$seriesPlot->SetShadow();\r\n\t\t\t}\r\n\t\t\tif (!$this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)) {\r\n\t\t\t\t$dataLabel = '';\r\n\t\t\t} else {\r\n\t\t\t\t$dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($j)->getDataValue();\r\n\t\t\t}\r\n\t\t\t$seriesPlot->SetLegend($dataLabel);\r\n\r\n\t\t\t$seriesPlots[] = $seriesPlot;\r\n\t\t}\r\n\t\t//\tReverse the plot order for bar rather than column chart\r\n\t\tif (($rotation == 'bar') && (!($grouping == 'percentStacked'))) {\r\n\t\t\t$seriesPlots = array_reverse($seriesPlots);\r\n\t\t}\r\n\r\n\t\tif ($grouping == 'clustered') {\r\n\t\t\t$groupPlot = new GroupBarPlot($seriesPlots);\r\n\t\t} elseif ($grouping == 'standard') {\r\n\t\t\t$groupPlot = new GroupBarPlot($seriesPlots);\r\n\t\t} else {\r\n\t\t\t$groupPlot = new AccBarPlot($seriesPlots);\r\n\t\t\tif ($dimensions == '3d') {\r\n\t\t\t\t$groupPlot->SetShadow();\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t$this->_graph->Add($groupPlot);\r\n\t}\t//\tfunction _renderPlotBar()\r\n\r\n\r\n\tprivate function _renderPlotScatter($groupID,$bubble) {\r\n\t\t$grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();\r\n\t\t$scatterStyle = $bubbleSize = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle();\r\n\r\n\t\t$seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();\r\n\t\t$seriesPlots = array();\r\n\r\n\t\t//\tLoop through each data series in turn\r\n\t\tfor($i = 0; $i < $seriesCount; ++$i) {\r\n\t\t\t$dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues();\r\n\t\t\t$dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues();\r\n\r\n\t\t\tforeach($dataValuesY as $k => $dataValueY) {\r\n\t\t\t\t$dataValuesY[$k] = $k;\r\n\t\t\t}\r\n\r\n\t\t\t$seriesPlot = new ScatterPlot($dataValuesX,$dataValuesY);\r\n\t\t\tif ($scatterStyle == 'lineMarker') {\r\n\t\t\t\t$seriesPlot->SetLinkPoints();\r\n\t\t\t\t$seriesPlot->link->SetColor(self::$_colourSet[self::$_plotColour]);\r\n\t\t\t} elseif ($scatterStyle == 'smoothMarker') {\r\n\t\t\t\t$spline = new Spline($dataValuesY,$dataValuesX);\r\n\t\t\t\tlist($splineDataY,$splineDataX) = $spline->Get(count($dataValuesX) * self::$_width / 20);\r\n\t\t\t\t$lplot = new LinePlot($splineDataX,$splineDataY);\r\n\t\t\t\t$lplot->SetColor(self::$_colourSet[self::$_plotColour]);\r\n\r\n\t\t\t\t$this->_graph->Add($lplot);\r\n\t\t\t}\r\n\r\n\t\t\tif ($bubble) {\r\n\t\t\t\t$this->_formatPointMarker($seriesPlot,'dot');\r\n\t\t\t\t$seriesPlot->mark->SetColor('black');\r\n\t\t\t\t$seriesPlot->mark->SetSize($bubbleSize);\r\n\t\t\t} else {\r\n\t\t\t\t$marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker();\r\n\t\t\t\t$this->_formatPointMarker($seriesPlot,$marker);\r\n\t\t\t}\r\n\t\t\t$dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue();\r\n\t\t\t$seriesPlot->SetLegend($dataLabel);\r\n\r\n\t\t\t$this->_graph->Add($seriesPlot);\r\n\t\t}\r\n\t}\t//\tfunction _renderPlotScatter()\r\n\r\n\r\n\tprivate function _renderPlotRadar($groupID) {\r\n\t\t$radarStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle();\r\n\r\n\t\t$seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();\r\n\t\t$seriesPlots = array();\r\n\r\n\t\t//\tLoop through each data series in turn\r\n\t\tfor($i = 0; $i < $seriesCount; ++$i) {\r\n\t\t\t$dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues();\r\n\t\t\t$dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues();\r\n\t\t\t$marker = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getPointMarker();\r\n\r\n\t\t\t$dataValues = array();\r\n\t\t\tforeach($dataValuesY as $k => $dataValueY) {\r\n\t\t\t\t$dataValues[$k] = implode(' ',array_reverse($dataValueY));\r\n\t\t\t}\r\n\t\t\t$tmp = array_shift($dataValues);\r\n\t\t\t$dataValues[] = $tmp;\r\n\t\t\t$tmp = array_shift($dataValuesX);\r\n\t\t\t$dataValuesX[] = $tmp;\r\n\r\n\t\t\t$this->_graph->SetTitles(array_reverse($dataValues));\r\n\r\n\t\t\t$seriesPlot = new RadarPlot(array_reverse($dataValuesX));\r\n\r\n\t\t\t$dataLabel = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotLabelByIndex($i)->getDataValue();\r\n\t\t\t$seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]);\r\n\t\t\tif ($radarStyle == 'filled') {\r\n\t\t\t\t$seriesPlot->SetFillColor(self::$_colourSet[self::$_plotColour]);\r\n\t\t\t}\r\n\t\t\t$this->_formatPointMarker($seriesPlot,$marker);\r\n\t\t\t$seriesPlot->SetLegend($dataLabel);\r\n\r\n\t\t\t$this->_graph->Add($seriesPlot);\r\n\t\t}\r\n\t}\t//\tfunction _renderPlotRadar()\r\n\r\n\r\n\tprivate function _renderPlotContour($groupID) {\r\n\t\t$contourStyle = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle();\r\n\r\n\t\t$seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();\r\n\t\t$seriesPlots = array();\r\n\r\n\t\t$dataValues = array();\r\n\t\t//\tLoop through each data series in turn\r\n\t\tfor($i = 0; $i < $seriesCount; ++$i) {\r\n\t\t\t$dataValuesY = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex($i)->getDataValues();\r\n\t\t\t$dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($i)->getDataValues();\r\n\r\n\t\t\t$dataValues[$i] = $dataValuesX;\r\n\t\t}\r\n\t\t$seriesPlot = new ContourPlot($dataValues);\r\n\r\n\t\t$this->_graph->Add($seriesPlot);\r\n\t}\t//\tfunction _renderPlotContour()\r\n\r\n\r\n\tprivate function _renderPlotStock($groupID) {\r\n\t\t$seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();\r\n\t\t$plotOrder = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotOrder();\r\n\r\n\t\t$dataValues = array();\r\n\t\t//\tLoop through each data series in turn and build the plot arrays\r\n\t\tforeach($plotOrder as $i => $v) {\r\n\t\t\t$dataValuesX = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($v)->getDataValues();\r\n\t\t\tforeach($dataValuesX as $j => $dataValueX) {\r\n\t\t\t\t$dataValues[$plotOrder[$i]][$j] = $dataValueX;\r\n\t\t\t}\r\n\t\t}\r\n\t\tif(empty($dataValues)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t$dataValuesPlot = array();\r\n        // Flatten the plot arrays to a single dimensional array to work with jpgraph\r\n\t\tfor($j = 0; $j < count($dataValues[0]); $j++) {\r\n\t\t\tfor($i = 0; $i < $seriesCount; $i++) {\r\n\t\t\t\t$dataValuesPlot[] = $dataValues[$i][$j];\r\n\t\t\t}\r\n\t\t}\r\n\r\n        // Set the x-axis labels\r\n        $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount());\r\n\t\tif ($labelCount > 0) {\r\n\t\t\t$datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues();\r\n\t\t\t$datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount);\r\n\t\t\t$this->_graph->xaxis->SetTickLabels($datasetLabels);\r\n\t\t}\r\n\r\n\t\t$seriesPlot = new StockPlot($dataValuesPlot);\r\n\t\t$seriesPlot->SetWidth(20);\r\n\r\n\t\t$this->_graph->Add($seriesPlot);\r\n\t}\t//\tfunction _renderPlotStock()\r\n\r\n\r\n\tprivate function _renderAreaChart($groupCount, $dimensions = '2d') {\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php');\r\n\r\n\t\t$this->_renderCartesianPlotArea();\r\n\r\n\t\tfor($i = 0; $i < $groupCount; ++$i) {\r\n\t\t\t$this->_renderPlotLine($i,True,False,$dimensions);\r\n\t\t}\r\n\t}\t//\tfunction _renderAreaChart()\r\n\r\n\r\n\tprivate function _renderLineChart($groupCount, $dimensions = '2d') {\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php');\r\n\r\n\t\t$this->_renderCartesianPlotArea();\r\n\r\n\t\tfor($i = 0; $i < $groupCount; ++$i) {\r\n\t\t\t$this->_renderPlotLine($i,False,False,$dimensions);\r\n\t\t}\r\n\t}\t//\tfunction _renderLineChart()\r\n\r\n\r\n\tprivate function _renderBarChart($groupCount, $dimensions = '2d') {\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php');\r\n\r\n\t\t$this->_renderCartesianPlotArea();\r\n\r\n\t\tfor($i = 0; $i < $groupCount; ++$i) {\r\n\t\t\t$this->_renderPlotBar($i,$dimensions);\r\n\t\t}\r\n\t}\t//\tfunction _renderBarChart()\r\n\r\n\r\n\tprivate function _renderScatterChart($groupCount) {\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php');\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php');\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php');\r\n\r\n\t\t$this->_renderCartesianPlotArea('linlin');\r\n\r\n\t\tfor($i = 0; $i < $groupCount; ++$i) {\r\n\t\t\t$this->_renderPlotScatter($i,false);\r\n\t\t}\r\n\t}\t//\tfunction _renderScatterChart()\r\n\r\n\r\n\tprivate function _renderBubbleChart($groupCount) {\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php');\r\n\r\n\t\t$this->_renderCartesianPlotArea('linlin');\r\n\r\n\t\tfor($i = 0; $i < $groupCount; ++$i) {\r\n\t\t\t$this->_renderPlotScatter($i,true);\r\n\t\t}\r\n\t}\t//\tfunction _renderBubbleChart()\r\n\r\n\r\n\tprivate function _renderPieChart($groupCount, $dimensions = '2d', $doughnut = False, $multiplePlots = False) {\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie.php');\r\n\t\tif ($dimensions == '3d') {\r\n\t\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_pie3d.php');\r\n\t\t}\r\n\r\n\t\t$this->_renderPiePlotArea($doughnut);\r\n\r\n\t\t$iLimit = ($multiplePlots) ? $groupCount : 1;\r\n\t\tfor($groupID = 0; $groupID < $iLimit; ++$groupID) {\r\n\t\t\t$grouping = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotGrouping();\r\n\t\t\t$exploded = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotStyle();\r\n\t\t\tif ($groupID == 0) {\r\n\t\t        $labelCount = count($this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex(0)->getPointCount());\r\n\t\t\t\tif ($labelCount > 0) {\r\n\t\t\t\t\t$datasetLabels = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotCategoryByIndex(0)->getDataValues();\r\n\t\t\t\t\t$datasetLabels = $this->_formatDataSetLabels($groupID, $datasetLabels, $labelCount);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t$seriesCount = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotSeriesCount();\r\n\t\t\t$seriesPlots = array();\r\n\t\t\t//\tFor pie charts, we only display the first series: doughnut charts generally display all series\r\n\t\t\t$jLimit = ($multiplePlots) ? $seriesCount : 1;\r\n\t\t\t//\tLoop through each data series in turn\r\n\t\t\tfor($j = 0; $j < $jLimit; ++$j) {\r\n\t\t\t\t$dataValues = $this->_chart->getPlotArea()->getPlotGroupByIndex($groupID)->getPlotValuesByIndex($j)->getDataValues();\r\n\r\n\t\t\t\t//\tFill in any missing values in the $dataValues array\r\n\t\t\t\t$testCurrentIndex = 0;\r\n\t\t\t\tforeach($dataValues as $k => $dataValue) {\r\n\t\t\t\t\twhile($k != $testCurrentIndex) {\r\n\t\t\t\t\t\t$dataValues[$testCurrentIndex] = null;\r\n\t\t\t\t\t\t++$testCurrentIndex;\r\n\t\t\t\t\t}\r\n\t\t\t\t\t++$testCurrentIndex;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif ($dimensions == '3d') {\r\n\t\t\t\t\t$seriesPlot = new PiePlot3D($dataValues);\r\n\t\t\t\t} else {\r\n\t\t\t\t\tif ($doughnut) {\r\n\t\t\t\t\t\t$seriesPlot = new PiePlotC($dataValues);\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t$seriesPlot = new PiePlot($dataValues);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif ($multiplePlots) {\r\n\t\t\t\t\t$seriesPlot->SetSize(($jLimit-$j) / ($jLimit * 4));\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif ($doughnut) {\r\n\t\t\t\t\t$seriesPlot->SetMidColor('white');\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$seriesPlot->SetColor(self::$_colourSet[self::$_plotColour++]);\r\n\t\t\t\tif (count($datasetLabels) > 0)\r\n\t\t\t\t\t$seriesPlot->SetLabels(array_fill(0,count($datasetLabels),''));\r\n\t\t\t\tif ($dimensions != '3d') {\r\n\t\t\t\t\t$seriesPlot->SetGuideLines(false);\r\n\t\t\t\t}\r\n\t\t\t\tif ($j == 0) {\r\n\t\t\t\t\tif ($exploded) {\r\n\t\t\t\t\t\t$seriesPlot->ExplodeAll();\r\n\t\t\t\t\t}\r\n\t\t\t\t\t$seriesPlot->SetLegends($datasetLabels);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$this->_graph->Add($seriesPlot);\r\n\t\t\t}\r\n\t\t}\r\n\t}\t//\tfunction _renderPieChart()\r\n\r\n\r\n\tprivate function _renderRadarChart($groupCount) {\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_radar.php');\r\n\r\n\t\t$this->_renderRadarPlotArea();\r\n\r\n\t\tfor($groupID = 0; $groupID < $groupCount; ++$groupID) {\r\n\t\t\t$this->_renderPlotRadar($groupID);\r\n\t\t}\r\n\t}\t//\tfunction _renderRadarChart()\r\n\r\n\r\n\tprivate function _renderStockChart($groupCount) {\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_stock.php');\r\n\r\n\t\t$this->_renderCartesianPlotArea('intint');\r\n\r\n\t\tfor($groupID = 0; $groupID < $groupCount; ++$groupID) {\r\n\t\t\t$this->_renderPlotStock($groupID);\r\n\t\t}\r\n\t}\t//\tfunction _renderStockChart()\r\n\r\n\r\n\tprivate function _renderContourChart($groupCount,$dimensions) {\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_contour.php');\r\n\r\n\t\t$this->_renderCartesianPlotArea('intint');\r\n\r\n\t\tfor($i = 0; $i < $groupCount; ++$i) {\r\n\t\t\t$this->_renderPlotContour($i);\r\n\t\t}\r\n\t}\t//\tfunction _renderContourChart()\r\n\r\n\r\n\tprivate function _renderCombinationChart($groupCount,$dimensions,$outputDestination) {\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php');\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_bar.php');\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_scatter.php');\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_regstat.php');\r\n\t\trequire_once(PHPExcel_Settings::getChartRendererPath().'jpgraph_line.php');\r\n\r\n\t\t$this->_renderCartesianPlotArea();\r\n\r\n\t\tfor($i = 0; $i < $groupCount; ++$i) {\r\n\t\t\t$dimensions = null;\r\n\t\t\t$chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();\r\n\t\t\tswitch ($chartType) {\r\n\t\t\t\tcase 'area3DChart' :\r\n\t\t\t\t\t$dimensions = '3d';\r\n\t\t\t\tcase 'areaChart' :\r\n\t\t\t\t\t$this->_renderPlotLine($i,True,True,$dimensions);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'bar3DChart' :\r\n\t\t\t\t\t$dimensions = '3d';\r\n\t\t\t\tcase 'barChart' :\r\n\t\t\t\t\t$this->_renderPlotBar($i,$dimensions);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'line3DChart' :\r\n\t\t\t\t\t$dimensions = '3d';\r\n\t\t\t\tcase 'lineChart' :\r\n\t\t\t\t\t$this->_renderPlotLine($i,False,True,$dimensions);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'scatterChart' :\r\n\t\t\t\t\t$this->_renderPlotScatter($i,false);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'bubbleChart' :\r\n\t\t\t\t\t$this->_renderPlotScatter($i,true);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tdefault\t:\r\n\t\t\t\t\t$this->_graph = null;\r\n\t\t\t\t\treturn false;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t$this->_renderLegend();\r\n\r\n\t\t$this->_graph->Stroke($outputDestination);\r\n\t\treturn true;\r\n\t}\t//\tfunction _renderCombinationChart()\r\n\r\n\r\n\tpublic function render($outputDestination) {\r\n        self::$_plotColour = 0;\r\n\r\n\t\t$groupCount = $this->_chart->getPlotArea()->getPlotGroupCount();\r\n\r\n\t\t$dimensions = null;\r\n\t\tif ($groupCount == 1) {\r\n\t\t\t$chartType = $this->_chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();\r\n\t\t} else {\r\n\t\t\t$chartTypes = array();\r\n\t\t\tfor($i = 0; $i < $groupCount; ++$i) {\r\n\t\t\t\t$chartTypes[] = $this->_chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();\r\n\t\t\t}\r\n\t\t\t$chartTypes = array_unique($chartTypes);\r\n\t\t\tif (count($chartTypes) == 1) {\r\n\t\t\t\t$chartType = array_pop($chartTypes);\r\n\t\t\t} elseif (count($chartTypes) == 0) {\r\n\t\t\t\techo 'Chart is not yet implemented<br />';\r\n\t\t\t\treturn false;\r\n\t\t\t} else {\r\n\t\t\t\treturn $this->_renderCombinationChart($groupCount,$dimensions,$outputDestination);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tswitch ($chartType) {\r\n\t\t\tcase 'area3DChart' :\r\n\t\t\t\t$dimensions = '3d';\r\n\t\t\tcase 'areaChart' :\r\n\t\t\t\t$this->_renderAreaChart($groupCount,$dimensions);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'bar3DChart' :\r\n\t\t\t\t$dimensions = '3d';\r\n\t\t\tcase 'barChart' :\r\n\t\t\t\t$this->_renderBarChart($groupCount,$dimensions);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'line3DChart' :\r\n\t\t\t\t$dimensions = '3d';\r\n\t\t\tcase 'lineChart' :\r\n\t\t\t\t$this->_renderLineChart($groupCount,$dimensions);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'pie3DChart' :\r\n\t\t\t\t$dimensions = '3d';\r\n\t\t\tcase 'pieChart' :\r\n\t\t\t\t$this->_renderPieChart($groupCount,$dimensions,False,False);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'doughnut3DChart' :\r\n\t\t\t\t$dimensions = '3d';\r\n\t\t\tcase 'doughnutChart' :\r\n\t\t\t\t$this->_renderPieChart($groupCount,$dimensions,True,True);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'scatterChart' :\r\n\t\t\t\t$this->_renderScatterChart($groupCount);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'bubbleChart' :\r\n\t\t\t\t$this->_renderBubbleChart($groupCount);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'radarChart' :\r\n\t\t\t\t$this->_renderRadarChart($groupCount);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'surface3DChart' :\r\n\t\t\t\t$dimensions = '3d';\r\n\t\t\tcase 'surfaceChart' :\r\n\t\t\t\t$this->_renderContourChart($groupCount,$dimensions);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'stockChart' :\r\n\t\t\t\t$this->_renderStockChart($groupCount,$dimensions);\r\n\t\t\t\tbreak;\r\n\t\t\tdefault\t:\r\n\t\t\t\techo $chartType.' is not yet implemented<br />';\r\n\t\t\t\treturn false;\r\n\t\t}\r\n\t\t$this->_renderLegend();\r\n\r\n\t\t$this->_graph->Stroke($outputDestination);\r\n\t\treturn true;\r\n\t}\t//\tfunction render()\r\n\r\n\r\n\t/**\r\n\t * Create a new PHPExcel_Chart_Renderer_jpgraph\r\n\t */\r\n\tpublic function __construct(PHPExcel_Chart $chart)\r\n\t{\r\n\t\t$this->_graph\t= null;\r\n\t\t$this->_chart\t= $chart;\r\n\t}\t//\tfunction __construct()\r\n\r\n}\t//\tPHPExcel_Chart_Renderer_jpgraph\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Chart/Title.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Chart_Title\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Chart_Title\n{\n\n\t/**\n\t * Title Caption\n\t *\n\t * @var string\n\t */\n\tprivate $_caption = null;\n\n\t/**\n\t * Title Layout\n\t *\n\t * @var PHPExcel_Chart_Layout\n\t */\n\tprivate $_layout = null;\n\n\t/**\n\t * Create a new PHPExcel_Chart_Title\n\t */\n\tpublic function __construct($caption = null, PHPExcel_Chart_Layout $layout = null)\n\t{\n\t\t$this->_caption = $caption;\n\t\t$this->_layout = $layout;\n\t}\n\n\t/**\n\t * Get caption\n\t *\n\t * @return string\n\t */\n\tpublic function getCaption() {\n\t\treturn $this->_caption;\n\t}\n\n\t/**\n\t * Set caption\n\t *\n\t * @param string $caption\n     * @return PHPExcel_Chart_Title\n\t */\n\tpublic function setCaption($caption = null) {\n\t\t$this->_caption = $caption;\n        \n        return $this;\n\t}\n\n\t/**\n\t * Get Layout\n\t *\n\t * @return PHPExcel_Chart_Layout\n\t */\n\tpublic function getLayout() {\n\t\treturn $this->_layout;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Chart.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Chart\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Chart\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Chart\n{\n\t/**\n\t * Chart Name\n\t *\n\t * @var string\n\t */\n\tprivate $_name = '';\n\n\t/**\n\t * Worksheet\n\t *\n\t * @var PHPExcel_Worksheet\n\t */\n\tprivate $_worksheet = null;\n\n\t/**\n\t * Chart Title\n\t *\n\t * @var PHPExcel_Chart_Title\n\t */\n\tprivate $_title = null;\n\n\t/**\n\t * Chart Legend\n\t *\n\t * @var PHPExcel_Chart_Legend\n\t */\n\tprivate $_legend = null;\n\n\t/**\n\t * X-Axis Label\n\t *\n\t * @var PHPExcel_Chart_Title\n\t */\n\tprivate $_xAxisLabel = null;\n\n\t/**\n\t * Y-Axis Label\n\t *\n\t * @var PHPExcel_Chart_Title\n\t */\n\tprivate $_yAxisLabel = null;\n\n\t/**\n\t * Chart Plot Area\n\t *\n\t * @var PHPExcel_Chart_PlotArea\n\t */\n\tprivate $_plotArea = null;\n\n\t/**\n\t * Plot Visible Only\n\t *\n\t * @var boolean\n\t */\n\tprivate $_plotVisibleOnly = true;\n\n\t/**\n\t * Display Blanks as\n\t *\n\t * @var string\n\t */\n\tprivate $_displayBlanksAs = '0';\n\n  /**\n   * Chart Asix Y as\n   *\n   * @var PHPExcel_Chart_Axis\n   */\n  private $_yAxis = null;\n\n  /**\n   * Chart Asix X as\n   *\n   * @var PHPExcel_Chart_Axis\n   */\n  private $_xAxis = null;\n\n  /**\n   * Chart Major Gridlines as\n   *\n   * @var PHPExcel_Chart_GridLines\n   */\n  private $_majorGridlines = null;\n\n  /**\n   * Chart Minor Gridlines as\n   *\n   * @var PHPExcel_Chart_GridLines\n   */\n  private $_minorGridlines = null;\n\n\t/**\n\t * Top-Left Cell Position\n\t *\n\t * @var string\n\t */\n\tprivate $_topLeftCellRef = 'A1';\n\n\n\t/**\n\t * Top-Left X-Offset\n\t *\n\t * @var integer\n\t */\n\tprivate $_topLeftXOffset = 0;\n\n\n\t/**\n\t * Top-Left Y-Offset\n\t *\n\t * @var integer\n\t */\n\tprivate $_topLeftYOffset = 0;\n\n\n\t/**\n\t * Bottom-Right Cell Position\n\t *\n\t * @var string\n\t */\n\tprivate $_bottomRightCellRef = 'A1';\n\n\n\t/**\n\t * Bottom-Right X-Offset\n\t *\n\t * @var integer\n\t */\n\tprivate $_bottomRightXOffset = 10;\n\n\n\t/**\n\t * Bottom-Right Y-Offset\n\t *\n\t * @var integer\n\t */\n\tprivate $_bottomRightYOffset = 10;\n\n\n\t/**\n\t * Create a new PHPExcel_Chart\n\t */\n\tpublic function __construct($name, PHPExcel_Chart_Title $title = null, PHPExcel_Chart_Legend $legend = null, PHPExcel_Chart_PlotArea $plotArea = null, $plotVisibleOnly = true, $displayBlanksAs = '0', PHPExcel_Chart_Title $xAxisLabel = null, PHPExcel_Chart_Title $yAxisLabel = null, PHPExcel_Chart_Axis $xAxis = null, PHPExcel_Chart_Axis $yAxis = null, PHPExcel_Chart_GridLines $majorGridlines = null, PHPExcel_Chart_GridLines $minorGridlines = null)\n\t{\n\t\t$this->_name = $name;\n\t\t$this->_title = $title;\n\t\t$this->_legend = $legend;\n\t\t$this->_xAxisLabel = $xAxisLabel;\n\t\t$this->_yAxisLabel = $yAxisLabel;\n\t\t$this->_plotArea = $plotArea;\n\t\t$this->_plotVisibleOnly = $plotVisibleOnly;\n\t\t$this->_displayBlanksAs = $displayBlanksAs;\n\t\t$this->_xAxis = $xAxis;\n\t\t$this->_yAxis = $yAxis;\n    $this->_majorGridlines = $majorGridlines;\n    $this->_minorGridlines = $minorGridlines;\n\t}\n\n\t/**\n\t * Get Name\n\t *\n\t * @return string\n\t */\n\tpublic function getName() {\n\t\treturn $this->_name;\n\t}\n\n\t/**\n\t * Get Worksheet\n\t *\n\t * @return PHPExcel_Worksheet\n\t */\n\tpublic function getWorksheet() {\n\t\treturn $this->_worksheet;\n\t}\n\n\t/**\n\t * Set Worksheet\n\t *\n\t * @param\tPHPExcel_Worksheet\t$pValue\n\t * @throws\tPHPExcel_Chart_Exception\n\t * @return PHPExcel_Chart\n\t */\n\tpublic function setWorksheet(PHPExcel_Worksheet $pValue = null) {\n\t\t$this->_worksheet = $pValue;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Title\n\t *\n\t * @return PHPExcel_Chart_Title\n\t */\n\tpublic function getTitle() {\n\t\treturn $this->_title;\n\t}\n\n\t/**\n\t * Set Title\n\t *\n\t * @param\tPHPExcel_Chart_Title $title\n\t * @return\tPHPExcel_Chart\n\t */\n\tpublic function setTitle(PHPExcel_Chart_Title $title) {\n\t\t$this->_title = $title;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Legend\n\t *\n\t * @return PHPExcel_Chart_Legend\n\t */\n\tpublic function getLegend() {\n\t\treturn $this->_legend;\n\t}\n\n\t/**\n\t * Set Legend\n\t *\n\t * @param\tPHPExcel_Chart_Legend $legend\n\t * @return\tPHPExcel_Chart\n\t */\n\tpublic function setLegend(PHPExcel_Chart_Legend $legend) {\n\t\t$this->_legend = $legend;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get X-Axis Label\n\t *\n\t * @return PHPExcel_Chart_Title\n\t */\n\tpublic function getXAxisLabel() {\n\t\treturn $this->_xAxisLabel;\n\t}\n\n\t/**\n\t * Set X-Axis Label\n\t *\n\t * @param\tPHPExcel_Chart_Title $label\n\t * @return\tPHPExcel_Chart\n\t */\n\tpublic function setXAxisLabel(PHPExcel_Chart_Title $label) {\n\t\t$this->_xAxisLabel = $label;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Y-Axis Label\n\t *\n\t * @return PHPExcel_Chart_Title\n\t */\n\tpublic function getYAxisLabel() {\n\t\treturn $this->_yAxisLabel;\n\t}\n\n\t/**\n\t * Set Y-Axis Label\n\t *\n\t * @param\tPHPExcel_Chart_Title $label\n\t * @return\tPHPExcel_Chart\n\t */\n\tpublic function setYAxisLabel(PHPExcel_Chart_Title $label) {\n\t\t$this->_yAxisLabel = $label;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Plot Area\n\t *\n\t * @return PHPExcel_Chart_PlotArea\n\t */\n\tpublic function getPlotArea() {\n\t\treturn $this->_plotArea;\n\t}\n\n\t/**\n\t * Get Plot Visible Only\n\t *\n\t * @return boolean\n\t */\n\tpublic function getPlotVisibleOnly() {\n\t\treturn $this->_plotVisibleOnly;\n\t}\n\n\t/**\n\t * Set Plot Visible Only\n\t *\n\t * @param boolean $plotVisibleOnly\n\t * @return PHPExcel_Chart\n\t */\n\tpublic function setPlotVisibleOnly($plotVisibleOnly = true) {\n\t\t$this->_plotVisibleOnly = $plotVisibleOnly;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Display Blanks as\n\t *\n\t * @return string\n\t */\n\tpublic function getDisplayBlanksAs() {\n\t\treturn $this->_displayBlanksAs;\n\t}\n\n\t/**\n\t * Set Display Blanks as\n\t *\n\t * @param string $displayBlanksAs\n\t * @return PHPExcel_Chart\n\t */\n\tpublic function setDisplayBlanksAs($displayBlanksAs = '0') {\n\t\t$this->_displayBlanksAs = $displayBlanksAs;\n\t}\n\n\n  /**\n   * Get yAxis\n   *\n   * @return PHPExcel_Chart_Axis\n   */\n  public function getChartAxisY() {\n    if($this->_yAxis !== NULL){\n      return $this->_yAxis;\n    }\n\n    return new PHPExcel_Chart_Axis();\n  }\n\n  /**\n   * Get xAxis\n   *\n   * @return PHPExcel_Chart_Axis\n   */\n  public function getChartAxisX() {\n    if($this->_xAxis !== NULL){\n      return $this->_xAxis;\n    }\n\n    return new PHPExcel_Chart_Axis();\n  }\n\n  /**\n   * Get Major Gridlines\n   *\n   * @return PHPExcel_Chart_GridLines\n   */\n  public function getMajorGridlines() {\n    if($this->_majorGridlines !== NULL){\n      return $this->_majorGridlines;\n    }\n\n    return new PHPExcel_Chart_GridLines();\n  }\n\n  /**\n   * Get Minor Gridlines\n   *\n   * @return PHPExcel_Chart_GridLines\n   */\n  public function getMinorGridlines() {\n    if($this->_minorGridlines !== NULL){\n      return $this->_minorGridlines;\n    }\n\n    return new PHPExcel_Chart_GridLines();\n  }\n\n\n\t/**\n\t * Set the Top Left position for the chart\n\t *\n\t * @param\tstring\t$cell\n\t * @param\tinteger\t$xOffset\n\t * @param\tinteger\t$yOffset\n\t * @return PHPExcel_Chart\n\t */\n\tpublic function setTopLeftPosition($cell, $xOffset=null, $yOffset=null) {\n\t\t$this->_topLeftCellRef = $cell;\n\t\tif (!is_null($xOffset))\n\t\t\t$this->setTopLeftXOffset($xOffset);\n\t\tif (!is_null($yOffset))\n\t\t\t$this->setTopLeftYOffset($yOffset);\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get the top left position of the chart\n\t *\n\t * @return array\tan associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell\n\t */\n\tpublic function getTopLeftPosition() {\n\t\treturn array( 'cell'\t=> $this->_topLeftCellRef,\n\t\t\t\t\t  'xOffset'\t=> $this->_topLeftXOffset,\n\t\t\t\t\t  'yOffset'\t=> $this->_topLeftYOffset\n\t\t\t\t\t);\n\t}\n\n\t/**\n\t * Get the cell address where the top left of the chart is fixed\n\t *\n\t * @return string\n\t */\n\tpublic function getTopLeftCell() {\n\t\treturn $this->_topLeftCellRef;\n\t}\n\n\t/**\n\t * Set the Top Left cell position for the chart\n\t *\n\t * @param\tstring\t$cell\n\t * @return PHPExcel_Chart\n\t */\n\tpublic function setTopLeftCell($cell) {\n\t\t$this->_topLeftCellRef = $cell;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Set the offset position within the Top Left cell for the chart\n\t *\n\t * @param\tinteger\t$xOffset\n\t * @param\tinteger\t$yOffset\n\t * @return PHPExcel_Chart\n\t */\n\tpublic function setTopLeftOffset($xOffset=null,$yOffset=null) {\n\t\tif (!is_null($xOffset))\n\t\t\t$this->setTopLeftXOffset($xOffset);\n\t\tif (!is_null($yOffset))\n\t\t\t$this->setTopLeftYOffset($yOffset);\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get the offset position within the Top Left cell for the chart\n\t *\n\t * @return integer[]\n\t */\n\tpublic function getTopLeftOffset() {\n\t\treturn array( 'X' => $this->_topLeftXOffset,\n\t\t\t\t\t  'Y' => $this->_topLeftYOffset\n\t\t\t\t\t);\n\t}\n\n\tpublic function setTopLeftXOffset($xOffset) {\n\t\t$this->_topLeftXOffset = $xOffset;\n\n\t\treturn $this;\n\t}\n\n\tpublic function getTopLeftXOffset() {\n\t\treturn $this->_topLeftXOffset;\n\t}\n\n\tpublic function setTopLeftYOffset($yOffset) {\n\t\t$this->_topLeftYOffset = $yOffset;\n\n\t\treturn $this;\n\t}\n\n\tpublic function getTopLeftYOffset() {\n\t\treturn $this->_topLeftYOffset;\n\t}\n\n\t/**\n\t * Set the Bottom Right position of the chart\n\t *\n\t * @param\tstring\t$cell\n\t * @param\tinteger\t$xOffset\n\t * @param\tinteger\t$yOffset\n\t * @return PHPExcel_Chart\n\t */\n\tpublic function setBottomRightPosition($cell, $xOffset=null, $yOffset=null) {\n\t\t$this->_bottomRightCellRef = $cell;\n\t\tif (!is_null($xOffset))\n\t\t\t$this->setBottomRightXOffset($xOffset);\n\t\tif (!is_null($yOffset))\n\t\t\t$this->setBottomRightYOffset($yOffset);\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get the bottom right position of the chart\n\t *\n\t * @return array\tan associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell\n\t */\n\tpublic function getBottomRightPosition() {\n\t\treturn array( 'cell'\t=> $this->_bottomRightCellRef,\n\t\t\t\t\t  'xOffset'\t=> $this->_bottomRightXOffset,\n\t\t\t\t\t  'yOffset'\t=> $this->_bottomRightYOffset\n\t\t\t\t\t);\n\t}\n\n\tpublic function setBottomRightCell($cell) {\n\t\t$this->_bottomRightCellRef = $cell;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get the cell address where the bottom right of the chart is fixed\n\t *\n\t * @return string\n\t */\n\tpublic function getBottomRightCell() {\n\t\treturn $this->_bottomRightCellRef;\n\t}\n\n\t/**\n\t * Set the offset position within the Bottom Right cell for the chart\n\t *\n\t * @param\tinteger\t$xOffset\n\t * @param\tinteger\t$yOffset\n\t * @return PHPExcel_Chart\n\t */\n\tpublic function setBottomRightOffset($xOffset=null,$yOffset=null) {\n\t\tif (!is_null($xOffset))\n\t\t\t$this->setBottomRightXOffset($xOffset);\n\t\tif (!is_null($yOffset))\n\t\t\t$this->setBottomRightYOffset($yOffset);\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get the offset position within the Bottom Right cell for the chart\n\t *\n\t * @return integer[]\n\t */\n\tpublic function getBottomRightOffset() {\n\t\treturn array( 'X' => $this->_bottomRightXOffset,\n\t\t\t\t\t  'Y' => $this->_bottomRightYOffset\n\t\t\t\t\t);\n\t}\n\n\tpublic function setBottomRightXOffset($xOffset) {\n\t\t$this->_bottomRightXOffset = $xOffset;\n\n\t\treturn $this;\n\t}\n\n\tpublic function getBottomRightXOffset() {\n\t\treturn $this->_bottomRightXOffset;\n\t}\n\n\tpublic function setBottomRightYOffset($yOffset) {\n\t\t$this->_bottomRightYOffset = $yOffset;\n\n\t\treturn $this;\n\t}\n\n\tpublic function getBottomRightYOffset() {\n\t\treturn $this->_bottomRightYOffset;\n\t}\n\n\n\tpublic function refresh() {\n\t\tif ($this->_worksheet !== NULL) {\n\t\t\t$this->_plotArea->refresh($this->_worksheet);\n\t\t}\n\t}\n\n\tpublic function render($outputDestination = null) {\n\t\t$libraryName = PHPExcel_Settings::getChartRendererName();\n\t\tif (is_null($libraryName)) {\n\t\t\treturn false;\n\t\t}\n\t\t//\tEnsure that data series values are up-to-date before we render\n\t\t$this->refresh();\n\n\t\t$libraryPath = PHPExcel_Settings::getChartRendererPath();\n\t\t$includePath = str_replace('\\\\','/',get_include_path());\n\t\t$rendererPath = str_replace('\\\\','/',$libraryPath);\n\t\tif (strpos($rendererPath,$includePath) === false) {\n\t\t\tset_include_path(get_include_path() . PATH_SEPARATOR . $libraryPath);\n\t\t}\n\n\t\t$rendererName = 'PHPExcel_Chart_Renderer_'.$libraryName;\n\t\t$renderer = new $rendererName($this);\n\n\t\tif ($outputDestination == 'php://output') {\n\t\t\t$outputDestination = null;\n\t\t}\n\t\treturn $renderer->render($outputDestination);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Comment.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Comment\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Comment implements PHPExcel_IComparable\n{\n    /**\n     * Author\n     *\n     * @var string\n     */\n    private $_author;\n\n    /**\n     * Rich text comment\n     *\n     * @var PHPExcel_RichText\n     */\n    private $_text;\n\n    /**\n     * Comment width (CSS style, i.e. XXpx or YYpt)\n     *\n     * @var string\n     */\n    private $_width = '96pt';\n\n    /**\n     * Left margin (CSS style, i.e. XXpx or YYpt)\n     *\n     * @var string\n     */\n    private $_marginLeft = '59.25pt';\n\n    /**\n     * Top margin (CSS style, i.e. XXpx or YYpt)\n     *\n     * @var string\n     */\n    private $_marginTop = '1.5pt';\n\n    /**\n     * Visible\n     *\n     * @var boolean\n     */\n    private $_visible = false;\n\n    /**\n     * Comment height (CSS style, i.e. XXpx or YYpt)\n     *\n     * @var string\n     */\n    private $_height = '55.5pt';\n\n    /**\n     * Comment fill color\n     *\n     * @var PHPExcel_Style_Color\n     */\n    private $_fillColor;\n\n    /**\n     * Alignment\n     *\n     * @var string\n     */\n    private $_alignment;\n\n    /**\n     * Create a new PHPExcel_Comment\n     *\n     * @throws PHPExcel_Exception\n     */\n    public function __construct()\n    {\n        // Initialise variables\n        $this->_author\t\t= 'Author';\n        $this->_text\t\t= new PHPExcel_RichText();\n        $this->_fillColor\t= new PHPExcel_Style_Color('FFFFFFE1');\n        $this->_alignment\t= PHPExcel_Style_Alignment::HORIZONTAL_GENERAL;\n    }\n\n    /**\n     * Get Author\n     *\n     * @return string\n     */\n    public function getAuthor() {\n        return $this->_author;\n    }\n\n    /**\n     * Set Author\n     *\n     * @param string $pValue\n     * @return PHPExcel_Comment\n     */\n    public function setAuthor($pValue = '') {\n        $this->_author = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get Rich text comment\n     *\n     * @return PHPExcel_RichText\n     */\n    public function getText() {\n        return $this->_text;\n    }\n\n    /**\n     * Set Rich text comment\n     *\n     * @param PHPExcel_RichText $pValue\n     * @return PHPExcel_Comment\n     */\n    public function setText(PHPExcel_RichText $pValue) {\n        $this->_text = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get comment width (CSS style, i.e. XXpx or YYpt)\n     *\n     * @return string\n     */\n    public function getWidth() {\n        return $this->_width;\n    }\n\n    /**\n     * Set comment width (CSS style, i.e. XXpx or YYpt)\n     *\n     * @param string $value\n     * @return PHPExcel_Comment\n     */\n    public function setWidth($value = '96pt') {\n        $this->_width = $value;\n        return $this;\n    }\n\n    /**\n     * Get comment height (CSS style, i.e. XXpx or YYpt)\n     *\n     * @return string\n     */\n    public function getHeight() {\n        return $this->_height;\n    }\n\n    /**\n     * Set comment height (CSS style, i.e. XXpx or YYpt)\n     *\n     * @param string $value\n     * @return PHPExcel_Comment\n     */\n    public function setHeight($value = '55.5pt') {\n        $this->_height = $value;\n        return $this;\n    }\n\n    /**\n     * Get left margin (CSS style, i.e. XXpx or YYpt)\n     *\n     * @return string\n     */\n    public function getMarginLeft() {\n        return $this->_marginLeft;\n    }\n\n    /**\n     * Set left margin (CSS style, i.e. XXpx or YYpt)\n     *\n     * @param string $value\n     * @return PHPExcel_Comment\n     */\n    public function setMarginLeft($value = '59.25pt') {\n        $this->_marginLeft = $value;\n        return $this;\n    }\n\n    /**\n     * Get top margin (CSS style, i.e. XXpx or YYpt)\n     *\n     * @return string\n     */\n    public function getMarginTop() {\n        return $this->_marginTop;\n    }\n\n    /**\n     * Set top margin (CSS style, i.e. XXpx or YYpt)\n     *\n     * @param string $value\n     * @return PHPExcel_Comment\n     */\n    public function setMarginTop($value = '1.5pt') {\n        $this->_marginTop = $value;\n        return $this;\n    }\n\n    /**\n     * Is the comment visible by default?\n     *\n     * @return boolean\n     */\n    public function getVisible() {\n        return $this->_visible;\n    }\n\n    /**\n     * Set comment default visibility\n     *\n     * @param boolean $value\n     * @return PHPExcel_Comment\n     */\n    public function setVisible($value = false) {\n        $this->_visible = $value;\n        return $this;\n    }\n\n    /**\n     * Get fill color\n     *\n     * @return PHPExcel_Style_Color\n     */\n    public function getFillColor() {\n        return $this->_fillColor;\n    }\n\n    /**\n     * Set Alignment\n     *\n     * @param string $pValue\n     * @return PHPExcel_Comment\n     */\n    public function setAlignment($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL) {\n        $this->_alignment = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get Alignment\n     *\n     * @return string\n     */\n    public function getAlignment() {\n        return $this->_alignment;\n    }\n\n    /**\n     * Get hash code\n     *\n     * @return string    Hash code\n     */\n    public function getHashCode() {\n        return md5(\n              $this->_author\n            . $this->_text->getHashCode()\n            . $this->_width\n            . $this->_height\n            . $this->_marginLeft\n            . $this->_marginTop\n            . ($this->_visible ? 1 : 0)\n            . $this->_fillColor->getHashCode()\n            . $this->_alignment\n            . __CLASS__\n        );\n    }\n\n    /**\n     * Implement PHP __clone to create a deep clone, not just a shallow copy.\n     */\n    public function __clone() {\n        $vars = get_object_vars($this);\n        foreach ($vars as $key => $value) {\n            if (is_object($value)) {\n                $this->$key = clone $value;\n            } else {\n                $this->$key = $value;\n            }\n        }\n    }\n\n    /**\n     * Convert to string\n     *\n     * @return string\n     */\n    public function __toString() {\n        return $this->_text->getPlainText();\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/DocumentProperties.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category    PHPExcel\n * @package    PHPExcel\n * @copyright    Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_DocumentProperties\n *\n * @category    PHPExcel\n * @package        PHPExcel\n * @copyright    Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_DocumentProperties\n{\n    /** constants */\n    const PROPERTY_TYPE_BOOLEAN\t= 'b';\n    const PROPERTY_TYPE_INTEGER = 'i';\n    const PROPERTY_TYPE_FLOAT   = 'f';\n    const PROPERTY_TYPE_DATE    = 'd';\n    const PROPERTY_TYPE_STRING  = 's';\n    const PROPERTY_TYPE_UNKNOWN = 'u';\n\n    /**\n     * Creator\n     *\n     * @var string\n     */\n    private $_creator    = 'Unknown Creator';\n\n    /**\n     * LastModifiedBy\n     *\n     * @var string\n     */\n    private $_lastModifiedBy;\n\n    /**\n     * Created\n     *\n     * @var datetime\n     */\n    private $_created;\n\n    /**\n     * Modified\n     *\n     * @var datetime\n     */\n    private $_modified;\n\n    /**\n     * Title\n     *\n     * @var string\n     */\n    private $_title            = 'Untitled Spreadsheet';\n\n    /**\n     * Description\n     *\n     * @var string\n     */\n    private $_description    = '';\n\n    /**\n     * Subject\n     *\n     * @var string\n     */\n    private $_subject        = '';\n\n    /**\n     * Keywords\n     *\n     * @var string\n     */\n    private $_keywords        = '';\n\n    /**\n     * Category\n     *\n     * @var string\n     */\n    private $_category        = '';\n\n    /**\n     * Manager\n     *\n     * @var string\n     */\n    private $_manager        = '';\n\n    /**\n     * Company\n     *\n     * @var string\n     */\n    private $_company        = 'Microsoft Corporation';\n\n    /**\n     * Custom Properties\n     *\n     * @var string\n     */\n    private $_customProperties    = array();\n\n\n    /**\n     * Create a new PHPExcel_DocumentProperties\n     */\n    public function __construct()\n    {\n        // Initialise values\n        $this->_lastModifiedBy    = $this->_creator;\n        $this->_created        = time();\n        $this->_modified    = time();\n    }\n\n    /**\n     * Get Creator\n     *\n     * @return string\n     */\n    public function getCreator() {\n        return $this->_creator;\n    }\n\n    /**\n     * Set Creator\n     *\n     * @param string $pValue\n     * @return PHPExcel_DocumentProperties\n     */\n    public function setCreator($pValue = '') {\n        $this->_creator = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get Last Modified By\n     *\n     * @return string\n     */\n    public function getLastModifiedBy() {\n        return $this->_lastModifiedBy;\n    }\n\n    /**\n     * Set Last Modified By\n     *\n     * @param string $pValue\n     * @return PHPExcel_DocumentProperties\n     */\n    public function setLastModifiedBy($pValue = '') {\n        $this->_lastModifiedBy = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get Created\n     *\n     * @return datetime\n     */\n    public function getCreated() {\n        return $this->_created;\n    }\n\n    /**\n     * Set Created\n     *\n     * @param datetime $pValue\n     * @return PHPExcel_DocumentProperties\n     */\n    public function setCreated($pValue = null) {\n        if ($pValue === NULL) {\n            $pValue = time();\n        } elseif (is_string($pValue)) {\n            if (is_numeric($pValue)) {\n                $pValue = intval($pValue);\n            } else {\n                $pValue = strtotime($pValue);\n            }\n        }\n\n        $this->_created = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get Modified\n     *\n     * @return datetime\n     */\n    public function getModified() {\n        return $this->_modified;\n    }\n\n    /**\n     * Set Modified\n     *\n     * @param datetime $pValue\n     * @return PHPExcel_DocumentProperties\n     */\n    public function setModified($pValue = null) {\n        if ($pValue === NULL) {\n            $pValue = time();\n        } elseif (is_string($pValue)) {\n            if (is_numeric($pValue)) {\n                $pValue = intval($pValue);\n            } else {\n                $pValue = strtotime($pValue);\n            }\n        }\n\n        $this->_modified = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get Title\n     *\n     * @return string\n     */\n    public function getTitle() {\n        return $this->_title;\n    }\n\n    /**\n     * Set Title\n     *\n     * @param string $pValue\n     * @return PHPExcel_DocumentProperties\n     */\n    public function setTitle($pValue = '') {\n        $this->_title = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get Description\n     *\n     * @return string\n     */\n    public function getDescription() {\n        return $this->_description;\n    }\n\n    /**\n     * Set Description\n     *\n     * @param string $pValue\n     * @return PHPExcel_DocumentProperties\n     */\n    public function setDescription($pValue = '') {\n        $this->_description = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get Subject\n     *\n     * @return string\n     */\n    public function getSubject() {\n        return $this->_subject;\n    }\n\n    /**\n     * Set Subject\n     *\n     * @param string $pValue\n     * @return PHPExcel_DocumentProperties\n     */\n    public function setSubject($pValue = '') {\n        $this->_subject = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get Keywords\n     *\n     * @return string\n     */\n    public function getKeywords() {\n        return $this->_keywords;\n    }\n\n    /**\n     * Set Keywords\n     *\n     * @param string $pValue\n     * @return PHPExcel_DocumentProperties\n     */\n    public function setKeywords($pValue = '') {\n        $this->_keywords = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get Category\n     *\n     * @return string\n     */\n    public function getCategory() {\n        return $this->_category;\n    }\n\n    /**\n     * Set Category\n     *\n     * @param string $pValue\n     * @return PHPExcel_DocumentProperties\n     */\n    public function setCategory($pValue = '') {\n        $this->_category = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get Company\n     *\n     * @return string\n     */\n    public function getCompany() {\n        return $this->_company;\n    }\n\n    /**\n     * Set Company\n     *\n     * @param string $pValue\n     * @return PHPExcel_DocumentProperties\n     */\n    public function setCompany($pValue = '') {\n        $this->_company = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get Manager\n     *\n     * @return string\n     */\n    public function getManager() {\n        return $this->_manager;\n    }\n\n    /**\n     * Set Manager\n     *\n     * @param string $pValue\n     * @return PHPExcel_DocumentProperties\n     */\n    public function setManager($pValue = '') {\n        $this->_manager = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get a List of Custom Property Names\n     *\n     * @return array of string\n     */\n    public function getCustomProperties() {\n        return array_keys($this->_customProperties);\n    }\n\n    /**\n     * Check if a Custom Property is defined\n     *\n     * @param string $propertyName\n     * @return boolean\n     */\n    public function isCustomPropertySet($propertyName) {\n        return isset($this->_customProperties[$propertyName]);\n    }\n\n    /**\n     * Get a Custom Property Value\n     *\n     * @param string $propertyName\n     * @return string\n     */\n    public function getCustomPropertyValue($propertyName) {\n        if (isset($this->_customProperties[$propertyName])) {\n            return $this->_customProperties[$propertyName]['value'];\n        }\n\n    }\n\n    /**\n     * Get a Custom Property Type\n     *\n     * @param string $propertyName\n     * @return string\n     */\n    public function getCustomPropertyType($propertyName) {\n        if (isset($this->_customProperties[$propertyName])) {\n            return $this->_customProperties[$propertyName]['type'];\n        }\n\n    }\n\n    /**\n     * Set a Custom Property\n     *\n     * @param string $propertyName\n     * @param mixed $propertyValue\n     * @param string $propertyType\n     * \t 'i'    : Integer\n     *   'f' : Floating Point\n     *   's' : String\n     *   'd' : Date/Time\n     *   'b' : Boolean\n     * @return PHPExcel_DocumentProperties\n     */\n    public function setCustomProperty($propertyName,$propertyValue='',$propertyType=NULL) {\n        if (($propertyType === NULL) || (!in_array($propertyType,array(self::PROPERTY_TYPE_INTEGER,\n                                                                       self::PROPERTY_TYPE_FLOAT,\n                                                                       self::PROPERTY_TYPE_STRING,\n                                                                       self::PROPERTY_TYPE_DATE,\n                                                                       self::PROPERTY_TYPE_BOOLEAN)))) {\n            if ($propertyValue === NULL) {\n                $propertyType = self::PROPERTY_TYPE_STRING;\n            } elseif (is_float($propertyValue)) {\n                $propertyType = self::PROPERTY_TYPE_FLOAT;\n            } elseif(is_int($propertyValue)) {\n                $propertyType = self::PROPERTY_TYPE_INTEGER;\n            } elseif (is_bool($propertyValue)) {\n                $propertyType = self::PROPERTY_TYPE_BOOLEAN;\n            } else {\n                $propertyType = self::PROPERTY_TYPE_STRING;\n            }\n        }\n\n        $this->_customProperties[$propertyName] = array('value' => $propertyValue, 'type' => $propertyType);\n        return $this;\n    }\n\n    /**\n     * Implement PHP __clone to create a deep clone, not just a shallow copy.\n     */\n    public function __clone() {\n        $vars = get_object_vars($this);\n        foreach ($vars as $key => $value) {\n            if (is_object($value)) {\n                $this->$key = clone $value;\n            } else {\n                $this->$key = $value;\n            }\n        }\n    }\n\n    public static function convertProperty($propertyValue,$propertyType) {\n        switch ($propertyType) {\n            case 'empty'    :    //    Empty\n                return '';\n                break;\n            case 'null'        :    //    Null\n                return NULL;\n                break;\n            case 'i1'        :    //    1-Byte Signed Integer\n            case 'i2'        :    //    2-Byte Signed Integer\n            case 'i4'        :    //    4-Byte Signed Integer\n            case 'i8'        :    //    8-Byte Signed Integer\n            case 'int'        :    //    Integer\n                return (int) $propertyValue;\n                break;\n            case 'ui1'        :    //    1-Byte Unsigned Integer\n            case 'ui2'        :    //    2-Byte Unsigned Integer\n            case 'ui4'        :    //    4-Byte Unsigned Integer\n            case 'ui8'        :    //    8-Byte Unsigned Integer\n            case 'uint'        :    //    Unsigned Integer\n                return abs((int) $propertyValue);\n                break;\n            case 'r4'        :    //    4-Byte Real Number\n            case 'r8'        :    //    8-Byte Real Number\n            case 'decimal'    :    //    Decimal\n                return (float) $propertyValue;\n                break;\n            case 'lpstr'    :    //    LPSTR\n            case 'lpwstr'    :    //    LPWSTR\n            case 'bstr'        :    //    Basic String\n                return $propertyValue;\n                break;\n            case 'date'        :    //    Date and Time\n            case 'filetime'    :    //    File Time\n                return strtotime($propertyValue);\n                break;\n            case 'bool'        :    //    Boolean\n                return ($propertyValue == 'true') ? True : False;\n                break;\n            case 'cy'        :    //    Currency\n            case 'error'    :    //    Error Status Code\n            case 'vector'    :    //    Vector\n            case 'array'    :    //    Array\n            case 'blob'        :    //    Binary Blob\n            case 'oblob'    :    //    Binary Blob Object\n            case 'stream'    :    //    Binary Stream\n            case 'ostream'    :    //    Binary Stream Object\n            case 'storage'    :    //    Binary Storage\n            case 'ostorage'    :    //    Binary Storage Object\n            case 'vstream'    :    //    Binary Versioned Stream\n            case 'clsid'    :    //    Class ID\n            case 'cf'        :    //    Clipboard Data\n                return $propertyValue;\n                break;\n        }\n        return $propertyValue;\n    }\n\n    public static function convertPropertyType($propertyType) {\n        switch ($propertyType) {\n            case 'i1'        :    //    1-Byte Signed Integer\n            case 'i2'        :    //    2-Byte Signed Integer\n            case 'i4'        :    //    4-Byte Signed Integer\n            case 'i8'        :    //    8-Byte Signed Integer\n            case 'int'        :    //    Integer\n            case 'ui1'        :    //    1-Byte Unsigned Integer\n            case 'ui2'        :    //    2-Byte Unsigned Integer\n            case 'ui4'        :    //    4-Byte Unsigned Integer\n            case 'ui8'        :    //    8-Byte Unsigned Integer\n            case 'uint'        :    //    Unsigned Integer\n                return self::PROPERTY_TYPE_INTEGER;\n                break;\n            case 'r4'        :    //    4-Byte Real Number\n            case 'r8'        :    //    8-Byte Real Number\n            case 'decimal'    :    //    Decimal\n                return self::PROPERTY_TYPE_FLOAT;\n                break;\n            case 'empty'    :    //    Empty\n            case 'null'        :    //    Null\n            case 'lpstr'    :    //    LPSTR\n            case 'lpwstr'    :    //    LPWSTR\n            case 'bstr'        :    //    Basic String\n                return self::PROPERTY_TYPE_STRING;\n                break;\n            case 'date'        :    //    Date and Time\n            case 'filetime'    :    //    File Time\n                return self::PROPERTY_TYPE_DATE;\n                break;\n            case 'bool'        :    //    Boolean\n                return self::PROPERTY_TYPE_BOOLEAN;\n                break;\n            case 'cy'        :    //    Currency\n            case 'error'    :    //    Error Status Code\n            case 'vector'    :    //    Vector\n            case 'array'    :    //    Array\n            case 'blob'        :    //    Binary Blob\n            case 'oblob'    :    //    Binary Blob Object\n            case 'stream'    :    //    Binary Stream\n            case 'ostream'    :    //    Binary Stream Object\n            case 'storage'    :    //    Binary Storage\n            case 'ostorage'    :    //    Binary Storage Object\n            case 'vstream'    :    //    Binary Versioned Stream\n            case 'clsid'    :    //    Class ID\n            case 'cf'        :    //    Clipboard Data\n                return self::PROPERTY_TYPE_UNKNOWN;\n                break;\n        }\n        return self::PROPERTY_TYPE_UNKNOWN;\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/DocumentSecurity.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_DocumentSecurity\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_DocumentSecurity\n{\n\t/**\n\t * LockRevision\n\t *\n\t * @var boolean\n\t */\n\tprivate $_lockRevision;\n\n\t/**\n\t * LockStructure\n\t *\n\t * @var boolean\n\t */\n\tprivate $_lockStructure;\n\n\t/**\n\t * LockWindows\n\t *\n\t * @var boolean\n\t */\n\tprivate $_lockWindows;\n\n\t/**\n\t * RevisionsPassword\n\t *\n\t * @var string\n\t */\n\tprivate $_revisionsPassword;\n\n\t/**\n\t * WorkbookPassword\n\t *\n\t * @var string\n\t */\n\tprivate $_workbookPassword;\n\n    /**\n     * Create a new PHPExcel_DocumentSecurity\n     */\n    public function __construct()\n    {\n    \t// Initialise values\n    \t$this->_lockRevision\t\t= false;\n    \t$this->_lockStructure\t\t= false;\n    \t$this->_lockWindows\t\t\t= false;\n    \t$this->_revisionsPassword\t= '';\n    \t$this->_workbookPassword\t= '';\n    }\n\n    /**\n     * Is some sort of dcument security enabled?\n     *\n     * @return boolean\n     */\n    function isSecurityEnabled() {\n    \treturn \t$this->_lockRevision ||\n\t\t    \t$this->_lockStructure ||\n\t\t    \t$this->_lockWindows;\n    }\n\n    /**\n     * Get LockRevision\n     *\n     * @return boolean\n     */\n    function getLockRevision() {\n    \treturn $this->_lockRevision;\n    }\n\n    /**\n     * Set LockRevision\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_DocumentSecurity\n     */\n    function setLockRevision($pValue = false) {\n    \t$this->_lockRevision = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get LockStructure\n     *\n     * @return boolean\n     */\n    function getLockStructure() {\n    \treturn $this->_lockStructure;\n    }\n\n    /**\n     * Set LockStructure\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_DocumentSecurity\n     */\n    function setLockStructure($pValue = false) {\n\t\t$this->_lockStructure = $pValue;\n\t\treturn $this;\n    }\n\n    /**\n     * Get LockWindows\n     *\n     * @return boolean\n     */\n    function getLockWindows() {\n    \treturn $this->_lockWindows;\n    }\n\n    /**\n     * Set LockWindows\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_DocumentSecurity\n     */\n    function setLockWindows($pValue = false) {\n    \t$this->_lockWindows = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get RevisionsPassword (hashed)\n     *\n     * @return string\n     */\n    function getRevisionsPassword() {\n    \treturn $this->_revisionsPassword;\n    }\n\n    /**\n     * Set RevisionsPassword\n     *\n     * @param string \t$pValue\n     * @param boolean \t$pAlreadyHashed If the password has already been hashed, set this to true\n     * @return PHPExcel_DocumentSecurity\n     */\n    function setRevisionsPassword($pValue = '', $pAlreadyHashed = false) {\n    \tif (!$pAlreadyHashed) {\n    \t\t$pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue);\n    \t}\n    \t$this->_revisionsPassword = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get WorkbookPassword (hashed)\n     *\n     * @return string\n     */\n    function getWorkbookPassword() {\n    \treturn $this->_workbookPassword;\n    }\n\n    /**\n     * Set WorkbookPassword\n     *\n     * @param string \t$pValue\n     * @param boolean \t$pAlreadyHashed If the password has already been hashed, set this to true\n     * @return PHPExcel_DocumentSecurity\n     */\n    function setWorkbookPassword($pValue = '', $pAlreadyHashed = false) {\n    \tif (!$pAlreadyHashed) {\n    \t\t$pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue);\n    \t}\n\t\t$this->_workbookPassword = $pValue;\n\t\treturn $this;\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Exception.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Exception\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Exception extends Exception {\n    /**\n     * Error handler callback\n     *\n     * @param mixed $code\n     * @param mixed $string\n     * @param mixed $file\n     * @param mixed $line\n     * @param mixed $context\n     */\n    public static function errorHandlerCallback($code, $string, $file, $line, $context) {\n        $e = new self($string, $code);\n        $e->line = $line;\n        $e->file = $file;\n        throw $e;\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/HashTable.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_HashTable\n *\n * @category   PHPExcel\n * @package\tPHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_HashTable\n{\n\t/**\n\t * HashTable elements\n\t *\n\t * @var array\n\t */\n\tpublic $_items = array();\n\n\t/**\n\t * HashTable key map\n\t *\n\t * @var array\n\t */\n\tpublic $_keyMap = array();\n\n\t/**\n\t * Create a new PHPExcel_HashTable\n\t *\n\t * @param\tPHPExcel_IComparable[] $pSource\tOptional source array to create HashTable from\n\t * @throws\tPHPExcel_Exception\n\t */\n\tpublic function __construct($pSource = null)\n\t{\n\t\tif ($pSource !== NULL) {\n\t\t\t// Create HashTable\n\t\t\t$this->addFromSource($pSource);\n\t\t}\n\t}\n\n\t/**\n\t * Add HashTable items from source\n\t *\n\t * @param\tPHPExcel_IComparable[] $pSource\tSource array to create HashTable from\n\t * @throws\tPHPExcel_Exception\n\t */\n\tpublic function addFromSource($pSource = null) {\n\t\t// Check if an array was passed\n\t\tif ($pSource == null) {\n\t\t\treturn;\n\t\t} else if (!is_array($pSource)) {\n\t\t\tthrow new PHPExcel_Exception('Invalid array parameter passed.');\n\t\t}\n\n\t\tforeach ($pSource as $item) {\n\t\t\t$this->add($item);\n\t\t}\n\t}\n\n\t/**\n\t * Add HashTable item\n\t *\n\t * @param\tPHPExcel_IComparable $pSource\tItem to add\n\t * @throws\tPHPExcel_Exception\n\t */\n\tpublic function add(PHPExcel_IComparable $pSource = null) {\n\t\t$hash = $pSource->getHashCode();\n\t\tif (!isset($this->_items[$hash])) {\n\t\t\t$this->_items[$hash] = $pSource;\n\t\t\t$this->_keyMap[count($this->_items) - 1] = $hash;\n\t\t}\n\t}\n\n\t/**\n\t * Remove HashTable item\n\t *\n\t * @param\tPHPExcel_IComparable $pSource\tItem to remove\n\t * @throws\tPHPExcel_Exception\n\t */\n\tpublic function remove(PHPExcel_IComparable $pSource = null) {\n\t\t$hash = $pSource->getHashCode();\n\t\tif (isset($this->_items[$hash])) {\n\t\t\tunset($this->_items[$hash]);\n\n\t\t\t$deleteKey = -1;\n\t\t\tforeach ($this->_keyMap as $key => $value) {\n\t\t\t\tif ($deleteKey >= 0) {\n\t\t\t\t\t$this->_keyMap[$key - 1] = $value;\n\t\t\t\t}\n\n\t\t\t\tif ($value == $hash) {\n\t\t\t\t\t$deleteKey = $key;\n\t\t\t\t}\n\t\t\t}\n\t\t\tunset($this->_keyMap[count($this->_keyMap) - 1]);\n\t\t}\n\t}\n\n\t/**\n\t * Clear HashTable\n\t *\n\t */\n\tpublic function clear() {\n\t\t$this->_items = array();\n\t\t$this->_keyMap = array();\n\t}\n\n\t/**\n\t * Count\n\t *\n\t * @return int\n\t */\n\tpublic function count() {\n\t\treturn count($this->_items);\n\t}\n\n\t/**\n\t * Get index for hash code\n\t *\n\t * @param\tstring\t$pHashCode\n\t * @return\tint\tIndex\n\t */\n\tpublic function getIndexForHashCode($pHashCode = '') {\n\t\treturn array_search($pHashCode, $this->_keyMap);\n\t}\n\n\t/**\n\t * Get by index\n\t *\n\t * @param\tint\t$pIndex\n\t * @return\tPHPExcel_IComparable\n\t *\n\t */\n\tpublic function getByIndex($pIndex = 0) {\n\t\tif (isset($this->_keyMap[$pIndex])) {\n\t\t\treturn $this->getByHashCode( $this->_keyMap[$pIndex] );\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * Get by hashcode\n\t *\n\t * @param\tstring\t$pHashCode\n\t * @return\tPHPExcel_IComparable\n\t *\n\t */\n\tpublic function getByHashCode($pHashCode = '') {\n\t\tif (isset($this->_items[$pHashCode])) {\n\t\t\treturn $this->_items[$pHashCode];\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t/**\n\t * HashTable to array\n\t *\n\t * @return PHPExcel_IComparable[]\n\t */\n\tpublic function toArray() {\n\t\treturn $this->_items;\n\t}\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Helper/HTML.php",
    "content": "<?php\n\nclass PHPExcel_Helper_HTML\n{\n    protected static $colourMap = array(\n        'aliceblue' => 'f0f8ff', \n        'antiquewhite' => 'faebd7',\n        'antiquewhite1' => 'ffefdb',\n        'antiquewhite2' => 'eedfcc',\n        'antiquewhite3' => 'cdc0b0',\n        'antiquewhite4' => '8b8378',\n        'aqua' => '00ffff',\n        'aquamarine1' => '7fffd4',\n        'aquamarine2' => '76eec6',\n        'aquamarine4' => '458b74',\n        'azure1' => 'f0ffff',\n        'azure2' => 'e0eeee',\n        'azure3' => 'c1cdcd',\n        'azure4' => '838b8b',\n        'beige' => 'f5f5dc',\n        'bisque1' => 'ffe4c4',\n        'bisque2' => 'eed5b7',\n        'bisque3' => 'cdb79e',\n        'bisque4' => '8b7d6b',\n        'black' => '000000',\n        'blanchedalmond' => 'ffebcd',\n        'blue' => '0000ff',\n        'blue1' => '0000ff',\n        'blue2' => '0000ee',\n        'blue4' => '00008b',\n        'blueviolet' => '8a2be2',\n        'brown' => 'a52a2a',\n        'brown1' => 'ff4040',\n        'brown2' => 'ee3b3b',\n        'brown3' => 'cd3333',\n        'brown4' => '8b2323',\n        'burlywood' => 'deb887',\n        'burlywood1' => 'ffd39b',\n        'burlywood2' => 'eec591',\n        'burlywood3' => 'cdaa7d',\n        'burlywood4' => '8b7355',\n        'cadetblue' => '5f9ea0',\n        'cadetblue1' => '98f5ff',\n        'cadetblue2' => '8ee5ee',\n        'cadetblue3' => '7ac5cd',\n        'cadetblue4' => '53868b',\n        'chartreuse1' => '7fff00',\n        'chartreuse2' => '76ee00',\n        'chartreuse3' => '66cd00',\n        'chartreuse4' => '458b00',\n        'chocolate' => 'd2691e',\n        'chocolate1' => 'ff7f24',\n        'chocolate2' => 'ee7621',\n        'chocolate3' => 'cd661d',\n        'coral' => 'ff7f50',\n        'coral1' => 'ff7256',\n        'coral2' => 'ee6a50',\n        'coral3' => 'cd5b45',\n        'coral4' => '8b3e2f',\n        'cornflowerblue' => '6495ed',\n        'cornsilk1' => 'fff8dc',\n        'cornsilk2' => 'eee8cd',\n        'cornsilk3' => 'cdc8b1',\n        'cornsilk4' => '8b8878',\n        'cyan1' => '00ffff',\n        'cyan2' => '00eeee',\n        'cyan3' => '00cdcd',\n        'cyan4' => '008b8b',\n        'darkgoldenrod' => 'b8860b',\n        'darkgoldenrod1' => 'ffb90f',\n        'darkgoldenrod2' => 'eead0e',\n        'darkgoldenrod3' => 'cd950c',\n        'darkgoldenrod4' => '8b6508',\n        'darkgreen' => '006400',\n        'darkkhaki' => 'bdb76b',\n        'darkolivegreen' => '556b2f',\n        'darkolivegreen1' => 'caff70',\n        'darkolivegreen2' => 'bcee68',\n        'darkolivegreen3' => 'a2cd5a',\n        'darkolivegreen4' => '6e8b3d',\n        'darkorange' => 'ff8c00',\n        'darkorange1' => 'ff7f00',\n        'darkorange2' => 'ee7600',\n        'darkorange3' => 'cd6600',\n        'darkorange4' => '8b4500',\n        'darkorchid' => '9932cc',\n        'darkorchid1' => 'bf3eff',\n        'darkorchid2' => 'b23aee',\n        'darkorchid3' => '9a32cd',\n        'darkorchid4' => '68228b',\n        'darksalmon' => 'e9967a',\n        'darkseagreen' => '8fbc8f',\n        'darkseagreen1' => 'c1ffc1',\n        'darkseagreen2' => 'b4eeb4',\n        'darkseagreen3' => '9bcd9b',\n        'darkseagreen4' => '698b69',\n        'darkslateblue' => '483d8b',\n        'darkslategray' => '2f4f4f',\n        'darkslategray1' => '97ffff',\n        'darkslategray2' => '8deeee',\n        'darkslategray3' => '79cdcd',\n        'darkslategray4' => '528b8b',\n        'darkturquoise' => '00ced1',\n        'darkviolet' => '9400d3',\n        'deeppink1' => 'ff1493',\n        'deeppink2' => 'ee1289',\n        'deeppink3' => 'cd1076',\n        'deeppink4' => '8b0a50',\n        'deepskyblue1' => '00bfff',\n        'deepskyblue2' => '00b2ee',\n        'deepskyblue3' => '009acd',\n        'deepskyblue4' => '00688b',\n        'dimgray' => '696969',\n        'dodgerblue1' => '1e90ff',\n        'dodgerblue2' => '1c86ee',\n        'dodgerblue3' => '1874cd',\n        'dodgerblue4' => '104e8b',\n        'firebrick' => 'b22222',\n        'firebrick1' => 'ff3030',\n        'firebrick2' => 'ee2c2c',\n        'firebrick3' => 'cd2626',\n        'firebrick4' => '8b1a1a',\n        'floralwhite' => 'fffaf0',\n        'forestgreen' => '228b22',\n        'fuchsia' => 'ff00ff',\n        'gainsboro' => 'dcdcdc',\n        'ghostwhite' => 'f8f8ff',\n        'gold1' => 'ffd700',\n        'gold2' => 'eec900',\n        'gold3' => 'cdad00',\n        'gold4' => '8b7500',\n        'goldenrod' => 'daa520',\n        'goldenrod1' => 'ffc125',\n        'goldenrod2' => 'eeb422',\n        'goldenrod3' => 'cd9b1d',\n        'goldenrod4' => '8b6914',\n        'gray' => 'bebebe',\n        'gray1' => '030303',\n        'gray10' => '1a1a1a',\n        'gray11' => '1c1c1c',\n        'gray12' => '1f1f1f',\n        'gray13' => '212121',\n        'gray14' => '242424',\n        'gray15' => '262626',\n        'gray16' => '292929',\n        'gray17' => '2b2b2b',\n        'gray18' => '2e2e2e',\n        'gray19' => '303030',\n        'gray2' => '050505',\n        'gray20' => '333333',\n        'gray21' => '363636',\n        'gray22' => '383838',\n        'gray23' => '3b3b3b',\n        'gray24' => '3d3d3d',\n        'gray25' => '404040',\n        'gray26' => '424242',\n        'gray27' => '454545',\n        'gray28' => '474747',\n        'gray29' => '4a4a4a',\n        'gray3' => '080808',\n        'gray30' => '4d4d4d',\n        'gray31' => '4f4f4f',\n        'gray32' => '525252',\n        'gray33' => '545454',\n        'gray34' => '575757',\n        'gray35' => '595959',\n        'gray36' => '5c5c5c',\n        'gray37' => '5e5e5e',\n        'gray38' => '616161',\n        'gray39' => '636363',\n        'gray4' => '0a0a0a',\n        'gray40' => '666666',\n        'gray41' => '696969',\n        'gray42' => '6b6b6b',\n        'gray43' => '6e6e6e',\n        'gray44' => '707070',\n        'gray45' => '737373',\n        'gray46' => '757575',\n        'gray47' => '787878',\n        'gray48' => '7a7a7a',\n        'gray49' => '7d7d7d',\n        'gray5' => '0d0d0d',\n        'gray50' => '7f7f7f',\n        'gray51' => '828282',\n        'gray52' => '858585',\n        'gray53' => '878787',\n        'gray54' => '8a8a8a',\n        'gray55' => '8c8c8c',\n        'gray56' => '8f8f8f',\n        'gray57' => '919191',\n        'gray58' => '949494',\n        'gray59' => '969696',\n        'gray6' => '0f0f0f',\n        'gray60' => '999999',\n        'gray61' => '9c9c9c',\n        'gray62' => '9e9e9e',\n        'gray63' => 'a1a1a1',\n        'gray64' => 'a3a3a3',\n        'gray65' => 'a6a6a6',\n        'gray66' => 'a8a8a8',\n        'gray67' => 'ababab',\n        'gray68' => 'adadad',\n        'gray69' => 'b0b0b0',\n        'gray7' => '121212',\n        'gray70' => 'b3b3b3',\n        'gray71' => 'b5b5b5',\n        'gray72' => 'b8b8b8',\n        'gray73' => 'bababa',\n        'gray74' => 'bdbdbd',\n        'gray75' => 'bfbfbf',\n        'gray76' => 'c2c2c2',\n        'gray77' => 'c4c4c4',\n        'gray78' => 'c7c7c7',\n        'gray79' => 'c9c9c9',\n        'gray8' => '141414',\n        'gray80' => 'cccccc',\n        'gray81' => 'cfcfcf',\n        'gray82' => 'd1d1d1',\n        'gray83' => 'd4d4d4',\n        'gray84' => 'd6d6d6',\n        'gray85' => 'd9d9d9',\n        'gray86' => 'dbdbdb',\n        'gray87' => 'dedede',\n        'gray88' => 'e0e0e0',\n        'gray89' => 'e3e3e3',\n        'gray9' => '171717',\n        'gray90' => 'e5e5e5',\n        'gray91' => 'e8e8e8',\n        'gray92' => 'ebebeb',\n        'gray93' => 'ededed',\n        'gray94' => 'f0f0f0',\n        'gray95' => 'f2f2f2',\n        'gray97' => 'f7f7f7',\n        'gray98' => 'fafafa',\n        'gray99' => 'fcfcfc',\n        'green' => '00ff00',\n        'green1' => '00ff00',\n        'green2' => '00ee00',\n        'green3' => '00cd00',\n        'green4' => '008b00',\n        'greenyellow' => 'adff2f',\n        'honeydew1' => 'f0fff0',\n        'honeydew2' => 'e0eee0',\n        'honeydew3' => 'c1cdc1',\n        'honeydew4' => '838b83',\n        'hotpink' => 'ff69b4',\n        'hotpink1' => 'ff6eb4',\n        'hotpink2' => 'ee6aa7',\n        'hotpink3' => 'cd6090',\n        'hotpink4' => '8b3a62',\n        'indianred' => 'cd5c5c',\n        'indianred1' => 'ff6a6a',\n        'indianred2' => 'ee6363',\n        'indianred3' => 'cd5555',\n        'indianred4' => '8b3a3a',\n        'ivory1' => 'fffff0',\n        'ivory2' => 'eeeee0',\n        'ivory3' => 'cdcdc1',\n        'ivory4' => '8b8b83',\n        'khaki' => 'f0e68c',\n        'khaki1' => 'fff68f',\n        'khaki2' => 'eee685',\n        'khaki3' => 'cdc673',\n        'khaki4' => '8b864e',\n        'lavender' => 'e6e6fa',\n        'lavenderblush1' => 'fff0f5',\n        'lavenderblush2' => 'eee0e5',\n        'lavenderblush3' => 'cdc1c5',\n        'lavenderblush4' => '8b8386',\n        'lawngreen' => '7cfc00',\n        'lemonchiffon1' => 'fffacd',\n        'lemonchiffon2' => 'eee9bf',\n        'lemonchiffon3' => 'cdc9a5',\n        'lemonchiffon4' => '8b8970',\n        'light' => 'eedd82',\n        'lightblue' => 'add8e6',\n        'lightblue1' => 'bfefff',\n        'lightblue2' => 'b2dfee',\n        'lightblue3' => '9ac0cd',\n        'lightblue4' => '68838b',\n        'lightcoral' => 'f08080',\n        'lightcyan1' => 'e0ffff',\n        'lightcyan2' => 'd1eeee',\n        'lightcyan3' => 'b4cdcd',\n        'lightcyan4' => '7a8b8b',\n        'lightgoldenrod1' => 'ffec8b',\n        'lightgoldenrod2' => 'eedc82',\n        'lightgoldenrod3' => 'cdbe70',\n        'lightgoldenrod4' => '8b814c',\n        'lightgoldenrodyellow' => 'fafad2',\n        'lightgray' => 'd3d3d3',\n        'lightpink' => 'ffb6c1',\n        'lightpink1' => 'ffaeb9',\n        'lightpink2' => 'eea2ad',\n        'lightpink3' => 'cd8c95',\n        'lightpink4' => '8b5f65',\n        'lightsalmon1' => 'ffa07a',\n        'lightsalmon2' => 'ee9572',\n        'lightsalmon3' => 'cd8162',\n        'lightsalmon4' => '8b5742',\n        'lightseagreen' => '20b2aa',\n        'lightskyblue' => '87cefa',\n        'lightskyblue1' => 'b0e2ff',\n        'lightskyblue2' => 'a4d3ee',\n        'lightskyblue3' => '8db6cd',\n        'lightskyblue4' => '607b8b',\n        'lightslateblue' => '8470ff',\n        'lightslategray' => '778899',\n        'lightsteelblue' => 'b0c4de',\n        'lightsteelblue1' => 'cae1ff',\n        'lightsteelblue2' => 'bcd2ee',\n        'lightsteelblue3' => 'a2b5cd',\n        'lightsteelblue4' => '6e7b8b',\n        'lightyellow1' => 'ffffe0',\n        'lightyellow2' => 'eeeed1',\n        'lightyellow3' => 'cdcdb4',\n        'lightyellow4' => '8b8b7a',\n        'lime' => '00ff00',\n        'limegreen' => '32cd32',\n        'linen' => 'faf0e6',\n        'magenta' => 'ff00ff',\n        'magenta2' => 'ee00ee',\n        'magenta3' => 'cd00cd',\n        'magenta4' => '8b008b',\n        'maroon' => 'b03060',\n        'maroon1' => 'ff34b3',\n        'maroon2' => 'ee30a7',\n        'maroon3' => 'cd2990',\n        'maroon4' => '8b1c62',\n        'medium' => '66cdaa',\n        'mediumaquamarine' => '66cdaa',\n        'mediumblue' => '0000cd',\n        'mediumorchid' => 'ba55d3',\n        'mediumorchid1' => 'e066ff',\n        'mediumorchid2' => 'd15fee',\n        'mediumorchid3' => 'b452cd',\n        'mediumorchid4' => '7a378b',\n        'mediumpurple' => '9370db',\n        'mediumpurple1' => 'ab82ff',\n        'mediumpurple2' => '9f79ee',\n        'mediumpurple3' => '8968cd',\n        'mediumpurple4' => '5d478b',\n        'mediumseagreen' => '3cb371',\n        'mediumslateblue' => '7b68ee',\n        'mediumspringgreen' => '00fa9a',\n        'mediumturquoise' => '48d1cc',\n        'mediumvioletred' => 'c71585',\n        'midnightblue' => '191970',\n        'mintcream' => 'f5fffa',\n        'mistyrose1' => 'ffe4e1',\n        'mistyrose2' => 'eed5d2',\n        'mistyrose3' => 'cdb7b5',\n        'mistyrose4' => '8b7d7b',\n        'moccasin' => 'ffe4b5',\n        'navajowhite1' => 'ffdead',\n        'navajowhite2' => 'eecfa1',\n        'navajowhite3' => 'cdb38b',\n        'navajowhite4' => '8b795e',\n        'navy' => '000080',\n        'navyblue' => '000080',\n        'oldlace' => 'fdf5e6',\n        'olive' => '808000',\n        'olivedrab' => '6b8e23',\n        'olivedrab1' => 'c0ff3e',\n        'olivedrab2' => 'b3ee3a',\n        'olivedrab4' => '698b22',\n        'orange' => 'ffa500',\n        'orange1' => 'ffa500',\n        'orange2' => 'ee9a00',\n        'orange3' => 'cd8500',\n        'orange4' => '8b5a00',\n        'orangered1' => 'ff4500',\n        'orangered2' => 'ee4000',\n        'orangered3' => 'cd3700',\n        'orangered4' => '8b2500',\n        'orchid' => 'da70d6',\n        'orchid1' => 'ff83fa',\n        'orchid2' => 'ee7ae9',\n        'orchid3' => 'cd69c9',\n        'orchid4' => '8b4789',\n        'pale' => 'db7093',\n        'palegoldenrod' => 'eee8aa',\n        'palegreen' => '98fb98',\n        'palegreen1' => '9aff9a',\n        'palegreen2' => '90ee90',\n        'palegreen3' => '7ccd7c',\n        'palegreen4' => '548b54',\n        'paleturquoise' => 'afeeee',\n        'paleturquoise1' => 'bbffff',\n        'paleturquoise2' => 'aeeeee',\n        'paleturquoise3' => '96cdcd',\n        'paleturquoise4' => '668b8b',\n        'palevioletred' => 'db7093',\n        'palevioletred1' => 'ff82ab',\n        'palevioletred2' => 'ee799f',\n        'palevioletred3' => 'cd6889',\n        'palevioletred4' => '8b475d',\n        'papayawhip' => 'ffefd5',\n        'peachpuff1' => 'ffdab9',\n        'peachpuff2' => 'eecbad',\n        'peachpuff3' => 'cdaf95',\n        'peachpuff4' => '8b7765',\n        'pink' => 'ffc0cb',\n        'pink1' => 'ffb5c5',\n        'pink2' => 'eea9b8',\n        'pink3' => 'cd919e',\n        'pink4' => '8b636c',\n        'plum' => 'dda0dd',\n        'plum1' => 'ffbbff',\n        'plum2' => 'eeaeee',\n        'plum3' => 'cd96cd',\n        'plum4' => '8b668b',\n        'powderblue' => 'b0e0e6',\n        'purple' => 'a020f0',\n        'rebeccapurple' => '663399',\n        'purple1' => '9b30ff',\n        'purple2' => '912cee',\n        'purple3' => '7d26cd',\n        'purple4' => '551a8b',\n        'red' => 'ff0000',\n        'red1' => 'ff0000',\n        'red2' => 'ee0000',\n        'red3' => 'cd0000',\n        'red4' => '8b0000',\n        'rosybrown' => 'bc8f8f',\n        'rosybrown1' => 'ffc1c1',\n        'rosybrown2' => 'eeb4b4',\n        'rosybrown3' => 'cd9b9b',\n        'rosybrown4' => '8b6969',\n        'royalblue' => '4169e1',\n        'royalblue1' => '4876ff',\n        'royalblue2' => '436eee',\n        'royalblue3' => '3a5fcd',\n        'royalblue4' => '27408b',\n        'saddlebrown' => '8b4513',\n        'salmon' => 'fa8072',\n        'salmon1' => 'ff8c69',\n        'salmon2' => 'ee8262',\n        'salmon3' => 'cd7054',\n        'salmon4' => '8b4c39',\n        'sandybrown' => 'f4a460',\n        'seagreen1' => '54ff9f',\n        'seagreen2' => '4eee94',\n        'seagreen3' => '43cd80',\n        'seagreen4' => '2e8b57',\n        'seashell1' => 'fff5ee',\n        'seashell2' => 'eee5de',\n        'seashell3' => 'cdc5bf',\n        'seashell4' => '8b8682',\n        'sienna' => 'a0522d',\n        'sienna1' => 'ff8247',\n        'sienna2' => 'ee7942',\n        'sienna3' => 'cd6839',\n        'sienna4' => '8b4726',\n        'silver' => 'c0c0c0',\n        'skyblue' => '87ceeb',\n        'skyblue1' => '87ceff',\n        'skyblue2' => '7ec0ee',\n        'skyblue3' => '6ca6cd',\n        'skyblue4' => '4a708b',\n        'slateblue' => '6a5acd',\n        'slateblue1' => '836fff',\n        'slateblue2' => '7a67ee',\n        'slateblue3' => '6959cd',\n        'slateblue4' => '473c8b',\n        'slategray' => '708090',\n        'slategray1' => 'c6e2ff',\n        'slategray2' => 'b9d3ee',\n        'slategray3' => '9fb6cd',\n        'slategray4' => '6c7b8b',\n        'snow1' => 'fffafa',\n        'snow2' => 'eee9e9',\n        'snow3' => 'cdc9c9',\n        'snow4' => '8b8989',\n        'springgreen1' => '00ff7f',\n        'springgreen2' => '00ee76',\n        'springgreen3' => '00cd66',\n        'springgreen4' => '008b45',\n        'steelblue' => '4682b4',\n        'steelblue1' => '63b8ff',\n        'steelblue2' => '5cacee',\n        'steelblue3' => '4f94cd',\n        'steelblue4' => '36648b',\n        'tan' => 'd2b48c',\n        'tan1' => 'ffa54f',\n        'tan2' => 'ee9a49',\n        'tan3' => 'cd853f',\n        'tan4' => '8b5a2b',\n        'teal' => '008080',\n        'thistle' => 'd8bfd8',\n        'thistle1' => 'ffe1ff',\n        'thistle2' => 'eed2ee',\n        'thistle3' => 'cdb5cd',\n        'thistle4' => '8b7b8b',\n        'tomato1' => 'ff6347',\n        'tomato2' => 'ee5c42',\n        'tomato3' => 'cd4f39',\n        'tomato4' => '8b3626',\n        'turquoise' => '40e0d0',\n        'turquoise1' => '00f5ff',\n        'turquoise2' => '00e5ee',\n        'turquoise3' => '00c5cd',\n        'turquoise4' => '00868b',\n        'violet' => 'ee82ee',\n        'violetred' => 'd02090',\n        'violetred1' => 'ff3e96',\n        'violetred2' => 'ee3a8c',\n        'violetred3' => 'cd3278',\n        'violetred4' => '8b2252',\n        'wheat' => 'f5deb3',\n        'wheat1' => 'ffe7ba',\n        'wheat2' => 'eed8ae',\n        'wheat3' => 'cdba96',\n        'wheat4' => '8b7e66',\n        'white' => 'ffffff',\n        'whitesmoke' => 'f5f5f5',\n        'yellow' => 'ffff00',\n        'yellow1' => 'ffff00',\n        'yellow2' => 'eeee00',\n        'yellow3' => 'cdcd00',\n        'yellow4' => '8b8b00',\n        'yellowgreen' => '9acd32',\n    );\n\n    protected $face;\n    protected $size;\n    protected $color;\n\n\tprotected $bold = false;\n\tprotected $italic = false;\n\tprotected $underline = false;\n\tprotected $superscript = false;\n\tprotected $subscript = false;\n\tprotected $strikethrough = false;\n\n    protected $startTagCallbacks = array(\n        'font' => 'startFontTag',\n        'b' => 'startBoldTag',\n        'strong' => 'startBoldTag',\n        'i' => 'startItalicTag',\n        'em' => 'startItalicTag',\n        'u' => 'startUnderlineTag',\n        'ins' => 'startUnderlineTag',\n        'del' => 'startStrikethruTag',\n        'sup' => 'startSuperscriptTag',\n        'sub' => 'startSubscriptTag',\n    );\n\n    protected $endTagCallbacks = array(\n        'font' => 'endFontTag',\n        'b' => 'endBoldTag',\n        'strong' => 'endBoldTag',\n        'i' => 'endItalicTag',\n        'em' => 'endItalicTag',\n        'u' => 'endUnderlineTag',\n        'ins' => 'endUnderlineTag',\n        'del' => 'endStrikethruTag',\n        'sup' => 'endSuperscriptTag',\n        'sub' => 'endSubscriptTag',\n        'br' => 'breakTag',\n        'p' => 'breakTag',\n        'h1' => 'breakTag',\n        'h2' => 'breakTag',\n        'h3' => 'breakTag',\n        'h4' => 'breakTag',\n        'h5' => 'breakTag',\n        'h6' => 'breakTag',\n    );\n\n    protected $stack = array();\n\n    protected $stringData = '';\n\n    protected $richTextObject;\n\n    protected function initialise() {\n        $this->face = $this->size = $this->color = null;\n        $this->bold = $this->italic = $this->underline = $this->superscript = $this->subscript = $this->strikethrough = false;\n\n        $this->stack = array();\n\n        $this->stringData = '';\n    }\n\n    public function toRichTextObject($html) {\n        $this->initialise();\n\n        //\tCreate a new DOM object\n        $dom = new domDocument;\n        //\tLoad the HTML file into the DOM object\n        //  Note the use of error suppression, because typically this will be an html fragment, so not fully valid markup\n        $loaded = @$dom->loadHTML($html);\n\n        //\tDiscard excess white space\n        $dom->preserveWhiteSpace = false;\n\n        $this->richTextObject = new PHPExcel_RichText();;\n        $this->parseElements($dom);\n        return $this->richTextObject;\n    }\n\n    protected function buildTextRun() {\n        $text = $this->stringData;\n        if (trim($text) === '')\n            return;\n\n        $richtextRun = $this->richTextObject->createTextRun($this->stringData);\n        if ($this->face) {\n            $richtextRun->getFont()->setName($this->face);\n        }\n        if ($this->size) {\n            $richtextRun->getFont()->setSize($this->size);\n        }\n        if ($this->color) {\n            $richtextRun->getFont()->setColor( new PHPExcel_Style_Color( 'ff' . $this->color ) );\n        }\n        if ($this->bold) {\n            $richtextRun->getFont()->setBold(true);\n        }\n        if ($this->italic) {\n            $richtextRun->getFont()->setItalic(true);\n        }\n        if ($this->underline) {\n            $richtextRun->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);\n        }\n        if ($this->superscript) {\n            $richtextRun->getFont()->setSuperScript(true);\n        }\n        if ($this->subscript) {\n            $richtextRun->getFont()->setSubScript(true);\n        }\n        if ($this->strikethrough) {\n            $richtextRun->getFont()->setStrikethrough(true);\n        }\n        $this->stringData = '';\n    }\n\n    protected function rgbToColour($rgb) {\n        preg_match_all('/\\d+/', $rgb, $values);\n        foreach($values[0] as &$value) {\n            $value = str_pad(dechex($value), 2, '0', STR_PAD_LEFT);\n        }\n        return implode($values[0]);\n    }\n\n    protected function colourNameLookup($rgb) {\n        return self::$colourMap[$rgb];\n    }\n\n    protected function startFontTag($tag) {\n        foreach ($tag->attributes as $attribute) {\n            $attributeName = strtolower($attribute->name);\n            $attributeValue = $attribute->value;\n\n            if ($attributeName == 'color') {\n                if (preg_match('/rgb\\s*\\(/', $attributeValue)) {\n                    $this->$attributeName = $this->rgbToColour($attributeValue);\n                } elseif(strpos(trim($attributeValue), '#') === 0) {\n                    $this->$attributeName = ltrim($attributeValue, '#');\n                } else {\n                    $this->$attributeName = $this->colourNameLookup($attributeValue);\n                }\n            } else {\n                $this->$attributeName = $attributeValue;\n            }\n        }\n    }\n\n    protected function endFontTag() {\n        $this->face = $this->size = $this->color = null;\n    }\n\n    protected function startBoldTag() {\n        $this->bold = true;\n    }\n\n    protected function endBoldTag() {\n        $this->bold = false;\n    }\n\n    protected function startItalicTag() {\n        $this->italic = true;\n    }\n\n    protected function endItalicTag() {\n        $this->italic = false;\n    }\n\n    protected function startUnderlineTag() {\n        $this->underline = true;\n    }\n\n    protected function endUnderlineTag() {\n        $this->underline = false;\n    }\n\n    protected function startSubscriptTag() {\n        $this->subscript = true;\n    }\n\n    protected function endSubscriptTag() {\n        $this->subscript = false;\n    }\n\n    protected function startSuperscriptTag() {\n        $this->superscript = true;\n    }\n\n    protected function endSuperscriptTag() {\n        $this->superscript = false;\n    }\n\n    protected function startStrikethruTag() {\n        $this->strikethrough = true;\n    }\n\n    protected function endStrikethruTag() {\n        $this->strikethrough = false;\n    }\n\n    protected function breakTag() {\n        $this->stringData .= PHP_EOL;\n    }\n\n    protected function parseTextNode(DOMText $textNode) {\n        $domText = preg_replace('/\\s+/u', ' ', ltrim($textNode->nodeValue));\n        $this->stringData .= $domText;\n        $this->buildTextRun();\n    }\n\n    protected function handleCallback($element, $callbackTag, $callbacks) {\n        if (isset($callbacks[$callbackTag])) {\n            $elementHandler = $callbacks[$callbackTag];\n            if (method_exists($this, $elementHandler)) {\n                call_user_func(array($this, $elementHandler), $element);\n            }\n        }\n    }\n\n    protected function parseElementNode(DOMElement $element) {\n        $callbackTag = strtolower($element->nodeName);\n        $this->stack[] = $callbackTag;\n\n        $this->handleCallback($element, $callbackTag, $this->startTagCallbacks);\n\n        $this->parseElements($element);\n        $this->stringData .= ' ';\n        array_pop($this->stack);\n\n        $this->handleCallback($element, $callbackTag, $this->endTagCallbacks);\n    }\n\n    protected function parseElements(DOMNode $element) {\n        foreach ($element->childNodes as $child) {\n            if ($child instanceof DOMText) {\n                $this->parseTextNode($child);\n            } elseif ($child instanceof DOMElement) {\n                $this->parseElementNode($child);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/IComparable.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_IComparable\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\ninterface PHPExcel_IComparable\n{\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode();\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/IOFactory.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\tPHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n/**\n * PHPExcel_IOFactory\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_IOFactory\n{\n\t/**\n\t * Search locations\n\t *\n\t * @var\tarray\n\t * @access\tprivate\n\t * @static\n\t */\n\tprivate static $_searchLocations = array(\n\t\tarray( 'type' => 'IWriter', 'path' => 'PHPExcel/Writer/{0}.php', 'class' => 'PHPExcel_Writer_{0}' ),\n\t\tarray( 'type' => 'IReader', 'path' => 'PHPExcel/Reader/{0}.php', 'class' => 'PHPExcel_Reader_{0}' )\n\t);\n\n\t/**\n\t * Autoresolve classes\n\t *\n\t * @var\tarray\n\t * @access\tprivate\n\t * @static\n\t */\n\tprivate static $_autoResolveClasses = array(\n\t\t'Excel2007',\n\t\t'Excel5',\n\t\t'Excel2003XML',\n\t\t'OOCalc',\n\t\t'SYLK',\n\t\t'Gnumeric',\n\t\t'HTML',\n\t\t'CSV',\n\t);\n\n    /**\n     *\tPrivate constructor for PHPExcel_IOFactory\n     */\n    private function __construct() { }\n\n    /**\n     * Get search locations\n     *\n\t * @static\n\t * @access\tpublic\n     * @return\tarray\n     */\n\tpublic static function getSearchLocations() {\n\t\treturn self::$_searchLocations;\n\t}\t//\tfunction getSearchLocations()\n\n\t/**\n\t * Set search locations\n\t *\n\t * @static\n\t * @access\tpublic\n\t * @param\tarray $value\n\t * @throws\tPHPExcel_Reader_Exception\n\t */\n\tpublic static function setSearchLocations($value) {\n\t\tif (is_array($value)) {\n\t\t\tself::$_searchLocations = $value;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Reader_Exception('Invalid parameter passed.');\n\t\t}\n\t}\t//\tfunction setSearchLocations()\n\n\t/**\n\t * Add search location\n\t *\n\t * @static\n\t * @access\tpublic\n\t * @param\tstring $type\t\tExample: IWriter\n\t * @param\tstring $location\tExample: PHPExcel/Writer/{0}.php\n\t * @param\tstring $classname \tExample: PHPExcel_Writer_{0}\n\t */\n\tpublic static function addSearchLocation($type = '', $location = '', $classname = '') {\n\t\tself::$_searchLocations[] = array( 'type' => $type, 'path' => $location, 'class' => $classname );\n\t}\t//\tfunction addSearchLocation()\n\n\t/**\n\t * Create PHPExcel_Writer_IWriter\n\t *\n\t * @static\n\t * @access\tpublic\n\t * @param\tPHPExcel $phpExcel\n\t * @param\tstring  $writerType\tExample: Excel2007\n\t * @return\tPHPExcel_Writer_IWriter\n\t * @throws\tPHPExcel_Reader_Exception\n\t */\n\tpublic static function createWriter(PHPExcel $phpExcel, $writerType = '') {\n\t\t// Search type\n\t\t$searchType = 'IWriter';\n\n\t\t// Include class\n\t\tforeach (self::$_searchLocations as $searchLocation) {\n\t\t\tif ($searchLocation['type'] == $searchType) {\n\t\t\t\t$className = str_replace('{0}', $writerType, $searchLocation['class']);\n\n\t\t\t\t$instance = new $className($phpExcel);\n\t\t\t\tif ($instance !== NULL) {\n\t\t\t\t\treturn $instance;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Nothing found...\n\t\tthrow new PHPExcel_Reader_Exception(\"No $searchType found for type $writerType\");\n\t}\t//\tfunction createWriter()\n\n\t/**\n\t * Create PHPExcel_Reader_IReader\n\t *\n\t * @static\n\t * @access\tpublic\n\t * @param\tstring $readerType\tExample: Excel2007\n\t * @return\tPHPExcel_Reader_IReader\n\t * @throws\tPHPExcel_Reader_Exception\n\t */\n\tpublic static function createReader($readerType = '') {\n\t\t// Search type\n\t\t$searchType = 'IReader';\n\n\t\t// Include class\n\t\tforeach (self::$_searchLocations as $searchLocation) {\n\t\t\tif ($searchLocation['type'] == $searchType) {\n\t\t\t\t$className = str_replace('{0}', $readerType, $searchLocation['class']);\n\n\t\t\t\t$instance = new $className();\n\t\t\t\tif ($instance !== NULL) {\n\t\t\t\t\treturn $instance;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Nothing found...\n\t\tthrow new PHPExcel_Reader_Exception(\"No $searchType found for type $readerType\");\n\t}\t//\tfunction createReader()\n\n\t/**\n\t * Loads PHPExcel from file using automatic PHPExcel_Reader_IReader resolution\n\t *\n\t * @static\n\t * @access public\n\t * @param \tstring \t\t$pFilename\t\tThe name of the spreadsheet file\n\t * @return\tPHPExcel\n\t * @throws\tPHPExcel_Reader_Exception\n\t */\n\tpublic static function load($pFilename) {\n\t\t$reader = self::createReaderForFile($pFilename);\n\t\treturn $reader->load($pFilename);\n\t}\t//\tfunction load()\n\n\t/**\n\t * Identify file type using automatic PHPExcel_Reader_IReader resolution\n\t *\n\t * @static\n\t * @access public\n\t * @param \tstring \t\t$pFilename\t\tThe name of the spreadsheet file to identify\n\t * @return\tstring\n\t * @throws\tPHPExcel_Reader_Exception\n\t */\n\tpublic static function identify($pFilename) {\n\t\t$reader = self::createReaderForFile($pFilename);\n\t\t$className = get_class($reader);\n\t\t$classType = explode('_',$className);\n\t\tunset($reader);\n\t\treturn array_pop($classType);\n\t}\t//\tfunction identify()\n\n\t/**\n\t * Create PHPExcel_Reader_IReader for file using automatic PHPExcel_Reader_IReader resolution\n\t *\n\t * @static\n\t * @access\tpublic\n\t * @param \tstring \t\t$pFilename\t\tThe name of the spreadsheet file\n\t * @return\tPHPExcel_Reader_IReader\n\t * @throws\tPHPExcel_Reader_Exception\n\t */\n\tpublic static function createReaderForFile($pFilename) {\n\n\t\t// First, lucky guess by inspecting file extension\n\t\t$pathinfo = pathinfo($pFilename);\n\n\t\t$extensionType = NULL;\n\t\tif (isset($pathinfo['extension'])) {\n\t\t\tswitch (strtolower($pathinfo['extension'])) {\n\t\t\t\tcase 'xlsx':\t\t\t//\tExcel (OfficeOpenXML) Spreadsheet\n\t\t\t\tcase 'xlsm':\t\t\t//\tExcel (OfficeOpenXML) Macro Spreadsheet (macros will be discarded)\n\t\t\t\tcase 'xltx':\t\t\t//\tExcel (OfficeOpenXML) Template\n\t\t\t\tcase 'xltm':\t\t\t//\tExcel (OfficeOpenXML) Macro Template (macros will be discarded)\n\t\t\t\t\t$extensionType = 'Excel2007';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'xls':\t\t\t\t//\tExcel (BIFF) Spreadsheet\n\t\t\t\tcase 'xlt':\t\t\t\t//\tExcel (BIFF) Template\n\t\t\t\t\t$extensionType = 'Excel5';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'ods':\t\t\t\t//\tOpen/Libre Offic Calc\n\t\t\t\tcase 'ots':\t\t\t\t//\tOpen/Libre Offic Calc Template\n\t\t\t\t\t$extensionType = 'OOCalc';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'slk':\n\t\t\t\t\t$extensionType = 'SYLK';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'xml':\t\t\t\t//\tExcel 2003 SpreadSheetML\n\t\t\t\t\t$extensionType = 'Excel2003XML';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'gnumeric':\n\t\t\t\t\t$extensionType = 'Gnumeric';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'htm':\n\t\t\t\tcase 'html':\n\t\t\t\t\t$extensionType = 'HTML';\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'csv':\n\t\t\t\t\t// Do nothing\n\t\t\t\t\t// We must not try to use CSV reader since it loads\n\t\t\t\t\t// all files including Excel files etc.\n\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tif ($extensionType !== NULL) {\n\t\t\t\t$reader = self::createReader($extensionType);\n\t\t\t\t// Let's see if we are lucky\n\t\t\t\tif (isset($reader) && $reader->canRead($pFilename)) {\n\t\t\t\t\treturn $reader;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If we reach here then \"lucky guess\" didn't give any result\n\t\t// Try walking through all the options in self::$_autoResolveClasses\n\t\tforeach (self::$_autoResolveClasses as $autoResolveClass) {\n\t\t\t//\tIgnore our original guess, we know that won't work\n\t\t\tif ($autoResolveClass !== $extensionType) {\n\t\t\t\t$reader = self::createReader($autoResolveClass);\n\t\t\t\tif ($reader->canRead($pFilename)) {\n\t\t\t\t\treturn $reader;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow new PHPExcel_Reader_Exception('Unable to identify a reader for this file');\n\t}\t//\tfunction createReaderForFile()\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/NamedRange.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_NamedRange\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_NamedRange\n{\n\t/**\n\t * Range name\n\t *\n\t * @var string\n\t */\n\tprivate $_name;\n\n\t/**\n\t * Worksheet on which the named range can be resolved\n\t *\n\t * @var PHPExcel_Worksheet\n\t */\n\tprivate $_worksheet;\n\n\t/**\n\t * Range of the referenced cells\n\t *\n\t * @var string\n\t */\n\tprivate $_range;\n\n\t/**\n\t * Is the named range local? (i.e. can only be used on $this->_worksheet)\n\t *\n\t * @var bool\n\t */\n\tprivate $_localOnly;\n\n\t/**\n\t * Scope\n\t *\n\t * @var PHPExcel_Worksheet\n\t */\n\tprivate $_scope;\n\n    /**\n     * Create a new NamedRange\n     *\n     * @param string $pName\n     * @param PHPExcel_Worksheet $pWorksheet\n     * @param string $pRange\n     * @param bool $pLocalOnly\n     * @param PHPExcel_Worksheet|null $pScope\tScope. Only applies when $pLocalOnly = true. Null for global scope.\n     * @throws PHPExcel_Exception\n     */\n    public function __construct($pName = null, PHPExcel_Worksheet $pWorksheet, $pRange = 'A1', $pLocalOnly = false, $pScope = null)\n    {\n    \t// Validate data\n    \tif (($pName === NULL) || ($pWorksheet === NULL) || ($pRange === NULL)) {\n    \t\tthrow new PHPExcel_Exception('Parameters can not be null.');\n    \t}\n\n    \t// Set local members\n    \t$this->_name \t\t= $pName;\n    \t$this->_worksheet \t= $pWorksheet;\n    \t$this->_range \t\t= $pRange;\n    \t$this->_localOnly \t= $pLocalOnly;\n    \t$this->_scope \t\t= ($pLocalOnly == true) ?\n\t\t\t\t\t\t\t\t(($pScope == null) ? $pWorksheet : $pScope) : null;\n    }\n\n    /**\n     * Get name\n     *\n     * @return string\n     */\n    public function getName() {\n    \treturn $this->_name;\n    }\n\n    /**\n     * Set name\n     *\n     * @param string $value\n     * @return PHPExcel_NamedRange\n     */\n    public function setName($value = null) {\n    \tif ($value !== NULL) {\n    \t\t// Old title\n    \t\t$oldTitle = $this->_name;\n\n    \t\t// Re-attach\n    \t\tif ($this->_worksheet !== NULL) {\n    \t\t\t$this->_worksheet->getParent()->removeNamedRange($this->_name,$this->_worksheet);\n    \t\t}\n    \t\t$this->_name = $value;\n\n    \t\tif ($this->_worksheet !== NULL) {\n    \t\t\t$this->_worksheet->getParent()->addNamedRange($this);\n    \t\t}\n\n\t    \t// New title\n\t    \t$newTitle = $this->_name;\n\t    \tPHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_worksheet->getParent(), $oldTitle, $newTitle);\n    \t}\n    \treturn $this;\n    }\n\n    /**\n     * Get worksheet\n     *\n     * @return PHPExcel_Worksheet\n     */\n    public function getWorksheet() {\n    \treturn $this->_worksheet;\n    }\n\n    /**\n     * Set worksheet\n     *\n     * @param PHPExcel_Worksheet $value\n     * @return PHPExcel_NamedRange\n     */\n    public function setWorksheet(PHPExcel_Worksheet $value = null) {\n    \tif ($value !== NULL) {\n    \t\t$this->_worksheet = $value;\n    \t}\n    \treturn $this;\n    }\n\n    /**\n     * Get range\n     *\n     * @return string\n     */\n    public function getRange() {\n    \treturn $this->_range;\n    }\n\n    /**\n     * Set range\n     *\n     * @param string $value\n     * @return PHPExcel_NamedRange\n     */\n    public function setRange($value = null) {\n    \tif ($value !== NULL) {\n    \t\t$this->_range = $value;\n    \t}\n    \treturn $this;\n    }\n\n    /**\n     * Get localOnly\n     *\n     * @return bool\n     */\n    public function getLocalOnly() {\n    \treturn $this->_localOnly;\n    }\n\n    /**\n     * Set localOnly\n     *\n     * @param bool $value\n     * @return PHPExcel_NamedRange\n     */\n    public function setLocalOnly($value = false) {\n    \t$this->_localOnly = $value;\n    \t$this->_scope = $value ? $this->_worksheet : null;\n    \treturn $this;\n    }\n\n    /**\n     * Get scope\n     *\n     * @return PHPExcel_Worksheet|null\n     */\n    public function getScope() {\n    \treturn $this->_scope;\n    }\n\n    /**\n     * Set scope\n     *\n     * @param PHPExcel_Worksheet|null $value\n     * @return PHPExcel_NamedRange\n     */\n    public function setScope(PHPExcel_Worksheet $value = null) {\n    \t$this->_scope = $value;\n    \t$this->_localOnly = ($value == null) ? false : true;\n    \treturn $this;\n    }\n\n    /**\n     * Resolve a named range to a regular cell range\n     *\n     * @param string $pNamedRange Named range\n     * @param PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope\n     * @return PHPExcel_NamedRange\n     */\n    public static function resolveRange($pNamedRange = '', PHPExcel_Worksheet $pSheet) {\n\t\treturn $pSheet->getParent()->getNamedRange($pNamedRange, $pSheet);\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/Abstract.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Reader_Abstract\n *\n * @category\tPHPExcel\n * @package\tPHPExcel_Reader\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nabstract class PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader\n{\n\t/**\n\t * Read data only?\n\t * Identifies whether the Reader should only read data values for cells, and ignore any formatting information;\n\t *\t\tor whether it should read both data and formatting\n\t *\n\t * @var\tboolean\n\t */\n\tprotected $_readDataOnly = FALSE;\n\n\t/**\n\t * Read charts that are defined in the workbook?\n\t * Identifies whether the Reader should read the definitions for any charts that exist in the workbook;\n\t *\n\t * @var\tboolean\n\t */\n\tprotected $_includeCharts = FALSE;\n\n\t/**\n\t * Restrict which sheets should be loaded?\n\t * This property holds an array of worksheet names to be loaded. If null, then all worksheets will be loaded.\n\t *\n\t * @var array of string\n\t */\n\tprotected $_loadSheetsOnly = NULL;\n\n\t/**\n\t * PHPExcel_Reader_IReadFilter instance\n\t *\n\t * @var PHPExcel_Reader_IReadFilter\n\t */\n\tprotected $_readFilter = NULL;\n\n\tprotected $_fileHandle = NULL;\n\n\n\t/**\n\t * Read data only?\n\t *\t\tIf this is true, then the Reader will only read data values for cells, it will not read any formatting information.\n\t *\t\tIf false (the default) it will read data and formatting.\n\t *\n\t * @return\tboolean\n\t */\n\tpublic function getReadDataOnly() {\n\t\treturn $this->_readDataOnly;\n\t}\n\n\t/**\n\t * Set read data only\n\t *\t\tSet to true, to advise the Reader only to read data values for cells, and to ignore any formatting information.\n\t *\t\tSet to false (the default) to advise the Reader to read both data and formatting for cells.\n\t *\n\t * @param\tboolean\t$pValue\n\t *\n\t * @return\tPHPExcel_Reader_IReader\n\t */\n\tpublic function setReadDataOnly($pValue = FALSE) {\n\t\t$this->_readDataOnly = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Read charts in workbook?\n\t *\t\tIf this is true, then the Reader will include any charts that exist in the workbook.\n\t *      Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value.\n\t *\t\tIf false (the default) it will ignore any charts defined in the workbook file.\n\t *\n\t * @return\tboolean\n\t */\n\tpublic function getIncludeCharts() {\n\t\treturn $this->_includeCharts;\n\t}\n\n\t/**\n\t * Set read charts in workbook\n\t *\t\tSet to true, to advise the Reader to include any charts that exist in the workbook.\n\t *      Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value.\n\t *\t\tSet to false (the default) to discard charts.\n\t *\n\t * @param\tboolean\t$pValue\n\t *\n\t * @return\tPHPExcel_Reader_IReader\n\t */\n\tpublic function setIncludeCharts($pValue = FALSE) {\n\t\t$this->_includeCharts = (boolean) $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get which sheets to load\n\t * Returns either an array of worksheet names (the list of worksheets that should be loaded), or a null\n\t *\t\tindicating that all worksheets in the workbook should be loaded.\n\t *\n\t * @return mixed\n\t */\n\tpublic function getLoadSheetsOnly()\n\t{\n\t\treturn $this->_loadSheetsOnly;\n\t}\n\n\t/**\n\t * Set which sheets to load\n\t *\n\t * @param mixed $value\n\t *\t\tThis should be either an array of worksheet names to be loaded, or a string containing a single worksheet name.\n\t *\t\tIf NULL, then it tells the Reader to read all worksheets in the workbook\n\t *\n\t * @return PHPExcel_Reader_IReader\n\t */\n\tpublic function setLoadSheetsOnly($value = NULL)\n\t{\n        if ($value === NULL)\n            return $this->setLoadAllSheets();\n\n        $this->_loadSheetsOnly = is_array($value) ?\n\t\t\t$value : array($value);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Set all sheets to load\n\t *\t\tTells the Reader to load all worksheets from the workbook.\n\t *\n\t * @return PHPExcel_Reader_IReader\n\t */\n\tpublic function setLoadAllSheets()\n\t{\n\t\t$this->_loadSheetsOnly = NULL;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Read filter\n\t *\n\t * @return PHPExcel_Reader_IReadFilter\n\t */\n\tpublic function getReadFilter() {\n\t\treturn $this->_readFilter;\n\t}\n\n\t/**\n\t * Set read filter\n\t *\n\t * @param PHPExcel_Reader_IReadFilter $pValue\n\t * @return PHPExcel_Reader_IReader\n\t */\n\tpublic function setReadFilter(PHPExcel_Reader_IReadFilter $pValue) {\n\t\t$this->_readFilter = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Open file for reading\n\t *\n\t * @param string $pFilename\n\t * @throws\tPHPExcel_Reader_Exception\n\t * @return resource\n\t */\n\tprotected function _openFile($pFilename)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename) || !is_readable($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n\t\t// Open file\n\t\t$this->_fileHandle = fopen($pFilename, 'r');\n\t\tif ($this->_fileHandle === FALSE) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open file \" . $pFilename . \" for reading.\");\n\t\t}\n\t}\n\n\t/**\n\t * Can the current PHPExcel_Reader_IReader read the file?\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @return boolean\n\t * @throws PHPExcel_Reader_Exception\n\t */\n\tpublic function canRead($pFilename)\n\t{\n\t\t// Check if file exists\n\t\ttry {\n\t\t\t$this->_openFile($pFilename);\n\t\t} catch (Exception $e) {\n\t\t\treturn FALSE;\n\t\t}\n\n\t\t$readable = $this->_isValidFormat();\n\t\tfclose ($this->_fileHandle);\n\t\treturn $readable;\n\t}\n\n\t/**\n\t * Scan theXML for use of <!ENTITY to prevent XXE/XEE attacks\n\t *\n\t * @param \tstring \t\t$xml\n\t * @throws PHPExcel_Reader_Exception\n\t */\n\tpublic function securityScan($xml)\n\t{\n        $pattern = '/\\\\0?' . implode('\\\\0?', str_split('<!DOCTYPE')) . '\\\\0?/';\n        if (preg_match($pattern, $xml)) { \n            throw new PHPExcel_Reader_Exception('Detected use of ENTITY in XML, spreadsheet file load() aborted to prevent XXE/XEE attacks');\n        }\n        return $xml;\n    }\n\n\t/**\n\t * Scan theXML for use of <!ENTITY to prevent XXE/XEE attacks\n\t *\n\t * @param \tstring \t\t$filestream\n\t * @throws PHPExcel_Reader_Exception\n\t */\n\tpublic function securityScanFile($filestream)\n\t{\n        return $this->securityScan(file_get_contents($filestream));\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/CSV.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n/**\n * PHPExcel_Reader_CSV\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_CSV extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader\n{\n\t/**\n\t * Input encoding\n\t *\n\t * @access\tprivate\n\t * @var\tstring\n\t */\n\tprivate $_inputEncoding\t= 'UTF-8';\n\n\t/**\n\t * Delimiter\n\t *\n\t * @access\tprivate\n\t * @var string\n\t */\n\tprivate $_delimiter\t\t= ',';\n\n\t/**\n\t * Enclosure\n\t *\n\t * @access\tprivate\n\t * @var\tstring\n\t */\n\tprivate $_enclosure\t\t= '\"';\n\n\t/**\n\t * Sheet index to read\n\t *\n\t * @access\tprivate\n\t * @var\tint\n\t */\n\tprivate $_sheetIndex\t= 0;\n\n\t/**\n\t * Load rows contiguously\n\t *\n\t * @access\tprivate\n\t * @var\tint\n\t */\n\tprivate $_contiguous\t= false;\n\n\t/**\n\t * Row counter for loading rows contiguously\n\t *\n\t * @var\tint\n\t */\n\tprivate $_contiguousRow\t= -1;\n\n\n\t/**\n\t * Create a new PHPExcel_Reader_CSV\n\t */\n\tpublic function __construct() {\n\t\t$this->_readFilter\t\t= new PHPExcel_Reader_DefaultReadFilter();\n\t}\n\n\t/**\n\t * Validate that the current file is a CSV file\n\t *\n\t * @return boolean\n\t */\n\tprotected function _isValidFormat()\n\t{\n\t\treturn TRUE;\n\t}\n\n\t/**\n\t * Set input encoding\n\t *\n\t * @param string $pValue Input encoding\n\t */\n\tpublic function setInputEncoding($pValue = 'UTF-8')\n\t{\n\t\t$this->_inputEncoding = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get input encoding\n\t *\n\t * @return string\n\t */\n\tpublic function getInputEncoding()\n\t{\n\t\treturn $this->_inputEncoding;\n\t}\n\n\t/**\n\t * Move filepointer past any BOM marker\n\t *\n\t */\n\tprotected function _skipBOM()\n\t{\n\t\trewind($this->_fileHandle);\n\n\t\tswitch ($this->_inputEncoding) {\n\t\t\tcase 'UTF-8':\n\t\t\t\tfgets($this->_fileHandle, 4) == \"\\xEF\\xBB\\xBF\" ?\n\t\t\t\t\tfseek($this->_fileHandle, 3) : fseek($this->_fileHandle, 0);\n\t\t\t\tbreak;\n\t\t\tcase 'UTF-16LE':\n\t\t\t\tfgets($this->_fileHandle, 3) == \"\\xFF\\xFE\" ?\n\t\t\t\t\tfseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0);\n\t\t\t\tbreak;\n\t\t\tcase 'UTF-16BE':\n\t\t\t\tfgets($this->_fileHandle, 3) == \"\\xFE\\xFF\" ?\n\t\t\t\t\tfseek($this->_fileHandle, 2) : fseek($this->_fileHandle, 0);\n\t\t\t\tbreak;\n\t\t\tcase 'UTF-32LE':\n\t\t\t\tfgets($this->_fileHandle, 5) == \"\\xFF\\xFE\\x00\\x00\" ?\n\t\t\t\t\tfseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0);\n\t\t\t\tbreak;\n\t\t\tcase 'UTF-32BE':\n\t\t\t\tfgets($this->_fileHandle, 5) == \"\\x00\\x00\\xFE\\xFF\" ?\n\t\t\t\t\tfseek($this->_fileHandle, 4) : fseek($this->_fileHandle, 0);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @throws\tPHPExcel_Reader_Exception\n\t */\n\tpublic function listWorksheetInfo($pFilename)\n\t{\n\t\t// Open file\n\t\t$this->_openFile($pFilename);\n\t\tif (!$this->_isValidFormat()) {\n\t\t\tfclose ($this->_fileHandle);\n\t\t\tthrow new PHPExcel_Reader_Exception($pFilename . \" is an Invalid Spreadsheet file.\");\n\t\t}\n\t\t$fileHandle = $this->_fileHandle;\n\n\t\t// Skip BOM, if any\n\t\t$this->_skipBOM();\n\n\t\t$escapeEnclosures = array( \"\\\\\" . $this->_enclosure, $this->_enclosure . $this->_enclosure );\n\n\t\t$worksheetInfo = array();\n\t\t$worksheetInfo[0]['worksheetName'] = 'Worksheet';\n\t\t$worksheetInfo[0]['lastColumnLetter'] = 'A';\n\t\t$worksheetInfo[0]['lastColumnIndex'] = 0;\n\t\t$worksheetInfo[0]['totalRows'] = 0;\n\t\t$worksheetInfo[0]['totalColumns'] = 0;\n\n\t\t// Loop through each line of the file in turn\n\t\twhile (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) {\n\t\t\t$worksheetInfo[0]['totalRows']++;\n\t\t\t$worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1);\n\t\t}\n\n\t\t$worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']);\n\t\t$worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1;\n\n\t\t// Close file\n\t\tfclose($fileHandle);\n\n\t\treturn $worksheetInfo;\n\t}\n\n\t/**\n\t * Loads PHPExcel from file\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @return PHPExcel\n\t * @throws PHPExcel_Reader_Exception\n\t */\n\tpublic function load($pFilename)\n\t{\n\t\t// Create new PHPExcel\n\t\t$objPHPExcel = new PHPExcel();\n\n\t\t// Load into this instance\n\t\treturn $this->loadIntoExisting($pFilename, $objPHPExcel);\n\t}\n\n\t/**\n\t * Loads PHPExcel from file into PHPExcel instance\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @param\tPHPExcel\t$objPHPExcel\n\t * @return \tPHPExcel\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)\n\t{\n\t\t$lineEnding = ini_get('auto_detect_line_endings');\n\t\tini_set('auto_detect_line_endings', true);\n\n\t\t// Open file\n\t\t$this->_openFile($pFilename);\n\t\tif (!$this->_isValidFormat()) {\n\t\t\tfclose ($this->_fileHandle);\n\t\t\tthrow new PHPExcel_Reader_Exception($pFilename . \" is an Invalid Spreadsheet file.\");\n\t\t}\n\t\t$fileHandle = $this->_fileHandle;\n\n\t\t// Skip BOM, if any\n\t\t$this->_skipBOM();\n\n\t\t// Create new PHPExcel object\n\t\twhile ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) {\n\t\t\t$objPHPExcel->createSheet();\n\t\t}\n\t\t$sheet = $objPHPExcel->setActiveSheetIndex($this->_sheetIndex);\n\n\t\t$escapeEnclosures = array( \"\\\\\" . $this->_enclosure,\n\t\t\t\t\t\t\t\t   $this->_enclosure . $this->_enclosure\n\t\t\t\t\t\t\t\t );\n\n\t\t// Set our starting row based on whether we're in contiguous mode or not\n\t\t$currentRow = 1;\n\t\tif ($this->_contiguous) {\n\t\t\t$currentRow = ($this->_contiguousRow == -1) ? $sheet->getHighestRow(): $this->_contiguousRow;\n\t\t}\n\n\t\t// Loop through each line of the file in turn\n\t\twhile (($rowData = fgetcsv($fileHandle, 0, $this->_delimiter, $this->_enclosure)) !== FALSE) {\n\t\t\t$columnLetter = 'A';\n\t\t\tforeach($rowData as $rowDatum) {\n\t\t\t\tif ($rowDatum != '' && $this->_readFilter->readCell($columnLetter, $currentRow)) {\n\t\t\t\t\t// Unescape enclosures\n\t\t\t\t\t$rowDatum = str_replace($escapeEnclosures, $this->_enclosure, $rowDatum);\n\n\t\t\t\t\t// Convert encoding if necessary\n\t\t\t\t\tif ($this->_inputEncoding !== 'UTF-8') {\n\t\t\t\t\t\t$rowDatum = PHPExcel_Shared_String::ConvertEncoding($rowDatum, 'UTF-8', $this->_inputEncoding);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Set cell value\n\t\t\t\t\t$sheet->getCell($columnLetter . $currentRow)->setValue($rowDatum);\n\t\t\t\t}\n\t\t\t\t++$columnLetter;\n\t\t\t}\n\t\t\t++$currentRow;\n\t\t}\n\n\t\t// Close file\n\t\tfclose($fileHandle);\n\n\t\tif ($this->_contiguous) {\n\t\t\t$this->_contiguousRow = $currentRow;\n\t\t}\n\n\t\tini_set('auto_detect_line_endings', $lineEnding);\n\n\t\t// Return\n\t\treturn $objPHPExcel;\n\t}\n\n\t/**\n\t * Get delimiter\n\t *\n\t * @return string\n\t */\n\tpublic function getDelimiter() {\n\t\treturn $this->_delimiter;\n\t}\n\n\t/**\n\t * Set delimiter\n\t *\n\t * @param\tstring\t$pValue\t\tDelimiter, defaults to ,\n\t * @return\tPHPExcel_Reader_CSV\n\t */\n\tpublic function setDelimiter($pValue = ',') {\n\t\t$this->_delimiter = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get enclosure\n\t *\n\t * @return string\n\t */\n\tpublic function getEnclosure() {\n\t\treturn $this->_enclosure;\n\t}\n\n\t/**\n\t * Set enclosure\n\t *\n\t * @param\tstring\t$pValue\t\tEnclosure, defaults to \"\n\t * @return PHPExcel_Reader_CSV\n\t */\n\tpublic function setEnclosure($pValue = '\"') {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = '\"';\n\t\t}\n\t\t$this->_enclosure = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get sheet index\n\t *\n\t * @return integer\n\t */\n\tpublic function getSheetIndex() {\n\t\treturn $this->_sheetIndex;\n\t}\n\n\t/**\n\t * Set sheet index\n\t *\n\t * @param\tinteger\t\t$pValue\t\tSheet index\n\t * @return PHPExcel_Reader_CSV\n\t */\n\tpublic function setSheetIndex($pValue = 0) {\n\t\t$this->_sheetIndex = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Set Contiguous\n\t *\n\t * @param boolean $contiguous\n\t */\n\tpublic function setContiguous($contiguous = FALSE)\n\t{\n\t\t$this->_contiguous = (bool) $contiguous;\n\t\tif (!$contiguous) {\n\t\t\t$this->_contiguousRow = -1;\n\t\t}\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Contiguous\n\t *\n\t * @return boolean\n\t */\n\tpublic function getContiguous() {\n\t\treturn $this->_contiguous;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/DefaultReadFilter.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n/**\n * PHPExcel_Reader_DefaultReadFilter\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_DefaultReadFilter implements PHPExcel_Reader_IReadFilter\n{\n\t/**\n\t * Should this cell be read?\n\t *\n\t * @param \t$column\t\tString column index\n\t * @param \t$row\t\t\tRow index\n\t * @param\t$worksheetName\tOptional worksheet name\n\t * @return\tboolean\n\t */\n\tpublic function readCell($column, $row, $worksheetName = '') {\n\t\treturn true;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/Excel2003XML.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n/**\n * PHPExcel_Reader_Excel2003XML\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_Excel2003XML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader\n{\n\t/**\n\t * Formats\n\t *\n\t * @var array\n\t */\n\tprotected $_styles = array();\n\n\t/**\n\t * Character set used in the file\n\t *\n\t * @var string\n\t */\n\tprotected $_charSet = 'UTF-8';\n\n\n\t/**\n\t * Create a new PHPExcel_Reader_Excel2003XML\n\t */\n\tpublic function __construct() {\n\t\t$this->_readFilter \t= new PHPExcel_Reader_DefaultReadFilter();\n\t}\n\n\n\t/**\n\t * Can the current PHPExcel_Reader_IReader read the file?\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @return \tboolean\n\t * @throws PHPExcel_Reader_Exception\n\t */\n\tpublic function canRead($pFilename)\n\t{\n\n\t\t//\tOffice\t\t\t\t\txmlns:o=\"urn:schemas-microsoft-com:office:office\"\n\t\t//\tExcel\t\t\t\t\txmlns:x=\"urn:schemas-microsoft-com:office:excel\"\n\t\t//\tXML Spreadsheet\t\t\txmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"\n\t\t//\tSpreadsheet component\txmlns:c=\"urn:schemas-microsoft-com:office:component:spreadsheet\"\n\t\t//\tXML schema \t\t\t\txmlns:s=\"uuid:BDC6E3F0-6DA3-11d1-A2A3-00AA00C14882\"\n\t\t//\tXML data type\t\t\txmlns:dt=\"uuid:C2F41010-65B3-11d1-A29F-00AA00C14882\"\n\t\t//\tMS-persist recordset\txmlns:rs=\"urn:schemas-microsoft-com:rowset\"\n\t\t//\tRowset\t\t\t\t\txmlns:z=\"#RowsetSchema\"\n\t\t//\n\n\t\t$signature = array(\n\t\t\t\t'<?xml version=\"1.0\"',\n\t\t\t\t'<?mso-application progid=\"Excel.Sheet\"?>'\n\t\t\t);\n\n\t\t// Open file\n\t\t$this->_openFile($pFilename);\n\t\t$fileHandle = $this->_fileHandle;\n\t\t\n\t\t// Read sample data (first 2 KB will do)\n\t\t$data = fread($fileHandle, 2048);\n\t\tfclose($fileHandle);\n\n\t\t$valid = true;\n\t\tforeach($signature as $match) {\n\t\t\t// every part of the signature must be present\n\t\t\tif (strpos($data, $match) === false) {\n\t\t\t\t$valid = false;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t//\tRetrieve charset encoding\n\t\tif(preg_match('/<?xml.*encoding=[\\'\"](.*?)[\\'\"].*?>/um',$data,$matches)) {\n\t\t\t$this->_charSet = strtoupper($matches[1]);\n\t\t}\n//\t\techo 'Character Set is ',$this->_charSet,'<br />';\n\n\t\treturn $valid;\n\t}\n\n\n\t/**\n\t * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function listWorksheetNames($pFilename)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\t\tif (!$this->canRead($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception($pFilename . \" is an Invalid Spreadsheet file.\");\n\t\t}\n\n\t\t$worksheetNames = array();\n\n\t\t$xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t$namespaces = $xml->getNamespaces(true);\n\n\t\t$xml_ss = $xml->children($namespaces['ss']);\n\t\tforeach($xml_ss->Worksheet as $worksheet) {\n\t\t\t$worksheet_ss = $worksheet->attributes($namespaces['ss']);\n\t\t\t$worksheetNames[] = self::_convertStringEncoding((string) $worksheet_ss['Name'],$this->_charSet);\n\t\t}\n\n\t\treturn $worksheetNames;\n\t}\n\n\n\t/**\n\t * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)\n\t *\n\t * @param   string     $pFilename\n\t * @throws   PHPExcel_Reader_Exception\n\t */\n\tpublic function listWorksheetInfo($pFilename)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n\t\t$worksheetInfo = array();\n\n\t\t$xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t$namespaces = $xml->getNamespaces(true);\n\n\t\t$worksheetID = 1;\n\t\t$xml_ss = $xml->children($namespaces['ss']);\n\t\tforeach($xml_ss->Worksheet as $worksheet) {\n\t\t\t$worksheet_ss = $worksheet->attributes($namespaces['ss']);\n\n\t\t\t$tmpInfo = array();\n\t\t\t$tmpInfo['worksheetName'] = '';\n\t\t\t$tmpInfo['lastColumnLetter'] = 'A';\n\t\t\t$tmpInfo['lastColumnIndex'] = 0;\n\t\t\t$tmpInfo['totalRows'] = 0;\n\t\t\t$tmpInfo['totalColumns'] = 0;\n\n\t\t\tif (isset($worksheet_ss['Name'])) {\n\t\t\t\t$tmpInfo['worksheetName'] = (string) $worksheet_ss['Name'];\n\t\t\t} else {\n\t\t\t\t$tmpInfo['worksheetName'] = \"Worksheet_{$worksheetID}\";\n\t\t\t}\n\n\t\t\tif (isset($worksheet->Table->Row)) {\n\t\t\t\t$rowIndex = 0;\n\n\t\t\t\tforeach($worksheet->Table->Row as $rowData) {\n\t\t\t\t\t$columnIndex = 0;\n\t\t\t\t\t$rowHasData = false;\n\n\t\t\t\t\tforeach($rowData->Cell as $cell) {\n\t\t\t\t\t\tif (isset($cell->Data)) {\n\t\t\t\t\t\t\t$tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex);\n\t\t\t\t\t\t\t$rowHasData = true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t++$columnIndex;\n\t\t\t\t\t}\n\n\t\t\t\t\t++$rowIndex;\n\n\t\t\t\t\tif ($rowHasData) {\n\t\t\t\t\t\t$tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);\n\t\t\t$tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;\n\n\t\t\t$worksheetInfo[] = $tmpInfo;\n\t\t\t++$worksheetID;\n\t\t}\n\n\t\treturn $worksheetInfo;\n\t}\n\n\n    /**\n\t * Loads PHPExcel from file\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @return \tPHPExcel\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function load($pFilename)\n\t{\n\t\t// Create new PHPExcel\n\t\t$objPHPExcel = new PHPExcel();\n        $objPHPExcel->removeSheetByIndex(0);\n\n\t\t// Load into this instance\n\t\treturn $this->loadIntoExisting($pFilename, $objPHPExcel);\n\t}\n\n\n\tprotected static function identifyFixedStyleValue($styleList,&$styleAttributeValue) {\n\t\t$styleAttributeValue = strtolower($styleAttributeValue);\n\t\tforeach($styleList as $style) {\n\t\t\tif ($styleAttributeValue == strtolower($style)) {\n\t\t\t\t$styleAttributeValue = $style;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\n \t/**\n \t * pixel units to excel width units(units of 1/256th of a character width)\n \t * @param pxs\n \t * @return\n \t */\n \tprotected static function _pixel2WidthUnits($pxs) {\n\t\t$UNIT_OFFSET_MAP = array(0, 36, 73, 109, 146, 182, 219);\n\n\t\t$widthUnits = 256 * ($pxs / 7);\n\t\t$widthUnits += $UNIT_OFFSET_MAP[($pxs % 7)];\n\t\treturn $widthUnits;\n\t}\n\n\n\t/**\n\t * excel width units(units of 1/256th of a character width) to pixel units\n\t * @param widthUnits\n\t * @return\n\t */\n\tprotected static function _widthUnits2Pixel($widthUnits) {\n\t\t$pixels = ($widthUnits / 256) * 7;\n\t\t$offsetWidthUnits = $widthUnits % 256;\n\t\t$pixels += round($offsetWidthUnits / (256 / 7));\n\t\treturn $pixels;\n\t}\n\n\n\tprotected static function _hex2str($hex) {\n\t\treturn chr(hexdec($hex[1]));\n\t}\n\n\n\t/**\n\t * Loads PHPExcel from file into PHPExcel instance\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @param\tPHPExcel\t$objPHPExcel\n\t * @return \tPHPExcel\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)\n\t{\n\t\t$fromFormats\t= array('\\-',\t'\\ ');\n\t\t$toFormats\t\t= array('-',\t' ');\n\n\t\t$underlineStyles = array (\n\t\t\t\tPHPExcel_Style_Font::UNDERLINE_NONE,\n\t\t\t\tPHPExcel_Style_Font::UNDERLINE_DOUBLE,\n\t\t\t\tPHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING,\n\t\t\t\tPHPExcel_Style_Font::UNDERLINE_SINGLE,\n\t\t\t\tPHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING\n\t\t\t);\n\t\t$verticalAlignmentStyles = array (\n\t\t\t\tPHPExcel_Style_Alignment::VERTICAL_BOTTOM,\n\t\t\t\tPHPExcel_Style_Alignment::VERTICAL_TOP,\n\t\t\t\tPHPExcel_Style_Alignment::VERTICAL_CENTER,\n\t\t\t\tPHPExcel_Style_Alignment::VERTICAL_JUSTIFY\n\t\t\t);\n\t\t$horizontalAlignmentStyles = array (\n\t\t\t\tPHPExcel_Style_Alignment::HORIZONTAL_GENERAL,\n\t\t\t\tPHPExcel_Style_Alignment::HORIZONTAL_LEFT,\n\t\t\t\tPHPExcel_Style_Alignment::HORIZONTAL_RIGHT,\n\t\t\t\tPHPExcel_Style_Alignment::HORIZONTAL_CENTER,\n\t\t\t\tPHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS,\n\t\t\t\tPHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY\n\t\t\t);\n\n\t\t$timezoneObj = new DateTimeZone('Europe/London');\n\t\t$GMT = new DateTimeZone('UTC');\n\n\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n\t\tif (!$this->canRead($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception($pFilename . \" is an Invalid Spreadsheet file.\");\n\t\t}\n\n\t\t$xml = simplexml_load_string($this->securityScan(file_get_contents($pFilename)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t$namespaces = $xml->getNamespaces(true);\n\n\t\t$docProps = $objPHPExcel->getProperties();\n\t\tif (isset($xml->DocumentProperties[0])) {\n\t\t\tforeach($xml->DocumentProperties[0] as $propertyName => $propertyValue) {\n\t\t\t\tswitch ($propertyName) {\n\t\t\t\t\tcase 'Title' :\n\t\t\t\t\t\t\t$docProps->setTitle(self::_convertStringEncoding($propertyValue,$this->_charSet));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Subject' :\n\t\t\t\t\t\t\t$docProps->setSubject(self::_convertStringEncoding($propertyValue,$this->_charSet));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Author' :\n\t\t\t\t\t\t\t$docProps->setCreator(self::_convertStringEncoding($propertyValue,$this->_charSet));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Created' :\n\t\t\t\t\t\t\t$creationDate = strtotime($propertyValue);\n\t\t\t\t\t\t\t$docProps->setCreated($creationDate);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'LastAuthor' :\n\t\t\t\t\t\t\t$docProps->setLastModifiedBy(self::_convertStringEncoding($propertyValue,$this->_charSet));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'LastSaved' :\n\t\t\t\t\t\t\t$lastSaveDate = strtotime($propertyValue);\n\t\t\t\t\t\t\t$docProps->setModified($lastSaveDate);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Company' :\n\t\t\t\t\t\t\t$docProps->setCompany(self::_convertStringEncoding($propertyValue,$this->_charSet));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Category' :\n\t\t\t\t\t\t\t$docProps->setCategory(self::_convertStringEncoding($propertyValue,$this->_charSet));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Manager' :\n\t\t\t\t\t\t\t$docProps->setManager(self::_convertStringEncoding($propertyValue,$this->_charSet));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Keywords' :\n\t\t\t\t\t\t\t$docProps->setKeywords(self::_convertStringEncoding($propertyValue,$this->_charSet));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Description' :\n\t\t\t\t\t\t\t$docProps->setDescription(self::_convertStringEncoding($propertyValue,$this->_charSet));\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif (isset($xml->CustomDocumentProperties)) {\n\t\t\tforeach($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) {\n\t\t\t\t$propertyAttributes = $propertyValue->attributes($namespaces['dt']);\n\t\t\t\t$propertyName = preg_replace_callback('/_x([0-9a-z]{4})_/','PHPExcel_Reader_Excel2003XML::_hex2str',$propertyName);\n\t\t\t\t$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_UNKNOWN;\n\t\t\t\tswitch((string) $propertyAttributes) {\n\t\t\t\t\tcase 'string' :\n\t\t\t\t\t\t$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING;\n\t\t\t\t\t\t$propertyValue = trim($propertyValue);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'boolean' :\n\t\t\t\t\t\t$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN;\n\t\t\t\t\t\t$propertyValue = (bool) $propertyValue;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'integer' :\n\t\t\t\t\t\t$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_INTEGER;\n\t\t\t\t\t\t$propertyValue = intval($propertyValue);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'float' :\n\t\t\t\t\t\t$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT;\n\t\t\t\t\t\t$propertyValue = floatval($propertyValue);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'dateTime.tz' :\n\t\t\t\t\t\t$propertyType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE;\n\t\t\t\t\t\t$propertyValue = strtotime(trim($propertyValue));\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t$docProps->setCustomProperty($propertyName,$propertyValue,$propertyType);\n\t\t\t}\n\t\t}\n\n\t\tforeach($xml->Styles[0] as $style) {\n\t\t\t$style_ss = $style->attributes($namespaces['ss']);\n\t\t\t$styleID = (string) $style_ss['ID'];\n//\t\t\techo 'Style ID = '.$styleID.'<br />';\n\t\t\tif ($styleID == 'Default') {\n\t\t\t\t$this->_styles['Default'] = array();\n\t\t\t} else {\n\t\t\t\t$this->_styles[$styleID] = $this->_styles['Default'];\n\t\t\t}\n\t\t\tforeach ($style as $styleType => $styleData) {\n\t\t\t\t$styleAttributes = $styleData->attributes($namespaces['ss']);\n//\t\t\t\techo $styleType.'<br />';\n\t\t\t\tswitch ($styleType) {\n\t\t\t\t\tcase 'Alignment' :\n\t\t\t\t\t\t\tforeach($styleAttributes as $styleAttributeKey => $styleAttributeValue) {\n//\t\t\t\t\t\t\t\techo $styleAttributeKey.' = '.$styleAttributeValue.'<br />';\n\t\t\t\t\t\t\t\t$styleAttributeValue = (string) $styleAttributeValue;\n\t\t\t\t\t\t\t\tswitch ($styleAttributeKey) {\n\t\t\t\t\t\t\t\t\tcase 'Vertical' :\n\t\t\t\t\t\t\t\t\t\t\tif (self::identifyFixedStyleValue($verticalAlignmentStyles,$styleAttributeValue)) {\n\t\t\t\t\t\t\t\t\t\t\t\t$this->_styles[$styleID]['alignment']['vertical'] = $styleAttributeValue;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'Horizontal' :\n\t\t\t\t\t\t\t\t\t\t\tif (self::identifyFixedStyleValue($horizontalAlignmentStyles,$styleAttributeValue)) {\n\t\t\t\t\t\t\t\t\t\t\t\t$this->_styles[$styleID]['alignment']['horizontal'] = $styleAttributeValue;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'WrapText' :\n\t\t\t\t\t\t\t\t\t\t\t$this->_styles[$styleID]['alignment']['wrap'] = true;\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Borders' :\n\t\t\t\t\t\t\tforeach($styleData->Border as $borderStyle) {\n\t\t\t\t\t\t\t\t$borderAttributes = $borderStyle->attributes($namespaces['ss']);\n\t\t\t\t\t\t\t\t$thisBorder = array();\n\t\t\t\t\t\t\t\tforeach($borderAttributes as $borderStyleKey => $borderStyleValue) {\n//\t\t\t\t\t\t\t\t\techo $borderStyleKey.' = '.$borderStyleValue.'<br />';\n\t\t\t\t\t\t\t\t\tswitch ($borderStyleKey) {\n\t\t\t\t\t\t\t\t\t\tcase 'LineStyle' :\n\t\t\t\t\t\t\t\t\t\t\t\t$thisBorder['style'] = PHPExcel_Style_Border::BORDER_MEDIUM;\n//\t\t\t\t\t\t\t\t\t\t\t\t$thisBorder['style'] = $borderStyleValue;\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tcase 'Weight' :\n//\t\t\t\t\t\t\t\t\t\t\t\t$thisBorder['style'] = $borderStyleValue;\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tcase 'Position' :\n\t\t\t\t\t\t\t\t\t\t\t\t$borderPosition = strtolower($borderStyleValue);\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tcase 'Color' :\n\t\t\t\t\t\t\t\t\t\t\t\t$borderColour = substr($borderStyleValue,1);\n\t\t\t\t\t\t\t\t\t\t\t\t$thisBorder['color']['rgb'] = $borderColour;\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (!empty($thisBorder)) {\n\t\t\t\t\t\t\t\t\tif (($borderPosition == 'left') || ($borderPosition == 'right') || ($borderPosition == 'top') || ($borderPosition == 'bottom')) {\n\t\t\t\t\t\t\t\t\t\t$this->_styles[$styleID]['borders'][$borderPosition] = $thisBorder;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Font' :\n\t\t\t\t\t\t\tforeach($styleAttributes as $styleAttributeKey => $styleAttributeValue) {\n//\t\t\t\t\t\t\t\techo $styleAttributeKey.' = '.$styleAttributeValue.'<br />';\n\t\t\t\t\t\t\t\t$styleAttributeValue = (string) $styleAttributeValue;\n\t\t\t\t\t\t\t\tswitch ($styleAttributeKey) {\n\t\t\t\t\t\t\t\t\tcase 'FontName' :\n\t\t\t\t\t\t\t\t\t\t\t$this->_styles[$styleID]['font']['name'] = $styleAttributeValue;\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'Size' :\n\t\t\t\t\t\t\t\t\t\t\t$this->_styles[$styleID]['font']['size'] = $styleAttributeValue;\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'Color' :\n\t\t\t\t\t\t\t\t\t\t\t$this->_styles[$styleID]['font']['color']['rgb'] = substr($styleAttributeValue,1);\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'Bold' :\n\t\t\t\t\t\t\t\t\t\t\t$this->_styles[$styleID]['font']['bold'] = true;\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'Italic' :\n\t\t\t\t\t\t\t\t\t\t\t$this->_styles[$styleID]['font']['italic'] = true;\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'Underline' :\n\t\t\t\t\t\t\t\t\t\t\tif (self::identifyFixedStyleValue($underlineStyles,$styleAttributeValue)) {\n\t\t\t\t\t\t\t\t\t\t\t\t$this->_styles[$styleID]['font']['underline'] = $styleAttributeValue;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Interior' :\n\t\t\t\t\t\t\tforeach($styleAttributes as $styleAttributeKey => $styleAttributeValue) {\n//\t\t\t\t\t\t\t\techo $styleAttributeKey.' = '.$styleAttributeValue.'<br />';\n\t\t\t\t\t\t\t\tswitch ($styleAttributeKey) {\n\t\t\t\t\t\t\t\t\tcase 'Color' :\n\t\t\t\t\t\t\t\t\t\t\t$this->_styles[$styleID]['fill']['color']['rgb'] = substr($styleAttributeValue,1);\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'NumberFormat' :\n\t\t\t\t\t\t\tforeach($styleAttributes as $styleAttributeKey => $styleAttributeValue) {\n//\t\t\t\t\t\t\t\techo $styleAttributeKey.' = '.$styleAttributeValue.'<br />';\n\t\t\t\t\t\t\t\t$styleAttributeValue = str_replace($fromFormats,$toFormats,$styleAttributeValue);\n\t\t\t\t\t\t\t\tswitch ($styleAttributeValue) {\n\t\t\t\t\t\t\t\t\tcase 'Short Date' :\n\t\t\t\t\t\t\t\t\t\t\t$styleAttributeValue = 'dd/mm/yyyy';\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ($styleAttributeValue > '') {\n\t\t\t\t\t\t\t\t\t$this->_styles[$styleID]['numberformat']['code'] = $styleAttributeValue;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'Protection' :\n\t\t\t\t\t\t\tforeach($styleAttributes as $styleAttributeKey => $styleAttributeValue) {\n//\t\t\t\t\t\t\t\techo $styleAttributeKey.' = '.$styleAttributeValue.'<br />';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n//\t\t\tprint_r($this->_styles[$styleID]);\n//\t\t\techo '<hr />';\n\t\t}\n//\t\techo '<hr />';\n\n\t\t$worksheetID = 0;\n\t\t$xml_ss = $xml->children($namespaces['ss']);\n\n\t\tforeach($xml_ss->Worksheet as $worksheet) {\n\t\t\t$worksheet_ss = $worksheet->attributes($namespaces['ss']);\n\n\t\t\tif ((isset($this->_loadSheetsOnly)) && (isset($worksheet_ss['Name'])) &&\n\t\t\t\t(!in_array($worksheet_ss['Name'], $this->_loadSheetsOnly))) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n//\t\t\techo '<h3>Worksheet: ',$worksheet_ss['Name'],'<h3>';\n//\n\t\t\t// Create new Worksheet\n\t\t\t$objPHPExcel->createSheet();\n\t\t\t$objPHPExcel->setActiveSheetIndex($worksheetID);\n\t\t\tif (isset($worksheet_ss['Name'])) {\n\t\t\t\t$worksheetName = self::_convertStringEncoding((string) $worksheet_ss['Name'],$this->_charSet);\n\t\t\t\t//\tUse false for $updateFormulaCellReferences to prevent adjustment of worksheet references in\n\t\t\t\t//\t\tformula cells... during the load, all formulae should be correct, and we're simply bringing\n\t\t\t\t//\t\tthe worksheet name in line with the formula, not the reverse\n\t\t\t\t$objPHPExcel->getActiveSheet()->setTitle($worksheetName,false);\n\t\t\t}\n\n\t\t\t$columnID = 'A';\n\t\t\tif (isset($worksheet->Table->Column)) {\n\t\t\t\tforeach($worksheet->Table->Column as $columnData) {\n\t\t\t\t\t$columnData_ss = $columnData->attributes($namespaces['ss']);\n\t\t\t\t\tif (isset($columnData_ss['Index'])) {\n\t\t\t\t\t\t$columnID = PHPExcel_Cell::stringFromColumnIndex($columnData_ss['Index']-1);\n\t\t\t\t\t}\n\t\t\t\t\tif (isset($columnData_ss['Width'])) {\n\t\t\t\t\t\t$columnWidth = $columnData_ss['Width'];\n//\t\t\t\t\t\techo '<b>Setting column width for '.$columnID.' to '.$columnWidth.'</b><br />';\n\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getColumnDimension($columnID)->setWidth($columnWidth / 5.4);\n\t\t\t\t\t}\n\t\t\t\t\t++$columnID;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$rowID = 1;\n\t\t\tif (isset($worksheet->Table->Row)) {\n                $additionalMergedCells = 0;\n\t\t\t\tforeach($worksheet->Table->Row as $rowData) {\n\t\t\t\t\t$rowHasData = false;\n\t\t\t\t\t$row_ss = $rowData->attributes($namespaces['ss']);\n\t\t\t\t\tif (isset($row_ss['Index'])) {\n\t\t\t\t\t\t$rowID = (integer) $row_ss['Index'];\n\t\t\t\t\t}\n//\t\t\t\t\techo '<b>Row '.$rowID.'</b><br />';\n\n\t\t\t\t\t$columnID = 'A';\n\t\t\t\t\tforeach($rowData->Cell as $cell) {\n\n\t\t\t\t\t\t$cell_ss = $cell->attributes($namespaces['ss']);\n\t\t\t\t\t\tif (isset($cell_ss['Index'])) {\n\t\t\t\t\t\t\t$columnID = PHPExcel_Cell::stringFromColumnIndex($cell_ss['Index']-1);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$cellRange = $columnID.$rowID;\n\n\t\t\t\t\t\tif ($this->getReadFilter() !== NULL) {\n\t\t\t\t\t\t\tif (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) {\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ((isset($cell_ss['MergeAcross'])) || (isset($cell_ss['MergeDown']))) {\n\t\t\t\t\t\t\t$columnTo = $columnID;\n\t\t\t\t\t\t\tif (isset($cell_ss['MergeAcross'])) {\n                                $additionalMergedCells += (int)$cell_ss['MergeAcross'];\n\t\t\t\t\t\t\t\t$columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cell_ss['MergeAcross'] -1);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$rowTo = $rowID;\n\t\t\t\t\t\t\tif (isset($cell_ss['MergeDown'])) {\n\t\t\t\t\t\t\t\t$rowTo = $rowTo + $cell_ss['MergeDown'];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$cellRange .= ':'.$columnTo.$rowTo;\n\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->mergeCells($cellRange);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t$cellIsSet = $hasCalculatedValue = false;\n\t\t\t\t\t\t$cellDataFormula = '';\n\t\t\t\t\t\tif (isset($cell_ss['Formula'])) {\n\t\t\t\t\t\t\t$cellDataFormula = $cell_ss['Formula'];\n\t\t\t\t\t\t\t// added this as a check for array formulas\n\t\t\t\t\t\t\tif (isset($cell_ss['ArrayRange'])) {\n\t\t\t\t\t\t\t\t$cellDataCSEFormula = $cell_ss['ArrayRange'];\n//\t\t\t\t\t\t\t\techo \"found an array formula at \".$columnID.$rowID.\"<br />\";\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$hasCalculatedValue = true;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (isset($cell->Data)) {\n\t\t\t\t\t\t\t$cellValue = $cellData = $cell->Data;\n\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_NULL;\n\t\t\t\t\t\t\t$cellData_ss = $cellData->attributes($namespaces['ss']);\n\t\t\t\t\t\t\tif (isset($cellData_ss['Type'])) {\n\t\t\t\t\t\t\t\t$cellDataType = $cellData_ss['Type'];\n\t\t\t\t\t\t\t\tswitch ($cellDataType) {\n\t\t\t\t\t\t\t\t\t/*\n\t\t\t\t\t\t\t\t\tconst TYPE_STRING\t\t= 's';\n\t\t\t\t\t\t\t\t\tconst TYPE_FORMULA\t\t= 'f';\n\t\t\t\t\t\t\t\t\tconst TYPE_NUMERIC\t\t= 'n';\n\t\t\t\t\t\t\t\t\tconst TYPE_BOOL\t\t\t= 'b';\n\t\t\t\t\t\t\t\t    const TYPE_NULL\t\t\t= 'null';\n\t\t\t\t\t\t\t\t    const TYPE_INLINE\t\t= 'inlineStr';\n\t\t\t\t\t\t\t\t\tconst TYPE_ERROR\t\t= 'e';\n\t\t\t\t\t\t\t\t\t*/\n\t\t\t\t\t\t\t\t\tcase 'String' :\n\t\t\t\t\t\t\t\t\t\t\t$cellValue = self::_convertStringEncoding($cellValue,$this->_charSet);\n\t\t\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_STRING;\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'Number' :\n\t\t\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;\n\t\t\t\t\t\t\t\t\t\t\t$cellValue = (float) $cellValue;\n\t\t\t\t\t\t\t\t\t\t\tif (floor($cellValue) == $cellValue) {\n\t\t\t\t\t\t\t\t\t\t\t\t$cellValue = (integer) $cellValue;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'Boolean' :\n\t\t\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_BOOL;\n\t\t\t\t\t\t\t\t\t\t\t$cellValue = ($cellValue != 0);\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'DateTime' :\n\t\t\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;\n\t\t\t\t\t\t\t\t\t\t\t$cellValue = PHPExcel_Shared_Date::PHPToExcel(strtotime($cellValue));\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'Error' :\n\t\t\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_ERROR;\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ($hasCalculatedValue) {\n//\t\t\t\t\t\t\t\techo 'FORMULA<br />';\n\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_FORMULA;\n\t\t\t\t\t\t\t\t$columnNumber = PHPExcel_Cell::columnIndexFromString($columnID);\n\t\t\t\t\t\t\t\tif (substr($cellDataFormula,0,3) == 'of:') {\n\t\t\t\t\t\t\t\t\t$cellDataFormula = substr($cellDataFormula,3);\n//\t\t\t\t\t\t\t\t\techo 'Before: ',$cellDataFormula,'<br />';\n\t\t\t\t\t\t\t\t\t$temp = explode('\"',$cellDataFormula);\n\t\t\t\t\t\t\t\t\t$key = false;\n\t\t\t\t\t\t\t\t\tforeach($temp as &$value) {\n\t\t\t\t\t\t\t\t\t\t//\tOnly replace in alternate array entries (i.e. non-quoted blocks)\n\t\t\t\t\t\t\t\t\t\tif ($key = !$key) {\n\t\t\t\t\t\t\t\t\t\t\t$value = str_replace(array('[.','.',']'),'',$value);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t//\tConvert R1C1 style references to A1 style references (but only when not quoted)\n//\t\t\t\t\t\t\t\t\techo 'Before: ',$cellDataFormula,'<br />';\n\t\t\t\t\t\t\t\t\t$temp = explode('\"',$cellDataFormula);\n\t\t\t\t\t\t\t\t\t$key = false;\n\t\t\t\t\t\t\t\t\tforeach($temp as &$value) {\n\t\t\t\t\t\t\t\t\t\t//\tOnly replace in alternate array entries (i.e. non-quoted blocks)\n\t\t\t\t\t\t\t\t\t\tif ($key = !$key) {\n\t\t\t\t\t\t\t\t\t\t\tpreg_match_all('/(R(\\[?-?\\d*\\]?))(C(\\[?-?\\d*\\]?))/',$value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE);\n\t\t\t\t\t\t\t\t\t\t\t//\tReverse the matches array, otherwise all our offsets will become incorrect if we modify our way\n\t\t\t\t\t\t\t\t\t\t\t//\t\tthrough the formula from left to right. Reversing means that we work right to left.through\n\t\t\t\t\t\t\t\t\t\t\t//\t\tthe formula\n\t\t\t\t\t\t\t\t\t\t\t$cellReferences = array_reverse($cellReferences);\n\t\t\t\t\t\t\t\t\t\t\t//\tLoop through each R1C1 style reference in turn, converting it to its A1 style equivalent,\n\t\t\t\t\t\t\t\t\t\t\t//\t\tthen modify the formula to use that new reference\n\t\t\t\t\t\t\t\t\t\t\tforeach($cellReferences as $cellReference) {\n\t\t\t\t\t\t\t\t\t\t\t\t$rowReference = $cellReference[2][0];\n\t\t\t\t\t\t\t\t\t\t\t\t//\tEmpty R reference is the current row\n\t\t\t\t\t\t\t\t\t\t\t\tif ($rowReference == '') $rowReference = $rowID;\n\t\t\t\t\t\t\t\t\t\t\t\t//\tBracketed R references are relative to the current row\n\t\t\t\t\t\t\t\t\t\t\t\tif ($rowReference{0} == '[') $rowReference = $rowID + trim($rowReference,'[]');\n\t\t\t\t\t\t\t\t\t\t\t\t$columnReference = $cellReference[4][0];\n\t\t\t\t\t\t\t\t\t\t\t\t//\tEmpty C reference is the current column\n\t\t\t\t\t\t\t\t\t\t\t\tif ($columnReference == '') $columnReference = $columnNumber;\n\t\t\t\t\t\t\t\t\t\t\t\t//\tBracketed C references are relative to the current column\n\t\t\t\t\t\t\t\t\t\t\t\tif ($columnReference{0} == '[') $columnReference = $columnNumber + trim($columnReference,'[]');\n\t\t\t\t\t\t\t\t\t\t\t\t$A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference;\n\t\t\t\t\t\t\t\t\t\t\t\t\t$value = substr_replace($value,$A1CellReference,$cellReference[0][1],strlen($cellReference[0][0]));\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tunset($value);\n\t\t\t\t\t\t\t\t//\tThen rebuild the formula string\n\t\t\t\t\t\t\t\t$cellDataFormula = implode('\"',$temp);\n//\t\t\t\t\t\t\t\techo 'After: ',$cellDataFormula,'<br />';\n\t\t\t\t\t\t\t}\n\n//\t\t\t\t\t\t\techo 'Cell '.$columnID.$rowID.' is a '.$type.' with a value of '.(($hasCalculatedValue) ? $cellDataFormula : $cellValue).'<br />';\n//\n\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $cellValue),$type);\n\t\t\t\t\t\t\tif ($hasCalculatedValue) {\n//\t\t\t\t\t\t\t\techo 'Formula result is '.$cellValue.'<br />';\n\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setCalculatedValue($cellValue);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$cellIsSet = $rowHasData = true;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (isset($cell->Comment)) {\n//\t\t\t\t\t\t\techo '<b>comment found</b><br />';\n\t\t\t\t\t\t\t$commentAttributes = $cell->Comment->attributes($namespaces['ss']);\n\t\t\t\t\t\t\t$author = 'unknown';\n\t\t\t\t\t\t\tif (isset($commentAttributes->Author)) {\n\t\t\t\t\t\t\t\t$author = (string)$commentAttributes->Author;\n//\t\t\t\t\t\t\t\techo 'Author: ',$author,'<br />';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$node = $cell->Comment->Data->asXML();\n//\t\t\t\t\t\t\t$annotation = str_replace('html:','',substr($node,49,-10));\n//\t\t\t\t\t\t\techo $annotation,'<br />';\n\t\t\t\t\t\t\t$annotation = strip_tags($node);\n//\t\t\t\t\t\t\techo 'Annotation: ',$annotation,'<br />';\n\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID )\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t->setAuthor(self::_convertStringEncoding($author ,$this->_charSet))\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t->setText($this->_parseRichText($annotation) );\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (($cellIsSet) && (isset($cell_ss['StyleID']))) {\n\t\t\t\t\t\t\t$style = (string) $cell_ss['StyleID'];\n//\t\t\t\t\t\t\techo 'Cell style for '.$columnID.$rowID.' is '.$style.'<br />';\n\t\t\t\t\t\t\tif ((isset($this->_styles[$style])) && (!empty($this->_styles[$style]))) {\n//\t\t\t\t\t\t\t\techo 'Cell '.$columnID.$rowID.'<br />';\n//\t\t\t\t\t\t\t\tprint_r($this->_styles[$style]);\n//\t\t\t\t\t\t\t\techo '<br />';\n\t\t\t\t\t\t\t\tif (!$objPHPExcel->getActiveSheet()->cellExists($columnID.$rowID)) {\n\t\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getCell($columnID.$rowID)->setValue(NULL);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($this->_styles[$style]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t++$columnID;\n                        while ($additionalMergedCells > 0) {\n                            ++$columnID;\n                            $additionalMergedCells--;\n                        }\n\t\t\t\t\t}\n\n\t\t\t\t\tif ($rowHasData) {\n\t\t\t\t\t\tif (isset($row_ss['StyleID'])) {\n\t\t\t\t\t\t\t$rowStyle = $row_ss['StyleID'];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (isset($row_ss['Height'])) {\n\t\t\t\t\t\t\t$rowHeight = $row_ss['Height'];\n//\t\t\t\t\t\t\techo '<b>Setting row height to '.$rowHeight.'</b><br />';\n\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getRowDimension($rowID)->setRowHeight($rowHeight);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t++$rowID;\n\t\t\t\t}\n\t\t\t}\n\t\t\t++$worksheetID;\n\t\t}\n\n\t\t// Return\n\t\treturn $objPHPExcel;\n\t}\n\n\n\tprotected static function _convertStringEncoding($string,$charset) {\n\t\tif ($charset != 'UTF-8') {\n\t\t\treturn PHPExcel_Shared_String::ConvertEncoding($string,'UTF-8',$charset);\n\t\t}\n\t\treturn $string;\n\t}\n\n\n\tprotected function _parseRichText($is = '') {\n\t\t$value = new PHPExcel_RichText();\n\n\t\t$value->createText(self::_convertStringEncoding($is,$this->_charSet));\n\n\t\treturn $value;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/Excel2007/Chart.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Reader_Excel2007\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Reader_Excel2007_Chart\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Reader_Excel2007\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_Excel2007_Chart\n{\n\tprivate static function _getAttribute($component, $name, $format) {\n\t\t$attributes = $component->attributes();\n\t\tif (isset($attributes[$name])) {\n\t\t\tif ($format == 'string') {\n\t\t\t\treturn (string) $attributes[$name];\n\t\t\t} elseif ($format == 'integer') {\n\t\t\t\treturn (integer) $attributes[$name];\n\t\t\t} elseif ($format == 'boolean') {\n\t\t\t\treturn (boolean) ($attributes[$name] === '0' || $attributes[$name] !== 'true') ? false : true;\n\t\t\t} else {\n\t\t\t\treturn (float) $attributes[$name];\n\t\t\t}\n\t\t}\n\t\treturn null;\n\t}\t//\tfunction _getAttribute()\n\n\n\tprivate static function _readColor($color,$background=false) {\n\t\tif (isset($color[\"rgb\"])) {\n\t\t\treturn (string)$color[\"rgb\"];\n\t\t} else if (isset($color[\"indexed\"])) {\n\t\t\treturn PHPExcel_Style_Color::indexedColor($color[\"indexed\"]-7,$background)->getARGB();\n\t\t}\n\t}\n\n\n\tpublic static function readChart($chartElements,$chartName) {\n\t\t$namespacesChartMeta = $chartElements->getNamespaces(true);\n\t\t$chartElementsC = $chartElements->children($namespacesChartMeta['c']);\n\n\t\t$XaxisLabel = $YaxisLabel = $legend = $title = NULL;\n\t\t$dispBlanksAs = $plotVisOnly = NULL;\n\n\t\tforeach($chartElementsC as $chartElementKey => $chartElement) {\n\t\t\tswitch ($chartElementKey) {\n\t\t\t\tcase \"chart\":\n\t\t\t\t\tforeach($chartElement as $chartDetailsKey => $chartDetails) {\n\t\t\t\t\t\t$chartDetailsC = $chartDetails->children($namespacesChartMeta['c']);\n\t\t\t\t\t\tswitch ($chartDetailsKey) {\n\t\t\t\t\t\t\tcase \"plotArea\":\n\t\t\t\t\t\t\t\t\t$plotAreaLayout = $XaxisLable = $YaxisLable = null;\n\t\t\t\t\t\t\t\t\t$plotSeries = $plotAttributes = array();\n\t\t\t\t\t\t\t\t\tforeach($chartDetails as $chartDetailKey => $chartDetail) {\n\t\t\t\t\t\t\t\t\t\tswitch ($chartDetailKey) {\n\t\t\t\t\t\t\t\t\t\t\tcase \"layout\":\n\t\t\t\t\t\t\t\t\t\t\t\t$plotAreaLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta,'plotArea');\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"catAx\":\n\t\t\t\t\t\t\t\t\t\t\t\tif (isset($chartDetail->title)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat');\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"dateAx\":\n\t\t\t\t\t\t\t\t\t\t\t\tif (isset($chartDetail->title)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$XaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat');\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"valAx\":\n\t\t\t\t\t\t\t\t\t\t\t\tif (isset($chartDetail->title)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$YaxisLabel = self::_chartTitle($chartDetail->title->children($namespacesChartMeta['c']),$namespacesChartMeta,'cat');\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"barChart\":\n\t\t\t\t\t\t\t\t\t\t\tcase \"bar3DChart\":\n\t\t\t\t\t\t\t\t\t\t\t\t$barDirection = self::_getAttribute($chartDetail->barDir, 'val', 'string');\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSer->setPlotDirection($barDirection);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSeries[] = $plotSer;\n\t\t\t\t\t\t\t\t\t\t\t\t$plotAttributes = self::_readChartAttributes($chartDetail);\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"lineChart\":\n\t\t\t\t\t\t\t\t\t\t\tcase \"line3DChart\":\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotAttributes = self::_readChartAttributes($chartDetail);\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"areaChart\":\n\t\t\t\t\t\t\t\t\t\t\tcase \"area3DChart\":\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotAttributes = self::_readChartAttributes($chartDetail);\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"doughnutChart\":\n\t\t\t\t\t\t\t\t\t\t\tcase \"pieChart\":\n\t\t\t\t\t\t\t\t\t\t\tcase \"pie3DChart\":\n\t\t\t\t\t\t\t\t\t\t\t\t$explosion = isset($chartDetail->ser->explosion);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSer->setPlotStyle($explosion);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSeries[] = $plotSer;\n\t\t\t\t\t\t\t\t\t\t\t\t$plotAttributes = self::_readChartAttributes($chartDetail);\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"scatterChart\":\n\t\t\t\t\t\t\t\t\t\t\t\t$scatterStyle = self::_getAttribute($chartDetail->scatterStyle, 'val', 'string');\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSer->setPlotStyle($scatterStyle);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSeries[] = $plotSer;\n\t\t\t\t\t\t\t\t\t\t\t\t$plotAttributes = self::_readChartAttributes($chartDetail);\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"bubbleChart\":\n\t\t\t\t\t\t\t\t\t\t\t\t$bubbleScale = self::_getAttribute($chartDetail->bubbleScale, 'val', 'integer');\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSer->setPlotStyle($bubbleScale);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSeries[] = $plotSer;\n\t\t\t\t\t\t\t\t\t\t\t\t$plotAttributes = self::_readChartAttributes($chartDetail);\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"radarChart\":\n\t\t\t\t\t\t\t\t\t\t\t\t$radarStyle = self::_getAttribute($chartDetail->radarStyle, 'val', 'string');\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSer->setPlotStyle($radarStyle);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSeries[] = $plotSer;\n\t\t\t\t\t\t\t\t\t\t\t\t$plotAttributes = self::_readChartAttributes($chartDetail);\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"surfaceChart\":\n\t\t\t\t\t\t\t\t\t\t\tcase \"surface3DChart\":\n\t\t\t\t\t\t\t\t\t\t\t\t$wireFrame = self::_getAttribute($chartDetail->wireframe, 'val', 'boolean');\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSer = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSer->setPlotStyle($wireFrame);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSeries[] = $plotSer;\n\t\t\t\t\t\t\t\t\t\t\t\t$plotAttributes = self::_readChartAttributes($chartDetail);\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"stockChart\":\n\t\t\t\t\t\t\t\t\t\t\t\t$plotSeries[] = self::_chartDataSeries($chartDetail,$namespacesChartMeta,$chartDetailKey);\n\t\t\t\t\t\t\t\t\t\t\t\t$plotAttributes = self::_readChartAttributes($plotAreaLayout);\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif ($plotAreaLayout == NULL) {\n\t\t\t\t\t\t\t\t\t\t$plotAreaLayout = new PHPExcel_Chart_Layout();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t$plotArea = new PHPExcel_Chart_PlotArea($plotAreaLayout,$plotSeries);\n\t\t\t\t\t\t\t\t\tself::_setChartAttributes($plotAreaLayout,$plotAttributes);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"plotVisOnly\":\n\t\t\t\t\t\t\t\t\t$plotVisOnly = self::_getAttribute($chartDetails, 'val', 'string');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"dispBlanksAs\":\n\t\t\t\t\t\t\t\t\t$dispBlanksAs = self::_getAttribute($chartDetails, 'val', 'string');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"title\":\n\t\t\t\t\t\t\t\t\t$title = self::_chartTitle($chartDetails,$namespacesChartMeta,'title');\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"legend\":\n\t\t\t\t\t\t\t\t\t$legendPos = 'r';\n\t\t\t\t\t\t\t\t\t$legendLayout = null;\n\t\t\t\t\t\t\t\t\t$legendOverlay = false;\n\t\t\t\t\t\t\t\t\tforeach($chartDetails as $chartDetailKey => $chartDetail) {\n\t\t\t\t\t\t\t\t\t\tswitch ($chartDetailKey) {\n\t\t\t\t\t\t\t\t\t\t\tcase \"legendPos\":\n\t\t\t\t\t\t\t\t\t\t\t\t$legendPos = self::_getAttribute($chartDetail, 'val', 'string');\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"overlay\":\n\t\t\t\t\t\t\t\t\t\t\t\t$legendOverlay = self::_getAttribute($chartDetail, 'val', 'boolean');\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"layout\":\n\t\t\t\t\t\t\t\t\t\t\t\t$legendLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta,'legend');\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t$legend = new PHPExcel_Chart_Legend($legendPos, $legendLayout, $legendOverlay);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t$chart = new PHPExcel_Chart($chartName,$title,$legend,$plotArea,$plotVisOnly,$dispBlanksAs,$XaxisLabel,$YaxisLabel);\n\n\t\treturn $chart;\n\t}\t//\tfunction readChart()\n\n\n\tprivate static function _chartTitle($titleDetails,$namespacesChartMeta,$type) {\n\t\t$caption = array();\n\t\t$titleLayout = null;\n\t\tforeach($titleDetails as $titleDetailKey => $chartDetail) {\n\t\t\tswitch ($titleDetailKey) {\n\t\t\t\tcase \"tx\":\n\t\t\t\t\t$titleDetails = $chartDetail->rich->children($namespacesChartMeta['a']);\n\t\t\t\t\tforeach($titleDetails as $titleKey => $titleDetail) {\n\t\t\t\t\t\tswitch ($titleKey) {\n\t\t\t\t\t\t\tcase \"p\":\n\t\t\t\t\t\t\t\t$titleDetailPart = $titleDetail->children($namespacesChartMeta['a']);\n\t\t\t\t\t\t\t\t$caption[] = self::_parseRichText($titleDetailPart);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"layout\":\n\t\t\t\t\t$titleLayout = self::_chartLayoutDetails($chartDetail,$namespacesChartMeta);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn new PHPExcel_Chart_Title($caption, $titleLayout);\n\t}\t//\tfunction _chartTitle()\n\n\n\tprivate static function _chartLayoutDetails($chartDetail,$namespacesChartMeta) {\n\t\tif (!isset($chartDetail->manualLayout)) {\n\t\t\treturn null;\n\t\t}\n\t\t$details = $chartDetail->manualLayout->children($namespacesChartMeta['c']);\n\t\tif (is_null($details)) {\n\t\t\treturn null;\n\t\t}\n\t\t$layout = array();\n\t\tforeach($details as $detailKey => $detail) {\n//\t\t\techo $detailKey,' => ',self::_getAttribute($detail, 'val', 'string'),PHP_EOL;\n\t\t\t$layout[$detailKey] = self::_getAttribute($detail, 'val', 'string');\n\t\t}\n\t\treturn new PHPExcel_Chart_Layout($layout);\n\t}\t//\tfunction _chartLayoutDetails()\n\n\n\tprivate static function _chartDataSeries($chartDetail,$namespacesChartMeta,$plotType) {\n\t\t$multiSeriesType = NULL;\n\t\t$smoothLine = false;\n\t\t$seriesLabel = $seriesCategory = $seriesValues = $plotOrder = array();\n\n\t\t$seriesDetailSet = $chartDetail->children($namespacesChartMeta['c']);\n\t\tforeach($seriesDetailSet as $seriesDetailKey => $seriesDetails) {\n\t\t\tswitch ($seriesDetailKey) {\n\t\t\t\tcase \"grouping\":\n\t\t\t\t\t$multiSeriesType = self::_getAttribute($chartDetail->grouping, 'val', 'string');\n\t\t\t\t\tbreak;\n\t\t\t\tcase \"ser\":\n\t\t\t\t\t$marker = NULL;\n\t\t\t\t\tforeach($seriesDetails as $seriesKey => $seriesDetail) {\n\t\t\t\t\t\tswitch ($seriesKey) {\n\t\t\t\t\t\t\tcase \"idx\":\n\t\t\t\t\t\t\t\t$seriesIndex = self::_getAttribute($seriesDetail, 'val', 'integer');\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"order\":\n\t\t\t\t\t\t\t\t$seriesOrder = self::_getAttribute($seriesDetail, 'val', 'integer');\n\t\t\t\t\t\t\t\t$plotOrder[$seriesIndex] = $seriesOrder;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"tx\":\n\t\t\t\t\t\t\t\t$seriesLabel[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"marker\":\n\t\t\t\t\t\t\t\t$marker = self::_getAttribute($seriesDetail->symbol, 'val', 'string');\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"smooth\":\n\t\t\t\t\t\t\t\t$smoothLine = self::_getAttribute($seriesDetail, 'val', 'boolean');\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"cat\":\n\t\t\t\t\t\t\t\t$seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"val\":\n\t\t\t\t\t\t\t\t$seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"xVal\":\n\t\t\t\t\t\t\t\t$seriesCategory[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase \"yVal\":\n\t\t\t\t\t\t\t\t$seriesValues[$seriesIndex] = self::_chartDataSeriesValueSet($seriesDetail,$namespacesChartMeta,$marker);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn new PHPExcel_Chart_DataSeries($plotType,$multiSeriesType,$plotOrder,$seriesLabel,$seriesCategory,$seriesValues,$smoothLine);\n\t}\t//\tfunction _chartDataSeries()\n\n\n\tprivate static function _chartDataSeriesValueSet($seriesDetail, $namespacesChartMeta, $marker = null, $smoothLine = false) {\n\t\tif (isset($seriesDetail->strRef)) {\n\t\t\t$seriesSource = (string) $seriesDetail->strRef->f;\n\t\t\t$seriesData = self::_chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']),'s');\n\n\t\t\treturn new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine);\n\t\t} elseif (isset($seriesDetail->numRef)) {\n\t\t\t$seriesSource = (string) $seriesDetail->numRef->f;\n\t\t\t$seriesData = self::_chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c']));\n\n\t\t\treturn new PHPExcel_Chart_DataSeriesValues('Number',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine);\n\t\t} elseif (isset($seriesDetail->multiLvlStrRef)) {\n\t\t\t$seriesSource = (string) $seriesDetail->multiLvlStrRef->f;\n\t\t\t$seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']),'s');\n\t\t\t$seriesData['pointCount'] = count($seriesData['dataValues']);\n\n\t\t\treturn new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine);\n\t\t} elseif (isset($seriesDetail->multiLvlNumRef)) {\n\t\t\t$seriesSource = (string) $seriesDetail->multiLvlNumRef->f;\n\t\t\t$seriesData = self::_chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']),'s');\n\t\t\t$seriesData['pointCount'] = count($seriesData['dataValues']);\n\n\t\t\treturn new PHPExcel_Chart_DataSeriesValues('String',$seriesSource,$seriesData['formatCode'],$seriesData['pointCount'],$seriesData['dataValues'],$marker,$smoothLine);\n\t\t}\n\t\treturn null;\n\t}\t//\tfunction _chartDataSeriesValueSet()\n\n\n\tprivate static function _chartDataSeriesValues($seriesValueSet,$dataType='n') {\n\t\t$seriesVal = array();\n\t\t$formatCode = '';\n\t\t$pointCount = 0;\n\n\t\tforeach($seriesValueSet as $seriesValueIdx => $seriesValue) {\n\t\t\tswitch ($seriesValueIdx) {\n\t\t\t\tcase 'ptCount':\n\t\t\t\t\t$pointCount = self::_getAttribute($seriesValue, 'val', 'integer');\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'formatCode':\n\t\t\t\t\t$formatCode = (string) $seriesValue;\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'pt':\n\t\t\t\t\t$pointVal = self::_getAttribute($seriesValue, 'idx', 'integer');\n\t\t\t\t\tif ($dataType == 's') {\n\t\t\t\t\t\t$seriesVal[$pointVal] = (string) $seriesValue->v;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$seriesVal[$pointVal] = (float) $seriesValue->v;\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\tif (empty($seriesVal)) {\n\t\t\t$seriesVal = NULL;\n\t\t}\n\n\t\treturn array( 'formatCode'\t=> $formatCode,\n\t\t\t\t\t  'pointCount'\t=> $pointCount,\n\t\t\t\t\t  'dataValues'\t=> $seriesVal\n\t\t\t\t\t);\n\t}\t//\tfunction _chartDataSeriesValues()\n\n\n\tprivate static function _chartDataSeriesValuesMultiLevel($seriesValueSet,$dataType='n') {\n\t\t$seriesVal = array();\n\t\t$formatCode = '';\n\t\t$pointCount = 0;\n\n\t\tforeach($seriesValueSet->lvl as $seriesLevelIdx => $seriesLevel) {\n\t\t\tforeach($seriesLevel as $seriesValueIdx => $seriesValue) {\n\t\t\t\tswitch ($seriesValueIdx) {\n\t\t\t\t\tcase 'ptCount':\n\t\t\t\t\t\t$pointCount = self::_getAttribute($seriesValue, 'val', 'integer');\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'formatCode':\n\t\t\t\t\t\t$formatCode = (string) $seriesValue;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'pt':\n\t\t\t\t\t\t$pointVal = self::_getAttribute($seriesValue, 'idx', 'integer');\n\t\t\t\t\t\tif ($dataType == 's') {\n\t\t\t\t\t\t\t$seriesVal[$pointVal][] = (string) $seriesValue->v;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$seriesVal[$pointVal][] = (float) $seriesValue->v;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn array( 'formatCode'\t=> $formatCode,\n\t\t\t\t\t  'pointCount'\t=> $pointCount,\n\t\t\t\t\t  'dataValues'\t=> $seriesVal\n\t\t\t\t\t);\n\t}\t//\tfunction _chartDataSeriesValuesMultiLevel()\n\n\tprivate static function _parseRichText($titleDetailPart = null) {\n\t\t$value = new PHPExcel_RichText();\n\n\t\tforeach($titleDetailPart as $titleDetailElementKey => $titleDetailElement) {\n\t\t\tif (isset($titleDetailElement->t)) {\n\t\t\t\t$objText = $value->createTextRun( (string) $titleDetailElement->t );\n\t\t\t}\n\t\t\tif (isset($titleDetailElement->rPr)) {\n\t\t\t\tif (isset($titleDetailElement->rPr->rFont[\"val\"])) {\n\t\t\t\t\t$objText->getFont()->setName((string) $titleDetailElement->rPr->rFont[\"val\"]);\n\t\t\t\t}\n\n\t\t\t\t$fontSize = (self::_getAttribute($titleDetailElement->rPr, 'sz', 'integer'));\n\t\t\t\tif (!is_null($fontSize)) {\n\t\t\t\t\t$objText->getFont()->setSize(floor($fontSize / 100));\n\t\t\t\t}\n\n\t\t\t\t$fontColor = (self::_getAttribute($titleDetailElement->rPr, 'color', 'string'));\n\t\t\t\tif (!is_null($fontColor)) {\n\t\t\t\t\t$objText->getFont()->setColor( new PHPExcel_Style_Color( self::_readColor($fontColor) ) );\n\t\t\t\t}\n\n\t\t\t\t$bold = self::_getAttribute($titleDetailElement->rPr, 'b', 'boolean');\n\t\t\t\tif (!is_null($bold)) {\n\t\t\t\t\t$objText->getFont()->setBold($bold);\n\t\t\t\t}\n\n\t\t\t\t$italic = self::_getAttribute($titleDetailElement->rPr, 'i', 'boolean');\n\t\t\t\tif (!is_null($italic)) {\n\t\t\t\t\t$objText->getFont()->setItalic($italic);\n\t\t\t\t}\n\n\t\t\t\t$baseline = self::_getAttribute($titleDetailElement->rPr, 'baseline', 'integer');\n\t\t\t\tif (!is_null($baseline)) {\n\t\t\t\t\tif ($baseline > 0) {\n\t\t\t\t\t\t$objText->getFont()->setSuperScript(true);\n\t\t\t\t\t} elseif($baseline < 0) {\n\t\t\t\t\t\t$objText->getFont()->setSubScript(true);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t$underscore = (self::_getAttribute($titleDetailElement->rPr, 'u', 'string'));\n\t\t\t\tif (!is_null($underscore)) {\n\t\t\t\t\tif ($underscore == 'sng') {\n\t\t\t\t\t\t$objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);\n\t\t\t\t\t} elseif($underscore == 'dbl') {\n\t\t\t\t\t\t$objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_NONE);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t$strikethrough = (self::_getAttribute($titleDetailElement->rPr, 's', 'string'));\n\t\t\t\tif (!is_null($strikethrough)) {\n\t\t\t\t\tif ($strikethrough == 'noStrike') {\n\t\t\t\t\t\t$objText->getFont()->setStrikethrough(false);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$objText->getFont()->setStrikethrough(true);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn $value;\n\t}\n\n\tprivate static function _readChartAttributes($chartDetail) {\n\t\t$plotAttributes = array();\n\t\tif (isset($chartDetail->dLbls)) {\n\t\t\tif (isset($chartDetail->dLbls->howLegendKey)) {\n\t\t\t\t$plotAttributes['showLegendKey'] = self::_getAttribute($chartDetail->dLbls->showLegendKey, 'val', 'string');\n\t\t\t}\n\t\t\tif (isset($chartDetail->dLbls->showVal)) {\n\t\t\t\t$plotAttributes['showVal'] = self::_getAttribute($chartDetail->dLbls->showVal, 'val', 'string');\n\t\t\t}\n\t\t\tif (isset($chartDetail->dLbls->showCatName)) {\n\t\t\t\t$plotAttributes['showCatName'] = self::_getAttribute($chartDetail->dLbls->showCatName, 'val', 'string');\n\t\t\t}\n\t\t\tif (isset($chartDetail->dLbls->showSerName)) {\n\t\t\t\t$plotAttributes['showSerName'] = self::_getAttribute($chartDetail->dLbls->showSerName, 'val', 'string');\n\t\t\t}\n\t\t\tif (isset($chartDetail->dLbls->showPercent)) {\n\t\t\t\t$plotAttributes['showPercent'] = self::_getAttribute($chartDetail->dLbls->showPercent, 'val', 'string');\n\t\t\t}\n\t\t\tif (isset($chartDetail->dLbls->showBubbleSize)) {\n\t\t\t\t$plotAttributes['showBubbleSize'] = self::_getAttribute($chartDetail->dLbls->showBubbleSize, 'val', 'string');\n\t\t\t}\n\t\t\tif (isset($chartDetail->dLbls->showLeaderLines)) {\n\t\t\t\t$plotAttributes['showLeaderLines'] = self::_getAttribute($chartDetail->dLbls->showLeaderLines, 'val', 'string');\n\t\t\t}\n\t\t}\n\n\t\treturn $plotAttributes;\n\t}\n\n\tprivate static function _setChartAttributes($plotArea,$plotAttributes)\n\t{\n\t\tforeach($plotAttributes as $plotAttributeKey => $plotAttributeValue) {\n\t\t\tswitch($plotAttributeKey) {\n\t\t\t\tcase 'showLegendKey' :\n\t\t\t\t\t$plotArea->setShowLegendKey($plotAttributeValue);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'showVal' :\n\t\t\t\t\t$plotArea->setShowVal($plotAttributeValue);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'showCatName' :\n\t\t\t\t\t$plotArea->setShowCatName($plotAttributeValue);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'showSerName' :\n\t\t\t\t\t$plotArea->setShowSerName($plotAttributeValue);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'showPercent' :\n\t\t\t\t\t$plotArea->setShowPercent($plotAttributeValue);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'showBubbleSize' :\n\t\t\t\t\t$plotArea->setShowBubbleSize($plotAttributeValue);\n\t\t\t\t\tbreak;\n\t\t\t\tcase 'showLeaderLines' :\n\t\t\t\t\t$plotArea->setShowLeaderLines($plotAttributeValue);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/Excel2007/Theme.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Reader_Excel2007_Theme\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_Excel2007_Theme\n{\n\t/**\n\t * Theme Name\n\t *\n\t * @var string\n\t */\n\tprivate $_themeName;\n\n\t/**\n\t * Colour Scheme Name\n\t *\n\t * @var string\n\t */\n\tprivate $_colourSchemeName;\n\n\t/**\n\t * Colour Map indexed by position\n\t *\n\t * @var array of string\n\t */\n\tprivate $_colourMapValues;\n\n\n\t/**\n\t * Colour Map\n\t *\n\t * @var array of string\n\t */\n\tprivate $_colourMap;\n\n\n    /**\n     * Create a new PHPExcel_Theme\n\t *\n     */\n    public function __construct($themeName,$colourSchemeName,$colourMap)\n    {\n\t\t// Initialise values\n    \t$this->_themeName\t\t\t= $themeName;\n\t\t$this->_colourSchemeName\t= $colourSchemeName;\n\t\t$this->_colourMap\t\t\t= $colourMap;\n    }\n\n\t/**\n\t * Get Theme Name\n\t *\n\t * @return string\n\t */\n\tpublic function getThemeName()\n\t{\n\t\treturn $this->_themeName;\n\t}\n\n    /**\n     * Get colour Scheme Name\n     *\n     * @return string\n     */\n    public function getColourSchemeName() {\n\t\treturn $this->_colourSchemeName;\n    }\n\n    /**\n     * Get colour Map Value by Position\n     *\n     * @return string\n     */\n    public function getColourByIndex($index=0) {\n    \tif (isset($this->_colourMap[$index])) {\n\t\t\treturn $this->_colourMap[$index];\n\t\t}\n\t\treturn null;\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif ((is_object($value)) && ($key != '_parent')) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/Excel2007.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n/**\n * PHPExcel_Reader_Excel2007\n *\n * @category\tPHPExcel\n * @package\tPHPExcel_Reader\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_Excel2007 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader\n{\n\t/**\n\t * PHPExcel_ReferenceHelper instance\n\t *\n\t * @var PHPExcel_ReferenceHelper\n\t */\n\tprivate $_referenceHelper = NULL;\n\n\t/**\n\t * PHPExcel_Reader_Excel2007_Theme instance\n\t *\n\t * @var PHPExcel_Reader_Excel2007_Theme\n\t */\n\tprivate static $_theme = NULL;\n\n\n\t/**\n\t * Create a new PHPExcel_Reader_Excel2007 instance\n\t */\n\tpublic function __construct() {\n\t\t$this->_readFilter = new PHPExcel_Reader_DefaultReadFilter();\n\t\t$this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance();\n\t}\n\n\n\t/**\n\t * Can the current PHPExcel_Reader_IReader read the file?\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @return \tboolean\n\t * @throws PHPExcel_Reader_Exception\n\t */\n\tpublic function canRead($pFilename)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n        $zipClass = PHPExcel_Settings::getZipClass();\n\n\t\t// Check if zip class exists\n//\t\tif (!class_exists($zipClass, FALSE)) {\n//\t\t\tthrow new PHPExcel_Reader_Exception($zipClass . \" library is not enabled\");\n//\t\t}\n\n\t\t$xl = false;\n\t\t// Load file\n\t\t$zip = new $zipClass;\n\t\tif ($zip->open($pFilename) === true) {\n\t\t\t// check if it is an OOXML archive\n\t\t\t$rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"_rels/.rels\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t\tif ($rels !== false) {\n\t\t\t\tforeach ($rels->Relationship as $rel) {\n\t\t\t\t\tswitch ($rel[\"Type\"]) {\n\t\t\t\t\t\tcase \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\":\n\t\t\t\t\t\t\tif (basename($rel[\"Target\"]) == 'workbook.xml') {\n\t\t\t\t\t\t\t\t$xl = true;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t$zip->close();\n\t\t}\n\n\t\treturn $xl;\n\t}\n\n\n\t/**\n\t * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function listWorksheetNames($pFilename)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n\t\t$worksheetNames = array();\n\n        $zipClass = PHPExcel_Settings::getZipClass();\n\n\t\t$zip = new $zipClass;\n\t\t$zip->open($pFilename);\n\n\t\t//\tThe files we're looking at here are small enough that simpleXML is more efficient than XMLReader\n\t\t$rels = simplexml_load_string(\n\t\t    $this->securityScan($this->_getFromZipArchive($zip, \"_rels/.rels\"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions())\n\t\t); //~ http://schemas.openxmlformats.org/package/2006/relationships\");\n\t\tforeach ($rels->Relationship as $rel) {\n\t\t\tswitch ($rel[\"Type\"]) {\n\t\t\t\tcase \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\":\n\t\t\t\t\t$xmlWorkbook = simplexml_load_string(\n\t\t\t\t\t    $this->securityScan($this->_getFromZipArchive($zip, \"{$rel['Target']}\"), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions())\n\t\t\t\t\t);  //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main\");\n\n\t\t\t\t\tif ($xmlWorkbook->sheets) {\n\t\t\t\t\t\tforeach ($xmlWorkbook->sheets->sheet as $eleSheet) {\n\t\t\t\t\t\t\t// Check if sheet should be skipped\n\t\t\t\t\t\t\t$worksheetNames[] = (string) $eleSheet[\"name\"];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t$zip->close();\n\n\t\treturn $worksheetNames;\n\t}\n\n\n\t/**\n\t * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)\n\t *\n\t * @param   string     $pFilename\n\t * @throws   PHPExcel_Reader_Exception\n\t */\n\tpublic function listWorksheetInfo($pFilename)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n\t\t$worksheetInfo = array();\n\n        $zipClass = PHPExcel_Settings::getZipClass();\n\n\t\t$zip = new $zipClass;\n\t\t$zip->open($pFilename);\n\n\t\t$rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"_rels/.rels\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships\");\n\t\tforeach ($rels->Relationship as $rel) {\n\t\t\tif ($rel[\"Type\"] == \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\") {\n\t\t\t\t$dir = dirname($rel[\"Target\"]);\n\t\t\t\t$relsWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"$dir/_rels/\" . basename($rel[\"Target\"]) . \".rels\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());  //~ http://schemas.openxmlformats.org/package/2006/relationships\");\n\t\t\t\t$relsWorkbook->registerXPathNamespace(\"rel\", \"http://schemas.openxmlformats.org/package/2006/relationships\");\n\n\t\t\t\t$worksheets = array();\n\t\t\t\tforeach ($relsWorkbook->Relationship as $ele) {\n\t\t\t\t\tif ($ele[\"Type\"] == \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\") {\n\t\t\t\t\t\t$worksheets[(string) $ele[\"Id\"]] = $ele[\"Target\"];\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t$xmlWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"{$rel['Target']}\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());  //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main\");\n\t\t\t\tif ($xmlWorkbook->sheets) {\n\t\t\t\t\t$dir = dirname($rel[\"Target\"]);\n\t\t\t\t\tforeach ($xmlWorkbook->sheets->sheet as $eleSheet) {\n\t\t\t\t\t\t$tmpInfo = array(\n\t\t\t\t\t\t\t'worksheetName' => (string) $eleSheet[\"name\"],\n\t\t\t\t\t\t\t'lastColumnLetter' => 'A',\n\t\t\t\t\t\t\t'lastColumnIndex' => 0,\n\t\t\t\t\t\t\t'totalRows' => 0,\n\t\t\t\t\t\t\t'totalColumns' => 0,\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t$fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes(\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"), \"id\")];\n\n\t\t\t\t\t\t$xml = new XMLReader();\n\t\t\t\t\t\t$res = $xml->xml($this->securityScanFile('zip://'.PHPExcel_Shared_File::realpath($pFilename).'#'.\"$dir/$fileWorksheet\"), null, PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t\t\t\t\t$xml->setParserProperty(2,true);\n\n\t\t\t\t\t\t$currCells = 0;\n\t\t\t\t\t\twhile ($xml->read()) {\n\t\t\t\t\t\t\tif ($xml->name == 'row' && $xml->nodeType == XMLReader::ELEMENT) {\n\t\t\t\t\t\t\t\t$row = $xml->getAttribute('r');\n\t\t\t\t\t\t\t\t$tmpInfo['totalRows'] = $row;\n\t\t\t\t\t\t\t\t$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);\n\t\t\t\t\t\t\t\t$currCells = 0;\n\t\t\t\t\t\t\t} elseif ($xml->name == 'c' && $xml->nodeType == XMLReader::ELEMENT) {\n\t\t\t\t\t\t\t\t$currCells++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);\n\t\t\t\t\t\t$xml->close();\n\n\t\t\t\t\t\t$tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;\n\t\t\t\t\t\t$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);\n\n\t\t\t\t\t\t$worksheetInfo[] = $tmpInfo;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t$zip->close();\n\n\t\treturn $worksheetInfo;\n\t}\n\n\n\tprivate static function _castToBool($c) {\n//\t\techo 'Initial Cast to Boolean', PHP_EOL;\n\t\t$value = isset($c->v) ? (string) $c->v : NULL;\n\t\tif ($value == '0') {\n\t\t\treturn FALSE;\n\t\t} elseif ($value == '1') {\n\t\t\treturn TRUE;\n\t\t} else {\n\t\t\treturn (bool)$c->v;\n\t\t}\n\t\treturn $value;\n\t}\t//\tfunction _castToBool()\n\n\n\tprivate static function _castToError($c) {\n//\t\techo 'Initial Cast to Error', PHP_EOL;\n\t\treturn isset($c->v) ? (string) $c->v : NULL;\n\t}\t//\tfunction _castToError()\n\n\n\tprivate static function _castToString($c) {\n//\t\techo 'Initial Cast to String, PHP_EOL;\n\t\treturn isset($c->v) ? (string) $c->v : NULL;\n\t}\t//\tfunction _castToString()\n\n\n\tprivate function _castToFormula($c,$r,&$cellDataType,&$value,&$calculatedValue,&$sharedFormulas,$castBaseType) {\n//\t\techo 'Formula', PHP_EOL;\n//\t\techo '$c->f is ', $c->f, PHP_EOL;\n\t\t$cellDataType \t\t= 'f';\n\t\t$value \t\t\t\t= \"={$c->f}\";\n\t\t$calculatedValue \t= self::$castBaseType($c);\n\n\t\t// Shared formula?\n\t\tif (isset($c->f['t']) && strtolower((string)$c->f['t']) == 'shared') {\n//\t\t\techo 'SHARED FORMULA', PHP_EOL;\n\t\t\t$instance = (string)$c->f['si'];\n\n//\t\t\techo 'Instance ID = ', $instance, PHP_EOL;\n//\n//\t\t\techo 'Shared Formula Array:', PHP_EOL;\n//\t\t\tprint_r($sharedFormulas);\n\t\t\tif (!isset($sharedFormulas[(string)$c->f['si']])) {\n//\t\t\t\techo 'SETTING NEW SHARED FORMULA', PHP_EOL;\n//\t\t\t\techo 'Master is ', $r, PHP_EOL;\n//\t\t\t\techo 'Formula is ', $value, PHP_EOL;\n\t\t\t\t$sharedFormulas[$instance] = array(\t'master' => $r,\n\t\t\t\t\t\t\t\t\t\t\t\t\t'formula' => $value\n\t\t\t\t\t\t\t\t\t\t\t\t  );\n//\t\t\t\techo 'New Shared Formula Array:', PHP_EOL;\n//\t\t\t\tprint_r($sharedFormulas);\n\t\t\t} else {\n//\t\t\t\techo 'GETTING SHARED FORMULA', PHP_EOL;\n//\t\t\t\techo 'Master is ', $sharedFormulas[$instance]['master'], PHP_EOL;\n//\t\t\t\techo 'Formula is ', $sharedFormulas[$instance]['formula'], PHP_EOL;\n\t\t\t\t$master = PHPExcel_Cell::coordinateFromString($sharedFormulas[$instance]['master']);\n\t\t\t\t$current = PHPExcel_Cell::coordinateFromString($r);\n\n\t\t\t\t$difference = array(0, 0);\n\t\t\t\t$difference[0] = PHPExcel_Cell::columnIndexFromString($current[0]) - PHPExcel_Cell::columnIndexFromString($master[0]);\n\t\t\t\t$difference[1] = $current[1] - $master[1];\n\n\t\t\t\t$value = $this->_referenceHelper->updateFormulaReferences(\t$sharedFormulas[$instance]['formula'],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'A1',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$difference[0],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t$difference[1]\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t );\n//\t\t\t\techo 'Adjusted Formula is ', $value, PHP_EOL;\n\t\t\t}\n\t\t}\n\t}\n\n\n\tpublic function _getFromZipArchive($archive, $fileName = '')\n\t{\n\t\t// Root-relative paths\n\t\tif (strpos($fileName, '//') !== false)\n\t\t{\n\t\t\t$fileName = substr($fileName, strpos($fileName, '//') + 1);\n\t\t}\n\t\t$fileName = PHPExcel_Shared_File::realpath($fileName);\n\n\t\t// Apache POI fixes\n\t\t$contents = $archive->getFromName($fileName);\n\t\tif ($contents === false)\n\t\t{\n\t\t\t$contents = $archive->getFromName(substr($fileName, 1));\n\t\t}\n\n\t\treturn $contents;\n\t}\n\n\n\t/**\n\t * Loads PHPExcel from file\n\t *\n\t * @param \tstring \t\t$pFilename\n     * @return  PHPExcel\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function load($pFilename)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n\t\t// Initialisations\n\t\t$excel = new PHPExcel;\n\t\t$excel->removeSheetByIndex(0);\n\t\tif (!$this->_readDataOnly) {\n\t\t\t$excel->removeCellStyleXfByIndex(0); // remove the default style\n\t\t\t$excel->removeCellXfByIndex(0); // remove the default style\n\t\t}\n\n        $zipClass = PHPExcel_Settings::getZipClass();\n\n\t\t$zip = new $zipClass;\n\t\t$zip->open($pFilename);\n\n\t\t//\tRead the theme first, because we need the colour scheme when reading the styles\n\t\t$wbRels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"xl/_rels/workbook.xml.rels\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships\");\n\t\tforeach ($wbRels->Relationship as $rel) {\n\t\t\tswitch ($rel[\"Type\"]) {\n\t\t\t\tcase \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme\":\n\t\t\t\t\t$themeOrderArray = array('lt1','dk1','lt2','dk2');\n\t\t\t\t\t$themeOrderAdditional = count($themeOrderArray);\n\n\t\t\t\t\t$xmlTheme = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"xl/{$rel['Target']}\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t\t\t\tif (is_object($xmlTheme)) {\n\t\t\t\t\t\t$xmlThemeName = $xmlTheme->attributes();\n\t\t\t\t\t\t$xmlTheme = $xmlTheme->children(\"http://schemas.openxmlformats.org/drawingml/2006/main\");\n\t\t\t\t\t\t$themeName = (string)$xmlThemeName['name'];\n\n\t\t\t\t\t\t$colourScheme = $xmlTheme->themeElements->clrScheme->attributes();\n\t\t\t\t\t\t$colourSchemeName = (string)$colourScheme['name'];\n\t\t\t\t\t\t$colourScheme = $xmlTheme->themeElements->clrScheme->children(\"http://schemas.openxmlformats.org/drawingml/2006/main\");\n\n\t\t\t\t\t\t$themeColours = array();\n\t\t\t\t\t\tforeach ($colourScheme as $k => $xmlColour) {\n\t\t\t\t\t\t\t$themePos = array_search($k,$themeOrderArray);\n\t\t\t\t\t\t\tif ($themePos === false) {\n\t\t\t\t\t\t\t\t$themePos = $themeOrderAdditional++;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (isset($xmlColour->sysClr)) {\n\t\t\t\t\t\t\t\t$xmlColourData = $xmlColour->sysClr->attributes();\n\t\t\t\t\t\t\t\t$themeColours[$themePos] = $xmlColourData['lastClr'];\n\t\t\t\t\t\t\t} elseif (isset($xmlColour->srgbClr)) {\n\t\t\t\t\t\t\t\t$xmlColourData = $xmlColour->srgbClr->attributes();\n\t\t\t\t\t\t\t\t$themeColours[$themePos] = $xmlColourData['val'];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tself::$_theme = new PHPExcel_Reader_Excel2007_Theme($themeName,$colourSchemeName,$themeColours);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t$rels = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"_rels/.rels\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships\");\n\t\tforeach ($rels->Relationship as $rel) {\n\t\t\tswitch ($rel[\"Type\"]) {\n\t\t\t\tcase \"http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties\":\n\t\t\t\t\t$xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"{$rel['Target']}\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t\t\t\tif (is_object($xmlCore)) {\n\t\t\t\t\t\t$xmlCore->registerXPathNamespace(\"dc\", \"http://purl.org/dc/elements/1.1/\");\n\t\t\t\t\t\t$xmlCore->registerXPathNamespace(\"dcterms\", \"http://purl.org/dc/terms/\");\n\t\t\t\t\t\t$xmlCore->registerXPathNamespace(\"cp\", \"http://schemas.openxmlformats.org/package/2006/metadata/core-properties\");\n\t\t\t\t\t\t$docProps = $excel->getProperties();\n\t\t\t\t\t\t$docProps->setCreator((string) self::array_item($xmlCore->xpath(\"dc:creator\")));\n\t\t\t\t\t\t$docProps->setLastModifiedBy((string) self::array_item($xmlCore->xpath(\"cp:lastModifiedBy\")));\n\t\t\t\t\t\t$docProps->setCreated(strtotime(self::array_item($xmlCore->xpath(\"dcterms:created\")))); //! respect xsi:type\n\t\t\t\t\t\t$docProps->setModified(strtotime(self::array_item($xmlCore->xpath(\"dcterms:modified\")))); //! respect xsi:type\n\t\t\t\t\t\t$docProps->setTitle((string) self::array_item($xmlCore->xpath(\"dc:title\")));\n\t\t\t\t\t\t$docProps->setDescription((string) self::array_item($xmlCore->xpath(\"dc:description\")));\n\t\t\t\t\t\t$docProps->setSubject((string) self::array_item($xmlCore->xpath(\"dc:subject\")));\n\t\t\t\t\t\t$docProps->setKeywords((string) self::array_item($xmlCore->xpath(\"cp:keywords\")));\n\t\t\t\t\t\t$docProps->setCategory((string) self::array_item($xmlCore->xpath(\"cp:category\")));\n\t\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\t\tcase \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties\":\n\t\t\t\t\t$xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"{$rel['Target']}\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t\t\t\tif (is_object($xmlCore)) {\n\t\t\t\t\t\t$docProps = $excel->getProperties();\n\t\t\t\t\t\tif (isset($xmlCore->Company))\n\t\t\t\t\t\t\t$docProps->setCompany((string) $xmlCore->Company);\n\t\t\t\t\t\tif (isset($xmlCore->Manager))\n\t\t\t\t\t\t\t$docProps->setManager((string) $xmlCore->Manager);\n\t\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\t\tcase \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties\":\n\t\t\t\t\t$xmlCore = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"{$rel['Target']}\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t\t\t\tif (is_object($xmlCore)) {\n\t\t\t\t\t\t$docProps = $excel->getProperties();\n\t\t\t\t\t\tforeach ($xmlCore as $xmlProperty) {\n\t\t\t\t\t\t\t$cellDataOfficeAttributes = $xmlProperty->attributes();\n\t\t\t\t\t\t\tif (isset($cellDataOfficeAttributes['name'])) {\n\t\t\t\t\t\t\t\t$propertyName = (string) $cellDataOfficeAttributes['name'];\n\t\t\t\t\t\t\t\t$cellDataOfficeChildren = $xmlProperty->children('http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes');\n\t\t\t\t\t\t\t\t$attributeType = $cellDataOfficeChildren->getName();\n\t\t\t\t\t\t\t\t$attributeValue = (string) $cellDataOfficeChildren->{$attributeType};\n\t\t\t\t\t\t\t\t$attributeValue = PHPExcel_DocumentProperties::convertProperty($attributeValue,$attributeType);\n\t\t\t\t\t\t\t\t$attributeType = PHPExcel_DocumentProperties::convertPropertyType($attributeType);\n\t\t\t\t\t\t\t\t$docProps->setCustomProperty($propertyName,$attributeValue,$attributeType);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\t//Ribbon\n\t\t\t\tcase \"http://schemas.microsoft.com/office/2006/relationships/ui/extensibility\":\n\t\t\t\t\t$customUI = $rel['Target'];\n\t\t\t\t\tif(!is_null($customUI)){\n\t\t\t\t\t\t$this->_readRibbon($excel, $customUI, $zip);\n\t\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t\tcase \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument\":\n\t\t\t\t\t$dir = dirname($rel[\"Target\"]);\n\t\t\t\t\t$relsWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"$dir/_rels/\" . basename($rel[\"Target\"]) . \".rels\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());  //~ http://schemas.openxmlformats.org/package/2006/relationships\");\n\t\t\t\t\t$relsWorkbook->registerXPathNamespace(\"rel\", \"http://schemas.openxmlformats.org/package/2006/relationships\");\n\n\t\t\t\t\t$sharedStrings = array();\n\t\t\t\t\t$xpath = self::array_item($relsWorkbook->xpath(\"rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']\"));\n\t\t\t\t\t$xmlStrings = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"$dir/$xpath[Target]\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());  //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main\");\n\t\t\t\t\tif (isset($xmlStrings) && isset($xmlStrings->si)) {\n\t\t\t\t\t\tforeach ($xmlStrings->si as $val) {\n\t\t\t\t\t\t\tif (isset($val->t)) {\n\t\t\t\t\t\t\t\t$sharedStrings[] = PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $val->t );\n\t\t\t\t\t\t\t} elseif (isset($val->r)) {\n\t\t\t\t\t\t\t\t$sharedStrings[] = $this->_parseRichText($val);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$worksheets = array();\n                    $macros = $customUI = NULL;\n\t\t\t\t\tforeach ($relsWorkbook->Relationship as $ele) {\n\t\t\t\t\t\tswitch($ele['Type']){\n\t\t\t\t\t\tcase \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet\":\n\t\t\t\t\t\t\t$worksheets[(string) $ele[\"Id\"]] = $ele[\"Target\"];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t// a vbaProject ? (: some macros)\n\t\t\t\t\t\tcase \"http://schemas.microsoft.com/office/2006/relationships/vbaProject\":\n\t\t\t\t\t\t\t$macros = $ele[\"Target\"];\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif(!is_null($macros)){\n\t\t\t\t\t\t$macrosCode = $this->_getFromZipArchive($zip, 'xl/vbaProject.bin');//vbaProject.bin always in 'xl' dir and always named vbaProject.bin\n\t\t\t\t\t\tif($macrosCode !== false){\n\t\t\t\t\t\t\t$excel->setMacrosCode($macrosCode);\n\t\t\t\t\t\t\t$excel->setHasMacros(true);\n\t\t\t\t\t\t\t//short-circuit : not reading vbaProject.bin.rel to get Signature =>allways vbaProjectSignature.bin in 'xl' dir\n\t\t\t\t\t\t\t$Certificate = $this->_getFromZipArchive($zip, 'xl/vbaProjectSignature.bin');\n\t\t\t\t\t\t\tif($Certificate !== false)\n\t\t\t\t\t\t\t\t$excel->setMacrosCertificate($Certificate);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t$styles \t= array();\n\t\t\t\t\t$cellStyles = array();\n\t\t\t\t\t$xpath = self::array_item($relsWorkbook->xpath(\"rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']\"));\n\t\t\t\t\t$xmlStyles = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"$dir/$xpath[Target]\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main\");\n\t\t\t\t\t$numFmts = null;\n\t\t\t\t\tif ($xmlStyles && $xmlStyles->numFmts[0]) {\n\t\t\t\t\t\t$numFmts = $xmlStyles->numFmts[0];\n\t\t\t\t\t}\n\t\t\t\t\tif (isset($numFmts) && ($numFmts !== NULL)) {\n\t\t\t\t\t\t$numFmts->registerXPathNamespace(\"sml\", \"http://schemas.openxmlformats.org/spreadsheetml/2006/main\");\n\t\t\t\t\t}\n\t\t\t\t\tif (!$this->_readDataOnly && $xmlStyles) {\n\t\t\t\t\t\tforeach ($xmlStyles->cellXfs->xf as $xf) {\n\t\t\t\t\t\t\t$numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;\n\n\t\t\t\t\t\t\tif ($xf[\"numFmtId\"]) {\n\t\t\t\t\t\t\t\tif (isset($numFmts)) {\n\t\t\t\t\t\t\t\t\t$tmpNumFmt = self::array_item($numFmts->xpath(\"sml:numFmt[@numFmtId=$xf[numFmtId]]\"));\n\n\t\t\t\t\t\t\t\t\tif (isset($tmpNumFmt[\"formatCode\"])) {\n\t\t\t\t\t\t\t\t\t\t$numFmt = (string) $tmpNumFmt[\"formatCode\"];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ((int)$xf[\"numFmtId\"] < 164) {\n\t\t\t\t\t\t\t\t\t$numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf[\"numFmtId\"]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n                            $quotePrefix = false;\n\t\t\t\t\t\t\tif (isset($xf[\"quotePrefix\"])) {\n                                $quotePrefix = (boolean) $xf[\"quotePrefix\"];\n                            }\n\t\t\t\t\t\t\t//$numFmt = str_replace('mm', 'i', $numFmt);\n\t\t\t\t\t\t\t//$numFmt = str_replace('h', 'H', $numFmt);\n\n\t\t\t\t\t\t\t$style = (object) array(\n\t\t\t\t\t\t\t\t\"numFmt\" => $numFmt,\n\t\t\t\t\t\t\t\t\"font\" => $xmlStyles->fonts->font[intval($xf[\"fontId\"])],\n\t\t\t\t\t\t\t\t\"fill\" => $xmlStyles->fills->fill[intval($xf[\"fillId\"])],\n\t\t\t\t\t\t\t\t\"border\" => $xmlStyles->borders->border[intval($xf[\"borderId\"])],\n\t\t\t\t\t\t\t\t\"alignment\" => $xf->alignment,\n\t\t\t\t\t\t\t\t\"protection\" => $xf->protection,\n\t\t\t\t\t\t\t\t\"quotePrefix\" => $quotePrefix,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t$styles[] = $style;\n\n\t\t\t\t\t\t\t// add style to cellXf collection\n\t\t\t\t\t\t\t$objStyle = new PHPExcel_Style;\n\t\t\t\t\t\t\tself::_readStyle($objStyle, $style);\n\t\t\t\t\t\t\t$excel->addCellXf($objStyle);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tforeach ($xmlStyles->cellStyleXfs->xf as $xf) {\n\t\t\t\t\t\t\t$numFmt = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;\n\t\t\t\t\t\t\tif ($numFmts && $xf[\"numFmtId\"]) {\n\t\t\t\t\t\t\t\t$tmpNumFmt = self::array_item($numFmts->xpath(\"sml:numFmt[@numFmtId=$xf[numFmtId]]\"));\n\t\t\t\t\t\t\t\tif (isset($tmpNumFmt[\"formatCode\"])) {\n\t\t\t\t\t\t\t\t\t$numFmt = (string) $tmpNumFmt[\"formatCode\"];\n\t\t\t\t\t\t\t\t} else if ((int)$xf[\"numFmtId\"] < 165) {\n\t\t\t\t\t\t\t\t\t$numFmt = PHPExcel_Style_NumberFormat::builtInFormatCode((int)$xf[\"numFmtId\"]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t$cellStyle = (object) array(\n\t\t\t\t\t\t\t\t\"numFmt\" => $numFmt,\n\t\t\t\t\t\t\t\t\"font\" => $xmlStyles->fonts->font[intval($xf[\"fontId\"])],\n\t\t\t\t\t\t\t\t\"fill\" => $xmlStyles->fills->fill[intval($xf[\"fillId\"])],\n\t\t\t\t\t\t\t\t\"border\" => $xmlStyles->borders->border[intval($xf[\"borderId\"])],\n\t\t\t\t\t\t\t\t\"alignment\" => $xf->alignment,\n\t\t\t\t\t\t\t\t\"protection\" => $xf->protection,\n\t\t\t\t\t\t\t\t\"quotePrefix\" => $quotePrefix,\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t$cellStyles[] = $cellStyle;\n\n\t\t\t\t\t\t\t// add style to cellStyleXf collection\n\t\t\t\t\t\t\t$objStyle = new PHPExcel_Style;\n\t\t\t\t\t\t\tself::_readStyle($objStyle, $cellStyle);\n\t\t\t\t\t\t\t$excel->addCellStyleXf($objStyle);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$dxfs = array();\n\t\t\t\t\tif (!$this->_readDataOnly && $xmlStyles) {\n\t\t\t\t\t\t//\tConditional Styles\n\t\t\t\t\t\tif ($xmlStyles->dxfs) {\n\t\t\t\t\t\t\tforeach ($xmlStyles->dxfs->dxf as $dxf) {\n\t\t\t\t\t\t\t\t$style = new PHPExcel_Style(FALSE, TRUE);\n\t\t\t\t\t\t\t\tself::_readStyle($style, $dxf);\n\t\t\t\t\t\t\t\t$dxfs[] = $style;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//\tCell Styles\n\t\t\t\t\t\tif ($xmlStyles->cellStyles) {\n\t\t\t\t\t\t\tforeach ($xmlStyles->cellStyles->cellStyle as $cellStyle) {\n\t\t\t\t\t\t\t\tif (intval($cellStyle['builtinId']) == 0) {\n\t\t\t\t\t\t\t\t\tif (isset($cellStyles[intval($cellStyle['xfId'])])) {\n\t\t\t\t\t\t\t\t\t\t// Set default style\n\t\t\t\t\t\t\t\t\t\t$style = new PHPExcel_Style;\n\t\t\t\t\t\t\t\t\t\tself::_readStyle($style, $cellStyles[intval($cellStyle['xfId'])]);\n\n\t\t\t\t\t\t\t\t\t\t// normal style, currently not using it for anything\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$xmlWorkbook = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"{$rel['Target']}\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());  //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main\");\n\n\t\t\t\t\t// Set base date\n\t\t\t\t\tif ($xmlWorkbook->workbookPr) {\n\t\t\t\t\t\tPHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900);\n\t\t\t\t\t\tif (isset($xmlWorkbook->workbookPr['date1904'])) {\n\t\t\t\t\t\t\tif (self::boolean((string) $xmlWorkbook->workbookPr['date1904'])) {\n\t\t\t\t\t\t\t\tPHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$sheetId = 0; // keep track of new sheet id in final workbook\n\t\t\t\t\t$oldSheetId = -1; // keep track of old sheet id in final workbook\n\t\t\t\t\t$countSkippedSheets = 0; // keep track of number of skipped sheets\n\t\t\t\t\t$mapSheetId = array(); // mapping of sheet ids from old to new\n\n\n\t\t\t\t\t$charts = $chartDetails = array();\n\n\t\t\t\t\tif ($xmlWorkbook->sheets) {\n\t\t\t\t\t\tforeach ($xmlWorkbook->sheets->sheet as $eleSheet) {\n\t\t\t\t\t\t\t++$oldSheetId;\n\n\t\t\t\t\t\t\t// Check if sheet should be skipped\n\t\t\t\t\t\t\tif (isset($this->_loadSheetsOnly) && !in_array((string) $eleSheet[\"name\"], $this->_loadSheetsOnly)) {\n\t\t\t\t\t\t\t\t++$countSkippedSheets;\n\t\t\t\t\t\t\t\t$mapSheetId[$oldSheetId] = null;\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Map old sheet id in original workbook to new sheet id.\n\t\t\t\t\t\t\t// They will differ if loadSheetsOnly() is being used\n\t\t\t\t\t\t\t$mapSheetId[$oldSheetId] = $oldSheetId - $countSkippedSheets;\n\n\t\t\t\t\t\t\t// Load sheet\n\t\t\t\t\t\t\t$docSheet = $excel->createSheet();\n\t\t\t\t\t\t\t//\tUse false for $updateFormulaCellReferences to prevent adjustment of worksheet\n\t\t\t\t\t\t\t//\t\treferences in formula cells... during the load, all formulae should be correct,\n\t\t\t\t\t\t\t//\t\tand we're simply bringing the worksheet name in line with the formula, not the\n\t\t\t\t\t\t\t//\t\treverse\n\t\t\t\t\t\t\t$docSheet->setTitle((string) $eleSheet[\"name\"],false);\n\t\t\t\t\t\t\t$fileWorksheet = $worksheets[(string) self::array_item($eleSheet->attributes(\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"), \"id\")];\n\t\t\t\t\t\t\t$xmlSheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"$dir/$fileWorksheet\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());  //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main\");\n\n\t\t\t\t\t\t\t$sharedFormulas = array();\n\n\t\t\t\t\t\t\tif (isset($eleSheet[\"state\"]) && (string) $eleSheet[\"state\"] != '') {\n\t\t\t\t\t\t\t\t$docSheet->setSheetState( (string) $eleSheet[\"state\"] );\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (isset($xmlSheet->sheetViews) && isset($xmlSheet->sheetViews->sheetView)) {\n\t\t\t\t\t\t\t    if (isset($xmlSheet->sheetViews->sheetView['zoomScale'])) {\n\t\t\t\t\t\t\t\t    $docSheet->getSheetView()->setZoomScale( intval($xmlSheet->sheetViews->sheetView['zoomScale']) );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t    if (isset($xmlSheet->sheetViews->sheetView['zoomScaleNormal'])) {\n\t\t\t\t\t\t\t\t    $docSheet->getSheetView()->setZoomScaleNormal( intval($xmlSheet->sheetViews->sheetView['zoomScaleNormal']) );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t    if (isset($xmlSheet->sheetViews->sheetView['view'])) {\n\t\t\t\t\t\t\t\t    $docSheet->getSheetView()->setView((string) $xmlSheet->sheetViews->sheetView['view']);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->sheetViews->sheetView['showGridLines'])) {\n\t\t\t\t\t\t\t\t\t$docSheet->setShowGridLines(self::boolean((string)$xmlSheet->sheetViews->sheetView['showGridLines']));\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->sheetViews->sheetView['showRowColHeaders'])) {\n\t\t\t\t\t\t\t\t\t$docSheet->setShowRowColHeaders(self::boolean((string)$xmlSheet->sheetViews->sheetView['showRowColHeaders']));\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->sheetViews->sheetView['rightToLeft'])) {\n\t\t\t\t\t\t\t\t\t$docSheet->setRightToLeft(self::boolean((string)$xmlSheet->sheetViews->sheetView['rightToLeft']));\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->sheetViews->sheetView->pane)) {\n\t\t\t\t\t\t\t\t    if (isset($xmlSheet->sheetViews->sheetView->pane['topLeftCell'])) {\n\t\t\t\t\t\t\t\t        $docSheet->freezePane( (string)$xmlSheet->sheetViews->sheetView->pane['topLeftCell'] );\n\t\t\t\t\t\t\t\t    } else {\n\t\t\t\t\t\t\t\t        $xSplit = 0;\n\t\t\t\t\t\t\t\t        $ySplit = 0;\n\n\t\t\t\t\t\t\t\t        if (isset($xmlSheet->sheetViews->sheetView->pane['xSplit'])) {\n\t\t\t\t\t\t\t\t            $xSplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['xSplit']);\n\t\t\t\t\t\t\t\t        }\n\n\t\t\t\t\t\t\t\t    \tif (isset($xmlSheet->sheetViews->sheetView->pane['ySplit'])) {\n\t\t\t\t\t\t\t\t            $ySplit = 1 + intval($xmlSheet->sheetViews->sheetView->pane['ySplit']);\n\t\t\t\t\t\t\t\t        }\n\n\t\t\t\t\t\t\t\t        $docSheet->freezePaneByColumnAndRow($xSplit, $ySplit);\n\t\t\t\t\t\t\t\t    }\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->sheetViews->sheetView->selection)) {\n\t\t\t\t\t\t\t\t\tif (isset($xmlSheet->sheetViews->sheetView->selection['sqref'])) {\n\t\t\t\t\t\t\t\t\t\t$sqref = (string)$xmlSheet->sheetViews->sheetView->selection['sqref'];\n\t\t\t\t\t\t\t\t\t\t$sqref = explode(' ', $sqref);\n\t\t\t\t\t\t\t\t\t\t$sqref = $sqref[0];\n\t\t\t\t\t\t\t\t\t\t$docSheet->setSelectedCells($sqref);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->tabColor)) {\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->sheetPr->tabColor['rgb'])) {\n\t\t\t\t\t\t\t\t\t$docSheet->getTabColor()->setARGB( (string)$xmlSheet->sheetPr->tabColor['rgb'] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr['codeName'])) {\n\t\t\t\t\t\t\t\t$docSheet->setCodeName((string) $xmlSheet->sheetPr['codeName']);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->outlinePr)) {\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->sheetPr->outlinePr['summaryRight']) &&\n\t\t\t\t\t\t\t\t\t!self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryRight'])) {\n\t\t\t\t\t\t\t\t\t$docSheet->setShowSummaryRight(FALSE);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$docSheet->setShowSummaryRight(TRUE);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->sheetPr->outlinePr['summaryBelow']) &&\n\t\t\t\t\t\t\t\t\t!self::boolean((string) $xmlSheet->sheetPr->outlinePr['summaryBelow'])) {\n\t\t\t\t\t\t\t\t\t$docSheet->setShowSummaryBelow(FALSE);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$docSheet->setShowSummaryBelow(TRUE);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (isset($xmlSheet->sheetPr) && isset($xmlSheet->sheetPr->pageSetUpPr)) {\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->sheetPr->pageSetUpPr['fitToPage']) &&\n\t\t\t\t\t\t\t\t\t!self::boolean((string) $xmlSheet->sheetPr->pageSetUpPr['fitToPage'])) {\n\t\t\t\t\t\t\t\t\t$docSheet->getPageSetup()->setFitToPage(FALSE);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$docSheet->getPageSetup()->setFitToPage(TRUE);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (isset($xmlSheet->sheetFormatPr)) {\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->sheetFormatPr['customHeight']) &&\n\t\t\t\t\t\t\t\t\tself::boolean((string) $xmlSheet->sheetFormatPr['customHeight']) &&\n\t\t\t\t\t\t\t\t\tisset($xmlSheet->sheetFormatPr['defaultRowHeight'])) {\n\t\t\t\t\t\t\t\t\t$docSheet->getDefaultRowDimension()->setRowHeight( (float)$xmlSheet->sheetFormatPr['defaultRowHeight'] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->sheetFormatPr['defaultColWidth'])) {\n\t\t\t\t\t\t\t\t\t$docSheet->getDefaultColumnDimension()->setWidth( (float)$xmlSheet->sheetFormatPr['defaultColWidth'] );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->sheetFormatPr['zeroHeight']) &&\n\t\t\t\t\t\t\t\t\t((string)$xmlSheet->sheetFormatPr['zeroHeight'] == '1')) {\n\t\t\t\t\t\t\t\t\t$docSheet->getDefaultRowDimension()->setZeroHeight(true);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (isset($xmlSheet->cols) && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\tforeach ($xmlSheet->cols->col as $col) {\n                                    for ($i = intval($col[\"min\"]) - 1; $i < intval($col[\"max\"]); ++$i) {\n\t\t\t\t\t\t\t\t\t\tif ($col[\"style\"] && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\t\t\t\t$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setXfIndex(intval($col[\"style\"]));\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif (self::boolean($col[\"bestFit\"])) {\n\t\t\t\t\t\t\t\t\t\t\t//$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setAutoSize(TRUE);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif (self::boolean($col[\"hidden\"])) {\n                                        // echo PHPExcel_Cell::stringFromColumnIndex($i),': HIDDEN COLUMN',PHP_EOL;\n\t\t\t\t\t\t\t\t\t\t\t$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setVisible(FALSE);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif (self::boolean($col[\"collapsed\"])) {\n\t\t\t\t\t\t\t\t\t\t\t$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setCollapsed(TRUE);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif ($col[\"outlineLevel\"] > 0) {\n\t\t\t\t\t\t\t\t\t\t\t$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setOutlineLevel(intval($col[\"outlineLevel\"]));\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t$docSheet->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($i))->setWidth(floatval($col[\"width\"]));\n\n\t\t\t\t\t\t\t\t\t\tif (intval($col[\"max\"]) == 16384) {\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (isset($xmlSheet->printOptions) && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\tif (self::boolean((string) $xmlSheet->printOptions['gridLinesSet'])) {\n\t\t\t\t\t\t\t\t\t$docSheet->setShowGridlines(TRUE);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (self::boolean((string) $xmlSheet->printOptions['gridLines'])) {\n\t\t\t\t\t\t\t\t\t$docSheet->setPrintGridlines(TRUE);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (self::boolean((string) $xmlSheet->printOptions['horizontalCentered'])) {\n\t\t\t\t\t\t\t\t\t$docSheet->getPageSetup()->setHorizontalCentered(TRUE);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (self::boolean((string) $xmlSheet->printOptions['verticalCentered'])) {\n\t\t\t\t\t\t\t\t\t$docSheet->getPageSetup()->setVerticalCentered(TRUE);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) {\n\t\t\t\t\t\t\t\tforeach ($xmlSheet->sheetData->row as $row) {\n\t\t\t\t\t\t\t\t\tif ($row[\"ht\"] && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\t\t\t$docSheet->getRowDimension(intval($row[\"r\"]))->setRowHeight(floatval($row[\"ht\"]));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (self::boolean($row[\"hidden\"]) && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\t\t\t$docSheet->getRowDimension(intval($row[\"r\"]))->setVisible(FALSE);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif (self::boolean($row[\"collapsed\"])) {\n\t\t\t\t\t\t\t\t\t\t$docSheet->getRowDimension(intval($row[\"r\"]))->setCollapsed(TRUE);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif ($row[\"outlineLevel\"] > 0) {\n\t\t\t\t\t\t\t\t\t\t$docSheet->getRowDimension(intval($row[\"r\"]))->setOutlineLevel(intval($row[\"outlineLevel\"]));\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tif ($row[\"s\"] && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\t\t\t$docSheet->getRowDimension(intval($row[\"r\"]))->setXfIndex(intval($row[\"s\"]));\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tforeach ($row->c as $c) {\n\t\t\t\t\t\t\t\t\t\t$r \t\t\t\t\t= (string) $c[\"r\"];\n\t\t\t\t\t\t\t\t\t\t$cellDataType \t\t= (string) $c[\"t\"];\n\t\t\t\t\t\t\t\t\t\t$value\t\t\t\t= null;\n\t\t\t\t\t\t\t\t\t\t$calculatedValue \t= null;\n\n\t\t\t\t\t\t\t\t\t\t// Read cell?\n\t\t\t\t\t\t\t\t\t\tif ($this->getReadFilter() !== NULL) {\n\t\t\t\t\t\t\t\t\t\t\t$coordinates = PHPExcel_Cell::coordinateFromString($r);\n\n\t\t\t\t\t\t\t\t\t\t\tif (!$this->getReadFilter()->readCell($coordinates[0], $coordinates[1], $docSheet->getTitle())) {\n\t\t\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\n\t//\t\t\t\t\t\t\t\t\techo 'Reading cell ', $coordinates[0], $coordinates[1], PHP_EOL;\n\t//\t\t\t\t\t\t\t\t\tprint_r($c);\n\t//\t\t\t\t\t\t\t\t\techo PHP_EOL;\n\t//\t\t\t\t\t\t\t\t\techo 'Cell Data Type is ', $cellDataType, ': ';\n\t//\n\t\t\t\t\t\t\t\t\t\t// Read cell!\n\t\t\t\t\t\t\t\t\t\tswitch ($cellDataType) {\n\t\t\t\t\t\t\t\t\t\t\tcase \"s\":\n\t//\t\t\t\t\t\t\t\t\t\t\techo 'String', PHP_EOL;\n\t\t\t\t\t\t\t\t\t\t\t\tif ((string)$c->v != '') {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$value = $sharedStrings[intval($c->v)];\n\n\t\t\t\t\t\t\t\t\t\t\t\t\tif ($value instanceof PHPExcel_RichText) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$value = clone $value;\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$value = '';\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"b\":\n\t//\t\t\t\t\t\t\t\t\t\t\techo 'Boolean', PHP_EOL;\n\t\t\t\t\t\t\t\t\t\t\t\tif (!isset($c->f)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$value = self::_castToBool($c);\n\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t// Formula\n\t\t\t\t\t\t\t\t\t\t\t\t\t$this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToBool');\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (isset($c->f['t'])) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$att = array();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$att = $c->f;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$docSheet->getCell($r)->setFormulaAttributes($att);\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t//\t\t\t\t\t\t\t\t\t\t\t\techo '$calculatedValue = ', $calculatedValue, PHP_EOL;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"inlineStr\":\n\t//\t\t\t\t\t\t\t\t\t\t\techo 'Inline String', PHP_EOL;\n\t\t\t\t\t\t\t\t\t\t\t\t$value = $this->_parseRichText($c->is);\n\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase \"e\":\n\t//\t\t\t\t\t\t\t\t\t\t\techo 'Error', PHP_EOL;\n\t\t\t\t\t\t\t\t\t\t\t\tif (!isset($c->f)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$value = self::_castToError($c);\n\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t// Formula\n\t\t\t\t\t\t\t\t\t\t\t\t\t$this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToError');\n\t//\t\t\t\t\t\t\t\t\t\t\t\techo '$calculatedValue = ', $calculatedValue, PHP_EOL;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t\t\t\tdefault:\n\t//\t\t\t\t\t\t\t\t\t\t\techo 'Default', PHP_EOL;\n\t\t\t\t\t\t\t\t\t\t\t\tif (!isset($c->f)) {\n\t//\t\t\t\t\t\t\t\t\t\t\t\techo 'Not a Formula', PHP_EOL;\n\t\t\t\t\t\t\t\t\t\t\t\t\t$value = self::_castToString($c);\n\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t//\t\t\t\t\t\t\t\t\t\t\t\techo 'Treat as Formula', PHP_EOL;\n\t\t\t\t\t\t\t\t\t\t\t\t\t// Formula\n\t\t\t\t\t\t\t\t\t\t\t\t\t$this->_castToFormula($c,$r,$cellDataType,$value,$calculatedValue,$sharedFormulas,'_castToString');\n\t//\t\t\t\t\t\t\t\t\t\t\t\techo '$calculatedValue = ', $calculatedValue, PHP_EOL;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t//\t\t\t\t\t\t\t\t\techo 'Value is ', $value, PHP_EOL;\n\n\t\t\t\t\t\t\t\t\t\t// Check for numeric values\n\t\t\t\t\t\t\t\t\t\tif (is_numeric($value) && $cellDataType != 's') {\n\t\t\t\t\t\t\t\t\t\t\tif ($value == (int)$value) $value = (int)$value;\n\t\t\t\t\t\t\t\t\t\t\telseif ($value == (float)$value) $value = (float)$value;\n\t\t\t\t\t\t\t\t\t\t\telseif ($value == (double)$value) $value = (double)$value;\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Rich text?\n\t\t\t\t\t\t\t\t\t\tif ($value instanceof PHPExcel_RichText && $this->_readDataOnly) {\n\t\t\t\t\t\t\t\t\t\t\t$value = $value->getPlainText();\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t$cell = $docSheet->getCell($r);\n\t\t\t\t\t\t\t\t\t\t// Assign value\n\t\t\t\t\t\t\t\t\t\tif ($cellDataType != '') {\n\t\t\t\t\t\t\t\t\t\t\t$cell->setValueExplicit($value, $cellDataType);\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t$cell->setValue($value);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif ($calculatedValue !== NULL) {\n\t\t\t\t\t\t\t\t\t\t\t$cell->setCalculatedValue($calculatedValue);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t// Style information?\n\t\t\t\t\t\t\t\t\t\tif ($c[\"s\"] && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\t\t\t\t// no style index means 0, it seems\n\t\t\t\t\t\t\t\t\t\t\t$cell->setXfIndex(isset($styles[intval($c[\"s\"])]) ?\n\t\t\t\t\t\t\t\t\t\t\t\tintval($c[\"s\"]) : 0);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t$conditionals = array();\n\t\t\t\t\t\t\tif (!$this->_readDataOnly && $xmlSheet && $xmlSheet->conditionalFormatting) {\n\t\t\t\t\t\t\t\tforeach ($xmlSheet->conditionalFormatting as $conditional) {\n\t\t\t\t\t\t\t\t\tforeach ($conditional->cfRule as $cfRule) {\n\t\t\t\t\t\t\t\t\t\tif (\n\t\t\t\t\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\t\t\t\t\t(string)$cfRule[\"type\"] == PHPExcel_Style_Conditional::CONDITION_NONE ||\n\t\t\t\t\t\t\t\t\t\t\t\t(string)$cfRule[\"type\"] == PHPExcel_Style_Conditional::CONDITION_CELLIS ||\n\t\t\t\t\t\t\t\t\t\t\t\t(string)$cfRule[\"type\"] == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT ||\n\t\t\t\t\t\t\t\t\t\t\t\t(string)$cfRule[\"type\"] == PHPExcel_Style_Conditional::CONDITION_EXPRESSION\n\t\t\t\t\t\t\t\t\t\t\t) && isset($dxfs[intval($cfRule[\"dxfId\"])])\n\t\t\t\t\t\t\t\t\t\t) {\n\t\t\t\t\t\t\t\t\t\t\t$conditionals[(string) $conditional[\"sqref\"]][intval($cfRule[\"priority\"])] = $cfRule;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tforeach ($conditionals as $ref => $cfRules) {\n\t\t\t\t\t\t\t\t\tksort($cfRules);\n\t\t\t\t\t\t\t\t\t$conditionalStyles = array();\n\t\t\t\t\t\t\t\t\tforeach ($cfRules as $cfRule) {\n\t\t\t\t\t\t\t\t\t\t$objConditional = new PHPExcel_Style_Conditional();\n\t\t\t\t\t\t\t\t\t\t$objConditional->setConditionType((string)$cfRule[\"type\"]);\n\t\t\t\t\t\t\t\t\t\t$objConditional->setOperatorType((string)$cfRule[\"operator\"]);\n\n\t\t\t\t\t\t\t\t\t\tif ((string)$cfRule[\"text\"] != '') {\n\t\t\t\t\t\t\t\t\t\t\t$objConditional->setText((string)$cfRule[\"text\"]);\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif (count($cfRule->formula) > 1) {\n\t\t\t\t\t\t\t\t\t\t\tforeach ($cfRule->formula as $formula) {\n\t\t\t\t\t\t\t\t\t\t\t\t$objConditional->addCondition((string)$formula);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t$objConditional->addCondition((string)$cfRule->formula);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t$objConditional->setStyle(clone $dxfs[intval($cfRule[\"dxfId\"])]);\n\t\t\t\t\t\t\t\t\t\t$conditionalStyles[] = $objConditional;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Extract all cell references in $ref\n\t\t\t\t\t\t\t\t\t$aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($ref);\n\t\t\t\t\t\t\t\t\tforeach ($aReferences as $reference) {\n\t\t\t\t\t\t\t\t\t\t$docSheet->getStyle($reference)->setConditionalStyles($conditionalStyles);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t$aKeys = array(\"sheet\", \"objects\", \"scenarios\", \"formatCells\", \"formatColumns\", \"formatRows\", \"insertColumns\", \"insertRows\", \"insertHyperlinks\", \"deleteColumns\", \"deleteRows\", \"selectLockedCells\", \"sort\", \"autoFilter\", \"pivotTables\", \"selectUnlockedCells\");\n\t\t\t\t\t\t\tif (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) {\n\t\t\t\t\t\t\t\tforeach ($aKeys as $key) {\n\t\t\t\t\t\t\t\t\t$method = \"set\" . ucfirst($key);\n\t\t\t\t\t\t\t\t\t$docSheet->getProtection()->$method(self::boolean((string) $xmlSheet->sheetProtection[$key]));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (!$this->_readDataOnly && $xmlSheet && $xmlSheet->sheetProtection) {\n\t\t\t\t\t\t\t\t$docSheet->getProtection()->setPassword((string) $xmlSheet->sheetProtection[\"password\"], TRUE);\n\t\t\t\t\t\t\t\tif ($xmlSheet->protectedRanges->protectedRange) {\n\t\t\t\t\t\t\t\t\tforeach ($xmlSheet->protectedRanges->protectedRange as $protectedRange) {\n\t\t\t\t\t\t\t\t\t\t$docSheet->protectCells((string) $protectedRange[\"sqref\"], (string) $protectedRange[\"password\"], true);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ($xmlSheet && $xmlSheet->autoFilter && !$this->_readDataOnly) {\n                                $autoFilterRange = (string) $xmlSheet->autoFilter[\"ref\"];\n                                if (strpos($autoFilterRange, ':') !== false) {\n                                    $autoFilter = $docSheet->getAutoFilter();\n                                    $autoFilter->setRange($autoFilterRange);\n\n                                    foreach ($xmlSheet->autoFilter->filterColumn as $filterColumn) {\n                                        $column = $autoFilter->getColumnByOffset((integer) $filterColumn[\"colId\"]);\n                                        //\tCheck for standard filters\n                                        if ($filterColumn->filters) {\n                                            $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER);\n                                            $filters = $filterColumn->filters;\n                                            if ((isset($filters[\"blank\"])) && ($filters[\"blank\"] == 1)) {\n                                                $column->createRule()->setRule(\n                                                    NULL,\t//\tOperator is undefined, but always treated as EQUAL\n                                                    ''\n                                                )\n                                                ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER);\n                                            }\n                                            //\tStandard filters are always an OR join, so no join rule needs to be set\n                                            //\tEntries can be either filter elements\n                                            foreach ($filters->filter as $filterRule) {\n                                                $column->createRule()->setRule(\n                                                    NULL,\t//\tOperator is undefined, but always treated as EQUAL\n                                                    (string) $filterRule[\"val\"]\n                                                )\n                                                ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER);\n                                            }\n                                            //\tOr Date Group elements\n                                            foreach ($filters->dateGroupItem as $dateGroupItem) {\n                                                $column->createRule()->setRule(\n                                                    NULL,\t//\tOperator is undefined, but always treated as EQUAL\n                                                    array(\n                                                        'year' => (string) $dateGroupItem[\"year\"],\n                                                        'month' => (string) $dateGroupItem[\"month\"],\n                                                        'day' => (string) $dateGroupItem[\"day\"],\n                                                        'hour' => (string) $dateGroupItem[\"hour\"],\n                                                        'minute' => (string) $dateGroupItem[\"minute\"],\n                                                        'second' => (string) $dateGroupItem[\"second\"],\n                                                    ),\n                                                    (string) $dateGroupItem[\"dateTimeGrouping\"]\n                                                )\n                                                ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP);\n                                            }\n                                        }\n                                        //\tCheck for custom filters\n                                        if ($filterColumn->customFilters) {\n                                            $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER);\n                                            $customFilters = $filterColumn->customFilters;\n                                            //\tCustom filters can an AND or an OR join;\n                                            //\t\tand there should only ever be one or two entries\n                                            if ((isset($customFilters[\"and\"])) && ($customFilters[\"and\"] == 1)) {\n                                                $column->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND);\n                                            }\n                                            foreach ($customFilters->customFilter as $filterRule) {\n                                                $column->createRule()->setRule(\n                                                    (string) $filterRule[\"operator\"],\n                                                    (string) $filterRule[\"val\"]\n                                                )\n                                                ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);\n                                            }\n                                        }\n                                        //\tCheck for dynamic filters\n                                        if ($filterColumn->dynamicFilter) {\n                                            $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);\n                                            //\tWe should only ever have one dynamic filter\n                                            foreach ($filterColumn->dynamicFilter as $filterRule) {\n                                                $column->createRule()->setRule(\n                                                    NULL,\t//\tOperator is undefined, but always treated as EQUAL\n                                                    (string) $filterRule[\"val\"],\n                                                    (string) $filterRule[\"type\"]\n                                                )\n                                                ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER);\n                                                if (isset($filterRule[\"val\"])) {\n                                                    $column->setAttribute('val',(string) $filterRule[\"val\"]);\n                                                }\n                                                if (isset($filterRule[\"maxVal\"])) {\n                                                    $column->setAttribute('maxVal',(string) $filterRule[\"maxVal\"]);\n                                                }\n                                            }\n                                        }\n                                        //\tCheck for dynamic filters\n                                        if ($filterColumn->top10) {\n                                            $column->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER);\n                                            //\tWe should only ever have one top10 filter\n                                            foreach ($filterColumn->top10 as $filterRule) {\n                                                $column->createRule()->setRule(\n                                                    (((isset($filterRule[\"percent\"])) && ($filterRule[\"percent\"] == 1))\n                                                        ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT\n                                                        : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE\n                                                    ),\n                                                    (string) $filterRule[\"val\"],\n                                                    (((isset($filterRule[\"top\"])) && ($filterRule[\"top\"] == 1))\n                                                        ? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP\n                                                        : PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM\n                                                    )\n                                                )\n                                                ->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER);\n                                            }\n                                        }\n                                    }\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ($xmlSheet && $xmlSheet->mergeCells && $xmlSheet->mergeCells->mergeCell && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\tforeach ($xmlSheet->mergeCells->mergeCell as $mergeCell) {\n\t\t\t\t\t\t\t\t\t$mergeRef = (string) $mergeCell[\"ref\"];\n\t\t\t\t\t\t\t\t\tif (strpos($mergeRef,':') !== FALSE) {\n\t\t\t\t\t\t\t\t\t\t$docSheet->mergeCells((string) $mergeCell[\"ref\"]);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ($xmlSheet && $xmlSheet->pageMargins && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\t$docPageMargins = $docSheet->getPageMargins();\n\t\t\t\t\t\t\t\t$docPageMargins->setLeft(floatval($xmlSheet->pageMargins[\"left\"]));\n\t\t\t\t\t\t\t\t$docPageMargins->setRight(floatval($xmlSheet->pageMargins[\"right\"]));\n\t\t\t\t\t\t\t\t$docPageMargins->setTop(floatval($xmlSheet->pageMargins[\"top\"]));\n\t\t\t\t\t\t\t\t$docPageMargins->setBottom(floatval($xmlSheet->pageMargins[\"bottom\"]));\n\t\t\t\t\t\t\t\t$docPageMargins->setHeader(floatval($xmlSheet->pageMargins[\"header\"]));\n\t\t\t\t\t\t\t\t$docPageMargins->setFooter(floatval($xmlSheet->pageMargins[\"footer\"]));\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ($xmlSheet && $xmlSheet->pageSetup && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\t$docPageSetup = $docSheet->getPageSetup();\n\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->pageSetup[\"orientation\"])) {\n\t\t\t\t\t\t\t\t\t$docPageSetup->setOrientation((string) $xmlSheet->pageSetup[\"orientation\"]);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->pageSetup[\"paperSize\"])) {\n\t\t\t\t\t\t\t\t\t$docPageSetup->setPaperSize(intval($xmlSheet->pageSetup[\"paperSize\"]));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->pageSetup[\"scale\"])) {\n\t\t\t\t\t\t\t\t\t$docPageSetup->setScale(intval($xmlSheet->pageSetup[\"scale\"]), FALSE);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->pageSetup[\"fitToHeight\"]) && intval($xmlSheet->pageSetup[\"fitToHeight\"]) >= 0) {\n\t\t\t\t\t\t\t\t\t$docPageSetup->setFitToHeight(intval($xmlSheet->pageSetup[\"fitToHeight\"]), FALSE);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->pageSetup[\"fitToWidth\"]) && intval($xmlSheet->pageSetup[\"fitToWidth\"]) >= 0) {\n\t\t\t\t\t\t\t\t\t$docPageSetup->setFitToWidth(intval($xmlSheet->pageSetup[\"fitToWidth\"]), FALSE);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->pageSetup[\"firstPageNumber\"]) && isset($xmlSheet->pageSetup[\"useFirstPageNumber\"]) &&\n\t\t\t\t\t\t\t\t\tself::boolean((string) $xmlSheet->pageSetup[\"useFirstPageNumber\"])) {\n\t\t\t\t\t\t\t\t\t$docPageSetup->setFirstPageNumber(intval($xmlSheet->pageSetup[\"firstPageNumber\"]));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ($xmlSheet && $xmlSheet->headerFooter && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\t$docHeaderFooter = $docSheet->getHeaderFooter();\n\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->headerFooter[\"differentOddEven\"]) &&\n\t\t\t\t\t\t\t\t\tself::boolean((string)$xmlSheet->headerFooter[\"differentOddEven\"])) {\n\t\t\t\t\t\t\t\t\t$docHeaderFooter->setDifferentOddEven(TRUE);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$docHeaderFooter->setDifferentOddEven(FALSE);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->headerFooter[\"differentFirst\"]) &&\n\t\t\t\t\t\t\t\t\tself::boolean((string)$xmlSheet->headerFooter[\"differentFirst\"])) {\n\t\t\t\t\t\t\t\t\t$docHeaderFooter->setDifferentFirst(TRUE);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$docHeaderFooter->setDifferentFirst(FALSE);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->headerFooter[\"scaleWithDoc\"]) &&\n\t\t\t\t\t\t\t\t\t!self::boolean((string)$xmlSheet->headerFooter[\"scaleWithDoc\"])) {\n\t\t\t\t\t\t\t\t\t$docHeaderFooter->setScaleWithDocument(FALSE);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$docHeaderFooter->setScaleWithDocument(TRUE);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isset($xmlSheet->headerFooter[\"alignWithMargins\"]) &&\n\t\t\t\t\t\t\t\t\t!self::boolean((string)$xmlSheet->headerFooter[\"alignWithMargins\"])) {\n\t\t\t\t\t\t\t\t\t$docHeaderFooter->setAlignWithMargins(FALSE);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$docHeaderFooter->setAlignWithMargins(TRUE);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t$docHeaderFooter->setOddHeader((string) $xmlSheet->headerFooter->oddHeader);\n\t\t\t\t\t\t\t\t$docHeaderFooter->setOddFooter((string) $xmlSheet->headerFooter->oddFooter);\n\t\t\t\t\t\t\t\t$docHeaderFooter->setEvenHeader((string) $xmlSheet->headerFooter->evenHeader);\n\t\t\t\t\t\t\t\t$docHeaderFooter->setEvenFooter((string) $xmlSheet->headerFooter->evenFooter);\n\t\t\t\t\t\t\t\t$docHeaderFooter->setFirstHeader((string) $xmlSheet->headerFooter->firstHeader);\n\t\t\t\t\t\t\t\t$docHeaderFooter->setFirstFooter((string) $xmlSheet->headerFooter->firstFooter);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ($xmlSheet && $xmlSheet->rowBreaks && $xmlSheet->rowBreaks->brk && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\tforeach ($xmlSheet->rowBreaks->brk as $brk) {\n\t\t\t\t\t\t\t\t\tif ($brk[\"man\"]) {\n\t\t\t\t\t\t\t\t\t\t$docSheet->setBreak(\"A$brk[id]\", PHPExcel_Worksheet::BREAK_ROW);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ($xmlSheet && $xmlSheet->colBreaks && $xmlSheet->colBreaks->brk && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\tforeach ($xmlSheet->colBreaks->brk as $brk) {\n\t\t\t\t\t\t\t\t\tif ($brk[\"man\"]) {\n\t\t\t\t\t\t\t\t\t\t$docSheet->setBreak(PHPExcel_Cell::stringFromColumnIndex((string) $brk[\"id\"]) . \"1\", PHPExcel_Worksheet::BREAK_COLUMN);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ($xmlSheet && $xmlSheet->dataValidations && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\tforeach ($xmlSheet->dataValidations->dataValidation as $dataValidation) {\n\t\t\t\t\t\t\t\t    // Uppercase coordinate\n\t\t\t\t\t\t\t    \t$range = strtoupper($dataValidation[\"sqref\"]);\n\t\t\t\t\t\t\t\t\t$rangeSet = explode(' ',$range);\n\t\t\t\t\t\t\t\t\tforeach($rangeSet as $range) {\n\t\t\t\t\t\t\t\t\t\t$stRange = $docSheet->shrinkRangeToFit($range);\n\n\t\t\t\t\t\t\t\t\t\t// Extract all cell references in $range\n\t\t\t\t\t\t\t\t\t\t$aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($stRange);\n\t\t\t\t\t\t\t\t\t\tforeach ($aReferences as $reference) {\n\t\t\t\t\t\t\t\t\t\t\t// Create validation\n\t\t\t\t\t\t\t\t\t\t\t$docValidation = $docSheet->getCell($reference)->getDataValidation();\n\t\t\t\t\t\t\t\t\t\t\t$docValidation->setType((string) $dataValidation[\"type\"]);\n\t\t\t\t\t\t\t\t\t\t\t$docValidation->setErrorStyle((string) $dataValidation[\"errorStyle\"]);\n\t\t\t\t\t\t\t\t\t\t\t$docValidation->setOperator((string) $dataValidation[\"operator\"]);\n\t\t\t\t\t\t\t\t\t\t\t$docValidation->setAllowBlank($dataValidation[\"allowBlank\"] != 0);\n\t\t\t\t\t\t\t\t\t\t\t$docValidation->setShowDropDown($dataValidation[\"showDropDown\"] == 0);\n\t\t\t\t\t\t\t\t\t\t\t$docValidation->setShowInputMessage($dataValidation[\"showInputMessage\"] != 0);\n\t\t\t\t\t\t\t\t\t\t\t$docValidation->setShowErrorMessage($dataValidation[\"showErrorMessage\"] != 0);\n\t\t\t\t\t\t\t\t\t\t\t$docValidation->setErrorTitle((string) $dataValidation[\"errorTitle\"]);\n\t\t\t\t\t\t\t\t\t\t\t$docValidation->setError((string) $dataValidation[\"error\"]);\n\t\t\t\t\t\t\t\t\t\t\t$docValidation->setPromptTitle((string) $dataValidation[\"promptTitle\"]);\n\t\t\t\t\t\t\t\t\t\t\t$docValidation->setPrompt((string) $dataValidation[\"prompt\"]);\n\t\t\t\t\t\t\t\t\t\t\t$docValidation->setFormula1((string) $dataValidation->formula1);\n\t\t\t\t\t\t\t\t\t\t\t$docValidation->setFormula2((string) $dataValidation->formula2);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Add hyperlinks\n\t\t\t\t\t\t\t$hyperlinks = array();\n\t\t\t\t\t\t\tif (!$this->_readDataOnly) {\n\t\t\t\t\t\t\t\t// Locate hyperlink relations\n\t\t\t\t\t\t\t\tif ($zip->locateName(dirname(\"$dir/$fileWorksheet\") . \"/_rels/\" . basename($fileWorksheet) . \".rels\")) {\n\t\t\t\t\t\t\t\t\t$relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip,  dirname(\"$dir/$fileWorksheet\") . \"/_rels/\" . basename($fileWorksheet) . \".rels\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships\");\n\t\t\t\t\t\t\t\t\tforeach ($relsWorksheet->Relationship as $ele) {\n\t\t\t\t\t\t\t\t\t\tif ($ele[\"Type\"] == \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink\") {\n\t\t\t\t\t\t\t\t\t\t\t$hyperlinks[(string)$ele[\"Id\"]] = (string)$ele[\"Target\"];\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Loop through hyperlinks\n\t\t\t\t\t\t\t\tif ($xmlSheet && $xmlSheet->hyperlinks) {\n\t\t\t\t\t\t\t\t\tforeach ($xmlSheet->hyperlinks->hyperlink as $hyperlink) {\n\t\t\t\t\t\t\t\t\t\t// Link url\n\t\t\t\t\t\t\t\t\t\t$linkRel = $hyperlink->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships');\n\n\t\t\t\t\t\t\t\t\t\tforeach (PHPExcel_Cell::extractAllCellReferencesInRange($hyperlink['ref']) as $cellReference) {\n\t\t\t\t\t\t\t\t\t\t\t$cell = $docSheet->getCell( $cellReference );\n\t\t\t\t\t\t\t\t\t\t\tif (isset($linkRel['id'])) {\n\t\t\t\t\t\t\t\t\t\t\t\t$hyperlinkUrl = $hyperlinks[ (string)$linkRel['id'] ];\n\t\t\t\t\t\t\t\t\t\t\t\tif (isset($hyperlink['location'])) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$hyperlinkUrl .= '#' . (string) $hyperlink['location'];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t$cell->getHyperlink()->setUrl($hyperlinkUrl);\n\t\t\t\t\t\t\t\t\t\t\t} elseif (isset($hyperlink['location'])) {\n\t\t\t\t\t\t\t\t\t\t\t\t$cell->getHyperlink()->setUrl( 'sheet://' . (string)$hyperlink['location'] );\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Tooltip\n\t\t\t\t\t\t\t\t\t\t\tif (isset($hyperlink['tooltip'])) {\n\t\t\t\t\t\t\t\t\t\t\t\t$cell->getHyperlink()->setTooltip( (string)$hyperlink['tooltip'] );\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Add comments\n\t\t\t\t\t\t\t$comments = array();\n\t\t\t\t\t\t\t$vmlComments = array();\n\t\t\t\t\t\t\tif (!$this->_readDataOnly) {\n\t\t\t\t\t\t\t\t// Locate comment relations\n\t\t\t\t\t\t\t\tif ($zip->locateName(dirname(\"$dir/$fileWorksheet\") . \"/_rels/\" . basename($fileWorksheet) . \".rels\")) {\n\t\t\t\t\t\t\t\t\t$relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip,  dirname(\"$dir/$fileWorksheet\") . \"/_rels/\" . basename($fileWorksheet) . \".rels\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships\");\n\t\t\t\t\t\t\t\t\tforeach ($relsWorksheet->Relationship as $ele) {\n\t\t\t\t\t\t\t\t\t    if ($ele[\"Type\"] == \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments\") {\n\t\t\t\t\t\t\t\t\t\t\t$comments[(string)$ele[\"Id\"]] = (string)$ele[\"Target\"];\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t    if ($ele[\"Type\"] == \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing\") {\n\t\t\t\t\t\t\t\t\t\t\t$vmlComments[(string)$ele[\"Id\"]] = (string)$ele[\"Target\"];\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Loop through comments\n\t\t\t\t\t\t\t\tforeach ($comments as $relName => $relPath) {\n\t\t\t\t\t\t\t\t\t// Load comments file\n\t\t\t\t\t\t\t\t\t$relPath = PHPExcel_Shared_File::realpath(dirname(\"$dir/$fileWorksheet\") . \"/\" . $relPath);\n\t\t\t\t\t\t\t\t\t$commentsFile = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $relPath)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\n\t\t\t\t\t\t\t\t\t// Utility variables\n\t\t\t\t\t\t\t\t\t$authors = array();\n\n\t\t\t\t\t\t\t\t\t// Loop through authors\n\t\t\t\t\t\t\t\t\tforeach ($commentsFile->authors->author as $author) {\n\t\t\t\t\t\t\t\t\t\t$authors[] = (string)$author;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Loop through contents\n\t\t\t\t\t\t\t\t\tforeach ($commentsFile->commentList->comment as $comment) {\n\t\t\t\t\t\t\t\t\t\tif(!empty($comment['authorId']))\n\t\t\t\t\t\t\t\t\t\t\t$docSheet->getComment( (string)$comment['ref'] )->setAuthor( $authors[(string)$comment['authorId']] );\n\t\t\t\t\t\t\t\t\t\t$docSheet->getComment( (string)$comment['ref'] )->setText( $this->_parseRichText($comment->text) );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Loop through VML comments\n\t\t\t\t\t\t\t    foreach ($vmlComments as $relName => $relPath) {\n\t\t\t\t\t\t\t\t\t// Load VML comments file\n\t\t\t\t\t\t\t\t\t$relPath = PHPExcel_Shared_File::realpath(dirname(\"$dir/$fileWorksheet\") . \"/\" . $relPath);\n\t\t\t\t\t\t\t\t\t$vmlCommentsFile = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $relPath)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t\t\t\t\t\t\t\t$vmlCommentsFile->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');\n\n\t\t\t\t\t\t\t\t\t$shapes = $vmlCommentsFile->xpath('//v:shape');\n\t\t\t\t\t\t\t\t\tforeach ($shapes as $shape) {\n\t\t\t\t\t\t\t\t\t\t$shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');\n\n\t\t\t\t\t\t\t\t\t\tif (isset($shape['style'])) {\n\t    \t\t\t\t\t\t\t\t\t$style        = (string)$shape['style'];\n\t    \t\t\t\t\t\t\t\t\t$fillColor    = strtoupper( substr( (string)$shape['fillcolor'], 1 ) );\n\t    \t\t\t\t\t\t\t\t\t$column       = null;\n\t    \t\t\t\t\t\t\t\t\t$row          = null;\n\n\t    \t\t\t\t\t\t\t\t\t$clientData   = $shape->xpath('.//x:ClientData');\n\t    \t\t\t\t\t\t\t\t\tif (is_array($clientData) && !empty($clientData)) {\n\t        \t\t\t\t\t\t\t\t\t$clientData   = $clientData[0];\n\n\t        \t\t\t\t\t\t\t\t\tif ( isset($clientData['ObjectType']) && (string)$clientData['ObjectType'] == 'Note' ) {\n\t        \t\t\t\t\t\t\t\t\t    $temp = $clientData->xpath('.//x:Row');\n\t        \t\t\t\t\t\t\t\t\t    if (is_array($temp)) $row = $temp[0];\n\n\t        \t\t\t\t\t\t\t\t\t    $temp = $clientData->xpath('.//x:Column');\n\t        \t\t\t\t\t\t\t\t\t    if (is_array($temp)) $column = $temp[0];\n\t        \t\t\t\t\t\t\t\t\t}\n\t    \t\t\t\t\t\t\t\t\t}\n\n\t    \t\t\t\t\t\t\t\t\tif (($column !== NULL) && ($row !== NULL)) {\n\t    \t\t\t\t\t\t\t\t\t    // Set comment properties\n\t    \t\t\t\t\t\t\t\t\t    $comment = $docSheet->getCommentByColumnAndRow((string) $column, $row + 1);\n\t    \t\t\t\t\t\t\t\t\t    $comment->getFillColor()->setRGB( $fillColor );\n\n\t    \t\t\t\t\t\t\t\t\t    // Parse style\n\t    \t\t\t\t\t\t\t\t\t    $styleArray = explode(';', str_replace(' ', '', $style));\n\t    \t\t\t\t\t\t\t\t\t    foreach ($styleArray as $stylePair) {\n\t    \t\t\t\t\t\t\t\t\t        $stylePair = explode(':', $stylePair);\n\n\t    \t\t\t\t\t\t\t\t\t        if ($stylePair[0] == 'margin-left')     $comment->setMarginLeft($stylePair[1]);\n\t    \t\t\t\t\t\t\t\t\t        if ($stylePair[0] == 'margin-top')      $comment->setMarginTop($stylePair[1]);\n\t    \t\t\t\t\t\t\t\t\t        if ($stylePair[0] == 'width')           $comment->setWidth($stylePair[1]);\n\t    \t\t\t\t\t\t\t\t\t        if ($stylePair[0] == 'height')          $comment->setHeight($stylePair[1]);\n\t    \t\t\t\t\t\t\t\t\t        if ($stylePair[0] == 'visibility')      $comment->setVisible( $stylePair[1] == 'visible' );\n\n\t    \t\t\t\t\t\t\t\t\t    }\n\t    \t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Header/footer images\n\t\t\t\t\t\t\t\tif ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\t\tif ($zip->locateName(dirname(\"$dir/$fileWorksheet\") . \"/_rels/\" . basename($fileWorksheet) . \".rels\")) {\n\t\t\t\t\t\t\t\t\t\t$relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip,  dirname(\"$dir/$fileWorksheet\") . \"/_rels/\" . basename($fileWorksheet) . \".rels\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships\");\n\t\t\t\t\t\t\t\t\t\t$vmlRelationship = '';\n\n\t\t\t\t\t\t\t\t\t\tforeach ($relsWorksheet->Relationship as $ele) {\n\t\t\t\t\t\t\t\t\t\t\tif ($ele[\"Type\"] == \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing\") {\n\t\t\t\t\t\t\t\t\t\t\t\t$vmlRelationship = self::dir_add(\"$dir/$fileWorksheet\", $ele[\"Target\"]);\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\tif ($vmlRelationship != '') {\n\t\t\t\t\t\t\t\t\t\t\t// Fetch linked images\n\t\t\t\t\t\t\t\t\t\t\t$relsVML = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip,  dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships\");\n\t\t\t\t\t\t\t\t\t\t\t$drawings = array();\n\t\t\t\t\t\t\t\t\t\t\tforeach ($relsVML->Relationship as $ele) {\n\t\t\t\t\t\t\t\t\t\t\t\tif ($ele[\"Type\"] == \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\") {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$drawings[(string) $ele[\"Id\"]] = self::dir_add($vmlRelationship, $ele[\"Target\"]);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t// Fetch VML document\n\t\t\t\t\t\t\t\t\t\t\t$vmlDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $vmlRelationship)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t\t\t\t\t\t\t\t\t\t$vmlDrawing->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');\n\n\t\t\t\t\t\t\t\t\t\t\t$hfImages = array();\n\n\t\t\t\t\t\t\t\t\t\t\t$shapes = $vmlDrawing->xpath('//v:shape');\n\t\t\t\t\t\t\t\t\t\t\tforeach ($shapes as $idx => $shape) {\n\t\t\t\t\t\t\t\t\t\t\t\t$shape->registerXPathNamespace('v', 'urn:schemas-microsoft-com:vml');\n\t\t\t\t\t\t\t\t\t\t\t\t$imageData = $shape->xpath('//v:imagedata');\n\t\t\t\t\t\t\t\t\t\t\t\t$imageData = $imageData[$idx];\n\n\t\t\t\t\t\t\t\t\t\t\t\t$imageData = $imageData->attributes('urn:schemas-microsoft-com:office:office');\n\t\t\t\t\t\t\t\t\t\t\t\t$style = self::toCSSArray( (string)$shape['style'] );\n\n\t\t\t\t\t\t\t\t\t\t\t\t$hfImages[ (string)$shape['id'] ] = new PHPExcel_Worksheet_HeaderFooterDrawing();\n\t\t\t\t\t\t\t\t\t\t\t\tif (isset($imageData['title'])) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$hfImages[ (string)$shape['id'] ]->setName( (string)$imageData['title'] );\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t\t$hfImages[ (string)$shape['id'] ]->setPath(\"zip://\".PHPExcel_Shared_File::realpath($pFilename).\"#\" . $drawings[(string)$imageData['relid']], false);\n\t\t\t\t\t\t\t\t\t\t\t\t$hfImages[ (string)$shape['id'] ]->setResizeProportional(false);\n\t\t\t\t\t\t\t\t\t\t\t\t$hfImages[ (string)$shape['id'] ]->setWidth($style['width']);\n\t\t\t\t\t\t\t\t\t\t\t\t$hfImages[ (string)$shape['id'] ]->setHeight($style['height']);\n\t\t\t\t\t\t\t\t\t\t\t\tif (isset($style['margin-left'])) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$hfImages[ (string)$shape['id'] ]->setOffsetX($style['margin-left']);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t$hfImages[ (string)$shape['id'] ]->setOffsetY($style['margin-top']);\n\t\t\t\t\t\t\t\t\t\t\t\t$hfImages[ (string)$shape['id'] ]->setResizeProportional(true);\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\t$docSheet->getHeaderFooter()->setImages($hfImages);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n                            // TODO: Autoshapes from twoCellAnchors!\n\t\t\t\t\t\t\tif ($zip->locateName(dirname(\"$dir/$fileWorksheet\") . \"/_rels/\" . basename($fileWorksheet) . \".rels\")) {\n\t\t\t\t\t\t\t\t$relsWorksheet = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip,  dirname(\"$dir/$fileWorksheet\") . \"/_rels/\" . basename($fileWorksheet) . \".rels\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships\");\n\t\t\t\t\t\t\t\t$drawings = array();\n\t\t\t\t\t\t\t\tforeach ($relsWorksheet->Relationship as $ele) {\n\t\t\t\t\t\t\t\t\tif ($ele[\"Type\"] == \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing\") {\n\t\t\t\t\t\t\t\t\t\t$drawings[(string) $ele[\"Id\"]] = self::dir_add(\"$dir/$fileWorksheet\", $ele[\"Target\"]);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ($xmlSheet->drawing && !$this->_readDataOnly) {\n\t\t\t\t\t\t\t\t\tforeach ($xmlSheet->drawing as $drawing) {\n\t\t\t\t\t\t\t\t\t\t$fileDrawing = $drawings[(string) self::array_item($drawing->attributes(\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"), \"id\")];\n\t\t\t\t\t\t\t\t\t\t$relsDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip,  dirname($fileDrawing) . \"/_rels/\" . basename($fileDrawing) . \".rels\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions()); //~ http://schemas.openxmlformats.org/package/2006/relationships\");\n\t\t\t\t\t\t\t\t\t\t$images = array();\n\n\t\t\t\t\t\t\t\t\t\tif ($relsDrawing && $relsDrawing->Relationship) {\n\t\t\t\t\t\t\t\t\t\t\tforeach ($relsDrawing->Relationship as $ele) {\n\t\t\t\t\t\t\t\t\t\t\t\tif ($ele[\"Type\"] == \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image\") {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$images[(string) $ele[\"Id\"]] = self::dir_add($fileDrawing, $ele[\"Target\"]);\n\t\t\t\t\t\t\t\t\t\t\t\t} elseif ($ele[\"Type\"] == \"http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart\") {\n\t\t\t\t\t\t\t\t\t\t\t\t\tif ($this->_includeCharts) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$charts[self::dir_add($fileDrawing, $ele[\"Target\"])] = array('id'\t\t=> (string) $ele[\"Id\"],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t 'sheet'\t=> $docSheet->getTitle()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t$xmlDrawing = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $fileDrawing)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions())->children(\"http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing\");\n\n\t\t\t\t\t\t\t\t\t\tif ($xmlDrawing->oneCellAnchor) {\n\t\t\t\t\t\t\t\t\t\t\tforeach ($xmlDrawing->oneCellAnchor as $oneCellAnchor) {\n\t\t\t\t\t\t\t\t\t\t\t\tif ($oneCellAnchor->pic->blipFill) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$blip = $oneCellAnchor->pic->blipFill->children(\"http://schemas.openxmlformats.org/drawingml/2006/main\")->blip;\n\t\t\t\t\t\t\t\t\t\t\t\t\t$xfrm = $oneCellAnchor->pic->spPr->children(\"http://schemas.openxmlformats.org/drawingml/2006/main\")->xfrm;\n\t\t\t\t\t\t\t\t\t\t\t\t\t$outerShdw = $oneCellAnchor->pic->spPr->children(\"http://schemas.openxmlformats.org/drawingml/2006/main\")->effectLst->outerShdw;\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing = new PHPExcel_Worksheet_Drawing;\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setName((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), \"name\"));\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setDescription((string) self::array_item($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), \"descr\"));\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setPath(\"zip://\".PHPExcel_Shared_File::realpath($pFilename).\"#\" . $images[(string) self::array_item($blip->attributes(\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"), \"embed\")], false);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1));\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff));\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff));\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setResizeProportional(false);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), \"cx\")));\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), \"cy\")));\n\t\t\t\t\t\t\t\t\t\t\t\t\tif ($xfrm) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), \"rot\")));\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\tif ($outerShdw) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow = $objDrawing->getShadow();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->setVisible(true);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), \"blurRad\")));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), \"dist\")));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), \"dir\")));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->setAlignment((string) self::array_item($outerShdw->attributes(), \"algn\"));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), \"val\"));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), \"val\") / 1000);\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setWorksheet($docSheet);\n\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t//\t? Can charts be positioned with a oneCellAnchor ?\n\t\t\t\t\t\t\t\t\t\t\t\t\t$coordinates\t= PHPExcel_Cell::stringFromColumnIndex((string) $oneCellAnchor->from->col) . ($oneCellAnchor->from->row + 1);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$offsetX\t\t= PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->colOff);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$offsetY\t\t= PHPExcel_Shared_Drawing::EMUToPixels($oneCellAnchor->from->rowOff);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$width\t\t\t= PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), \"cx\"));\n\t\t\t\t\t\t\t\t\t\t\t\t\t$height\t\t\t= PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($oneCellAnchor->ext->attributes(), \"cy\"));\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif ($xmlDrawing->twoCellAnchor) {\n\t\t\t\t\t\t\t\t\t\t\tforeach ($xmlDrawing->twoCellAnchor as $twoCellAnchor) {\n\t\t\t\t\t\t\t\t\t\t\t\tif ($twoCellAnchor->pic->blipFill) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$blip = $twoCellAnchor->pic->blipFill->children(\"http://schemas.openxmlformats.org/drawingml/2006/main\")->blip;\n\t\t\t\t\t\t\t\t\t\t\t\t\t$xfrm = $twoCellAnchor->pic->spPr->children(\"http://schemas.openxmlformats.org/drawingml/2006/main\")->xfrm;\n\t\t\t\t\t\t\t\t\t\t\t\t\t$outerShdw = $twoCellAnchor->pic->spPr->children(\"http://schemas.openxmlformats.org/drawingml/2006/main\")->effectLst->outerShdw;\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing = new PHPExcel_Worksheet_Drawing;\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setName((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), \"name\"));\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setDescription((string) self::array_item($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), \"descr\"));\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setPath(\"zip://\".PHPExcel_Shared_File::realpath($pFilename).\"#\" . $images[(string) self::array_item($blip->attributes(\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\"), \"embed\")], false);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setCoordinates(PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1));\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setOffsetX(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff));\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setOffsetY(PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff));\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setResizeProportional(false);\n\n\t\t\t\t\t\t\t\t\t\t\t\t\tif ($xfrm) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setWidth(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), \"cx\")));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setHeight(PHPExcel_Shared_Drawing::EMUToPixels(self::array_item($xfrm->ext->attributes(), \"cy\")));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setRotation(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($xfrm->attributes(), \"rot\")));\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\tif ($outerShdw) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow = $objDrawing->getShadow();\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->setVisible(true);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->setBlurRadius(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), \"blurRad\")));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->setDistance(PHPExcel_Shared_Drawing::EMUTopixels(self::array_item($outerShdw->attributes(), \"dist\")));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->setDirection(PHPExcel_Shared_Drawing::angleToDegrees(self::array_item($outerShdw->attributes(), \"dir\")));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->setAlignment((string) self::array_item($outerShdw->attributes(), \"algn\"));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->getColor()->setRGB(self::array_item($outerShdw->srgbClr->attributes(), \"val\"));\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$shadow->setAlpha(self::array_item($outerShdw->srgbClr->alpha->attributes(), \"val\") / 1000);\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objDrawing->setWorksheet($docSheet);\n\t\t\t\t\t\t\t\t\t\t\t\t} elseif(($this->_includeCharts) && ($twoCellAnchor->graphicFrame)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$fromCoordinate\t= PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->from->col) . ($twoCellAnchor->from->row + 1);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$fromOffsetX\t= PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->colOff);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$fromOffsetY\t= PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->from->rowOff);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$toCoordinate\t= PHPExcel_Cell::stringFromColumnIndex((string) $twoCellAnchor->to->col) . ($twoCellAnchor->to->row + 1);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$toOffsetX\t\t= PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->colOff);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$toOffsetY\t\t= PHPExcel_Shared_Drawing::EMUToPixels($twoCellAnchor->to->rowOff);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$graphic\t\t= $twoCellAnchor->graphicFrame->children(\"http://schemas.openxmlformats.org/drawingml/2006/main\")->graphic;\n\t\t\t\t\t\t\t\t\t\t\t\t\t$chartRef\t\t= $graphic->graphicData->children(\"http://schemas.openxmlformats.org/drawingml/2006/chart\")->chart;\n\t\t\t\t\t\t\t\t\t\t\t\t\t$thisChart\t\t= (string) $chartRef->attributes(\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\");\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t$chartDetails[$docSheet->getTitle().'!'.$thisChart] =\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tarray(\t'fromCoordinate'\t=> $fromCoordinate,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'fromOffsetX'\t\t=> $fromOffsetX,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'fromOffsetY'\t\t=> $fromOffsetY,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'toCoordinate'\t\t=> $toCoordinate,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'toOffsetX'\t\t\t=> $toOffsetX,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'toOffsetY'\t\t\t=> $toOffsetY,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'worksheetTitle'\t=> $docSheet->getTitle()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t );\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Loop through definedNames\n\t\t\t\t\t\t\tif ($xmlWorkbook->definedNames) {\n\t\t\t\t\t\t\t\tforeach ($xmlWorkbook->definedNames->definedName as $definedName) {\n\t\t\t\t\t\t\t\t\t// Extract range\n\t\t\t\t\t\t\t\t\t$extractedRange = (string)$definedName;\n\t\t\t\t\t\t\t\t\t$extractedRange = preg_replace('/\\'(\\w+)\\'\\!/', '', $extractedRange);\n\t\t\t\t\t\t\t\t\tif (($spos = strpos($extractedRange,'!')) !== false) {\n\t\t\t\t\t\t\t\t\t\t$extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos));\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t$extractedRange = str_replace('$', '', $extractedRange);\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Valid range?\n\t\t\t\t\t\t\t\t\tif (stripos((string)$definedName, '#REF!') !== FALSE || $extractedRange == '') {\n\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t// Some definedNames are only applicable if we are on the same sheet...\n\t\t\t\t\t\t\t\t\tif ((string)$definedName['localSheetId'] != '' && (string)$definedName['localSheetId'] == $sheetId) {\n\t\t\t\t\t\t\t\t\t\t// Switch on type\n\t\t\t\t\t\t\t\t\t\tswitch ((string)$definedName['name']) {\n\n\t\t\t\t\t\t\t\t\t\t\tcase '_xlnm._FilterDatabase':\n\t\t\t\t\t\t\t\t\t\t\t\tif ((string)$definedName['hidden'] !== '1') {\n                                                    $extractedRange = explode(',', $extractedRange);\n                                                    foreach ($extractedRange as $range) {\n                                                        $autoFilterRange = $range;\n                                                        if (strpos($autoFilterRange, ':') !== false) {\n                                                            $docSheet->getAutoFilter()->setRange($autoFilterRange);\n                                                        }\n                                                    }\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t\t\t\tcase '_xlnm.Print_Titles':\n\t\t\t\t\t\t\t\t\t\t\t\t// Split $extractedRange\n\t\t\t\t\t\t\t\t\t\t\t\t$extractedRange = explode(',', $extractedRange);\n\n\t\t\t\t\t\t\t\t\t\t\t\t// Set print titles\n\t\t\t\t\t\t\t\t\t\t\t\tforeach ($extractedRange as $range) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$matches = array();\n\t\t\t\t\t\t\t\t\t\t\t\t\t$range = str_replace('$', '', $range);\n\n\t\t\t\t\t\t\t\t\t\t\t\t\t// check for repeating columns, e g. 'A:A' or 'A:D'\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (preg_match('/!?([A-Z]+)\\:([A-Z]+)$/', $range, $matches)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($matches[1], $matches[2]));\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t// check for repeating rows, e.g. '1:1' or '1:5'\n\t\t\t\t\t\t\t\t\t\t\t\t\telseif (preg_match('/!?(\\d+)\\:(\\d+)$/', $range, $matches)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$docSheet->getPageSetup()->setRowsToRepeatAtTop(array($matches[1], $matches[2]));\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t\t\t\tcase '_xlnm.Print_Area':\n\t\t\t\t\t\t\t\t\t\t\t\t$rangeSets = explode(',', $extractedRange);\t\t// FIXME: what if sheetname contains comma?\n\t\t\t\t\t\t\t\t\t\t\t\t$newRangeSets = array();\n\t\t\t\t\t\t\t\t\t\t\t\tforeach($rangeSets as $rangeSet) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$range = explode('!', $rangeSet);\t// FIXME: what if sheetname contains exclamation mark?\n\t\t\t\t\t\t\t\t\t\t\t\t\t$rangeSet = isset($range[1]) ? $range[1] : $range[0];\n\t\t\t\t\t\t\t\t\t\t\t\t\tif (strpos($rangeSet, ':') === FALSE) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$rangeSet = $rangeSet . ':' . $rangeSet;\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t$newRangeSets[] = str_replace('$', '', $rangeSet);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t$docSheet->getPageSetup()->setPrintArea(implode(',',$newRangeSets));\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Next sheet id\n\t\t\t\t\t\t\t++$sheetId;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Loop through definedNames\n\t\t\t\t\t\tif ($xmlWorkbook->definedNames) {\n\t\t\t\t\t\t\tforeach ($xmlWorkbook->definedNames->definedName as $definedName) {\n\t\t\t\t\t\t\t\t// Extract range\n\t\t\t\t\t\t\t\t$extractedRange = (string)$definedName;\n\t\t\t\t\t\t\t\t$extractedRange = preg_replace('/\\'(\\w+)\\'\\!/', '', $extractedRange);\n\t\t\t\t\t\t\t\tif (($spos = strpos($extractedRange,'!')) !== false) {\n\t\t\t\t\t\t\t\t\t$extractedRange = substr($extractedRange,0,$spos).str_replace('$', '', substr($extractedRange,$spos));\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$extractedRange = str_replace('$', '', $extractedRange);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Valid range?\n\t\t\t\t\t\t\t\tif (stripos((string)$definedName, '#REF!') !== false || $extractedRange == '') {\n\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t// Some definedNames are only applicable if we are on the same sheet...\n\t\t\t\t\t\t\t\tif ((string)$definedName['localSheetId'] != '') {\n\t\t\t\t\t\t\t\t\t// Local defined name\n\t\t\t\t\t\t\t\t\t// Switch on type\n\t\t\t\t\t\t\t\t\tswitch ((string)$definedName['name']) {\n\n\t\t\t\t\t\t\t\t\t\tcase '_xlnm._FilterDatabase':\n\t\t\t\t\t\t\t\t\t\tcase '_xlnm.Print_Titles':\n\t\t\t\t\t\t\t\t\t\tcase '_xlnm.Print_Area':\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t\t\tdefault:\n\t\t\t\t\t\t\t\t\t\t\tif ($mapSheetId[(integer) $definedName['localSheetId']] !== null) {\n\t\t\t\t\t\t\t\t\t\t\t\t$range = explode('!', (string)$definedName);\n\t\t\t\t\t\t\t\t\t\t\t\tif (count($range) == 2) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$range[0] = str_replace(\"''\", \"'\", $range[0]);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$range[0] = str_replace(\"'\", \"\", $range[0]);\n\t\t\t\t\t\t\t\t\t\t\t\t\tif ($worksheet = $docSheet->getParent()->getSheetByName($range[0])) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$extractedRange = str_replace('$', '', $range[1]);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$scope = $docSheet->getParent()->getSheet($mapSheetId[(integer) $definedName['localSheetId']]);\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $worksheet, $extractedRange, true, $scope) );\n\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else if (!isset($definedName['localSheetId'])) {\n\t\t\t\t\t\t\t\t\t// \"Global\" definedNames\n\t\t\t\t\t\t\t\t\t$locatedSheet = null;\n\t\t\t\t\t\t\t\t\t$extractedSheetName = '';\n\t\t\t\t\t\t\t\t\tif (strpos( (string)$definedName, '!' ) !== false) {\n\t\t\t\t\t\t\t\t\t\t// Extract sheet name\n\t\t\t\t\t\t\t\t\t\t$extractedSheetName = PHPExcel_Worksheet::extractSheetTitle( (string)$definedName, true );\n\t\t\t\t\t\t\t\t\t\t$extractedSheetName = $extractedSheetName[0];\n\n\t\t\t\t\t\t\t\t\t\t// Locate sheet\n\t\t\t\t\t\t\t\t\t\t$locatedSheet = $excel->getSheetByName($extractedSheetName);\n\n\t\t\t\t\t\t\t\t\t\t// Modify range\n\t\t\t\t\t\t\t\t\t\t$range = explode('!', $extractedRange);\n\t\t\t\t\t\t\t\t\t\t$extractedRange = isset($range[1]) ? $range[1] : $range[0];\n\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif ($locatedSheet !== NULL) {\n\t\t\t\t\t\t\t\t\t\t$excel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $locatedSheet, $extractedRange, false) );\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif ((!$this->_readDataOnly) || (!empty($this->_loadSheetsOnly))) {\n\t\t\t\t\t\t// active sheet index\n\t\t\t\t\t\t$activeTab = intval($xmlWorkbook->bookViews->workbookView[\"activeTab\"]); // refers to old sheet index\n\n\t\t\t\t\t\t// keep active sheet index if sheet is still loaded, else first sheet is set as the active\n\t\t\t\t\t\tif (isset($mapSheetId[$activeTab]) && $mapSheetId[$activeTab] !== null) {\n\t\t\t\t\t\t\t$excel->setActiveSheetIndex($mapSheetId[$activeTab]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif ($excel->getSheetCount() == 0) {\n\t\t\t\t\t\t\t\t$excel->createSheet();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$excel->setActiveSheetIndex(0);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t}\n\n\n\t\tif (!$this->_readDataOnly) {\n\t\t\t$contentTypes = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, \"[Content_Types].xml\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t\tforeach ($contentTypes->Override as $contentType) {\n\t\t\t\tswitch ($contentType[\"ContentType\"]) {\n\t\t\t\t\tcase \"application/vnd.openxmlformats-officedocument.drawingml.chart+xml\":\n\t\t\t\t\t\tif ($this->_includeCharts) {\n\t\t\t\t\t\t\t$chartEntryRef = ltrim($contentType['PartName'],'/');\n\t\t\t\t\t\t\t$chartElements = simplexml_load_string($this->securityScan($this->_getFromZipArchive($zip, $chartEntryRef)), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t\t\t\t\t\t$objChart = PHPExcel_Reader_Excel2007_Chart::readChart($chartElements,basename($chartEntryRef,'.xml'));\n\n//\t\t\t\t\t\t\techo 'Chart ',$chartEntryRef,'<br />';\n//\t\t\t\t\t\t\tvar_dump($charts[$chartEntryRef]);\n//\n\t\t\t\t\t\t\tif (isset($charts[$chartEntryRef])) {\n\t\t\t\t\t\t\t\t$chartPositionRef = $charts[$chartEntryRef]['sheet'].'!'.$charts[$chartEntryRef]['id'];\n//\t\t\t\t\t\t\t\techo 'Position Ref ',$chartPositionRef,'<br />';\n\t\t\t\t\t\t\t\tif (isset($chartDetails[$chartPositionRef])) {\n//\t\t\t\t\t\t\t\t\tvar_dump($chartDetails[$chartPositionRef]);\n\n\t\t\t\t\t\t\t\t\t$excel->getSheetByName($charts[$chartEntryRef]['sheet'])->addChart($objChart);\n\t\t\t\t\t\t\t\t\t$objChart->setWorksheet($excel->getSheetByName($charts[$chartEntryRef]['sheet']));\n\t\t\t\t\t\t\t\t\t$objChart->setTopLeftPosition( $chartDetails[$chartPositionRef]['fromCoordinate'],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   $chartDetails[$chartPositionRef]['fromOffsetX'],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   $chartDetails[$chartPositionRef]['fromOffsetY']\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t );\n\t\t\t\t\t\t\t\t\t$objChart->setBottomRightPosition( $chartDetails[$chartPositionRef]['toCoordinate'],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   $chartDetails[$chartPositionRef]['toOffsetX'],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   $chartDetails[$chartPositionRef]['toOffsetY']\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t );\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t$zip->close();\n\n\t\treturn $excel;\n\t}\n\n\n\tprivate static function _readColor($color, $background=FALSE) {\n\t\tif (isset($color[\"rgb\"])) {\n\t\t\treturn (string)$color[\"rgb\"];\n\t\t} else if (isset($color[\"indexed\"])) {\n\t\t\treturn PHPExcel_Style_Color::indexedColor($color[\"indexed\"]-7,$background)->getARGB();\n\t\t} else if (isset($color[\"theme\"])) {\n\t\t\tif (self::$_theme !== NULL) {\n\t\t\t\t$returnColour = self::$_theme->getColourByIndex((int)$color[\"theme\"]);\n\t\t\t\tif (isset($color[\"tint\"])) {\n\t\t\t\t\t$tintAdjust = (float) $color[\"tint\"];\n\t\t\t\t\t$returnColour = PHPExcel_Style_Color::changeBrightness($returnColour, $tintAdjust);\n\t\t\t\t}\n\t\t\t\treturn 'FF'.$returnColour;\n\t\t\t}\n\t\t}\n\n\t\tif ($background) {\n\t\t\treturn 'FFFFFFFF';\n\t\t}\n\t\treturn 'FF000000';\n\t}\n\n\n\tprivate static function _readStyle($docStyle, $style) {\n\t\t// format code\n//\t\tif (isset($style->numFmt)) {\n//\t\t\tif (isset($style->numFmt['formatCode'])) {\n//\t\t\t\t$docStyle->getNumberFormat()->setFormatCode((string) $style->numFmt['formatCode']);\n//\t\t\t} else {\n\t\t\t\t$docStyle->getNumberFormat()->setFormatCode($style->numFmt);\n//\t\t\t}\n//\t\t}\n\n\t\t// font\n\t\tif (isset($style->font)) {\n\t\t\t$docStyle->getFont()->setName((string) $style->font->name[\"val\"]);\n\t\t\t$docStyle->getFont()->setSize((string) $style->font->sz[\"val\"]);\n\t\t\tif (isset($style->font->b)) {\n\t\t\t\t$docStyle->getFont()->setBold(!isset($style->font->b[\"val\"]) || self::boolean((string) $style->font->b[\"val\"]));\n\t\t\t}\n\t\t\tif (isset($style->font->i)) {\n\t\t\t\t$docStyle->getFont()->setItalic(!isset($style->font->i[\"val\"]) || self::boolean((string) $style->font->i[\"val\"]));\n\t\t\t}\n\t\t\tif (isset($style->font->strike)) {\n\t\t\t\t$docStyle->getFont()->setStrikethrough(!isset($style->font->strike[\"val\"]) || self::boolean((string) $style->font->strike[\"val\"]));\n\t\t\t}\n\t\t\t$docStyle->getFont()->getColor()->setARGB(self::_readColor($style->font->color));\n\n\t\t\tif (isset($style->font->u) && !isset($style->font->u[\"val\"])) {\n\t\t\t\t$docStyle->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);\n\t\t\t} else if (isset($style->font->u) && isset($style->font->u[\"val\"])) {\n\t\t\t\t$docStyle->getFont()->setUnderline((string)$style->font->u[\"val\"]);\n\t\t\t}\n\n\t\t\tif (isset($style->font->vertAlign) && isset($style->font->vertAlign[\"val\"])) {\n\t\t\t\t$vertAlign = strtolower((string)$style->font->vertAlign[\"val\"]);\n\t\t\t\tif ($vertAlign == 'superscript') {\n\t\t\t\t\t$docStyle->getFont()->setSuperScript(true);\n\t\t\t\t}\n\t\t\t\tif ($vertAlign == 'subscript') {\n\t\t\t\t\t$docStyle->getFont()->setSubScript(true);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// fill\n\t\tif (isset($style->fill)) {\n\t\t\tif ($style->fill->gradientFill) {\n\t\t\t\t$gradientFill = $style->fill->gradientFill[0];\n\t\t\t\tif(!empty($gradientFill[\"type\"])) {\n\t\t\t\t\t$docStyle->getFill()->setFillType((string) $gradientFill[\"type\"]);\n\t\t\t\t}\n\t\t\t\t$docStyle->getFill()->setRotation(floatval($gradientFill[\"degree\"]));\n\t\t\t\t$gradientFill->registerXPathNamespace(\"sml\", \"http://schemas.openxmlformats.org/spreadsheetml/2006/main\");\n\t\t\t\t$docStyle->getFill()->getStartColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath(\"sml:stop[@position=0]\"))->color) );\n\t\t\t\t$docStyle->getFill()->getEndColor()->setARGB(self::_readColor( self::array_item($gradientFill->xpath(\"sml:stop[@position=1]\"))->color) );\n\t\t\t} elseif ($style->fill->patternFill) {\n\t\t\t\t$patternType = (string)$style->fill->patternFill[\"patternType\"] != '' ? (string)$style->fill->patternFill[\"patternType\"] : 'solid';\n\t\t\t\t$docStyle->getFill()->setFillType($patternType);\n\t\t\t\tif ($style->fill->patternFill->fgColor) {\n\t\t\t\t\t$docStyle->getFill()->getStartColor()->setARGB(self::_readColor($style->fill->patternFill->fgColor,true));\n\t\t\t\t} else {\n\t\t\t\t\t$docStyle->getFill()->getStartColor()->setARGB('FF000000');\n\t\t\t\t}\n\t\t\t\tif ($style->fill->patternFill->bgColor) {\n\t\t\t\t\t$docStyle->getFill()->getEndColor()->setARGB(self::_readColor($style->fill->patternFill->bgColor,true));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// border\n\t\tif (isset($style->border)) {\n\t\t\t$diagonalUp = self::boolean((string) $style->border[\"diagonalUp\"]);\n\t\t\t$diagonalDown = self::boolean((string) $style->border[\"diagonalDown\"]);\n\t\t\tif (!$diagonalUp && !$diagonalDown) {\n\t\t\t\t$docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE);\n\t\t\t} elseif ($diagonalUp && !$diagonalDown) {\n\t\t\t\t$docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP);\n\t\t\t} elseif (!$diagonalUp && $diagonalDown) {\n\t\t\t\t$docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN);\n\t\t\t} else {\n\t\t\t\t$docStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH);\n\t\t\t}\n\t\t\tself::_readBorder($docStyle->getBorders()->getLeft(), $style->border->left);\n\t\t\tself::_readBorder($docStyle->getBorders()->getRight(), $style->border->right);\n\t\t\tself::_readBorder($docStyle->getBorders()->getTop(), $style->border->top);\n\t\t\tself::_readBorder($docStyle->getBorders()->getBottom(), $style->border->bottom);\n\t\t\tself::_readBorder($docStyle->getBorders()->getDiagonal(), $style->border->diagonal);\n\t\t}\n\n\t\t// alignment\n\t\tif (isset($style->alignment)) {\n\t\t\t$docStyle->getAlignment()->setHorizontal((string) $style->alignment[\"horizontal\"]);\n\t\t\t$docStyle->getAlignment()->setVertical((string) $style->alignment[\"vertical\"]);\n\n\t\t\t$textRotation = 0;\n\t\t\tif ((int)$style->alignment[\"textRotation\"] <= 90) {\n\t\t\t\t$textRotation = (int)$style->alignment[\"textRotation\"];\n\t\t\t} else if ((int)$style->alignment[\"textRotation\"] > 90) {\n\t\t\t\t$textRotation = 90 - (int)$style->alignment[\"textRotation\"];\n\t\t\t}\n\n\t\t\t$docStyle->getAlignment()->setTextRotation(intval($textRotation));\n\t\t\t$docStyle->getAlignment()->setWrapText(self::boolean((string) $style->alignment[\"wrapText\"]));\n\t\t\t$docStyle->getAlignment()->setShrinkToFit(self::boolean((string) $style->alignment[\"shrinkToFit\"]));\n\t\t\t$docStyle->getAlignment()->setIndent( intval((string)$style->alignment[\"indent\"]) > 0 ? intval((string)$style->alignment[\"indent\"]) : 0 );\n\t\t\t$docStyle->getAlignment()->setReadorder( intval((string)$style->alignment[\"readingOrder\"]) > 0 ? intval((string)$style->alignment[\"readingOrder\"]) : 0 );\n\t\t}\n\n\t\t// protection\n\t\tif (isset($style->protection)) {\n\t\t\tif (isset($style->protection['locked'])) {\n\t\t\t\tif (self::boolean((string) $style->protection['locked'])) {\n\t\t\t\t\t$docStyle->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_PROTECTED);\n\t\t\t\t} else {\n\t\t\t\t\t$docStyle->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (isset($style->protection['hidden'])) {\n\t\t\t\tif (self::boolean((string) $style->protection['hidden'])) {\n\t\t\t\t\t$docStyle->getProtection()->setHidden(PHPExcel_Style_Protection::PROTECTION_PROTECTED);\n\t\t\t\t} else {\n\t\t\t\t\t$docStyle->getProtection()->setHidden(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// top-level style settings\n\t\tif (isset($style->quotePrefix)) {\n\t\t\t$docStyle->setQuotePrefix($style->quotePrefix);\n        }\n\t}\n\n\n\tprivate static function _readBorder($docBorder, $eleBorder) {\n\t\tif (isset($eleBorder[\"style\"])) {\n\t\t\t$docBorder->setBorderStyle((string) $eleBorder[\"style\"]);\n\t\t}\n\t\tif (isset($eleBorder->color)) {\n\t\t\t$docBorder->getColor()->setARGB(self::_readColor($eleBorder->color));\n\t\t}\n\t}\n\n\n\tprivate function _parseRichText($is = null) {\n\t\t$value = new PHPExcel_RichText();\n\n\t\tif (isset($is->t)) {\n\t\t\t$value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $is->t ) );\n\t\t} else {\n\t\t\tif(is_object($is->r)) {\n\t\t\tforeach ($is->r as $run) {\n\t\t\t\tif (!isset($run->rPr)) {\n\t\t\t\t\t$objText = $value->createText( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) );\n\n\t\t\t\t} else {\n\t\t\t\t\t$objText = $value->createTextRun( PHPExcel_Shared_String::ControlCharacterOOXML2PHP( (string) $run->t ) );\n\n\t\t\t\t\tif (isset($run->rPr->rFont[\"val\"])) {\n\t\t\t\t\t\t$objText->getFont()->setName((string) $run->rPr->rFont[\"val\"]);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isset($run->rPr->sz[\"val\"])) {\n\t\t\t\t\t\t$objText->getFont()->setSize((string) $run->rPr->sz[\"val\"]);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isset($run->rPr->color)) {\n\t\t\t\t\t\t$objText->getFont()->setColor( new PHPExcel_Style_Color( self::_readColor($run->rPr->color) ) );\n\t\t\t\t\t}\n\n\t\t\t\t\tif ((isset($run->rPr->b[\"val\"]) && self::boolean((string) $run->rPr->b[\"val\"])) ||\n\t\t\t\t\t\t(isset($run->rPr->b) && !isset($run->rPr->b[\"val\"]))) {\n\t\t\t\t\t\t$objText->getFont()->setBold(TRUE);\n\t\t\t\t\t}\n\n\t\t\t\t\tif ((isset($run->rPr->i[\"val\"]) && self::boolean((string) $run->rPr->i[\"val\"])) ||\n\t\t\t\t\t\t(isset($run->rPr->i) && !isset($run->rPr->i[\"val\"]))) {\n\t\t\t\t\t\t$objText->getFont()->setItalic(TRUE);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isset($run->rPr->vertAlign) && isset($run->rPr->vertAlign[\"val\"])) {\n\t\t\t\t\t\t$vertAlign = strtolower((string)$run->rPr->vertAlign[\"val\"]);\n\t\t\t\t\t\tif ($vertAlign == 'superscript') {\n\t\t\t\t\t\t\t$objText->getFont()->setSuperScript(TRUE);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ($vertAlign == 'subscript') {\n\t\t\t\t\t\t\t$objText->getFont()->setSubScript(TRUE);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tif (isset($run->rPr->u) && !isset($run->rPr->u[\"val\"])) {\n\t\t\t\t\t\t$objText->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);\n\t\t\t\t\t} else if (isset($run->rPr->u) && isset($run->rPr->u[\"val\"])) {\n\t\t\t\t\t\t$objText->getFont()->setUnderline((string)$run->rPr->u[\"val\"]);\n\t\t\t\t\t}\n\n\t\t\t\t\tif ((isset($run->rPr->strike[\"val\"]) && self::boolean((string) $run->rPr->strike[\"val\"])) ||\n\t\t\t\t\t\t(isset($run->rPr->strike) && !isset($run->rPr->strike[\"val\"]))) {\n\t\t\t\t\t\t$objText->getFont()->setStrikethrough(TRUE);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn $value;\n\t}\n\n\tprivate function _readRibbon($excel, $customUITarget, $zip)\n    {\n\t\t$baseDir = dirname($customUITarget);\n\t\t$nameCustomUI = basename($customUITarget);\n        // get the xml file (ribbon)\n\t\t$localRibbon = $this->_getFromZipArchive($zip, $customUITarget);\n\t\t$customUIImagesNames = array();\n        $customUIImagesBinaries = array();\n        // something like customUI/_rels/customUI.xml.rels\n\t\t$pathRels = $baseDir . '/_rels/' . $nameCustomUI . '.rels';\n\t\t$dataRels = $this->_getFromZipArchive($zip, $pathRels);\n\t\tif ($dataRels) {\n            // exists and not empty if the ribbon have some pictures (other than internal MSO)\n\t\t\t$UIRels = simplexml_load_string($this->securityScan($dataRels), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t\tif ($UIRels) {\n\t\t\t\t// we need to save id and target to avoid parsing customUI.xml and \"guess\" if it's a pseudo callback who load the image\n\t\t\t\tforeach ($UIRels->Relationship as $ele) {\n\t\t\t\t\tif ($ele[\"Type\"] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image') {\n                        // an image ?\n\t\t\t\t\t\t$customUIImagesNames[(string) $ele['Id']] = (string)$ele['Target'];\n\t\t\t\t\t\t$customUIImagesBinaries[(string)$ele['Target']] = $this->_getFromZipArchive($zip, $baseDir . '/' . (string) $ele['Target']);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tif ($localRibbon) {\n\t\t\t$excel->setRibbonXMLData($customUITarget, $localRibbon);\n\t\t\tif (count($customUIImagesNames) > 0 && count($customUIImagesBinaries) > 0) {\n\t\t\t\t$excel->setRibbonBinObjects($customUIImagesNames, $customUIImagesBinaries);\n\t\t\t} else {\n\t\t\t\t$excel->setRibbonBinObjects(NULL);\n\t\t\t}\n\t\t} else {\n\t\t\t$excel->setRibbonXMLData(NULL);\n\t\t\t$excel->setRibbonBinObjects(NULL);\n\t\t}\n\t}\n\n\tprivate static function array_item($array, $key = 0) {\n\t\treturn (isset($array[$key]) ? $array[$key] : null);\n\t}\n\n\n\tprivate static function dir_add($base, $add) {\n\t\treturn preg_replace('~[^/]+/\\.\\./~', '', dirname($base) . \"/$add\");\n\t}\n\n\n\tprivate static function toCSSArray($style) {\n\t\t$style = str_replace(array(\"\\r\",\"\\n\"), \"\", $style);\n\n\t\t$temp = explode(';', $style);\n\t\t$style = array();\n\t\tforeach ($temp as $item) {\n\t\t\t$item = explode(':', $item);\n\n\t\t\tif (strpos($item[1], 'px') !== false) {\n\t\t\t\t$item[1] = str_replace('px', '', $item[1]);\n\t\t\t}\n\t\t\tif (strpos($item[1], 'pt') !== false) {\n\t\t\t\t$item[1] = str_replace('pt', '', $item[1]);\n\t\t\t\t$item[1] = PHPExcel_Shared_Font::fontSizeToPixels($item[1]);\n\t\t\t}\n\t\t\tif (strpos($item[1], 'in') !== false) {\n\t\t\t\t$item[1] = str_replace('in', '', $item[1]);\n\t\t\t\t$item[1] = PHPExcel_Shared_Font::inchSizeToPixels($item[1]);\n\t\t\t}\n\t\t\tif (strpos($item[1], 'cm') !== false) {\n\t\t\t\t$item[1] = str_replace('cm', '', $item[1]);\n\t\t\t\t$item[1] = PHPExcel_Shared_Font::centimeterSizeToPixels($item[1]);\n\t\t\t}\n\n\t\t\t$style[$item[0]] = $item[1];\n\t\t}\n\n\t\treturn $style;\n\t}\n\n\tprivate static function boolean($value = NULL)\n\t{\n        if (is_object($value)) {\n\t\t\t$value = (string) $value;\n        }\n\t\tif (is_numeric($value)) {\n\t\t\treturn (bool) $value;\n        }\n\t\treturn ($value === 'true' || $value === 'TRUE');\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/Excel5/Escher.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Reader_Excel5_Escher\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_Excel5_Escher\n{\n\tconst DGGCONTAINER\t\t= 0xF000;\n\tconst BSTORECONTAINER\t= 0xF001;\n\tconst DGCONTAINER\t\t= 0xF002;\n\tconst SPGRCONTAINER\t\t= 0xF003;\n\tconst SPCONTAINER\t\t= 0xF004;\n\tconst DGG\t\t\t\t= 0xF006;\n\tconst BSE\t\t\t\t= 0xF007;\n\tconst DG\t\t\t\t= 0xF008;\n\tconst SPGR\t\t\t\t= 0xF009;\n\tconst SP\t\t\t\t= 0xF00A;\n\tconst OPT\t\t\t\t= 0xF00B;\n\tconst CLIENTTEXTBOX\t\t= 0xF00D;\n\tconst CLIENTANCHOR\t\t= 0xF010;\n\tconst CLIENTDATA\t\t= 0xF011;\n\tconst BLIPJPEG\t\t\t= 0xF01D;\n\tconst BLIPPNG\t\t\t= 0xF01E;\n\tconst SPLITMENUCOLORS\t= 0xF11E;\n\tconst TERTIARYOPT\t\t= 0xF122;\n\n\t/**\n\t * Escher stream data (binary)\n\t *\n\t * @var string\n\t */\n\tprivate $_data;\n\n\t/**\n\t * Size in bytes of the Escher stream data\n\t *\n\t * @var int\n\t */\n\tprivate $_dataSize;\n\n\t/**\n\t * Current position of stream pointer in Escher stream data\n\t *\n\t * @var int\n\t */\n\tprivate $_pos;\n\n\t/**\n\t * The object to be returned by the reader. Modified during load.\n\t *\n\t * @var mixed\n\t */\n\tprivate $_object;\n\n\t/**\n\t * Create a new PHPExcel_Reader_Excel5_Escher instance\n\t *\n\t * @param mixed $object\n\t */\n\tpublic function __construct($object)\n\t{\n\t\t$this->_object = $object;\n\t}\n\n\t/**\n\t * Load Escher stream data. May be a partial Escher stream.\n\t *\n\t * @param string $data\n\t */\n\tpublic function load($data)\n\t{\n\t\t$this->_data = $data;\n\n\t\t// total byte size of Excel data (workbook global substream + sheet substreams)\n\t\t$this->_dataSize = strlen($this->_data);\n\n\t\t$this->_pos = 0;\n\n\t\t// Parse Escher stream\n\t\twhile ($this->_pos < $this->_dataSize) {\n\n\t\t\t// offset: 2; size: 2: Record Type\n\t\t\t$fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2);\n\n\t\t\tswitch ($fbt) {\n\t\t\t\tcase self::DGGCONTAINER:\t$this->_readDggContainer();\t\tbreak;\n\t\t\t\tcase self::DGG:\t\t\t\t$this->_readDgg();\t\t\t\tbreak;\n\t\t\t\tcase self::BSTORECONTAINER:\t$this->_readBstoreContainer();\tbreak;\n\t\t\t\tcase self::BSE:\t\t\t\t$this->_readBSE();\t\t\t\tbreak;\n\t\t\t\tcase self::BLIPJPEG:\t\t$this->_readBlipJPEG();\t\t\tbreak;\n\t\t\t\tcase self::BLIPPNG:\t\t\t$this->_readBlipPNG();\t\t\tbreak;\n\t\t\t\tcase self::OPT:\t\t\t\t$this->_readOPT();\t\t\t\tbreak;\n\t\t\t\tcase self::TERTIARYOPT:\t\t$this->_readTertiaryOPT();\t\tbreak;\n\t\t\t\tcase self::SPLITMENUCOLORS:\t$this->_readSplitMenuColors();\tbreak;\n\t\t\t\tcase self::DGCONTAINER:\t\t$this->_readDgContainer();\t\tbreak;\n\t\t\t\tcase self::DG:\t\t\t\t$this->_readDg();\t\t\t\tbreak;\n\t\t\t\tcase self::SPGRCONTAINER:\t$this->_readSpgrContainer();\tbreak;\n\t\t\t\tcase self::SPCONTAINER:\t\t$this->_readSpContainer();\t\tbreak;\n\t\t\t\tcase self::SPGR:\t\t\t$this->_readSpgr();\t\t\t\tbreak;\n\t\t\t\tcase self::SP:\t\t\t\t$this->_readSp();\t\t\t\tbreak;\n\t\t\t\tcase self::CLIENTTEXTBOX:\t$this->_readClientTextbox();\tbreak;\n\t\t\t\tcase self::CLIENTANCHOR:\t$this->_readClientAnchor();\t\tbreak;\n\t\t\t\tcase self::CLIENTDATA:\t\t$this->_readClientData();\t\tbreak;\n\t\t\t\tdefault:\t\t\t\t\t$this->_readDefault();\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn $this->_object;\n\t}\n\n\t/**\n\t * Read a generic record\n\t */\n\tprivate function _readDefault()\n\t{\n\t\t// offset 0; size: 2; recVer and recInstance\n\t\t$verInstance = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos);\n\n\t\t// offset: 2; size: 2: Record Type\n\t\t$fbt = PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos + 2);\n\n\t\t// bit: 0-3; mask: 0x000F; recVer\n\t\t$recVer = (0x000F & $verInstance) >> 0;\n\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\t}\n\n\t/**\n\t * Read DggContainer record (Drawing Group Container)\n\t */\n\tprivate function _readDggContainer()\n\t{\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\n\t\t// record is a container, read contents\n\t\t$dggContainer = new PHPExcel_Shared_Escher_DggContainer();\n\t\t$this->_object->setDggContainer($dggContainer);\n\t\t$reader = new PHPExcel_Reader_Excel5_Escher($dggContainer);\n\t\t$reader->load($recordData);\n\t}\n\n\t/**\n\t * Read Dgg record (Drawing Group)\n\t */\n\tprivate function _readDgg()\n\t{\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\t}\n\n\t/**\n\t * Read BstoreContainer record (Blip Store Container)\n\t */\n\tprivate function _readBstoreContainer()\n\t{\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\n\t\t// record is a container, read contents\n\t\t$bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer();\n\t\t$this->_object->setBstoreContainer($bstoreContainer);\n\t\t$reader = new PHPExcel_Reader_Excel5_Escher($bstoreContainer);\n\t\t$reader->load($recordData);\n\t}\n\n\t/**\n\t * Read BSE record\n\t */\n\tprivate function _readBSE()\n\t{\n\t\t// offset: 0; size: 2; recVer and recInstance\n\n\t\t// bit: 4-15; mask: 0xFFF0; recInstance\n\t\t$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;\n\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\n\t\t// add BSE to BstoreContainer\n\t\t$BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE();\n\t\t$this->_object->addBSE($BSE);\n\n\t\t$BSE->setBLIPType($recInstance);\n\n\t\t// offset: 0; size: 1; btWin32 (MSOBLIPTYPE)\n\t\t$btWin32 = ord($recordData[0]);\n\n\t\t// offset: 1; size: 1; btWin32 (MSOBLIPTYPE)\n\t\t$btMacOS = ord($recordData[1]);\n\n\t\t// offset: 2; size: 16; MD4 digest\n\t\t$rgbUid = substr($recordData, 2, 16);\n\n\t\t// offset: 18; size: 2; tag\n\t\t$tag = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 18);\n\n\t\t// offset: 20; size: 4; size of BLIP in bytes\n\t\t$size = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 20);\n\n\t\t// offset: 24; size: 4; number of references to this BLIP\n\t\t$cRef = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 24);\n\n\t\t// offset: 28; size: 4; MSOFO file offset\n\t\t$foDelay = PHPExcel_Reader_Excel5::_GetInt4d($recordData, 28);\n\n\t\t// offset: 32; size: 1; unused1\n\t\t$unused1 = ord($recordData{32});\n\n\t\t// offset: 33; size: 1; size of nameData in bytes (including null terminator)\n\t\t$cbName = ord($recordData{33});\n\n\t\t// offset: 34; size: 1; unused2\n\t\t$unused2 = ord($recordData{34});\n\n\t\t// offset: 35; size: 1; unused3\n\t\t$unused3 = ord($recordData{35});\n\n\t\t// offset: 36; size: $cbName; nameData\n\t\t$nameData = substr($recordData, 36, $cbName);\n\n\t\t// offset: 36 + $cbName, size: var; the BLIP data\n\t\t$blipData = substr($recordData, 36 + $cbName);\n\n\t\t// record is a container, read contents\n\t\t$reader = new PHPExcel_Reader_Excel5_Escher($BSE);\n\t\t$reader->load($blipData);\n\t}\n\n\t/**\n\t * Read BlipJPEG record. Holds raw JPEG image data\n\t */\n\tprivate function _readBlipJPEG()\n\t{\n\t\t// offset: 0; size: 2; recVer and recInstance\n\n\t\t// bit: 4-15; mask: 0xFFF0; recInstance\n\t\t$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;\n\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\n\t\t$pos = 0;\n\n\t\t// offset: 0; size: 16; rgbUid1 (MD4 digest of)\n\t\t$rgbUid1 = substr($recordData, 0, 16);\n\t\t$pos += 16;\n\n\t\t// offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3\n\t\tif (in_array($recInstance, array(0x046B, 0x06E3))) {\n\t\t\t$rgbUid2 = substr($recordData, 16, 16);\n\t\t\t$pos += 16;\n\t\t}\n\n\t\t// offset: var; size: 1; tag\n\t\t$tag = ord($recordData{$pos});\n\t\t$pos += 1;\n\n\t\t// offset: var; size: var; the raw image data\n\t\t$data = substr($recordData, $pos);\n\n\t\t$blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip();\n\t\t$blip->setData($data);\n\n\t\t$this->_object->setBlip($blip);\n\t}\n\n\t/**\n\t * Read BlipPNG record. Holds raw PNG image data\n\t */\n\tprivate function _readBlipPNG()\n\t{\n\t\t// offset: 0; size: 2; recVer and recInstance\n\n\t\t// bit: 4-15; mask: 0xFFF0; recInstance\n\t\t$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;\n\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\n\t\t$pos = 0;\n\n\t\t// offset: 0; size: 16; rgbUid1 (MD4 digest of)\n\t\t$rgbUid1 = substr($recordData, 0, 16);\n\t\t$pos += 16;\n\n\t\t// offset: 16; size: 16; rgbUid2 (MD4 digest), only if $recInstance = 0x46B or 0x6E3\n\t\tif ($recInstance == 0x06E1) {\n\t\t\t$rgbUid2 = substr($recordData, 16, 16);\n\t\t\t$pos += 16;\n\t\t}\n\n\t\t// offset: var; size: 1; tag\n\t\t$tag = ord($recordData{$pos});\n\t\t$pos += 1;\n\n\t\t// offset: var; size: var; the raw image data\n\t\t$data = substr($recordData, $pos);\n\n\t\t$blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip();\n\t\t$blip->setData($data);\n\n\t\t$this->_object->setBlip($blip);\n\t}\n\n\t/**\n\t * Read OPT record. This record may occur within DggContainer record or SpContainer\n\t */\n\tprivate function _readOPT()\n\t{\n\t\t// offset: 0; size: 2; recVer and recInstance\n\n\t\t// bit: 4-15; mask: 0xFFF0; recInstance\n\t\t$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;\n\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\n\t\t$this->_readOfficeArtRGFOPTE($recordData, $recInstance);\n\t}\n\n\t/**\n\t * Read TertiaryOPT record\n\t */\n\tprivate function _readTertiaryOPT()\n\t{\n\t\t// offset: 0; size: 2; recVer and recInstance\n\n\t\t// bit: 4-15; mask: 0xFFF0; recInstance\n\t\t$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;\n\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\t}\n\n\t/**\n\t * Read SplitMenuColors record\n\t */\n\tprivate function _readSplitMenuColors()\n\t{\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\t}\n\n\t/**\n\t * Read DgContainer record (Drawing Container)\n\t */\n\tprivate function _readDgContainer()\n\t{\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\n\t\t// record is a container, read contents\n\t\t$dgContainer = new PHPExcel_Shared_Escher_DgContainer();\n\t\t$this->_object->setDgContainer($dgContainer);\n\t\t$reader = new PHPExcel_Reader_Excel5_Escher($dgContainer);\n\t\t$escher = $reader->load($recordData);\n\t}\n\n\t/**\n\t * Read Dg record (Drawing)\n\t */\n\tprivate function _readDg()\n\t{\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\t}\n\n\t/**\n\t * Read SpgrContainer record (Shape Group Container)\n\t */\n\tprivate function _readSpgrContainer()\n\t{\n\t\t// context is either context DgContainer or SpgrContainer\n\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\n\t\t// record is a container, read contents\n\t\t$spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer();\n\n\t\tif ($this->_object instanceof PHPExcel_Shared_Escher_DgContainer) {\n\t\t\t// DgContainer\n\t\t\t$this->_object->setSpgrContainer($spgrContainer);\n\t\t} else {\n\t\t\t// SpgrContainer\n\t\t\t$this->_object->addChild($spgrContainer);\n\t\t}\n\n\t\t$reader = new PHPExcel_Reader_Excel5_Escher($spgrContainer);\n\t\t$escher = $reader->load($recordData);\n\t}\n\n\t/**\n\t * Read SpContainer record (Shape Container)\n\t */\n\tprivate function _readSpContainer()\n\t{\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// add spContainer to spgrContainer\n\t\t$spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();\n\t\t$this->_object->addChild($spContainer);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\n\t\t// record is a container, read contents\n\t\t$reader = new PHPExcel_Reader_Excel5_Escher($spContainer);\n\t\t$escher = $reader->load($recordData);\n\t}\n\n\t/**\n\t * Read Spgr record (Shape Group)\n\t */\n\tprivate function _readSpgr()\n\t{\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\t}\n\n\t/**\n\t * Read Sp record (Shape)\n\t */\n\tprivate function _readSp()\n\t{\n\t\t// offset: 0; size: 2; recVer and recInstance\n\n\t\t// bit: 4-15; mask: 0xFFF0; recInstance\n\t\t$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;\n\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\t}\n\n\t/**\n\t * Read ClientTextbox record\n\t */\n\tprivate function _readClientTextbox()\n\t{\n\t\t// offset: 0; size: 2; recVer and recInstance\n\n\t\t// bit: 4-15; mask: 0xFFF0; recInstance\n\t\t$recInstance = (0xFFF0 & PHPExcel_Reader_Excel5::_GetInt2d($this->_data, $this->_pos)) >> 4;\n\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\t}\n\n\t/**\n\t * Read ClientAnchor record. This record holds information about where the shape is anchored in worksheet\n\t */\n\tprivate function _readClientAnchor()\n\t{\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\n\t\t// offset: 2; size: 2; upper-left corner column index (0-based)\n\t\t$c1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 2);\n\n\t\t// offset: 4; size: 2; upper-left corner horizontal offset in 1/1024 of column width\n\t\t$startOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 4);\n\n\t\t// offset: 6; size: 2; upper-left corner row index (0-based)\n\t\t$r1 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 6);\n\n\t\t// offset: 8; size: 2; upper-left corner vertical offset in 1/256 of row height\n\t\t$startOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 8);\n\n\t\t// offset: 10; size: 2; bottom-right corner column index (0-based)\n\t\t$c2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 10);\n\n\t\t// offset: 12; size: 2; bottom-right corner horizontal offset in 1/1024 of column width\n\t\t$endOffsetX = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 12);\n\n\t\t// offset: 14; size: 2; bottom-right corner row index (0-based)\n\t\t$r2 = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 14);\n\n\t\t// offset: 16; size: 2; bottom-right corner vertical offset in 1/256 of row height\n\t\t$endOffsetY = PHPExcel_Reader_Excel5::_GetInt2d($recordData, 16);\n\n\t\t// set the start coordinates\n\t\t$this->_object->setStartCoordinates(PHPExcel_Cell::stringFromColumnIndex($c1) . ($r1 + 1));\n\n\t\t// set the start offsetX\n\t\t$this->_object->setStartOffsetX($startOffsetX);\n\n\t\t// set the start offsetY\n\t\t$this->_object->setStartOffsetY($startOffsetY);\n\n\t\t// set the end coordinates\n\t\t$this->_object->setEndCoordinates(PHPExcel_Cell::stringFromColumnIndex($c2) . ($r2 + 1));\n\n\t\t// set the end offsetX\n\t\t$this->_object->setEndOffsetX($endOffsetX);\n\n\t\t// set the end offsetY\n\t\t$this->_object->setEndOffsetY($endOffsetY);\n\t}\n\n\t/**\n\t * Read ClientData record\n\t */\n\tprivate function _readClientData()\n\t{\n\t\t$length = PHPExcel_Reader_Excel5::_GetInt4d($this->_data, $this->_pos + 4);\n\t\t$recordData = substr($this->_data, $this->_pos + 8, $length);\n\n\t\t// move stream pointer to next record\n\t\t$this->_pos += 8 + $length;\n\t}\n\n\t/**\n\t * Read OfficeArtRGFOPTE table of property-value pairs\n\t *\n\t * @param string $data Binary data\n\t * @param int $n Number of properties\n\t */\n\tprivate function _readOfficeArtRGFOPTE($data, $n) {\n\n\t\t$splicedComplexData = substr($data, 6 * $n);\n\n\t\t// loop through property-value pairs\n\t\tfor ($i = 0; $i < $n; ++$i) {\n\t\t\t// read 6 bytes at a time\n\t\t\t$fopte = substr($data, 6 * $i, 6);\n\n\t\t\t// offset: 0; size: 2; opid\n\t\t\t$opid = PHPExcel_Reader_Excel5::_GetInt2d($fopte, 0);\n\n\t\t\t// bit: 0-13; mask: 0x3FFF; opid.opid\n\t\t\t$opidOpid = (0x3FFF & $opid) >> 0;\n\n\t\t\t// bit: 14; mask 0x4000; 1 = value in op field is BLIP identifier\n\t\t\t$opidFBid = (0x4000 & $opid) >> 14;\n\n\t\t\t// bit: 15; mask 0x8000; 1 = this is a complex property, op field specifies size of complex data\n\t\t\t$opidFComplex = (0x8000 & $opid) >> 15;\n\n\t\t\t// offset: 2; size: 4; the value for this property\n\t\t\t$op = PHPExcel_Reader_Excel5::_GetInt4d($fopte, 2);\n\n\t\t\tif ($opidFComplex) {\n\t\t\t\t$complexData = substr($splicedComplexData, 0, $op);\n\t\t\t\t$splicedComplexData = substr($splicedComplexData, $op);\n\n\t\t\t\t// we store string value with complex data\n\t\t\t\t$value = $complexData;\n\t\t\t} else {\n\t\t\t\t// we store integer value\n\t\t\t\t$value = $op;\n\t\t\t}\n\n\t\t\t$this->_object->setOPT($opidOpid, $value);\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/Excel5/MD5.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt        LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Reader_Excel5_MD5\n *\n * @category        PHPExcel\n * @package                PHPExcel_Reader_Excel5\n * @copyright        Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_Excel5_MD5\n{\n    // Context\n    private $a;\n    private $b;\n    private $c;\n    private $d;\n\n\n    /**\n     * MD5 stream constructor\n     */\n    public function __construct()\n    {\n        $this->reset();\n    }\n\n\n    /**\n     * Reset the MD5 stream context\n     */\n    public function reset()\n    {\n        $this->a = 0x67452301;\n        $this->b = 0xEFCDAB89;\n        $this->c = 0x98BADCFE;\n        $this->d = 0x10325476;\n    }\n\n\n    /**\n     * Get MD5 stream context\n     * \n     * @return string\n     */\n    public function getContext()\n    {\n        $s = '';\n        foreach (array('a', 'b', 'c', 'd') as $i) {\n            $v = $this->{$i};\n            $s .= chr($v & 0xff);\n            $s .= chr(($v >> 8) & 0xff);\n            $s .= chr(($v >> 16) & 0xff);\n            $s .= chr(($v >> 24) & 0xff);\n        }\n\n        return $s;\n    }\n\n\n    /**\n     * Add data to context\n     * \n     * @param string $data Data to add\n     */\n    public function add($data)\n    {\n        $words = array_values(unpack('V16', $data));\n\n        $A = $this->a;\n        $B = $this->b;\n        $C = $this->c;\n        $D = $this->d;\n\n        $F = array('PHPExcel_Reader_Excel5_MD5','F');\n        $G = array('PHPExcel_Reader_Excel5_MD5','G');\n        $H = array('PHPExcel_Reader_Excel5_MD5','H');\n        $I = array('PHPExcel_Reader_Excel5_MD5','I');\n\n        /* ROUND 1 */\n        self::step($F, $A, $B, $C, $D, $words[0], 7, 0xd76aa478);\n        self::step($F, $D, $A, $B, $C, $words[1], 12, 0xe8c7b756);\n        self::step($F, $C, $D, $A, $B, $words[2], 17, 0x242070db);\n        self::step($F, $B, $C, $D, $A, $words[3], 22, 0xc1bdceee);\n        self::step($F, $A, $B, $C, $D, $words[4], 7, 0xf57c0faf);\n        self::step($F, $D, $A, $B, $C, $words[5], 12, 0x4787c62a);\n        self::step($F, $C, $D, $A, $B, $words[6], 17, 0xa8304613);\n        self::step($F, $B, $C, $D, $A, $words[7], 22, 0xfd469501);\n        self::step($F, $A, $B, $C, $D, $words[8], 7, 0x698098d8);\n        self::step($F, $D, $A, $B, $C, $words[9], 12, 0x8b44f7af);\n        self::step($F, $C, $D, $A, $B, $words[10], 17, 0xffff5bb1);\n        self::step($F, $B, $C, $D, $A, $words[11], 22, 0x895cd7be);\n        self::step($F, $A, $B, $C, $D, $words[12], 7, 0x6b901122);\n        self::step($F, $D, $A, $B, $C, $words[13], 12, 0xfd987193);\n        self::step($F, $C, $D, $A, $B, $words[14], 17, 0xa679438e);\n        self::step($F, $B, $C, $D, $A, $words[15], 22, 0x49b40821);\n\n        /* ROUND 2 */\n        self::step($G, $A, $B, $C, $D, $words[1], 5, 0xf61e2562);\n        self::step($G, $D, $A, $B, $C, $words[6], 9, 0xc040b340);\n        self::step($G, $C, $D, $A, $B, $words[11], 14, 0x265e5a51);\n        self::step($G, $B, $C, $D, $A, $words[0], 20, 0xe9b6c7aa);\n        self::step($G, $A, $B, $C, $D, $words[5], 5, 0xd62f105d);\n        self::step($G, $D, $A, $B, $C, $words[10], 9, 0x02441453);\n        self::step($G, $C, $D, $A, $B, $words[15], 14, 0xd8a1e681);\n        self::step($G, $B, $C, $D, $A, $words[4], 20, 0xe7d3fbc8);\n        self::step($G, $A, $B, $C, $D, $words[9], 5, 0x21e1cde6);\n        self::step($G, $D, $A, $B, $C, $words[14], 9, 0xc33707d6);\n        self::step($G, $C, $D, $A, $B, $words[3], 14, 0xf4d50d87);\n        self::step($G, $B, $C, $D, $A, $words[8], 20, 0x455a14ed);\n        self::step($G, $A, $B, $C, $D, $words[13], 5, 0xa9e3e905);\n        self::step($G, $D, $A, $B, $C, $words[2], 9, 0xfcefa3f8);\n        self::step($G, $C, $D, $A, $B, $words[7], 14, 0x676f02d9);\n        self::step($G, $B, $C, $D, $A, $words[12], 20, 0x8d2a4c8a);\n\n        /* ROUND 3 */\n        self::step($H, $A, $B, $C, $D, $words[5], 4, 0xfffa3942);\n        self::step($H, $D, $A, $B, $C, $words[8], 11, 0x8771f681);\n        self::step($H, $C, $D, $A, $B, $words[11], 16, 0x6d9d6122);\n        self::step($H, $B, $C, $D, $A, $words[14], 23, 0xfde5380c);\n        self::step($H, $A, $B, $C, $D, $words[1], 4, 0xa4beea44);\n        self::step($H, $D, $A, $B, $C, $words[4], 11, 0x4bdecfa9);\n        self::step($H, $C, $D, $A, $B, $words[7], 16, 0xf6bb4b60);\n        self::step($H, $B, $C, $D, $A, $words[10], 23, 0xbebfbc70);\n        self::step($H, $A, $B, $C, $D, $words[13], 4, 0x289b7ec6);\n        self::step($H, $D, $A, $B, $C, $words[0], 11, 0xeaa127fa);\n        self::step($H, $C, $D, $A, $B, $words[3], 16, 0xd4ef3085);\n        self::step($H, $B, $C, $D, $A, $words[6], 23, 0x04881d05);\n        self::step($H, $A, $B, $C, $D, $words[9], 4, 0xd9d4d039);\n        self::step($H, $D, $A, $B, $C, $words[12], 11, 0xe6db99e5);\n        self::step($H, $C, $D, $A, $B, $words[15], 16, 0x1fa27cf8);\n        self::step($H, $B, $C, $D, $A, $words[2], 23, 0xc4ac5665);\n\n        /* ROUND 4 */\n        self::step($I, $A, $B, $C, $D, $words[0], 6, 0xf4292244);\n        self::step($I, $D, $A, $B, $C, $words[7], 10, 0x432aff97);\n        self::step($I, $C, $D, $A, $B, $words[14], 15, 0xab9423a7);\n        self::step($I, $B, $C, $D, $A, $words[5], 21, 0xfc93a039);\n        self::step($I, $A, $B, $C, $D, $words[12], 6, 0x655b59c3);\n        self::step($I, $D, $A, $B, $C, $words[3], 10, 0x8f0ccc92);\n        self::step($I, $C, $D, $A, $B, $words[10], 15, 0xffeff47d);\n        self::step($I, $B, $C, $D, $A, $words[1], 21, 0x85845dd1);\n        self::step($I, $A, $B, $C, $D, $words[8], 6, 0x6fa87e4f);\n        self::step($I, $D, $A, $B, $C, $words[15], 10, 0xfe2ce6e0);\n        self::step($I, $C, $D, $A, $B, $words[6], 15, 0xa3014314);\n        self::step($I, $B, $C, $D, $A, $words[13], 21, 0x4e0811a1);\n        self::step($I, $A, $B, $C, $D, $words[4], 6, 0xf7537e82);\n        self::step($I, $D, $A, $B, $C, $words[11], 10, 0xbd3af235);\n        self::step($I, $C, $D, $A, $B, $words[2], 15, 0x2ad7d2bb);\n        self::step($I, $B, $C, $D, $A, $words[9], 21, 0xeb86d391);\n\n        $this->a = ($this->a + $A) & 0xffffffff;\n        $this->b = ($this->b + $B) & 0xffffffff;\n        $this->c = ($this->c + $C) & 0xffffffff;\n        $this->d = ($this->d + $D) & 0xffffffff;\n    }\n\n\n    private static function F($X, $Y, $Z)\n    {\n        return (($X & $Y) | ((~ $X) & $Z)); // X AND Y OR NOT X AND Z\n    }\n\n\n    private static function G($X, $Y, $Z)\n    {\n        return (($X & $Z) | ($Y & (~ $Z))); // X AND Z OR Y AND NOT Z\n    }\n\n\n    private static function H($X, $Y, $Z)\n    {\n        return ($X ^ $Y ^ $Z); // X XOR Y XOR Z\n    }\n\n\n    private static function I($X, $Y, $Z)\n    {\n        return ($Y ^ ($X | (~ $Z))) ; // Y XOR (X OR NOT Z)\n    }\n\n\n    private static function step($func, &$A, $B, $C, $D, $M, $s, $t)\n    {\n        $A = ($A + call_user_func($func, $B, $C, $D) + $M + $t) & 0xffffffff;\n        $A = self::rotate($A, $s);\n        $A = ($B + $A) & 0xffffffff;\n    }\n\n\n    private static function rotate($decimal, $bits)\n    {\n        $binary = str_pad(decbin($decimal), 32, \"0\", STR_PAD_LEFT);\n        return bindec(substr($binary, $bits).substr($binary, 0, $bits));\n    }\n}"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/Excel5/RC4.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Reader_Excel5_RC4\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Reader_Excel5\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_Excel5_RC4\n{\n\t// Context\n\tvar $s = array();\n\tvar $i = 0;\n\tvar $j = 0;\n\n\t/**\n\t * RC4 stream decryption/encryption constrcutor\n\t * \n\t * @param string $key Encryption key/passphrase\n\t */\n\tpublic function __construct($key)\n\t{\n\t\t$len = strlen($key);\n\n\t\tfor ($this->i = 0; $this->i < 256; $this->i++) {\n\t\t\t$this->s[$this->i] = $this->i;\n\t\t}\n\n\t\t$this->j = 0;\n\t\tfor ($this->i = 0; $this->i < 256; $this->i++) {\n\t\t\t$this->j = ($this->j + $this->s[$this->i] + ord($key[$this->i % $len])) % 256;\n\t\t\t$t = $this->s[$this->i];\n\t\t\t$this->s[$this->i] = $this->s[$this->j];\n\t\t\t$this->s[$this->j] = $t;\n\t\t}\n\t\t$this->i = $this->j = 0;\n\t}\n\n\t/**\n\t * Symmetric decryption/encryption function\n\t * \n\t * @param string $data Data to encrypt/decrypt\n\t * \n\t * @return string\n\t */\n\tpublic function RC4($data)\n\t{\n\t\t$len = strlen($data);\n\t\tfor ($c = 0; $c < $len; $c++) {\n\t\t\t$this->i = ($this->i + 1) % 256;\n\t\t\t$this->j = ($this->j + $this->s[$this->i]) % 256;\n\t\t\t$t = $this->s[$this->i];\n\t\t\t$this->s[$this->i] = $this->s[$this->j];\n\t\t\t$this->s[$this->j] = $t;\n\n\t\t\t$t = ($this->s[$this->i] + $this->s[$this->j]) % 256;\n\n\t\t\t$data[$c] = chr(ord($data[$c]) ^ $this->s[$t]);\n\t\t}\n\t\treturn $data;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/Excel5.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (c) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel_Reader_Excel5\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n// Original file header of ParseXL (used as the base for this class):\r\n// --------------------------------------------------------------------------------\r\n// Adapted from Excel_Spreadsheet_Reader developed by users bizon153,\r\n// trex005, and mmp11 (SourceForge.net)\r\n// http://sourceforge.net/projects/phpexcelreader/\r\n// Primary changes made by canyoncasa (dvc) for ParseXL 1.00 ...\r\n//\t Modelled moreso after Perl Excel Parse/Write modules\r\n//\t Added Parse_Excel_Spreadsheet object\r\n//\t\t Reads a whole worksheet or tab as row,column array or as\r\n//\t\t associated hash of indexed rows and named column fields\r\n//\t Added variables for worksheet (tab) indexes and names\r\n//\t Added an object call for loading individual woorksheets\r\n//\t Changed default indexing defaults to 0 based arrays\r\n//\t Fixed date/time and percent formats\r\n//\t Includes patches found at SourceForge...\r\n//\t\t unicode patch by nobody\r\n//\t\t unpack(\"d\") machine depedency patch by matchy\r\n//\t\t boundsheet utf16 patch by bjaenichen\r\n//\t Renamed functions for shorter names\r\n//\t General code cleanup and rigor, including <80 column width\r\n//\t Included a testcase Excel file and PHP example calls\r\n//\t Code works for PHP 5.x\r\n\r\n// Primary changes made by canyoncasa (dvc) for ParseXL 1.10 ...\r\n// http://sourceforge.net/tracker/index.php?func=detail&aid=1466964&group_id=99160&atid=623334\r\n//\t Decoding of formula conditions, results, and tokens.\r\n//\t Support for user-defined named cells added as an array \"namedcells\"\r\n//\t\t Patch code for user-defined named cells supports single cells only.\r\n//\t\t NOTE: this patch only works for BIFF8 as BIFF5-7 use a different\r\n//\t\t external sheet reference structure\r\n\r\n\r\n/** PHPExcel root directory */\r\nif (!defined('PHPEXCEL_ROOT')) {\r\n\t/**\r\n\t * @ignore\r\n\t */\r\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\r\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\r\n}\r\n\r\n/**\r\n * PHPExcel_Reader_Excel5\r\n *\r\n * This class uses {@link http://sourceforge.net/projects/phpexcelreader/parseXL}\r\n *\r\n * @category\tPHPExcel\r\n * @package\t\tPHPExcel_Reader_Excel5\r\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n */\r\nclass PHPExcel_Reader_Excel5 extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader\r\n{\r\n\t// ParseXL definitions\r\n\tconst XLS_BIFF8\t\t\t\t\t\t= 0x0600;\r\n\tconst XLS_BIFF7\t\t\t\t\t\t= 0x0500;\r\n\tconst XLS_WorkbookGlobals\t\t\t= 0x0005;\r\n\tconst XLS_Worksheet\t\t\t\t\t= 0x0010;\r\n\r\n\t// record identifiers\r\n\tconst XLS_Type_FORMULA\t\t\t\t= 0x0006;\r\n\tconst XLS_Type_EOF\t\t\t\t\t= 0x000a;\r\n\tconst XLS_Type_PROTECT\t\t\t\t= 0x0012;\r\n\tconst XLS_Type_OBJECTPROTECT\t\t= 0x0063;\r\n\tconst XLS_Type_SCENPROTECT\t\t\t= 0x00dd;\r\n\tconst XLS_Type_PASSWORD\t\t\t\t= 0x0013;\r\n\tconst XLS_Type_HEADER\t\t\t\t= 0x0014;\r\n\tconst XLS_Type_FOOTER\t\t\t\t= 0x0015;\r\n\tconst XLS_Type_EXTERNSHEET\t\t\t= 0x0017;\r\n\tconst XLS_Type_DEFINEDNAME\t\t\t= 0x0018;\r\n\tconst XLS_Type_VERTICALPAGEBREAKS\t= 0x001a;\r\n\tconst XLS_Type_HORIZONTALPAGEBREAKS\t= 0x001b;\r\n\tconst XLS_Type_NOTE\t\t\t\t\t= 0x001c;\r\n\tconst XLS_Type_SELECTION\t\t\t= 0x001d;\r\n\tconst XLS_Type_DATEMODE\t\t\t\t= 0x0022;\r\n\tconst XLS_Type_EXTERNNAME\t\t\t= 0x0023;\r\n\tconst XLS_Type_LEFTMARGIN\t\t\t= 0x0026;\r\n\tconst XLS_Type_RIGHTMARGIN\t\t\t= 0x0027;\r\n\tconst XLS_Type_TOPMARGIN\t\t\t= 0x0028;\r\n\tconst XLS_Type_BOTTOMMARGIN\t\t\t= 0x0029;\r\n\tconst XLS_Type_PRINTGRIDLINES\t\t= 0x002b;\r\n\tconst XLS_Type_FILEPASS\t\t\t\t= 0x002f;\r\n\tconst XLS_Type_FONT\t\t\t\t\t= 0x0031;\r\n\tconst XLS_Type_CONTINUE\t\t\t\t= 0x003c;\r\n\tconst XLS_Type_PANE\t\t\t\t\t= 0x0041;\r\n\tconst XLS_Type_CODEPAGE\t\t\t\t= 0x0042;\r\n\tconst XLS_Type_DEFCOLWIDTH \t\t\t= 0x0055;\r\n\tconst XLS_Type_OBJ\t\t\t\t\t= 0x005d;\r\n\tconst XLS_Type_COLINFO\t\t\t\t= 0x007d;\r\n\tconst XLS_Type_IMDATA\t\t\t\t= 0x007f;\r\n\tconst XLS_Type_SHEETPR\t\t\t\t= 0x0081;\r\n\tconst XLS_Type_HCENTER\t\t\t\t= 0x0083;\r\n\tconst XLS_Type_VCENTER\t\t\t\t= 0x0084;\r\n\tconst XLS_Type_SHEET\t\t\t\t= 0x0085;\r\n\tconst XLS_Type_PALETTE\t\t\t\t= 0x0092;\r\n\tconst XLS_Type_SCL\t\t\t\t\t= 0x00a0;\r\n\tconst XLS_Type_PAGESETUP\t\t\t= 0x00a1;\r\n\tconst XLS_Type_MULRK\t\t\t\t= 0x00bd;\r\n\tconst XLS_Type_MULBLANK\t\t\t\t= 0x00be;\r\n\tconst XLS_Type_DBCELL\t\t\t\t= 0x00d7;\r\n\tconst XLS_Type_XF\t\t\t\t\t= 0x00e0;\r\n\tconst XLS_Type_MERGEDCELLS\t\t\t= 0x00e5;\r\n\tconst XLS_Type_MSODRAWINGGROUP\t\t= 0x00eb;\r\n\tconst XLS_Type_MSODRAWING\t\t\t= 0x00ec;\r\n\tconst XLS_Type_SST\t\t\t\t\t= 0x00fc;\r\n\tconst XLS_Type_LABELSST\t\t\t\t= 0x00fd;\r\n\tconst XLS_Type_EXTSST\t\t\t\t= 0x00ff;\r\n\tconst XLS_Type_EXTERNALBOOK\t\t\t= 0x01ae;\r\n\tconst XLS_Type_DATAVALIDATIONS\t\t= 0x01b2;\r\n\tconst XLS_Type_TXO\t\t\t\t\t= 0x01b6;\r\n\tconst XLS_Type_HYPERLINK\t\t\t= 0x01b8;\r\n\tconst XLS_Type_DATAVALIDATION\t\t= 0x01be;\r\n\tconst XLS_Type_DIMENSION\t\t\t= 0x0200;\r\n\tconst XLS_Type_BLANK\t\t\t\t= 0x0201;\r\n\tconst XLS_Type_NUMBER\t\t\t\t= 0x0203;\r\n\tconst XLS_Type_LABEL\t\t\t\t= 0x0204;\r\n\tconst XLS_Type_BOOLERR\t\t\t\t= 0x0205;\r\n\tconst XLS_Type_STRING\t\t\t\t= 0x0207;\r\n\tconst XLS_Type_ROW\t\t\t\t\t= 0x0208;\r\n\tconst XLS_Type_INDEX\t\t\t\t= 0x020b;\r\n\tconst XLS_Type_ARRAY\t\t\t\t= 0x0221;\r\n\tconst XLS_Type_DEFAULTROWHEIGHT \t= 0x0225;\r\n\tconst XLS_Type_WINDOW2\t\t\t\t= 0x023e;\r\n\tconst XLS_Type_RK\t\t\t\t\t= 0x027e;\r\n\tconst XLS_Type_STYLE\t\t\t\t= 0x0293;\r\n\tconst XLS_Type_FORMAT\t\t\t\t= 0x041e;\r\n\tconst XLS_Type_SHAREDFMLA\t\t\t= 0x04bc;\r\n\tconst XLS_Type_BOF\t\t\t\t\t= 0x0809;\r\n\tconst XLS_Type_SHEETPROTECTION\t\t= 0x0867;\r\n\tconst XLS_Type_RANGEPROTECTION\t\t= 0x0868;\r\n\tconst XLS_Type_SHEETLAYOUT\t\t\t= 0x0862;\r\n\tconst XLS_Type_XFEXT\t\t\t\t= 0x087d;\r\n\tconst XLS_Type_PAGELAYOUTVIEW\t\t= 0x088b;\r\n\tconst XLS_Type_UNKNOWN\t\t\t\t= 0xffff;\r\n\r\n\t// Encryption type\r\n\tconst MS_BIFF_CRYPTO_NONE = 0;\r\n\tconst MS_BIFF_CRYPTO_XOR  = 1;\r\n\tconst MS_BIFF_CRYPTO_RC4  = 2;\r\n\t\r\n\t// Size of stream blocks when using RC4 encryption\r\n\tconst REKEY_BLOCK = 0x400;\r\n\r\n\t/**\r\n\t * Summary Information stream data.\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_summaryInformation;\r\n\r\n\t/**\r\n\t * Extended Summary Information stream data.\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_documentSummaryInformation;\r\n\r\n\t/**\r\n\t * User-Defined Properties stream data.\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_userDefinedProperties;\r\n\r\n\t/**\r\n\t * Workbook stream data. (Includes workbook globals substream as well as sheet substreams)\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_data;\r\n\r\n\t/**\r\n\t * Size in bytes of $this->_data\r\n\t *\r\n\t * @var int\r\n\t */\r\n\tprivate $_dataSize;\r\n\r\n\t/**\r\n\t * Current position in stream\r\n\t *\r\n\t * @var integer\r\n\t */\r\n\tprivate $_pos;\r\n\r\n\t/**\r\n\t * Workbook to be returned by the reader.\r\n\t *\r\n\t * @var PHPExcel\r\n\t */\r\n\tprivate $_phpExcel;\r\n\r\n\t/**\r\n\t * Worksheet that is currently being built by the reader.\r\n\t *\r\n\t * @var PHPExcel_Worksheet\r\n\t */\r\n\tprivate $_phpSheet;\r\n\r\n\t/**\r\n\t * BIFF version\r\n\t *\r\n\t * @var int\r\n\t */\r\n\tprivate $_version;\r\n\r\n\t/**\r\n\t * Codepage set in the Excel file being read. Only important for BIFF5 (Excel 5.0 - Excel 95)\r\n\t * For BIFF8 (Excel 97 - Excel 2003) this will always have the value 'UTF-16LE'\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_codepage;\r\n\r\n\t/**\r\n\t * Shared formats\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_formats;\r\n\r\n\t/**\r\n\t * Shared fonts\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_objFonts;\r\n\r\n\t/**\r\n\t * Color palette\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_palette;\r\n\r\n\t/**\r\n\t * Worksheets\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_sheets;\r\n\r\n\t/**\r\n\t * External books\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_externalBooks;\r\n\r\n\t/**\r\n\t * REF structures. Only applies to BIFF8.\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_ref;\r\n\r\n\t/**\r\n\t * External names\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_externalNames;\r\n\r\n\t/**\r\n\t * Defined names\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_definedname;\r\n\r\n\t/**\r\n\t * Shared strings. Only applies to BIFF8.\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_sst;\r\n\r\n\t/**\r\n\t * Panes are frozen? (in sheet currently being read). See WINDOW2 record.\r\n\t *\r\n\t * @var boolean\r\n\t */\r\n\tprivate $_frozen;\r\n\r\n\t/**\r\n\t * Fit printout to number of pages? (in sheet currently being read). See SHEETPR record.\r\n\t *\r\n\t * @var boolean\r\n\t */\r\n\tprivate $_isFitToPages;\r\n\r\n\t/**\r\n\t * Objects. One OBJ record contributes with one entry.\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_objs;\r\n\r\n\t/**\r\n\t * Text Objects. One TXO record corresponds with one entry.\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_textObjects;\r\n\r\n\t/**\r\n\t * Cell Annotations (BIFF8)\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_cellNotes;\r\n\r\n\t/**\r\n\t * The combined MSODRAWINGGROUP data\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_drawingGroupData;\r\n\r\n\t/**\r\n\t * The combined MSODRAWING data (per sheet)\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_drawingData;\r\n\r\n\t/**\r\n\t * Keep track of XF index\r\n\t *\r\n\t * @var int\r\n\t */\r\n\tprivate $_xfIndex;\r\n\r\n\t/**\r\n\t * Mapping of XF index (that is a cell XF) to final index in cellXf collection\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_mapCellXfIndex;\r\n\r\n\t/**\r\n\t * Mapping of XF index (that is a style XF) to final index in cellStyleXf collection\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_mapCellStyleXfIndex;\r\n\r\n\t/**\r\n\t * The shared formulas in a sheet. One SHAREDFMLA record contributes with one value.\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_sharedFormulas;\r\n\r\n\t/**\r\n\t * The shared formula parts in a sheet. One FORMULA record contributes with one value if it\r\n\t * refers to a shared formula.\r\n\t *\r\n\t * @var array\r\n\t */\r\n\tprivate $_sharedFormulaParts;\r\n\r\n\t/**\r\n\t * The type of encryption in use\r\n\t *\r\n\t * @var int\t\r\n\t */\r\n\tprivate $_encryption = 0;\r\n\t\r\n\t/**\r\n\t * The position in the stream after which contents are encrypted\r\n\t *\r\n\t * @var int\r\n\t */\r\n\tprivate $_encryptionStartPos = false;\r\n\r\n\t/**\r\n\t * The current RC4 decryption object\r\n\t *\r\n\t * @var PHPExcel_Reader_Excel5_RC4\r\n\t */\r\n\tprivate $_rc4Key = null;\r\n\r\n\t/**\r\n\t * The position in the stream that the RC4 decryption object was left at\r\n\t *\r\n\t * @var int\r\n\t */\r\n\tprivate $_rc4Pos = 0;\r\n\r\n\t/**\r\n\t * The current MD5 context state\r\n\t *\r\n\t * @var string\r\n\t */\r\n\tprivate $_md5Ctxt = null;\r\n\r\n\t/**\r\n\t * Create a new PHPExcel_Reader_Excel5 instance\r\n\t */\r\n\tpublic function __construct() {\r\n\t\t$this->_readFilter = new PHPExcel_Reader_DefaultReadFilter();\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Can the current PHPExcel_Reader_IReader read the file?\r\n\t *\r\n\t * @param \tstring \t\t$pFilename\r\n\t * @return \tboolean\r\n\t * @throws PHPExcel_Reader_Exception\r\n\t */\r\n\tpublic function canRead($pFilename)\r\n\t{\r\n\t\t// Check if file exists\r\n\t\tif (!file_exists($pFilename)) {\r\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\r\n\t\t}\r\n\r\n\t\ttry {\r\n\t\t\t// Use ParseXL for the hard work.\r\n\t\t\t$ole = new PHPExcel_Shared_OLERead();\r\n\r\n\t\t\t// get excel data\r\n\t\t\t$res = $ole->read($pFilename);\r\n\t\t\treturn true;\r\n\t\t} catch (PHPExcel_Exception $e) {\r\n\t\t\treturn false;\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object\r\n\t *\r\n\t * @param \tstring \t\t$pFilename\r\n\t * @throws \tPHPExcel_Reader_Exception\r\n\t */\r\n\tpublic function listWorksheetNames($pFilename)\r\n\t{\r\n\t\t// Check if file exists\r\n\t\tif (!file_exists($pFilename)) {\r\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\r\n\t\t}\r\n\r\n\t\t$worksheetNames = array();\r\n\r\n\t\t// Read the OLE file\r\n\t\t$this->_loadOLE($pFilename);\r\n\r\n\t\t// total byte size of Excel data (workbook global substream + sheet substreams)\r\n\t\t$this->_dataSize = strlen($this->_data);\r\n\r\n\t\t$this->_pos\t\t= 0;\r\n\t\t$this->_sheets\t= array();\r\n\r\n\t\t// Parse Workbook Global Substream\r\n\t\twhile ($this->_pos < $this->_dataSize) {\r\n\t\t\t$code = self::_GetInt2d($this->_data, $this->_pos);\r\n\r\n\t\t\tswitch ($code) {\r\n\t\t\t\tcase self::XLS_Type_BOF:\t$this->_readBof();\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_SHEET:\t$this->_readSheet();\tbreak;\r\n\t\t\t\tcase self::XLS_Type_EOF:\t$this->_readDefault();\tbreak 2;\r\n\t\t\t\tdefault:\t\t\t\t\t$this->_readDefault();\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tforeach ($this->_sheets as $sheet) {\r\n\t\t\tif ($sheet['sheetType'] != 0x00) {\r\n\t\t\t\t// 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t$worksheetNames[] = $sheet['name'];\r\n\t\t}\r\n\r\n\t\treturn $worksheetNames;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)\r\n\t *\r\n\t * @param   string     $pFilename\r\n\t * @throws   PHPExcel_Reader_Exception\r\n\t */\r\n\tpublic function listWorksheetInfo($pFilename)\r\n\t{\r\n\t\t// Check if file exists\r\n\t\tif (!file_exists($pFilename)) {\r\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\r\n\t\t}\r\n\r\n\t\t$worksheetInfo = array();\r\n\r\n\t\t// Read the OLE file\r\n\t\t$this->_loadOLE($pFilename);\r\n\r\n\t\t// total byte size of Excel data (workbook global substream + sheet substreams)\r\n\t\t$this->_dataSize = strlen($this->_data);\r\n\r\n\t\t// initialize\r\n\t\t$this->_pos    = 0;\r\n\t\t$this->_sheets = array();\r\n\r\n\t\t// Parse Workbook Global Substream\r\n\t\twhile ($this->_pos < $this->_dataSize) {\r\n\t\t\t$code = self::_GetInt2d($this->_data, $this->_pos);\r\n\r\n\t\t\tswitch ($code) {\r\n\t\t\t\tcase self::XLS_Type_BOF:        $this->_readBof();        break;\r\n\t\t\t\tcase self::XLS_Type_SHEET:      $this->_readSheet();      break;\r\n\t\t\t\tcase self::XLS_Type_EOF:        $this->_readDefault();    break 2;\r\n\t\t\t\tdefault:                        $this->_readDefault();    break;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Parse the individual sheets\r\n\t\tforeach ($this->_sheets as $sheet) {\r\n\r\n\t\t\tif ($sheet['sheetType'] != 0x00) {\r\n\t\t\t\t// 0x00: Worksheet\r\n\t\t\t\t// 0x02: Chart\r\n\t\t\t\t// 0x06: Visual Basic module\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t$tmpInfo = array();\r\n\t\t\t$tmpInfo['worksheetName'] = $sheet['name'];\r\n\t\t\t$tmpInfo['lastColumnLetter'] = 'A';\r\n\t\t\t$tmpInfo['lastColumnIndex'] = 0;\r\n\t\t\t$tmpInfo['totalRows'] = 0;\r\n\t\t\t$tmpInfo['totalColumns'] = 0;\r\n\r\n\t\t\t$this->_pos = $sheet['offset'];\r\n\r\n\t\t\twhile ($this->_pos <= $this->_dataSize - 4) {\r\n\t\t\t\t$code = self::_GetInt2d($this->_data, $this->_pos);\r\n\r\n\t\t\t\tswitch ($code) {\r\n\t\t\t\t\tcase self::XLS_Type_RK:\r\n\t\t\t\t\tcase self::XLS_Type_LABELSST:\r\n\t\t\t\t\tcase self::XLS_Type_NUMBER:\r\n\t\t\t\t\tcase self::XLS_Type_FORMULA:\r\n\t\t\t\t\tcase self::XLS_Type_BOOLERR:\r\n\t\t\t\t\tcase self::XLS_Type_LABEL:\r\n\t\t\t\t\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t\t\t\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t\t\t\t\t// move stream pointer to next record\r\n\t\t\t\t\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t\t\t\t\t$rowIndex = self::_GetInt2d($recordData, 0) + 1;\r\n\t\t\t\t\t\t$columnIndex = self::_GetInt2d($recordData, 2);\r\n\r\n\t\t\t\t\t\t$tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex);\r\n\t\t\t\t\t\t$tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_BOF:      $this->_readBof();          break;\r\n\t\t\t\t\tcase self::XLS_Type_EOF:      $this->_readDefault();      break 2;\r\n\t\t\t\t\tdefault:                      $this->_readDefault();      break;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);\r\n\t\t\t$tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;\r\n\r\n\t\t\t$worksheetInfo[] = $tmpInfo;\r\n\t\t}\r\n\r\n\t\treturn $worksheetInfo;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Loads PHPExcel from file\r\n\t *\r\n\t * @param \tstring \t\t$pFilename\r\n\t * @return \tPHPExcel\r\n\t * @throws \tPHPExcel_Reader_Exception\r\n\t */\r\n\tpublic function load($pFilename)\r\n\t{\r\n\t\t// Read the OLE file\r\n\t\t$this->_loadOLE($pFilename);\r\n\r\n\t\t// Initialisations\r\n\t\t$this->_phpExcel = new PHPExcel;\r\n\t\t$this->_phpExcel->removeSheetByIndex(0); // remove 1st sheet\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t$this->_phpExcel->removeCellStyleXfByIndex(0); // remove the default style\r\n\t\t\t$this->_phpExcel->removeCellXfByIndex(0); // remove the default style\r\n\t\t}\r\n\r\n\t\t// Read the summary information stream (containing meta data)\r\n\t\t$this->_readSummaryInformation();\r\n\r\n\t\t// Read the Additional document summary information stream (containing application-specific meta data)\r\n\t\t$this->_readDocumentSummaryInformation();\r\n\r\n\t\t// total byte size of Excel data (workbook global substream + sheet substreams)\r\n\t\t$this->_dataSize = strlen($this->_data);\r\n\r\n\t\t// initialize\r\n\t\t$this->_pos\t\t\t\t\t= 0;\r\n\t\t$this->_codepage\t\t\t= 'CP1252';\r\n\t\t$this->_formats\t\t\t\t= array();\r\n\t\t$this->_objFonts\t\t\t= array();\r\n\t\t$this->_palette\t\t\t\t= array();\r\n\t\t$this->_sheets\t\t\t\t= array();\r\n\t\t$this->_externalBooks\t\t= array();\r\n\t\t$this->_ref\t\t\t\t\t= array();\r\n\t\t$this->_definedname\t\t\t= array();\r\n\t\t$this->_sst\t\t\t\t\t= array();\r\n\t\t$this->_drawingGroupData\t= '';\r\n\t\t$this->_xfIndex\t\t\t\t= '';\r\n\t\t$this->_mapCellXfIndex\t\t= array();\r\n\t\t$this->_mapCellStyleXfIndex\t= array();\r\n\r\n\t\t// Parse Workbook Global Substream\r\n\t\twhile ($this->_pos < $this->_dataSize) {\r\n\t\t\t$code = self::_GetInt2d($this->_data, $this->_pos);\r\n\r\n\t\t\tswitch ($code) {\r\n\t\t\t\tcase self::XLS_Type_BOF:\t\t\t$this->_readBof();\t\t\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_FILEPASS:\t\t$this->_readFilepass();\t\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_CODEPAGE:\t\t$this->_readCodepage();\t\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_DATEMODE:\t\t$this->_readDateMode();\t\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_FONT:\t\t\t$this->_readFont();\t\t\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_FORMAT:\t\t\t$this->_readFormat();\t\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_XF:\t\t\t\t$this->_readXf();\t\t\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_XFEXT:\t\t\t$this->_readXfExt();\t\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_STYLE:\t\t\t$this->_readStyle();\t\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_PALETTE:\t\t$this->_readPalette();\t\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_SHEET:\t\t\t$this->_readSheet();\t\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_EXTERNALBOOK:\t$this->_readExternalBook();\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_EXTERNNAME:\t\t$this->_readExternName();\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_EXTERNSHEET:\t$this->_readExternSheet();\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_DEFINEDNAME:\t$this->_readDefinedName();\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_MSODRAWINGGROUP:\t$this->_readMsoDrawingGroup();\tbreak;\r\n\t\t\t\tcase self::XLS_Type_SST:\t\t\t$this->_readSst();\t\t\t\tbreak;\r\n\t\t\t\tcase self::XLS_Type_EOF:\t\t\t$this->_readDefault();\t\t\tbreak 2;\r\n\t\t\t\tdefault:\t\t\t\t\t\t\t$this->_readDefault();\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// Resolve indexed colors for font, fill, and border colors\r\n\t\t// Cannot be resolved already in XF record, because PALETTE record comes afterwards\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\tforeach ($this->_objFonts as $objFont) {\r\n\t\t\t\tif (isset($objFont->colorIndex)) {\r\n\t\t\t\t\t$color = self::_readColor($objFont->colorIndex,$this->_palette,$this->_version);\r\n\t\t\t\t\t$objFont->getColor()->setRGB($color['rgb']);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tforeach ($this->_phpExcel->getCellXfCollection() as $objStyle) {\r\n\t\t\t\t// fill start and end color\r\n\t\t\t\t$fill = $objStyle->getFill();\r\n\r\n\t\t\t\tif (isset($fill->startcolorIndex)) {\r\n\t\t\t\t\t$startColor = self::_readColor($fill->startcolorIndex,$this->_palette,$this->_version);\r\n\t\t\t\t\t$fill->getStartColor()->setRGB($startColor['rgb']);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (isset($fill->endcolorIndex)) {\r\n\t\t\t\t\t$endColor = self::_readColor($fill->endcolorIndex,$this->_palette,$this->_version);\r\n\t\t\t\t\t$fill->getEndColor()->setRGB($endColor['rgb']);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// border colors\r\n\t\t\t\t$top      = $objStyle->getBorders()->getTop();\r\n\t\t\t\t$right    = $objStyle->getBorders()->getRight();\r\n\t\t\t\t$bottom   = $objStyle->getBorders()->getBottom();\r\n\t\t\t\t$left     = $objStyle->getBorders()->getLeft();\r\n\t\t\t\t$diagonal = $objStyle->getBorders()->getDiagonal();\r\n\r\n\t\t\t\tif (isset($top->colorIndex)) {\r\n\t\t\t\t\t$borderTopColor = self::_readColor($top->colorIndex,$this->_palette,$this->_version);\r\n\t\t\t\t\t$top->getColor()->setRGB($borderTopColor['rgb']);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (isset($right->colorIndex)) {\r\n\t\t\t\t\t$borderRightColor = self::_readColor($right->colorIndex,$this->_palette,$this->_version);\r\n\t\t\t\t\t$right->getColor()->setRGB($borderRightColor['rgb']);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (isset($bottom->colorIndex)) {\r\n\t\t\t\t\t$borderBottomColor = self::_readColor($bottom->colorIndex,$this->_palette,$this->_version);\r\n\t\t\t\t\t$bottom->getColor()->setRGB($borderBottomColor['rgb']);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (isset($left->colorIndex)) {\r\n\t\t\t\t\t$borderLeftColor = self::_readColor($left->colorIndex,$this->_palette,$this->_version);\r\n\t\t\t\t\t$left->getColor()->setRGB($borderLeftColor['rgb']);\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (isset($diagonal->colorIndex)) {\r\n\t\t\t\t\t$borderDiagonalColor = self::_readColor($diagonal->colorIndex,$this->_palette,$this->_version);\r\n\t\t\t\t\t$diagonal->getColor()->setRGB($borderDiagonalColor['rgb']);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// treat MSODRAWINGGROUP records, workbook-level Escher\r\n\t\tif (!$this->_readDataOnly && $this->_drawingGroupData) {\r\n\t\t\t$escherWorkbook = new PHPExcel_Shared_Escher();\r\n\t\t\t$reader = new PHPExcel_Reader_Excel5_Escher($escherWorkbook);\r\n\t\t\t$escherWorkbook = $reader->load($this->_drawingGroupData);\r\n\r\n\t\t\t// debug Escher stream\r\n\t\t\t//$debug = new Debug_Escher(new PHPExcel_Shared_Escher());\r\n\t\t\t//$debug->load($this->_drawingGroupData);\r\n\t\t}\r\n\r\n\t\t// Parse the individual sheets\r\n\t\tforeach ($this->_sheets as $sheet) {\r\n\r\n\t\t\tif ($sheet['sheetType'] != 0x00) {\r\n\t\t\t\t// 0x00: Worksheet, 0x02: Chart, 0x06: Visual Basic module\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// check if sheet should be skipped\r\n\t\t\tif (isset($this->_loadSheetsOnly) && !in_array($sheet['name'], $this->_loadSheetsOnly)) {\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t// add sheet to PHPExcel object\r\n\t\t\t$this->_phpSheet = $this->_phpExcel->createSheet();\r\n\t\t\t//\tUse false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula\r\n\t\t\t//\t\tcells... during the load, all formulae should be correct, and we're simply bringing the worksheet\r\n\t\t\t//\t\tname in line with the formula, not the reverse\r\n\t\t\t$this->_phpSheet->setTitle($sheet['name'],false);\r\n\t\t\t$this->_phpSheet->setSheetState($sheet['sheetState']);\r\n\r\n\t\t\t$this->_pos = $sheet['offset'];\r\n\r\n\t\t\t// Initialize isFitToPages. May change after reading SHEETPR record.\r\n\t\t\t$this->_isFitToPages = false;\r\n\r\n\t\t\t// Initialize drawingData\r\n\t\t\t$this->_drawingData = '';\r\n\r\n\t\t\t// Initialize objs\r\n\t\t\t$this->_objs = array();\r\n\r\n\t\t\t// Initialize shared formula parts\r\n\t\t\t$this->_sharedFormulaParts = array();\r\n\r\n\t\t\t// Initialize shared formulas\r\n\t\t\t$this->_sharedFormulas = array();\r\n\r\n\t\t\t// Initialize text objs\r\n\t\t\t$this->_textObjects = array();\r\n\r\n\t\t\t// Initialize cell annotations\r\n\t\t\t$this->_cellNotes = array();\r\n\t\t\t$this->textObjRef = -1;\r\n\r\n\t\t\twhile ($this->_pos <= $this->_dataSize - 4) {\r\n\t\t\t\t$code = self::_GetInt2d($this->_data, $this->_pos);\r\n\r\n\t\t\t\tswitch ($code) {\r\n\t\t\t\t\tcase self::XLS_Type_BOF:\t\t\t\t\t$this->_readBof();\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_PRINTGRIDLINES:\t\t\t$this->_readPrintGridlines();\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_DEFAULTROWHEIGHT:\t\t$this->_readDefaultRowHeight();\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_SHEETPR:\t\t\t\t$this->_readSheetPr();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_HORIZONTALPAGEBREAKS:\t$this->_readHorizontalPageBreaks();\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_VERTICALPAGEBREAKS:\t\t$this->_readVerticalPageBreaks();\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_HEADER:\t\t\t\t\t$this->_readHeader();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_FOOTER:\t\t\t\t\t$this->_readFooter();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_HCENTER:\t\t\t\t$this->_readHcenter();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_VCENTER:\t\t\t\t$this->_readVcenter();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_LEFTMARGIN:\t\t\t\t$this->_readLeftMargin();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_RIGHTMARGIN:\t\t\t$this->_readRightMargin();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_TOPMARGIN:\t\t\t\t$this->_readTopMargin();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_BOTTOMMARGIN:\t\t\t$this->_readBottomMargin();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_PAGESETUP:\t\t\t\t$this->_readPageSetup();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_PROTECT:\t\t\t\t$this->_readProtect();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_SCENPROTECT:\t\t\t$this->_readScenProtect();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_OBJECTPROTECT:\t\t\t$this->_readObjectProtect();\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_PASSWORD:\t\t\t\t$this->_readPassword();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_DEFCOLWIDTH:\t\t\t$this->_readDefColWidth();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_COLINFO:\t\t\t\t$this->_readColInfo();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_DIMENSION:\t\t\t\t$this->_readDefault();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_ROW:\t\t\t\t\t$this->_readRow();\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_DBCELL:\t\t\t\t\t$this->_readDefault();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_RK:\t\t\t\t\t\t$this->_readRk();\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_LABELSST:\t\t\t\t$this->_readLabelSst();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_MULRK:\t\t\t\t\t$this->_readMulRk();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_NUMBER:\t\t\t\t\t$this->_readNumber();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_FORMULA:\t\t\t\t$this->_readFormula();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_SHAREDFMLA:\t\t\t\t$this->_readSharedFmla();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_BOOLERR:\t\t\t\t$this->_readBoolErr();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_MULBLANK:\t\t\t\t$this->_readMulBlank();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_LABEL:\t\t\t\t\t$this->_readLabel();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_BLANK:\t\t\t\t\t$this->_readBlank();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_MSODRAWING:\t\t\t\t$this->_readMsoDrawing();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_OBJ:\t\t\t\t\t$this->_readObj();\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_WINDOW2:\t\t\t\t$this->_readWindow2();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_PAGELAYOUTVIEW:\t$this->_readPageLayoutView();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_SCL:\t\t\t\t\t$this->_readScl();\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_PANE:\t\t\t\t\t$this->_readPane();\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_SELECTION:\t\t\t\t$this->_readSelection();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_MERGEDCELLS:\t\t\t$this->_readMergedCells();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_HYPERLINK:\t\t\t\t$this->_readHyperLink();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_DATAVALIDATIONS:\t\t$this->_readDataValidations();\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_DATAVALIDATION:\t\t\t$this->_readDataValidation();\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_SHEETLAYOUT:\t\t\t$this->_readSheetLayout();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_SHEETPROTECTION:\t\t$this->_readSheetProtection();\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_RANGEPROTECTION:\t\t$this->_readRangeProtection();\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_NOTE:\t\t\t\t\t$this->_readNote();\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t//case self::XLS_Type_IMDATA:\t\t\t\t$this->_readImData();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_TXO:\t\t\t\t\t$this->_readTextObject();\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_CONTINUE:\t\t\t\t$this->_readContinue();\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase self::XLS_Type_EOF:\t\t\t\t\t$this->_readDefault();\t\t\t\t\tbreak 2;\r\n\t\t\t\t\tdefault:\t\t\t\t\t\t\t\t\t$this->_readDefault();\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t}\r\n\r\n\t\t\t// treat MSODRAWING records, sheet-level Escher\r\n\t\t\tif (!$this->_readDataOnly && $this->_drawingData) {\r\n\t\t\t\t$escherWorksheet = new PHPExcel_Shared_Escher();\r\n\t\t\t\t$reader = new PHPExcel_Reader_Excel5_Escher($escherWorksheet);\r\n\t\t\t\t$escherWorksheet = $reader->load($this->_drawingData);\r\n\r\n\t\t\t\t// debug Escher stream\r\n\t\t\t\t//$debug = new Debug_Escher(new PHPExcel_Shared_Escher());\r\n\t\t\t\t//$debug->load($this->_drawingData);\r\n\r\n\t\t\t\t// get all spContainers in one long array, so they can be mapped to OBJ records\r\n\t\t\t\t$allSpContainers = $escherWorksheet->getDgContainer()->getSpgrContainer()->getAllSpContainers();\r\n\t\t\t}\r\n\r\n\t\t\t// treat OBJ records\r\n\t\t\tforeach ($this->_objs as $n => $obj) {\r\n//\t\t\t\techo '<hr /><b>Object</b> reference is ',$n,'<br />';\r\n//\t\t\t\tvar_dump($obj);\r\n//\t\t\t\techo '<br />';\r\n\r\n\t\t\t\t// the first shape container never has a corresponding OBJ record, hence $n + 1\r\n\t\t\t\tif (isset($allSpContainers[$n + 1]) && is_object($allSpContainers[$n + 1])) {\r\n\t\t\t\t\t$spContainer = $allSpContainers[$n + 1];\r\n\r\n\t\t\t\t\t// we skip all spContainers that are a part of a group shape since we cannot yet handle those\r\n\t\t\t\t\tif ($spContainer->getNestingLevel() > 1) {\r\n\t\t\t\t\t\tcontinue;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// calculate the width and height of the shape\r\n\t\t\t\t\tlist($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($spContainer->getStartCoordinates());\r\n\t\t\t\t\tlist($endColumn, $endRow) = PHPExcel_Cell::coordinateFromString($spContainer->getEndCoordinates());\r\n\r\n\t\t\t\t\t$startOffsetX = $spContainer->getStartOffsetX();\r\n\t\t\t\t\t$startOffsetY = $spContainer->getStartOffsetY();\r\n\t\t\t\t\t$endOffsetX = $spContainer->getEndOffsetX();\r\n\t\t\t\t\t$endOffsetY = $spContainer->getEndOffsetY();\r\n\r\n\t\t\t\t\t$width = PHPExcel_Shared_Excel5::getDistanceX($this->_phpSheet, $startColumn, $startOffsetX, $endColumn, $endOffsetX);\r\n\t\t\t\t\t$height = PHPExcel_Shared_Excel5::getDistanceY($this->_phpSheet, $startRow, $startOffsetY, $endRow, $endOffsetY);\r\n\r\n\t\t\t\t\t// calculate offsetX and offsetY of the shape\r\n\t\t\t\t\t$offsetX = $startOffsetX * PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, $startColumn) / 1024;\r\n\t\t\t\t\t$offsetY = $startOffsetY * PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $startRow) / 256;\r\n\r\n\t\t\t\t\tswitch ($obj['otObjType']) {\r\n\t\t\t\t\t\tcase 0x19:\r\n\t\t\t\t\t\t\t// Note\r\n//\t\t\t\t\t\t\techo 'Cell Annotation Object<br />';\r\n//\t\t\t\t\t\t\techo 'Object ID is ',$obj['idObjID'],'<br />';\r\n//\r\n\t\t\t\t\t\t\tif (isset($this->_cellNotes[$obj['idObjID']])) {\r\n\t\t\t\t\t\t\t\t$cellNote = $this->_cellNotes[$obj['idObjID']];\r\n\r\n\t\t\t\t\t\t\t\tif (isset($this->_textObjects[$obj['idObjID']])) {\r\n\t\t\t\t\t\t\t\t\t$textObject = $this->_textObjects[$obj['idObjID']];\r\n\t\t\t\t\t\t\t\t\t$this->_cellNotes[$obj['idObjID']]['objTextData'] = $textObject;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\tcase 0x08:\r\n//\t\t\t\t\t\t\techo 'Picture Object<br />';\r\n\t\t\t\t\t\t\t// picture\r\n\r\n\t\t\t\t\t\t\t// get index to BSE entry (1-based)\r\n\t\t\t\t\t\t\t$BSEindex = $spContainer->getOPT(0x0104);\r\n\t\t\t\t\t\t\t$BSECollection = $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection();\r\n\t\t\t\t\t\t\t$BSE = $BSECollection[$BSEindex - 1];\r\n\t\t\t\t\t\t\t$blipType = $BSE->getBlipType();\r\n\r\n\t\t\t\t\t\t\t// need check because some blip types are not supported by Escher reader such as EMF\r\n\t\t\t\t\t\t\tif ($blip = $BSE->getBlip()) {\r\n\t\t\t\t\t\t\t\t$ih = imagecreatefromstring($blip->getData());\r\n\t\t\t\t\t\t\t\t$drawing = new PHPExcel_Worksheet_MemoryDrawing();\r\n\t\t\t\t\t\t\t\t$drawing->setImageResource($ih);\r\n\r\n\t\t\t\t\t\t\t\t// width, height, offsetX, offsetY\r\n\t\t\t\t\t\t\t\t$drawing->setResizeProportional(false);\r\n\t\t\t\t\t\t\t\t$drawing->setWidth($width);\r\n\t\t\t\t\t\t\t\t$drawing->setHeight($height);\r\n\t\t\t\t\t\t\t\t$drawing->setOffsetX($offsetX);\r\n\t\t\t\t\t\t\t\t$drawing->setOffsetY($offsetY);\r\n\r\n\t\t\t\t\t\t\t\tswitch ($blipType) {\r\n\t\t\t\t\t\t\t\t\tcase PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG:\r\n\t\t\t\t\t\t\t\t\t\t$drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG);\r\n\t\t\t\t\t\t\t\t\t\t$drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_JPEG);\r\n\t\t\t\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\t\t\t\tcase PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG:\r\n\t\t\t\t\t\t\t\t\t\t$drawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG);\r\n\t\t\t\t\t\t\t\t\t\t$drawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_PNG);\r\n\t\t\t\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\t\t$drawing->setWorksheet($this->_phpSheet);\r\n\t\t\t\t\t\t\t\t$drawing->setCoordinates($spContainer->getStartCoordinates());\r\n\t\t\t\t\t\t\t}\r\n\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t\tdefault:\r\n\t\t\t\t\t\t\t// other object type\r\n\t\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// treat SHAREDFMLA records\r\n\t\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t\tforeach ($this->_sharedFormulaParts as $cell => $baseCell) {\r\n\t\t\t\t\tlist($column, $row) = PHPExcel_Cell::coordinateFromString($cell);\r\n\t\t\t\t\tif (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle()) ) {\r\n\t\t\t\t\t\t$formula = $this->_getFormulaFromStructure($this->_sharedFormulas[$baseCell], $cell);\r\n\t\t\t\t\t\t$this->_phpSheet->getCell($cell)->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA);\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif (!empty($this->_cellNotes)) {\r\n\t\t\t\tforeach($this->_cellNotes as $note => $noteDetails) {\r\n\t\t\t\t\tif (!isset($noteDetails['objTextData'])) {\r\n\t\t\t\t\t\tif (isset($this->_textObjects[$note])) {\r\n\t\t\t\t\t\t\t$textObject = $this->_textObjects[$note];\r\n\t\t\t\t\t\t\t$noteDetails['objTextData'] = $textObject;\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t$noteDetails['objTextData']['text'] = '';\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n//\t\t\t\t\techo '<b>Cell annotation ',$note,'</b><br />';\r\n//\t\t\t\t\tvar_dump($noteDetails);\r\n//\t\t\t\t\techo '<br />';\r\n\t\t\t\t\t$cellAddress = str_replace('$','',$noteDetails['cellRef']);\r\n\t\t\t\t\t$this->_phpSheet->getComment( $cellAddress )\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t->setAuthor( $noteDetails['author'] )\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t->setText($this->_parseRichText($noteDetails['objTextData']['text']) );\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// add the named ranges (defined names)\r\n\t\tforeach ($this->_definedname as $definedName) {\r\n\t\t\tif ($definedName['isBuiltInName']) {\r\n\t\t\t\tswitch ($definedName['name']) {\r\n\r\n\t\t\t\tcase pack('C', 0x06):\r\n\t\t\t\t\t// print area\r\n\t\t\t\t\t//\tin general, formula looks like this: Foo!$C$7:$J$66,Bar!$A$1:$IV$2\r\n\t\t\t\t\t$ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma?\r\n\r\n\t\t\t\t\t$extractedRanges = array();\r\n\t\t\t\t\tforeach ($ranges as $range) {\r\n\t\t\t\t\t\t// $range should look like one of these\r\n\t\t\t\t\t\t//\t\tFoo!$C$7:$J$66\r\n\t\t\t\t\t\t//\t\tBar!$A$1:$IV$2\r\n\r\n\t\t\t\t\t\t$explodes = explode('!', $range);\t// FIXME: what if sheetname contains exclamation mark?\r\n\t\t\t\t\t\t$sheetName = trim($explodes[0], \"'\");\r\n\r\n\t\t\t\t\t\tif (count($explodes) == 2) {\r\n\t\t\t\t\t\t\tif (strpos($explodes[1], ':') === FALSE) {\r\n\t\t\t\t\t\t\t\t$explodes[1] = $explodes[1] . ':' . $explodes[1];\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t$extractedRanges[] = str_replace('$', '', $explodes[1]); // C7:J66\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tif ($docSheet = $this->_phpExcel->getSheetByName($sheetName)) {\r\n\t\t\t\t\t\t$docSheet->getPageSetup()->setPrintArea(implode(',', $extractedRanges)); // C7:J66,A1:IV2\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase pack('C', 0x07):\r\n\t\t\t\t\t// print titles (repeating rows)\r\n\t\t\t\t\t// Assuming BIFF8, there are 3 cases\r\n\t\t\t\t\t// 1. repeating rows\r\n\t\t\t\t\t//\t\tformula looks like this: Sheet!$A$1:$IV$2\r\n\t\t\t\t\t//\t\trows 1-2 repeat\r\n\t\t\t\t\t// 2. repeating columns\r\n\t\t\t\t\t//\t\tformula looks like this: Sheet!$A$1:$B$65536\r\n\t\t\t\t\t//\t\tcolumns A-B repeat\r\n\t\t\t\t\t// 3. both repeating rows and repeating columns\r\n\t\t\t\t\t//\t\tformula looks like this: Sheet!$A$1:$B$65536,Sheet!$A$1:$IV$2\r\n\r\n\t\t\t\t\t$ranges = explode(',', $definedName['formula']); // FIXME: what if sheetname contains comma?\r\n\r\n\t\t\t\t\tforeach ($ranges as $range) {\r\n\t\t\t\t\t\t// $range should look like this one of these\r\n\t\t\t\t\t\t//\t\tSheet!$A$1:$B$65536\r\n\t\t\t\t\t\t//\t\tSheet!$A$1:$IV$2\r\n\r\n\t\t\t\t\t\t$explodes = explode('!', $range);\r\n\r\n\t\t\t\t\t\tif (count($explodes) == 2) {\r\n\t\t\t\t\t\t\tif ($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) {\r\n\r\n\t\t\t\t\t\t\t\t$extractedRange = $explodes[1];\r\n\t\t\t\t\t\t\t\t$extractedRange = str_replace('$', '', $extractedRange);\r\n\r\n\t\t\t\t\t\t\t\t$coordinateStrings = explode(':', $extractedRange);\r\n\t\t\t\t\t\t\t\tif (count($coordinateStrings) == 2) {\r\n\t\t\t\t\t\t\t\t\tlist($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[0]);\r\n\t\t\t\t\t\t\t\t\tlist($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($coordinateStrings[1]);\r\n\r\n\t\t\t\t\t\t\t\t\tif ($firstColumn == 'A' and $lastColumn == 'IV') {\r\n\t\t\t\t\t\t\t\t\t\t// then we have repeating rows\r\n\t\t\t\t\t\t\t\t\t\t$docSheet->getPageSetup()->setRowsToRepeatAtTop(array($firstRow, $lastRow));\r\n\t\t\t\t\t\t\t\t\t} elseif ($firstRow == 1 and $lastRow == 65536) {\r\n\t\t\t\t\t\t\t\t\t\t// then we have repeating columns\r\n\t\t\t\t\t\t\t\t\t\t$docSheet->getPageSetup()->setColumnsToRepeatAtLeft(array($firstColumn, $lastColumn));\r\n\t\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// Extract range\r\n\t\t\t\t$explodes = explode('!', $definedName['formula']);\r\n\r\n\t\t\t\tif (count($explodes) == 2) {\r\n\t\t\t\t\tif (($docSheet = $this->_phpExcel->getSheetByName($explodes[0])) ||\r\n\t\t\t\t\t\t($docSheet = $this->_phpExcel->getSheetByName(trim($explodes[0],\"'\")))) {\r\n\t\t\t\t\t\t$extractedRange = $explodes[1];\r\n\t\t\t\t\t\t$extractedRange = str_replace('$', '', $extractedRange);\r\n\r\n\t\t\t\t\t\t$localOnly = ($definedName['scope'] == 0) ? false : true;\r\n\r\n\t\t\t\t\t\t$scope = ($definedName['scope'] == 0) ?\r\n\t\t\t\t\t\t\tnull : $this->_phpExcel->getSheetByName($this->_sheets[$definedName['scope'] - 1]['name']);\r\n\r\n\t\t\t\t\t\t$this->_phpExcel->addNamedRange( new PHPExcel_NamedRange((string)$definedName['name'], $docSheet, $extractedRange, $localOnly, $scope) );\r\n\t\t\t\t\t}\r\n\t\t\t\t} else {\r\n\t\t\t\t\t//\tNamed Value\r\n\t\t\t\t\t//\tTODO Provide support for named values\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n        $this->_data = null;\r\n\r\n\t\treturn $this->_phpExcel;\r\n\t}\r\n\t\r\n\t/**\r\n\t * Read record data from stream, decrypting as required\r\n\t * \r\n\t * @param string $data   Data stream to read from\r\n\t * @param int    $pos    Position to start reading from\r\n\t * @param int    $length Record data length\r\n\t * \r\n\t * @return string Record data\r\n\t */\r\n\tprivate function _readRecordData($data, $pos, $len)\r\n\t{\r\n\t\t$data = substr($data, $pos, $len);\r\n\t\t\r\n\t\t// File not encrypted, or record before encryption start point\r\n\t\tif ($this->_encryption == self::MS_BIFF_CRYPTO_NONE || $pos < $this->_encryptionStartPos) {\r\n\t\t\treturn $data;\r\n\t\t}\r\n\t\r\n\t\t$recordData = '';\r\n\t\tif ($this->_encryption == self::MS_BIFF_CRYPTO_RC4) {\r\n\r\n\t\t\t$oldBlock = floor($this->_rc4Pos / self::REKEY_BLOCK);\r\n\t\t\t$block = floor($pos / self::REKEY_BLOCK);\r\n\t\t\t$endBlock = floor(($pos + $len) / self::REKEY_BLOCK);\r\n\r\n\t\t\t// Spin an RC4 decryptor to the right spot. If we have a decryptor sitting\r\n\t\t\t// at a point earlier in the current block, re-use it as we can save some time.\r\n\t\t\tif ($block != $oldBlock || $pos < $this->_rc4Pos || !$this->_rc4Key) {\r\n\t\t\t\t$this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt);\r\n\t\t\t\t$step = $pos % self::REKEY_BLOCK;\r\n\t\t\t} else {\r\n\t\t\t\t$step = $pos - $this->_rc4Pos;\r\n\t\t\t}\r\n\t\t\t$this->_rc4Key->RC4(str_repeat(\"\\0\", $step));\r\n\r\n\t\t\t// Decrypt record data (re-keying at the end of every block)\r\n\t\t\twhile ($block != $endBlock) {\r\n\t\t\t\t$step = self::REKEY_BLOCK - ($pos % self::REKEY_BLOCK);\r\n\t\t\t\t$recordData .= $this->_rc4Key->RC4(substr($data, 0, $step));\r\n\t\t\t\t$data = substr($data, $step);\r\n\t\t\t\t$pos += $step;\r\n\t\t\t\t$len -= $step;\r\n\t\t\t\t$block++;\r\n\t\t\t\t$this->_rc4Key = $this->_makeKey($block, $this->_md5Ctxt);\r\n\t\t\t}\r\n\t\t\t$recordData .= $this->_rc4Key->RC4(substr($data, 0, $len));\r\n\r\n\t\t\t// Keep track of the position of this decryptor.\r\n\t\t\t// We'll try and re-use it later if we can to speed things up\r\n\t\t\t$this->_rc4Pos = $pos + $len;\r\n\t\t\t\r\n\t\t} elseif ($this->_encryption == self::MS_BIFF_CRYPTO_XOR) {\r\n\t\t\tthrow new PHPExcel_Reader_Exception('XOr encryption not supported');\r\n\t\t}\r\n\t\treturn $recordData;\r\n\t}\r\n\r\n\t/**\r\n\t * Use OLE reader to extract the relevant data streams from the OLE file\r\n\t *\r\n\t * @param string $pFilename\r\n\t */\r\n\tprivate function _loadOLE($pFilename)\r\n\t{\r\n\t\t// OLE reader\r\n\t\t$ole = new PHPExcel_Shared_OLERead();\r\n\r\n\t\t// get excel data,\r\n\t\t$res = $ole->read($pFilename);\r\n\t\t// Get workbook data: workbook stream + sheet streams\r\n\t\t$this->_data = $ole->getStream($ole->wrkbook);\r\n\r\n\t\t// Get summary information data\r\n\t\t$this->_summaryInformation = $ole->getStream($ole->summaryInformation);\r\n\r\n\t\t// Get additional document summary information data\r\n\t\t$this->_documentSummaryInformation = $ole->getStream($ole->documentSummaryInformation);\r\n\r\n\t\t// Get user-defined property data\r\n//\t\t$this->_userDefinedProperties = $ole->getUserDefinedProperties();\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read summary information\r\n\t */\r\n\tprivate function _readSummaryInformation()\r\n\t{\r\n\t\tif (!isset($this->_summaryInformation)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark)\r\n\t\t// offset: 2; size: 2;\r\n\t\t// offset: 4; size: 2; OS version\r\n\t\t// offset: 6; size: 2; OS indicator\r\n\t\t// offset: 8; size: 16\r\n\t\t// offset: 24; size: 4; section count\r\n\t\t$secCount = self::_GetInt4d($this->_summaryInformation, 24);\r\n\r\n\t\t// offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9\r\n\t\t// offset: 44; size: 4\r\n\t\t$secOffset = self::_GetInt4d($this->_summaryInformation, 44);\r\n\r\n\t\t// section header\r\n\t\t// offset: $secOffset; size: 4; section length\r\n\t\t$secLength = self::_GetInt4d($this->_summaryInformation, $secOffset);\r\n\r\n\t\t// offset: $secOffset+4; size: 4; property count\r\n\t\t$countProperties = self::_GetInt4d($this->_summaryInformation, $secOffset+4);\r\n\r\n\t\t// initialize code page (used to resolve string values)\r\n\t\t$codePage = 'CP1252';\r\n\r\n\t\t// offset: ($secOffset+8); size: var\r\n\t\t// loop through property decarations and properties\r\n\t\tfor ($i = 0; $i < $countProperties; ++$i) {\r\n\r\n\t\t\t// offset: ($secOffset+8) + (8 * $i); size: 4; property ID\r\n\t\t\t$id = self::_GetInt4d($this->_summaryInformation, ($secOffset+8) + (8 * $i));\r\n\r\n\t\t\t// Use value of property id as appropriate\r\n\t\t\t// offset: ($secOffset+12) + (8 * $i); size: 4; offset from beginning of section (48)\r\n\t\t\t$offset = self::_GetInt4d($this->_summaryInformation, ($secOffset+12) + (8 * $i));\r\n\r\n\t\t\t$type = self::_GetInt4d($this->_summaryInformation, $secOffset + $offset);\r\n\r\n\t\t\t// initialize property value\r\n\t\t\t$value = null;\r\n\r\n\t\t\t// extract property value based on property type\r\n\t\t\tswitch ($type) {\r\n\t\t\t\tcase 0x02: // 2 byte signed integer\r\n\t\t\t\t\t$value = self::_GetInt2d($this->_summaryInformation, $secOffset + 4 + $offset);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x03: // 4 byte signed integer\r\n\t\t\t\t\t$value = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x13: // 4 byte unsigned integer\r\n\t\t\t\t\t// not needed yet, fix later if necessary\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x1E: // null-terminated string prepended by dword string length\r\n\t\t\t\t\t$byteLength = self::_GetInt4d($this->_summaryInformation, $secOffset + 4 + $offset);\r\n\t\t\t\t\t$value = substr($this->_summaryInformation, $secOffset + 8 + $offset, $byteLength);\r\n\t\t\t\t\t$value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage);\r\n\t\t\t\t\t$value = rtrim($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x40: // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)\r\n\t\t\t\t\t// PHP-time\r\n\t\t\t\t\t$value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_summaryInformation, $secOffset + 4 + $offset, 8));\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x47: // Clipboard format\r\n\t\t\t\t\t// not needed yet, fix later if necessary\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tswitch ($id) {\r\n\t\t\t\tcase 0x01:\t//\tCode Page\r\n\t\t\t\t\t$codePage = PHPExcel_Shared_CodePage::NumberToName($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x02:\t//\tTitle\r\n\t\t\t\t\t$this->_phpExcel->getProperties()->setTitle($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x03:\t//\tSubject\r\n\t\t\t\t\t$this->_phpExcel->getProperties()->setSubject($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x04:\t//\tAuthor (Creator)\r\n\t\t\t\t\t$this->_phpExcel->getProperties()->setCreator($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x05:\t//\tKeywords\r\n\t\t\t\t\t$this->_phpExcel->getProperties()->setKeywords($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x06:\t//\tComments (Description)\r\n\t\t\t\t\t$this->_phpExcel->getProperties()->setDescription($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x07:\t//\tTemplate\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x08:\t//\tLast Saved By (LastModifiedBy)\r\n\t\t\t\t\t$this->_phpExcel->getProperties()->setLastModifiedBy($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x09:\t//\tRevision\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x0A:\t//\tTotal Editing Time\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x0B:\t//\tLast Printed\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x0C:\t//\tCreated Date/Time\r\n\t\t\t\t\t$this->_phpExcel->getProperties()->setCreated($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x0D:\t//\tModified Date/Time\r\n\t\t\t\t\t$this->_phpExcel->getProperties()->setModified($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x0E:\t//\tNumber of Pages\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x0F:\t//\tNumber of Words\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x10:\t//\tNumber of Characters\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x11:\t//\tThumbnail\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x12:\t//\tName of creating application\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x13:\t//\tSecurity\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read additional document summary information\r\n\t */\r\n\tprivate function _readDocumentSummaryInformation()\r\n\t{\r\n\t\tif (!isset($this->_documentSummaryInformation)) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t//\toffset: 0;\tsize: 2;\tmust be 0xFE 0xFF (UTF-16 LE byte order mark)\r\n\t\t//\toffset: 2;\tsize: 2;\r\n\t\t//\toffset: 4;\tsize: 2;\tOS version\r\n\t\t//\toffset: 6;\tsize: 2;\tOS indicator\r\n\t\t//\toffset: 8;\tsize: 16\r\n\t\t//\toffset: 24;\tsize: 4;\tsection count\r\n\t\t$secCount = self::_GetInt4d($this->_documentSummaryInformation, 24);\r\n//\t\techo '$secCount = ',$secCount,'<br />';\r\n\r\n\t\t// offset: 28;\tsize: 16;\tfirst section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae\r\n\t\t// offset: 44;\tsize: 4;\tfirst section offset\r\n\t\t$secOffset = self::_GetInt4d($this->_documentSummaryInformation, 44);\r\n//\t\techo '$secOffset = ',$secOffset,'<br />';\r\n\r\n\t\t//\tsection header\r\n\t\t//\toffset: $secOffset;\tsize: 4;\tsection length\r\n\t\t$secLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset);\r\n//\t\techo '$secLength = ',$secLength,'<br />';\r\n\r\n\t\t//\toffset: $secOffset+4;\tsize: 4;\tproperty count\r\n\t\t$countProperties = self::_GetInt4d($this->_documentSummaryInformation, $secOffset+4);\r\n//\t\techo '$countProperties = ',$countProperties,'<br />';\r\n\r\n\t\t// initialize code page (used to resolve string values)\r\n\t\t$codePage = 'CP1252';\r\n\r\n\t\t//\toffset: ($secOffset+8);\tsize: var\r\n\t\t//\tloop through property decarations and properties\r\n\t\tfor ($i = 0; $i < $countProperties; ++$i) {\r\n//\t\t\techo 'Property ',$i,'<br />';\r\n\t\t\t//\toffset: ($secOffset+8) + (8 * $i);\tsize: 4;\tproperty ID\r\n\t\t\t$id = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+8) + (8 * $i));\r\n//\t\t\techo 'ID is ',$id,'<br />';\r\n\r\n\t\t\t// Use value of property id as appropriate\r\n\t\t\t// offset: 60 + 8 * $i;\tsize: 4;\toffset from beginning of section (48)\r\n\t\t\t$offset = self::_GetInt4d($this->_documentSummaryInformation, ($secOffset+12) + (8 * $i));\r\n\r\n\t\t\t$type = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + $offset);\r\n//\t\t\techo 'Type is ',$type,', ';\r\n\r\n\t\t\t// initialize property value\r\n\t\t\t$value = null;\r\n\r\n\t\t\t// extract property value based on property type\r\n\t\t\tswitch ($type) {\r\n\t\t\t\tcase 0x02:\t//\t2 byte signed integer\r\n\t\t\t\t\t$value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x03:\t//\t4 byte signed integer\r\n\t\t\t\t\t$value = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x0B:  // Boolean\r\n\t\t\t\t\t$value = self::_GetInt2d($this->_documentSummaryInformation, $secOffset + 4 + $offset);\r\n\t\t\t\t\t$value = ($value == 0 ? false : true);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x13:\t//\t4 byte unsigned integer\r\n\t\t\t\t\t// not needed yet, fix later if necessary\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x1E:\t//\tnull-terminated string prepended by dword string length\r\n\t\t\t\t\t$byteLength = self::_GetInt4d($this->_documentSummaryInformation, $secOffset + 4 + $offset);\r\n\t\t\t\t\t$value = substr($this->_documentSummaryInformation, $secOffset + 8 + $offset, $byteLength);\r\n\t\t\t\t\t$value = PHPExcel_Shared_String::ConvertEncoding($value, 'UTF-8', $codePage);\r\n\t\t\t\t\t$value = rtrim($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x40:\t//\tFiletime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)\r\n\t\t\t\t\t// PHP-Time\r\n\t\t\t\t\t$value = PHPExcel_Shared_OLE::OLE2LocalDate(substr($this->_documentSummaryInformation, $secOffset + 4 + $offset, 8));\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x47:\t//\tClipboard format\r\n\t\t\t\t\t// not needed yet, fix later if necessary\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tswitch ($id) {\r\n\t\t\t\tcase 0x01:\t//\tCode Page\r\n\t\t\t\t\t$codePage = PHPExcel_Shared_CodePage::NumberToName($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x02:\t//\tCategory\r\n\t\t\t\t\t$this->_phpExcel->getProperties()->setCategory($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x03:\t//\tPresentation Target\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x04:\t//\tBytes\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x05:\t//\tLines\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x06:\t//\tParagraphs\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x07:\t//\tSlides\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x08:\t//\tNotes\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x09:\t//\tHidden Slides\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x0A:\t//\tMM Clips\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x0B:\t//\tScale Crop\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x0C:\t//\tHeading Pairs\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x0D:\t//\tTitles of Parts\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x0E:\t//\tManager\r\n\t\t\t\t\t$this->_phpExcel->getProperties()->setManager($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x0F:\t//\tCompany\r\n\t\t\t\t\t$this->_phpExcel->getProperties()->setCompany($value);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x10:\t//\tLinks up-to-date\r\n\t\t\t\t\t//\tNot supported by PHPExcel\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Reads a general type of BIFF record. Does nothing except for moving stream pointer forward to next record.\r\n\t */\r\n\tprivate function _readDefault()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n//\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t *\tThe NOTE record specifies a comment associated with a particular cell. In Excel 95 (BIFF7) and earlier versions,\r\n\t *\t\tthis record stores a note (cell note). This feature was significantly enhanced in Excel 97.\r\n\t */\r\n\tprivate function _readNote()\r\n\t{\r\n//\t\techo '<b>Read Cell Annotation</b><br />';\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_readDataOnly) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t$cellAddress = $this->_readBIFF8CellAddress(substr($recordData, 0, 4));\r\n\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t$noteObjID = self::_GetInt2d($recordData, 6);\r\n\t\t\t$noteAuthor = self::_readUnicodeStringLong(substr($recordData, 8));\r\n\t\t\t$noteAuthor = $noteAuthor['value'];\r\n//\t\t\techo 'Note Address=',$cellAddress,'<br />';\r\n//\t\t\techo 'Note Object ID=',$noteObjID,'<br />';\r\n//\t\t\techo 'Note Author=',$noteAuthor,'<hr />';\r\n//\r\n\t\t\t$this->_cellNotes[$noteObjID] = array('cellRef'\t\t=> $cellAddress,\r\n\t\t\t\t\t\t\t\t\t\t\t\t  'objectID'\t=> $noteObjID,\r\n\t\t\t\t\t\t\t\t\t\t\t\t  'author'\t\t=> $noteAuthor\r\n\t\t\t\t\t\t\t\t\t\t\t\t );\r\n\t\t} else {\r\n\t\t\t$extension = false;\r\n\t\t\tif ($cellAddress == '$B$65536') {\r\n\t\t\t\t//\tIf the address row is -1 and the column is 0, (which translates as $B$65536) then this is a continuation\r\n\t\t\t\t//\t\tnote from the previous cell annotation. We're not yet handling this, so annotations longer than the\r\n\t\t\t\t//\t\tmax 2048 bytes will probably throw a wobbly.\r\n\t\t\t\t$row = self::_GetInt2d($recordData, 0);\r\n\t\t\t\t$extension = true;\r\n\t\t\t\t$cellAddress = array_pop(array_keys($this->_phpSheet->getComments()));\r\n\t\t\t}\r\n//\t\t\techo 'Note Address=',$cellAddress,'<br />';\r\n\r\n\t\t\t$cellAddress = str_replace('$','',$cellAddress);\r\n\t\t\t$noteLength = self::_GetInt2d($recordData, 4);\r\n\t\t\t$noteText = trim(substr($recordData, 6));\r\n//\t\t\techo 'Note Length=',$noteLength,'<br />';\r\n//\t\t\techo 'Note Text=',$noteText,'<br />';\r\n\r\n\t\t\tif ($extension) {\r\n\t\t\t\t//\tConcatenate this extension with the currently set comment for the cell\r\n\t\t\t\t$comment = $this->_phpSheet->getComment( $cellAddress );\r\n\t\t\t\t$commentText = $comment->getText()->getPlainText();\r\n\t\t\t\t$comment->setText($this->_parseRichText($commentText.$noteText) );\r\n\t\t\t} else {\r\n\t\t\t\t//\tSet comment for the cell\r\n\t\t\t\t$this->_phpSheet->getComment( $cellAddress )\r\n//\t\t\t\t\t\t\t\t\t\t\t\t\t->setAuthor( $author )\r\n\t\t\t\t\t\t\t\t\t\t\t\t\t->setText($this->_parseRichText($noteText) );\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t}\r\n\r\n\r\n\t/**\r\n\t *\tThe TEXT Object record contains the text associated with a cell annotation.\r\n\t */\r\n\tprivate function _readTextObject()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_readDataOnly) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// recordData consists of an array of subrecords looking like this:\r\n\t\t//\tgrbit: 2 bytes; Option Flags\r\n\t\t//\trot: 2 bytes; rotation\r\n\t\t//\tcchText: 2 bytes; length of the text (in the first continue record)\r\n\t\t//\tcbRuns: 2 bytes; length of the formatting (in the second continue record)\r\n\t\t// followed by the continuation records containing the actual text and formatting\r\n\t\t$grbitOpts\t= self::_GetInt2d($recordData, 0);\r\n\t\t$rot\t\t= self::_GetInt2d($recordData, 2);\r\n\t\t$cchText\t= self::_GetInt2d($recordData, 10);\r\n\t\t$cbRuns\t\t= self::_GetInt2d($recordData, 12);\r\n\t\t$text\t\t= $this->_getSplicedRecordData();\r\n\r\n\t\t$this->_textObjects[$this->textObjRef] = array(\r\n\t\t\t\t'text'\t\t=> substr($text[\"recordData\"],$text[\"spliceOffsets\"][0]+1,$cchText),\r\n\t\t\t\t'format'\t=> substr($text[\"recordData\"],$text[\"spliceOffsets\"][1],$cbRuns),\r\n\t\t\t\t'alignment'\t=> $grbitOpts,\r\n\t\t\t\t'rotation'\t=> $rot\r\n\t\t\t );\r\n\r\n//\t\techo '<b>_readTextObject()</b><br />';\r\n//\t\tvar_dump($this->_textObjects[$this->textObjRef]);\r\n//\t\techo '<br />';\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read BOF\r\n\t */\r\n\tprivate function _readBof()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = substr($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 2; size: 2; type of the following data\r\n\t\t$substreamType = self::_GetInt2d($recordData, 2);\r\n\r\n\t\tswitch ($substreamType) {\r\n\t\t\tcase self::XLS_WorkbookGlobals:\r\n\t\t\t\t$version = self::_GetInt2d($recordData, 0);\r\n\t\t\t\tif (($version != self::XLS_BIFF8) && ($version != self::XLS_BIFF7)) {\r\n\t\t\t\t\tthrow new PHPExcel_Reader_Exception('Cannot read this Excel file. Version is too old.');\r\n\t\t\t\t}\r\n\t\t\t\t$this->_version = $version;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase self::XLS_Worksheet:\r\n\t\t\t\t// do not use this version information for anything\r\n\t\t\t\t// it is unreliable (OpenOffice doc, 5.8), use only version information from the global stream\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tdefault:\r\n\t\t\t\t// substream, e.g. chart\r\n\t\t\t\t// just skip the entire substream\r\n\t\t\t\tdo {\r\n\t\t\t\t\t$code = self::_GetInt2d($this->_data, $this->_pos);\r\n\t\t\t\t\t$this->_readDefault();\r\n\t\t\t\t} while ($code != self::XLS_Type_EOF && $this->_pos < $this->_dataSize);\r\n\t\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * FILEPASS\r\n\t *\r\n\t * This record is part of the File Protection Block. It\r\n\t * contains information about the read/write password of the\r\n\t * file. All record contents following this record will be\r\n\t * encrypted.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t * \r\n\t * The decryption functions and objects used from here on in\r\n\t * are based on the source of Spreadsheet-ParseExcel:\r\n\t * http://search.cpan.org/~jmcnamara/Spreadsheet-ParseExcel/\r\n\t */\r\n\tprivate function _readFilepass()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\r\n\t\tif ($length != 54) {\r\n\t\t\tthrow new PHPExcel_Reader_Exception('Unexpected file pass record length');\r\n\t\t}\r\n\t\t\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\t\t\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\t\t\r\n\t\tif (!$this->_verifyPassword(\r\n\t\t\t'VelvetSweatshop',\r\n\t\t\tsubstr($recordData, 6,  16),\r\n\t\t\tsubstr($recordData, 22, 16),\r\n\t\t\tsubstr($recordData, 38, 16),\r\n\t\t\t$this->_md5Ctxt\r\n\t\t)) {\r\n\t\t\tthrow new PHPExcel_Reader_Exception('Decryption password incorrect');\r\n\t\t}\r\n\t\t\r\n\t\t$this->_encryption = self::MS_BIFF_CRYPTO_RC4;\r\n\r\n\t\t// Decryption required from the record after next onwards\r\n\t\t$this->_encryptionStartPos = $this->_pos + self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t}\r\n\r\n\t/**\r\n\t * Make an RC4 decryptor for the given block\r\n\t * \r\n\t * @var int    $block      Block for which to create decrypto\r\n\t * @var string $valContext MD5 context state\r\n\t * \r\n\t * @return PHPExcel_Reader_Excel5_RC4\r\n\t */\r\n\tprivate function _makeKey($block, $valContext)\r\n\t{\r\n\t\t$pwarray = str_repeat(\"\\0\", 64);\r\n\r\n\t\tfor ($i = 0; $i < 5; $i++) {\r\n\t\t\t$pwarray[$i] = $valContext[$i];\r\n\t\t}\r\n\t\t\r\n\t\t$pwarray[5] = chr($block & 0xff);\r\n\t\t$pwarray[6] = chr(($block >> 8) & 0xff);\r\n\t\t$pwarray[7] = chr(($block >> 16) & 0xff);\r\n\t\t$pwarray[8] = chr(($block >> 24) & 0xff);\r\n\r\n\t\t$pwarray[9] = \"\\x80\";\r\n\t\t$pwarray[56] = \"\\x48\";\r\n\r\n\t\t$md5 = new PHPExcel_Reader_Excel5_MD5();\r\n\t\t$md5->add($pwarray);\r\n\r\n\t\t$s = $md5->getContext();\r\n\t\treturn new PHPExcel_Reader_Excel5_RC4($s);\r\n\t}\r\n\r\n\t/**\r\n\t * Verify RC4 file password\r\n\t * \r\n\t * @var string $password        Password to check\r\n\t * @var string $docid           Document id\r\n\t * @var string $salt_data       Salt data\r\n\t * @var string $hashedsalt_data Hashed salt data\r\n\t * @var string &$valContext     Set to the MD5 context of the value\r\n\t * \r\n\t * @return bool Success\r\n\t */\r\n\tprivate function _verifyPassword($password, $docid, $salt_data, $hashedsalt_data, &$valContext)\r\n\t{\r\n\t\t$pwarray = str_repeat(\"\\0\", 64);\r\n\r\n\t\tfor ($i = 0; $i < strlen($password); $i++) {\r\n\t\t\t$o = ord(substr($password, $i, 1));\r\n\t\t\t$pwarray[2 * $i] = chr($o & 0xff);\r\n\t\t\t$pwarray[2 * $i + 1] = chr(($o >> 8) & 0xff);\r\n\t\t}\r\n\t\t$pwarray[2 * $i] = chr(0x80);\r\n\t\t$pwarray[56] = chr(($i << 4) & 0xff);\r\n\r\n\t\t$md5 = new PHPExcel_Reader_Excel5_MD5();\r\n\t\t$md5->add($pwarray);\r\n\r\n\t\t$mdContext1 = $md5->getContext();\r\n\r\n\t\t$offset = 0;\r\n\t\t$keyoffset = 0;\r\n\t\t$tocopy = 5;\r\n\r\n\t\t$md5->reset();\r\n\r\n\t\twhile ($offset != 16) {\r\n\t\t\tif ((64 - $offset) < 5) {\r\n\t\t\t\t$tocopy = 64 - $offset;\r\n\t\t\t}\r\n\t\t\t\r\n\t\t\tfor ($i = 0; $i <= $tocopy; $i++) {\r\n\t\t\t\t$pwarray[$offset + $i] = $mdContext1[$keyoffset + $i];\r\n\t\t\t}\r\n\r\n\t\t\t$offset += $tocopy;\r\n\r\n\t\t\tif ($offset == 64) {\r\n\t\t\t\t$md5->add($pwarray);\r\n\t\t\t\t$keyoffset = $tocopy;\r\n\t\t\t\t$tocopy = 5 - $tocopy;\r\n\t\t\t\t$offset = 0;\r\n\t\t\t\tcontinue;\r\n\t\t\t}\r\n\r\n\t\t\t$keyoffset = 0;\r\n\t\t\t$tocopy = 5;\r\n\t\t\tfor ($i = 0; $i < 16; $i++) {\r\n\t\t\t\t$pwarray[$offset + $i] = $docid[$i];\r\n\t\t\t}\r\n\t\t\t$offset += 16;\r\n\t\t}\r\n\r\n\t\t$pwarray[16] = \"\\x80\";\r\n\t\tfor ($i = 0; $i < 47; $i++) {\r\n\t\t\t$pwarray[17 + $i] = \"\\0\";\r\n\t\t}\r\n\t\t$pwarray[56] = \"\\x80\";\r\n\t\t$pwarray[57] = \"\\x0a\";\r\n\r\n\t\t$md5->add($pwarray);\r\n\t\t$valContext = $md5->getContext();\r\n\r\n\t\t$key = $this->_makeKey(0, $valContext);\r\n\r\n\t\t$salt = $key->RC4($salt_data);\r\n\t\t$hashedsalt = $key->RC4($hashedsalt_data);\r\n\t\t\r\n\t\t$salt .= \"\\x80\" . str_repeat(\"\\0\", 47);\r\n\t\t$salt[56] = \"\\x80\";\r\n\r\n\t\t$md5->reset();\r\n\t\t$md5->add($salt);\r\n\t\t$mdContext2 = $md5->getContext();\r\n\r\n\t\treturn $mdContext2 == $hashedsalt;\r\n\t}\r\n\r\n\t/**\r\n\t * CODEPAGE\r\n\t *\r\n\t * This record stores the text encoding used to write byte\r\n\t * strings, stored as MS Windows code page identifier.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readCodepage()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; code page identifier\r\n\t\t$codepage = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t$this->_codepage = PHPExcel_Shared_CodePage::NumberToName($codepage);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * DATEMODE\r\n\t *\r\n\t * This record specifies the base date for displaying date\r\n\t * values. All dates are stored as count of days past this\r\n\t * base date. In BIFF2-BIFF4 this record is part of the\r\n\t * Calculation Settings Block. In BIFF5-BIFF8 it is\r\n\t * stored in the Workbook Globals Substream.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readDateMode()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; 0 = base 1900, 1 = base 1904\r\n\t\tPHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900);\r\n\t\tif (ord($recordData{0}) == 1) {\r\n\t\t\tPHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read a FONT record\r\n\t */\r\n\tprivate function _readFont()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t$objFont = new PHPExcel_Style_Font();\r\n\r\n\t\t\t// offset: 0; size: 2; height of the font (in twips = 1/20 of a point)\r\n\t\t\t$size = self::_GetInt2d($recordData, 0);\r\n\t\t\t$objFont->setSize($size / 20);\r\n\r\n\t\t\t// offset: 2; size: 2; option flags\r\n\t\t\t\t// bit: 0; mask 0x0001; bold (redundant in BIFF5-BIFF8)\r\n\t\t\t\t// bit: 1; mask 0x0002; italic\r\n\t\t\t\t$isItalic = (0x0002 & self::_GetInt2d($recordData, 2)) >> 1;\r\n\t\t\t\tif ($isItalic) $objFont->setItalic(true);\r\n\r\n\t\t\t\t// bit: 2; mask 0x0004; underlined (redundant in BIFF5-BIFF8)\r\n\t\t\t\t// bit: 3; mask 0x0008; strike\r\n\t\t\t\t$isStrike = (0x0008 & self::_GetInt2d($recordData, 2)) >> 3;\r\n\t\t\t\tif ($isStrike) $objFont->setStrikethrough(true);\r\n\r\n\t\t\t// offset: 4; size: 2; colour index\r\n\t\t\t$colorIndex = self::_GetInt2d($recordData, 4);\r\n\t\t\t$objFont->colorIndex = $colorIndex;\r\n\r\n\t\t\t// offset: 6; size: 2; font weight\r\n\t\t\t$weight = self::_GetInt2d($recordData, 6);\r\n\t\t\tswitch ($weight) {\r\n\t\t\t\tcase 0x02BC:\r\n\t\t\t\t\t$objFont->setBold(true);\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\t// offset: 8; size: 2; escapement type\r\n\t\t\t$escapement = self::_GetInt2d($recordData, 8);\r\n\t\t\tswitch ($escapement) {\r\n\t\t\t\tcase 0x0001:\r\n\t\t\t\t\t$objFont->setSuperScript(true);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 0x0002:\r\n\t\t\t\t\t$objFont->setSubScript(true);\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\t// offset: 10; size: 1; underline type\r\n\t\t\t$underlineType = ord($recordData{10});\r\n\t\t\tswitch ($underlineType) {\r\n\t\t\t\tcase 0x00:\r\n\t\t\t\t\tbreak; // no underline\r\n\t\t\t\tcase 0x01:\r\n\t\t\t\t\t$objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 0x02:\r\n\t\t\t\t\t$objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLE);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 0x21:\r\n\t\t\t\t\t$objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 0x22:\r\n\t\t\t\t\t$objFont->setUnderline(PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING);\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\t// offset: 11; size: 1; font family\r\n\t\t\t// offset: 12; size: 1; character set\r\n\t\t\t// offset: 13; size: 1; not used\r\n\t\t\t// offset: 14; size: var; font name\r\n\t\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t\t$string = self::_readUnicodeStringShort(substr($recordData, 14));\r\n\t\t\t} else {\r\n\t\t\t\t$string = $this->_readByteStringShort(substr($recordData, 14));\r\n\t\t\t}\r\n\t\t\t$objFont->setName($string['value']);\r\n\r\n\t\t\t$this->_objFonts[] = $objFont;\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * FORMAT\r\n\t *\r\n\t * This record contains information about a number format.\r\n\t * All FORMAT records occur together in a sequential list.\r\n\t *\r\n\t * In BIFF2-BIFF4 other records referencing a FORMAT record\r\n\t * contain a zero-based index into this list. From BIFF5 on\r\n\t * the FORMAT record contains the index itself that will be\r\n\t * used by other records.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readFormat()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t$indexCode = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t\t$string = self::_readUnicodeStringLong(substr($recordData, 2));\r\n\t\t\t} else {\r\n\t\t\t\t// BIFF7\r\n\t\t\t\t$string = $this->_readByteStringShort(substr($recordData, 2));\r\n\t\t\t}\r\n\r\n\t\t\t$formatString = $string['value'];\r\n\t\t\t$this->_formats[$indexCode] = $formatString;\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * XF - Extended Format\r\n\t *\r\n\t * This record contains formatting information for cells, rows, columns or styles.\r\n\t * According to http://support.microsoft.com/kb/147732 there are always at least 15 cell style XF\r\n\t * and 1 cell XF.\r\n\t * Inspection of Excel files generated by MS Office Excel shows that XF records 0-14 are cell style XF\r\n\t * and XF record 15 is a cell XF\r\n\t * We only read the first cell style XF and skip the remaining cell style XF records\r\n\t * We read all cell XF records.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readXf()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t$objStyle = new PHPExcel_Style();\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset:  0; size: 2; Index to FONT record\r\n\t\t\tif (self::_GetInt2d($recordData, 0) < 4) {\r\n\t\t\t\t$fontIndex = self::_GetInt2d($recordData, 0);\r\n\t\t\t} else {\r\n\t\t\t\t// this has to do with that index 4 is omitted in all BIFF versions for some strange reason\r\n\t\t\t\t// check the OpenOffice documentation of the FONT record\r\n\t\t\t\t$fontIndex = self::_GetInt2d($recordData, 0) - 1;\r\n\t\t\t}\r\n\t\t\t$objStyle->setFont($this->_objFonts[$fontIndex]);\r\n\r\n\t\t\t// offset:  2; size: 2; Index to FORMAT record\r\n\t\t\t$numberFormatIndex = self::_GetInt2d($recordData, 2);\r\n\t\t\tif (isset($this->_formats[$numberFormatIndex])) {\r\n\t\t\t\t// then we have user-defined format code\r\n\t\t\t\t$numberformat = array('code' => $this->_formats[$numberFormatIndex]);\r\n\t\t\t} elseif (($code = PHPExcel_Style_NumberFormat::builtInFormatCode($numberFormatIndex)) !== '') {\r\n\t\t\t\t// then we have built-in format code\r\n\t\t\t\t$numberformat = array('code' => $code);\r\n\t\t\t} else {\r\n\t\t\t\t// we set the general format code\r\n\t\t\t\t$numberformat = array('code' => 'General');\r\n\t\t\t}\r\n\t\t\t$objStyle->getNumberFormat()->setFormatCode($numberformat['code']);\r\n\r\n\t\t\t// offset:  4; size: 2; XF type, cell protection, and parent style XF\r\n\t\t\t// bit 2-0; mask 0x0007; XF_TYPE_PROT\r\n\t\t\t$xfTypeProt = self::_GetInt2d($recordData, 4);\r\n\t\t\t// bit 0; mask 0x01; 1 = cell is locked\r\n\t\t\t$isLocked = (0x01 & $xfTypeProt) >> 0;\r\n\t\t\t$objStyle->getProtection()->setLocked($isLocked ?\r\n\t\t\t\tPHPExcel_Style_Protection::PROTECTION_INHERIT : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED);\r\n\r\n\t\t\t// bit 1; mask 0x02; 1 = Formula is hidden\r\n\t\t\t$isHidden = (0x02 & $xfTypeProt) >> 1;\r\n\t\t\t$objStyle->getProtection()->setHidden($isHidden ?\r\n\t\t\t\tPHPExcel_Style_Protection::PROTECTION_PROTECTED : PHPExcel_Style_Protection::PROTECTION_UNPROTECTED);\r\n\r\n\t\t\t// bit 2; mask 0x04; 0 = Cell XF, 1 = Cell Style XF\r\n\t\t\t$isCellStyleXf = (0x04 & $xfTypeProt) >> 2;\r\n\r\n\t\t\t// offset:  6; size: 1; Alignment and text break\r\n\t\t\t// bit 2-0, mask 0x07; horizontal alignment\r\n\t\t\t$horAlign = (0x07 & ord($recordData{6})) >> 0;\r\n\t\t\tswitch ($horAlign) {\r\n\t\t\t\tcase 0:\r\n\t\t\t\t\t$objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_GENERAL);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 1:\r\n\t\t\t\t\t$objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_LEFT);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 2:\r\n\t\t\t\t\t$objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 3:\r\n\t\t\t\t\t$objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 4:\r\n\t\t\t\t\t$objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_FILL);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 5:\r\n\t\t\t\t\t$objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 6:\r\n\t\t\t\t\t$objStyle->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS);\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\t// bit 3, mask 0x08; wrap text\r\n\t\t\t$wrapText = (0x08 & ord($recordData{6})) >> 3;\r\n\t\t\tswitch ($wrapText) {\r\n\t\t\t\tcase 0:\r\n\t\t\t\t\t$objStyle->getAlignment()->setWrapText(false);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 1:\r\n\t\t\t\t\t$objStyle->getAlignment()->setWrapText(true);\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\t// bit 6-4, mask 0x70; vertical alignment\r\n\t\t\t$vertAlign = (0x70 & ord($recordData{6})) >> 4;\r\n\t\t\tswitch ($vertAlign) {\r\n\t\t\t\tcase 0:\r\n\t\t\t\t\t$objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_TOP);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 1:\r\n\t\t\t\t\t$objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 2:\r\n\t\t\t\t\t$objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_BOTTOM);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 3:\r\n\t\t\t\t\t$objStyle->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_JUSTIFY);\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t\t// offset:  7; size: 1; XF_ROTATION: Text rotation angle\r\n\t\t\t\t\t$angle = ord($recordData{7});\r\n\t\t\t\t\t$rotation = 0;\r\n\t\t\t\t\tif ($angle <= 90) {\r\n\t\t\t\t\t\t$rotation = $angle;\r\n\t\t\t\t\t} else if ($angle <= 180) {\r\n\t\t\t\t\t\t$rotation = 90 - $angle;\r\n\t\t\t\t\t} else if ($angle == 255) {\r\n\t\t\t\t\t\t$rotation = -165;\r\n\t\t\t\t\t}\r\n\t\t\t\t\t$objStyle->getAlignment()->setTextRotation($rotation);\r\n\r\n\t\t\t\t// offset:  8; size: 1; Indentation, shrink to cell size, and text direction\r\n\t\t\t\t\t// bit: 3-0; mask: 0x0F; indent level\r\n\t\t\t\t\t$indent = (0x0F & ord($recordData{8})) >> 0;\r\n\t\t\t\t\t$objStyle->getAlignment()->setIndent($indent);\r\n\r\n\t\t\t\t\t// bit: 4; mask: 0x10; 1 = shrink content to fit into cell\r\n\t\t\t\t\t$shrinkToFit = (0x10 & ord($recordData{8})) >> 4;\r\n\t\t\t\t\tswitch ($shrinkToFit) {\r\n\t\t\t\t\t\tcase 0:\r\n\t\t\t\t\t\t\t$objStyle->getAlignment()->setShrinkToFit(false);\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\tcase 1:\r\n\t\t\t\t\t\t\t$objStyle->getAlignment()->setShrinkToFit(true);\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t// offset:  9; size: 1; Flags used for attribute groups\r\n\r\n\t\t\t\t// offset: 10; size: 4; Cell border lines and background area\r\n\t\t\t\t\t// bit: 3-0; mask: 0x0000000F; left style\r\n\t\t\t\t\tif ($bordersLeftStyle = self::_mapBorderStyle((0x0000000F & self::_GetInt4d($recordData, 10)) >> 0)) {\r\n\t\t\t\t\t\t$objStyle->getBorders()->getLeft()->setBorderStyle($bordersLeftStyle);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// bit: 7-4; mask: 0x000000F0; right style\r\n\t\t\t\t\tif ($bordersRightStyle = self::_mapBorderStyle((0x000000F0 & self::_GetInt4d($recordData, 10)) >> 4)) {\r\n\t\t\t\t\t\t$objStyle->getBorders()->getRight()->setBorderStyle($bordersRightStyle);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// bit: 11-8; mask: 0x00000F00; top style\r\n\t\t\t\t\tif ($bordersTopStyle = self::_mapBorderStyle((0x00000F00 & self::_GetInt4d($recordData, 10)) >> 8)) {\r\n\t\t\t\t\t\t$objStyle->getBorders()->getTop()->setBorderStyle($bordersTopStyle);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// bit: 15-12; mask: 0x0000F000; bottom style\r\n\t\t\t\t\tif ($bordersBottomStyle = self::_mapBorderStyle((0x0000F000 & self::_GetInt4d($recordData, 10)) >> 12)) {\r\n\t\t\t\t\t\t$objStyle->getBorders()->getBottom()->setBorderStyle($bordersBottomStyle);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t// bit: 22-16; mask: 0x007F0000; left color\r\n\t\t\t\t\t$objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & self::_GetInt4d($recordData, 10)) >> 16;\r\n\r\n\t\t\t\t\t// bit: 29-23; mask: 0x3F800000; right color\r\n\t\t\t\t\t$objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & self::_GetInt4d($recordData, 10)) >> 23;\r\n\r\n\t\t\t\t\t// bit: 30; mask: 0x40000000; 1 = diagonal line from top left to right bottom\r\n\t\t\t\t\t$diagonalDown = (0x40000000 & self::_GetInt4d($recordData, 10)) >> 30 ?\r\n\t\t\t\t\t\ttrue : false;\r\n\r\n\t\t\t\t\t// bit: 31; mask: 0x80000000; 1 = diagonal line from bottom left to top right\r\n\t\t\t\t\t$diagonalUp = (0x80000000 & self::_GetInt4d($recordData, 10)) >> 31 ?\r\n\t\t\t\t\t\ttrue : false;\r\n\r\n\t\t\t\t\tif ($diagonalUp == false && $diagonalDown == false) {\r\n\t\t\t\t\t\t$objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_NONE);\r\n\t\t\t\t\t} elseif ($diagonalUp == true && $diagonalDown == false) {\r\n\t\t\t\t\t\t$objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_UP);\r\n\t\t\t\t\t} elseif ($diagonalUp == false && $diagonalDown == true) {\r\n\t\t\t\t\t\t$objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_DOWN);\r\n\t\t\t\t\t} elseif ($diagonalUp == true && $diagonalDown == true) {\r\n\t\t\t\t\t\t$objStyle->getBorders()->setDiagonalDirection(PHPExcel_Style_Borders::DIAGONAL_BOTH);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t// offset: 14; size: 4;\r\n\t\t\t\t\t// bit: 6-0; mask: 0x0000007F; top color\r\n\t\t\t\t\t$objStyle->getBorders()->getTop()->colorIndex = (0x0000007F & self::_GetInt4d($recordData, 14)) >> 0;\r\n\r\n\t\t\t\t\t// bit: 13-7; mask: 0x00003F80; bottom color\r\n\t\t\t\t\t$objStyle->getBorders()->getBottom()->colorIndex = (0x00003F80 & self::_GetInt4d($recordData, 14)) >> 7;\r\n\r\n\t\t\t\t\t// bit: 20-14; mask: 0x001FC000; diagonal color\r\n\t\t\t\t\t$objStyle->getBorders()->getDiagonal()->colorIndex = (0x001FC000 & self::_GetInt4d($recordData, 14)) >> 14;\r\n\r\n\t\t\t\t\t// bit: 24-21; mask: 0x01E00000; diagonal style\r\n\t\t\t\t\tif ($bordersDiagonalStyle = self::_mapBorderStyle((0x01E00000 & self::_GetInt4d($recordData, 14)) >> 21)) {\r\n\t\t\t\t\t\t$objStyle->getBorders()->getDiagonal()->setBorderStyle($bordersDiagonalStyle);\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// bit: 31-26; mask: 0xFC000000 fill pattern\r\n\t\t\t\t\tif ($fillType = self::_mapFillPattern((0xFC000000 & self::_GetInt4d($recordData, 14)) >> 26)) {\r\n\t\t\t\t\t\t$objStyle->getFill()->setFillType($fillType);\r\n\t\t\t\t\t}\r\n\t\t\t\t// offset: 18; size: 2; pattern and background colour\r\n\t\t\t\t\t// bit: 6-0; mask: 0x007F; color index for pattern color\r\n\t\t\t\t\t$objStyle->getFill()->startcolorIndex = (0x007F & self::_GetInt2d($recordData, 18)) >> 0;\r\n\r\n\t\t\t\t\t// bit: 13-7; mask: 0x3F80; color index for pattern background\r\n\t\t\t\t\t$objStyle->getFill()->endcolorIndex = (0x3F80 & self::_GetInt2d($recordData, 18)) >> 7;\r\n\t\t\t} else {\r\n\t\t\t\t// BIFF5\r\n\r\n\t\t\t\t// offset: 7; size: 1; Text orientation and flags\r\n\t\t\t\t$orientationAndFlags = ord($recordData{7});\r\n\r\n\t\t\t\t// bit: 1-0; mask: 0x03; XF_ORIENTATION: Text orientation\r\n\t\t\t\t$xfOrientation = (0x03 & $orientationAndFlags) >> 0;\r\n\t\t\t\tswitch ($xfOrientation) {\r\n\t\t\t\t\tcase 0:\r\n\t\t\t\t\t\t$objStyle->getAlignment()->setTextRotation(0);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 1:\r\n\t\t\t\t\t\t$objStyle->getAlignment()->setTextRotation(-165);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 2:\r\n\t\t\t\t\t\t$objStyle->getAlignment()->setTextRotation(90);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t\tcase 3:\r\n\t\t\t\t\t\t$objStyle->getAlignment()->setTextRotation(-90);\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// offset: 8; size: 4; cell border lines and background area\r\n\t\t\t\t$borderAndBackground = self::_GetInt4d($recordData, 8);\r\n\r\n\t\t\t\t// bit: 6-0; mask: 0x0000007F; color index for pattern color\r\n\t\t\t\t$objStyle->getFill()->startcolorIndex = (0x0000007F & $borderAndBackground) >> 0;\r\n\r\n\t\t\t\t// bit: 13-7; mask: 0x00003F80; color index for pattern background\r\n\t\t\t\t$objStyle->getFill()->endcolorIndex = (0x00003F80 & $borderAndBackground) >> 7;\r\n\r\n\t\t\t\t// bit: 21-16; mask: 0x003F0000; fill pattern\r\n\t\t\t\t$objStyle->getFill()->setFillType(self::_mapFillPattern((0x003F0000 & $borderAndBackground) >> 16));\r\n\r\n\t\t\t\t// bit: 24-22; mask: 0x01C00000; bottom line style\r\n\t\t\t\t$objStyle->getBorders()->getBottom()->setBorderStyle(self::_mapBorderStyle((0x01C00000 & $borderAndBackground) >> 22));\r\n\r\n\t\t\t\t// bit: 31-25; mask: 0xFE000000; bottom line color\r\n\t\t\t\t$objStyle->getBorders()->getBottom()->colorIndex = (0xFE000000 & $borderAndBackground) >> 25;\r\n\r\n\t\t\t\t// offset: 12; size: 4; cell border lines\r\n\t\t\t\t$borderLines = self::_GetInt4d($recordData, 12);\r\n\r\n\t\t\t\t// bit: 2-0; mask: 0x00000007; top line style\r\n\t\t\t\t$objStyle->getBorders()->getTop()->setBorderStyle(self::_mapBorderStyle((0x00000007 & $borderLines) >> 0));\r\n\r\n\t\t\t\t// bit: 5-3; mask: 0x00000038; left line style\r\n\t\t\t\t$objStyle->getBorders()->getLeft()->setBorderStyle(self::_mapBorderStyle((0x00000038 & $borderLines) >> 3));\r\n\r\n\t\t\t\t// bit: 8-6; mask: 0x000001C0; right line style\r\n\t\t\t\t$objStyle->getBorders()->getRight()->setBorderStyle(self::_mapBorderStyle((0x000001C0 & $borderLines) >> 6));\r\n\r\n\t\t\t\t// bit: 15-9; mask: 0x0000FE00; top line color index\r\n\t\t\t\t$objStyle->getBorders()->getTop()->colorIndex = (0x0000FE00 & $borderLines) >> 9;\r\n\r\n\t\t\t\t// bit: 22-16; mask: 0x007F0000; left line color index\r\n\t\t\t\t$objStyle->getBorders()->getLeft()->colorIndex = (0x007F0000 & $borderLines) >> 16;\r\n\r\n\t\t\t\t// bit: 29-23; mask: 0x3F800000; right line color index\r\n\t\t\t\t$objStyle->getBorders()->getRight()->colorIndex = (0x3F800000 & $borderLines) >> 23;\r\n\t\t\t}\r\n\r\n\t\t\t// add cellStyleXf or cellXf and update mapping\r\n\t\t\tif ($isCellStyleXf) {\r\n\t\t\t\t// we only read one style XF record which is always the first\r\n\t\t\t\tif ($this->_xfIndex == 0) {\r\n\t\t\t\t\t$this->_phpExcel->addCellStyleXf($objStyle);\r\n\t\t\t\t\t$this->_mapCellStyleXfIndex[$this->_xfIndex] = 0;\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\t// we read all cell XF records\r\n\t\t\t\t$this->_phpExcel->addCellXf($objStyle);\r\n\t\t\t\t$this->_mapCellXfIndex[$this->_xfIndex] = count($this->_phpExcel->getCellXfCollection()) - 1;\r\n\t\t\t}\r\n\r\n\t\t\t// update XF index for when we read next record\r\n\t\t\t++$this->_xfIndex;\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t *\r\n\t */\r\n\tprivate function _readXfExt()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 2; 0x087D = repeated header\r\n\r\n\t\t\t// offset: 2; size: 2\r\n\r\n\t\t\t// offset: 4; size: 8; not used\r\n\r\n\t\t\t// offset: 12; size: 2; record version\r\n\r\n\t\t\t// offset: 14; size: 2; index to XF record which this record modifies\r\n\t\t\t$ixfe = self::_GetInt2d($recordData, 14);\r\n\r\n\t\t\t// offset: 16; size: 2; not used\r\n\r\n\t\t\t// offset: 18; size: 2; number of extension properties that follow\r\n\t\t\t$cexts = self::_GetInt2d($recordData, 18);\r\n\r\n\t\t\t// start reading the actual extension data\r\n\t\t\t$offset = 20;\r\n\t\t\twhile ($offset < $length) {\r\n\t\t\t\t// extension type\r\n\t\t\t\t$extType = self::_GetInt2d($recordData, $offset);\r\n\r\n\t\t\t\t// extension length\r\n\t\t\t\t$cb = self::_GetInt2d($recordData, $offset + 2);\r\n\r\n\t\t\t\t// extension data\r\n\t\t\t\t$extData = substr($recordData, $offset + 4, $cb);\r\n\r\n\t\t\t\tswitch ($extType) {\r\n\t\t\t\t\tcase 4:\t\t// fill start color\r\n\t\t\t\t\t\t$xclfType  = self::_GetInt2d($extData, 0); // color type\r\n\t\t\t\t\t\t$xclrValue = substr($extData, 4, 4); // color value (value based on color type)\r\n\r\n\t\t\t\t\t\tif ($xclfType == 2) {\r\n\t\t\t\t\t\t\t$rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));\r\n\r\n\t\t\t\t\t\t\t// modify the relevant style property\r\n\t\t\t\t\t\t\tif ( isset($this->_mapCellXfIndex[$ixfe]) ) {\r\n\t\t\t\t\t\t\t\t$fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill();\r\n\t\t\t\t\t\t\t\t$fill->getStartColor()->setRGB($rgb);\r\n\t\t\t\t\t\t\t\tunset($fill->startcolorIndex); // normal color index does not apply, discard\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\tcase 5:\t\t// fill end color\r\n\t\t\t\t\t\t$xclfType  = self::_GetInt2d($extData, 0); // color type\r\n\t\t\t\t\t\t$xclrValue = substr($extData, 4, 4); // color value (value based on color type)\r\n\r\n\t\t\t\t\t\tif ($xclfType == 2) {\r\n\t\t\t\t\t\t\t$rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));\r\n\r\n\t\t\t\t\t\t\t// modify the relevant style property\r\n\t\t\t\t\t\t\tif ( isset($this->_mapCellXfIndex[$ixfe]) ) {\r\n\t\t\t\t\t\t\t\t$fill = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFill();\r\n\t\t\t\t\t\t\t\t$fill->getEndColor()->setRGB($rgb);\r\n\t\t\t\t\t\t\t\tunset($fill->endcolorIndex); // normal color index does not apply, discard\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\tcase 7:\t\t// border color top\r\n\t\t\t\t\t\t$xclfType  = self::_GetInt2d($extData, 0); // color type\r\n\t\t\t\t\t\t$xclrValue = substr($extData, 4, 4); // color value (value based on color type)\r\n\r\n\t\t\t\t\t\tif ($xclfType == 2) {\r\n\t\t\t\t\t\t\t$rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));\r\n\r\n\t\t\t\t\t\t\t// modify the relevant style property\r\n\t\t\t\t\t\t\tif ( isset($this->_mapCellXfIndex[$ixfe]) ) {\r\n\t\t\t\t\t\t\t\t$top = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getTop();\r\n\t\t\t\t\t\t\t\t$top->getColor()->setRGB($rgb);\r\n\t\t\t\t\t\t\t\tunset($top->colorIndex); // normal color index does not apply, discard\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\tcase 8:\t\t// border color bottom\r\n\t\t\t\t\t\t$xclfType  = self::_GetInt2d($extData, 0); // color type\r\n\t\t\t\t\t\t$xclrValue = substr($extData, 4, 4); // color value (value based on color type)\r\n\r\n\t\t\t\t\t\tif ($xclfType == 2) {\r\n\t\t\t\t\t\t\t$rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));\r\n\r\n\t\t\t\t\t\t\t// modify the relevant style property\r\n\t\t\t\t\t\t\tif ( isset($this->_mapCellXfIndex[$ixfe]) ) {\r\n\t\t\t\t\t\t\t\t$bottom = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getBottom();\r\n\t\t\t\t\t\t\t\t$bottom->getColor()->setRGB($rgb);\r\n\t\t\t\t\t\t\t\tunset($bottom->colorIndex); // normal color index does not apply, discard\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\tcase 9:\t\t// border color left\r\n\t\t\t\t\t\t$xclfType  = self::_GetInt2d($extData, 0); // color type\r\n\t\t\t\t\t\t$xclrValue = substr($extData, 4, 4); // color value (value based on color type)\r\n\r\n\t\t\t\t\t\tif ($xclfType == 2) {\r\n\t\t\t\t\t\t\t$rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));\r\n\r\n\t\t\t\t\t\t\t// modify the relevant style property\r\n\t\t\t\t\t\t\tif ( isset($this->_mapCellXfIndex[$ixfe]) ) {\r\n\t\t\t\t\t\t\t\t$left = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getLeft();\r\n\t\t\t\t\t\t\t\t$left->getColor()->setRGB($rgb);\r\n\t\t\t\t\t\t\t\tunset($left->colorIndex); // normal color index does not apply, discard\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\tcase 10:\t\t// border color right\r\n\t\t\t\t\t\t$xclfType  = self::_GetInt2d($extData, 0); // color type\r\n\t\t\t\t\t\t$xclrValue = substr($extData, 4, 4); // color value (value based on color type)\r\n\r\n\t\t\t\t\t\tif ($xclfType == 2) {\r\n\t\t\t\t\t\t\t$rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));\r\n\r\n\t\t\t\t\t\t\t// modify the relevant style property\r\n\t\t\t\t\t\t\tif ( isset($this->_mapCellXfIndex[$ixfe]) ) {\r\n\t\t\t\t\t\t\t\t$right = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getRight();\r\n\t\t\t\t\t\t\t\t$right->getColor()->setRGB($rgb);\r\n\t\t\t\t\t\t\t\tunset($right->colorIndex); // normal color index does not apply, discard\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\tcase 11:\t\t// border color diagonal\r\n\t\t\t\t\t\t$xclfType  = self::_GetInt2d($extData, 0); // color type\r\n\t\t\t\t\t\t$xclrValue = substr($extData, 4, 4); // color value (value based on color type)\r\n\r\n\t\t\t\t\t\tif ($xclfType == 2) {\r\n\t\t\t\t\t\t\t$rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));\r\n\r\n\t\t\t\t\t\t\t// modify the relevant style property\r\n\t\t\t\t\t\t\tif ( isset($this->_mapCellXfIndex[$ixfe]) ) {\r\n\t\t\t\t\t\t\t\t$diagonal = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getBorders()->getDiagonal();\r\n\t\t\t\t\t\t\t\t$diagonal->getColor()->setRGB($rgb);\r\n\t\t\t\t\t\t\t\tunset($diagonal->colorIndex); // normal color index does not apply, discard\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tbreak;\r\n\r\n\t\t\t\t\tcase 13:\t// font color\r\n\t\t\t\t\t\t$xclfType  = self::_GetInt2d($extData, 0); // color type\r\n\t\t\t\t\t\t$xclrValue = substr($extData, 4, 4); // color value (value based on color type)\r\n\r\n\t\t\t\t\t\tif ($xclfType == 2) {\r\n\t\t\t\t\t\t\t$rgb = sprintf('%02X%02X%02X', ord($xclrValue{0}), ord($xclrValue{1}), ord($xclrValue{2}));\r\n\r\n\t\t\t\t\t\t\t// modify the relevant style property\r\n\t\t\t\t\t\t\tif ( isset($this->_mapCellXfIndex[$ixfe]) ) {\r\n\t\t\t\t\t\t\t\t$font = $this->_phpExcel->getCellXfByIndex($this->_mapCellXfIndex[$ixfe])->getFont();\r\n\t\t\t\t\t\t\t\t$font->getColor()->setRGB($rgb);\r\n\t\t\t\t\t\t\t\tunset($font->colorIndex); // normal color index does not apply, discard\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$offset += $cb;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read STYLE record\r\n\t */\r\n\tprivate function _readStyle()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 2; index to XF record and flag for built-in style\r\n\t\t\t$ixfe = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t\t// bit: 11-0; mask 0x0FFF; index to XF record\r\n\t\t\t$xfIndex = (0x0FFF & $ixfe) >> 0;\r\n\r\n\t\t\t// bit: 15; mask 0x8000; 0 = user-defined style, 1 = built-in style\r\n\t\t\t$isBuiltIn = (bool) ((0x8000 & $ixfe) >> 15);\r\n\r\n\t\t\tif ($isBuiltIn) {\r\n\t\t\t\t// offset: 2; size: 1; identifier for built-in style\r\n\t\t\t\t$builtInId = ord($recordData{2});\r\n\r\n\t\t\t\tswitch ($builtInId) {\r\n\t\t\t\tcase 0x00:\r\n\t\t\t\t\t// currently, we are not using this for anything\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tdefault:\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\r\n\t\t\t} else {\r\n\t\t\t\t// user-defined; not supported by PHPExcel\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read PALETTE record\r\n\t */\r\n\tprivate function _readPalette()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 2; number of following colors\r\n\t\t\t$nm = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t\t// list of RGB colors\r\n\t\t\tfor ($i = 0; $i < $nm; ++$i) {\r\n\t\t\t\t$rgb = substr($recordData, 2 + 4 * $i, 4);\r\n\t\t\t\t$this->_palette[] = self::_readRGB($rgb);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * SHEET\r\n\t *\r\n\t * This record is  located in the  Workbook Globals\r\n\t * Substream  and represents a sheet inside the workbook.\r\n\t * One SHEET record is written for each sheet. It stores the\r\n\t * sheet name and a stream offset to the BOF record of the\r\n\t * respective Sheet Substream within the Workbook Stream.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readSheet()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// offset: 0; size: 4; absolute stream position of the BOF record of the sheet\r\n\t\t// NOTE: not encrypted\r\n\t\t$rec_offset = self::_GetInt4d($this->_data, $this->_pos + 4);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 4; size: 1; sheet state\r\n\t\tswitch (ord($recordData{4})) {\r\n\t\t\tcase 0x00: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE;    break;\r\n\t\t\tcase 0x01: $sheetState = PHPExcel_Worksheet::SHEETSTATE_HIDDEN;     break;\r\n\t\t\tcase 0x02: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN; break;\r\n\t\t\tdefault: $sheetState = PHPExcel_Worksheet::SHEETSTATE_VISIBLE;      break;\r\n\t\t}\r\n\r\n\t\t// offset: 5; size: 1; sheet type\r\n\t\t$sheetType = ord($recordData{5});\r\n\r\n\t\t// offset: 6; size: var; sheet name\r\n\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t$string = self::_readUnicodeStringShort(substr($recordData, 6));\r\n\t\t\t$rec_name = $string['value'];\r\n\t\t} elseif ($this->_version == self::XLS_BIFF7) {\r\n\t\t\t$string = $this->_readByteStringShort(substr($recordData, 6));\r\n\t\t\t$rec_name = $string['value'];\r\n\t\t}\r\n\r\n\t\t$this->_sheets[] = array(\r\n\t\t\t'name' => $rec_name,\r\n\t\t\t'offset' => $rec_offset,\r\n\t\t\t'sheetState' => $sheetState,\r\n\t\t\t'sheetType' => $sheetType,\r\n\t\t);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read EXTERNALBOOK record\r\n\t */\r\n\tprivate function _readExternalBook()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset within record data\r\n\t\t$offset = 0;\r\n\r\n\t\t// there are 4 types of records\r\n\t\tif (strlen($recordData) > 4) {\r\n\t\t\t// external reference\r\n\t\t\t// offset: 0; size: 2; number of sheet names ($nm)\r\n\t\t\t$nm = self::_GetInt2d($recordData, 0);\r\n\t\t\t$offset += 2;\r\n\r\n\t\t\t// offset: 2; size: var; encoded URL without sheet name (Unicode string, 16-bit length)\r\n\t\t\t$encodedUrlString = self::_readUnicodeStringLong(substr($recordData, 2));\r\n\t\t\t$offset += $encodedUrlString['size'];\r\n\r\n\t\t\t// offset: var; size: var; list of $nm sheet names (Unicode strings, 16-bit length)\r\n\t\t\t$externalSheetNames = array();\r\n\t\t\tfor ($i = 0; $i < $nm; ++$i) {\r\n\t\t\t\t$externalSheetNameString = self::_readUnicodeStringLong(substr($recordData, $offset));\r\n\t\t\t\t$externalSheetNames[] = $externalSheetNameString['value'];\r\n\t\t\t\t$offset += $externalSheetNameString['size'];\r\n\t\t\t}\r\n\r\n\t\t\t// store the record data\r\n\t\t\t$this->_externalBooks[] = array(\r\n\t\t\t\t'type' => 'external',\r\n\t\t\t\t'encodedUrl' => $encodedUrlString['value'],\r\n\t\t\t\t'externalSheetNames' => $externalSheetNames,\r\n\t\t\t);\r\n\r\n\t\t} elseif (substr($recordData, 2, 2) == pack('CC', 0x01, 0x04)) {\r\n\t\t\t// internal reference\r\n\t\t\t// offset: 0; size: 2; number of sheet in this document\r\n\t\t\t// offset: 2; size: 2; 0x01 0x04\r\n\t\t\t$this->_externalBooks[] = array(\r\n\t\t\t\t'type' => 'internal',\r\n\t\t\t);\r\n\t\t} elseif (substr($recordData, 0, 4) == pack('vCC', 0x0001, 0x01, 0x3A)) {\r\n\t\t\t// add-in function\r\n\t\t\t// offset: 0; size: 2; 0x0001\r\n\t\t\t$this->_externalBooks[] = array(\r\n\t\t\t\t'type' => 'addInFunction',\r\n\t\t\t);\r\n\t\t} elseif (substr($recordData, 0, 2) == pack('v', 0x0000)) {\r\n\t\t\t// DDE links, OLE links\r\n\t\t\t// offset: 0; size: 2; 0x0000\r\n\t\t\t// offset: 2; size: var; encoded source document name\r\n\t\t\t$this->_externalBooks[] = array(\r\n\t\t\t\t'type' => 'DDEorOLE',\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read EXTERNNAME record.\r\n\t */\r\n\tprivate function _readExternName()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// external sheet references provided for named cells\r\n\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t// offset: 0; size: 2; options\r\n\t\t\t$options = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t\t// offset: 2; size: 2;\r\n\r\n\t\t\t// offset: 4; size: 2; not used\r\n\r\n\t\t\t// offset: 6; size: var\r\n\t\t\t$nameString = self::_readUnicodeStringShort(substr($recordData, 6));\r\n\r\n\t\t\t// offset: var; size: var; formula data\r\n\t\t\t$offset = 6 + $nameString['size'];\r\n\t\t\t$formula = $this->_getFormulaFromStructure(substr($recordData, $offset));\r\n\r\n\t\t\t$this->_externalNames[] = array(\r\n\t\t\t\t'name' => $nameString['value'],\r\n\t\t\t\t'formula' => $formula,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read EXTERNSHEET record\r\n\t */\r\n\tprivate function _readExternSheet()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// external sheet references provided for named cells\r\n\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t// offset: 0; size: 2; number of following ref structures\r\n\t\t\t$nm = self::_GetInt2d($recordData, 0);\r\n\t\t\tfor ($i = 0; $i < $nm; ++$i) {\r\n\t\t\t\t$this->_ref[] = array(\r\n\t\t\t\t\t// offset: 2 + 6 * $i; index to EXTERNALBOOK record\r\n\t\t\t\t\t'externalBookIndex' => self::_GetInt2d($recordData, 2 + 6 * $i),\r\n\t\t\t\t\t// offset: 4 + 6 * $i; index to first sheet in EXTERNALBOOK record\r\n\t\t\t\t\t'firstSheetIndex' => self::_GetInt2d($recordData, 4 + 6 * $i),\r\n\t\t\t\t\t// offset: 6 + 6 * $i; index to last sheet in EXTERNALBOOK record\r\n\t\t\t\t\t'lastSheetIndex' => self::_GetInt2d($recordData, 6 + 6 * $i),\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * DEFINEDNAME\r\n\t *\r\n\t * This record is part of a Link Table. It contains the name\r\n\t * and the token array of an internal defined name. Token\r\n\t * arrays of defined names contain tokens with aberrant\r\n\t * token classes.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readDefinedName()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t// retrieves named cells\r\n\r\n\t\t\t// offset: 0; size: 2; option flags\r\n\t\t\t$opts = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t\t\t// bit: 5; mask: 0x0020; 0 = user-defined name, 1 = built-in-name\r\n\t\t\t\t$isBuiltInName = (0x0020 & $opts) >> 5;\r\n\r\n\t\t\t// offset: 2; size: 1; keyboard shortcut\r\n\r\n\t\t\t// offset: 3; size: 1; length of the name (character count)\r\n\t\t\t$nlen = ord($recordData{3});\r\n\r\n\t\t\t// offset: 4; size: 2; size of the formula data (it can happen that this is zero)\r\n\t\t\t// note: there can also be additional data, this is not included in $flen\r\n\t\t\t$flen = self::_GetInt2d($recordData, 4);\r\n\r\n\t\t\t// offset: 8; size: 2; 0=Global name, otherwise index to sheet (1-based)\r\n\t\t\t$scope = self::_GetInt2d($recordData, 8);\r\n\r\n\t\t\t// offset: 14; size: var; Name (Unicode string without length field)\r\n\t\t\t$string = self::_readUnicodeString(substr($recordData, 14), $nlen);\r\n\r\n\t\t\t// offset: var; size: $flen; formula data\r\n\t\t\t$offset = 14 + $string['size'];\r\n\t\t\t$formulaStructure = pack('v', $flen) . substr($recordData, $offset);\r\n\r\n\t\t\ttry {\r\n\t\t\t\t$formula = $this->_getFormulaFromStructure($formulaStructure);\r\n\t\t\t} catch (PHPExcel_Exception $e) {\r\n\t\t\t\t$formula = '';\r\n\t\t\t}\r\n\r\n\t\t\t$this->_definedname[] = array(\r\n\t\t\t\t'isBuiltInName' => $isBuiltInName,\r\n\t\t\t\t'name' => $string['value'],\r\n\t\t\t\t'formula' => $formula,\r\n\t\t\t\t'scope' => $scope,\r\n\t\t\t);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read MSODRAWINGGROUP record\r\n\t */\r\n\tprivate function _readMsoDrawingGroup()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\r\n\t\t// get spliced record data\r\n\t\t$splicedRecordData = $this->_getSplicedRecordData();\r\n\t\t$recordData = $splicedRecordData['recordData'];\r\n\r\n\t\t$this->_drawingGroupData .= $recordData;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * SST - Shared String Table\r\n\t *\r\n\t * This record contains a list of all strings used anywhere\r\n\t * in the workbook. Each string occurs only once. The\r\n\t * workbook uses indexes into the list to reference the\r\n\t * strings.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t **/\r\n\tprivate function _readSst()\r\n\t{\r\n\t\t// offset within (spliced) record data\r\n\t\t$pos = 0;\r\n\r\n\t\t// get spliced record data\r\n\t\t$splicedRecordData = $this->_getSplicedRecordData();\r\n\r\n\t\t$recordData = $splicedRecordData['recordData'];\r\n\t\t$spliceOffsets = $splicedRecordData['spliceOffsets'];\r\n\r\n\t\t// offset: 0; size: 4; total number of strings in the workbook\r\n\t\t$pos += 4;\r\n\r\n\t\t// offset: 4; size: 4; number of following strings ($nm)\r\n\t\t$nm = self::_GetInt4d($recordData, 4);\r\n\t\t$pos += 4;\r\n\r\n\t\t// loop through the Unicode strings (16-bit length)\r\n\t\tfor ($i = 0; $i < $nm; ++$i) {\r\n\r\n\t\t\t// number of characters in the Unicode string\r\n\t\t\t$numChars = self::_GetInt2d($recordData, $pos);\r\n\t\t\t$pos += 2;\r\n\r\n\t\t\t// option flags\r\n\t\t\t$optionFlags = ord($recordData{$pos});\r\n\t\t\t++$pos;\r\n\r\n\t\t\t// bit: 0; mask: 0x01; 0 = compressed; 1 = uncompressed\r\n\t\t\t$isCompressed = (($optionFlags & 0x01) == 0) ;\r\n\r\n\t\t\t// bit: 2; mask: 0x02; 0 = ordinary; 1 = Asian phonetic\r\n\t\t\t$hasAsian = (($optionFlags & 0x04) != 0);\r\n\r\n\t\t\t// bit: 3; mask: 0x03; 0 = ordinary; 1 = Rich-Text\r\n\t\t\t$hasRichText = (($optionFlags & 0x08) != 0);\r\n\r\n\t\t\tif ($hasRichText) {\r\n\t\t\t\t// number of Rich-Text formatting runs\r\n\t\t\t\t$formattingRuns = self::_GetInt2d($recordData, $pos);\r\n\t\t\t\t$pos += 2;\r\n\t\t\t}\r\n\r\n\t\t\tif ($hasAsian) {\r\n\t\t\t\t// size of Asian phonetic setting\r\n\t\t\t\t$extendedRunLength = self::_GetInt4d($recordData, $pos);\r\n\t\t\t\t$pos += 4;\r\n\t\t\t}\r\n\r\n\t\t\t// expected byte length of character array if not split\r\n\t\t\t$len = ($isCompressed) ? $numChars : $numChars * 2;\r\n\r\n\t\t\t// look up limit position\r\n\t\t\tforeach ($spliceOffsets as $spliceOffset) {\r\n\t\t\t\t// it can happen that the string is empty, therefore we need\r\n\t\t\t\t// <= and not just <\r\n\t\t\t\tif ($pos <= $spliceOffset) {\r\n\t\t\t\t\t$limitpos = $spliceOffset;\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\tif ($pos + $len <= $limitpos) {\r\n\t\t\t\t// character array is not split between records\r\n\r\n\t\t\t\t$retstr = substr($recordData, $pos, $len);\r\n\t\t\t\t$pos += $len;\r\n\r\n\t\t\t} else {\r\n\t\t\t\t// character array is split between records\r\n\r\n\t\t\t\t// first part of character array\r\n\t\t\t\t$retstr = substr($recordData, $pos, $limitpos - $pos);\r\n\r\n\t\t\t\t$bytesRead = $limitpos - $pos;\r\n\r\n\t\t\t\t// remaining characters in Unicode string\r\n\t\t\t\t$charsLeft = $numChars - (($isCompressed) ? $bytesRead : ($bytesRead / 2));\r\n\r\n\t\t\t\t$pos = $limitpos;\r\n\r\n\t\t\t\t// keep reading the characters\r\n\t\t\t\twhile ($charsLeft > 0) {\r\n\r\n\t\t\t\t\t// look up next limit position, in case the string span more than one continue record\r\n\t\t\t\t\tforeach ($spliceOffsets as $spliceOffset) {\r\n\t\t\t\t\t\tif ($pos < $spliceOffset) {\r\n\t\t\t\t\t\t\t$limitpos = $spliceOffset;\r\n\t\t\t\t\t\t\tbreak;\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// repeated option flags\r\n\t\t\t\t\t// OpenOffice.org documentation 5.21\r\n\t\t\t\t\t$option = ord($recordData{$pos});\r\n\t\t\t\t\t++$pos;\r\n\r\n\t\t\t\t\tif ($isCompressed && ($option == 0)) {\r\n\t\t\t\t\t\t// 1st fragment compressed\r\n\t\t\t\t\t\t// this fragment compressed\r\n\t\t\t\t\t\t$len = min($charsLeft, $limitpos - $pos);\r\n\t\t\t\t\t\t$retstr .= substr($recordData, $pos, $len);\r\n\t\t\t\t\t\t$charsLeft -= $len;\r\n\t\t\t\t\t\t$isCompressed = true;\r\n\r\n\t\t\t\t\t} elseif (!$isCompressed && ($option != 0)) {\r\n\t\t\t\t\t\t// 1st fragment uncompressed\r\n\t\t\t\t\t\t// this fragment uncompressed\r\n\t\t\t\t\t\t$len = min($charsLeft * 2, $limitpos - $pos);\r\n\t\t\t\t\t\t$retstr .= substr($recordData, $pos, $len);\r\n\t\t\t\t\t\t$charsLeft -= $len / 2;\r\n\t\t\t\t\t\t$isCompressed = false;\r\n\r\n\t\t\t\t\t} elseif (!$isCompressed && ($option == 0)) {\r\n\t\t\t\t\t\t// 1st fragment uncompressed\r\n\t\t\t\t\t\t// this fragment compressed\r\n\t\t\t\t\t\t$len = min($charsLeft, $limitpos - $pos);\r\n\t\t\t\t\t\tfor ($j = 0; $j < $len; ++$j) {\r\n\t\t\t\t\t\t\t$retstr .= $recordData{$pos + $j} . chr(0);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t$charsLeft -= $len;\r\n\t\t\t\t\t\t$isCompressed = false;\r\n\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t// 1st fragment compressed\r\n\t\t\t\t\t\t// this fragment uncompressed\r\n\t\t\t\t\t\t$newstr = '';\r\n\t\t\t\t\t\tfor ($j = 0; $j < strlen($retstr); ++$j) {\r\n\t\t\t\t\t\t\t$newstr .= $retstr[$j] . chr(0);\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t\t$retstr = $newstr;\r\n\t\t\t\t\t\t$len = min($charsLeft * 2, $limitpos - $pos);\r\n\t\t\t\t\t\t$retstr .= substr($recordData, $pos, $len);\r\n\t\t\t\t\t\t$charsLeft -= $len / 2;\r\n\t\t\t\t\t\t$isCompressed = false;\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t$pos += $len;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// convert to UTF-8\r\n\t\t\t$retstr = self::_encodeUTF16($retstr, $isCompressed);\r\n\r\n\t\t\t// read additional Rich-Text information, if any\r\n\t\t\t$fmtRuns = array();\r\n\t\t\tif ($hasRichText) {\r\n\t\t\t\t// list of formatting runs\r\n\t\t\t\tfor ($j = 0; $j < $formattingRuns; ++$j) {\r\n\t\t\t\t\t// first formatted character; zero-based\r\n\t\t\t\t\t$charPos = self::_GetInt2d($recordData, $pos + $j * 4);\r\n\r\n\t\t\t\t\t// index to font record\r\n\t\t\t\t\t$fontIndex = self::_GetInt2d($recordData, $pos + 2 + $j * 4);\r\n\r\n\t\t\t\t\t$fmtRuns[] = array(\r\n\t\t\t\t\t\t'charPos' => $charPos,\r\n\t\t\t\t\t\t'fontIndex' => $fontIndex,\r\n\t\t\t\t\t);\r\n\t\t\t\t}\r\n\t\t\t\t$pos += 4 * $formattingRuns;\r\n\t\t\t}\r\n\r\n\t\t\t// read additional Asian phonetics information, if any\r\n\t\t\tif ($hasAsian) {\r\n\t\t\t\t// For Asian phonetic settings, we skip the extended string data\r\n\t\t\t\t$pos += $extendedRunLength;\r\n\t\t\t}\r\n\r\n\t\t\t// store the shared sting\r\n\t\t\t$this->_sst[] = array(\r\n\t\t\t\t'value' => $retstr,\r\n\t\t\t\t'fmtRuns' => $fmtRuns,\r\n\t\t\t);\r\n\t\t}\r\n\r\n\t\t// _getSplicedRecordData() takes care of moving current position in data stream\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read PRINTGRIDLINES record\r\n\t */\r\n\tprivate function _readPrintGridlines()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 2; 0 = do not print sheet grid lines; 1 = print sheet gridlines\r\n\t\t\t$printGridlines = (bool) self::_GetInt2d($recordData, 0);\r\n\t\t\t$this->_phpSheet->setPrintGridlines($printGridlines);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read DEFAULTROWHEIGHT record\r\n\t */\r\n\tprivate function _readDefaultRowHeight()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; option flags\r\n\t\t// offset: 2; size: 2; default height for unused rows, (twips 1/20 point)\r\n\t\t$height = self::_GetInt2d($recordData, 2);\r\n\t\t$this->_phpSheet->getDefaultRowDimension()->setRowHeight($height / 20);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read SHEETPR record\r\n\t */\r\n\tprivate function _readSheetPr()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2\r\n\r\n\t\t// bit: 6; mask: 0x0040; 0 = outline buttons above outline group\r\n\t\t$isSummaryBelow = (0x0040 & self::_GetInt2d($recordData, 0)) >> 6;\r\n\t\t$this->_phpSheet->setShowSummaryBelow($isSummaryBelow);\r\n\r\n\t\t// bit: 7; mask: 0x0080; 0 = outline buttons left of outline group\r\n\t\t$isSummaryRight = (0x0080 & self::_GetInt2d($recordData, 0)) >> 7;\r\n\t\t$this->_phpSheet->setShowSummaryRight($isSummaryRight);\r\n\r\n\t\t// bit: 8; mask: 0x100; 0 = scale printout in percent, 1 = fit printout to number of pages\r\n\t\t// this corresponds to radio button setting in page setup dialog in Excel\r\n\t\t$this->_isFitToPages = (bool) ((0x0100 & self::_GetInt2d($recordData, 0)) >> 8);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read HORIZONTALPAGEBREAKS record\r\n\t */\r\n\tprivate function _readHorizontalPageBreaks()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) {\r\n\r\n\t\t\t// offset: 0; size: 2; number of the following row index structures\r\n\t\t\t$nm = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t\t// offset: 2; size: 6 * $nm; list of $nm row index structures\r\n\t\t\tfor ($i = 0; $i < $nm; ++$i) {\r\n\t\t\t\t$r = self::_GetInt2d($recordData, 2 + 6 * $i);\r\n\t\t\t\t$cf = self::_GetInt2d($recordData, 2 + 6 * $i + 2);\r\n\t\t\t\t$cl = self::_GetInt2d($recordData, 2 + 6 * $i + 4);\r\n\r\n\t\t\t\t// not sure why two column indexes are necessary?\r\n\t\t\t\t$this->_phpSheet->setBreakByColumnAndRow($cf, $r, PHPExcel_Worksheet::BREAK_ROW);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read VERTICALPAGEBREAKS record\r\n\t */\r\n\tprivate function _readVerticalPageBreaks()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 2; number of the following column index structures\r\n\t\t\t$nm = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t\t// offset: 2; size: 6 * $nm; list of $nm row index structures\r\n\t\t\tfor ($i = 0; $i < $nm; ++$i) {\r\n\t\t\t\t$c = self::_GetInt2d($recordData, 2 + 6 * $i);\r\n\t\t\t\t$rf = self::_GetInt2d($recordData, 2 + 6 * $i + 2);\r\n\t\t\t\t$rl = self::_GetInt2d($recordData, 2 + 6 * $i + 4);\r\n\r\n\t\t\t\t// not sure why two row indexes are necessary?\r\n\t\t\t\t$this->_phpSheet->setBreakByColumnAndRow($c, $rf, PHPExcel_Worksheet::BREAK_COLUMN);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read HEADER record\r\n\t */\r\n\tprivate function _readHeader()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: var\r\n\t\t\t// realized that $recordData can be empty even when record exists\r\n\t\t\tif ($recordData) {\r\n\t\t\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t\t\t$string = self::_readUnicodeStringLong($recordData);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t$string = $this->_readByteStringShort($recordData);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$this->_phpSheet->getHeaderFooter()->setOddHeader($string['value']);\r\n\t\t\t\t$this->_phpSheet->getHeaderFooter()->setEvenHeader($string['value']);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read FOOTER record\r\n\t */\r\n\tprivate function _readFooter()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: var\r\n\t\t\t// realized that $recordData can be empty even when record exists\r\n\t\t\tif ($recordData) {\r\n\t\t\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t\t\t$string = self::_readUnicodeStringLong($recordData);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t$string = $this->_readByteStringShort($recordData);\r\n\t\t\t\t}\r\n\t\t\t\t$this->_phpSheet->getHeaderFooter()->setOddFooter($string['value']);\r\n\t\t\t\t$this->_phpSheet->getHeaderFooter()->setEvenFooter($string['value']);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read HCENTER record\r\n\t */\r\n\tprivate function _readHcenter()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 2; 0 = print sheet left aligned, 1 = print sheet centered horizontally\r\n\t\t\t$isHorizontalCentered = (bool) self::_GetInt2d($recordData, 0);\r\n\r\n\t\t\t$this->_phpSheet->getPageSetup()->setHorizontalCentered($isHorizontalCentered);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read VCENTER record\r\n\t */\r\n\tprivate function _readVcenter()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 2; 0 = print sheet aligned at top page border, 1 = print sheet vertically centered\r\n\t\t\t$isVerticalCentered = (bool) self::_GetInt2d($recordData, 0);\r\n\r\n\t\t\t$this->_phpSheet->getPageSetup()->setVerticalCentered($isVerticalCentered);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read LEFTMARGIN record\r\n\t */\r\n\tprivate function _readLeftMargin()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 8\r\n\t\t\t$this->_phpSheet->getPageMargins()->setLeft(self::_extractNumber($recordData));\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read RIGHTMARGIN record\r\n\t */\r\n\tprivate function _readRightMargin()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 8\r\n\t\t\t$this->_phpSheet->getPageMargins()->setRight(self::_extractNumber($recordData));\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read TOPMARGIN record\r\n\t */\r\n\tprivate function _readTopMargin()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 8\r\n\t\t\t$this->_phpSheet->getPageMargins()->setTop(self::_extractNumber($recordData));\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read BOTTOMMARGIN record\r\n\t */\r\n\tprivate function _readBottomMargin()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 8\r\n\t\t\t$this->_phpSheet->getPageMargins()->setBottom(self::_extractNumber($recordData));\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read PAGESETUP record\r\n\t */\r\n\tprivate function _readPageSetup()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 2; paper size\r\n\t\t\t$paperSize = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t\t// offset: 2; size: 2; scaling factor\r\n\t\t\t$scale = self::_GetInt2d($recordData, 2);\r\n\r\n\t\t\t// offset: 6; size: 2; fit worksheet width to this number of pages, 0 = use as many as needed\r\n\t\t\t$fitToWidth = self::_GetInt2d($recordData, 6);\r\n\r\n\t\t\t// offset: 8; size: 2; fit worksheet height to this number of pages, 0 = use as many as needed\r\n\t\t\t$fitToHeight = self::_GetInt2d($recordData, 8);\r\n\r\n\t\t\t// offset: 10; size: 2; option flags\r\n\r\n\t\t\t\t// bit: 1; mask: 0x0002; 0=landscape, 1=portrait\r\n\t\t\t\t$isPortrait = (0x0002 & self::_GetInt2d($recordData, 10)) >> 1;\r\n\r\n\t\t\t\t// bit: 2; mask: 0x0004; 1= paper size, scaling factor, paper orient. not init\r\n\t\t\t\t// when this bit is set, do not use flags for those properties\r\n\t\t\t\t$isNotInit = (0x0004 & self::_GetInt2d($recordData, 10)) >> 2;\r\n\r\n\t\t\tif (!$isNotInit) {\r\n\t\t\t\t$this->_phpSheet->getPageSetup()->setPaperSize($paperSize);\r\n\t\t\t\tswitch ($isPortrait) {\r\n\t\t\t\tcase 0: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE); break;\r\n\t\t\t\tcase 1: $this->_phpSheet->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT); break;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t$this->_phpSheet->getPageSetup()->setScale($scale, false);\r\n\t\t\t\t$this->_phpSheet->getPageSetup()->setFitToPage((bool) $this->_isFitToPages);\r\n\t\t\t\t$this->_phpSheet->getPageSetup()->setFitToWidth($fitToWidth, false);\r\n\t\t\t\t$this->_phpSheet->getPageSetup()->setFitToHeight($fitToHeight, false);\r\n\t\t\t}\r\n\r\n\t\t\t// offset: 16; size: 8; header margin (IEEE 754 floating-point value)\r\n\t\t\t$marginHeader = self::_extractNumber(substr($recordData, 16, 8));\r\n\t\t\t$this->_phpSheet->getPageMargins()->setHeader($marginHeader);\r\n\r\n\t\t\t// offset: 24; size: 8; footer margin (IEEE 754 floating-point value)\r\n\t\t\t$marginFooter = self::_extractNumber(substr($recordData, 24, 8));\r\n\t\t\t$this->_phpSheet->getPageMargins()->setFooter($marginFooter);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * PROTECT - Sheet protection (BIFF2 through BIFF8)\r\n\t *   if this record is omitted, then it also means no sheet protection\r\n\t */\r\n\tprivate function _readProtect()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_readDataOnly) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// offset: 0; size: 2;\r\n\r\n\t\t// bit 0, mask 0x01; 1 = sheet is protected\r\n\t\t$bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0;\r\n\t\t$this->_phpSheet->getProtection()->setSheet((bool)$bool);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * SCENPROTECT\r\n\t */\r\n\tprivate function _readScenProtect()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_readDataOnly) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// offset: 0; size: 2;\r\n\r\n\t\t// bit: 0, mask 0x01; 1 = scenarios are protected\r\n\t\t$bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0;\r\n\r\n\t\t$this->_phpSheet->getProtection()->setScenarios((bool)$bool);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * OBJECTPROTECT\r\n\t */\r\n\tprivate function _readObjectProtect()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_readDataOnly) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// offset: 0; size: 2;\r\n\r\n\t\t// bit: 0, mask 0x01; 1 = objects are protected\r\n\t\t$bool = (0x01 & self::_GetInt2d($recordData, 0)) >> 0;\r\n\r\n\t\t$this->_phpSheet->getProtection()->setObjects((bool)$bool);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * PASSWORD - Sheet protection (hashed) password (BIFF2 through BIFF8)\r\n\t */\r\n\tprivate function _readPassword()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 2; 16-bit hash value of password\r\n\t\t\t$password = strtoupper(dechex(self::_GetInt2d($recordData, 0))); // the hashed password\r\n\t\t\t$this->_phpSheet->getProtection()->setPassword($password, true);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read DEFCOLWIDTH record\r\n\t */\r\n\tprivate function _readDefColWidth()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; default column width\r\n\t\t$width = self::_GetInt2d($recordData, 0);\r\n\t\tif ($width != 8) {\r\n\t\t\t$this->_phpSheet->getDefaultColumnDimension()->setWidth($width);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read COLINFO record\r\n\t */\r\n\tprivate function _readColInfo()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 2; index to first column in range\r\n\t\t\t$fc = self::_GetInt2d($recordData, 0); // first column index\r\n\r\n\t\t\t// offset: 2; size: 2; index to last column in range\r\n\t\t\t$lc = self::_GetInt2d($recordData, 2); // first column index\r\n\r\n\t\t\t// offset: 4; size: 2; width of the column in 1/256 of the width of the zero character\r\n\t\t\t$width = self::_GetInt2d($recordData, 4);\r\n\r\n\t\t\t// offset: 6; size: 2; index to XF record for default column formatting\r\n\t\t\t$xfIndex = self::_GetInt2d($recordData, 6);\r\n\r\n\t\t\t// offset: 8; size: 2; option flags\r\n\r\n\t\t\t\t// bit: 0; mask: 0x0001; 1= columns are hidden\r\n\t\t\t\t$isHidden = (0x0001 & self::_GetInt2d($recordData, 8)) >> 0;\r\n\r\n\t\t\t\t// bit: 10-8; mask: 0x0700; outline level of the columns (0 = no outline)\r\n\t\t\t\t$level = (0x0700 & self::_GetInt2d($recordData, 8)) >> 8;\r\n\r\n\t\t\t\t// bit: 12; mask: 0x1000; 1 = collapsed\r\n\t\t\t\t$isCollapsed = (0x1000 & self::_GetInt2d($recordData, 8)) >> 12;\r\n\r\n\t\t\t// offset: 10; size: 2; not used\r\n\r\n\t\t\tfor ($i = $fc; $i <= $lc; ++$i) {\r\n\t\t\t\tif ($lc == 255 || $lc == 256) {\r\n\t\t\t\t\t$this->_phpSheet->getDefaultColumnDimension()->setWidth($width / 256);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\t$this->_phpSheet->getColumnDimensionByColumn($i)->setWidth($width / 256);\r\n\t\t\t\t$this->_phpSheet->getColumnDimensionByColumn($i)->setVisible(!$isHidden);\r\n\t\t\t\t$this->_phpSheet->getColumnDimensionByColumn($i)->setOutlineLevel($level);\r\n\t\t\t\t$this->_phpSheet->getColumnDimensionByColumn($i)->setCollapsed($isCollapsed);\r\n\t\t\t\t$this->_phpSheet->getColumnDimensionByColumn($i)->setXfIndex($this->_mapCellXfIndex[$xfIndex]);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * ROW\r\n\t *\r\n\t * This record contains the properties of a single row in a\r\n\t * sheet. Rows and cells in a sheet are divided into blocks\r\n\t * of 32 rows.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readRow()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 2; index of this row\r\n\t\t\t$r = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t\t// offset: 2; size: 2; index to column of the first cell which is described by a cell record\r\n\r\n\t\t\t// offset: 4; size: 2; index to column of the last cell which is described by a cell record, increased by 1\r\n\r\n\t\t\t// offset: 6; size: 2;\r\n\r\n\t\t\t// bit: 14-0; mask: 0x7FFF; height of the row, in twips = 1/20 of a point\r\n\t\t\t$height = (0x7FFF & self::_GetInt2d($recordData, 6)) >> 0;\r\n\r\n\t\t\t// bit: 15: mask: 0x8000; 0 = row has custom height; 1= row has default height\r\n\t\t\t$useDefaultHeight = (0x8000 & self::_GetInt2d($recordData, 6)) >> 15;\r\n\r\n\t\t\tif (!$useDefaultHeight) {\r\n\t\t\t\t$this->_phpSheet->getRowDimension($r + 1)->setRowHeight($height / 20);\r\n\t\t\t}\r\n\r\n\t\t\t// offset: 8; size: 2; not used\r\n\r\n\t\t\t// offset: 10; size: 2; not used in BIFF5-BIFF8\r\n\r\n\t\t\t// offset: 12; size: 4; option flags and default row formatting\r\n\r\n\t\t\t// bit: 2-0: mask: 0x00000007; outline level of the row\r\n\t\t\t$level = (0x00000007 & self::_GetInt4d($recordData, 12)) >> 0;\r\n\t\t\t$this->_phpSheet->getRowDimension($r + 1)->setOutlineLevel($level);\r\n\r\n\t\t\t// bit: 4; mask: 0x00000010; 1 = outline group start or ends here... and is collapsed\r\n\t\t\t$isCollapsed = (0x00000010 & self::_GetInt4d($recordData, 12)) >> 4;\r\n\t\t\t$this->_phpSheet->getRowDimension($r + 1)->setCollapsed($isCollapsed);\r\n\r\n\t\t\t// bit: 5; mask: 0x00000020; 1 = row is hidden\r\n\t\t\t$isHidden = (0x00000020 & self::_GetInt4d($recordData, 12)) >> 5;\r\n\t\t\t$this->_phpSheet->getRowDimension($r + 1)->setVisible(!$isHidden);\r\n\r\n\t\t\t// bit: 7; mask: 0x00000080; 1 = row has explicit format\r\n\t\t\t$hasExplicitFormat = (0x00000080 & self::_GetInt4d($recordData, 12)) >> 7;\r\n\r\n\t\t\t// bit: 27-16; mask: 0x0FFF0000; only applies when hasExplicitFormat = 1; index to XF record\r\n\t\t\t$xfIndex = (0x0FFF0000 & self::_GetInt4d($recordData, 12)) >> 16;\r\n\r\n\t\t\tif ($hasExplicitFormat) {\r\n\t\t\t\t$this->_phpSheet->getRowDimension($r + 1)->setXfIndex($this->_mapCellXfIndex[$xfIndex]);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read RK record\r\n\t * This record represents a cell that contains an RK value\r\n\t * (encoded integer or floating-point value). If a\r\n\t * floating-point value cannot be encoded to an RK value,\r\n\t * a NUMBER record will be written. This record replaces the\r\n\t * record INTEGER written in BIFF2.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readRk()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; index to row\r\n\t\t$row = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t// offset: 2; size: 2; index to column\r\n\t\t$column = self::_GetInt2d($recordData, 2);\r\n\t\t$columnString = PHPExcel_Cell::stringFromColumnIndex($column);\r\n\r\n\t\t// Read cell?\r\n\t\tif (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {\r\n\t\t\t// offset: 4; size: 2; index to XF record\r\n\t\t\t$xfIndex = self::_GetInt2d($recordData, 4);\r\n\r\n\t\t\t// offset: 6; size: 4; RK value\r\n\t\t\t$rknum = self::_GetInt4d($recordData, 6);\r\n\t\t\t$numValue = self::_GetIEEE754($rknum);\r\n\r\n\t\t\t$cell = $this->_phpSheet->getCell($columnString . ($row + 1));\r\n\t\t\tif (!$this->_readDataOnly) {\r\n\t\t\t\t// add style information\r\n\t\t\t\t$cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);\r\n\t\t\t}\r\n\r\n\t\t\t// add cell\r\n\t\t\t$cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read LABELSST record\r\n\t * This record represents a cell that contains a string. It\r\n\t * replaces the LABEL record and RSTRING record used in\r\n\t * BIFF2-BIFF5.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readLabelSst()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; index to row\r\n\t\t$row = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t// offset: 2; size: 2; index to column\r\n\t\t$column = self::_GetInt2d($recordData, 2);\r\n\t\t$columnString = PHPExcel_Cell::stringFromColumnIndex($column);\r\n\r\n\t\t// Read cell?\r\n\t\tif (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {\r\n\t\t\t// offset: 4; size: 2; index to XF record\r\n\t\t\t$xfIndex = self::_GetInt2d($recordData, 4);\r\n\r\n\t\t\t// offset: 6; size: 4; index to SST record\r\n\t\t\t$index = self::_GetInt4d($recordData, 6);\r\n\r\n\t\t\t// add cell\r\n\t\t\tif (($fmtRuns = $this->_sst[$index]['fmtRuns']) && !$this->_readDataOnly) {\r\n\t\t\t\t// then we should treat as rich text\r\n\t\t\t\t$richText = new PHPExcel_RichText();\r\n\t\t\t\t$charPos = 0;\r\n\t\t\t\t$sstCount = count($this->_sst[$index]['fmtRuns']);\r\n\t\t\t\tfor ($i = 0; $i <= $sstCount; ++$i) {\r\n\t\t\t\t\tif (isset($fmtRuns[$i])) {\r\n\t\t\t\t\t\t$text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, $fmtRuns[$i]['charPos'] - $charPos);\r\n\t\t\t\t\t\t$charPos = $fmtRuns[$i]['charPos'];\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t$text = PHPExcel_Shared_String::Substring($this->_sst[$index]['value'], $charPos, PHPExcel_Shared_String::CountCharacters($this->_sst[$index]['value']));\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\tif (PHPExcel_Shared_String::CountCharacters($text) > 0) {\r\n\t\t\t\t\t\tif ($i == 0) { // first text run, no style\r\n\t\t\t\t\t\t\t$richText->createText($text);\r\n\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t$textRun = $richText->createTextRun($text);\r\n\t\t\t\t\t\t\tif (isset($fmtRuns[$i - 1])) {\r\n\t\t\t\t\t\t\t\tif ($fmtRuns[$i - 1]['fontIndex'] < 4) {\r\n\t\t\t\t\t\t\t\t\t$fontIndex = $fmtRuns[$i - 1]['fontIndex'];\r\n\t\t\t\t\t\t\t\t} else {\r\n\t\t\t\t\t\t\t\t\t// this has to do with that index 4 is omitted in all BIFF versions for some strange reason\r\n\t\t\t\t\t\t\t\t\t// check the OpenOffice documentation of the FONT record\r\n\t\t\t\t\t\t\t\t\t$fontIndex = $fmtRuns[$i - 1]['fontIndex'] - 1;\r\n\t\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t\t\t$textRun->setFont(clone $this->_objFonts[$fontIndex]);\r\n\t\t\t\t\t\t\t}\r\n\t\t\t\t\t\t}\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t\t$cell = $this->_phpSheet->getCell($columnString . ($row + 1));\r\n\t\t\t\t$cell->setValueExplicit($richText, PHPExcel_Cell_DataType::TYPE_STRING);\r\n\t\t\t} else {\r\n\t\t\t\t$cell = $this->_phpSheet->getCell($columnString . ($row + 1));\r\n\t\t\t\t$cell->setValueExplicit($this->_sst[$index]['value'], PHPExcel_Cell_DataType::TYPE_STRING);\r\n\t\t\t}\r\n\r\n\t\t\tif (!$this->_readDataOnly) {\r\n\t\t\t\t// add style information\r\n\t\t\t\t$cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read MULRK record\r\n\t * This record represents a cell range containing RK value\r\n\t * cells. All cells are located in the same row.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readMulRk()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; index to row\r\n\t\t$row = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t// offset: 2; size: 2; index to first column\r\n\t\t$colFirst = self::_GetInt2d($recordData, 2);\r\n\r\n\t\t// offset: var; size: 2; index to last column\r\n\t\t$colLast = self::_GetInt2d($recordData, $length - 2);\r\n\t\t$columns = $colLast - $colFirst + 1;\r\n\r\n\t\t// offset within record data\r\n\t\t$offset = 4;\r\n\r\n\t\tfor ($i = 0; $i < $columns; ++$i) {\r\n\t\t\t$columnString = PHPExcel_Cell::stringFromColumnIndex($colFirst + $i);\r\n\r\n\t\t\t// Read cell?\r\n\t\t\tif (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {\r\n\r\n\t\t\t\t// offset: var; size: 2; index to XF record\r\n\t\t\t\t$xfIndex = self::_GetInt2d($recordData, $offset);\r\n\r\n\t\t\t\t// offset: var; size: 4; RK value\r\n\t\t\t\t$numValue = self::_GetIEEE754(self::_GetInt4d($recordData, $offset + 2));\r\n\t\t\t\t$cell = $this->_phpSheet->getCell($columnString . ($row + 1));\r\n\t\t\t\tif (!$this->_readDataOnly) {\r\n\t\t\t\t\t// add style\r\n\t\t\t\t\t$cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// add cell value\r\n\t\t\t\t$cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC);\r\n\t\t\t}\r\n\r\n\t\t\t$offset += 6;\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read NUMBER record\r\n\t * This record represents a cell that contains a\r\n\t * floating-point value.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readNumber()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; index to row\r\n\t\t$row = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t// offset: 2; size 2; index to column\r\n\t\t$column = self::_GetInt2d($recordData, 2);\r\n\t\t$columnString = PHPExcel_Cell::stringFromColumnIndex($column);\r\n\r\n\t\t// Read cell?\r\n\t\tif (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {\r\n\t\t\t// offset 4; size: 2; index to XF record\r\n\t\t\t$xfIndex = self::_GetInt2d($recordData, 4);\r\n\r\n\t\t\t$numValue = self::_extractNumber(substr($recordData, 6, 8));\r\n\r\n\t\t\t$cell = $this->_phpSheet->getCell($columnString . ($row + 1));\r\n\t\t\tif (!$this->_readDataOnly) {\r\n\t\t\t\t// add cell style\r\n\t\t\t\t$cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);\r\n\t\t\t}\r\n\r\n\t\t\t// add cell value\r\n\t\t\t$cell->setValueExplicit($numValue, PHPExcel_Cell_DataType::TYPE_NUMERIC);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read FORMULA record + perhaps a following STRING record if formula result is a string\r\n\t * This record contains the token array and the result of a\r\n\t * formula cell.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readFormula()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; row index\r\n\t\t$row = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t// offset: 2; size: 2; col index\r\n\t\t$column = self::_GetInt2d($recordData, 2);\r\n\t\t$columnString = PHPExcel_Cell::stringFromColumnIndex($column);\r\n\r\n\t\t// offset: 20: size: variable; formula structure\r\n\t\t$formulaStructure = substr($recordData, 20);\r\n\r\n\t\t// offset: 14: size: 2; option flags, recalculate always, recalculate on open etc.\r\n\t\t$options = self::_GetInt2d($recordData, 14);\r\n\r\n\t\t// bit: 0; mask: 0x0001; 1 = recalculate always\r\n\t\t// bit: 1; mask: 0x0002; 1 = calculate on open\r\n\t\t// bit: 2; mask: 0x0008; 1 = part of a shared formula\r\n\t\t$isPartOfSharedFormula = (bool) (0x0008 & $options);\r\n\r\n\t\t// WARNING:\r\n\t\t// We can apparently not rely on $isPartOfSharedFormula. Even when $isPartOfSharedFormula = true\r\n\t\t// the formula data may be ordinary formula data, therefore we need to check\r\n\t\t// explicitly for the tExp token (0x01)\r\n\t\t$isPartOfSharedFormula = $isPartOfSharedFormula && ord($formulaStructure{2}) == 0x01;\r\n\r\n\t\tif ($isPartOfSharedFormula) {\r\n\t\t\t// part of shared formula which means there will be a formula with a tExp token and nothing else\r\n\t\t\t// get the base cell, grab tExp token\r\n\t\t\t$baseRow = self::_GetInt2d($formulaStructure, 3);\r\n\t\t\t$baseCol = self::_GetInt2d($formulaStructure, 5);\r\n\t\t\t$this->_baseCell = PHPExcel_Cell::stringFromColumnIndex($baseCol). ($baseRow + 1);\r\n\t\t}\r\n\r\n\t\t// Read cell?\r\n\t\tif (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {\r\n\r\n\t\t\tif ($isPartOfSharedFormula) {\r\n\t\t\t\t// formula is added to this cell after the sheet has been read\r\n\t\t\t\t$this->_sharedFormulaParts[$columnString . ($row + 1)] = $this->_baseCell;\r\n\t\t\t}\r\n\r\n\t\t\t// offset: 16: size: 4; not used\r\n\r\n\t\t\t// offset: 4; size: 2; XF index\r\n\t\t\t$xfIndex = self::_GetInt2d($recordData, 4);\r\n\r\n\t\t\t// offset: 6; size: 8; result of the formula\r\n\t\t\tif ( (ord($recordData{6}) == 0)\r\n\t\t\t\t&& (ord($recordData{12}) == 255)\r\n\t\t\t\t&& (ord($recordData{13}) == 255) ) {\r\n\r\n\t\t\t\t// String formula. Result follows in appended STRING record\r\n\t\t\t\t$dataType = PHPExcel_Cell_DataType::TYPE_STRING;\r\n\r\n\t\t\t\t// read possible SHAREDFMLA record\r\n\t\t\t\t$code = self::_GetInt2d($this->_data, $this->_pos);\r\n\t\t\t\tif ($code == self::XLS_Type_SHAREDFMLA) {\r\n\t\t\t\t\t$this->_readSharedFmla();\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// read STRING record\r\n\t\t\t\t$value = $this->_readString();\r\n\r\n\t\t\t} elseif ((ord($recordData{6}) == 1)\r\n\t\t\t\t&& (ord($recordData{12}) == 255)\r\n\t\t\t\t&& (ord($recordData{13}) == 255)) {\r\n\r\n\t\t\t\t// Boolean formula. Result is in +2; 0=false, 1=true\r\n\t\t\t\t$dataType = PHPExcel_Cell_DataType::TYPE_BOOL;\r\n\t\t\t\t$value = (bool) ord($recordData{8});\r\n\r\n\t\t\t} elseif ((ord($recordData{6}) == 2)\r\n\t\t\t\t&& (ord($recordData{12}) == 255)\r\n\t\t\t\t&& (ord($recordData{13}) == 255)) {\r\n\r\n\t\t\t\t// Error formula. Error code is in +2\r\n\t\t\t\t$dataType = PHPExcel_Cell_DataType::TYPE_ERROR;\r\n\t\t\t\t$value = self::_mapErrorCode(ord($recordData{8}));\r\n\r\n\t\t\t} elseif ((ord($recordData{6}) == 3)\r\n\t\t\t\t&& (ord($recordData{12}) == 255)\r\n\t\t\t\t&& (ord($recordData{13}) == 255)) {\r\n\r\n\t\t\t\t// Formula result is a null string\r\n\t\t\t\t$dataType = PHPExcel_Cell_DataType::TYPE_NULL;\r\n\t\t\t\t$value = '';\r\n\r\n\t\t\t} else {\r\n\r\n\t\t\t\t// forumla result is a number, first 14 bytes like _NUMBER record\r\n\t\t\t\t$dataType = PHPExcel_Cell_DataType::TYPE_NUMERIC;\r\n\t\t\t\t$value = self::_extractNumber(substr($recordData, 6, 8));\r\n\r\n\t\t\t}\r\n\r\n\t\t\t$cell = $this->_phpSheet->getCell($columnString . ($row + 1));\r\n\t\t\tif (!$this->_readDataOnly) {\r\n\t\t\t\t// add cell style\r\n\t\t\t\t$cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);\r\n\t\t\t}\r\n\r\n\t\t\t// store the formula\r\n\t\t\tif (!$isPartOfSharedFormula) {\r\n\t\t\t\t// not part of shared formula\r\n\t\t\t\t// add cell value. If we can read formula, populate with formula, otherwise just used cached value\r\n\t\t\t\ttry {\r\n\t\t\t\t\tif ($this->_version != self::XLS_BIFF8) {\r\n\t\t\t\t\t\tthrow new PHPExcel_Reader_Exception('Not BIFF8. Can only read BIFF8 formulas');\r\n\t\t\t\t\t}\r\n\t\t\t\t\t$formula = $this->_getFormulaFromStructure($formulaStructure); // get formula in human language\r\n\t\t\t\t\t$cell->setValueExplicit('=' . $formula, PHPExcel_Cell_DataType::TYPE_FORMULA);\r\n\r\n\t\t\t\t} catch (PHPExcel_Exception $e) {\r\n\t\t\t\t\t$cell->setValueExplicit($value, $dataType);\r\n\t\t\t\t}\r\n\t\t\t} else {\r\n\t\t\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t\t\t// do nothing at this point, formula id added later in the code\r\n\t\t\t\t} else {\r\n\t\t\t\t\t$cell->setValueExplicit($value, $dataType);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\r\n\t\t\t// store the cached calculated value\r\n\t\t\t$cell->setCalculatedValue($value);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read a SHAREDFMLA record. This function just stores the binary shared formula in the reader,\r\n\t * which usually contains relative references.\r\n\t * These will be used to construct the formula in each shared formula part after the sheet is read.\r\n\t */\r\n\tprivate function _readSharedFmla()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0, size: 6; cell range address of the area used by the shared formula, not used for anything\r\n\t\t$cellRange = substr($recordData, 0, 6);\r\n\t\t$cellRange = $this->_readBIFF5CellRangeAddressFixed($cellRange); // note: even BIFF8 uses BIFF5 syntax\r\n\r\n\t\t// offset: 6, size: 1; not used\r\n\r\n\t\t// offset: 7, size: 1; number of existing FORMULA records for this shared formula\r\n\t\t$no = ord($recordData{7});\r\n\r\n\t\t// offset: 8, size: var; Binary token array of the shared formula\r\n\t\t$formula = substr($recordData, 8);\r\n\r\n\t\t// at this point we only store the shared formula for later use\r\n\t\t$this->_sharedFormulas[$this->_baseCell] = $formula;\r\n\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read a STRING record from current stream position and advance the stream pointer to next record\r\n\t * This record is used for storing result from FORMULA record when it is a string, and\r\n\t * it occurs directly after the FORMULA record\r\n\t *\r\n\t * @return string The string contents as UTF-8\r\n\t */\r\n\tprivate function _readString()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t$string = self::_readUnicodeStringLong($recordData);\r\n\t\t\t$value = $string['value'];\r\n\t\t} else {\r\n\t\t\t$string = $this->_readByteStringLong($recordData);\r\n\t\t\t$value = $string['value'];\r\n\t\t}\r\n\r\n\t\treturn $value;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read BOOLERR record\r\n\t * This record represents a Boolean value or error value\r\n\t * cell.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readBoolErr()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; row index\r\n\t\t$row = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t// offset: 2; size: 2; column index\r\n\t\t$column = self::_GetInt2d($recordData, 2);\r\n\t\t$columnString = PHPExcel_Cell::stringFromColumnIndex($column);\r\n\r\n\t\t// Read cell?\r\n\t\tif (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {\r\n\t\t\t// offset: 4; size: 2; index to XF record\r\n\t\t\t$xfIndex = self::_GetInt2d($recordData, 4);\r\n\r\n\t\t\t// offset: 6; size: 1; the boolean value or error value\r\n\t\t\t$boolErr = ord($recordData{6});\r\n\r\n\t\t\t// offset: 7; size: 1; 0=boolean; 1=error\r\n\t\t\t$isError = ord($recordData{7});\r\n\r\n\t\t\t$cell = $this->_phpSheet->getCell($columnString . ($row + 1));\r\n\t\t\tswitch ($isError) {\r\n\t\t\t\tcase 0: // boolean\r\n\t\t\t\t\t$value = (bool) $boolErr;\r\n\r\n\t\t\t\t\t// add cell value\r\n\t\t\t\t\t$cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_BOOL);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 1: // error type\r\n\t\t\t\t\t$value = self::_mapErrorCode($boolErr);\r\n\r\n\t\t\t\t\t// add cell value\r\n\t\t\t\t\t$cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_ERROR);\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\r\n\t\t\tif (!$this->_readDataOnly) {\r\n\t\t\t\t// add cell style\r\n\t\t\t\t$cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read MULBLANK record\r\n\t * This record represents a cell range of empty cells. All\r\n\t * cells are located in the same row\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readMulBlank()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; index to row\r\n\t\t$row = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t// offset: 2; size: 2; index to first column\r\n\t\t$fc = self::_GetInt2d($recordData, 2);\r\n\r\n\t\t// offset: 4; size: 2 x nc; list of indexes to XF records\r\n\t\t// add style information\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\tfor ($i = 0; $i < $length / 2 - 3; ++$i) {\r\n\t\t\t\t$columnString = PHPExcel_Cell::stringFromColumnIndex($fc + $i);\r\n\r\n\t\t\t\t// Read cell?\r\n\t\t\t\tif (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {\r\n\t\t\t\t\t$xfIndex = self::_GetInt2d($recordData, 4 + 2 * $i);\r\n\t\t\t\t\t$this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t// offset: 6; size 2; index to last column (not needed)\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read LABEL record\r\n\t * This record represents a cell that contains a string. In\r\n\t * BIFF8 it is usually replaced by the LABELSST record.\r\n\t * Excel still uses this record, if it copies unformatted\r\n\t * text cells to the clipboard.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readLabel()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; index to row\r\n\t\t$row = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t// offset: 2; size: 2; index to column\r\n\t\t$column = self::_GetInt2d($recordData, 2);\r\n\t\t$columnString = PHPExcel_Cell::stringFromColumnIndex($column);\r\n\r\n\t\t// Read cell?\r\n\t\tif (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {\r\n\t\t\t// offset: 4; size: 2; XF index\r\n\t\t\t$xfIndex = self::_GetInt2d($recordData, 4);\r\n\r\n\t\t\t// add cell value\r\n\t\t\t// todo: what if string is very long? continue record\r\n\t\t\tif ($this->_version == self::XLS_BIFF8) {\r\n\t\t\t\t$string = self::_readUnicodeStringLong(substr($recordData, 6));\r\n\t\t\t\t$value = $string['value'];\r\n\t\t\t} else {\r\n\t\t\t\t$string = $this->_readByteStringLong(substr($recordData, 6));\r\n\t\t\t\t$value = $string['value'];\r\n\t\t\t}\r\n\t\t\t$cell = $this->_phpSheet->getCell($columnString . ($row + 1));\r\n\t\t\t$cell->setValueExplicit($value, PHPExcel_Cell_DataType::TYPE_STRING);\r\n\r\n\t\t\tif (!$this->_readDataOnly) {\r\n\t\t\t\t// add cell style\r\n\t\t\t\t$cell->setXfIndex($this->_mapCellXfIndex[$xfIndex]);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read BLANK record\r\n\t */\r\n\tprivate function _readBlank()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; row index\r\n\t\t$row = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t// offset: 2; size: 2; col index\r\n\t\t$col = self::_GetInt2d($recordData, 2);\r\n\t\t$columnString = PHPExcel_Cell::stringFromColumnIndex($col);\r\n\r\n\t\t// Read cell?\r\n\t\tif (($this->getReadFilter() !== NULL) && $this->getReadFilter()->readCell($columnString, $row + 1, $this->_phpSheet->getTitle()) ) {\r\n\t\t\t// offset: 4; size: 2; XF index\r\n\t\t\t$xfIndex = self::_GetInt2d($recordData, 4);\r\n\r\n\t\t\t// add style information\r\n\t\t\tif (!$this->_readDataOnly) {\r\n\t\t\t\t$this->_phpSheet->getCell($columnString . ($row + 1))->setXfIndex($this->_mapCellXfIndex[$xfIndex]);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read MSODRAWING record\r\n\t */\r\n\tprivate function _readMsoDrawing()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\r\n\t\t// get spliced record data\r\n\t\t$splicedRecordData = $this->_getSplicedRecordData();\r\n\t\t$recordData = $splicedRecordData['recordData'];\r\n\r\n\t\t$this->_drawingData .= $recordData;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read OBJ record\r\n\t */\r\n\tprivate function _readObj()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_readDataOnly || $this->_version != self::XLS_BIFF8) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// recordData consists of an array of subrecords looking like this:\r\n\t\t//\tft: 2 bytes; ftCmo type (0x15)\r\n\t\t//\tcb: 2 bytes; size in bytes of ftCmo data\r\n\t\t//\tot: 2 bytes; Object Type\r\n\t\t//\tid: 2 bytes; Object id number\r\n\t\t//\tgrbit: 2 bytes; Option Flags\r\n\t\t//\tdata: var; subrecord data\r\n\r\n\t\t// for now, we are just interested in the second subrecord containing the object type\r\n\t\t$ftCmoType\t= self::_GetInt2d($recordData, 0);\r\n\t\t$cbCmoSize\t= self::_GetInt2d($recordData, 2);\r\n\t\t$otObjType\t= self::_GetInt2d($recordData, 4);\r\n\t\t$idObjID\t= self::_GetInt2d($recordData, 6);\r\n\t\t$grbitOpts\t= self::_GetInt2d($recordData, 6);\r\n\r\n\t\t$this->_objs[] = array(\r\n\t\t\t'ftCmoType'\t=> $ftCmoType,\r\n\t\t\t'cbCmoSize'\t=> $cbCmoSize,\r\n\t\t\t'otObjType'\t=> $otObjType,\r\n\t\t\t'idObjID'\t=> $idObjID,\r\n\t\t\t'grbitOpts'\t=> $grbitOpts\r\n\t\t);\r\n\t\t$this->textObjRef = $idObjID;\r\n\r\n//\t\techo '<b>_readObj()</b><br />';\r\n//\t\tvar_dump(end($this->_objs));\r\n//\t\techo '<br />';\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read WINDOW2 record\r\n\t */\r\n\tprivate function _readWindow2()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; option flags\r\n\t\t$options = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t// offset: 2; size: 2; index to first visible row\r\n\t\t$firstVisibleRow = self::_GetInt2d($recordData, 2);\r\n\r\n\t\t// offset: 4; size: 2; index to first visible colum\r\n\t\t$firstVisibleColumn = self::_GetInt2d($recordData, 4);\r\n\t\tif ($this->_version === self::XLS_BIFF8) {\r\n\t\t\t// offset:  8; size: 2; not used\r\n\t\t\t// offset: 10; size: 2; cached magnification factor in page break preview (in percent); 0 = Default (60%)\r\n\t\t\t// offset: 12; size: 2; cached magnification factor in normal view (in percent); 0 = Default (100%)\r\n\t\t\t// offset: 14; size: 4; not used\r\n\t\t\t$zoomscaleInPageBreakPreview = self::_GetInt2d($recordData, 10);\r\n\t\t\tif ($zoomscaleInPageBreakPreview === 0) $zoomscaleInPageBreakPreview = 60;\r\n\t\t\t$zoomscaleInNormalView = self::_GetInt2d($recordData, 12);\r\n\t\t\tif ($zoomscaleInNormalView === 0) $zoomscaleInNormalView = 100;\r\n\t\t}\r\n\r\n\t\t// bit: 1; mask: 0x0002; 0 = do not show gridlines, 1 = show gridlines\r\n\t\t$showGridlines = (bool) ((0x0002 & $options) >> 1);\r\n\t\t$this->_phpSheet->setShowGridlines($showGridlines);\r\n\r\n\t\t// bit: 2; mask: 0x0004; 0 = do not show headers, 1 = show headers\r\n\t\t$showRowColHeaders = (bool) ((0x0004 & $options) >> 2);\r\n\t\t$this->_phpSheet->setShowRowColHeaders($showRowColHeaders);\r\n\r\n\t\t// bit: 3; mask: 0x0008; 0 = panes are not frozen, 1 = panes are frozen\r\n\t\t$this->_frozen = (bool) ((0x0008 & $options) >> 3);\r\n\r\n\t\t// bit: 6; mask: 0x0040; 0 = columns from left to right, 1 = columns from right to left\r\n\t\t$this->_phpSheet->setRightToLeft((bool)((0x0040 & $options) >> 6));\r\n\r\n\t\t// bit: 10; mask: 0x0400; 0 = sheet not active, 1 = sheet active\r\n\t\t$isActive = (bool) ((0x0400 & $options) >> 10);\r\n\t\tif ($isActive) {\r\n\t\t\t$this->_phpExcel->setActiveSheetIndex($this->_phpExcel->getIndex($this->_phpSheet));\r\n\t\t}\r\n\r\n\t\t// bit: 11; mask: 0x0800; 0 = normal view, 1 = page break view\r\n\t\t$isPageBreakPreview = (bool) ((0x0800 & $options) >> 11);\r\n\r\n\t\t//FIXME: set $firstVisibleRow and $firstVisibleColumn\r\n\r\n\t\tif ($this->_phpSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT) {\r\n\t\t\t//NOTE: this setting is inferior to page layout view(Excel2007-)\r\n\t\t\t$view = $isPageBreakPreview? PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW :\r\n\t\t\t\tPHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL;\r\n\t\t\t$this->_phpSheet->getSheetView()->setView($view);\r\n\t\t\tif ($this->_version === self::XLS_BIFF8) {\r\n\t\t\t\t$zoomScale = $isPageBreakPreview? $zoomscaleInPageBreakPreview : $zoomscaleInNormalView;\r\n\t\t\t\t$this->_phpSheet->getSheetView()->setZoomScale($zoomScale);\r\n\t\t\t\t$this->_phpSheet->getSheetView()->setZoomScaleNormal($zoomscaleInNormalView);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\t/**\r\n\t * Read PLV Record(Created by Excel2007 or upper)\r\n\t */\r\n\tprivate function _readPageLayoutView(){\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t//var_dump(unpack(\"vrt/vgrbitFrt/V2reserved/vwScalePLV/vgrbit\", $recordData));\r\n\r\n\t\t// offset: 0; size: 2; rt\r\n\t\t//->ignore\r\n\t\t$rt = self::_GetInt2d($recordData, 0);\r\n\t\t// offset: 2; size: 2; grbitfr\r\n\t\t//->ignore\r\n\t\t$grbitFrt = self::_GetInt2d($recordData, 2);\r\n\t\t// offset: 4; size: 8; reserved\r\n\t\t//->ignore\r\n\r\n\t\t// offset: 12; size 2; zoom scale\r\n\t\t$wScalePLV = self::_GetInt2d($recordData, 12);\r\n\t\t// offset: 14; size 2; grbit\r\n\t\t$grbit = self::_GetInt2d($recordData, 14);\r\n\r\n\t\t// decomprise grbit\r\n\t\t$fPageLayoutView   = $grbit & 0x01;\r\n\t\t$fRulerVisible     = ($grbit >> 1) & 0x01; //no support\r\n\t\t$fWhitespaceHidden = ($grbit >> 3) & 0x01; //no support\r\n\r\n\t\tif ($fPageLayoutView === 1) {\r\n\t\t\t$this->_phpSheet->getSheetView()->setView(PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT);\r\n\t\t\t$this->_phpSheet->getSheetView()->setZoomScale($wScalePLV); //set by Excel2007 only if SHEETVIEW_PAGE_LAYOUT\r\n\t\t}\r\n\t\t//otherwise, we cannot know whether SHEETVIEW_PAGE_LAYOUT or SHEETVIEW_PAGE_BREAK_PREVIEW.\r\n\t}\r\n\r\n\t/**\r\n\t * Read SCL record\r\n\t */\r\n\tprivate function _readScl()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// offset: 0; size: 2; numerator of the view magnification\r\n\t\t$numerator = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t// offset: 2; size: 2; numerator of the view magnification\r\n\t\t$denumerator = self::_GetInt2d($recordData, 2);\r\n\r\n\t\t// set the zoom scale (in percent)\r\n\t\t$this->_phpSheet->getSheetView()->setZoomScale($numerator * 100 / $denumerator);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read PANE record\r\n\t */\r\n\tprivate function _readPane()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 2; position of vertical split\r\n\t\t\t$px = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t\t// offset: 2; size: 2; position of horizontal split\r\n\t\t\t$py = self::_GetInt2d($recordData, 2);\r\n\r\n\t\t\tif ($this->_frozen) {\r\n\t\t\t\t// frozen panes\r\n\t\t\t\t$this->_phpSheet->freezePane(PHPExcel_Cell::stringFromColumnIndex($px) . ($py + 1));\r\n\t\t\t} else {\r\n\t\t\t\t// unfrozen panes; split windows; not supported by PHPExcel core\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read SELECTION record. There is one such record for each pane in the sheet.\r\n\t */\r\n\tprivate function _readSelection()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 1; pane identifier\r\n\t\t\t$paneId = ord($recordData{0});\r\n\r\n\t\t\t// offset: 1; size: 2; index to row of the active cell\r\n\t\t\t$r = self::_GetInt2d($recordData, 1);\r\n\r\n\t\t\t// offset: 3; size: 2; index to column of the active cell\r\n\t\t\t$c = self::_GetInt2d($recordData, 3);\r\n\r\n\t\t\t// offset: 5; size: 2; index into the following cell range list to the\r\n\t\t\t//  entry that contains the active cell\r\n\t\t\t$index = self::_GetInt2d($recordData, 5);\r\n\r\n\t\t\t// offset: 7; size: var; cell range address list containing all selected cell ranges\r\n\t\t\t$data = substr($recordData, 7);\r\n\t\t\t$cellRangeAddressList = $this->_readBIFF5CellRangeAddressList($data); // note: also BIFF8 uses BIFF5 syntax\r\n\r\n\t\t\t$selectedCells = $cellRangeAddressList['cellRangeAddresses'][0];\r\n\r\n\t\t\t// first row '1' + last row '16384' indicates that full column is selected (apparently also in BIFF8!)\r\n\t\t\tif (preg_match('/^([A-Z]+1\\:[A-Z]+)16384$/', $selectedCells)) {\r\n\t\t\t\t$selectedCells = preg_replace('/^([A-Z]+1\\:[A-Z]+)16384$/', '${1}1048576', $selectedCells);\r\n\t\t\t}\r\n\r\n\t\t\t// first row '1' + last row '65536' indicates that full column is selected\r\n\t\t\tif (preg_match('/^([A-Z]+1\\:[A-Z]+)65536$/', $selectedCells)) {\r\n\t\t\t\t$selectedCells = preg_replace('/^([A-Z]+1\\:[A-Z]+)65536$/', '${1}1048576', $selectedCells);\r\n\t\t\t}\r\n\r\n\t\t\t// first column 'A' + last column 'IV' indicates that full row is selected\r\n\t\t\tif (preg_match('/^(A[0-9]+\\:)IV([0-9]+)$/', $selectedCells)) {\r\n\t\t\t\t$selectedCells = preg_replace('/^(A[0-9]+\\:)IV([0-9]+)$/', '${1}XFD${2}', $selectedCells);\r\n\t\t\t}\r\n\r\n\t\t\t$this->_phpSheet->setSelectedCells($selectedCells);\r\n\t\t}\r\n\t}\r\n\r\n\r\n\tprivate function _includeCellRangeFiltered($cellRangeAddress)\r\n\t{\r\n\t\t$includeCellRange = true;\r\n\t\tif ($this->getReadFilter() !== NULL) {\r\n\t\t\t$includeCellRange = false;\r\n\t\t\t$rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($cellRangeAddress);\r\n\t\t\t$rangeBoundaries[1][0]++;\r\n\t\t\tfor ($row = $rangeBoundaries[0][1]; $row <= $rangeBoundaries[1][1]; $row++) {\r\n\t\t\t\tfor ($column = $rangeBoundaries[0][0]; $column != $rangeBoundaries[1][0]; $column++) {\r\n\t\t\t\t\tif ($this->getReadFilter()->readCell($column, $row, $this->_phpSheet->getTitle())) {\r\n\t\t\t\t\t\t$includeCellRange = true;\r\n\t\t\t\t\t\tbreak 2;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn $includeCellRange;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * MERGEDCELLS\r\n\t *\r\n\t * This record contains the addresses of merged cell ranges\r\n\t * in the current sheet.\r\n\t *\r\n\t * --\t\"OpenOffice.org's Documentation of the Microsoft\r\n\t * \t\tExcel File Format\"\r\n\t */\r\n\tprivate function _readMergedCells()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_version == self::XLS_BIFF8 && !$this->_readDataOnly) {\r\n\t\t\t$cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($recordData);\r\n\t\t\tforeach ($cellRangeAddressList['cellRangeAddresses'] as $cellRangeAddress) {\r\n\t\t\t\tif ((strpos($cellRangeAddress,':') !== FALSE) &&\r\n\t\t\t\t\t($this->_includeCellRangeFiltered($cellRangeAddress))) {\r\n\t\t\t\t\t$this->_phpSheet->mergeCells($cellRangeAddress);\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read HYPERLINK record\r\n\t */\r\n\tprivate function _readHyperLink()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer forward to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 8; cell range address of all cells containing this hyperlink\r\n\t\t\ttry {\r\n\t\t\t\t$cellRange = $this->_readBIFF8CellRangeAddressFixed($recordData, 0, 8);\r\n\t\t\t} catch (PHPExcel_Exception $e) {\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\r\n\t\t\t// offset: 8, size: 16; GUID of StdLink\r\n\r\n\t\t\t// offset: 24, size: 4; unknown value\r\n\r\n\t\t\t// offset: 28, size: 4; option flags\r\n\r\n\t\t\t\t// bit: 0; mask: 0x00000001; 0 = no link or extant, 1 = file link or URL\r\n\t\t\t\t$isFileLinkOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 0;\r\n\r\n\t\t\t\t// bit: 1; mask: 0x00000002; 0 = relative path, 1 = absolute path or URL\r\n\t\t\t\t$isAbsPathOrUrl = (0x00000001 & self::_GetInt2d($recordData, 28)) >> 1;\r\n\r\n\t\t\t\t// bit: 2 (and 4); mask: 0x00000014; 0 = no description\r\n\t\t\t\t$hasDesc = (0x00000014 & self::_GetInt2d($recordData, 28)) >> 2;\r\n\r\n\t\t\t\t// bit: 3; mask: 0x00000008; 0 = no text, 1 = has text\r\n\t\t\t\t$hasText = (0x00000008 & self::_GetInt2d($recordData, 28)) >> 3;\r\n\r\n\t\t\t\t// bit: 7; mask: 0x00000080; 0 = no target frame, 1 = has target frame\r\n\t\t\t\t$hasFrame = (0x00000080 & self::_GetInt2d($recordData, 28)) >> 7;\r\n\r\n\t\t\t\t// bit: 8; mask: 0x00000100; 0 = file link or URL, 1 = UNC path (inc. server name)\r\n\t\t\t\t$isUNC = (0x00000100 & self::_GetInt2d($recordData, 28)) >> 8;\r\n\r\n\t\t\t// offset within record data\r\n\t\t\t$offset = 32;\r\n\r\n\t\t\tif ($hasDesc) {\r\n\t\t\t\t// offset: 32; size: var; character count of description text\r\n\t\t\t\t$dl = self::_GetInt4d($recordData, 32);\r\n\t\t\t\t// offset: 36; size: var; character array of description text, no Unicode string header, always 16-bit characters, zero terminated\r\n\t\t\t\t$desc = self::_encodeUTF16(substr($recordData, 36, 2 * ($dl - 1)), false);\r\n\t\t\t\t$offset += 4 + 2 * $dl;\r\n\t\t\t}\r\n\t\t\tif ($hasFrame) {\r\n\t\t\t\t$fl = self::_GetInt4d($recordData, $offset);\r\n\t\t\t\t$offset += 4 + 2 * $fl;\r\n\t\t\t}\r\n\r\n\t\t\t// detect type of hyperlink (there are 4 types)\r\n\t\t\t$hyperlinkType = null;\r\n\r\n\t\t\tif ($isUNC) {\r\n\t\t\t\t$hyperlinkType = 'UNC';\r\n\t\t\t} else if (!$isFileLinkOrUrl) {\r\n\t\t\t\t$hyperlinkType = 'workbook';\r\n\t\t\t} else if (ord($recordData{$offset}) == 0x03) {\r\n\t\t\t\t$hyperlinkType = 'local';\r\n\t\t\t} else if (ord($recordData{$offset}) == 0xE0) {\r\n\t\t\t\t$hyperlinkType = 'URL';\r\n\t\t\t}\r\n\r\n\t\t\tswitch ($hyperlinkType) {\r\n\t\t\tcase 'URL':\r\n\t\t\t\t// section 5.58.2: Hyperlink containing a URL\r\n\t\t\t\t// e.g. http://example.org/index.php\r\n\r\n\t\t\t\t// offset: var; size: 16; GUID of URL Moniker\r\n\t\t\t\t$offset += 16;\r\n\t\t\t\t// offset: var; size: 4; size (in bytes) of character array of the URL including trailing zero word\r\n\t\t\t\t$us = self::_GetInt4d($recordData, $offset);\r\n\t\t\t\t$offset += 4;\r\n\t\t\t\t// offset: var; size: $us; character array of the URL, no Unicode string header, always 16-bit characters, zero-terminated\r\n\t\t\t\t$url = self::_encodeUTF16(substr($recordData, $offset, $us - 2), false);\r\n                $nullOffset = strpos($url, 0x00);\r\n\t\t\t\tif ($nullOffset)\r\n                    $url = substr($url,0,$nullOffset);\r\n\t\t\t\t$url .= $hasText ? '#' : '';\r\n\t\t\t\t$offset += $us;\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tcase 'local':\r\n\t\t\t\t// section 5.58.3: Hyperlink to local file\r\n\t\t\t\t// examples:\r\n\t\t\t\t//   mydoc.txt\r\n\t\t\t\t//   ../../somedoc.xls#Sheet!A1\r\n\r\n\t\t\t\t// offset: var; size: 16; GUI of File Moniker\r\n\t\t\t\t$offset += 16;\r\n\r\n\t\t\t\t// offset: var; size: 2; directory up-level count.\r\n\t\t\t\t$upLevelCount = self::_GetInt2d($recordData, $offset);\r\n\t\t\t\t$offset += 2;\r\n\r\n\t\t\t\t// offset: var; size: 4; character count of the shortened file path and name, including trailing zero word\r\n\t\t\t\t$sl = self::_GetInt4d($recordData, $offset);\r\n\t\t\t\t$offset += 4;\r\n\r\n\t\t\t\t// offset: var; size: sl; character array of the shortened file path and name in 8.3-DOS-format (compressed Unicode string)\r\n\t\t\t\t$shortenedFilePath = substr($recordData, $offset, $sl);\r\n\t\t\t\t$shortenedFilePath = self::_encodeUTF16($shortenedFilePath, true);\r\n\t\t\t\t$shortenedFilePath = substr($shortenedFilePath, 0, -1); // remove trailing zero\r\n\r\n\t\t\t\t$offset += $sl;\r\n\r\n\t\t\t\t// offset: var; size: 24; unknown sequence\r\n\t\t\t\t$offset += 24;\r\n\r\n\t\t\t\t// extended file path\r\n\t\t\t\t// offset: var; size: 4; size of the following file link field including string lenth mark\r\n\t\t\t\t$sz = self::_GetInt4d($recordData, $offset);\r\n\t\t\t\t$offset += 4;\r\n\r\n\t\t\t\t// only present if $sz > 0\r\n\t\t\t\tif ($sz > 0) {\r\n\t\t\t\t\t// offset: var; size: 4; size of the character array of the extended file path and name\r\n\t\t\t\t\t$xl = self::_GetInt4d($recordData, $offset);\r\n\t\t\t\t\t$offset += 4;\r\n\r\n\t\t\t\t\t// offset: var; size 2; unknown\r\n\t\t\t\t\t$offset += 2;\r\n\r\n\t\t\t\t\t// offset: var; size $xl; character array of the extended file path and name.\r\n\t\t\t\t\t$extendedFilePath = substr($recordData, $offset, $xl);\r\n\t\t\t\t\t$extendedFilePath = self::_encodeUTF16($extendedFilePath, false);\r\n\t\t\t\t\t$offset += $xl;\r\n\t\t\t\t}\r\n\r\n\t\t\t\t// construct the path\r\n\t\t\t\t$url = str_repeat('..\\\\', $upLevelCount);\r\n\t\t\t\t$url .= ($sz > 0) ?\r\n\t\t\t\t\t$extendedFilePath : $shortenedFilePath; // use extended path if available\r\n\t\t\t\t$url .= $hasText ? '#' : '';\r\n\r\n\t\t\t\tbreak;\r\n\r\n\r\n\t\t\tcase 'UNC':\r\n\t\t\t\t// section 5.58.4: Hyperlink to a File with UNC (Universal Naming Convention) Path\r\n\t\t\t\t// todo: implement\r\n\t\t\t\treturn;\r\n\r\n\t\t\tcase 'workbook':\r\n\t\t\t\t// section 5.58.5: Hyperlink to the Current Workbook\r\n\t\t\t\t// e.g. Sheet2!B1:C2, stored in text mark field\r\n\t\t\t\t$url = 'sheet://';\r\n\t\t\t\tbreak;\r\n\r\n\t\t\tdefault:\r\n\t\t\t\treturn;\r\n\r\n\t\t\t}\r\n\r\n\t\t\tif ($hasText) {\r\n\t\t\t\t// offset: var; size: 4; character count of text mark including trailing zero word\r\n\t\t\t\t$tl = self::_GetInt4d($recordData, $offset);\r\n\t\t\t\t$offset += 4;\r\n\t\t\t\t// offset: var; size: var; character array of the text mark without the # sign, no Unicode header, always 16-bit characters, zero-terminated\r\n\t\t\t\t$text = self::_encodeUTF16(substr($recordData, $offset, 2 * ($tl - 1)), false);\r\n\t\t\t\t$url .= $text;\r\n\t\t\t}\r\n\r\n\t\t\t// apply the hyperlink to all the relevant cells\r\n\t\t\tforeach (PHPExcel_Cell::extractAllCellReferencesInRange($cellRange) as $coordinate) {\r\n\t\t\t\t$this->_phpSheet->getCell($coordinate)->getHyperLink()->setUrl($url);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read DATAVALIDATIONS record\r\n\t */\r\n\tprivate function _readDataValidations()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer forward to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read DATAVALIDATION record\r\n\t */\r\n\tprivate function _readDataValidation()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer forward to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_readDataOnly) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// offset: 0; size: 4; Options\r\n\t\t$options = self::_GetInt4d($recordData, 0);\r\n\r\n\t\t// bit: 0-3; mask: 0x0000000F; type\r\n\t\t$type = (0x0000000F & $options) >> 0;\r\n\t\tswitch ($type) {\r\n\t\t\tcase 0x00:\t$type = PHPExcel_Cell_DataValidation::TYPE_NONE;\t\tbreak;\r\n\t\t\tcase 0x01:\t$type = PHPExcel_Cell_DataValidation::TYPE_WHOLE;\t\tbreak;\r\n\t\t\tcase 0x02:\t$type = PHPExcel_Cell_DataValidation::TYPE_DECIMAL;\t\tbreak;\r\n\t\t\tcase 0x03:\t$type = PHPExcel_Cell_DataValidation::TYPE_LIST;\t\tbreak;\r\n\t\t\tcase 0x04:\t$type = PHPExcel_Cell_DataValidation::TYPE_DATE;\t\tbreak;\r\n\t\t\tcase 0x05:\t$type = PHPExcel_Cell_DataValidation::TYPE_TIME;\t\tbreak;\r\n\t\t\tcase 0x06:\t$type = PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH;\tbreak;\r\n\t\t\tcase 0x07:\t$type = PHPExcel_Cell_DataValidation::TYPE_CUSTOM;\t\tbreak;\r\n\t\t}\r\n\r\n\t\t// bit: 4-6; mask: 0x00000070; error type\r\n\t\t$errorStyle = (0x00000070 & $options) >> 4;\r\n\t\tswitch ($errorStyle) {\r\n\t\t\tcase 0x00:\t$errorStyle = PHPExcel_Cell_DataValidation::STYLE_STOP;\t\t\tbreak;\r\n\t\t\tcase 0x01:\t$errorStyle = PHPExcel_Cell_DataValidation::STYLE_WARNING;\t\tbreak;\r\n\t\t\tcase 0x02:\t$errorStyle = PHPExcel_Cell_DataValidation::STYLE_INFORMATION;\tbreak;\r\n\t\t}\r\n\r\n\t\t// bit: 7; mask: 0x00000080; 1= formula is explicit (only applies to list)\r\n\t\t// I have only seen cases where this is 1\r\n\t\t$explicitFormula = (0x00000080 & $options) >> 7;\r\n\r\n\t\t// bit: 8; mask: 0x00000100; 1= empty cells allowed\r\n\t\t$allowBlank = (0x00000100 & $options) >> 8;\r\n\r\n\t\t// bit: 9; mask: 0x00000200; 1= suppress drop down arrow in list type validity\r\n\t\t$suppressDropDown = (0x00000200 & $options) >> 9;\r\n\r\n\t\t// bit: 18; mask: 0x00040000; 1= show prompt box if cell selected\r\n\t\t$showInputMessage = (0x00040000 & $options) >> 18;\r\n\r\n\t\t// bit: 19; mask: 0x00080000; 1= show error box if invalid values entered\r\n\t\t$showErrorMessage = (0x00080000 & $options) >> 19;\r\n\r\n\t\t// bit: 20-23; mask: 0x00F00000; condition operator\r\n\t\t$operator = (0x00F00000 & $options) >> 20;\r\n\t\tswitch ($operator) {\r\n\t\t\tcase 0x00: $operator = PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN\t\t\t;\tbreak;\r\n\t\t\tcase 0x01: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN\t\t;\tbreak;\r\n\t\t\tcase 0x02: $operator = PHPExcel_Cell_DataValidation::OPERATOR_EQUAL\t\t\t\t;\tbreak;\r\n\t\t\tcase 0x03: $operator = PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL\t\t\t;\tbreak;\r\n\t\t\tcase 0x04: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN\t\t;\tbreak;\r\n\t\t\tcase 0x05: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN\t\t\t;\tbreak;\r\n\t\t\tcase 0x06: $operator = PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL;\tbreak;\r\n\t\t\tcase 0x07: $operator = PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL\t;\tbreak;\r\n\t\t}\r\n\r\n\t\t// offset: 4; size: var; title of the prompt box\r\n\t\t$offset = 4;\r\n\t\t$string = self::_readUnicodeStringLong(substr($recordData, $offset));\r\n\t\t$promptTitle = $string['value'] !== chr(0) ?\r\n\t\t\t$string['value'] : '';\r\n\t\t$offset += $string['size'];\r\n\r\n\t\t// offset: var; size: var; title of the error box\r\n\t\t$string = self::_readUnicodeStringLong(substr($recordData, $offset));\r\n\t\t$errorTitle = $string['value'] !== chr(0) ?\r\n\t\t\t$string['value'] : '';\r\n\t\t$offset += $string['size'];\r\n\r\n\t\t// offset: var; size: var; text of the prompt box\r\n\t\t$string = self::_readUnicodeStringLong(substr($recordData, $offset));\r\n\t\t$prompt = $string['value'] !== chr(0) ?\r\n\t\t\t$string['value'] : '';\r\n\t\t$offset += $string['size'];\r\n\r\n\t\t// offset: var; size: var; text of the error box\r\n\t\t$string = self::_readUnicodeStringLong(substr($recordData, $offset));\r\n\t\t$error = $string['value'] !== chr(0) ?\r\n\t\t\t$string['value'] : '';\r\n\t\t$offset += $string['size'];\r\n\r\n\t\t// offset: var; size: 2; size of the formula data for the first condition\r\n\t\t$sz1 = self::_GetInt2d($recordData, $offset);\r\n\t\t$offset += 2;\r\n\r\n\t\t// offset: var; size: 2; not used\r\n\t\t$offset += 2;\r\n\r\n\t\t// offset: var; size: $sz1; formula data for first condition (without size field)\r\n\t\t$formula1 = substr($recordData, $offset, $sz1);\r\n\t\t$formula1 = pack('v', $sz1) . $formula1; // prepend the length\r\n\t\ttry {\r\n\t\t\t$formula1 = $this->_getFormulaFromStructure($formula1);\r\n\r\n\t\t\t// in list type validity, null characters are used as item separators\r\n\t\t\tif ($type == PHPExcel_Cell_DataValidation::TYPE_LIST) {\r\n\t\t\t\t$formula1 = str_replace(chr(0), ',', $formula1);\r\n\t\t\t}\r\n\t\t} catch (PHPExcel_Exception $e) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t$offset += $sz1;\r\n\r\n\t\t// offset: var; size: 2; size of the formula data for the first condition\r\n\t\t$sz2 = self::_GetInt2d($recordData, $offset);\r\n\t\t$offset += 2;\r\n\r\n\t\t// offset: var; size: 2; not used\r\n\t\t$offset += 2;\r\n\r\n\t\t// offset: var; size: $sz2; formula data for second condition (without size field)\r\n\t\t$formula2 = substr($recordData, $offset, $sz2);\r\n\t\t$formula2 = pack('v', $sz2) . $formula2; // prepend the length\r\n\t\ttry {\r\n\t\t\t$formula2 = $this->_getFormulaFromStructure($formula2);\r\n\t\t} catch (PHPExcel_Exception $e) {\r\n\t\t\treturn;\r\n\t\t}\r\n\t\t$offset += $sz2;\r\n\r\n\t\t// offset: var; size: var; cell range address list with\r\n\t\t$cellRangeAddressList = $this->_readBIFF8CellRangeAddressList(substr($recordData, $offset));\r\n\t\t$cellRangeAddresses = $cellRangeAddressList['cellRangeAddresses'];\r\n\r\n\t\tforeach ($cellRangeAddresses as $cellRange) {\r\n\t\t\t$stRange = $this->_phpSheet->shrinkRangeToFit($cellRange);\r\n\t\t\t$stRange = PHPExcel_Cell::extractAllCellReferencesInRange($stRange);\r\n\t\t\tforeach ($stRange as $coordinate) {\r\n\t\t\t\t$objValidation = $this->_phpSheet->getCell($coordinate)->getDataValidation();\r\n\t\t\t\t$objValidation->setType($type);\r\n\t\t\t\t$objValidation->setErrorStyle($errorStyle);\r\n\t\t\t\t$objValidation->setAllowBlank((bool)$allowBlank);\r\n\t\t\t\t$objValidation->setShowInputMessage((bool)$showInputMessage);\r\n\t\t\t\t$objValidation->setShowErrorMessage((bool)$showErrorMessage);\r\n\t\t\t\t$objValidation->setShowDropDown(!$suppressDropDown);\r\n\t\t\t\t$objValidation->setOperator($operator);\r\n\t\t\t\t$objValidation->setErrorTitle($errorTitle);\r\n\t\t\t\t$objValidation->setError($error);\r\n\t\t\t\t$objValidation->setPromptTitle($promptTitle);\r\n\t\t\t\t$objValidation->setPrompt($prompt);\r\n\t\t\t\t$objValidation->setFormula1($formula1);\r\n\t\t\t\t$objValidation->setFormula2($formula2);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read SHEETLAYOUT record. Stores sheet tab color information.\r\n\t */\r\n\tprivate function _readSheetLayout()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// local pointer in record data\r\n\t\t$offset = 0;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t// offset: 0; size: 2; repeated record identifier 0x0862\r\n\r\n\t\t\t// offset: 2; size: 10; not used\r\n\r\n\t\t\t// offset: 12; size: 4; size of record data\r\n\t\t\t// Excel 2003 uses size of 0x14 (documented), Excel 2007 uses size of 0x28 (not documented?)\r\n\t\t\t$sz = self::_GetInt4d($recordData, 12);\r\n\r\n\t\t\tswitch ($sz) {\r\n\t\t\t\tcase 0x14:\r\n\t\t\t\t\t// offset: 16; size: 2; color index for sheet tab\r\n\t\t\t\t\t$colorIndex = self::_GetInt2d($recordData, 16);\r\n\t\t\t\t\t$color = self::_readColor($colorIndex,$this->_palette,$this->_version);\r\n\t\t\t\t\t$this->_phpSheet->getTabColor()->setRGB($color['rgb']);\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tcase 0x28:\r\n\t\t\t\t\t// TODO: Investigate structure for .xls SHEETLAYOUT record as saved by MS Office Excel 2007\r\n\t\t\t\t\treturn;\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read SHEETPROTECTION record (FEATHEADR)\r\n\t */\r\n\tprivate function _readSheetProtection()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\tif ($this->_readDataOnly) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// offset: 0; size: 2; repeated record header\r\n\r\n\t\t// offset: 2; size: 2; FRT cell reference flag (=0 currently)\r\n\r\n\t\t// offset: 4; size: 8; Currently not used and set to 0\r\n\r\n\t\t// offset: 12; size: 2; Shared feature type index (2=Enhanced Protetion, 4=SmartTag)\r\n\t\t$isf = self::_GetInt2d($recordData, 12);\r\n\t\tif ($isf != 2) {\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// offset: 14; size: 1; =1 since this is a feat header\r\n\r\n\t\t// offset: 15; size: 4; size of rgbHdrSData\r\n\r\n\t\t// rgbHdrSData, assume \"Enhanced Protection\"\r\n\t\t// offset: 19; size: 2; option flags\r\n\t\t$options = self::_GetInt2d($recordData, 19);\r\n\r\n\t\t// bit: 0; mask 0x0001; 1 = user may edit objects, 0 = users must not edit objects\r\n\t\t$bool = (0x0001 & $options) >> 0;\r\n\t\t$this->_phpSheet->getProtection()->setObjects(!$bool);\r\n\r\n\t\t// bit: 1; mask 0x0002; edit scenarios\r\n\t\t$bool = (0x0002 & $options) >> 1;\r\n\t\t$this->_phpSheet->getProtection()->setScenarios(!$bool);\r\n\r\n\t\t// bit: 2; mask 0x0004; format cells\r\n\t\t$bool = (0x0004 & $options) >> 2;\r\n\t\t$this->_phpSheet->getProtection()->setFormatCells(!$bool);\r\n\r\n\t\t// bit: 3; mask 0x0008; format columns\r\n\t\t$bool = (0x0008 & $options) >> 3;\r\n\t\t$this->_phpSheet->getProtection()->setFormatColumns(!$bool);\r\n\r\n\t\t// bit: 4; mask 0x0010; format rows\r\n\t\t$bool = (0x0010 & $options) >> 4;\r\n\t\t$this->_phpSheet->getProtection()->setFormatRows(!$bool);\r\n\r\n\t\t// bit: 5; mask 0x0020; insert columns\r\n\t\t$bool = (0x0020 & $options) >> 5;\r\n\t\t$this->_phpSheet->getProtection()->setInsertColumns(!$bool);\r\n\r\n\t\t// bit: 6; mask 0x0040; insert rows\r\n\t\t$bool = (0x0040 & $options) >> 6;\r\n\t\t$this->_phpSheet->getProtection()->setInsertRows(!$bool);\r\n\r\n\t\t// bit: 7; mask 0x0080; insert hyperlinks\r\n\t\t$bool = (0x0080 & $options) >> 7;\r\n\t\t$this->_phpSheet->getProtection()->setInsertHyperlinks(!$bool);\r\n\r\n\t\t// bit: 8; mask 0x0100; delete columns\r\n\t\t$bool = (0x0100 & $options) >> 8;\r\n\t\t$this->_phpSheet->getProtection()->setDeleteColumns(!$bool);\r\n\r\n\t\t// bit: 9; mask 0x0200; delete rows\r\n\t\t$bool = (0x0200 & $options) >> 9;\r\n\t\t$this->_phpSheet->getProtection()->setDeleteRows(!$bool);\r\n\r\n\t\t// bit: 10; mask 0x0400; select locked cells\r\n\t\t$bool = (0x0400 & $options) >> 10;\r\n\t\t$this->_phpSheet->getProtection()->setSelectLockedCells(!$bool);\r\n\r\n\t\t// bit: 11; mask 0x0800; sort cell range\r\n\t\t$bool = (0x0800 & $options) >> 11;\r\n\t\t$this->_phpSheet->getProtection()->setSort(!$bool);\r\n\r\n\t\t// bit: 12; mask 0x1000; auto filter\r\n\t\t$bool = (0x1000 & $options) >> 12;\r\n\t\t$this->_phpSheet->getProtection()->setAutoFilter(!$bool);\r\n\r\n\t\t// bit: 13; mask 0x2000; pivot tables\r\n\t\t$bool = (0x2000 & $options) >> 13;\r\n\t\t$this->_phpSheet->getProtection()->setPivotTables(!$bool);\r\n\r\n\t\t// bit: 14; mask 0x4000; select unlocked cells\r\n\t\t$bool = (0x4000 & $options) >> 14;\r\n\t\t$this->_phpSheet->getProtection()->setSelectUnlockedCells(!$bool);\r\n\r\n\t\t// offset: 21; size: 2; not used\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read RANGEPROTECTION record\r\n\t * Reading of this record is based on Microsoft Office Excel 97-2000 Binary File Format Specification,\r\n\t * where it is referred to as FEAT record\r\n\t */\r\n\tprivate function _readRangeProtection()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t// local pointer in record data\r\n\t\t$offset = 0;\r\n\r\n\t\tif (!$this->_readDataOnly) {\r\n\t\t\t$offset += 12;\r\n\r\n\t\t\t// offset: 12; size: 2; shared feature type, 2 = enhanced protection, 4 = smart tag\r\n\t\t\t$isf = self::_GetInt2d($recordData, 12);\r\n\t\t\tif ($isf != 2) {\r\n\t\t\t\t// we only read FEAT records of type 2\r\n\t\t\t\treturn;\r\n\t\t\t}\r\n\t\t\t$offset += 2;\r\n\r\n\t\t\t$offset += 5;\r\n\r\n\t\t\t// offset: 19; size: 2; count of ref ranges this feature is on\r\n\t\t\t$cref = self::_GetInt2d($recordData, 19);\r\n\t\t\t$offset += 2;\r\n\r\n\t\t\t$offset += 6;\r\n\r\n\t\t\t// offset: 27; size: 8 * $cref; list of cell ranges (like in hyperlink record)\r\n\t\t\t$cellRanges = array();\r\n\t\t\tfor ($i = 0; $i < $cref; ++$i) {\r\n\t\t\t\ttry {\r\n\t\t\t\t\t$cellRange = $this->_readBIFF8CellRangeAddressFixed(substr($recordData, 27 + 8 * $i, 8));\r\n\t\t\t\t} catch (PHPExcel_Exception $e) {\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\t\t\t\t$cellRanges[] = $cellRange;\r\n\t\t\t\t$offset += 8;\r\n\t\t\t}\r\n\r\n\t\t\t// offset: var; size: var; variable length of feature specific data\r\n\t\t\t$rgbFeat = substr($recordData, $offset);\r\n\t\t\t$offset += 4;\r\n\r\n\t\t\t// offset: var; size: 4; the encrypted password (only 16-bit although field is 32-bit)\r\n\t\t\t$wPassword = self::_GetInt4d($recordData, $offset);\r\n\t\t\t$offset += 4;\r\n\r\n\t\t\t// Apply range protection to sheet\r\n\t\t\tif ($cellRanges) {\r\n\t\t\t\t$this->_phpSheet->protectCells(implode(' ', $cellRanges), strtoupper(dechex($wPassword)), true);\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read IMDATA record\r\n\t */\r\n\tprivate function _readImData()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\r\n\t\t// get spliced record data\r\n\t\t$splicedRecordData = $this->_getSplicedRecordData();\r\n\t\t$recordData = $splicedRecordData['recordData'];\r\n\r\n\t\t// UNDER CONSTRUCTION\r\n\r\n\t\t// offset: 0; size: 2; image format\r\n\t\t$cf = self::_GetInt2d($recordData, 0);\r\n\r\n\t\t// offset: 2; size: 2; environment from which the file was written\r\n\t\t$env = self::_GetInt2d($recordData, 2);\r\n\r\n\t\t// offset: 4; size: 4; length of the image data\r\n\t\t$lcb = self::_GetInt4d($recordData, 4);\r\n\r\n\t\t// offset: 8; size: var; image data\r\n\t\t$iData = substr($recordData, 8);\r\n\r\n\t\tswitch ($cf) {\r\n\t\tcase 0x09: // Windows bitmap format\r\n\t\t\t// BITMAPCOREINFO\r\n\t\t\t// 1. BITMAPCOREHEADER\r\n\t\t\t// offset: 0; size: 4; bcSize, Specifies the number of bytes required by the structure\r\n\t\t\t$bcSize = self::_GetInt4d($iData, 0);\r\n//\t\t\tvar_dump($bcSize);\r\n\r\n\t\t\t// offset: 4; size: 2; bcWidth, specifies the width of the bitmap, in pixels\r\n\t\t\t$bcWidth = self::_GetInt2d($iData, 4);\r\n//\t\t\tvar_dump($bcWidth);\r\n\r\n\t\t\t// offset: 6; size: 2; bcHeight, specifies the height of the bitmap, in pixels.\r\n\t\t\t$bcHeight = self::_GetInt2d($iData, 6);\r\n//\t\t\tvar_dump($bcHeight);\r\n\t\t\t$ih = imagecreatetruecolor($bcWidth, $bcHeight);\r\n\r\n\t\t\t// offset: 8; size: 2; bcPlanes, specifies the number of planes for the target device. This value must be 1\r\n\r\n\t\t\t// offset: 10; size: 2; bcBitCount specifies the number of bits-per-pixel. This value must be 1, 4, 8, or 24\r\n\t\t\t$bcBitCount = self::_GetInt2d($iData, 10);\r\n//\t\t\tvar_dump($bcBitCount);\r\n\r\n\t\t\t$rgbString = substr($iData, 12);\r\n\t\t\t$rgbTriples = array();\r\n\t\t\twhile (strlen($rgbString) > 0) {\r\n\t\t\t\t$rgbTriples[] = unpack('Cb/Cg/Cr', $rgbString);\r\n\t\t\t\t$rgbString = substr($rgbString, 3);\r\n\t\t\t}\r\n\t\t\t$x = 0;\r\n\t\t\t$y = 0;\r\n\t\t\tforeach ($rgbTriples as $i => $rgbTriple) {\r\n\t\t\t\t$color = imagecolorallocate($ih, $rgbTriple['r'], $rgbTriple['g'], $rgbTriple['b']);\r\n\t\t\t\timagesetpixel($ih, $x, $bcHeight - 1 - $y, $color);\r\n\t\t\t\t$x = ($x + 1) % $bcWidth;\r\n\t\t\t\t$y = $y + floor(($x + 1) / $bcWidth);\r\n\t\t\t}\r\n\t\t\t//imagepng($ih, 'image.png');\r\n\r\n\t\t\t$drawing = new PHPExcel_Worksheet_Drawing();\r\n\t\t\t$drawing->setPath($filename);\r\n\t\t\t$drawing->setWorksheet($this->_phpSheet);\r\n\r\n\t\t\tbreak;\r\n\r\n\t\tcase 0x02: // Windows metafile or Macintosh PICT format\r\n\t\tcase 0x0e: // native format\r\n\t\tdefault;\r\n\t\t\tbreak;\r\n\r\n\t\t}\r\n\r\n\t\t// _getSplicedRecordData() takes care of moving current position in data stream\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read a free CONTINUE record. Free CONTINUE record may be a camouflaged MSODRAWING record\r\n\t * When MSODRAWING data on a sheet exceeds 8224 bytes, CONTINUE records are used instead. Undocumented.\r\n\t * In this case, we must treat the CONTINUE record as a MSODRAWING record\r\n\t */\r\n\tprivate function _readContinue()\r\n\t{\r\n\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t$recordData = $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t// check if we are reading drawing data\r\n\t\t// this is in case a free CONTINUE record occurs in other circumstances we are unaware of\r\n\t\tif ($this->_drawingData == '') {\r\n\t\t\t// move stream pointer to next record\r\n\t\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// check if record data is at least 4 bytes long, otherwise there is no chance this is MSODRAWING data\r\n\t\tif ($length < 4) {\r\n\t\t\t// move stream pointer to next record\r\n\t\t\t$this->_pos += 4 + $length;\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// dirty check to see if CONTINUE record could be a camouflaged MSODRAWING record\r\n\t\t// look inside CONTINUE record to see if it looks like a part of an Escher stream\r\n\t\t// we know that Escher stream may be split at least at\r\n\t\t//\t\t0xF003 MsofbtSpgrContainer\r\n\t\t//\t\t0xF004 MsofbtSpContainer\r\n\t\t//\t\t0xF00D MsofbtClientTextbox\r\n\t\t$validSplitPoints = array(0xF003, 0xF004, 0xF00D); // add identifiers if we find more\r\n\r\n\t\t$splitPoint = self::_GetInt2d($recordData, 2);\r\n\t\tif (in_array($splitPoint, $validSplitPoints)) {\r\n\t\t\t// get spliced record data (and move pointer to next record)\r\n\t\t\t$splicedRecordData = $this->_getSplicedRecordData();\r\n\t\t\t$this->_drawingData .= $splicedRecordData['recordData'];\r\n\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t// move stream pointer to next record\r\n\t\t$this->_pos += 4 + $length;\r\n\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Reads a record from current position in data stream and continues reading data as long as CONTINUE\r\n\t * records are found. Splices the record data pieces and returns the combined string as if record data\r\n\t * is in one piece.\r\n\t * Moves to next current position in data stream to start of next record different from a CONtINUE record\r\n\t *\r\n\t * @return array\r\n\t */\r\n\tprivate function _getSplicedRecordData()\r\n\t{\r\n\t\t$data = '';\r\n\t\t$spliceOffsets = array();\r\n\r\n\t\t$i = 0;\r\n\t\t$spliceOffsets[0] = 0;\r\n\r\n\t\tdo {\r\n\t\t\t++$i;\r\n\r\n\t\t\t// offset: 0; size: 2; identifier\r\n\t\t\t$identifier = self::_GetInt2d($this->_data, $this->_pos);\r\n\t\t\t// offset: 2; size: 2; length\r\n\t\t\t$length = self::_GetInt2d($this->_data, $this->_pos + 2);\r\n\t\t\t$data .= $this->_readRecordData($this->_data, $this->_pos + 4, $length);\r\n\r\n\t\t\t$spliceOffsets[$i] = $spliceOffsets[$i - 1] + $length;\r\n\r\n\t\t\t$this->_pos += 4 + $length;\r\n\t\t\t$nextIdentifier = self::_GetInt2d($this->_data, $this->_pos);\r\n\t\t}\r\n\t\twhile ($nextIdentifier == self::XLS_Type_CONTINUE);\r\n\r\n\t\t$splicedData = array(\r\n\t\t\t'recordData' => $data,\r\n\t\t\t'spliceOffsets' => $spliceOffsets,\r\n\t\t);\r\n\r\n\t\treturn $splicedData;\r\n\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Convert formula structure into human readable Excel formula like 'A3+A5*5'\r\n\t *\r\n\t * @param string $formulaStructure The complete binary data for the formula\r\n\t * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas\r\n\t * @return string Human readable formula\r\n\t */\r\n\tprivate function _getFormulaFromStructure($formulaStructure, $baseCell = 'A1')\r\n\t{\r\n\t\t// offset: 0; size: 2; size of the following formula data\r\n\t\t$sz = self::_GetInt2d($formulaStructure, 0);\r\n\r\n\t\t// offset: 2; size: sz\r\n\t\t$formulaData = substr($formulaStructure, 2, $sz);\r\n\r\n\t\t// for debug: dump the formula data\r\n\t\t//echo '<xmp>';\r\n\t\t//echo 'size: ' . $sz . \"\\n\";\r\n\t\t//echo 'the entire formula data: ';\r\n\t\t//Debug::dump($formulaData);\r\n\t\t//echo \"\\n----\\n\";\r\n\r\n\t\t// offset: 2 + sz; size: variable (optional)\r\n\t\tif (strlen($formulaStructure) > 2 + $sz) {\r\n\t\t\t$additionalData = substr($formulaStructure, 2 + $sz);\r\n\r\n\t\t\t// for debug: dump the additional data\r\n\t\t\t//echo 'the entire additional data: ';\r\n\t\t\t//Debug::dump($additionalData);\r\n\t\t\t//echo \"\\n----\\n\";\r\n\r\n\t\t} else {\r\n\t\t\t$additionalData = '';\r\n\t\t}\r\n\r\n\t\treturn $this->_getFormulaFromData($formulaData, $additionalData, $baseCell);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Take formula data and additional data for formula and return human readable formula\r\n\t *\r\n\t * @param string $formulaData The binary data for the formula itself\r\n\t * @param string $additionalData Additional binary data going with the formula\r\n\t * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas\r\n\t * @return string Human readable formula\r\n\t */\r\n\tprivate function _getFormulaFromData($formulaData,  $additionalData = '', $baseCell = 'A1')\r\n\t{\r\n\t\t// start parsing the formula data\r\n\t\t$tokens = array();\r\n\r\n\t\twhile (strlen($formulaData) > 0 and $token = $this->_getNextToken($formulaData, $baseCell)) {\r\n\t\t\t$tokens[] = $token;\r\n\t\t\t$formulaData = substr($formulaData, $token['size']);\r\n\r\n\t\t\t// for debug: dump the token\r\n\t\t\t//var_dump($token);\r\n\t\t}\r\n\r\n\t\t$formulaString = $this->_createFormulaFromTokens($tokens, $additionalData);\r\n\r\n\t\treturn $formulaString;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Take array of tokens together with additional data for formula and return human readable formula\r\n\t *\r\n\t * @param array $tokens\r\n\t * @param array $additionalData Additional binary data going with the formula\r\n\t * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas\r\n\t * @return string Human readable formula\r\n\t */\r\n\tprivate function _createFormulaFromTokens($tokens, $additionalData)\r\n\t{\r\n\t\t// empty formula?\r\n\t\tif (empty($tokens)) {\r\n\t\t\treturn '';\r\n\t\t}\r\n\r\n\t\t$formulaStrings = array();\r\n\t\tforeach ($tokens as $token) {\r\n\t\t\t// initialize spaces\r\n\t\t\t$space0 = isset($space0) ? $space0 : ''; // spaces before next token, not tParen\r\n\t\t\t$space1 = isset($space1) ? $space1 : ''; // carriage returns before next token, not tParen\r\n\t\t\t$space2 = isset($space2) ? $space2 : ''; // spaces before opening parenthesis\r\n\t\t\t$space3 = isset($space3) ? $space3 : ''; // carriage returns before opening parenthesis\r\n\t\t\t$space4 = isset($space4) ? $space4 : ''; // spaces before closing parenthesis\r\n\t\t\t$space5 = isset($space5) ? $space5 : ''; // carriage returns before closing parenthesis\r\n\r\n\t\t\tswitch ($token['name']) {\r\n\t\t\tcase 'tAdd': // addition\r\n\t\t\tcase 'tConcat': // addition\r\n\t\t\tcase 'tDiv': // division\r\n\t\t\tcase 'tEQ': // equality\r\n\t\t\tcase 'tGE': // greater than or equal\r\n\t\t\tcase 'tGT': // greater than\r\n\t\t\tcase 'tIsect': // intersection\r\n\t\t\tcase 'tLE': // less than or equal\r\n\t\t\tcase 'tList': // less than or equal\r\n\t\t\tcase 'tLT': // less than\r\n\t\t\tcase 'tMul': // multiplication\r\n\t\t\tcase 'tNE': // multiplication\r\n\t\t\tcase 'tPower': // power\r\n\t\t\tcase 'tRange': // range\r\n\t\t\tcase 'tSub': // subtraction\r\n\t\t\t\t$op2 = array_pop($formulaStrings);\r\n\t\t\t\t$op1 = array_pop($formulaStrings);\r\n\t\t\t\t$formulaStrings[] = \"$op1$space1$space0{$token['data']}$op2\";\r\n\t\t\t\tunset($space0, $space1);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tUplus': // unary plus\r\n\t\t\tcase 'tUminus': // unary minus\r\n\t\t\t\t$op = array_pop($formulaStrings);\r\n\t\t\t\t$formulaStrings[] = \"$space1$space0{$token['data']}$op\";\r\n\t\t\t\tunset($space0, $space1);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tPercent': // percent sign\r\n\t\t\t\t$op = array_pop($formulaStrings);\r\n\t\t\t\t$formulaStrings[] = \"$op$space1$space0{$token['data']}\";\r\n\t\t\t\tunset($space0, $space1);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tAttrVolatile': // indicates volatile function\r\n\t\t\tcase 'tAttrIf':\r\n\t\t\tcase 'tAttrSkip':\r\n\t\t\tcase 'tAttrChoose':\r\n\t\t\t\t// token is only important for Excel formula evaluator\r\n\t\t\t\t// do nothing\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tAttrSpace': // space / carriage return\r\n\t\t\t\t// space will be used when next token arrives, do not alter formulaString stack\r\n\t\t\t\tswitch ($token['data']['spacetype']) {\r\n\t\t\t\tcase 'type0':\r\n\t\t\t\t\t$space0 = str_repeat(' ', $token['data']['spacecount']);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'type1':\r\n\t\t\t\t\t$space1 = str_repeat(\"\\n\", $token['data']['spacecount']);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'type2':\r\n\t\t\t\t\t$space2 = str_repeat(' ', $token['data']['spacecount']);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'type3':\r\n\t\t\t\t\t$space3 = str_repeat(\"\\n\", $token['data']['spacecount']);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'type4':\r\n\t\t\t\t\t$space4 = str_repeat(' ', $token['data']['spacecount']);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 'type5':\r\n\t\t\t\t\t$space5 = str_repeat(\"\\n\", $token['data']['spacecount']);\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tAttrSum': // SUM function with one parameter\r\n\t\t\t\t$op = array_pop($formulaStrings);\r\n\t\t\t\t$formulaStrings[] = \"{$space1}{$space0}SUM($op)\";\r\n\t\t\t\tunset($space0, $space1);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tFunc': // function with fixed number of arguments\r\n\t\t\tcase 'tFuncV': // function with variable number of arguments\r\n\t\t\t\tif ($token['data']['function'] != '') {\r\n\t\t\t\t\t// normal function\r\n\t\t\t\t\t$ops = array(); // array of operators\r\n\t\t\t\t\tfor ($i = 0; $i < $token['data']['args']; ++$i) {\r\n\t\t\t\t\t\t$ops[] = array_pop($formulaStrings);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t$ops = array_reverse($ops);\r\n\t\t\t\t\t$formulaStrings[] = \"$space1$space0{$token['data']['function']}(\" . implode(',', $ops) . \")\";\r\n\t\t\t\t\tunset($space0, $space1);\r\n\t\t\t\t} else {\r\n\t\t\t\t\t// add-in function\r\n\t\t\t\t\t$ops = array(); // array of operators\r\n\t\t\t\t\tfor ($i = 0; $i < $token['data']['args'] - 1; ++$i) {\r\n\t\t\t\t\t\t$ops[] = array_pop($formulaStrings);\r\n\t\t\t\t\t}\r\n\t\t\t\t\t$ops = array_reverse($ops);\r\n\t\t\t\t\t$function = array_pop($formulaStrings);\r\n\t\t\t\t\t$formulaStrings[] = \"$space1$space0$function(\" . implode(',', $ops) . \")\";\r\n\t\t\t\t\tunset($space0, $space1);\r\n\t\t\t\t}\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tParen': // parenthesis\r\n\t\t\t\t$expression = array_pop($formulaStrings);\r\n\t\t\t\t$formulaStrings[] = \"$space3$space2($expression$space5$space4)\";\r\n\t\t\t\tunset($space2, $space3, $space4, $space5);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tArray': // array constant\r\n\t\t\t\t$constantArray = self::_readBIFF8ConstantArray($additionalData);\r\n\t\t\t\t$formulaStrings[] = $space1 . $space0 . $constantArray['value'];\r\n\t\t\t\t$additionalData = substr($additionalData, $constantArray['size']); // bite of chunk of additional data\r\n\t\t\t\tunset($space0, $space1);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tMemArea':\r\n\t\t\t\t// bite off chunk of additional data\r\n\t\t\t\t$cellRangeAddressList = $this->_readBIFF8CellRangeAddressList($additionalData);\r\n\t\t\t\t$additionalData = substr($additionalData, $cellRangeAddressList['size']);\r\n\t\t\t\t$formulaStrings[] = \"$space1$space0{$token['data']}\";\r\n\t\t\t\tunset($space0, $space1);\r\n\t\t\t\tbreak;\r\n\t\t\tcase 'tArea': // cell range address\r\n\t\t\tcase 'tBool': // boolean\r\n\t\t\tcase 'tErr': // error code\r\n\t\t\tcase 'tInt': // integer\r\n\t\t\tcase 'tMemErr':\r\n\t\t\tcase 'tMemFunc':\r\n\t\t\tcase 'tMissArg':\r\n\t\t\tcase 'tName':\r\n\t\t\tcase 'tNameX':\r\n\t\t\tcase 'tNum': // number\r\n\t\t\tcase 'tRef': // single cell reference\r\n\t\t\tcase 'tRef3d': // 3d cell reference\r\n\t\t\tcase 'tArea3d': // 3d cell range reference\r\n\t\t\tcase 'tRefN':\r\n\t\t\tcase 'tAreaN':\r\n\t\t\tcase 'tStr': // string\r\n\t\t\t\t$formulaStrings[] = \"$space1$space0{$token['data']}\";\r\n\t\t\t\tunset($space0, $space1);\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t\t$formulaString = $formulaStrings[0];\r\n\r\n\t\t// for debug: dump the human readable formula\r\n\t\t//echo '----' . \"\\n\";\r\n\t\t//echo 'Formula: ' . $formulaString;\r\n\r\n\t\treturn $formulaString;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Fetch next token from binary formula data\r\n\t *\r\n\t * @param string Formula data\r\n\t * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas\r\n\t * @return array\r\n\t * @throws PHPExcel_Reader_Exception\r\n\t */\r\n\tprivate function _getNextToken($formulaData, $baseCell = 'A1')\r\n\t{\r\n\t\t// offset: 0; size: 1; token id\r\n\t\t$id = ord($formulaData[0]); // token id\r\n\t\t$name = false; // initialize token name\r\n\r\n\t\tswitch ($id) {\r\n\t\tcase 0x03: $name = 'tAdd';\t\t$size = 1;\t$data = '+';\tbreak;\r\n\t\tcase 0x04: $name = 'tSub';\t\t$size = 1;\t$data = '-';\tbreak;\r\n\t\tcase 0x05: $name = 'tMul';\t\t$size = 1;\t$data = '*';\tbreak;\r\n\t\tcase 0x06: $name = 'tDiv';\t\t$size = 1;\t$data = '/';\tbreak;\r\n\t\tcase 0x07: $name = 'tPower';\t$size = 1;\t$data = '^';\tbreak;\r\n\t\tcase 0x08: $name = 'tConcat';\t$size = 1;\t$data = '&';\tbreak;\r\n\t\tcase 0x09: $name = 'tLT';\t\t$size = 1;\t$data = '<';\tbreak;\r\n\t\tcase 0x0A: $name = 'tLE';\t\t$size = 1;\t$data = '<=';\tbreak;\r\n\t\tcase 0x0B: $name = 'tEQ';\t\t$size = 1;\t$data = '=';\tbreak;\r\n\t\tcase 0x0C: $name = 'tGE';\t\t$size = 1;\t$data = '>=';\tbreak;\r\n\t\tcase 0x0D: $name = 'tGT';\t\t$size = 1;\t$data = '>';\tbreak;\r\n\t\tcase 0x0E: $name = 'tNE';\t\t$size = 1;\t$data = '<>';\tbreak;\r\n\t\tcase 0x0F: $name = 'tIsect';\t$size = 1;\t$data = ' ';\tbreak;\r\n\t\tcase 0x10: $name = 'tList';\t\t$size = 1;\t$data = ',';\tbreak;\r\n\t\tcase 0x11: $name = 'tRange';\t$size = 1;\t$data = ':';\tbreak;\r\n\t\tcase 0x12: $name = 'tUplus';\t$size = 1;\t$data = '+';\tbreak;\r\n\t\tcase 0x13: $name = 'tUminus';\t$size = 1;\t$data = '-';\tbreak;\r\n\t\tcase 0x14: $name = 'tPercent';\t$size = 1;\t$data = '%';\tbreak;\r\n\t\tcase 0x15:\t//\tparenthesis\r\n\t\t\t$name  = 'tParen';\r\n\t\t\t$size  = 1;\r\n\t\t\t$data = null;\r\n\t\t\tbreak;\r\n\t\tcase 0x16:\t//\tmissing argument\r\n\t\t\t$name = 'tMissArg';\r\n\t\t\t$size = 1;\r\n\t\t\t$data = '';\r\n\t\t\tbreak;\r\n\t\tcase 0x17:\t//\tstring\r\n\t\t\t$name = 'tStr';\r\n\t\t\t// offset: 1; size: var; Unicode string, 8-bit string length\r\n\t\t\t$string = self::_readUnicodeStringShort(substr($formulaData, 1));\r\n\t\t\t$size = 1 + $string['size'];\r\n\t\t\t$data = self::_UTF8toExcelDoubleQuoted($string['value']);\r\n\t\t\tbreak;\r\n\t\tcase 0x19:\t//\tSpecial attribute\r\n\t\t\t// offset: 1; size: 1; attribute type flags:\r\n\t\t\tswitch (ord($formulaData[1])) {\r\n\t\t\tcase 0x01:\r\n\t\t\t\t$name = 'tAttrVolatile';\r\n\t\t\t\t$size = 4;\r\n\t\t\t\t$data = null;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 0x02:\r\n\t\t\t\t$name = 'tAttrIf';\r\n\t\t\t\t$size = 4;\r\n\t\t\t\t$data = null;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 0x04:\r\n\t\t\t\t$name = 'tAttrChoose';\r\n\t\t\t\t// offset: 2; size: 2; number of choices in the CHOOSE function ($nc, number of parameters decreased by 1)\r\n\t\t\t\t$nc = self::_GetInt2d($formulaData, 2);\r\n\t\t\t\t// offset: 4; size: 2 * $nc\r\n\t\t\t\t// offset: 4 + 2 * $nc; size: 2\r\n\t\t\t\t$size = 2 * $nc + 6;\r\n\t\t\t\t$data = null;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 0x08:\r\n\t\t\t\t$name = 'tAttrSkip';\r\n\t\t\t\t$size = 4;\r\n\t\t\t\t$data = null;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 0x10:\r\n\t\t\t\t$name = 'tAttrSum';\r\n\t\t\t\t$size = 4;\r\n\t\t\t\t$data = null;\r\n\t\t\t\tbreak;\r\n\t\t\tcase 0x40:\r\n\t\t\tcase 0x41:\r\n\t\t\t\t$name = 'tAttrSpace';\r\n\t\t\t\t$size = 4;\r\n\t\t\t\t// offset: 2; size: 2; space type and position\r\n\t\t\t\tswitch (ord($formulaData[2])) {\r\n\t\t\t\tcase 0x00:\r\n\t\t\t\t\t$spacetype = 'type0';\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 0x01:\r\n\t\t\t\t\t$spacetype = 'type1';\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 0x02:\r\n\t\t\t\t\t$spacetype = 'type2';\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 0x03:\r\n\t\t\t\t\t$spacetype = 'type3';\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 0x04:\r\n\t\t\t\t\t$spacetype = 'type4';\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tcase 0x05:\r\n\t\t\t\t\t$spacetype = 'type5';\r\n\t\t\t\t\tbreak;\r\n\t\t\t\tdefault:\r\n\t\t\t\t\tthrow new PHPExcel_Reader_Exception('Unrecognized space type in tAttrSpace token');\r\n\t\t\t\t\tbreak;\r\n\t\t\t\t}\r\n\t\t\t\t// offset: 3; size: 1; number of inserted spaces/carriage returns\r\n\t\t\t\t$spacecount = ord($formulaData[3]);\r\n\r\n\t\t\t\t$data = array('spacetype' => $spacetype, 'spacecount' => $spacecount);\r\n\t\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tthrow new PHPExcel_Reader_Exception('Unrecognized attribute flag in tAttr token');\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\tbreak;\r\n\t\tcase 0x1C:\t//\terror code\r\n\t\t\t// offset: 1; size: 1; error code\r\n\t\t\t$name = 'tErr';\r\n\t\t\t$size = 2;\r\n\t\t\t$data = self::_mapErrorCode(ord($formulaData[1]));\r\n\t\t\tbreak;\r\n\t\tcase 0x1D:\t//\tboolean\r\n\t\t\t// offset: 1; size: 1; 0 = false, 1 = true;\r\n\t\t\t$name = 'tBool';\r\n\t\t\t$size = 2;\r\n\t\t\t$data = ord($formulaData[1]) ? 'TRUE' : 'FALSE';\r\n\t\t\tbreak;\r\n\t\tcase 0x1E:\t//\tinteger\r\n\t\t\t// offset: 1; size: 2; unsigned 16-bit integer\r\n\t\t\t$name = 'tInt';\r\n\t\t\t$size = 3;\r\n\t\t\t$data = self::_GetInt2d($formulaData, 1);\r\n\t\t\tbreak;\r\n\t\tcase 0x1F:\t//\tnumber\r\n\t\t\t// offset: 1; size: 8;\r\n\t\t\t$name = 'tNum';\r\n\t\t\t$size = 9;\r\n\t\t\t$data = self::_extractNumber(substr($formulaData, 1));\r\n\t\t\t$data = str_replace(',', '.', (string)$data); // in case non-English locale\r\n\t\t\tbreak;\r\n\t\tcase 0x20:\t//\tarray constant\r\n\t\tcase 0x40:\r\n\t\tcase 0x60:\r\n\t\t\t// offset: 1; size: 7; not used\r\n\t\t\t$name = 'tArray';\r\n\t\t\t$size = 8;\r\n\t\t\t$data = null;\r\n\t\t\tbreak;\r\n\t\tcase 0x21:\t//\tfunction with fixed number of arguments\r\n\t\tcase 0x41:\r\n\t\tcase 0x61:\r\n\t\t\t$name = 'tFunc';\r\n\t\t\t$size = 3;\r\n\t\t\t// offset: 1; size: 2; index to built-in sheet function\r\n\t\t\tswitch (self::_GetInt2d($formulaData, 1)) {\r\n\t\t\tcase   2: $function = 'ISNA'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase   3: $function = 'ISERROR'; \t\t$args = 1; \tbreak;\r\n\t\t\tcase  10: $function = 'NA'; \t\t\t$args = 0; \tbreak;\r\n\t\t\tcase  15: $function = 'SIN'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  16: $function = 'COS'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  17: $function = 'TAN'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  18: $function = 'ATAN'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  19: $function = 'PI'; \t\t\t$args = 0; \tbreak;\r\n\t\t\tcase  20: $function = 'SQRT'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  21: $function = 'EXP'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  22: $function = 'LN'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  23: $function = 'LOG10'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  24: $function = 'ABS'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  25: $function = 'INT'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  26: $function = 'SIGN'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  27: $function = 'ROUND'; \t\t\t$args = 2; \tbreak;\r\n\t\t\tcase  30: $function = 'REPT'; \t\t\t$args = 2; \tbreak;\r\n\t\t\tcase  31: $function = 'MID'; \t\t\t$args = 3; \tbreak;\r\n\t\t\tcase  32: $function = 'LEN'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  33: $function = 'VALUE'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  34: $function = 'TRUE'; \t\t\t$args = 0; \tbreak;\r\n\t\t\tcase  35: $function = 'FALSE'; \t\t\t$args = 0; \tbreak;\r\n\t\t\tcase  38: $function = 'NOT'; \t\t\t$args = 1; \tbreak;\r\n\t\t\tcase  39: $function = 'MOD'; \t\t\t$args = 2;\tbreak;\r\n\t\t\tcase  40: $function = 'DCOUNT'; \t\t$args = 3;\tbreak;\r\n\t\t\tcase  41: $function = 'DSUM'; \t\t\t$args = 3;\tbreak;\r\n\t\t\tcase  42: $function = 'DAVERAGE'; \t\t$args = 3;\tbreak;\r\n\t\t\tcase  43: $function = 'DMIN'; \t\t\t$args = 3;\tbreak;\r\n\t\t\tcase  44: $function = 'DMAX'; \t\t\t$args = 3;\tbreak;\r\n\t\t\tcase  45: $function = 'DSTDEV'; \t\t$args = 3;\tbreak;\r\n\t\t\tcase  48: $function = 'TEXT'; \t\t\t$args = 2;\tbreak;\r\n\t\t\tcase  61: $function = 'MIRR'; \t\t\t$args = 3;\tbreak;\r\n\t\t\tcase  63: $function = 'RAND'; \t\t\t$args = 0;\tbreak;\r\n\t\t\tcase  65: $function = 'DATE'; \t\t\t$args = 3;\tbreak;\r\n\t\t\tcase  66: $function = 'TIME'; \t\t\t$args = 3;\tbreak;\r\n\t\t\tcase  67: $function = 'DAY'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase  68: $function = 'MONTH'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase  69: $function = 'YEAR'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase  71: $function = 'HOUR'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase  72: $function = 'MINUTE'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase  73: $function = 'SECOND'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase  74: $function = 'NOW'; \t\t\t$args = 0;\tbreak;\r\n\t\t\tcase  75: $function = 'AREAS'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase  76: $function = 'ROWS'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase  77: $function = 'COLUMNS'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase  83: $function = 'TRANSPOSE'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase  86: $function = 'TYPE'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase  97: $function = 'ATAN2'; \t\t\t$args = 2;\tbreak;\r\n\t\t\tcase  98: $function = 'ASIN'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase  99: $function = 'ACOS'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 105: $function = 'ISREF'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 111: $function = 'CHAR'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 112: $function = 'LOWER'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 113: $function = 'UPPER'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 114: $function = 'PROPER'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase 117: $function = 'EXACT'; \t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 118: $function = 'TRIM'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 119: $function = 'REPLACE'; \t\t$args = 4;\tbreak;\r\n\t\t\tcase 121: $function = 'CODE'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 126: $function = 'ISERR'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 127: $function = 'ISTEXT'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase 128: $function = 'ISNUMBER'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase 129: $function = 'ISBLANK'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase 130: $function = 'T'; \t\t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 131: $function = 'N'; \t\t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 140: $function = 'DATEVALUE'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase 141: $function = 'TIMEVALUE'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase 142: $function = 'SLN'; \t\t\t$args = 3;\tbreak;\r\n\t\t\tcase 143: $function = 'SYD'; \t\t\t$args = 4;\tbreak;\r\n\t\t\tcase 162: $function = 'CLEAN'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 163: $function = 'MDETERM'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase 164: $function = 'MINVERSE'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase 165: $function = 'MMULT'; \t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 184: $function = 'FACT'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 189: $function = 'DPRODUCT'; \t\t$args = 3;\tbreak;\r\n\t\t\tcase 190: $function = 'ISNONTEXT'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase 195: $function = 'DSTDEVP'; \t\t$args = 3;\tbreak;\r\n\t\t\tcase 196: $function = 'DVARP'; \t\t\t$args = 3;\tbreak;\r\n\t\t\tcase 198: $function = 'ISLOGICAL'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase 199: $function = 'DCOUNTA'; \t\t$args = 3;\tbreak;\r\n\t\t\tcase 207: $function = 'REPLACEB'; \t\t$args = 4;\tbreak;\r\n\t\t\tcase 210: $function = 'MIDB'; \t\t\t$args = 3;\tbreak;\r\n\t\t\tcase 211: $function = 'LENB'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 212: $function = 'ROUNDUP'; \t\t$args = 2;\tbreak;\r\n\t\t\tcase 213: $function = 'ROUNDDOWN'; \t\t$args = 2;\tbreak;\r\n\t\t\tcase 214: $function = 'ASC'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 215: $function = 'DBCS'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 221: $function = 'TODAY'; \t\t\t$args = 0;\tbreak;\r\n\t\t\tcase 229: $function = 'SINH'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 230: $function = 'COSH'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 231: $function = 'TANH'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 232: $function = 'ASINH'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 233: $function = 'ACOSH'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 234: $function = 'ATANH'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 235: $function = 'DGET'; \t\t\t$args = 3;\tbreak;\r\n\t\t\tcase 244: $function = 'INFO'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 252: $function = 'FREQUENCY'; \t\t$args = 2;\tbreak;\r\n\t\t\tcase 261: $function = 'ERROR.TYPE'; \t$args = 1;\tbreak;\r\n\t\t\tcase 271: $function = 'GAMMALN'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase 273: $function = 'BINOMDIST'; \t\t$args = 4;\tbreak;\r\n\t\t\tcase 274: $function = 'CHIDIST'; \t\t$args = 2;\tbreak;\r\n\t\t\tcase 275: $function = 'CHIINV'; \t\t$args = 2;\tbreak;\r\n\t\t\tcase 276: $function = 'COMBIN'; \t\t$args = 2;\tbreak;\r\n\t\t\tcase 277: $function = 'CONFIDENCE'; \t$args = 3;\tbreak;\r\n\t\t\tcase 278: $function = 'CRITBINOM'; \t\t$args = 3;\tbreak;\r\n\t\t\tcase 279: $function = 'EVEN'; \t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 280: $function = 'EXPONDIST'; \t\t$args = 3;\tbreak;\r\n\t\t\tcase 281: $function = 'FDIST'; \t\t\t$args = 3;\tbreak;\r\n\t\t\tcase 282: $function = 'FINV'; \t\t\t$args = 3;\tbreak;\r\n\t\t\tcase 283: $function = 'FISHER'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase 284: $function = 'FISHERINV'; \t\t$args = 1;\tbreak;\r\n\t\t\tcase 285: $function = 'FLOOR'; \t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 286: $function = 'GAMMADIST'; \t\t$args = 4;\tbreak;\r\n\t\t\tcase 287: $function = 'GAMMAINV'; \t\t$args = 3;\tbreak;\r\n\t\t\tcase 288: $function = 'CEILING'; \t\t$args = 2;\tbreak;\r\n\t\t\tcase 289: $function = 'HYPGEOMDIST';\t$args = 4;\tbreak;\r\n\t\t\tcase 290: $function = 'LOGNORMDIST';\t$args = 3;\tbreak;\r\n\t\t\tcase 291: $function = 'LOGINV';\t\t\t$args = 3;\tbreak;\r\n\t\t\tcase 292: $function = 'NEGBINOMDIST';\t$args = 3;\tbreak;\r\n\t\t\tcase 293: $function = 'NORMDIST';\t\t$args = 4;\tbreak;\r\n\t\t\tcase 294: $function = 'NORMSDIST';\t\t$args = 1;\tbreak;\r\n\t\t\tcase 295: $function = 'NORMINV';\t\t$args = 3;\tbreak;\r\n\t\t\tcase 296: $function = 'NORMSINV';\t\t$args = 1;\tbreak;\r\n\t\t\tcase 297: $function = 'STANDARDIZE';\t$args = 3;\tbreak;\r\n\t\t\tcase 298: $function = 'ODD';\t\t\t$args = 1;\tbreak;\r\n\t\t\tcase 299: $function = 'PERMUT';\t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 300: $function = 'POISSON';\t\t$args = 3;\tbreak;\r\n\t\t\tcase 301: $function = 'TDIST';\t\t\t$args = 3;\tbreak;\r\n\t\t\tcase 302: $function = 'WEIBULL';\t\t$args = 4;\tbreak;\r\n\t\t\tcase 303: $function = 'SUMXMY2';\t\t$args = 2;\tbreak;\r\n\t\t\tcase 304: $function = 'SUMX2MY2';\t\t$args = 2;\tbreak;\r\n\t\t\tcase 305: $function = 'SUMX2PY2';\t\t$args = 2;\tbreak;\r\n\t\t\tcase 306: $function = 'CHITEST';\t\t$args = 2;\tbreak;\r\n\t\t\tcase 307: $function = 'CORREL';\t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 308: $function = 'COVAR';\t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 309: $function = 'FORECAST';\t\t$args = 3;\tbreak;\r\n\t\t\tcase 310: $function = 'FTEST';\t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 311: $function = 'INTERCEPT';\t\t$args = 2;\tbreak;\r\n\t\t\tcase 312: $function = 'PEARSON';\t\t$args = 2;\tbreak;\r\n\t\t\tcase 313: $function = 'RSQ';\t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 314: $function = 'STEYX';\t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 315: $function = 'SLOPE';\t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 316: $function = 'TTEST';\t\t\t$args = 4;\tbreak;\r\n\t\t\tcase 325: $function = 'LARGE';\t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 326: $function = 'SMALL';\t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 327: $function = 'QUARTILE';\t\t$args = 2;\tbreak;\r\n\t\t\tcase 328: $function = 'PERCENTILE';\t\t$args = 2;\tbreak;\r\n\t\t\tcase 331: $function = 'TRIMMEAN';\t\t$args = 2;\tbreak;\r\n\t\t\tcase 332: $function = 'TINV';\t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 337: $function = 'POWER';\t\t\t$args = 2;\tbreak;\r\n\t\t\tcase 342: $function = 'RADIANS';\t\t$args = 1;\tbreak;\r\n\t\t\tcase 343: $function = 'DEGREES';\t\t$args = 1;\tbreak;\r\n\t\t\tcase 346: $function = 'COUNTIF';\t\t$args = 2;\tbreak;\r\n\t\t\tcase 347: $function = 'COUNTBLANK';\t\t$args = 1;\tbreak;\r\n\t\t\tcase 350: $function = 'ISPMT';\t\t\t$args = 4;\tbreak;\r\n\t\t\tcase 351: $function = 'DATEDIF';\t\t$args = 3;\tbreak;\r\n\t\t\tcase 352: $function = 'DATESTRING';\t\t$args = 1;\tbreak;\r\n\t\t\tcase 353: $function = 'NUMBERSTRING';\t$args = 2;\tbreak;\r\n\t\t\tcase 360: $function = 'PHONETIC';\t\t$args = 1;\tbreak;\r\n\t\t\tcase 368: $function = 'BAHTTEXT';\t\t$args = 1;\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tthrow new PHPExcel_Reader_Exception('Unrecognized function in formula');\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\t$data = array('function' => $function, 'args' => $args);\r\n\t\t\tbreak;\r\n\t\tcase 0x22:\t//\tfunction with variable number of arguments\r\n\t\tcase 0x42:\r\n\t\tcase 0x62:\r\n\t\t\t$name = 'tFuncV';\r\n\t\t\t$size = 4;\r\n\t\t\t// offset: 1; size: 1; number of arguments\r\n\t\t\t$args = ord($formulaData[1]);\r\n\t\t\t// offset: 2: size: 2; index to built-in sheet function\r\n\t\t\t$index = self::_GetInt2d($formulaData, 2);\r\n\t\t\tswitch ($index) {\r\n\t\t\tcase   0: $function = 'COUNT';\t\t\tbreak;\r\n\t\t\tcase   1: $function = 'IF';\t\t\t\tbreak;\r\n\t\t\tcase   4: $function = 'SUM';\t\t\tbreak;\r\n\t\t\tcase   5: $function = 'AVERAGE';\t\tbreak;\r\n\t\t\tcase   6: $function = 'MIN';\t\t\tbreak;\r\n\t\t\tcase   7: $function = 'MAX';\t\t\tbreak;\r\n\t\t\tcase   8: $function = 'ROW';\t\t\tbreak;\r\n\t\t\tcase   9: $function = 'COLUMN';\t\t\tbreak;\r\n\t\t\tcase  11: $function = 'NPV';\t\t\tbreak;\r\n\t\t\tcase  12: $function = 'STDEV';\t\t\tbreak;\r\n\t\t\tcase  13: $function = 'DOLLAR';\t\t\tbreak;\r\n\t\t\tcase  14: $function = 'FIXED';\t\t\tbreak;\r\n\t\t\tcase  28: $function = 'LOOKUP';\t\t\tbreak;\r\n\t\t\tcase  29: $function = 'INDEX';\t\t\tbreak;\r\n\t\t\tcase  36: $function = 'AND';\t\t\tbreak;\r\n\t\t\tcase  37: $function = 'OR';\t\t\t\tbreak;\r\n\t\t\tcase  46: $function = 'VAR';\t\t\tbreak;\r\n\t\t\tcase  49: $function = 'LINEST';\t\t\tbreak;\r\n\t\t\tcase  50: $function = 'TREND';\t\t\tbreak;\r\n\t\t\tcase  51: $function = 'LOGEST';\t\t\tbreak;\r\n\t\t\tcase  52: $function = 'GROWTH';\t\t\tbreak;\r\n\t\t\tcase  56: $function = 'PV';\t\t\t\tbreak;\r\n\t\t\tcase  57: $function = 'FV';\t\t\t\tbreak;\r\n\t\t\tcase  58: $function = 'NPER';\t\t\tbreak;\r\n\t\t\tcase  59: $function = 'PMT';\t\t\tbreak;\r\n\t\t\tcase  60: $function = 'RATE';\t\t\tbreak;\r\n\t\t\tcase  62: $function = 'IRR';\t\t\tbreak;\r\n\t\t\tcase  64: $function = 'MATCH';\t\t\tbreak;\r\n\t\t\tcase  70: $function = 'WEEKDAY';\t\tbreak;\r\n\t\t\tcase  78: $function = 'OFFSET';\t\t\tbreak;\r\n\t\t\tcase  82: $function = 'SEARCH';\t\t\tbreak;\r\n\t\t\tcase 100: $function = 'CHOOSE';\t\t\tbreak;\r\n\t\t\tcase 101: $function = 'HLOOKUP';\t\tbreak;\r\n\t\t\tcase 102: $function = 'VLOOKUP';\t\tbreak;\r\n\t\t\tcase 109: $function = 'LOG';\t\t\tbreak;\r\n\t\t\tcase 115: $function = 'LEFT';\t\t\tbreak;\r\n\t\t\tcase 116: $function = 'RIGHT';\t\t\tbreak;\r\n\t\t\tcase 120: $function = 'SUBSTITUTE';\t\tbreak;\r\n\t\t\tcase 124: $function = 'FIND';\t\t\tbreak;\r\n\t\t\tcase 125: $function = 'CELL';\t\t\tbreak;\r\n\t\t\tcase 144: $function = 'DDB';\t\t\tbreak;\r\n\t\t\tcase 148: $function = 'INDIRECT';\t\tbreak;\r\n\t\t\tcase 167: $function = 'IPMT';\t\t\tbreak;\r\n\t\t\tcase 168: $function = 'PPMT';\t\t\tbreak;\r\n\t\t\tcase 169: $function = 'COUNTA';\t\t\tbreak;\r\n\t\t\tcase 183: $function = 'PRODUCT';\t\tbreak;\r\n\t\t\tcase 193: $function = 'STDEVP';\t\t\tbreak;\r\n\t\t\tcase 194: $function = 'VARP';\t\t\tbreak;\r\n\t\t\tcase 197: $function = 'TRUNC';\t\t\tbreak;\r\n\t\t\tcase 204: $function = 'USDOLLAR';\t\tbreak;\r\n\t\t\tcase 205: $function = 'FINDB';\t\t\tbreak;\r\n\t\t\tcase 206: $function = 'SEARCHB';\t\tbreak;\r\n\t\t\tcase 208: $function = 'LEFTB';\t\t\tbreak;\r\n\t\t\tcase 209: $function = 'RIGHTB';\t\t\tbreak;\r\n\t\t\tcase 216: $function = 'RANK';\t\t\tbreak;\r\n\t\t\tcase 219: $function = 'ADDRESS';\t\tbreak;\r\n\t\t\tcase 220: $function = 'DAYS360';\t\tbreak;\r\n\t\t\tcase 222: $function = 'VDB';\t\t\tbreak;\r\n\t\t\tcase 227: $function = 'MEDIAN';\t\t\tbreak;\r\n\t\t\tcase 228: $function = 'SUMPRODUCT';\t\tbreak;\r\n\t\t\tcase 247: $function = 'DB';\t\t\t\tbreak;\r\n\t\t\tcase 255: $function = '';\t\t\t\tbreak;\r\n\t\t\tcase 269: $function = 'AVEDEV';\t\t\tbreak;\r\n\t\t\tcase 270: $function = 'BETADIST';\t\tbreak;\r\n\t\t\tcase 272: $function = 'BETAINV';\t\tbreak;\r\n\t\t\tcase 317: $function = 'PROB';\t\t\tbreak;\r\n\t\t\tcase 318: $function = 'DEVSQ';\t\t\tbreak;\r\n\t\t\tcase 319: $function = 'GEOMEAN';\t\tbreak;\r\n\t\t\tcase 320: $function = 'HARMEAN';\t\tbreak;\r\n\t\t\tcase 321: $function = 'SUMSQ';\t\t\tbreak;\r\n\t\t\tcase 322: $function = 'KURT';\t\t\tbreak;\r\n\t\t\tcase 323: $function = 'SKEW';\t\t\tbreak;\r\n\t\t\tcase 324: $function = 'ZTEST';\t\t\tbreak;\r\n\t\t\tcase 329: $function = 'PERCENTRANK';\tbreak;\r\n\t\t\tcase 330: $function = 'MODE';\t\t\tbreak;\r\n\t\t\tcase 336: $function = 'CONCATENATE';\tbreak;\r\n\t\t\tcase 344: $function = 'SUBTOTAL';\t\tbreak;\r\n\t\t\tcase 345: $function = 'SUMIF';\t\t\tbreak;\r\n\t\t\tcase 354: $function = 'ROMAN';\t\t\tbreak;\r\n\t\t\tcase 358: $function = 'GETPIVOTDATA';\tbreak;\r\n\t\t\tcase 359: $function = 'HYPERLINK';\t\tbreak;\r\n\t\t\tcase 361: $function = 'AVERAGEA';\t\tbreak;\r\n\t\t\tcase 362: $function = 'MAXA';\t\t\tbreak;\r\n\t\t\tcase 363: $function = 'MINA';\t\t\tbreak;\r\n\t\t\tcase 364: $function = 'STDEVPA';\t\tbreak;\r\n\t\t\tcase 365: $function = 'VARPA';\t\t\tbreak;\r\n\t\t\tcase 366: $function = 'STDEVA';\t\t\tbreak;\r\n\t\t\tcase 367: $function = 'VARA';\t\t\tbreak;\r\n\t\t\tdefault:\r\n\t\t\t\tthrow new PHPExcel_Reader_Exception('Unrecognized function in formula');\r\n\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t\t$data = array('function' => $function, 'args' => $args);\r\n\t\t\tbreak;\r\n\t\tcase 0x23:\t//\tindex to defined name\r\n\t\tcase 0x43:\r\n\t\tcase 0x63:\r\n\t\t\t$name = 'tName';\r\n\t\t\t$size = 5;\r\n\t\t\t// offset: 1; size: 2; one-based index to definedname record\r\n\t\t\t$definedNameIndex = self::_GetInt2d($formulaData, 1) - 1;\r\n\t\t\t// offset: 2; size: 2; not used\r\n\t\t\t$data = $this->_definedname[$definedNameIndex]['name'];\r\n\t\t\tbreak;\r\n\t\tcase 0x24:\t//\tsingle cell reference e.g. A5\r\n\t\tcase 0x44:\r\n\t\tcase 0x64:\r\n\t\t\t$name = 'tRef';\r\n\t\t\t$size = 5;\r\n\t\t\t$data = $this->_readBIFF8CellAddress(substr($formulaData, 1, 4));\r\n\t\t\tbreak;\r\n\t\tcase 0x25:\t//\tcell range reference to cells in the same sheet (2d)\r\n\t\tcase 0x45:\r\n\t\tcase 0x65:\r\n\t\t\t$name = 'tArea';\r\n\t\t\t$size = 9;\r\n\t\t\t$data = $this->_readBIFF8CellRangeAddress(substr($formulaData, 1, 8));\r\n\t\t\tbreak;\r\n\t\tcase 0x26:\t//\tConstant reference sub-expression\r\n\t\tcase 0x46:\r\n\t\tcase 0x66:\r\n\t\t\t$name = 'tMemArea';\r\n\t\t\t// offset: 1; size: 4; not used\r\n\t\t\t// offset: 5; size: 2; size of the following subexpression\r\n\t\t\t$subSize = self::_GetInt2d($formulaData, 5);\r\n\t\t\t$size = 7 + $subSize;\r\n\t\t\t$data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize));\r\n\t\t\tbreak;\r\n\t\tcase 0x27:\t//\tDeleted constant reference sub-expression\r\n\t\tcase 0x47:\r\n\t\tcase 0x67:\r\n\t\t\t$name = 'tMemErr';\r\n\t\t\t// offset: 1; size: 4; not used\r\n\t\t\t// offset: 5; size: 2; size of the following subexpression\r\n\t\t\t$subSize = self::_GetInt2d($formulaData, 5);\r\n\t\t\t$size = 7 + $subSize;\r\n\t\t\t$data = $this->_getFormulaFromData(substr($formulaData, 7, $subSize));\r\n\t\t\tbreak;\r\n\t\tcase 0x29:\t//\tVariable reference sub-expression\r\n\t\tcase 0x49:\r\n\t\tcase 0x69:\r\n\t\t\t$name = 'tMemFunc';\r\n\t\t\t// offset: 1; size: 2; size of the following sub-expression\r\n\t\t\t$subSize = self::_GetInt2d($formulaData, 1);\r\n\t\t\t$size = 3 + $subSize;\r\n\t\t\t$data = $this->_getFormulaFromData(substr($formulaData, 3, $subSize));\r\n\t\t\tbreak;\r\n\r\n\t\tcase 0x2C: // Relative 2d cell reference reference, used in shared formulas and some other places\r\n\t\tcase 0x4C:\r\n\t\tcase 0x6C:\r\n\t\t\t$name = 'tRefN';\r\n\t\t\t$size = 5;\r\n\t\t\t$data = $this->_readBIFF8CellAddressB(substr($formulaData, 1, 4), $baseCell);\r\n\t\t\tbreak;\r\n\r\n\t\tcase 0x2D:\t//\tRelative 2d range reference\r\n\t\tcase 0x4D:\r\n\t\tcase 0x6D:\r\n\t\t\t$name = 'tAreaN';\r\n\t\t\t$size = 9;\r\n\t\t\t$data = $this->_readBIFF8CellRangeAddressB(substr($formulaData, 1, 8), $baseCell);\r\n\t\t\tbreak;\r\n\r\n\t\tcase 0x39:\t//\tExternal name\r\n\t\tcase 0x59:\r\n\t\tcase 0x79:\r\n\t\t\t$name = 'tNameX';\r\n\t\t\t$size = 7;\r\n\t\t\t// offset: 1; size: 2; index to REF entry in EXTERNSHEET record\r\n\t\t\t// offset: 3; size: 2; one-based index to DEFINEDNAME or EXTERNNAME record\r\n\t\t\t$index = self::_GetInt2d($formulaData, 3);\r\n\t\t\t// assume index is to EXTERNNAME record\r\n\t\t\t$data = $this->_externalNames[$index - 1]['name'];\r\n\t\t\t// offset: 5; size: 2; not used\r\n\t\t\tbreak;\r\n\r\n\t\tcase 0x3A:\t//\t3d reference to cell\r\n\t\tcase 0x5A:\r\n\t\tcase 0x7A:\r\n\t\t\t$name = 'tRef3d';\r\n\t\t\t$size = 7;\r\n\r\n\t\t\ttry {\r\n\t\t\t\t// offset: 1; size: 2; index to REF entry\r\n\t\t\t\t$sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1));\r\n\t\t\t\t// offset: 3; size: 4; cell address\r\n\t\t\t\t$cellAddress = $this->_readBIFF8CellAddress(substr($formulaData, 3, 4));\r\n\r\n\t\t\t\t$data = \"$sheetRange!$cellAddress\";\r\n\t\t\t} catch (PHPExcel_Exception $e) {\r\n\t\t\t\t// deleted sheet reference\r\n\t\t\t\t$data = '#REF!';\r\n\t\t\t}\r\n\r\n\t\t\tbreak;\r\n\t\tcase 0x3B:\t//\t3d reference to cell range\r\n\t\tcase 0x5B:\r\n\t\tcase 0x7B:\r\n\t\t\t$name = 'tArea3d';\r\n\t\t\t$size = 11;\r\n\r\n\t\t\ttry {\r\n\t\t\t\t// offset: 1; size: 2; index to REF entry\r\n\t\t\t\t$sheetRange = $this->_readSheetRangeByRefIndex(self::_GetInt2d($formulaData, 1));\r\n\t\t\t\t// offset: 3; size: 8; cell address\r\n\t\t\t\t$cellRangeAddress = $this->_readBIFF8CellRangeAddress(substr($formulaData, 3, 8));\r\n\r\n\t\t\t\t$data = \"$sheetRange!$cellRangeAddress\";\r\n\t\t\t} catch (PHPExcel_Exception $e) {\r\n\t\t\t\t// deleted sheet reference\r\n\t\t\t\t$data = '#REF!';\r\n\t\t\t}\r\n\r\n\t\t\tbreak;\r\n\t\t// Unknown cases\t// don't know how to deal with\r\n\t\tdefault:\r\n\t\t\tthrow new PHPExcel_Reader_Exception('Unrecognized token ' . sprintf('%02X', $id) . ' in formula');\r\n\t\t\tbreak;\r\n\t\t}\r\n\r\n\t\treturn array(\r\n\t\t\t'id' => $id,\r\n\t\t\t'name' => $name,\r\n\t\t\t'size' => $size,\r\n\t\t\t'data' => $data,\r\n\t\t);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Reads a cell address in BIFF8 e.g. 'A2' or '$A$2'\r\n\t * section 3.3.4\r\n\t *\r\n\t * @param string $cellAddressStructure\r\n\t * @return string\r\n\t */\r\n\tprivate function _readBIFF8CellAddress($cellAddressStructure)\r\n\t{\r\n\t\t// offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767))\r\n\t\t$row = self::_GetInt2d($cellAddressStructure, 0) + 1;\r\n\r\n\t\t// offset: 2; size: 2; index to column or column offset + relative flags\r\n\r\n\t\t\t// bit: 7-0; mask 0x00FF; column index\r\n\t\t\t$column = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($cellAddressStructure, 2));\r\n\r\n\t\t\t// bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index)\r\n\t\t\tif (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) {\r\n\t\t\t\t$column = '$' . $column;\r\n\t\t\t}\r\n\t\t\t// bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index)\r\n\t\t\tif (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) {\r\n\t\t\t\t$row = '$' . $row;\r\n\t\t\t}\r\n\r\n\t\treturn $column . $row;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Reads a cell address in BIFF8 for shared formulas. Uses positive and negative values for row and column\r\n\t * to indicate offsets from a base cell\r\n\t * section 3.3.4\r\n\t *\r\n\t * @param string $cellAddressStructure\r\n\t * @param string $baseCell Base cell, only needed when formula contains tRefN tokens, e.g. with shared formulas\r\n\t * @return string\r\n\t */\r\n\tprivate function _readBIFF8CellAddressB($cellAddressStructure, $baseCell = 'A1')\r\n\t{\r\n\t\tlist($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell);\r\n\t\t$baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1;\r\n\r\n\t\t// offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767))\r\n\t\t\t$rowIndex = self::_GetInt2d($cellAddressStructure, 0);\r\n\t\t\t$row = self::_GetInt2d($cellAddressStructure, 0) + 1;\r\n\r\n\t\t// offset: 2; size: 2; index to column or column offset + relative flags\r\n\r\n\t\t\t// bit: 7-0; mask 0x00FF; column index\r\n\t\t\t$colIndex = 0x00FF & self::_GetInt2d($cellAddressStructure, 2);\r\n\r\n\t\t\t// bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index)\r\n\t\t\tif (!(0x4000 & self::_GetInt2d($cellAddressStructure, 2))) {\r\n\t\t\t\t$column = PHPExcel_Cell::stringFromColumnIndex($colIndex);\r\n\t\t\t\t$column = '$' . $column;\r\n\t\t\t} else {\r\n\t\t\t\t$colIndex = ($colIndex <= 127) ? $colIndex : $colIndex - 256;\r\n\t\t\t\t$column = PHPExcel_Cell::stringFromColumnIndex($baseCol + $colIndex);\r\n\t\t\t}\r\n\r\n\t\t\t// bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index)\r\n\t\t\tif (!(0x8000 & self::_GetInt2d($cellAddressStructure, 2))) {\r\n\t\t\t\t$row = '$' . $row;\r\n\t\t\t} else {\r\n\t\t\t\t$rowIndex = ($rowIndex <= 32767) ? $rowIndex : $rowIndex - 65536;\r\n\t\t\t\t$row = $baseRow + $rowIndex;\r\n\t\t\t}\r\n\r\n\t\treturn $column . $row;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Reads a cell range address in BIFF5 e.g. 'A2:B6' or 'A1'\r\n\t * always fixed range\r\n\t * section 2.5.14\r\n\t *\r\n\t * @param string $subData\r\n\t * @return string\r\n\t * @throws PHPExcel_Reader_Exception\r\n\t */\r\n\tprivate function _readBIFF5CellRangeAddressFixed($subData)\r\n\t{\r\n\t\t// offset: 0; size: 2; index to first row\r\n\t\t$fr = self::_GetInt2d($subData, 0) + 1;\r\n\r\n\t\t// offset: 2; size: 2; index to last row\r\n\t\t$lr = self::_GetInt2d($subData, 2) + 1;\r\n\r\n\t\t// offset: 4; size: 1; index to first column\r\n\t\t$fc = ord($subData{4});\r\n\r\n\t\t// offset: 5; size: 1; index to last column\r\n\t\t$lc = ord($subData{5});\r\n\r\n\t\t// check values\r\n\t\tif ($fr > $lr || $fc > $lc) {\r\n\t\t\tthrow new PHPExcel_Reader_Exception('Not a cell range address');\r\n\t\t}\r\n\r\n\t\t// column index to letter\r\n\t\t$fc = PHPExcel_Cell::stringFromColumnIndex($fc);\r\n\t\t$lc = PHPExcel_Cell::stringFromColumnIndex($lc);\r\n\r\n\t\tif ($fr == $lr and $fc == $lc) {\r\n\t\t\treturn \"$fc$fr\";\r\n\t\t}\r\n\t\treturn \"$fc$fr:$lc$lr\";\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Reads a cell range address in BIFF8 e.g. 'A2:B6' or 'A1'\r\n\t * always fixed range\r\n\t * section 2.5.14\r\n\t *\r\n\t * @param string $subData\r\n\t * @return string\r\n\t * @throws PHPExcel_Reader_Exception\r\n\t */\r\n\tprivate function _readBIFF8CellRangeAddressFixed($subData)\r\n\t{\r\n\t\t// offset: 0; size: 2; index to first row\r\n\t\t$fr = self::_GetInt2d($subData, 0) + 1;\r\n\r\n\t\t// offset: 2; size: 2; index to last row\r\n\t\t$lr = self::_GetInt2d($subData, 2) + 1;\r\n\r\n\t\t// offset: 4; size: 2; index to first column\r\n\t\t$fc = self::_GetInt2d($subData, 4);\r\n\r\n\t\t// offset: 6; size: 2; index to last column\r\n\t\t$lc = self::_GetInt2d($subData, 6);\r\n\r\n\t\t// check values\r\n\t\tif ($fr > $lr || $fc > $lc) {\r\n\t\t\tthrow new PHPExcel_Reader_Exception('Not a cell range address');\r\n\t\t}\r\n\r\n\t\t// column index to letter\r\n\t\t$fc = PHPExcel_Cell::stringFromColumnIndex($fc);\r\n\t\t$lc = PHPExcel_Cell::stringFromColumnIndex($lc);\r\n\r\n\t\tif ($fr == $lr and $fc == $lc) {\r\n\t\t\treturn \"$fc$fr\";\r\n\t\t}\r\n\t\treturn \"$fc$fr:$lc$lr\";\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Reads a cell range address in BIFF8 e.g. 'A2:B6' or '$A$2:$B$6'\r\n\t * there are flags indicating whether column/row index is relative\r\n\t * section 3.3.4\r\n\t *\r\n\t * @param string $subData\r\n\t * @return string\r\n\t */\r\n\tprivate function _readBIFF8CellRangeAddress($subData)\r\n\t{\r\n\t\t// todo: if cell range is just a single cell, should this funciton\r\n\t\t// not just return e.g. 'A1' and not 'A1:A1' ?\r\n\r\n\t\t// offset: 0; size: 2; index to first row (0... 65535) (or offset (-32768... 32767))\r\n\t\t\t$fr = self::_GetInt2d($subData, 0) + 1;\r\n\r\n\t\t// offset: 2; size: 2; index to last row (0... 65535) (or offset (-32768... 32767))\r\n\t\t\t$lr = self::_GetInt2d($subData, 2) + 1;\r\n\r\n\t\t// offset: 4; size: 2; index to first column or column offset + relative flags\r\n\r\n\t\t// bit: 7-0; mask 0x00FF; column index\r\n\t\t$fc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 4));\r\n\r\n\t\t// bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index)\r\n\t\tif (!(0x4000 & self::_GetInt2d($subData, 4))) {\r\n\t\t\t$fc = '$' . $fc;\r\n\t\t}\r\n\r\n\t\t// bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index)\r\n\t\tif (!(0x8000 & self::_GetInt2d($subData, 4))) {\r\n\t\t\t$fr = '$' . $fr;\r\n\t\t}\r\n\r\n\t\t// offset: 6; size: 2; index to last column or column offset + relative flags\r\n\r\n\t\t// bit: 7-0; mask 0x00FF; column index\r\n\t\t$lc = PHPExcel_Cell::stringFromColumnIndex(0x00FF & self::_GetInt2d($subData, 6));\r\n\r\n\t\t// bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index)\r\n\t\tif (!(0x4000 & self::_GetInt2d($subData, 6))) {\r\n\t\t\t$lc = '$' . $lc;\r\n\t\t}\r\n\r\n\t\t// bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index)\r\n\t\tif (!(0x8000 & self::_GetInt2d($subData, 6))) {\r\n\t\t\t$lr = '$' . $lr;\r\n\t\t}\r\n\r\n\t\treturn \"$fc$fr:$lc$lr\";\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Reads a cell range address in BIFF8 for shared formulas. Uses positive and negative values for row and column\r\n\t * to indicate offsets from a base cell\r\n\t * section 3.3.4\r\n\t *\r\n\t * @param string $subData\r\n\t * @param string $baseCell Base cell\r\n\t * @return string Cell range address\r\n\t */\r\n\tprivate function _readBIFF8CellRangeAddressB($subData, $baseCell = 'A1')\r\n\t{\r\n\t\tlist($baseCol, $baseRow) = PHPExcel_Cell::coordinateFromString($baseCell);\r\n\t\t$baseCol = PHPExcel_Cell::columnIndexFromString($baseCol) - 1;\r\n\r\n\t\t// TODO: if cell range is just a single cell, should this funciton\r\n\t\t// not just return e.g. 'A1' and not 'A1:A1' ?\r\n\r\n\t\t// offset: 0; size: 2; first row\r\n\t\t$frIndex = self::_GetInt2d($subData, 0); // adjust below\r\n\r\n\t\t// offset: 2; size: 2; relative index to first row (0... 65535) should be treated as offset (-32768... 32767)\r\n\t\t$lrIndex = self::_GetInt2d($subData, 2); // adjust below\r\n\r\n\t\t// offset: 4; size: 2; first column with relative/absolute flags\r\n\r\n\t\t// bit: 7-0; mask 0x00FF; column index\r\n\t\t$fcIndex = 0x00FF & self::_GetInt2d($subData, 4);\r\n\r\n\t\t// bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index)\r\n\t\tif (!(0x4000 & self::_GetInt2d($subData, 4))) {\r\n\t\t\t// absolute column index\r\n\t\t\t$fc = PHPExcel_Cell::stringFromColumnIndex($fcIndex);\r\n\t\t\t$fc = '$' . $fc;\r\n\t\t} else {\r\n\t\t\t// column offset\r\n\t\t\t$fcIndex = ($fcIndex <= 127) ? $fcIndex : $fcIndex - 256;\r\n\t\t\t$fc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $fcIndex);\r\n\t\t}\r\n\r\n\t\t// bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index)\r\n\t\tif (!(0x8000 & self::_GetInt2d($subData, 4))) {\r\n\t\t\t// absolute row index\r\n\t\t\t$fr = $frIndex + 1;\r\n\t\t\t$fr = '$' . $fr;\r\n\t\t} else {\r\n\t\t\t// row offset\r\n\t\t\t$frIndex = ($frIndex <= 32767) ? $frIndex : $frIndex - 65536;\r\n\t\t\t$fr = $baseRow + $frIndex;\r\n\t\t}\r\n\r\n\t\t// offset: 6; size: 2; last column with relative/absolute flags\r\n\r\n\t\t// bit: 7-0; mask 0x00FF; column index\r\n\t\t$lcIndex = 0x00FF & self::_GetInt2d($subData, 6);\r\n\t\t$lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256;\r\n\t\t$lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex);\r\n\r\n\t\t// bit: 14; mask 0x4000; (1 = relative column index, 0 = absolute column index)\r\n\t\tif (!(0x4000 & self::_GetInt2d($subData, 6))) {\r\n\t\t\t// absolute column index\r\n\t\t\t$lc = PHPExcel_Cell::stringFromColumnIndex($lcIndex);\r\n\t\t\t$lc = '$' . $lc;\r\n\t\t} else {\r\n\t\t\t// column offset\r\n\t\t\t$lcIndex = ($lcIndex <= 127) ? $lcIndex : $lcIndex - 256;\r\n\t\t\t$lc = PHPExcel_Cell::stringFromColumnIndex($baseCol + $lcIndex);\r\n\t\t}\r\n\r\n\t\t// bit: 15; mask 0x8000; (1 = relative row index, 0 = absolute row index)\r\n\t\tif (!(0x8000 & self::_GetInt2d($subData, 6))) {\r\n\t\t\t// absolute row index\r\n\t\t\t$lr = $lrIndex + 1;\r\n\t\t\t$lr = '$' . $lr;\r\n\t\t} else {\r\n\t\t\t// row offset\r\n\t\t\t$lrIndex = ($lrIndex <= 32767) ? $lrIndex : $lrIndex - 65536;\r\n\t\t\t$lr = $baseRow + $lrIndex;\r\n\t\t}\r\n\r\n\t\treturn \"$fc$fr:$lc$lr\";\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read BIFF8 cell range address list\r\n\t * section 2.5.15\r\n\t *\r\n\t * @param string $subData\r\n\t * @return array\r\n\t */\r\n\tprivate function _readBIFF8CellRangeAddressList($subData)\r\n\t{\r\n\t\t$cellRangeAddresses = array();\r\n\r\n\t\t// offset: 0; size: 2; number of the following cell range addresses\r\n\t\t$nm = self::_GetInt2d($subData, 0);\r\n\r\n\t\t$offset = 2;\r\n\t\t// offset: 2; size: 8 * $nm; list of $nm (fixed) cell range addresses\r\n\t\tfor ($i = 0; $i < $nm; ++$i) {\r\n\t\t\t$cellRangeAddresses[] = $this->_readBIFF8CellRangeAddressFixed(substr($subData, $offset, 8));\r\n\t\t\t$offset += 8;\r\n\t\t}\r\n\r\n\t\treturn array(\r\n\t\t\t'size' => 2 + 8 * $nm,\r\n\t\t\t'cellRangeAddresses' => $cellRangeAddresses,\r\n\t\t);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read BIFF5 cell range address list\r\n\t * section 2.5.15\r\n\t *\r\n\t * @param string $subData\r\n\t * @return array\r\n\t */\r\n\tprivate function _readBIFF5CellRangeAddressList($subData)\r\n\t{\r\n\t\t$cellRangeAddresses = array();\r\n\r\n\t\t// offset: 0; size: 2; number of the following cell range addresses\r\n\t\t$nm = self::_GetInt2d($subData, 0);\r\n\r\n\t\t$offset = 2;\r\n\t\t// offset: 2; size: 6 * $nm; list of $nm (fixed) cell range addresses\r\n\t\tfor ($i = 0; $i < $nm; ++$i) {\r\n\t\t\t$cellRangeAddresses[] = $this->_readBIFF5CellRangeAddressFixed(substr($subData, $offset, 6));\r\n\t\t\t$offset += 6;\r\n\t\t}\r\n\r\n\t\treturn array(\r\n\t\t\t'size' => 2 + 6 * $nm,\r\n\t\t\t'cellRangeAddresses' => $cellRangeAddresses,\r\n\t\t);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Get a sheet range like Sheet1:Sheet3 from REF index\r\n\t * Note: If there is only one sheet in the range, one gets e.g Sheet1\r\n\t * It can also happen that the REF structure uses the -1 (FFFF) code to indicate deleted sheets,\r\n\t * in which case an PHPExcel_Reader_Exception is thrown\r\n\t *\r\n\t * @param int $index\r\n\t * @return string|false\r\n\t * @throws PHPExcel_Reader_Exception\r\n\t */\r\n\tprivate function _readSheetRangeByRefIndex($index)\r\n\t{\r\n\t\tif (isset($this->_ref[$index])) {\r\n\r\n\t\t\t$type = $this->_externalBooks[$this->_ref[$index]['externalBookIndex']]['type'];\r\n\r\n\t\t\tswitch ($type) {\r\n\t\t\t\tcase 'internal':\r\n\t\t\t\t\t// check if we have a deleted 3d reference\r\n\t\t\t\t\tif ($this->_ref[$index]['firstSheetIndex'] == 0xFFFF or $this->_ref[$index]['lastSheetIndex'] == 0xFFFF) {\r\n\t\t\t\t\t\tthrow new PHPExcel_Reader_Exception('Deleted sheet reference');\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// we have normal sheet range (collapsed or uncollapsed)\r\n\t\t\t\t\t$firstSheetName = $this->_sheets[$this->_ref[$index]['firstSheetIndex']]['name'];\r\n\t\t\t\t\t$lastSheetName = $this->_sheets[$this->_ref[$index]['lastSheetIndex']]['name'];\r\n\r\n\t\t\t\t\tif ($firstSheetName == $lastSheetName) {\r\n\t\t\t\t\t\t// collapsed sheet range\r\n\t\t\t\t\t\t$sheetRange = $firstSheetName;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\t$sheetRange = \"$firstSheetName:$lastSheetName\";\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\t// escape the single-quotes\r\n\t\t\t\t\t$sheetRange = str_replace(\"'\", \"''\", $sheetRange);\r\n\r\n\t\t\t\t\t// if there are special characters, we need to enclose the range in single-quotes\r\n\t\t\t\t\t// todo: check if we have identified the whole set of special characters\r\n\t\t\t\t\t// it seems that the following characters are not accepted for sheet names\r\n\t\t\t\t\t// and we may assume that they are not present: []*/:\\?\r\n\t\t\t\t\tif (preg_match(\"/[ !\\\"@#£$%&{()}<>=+'|^,;-]/\", $sheetRange)) {\r\n\t\t\t\t\t\t$sheetRange = \"'$sheetRange'\";\r\n\t\t\t\t\t}\r\n\r\n\t\t\t\t\treturn $sheetRange;\r\n\t\t\t\t\tbreak;\r\n\r\n\t\t\t\tdefault:\r\n\t\t\t\t\t// TODO: external sheet support\r\n\t\t\t\t\tthrow new PHPExcel_Reader_Exception('Excel5 reader only supports internal sheets in fomulas');\r\n\t\t\t\t\tbreak;\r\n\t\t\t}\r\n\t\t}\r\n\t\treturn false;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * read BIFF8 constant value array from array data\r\n\t * returns e.g. array('value' => '{1,2;3,4}', 'size' => 40}\r\n\t * section 2.5.8\r\n\t *\r\n\t * @param string $arrayData\r\n\t * @return array\r\n\t */\r\n\tprivate static function _readBIFF8ConstantArray($arrayData)\r\n\t{\r\n\t\t// offset: 0; size: 1; number of columns decreased by 1\r\n\t\t$nc = ord($arrayData[0]);\r\n\r\n\t\t// offset: 1; size: 2; number of rows decreased by 1\r\n\t\t$nr = self::_GetInt2d($arrayData, 1);\r\n\t\t$size = 3; // initialize\r\n\t\t$arrayData = substr($arrayData, 3);\r\n\r\n\t\t// offset: 3; size: var; list of ($nc + 1) * ($nr + 1) constant values\r\n\t\t$matrixChunks = array();\r\n\t\tfor ($r = 1; $r <= $nr + 1; ++$r) {\r\n\t\t\t$items = array();\r\n\t\t\tfor ($c = 1; $c <= $nc + 1; ++$c) {\r\n\t\t\t\t$constant = self::_readBIFF8Constant($arrayData);\r\n\t\t\t\t$items[] = $constant['value'];\r\n\t\t\t\t$arrayData = substr($arrayData, $constant['size']);\r\n\t\t\t\t$size += $constant['size'];\r\n\t\t\t}\r\n\t\t\t$matrixChunks[] = implode(',', $items); // looks like e.g. '1,\"hello\"'\r\n\t\t}\r\n\t\t$matrix = '{' . implode(';', $matrixChunks) . '}';\r\n\r\n\t\treturn array(\r\n\t\t\t'value' => $matrix,\r\n\t\t\t'size' => $size,\r\n\t\t);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * read BIFF8 constant value which may be 'Empty Value', 'Number', 'String Value', 'Boolean Value', 'Error Value'\r\n\t * section 2.5.7\r\n\t * returns e.g. array('value' => '5', 'size' => 9)\r\n\t *\r\n\t * @param string $valueData\r\n\t * @return array\r\n\t */\r\n\tprivate static function _readBIFF8Constant($valueData)\r\n\t{\r\n\t\t// offset: 0; size: 1; identifier for type of constant\r\n\t\t$identifier = ord($valueData[0]);\r\n\r\n\t\tswitch ($identifier) {\r\n\t\tcase 0x00: // empty constant (what is this?)\r\n\t\t\t$value = '';\r\n\t\t\t$size = 9;\r\n\t\t\tbreak;\r\n\t\tcase 0x01: // number\r\n\t\t\t// offset: 1; size: 8; IEEE 754 floating-point value\r\n\t\t\t$value = self::_extractNumber(substr($valueData, 1, 8));\r\n\t\t\t$size = 9;\r\n\t\t\tbreak;\r\n\t\tcase 0x02: // string value\r\n\t\t\t// offset: 1; size: var; Unicode string, 16-bit string length\r\n\t\t\t$string = self::_readUnicodeStringLong(substr($valueData, 1));\r\n\t\t\t$value = '\"' . $string['value'] . '\"';\r\n\t\t\t$size = 1 + $string['size'];\r\n\t\t\tbreak;\r\n\t\tcase 0x04: // boolean\r\n\t\t\t// offset: 1; size: 1; 0 = FALSE, 1 = TRUE\r\n\t\t\tif (ord($valueData[1])) {\r\n\t\t\t\t$value = 'TRUE';\r\n\t\t\t} else {\r\n\t\t\t\t$value = 'FALSE';\r\n\t\t\t}\r\n\t\t\t$size = 9;\r\n\t\t\tbreak;\r\n\t\tcase 0x10: // error code\r\n\t\t\t// offset: 1; size: 1; error code\r\n\t\t\t$value = self::_mapErrorCode(ord($valueData[1]));\r\n\t\t\t$size = 9;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t\treturn array(\r\n\t\t\t'value' => $value,\r\n\t\t\t'size' => $size,\r\n\t\t);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Extract RGB color\r\n\t * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.4\r\n\t *\r\n\t * @param string $rgb Encoded RGB value (4 bytes)\r\n\t * @return array\r\n\t */\r\n\tprivate static function _readRGB($rgb)\r\n\t{\r\n\t\t// offset: 0; size 1; Red component\r\n\t\t$r = ord($rgb{0});\r\n\r\n\t\t// offset: 1; size: 1; Green component\r\n\t\t$g = ord($rgb{1});\r\n\r\n\t\t// offset: 2; size: 1; Blue component\r\n\t\t$b = ord($rgb{2});\r\n\r\n\t\t// HEX notation, e.g. 'FF00FC'\r\n\t\t$rgb = sprintf('%02X%02X%02X', $r, $g, $b);\r\n\r\n\t\treturn array('rgb' => $rgb);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read byte string (8-bit string length)\r\n\t * OpenOffice documentation: 2.5.2\r\n\t *\r\n\t * @param string $subData\r\n\t * @return array\r\n\t */\r\n\tprivate function _readByteStringShort($subData)\r\n\t{\r\n\t\t// offset: 0; size: 1; length of the string (character count)\r\n\t\t$ln = ord($subData[0]);\r\n\r\n\t\t// offset: 1: size: var; character array (8-bit characters)\r\n\t\t$value = $this->_decodeCodepage(substr($subData, 1, $ln));\r\n\r\n\t\treturn array(\r\n\t\t\t'value' => $value,\r\n\t\t\t'size' => 1 + $ln, // size in bytes of data structure\r\n\t\t);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read byte string (16-bit string length)\r\n\t * OpenOffice documentation: 2.5.2\r\n\t *\r\n\t * @param string $subData\r\n\t * @return array\r\n\t */\r\n\tprivate function _readByteStringLong($subData)\r\n\t{\r\n\t\t// offset: 0; size: 2; length of the string (character count)\r\n\t\t$ln = self::_GetInt2d($subData, 0);\r\n\r\n\t\t// offset: 2: size: var; character array (8-bit characters)\r\n\t\t$value = $this->_decodeCodepage(substr($subData, 2));\r\n\r\n\t\t//return $string;\r\n\t\treturn array(\r\n\t\t\t'value' => $value,\r\n\t\t\t'size' => 2 + $ln, // size in bytes of data structure\r\n\t\t);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Extracts an Excel Unicode short string (8-bit string length)\r\n\t * OpenOffice documentation: 2.5.3\r\n\t * function will automatically find out where the Unicode string ends.\r\n\t *\r\n\t * @param string $subData\r\n\t * @return array\r\n\t */\r\n\tprivate static function _readUnicodeStringShort($subData)\r\n\t{\r\n\t\t$value = '';\r\n\r\n\t\t// offset: 0: size: 1; length of the string (character count)\r\n\t\t$characterCount = ord($subData[0]);\r\n\r\n\t\t$string = self::_readUnicodeString(substr($subData, 1), $characterCount);\r\n\r\n\t\t// add 1 for the string length\r\n\t\t$string['size'] += 1;\r\n\r\n\t\treturn $string;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Extracts an Excel Unicode long string (16-bit string length)\r\n\t * OpenOffice documentation: 2.5.3\r\n\t * this function is under construction, needs to support rich text, and Asian phonetic settings\r\n\t *\r\n\t * @param string $subData\r\n\t * @return array\r\n\t */\r\n\tprivate static function _readUnicodeStringLong($subData)\r\n\t{\r\n\t\t$value = '';\r\n\r\n\t\t// offset: 0: size: 2; length of the string (character count)\r\n\t\t$characterCount = self::_GetInt2d($subData, 0);\r\n\r\n\t\t$string = self::_readUnicodeString(substr($subData, 2), $characterCount);\r\n\r\n\t\t// add 2 for the string length\r\n\t\t$string['size'] += 2;\r\n\r\n\t\treturn $string;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read Unicode string with no string length field, but with known character count\r\n\t * this function is under construction, needs to support rich text, and Asian phonetic settings\r\n\t * OpenOffice.org's Documentation of the Microsoft Excel File Format, section 2.5.3\r\n\t *\r\n\t * @param string $subData\r\n\t * @param int $characterCount\r\n\t * @return array\r\n\t */\r\n\tprivate static function _readUnicodeString($subData, $characterCount)\r\n\t{\r\n\t\t$value = '';\r\n\r\n\t\t// offset: 0: size: 1; option flags\r\n\r\n\t\t\t// bit: 0; mask: 0x01; character compression (0 = compressed 8-bit, 1 = uncompressed 16-bit)\r\n\t\t\t$isCompressed = !((0x01 & ord($subData[0])) >> 0);\r\n\r\n\t\t\t// bit: 2; mask: 0x04; Asian phonetic settings\r\n\t\t\t$hasAsian = (0x04) & ord($subData[0]) >> 2;\r\n\r\n\t\t\t// bit: 3; mask: 0x08; Rich-Text settings\r\n\t\t\t$hasRichText = (0x08) & ord($subData[0]) >> 3;\r\n\r\n\t\t// offset: 1: size: var; character array\r\n\t\t// this offset assumes richtext and Asian phonetic settings are off which is generally wrong\r\n\t\t// needs to be fixed\r\n\t\t$value = self::_encodeUTF16(substr($subData, 1, $isCompressed ? $characterCount : 2 * $characterCount), $isCompressed);\r\n\r\n\t\treturn array(\r\n\t\t\t'value' => $value,\r\n\t\t\t'size' => $isCompressed ? 1 + $characterCount : 1 + 2 * $characterCount, // the size in bytes including the option flags\r\n\t\t);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Convert UTF-8 string to string surounded by double quotes. Used for explicit string tokens in formulas.\r\n\t * Example:  hello\"world  -->  \"hello\"\"world\"\r\n\t *\r\n\t * @param string $value UTF-8 encoded string\r\n\t * @return string\r\n\t */\r\n\tprivate static function _UTF8toExcelDoubleQuoted($value)\r\n\t{\r\n\t\treturn '\"' . str_replace('\"', '\"\"', $value) . '\"';\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Reads first 8 bytes of a string and return IEEE 754 float\r\n\t *\r\n\t * @param string $data Binary string that is at least 8 bytes long\r\n\t * @return float\r\n\t */\r\n\tprivate static function _extractNumber($data)\r\n\t{\r\n\t\t$rknumhigh = self::_GetInt4d($data, 4);\r\n\t\t$rknumlow = self::_GetInt4d($data, 0);\r\n\t\t$sign = ($rknumhigh & 0x80000000) >> 31;\r\n\t\t$exp = (($rknumhigh & 0x7ff00000) >> 20) - 1023;\r\n\t\t$mantissa = (0x100000 | ($rknumhigh & 0x000fffff));\r\n\t\t$mantissalow1 = ($rknumlow & 0x80000000) >> 31;\r\n\t\t$mantissalow2 = ($rknumlow & 0x7fffffff);\r\n\t\t$value = $mantissa / pow( 2 , (20 - $exp));\r\n\r\n\t\tif ($mantissalow1 != 0) {\r\n\t\t\t$value += 1 / pow (2 , (21 - $exp));\r\n\t\t}\r\n\r\n\t\t$value += $mantissalow2 / pow (2 , (52 - $exp));\r\n\t\tif ($sign) {\r\n\t\t\t$value *= -1;\r\n\t\t}\r\n\r\n\t\treturn $value;\r\n\t}\r\n\r\n\r\n\tprivate static function _GetIEEE754($rknum)\r\n\t{\r\n\t\tif (($rknum & 0x02) != 0) {\r\n\t\t\t$value = $rknum >> 2;\r\n\t\t} else {\r\n\t\t\t// changes by mmp, info on IEEE754 encoding from\r\n\t\t\t// research.microsoft.com/~hollasch/cgindex/coding/ieeefloat.html\r\n\t\t\t// The RK format calls for using only the most significant 30 bits\r\n\t\t\t// of the 64 bit floating point value. The other 34 bits are assumed\r\n\t\t\t// to be 0 so we use the upper 30 bits of $rknum as follows...\r\n\t\t\t$sign = ($rknum & 0x80000000) >> 31;\r\n\t\t\t$exp = ($rknum & 0x7ff00000) >> 20;\r\n\t\t\t$mantissa = (0x100000 | ($rknum & 0x000ffffc));\r\n\t\t\t$value = $mantissa / pow( 2 , (20- ($exp - 1023)));\r\n\t\t\tif ($sign) {\r\n\t\t\t\t$value = -1 * $value;\r\n\t\t\t}\r\n\t\t\t//end of changes by mmp\r\n\t\t}\r\n\t\tif (($rknum & 0x01) != 0) {\r\n\t\t\t$value /= 100;\r\n\t\t}\r\n\t\treturn $value;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Get UTF-8 string from (compressed or uncompressed) UTF-16 string\r\n\t *\r\n\t * @param string $string\r\n\t * @param bool $compressed\r\n\t * @return string\r\n\t */\r\n\tprivate static function _encodeUTF16($string, $compressed = '')\r\n\t{\r\n\t\tif ($compressed) {\r\n\t\t\t$string = self::_uncompressByteString($string);\r\n \t\t}\r\n\r\n\t\treturn PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', 'UTF-16LE');\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Convert UTF-16 string in compressed notation to uncompressed form. Only used for BIFF8.\r\n\t *\r\n\t * @param string $string\r\n\t * @return string\r\n\t */\r\n\tprivate static function _uncompressByteString($string)\r\n\t{\r\n\t\t$uncompressedString = '';\r\n\t\t$strLen = strlen($string);\r\n\t\tfor ($i = 0; $i < $strLen; ++$i) {\r\n\t\t\t$uncompressedString .= $string[$i] . \"\\0\";\r\n\t\t}\r\n\r\n\t\treturn $uncompressedString;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Convert string to UTF-8. Only used for BIFF5.\r\n\t *\r\n\t * @param string $string\r\n\t * @return string\r\n\t */\r\n\tprivate function _decodeCodepage($string)\r\n\t{\r\n\t\treturn PHPExcel_Shared_String::ConvertEncoding($string, 'UTF-8', $this->_codepage);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read 16-bit unsigned integer\r\n\t *\r\n\t * @param string $data\r\n\t * @param int $pos\r\n\t * @return int\r\n\t */\r\n\tpublic static function _GetInt2d($data, $pos)\r\n\t{\r\n\t\treturn ord($data[$pos]) | (ord($data[$pos+1]) << 8);\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read 32-bit signed integer\r\n\t *\r\n\t * @param string $data\r\n\t * @param int $pos\r\n\t * @return int\r\n\t */\r\n\tpublic static function _GetInt4d($data, $pos)\r\n\t{\r\n\t\t// FIX: represent numbers correctly on 64-bit system\r\n\t\t// http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334\r\n\t\t// Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems\r\n\t\t$_or_24 = ord($data[$pos + 3]);\r\n\t\tif ($_or_24 >= 128) {\r\n\t\t\t// negative number\r\n\t\t\t$_ord_24 = -abs((256 - $_or_24) << 24);\r\n\t\t} else {\r\n\t\t\t$_ord_24 = ($_or_24 & 127) << 24;\r\n\t\t}\r\n\t\treturn ord($data[$pos]) | (ord($data[$pos+1]) << 8) | (ord($data[$pos+2]) << 16) | $_ord_24;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Read color\r\n\t *\r\n\t * @param int $color Indexed color\r\n\t * @param array $palette Color palette\r\n\t * @return array RGB color value, example: array('rgb' => 'FF0000')\r\n\t */\r\n\tprivate static function _readColor($color,$palette,$version)\r\n\t{\r\n\t\tif ($color <= 0x07 || $color >= 0x40) {\r\n\t\t\t// special built-in color\r\n\t\t\treturn self::_mapBuiltInColor($color);\r\n\t\t} elseif (isset($palette) && isset($palette[$color - 8])) {\r\n\t\t\t// palette color, color index 0x08 maps to pallete index 0\r\n\t\t\treturn $palette[$color - 8];\r\n\t\t} else {\r\n\t\t\t// default color table\r\n\t\t\tif ($version == self::XLS_BIFF8) {\r\n\t\t\t\treturn self::_mapColor($color);\r\n\t\t\t} else {\r\n\t\t\t\t// BIFF5\r\n\t\t\t\treturn self::_mapColorBIFF5($color);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\treturn $color;\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Map border style\r\n\t * OpenOffice documentation: 2.5.11\r\n\t *\r\n\t * @param int $index\r\n\t * @return string\r\n\t */\r\n\tprivate static function _mapBorderStyle($index)\r\n\t{\r\n\t\tswitch ($index) {\r\n\t\t\tcase 0x00: return PHPExcel_Style_Border::BORDER_NONE;\r\n\t\t\tcase 0x01: return PHPExcel_Style_Border::BORDER_THIN;\r\n\t\t\tcase 0x02: return PHPExcel_Style_Border::BORDER_MEDIUM;\r\n\t\t\tcase 0x03: return PHPExcel_Style_Border::BORDER_DASHED;\r\n\t\t\tcase 0x04: return PHPExcel_Style_Border::BORDER_DOTTED;\r\n\t\t\tcase 0x05: return PHPExcel_Style_Border::BORDER_THICK;\r\n\t\t\tcase 0x06: return PHPExcel_Style_Border::BORDER_DOUBLE;\r\n\t\t\tcase 0x07: return PHPExcel_Style_Border::BORDER_HAIR;\r\n\t\t\tcase 0x08: return PHPExcel_Style_Border::BORDER_MEDIUMDASHED;\r\n\t\t\tcase 0x09: return PHPExcel_Style_Border::BORDER_DASHDOT;\r\n\t\t\tcase 0x0A: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT;\r\n\t\t\tcase 0x0B: return PHPExcel_Style_Border::BORDER_DASHDOTDOT;\r\n\t\t\tcase 0x0C: return PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT;\r\n\t\t\tcase 0x0D: return PHPExcel_Style_Border::BORDER_SLANTDASHDOT;\r\n\t\t\tdefault:   return PHPExcel_Style_Border::BORDER_NONE;\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Get fill pattern from index\r\n\t * OpenOffice documentation: 2.5.12\r\n\t *\r\n\t * @param int $index\r\n\t * @return string\r\n\t */\r\n\tprivate static function _mapFillPattern($index)\r\n\t{\r\n\t\tswitch ($index) {\r\n\t\t\tcase 0x00: return PHPExcel_Style_Fill::FILL_NONE;\r\n\t\t\tcase 0x01: return PHPExcel_Style_Fill::FILL_SOLID;\r\n\t\t\tcase 0x02: return PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY;\r\n\t\t\tcase 0x03: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY;\r\n\t\t\tcase 0x04: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY;\r\n\t\t\tcase 0x05: return PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL;\r\n\t\t\tcase 0x06: return PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL;\r\n\t\t\tcase 0x07: return PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN;\r\n\t\t\tcase 0x08: return PHPExcel_Style_Fill::FILL_PATTERN_DARKUP;\r\n\t\t\tcase 0x09: return PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID;\r\n\t\t\tcase 0x0A: return PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS;\r\n\t\t\tcase 0x0B: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL;\r\n\t\t\tcase 0x0C: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL;\r\n\t\t\tcase 0x0D: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN;\r\n\t\t\tcase 0x0E: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP;\r\n\t\t\tcase 0x0F: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID;\r\n\t\t\tcase 0x10: return PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS;\r\n\t\t\tcase 0x11: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY125;\r\n\t\t\tcase 0x12: return PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625;\r\n\t\t\tdefault:   return PHPExcel_Style_Fill::FILL_NONE;\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Map error code, e.g. '#N/A'\r\n\t *\r\n\t * @param int $subData\r\n\t * @return string\r\n\t */\r\n\tprivate static function _mapErrorCode($subData)\r\n\t{\r\n\t\tswitch ($subData) {\r\n\t\t\tcase 0x00: return '#NULL!';\t\tbreak;\r\n\t\t\tcase 0x07: return '#DIV/0!';\tbreak;\r\n\t\t\tcase 0x0F: return '#VALUE!';\tbreak;\r\n\t\t\tcase 0x17: return '#REF!';\t\tbreak;\r\n\t\t\tcase 0x1D: return '#NAME?';\t\tbreak;\r\n\t\t\tcase 0x24: return '#NUM!';\t\tbreak;\r\n\t\t\tcase 0x2A: return '#N/A';\t\tbreak;\r\n\t\t\tdefault: return false;\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Map built-in color to RGB value\r\n\t *\r\n\t * @param int $color Indexed color\r\n\t * @return array\r\n\t */\r\n\tprivate static function _mapBuiltInColor($color)\r\n\t{\r\n\t\tswitch ($color) {\r\n\t\t\tcase 0x00: return array('rgb' => '000000');\r\n\t\t\tcase 0x01: return array('rgb' => 'FFFFFF');\r\n\t\t\tcase 0x02: return array('rgb' => 'FF0000');\r\n\t\t\tcase 0x03: return array('rgb' => '00FF00');\r\n\t\t\tcase 0x04: return array('rgb' => '0000FF');\r\n\t\t\tcase 0x05: return array('rgb' => 'FFFF00');\r\n\t\t\tcase 0x06: return array('rgb' => 'FF00FF');\r\n\t\t\tcase 0x07: return array('rgb' => '00FFFF');\r\n\t\t\tcase 0x40: return array('rgb' => '000000'); // system window text color\r\n\t\t\tcase 0x41: return array('rgb' => 'FFFFFF'); // system window background color\r\n\t\t\tdefault:   return array('rgb' => '000000');\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Map color array from BIFF5 built-in color index\r\n\t *\r\n\t * @param int $subData\r\n\t * @return array\r\n\t */\r\n\tprivate static function _mapColorBIFF5($subData)\r\n\t{\r\n\t\tswitch ($subData) {\r\n\t\t\tcase 0x08: return array('rgb' => '000000');\r\n\t\t\tcase 0x09: return array('rgb' => 'FFFFFF');\r\n\t\t\tcase 0x0A: return array('rgb' => 'FF0000');\r\n\t\t\tcase 0x0B: return array('rgb' => '00FF00');\r\n\t\t\tcase 0x0C: return array('rgb' => '0000FF');\r\n\t\t\tcase 0x0D: return array('rgb' => 'FFFF00');\r\n\t\t\tcase 0x0E: return array('rgb' => 'FF00FF');\r\n\t\t\tcase 0x0F: return array('rgb' => '00FFFF');\r\n\t\t\tcase 0x10: return array('rgb' => '800000');\r\n\t\t\tcase 0x11: return array('rgb' => '008000');\r\n\t\t\tcase 0x12: return array('rgb' => '000080');\r\n\t\t\tcase 0x13: return array('rgb' => '808000');\r\n\t\t\tcase 0x14: return array('rgb' => '800080');\r\n\t\t\tcase 0x15: return array('rgb' => '008080');\r\n\t\t\tcase 0x16: return array('rgb' => 'C0C0C0');\r\n\t\t\tcase 0x17: return array('rgb' => '808080');\r\n\t\t\tcase 0x18: return array('rgb' => '8080FF');\r\n\t\t\tcase 0x19: return array('rgb' => '802060');\r\n\t\t\tcase 0x1A: return array('rgb' => 'FFFFC0');\r\n\t\t\tcase 0x1B: return array('rgb' => 'A0E0F0');\r\n\t\t\tcase 0x1C: return array('rgb' => '600080');\r\n\t\t\tcase 0x1D: return array('rgb' => 'FF8080');\r\n\t\t\tcase 0x1E: return array('rgb' => '0080C0');\r\n\t\t\tcase 0x1F: return array('rgb' => 'C0C0FF');\r\n\t\t\tcase 0x20: return array('rgb' => '000080');\r\n\t\t\tcase 0x21: return array('rgb' => 'FF00FF');\r\n\t\t\tcase 0x22: return array('rgb' => 'FFFF00');\r\n\t\t\tcase 0x23: return array('rgb' => '00FFFF');\r\n\t\t\tcase 0x24: return array('rgb' => '800080');\r\n\t\t\tcase 0x25: return array('rgb' => '800000');\r\n\t\t\tcase 0x26: return array('rgb' => '008080');\r\n\t\t\tcase 0x27: return array('rgb' => '0000FF');\r\n\t\t\tcase 0x28: return array('rgb' => '00CFFF');\r\n\t\t\tcase 0x29: return array('rgb' => '69FFFF');\r\n\t\t\tcase 0x2A: return array('rgb' => 'E0FFE0');\r\n\t\t\tcase 0x2B: return array('rgb' => 'FFFF80');\r\n\t\t\tcase 0x2C: return array('rgb' => 'A6CAF0');\r\n\t\t\tcase 0x2D: return array('rgb' => 'DD9CB3');\r\n\t\t\tcase 0x2E: return array('rgb' => 'B38FEE');\r\n\t\t\tcase 0x2F: return array('rgb' => 'E3E3E3');\r\n\t\t\tcase 0x30: return array('rgb' => '2A6FF9');\r\n\t\t\tcase 0x31: return array('rgb' => '3FB8CD');\r\n\t\t\tcase 0x32: return array('rgb' => '488436');\r\n\t\t\tcase 0x33: return array('rgb' => '958C41');\r\n\t\t\tcase 0x34: return array('rgb' => '8E5E42');\r\n\t\t\tcase 0x35: return array('rgb' => 'A0627A');\r\n\t\t\tcase 0x36: return array('rgb' => '624FAC');\r\n\t\t\tcase 0x37: return array('rgb' => '969696');\r\n\t\t\tcase 0x38: return array('rgb' => '1D2FBE');\r\n\t\t\tcase 0x39: return array('rgb' => '286676');\r\n\t\t\tcase 0x3A: return array('rgb' => '004500');\r\n\t\t\tcase 0x3B: return array('rgb' => '453E01');\r\n\t\t\tcase 0x3C: return array('rgb' => '6A2813');\r\n\t\t\tcase 0x3D: return array('rgb' => '85396A');\r\n\t\t\tcase 0x3E: return array('rgb' => '4A3285');\r\n\t\t\tcase 0x3F: return array('rgb' => '424242');\r\n\t\t\tdefault:   return array('rgb' => '000000');\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t/**\r\n\t * Map color array from BIFF8 built-in color index\r\n\t *\r\n\t * @param int $subData\r\n\t * @return array\r\n\t */\r\n\tprivate static function _mapColor($subData)\r\n\t{\r\n\t\tswitch ($subData) {\r\n\t\t\tcase 0x08: return array('rgb' => '000000');\r\n\t\t\tcase 0x09: return array('rgb' => 'FFFFFF');\r\n\t\t\tcase 0x0A: return array('rgb' => 'FF0000');\r\n\t\t\tcase 0x0B: return array('rgb' => '00FF00');\r\n\t\t\tcase 0x0C: return array('rgb' => '0000FF');\r\n\t\t\tcase 0x0D: return array('rgb' => 'FFFF00');\r\n\t\t\tcase 0x0E: return array('rgb' => 'FF00FF');\r\n\t\t\tcase 0x0F: return array('rgb' => '00FFFF');\r\n\t\t\tcase 0x10: return array('rgb' => '800000');\r\n\t\t\tcase 0x11: return array('rgb' => '008000');\r\n\t\t\tcase 0x12: return array('rgb' => '000080');\r\n\t\t\tcase 0x13: return array('rgb' => '808000');\r\n\t\t\tcase 0x14: return array('rgb' => '800080');\r\n\t\t\tcase 0x15: return array('rgb' => '008080');\r\n\t\t\tcase 0x16: return array('rgb' => 'C0C0C0');\r\n\t\t\tcase 0x17: return array('rgb' => '808080');\r\n\t\t\tcase 0x18: return array('rgb' => '9999FF');\r\n\t\t\tcase 0x19: return array('rgb' => '993366');\r\n\t\t\tcase 0x1A: return array('rgb' => 'FFFFCC');\r\n\t\t\tcase 0x1B: return array('rgb' => 'CCFFFF');\r\n\t\t\tcase 0x1C: return array('rgb' => '660066');\r\n\t\t\tcase 0x1D: return array('rgb' => 'FF8080');\r\n\t\t\tcase 0x1E: return array('rgb' => '0066CC');\r\n\t\t\tcase 0x1F: return array('rgb' => 'CCCCFF');\r\n\t\t\tcase 0x20: return array('rgb' => '000080');\r\n\t\t\tcase 0x21: return array('rgb' => 'FF00FF');\r\n\t\t\tcase 0x22: return array('rgb' => 'FFFF00');\r\n\t\t\tcase 0x23: return array('rgb' => '00FFFF');\r\n\t\t\tcase 0x24: return array('rgb' => '800080');\r\n\t\t\tcase 0x25: return array('rgb' => '800000');\r\n\t\t\tcase 0x26: return array('rgb' => '008080');\r\n\t\t\tcase 0x27: return array('rgb' => '0000FF');\r\n\t\t\tcase 0x28: return array('rgb' => '00CCFF');\r\n\t\t\tcase 0x29: return array('rgb' => 'CCFFFF');\r\n\t\t\tcase 0x2A: return array('rgb' => 'CCFFCC');\r\n\t\t\tcase 0x2B: return array('rgb' => 'FFFF99');\r\n\t\t\tcase 0x2C: return array('rgb' => '99CCFF');\r\n\t\t\tcase 0x2D: return array('rgb' => 'FF99CC');\r\n\t\t\tcase 0x2E: return array('rgb' => 'CC99FF');\r\n\t\t\tcase 0x2F: return array('rgb' => 'FFCC99');\r\n\t\t\tcase 0x30: return array('rgb' => '3366FF');\r\n\t\t\tcase 0x31: return array('rgb' => '33CCCC');\r\n\t\t\tcase 0x32: return array('rgb' => '99CC00');\r\n\t\t\tcase 0x33: return array('rgb' => 'FFCC00');\r\n\t\t\tcase 0x34: return array('rgb' => 'FF9900');\r\n\t\t\tcase 0x35: return array('rgb' => 'FF6600');\r\n\t\t\tcase 0x36: return array('rgb' => '666699');\r\n\t\t\tcase 0x37: return array('rgb' => '969696');\r\n\t\t\tcase 0x38: return array('rgb' => '003366');\r\n\t\t\tcase 0x39: return array('rgb' => '339966');\r\n\t\t\tcase 0x3A: return array('rgb' => '003300');\r\n\t\t\tcase 0x3B: return array('rgb' => '333300');\r\n\t\t\tcase 0x3C: return array('rgb' => '993300');\r\n\t\t\tcase 0x3D: return array('rgb' => '993366');\r\n\t\t\tcase 0x3E: return array('rgb' => '333399');\r\n\t\t\tcase 0x3F: return array('rgb' => '333333');\r\n\t\t\tdefault:   return array('rgb' => '000000');\r\n\t\t}\r\n\t}\r\n\r\n\r\n\tprivate function _parseRichText($is = '') {\r\n\t\t$value = new PHPExcel_RichText();\r\n\r\n\t\t$value->createText($is);\r\n\r\n\t\treturn $value;\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/Exception.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Reader_Exception\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_Exception extends PHPExcel_Exception {\n\t/**\n\t * Error handler callback\n\t *\n\t * @param mixed $code\n\t * @param mixed $string\n\t * @param mixed $file\n\t * @param mixed $line\n\t * @param mixed $context\n\t */\n\tpublic static function errorHandlerCallback($code, $string, $file, $line, $context) {\n\t\t$e = new self($string, $code);\n\t\t$e->line = $line;\n\t\t$e->file = $file;\n\t\tthrow $e;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/Gnumeric.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n/**\n * PHPExcel_Reader_Gnumeric\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Reader\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_Gnumeric extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader\n{\n\t/**\n\t * Formats\n\t *\n\t * @var array\n\t */\n\tprivate $_styles = array();\n\n\t/**\n\t * Shared Expressions\n\t *\n\t * @var array\n\t */\n\tprivate $_expressions = array();\n\n\tprivate $_referenceHelper = null;\n\n\n\t/**\n\t * Create a new PHPExcel_Reader_Gnumeric\n\t */\n\tpublic function __construct() {\n\t\t$this->_readFilter \t= new PHPExcel_Reader_DefaultReadFilter();\n\t\t$this->_referenceHelper = PHPExcel_ReferenceHelper::getInstance();\n\t}\n\n\n\t/**\n\t * Can the current PHPExcel_Reader_IReader read the file?\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @return \tboolean\n\t * @throws PHPExcel_Reader_Exception\n\t */\n\tpublic function canRead($pFilename)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n\t\t// Check if gzlib functions are available\n\t\tif (!function_exists('gzread')) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"gzlib library is not enabled\");\n\t\t}\n\n\t\t// Read signature data (first 3 bytes)\n\t\t$fh = fopen($pFilename, 'r');\n\t\t$data = fread($fh, 2);\n\t\tfclose($fh);\n\n\t\tif ($data != chr(0x1F).chr(0x8B)) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\n\t/**\n\t * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function listWorksheetNames($pFilename)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n\t\t$xml = new XMLReader();\n\t\t$xml->xml(\n\t\t\t$this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions()\n\t\t);\n\t\t$xml->setParserProperty(2,true);\n\n\t\t$worksheetNames = array();\n\t\twhile ($xml->read()) {\n\t\t\tif ($xml->name == 'gnm:SheetName' && $xml->nodeType == XMLReader::ELEMENT) {\n\t\t\t    $xml->read();\t//\tMove onto the value node\n\t\t\t\t$worksheetNames[] = (string) $xml->value;\n\t\t\t} elseif ($xml->name == 'gnm:Sheets') {\n\t\t\t\t//\tbreak out of the loop once we've got our sheet names rather than parse the entire file\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn $worksheetNames;\n\t}\n\n\n\t/**\n\t * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)\n\t *\n\t * @param   string     $pFilename\n\t * @throws   PHPExcel_Reader_Exception\n\t */\n\tpublic function listWorksheetInfo($pFilename)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n\t\t$xml = new XMLReader();\n\t\t$xml->xml(\n\t\t\t$this->securityScanFile('compress.zlib://'.realpath($pFilename)), null, PHPExcel_Settings::getLibXmlLoaderOptions()\n\t\t);\n\t\t$xml->setParserProperty(2,true);\n\n\t\t$worksheetInfo = array();\n\t\twhile ($xml->read()) {\n\t\t\tif ($xml->name == 'gnm:Sheet' && $xml->nodeType == XMLReader::ELEMENT) {\n\t\t\t\t$tmpInfo = array(\n\t\t\t\t\t'worksheetName' => '',\n\t\t\t\t\t'lastColumnLetter' => 'A',\n\t\t\t\t\t'lastColumnIndex' => 0,\n\t\t\t\t\t'totalRows' => 0,\n\t\t\t\t\t'totalColumns' => 0,\n\t\t\t\t);\n\n\t\t\t\twhile ($xml->read()) {\n\t\t\t\t\tif ($xml->name == 'gnm:Name' && $xml->nodeType == XMLReader::ELEMENT) {\n\t\t\t\t\t    $xml->read();\t//\tMove onto the value node\n\t\t\t\t\t\t$tmpInfo['worksheetName'] = (string) $xml->value;\n\t\t\t\t\t} elseif ($xml->name == 'gnm:MaxCol' && $xml->nodeType == XMLReader::ELEMENT) {\n\t\t\t\t\t    $xml->read();\t//\tMove onto the value node\n\t\t\t\t\t\t$tmpInfo['lastColumnIndex'] = (int) $xml->value;\n\t\t\t\t\t\t$tmpInfo['totalColumns'] = (int) $xml->value + 1;\n\t\t\t\t\t} elseif ($xml->name == 'gnm:MaxRow' && $xml->nodeType == XMLReader::ELEMENT) {\n\t\t\t\t\t    $xml->read();\t//\tMove onto the value node\n\t\t\t\t\t\t$tmpInfo['totalRows'] = (int) $xml->value + 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);\n\t\t\t\t$worksheetInfo[] = $tmpInfo;\n\t\t\t}\n\t\t}\n\n\t\treturn $worksheetInfo;\n\t}\n\n\n\tprivate function _gzfileGetContents($filename) {\n\t\t$file = @gzopen($filename, 'rb');\n\t\tif ($file !== false) {\n\t\t\t$data = '';\n\t\t\twhile (!gzeof($file)) {\n\t\t\t\t$data .= gzread($file, 1024);\n\t\t\t}\n\t\t\tgzclose($file);\n\t\t}\n\t\treturn $data;\n\t}\n\n\n\t/**\n\t * Loads PHPExcel from file\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @return \tPHPExcel\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function load($pFilename)\n\t{\n\t\t// Create new PHPExcel\n\t\t$objPHPExcel = new PHPExcel();\n\n\t\t// Load into this instance\n\t\treturn $this->loadIntoExisting($pFilename, $objPHPExcel);\n\t}\n\n\n\t/**\n\t * Loads PHPExcel from file into PHPExcel instance\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @param\tPHPExcel\t$objPHPExcel\n\t * @return \tPHPExcel\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n\t\t$timezoneObj = new DateTimeZone('Europe/London');\n\t\t$GMT = new DateTimeZone('UTC');\n\n\t\t$gFileData = $this->_gzfileGetContents($pFilename);\n\n//\t\techo '<pre>';\n//\t\techo htmlentities($gFileData,ENT_QUOTES,'UTF-8');\n//\t\techo '</pre><hr />';\n//\n\t\t$xml = simplexml_load_string($this->securityScan($gFileData), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t$namespacesMeta = $xml->getNamespaces(true);\n\n//\t\tvar_dump($namespacesMeta);\n//\n\t\t$gnmXML = $xml->children($namespacesMeta['gnm']);\n\n\t\t$docProps = $objPHPExcel->getProperties();\n\t\t//\tDocument Properties are held differently, depending on the version of Gnumeric\n\t\tif (isset($namespacesMeta['office'])) {\n\t\t\t$officeXML = $xml->children($namespacesMeta['office']);\n\t\t    $officeDocXML = $officeXML->{'document-meta'};\n\t\t\t$officeDocMetaXML = $officeDocXML->meta;\n\n\t\t\tforeach($officeDocMetaXML as $officePropertyData) {\n\n\t\t\t\t$officePropertyDC = array();\n\t\t\t\tif (isset($namespacesMeta['dc'])) {\n\t\t\t\t\t$officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);\n\t\t\t\t}\n\t\t\t\tforeach($officePropertyDC as $propertyName => $propertyValue) {\n\t\t\t\t\t$propertyValue = (string) $propertyValue;\n\t\t\t\t\tswitch ($propertyName) {\n\t\t\t\t\t\tcase 'title' :\n\t\t\t\t\t\t\t\t$docProps->setTitle(trim($propertyValue));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'subject' :\n\t\t\t\t\t\t\t\t$docProps->setSubject(trim($propertyValue));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'creator' :\n\t\t\t\t\t\t\t\t$docProps->setCreator(trim($propertyValue));\n\t\t\t\t\t\t\t\t$docProps->setLastModifiedBy(trim($propertyValue));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'date' :\n\t\t\t\t\t\t\t\t$creationDate = strtotime(trim($propertyValue));\n\t\t\t\t\t\t\t\t$docProps->setCreated($creationDate);\n\t\t\t\t\t\t\t\t$docProps->setModified($creationDate);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'description' :\n\t\t\t\t\t\t\t\t$docProps->setDescription(trim($propertyValue));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$officePropertyMeta = array();\n\t\t\t\tif (isset($namespacesMeta['meta'])) {\n\t\t\t\t\t$officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);\n\t\t\t\t}\n\t\t\t\tforeach($officePropertyMeta as $propertyName => $propertyValue) {\n\t\t\t\t\t$attributes = $propertyValue->attributes($namespacesMeta['meta']);\n\t\t\t\t\t$propertyValue = (string) $propertyValue;\n\t\t\t\t\tswitch ($propertyName) {\n\t\t\t\t\t\tcase 'keyword' :\n\t\t\t\t\t\t\t\t$docProps->setKeywords(trim($propertyValue));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'initial-creator' :\n\t\t\t\t\t\t\t\t$docProps->setCreator(trim($propertyValue));\n\t\t\t\t\t\t\t\t$docProps->setLastModifiedBy(trim($propertyValue));\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'creation-date' :\n\t\t\t\t\t\t\t\t$creationDate = strtotime(trim($propertyValue));\n\t\t\t\t\t\t\t\t$docProps->setCreated($creationDate);\n\t\t\t\t\t\t\t\t$docProps->setModified($creationDate);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'user-defined' :\n\t\t\t\t\t\t\t\tlist(,$attrName) = explode(':',$attributes['name']);\n\t\t\t\t\t\t\t\tswitch ($attrName) {\n\t\t\t\t\t\t\t\t\tcase 'publisher' :\n\t\t\t\t\t\t\t\t\t\t\t$docProps->setCompany(trim($propertyValue));\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'category' :\n\t\t\t\t\t\t\t\t\t\t\t$docProps->setCategory(trim($propertyValue));\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase 'manager' :\n\t\t\t\t\t\t\t\t\t\t\t$docProps->setManager(trim($propertyValue));\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} elseif (isset($gnmXML->Summary)) {\n\t\t\tforeach($gnmXML->Summary->Item as $summaryItem) {\n\t\t\t\t$propertyName = $summaryItem->name;\n\t\t\t\t$propertyValue = $summaryItem->{'val-string'};\n\t\t\t\tswitch ($propertyName) {\n\t\t\t\t\tcase 'title' :\n\t\t\t\t\t\t$docProps->setTitle(trim($propertyValue));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'comments' :\n\t\t\t\t\t\t$docProps->setDescription(trim($propertyValue));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'keywords' :\n\t\t\t\t\t\t$docProps->setKeywords(trim($propertyValue));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'category' :\n\t\t\t\t\t\t$docProps->setCategory(trim($propertyValue));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'manager' :\n\t\t\t\t\t\t$docProps->setManager(trim($propertyValue));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'author' :\n\t\t\t\t\t\t$docProps->setCreator(trim($propertyValue));\n\t\t\t\t\t\t$docProps->setLastModifiedBy(trim($propertyValue));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'company' :\n\t\t\t\t\t\t$docProps->setCompany(trim($propertyValue));\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t$worksheetID = 0;\n\t\tforeach($gnmXML->Sheets->Sheet as $sheet) {\n\t\t\t$worksheetName = (string) $sheet->Name;\n//\t\t\techo '<b>Worksheet: ',$worksheetName,'</b><br />';\n\t\t\tif ((isset($this->_loadSheetsOnly)) && (!in_array($worksheetName, $this->_loadSheetsOnly))) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t$maxRow = $maxCol = 0;\n\n\t\t\t// Create new Worksheet\n\t\t\t$objPHPExcel->createSheet();\n\t\t\t$objPHPExcel->setActiveSheetIndex($worksheetID);\n\t\t\t//\tUse false for $updateFormulaCellReferences to prevent adjustment of worksheet references in formula\n\t\t\t//\t\tcells... during the load, all formulae should be correct, and we're simply bringing the worksheet\n\t\t\t//\t\tname in line with the formula, not the reverse\n\t\t\t$objPHPExcel->getActiveSheet()->setTitle($worksheetName,false);\n\n\t\t\tif ((!$this->_readDataOnly) && (isset($sheet->PrintInformation))) {\n\t\t\t\tif (isset($sheet->PrintInformation->Margins)) {\n\t\t\t\t\tforeach($sheet->PrintInformation->Margins->children('gnm',TRUE) as $key => $margin) {\n\t\t\t\t\t\t$marginAttributes = $margin->attributes();\n\t\t\t\t\t\t$marginSize = 72 / 100;\t//\tDefault\n\t\t\t\t\t\tswitch($marginAttributes['PrefUnit']) {\n\t\t\t\t\t\t\tcase 'mm' :\n\t\t\t\t\t\t\t\t$marginSize = intval($marginAttributes['Points']) / 100;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tswitch($key) {\n\t\t\t\t\t\t\tcase 'top' :\n\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getPageMargins()->setTop($marginSize);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'bottom' :\n\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getPageMargins()->setBottom($marginSize);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'left' :\n\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getPageMargins()->setLeft($marginSize);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'right' :\n\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getPageMargins()->setRight($marginSize);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'header' :\n\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getPageMargins()->setHeader($marginSize);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\tcase 'footer' :\n\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getPageMargins()->setFooter($marginSize);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tforeach($sheet->Cells->Cell as $cell) {\n\t\t\t\t$cellAttributes = $cell->attributes();\n\t\t\t\t$row = (int) $cellAttributes->Row + 1;\n\t\t\t\t$column = (int) $cellAttributes->Col;\n\n\t\t\t\tif ($row > $maxRow) $maxRow = $row;\n\t\t\t\tif ($column > $maxCol) $maxCol = $column;\n\n\t\t\t\t$column = PHPExcel_Cell::stringFromColumnIndex($column);\n\n\t\t\t\t// Read cell?\n\t\t\t\tif ($this->getReadFilter() !== NULL) {\n\t\t\t\t\tif (!$this->getReadFilter()->readCell($column, $row, $worksheetName)) {\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t$ValueType = $cellAttributes->ValueType;\n\t\t\t\t$ExprID = (string) $cellAttributes->ExprID;\n//\t\t\t\techo 'Cell ',$column,$row,'<br />';\n//\t\t\t\techo 'Type is ',$ValueType,'<br />';\n//\t\t\t\techo 'Value is ',$cell,'<br />';\n\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_FORMULA;\n\t\t\t\tif ($ExprID > '') {\n\t\t\t\t\tif (((string) $cell) > '') {\n\n\t\t\t\t\t\t$this->_expressions[$ExprID] = array( 'column'\t=> $cellAttributes->Col,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  'row'\t\t=> $cellAttributes->Row,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  'formula'\t=> (string) $cell\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t);\n//\t\t\t\t\t\techo 'NEW EXPRESSION ',$ExprID,'<br />';\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$expression = $this->_expressions[$ExprID];\n\n\t\t\t\t\t\t$cell = $this->_referenceHelper->updateFormulaReferences( $expression['formula'],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  'A1',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  $cellAttributes->Col - $expression['column'],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  $cellAttributes->Row - $expression['row'],\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t  $worksheetName\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t);\n//\t\t\t\t\t\techo 'SHARED EXPRESSION ',$ExprID,'<br />';\n//\t\t\t\t\t\techo 'New Value is ',$cell,'<br />';\n\t\t\t\t\t}\n\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_FORMULA;\n\t\t\t\t} else {\n\t\t\t\t\tswitch($ValueType) {\n\t\t\t\t\t\tcase '10' :\t\t//\tNULL\n\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_NULL;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '20' :\t\t//\tBoolean\n\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_BOOL;\n\t\t\t\t\t\t\t$cell = ($cell == 'TRUE') ? True : False;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '30' :\t\t//\tInteger\n\t\t\t\t\t\t\t$cell = intval($cell);\n\t\t\t\t\t\tcase '40' :\t\t//\tFloat\n\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '50' :\t\t//\tError\n\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_ERROR;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '60' :\t\t//\tString\n\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_STRING;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase '70' :\t\t//\tCell Range\n\t\t\t\t\t\tcase '80' :\t\t//\tArray\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$objPHPExcel->getActiveSheet()->getCell($column.$row)->setValueExplicit($cell,$type);\n\t\t\t}\n\n\t\t\tif ((!$this->_readDataOnly) && (isset($sheet->Objects))) {\n\t\t\t\tforeach($sheet->Objects->children('gnm',TRUE) as $key => $comment) {\n\t\t\t\t\t$commentAttributes = $comment->attributes();\n\t\t\t\t\t//\tOnly comment objects are handled at the moment\n\t\t\t\t\tif ($commentAttributes->Text) {\n\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getComment( (string)$commentAttributes->ObjectBound )\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t->setAuthor( (string)$commentAttributes->Author )\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t->setText($this->_parseRichText((string)$commentAttributes->Text) );\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n//\t\t\techo '$maxCol=',$maxCol,'; $maxRow=',$maxRow,'<br />';\n//\n\t\t\tforeach($sheet->Styles->StyleRegion as $styleRegion) {\n\t\t\t\t$styleAttributes = $styleRegion->attributes();\n\t\t\t\tif (($styleAttributes['startRow'] <= $maxRow) &&\n\t\t\t\t\t($styleAttributes['startCol'] <= $maxCol)) {\n\n\t\t\t\t\t$startColumn = PHPExcel_Cell::stringFromColumnIndex((int) $styleAttributes['startCol']);\n\t\t\t\t\t$startRow = $styleAttributes['startRow'] + 1;\n\n\t\t\t\t\t$endColumn = ($styleAttributes['endCol'] > $maxCol) ? $maxCol : (int) $styleAttributes['endCol'];\n\t\t\t\t\t$endColumn = PHPExcel_Cell::stringFromColumnIndex($endColumn);\n\t\t\t\t\t$endRow = ($styleAttributes['endRow'] > $maxRow) ? $maxRow : $styleAttributes['endRow'];\n\t\t\t\t\t$endRow += 1;\n\t\t\t\t\t$cellRange = $startColumn.$startRow.':'.$endColumn.$endRow;\n//\t\t\t\t\techo $cellRange,'<br />';\n\n\t\t\t\t\t$styleAttributes = $styleRegion->Style->attributes();\n//\t\t\t\t\tvar_dump($styleAttributes);\n//\t\t\t\t\techo '<br />';\n\n\t\t\t\t\t//\tWe still set the number format mask for date/time values, even if _readDataOnly is true\n\t\t\t\t\tif ((!$this->_readDataOnly) ||\n\t\t\t\t\t\t(PHPExcel_Shared_Date::isDateTimeFormatCode((string) $styleAttributes['Format']))) {\n\t\t\t\t\t\t$styleArray = array();\n\t\t\t\t\t\t$styleArray['numberformat']['code'] = (string) $styleAttributes['Format'];\n\t\t\t\t\t\t//\tIf _readDataOnly is false, we set all formatting information\n\t\t\t\t\t\tif (!$this->_readDataOnly) {\n\t\t\t\t\t\t\tswitch($styleAttributes['HAlign']) {\n\t\t\t\t\t\t\t\tcase '1' :\n\t\t\t\t\t\t\t\t\t$styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase '2' :\n\t\t\t\t\t\t\t\t\t$styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_LEFT;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase '4' :\n\t\t\t\t\t\t\t\t\t$styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_RIGHT;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase '8' :\n\t\t\t\t\t\t\t\t\t$styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase '16' :\n\t\t\t\t\t\t\t\tcase '64' :\n\t\t\t\t\t\t\t\t\t$styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase '32' :\n\t\t\t\t\t\t\t\t\t$styleArray['alignment']['horizontal'] = PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tswitch($styleAttributes['VAlign']) {\n\t\t\t\t\t\t\t\tcase '1' :\n\t\t\t\t\t\t\t\t\t$styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_TOP;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase '2' :\n\t\t\t\t\t\t\t\t\t$styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_BOTTOM;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase '4' :\n\t\t\t\t\t\t\t\t\t$styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_CENTER;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase '8' :\n\t\t\t\t\t\t\t\t\t$styleArray['alignment']['vertical'] = PHPExcel_Style_Alignment::VERTICAL_JUSTIFY;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t$styleArray['alignment']['wrap'] = ($styleAttributes['WrapText'] == '1') ? True : False;\n\t\t\t\t\t\t\t$styleArray['alignment']['shrinkToFit'] = ($styleAttributes['ShrinkToFit'] == '1') ? True : False;\n\t\t\t\t\t\t\t$styleArray['alignment']['indent'] = (intval($styleAttributes[\"Indent\"]) > 0) ? $styleAttributes[\"indent\"] : 0;\n\n\t\t\t\t\t\t\t$RGB = self::_parseGnumericColour($styleAttributes[\"Fore\"]);\n\t\t\t\t\t\t\t$styleArray['font']['color']['rgb'] = $RGB;\n\t\t\t\t\t\t\t$RGB = self::_parseGnumericColour($styleAttributes[\"Back\"]);\n\t\t\t\t\t\t\t$shade = $styleAttributes[\"Shade\"];\n\t\t\t\t\t\t\tif (($RGB != '000000') || ($shade != '0')) {\n\t\t\t\t\t\t\t\t$styleArray['fill']['color']['rgb'] = $styleArray['fill']['startcolor']['rgb'] = $RGB;\n\t\t\t\t\t\t\t\t$RGB2 = self::_parseGnumericColour($styleAttributes[\"PatternColor\"]);\n\t\t\t\t\t\t\t\t$styleArray['fill']['endcolor']['rgb'] = $RGB2;\n\t\t\t\t\t\t\t\tswitch($shade) {\n\t\t\t\t\t\t\t\t\tcase '1' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_SOLID;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '2' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '3' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_GRADIENT_PATH;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '4' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '5' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '6' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '7' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '8' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '9' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKUP;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '10' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '11' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '12' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_GRAY125;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '13' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '14' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '15' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '16' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '17' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '18' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '19' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\tcase '20' :\n\t\t\t\t\t\t\t\t\t\t$styleArray['fill']['type'] = PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY;\n\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t$fontAttributes = $styleRegion->Style->Font->attributes();\n//\t\t\t\t\t\t\tvar_dump($fontAttributes);\n//\t\t\t\t\t\t\techo '<br />';\n\t\t\t\t\t\t\t$styleArray['font']['name'] = (string) $styleRegion->Style->Font;\n\t\t\t\t\t\t\t$styleArray['font']['size'] = intval($fontAttributes['Unit']);\n\t\t\t\t\t\t\t$styleArray['font']['bold'] = ($fontAttributes['Bold'] == '1') ? True : False;\n\t\t\t\t\t\t\t$styleArray['font']['italic'] = ($fontAttributes['Italic'] == '1') ? True : False;\n\t\t\t\t\t\t\t$styleArray['font']['strike'] = ($fontAttributes['StrikeThrough'] == '1') ? True : False;\n\t\t\t\t\t\t\tswitch($fontAttributes['Underline']) {\n\t\t\t\t\t\t\t\tcase '1' :\n\t\t\t\t\t\t\t\t\t$styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLE;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase '2' :\n\t\t\t\t\t\t\t\t\t$styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLE;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase '3' :\n\t\t\t\t\t\t\t\t\t$styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase '4' :\n\t\t\t\t\t\t\t\t\t$styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tdefault :\n\t\t\t\t\t\t\t\t\t$styleArray['font']['underline'] = PHPExcel_Style_Font::UNDERLINE_NONE;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tswitch($fontAttributes['Script']) {\n\t\t\t\t\t\t\t\tcase '1' :\n\t\t\t\t\t\t\t\t\t$styleArray['font']['superScript'] = True;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\tcase '-1' :\n\t\t\t\t\t\t\t\t\t$styleArray['font']['subScript'] = True;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (isset($styleRegion->Style->StyleBorder)) {\n\t\t\t\t\t\t\t\tif (isset($styleRegion->Style->StyleBorder->Top)) {\n\t\t\t\t\t\t\t\t\t$styleArray['borders']['top'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Top->attributes());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isset($styleRegion->Style->StyleBorder->Bottom)) {\n\t\t\t\t\t\t\t\t\t$styleArray['borders']['bottom'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Bottom->attributes());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isset($styleRegion->Style->StyleBorder->Left)) {\n\t\t\t\t\t\t\t\t\t$styleArray['borders']['left'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Left->attributes());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif (isset($styleRegion->Style->StyleBorder->Right)) {\n\t\t\t\t\t\t\t\t\t$styleArray['borders']['right'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Right->attributes());\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tif ((isset($styleRegion->Style->StyleBorder->Diagonal)) && (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}))) {\n\t\t\t\t\t\t\t\t\t$styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes());\n\t\t\t\t\t\t\t\t\t$styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_BOTH;\n\t\t\t\t\t\t\t\t} elseif (isset($styleRegion->Style->StyleBorder->Diagonal)) {\n\t\t\t\t\t\t\t\t\t$styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->Diagonal->attributes());\n\t\t\t\t\t\t\t\t\t$styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_UP;\n\t\t\t\t\t\t\t\t} elseif (isset($styleRegion->Style->StyleBorder->{'Rev-Diagonal'})) {\n\t\t\t\t\t\t\t\t\t$styleArray['borders']['diagonal'] = self::_parseBorderAttributes($styleRegion->Style->StyleBorder->{'Rev-Diagonal'}->attributes());\n\t\t\t\t\t\t\t\t\t$styleArray['borders']['diagonaldirection'] = PHPExcel_Style_Borders::DIAGONAL_DOWN;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif (isset($styleRegion->Style->HyperLink)) {\n\t\t\t\t\t\t\t\t//\tTO DO\n\t\t\t\t\t\t\t\t$hyperlink = $styleRegion->Style->HyperLink->attributes();\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n//\t\t\t\t\t\tvar_dump($styleArray);\n//\t\t\t\t\t\techo '<br />';\n\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getStyle($cellRange)->applyFromArray($styleArray);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ((!$this->_readDataOnly) && (isset($sheet->Cols))) {\n\t\t\t\t//\tColumn Widths\n\t\t\t\t$columnAttributes = $sheet->Cols->attributes();\n\t\t\t\t$defaultWidth = $columnAttributes['DefaultSizePts']  / 5.4;\n\t\t\t\t$c = 0;\n\t\t\t\tforeach($sheet->Cols->ColInfo as $columnOverride) {\n\t\t\t\t\t$columnAttributes = $columnOverride->attributes();\n\t\t\t\t\t$column = $columnAttributes['No'];\n\t\t\t\t\t$columnWidth = $columnAttributes['Unit']  / 5.4;\n\t\t\t\t\t$hidden = ((isset($columnAttributes['Hidden'])) && ($columnAttributes['Hidden'] == '1')) ? true : false;\n\t\t\t\t\t$columnCount = (isset($columnAttributes['Count'])) ? $columnAttributes['Count'] : 1;\n\t\t\t\t\twhile ($c < $column) {\n\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($defaultWidth);\n\t\t\t\t\t\t++$c;\n\t\t\t\t\t}\n\t\t\t\t\twhile (($c < ($column+$columnCount)) && ($c <= $maxCol)) {\n\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($columnWidth);\n\t\t\t\t\t\tif ($hidden) {\n\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setVisible(false);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t++$c;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\twhile ($c <= $maxCol) {\n\t\t\t\t\t$objPHPExcel->getActiveSheet()->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($c))->setWidth($defaultWidth);\n\t\t\t\t\t++$c;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ((!$this->_readDataOnly) && (isset($sheet->Rows))) {\n\t\t\t\t//\tRow Heights\n\t\t\t\t$rowAttributes = $sheet->Rows->attributes();\n\t\t\t\t$defaultHeight = $rowAttributes['DefaultSizePts'];\n\t\t\t\t$r = 0;\n\n\t\t\t\tforeach($sheet->Rows->RowInfo as $rowOverride) {\n\t\t\t\t\t$rowAttributes = $rowOverride->attributes();\n\t\t\t\t\t$row = $rowAttributes['No'];\n\t\t\t\t\t$rowHeight = $rowAttributes['Unit'];\n\t\t\t\t\t$hidden = ((isset($rowAttributes['Hidden'])) && ($rowAttributes['Hidden'] == '1')) ? true : false;\n\t\t\t\t\t$rowCount = (isset($rowAttributes['Count'])) ? $rowAttributes['Count'] : 1;\n\t\t\t\t\twhile ($r < $row) {\n\t\t\t\t\t\t++$r;\n\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight);\n\t\t\t\t\t}\n\t\t\t\t\twhile (($r < ($row+$rowCount)) && ($r < $maxRow)) {\n\t\t\t\t\t\t++$r;\n\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($rowHeight);\n\t\t\t\t\t\tif ($hidden) {\n\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getRowDimension($r)->setVisible(false);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\twhile ($r < $maxRow) {\n\t\t\t\t\t++$r;\n\t\t\t\t\t$objPHPExcel->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t//\tHandle Merged Cells in this worksheet\n\t\t\tif (isset($sheet->MergedRegions)) {\n\t\t\t\tforeach($sheet->MergedRegions->Merge as $mergeCells) {\n\t\t\t\t\tif (strpos($mergeCells,':') !== FALSE) {\n\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->mergeCells($mergeCells);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$worksheetID++;\n\t\t}\n\n\t\t//\tLoop through definedNames (global named ranges)\n\t\tif (isset($gnmXML->Names)) {\n\t\t\tforeach($gnmXML->Names->Name as $namedRange) {\n\t\t\t\t$name = (string) $namedRange->name;\n\t\t\t\t$range = (string) $namedRange->value;\n\t\t\t\tif (stripos($range, '#REF!') !== false) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n\t\t\t\t$range = explode('!',$range);\n\t\t\t\t$range[0] = trim($range[0],\"'\");;\n\t\t\t\tif ($worksheet = $objPHPExcel->getSheetByName($range[0])) {\n\t\t\t\t\t$extractedRange = str_replace('$', '', $range[1]);\n\t\t\t\t\t$objPHPExcel->addNamedRange( new PHPExcel_NamedRange($name, $worksheet, $extractedRange) );\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\n\t\t// Return\n\t\treturn $objPHPExcel;\n\t}\n\n\n\tprivate static function _parseBorderAttributes($borderAttributes)\n\t{\n\t\t$styleArray = array();\n\n\t\tif (isset($borderAttributes[\"Color\"])) {\n\t\t\t$RGB = self::_parseGnumericColour($borderAttributes[\"Color\"]);\n\t\t\t$styleArray['color']['rgb'] = $RGB;\n\t\t}\n\n\t\tswitch ($borderAttributes[\"Style\"]) {\n\t\t\tcase '0' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_NONE;\n\t\t\t\tbreak;\n\t\t\tcase '1' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_THIN;\n\t\t\t\tbreak;\n\t\t\tcase '2' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUM;\n\t\t\t\tbreak;\n\t\t\tcase '4' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHED;\n\t\t\t\tbreak;\n\t\t\tcase '5' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_THICK;\n\t\t\t\tbreak;\n\t\t\tcase '6' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_DOUBLE;\n\t\t\t\tbreak;\n\t\t\tcase '7' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_DOTTED;\n\t\t\t\tbreak;\n\t\t\tcase '9' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOT;\n\t\t\t\tbreak;\n\t\t\tcase '10' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT;\n\t\t\t\tbreak;\n\t\t\tcase '11' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_DASHDOTDOT;\n\t\t\t\tbreak;\n\t\t\tcase '12' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT;\n\t\t\t\tbreak;\n\t\t\tcase '13' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT;\n\t\t\t\tbreak;\n\t\t\tcase '3' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_SLANTDASHDOT;\n\t\t\t\tbreak;\n\t\t\tcase '8' :\n\t\t\t\t$styleArray['style'] = PHPExcel_Style_Border::BORDER_MEDIUMDASHED;\n\t\t\t\tbreak;\n\t\t}\n\t\treturn $styleArray;\n\t}\n\n\n\tprivate function _parseRichText($is = '') {\n\t\t$value = new PHPExcel_RichText();\n\n\t\t$value->createText($is);\n\n\t\treturn $value;\n\t}\n\n\n\tprivate static function _parseGnumericColour($gnmColour) {\n\t\tlist($gnmR,$gnmG,$gnmB) = explode(':',$gnmColour);\n\t\t$gnmR = substr(str_pad($gnmR,4,'0',STR_PAD_RIGHT),0,2);\n\t\t$gnmG = substr(str_pad($gnmG,4,'0',STR_PAD_RIGHT),0,2);\n\t\t$gnmB = substr(str_pad($gnmB,4,'0',STR_PAD_RIGHT),0,2);\n\t\t$RGB = $gnmR.$gnmG.$gnmB;\n//\t\techo 'Excel Colour: ',$RGB,'<br />';\n\t\treturn $RGB;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/HTML.php",
    "content": "<?php\n\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n    /**\n     * @ignore\n     */\n    define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n    require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n/**\n * PHPExcel_Reader_HTML\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_HTML extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader\n{\n\n    /**\n     * Input encoding\n     *\n     * @var string\n     */\n    protected $_inputEncoding = 'ANSI';\n\n    /**\n     * Sheet index to read\n     *\n     * @var int\n     */\n    protected $_sheetIndex = 0;\n\n    /**\n     * Formats\n     *\n     * @var array\n     */\n    protected $_formats = array(\n        'h1' => array('font' => array('bold' => true,\n                'size' => 24,\n            ),\n        ), //\tBold, 24pt\n        'h2' => array('font' => array('bold' => true,\n                'size' => 18,\n            ),\n        ), //\tBold, 18pt\n        'h3' => array('font' => array('bold' => true,\n                'size' => 13.5,\n            ),\n        ), //\tBold, 13.5pt\n        'h4' => array('font' => array('bold' => true,\n                'size' => 12,\n            ),\n        ), //\tBold, 12pt\n        'h5' => array('font' => array('bold' => true,\n                'size' => 10,\n            ),\n        ), //\tBold, 10pt\n        'h6' => array('font' => array('bold' => true,\n                'size' => 7.5,\n            ),\n        ), //\tBold, 7.5pt\n        'a' => array('font' => array('underline' => true,\n                'color' => array('argb' => PHPExcel_Style_Color::COLOR_BLUE,\n                ),\n            ),\n        ), //\tBlue underlined\n        'hr' => array('borders' => array('bottom' => array('style' => PHPExcel_Style_Border::BORDER_THIN,\n                    'color' => array(\\PHPExcel_Style_Color::COLOR_BLACK,\n                    ),\n                ),\n            ),\n        ), //\tBottom border\n    );\n\n    protected $rowspan = array();\n\n    /**\n     * Create a new PHPExcel_Reader_HTML\n     */\n    public function __construct()\n    {\n        $this->_readFilter = new PHPExcel_Reader_DefaultReadFilter();\n    }\n\n    /**\n     * Validate that the current file is an HTML file\n     *\n     * @return boolean\n     */\n    protected function _isValidFormat()\n    {\n        //\tReading 2048 bytes should be enough to validate that the format is HTML\n        $data = fread($this->_fileHandle, 2048);\n        if ((strpos($data, '<') !== FALSE) &&\n                (strlen($data) !== strlen(strip_tags($data)))) {\n            return TRUE;\n        }\n\n        return FALSE;\n    }\n\n    /**\n     * Loads PHPExcel from file\n     *\n     * @param  string                    $pFilename\n     * @return PHPExcel\n     * @throws PHPExcel_Reader_Exception\n     */\n    public function load($pFilename)\n    {\n        // Create new PHPExcel\n        $objPHPExcel = new PHPExcel();\n\n        // Load into this instance\n        return $this->loadIntoExisting($pFilename, $objPHPExcel);\n    }\n\n    /**\n     * Set input encoding\n     *\n     * @param string $pValue Input encoding\n     */\n    public function setInputEncoding($pValue = 'ANSI')\n    {\n        $this->_inputEncoding = $pValue;\n\n        return $this;\n    }\n\n    /**\n     * Get input encoding\n     *\n     * @return string\n     */\n    public function getInputEncoding()\n    {\n        return $this->_inputEncoding;\n    }\n\n    //\tData Array used for testing only, should write to PHPExcel object on completion of tests\n    protected $_dataArray = array();\n    protected $_tableLevel = 0;\n    protected $_nestedColumn = array('A');\n\n    protected function _setTableStartColumn($column)\n    {\n        if ($this->_tableLevel == 0)\n            $column = 'A';\n        ++$this->_tableLevel;\n        $this->_nestedColumn[$this->_tableLevel] = $column;\n\n        return $this->_nestedColumn[$this->_tableLevel];\n    }\n\n    protected function _getTableStartColumn()\n    {\n        return $this->_nestedColumn[$this->_tableLevel];\n    }\n\n    protected function _releaseTableStartColumn()\n    {\n        --$this->_tableLevel;\n\n        return array_pop($this->_nestedColumn);\n    }\n\n    protected function _flushCell($sheet, $column, $row, &$cellContent)\n    {\n        if (is_string($cellContent)) {\n            //\tSimple String content\n            if (trim($cellContent) > '') {\n                //\tOnly actually write it if there's content in the string\n//\t\t\t\techo 'FLUSH CELL: ' , $column , $row , ' => ' , $cellContent , '<br />';\n                //\tWrite to worksheet to be done here...\n                //\t... we return the cell so we can mess about with styles more easily\n                $sheet->setCellValue($column . $row, $cellContent, true);\n                $this->_dataArray[$row][$column] = $cellContent;\n            }\n        } else {\n            //\tWe have a Rich Text run\n            //\tTODO\n            $this->_dataArray[$row][$column] = 'RICH TEXT: ' . $cellContent;\n        }\n        $cellContent = (string) '';\n    }\n\n    protected function _processDomElement(DOMNode $element, $sheet, &$row, &$column, &$cellContent, $format = null)\n    {\n        foreach ($element->childNodes as $child) {\n            if ($child instanceof DOMText) {\n                $domText = preg_replace('/\\s+/u', ' ', trim($child->nodeValue));\n                if (is_string($cellContent)) {\n                    //\tsimply append the text if the cell content is a plain text string\n                    $cellContent .= $domText;\n                } else {\n                    //\tbut if we have a rich text run instead, we need to append it correctly\n                    //\tTODO\n                }\n            } elseif ($child instanceof DOMElement) {\n//\t\t\t\techo '<b>DOM ELEMENT: </b>' , strtoupper($child->nodeName) , '<br />';\n\n                $attributeArray = array();\n                foreach ($child->attributes as $attribute) {\n//\t\t\t\t\techo '<b>ATTRIBUTE: </b>' , $attribute->name , ' => ' , $attribute->value , '<br />';\n                    $attributeArray[$attribute->name] = $attribute->value;\n                }\n\n                switch ($child->nodeName) {\n                    case 'meta' :\n                        foreach ($attributeArray as $attributeName => $attributeValue) {\n                            switch ($attributeName) {\n                                case 'content':\n                                    //\tTODO\n                                    //\tExtract character set, so we can convert to UTF-8 if required\n                                    break;\n                            }\n                        }\n                        $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n                        break;\n                    case 'title' :\n                        $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n                        $sheet->setTitle($cellContent);\n                        $cellContent = '';\n                        break;\n                    case 'span' :\n                    case 'div' :\n                    case 'font' :\n                    case 'i' :\n                    case 'em' :\n                    case 'strong':\n                    case 'b' :\n//\t\t\t\t\t\techo 'STYLING, SPAN OR DIV<br />';\n                        if ($cellContent > '')\n                            $cellContent .= ' ';\n                        $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n                        if ($cellContent > '')\n                            $cellContent .= ' ';\n//\t\t\t\t\t\techo 'END OF STYLING, SPAN OR DIV<br />';\n                        break;\n                    case 'hr' :\n                        $this->_flushCell($sheet, $column, $row, $cellContent);\n                        ++$row;\n                        if (isset($this->_formats[$child->nodeName])) {\n                            $sheet->getStyle($column . $row)->applyFromArray($this->_formats[$child->nodeName]);\n                        } else {\n                            $cellContent = '----------';\n                            $this->_flushCell($sheet, $column, $row, $cellContent);\n                        }\n                        ++$row;\n                    case 'br' :\n                        if ($this->_tableLevel > 0) {\n                            //\tIf we're inside a table, replace with a \\n\n                            $cellContent .= \"\\n\";\n                        } else {\n                            //\tOtherwise flush our existing content and move the row cursor on\n                            $this->_flushCell($sheet, $column, $row, $cellContent);\n                            ++$row;\n                        }\n//\t\t\t\t\t\techo 'HARD LINE BREAK: ' , '<br />';\n                        break;\n                    case 'a' :\n//\t\t\t\t\t\techo 'START OF HYPERLINK: ' , '<br />';\n                        foreach ($attributeArray as $attributeName => $attributeValue) {\n                            switch ($attributeName) {\n                                case 'href':\n//\t\t\t\t\t\t\t\t\techo 'Link to ' , $attributeValue , '<br />';\n                                    $sheet->getCell($column . $row)->getHyperlink()->setUrl($attributeValue);\n                                    if (isset($this->_formats[$child->nodeName])) {\n                                        $sheet->getStyle($column . $row)->applyFromArray($this->_formats[$child->nodeName]);\n                                    }\n                                    break;\n                            }\n                        }\n                        $cellContent .= ' ';\n                        $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n//\t\t\t\t\t\techo 'END OF HYPERLINK:' , '<br />';\n                        break;\n                    case 'h1' :\n                    case 'h2' :\n                    case 'h3' :\n                    case 'h4' :\n                    case 'h5' :\n                    case 'h6' :\n                    case 'ol' :\n                    case 'ul' :\n                    case 'p' :\n                        if ($this->_tableLevel > 0) {\n                            //\tIf we're inside a table, replace with a \\n\n                            $cellContent .= \"\\n\";\n//\t\t\t\t\t\t\techo 'LIST ENTRY: ' , '<br />';\n                            $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n//\t\t\t\t\t\t\techo 'END OF LIST ENTRY:' , '<br />';\n                        } else {\n                            if ($cellContent > '') {\n                                $this->_flushCell($sheet, $column, $row, $cellContent);\n                                $row++;\n                            }\n//\t\t\t\t\t\t\techo 'START OF PARAGRAPH: ' , '<br />';\n                            $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n//\t\t\t\t\t\t\techo 'END OF PARAGRAPH:' , '<br />';\n                            $this->_flushCell($sheet, $column, $row, $cellContent);\n\n                            if (isset($this->_formats[$child->nodeName])) {\n                                $sheet->getStyle($column . $row)->applyFromArray($this->_formats[$child->nodeName]);\n                            }\n\n                            $row++;\n                            $column = 'A';\n                        }\n                        break;\n                    case 'li' :\n                        if ($this->_tableLevel > 0) {\n                            //\tIf we're inside a table, replace with a \\n\n                            $cellContent .= \"\\n\";\n//\t\t\t\t\t\t\techo 'LIST ENTRY: ' , '<br />';\n                            $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n//\t\t\t\t\t\t\techo 'END OF LIST ENTRY:' , '<br />';\n                        } else {\n                            if ($cellContent > '') {\n                                $this->_flushCell($sheet, $column, $row, $cellContent);\n                            }\n                            ++$row;\n//\t\t\t\t\t\t\techo 'LIST ENTRY: ' , '<br />';\n                            $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n//\t\t\t\t\t\t\techo 'END OF LIST ENTRY:' , '<br />';\n                            $this->_flushCell($sheet, $column, $row, $cellContent);\n                            $column = 'A';\n                        }\n                        break;\n                    case 'table' :\n                        $this->_flushCell($sheet, $column, $row, $cellContent);\n                        $column = $this->_setTableStartColumn($column);\n//\t\t\t\t\t\techo 'START OF TABLE LEVEL ' , $this->_tableLevel , '<br />';\n                        if ($this->_tableLevel > 1)\n                            --$row;\n                        $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n//\t\t\t\t\t\techo 'END OF TABLE LEVEL ' , $this->_tableLevel , '<br />';\n                        $column = $this->_releaseTableStartColumn();\n                        if ($this->_tableLevel > 1) {\n                            ++$column;\n                        } else {\n                            ++$row;\n                        }\n                        break;\n                    case 'thead' :\n                    case 'tbody' :\n                        $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n                        break;\n                    case 'tr' :\n                        $column = $this->_getTableStartColumn();\n                        $cellContent = '';\n//\t\t\t\t\t\techo 'START OF TABLE ' , $this->_tableLevel , ' ROW<br />';\n                        $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n                        ++$row;\n//\t\t\t\t\t\techo 'END OF TABLE ' , $this->_tableLevel , ' ROW<br />';\n                        break;\n                    case 'th' :\n                    case 'td' :\n//\t\t\t\t\t\techo 'START OF TABLE ' , $this->_tableLevel , ' CELL<br />';\n                        $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n//\t\t\t\t\t\techo 'END OF TABLE ' , $this->_tableLevel , ' CELL<br />';\n\n                        while (isset($this->rowspan[$column . $row])) {\n                            ++$column;\n                        }\n\n                        $this->_flushCell($sheet, $column, $row, $cellContent);\n\n//                        if (isset($attributeArray['style']) && !empty($attributeArray['style'])) {\n//                            $styleAry = $this->getPhpExcelStyleArray($attributeArray['style']);\n//\n//                            if (!empty($styleAry)) {\n//                                $sheet->getStyle($column . $row)->applyFromArray($styleAry);\n//                            }\n//                        }\n\n                        if (isset($attributeArray['rowspan']) && isset($attributeArray['colspan'])) {\n                            //create merging rowspan and colspan\n                            $columnTo = $column;\n                            for ($i = 0; $i < $attributeArray['colspan'] - 1; $i++) {\n                                ++$columnTo;\n                            }\n                            $range = $column . $row . ':' . $columnTo . ($row + $attributeArray['rowspan'] - 1);\n                            foreach (\\PHPExcel_Cell::extractAllCellReferencesInRange($range) as $value) {\n                                $this->rowspan[$value] = true;\n                            }\n                            $sheet->mergeCells($range);\n                            $column = $columnTo;\n                        } elseif (isset($attributeArray['rowspan'])) {\n                            //create merging rowspan\n                            $range = $column . $row . ':' . $column . ($row + $attributeArray['rowspan'] - 1);\n                            foreach (\\PHPExcel_Cell::extractAllCellReferencesInRange($range) as $value) {\n                                $this->rowspan[$value] = true;\n                            }\n                            $sheet->mergeCells($range);\n                        } elseif (isset($attributeArray['colspan'])) {\n                            //create merging colspan\n                            $columnTo = $column;\n                            for ($i = 0; $i < $attributeArray['colspan'] - 1; $i++) {\n                                ++$columnTo;\n                            }\n                            $sheet->mergeCells($column . $row . ':' . $columnTo . $row);\n                            $column = $columnTo;\n                        }\n                        ++$column;\n                        break;\n                    case 'body' :\n                        $row = 1;\n                        $column = 'A';\n                        $content = '';\n                        $this->_tableLevel = 0;\n                        $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n                        break;\n                    default:\n                        $this->_processDomElement($child, $sheet, $row, $column, $cellContent);\n                }\n            }\n        }\n    }\n\n    /**\n     * Loads PHPExcel from file into PHPExcel instance\n     *\n     * @param  string                    $pFilename\n     * @param  PHPExcel                  $objPHPExcel\n     * @return PHPExcel\n     * @throws PHPExcel_Reader_Exception\n     */\n    public function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)\n    {\n        // Open file to validate\n        $this->_openFile($pFilename);\n        if (!$this->_isValidFormat()) {\n            fclose($this->_fileHandle);\n            throw new PHPExcel_Reader_Exception($pFilename . \" is an Invalid HTML file.\");\n        }\n        //\tClose after validating\n        fclose($this->_fileHandle);\n\n        // Create new PHPExcel\n        while ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) {\n            $objPHPExcel->createSheet();\n        }\n        $objPHPExcel->setActiveSheetIndex($this->_sheetIndex);\n\n        //\tCreate a new DOM object\n        $dom = new domDocument;\n        //\tReload the HTML file into the DOM object\n        $loaded = $dom->loadHTML($this->securityScanFile($pFilename));\n        if ($loaded === FALSE) {\n            throw new PHPExcel_Reader_Exception('Failed to load ', $pFilename, ' as a DOM Document');\n        }\n\n        //\tDiscard white space\n        $dom->preserveWhiteSpace = false;\n\n        $row = 0;\n        $column = 'A';\n        $content = '';\n        $this->_processDomElement($dom, $objPHPExcel->getActiveSheet(), $row, $column, $content);\n\n\t\t// Return\n        return $objPHPExcel;\n    }\n\n    /**\n     * Get sheet index\n     *\n     * @return int\n     */\n    public function getSheetIndex()\n    {\n        return $this->_sheetIndex;\n    }\n\n    /**\n     * Set sheet index\n     *\n     * @param  int                  $pValue Sheet index\n     * @return PHPExcel_Reader_HTML\n     */\n    public function setSheetIndex($pValue = 0)\n    {\n        $this->_sheetIndex = $pValue;\n\n        return $this;\n    }\n\n\t/**\n\t * Scan theXML for use of <!ENTITY to prevent XXE/XEE attacks\n\t *\n\t * @param \tstring \t\t$xml\n\t * @throws PHPExcel_Reader_Exception\n\t */\n\tpublic function securityScan($xml)\n\t{\n        $pattern = '/\\\\0?' . implode('\\\\0?', str_split('<!ENTITY')) . '\\\\0?/';\n        if (preg_match($pattern, $xml)) { \n            throw new PHPExcel_Reader_Exception('Detected use of ENTITY in XML, spreadsheet file load() aborted to prevent XXE/XEE attacks');\n        }\n        return $xml;\n    }\n\n}\n\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/IReadFilter.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Reader_IReadFilter\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\ninterface PHPExcel_Reader_IReadFilter\n{\n\t/**\n\t * Should this cell be read?\n\t *\n\t * @param \t$column\t\tString column index\n\t * @param \t$row\t\t\tRow index\n\t * @param\t$worksheetName\tOptional worksheet name\n\t * @return\tboolean\n\t */\n\tpublic function readCell($column, $row, $worksheetName = '');\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/IReader.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Reader_IReader\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\ninterface PHPExcel_Reader_IReader\n{\n\t/**\n\t * Can the current PHPExcel_Reader_IReader read the file?\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @return \tboolean\n\t */\n\tpublic function canRead($pFilename);\n\n\t/**\n\t * Loads PHPExcel from file\n\t *\n\t * @param \tstring \t\t$pFilename\n     * @return  PHPExcel\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function load($pFilename);\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/OOCalc.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n/**\n * PHPExcel_Reader_OOCalc\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Reader\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_OOCalc extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader\n{\n\t/**\n\t * Formats\n\t *\n\t * @var array\n\t */\n\tprivate $_styles = array();\n\n\n\t/**\n\t * Create a new PHPExcel_Reader_OOCalc\n\t */\n\tpublic function __construct() {\n\t\t$this->_readFilter \t= new PHPExcel_Reader_DefaultReadFilter();\n\t}\n\n\n\t/**\n\t * Can the current PHPExcel_Reader_IReader read the file?\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @return \tboolean\n\t * @throws PHPExcel_Reader_Exception\n\t */\n\tpublic function canRead($pFilename)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n        $zipClass = PHPExcel_Settings::getZipClass();\n\n\t\t// Check if zip class exists\n//\t\tif (!class_exists($zipClass, FALSE)) {\n//\t\t\tthrow new PHPExcel_Reader_Exception($zipClass . \" library is not enabled\");\n//\t\t}\n\n        $mimeType = 'UNKNOWN';\n\t\t// Load file\n\t\t$zip = new $zipClass;\n\t\tif ($zip->open($pFilename) === true) {\n\t\t\t// check if it is an OOXML archive\n\t\t\t$stat = $zip->statName('mimetype');\n\t\t\tif ($stat && ($stat['size'] <= 255)) {\n\t\t\t\t$mimeType = $zip->getFromName($stat['name']);\n\t\t\t} elseif($stat = $zip->statName('META-INF/manifest.xml')) {\n\t\t        $xml = simplexml_load_string($this->securityScan($zip->getFromName('META-INF/manifest.xml')), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t        $namespacesContent = $xml->getNamespaces(true);\n\t\t\t\tif (isset($namespacesContent['manifest'])) {\n\t\t\t        $manifest = $xml->children($namespacesContent['manifest']);\n\t\t\t\t    foreach($manifest as $manifestDataSet) {\n\t\t\t\t\t    $manifestAttributes = $manifestDataSet->attributes($namespacesContent['manifest']);\n\t\t\t\t        if ($manifestAttributes->{'full-path'} == '/') {\n\t\t\t\t            $mimeType = (string) $manifestAttributes->{'media-type'};\n\t\t\t\t            break;\n\t\t\t\t    \t}\n\t\t\t\t    }\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$zip->close();\n\n\t\t\treturn ($mimeType === 'application/vnd.oasis.opendocument.spreadsheet');\n\t\t}\n\n\t\treturn FALSE;\n\t}\n\n\n\t/**\n\t * Reads names of the worksheets from a file, without parsing the whole file to a PHPExcel object\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function listWorksheetNames($pFilename)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n        $zipClass = PHPExcel_Settings::getZipClass();\n\n\t\t$zip = new $zipClass;\n\t\tif (!$zip->open($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! Error opening file.\");\n\t\t}\n\n\t\t$worksheetNames = array();\n\n\t\t$xml = new XMLReader();\n\t\t$res = $xml->xml($this->securityScanFile('zip://'.realpath($pFilename).'#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t$xml->setParserProperty(2,true);\n\n\t\t//\tStep into the first level of content of the XML\n\t\t$xml->read();\n\t\twhile ($xml->read()) {\n\t\t\t//\tQuickly jump through to the office:body node\n\t\t\twhile ($xml->name !== 'office:body') {\n\t\t\t\tif ($xml->isEmptyElement)\n\t\t\t\t\t$xml->read();\n\t\t\t\telse\n\t\t\t\t\t$xml->next();\n\t\t\t}\n\t\t\t//\tNow read each node until we find our first table:table node\n\t\t\twhile ($xml->read()) {\n\t\t\t\tif ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {\n\t\t\t\t\t//\tLoop through each table:table node reading the table:name attribute for each worksheet name\n\t\t\t\t\tdo {\n\t\t\t\t\t\t$worksheetNames[] = $xml->getAttribute('table:name');\n\t\t\t\t\t\t$xml->next();\n\t\t\t\t\t} while ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn $worksheetNames;\n\t}\n\n\n\t/**\n\t * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)\n\t *\n\t * @param   string     $pFilename\n\t * @throws   PHPExcel_Reader_Exception\n\t */\n\tpublic function listWorksheetInfo($pFilename)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n\t\t$worksheetInfo = array();\n\n        $zipClass = PHPExcel_Settings::getZipClass();\n\n\t\t$zip = new $zipClass;\n\t\tif (!$zip->open($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! Error opening file.\");\n\t\t}\n\n\t\t$xml = new XMLReader();\n\t\t$res = $xml->xml($this->securityScanFile('zip://'.realpath($pFilename).'#content.xml'), null, PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t$xml->setParserProperty(2,true);\n\n\t\t//\tStep into the first level of content of the XML\n\t\t$xml->read();\n\t\twhile ($xml->read()) {\n\t\t\t//\tQuickly jump through to the office:body node\n\t\t\twhile ($xml->name !== 'office:body') {\n\t\t\t\tif ($xml->isEmptyElement)\n\t\t\t\t\t$xml->read();\n\t\t\t\telse\n\t\t\t\t\t$xml->next();\n\t\t\t}\n\t\t\t\t//\tNow read each node until we find our first table:table node\n\t\t\twhile ($xml->read()) {\n\t\t\t\tif ($xml->name == 'table:table' && $xml->nodeType == XMLReader::ELEMENT) {\n\t\t\t\t\t$worksheetNames[] = $xml->getAttribute('table:name');\n\n\t\t\t\t\t$tmpInfo = array(\n\t\t\t\t\t\t'worksheetName' => $xml->getAttribute('table:name'),\n\t\t\t\t\t\t'lastColumnLetter' => 'A',\n\t\t\t\t\t\t'lastColumnIndex' => 0,\n\t\t\t\t\t\t'totalRows' => 0,\n\t\t\t\t\t\t'totalColumns' => 0,\n\t\t\t\t\t);\n\n\t\t\t\t\t//\tLoop through each child node of the table:table element reading\n\t\t\t\t\t$currCells = 0;\n\t\t\t\t\tdo {\n\t\t\t\t\t\t$xml->read();\n\t\t\t\t\t\tif ($xml->name == 'table:table-row' && $xml->nodeType == XMLReader::ELEMENT) {\n\t\t\t\t\t\t\t$rowspan = $xml->getAttribute('table:number-rows-repeated');\n\t\t\t\t\t\t\t$rowspan = empty($rowspan) ? 1 : $rowspan;\n\t\t\t\t\t\t\t$tmpInfo['totalRows'] += $rowspan;\n\t\t\t\t\t\t\t$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);\n\t\t\t\t\t\t\t$currCells = 0;\n\t\t\t\t\t\t\t//\tStep into the row\n\t\t\t\t\t\t\t$xml->read();\n\t\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\t\tif ($xml->name == 'table:table-cell' && $xml->nodeType == XMLReader::ELEMENT) {\n\t\t\t\t\t\t\t\t\tif (!$xml->isEmptyElement) {\n\t\t\t\t\t\t\t\t\t\t$currCells++;\n\t\t\t\t\t\t\t\t\t\t$xml->next();\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t$xml->read();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} elseif ($xml->name == 'table:covered-table-cell' && $xml->nodeType == XMLReader::ELEMENT) {\n\t\t\t\t\t\t\t\t\t$mergeSize = $xml->getAttribute('table:number-columns-repeated');\n\t\t\t\t\t\t\t\t\t$currCells += $mergeSize;\n\t\t\t\t\t\t\t\t\t$xml->read();\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} while ($xml->name != 'table:table-row');\n\t\t\t\t\t\t}\n\t\t\t\t\t} while ($xml->name != 'table:table');\n\n\t\t\t\t\t$tmpInfo['totalColumns'] = max($tmpInfo['totalColumns'],$currCells);\n\t\t\t\t\t$tmpInfo['lastColumnIndex'] = $tmpInfo['totalColumns'] - 1;\n\t\t\t\t\t$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);\n\t\t\t\t\t$worksheetInfo[] = $tmpInfo;\n\t\t\t\t}\n\t\t\t}\n\n//\t\t\t\tforeach($workbookData->table as $worksheetDataSet) {\n//\t\t\t\t\t$worksheetData = $worksheetDataSet->children($namespacesContent['table']);\n//\t\t\t\t\t$worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']);\n//\n//\t\t\t\t\t$rowIndex = 0;\n//\t\t\t\t\tforeach ($worksheetData as $key => $rowData) {\n//\t\t\t\t\t\tswitch ($key) {\n//\t\t\t\t\t\t\tcase 'table-row' :\n//\t\t\t\t\t\t\t\t$rowDataTableAttributes = $rowData->attributes($namespacesContent['table']);\n//\t\t\t\t\t\t\t\t$rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ?\n//\t\t\t\t\t\t\t\t\t\t$rowDataTableAttributes['number-rows-repeated'] : 1;\n//\t\t\t\t\t\t\t\t$columnIndex = 0;\n//\n//\t\t\t\t\t\t\t\tforeach ($rowData as $key => $cellData) {\n//\t\t\t\t\t\t\t\t\t$cellDataTableAttributes = $cellData->attributes($namespacesContent['table']);\n//\t\t\t\t\t\t\t\t\t$colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ?\n//\t\t\t\t\t\t\t\t\t\t$cellDataTableAttributes['number-columns-repeated'] : 1;\n//\t\t\t\t\t\t\t\t\t$cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']);\n//\t\t\t\t\t\t\t\t\tif (isset($cellDataOfficeAttributes['value-type'])) {\n//\t\t\t\t\t\t\t\t\t\t$tmpInfo['lastColumnIndex'] = max($tmpInfo['lastColumnIndex'], $columnIndex + $colRepeats - 1);\n//\t\t\t\t\t\t\t\t\t\t$tmpInfo['totalRows'] = max($tmpInfo['totalRows'], $rowIndex + $rowRepeats);\n//\t\t\t\t\t\t\t\t\t}\n//\t\t\t\t\t\t\t\t\t$columnIndex += $colRepeats;\n//\t\t\t\t\t\t\t\t}\n//\t\t\t\t\t\t\t\t$rowIndex += $rowRepeats;\n//\t\t\t\t\t\t\t\tbreak;\n//\t\t\t\t\t\t}\n//\t\t\t\t\t}\n//\n//\t\t\t\t\t$tmpInfo['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($tmpInfo['lastColumnIndex']);\n//\t\t\t\t\t$tmpInfo['totalColumns'] = $tmpInfo['lastColumnIndex'] + 1;\n//\n//\t\t\t\t}\n//\t\t\t}\n\t\t}\n\n\t\treturn $worksheetInfo;\n\t}\n\n\n\t/**\n\t * Loads PHPExcel from file\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @return \tPHPExcel\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function load($pFilename)\n\t{\n\t\t// Create new PHPExcel\n\t\t$objPHPExcel = new PHPExcel();\n\n\t\t// Load into this instance\n\t\treturn $this->loadIntoExisting($pFilename, $objPHPExcel);\n\t}\n\n\n\tprivate static function identifyFixedStyleValue($styleList,&$styleAttributeValue) {\n\t\t$styleAttributeValue = strtolower($styleAttributeValue);\n\t\tforeach($styleList as $style) {\n\t\t\tif ($styleAttributeValue == strtolower($style)) {\n\t\t\t\t$styleAttributeValue = $style;\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\t\treturn false;\n\t}\n\n\n\t/**\n\t * Loads PHPExcel from file into PHPExcel instance\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @param\tPHPExcel\t$objPHPExcel\n\t * @return \tPHPExcel\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)\n\t{\n\t\t// Check if file exists\n\t\tif (!file_exists($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! File does not exist.\");\n\t\t}\n\n\t\t$timezoneObj = new DateTimeZone('Europe/London');\n\t\t$GMT = new DateTimeZone('UTC');\n\n        $zipClass = PHPExcel_Settings::getZipClass();\n\n\t\t$zip = new $zipClass;\n\t\tif (!$zip->open($pFilename)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $pFilename . \" for reading! Error opening file.\");\n\t\t}\n\n//\t\techo '<h1>Meta Information</h1>';\n\t\t$xml = simplexml_load_string($this->securityScan($zip->getFromName(\"meta.xml\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t$namespacesMeta = $xml->getNamespaces(true);\n//\t\techo '<pre>';\n//\t\tprint_r($namespacesMeta);\n//\t\techo '</pre><hr />';\n\n\t\t$docProps = $objPHPExcel->getProperties();\n\t\t$officeProperty = $xml->children($namespacesMeta['office']);\n\t\tforeach($officeProperty as $officePropertyData) {\n\t\t\t$officePropertyDC = array();\n\t\t\tif (isset($namespacesMeta['dc'])) {\n\t\t\t\t$officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);\n\t\t\t}\n\t\t\tforeach($officePropertyDC as $propertyName => $propertyValue) {\n\t\t\t\t$propertyValue = (string) $propertyValue;\n\t\t\t\tswitch ($propertyName) {\n\t\t\t\t\tcase 'title' :\n\t\t\t\t\t\t\t$docProps->setTitle($propertyValue);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'subject' :\n\t\t\t\t\t\t\t$docProps->setSubject($propertyValue);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'creator' :\n\t\t\t\t\t\t\t$docProps->setCreator($propertyValue);\n\t\t\t\t\t\t\t$docProps->setLastModifiedBy($propertyValue);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'date' :\n\t\t\t\t\t\t\t$creationDate = strtotime($propertyValue);\n\t\t\t\t\t\t\t$docProps->setCreated($creationDate);\n\t\t\t\t\t\t\t$docProps->setModified($creationDate);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'description' :\n\t\t\t\t\t\t\t$docProps->setDescription($propertyValue);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\t$officePropertyMeta = array();\n\t\t\tif (isset($namespacesMeta['dc'])) {\n\t\t\t\t$officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);\n\t\t\t}\n\t\t\tforeach($officePropertyMeta as $propertyName => $propertyValue) {\n\t\t\t\t$propertyValueAttributes = $propertyValue->attributes($namespacesMeta['meta']);\n\t\t\t\t$propertyValue = (string) $propertyValue;\n\t\t\t\tswitch ($propertyName) {\n\t\t\t\t\tcase 'initial-creator' :\n\t\t\t\t\t\t\t$docProps->setCreator($propertyValue);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'keyword' :\n\t\t\t\t\t\t\t$docProps->setKeywords($propertyValue);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'creation-date' :\n\t\t\t\t\t\t\t$creationDate = strtotime($propertyValue);\n\t\t\t\t\t\t\t$docProps->setCreated($creationDate);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'user-defined' :\n\t\t\t\t\t\t\t$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING;\n\t\t\t\t\t\t\tforeach ($propertyValueAttributes as $key => $value) {\n\t\t\t\t\t\t\t\tif ($key == 'name') {\n\t\t\t\t\t\t\t\t\t$propertyValueName = (string) $value;\n\t\t\t\t\t\t\t\t} elseif($key == 'value-type') {\n\t\t\t\t\t\t\t\t\tswitch ($value) {\n\t\t\t\t\t\t\t\t\t\tcase 'date'\t:\n\t\t\t\t\t\t\t\t\t\t\t$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'date');\n\t\t\t\t\t\t\t\t\t\t\t$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE;\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tcase 'boolean'\t:\n\t\t\t\t\t\t\t\t\t\t\t$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'bool');\n\t\t\t\t\t\t\t\t\t\t\t$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN;\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tcase 'float'\t:\n\t\t\t\t\t\t\t\t\t\t\t$propertyValue = PHPExcel_DocumentProperties::convertProperty($propertyValue,'r4');\n\t\t\t\t\t\t\t\t\t\t\t$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_FLOAT;\n\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tdefault :\n\t\t\t\t\t\t\t\t\t\t\t$propertyValueType = PHPExcel_DocumentProperties::PROPERTY_TYPE_STRING;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$docProps->setCustomProperty($propertyValueName,$propertyValue,$propertyValueType);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\n//\t\techo '<h1>Workbook Content</h1>';\n\t\t$xml = simplexml_load_string($this->securityScan($zip->getFromName(\"content.xml\")), 'SimpleXMLElement', PHPExcel_Settings::getLibXmlLoaderOptions());\n\t\t$namespacesContent = $xml->getNamespaces(true);\n//\t\techo '<pre>';\n//\t\tprint_r($namespacesContent);\n//\t\techo '</pre><hr />';\n\n\t\t$workbook = $xml->children($namespacesContent['office']);\n\t\tforeach($workbook->body->spreadsheet as $workbookData) {\n\t\t\t$workbookData = $workbookData->children($namespacesContent['table']);\n\t\t\t$worksheetID = 0;\n\t\t\tforeach($workbookData->table as $worksheetDataSet) {\n\t\t\t\t$worksheetData = $worksheetDataSet->children($namespacesContent['table']);\n//\t\t\t\tprint_r($worksheetData);\n//\t\t\t\techo '<br />';\n\t\t\t\t$worksheetDataAttributes = $worksheetDataSet->attributes($namespacesContent['table']);\n//\t\t\t\tprint_r($worksheetDataAttributes);\n//\t\t\t\techo '<br />';\n\t\t\t\tif ((isset($this->_loadSheetsOnly)) && (isset($worksheetDataAttributes['name'])) &&\n\t\t\t\t\t(!in_array($worksheetDataAttributes['name'], $this->_loadSheetsOnly))) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\n//\t\t\t\techo '<h2>Worksheet '.$worksheetDataAttributes['name'].'</h2>';\n\t\t\t\t// Create new Worksheet\n\t\t\t\t$objPHPExcel->createSheet();\n\t\t\t\t$objPHPExcel->setActiveSheetIndex($worksheetID);\n\t\t\t\tif (isset($worksheetDataAttributes['name'])) {\n\t\t\t\t\t$worksheetName = (string) $worksheetDataAttributes['name'];\n\t\t\t\t\t//\tUse false for $updateFormulaCellReferences to prevent adjustment of worksheet references in\n\t\t\t\t\t//\t\tformula cells... during the load, all formulae should be correct, and we're simply\n\t\t\t\t\t//\t\tbringing the worksheet name in line with the formula, not the reverse\n\t\t\t\t\t$objPHPExcel->getActiveSheet()->setTitle($worksheetName,false);\n\t\t\t\t}\n\n\t\t\t\t$rowID = 1;\n\t\t\t\tforeach($worksheetData as $key => $rowData) {\n//\t\t\t\t\techo '<b>'.$key.'</b><br />';\n\t\t\t\t\tswitch ($key) {\n\t\t\t\t\t\tcase 'table-header-rows':\n\t\t\t\t\t\t\tforeach ($rowData as $key=>$cellData) {\n\t\t\t\t\t\t\t\t$rowData = $cellData;\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\tcase 'table-row' :\n\t\t\t\t\t\t\t$rowDataTableAttributes = $rowData->attributes($namespacesContent['table']);\n\t\t\t\t\t\t\t$rowRepeats = (isset($rowDataTableAttributes['number-rows-repeated'])) ?\n\t\t\t\t\t\t\t\t\t$rowDataTableAttributes['number-rows-repeated'] : 1;\n\t\t\t\t\t\t\t$columnID = 'A';\n\t\t\t\t\t\t\tforeach($rowData as $key => $cellData) {\n\t\t\t\t\t\t\t\tif ($this->getReadFilter() !== NULL) {\n\t\t\t\t\t\t\t\t\tif (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) {\n\t\t\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n//\t\t\t\t\t\t\t\techo '<b>'.$columnID.$rowID.'</b><br />';\n\t\t\t\t\t\t\t\t$cellDataText = (isset($namespacesContent['text'])) ?\n\t\t\t\t\t\t\t\t\t$cellData->children($namespacesContent['text']) :\n\t\t\t\t\t\t\t\t\t'';\n\t\t\t\t\t\t\t\t$cellDataOffice = $cellData->children($namespacesContent['office']);\n\t\t\t\t\t\t\t\t$cellDataOfficeAttributes = $cellData->attributes($namespacesContent['office']);\n\t\t\t\t\t\t\t\t$cellDataTableAttributes = $cellData->attributes($namespacesContent['table']);\n\n//\t\t\t\t\t\t\t\techo 'Office Attributes: ';\n//\t\t\t\t\t\t\t\tprint_r($cellDataOfficeAttributes);\n//\t\t\t\t\t\t\t\techo '<br />Table Attributes: ';\n//\t\t\t\t\t\t\t\tprint_r($cellDataTableAttributes);\n//\t\t\t\t\t\t\t\techo '<br />Cell Data Text';\n//\t\t\t\t\t\t\t\tprint_r($cellDataText);\n//\t\t\t\t\t\t\t\techo '<br />';\n//\n\t\t\t\t\t\t\t\t$type = $formatting = $hyperlink = null;\n\t\t\t\t\t\t\t\t$hasCalculatedValue = false;\n\t\t\t\t\t\t\t\t$cellDataFormula = '';\n\t\t\t\t\t\t\t\tif (isset($cellDataTableAttributes['formula'])) {\n\t\t\t\t\t\t\t\t\t$cellDataFormula = $cellDataTableAttributes['formula'];\n\t\t\t\t\t\t\t\t\t$hasCalculatedValue = true;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif (isset($cellDataOffice->annotation)) {\n//\t\t\t\t\t\t\t\t\techo 'Cell has comment<br />';\n\t\t\t\t\t\t\t\t\t$annotationText = $cellDataOffice->annotation->children($namespacesContent['text']);\n\t\t\t\t\t\t\t\t\t$textArray = array();\n\t\t\t\t\t\t\t\t\tforeach($annotationText as $t) {\n\t\t\t\t\t\t\t\t\t    if (isset($t->span)) {\n    \t\t\t\t\t\t\t\t\t\tforeach($t->span as $text) {\n    \t\t\t\t\t\t\t\t\t\t\t$textArray[] = (string)$text;\n    \t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t    } else {\n\t\t\t\t\t\t\t\t\t        $textArray[] = (string) $t;\n\t\t\t\t\t\t\t\t\t    }\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t$text = implode(\"\\n\",$textArray);\n//\t\t\t\t\t\t\t\t\techo $text,'<br />';\n\t\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getComment( $columnID.$rowID )\n//\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t->setAuthor( $author )\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t->setText($this->_parseRichText($text) );\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\tif (isset($cellDataText->p)) {\n\t\t\t\t\t\t\t\t\t// Consolidate if there are multiple p records (maybe with spans as well)\n\t\t\t\t\t\t\t\t\t$dataArray = array();\n\t\t\t\t\t\t\t\t\t// Text can have multiple text:p and within those, multiple text:span.\n\t\t\t\t\t\t\t\t\t// text:p newlines, but text:span does not.\n\t\t\t\t\t\t\t\t\t// Also, here we assume there is no text data is span fields are specified, since\n\t\t\t\t\t\t\t\t\t// we have no way of knowing proper positioning anyway.\n\t\t\t\t\t\t\t\t\tforeach ($cellDataText->p as $pData) {\n\t\t\t\t\t\t\t\t\t\tif (isset($pData->span)) {\n\t\t\t\t\t\t\t\t\t\t\t// span sections do not newline, so we just create one large string here\n\t\t\t\t\t\t\t\t\t\t\t$spanSection = \"\";\n\t\t\t\t\t\t\t\t\t\t\tforeach ($pData->span as $spanData) {\n\t\t\t\t\t\t\t\t\t\t\t\t$spanSection .= $spanData;\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tarray_push($dataArray, $spanSection);\n\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\tarray_push($dataArray, $pData);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t$allCellDataText = implode($dataArray, \"\\n\");\n\n//\t\t\t\t\t\t\t\t\techo 'Value Type is '.$cellDataOfficeAttributes['value-type'].'<br />';\n\t\t\t\t\t\t\t\t\tswitch ($cellDataOfficeAttributes['value-type']) {\n \t\t\t\t\t\t\t\t\t\tcase 'string' :\n\t\t\t\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_STRING;\n\t\t\t\t\t\t\t\t\t\t\t\t$dataValue = $allCellDataText;\n\t\t\t\t\t\t\t\t\t\t\t\tif (isset($dataValue->a)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$dataValue = $dataValue->a;\n\t\t\t\t\t\t\t\t\t\t\t\t\t$cellXLinkAttributes = $dataValue->attributes($namespacesContent['xlink']);\n\t\t\t\t\t\t\t\t\t\t\t\t\t$hyperlink = $cellXLinkAttributes['href'];\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tcase 'boolean' :\n\t\t\t\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_BOOL;\n\t\t\t\t\t\t\t\t\t\t\t\t$dataValue = ($allCellDataText == 'TRUE') ? True : False;\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tcase 'percentage' :\n\t\t\t\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;\n\t\t\t\t\t\t\t\t\t\t\t\t$dataValue = (float) $cellDataOfficeAttributes['value'];\n\t\t\t\t\t\t\t\t\t\t\t\tif (floor($dataValue) == $dataValue) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$dataValue = (integer) $dataValue;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t$formatting = PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00;\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tcase 'currency' :\n\t\t\t\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;\n\t\t\t\t\t\t\t\t\t\t\t\t$dataValue = (float) $cellDataOfficeAttributes['value'];\n\t\t\t\t\t\t\t\t\t\t\t\tif (floor($dataValue) == $dataValue) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$dataValue = (integer) $dataValue;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t$formatting = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE;\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tcase 'float' :\n\t\t\t\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;\n\t\t\t\t\t\t\t\t\t\t\t\t$dataValue = (float) $cellDataOfficeAttributes['value'];\n\t\t\t\t\t\t\t\t\t\t\t\tif (floor($dataValue) == $dataValue) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tif ($dataValue == (integer) $dataValue)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$dataValue = (integer) $dataValue;\n\t\t\t\t\t\t\t\t\t\t\t\t\telse\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t$dataValue = (float) $dataValue;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tcase 'date' :\n\t\t\t\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;\n\t\t\t\t\t\t\t\t\t\t\t    $dateObj = new DateTime($cellDataOfficeAttributes['date-value'], $GMT);\n\t\t\t\t\t\t\t\t\t\t\t\t$dateObj->setTimeZone($timezoneObj);\n\t\t\t\t\t\t\t\t\t\t\t\tlist($year,$month,$day,$hour,$minute,$second) = explode(' ',$dateObj->format('Y m d H i s'));\n\t\t\t\t\t\t\t\t\t\t\t\t$dataValue = PHPExcel_Shared_Date::FormattedPHPToExcel($year,$month,$day,$hour,$minute,$second);\n\t\t\t\t\t\t\t\t\t\t\t\tif ($dataValue != floor($dataValue)) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15.' '.PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4;\n\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15;\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\tcase 'time' :\n\t\t\t\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_NUMERIC;\n\t\t\t\t\t\t\t\t\t\t\t\t$dataValue = PHPExcel_Shared_Date::PHPToExcel(strtotime('01-01-1970 '.implode(':',sscanf($cellDataOfficeAttributes['time-value'],'PT%dH%dM%dS'))));\n\t\t\t\t\t\t\t\t\t\t\t\t$formatting = PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4;\n\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t}\n//\t\t\t\t\t\t\t\t\techo 'Data value is '.$dataValue.'<br />';\n//\t\t\t\t\t\t\t\t\tif ($hyperlink !== NULL) {\n//\t\t\t\t\t\t\t\t\t\techo 'Hyperlink is '.$hyperlink.'<br />';\n//\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_NULL;\n\t\t\t\t\t\t\t\t\t$dataValue = NULL;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tif ($hasCalculatedValue) {\n\t\t\t\t\t\t\t\t\t$type = PHPExcel_Cell_DataType::TYPE_FORMULA;\n//\t\t\t\t\t\t\t\t\techo 'Formula: ', $cellDataFormula, PHP_EOL;\n\t\t\t\t\t\t\t\t\t$cellDataFormula = substr($cellDataFormula,strpos($cellDataFormula,':=')+1);\n\t\t\t\t\t\t\t\t\t$temp = explode('\"',$cellDataFormula);\n\t\t\t\t\t\t\t\t\t$tKey = false;\n\t\t\t\t\t\t\t\t\tforeach($temp as &$value) {\n\t\t\t\t\t\t\t\t\t\t//\tOnly replace in alternate array entries (i.e. non-quoted blocks)\n\t\t\t\t\t\t\t\t\t\tif ($tKey = !$tKey) {\n\t\t\t\t\t\t\t\t\t\t\t$value = preg_replace('/\\[([^\\.]+)\\.([^\\.]+):\\.([^\\.]+)\\]/Ui','$1!$2:$3',$value);    //  Cell range reference in another sheet\n\t\t\t\t\t\t\t\t\t\t\t$value = preg_replace('/\\[([^\\.]+)\\.([^\\.]+)\\]/Ui','$1!$2',$value);       //  Cell reference in another sheet\n\t\t\t\t\t\t\t\t\t\t\t$value = preg_replace('/\\[\\.([^\\.]+):\\.([^\\.]+)\\]/Ui','$1:$2',$value);    //  Cell range reference\n\t\t\t\t\t\t\t\t\t\t\t$value = preg_replace('/\\[\\.([^\\.]+)\\]/Ui','$1',$value);                  //  Simple cell reference\n\t\t\t\t\t\t\t\t\t\t\t$value = PHPExcel_Calculation::_translateSeparator(';',',',$value,$inBraces);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tunset($value);\n\t\t\t\t\t\t\t\t\t//\tThen rebuild the formula string\n\t\t\t\t\t\t\t\t\t$cellDataFormula = implode('\"',$temp);\n//\t\t\t\t\t\t\t\t\techo 'Adjusted Formula: ', $cellDataFormula, PHP_EOL;\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t$colRepeats = (isset($cellDataTableAttributes['number-columns-repeated'])) ?\n\t\t\t\t\t\t\t\t\t$cellDataTableAttributes['number-columns-repeated'] : 1;\n\t\t\t\t\t\t\t\tif ($type !== NULL) {\n\t\t\t\t\t\t\t\t\tfor ($i = 0; $i < $colRepeats; ++$i) {\n\t\t\t\t\t\t\t\t\t\tif ($i > 0) {\n\t\t\t\t\t\t\t\t\t\t\t++$columnID;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\tif ($type !== PHPExcel_Cell_DataType::TYPE_NULL) {\n\t\t\t\t\t\t\t\t\t\t\tfor ($rowAdjust = 0; $rowAdjust < $rowRepeats; ++$rowAdjust) {\n\t\t\t\t\t\t\t\t\t\t\t\t$rID = $rowID + $rowAdjust;\n\t\t\t\t\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setValueExplicit((($hasCalculatedValue) ? $cellDataFormula : $dataValue),$type);\n\t\t\t\t\t\t\t\t\t\t\t\tif ($hasCalculatedValue) {\n//\t\t\t\t\t\t\t\t\t\t\t\t\techo 'Forumla result is '.$dataValue.'<br />';\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->setCalculatedValue($dataValue);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tif ($formatting !== NULL) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode($formatting);\n\t\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getStyle($columnID.$rID)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_GENERAL);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\tif ($hyperlink !== NULL) {\n\t\t\t\t\t\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getCell($columnID.$rID)->getHyperlink()->setUrl($hyperlink);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t//\tMerged cells\n\t\t\t\t\t\t\t\tif ((isset($cellDataTableAttributes['number-columns-spanned'])) || (isset($cellDataTableAttributes['number-rows-spanned']))) {\n\t\t\t\t\t\t\t\t\tif (($type !== PHPExcel_Cell_DataType::TYPE_NULL) || (!$this->_readDataOnly)) {\n\t\t\t\t\t\t\t\t\t\t$columnTo = $columnID;\n\t\t\t\t\t\t\t\t\t\tif (isset($cellDataTableAttributes['number-columns-spanned'])) {\n\t\t\t\t\t\t\t\t\t\t\t$columnTo = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($columnID) + $cellDataTableAttributes['number-columns-spanned'] -2);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t$rowTo = $rowID;\n\t\t\t\t\t\t\t\t\t\tif (isset($cellDataTableAttributes['number-rows-spanned'])) {\n\t\t\t\t\t\t\t\t\t\t\t$rowTo = $rowTo + $cellDataTableAttributes['number-rows-spanned'] - 1;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t$cellRange = $columnID.$rowID.':'.$columnTo.$rowTo;\n\t\t\t\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->mergeCells($cellRange);\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t++$columnID;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$rowID += $rowRepeats;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t++$worksheetID;\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $objPHPExcel;\n\t}\n\n\n\tprivate function _parseRichText($is = '') {\n\t\t$value = new PHPExcel_RichText();\n\n\t\t$value->createText($is);\n\n\t\treturn $value;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Reader/SYLK.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n/**\n * PHPExcel_Reader_SYLK\n *\n * @category   PHPExcel\n * @package    PHPExcel_Reader\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Reader_SYLK extends PHPExcel_Reader_Abstract implements PHPExcel_Reader_IReader\n{\n\t/**\n\t * Input encoding\n\t *\n\t * @var string\n\t */\n\tprivate $_inputEncoding\t= 'ANSI';\n\n\t/**\n\t * Sheet index to read\n\t *\n\t * @var int\n\t */\n\tprivate $_sheetIndex \t= 0;\n\n\t/**\n\t * Formats\n\t *\n\t * @var array\n\t */\n\tprivate $_formats = array();\n\n\t/**\n\t * Format Count\n\t *\n\t * @var int\n\t */\n\tprivate $_format = 0;\n\n\t/**\n\t * Create a new PHPExcel_Reader_SYLK\n\t */\n\tpublic function __construct() {\n\t\t$this->_readFilter \t= new PHPExcel_Reader_DefaultReadFilter();\n\t}\n\n\t/**\n\t * Validate that the current file is a SYLK file\n\t *\n\t * @return boolean\n\t */\n\tprotected function _isValidFormat()\n\t{\n\t\t// Read sample data (first 2 KB will do)\n\t\t$data = fread($this->_fileHandle, 2048);\n\n\t\t// Count delimiters in file\n\t\t$delimiterCount = substr_count($data, ';');\n\t\tif ($delimiterCount < 1) {\n\t\t\treturn FALSE;\n\t\t}\n\n\t\t// Analyze first line looking for ID; signature\n\t\t$lines = explode(\"\\n\", $data);\n\t\tif (substr($lines[0],0,4) != 'ID;P') {\n\t\t\treturn FALSE;\n\t\t}\n\n\t\treturn TRUE;\n\t}\n\n\t/**\n\t * Set input encoding\n\t *\n\t * @param string $pValue Input encoding\n\t */\n\tpublic function setInputEncoding($pValue = 'ANSI')\n\t{\n\t\t$this->_inputEncoding = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get input encoding\n\t *\n\t * @return string\n\t */\n\tpublic function getInputEncoding()\n\t{\n\t\treturn $this->_inputEncoding;\n\t}\n\n\t/**\n\t * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns)\n\t *\n\t * @param   string     $pFilename\n\t * @throws   PHPExcel_Reader_Exception\n\t */\n\tpublic function listWorksheetInfo($pFilename)\n\t{\n\t\t// Open file\n\t\t$this->_openFile($pFilename);\n\t\tif (!$this->_isValidFormat()) {\n\t\t\tfclose ($this->_fileHandle);\n\t\t\tthrow new PHPExcel_Reader_Exception($pFilename . \" is an Invalid Spreadsheet file.\");\n\t\t}\n\t\t$fileHandle = $this->_fileHandle;\n\t\trewind($fileHandle);\n\n\t\t$worksheetInfo = array();\n\t\t$worksheetInfo[0]['worksheetName'] = 'Worksheet';\n\t\t$worksheetInfo[0]['lastColumnLetter'] = 'A';\n\t\t$worksheetInfo[0]['lastColumnIndex'] = 0;\n\t\t$worksheetInfo[0]['totalRows'] = 0;\n\t\t$worksheetInfo[0]['totalColumns'] = 0;\n\n\t\t// Loop through file\n\t\t$rowData = array();\n\n\t\t// loop through one row (line) at a time in the file\n\t\t$rowIndex = 0;\n\t\twhile (($rowData = fgets($fileHandle)) !== FALSE) {\n\t\t\t$columnIndex = 0;\n\n\t\t\t// convert SYLK encoded $rowData to UTF-8\n\t\t\t$rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData);\n\n\t\t\t// explode each row at semicolons while taking into account that literal semicolon (;)\n\t\t\t// is escaped like this (;;)\n\t\t\t$rowData = explode(\"\\t\",str_replace('¤',';',str_replace(';',\"\\t\",str_replace(';;','¤',rtrim($rowData)))));\n\n\t\t\t$dataType = array_shift($rowData);\n\t\t\tif ($dataType == 'C') {\n\t\t\t\t//  Read cell value data\n\t\t\t\tforeach($rowData as $rowDatum) {\n\t\t\t\t\tswitch($rowDatum{0}) {\n\t\t\t\t\t\tcase 'C' :\n\t\t\t\t\t\tcase 'X' :\n\t\t\t\t\t\t\t$columnIndex = substr($rowDatum,1) - 1;\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'R' :\n\t\t\t\t\t\tcase 'Y' :\n\t\t\t\t\t\t\t$rowIndex = substr($rowDatum,1);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t\t$worksheetInfo[0]['totalRows'] = max($worksheetInfo[0]['totalRows'], $rowIndex);\n\t\t\t\t\t$worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], $columnIndex);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t$worksheetInfo[0]['lastColumnLetter'] = PHPExcel_Cell::stringFromColumnIndex($worksheetInfo[0]['lastColumnIndex']);\n\t\t$worksheetInfo[0]['totalColumns'] = $worksheetInfo[0]['lastColumnIndex'] + 1;\n\n\t\t// Close file\n\t\tfclose($fileHandle);\n\n\t\treturn $worksheetInfo;\n\t}\n\n\t/**\n\t * Loads PHPExcel from file\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @return \tPHPExcel\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function load($pFilename)\n\t{\n\t\t// Create new PHPExcel\n\t\t$objPHPExcel = new PHPExcel();\n\n\t\t// Load into this instance\n\t\treturn $this->loadIntoExisting($pFilename, $objPHPExcel);\n\t}\n\n\t/**\n\t * Loads PHPExcel from file into PHPExcel instance\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @param\tPHPExcel\t$objPHPExcel\n\t * @return \tPHPExcel\n\t * @throws \tPHPExcel_Reader_Exception\n\t */\n\tpublic function loadIntoExisting($pFilename, PHPExcel $objPHPExcel)\n\t{\n\t\t// Open file\n\t\t$this->_openFile($pFilename);\n\t\tif (!$this->_isValidFormat()) {\n\t\t\tfclose ($this->_fileHandle);\n\t\t\tthrow new PHPExcel_Reader_Exception($pFilename . \" is an Invalid Spreadsheet file.\");\n\t\t}\n\t\t$fileHandle = $this->_fileHandle;\n\t\trewind($fileHandle);\n\n\t\t// Create new PHPExcel\n\t\twhile ($objPHPExcel->getSheetCount() <= $this->_sheetIndex) {\n\t\t\t$objPHPExcel->createSheet();\n\t\t}\n\t\t$objPHPExcel->setActiveSheetIndex( $this->_sheetIndex );\n\n\t\t$fromFormats\t= array('\\-',\t'\\ ');\n\t\t$toFormats\t\t= array('-',\t' ');\n\n\t\t// Loop through file\n\t\t$rowData = array();\n\t\t$column = $row = '';\n\n\t\t// loop through one row (line) at a time in the file\n\t\twhile (($rowData = fgets($fileHandle)) !== FALSE) {\n\n\t\t\t// convert SYLK encoded $rowData to UTF-8\n\t\t\t$rowData = PHPExcel_Shared_String::SYLKtoUTF8($rowData);\n\n\t\t\t// explode each row at semicolons while taking into account that literal semicolon (;)\n\t\t\t// is escaped like this (;;)\n\t\t\t$rowData = explode(\"\\t\",str_replace('¤',';',str_replace(';',\"\\t\",str_replace(';;','¤',rtrim($rowData)))));\n\n\t\t\t$dataType = array_shift($rowData);\n\t\t\t//\tRead shared styles\n\t\t\tif ($dataType == 'P') {\n\t\t\t\t$formatArray = array();\n\t\t\t\tforeach($rowData as $rowDatum) {\n\t\t\t\t\tswitch($rowDatum{0}) {\n\t\t\t\t\t\tcase 'P' :\t$formatArray['numberformat']['code'] = str_replace($fromFormats,$toFormats,substr($rowDatum,1));\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'E' :\n\t\t\t\t\t\tcase 'F' :\t$formatArray['font']['name'] = substr($rowDatum,1);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'L' :\t$formatArray['font']['size'] = substr($rowDatum,1);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'S' :\t$styleSettings = substr($rowDatum,1);\n\t\t\t\t\t\t\t\t\tfor ($i=0;$i<strlen($styleSettings);++$i) {\n\t\t\t\t\t\t\t\t\t\tswitch ($styleSettings{$i}) {\n\t\t\t\t\t\t\t\t\t\t\tcase 'I' :\t$formatArray['font']['italic'] = true;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase 'D' :\t$formatArray['font']['bold'] = true;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase 'T' :\t$formatArray['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase 'B' :\t$formatArray['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase 'L' :\t$formatArray['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase 'R' :\t$formatArray['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$this->_formats['P'.$this->_format++] = $formatArray;\n\t\t\t//\tRead cell value data\n\t\t\t} elseif ($dataType == 'C') {\n\t\t\t\t$hasCalculatedValue = false;\n\t\t\t\t$cellData = $cellDataFormula = '';\n\t\t\t\tforeach($rowData as $rowDatum) {\n\t\t\t\t\tswitch($rowDatum{0}) {\n\t\t\t\t\t\tcase 'C' :\n\t\t\t\t\t\tcase 'X' :\t$column = substr($rowDatum,1);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'R' :\n\t\t\t\t\t\tcase 'Y' :\t$row = substr($rowDatum,1);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'K' :\t$cellData = substr($rowDatum,1);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'E' :\t$cellDataFormula = '='.substr($rowDatum,1);\n\t\t\t\t\t\t\t\t\t//\tConvert R1C1 style references to A1 style references (but only when not quoted)\n\t\t\t\t\t\t\t\t\t$temp = explode('\"',$cellDataFormula);\n\t\t\t\t\t\t\t\t\t$key = false;\n\t\t\t\t\t\t\t\t\tforeach($temp as &$value) {\n\t\t\t\t\t\t\t\t\t\t//\tOnly count/replace in alternate array entries\n\t\t\t\t\t\t\t\t\t\tif ($key = !$key) {\n\t\t\t\t\t\t\t\t\t\t\tpreg_match_all('/(R(\\[?-?\\d*\\]?))(C(\\[?-?\\d*\\]?))/',$value, $cellReferences,PREG_SET_ORDER+PREG_OFFSET_CAPTURE);\n\t\t\t\t\t\t\t\t\t\t\t//\tReverse the matches array, otherwise all our offsets will become incorrect if we modify our way\n\t\t\t\t\t\t\t\t\t\t\t//\t\tthrough the formula from left to right. Reversing means that we work right to left.through\n\t\t\t\t\t\t\t\t\t\t\t//\t\tthe formula\n\t\t\t\t\t\t\t\t\t\t\t$cellReferences = array_reverse($cellReferences);\n\t\t\t\t\t\t\t\t\t\t\t//\tLoop through each R1C1 style reference in turn, converting it to its A1 style equivalent,\n\t\t\t\t\t\t\t\t\t\t\t//\t\tthen modify the formula to use that new reference\n\t\t\t\t\t\t\t\t\t\t\tforeach($cellReferences as $cellReference) {\n\t\t\t\t\t\t\t\t\t\t\t\t$rowReference = $cellReference[2][0];\n\t\t\t\t\t\t\t\t\t\t\t\t//\tEmpty R reference is the current row\n\t\t\t\t\t\t\t\t\t\t\t\tif ($rowReference == '') $rowReference = $row;\n\t\t\t\t\t\t\t\t\t\t\t\t//\tBracketed R references are relative to the current row\n\t\t\t\t\t\t\t\t\t\t\t\tif ($rowReference{0} == '[') $rowReference = $row + trim($rowReference,'[]');\n\t\t\t\t\t\t\t\t\t\t\t\t$columnReference = $cellReference[4][0];\n\t\t\t\t\t\t\t\t\t\t\t\t//\tEmpty C reference is the current column\n\t\t\t\t\t\t\t\t\t\t\t\tif ($columnReference == '') $columnReference = $column;\n\t\t\t\t\t\t\t\t\t\t\t\t//\tBracketed C references are relative to the current column\n\t\t\t\t\t\t\t\t\t\t\t\tif ($columnReference{0} == '[') $columnReference = $column + trim($columnReference,'[]');\n\t\t\t\t\t\t\t\t\t\t\t\t$A1CellReference = PHPExcel_Cell::stringFromColumnIndex($columnReference-1).$rowReference;\n\n\t\t\t\t\t\t\t\t\t\t\t\t$value = substr_replace($value,$A1CellReference,$cellReference[0][1],strlen($cellReference[0][0]));\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tunset($value);\n\t\t\t\t\t\t\t\t\t//\tThen rebuild the formula string\n\t\t\t\t\t\t\t\t\t$cellDataFormula = implode('\"',$temp);\n\t\t\t\t\t\t\t\t\t$hasCalculatedValue = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1);\n\t\t\t\t$cellData = PHPExcel_Calculation::_unwrapResult($cellData);\n\n\t\t\t\t// Set cell value\n\t\t\t\t$objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setValue(($hasCalculatedValue) ? $cellDataFormula : $cellData);\n\t\t\t\tif ($hasCalculatedValue) {\n\t\t\t\t\t$cellData = PHPExcel_Calculation::_unwrapResult($cellData);\n\t\t\t\t\t$objPHPExcel->getActiveSheet()->getCell($columnLetter.$row)->setCalculatedValue($cellData);\n\t\t\t\t}\n\t\t\t//\tRead cell formatting\n\t\t\t} elseif ($dataType == 'F') {\n\t\t\t\t$formatStyle = $columnWidth = $styleSettings = '';\n\t\t\t\t$styleData = array();\n\t\t\t\tforeach($rowData as $rowDatum) {\n\t\t\t\t\tswitch($rowDatum{0}) {\n\t\t\t\t\t\tcase 'C' :\n\t\t\t\t\t\tcase 'X' :\t$column = substr($rowDatum,1);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'R' :\n\t\t\t\t\t\tcase 'Y' :\t$row = substr($rowDatum,1);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'P' :\t$formatStyle = $rowDatum;\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'W' :\tlist($startCol,$endCol,$columnWidth) = explode(' ',substr($rowDatum,1));\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'S' :\t$styleSettings = substr($rowDatum,1);\n\t\t\t\t\t\t\t\t\tfor ($i=0;$i<strlen($styleSettings);++$i) {\n\t\t\t\t\t\t\t\t\t\tswitch ($styleSettings{$i}) {\n\t\t\t\t\t\t\t\t\t\t\tcase 'I' :\t$styleData['font']['italic'] = true;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase 'D' :\t$styleData['font']['bold'] = true;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase 'T' :\t$styleData['borders']['top']['style'] = PHPExcel_Style_Border::BORDER_THIN;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase 'B' :\t$styleData['borders']['bottom']['style'] = PHPExcel_Style_Border::BORDER_THIN;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase 'L' :\t$styleData['borders']['left']['style'] = PHPExcel_Style_Border::BORDER_THIN;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t\tcase 'R' :\t$styleData['borders']['right']['style'] = PHPExcel_Style_Border::BORDER_THIN;\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (($formatStyle > '') && ($column > '') && ($row > '')) {\n\t\t\t\t\t$columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1);\n\t\t\t\t\tif (isset($this->_formats[$formatStyle])) {\n\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($this->_formats[$formatStyle]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ((!empty($styleData)) && ($column > '') && ($row > '')) {\n\t\t\t\t\t$columnLetter = PHPExcel_Cell::stringFromColumnIndex($column-1);\n\t\t\t\t\t$objPHPExcel->getActiveSheet()->getStyle($columnLetter.$row)->applyFromArray($styleData);\n\t\t\t\t}\n\t\t\t\tif ($columnWidth > '') {\n\t\t\t\t\tif ($startCol == $endCol) {\n\t\t\t\t\t\t$startCol = PHPExcel_Cell::stringFromColumnIndex($startCol-1);\n\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$startCol = PHPExcel_Cell::stringFromColumnIndex($startCol-1);\n\t\t\t\t\t\t$endCol = PHPExcel_Cell::stringFromColumnIndex($endCol-1);\n\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth);\n\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\t$objPHPExcel->getActiveSheet()->getColumnDimension(++$startCol)->setWidth($columnWidth);\n\t\t\t\t\t\t} while ($startCol != $endCol);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tforeach($rowData as $rowDatum) {\n\t\t\t\t\tswitch($rowDatum{0}) {\n\t\t\t\t\t\tcase 'C' :\n\t\t\t\t\t\tcase 'X' :\t$column = substr($rowDatum,1);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'R' :\n\t\t\t\t\t\tcase 'Y' :\t$row = substr($rowDatum,1);\n\t\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Close file\n\t\tfclose($fileHandle);\n\n\t\t// Return\n\t\treturn $objPHPExcel;\n\t}\n\n\t/**\n\t * Get sheet index\n\t *\n\t * @return int\n\t */\n\tpublic function getSheetIndex() {\n\t\treturn $this->_sheetIndex;\n\t}\n\n\t/**\n\t * Set sheet index\n\t *\n\t * @param\tint\t\t$pValue\t\tSheet index\n\t * @return PHPExcel_Reader_SYLK\n\t */\n\tpublic function setSheetIndex($pValue = 0) {\n\t\t$this->_sheetIndex = $pValue;\n\t\treturn $this;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/ReferenceHelper.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_ReferenceHelper (Singleton)\n *\n * @category   PHPExcel\n * @package\tPHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_ReferenceHelper\n{\n\t/**\tConstants\t\t\t\t*/\n\t/**\tRegular Expressions\t\t*/\n\tconst REFHELPER_REGEXP_CELLREF\t\t= '((\\w*|\\'[^!]*\\')!)?(?<![:a-z\\$])(\\$?[a-z]{1,3}\\$?\\d+)(?=[^:!\\d\\'])';\n\tconst REFHELPER_REGEXP_CELLRANGE\t= '((\\w*|\\'[^!]*\\')!)?(\\$?[a-z]{1,3}\\$?\\d+):(\\$?[a-z]{1,3}\\$?\\d+)';\n\tconst REFHELPER_REGEXP_ROWRANGE\t\t= '((\\w*|\\'[^!]*\\')!)?(\\$?\\d+):(\\$?\\d+)';\n\tconst REFHELPER_REGEXP_COLRANGE\t\t= '((\\w*|\\'[^!]*\\')!)?(\\$?[a-z]{1,3}):(\\$?[a-z]{1,3})';\n\n\t/**\n\t * Instance of this class\n\t *\n\t * @var PHPExcel_ReferenceHelper\n\t */\n\tprivate static $_instance;\n\n\t/**\n\t * Get an instance of this class\n\t *\n\t * @return PHPExcel_ReferenceHelper\n\t */\n\tpublic static function getInstance() {\n\t\tif (!isset(self::$_instance) || (self::$_instance === NULL)) {\n\t\t\tself::$_instance = new PHPExcel_ReferenceHelper();\n\t\t}\n\n\t\treturn self::$_instance;\n\t}\n\n\t/**\n\t * Create a new PHPExcel_ReferenceHelper\n\t */\n\tprotected function __construct() {\n\t}\n\n\t/**\n\t * Compare two column addresses\n\t * Intended for use as a Callback function for sorting column addresses by column\n\t *\n\t * @param   string   $a  First column to test (e.g. 'AA')\n\t * @param   string   $b  Second column to test (e.g. 'Z')\n\t * @return  integer\n\t */\n\tpublic static function columnSort($a, $b) {\n\t\treturn strcasecmp(strlen($a) . $a, strlen($b) . $b);\n\t}\n\n\t/**\n\t * Compare two column addresses\n\t * Intended for use as a Callback function for reverse sorting column addresses by column\n\t *\n\t * @param   string   $a  First column to test (e.g. 'AA')\n\t * @param   string   $b  Second column to test (e.g. 'Z')\n\t * @return  integer\n\t */\n\tpublic static function columnReverseSort($a, $b) {\n\t\treturn 1 - strcasecmp(strlen($a) . $a, strlen($b) . $b);\n\t}\n\n\t/**\n\t * Compare two cell addresses\n\t * Intended for use as a Callback function for sorting cell addresses by column and row\n\t *\n\t * @param   string   $a  First cell to test (e.g. 'AA1')\n\t * @param   string   $b  Second cell to test (e.g. 'Z1')\n\t * @return  integer\n\t */\n\tpublic static function cellSort($a, $b) {\n\t\tsscanf($a,'%[A-Z]%d', $ac, $ar);\n\t\tsscanf($b,'%[A-Z]%d', $bc, $br);\n\n\t\tif ($ar == $br) {\n\t\t\treturn strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc);\n\t\t}\n\t\treturn ($ar < $br) ? -1 : 1;\n\t}\n\n\t/**\n\t * Compare two cell addresses\n\t * Intended for use as a Callback function for sorting cell addresses by column and row\n\t *\n\t * @param   string   $a  First cell to test (e.g. 'AA1')\n\t * @param   string   $b  Second cell to test (e.g. 'Z1')\n\t * @return  integer\n\t */\n\tpublic static function cellReverseSort($a, $b) {\n\t\tsscanf($a,'%[A-Z]%d', $ac, $ar);\n\t\tsscanf($b,'%[A-Z]%d', $bc, $br);\n\n\t\tif ($ar == $br) {\n\t\t\treturn 1 - strcasecmp(strlen($ac) . $ac, strlen($bc) . $bc);\n\t\t}\n\t\treturn ($ar < $br) ? 1 : -1;\n\t}\n\n\t/**\n\t * Test whether a cell address falls within a defined range of cells\n\t *\n\t * @param   string     $cellAddress        Address of the cell we're testing\n\t * @param   integer    $beforeRow          Number of the row we're inserting/deleting before\n\t * @param   integer    $pNumRows           Number of rows to insert/delete (negative values indicate deletion)\n\t * @param   integer    $beforeColumnIndex  Index number of the column we're inserting/deleting before\n\t * @param   integer    $pNumCols           Number of columns to insert/delete (negative values indicate deletion)\n\t * @return  boolean\n\t */\n\tprivate static function cellAddressInDeleteRange($cellAddress, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols) {\n\t\tlist($cellColumn, $cellRow) = PHPExcel_Cell::coordinateFromString($cellAddress);\n\t\t$cellColumnIndex = PHPExcel_Cell::columnIndexFromString($cellColumn);\n\t\t//\tIs cell within the range of rows/columns if we're deleting\n\t\tif ($pNumRows < 0 &&\n\t\t\t($cellRow >= ($beforeRow + $pNumRows)) &&\n\t\t\t($cellRow < $beforeRow)) {\n\t\t\treturn TRUE;\n\t\t} elseif ($pNumCols < 0 &&\n\t\t\t($cellColumnIndex >= ($beforeColumnIndex + $pNumCols)) &&\n\t\t\t($cellColumnIndex < $beforeColumnIndex)) {\n\t\t\treturn TRUE;\n\t\t}\n\t\treturn FALSE;\n\t}\n\n\t/**\n\t * Update page breaks when inserting/deleting rows/columns\n\t *\n\t * @param   PHPExcel_Worksheet  $pSheet             The worksheet that we're editing\n\t * @param   string              $pBefore            Insert/Delete before this cell address (e.g. 'A1')\n\t * @param   integer             $beforeColumnIndex  Index number of the column we're inserting/deleting before\n\t * @param   integer             $pNumCols           Number of columns to insert/delete (negative values indicate deletion)\n\t * @param   integer             $beforeRow          Number of the row we're inserting/deleting before\n\t * @param   integer             $pNumRows           Number of rows to insert/delete (negative values indicate deletion)\n\t */\n\tprotected function _adjustPageBreaks(PHPExcel_Worksheet $pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)\n\t{\n\t\t$aBreaks = $pSheet->getBreaks();\n\t\t($pNumCols > 0 || $pNumRows > 0) ?\n\t\t\tuksort($aBreaks, array('PHPExcel_ReferenceHelper','cellReverseSort')) :\n\t\t\tuksort($aBreaks, array('PHPExcel_ReferenceHelper','cellSort'));\n\n\t\tforeach ($aBreaks as $key => $value) {\n\t\t\tif (self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) {\n\t\t\t\t//\tIf we're deleting, then clear any defined breaks that are within the range\n\t\t\t\t//\t\tof rows/columns that we're deleting\n\t\t\t\t$pSheet->setBreak($key, PHPExcel_Worksheet::BREAK_NONE);\n\t\t\t} else {\n\t\t\t\t//\tOtherwise update any affected breaks by inserting a new break at the appropriate point\n\t\t\t\t//\t\tand removing the old affected break\n\t\t\t\t$newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows);\n\t\t\t\tif ($key != $newReference) {\n\t\t\t\t\t$pSheet->setBreak($newReference, $value)\n\t\t\t\t\t    ->setBreak($key, PHPExcel_Worksheet::BREAK_NONE);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Update cell comments when inserting/deleting rows/columns\n\t *\n\t * @param   PHPExcel_Worksheet  $pSheet             The worksheet that we're editing\n\t * @param   string              $pBefore            Insert/Delete before this cell address (e.g. 'A1')\n\t * @param   integer             $beforeColumnIndex  Index number of the column we're inserting/deleting before\n\t * @param   integer             $pNumCols           Number of columns to insert/delete (negative values indicate deletion)\n\t * @param   integer             $beforeRow          Number of the row we're inserting/deleting before\n\t * @param   integer             $pNumRows           Number of rows to insert/delete (negative values indicate deletion)\n\t */\n\tprotected function _adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)\n\t{\n\t\t$aComments = $pSheet->getComments();\n\t\t$aNewComments = array(); // the new array of all comments\n\n\t\tforeach ($aComments as $key => &$value) {\n\t\t\t// Any comments inside a deleted range will be ignored\n\t\t\tif (!self::cellAddressInDeleteRange($key, $beforeRow, $pNumRows, $beforeColumnIndex, $pNumCols)) {\n\t\t\t\t//\tOtherwise build a new array of comments indexed by the adjusted cell reference\n\t\t\t\t$newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows);\n\t\t\t\t$aNewComments[$newReference] = $value;\n\t\t\t}\n\t\t}\n\t\t//\tReplace the comments array with the new set of comments\n\t\t$pSheet->setComments($aNewComments);\n\t}\n\n\t/**\n\t * Update hyperlinks when inserting/deleting rows/columns\n\t *\n\t * @param   PHPExcel_Worksheet  $pSheet             The worksheet that we're editing\n\t * @param   string              $pBefore            Insert/Delete before this cell address (e.g. 'A1')\n\t * @param   integer             $beforeColumnIndex  Index number of the column we're inserting/deleting before\n\t * @param   integer             $pNumCols           Number of columns to insert/delete (negative values indicate deletion)\n\t * @param   integer             $beforeRow          Number of the row we're inserting/deleting before\n\t * @param   integer             $pNumRows           Number of rows to insert/delete (negative values indicate deletion)\n\t */\n\tprotected function _adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)\n\t{\n\t\t$aHyperlinkCollection = $pSheet->getHyperlinkCollection();\n\t\t($pNumCols > 0 || $pNumRows > 0) ?\n\t\t\tuksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) :\n\t\t\tuksort($aHyperlinkCollection, array('PHPExcel_ReferenceHelper','cellSort'));\n\n\t\tforeach ($aHyperlinkCollection as $key => $value) {\n\t\t\t$newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows);\n\t\t\tif ($key != $newReference) {\n\t\t\t\t$pSheet->setHyperlink( $newReference, $value );\n\t\t\t\t$pSheet->setHyperlink( $key, null );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Update data validations when inserting/deleting rows/columns\n\t *\n\t * @param   PHPExcel_Worksheet  $pSheet             The worksheet that we're editing\n\t * @param   string              $pBefore            Insert/Delete before this cell address (e.g. 'A1')\n\t * @param   integer             $beforeColumnIndex  Index number of the column we're inserting/deleting before\n\t * @param   integer             $pNumCols           Number of columns to insert/delete (negative values indicate deletion)\n\t * @param   integer             $beforeRow          Number of the row we're inserting/deleting before\n\t * @param   integer             $pNumRows           Number of rows to insert/delete (negative values indicate deletion)\n\t */\n\tprotected function _adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)\n\t{\n\t\t$aDataValidationCollection = $pSheet->getDataValidationCollection();\n\t\t($pNumCols > 0 || $pNumRows > 0) ?\n\t\t\tuksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellReverseSort')) :\n\t\t\tuksort($aDataValidationCollection, array('PHPExcel_ReferenceHelper','cellSort'));\n\t\tforeach ($aDataValidationCollection as $key => $value) {\n\t\t\t$newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows);\n\t\t\tif ($key != $newReference) {\n\t\t\t\t$pSheet->setDataValidation( $newReference, $value );\n\t\t\t\t$pSheet->setDataValidation( $key, null );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Update merged cells when inserting/deleting rows/columns\n\t *\n\t * @param   PHPExcel_Worksheet  $pSheet             The worksheet that we're editing\n\t * @param   string              $pBefore            Insert/Delete before this cell address (e.g. 'A1')\n\t * @param   integer             $beforeColumnIndex  Index number of the column we're inserting/deleting before\n\t * @param   integer             $pNumCols           Number of columns to insert/delete (negative values indicate deletion)\n\t * @param   integer             $beforeRow          Number of the row we're inserting/deleting before\n\t * @param   integer             $pNumRows           Number of rows to insert/delete (negative values indicate deletion)\n\t */\n\tprotected function _adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)\n\t{\n\t\t$aMergeCells = $pSheet->getMergeCells();\n\t\t$aNewMergeCells = array(); // the new array of all merge cells\n\t\tforeach ($aMergeCells as $key => &$value) {\n\t\t\t$newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows);\n\t\t\t$aNewMergeCells[$newReference] = $newReference;\n\t\t}\n\t\t$pSheet->setMergeCells($aNewMergeCells); // replace the merge cells array\n\t}\n\n\t/**\n\t * Update protected cells when inserting/deleting rows/columns\n\t *\n\t * @param   PHPExcel_Worksheet  $pSheet             The worksheet that we're editing\n\t * @param   string              $pBefore            Insert/Delete before this cell address (e.g. 'A1')\n\t * @param   integer             $beforeColumnIndex  Index number of the column we're inserting/deleting before\n\t * @param   integer             $pNumCols           Number of columns to insert/delete (negative values indicate deletion)\n\t * @param   integer             $beforeRow          Number of the row we're inserting/deleting before\n\t * @param   integer             $pNumRows           Number of rows to insert/delete (negative values indicate deletion)\n\t */\n\tprotected function _adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)\n\t{\n\t\t$aProtectedCells = $pSheet->getProtectedCells();\n\t\t($pNumCols > 0 || $pNumRows > 0) ?\n\t\t\tuksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellReverseSort')) :\n\t\t\tuksort($aProtectedCells, array('PHPExcel_ReferenceHelper','cellSort'));\n\t\tforeach ($aProtectedCells as $key => $value) {\n\t\t\t$newReference = $this->updateCellReference($key, $pBefore, $pNumCols, $pNumRows);\n\t\t\tif ($key != $newReference) {\n\t\t\t\t$pSheet->protectCells( $newReference, $value, true );\n\t\t\t\t$pSheet->unprotectCells( $key );\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Update column dimensions when inserting/deleting rows/columns\n\t *\n\t * @param   PHPExcel_Worksheet  $pSheet             The worksheet that we're editing\n\t * @param   string              $pBefore            Insert/Delete before this cell address (e.g. 'A1')\n\t * @param   integer             $beforeColumnIndex  Index number of the column we're inserting/deleting before\n\t * @param   integer             $pNumCols           Number of columns to insert/delete (negative values indicate deletion)\n\t * @param   integer             $beforeRow          Number of the row we're inserting/deleting before\n\t * @param   integer             $pNumRows           Number of rows to insert/delete (negative values indicate deletion)\n\t */\n\tprotected function _adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)\n\t{\n\t\t$aColumnDimensions = array_reverse($pSheet->getColumnDimensions(), true);\n\t\tif (!empty($aColumnDimensions)) {\n\t\t\tforeach ($aColumnDimensions as $objColumnDimension) {\n\t\t\t\t$newReference = $this->updateCellReference($objColumnDimension->getColumnIndex() . '1', $pBefore, $pNumCols, $pNumRows);\n\t\t\t\tlist($newReference) = PHPExcel_Cell::coordinateFromString($newReference);\n\t\t\t\tif ($objColumnDimension->getColumnIndex() != $newReference) {\n\t\t\t\t\t$objColumnDimension->setColumnIndex($newReference);\n\t\t\t\t}\n\t\t\t}\n\t\t\t$pSheet->refreshColumnDimensions();\n\t\t}\n\t}\n\n\t/**\n\t * Update row dimensions when inserting/deleting rows/columns\n\t *\n\t * @param   PHPExcel_Worksheet  $pSheet             The worksheet that we're editing\n\t * @param   string              $pBefore            Insert/Delete before this cell address (e.g. 'A1')\n\t * @param   integer             $beforeColumnIndex  Index number of the column we're inserting/deleting before\n\t * @param   integer             $pNumCols           Number of columns to insert/delete (negative values indicate deletion)\n\t * @param   integer             $beforeRow          Number of the row we're inserting/deleting before\n\t * @param   integer             $pNumRows           Number of rows to insert/delete (negative values indicate deletion)\n\t */\n\tprotected function _adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows)\n\t{\n\t\t$aRowDimensions = array_reverse($pSheet->getRowDimensions(), true);\n\t\tif (!empty($aRowDimensions)) {\n\t\t\tforeach ($aRowDimensions as $objRowDimension) {\n\t\t\t\t$newReference = $this->updateCellReference('A' . $objRowDimension->getRowIndex(), $pBefore, $pNumCols, $pNumRows);\n\t\t\t\tlist(, $newReference) = PHPExcel_Cell::coordinateFromString($newReference);\n\t\t\t\tif ($objRowDimension->getRowIndex() != $newReference) {\n\t\t\t\t\t$objRowDimension->setRowIndex($newReference);\n\t\t\t\t}\n\t\t\t}\n\t\t\t$pSheet->refreshRowDimensions();\n\n\t\t\t$copyDimension = $pSheet->getRowDimension($beforeRow - 1);\n\t\t\tfor ($i = $beforeRow; $i <= $beforeRow - 1 + $pNumRows; ++$i) {\n\t\t\t\t$newDimension = $pSheet->getRowDimension($i);\n\t\t\t\t$newDimension->setRowHeight($copyDimension->getRowHeight());\n\t\t\t\t$newDimension->setVisible($copyDimension->getVisible());\n\t\t\t\t$newDimension->setOutlineLevel($copyDimension->getOutlineLevel());\n\t\t\t\t$newDimension->setCollapsed($copyDimension->getCollapsed());\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Insert a new column or row, updating all possible related data\n\t *\n\t * @param   string              $pBefore    Insert before this cell address (e.g. 'A1')\n\t * @param   integer             $pNumCols   Number of columns to insert/delete (negative values indicate deletion)\n\t * @param   integer             $pNumRows   Number of rows to insert/delete (negative values indicate deletion)\n\t * @param   PHPExcel_Worksheet  $pSheet     The worksheet that we're editing\n\t * @throws  PHPExcel_Exception\n\t */\n\tpublic function insertNewBefore($pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, PHPExcel_Worksheet $pSheet = NULL)\n\t{\n\t\t$remove = ($pNumCols < 0 || $pNumRows < 0);\n\t\t$aCellCollection = $pSheet->getCellCollection();\n\n\t\t// Get coordinates of $pBefore\n\t\t$beforeColumn\t= 'A';\n\t\t$beforeRow\t\t= 1;\n\t\tlist($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString($pBefore);\n\t\t$beforeColumnIndex = PHPExcel_Cell::columnIndexFromString($beforeColumn);\n\n\t\t// Clear cells if we are removing columns or rows\n\t\t$highestColumn\t= $pSheet->getHighestColumn();\n\t\t$highestRow\t= $pSheet->getHighestRow();\n\n\t\t// 1. Clear column strips if we are removing columns\n\t\tif ($pNumCols < 0 && $beforeColumnIndex - 2 + $pNumCols > 0) {\n\t\t\tfor ($i = 1; $i <= $highestRow - 1; ++$i) {\n\t\t\t\tfor ($j = $beforeColumnIndex - 1 + $pNumCols; $j <= $beforeColumnIndex - 2; ++$j) {\n\t\t\t\t\t$coordinate = PHPExcel_Cell::stringFromColumnIndex($j) . $i;\n\t\t\t\t\t$pSheet->removeConditionalStyles($coordinate);\n\t\t\t\t\tif ($pSheet->cellExists($coordinate)) {\n\t\t\t\t\t\t$pSheet->getCell($coordinate)->setValueExplicit('', PHPExcel_Cell_DataType::TYPE_NULL);\n\t\t\t\t\t\t$pSheet->getCell($coordinate)->setXfIndex(0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// 2. Clear row strips if we are removing rows\n\t\tif ($pNumRows < 0 && $beforeRow - 1 + $pNumRows > 0) {\n\t\t\tfor ($i = $beforeColumnIndex - 1; $i <= PHPExcel_Cell::columnIndexFromString($highestColumn) - 1; ++$i) {\n\t\t\t\tfor ($j = $beforeRow + $pNumRows; $j <= $beforeRow - 1; ++$j) {\n\t\t\t\t\t$coordinate = PHPExcel_Cell::stringFromColumnIndex($i) . $j;\n\t\t\t\t\t$pSheet->removeConditionalStyles($coordinate);\n\t\t\t\t\tif ($pSheet->cellExists($coordinate)) {\n\t\t\t\t\t\t$pSheet->getCell($coordinate)->setValueExplicit('', PHPExcel_Cell_DataType::TYPE_NULL);\n\t\t\t\t\t\t$pSheet->getCell($coordinate)->setXfIndex(0);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Loop through cells, bottom-up, and change cell coordinates\n        if($remove) {\n            // It's faster to reverse and pop than to use unshift, especially with large cell collections\n            $aCellCollection = array_reverse($aCellCollection);\n        }\n\t\twhile ($cellID = array_pop($aCellCollection)) {\n\t\t\t$cell = $pSheet->getCell($cellID);\n\t\t\t$cellIndex = PHPExcel_Cell::columnIndexFromString($cell->getColumn());\n\n\t\t\tif ($cellIndex-1 + $pNumCols < 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// New coordinates\n\t\t\t$newCoordinates = PHPExcel_Cell::stringFromColumnIndex($cellIndex-1 + $pNumCols) . ($cell->getRow() + $pNumRows);\n\n\t\t\t// Should the cell be updated? Move value and cellXf index from one cell to another.\n\t\t\tif (($cellIndex >= $beforeColumnIndex) &&\n\t\t\t\t($cell->getRow() >= $beforeRow)) {\n\n\t\t\t\t// Update cell styles\n\t\t\t\t$pSheet->getCell($newCoordinates)->setXfIndex($cell->getXfIndex());\n\n\t\t\t\t// Insert this cell at its new location\n\t\t\t\tif ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA) {\n\t\t\t\t\t// Formula should be adjusted\n\t\t\t\t\t$pSheet->getCell($newCoordinates)\n\t\t\t\t\t\t   ->setValue($this->updateFormulaReferences($cell->getValue(),\n\t\t\t\t\t\t   \t\t\t\t\t$pBefore, $pNumCols, $pNumRows, $pSheet->getTitle()));\n\t\t\t\t} else {\n\t\t\t\t\t// Formula should not be adjusted\n\t\t\t\t\t$pSheet->getCell($newCoordinates)->setValue($cell->getValue());\n\t\t\t\t}\n\n\t\t\t\t// Clear the original cell\n\t\t\t\t$pSheet->getCellCacheController()->deleteCacheData($cellID);\n\n\t\t\t} else {\n\t\t\t\t/*\tWe don't need to update styles for rows/columns before our insertion position,\n\t\t\t\t\t\tbut we do still need to adjust any formulae\tin those cells\t\t\t\t\t*/\n\t\t\t\tif ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA) {\n\t\t\t\t\t// Formula should be adjusted\n\t\t\t\t\t$cell->setValue($this->updateFormulaReferences($cell->getValue(),\n\t\t\t\t\t\t\t\t\t\t$pBefore, $pNumCols, $pNumRows, $pSheet->getTitle()));\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t\t// Duplicate styles for the newly inserted cells\n\t\t$highestColumn\t= $pSheet->getHighestColumn();\n\t\t$highestRow\t= $pSheet->getHighestRow();\n\n\t\tif ($pNumCols > 0 && $beforeColumnIndex - 2 > 0) {\n\t\t\tfor ($i = $beforeRow; $i <= $highestRow - 1; ++$i) {\n\n\t\t\t\t// Style\n\t\t\t\t$coordinate = PHPExcel_Cell::stringFromColumnIndex( $beforeColumnIndex - 2 ) . $i;\n\t\t\t\tif ($pSheet->cellExists($coordinate)) {\n\t\t\t\t\t$xfIndex = $pSheet->getCell($coordinate)->getXfIndex();\n\t\t\t\t\t$conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ?\n\t\t\t\t\t\t$pSheet->getConditionalStyles($coordinate) : false;\n\t\t\t\t\tfor ($j = $beforeColumnIndex - 1; $j <= $beforeColumnIndex - 2 + $pNumCols; ++$j) {\n\t\t\t\t\t\t$pSheet->getCellByColumnAndRow($j, $i)->setXfIndex($xfIndex);\n\t\t\t\t\t\tif ($conditionalStyles) {\n\t\t\t\t\t\t\t$cloned = array();\n\t\t\t\t\t\t\tforeach ($conditionalStyles as $conditionalStyle) {\n\t\t\t\t\t\t\t\t$cloned[] = clone $conditionalStyle;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($j) . $i, $cloned);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t}\n\t\t}\n\n\t\tif ($pNumRows > 0 && $beforeRow - 1 > 0) {\n\t\t\tfor ($i = $beforeColumnIndex - 1; $i <= PHPExcel_Cell::columnIndexFromString($highestColumn) - 1; ++$i) {\n\n\t\t\t\t// Style\n\t\t\t\t$coordinate = PHPExcel_Cell::stringFromColumnIndex($i) . ($beforeRow - 1);\n\t\t\t\tif ($pSheet->cellExists($coordinate)) {\n\t\t\t\t\t$xfIndex = $pSheet->getCell($coordinate)->getXfIndex();\n\t\t\t\t\t$conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ?\n\t\t\t\t\t\t$pSheet->getConditionalStyles($coordinate) : false;\n\t\t\t\t\tfor ($j = $beforeRow; $j <= $beforeRow - 1 + $pNumRows; ++$j) {\n\t\t\t\t\t\t$pSheet->getCell(PHPExcel_Cell::stringFromColumnIndex($i) . $j)->setXfIndex($xfIndex);\n\t\t\t\t\t\tif ($conditionalStyles) {\n\t\t\t\t\t\t\t$cloned = array();\n\t\t\t\t\t\t\tforeach ($conditionalStyles as $conditionalStyle) {\n\t\t\t\t\t\t\t\t$cloned[] = clone $conditionalStyle;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$pSheet->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($i) . $j, $cloned);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Update worksheet: column dimensions\n\t\t$this->_adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);\n\n\t\t// Update worksheet: row dimensions\n\t\t$this->_adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);\n\n\t\t//\tUpdate worksheet: page breaks\n\t\t$this->_adjustPageBreaks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);\n\n\t\t//\tUpdate worksheet: comments\n\t\t$this->_adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);\n\n\t\t// Update worksheet: hyperlinks\n\t\t$this->_adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);\n\n\t\t// Update worksheet: data validations\n\t\t$this->_adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);\n\n\t\t// Update worksheet: merge cells\n\t\t$this->_adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);\n\n\t\t// Update worksheet: protected cells\n\t\t$this->_adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);\n\n\t\t// Update worksheet: autofilter\n\t\t$autoFilter = $pSheet->getAutoFilter();\n\t\t$autoFilterRange = $autoFilter->getRange();\n\t\tif (!empty($autoFilterRange)) {\n\t\t\tif ($pNumCols != 0) {\n\t\t\t\t$autoFilterColumns = array_keys($autoFilter->getColumns());\n\t\t\t\tif (count($autoFilterColumns) > 0) {\n\t\t\t\t\tsscanf($pBefore,'%[A-Z]%d', $column, $row);\n\t\t\t\t\t$columnIndex = PHPExcel_Cell::columnIndexFromString($column);\n\t\t\t\t\tlist($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($autoFilterRange);\n\t\t\t\t\tif ($columnIndex <= $rangeEnd[0]) {\n\t\t\t\t\t\tif ($pNumCols < 0) {\n\t\t\t\t\t\t\t//\tIf we're actually deleting any columns that fall within the autofilter range,\n\t\t\t\t\t\t\t//\t\tthen we delete any rules for those columns\n\t\t\t\t\t\t\t$deleteColumn = $columnIndex + $pNumCols - 1;\n\t\t\t\t\t\t\t$deleteCount = abs($pNumCols);\n\t\t\t\t\t\t\tfor ($i = 1; $i <= $deleteCount; ++$i) {\n\t\t\t\t\t\t\t\tif (in_array(PHPExcel_Cell::stringFromColumnIndex($deleteColumn),$autoFilterColumns)) {\n\t\t\t\t\t\t\t\t\t$autoFilter->clearColumn(PHPExcel_Cell::stringFromColumnIndex($deleteColumn));\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t++$deleteColumn;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$startCol = ($columnIndex > $rangeStart[0]) ? $columnIndex : $rangeStart[0];\n\n\t\t\t\t\t\t//\tShuffle columns in autofilter range\n\t\t\t\t\t\tif ($pNumCols > 0) {\n\t\t\t\t\t\t\t//\tFor insert, we shuffle from end to beginning to avoid overwriting\n\t\t\t\t\t\t\t$startColID = PHPExcel_Cell::stringFromColumnIndex($startCol-1);\n\t\t\t\t\t\t\t$toColID = PHPExcel_Cell::stringFromColumnIndex($startCol+$pNumCols-1);\n\t\t\t\t\t\t\t$endColID = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]);\n\n\t\t\t\t\t\t\t$startColRef = $startCol;\n\t\t\t\t\t\t\t$endColRef = $rangeEnd[0];\n\t\t\t\t\t\t\t$toColRef = $rangeEnd[0]+$pNumCols;\n\n\t\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\t\t$autoFilter->shiftColumn(PHPExcel_Cell::stringFromColumnIndex($endColRef-1),PHPExcel_Cell::stringFromColumnIndex($toColRef-1));\n\t\t\t\t\t\t\t\t--$endColRef;\n\t\t\t\t\t\t\t\t--$toColRef;\n\t\t\t\t\t\t\t} while ($startColRef <= $endColRef);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t//\tFor delete, we shuffle from beginning to end to avoid overwriting\n\t\t\t\t\t\t\t$startColID = PHPExcel_Cell::stringFromColumnIndex($startCol-1);\n\t\t\t\t\t\t\t$toColID = PHPExcel_Cell::stringFromColumnIndex($startCol+$pNumCols-1);\n\t\t\t\t\t\t\t$endColID = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0]);\n\t\t\t\t\t\t\tdo {\n\t\t\t\t\t\t\t\t$autoFilter->shiftColumn($startColID,$toColID);\n\t\t\t\t\t\t\t\t++$startColID;\n\t\t\t\t\t\t\t\t++$toColID;\n\t\t\t\t\t\t\t} while ($startColID != $endColID);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t$pSheet->setAutoFilter( $this->updateCellReference($autoFilterRange, $pBefore, $pNumCols, $pNumRows) );\n\t\t}\n\n\t\t// Update worksheet: freeze pane\n\t\tif ($pSheet->getFreezePane() != '') {\n\t\t\t$pSheet->freezePane( $this->updateCellReference($pSheet->getFreezePane(), $pBefore, $pNumCols, $pNumRows) );\n\t\t}\n\n\t\t// Page setup\n\t\tif ($pSheet->getPageSetup()->isPrintAreaSet()) {\n\t\t\t$pSheet->getPageSetup()->setPrintArea( $this->updateCellReference($pSheet->getPageSetup()->getPrintArea(), $pBefore, $pNumCols, $pNumRows) );\n\t\t}\n\n\t\t// Update worksheet: drawings\n\t\t$aDrawings = $pSheet->getDrawingCollection();\n\t\tforeach ($aDrawings as $objDrawing) {\n\t\t\t$newReference = $this->updateCellReference($objDrawing->getCoordinates(), $pBefore, $pNumCols, $pNumRows);\n\t\t\tif ($objDrawing->getCoordinates() != $newReference) {\n\t\t\t\t$objDrawing->setCoordinates($newReference);\n\t\t\t}\n\t\t}\n\n\t\t// Update workbook: named ranges\n\t\tif (count($pSheet->getParent()->getNamedRanges()) > 0) {\n\t\t\tforeach ($pSheet->getParent()->getNamedRanges() as $namedRange) {\n\t\t\t\tif ($namedRange->getWorksheet()->getHashCode() == $pSheet->getHashCode()) {\n\t\t\t\t\t$namedRange->setRange(\n\t\t\t\t\t\t$this->updateCellReference($namedRange->getRange(), $pBefore, $pNumCols, $pNumRows)\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Garbage collect\n\t\t$pSheet->garbageCollect();\n\t}\n\n\t/**\n\t * Update references within formulas\n\t *\n\t * @param\tstring\t$pFormula\tFormula to update\n\t * @param\tint\t\t$pBefore\tInsert before this one\n\t * @param\tint\t\t$pNumCols\tNumber of columns to insert\n\t * @param\tint\t\t$pNumRows\tNumber of rows to insert\n\t * @param   string  $sheetName  Worksheet name/title\n\t * @return\tstring\tUpdated formula\n\t * @throws\tPHPExcel_Exception\n\t */\n\tpublic function updateFormulaReferences($pFormula = '', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0, $sheetName = '') {\n\t\t//\tUpdate cell references in the formula\n\t\t$formulaBlocks = explode('\"',$pFormula);\n\t\t$i = false;\n\t\tforeach($formulaBlocks as &$formulaBlock) {\n\t\t\t//\tIgnore blocks that were enclosed in quotes (alternating entries in the $formulaBlocks array after the explode)\n\t\t\tif ($i = !$i) {\n\t\t\t\t$adjustCount = 0;\n\t\t\t\t$newCellTokens = $cellTokens = array();\n\t\t\t\t//\tSearch for row ranges (e.g. 'Sheet1'!3:5 or 3:5) with or without $ absolutes (e.g. $3:5)\n\t\t\t\t$matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_ROWRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER);\n\t\t\t\tif ($matchCount > 0) {\n\t\t\t\t\tforeach($matches as $match) {\n\t\t\t\t\t\t$fromString = ($match[2] > '') ? $match[2].'!' : '';\n\t\t\t\t\t\t$fromString .= $match[3].':'.$match[4];\n\t\t\t\t\t\t$modified3 = substr($this->updateCellReference('$A'.$match[3],$pBefore,$pNumCols,$pNumRows),2);\n\t\t\t\t\t\t$modified4 = substr($this->updateCellReference('$A'.$match[4],$pBefore,$pNumCols,$pNumRows),2);\n\n\t\t\t\t\t\tif ($match[3].':'.$match[4] !== $modified3.':'.$modified4) {\n\t\t\t\t\t\t\tif (($match[2] == '') || (trim($match[2],\"'\") == $sheetName)) {\n\t\t\t\t\t\t\t\t$toString = ($match[2] > '') ? $match[2].'!' : '';\n\t\t\t\t\t\t\t\t$toString .= $modified3.':'.$modified4;\n\t\t\t\t\t\t\t\t//\tMax worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more\n\t\t\t\t\t\t\t\t$column = 100000;\n\t\t\t\t\t\t\t\t$row = 10000000+trim($match[3],'$');\n\t\t\t\t\t\t\t\t$cellIndex = $column.$row;\n\n\t\t\t\t\t\t\t\t$newCellTokens[$cellIndex] = preg_quote($toString);\n\t\t\t\t\t\t\t\t$cellTokens[$cellIndex] = '/(?<!\\d\\$\\!)'.preg_quote($fromString).'(?!\\d)/i';\n\t\t\t\t\t\t\t\t++$adjustCount;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//\tSearch for column ranges (e.g. 'Sheet1'!C:E or C:E) with or without $ absolutes (e.g. $C:E)\n\t\t\t\t$matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_COLRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER);\n\t\t\t\tif ($matchCount > 0) {\n\t\t\t\t\tforeach($matches as $match) {\n\t\t\t\t\t\t$fromString = ($match[2] > '') ? $match[2].'!' : '';\n\t\t\t\t\t\t$fromString .= $match[3].':'.$match[4];\n\t\t\t\t\t\t$modified3 = substr($this->updateCellReference($match[3].'$1',$pBefore,$pNumCols,$pNumRows),0,-2);\n\t\t\t\t\t\t$modified4 = substr($this->updateCellReference($match[4].'$1',$pBefore,$pNumCols,$pNumRows),0,-2);\n\n\t\t\t\t\t\tif ($match[3].':'.$match[4] !== $modified3.':'.$modified4) {\n\t\t\t\t\t\t\tif (($match[2] == '') || (trim($match[2],\"'\") == $sheetName)) {\n\t\t\t\t\t\t\t\t$toString = ($match[2] > '') ? $match[2].'!' : '';\n\t\t\t\t\t\t\t\t$toString .= $modified3.':'.$modified4;\n\t\t\t\t\t\t\t\t//\tMax worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more\n\t\t\t\t\t\t\t\t$column = PHPExcel_Cell::columnIndexFromString(trim($match[3],'$')) + 100000;\n\t\t\t\t\t\t\t\t$row = 10000000;\n\t\t\t\t\t\t\t\t$cellIndex = $column.$row;\n\n\t\t\t\t\t\t\t\t$newCellTokens[$cellIndex] = preg_quote($toString);\n\t\t\t\t\t\t\t\t$cellTokens[$cellIndex] = '/(?<![A-Z\\$\\!])'.preg_quote($fromString).'(?![A-Z])/i';\n\t\t\t\t\t\t\t\t++$adjustCount;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//\tSearch for cell ranges (e.g. 'Sheet1'!A3:C5 or A3:C5) with or without $ absolutes (e.g. $A1:C$5)\n\t\t\t\t$matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_CELLRANGE.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER);\n\t\t\t\tif ($matchCount > 0) {\n\t\t\t\t\tforeach($matches as $match) {\n\t\t\t\t\t\t$fromString = ($match[2] > '') ? $match[2].'!' : '';\n\t\t\t\t\t\t$fromString .= $match[3].':'.$match[4];\n\t\t\t\t\t\t$modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows);\n\t\t\t\t\t\t$modified4 = $this->updateCellReference($match[4],$pBefore,$pNumCols,$pNumRows);\n\n\t\t\t\t\t\tif ($match[3].$match[4] !== $modified3.$modified4) {\n\t\t\t\t\t\t\tif (($match[2] == '') || (trim($match[2],\"'\") == $sheetName)) {\n\t\t\t\t\t\t\t\t$toString = ($match[2] > '') ? $match[2].'!' : '';\n\t\t\t\t\t\t\t\t$toString .= $modified3.':'.$modified4;\n\t\t\t\t\t\t\t\tlist($column,$row) = PHPExcel_Cell::coordinateFromString($match[3]);\n\t\t\t\t\t\t\t\t//\tMax worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more\n\t\t\t\t\t\t\t\t$column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000;\n\t\t\t\t\t\t\t\t$row = trim($row,'$') + 10000000;\n\t\t\t\t\t\t\t\t$cellIndex = $column.$row;\n\n\t\t\t\t\t\t\t\t$newCellTokens[$cellIndex] = preg_quote($toString);\n\t\t\t\t\t\t\t\t$cellTokens[$cellIndex] = '/(?<![A-Z]\\$\\!)'.preg_quote($fromString).'(?!\\d)/i';\n\t\t\t\t\t\t\t\t++$adjustCount;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//\tSearch for cell references (e.g. 'Sheet1'!A3 or C5) with or without $ absolutes (e.g. $A1 or C$5)\n\t\t\t\t$matchCount = preg_match_all('/'.self::REFHELPER_REGEXP_CELLREF.'/i', ' '.$formulaBlock.' ', $matches, PREG_SET_ORDER);\n\n\t\t\t\tif ($matchCount > 0) {\n\t\t\t\t\tforeach($matches as $match) {\n\t\t\t\t\t\t$fromString = ($match[2] > '') ? $match[2].'!' : '';\n\t\t\t\t\t\t$fromString .= $match[3];\n\n\t\t\t\t\t\t$modified3 = $this->updateCellReference($match[3],$pBefore,$pNumCols,$pNumRows);\n\t\t\t\t\t\tif ($match[3] !== $modified3) {\n\t\t\t\t\t\t\tif (($match[2] == '') || (trim($match[2],\"'\") == $sheetName)) {\n\t\t\t\t\t\t\t\t$toString = ($match[2] > '') ? $match[2].'!' : '';\n\t\t\t\t\t\t\t\t$toString .= $modified3;\n\t\t\t\t\t\t\t\tlist($column,$row) = PHPExcel_Cell::coordinateFromString($match[3]);\n\t\t\t\t\t\t\t\t//\tMax worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more\n\t\t\t\t\t\t\t\t$column = PHPExcel_Cell::columnIndexFromString(trim($column,'$')) + 100000;\n\t\t\t\t\t\t\t\t$row = trim($row,'$') + 10000000;\n\t\t\t\t\t\t\t\t$cellIndex = $row . $column;\n\n\t\t\t\t\t\t\t\t$newCellTokens[$cellIndex] = preg_quote($toString);\n\t\t\t\t\t\t\t\t$cellTokens[$cellIndex] = '/(?<![A-Z\\$\\!])'.preg_quote($fromString).'(?!\\d)/i';\n\t\t\t\t\t\t\t\t++$adjustCount;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ($adjustCount > 0) {\n                    if ($pNumCols > 0 || $pNumRows > 0) {\n                        krsort($cellTokens);\n                        krsort($newCellTokens);\n                      } else {\n                        ksort($cellTokens);\n                        ksort($newCellTokens);\n                    }   //  Update cell references in the formula\n\t\t\t\t\t$formulaBlock = str_replace('\\\\','',preg_replace($cellTokens,$newCellTokens,$formulaBlock));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tunset($formulaBlock);\n\n\t\t//\tThen rebuild the formula string\n\t\treturn implode('\"',$formulaBlocks);\n\t}\n\n\t/**\n\t * Update cell reference\n\t *\n\t * @param\tstring\t$pCellRange\t\t\tCell range\n\t * @param\tint\t\t$pBefore\t\t\tInsert before this one\n\t * @param\tint\t\t$pNumCols\t\t\tNumber of columns to increment\n\t * @param\tint\t\t$pNumRows\t\t\tNumber of rows to increment\n\t * @return\tstring\tUpdated cell range\n\t * @throws\tPHPExcel_Exception\n\t */\n\tpublic function updateCellReference($pCellRange = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) {\n\t\t// Is it in another worksheet? Will not have to update anything.\n\t\tif (strpos($pCellRange, \"!\") !== false) {\n\t\t\treturn $pCellRange;\n\t\t// Is it a range or a single cell?\n\t\t} elseif (strpos($pCellRange, ':') === false && strpos($pCellRange, ',') === false) {\n\t\t\t// Single cell\n\t\t\treturn $this->_updateSingleCellReference($pCellRange, $pBefore, $pNumCols, $pNumRows);\n\t\t} elseif (strpos($pCellRange, ':') !== false || strpos($pCellRange, ',') !== false) {\n\t\t\t// Range\n\t\t\treturn $this->_updateCellRange($pCellRange, $pBefore, $pNumCols, $pNumRows);\n\t\t} else {\n\t\t\t// Return original\n\t\t\treturn $pCellRange;\n\t\t}\n\t}\n\n\t/**\n\t * Update named formulas (i.e. containing worksheet references / named ranges)\n\t *\n\t * @param PHPExcel $pPhpExcel\tObject to update\n\t * @param string $oldName\t\tOld name (name to replace)\n\t * @param string $newName\t\tNew name\n\t */\n\tpublic function updateNamedFormulas(PHPExcel $pPhpExcel, $oldName = '', $newName = '') {\n\t\tif ($oldName == '') {\n\t\t\treturn;\n\t\t}\n\n\t\tforeach ($pPhpExcel->getWorksheetIterator() as $sheet) {\n\t\t\tforeach ($sheet->getCellCollection(false) as $cellID) {\n\t\t\t\t$cell = $sheet->getCell($cellID);\n\t\t\t\tif (($cell !== NULL) && ($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_FORMULA)) {\n\t\t\t\t\t$formula = $cell->getValue();\n\t\t\t\t\tif (strpos($formula, $oldName) !== false) {\n\t\t\t\t\t\t$formula = str_replace(\"'\" . $oldName . \"'!\", \"'\" . $newName . \"'!\", $formula);\n\t\t\t\t\t\t$formula = str_replace($oldName . \"!\", $newName . \"!\", $formula);\n\t\t\t\t\t\t$cell->setValueExplicit($formula, PHPExcel_Cell_DataType::TYPE_FORMULA);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Update cell range\n\t *\n\t * @param\tstring\t$pCellRange\t\t\tCell range\t(e.g. 'B2:D4', 'B:C' or '2:3')\n\t * @param\tint\t\t$pBefore\t\t\tInsert before this one\n\t * @param\tint\t\t$pNumCols\t\t\tNumber of columns to increment\n\t * @param\tint\t\t$pNumRows\t\t\tNumber of rows to increment\n\t * @return\tstring\tUpdated cell range\n\t * @throws\tPHPExcel_Exception\n\t */\n\tprivate function _updateCellRange($pCellRange = 'A1:A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) {\n\t\tif (strpos($pCellRange,':') !== false || strpos($pCellRange, ',') !== false) {\n\t\t\t// Update range\n\t\t\t$range = PHPExcel_Cell::splitRange($pCellRange);\n\t\t\t$ic = count($range);\n\t\t\tfor ($i = 0; $i < $ic; ++$i) {\n\t\t\t\t$jc = count($range[$i]);\n\t\t\t\tfor ($j = 0; $j < $jc; ++$j) {\n\t\t\t\t\tif (ctype_alpha($range[$i][$j])) {\n\t\t\t\t\t\t$r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference($range[$i][$j].'1', $pBefore, $pNumCols, $pNumRows));\n\t\t\t\t\t\t$range[$i][$j] = $r[0];\n\t\t\t\t\t} elseif(ctype_digit($range[$i][$j])) {\n\t\t\t\t\t\t$r = PHPExcel_Cell::coordinateFromString($this->_updateSingleCellReference('A'.$range[$i][$j], $pBefore, $pNumCols, $pNumRows));\n\t\t\t\t\t\t$range[$i][$j] = $r[1];\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$range[$i][$j] = $this->_updateSingleCellReference($range[$i][$j], $pBefore, $pNumCols, $pNumRows);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Recreate range string\n\t\t\treturn PHPExcel_Cell::buildRange($range);\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Only cell ranges may be passed to this method.\");\n\t\t}\n\t}\n\n\t/**\n\t * Update single cell reference\n\t *\n\t * @param\tstring\t$pCellReference\t\tSingle cell reference\n\t * @param\tint\t\t$pBefore\t\t\tInsert before this one\n\t * @param\tint\t\t$pNumCols\t\t\tNumber of columns to increment\n\t * @param\tint\t\t$pNumRows\t\t\tNumber of rows to increment\n\t * @return\tstring\tUpdated cell reference\n\t * @throws\tPHPExcel_Exception\n\t */\n\tprivate function _updateSingleCellReference($pCellReference = 'A1', $pBefore = 'A1', $pNumCols = 0, $pNumRows = 0) {\n\t\tif (strpos($pCellReference, ':') === false && strpos($pCellReference, ',') === false) {\n\t\t\t// Get coordinates of $pBefore\n\t\t\tlist($beforeColumn, $beforeRow) = PHPExcel_Cell::coordinateFromString( $pBefore );\n\n\t\t\t// Get coordinates of $pCellReference\n\t\t\tlist($newColumn, $newRow) = PHPExcel_Cell::coordinateFromString( $pCellReference );\n\n\t\t\t// Verify which parts should be updated\n\t\t\t$updateColumn = (($newColumn{0} != '$') && ($beforeColumn{0} != '$') &&\n\t\t\t\t\t\t\t PHPExcel_Cell::columnIndexFromString($newColumn) >= PHPExcel_Cell::columnIndexFromString($beforeColumn));\n\t\t\t$updateRow = (($newRow{0} != '$') && ($beforeRow{0} != '$') &&\n\t\t\t\t\t\t  $newRow >= $beforeRow);\n\n\t\t\t// Create new column reference\n\t\t\tif ($updateColumn) {\n\t\t\t\t$newColumn\t= PHPExcel_Cell::stringFromColumnIndex( PHPExcel_Cell::columnIndexFromString($newColumn) - 1 + $pNumCols );\n\t\t\t}\n\n\t\t\t// Create new row reference\n\t\t\tif ($updateRow) {\n\t\t\t\t$newRow\t= $newRow + $pNumRows;\n\t\t\t}\n\n\t\t\t// Return new reference\n\t\t\treturn $newColumn . $newRow;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Only single cell references may be passed to this method.\");\n\t\t}\n\t}\n\n\t/**\n\t * __clone implementation. Cloning should not be allowed in a Singleton!\n\t *\n\t * @throws\tPHPExcel_Exception\n\t */\n\tpublic final function __clone() {\n\t\tthrow new PHPExcel_Exception(\"Cloning a Singleton is not allowed!\");\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/RichText/ITextElement.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_RichText\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_RichText_ITextElement\n *\n * @category   PHPExcel\n * @package    PHPExcel_RichText\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\ninterface PHPExcel_RichText_ITextElement\n{\n\t/**\n\t * Get text\n\t *\n\t * @return string\tText\n\t */\n\tpublic function getText();\n\n\t/**\n\t * Set text\n\t *\n\t * @param \t$pText string\tText\n\t * @return PHPExcel_RichText_ITextElement\n\t */\n\tpublic function setText($pText = '');\n\n\t/**\n\t * Get font\n\t *\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function getFont();\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode();\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/RichText/Run.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_RichText\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_RichText_Run\n *\n * @category   PHPExcel\n * @package    PHPExcel_RichText\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_RichText_Run extends PHPExcel_RichText_TextElement implements PHPExcel_RichText_ITextElement\n{\n\t/**\n\t * Font\n\t *\n\t * @var PHPExcel_Style_Font\n\t */\n\tprivate $_font;\n\n    /**\n     * Create a new PHPExcel_RichText_Run instance\n     *\n     * @param \tstring\t\t$pText\t\tText\n     */\n    public function __construct($pText = '')\n    {\n    \t// Initialise variables\n    \t$this->setText($pText);\n    \t$this->_font = new PHPExcel_Style_Font();\n    }\n\n\t/**\n\t * Get font\n\t *\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function getFont() {\n\t\treturn $this->_font;\n\t}\n\n\t/**\n\t * Set font\n\t *\n\t * @param\tPHPExcel_Style_Font\t\t$pFont\t\tFont\n\t * @throws \tPHPExcel_Exception\n\t * @return PHPExcel_RichText_ITextElement\n\t */\n\tpublic function setFont(PHPExcel_Style_Font $pFont = null) {\n\t\t$this->_font = $pFont;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n    \treturn md5(\n    \t\t  $this->getText()\n    \t\t. $this->_font->getHashCode()\n    \t\t. __CLASS__\n    \t);\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/RichText/TextElement.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_RichText\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_RichText_TextElement\n *\n * @category   PHPExcel\n * @package    PHPExcel_RichText\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_RichText_TextElement implements PHPExcel_RichText_ITextElement\n{\n\t/**\n\t * Text\n\t *\n\t * @var string\n\t */\n\tprivate $_text;\n\n    /**\n     * Create a new PHPExcel_RichText_TextElement instance\n     *\n     * @param \tstring\t\t$pText\t\tText\n     */\n    public function __construct($pText = '')\n    {\n    \t// Initialise variables\n    \t$this->_text = $pText;\n    }\n\n\t/**\n\t * Get text\n\t *\n\t * @return string\tText\n\t */\n\tpublic function getText() {\n\t\treturn $this->_text;\n\t}\n\n\t/**\n\t * Set text\n\t *\n\t * @param \t$pText string\tText\n\t * @return PHPExcel_RichText_ITextElement\n\t */\n\tpublic function setText($pText = '') {\n\t\t$this->_text = $pText;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get font\n\t *\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function getFont() {\n\t\treturn null;\n\t}\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n    \treturn md5(\n    \t\t  $this->_text\n    \t\t. __CLASS__\n    \t);\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/RichText.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_RichText\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_RichText\n *\n * @category   PHPExcel\n * @package    PHPExcel_RichText\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_RichText implements PHPExcel_IComparable\n{\n    /**\n     * Rich text elements\n     *\n     * @var PHPExcel_RichText_ITextElement[]\n     */\n    private $_richTextElements;\n\n    /**\n     * Create a new PHPExcel_RichText instance\n     *\n     * @param PHPExcel_Cell $pCell\n     * @throws PHPExcel_Exception\n     */\n    public function __construct(PHPExcel_Cell $pCell = null)\n    {\n        // Initialise variables\n        $this->_richTextElements = array();\n\n        // Rich-Text string attached to cell?\n        if ($pCell !== NULL) {\n            // Add cell text and style\n            if ($pCell->getValue() != \"\") {\n                $objRun = new PHPExcel_RichText_Run($pCell->getValue());\n                $objRun->setFont(clone $pCell->getParent()->getStyle($pCell->getCoordinate())->getFont());\n                $this->addText($objRun);\n            }\n\n            // Set parent value\n            $pCell->setValueExplicit($this, PHPExcel_Cell_DataType::TYPE_STRING);\n        }\n    }\n\n    /**\n     * Add text\n     *\n     * @param PHPExcel_RichText_ITextElement $pText Rich text element\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_RichText\n     */\n    public function addText(PHPExcel_RichText_ITextElement $pText = null)\n    {\n        $this->_richTextElements[] = $pText;\n        return $this;\n    }\n\n    /**\n     * Create text\n     *\n     * @param string $pText Text\n     * @return PHPExcel_RichText_TextElement\n     * @throws PHPExcel_Exception\n     */\n    public function createText($pText = '')\n    {\n        $objText = new PHPExcel_RichText_TextElement($pText);\n        $this->addText($objText);\n        return $objText;\n    }\n\n    /**\n     * Create text run\n     *\n     * @param string $pText Text\n     * @return PHPExcel_RichText_Run\n     * @throws PHPExcel_Exception\n     */\n    public function createTextRun($pText = '')\n    {\n        $objText = new PHPExcel_RichText_Run($pText);\n        $this->addText($objText);\n        return $objText;\n    }\n\n    /**\n     * Get plain text\n     *\n     * @return string\n     */\n    public function getPlainText()\n    {\n        // Return value\n        $returnValue = '';\n\n        // Loop through all PHPExcel_RichText_ITextElement\n        foreach ($this->_richTextElements as $text) {\n            $returnValue .= $text->getText();\n        }\n\n        // Return\n        return $returnValue;\n    }\n\n    /**\n     * Convert to string\n     *\n     * @return string\n     */\n    public function __toString()\n    {\n        return $this->getPlainText();\n    }\n\n    /**\n     * Get Rich Text elements\n     *\n     * @return PHPExcel_RichText_ITextElement[]\n     */\n    public function getRichTextElements()\n    {\n        return $this->_richTextElements;\n    }\n\n    /**\n     * Set Rich Text elements\n     *\n     * @param PHPExcel_RichText_ITextElement[] $pElements Array of elements\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_RichText\n     */\n    public function setRichTextElements($pElements = null)\n    {\n        if (is_array($pElements)) {\n            $this->_richTextElements = $pElements;\n        } else {\n            throw new PHPExcel_Exception(\"Invalid PHPExcel_RichText_ITextElement[] array passed.\");\n        }\n        return $this;\n    }\n\n    /**\n     * Get hash code\n     *\n     * @return string    Hash code\n     */\n    public function getHashCode()\n    {\n        $hashElements = '';\n        foreach ($this->_richTextElements as $element) {\n            $hashElements .= $element->getHashCode();\n        }\n\n        return md5(\n              $hashElements\n            . __CLASS__\n        );\n    }\n\n    /**\n     * Implement PHP __clone to create a deep clone, not just a shallow copy.\n     */\n    public function __clone()\n    {\n        $vars = get_object_vars($this);\n        foreach ($vars as $key => $value) {\n            if (is_object($value)) {\n                $this->$key = clone $value;\n            } else {\n                $this->$key = $value;\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Settings.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Settings\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n    /**\n     * @ignore\n     */\n    define('PHPEXCEL_ROOT', dirname(__FILE__) . '/../');\n    require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\nclass PHPExcel_Settings\n{\n    /**    constants */\n    /**    Available Zip library classes */\n    const PCLZIP        = 'PHPExcel_Shared_ZipArchive';\n    const ZIPARCHIVE    = 'ZipArchive';\n\n    /**    Optional Chart Rendering libraries */\n    const CHART_RENDERER_JPGRAPH    = 'jpgraph';\n\n    /**    Optional PDF Rendering libraries */\n    const PDF_RENDERER_TCPDF\t\t= 'tcPDF';\n    const PDF_RENDERER_DOMPDF\t\t= 'DomPDF';\n    const PDF_RENDERER_MPDF \t\t= 'mPDF';\n\n\n    private static $_chartRenderers = array(\n        self::CHART_RENDERER_JPGRAPH,\n    );\n\n    private static $_pdfRenderers = array(\n        self::PDF_RENDERER_TCPDF,\n        self::PDF_RENDERER_DOMPDF,\n        self::PDF_RENDERER_MPDF,\n    );\n\n\n    /**\n     * Name of the class used for Zip file management\n     *\te.g.\n     *\t\tZipArchive\n     *\n     * @var string\n     */\n    private static $_zipClass    = self::ZIPARCHIVE;\n\n\n    /**\n     * Name of the external Library used for rendering charts\n     *\te.g.\n     *\t\tjpgraph\n     *\n     * @var string\n     */\n    private static $_chartRendererName = NULL;\n\n    /**\n     * Directory Path to the external Library used for rendering charts\n     *\n     * @var string\n     */\n    private static $_chartRendererPath = NULL;\n\n\n    /**\n     * Name of the external Library used for rendering PDF files\n     *\te.g.\n     * \t\tmPDF\n     *\n     * @var string\n     */\n    private static $_pdfRendererName = NULL;\n\n    /**\n     * Directory Path to the external Library used for rendering PDF files\n     *\n     * @var string\n     */\n    private static $_pdfRendererPath = NULL;\n\n    /**\n     * Default options for libxml loader\n     *\n     * @var int\n     */\n    private static $_libXmlLoaderOptions = null;\n\n    /**\n     * Set the Zip handler Class that PHPExcel should use for Zip file management (PCLZip or ZipArchive)\n     *\n     * @param string $zipClass\tThe Zip handler class that PHPExcel should use for Zip file management\n     * \t e.g. PHPExcel_Settings::PCLZip or PHPExcel_Settings::ZipArchive\n     * @return\tboolean\tSuccess or failure\n     */\n    public static function setZipClass($zipClass)\n    {\n        if (($zipClass === self::PCLZIP) ||\n            ($zipClass === self::ZIPARCHIVE)) {\n            self::$_zipClass = $zipClass;\n            return TRUE;\n        }\n        return FALSE;\n    } // function setZipClass()\n\n\n    /**\n     * Return the name of the Zip handler Class that PHPExcel is configured to use (PCLZip or ZipArchive)\n     *\tor Zip file management\n     *\n     * @return string Name of the Zip handler Class that PHPExcel is configured to use\n     *\tfor Zip file management\n     *\te.g. PHPExcel_Settings::PCLZip or PHPExcel_Settings::ZipArchive\n     */\n    public static function getZipClass()\n    {\n        return self::$_zipClass;\n    } // function getZipClass()\n\n\n    /**\n     * Return the name of the method that is currently configured for cell cacheing\n     *\n     * @return string Name of the cacheing method\n     */\n    public static function getCacheStorageMethod()\n    {\n        return PHPExcel_CachedObjectStorageFactory::getCacheStorageMethod();\n    } // function getCacheStorageMethod()\n\n\n    /**\n     * Return the name of the class that is currently being used for cell cacheing\n     *\n     * @return string Name of the class currently being used for cacheing\n     */\n    public static function getCacheStorageClass()\n    {\n        return PHPExcel_CachedObjectStorageFactory::getCacheStorageClass();\n    } // function getCacheStorageClass()\n\n\n    /**\n     * Set the method that should be used for cell cacheing\n     *\n     * @param string $method Name of the cacheing method\n     * @param array $arguments Optional configuration arguments for the cacheing method\n     * @return boolean Success or failure\n     */\n    public static function setCacheStorageMethod(\n    \t$method = PHPExcel_CachedObjectStorageFactory::cache_in_memory,\n      $arguments = array()\n    )\n    {\n        return PHPExcel_CachedObjectStorageFactory::initialize($method, $arguments);\n    } // function setCacheStorageMethod()\n\n\n    /**\n     * Set the locale code to use for formula translations and any special formatting\n     *\n     * @param string $locale The locale code to use (e.g. \"fr\" or \"pt_br\" or \"en_uk\")\n     * @return boolean Success or failure\n     */\n    public static function setLocale($locale='en_us')\n    {\n        return PHPExcel_Calculation::getInstance()->setLocale($locale);\n    } // function setLocale()\n\n\n    /**\n     * Set details of the external library that PHPExcel should use for rendering charts\n     *\n     * @param string $libraryName\tInternal reference name of the library\n     *\te.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH\n     * @param string $libraryBaseDir Directory path to the library's base folder\n     *\n     * @return\tboolean\tSuccess or failure\n     */\n    public static function setChartRenderer($libraryName, $libraryBaseDir)\n    {\n        if (!self::setChartRendererName($libraryName))\n            return FALSE;\n        return self::setChartRendererPath($libraryBaseDir);\n    } // function setChartRenderer()\n\n\n    /**\n     * Identify to PHPExcel the external library to use for rendering charts\n     *\n     * @param string $libraryName\tInternal reference name of the library\n     *\te.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH\n     *\n     * @return\tboolean\tSuccess or failure\n     */\n    public static function setChartRendererName($libraryName)\n    {\n        if (!in_array($libraryName,self::$_chartRenderers)) {\n            return FALSE;\n        }\n\n        self::$_chartRendererName = $libraryName;\n\n        return TRUE;\n    } // function setChartRendererName()\n\n\n    /**\n     * Tell PHPExcel where to find the external library to use for rendering charts\n     *\n     * @param string $libraryBaseDir\tDirectory path to the library's base folder\n     * @return\tboolean\tSuccess or failure\n     */\n    public static function setChartRendererPath($libraryBaseDir)\n    {\n        if ((file_exists($libraryBaseDir) === false) || (is_readable($libraryBaseDir) === false)) {\n            return FALSE;\n        }\n        self::$_chartRendererPath = $libraryBaseDir;\n\n        return TRUE;\n    } // function setChartRendererPath()\n\n\n    /**\n     * Return the Chart Rendering Library that PHPExcel is currently configured to use (e.g. jpgraph)\n     *\n     * @return string|NULL Internal reference name of the Chart Rendering Library that PHPExcel is\n     *\tcurrently configured to use\n     *\te.g. PHPExcel_Settings::CHART_RENDERER_JPGRAPH\n     */\n    public static function getChartRendererName()\n    {\n        return self::$_chartRendererName;\n    } // function getChartRendererName()\n\n\n    /**\n     * Return the directory path to the Chart Rendering Library that PHPExcel is currently configured to use\n     *\n     * @return string|NULL Directory Path to the Chart Rendering Library that PHPExcel is\n     * \tcurrently configured to use\n     */\n    public static function getChartRendererPath()\n    {\n        return self::$_chartRendererPath;\n    } // function getChartRendererPath()\n\n\n    /**\n     * Set details of the external library that PHPExcel should use for rendering PDF files\n     *\n     * @param string $libraryName Internal reference name of the library\n     * \te.g. PHPExcel_Settings::PDF_RENDERER_TCPDF,\n     * \tPHPExcel_Settings::PDF_RENDERER_DOMPDF\n     *  or PHPExcel_Settings::PDF_RENDERER_MPDF\n     * @param string $libraryBaseDir Directory path to the library's base folder\n     *\n     * @return boolean Success or failure\n     */\n    public static function setPdfRenderer($libraryName, $libraryBaseDir)\n    {\n        if (!self::setPdfRendererName($libraryName))\n            return FALSE;\n        return self::setPdfRendererPath($libraryBaseDir);\n    } // function setPdfRenderer()\n\n\n    /**\n     * Identify to PHPExcel the external library to use for rendering PDF files\n     *\n     * @param string $libraryName Internal reference name of the library\n     * \te.g. PHPExcel_Settings::PDF_RENDERER_TCPDF,\n     *\tPHPExcel_Settings::PDF_RENDERER_DOMPDF\n     * \tor PHPExcel_Settings::PDF_RENDERER_MPDF\n     *\n     * @return boolean Success or failure\n     */\n    public static function setPdfRendererName($libraryName)\n    {\n        if (!in_array($libraryName,self::$_pdfRenderers)) {\n            return FALSE;\n        }\n\n        self::$_pdfRendererName = $libraryName;\n\n        return TRUE;\n    } // function setPdfRendererName()\n\n\n    /**\n     * Tell PHPExcel where to find the external library to use for rendering PDF files\n     *\n     * @param string $libraryBaseDir Directory path to the library's base folder\n     * @return boolean Success or failure\n     */\n    public static function setPdfRendererPath($libraryBaseDir)\n    {\n        if ((file_exists($libraryBaseDir) === false) || (is_readable($libraryBaseDir) === false)) {\n            return FALSE;\n        }\n        self::$_pdfRendererPath = $libraryBaseDir;\n\n        return TRUE;\n    } // function setPdfRendererPath()\n\n\n    /**\n     * Return the PDF Rendering Library that PHPExcel is currently configured to use (e.g. dompdf)\n     *\n     * @return string|NULL Internal reference name of the PDF Rendering Library that PHPExcel is\n     * \tcurrently configured to use\n     *  e.g. PHPExcel_Settings::PDF_RENDERER_TCPDF,\n     *  PHPExcel_Settings::PDF_RENDERER_DOMPDF\n     *  or PHPExcel_Settings::PDF_RENDERER_MPDF\n     */\n    public static function getPdfRendererName()\n    {\n        return self::$_pdfRendererName;\n    } // function getPdfRendererName()\n\n    /**\n     * Return the directory path to the PDF Rendering Library that PHPExcel is currently configured to use\n     *\n     * @return string|NULL Directory Path to the PDF Rendering Library that PHPExcel is\n     *\t\tcurrently configured to use\n     */\n    public static function getPdfRendererPath()\n    {\n        return self::$_pdfRendererPath;\n    } // function getPdfRendererPath()\n\n    /**\n     * Set default options for libxml loader\n     *\n     * @param int $options Default options for libxml loader\n     */\n    public static function setLibXmlLoaderOptions($options = null)\n    {\n        if (is_null($options) && defined(LIBXML_DTDLOAD)) {\n            $options = LIBXML_DTDLOAD | LIBXML_DTDATTR;\n        }\n        if (version_compare(PHP_VERSION, '5.2.11') >= 0) {\n            @libxml_disable_entity_loader($options == (LIBXML_DTDLOAD | LIBXML_DTDATTR)); \n        }\n        self::$_libXmlLoaderOptions = $options;\n    } // function setLibXmlLoaderOptions\n\n    /**\n     * Get default options for libxml loader.\n     * Defaults to LIBXML_DTDLOAD | LIBXML_DTDATTR when not set explicitly.\n     *\n     * @return int Default options for libxml loader\n     */\n    public static function getLibXmlLoaderOptions()\n    {\n        if (is_null(self::$_libXmlLoaderOptions) && defined(LIBXML_DTDLOAD)) {\n            self::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR);\n        }\n        if (version_compare(PHP_VERSION, '5.2.11') >= 0) {\n            @libxml_disable_entity_loader(self::$_libXmlLoaderOptions == (LIBXML_DTDLOAD | LIBXML_DTDATTR));\n        }\n        return self::$_libXmlLoaderOptions;\n    } // function getLibXmlLoaderOptions\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/CodePage.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Shared_CodePage\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_CodePage\n{\n\t/**\n\t * Convert Microsoft Code Page Identifier to Code Page Name which iconv\n\t * and mbstring understands\n\t *\n\t * @param integer $codePage Microsoft Code Page Indentifier\n\t * @return string Code Page Name\n\t * @throws PHPExcel_Exception\n\t */\n\tpublic static function NumberToName($codePage = 1252)\n\t{\n\t\tswitch ($codePage) {\n\t\t\tcase 367:\treturn 'ASCII';\t\t\t\tbreak;\t//\tASCII\n\t\t\tcase 437:\treturn 'CP437';\t\t\t\tbreak;\t//\tOEM US\n\t\t\tcase 720:\tthrow new PHPExcel_Exception('Code page 720 not supported.');\n\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\t//\tOEM Arabic\n\t\t\tcase 737:\treturn 'CP737';\t\t\t\tbreak;\t//\tOEM Greek\n\t\t\tcase 775:\treturn 'CP775';\t\t\t\tbreak;\t//\tOEM Baltic\n\t\t\tcase 850:\treturn 'CP850';\t\t\t\tbreak;\t//\tOEM Latin I\n\t\t\tcase 852:\treturn 'CP852';\t\t\t\tbreak;\t//\tOEM Latin II (Central European)\n\t\t\tcase 855:\treturn 'CP855';\t\t\t\tbreak;\t//\tOEM Cyrillic\n\t\t\tcase 857:\treturn 'CP857';\t\t\t\tbreak;\t//\tOEM Turkish\n\t\t\tcase 858:\treturn 'CP858';\t\t\t\tbreak;\t//\tOEM Multilingual Latin I with Euro\n\t\t\tcase 860:\treturn 'CP860';\t\t\t\tbreak;\t//\tOEM Portugese\n\t\t\tcase 861:\treturn 'CP861';\t\t\t\tbreak;\t//\tOEM Icelandic\n\t\t\tcase 862:\treturn 'CP862';\t\t\t\tbreak;\t//\tOEM Hebrew\n\t\t\tcase 863:\treturn 'CP863';\t\t\t\tbreak;\t//\tOEM Canadian (French)\n\t\t\tcase 864:\treturn 'CP864';\t\t\t\tbreak;\t//\tOEM Arabic\n\t\t\tcase 865:\treturn 'CP865';\t\t\t\tbreak;\t//\tOEM Nordic\n\t\t\tcase 866:\treturn 'CP866';\t\t\t\tbreak;\t//\tOEM Cyrillic (Russian)\n\t\t\tcase 869:\treturn 'CP869';\t\t\t\tbreak;\t//\tOEM Greek (Modern)\n\t\t\tcase 874:\treturn 'CP874';\t\t\t\tbreak;\t//\tANSI Thai\n\t\t\tcase 932:\treturn 'CP932';\t\t\t\tbreak;\t//\tANSI Japanese Shift-JIS\n\t\t\tcase 936:\treturn 'CP936';\t\t\t\tbreak;\t//\tANSI Chinese Simplified GBK\n\t\t\tcase 949:\treturn 'CP949';\t\t\t\tbreak;\t//\tANSI Korean (Wansung)\n\t\t\tcase 950:\treturn 'CP950';\t\t\t\tbreak;\t//\tANSI Chinese Traditional BIG5\n\t\t\tcase 1200:\treturn 'UTF-16LE';\t\t\tbreak;\t//\tUTF-16 (BIFF8)\n\t\t\tcase 1250:\treturn 'CP1250';\t\t\tbreak;\t//\tANSI Latin II (Central European)\n\t\t\tcase 1251:\treturn 'CP1251';\t\t\tbreak;\t//\tANSI Cyrillic\n\t\t\tcase 0:\t\t//\tCodePage is not always correctly set when the xls file was saved by Apple's Numbers program\n\t\t\tcase 1252:\treturn 'CP1252';\t\t\tbreak;\t//\tANSI Latin I (BIFF4-BIFF7)\n\t\t\tcase 1253:\treturn 'CP1253';\t\t\tbreak;\t//\tANSI Greek\n\t\t\tcase 1254:\treturn 'CP1254';\t\t\tbreak;\t//\tANSI Turkish\n\t\t\tcase 1255:\treturn 'CP1255';\t\t\tbreak;\t//\tANSI Hebrew\n\t\t\tcase 1256:\treturn 'CP1256';\t\t\tbreak;\t//\tANSI Arabic\n\t\t\tcase 1257:\treturn 'CP1257';\t\t\tbreak;\t//\tANSI Baltic\n\t\t\tcase 1258:\treturn 'CP1258';\t\t\tbreak;\t//\tANSI Vietnamese\n\t\t\tcase 1361:\treturn 'CP1361';\t\t\tbreak;\t//\tANSI Korean (Johab)\n\t\t\tcase 10000:\treturn 'MAC';\t\t\t\tbreak;\t//\tApple Roman\n\t\t\tcase 10001:\treturn 'CP932';\t\t\t\tbreak;\t//\tMacintosh Japanese\n\t\t\tcase 10002:\treturn 'CP950';\t\t\t\tbreak;\t//\tMacintosh Chinese Traditional\n\t\t\tcase 10003:\treturn 'CP1361';\t\t\tbreak;\t//\tMacintosh Korean\n\t\t\tcase 10006:\treturn 'MACGREEK';\t\t\tbreak;\t//\tMacintosh Greek\n\t\t\tcase 10007:\treturn 'MACCYRILLIC';\t\t\tbreak;\t//\tMacintosh Cyrillic\n                        case 10008:\treturn 'CP936';\t\t\t\tbreak;  //\tMacintosh - Simplified Chinese (GB 2312)\n\t\t\tcase 10029:\treturn 'MACCENTRALEUROPE';\t\tbreak;\t//\tMacintosh Central Europe\n\t\t\tcase 10079:\treturn 'MACICELAND';\t\t\tbreak;\t//\tMacintosh Icelandic\n\t\t\tcase 10081:\treturn 'MACTURKISH';\t\t\tbreak;\t//\tMacintosh Turkish\n\t\t\tcase 21010:\treturn 'UTF-16LE';\t\t\tbreak;\t//\tUTF-16 (BIFF8) This isn't correct, but some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE\n\t\t\tcase 32768:\treturn 'MAC';\t\t\t\tbreak;\t//\tApple Roman\n\t\t\tcase 32769:\tthrow new PHPExcel_Exception('Code page 32769 not supported.');\n\t\t\t\t\t\t\t\t\t\t\t\t\tbreak;\t//\tANSI Latin I (BIFF2-BIFF3)\n\t\t\tcase 65000:\treturn 'UTF-7';\t\t\t\tbreak;\t//\tUnicode (UTF-7)\n\t\t\tcase 65001:\treturn 'UTF-8';\t\t\t\tbreak;\t//\tUnicode (UTF-8)\n\t\t}\n\n\t\tthrow new PHPExcel_Exception('Unknown codepage: ' . $codePage);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/Date.php",
    "content": "<?php\n\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Shared_Date\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_Date\n{\n\t/** constants */\n\tconst CALENDAR_WINDOWS_1900 = 1900;\t\t//\tBase date of 1st Jan 1900 = 1.0\n\tconst CALENDAR_MAC_1904 = 1904;\t\t\t//\tBase date of 2nd Jan 1904 = 1.0\n\n\t/*\n\t * Names of the months of the year, indexed by shortname\n\t * Planned usage for locale settings\n\t *\n\t * @public\n\t * @var\tstring[]\n\t */\n\tpublic static $_monthNames = array(\t'Jan' => 'January',\n\t\t\t\t\t\t\t\t\t\t'Feb' => 'February',\n\t\t\t\t\t\t\t\t\t\t'Mar' => 'March',\n\t\t\t\t\t\t\t\t\t\t'Apr' => 'April',\n\t\t\t\t\t\t\t\t\t\t'May' => 'May',\n\t\t\t\t\t\t\t\t\t\t'Jun' => 'June',\n\t\t\t\t\t\t\t\t\t\t'Jul' => 'July',\n\t\t\t\t\t\t\t\t\t\t'Aug' => 'August',\n\t\t\t\t\t\t\t\t\t\t'Sep' => 'September',\n\t\t\t\t\t\t\t\t\t\t'Oct' => 'October',\n\t\t\t\t\t\t\t\t\t\t'Nov' => 'November',\n\t\t\t\t\t\t\t\t\t\t'Dec' => 'December',\n\t\t\t\t\t\t\t\t\t  );\n\n\t/*\n\t * Names of the months of the year, indexed by shortname\n\t * Planned usage for locale settings\n\t *\n\t * @public\n\t * @var\tstring[]\n\t */\n\tpublic static $_numberSuffixes = array(\t'st',\n\t\t\t\t\t\t\t\t\t\t\t'nd',\n\t\t\t\t\t\t\t\t\t\t\t'rd',\n\t\t\t\t\t\t\t\t\t\t\t'th',\n\t\t\t\t\t\t\t\t\t\t  );\n\n\t/*\n\t * Base calendar year to use for calculations\n\t *\n\t * @private\n\t * @var\tint\n\t */\n\tprotected static $_excelBaseDate\t= self::CALENDAR_WINDOWS_1900;\n\n\t/**\n\t * Set the Excel calendar (Windows 1900 or Mac 1904)\n\t *\n\t * @param\t integer\t$baseDate\t\t\tExcel base date (1900 or 1904)\n\t * @return\t boolean\t\t\t\t\t\tSuccess or failure\n\t */\n\tpublic static function setExcelCalendar($baseDate) {\n\t\tif (($baseDate == self::CALENDAR_WINDOWS_1900) ||\n\t\t\t($baseDate == self::CALENDAR_MAC_1904)) {\n\t\t\tself::$_excelBaseDate = $baseDate;\n\t\t\treturn TRUE;\n\t\t}\n\t\treturn FALSE;\n\t}\t//\tfunction setExcelCalendar()\n\n\n\t/**\n\t * Return the Excel calendar (Windows 1900 or Mac 1904)\n\t *\n\t * @return\t integer\tExcel base date (1900 or 1904)\n\t */\n\tpublic static function getExcelCalendar() {\n\t\treturn self::$_excelBaseDate;\n\t}\t//\tfunction getExcelCalendar()\n\n\n\t/**\n\t *\tConvert a date from Excel to PHP\n\t *\n\t *\t@param\t\tlong\t\t$dateValue\t\t\tExcel date/time value\n\t *\t@param\t\tboolean\t\t$adjustToTimezone\tFlag indicating whether $dateValue should be treated as\n\t *\t\t\t\t\t\t\t\t\t\t\t\t\ta UST timestamp, or adjusted to UST\n\t *\t@param\t\tstring\t \t$timezone\t\t\tThe timezone for finding the adjustment from UST\n\t *\t@return\t\tlong\t\tPHP serialized date/time\n\t */\n\tpublic static function ExcelToPHP($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) {\n\t\tif (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) {\n\t\t\t$my_excelBaseDate = 25569;\n\t\t\t//\tAdjust for the spurious 29-Feb-1900 (Day 60)\n\t\t\tif ($dateValue < 60) {\n\t\t\t\t--$my_excelBaseDate;\n\t\t\t}\n\t\t} else {\n\t\t\t$my_excelBaseDate = 24107;\n\t\t}\n\n\t\t// Perform conversion\n\t\tif ($dateValue >= 1) {\n\t\t\t$utcDays = $dateValue - $my_excelBaseDate;\n\t\t\t$returnValue = round($utcDays * 86400);\n\t\t\tif (($returnValue <= PHP_INT_MAX) && ($returnValue >= -PHP_INT_MAX)) {\n\t\t\t\t$returnValue = (integer) $returnValue;\n\t\t\t}\n\t\t} else {\n\t\t\t$hours = round($dateValue * 24);\n\t\t\t$mins = round($dateValue * 1440) - round($hours * 60);\n\t\t\t$secs = round($dateValue * 86400) - round($hours * 3600) - round($mins * 60);\n\t\t\t$returnValue = (integer) gmmktime($hours, $mins, $secs);\n\t\t}\n\n\t\t$timezoneAdjustment = ($adjustToTimezone) ?\n\t\t    PHPExcel_Shared_TimeZone::getTimezoneAdjustment($timezone, $returnValue) :\n\t\t    0;\n\n\t\t// Return\n\t\treturn $returnValue + $timezoneAdjustment;\n\t}\t//\tfunction ExcelToPHP()\n\n\n\t/**\n\t * Convert a date from Excel to a PHP Date/Time object\n\t *\n\t * @param\tinteger\t\t$dateValue\t\tExcel date/time value\n\t * @return\tDateTime\t\t\t\t\tPHP date/time object\n\t */\n\tpublic static function ExcelToPHPObject($dateValue = 0) {\n\t\t$dateTime = self::ExcelToPHP($dateValue);\n\t\t$days = floor($dateTime / 86400);\n\t\t$time = round((($dateTime / 86400) - $days) * 86400);\n\t\t$hours = round($time / 3600);\n\t\t$minutes = round($time / 60) - ($hours * 60);\n\t\t$seconds = round($time) - ($hours * 3600) - ($minutes * 60);\n\n\t\t$dateObj = date_create('1-Jan-1970+'.$days.' days');\n\t\t$dateObj->setTime($hours,$minutes,$seconds);\n\n\t\treturn $dateObj;\n\t}\t//\tfunction ExcelToPHPObject()\n\n\n\t/**\n\t *\tConvert a date from PHP to Excel\n\t *\n\t *\t@param\tmixed\t\t$dateValue\t\t\tPHP serialized date/time or date object\n\t *\t@param\tboolean\t\t$adjustToTimezone\tFlag indicating whether $dateValue should be treated as\n\t *\t\t\t\t\t\t\t\t\t\t\t\t\ta UST timestamp, or adjusted to UST\n\t *\t@param\tstring\t \t$timezone\t\t\tThe timezone for finding the adjustment from UST\n\t *\t@return\tmixed\t\tExcel date/time value\n\t *\t\t\t\t\t\t\tor boolean FALSE on failure\n\t */\n\tpublic static function PHPToExcel($dateValue = 0, $adjustToTimezone = FALSE, $timezone = NULL) {\n\t\t$saveTimeZone = date_default_timezone_get();\n\t\tdate_default_timezone_set('UTC');\n\t\t$retValue = FALSE;\n\t\tif ((is_object($dateValue)) && ($dateValue instanceof DateTime)) {\n\t\t\t$retValue = self::FormattedPHPToExcel( $dateValue->format('Y'), $dateValue->format('m'), $dateValue->format('d'),\n\t\t\t\t\t\t\t\t\t\t\t\t   $dateValue->format('H'), $dateValue->format('i'), $dateValue->format('s')\n\t\t\t\t\t\t\t\t\t\t\t\t );\n\t\t} elseif (is_numeric($dateValue)) {\n\t\t\t$retValue = self::FormattedPHPToExcel( date('Y',$dateValue), date('m',$dateValue), date('d',$dateValue),\n\t\t\t\t\t\t\t\t\t\t\t\t   date('H',$dateValue), date('i',$dateValue), date('s',$dateValue)\n\t\t\t\t\t\t\t\t\t\t\t\t );\n\t\t}\n\t\tdate_default_timezone_set($saveTimeZone);\n\n\t\treturn $retValue;\n\t}\t//\tfunction PHPToExcel()\n\n\n\t/**\n\t * FormattedPHPToExcel\n\t *\n\t * @param\tlong\t$year\n\t * @param\tlong\t$month\n\t * @param\tlong\t$day\n\t * @param\tlong\t$hours\n\t * @param\tlong\t$minutes\n\t * @param\tlong\t$seconds\n\t * @return  long\t\t\t\tExcel date/time value\n\t */\n\tpublic static function FormattedPHPToExcel($year, $month, $day, $hours=0, $minutes=0, $seconds=0) {\n\t\tif (self::$_excelBaseDate == self::CALENDAR_WINDOWS_1900) {\n\t\t\t//\n\t\t\t//\tFudge factor for the erroneous fact that the year 1900 is treated as a Leap Year in MS Excel\n\t\t\t//\tThis affects every date following 28th February 1900\n\t\t\t//\n\t\t\t$excel1900isLeapYear = TRUE;\n\t\t\tif (($year == 1900) && ($month <= 2)) { $excel1900isLeapYear = FALSE; }\n\t\t\t$my_excelBaseDate = 2415020;\n\t\t} else {\n\t\t\t$my_excelBaseDate = 2416481;\n\t\t\t$excel1900isLeapYear = FALSE;\n\t\t}\n\n\t\t//\tJulian base date Adjustment\n\t\tif ($month > 2) {\n\t\t\t$month -= 3;\n\t\t} else {\n\t\t\t$month += 9;\n\t\t\t--$year;\n\t\t}\n\n\t\t//\tCalculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0)\n\t\t$century = substr($year,0,2);\n\t\t$decade = substr($year,2,2);\n\t\t$excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $my_excelBaseDate + $excel1900isLeapYear;\n\n\t\t$excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400;\n\n\t\treturn (float) $excelDate + $excelTime;\n\t}\t//\tfunction FormattedPHPToExcel()\n\n\n\t/**\n\t * Is a given cell a date/time?\n\t *\n\t * @param\t PHPExcel_Cell\t$pCell\n\t * @return\t boolean\n\t */\n\tpublic static function isDateTime(PHPExcel_Cell $pCell) {\n\t\treturn self::isDateTimeFormat(\n\t\t\t$pCell->getWorksheet()->getStyle(\n\t\t\t\t$pCell->getCoordinate()\n\t\t\t)->getNumberFormat()\n\t\t);\n\t}\t//\tfunction isDateTime()\n\n\n\t/**\n\t * Is a given number format a date/time?\n\t *\n\t * @param\t PHPExcel_Style_NumberFormat\t$pFormat\n\t * @return\t boolean\n\t */\n\tpublic static function isDateTimeFormat(PHPExcel_Style_NumberFormat $pFormat) {\n\t\treturn self::isDateTimeFormatCode($pFormat->getFormatCode());\n\t}\t//\tfunction isDateTimeFormat()\n\n\n\tprivate static\t$possibleDateFormatCharacters = 'eymdHs';\n\n\t/**\n\t * Is a given number format code a date/time?\n\t *\n\t * @param\t string\t$pFormatCode\n\t * @return\t boolean\n\t */\n\tpublic static function isDateTimeFormatCode($pFormatCode = '') {\n\t\tif (strtolower($pFormatCode) === strtolower(PHPExcel_Style_NumberFormat::FORMAT_GENERAL))\n            //\t\"General\" contains an epoch letter 'e', so we trap for it explicitly here (case-insensitive check)\n\t\t\treturn FALSE;\n        if (preg_match('/[0#]E[+-]0/i', $pFormatCode))\n\t\t\t//\tScientific format\n\t\t\treturn FALSE;\n\t\t// Switch on formatcode\n\t\tswitch ($pFormatCode) {\n\t\t\t//\tExplicitly defined date formats\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_DDMMYYYY:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYSLASH:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_DMYMINUS:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_DMMINUS:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_MYMINUS:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME1:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME2:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME3:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME5:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME6:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME7:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME8:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDDSLASH:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX14:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX16:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX17:\n\t\t\tcase PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX22:\n\t\t\t\treturn TRUE;\n\t\t}\n\n\t\t//\tTypically number, currency or accounting (or occasionally fraction) formats\n\t\tif ((substr($pFormatCode,0,1) == '_') || (substr($pFormatCode,0,2) == '0 ')) {\n\t\t\treturn FALSE;\n\t\t}\n\t\t// Try checking for any of the date formatting characters that don't appear within square braces\n\t\tif (preg_match('/(^|\\])[^\\[]*['.self::$possibleDateFormatCharacters.']/i',$pFormatCode)) {\n\t\t\t//\tWe might also have a format mask containing quoted strings...\n\t\t\t//\t\twe don't want to test for any of our characters within the quoted blocks\n\t\t\tif (strpos($pFormatCode,'\"') !== FALSE) {\n\t\t\t\t$segMatcher = FALSE;\n\t\t\t\tforeach(explode('\"',$pFormatCode) as $subVal) {\n\t\t\t\t\t//\tOnly test in alternate array entries (the non-quoted blocks)\n\t\t\t\t\tif (($segMatcher = !$segMatcher) &&\n\t\t\t\t\t\t(preg_match('/(^|\\])[^\\[]*['.self::$possibleDateFormatCharacters.']/i',$subVal))) {\n\t\t\t\t\t\treturn TRUE;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn FALSE;\n\t\t\t}\n\t\t\treturn TRUE;\n\t\t}\n\n\t\t// No date...\n\t\treturn FALSE;\n\t}\t//\tfunction isDateTimeFormatCode()\n\n\n\t/**\n\t * Convert a date/time string to Excel time\n\t *\n\t * @param\tstring\t$dateValue\t\tExamples: '2009-12-31', '2009-12-31 15:59', '2009-12-31 15:59:10'\n\t * @return\tfloat|FALSE\t\tExcel date/time serial value\n\t */\n\tpublic static function stringToExcel($dateValue = '') {\n\t\tif (strlen($dateValue) < 2)\n\t\t\treturn FALSE;\n\t\tif (!preg_match('/^(\\d{1,4}[ \\.\\/\\-][A-Z]{3,9}([ \\.\\/\\-]\\d{1,4})?|[A-Z]{3,9}[ \\.\\/\\-]\\d{1,4}([ \\.\\/\\-]\\d{1,4})?|\\d{1,4}[ \\.\\/\\-]\\d{1,4}([ \\.\\/\\-]\\d{1,4})?)( \\d{1,2}:\\d{1,2}(:\\d{1,2})?)?$/iu', $dateValue))\n\t\t\treturn FALSE;\n\n\t\t$dateValueNew = PHPExcel_Calculation_DateTime::DATEVALUE($dateValue);\n\n\t\tif ($dateValueNew === PHPExcel_Calculation_Functions::VALUE()) {\n\t\t\treturn FALSE;\n\t\t} else {\n\t\t\tif (strpos($dateValue, ':') !== FALSE) {\n\t\t\t\t$timeValue = PHPExcel_Calculation_DateTime::TIMEVALUE($dateValue);\n\t\t\t\tif ($timeValue === PHPExcel_Calculation_Functions::VALUE()) {\n\t\t\t\t\treturn FALSE;\n\t\t\t\t}\n\t\t\t\t$dateValueNew += $timeValue;\n\t\t\t}\n\t\t\treturn $dateValueNew;\n\t\t}\n\n\n\t}\n\n    public static function monthStringToNumber($month) {\n        $monthIndex = 1;\n        foreach(self::$_monthNames as $shortMonthName => $longMonthName) {\n            if (($month === $longMonthName) || ($month === $shortMonthName)) {\n                return $monthIndex;\n            }\n            ++$monthIndex;\n        }\n        return $month;\n    }\n\n    public static function dayStringToNumber($day) {\n\t\t$strippedDayValue = (str_replace(self::$_numberSuffixes,'',$day));\n\t\tif (is_numeric($strippedDayValue)) {\n\t\t    return $strippedDayValue;\n\t\t}\n\t\treturn $day;\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/Drawing.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Shared_Drawing\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_Drawing\n{\n\t/**\n\t * Convert pixels to EMU\n\t *\n\t * @param \tint $pValue\tValue in pixels\n\t * @return \tint\t\t\tValue in EMU\n\t */\n\tpublic static function pixelsToEMU($pValue = 0) {\n\t\treturn round($pValue * 9525);\n\t}\n\n\t/**\n\t * Convert EMU to pixels\n\t *\n\t * @param \tint $pValue\tValue in EMU\n\t * @return \tint\t\t\tValue in pixels\n\t */\n\tpublic static function EMUToPixels($pValue = 0) {\n\t\tif ($pValue != 0) {\n\t\t\treturn round($pValue / 9525);\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/**\n\t * Convert pixels to column width. Exact algorithm not known.\n\t * By inspection of a real Excel file using Calibri 11, one finds 1000px ~ 142.85546875\n\t * This gives a conversion factor of 7. Also, we assume that pixels and font size are proportional.\n\t *\n\t * @param \tint $pValue\tValue in pixels\n\t * @param \tPHPExcel_Style_Font $pDefaultFont\tDefault font of the workbook\n\t * @return \tint\t\t\tValue in cell dimension\n\t */\n\tpublic static function pixelsToCellDimension($pValue = 0, PHPExcel_Style_Font $pDefaultFont) {\n\t\t// Font name and size\n\t\t$name = $pDefaultFont->getName();\n\t\t$size = $pDefaultFont->getSize();\n\n\t\tif (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) {\n\t\t\t// Exact width can be determined\n\t\t\t$colWidth = $pValue\n\t\t\t\t* PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width']\n\t\t\t\t/ PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px'];\n\t\t} else {\n\t\t\t// We don't have data for this particular font and size, use approximation by\n\t\t\t// extrapolating from Calibri 11\n\t\t\t$colWidth = $pValue * 11\n\t\t\t\t* PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width']\n\t\t\t\t/ PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px'] / $size;\n\t\t}\n\n\t\treturn $colWidth;\n\t}\n\n\t/**\n\t * Convert column width from (intrinsic) Excel units to pixels\n\t *\n\t * @param \tfloat\t$pValue\t\tValue in cell dimension\n\t * @param \tPHPExcel_Style_Font $pDefaultFont\tDefault font of the workbook\n\t * @return \tint\t\tValue in pixels\n\t */\n\tpublic static function cellDimensionToPixels($pValue = 0, PHPExcel_Style_Font $pDefaultFont) {\n\t\t// Font name and size\n\t\t$name = $pDefaultFont->getName();\n\t\t$size = $pDefaultFont->getSize();\n\n\t\tif (isset(PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size])) {\n\t\t\t// Exact width can be determined\n\t\t\t$colWidth = $pValue\n\t\t\t\t* PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['px']\n\t\t\t\t/ PHPExcel_Shared_Font::$defaultColumnWidths[$name][$size]['width'];\n\n\t\t} else {\n\t\t\t// We don't have data for this particular font and size, use approximation by\n\t\t\t// extrapolating from Calibri 11\n\t\t\t$colWidth = $pValue * $size\n\t\t\t\t* PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['px']\n\t\t\t\t/ PHPExcel_Shared_Font::$defaultColumnWidths['Calibri'][11]['width'] / 11;\n\t\t}\n\n\t\t// Round pixels to closest integer\n\t\t$colWidth = (int) round($colWidth);\n\n\t\treturn $colWidth;\n\t}\n\n\t/**\n\t * Convert pixels to points\n\t *\n\t * @param \tint $pValue\tValue in pixels\n\t * @return \tint\t\t\tValue in points\n\t */\n\tpublic static function pixelsToPoints($pValue = 0) {\n\t\treturn $pValue * 0.67777777;\n\t}\n\n\t/**\n\t * Convert points to pixels\n\t *\n\t * @param \tint $pValue\tValue in points\n\t * @return \tint\t\t\tValue in pixels\n\t */\n\tpublic static function pointsToPixels($pValue = 0) {\n\t\tif ($pValue != 0) {\n\t\t\treturn (int) ceil($pValue * 1.333333333);\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/**\n\t * Convert degrees to angle\n\t *\n\t * @param \tint $pValue\tDegrees\n\t * @return \tint\t\t\tAngle\n\t */\n\tpublic static function degreesToAngle($pValue = 0) {\n\t\treturn (int)round($pValue * 60000);\n\t}\n\n\t/**\n\t * Convert angle to degrees\n\t *\n\t * @param \tint $pValue\tAngle\n\t * @return \tint\t\t\tDegrees\n\t */\n\tpublic static function angleToDegrees($pValue = 0) {\n\t\tif ($pValue != 0) {\n\t\t\treturn round($pValue / 60000);\n\t\t} else {\n\t\t\treturn 0;\n\t\t}\n\t}\n\n\t/**\n\t * Create a new image from file. By alexander at alexauto dot nl\n\t *\n\t * @link http://www.php.net/manual/en/function.imagecreatefromwbmp.php#86214\n\t * @param string $filename Path to Windows DIB (BMP) image\n\t * @return resource\n\t */\n\tpublic static function imagecreatefrombmp($p_sFile)\n\t{\n        //    Load the image into a string\n        $file    =    fopen($p_sFile,\"rb\");\n        $read    =    fread($file,10);\n        while(!feof($file)&&($read<>\"\"))\n            $read    .=    fread($file,1024);\n\n        $temp    =    unpack(\"H*\",$read);\n        $hex    =    $temp[1];\n        $header    =    substr($hex,0,108);\n\n        //    Process the header\n        //    Structure: http://www.fastgraph.com/help/bmp_header_format.html\n        if (substr($header,0,4)==\"424d\")\n        {\n            //    Cut it in parts of 2 bytes\n            $header_parts    =    str_split($header,2);\n\n            //    Get the width        4 bytes\n            $width            =    hexdec($header_parts[19].$header_parts[18]);\n\n            //    Get the height        4 bytes\n            $height            =    hexdec($header_parts[23].$header_parts[22]);\n\n            //    Unset the header params\n            unset($header_parts);\n        }\n\n        //    Define starting X and Y\n        $x                =    0;\n        $y                =    1;\n\n        //    Create newimage\n        $image            =    imagecreatetruecolor($width,$height);\n\n        //    Grab the body from the image\n        $body            =    substr($hex,108);\n\n        //    Calculate if padding at the end-line is needed\n        //    Divided by two to keep overview.\n        //    1 byte = 2 HEX-chars\n        $body_size        =    (strlen($body)/2);\n        $header_size    =    ($width*$height);\n\n        //    Use end-line padding? Only when needed\n        $usePadding        =    ($body_size>($header_size*3)+4);\n\n        //    Using a for-loop with index-calculation instaid of str_split to avoid large memory consumption\n        //    Calculate the next DWORD-position in the body\n        for ($i=0;$i<$body_size;$i+=3)\n        {\n            //    Calculate line-ending and padding\n            if ($x>=$width)\n            {\n                //    If padding needed, ignore image-padding\n                //    Shift i to the ending of the current 32-bit-block\n                if ($usePadding)\n                    $i    +=    $width%4;\n\n                //    Reset horizontal position\n                $x    =    0;\n\n                //    Raise the height-position (bottom-up)\n                $y++;\n\n                //    Reached the image-height? Break the for-loop\n                if ($y>$height)\n                    break;\n            }\n\n            //    Calculation of the RGB-pixel (defined as BGR in image-data)\n            //    Define $i_pos as absolute position in the body\n            $i_pos    =    $i*2;\n            $r        =    hexdec($body[$i_pos+4].$body[$i_pos+5]);\n            $g        =    hexdec($body[$i_pos+2].$body[$i_pos+3]);\n            $b        =    hexdec($body[$i_pos].$body[$i_pos+1]);\n\n            //    Calculate and draw the pixel\n            $color    =    imagecolorallocate($image,$r,$g,$b);\n            imagesetpixel($image,$x,$height-$y,$color);\n\n            //    Raise the horizontal position\n            $x++;\n        }\n\n        //    Unset the body / free the memory\n        unset($body);\n\n        //    Return image-object\n        return $image;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer/SpContainer.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer\n{\n\t/**\n\t * Parent Shape Group Container\n\t *\n\t * @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer\n\t */\n\tprivate $_parent;\n\n\t/**\n\t * Is this a group shape?\n\t *\n\t * @var boolean\n\t */\n\tprivate $_spgr = false;\n\n\t/**\n\t * Shape type\n\t *\n\t * @var int\n\t */\n\tprivate $_spType;\n\n\t/**\n\t * Shape flag\n\t *\n\t * @var int\n\t */\n\tprivate $_spFlag;\n\n\t/**\n\t * Shape index (usually group shape has index 0, and the rest: 1,2,3...)\n\t *\n\t * @var boolean\n\t */\n\tprivate $_spId;\n\n\t/**\n\t * Array of options\n\t *\n\t * @var array\n\t */\n\tprivate $_OPT;\n\n\t/**\n\t * Cell coordinates of upper-left corner of shape, e.g. 'A1'\n\t *\n\t * @var string\n\t */\n\tprivate $_startCoordinates;\n\n\t/**\n\t * Horizontal offset of upper-left corner of shape measured in 1/1024 of column width\n\t *\n\t * @var int\n\t */\n\tprivate $_startOffsetX;\n\n\t/**\n\t * Vertical offset of upper-left corner of shape measured in 1/256 of row height\n\t *\n\t * @var int\n\t */\n\tprivate $_startOffsetY;\n\n\t/**\n\t * Cell coordinates of bottom-right corner of shape, e.g. 'B2'\n\t *\n\t * @var string\n\t */\n\tprivate $_endCoordinates;\n\n\t/**\n\t * Horizontal offset of bottom-right corner of shape measured in 1/1024 of column width\n\t *\n\t * @var int\n\t */\n\tprivate $_endOffsetX;\n\n\t/**\n\t * Vertical offset of bottom-right corner of shape measured in 1/256 of row height\n\t *\n\t * @var int\n\t */\n\tprivate $_endOffsetY;\n\n\t/**\n\t * Set parent Shape Group Container\n\t *\n\t * @param PHPExcel_Shared_Escher_DgContainer_SpgrContainer $parent\n\t */\n\tpublic function setParent($parent)\n\t{\n\t\t$this->_parent = $parent;\n\t}\n\n\t/**\n\t * Get the parent Shape Group Container\n\t *\n\t * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer\n\t */\n\tpublic function getParent()\n\t{\n\t\treturn $this->_parent;\n\t}\n\n\t/**\n\t * Set whether this is a group shape\n\t *\n\t * @param boolean $value\n\t */\n\tpublic function setSpgr($value = false)\n\t{\n\t\t$this->_spgr = $value;\n\t}\n\n\t/**\n\t * Get whether this is a group shape\n\t *\n\t * @return boolean\n\t */\n\tpublic function getSpgr()\n\t{\n\t\treturn $this->_spgr;\n\t}\n\n\t/**\n\t * Set the shape type\n\t *\n\t * @param int $value\n\t */\n\tpublic function setSpType($value)\n\t{\n\t\t$this->_spType = $value;\n\t}\n\n\t/**\n\t * Get the shape type\n\t *\n\t * @return int\n\t */\n\tpublic function getSpType()\n\t{\n\t\treturn $this->_spType;\n\t}\n\n\t/**\n\t * Set the shape flag\n\t *\n\t * @param int $value\n\t */\n\tpublic function setSpFlag($value)\n\t{\n\t\t$this->_spFlag = $value;\n\t}\n\n\t/**\n\t * Get the shape flag\n\t *\n\t * @return int\n\t */\n\tpublic function getSpFlag()\n\t{\n\t\treturn $this->_spFlag;\n\t}\n\n\t/**\n\t * Set the shape index\n\t *\n\t * @param int $value\n\t */\n\tpublic function setSpId($value)\n\t{\n\t\t$this->_spId = $value;\n\t}\n\n\t/**\n\t * Get the shape index\n\t *\n\t * @return int\n\t */\n\tpublic function getSpId()\n\t{\n\t\treturn $this->_spId;\n\t}\n\n\t/**\n\t * Set an option for the Shape Group Container\n\t *\n\t * @param int $property The number specifies the option\n\t * @param mixed $value\n\t */\n\tpublic function setOPT($property, $value)\n\t{\n\t\t$this->_OPT[$property] = $value;\n\t}\n\n\t/**\n\t * Get an option for the Shape Group Container\n\t *\n\t * @param int $property The number specifies the option\n\t * @return mixed\n\t */\n\tpublic function getOPT($property)\n\t{\n\t\tif (isset($this->_OPT[$property])) {\n\t\t\treturn $this->_OPT[$property];\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * Get the collection of options\n\t *\n\t * @return array\n\t */\n\tpublic function getOPTCollection()\n\t{\n\t\treturn $this->_OPT;\n\t}\n\n\t/**\n\t * Set cell coordinates of upper-left corner of shape\n\t *\n\t * @param string $value\n\t */\n\tpublic function setStartCoordinates($value = 'A1')\n\t{\n\t\t$this->_startCoordinates = $value;\n\t}\n\n\t/**\n\t * Get cell coordinates of upper-left corner of shape\n\t *\n\t * @return string\n\t */\n\tpublic function getStartCoordinates()\n\t{\n\t\treturn $this->_startCoordinates;\n\t}\n\n\t/**\n\t * Set offset in x-direction of upper-left corner of shape measured in 1/1024 of column width\n\t *\n\t * @param int $startOffsetX\n\t */\n\tpublic function setStartOffsetX($startOffsetX = 0)\n\t{\n\t\t$this->_startOffsetX = $startOffsetX;\n\t}\n\n\t/**\n\t * Get offset in x-direction of upper-left corner of shape measured in 1/1024 of column width\n\t *\n\t * @return int\n\t */\n\tpublic function getStartOffsetX()\n\t{\n\t\treturn $this->_startOffsetX;\n\t}\n\n\t/**\n\t * Set offset in y-direction of upper-left corner of shape measured in 1/256 of row height\n\t *\n\t * @param int $startOffsetY\n\t */\n\tpublic function setStartOffsetY($startOffsetY = 0)\n\t{\n\t\t$this->_startOffsetY = $startOffsetY;\n\t}\n\n\t/**\n\t * Get offset in y-direction of upper-left corner of shape measured in 1/256 of row height\n\t *\n\t * @return int\n\t */\n\tpublic function getStartOffsetY()\n\t{\n\t\treturn $this->_startOffsetY;\n\t}\n\n\t/**\n\t * Set cell coordinates of bottom-right corner of shape\n\t *\n\t * @param string $value\n\t */\n\tpublic function setEndCoordinates($value = 'A1')\n\t{\n\t\t$this->_endCoordinates = $value;\n\t}\n\n\t/**\n\t * Get cell coordinates of bottom-right corner of shape\n\t *\n\t * @return string\n\t */\n\tpublic function getEndCoordinates()\n\t{\n\t\treturn $this->_endCoordinates;\n\t}\n\n\t/**\n\t * Set offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width\n\t *\n\t * @param int $startOffsetX\n\t */\n\tpublic function setEndOffsetX($endOffsetX = 0)\n\t{\n\t\t$this->_endOffsetX = $endOffsetX;\n\t}\n\n\t/**\n\t * Get offset in x-direction of bottom-right corner of shape measured in 1/1024 of column width\n\t *\n\t * @return int\n\t */\n\tpublic function getEndOffsetX()\n\t{\n\t\treturn $this->_endOffsetX;\n\t}\n\n\t/**\n\t * Set offset in y-direction of bottom-right corner of shape measured in 1/256 of row height\n\t *\n\t * @param int $endOffsetY\n\t */\n\tpublic function setEndOffsetY($endOffsetY = 0)\n\t{\n\t\t$this->_endOffsetY = $endOffsetY;\n\t}\n\n\t/**\n\t * Get offset in y-direction of bottom-right corner of shape measured in 1/256 of row height\n\t *\n\t * @return int\n\t */\n\tpublic function getEndOffsetY()\n\t{\n\t\treturn $this->_endOffsetY;\n\t}\n\n\t/**\n\t * Get the nesting level of this spContainer. This is the number of spgrContainers between this spContainer and\n\t * the dgContainer. A value of 1 = immediately within first spgrContainer\n\t * Higher nesting level occurs if and only if spContainer is part of a shape group\n\t *\n\t * @return int Nesting level\n\t */\n\tpublic function getNestingLevel()\n\t{\n\t\t$nestingLevel = 0;\n\n\t\t$parent = $this->getParent();\n\t\twhile ($parent instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) {\n\t\t\t++$nestingLevel;\n\t\t\t$parent = $parent->getParent();\n\t\t}\n\n\t\treturn $nestingLevel;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/Escher/DgContainer/SpgrContainer.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Shared_Escher_DgContainer_SpgrContainer\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_Escher_DgContainer_SpgrContainer\n{\n\t/**\n\t * Parent Shape Group Container\n\t *\n\t * @var PHPExcel_Shared_Escher_DgContainer_SpgrContainer\n\t */\n\tprivate $_parent;\n\n\t/**\n\t * Shape Container collection\n\t *\n\t * @var array\n\t */\n\tprivate $_children = array();\n\n\t/**\n\t * Set parent Shape Group Container\n\t *\n\t * @param PHPExcel_Shared_Escher_DgContainer_SpgrContainer $parent\n\t */\n\tpublic function setParent($parent)\n\t{\n\t\t$this->_parent = $parent;\n\t}\n\n\t/**\n\t * Get the parent Shape Group Container if any\n\t *\n\t * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer|null\n\t */\n\tpublic function getParent()\n\t{\n\t\treturn $this->_parent;\n\t}\n\n\t/**\n\t * Add a child. This will be either spgrContainer or spContainer\n\t *\n\t * @param mixed $child\n\t */\n\tpublic function addChild($child)\n\t{\n\t\t$this->_children[] = $child;\n\t\t$child->setParent($this);\n\t}\n\n\t/**\n\t * Get collection of Shape Containers\n\t */\n\tpublic function getChildren()\n\t{\n\t\treturn $this->_children;\n\t}\n\n\t/**\n\t * Recursively get all spContainers within this spgrContainer\n\t *\n\t * @return PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer[]\n\t */\n\tpublic function getAllSpContainers()\n\t{\n\t\t$allSpContainers = array();\n\n\t\tforeach ($this->_children as $child) {\n\t\t\tif ($child instanceof PHPExcel_Shared_Escher_DgContainer_SpgrContainer) {\n\t\t\t\t$allSpContainers = array_merge($allSpContainers, $child->getAllSpContainers());\n\t\t\t} else {\n\t\t\t\t$allSpContainers[] = $child;\n\t\t\t}\n\t\t}\n\n\t\treturn $allSpContainers;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/Escher/DgContainer.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Shared_Escher_DgContainer\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_Escher_DgContainer\n{\n\t/**\n\t * Drawing index, 1-based.\n\t *\n\t * @var int\n\t */\n\tprivate $_dgId;\n\n\t/**\n\t * Last shape index in this drawing\n\t *\n\t * @var int\n\t */\n\tprivate $_lastSpId;\n\n\tprivate $_spgrContainer = null;\n\n\tpublic function getDgId()\n\t{\n\t\treturn $this->_dgId;\n\t}\n\n\tpublic function setDgId($value)\n\t{\n\t\t$this->_dgId = $value;\n\t}\n\n\tpublic function getLastSpId()\n\t{\n\t\treturn $this->_lastSpId;\n\t}\n\n\tpublic function setLastSpId($value)\n\t{\n\t\t$this->_lastSpId = $value;\n\t}\n\n\tpublic function getSpgrContainer()\n\t{\n\t\treturn $this->_spgrContainer;\n\t}\n\n\tpublic function setSpgrContainer($spgrContainer)\n\t{\n\t\treturn $this->_spgrContainer = $spgrContainer;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE/Blip.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip\n{\n\t/**\n\t * The parent BSE\n\t *\n\t * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE\n\t */\n\tprivate $_parent;\n\n\t/**\n\t * Raw image data\n\t *\n\t * @var string\n\t */\n\tprivate $_data;\n\n\t/**\n\t * Get the raw image data\n\t *\n\t * @return string\n\t */\n\tpublic function getData()\n\t{\n\t\treturn $this->_data;\n\t}\n\n\t/**\n\t * Set the raw image data\n\t *\n\t * @param string\n\t */\n\tpublic function setData($data)\n\t{\n\t\t$this->_data = $data;\n\t}\n\n\t/**\n\t * Set parent BSE\n\t *\n\t * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $parent\n\t */\n\tpublic function setParent($parent)\n\t{\n\t\t$this->_parent = $parent;\n\t}\n\n\t/**\n\t * Get parent BSE\n\t *\n\t * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $parent\n\t */\n\tpublic function getParent()\n\t{\n\t\treturn $this->_parent;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer/BSE.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE\n{\n\tconst BLIPTYPE_ERROR\t= 0x00;\n\tconst BLIPTYPE_UNKNOWN\t= 0x01;\n\tconst BLIPTYPE_EMF\t\t= 0x02;\n\tconst BLIPTYPE_WMF\t\t= 0x03;\n\tconst BLIPTYPE_PICT\t\t= 0x04;\n\tconst BLIPTYPE_JPEG\t\t= 0x05;\n\tconst BLIPTYPE_PNG\t\t= 0x06;\n\tconst BLIPTYPE_DIB\t\t= 0x07;\n\tconst BLIPTYPE_TIFF\t\t= 0x11;\n\tconst BLIPTYPE_CMYKJPEG\t= 0x12;\n\n\t/**\n\t * The parent BLIP Store Entry Container\n\t *\n\t * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer\n\t */\n\tprivate $_parent;\n\n\t/**\n\t * The BLIP (Big Large Image or Picture)\n\t *\n\t * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip\n\t */\n\tprivate $_blip;\n\n\t/**\n\t * The BLIP type\n\t *\n\t * @var int\n\t */\n\tprivate $_blipType;\n\n\t/**\n\t * Set parent BLIP Store Entry Container\n\t *\n\t * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer $parent\n\t */\n\tpublic function setParent($parent)\n\t{\n\t\t$this->_parent = $parent;\n\t}\n\n\t/**\n\t * Get the BLIP\n\t *\n\t * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip\n\t */\n\tpublic function getBlip()\n\t{\n\t\treturn $this->_blip;\n\t}\n\n\t/**\n\t * Set the BLIP\n\t *\n\t * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip $blip\n\t */\n\tpublic function setBlip($blip)\n\t{\n\t\t$this->_blip = $blip;\n\t\t$blip->setParent($this);\n\t}\n\n\t/**\n\t * Get the BLIP type\n\t *\n\t * @return int\n\t */\n\tpublic function getBlipType()\n\t{\n\t\treturn $this->_blipType;\n\t}\n\n\t/**\n\t * Set the BLIP type\n\t *\n\t * @param int\n\t */\n\tpublic function setBlipType($blipType)\n\t{\n\t\t$this->_blipType = $blipType;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/Escher/DggContainer/BstoreContainer.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Shared_Escher_DggContainer_BstoreContainer\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_Escher_DggContainer_BstoreContainer\n{\n\t/**\n\t * BLIP Store Entries. Each of them holds one BLIP (Big Large Image or Picture)\n\t *\n\t * @var array\n\t */\n\tprivate $_BSECollection = array();\n\n\t/**\n\t * Add a BLIP Store Entry\n\t *\n\t * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE $BSE\n\t */\n\tpublic function addBSE($BSE)\n\t{\n\t\t$this->_BSECollection[] = $BSE;\n\t\t$BSE->setParent($this);\n\t}\n\n\t/**\n\t * Get the collection of BLIP Store Entries\n\t *\n\t * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE[]\n\t */\n\tpublic function getBSECollection()\n\t{\n\t\treturn $this->_BSECollection;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/Escher/DggContainer.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Shared_Escher_DggContainer\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_Escher_DggContainer\n{\n\t/**\n\t * Maximum shape index of all shapes in all drawings increased by one\n\t *\n\t * @var int\n\t */\n\tprivate $_spIdMax;\n\n\t/**\n\t * Total number of drawings saved\n\t *\n\t * @var int\n\t */\n\tprivate $_cDgSaved;\n\n\t/**\n\t * Total number of shapes saved (including group shapes)\n\t *\n\t * @var int\n\t */\n\tprivate $_cSpSaved;\n\n\t/**\n\t * BLIP Store Container\n\t *\n\t * @var PHPExcel_Shared_Escher_DggContainer_BstoreContainer\n\t */\n\tprivate $_bstoreContainer;\n\n\t/**\n\t * Array of options for the drawing group\n\t *\n\t * @var array\n\t */\n\tprivate $_OPT = array();\n\n\t/**\n\t * Array of identifier clusters containg information about the maximum shape identifiers\n\t *\n\t * @var array\n\t */\n\tprivate $_IDCLs = array();\n\n\t/**\n\t * Get maximum shape index of all shapes in all drawings (plus one)\n\t *\n\t * @return int\n\t */\n\tpublic function getSpIdMax()\n\t{\n\t\treturn $this->_spIdMax;\n\t}\n\n\t/**\n\t * Set maximum shape index of all shapes in all drawings (plus one)\n\t *\n\t * @param int\n\t */\n\tpublic function setSpIdMax($value)\n\t{\n\t\t$this->_spIdMax = $value;\n\t}\n\n\t/**\n\t * Get total number of drawings saved\n\t *\n\t * @return int\n\t */\n\tpublic function getCDgSaved()\n\t{\n\t\treturn $this->_cDgSaved;\n\t}\n\n\t/**\n\t * Set total number of drawings saved\n\t *\n\t * @param int\n\t */\n\tpublic function setCDgSaved($value)\n\t{\n\t\t$this->_cDgSaved = $value;\n\t}\n\n\t/**\n\t * Get total number of shapes saved (including group shapes)\n\t *\n\t * @return int\n\t */\n\tpublic function getCSpSaved()\n\t{\n\t\treturn $this->_cSpSaved;\n\t}\n\n\t/**\n\t * Set total number of shapes saved (including group shapes)\n\t *\n\t * @param int\n\t */\n\tpublic function setCSpSaved($value)\n\t{\n\t\t$this->_cSpSaved = $value;\n\t}\n\n\t/**\n\t * Get BLIP Store Container\n\t *\n\t * @return PHPExcel_Shared_Escher_DggContainer_BstoreContainer\n\t */\n\tpublic function getBstoreContainer()\n\t{\n\t\treturn $this->_bstoreContainer;\n\t}\n\n\t/**\n\t * Set BLIP Store Container\n\t *\n\t * @param PHPExcel_Shared_Escher_DggContainer_BstoreContainer $bstoreContainer\n\t */\n\tpublic function setBstoreContainer($bstoreContainer)\n\t{\n\t\t$this->_bstoreContainer = $bstoreContainer;\n\t}\n\n\t/**\n\t * Set an option for the drawing group\n\t *\n\t * @param int $property The number specifies the option\n\t * @param mixed $value\n\t */\n\tpublic function setOPT($property, $value)\n\t{\n\t\t$this->_OPT[$property] = $value;\n\t}\n\n\t/**\n\t * Get an option for the drawing group\n\t *\n\t * @param int $property The number specifies the option\n\t * @return mixed\n\t */\n\tpublic function getOPT($property)\n\t{\n\t\tif (isset($this->_OPT[$property])) {\n\t\t\treturn $this->_OPT[$property];\n\t\t}\n\t\treturn null;\n\t}\n\n\t/**\n\t * Get identifier clusters\n\t *\n\t * @return array\n\t */\n\tpublic function getIDCLs()\n\t{\n\t\treturn $this->_IDCLs;\n\t}\n\n\t/**\n\t * Set identifier clusters. array(<drawingId> => <max shape id>, ...)\n\t *\n\t * @param array $pValue\n\t */\n\tpublic function setIDCLs($pValue)\n\t{\n\t\t$this->_IDCLs = $pValue;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/Escher.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Shared_Escher\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Escher\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_Escher\n{\n\t/**\n\t * Drawing Group Container\n\t *\n\t * @var PHPExcel_Shared_Escher_DggContainer\n\t */\n\tprivate $_dggContainer;\n\n\t/**\n\t * Drawing Container\n\t *\n\t * @var PHPExcel_Shared_Escher_DgContainer\n\t */\n\tprivate $_dgContainer;\n\n\t/**\n\t * Get Drawing Group Container\n\t *\n\t * @return PHPExcel_Shared_Escher_DgContainer\n\t */\n\tpublic function getDggContainer()\n\t{\n\t\treturn $this->_dggContainer;\n\t}\n\n\t/**\n\t * Set Drawing Group Container\n\t *\n\t * @param PHPExcel_Shared_Escher_DggContainer $dggContainer\n\t */\n\tpublic function setDggContainer($dggContainer)\n\t{\n\t\treturn $this->_dggContainer = $dggContainer;\n\t}\n\n\t/**\n\t * Get Drawing Container\n\t *\n\t * @return PHPExcel_Shared_Escher_DgContainer\n\t */\n\tpublic function getDgContainer()\n\t{\n\t\treturn $this->_dgContainer;\n\t}\n\n\t/**\n\t * Set Drawing Container\n\t *\n\t * @param PHPExcel_Shared_Escher_DgContainer $dgContainer\n\t */\n\tpublic function setDgContainer($dgContainer)\n\t{\n\t\treturn $this->_dgContainer = $dgContainer;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/Excel5.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Shared_Excel5\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_Excel5\n{\n\t/**\n\t * Get the width of a column in pixels. We use the relationship y = ceil(7x) where\n\t * x is the width in intrinsic Excel units (measuring width in number of normal characters)\n\t * This holds for Arial 10\n\t *\n\t * @param PHPExcel_Worksheet $sheet The sheet\n\t * @param string $col The column\n\t * @return integer The width in pixels\n\t*/\n\tpublic static function sizeCol($sheet, $col = 'A')\n\t{\n\t\t// default font of the workbook\n\t\t$font = $sheet->getParent()->getDefaultStyle()->getFont();\n\n\t\t$columnDimensions = $sheet->getColumnDimensions();\n\n\t\t// first find the true column width in pixels (uncollapsed and unhidden)\n\t\tif ( isset($columnDimensions[$col]) and $columnDimensions[$col]->getWidth() != -1 ) {\n\n\t\t\t// then we have column dimension with explicit width\n\t\t\t$columnDimension = $columnDimensions[$col];\n\t\t\t$width = $columnDimension->getWidth();\n\t\t\t$pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font);\n\n\t\t} else if ($sheet->getDefaultColumnDimension()->getWidth() != -1) {\n\n\t\t\t// then we have default column dimension with explicit width\n\t\t\t$defaultColumnDimension = $sheet->getDefaultColumnDimension();\n\t\t\t$width = $defaultColumnDimension->getWidth();\n\t\t\t$pixelWidth = PHPExcel_Shared_Drawing::cellDimensionToPixels($width, $font);\n\n\t\t} else {\n\n\t\t\t// we don't even have any default column dimension. Width depends on default font\n\t\t\t$pixelWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($font, true);\n\t\t}\n\n\t\t// now find the effective column width in pixels\n\t\tif (isset($columnDimensions[$col]) and !$columnDimensions[$col]->getVisible()) {\n\t\t\t$effectivePixelWidth = 0;\n\t\t} else {\n\t\t\t$effectivePixelWidth = $pixelWidth;\n\t\t}\n\n\t\treturn $effectivePixelWidth;\n\t}\n\n\t/**\n\t * Convert the height of a cell from user's units to pixels. By interpolation\n\t * the relationship is: y = 4/3x. If the height hasn't been set by the user we\n\t * use the default value. If the row is hidden we use a value of zero.\n\t *\n\t * @param PHPExcel_Worksheet $sheet The sheet\n\t * @param integer $row The row index (1-based)\n\t * @return integer The width in pixels\n\t */\n\tpublic static function sizeRow($sheet, $row = 1)\n\t{\n\t\t// default font of the workbook\n\t\t$font = $sheet->getParent()->getDefaultStyle()->getFont();\n\n\t\t$rowDimensions = $sheet->getRowDimensions();\n\n\t\t// first find the true row height in pixels (uncollapsed and unhidden)\n\t\tif ( isset($rowDimensions[$row]) and $rowDimensions[$row]->getRowHeight() != -1) {\n\n\t\t\t// then we have a row dimension\n\t\t\t$rowDimension = $rowDimensions[$row];\n\t\t\t$rowHeight = $rowDimension->getRowHeight();\n\t\t\t$pixelRowHeight = (int) ceil(4 * $rowHeight / 3); // here we assume Arial 10\n\n\t\t} else if ($sheet->getDefaultRowDimension()->getRowHeight() != -1) {\n\n\t\t\t// then we have a default row dimension with explicit height\n\t\t\t$defaultRowDimension = $sheet->getDefaultRowDimension();\n\t\t\t$rowHeight = $defaultRowDimension->getRowHeight();\n\t\t\t$pixelRowHeight = PHPExcel_Shared_Drawing::pointsToPixels($rowHeight);\n\n\t\t} else {\n\n\t\t\t// we don't even have any default row dimension. Height depends on default font\n\t\t\t$pointRowHeight = PHPExcel_Shared_Font::getDefaultRowHeightByFont($font);\n\t\t\t$pixelRowHeight = PHPExcel_Shared_Font::fontSizeToPixels($pointRowHeight);\n\n\t\t}\n\n\t\t// now find the effective row height in pixels\n\t\tif ( isset($rowDimensions[$row]) and !$rowDimensions[$row]->getVisible() ) {\n\t\t\t$effectivePixelRowHeight = 0;\n\t\t} else {\n\t\t\t$effectivePixelRowHeight = $pixelRowHeight;\n\t\t}\n\n\t\treturn $effectivePixelRowHeight;\n\t}\n\n\t/**\n\t * Get the horizontal distance in pixels between two anchors\n\t * The distanceX is found as sum of all the spanning columns widths minus correction for the two offsets\n\t *\n\t * @param PHPExcel_Worksheet $sheet\n\t * @param string $startColumn\n\t * @param integer $startOffsetX Offset within start cell measured in 1/1024 of the cell width\n\t * @param string $endColumn\n\t * @param integer $endOffsetX Offset within end cell measured in 1/1024 of the cell width\n\t * @return integer Horizontal measured in pixels\n\t */\n\tpublic static function getDistanceX(PHPExcel_Worksheet $sheet, $startColumn = 'A', $startOffsetX = 0, $endColumn = 'A', $endOffsetX = 0)\n\t{\n\t\t$distanceX = 0;\n\n\t\t// add the widths of the spanning columns\n\t\t$startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1; // 1-based\n\t\t$endColumnIndex = PHPExcel_Cell::columnIndexFromString($endColumn) - 1; // 1-based\n\t\tfor ($i = $startColumnIndex; $i <= $endColumnIndex; ++$i) {\n\t\t\t$distanceX += self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($i));\n\t\t}\n\n\t\t// correct for offsetX in startcell\n\t\t$distanceX -= (int) floor(self::sizeCol($sheet, $startColumn) * $startOffsetX / 1024);\n\n\t\t// correct for offsetX in endcell\n\t\t$distanceX -= (int) floor(self::sizeCol($sheet, $endColumn) * (1 - $endOffsetX / 1024));\n\n\t\treturn $distanceX;\n\t}\n\n\t/**\n\t * Get the vertical distance in pixels between two anchors\n\t * The distanceY is found as sum of all the spanning rows minus two offsets\n\t *\n\t * @param PHPExcel_Worksheet $sheet\n\t * @param integer $startRow (1-based)\n\t * @param integer $startOffsetY Offset within start cell measured in 1/256 of the cell height\n\t * @param integer $endRow (1-based)\n\t * @param integer $endOffsetY Offset within end cell measured in 1/256 of the cell height\n\t * @return integer Vertical distance measured in pixels\n\t */\n\tpublic static function getDistanceY(PHPExcel_Worksheet $sheet, $startRow = 1, $startOffsetY = 0, $endRow = 1, $endOffsetY = 0)\n\t{\n\t\t$distanceY = 0;\n\n\t\t// add the widths of the spanning rows\n\t\tfor ($row = $startRow; $row <= $endRow; ++$row) {\n\t\t\t$distanceY += self::sizeRow($sheet, $row);\n\t\t}\n\n\t\t// correct for offsetX in startcell\n\t\t$distanceY -= (int) floor(self::sizeRow($sheet, $startRow) * $startOffsetY / 256);\n\n\t\t// correct for offsetX in endcell\n\t\t$distanceY -= (int) floor(self::sizeRow($sheet, $endRow) * (1 - $endOffsetY / 256));\n\n\t\treturn $distanceY;\n\t}\n\n\t/**\n\t * Convert 1-cell anchor coordinates to 2-cell anchor coordinates\n\t * This function is ported from PEAR Spreadsheet_Writer_Excel with small modifications\n\t *\n\t * Calculate the vertices that define the position of the image as required by\n\t * the OBJ record.\n\t *\n\t *\t\t +------------+------------+\n\t *\t\t |\t A\t  |\t  B\t |\n\t *   +-----+------------+------------+\n\t *   |\t |(x1,y1)\t |\t\t\t|\n\t *   |  1  |(A1)._______|______\t  |\n\t *   |\t |\t|\t\t\t  |\t |\n\t *   |\t |\t|\t\t\t  |\t |\n\t *   +-----+----|\tBITMAP\t|-----+\n\t *   |\t |\t|\t\t\t  |\t |\n\t *   |  2  |\t|______________.\t |\n\t *   |\t |\t\t\t|\t\t(B2)|\n\t *   |\t |\t\t\t|\t (x2,y2)|\n\t *   +---- +------------+------------+\n\t *\n\t * Example of a bitmap that covers some of the area from cell A1 to cell B2.\n\t *\n\t * Based on the width and height of the bitmap we need to calculate 8 vars:\n\t *\t $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2.\n\t * The width and height of the cells are also variable and have to be taken into\n\t * account.\n\t * The values of $col_start and $row_start are passed in from the calling\n\t * function. The values of $col_end and $row_end are calculated by subtracting\n\t * the width and height of the bitmap from the width and height of the\n\t * underlying cells.\n\t * The vertices are expressed as a percentage of the underlying cell width as\n\t * follows (rhs values are in pixels):\n\t *\n\t *\t   x1 = X / W *1024\n\t *\t   y1 = Y / H *256\n\t *\t   x2 = (X-1) / W *1024\n\t *\t   y2 = (Y-1) / H *256\n\t *\n\t *\t   Where:  X is distance from the left side of the underlying cell\n\t *\t\t\t   Y is distance from the top of the underlying cell\n\t *\t\t\t   W is the width of the cell\n\t *\t\t\t   H is the height of the cell\n\t *\n\t * @param PHPExcel_Worksheet $sheet\n\t * @param string $coordinates E.g. 'A1'\n\t * @param integer $offsetX Horizontal offset in pixels\n\t * @param integer $offsetY Vertical offset in pixels\n\t * @param integer $width Width in pixels\n\t * @param integer $height Height in pixels\n\t * @return array\n\t */\n\tpublic static function oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height)\n\t{\n\t\tlist($column, $row) = PHPExcel_Cell::coordinateFromString($coordinates);\n\t\t$col_start = PHPExcel_Cell::columnIndexFromString($column) - 1;\n\t\t$row_start = $row - 1;\n\n\t\t$x1 = $offsetX;\n\t\t$y1 = $offsetY;\n\n\t\t// Initialise end cell to the same as the start cell\n\t\t$col_end\t= $col_start;  // Col containing lower right corner of object\n\t\t$row_end\t= $row_start;  // Row containing bottom right corner of object\n\n\t\t// Zero the specified offset if greater than the cell dimensions\n\t\tif ($x1 >= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) {\n\t\t\t$x1 = 0;\n\t\t}\n\t\tif ($y1 >= self::sizeRow($sheet, $row_start + 1)) {\n\t\t\t$y1 = 0;\n\t\t}\n\n\t\t$width\t  = $width  + $x1 -1;\n\t\t$height\t = $height + $y1 -1;\n\n\t\t// Subtract the underlying cell widths to find the end cell of the image\n\t\twhile ($width >= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) {\n\t\t\t$width -= self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end));\n\t\t\t++$col_end;\n\t\t}\n\n\t\t// Subtract the underlying cell heights to find the end cell of the image\n\t\twhile ($height >= self::sizeRow($sheet, $row_end + 1)) {\n\t\t\t$height -= self::sizeRow($sheet, $row_end + 1);\n\t\t\t++$row_end;\n\t\t}\n\n\t\t// Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell\n\t\t// with zero height or width.\n\t\tif (self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) {\n\t\t\treturn;\n\t\t}\n\t\tif (self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end))   == 0) {\n\t\t\treturn;\n\t\t}\n\t\tif (self::sizeRow($sheet, $row_start + 1) == 0) {\n\t\t\treturn;\n\t\t}\n\t\tif (self::sizeRow($sheet, $row_end + 1)   == 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Convert the pixel values to the percentage value expected by Excel\n\t\t$x1 = $x1\t / self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_start))   * 1024;\n\t\t$y1 = $y1\t / self::sizeRow($sheet, $row_start + 1)   *  256;\n\t\t$x2 = ($width + 1)  / self::sizeCol($sheet, PHPExcel_Cell::stringFromColumnIndex($col_end))\t * 1024; // Distance to right side of object\n\t\t$y2 = ($height + 1) / self::sizeRow($sheet, $row_end + 1)\t *  256; // Distance to bottom of object\n\n\t\t$startCoordinates = PHPExcel_Cell::stringFromColumnIndex($col_start) . ($row_start + 1);\n\t\t$endCoordinates = PHPExcel_Cell::stringFromColumnIndex($col_end) . ($row_end + 1);\n\n\t\t$twoAnchor = array(\n\t\t\t'startCoordinates' => $startCoordinates,\n\t\t\t'startOffsetX' => $x1,\n\t\t\t'startOffsetY' => $y1,\n\t\t\t'endCoordinates' => $endCoordinates,\n\t\t\t'endOffsetX' => $x2,\n\t\t\t'endOffsetY' => $y2,\n\t\t);\n\n\t\treturn  $twoAnchor;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/File.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Shared_File\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_File\n{\n\t/*\n\t * Use Temp or File Upload Temp for temporary files\n\t *\n\t * @protected\n\t * @var\tboolean\n\t */\n\tprotected static $_useUploadTempDirectory\t= FALSE;\n\n\n\t/**\n\t * Set the flag indicating whether the File Upload Temp directory should be used for temporary files\n\t *\n\t * @param\t boolean\t$useUploadTempDir\t\tUse File Upload Temporary directory (true or false)\n\t */\n\tpublic static function setUseUploadTempDirectory($useUploadTempDir = FALSE) {\n\t\tself::$_useUploadTempDirectory = (boolean) $useUploadTempDir;\n\t}\t//\tfunction setUseUploadTempDirectory()\n\n\n\t/**\n\t * Get the flag indicating whether the File Upload Temp directory should be used for temporary files\n\t *\n\t * @return\t boolean\tUse File Upload Temporary directory (true or false)\n\t */\n\tpublic static function getUseUploadTempDirectory() {\n\t\treturn self::$_useUploadTempDirectory;\n\t}\t//\tfunction getUseUploadTempDirectory()\n\n\n\t/**\n\t  * Verify if a file exists\n\t  *\n\t  * @param \tstring\t$pFilename\tFilename\n\t  * @return bool\n\t  */\n\tpublic static function file_exists($pFilename) {\n\t\t// Sick construction, but it seems that\n\t\t// file_exists returns strange values when\n\t\t// doing the original file_exists on ZIP archives...\n\t\tif ( strtolower(substr($pFilename, 0, 3)) == 'zip' ) {\n\t\t\t// Open ZIP file and verify if the file exists\n\t\t\t$zipFile \t\t= substr($pFilename, 6, strpos($pFilename, '#') - 6);\n\t\t\t$archiveFile \t= substr($pFilename, strpos($pFilename, '#') + 1);\n\n\t\t\t$zip = new ZipArchive();\n\t\t\tif ($zip->open($zipFile) === true) {\n\t\t\t\t$returnValue = ($zip->getFromName($archiveFile) !== false);\n\t\t\t\t$zip->close();\n\t\t\t\treturn $returnValue;\n\t\t\t} else {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t} else {\n\t\t\t// Regular file_exists\n\t\t\treturn file_exists($pFilename);\n\t\t}\n\t}\n\n\t/**\n\t * Returns canonicalized absolute pathname, also for ZIP archives\n\t *\n\t * @param string $pFilename\n\t * @return string\n\t */\n\tpublic static function realpath($pFilename) {\n\t\t// Returnvalue\n\t\t$returnValue = '';\n\n\t\t// Try using realpath()\n\t\tif (file_exists($pFilename)) {\n\t\t\t$returnValue = realpath($pFilename);\n\t\t}\n\n\t\t// Found something?\n\t\tif ($returnValue == '' || ($returnValue === NULL)) {\n\t\t\t$pathArray = explode('/' , $pFilename);\n\t\t\twhile(in_array('..', $pathArray) && $pathArray[0] != '..') {\n\t\t\t\tfor ($i = 0; $i < count($pathArray); ++$i) {\n\t\t\t\t\tif ($pathArray[$i] == '..' && $i > 0) {\n\t\t\t\t\t\tunset($pathArray[$i]);\n\t\t\t\t\t\tunset($pathArray[$i - 1]);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t$returnValue = implode('/', $pathArray);\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\n\n\t/**\n\t * Get the systems temporary directory.\n\t *\n\t * @return string\n\t */\n\tpublic static function sys_get_temp_dir()\n\t{\n\t\tif (self::$_useUploadTempDirectory) {\n\t\t\t//  use upload-directory when defined to allow running on environments having very restricted\n\t\t\t//      open_basedir configs\n\t\t\tif (ini_get('upload_tmp_dir') !== FALSE) {\n\t\t\t\tif ($temp = ini_get('upload_tmp_dir')) {\n\t\t\t\t\tif (file_exists($temp))\n\t\t\t\t\t\treturn realpath($temp);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// sys_get_temp_dir is only available since PHP 5.2.1\n\t\t// http://php.net/manual/en/function.sys-get-temp-dir.php#94119\n\t\tif ( !function_exists('sys_get_temp_dir')) {\n\t\t\tif ($temp = getenv('TMP') ) {\n\t\t\t\tif ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); }\n\t\t\t}\n\t\t\tif ($temp = getenv('TEMP') ) {\n\t\t\t\tif ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); }\n\t\t\t}\n\t\t\tif ($temp = getenv('TMPDIR') ) {\n\t\t\t\tif ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); }\n\t\t\t}\n\n\t\t\t// trick for creating a file in system's temporary dir\n\t\t\t// without knowing the path of the system's temporary dir\n\t\t\t$temp = tempnam(__FILE__, '');\n\t\t\tif (file_exists($temp)) {\n\t\t\t\tunlink($temp);\n\t\t\t\treturn realpath(dirname($temp));\n\t\t\t}\n\n\t\t\treturn null;\n\t\t}\n\n\t\t// use ordinary built-in PHP function\n\t\t//\tThere should be no problem with the 5.2.4 Suhosin realpath() bug, because this line should only\n\t\t//\t\tbe called if we're running 5.2.1 or earlier\n\t\treturn realpath(sys_get_temp_dir());\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/Font.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Shared_Font\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_Font\n{\n\t/* Methods for resolving autosize value */\n\tconst AUTOSIZE_METHOD_APPROX\t= 'approx';\n\tconst AUTOSIZE_METHOD_EXACT\t\t= 'exact';\n\n\tprivate static $_autoSizeMethods = array(\n\t\tself::AUTOSIZE_METHOD_APPROX,\n\t\tself::AUTOSIZE_METHOD_EXACT,\n\t);\n\n\t/** Character set codes used by BIFF5-8 in Font records */\n\tconst CHARSET_ANSI_LATIN\t\t\t\t= 0x00;\n\tconst CHARSET_SYSTEM_DEFAULT\t\t\t= 0x01;\n\tconst CHARSET_SYMBOL\t\t\t\t\t= 0x02;\n\tconst CHARSET_APPLE_ROMAN\t\t\t\t= 0x4D;\n\tconst CHARSET_ANSI_JAPANESE_SHIFTJIS\t= 0x80;\n\tconst CHARSET_ANSI_KOREAN_HANGUL\t\t= 0x81;\n\tconst CHARSET_ANSI_KOREAN_JOHAB\t\t\t= 0x82;\n\tconst CHARSET_ANSI_CHINESE_SIMIPLIFIED\t= 0x86;\t\t//\tgb2312\n\tconst CHARSET_ANSI_CHINESE_TRADITIONAL\t= 0x88;\t\t//\tbig5\n\tconst CHARSET_ANSI_GREEK\t\t\t\t= 0xA1;\n\tconst CHARSET_ANSI_TURKISH\t\t\t\t= 0xA2;\n\tconst CHARSET_ANSI_VIETNAMESE\t\t\t= 0xA3;\n\tconst CHARSET_ANSI_HEBREW\t\t\t\t= 0xB1;\n\tconst CHARSET_ANSI_ARABIC\t\t\t\t= 0xB2;\n\tconst CHARSET_ANSI_BALTIC\t\t\t\t= 0xBA;\n\tconst CHARSET_ANSI_CYRILLIC\t\t\t\t= 0xCC;\n\tconst CHARSET_ANSI_THAI\t\t\t\t\t= 0xDD;\n\tconst CHARSET_ANSI_LATIN_II\t\t\t\t= 0xEE;\n\tconst CHARSET_OEM_LATIN_I\t\t\t\t= 0xFF;\n\n\t//  XXX: Constants created!\n\t/** Font filenames */\n\tconst ARIAL\t\t\t\t\t\t\t\t= 'arial.ttf';\n\tconst ARIAL_BOLD\t\t\t\t\t\t= 'arialbd.ttf';\n\tconst ARIAL_ITALIC\t\t\t\t\t\t= 'ariali.ttf';\n\tconst ARIAL_BOLD_ITALIC\t\t\t\t\t= 'arialbi.ttf';\n\n\tconst CALIBRI\t\t\t\t\t\t\t= 'CALIBRI.TTF';\n\tconst CALIBRI_BOLD\t\t\t\t\t\t= 'CALIBRIB.TTF';\n\tconst CALIBRI_ITALIC\t\t\t\t\t= 'CALIBRII.TTF';\n\tconst CALIBRI_BOLD_ITALIC\t\t\t\t= 'CALIBRIZ.TTF';\n\n\tconst COMIC_SANS_MS\t\t\t\t\t\t= 'comic.ttf';\n\tconst COMIC_SANS_MS_BOLD\t\t\t\t= 'comicbd.ttf';\n\n\tconst COURIER_NEW\t\t\t\t\t\t= 'cour.ttf';\n\tconst COURIER_NEW_BOLD\t\t\t\t\t= 'courbd.ttf';\n\tconst COURIER_NEW_ITALIC\t\t\t\t= 'couri.ttf';\n\tconst COURIER_NEW_BOLD_ITALIC\t\t\t= 'courbi.ttf';\n\n\tconst GEORGIA\t\t\t\t\t\t\t= 'georgia.ttf';\n\tconst GEORGIA_BOLD\t\t\t\t\t\t= 'georgiab.ttf';\n\tconst GEORGIA_ITALIC\t\t\t\t\t= 'georgiai.ttf';\n\tconst GEORGIA_BOLD_ITALIC\t\t\t\t= 'georgiaz.ttf';\n\n\tconst IMPACT\t\t\t\t\t\t\t= 'impact.ttf';\n\n\tconst LIBERATION_SANS\t\t\t\t\t= 'LiberationSans-Regular.ttf';\n\tconst LIBERATION_SANS_BOLD\t\t\t\t= 'LiberationSans-Bold.ttf';\n\tconst LIBERATION_SANS_ITALIC\t\t\t= 'LiberationSans-Italic.ttf';\n\tconst LIBERATION_SANS_BOLD_ITALIC\t\t= 'LiberationSans-BoldItalic.ttf';\n\n\tconst LUCIDA_CONSOLE\t\t\t\t\t= 'lucon.ttf';\n\tconst LUCIDA_SANS_UNICODE\t\t\t\t= 'l_10646.ttf';\n\n\tconst MICROSOFT_SANS_SERIF\t\t\t\t= 'micross.ttf';\n\n\tconst PALATINO_LINOTYPE\t\t\t\t\t= 'pala.ttf';\n\tconst PALATINO_LINOTYPE_BOLD\t\t\t= 'palab.ttf';\n\tconst PALATINO_LINOTYPE_ITALIC\t\t\t= 'palai.ttf';\n\tconst PALATINO_LINOTYPE_BOLD_ITALIC\t\t= 'palabi.ttf';\n\n\tconst SYMBOL\t\t\t\t\t\t\t= 'symbol.ttf';\n\n\tconst TAHOMA\t\t\t\t\t\t\t= 'tahoma.ttf';\n\tconst TAHOMA_BOLD\t\t\t\t\t\t= 'tahomabd.ttf';\n\n\tconst TIMES_NEW_ROMAN\t\t\t\t\t= 'times.ttf';\n\tconst TIMES_NEW_ROMAN_BOLD\t\t\t\t= 'timesbd.ttf';\n\tconst TIMES_NEW_ROMAN_ITALIC\t\t\t= 'timesi.ttf';\n\tconst TIMES_NEW_ROMAN_BOLD_ITALIC\t\t= 'timesbi.ttf';\n\n\tconst TREBUCHET_MS\t\t\t\t\t\t= 'trebuc.ttf';\n\tconst TREBUCHET_MS_BOLD\t\t\t\t\t= 'trebucbd.ttf';\n\tconst TREBUCHET_MS_ITALIC\t\t\t\t= 'trebucit.ttf';\n\tconst TREBUCHET_MS_BOLD_ITALIC\t\t\t= 'trebucbi.ttf';\n\n\tconst VERDANA\t\t\t\t\t\t\t= 'verdana.ttf';\n\tconst VERDANA_BOLD\t\t\t\t\t\t= 'verdanab.ttf';\n\tconst VERDANA_ITALIC\t\t\t\t\t= 'verdanai.ttf';\n\tconst VERDANA_BOLD_ITALIC\t\t\t\t= 'verdanaz.ttf';\n\n\t/**\n\t * AutoSize method\n\t *\n\t * @var string\n\t */\n\tprivate static $autoSizeMethod = self::AUTOSIZE_METHOD_APPROX;\n\n\t/**\n\t * Path to folder containing TrueType font .ttf files\n\t *\n\t * @var string\n\t */\n\tprivate static $trueTypeFontPath = null;\n\n\t/**\n\t * How wide is a default column for a given default font and size?\n\t * Empirical data found by inspecting real Excel files and reading off the pixel width\n\t * in Microsoft Office Excel 2007.\n\t *\n\t * @var array\n\t */\n\tpublic static $defaultColumnWidths = array(\n\t\t'Arial' => array(\n\t\t\t 1 => array('px' => 24, 'width' => 12.00000000),\n\t\t\t 2 => array('px' => 24, 'width' => 12.00000000),\n\t\t\t 3 => array('px' => 32, 'width' => 10.66406250),\n\t\t\t 4 => array('px' => 32, 'width' => 10.66406250),\n\t\t\t 5 => array('px' => 40, 'width' => 10.00000000),\n\t\t\t 6 => array('px' => 48, 'width' =>  9.59765625),\n\t\t\t 7 => array('px' => 48, 'width' =>  9.59765625),\n\t\t\t 8 => array('px' => 56, 'width' =>  9.33203125),\n\t\t\t 9 => array('px' => 64, 'width' =>  9.14062500),\n\t\t\t10 => array('px' => 64, 'width' =>  9.14062500),\n\t\t),\n\t\t'Calibri' => array(\n\t\t\t 1 => array('px' => 24, 'width' => 12.00000000),\n\t\t\t 2 => array('px' => 24, 'width' => 12.00000000),\n\t\t\t 3 => array('px' => 32, 'width' => 10.66406250),\n\t\t\t 4 => array('px' => 32, 'width' => 10.66406250),\n\t\t\t 5 => array('px' => 40, 'width' => 10.00000000),\n\t\t\t 6 => array('px' => 48, 'width' =>  9.59765625),\n\t\t\t 7 => array('px' => 48, 'width' =>  9.59765625),\n\t\t\t 8 => array('px' => 56, 'width' =>  9.33203125),\n\t\t\t 9 => array('px' => 56, 'width' =>  9.33203125),\n\t\t\t10 => array('px' => 64, 'width' =>  9.14062500),\n\t\t\t11 => array('px' => 64, 'width' =>  9.14062500),\n\t\t),\n\t\t'Verdana' => array(\n\t\t\t 1 => array('px' => 24, 'width' => 12.00000000),\n\t\t\t 2 => array('px' => 24, 'width' => 12.00000000),\n\t\t\t 3 => array('px' => 32, 'width' => 10.66406250),\n\t\t\t 4 => array('px' => 32, 'width' => 10.66406250),\n\t\t\t 5 => array('px' => 40, 'width' => 10.00000000),\n\t\t\t 6 => array('px' => 48, 'width' =>  9.59765625),\n\t\t\t 7 => array('px' => 48, 'width' =>  9.59765625),\n\t\t\t 8 => array('px' => 64, 'width' =>  9.14062500),\n\t\t\t 9 => array('px' => 72, 'width' =>  9.00000000),\n\t\t\t10 => array('px' => 72, 'width' =>  9.00000000),\n\t\t),\n\t);\n\n\t/**\n\t * Set autoSize method\n\t *\n\t * @param string $pValue\n\t * @return\t boolean\t\t\t\t\tSuccess or failure\n\t */\n\tpublic static function setAutoSizeMethod($pValue = self::AUTOSIZE_METHOD_APPROX)\n\t{\n\t\tif (!in_array($pValue,self::$_autoSizeMethods)) {\n\t\t\treturn FALSE;\n\t\t}\n\t\tself::$autoSizeMethod = $pValue;\n\n\t\treturn TRUE;\n\t}\n\n\t/**\n\t * Get autoSize method\n\t *\n\t * @return string\n\t */\n\tpublic static function getAutoSizeMethod()\n\t{\n\t\treturn self::$autoSizeMethod;\n\t}\n\n\t/**\n\t * Set the path to the folder containing .ttf files. There should be a trailing slash.\n\t * Typical locations on variout some platforms:\n\t *\t<ul>\n\t *\t\t<li>C:/Windows/Fonts/</li>\n\t *\t\t<li>/usr/share/fonts/truetype/</li>\n\t *\t\t<li>~/.fonts/</li>\n\t *\t</ul>\n\t *\n\t * @param string $pValue\n\t */\n\tpublic static function setTrueTypeFontPath($pValue = '')\n\t{\n\t\tself::$trueTypeFontPath = $pValue;\n\t}\n\n\t/**\n\t * Get the path to the folder containing .ttf files.\n\t *\n\t * @return string\n\t */\n\tpublic static function getTrueTypeFontPath()\n\t{\n\t\treturn self::$trueTypeFontPath;\n\t}\n\n    /**\n\t * Calculate an (approximate) OpenXML column width, based on font size and text contained\n\t *\n\t * @param \tPHPExcel_Style_Font\t\t\t$font\t\t\tFont object\n\t * @param \tPHPExcel_RichText|string\t$cellText\t\tText to calculate width\n\t * @param \tinteger\t\t\t\t\t\t$rotation\t\tRotation angle\n\t * @param \tPHPExcel_Style_Font|NULL\t$defaultFont\tFont object\n\t * @return \tinteger\t\tColumn width\n\t */\n\tpublic static function calculateColumnWidth(PHPExcel_Style_Font $font, $cellText = '', $rotation = 0, PHPExcel_Style_Font $defaultFont = null) {\n\t\t// If it is rich text, use plain text\n\t\tif ($cellText instanceof PHPExcel_RichText) {\n\t\t\t$cellText = $cellText->getPlainText();\n\t\t}\n\n\t\t// Special case if there are one or more newline characters (\"\\n\")\n\t\tif (strpos($cellText, \"\\n\") !== false) {\n\t\t\t$lineTexts = explode(\"\\n\", $cellText);\n\t\t\t$lineWidths = array();\n\t\t\tforeach ($lineTexts as $lineText) {\n\t\t\t\t$lineWidths[] = self::calculateColumnWidth($font, $lineText, $rotation = 0, $defaultFont);\n\t\t\t}\n\t\t\treturn max($lineWidths); // width of longest line in cell\n\t\t}\n\n\t\t// Try to get the exact text width in pixels\n        $approximate = self::$autoSizeMethod == self::AUTOSIZE_METHOD_APPROX;\n        if (!$approximate) {\n            $columnWidthAdjust = ceil(self::getTextWidthPixelsExact('n', $font, 0) * 1.07);\n            try {\n                // Width of text in pixels excl. padding\n                // and addition because Excel adds some padding, just use approx width of 'n' glyph\n                $columnWidth = self::getTextWidthPixelsExact($cellText, $font, $rotation) + $columnWidthAdjust;\n            } catch (PHPExcel_Exception $e) {\n                $approximate = true;\n            }\n        }\n\n        if ($approximate) {\n            $columnWidthAdjust = self::getTextWidthPixelsApprox('n', $font, 0);\n\t\t\t// Width of text in pixels excl. padding, approximation\n\t\t\t// and addition because Excel adds some padding, just use approx width of 'n' glyph\n\t\t\t$columnWidth = self::getTextWidthPixelsApprox($cellText, $font, $rotation) + $columnWidthAdjust;\n        }\n\n\t\t// Convert from pixel width to column width\n\t\t$columnWidth = PHPExcel_Shared_Drawing::pixelsToCellDimension($columnWidth, $defaultFont);\n\n\t\t// Return\n\t\treturn round($columnWidth, 6);\n\t}\n\n\t/**\n\t * Get GD text width in pixels for a string of text in a certain font at a certain rotation angle\n\t *\n\t * @param string $text\n\t * @param PHPExcel_Style_Font\n\t * @param int $rotation\n\t * @return int\n\t * @throws PHPExcel_Exception\n\t */\n\tpublic static function getTextWidthPixelsExact($text, PHPExcel_Style_Font $font, $rotation = 0) {\n\t\tif (!function_exists('imagettfbbox')) {\n\t\t\tthrow new PHPExcel_Exception('GD library needs to be enabled');\n\t\t}\n\n\t\t// font size should really be supplied in pixels in GD2,\n\t\t// but since GD2 seems to assume 72dpi, pixels and points are the same\n\t\t$fontFile = self::getTrueTypeFontFileFromFont($font);\n\t\t$textBox = imagettfbbox($font->getSize(), $rotation, $fontFile, $text);\n\n\t\t// Get corners positions\n\t\t$lowerLeftCornerX  = $textBox[0];\n//\t\t$lowerLeftCornerY  = $textBox[1];\n\t\t$lowerRightCornerX = $textBox[2];\n//\t\t$lowerRightCornerY = $textBox[3];\n\t\t$upperRightCornerX = $textBox[4];\n//\t\t$upperRightCornerY = $textBox[5];\n\t\t$upperLeftCornerX  = $textBox[6];\n//\t\t$upperLeftCornerY  = $textBox[7];\n\n\t\t// Consider the rotation when calculating the width\n\t\t$textWidth = max($lowerRightCornerX - $upperLeftCornerX, $upperRightCornerX - $lowerLeftCornerX);\n\n\t\treturn $textWidth;\n\t}\n\n\t/**\n\t * Get approximate width in pixels for a string of text in a certain font at a certain rotation angle\n\t *\n\t * @param string $columnText\n\t * @param PHPExcel_Style_Font $font\n\t * @param int $rotation\n\t * @return int Text width in pixels (no padding added)\n\t */\n\tpublic static function getTextWidthPixelsApprox($columnText, PHPExcel_Style_Font $font = null, $rotation = 0)\n\t{\n\t\t$fontName = $font->getName();\n\t\t$fontSize = $font->getSize();\n\n\t\t// Calculate column width in pixels. We assume fixed glyph width. Result varies with font name and size.\n\t\tswitch ($fontName) {\n\t\t\tcase 'Calibri':\n\t\t\t\t// value 8.26 was found via interpolation by inspecting real Excel files with Calibri 11 font.\n\t\t\t\t$columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText));\n\t\t\t\t$columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size\n\t\t\t\tbreak;\n\n\t\t\tcase 'Arial':\n\t\t\t\t// value 7 was found via interpolation by inspecting real Excel files with Arial 10 font.\n//\t\t\t\t$columnWidth = (int) (7 * PHPExcel_Shared_String::CountCharacters($columnText));\n                // value 8 was set because of experience in different exports at Arial 10 font.\n\t\t\t\t$columnWidth = (int) (8 * PHPExcel_Shared_String::CountCharacters($columnText));\n\t\t\t\t$columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size\n                break;\n\n\t\t\tcase 'Verdana':\n\t\t\t\t// value 8 was found via interpolation by inspecting real Excel files with Verdana 10 font.\n\t\t\t\t$columnWidth = (int) (8 * PHPExcel_Shared_String::CountCharacters($columnText));\n\t\t\t\t$columnWidth = $columnWidth * $fontSize / 10; // extrapolate from font size\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// just assume Calibri\n\t\t\t\t$columnWidth = (int) (8.26 * PHPExcel_Shared_String::CountCharacters($columnText));\n\t\t\t\t$columnWidth = $columnWidth * $fontSize / 11; // extrapolate from font size\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Calculate approximate rotated column width\n\t\tif ($rotation !== 0) {\n\t\t\tif ($rotation == -165) {\n\t\t\t\t// stacked text\n\t\t\t\t$columnWidth = 4; // approximation\n\t\t\t} else {\n\t\t\t\t// rotated text\n\t\t\t\t$columnWidth = $columnWidth * cos(deg2rad($rotation))\n\t\t\t\t\t\t\t\t+ $fontSize * abs(sin(deg2rad($rotation))) / 5; // approximation\n\t\t\t}\n\t\t}\n\n\t\t// pixel width is an integer\n\t\treturn (int) $columnWidth;\n\t}\n\n\t/**\n\t * Calculate an (approximate) pixel size, based on a font points size\n\t *\n\t * @param \tint\t\t$fontSizeInPoints\tFont size (in points)\n\t * @return \tint\t\tFont size (in pixels)\n\t */\n\tpublic static function fontSizeToPixels($fontSizeInPoints = 11) {\n\t\treturn (int) ((4 / 3) * $fontSizeInPoints);\n\t}\n\n\t/**\n\t * Calculate an (approximate) pixel size, based on inch size\n\t *\n\t * @param \tint\t\t$sizeInInch\tFont size (in inch)\n\t * @return \tint\t\tSize (in pixels)\n\t */\n\tpublic static function inchSizeToPixels($sizeInInch = 1) {\n\t\treturn ($sizeInInch * 96);\n\t}\n\n\t/**\n\t * Calculate an (approximate) pixel size, based on centimeter size\n\t *\n\t * @param \tint\t\t$sizeInCm\tFont size (in centimeters)\n\t * @return \tint\t\tSize (in pixels)\n\t */\n\tpublic static function centimeterSizeToPixels($sizeInCm = 1) {\n\t\treturn ($sizeInCm * 37.795275591);\n\t}\n\n\t/**\n\t * Returns the font path given the font\n\t *\n\t * @param PHPExcel_Style_Font\n\t * @return string Path to TrueType font file\n\t */\n\tpublic static function getTrueTypeFontFileFromFont($font) {\n\t\tif (!file_exists(self::$trueTypeFontPath) || !is_dir(self::$trueTypeFontPath)) {\n\t\t\tthrow new PHPExcel_Exception('Valid directory to TrueType Font files not specified');\n\t\t}\n\n\t\t$name\t\t= $font->getName();\n\t\t$bold\t\t= $font->getBold();\n\t\t$italic\t\t= $font->getItalic();\n\n\t\t// Check if we can map font to true type font file\n\t\tswitch ($name) {\n\t\t\tcase 'Arial':\n\t\t\t\t$fontFile = (\n\t\t\t\t\t$bold ? ($italic ? self::ARIAL_BOLD_ITALIC : self::ARIAL_BOLD)\n\t\t\t\t\t\t  : ($italic ? self::ARIAL_ITALIC : self::ARIAL)\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Calibri':\n\t\t\t\t$fontFile = (\n\t\t\t\t\t$bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD)\n\t\t\t\t\t\t  : ($italic ? self::CALIBRI_ITALIC : self::CALIBRI)\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Courier New':\n\t\t\t\t$fontFile = (\n\t\t\t\t\t$bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD)\n\t\t\t\t\t\t  : ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW)\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Comic Sans MS':\n\t\t\t\t$fontFile = (\n\t\t\t\t\t$bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Georgia':\n\t\t\t\t$fontFile = (\n\t\t\t\t\t$bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD)\n\t\t\t\t\t\t  : ($italic ? self::GEORGIA_ITALIC : self::GEORGIA)\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Impact':\n\t\t\t\t$fontFile = self::IMPACT;\n\t\t\t\tbreak;\n\n\t\t\tcase 'Liberation Sans':\n\t\t\t\t$fontFile = (\n\t\t\t\t\t$bold ? ($italic ? self::LIBERATION_SANS_BOLD_ITALIC : self::LIBERATION_SANS_BOLD)\n\t\t\t\t\t\t  : ($italic ? self::LIBERATION_SANS_ITALIC : self::LIBERATION_SANS)\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Lucida Console':\n\t\t\t\t$fontFile = self::LUCIDA_CONSOLE;\n\t\t\t\tbreak;\n\n\t\t\tcase 'Lucida Sans Unicode':\n\t\t\t\t$fontFile = self::LUCIDA_SANS_UNICODE;\n\t\t\t\tbreak;\n\n\t\t\tcase 'Microsoft Sans Serif':\n\t\t\t\t$fontFile = self::MICROSOFT_SANS_SERIF;\n\t\t\t\tbreak;\n\n\t\t\tcase 'Palatino Linotype':\n\t\t\t\t$fontFile = (\n\t\t\t\t\t$bold ? ($italic ? self::PALATINO_LINOTYPE_BOLD_ITALIC : self::PALATINO_LINOTYPE_BOLD)\n\t\t\t\t\t\t  : ($italic ? self::PALATINO_LINOTYPE_ITALIC : self::PALATINO_LINOTYPE)\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Symbol':\n\t\t\t\t$fontFile = self::SYMBOL;\n\t\t\t\tbreak;\n\n\t\t\tcase 'Tahoma':\n\t\t\t\t$fontFile = (\n\t\t\t\t\t$bold ? self::TAHOMA_BOLD : self::TAHOMA\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Times New Roman':\n\t\t\t\t$fontFile = (\n\t\t\t\t\t$bold ? ($italic ? self::TIMES_NEW_ROMAN_BOLD_ITALIC : self::TIMES_NEW_ROMAN_BOLD)\n\t\t\t\t\t\t  : ($italic ? self::TIMES_NEW_ROMAN_ITALIC : self::TIMES_NEW_ROMAN)\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Trebuchet MS':\n\t\t\t\t$fontFile = (\n\t\t\t\t\t$bold ? ($italic ? self::TREBUCHET_MS_BOLD_ITALIC : self::TREBUCHET_MS_BOLD)\n\t\t\t\t\t\t  : ($italic ? self::TREBUCHET_MS_ITALIC : self::TREBUCHET_MS)\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tcase 'Verdana':\n\t\t\t\t$fontFile = (\n\t\t\t\t\t$bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD)\n\t\t\t\t\t\t  : ($italic ? self::VERDANA_ITALIC : self::VERDANA)\n\t\t\t\t);\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\tthrow new PHPExcel_Exception('Unknown font name \"'. $name .'\". Cannot map to TrueType font file');\n\t\t\t\tbreak;\n\t\t}\n\n\t\t$fontFile = self::$trueTypeFontPath . $fontFile;\n\n\t\t// Check if file actually exists\n\t\tif (!file_exists($fontFile)) {\n\t\t\tthrow New PHPExcel_Exception('TrueType Font file not found');\n\t\t}\n\n\t\treturn $fontFile;\n\t}\n\n\t/**\n\t * Returns the associated charset for the font name.\n\t *\n\t * @param string $name Font name\n\t * @return int Character set code\n\t */\n\tpublic static function getCharsetFromFontName($name)\n\t{\n\t\tswitch ($name) {\n\t\t\t// Add more cases. Check FONT records in real Excel files.\n\t\t\tcase 'EucrosiaUPC':\t\treturn self::CHARSET_ANSI_THAI;\n\t\t\tcase 'Wingdings':\t\treturn self::CHARSET_SYMBOL;\n\t\t\tcase 'Wingdings 2':\t\treturn self::CHARSET_SYMBOL;\n\t\t\tcase 'Wingdings 3':\t\treturn self::CHARSET_SYMBOL;\n\t\t\tdefault:\t\t\t\treturn self::CHARSET_ANSI_LATIN;\n\t\t}\n\t}\n\n\t/**\n\t * Get the effective column width for columns without a column dimension or column with width -1\n\t * For example, for Calibri 11 this is 9.140625 (64 px)\n\t *\n\t * @param PHPExcel_Style_Font $font The workbooks default font\n\t * @param boolean $pPixels true = return column width in pixels, false = return in OOXML units\n\t * @return mixed Column width\n\t */\n\tpublic static function getDefaultColumnWidthByFont(PHPExcel_Style_Font $font, $pPixels = false)\n\t{\n\t\tif (isset(self::$defaultColumnWidths[$font->getName()][$font->getSize()])) {\n\t\t\t// Exact width can be determined\n\t\t\t$columnWidth = $pPixels ?\n\t\t\t\tself::$defaultColumnWidths[$font->getName()][$font->getSize()]['px']\n\t\t\t\t\t: self::$defaultColumnWidths[$font->getName()][$font->getSize()]['width'];\n\n\t\t} else {\n\t\t\t// We don't have data for this particular font and size, use approximation by\n\t\t\t// extrapolating from Calibri 11\n\t\t\t$columnWidth = $pPixels ?\n\t\t\t\tself::$defaultColumnWidths['Calibri'][11]['px']\n\t\t\t\t\t: self::$defaultColumnWidths['Calibri'][11]['width'];\n\t\t\t$columnWidth = $columnWidth * $font->getSize() / 11;\n\n\t\t\t// Round pixels to closest integer\n\t\t\tif ($pPixels) {\n\t\t\t\t$columnWidth = (int) round($columnWidth);\n\t\t\t}\n\t\t}\n\n\t\treturn $columnWidth;\n\t}\n\n\t/**\n\t * Get the effective row height for rows without a row dimension or rows with height -1\n\t * For example, for Calibri 11 this is 15 points\n\t *\n\t * @param PHPExcel_Style_Font $font The workbooks default font\n\t * @return float Row height in points\n\t */\n\tpublic static function getDefaultRowHeightByFont(PHPExcel_Style_Font $font)\n\t{\n\t\tswitch ($font->getName()) {\n\t\t\tcase 'Arial':\n\t\t\t\tswitch ($font->getSize()) {\n\t\t\t\t\tcase 10:\n\t\t\t\t\t\t// inspection of Arial 10 workbook says 12.75pt ~17px\n\t\t\t\t\t\t$rowHeight = 12.75;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 9:\n\t\t\t\t\t\t// inspection of Arial 9 workbook says 12.00pt ~16px\n\t\t\t\t\t\t$rowHeight = 12;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 8:\n\t\t\t\t\t\t// inspection of Arial 8 workbook says 11.25pt ~15px\n\t\t\t\t\t\t$rowHeight = 11.25;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 7:\n\t\t\t\t\t\t// inspection of Arial 7 workbook says 9.00pt ~12px\n\t\t\t\t\t\t$rowHeight = 9;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 6:\n\t\t\t\t\tcase 5:\n\t\t\t\t\t\t// inspection of Arial 5,6 workbook says 8.25pt ~11px\n\t\t\t\t\t\t$rowHeight = 8.25;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\t// inspection of Arial 4 workbook says 6.75pt ~9px\n\t\t\t\t\t\t$rowHeight = 6.75;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\t// inspection of Arial 3 workbook says 6.00pt ~8px\n\t\t\t\t\t\t$rowHeight = 6;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 2:\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\t// inspection of Arial 1,2 workbook says 5.25pt ~7px\n\t\t\t\t\t\t$rowHeight = 5.25;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// use Arial 10 workbook as an approximation, extrapolation\n\t\t\t\t\t\t$rowHeight = 12.75 * $font->getSize() / 10;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'Calibri':\n\t\t\t\tswitch ($font->getSize()) {\n\t\t\t\t\tcase 11:\n\t\t\t\t\t\t// inspection of Calibri 11 workbook says 15.00pt ~20px\n\t\t\t\t\t\t$rowHeight = 15;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 10:\n\t\t\t\t\t\t// inspection of Calibri 10 workbook says 12.75pt ~17px\n\t\t\t\t\t\t$rowHeight = 12.75;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 9:\n\t\t\t\t\t\t// inspection of Calibri 9 workbook says 12.00pt ~16px\n\t\t\t\t\t\t$rowHeight = 12;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 8:\n\t\t\t\t\t\t// inspection of Calibri 8 workbook says 11.25pt ~15px\n\t\t\t\t\t\t$rowHeight = 11.25;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 7:\n\t\t\t\t\t\t// inspection of Calibri 7 workbook says 9.00pt ~12px\n\t\t\t\t\t\t$rowHeight = 9;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 6:\n\t\t\t\t\tcase 5:\n\t\t\t\t\t\t// inspection of Calibri 5,6 workbook says 8.25pt ~11px\n\t\t\t\t\t\t$rowHeight = 8.25;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\t// inspection of Calibri 4 workbook says 6.75pt ~9px\n\t\t\t\t\t\t$rowHeight = 6.75;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\t// inspection of Calibri 3 workbook says 6.00pt ~8px\n\t\t\t\t\t\t$rowHeight = 6.00;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 2:\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\t// inspection of Calibri 1,2 workbook says 5.25pt ~7px\n\t\t\t\t\t\t$rowHeight = 5.25;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// use Calibri 11 workbook as an approximation, extrapolation\n\t\t\t\t\t\t$rowHeight = 15 * $font->getSize() / 11;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tcase 'Verdana':\n\t\t\t\tswitch ($font->getSize()) {\n\t\t\t\t\tcase 10:\n\t\t\t\t\t\t// inspection of Verdana 10 workbook says 12.75pt ~17px\n\t\t\t\t\t\t$rowHeight = 12.75;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 9:\n\t\t\t\t\t\t// inspection of Verdana 9 workbook says 11.25pt ~15px\n\t\t\t\t\t\t$rowHeight = 11.25;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 8:\n\t\t\t\t\t\t// inspection of Verdana 8 workbook says 10.50pt ~14px\n\t\t\t\t\t\t$rowHeight = 10.50;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 7:\n\t\t\t\t\t\t// inspection of Verdana 7 workbook says 9.00pt ~12px\n\t\t\t\t\t\t$rowHeight = 9.00;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 6:\n\t\t\t\t\tcase 5:\n\t\t\t\t\t\t// inspection of Verdana 5,6 workbook says 8.25pt ~11px\n\t\t\t\t\t\t$rowHeight = 8.25;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 4:\n\t\t\t\t\t\t// inspection of Verdana 4 workbook says 6.75pt ~9px\n\t\t\t\t\t\t$rowHeight = 6.75;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 3:\n\t\t\t\t\t\t// inspection of Verdana 3 workbook says 6.00pt ~8px\n\t\t\t\t\t\t$rowHeight = 6;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 2:\n\t\t\t\t\tcase 1:\n\t\t\t\t\t\t// inspection of Verdana 1,2 workbook says 5.25pt ~7px\n\t\t\t\t\t\t$rowHeight = 5.25;\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault:\n\t\t\t\t\t\t// use Verdana 10 workbook as an approximation, extrapolation\n\t\t\t\t\t\t$rowHeight = 12.75 * $font->getSize() / 10;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// just use Calibri as an approximation\n\t\t\t\t$rowHeight = 15 * $font->getSize() / 11;\n\t\t\t\tbreak;\n\t\t}\n\n\t\treturn $rowHeight;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/CHANGELOG.TXT",
    "content": "Mar 1, 2005 11:15 AST by PM\n\n+ For consistency, renamed Math.php to Maths.java, utils to util, \n  tests to test, docs to doc - \n\n+ Removed conditional logic from top of Matrix class.\n\n+ Switched to using hypo function in Maths.php for all php-hypot calls.\n  NOTE TO SELF: Need to make sure that all decompositions have been \n  switched over to using the bundled hypo.\n\nFeb 25, 2005 at 10:00 AST by PM\n\n+ Recommend using simpler Error.php instead of JAMA_Error.php but \n  can be persuaded otherwise.\n\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/CholeskyDecomposition.php",
    "content": "<?php\n/**\n *\t@package JAMA\n *\n *\tCholesky decomposition class\n *\n *\tFor a symmetric, positive definite matrix A, the Cholesky decomposition\n *\tis an lower triangular matrix L so that A = L*L'.\n *\n *\tIf the matrix is not symmetric or positive definite, the constructor\n *\treturns a partial decomposition and sets an internal flag that may\n *\tbe queried by the isSPD() method.\n *\n *\t@author Paul Meagher\n *\t@author Michael Bommarito\n *\t@version 1.2\n */\nclass CholeskyDecomposition {\n\n\t/**\n\t *\tDecomposition storage\n\t *\t@var array\n\t *\t@access private\n\t */\n\tprivate $L = array();\n\n\t/**\n\t *\tMatrix row and column dimension\n\t *\t@var int\n\t *\t@access private\n\t */\n\tprivate $m;\n\n\t/**\n\t *\tSymmetric positive definite flag\n\t *\t@var boolean\n\t *\t@access private\n\t */\n\tprivate $isspd = true;\n\n\n\t/**\n\t *\tCholeskyDecomposition\n\t *\n\t *\tClass constructor - decomposes symmetric positive definite matrix\n\t *\t@param mixed Matrix square symmetric positive definite matrix\n\t */\n\tpublic function __construct($A = null) {\n\t\tif ($A instanceof Matrix) {\n\t\t\t$this->L = $A->getArray();\n\t\t\t$this->m = $A->getRowDimension();\n\n\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\tfor($j = $i; $j < $this->m; ++$j) {\n\t\t\t\t\tfor($sum = $this->L[$i][$j], $k = $i - 1; $k >= 0; --$k) {\n\t\t\t\t\t\t$sum -= $this->L[$i][$k] * $this->L[$j][$k];\n\t\t\t\t\t}\n\t\t\t\t\tif ($i == $j) {\n\t\t\t\t\t\tif ($sum >= 0) {\n\t\t\t\t\t\t\t$this->L[$i][$i] = sqrt($sum);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$this->isspd = false;\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ($this->L[$i][$i] != 0) {\n\t\t\t\t\t\t\t$this->L[$j][$i] = $sum / $this->L[$i][$i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tfor ($k = $i+1; $k < $this->m; ++$k) {\n\t\t\t\t\t$this->L[$i][$k] = 0.0;\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException));\n\t\t}\n\t}\t//\tfunction __construct()\n\n\n\t/**\n\t *\tIs the matrix symmetric and positive definite?\n\t *\n\t *\t@return boolean\n\t */\n\tpublic function isSPD() {\n\t\treturn $this->isspd;\n\t}\t//\tfunction isSPD()\n\n\n\t/**\n\t *\tgetL\n\t *\n\t *\tReturn triangular factor.\n\t *\t@return Matrix Lower triangular matrix\n\t */\n\tpublic function getL() {\n\t\treturn new Matrix($this->L);\n\t}\t//\tfunction getL()\n\n\n\t/**\n\t *\tSolve A*X = B\n\t *\n\t *\t@param $B Row-equal matrix\n\t *\t@return Matrix L * L' * X = B\n\t */\n\tpublic function solve($B = null) {\n\t\tif ($B instanceof Matrix) {\n\t\t\tif ($B->getRowDimension() == $this->m) {\n\t\t\t\tif ($this->isspd) {\n\t\t\t\t\t$X  = $B->getArrayCopy();\n\t\t\t\t\t$nx = $B->getColumnDimension();\n\n\t\t\t\t\tfor ($k = 0; $k < $this->m; ++$k) {\n\t\t\t\t\t\tfor ($i = $k + 1; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\tfor ($j = 0; $j < $nx; ++$j) {\n\t\t\t\t\t\t\t\t$X[$i][$j] -= $X[$k][$j] * $this->L[$i][$k];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor ($j = 0; $j < $nx; ++$j) {\n\t\t\t\t\t\t\t$X[$k][$j] /= $this->L[$k][$k];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tfor ($k = $this->m - 1; $k >= 0; --$k) {\n\t\t\t\t\t\tfor ($j = 0; $j < $nx; ++$j) {\n\t\t\t\t\t\t\t$X[$k][$j] /= $this->L[$k][$k];\n\t\t\t\t\t\t}\n\t\t\t\t\t\tfor ($i = 0; $i < $k; ++$i) {\n\t\t\t\t\t\t\tfor ($j = 0; $j < $nx; ++$j) {\n\t\t\t\t\t\t\t\t$X[$i][$j] -= $X[$k][$j] * $this->L[$k][$i];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\treturn new Matrix($X, $this->m, $nx);\n\t\t\t\t} else {\n\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(JAMAError(MatrixSPDException));\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tthrow new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionException));\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException));\n\t\t}\n\t}\t//\tfunction solve()\n\n}\t//\tclass CholeskyDecomposition\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/EigenvalueDecomposition.php",
    "content": "<?php\n/**\n *\t@package JAMA\n *\n *\tClass to obtain eigenvalues and eigenvectors of a real matrix.\n *\n *\tIf A is symmetric, then A = V*D*V' where the eigenvalue matrix D\n *\tis diagonal and the eigenvector matrix V is orthogonal (i.e.\n *\tA = V.times(D.times(V.transpose())) and V.times(V.transpose())\n *\tequals the identity matrix).\n *\n *\tIf A is not symmetric, then the eigenvalue matrix D is block diagonal\n *\twith the real eigenvalues in 1-by-1 blocks and any complex eigenvalues,\n *\tlambda + i*mu, in 2-by-2 blocks, [lambda, mu; -mu, lambda].  The\n *\tcolumns of V represent the eigenvectors in the sense that A*V = V*D,\n *\ti.e. A.times(V) equals V.times(D).  The matrix V may be badly\n *\tconditioned, or even singular, so the validity of the equation\n *\tA = V*D*inverse(V) depends upon V.cond().\n *\n *\t@author  Paul Meagher\n *\t@license PHP v3.0\n *\t@version 1.1\n */\nclass EigenvalueDecomposition {\n\n\t/**\n\t *\tRow and column dimension (square matrix).\n\t *\t@var int\n\t */\n\tprivate $n;\n\n\t/**\n\t *\tInternal symmetry flag.\n\t *\t@var int\n\t */\n\tprivate $issymmetric;\n\n\t/**\n\t *\tArrays for internal storage of eigenvalues.\n\t *\t@var array\n\t */\n\tprivate $d = array();\n\tprivate $e = array();\n\n\t/**\n\t *\tArray for internal storage of eigenvectors.\n\t *\t@var array\n\t */\n\tprivate $V = array();\n\n\t/**\n\t*\tArray for internal storage of nonsymmetric Hessenberg form.\n\t*\t@var array\n\t*/\n\tprivate $H = array();\n\n\t/**\n\t*\tWorking storage for nonsymmetric algorithm.\n\t*\t@var array\n\t*/\n\tprivate $ort;\n\n\t/**\n\t*\tUsed for complex scalar division.\n\t*\t@var float\n\t*/\n\tprivate $cdivr;\n\tprivate $cdivi;\n\n\n\t/**\n\t *\tSymmetric Householder reduction to tridiagonal form.\n\t *\n\t *\t@access private\n\t */\n\tprivate function tred2 () {\n\t\t//  This is derived from the Algol procedures tred2 by\n\t\t//  Bowdler, Martin, Reinsch, and Wilkinson, Handbook for\n\t\t//  Auto. Comp., Vol.ii-Linear Algebra, and the corresponding\n\t\t//  Fortran subroutine in EISPACK.\n\t\t$this->d = $this->V[$this->n-1];\n\t\t// Householder reduction to tridiagonal form.\n\t\tfor ($i = $this->n-1; $i > 0; --$i) {\n\t\t\t$i_ = $i -1;\n\t\t\t// Scale to avoid under/overflow.\n\t\t\t$h = $scale = 0.0;\n\t\t\t$scale += array_sum(array_map(abs, $this->d));\n\t\t\tif ($scale == 0.0) {\n\t\t\t\t$this->e[$i] = $this->d[$i_];\n\t\t\t\t$this->d = array_slice($this->V[$i_], 0, $i_);\n\t\t\t\tfor ($j = 0; $j < $i; ++$j) {\n\t\t\t\t\t$this->V[$j][$i] = $this->V[$i][$j] = 0.0;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// Generate Householder vector.\n\t\t\t\tfor ($k = 0; $k < $i; ++$k) {\n\t\t\t\t\t$this->d[$k] /= $scale;\n\t\t\t\t\t$h += pow($this->d[$k], 2);\n\t\t\t\t}\n\t\t\t\t$f = $this->d[$i_];\n\t\t\t\t$g = sqrt($h);\n\t\t\t\tif ($f > 0) {\n\t\t\t\t\t$g = -$g;\n\t\t\t\t}\n\t\t\t\t$this->e[$i] = $scale * $g;\n\t\t\t\t$h = $h - $f * $g;\n\t\t\t\t$this->d[$i_] = $f - $g;\n\t\t\t\tfor ($j = 0; $j < $i; ++$j) {\n\t\t\t\t\t$this->e[$j] = 0.0;\n\t\t\t\t}\n\t\t\t\t// Apply similarity transformation to remaining columns.\n\t\t\t\tfor ($j = 0; $j < $i; ++$j) {\n\t\t\t\t\t$f = $this->d[$j];\n\t\t\t\t\t$this->V[$j][$i] = $f;\n\t\t\t\t\t$g = $this->e[$j] + $this->V[$j][$j] * $f;\n\t\t\t\t\tfor ($k = $j+1; $k <= $i_; ++$k) {\n\t\t\t\t\t\t$g += $this->V[$k][$j] * $this->d[$k];\n\t\t\t\t\t\t$this->e[$k] += $this->V[$k][$j] * $f;\n\t\t\t\t\t}\n\t\t\t\t\t$this->e[$j] = $g;\n\t\t\t\t}\n\t\t\t\t$f = 0.0;\n\t\t\t\tfor ($j = 0; $j < $i; ++$j) {\n\t\t\t\t\t$this->e[$j] /= $h;\n\t\t\t\t\t$f += $this->e[$j] * $this->d[$j];\n\t\t\t\t}\n\t\t\t\t$hh = $f / (2 * $h);\n\t\t\t\tfor ($j=0; $j < $i; ++$j) {\n\t\t\t\t\t$this->e[$j] -= $hh * $this->d[$j];\n\t\t\t\t}\n\t\t\t\tfor ($j = 0; $j < $i; ++$j) {\n\t\t\t\t\t$f = $this->d[$j];\n\t\t\t\t\t$g = $this->e[$j];\n\t\t\t\t\tfor ($k = $j; $k <= $i_; ++$k) {\n\t\t\t\t\t\t$this->V[$k][$j] -= ($f * $this->e[$k] + $g * $this->d[$k]);\n\t\t\t\t\t}\n\t\t\t\t\t$this->d[$j] = $this->V[$i-1][$j];\n\t\t\t\t\t$this->V[$i][$j] = 0.0;\n\t\t\t\t}\n\t\t\t}\n\t\t\t$this->d[$i] = $h;\n\t\t}\n\n\t\t// Accumulate transformations.\n\t\tfor ($i = 0; $i < $this->n-1; ++$i) {\n\t\t\t$this->V[$this->n-1][$i] = $this->V[$i][$i];\n\t\t\t$this->V[$i][$i] = 1.0;\n\t\t\t$h = $this->d[$i+1];\n\t\t\tif ($h != 0.0) {\n\t\t\t\tfor ($k = 0; $k <= $i; ++$k) {\n\t\t\t\t\t$this->d[$k] = $this->V[$k][$i+1] / $h;\n\t\t\t\t}\n\t\t\t\tfor ($j = 0; $j <= $i; ++$j) {\n\t\t\t\t\t$g = 0.0;\n\t\t\t\t\tfor ($k = 0; $k <= $i; ++$k) {\n\t\t\t\t\t\t$g += $this->V[$k][$i+1] * $this->V[$k][$j];\n\t\t\t\t\t}\n\t\t\t\t\tfor ($k = 0; $k <= $i; ++$k) {\n\t\t\t\t\t\t$this->V[$k][$j] -= $g * $this->d[$k];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\tfor ($k = 0; $k <= $i; ++$k) {\n\t\t\t\t$this->V[$k][$i+1] = 0.0;\n\t\t\t}\n\t\t}\n\n\t\t$this->d = $this->V[$this->n-1];\n\t\t$this->V[$this->n-1] = array_fill(0, $j, 0.0);\n\t\t$this->V[$this->n-1][$this->n-1] = 1.0;\n\t\t$this->e[0] = 0.0;\n\t}\n\n\n\t/**\n\t *\tSymmetric tridiagonal QL algorithm.\n\t *\n\t *\tThis is derived from the Algol procedures tql2, by\n\t *\tBowdler, Martin, Reinsch, and Wilkinson, Handbook for\n\t *\tAuto. Comp., Vol.ii-Linear Algebra, and the corresponding\n\t *\tFortran subroutine in EISPACK.\n\t *\n\t *\t@access private\n\t */\n\tprivate function tql2() {\n\t\tfor ($i = 1; $i < $this->n; ++$i) {\n\t\t\t$this->e[$i-1] = $this->e[$i];\n\t\t}\n\t\t$this->e[$this->n-1] = 0.0;\n\t\t$f = 0.0;\n\t\t$tst1 = 0.0;\n\t\t$eps  = pow(2.0,-52.0);\n\n\t\tfor ($l = 0; $l < $this->n; ++$l) {\n\t\t\t// Find small subdiagonal element\n\t\t\t$tst1 = max($tst1, abs($this->d[$l]) + abs($this->e[$l]));\n\t\t\t$m = $l;\n\t\t\twhile ($m < $this->n) {\n\t\t\t\tif (abs($this->e[$m]) <= $eps * $tst1)\n\t\t\t\t\tbreak;\n\t\t\t\t++$m;\n\t\t\t}\n\t\t\t// If m == l, $this->d[l] is an eigenvalue,\n\t\t\t// otherwise, iterate.\n\t\t\tif ($m > $l) {\n\t\t\t\t$iter = 0;\n\t\t\t\tdo {\n\t\t\t\t\t// Could check iteration count here.\n\t\t\t\t\t$iter += 1;\n\t\t\t\t\t// Compute implicit shift\n\t\t\t\t\t$g = $this->d[$l];\n\t\t\t\t\t$p = ($this->d[$l+1] - $g) / (2.0 * $this->e[$l]);\n\t\t\t\t\t$r = hypo($p, 1.0);\n\t\t\t\t\tif ($p < 0)\n\t\t\t\t\t\t$r *= -1;\n\t\t\t\t\t$this->d[$l] = $this->e[$l] / ($p + $r);\n\t\t\t\t\t$this->d[$l+1] = $this->e[$l] * ($p + $r);\n\t\t\t\t\t$dl1 = $this->d[$l+1];\n\t\t\t\t\t$h = $g - $this->d[$l];\n\t\t\t\t\tfor ($i = $l + 2; $i < $this->n; ++$i)\n\t\t\t\t\t\t$this->d[$i] -= $h;\n\t\t\t\t\t$f += $h;\n\t\t\t\t\t// Implicit QL transformation.\n\t\t\t\t\t$p = $this->d[$m];\n\t\t\t\t\t$c = 1.0;\n\t\t\t\t\t$c2 = $c3 = $c;\n\t\t\t\t\t$el1 = $this->e[$l + 1];\n\t\t\t\t\t$s = $s2 = 0.0;\n\t\t\t\t\tfor ($i = $m-1; $i >= $l; --$i) {\n\t\t\t\t\t\t$c3 = $c2;\n\t\t\t\t\t\t$c2 = $c;\n\t\t\t\t\t\t$s2 = $s;\n\t\t\t\t\t\t$g  = $c * $this->e[$i];\n\t\t\t\t\t\t$h  = $c * $p;\n\t\t\t\t\t\t$r  = hypo($p, $this->e[$i]);\n\t\t\t\t\t\t$this->e[$i+1] = $s * $r;\n\t\t\t\t\t\t$s = $this->e[$i] / $r;\n\t\t\t\t\t\t$c = $p / $r;\n\t\t\t\t\t\t$p = $c * $this->d[$i] - $s * $g;\n\t\t\t\t\t\t$this->d[$i+1] = $h + $s * ($c * $g + $s * $this->d[$i]);\n\t\t\t\t\t\t// Accumulate transformation.\n\t\t\t\t\t\tfor ($k = 0; $k < $this->n; ++$k) {\n\t\t\t\t\t\t\t$h = $this->V[$k][$i+1];\n\t\t\t\t\t\t\t$this->V[$k][$i+1] = $s * $this->V[$k][$i] + $c * $h;\n\t\t\t\t\t\t\t$this->V[$k][$i] = $c * $this->V[$k][$i] - $s * $h;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t$p = -$s * $s2 * $c3 * $el1 * $this->e[$l] / $dl1;\n\t\t\t\t\t$this->e[$l] = $s * $p;\n\t\t\t\t\t$this->d[$l] = $c * $p;\n\t\t\t\t// Check for convergence.\n\t\t\t\t} while (abs($this->e[$l]) > $eps * $tst1);\n\t\t\t}\n\t\t\t$this->d[$l] = $this->d[$l] + $f;\n\t\t\t$this->e[$l] = 0.0;\n\t\t}\n\n\t\t// Sort eigenvalues and corresponding vectors.\n\t\tfor ($i = 0; $i < $this->n - 1; ++$i) {\n\t\t\t$k = $i;\n\t\t\t$p = $this->d[$i];\n\t\t\tfor ($j = $i+1; $j < $this->n; ++$j) {\n\t\t\t\tif ($this->d[$j] < $p) {\n\t\t\t\t\t$k = $j;\n\t\t\t\t\t$p = $this->d[$j];\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ($k != $i) {\n\t\t\t\t$this->d[$k] = $this->d[$i];\n\t\t\t\t$this->d[$i] = $p;\n\t\t\t\tfor ($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t$p = $this->V[$j][$i];\n\t\t\t\t\t$this->V[$j][$i] = $this->V[$j][$k];\n\t\t\t\t\t$this->V[$j][$k] = $p;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\n\t/**\n\t *\tNonsymmetric reduction to Hessenberg form.\n\t *\n\t *\tThis is derived from the Algol procedures orthes and ortran,\n\t *\tby Martin and Wilkinson, Handbook for Auto. Comp.,\n\t *\tVol.ii-Linear Algebra, and the corresponding\n\t *\tFortran subroutines in EISPACK.\n\t *\n\t *\t@access private\n\t */\n\tprivate function orthes () {\n\t\t$low  = 0;\n\t\t$high = $this->n-1;\n\n\t\tfor ($m = $low+1; $m <= $high-1; ++$m) {\n\t\t\t// Scale column.\n\t\t\t$scale = 0.0;\n\t\t\tfor ($i = $m; $i <= $high; ++$i) {\n\t\t\t\t$scale = $scale + abs($this->H[$i][$m-1]);\n\t\t\t}\n\t\t\tif ($scale != 0.0) {\n\t\t\t\t// Compute Householder transformation.\n\t\t\t\t$h = 0.0;\n\t\t\t\tfor ($i = $high; $i >= $m; --$i) {\n\t\t\t\t\t$this->ort[$i] = $this->H[$i][$m-1] / $scale;\n\t\t\t\t\t$h += $this->ort[$i] * $this->ort[$i];\n\t\t\t\t}\n\t\t\t\t$g = sqrt($h);\n\t\t\t\tif ($this->ort[$m] > 0) {\n\t\t\t\t\t$g *= -1;\n\t\t\t\t}\n\t\t\t\t$h -= $this->ort[$m] * $g;\n\t\t\t\t$this->ort[$m] -= $g;\n\t\t\t\t// Apply Householder similarity transformation\n\t\t\t\t// H = (I -u * u' / h) * H * (I -u * u') / h)\n\t\t\t\tfor ($j = $m; $j < $this->n; ++$j) {\n\t\t\t\t\t$f = 0.0;\n\t\t\t\t\tfor ($i = $high; $i >= $m; --$i) {\n\t\t\t\t\t\t$f += $this->ort[$i] * $this->H[$i][$j];\n\t\t\t\t\t}\n\t\t\t\t\t$f /= $h;\n\t\t\t\t\tfor ($i = $m; $i <= $high; ++$i) {\n\t\t\t\t\t\t$this->H[$i][$j] -= $f * $this->ort[$i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor ($i = 0; $i <= $high; ++$i) {\n\t\t\t\t\t$f = 0.0;\n\t\t\t\t\tfor ($j = $high; $j >= $m; --$j) {\n\t\t\t\t\t\t$f += $this->ort[$j] * $this->H[$i][$j];\n\t\t\t\t\t}\n\t\t\t\t\t$f = $f / $h;\n\t\t\t\t\tfor ($j = $m; $j <= $high; ++$j) {\n\t\t\t\t\t\t$this->H[$i][$j] -= $f * $this->ort[$j];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$this->ort[$m] = $scale * $this->ort[$m];\n\t\t\t\t$this->H[$m][$m-1] = $scale * $g;\n\t\t\t}\n\t\t}\n\n\t\t// Accumulate transformations (Algol's ortran).\n\t\tfor ($i = 0; $i < $this->n; ++$i) {\n\t\t\tfor ($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t$this->V[$i][$j] = ($i == $j ? 1.0 : 0.0);\n\t\t\t}\n\t\t}\n\t\tfor ($m = $high-1; $m >= $low+1; --$m) {\n\t\t\tif ($this->H[$m][$m-1] != 0.0) {\n\t\t\t\tfor ($i = $m+1; $i <= $high; ++$i) {\n\t\t\t\t\t$this->ort[$i] = $this->H[$i][$m-1];\n\t\t\t\t}\n\t\t\t\tfor ($j = $m; $j <= $high; ++$j) {\n\t\t\t\t\t$g = 0.0;\n\t\t\t\t\tfor ($i = $m; $i <= $high; ++$i) {\n\t\t\t\t\t\t$g += $this->ort[$i] * $this->V[$i][$j];\n\t\t\t\t\t}\n\t\t\t\t\t// Double division avoids possible underflow\n\t\t\t\t\t$g = ($g / $this->ort[$m]) / $this->H[$m][$m-1];\n\t\t\t\t\tfor ($i = $m; $i <= $high; ++$i) {\n\t\t\t\t\t\t$this->V[$i][$j] += $g * $this->ort[$i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\n\t/**\n\t *\tPerforms complex division.\n\t *\n\t *\t@access private\n\t */\n\tprivate function cdiv($xr, $xi, $yr, $yi) {\n\t\tif (abs($yr) > abs($yi)) {\n\t\t\t$r = $yi / $yr;\n\t\t\t$d = $yr + $r * $yi;\n\t\t\t$this->cdivr = ($xr + $r * $xi) / $d;\n\t\t\t$this->cdivi = ($xi - $r * $xr) / $d;\n\t\t} else {\n\t\t\t$r = $yr / $yi;\n\t\t\t$d = $yi + $r * $yr;\n\t\t\t$this->cdivr = ($r * $xr + $xi) / $d;\n\t\t\t$this->cdivi = ($r * $xi - $xr) / $d;\n\t\t}\n\t}\n\n\n\t/**\n\t *\tNonsymmetric reduction from Hessenberg to real Schur form.\n\t *\n\t *\tCode is derived from the Algol procedure hqr2,\n\t *\tby Martin and Wilkinson, Handbook for Auto. Comp.,\n\t *\tVol.ii-Linear Algebra, and the corresponding\n\t *\tFortran subroutine in EISPACK.\n\t *\n\t *\t@access private\n\t */\n\tprivate function hqr2 () {\n\t\t//  Initialize\n\t\t$nn = $this->n;\n\t\t$n  = $nn - 1;\n\t\t$low = 0;\n\t\t$high = $nn - 1;\n\t\t$eps = pow(2.0, -52.0);\n\t\t$exshift = 0.0;\n\t\t$p = $q = $r = $s = $z = 0;\n\t\t// Store roots isolated by balanc and compute matrix norm\n\t\t$norm = 0.0;\n\n\t\tfor ($i = 0; $i < $nn; ++$i) {\n\t\t\tif (($i < $low) OR ($i > $high)) {\n\t\t\t\t$this->d[$i] = $this->H[$i][$i];\n\t\t\t\t$this->e[$i] = 0.0;\n\t\t\t}\n\t\t\tfor ($j = max($i-1, 0); $j < $nn; ++$j) {\n\t\t\t\t$norm = $norm + abs($this->H[$i][$j]);\n\t\t\t}\n\t\t}\n\n\t\t// Outer loop over eigenvalue index\n\t\t$iter = 0;\n\t\twhile ($n >= $low) {\n\t\t\t// Look for single small sub-diagonal element\n\t\t\t$l = $n;\n\t\t\twhile ($l > $low) {\n\t\t\t\t$s = abs($this->H[$l-1][$l-1]) + abs($this->H[$l][$l]);\n\t\t\t\tif ($s == 0.0) {\n\t\t\t\t\t$s = $norm;\n\t\t\t\t}\n\t\t\t\tif (abs($this->H[$l][$l-1]) < $eps * $s) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\t--$l;\n\t\t\t}\n\t\t\t// Check for convergence\n\t\t\t// One root found\n\t\t\tif ($l == $n) {\n\t\t\t\t$this->H[$n][$n] = $this->H[$n][$n] + $exshift;\n\t\t\t\t$this->d[$n] = $this->H[$n][$n];\n\t\t\t\t$this->e[$n] = 0.0;\n\t\t\t\t--$n;\n\t\t\t\t$iter = 0;\n\t\t\t// Two roots found\n\t\t\t} else if ($l == $n-1) {\n\t\t\t\t$w = $this->H[$n][$n-1] * $this->H[$n-1][$n];\n\t\t\t\t$p = ($this->H[$n-1][$n-1] - $this->H[$n][$n]) / 2.0;\n\t\t\t\t$q = $p * $p + $w;\n\t\t\t\t$z = sqrt(abs($q));\n\t\t\t\t$this->H[$n][$n] = $this->H[$n][$n] + $exshift;\n\t\t\t\t$this->H[$n-1][$n-1] = $this->H[$n-1][$n-1] + $exshift;\n\t\t\t\t$x = $this->H[$n][$n];\n\t\t\t\t// Real pair\n\t\t\t\tif ($q >= 0) {\n\t\t\t\t\tif ($p >= 0) {\n\t\t\t\t\t\t$z = $p + $z;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$z = $p - $z;\n\t\t\t\t\t}\n\t\t\t\t\t$this->d[$n-1] = $x + $z;\n\t\t\t\t\t$this->d[$n] = $this->d[$n-1];\n\t\t\t\t\tif ($z != 0.0) {\n\t\t\t\t\t\t$this->d[$n] = $x - $w / $z;\n\t\t\t\t\t}\n\t\t\t\t\t$this->e[$n-1] = 0.0;\n\t\t\t\t\t$this->e[$n] = 0.0;\n\t\t\t\t\t$x = $this->H[$n][$n-1];\n\t\t\t\t\t$s = abs($x) + abs($z);\n\t\t\t\t\t$p = $x / $s;\n\t\t\t\t\t$q = $z / $s;\n\t\t\t\t\t$r = sqrt($p * $p + $q * $q);\n\t\t\t\t\t$p = $p / $r;\n\t\t\t\t\t$q = $q / $r;\n\t\t\t\t\t// Row modification\n\t\t\t\t\tfor ($j = $n-1; $j < $nn; ++$j) {\n\t\t\t\t\t\t$z = $this->H[$n-1][$j];\n\t\t\t\t\t\t$this->H[$n-1][$j] = $q * $z + $p * $this->H[$n][$j];\n\t\t\t\t\t\t$this->H[$n][$j] = $q * $this->H[$n][$j] - $p * $z;\n\t\t\t\t\t}\n\t\t\t\t\t// Column modification\n\t\t\t\t\tfor ($i = 0; $i <= n; ++$i) {\n\t\t\t\t\t\t$z = $this->H[$i][$n-1];\n\t\t\t\t\t\t$this->H[$i][$n-1] = $q * $z + $p * $this->H[$i][$n];\n\t\t\t\t\t\t$this->H[$i][$n] = $q * $this->H[$i][$n] - $p * $z;\n\t\t\t\t\t}\n\t\t\t\t\t// Accumulate transformations\n\t\t\t\t\tfor ($i = $low; $i <= $high; ++$i) {\n\t\t\t\t\t\t$z = $this->V[$i][$n-1];\n\t\t\t\t\t\t$this->V[$i][$n-1] = $q * $z + $p * $this->V[$i][$n];\n\t\t\t\t\t\t$this->V[$i][$n] = $q * $this->V[$i][$n] - $p * $z;\n\t\t\t\t\t}\n\t\t\t\t// Complex pair\n\t\t\t\t} else {\n\t\t\t\t\t$this->d[$n-1] = $x + $p;\n\t\t\t\t\t$this->d[$n] = $x + $p;\n\t\t\t\t\t$this->e[$n-1] = $z;\n\t\t\t\t\t$this->e[$n] = -$z;\n\t\t\t\t}\n\t\t\t\t$n = $n - 2;\n\t\t\t\t$iter = 0;\n\t\t\t// No convergence yet\n\t\t\t} else {\n\t\t\t\t// Form shift\n\t\t\t\t$x = $this->H[$n][$n];\n\t\t\t\t$y = 0.0;\n\t\t\t\t$w = 0.0;\n\t\t\t\tif ($l < $n) {\n\t\t\t\t\t$y = $this->H[$n-1][$n-1];\n\t\t\t\t\t$w = $this->H[$n][$n-1] * $this->H[$n-1][$n];\n\t\t\t\t}\n\t\t\t\t// Wilkinson's original ad hoc shift\n\t\t\t\tif ($iter == 10) {\n\t\t\t\t\t$exshift += $x;\n\t\t\t\t\tfor ($i = $low; $i <= $n; ++$i) {\n\t\t\t\t\t\t$this->H[$i][$i] -= $x;\n\t\t\t\t\t}\n\t\t\t\t\t$s = abs($this->H[$n][$n-1]) + abs($this->H[$n-1][$n-2]);\n\t\t\t\t\t$x = $y = 0.75 * $s;\n\t\t\t\t\t$w = -0.4375 * $s * $s;\n\t\t\t\t}\n\t\t\t\t// MATLAB's new ad hoc shift\n\t\t\t\tif ($iter == 30) {\n\t\t\t\t\t$s = ($y - $x) / 2.0;\n\t\t\t\t\t$s = $s * $s + $w;\n\t\t\t\t\tif ($s > 0) {\n\t\t\t\t\t\t$s = sqrt($s);\n\t\t\t\t\t\tif ($y < $x) {\n\t\t\t\t\t\t\t$s = -$s;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$s = $x - $w / (($y - $x) / 2.0 + $s);\n\t\t\t\t\t\tfor ($i = $low; $i <= $n; ++$i) {\n\t\t\t\t\t\t\t$this->H[$i][$i] -= $s;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$exshift += $s;\n\t\t\t\t\t\t$x = $y = $w = 0.964;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Could check iteration count here.\n\t\t\t\t$iter = $iter + 1;\n\t\t\t\t// Look for two consecutive small sub-diagonal elements\n\t\t\t\t$m = $n - 2;\n\t\t\t\twhile ($m >= $l) {\n\t\t\t\t\t$z = $this->H[$m][$m];\n\t\t\t\t\t$r = $x - $z;\n\t\t\t\t\t$s = $y - $z;\n\t\t\t\t\t$p = ($r * $s - $w) / $this->H[$m+1][$m] + $this->H[$m][$m+1];\n\t\t\t\t\t$q = $this->H[$m+1][$m+1] - $z - $r - $s;\n\t\t\t\t\t$r = $this->H[$m+2][$m+1];\n\t\t\t\t\t$s = abs($p) + abs($q) + abs($r);\n\t\t\t\t\t$p = $p / $s;\n\t\t\t\t\t$q = $q / $s;\n\t\t\t\t\t$r = $r / $s;\n\t\t\t\t\tif ($m == $l) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tif (abs($this->H[$m][$m-1]) * (abs($q) + abs($r)) <\n\t\t\t\t\t\t$eps * (abs($p) * (abs($this->H[$m-1][$m-1]) + abs($z) + abs($this->H[$m+1][$m+1])))) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\t--$m;\n\t\t\t\t}\n\t\t\t\tfor ($i = $m + 2; $i <= $n; ++$i) {\n\t\t\t\t\t$this->H[$i][$i-2] = 0.0;\n\t\t\t\t\tif ($i > $m+2) {\n\t\t\t\t\t\t$this->H[$i][$i-3] = 0.0;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Double QR step involving rows l:n and columns m:n\n\t\t\t\tfor ($k = $m; $k <= $n-1; ++$k) {\n\t\t\t\t\t$notlast = ($k != $n-1);\n\t\t\t\t\tif ($k != $m) {\n\t\t\t\t\t\t$p = $this->H[$k][$k-1];\n\t\t\t\t\t\t$q = $this->H[$k+1][$k-1];\n\t\t\t\t\t\t$r = ($notlast ? $this->H[$k+2][$k-1] : 0.0);\n\t\t\t\t\t\t$x = abs($p) + abs($q) + abs($r);\n\t\t\t\t\t\tif ($x != 0.0) {\n\t\t\t\t\t\t\t$p = $p / $x;\n\t\t\t\t\t\t\t$q = $q / $x;\n\t\t\t\t\t\t\t$r = $r / $x;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tif ($x == 0.0) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\t$s = sqrt($p * $p + $q * $q + $r * $r);\n\t\t\t\t\tif ($p < 0) {\n\t\t\t\t\t\t$s = -$s;\n\t\t\t\t\t}\n\t\t\t\t\tif ($s != 0) {\n\t\t\t\t\t\tif ($k != $m) {\n\t\t\t\t\t\t\t$this->H[$k][$k-1] = -$s * $x;\n\t\t\t\t\t\t} elseif ($l != $m) {\n\t\t\t\t\t\t\t$this->H[$k][$k-1] = -$this->H[$k][$k-1];\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$p = $p + $s;\n\t\t\t\t\t\t$x = $p / $s;\n\t\t\t\t\t\t$y = $q / $s;\n\t\t\t\t\t\t$z = $r / $s;\n\t\t\t\t\t\t$q = $q / $p;\n\t\t\t\t\t\t$r = $r / $p;\n\t\t\t\t\t\t// Row modification\n\t\t\t\t\t\tfor ($j = $k; $j < $nn; ++$j) {\n\t\t\t\t\t\t\t$p = $this->H[$k][$j] + $q * $this->H[$k+1][$j];\n\t\t\t\t\t\t\tif ($notlast) {\n\t\t\t\t\t\t\t\t$p = $p + $r * $this->H[$k+2][$j];\n\t\t\t\t\t\t\t\t$this->H[$k+2][$j] = $this->H[$k+2][$j] - $p * $z;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$this->H[$k][$j] = $this->H[$k][$j] - $p * $x;\n\t\t\t\t\t\t\t$this->H[$k+1][$j] = $this->H[$k+1][$j] - $p * $y;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Column modification\n\t\t\t\t\t\tfor ($i = 0; $i <= min($n, $k+3); ++$i) {\n\t\t\t\t\t\t\t$p = $x * $this->H[$i][$k] + $y * $this->H[$i][$k+1];\n\t\t\t\t\t\t\tif ($notlast) {\n\t\t\t\t\t\t\t\t$p = $p + $z * $this->H[$i][$k+2];\n\t\t\t\t\t\t\t\t$this->H[$i][$k+2] = $this->H[$i][$k+2] - $p * $r;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$this->H[$i][$k] = $this->H[$i][$k] - $p;\n\t\t\t\t\t\t\t$this->H[$i][$k+1] = $this->H[$i][$k+1] - $p * $q;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Accumulate transformations\n\t\t\t\t\t\tfor ($i = $low; $i <= $high; ++$i) {\n\t\t\t\t\t\t\t$p = $x * $this->V[$i][$k] + $y * $this->V[$i][$k+1];\n\t\t\t\t\t\t\tif ($notlast) {\n\t\t\t\t\t\t\t\t$p = $p + $z * $this->V[$i][$k+2];\n\t\t\t\t\t\t\t\t$this->V[$i][$k+2] = $this->V[$i][$k+2] - $p * $r;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$this->V[$i][$k] = $this->V[$i][$k] - $p;\n\t\t\t\t\t\t\t$this->V[$i][$k+1] = $this->V[$i][$k+1] - $p * $q;\n\t\t\t\t\t\t}\n\t\t\t\t\t}  // ($s != 0)\n\t\t\t\t}  // k loop\n\t\t\t}  // check convergence\n\t\t}  // while ($n >= $low)\n\n\t\t// Backsubstitute to find vectors of upper triangular form\n\t\tif ($norm == 0.0) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor ($n = $nn-1; $n >= 0; --$n) {\n\t\t\t$p = $this->d[$n];\n\t\t\t$q = $this->e[$n];\n\t\t\t// Real vector\n\t\t\tif ($q == 0) {\n\t\t\t\t$l = $n;\n\t\t\t\t$this->H[$n][$n] = 1.0;\n\t\t\t\tfor ($i = $n-1; $i >= 0; --$i) {\n\t\t\t\t\t$w = $this->H[$i][$i] - $p;\n\t\t\t\t\t$r = 0.0;\n\t\t\t\t\tfor ($j = $l; $j <= $n; ++$j) {\n\t\t\t\t\t\t$r = $r + $this->H[$i][$j] * $this->H[$j][$n];\n\t\t\t\t\t}\n\t\t\t\t\tif ($this->e[$i] < 0.0) {\n\t\t\t\t\t\t$z = $w;\n\t\t\t\t\t\t$s = $r;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$l = $i;\n\t\t\t\t\t\tif ($this->e[$i] == 0.0) {\n\t\t\t\t\t\t\tif ($w != 0.0) {\n\t\t\t\t\t\t\t\t$this->H[$i][$n] = -$r / $w;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t$this->H[$i][$n] = -$r / ($eps * $norm);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t// Solve real equations\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$x = $this->H[$i][$i+1];\n\t\t\t\t\t\t\t$y = $this->H[$i+1][$i];\n\t\t\t\t\t\t\t$q = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i];\n\t\t\t\t\t\t\t$t = ($x * $s - $z * $r) / $q;\n\t\t\t\t\t\t\t$this->H[$i][$n] = $t;\n\t\t\t\t\t\t\tif (abs($x) > abs($z)) {\n\t\t\t\t\t\t\t\t$this->H[$i+1][$n] = (-$r - $w * $t) / $x;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t$this->H[$i+1][$n] = (-$s - $y * $t) / $z;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Overflow control\n\t\t\t\t\t\t$t = abs($this->H[$i][$n]);\n\t\t\t\t\t\tif (($eps * $t) * $t > 1) {\n\t\t\t\t\t\t\tfor ($j = $i; $j <= $n; ++$j) {\n\t\t\t\t\t\t\t\t$this->H[$j][$n] = $this->H[$j][$n] / $t;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t// Complex vector\n\t\t\t} else if ($q < 0) {\n\t\t\t\t$l = $n-1;\n\t\t\t\t// Last vector component imaginary so matrix is triangular\n\t\t\t\tif (abs($this->H[$n][$n-1]) > abs($this->H[$n-1][$n])) {\n\t\t\t\t\t$this->H[$n-1][$n-1] = $q / $this->H[$n][$n-1];\n\t\t\t\t\t$this->H[$n-1][$n] = -($this->H[$n][$n] - $p) / $this->H[$n][$n-1];\n\t\t\t\t} else {\n\t\t\t\t\t$this->cdiv(0.0, -$this->H[$n-1][$n], $this->H[$n-1][$n-1] - $p, $q);\n\t\t\t\t\t$this->H[$n-1][$n-1] = $this->cdivr;\n\t\t\t\t\t$this->H[$n-1][$n]   = $this->cdivi;\n\t\t\t\t}\n\t\t\t\t$this->H[$n][$n-1] = 0.0;\n\t\t\t\t$this->H[$n][$n] = 1.0;\n\t\t\t\tfor ($i = $n-2; $i >= 0; --$i) {\n\t\t\t\t\t// double ra,sa,vr,vi;\n\t\t\t\t\t$ra = 0.0;\n\t\t\t\t\t$sa = 0.0;\n\t\t\t\t\tfor ($j = $l; $j <= $n; ++$j) {\n\t\t\t\t\t\t$ra = $ra + $this->H[$i][$j] * $this->H[$j][$n-1];\n\t\t\t\t\t\t$sa = $sa + $this->H[$i][$j] * $this->H[$j][$n];\n\t\t\t\t\t}\n\t\t\t\t\t$w = $this->H[$i][$i] - $p;\n\t\t\t\t\tif ($this->e[$i] < 0.0) {\n\t\t\t\t\t\t$z = $w;\n\t\t\t\t\t\t$r = $ra;\n\t\t\t\t\t\t$s = $sa;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$l = $i;\n\t\t\t\t\t\tif ($this->e[$i] == 0) {\n\t\t\t\t\t\t\t$this->cdiv(-$ra, -$sa, $w, $q);\n\t\t\t\t\t\t\t$this->H[$i][$n-1] = $this->cdivr;\n\t\t\t\t\t\t\t$this->H[$i][$n]   = $this->cdivi;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// Solve complex equations\n\t\t\t\t\t\t\t$x = $this->H[$i][$i+1];\n\t\t\t\t\t\t\t$y = $this->H[$i+1][$i];\n\t\t\t\t\t\t\t$vr = ($this->d[$i] - $p) * ($this->d[$i] - $p) + $this->e[$i] * $this->e[$i] - $q * $q;\n\t\t\t\t\t\t\t$vi = ($this->d[$i] - $p) * 2.0 * $q;\n\t\t\t\t\t\t\tif ($vr == 0.0 & $vi == 0.0) {\n\t\t\t\t\t\t\t\t$vr = $eps * $norm * (abs($w) + abs($q) + abs($x) + abs($y) + abs($z));\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$this->cdiv($x * $r - $z * $ra + $q * $sa, $x * $s - $z * $sa - $q * $ra, $vr, $vi);\n\t\t\t\t\t\t\t$this->H[$i][$n-1] = $this->cdivr;\n\t\t\t\t\t\t\t$this->H[$i][$n]   = $this->cdivi;\n\t\t\t\t\t\t\tif (abs($x) > (abs($z) + abs($q))) {\n\t\t\t\t\t\t\t\t$this->H[$i+1][$n-1] = (-$ra - $w * $this->H[$i][$n-1] + $q * $this->H[$i][$n]) / $x;\n\t\t\t\t\t\t\t\t$this->H[$i+1][$n] = (-$sa - $w * $this->H[$i][$n] - $q * $this->H[$i][$n-1]) / $x;\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t$this->cdiv(-$r - $y * $this->H[$i][$n-1], -$s - $y * $this->H[$i][$n], $z, $q);\n\t\t\t\t\t\t\t\t$this->H[$i+1][$n-1] = $this->cdivr;\n\t\t\t\t\t\t\t\t$this->H[$i+1][$n]   = $this->cdivi;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Overflow control\n\t\t\t\t\t\t$t = max(abs($this->H[$i][$n-1]),abs($this->H[$i][$n]));\n\t\t\t\t\t\tif (($eps * $t) * $t > 1) {\n\t\t\t\t\t\t\tfor ($j = $i; $j <= $n; ++$j) {\n\t\t\t\t\t\t\t\t$this->H[$j][$n-1] = $this->H[$j][$n-1] / $t;\n\t\t\t\t\t\t\t\t$this->H[$j][$n]   = $this->H[$j][$n] / $t;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} // end else\n\t\t\t\t} // end for\n\t\t\t} // end else for complex case\n\t\t} // end for\n\n\t\t// Vectors of isolated roots\n\t\tfor ($i = 0; $i < $nn; ++$i) {\n\t\t\tif ($i < $low | $i > $high) {\n\t\t\t\tfor ($j = $i; $j < $nn; ++$j) {\n\t\t\t\t\t$this->V[$i][$j] = $this->H[$i][$j];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Back transformation to get eigenvectors of original matrix\n\t\tfor ($j = $nn-1; $j >= $low; --$j) {\n\t\t\tfor ($i = $low; $i <= $high; ++$i) {\n\t\t\t\t$z = 0.0;\n\t\t\t\tfor ($k = $low; $k <= min($j,$high); ++$k) {\n\t\t\t\t\t$z = $z + $this->V[$i][$k] * $this->H[$k][$j];\n\t\t\t\t}\n\t\t\t\t$this->V[$i][$j] = $z;\n\t\t\t}\n\t\t}\n\t} // end hqr2\n\n\n\t/**\n\t *\tConstructor: Check for symmetry, then construct the eigenvalue decomposition\n\t *\n\t *\t@access public\n\t *\t@param A  Square matrix\n\t *\t@return Structure to access D and V.\n\t */\n\tpublic function __construct($Arg) {\n\t\t$this->A = $Arg->getArray();\n\t\t$this->n = $Arg->getColumnDimension();\n\n\t\t$issymmetric = true;\n\t\tfor ($j = 0; ($j < $this->n) & $issymmetric; ++$j) {\n\t\t\tfor ($i = 0; ($i < $this->n) & $issymmetric; ++$i) {\n\t\t\t\t$issymmetric = ($this->A[$i][$j] == $this->A[$j][$i]);\n\t\t\t}\n\t\t}\n\n\t\tif ($issymmetric) {\n\t\t\t$this->V = $this->A;\n\t\t\t// Tridiagonalize.\n\t\t\t$this->tred2();\n\t\t\t// Diagonalize.\n\t\t\t$this->tql2();\n\t\t} else {\n\t\t\t$this->H = $this->A;\n\t\t\t$this->ort = array();\n\t\t\t// Reduce to Hessenberg form.\n\t\t\t$this->orthes();\n\t\t\t// Reduce Hessenberg to real Schur form.\n\t\t\t$this->hqr2();\n\t\t}\n\t}\n\n\n\t/**\n\t *\tReturn the eigenvector matrix\n\t *\n\t *\t@access public\n\t *\t@return V\n\t */\n\tpublic function getV() {\n\t\treturn new Matrix($this->V, $this->n, $this->n);\n\t}\n\n\n\t/**\n\t *\tReturn the real parts of the eigenvalues\n\t *\n\t *\t@access public\n\t *\t@return real(diag(D))\n\t */\n\tpublic function getRealEigenvalues() {\n\t\treturn $this->d;\n\t}\n\n\n\t/**\n\t *\tReturn the imaginary parts of the eigenvalues\n\t *\n\t *\t@access public\n\t *\t@return imag(diag(D))\n\t */\n\tpublic function getImagEigenvalues() {\n\t\treturn $this->e;\n\t}\n\n\n\t/**\n\t *\tReturn the block diagonal eigenvalue matrix\n\t *\n\t *\t@access public\n\t *\t@return D\n\t */\n\tpublic function getD() {\n\t\tfor ($i = 0; $i < $this->n; ++$i) {\n\t\t\t$D[$i] = array_fill(0, $this->n, 0.0);\n\t\t\t$D[$i][$i] = $this->d[$i];\n\t\t\tif ($this->e[$i] == 0) {\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\t$o = ($this->e[$i] > 0) ? $i + 1 : $i - 1;\n\t\t\t$D[$i][$o] = $this->e[$i];\n\t\t}\n\t\treturn new Matrix($D);\n\t}\n\n}\t//\tclass EigenvalueDecomposition\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/LUDecomposition.php",
    "content": "<?php\n/**\n *\t@package JAMA\n *\n *\tFor an m-by-n matrix A with m >= n, the LU decomposition is an m-by-n\n *\tunit lower triangular matrix L, an n-by-n upper triangular matrix U,\n *\tand a permutation vector piv of length m so that A(piv,:) = L*U.\n *\tIf m < n, then L is m-by-m and U is m-by-n.\n *\n *\tThe LU decompostion with pivoting always exists, even if the matrix is\n *\tsingular, so the constructor will never fail. The primary use of the\n *\tLU decomposition is in the solution of square systems of simultaneous\n *\tlinear equations. This will fail if isNonsingular() returns false.\n *\n *\t@author Paul Meagher\n *\t@author Bartosz Matosiuk\n *\t@author Michael Bommarito\n *\t@version 1.1\n *\t@license PHP v3.0\n */\nclass PHPExcel_Shared_JAMA_LUDecomposition {\n\n\tconst MatrixSingularException\t= \"Can only perform operation on singular matrix.\";\n\tconst MatrixSquareException\t\t= \"Mismatched Row dimension\";\n\n\t/**\n\t *\tDecomposition storage\n\t *\t@var array\n\t */\n\tprivate $LU = array();\n\n\t/**\n\t *\tRow dimension.\n\t *\t@var int\n\t */\n\tprivate $m;\n\n\t/**\n\t *\tColumn dimension.\n\t *\t@var int\n\t */\n\tprivate $n;\n\n\t/**\n\t *\tPivot sign.\n\t *\t@var int\n\t */\n\tprivate $pivsign;\n\n\t/**\n\t *\tInternal storage of pivot vector.\n\t *\t@var array\n\t */\n\tprivate $piv = array();\n\n\n\t/**\n\t *\tLU Decomposition constructor.\n\t *\n\t *\t@param $A Rectangular matrix\n\t *\t@return Structure to access L, U and piv.\n\t */\n\tpublic function __construct($A) {\n\t\tif ($A instanceof PHPExcel_Shared_JAMA_Matrix) {\n\t\t\t// Use a \"left-looking\", dot-product, Crout/Doolittle algorithm.\n\t\t\t$this->LU = $A->getArray();\n\t\t\t$this->m  = $A->getRowDimension();\n\t\t\t$this->n  = $A->getColumnDimension();\n\t\t\tfor ($i = 0; $i < $this->m; ++$i) {\n\t\t\t\t$this->piv[$i] = $i;\n\t\t\t}\n\t\t\t$this->pivsign = 1;\n\t\t\t$LUrowi = $LUcolj = array();\n\n\t\t\t// Outer loop.\n\t\t\tfor ($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t// Make a copy of the j-th column to localize references.\n\t\t\t\tfor ($i = 0; $i < $this->m; ++$i) {\n\t\t\t\t\t$LUcolj[$i] = &$this->LU[$i][$j];\n\t\t\t\t}\n\t\t\t\t// Apply previous transformations.\n\t\t\t\tfor ($i = 0; $i < $this->m; ++$i) {\n\t\t\t\t\t$LUrowi = $this->LU[$i];\n\t\t\t\t\t// Most of the time is spent in the following dot product.\n\t\t\t\t\t$kmax = min($i,$j);\n\t\t\t\t\t$s = 0.0;\n\t\t\t\t\tfor ($k = 0; $k < $kmax; ++$k) {\n\t\t\t\t\t\t$s += $LUrowi[$k] * $LUcolj[$k];\n\t\t\t\t\t}\n\t\t\t\t\t$LUrowi[$j] = $LUcolj[$i] -= $s;\n\t\t\t\t}\n\t\t\t\t// Find pivot and exchange if necessary.\n\t\t\t\t$p = $j;\n\t\t\t\tfor ($i = $j+1; $i < $this->m; ++$i) {\n\t\t\t\t\tif (abs($LUcolj[$i]) > abs($LUcolj[$p])) {\n\t\t\t\t\t\t$p = $i;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ($p != $j) {\n\t\t\t\t\tfor ($k = 0; $k < $this->n; ++$k) {\n\t\t\t\t\t\t$t = $this->LU[$p][$k];\n\t\t\t\t\t\t$this->LU[$p][$k] = $this->LU[$j][$k];\n\t\t\t\t\t\t$this->LU[$j][$k] = $t;\n\t\t\t\t\t}\n\t\t\t\t\t$k = $this->piv[$p];\n\t\t\t\t\t$this->piv[$p] = $this->piv[$j];\n\t\t\t\t\t$this->piv[$j] = $k;\n\t\t\t\t\t$this->pivsign = $this->pivsign * -1;\n\t\t\t\t}\n\t\t\t\t// Compute multipliers.\n\t\t\t\tif (($j < $this->m) && ($this->LU[$j][$j] != 0.0)) {\n\t\t\t\t\tfor ($i = $j+1; $i < $this->m; ++$i) {\n\t\t\t\t\t\t$this->LU[$i][$j] /= $this->LU[$j][$j];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException);\n\t\t}\n\t}\t//\tfunction __construct()\n\n\n\t/**\n\t *\tGet lower triangular factor.\n\t *\n\t *\t@return array Lower triangular factor\n\t */\n\tpublic function getL() {\n\t\tfor ($i = 0; $i < $this->m; ++$i) {\n\t\t\tfor ($j = 0; $j < $this->n; ++$j) {\n\t\t\t\tif ($i > $j) {\n\t\t\t\t\t$L[$i][$j] = $this->LU[$i][$j];\n\t\t\t\t} elseif ($i == $j) {\n\t\t\t\t\t$L[$i][$j] = 1.0;\n\t\t\t\t} else {\n\t\t\t\t\t$L[$i][$j] = 0.0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn new PHPExcel_Shared_JAMA_Matrix($L);\n\t}\t//\tfunction getL()\n\n\n\t/**\n\t *\tGet upper triangular factor.\n\t *\n\t *\t@return array Upper triangular factor\n\t */\n\tpublic function getU() {\n\t\tfor ($i = 0; $i < $this->n; ++$i) {\n\t\t\tfor ($j = 0; $j < $this->n; ++$j) {\n\t\t\t\tif ($i <= $j) {\n\t\t\t\t\t$U[$i][$j] = $this->LU[$i][$j];\n\t\t\t\t} else {\n\t\t\t\t\t$U[$i][$j] = 0.0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn new PHPExcel_Shared_JAMA_Matrix($U);\n\t}\t//\tfunction getU()\n\n\n\t/**\n\t *\tReturn pivot permutation vector.\n\t *\n\t *\t@return array Pivot vector\n\t */\n\tpublic function getPivot() {\n\t\treturn $this->piv;\n\t}\t//\tfunction getPivot()\n\n\n\t/**\n\t *\tAlias for getPivot\n\t *\n\t *\t@see getPivot\n\t */\n\tpublic function getDoublePivot() {\n\t\treturn $this->getPivot();\n\t}\t//\tfunction getDoublePivot()\n\n\n\t/**\n\t *\tIs the matrix nonsingular?\n\t *\n\t *\t@return true if U, and hence A, is nonsingular.\n\t */\n\tpublic function isNonsingular() {\n\t\tfor ($j = 0; $j < $this->n; ++$j) {\n\t\t\tif ($this->LU[$j][$j] == 0) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\t//\tfunction isNonsingular()\n\n\n\t/**\n\t *\tCount determinants\n\t *\n\t *\t@return array d matrix deterninat\n\t */\n\tpublic function det() {\n\t\tif ($this->m == $this->n) {\n\t\t\t$d = $this->pivsign;\n\t\t\tfor ($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t$d *= $this->LU[$j][$j];\n\t\t\t}\n\t\t\treturn $d;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException);\n\t\t}\n\t}\t//\tfunction det()\n\n\n\t/**\n\t *\tSolve A*X = B\n\t *\n\t *\t@param  $B  A Matrix with as many rows as A and any number of columns.\n\t *\t@return  X so that L*U*X = B(piv,:)\n\t *\t@PHPExcel_Calculation_Exception  IllegalArgumentException Matrix row dimensions must agree.\n\t *\t@PHPExcel_Calculation_Exception  RuntimeException  Matrix is singular.\n\t */\n\tpublic function solve($B) {\n\t\tif ($B->getRowDimension() == $this->m) {\n\t\t\tif ($this->isNonsingular()) {\n\t\t\t\t// Copy right hand side with pivoting\n\t\t\t\t$nx = $B->getColumnDimension();\n\t\t\t\t$X  = $B->getMatrix($this->piv, 0, $nx-1);\n\t\t\t\t// Solve L*Y = B(piv,:)\n\t\t\t\tfor ($k = 0; $k < $this->n; ++$k) {\n\t\t\t\t\tfor ($i = $k+1; $i < $this->n; ++$i) {\n\t\t\t\t\t\tfor ($j = 0; $j < $nx; ++$j) {\n\t\t\t\t\t\t\t$X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Solve U*X = Y;\n\t\t\t\tfor ($k = $this->n-1; $k >= 0; --$k) {\n\t\t\t\t\tfor ($j = 0; $j < $nx; ++$j) {\n\t\t\t\t\t\t$X->A[$k][$j] /= $this->LU[$k][$k];\n\t\t\t\t\t}\n\t\t\t\t\tfor ($i = 0; $i < $k; ++$i) {\n\t\t\t\t\t\tfor ($j = 0; $j < $nx; ++$j) {\n\t\t\t\t\t\t\t$X->A[$i][$j] -= $X->A[$k][$j] * $this->LU[$i][$k];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\treturn $X;\n\t\t\t} else {\n\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::MatrixSingularException);\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::MatrixSquareException);\n\t\t}\n\t}\t//\tfunction solve()\n\n}\t//\tclass PHPExcel_Shared_JAMA_LUDecomposition\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/Matrix.php",
    "content": "<?php\n/**\n * @package JAMA\n */\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n\t/**\n\t * @ignore\n\t */\n\tdefine('PHPEXCEL_ROOT', dirname(__FILE__) . '/../../../');\n\trequire(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\n/*\n *\tMatrix class\n *\n *\t@author Paul Meagher\n *\t@author Michael Bommarito\n *\t@author Lukasz Karapuda\n *\t@author Bartek Matosiuk\n *\t@version 1.8\n *\t@license PHP v3.0\n *\t@see http://math.nist.gov/javanumerics/jama/\n */\nclass PHPExcel_Shared_JAMA_Matrix {\n\n\n\tconst PolymorphicArgumentException\t= \"Invalid argument pattern for polymorphic function.\";\n\tconst ArgumentTypeException\t\t\t= \"Invalid argument type.\";\n\tconst ArgumentBoundsException\t\t= \"Invalid argument range.\";\n\tconst MatrixDimensionException\t\t= \"Matrix dimensions are not equal.\";\n\tconst ArrayLengthException\t\t\t= \"Array length must be a multiple of m.\";\n\n\t/**\n\t *\tMatrix storage\n\t *\n\t *\t@var array\n\t *\t@access public\n\t */\n\tpublic $A = array();\n\n\t/**\n\t *\tMatrix row dimension\n\t *\n\t *\t@var int\n\t *\t@access private\n\t */\n\tprivate $m;\n\n\t/**\n\t *\tMatrix column dimension\n\t *\n\t *\t@var int\n\t *\t@access private\n\t */\n\tprivate $n;\n\n\n\t/**\n\t *\tPolymorphic constructor\n\t *\n\t *\tAs PHP has no support for polymorphic constructors, we hack our own sort of polymorphism using func_num_args, func_get_arg, and gettype. In essence, we're just implementing a simple RTTI filter and calling the appropriate constructor.\n\t */\n\tpublic function __construct() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\t//Rectangular matrix - m x n initialized from 2D array\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$this->m = count($args[0]);\n\t\t\t\t\t\t$this->n = count($args[0][0]);\n\t\t\t\t\t\t$this->A = $args[0];\n\t\t\t\t\t\tbreak;\n\t\t\t\t//Square matrix - n x n\n\t\t\t\tcase 'integer':\n\t\t\t\t\t\t$this->m = $args[0];\n\t\t\t\t\t\t$this->n = $args[0];\n\t\t\t\t\t\t$this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0));\n\t\t\t\t\t\tbreak;\n\t\t\t\t//Rectangular matrix - m x n\n\t\t\t\tcase 'integer,integer':\n\t\t\t\t\t\t$this->m = $args[0];\n\t\t\t\t\t\t$this->n = $args[1];\n\t\t\t\t\t\t$this->A = array_fill(0, $this->m, array_fill(0, $this->n, 0));\n\t\t\t\t\t\tbreak;\n\t\t\t\t//Rectangular matrix - m x n initialized from packed array\n\t\t\t\tcase 'array,integer':\n\t\t\t\t\t\t$this->m = $args[1];\n\t\t\t\t\t\tif ($this->m != 0) {\n\t\t\t\t\t\t\t$this->n = count($args[0]) / $this->m;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$this->n = 0;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (($this->m * $this->n) == count($args[0])) {\n\t\t\t\t\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t\t\t\t\t$this->A[$i][$j] = $args[0][$i + $j * $this->m];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::ArrayLengthException);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction __construct()\n\n\n\t/**\n\t *\tgetArray\n\t *\n\t *\t@return array Matrix array\n\t */\n\tpublic function getArray() {\n\t\treturn $this->A;\n\t}\t//\tfunction getArray()\n\n\n\t/**\n\t *\tgetRowDimension\n\t *\n\t *\t@return int Row dimension\n\t */\n\tpublic function getRowDimension() {\n\t\treturn $this->m;\n\t}\t//\tfunction getRowDimension()\n\n\n\t/**\n\t *\tgetColumnDimension\n\t *\n\t *\t@return int Column dimension\n\t */\n\tpublic function getColumnDimension() {\n\t\treturn $this->n;\n\t}\t//\tfunction getColumnDimension()\n\n\n\t/**\n\t *\tget\n\t *\n\t *\tGet the i,j-th element of the matrix.\n\t *\t@param int $i Row position\n\t *\t@param int $j Column position\n\t *\t@return mixed Element (int/float/double)\n\t */\n\tpublic function get($i = null, $j = null) {\n\t\treturn $this->A[$i][$j];\n\t}\t//\tfunction get()\n\n\n\t/**\n\t *\tgetMatrix\n\t *\n\t *\tGet a submatrix\n\t *\t@param int $i0 Initial row index\n\t *\t@param int $iF Final row index\n\t *\t@param int $j0 Initial column index\n\t *\t@param int $jF Final column index\n\t *\t@return Matrix Submatrix\n\t */\n\tpublic function getMatrix() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\t//A($i0...; $j0...)\n\t\t\t\tcase 'integer,integer':\n\t\t\t\t\t\tlist($i0, $j0) = $args;\n\t\t\t\t\t\tif ($i0 >= 0) { $m = $this->m - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }\n\t\t\t\t\t\tif ($j0 >= 0) { $n = $this->n - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }\n\t\t\t\t\t\t$R = new PHPExcel_Shared_JAMA_Matrix($m, $n);\n\t\t\t\t\t\tfor($i = $i0; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\tfor($j = $j0; $j < $this->n; ++$j) {\n\t\t\t\t\t\t\t\t$R->set($i, $j, $this->A[$i][$j]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn $R;\n\t\t\t\t\t\tbreak;\n\t\t\t\t//A($i0...$iF; $j0...$jF)\n\t\t\t\tcase 'integer,integer,integer,integer':\n\t\t\t\t\t\tlist($i0, $iF, $j0, $jF) = $args;\n\t\t\t\t\t\tif (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }\n\t\t\t\t\t\tif (($jF > $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }\n\t\t\t\t\t\t$R = new PHPExcel_Shared_JAMA_Matrix($m+1, $n+1);\n\t\t\t\t\t\tfor($i = $i0; $i <= $iF; ++$i) {\n\t\t\t\t\t\t\tfor($j = $j0; $j <= $jF; ++$j) {\n\t\t\t\t\t\t\t\t$R->set($i - $i0, $j - $j0, $this->A[$i][$j]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn $R;\n\t\t\t\t\t\tbreak;\n\t\t\t\t//$R = array of row indices; $C = array of column indices\n\t\t\t\tcase 'array,array':\n\t\t\t\t\t\tlist($RL, $CL) = $args;\n\t\t\t\t\t\tif (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }\n\t\t\t\t\t\tif (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }\n\t\t\t\t\t\t$R = new PHPExcel_Shared_JAMA_Matrix($m, $n);\n\t\t\t\t\t\tfor($i = 0; $i < $m; ++$i) {\n\t\t\t\t\t\t\tfor($j = 0; $j < $n; ++$j) {\n\t\t\t\t\t\t\t\t$R->set($i - $i0, $j - $j0, $this->A[$RL[$i]][$CL[$j]]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn $R;\n\t\t\t\t\t\tbreak;\n\t\t\t\t//$RL = array of row indices; $CL = array of column indices\n\t\t\t\tcase 'array,array':\n\t\t\t\t\t\tlist($RL, $CL) = $args;\n\t\t\t\t\t\tif (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }\n\t\t\t\t\t\tif (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }\n\t\t\t\t\t\t$R = new PHPExcel_Shared_JAMA_Matrix($m, $n);\n\t\t\t\t\t\tfor($i = 0; $i < $m; ++$i) {\n\t\t\t\t\t\t\tfor($j = 0; $j < $n; ++$j) {\n\t\t\t\t\t\t\t\t$R->set($i, $j, $this->A[$RL[$i]][$CL[$j]]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn $R;\n\t\t\t\t\t\tbreak;\n\t\t\t\t//A($i0...$iF); $CL = array of column indices\n\t\t\t\tcase 'integer,integer,array':\n\t\t\t\t\t\tlist($i0, $iF, $CL) = $args;\n\t\t\t\t\t\tif (($iF > $i0) && ($this->m >= $iF) && ($i0 >= 0)) { $m = $iF - $i0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }\n\t\t\t\t\t\tif (count($CL) > 0) { $n = count($CL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }\n\t\t\t\t\t\t$R = new PHPExcel_Shared_JAMA_Matrix($m, $n);\n\t\t\t\t\t\tfor($i = $i0; $i < $iF; ++$i) {\n\t\t\t\t\t\t\tfor($j = 0; $j < $n; ++$j) {\n\t\t\t\t\t\t\t\t$R->set($i - $i0, $j, $this->A[$RL[$i]][$j]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn $R;\n\t\t\t\t\t\tbreak;\n\t\t\t\t//$RL = array of row indices\n\t\t\t\tcase 'array,integer,integer':\n\t\t\t\t\t\tlist($RL, $j0, $jF) = $args;\n\t\t\t\t\t\tif (count($RL) > 0) { $m = count($RL); } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }\n\t\t\t\t\t\tif (($jF >= $j0) && ($this->n >= $jF) && ($j0 >= 0)) { $n = $jF - $j0; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentBoundsException); }\n\t\t\t\t\t\t$R = new PHPExcel_Shared_JAMA_Matrix($m, $n+1);\n\t\t\t\t\t\tfor($i = 0; $i < $m; ++$i) {\n\t\t\t\t\t\t\tfor($j = $j0; $j <= $jF; ++$j) {\n\t\t\t\t\t\t\t\t$R->set($i, $j - $j0, $this->A[$RL[$i]][$j]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn $R;\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction getMatrix()\n\n\n\t/**\n\t *\tcheckMatrixDimensions\n\t *\n\t *\tIs matrix B the same size?\n\t *\t@param Matrix $B Matrix B\n\t *\t@return boolean\n\t */\n\tpublic function checkMatrixDimensions($B = null) {\n\t\tif ($B instanceof PHPExcel_Shared_JAMA_Matrix) {\n\t\t\tif (($this->m == $B->getRowDimension()) && ($this->n == $B->getColumnDimension())) {\n\t\t\t\treturn true;\n\t\t\t} else {\n\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::MatrixDimensionException);\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::ArgumentTypeException);\n\t\t}\n\t}\t//\tfunction checkMatrixDimensions()\n\n\n\n\t/**\n\t *\tset\n\t *\n\t *\tSet the i,j-th element of the matrix.\n\t *\t@param int $i Row position\n\t *\t@param int $j Column position\n\t *\t@param mixed $c Int/float/double value\n\t *\t@return mixed Element (int/float/double)\n\t */\n\tpublic function set($i = null, $j = null, $c = null) {\n\t\t// Optimized set version just has this\n\t\t$this->A[$i][$j] = $c;\n\t}\t//\tfunction set()\n\n\n\t/**\n\t *\tidentity\n\t *\n\t *\tGenerate an identity matrix.\n\t *\t@param int $m Row dimension\n\t *\t@param int $n Column dimension\n\t *\t@return Matrix Identity matrix\n\t */\n\tpublic function identity($m = null, $n = null) {\n\t\treturn $this->diagonal($m, $n, 1);\n\t}\t//\tfunction identity()\n\n\n\t/**\n\t *\tdiagonal\n\t *\n\t *\tGenerate a diagonal matrix\n\t *\t@param int $m Row dimension\n\t *\t@param int $n Column dimension\n\t *\t@param mixed $c Diagonal value\n\t *\t@return Matrix Diagonal matrix\n\t */\n\tpublic function diagonal($m = null, $n = null, $c = 1) {\n\t\t$R = new PHPExcel_Shared_JAMA_Matrix($m, $n);\n\t\tfor($i = 0; $i < $m; ++$i) {\n\t\t\t$R->set($i, $i, $c);\n\t\t}\n\t\treturn $R;\n\t}\t//\tfunction diagonal()\n\n\n\t/**\n\t *\tgetMatrixByRow\n\t *\n\t *\tGet a submatrix by row index/range\n\t *\t@param int $i0 Initial row index\n\t *\t@param int $iF Final row index\n\t *\t@return Matrix Submatrix\n\t */\n\tpublic function getMatrixByRow($i0 = null, $iF = null) {\n\t\tif (is_int($i0)) {\n\t\t\tif (is_int($iF)) {\n\t\t\t\treturn $this->getMatrix($i0, 0, $iF + 1, $this->n);\n\t\t\t} else {\n\t\t\t\treturn $this->getMatrix($i0, 0, $i0 + 1, $this->n);\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::ArgumentTypeException);\n\t\t}\n\t}\t//\tfunction getMatrixByRow()\n\n\n\t/**\n\t *\tgetMatrixByCol\n\t *\n\t *\tGet a submatrix by column index/range\n\t *\t@param int $i0 Initial column index\n\t *\t@param int $iF Final column index\n\t *\t@return Matrix Submatrix\n\t */\n\tpublic function getMatrixByCol($j0 = null, $jF = null) {\n\t\tif (is_int($j0)) {\n\t\t\tif (is_int($jF)) {\n\t\t\t\treturn $this->getMatrix(0, $j0, $this->m, $jF + 1);\n\t\t\t} else {\n\t\t\t\treturn $this->getMatrix(0, $j0, $this->m, $j0 + 1);\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::ArgumentTypeException);\n\t\t}\n\t}\t//\tfunction getMatrixByCol()\n\n\n\t/**\n\t *\ttranspose\n\t *\n\t *\tTranpose matrix\n\t *\t@return Matrix Transposed matrix\n\t */\n\tpublic function transpose() {\n\t\t$R = new PHPExcel_Shared_JAMA_Matrix($this->n, $this->m);\n\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t$R->set($j, $i, $this->A[$i][$j]);\n\t\t\t}\n\t\t}\n\t\treturn $R;\n\t}\t//\tfunction transpose()\n\n\n\t/**\n\t *\ttrace\n\t *\n\t *\tSum of diagonal elements\n\t *\t@return float Sum of diagonal elements\n\t */\n\tpublic function trace() {\n\t\t$s = 0;\n\t\t$n = min($this->m, $this->n);\n\t\tfor($i = 0; $i < $n; ++$i) {\n\t\t\t$s += $this->A[$i][$i];\n\t\t}\n\t\treturn $s;\n\t}\t//\tfunction trace()\n\n\n\t/**\n\t *\tuminus\n\t *\n\t *\tUnary minus matrix -A\n\t *\t@return Matrix Unary minus matrix\n\t */\n\tpublic function uminus() {\n\t}\t//\tfunction uminus()\n\n\n\t/**\n\t *\tplus\n\t *\n\t *\tA + B\n\t *\t@param mixed $B Matrix/Array\n\t *\t@return Matrix Sum\n\t */\n\tpublic function plus() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\tcase 'object':\n\t\t\t\t\t\tif ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$M = new PHPExcel_Shared_JAMA_Matrix($args[0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$this->checkMatrixDimensions($M);\n\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t$M->set($i, $j, $M->get($i, $j) + $this->A[$i][$j]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $M;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction plus()\n\n\n\t/**\n\t *\tplusEquals\n\t *\n\t *\tA = A + B\n\t *\t@param mixed $B Matrix/Array\n\t *\t@return Matrix Sum\n\t */\n\tpublic function plusEquals() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\tcase 'object':\n\t\t\t\t\t\tif ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$M = new PHPExcel_Shared_JAMA_Matrix($args[0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$this->checkMatrixDimensions($M);\n\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t$validValues = True;\n\t\t\t\t\t$value = $M->get($i, $j);\n\t\t\t\t\tif ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {\n\t\t\t\t\t\t$this->A[$i][$j] = trim($this->A[$i][$j],'\"');\n\t\t\t\t\t\t$validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]);\n\t\t\t\t\t}\n\t\t\t\t\tif ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {\n\t\t\t\t\t\t$value = trim($value,'\"');\n\t\t\t\t\t\t$validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value);\n\t\t\t\t\t}\n\t\t\t\t\tif ($validValues) {\n\t\t\t\t\t\t$this->A[$i][$j] += $value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $this;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction plusEquals()\n\n\n\t/**\n\t *\tminus\n\t *\n\t *\tA - B\n\t *\t@param mixed $B Matrix/Array\n\t *\t@return Matrix Sum\n\t */\n\tpublic function minus() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\tcase 'object':\n\t\t\t\t\t\tif ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$M = new PHPExcel_Shared_JAMA_Matrix($args[0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$this->checkMatrixDimensions($M);\n\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t$M->set($i, $j, $M->get($i, $j) - $this->A[$i][$j]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $M;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction minus()\n\n\n\t/**\n\t *\tminusEquals\n\t *\n\t *\tA = A - B\n\t *\t@param mixed $B Matrix/Array\n\t *\t@return Matrix Sum\n\t */\n\tpublic function minusEquals() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\tcase 'object':\n\t\t\t\t\t\tif ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$M = new PHPExcel_Shared_JAMA_Matrix($args[0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$this->checkMatrixDimensions($M);\n\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t$validValues = True;\n\t\t\t\t\t$value = $M->get($i, $j);\n\t\t\t\t\tif ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {\n\t\t\t\t\t\t$this->A[$i][$j] = trim($this->A[$i][$j],'\"');\n\t\t\t\t\t\t$validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]);\n\t\t\t\t\t}\n\t\t\t\t\tif ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {\n\t\t\t\t\t\t$value = trim($value,'\"');\n\t\t\t\t\t\t$validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value);\n\t\t\t\t\t}\n\t\t\t\t\tif ($validValues) {\n\t\t\t\t\t\t$this->A[$i][$j] -= $value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $this;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction minusEquals()\n\n\n\t/**\n\t *\tarrayTimes\n\t *\n\t *\tElement-by-element multiplication\n\t *\tCij = Aij * Bij\n\t *\t@param mixed $B Matrix/Array\n\t *\t@return Matrix Matrix Cij\n\t */\n\tpublic function arrayTimes() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\tcase 'object':\n\t\t\t\t\t\tif ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$M = new PHPExcel_Shared_JAMA_Matrix($args[0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$this->checkMatrixDimensions($M);\n\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t$M->set($i, $j, $M->get($i, $j) * $this->A[$i][$j]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $M;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction arrayTimes()\n\n\n\t/**\n\t *\tarrayTimesEquals\n\t *\n\t *\tElement-by-element multiplication\n\t *\tAij = Aij * Bij\n\t *\t@param mixed $B Matrix/Array\n\t *\t@return Matrix Matrix Aij\n\t */\n\tpublic function arrayTimesEquals() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\tcase 'object':\n\t\t\t\t\t\tif ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$M = new PHPExcel_Shared_JAMA_Matrix($args[0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$this->checkMatrixDimensions($M);\n\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t$validValues = True;\n\t\t\t\t\t$value = $M->get($i, $j);\n\t\t\t\t\tif ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {\n\t\t\t\t\t\t$this->A[$i][$j] = trim($this->A[$i][$j],'\"');\n\t\t\t\t\t\t$validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]);\n\t\t\t\t\t}\n\t\t\t\t\tif ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {\n\t\t\t\t\t\t$value = trim($value,'\"');\n\t\t\t\t\t\t$validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value);\n\t\t\t\t\t}\n\t\t\t\t\tif ($validValues) {\n\t\t\t\t\t\t$this->A[$i][$j] *= $value;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $this;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction arrayTimesEquals()\n\n\n\t/**\n\t *\tarrayRightDivide\n\t *\n\t *\tElement-by-element right division\n\t *\tA / B\n\t *\t@param Matrix $B Matrix B\n\t *\t@return Matrix Division result\n\t */\n\tpublic function arrayRightDivide() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\tcase 'object':\n\t\t\t\t\t\tif ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$M = new PHPExcel_Shared_JAMA_Matrix($args[0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$this->checkMatrixDimensions($M);\n\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t$validValues = True;\n\t\t\t\t\t$value = $M->get($i, $j);\n\t\t\t\t\tif ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {\n\t\t\t\t\t\t$this->A[$i][$j] = trim($this->A[$i][$j],'\"');\n\t\t\t\t\t\t$validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]);\n\t\t\t\t\t}\n\t\t\t\t\tif ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {\n\t\t\t\t\t\t$value = trim($value,'\"');\n\t\t\t\t\t\t$validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value);\n\t\t\t\t\t}\n\t\t\t\t\tif ($validValues) {\n\t\t\t\t\t\tif ($value == 0) {\n\t\t\t\t\t\t\t//\tTrap for Divide by Zero error\n\t\t\t\t\t\t\t$M->set($i, $j, '#DIV/0!');\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$M->set($i, $j, $this->A[$i][$j] / $value);\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$M->set($i, $j, PHPExcel_Calculation_Functions::NaN());\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $M;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction arrayRightDivide()\n\n\n\t/**\n\t *\tarrayRightDivideEquals\n\t *\n\t *\tElement-by-element right division\n\t *\tAij = Aij / Bij\n\t *\t@param mixed $B Matrix/Array\n\t *\t@return Matrix Matrix Aij\n\t */\n\tpublic function arrayRightDivideEquals() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\tcase 'object':\n\t\t\t\t\t\tif ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$M = new PHPExcel_Shared_JAMA_Matrix($args[0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$this->checkMatrixDimensions($M);\n\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t$this->A[$i][$j] = $this->A[$i][$j] / $M->get($i, $j);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $M;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction arrayRightDivideEquals()\n\n\n\t/**\n\t *\tarrayLeftDivide\n\t *\n\t *\tElement-by-element Left division\n\t *\tA / B\n\t *\t@param Matrix $B Matrix B\n\t *\t@return Matrix Division result\n\t */\n\tpublic function arrayLeftDivide() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\tcase 'object':\n\t\t\t\t\t\tif ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$M = new PHPExcel_Shared_JAMA_Matrix($args[0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$this->checkMatrixDimensions($M);\n\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t$M->set($i, $j, $M->get($i, $j) / $this->A[$i][$j]);\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $M;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction arrayLeftDivide()\n\n\n\t/**\n\t *\tarrayLeftDivideEquals\n\t *\n\t *\tElement-by-element Left division\n\t *\tAij = Aij / Bij\n\t *\t@param mixed $B Matrix/Array\n\t *\t@return Matrix Matrix Aij\n\t */\n\tpublic function arrayLeftDivideEquals() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\tcase 'object':\n\t\t\t\t\t\tif ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$M = new PHPExcel_Shared_JAMA_Matrix($args[0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$this->checkMatrixDimensions($M);\n\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t$this->A[$i][$j] = $M->get($i, $j) / $this->A[$i][$j];\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $M;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction arrayLeftDivideEquals()\n\n\n\t/**\n\t *\ttimes\n\t *\n\t *\tMatrix multiplication\n\t *\t@param mixed $n Matrix/Array/Scalar\n\t *\t@return Matrix Product\n\t */\n\tpublic function times() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args  = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\tcase 'object':\n\t\t\t\t\t\tif ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $B = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }\n\t\t\t\t\t\tif ($this->n == $B->m) {\n\t\t\t\t\t\t\t$C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n);\n\t\t\t\t\t\t\tfor($j = 0; $j < $B->n; ++$j) {\n\t\t\t\t\t\t\t\tfor ($k = 0; $k < $this->n; ++$k) {\n\t\t\t\t\t\t\t\t\t$Bcolj[$k] = $B->A[$k][$j];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\t\t\t$Arowi = $this->A[$i];\n\t\t\t\t\t\t\t\t\t$s = 0;\n\t\t\t\t\t\t\t\t\tfor($k = 0; $k < $this->n; ++$k) {\n\t\t\t\t\t\t\t\t\t\t$s += $Arowi[$k] * $Bcolj[$k];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t$C->A[$i][$j] = $s;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn $C;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$B = new PHPExcel_Shared_JAMA_Matrix($args[0]);\n\t\t\t\t\t\tif ($this->n == $B->m) {\n\t\t\t\t\t\t\t$C = new PHPExcel_Shared_JAMA_Matrix($this->m, $B->n);\n\t\t\t\t\t\t\tfor($i = 0; $i < $C->m; ++$i) {\n\t\t\t\t\t\t\t\tfor($j = 0; $j < $C->n; ++$j) {\n\t\t\t\t\t\t\t\t\t$s = \"0\";\n\t\t\t\t\t\t\t\t\tfor($k = 0; $k < $C->n; ++$k) {\n\t\t\t\t\t\t\t\t\t\t$s += $this->A[$i][$k] * $B->A[$k][$j];\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t$C->A[$i][$j] = $s;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\treturn $C;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(JAMAError(MatrixDimensionMismatch));\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn $M;\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'integer':\n\t\t\t\t\t\t$C = new PHPExcel_Shared_JAMA_Matrix($this->A);\n\t\t\t\t\t\tfor($i = 0; $i < $C->m; ++$i) {\n\t\t\t\t\t\t\tfor($j = 0; $j < $C->n; ++$j) {\n\t\t\t\t\t\t\t\t$C->A[$i][$j] *= $args[0];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn $C;\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'double':\n\t\t\t\t\t\t$C = new PHPExcel_Shared_JAMA_Matrix($this->m, $this->n);\n\t\t\t\t\t\tfor($i = 0; $i < $C->m; ++$i) {\n\t\t\t\t\t\t\tfor($j = 0; $j < $C->n; ++$j) {\n\t\t\t\t\t\t\t\t$C->A[$i][$j] = $args[0] * $this->A[$i][$j];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn $C;\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'float':\n\t\t\t\t\t\t$C = new PHPExcel_Shared_JAMA_Matrix($this->A);\n\t\t\t\t\t\tfor($i = 0; $i < $C->m; ++$i) {\n\t\t\t\t\t\t\tfor($j = 0; $j < $C->n; ++$j) {\n\t\t\t\t\t\t\t\t$C->A[$i][$j] *= $args[0];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn $C;\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction times()\n\n\n\t/**\n\t *\tpower\n\t *\n\t *\tA = A ^ B\n\t *\t@param mixed $B Matrix/Array\n\t *\t@return Matrix Sum\n\t */\n\tpublic function power() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\tcase 'object':\n\t\t\t\t\t\tif ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }\n\t\t\t\t\t\tbreak;\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$M = new PHPExcel_Shared_JAMA_Matrix($args[0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$this->checkMatrixDimensions($M);\n\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t$validValues = True;\n\t\t\t\t\t$value = $M->get($i, $j);\n\t\t\t\t\tif ((is_string($this->A[$i][$j])) && (strlen($this->A[$i][$j]) > 0) && (!is_numeric($this->A[$i][$j]))) {\n\t\t\t\t\t\t$this->A[$i][$j] = trim($this->A[$i][$j],'\"');\n\t\t\t\t\t\t$validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($this->A[$i][$j]);\n\t\t\t\t\t}\n\t\t\t\t\tif ((is_string($value)) && (strlen($value) > 0) && (!is_numeric($value))) {\n\t\t\t\t\t\t$value = trim($value,'\"');\n\t\t\t\t\t\t$validValues &= PHPExcel_Shared_String::convertToNumberIfFraction($value);\n\t\t\t\t\t}\n\t\t\t\t\tif ($validValues) {\n\t\t\t\t\t\t$this->A[$i][$j] = pow($this->A[$i][$j],$value);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$this->A[$i][$j] = PHPExcel_Calculation_Functions::NaN();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $this;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction power()\n\n\n\t/**\n\t *\tconcat\n\t *\n\t *\tA = A & B\n\t *\t@param mixed $B Matrix/Array\n\t *\t@return Matrix Sum\n\t */\n\tpublic function concat() {\n\t\tif (func_num_args() > 0) {\n\t\t\t$args = func_get_args();\n\t\t\t$match = implode(\",\", array_map('gettype', $args));\n\n\t\t\tswitch($match) {\n\t\t\t\tcase 'object':\n\t\t\t\t\t\tif ($args[0] instanceof PHPExcel_Shared_JAMA_Matrix) { $M = $args[0]; } else { throw new PHPExcel_Calculation_Exception(self::ArgumentTypeException); }\n\t\t\t\tcase 'array':\n\t\t\t\t\t\t$M = new PHPExcel_Shared_JAMA_Matrix($args[0]);\n\t\t\t\t\t\tbreak;\n\t\t\t\tdefault:\n\t\t\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t$this->checkMatrixDimensions($M);\n\t\t\tfor($i = 0; $i < $this->m; ++$i) {\n\t\t\t\tfor($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t\t$this->A[$i][$j] = trim($this->A[$i][$j],'\"').trim($M->get($i, $j),'\"');\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn $this;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(self::PolymorphicArgumentException);\n\t\t}\n\t}\t//\tfunction concat()\n\n\n\t/**\n\t *\tSolve A*X = B.\n\t *\n\t *\t@param Matrix $B Right hand side\n\t *\t@return Matrix ... Solution if A is square, least squares solution otherwise\n\t */\n\tpublic function solve($B) {\n\t\tif ($this->m == $this->n) {\n\t\t\t$LU = new PHPExcel_Shared_JAMA_LUDecomposition($this);\n\t\t\treturn $LU->solve($B);\n\t\t} else {\n\t\t\t$QR = new PHPExcel_Shared_JAMA_QRDecomposition($this);\n\t\t\treturn $QR->solve($B);\n\t\t}\n\t}\t//\tfunction solve()\n\n\n\t/**\n\t *\tMatrix inverse or pseudoinverse.\n\t *\n\t *\t@return Matrix ... Inverse(A) if A is square, pseudoinverse otherwise.\n\t */\n\tpublic function inverse() {\n\t\treturn $this->solve($this->identity($this->m, $this->m));\n\t}\t//\tfunction inverse()\n\n\n\t/**\n\t *\tdet\n\t *\n\t *\tCalculate determinant\n\t *\t@return float Determinant\n\t */\n\tpublic function det() {\n\t\t$L = new PHPExcel_Shared_JAMA_LUDecomposition($this);\n\t\treturn $L->det();\n\t}\t//\tfunction det()\n}\t//\tclass PHPExcel_Shared_JAMA_Matrix\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/QRDecomposition.php",
    "content": "<?php\n/**\n *\t@package JAMA\n *\n *\tFor an m-by-n matrix A with m >= n, the QR decomposition is an m-by-n\n *\torthogonal matrix Q and an n-by-n upper triangular matrix R so that\n *\tA = Q*R.\n *\n *\tThe QR decompostion always exists, even if the matrix does not have\n *\tfull rank, so the constructor will never fail.  The primary use of the\n *\tQR decomposition is in the least squares solution of nonsquare systems\n *\tof simultaneous linear equations.  This will fail if isFullRank()\n *\treturns false.\n *\n *\t@author  Paul Meagher\n *\t@license PHP v3.0\n *\t@version 1.1\n */\nclass PHPExcel_Shared_JAMA_QRDecomposition {\n\n\tconst MatrixRankException\t= \"Can only perform operation on full-rank matrix.\";\n\n\t/**\n\t *\tArray for internal storage of decomposition.\n\t *\t@var array\n\t */\n\tprivate $QR = array();\n\n\t/**\n\t *\tRow dimension.\n\t *\t@var integer\n\t */\n\tprivate $m;\n\n\t/**\n\t*\tColumn dimension.\n\t*\t@var integer\n\t*/\n\tprivate $n;\n\n\t/**\n\t *\tArray for internal storage of diagonal of R.\n\t *\t@var  array\n\t */\n\tprivate $Rdiag = array();\n\n\n\t/**\n\t *\tQR Decomposition computed by Householder reflections.\n\t *\n\t *\t@param matrix $A Rectangular matrix\n\t *\t@return Structure to access R and the Householder vectors and compute Q.\n\t */\n\tpublic function __construct($A) {\n\t\tif($A instanceof PHPExcel_Shared_JAMA_Matrix) {\n\t\t\t// Initialize.\n\t\t\t$this->QR = $A->getArrayCopy();\n\t\t\t$this->m  = $A->getRowDimension();\n\t\t\t$this->n  = $A->getColumnDimension();\n\t\t\t// Main loop.\n\t\t\tfor ($k = 0; $k < $this->n; ++$k) {\n\t\t\t\t// Compute 2-norm of k-th column without under/overflow.\n\t\t\t\t$nrm = 0.0;\n\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t$nrm = hypo($nrm, $this->QR[$i][$k]);\n\t\t\t\t}\n\t\t\t\tif ($nrm != 0.0) {\n\t\t\t\t\t// Form k-th Householder vector.\n\t\t\t\t\tif ($this->QR[$k][$k] < 0) {\n\t\t\t\t\t\t$nrm = -$nrm;\n\t\t\t\t\t}\n\t\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t\t$this->QR[$i][$k] /= $nrm;\n\t\t\t\t\t}\n\t\t\t\t\t$this->QR[$k][$k] += 1.0;\n\t\t\t\t\t// Apply transformation to remaining columns.\n\t\t\t\t\tfor ($j = $k+1; $j < $this->n; ++$j) {\n\t\t\t\t\t\t$s = 0.0;\n\t\t\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\t$s += $this->QR[$i][$k] * $this->QR[$i][$j];\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$s = -$s/$this->QR[$k][$k];\n\t\t\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\t$this->QR[$i][$j] += $s * $this->QR[$i][$k];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$this->Rdiag[$k] = -$nrm;\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::ArgumentTypeException);\n\t\t}\n\t}\t//\tfunction __construct()\n\n\n\t/**\n\t *\tIs the matrix full rank?\n\t *\n\t *\t@return boolean true if R, and hence A, has full rank, else false.\n\t */\n\tpublic function isFullRank() {\n\t\tfor ($j = 0; $j < $this->n; ++$j) {\n\t\t\tif ($this->Rdiag[$j] == 0) {\n\t\t\t\treturn false;\n\t\t\t}\n\t\t}\n\t\treturn true;\n\t}\t//\tfunction isFullRank()\n\n\n\t/**\n\t *\tReturn the Householder vectors\n\t *\n\t *\t@return Matrix Lower trapezoidal matrix whose columns define the reflections\n\t */\n\tpublic function getH() {\n\t\tfor ($i = 0; $i < $this->m; ++$i) {\n\t\t\tfor ($j = 0; $j < $this->n; ++$j) {\n\t\t\t\tif ($i >= $j) {\n\t\t\t\t\t$H[$i][$j] = $this->QR[$i][$j];\n\t\t\t\t} else {\n\t\t\t\t\t$H[$i][$j] = 0.0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn new PHPExcel_Shared_JAMA_Matrix($H);\n\t}\t//\tfunction getH()\n\n\n\t/**\n\t *\tReturn the upper triangular factor\n\t *\n\t *\t@return Matrix upper triangular factor\n\t */\n\tpublic function getR() {\n\t\tfor ($i = 0; $i < $this->n; ++$i) {\n\t\t\tfor ($j = 0; $j < $this->n; ++$j) {\n\t\t\t\tif ($i < $j) {\n\t\t\t\t\t$R[$i][$j] = $this->QR[$i][$j];\n\t\t\t\t} elseif ($i == $j) {\n\t\t\t\t\t$R[$i][$j] = $this->Rdiag[$i];\n\t\t\t\t} else {\n\t\t\t\t\t$R[$i][$j] = 0.0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn new PHPExcel_Shared_JAMA_Matrix($R);\n\t}\t//\tfunction getR()\n\n\n\t/**\n\t *\tGenerate and return the (economy-sized) orthogonal factor\n\t *\n\t *\t@return Matrix orthogonal factor\n\t */\n\tpublic function getQ() {\n\t\tfor ($k = $this->n-1; $k >= 0; --$k) {\n\t\t\tfor ($i = 0; $i < $this->m; ++$i) {\n\t\t\t\t$Q[$i][$k] = 0.0;\n\t\t\t}\n\t\t\t$Q[$k][$k] = 1.0;\n\t\t\tfor ($j = $k; $j < $this->n; ++$j) {\n\t\t\t\tif ($this->QR[$k][$k] != 0) {\n\t\t\t\t\t$s = 0.0;\n\t\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t\t$s += $this->QR[$i][$k] * $Q[$i][$j];\n\t\t\t\t\t}\n\t\t\t\t\t$s = -$s/$this->QR[$k][$k];\n\t\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t\t$Q[$i][$j] += $s * $this->QR[$i][$k];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t/*\n\t\tfor($i = 0; $i < count($Q); ++$i) {\n\t\t\tfor($j = 0; $j < count($Q); ++$j) {\n\t\t\t\tif(! isset($Q[$i][$j]) ) {\n\t\t\t\t\t$Q[$i][$j] = 0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t*/\n\t\treturn new PHPExcel_Shared_JAMA_Matrix($Q);\n\t}\t//\tfunction getQ()\n\n\n\t/**\n\t *\tLeast squares solution of A*X = B\n\t *\n\t *\t@param Matrix $B A Matrix with as many rows as A and any number of columns.\n\t *\t@return Matrix Matrix that minimizes the two norm of Q*R*X-B.\n\t */\n\tpublic function solve($B) {\n\t\tif ($B->getRowDimension() == $this->m) {\n\t\t\tif ($this->isFullRank()) {\n\t\t\t\t// Copy right hand side\n\t\t\t\t$nx = $B->getColumnDimension();\n\t\t\t\t$X  = $B->getArrayCopy();\n\t\t\t\t// Compute Y = transpose(Q)*B\n\t\t\t\tfor ($k = 0; $k < $this->n; ++$k) {\n\t\t\t\t\tfor ($j = 0; $j < $nx; ++$j) {\n\t\t\t\t\t\t$s = 0.0;\n\t\t\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\t$s += $this->QR[$i][$k] * $X[$i][$j];\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$s = -$s/$this->QR[$k][$k];\n\t\t\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\t$X[$i][$j] += $s * $this->QR[$i][$k];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t// Solve R*X = Y;\n\t\t\t\tfor ($k = $this->n-1; $k >= 0; --$k) {\n\t\t\t\t\tfor ($j = 0; $j < $nx; ++$j) {\n\t\t\t\t\t\t$X[$k][$j] /= $this->Rdiag[$k];\n\t\t\t\t\t}\n\t\t\t\t\tfor ($i = 0; $i < $k; ++$i) {\n\t\t\t\t\t\tfor ($j = 0; $j < $nx; ++$j) {\n\t\t\t\t\t\t\t$X[$i][$j] -= $X[$k][$j]* $this->QR[$i][$k];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$X = new PHPExcel_Shared_JAMA_Matrix($X);\n\t\t\t\treturn ($X->getMatrix(0, $this->n-1, 0, $nx));\n\t\t\t} else {\n\t\t\t\tthrow new PHPExcel_Calculation_Exception(self::MatrixRankException);\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(PHPExcel_Shared_JAMA_Matrix::MatrixDimensionException);\n\t\t}\n\t}\t//\tfunction solve()\n\n}\t//\tPHPExcel_Shared_JAMA_class QRDecomposition\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/SingularValueDecomposition.php",
    "content": "<?php\n/**\n *\t@package JAMA\n *\n *\tFor an m-by-n matrix A with m >= n, the singular value decomposition is\n *\tan m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and\n *\tan n-by-n orthogonal matrix V so that A = U*S*V'.\n *\n *\tThe singular values, sigma[$k] = S[$k][$k], are ordered so that\n *\tsigma[0] >= sigma[1] >= ... >= sigma[n-1].\n *\n *\tThe singular value decompostion always exists, so the constructor will\n *\tnever fail.  The matrix condition number and the effective numerical\n *\trank can be computed from this decomposition.\n *\n *\t@author  Paul Meagher\n *\t@license PHP v3.0\n *\t@version 1.1\n */\nclass SingularValueDecomposition  {\n\n\t/**\n\t *\tInternal storage of U.\n\t *\t@var array\n\t */\n\tprivate $U = array();\n\n\t/**\n\t *\tInternal storage of V.\n\t *\t@var array\n\t */\n\tprivate $V = array();\n\n\t/**\n\t *\tInternal storage of singular values.\n\t *\t@var array\n\t */\n\tprivate $s = array();\n\n\t/**\n\t *\tRow dimension.\n\t *\t@var int\n\t */\n\tprivate $m;\n\n\t/**\n\t *\tColumn dimension.\n\t *\t@var int\n\t */\n\tprivate $n;\n\n\n\t/**\n\t *\tConstruct the singular value decomposition\n\t *\n\t *\tDerived from LINPACK code.\n\t *\n\t *\t@param $A Rectangular matrix\n\t *\t@return Structure to access U, S and V.\n\t */\n\tpublic function __construct($Arg) {\n\n\t\t// Initialize.\n\t\t$A = $Arg->getArrayCopy();\n\t\t$this->m = $Arg->getRowDimension();\n\t\t$this->n = $Arg->getColumnDimension();\n\t\t$nu      = min($this->m, $this->n);\n\t\t$e       = array();\n\t\t$work    = array();\n\t\t$wantu   = true;\n\t\t$wantv   = true;\n\t\t$nct = min($this->m - 1, $this->n);\n\t\t$nrt = max(0, min($this->n - 2, $this->m));\n\n\t\t// Reduce A to bidiagonal form, storing the diagonal elements\n\t\t// in s and the super-diagonal elements in e.\n\t\tfor ($k = 0; $k < max($nct,$nrt); ++$k) {\n\n\t\t\tif ($k < $nct) {\n\t\t\t\t// Compute the transformation for the k-th column and\n\t\t\t\t// place the k-th diagonal in s[$k].\n\t\t\t\t// Compute 2-norm of k-th column without under/overflow.\n\t\t\t\t$this->s[$k] = 0;\n\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t$this->s[$k] = hypo($this->s[$k], $A[$i][$k]);\n\t\t\t\t}\n\t\t\t\tif ($this->s[$k] != 0.0) {\n\t\t\t\t\tif ($A[$k][$k] < 0.0) {\n\t\t\t\t\t\t$this->s[$k] = -$this->s[$k];\n\t\t\t\t\t}\n\t\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t\t$A[$i][$k] /= $this->s[$k];\n\t\t\t\t\t}\n\t\t\t\t\t$A[$k][$k] += 1.0;\n\t\t\t\t}\n\t\t\t\t$this->s[$k] = -$this->s[$k];\n\t\t\t}\n\n\t\t\tfor ($j = $k + 1; $j < $this->n; ++$j) {\n\t\t\t\tif (($k < $nct) & ($this->s[$k] != 0.0)) {\n\t\t\t\t\t// Apply the transformation.\n\t\t\t\t\t$t = 0;\n\t\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t\t$t += $A[$i][$k] * $A[$i][$j];\n\t\t\t\t\t}\n\t\t\t\t\t$t = -$t / $A[$k][$k];\n\t\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t\t$A[$i][$j] += $t * $A[$i][$k];\n\t\t\t\t\t}\n\t\t\t\t\t// Place the k-th row of A into e for the\n\t\t\t\t\t// subsequent calculation of the row transformation.\n\t\t\t\t\t$e[$j] = $A[$k][$j];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ($wantu AND ($k < $nct)) {\n\t\t\t\t// Place the transformation in U for subsequent back\n\t\t\t\t// multiplication.\n\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t$this->U[$i][$k] = $A[$i][$k];\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif ($k < $nrt) {\n\t\t\t\t// Compute the k-th row transformation and place the\n\t\t\t\t// k-th super-diagonal in e[$k].\n\t\t\t\t// Compute 2-norm without under/overflow.\n\t\t\t\t$e[$k] = 0;\n\t\t\t\tfor ($i = $k + 1; $i < $this->n; ++$i) {\n\t\t\t\t\t$e[$k] = hypo($e[$k], $e[$i]);\n\t\t\t\t}\n\t\t\t\tif ($e[$k] != 0.0) {\n\t\t\t\t\tif ($e[$k+1] < 0.0) {\n\t\t\t\t\t\t$e[$k] = -$e[$k];\n\t\t\t\t\t}\n\t\t\t\t\tfor ($i = $k + 1; $i < $this->n; ++$i) {\n\t\t\t\t\t\t$e[$i] /= $e[$k];\n\t\t\t\t\t}\n\t\t\t\t\t$e[$k+1] += 1.0;\n\t\t\t\t}\n\t\t\t\t$e[$k] = -$e[$k];\n\t\t\t\tif (($k+1 < $this->m) AND ($e[$k] != 0.0)) {\n\t\t\t\t\t// Apply the transformation.\n\t\t\t\t\tfor ($i = $k+1; $i < $this->m; ++$i) {\n\t\t\t\t\t\t$work[$i] = 0.0;\n\t\t\t\t\t}\n\t\t\t\t\tfor ($j = $k+1; $j < $this->n; ++$j) {\n\t\t\t\t\t\tfor ($i = $k+1; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\t$work[$i] += $e[$j] * $A[$i][$j];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor ($j = $k + 1; $j < $this->n; ++$j) {\n\t\t\t\t\t\t$t = -$e[$j] / $e[$k+1];\n\t\t\t\t\t\tfor ($i = $k + 1; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\t$A[$i][$j] += $t * $work[$i];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ($wantv) {\n\t\t\t\t\t// Place the transformation in V for subsequent\n\t\t\t\t\t// back multiplication.\n\t\t\t\t\tfor ($i = $k + 1; $i < $this->n; ++$i) {\n\t\t\t\t\t\t$this->V[$i][$k] = $e[$i];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Set up the final bidiagonal matrix or order p.\n\t\t$p = min($this->n, $this->m + 1);\n\t\tif ($nct < $this->n) {\n\t\t\t$this->s[$nct] = $A[$nct][$nct];\n\t\t}\n\t\tif ($this->m < $p) {\n\t\t\t$this->s[$p-1] = 0.0;\n\t\t}\n\t\tif ($nrt + 1 < $p) {\n\t\t\t$e[$nrt] = $A[$nrt][$p-1];\n\t\t}\n\t\t$e[$p-1] = 0.0;\n\t\t// If required, generate U.\n\t\tif ($wantu) {\n\t\t\tfor ($j = $nct; $j < $nu; ++$j) {\n\t\t\t\tfor ($i = 0; $i < $this->m; ++$i) {\n\t\t\t\t\t$this->U[$i][$j] = 0.0;\n\t\t\t\t}\n\t\t\t\t$this->U[$j][$j] = 1.0;\n\t\t\t}\n\t\t\tfor ($k = $nct - 1; $k >= 0; --$k) {\n\t\t\t\tif ($this->s[$k] != 0.0) {\n\t\t\t\t\tfor ($j = $k + 1; $j < $nu; ++$j) {\n\t\t\t\t\t\t$t = 0;\n\t\t\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\t$t += $this->U[$i][$k] * $this->U[$i][$j];\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$t = -$t / $this->U[$k][$k];\n\t\t\t\t\t\tfor ($i = $k; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\t$this->U[$i][$j] += $t * $this->U[$i][$k];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tfor ($i = $k; $i < $this->m; ++$i ) {\n\t\t\t\t\t\t$this->U[$i][$k] = -$this->U[$i][$k];\n\t\t\t\t\t}\n\t\t\t\t\t$this->U[$k][$k] = 1.0 + $this->U[$k][$k];\n\t\t\t\t\tfor ($i = 0; $i < $k - 1; ++$i) {\n\t\t\t\t\t\t$this->U[$i][$k] = 0.0;\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor ($i = 0; $i < $this->m; ++$i) {\n\t\t\t\t\t\t$this->U[$i][$k] = 0.0;\n\t\t\t\t\t}\n\t\t\t\t\t$this->U[$k][$k] = 1.0;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// If required, generate V.\n\t\tif ($wantv) {\n\t\t\tfor ($k = $this->n - 1; $k >= 0; --$k) {\n\t\t\t\tif (($k < $nrt) AND ($e[$k] != 0.0)) {\n\t\t\t\t\tfor ($j = $k + 1; $j < $nu; ++$j) {\n\t\t\t\t\t\t$t = 0;\n\t\t\t\t\t\tfor ($i = $k + 1; $i < $this->n; ++$i) {\n\t\t\t\t\t\t\t$t += $this->V[$i][$k]* $this->V[$i][$j];\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$t = -$t / $this->V[$k+1][$k];\n\t\t\t\t\t\tfor ($i = $k + 1; $i < $this->n; ++$i) {\n\t\t\t\t\t\t\t$this->V[$i][$j] += $t * $this->V[$i][$k];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tfor ($i = 0; $i < $this->n; ++$i) {\n\t\t\t\t\t$this->V[$i][$k] = 0.0;\n\t\t\t\t}\n\t\t\t\t$this->V[$k][$k] = 1.0;\n\t\t\t}\n\t\t}\n\n\t\t// Main iteration loop for the singular values.\n\t\t$pp   = $p - 1;\n\t\t$iter = 0;\n\t\t$eps  = pow(2.0, -52.0);\n\n\t\twhile ($p > 0) {\n\t\t\t// Here is where a test for too many iterations would go.\n\t\t\t// This section of the program inspects for negligible\n\t\t\t// elements in the s and e arrays.  On completion the\n\t\t\t// variables kase and k are set as follows:\n\t\t\t// kase = 1  if s(p) and e[k-1] are negligible and k<p\n\t\t\t// kase = 2  if s(k) is negligible and k<p\n\t\t\t// kase = 3  if e[k-1] is negligible, k<p, and\n\t\t\t//           s(k), ..., s(p) are not negligible (qr step).\n\t\t\t// kase = 4  if e(p-1) is negligible (convergence).\n\t\t\tfor ($k = $p - 2; $k >= -1; --$k) {\n\t\t\t\tif ($k == -1) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tif (abs($e[$k]) <= $eps * (abs($this->s[$k]) + abs($this->s[$k+1]))) {\n\t\t\t\t\t$e[$k] = 0.0;\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t\tif ($k == $p - 2) {\n\t\t\t\t$kase = 4;\n\t\t\t} else {\n\t\t\t\tfor ($ks = $p - 1; $ks >= $k; --$ks) {\n\t\t\t\t\tif ($ks == $k) {\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\t$t = ($ks != $p ? abs($e[$ks]) : 0.) + ($ks != $k + 1 ? abs($e[$ks-1]) : 0.);\n\t\t\t\t\tif (abs($this->s[$ks]) <= $eps * $t)  {\n\t\t\t\t\t\t$this->s[$ks] = 0.0;\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ($ks == $k) {\n\t\t\t\t\t$kase = 3;\n\t\t\t\t} else if ($ks == $p-1) {\n\t\t\t\t\t$kase = 1;\n\t\t\t\t} else {\n\t\t\t\t\t$kase = 2;\n\t\t\t\t\t$k = $ks;\n\t\t\t\t}\n\t\t\t}\n\t\t\t++$k;\n\n\t\t\t// Perform the task indicated by kase.\n\t\t\tswitch ($kase) {\n\t\t\t\t// Deflate negligible s(p).\n\t\t\t\tcase 1:\n\t\t\t\t\t\t$f = $e[$p-2];\n\t\t\t\t\t\t$e[$p-2] = 0.0;\n\t\t\t\t\t\tfor ($j = $p - 2; $j >= $k; --$j) {\n\t\t\t\t\t\t\t$t  = hypo($this->s[$j],$f);\n\t\t\t\t\t\t\t$cs = $this->s[$j] / $t;\n\t\t\t\t\t\t\t$sn = $f / $t;\n\t\t\t\t\t\t\t$this->s[$j] = $t;\n\t\t\t\t\t\t\tif ($j != $k) {\n\t\t\t\t\t\t\t\t$f = -$sn * $e[$j-1];\n\t\t\t\t\t\t\t\t$e[$j-1] = $cs * $e[$j-1];\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ($wantv) {\n\t\t\t\t\t\t\t\tfor ($i = 0; $i < $this->n; ++$i) {\n\t\t\t\t\t\t\t\t\t$t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$p-1];\n\t\t\t\t\t\t\t\t\t$this->V[$i][$p-1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$p-1];\n\t\t\t\t\t\t\t\t\t$this->V[$i][$j] = $t;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t// Split at negligible s(k).\n\t\t\t\tcase 2:\n\t\t\t\t\t\t$f = $e[$k-1];\n\t\t\t\t\t\t$e[$k-1] = 0.0;\n\t\t\t\t\t\tfor ($j = $k; $j < $p; ++$j) {\n\t\t\t\t\t\t\t$t = hypo($this->s[$j], $f);\n\t\t\t\t\t\t\t$cs = $this->s[$j] / $t;\n\t\t\t\t\t\t\t$sn = $f / $t;\n\t\t\t\t\t\t\t$this->s[$j] = $t;\n\t\t\t\t\t\t\t$f = -$sn * $e[$j];\n\t\t\t\t\t\t\t$e[$j] = $cs * $e[$j];\n\t\t\t\t\t\t\tif ($wantu) {\n\t\t\t\t\t\t\t\tfor ($i = 0; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\t\t\t$t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$k-1];\n\t\t\t\t\t\t\t\t\t$this->U[$i][$k-1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$k-1];\n\t\t\t\t\t\t\t\t\t$this->U[$i][$j] = $t;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t// Perform one qr step.\n\t\t\t\tcase 3:\n\t\t\t\t\t\t// Calculate the shift.\n\t\t\t\t\t\t$scale = max(max(max(max(\n\t\t\t\t\t\t\t\t\tabs($this->s[$p-1]),abs($this->s[$p-2])),abs($e[$p-2])),\n\t\t\t\t\t\t\t\t\tabs($this->s[$k])), abs($e[$k]));\n\t\t\t\t\t\t$sp   = $this->s[$p-1] / $scale;\n\t\t\t\t\t\t$spm1 = $this->s[$p-2] / $scale;\n\t\t\t\t\t\t$epm1 = $e[$p-2] / $scale;\n\t\t\t\t\t\t$sk   = $this->s[$k] / $scale;\n\t\t\t\t\t\t$ek   = $e[$k] / $scale;\n\t\t\t\t\t\t$b    = (($spm1 + $sp) * ($spm1 - $sp) + $epm1 * $epm1) / 2.0;\n\t\t\t\t\t\t$c    = ($sp * $epm1) * ($sp * $epm1);\n\t\t\t\t\t\t$shift = 0.0;\n\t\t\t\t\t\tif (($b != 0.0) || ($c != 0.0)) {\n\t\t\t\t\t\t\t$shift = sqrt($b * $b + $c);\n\t\t\t\t\t\t\tif ($b < 0.0) {\n\t\t\t\t\t\t\t\t$shift = -$shift;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$shift = $c / ($b + $shift);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$f = ($sk + $sp) * ($sk - $sp) + $shift;\n\t\t\t\t\t\t$g = $sk * $ek;\n\t\t\t\t\t\t// Chase zeros.\n\t\t\t\t\t\tfor ($j = $k; $j < $p-1; ++$j) {\n\t\t\t\t\t\t\t$t  = hypo($f,$g);\n\t\t\t\t\t\t\t$cs = $f/$t;\n\t\t\t\t\t\t\t$sn = $g/$t;\n\t\t\t\t\t\t\tif ($j != $k) {\n\t\t\t\t\t\t\t\t$e[$j-1] = $t;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$f = $cs * $this->s[$j] + $sn * $e[$j];\n\t\t\t\t\t\t\t$e[$j] = $cs * $e[$j] - $sn * $this->s[$j];\n\t\t\t\t\t\t\t$g = $sn * $this->s[$j+1];\n\t\t\t\t\t\t\t$this->s[$j+1] = $cs * $this->s[$j+1];\n\t\t\t\t\t\t\tif ($wantv) {\n\t\t\t\t\t\t\t\tfor ($i = 0; $i < $this->n; ++$i) {\n\t\t\t\t\t\t\t\t\t$t = $cs * $this->V[$i][$j] + $sn * $this->V[$i][$j+1];\n\t\t\t\t\t\t\t\t\t$this->V[$i][$j+1] = -$sn * $this->V[$i][$j] + $cs * $this->V[$i][$j+1];\n\t\t\t\t\t\t\t\t\t$this->V[$i][$j] = $t;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$t = hypo($f,$g);\n\t\t\t\t\t\t\t$cs = $f/$t;\n\t\t\t\t\t\t\t$sn = $g/$t;\n\t\t\t\t\t\t\t$this->s[$j] = $t;\n\t\t\t\t\t\t\t$f = $cs * $e[$j] + $sn * $this->s[$j+1];\n\t\t\t\t\t\t\t$this->s[$j+1] = -$sn * $e[$j] + $cs * $this->s[$j+1];\n\t\t\t\t\t\t\t$g = $sn * $e[$j+1];\n\t\t\t\t\t\t\t$e[$j+1] = $cs * $e[$j+1];\n\t\t\t\t\t\t\tif ($wantu && ($j < $this->m - 1)) {\n\t\t\t\t\t\t\t\tfor ($i = 0; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\t\t\t$t = $cs * $this->U[$i][$j] + $sn * $this->U[$i][$j+1];\n\t\t\t\t\t\t\t\t\t$this->U[$i][$j+1] = -$sn * $this->U[$i][$j] + $cs * $this->U[$i][$j+1];\n\t\t\t\t\t\t\t\t\t$this->U[$i][$j] = $t;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$e[$p-2] = $f;\n\t\t\t\t\t\t$iter = $iter + 1;\n\t\t\t\t\t\tbreak;\n\t\t\t\t// Convergence.\n\t\t\t\tcase 4:\n\t\t\t\t\t\t// Make the singular values positive.\n\t\t\t\t\t\tif ($this->s[$k] <= 0.0) {\n\t\t\t\t\t\t\t$this->s[$k] = ($this->s[$k] < 0.0 ? -$this->s[$k] : 0.0);\n\t\t\t\t\t\t\tif ($wantv) {\n\t\t\t\t\t\t\t\tfor ($i = 0; $i <= $pp; ++$i) {\n\t\t\t\t\t\t\t\t\t$this->V[$i][$k] = -$this->V[$i][$k];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t// Order the singular values.\n\t\t\t\t\t\twhile ($k < $pp) {\n\t\t\t\t\t\t\tif ($this->s[$k] >= $this->s[$k+1]) {\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$t = $this->s[$k];\n\t\t\t\t\t\t\t$this->s[$k] = $this->s[$k+1];\n\t\t\t\t\t\t\t$this->s[$k+1] = $t;\n\t\t\t\t\t\t\tif ($wantv AND ($k < $this->n - 1)) {\n\t\t\t\t\t\t\t\tfor ($i = 0; $i < $this->n; ++$i) {\n\t\t\t\t\t\t\t\t\t$t = $this->V[$i][$k+1];\n\t\t\t\t\t\t\t\t\t$this->V[$i][$k+1] = $this->V[$i][$k];\n\t\t\t\t\t\t\t\t\t$this->V[$i][$k] = $t;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tif ($wantu AND ($k < $this->m-1)) {\n\t\t\t\t\t\t\t\tfor ($i = 0; $i < $this->m; ++$i) {\n\t\t\t\t\t\t\t\t\t$t = $this->U[$i][$k+1];\n\t\t\t\t\t\t\t\t\t$this->U[$i][$k+1] = $this->U[$i][$k];\n\t\t\t\t\t\t\t\t\t$this->U[$i][$k] = $t;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t++$k;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$iter = 0;\n\t\t\t\t\t\t--$p;\n\t\t\t\t\t\tbreak;\n\t\t\t} // end switch\n\t\t} // end while\n\n\t} // end constructor\n\n\n\t/**\n\t *\tReturn the left singular vectors\n\t *\n\t *\t@access public\n\t *\t@return U\n\t */\n\tpublic function getU() {\n\t\treturn new Matrix($this->U, $this->m, min($this->m + 1, $this->n));\n\t}\n\n\n\t/**\n\t *\tReturn the right singular vectors\n\t *\n\t *\t@access public\n\t *\t@return V\n\t */\n\tpublic function getV() {\n\t\treturn new Matrix($this->V);\n\t}\n\n\n\t/**\n\t *\tReturn the one-dimensional array of singular values\n\t *\n\t *\t@access public\n\t *\t@return diagonal of S.\n\t */\n\tpublic function getSingularValues() {\n\t\treturn $this->s;\n\t}\n\n\n\t/**\n\t *\tReturn the diagonal matrix of singular values\n\t *\n\t *\t@access public\n\t *\t@return S\n\t */\n\tpublic function getS() {\n\t\tfor ($i = 0; $i < $this->n; ++$i) {\n\t\t\tfor ($j = 0; $j < $this->n; ++$j) {\n\t\t\t\t$S[$i][$j] = 0.0;\n\t\t\t}\n\t\t\t$S[$i][$i] = $this->s[$i];\n\t\t}\n\t\treturn new Matrix($S);\n\t}\n\n\n\t/**\n\t *\tTwo norm\n\t *\n\t *\t@access public\n\t *\t@return max(S)\n\t */\n\tpublic function norm2() {\n\t\treturn $this->s[0];\n\t}\n\n\n\t/**\n\t *\tTwo norm condition number\n\t *\n\t *\t@access public\n\t *\t@return max(S)/min(S)\n\t */\n\tpublic function cond() {\n\t\treturn $this->s[0] / $this->s[min($this->m, $this->n) - 1];\n\t}\n\n\n\t/**\n\t *\tEffective numerical matrix rank\n\t *\n\t *\t@access public\n\t *\t@return Number of nonnegligible singular values.\n\t */\n\tpublic function rank() {\n\t\t$eps = pow(2.0, -52.0);\n\t\t$tol = max($this->m, $this->n) * $this->s[0] * $eps;\n\t\t$r = 0;\n\t\tfor ($i = 0; $i < count($this->s); ++$i) {\n\t\t\tif ($this->s[$i] > $tol) {\n\t\t\t\t++$r;\n\t\t\t}\n\t\t}\n\t\treturn $r;\n\t}\n\n}\t//\tclass SingularValueDecomposition\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/utils/Error.php",
    "content": "<?php\n/**\n *\t@package JAMA\n *\n *\tError handling\n *\t@author Michael Bommarito\n *\t@version 01292005\n */\n\n//Language constant\ndefine('JAMALANG', 'EN');\n\n\n//All errors may be defined by the following format:\n//define('ExceptionName', N);\n//$error['lang'][ExceptionName] = 'Error message';\n$error = array();\n\n/*\nI've used Babelfish and a little poor knowledge of Romance/Germanic languages for the translations here.\nFeel free to correct anything that looks amiss to you.\n*/\n\ndefine('PolymorphicArgumentException', -1);\n$error['EN'][PolymorphicArgumentException] = \"Invalid argument pattern for polymorphic function.\";\n$error['FR'][PolymorphicArgumentException] = \"Modèle inadmissible d'argument pour la fonction polymorphe.\".\n$error['DE'][PolymorphicArgumentException] = \"Unzulässiges Argumentmuster für polymorphe Funktion.\";\n\ndefine('ArgumentTypeException', -2);\n$error['EN'][ArgumentTypeException] = \"Invalid argument type.\";\n$error['FR'][ArgumentTypeException] = \"Type inadmissible d'argument.\";\n$error['DE'][ArgumentTypeException] = \"Unzulässige Argumentart.\";\n\ndefine('ArgumentBoundsException', -3);\n$error['EN'][ArgumentBoundsException] = \"Invalid argument range.\";\n$error['FR'][ArgumentBoundsException] = \"Gamme inadmissible d'argument.\";\n$error['DE'][ArgumentBoundsException] = \"Unzulässige Argumentstrecke.\";\n\ndefine('MatrixDimensionException', -4);\n$error['EN'][MatrixDimensionException] = \"Matrix dimensions are not equal.\";\n$error['FR'][MatrixDimensionException] = \"Les dimensions de Matrix ne sont pas égales.\";\n$error['DE'][MatrixDimensionException] = \"Matrixmaße sind nicht gleich.\";\n\ndefine('PrecisionLossException', -5);\n$error['EN'][PrecisionLossException] = \"Significant precision loss detected.\";\n$error['FR'][PrecisionLossException] = \"Perte significative de précision détectée.\";\n$error['DE'][PrecisionLossException] = \"Bedeutender Präzision Verlust ermittelte.\";\n\ndefine('MatrixSPDException', -6);\n$error['EN'][MatrixSPDException] = \"Can only perform operation on symmetric positive definite matrix.\";\n$error['FR'][MatrixSPDException] = \"Perte significative de précision détectée.\";\n$error['DE'][MatrixSPDException] = \"Bedeutender Präzision Verlust ermittelte.\";\n\ndefine('MatrixSingularException', -7);\n$error['EN'][MatrixSingularException] = \"Can only perform operation on singular matrix.\";\n\ndefine('MatrixRankException', -8);\n$error['EN'][MatrixRankException] = \"Can only perform operation on full-rank matrix.\";\n\ndefine('ArrayLengthException', -9);\n$error['EN'][ArrayLengthException] = \"Array length must be a multiple of m.\";\n\ndefine('RowLengthException', -10);\n$error['EN'][RowLengthException] = \"All rows must have the same length.\";\n\n/**\n *\tCustom error handler\n *\t@param int $num Error number\n */\nfunction JAMAError($errorNumber = null) {\n\tglobal $error;\n\n\tif (isset($errorNumber)) {\n\t\tif (isset($error[JAMALANG][$errorNumber])) {\n\t\t\treturn $error[JAMALANG][$errorNumber];\n\t\t} else {\n\t\t\treturn $error['EN'][$errorNumber];\n\t\t}\n\t} else {\n\t\treturn (\"Invalid argument to JAMAError()\");\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/JAMA/utils/Maths.php",
    "content": "<?php\n/**\n *\t@package JAMA\n *\n *\tPythagorean Theorem:\n *\n *\ta = 3\n *\tb = 4\n *\tr = sqrt(square(a) + square(b))\n *\tr = 5\n *\n *\tr = sqrt(a^2 + b^2) without under/overflow.\n */\nfunction hypo($a, $b) {\n\tif (abs($a) > abs($b)) {\n\t\t$r = $b / $a;\n\t\t$r = abs($a) * sqrt(1 + $r * $r);\n\t} elseif ($b != 0) {\n\t\t$r = $a / $b;\n\t\t$r = abs($b) * sqrt(1 + $r * $r);\n\t} else {\n\t\t$r = 0.0;\n\t}\n\treturn $r;\n}\t//\tfunction hypo()\n\n\n/**\n *\tMike Bommarito's version.\n *\tCompute n-dimensional hyotheneuse.\n *\nfunction hypot() {\n\t$s = 0;\n\tforeach (func_get_args() as $d) {\n\t\tif (is_numeric($d)) {\n\t\t\t$s += pow($d, 2);\n\t\t} else {\n\t\t\tthrow new PHPExcel_Calculation_Exception(JAMAError(ArgumentTypeException));\n\t\t}\n\t}\n\treturn sqrt($s);\n}\n*/\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/OLE/ChainedBlockStream.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_OLE\n * @copyright  Copyright (c) 2006 - 2007 Christian Schmidt\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version ##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Shared_OLE_ChainedBlockStream\n *\n * Stream wrapper for reading data stored in an OLE file. Implements methods\n * for PHP's stream_wrapper_register(). For creating streams using this\n * wrapper, use PHPExcel_Shared_OLE_PPS_File::getStream().\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_OLE\n */\nclass PHPExcel_Shared_OLE_ChainedBlockStream\n{\n\t/**\n\t * The OLE container of the file that is being read.\n\t * @var OLE\n\t */\n\tpublic $ole;\n\n\t/**\n\t * Parameters specified by fopen().\n\t * @var array\n\t */\n\tpublic $params;\n\n\t/**\n\t * The binary data of the file.\n\t * @var  string\n\t */\n\tpublic $data;\n\n\t/**\n\t * The file pointer.\n\t * @var  int  byte offset\n\t */\n\tpublic $pos;\n\n\t/**\n\t * Implements support for fopen().\n\t * For creating streams using this wrapper, use OLE_PPS_File::getStream().\n\t *\n\t * @param\tstring\t$path\t\t\tresource name including scheme, e.g.\n\t *\t\t\t\t\t\t\t\t\tole-chainedblockstream://oleInstanceId=1\n\t * @param\tstring\t$mode\t\t\tonly \"r\" is supported\n\t * @param\tint\t\t$options\t\tmask of STREAM_REPORT_ERRORS and STREAM_USE_PATH\n\t * @param\tstring  &$openedPath\tabsolute path of the opened stream (out parameter)\n\t * @return\tbool    true on success\n\t */\n\tpublic function stream_open($path, $mode, $options, &$openedPath)\n\t{\n\t\tif ($mode != 'r') {\n\t\t\tif ($options & STREAM_REPORT_ERRORS) {\n\t\t\t\ttrigger_error('Only reading is supported', E_USER_WARNING);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\n\t\t// 25 is length of \"ole-chainedblockstream://\"\n\t\tparse_str(substr($path, 25), $this->params);\n\t\tif (!isset($this->params['oleInstanceId'],\n\t\t\t\t   $this->params['blockId'],\n\t\t\t\t   $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']])) {\n\n\t\t\tif ($options & STREAM_REPORT_ERRORS) {\n\t\t\t\ttrigger_error('OLE stream not found', E_USER_WARNING);\n\t\t\t}\n\t\t\treturn false;\n\t\t}\n\t\t$this->ole = $GLOBALS['_OLE_INSTANCES'][$this->params['oleInstanceId']];\n\n\t\t$blockId = $this->params['blockId'];\n\t\t$this->data = '';\n\t\tif (isset($this->params['size']) &&\n\t\t\t$this->params['size'] < $this->ole->bigBlockThreshold &&\n\t\t\t$blockId != $this->ole->root->_StartBlock) {\n\n\t\t\t// Block id refers to small blocks\n\t\t\t$rootPos = $this->ole->_getBlockOffset($this->ole->root->_StartBlock);\n\t\t\twhile ($blockId != -2) {\n\t\t\t\t$pos = $rootPos + $blockId * $this->ole->bigBlockSize;\n\t\t\t\t$blockId = $this->ole->sbat[$blockId];\n\t\t\t\tfseek($this->ole->_file_handle, $pos);\n\t\t\t\t$this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize);\n\t\t\t}\n\t\t} else {\n\t\t\t// Block id refers to big blocks\n\t\t\twhile ($blockId != -2) {\n\t\t\t\t$pos = $this->ole->_getBlockOffset($blockId);\n\t\t\t\tfseek($this->ole->_file_handle, $pos);\n\t\t\t\t$this->data .= fread($this->ole->_file_handle, $this->ole->bigBlockSize);\n\t\t\t\t$blockId = $this->ole->bbat[$blockId];\n\t\t\t}\n\t\t}\n\t\tif (isset($this->params['size'])) {\n\t\t\t$this->data = substr($this->data, 0, $this->params['size']);\n\t\t}\n\n\t\tif ($options & STREAM_USE_PATH) {\n\t\t\t$openedPath = $path;\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * Implements support for fclose().\n\t *\n\t */\n\tpublic function stream_close()\n\t{\n\t\t$this->ole = null;\n\t\tunset($GLOBALS['_OLE_INSTANCES']);\n\t}\n\n\t/**\n\t * Implements support for fread(), fgets() etc.\n\t *\n\t * @param   int\t\t$count\tmaximum number of bytes to read\n\t * @return  string\n\t */\n\tpublic function stream_read($count)\n\t{\n\t\tif ($this->stream_eof()) {\n\t\t\treturn false;\n\t\t}\n\t\t$s = substr($this->data, $this->pos, $count);\n\t\t$this->pos += $count;\n\t\treturn $s;\n\t}\n\n\t/**\n\t * Implements support for feof().\n\t *\n\t * @return  bool  TRUE if the file pointer is at EOF; otherwise FALSE\n\t */\n\tpublic function stream_eof()\n\t{\n\t\treturn $this->pos >= strlen($this->data);\n\t}\n\n\t/**\n\t * Returns the position of the file pointer, i.e. its offset into the file\n\t * stream. Implements support for ftell().\n\t *\n\t * @return  int\n\t */\n\tpublic function stream_tell()\n\t{\n\t\treturn $this->pos;\n\t}\n\n\t/**\n\t * Implements support for fseek().\n\t *\n\t * @param\tint\t\t$offset\tbyte offset\n\t * @param\tint\t\t$whence\tSEEK_SET, SEEK_CUR or SEEK_END\n\t * @return\tbool\n\t */\n\tpublic function stream_seek($offset, $whence)\n\t{\n\t\tif ($whence == SEEK_SET && $offset >= 0) {\n\t\t\t$this->pos = $offset;\n\t\t} elseif ($whence == SEEK_CUR && -$offset <= $this->pos) {\n\t\t\t$this->pos += $offset;\n\t\t} elseif ($whence == SEEK_END && -$offset <= sizeof($this->data)) {\n\t\t\t$this->pos = strlen($this->data) + $offset;\n\t\t} else {\n\t\t\treturn false;\n\t\t}\n\t\treturn true;\n\t}\n\n\t/**\n\t * Implements support for fstat(). Currently the only supported field is\n\t * \"size\".\n\t * @return  array\n\t */\n\tpublic function stream_stat()\n\t{\n\t\treturn array(\n\t\t\t'size' => strlen($this->data),\n\t\t\t);\n\t}\n\n\t// Methods used by stream_wrapper_register() that are not implemented:\n\t// bool stream_flush ( void )\n\t// int stream_write ( string data )\n\t// bool rename ( string path_from, string path_to )\n\t// bool mkdir ( string path, int mode, int options )\n\t// bool rmdir ( string path, int options )\n\t// bool dir_opendir ( string path, int options )\n\t// array url_stat ( string path, int flags )\n\t// string dir_readdir ( void )\n\t// bool dir_rewinddir ( void )\n\t// bool dir_closedir ( void )\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/OLE/PPS/File.php",
    "content": "<?php\n/* vim: set expandtab tabstop=4 shiftwidth=4: */\n// +----------------------------------------------------------------------+\n// | PHP Version 4                                                        |\n// +----------------------------------------------------------------------+\n// | Copyright (c) 1997-2002 The PHP Group                                |\n// +----------------------------------------------------------------------+\n// | This source file is subject to version 2.02 of the PHP license,      |\n// | that is bundled with this package in the file LICENSE, and is        |\n// | available at through the world-wide-web at                           |\n// | http://www.php.net/license/2_02.txt.                                 |\n// | If you did not receive a copy of the PHP license and are unable to   |\n// | obtain it through the world-wide-web, please send a note to          |\n// | license@php.net so we can mail you a copy immediately.               |\n// +----------------------------------------------------------------------+\n// | Author: Xavier Noguer <xnoguer@php.net>                              |\n// | Based on OLE::Storage_Lite by Kawai, Takanori                        |\n// +----------------------------------------------------------------------+\n//\n// $Id: File.php,v 1.11 2007/02/13 21:00:42 schmidt Exp $\n\n\n/**\n* Class for creating File PPS's for OLE containers\n*\n* @author   Xavier Noguer <xnoguer@php.net>\n* @category PHPExcel\n* @package  PHPExcel_Shared_OLE\n*/\nclass PHPExcel_Shared_OLE_PPS_File extends PHPExcel_Shared_OLE_PPS\n\t{\n\t/**\n\t* The constructor\n\t*\n\t* @access public\n\t* @param string $name The name of the file (in Unicode)\n\t* @see OLE::Asc2Ucs()\n\t*/\n\tpublic function __construct($name)\n\t{\n\t\tparent::__construct(\n\t\t\tnull,\n\t\t\t$name,\n\t\t\tPHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE,\n\t\t\tnull,\n\t\t\tnull,\n\t\t\tnull,\n\t\t\tnull,\n\t\t\tnull,\n\t\t\t'',\n\t\t\tarray());\n\t}\n\n\t/**\n\t* Initialization method. Has to be called right after OLE_PPS_File().\n\t*\n\t* @access public\n\t* @return mixed true on success\n\t*/\n\tpublic function init()\n\t{\n\t\treturn true;\n\t}\n\n\t/**\n\t* Append data to PPS\n\t*\n\t* @access public\n\t* @param string $data The data to append\n\t*/\n\tpublic function append($data)\n\t{\n\t\t$this->_data .= $data;\n\t}\n\n\t/**\n\t * Returns a stream for reading this file using fread() etc.\n\t * @return  resource  a read-only stream\n\t */\n\tpublic function getStream()\n\t{\n\t\t$this->ole->getStream($this);\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/OLE/PPS/Root.php",
    "content": "<?php\n/* vim: set expandtab tabstop=4 shiftwidth=4: */\n// +----------------------------------------------------------------------+\n// | PHP Version 4                                                        |\n// +----------------------------------------------------------------------+\n// | Copyright (c) 1997-2002 The PHP Group                                |\n// +----------------------------------------------------------------------+\n// | This source file is subject to version 2.02 of the PHP license,      |\n// | that is bundled with this package in the file LICENSE, and is        |\n// | available at through the world-wide-web at                           |\n// | http://www.php.net/license/2_02.txt.                                 |\n// | If you did not receive a copy of the PHP license and are unable to   |\n// | obtain it through the world-wide-web, please send a note to          |\n// | license@php.net so we can mail you a copy immediately.               |\n// +----------------------------------------------------------------------+\n// | Author: Xavier Noguer <xnoguer@php.net>                              |\n// | Based on OLE::Storage_Lite by Kawai, Takanori                        |\n// +----------------------------------------------------------------------+\n//\n// $Id: Root.php,v 1.9 2005/04/23 21:53:49 dufuz Exp $\n\n\n/**\n* Class for creating Root PPS's for OLE containers\n*\n* @author   Xavier Noguer <xnoguer@php.net>\n* @category PHPExcel\n* @package  PHPExcel_Shared_OLE\n*/\nclass PHPExcel_Shared_OLE_PPS_Root extends PHPExcel_Shared_OLE_PPS\n\t{\n\n\t/**\n\t * Directory for temporary files\n\t * @var string\n\t */\n\tprotected $_tmp_dir\t\t= NULL;\n\n\t/**\n\t * @param integer $time_1st A timestamp\n\t * @param integer $time_2nd A timestamp\n\t */\n\tpublic function __construct($time_1st, $time_2nd, $raChild)\n\t{\n\t\t$this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir();\n\n\t\tparent::__construct(\n\t\t   null,\n\t\t   PHPExcel_Shared_OLE::Asc2Ucs('Root Entry'),\n\t\t   PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT,\n\t\t   null,\n\t\t   null,\n\t\t   null,\n\t\t   $time_1st,\n\t\t   $time_2nd,\n\t\t   null,\n\t\t   $raChild);\n\t}\n\n\t/**\n\t* Method for saving the whole OLE container (including files).\n\t* In fact, if called with an empty argument (or '-'), it saves to a\n\t* temporary file and then outputs it's contents to stdout.\n\t* If a resource pointer to a stream created by fopen() is passed\n\t* it will be used, but you have to close such stream by yourself.\n\t*\n\t* @param string|resource $filename The name of the file or stream where to save the OLE container.\n\t* @access public\n\t* @return mixed true on success\n\t*/\n\tpublic function save($filename)\n\t{\n\t\t// Initial Setting for saving\n\t\t$this->_BIG_BLOCK_SIZE  = pow(2,\n\t\t\t\t\t  ((isset($this->_BIG_BLOCK_SIZE))? self::_adjust2($this->_BIG_BLOCK_SIZE)  : 9));\n\t\t$this->_SMALL_BLOCK_SIZE= pow(2,\n\t\t\t\t\t  ((isset($this->_SMALL_BLOCK_SIZE))?  self::_adjust2($this->_SMALL_BLOCK_SIZE): 6));\n\n\t\tif (is_resource($filename)) {\n\t\t    $this->_FILEH_ = $filename;\n\t\t} else if ($filename == '-' || $filename == '') {\r\n\t\t\tif ($this->_tmp_dir === NULL)\r\n\t\t\t\t$this->_tmp_dir = PHPExcel_Shared_File::sys_get_temp_dir();\r\n\t\t\t$this->_tmp_filename = tempnam($this->_tmp_dir, \"OLE_PPS_Root\");\r\n\t\t\t$this->_FILEH_ = fopen($this->_tmp_filename,\"w+b\");\r\n\t\t\tif ($this->_FILEH_ == false) {\r\n\t\t\t\tthrow new PHPExcel_Writer_Exception(\"Can't create temporary file.\");\r\n\t\t\t}\n\t\t} else {\n\t\t\t$this->_FILEH_ = fopen($filename, \"wb\");\n\t\t}\n\t\tif ($this->_FILEH_ == false) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Can't open $filename. It may be in use or protected.\");\n\t\t}\n\t\t// Make an array of PPS's (for Save)\n\t\t$aList = array();\n\t\tPHPExcel_Shared_OLE_PPS::_savePpsSetPnt($aList, array($this));\r\n\t\t// calculate values for header\n\t\tlist($iSBDcnt, $iBBcnt, $iPPScnt) = $this->_calcSize($aList); //, $rhInfo);\n\t\t// Save Header\n\t\t$this->_saveHeader($iSBDcnt, $iBBcnt, $iPPScnt);\n\n\t\t// Make Small Data string (write SBD)\n\t\t$this->_data = $this->_makeSmallData($aList);\n\n\t\t// Write BB\n\t\t$this->_saveBigData($iSBDcnt, $aList);\n\t\t// Write PPS\n\t\t$this->_savePps($aList);\n\t\t// Write Big Block Depot and BDList and Adding Header informations\n\t\t$this->_saveBbd($iSBDcnt, $iBBcnt, $iPPScnt);\n\n\t\tif (!is_resource($filename)) {\n \t\t\tfclose($this->_FILEH_);\n \t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t* Calculate some numbers\n\t*\n\t* @access public\n\t* @param array $raList Reference to an array of PPS's\n\t* @return array The array of numbers\n\t*/\n\tpublic function _calcSize(&$raList)\n\t{\n\t\t// Calculate Basic Setting\n\t\tlist($iSBDcnt, $iBBcnt, $iPPScnt) = array(0,0,0);\n\t\t$iSmallLen = 0;\n\t\t$iSBcnt = 0;\n\t\t$iCount = count($raList);\n\t\tfor ($i = 0; $i < $iCount; ++$i) {\n\t\t\tif ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) {\n\t\t\t\t$raList[$i]->Size = $raList[$i]->_DataLen();\n\t\t\t\tif ($raList[$i]->Size < PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) {\n\t\t\t\t\t$iSBcnt += floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)\n\t\t\t\t\t\t\t\t  + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);\n\t\t\t\t} else {\n\t\t\t\t\t$iBBcnt += (floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +\n\t\t\t\t\t\t(($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t$iSmallLen = $iSBcnt * $this->_SMALL_BLOCK_SIZE;\n\t\t$iSlCnt = floor($this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE);\n\t\t$iSBDcnt = floor($iSBcnt / $iSlCnt) + (($iSBcnt % $iSlCnt)? 1:0);\n\t\t$iBBcnt +=  (floor($iSmallLen / $this->_BIG_BLOCK_SIZE) +\n\t\t\t\t\t  (( $iSmallLen % $this->_BIG_BLOCK_SIZE)? 1: 0));\n\t\t$iCnt = count($raList);\n\t\t$iBdCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE;\n\t\t$iPPScnt = (floor($iCnt/$iBdCnt) + (($iCnt % $iBdCnt)? 1: 0));\n\n\t\treturn array($iSBDcnt, $iBBcnt, $iPPScnt);\n\t}\n\n\t/**\n\t* Helper function for caculating a magic value for block sizes\n\t*\n\t* @access public\n\t* @param integer $i2 The argument\n\t* @see save()\n\t* @return integer\n\t*/\n\tprivate static function _adjust2($i2)\n\t{\n\t\t$iWk = log($i2)/log(2);\n\t\treturn ($iWk > floor($iWk))? floor($iWk)+1:$iWk;\n\t}\n\n\t/**\n\t* Save OLE header\n\t*\n\t* @access public\n\t* @param integer $iSBDcnt\n\t* @param integer $iBBcnt\n\t* @param integer $iPPScnt\n\t*/\n\tpublic function _saveHeader($iSBDcnt, $iBBcnt, $iPPScnt)\n\t{\n\t\t$FILE = $this->_FILEH_;\n\n\t\t// Calculate Basic Setting\n\t\t$iBlCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE;\n\t\t$i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE;\n\n\t\t$iBdExL = 0;\n\t\t$iAll = $iBBcnt + $iPPScnt + $iSBDcnt;\n\t\t$iAllW = $iAll;\n\t\t$iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);\n\t\t$iBdCnt = floor(($iAll + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);\n\n\t\t// Calculate BD count\n\t\tif ($iBdCnt > $i1stBdL) {\n\t\t\twhile (1) {\n\t\t\t\t++$iBdExL;\n\t\t\t\t++$iAllW;\n\t\t\t\t$iBdCntW = floor($iAllW / $iBlCnt) + (($iAllW % $iBlCnt)? 1: 0);\n\t\t\t\t$iBdCnt = floor(($iAllW + $iBdCntW) / $iBlCnt) + ((($iAllW+$iBdCntW) % $iBlCnt)? 1: 0);\n\t\t\t\tif ($iBdCnt <= ($iBdExL*$iBlCnt+ $i1stBdL)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Save Header\n\t\tfwrite($FILE,\n\t\t\t\t\"\\xD0\\xCF\\x11\\xE0\\xA1\\xB1\\x1A\\xE1\"\n\t\t\t\t. \"\\x00\\x00\\x00\\x00\"\n\t\t\t\t. \"\\x00\\x00\\x00\\x00\"\n\t\t\t\t. \"\\x00\\x00\\x00\\x00\"\n\t\t\t\t. \"\\x00\\x00\\x00\\x00\"\n\t\t\t\t. pack(\"v\", 0x3b)\n\t\t\t\t. pack(\"v\", 0x03)\n\t\t\t\t. pack(\"v\", -2)\n\t\t\t\t. pack(\"v\", 9)\n\t\t\t\t. pack(\"v\", 6)\n\t\t\t\t. pack(\"v\", 0)\n\t\t\t\t. \"\\x00\\x00\\x00\\x00\"\n\t\t\t\t. \"\\x00\\x00\\x00\\x00\"\n\t\t\t\t. pack(\"V\", $iBdCnt)\n\t\t\t\t. pack(\"V\", $iBBcnt+$iSBDcnt) //ROOT START\n\t\t\t\t. pack(\"V\", 0)\n\t\t\t\t. pack(\"V\", 0x1000)\n\t\t\t\t. pack(\"V\", $iSBDcnt ? 0 : -2)                  //Small Block Depot\n\t\t\t\t. pack(\"V\", $iSBDcnt)\n\t\t  );\n\t\t// Extra BDList Start, Count\n\t\tif ($iBdCnt < $i1stBdL) {\n\t\t\tfwrite($FILE,\n\t\t\t\t\tpack(\"V\", -2)      // Extra BDList Start\n\t\t\t\t\t. pack(\"V\", 0)        // Extra BDList Count\n\t\t\t\t  );\n\t\t} else {\n\t\t\tfwrite($FILE, pack(\"V\", $iAll+$iBdCnt) . pack(\"V\", $iBdExL));\n\t\t}\n\n\t\t// BDList\n\t\tfor ($i = 0; $i < $i1stBdL && $i < $iBdCnt; ++$i) {\n\t\t\tfwrite($FILE, pack(\"V\", $iAll+$i));\n\t\t}\n\t\tif ($i < $i1stBdL) {\n\t\t\t$jB = $i1stBdL - $i;\n\t\t\tfor ($j = 0; $j < $jB; ++$j) {\n\t\t\t\tfwrite($FILE, (pack(\"V\", -1)));\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t* Saving big data (PPS's with data bigger than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL)\n\t*\n\t* @access public\n\t* @param integer $iStBlk\n\t* @param array &$raList Reference to array of PPS's\n\t*/\n\tpublic function _saveBigData($iStBlk, &$raList)\n\t{\n\t\t$FILE = $this->_FILEH_;\n\n\t\t// cycle through PPS's\n\t\t$iCount = count($raList);\n\t\tfor ($i = 0; $i < $iCount; ++$i) {\n\t\t\tif ($raList[$i]->Type != PHPExcel_Shared_OLE::OLE_PPS_TYPE_DIR) {\n\t\t\t\t$raList[$i]->Size = $raList[$i]->_DataLen();\n\t\t\t\tif (($raList[$i]->Size >= PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) ||\n\t\t\t\t\t(($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_ROOT) && isset($raList[$i]->_data)))\n\t\t\t\t{\n\t\t\t\t\t// Write Data\n\t\t\t\t\t//if (isset($raList[$i]->_PPS_FILE)) {\n\t\t\t\t\t//\t$iLen = 0;\n\t\t\t\t\t//\tfseek($raList[$i]->_PPS_FILE, 0); // To The Top\n\t\t\t\t\t//\twhile($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {\n\t\t\t\t\t//\t\t$iLen += strlen($sBuff);\n\t\t\t\t\t//\t\tfwrite($FILE, $sBuff);\n\t\t\t\t\t//\t}\n\t\t\t\t\t//} else {\n\t\t\t\t\t\tfwrite($FILE, $raList[$i]->_data);\n\t\t\t\t\t//}\n\n\t\t\t\t\tif ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE) {\n\t\t\t\t\t\tfwrite($FILE, str_repeat(\"\\x00\", $this->_BIG_BLOCK_SIZE - ($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)));\n\t\t\t\t\t}\n\t\t\t\t\t// Set For PPS\n\t\t\t\t\t$raList[$i]->_StartBlock = $iStBlk;\n\t\t\t\t\t$iStBlk +=\n\t\t\t\t\t\t\t(floor($raList[$i]->Size / $this->_BIG_BLOCK_SIZE) +\n\t\t\t\t\t\t\t\t(($raList[$i]->Size % $this->_BIG_BLOCK_SIZE)? 1: 0));\n\t\t\t\t}\n\t\t\t\t// Close file for each PPS, and unlink it\n\t\t\t\t//if (isset($raList[$i]->_PPS_FILE)) {\n\t\t\t\t//\tfclose($raList[$i]->_PPS_FILE);\n\t\t\t\t//\t$raList[$i]->_PPS_FILE = null;\n\t\t\t\t//\tunlink($raList[$i]->_tmp_filename);\n\t\t\t\t//}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t* get small data (PPS's with data smaller than PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL)\n\t*\n\t* @access public\n\t* @param array &$raList Reference to array of PPS's\n\t*/\n\tpublic function _makeSmallData(&$raList)\n\t{\n\t\t$sRes = '';\n\t\t$FILE = $this->_FILEH_;\n\t\t$iSmBlk = 0;\n\n\t\t$iCount = count($raList);\n\t\tfor ($i = 0; $i < $iCount; ++$i) {\n\t\t\t// Make SBD, small data string\n\t\t\tif ($raList[$i]->Type == PHPExcel_Shared_OLE::OLE_PPS_TYPE_FILE) {\n\t\t\t\tif ($raList[$i]->Size <= 0) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tif ($raList[$i]->Size < PHPExcel_Shared_OLE::OLE_DATA_SIZE_SMALL) {\n\t\t\t\t\t$iSmbCnt = floor($raList[$i]->Size / $this->_SMALL_BLOCK_SIZE)\n\t\t\t\t\t\t\t\t  + (($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE)? 1: 0);\n\t\t\t\t\t// Add to SBD\n\t\t\t\t\t$jB = $iSmbCnt - 1;\n\t\t\t\t\tfor ($j = 0; $j < $jB; ++$j) {\n\t\t\t\t\t\tfwrite($FILE, pack(\"V\", $j+$iSmBlk+1));\n\t\t\t\t\t}\n\t\t\t\t\tfwrite($FILE, pack(\"V\", -2));\n\n\t\t\t\t\t//// Add to Data String(this will be written for RootEntry)\n\t\t\t\t\t//if ($raList[$i]->_PPS_FILE) {\n\t\t\t\t\t//\tfseek($raList[$i]->_PPS_FILE, 0); // To The Top\n\t\t\t\t\t//\twhile ($sBuff = fread($raList[$i]->_PPS_FILE, 4096)) {\n\t\t\t\t\t//\t\t$sRes .= $sBuff;\n\t\t\t\t\t//\t}\n\t\t\t\t\t//} else {\n\t\t\t\t\t\t$sRes .= $raList[$i]->_data;\n\t\t\t\t\t//}\n\t\t\t\t\tif ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE) {\n\t\t\t\t\t\t$sRes .= str_repeat(\"\\x00\",$this->_SMALL_BLOCK_SIZE - ($raList[$i]->Size % $this->_SMALL_BLOCK_SIZE));\n\t\t\t\t\t}\n\t\t\t\t\t// Set for PPS\n\t\t\t\t\t$raList[$i]->_StartBlock = $iSmBlk;\n\t\t\t\t\t$iSmBlk += $iSmbCnt;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t$iSbCnt = floor($this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE);\n\t\tif ($iSmBlk % $iSbCnt) {\n\t\t\t$iB = $iSbCnt - ($iSmBlk % $iSbCnt);\n\t\t\tfor ($i = 0; $i < $iB; ++$i) {\n\t\t\t\tfwrite($FILE, pack(\"V\", -1));\n\t\t\t}\n\t\t}\n\t\treturn $sRes;\n\t}\n\n\t/**\n\t* Saves all the PPS's WKs\n\t*\n\t* @access public\n\t* @param array $raList Reference to an array with all PPS's\n\t*/\n\tpublic function _savePps(&$raList)\n\t{\n\t\t// Save each PPS WK\n\t\t$iC = count($raList);\n\t\tfor ($i = 0; $i < $iC; ++$i) {\n\t\t\tfwrite($this->_FILEH_, $raList[$i]->_getPpsWk());\n\t\t}\n\t\t// Adjust for Block\n\t\t$iCnt = count($raList);\n\t\t$iBCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_PPS_SIZE;\n\t\tif ($iCnt % $iBCnt) {\n\t\t\tfwrite($this->_FILEH_, str_repeat(\"\\x00\",($iBCnt - ($iCnt % $iBCnt)) * PHPExcel_Shared_OLE::OLE_PPS_SIZE));\n\t\t}\n\t}\n\n\t/**\n\t* Saving Big Block Depot\n\t*\n\t* @access public\n\t* @param integer $iSbdSize\n\t* @param integer $iBsize\n\t* @param integer $iPpsCnt\n\t*/\n\tpublic function _saveBbd($iSbdSize, $iBsize, $iPpsCnt)\n\t{\n\t\t$FILE = $this->_FILEH_;\n\t\t// Calculate Basic Setting\n\t\t$iBbCnt = $this->_BIG_BLOCK_SIZE / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE;\n\t\t$i1stBdL = ($this->_BIG_BLOCK_SIZE - 0x4C) / PHPExcel_Shared_OLE::OLE_LONG_INT_SIZE;\n\n\t\t$iBdExL = 0;\n\t\t$iAll = $iBsize + $iPpsCnt + $iSbdSize;\n\t\t$iAllW = $iAll;\n\t\t$iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);\n\t\t$iBdCnt = floor(($iAll + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);\n\t\t// Calculate BD count\n\t\tif ($iBdCnt >$i1stBdL) {\n\t\t\twhile (1) {\n\t\t\t\t++$iBdExL;\n\t\t\t\t++$iAllW;\n\t\t\t\t$iBdCntW = floor($iAllW / $iBbCnt) + (($iAllW % $iBbCnt)? 1: 0);\n\t\t\t\t$iBdCnt = floor(($iAllW + $iBdCntW) / $iBbCnt) + ((($iAllW+$iBdCntW) % $iBbCnt)? 1: 0);\n\t\t\t\tif ($iBdCnt <= ($iBdExL*$iBbCnt+ $i1stBdL)) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Making BD\n\t\t// Set for SBD\n\t\tif ($iSbdSize > 0) {\n\t\t\tfor ($i = 0; $i < ($iSbdSize - 1); ++$i) {\n\t\t\t\tfwrite($FILE, pack(\"V\", $i+1));\n\t\t\t}\n\t\t\tfwrite($FILE, pack(\"V\", -2));\n\t\t}\n\t\t// Set for B\n\t\tfor ($i = 0; $i < ($iBsize - 1); ++$i) {\n\t\t\tfwrite($FILE, pack(\"V\", $i+$iSbdSize+1));\n\t\t}\n\t\tfwrite($FILE, pack(\"V\", -2));\n\n\t\t// Set for PPS\n\t\tfor ($i = 0; $i < ($iPpsCnt - 1); ++$i) {\n\t\t\tfwrite($FILE, pack(\"V\", $i+$iSbdSize+$iBsize+1));\n\t\t}\n\t\tfwrite($FILE, pack(\"V\", -2));\n\t\t// Set for BBD itself ( 0xFFFFFFFD : BBD)\n\t\tfor ($i = 0; $i < $iBdCnt; ++$i) {\n\t\t\tfwrite($FILE, pack(\"V\", 0xFFFFFFFD));\n\t\t}\n\t\t// Set for ExtraBDList\n\t\tfor ($i = 0; $i < $iBdExL; ++$i) {\n\t\t\tfwrite($FILE, pack(\"V\", 0xFFFFFFFC));\n\t\t}\n\t\t// Adjust for Block\n\t\tif (($iAllW + $iBdCnt) % $iBbCnt) {\n\t\t\t$iBlock = ($iBbCnt - (($iAllW + $iBdCnt) % $iBbCnt));\n\t\t\tfor ($i = 0; $i < $iBlock; ++$i) {\n\t\t\t\tfwrite($FILE, pack(\"V\", -1));\n\t\t\t}\n\t\t}\n\t\t// Extra BDList\n\t\tif ($iBdCnt > $i1stBdL) {\n\t\t\t$iN=0;\n\t\t\t$iNb=0;\n\t\t\tfor ($i = $i1stBdL;$i < $iBdCnt; $i++, ++$iN) {\n\t\t\t\tif ($iN >= ($iBbCnt - 1)) {\n\t\t\t\t\t$iN = 0;\n\t\t\t\t\t++$iNb;\n\t\t\t\t\tfwrite($FILE, pack(\"V\", $iAll+$iBdCnt+$iNb));\n\t\t\t\t}\n\t\t\t\tfwrite($FILE, pack(\"V\", $iBsize+$iSbdSize+$iPpsCnt+$i));\n\t\t\t}\n\t\t\tif (($iBdCnt-$i1stBdL) % ($iBbCnt-1)) {\n\t\t\t\t$iB = ($iBbCnt - 1) - (($iBdCnt - $i1stBdL) % ($iBbCnt - 1));\n\t\t\t\tfor ($i = 0; $i < $iB; ++$i) {\n\t\t\t\t\tfwrite($FILE, pack(\"V\", -1));\n\t\t\t\t}\n\t\t\t}\n\t\t\tfwrite($FILE, pack(\"V\", -2));\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/OLE/PPS.php",
    "content": "<?php\n/* vim: set expandtab tabstop=4 shiftwidth=4: */\n// +----------------------------------------------------------------------+\n// | PHP Version 4                                                        |\n// +----------------------------------------------------------------------+\n// | Copyright (c) 1997-2002 The PHP Group                                |\n// +----------------------------------------------------------------------+\n// | This source file is subject to version 2.02 of the PHP license,      |\n// | that is bundled with this package in the file LICENSE, and is        |\n// | available at through the world-wide-web at                           |\n// | http://www.php.net/license/2_02.txt.                                 |\n// | If you did not receive a copy of the PHP license and are unable to   |\n// | obtain it through the world-wide-web, please send a note to          |\n// | license@php.net so we can mail you a copy immediately.               |\n// +----------------------------------------------------------------------+\n// | Author: Xavier Noguer <xnoguer@php.net>                              |\n// | Based on OLE::Storage_Lite by Kawai, Takanori                        |\n// +----------------------------------------------------------------------+\n//\n// $Id: PPS.php,v 1.7 2007/02/13 21:00:42 schmidt Exp $\n\n\n/**\n* Class for creating PPS's for OLE containers\n*\n* @author   Xavier Noguer <xnoguer@php.net>\n* @category PHPExcel\n* @package  PHPExcel_Shared_OLE\n*/\nclass PHPExcel_Shared_OLE_PPS\n{\n\t/**\n\t* The PPS index\n\t* @var integer\n\t*/\n\tpublic $No;\n\n\t/**\n\t* The PPS name (in Unicode)\n\t* @var string\n\t*/\n\tpublic $Name;\n\n\t/**\n\t* The PPS type. Dir, Root or File\n\t* @var integer\n\t*/\n\tpublic $Type;\n\n\t/**\n\t* The index of the previous PPS\n\t* @var integer\n\t*/\n\tpublic $PrevPps;\n\n\t/**\n\t* The index of the next PPS\n\t* @var integer\n\t*/\n\tpublic $NextPps;\n\n\t/**\n\t* The index of it's first child if this is a Dir or Root PPS\n\t* @var integer\n\t*/\n\tpublic $DirPps;\n\n\t/**\n\t* A timestamp\n\t* @var integer\n\t*/\n\tpublic $Time1st;\n\n\t/**\n\t* A timestamp\n\t* @var integer\n\t*/\n\tpublic $Time2nd;\n\n\t/**\n\t* Starting block (small or big) for this PPS's data  inside the container\n\t* @var integer\n\t*/\n\tpublic $_StartBlock;\n\n\t/**\n\t* The size of the PPS's data (in bytes)\n\t* @var integer\n\t*/\n\tpublic $Size;\n\n\t/**\n\t* The PPS's data (only used if it's not using a temporary file)\n\t* @var string\n\t*/\n\tpublic $_data;\n\n\t/**\n\t* Array of child PPS's (only used by Root and Dir PPS's)\n\t* @var array\n\t*/\n\tpublic $children = array();\n\n\t/**\n\t* Pointer to OLE container\n\t* @var OLE\n\t*/\n\tpublic $ole;\n\n\t/**\n\t* The constructor\n\t*\n\t* @access public\n\t* @param integer $No   The PPS index\n\t* @param string  $name The PPS name\n\t* @param integer $type The PPS type. Dir, Root or File\n\t* @param integer $prev The index of the previous PPS\n\t* @param integer $next The index of the next PPS\n\t* @param integer $dir  The index of it's first child if this is a Dir or Root PPS\n\t* @param integer $time_1st A timestamp\n\t* @param integer $time_2nd A timestamp\n\t* @param string  $data  The (usually binary) source data of the PPS\n\t* @param array   $children Array containing children PPS for this PPS\n\t*/\n\tpublic function __construct($No, $name, $type, $prev, $next, $dir, $time_1st, $time_2nd, $data, $children)\n\t{\n\t\t$this->No      = $No;\n\t\t$this->Name    = $name;\n\t\t$this->Type    = $type;\n\t\t$this->PrevPps = $prev;\n\t\t$this->NextPps = $next;\n\t\t$this->DirPps  = $dir;\n\t\t$this->Time1st = $time_1st;\n\t\t$this->Time2nd = $time_2nd;\n\t\t$this->_data      = $data;\n\t\t$this->children   = $children;\n\t\tif ($data != '') {\n\t\t\t$this->Size = strlen($data);\n\t\t} else {\n\t\t\t$this->Size = 0;\n\t\t}\n\t}\n\n\t/**\n\t* Returns the amount of data saved for this PPS\n\t*\n\t* @access public\n\t* @return integer The amount of data (in bytes)\n\t*/\n\tpublic function _DataLen()\n\t{\n\t\tif (!isset($this->_data)) {\n\t\t\treturn 0;\n\t\t}\n\t\t//if (isset($this->_PPS_FILE)) {\n\t\t//\tfseek($this->_PPS_FILE, 0);\n\t\t//\t$stats = fstat($this->_PPS_FILE);\n\t\t//\treturn $stats[7];\n\t\t//} else {\n\t\t\treturn strlen($this->_data);\n\t\t//}\n\t}\n\n\t/**\n\t* Returns a string with the PPS's WK (What is a WK?)\n\t*\n\t* @access public\n\t* @return string The binary string\n\t*/\n\tpublic function _getPpsWk()\n\t{\n\t\t$ret = str_pad($this->Name,64,\"\\x00\");\n\n\t\t$ret .= pack(\"v\", strlen($this->Name) + 2)  // 66\n\t\t\t  . pack(\"c\", $this->Type)              // 67\n\t\t\t  . pack(\"c\", 0x00) //UK                // 68\n\t\t\t  . pack(\"V\", $this->PrevPps) //Prev    // 72\n\t\t\t  . pack(\"V\", $this->NextPps) //Next    // 76\n\t\t\t  . pack(\"V\", $this->DirPps)  //Dir     // 80\n\t\t\t  . \"\\x00\\x09\\x02\\x00\"                  // 84\n\t\t\t  . \"\\x00\\x00\\x00\\x00\"                  // 88\n\t\t\t  . \"\\xc0\\x00\\x00\\x00\"                  // 92\n\t\t\t  . \"\\x00\\x00\\x00\\x46\"                  // 96 // Seems to be ok only for Root\n\t\t\t  . \"\\x00\\x00\\x00\\x00\"                  // 100\n\t\t\t  . PHPExcel_Shared_OLE::LocalDate2OLE($this->Time1st)       // 108\n\t\t\t  . PHPExcel_Shared_OLE::LocalDate2OLE($this->Time2nd)       // 116\n\t\t\t  . pack(\"V\", isset($this->_StartBlock)?\n\t\t\t\t\t\t$this->_StartBlock:0)        // 120\n\t\t\t  . pack(\"V\", $this->Size)               // 124\n\t\t\t  . pack(\"V\", 0);                        // 128\n\t\treturn $ret;\n\t}\n\n\t/**\n\t* Updates index and pointers to previous, next and children PPS's for this\n\t* PPS. I don't think it'll work with Dir PPS's.\n\t*\n\t* @access public\n\t* @param array &$raList Reference to the array of PPS's for the whole OLE\n\t*                          container\n\t* @return integer          The index for this PPS\n\t*/\n\tpublic static function _savePpsSetPnt(&$raList, $to_save, $depth = 0)\n\t{\n\t\tif ( !is_array($to_save) || (empty($to_save)) ) {\n\t\t\treturn 0xFFFFFFFF;\n\t\t} elseif( count($to_save) == 1 ) {\n\t\t\t$cnt = count($raList);\n\t\t\t// If the first entry, it's the root... Don't clone it!\n\t\t\t$raList[$cnt] = ( $depth == 0 ) ? $to_save[0] : clone $to_save[0];\n\t\t\t$raList[$cnt]->No = $cnt;\n\t\t\t$raList[$cnt]->PrevPps = 0xFFFFFFFF;\n\t\t\t$raList[$cnt]->NextPps = 0xFFFFFFFF;\n\t\t\t$raList[$cnt]->DirPps  = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++);\n\t\t} else {\n\t\t\t$iPos  = floor(count($to_save) / 2);\n\t\t\t$aPrev = array_slice($to_save, 0, $iPos);\n\t\t\t$aNext = array_slice($to_save, $iPos + 1);\n\t\t\t$cnt   = count($raList);\n\t\t\t// If the first entry, it's the root... Don't clone it!\n\t\t\t$raList[$cnt] = ( $depth == 0 ) ? $to_save[$iPos] : clone $to_save[$iPos];\n\t\t\t$raList[$cnt]->No = $cnt;\n\t\t\t$raList[$cnt]->PrevPps = self::_savePpsSetPnt($raList, $aPrev, $depth++);\n\t\t\t$raList[$cnt]->NextPps = self::_savePpsSetPnt($raList, $aNext, $depth++);\n\t\t\t$raList[$cnt]->DirPps  = self::_savePpsSetPnt($raList, @$raList[$cnt]->children, $depth++);\n\n\t\t}\n\t\treturn $cnt;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/OLE.php",
    "content": "<?php\n/* vim: set expandtab tabstop=4 shiftwidth=4: */\n// +----------------------------------------------------------------------+\n// | PHP Version 4                                                        |\n// +----------------------------------------------------------------------+\n// | Copyright (c) 1997-2002 The PHP Group                                |\n// +----------------------------------------------------------------------+\n// | This source file is subject to version 2.02 of the PHP license,      |\n// | that is bundled with this package in the file LICENSE, and is        |\n// | available at through the world-wide-web at                           |\n// | http://www.php.net/license/2_02.txt.                                 |\n// | If you did not receive a copy of the PHP license and are unable to   |\n// | obtain it through the world-wide-web, please send a note to          |\n// | license@php.net so we can mail you a copy immediately.               |\n// +----------------------------------------------------------------------+\n// | Author: Xavier Noguer <xnoguer@php.net>                              |\n// | Based on OLE::Storage_Lite by Kawai, Takanori                        |\n// +----------------------------------------------------------------------+\n//\n// $Id: OLE.php,v 1.13 2007/03/07 14:38:25 schmidt Exp $\n\n\n/**\n* Array for storing OLE instances that are accessed from\n* OLE_ChainedBlockStream::stream_open().\n* @var  array\n*/\n$GLOBALS['_OLE_INSTANCES'] = array();\n\n/**\n* OLE package base class.\n*\n* @author   Xavier Noguer <xnoguer@php.net>\n* @author   Christian Schmidt <schmidt@php.net>\n* @category   PHPExcel\n* @package    PHPExcel_Shared_OLE\n*/\nclass PHPExcel_Shared_OLE\n{\n\tconst OLE_PPS_TYPE_ROOT   =      5;\n\tconst OLE_PPS_TYPE_DIR    =      1;\n\tconst OLE_PPS_TYPE_FILE   =      2;\n\tconst OLE_DATA_SIZE_SMALL = 0x1000;\n\tconst OLE_LONG_INT_SIZE   =      4;\n\tconst OLE_PPS_SIZE        =   0x80;\n\n\t/**\n\t * The file handle for reading an OLE container\n\t * @var resource\n\t*/\n\tpublic $_file_handle;\n\n\t/**\n\t* Array of PPS's found on the OLE container\n\t* @var array\n\t*/\n\tpublic $_list = array();\n\n\t/**\n\t * Root directory of OLE container\n\t * @var OLE_PPS_Root\n\t*/\n\tpublic $root;\n\n\t/**\n\t * Big Block Allocation Table\n\t * @var array  (blockId => nextBlockId)\n\t*/\n\tpublic $bbat;\n\n\t/**\n\t * Short Block Allocation Table\n\t * @var array  (blockId => nextBlockId)\n\t*/\n\tpublic $sbat;\n\n\t/**\n\t * Size of big blocks. This is usually 512.\n\t * @var  int  number of octets per block.\n\t*/\n\tpublic $bigBlockSize;\n\n\t/**\n\t * Size of small blocks. This is usually 64.\n\t * @var  int  number of octets per block\n\t*/\n\tpublic $smallBlockSize;\n\n\t/**\n\t * Reads an OLE container from the contents of the file given.\n\t *\n\t * @acces public\n\t * @param string $file\n\t * @return mixed true on success, PEAR_Error on failure\n\t*/\n\tpublic function read($file)\n\t{\n\t\t$fh = fopen($file, \"r\");\n\t\tif (!$fh) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Can't open file $file\");\n\t\t}\n\t\t$this->_file_handle = $fh;\n\n\t\t$signature = fread($fh, 8);\n\t\tif (\"\\xD0\\xCF\\x11\\xE0\\xA1\\xB1\\x1A\\xE1\" != $signature) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"File doesn't seem to be an OLE container.\");\n\t\t}\n\t\tfseek($fh, 28);\n\t\tif (fread($fh, 2) != \"\\xFE\\xFF\") {\n\t\t\t// This shouldn't be a problem in practice\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Only Little-Endian encoding is supported.\");\n\t\t}\n\t\t// Size of blocks and short blocks in bytes\n\t\t$this->bigBlockSize = pow(2, self::_readInt2($fh));\n\t\t$this->smallBlockSize  = pow(2, self::_readInt2($fh));\n\n\t\t// Skip UID, revision number and version number\n\t\tfseek($fh, 44);\n\t\t// Number of blocks in Big Block Allocation Table\n\t\t$bbatBlockCount = self::_readInt4($fh);\n\n\t\t// Root chain 1st block\n\t\t$directoryFirstBlockId = self::_readInt4($fh);\n\n\t\t// Skip unused bytes\n\t\tfseek($fh, 56);\n\t\t// Streams shorter than this are stored using small blocks\n\t\t$this->bigBlockThreshold = self::_readInt4($fh);\n\t\t// Block id of first sector in Short Block Allocation Table\n\t\t$sbatFirstBlockId = self::_readInt4($fh);\n\t\t// Number of blocks in Short Block Allocation Table\n\t\t$sbbatBlockCount = self::_readInt4($fh);\n\t\t// Block id of first sector in Master Block Allocation Table\n\t\t$mbatFirstBlockId = self::_readInt4($fh);\n\t\t// Number of blocks in Master Block Allocation Table\n\t\t$mbbatBlockCount = self::_readInt4($fh);\n\t\t$this->bbat = array();\n\n\t\t// Remaining 4 * 109 bytes of current block is beginning of Master\n\t\t// Block Allocation Table\n\t\t$mbatBlocks = array();\n\t\tfor ($i = 0; $i < 109; ++$i) {\n\t\t\t$mbatBlocks[] = self::_readInt4($fh);\n\t\t}\n\n\t\t// Read rest of Master Block Allocation Table (if any is left)\n\t\t$pos = $this->_getBlockOffset($mbatFirstBlockId);\n\t\tfor ($i = 0; $i < $mbbatBlockCount; ++$i) {\n\t\t\tfseek($fh, $pos);\n\t\t\tfor ($j = 0; $j < $this->bigBlockSize / 4 - 1; ++$j) {\n\t\t\t\t$mbatBlocks[] = self::_readInt4($fh);\n\t\t\t}\n\t\t\t// Last block id in each block points to next block\n\t\t\t$pos = $this->_getBlockOffset(self::_readInt4($fh));\n\t\t}\n\n\t\t// Read Big Block Allocation Table according to chain specified by\n\t\t// $mbatBlocks\n\t\tfor ($i = 0; $i < $bbatBlockCount; ++$i) {\n\t\t\t$pos = $this->_getBlockOffset($mbatBlocks[$i]);\n\t\t\tfseek($fh, $pos);\n\t\t\tfor ($j = 0 ; $j < $this->bigBlockSize / 4; ++$j) {\n\t\t\t\t$this->bbat[] = self::_readInt4($fh);\n\t\t\t}\n\t\t}\n\n\t\t// Read short block allocation table (SBAT)\n\t\t$this->sbat = array();\n\t\t$shortBlockCount = $sbbatBlockCount * $this->bigBlockSize / 4;\n\t\t$sbatFh = $this->getStream($sbatFirstBlockId);\n\t\tfor ($blockId = 0; $blockId < $shortBlockCount; ++$blockId) {\n\t\t\t$this->sbat[$blockId] = self::_readInt4($sbatFh);\n\t\t}\n\t\tfclose($sbatFh);\n\n\t\t$this->_readPpsWks($directoryFirstBlockId);\n\n\t\treturn true;\n\t}\n\n\t/**\n\t * @param  int  block id\n\t * @param  int  byte offset from beginning of file\n\t * @access public\n\t */\n\tpublic function _getBlockOffset($blockId)\n\t{\n\t\treturn 512 + $blockId * $this->bigBlockSize;\n\t}\n\n\t/**\n\t* Returns a stream for use with fread() etc. External callers should\n\t* use PHPExcel_Shared_OLE_PPS_File::getStream().\n\t* @param   int|PPS   block id or PPS\n\t* @return  resource  read-only stream\n\t*/\n\tpublic function getStream($blockIdOrPps)\n\t{\n\t\tstatic $isRegistered = false;\n\t\tif (!$isRegistered) {\n\t\t\tstream_wrapper_register('ole-chainedblockstream',\n\t\t\t\t'PHPExcel_Shared_OLE_ChainedBlockStream');\n\t\t\t$isRegistered = true;\n\t\t}\n\n\t\t// Store current instance in global array, so that it can be accessed\n\t\t// in OLE_ChainedBlockStream::stream_open().\n\t\t// Object is removed from self::$instances in OLE_Stream::close().\n\t\t$GLOBALS['_OLE_INSTANCES'][] = $this;\n\t\t$instanceId = end(array_keys($GLOBALS['_OLE_INSTANCES']));\n\n\t\t$path = 'ole-chainedblockstream://oleInstanceId=' . $instanceId;\n\t\tif ($blockIdOrPps instanceof PHPExcel_Shared_OLE_PPS) {\n\t\t\t$path .= '&blockId=' . $blockIdOrPps->_StartBlock;\n\t\t\t$path .= '&size=' . $blockIdOrPps->Size;\n\t\t} else {\n\t\t\t$path .= '&blockId=' . $blockIdOrPps;\n\t\t}\n\t\treturn fopen($path, 'r');\n\t}\n\n\t/**\n\t * Reads a signed char.\n\t * @param   resource  file handle\n\t * @return  int\n\t * @access public\n\t */\n\tprivate static function _readInt1($fh)\n\t{\n\t\tlist(, $tmp) = unpack(\"c\", fread($fh, 1));\n\t\treturn $tmp;\n\t}\n\n\t/**\n\t * Reads an unsigned short (2 octets).\n\t * @param   resource  file handle\n\t * @return  int\n\t * @access public\n\t */\n\tprivate static function _readInt2($fh)\n\t{\n\t\tlist(, $tmp) = unpack(\"v\", fread($fh, 2));\n\t\treturn $tmp;\n\t}\n\n\t/**\n\t * Reads an unsigned long (4 octets).\n\t * @param   resource  file handle\n\t * @return  int\n\t * @access public\n\t */\n\tprivate static function _readInt4($fh)\n\t{\n\t\tlist(, $tmp) = unpack(\"V\", fread($fh, 4));\n\t\treturn $tmp;\n\t}\n\n\t/**\n\t* Gets information about all PPS's on the OLE container from the PPS WK's\n\t* creates an OLE_PPS object for each one.\n\t*\n\t* @access public\n\t* @param  integer  the block id of the first block\n\t* @return mixed true on success, PEAR_Error on failure\n\t*/\n\tpublic function _readPpsWks($blockId)\n\t{\n\t\t$fh = $this->getStream($blockId);\n\t\tfor ($pos = 0; ; $pos += 128) {\n\t\t\tfseek($fh, $pos, SEEK_SET);\n\t\t\t$nameUtf16 = fread($fh, 64);\n\t\t\t$nameLength = self::_readInt2($fh);\n\t\t\t$nameUtf16 = substr($nameUtf16, 0, $nameLength - 2);\n\t\t\t// Simple conversion from UTF-16LE to ISO-8859-1\n\t\t\t$name = str_replace(\"\\x00\", \"\", $nameUtf16);\n\t\t\t$type = self::_readInt1($fh);\n\t\t\tswitch ($type) {\n\t\t\tcase self::OLE_PPS_TYPE_ROOT:\n\t\t\t\t$pps = new PHPExcel_Shared_OLE_PPS_Root(null, null, array());\n\t\t\t\t$this->root = $pps;\n\t\t\t\tbreak;\n\t\t\tcase self::OLE_PPS_TYPE_DIR:\n\t\t\t\t$pps = new PHPExcel_Shared_OLE_PPS(null, null, null, null, null,\n\t\t\t\t\t\t\t\t   null, null, null, null, array());\n\t\t\t\tbreak;\n\t\t\tcase self::OLE_PPS_TYPE_FILE:\n\t\t\t\t$pps = new PHPExcel_Shared_OLE_PPS_File($name);\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t\tfseek($fh, 1, SEEK_CUR);\n\t\t\t$pps->Type    = $type;\n\t\t\t$pps->Name    = $name;\n\t\t\t$pps->PrevPps = self::_readInt4($fh);\n\t\t\t$pps->NextPps = self::_readInt4($fh);\n\t\t\t$pps->DirPps  = self::_readInt4($fh);\n\t\t\tfseek($fh, 20, SEEK_CUR);\n\t\t\t$pps->Time1st = self::OLE2LocalDate(fread($fh, 8));\n\t\t\t$pps->Time2nd = self::OLE2LocalDate(fread($fh, 8));\n\t\t\t$pps->_StartBlock = self::_readInt4($fh);\n\t\t\t$pps->Size = self::_readInt4($fh);\n\t\t\t$pps->No = count($this->_list);\n\t\t\t$this->_list[] = $pps;\n\n\t\t\t// check if the PPS tree (starting from root) is complete\n\t\t\tif (isset($this->root) &&\n\t\t\t\t$this->_ppsTreeComplete($this->root->No)) {\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\tfclose($fh);\n\n\t\t// Initialize $pps->children on directories\n\t\tforeach ($this->_list as $pps) {\n\t\t\tif ($pps->Type == self::OLE_PPS_TYPE_DIR || $pps->Type == self::OLE_PPS_TYPE_ROOT) {\n\t\t\t\t$nos = array($pps->DirPps);\n\t\t\t\t$pps->children = array();\n\t\t\t\twhile ($nos) {\n\t\t\t\t\t$no = array_pop($nos);\n\t\t\t\t\tif ($no != -1) {\n\t\t\t\t\t\t$childPps = $this->_list[$no];\n\t\t\t\t\t\t$nos[] = $childPps->PrevPps;\n\t\t\t\t\t\t$nos[] = $childPps->NextPps;\n\t\t\t\t\t\t$pps->children[] = $childPps;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn true;\n\t}\n\n\t/**\n\t* It checks whether the PPS tree is complete (all PPS's read)\n\t* starting with the given PPS (not necessarily root)\n\t*\n\t* @access public\n\t* @param integer $index The index of the PPS from which we are checking\n\t* @return boolean Whether the PPS tree for the given PPS is complete\n\t*/\n\tpublic function _ppsTreeComplete($index)\n\t{\n\t\treturn isset($this->_list[$index]) &&\n\t\t\t   ($pps = $this->_list[$index]) &&\n\t\t\t   ($pps->PrevPps == -1 ||\n\t\t\t\t$this->_ppsTreeComplete($pps->PrevPps)) &&\n\t\t\t   ($pps->NextPps == -1 ||\n\t\t\t\t$this->_ppsTreeComplete($pps->NextPps)) &&\n\t\t\t   ($pps->DirPps == -1 ||\n\t\t\t\t$this->_ppsTreeComplete($pps->DirPps));\n\t}\n\n\t/**\n\t* Checks whether a PPS is a File PPS or not.\n\t* If there is no PPS for the index given, it will return false.\n\t*\n\t* @access public\n\t* @param integer $index The index for the PPS\n\t* @return bool true if it's a File PPS, false otherwise\n\t*/\n\tpublic function isFile($index)\n\t{\n\t\tif (isset($this->_list[$index])) {\n\t\t\treturn ($this->_list[$index]->Type == self::OLE_PPS_TYPE_FILE);\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t* Checks whether a PPS is a Root PPS or not.\n\t* If there is no PPS for the index given, it will return false.\n\t*\n\t* @access public\n\t* @param integer $index The index for the PPS.\n\t* @return bool true if it's a Root PPS, false otherwise\n\t*/\n\tpublic function isRoot($index)\n\t{\n\t\tif (isset($this->_list[$index])) {\n\t\t\treturn ($this->_list[$index]->Type == self::OLE_PPS_TYPE_ROOT);\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t* Gives the total number of PPS's found in the OLE container.\n\t*\n\t* @access public\n\t* @return integer The total number of PPS's found in the OLE container\n\t*/\n\tpublic function ppsTotal()\n\t{\n\t\treturn count($this->_list);\n\t}\n\n\t/**\n\t* Gets data from a PPS\n\t* If there is no PPS for the index given, it will return an empty string.\n\t*\n\t* @access public\n\t* @param integer $index    The index for the PPS\n\t* @param integer $position The position from which to start reading\n\t*                          (relative to the PPS)\n\t* @param integer $length   The amount of bytes to read (at most)\n\t* @return string The binary string containing the data requested\n\t* @see OLE_PPS_File::getStream()\n\t*/\n\tpublic function getData($index, $position, $length)\n\t{\n\t\t// if position is not valid return empty string\n\t\tif (!isset($this->_list[$index]) || ($position >= $this->_list[$index]->Size) || ($position < 0)) {\n\t\t\treturn '';\n\t\t}\n\t\t$fh = $this->getStream($this->_list[$index]);\n\t\t$data = stream_get_contents($fh, $length, $position);\n\t\tfclose($fh);\n\t\treturn $data;\n\t}\n\n\t/**\n\t* Gets the data length from a PPS\n\t* If there is no PPS for the index given, it will return 0.\n\t*\n\t* @access public\n\t* @param integer $index    The index for the PPS\n\t* @return integer The amount of bytes in data the PPS has\n\t*/\n\tpublic function getDataLength($index)\n\t{\n\t\tif (isset($this->_list[$index])) {\n\t\t\treturn $this->_list[$index]->Size;\n\t\t}\n\t\treturn 0;\n\t}\n\n\t/**\n\t* Utility function to transform ASCII text to Unicode\n\t*\n\t* @access public\n\t* @static\n\t* @param string $ascii The ASCII string to transform\n\t* @return string The string in Unicode\n\t*/\n\tpublic static function Asc2Ucs($ascii)\n\t{\n\t\t$rawname = '';\n\t\tfor ($i = 0; $i < strlen($ascii); ++$i) {\n\t\t\t$rawname .= $ascii{$i} . \"\\x00\";\n\t\t}\n\t\treturn $rawname;\n\t}\n\n\t/**\n\t* Utility function\n\t* Returns a string for the OLE container with the date given\n\t*\n\t* @access public\n\t* @static\n\t* @param integer $date A timestamp\n\t* @return string The string for the OLE container\n\t*/\n\tpublic static function LocalDate2OLE($date = null)\n\t{\n\t\tif (!isset($date)) {\n\t\t\treturn \"\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\";\n\t\t}\n\n\t\t// factor used for separating numbers into 4 bytes parts\n\t\t$factor = pow(2, 32);\n\n\t\t// days from 1-1-1601 until the beggining of UNIX era\n\t\t$days = 134774;\n\t\t// calculate seconds\n\t\t$big_date = $days*24*3600 + gmmktime(date(\"H\",$date),date(\"i\",$date),date(\"s\",$date),\n\t\t\t\t\t\t\t\t\t\t\t date(\"m\",$date),date(\"d\",$date),date(\"Y\",$date));\n\t\t// multiply just to make MS happy\n\t\t$big_date *= 10000000;\n\n\t\t$high_part = floor($big_date / $factor);\n\t\t// lower 4 bytes\n\t\t$low_part = floor((($big_date / $factor) - $high_part) * $factor);\n\n\t\t// Make HEX string\n\t\t$res = '';\n\n\t\tfor ($i = 0; $i < 4; ++$i) {\n\t\t\t$hex = $low_part % 0x100;\n\t\t\t$res .= pack('c', $hex);\n\t\t\t$low_part /= 0x100;\n\t\t}\n\t\tfor ($i = 0; $i < 4; ++$i) {\n\t\t\t$hex = $high_part % 0x100;\n\t\t\t$res .= pack('c', $hex);\n\t\t\t$high_part /= 0x100;\n\t\t}\n\t\treturn $res;\n\t}\n\n\t/**\n\t* Returns a timestamp from an OLE container's date\n\t*\n\t* @access public\n\t* @static\n\t* @param integer $string A binary string with the encoded date\n\t* @return string The timestamp corresponding to the string\n\t*/\n\tpublic static function OLE2LocalDate($string)\n\t{\n\t\tif (strlen($string) != 8) {\n\t\t\treturn new PEAR_Error(\"Expecting 8 byte string\");\n\t\t}\n\n\t\t// factor used for separating numbers into 4 bytes parts\n\t\t$factor = pow(2,32);\n\t\tlist(, $high_part) = unpack('V', substr($string, 4, 4));\n\t\tlist(, $low_part) = unpack('V', substr($string, 0, 4));\n\n\t\t$big_date = ($high_part * $factor) + $low_part;\n\t\t// translate to seconds\n\t\t$big_date /= 10000000;\n\n\t\t// days from 1-1-1601 until the beggining of UNIX era\n\t\t$days = 134774;\n\n\t\t// translate to seconds from beggining of UNIX era\n\t\t$big_date -= $days * 24 * 3600;\n\t\treturn floor($big_date);\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/OLERead.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\ndefined('IDENTIFIER_OLE') ||\n    define('IDENTIFIER_OLE', pack('CCCCCCCC', 0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1));\n\nclass PHPExcel_Shared_OLERead {\n\tprivate $data = '';\n\n\t// OLE identifier\n\tconst IDENTIFIER_OLE = IDENTIFIER_OLE;\n\n\t// Size of a sector = 512 bytes\n\tconst BIG_BLOCK_SIZE\t\t\t\t\t= 0x200;\n\n\t// Size of a short sector = 64 bytes\n\tconst SMALL_BLOCK_SIZE\t\t\t\t\t= 0x40;\n\n\t// Size of a directory entry always = 128 bytes\n\tconst PROPERTY_STORAGE_BLOCK_SIZE\t\t= 0x80;\n\n\t// Minimum size of a standard stream = 4096 bytes, streams smaller than this are stored as short streams\n\tconst SMALL_BLOCK_THRESHOLD\t\t\t\t= 0x1000;\n\n\t// header offsets\n\tconst NUM_BIG_BLOCK_DEPOT_BLOCKS_POS\t= 0x2c;\n\tconst ROOT_START_BLOCK_POS\t\t\t\t= 0x30;\n\tconst SMALL_BLOCK_DEPOT_BLOCK_POS\t\t= 0x3c;\n\tconst EXTENSION_BLOCK_POS\t\t\t\t= 0x44;\n\tconst NUM_EXTENSION_BLOCK_POS\t\t\t= 0x48;\n\tconst BIG_BLOCK_DEPOT_BLOCKS_POS\t\t= 0x4c;\n\n\t// property storage offsets (directory offsets)\n\tconst SIZE_OF_NAME_POS\t\t\t\t\t= 0x40;\n\tconst TYPE_POS\t\t\t\t\t\t\t= 0x42;\n\tconst START_BLOCK_POS\t\t\t\t\t= 0x74;\n\tconst SIZE_POS\t\t\t\t\t\t\t= 0x78;\n\n\n\n\tpublic $wrkbook\t\t\t\t\t\t= null;\n\tpublic $summaryInformation\t\t\t= null;\n\tpublic $documentSummaryInformation\t= null;\n\n\n\t/**\n\t * Read the file\n\t *\n\t * @param $sFileName string Filename\n\t * @throws PHPExcel_Reader_Exception\n\t */\n\tpublic function read($sFileName)\n\t{\n\t\t// Check if file exists and is readable\n\t\tif(!is_readable($sFileName)) {\n\t\t\tthrow new PHPExcel_Reader_Exception(\"Could not open \" . $sFileName . \" for reading! File does not exist, or it is not readable.\");\n\t\t}\n\n\t\t// Get the file identifier\n\t\t// Don't bother reading the whole file until we know it's a valid OLE file\n\t\t$this->data = file_get_contents($sFileName, FALSE, NULL, 0, 8);\n\n\t\t// Check OLE identifier\n\t\tif ($this->data != self::IDENTIFIER_OLE) {\n\t\t\tthrow new PHPExcel_Reader_Exception('The filename ' . $sFileName . ' is not recognised as an OLE file');\n\t\t}\n\n\t\t// Get the file data\n\t\t$this->data = file_get_contents($sFileName);\n\n\t\t// Total number of sectors used for the SAT\n\t\t$this->numBigBlockDepotBlocks = self::_GetInt4d($this->data, self::NUM_BIG_BLOCK_DEPOT_BLOCKS_POS);\n\n\t\t// SecID of the first sector of the directory stream\n\t\t$this->rootStartBlock = self::_GetInt4d($this->data, self::ROOT_START_BLOCK_POS);\n\n\t\t// SecID of the first sector of the SSAT (or -2 if not extant)\n\t\t$this->sbdStartBlock = self::_GetInt4d($this->data, self::SMALL_BLOCK_DEPOT_BLOCK_POS);\n\n\t\t// SecID of the first sector of the MSAT (or -2 if no additional sectors are used)\n\t\t$this->extensionBlock = self::_GetInt4d($this->data, self::EXTENSION_BLOCK_POS);\n\n\t\t// Total number of sectors used by MSAT\n\t\t$this->numExtensionBlocks = self::_GetInt4d($this->data, self::NUM_EXTENSION_BLOCK_POS);\n\n\t\t$bigBlockDepotBlocks = array();\n\t\t$pos = self::BIG_BLOCK_DEPOT_BLOCKS_POS;\n\n\t\t$bbdBlocks = $this->numBigBlockDepotBlocks;\n\n\t\tif ($this->numExtensionBlocks != 0) {\n\t\t\t$bbdBlocks = (self::BIG_BLOCK_SIZE - self::BIG_BLOCK_DEPOT_BLOCKS_POS)/4;\n\t\t}\n\n\t\tfor ($i = 0; $i < $bbdBlocks; ++$i) {\n\t\t\t  $bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);\n\t\t\t  $pos += 4;\n\t\t}\n\n\t\tfor ($j = 0; $j < $this->numExtensionBlocks; ++$j) {\n\t\t\t$pos = ($this->extensionBlock + 1) * self::BIG_BLOCK_SIZE;\n\t\t\t$blocksToRead = min($this->numBigBlockDepotBlocks - $bbdBlocks, self::BIG_BLOCK_SIZE / 4 - 1);\n\n\t\t\tfor ($i = $bbdBlocks; $i < $bbdBlocks + $blocksToRead; ++$i) {\n\t\t\t\t$bigBlockDepotBlocks[$i] = self::_GetInt4d($this->data, $pos);\n\t\t\t\t$pos += 4;\n\t\t\t}\n\n\t\t\t$bbdBlocks += $blocksToRead;\n\t\t\tif ($bbdBlocks < $this->numBigBlockDepotBlocks) {\n\t\t\t\t$this->extensionBlock = self::_GetInt4d($this->data, $pos);\n\t\t\t}\n\t\t}\n\n\t\t$pos = 0;\n\t\t$this->bigBlockChain = '';\n\t\t$bbs = self::BIG_BLOCK_SIZE / 4;\n\t\tfor ($i = 0; $i < $this->numBigBlockDepotBlocks; ++$i) {\n\t\t\t$pos = ($bigBlockDepotBlocks[$i] + 1) * self::BIG_BLOCK_SIZE;\n\n\t\t\t$this->bigBlockChain .= substr($this->data, $pos, 4*$bbs);\n\t\t\t$pos += 4*$bbs;\n\t\t}\n\n\t\t$pos = 0;\n\t\t$sbdBlock = $this->sbdStartBlock;\n\t\t$this->smallBlockChain = '';\n\t\twhile ($sbdBlock != -2) {\n\t\t\t$pos = ($sbdBlock + 1) * self::BIG_BLOCK_SIZE;\n\n\t\t\t$this->smallBlockChain .= substr($this->data, $pos, 4*$bbs);\n\t\t\t$pos += 4*$bbs;\n\n\t\t\t$sbdBlock = self::_GetInt4d($this->bigBlockChain, $sbdBlock*4);\n\t\t}\n\n\t\t// read the directory stream\n\t\t$block = $this->rootStartBlock;\n\t\t$this->entry = $this->_readData($block);\n\n\t\t$this->_readPropertySets();\n\t}\n\n\t/**\n\t * Extract binary stream data\n\t *\n\t * @return string\n\t */\n\tpublic function getStream($stream)\n\t{\n\t\tif ($stream === NULL) {\n\t\t\treturn null;\n\t\t}\n\n\t\t$streamData = '';\n\n\t\tif ($this->props[$stream]['size'] < self::SMALL_BLOCK_THRESHOLD) {\n\t\t\t$rootdata = $this->_readData($this->props[$this->rootentry]['startBlock']);\n\n\t\t\t$block = $this->props[$stream]['startBlock'];\n\n\t\t\twhile ($block != -2) {\n\t  \t\t\t$pos = $block * self::SMALL_BLOCK_SIZE;\n\t\t\t\t$streamData .= substr($rootdata, $pos, self::SMALL_BLOCK_SIZE);\n\n\t\t\t\t$block = self::_GetInt4d($this->smallBlockChain, $block*4);\n\t\t\t}\n\n\t\t\treturn $streamData;\n\t\t} else {\n\t\t\t$numBlocks = $this->props[$stream]['size'] / self::BIG_BLOCK_SIZE;\n\t\t\tif ($this->props[$stream]['size'] % self::BIG_BLOCK_SIZE != 0) {\n\t\t\t\t++$numBlocks;\n\t\t\t}\n\n\t\t\tif ($numBlocks == 0) return '';\n\n\t\t\t$block = $this->props[$stream]['startBlock'];\n\n\t\t\twhile ($block != -2) {\n\t\t\t\t$pos = ($block + 1) * self::BIG_BLOCK_SIZE;\n\t\t\t\t$streamData .= substr($this->data, $pos, self::BIG_BLOCK_SIZE);\n\t\t\t\t$block = self::_GetInt4d($this->bigBlockChain, $block*4);\n\t\t\t}\n\n\t\t\treturn $streamData;\n\t\t}\n\t}\n\n\t/**\n\t * Read a standard stream (by joining sectors using information from SAT)\n\t *\n\t * @param int $bl Sector ID where the stream starts\n\t * @return string Data for standard stream\n\t */\n\tprivate function _readData($bl)\n\t{\n\t\t$block = $bl;\n\t\t$data = '';\n\n\t\twhile ($block != -2)  {\n\t\t\t$pos = ($block + 1) * self::BIG_BLOCK_SIZE;\n\t\t\t$data .= substr($this->data, $pos, self::BIG_BLOCK_SIZE);\n\t\t\t$block = self::_GetInt4d($this->bigBlockChain, $block*4);\n\t\t}\n\t\treturn $data;\n\t }\n\n\t/**\n\t * Read entries in the directory stream.\n\t */\n\tprivate function _readPropertySets() {\n\t\t$offset = 0;\n\n\t\t// loop through entires, each entry is 128 bytes\n\t\t$entryLen = strlen($this->entry);\n\t\twhile ($offset < $entryLen) {\n\t\t\t// entry data (128 bytes)\n\t\t\t$d = substr($this->entry, $offset, self::PROPERTY_STORAGE_BLOCK_SIZE);\n\n\t\t\t// size in bytes of name\n\t\t\t$nameSize = ord($d[self::SIZE_OF_NAME_POS]) | (ord($d[self::SIZE_OF_NAME_POS+1]) << 8);\n\n\t\t\t// type of entry\n\t\t\t$type = ord($d[self::TYPE_POS]);\n\n\t\t\t// sectorID of first sector or short sector, if this entry refers to a stream (the case with workbook)\n\t\t\t// sectorID of first sector of the short-stream container stream, if this entry is root entry\n\t\t\t$startBlock = self::_GetInt4d($d, self::START_BLOCK_POS);\n\n\t\t\t$size = self::_GetInt4d($d, self::SIZE_POS);\n\n\t\t\t$name = str_replace(\"\\x00\", \"\", substr($d,0,$nameSize));\n\n\n\t\t\t$this->props[] = array (\n\t\t\t\t'name' => $name,\n\t\t\t\t'type' => $type,\n\t\t\t\t'startBlock' => $startBlock,\n\t\t\t\t'size' => $size);\n\n\t\t\t// tmp helper to simplify checks\n\t\t\t$upName = strtoupper($name);\n\n\t\t\t// Workbook directory entry (BIFF5 uses Book, BIFF8 uses Workbook)\n\t\t\tif (($upName === 'WORKBOOK') || ($upName === 'BOOK')) {\n\t\t\t\t$this->wrkbook = count($this->props) - 1;\n\t\t\t}\n\t\t\telse if ( $upName === 'ROOT ENTRY' || $upName === 'R') {\n\t\t\t\t// Root entry\n\t\t\t\t$this->rootentry = count($this->props) - 1;\n\t\t\t}\n\n\t\t\t// Summary information\n\t\t\tif ($name == chr(5) . 'SummaryInformation') {\n//\t\t\t\techo 'Summary Information<br />';\n\t\t\t\t$this->summaryInformation = count($this->props) - 1;\n\t\t\t}\n\n\t\t\t// Additional Document Summary information\n\t\t\tif ($name == chr(5) . 'DocumentSummaryInformation') {\n//\t\t\t\techo 'Document Summary Information<br />';\n\t\t\t\t$this->documentSummaryInformation = count($this->props) - 1;\n\t\t\t}\n\n\t\t\t$offset += self::PROPERTY_STORAGE_BLOCK_SIZE;\n\t\t}\n\n\t}\n\n\t/**\n\t * Read 4 bytes of data at specified position\n\t *\n\t * @param string $data\n\t * @param int $pos\n\t * @return int\n\t */\n\tprivate static function _GetInt4d($data, $pos)\n\t{\n\t\t// FIX: represent numbers correctly on 64-bit system\n\t\t// http://sourceforge.net/tracker/index.php?func=detail&aid=1487372&group_id=99160&atid=623334\n\t\t// Hacked by Andreas Rehm 2006 to ensure correct result of the <<24 block on 32 and 64bit systems\n\t\t$_or_24 = ord($data[$pos + 3]);\n\t\tif ($_or_24 >= 128) {\n\t\t\t// negative number\n\t\t\t$_ord_24 = -abs((256 - $_or_24) << 24);\n\t\t} else {\n\t\t\t$_ord_24 = ($_or_24 & 127) << 24;\n\t\t}\n\t\treturn ord($data[$pos]) | (ord($data[$pos + 1]) << 8) | (ord($data[$pos + 2]) << 16) | $_ord_24;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/PCLZip/gnu-lgpl.txt",
    "content": "\t\t  GNU LESSER GENERAL PUBLIC LICENSE\r\n\t\t       Version 2.1, February 1999\r\n\r\n Copyright (C) 1991, 1999 Free Software Foundation, Inc.\r\n     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r\n Everyone is permitted to copy and distribute verbatim copies\r\n of this license document, but changing it is not allowed.\r\n\r\n[This is the first released version of the Lesser GPL.  It also counts\r\n as the successor of the GNU Library Public License, version 2, hence\r\n the version number 2.1.]\r\n\r\n\t\t\t    Preamble\r\n\r\n  The licenses for most software are designed to take away your\r\nfreedom to share and change it.  By contrast, the GNU General Public\r\nLicenses are intended to guarantee your freedom to share and change\r\nfree software--to make sure the software is free for all its users.\r\n\r\n  This license, the Lesser General Public License, applies to some\r\nspecially designated software packages--typically libraries--of the\r\nFree Software Foundation and other authors who decide to use it.  You\r\ncan use it too, but we suggest you first think carefully about whether\r\nthis license or the ordinary General Public License is the better\r\nstrategy to use in any particular case, based on the explanations below.\r\n\r\n  When we speak of free software, we are referring to freedom of use,\r\nnot price.  Our General Public Licenses are designed to make sure that\r\nyou have the freedom to distribute copies of free software (and charge\r\nfor this service if you wish); that you receive source code or can get\r\nit if you want it; that you can change the software and use pieces of\r\nit in new free programs; and that you are informed that you can do\r\nthese things.\r\n\r\n  To protect your rights, we need to make restrictions that forbid\r\ndistributors to deny you these rights or to ask you to surrender these\r\nrights.  These restrictions translate to certain responsibilities for\r\nyou if you distribute copies of the library or if you modify it.\r\n\r\n  For example, if you distribute copies of the library, whether gratis\r\nor for a fee, you must give the recipients all the rights that we gave\r\nyou.  You must make sure that they, too, receive or can get the source\r\ncode.  If you link other code with the library, you must provide\r\ncomplete object files to the recipients, so that they can relink them\r\nwith the library after making changes to the library and recompiling\r\nit.  And you must show them these terms so they know their rights.\r\n\r\n  We protect your rights with a two-step method: (1) we copyright the\r\nlibrary, and (2) we offer you this license, which gives you legal\r\npermission to copy, distribute and/or modify the library.\r\n\r\n  To protect each distributor, we want to make it very clear that\r\nthere is no warranty for the free library.  Also, if the library is\r\nmodified by someone else and passed on, the recipients should know\r\nthat what they have is not the original version, so that the original\r\nauthor's reputation will not be affected by problems that might be\r\nintroduced by others.\r\n\f\r\n  Finally, software patents pose a constant threat to the existence of\r\nany free program.  We wish to make sure that a company cannot\r\neffectively restrict the users of a free program by obtaining a\r\nrestrictive license from a patent holder.  Therefore, we insist that\r\nany patent license obtained for a version of the library must be\r\nconsistent with the full freedom of use specified in this license.\r\n\r\n  Most GNU software, including some libraries, is covered by the\r\nordinary GNU General Public License.  This license, the GNU Lesser\r\nGeneral Public License, applies to certain designated libraries, and\r\nis quite different from the ordinary General Public License.  We use\r\nthis license for certain libraries in order to permit linking those\r\nlibraries into non-free programs.\r\n\r\n  When a program is linked with a library, whether statically or using\r\na shared library, the combination of the two is legally speaking a\r\ncombined work, a derivative of the original library.  The ordinary\r\nGeneral Public License therefore permits such linking only if the\r\nentire combination fits its criteria of freedom.  The Lesser General\r\nPublic License permits more lax criteria for linking other code with\r\nthe library.\r\n\r\n  We call this license the \"Lesser\" General Public License because it\r\ndoes Less to protect the user's freedom than the ordinary General\r\nPublic License.  It also provides other free software developers Less\r\nof an advantage over competing non-free programs.  These disadvantages\r\nare the reason we use the ordinary General Public License for many\r\nlibraries.  However, the Lesser license provides advantages in certain\r\nspecial circumstances.\r\n\r\n  For example, on rare occasions, there may be a special need to\r\nencourage the widest possible use of a certain library, so that it becomes\r\na de-facto standard.  To achieve this, non-free programs must be\r\nallowed to use the library.  A more frequent case is that a free\r\nlibrary does the same job as widely used non-free libraries.  In this\r\ncase, there is little to gain by limiting the free library to free\r\nsoftware only, so we use the Lesser General Public License.\r\n\r\n  In other cases, permission to use a particular library in non-free\r\nprograms enables a greater number of people to use a large body of\r\nfree software.  For example, permission to use the GNU C Library in\r\nnon-free programs enables many more people to use the whole GNU\r\noperating system, as well as its variant, the GNU/Linux operating\r\nsystem.\r\n\r\n  Although the Lesser General Public License is Less protective of the\r\nusers' freedom, it does ensure that the user of a program that is\r\nlinked with the Library has the freedom and the wherewithal to run\r\nthat program using a modified version of the Library.\r\n\r\n  The precise terms and conditions for copying, distribution and\r\nmodification follow.  Pay close attention to the difference between a\r\n\"work based on the library\" and a \"work that uses the library\".  The\r\nformer contains code derived from the library, whereas the latter must\r\nbe combined with the library in order to run.\r\n\f\r\n\t\t  GNU LESSER GENERAL PUBLIC LICENSE\r\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\r\n\r\n  0. This License Agreement applies to any software library or other\r\nprogram which contains a notice placed by the copyright holder or\r\nother authorized party saying it may be distributed under the terms of\r\nthis Lesser General Public License (also called \"this License\").\r\nEach licensee is addressed as \"you\".\r\n\r\n  A \"library\" means a collection of software functions and/or data\r\nprepared so as to be conveniently linked with application programs\r\n(which use some of those functions and data) to form executables.\r\n\r\n  The \"Library\", below, refers to any such software library or work\r\nwhich has been distributed under these terms.  A \"work based on the\r\nLibrary\" means either the Library or any derivative work under\r\ncopyright law: that is to say, a work containing the Library or a\r\nportion of it, either verbatim or with modifications and/or translated\r\nstraightforwardly into another language.  (Hereinafter, translation is\r\nincluded without limitation in the term \"modification\".)\r\n\r\n  \"Source code\" for a work means the preferred form of the work for\r\nmaking modifications to it.  For a library, complete source code means\r\nall the source code for all modules it contains, plus any associated\r\ninterface definition files, plus the scripts used to control compilation\r\nand installation of the library.\r\n\r\n  Activities other than copying, distribution and modification are not\r\ncovered by this License; they are outside its scope.  The act of\r\nrunning a program using the Library is not restricted, and output from\r\nsuch a program is covered only if its contents constitute a work based\r\non the Library (independent of the use of the Library in a tool for\r\nwriting it).  Whether that is true depends on what the Library does\r\nand what the program that uses the Library does.\r\n  \r\n  1. You may copy and distribute verbatim copies of the Library's\r\ncomplete source code as you receive it, in any medium, provided that\r\nyou conspicuously and appropriately publish on each copy an\r\nappropriate copyright notice and disclaimer of warranty; keep intact\r\nall the notices that refer to this License and to the absence of any\r\nwarranty; and distribute a copy of this License along with the\r\nLibrary.\r\n\r\n  You may charge a fee for the physical act of transferring a copy,\r\nand you may at your option offer warranty protection in exchange for a\r\nfee.\r\n\f\r\n  2. You may modify your copy or copies of the Library or any portion\r\nof it, thus forming a work based on the Library, and copy and\r\ndistribute such modifications or work under the terms of Section 1\r\nabove, provided that you also meet all of these conditions:\r\n\r\n    a) The modified work must itself be a software library.\r\n\r\n    b) You must cause the files modified to carry prominent notices\r\n    stating that you changed the files and the date of any change.\r\n\r\n    c) You must cause the whole of the work to be licensed at no\r\n    charge to all third parties under the terms of this License.\r\n\r\n    d) If a facility in the modified Library refers to a function or a\r\n    table of data to be supplied by an application program that uses\r\n    the facility, other than as an argument passed when the facility\r\n    is invoked, then you must make a good faith effort to ensure that,\r\n    in the event an application does not supply such function or\r\n    table, the facility still operates, and performs whatever part of\r\n    its purpose remains meaningful.\r\n\r\n    (For example, a function in a library to compute square roots has\r\n    a purpose that is entirely well-defined independent of the\r\n    application.  Therefore, Subsection 2d requires that any\r\n    application-supplied function or table used by this function must\r\n    be optional: if the application does not supply it, the square\r\n    root function must still compute square roots.)\r\n\r\nThese requirements apply to the modified work as a whole.  If\r\nidentifiable sections of that work are not derived from the Library,\r\nand can be reasonably considered independent and separate works in\r\nthemselves, then this License, and its terms, do not apply to those\r\nsections when you distribute them as separate works.  But when you\r\ndistribute the same sections as part of a whole which is a work based\r\non the Library, the distribution of the whole must be on the terms of\r\nthis License, whose permissions for other licensees extend to the\r\nentire whole, and thus to each and every part regardless of who wrote\r\nit.\r\n\r\nThus, it is not the intent of this section to claim rights or contest\r\nyour rights to work written entirely by you; rather, the intent is to\r\nexercise the right to control the distribution of derivative or\r\ncollective works based on the Library.\r\n\r\nIn addition, mere aggregation of another work not based on the Library\r\nwith the Library (or with a work based on the Library) on a volume of\r\na storage or distribution medium does not bring the other work under\r\nthe scope of this License.\r\n\r\n  3. You may opt to apply the terms of the ordinary GNU General Public\r\nLicense instead of this License to a given copy of the Library.  To do\r\nthis, you must alter all the notices that refer to this License, so\r\nthat they refer to the ordinary GNU General Public License, version 2,\r\ninstead of to this License.  (If a newer version than version 2 of the\r\nordinary GNU General Public License has appeared, then you can specify\r\nthat version instead if you wish.)  Do not make any other change in\r\nthese notices.\r\n\f\r\n  Once this change is made in a given copy, it is irreversible for\r\nthat copy, so the ordinary GNU General Public License applies to all\r\nsubsequent copies and derivative works made from that copy.\r\n\r\n  This option is useful when you wish to copy part of the code of\r\nthe Library into a program that is not a library.\r\n\r\n  4. You may copy and distribute the Library (or a portion or\r\nderivative of it, under Section 2) in object code or executable form\r\nunder the terms of Sections 1 and 2 above provided that you accompany\r\nit with the complete corresponding machine-readable source code, which\r\nmust be distributed under the terms of Sections 1 and 2 above on a\r\nmedium customarily used for software interchange.\r\n\r\n  If distribution of object code is made by offering access to copy\r\nfrom a designated place, then offering equivalent access to copy the\r\nsource code from the same place satisfies the requirement to\r\ndistribute the source code, even though third parties are not\r\ncompelled to copy the source along with the object code.\r\n\r\n  5. A program that contains no derivative of any portion of the\r\nLibrary, but is designed to work with the Library by being compiled or\r\nlinked with it, is called a \"work that uses the Library\".  Such a\r\nwork, in isolation, is not a derivative work of the Library, and\r\ntherefore falls outside the scope of this License.\r\n\r\n  However, linking a \"work that uses the Library\" with the Library\r\ncreates an executable that is a derivative of the Library (because it\r\ncontains portions of the Library), rather than a \"work that uses the\r\nlibrary\".  The executable is therefore covered by this License.\r\nSection 6 states terms for distribution of such executables.\r\n\r\n  When a \"work that uses the Library\" uses material from a header file\r\nthat is part of the Library, the object code for the work may be a\r\nderivative work of the Library even though the source code is not.\r\nWhether this is true is especially significant if the work can be\r\nlinked without the Library, or if the work is itself a library.  The\r\nthreshold for this to be true is not precisely defined by law.\r\n\r\n  If such an object file uses only numerical parameters, data\r\nstructure layouts and accessors, and small macros and small inline\r\nfunctions (ten lines or less in length), then the use of the object\r\nfile is unrestricted, regardless of whether it is legally a derivative\r\nwork.  (Executables containing this object code plus portions of the\r\nLibrary will still fall under Section 6.)\r\n\r\n  Otherwise, if the work is a derivative of the Library, you may\r\ndistribute the object code for the work under the terms of Section 6.\r\nAny executables containing that work also fall under Section 6,\r\nwhether or not they are linked directly with the Library itself.\r\n\f\r\n  6. As an exception to the Sections above, you may also combine or\r\nlink a \"work that uses the Library\" with the Library to produce a\r\nwork containing portions of the Library, and distribute that work\r\nunder terms of your choice, provided that the terms permit\r\nmodification of the work for the customer's own use and reverse\r\nengineering for debugging such modifications.\r\n\r\n  You must give prominent notice with each copy of the work that the\r\nLibrary is used in it and that the Library and its use are covered by\r\nthis License.  You must supply a copy of this License.  If the work\r\nduring execution displays copyright notices, you must include the\r\ncopyright notice for the Library among them, as well as a reference\r\ndirecting the user to the copy of this License.  Also, you must do one\r\nof these things:\r\n\r\n    a) Accompany the work with the complete corresponding\r\n    machine-readable source code for the Library including whatever\r\n    changes were used in the work (which must be distributed under\r\n    Sections 1 and 2 above); and, if the work is an executable linked\r\n    with the Library, with the complete machine-readable \"work that\r\n    uses the Library\", as object code and/or source code, so that the\r\n    user can modify the Library and then relink to produce a modified\r\n    executable containing the modified Library.  (It is understood\r\n    that the user who changes the contents of definitions files in the\r\n    Library will not necessarily be able to recompile the application\r\n    to use the modified definitions.)\r\n\r\n    b) Use a suitable shared library mechanism for linking with the\r\n    Library.  A suitable mechanism is one that (1) uses at run time a\r\n    copy of the library already present on the user's computer system,\r\n    rather than copying library functions into the executable, and (2)\r\n    will operate properly with a modified version of the library, if\r\n    the user installs one, as long as the modified version is\r\n    interface-compatible with the version that the work was made with.\r\n\r\n    c) Accompany the work with a written offer, valid for at\r\n    least three years, to give the same user the materials\r\n    specified in Subsection 6a, above, for a charge no more\r\n    than the cost of performing this distribution.\r\n\r\n    d) If distribution of the work is made by offering access to copy\r\n    from a designated place, offer equivalent access to copy the above\r\n    specified materials from the same place.\r\n\r\n    e) Verify that the user has already received a copy of these\r\n    materials or that you have already sent this user a copy.\r\n\r\n  For an executable, the required form of the \"work that uses the\r\nLibrary\" must include any data and utility programs needed for\r\nreproducing the executable from it.  However, as a special exception,\r\nthe materials to be distributed need not include anything that is\r\nnormally distributed (in either source or binary form) with the major\r\ncomponents (compiler, kernel, and so on) of the operating system on\r\nwhich the executable runs, unless that component itself accompanies\r\nthe executable.\r\n\r\n  It may happen that this requirement contradicts the license\r\nrestrictions of other proprietary libraries that do not normally\r\naccompany the operating system.  Such a contradiction means you cannot\r\nuse both them and the Library together in an executable that you\r\ndistribute.\r\n\f\r\n  7. You may place library facilities that are a work based on the\r\nLibrary side-by-side in a single library together with other library\r\nfacilities not covered by this License, and distribute such a combined\r\nlibrary, provided that the separate distribution of the work based on\r\nthe Library and of the other library facilities is otherwise\r\npermitted, and provided that you do these two things:\r\n\r\n    a) Accompany the combined library with a copy of the same work\r\n    based on the Library, uncombined with any other library\r\n    facilities.  This must be distributed under the terms of the\r\n    Sections above.\r\n\r\n    b) Give prominent notice with the combined library of the fact\r\n    that part of it is a work based on the Library, and explaining\r\n    where to find the accompanying uncombined form of the same work.\r\n\r\n  8. You may not copy, modify, sublicense, link with, or distribute\r\nthe Library except as expressly provided under this License.  Any\r\nattempt otherwise to copy, modify, sublicense, link with, or\r\ndistribute the Library is void, and will automatically terminate your\r\nrights under this License.  However, parties who have received copies,\r\nor rights, from you under this License will not have their licenses\r\nterminated so long as such parties remain in full compliance.\r\n\r\n  9. You are not required to accept this License, since you have not\r\nsigned it.  However, nothing else grants you permission to modify or\r\ndistribute the Library or its derivative works.  These actions are\r\nprohibited by law if you do not accept this License.  Therefore, by\r\nmodifying or distributing the Library (or any work based on the\r\nLibrary), you indicate your acceptance of this License to do so, and\r\nall its terms and conditions for copying, distributing or modifying\r\nthe Library or works based on it.\r\n\r\n  10. Each time you redistribute the Library (or any work based on the\r\nLibrary), the recipient automatically receives a license from the\r\noriginal licensor to copy, distribute, link with or modify the Library\r\nsubject to these terms and conditions.  You may not impose any further\r\nrestrictions on the recipients' exercise of the rights granted herein.\r\nYou are not responsible for enforcing compliance by third parties with\r\nthis License.\r\n\f\r\n  11. If, as a consequence of a court judgment or allegation of patent\r\ninfringement or for any other reason (not limited to patent issues),\r\nconditions are imposed on you (whether by court order, agreement or\r\notherwise) that contradict the conditions of this License, they do not\r\nexcuse you from the conditions of this License.  If you cannot\r\ndistribute so as to satisfy simultaneously your obligations under this\r\nLicense and any other pertinent obligations, then as a consequence you\r\nmay not distribute the Library at all.  For example, if a patent\r\nlicense would not permit royalty-free redistribution of the Library by\r\nall those who receive copies directly or indirectly through you, then\r\nthe only way you could satisfy both it and this License would be to\r\nrefrain entirely from distribution of the Library.\r\n\r\nIf any portion of this section is held invalid or unenforceable under any\r\nparticular circumstance, the balance of the section is intended to apply,\r\nand the section as a whole is intended to apply in other circumstances.\r\n\r\nIt is not the purpose of this section to induce you to infringe any\r\npatents or other property right claims or to contest validity of any\r\nsuch claims; this section has the sole purpose of protecting the\r\nintegrity of the free software distribution system which is\r\nimplemented by public license practices.  Many people have made\r\ngenerous contributions to the wide range of software distributed\r\nthrough that system in reliance on consistent application of that\r\nsystem; it is up to the author/donor to decide if he or she is willing\r\nto distribute software through any other system and a licensee cannot\r\nimpose that choice.\r\n\r\nThis section is intended to make thoroughly clear what is believed to\r\nbe a consequence of the rest of this License.\r\n\r\n  12. If the distribution and/or use of the Library is restricted in\r\ncertain countries either by patents or by copyrighted interfaces, the\r\noriginal copyright holder who places the Library under this License may add\r\nan explicit geographical distribution limitation excluding those countries,\r\nso that distribution is permitted only in or among countries not thus\r\nexcluded.  In such case, this License incorporates the limitation as if\r\nwritten in the body of this License.\r\n\r\n  13. The Free Software Foundation may publish revised and/or new\r\nversions of the Lesser General Public License from time to time.\r\nSuch new versions will be similar in spirit to the present version,\r\nbut may differ in detail to address new problems or concerns.\r\n\r\nEach version is given a distinguishing version number.  If the Library\r\nspecifies a version number of this License which applies to it and\r\n\"any later version\", you have the option of following the terms and\r\nconditions either of that version or of any later version published by\r\nthe Free Software Foundation.  If the Library does not specify a\r\nlicense version number, you may choose any version ever published by\r\nthe Free Software Foundation.\r\n\f\r\n  14. If you wish to incorporate parts of the Library into other free\r\nprograms whose distribution conditions are incompatible with these,\r\nwrite to the author to ask for permission.  For software which is\r\ncopyrighted by the Free Software Foundation, write to the Free\r\nSoftware Foundation; we sometimes make exceptions for this.  Our\r\ndecision will be guided by the two goals of preserving the free status\r\nof all derivatives of our free software and of promoting the sharing\r\nand reuse of software generally.\r\n\r\n\t\t\t    NO WARRANTY\r\n\r\n  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO\r\nWARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\r\nEXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\r\nOTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY\r\nKIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE\r\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\r\nLIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME\r\nTHE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\r\n\r\n  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\r\nWRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\r\nAND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU\r\nFOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR\r\nCONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\r\nLIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\r\nRENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\r\nFAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF\r\nSUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\r\nDAMAGES.\r\n\r\n\t\t     END OF TERMS AND CONDITIONS\r\n\f\r\n           How to Apply These Terms to Your New Libraries\r\n\r\n  If you develop a new library, and you want it to be of the greatest\r\npossible use to the public, we recommend making it free software that\r\neveryone can redistribute and change.  You can do so by permitting\r\nredistribution under these terms (or, alternatively, under the terms of the\r\nordinary General Public License).\r\n\r\n  To apply these terms, attach the following notices to the library.  It is\r\nsafest to attach them to the start of each source file to most effectively\r\nconvey the exclusion of warranty; and each file should have at least the\r\n\"copyright\" line and a pointer to where the full notice is found.\r\n\r\n    <one line to give the library's name and a brief idea of what it does.>\r\n    Copyright (C) <year>  <name of author>\r\n\r\n    This library is free software; you can redistribute it and/or\r\n    modify it under the terms of the GNU Lesser General Public\r\n    License as published by the Free Software Foundation; either\r\n    version 2.1 of the License, or (at your option) any later version.\r\n\r\n    This library is distributed in the hope that it will be useful,\r\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n    Lesser General Public License for more details.\r\n\r\n    You should have received a copy of the GNU Lesser General Public\r\n    License along with this library; if not, write to the Free Software\r\n    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r\n\r\nAlso add information on how to contact you by electronic and paper mail.\r\n\r\nYou should also get your employer (if you work as a programmer) or your\r\nschool, if any, to sign a \"copyright disclaimer\" for the library, if\r\nnecessary.  Here is a sample; alter the names:\r\n\r\n  Yoyodyne, Inc., hereby disclaims all copyright interest in the\r\n  library `Frob' (a library for tweaking knobs) written by James Random Hacker.\r\n\r\n  <signature of Ty Coon>, 1 April 1990\r\n  Ty Coon, President of Vice\r\n\r\nThat's all there is to it!\r\n\r\n\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/PCLZip/pclzip.lib.php",
    "content": "<?php\r\n// --------------------------------------------------------------------------------\r\n// PhpConcept Library - Zip Module 2.8.2\r\n// --------------------------------------------------------------------------------\r\n// License GNU/LGPL - Vincent Blavet - August 2009\r\n// http://www.phpconcept.net\r\n// --------------------------------------------------------------------------------\r\n//\r\n// Presentation :\r\n//   PclZip is a PHP library that manage ZIP archives.\r\n//   So far tests show that archives generated by PclZip are readable by\r\n//   WinZip application and other tools.\r\n//\r\n// Description :\r\n//   See readme.txt and http://www.phpconcept.net\r\n//\r\n// Warning :\r\n//   This library and the associated files are non commercial, non professional\r\n//   work.\r\n//   It should not have unexpected results. However if any damage is caused by\r\n//   this software the author can not be responsible.\r\n//   The use of this software is at the risk of the user.\r\n//\r\n// --------------------------------------------------------------------------------\r\n// $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $\r\n// --------------------------------------------------------------------------------\r\n\r\n  // ----- Constants\r\n  if (!defined('PCLZIP_READ_BLOCK_SIZE')) {\r\n    define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );\r\n  }\r\n  \r\n  // ----- File list separator\r\n  // In version 1.x of PclZip, the separator for file list is a space\r\n  // (which is not a very smart choice, specifically for windows paths !).\r\n  // A better separator should be a comma (,). This constant gives you the\r\n  // abilty to change that.\r\n  // However notice that changing this value, may have impact on existing\r\n  // scripts, using space separated filenames.\r\n  // Recommanded values for compatibility with older versions :\r\n  //define( 'PCLZIP_SEPARATOR', ' ' );\r\n  // Recommanded values for smart separation of filenames.\r\n  if (!defined('PCLZIP_SEPARATOR')) {\r\n    define( 'PCLZIP_SEPARATOR', ',' );\r\n  }\r\n\r\n  // ----- Error configuration\r\n  // 0 : PclZip Class integrated error handling\r\n  // 1 : PclError external library error handling. By enabling this\r\n  //     you must ensure that you have included PclError library.\r\n  // [2,...] : reserved for futur use\r\n  if (!defined('PCLZIP_ERROR_EXTERNAL')) {\r\n    define( 'PCLZIP_ERROR_EXTERNAL', 0 );\r\n  }\r\n\r\n  // ----- Optional static temporary directory\r\n  //       By default temporary files are generated in the script current\r\n  //       path.\r\n  //       If defined :\r\n  //       - MUST BE terminated by a '/'.\r\n  //       - MUST be a valid, already created directory\r\n  //       Samples :\r\n  // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );\r\n  // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );\r\n  if (!defined('PCLZIP_TEMPORARY_DIR')) {\r\n    define( 'PCLZIP_TEMPORARY_DIR', '' );\r\n  }\r\n\r\n  // ----- Optional threshold ratio for use of temporary files\r\n  //       Pclzip sense the size of the file to add/extract and decide to\r\n  //       use or not temporary file. The algorythm is looking for \r\n  //       memory_limit of PHP and apply a ratio.\r\n  //       threshold = memory_limit * ratio.\r\n  //       Recommended values are under 0.5. Default 0.47.\r\n  //       Samples :\r\n  // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 );\r\n  if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {\r\n    define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );\r\n  }\r\n\r\n// --------------------------------------------------------------------------------\r\n// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****\r\n// --------------------------------------------------------------------------------\r\n\r\n  // ----- Global variables\r\n  $g_pclzip_version = \"2.8.2\";\r\n\r\n  // ----- Error codes\r\n  //   -1 : Unable to open file in binary write mode\r\n  //   -2 : Unable to open file in binary read mode\r\n  //   -3 : Invalid parameters\r\n  //   -4 : File does not exist\r\n  //   -5 : Filename is too long (max. 255)\r\n  //   -6 : Not a valid zip file\r\n  //   -7 : Invalid extracted file size\r\n  //   -8 : Unable to create directory\r\n  //   -9 : Invalid archive extension\r\n  //  -10 : Invalid archive format\r\n  //  -11 : Unable to delete file (unlink)\r\n  //  -12 : Unable to rename file (rename)\r\n  //  -13 : Invalid header checksum\r\n  //  -14 : Invalid archive size\r\n  define( 'PCLZIP_ERR_USER_ABORTED', 2 );\r\n  define( 'PCLZIP_ERR_NO_ERROR', 0 );\r\n  define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );\r\n  define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );\r\n  define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );\r\n  define( 'PCLZIP_ERR_MISSING_FILE', -4 );\r\n  define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );\r\n  define( 'PCLZIP_ERR_INVALID_ZIP', -6 );\r\n  define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );\r\n  define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );\r\n  define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );\r\n  define( 'PCLZIP_ERR_BAD_FORMAT', -10 );\r\n  define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );\r\n  define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );\r\n  define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );\r\n  define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );\r\n  define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );\r\n  define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );\r\n  define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );\r\n  define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );\r\n  define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );\r\n  define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );\r\n  define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );\r\n\r\n  // ----- Options values\r\n  define( 'PCLZIP_OPT_PATH', 77001 );\r\n  define( 'PCLZIP_OPT_ADD_PATH', 77002 );\r\n  define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );\r\n  define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );\r\n  define( 'PCLZIP_OPT_SET_CHMOD', 77005 );\r\n  define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );\r\n  define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );\r\n  define( 'PCLZIP_OPT_BY_NAME', 77008 );\r\n  define( 'PCLZIP_OPT_BY_INDEX', 77009 );\r\n  define( 'PCLZIP_OPT_BY_EREG', 77010 );\r\n  define( 'PCLZIP_OPT_BY_PREG', 77011 );\r\n  define( 'PCLZIP_OPT_COMMENT', 77012 );\r\n  define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );\r\n  define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );\r\n  define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );\r\n  define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );\r\n  define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );\r\n  // Having big trouble with crypt. Need to multiply 2 long int\r\n  // which is not correctly supported by PHP ...\r\n  //define( 'PCLZIP_OPT_CRYPT', 77018 );\r\n  define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );\r\n  define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );\r\n  define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias\r\n  define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );\r\n  define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias\r\n  define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );\r\n  define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias\r\n  \r\n  // ----- File description attributes\r\n  define( 'PCLZIP_ATT_FILE_NAME', 79001 );\r\n  define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );\r\n  define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );\r\n  define( 'PCLZIP_ATT_FILE_MTIME', 79004 );\r\n  define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );\r\n  define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );\r\n\r\n  // ----- Call backs values\r\n  define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );\r\n  define( 'PCLZIP_CB_POST_EXTRACT', 78002 );\r\n  define( 'PCLZIP_CB_PRE_ADD', 78003 );\r\n  define( 'PCLZIP_CB_POST_ADD', 78004 );\r\n  /* For futur use\r\n  define( 'PCLZIP_CB_PRE_LIST', 78005 );\r\n  define( 'PCLZIP_CB_POST_LIST', 78006 );\r\n  define( 'PCLZIP_CB_PRE_DELETE', 78007 );\r\n  define( 'PCLZIP_CB_POST_DELETE', 78008 );\r\n  */\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Class : PclZip\r\n  // Description :\r\n  //   PclZip is the class that represent a Zip archive.\r\n  //   The public methods allow the manipulation of the archive.\r\n  // Attributes :\r\n  //   Attributes must not be accessed directly.\r\n  // Methods :\r\n  //   PclZip() : Object creator\r\n  //   create() : Creates the Zip archive\r\n  //   listContent() : List the content of the Zip archive\r\n  //   extract() : Extract the content of the archive\r\n  //   properties() : List the properties of the archive\r\n  // --------------------------------------------------------------------------------\r\n  class PclZip\r\n  {\r\n    // ----- Filename of the zip file\r\n    var $zipname = '';\r\n\r\n    // ----- File descriptor of the zip file\r\n    var $zip_fd = 0;\r\n\r\n    // ----- Internal error handling\r\n    var $error_code = 1;\r\n    var $error_string = '';\r\n    \r\n    // ----- Current status of the magic_quotes_runtime\r\n    // This value store the php configuration for magic_quotes\r\n    // The class can then disable the magic_quotes and reset it after\r\n    var $magic_quotes_status;\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : PclZip()\r\n  // Description :\r\n  //   Creates a PclZip object and set the name of the associated Zip archive\r\n  //   filename.\r\n  //   Note that no real action is taken, if the archive does not exist it is not\r\n  //   created. Use create() for that.\r\n  // --------------------------------------------------------------------------------\r\n  function PclZip($p_zipname)\r\n  {\r\n\r\n    // ----- Tests the zlib\r\n    if (!function_exists('gzopen'))\r\n    {\r\n      die('Abort '.basename(__FILE__).' : Missing zlib extensions');\r\n    }\r\n\r\n    // ----- Set the attributes\r\n    $this->zipname = $p_zipname;\r\n    $this->zip_fd = 0;\r\n    $this->magic_quotes_status = -1;\r\n\r\n    // ----- Return\r\n    return;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function :\r\n  //   create($p_filelist, $p_add_dir=\"\", $p_remove_dir=\"\")\r\n  //   create($p_filelist, $p_option, $p_option_value, ...)\r\n  // Description :\r\n  //   This method supports two different synopsis. The first one is historical.\r\n  //   This method creates a Zip Archive. The Zip file is created in the\r\n  //   filesystem. The files and directories indicated in $p_filelist\r\n  //   are added in the archive. See the parameters description for the\r\n  //   supported format of $p_filelist.\r\n  //   When a directory is in the list, the directory and its content is added\r\n  //   in the archive.\r\n  //   In this synopsis, the function takes an optional variable list of\r\n  //   options. See bellow the supported options.\r\n  // Parameters :\r\n  //   $p_filelist : An array containing file or directory names, or\r\n  //                 a string containing one filename or one directory name, or\r\n  //                 a string containing a list of filenames and/or directory\r\n  //                 names separated by spaces.\r\n  //   $p_add_dir : A path to add before the real path of the archived file,\r\n  //                in order to have it memorized in the archive.\r\n  //   $p_remove_dir : A path to remove from the real path of the file to archive,\r\n  //                   in order to have a shorter path memorized in the archive.\r\n  //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir\r\n  //                   is removed first, before $p_add_dir is added.\r\n  // Options :\r\n  //   PCLZIP_OPT_ADD_PATH :\r\n  //   PCLZIP_OPT_REMOVE_PATH :\r\n  //   PCLZIP_OPT_REMOVE_ALL_PATH :\r\n  //   PCLZIP_OPT_COMMENT :\r\n  //   PCLZIP_CB_PRE_ADD :\r\n  //   PCLZIP_CB_POST_ADD :\r\n  // Return Values :\r\n  //   0 on failure,\r\n  //   The list of the added files, with a status of the add action.\r\n  //   (see PclZip::listContent() for list entry format)\r\n  // --------------------------------------------------------------------------------\r\n  function create($p_filelist)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Reset the error handler\r\n    $this->privErrorReset();\r\n\r\n    // ----- Set default values\r\n    $v_options = array();\r\n    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;\r\n\r\n    // ----- Look for variable options arguments\r\n    $v_size = func_num_args();\r\n\r\n    // ----- Look for arguments\r\n    if ($v_size > 1) {\r\n      // ----- Get the arguments\r\n      $v_arg_list = func_get_args();\r\n\r\n      // ----- Remove from the options list the first argument\r\n      array_shift($v_arg_list);\r\n      $v_size--;\r\n\r\n      // ----- Look for first arg\r\n      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {\r\n\r\n        // ----- Parse the options\r\n        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,\r\n                                            array (PCLZIP_OPT_REMOVE_PATH => 'optional',\r\n                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',\r\n                                                   PCLZIP_OPT_ADD_PATH => 'optional',\r\n                                                   PCLZIP_CB_PRE_ADD => 'optional',\r\n                                                   PCLZIP_CB_POST_ADD => 'optional',\r\n                                                   PCLZIP_OPT_NO_COMPRESSION => 'optional',\r\n                                                   PCLZIP_OPT_COMMENT => 'optional',\r\n                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',\r\n                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',\r\n                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'\r\n                                                   //, PCLZIP_OPT_CRYPT => 'optional'\r\n                                             ));\r\n        if ($v_result != 1) {\r\n          return 0;\r\n        }\r\n      }\r\n\r\n      // ----- Look for 2 args\r\n      // Here we need to support the first historic synopsis of the\r\n      // method.\r\n      else {\r\n\r\n        // ----- Get the first argument\r\n        $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];\r\n\r\n        // ----- Look for the optional second argument\r\n        if ($v_size == 2) {\r\n          $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];\r\n        }\r\n        else if ($v_size > 2) {\r\n          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,\r\n\t\t                       \"Invalid number / type of arguments\");\r\n          return 0;\r\n        }\r\n      }\r\n    }\r\n    \r\n    // ----- Look for default option values\r\n    $this->privOptionDefaultThreshold($v_options);\r\n\r\n    // ----- Init\r\n    $v_string_list = array();\r\n    $v_att_list = array();\r\n    $v_filedescr_list = array();\r\n    $p_result_list = array();\r\n    \r\n    // ----- Look if the $p_filelist is really an array\r\n    if (is_array($p_filelist)) {\r\n    \r\n      // ----- Look if the first element is also an array\r\n      //       This will mean that this is a file description entry\r\n      if (isset($p_filelist[0]) && is_array($p_filelist[0])) {\r\n        $v_att_list = $p_filelist;\r\n      }\r\n      \r\n      // ----- The list is a list of string names\r\n      else {\r\n        $v_string_list = $p_filelist;\r\n      }\r\n    }\r\n\r\n    // ----- Look if the $p_filelist is a string\r\n    else if (is_string($p_filelist)) {\r\n      // ----- Create a list from the string\r\n      $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);\r\n    }\r\n\r\n    // ----- Invalid variable type for $p_filelist\r\n    else {\r\n      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Invalid variable type p_filelist\");\r\n      return 0;\r\n    }\r\n    \r\n    // ----- Reformat the string list\r\n    if (sizeof($v_string_list) != 0) {\r\n      foreach ($v_string_list as $v_string) {\r\n        if ($v_string != '') {\r\n          $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;\r\n        }\r\n        else {\r\n        }\r\n      }\r\n    }\r\n    \r\n    // ----- For each file in the list check the attributes\r\n    $v_supported_attributes\r\n    = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'\r\n             ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'\r\n             ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'\r\n             ,PCLZIP_ATT_FILE_MTIME => 'optional'\r\n             ,PCLZIP_ATT_FILE_CONTENT => 'optional'\r\n             ,PCLZIP_ATT_FILE_COMMENT => 'optional'\r\n\t\t\t\t\t\t);\r\n    foreach ($v_att_list as $v_entry) {\r\n      $v_result = $this->privFileDescrParseAtt($v_entry,\r\n                                               $v_filedescr_list[],\r\n                                               $v_options,\r\n                                               $v_supported_attributes);\r\n      if ($v_result != 1) {\r\n        return 0;\r\n      }\r\n    }\r\n\r\n    // ----- Expand the filelist (expand directories)\r\n    $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);\r\n    if ($v_result != 1) {\r\n      return 0;\r\n    }\r\n\r\n    // ----- Call the create fct\r\n    $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);\r\n    if ($v_result != 1) {\r\n      return 0;\r\n    }\r\n\r\n    // ----- Return\r\n    return $p_result_list;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function :\r\n  //   add($p_filelist, $p_add_dir=\"\", $p_remove_dir=\"\")\r\n  //   add($p_filelist, $p_option, $p_option_value, ...)\r\n  // Description :\r\n  //   This method supports two synopsis. The first one is historical.\r\n  //   This methods add the list of files in an existing archive.\r\n  //   If a file with the same name already exists, it is added at the end of the\r\n  //   archive, the first one is still present.\r\n  //   If the archive does not exist, it is created.\r\n  // Parameters :\r\n  //   $p_filelist : An array containing file or directory names, or\r\n  //                 a string containing one filename or one directory name, or\r\n  //                 a string containing a list of filenames and/or directory\r\n  //                 names separated by spaces.\r\n  //   $p_add_dir : A path to add before the real path of the archived file,\r\n  //                in order to have it memorized in the archive.\r\n  //   $p_remove_dir : A path to remove from the real path of the file to archive,\r\n  //                   in order to have a shorter path memorized in the archive.\r\n  //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir\r\n  //                   is removed first, before $p_add_dir is added.\r\n  // Options :\r\n  //   PCLZIP_OPT_ADD_PATH :\r\n  //   PCLZIP_OPT_REMOVE_PATH :\r\n  //   PCLZIP_OPT_REMOVE_ALL_PATH :\r\n  //   PCLZIP_OPT_COMMENT :\r\n  //   PCLZIP_OPT_ADD_COMMENT :\r\n  //   PCLZIP_OPT_PREPEND_COMMENT :\r\n  //   PCLZIP_CB_PRE_ADD :\r\n  //   PCLZIP_CB_POST_ADD :\r\n  // Return Values :\r\n  //   0 on failure,\r\n  //   The list of the added files, with a status of the add action.\r\n  //   (see PclZip::listContent() for list entry format)\r\n  // --------------------------------------------------------------------------------\r\n  function add($p_filelist)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Reset the error handler\r\n    $this->privErrorReset();\r\n\r\n    // ----- Set default values\r\n    $v_options = array();\r\n    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;\r\n\r\n    // ----- Look for variable options arguments\r\n    $v_size = func_num_args();\r\n\r\n    // ----- Look for arguments\r\n    if ($v_size > 1) {\r\n      // ----- Get the arguments\r\n      $v_arg_list = func_get_args();\r\n\r\n      // ----- Remove form the options list the first argument\r\n      array_shift($v_arg_list);\r\n      $v_size--;\r\n\r\n      // ----- Look for first arg\r\n      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {\r\n\r\n        // ----- Parse the options\r\n        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,\r\n                                            array (PCLZIP_OPT_REMOVE_PATH => 'optional',\r\n                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',\r\n                                                   PCLZIP_OPT_ADD_PATH => 'optional',\r\n                                                   PCLZIP_CB_PRE_ADD => 'optional',\r\n                                                   PCLZIP_CB_POST_ADD => 'optional',\r\n                                                   PCLZIP_OPT_NO_COMPRESSION => 'optional',\r\n                                                   PCLZIP_OPT_COMMENT => 'optional',\r\n                                                   PCLZIP_OPT_ADD_COMMENT => 'optional',\r\n                                                   PCLZIP_OPT_PREPEND_COMMENT => 'optional',\r\n                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',\r\n                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',\r\n                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'\r\n                                                   //, PCLZIP_OPT_CRYPT => 'optional'\r\n\t\t\t\t\t\t\t\t\t\t\t\t   ));\r\n        if ($v_result != 1) {\r\n          return 0;\r\n        }\r\n      }\r\n\r\n      // ----- Look for 2 args\r\n      // Here we need to support the first historic synopsis of the\r\n      // method.\r\n      else {\r\n\r\n        // ----- Get the first argument\r\n        $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];\r\n\r\n        // ----- Look for the optional second argument\r\n        if ($v_size == 2) {\r\n          $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];\r\n        }\r\n        else if ($v_size > 2) {\r\n          // ----- Error log\r\n          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Invalid number / type of arguments\");\r\n\r\n          // ----- Return\r\n          return 0;\r\n        }\r\n      }\r\n    }\r\n\r\n    // ----- Look for default option values\r\n    $this->privOptionDefaultThreshold($v_options);\r\n\r\n    // ----- Init\r\n    $v_string_list = array();\r\n    $v_att_list = array();\r\n    $v_filedescr_list = array();\r\n    $p_result_list = array();\r\n    \r\n    // ----- Look if the $p_filelist is really an array\r\n    if (is_array($p_filelist)) {\r\n    \r\n      // ----- Look if the first element is also an array\r\n      //       This will mean that this is a file description entry\r\n      if (isset($p_filelist[0]) && is_array($p_filelist[0])) {\r\n        $v_att_list = $p_filelist;\r\n      }\r\n      \r\n      // ----- The list is a list of string names\r\n      else {\r\n        $v_string_list = $p_filelist;\r\n      }\r\n    }\r\n\r\n    // ----- Look if the $p_filelist is a string\r\n    else if (is_string($p_filelist)) {\r\n      // ----- Create a list from the string\r\n      $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);\r\n    }\r\n\r\n    // ----- Invalid variable type for $p_filelist\r\n    else {\r\n      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Invalid variable type '\".gettype($p_filelist).\"' for p_filelist\");\r\n      return 0;\r\n    }\r\n    \r\n    // ----- Reformat the string list\r\n    if (sizeof($v_string_list) != 0) {\r\n      foreach ($v_string_list as $v_string) {\r\n        $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;\r\n      }\r\n    }\r\n    \r\n    // ----- For each file in the list check the attributes\r\n    $v_supported_attributes\r\n    = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'\r\n             ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'\r\n             ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'\r\n             ,PCLZIP_ATT_FILE_MTIME => 'optional'\r\n             ,PCLZIP_ATT_FILE_CONTENT => 'optional'\r\n             ,PCLZIP_ATT_FILE_COMMENT => 'optional'\r\n\t\t\t\t\t\t);\r\n    foreach ($v_att_list as $v_entry) {\r\n      $v_result = $this->privFileDescrParseAtt($v_entry,\r\n                                               $v_filedescr_list[],\r\n                                               $v_options,\r\n                                               $v_supported_attributes);\r\n      if ($v_result != 1) {\r\n        return 0;\r\n      }\r\n    }\r\n\r\n    // ----- Expand the filelist (expand directories)\r\n    $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);\r\n    if ($v_result != 1) {\r\n      return 0;\r\n    }\r\n\r\n    // ----- Call the create fct\r\n    $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);\r\n    if ($v_result != 1) {\r\n      return 0;\r\n    }\r\n\r\n    // ----- Return\r\n    return $p_result_list;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : listContent()\r\n  // Description :\r\n  //   This public method, gives the list of the files and directories, with their\r\n  //   properties.\r\n  //   The properties of each entries in the list are (used also in other functions) :\r\n  //     filename : Name of the file. For a create or add action it is the filename\r\n  //                given by the user. For an extract function it is the filename\r\n  //                of the extracted file.\r\n  //     stored_filename : Name of the file / directory stored in the archive.\r\n  //     size : Size of the stored file.\r\n  //     compressed_size : Size of the file's data compressed in the archive\r\n  //                       (without the headers overhead)\r\n  //     mtime : Last known modification date of the file (UNIX timestamp)\r\n  //     comment : Comment associated with the file\r\n  //     folder : true | false\r\n  //     index : index of the file in the archive\r\n  //     status : status of the action (depending of the action) :\r\n  //              Values are :\r\n  //                ok : OK !\r\n  //                filtered : the file / dir is not extracted (filtered by user)\r\n  //                already_a_directory : the file can not be extracted because a\r\n  //                                      directory with the same name already exists\r\n  //                write_protected : the file can not be extracted because a file\r\n  //                                  with the same name already exists and is\r\n  //                                  write protected\r\n  //                newer_exist : the file was not extracted because a newer file exists\r\n  //                path_creation_fail : the file is not extracted because the folder\r\n  //                                     does not exist and can not be created\r\n  //                write_error : the file was not extracted because there was a\r\n  //                              error while writing the file\r\n  //                read_error : the file was not extracted because there was a error\r\n  //                             while reading the file\r\n  //                invalid_header : the file was not extracted because of an archive\r\n  //                                 format error (bad file header)\r\n  //   Note that each time a method can continue operating when there\r\n  //   is an action error on a file, the error is only logged in the file status.\r\n  // Return Values :\r\n  //   0 on an unrecoverable failure,\r\n  //   The list of the files in the archive.\r\n  // --------------------------------------------------------------------------------\r\n  function listContent()\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Reset the error handler\r\n    $this->privErrorReset();\r\n\r\n    // ----- Check archive\r\n    if (!$this->privCheckFormat()) {\r\n      return(0);\r\n    }\r\n\r\n    // ----- Call the extracting fct\r\n    $p_list = array();\r\n    if (($v_result = $this->privList($p_list)) != 1)\r\n    {\r\n      unset($p_list);\r\n      return(0);\r\n    }\r\n\r\n    // ----- Return\r\n    return $p_list;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function :\r\n  //   extract($p_path=\"./\", $p_remove_path=\"\")\r\n  //   extract([$p_option, $p_option_value, ...])\r\n  // Description :\r\n  //   This method supports two synopsis. The first one is historical.\r\n  //   This method extract all the files / directories from the archive to the\r\n  //   folder indicated in $p_path.\r\n  //   If you want to ignore the 'root' part of path of the memorized files\r\n  //   you can indicate this in the optional $p_remove_path parameter.\r\n  //   By default, if a newer file with the same name already exists, the\r\n  //   file is not extracted.\r\n  //\r\n  //   If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions\r\n  //   are used, the path indicated in PCLZIP_OPT_ADD_PATH is append\r\n  //   at the end of the path value of PCLZIP_OPT_PATH.\r\n  // Parameters :\r\n  //   $p_path : Path where the files and directories are to be extracted\r\n  //   $p_remove_path : First part ('root' part) of the memorized path\r\n  //                    (if any similar) to remove while extracting.\r\n  // Options :\r\n  //   PCLZIP_OPT_PATH :\r\n  //   PCLZIP_OPT_ADD_PATH :\r\n  //   PCLZIP_OPT_REMOVE_PATH :\r\n  //   PCLZIP_OPT_REMOVE_ALL_PATH :\r\n  //   PCLZIP_CB_PRE_EXTRACT :\r\n  //   PCLZIP_CB_POST_EXTRACT :\r\n  // Return Values :\r\n  //   0 or a negative value on failure,\r\n  //   The list of the extracted files, with a status of the action.\r\n  //   (see PclZip::listContent() for list entry format)\r\n  // --------------------------------------------------------------------------------\r\n  function extract()\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Reset the error handler\r\n    $this->privErrorReset();\r\n\r\n    // ----- Check archive\r\n    if (!$this->privCheckFormat()) {\r\n      return(0);\r\n    }\r\n\r\n    // ----- Set default values\r\n    $v_options = array();\r\n//    $v_path = \"./\";\r\n    $v_path = '';\r\n    $v_remove_path = \"\";\r\n    $v_remove_all_path = false;\r\n\r\n    // ----- Look for variable options arguments\r\n    $v_size = func_num_args();\r\n\r\n    // ----- Default values for option\r\n    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;\r\n\r\n    // ----- Look for arguments\r\n    if ($v_size > 0) {\r\n      // ----- Get the arguments\r\n      $v_arg_list = func_get_args();\r\n\r\n      // ----- Look for first arg\r\n      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {\r\n\r\n        // ----- Parse the options\r\n        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,\r\n                                            array (PCLZIP_OPT_PATH => 'optional',\r\n                                                   PCLZIP_OPT_REMOVE_PATH => 'optional',\r\n                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',\r\n                                                   PCLZIP_OPT_ADD_PATH => 'optional',\r\n                                                   PCLZIP_CB_PRE_EXTRACT => 'optional',\r\n                                                   PCLZIP_CB_POST_EXTRACT => 'optional',\r\n                                                   PCLZIP_OPT_SET_CHMOD => 'optional',\r\n                                                   PCLZIP_OPT_BY_NAME => 'optional',\r\n                                                   PCLZIP_OPT_BY_EREG => 'optional',\r\n                                                   PCLZIP_OPT_BY_PREG => 'optional',\r\n                                                   PCLZIP_OPT_BY_INDEX => 'optional',\r\n                                                   PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',\r\n                                                   PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',\r\n                                                   PCLZIP_OPT_REPLACE_NEWER => 'optional'\r\n                                                   ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'\r\n                                                   ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',\r\n                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',\r\n                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',\r\n                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'\r\n\t\t\t\t\t\t\t\t\t\t\t\t    ));\r\n        if ($v_result != 1) {\r\n          return 0;\r\n        }\r\n\r\n        // ----- Set the arguments\r\n        if (isset($v_options[PCLZIP_OPT_PATH])) {\r\n          $v_path = $v_options[PCLZIP_OPT_PATH];\r\n        }\r\n        if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {\r\n          $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];\r\n        }\r\n        if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {\r\n          $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];\r\n        }\r\n        if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {\r\n          // ----- Check for '/' in last path char\r\n          if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {\r\n            $v_path .= '/';\r\n          }\r\n          $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];\r\n        }\r\n      }\r\n\r\n      // ----- Look for 2 args\r\n      // Here we need to support the first historic synopsis of the\r\n      // method.\r\n      else {\r\n\r\n        // ----- Get the first argument\r\n        $v_path = $v_arg_list[0];\r\n\r\n        // ----- Look for the optional second argument\r\n        if ($v_size == 2) {\r\n          $v_remove_path = $v_arg_list[1];\r\n        }\r\n        else if ($v_size > 2) {\r\n          // ----- Error log\r\n          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Invalid number / type of arguments\");\r\n\r\n          // ----- Return\r\n          return 0;\r\n        }\r\n      }\r\n    }\r\n\r\n    // ----- Look for default option values\r\n    $this->privOptionDefaultThreshold($v_options);\r\n\r\n    // ----- Trace\r\n\r\n    // ----- Call the extracting fct\r\n    $p_list = array();\r\n    $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,\r\n\t                                     $v_remove_all_path, $v_options);\r\n    if ($v_result < 1) {\r\n      unset($p_list);\r\n      return(0);\r\n    }\r\n\r\n    // ----- Return\r\n    return $p_list;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function :\r\n  //   extractByIndex($p_index, $p_path=\"./\", $p_remove_path=\"\")\r\n  //   extractByIndex($p_index, [$p_option, $p_option_value, ...])\r\n  // Description :\r\n  //   This method supports two synopsis. The first one is historical.\r\n  //   This method is doing a partial extract of the archive.\r\n  //   The extracted files or folders are identified by their index in the\r\n  //   archive (from 0 to n).\r\n  //   Note that if the index identify a folder, only the folder entry is\r\n  //   extracted, not all the files included in the archive.\r\n  // Parameters :\r\n  //   $p_index : A single index (integer) or a string of indexes of files to\r\n  //              extract. The form of the string is \"0,4-6,8-12\" with only numbers\r\n  //              and '-' for range or ',' to separate ranges. No spaces or ';'\r\n  //              are allowed.\r\n  //   $p_path : Path where the files and directories are to be extracted\r\n  //   $p_remove_path : First part ('root' part) of the memorized path\r\n  //                    (if any similar) to remove while extracting.\r\n  // Options :\r\n  //   PCLZIP_OPT_PATH :\r\n  //   PCLZIP_OPT_ADD_PATH :\r\n  //   PCLZIP_OPT_REMOVE_PATH :\r\n  //   PCLZIP_OPT_REMOVE_ALL_PATH :\r\n  //   PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and\r\n  //     not as files.\r\n  //     The resulting content is in a new field 'content' in the file\r\n  //     structure.\r\n  //     This option must be used alone (any other options are ignored).\r\n  //   PCLZIP_CB_PRE_EXTRACT :\r\n  //   PCLZIP_CB_POST_EXTRACT :\r\n  // Return Values :\r\n  //   0 on failure,\r\n  //   The list of the extracted files, with a status of the action.\r\n  //   (see PclZip::listContent() for list entry format)\r\n  // --------------------------------------------------------------------------------\r\n  //function extractByIndex($p_index, options...)\r\n  function extractByIndex($p_index)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Reset the error handler\r\n    $this->privErrorReset();\r\n\r\n    // ----- Check archive\r\n    if (!$this->privCheckFormat()) {\r\n      return(0);\r\n    }\r\n\r\n    // ----- Set default values\r\n    $v_options = array();\r\n//    $v_path = \"./\";\r\n    $v_path = '';\r\n    $v_remove_path = \"\";\r\n    $v_remove_all_path = false;\r\n\r\n    // ----- Look for variable options arguments\r\n    $v_size = func_num_args();\r\n\r\n    // ----- Default values for option\r\n    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;\r\n\r\n    // ----- Look for arguments\r\n    if ($v_size > 1) {\r\n      // ----- Get the arguments\r\n      $v_arg_list = func_get_args();\r\n\r\n      // ----- Remove form the options list the first argument\r\n      array_shift($v_arg_list);\r\n      $v_size--;\r\n\r\n      // ----- Look for first arg\r\n      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {\r\n\r\n        // ----- Parse the options\r\n        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,\r\n                                            array (PCLZIP_OPT_PATH => 'optional',\r\n                                                   PCLZIP_OPT_REMOVE_PATH => 'optional',\r\n                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',\r\n                                                   PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',\r\n                                                   PCLZIP_OPT_ADD_PATH => 'optional',\r\n                                                   PCLZIP_CB_PRE_EXTRACT => 'optional',\r\n                                                   PCLZIP_CB_POST_EXTRACT => 'optional',\r\n                                                   PCLZIP_OPT_SET_CHMOD => 'optional',\r\n                                                   PCLZIP_OPT_REPLACE_NEWER => 'optional'\r\n                                                   ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'\r\n                                                   ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',\r\n                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',\r\n                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',\r\n                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'\r\n\t\t\t\t\t\t\t\t\t\t\t\t   ));\r\n        if ($v_result != 1) {\r\n          return 0;\r\n        }\r\n\r\n        // ----- Set the arguments\r\n        if (isset($v_options[PCLZIP_OPT_PATH])) {\r\n          $v_path = $v_options[PCLZIP_OPT_PATH];\r\n        }\r\n        if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {\r\n          $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];\r\n        }\r\n        if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {\r\n          $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];\r\n        }\r\n        if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {\r\n          // ----- Check for '/' in last path char\r\n          if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {\r\n            $v_path .= '/';\r\n          }\r\n          $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];\r\n        }\r\n        if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {\r\n          $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;\r\n        }\r\n        else {\r\n        }\r\n      }\r\n\r\n      // ----- Look for 2 args\r\n      // Here we need to support the first historic synopsis of the\r\n      // method.\r\n      else {\r\n\r\n        // ----- Get the first argument\r\n        $v_path = $v_arg_list[0];\r\n\r\n        // ----- Look for the optional second argument\r\n        if ($v_size == 2) {\r\n          $v_remove_path = $v_arg_list[1];\r\n        }\r\n        else if ($v_size > 2) {\r\n          // ----- Error log\r\n          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Invalid number / type of arguments\");\r\n\r\n          // ----- Return\r\n          return 0;\r\n        }\r\n      }\r\n    }\r\n\r\n    // ----- Trace\r\n\r\n    // ----- Trick\r\n    // Here I want to reuse extractByRule(), so I need to parse the $p_index\r\n    // with privParseOptions()\r\n    $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);\r\n    $v_options_trick = array();\r\n    $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,\r\n                                        array (PCLZIP_OPT_BY_INDEX => 'optional' ));\r\n    if ($v_result != 1) {\r\n        return 0;\r\n    }\r\n    $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];\r\n\r\n    // ----- Look for default option values\r\n    $this->privOptionDefaultThreshold($v_options);\r\n\r\n    // ----- Call the extracting fct\r\n    if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {\r\n        return(0);\r\n    }\r\n\r\n    // ----- Return\r\n    return $p_list;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function :\r\n  //   delete([$p_option, $p_option_value, ...])\r\n  // Description :\r\n  //   This method removes files from the archive.\r\n  //   If no parameters are given, then all the archive is emptied.\r\n  // Parameters :\r\n  //   None or optional arguments.\r\n  // Options :\r\n  //   PCLZIP_OPT_BY_INDEX :\r\n  //   PCLZIP_OPT_BY_NAME :\r\n  //   PCLZIP_OPT_BY_EREG : \r\n  //   PCLZIP_OPT_BY_PREG :\r\n  // Return Values :\r\n  //   0 on failure,\r\n  //   The list of the files which are still present in the archive.\r\n  //   (see PclZip::listContent() for list entry format)\r\n  // --------------------------------------------------------------------------------\r\n  function delete()\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Reset the error handler\r\n    $this->privErrorReset();\r\n\r\n    // ----- Check archive\r\n    if (!$this->privCheckFormat()) {\r\n      return(0);\r\n    }\r\n\r\n    // ----- Set default values\r\n    $v_options = array();\r\n\r\n    // ----- Look for variable options arguments\r\n    $v_size = func_num_args();\r\n\r\n    // ----- Look for arguments\r\n    if ($v_size > 0) {\r\n      // ----- Get the arguments\r\n      $v_arg_list = func_get_args();\r\n\r\n      // ----- Parse the options\r\n      $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,\r\n                                        array (PCLZIP_OPT_BY_NAME => 'optional',\r\n                                               PCLZIP_OPT_BY_EREG => 'optional',\r\n                                               PCLZIP_OPT_BY_PREG => 'optional',\r\n                                               PCLZIP_OPT_BY_INDEX => 'optional' ));\r\n      if ($v_result != 1) {\r\n          return 0;\r\n      }\r\n    }\r\n\r\n    // ----- Magic quotes trick\r\n    $this->privDisableMagicQuotes();\r\n\r\n    // ----- Call the delete fct\r\n    $v_list = array();\r\n    if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {\r\n      $this->privSwapBackMagicQuotes();\r\n      unset($v_list);\r\n      return(0);\r\n    }\r\n\r\n    // ----- Magic quotes trick\r\n    $this->privSwapBackMagicQuotes();\r\n\r\n    // ----- Return\r\n    return $v_list;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : deleteByIndex()\r\n  // Description :\r\n  //   ***** Deprecated *****\r\n  //   delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.\r\n  // --------------------------------------------------------------------------------\r\n  function deleteByIndex($p_index)\r\n  {\r\n    \r\n    $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);\r\n\r\n    // ----- Return\r\n    return $p_list;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : properties()\r\n  // Description :\r\n  //   This method gives the properties of the archive.\r\n  //   The properties are :\r\n  //     nb : Number of files in the archive\r\n  //     comment : Comment associated with the archive file\r\n  //     status : not_exist, ok\r\n  // Parameters :\r\n  //   None\r\n  // Return Values :\r\n  //   0 on failure,\r\n  //   An array with the archive properties.\r\n  // --------------------------------------------------------------------------------\r\n  function properties()\r\n  {\r\n\r\n    // ----- Reset the error handler\r\n    $this->privErrorReset();\r\n\r\n    // ----- Magic quotes trick\r\n    $this->privDisableMagicQuotes();\r\n\r\n    // ----- Check archive\r\n    if (!$this->privCheckFormat()) {\r\n      $this->privSwapBackMagicQuotes();\r\n      return(0);\r\n    }\r\n\r\n    // ----- Default properties\r\n    $v_prop = array();\r\n    $v_prop['comment'] = '';\r\n    $v_prop['nb'] = 0;\r\n    $v_prop['status'] = 'not_exist';\r\n\r\n    // ----- Look if file exists\r\n    if (@is_file($this->zipname))\r\n    {\r\n      // ----- Open the zip file\r\n      if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)\r\n      {\r\n        $this->privSwapBackMagicQuotes();\r\n        \r\n        // ----- Error log\r\n        PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \\''.$this->zipname.'\\' in binary read mode');\r\n\r\n        // ----- Return\r\n        return 0;\r\n      }\r\n\r\n      // ----- Read the central directory informations\r\n      $v_central_dir = array();\r\n      if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)\r\n      {\r\n        $this->privSwapBackMagicQuotes();\r\n        return 0;\r\n      }\r\n\r\n      // ----- Close the zip file\r\n      $this->privCloseFd();\r\n\r\n      // ----- Set the user attributes\r\n      $v_prop['comment'] = $v_central_dir['comment'];\r\n      $v_prop['nb'] = $v_central_dir['entries'];\r\n      $v_prop['status'] = 'ok';\r\n    }\r\n\r\n    // ----- Magic quotes trick\r\n    $this->privSwapBackMagicQuotes();\r\n\r\n    // ----- Return\r\n    return $v_prop;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : duplicate()\r\n  // Description :\r\n  //   This method creates an archive by copying the content of an other one. If\r\n  //   the archive already exist, it is replaced by the new one without any warning.\r\n  // Parameters :\r\n  //   $p_archive : The filename of a valid archive, or\r\n  //                a valid PclZip object.\r\n  // Return Values :\r\n  //   1 on success.\r\n  //   0 or a negative value on error (error code).\r\n  // --------------------------------------------------------------------------------\r\n  function duplicate($p_archive)\r\n  {\r\n    $v_result = 1;\r\n\r\n    // ----- Reset the error handler\r\n    $this->privErrorReset();\r\n\r\n    // ----- Look if the $p_archive is a PclZip object\r\n    if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))\r\n    {\r\n\r\n      // ----- Duplicate the archive\r\n      $v_result = $this->privDuplicate($p_archive->zipname);\r\n    }\r\n\r\n    // ----- Look if the $p_archive is a string (so a filename)\r\n    else if (is_string($p_archive))\r\n    {\r\n\r\n      // ----- Check that $p_archive is a valid zip file\r\n      // TBC : Should also check the archive format\r\n      if (!is_file($p_archive)) {\r\n        // ----- Error log\r\n        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, \"No file with filename '\".$p_archive.\"'\");\r\n        $v_result = PCLZIP_ERR_MISSING_FILE;\r\n      }\r\n      else {\r\n        // ----- Duplicate the archive\r\n        $v_result = $this->privDuplicate($p_archive);\r\n      }\r\n    }\r\n\r\n    // ----- Invalid variable\r\n    else\r\n    {\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Invalid variable type p_archive_to_add\");\r\n      $v_result = PCLZIP_ERR_INVALID_PARAMETER;\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : merge()\r\n  // Description :\r\n  //   This method merge the $p_archive_to_add archive at the end of the current\r\n  //   one ($this).\r\n  //   If the archive ($this) does not exist, the merge becomes a duplicate.\r\n  //   If the $p_archive_to_add archive does not exist, the merge is a success.\r\n  // Parameters :\r\n  //   $p_archive_to_add : It can be directly the filename of a valid zip archive,\r\n  //                       or a PclZip object archive.\r\n  // Return Values :\r\n  //   1 on success,\r\n  //   0 or negative values on error (see below).\r\n  // --------------------------------------------------------------------------------\r\n  function merge($p_archive_to_add)\r\n  {\r\n    $v_result = 1;\r\n\r\n    // ----- Reset the error handler\r\n    $this->privErrorReset();\r\n\r\n    // ----- Check archive\r\n    if (!$this->privCheckFormat()) {\r\n      return(0);\r\n    }\r\n\r\n    // ----- Look if the $p_archive_to_add is a PclZip object\r\n    if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))\r\n    {\r\n\r\n      // ----- Merge the archive\r\n      $v_result = $this->privMerge($p_archive_to_add);\r\n    }\r\n\r\n    // ----- Look if the $p_archive_to_add is a string (so a filename)\r\n    else if (is_string($p_archive_to_add))\r\n    {\r\n\r\n      // ----- Create a temporary archive\r\n      $v_object_archive = new PclZip($p_archive_to_add);\r\n\r\n      // ----- Merge the archive\r\n      $v_result = $this->privMerge($v_object_archive);\r\n    }\r\n\r\n    // ----- Invalid variable\r\n    else\r\n    {\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Invalid variable type p_archive_to_add\");\r\n      $v_result = PCLZIP_ERR_INVALID_PARAMETER;\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : errorCode()\r\n  // Description :\r\n  // Parameters :\r\n  // --------------------------------------------------------------------------------\r\n  function errorCode()\r\n  {\r\n    if (PCLZIP_ERROR_EXTERNAL == 1) {\r\n      return(PclErrorCode());\r\n    }\r\n    else {\r\n      return($this->error_code);\r\n    }\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : errorName()\r\n  // Description :\r\n  // Parameters :\r\n  // --------------------------------------------------------------------------------\r\n  function errorName($p_with_code=false)\r\n  {\r\n    $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',\r\n                      PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',\r\n                      PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',\r\n                      PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',\r\n                      PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',\r\n                      PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',\r\n                      PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',\r\n                      PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',\r\n                      PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',\r\n                      PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',\r\n                      PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',\r\n                      PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',\r\n                      PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',\r\n                      PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',\r\n                      PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',\r\n                      PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',\r\n                      PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',\r\n                      PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',\r\n                      PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'\r\n                      ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'\r\n                      ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'\r\n                    );\r\n\r\n    if (isset($v_name[$this->error_code])) {\r\n      $v_value = $v_name[$this->error_code];\r\n    }\r\n    else {\r\n      $v_value = 'NoName';\r\n    }\r\n\r\n    if ($p_with_code) {\r\n      return($v_value.' ('.$this->error_code.')');\r\n    }\r\n    else {\r\n      return($v_value);\r\n    }\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : errorInfo()\r\n  // Description :\r\n  // Parameters :\r\n  // --------------------------------------------------------------------------------\r\n  function errorInfo($p_full=false)\r\n  {\r\n    if (PCLZIP_ERROR_EXTERNAL == 1) {\r\n      return(PclErrorString());\r\n    }\r\n    else {\r\n      if ($p_full) {\r\n        return($this->errorName(true).\" : \".$this->error_string);\r\n      }\r\n      else {\r\n        return($this->error_string.\" [code \".$this->error_code.\"]\");\r\n      }\r\n    }\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n\r\n// --------------------------------------------------------------------------------\r\n// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****\r\n// *****                                                        *****\r\n// *****       THESES FUNCTIONS MUST NOT BE USED DIRECTLY       *****\r\n// --------------------------------------------------------------------------------\r\n\r\n\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privCheckFormat()\r\n  // Description :\r\n  //   This method check that the archive exists and is a valid zip archive.\r\n  //   Several level of check exists. (futur)\r\n  // Parameters :\r\n  //   $p_level : Level of check. Default 0.\r\n  //              0 : Check the first bytes (magic codes) (default value))\r\n  //              1 : 0 + Check the central directory (futur)\r\n  //              2 : 1 + Check each file header (futur)\r\n  // Return Values :\r\n  //   true on success,\r\n  //   false on error, the error code is set.\r\n  // --------------------------------------------------------------------------------\r\n  function privCheckFormat($p_level=0)\r\n  {\r\n    $v_result = true;\r\n\r\n\t// ----- Reset the file system cache\r\n    clearstatcache();\r\n\r\n    // ----- Reset the error handler\r\n    $this->privErrorReset();\r\n\r\n    // ----- Look if the file exits\r\n    if (!is_file($this->zipname)) {\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, \"Missing archive file '\".$this->zipname.\"'\");\r\n      return(false);\r\n    }\r\n\r\n    // ----- Check that the file is readeable\r\n    if (!is_readable($this->zipname)) {\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, \"Unable to read archive '\".$this->zipname.\"'\");\r\n      return(false);\r\n    }\r\n\r\n    // ----- Check the magic code\r\n    // TBC\r\n\r\n    // ----- Check the central header\r\n    // TBC\r\n\r\n    // ----- Check each file header\r\n    // TBC\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privParseOptions()\r\n  // Description :\r\n  //   This internal methods reads the variable list of arguments ($p_options_list,\r\n  //   $p_size) and generate an array with the options and values ($v_result_list).\r\n  //   $v_requested_options contains the options that can be present and those that\r\n  //   must be present.\r\n  //   $v_requested_options is an array, with the option value as key, and 'optional',\r\n  //   or 'mandatory' as value.\r\n  // Parameters :\r\n  //   See above.\r\n  // Return Values :\r\n  //   1 on success.\r\n  //   0 on failure.\r\n  // --------------------------------------------------------------------------------\r\n  function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)\r\n  {\r\n    $v_result=1;\r\n    \r\n    // ----- Read the options\r\n    $i=0;\r\n    while ($i<$p_size) {\r\n\r\n      // ----- Check if the option is supported\r\n      if (!isset($v_requested_options[$p_options_list[$i]])) {\r\n        // ----- Error log\r\n        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Invalid optional parameter '\".$p_options_list[$i].\"' for this method\");\r\n\r\n        // ----- Return\r\n        return PclZip::errorCode();\r\n      }\r\n\r\n      // ----- Look for next option\r\n      switch ($p_options_list[$i]) {\r\n        // ----- Look for options that request a path value\r\n        case PCLZIP_OPT_PATH :\r\n        case PCLZIP_OPT_REMOVE_PATH :\r\n        case PCLZIP_OPT_ADD_PATH :\r\n          // ----- Check the number of parameters\r\n          if (($i+1) >= $p_size) {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, \"Missing parameter value for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          // ----- Get the value\r\n          $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);\r\n          $i++;\r\n        break;\r\n\r\n        case PCLZIP_OPT_TEMP_FILE_THRESHOLD :\r\n          // ----- Check the number of parameters\r\n          if (($i+1) >= $p_size) {\r\n            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, \"Missing parameter value for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n            return PclZip::errorCode();\r\n          }\r\n          \r\n          // ----- Check for incompatible options\r\n          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Option '\".PclZipUtilOptionText($p_options_list[$i]).\"' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'\");\r\n            return PclZip::errorCode();\r\n          }\r\n          \r\n          // ----- Check the value\r\n          $v_value = $p_options_list[$i+1];\r\n          if ((!is_integer($v_value)) || ($v_value<0)) {\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, \"Integer expected for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          // ----- Get the value (and convert it in bytes)\r\n          $v_result_list[$p_options_list[$i]] = $v_value*1048576;\r\n          $i++;\r\n        break;\r\n\r\n        case PCLZIP_OPT_TEMP_FILE_ON :\r\n          // ----- Check for incompatible options\r\n          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Option '\".PclZipUtilOptionText($p_options_list[$i]).\"' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'\");\r\n            return PclZip::errorCode();\r\n          }\r\n          \r\n          $v_result_list[$p_options_list[$i]] = true;\r\n        break;\r\n\r\n        case PCLZIP_OPT_TEMP_FILE_OFF :\r\n          // ----- Check for incompatible options\r\n          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Option '\".PclZipUtilOptionText($p_options_list[$i]).\"' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'\");\r\n            return PclZip::errorCode();\r\n          }\r\n          // ----- Check for incompatible options\r\n          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Option '\".PclZipUtilOptionText($p_options_list[$i]).\"' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'\");\r\n            return PclZip::errorCode();\r\n          }\r\n          \r\n          $v_result_list[$p_options_list[$i]] = true;\r\n        break;\r\n\r\n        case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :\r\n          // ----- Check the number of parameters\r\n          if (($i+1) >= $p_size) {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, \"Missing parameter value for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          // ----- Get the value\r\n          if (   is_string($p_options_list[$i+1])\r\n              && ($p_options_list[$i+1] != '')) {\r\n            $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);\r\n            $i++;\r\n          }\r\n          else {\r\n          }\r\n        break;\r\n\r\n        // ----- Look for options that request an array of string for value\r\n        case PCLZIP_OPT_BY_NAME :\r\n          // ----- Check the number of parameters\r\n          if (($i+1) >= $p_size) {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, \"Missing parameter value for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          // ----- Get the value\r\n          if (is_string($p_options_list[$i+1])) {\r\n              $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];\r\n          }\r\n          else if (is_array($p_options_list[$i+1])) {\r\n              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];\r\n          }\r\n          else {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, \"Wrong parameter value for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n          $i++;\r\n        break;\r\n\r\n        // ----- Look for options that request an EREG or PREG expression\r\n        case PCLZIP_OPT_BY_EREG :\r\n          // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG\r\n          // to PCLZIP_OPT_BY_PREG\r\n          $p_options_list[$i] = PCLZIP_OPT_BY_PREG;\r\n        case PCLZIP_OPT_BY_PREG :\r\n        //case PCLZIP_OPT_CRYPT :\r\n          // ----- Check the number of parameters\r\n          if (($i+1) >= $p_size) {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, \"Missing parameter value for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          // ----- Get the value\r\n          if (is_string($p_options_list[$i+1])) {\r\n              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];\r\n          }\r\n          else {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, \"Wrong parameter value for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n          $i++;\r\n        break;\r\n\r\n        // ----- Look for options that takes a string\r\n        case PCLZIP_OPT_COMMENT :\r\n        case PCLZIP_OPT_ADD_COMMENT :\r\n        case PCLZIP_OPT_PREPEND_COMMENT :\r\n          // ----- Check the number of parameters\r\n          if (($i+1) >= $p_size) {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,\r\n\t\t\t                     \"Missing parameter value for option '\"\r\n\t\t\t\t\t\t\t\t .PclZipUtilOptionText($p_options_list[$i])\r\n\t\t\t\t\t\t\t\t .\"'\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          // ----- Get the value\r\n          if (is_string($p_options_list[$i+1])) {\r\n              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];\r\n          }\r\n          else {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,\r\n\t\t\t                     \"Wrong parameter value for option '\"\r\n\t\t\t\t\t\t\t\t .PclZipUtilOptionText($p_options_list[$i])\r\n\t\t\t\t\t\t\t\t .\"'\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n          $i++;\r\n        break;\r\n\r\n        // ----- Look for options that request an array of index\r\n        case PCLZIP_OPT_BY_INDEX :\r\n          // ----- Check the number of parameters\r\n          if (($i+1) >= $p_size) {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, \"Missing parameter value for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          // ----- Get the value\r\n          $v_work_list = array();\r\n          if (is_string($p_options_list[$i+1])) {\r\n\r\n              // ----- Remove spaces\r\n              $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');\r\n\r\n              // ----- Parse items\r\n              $v_work_list = explode(\",\", $p_options_list[$i+1]);\r\n          }\r\n          else if (is_integer($p_options_list[$i+1])) {\r\n              $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];\r\n          }\r\n          else if (is_array($p_options_list[$i+1])) {\r\n              $v_work_list = $p_options_list[$i+1];\r\n          }\r\n          else {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, \"Value must be integer, string or array for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n          \r\n          // ----- Reduce the index list\r\n          // each index item in the list must be a couple with a start and\r\n          // an end value : [0,3], [5-5], [8-10], ...\r\n          // ----- Check the format of each item\r\n          $v_sort_flag=false;\r\n          $v_sort_value=0;\r\n          for ($j=0; $j<sizeof($v_work_list); $j++) {\r\n              // ----- Explode the item\r\n              $v_item_list = explode(\"-\", $v_work_list[$j]);\r\n              $v_size_item_list = sizeof($v_item_list);\r\n              \r\n              // ----- TBC : Here we might check that each item is a\r\n              // real integer ...\r\n              \r\n              // ----- Look for single value\r\n              if ($v_size_item_list == 1) {\r\n                  // ----- Set the option value\r\n                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];\r\n                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];\r\n              }\r\n              elseif ($v_size_item_list == 2) {\r\n                  // ----- Set the option value\r\n                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];\r\n                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];\r\n              }\r\n              else {\r\n                  // ----- Error log\r\n                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, \"Too many values in index range for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n\r\n                  // ----- Return\r\n                  return PclZip::errorCode();\r\n              }\r\n\r\n\r\n              // ----- Look for list sort\r\n              if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {\r\n                  $v_sort_flag=true;\r\n\r\n                  // ----- TBC : An automatic sort should be writen ...\r\n                  // ----- Error log\r\n                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, \"Invalid order of index range for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n\r\n                  // ----- Return\r\n                  return PclZip::errorCode();\r\n              }\r\n              $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];\r\n          }\r\n          \r\n          // ----- Sort the items\r\n          if ($v_sort_flag) {\r\n              // TBC : To Be Completed\r\n          }\r\n\r\n          // ----- Next option\r\n          $i++;\r\n        break;\r\n\r\n        // ----- Look for options that request no value\r\n        case PCLZIP_OPT_REMOVE_ALL_PATH :\r\n        case PCLZIP_OPT_EXTRACT_AS_STRING :\r\n        case PCLZIP_OPT_NO_COMPRESSION :\r\n        case PCLZIP_OPT_EXTRACT_IN_OUTPUT :\r\n        case PCLZIP_OPT_REPLACE_NEWER :\r\n        case PCLZIP_OPT_STOP_ON_ERROR :\r\n          $v_result_list[$p_options_list[$i]] = true;\r\n        break;\r\n\r\n        // ----- Look for options that request an octal value\r\n        case PCLZIP_OPT_SET_CHMOD :\r\n          // ----- Check the number of parameters\r\n          if (($i+1) >= $p_size) {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, \"Missing parameter value for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          // ----- Get the value\r\n          $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];\r\n          $i++;\r\n        break;\r\n\r\n        // ----- Look for options that request a call-back\r\n        case PCLZIP_CB_PRE_EXTRACT :\r\n        case PCLZIP_CB_POST_EXTRACT :\r\n        case PCLZIP_CB_PRE_ADD :\r\n        case PCLZIP_CB_POST_ADD :\r\n        /* for futur use\r\n        case PCLZIP_CB_PRE_DELETE :\r\n        case PCLZIP_CB_POST_DELETE :\r\n        case PCLZIP_CB_PRE_LIST :\r\n        case PCLZIP_CB_POST_LIST :\r\n        */\r\n          // ----- Check the number of parameters\r\n          if (($i+1) >= $p_size) {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, \"Missing parameter value for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          // ----- Get the value\r\n          $v_function_name = $p_options_list[$i+1];\r\n\r\n          // ----- Check that the value is a valid existing function\r\n          if (!function_exists($v_function_name)) {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, \"Function '\".$v_function_name.\"()' is not an existing function for option '\".PclZipUtilOptionText($p_options_list[$i]).\"'\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          // ----- Set the attribute\r\n          $v_result_list[$p_options_list[$i]] = $v_function_name;\r\n          $i++;\r\n        break;\r\n\r\n        default :\r\n          // ----- Error log\r\n          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,\r\n\t\t                       \"Unknown parameter '\"\r\n\t\t\t\t\t\t\t   .$p_options_list[$i].\"'\");\r\n\r\n          // ----- Return\r\n          return PclZip::errorCode();\r\n      }\r\n\r\n      // ----- Next options\r\n      $i++;\r\n    }\r\n\r\n    // ----- Look for mandatory options\r\n    if ($v_requested_options !== false) {\r\n      for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {\r\n        // ----- Look for mandatory option\r\n        if ($v_requested_options[$key] == 'mandatory') {\r\n          // ----- Look if present\r\n          if (!isset($v_result_list[$key])) {\r\n            // ----- Error log\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Missing mandatory parameter \".PclZipUtilOptionText($key).\"(\".$key.\")\");\r\n\r\n            // ----- Return\r\n            return PclZip::errorCode();\r\n          }\r\n        }\r\n      }\r\n    }\r\n    \r\n    // ----- Look for default values\r\n    if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {\r\n      \r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privOptionDefaultThreshold()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privOptionDefaultThreshold(&$p_options)\r\n  {\r\n    $v_result=1;\r\n    \r\n    if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])\r\n        || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {\r\n      return $v_result;\r\n    }\r\n    \r\n    // ----- Get 'memory_limit' configuration value\r\n    $v_memory_limit = ini_get('memory_limit');\r\n    $v_memory_limit = trim($v_memory_limit);\r\n    $last = strtolower(substr($v_memory_limit, -1));\r\n \r\n    if($last == 'g')\r\n        //$v_memory_limit = $v_memory_limit*1024*1024*1024;\r\n        $v_memory_limit = $v_memory_limit*1073741824;\r\n    if($last == 'm')\r\n        //$v_memory_limit = $v_memory_limit*1024*1024;\r\n        $v_memory_limit = $v_memory_limit*1048576;\r\n    if($last == 'k')\r\n        $v_memory_limit = $v_memory_limit*1024;\r\n            \r\n    $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);\r\n    \r\n\r\n    // ----- Sanity check : No threshold if value lower than 1M\r\n    if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {\r\n      unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);\r\n    }\r\n          \r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privFileDescrParseAtt()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  //   1 on success.\r\n  //   0 on failure.\r\n  // --------------------------------------------------------------------------------\r\n  function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)\r\n  {\r\n    $v_result=1;\r\n    \r\n    // ----- For each file in the list check the attributes\r\n    foreach ($p_file_list as $v_key => $v_value) {\r\n    \r\n      // ----- Check if the option is supported\r\n      if (!isset($v_requested_options[$v_key])) {\r\n        // ----- Error log\r\n        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Invalid file attribute '\".$v_key.\"' for this file\");\r\n\r\n        // ----- Return\r\n        return PclZip::errorCode();\r\n      }\r\n\r\n      // ----- Look for attribute\r\n      switch ($v_key) {\r\n        case PCLZIP_ATT_FILE_NAME :\r\n          if (!is_string($v_value)) {\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, \"Invalid type \".gettype($v_value).\". String expected for attribute '\".PclZipUtilOptionText($v_key).\"'\");\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);\r\n          \r\n          if ($p_filedescr['filename'] == '') {\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, \"Invalid empty filename for attribute '\".PclZipUtilOptionText($v_key).\"'\");\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n        break;\r\n\r\n        case PCLZIP_ATT_FILE_NEW_SHORT_NAME :\r\n          if (!is_string($v_value)) {\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, \"Invalid type \".gettype($v_value).\". String expected for attribute '\".PclZipUtilOptionText($v_key).\"'\");\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);\r\n\r\n          if ($p_filedescr['new_short_name'] == '') {\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, \"Invalid empty short filename for attribute '\".PclZipUtilOptionText($v_key).\"'\");\r\n            return PclZip::errorCode();\r\n          }\r\n        break;\r\n\r\n        case PCLZIP_ATT_FILE_NEW_FULL_NAME :\r\n          if (!is_string($v_value)) {\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, \"Invalid type \".gettype($v_value).\". String expected for attribute '\".PclZipUtilOptionText($v_key).\"'\");\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);\r\n\r\n          if ($p_filedescr['new_full_name'] == '') {\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, \"Invalid empty full filename for attribute '\".PclZipUtilOptionText($v_key).\"'\");\r\n            return PclZip::errorCode();\r\n          }\r\n        break;\r\n\r\n        // ----- Look for options that takes a string\r\n        case PCLZIP_ATT_FILE_COMMENT :\r\n          if (!is_string($v_value)) {\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, \"Invalid type \".gettype($v_value).\". String expected for attribute '\".PclZipUtilOptionText($v_key).\"'\");\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          $p_filedescr['comment'] = $v_value;\r\n        break;\r\n\r\n        case PCLZIP_ATT_FILE_MTIME :\r\n          if (!is_integer($v_value)) {\r\n            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, \"Invalid type \".gettype($v_value).\". Integer expected for attribute '\".PclZipUtilOptionText($v_key).\"'\");\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n          $p_filedescr['mtime'] = $v_value;\r\n        break;\r\n\r\n        case PCLZIP_ATT_FILE_CONTENT :\r\n          $p_filedescr['content'] = $v_value;\r\n        break;\r\n\r\n        default :\r\n          // ----- Error log\r\n          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,\r\n\t\t                           \"Unknown parameter '\".$v_key.\"'\");\r\n\r\n          // ----- Return\r\n          return PclZip::errorCode();\r\n      }\r\n\r\n      // ----- Look for mandatory options\r\n      if ($v_requested_options !== false) {\r\n        for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {\r\n          // ----- Look for mandatory option\r\n          if ($v_requested_options[$key] == 'mandatory') {\r\n            // ----- Look if present\r\n            if (!isset($p_file_list[$key])) {\r\n              PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Missing mandatory parameter \".PclZipUtilOptionText($key).\"(\".$key.\")\");\r\n              return PclZip::errorCode();\r\n            }\r\n          }\r\n        }\r\n      }\r\n    \r\n    // end foreach\r\n    }\r\n    \r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privFileDescrExpand()\r\n  // Description :\r\n  //   This method look for each item of the list to see if its a file, a folder\r\n  //   or a string to be added as file. For any other type of files (link, other)\r\n  //   just ignore the item.\r\n  //   Then prepare the information that will be stored for that file.\r\n  //   When its a folder, expand the folder with all the files that are in that \r\n  //   folder (recursively).\r\n  // Parameters :\r\n  // Return Values :\r\n  //   1 on success.\r\n  //   0 on failure.\r\n  // --------------------------------------------------------------------------------\r\n  function privFileDescrExpand(&$p_filedescr_list, &$p_options)\r\n  {\r\n    $v_result=1;\r\n    \r\n    // ----- Create a result list\r\n    $v_result_list = array();\r\n    \r\n    // ----- Look each entry\r\n    for ($i=0; $i<sizeof($p_filedescr_list); $i++) {\r\n      \r\n      // ----- Get filedescr\r\n      $v_descr = $p_filedescr_list[$i];\r\n      \r\n      // ----- Reduce the filename\r\n      $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);\r\n      $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);\r\n      \r\n      // ----- Look for real file or folder\r\n      if (file_exists($v_descr['filename'])) {\r\n        if (@is_file($v_descr['filename'])) {\r\n          $v_descr['type'] = 'file';\r\n        }\r\n        else if (@is_dir($v_descr['filename'])) {\r\n          $v_descr['type'] = 'folder';\r\n        }\r\n        else if (@is_link($v_descr['filename'])) {\r\n          // skip\r\n          continue;\r\n        }\r\n        else {\r\n          // skip\r\n          continue;\r\n        }\r\n      }\r\n      \r\n      // ----- Look for string added as file\r\n      else if (isset($v_descr['content'])) {\r\n        $v_descr['type'] = 'virtual_file';\r\n      }\r\n      \r\n      // ----- Missing file\r\n      else {\r\n        // ----- Error log\r\n        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, \"File '\".$v_descr['filename'].\"' does not exist\");\r\n\r\n        // ----- Return\r\n        return PclZip::errorCode();\r\n      }\r\n      \r\n      // ----- Calculate the stored filename\r\n      $this->privCalculateStoredFilename($v_descr, $p_options);\r\n      \r\n      // ----- Add the descriptor in result list\r\n      $v_result_list[sizeof($v_result_list)] = $v_descr;\r\n      \r\n      // ----- Look for folder\r\n      if ($v_descr['type'] == 'folder') {\r\n        // ----- List of items in folder\r\n        $v_dirlist_descr = array();\r\n        $v_dirlist_nb = 0;\r\n        if ($v_folder_handler = @opendir($v_descr['filename'])) {\r\n          while (($v_item_handler = @readdir($v_folder_handler)) !== false) {\r\n\r\n            // ----- Skip '.' and '..'\r\n            if (($v_item_handler == '.') || ($v_item_handler == '..')) {\r\n                continue;\r\n            }\r\n            \r\n            // ----- Compose the full filename\r\n            $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;\r\n            \r\n            // ----- Look for different stored filename\r\n            // Because the name of the folder was changed, the name of the\r\n            // files/sub-folders also change\r\n            if (($v_descr['stored_filename'] != $v_descr['filename'])\r\n                 && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {\r\n              if ($v_descr['stored_filename'] != '') {\r\n                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;\r\n              }\r\n              else {\r\n                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;\r\n              }\r\n            }\r\n      \r\n            $v_dirlist_nb++;\r\n          }\r\n          \r\n          @closedir($v_folder_handler);\r\n        }\r\n        else {\r\n          // TBC : unable to open folder in read mode\r\n        }\r\n        \r\n        // ----- Expand each element of the list\r\n        if ($v_dirlist_nb != 0) {\r\n          // ----- Expand\r\n          if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {\r\n            return $v_result;\r\n          }\r\n          \r\n          // ----- Concat the resulting list\r\n          $v_result_list = array_merge($v_result_list, $v_dirlist_descr);\r\n        }\r\n        else {\r\n        }\r\n          \r\n        // ----- Free local array\r\n        unset($v_dirlist_descr);\r\n      }\r\n    }\r\n    \r\n    // ----- Get the result list\r\n    $p_filedescr_list = $v_result_list;\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privCreate()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privCreate($p_filedescr_list, &$p_result_list, &$p_options)\r\n  {\r\n    $v_result=1;\r\n    $v_list_detail = array();\r\n    \r\n    // ----- Magic quotes trick\r\n    $this->privDisableMagicQuotes();\r\n\r\n    // ----- Open the file in write mode\r\n    if (($v_result = $this->privOpenFd('wb')) != 1)\r\n    {\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Add the list of files\r\n    $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);\r\n\r\n    // ----- Close\r\n    $this->privCloseFd();\r\n\r\n    // ----- Magic quotes trick\r\n    $this->privSwapBackMagicQuotes();\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privAdd()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privAdd($p_filedescr_list, &$p_result_list, &$p_options)\r\n  {\r\n    $v_result=1;\r\n    $v_list_detail = array();\r\n\r\n    // ----- Look if the archive exists or is empty\r\n    if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))\r\n    {\r\n\r\n      // ----- Do a create\r\n      $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);\r\n\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n    // ----- Magic quotes trick\r\n    $this->privDisableMagicQuotes();\r\n\r\n    // ----- Open the zip file\r\n    if (($v_result=$this->privOpenFd('rb')) != 1)\r\n    {\r\n      // ----- Magic quotes trick\r\n      $this->privSwapBackMagicQuotes();\r\n\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Read the central directory informations\r\n    $v_central_dir = array();\r\n    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)\r\n    {\r\n      $this->privCloseFd();\r\n      $this->privSwapBackMagicQuotes();\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Go to beginning of File\r\n    @rewind($this->zip_fd);\r\n\r\n    // ----- Creates a temporay file\r\n    $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';\r\n\r\n    // ----- Open the temporary file in write mode\r\n    if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)\r\n    {\r\n      $this->privCloseFd();\r\n      $this->privSwapBackMagicQuotes();\r\n\r\n      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \\''.$v_zip_temp_name.'\\' in binary write mode');\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Copy the files from the archive to the temporary file\r\n    // TBC : Here I should better append the file and go back to erase the central dir\r\n    $v_size = $v_central_dir['offset'];\r\n    while ($v_size != 0)\r\n    {\r\n      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);\r\n      $v_buffer = fread($this->zip_fd, $v_read_size);\r\n      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);\r\n      $v_size -= $v_read_size;\r\n    }\r\n\r\n    // ----- Swap the file descriptor\r\n    // Here is a trick : I swap the temporary fd with the zip fd, in order to use\r\n    // the following methods on the temporary fil and not the real archive\r\n    $v_swap = $this->zip_fd;\r\n    $this->zip_fd = $v_zip_temp_fd;\r\n    $v_zip_temp_fd = $v_swap;\r\n\r\n    // ----- Add the files\r\n    $v_header_list = array();\r\n    if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)\r\n    {\r\n      fclose($v_zip_temp_fd);\r\n      $this->privCloseFd();\r\n      @unlink($v_zip_temp_name);\r\n      $this->privSwapBackMagicQuotes();\r\n\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Store the offset of the central dir\r\n    $v_offset = @ftell($this->zip_fd);\r\n\r\n    // ----- Copy the block of file headers from the old archive\r\n    $v_size = $v_central_dir['size'];\r\n    while ($v_size != 0)\r\n    {\r\n      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);\r\n      $v_buffer = @fread($v_zip_temp_fd, $v_read_size);\r\n      @fwrite($this->zip_fd, $v_buffer, $v_read_size);\r\n      $v_size -= $v_read_size;\r\n    }\r\n\r\n    // ----- Create the Central Dir files header\r\n    for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)\r\n    {\r\n      // ----- Create the file header\r\n      if ($v_header_list[$i]['status'] == 'ok') {\r\n        if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {\r\n          fclose($v_zip_temp_fd);\r\n          $this->privCloseFd();\r\n          @unlink($v_zip_temp_name);\r\n          $this->privSwapBackMagicQuotes();\r\n\r\n          // ----- Return\r\n          return $v_result;\r\n        }\r\n        $v_count++;\r\n      }\r\n\r\n      // ----- Transform the header to a 'usable' info\r\n      $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);\r\n    }\r\n\r\n    // ----- Zip file comment\r\n    $v_comment = $v_central_dir['comment'];\r\n    if (isset($p_options[PCLZIP_OPT_COMMENT])) {\r\n      $v_comment = $p_options[PCLZIP_OPT_COMMENT];\r\n    }\r\n    if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {\r\n      $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];\r\n    }\r\n    if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {\r\n      $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;\r\n    }\r\n\r\n    // ----- Calculate the size of the central header\r\n    $v_size = @ftell($this->zip_fd)-$v_offset;\r\n\r\n    // ----- Create the central dir footer\r\n    if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)\r\n    {\r\n      // ----- Reset the file list\r\n      unset($v_header_list);\r\n      $this->privSwapBackMagicQuotes();\r\n\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Swap back the file descriptor\r\n    $v_swap = $this->zip_fd;\r\n    $this->zip_fd = $v_zip_temp_fd;\r\n    $v_zip_temp_fd = $v_swap;\r\n\r\n    // ----- Close\r\n    $this->privCloseFd();\r\n\r\n    // ----- Close the temporary file\r\n    @fclose($v_zip_temp_fd);\r\n\r\n    // ----- Magic quotes trick\r\n    $this->privSwapBackMagicQuotes();\r\n\r\n    // ----- Delete the zip file\r\n    // TBC : I should test the result ...\r\n    @unlink($this->zipname);\r\n\r\n    // ----- Rename the temporary file\r\n    // TBC : I should test the result ...\r\n    //@rename($v_zip_temp_name, $this->zipname);\r\n    PclZipUtilRename($v_zip_temp_name, $this->zipname);\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privOpenFd()\r\n  // Description :\r\n  // Parameters :\r\n  // --------------------------------------------------------------------------------\r\n  function privOpenFd($p_mode)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Look if already open\r\n    if ($this->zip_fd != 0)\r\n    {\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \\''.$this->zipname.'\\' already open');\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Open the zip file\r\n    if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)\r\n    {\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \\''.$this->zipname.'\\' in '.$p_mode.' mode');\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privCloseFd()\r\n  // Description :\r\n  // Parameters :\r\n  // --------------------------------------------------------------------------------\r\n  function privCloseFd()\r\n  {\r\n    $v_result=1;\r\n\r\n    if ($this->zip_fd != 0)\r\n      @fclose($this->zip_fd);\r\n    $this->zip_fd = 0;\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privAddList()\r\n  // Description :\r\n  //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is\r\n  //   different from the real path of the file. This is usefull if you want to have PclTar\r\n  //   running in any directory, and memorize relative path from an other directory.\r\n  // Parameters :\r\n  //   $p_list : An array containing the file or directory names to add in the tar\r\n  //   $p_result_list : list of added files with their properties (specially the status field)\r\n  //   $p_add_dir : Path to add in the filename path archived\r\n  //   $p_remove_dir : Path to remove in the filename path archived\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n//  function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)\r\n  function privAddList($p_filedescr_list, &$p_result_list, &$p_options)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Add the files\r\n    $v_header_list = array();\r\n    if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)\r\n    {\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Store the offset of the central dir\r\n    $v_offset = @ftell($this->zip_fd);\r\n\r\n    // ----- Create the Central Dir files header\r\n    for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)\r\n    {\r\n      // ----- Create the file header\r\n      if ($v_header_list[$i]['status'] == 'ok') {\r\n        if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {\r\n          // ----- Return\r\n          return $v_result;\r\n        }\r\n        $v_count++;\r\n      }\r\n\r\n      // ----- Transform the header to a 'usable' info\r\n      $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);\r\n    }\r\n\r\n    // ----- Zip file comment\r\n    $v_comment = '';\r\n    if (isset($p_options[PCLZIP_OPT_COMMENT])) {\r\n      $v_comment = $p_options[PCLZIP_OPT_COMMENT];\r\n    }\r\n\r\n    // ----- Calculate the size of the central header\r\n    $v_size = @ftell($this->zip_fd)-$v_offset;\r\n\r\n    // ----- Create the central dir footer\r\n    if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)\r\n    {\r\n      // ----- Reset the file list\r\n      unset($v_header_list);\r\n\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privAddFileList()\r\n  // Description :\r\n  // Parameters :\r\n  //   $p_filedescr_list : An array containing the file description \r\n  //                      or directory names to add in the zip\r\n  //   $p_result_list : list of added files with their properties (specially the status field)\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)\r\n  {\r\n    $v_result=1;\r\n    $v_header = array();\r\n\r\n    // ----- Recuperate the current number of elt in list\r\n    $v_nb = sizeof($p_result_list);\r\n\r\n    // ----- Loop on the files\r\n    for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {\r\n      // ----- Format the filename\r\n      $p_filedescr_list[$j]['filename']\r\n      = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);\r\n      \r\n\r\n      // ----- Skip empty file names\r\n      // TBC : Can this be possible ? not checked in DescrParseAtt ?\r\n      if ($p_filedescr_list[$j]['filename'] == \"\") {\r\n        continue;\r\n      }\r\n\r\n      // ----- Check the filename\r\n      if (   ($p_filedescr_list[$j]['type'] != 'virtual_file')\r\n          && (!file_exists($p_filedescr_list[$j]['filename']))) {\r\n        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, \"File '\".$p_filedescr_list[$j]['filename'].\"' does not exist\");\r\n        return PclZip::errorCode();\r\n      }\r\n\r\n      // ----- Look if it is a file or a dir with no all path remove option\r\n      // or a dir with all its path removed\r\n//      if (   (is_file($p_filedescr_list[$j]['filename']))\r\n//          || (   is_dir($p_filedescr_list[$j]['filename'])\r\n      if (   ($p_filedescr_list[$j]['type'] == 'file')\r\n          || ($p_filedescr_list[$j]['type'] == 'virtual_file')\r\n          || (   ($p_filedescr_list[$j]['type'] == 'folder')\r\n              && (   !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])\r\n                  || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))\r\n          ) {\r\n\r\n        // ----- Add the file\r\n        $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,\r\n                                       $p_options);\r\n        if ($v_result != 1) {\r\n          return $v_result;\r\n        }\r\n\r\n        // ----- Store the file infos\r\n        $p_result_list[$v_nb++] = $v_header;\r\n      }\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privAddFile()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privAddFile($p_filedescr, &$p_header, &$p_options)\r\n  {\r\n    $v_result=1;\r\n    \r\n    // ----- Working variable\r\n    $p_filename = $p_filedescr['filename'];\r\n\r\n    // TBC : Already done in the fileAtt check ... ?\r\n    if ($p_filename == \"\") {\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, \"Invalid file list parameter (invalid or empty list)\");\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n  \r\n    // ----- Look for a stored different filename \r\n    /* TBC : Removed\r\n    if (isset($p_filedescr['stored_filename'])) {\r\n      $v_stored_filename = $p_filedescr['stored_filename'];\r\n    }\r\n    else {\r\n      $v_stored_filename = $p_filedescr['stored_filename'];\r\n    }\r\n    */\r\n\r\n    // ----- Set the file properties\r\n    clearstatcache();\r\n    $p_header['version'] = 20;\r\n    $p_header['version_extracted'] = 10;\r\n    $p_header['flag'] = 0;\r\n    $p_header['compression'] = 0;\r\n    $p_header['crc'] = 0;\r\n    $p_header['compressed_size'] = 0;\r\n    $p_header['filename_len'] = strlen($p_filename);\r\n    $p_header['extra_len'] = 0;\r\n    $p_header['disk'] = 0;\r\n    $p_header['internal'] = 0;\r\n    $p_header['offset'] = 0;\r\n    $p_header['filename'] = $p_filename;\r\n// TBC : Removed    $p_header['stored_filename'] = $v_stored_filename;\r\n    $p_header['stored_filename'] = $p_filedescr['stored_filename'];\r\n    $p_header['extra'] = '';\r\n    $p_header['status'] = 'ok';\r\n    $p_header['index'] = -1;\r\n\r\n    // ----- Look for regular file\r\n    if ($p_filedescr['type']=='file') {\r\n      $p_header['external'] = 0x00000000;\r\n      $p_header['size'] = filesize($p_filename);\r\n    }\r\n    \r\n    // ----- Look for regular folder\r\n    else if ($p_filedescr['type']=='folder') {\r\n      $p_header['external'] = 0x00000010;\r\n      $p_header['mtime'] = filemtime($p_filename);\r\n      $p_header['size'] = filesize($p_filename);\r\n    }\r\n    \r\n    // ----- Look for virtual file\r\n    else if ($p_filedescr['type'] == 'virtual_file') {\r\n      $p_header['external'] = 0x00000000;\r\n      $p_header['size'] = strlen($p_filedescr['content']);\r\n    }\r\n    \r\n\r\n    // ----- Look for filetime\r\n    if (isset($p_filedescr['mtime'])) {\r\n      $p_header['mtime'] = $p_filedescr['mtime'];\r\n    }\r\n    else if ($p_filedescr['type'] == 'virtual_file') {\r\n      $p_header['mtime'] = time();\r\n    }\r\n    else {\r\n      $p_header['mtime'] = filemtime($p_filename);\r\n    }\r\n\r\n    // ------ Look for file comment\r\n    if (isset($p_filedescr['comment'])) {\r\n      $p_header['comment_len'] = strlen($p_filedescr['comment']);\r\n      $p_header['comment'] = $p_filedescr['comment'];\r\n    }\r\n    else {\r\n      $p_header['comment_len'] = 0;\r\n      $p_header['comment'] = '';\r\n    }\r\n\r\n    // ----- Look for pre-add callback\r\n    if (isset($p_options[PCLZIP_CB_PRE_ADD])) {\r\n\r\n      // ----- Generate a local information\r\n      $v_local_header = array();\r\n      $this->privConvertHeader2FileInfo($p_header, $v_local_header);\r\n\r\n      // ----- Call the callback\r\n      // Here I do not use call_user_func() because I need to send a reference to the\r\n      // header.\r\n//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');\r\n      $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);\r\n      if ($v_result == 0) {\r\n        // ----- Change the file status\r\n        $p_header['status'] = \"skipped\";\r\n        $v_result = 1;\r\n      }\r\n\r\n      // ----- Update the informations\r\n      // Only some fields can be modified\r\n      if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {\r\n        $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);\r\n      }\r\n    }\r\n\r\n    // ----- Look for empty stored filename\r\n    if ($p_header['stored_filename'] == \"\") {\r\n      $p_header['status'] = \"filtered\";\r\n    }\r\n    \r\n    // ----- Check the path length\r\n    if (strlen($p_header['stored_filename']) > 0xFF) {\r\n      $p_header['status'] = 'filename_too_long';\r\n    }\r\n\r\n    // ----- Look if no error, or file not skipped\r\n    if ($p_header['status'] == 'ok') {\r\n\r\n      // ----- Look for a file\r\n      if ($p_filedescr['type'] == 'file') {\r\n        // ----- Look for using temporary file to zip\r\n        if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) \r\n            && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])\r\n                || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])\r\n                    && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {\r\n          $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);\r\n          if ($v_result < PCLZIP_ERR_NO_ERROR) {\r\n            return $v_result;\r\n          }\r\n        }\r\n        \r\n        // ----- Use \"in memory\" zip algo\r\n        else {\r\n\r\n        // ----- Open the source file\r\n        if (($v_file = @fopen($p_filename, \"rb\")) == 0) {\r\n          PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, \"Unable to open file '$p_filename' in binary read mode\");\r\n          return PclZip::errorCode();\r\n        }\r\n\r\n        // ----- Read the file content\r\n        $v_content = @fread($v_file, $p_header['size']);\r\n\r\n        // ----- Close the file\r\n        @fclose($v_file);\r\n\r\n        // ----- Calculate the CRC\r\n        $p_header['crc'] = @crc32($v_content);\r\n        \r\n        // ----- Look for no compression\r\n        if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {\r\n          // ----- Set header parameters\r\n          $p_header['compressed_size'] = $p_header['size'];\r\n          $p_header['compression'] = 0;\r\n        }\r\n        \r\n        // ----- Look for normal compression\r\n        else {\r\n          // ----- Compress the content\r\n          $v_content = @gzdeflate($v_content);\r\n\r\n          // ----- Set header parameters\r\n          $p_header['compressed_size'] = strlen($v_content);\r\n          $p_header['compression'] = 8;\r\n        }\r\n        \r\n        // ----- Call the header generation\r\n        if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {\r\n          @fclose($v_file);\r\n          return $v_result;\r\n        }\r\n\r\n        // ----- Write the compressed (or not) content\r\n        @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);\r\n\r\n        }\r\n\r\n      }\r\n\r\n      // ----- Look for a virtual file (a file from string)\r\n      else if ($p_filedescr['type'] == 'virtual_file') {\r\n          \r\n        $v_content = $p_filedescr['content'];\r\n\r\n        // ----- Calculate the CRC\r\n        $p_header['crc'] = @crc32($v_content);\r\n        \r\n        // ----- Look for no compression\r\n        if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {\r\n          // ----- Set header parameters\r\n          $p_header['compressed_size'] = $p_header['size'];\r\n          $p_header['compression'] = 0;\r\n        }\r\n        \r\n        // ----- Look for normal compression\r\n        else {\r\n          // ----- Compress the content\r\n          $v_content = @gzdeflate($v_content);\r\n\r\n          // ----- Set header parameters\r\n          $p_header['compressed_size'] = strlen($v_content);\r\n          $p_header['compression'] = 8;\r\n        }\r\n        \r\n        // ----- Call the header generation\r\n        if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {\r\n          @fclose($v_file);\r\n          return $v_result;\r\n        }\r\n\r\n        // ----- Write the compressed (or not) content\r\n        @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);\r\n      }\r\n\r\n      // ----- Look for a directory\r\n      else if ($p_filedescr['type'] == 'folder') {\r\n        // ----- Look for directory last '/'\r\n        if (@substr($p_header['stored_filename'], -1) != '/') {\r\n          $p_header['stored_filename'] .= '/';\r\n        }\r\n\r\n        // ----- Set the file properties\r\n        $p_header['size'] = 0;\r\n        //$p_header['external'] = 0x41FF0010;   // Value for a folder : to be checked\r\n        $p_header['external'] = 0x00000010;   // Value for a folder : to be checked\r\n\r\n        // ----- Call the header generation\r\n        if (($v_result = $this->privWriteFileHeader($p_header)) != 1)\r\n        {\r\n          return $v_result;\r\n        }\r\n      }\r\n    }\r\n\r\n    // ----- Look for post-add callback\r\n    if (isset($p_options[PCLZIP_CB_POST_ADD])) {\r\n\r\n      // ----- Generate a local information\r\n      $v_local_header = array();\r\n      $this->privConvertHeader2FileInfo($p_header, $v_local_header);\r\n\r\n      // ----- Call the callback\r\n      // Here I do not use call_user_func() because I need to send a reference to the\r\n      // header.\r\n//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');\r\n      $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);\r\n      if ($v_result == 0) {\r\n        // ----- Ignored\r\n        $v_result = 1;\r\n      }\r\n\r\n      // ----- Update the informations\r\n      // Nothing can be modified\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privAddFileUsingTempFile()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)\r\n  {\r\n    $v_result=PCLZIP_ERR_NO_ERROR;\r\n    \r\n    // ----- Working variable\r\n    $p_filename = $p_filedescr['filename'];\r\n\r\n\r\n    // ----- Open the source file\r\n    if (($v_file = @fopen($p_filename, \"rb\")) == 0) {\r\n      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, \"Unable to open file '$p_filename' in binary read mode\");\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Creates a compressed temporary file\r\n    $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';\r\n    if (($v_file_compressed = @gzopen($v_gzip_temp_name, \"wb\")) == 0) {\r\n      fclose($v_file);\r\n      PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \\''.$v_gzip_temp_name.'\\' in binary write mode');\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks\r\n    $v_size = filesize($p_filename);\r\n    while ($v_size != 0) {\r\n      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);\r\n      $v_buffer = @fread($v_file, $v_read_size);\r\n      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);\r\n      @gzputs($v_file_compressed, $v_buffer, $v_read_size);\r\n      $v_size -= $v_read_size;\r\n    }\r\n\r\n    // ----- Close the file\r\n    @fclose($v_file);\r\n    @gzclose($v_file_compressed);\r\n\r\n    // ----- Check the minimum file size\r\n    if (filesize($v_gzip_temp_name) < 18) {\r\n      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \\''.$v_gzip_temp_name.'\\' has invalid filesize - should be minimum 18 bytes');\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Extract the compressed attributes\r\n    if (($v_file_compressed = @fopen($v_gzip_temp_name, \"rb\")) == 0) {\r\n      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \\''.$v_gzip_temp_name.'\\' in binary read mode');\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Read the gzip file header\r\n    $v_binary_data = @fread($v_file_compressed, 10);\r\n    $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);\r\n\r\n    // ----- Check some parameters\r\n    $v_data_header['os'] = bin2hex($v_data_header['os']);\r\n\r\n    // ----- Read the gzip file footer\r\n    @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);\r\n    $v_binary_data = @fread($v_file_compressed, 8);\r\n    $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);\r\n\r\n    // ----- Set the attributes\r\n    $p_header['compression'] = ord($v_data_header['cm']);\r\n    //$p_header['mtime'] = $v_data_header['mtime'];\r\n    $p_header['crc'] = $v_data_footer['crc'];\r\n    $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;\r\n\r\n    // ----- Close the file\r\n    @fclose($v_file_compressed);\r\n\r\n    // ----- Call the header generation\r\n    if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Add the compressed data\r\n    if (($v_file_compressed = @fopen($v_gzip_temp_name, \"rb\")) == 0)\r\n    {\r\n      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \\''.$v_gzip_temp_name.'\\' in binary read mode');\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks\r\n    fseek($v_file_compressed, 10);\r\n    $v_size = $p_header['compressed_size'];\r\n    while ($v_size != 0)\r\n    {\r\n      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);\r\n      $v_buffer = @fread($v_file_compressed, $v_read_size);\r\n      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);\r\n      @fwrite($this->zip_fd, $v_buffer, $v_read_size);\r\n      $v_size -= $v_read_size;\r\n    }\r\n\r\n    // ----- Close the file\r\n    @fclose($v_file_compressed);\r\n\r\n    // ----- Unlink the temporary file\r\n    @unlink($v_gzip_temp_name);\r\n    \r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privCalculateStoredFilename()\r\n  // Description :\r\n  //   Based on file descriptor properties and global options, this method\r\n  //   calculate the filename that will be stored in the archive.\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privCalculateStoredFilename(&$p_filedescr, &$p_options)\r\n  {\r\n    $v_result=1;\r\n    \r\n    // ----- Working variables\r\n    $p_filename = $p_filedescr['filename'];\r\n    if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {\r\n      $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];\r\n    }\r\n    else {\r\n      $p_add_dir = '';\r\n    }\r\n    if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {\r\n      $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];\r\n    }\r\n    else {\r\n      $p_remove_dir = '';\r\n    }\r\n    if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {\r\n      $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];\r\n    }\r\n    else {\r\n      $p_remove_all_dir = 0;\r\n    }\r\n\r\n\r\n    // ----- Look for full name change\r\n    if (isset($p_filedescr['new_full_name'])) {\r\n      // ----- Remove drive letter if any\r\n      $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);\r\n    }\r\n    \r\n    // ----- Look for path and/or short name change\r\n    else {\r\n\r\n      // ----- Look for short name change\r\n      // Its when we cahnge just the filename but not the path\r\n      if (isset($p_filedescr['new_short_name'])) {\r\n        $v_path_info = pathinfo($p_filename);\r\n        $v_dir = '';\r\n        if ($v_path_info['dirname'] != '') {\r\n          $v_dir = $v_path_info['dirname'].'/';\r\n        }\r\n        $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];\r\n      }\r\n      else {\r\n        // ----- Calculate the stored filename\r\n        $v_stored_filename = $p_filename;\r\n      }\r\n\r\n      // ----- Look for all path to remove\r\n      if ($p_remove_all_dir) {\r\n        $v_stored_filename = basename($p_filename);\r\n      }\r\n      // ----- Look for partial path remove\r\n      else if ($p_remove_dir != \"\") {\r\n        if (substr($p_remove_dir, -1) != '/')\r\n          $p_remove_dir .= \"/\";\r\n\r\n        if (   (substr($p_filename, 0, 2) == \"./\")\r\n            || (substr($p_remove_dir, 0, 2) == \"./\")) {\r\n            \r\n          if (   (substr($p_filename, 0, 2) == \"./\")\r\n              && (substr($p_remove_dir, 0, 2) != \"./\")) {\r\n            $p_remove_dir = \"./\".$p_remove_dir;\r\n          }\r\n          if (   (substr($p_filename, 0, 2) != \"./\")\r\n              && (substr($p_remove_dir, 0, 2) == \"./\")) {\r\n            $p_remove_dir = substr($p_remove_dir, 2);\r\n          }\r\n        }\r\n\r\n        $v_compare = PclZipUtilPathInclusion($p_remove_dir,\r\n                                             $v_stored_filename);\r\n        if ($v_compare > 0) {\r\n          if ($v_compare == 2) {\r\n            $v_stored_filename = \"\";\r\n          }\r\n          else {\r\n            $v_stored_filename = substr($v_stored_filename,\r\n                                        strlen($p_remove_dir));\r\n          }\r\n        }\r\n      }\r\n      \r\n      // ----- Remove drive letter if any\r\n      $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);\r\n      \r\n      // ----- Look for path to add\r\n      if ($p_add_dir != \"\") {\r\n        if (substr($p_add_dir, -1) == \"/\")\r\n          $v_stored_filename = $p_add_dir.$v_stored_filename;\r\n        else\r\n          $v_stored_filename = $p_add_dir.\"/\".$v_stored_filename;\r\n      }\r\n    }\r\n\r\n    // ----- Filename (reduce the path of stored name)\r\n    $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);\r\n    $p_filedescr['stored_filename'] = $v_stored_filename;\r\n    \r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privWriteFileHeader()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privWriteFileHeader(&$p_header)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Store the offset position of the file\r\n    $p_header['offset'] = ftell($this->zip_fd);\r\n\r\n    // ----- Transform UNIX mtime to DOS format mdate/mtime\r\n    $v_date = getdate($p_header['mtime']);\r\n    $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;\r\n    $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];\r\n\r\n    // ----- Packed data\r\n    $v_binary_data = pack(\"VvvvvvVVVvv\", 0x04034b50,\r\n\t                      $p_header['version_extracted'], $p_header['flag'],\r\n                          $p_header['compression'], $v_mtime, $v_mdate,\r\n                          $p_header['crc'], $p_header['compressed_size'],\r\n\t\t\t\t\t\t  $p_header['size'],\r\n                          strlen($p_header['stored_filename']),\r\n\t\t\t\t\t\t  $p_header['extra_len']);\r\n\r\n    // ----- Write the first 148 bytes of the header in the archive\r\n    fputs($this->zip_fd, $v_binary_data, 30);\r\n\r\n    // ----- Write the variable fields\r\n    if (strlen($p_header['stored_filename']) != 0)\r\n    {\r\n      fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));\r\n    }\r\n    if ($p_header['extra_len'] != 0)\r\n    {\r\n      fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privWriteCentralFileHeader()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privWriteCentralFileHeader(&$p_header)\r\n  {\r\n    $v_result=1;\r\n\r\n    // TBC\r\n    //for(reset($p_header); $key = key($p_header); next($p_header)) {\r\n    //}\r\n\r\n    // ----- Transform UNIX mtime to DOS format mdate/mtime\r\n    $v_date = getdate($p_header['mtime']);\r\n    $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;\r\n    $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];\r\n\r\n\r\n    // ----- Packed data\r\n    $v_binary_data = pack(\"VvvvvvvVVVvvvvvVV\", 0x02014b50,\r\n\t                      $p_header['version'], $p_header['version_extracted'],\r\n                          $p_header['flag'], $p_header['compression'],\r\n\t\t\t\t\t\t  $v_mtime, $v_mdate, $p_header['crc'],\r\n                          $p_header['compressed_size'], $p_header['size'],\r\n                          strlen($p_header['stored_filename']),\r\n\t\t\t\t\t\t  $p_header['extra_len'], $p_header['comment_len'],\r\n                          $p_header['disk'], $p_header['internal'],\r\n\t\t\t\t\t\t  $p_header['external'], $p_header['offset']);\r\n\r\n    // ----- Write the 42 bytes of the header in the zip file\r\n    fputs($this->zip_fd, $v_binary_data, 46);\r\n\r\n    // ----- Write the variable fields\r\n    if (strlen($p_header['stored_filename']) != 0)\r\n    {\r\n      fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));\r\n    }\r\n    if ($p_header['extra_len'] != 0)\r\n    {\r\n      fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);\r\n    }\r\n    if ($p_header['comment_len'] != 0)\r\n    {\r\n      fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privWriteCentralHeader()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Packed data\r\n    $v_binary_data = pack(\"VvvvvVVv\", 0x06054b50, 0, 0, $p_nb_entries,\r\n\t                      $p_nb_entries, $p_size,\r\n\t\t\t\t\t\t  $p_offset, strlen($p_comment));\r\n\r\n    // ----- Write the 22 bytes of the header in the zip file\r\n    fputs($this->zip_fd, $v_binary_data, 22);\r\n\r\n    // ----- Write the variable fields\r\n    if (strlen($p_comment) != 0)\r\n    {\r\n      fputs($this->zip_fd, $p_comment, strlen($p_comment));\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privList()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privList(&$p_list)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Magic quotes trick\r\n    $this->privDisableMagicQuotes();\r\n\r\n    // ----- Open the zip file\r\n    if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)\r\n    {\r\n      // ----- Magic quotes trick\r\n      $this->privSwapBackMagicQuotes();\r\n      \r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \\''.$this->zipname.'\\' in binary read mode');\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Read the central directory informations\r\n    $v_central_dir = array();\r\n    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)\r\n    {\r\n      $this->privSwapBackMagicQuotes();\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Go to beginning of Central Dir\r\n    @rewind($this->zip_fd);\r\n    if (@fseek($this->zip_fd, $v_central_dir['offset']))\r\n    {\r\n      $this->privSwapBackMagicQuotes();\r\n\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Read each entry\r\n    for ($i=0; $i<$v_central_dir['entries']; $i++)\r\n    {\r\n      // ----- Read the file header\r\n      if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)\r\n      {\r\n        $this->privSwapBackMagicQuotes();\r\n        return $v_result;\r\n      }\r\n      $v_header['index'] = $i;\r\n\r\n      // ----- Get the only interesting attributes\r\n      $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);\r\n      unset($v_header);\r\n    }\r\n\r\n    // ----- Close the zip file\r\n    $this->privCloseFd();\r\n\r\n    // ----- Magic quotes trick\r\n    $this->privSwapBackMagicQuotes();\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privConvertHeader2FileInfo()\r\n  // Description :\r\n  //   This function takes the file informations from the central directory\r\n  //   entries and extract the interesting parameters that will be given back.\r\n  //   The resulting file infos are set in the array $p_info\r\n  //     $p_info['filename'] : Filename with full path. Given by user (add),\r\n  //                           extracted in the filesystem (extract).\r\n  //     $p_info['stored_filename'] : Stored filename in the archive.\r\n  //     $p_info['size'] = Size of the file.\r\n  //     $p_info['compressed_size'] = Compressed size of the file.\r\n  //     $p_info['mtime'] = Last modification date of the file.\r\n  //     $p_info['comment'] = Comment associated with the file.\r\n  //     $p_info['folder'] = true/false : indicates if the entry is a folder or not.\r\n  //     $p_info['status'] = status of the action on the file.\r\n  //     $p_info['crc'] = CRC of the file content.\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privConvertHeader2FileInfo($p_header, &$p_info)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Get the interesting attributes\r\n    $v_temp_path = PclZipUtilPathReduction($p_header['filename']);\r\n    $p_info['filename'] = $v_temp_path;\r\n    $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);\r\n    $p_info['stored_filename'] = $v_temp_path;\r\n    $p_info['size'] = $p_header['size'];\r\n    $p_info['compressed_size'] = $p_header['compressed_size'];\r\n    $p_info['mtime'] = $p_header['mtime'];\r\n    $p_info['comment'] = $p_header['comment'];\r\n    $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);\r\n    $p_info['index'] = $p_header['index'];\r\n    $p_info['status'] = $p_header['status'];\r\n    $p_info['crc'] = $p_header['crc'];\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privExtractByRule()\r\n  // Description :\r\n  //   Extract a file or directory depending of rules (by index, by name, ...)\r\n  // Parameters :\r\n  //   $p_file_list : An array where will be placed the properties of each\r\n  //                  extracted file\r\n  //   $p_path : Path to add while writing the extracted files\r\n  //   $p_remove_path : Path to remove (from the file memorized path) while writing the\r\n  //                    extracted files. If the path does not match the file path,\r\n  //                    the file is extracted with its memorized path.\r\n  //                    $p_remove_path does not apply to 'list' mode.\r\n  //                    $p_path and $p_remove_path are commulative.\r\n  // Return Values :\r\n  //   1 on success,0 or less on error (see error code list)\r\n  // --------------------------------------------------------------------------------\r\n  function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Magic quotes trick\r\n    $this->privDisableMagicQuotes();\r\n\r\n    // ----- Check the path\r\n    if (   ($p_path == \"\")\r\n\t    || (   (substr($p_path, 0, 1) != \"/\")\r\n\t\t    && (substr($p_path, 0, 3) != \"../\")\r\n\t\t\t&& (substr($p_path,1,2)!=\":/\")))\r\n      $p_path = \"./\".$p_path;\r\n\r\n    // ----- Reduce the path last (and duplicated) '/'\r\n    if (($p_path != \"./\") && ($p_path != \"/\"))\r\n    {\r\n      // ----- Look for the path end '/'\r\n      while (substr($p_path, -1) == \"/\")\r\n      {\r\n        $p_path = substr($p_path, 0, strlen($p_path)-1);\r\n      }\r\n    }\r\n\r\n    // ----- Look for path to remove format (should end by /)\r\n    if (($p_remove_path != \"\") && (substr($p_remove_path, -1) != '/'))\r\n    {\r\n      $p_remove_path .= '/';\r\n    }\r\n    $p_remove_path_size = strlen($p_remove_path);\r\n\r\n    // ----- Open the zip file\r\n    if (($v_result = $this->privOpenFd('rb')) != 1)\r\n    {\r\n      $this->privSwapBackMagicQuotes();\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Read the central directory informations\r\n    $v_central_dir = array();\r\n    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)\r\n    {\r\n      // ----- Close the zip file\r\n      $this->privCloseFd();\r\n      $this->privSwapBackMagicQuotes();\r\n\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Start at beginning of Central Dir\r\n    $v_pos_entry = $v_central_dir['offset'];\r\n\r\n    // ----- Read each entry\r\n    $j_start = 0;\r\n    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)\r\n    {\r\n\r\n      // ----- Read next Central dir entry\r\n      @rewind($this->zip_fd);\r\n      if (@fseek($this->zip_fd, $v_pos_entry))\r\n      {\r\n        // ----- Close the zip file\r\n        $this->privCloseFd();\r\n        $this->privSwapBackMagicQuotes();\r\n\r\n        // ----- Error log\r\n        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');\r\n\r\n        // ----- Return\r\n        return PclZip::errorCode();\r\n      }\r\n\r\n      // ----- Read the file header\r\n      $v_header = array();\r\n      if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)\r\n      {\r\n        // ----- Close the zip file\r\n        $this->privCloseFd();\r\n        $this->privSwapBackMagicQuotes();\r\n\r\n        return $v_result;\r\n      }\r\n\r\n      // ----- Store the index\r\n      $v_header['index'] = $i;\r\n\r\n      // ----- Store the file position\r\n      $v_pos_entry = ftell($this->zip_fd);\r\n\r\n      // ----- Look for the specific extract rules\r\n      $v_extract = false;\r\n\r\n      // ----- Look for extract by name rule\r\n      if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))\r\n          && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {\r\n\r\n          // ----- Look if the filename is in the list\r\n          for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {\r\n\r\n              // ----- Look for a directory\r\n              if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == \"/\") {\r\n\r\n                  // ----- Look if the directory is in the filename path\r\n                  if (   (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))\r\n                      && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {\r\n                      $v_extract = true;\r\n                  }\r\n              }\r\n              // ----- Look for a filename\r\n              elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {\r\n                  $v_extract = true;\r\n              }\r\n          }\r\n      }\r\n\r\n      // ----- Look for extract by ereg rule\r\n      // ereg() is deprecated with PHP 5.3\r\n      /* \r\n      else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))\r\n               && ($p_options[PCLZIP_OPT_BY_EREG] != \"\")) {\r\n\r\n          if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {\r\n              $v_extract = true;\r\n          }\r\n      }\r\n      */\r\n\r\n      // ----- Look for extract by preg rule\r\n      else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))\r\n               && ($p_options[PCLZIP_OPT_BY_PREG] != \"\")) {\r\n\r\n          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {\r\n              $v_extract = true;\r\n          }\r\n      }\r\n\r\n      // ----- Look for extract by index rule\r\n      else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))\r\n               && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {\r\n          \r\n          // ----- Look if the index is in the list\r\n          for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {\r\n\r\n              if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {\r\n                  $v_extract = true;\r\n              }\r\n              if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {\r\n                  $j_start = $j+1;\r\n              }\r\n\r\n              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {\r\n                  break;\r\n              }\r\n          }\r\n      }\r\n\r\n      // ----- Look for no rule, which means extract all the archive\r\n      else {\r\n          $v_extract = true;\r\n      }\r\n\r\n\t  // ----- Check compression method\r\n\t  if (   ($v_extract)\r\n\t      && (   ($v_header['compression'] != 8)\r\n\t\t      && ($v_header['compression'] != 0))) {\r\n          $v_header['status'] = 'unsupported_compression';\r\n\r\n          // ----- Look for PCLZIP_OPT_STOP_ON_ERROR\r\n          if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))\r\n\t\t      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {\r\n\r\n              $this->privSwapBackMagicQuotes();\r\n              \r\n              PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,\r\n\t\t\t                       \"Filename '\".$v_header['stored_filename'].\"' is \"\r\n\t\t\t\t  \t    \t  \t   .\"compressed by an unsupported compression \"\r\n\t\t\t\t  \t    \t  \t   .\"method (\".$v_header['compression'].\") \");\r\n\r\n              return PclZip::errorCode();\r\n\t\t  }\r\n\t  }\r\n\t  \r\n\t  // ----- Check encrypted files\r\n\t  if (($v_extract) && (($v_header['flag'] & 1) == 1)) {\r\n          $v_header['status'] = 'unsupported_encryption';\r\n\r\n          // ----- Look for PCLZIP_OPT_STOP_ON_ERROR\r\n          if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))\r\n\t\t      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {\r\n\r\n              $this->privSwapBackMagicQuotes();\r\n\r\n              PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,\r\n\t\t\t                       \"Unsupported encryption for \"\r\n\t\t\t\t  \t    \t  \t   .\" filename '\".$v_header['stored_filename']\r\n\t\t\t\t\t\t\t\t   .\"'\");\r\n\r\n              return PclZip::errorCode();\r\n\t\t  }\r\n    }\r\n\r\n      // ----- Look for real extraction\r\n      if (($v_extract) && ($v_header['status'] != 'ok')) {\r\n          $v_result = $this->privConvertHeader2FileInfo($v_header,\r\n\t\t                                        $p_file_list[$v_nb_extracted++]);\r\n          if ($v_result != 1) {\r\n              $this->privCloseFd();\r\n              $this->privSwapBackMagicQuotes();\r\n              return $v_result;\r\n          }\r\n\r\n          $v_extract = false;\r\n      }\r\n      \r\n      // ----- Look for real extraction\r\n      if ($v_extract)\r\n      {\r\n\r\n        // ----- Go to the file position\r\n        @rewind($this->zip_fd);\r\n        if (@fseek($this->zip_fd, $v_header['offset']))\r\n        {\r\n          // ----- Close the zip file\r\n          $this->privCloseFd();\r\n\r\n          $this->privSwapBackMagicQuotes();\r\n\r\n          // ----- Error log\r\n          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');\r\n\r\n          // ----- Return\r\n          return PclZip::errorCode();\r\n        }\r\n\r\n        // ----- Look for extraction as string\r\n        if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {\r\n\r\n          $v_string = '';\r\n\r\n          // ----- Extracting the file\r\n          $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);\r\n          if ($v_result1 < 1) {\r\n            $this->privCloseFd();\r\n            $this->privSwapBackMagicQuotes();\r\n            return $v_result1;\r\n          }\r\n\r\n          // ----- Get the only interesting attributes\r\n          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)\r\n          {\r\n            // ----- Close the zip file\r\n            $this->privCloseFd();\r\n            $this->privSwapBackMagicQuotes();\r\n\r\n            return $v_result;\r\n          }\r\n\r\n          // ----- Set the file content\r\n          $p_file_list[$v_nb_extracted]['content'] = $v_string;\r\n\r\n          // ----- Next extracted file\r\n          $v_nb_extracted++;\r\n          \r\n          // ----- Look for user callback abort\r\n          if ($v_result1 == 2) {\r\n          \tbreak;\r\n          }\r\n        }\r\n        // ----- Look for extraction in standard output\r\n        elseif (   (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))\r\n\t\t        && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {\r\n          // ----- Extracting the file in standard output\r\n          $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);\r\n          if ($v_result1 < 1) {\r\n            $this->privCloseFd();\r\n            $this->privSwapBackMagicQuotes();\r\n            return $v_result1;\r\n          }\r\n\r\n          // ----- Get the only interesting attributes\r\n          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {\r\n            $this->privCloseFd();\r\n            $this->privSwapBackMagicQuotes();\r\n            return $v_result;\r\n          }\r\n\r\n          // ----- Look for user callback abort\r\n          if ($v_result1 == 2) {\r\n          \tbreak;\r\n          }\r\n        }\r\n        // ----- Look for normal extraction\r\n        else {\r\n          // ----- Extracting the file\r\n          $v_result1 = $this->privExtractFile($v_header,\r\n\t\t                                      $p_path, $p_remove_path,\r\n\t\t\t\t\t\t\t\t\t\t\t  $p_remove_all_path,\r\n\t\t\t\t\t\t\t\t\t\t\t  $p_options);\r\n          if ($v_result1 < 1) {\r\n            $this->privCloseFd();\r\n            $this->privSwapBackMagicQuotes();\r\n            return $v_result1;\r\n          }\r\n\r\n          // ----- Get the only interesting attributes\r\n          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)\r\n          {\r\n            // ----- Close the zip file\r\n            $this->privCloseFd();\r\n            $this->privSwapBackMagicQuotes();\r\n\r\n            return $v_result;\r\n          }\r\n\r\n          // ----- Look for user callback abort\r\n          if ($v_result1 == 2) {\r\n          \tbreak;\r\n          }\r\n        }\r\n      }\r\n    }\r\n\r\n    // ----- Close the zip file\r\n    $this->privCloseFd();\r\n    $this->privSwapBackMagicQuotes();\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privExtractFile()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  //\r\n  // 1 : ... ?\r\n  // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback\r\n  // --------------------------------------------------------------------------------\r\n  function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Read the file header\r\n    if (($v_result = $this->privReadFileHeader($v_header)) != 1)\r\n    {\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n\r\n    // ----- Check that the file header is coherent with $p_entry info\r\n    if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {\r\n        // TBC\r\n    }\r\n\r\n    // ----- Look for all path to remove\r\n    if ($p_remove_all_path == true) {\r\n        // ----- Look for folder entry that not need to be extracted\r\n        if (($p_entry['external']&0x00000010)==0x00000010) {\r\n\r\n            $p_entry['status'] = \"filtered\";\r\n\r\n            return $v_result;\r\n        }\r\n\r\n        // ----- Get the basename of the path\r\n        $p_entry['filename'] = basename($p_entry['filename']);\r\n    }\r\n\r\n    // ----- Look for path to remove\r\n    else if ($p_remove_path != \"\")\r\n    {\r\n      if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)\r\n      {\r\n\r\n        // ----- Change the file status\r\n        $p_entry['status'] = \"filtered\";\r\n\r\n        // ----- Return\r\n        return $v_result;\r\n      }\r\n\r\n      $p_remove_path_size = strlen($p_remove_path);\r\n      if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)\r\n      {\r\n\r\n        // ----- Remove the path\r\n        $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);\r\n\r\n      }\r\n    }\r\n\r\n    // ----- Add the path\r\n    if ($p_path != '') {\r\n      $p_entry['filename'] = $p_path.\"/\".$p_entry['filename'];\r\n    }\r\n    \r\n    // ----- Check a base_dir_restriction\r\n    if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {\r\n      $v_inclusion\r\n      = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],\r\n                                $p_entry['filename']); \r\n      if ($v_inclusion == 0) {\r\n\r\n        PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,\r\n\t\t\t                     \"Filename '\".$p_entry['filename'].\"' is \"\r\n\t\t\t\t\t\t\t\t .\"outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION\");\r\n\r\n        return PclZip::errorCode();\r\n      }\r\n    }\r\n\r\n    // ----- Look for pre-extract callback\r\n    if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {\r\n\r\n      // ----- Generate a local information\r\n      $v_local_header = array();\r\n      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);\r\n\r\n      // ----- Call the callback\r\n      // Here I do not use call_user_func() because I need to send a reference to the\r\n      // header.\r\n//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');\r\n      $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);\r\n      if ($v_result == 0) {\r\n        // ----- Change the file status\r\n        $p_entry['status'] = \"skipped\";\r\n        $v_result = 1;\r\n      }\r\n      \r\n      // ----- Look for abort result\r\n      if ($v_result == 2) {\r\n        // ----- This status is internal and will be changed in 'skipped'\r\n        $p_entry['status'] = \"aborted\";\r\n      \t$v_result = PCLZIP_ERR_USER_ABORTED;\r\n      }\r\n\r\n      // ----- Update the informations\r\n      // Only some fields can be modified\r\n      $p_entry['filename'] = $v_local_header['filename'];\r\n    }\r\n\r\n\r\n    // ----- Look if extraction should be done\r\n    if ($p_entry['status'] == 'ok') {\r\n\r\n    // ----- Look for specific actions while the file exist\r\n    if (file_exists($p_entry['filename']))\r\n    {\r\n\r\n      // ----- Look if file is a directory\r\n      if (is_dir($p_entry['filename']))\r\n      {\r\n\r\n        // ----- Change the file status\r\n        $p_entry['status'] = \"already_a_directory\";\r\n        \r\n        // ----- Look for PCLZIP_OPT_STOP_ON_ERROR\r\n        // For historical reason first PclZip implementation does not stop\r\n        // when this kind of error occurs.\r\n        if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))\r\n\t\t    && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {\r\n\r\n            PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,\r\n\t\t\t                     \"Filename '\".$p_entry['filename'].\"' is \"\r\n\t\t\t\t\t\t\t\t .\"already used by an existing directory\");\r\n\r\n            return PclZip::errorCode();\r\n\t\t    }\r\n      }\r\n      // ----- Look if file is write protected\r\n      else if (!is_writeable($p_entry['filename']))\r\n      {\r\n\r\n        // ----- Change the file status\r\n        $p_entry['status'] = \"write_protected\";\r\n\r\n        // ----- Look for PCLZIP_OPT_STOP_ON_ERROR\r\n        // For historical reason first PclZip implementation does not stop\r\n        // when this kind of error occurs.\r\n        if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))\r\n\t\t    && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {\r\n\r\n            PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,\r\n\t\t\t                     \"Filename '\".$p_entry['filename'].\"' exists \"\r\n\t\t\t\t\t\t\t\t .\"and is write protected\");\r\n\r\n            return PclZip::errorCode();\r\n\t\t    }\r\n      }\r\n\r\n      // ----- Look if the extracted file is older\r\n      else if (filemtime($p_entry['filename']) > $p_entry['mtime'])\r\n      {\r\n        // ----- Change the file status\r\n        if (   (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))\r\n\t\t    && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {\r\n\t  \t  }\r\n\t\t    else {\r\n            $p_entry['status'] = \"newer_exist\";\r\n\r\n            // ----- Look for PCLZIP_OPT_STOP_ON_ERROR\r\n            // For historical reason first PclZip implementation does not stop\r\n            // when this kind of error occurs.\r\n            if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))\r\n\t\t        && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {\r\n\r\n                PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,\r\n\t\t\t             \"Newer version of '\".$p_entry['filename'].\"' exists \"\r\n\t\t\t\t\t    .\"and option PCLZIP_OPT_REPLACE_NEWER is not selected\");\r\n\r\n                return PclZip::errorCode();\r\n\t\t      }\r\n\t\t    }\r\n      }\r\n      else {\r\n      }\r\n    }\r\n\r\n    // ----- Check the directory availability and create it if necessary\r\n    else {\r\n      if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))\r\n        $v_dir_to_check = $p_entry['filename'];\r\n      else if (!strstr($p_entry['filename'], \"/\"))\r\n        $v_dir_to_check = \"\";\r\n      else\r\n        $v_dir_to_check = dirname($p_entry['filename']);\r\n\r\n        if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {\r\n  \r\n          // ----- Change the file status\r\n          $p_entry['status'] = \"path_creation_fail\";\r\n  \r\n          // ----- Return\r\n          //return $v_result;\r\n          $v_result = 1;\r\n        }\r\n      }\r\n    }\r\n\r\n    // ----- Look if extraction should be done\r\n    if ($p_entry['status'] == 'ok') {\r\n\r\n      // ----- Do the extraction (if not a folder)\r\n      if (!(($p_entry['external']&0x00000010)==0x00000010))\r\n      {\r\n        // ----- Look for not compressed file\r\n        if ($p_entry['compression'] == 0) {\r\n\r\n    \t\t  // ----- Opening destination file\r\n          if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)\r\n          {\r\n\r\n            // ----- Change the file status\r\n            $p_entry['status'] = \"write_error\";\r\n\r\n            // ----- Return\r\n            return $v_result;\r\n          }\r\n\r\n\r\n          // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks\r\n          $v_size = $p_entry['compressed_size'];\r\n          while ($v_size != 0)\r\n          {\r\n            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);\r\n            $v_buffer = @fread($this->zip_fd, $v_read_size);\r\n            /* Try to speed up the code\r\n            $v_binary_data = pack('a'.$v_read_size, $v_buffer);\r\n            @fwrite($v_dest_file, $v_binary_data, $v_read_size);\r\n            */\r\n            @fwrite($v_dest_file, $v_buffer, $v_read_size);            \r\n            $v_size -= $v_read_size;\r\n          }\r\n\r\n          // ----- Closing the destination file\r\n          fclose($v_dest_file);\r\n\r\n          // ----- Change the file mtime\r\n          touch($p_entry['filename'], $p_entry['mtime']);\r\n          \r\n\r\n        }\r\n        else {\r\n          // ----- TBC\r\n          // Need to be finished\r\n          if (($p_entry['flag'] & 1) == 1) {\r\n            PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \\''.$p_entry['filename'].'\\' is encrypted. Encrypted files are not supported.');\r\n            return PclZip::errorCode();\r\n          }\r\n\r\n\r\n          // ----- Look for using temporary file to unzip\r\n          if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) \r\n              && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])\r\n                  || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])\r\n                      && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {\r\n            $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);\r\n            if ($v_result < PCLZIP_ERR_NO_ERROR) {\r\n              return $v_result;\r\n            }\r\n          }\r\n          \r\n          // ----- Look for extract in memory\r\n          else {\r\n\r\n          \r\n            // ----- Read the compressed file in a buffer (one shot)\r\n            $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);\r\n            \r\n            // ----- Decompress the file\r\n            $v_file_content = @gzinflate($v_buffer);\r\n            unset($v_buffer);\r\n            if ($v_file_content === FALSE) {\r\n  \r\n              // ----- Change the file status\r\n              // TBC\r\n              $p_entry['status'] = \"error\";\r\n              \r\n              return $v_result;\r\n            }\r\n            \r\n            // ----- Opening destination file\r\n            if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {\r\n  \r\n              // ----- Change the file status\r\n              $p_entry['status'] = \"write_error\";\r\n  \r\n              return $v_result;\r\n            }\r\n  \r\n            // ----- Write the uncompressed data\r\n            @fwrite($v_dest_file, $v_file_content, $p_entry['size']);\r\n            unset($v_file_content);\r\n  \r\n            // ----- Closing the destination file\r\n            @fclose($v_dest_file);\r\n            \r\n          }\r\n\r\n          // ----- Change the file mtime\r\n          @touch($p_entry['filename'], $p_entry['mtime']);\r\n        }\r\n\r\n        // ----- Look for chmod option\r\n        if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {\r\n\r\n          // ----- Change the mode of the file\r\n          @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);\r\n        }\r\n\r\n      }\r\n    }\r\n\r\n  \t// ----- Change abort status\r\n  \tif ($p_entry['status'] == \"aborted\") {\r\n        $p_entry['status'] = \"skipped\";\r\n  \t}\r\n\t\r\n    // ----- Look for post-extract callback\r\n    elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {\r\n\r\n      // ----- Generate a local information\r\n      $v_local_header = array();\r\n      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);\r\n\r\n      // ----- Call the callback\r\n      // Here I do not use call_user_func() because I need to send a reference to the\r\n      // header.\r\n//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');\r\n      $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);\r\n\r\n      // ----- Look for abort result\r\n      if ($v_result == 2) {\r\n      \t$v_result = PCLZIP_ERR_USER_ABORTED;\r\n      }\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privExtractFileUsingTempFile()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privExtractFileUsingTempFile(&$p_entry, &$p_options)\r\n  {\r\n    $v_result=1;\r\n        \r\n    // ----- Creates a temporary file\r\n    $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';\r\n    if (($v_dest_file = @fopen($v_gzip_temp_name, \"wb\")) == 0) {\r\n      fclose($v_file);\r\n      PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \\''.$v_gzip_temp_name.'\\' in binary write mode');\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n\r\n    // ----- Write gz file format header\r\n    $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));\r\n    @fwrite($v_dest_file, $v_binary_data, 10);\r\n\r\n    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks\r\n    $v_size = $p_entry['compressed_size'];\r\n    while ($v_size != 0)\r\n    {\r\n      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);\r\n      $v_buffer = @fread($this->zip_fd, $v_read_size);\r\n      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);\r\n      @fwrite($v_dest_file, $v_buffer, $v_read_size);\r\n      $v_size -= $v_read_size;\r\n    }\r\n\r\n    // ----- Write gz file format footer\r\n    $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);\r\n    @fwrite($v_dest_file, $v_binary_data, 8);\r\n\r\n    // ----- Close the temporary file\r\n    @fclose($v_dest_file);\r\n\r\n    // ----- Opening destination file\r\n    if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {\r\n      $p_entry['status'] = \"write_error\";\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Open the temporary gz file\r\n    if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {\r\n      @fclose($v_dest_file);\r\n      $p_entry['status'] = \"read_error\";\r\n      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \\''.$v_gzip_temp_name.'\\' in binary read mode');\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n\r\n    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks\r\n    $v_size = $p_entry['size'];\r\n    while ($v_size != 0) {\r\n      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);\r\n      $v_buffer = @gzread($v_src_file, $v_read_size);\r\n      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);\r\n      @fwrite($v_dest_file, $v_buffer, $v_read_size);\r\n      $v_size -= $v_read_size;\r\n    }\r\n    @fclose($v_dest_file);\r\n    @gzclose($v_src_file);\r\n\r\n    // ----- Delete the temporary file\r\n    @unlink($v_gzip_temp_name);\r\n    \r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privExtractFileInOutput()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privExtractFileInOutput(&$p_entry, &$p_options)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Read the file header\r\n    if (($v_result = $this->privReadFileHeader($v_header)) != 1) {\r\n      return $v_result;\r\n    }\r\n\r\n\r\n    // ----- Check that the file header is coherent with $p_entry info\r\n    if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {\r\n        // TBC\r\n    }\r\n\r\n    // ----- Look for pre-extract callback\r\n    if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {\r\n\r\n      // ----- Generate a local information\r\n      $v_local_header = array();\r\n      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);\r\n\r\n      // ----- Call the callback\r\n      // Here I do not use call_user_func() because I need to send a reference to the\r\n      // header.\r\n//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');\r\n      $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);\r\n      if ($v_result == 0) {\r\n        // ----- Change the file status\r\n        $p_entry['status'] = \"skipped\";\r\n        $v_result = 1;\r\n      }\r\n\r\n      // ----- Look for abort result\r\n      if ($v_result == 2) {\r\n        // ----- This status is internal and will be changed in 'skipped'\r\n        $p_entry['status'] = \"aborted\";\r\n      \t$v_result = PCLZIP_ERR_USER_ABORTED;\r\n      }\r\n\r\n      // ----- Update the informations\r\n      // Only some fields can be modified\r\n      $p_entry['filename'] = $v_local_header['filename'];\r\n    }\r\n\r\n    // ----- Trace\r\n\r\n    // ----- Look if extraction should be done\r\n    if ($p_entry['status'] == 'ok') {\r\n\r\n      // ----- Do the extraction (if not a folder)\r\n      if (!(($p_entry['external']&0x00000010)==0x00000010)) {\r\n        // ----- Look for not compressed file\r\n        if ($p_entry['compressed_size'] == $p_entry['size']) {\r\n\r\n          // ----- Read the file in a buffer (one shot)\r\n          $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);\r\n\r\n          // ----- Send the file to the output\r\n          echo $v_buffer;\r\n          unset($v_buffer);\r\n        }\r\n        else {\r\n\r\n          // ----- Read the compressed file in a buffer (one shot)\r\n          $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);\r\n          \r\n          // ----- Decompress the file\r\n          $v_file_content = gzinflate($v_buffer);\r\n          unset($v_buffer);\r\n\r\n          // ----- Send the file to the output\r\n          echo $v_file_content;\r\n          unset($v_file_content);\r\n        }\r\n      }\r\n    }\r\n\r\n\t// ----- Change abort status\r\n\tif ($p_entry['status'] == \"aborted\") {\r\n      $p_entry['status'] = \"skipped\";\r\n\t}\r\n\r\n    // ----- Look for post-extract callback\r\n    elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {\r\n\r\n      // ----- Generate a local information\r\n      $v_local_header = array();\r\n      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);\r\n\r\n      // ----- Call the callback\r\n      // Here I do not use call_user_func() because I need to send a reference to the\r\n      // header.\r\n//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');\r\n      $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);\r\n\r\n      // ----- Look for abort result\r\n      if ($v_result == 2) {\r\n      \t$v_result = PCLZIP_ERR_USER_ABORTED;\r\n      }\r\n    }\r\n\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privExtractFileAsString()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Read the file header\r\n    $v_header = array();\r\n    if (($v_result = $this->privReadFileHeader($v_header)) != 1)\r\n    {\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n\r\n    // ----- Check that the file header is coherent with $p_entry info\r\n    if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {\r\n        // TBC\r\n    }\r\n\r\n    // ----- Look for pre-extract callback\r\n    if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {\r\n\r\n      // ----- Generate a local information\r\n      $v_local_header = array();\r\n      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);\r\n\r\n      // ----- Call the callback\r\n      // Here I do not use call_user_func() because I need to send a reference to the\r\n      // header.\r\n//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');\r\n      $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);\r\n      if ($v_result == 0) {\r\n        // ----- Change the file status\r\n        $p_entry['status'] = \"skipped\";\r\n        $v_result = 1;\r\n      }\r\n      \r\n      // ----- Look for abort result\r\n      if ($v_result == 2) {\r\n        // ----- This status is internal and will be changed in 'skipped'\r\n        $p_entry['status'] = \"aborted\";\r\n      \t$v_result = PCLZIP_ERR_USER_ABORTED;\r\n      }\r\n\r\n      // ----- Update the informations\r\n      // Only some fields can be modified\r\n      $p_entry['filename'] = $v_local_header['filename'];\r\n    }\r\n\r\n\r\n    // ----- Look if extraction should be done\r\n    if ($p_entry['status'] == 'ok') {\r\n\r\n      // ----- Do the extraction (if not a folder)\r\n      if (!(($p_entry['external']&0x00000010)==0x00000010)) {\r\n        // ----- Look for not compressed file\r\n  //      if ($p_entry['compressed_size'] == $p_entry['size'])\r\n        if ($p_entry['compression'] == 0) {\r\n  \r\n          // ----- Reading the file\r\n          $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);\r\n        }\r\n        else {\r\n  \r\n          // ----- Reading the file\r\n          $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);\r\n          \r\n          // ----- Decompress the file\r\n          if (($p_string = @gzinflate($v_data)) === FALSE) {\r\n              // TBC\r\n          }\r\n        }\r\n  \r\n        // ----- Trace\r\n      }\r\n      else {\r\n          // TBC : error : can not extract a folder in a string\r\n      }\r\n      \r\n    }\r\n\r\n  \t// ----- Change abort status\r\n  \tif ($p_entry['status'] == \"aborted\") {\r\n        $p_entry['status'] = \"skipped\";\r\n  \t}\r\n\t\r\n    // ----- Look for post-extract callback\r\n    elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {\r\n\r\n      // ----- Generate a local information\r\n      $v_local_header = array();\r\n      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);\r\n      \r\n      // ----- Swap the content to header\r\n      $v_local_header['content'] = $p_string;\r\n      $p_string = '';\r\n\r\n      // ----- Call the callback\r\n      // Here I do not use call_user_func() because I need to send a reference to the\r\n      // header.\r\n//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');\r\n      $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);\r\n\r\n      // ----- Swap back the content to header\r\n      $p_string = $v_local_header['content'];\r\n      unset($v_local_header['content']);\r\n\r\n      // ----- Look for abort result\r\n      if ($v_result == 2) {\r\n      \t$v_result = PCLZIP_ERR_USER_ABORTED;\r\n      }\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privReadFileHeader()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privReadFileHeader(&$p_header)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Read the 4 bytes signature\r\n    $v_binary_data = @fread($this->zip_fd, 4);\r\n    $v_data = unpack('Vid', $v_binary_data);\r\n\r\n    // ----- Check signature\r\n    if ($v_data['id'] != 0x04034b50)\r\n    {\r\n\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Read the first 42 bytes of the header\r\n    $v_binary_data = fread($this->zip_fd, 26);\r\n\r\n    // ----- Look for invalid block size\r\n    if (strlen($v_binary_data) != 26)\r\n    {\r\n      $p_header['filename'] = \"\";\r\n      $p_header['status'] = \"invalid_header\";\r\n\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, \"Invalid block size : \".strlen($v_binary_data));\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Extract the values\r\n    $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);\r\n\r\n    // ----- Get filename\r\n    $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);\r\n\r\n    // ----- Get extra_fields\r\n    if ($v_data['extra_len'] != 0) {\r\n      $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);\r\n    }\r\n    else {\r\n      $p_header['extra'] = '';\r\n    }\r\n\r\n    // ----- Extract properties\r\n    $p_header['version_extracted'] = $v_data['version'];\r\n    $p_header['compression'] = $v_data['compression'];\r\n    $p_header['size'] = $v_data['size'];\r\n    $p_header['compressed_size'] = $v_data['compressed_size'];\r\n    $p_header['crc'] = $v_data['crc'];\r\n    $p_header['flag'] = $v_data['flag'];\r\n    $p_header['filename_len'] = $v_data['filename_len'];\r\n\r\n    // ----- Recuperate date in UNIX format\r\n    $p_header['mdate'] = $v_data['mdate'];\r\n    $p_header['mtime'] = $v_data['mtime'];\r\n    if ($p_header['mdate'] && $p_header['mtime'])\r\n    {\r\n      // ----- Extract time\r\n      $v_hour = ($p_header['mtime'] & 0xF800) >> 11;\r\n      $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;\r\n      $v_seconde = ($p_header['mtime'] & 0x001F)*2;\r\n\r\n      // ----- Extract date\r\n      $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;\r\n      $v_month = ($p_header['mdate'] & 0x01E0) >> 5;\r\n      $v_day = $p_header['mdate'] & 0x001F;\r\n\r\n      // ----- Get UNIX date format\r\n      $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);\r\n\r\n    }\r\n    else\r\n    {\r\n      $p_header['mtime'] = time();\r\n    }\r\n\r\n    // TBC\r\n    //for(reset($v_data); $key = key($v_data); next($v_data)) {\r\n    //}\r\n\r\n    // ----- Set the stored filename\r\n    $p_header['stored_filename'] = $p_header['filename'];\r\n\r\n    // ----- Set the status field\r\n    $p_header['status'] = \"ok\";\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privReadCentralFileHeader()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privReadCentralFileHeader(&$p_header)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Read the 4 bytes signature\r\n    $v_binary_data = @fread($this->zip_fd, 4);\r\n    $v_data = unpack('Vid', $v_binary_data);\r\n\r\n    // ----- Check signature\r\n    if ($v_data['id'] != 0x02014b50)\r\n    {\r\n\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Read the first 42 bytes of the header\r\n    $v_binary_data = fread($this->zip_fd, 42);\r\n\r\n    // ----- Look for invalid block size\r\n    if (strlen($v_binary_data) != 42)\r\n    {\r\n      $p_header['filename'] = \"\";\r\n      $p_header['status'] = \"invalid_header\";\r\n\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, \"Invalid block size : \".strlen($v_binary_data));\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Extract the values\r\n    $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);\r\n\r\n    // ----- Get filename\r\n    if ($p_header['filename_len'] != 0)\r\n      $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);\r\n    else\r\n      $p_header['filename'] = '';\r\n\r\n    // ----- Get extra\r\n    if ($p_header['extra_len'] != 0)\r\n      $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);\r\n    else\r\n      $p_header['extra'] = '';\r\n\r\n    // ----- Get comment\r\n    if ($p_header['comment_len'] != 0)\r\n      $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);\r\n    else\r\n      $p_header['comment'] = '';\r\n\r\n    // ----- Extract properties\r\n\r\n    // ----- Recuperate date in UNIX format\r\n    //if ($p_header['mdate'] && $p_header['mtime'])\r\n    // TBC : bug : this was ignoring time with 0/0/0\r\n    if (1)\r\n    {\r\n      // ----- Extract time\r\n      $v_hour = ($p_header['mtime'] & 0xF800) >> 11;\r\n      $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;\r\n      $v_seconde = ($p_header['mtime'] & 0x001F)*2;\r\n\r\n      // ----- Extract date\r\n      $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;\r\n      $v_month = ($p_header['mdate'] & 0x01E0) >> 5;\r\n      $v_day = $p_header['mdate'] & 0x001F;\r\n\r\n      // ----- Get UNIX date format\r\n      $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);\r\n\r\n    }\r\n    else\r\n    {\r\n      $p_header['mtime'] = time();\r\n    }\r\n\r\n    // ----- Set the stored filename\r\n    $p_header['stored_filename'] = $p_header['filename'];\r\n\r\n    // ----- Set default status to ok\r\n    $p_header['status'] = 'ok';\r\n\r\n    // ----- Look if it is a directory\r\n    if (substr($p_header['filename'], -1) == '/') {\r\n      //$p_header['external'] = 0x41FF0010;\r\n      $p_header['external'] = 0x00000010;\r\n    }\r\n\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privCheckFileHeaders()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  //   1 on success,\r\n  //   0 on error;\r\n  // --------------------------------------------------------------------------------\r\n  function privCheckFileHeaders(&$p_local_header, &$p_central_header)\r\n  {\r\n    $v_result=1;\r\n\r\n  \t// ----- Check the static values\r\n  \t// TBC\r\n  \tif ($p_local_header['filename'] != $p_central_header['filename']) {\r\n  \t}\r\n  \tif ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {\r\n  \t}\r\n  \tif ($p_local_header['flag'] != $p_central_header['flag']) {\r\n  \t}\r\n  \tif ($p_local_header['compression'] != $p_central_header['compression']) {\r\n  \t}\r\n  \tif ($p_local_header['mtime'] != $p_central_header['mtime']) {\r\n  \t}\r\n  \tif ($p_local_header['filename_len'] != $p_central_header['filename_len']) {\r\n  \t}\r\n  \r\n  \t// ----- Look for flag bit 3\r\n  \tif (($p_local_header['flag'] & 8) == 8) {\r\n          $p_local_header['size'] = $p_central_header['size'];\r\n          $p_local_header['compressed_size'] = $p_central_header['compressed_size'];\r\n          $p_local_header['crc'] = $p_central_header['crc'];\r\n  \t}\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privReadEndCentralDir()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privReadEndCentralDir(&$p_central_dir)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Go to the end of the zip file\r\n    $v_size = filesize($this->zipname);\r\n    @fseek($this->zip_fd, $v_size);\r\n    if (@ftell($this->zip_fd) != $v_size)\r\n    {\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \\''.$this->zipname.'\\'');\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- First try : look if this is an archive with no commentaries (most of the time)\r\n    // in this case the end of central dir is at 22 bytes of the file end\r\n    $v_found = 0;\r\n    if ($v_size > 26) {\r\n      @fseek($this->zip_fd, $v_size-22);\r\n      if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))\r\n      {\r\n        // ----- Error log\r\n        PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \\''.$this->zipname.'\\'');\r\n\r\n        // ----- Return\r\n        return PclZip::errorCode();\r\n      }\r\n\r\n      // ----- Read for bytes\r\n      $v_binary_data = @fread($this->zip_fd, 4);\r\n      $v_data = @unpack('Vid', $v_binary_data);\r\n\r\n      // ----- Check signature\r\n      if ($v_data['id'] == 0x06054b50) {\r\n        $v_found = 1;\r\n      }\r\n\r\n      $v_pos = ftell($this->zip_fd);\r\n    }\r\n\r\n    // ----- Go back to the maximum possible size of the Central Dir End Record\r\n    if (!$v_found) {\r\n      $v_maximum_size = 65557; // 0xFFFF + 22;\r\n      if ($v_maximum_size > $v_size)\r\n        $v_maximum_size = $v_size;\r\n      @fseek($this->zip_fd, $v_size-$v_maximum_size);\r\n      if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))\r\n      {\r\n        // ----- Error log\r\n        PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \\''.$this->zipname.'\\'');\r\n\r\n        // ----- Return\r\n        return PclZip::errorCode();\r\n      }\r\n\r\n      // ----- Read byte per byte in order to find the signature\r\n      $v_pos = ftell($this->zip_fd);\r\n      $v_bytes = 0x00000000;\r\n      while ($v_pos < $v_size)\r\n      {\r\n        // ----- Read a byte\r\n        $v_byte = @fread($this->zip_fd, 1);\r\n\r\n        // -----  Add the byte\r\n        //$v_bytes = ($v_bytes << 8) | Ord($v_byte);\r\n        // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number \r\n        // Otherwise on systems where we have 64bit integers the check below for the magic number will fail. \r\n        $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte); \r\n\r\n        // ----- Compare the bytes\r\n        if ($v_bytes == 0x504b0506)\r\n        {\r\n          $v_pos++;\r\n          break;\r\n        }\r\n\r\n        $v_pos++;\r\n      }\r\n\r\n      // ----- Look if not found end of central dir\r\n      if ($v_pos == $v_size)\r\n      {\r\n\r\n        // ----- Error log\r\n        PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, \"Unable to find End of Central Dir Record signature\");\r\n\r\n        // ----- Return\r\n        return PclZip::errorCode();\r\n      }\r\n    }\r\n\r\n    // ----- Read the first 18 bytes of the header\r\n    $v_binary_data = fread($this->zip_fd, 18);\r\n\r\n    // ----- Look for invalid block size\r\n    if (strlen($v_binary_data) != 18)\r\n    {\r\n\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, \"Invalid End of Central Dir Record size : \".strlen($v_binary_data));\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Extract the values\r\n    $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);\r\n\r\n    // ----- Check the global size\r\n    if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {\r\n\r\n\t  // ----- Removed in release 2.2 see readme file\r\n\t  // The check of the file size is a little too strict.\r\n\t  // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.\r\n\t  // While decrypted, zip has training 0 bytes\r\n\t  if (0) {\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,\r\n\t                       'The central dir is not at the end of the archive.'\r\n\t\t\t\t\t\t   .' Some trailing bytes exists after the archive.');\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n\t  }\r\n    }\r\n\r\n    // ----- Get comment\r\n    if ($v_data['comment_size'] != 0) {\r\n      $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);\r\n    }\r\n    else\r\n      $p_central_dir['comment'] = '';\r\n\r\n    $p_central_dir['entries'] = $v_data['entries'];\r\n    $p_central_dir['disk_entries'] = $v_data['disk_entries'];\r\n    $p_central_dir['offset'] = $v_data['offset'];\r\n    $p_central_dir['size'] = $v_data['size'];\r\n    $p_central_dir['disk'] = $v_data['disk'];\r\n    $p_central_dir['disk_start'] = $v_data['disk_start'];\r\n\r\n    // TBC\r\n    //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {\r\n    //}\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privDeleteByRule()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privDeleteByRule(&$p_result_list, &$p_options)\r\n  {\r\n    $v_result=1;\r\n    $v_list_detail = array();\r\n\r\n    // ----- Open the zip file\r\n    if (($v_result=$this->privOpenFd('rb')) != 1)\r\n    {\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Read the central directory informations\r\n    $v_central_dir = array();\r\n    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)\r\n    {\r\n      $this->privCloseFd();\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Go to beginning of File\r\n    @rewind($this->zip_fd);\r\n\r\n    // ----- Scan all the files\r\n    // ----- Start at beginning of Central Dir\r\n    $v_pos_entry = $v_central_dir['offset'];\r\n    @rewind($this->zip_fd);\r\n    if (@fseek($this->zip_fd, $v_pos_entry))\r\n    {\r\n      // ----- Close the zip file\r\n      $this->privCloseFd();\r\n\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Read each entry\r\n    $v_header_list = array();\r\n    $j_start = 0;\r\n    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)\r\n    {\r\n\r\n      // ----- Read the file header\r\n      $v_header_list[$v_nb_extracted] = array();\r\n      if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)\r\n      {\r\n        // ----- Close the zip file\r\n        $this->privCloseFd();\r\n\r\n        return $v_result;\r\n      }\r\n\r\n\r\n      // ----- Store the index\r\n      $v_header_list[$v_nb_extracted]['index'] = $i;\r\n\r\n      // ----- Look for the specific extract rules\r\n      $v_found = false;\r\n\r\n      // ----- Look for extract by name rule\r\n      if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))\r\n          && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {\r\n\r\n          // ----- Look if the filename is in the list\r\n          for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {\r\n\r\n              // ----- Look for a directory\r\n              if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == \"/\") {\r\n\r\n                  // ----- Look if the directory is in the filename path\r\n                  if (   (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))\r\n                      && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {\r\n                      $v_found = true;\r\n                  }\r\n                  elseif (   (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */\r\n                          && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {\r\n                      $v_found = true;\r\n                  }\r\n              }\r\n              // ----- Look for a filename\r\n              elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {\r\n                  $v_found = true;\r\n              }\r\n          }\r\n      }\r\n\r\n      // ----- Look for extract by ereg rule\r\n      // ereg() is deprecated with PHP 5.3\r\n      /*\r\n      else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))\r\n               && ($p_options[PCLZIP_OPT_BY_EREG] != \"\")) {\r\n\r\n          if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {\r\n              $v_found = true;\r\n          }\r\n      }\r\n      */\r\n\r\n      // ----- Look for extract by preg rule\r\n      else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))\r\n               && ($p_options[PCLZIP_OPT_BY_PREG] != \"\")) {\r\n\r\n          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {\r\n              $v_found = true;\r\n          }\r\n      }\r\n\r\n      // ----- Look for extract by index rule\r\n      else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))\r\n               && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {\r\n\r\n          // ----- Look if the index is in the list\r\n          for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {\r\n\r\n              if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {\r\n                  $v_found = true;\r\n              }\r\n              if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {\r\n                  $j_start = $j+1;\r\n              }\r\n\r\n              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {\r\n                  break;\r\n              }\r\n          }\r\n      }\r\n      else {\r\n      \t$v_found = true;\r\n      }\r\n\r\n      // ----- Look for deletion\r\n      if ($v_found)\r\n      {\r\n        unset($v_header_list[$v_nb_extracted]);\r\n      }\r\n      else\r\n      {\r\n        $v_nb_extracted++;\r\n      }\r\n    }\r\n\r\n    // ----- Look if something need to be deleted\r\n    if ($v_nb_extracted > 0) {\r\n\r\n        // ----- Creates a temporay file\r\n        $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';\r\n\r\n        // ----- Creates a temporary zip archive\r\n        $v_temp_zip = new PclZip($v_zip_temp_name);\r\n\r\n        // ----- Open the temporary zip file in write mode\r\n        if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {\r\n            $this->privCloseFd();\r\n\r\n            // ----- Return\r\n            return $v_result;\r\n        }\r\n\r\n        // ----- Look which file need to be kept\r\n        for ($i=0; $i<sizeof($v_header_list); $i++) {\r\n\r\n            // ----- Calculate the position of the header\r\n            @rewind($this->zip_fd);\r\n            if (@fseek($this->zip_fd,  $v_header_list[$i]['offset'])) {\r\n                // ----- Close the zip file\r\n                $this->privCloseFd();\r\n                $v_temp_zip->privCloseFd();\r\n                @unlink($v_zip_temp_name);\r\n\r\n                // ----- Error log\r\n                PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');\r\n\r\n                // ----- Return\r\n                return PclZip::errorCode();\r\n            }\r\n\r\n            // ----- Read the file header\r\n            $v_local_header = array();\r\n            if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {\r\n                // ----- Close the zip file\r\n                $this->privCloseFd();\r\n                $v_temp_zip->privCloseFd();\r\n                @unlink($v_zip_temp_name);\r\n\r\n                // ----- Return\r\n                return $v_result;\r\n            }\r\n            \r\n            // ----- Check that local file header is same as central file header\r\n            if ($this->privCheckFileHeaders($v_local_header,\r\n\t\t\t                                $v_header_list[$i]) != 1) {\r\n                // TBC\r\n            }\r\n            unset($v_local_header);\r\n\r\n            // ----- Write the file header\r\n            if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {\r\n                // ----- Close the zip file\r\n                $this->privCloseFd();\r\n                $v_temp_zip->privCloseFd();\r\n                @unlink($v_zip_temp_name);\r\n\r\n                // ----- Return\r\n                return $v_result;\r\n            }\r\n\r\n            // ----- Read/write the data block\r\n            if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {\r\n                // ----- Close the zip file\r\n                $this->privCloseFd();\r\n                $v_temp_zip->privCloseFd();\r\n                @unlink($v_zip_temp_name);\r\n\r\n                // ----- Return\r\n                return $v_result;\r\n            }\r\n        }\r\n\r\n        // ----- Store the offset of the central dir\r\n        $v_offset = @ftell($v_temp_zip->zip_fd);\r\n\r\n        // ----- Re-Create the Central Dir files header\r\n        for ($i=0; $i<sizeof($v_header_list); $i++) {\r\n            // ----- Create the file header\r\n            if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {\r\n                $v_temp_zip->privCloseFd();\r\n                $this->privCloseFd();\r\n                @unlink($v_zip_temp_name);\r\n\r\n                // ----- Return\r\n                return $v_result;\r\n            }\r\n\r\n            // ----- Transform the header to a 'usable' info\r\n            $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);\r\n        }\r\n\r\n\r\n        // ----- Zip file comment\r\n        $v_comment = '';\r\n        if (isset($p_options[PCLZIP_OPT_COMMENT])) {\r\n          $v_comment = $p_options[PCLZIP_OPT_COMMENT];\r\n        }\r\n\r\n        // ----- Calculate the size of the central header\r\n        $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;\r\n\r\n        // ----- Create the central dir footer\r\n        if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {\r\n            // ----- Reset the file list\r\n            unset($v_header_list);\r\n            $v_temp_zip->privCloseFd();\r\n            $this->privCloseFd();\r\n            @unlink($v_zip_temp_name);\r\n\r\n            // ----- Return\r\n            return $v_result;\r\n        }\r\n\r\n        // ----- Close\r\n        $v_temp_zip->privCloseFd();\r\n        $this->privCloseFd();\r\n\r\n        // ----- Delete the zip file\r\n        // TBC : I should test the result ...\r\n        @unlink($this->zipname);\r\n\r\n        // ----- Rename the temporary file\r\n        // TBC : I should test the result ...\r\n        //@rename($v_zip_temp_name, $this->zipname);\r\n        PclZipUtilRename($v_zip_temp_name, $this->zipname);\r\n    \r\n        // ----- Destroy the temporary archive\r\n        unset($v_temp_zip);\r\n    }\r\n    \r\n    // ----- Remove every files : reset the file\r\n    else if ($v_central_dir['entries'] != 0) {\r\n        $this->privCloseFd();\r\n\r\n        if (($v_result = $this->privOpenFd('wb')) != 1) {\r\n          return $v_result;\r\n        }\r\n\r\n        if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {\r\n          return $v_result;\r\n        }\r\n\r\n        $this->privCloseFd();\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privDirCheck()\r\n  // Description :\r\n  //   Check if a directory exists, if not it creates it and all the parents directory\r\n  //   which may be useful.\r\n  // Parameters :\r\n  //   $p_dir : Directory path to check.\r\n  // Return Values :\r\n  //    1 : OK\r\n  //   -1 : Unable to create directory\r\n  // --------------------------------------------------------------------------------\r\n  function privDirCheck($p_dir, $p_is_dir=false)\r\n  {\r\n    $v_result = 1;\r\n\r\n\r\n    // ----- Remove the final '/'\r\n    if (($p_is_dir) && (substr($p_dir, -1)=='/'))\r\n    {\r\n      $p_dir = substr($p_dir, 0, strlen($p_dir)-1);\r\n    }\r\n\r\n    // ----- Check the directory availability\r\n    if ((is_dir($p_dir)) || ($p_dir == \"\"))\r\n    {\r\n      return 1;\r\n    }\r\n\r\n    // ----- Extract parent directory\r\n    $p_parent_dir = dirname($p_dir);\r\n\r\n    // ----- Just a check\r\n    if ($p_parent_dir != $p_dir)\r\n    {\r\n      // ----- Look for parent directory\r\n      if ($p_parent_dir != \"\")\r\n      {\r\n        if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)\r\n        {\r\n          return $v_result;\r\n        }\r\n      }\r\n    }\r\n\r\n    // ----- Create the directory\r\n    if (!@mkdir($p_dir, 0777))\r\n    {\r\n      // ----- Error log\r\n      PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, \"Unable to create directory '$p_dir'\");\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privMerge()\r\n  // Description :\r\n  //   If $p_archive_to_add does not exist, the function exit with a success result.\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privMerge(&$p_archive_to_add)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Look if the archive_to_add exists\r\n    if (!is_file($p_archive_to_add->zipname))\r\n    {\r\n\r\n      // ----- Nothing to merge, so merge is a success\r\n      $v_result = 1;\r\n\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Look if the archive exists\r\n    if (!is_file($this->zipname))\r\n    {\r\n\r\n      // ----- Do a duplicate\r\n      $v_result = $this->privDuplicate($p_archive_to_add->zipname);\r\n\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Open the zip file\r\n    if (($v_result=$this->privOpenFd('rb')) != 1)\r\n    {\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Read the central directory informations\r\n    $v_central_dir = array();\r\n    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)\r\n    {\r\n      $this->privCloseFd();\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Go to beginning of File\r\n    @rewind($this->zip_fd);\r\n\r\n    // ----- Open the archive_to_add file\r\n    if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)\r\n    {\r\n      $this->privCloseFd();\r\n\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Read the central directory informations\r\n    $v_central_dir_to_add = array();\r\n    if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)\r\n    {\r\n      $this->privCloseFd();\r\n      $p_archive_to_add->privCloseFd();\r\n\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Go to beginning of File\r\n    @rewind($p_archive_to_add->zip_fd);\r\n\r\n    // ----- Creates a temporay file\r\n    $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';\r\n\r\n    // ----- Open the temporary file in write mode\r\n    if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)\r\n    {\r\n      $this->privCloseFd();\r\n      $p_archive_to_add->privCloseFd();\r\n\r\n      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \\''.$v_zip_temp_name.'\\' in binary write mode');\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Copy the files from the archive to the temporary file\r\n    // TBC : Here I should better append the file and go back to erase the central dir\r\n    $v_size = $v_central_dir['offset'];\r\n    while ($v_size != 0)\r\n    {\r\n      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);\r\n      $v_buffer = fread($this->zip_fd, $v_read_size);\r\n      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);\r\n      $v_size -= $v_read_size;\r\n    }\r\n\r\n    // ----- Copy the files from the archive_to_add into the temporary file\r\n    $v_size = $v_central_dir_to_add['offset'];\r\n    while ($v_size != 0)\r\n    {\r\n      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);\r\n      $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);\r\n      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);\r\n      $v_size -= $v_read_size;\r\n    }\r\n\r\n    // ----- Store the offset of the central dir\r\n    $v_offset = @ftell($v_zip_temp_fd);\r\n\r\n    // ----- Copy the block of file headers from the old archive\r\n    $v_size = $v_central_dir['size'];\r\n    while ($v_size != 0)\r\n    {\r\n      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);\r\n      $v_buffer = @fread($this->zip_fd, $v_read_size);\r\n      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);\r\n      $v_size -= $v_read_size;\r\n    }\r\n\r\n    // ----- Copy the block of file headers from the archive_to_add\r\n    $v_size = $v_central_dir_to_add['size'];\r\n    while ($v_size != 0)\r\n    {\r\n      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);\r\n      $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);\r\n      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);\r\n      $v_size -= $v_read_size;\r\n    }\r\n\r\n    // ----- Merge the file comments\r\n    $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];\r\n\r\n    // ----- Calculate the size of the (new) central header\r\n    $v_size = @ftell($v_zip_temp_fd)-$v_offset;\r\n\r\n    // ----- Swap the file descriptor\r\n    // Here is a trick : I swap the temporary fd with the zip fd, in order to use\r\n    // the following methods on the temporary fil and not the real archive fd\r\n    $v_swap = $this->zip_fd;\r\n    $this->zip_fd = $v_zip_temp_fd;\r\n    $v_zip_temp_fd = $v_swap;\r\n\r\n    // ----- Create the central dir footer\r\n    if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)\r\n    {\r\n      $this->privCloseFd();\r\n      $p_archive_to_add->privCloseFd();\r\n      @fclose($v_zip_temp_fd);\r\n      $this->zip_fd = null;\r\n\r\n      // ----- Reset the file list\r\n      unset($v_header_list);\r\n\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Swap back the file descriptor\r\n    $v_swap = $this->zip_fd;\r\n    $this->zip_fd = $v_zip_temp_fd;\r\n    $v_zip_temp_fd = $v_swap;\r\n\r\n    // ----- Close\r\n    $this->privCloseFd();\r\n    $p_archive_to_add->privCloseFd();\r\n\r\n    // ----- Close the temporary file\r\n    @fclose($v_zip_temp_fd);\r\n\r\n    // ----- Delete the zip file\r\n    // TBC : I should test the result ...\r\n    @unlink($this->zipname);\r\n\r\n    // ----- Rename the temporary file\r\n    // TBC : I should test the result ...\r\n    //@rename($v_zip_temp_name, $this->zipname);\r\n    PclZipUtilRename($v_zip_temp_name, $this->zipname);\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privDuplicate()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privDuplicate($p_archive_filename)\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Look if the $p_archive_filename exists\r\n    if (!is_file($p_archive_filename))\r\n    {\r\n\r\n      // ----- Nothing to duplicate, so duplicate is a success.\r\n      $v_result = 1;\r\n\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Open the zip file\r\n    if (($v_result=$this->privOpenFd('wb')) != 1)\r\n    {\r\n      // ----- Return\r\n      return $v_result;\r\n    }\r\n\r\n    // ----- Open the temporary file in write mode\r\n    if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)\r\n    {\r\n      $this->privCloseFd();\r\n\r\n      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \\''.$p_archive_filename.'\\' in binary write mode');\r\n\r\n      // ----- Return\r\n      return PclZip::errorCode();\r\n    }\r\n\r\n    // ----- Copy the files from the archive to the temporary file\r\n    // TBC : Here I should better append the file and go back to erase the central dir\r\n    $v_size = filesize($p_archive_filename);\r\n    while ($v_size != 0)\r\n    {\r\n      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);\r\n      $v_buffer = fread($v_zip_temp_fd, $v_read_size);\r\n      @fwrite($this->zip_fd, $v_buffer, $v_read_size);\r\n      $v_size -= $v_read_size;\r\n    }\r\n\r\n    // ----- Close\r\n    $this->privCloseFd();\r\n\r\n    // ----- Close the temporary file\r\n    @fclose($v_zip_temp_fd);\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privErrorLog()\r\n  // Description :\r\n  // Parameters :\r\n  // --------------------------------------------------------------------------------\r\n  function privErrorLog($p_error_code=0, $p_error_string='')\r\n  {\r\n    if (PCLZIP_ERROR_EXTERNAL == 1) {\r\n      PclError($p_error_code, $p_error_string);\r\n    }\r\n    else {\r\n      $this->error_code = $p_error_code;\r\n      $this->error_string = $p_error_string;\r\n    }\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privErrorReset()\r\n  // Description :\r\n  // Parameters :\r\n  // --------------------------------------------------------------------------------\r\n  function privErrorReset()\r\n  {\r\n    if (PCLZIP_ERROR_EXTERNAL == 1) {\r\n      PclErrorReset();\r\n    }\r\n    else {\r\n      $this->error_code = 0;\r\n      $this->error_string = '';\r\n    }\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privDisableMagicQuotes()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privDisableMagicQuotes()\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Look if function exists\r\n    if (   (!function_exists(\"get_magic_quotes_runtime\"))\r\n\t    || (!function_exists(\"set_magic_quotes_runtime\"))) {\r\n      return $v_result;\r\n\t}\r\n\r\n    // ----- Look if already done\r\n    if ($this->magic_quotes_status != -1) {\r\n      return $v_result;\r\n\t}\r\n\r\n\t// ----- Get and memorize the magic_quote value\r\n\t$this->magic_quotes_status = @get_magic_quotes_runtime();\r\n\r\n\t// ----- Disable magic_quotes\r\n\tif ($this->magic_quotes_status == 1) {\r\n\t  @set_magic_quotes_runtime(0);\r\n\t}\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : privSwapBackMagicQuotes()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function privSwapBackMagicQuotes()\r\n  {\r\n    $v_result=1;\r\n\r\n    // ----- Look if function exists\r\n    if (   (!function_exists(\"get_magic_quotes_runtime\"))\r\n\t    || (!function_exists(\"set_magic_quotes_runtime\"))) {\r\n      return $v_result;\r\n\t}\r\n\r\n    // ----- Look if something to do\r\n    if ($this->magic_quotes_status != -1) {\r\n      return $v_result;\r\n\t}\r\n\r\n\t// ----- Swap back magic_quotes\r\n\tif ($this->magic_quotes_status == 1) {\r\n  \t  @set_magic_quotes_runtime($this->magic_quotes_status);\r\n\t}\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  }\r\n  // End of class\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : PclZipUtilPathReduction()\r\n  // Description :\r\n  // Parameters :\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function PclZipUtilPathReduction($p_dir)\r\n  {\r\n    $v_result = \"\";\r\n\r\n    // ----- Look for not empty path\r\n    if ($p_dir != \"\") {\r\n      // ----- Explode path by directory names\r\n      $v_list = explode(\"/\", $p_dir);\r\n\r\n      // ----- Study directories from last to first\r\n      $v_skip = 0;\r\n      for ($i=sizeof($v_list)-1; $i>=0; $i--) {\r\n        // ----- Look for current path\r\n        if ($v_list[$i] == \".\") {\r\n          // ----- Ignore this directory\r\n          // Should be the first $i=0, but no check is done\r\n        }\r\n        else if ($v_list[$i] == \"..\") {\r\n\t\t  $v_skip++;\r\n        }\r\n        else if ($v_list[$i] == \"\") {\r\n\t\t  // ----- First '/' i.e. root slash\r\n\t\t  if ($i == 0) {\r\n            $v_result = \"/\".$v_result;\r\n\t\t    if ($v_skip > 0) {\r\n\t\t        // ----- It is an invalid path, so the path is not modified\r\n\t\t        // TBC\r\n\t\t        $v_result = $p_dir;\r\n                $v_skip = 0;\r\n\t\t    }\r\n\t\t  }\r\n\t\t  // ----- Last '/' i.e. indicates a directory\r\n\t\t  else if ($i == (sizeof($v_list)-1)) {\r\n            $v_result = $v_list[$i];\r\n\t\t  }\r\n\t\t  // ----- Double '/' inside the path\r\n\t\t  else {\r\n            // ----- Ignore only the double '//' in path,\r\n            // but not the first and last '/'\r\n\t\t  }\r\n        }\r\n        else {\r\n\t\t  // ----- Look for item to skip\r\n\t\t  if ($v_skip > 0) {\r\n\t\t    $v_skip--;\r\n\t\t  }\r\n\t\t  else {\r\n            $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?\"/\".$v_result:\"\");\r\n\t\t  }\r\n        }\r\n      }\r\n      \r\n      // ----- Look for skip\r\n      if ($v_skip > 0) {\r\n        while ($v_skip > 0) {\r\n            $v_result = '../'.$v_result;\r\n            $v_skip--;\r\n        }\r\n      }\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : PclZipUtilPathInclusion()\r\n  // Description :\r\n  //   This function indicates if the path $p_path is under the $p_dir tree. Or,\r\n  //   said in an other way, if the file or sub-dir $p_path is inside the dir\r\n  //   $p_dir.\r\n  //   The function indicates also if the path is exactly the same as the dir.\r\n  //   This function supports path with duplicated '/' like '//', but does not\r\n  //   support '.' or '..' statements.\r\n  // Parameters :\r\n  // Return Values :\r\n  //   0 if $p_path is not inside directory $p_dir\r\n  //   1 if $p_path is inside directory $p_dir\r\n  //   2 if $p_path is exactly the same as $p_dir\r\n  // --------------------------------------------------------------------------------\r\n  function PclZipUtilPathInclusion($p_dir, $p_path)\r\n  {\r\n    $v_result = 1;\r\n    \r\n    // ----- Look for path beginning by ./\r\n    if (   ($p_dir == '.')\r\n        || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {\r\n      $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);\r\n    }\r\n    if (   ($p_path == '.')\r\n        || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {\r\n      $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);\r\n    }\r\n\r\n    // ----- Explode dir and path by directory separator\r\n    $v_list_dir = explode(\"/\", $p_dir);\r\n    $v_list_dir_size = sizeof($v_list_dir);\r\n    $v_list_path = explode(\"/\", $p_path);\r\n    $v_list_path_size = sizeof($v_list_path);\r\n\r\n    // ----- Study directories paths\r\n    $i = 0;\r\n    $j = 0;\r\n    while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {\r\n\r\n      // ----- Look for empty dir (path reduction)\r\n      if ($v_list_dir[$i] == '') {\r\n        $i++;\r\n        continue;\r\n      }\r\n      if ($v_list_path[$j] == '') {\r\n        $j++;\r\n        continue;\r\n      }\r\n\r\n      // ----- Compare the items\r\n      if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != ''))  {\r\n        $v_result = 0;\r\n      }\r\n\r\n      // ----- Next items\r\n      $i++;\r\n      $j++;\r\n    }\r\n\r\n    // ----- Look if everything seems to be the same\r\n    if ($v_result) {\r\n      // ----- Skip all the empty items\r\n      while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;\r\n      while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;\r\n\r\n      if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {\r\n        // ----- There are exactly the same\r\n        $v_result = 2;\r\n      }\r\n      else if ($i < $v_list_dir_size) {\r\n        // ----- The path is shorter than the dir\r\n        $v_result = 0;\r\n      }\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : PclZipUtilCopyBlock()\r\n  // Description :\r\n  // Parameters :\r\n  //   $p_mode : read/write compression mode\r\n  //             0 : src & dest normal\r\n  //             1 : src gzip, dest normal\r\n  //             2 : src normal, dest gzip\r\n  //             3 : src & dest gzip\r\n  // Return Values :\r\n  // --------------------------------------------------------------------------------\r\n  function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)\r\n  {\r\n    $v_result = 1;\r\n\r\n    if ($p_mode==0)\r\n    {\r\n      while ($p_size != 0)\r\n      {\r\n        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);\r\n        $v_buffer = @fread($p_src, $v_read_size);\r\n        @fwrite($p_dest, $v_buffer, $v_read_size);\r\n        $p_size -= $v_read_size;\r\n      }\r\n    }\r\n    else if ($p_mode==1)\r\n    {\r\n      while ($p_size != 0)\r\n      {\r\n        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);\r\n        $v_buffer = @gzread($p_src, $v_read_size);\r\n        @fwrite($p_dest, $v_buffer, $v_read_size);\r\n        $p_size -= $v_read_size;\r\n      }\r\n    }\r\n    else if ($p_mode==2)\r\n    {\r\n      while ($p_size != 0)\r\n      {\r\n        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);\r\n        $v_buffer = @fread($p_src, $v_read_size);\r\n        @gzwrite($p_dest, $v_buffer, $v_read_size);\r\n        $p_size -= $v_read_size;\r\n      }\r\n    }\r\n    else if ($p_mode==3)\r\n    {\r\n      while ($p_size != 0)\r\n      {\r\n        $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);\r\n        $v_buffer = @gzread($p_src, $v_read_size);\r\n        @gzwrite($p_dest, $v_buffer, $v_read_size);\r\n        $p_size -= $v_read_size;\r\n      }\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : PclZipUtilRename()\r\n  // Description :\r\n  //   This function tries to do a simple rename() function. If it fails, it\r\n  //   tries to copy the $p_src file in a new $p_dest file and then unlink the\r\n  //   first one.\r\n  // Parameters :\r\n  //   $p_src : Old filename\r\n  //   $p_dest : New filename\r\n  // Return Values :\r\n  //   1 on success, 0 on failure.\r\n  // --------------------------------------------------------------------------------\r\n  function PclZipUtilRename($p_src, $p_dest)\r\n  {\r\n    $v_result = 1;\r\n\r\n    // ----- Try to rename the files\r\n    if (!@rename($p_src, $p_dest)) {\r\n\r\n      // ----- Try to copy & unlink the src\r\n      if (!@copy($p_src, $p_dest)) {\r\n        $v_result = 0;\r\n      }\r\n      else if (!@unlink($p_src)) {\r\n        $v_result = 0;\r\n      }\r\n    }\r\n\r\n    // ----- Return\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : PclZipUtilOptionText()\r\n  // Description :\r\n  //   Translate option value in text. Mainly for debug purpose.\r\n  // Parameters :\r\n  //   $p_option : the option value.\r\n  // Return Values :\r\n  //   The option text value.\r\n  // --------------------------------------------------------------------------------\r\n  function PclZipUtilOptionText($p_option)\r\n  {\r\n    \r\n    $v_list = get_defined_constants();\r\n    for (reset($v_list); $v_key = key($v_list); next($v_list)) {\r\n\t    $v_prefix = substr($v_key, 0, 10);\r\n\t    if ((   ($v_prefix == 'PCLZIP_OPT')\r\n           || ($v_prefix == 'PCLZIP_CB_')\r\n           || ($v_prefix == 'PCLZIP_ATT'))\r\n\t        && ($v_list[$v_key] == $p_option)) {\r\n        return $v_key;\r\n\t    }\r\n    }\r\n    \r\n    $v_result = 'Unknown';\r\n\r\n    return $v_result;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n\r\n  // --------------------------------------------------------------------------------\r\n  // Function : PclZipUtilTranslateWinPath()\r\n  // Description :\r\n  //   Translate windows path by replacing '\\' by '/' and optionally removing\r\n  //   drive letter.\r\n  // Parameters :\r\n  //   $p_path : path to translate.\r\n  //   $p_remove_disk_letter : true | false\r\n  // Return Values :\r\n  //   The path translated.\r\n  // --------------------------------------------------------------------------------\r\n  function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)\r\n  {\r\n    if (stristr(php_uname(), 'windows')) {\r\n      // ----- Look for potential disk letter\r\n      if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {\r\n          $p_path = substr($p_path, $v_position+1);\r\n      }\r\n      // ----- Change potential windows directory separator\r\n      if ((strpos($p_path, '\\\\') > 0) || (substr($p_path, 0,1) == '\\\\')) {\r\n          $p_path = strtr($p_path, '\\\\', '/');\r\n      }\r\n    }\r\n    return $p_path;\r\n  }\r\n  // --------------------------------------------------------------------------------\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/PCLZip/readme.txt",
    "content": "// --------------------------------------------------------------------------------\r\n// PclZip 2.8.2 - readme.txt\r\n// --------------------------------------------------------------------------------\r\n// License GNU/LGPL - August 2009\r\n// Vincent Blavet - vincent@phpconcept.net\r\n// http://www.phpconcept.net\r\n// --------------------------------------------------------------------------------\r\n// $Id: readme.txt,v 1.60 2009/09/30 20:35:21 vblavet Exp $\r\n// --------------------------------------------------------------------------------\r\n\r\n\r\n\r\n0 - Sommaire\r\n============\r\n    1 - Introduction\r\n    2 - What's new\r\n    3 - Corrected bugs\r\n    4 - Known bugs or limitations\r\n    5 - License\r\n    6 - Warning\r\n    7 - Documentation\r\n    8 - Author\r\n    9 - Contribute\r\n\r\n1 - Introduction\r\n================\r\n\r\n  PclZip is a library that allow you to manage a Zip archive.\r\n\r\n  Full documentation about PclZip can be found here : http://www.phpconcept.net/pclzip\r\n\r\n2 - What's new\r\n==============\r\n\r\n  Version 2.8.2 :\r\n    - PCLZIP_CB_PRE_EXTRACT and PCLZIP_CB_POST_EXTRACT are now supported with \r\n      extraction as a string (PCLZIP_OPT_EXTRACT_AS_STRING). The string\r\n      can also be modified in the post-extract call back.\r\n    **Bugs correction :\r\n    - PCLZIP_OPT_REMOVE_ALL_PATH was not working correctly    \r\n    - Remove use of eval() and do direct call to callback functions\r\n    - Correct support of 64bits systems (Thanks to WordPress team)\r\n\r\n  Version 2.8.1 :\r\n    - Move option PCLZIP_OPT_BY_EREG to PCLZIP_OPT_BY_PREG because ereg() is\r\n      deprecated in PHP 5.3. When using option PCLZIP_OPT_BY_EREG, PclZip will\r\n      automatically replace it by PCLZIP_OPT_BY_PREG.\r\n  \r\n  Version 2.8 :\r\n    - Improve extraction of zip archive for large files by using temporary files\r\n      This feature is working like the one defined in r2.7.\r\n      Options are renamed : PCLZIP_OPT_TEMP_FILE_ON, PCLZIP_OPT_TEMP_FILE_OFF,\r\n      PCLZIP_OPT_TEMP_FILE_THRESHOLD\r\n    - Add a ratio constant PCLZIP_TEMPORARY_FILE_RATIO to configure the auto\r\n      sense of temporary file use.\r\n    - Bug correction : Reduce filepath in returned file list to remove ennoying\r\n      './/' preambule in file path.\r\n\r\n  Version 2.7 :\r\n    - Improve creation of zip archive for large files :\r\n      PclZip will now autosense the configured memory and use temporary files\r\n      when large file is suspected.\r\n      This feature can also ne triggered by manual options in create() and add()\r\n      methods. 'PCLZIP_OPT_ADD_TEMP_FILE_ON' force the use of temporary files,\r\n      'PCLZIP_OPT_ADD_TEMP_FILE_OFF' disable the autosense technic, \r\n      'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD' allow for configuration of a size\r\n      threshold to use temporary files.\r\n      Using \"temporary files\" rather than \"memory\" might take more time, but\r\n      might give the ability to zip very large files :\r\n      Tested on my win laptop with a 88Mo file :\r\n        Zip \"in-memory\" : 18sec (max_execution_time=30, memory_limit=180Mo)\r\n        Zip \"tmporary-files\" : 23sec (max_execution_time=30, memory_limit=30Mo)\r\n    - Replace use of mktime() by time() to limit the E_STRICT error messages.\r\n    - Bug correction : When adding files with full windows path (drive letter)\r\n      PclZip is now working. Before, if the drive letter is not the default\r\n      path, PclZip was not able to add the file.\r\n\r\n  Version 2.6 :\r\n    - Code optimisation\r\n    - New attributes PCLZIP_ATT_FILE_COMMENT gives the ability to\r\n      add a comment for a specific file. (Don't really know if this is usefull)\r\n    - New attribute PCLZIP_ATT_FILE_CONTENT gives the ability to add a string \r\n      as a file.\r\n    - New attribute PCLZIP_ATT_FILE_MTIME modify the timestamp associated with\r\n      a file.\r\n    - Correct a bug. Files archived with a timestamp with 0h0m0s were extracted\r\n      with current time\r\n    - Add CRC value in the informations returned back for each file after an\r\n      action.\r\n    - Add missing closedir() statement.\r\n    - When adding a folder, and removing the path of this folder, files were\r\n      incorrectly added with a '/' at the beginning. Which means files are \r\n      related to root in unix systems. Corrected.\r\n    - Add conditional if before constant definition. This will allow users\r\n      to redefine constants without changing the file, and then improve\r\n      upgrade of pclzip code for new versions.\r\n  \r\n  Version 2.5 :\r\n    - Introduce the ability to add file/folder with individual properties (file descriptor).\r\n      This gives for example the ability to change the filename of a zipped file.\r\n      . Able to add files individually\r\n      . Able to change full name\r\n      . Able to change short name\r\n      . Compatible with global options\r\n    - New attributes : PCLZIP_ATT_FILE_NAME, PCLZIP_ATT_FILE_NEW_SHORT_NAME, PCLZIP_ATT_FILE_NEW_FULL_NAME\r\n    - New error code : PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE\r\n    - Add a security control feature. PclZip can extract any file in any folder\r\n      of a system. People may use this to upload a zip file and try to override\r\n      a system file. The PCLZIP_OPT_EXTRACT_DIR_RESTRICTION will give the\r\n      ability to forgive any directory transversal behavior.\r\n    - New PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : check extraction path\r\n    - New error code : PCLZIP_ERR_DIRECTORY_RESTRICTION\r\n    - Modification in PclZipUtilPathInclusion() : dir and path beginning with ./ will be prepend\r\n      by current path (getcwd())\r\n  \r\n  Version 2.4 :\r\n    - Code improvment : try to speed up the code by removing unusefull call to pack()\r\n    - Correct bug in delete() : delete() should be called with no argument. This was not\r\n      the case in 2.3. This is corrected in 2.4.\r\n    - Correct a bug in path_inclusion function. When the path has several '../../', the\r\n      result was bad.\r\n    - Add a check for magic_quotes_runtime configuration. If enabled, PclZip will \r\n      disable it while working and det it back to its original value.\r\n      This resolve a lots of bad formated archive errors.\r\n    - Bug correction : PclZip now correctly unzip file in some specific situation,\r\n      when compressed content has same size as uncompressed content.\r\n    - Bug correction : When selecting option 'PCLZIP_OPT_REMOVE_ALL_PATH', \r\n      directories are not any more created.\r\n    - Code improvment : correct unclosed opendir(), better handling of . and .. in\r\n      loops.\r\n\r\n\r\n  Version 2.3 :\r\n    - Correct a bug with PHP5 : affecting the value 0xFE49FFE0 to a variable does not\r\n      give the same result in PHP4 and PHP5 ....\r\n\r\n  Version 2.2 :\r\n    - Try development of PCLZIP_OPT_CRYPT .....\r\n      However this becomes to a stop. To crypt/decrypt I need to multiply 2 long integers,\r\n      the result (greater than a long) is not supported by PHP. Even the use of bcmath\r\n      functions does not help. I did not find yet a solution ...;\r\n    - Add missing '/' at end of directory entries\r\n    - Check is a file is encrypted or not. Returns status 'unsupported_encryption' and/or\r\n      error code PCLZIP_ERR_UNSUPPORTED_ENCRYPTION.\r\n    - Corrected : Bad \"version need to extract\" field in local file header\r\n    - Add private method privCheckFileHeaders() in order to check local and central\r\n      file headers. PclZip is now supporting purpose bit flag bit 3. Purpose bit flag bit 3 gives\r\n      the ability to have a local file header without size, compressed size and crc filled.\r\n    - Add a generic status 'error' for file status\r\n    - Add control of compression type. PclZip only support deflate compression method.\r\n      Before v2.2, PclZip does not check the compression method used in an archive while\r\n      extracting. With v2.2 PclZip returns a new error status for a file using an unsupported\r\n      compression method. New status is \"unsupported_compression\". New error code is\r\n      PCLZIP_ERR_UNSUPPORTED_COMPRESSION.\r\n    - Add optional attribute PCLZIP_OPT_STOP_ON_ERROR. This will stop the extract of files\r\n      when errors like 'a folder with same name exists' or 'a newer file exists' or\r\n      'a write protected file' exists, rather than set a status for the concerning file\r\n      and resume the extract of the zip.\r\n    - Add optional attribute PCLZIP_OPT_REPLACE_NEWER. This will force, during an extract' the\r\n      replacement of the file, even if a  newer version of the file exists.\r\n      Note that today if a file with the same name already exists but is older it will be\r\n      replaced by the extracted one.\r\n    - Improve PclZipUtilOption()\r\n    - Support of zip archive with trailing bytes. Before 2.2, PclZip checks that the central\r\n      directory structure is the last data in the archive. Crypt encryption/decryption of\r\n      zip archive put trailing 0 bytes after decryption. PclZip is now supporting this.\r\n\r\n  Version 2.1 :\r\n    - Add the ability to abort the extraction by using a user callback function.\r\n      The user can now return the value '2' in its callback which indicates to stop the\r\n      extraction. For a pre call-back extract is stopped before the extration of the current\r\n      file. For a post call back, the extraction is stopped after.\r\n    - Add the ability to extract a file (or several files) directly in the standard output.\r\n      This is done by the new parameter PCLZIP_OPT_EXTRACT_IN_OUTPUT with method extract().\r\n    - Add support for parameters PCLZIP_OPT_COMMENT, PCLZIP_OPT_ADD_COMMENT,\r\n      PCLZIP_OPT_PREPEND_COMMENT. This will create, replace, add, or prepend comments\r\n      in the zip archive.\r\n    - When merging two archives, the comments are not any more lost, but merged, with a \r\n      blank space separator.\r\n    - Corrected bug : Files are not deleted when all files are asked to be deleted.\r\n    - Corrected bug : Folders with name '0' made PclZip to abort the create or add feature.\r\n\r\n\r\n  Version 2.0 :\r\n    ***** Warning : Some new features may break the backward compatibility for your scripts.\r\n                    Please carefully read the readme file.\r\n    - Add the ability to delete by Index, name and regular expression. This feature is \r\n      performed by the method delete(), which uses the optional parameters\r\n      PCLZIP_OPT_BY_INDEX, PCLZIP_OPT_BY_NAME, PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG.\r\n    - Add the ability to extract by regular expression. To extract by regexp you must use the method\r\n      extract(), with the option PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG \r\n      (depending if you want to use ereg() or preg_match() syntax) followed by the \r\n      regular expression pattern.\r\n    - Add the ability to extract by index, directly with the extract() method. This is a\r\n      code improvment of the extractByIndex() method.\r\n    - Add the ability to extract by name. To extract by name you must use the method\r\n      extract(), with the option PCLZIP_OPT_BY_NAME followed by the filename to\r\n      extract or an array of filenames to extract. To extract all a folder, use the folder\r\n      name rather than the filename with a '/' at the end.\r\n    - Add the ability to add files without compression. This is done with a new attribute\r\n      which is PCLZIP_OPT_NO_COMPRESSION.\r\n    - Add the attribute PCLZIP_OPT_EXTRACT_AS_STRING, which allow to extract a file directly\r\n      in a string without using any file (or temporary file).\r\n    - Add constant PCLZIP_SEPARATOR for static configuration of filename separators in a single string.\r\n      The default separator is now a comma (,) and not any more a blank space.\r\n      THIS BREAK THE BACKWARD COMPATIBILITY : Please check if this may have an impact with\r\n      your script.\r\n    - Improve algorythm performance by removing the use of temporary files when adding or \r\n      extracting files in an archive.\r\n    - Add (correct) detection of empty filename zipping. This can occurs when the removed\r\n      path is the same\r\n      as a zipped dir. The dir is not zipped (['status'] = filtered), only its content.\r\n    - Add better support for windows paths (thanks for help from manus@manusfreedom.com).\r\n    - Corrected bug : When the archive file already exists with size=0, the add() method\r\n      fails. Corrected in 2.0.\r\n    - Remove the use of OS_WINDOWS constant. Use php_uname() function rather.\r\n    - Control the order of index ranges in extract by index feature.\r\n    - Change the internal management of folders (better handling of internal flag).\r\n\r\n\r\n  Version 1.3 :\r\n    - Removing the double include check. This is now done by include_once() and require_once()\r\n      PHP directives.\r\n    - Changing the error handling mecanism : Remove the use of an external error library.\r\n      The former PclError...() functions are replaced by internal equivalent methods.\r\n      By changing the environment variable PCLZIP_ERROR_EXTERNAL you can still use the former library.\r\n      Introducing the use of constants for error codes rather than integer values. This will help\r\n      in futur improvment.\r\n      Introduction of error handling functions like errorCode(), errorName() and errorInfo().\r\n    - Remove the deprecated use of calling function with arguments passed by reference.\r\n    - Add the calling of extract(), extractByIndex(), create() and add() functions\r\n      with variable options rather than fixed arguments.\r\n    - Add the ability to remove all the file path while extracting or adding,\r\n      without any need to specify the path to remove.\r\n      This is available for extract(), extractByIndex(), create() and add() functionS by using\r\n      the new variable options parameters :\r\n      - PCLZIP_OPT_REMOVE_ALL_PATH : by indicating this option while calling the fct.\r\n    - Ability to change the mode of a file after the extraction (chmod()).\r\n      This is available for extract() and extractByIndex() functionS by using\r\n      the new variable options parameters.\r\n      - PCLZIP_OPT_SET_CHMOD : by setting the value of this option.\r\n    - Ability to definition call-back options. These call-back will be called during the adding,\r\n      or the extracting of file (extract(), extractByIndex(), create() and add() functions) :\r\n      - PCLZIP_CB_PRE_EXTRACT : will be called before each extraction of a file. The user\r\n        can trigerred the change the filename of the extracted file. The user can triggered the\r\n        skip of the extraction. This is adding a 'skipped' status in the file list result value.\r\n      - PCLZIP_CB_POST_EXTRACT : will be called after each extraction of a file.\r\n        Nothing can be triggered from that point.\r\n      - PCLZIP_CB_PRE_ADD : will be called before each add of a file. The user\r\n        can trigerred the change the stored filename of the added file. The user can triggered the\r\n        skip of the add. This is adding a 'skipped' status in the file list result value.\r\n      - PCLZIP_CB_POST_ADD : will be called after each add of a file.\r\n        Nothing can be triggered from that point.\r\n    - Two status are added in the file list returned as function result : skipped & filename_too_long\r\n      'skipped' is used when a call-back function ask for skipping the file.\r\n      'filename_too_long' is used while adding a file with a too long filename to archive (the file is\r\n      not added)\r\n    - Adding the function PclZipUtilPathInclusion(), that check the inclusion of a path into\r\n      a directory.\r\n    - Add a check of the presence of the archive file before some actions (like list, ...)\r\n    - Add the initialisation of field \"index\" in header array. This means that by\r\n      default index will be -1 when not explicitly set by the methods.\r\n\r\n  Version 1.2 :\r\n    - Adding a duplicate function.\r\n    - Adding a merge function. The merge function is a \"quick merge\" function,\r\n      it just append the content of an archive at the end of the first one. There\r\n      is no check for duplicate files or more recent files.\r\n    - Improve the search of the central directory end.\r\n\r\n  Version 1.1.2 :\r\n\r\n    - Changing the license of PclZip. PclZip is now released under the GNU / LGPL license\r\n      (see License section).\r\n    - Adding the optional support of a static temporary directory. You will need to configure\r\n      the constant PCLZIP_TEMPORARY_DIR if you want to use this feature.\r\n    - Improving the rename() function. In some cases rename() does not work (different\r\n      Filesystems), so it will be replaced by a copy() + unlink() functions.\r\n\r\n  Version 1.1.1 :\r\n\r\n    - Maintenance release, no new feature.\r\n\r\n  Version 1.1 :\r\n\r\n    - New method Add() : adding files in the archive\r\n    - New method ExtractByIndex() : partial extract of the archive, files are identified by\r\n      their index in the archive\r\n    - New method DeleteByIndex() : delete some files/folder entries from the archive,\r\n      files are identified by their index in the archive.\r\n    - Adding a test of the zlib extension presence. If not present abort the script.\r\n\r\n  Version 1.0.1 :\r\n\r\n    - No new feature\r\n\r\n\r\n3 - Corrected bugs\r\n==================\r\n\r\n  Corrected in Version 2.0 :\r\n    - Corrected : During an extraction, if a call-back fucntion is used and try to skip\r\n                  a file, all the extraction process is stopped. \r\n\r\n  Corrected in Version 1.3 :\r\n    - Corrected : Support of static synopsis for method extract() is broken.\r\n    - Corrected : invalid size of archive content field (0xFF) should be (0xFFFF).\r\n    - Corrected : When an extract is done with a remove_path parameter, the entry for\r\n      the directory with exactly the same path is not skipped/filtered.\r\n    - Corrected : extractByIndex() and deleteByIndex() were not managing index in the\r\n      right way. For example indexes '1,3-5,11' will only extract files 1 and 11. This\r\n      is due to a sort of the index resulting table that puts 11 before 3-5 (sort on\r\n      string and not interger). The sort is temporarilly removed, this means that\r\n      you must provide a sorted list of index ranges.\r\n\r\n  Corrected in Version 1.2 :\r\n\r\n    - Nothing.\r\n\r\n  Corrected in Version 1.1.2 :\r\n\r\n    - Corrected : Winzip is unable to delete or add new files in a PclZip created archives.\r\n\r\n  Corrected in Version 1.1.1 :\r\n\r\n    - Corrected : When archived file is not compressed (0% compression), the\r\n      extract method fails.\r\n\r\n  Corrected in Version 1.1 :\r\n\r\n    - Corrected : Adding a complete tree of folder may result in a bad archive\r\n      creation.\r\n\r\n  Corrected in Version 1.0.1 :\r\n\r\n    - Corrected : Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024).\r\n\r\n\r\n4 - Known bugs or limitations\r\n=============================\r\n\r\n  Please publish bugs reports in SourceForge :\r\n    http://sourceforge.net/tracker/?group_id=40254&atid=427564\r\n\r\n  In Version 2.x :\r\n    - PclZip does only support file uncompressed or compressed with deflate (compression method 8)\r\n    - PclZip does not support password protected zip archive\r\n    - Some concern were seen when changing mtime of a file while archiving. \r\n      Seems to be linked to Daylight Saving Time (PclTest_changing_mtime).\r\n\r\n  In Version 1.2 :\r\n\r\n    - merge() methods does not check for duplicate files or last date of modifications.\r\n\r\n  In Version 1.1 :\r\n\r\n    - Limitation : Using 'extract' fields in the file header in the zip archive is not supported.\r\n    - WinZip is unable to delete a single file in a PclZip created archive. It is also unable to\r\n      add a file in a PclZip created archive. (Corrected in v.1.2)\r\n\r\n  In Version 1.0.1 :\r\n\r\n    - Adding a complete tree of folder may result in a bad archive\r\n      creation. (Corrected in V.1.1).\r\n    - Path given to methods must be in the unix format (/) and not the Windows format (\\).\r\n      Workaround : Use only / directory separators.\r\n    - PclZip is using temporary files that are sometime the name of the file with a .tmp or .gz\r\n      added suffix. Files with these names may already exist and may be overwritten.\r\n      Workaround : none.\r\n    - PclZip does not check if the zlib extension is present. If it is absent, the zip\r\n      file is not created and the lib abort without warning.\r\n      Workaround : enable the zlib extension on the php install\r\n\r\n  In Version 1.0 :\r\n\r\n    - Error while compressing files greater than PCLZIP_READ_BLOCK_SIZE (default=1024).\r\n      (Corrected in v.1.0.1)\r\n    - Limitation : Multi-disk zip archive are not supported.\r\n\r\n\r\n5 - License\r\n===========\r\n\r\n  Since version 1.1.2, PclZip Library is released under GNU/LGPL license.\r\n  This library is free, so you can use it at no cost.\r\n\r\n  HOWEVER, if you release a script, an application, a library or any kind of\r\n  code using PclZip library (or a part of it), YOU MUST :\r\n  - Indicate in the documentation (or a readme file), that your work\r\n    uses PclZip Library, and make a reference to the author and the web site\r\n    http://www.phpconcept.net\r\n  - Gives the ability to the final user to update the PclZip libary.\r\n\r\n  I will also appreciate that you send me a mail (vincent@phpconcept.net), just to\r\n  be aware that someone is using PclZip.\r\n\r\n  For more information about GNU/LGPL license : http://www.gnu.org\r\n\r\n6 - Warning\r\n=================\r\n\r\n  This library and the associated files are non commercial, non professional work.\r\n  It should not have unexpected results. However if any damage is caused by this software\r\n  the author can not be responsible.\r\n  The use of this software is at the risk of the user.\r\n\r\n7 - Documentation\r\n=================\r\n  PclZip User Manuel is available in English on PhpConcept : http://www.phpconcept.net/pclzip/man/en/index.php\r\n  A Russian translation was done by Feskov Kuzma : http://php.russofile.ru/ru/authors/unsort/zip/\r\n\r\n8 - Author\r\n==========\r\n\r\n  This software was written by Vincent Blavet (vincent@phpconcept.net) on its leasure time.\r\n\r\n9 - Contribute\r\n==============\r\n  If you want to contribute to the development of PclZip, please contact vincent@phpconcept.net.\r\n  If you can help in financing PhpConcept hosting service, please go to\r\n  http://www.phpconcept.net/soutien.php\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/PasswordHasher.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Shared_PasswordHasher\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_PasswordHasher\n{\n\t/**\n\t * Create a password hash from a given string.\n\t *\n\t * This method is based on the algorithm provided by\n\t * Daniel Rentz of OpenOffice and the PEAR package\n\t * Spreadsheet_Excel_Writer by Xavier Noguer <xnoguer@rezebra.com>.\n\t *\n\t * @param \tstring\t$pPassword\tPassword to hash\n\t * @return \tstring\t\t\t\tHashed password\n\t */\n\tpublic static function hashPassword($pPassword = '') {\n        $password\t= 0x0000;\n        $charPos\t= 1;       // char position\n\n        // split the plain text password in its component characters\n        $chars = preg_split('//', $pPassword, -1, PREG_SPLIT_NO_EMPTY);\n        foreach ($chars as $char) {\n            $value\t\t\t= ord($char) << $charPos++;\t// shifted ASCII value\n            $rotated_bits\t= $value >> 15;\t\t\t\t// rotated bits beyond bit 15\n            $value\t\t\t&= 0x7fff;\t\t\t\t\t// first 15 bits\n            $password\t\t^= ($value | $rotated_bits);\n        }\n\n        $password ^= strlen($pPassword);\n        $password ^= 0xCE4B;\n\n        return(strtoupper(dechex($password)));\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/String.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Shared_String\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_String\n{\n\t/**\tConstants\t\t\t\t*/\n\t/**\tRegular Expressions\t\t*/\n\t//\tFraction\n\tconst STRING_REGEXP_FRACTION\t= '(-?)(\\d+)\\s+(\\d+\\/\\d+)';\n\n\n\t/**\n\t * Control characters array\n\t *\n\t * @var string[]\n\t */\n\tprivate static $_controlCharacters = array();\n\n\t/**\n\t * SYLK Characters array\n\t *\n\t * $var array\n\t */\n\tprivate static $_SYLKCharacters = array();\n\n\t/**\n\t * Decimal separator\n\t *\n\t * @var string\n\t */\n\tprivate static $_decimalSeparator;\n\n\t/**\n\t * Thousands separator\n\t *\n\t * @var string\n\t */\n\tprivate static $_thousandsSeparator;\n\n\t/**\n\t * Currency code\n\t *\n\t * @var string\n\t */\n\tprivate static $_currencyCode;\n\n\t/**\n\t * Is mbstring extension avalable?\n\t *\n\t * @var boolean\n\t */\n\tprivate static $_isMbstringEnabled;\n\n\t/**\n\t * Is iconv extension avalable?\n\t *\n\t * @var boolean\n\t */\n\tprivate static $_isIconvEnabled;\n\n\t/**\n\t * Build control characters array\n\t */\n\tprivate static function _buildControlCharacters() {\n\t\tfor ($i = 0; $i <= 31; ++$i) {\n\t\t\tif ($i != 9 && $i != 10 && $i != 13) {\n\t\t\t\t$find = '_x' . sprintf('%04s' , strtoupper(dechex($i))) . '_';\n\t\t\t\t$replace = chr($i);\n\t\t\t\tself::$_controlCharacters[$find] = $replace;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Build SYLK characters array\n\t */\n\tprivate static function _buildSYLKCharacters()\n\t{\n\t\tself::$_SYLKCharacters = array(\n\t\t\t\"\\x1B 0\"  => chr(0),\n\t\t\t\"\\x1B 1\"  => chr(1),\n\t\t\t\"\\x1B 2\"  => chr(2),\n\t\t\t\"\\x1B 3\"  => chr(3),\n\t\t\t\"\\x1B 4\"  => chr(4),\n\t\t\t\"\\x1B 5\"  => chr(5),\n\t\t\t\"\\x1B 6\"  => chr(6),\n\t\t\t\"\\x1B 7\"  => chr(7),\n\t\t\t\"\\x1B 8\"  => chr(8),\n\t\t\t\"\\x1B 9\"  => chr(9),\n\t\t\t\"\\x1B :\"  => chr(10),\n\t\t\t\"\\x1B ;\"  => chr(11),\n\t\t\t\"\\x1B <\"  => chr(12),\n\t\t\t\"\\x1B :\"  => chr(13),\n\t\t\t\"\\x1B >\"  => chr(14),\n\t\t\t\"\\x1B ?\"  => chr(15),\n\t\t\t\"\\x1B!0\"  => chr(16),\n\t\t\t\"\\x1B!1\"  => chr(17),\n\t\t\t\"\\x1B!2\"  => chr(18),\n\t\t\t\"\\x1B!3\"  => chr(19),\n\t\t\t\"\\x1B!4\"  => chr(20),\n\t\t\t\"\\x1B!5\"  => chr(21),\n\t\t\t\"\\x1B!6\"  => chr(22),\n\t\t\t\"\\x1B!7\"  => chr(23),\n\t\t\t\"\\x1B!8\"  => chr(24),\n\t\t\t\"\\x1B!9\"  => chr(25),\n\t\t\t\"\\x1B!:\"  => chr(26),\n\t\t\t\"\\x1B!;\"  => chr(27),\n\t\t\t\"\\x1B!<\"  => chr(28),\n\t\t\t\"\\x1B!=\"  => chr(29),\n\t\t\t\"\\x1B!>\"  => chr(30),\n\t\t\t\"\\x1B!?\"  => chr(31),\n\t\t\t\"\\x1B'?\"  => chr(127),\n\t\t\t\"\\x1B(0\"  => '€', // 128 in CP1252\n\t\t\t\"\\x1B(2\"  => '‚', // 130 in CP1252\n\t\t\t\"\\x1B(3\"  => 'ƒ', // 131 in CP1252\n\t\t\t\"\\x1B(4\"  => '„', // 132 in CP1252\n\t\t\t\"\\x1B(5\"  => '…', // 133 in CP1252\n\t\t\t\"\\x1B(6\"  => '†', // 134 in CP1252\n\t\t\t\"\\x1B(7\"  => '‡', // 135 in CP1252\n\t\t\t\"\\x1B(8\"  => 'ˆ', // 136 in CP1252\n\t\t\t\"\\x1B(9\"  => '‰', // 137 in CP1252\n\t\t\t\"\\x1B(:\"  => 'Š', // 138 in CP1252\n\t\t\t\"\\x1B(;\"  => '‹', // 139 in CP1252\n\t\t\t\"\\x1BNj\"  => 'Œ', // 140 in CP1252\n\t\t\t\"\\x1B(>\"  => 'Ž', // 142 in CP1252\n\t\t\t\"\\x1B)1\"  => '‘', // 145 in CP1252\n\t\t\t\"\\x1B)2\"  => '’', // 146 in CP1252\n\t\t\t\"\\x1B)3\"  => '“', // 147 in CP1252\n\t\t\t\"\\x1B)4\"  => '”', // 148 in CP1252\n\t\t\t\"\\x1B)5\"  => '•', // 149 in CP1252\n\t\t\t\"\\x1B)6\"  => '–', // 150 in CP1252\n\t\t\t\"\\x1B)7\"  => '—', // 151 in CP1252\n\t\t\t\"\\x1B)8\"  => '˜', // 152 in CP1252\n\t\t\t\"\\x1B)9\"  => '™', // 153 in CP1252\n\t\t\t\"\\x1B):\"  => 'š', // 154 in CP1252\n\t\t\t\"\\x1B);\"  => '›', // 155 in CP1252\n\t\t\t\"\\x1BNz\"  => 'œ', // 156 in CP1252\n\t\t\t\"\\x1B)>\"  => 'ž', // 158 in CP1252\n\t\t\t\"\\x1B)?\"  => 'Ÿ', // 159 in CP1252\n\t\t\t\"\\x1B*0\"  => ' ', // 160 in CP1252\n\t\t\t\"\\x1BN!\"  => '¡', // 161 in CP1252\n\t\t\t\"\\x1BN\\\"\" => '¢', // 162 in CP1252\n\t\t\t\"\\x1BN#\"  => '£', // 163 in CP1252\n\t\t\t\"\\x1BN(\"  => '¤', // 164 in CP1252\n\t\t\t\"\\x1BN%\"  => '¥', // 165 in CP1252\n\t\t\t\"\\x1B*6\"  => '¦', // 166 in CP1252\n\t\t\t\"\\x1BN'\"  => '§', // 167 in CP1252\n\t\t\t\"\\x1BNH \" => '¨', // 168 in CP1252\n\t\t\t\"\\x1BNS\"  => '©', // 169 in CP1252\n\t\t\t\"\\x1BNc\"  => 'ª', // 170 in CP1252\n\t\t\t\"\\x1BN+\"  => '«', // 171 in CP1252\n\t\t\t\"\\x1B*<\"  => '¬', // 172 in CP1252\n\t\t\t\"\\x1B*=\"  => '­', // 173 in CP1252\n\t\t\t\"\\x1BNR\"  => '®', // 174 in CP1252\n\t\t\t\"\\x1B*?\"  => '¯', // 175 in CP1252\n\t\t\t\"\\x1BN0\"  => '°', // 176 in CP1252\n\t\t\t\"\\x1BN1\"  => '±', // 177 in CP1252\n\t\t\t\"\\x1BN2\"  => '²', // 178 in CP1252\n\t\t\t\"\\x1BN3\"  => '³', // 179 in CP1252\n\t\t\t\"\\x1BNB \" => '´', // 180 in CP1252\n\t\t\t\"\\x1BN5\"  => 'µ', // 181 in CP1252\n\t\t\t\"\\x1BN6\"  => '¶', // 182 in CP1252\n\t\t\t\"\\x1BN7\"  => '·', // 183 in CP1252\n\t\t\t\"\\x1B+8\"  => '¸', // 184 in CP1252\n\t\t\t\"\\x1BNQ\"  => '¹', // 185 in CP1252\n\t\t\t\"\\x1BNk\"  => 'º', // 186 in CP1252\n\t\t\t\"\\x1BN;\"  => '»', // 187 in CP1252\n\t\t\t\"\\x1BN<\"  => '¼', // 188 in CP1252\n\t\t\t\"\\x1BN=\"  => '½', // 189 in CP1252\n\t\t\t\"\\x1BN>\"  => '¾', // 190 in CP1252\n\t\t\t\"\\x1BN?\"  => '¿', // 191 in CP1252\n\t\t\t\"\\x1BNAA\" => 'À', // 192 in CP1252\n\t\t\t\"\\x1BNBA\" => 'Á', // 193 in CP1252\n\t\t\t\"\\x1BNCA\" => 'Â', // 194 in CP1252\n\t\t\t\"\\x1BNDA\" => 'Ã', // 195 in CP1252\n\t\t\t\"\\x1BNHA\" => 'Ä', // 196 in CP1252\n\t\t\t\"\\x1BNJA\" => 'Å', // 197 in CP1252\n\t\t\t\"\\x1BNa\"  => 'Æ', // 198 in CP1252\n\t\t\t\"\\x1BNKC\" => 'Ç', // 199 in CP1252\n\t\t\t\"\\x1BNAE\" => 'È', // 200 in CP1252\n\t\t\t\"\\x1BNBE\" => 'É', // 201 in CP1252\n\t\t\t\"\\x1BNCE\" => 'Ê', // 202 in CP1252\n\t\t\t\"\\x1BNHE\" => 'Ë', // 203 in CP1252\n\t\t\t\"\\x1BNAI\" => 'Ì', // 204 in CP1252\n\t\t\t\"\\x1BNBI\" => 'Í', // 205 in CP1252\n\t\t\t\"\\x1BNCI\" => 'Î', // 206 in CP1252\n\t\t\t\"\\x1BNHI\" => 'Ï', // 207 in CP1252\n\t\t\t\"\\x1BNb\"  => 'Ð', // 208 in CP1252\n\t\t\t\"\\x1BNDN\" => 'Ñ', // 209 in CP1252\n\t\t\t\"\\x1BNAO\" => 'Ò', // 210 in CP1252\n\t\t\t\"\\x1BNBO\" => 'Ó', // 211 in CP1252\n\t\t\t\"\\x1BNCO\" => 'Ô', // 212 in CP1252\n\t\t\t\"\\x1BNDO\" => 'Õ', // 213 in CP1252\n\t\t\t\"\\x1BNHO\" => 'Ö', // 214 in CP1252\n\t\t\t\"\\x1B-7\"  => '×', // 215 in CP1252\n\t\t\t\"\\x1BNi\"  => 'Ø', // 216 in CP1252\n\t\t\t\"\\x1BNAU\" => 'Ù', // 217 in CP1252\n\t\t\t\"\\x1BNBU\" => 'Ú', // 218 in CP1252\n\t\t\t\"\\x1BNCU\" => 'Û', // 219 in CP1252\n\t\t\t\"\\x1BNHU\" => 'Ü', // 220 in CP1252\n\t\t\t\"\\x1B-=\"  => 'Ý', // 221 in CP1252\n\t\t\t\"\\x1BNl\"  => 'Þ', // 222 in CP1252\n\t\t\t\"\\x1BN{\"  => 'ß', // 223 in CP1252\n\t\t\t\"\\x1BNAa\" => 'à', // 224 in CP1252\n\t\t\t\"\\x1BNBa\" => 'á', // 225 in CP1252\n\t\t\t\"\\x1BNCa\" => 'â', // 226 in CP1252\n\t\t\t\"\\x1BNDa\" => 'ã', // 227 in CP1252\n\t\t\t\"\\x1BNHa\" => 'ä', // 228 in CP1252\n\t\t\t\"\\x1BNJa\" => 'å', // 229 in CP1252\n\t\t\t\"\\x1BNq\"  => 'æ', // 230 in CP1252\n\t\t\t\"\\x1BNKc\" => 'ç', // 231 in CP1252\n\t\t\t\"\\x1BNAe\" => 'è', // 232 in CP1252\n\t\t\t\"\\x1BNBe\" => 'é', // 233 in CP1252\n\t\t\t\"\\x1BNCe\" => 'ê', // 234 in CP1252\n\t\t\t\"\\x1BNHe\" => 'ë', // 235 in CP1252\n\t\t\t\"\\x1BNAi\" => 'ì', // 236 in CP1252\n\t\t\t\"\\x1BNBi\" => 'í', // 237 in CP1252\n\t\t\t\"\\x1BNCi\" => 'î', // 238 in CP1252\n\t\t\t\"\\x1BNHi\" => 'ï', // 239 in CP1252\n\t\t\t\"\\x1BNs\"  => 'ð', // 240 in CP1252\n\t\t\t\"\\x1BNDn\" => 'ñ', // 241 in CP1252\n\t\t\t\"\\x1BNAo\" => 'ò', // 242 in CP1252\n\t\t\t\"\\x1BNBo\" => 'ó', // 243 in CP1252\n\t\t\t\"\\x1BNCo\" => 'ô', // 244 in CP1252\n\t\t\t\"\\x1BNDo\" => 'õ', // 245 in CP1252\n\t\t\t\"\\x1BNHo\" => 'ö', // 246 in CP1252\n\t\t\t\"\\x1B/7\"  => '÷', // 247 in CP1252\n\t\t\t\"\\x1BNy\"  => 'ø', // 248 in CP1252\n\t\t\t\"\\x1BNAu\" => 'ù', // 249 in CP1252\n\t\t\t\"\\x1BNBu\" => 'ú', // 250 in CP1252\n\t\t\t\"\\x1BNCu\" => 'û', // 251 in CP1252\n\t\t\t\"\\x1BNHu\" => 'ü', // 252 in CP1252\n\t\t\t\"\\x1B/=\"  => 'ý', // 253 in CP1252\n\t\t\t\"\\x1BN|\"  => 'þ', // 254 in CP1252\n\t\t\t\"\\x1BNHy\" => 'ÿ', // 255 in CP1252\n\t\t);\n\t}\n\n\t/**\n\t * Get whether mbstring extension is available\n\t *\n\t * @return boolean\n\t */\n\tpublic static function getIsMbstringEnabled()\n\t{\n\t\tif (isset(self::$_isMbstringEnabled)) {\n\t\t\treturn self::$_isMbstringEnabled;\n\t\t}\n\n\t\tself::$_isMbstringEnabled = function_exists('mb_convert_encoding') ?\n\t\t\ttrue : false;\n\n\t\treturn self::$_isMbstringEnabled;\n\t}\n\n\t/**\n\t * Get whether iconv extension is available\n\t *\n\t * @return boolean\n\t */\n\tpublic static function getIsIconvEnabled()\n\t{\n\t\tif (isset(self::$_isIconvEnabled)) {\n\t\t\treturn self::$_isIconvEnabled;\n\t\t}\n\n\t\t// Fail if iconv doesn't exist\n\t\tif (!function_exists('iconv')) {\n\t\t\tself::$_isIconvEnabled = false;\n\t\t\treturn false;\n\t\t}\n\n\t\t// Sometimes iconv is not working, and e.g. iconv('UTF-8', 'UTF-16LE', 'x') just returns false,\n\t\tif (!@iconv('UTF-8', 'UTF-16LE', 'x')) {\n\t\t\tself::$_isIconvEnabled = false;\n\t\t\treturn false;\n\t\t}\n\n\t\t// Sometimes iconv_substr('A', 0, 1, 'UTF-8') just returns false in PHP 5.2.0\n\t\t// we cannot use iconv in that case either (http://bugs.php.net/bug.php?id=37773)\n\t\tif (!@iconv_substr('A', 0, 1, 'UTF-8')) {\n\t\t\tself::$_isIconvEnabled = false;\n\t\t\treturn false;\n\t\t}\n\n\t\t// CUSTOM: IBM AIX iconv() does not work\n\t\tif ( defined('PHP_OS') && @stristr(PHP_OS, 'AIX')\n\t\t\t\t&& defined('ICONV_IMPL') && (@strcasecmp(ICONV_IMPL, 'unknown') == 0)\n\t\t\t\t&& defined('ICONV_VERSION') && (@strcasecmp(ICONV_VERSION, 'unknown') == 0) )\n\t\t{\n\t\t\tself::$_isIconvEnabled = false;\n\t\t\treturn false;\n\t\t}\n\n\t\t// If we reach here no problems were detected with iconv\n\t\tself::$_isIconvEnabled = true;\n\t\treturn true;\n\t}\n\n\tpublic static function buildCharacterSets() {\n\t\tif(empty(self::$_controlCharacters)) {\n\t\t\tself::_buildControlCharacters();\n\t\t}\n\t\tif(empty(self::$_SYLKCharacters)) {\n\t\t\tself::_buildSYLKCharacters();\n\t\t}\n\t}\n\n\t/**\n\t * Convert from OpenXML escaped control character to PHP control character\n\t *\n\t * Excel 2007 team:\n\t * ----------------\n\t * That's correct, control characters are stored directly in the shared-strings table.\n\t * We do encode characters that cannot be represented in XML using the following escape sequence:\n\t * _xHHHH_ where H represents a hexadecimal character in the character's value...\n\t * So you could end up with something like _x0008_ in a string (either in a cell value (<v>)\n\t * element or in the shared string <t> element.\n\t *\n\t * @param \tstring\t$value\tValue to unescape\n\t * @return \tstring\n\t */\n\tpublic static function ControlCharacterOOXML2PHP($value = '') {\n\t\treturn str_replace( array_keys(self::$_controlCharacters), array_values(self::$_controlCharacters), $value );\n\t}\n\n\t/**\n\t * Convert from PHP control character to OpenXML escaped control character\n\t *\n\t * Excel 2007 team:\n\t * ----------------\n\t * That's correct, control characters are stored directly in the shared-strings table.\n\t * We do encode characters that cannot be represented in XML using the following escape sequence:\n\t * _xHHHH_ where H represents a hexadecimal character in the character's value...\n\t * So you could end up with something like _x0008_ in a string (either in a cell value (<v>)\n\t * element or in the shared string <t> element.\n\t *\n\t * @param \tstring\t$value\tValue to escape\n\t * @return \tstring\n\t */\n\tpublic static function ControlCharacterPHP2OOXML($value = '') {\n\t\treturn str_replace( array_values(self::$_controlCharacters), array_keys(self::$_controlCharacters), $value );\n\t}\n\n\t/**\n\t * Try to sanitize UTF8, stripping invalid byte sequences. Not perfect. Does not surrogate characters.\n\t *\n\t * @param string $value\n\t * @return string\n\t */\n\tpublic static function SanitizeUTF8($value)\n\t{\n\t\tif (self::getIsIconvEnabled()) {\n\t\t\t$value = @iconv('UTF-8', 'UTF-8', $value);\n\t\t\treturn $value;\n\t\t}\n\n\t\tif (self::getIsMbstringEnabled()) {\n\t\t\t$value = mb_convert_encoding($value, 'UTF-8', 'UTF-8');\n\t\t\treturn $value;\n\t\t}\n\n\t\t// else, no conversion\n\t\treturn $value;\n\t}\n\n\t/**\n\t * Check if a string contains UTF8 data\n\t *\n\t * @param string $value\n\t * @return boolean\n\t */\n\tpublic static function IsUTF8($value = '') {\n\t\treturn $value === '' || preg_match('/^./su', $value) === 1;\n\t}\n\n\t/**\n\t * Formats a numeric value as a string for output in various output writers forcing\n\t * point as decimal separator in case locale is other than English.\n\t *\n\t * @param mixed $value\n\t * @return string\n\t */\n\tpublic static function FormatNumber($value) {\n\t\tif (is_float($value)) {\n\t\t\treturn str_replace(',', '.', $value);\n\t\t}\n\t\treturn (string) $value;\n\t}\n\n\t/**\n\t * Converts a UTF-8 string into BIFF8 Unicode string data (8-bit string length)\n\t * Writes the string using uncompressed notation, no rich text, no Asian phonetics\n\t * If mbstring extension is not available, ASCII is assumed, and compressed notation is used\n\t * although this will give wrong results for non-ASCII strings\n\t * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3\n\t *\n\t * @param string  $value    UTF-8 encoded string\n\t * @param mixed[] $arrcRuns Details of rich text runs in $value\n\t * @return string\n\t */\n\tpublic static function UTF8toBIFF8UnicodeShort($value, $arrcRuns = array())\n\t{\n\t\t// character count\n\t\t$ln = self::CountCharacters($value, 'UTF-8');\n\t\t// option flags\n\t\tif(empty($arrcRuns)){\n\t\t\t$opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ?\n\t\t\t\t0x0001 : 0x0000;\n\t\t\t$data = pack('CC', $ln, $opt);\n\t\t\t// characters\n\t\t\t$data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8');\n\t\t}\n\t\telse {\n\t\t\t$data = pack('vC', $ln, 0x09);\n\t\t\t$data .= pack('v', count($arrcRuns));\n\t\t\t// characters\n\t\t\t$data .= self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8');\n\t\t\tforeach ($arrcRuns as $cRun){\n\t\t\t\t$data .= pack('v', $cRun['strlen']);\n\t\t\t\t$data .= pack('v', $cRun['fontidx']);\n\t\t\t}\n\t\t}\n\t\treturn $data;\n\t}\n\n\t/**\n\t * Converts a UTF-8 string into BIFF8 Unicode string data (16-bit string length)\n\t * Writes the string using uncompressed notation, no rich text, no Asian phonetics\n\t * If mbstring extension is not available, ASCII is assumed, and compressed notation is used\n\t * although this will give wrong results for non-ASCII strings\n\t * see OpenOffice.org's Documentation of the Microsoft Excel File Format, sect. 2.5.3\n\t *\n\t * @param string $value UTF-8 encoded string\n\t * @return string\n\t */\n\tpublic static function UTF8toBIFF8UnicodeLong($value)\n\t{\n\t\t// character count\n\t\t$ln = self::CountCharacters($value, 'UTF-8');\n\n\t\t// option flags\n\t\t$opt = (self::getIsIconvEnabled() || self::getIsMbstringEnabled()) ?\n\t\t\t0x0001 : 0x0000;\n\n\t\t// characters\n\t\t$chars = self::ConvertEncoding($value, 'UTF-16LE', 'UTF-8');\n\n\t\t$data = pack('vC', $ln, $opt) . $chars;\n\t\treturn $data;\n\t}\n\n\t/**\n\t * Convert string from one encoding to another. First try mbstring, then iconv, finally strlen\n\t *\n\t * @param string $value\n\t * @param string $to Encoding to convert to, e.g. 'UTF-8'\n\t * @param string $from Encoding to convert from, e.g. 'UTF-16LE'\n\t * @return string\n\t */\n\tpublic static function ConvertEncoding($value, $to, $from)\n\t{\n\t\tif (self::getIsIconvEnabled()) {\n\t\t\treturn iconv($from, $to, $value);\n\t\t}\n\n\t\tif (self::getIsMbstringEnabled()) {\n\t\t\treturn mb_convert_encoding($value, $to, $from);\n\t\t}\n\n\t\tif($from == 'UTF-16LE'){\n\t\t\treturn self::utf16_decode($value, false);\n\t\t}else if($from == 'UTF-16BE'){\n\t\t\treturn self::utf16_decode($value);\n\t\t}\n\t\t// else, no conversion\n\t\treturn $value;\n\t}\n\n\t/**\n\t * Decode UTF-16 encoded strings.\n\t *\n\t * Can handle both BOM'ed data and un-BOM'ed data.\n\t * Assumes Big-Endian byte order if no BOM is available.\n\t * This function was taken from http://php.net/manual/en/function.utf8-decode.php\n\t * and $bom_be parameter added.\n\t *\n\t * @param   string  $str  UTF-16 encoded data to decode.\n\t * @return  string  UTF-8 / ISO encoded data.\n\t * @access  public\n\t * @version 0.2 / 2010-05-13\n\t * @author  Rasmus Andersson {@link http://rasmusandersson.se/}\n\t * @author vadik56\n\t */\n\tpublic static function utf16_decode($str, $bom_be = TRUE) {\n\t\tif( strlen($str) < 2 ) return $str;\n\t\t$c0 = ord($str{0});\n\t\t$c1 = ord($str{1});\n\t\tif( $c0 == 0xfe && $c1 == 0xff ) { $str = substr($str,2); }\n\t\telseif( $c0 == 0xff && $c1 == 0xfe ) { $str = substr($str,2); $bom_be = false; }\n\t\t$len = strlen($str);\n\t\t$newstr = '';\n\t\tfor($i=0;$i<$len;$i+=2) {\n\t\t\tif( $bom_be ) { $val = ord($str{$i})   << 4; $val += ord($str{$i+1}); }\n\t\t\telse {        $val = ord($str{$i+1}) << 4; $val += ord($str{$i}); }\n\t\t\t$newstr .= ($val == 0x228) ? \"\\n\" : chr($val);\n\t\t}\n\t\treturn $newstr;\n\t}\n\n\t/**\n\t * Get character count. First try mbstring, then iconv, finally strlen\n\t *\n\t * @param string $value\n\t * @param string $enc Encoding\n\t * @return int Character count\n\t */\n\tpublic static function CountCharacters($value, $enc = 'UTF-8')\n\t{\n\t\tif (self::getIsMbstringEnabled()) {\n\t\t\treturn mb_strlen($value, $enc);\n\t\t}\n\n\t\tif (self::getIsIconvEnabled()) {\n\t\t\treturn iconv_strlen($value, $enc);\n\t\t}\n\n\t\t// else strlen\n\t\treturn strlen($value);\n\t}\n\n\t/**\n\t * Get a substring of a UTF-8 encoded string. First try mbstring, then iconv, finally strlen\n\t *\n\t * @param string $pValue UTF-8 encoded string\n\t * @param int $pStart Start offset\n\t * @param int $pLength Maximum number of characters in substring\n\t * @return string\n\t */\n\tpublic static function Substring($pValue = '', $pStart = 0, $pLength = 0)\n\t{\n\t\tif (self::getIsMbstringEnabled()) {\n\t\t\treturn mb_substr($pValue, $pStart, $pLength, 'UTF-8');\n\t\t}\n\n\t\tif (self::getIsIconvEnabled()) {\n\t\t\treturn iconv_substr($pValue, $pStart, $pLength, 'UTF-8');\n\t\t}\n\n\t\t// else substr\n\t\treturn substr($pValue, $pStart, $pLength);\n\t}\n\n\t/**\n\t * Convert a UTF-8 encoded string to upper case\n\t *\n\t * @param string $pValue UTF-8 encoded string\n\t * @return string\n\t */\n\tpublic static function StrToUpper($pValue = '')\n\t{\n\t\tif (function_exists('mb_convert_case')) {\n\t\t\treturn mb_convert_case($pValue, MB_CASE_UPPER, \"UTF-8\");\n\t\t}\n\t\treturn strtoupper($pValue);\n\t}\n\n\t/**\n\t * Convert a UTF-8 encoded string to lower case\n\t *\n\t * @param string $pValue UTF-8 encoded string\n\t * @return string\n\t */\n\tpublic static function StrToLower($pValue = '')\n\t{\n\t\tif (function_exists('mb_convert_case')) {\n\t\t\treturn mb_convert_case($pValue, MB_CASE_LOWER, \"UTF-8\");\n\t\t}\n\t\treturn strtolower($pValue);\n\t}\n\n\t/**\n\t * Convert a UTF-8 encoded string to title/proper case\n\t *    (uppercase every first character in each word, lower case all other characters)\n\t *\n\t * @param string $pValue UTF-8 encoded string\n\t * @return string\n\t */\n\tpublic static function StrToTitle($pValue = '')\n\t{\n\t\tif (function_exists('mb_convert_case')) {\n\t\t\treturn mb_convert_case($pValue, MB_CASE_TITLE, \"UTF-8\");\n\t\t}\n\t\treturn ucwords($pValue);\n\t}\n\n    public static function mb_is_upper($char)\n    {\n        return mb_strtolower($char, \"UTF-8\") != $char;\n    }\n\n    public static function mb_str_split($string)\n    {\n        # Split at all position not after the start: ^\n        # and not before the end: $\n        return preg_split('/(?<!^)(?!$)/u', $string );\n    }\n\n\t/**\n\t * Reverse the case of a string, so that all uppercase characters become lowercase\n     *    and all lowercase characters become uppercase\n\t *\n\t * @param string $pValue UTF-8 encoded string\n\t * @return string\n\t */\n\tpublic static function StrCaseReverse($pValue = '')\n\t{\n        if (self::getIsMbstringEnabled()) {\n            $characters = self::mb_str_split($pValue);\n            foreach($characters as &$character) {\n                if(self::mb_is_upper($character)) {\n                    $character = mb_strtolower($character, 'UTF-8');\n                } else {\n                    $character = mb_strtoupper($character, 'UTF-8');\n                }\n            }\n            return implode('', $characters);\n\t\t}\n\t\treturn strtolower($pValue) ^ strtoupper($pValue) ^ $pValue;\n\t}\n\n\t/**\n\t * Identify whether a string contains a fractional numeric value,\n\t *    and convert it to a numeric if it is\n\t *\n\t * @param string &$operand string value to test\n\t * @return boolean\n\t */\n\tpublic static function convertToNumberIfFraction(&$operand) {\n\t\tif (preg_match('/^'.self::STRING_REGEXP_FRACTION.'$/i', $operand, $match)) {\n\t\t\t$sign = ($match[1] == '-') ? '-' : '+';\n\t\t\t$fractionFormula = '='.$sign.$match[2].$sign.$match[3];\n\t\t\t$operand = PHPExcel_Calculation::getInstance()->_calculateFormulaValue($fractionFormula);\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\t//\tfunction convertToNumberIfFraction()\n\n\t/**\n\t * Get the decimal separator. If it has not yet been set explicitly, try to obtain number\n\t * formatting information from locale.\n\t *\n\t * @return string\n\t */\n\tpublic static function getDecimalSeparator()\n\t{\n\t\tif (!isset(self::$_decimalSeparator)) {\n\t\t\t$localeconv = localeconv();\n\t\t\tself::$_decimalSeparator = ($localeconv['decimal_point'] != '')\n\t\t\t\t? $localeconv['decimal_point'] : $localeconv['mon_decimal_point'];\n\n\t\t\tif (self::$_decimalSeparator == '') {\n\t\t\t\t// Default to .\n\t\t\t\tself::$_decimalSeparator = '.';\n\t\t\t}\n\t\t}\n\t\treturn self::$_decimalSeparator;\n\t}\n\n\t/**\n\t * Set the decimal separator. Only used by PHPExcel_Style_NumberFormat::toFormattedString()\n\t * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF\n\t *\n\t * @param string $pValue Character for decimal separator\n\t */\n\tpublic static function setDecimalSeparator($pValue = '.')\n\t{\n\t\tself::$_decimalSeparator = $pValue;\n\t}\n\n\t/**\n\t * Get the thousands separator. If it has not yet been set explicitly, try to obtain number\n\t * formatting information from locale.\n\t *\n\t * @return string\n\t */\n\tpublic static function getThousandsSeparator()\n\t{\n\t\tif (!isset(self::$_thousandsSeparator)) {\n\t\t\t$localeconv = localeconv();\n\t\t\tself::$_thousandsSeparator = ($localeconv['thousands_sep'] != '')\n\t\t\t\t? $localeconv['thousands_sep'] : $localeconv['mon_thousands_sep'];\n\n\t\t\tif (self::$_thousandsSeparator == '') {\n\t\t\t\t// Default to .\n\t\t\t\tself::$_thousandsSeparator = ',';\n\t\t\t}\n\t\t}\n\t\treturn self::$_thousandsSeparator;\n\t}\n\n\t/**\n\t * Set the thousands separator. Only used by PHPExcel_Style_NumberFormat::toFormattedString()\n\t * to format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF\n\t *\n\t * @param string $pValue Character for thousands separator\n\t */\n\tpublic static function setThousandsSeparator($pValue = ',')\n\t{\n\t\tself::$_thousandsSeparator = $pValue;\n\t}\n\n\t/**\n\t *\tGet the currency code. If it has not yet been set explicitly, try to obtain the\n\t *\t\tsymbol information from locale.\n\t *\n\t * @return string\n\t */\n\tpublic static function getCurrencyCode()\n\t{\n\t\tif (!isset(self::$_currencyCode)) {\n\t\t\t$localeconv = localeconv();\n\t\t\tself::$_currencyCode = ($localeconv['currency_symbol'] != '')\n\t\t\t\t? $localeconv['currency_symbol'] : $localeconv['int_curr_symbol'];\n\n\t\t\tif (self::$_currencyCode == '') {\n\t\t\t\t// Default to $\n\t\t\t\tself::$_currencyCode = '$';\n\t\t\t}\n\t\t}\n\t\treturn self::$_currencyCode;\n\t}\n\n\t/**\n\t * Set the currency code. Only used by PHPExcel_Style_NumberFormat::toFormattedString()\n\t *\t\tto format output by PHPExcel_Writer_HTML and PHPExcel_Writer_PDF\n\t *\n\t * @param string $pValue Character for currency code\n\t */\n\tpublic static function setCurrencyCode($pValue = '$')\n\t{\n\t\tself::$_currencyCode = $pValue;\n\t}\n\n\t/**\n\t * Convert SYLK encoded string to UTF-8\n\t *\n\t * @param string $pValue\n\t * @return string UTF-8 encoded string\n\t */\n\tpublic static function SYLKtoUTF8($pValue = '')\n\t{\n\t\t// If there is no escape character in the string there is nothing to do\n\t\tif (strpos($pValue, '\u001b') === false) {\n\t\t\treturn $pValue;\n\t\t}\n\n\t\tforeach (self::$_SYLKCharacters as $k => $v) {\n\t\t\t$pValue = str_replace($k, $v, $pValue);\n\t\t}\n\n\t\treturn $pValue;\n\t}\n\n\t/**\n\t * Retrieve any leading numeric part of a string, or return the full string if no leading numeric\n\t *\t(handles basic integer or float, but not exponent or non decimal)\n\t *\n\t * @param\tstring\t$value\n\t * @return\tmixed\tstring or only the leading numeric part of the string\n\t */\n\tpublic static function testStringAsNumeric($value)\n\t{\n\t\tif (is_numeric($value))\n\t\t\treturn $value;\n\t\t$v = floatval($value);\n\t\treturn (is_numeric(substr($value, 0, strlen($v)))) ? $v : $value;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/TimeZone.php",
    "content": "<?php\n\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Shared_TimeZone\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_TimeZone\n{\n\t/*\n\t * Default Timezone used for date/time conversions\n\t *\n\t * @private\n\t * @var\tstring\n\t */\n\tprotected static $_timezone\t= 'UTC';\n\n\t/**\n\t * Validate a Timezone name\n\t *\n\t * @param\t string\t\t$timezone\t\t\tTime zone (e.g. 'Europe/London')\n\t * @return\t boolean\t\t\t\t\t\tSuccess or failure\n\t */\n\tpublic static function _validateTimeZone($timezone) {\n\t\tif (in_array($timezone, DateTimeZone::listIdentifiers())) {\n\t\t\treturn TRUE;\n\t\t}\n\t\treturn FALSE;\n\t}\n\n\t/**\n\t * Set the Default Timezone used for date/time conversions\n\t *\n\t * @param\t string\t\t$timezone\t\t\tTime zone (e.g. 'Europe/London')\n\t * @return\t boolean\t\t\t\t\t\tSuccess or failure\n\t */\n\tpublic static function setTimeZone($timezone) {\n\t\tif (self::_validateTimezone($timezone)) {\n\t\t\tself::$_timezone = $timezone;\n\t\t\treturn TRUE;\n\t\t}\n\t\treturn FALSE;\n\t}\t//\tfunction setTimezone()\n\n\n\t/**\n\t * Return the Default Timezone used for date/time conversions\n\t *\n\t * @return\t string\t\tTimezone (e.g. 'Europe/London')\n\t */\n\tpublic static function getTimeZone() {\n\t\treturn self::$_timezone;\n\t}\t//\tfunction getTimezone()\n\n\n\t/**\n\t *\tReturn the Timezone transition for the specified timezone and timestamp\n\t *\n\t *\t@param\t\tDateTimeZone\t \t$objTimezone\tThe timezone for finding the transitions\n\t *\t@param\t\tinteger\t \t\t\t$timestamp\t\tPHP date/time value for finding the current transition\n\t *\t@return\t \tarray\t\t\t\tThe current transition details\n\t */\n\tprivate static function _getTimezoneTransitions($objTimezone, $timestamp) {\n\t\t$allTransitions = $objTimezone->getTransitions();\n\t\t$transitions = array();\n\t\tforeach($allTransitions as $key => $transition) {\n\t\t\tif ($transition['ts'] > $timestamp) {\n\t\t\t\t$transitions[] = ($key > 0) ? $allTransitions[$key - 1] : $transition;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tif (empty($transitions)) {\n\t\t\t\t$transitions[] = end($allTransitions);\n\t\t\t}\n\t\t}\n\n\t\treturn $transitions;\n\t}\n\n\t/**\n\t *\tReturn the Timezone offset used for date/time conversions to/from UST\n\t *\tThis requires both the timezone and the calculated date/time to allow for local DST\n\t *\n\t *\t@param\t\tstring\t \t\t\t$timezone\t\tThe timezone for finding the adjustment to UST\n\t *\t@param\t\tinteger\t \t\t\t$timestamp\t\tPHP date/time value\n\t *\t@return\t \tinteger\t\t\t\tNumber of seconds for timezone adjustment\n\t *\t@throws\t\tPHPExcel_Exception\n\t */\n\tpublic static function getTimeZoneAdjustment($timezone, $timestamp) {\n\t\tif ($timezone !== NULL) {\n\t\t\tif (!self::_validateTimezone($timezone)) {\n\t\t\t\tthrow new PHPExcel_Exception(\"Invalid timezone \" . $timezone);\n\t\t\t}\n\t\t} else {\n\t\t\t$timezone = self::$_timezone;\n\t\t}\n\n\t\tif ($timezone == 'UST') {\n\t\t\treturn 0;\n\t\t}\n\n\t\t$objTimezone = new DateTimeZone($timezone);\n\t\tif (version_compare(PHP_VERSION, '5.3.0') >= 0) {\n\t\t\t$transitions = $objTimezone->getTransitions($timestamp,$timestamp);\n\t\t} else {\n\t\t\t$transitions = self::_getTimezoneTransitions($objTimezone, $timestamp);\n\t\t}\n\n\t\treturn (count($transitions) > 0) ? $transitions[0]['offset'] : 0;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/XMLWriter.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\nif (!defined('DATE_W3C')) {\n  define('DATE_W3C', 'Y-m-d\\TH:i:sP');\n}\n\nif (!defined('DEBUGMODE_ENABLED')) {\n  define('DEBUGMODE_ENABLED', false);\n}\n\n\n/**\n * PHPExcel_Shared_XMLWriter\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_XMLWriter extends XMLWriter {\n\t/** Temporary storage method */\n\tconst STORAGE_MEMORY\t= 1;\n\tconst STORAGE_DISK\t\t= 2;\n\n\t/**\n\t * Temporary filename\n\t *\n\t * @var string\n\t */\n\tprivate $_tempFileName = '';\n\n\t/**\n\t * Create a new PHPExcel_Shared_XMLWriter instance\n\t *\n\t * @param int\t\t$pTemporaryStorage\t\t\tTemporary storage location\n\t * @param string\t$pTemporaryStorageFolder\tTemporary storage folder\n\t */\n\tpublic function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTemporaryStorageFolder = NULL) {\n\t\t// Open temporary storage\n\t\tif ($pTemporaryStorage == self::STORAGE_MEMORY) {\n\t\t\t$this->openMemory();\n\t\t} else {\n\t\t\t// Create temporary filename\n\t\t\tif ($pTemporaryStorageFolder === NULL)\n\t\t\t\t$pTemporaryStorageFolder = PHPExcel_Shared_File::sys_get_temp_dir();\n\t\t\t$this->_tempFileName = @tempnam($pTemporaryStorageFolder, 'xml');\n\n\t\t\t// Open storage\n\t\t\tif ($this->openUri($this->_tempFileName) === false) {\n\t\t\t\t// Fallback to memory...\n\t\t\t\t$this->openMemory();\n\t\t\t}\n\t\t}\n\n\t\t// Set default values\n\t\tif (DEBUGMODE_ENABLED) {\n\t\t\t$this->setIndent(true);\n\t\t}\n\t}\n\n\t/**\n\t * Destructor\n\t */\n\tpublic function __destruct() {\n\t\t// Unlink temporary files\n\t\tif ($this->_tempFileName != '') {\n\t\t\t@unlink($this->_tempFileName);\n\t\t}\n\t}\n\n\t/**\n\t * Get written data\n\t *\n\t * @return $data\n\t */\n\tpublic function getData() {\n\t\tif ($this->_tempFileName == '') {\n\t\t\treturn $this->outputMemory(true);\n\t\t} else {\n\t\t\t$this->flush();\n\t\t\treturn file_get_contents($this->_tempFileName);\n\t\t}\n\t}\n\n\t/**\n\t * Fallback method for writeRaw, introduced in PHP 5.2\n\t *\n\t * @param string $text\n\t * @return string\n\t */\n\tpublic function writeRawData($text)\n\t{\n\t\tif (is_array($text)) {\n\t\t\t$text = implode(\"\\n\",$text);\n\t\t}\n\n\t\tif (method_exists($this, 'writeRaw')) {\n\t\t\treturn $this->writeRaw(htmlspecialchars($text));\n\t\t}\n\n\t\treturn $this->text($text);\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/ZipArchive.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_ZipArchive\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\nif (!defined('PCLZIP_TEMPORARY_DIR')) {\n\tdefine('PCLZIP_TEMPORARY_DIR', PHPExcel_Shared_File::sys_get_temp_dir() . DIRECTORY_SEPARATOR);\n}\nrequire_once PHPEXCEL_ROOT . 'PHPExcel/Shared/PCLZip/pclzip.lib.php';\n\n\n/**\n * PHPExcel_Shared_ZipArchive\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_ZipArchive\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_ZipArchive\n{\n\n\t/**\tconstants */\n\tconst OVERWRITE\t\t= 'OVERWRITE';\n\tconst CREATE\t\t= 'CREATE';\n\n\n\t/**\n\t * Temporary storage directory\n\t *\n\t * @var string\n\t */\n\tprivate $_tempDir;\n\n\t/**\n\t * Zip Archive Stream Handle\n\t *\n\t * @var string\n\t */\n\tprivate $_zip;\n\n\n    /**\n\t * Open a new zip archive\n\t *\n\t * @param\tstring\t$fileName\tFilename for the zip archive\n\t * @return\tboolean\n     */\n\tpublic function open($fileName)\n\t{\n\t\t$this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir();\n\n\t\t$this->_zip = new PclZip($fileName);\n\n\t\treturn true;\n\t}\n\n\n    /**\n\t * Close this zip archive\n\t *\n     */\n\tpublic function close()\n\t{\n\t}\n\n\n    /**\n\t * Add a new file to the zip archive from a string of raw data.\n\t *\n\t * @param\tstring\t$localname\t\tDirectory/Name of the file to add to the zip archive\n\t * @param\tstring\t$contents\t\tString of data to add to the zip archive\n     */\n\tpublic function addFromString($localname, $contents)\n\t{\n\t\t$filenameParts = pathinfo($localname);\n\n\t\t$handle = fopen($this->_tempDir.'/'.$filenameParts[\"basename\"], \"wb\");\n\t\tfwrite($handle, $contents);\n\t\tfclose($handle);\n\n\t\t$res = $this->_zip->add($this->_tempDir.'/'.$filenameParts[\"basename\"],\n\t\t\t\t\t\t\t\tPCLZIP_OPT_REMOVE_PATH, $this->_tempDir,\n\t\t\t\t\t\t\t\tPCLZIP_OPT_ADD_PATH, $filenameParts[\"dirname\"]\n\t\t\t\t\t\t\t   );\n\t\tif ($res == 0) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Error zipping files : \" . $this->_zip->errorInfo(true));\n\t\t}\n\n\t\tunlink($this->_tempDir.'/'.$filenameParts[\"basename\"]);\n\t}\n\n    /**\n     * Find if given fileName exist in archive (Emulate ZipArchive locateName())\n     *\n     * @param        string        $fileName        Filename for the file in zip archive\n     * @return        boolean\n     */\n    public function locateName($fileName)\n    {\n        $list = $this->_zip->listContent();\n        $listCount = count($list);\n        $list_index = -1;\n        for ($i = 0; $i < $listCount; ++$i) {\n            if (strtolower($list[$i][\"filename\"]) == strtolower($fileName) ||\n                strtolower($list[$i][\"stored_filename\"]) == strtolower($fileName)) {\n                $list_index = $i;\n                break;\n            }\n        }\n        return ($list_index > -1);\n    }\n\n    /**\n     * Extract file from archive by given fileName (Emulate ZipArchive getFromName())\n     *\n     * @param        string        $fileName        Filename for the file in zip archive\n     * @return        string  $contents        File string contents\n     */\n    public function getFromName($fileName) \n    {\n        $list = $this->_zip->listContent();\n        $listCount = count($list);\n        $list_index = -1;\n        for ($i = 0; $i < $listCount; ++$i) {\n            if (strtolower($list[$i][\"filename\"]) == strtolower($fileName) ||\n                strtolower($list[$i][\"stored_filename\"]) == strtolower($fileName)) {\n                $list_index = $i;\n                break;\n            }\n        }\n\n        $extracted = \"\";\n        if ($list_index != -1) {\n            $extracted = $this->_zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING);\n        } else {\n            $filename = substr($fileName, 1);\n            $list_index = -1;\n            for ($i = 0; $i < $listCount; ++$i) {\n                if (strtolower($list[$i][\"filename\"]) == strtolower($fileName) || \n                    strtolower($list[$i][\"stored_filename\"]) == strtolower($fileName)) {\n                    $list_index = $i;\n                    break;\n                }\n            }\n            $extracted = $this->_zip->extractByIndex($list_index, PCLZIP_OPT_EXTRACT_AS_STRING);\n        }\n        if ((is_array($extracted)) && ($extracted != 0)) {\n            $contents = $extracted[0][\"content\"];\n        }\n\n        return $contents;\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/ZipStreamWrapper.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Shared_ZipStreamWrapper\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Shared_ZipStreamWrapper {\n\t/**\n\t * Internal ZipAcrhive\n\t *\n\t * @var ZipAcrhive\n\t */\n    private $_archive;\n\n    /**\n     * Filename in ZipAcrhive\n     *\n     * @var string\n     */\n    private $_fileNameInArchive = '';\n\n    /**\n     * Position in file\n     *\n     * @var int\n     */\n    private $_position = 0;\n\n    /**\n     * Data\n     *\n     * @var mixed\n     */\n    private $_data = '';\n\n    /**\n     * Register wrapper\n     */\n    public static function register() {\n\t\t@stream_wrapper_unregister(\"zip\");\n\t\t@stream_wrapper_register(\"zip\", __CLASS__);\n    }\n\n    /**\n\t * Implements support for fopen().\n\t *\n\t * @param\tstring\t$path\t\t\tresource name including scheme, e.g.\n\t * @param\tstring\t$mode\t\t\tonly \"r\" is supported\n\t * @param\tint\t\t$options\t\tmask of STREAM_REPORT_ERRORS and STREAM_USE_PATH\n\t * @param\tstring  &$openedPath\tabsolute path of the opened stream (out parameter)\n\t * @return\tbool    true on success\n     */\n    public function stream_open($path, $mode, $options, &$opened_path) {\n        // Check for mode\n        if ($mode{0} != 'r') {\n            throw new PHPExcel_Reader_Exception('Mode ' . $mode . ' is not supported. Only read mode is supported.');\n        }\n\n\t\t$pos = strrpos($path, '#');\n\t\t$url['host'] = substr($path, 6, $pos - 6); // 6: strlen('zip://')\n\t\t$url['fragment'] = substr($path, $pos + 1);\n\n        // Open archive\n        $this->_archive = new ZipArchive();\n        $this->_archive->open($url['host']);\n\n        $this->_fileNameInArchive = $url['fragment'];\n        $this->_position = 0;\n        $this->_data = $this->_archive->getFromName( $this->_fileNameInArchive );\n\n        return true;\n    }\n\n    /**\n\t * Implements support for fstat().\n\t *\n\t * @return  boolean\n     */\n    public function statName() {\n        return $this->_fileNameInArchive;\n    }\n\n    /**\n\t * Implements support for fstat().\n\t *\n\t * @return  boolean\n     */\n    public function url_stat() {\n        return $this->statName( $this->_fileNameInArchive );\n    }\n\n    /**\n\t * Implements support for fstat().\n\t *\n\t * @return  boolean\n     */\n    public function stream_stat() {\n        return $this->_archive->statName( $this->_fileNameInArchive );\n    }\n\n    /**\n\t * Implements support for fread(), fgets() etc.\n\t *\n\t * @param   int\t\t$count\tmaximum number of bytes to read\n\t * @return  string\n     */\n    function stream_read($count) {\n        $ret = substr($this->_data, $this->_position, $count);\n        $this->_position += strlen($ret);\n        return $ret;\n    }\n\n    /**\n\t * Returns the position of the file pointer, i.e. its offset into the file\n\t * stream. Implements support for ftell().\n\t *\n\t * @return  int\n     */\n    public function stream_tell() {\n        return $this->_position;\n    }\n\n    /**\n     * EOF stream\n\t *\n\t * @return\tbool\n     */\n    public function stream_eof() {\n        return $this->_position >= strlen($this->_data);\n    }\n\n    /**\n     * Seek stream\n\t *\n\t * @param\tint\t\t$offset\tbyte offset\n\t * @param\tint\t\t$whence\tSEEK_SET, SEEK_CUR or SEEK_END\n\t * @return\tbool\n     */\n    public function stream_seek($offset, $whence) {\n        switch ($whence) {\n            case SEEK_SET:\n                if ($offset < strlen($this->_data) && $offset >= 0) {\n                     $this->_position = $offset;\n                     return true;\n                } else {\n                     return false;\n                }\n                break;\n\n            case SEEK_CUR:\n                if ($offset >= 0) {\n                     $this->_position += $offset;\n                     return true;\n                } else {\n                     return false;\n                }\n                break;\n\n            case SEEK_END:\n                if (strlen($this->_data) + $offset >= 0) {\n                     $this->_position = strlen($this->_data) + $offset;\n                     return true;\n                } else {\n                     return false;\n                }\n                break;\n\n            default:\n                return false;\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/trend/bestFitClass.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Best_Fit\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Best_Fit\n{\n\t/**\n\t * Indicator flag for a calculation error\n\t *\n\t * @var\tboolean\n\t **/\n\tprotected $_error\t\t\t\t= False;\n\n\t/**\n\t * Algorithm type to use for best-fit\n\t *\n\t * @var\tstring\n\t **/\n\tprotected $_bestFitType\t\t\t= 'undetermined';\n\n\t/**\n\t * Number of entries in the sets of x- and y-value arrays\n\t *\n\t * @var\tint\n\t **/\n\tprotected $_valueCount\t\t\t= 0;\n\n\t/**\n\t * X-value dataseries of values\n\t *\n\t * @var\tfloat[]\n\t **/\n\tprotected $_xValues\t\t\t\t= array();\n\n\t/**\n\t * Y-value dataseries of values\n\t *\n\t * @var\tfloat[]\n\t **/\n\tprotected $_yValues\t\t\t\t= array();\n\n\t/**\n\t * Flag indicating whether values should be adjusted to Y=0\n\t *\n\t * @var\tboolean\n\t **/\n\tprotected $_adjustToZero\t\t= False;\n\n\t/**\n\t * Y-value series of best-fit values\n\t *\n\t * @var\tfloat[]\n\t **/\n\tprotected $_yBestFitValues\t\t= array();\n\n\tprotected $_goodnessOfFit \t\t= 1;\n\n\tprotected $_stdevOfResiduals\t= 0;\n\n\tprotected $_covariance\t\t\t= 0;\n\n\tprotected $_correlation\t\t\t= 0;\n\n\tprotected $_SSRegression\t\t= 0;\n\n\tprotected $_SSResiduals\t\t\t= 0;\n\n\tprotected $_DFResiduals\t\t\t= 0;\n\n\tprotected $_F\t\t\t\t\t= 0;\n\n\tprotected $_slope\t\t\t\t= 0;\n\n\tprotected $_slopeSE\t\t\t\t= 0;\n\n\tprotected $_intersect\t\t\t= 0;\n\n\tprotected $_intersectSE\t\t\t= 0;\n\n\tprotected $_Xoffset\t\t\t\t= 0;\n\n\tprotected $_Yoffset\t\t\t\t= 0;\n\n\n\tpublic function getError() {\n\t\treturn $this->_error;\n\t}\t//\tfunction getBestFitType()\n\n\n\tpublic function getBestFitType() {\n\t\treturn $this->_bestFitType;\n\t}\t//\tfunction getBestFitType()\n\n\n\t/**\n\t * Return the Y-Value for a specified value of X\n\t *\n\t * @param\t float\t\t$xValue\t\t\tX-Value\n\t * @return\t float\t\t\t\t\t\tY-Value\n\t */\n\tpublic function getValueOfYForX($xValue) {\n\t\treturn False;\n\t}\t//\tfunction getValueOfYForX()\n\n\n\t/**\n\t * Return the X-Value for a specified value of Y\n\t *\n\t * @param\t float\t\t$yValue\t\t\tY-Value\n\t * @return\t float\t\t\t\t\t\tX-Value\n\t */\n\tpublic function getValueOfXForY($yValue) {\n\t\treturn False;\n\t}\t//\tfunction getValueOfXForY()\n\n\n\t/**\n\t * Return the original set of X-Values\n\t *\n\t * @return\t float[]\t\t\t\tX-Values\n\t */\n\tpublic function getXValues() {\n\t\treturn $this->_xValues;\n\t}\t//\tfunction getValueOfXForY()\n\n\n\t/**\n\t * Return the Equation of the best-fit line\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t */\n\tpublic function getEquation($dp=0) {\n\t\treturn False;\n\t}\t//\tfunction getEquation()\n\n\n\t/**\n\t * Return the Slope of the line\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t */\n\tpublic function getSlope($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round($this->_slope,$dp);\n\t\t}\n\t\treturn $this->_slope;\n\t}\t//\tfunction getSlope()\n\n\n\t/**\n\t * Return the standard error of the Slope\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t */\n\tpublic function getSlopeSE($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round($this->_slopeSE,$dp);\n\t\t}\n\t\treturn $this->_slopeSE;\n\t}\t//\tfunction getSlopeSE()\n\n\n\t/**\n\t * Return the Value of X where it intersects Y = 0\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t */\n\tpublic function getIntersect($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round($this->_intersect,$dp);\n\t\t}\n\t\treturn $this->_intersect;\n\t}\t//\tfunction getIntersect()\n\n\n\t/**\n\t * Return the standard error of the Intersect\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t */\n\tpublic function getIntersectSE($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round($this->_intersectSE,$dp);\n\t\t}\n\t\treturn $this->_intersectSE;\n\t}\t//\tfunction getIntersectSE()\n\n\n\t/**\n\t * Return the goodness of fit for this regression\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to return\n\t * @return\t float\n\t */\n\tpublic function getGoodnessOfFit($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round($this->_goodnessOfFit,$dp);\n\t\t}\n\t\treturn $this->_goodnessOfFit;\n\t}\t//\tfunction getGoodnessOfFit()\n\n\n\tpublic function getGoodnessOfFitPercent($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round($this->_goodnessOfFit * 100,$dp);\n\t\t}\n\t\treturn $this->_goodnessOfFit * 100;\n\t}\t//\tfunction getGoodnessOfFitPercent()\n\n\n\t/**\n\t * Return the standard deviation of the residuals for this regression\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to return\n\t * @return\t float\n\t */\n\tpublic function getStdevOfResiduals($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round($this->_stdevOfResiduals,$dp);\n\t\t}\n\t\treturn $this->_stdevOfResiduals;\n\t}\t//\tfunction getStdevOfResiduals()\n\n\n\tpublic function getSSRegression($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round($this->_SSRegression,$dp);\n\t\t}\n\t\treturn $this->_SSRegression;\n\t}\t//\tfunction getSSRegression()\n\n\n\tpublic function getSSResiduals($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round($this->_SSResiduals,$dp);\n\t\t}\n\t\treturn $this->_SSResiduals;\n\t}\t//\tfunction getSSResiduals()\n\n\n\tpublic function getDFResiduals($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round($this->_DFResiduals,$dp);\n\t\t}\n\t\treturn $this->_DFResiduals;\n\t}\t//\tfunction getDFResiduals()\n\n\n\tpublic function getF($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round($this->_F,$dp);\n\t\t}\n\t\treturn $this->_F;\n\t}\t//\tfunction getF()\n\n\n\tpublic function getCovariance($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round($this->_covariance,$dp);\n\t\t}\n\t\treturn $this->_covariance;\n\t}\t//\tfunction getCovariance()\n\n\n\tpublic function getCorrelation($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round($this->_correlation,$dp);\n\t\t}\n\t\treturn $this->_correlation;\n\t}\t//\tfunction getCorrelation()\n\n\n\tpublic function getYBestFitValues() {\n\t\treturn $this->_yBestFitValues;\n\t}\t//\tfunction getYBestFitValues()\n\n\n\tprotected function _calculateGoodnessOfFit($sumX,$sumY,$sumX2,$sumY2,$sumXY,$meanX,$meanY, $const) {\n\t\t$SSres = $SScov = $SScor = $SStot = $SSsex = 0.0;\n\t\tforeach($this->_xValues as $xKey => $xValue) {\n\t\t\t$bestFitY = $this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue);\n\n\t\t\t$SSres += ($this->_yValues[$xKey] - $bestFitY) * ($this->_yValues[$xKey] - $bestFitY);\n\t\t\tif ($const) {\n\t\t\t\t$SStot += ($this->_yValues[$xKey] - $meanY) * ($this->_yValues[$xKey] - $meanY);\n\t\t\t} else {\n\t\t\t\t$SStot += $this->_yValues[$xKey] * $this->_yValues[$xKey];\n\t\t\t}\n\t\t\t$SScov += ($this->_xValues[$xKey] - $meanX) * ($this->_yValues[$xKey] - $meanY);\n\t\t\tif ($const) {\n\t\t\t\t$SSsex += ($this->_xValues[$xKey] - $meanX) * ($this->_xValues[$xKey] - $meanX);\n\t\t\t} else {\n\t\t\t\t$SSsex += $this->_xValues[$xKey] * $this->_xValues[$xKey];\n\t\t\t}\n\t\t}\n\n\t\t$this->_SSResiduals = $SSres;\n\t\t$this->_DFResiduals = $this->_valueCount - 1 - $const;\n\n\t\tif ($this->_DFResiduals == 0.0) {\n\t\t\t$this->_stdevOfResiduals = 0.0;\n\t\t} else {\n\t\t\t$this->_stdevOfResiduals = sqrt($SSres / $this->_DFResiduals);\n\t\t}\n\t\tif (($SStot == 0.0) || ($SSres == $SStot)) {\n\t\t\t$this->_goodnessOfFit = 1;\n\t\t} else {\n\t\t\t$this->_goodnessOfFit = 1 - ($SSres / $SStot);\n\t\t}\n\n\t\t$this->_SSRegression = $this->_goodnessOfFit * $SStot;\n\t\t$this->_covariance = $SScov / $this->_valueCount;\n\t\t$this->_correlation = ($this->_valueCount * $sumXY - $sumX * $sumY) / sqrt(($this->_valueCount * $sumX2 - pow($sumX,2)) * ($this->_valueCount * $sumY2 - pow($sumY,2)));\n\t\t$this->_slopeSE = $this->_stdevOfResiduals / sqrt($SSsex);\n\t\t$this->_intersectSE = $this->_stdevOfResiduals * sqrt(1 / ($this->_valueCount - ($sumX * $sumX) / $sumX2));\n\t\tif ($this->_SSResiduals != 0.0) {\n\t\t\tif ($this->_DFResiduals == 0.0) {\n\t\t\t\t$this->_F = 0.0;\n\t\t\t} else {\n\t\t\t\t$this->_F = $this->_SSRegression / ($this->_SSResiduals / $this->_DFResiduals);\n\t\t\t}\n\t\t} else {\n\t\t\tif ($this->_DFResiduals == 0.0) {\n\t\t\t\t$this->_F = 0.0;\n\t\t\t} else {\n\t\t\t\t$this->_F = $this->_SSRegression / $this->_DFResiduals;\n\t\t\t}\n\t\t}\n\t}\t//\tfunction _calculateGoodnessOfFit()\n\n\n\tprotected function _leastSquareFit($yValues, $xValues, $const) {\n\t\t// calculate sums\n\t\t$x_sum = array_sum($xValues);\n\t\t$y_sum = array_sum($yValues);\n\t\t$meanX = $x_sum / $this->_valueCount;\n\t\t$meanY = $y_sum / $this->_valueCount;\n\t\t$mBase = $mDivisor = $xx_sum = $xy_sum = $yy_sum = 0.0;\n\t\tfor($i = 0; $i < $this->_valueCount; ++$i) {\n\t\t\t$xy_sum += $xValues[$i] * $yValues[$i];\n\t\t\t$xx_sum += $xValues[$i] * $xValues[$i];\n\t\t\t$yy_sum += $yValues[$i] * $yValues[$i];\n\n\t\t\tif ($const) {\n\t\t\t\t$mBase += ($xValues[$i] - $meanX) * ($yValues[$i] - $meanY);\n\t\t\t\t$mDivisor += ($xValues[$i] - $meanX) * ($xValues[$i] - $meanX);\n\t\t\t} else {\n\t\t\t\t$mBase += $xValues[$i] * $yValues[$i];\n\t\t\t\t$mDivisor += $xValues[$i] * $xValues[$i];\n\t\t\t}\n\t\t}\n\n\t\t// calculate slope\n//\t\t$this->_slope = (($this->_valueCount * $xy_sum) - ($x_sum * $y_sum)) / (($this->_valueCount * $xx_sum) - ($x_sum * $x_sum));\n\t\t$this->_slope = $mBase / $mDivisor;\n\n\t\t// calculate intersect\n//\t\t$this->_intersect = ($y_sum - ($this->_slope * $x_sum)) / $this->_valueCount;\n\t\tif ($const) {\n\t\t\t$this->_intersect = $meanY - ($this->_slope * $meanX);\n\t\t} else {\n\t\t\t$this->_intersect = 0;\n\t\t}\n\n\t\t$this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum,$meanX,$meanY,$const);\n\t}\t//\tfunction _leastSquareFit()\n\n\n\t/**\n\t * Define the regression\n\t *\n\t * @param\tfloat[]\t\t$yValues\tThe set of Y-values for this regression\n\t * @param\tfloat[]\t\t$xValues\tThe set of X-values for this regression\n\t * @param\tboolean\t\t$const\n\t */\n\tfunction __construct($yValues, $xValues=array(), $const=True) {\n\t\t//\tCalculate number of points\n\t\t$nY = count($yValues);\n\t\t$nX = count($xValues);\n\n\t\t//\tDefine X Values if necessary\n\t\tif ($nX == 0) {\n\t\t\t$xValues = range(1,$nY);\n\t\t\t$nX = $nY;\n\t\t} elseif ($nY != $nX) {\n\t\t\t//\tEnsure both arrays of points are the same size\n\t\t\t$this->_error = True;\n\t\t\treturn False;\n\t\t}\n\n\t\t$this->_valueCount = $nY;\n\t\t$this->_xValues = $xValues;\n\t\t$this->_yValues = $yValues;\n\t}\t//\tfunction __construct()\n\n}\t//\tclass bestFit\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/trend/exponentialBestFitClass.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\nrequire_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php');\n\n\n/**\n * PHPExcel_Exponential_Best_Fit\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Exponential_Best_Fit extends PHPExcel_Best_Fit\n{\n\t/**\n\t * Algorithm type to use for best-fit\n\t * (Name of this trend class)\n\t *\n\t * @var\tstring\n\t **/\n\tprotected $_bestFitType\t\t= 'exponential';\n\n\n\t/**\n\t * Return the Y-Value for a specified value of X\n\t *\n\t * @param\t float\t\t$xValue\t\t\tX-Value\n\t * @return\t float\t\t\t\t\t\tY-Value\n\t **/\n\tpublic function getValueOfYForX($xValue) {\n\t\treturn $this->getIntersect() * pow($this->getSlope(),($xValue - $this->_Xoffset));\n\t}\t//\tfunction getValueOfYForX()\n\n\n\t/**\n\t * Return the X-Value for a specified value of Y\n\t *\n\t * @param\t float\t\t$yValue\t\t\tY-Value\n\t * @return\t float\t\t\t\t\t\tX-Value\n\t **/\n\tpublic function getValueOfXForY($yValue) {\n\t\treturn log(($yValue + $this->_Yoffset) / $this->getIntersect()) / log($this->getSlope());\n\t}\t//\tfunction getValueOfXForY()\n\n\n\t/**\n\t * Return the Equation of the best-fit line\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t **/\n\tpublic function getEquation($dp=0) {\n\t\t$slope = $this->getSlope($dp);\n\t\t$intersect = $this->getIntersect($dp);\n\n\t\treturn 'Y = '.$intersect.' * '.$slope.'^X';\n\t}\t//\tfunction getEquation()\n\n\n\t/**\n\t * Return the Slope of the line\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t **/\n\tpublic function getSlope($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round(exp($this->_slope),$dp);\n\t\t}\n\t\treturn exp($this->_slope);\n\t}\t//\tfunction getSlope()\n\n\n\t/**\n\t * Return the Value of X where it intersects Y = 0\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t **/\n\tpublic function getIntersect($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round(exp($this->_intersect),$dp);\n\t\t}\n\t\treturn exp($this->_intersect);\n\t}\t//\tfunction getIntersect()\n\n\n\t/**\n\t * Execute the regression and calculate the goodness of fit for a set of X and Y data values\n\t *\n\t * @param\t float[]\t$yValues\tThe set of Y-values for this regression\n\t * @param\t float[]\t$xValues\tThe set of X-values for this regression\n\t * @param\t boolean\t$const\n\t */\n\tprivate function _exponential_regression($yValues, $xValues, $const) {\n\t\tforeach($yValues as &$value) {\n\t\t\tif ($value < 0.0) {\n\t\t\t\t$value = 0 - log(abs($value));\n\t\t\t} elseif ($value > 0.0) {\n\t\t\t\t$value = log($value);\n\t\t\t}\n\t\t}\n\t\tunset($value);\n\n\t\t$this->_leastSquareFit($yValues, $xValues, $const);\n\t}\t//\tfunction _exponential_regression()\n\n\n\t/**\n\t * Define the regression and calculate the goodness of fit for a set of X and Y data values\n\t *\n\t * @param\tfloat[]\t\t$yValues\tThe set of Y-values for this regression\n\t * @param\tfloat[]\t\t$xValues\tThe set of X-values for this regression\n\t * @param\tboolean\t\t$const\n\t */\n\tfunction __construct($yValues, $xValues=array(), $const=True) {\n\t\tif (parent::__construct($yValues, $xValues) !== False) {\n\t\t\t$this->_exponential_regression($yValues, $xValues, $const);\n\t\t}\n\t}\t//\tfunction __construct()\n\n}\t//\tclass exponentialBestFit"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/trend/linearBestFitClass.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\nrequire_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php');\n\n\n/**\n * PHPExcel_Linear_Best_Fit\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Linear_Best_Fit extends PHPExcel_Best_Fit\n{\n\t/**\n\t * Algorithm type to use for best-fit\n\t * (Name of this trend class)\n\t *\n\t * @var\tstring\n\t **/\n\tprotected $_bestFitType\t\t= 'linear';\n\n\n\t/**\n\t * Return the Y-Value for a specified value of X\n\t *\n\t * @param\t float\t\t$xValue\t\t\tX-Value\n\t * @return\t float\t\t\t\t\t\tY-Value\n\t **/\n\tpublic function getValueOfYForX($xValue) {\n\t\treturn $this->getIntersect() + $this->getSlope() * $xValue;\n\t}\t//\tfunction getValueOfYForX()\n\n\n\t/**\n\t * Return the X-Value for a specified value of Y\n\t *\n\t * @param\t float\t\t$yValue\t\t\tY-Value\n\t * @return\t float\t\t\t\t\t\tX-Value\n\t **/\n\tpublic function getValueOfXForY($yValue) {\n\t\treturn ($yValue - $this->getIntersect()) / $this->getSlope();\n\t}\t//\tfunction getValueOfXForY()\n\n\n\t/**\n\t * Return the Equation of the best-fit line\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t **/\n\tpublic function getEquation($dp=0) {\n\t\t$slope = $this->getSlope($dp);\n\t\t$intersect = $this->getIntersect($dp);\n\n\t\treturn 'Y = '.$intersect.' + '.$slope.' * X';\n\t}\t//\tfunction getEquation()\n\n\n\t/**\n\t * Execute the regression and calculate the goodness of fit for a set of X and Y data values\n\t *\n\t * @param\t float[]\t$yValues\tThe set of Y-values for this regression\n\t * @param\t float[]\t$xValues\tThe set of X-values for this regression\n\t * @param\t boolean\t$const\n\t */\n\tprivate function _linear_regression($yValues, $xValues, $const) {\n\t\t$this->_leastSquareFit($yValues, $xValues,$const);\n\t}\t//\tfunction _linear_regression()\n\n\n\t/**\n\t * Define the regression and calculate the goodness of fit for a set of X and Y data values\n\t *\n\t * @param\tfloat[]\t\t$yValues\tThe set of Y-values for this regression\n\t * @param\tfloat[]\t\t$xValues\tThe set of X-values for this regression\n\t * @param\tboolean\t\t$const\n\t */\n\tfunction __construct($yValues, $xValues=array(), $const=True) {\n\t\tif (parent::__construct($yValues, $xValues) !== False) {\n\t\t\t$this->_linear_regression($yValues, $xValues, $const);\n\t\t}\n\t}\t//\tfunction __construct()\n\n}\t//\tclass linearBestFit"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/trend/logarithmicBestFitClass.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\nrequire_once(PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php');\n\n\n/**\n * PHPExcel_Logarithmic_Best_Fit\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Logarithmic_Best_Fit extends PHPExcel_Best_Fit\n{\n\t/**\n\t * Algorithm type to use for best-fit\n\t * (Name of this trend class)\n\t *\n\t * @var\tstring\n\t **/\n\tprotected $_bestFitType\t\t= 'logarithmic';\n\n\n\t/**\n\t * Return the Y-Value for a specified value of X\n\t *\n\t * @param\t float\t\t$xValue\t\t\tX-Value\n\t * @return\t float\t\t\t\t\t\tY-Value\n\t **/\n\tpublic function getValueOfYForX($xValue) {\n\t\treturn $this->getIntersect() + $this->getSlope() * log($xValue - $this->_Xoffset);\n\t}\t//\tfunction getValueOfYForX()\n\n\n\t/**\n\t * Return the X-Value for a specified value of Y\n\t *\n\t * @param\t float\t\t$yValue\t\t\tY-Value\n\t * @return\t float\t\t\t\t\t\tX-Value\n\t **/\n\tpublic function getValueOfXForY($yValue) {\n\t\treturn exp(($yValue - $this->getIntersect()) / $this->getSlope());\n\t}\t//\tfunction getValueOfXForY()\n\n\n\t/**\n\t * Return the Equation of the best-fit line\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t **/\n\tpublic function getEquation($dp=0) {\n\t\t$slope = $this->getSlope($dp);\n\t\t$intersect = $this->getIntersect($dp);\n\n\t\treturn 'Y = '.$intersect.' + '.$slope.' * log(X)';\n\t}\t//\tfunction getEquation()\n\n\n\t/**\n\t * Execute the regression and calculate the goodness of fit for a set of X and Y data values\n\t *\n\t * @param\t float[]\t$yValues\tThe set of Y-values for this regression\n\t * @param\t float[]\t$xValues\tThe set of X-values for this regression\n\t * @param\t boolean\t$const\n\t */\n\tprivate function _logarithmic_regression($yValues, $xValues, $const) {\n\t\tforeach($xValues as &$value) {\n\t\t\tif ($value < 0.0) {\n\t\t\t\t$value = 0 - log(abs($value));\n\t\t\t} elseif ($value > 0.0) {\n\t\t\t\t$value = log($value);\n\t\t\t}\n\t\t}\n\t\tunset($value);\n\n\t\t$this->_leastSquareFit($yValues, $xValues, $const);\n\t}\t//\tfunction _logarithmic_regression()\n\n\n\t/**\n\t * Define the regression and calculate the goodness of fit for a set of X and Y data values\n\t *\n\t * @param\tfloat[]\t\t$yValues\tThe set of Y-values for this regression\n\t * @param\tfloat[]\t\t$xValues\tThe set of X-values for this regression\n\t * @param\tboolean\t\t$const\n\t */\n\tfunction __construct($yValues, $xValues=array(), $const=True) {\n\t\tif (parent::__construct($yValues, $xValues) !== False) {\n\t\t\t$this->_logarithmic_regression($yValues, $xValues, $const);\n\t\t}\n\t}\t//\tfunction __construct()\n\n}\t//\tclass logarithmicBestFit"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/trend/polynomialBestFitClass.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\nrequire_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php';\nrequire_once PHPEXCEL_ROOT . 'PHPExcel/Shared/JAMA/Matrix.php';\n\n\n/**\n * PHPExcel_Polynomial_Best_Fit\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Polynomial_Best_Fit extends PHPExcel_Best_Fit\n{\n\t/**\n\t * Algorithm type to use for best-fit\n\t * (Name of this trend class)\n\t *\n\t * @var\tstring\n\t **/\n\tprotected $_bestFitType\t\t= 'polynomial';\n\n\t/**\n\t * Polynomial order\n\t *\n\t * @protected\n\t * @var\tint\n\t **/\n\tprotected $_order\t\t\t= 0;\n\n\n\t/**\n\t * Return the order of this polynomial\n\t *\n\t * @return\t int\n\t **/\n\tpublic function getOrder() {\n\t\treturn $this->_order;\n\t}\t//\tfunction getOrder()\n\n\n\t/**\n\t * Return the Y-Value for a specified value of X\n\t *\n\t * @param\t float\t\t$xValue\t\t\tX-Value\n\t * @return\t float\t\t\t\t\t\tY-Value\n\t **/\n\tpublic function getValueOfYForX($xValue) {\n\t\t$retVal = $this->getIntersect();\n\t\t$slope = $this->getSlope();\n\t\tforeach($slope as $key => $value) {\n\t\t\tif ($value != 0.0) {\n\t\t\t\t$retVal += $value * pow($xValue, $key + 1);\n\t\t\t}\n\t\t}\n\t\treturn $retVal;\n\t}\t//\tfunction getValueOfYForX()\n\n\n\t/**\n\t * Return the X-Value for a specified value of Y\n\t *\n\t * @param\t float\t\t$yValue\t\t\tY-Value\n\t * @return\t float\t\t\t\t\t\tX-Value\n\t **/\n\tpublic function getValueOfXForY($yValue) {\n\t\treturn ($yValue - $this->getIntersect()) / $this->getSlope();\n\t}\t//\tfunction getValueOfXForY()\n\n\n\t/**\n\t * Return the Equation of the best-fit line\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t **/\n\tpublic function getEquation($dp=0) {\n\t\t$slope = $this->getSlope($dp);\n\t\t$intersect = $this->getIntersect($dp);\n\n\t\t$equation = 'Y = '.$intersect;\n\t\tforeach($slope as $key => $value) {\n\t\t\tif ($value != 0.0) {\n\t\t\t\t$equation .= ' + '.$value.' * X';\n\t\t\t\tif ($key > 0) {\n\t\t\t\t\t$equation .= '^'.($key + 1);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn $equation;\n\t}\t//\tfunction getEquation()\n\n\n\t/**\n\t * Return the Slope of the line\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t **/\n\tpublic function getSlope($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\t$coefficients = array();\n\t\t\tforeach($this->_slope as $coefficient) {\n\t\t\t\t$coefficients[] = round($coefficient,$dp);\n\t\t\t}\n\t\t\treturn $coefficients;\n\t\t}\n\t\treturn $this->_slope;\n\t}\t//\tfunction getSlope()\n\n\n\tpublic function getCoefficients($dp=0) {\n\t\treturn array_merge(array($this->getIntersect($dp)),$this->getSlope($dp));\n\t}\t//\tfunction getCoefficients()\n\n\n\t/**\n\t * Execute the regression and calculate the goodness of fit for a set of X and Y data values\n\t *\n\t * @param\tint\t\t\t$order\t\tOrder of Polynomial for this regression\n\t * @param\tfloat[]\t\t$yValues\tThe set of Y-values for this regression\n\t * @param\tfloat[]\t\t$xValues\tThe set of X-values for this regression\n\t * @param\tboolean\t\t$const\n\t */\n\tprivate function _polynomial_regression($order, $yValues, $xValues, $const) {\n\t\t// calculate sums\n\t\t$x_sum = array_sum($xValues);\n\t\t$y_sum = array_sum($yValues);\n\t\t$xx_sum = $xy_sum = 0;\n\t\tfor($i = 0; $i < $this->_valueCount; ++$i) {\n\t\t\t$xy_sum += $xValues[$i] * $yValues[$i];\n\t\t\t$xx_sum += $xValues[$i] * $xValues[$i];\n\t\t\t$yy_sum += $yValues[$i] * $yValues[$i];\n\t\t}\n\t\t/*\n\t\t *\tThis routine uses logic from the PHP port of polyfit version 0.1\n\t\t *\twritten by Michael Bommarito and Paul Meagher\n\t\t *\n\t\t *\tThe function fits a polynomial function of order $order through\n\t\t *\ta series of x-y data points using least squares.\n\t\t *\n\t\t */\n\t\tfor ($i = 0; $i < $this->_valueCount; ++$i) {\n\t\t\tfor ($j = 0; $j <= $order; ++$j) {\n\t\t\t\t$A[$i][$j] = pow($xValues[$i], $j);\n\t\t\t}\n\t\t}\n\t\tfor ($i=0; $i < $this->_valueCount; ++$i) {\n\t\t\t$B[$i] = array($yValues[$i]);\n\t\t}\n\t\t$matrixA = new Matrix($A);\n\t\t$matrixB = new Matrix($B);\n\t\t$C = $matrixA->solve($matrixB);\n\n\t\t$coefficients = array();\n\t\tfor($i = 0; $i < $C->m; ++$i) {\n\t\t\t$r = $C->get($i, 0);\n\t\t\tif (abs($r) <= pow(10, -9)) {\n\t\t\t\t$r = 0;\n\t\t\t}\n\t\t\t$coefficients[] = $r;\n\t\t}\n\n\t\t$this->_intersect = array_shift($coefficients);\n\t\t$this->_slope = $coefficients;\n\n\t\t$this->_calculateGoodnessOfFit($x_sum,$y_sum,$xx_sum,$yy_sum,$xy_sum);\n\t\tforeach($this->_xValues as $xKey => $xValue) {\n\t\t\t$this->_yBestFitValues[$xKey] = $this->getValueOfYForX($xValue);\n\t\t}\n\t}\t//\tfunction _polynomial_regression()\n\n\n\t/**\n\t * Define the regression and calculate the goodness of fit for a set of X and Y data values\n\t *\n\t * @param\tint\t\t\t$order\t\tOrder of Polynomial for this regression\n\t * @param\tfloat[]\t\t$yValues\tThe set of Y-values for this regression\n\t * @param\tfloat[]\t\t$xValues\tThe set of X-values for this regression\n\t * @param\tboolean\t\t$const\n\t */\n\tfunction __construct($order, $yValues, $xValues=array(), $const=True) {\n\t\tif (parent::__construct($yValues, $xValues) !== False) {\n\t\t\tif ($order < $this->_valueCount) {\n\t\t\t\t$this->_bestFitType .= '_'.$order;\n\t\t\t\t$this->_order = $order;\n\t\t\t\t$this->_polynomial_regression($order, $yValues, $xValues, $const);\n\t\t\t\tif (($this->getGoodnessOfFit() < 0.0) || ($this->getGoodnessOfFit() > 1.0)) {\n\t\t\t\t\t$this->_error = True;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$this->_error = True;\n\t\t\t}\n\t\t}\n\t}\t//\tfunction __construct()\n\n}\t//\tclass polynomialBestFit"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/trend/powerBestFitClass.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\nrequire_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/bestFitClass.php';\n\n\n/**\n * PHPExcel_Power_Best_Fit\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Power_Best_Fit extends PHPExcel_Best_Fit\n{\n\t/**\n\t * Algorithm type to use for best-fit\n\t * (Name of this trend class)\n\t *\n\t * @var\tstring\n\t **/\n\tprotected $_bestFitType\t\t= 'power';\n\n\n\t/**\n\t * Return the Y-Value for a specified value of X\n\t *\n\t * @param\t float\t\t$xValue\t\t\tX-Value\n\t * @return\t float\t\t\t\t\t\tY-Value\n\t **/\n\tpublic function getValueOfYForX($xValue) {\n\t\treturn $this->getIntersect() * pow(($xValue - $this->_Xoffset),$this->getSlope());\n\t}\t//\tfunction getValueOfYForX()\n\n\n\t/**\n\t * Return the X-Value for a specified value of Y\n\t *\n\t * @param\t float\t\t$yValue\t\t\tY-Value\n\t * @return\t float\t\t\t\t\t\tX-Value\n\t **/\n\tpublic function getValueOfXForY($yValue) {\n\t\treturn pow((($yValue + $this->_Yoffset) / $this->getIntersect()),(1 / $this->getSlope()));\n\t}\t//\tfunction getValueOfXForY()\n\n\n\t/**\n\t * Return the Equation of the best-fit line\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t **/\n\tpublic function getEquation($dp=0) {\n\t\t$slope = $this->getSlope($dp);\n\t\t$intersect = $this->getIntersect($dp);\n\n\t\treturn 'Y = '.$intersect.' * X^'.$slope;\n\t}\t//\tfunction getEquation()\n\n\n\t/**\n\t * Return the Value of X where it intersects Y = 0\n\t *\n\t * @param\t int\t\t$dp\t\tNumber of places of decimal precision to display\n\t * @return\t string\n\t **/\n\tpublic function getIntersect($dp=0) {\n\t\tif ($dp != 0) {\n\t\t\treturn round(exp($this->_intersect),$dp);\n\t\t}\n\t\treturn exp($this->_intersect);\n\t}\t//\tfunction getIntersect()\n\n\n\t/**\n\t * Execute the regression and calculate the goodness of fit for a set of X and Y data values\n\t *\n\t * @param\t float[]\t$yValues\tThe set of Y-values for this regression\n\t * @param\t float[]\t$xValues\tThe set of X-values for this regression\n\t * @param\t boolean\t$const\n\t */\n\tprivate function _power_regression($yValues, $xValues, $const) {\n\t\tforeach($xValues as &$value) {\n\t\t\tif ($value < 0.0) {\n\t\t\t\t$value = 0 - log(abs($value));\n\t\t\t} elseif ($value > 0.0) {\n\t\t\t\t$value = log($value);\n\t\t\t}\n\t\t}\n\t\tunset($value);\n\t\tforeach($yValues as &$value) {\n\t\t\tif ($value < 0.0) {\n\t\t\t\t$value = 0 - log(abs($value));\n\t\t\t} elseif ($value > 0.0) {\n\t\t\t\t$value = log($value);\n\t\t\t}\n\t\t}\n\t\tunset($value);\n\n\t\t$this->_leastSquareFit($yValues, $xValues, $const);\n\t}\t//\tfunction _power_regression()\n\n\n\t/**\n\t * Define the regression and calculate the goodness of fit for a set of X and Y data values\n\t *\n\t * @param\t float[]\t$yValues\tThe set of Y-values for this regression\n\t * @param\t float[]\t$xValues\tThe set of X-values for this regression\n\t * @param\t boolean\t$const\n\t */\n\tfunction __construct($yValues, $xValues=array(), $const=True) {\n\t\tif (parent::__construct($yValues, $xValues) !== False) {\n\t\t\t$this->_power_regression($yValues, $xValues, $const);\n\t\t}\n\t}\t//\tfunction __construct()\n\n}\t//\tclass powerBestFit"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Shared/trend/trendClass.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\nrequire_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/linearBestFitClass.php';\nrequire_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/logarithmicBestFitClass.php';\nrequire_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/exponentialBestFitClass.php';\nrequire_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/powerBestFitClass.php';\nrequire_once PHPEXCEL_ROOT . 'PHPExcel/Shared/trend/polynomialBestFitClass.php';\n\n\n/**\n * PHPExcel_trendClass\n *\n * @category   PHPExcel\n * @package    PHPExcel_Shared_Trend\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass trendClass\n{\n\tconst TREND_LINEAR\t\t\t\t= 'Linear';\n\tconst TREND_LOGARITHMIC\t\t\t= 'Logarithmic';\n\tconst TREND_EXPONENTIAL\t\t\t= 'Exponential';\n\tconst TREND_POWER\t\t\t\t= 'Power';\n\tconst TREND_POLYNOMIAL_2\t\t= 'Polynomial_2';\n\tconst TREND_POLYNOMIAL_3\t\t= 'Polynomial_3';\n\tconst TREND_POLYNOMIAL_4\t\t= 'Polynomial_4';\n\tconst TREND_POLYNOMIAL_5\t\t= 'Polynomial_5';\n\tconst TREND_POLYNOMIAL_6\t\t= 'Polynomial_6';\n\tconst TREND_BEST_FIT\t\t\t= 'Bestfit';\n\tconst TREND_BEST_FIT_NO_POLY\t= 'Bestfit_no_Polynomials';\n\n\t/**\n\t * Names of the best-fit trend analysis methods\n\t *\n\t * @var string[]\n\t **/\n\tprivate static $_trendTypes = array( self::TREND_LINEAR,\n\t\t\t\t\t\t\t\t\t\t self::TREND_LOGARITHMIC,\n\t\t\t\t\t\t\t\t\t\t self::TREND_EXPONENTIAL,\n\t\t\t\t\t\t\t\t\t\t self::TREND_POWER\n\t\t\t\t\t\t\t\t\t   );\n\t/**\n\t * Names of the best-fit trend polynomial orders\n\t *\n\t * @var string[]\n\t **/\n\tprivate static $_trendTypePolyOrders = array( self::TREND_POLYNOMIAL_2,\n\t\t\t\t\t\t\t\t\t\t\t\t  self::TREND_POLYNOMIAL_3,\n\t\t\t\t\t\t\t\t\t\t\t\t  self::TREND_POLYNOMIAL_4,\n\t\t\t\t\t\t\t\t\t\t\t\t  self::TREND_POLYNOMIAL_5,\n\t\t\t\t\t\t\t\t\t\t\t\t  self::TREND_POLYNOMIAL_6\n\t\t\t\t\t\t\t\t\t\t\t    );\n\n\t/**\n\t * Cached results for each method when trying to identify which provides the best fit\n\t *\n\t * @var PHPExcel_Best_Fit[]\n\t **/\n\tprivate static $_trendCache = array();\n\n\n\tpublic static function calculate($trendType=self::TREND_BEST_FIT, $yValues, $xValues=array(), $const=True) {\n\t\t//\tCalculate number of points in each dataset\n\t\t$nY = count($yValues);\n\t\t$nX = count($xValues);\n\n\t\t//\tDefine X Values if necessary\n\t\tif ($nX == 0) {\n\t\t\t$xValues = range(1,$nY);\n\t\t\t$nX = $nY;\n\t\t} elseif ($nY != $nX) {\n\t\t\t//\tEnsure both arrays of points are the same size\n\t\t\ttrigger_error(\"trend(): Number of elements in coordinate arrays do not match.\", E_USER_ERROR);\n\t\t}\n\n\t\t$key = md5($trendType.$const.serialize($yValues).serialize($xValues));\n\t\t//\tDetermine which trend method has been requested\n\t\tswitch ($trendType) {\n\t\t\t//\tInstantiate and return the class for the requested trend method\n\t\t\tcase self::TREND_LINEAR :\n\t\t\tcase self::TREND_LOGARITHMIC :\n\t\t\tcase self::TREND_EXPONENTIAL :\n\t\t\tcase self::TREND_POWER :\n\t\t\t\tif (!isset(self::$_trendCache[$key])) {\n\t\t\t\t\t$className = 'PHPExcel_'.$trendType.'_Best_Fit';\n\t\t\t\t\tself::$_trendCache[$key] = new $className($yValues,$xValues,$const);\n\t\t\t\t}\n\t\t\t\treturn self::$_trendCache[$key];\n\t\t\t\tbreak;\n\t\t\tcase self::TREND_POLYNOMIAL_2\t:\n\t\t\tcase self::TREND_POLYNOMIAL_3\t:\n\t\t\tcase self::TREND_POLYNOMIAL_4\t:\n\t\t\tcase self::TREND_POLYNOMIAL_5\t:\n\t\t\tcase self::TREND_POLYNOMIAL_6\t:\n\t\t\t\tif (!isset(self::$_trendCache[$key])) {\n\t\t\t\t\t$order = substr($trendType,-1);\n\t\t\t\t\tself::$_trendCache[$key] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const);\n\t\t\t\t}\n\t\t\t\treturn self::$_trendCache[$key];\n\t\t\t\tbreak;\n\t\t\tcase self::TREND_BEST_FIT\t\t\t:\n\t\t\tcase self::TREND_BEST_FIT_NO_POLY\t:\n\t\t\t\t//\tIf the request is to determine the best fit regression, then we test each trend line in turn\n\t\t\t\t//\tStart by generating an instance of each available trend method\n\t\t\t\tforeach(self::$_trendTypes as $trendMethod) {\n\t\t\t\t\t$className = 'PHPExcel_'.$trendMethod.'BestFit';\n\t\t\t\t\t$bestFit[$trendMethod] = new $className($yValues,$xValues,$const);\n\t\t\t\t\t$bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit();\n\t\t\t\t}\n\t\t\t\tif ($trendType != self::TREND_BEST_FIT_NO_POLY) {\n\t\t\t\t\tforeach(self::$_trendTypePolyOrders as $trendMethod) {\n\t\t\t\t\t\t$order = substr($trendMethod,-1);\n\t\t\t\t\t\t$bestFit[$trendMethod] = new PHPExcel_Polynomial_Best_Fit($order,$yValues,$xValues,$const);\n\t\t\t\t\t\tif ($bestFit[$trendMethod]->getError()) {\n\t\t\t\t\t\t\tunset($bestFit[$trendMethod]);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$bestFitValue[$trendMethod] = $bestFit[$trendMethod]->getGoodnessOfFit();\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t//\tDetermine which of our trend lines is the best fit, and then we return the instance of that trend class\n\t\t\t\tarsort($bestFitValue);\n\t\t\t\t$bestFitType = key($bestFitValue);\n\t\t\t\treturn $bestFit[$bestFitType];\n\t\t\t\tbreak;\n\t\t\tdefault\t:\n\t\t\t\treturn false;\n\t\t}\n\t}\t//\tfunction calculate()\n\n}\t//\tclass trendClass"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Alignment.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Style_Alignment\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Style_Alignment extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable\n{\n\t/* Horizontal alignment styles */\n\tconst HORIZONTAL_GENERAL\t\t\t= 'general';\n\tconst HORIZONTAL_LEFT\t\t\t\t= 'left';\n\tconst HORIZONTAL_RIGHT\t\t\t\t= 'right';\n\tconst HORIZONTAL_CENTER\t\t\t\t= 'center';\n\tconst HORIZONTAL_CENTER_CONTINUOUS\t= 'centerContinuous';\n\tconst HORIZONTAL_JUSTIFY\t\t\t= 'justify';\n\tconst HORIZONTAL_FILL\t\t\t\t= 'fill';\n\tconst HORIZONTAL_DISTRIBUTED\t\t= 'distributed';        // Excel2007 only\n\n\t/* Vertical alignment styles */\n\tconst VERTICAL_BOTTOM\t\t\t\t= 'bottom';\n\tconst VERTICAL_TOP\t\t\t\t\t= 'top';\n\tconst VERTICAL_CENTER\t\t\t\t= 'center';\n\tconst VERTICAL_JUSTIFY\t\t\t\t= 'justify';\n\tconst VERTICAL_DISTRIBUTED\t\t    = 'distributed';        // Excel2007 only\n\n\t/* Read order */\n\tconst READORDER_CONTEXT\t\t\t\t= 0;\n\tconst READORDER_LTR\t    \t\t\t= 1;\n\tconst READORDER_RTL  \t\t\t\t= 2;\n\n\t/**\n\t * Horizontal alignment\n\t *\n\t * @var string\n\t */\n\tprotected $_horizontal = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL;\n\n\t/**\n\t * Vertical alignment\n\t *\n\t * @var string\n\t */\n\tprotected $_vertical = PHPExcel_Style_Alignment::VERTICAL_BOTTOM;\n\n\t/**\n\t * Text rotation\n\t *\n\t * @var integer\n\t */\n\tprotected $_textRotation = 0;\n\n\t/**\n\t * Wrap text\n\t *\n\t * @var boolean\n\t */\n\tprotected $_wrapText = FALSE;\n\n\t/**\n\t * Shrink to fit\n\t *\n\t * @var boolean\n\t */\n\tprotected $_shrinkToFit\t= FALSE;\n\n\t/**\n\t * Indent - only possible with horizontal alignment left and right\n\t *\n\t * @var integer\n\t */\n\tprotected $_indent = 0;\n\n\t/**\n\t * Read order\n\t *\n\t * @var integer\n\t */\n\tprotected $_readorder = 0;\n\n\t/**\n\t * Create a new PHPExcel_Style_Alignment\n\t *\n\t * @param\tboolean\t$isSupervisor\tFlag indicating if this is a supervisor or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t * @param\tboolean\t$isConditional\tFlag indicating if this is a conditional style or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t */\n\tpublic function __construct($isSupervisor = FALSE, $isConditional = FALSE)\n\t{\n\t\t// Supervisor?\n\t\tparent::__construct($isSupervisor);\n\n\t\tif ($isConditional) {\n\t\t\t$this->_horizontal\t\t= NULL;\n\t\t\t$this->_vertical\t\t= NULL;\n\t\t\t$this->_textRotation\t= NULL;\n\t\t}\n\t}\n\n\t/**\n\t * Get the shared style component for the currently active cell in currently active sheet.\n\t * Only used for style supervisor\n\t *\n\t * @return PHPExcel_Style_Alignment\n\t */\n\tpublic function getSharedComponent()\n\t{\n\t\treturn $this->_parent->getSharedComponent()->getAlignment();\n\t}\n\n\t/**\n\t * Build style array from subcomponents\n\t *\n\t * @param array $array\n\t * @return array\n\t */\n\tpublic function getStyleArray($array)\n\t{\n\t\treturn array('alignment' => $array);\n\t}\n\n\t/**\n\t * Apply styles from array\n\t *\n\t * <code>\n\t * $objPHPExcel->getActiveSheet()->getStyle('B2')->getAlignment()->applyFromArray(\n\t *\t\tarray(\n\t *\t\t\t'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_CENTER,\n\t *\t\t\t'vertical'   => PHPExcel_Style_Alignment::VERTICAL_CENTER,\n\t *\t\t\t'rotation'   => 0,\n\t *\t\t\t'wrap'\t\t\t=> TRUE\n\t *\t\t)\n\t * );\n\t * </code>\n\t *\n\t * @param\tarray\t$pStyles\tArray containing style information\n\t * @throws\tPHPExcel_Exception\n\t * @return PHPExcel_Style_Alignment\n\t */\n\tpublic function applyFromArray($pStyles = NULL) {\n\t\tif (is_array($pStyles)) {\n\t\t\tif ($this->_isSupervisor) {\n\t\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())\n\t\t\t\t    ->applyFromArray($this->getStyleArray($pStyles));\n\t\t\t} else {\n\t\t\t\tif (isset($pStyles['horizontal'])) {\n\t\t\t\t\t$this->setHorizontal($pStyles['horizontal']);\n\t\t\t\t}\n\t\t\t\tif (isset($pStyles['vertical'])) {\n\t\t\t\t\t$this->setVertical($pStyles['vertical']);\n\t\t\t\t}\n\t\t\t\tif (isset($pStyles['rotation'])) {\n\t\t\t\t\t$this->setTextRotation($pStyles['rotation']);\n\t\t\t\t}\n\t\t\t\tif (isset($pStyles['wrap'])) {\n\t\t\t\t\t$this->setWrapText($pStyles['wrap']);\n\t\t\t\t}\n\t\t\t\tif (isset($pStyles['shrinkToFit'])) {\n\t\t\t\t\t$this->setShrinkToFit($pStyles['shrinkToFit']);\n\t\t\t\t}\n\t\t\t\tif (isset($pStyles['indent'])) {\n\t\t\t\t\t$this->setIndent($pStyles['indent']);\n\t\t\t\t}\n\t\t\t\tif (isset($pStyles['readorder'])) {\n\t\t\t\t\t$this->setReadorder($pStyles['readorder']);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Invalid style array passed.\");\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Horizontal\n\t *\n\t * @return string\n\t */\n\tpublic function getHorizontal() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getHorizontal();\n\t\t}\n\t\treturn $this->_horizontal;\n\t}\n\n\t/**\n\t * Set Horizontal\n\t *\n\t * @param string $pValue\n\t * @return PHPExcel_Style_Alignment\n\t */\n\tpublic function setHorizontal($pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL) {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = PHPExcel_Style_Alignment::HORIZONTAL_GENERAL;\n\t\t}\n\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('horizontal' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t}\n\t\telse {\n\t\t\t$this->_horizontal = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Vertical\n\t *\n\t * @return string\n\t */\n\tpublic function getVertical() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getVertical();\n\t\t}\n\t\treturn $this->_vertical;\n\t}\n\n\t/**\n\t * Set Vertical\n\t *\n\t * @param string $pValue\n\t * @return PHPExcel_Style_Alignment\n\t */\n\tpublic function setVertical($pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM) {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = PHPExcel_Style_Alignment::VERTICAL_BOTTOM;\n\t\t}\n\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('vertical' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_vertical = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get TextRotation\n\t *\n\t * @return int\n\t */\n\tpublic function getTextRotation() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getTextRotation();\n\t\t}\n\t\treturn $this->_textRotation;\n\t}\n\n\t/**\n\t * Set TextRotation\n\t *\n\t * @param int $pValue\n\t * @throws PHPExcel_Exception\n\t * @return PHPExcel_Style_Alignment\n\t */\n\tpublic function setTextRotation($pValue = 0) {\n\t\t// Excel2007 value 255 => PHPExcel value -165\n\t\tif ($pValue == 255) {\n\t\t\t$pValue = -165;\n\t\t}\n\n\t\t// Set rotation\n\t\tif ( ($pValue >= -90 && $pValue <= 90) || $pValue == -165 ) {\n\t\t\tif ($this->_isSupervisor) {\n\t\t\t\t$styleArray = $this->getStyleArray(array('rotation' => $pValue));\n\t\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t\t} else {\n\t\t\t\t$this->_textRotation = $pValue;\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Text rotation should be a value between -90 and 90.\");\n\t\t}\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Wrap Text\n\t *\n\t * @return boolean\n\t */\n\tpublic function getWrapText() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getWrapText();\n\t\t}\n\t\treturn $this->_wrapText;\n\t}\n\n\t/**\n\t * Set Wrap Text\n\t *\n\t * @param boolean $pValue\n\t * @return PHPExcel_Style_Alignment\n\t */\n\tpublic function setWrapText($pValue = FALSE) {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = FALSE;\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('wrap' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_wrapText = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Shrink to fit\n\t *\n\t * @return boolean\n\t */\n\tpublic function getShrinkToFit() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getShrinkToFit();\n\t\t}\n\t\treturn $this->_shrinkToFit;\n\t}\n\n\t/**\n\t * Set Shrink to fit\n\t *\n\t * @param boolean $pValue\n\t * @return PHPExcel_Style_Alignment\n\t */\n\tpublic function setShrinkToFit($pValue = FALSE) {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = FALSE;\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('shrinkToFit' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_shrinkToFit = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get indent\n\t *\n\t * @return int\n\t */\n\tpublic function getIndent() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getIndent();\n\t\t}\n\t\treturn $this->_indent;\n\t}\n\n\t/**\n\t * Set indent\n\t *\n\t * @param int $pValue\n\t * @return PHPExcel_Style_Alignment\n\t */\n\tpublic function setIndent($pValue = 0) {\n\t\tif ($pValue > 0) {\n\t\t\tif ($this->getHorizontal() != self::HORIZONTAL_GENERAL &&\n\t\t\t\t$this->getHorizontal() != self::HORIZONTAL_LEFT &&\n\t\t\t\t$this->getHorizontal() != self::HORIZONTAL_RIGHT) {\n\t\t\t\t$pValue = 0; // indent not supported\n\t\t\t}\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('indent' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_indent = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get read order\n\t *\n\t * @return integer\n\t */\n\tpublic function getReadorder() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getReadorder();\n\t\t}\n\t\treturn $this->_readorder;\n\t}\n\n\t/**\n\t * Set read order\n\t *\n\t * @param int $pValue\n\t * @return PHPExcel_Style_Alignment\n\t */\n\tpublic function setReadorder($pValue = 0) {\n\t\tif ($pValue < 0 || $pValue > 2) {\n            $pValue = 0;\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('readorder' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_readorder = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getHashCode();\n\t\t}\n\t\treturn md5(\n\t\t\t  $this->_horizontal\n\t\t\t. $this->_vertical\n\t\t\t. $this->_textRotation\n\t\t\t. ($this->_wrapText ? 't' : 'f')\n\t\t\t. ($this->_shrinkToFit ? 't' : 'f')\n\t\t\t. $this->_indent\n\t\t\t. $this->_readorder\n\t\t\t. __CLASS__\n\t\t);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Border.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Style_Border\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Style_Border extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable\n{\n\t/* Border style */\n\tconst BORDER_NONE\t\t\t\t= 'none';\n\tconst BORDER_DASHDOT\t\t\t= 'dashDot';\n\tconst BORDER_DASHDOTDOT\t\t\t= 'dashDotDot';\n\tconst BORDER_DASHED\t\t\t\t= 'dashed';\n\tconst BORDER_DOTTED\t\t\t\t= 'dotted';\n\tconst BORDER_DOUBLE\t\t\t\t= 'double';\n\tconst BORDER_HAIR\t\t\t\t= 'hair';\n\tconst BORDER_MEDIUM\t\t\t\t= 'medium';\n\tconst BORDER_MEDIUMDASHDOT\t\t= 'mediumDashDot';\n\tconst BORDER_MEDIUMDASHDOTDOT\t= 'mediumDashDotDot';\n\tconst BORDER_MEDIUMDASHED\t\t= 'mediumDashed';\n\tconst BORDER_SLANTDASHDOT\t\t= 'slantDashDot';\n\tconst BORDER_THICK\t\t\t\t= 'thick';\n\tconst BORDER_THIN\t\t\t\t= 'thin';\n\n\t/**\n\t * Border style\n\t *\n\t * @var string\n\t */\n\tprotected $_borderStyle\t= PHPExcel_Style_Border::BORDER_NONE;\n\n\t/**\n\t * Border color\n\t *\n\t * @var PHPExcel_Style_Color\n\t */\n\tprotected $_color;\n\n\t/**\n\t * Parent property name\n\t *\n\t * @var string\n\t */\n\tprotected $_parentPropertyName;\n\n\t/**\n\t * Create a new PHPExcel_Style_Border\n\t *\n\t * @param\tboolean\t$isSupervisor\tFlag indicating if this is a supervisor or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t * @param\tboolean\t$isConditional\tFlag indicating if this is a conditional style or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t */\n\tpublic function __construct($isSupervisor = FALSE, $isConditional = FALSE)\n\t{\n\t\t// Supervisor?\n\t\tparent::__construct($isSupervisor);\n\n\t\t// Initialise values\n\t\t$this->_color\t= new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor);\n\n\t\t// bind parent if we are a supervisor\n\t\tif ($isSupervisor) {\n\t\t\t$this->_color->bindParent($this, '_color');\n\t\t}\n\t}\n\n\t/**\n\t * Bind parent. Only used for supervisor\n\t *\n\t * @param PHPExcel_Style_Borders $parent\n\t * @param string $parentPropertyName\n\t * @return PHPExcel_Style_Border\n\t */\n\tpublic function bindParent($parent, $parentPropertyName=NULL)\n\t{\n\t\t$this->_parent = $parent;\n\t\t$this->_parentPropertyName = $parentPropertyName;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get the shared style component for the currently active cell in currently active sheet.\n\t * Only used for style supervisor\n\t *\n\t * @return PHPExcel_Style_Border\n\t * @throws PHPExcel_Exception\n\t */\n\tpublic function getSharedComponent()\n\t{\n\t\tswitch ($this->_parentPropertyName) {\n\t\t\tcase '_allBorders':\n\t\t\tcase '_horizontal':\n\t\t\tcase '_inside':\n\t\t\tcase '_outline':\n\t\t\tcase '_vertical':\n\t\t\t\tthrow new PHPExcel_Exception('Cannot get shared component for a pseudo-border.');\n\t\t\t\tbreak;\n\t\t\tcase '_bottom':\n\t\t\t\treturn $this->_parent->getSharedComponent()->getBottom();\t\tbreak;\n\t\t\tcase '_diagonal':\n\t\t\t\treturn $this->_parent->getSharedComponent()->getDiagonal();\t\tbreak;\n\t\t\tcase '_left':\n\t\t\t\treturn $this->_parent->getSharedComponent()->getLeft();\t\t\tbreak;\n\t\t\tcase '_right':\n\t\t\t\treturn $this->_parent->getSharedComponent()->getRight();\t\tbreak;\n\t\t\tcase '_top':\n\t\t\t\treturn $this->_parent->getSharedComponent()->getTop();\t\t\tbreak;\n\n\t\t}\n\t}\n\n\t/**\n\t * Build style array from subcomponents\n\t *\n\t * @param array $array\n\t * @return array\n\t */\n\tpublic function getStyleArray($array)\n\t{\n\t\tswitch ($this->_parentPropertyName) {\n\t\tcase '_allBorders':\n\t\t\t\t$key = 'allborders';\tbreak;\n\t\tcase '_bottom':\n\t\t\t\t$key = 'bottom';\t\tbreak;\n\t\tcase '_diagonal':\n\t\t\t\t$key = 'diagonal';\t\tbreak;\n\t\tcase '_horizontal':\n\t\t\t\t$key = 'horizontal';\tbreak;\n\t\tcase '_inside':\n\t\t\t\t$key = 'inside';\t\tbreak;\n\t\tcase '_left':\n\t\t\t\t$key = 'left';\t\t\tbreak;\n\t\tcase '_outline':\n\t\t\t\t$key = 'outline';\t\tbreak;\n\t\tcase '_right':\n\t\t\t\t$key = 'right';\t\t\tbreak;\n\t\tcase '_top':\n\t\t\t\t$key = 'top';\t\t\tbreak;\n\t\tcase '_vertical':\n\t\t\t\t$key = 'vertical';\t\tbreak;\n\t\t}\n\t\treturn $this->_parent->getStyleArray(array($key => $array));\n\t}\n\n\t/**\n\t * Apply styles from array\n\t *\n\t * <code>\n\t * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->getTop()->applyFromArray(\n\t *\t\tarray(\n\t *\t\t\t'style' => PHPExcel_Style_Border::BORDER_DASHDOT,\n\t *\t\t\t'color' => array(\n\t *\t\t\t\t'rgb' => '808080'\n\t *\t\t\t)\n\t *\t\t)\n\t * );\n\t * </code>\n\t *\n\t * @param\tarray\t$pStyles\tArray containing style information\n\t * @throws\tPHPExcel_Exception\n\t * @return PHPExcel_Style_Border\n\t */\n\tpublic function applyFromArray($pStyles = null) {\n\t\tif (is_array($pStyles)) {\n\t\t\tif ($this->_isSupervisor) {\n\t\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));\n\t\t\t} else {\n\t\t\t\tif (isset($pStyles['style'])) {\n\t\t\t\t\t$this->setBorderStyle($pStyles['style']);\n\t\t\t\t}\n\t\t\t\tif (isset($pStyles['color'])) {\n\t\t\t\t\t$this->getColor()->applyFromArray($pStyles['color']);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Invalid style array passed.\");\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Border style\n\t *\n\t * @return string\n\t */\n\tpublic function getBorderStyle() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getBorderStyle();\n\t\t}\n\t\treturn $this->_borderStyle;\n\t}\n\n\t/**\n\t * Set Border style\n\t *\n\t * @param string|boolean\t$pValue\n\t *\t\t\t\t\t\t\tWhen passing a boolean, FALSE equates PHPExcel_Style_Border::BORDER_NONE\n\t *\t\t\t\t\t\t\t\tand TRUE to PHPExcel_Style_Border::BORDER_MEDIUM\n\t * @return PHPExcel_Style_Border\n\t */\n\tpublic function setBorderStyle($pValue = PHPExcel_Style_Border::BORDER_NONE) {\n\n\t\tif (empty($pValue)) {\n\t\t\t$pValue = PHPExcel_Style_Border::BORDER_NONE;\n\t\t} elseif(is_bool($pValue) && $pValue) {\n\t\t\t$pValue = PHPExcel_Style_Border::BORDER_MEDIUM;\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('style' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_borderStyle = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Border Color\n\t *\n\t * @return PHPExcel_Style_Color\n\t */\n\tpublic function getColor() {\n\t\treturn $this->_color;\n\t}\n\n\t/**\n\t * Set Border Color\n\t *\n\t * @param\tPHPExcel_Style_Color $pValue\n\t * @throws\tPHPExcel_Exception\n\t * @return PHPExcel_Style_Border\n\t */\n\tpublic function setColor(PHPExcel_Style_Color $pValue = null) {\n\t\t// make sure parameter is a real color and not a supervisor\n\t\t$color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;\n\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getColor()->getStyleArray(array('argb' => $color->getARGB()));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_color = $color;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getHashCode();\n\t\t}\n\t\treturn md5(\n\t\t\t  $this->_borderStyle\n\t\t\t. $this->_color->getHashCode()\n\t\t\t. __CLASS__\n\t\t);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Borders.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Style_Borders\n *\n * @category   PHPExcel\n * @package    PHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Style_Borders extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable\n{\n\t/* Diagonal directions */\n\tconst DIAGONAL_NONE\t\t= 0;\n\tconst DIAGONAL_UP\t\t= 1;\n\tconst DIAGONAL_DOWN\t\t= 2;\n\tconst DIAGONAL_BOTH\t\t= 3;\n\n\t/**\n\t * Left\n\t *\n\t * @var PHPExcel_Style_Border\n\t */\n\tprotected $_left;\n\n\t/**\n\t * Right\n\t *\n\t * @var PHPExcel_Style_Border\n\t */\n\tprotected $_right;\n\n\t/**\n\t * Top\n\t *\n\t * @var PHPExcel_Style_Border\n\t */\n\tprotected $_top;\n\n\t/**\n\t * Bottom\n\t *\n\t * @var PHPExcel_Style_Border\n\t */\n\tprotected $_bottom;\n\n\t/**\n\t * Diagonal\n\t *\n\t * @var PHPExcel_Style_Border\n\t */\n\tprotected $_diagonal;\n\n\t/**\n\t * DiagonalDirection\n\t *\n\t * @var int\n\t */\n\tprotected $_diagonalDirection;\n\n\t/**\n\t * All borders psedo-border. Only applies to supervisor.\n\t *\n\t * @var PHPExcel_Style_Border\n\t */\n\tprotected $_allBorders;\n\n\t/**\n\t * Outline psedo-border. Only applies to supervisor.\n\t *\n\t * @var PHPExcel_Style_Border\n\t */\n\tprotected $_outline;\n\n\t/**\n\t * Inside psedo-border. Only applies to supervisor.\n\t *\n\t * @var PHPExcel_Style_Border\n\t */\n\tprotected $_inside;\n\n\t/**\n\t * Vertical pseudo-border. Only applies to supervisor.\n\t *\n\t * @var PHPExcel_Style_Border\n\t */\n\tprotected $_vertical;\n\n\t/**\n\t * Horizontal pseudo-border. Only applies to supervisor.\n\t *\n\t * @var PHPExcel_Style_Border\n\t */\n\tprotected $_horizontal;\n\n\t/**\n     * Create a new PHPExcel_Style_Borders\n\t *\n\t * @param\tboolean\t$isSupervisor\tFlag indicating if this is a supervisor or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t * @param\tboolean\t$isConditional\tFlag indicating if this is a conditional style or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n     */\n    public function __construct($isSupervisor = FALSE, $isConditional = FALSE)\n    {\n    \t// Supervisor?\n\t\tparent::__construct($isSupervisor);\n\n    \t// Initialise values\n    \t$this->_left\t\t\t\t= new PHPExcel_Style_Border($isSupervisor, $isConditional);\n    \t$this->_right\t\t\t\t= new PHPExcel_Style_Border($isSupervisor, $isConditional);\n    \t$this->_top\t\t\t\t\t= new PHPExcel_Style_Border($isSupervisor, $isConditional);\n    \t$this->_bottom\t\t\t\t= new PHPExcel_Style_Border($isSupervisor, $isConditional);\n    \t$this->_diagonal\t\t\t= new PHPExcel_Style_Border($isSupervisor, $isConditional);\n\t\t$this->_diagonalDirection\t= PHPExcel_Style_Borders::DIAGONAL_NONE;\n\n\t\t// Specially for supervisor\n\t\tif ($isSupervisor) {\n\t\t\t// Initialize pseudo-borders\n\t\t\t$this->_allBorders\t\t\t= new PHPExcel_Style_Border(TRUE);\n\t\t\t$this->_outline\t\t\t\t= new PHPExcel_Style_Border(TRUE);\n\t\t\t$this->_inside\t\t\t\t= new PHPExcel_Style_Border(TRUE);\n\t\t\t$this->_vertical\t\t\t= new PHPExcel_Style_Border(TRUE);\n\t\t\t$this->_horizontal\t\t\t= new PHPExcel_Style_Border(TRUE);\n\n\t\t\t// bind parent if we are a supervisor\n\t\t\t$this->_left->bindParent($this, '_left');\n\t\t\t$this->_right->bindParent($this, '_right');\n\t\t\t$this->_top->bindParent($this, '_top');\n\t\t\t$this->_bottom->bindParent($this, '_bottom');\n\t\t\t$this->_diagonal->bindParent($this, '_diagonal');\n\t\t\t$this->_allBorders->bindParent($this, '_allBorders');\n\t\t\t$this->_outline->bindParent($this, '_outline');\n\t\t\t$this->_inside->bindParent($this, '_inside');\n\t\t\t$this->_vertical->bindParent($this, '_vertical');\n\t\t\t$this->_horizontal->bindParent($this, '_horizontal');\n\t\t}\n    }\n\n\t/**\n\t * Get the shared style component for the currently active cell in currently active sheet.\n\t * Only used for style supervisor\n\t *\n\t * @return PHPExcel_Style_Borders\n\t */\n\tpublic function getSharedComponent()\n\t{\n\t\treturn $this->_parent->getSharedComponent()->getBorders();\n\t}\n\n\t/**\n\t * Build style array from subcomponents\n\t *\n\t * @param array $array\n\t * @return array\n\t */\n\tpublic function getStyleArray($array)\n\t{\n\t\treturn array('borders' => $array);\n\t}\n\n\t/**\n     * Apply styles from array\n     *\n     * <code>\n     * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray(\n     * \t\tarray(\n     * \t\t\t'bottom'     => array(\n     * \t\t\t\t'style' => PHPExcel_Style_Border::BORDER_DASHDOT,\n     * \t\t\t\t'color' => array(\n     * \t\t\t\t\t'rgb' => '808080'\n     * \t\t\t\t)\n     * \t\t\t),\n     * \t\t\t'top'     => array(\n     * \t\t\t\t'style' => PHPExcel_Style_Border::BORDER_DASHDOT,\n     * \t\t\t\t'color' => array(\n     * \t\t\t\t\t'rgb' => '808080'\n     * \t\t\t\t)\n     * \t\t\t)\n     * \t\t)\n     * );\n     * </code>\n     * <code>\n     * $objPHPExcel->getActiveSheet()->getStyle('B2')->getBorders()->applyFromArray(\n     * \t\tarray(\n     * \t\t\t'allborders' => array(\n     * \t\t\t\t'style' => PHPExcel_Style_Border::BORDER_DASHDOT,\n     * \t\t\t\t'color' => array(\n     * \t\t\t\t\t'rgb' => '808080'\n     * \t\t\t\t)\n     * \t\t\t)\n     * \t\t)\n     * );\n     * </code>\n     *\n     * @param\tarray\t$pStyles\tArray containing style information\n     * @throws\tPHPExcel_Exception\n     * @return PHPExcel_Style_Borders\n     */\n\tpublic function applyFromArray($pStyles = null) {\n\t\tif (is_array($pStyles)) {\n\t\t\tif ($this->_isSupervisor) {\n\t\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));\n\t\t\t} else {\n\t\t\t\tif (array_key_exists('left', $pStyles)) {\n\t\t\t\t\t$this->getLeft()->applyFromArray($pStyles['left']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('right', $pStyles)) {\n\t\t\t\t\t$this->getRight()->applyFromArray($pStyles['right']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('top', $pStyles)) {\n\t\t\t\t\t$this->getTop()->applyFromArray($pStyles['top']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('bottom', $pStyles)) {\n\t\t\t\t\t$this->getBottom()->applyFromArray($pStyles['bottom']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('diagonal', $pStyles)) {\n\t\t\t\t\t$this->getDiagonal()->applyFromArray($pStyles['diagonal']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('diagonaldirection', $pStyles)) {\n\t\t\t\t\t$this->setDiagonalDirection($pStyles['diagonaldirection']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('allborders', $pStyles)) {\n\t\t\t\t\t$this->getLeft()->applyFromArray($pStyles['allborders']);\n\t\t\t\t\t$this->getRight()->applyFromArray($pStyles['allborders']);\n\t\t\t\t\t$this->getTop()->applyFromArray($pStyles['allborders']);\n\t\t\t\t\t$this->getBottom()->applyFromArray($pStyles['allborders']);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Invalid style array passed.\");\n\t\t}\n\t\treturn $this;\n\t}\n\n    /**\n     * Get Left\n     *\n     * @return PHPExcel_Style_Border\n     */\n    public function getLeft() {\n\t\treturn $this->_left;\n    }\n\n    /**\n     * Get Right\n     *\n     * @return PHPExcel_Style_Border\n     */\n    public function getRight() {\n\t\treturn $this->_right;\n    }\n\n    /**\n     * Get Top\n     *\n     * @return PHPExcel_Style_Border\n     */\n    public function getTop() {\n\t\treturn $this->_top;\n    }\n\n    /**\n     * Get Bottom\n     *\n     * @return PHPExcel_Style_Border\n     */\n    public function getBottom() {\n\t\treturn $this->_bottom;\n    }\n\n    /**\n     * Get Diagonal\n     *\n     * @return PHPExcel_Style_Border\n     */\n    public function getDiagonal() {\n\t\treturn $this->_diagonal;\n    }\n\n    /**\n     * Get AllBorders (pseudo-border). Only applies to supervisor.\n     *\n     * @return PHPExcel_Style_Border\n     * @throws PHPExcel_Exception\n     */\n    public function getAllBorders() {\n\t\tif (!$this->_isSupervisor) {\n\t\t\tthrow new PHPExcel_Exception('Can only get pseudo-border for supervisor.');\n\t\t}\n\t\treturn $this->_allBorders;\n    }\n\n    /**\n     * Get Outline (pseudo-border). Only applies to supervisor.\n     *\n     * @return boolean\n     * @throws PHPExcel_Exception\n     */\n    public function getOutline() {\n\t\tif (!$this->_isSupervisor) {\n\t\t\tthrow new PHPExcel_Exception('Can only get pseudo-border for supervisor.');\n\t\t}\n    \treturn $this->_outline;\n    }\n\n    /**\n     * Get Inside (pseudo-border). Only applies to supervisor.\n     *\n     * @return boolean\n     * @throws PHPExcel_Exception\n     */\n    public function getInside() {\n\t\tif (!$this->_isSupervisor) {\n\t\t\tthrow new PHPExcel_Exception('Can only get pseudo-border for supervisor.');\n\t\t}\n    \treturn $this->_inside;\n    }\n\n    /**\n     * Get Vertical (pseudo-border). Only applies to supervisor.\n     *\n     * @return PHPExcel_Style_Border\n     * @throws PHPExcel_Exception\n     */\n    public function getVertical() {\n\t\tif (!$this->_isSupervisor) {\n\t\t\tthrow new PHPExcel_Exception('Can only get pseudo-border for supervisor.');\n\t\t}\n\t\treturn $this->_vertical;\n    }\n\n    /**\n     * Get Horizontal (pseudo-border). Only applies to supervisor.\n     *\n     * @return PHPExcel_Style_Border\n     * @throws PHPExcel_Exception\n     */\n    public function getHorizontal() {\n\t\tif (!$this->_isSupervisor) {\n\t\t\tthrow new PHPExcel_Exception('Can only get pseudo-border for supervisor.');\n\t\t}\n\t\treturn $this->_horizontal;\n    }\n\n    /**\n     * Get DiagonalDirection\n     *\n     * @return int\n     */\n    public function getDiagonalDirection() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getDiagonalDirection();\n\t\t}\n    \treturn $this->_diagonalDirection;\n    }\n\n    /**\n     * Set DiagonalDirection\n     *\n     * @param int $pValue\n     * @return PHPExcel_Style_Borders\n     */\n    public function setDiagonalDirection($pValue = PHPExcel_Style_Borders::DIAGONAL_NONE) {\n        if ($pValue == '') {\n    \t\t$pValue = PHPExcel_Style_Borders::DIAGONAL_NONE;\n    \t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('diagonaldirection' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_diagonalDirection = $pValue;\n\t\t}\n\t\treturn $this;\n    }\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getHashcode();\n\t\t}\n    \treturn md5(\n    \t\t  $this->getLeft()->getHashCode()\n    \t\t. $this->getRight()->getHashCode()\n    \t\t. $this->getTop()->getHashCode()\n    \t\t. $this->getBottom()->getHashCode()\n    \t\t. $this->getDiagonal()->getHashCode()\n    \t\t. $this->getDiagonalDirection()\n    \t\t. __CLASS__\n    \t);\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Color.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Style_Color\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Style_Color extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable\n{\n\t/* Colors */\n\tconst COLOR_BLACK\t\t\t\t\t\t= 'FF000000';\n\tconst COLOR_WHITE\t\t\t\t\t\t= 'FFFFFFFF';\n\tconst COLOR_RED\t\t\t\t\t\t\t= 'FFFF0000';\n\tconst COLOR_DARKRED\t\t\t\t\t\t= 'FF800000';\n\tconst COLOR_BLUE\t\t\t\t\t\t= 'FF0000FF';\n\tconst COLOR_DARKBLUE\t\t\t\t\t= 'FF000080';\n\tconst COLOR_GREEN\t\t\t\t\t\t= 'FF00FF00';\n\tconst COLOR_DARKGREEN\t\t\t\t\t= 'FF008000';\n\tconst COLOR_YELLOW\t\t\t\t\t\t= 'FFFFFF00';\n\tconst COLOR_DARKYELLOW\t\t\t\t\t= 'FF808000';\n\n\t/**\n\t * Indexed colors array\n\t *\n\t * @var array\n\t */\n\tprotected static $_indexedColors;\n\n\t/**\n\t * ARGB - Alpha RGB\n\t *\n\t * @var string\n\t */\n\tprotected $_argb\t= NULL;\n\n\t/**\n\t * Parent property name\n\t *\n\t * @var string\n\t */\n\tprotected $_parentPropertyName;\n\n\n\t/**\n\t * Create a new PHPExcel_Style_Color\n\t *\n\t * @param\tstring\t$pARGB\t\t\tARGB value for the colour\n\t * @param\tboolean\t$isSupervisor\tFlag indicating if this is a supervisor or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t * @param\tboolean\t$isConditional\tFlag indicating if this is a conditional style or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t */\n\tpublic function __construct($pARGB = PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor = FALSE, $isConditional = FALSE)\n\t{\n\t\t//\tSupervisor?\n\t\tparent::__construct($isSupervisor);\n\n\t\t//\tInitialise values\n\t\tif (!$isConditional) {\n\t\t\t$this->_argb = $pARGB;\n\t\t}\n\t}\n\n\t/**\n\t * Bind parent. Only used for supervisor\n\t *\n\t * @param mixed $parent\n\t * @param string $parentPropertyName\n\t * @return PHPExcel_Style_Color\n\t */\n\tpublic function bindParent($parent, $parentPropertyName=NULL)\n\t{\n\t\t$this->_parent = $parent;\n\t\t$this->_parentPropertyName = $parentPropertyName;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get the shared style component for the currently active cell in currently active sheet.\n\t * Only used for style supervisor\n\t *\n\t * @return PHPExcel_Style_Color\n\t */\n\tpublic function getSharedComponent()\n\t{\n\t\tswitch ($this->_parentPropertyName) {\n\t\t\tcase '_endColor':\n\t\t\t\treturn $this->_parent->getSharedComponent()->getEndColor();\t\tbreak;\n\t\t\tcase '_color':\n\t\t\t\treturn $this->_parent->getSharedComponent()->getColor();\t\tbreak;\n\t\t\tcase '_startColor':\n\t\t\t\treturn $this->_parent->getSharedComponent()->getStartColor();\tbreak;\n\t\t}\n\t}\n\n\t/**\n\t * Build style array from subcomponents\n\t *\n\t * @param array $array\n\t * @return array\n\t */\n\tpublic function getStyleArray($array)\n\t{\n\t\tswitch ($this->_parentPropertyName) {\n\t\t\tcase '_endColor':\n\t\t\t\t$key = 'endcolor';\n\t\t\t\tbreak;\n\t\t\tcase '_color':\n\t\t\t\t$key = 'color';\n\t\t\t\tbreak;\n\t\t\tcase '_startColor':\n\t\t\t\t$key = 'startcolor';\n\t\t\t\tbreak;\n\n\t\t}\n\t\treturn $this->_parent->getStyleArray(array($key => $array));\n\t}\n\n\t/**\n\t * Apply styles from array\n\t *\n\t * <code>\n\t * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->getColor()->applyFromArray( array('rgb' => '808080') );\n\t * </code>\n\t *\n\t * @param\tarray\t$pStyles\tArray containing style information\n\t * @throws\tPHPExcel_Exception\n\t * @return PHPExcel_Style_Color\n\t */\n\tpublic function applyFromArray($pStyles = NULL) {\n\t\tif (is_array($pStyles)) {\n\t\t\tif ($this->_isSupervisor) {\n\t\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));\n\t\t\t} else {\n\t\t\t\tif (array_key_exists('rgb', $pStyles)) {\n\t\t\t\t\t$this->setRGB($pStyles['rgb']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('argb', $pStyles)) {\n\t\t\t\t\t$this->setARGB($pStyles['argb']);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Invalid style array passed.\");\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get ARGB\n\t *\n\t * @return string\n\t */\n\tpublic function getARGB() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getARGB();\n\t\t}\n\t\treturn $this->_argb;\n\t}\n\n\t/**\n\t * Set ARGB\n\t *\n\t * @param string $pValue\n\t * @return PHPExcel_Style_Color\n\t */\n\tpublic function setARGB($pValue = PHPExcel_Style_Color::COLOR_BLACK) {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = PHPExcel_Style_Color::COLOR_BLACK;\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('argb' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_argb = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get RGB\n\t *\n\t * @return string\n\t */\n\tpublic function getRGB() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getRGB();\n\t\t}\n\t\treturn substr($this->_argb, 2);\n\t}\n\n\t/**\n\t * Set RGB\n\t *\n\t * @param\tstring\t$pValue\tRGB value\n\t * @return PHPExcel_Style_Color\n\t */\n\tpublic function setRGB($pValue = '000000') {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = '000000';\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('argb' => 'FF' . $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_argb = 'FF' . $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get a specified colour component of an RGB value\n\t *\n\t * @private\n\t * @param\tstring\t\t$RGB\t\tThe colour as an RGB value (e.g. FF00CCCC or CCDDEE\n\t * @param\tint\t\t\t$offset\t\tPosition within the RGB value to extract\n\t * @param\tboolean\t\t$hex\t\tFlag indicating whether the component should be returned as a hex or a\n\t *\t\t\t\t\t\t\t\t\tdecimal value\n\t * @return\tstring\t\tThe extracted colour component\n\t */\n\tprivate static function _getColourComponent($RGB,$offset,$hex=TRUE) {\n\t\t$colour = substr($RGB, $offset, 2);\n\t\tif (!$hex)\n\t\t\t$colour = hexdec($colour);\n\t\treturn $colour;\n\t}\n\n\t/**\n\t * Get the red colour component of an RGB value\n\t *\n\t * @param\tstring\t\t$RGB\t\tThe colour as an RGB value (e.g. FF00CCCC or CCDDEE\n\t * @param\tboolean\t\t$hex\t\tFlag indicating whether the component should be returned as a hex or a\n\t *\t\t\t\t\t\t\t\t\tdecimal value\n\t * @return\tstring\t\tThe red colour component\n\t */\n\tpublic static function getRed($RGB,$hex=TRUE) {\n\t\treturn self::_getColourComponent($RGB, strlen($RGB) - 6, $hex);\n\t}\n\n\t/**\n\t * Get the green colour component of an RGB value\n\t *\n\t * @param\tstring\t\t$RGB\t\tThe colour as an RGB value (e.g. FF00CCCC or CCDDEE\n\t * @param\tboolean\t\t$hex\t\tFlag indicating whether the component should be returned as a hex or a\n\t *\t\t\t\t\t\t\t\t\tdecimal value\n\t * @return\tstring\t\tThe green colour component\n\t */\n\tpublic static function getGreen($RGB,$hex=TRUE) {\n\t\treturn self::_getColourComponent($RGB, strlen($RGB) - 4, $hex);\n\t}\n\n\t/**\n\t * Get the blue colour component of an RGB value\n\t *\n\t * @param\tstring\t\t$RGB\t\tThe colour as an RGB value (e.g. FF00CCCC or CCDDEE\n\t * @param\tboolean\t\t$hex\t\tFlag indicating whether the component should be returned as a hex or a\n\t *\t\t\t\t\t\t\t\t\tdecimal value\n\t * @return\tstring\t\tThe blue colour component\n\t */\n\tpublic static function getBlue($RGB,$hex=TRUE) {\n\t\treturn self::_getColourComponent($RGB, strlen($RGB) - 2, $hex);\n\t}\n\n\t/**\n\t * Adjust the brightness of a color\n\t *\n\t * @param\tstring\t\t$hex\tThe colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE)\n\t * @param\tfloat\t\t$adjustPercentage\tThe percentage by which to adjust the colour as a float from -1 to 1\n\t * @return\tstring\t\tThe adjusted colour as an RGBA or RGB value (e.g. FF00CCCC or CCDDEE)\n\t */\n\tpublic static function changeBrightness($hex, $adjustPercentage) {\n\t\t$rgba = (strlen($hex) == 8);\n\n\t\t$red\t= self::getRed($hex, FALSE);\n\t\t$green\t= self::getGreen($hex, FALSE);\n\t\t$blue\t= self::getBlue($hex, FALSE);\n\t\tif ($adjustPercentage > 0) {\n\t\t\t$red\t+= (255 - $red) * $adjustPercentage;\n\t\t\t$green\t+= (255 - $green) * $adjustPercentage;\n\t\t\t$blue\t+= (255 - $blue) * $adjustPercentage;\n\t\t} else {\n\t\t\t$red\t+= $red * $adjustPercentage;\n\t\t\t$green\t+= $green * $adjustPercentage;\n\t\t\t$blue\t+= $blue * $adjustPercentage;\n\t\t}\n\n\t\tif ($red < 0) $red = 0;\n\t\telseif ($red > 255) $red = 255;\n\t\tif ($green < 0) $green = 0;\n\t\telseif ($green > 255) $green = 255;\n\t\tif ($blue < 0) $blue = 0;\n\t\telseif ($blue > 255) $blue = 255;\n\n\t\t$rgb = strtoupper(\tstr_pad(dechex($red), 2, '0', 0) .\n\t\t\t\t\t\t\tstr_pad(dechex($green), 2, '0', 0) .\n\t\t\t\t\t\t\tstr_pad(dechex($blue), 2, '0', 0)\n\t\t\t\t\t\t );\n\t\treturn (($rgba) ? 'FF' : '') . $rgb;\n\t}\n\n\t/**\n\t * Get indexed color\n\t *\n\t * @param\tint\t\t\t$pIndex\t\t\tIndex entry point into the colour array\n\t * @param\tboolean\t\t$background\t\tFlag to indicate whether default background or foreground colour\n\t *\t\t\t\t\t\t\t\t\t\t\tshould be returned if the indexed colour doesn't exist\n\t * @return\tPHPExcel_Style_Color\n\t */\n\tpublic static function indexedColor($pIndex, $background=FALSE) {\n\t\t// Clean parameter\n\t\t$pIndex = intval($pIndex);\n\n\t\t// Indexed colors\n\t\tif (is_null(self::$_indexedColors)) {\n\t\t\tself::$_indexedColors = array(\n\t\t\t\t\t1\t=> 'FF000000',\t//\tSystem Colour #1 - Black\n\t\t\t\t\t2\t=> 'FFFFFFFF',\t//\tSystem Colour #2 - White\n\t\t\t\t\t3\t=> 'FFFF0000',\t//\tSystem Colour #3 - Red\n\t\t\t\t\t4\t=> 'FF00FF00',\t//\tSystem Colour #4 - Green\n\t\t\t\t\t5\t=> 'FF0000FF',\t//\tSystem Colour #5 - Blue\n\t\t\t\t\t6\t=> 'FFFFFF00',\t//\tSystem Colour #6 - Yellow\n\t\t\t\t\t7\t=> 'FFFF00FF',\t//\tSystem Colour #7- Magenta\n\t\t\t\t\t8\t=> 'FF00FFFF',\t//\tSystem Colour #8- Cyan\n\t\t\t\t\t9\t=> 'FF800000',\t//\tStandard Colour #9\n\t\t\t\t\t10\t=> 'FF008000',\t//\tStandard Colour #10\n\t\t\t\t\t11\t=> 'FF000080',\t//\tStandard Colour #11\n\t\t\t\t\t12\t=> 'FF808000',\t//\tStandard Colour #12\n\t\t\t\t\t13\t=> 'FF800080',\t//\tStandard Colour #13\n\t\t\t\t\t14\t=> 'FF008080',\t//\tStandard Colour #14\n\t\t\t\t\t15\t=> 'FFC0C0C0',\t//\tStandard Colour #15\n\t\t\t\t\t16\t=> 'FF808080',\t//\tStandard Colour #16\n\t\t\t\t\t17\t=> 'FF9999FF',\t//\tChart Fill Colour #17\n\t\t\t\t\t18\t=> 'FF993366',\t//\tChart Fill Colour #18\n\t\t\t\t\t19\t=> 'FFFFFFCC',\t//\tChart Fill Colour #19\n\t\t\t\t\t20\t=> 'FFCCFFFF',\t//\tChart Fill Colour #20\n\t\t\t\t\t21\t=> 'FF660066',\t//\tChart Fill Colour #21\n\t\t\t\t\t22\t=> 'FFFF8080',\t//\tChart Fill Colour #22\n\t\t\t\t\t23\t=> 'FF0066CC',\t//\tChart Fill Colour #23\n\t\t\t\t\t24\t=> 'FFCCCCFF',\t//\tChart Fill Colour #24\n\t\t\t\t\t25\t=> 'FF000080',\t//\tChart Line Colour #25\n\t\t\t\t\t26\t=> 'FFFF00FF',\t//\tChart Line Colour #26\n\t\t\t\t\t27\t=> 'FFFFFF00',\t//\tChart Line Colour #27\n\t\t\t\t\t28\t=> 'FF00FFFF',\t//\tChart Line Colour #28\n\t\t\t\t\t29\t=> 'FF800080',\t//\tChart Line Colour #29\n\t\t\t\t\t30\t=> 'FF800000',\t//\tChart Line Colour #30\n\t\t\t\t\t31\t=> 'FF008080',\t//\tChart Line Colour #31\n\t\t\t\t\t32\t=> 'FF0000FF',\t//\tChart Line Colour #32\n\t\t\t\t\t33\t=> 'FF00CCFF',\t//\tStandard Colour #33\n\t\t\t\t\t34\t=> 'FFCCFFFF',\t//\tStandard Colour #34\n\t\t\t\t\t35\t=> 'FFCCFFCC',\t//\tStandard Colour #35\n\t\t\t\t\t36\t=> 'FFFFFF99',\t//\tStandard Colour #36\n\t\t\t\t\t37\t=> 'FF99CCFF',\t//\tStandard Colour #37\n\t\t\t\t\t38\t=> 'FFFF99CC',\t//\tStandard Colour #38\n\t\t\t\t\t39\t=> 'FFCC99FF',\t//\tStandard Colour #39\n\t\t\t\t\t40\t=> 'FFFFCC99',\t//\tStandard Colour #40\n\t\t\t\t\t41\t=> 'FF3366FF',\t//\tStandard Colour #41\n\t\t\t\t\t42\t=> 'FF33CCCC',\t//\tStandard Colour #42\n\t\t\t\t\t43\t=> 'FF99CC00',\t//\tStandard Colour #43\n\t\t\t\t\t44\t=> 'FFFFCC00',\t//\tStandard Colour #44\n\t\t\t\t\t45\t=> 'FFFF9900',\t//\tStandard Colour #45\n\t\t\t\t\t46\t=> 'FFFF6600',\t//\tStandard Colour #46\n\t\t\t\t\t47\t=> 'FF666699',\t//\tStandard Colour #47\n\t\t\t\t\t48\t=> 'FF969696',\t//\tStandard Colour #48\n\t\t\t\t\t49\t=> 'FF003366',\t//\tStandard Colour #49\n\t\t\t\t\t50\t=> 'FF339966',\t//\tStandard Colour #50\n\t\t\t\t\t51\t=> 'FF003300',\t//\tStandard Colour #51\n\t\t\t\t\t52\t=> 'FF333300',\t//\tStandard Colour #52\n\t\t\t\t\t53\t=> 'FF993300',\t//\tStandard Colour #53\n\t\t\t\t\t54\t=> 'FF993366',\t//\tStandard Colour #54\n\t\t\t\t\t55\t=> 'FF333399',\t//\tStandard Colour #55\n\t\t\t\t\t56\t=> 'FF333333'\t//\tStandard Colour #56\n\t\t\t\t);\n\t\t}\n\n\t\tif (array_key_exists($pIndex, self::$_indexedColors)) {\n\t\t\treturn new PHPExcel_Style_Color(self::$_indexedColors[$pIndex]);\n\t\t}\n\n\t\tif ($background) {\n\t\t\treturn new PHPExcel_Style_Color('FFFFFFFF');\n\t\t}\n\t\treturn new PHPExcel_Style_Color('FF000000');\n\t}\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getHashCode();\n\t\t}\n\t\treturn md5(\n\t\t\t  $this->_argb\n\t\t\t. __CLASS__\n\t\t);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Conditional.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Style_Conditional\n *\n * @category   PHPExcel\n * @package    PHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Style_Conditional implements PHPExcel_IComparable\n{\n\t/* Condition types */\n\tconst CONDITION_NONE\t\t\t\t\t= 'none';\n\tconst CONDITION_CELLIS\t\t\t\t\t= 'cellIs';\n\tconst CONDITION_CONTAINSTEXT\t\t\t= 'containsText';\n\tconst CONDITION_EXPRESSION \t\t\t\t= 'expression';\n\n\t/* Operator types */\n\tconst OPERATOR_NONE\t\t\t\t\t\t= '';\n\tconst OPERATOR_BEGINSWITH\t\t\t\t= 'beginsWith';\n\tconst OPERATOR_ENDSWITH\t\t\t\t\t= 'endsWith';\n\tconst OPERATOR_EQUAL\t\t\t\t\t= 'equal';\n\tconst OPERATOR_GREATERTHAN\t\t\t\t= 'greaterThan';\n\tconst OPERATOR_GREATERTHANOREQUAL\t\t= 'greaterThanOrEqual';\n\tconst OPERATOR_LESSTHAN\t\t\t\t\t= 'lessThan';\n\tconst OPERATOR_LESSTHANOREQUAL\t\t\t= 'lessThanOrEqual';\n\tconst OPERATOR_NOTEQUAL\t\t\t\t\t= 'notEqual';\n\tconst OPERATOR_CONTAINSTEXT\t\t\t\t= 'containsText';\n\tconst OPERATOR_NOTCONTAINS\t\t\t\t= 'notContains';\n\tconst OPERATOR_BETWEEN\t\t\t\t\t= 'between';\n\n\t/**\n\t * Condition type\n\t *\n\t * @var int\n\t */\n\tprivate $_conditionType;\n\n\t/**\n\t * Operator type\n\t *\n\t * @var int\n\t */\n\tprivate $_operatorType;\n\n\t/**\n\t * Text\n\t *\n\t * @var string\n\t */\n\tprivate $_text;\n\n\t/**\n\t * Condition\n\t *\n\t * @var string[]\n\t */\n\tprivate $_condition = array();\n\n\t/**\n\t * Style\n\t *\n\t * @var PHPExcel_Style\n\t */\n\tprivate $_style;\n\n    /**\n     * Create a new PHPExcel_Style_Conditional\n     */\n    public function __construct()\n    {\n    \t// Initialise values\n    \t$this->_conditionType\t\t= PHPExcel_Style_Conditional::CONDITION_NONE;\n    \t$this->_operatorType\t\t= PHPExcel_Style_Conditional::OPERATOR_NONE;\n    \t$this->_text    \t\t\t= null;\n    \t$this->_condition\t\t\t= array();\n    \t$this->_style\t\t\t\t= new PHPExcel_Style(FALSE, TRUE);\n    }\n\n    /**\n     * Get Condition type\n     *\n     * @return string\n     */\n    public function getConditionType() {\n    \treturn $this->_conditionType;\n    }\n\n    /**\n     * Set Condition type\n     *\n     * @param string $pValue\tPHPExcel_Style_Conditional condition type\n     * @return PHPExcel_Style_Conditional\n     */\n    public function setConditionType($pValue = PHPExcel_Style_Conditional::CONDITION_NONE) {\n    \t$this->_conditionType = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Operator type\n     *\n     * @return string\n     */\n    public function getOperatorType() {\n    \treturn $this->_operatorType;\n    }\n\n    /**\n     * Set Operator type\n     *\n     * @param string $pValue\tPHPExcel_Style_Conditional operator type\n     * @return PHPExcel_Style_Conditional\n     */\n    public function setOperatorType($pValue = PHPExcel_Style_Conditional::OPERATOR_NONE) {\n    \t$this->_operatorType = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get text\n     *\n     * @return string\n     */\n    public function getText() {\n        return $this->_text;\n    }\n\n    /**\n     * Set text\n     *\n     * @param string $value\n     * @return PHPExcel_Style_Conditional\n     */\n    public function setText($value = null) {\n           $this->_text = $value;\n           return $this;\n    }\n\n    /**\n     * Get Condition\n     *\n     * @deprecated Deprecated, use getConditions instead\n     * @return string\n     */\n    public function getCondition() {\n    \tif (isset($this->_condition[0])) {\n    \t\treturn $this->_condition[0];\n    \t}\n\n    \treturn '';\n    }\n\n    /**\n     * Set Condition\n     *\n     * @deprecated Deprecated, use setConditions instead\n     * @param string $pValue\tCondition\n     * @return PHPExcel_Style_Conditional\n     */\n    public function setCondition($pValue = '') {\n    \tif (!is_array($pValue))\n    \t\t$pValue = array($pValue);\n\n    \treturn $this->setConditions($pValue);\n    }\n\n    /**\n     * Get Conditions\n     *\n     * @return string[]\n     */\n    public function getConditions() {\n    \treturn $this->_condition;\n    }\n\n    /**\n     * Set Conditions\n     *\n     * @param string[] $pValue\tCondition\n     * @return PHPExcel_Style_Conditional\n     */\n    public function setConditions($pValue) {\n    \tif (!is_array($pValue))\n    \t\t$pValue = array($pValue);\n\n    \t$this->_condition = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Add Condition\n     *\n     * @param string $pValue\tCondition\n     * @return PHPExcel_Style_Conditional\n     */\n    public function addCondition($pValue = '') {\n    \t$this->_condition[] = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Style\n     *\n     * @return PHPExcel_Style\n     */\n    public function getStyle() {\n    \treturn $this->_style;\n    }\n\n    /**\n     * Set Style\n     *\n     * @param \tPHPExcel_Style $pValue\n     * @throws \tPHPExcel_Exception\n     * @return PHPExcel_Style_Conditional\n     */\n    public function setStyle(PHPExcel_Style $pValue = null) {\n   \t\t$this->_style = $pValue;\n   \t\treturn $this;\n    }\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n    \treturn md5(\n    \t\t  $this->_conditionType\n    \t\t. $this->_operatorType\n    \t\t. implode(';', $this->_condition)\n    \t\t. $this->_style->getHashCode()\n    \t\t. __CLASS__\n    \t);\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Fill.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Style_Fill\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Style_Fill extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable\n{\n\t/* Fill types */\n\tconst FILL_NONE\t\t\t\t\t\t\t= 'none';\n\tconst FILL_SOLID\t\t\t\t\t\t= 'solid';\n\tconst FILL_GRADIENT_LINEAR\t\t\t\t= 'linear';\n\tconst FILL_GRADIENT_PATH\t\t\t\t= 'path';\n\tconst FILL_PATTERN_DARKDOWN\t\t\t\t= 'darkDown';\n\tconst FILL_PATTERN_DARKGRAY\t\t\t\t= 'darkGray';\n\tconst FILL_PATTERN_DARKGRID\t\t\t\t= 'darkGrid';\n\tconst FILL_PATTERN_DARKHORIZONTAL\t\t= 'darkHorizontal';\n\tconst FILL_PATTERN_DARKTRELLIS\t\t\t= 'darkTrellis';\n\tconst FILL_PATTERN_DARKUP\t\t\t\t= 'darkUp';\n\tconst FILL_PATTERN_DARKVERTICAL\t\t\t= 'darkVertical';\n\tconst FILL_PATTERN_GRAY0625\t\t\t\t= 'gray0625';\n\tconst FILL_PATTERN_GRAY125\t\t\t\t= 'gray125';\n\tconst FILL_PATTERN_LIGHTDOWN\t\t\t= 'lightDown';\n\tconst FILL_PATTERN_LIGHTGRAY\t\t\t= 'lightGray';\n\tconst FILL_PATTERN_LIGHTGRID\t\t\t= 'lightGrid';\n\tconst FILL_PATTERN_LIGHTHORIZONTAL\t\t= 'lightHorizontal';\n\tconst FILL_PATTERN_LIGHTTRELLIS\t\t\t= 'lightTrellis';\n\tconst FILL_PATTERN_LIGHTUP\t\t\t\t= 'lightUp';\n\tconst FILL_PATTERN_LIGHTVERTICAL\t\t= 'lightVertical';\n\tconst FILL_PATTERN_MEDIUMGRAY\t\t\t= 'mediumGray';\n\n\t/**\n\t * Fill type\n\t *\n\t * @var string\n\t */\n\tprotected $_fillType\t= PHPExcel_Style_Fill::FILL_NONE;\n\n\t/**\n\t * Rotation\n\t *\n\t * @var double\n\t */\n\tprotected $_rotation\t= 0;\n\n\t/**\n\t * Start color\n\t *\n\t * @var PHPExcel_Style_Color\n\t */\n\tprotected $_startColor;\n\n\t/**\n\t * End color\n\t *\n\t * @var PHPExcel_Style_Color\n\t */\n\tprotected $_endColor;\n\n\t/**\n\t * Create a new PHPExcel_Style_Fill\n\t *\n\t * @param\tboolean\t$isSupervisor\tFlag indicating if this is a supervisor or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t * @param\tboolean\t$isConditional\tFlag indicating if this is a conditional style or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t */\n\tpublic function __construct($isSupervisor = FALSE, $isConditional = FALSE)\n\t{\n\t\t// Supervisor?\n\t\tparent::__construct($isSupervisor);\n\n\t\t// Initialise values\n\t\tif ($isConditional) {\n\t\t\t$this->_fillType = NULL;\n\t\t}\n\t\t$this->_startColor\t\t\t= new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_WHITE, $isSupervisor, $isConditional);\n\t\t$this->_endColor\t\t\t= new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor, $isConditional);\n\n\t\t// bind parent if we are a supervisor\n\t\tif ($isSupervisor) {\n\t\t\t$this->_startColor->bindParent($this, '_startColor');\n\t\t\t$this->_endColor->bindParent($this, '_endColor');\n\t\t}\n\t}\n\n\t/**\n\t * Get the shared style component for the currently active cell in currently active sheet.\n\t * Only used for style supervisor\n\t *\n\t * @return PHPExcel_Style_Fill\n\t */\n\tpublic function getSharedComponent()\n\t{\n\t\treturn $this->_parent->getSharedComponent()->getFill();\n\t}\n\n\t/**\n\t * Build style array from subcomponents\n\t *\n\t * @param array $array\n\t * @return array\n\t */\n\tpublic function getStyleArray($array)\n\t{\n\t\treturn array('fill' => $array);\n\t}\n\n\t/**\n\t * Apply styles from array\n\t *\n\t * <code>\n\t * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFill()->applyFromArray(\n\t *\t\tarray(\n\t *\t\t\t'type'\t   => PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR,\n\t *\t\t\t'rotation'   => 0,\n\t *\t\t\t'startcolor' => array(\n\t *\t\t\t\t'rgb' => '000000'\n\t *\t\t\t),\n\t *\t\t\t'endcolor'   => array(\n\t *\t\t\t\t'argb' => 'FFFFFFFF'\n\t *\t\t\t)\n\t *\t\t)\n\t * );\n\t * </code>\n\t *\n\t * @param\tarray\t$pStyles\tArray containing style information\n\t * @throws\tPHPExcel_Exception\n\t * @return PHPExcel_Style_Fill\n\t */\n\tpublic function applyFromArray($pStyles = null) {\n\t\tif (is_array($pStyles)) {\n\t\t\tif ($this->_isSupervisor) {\n\t\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));\n\t\t\t} else {\n\t\t\t\tif (array_key_exists('type', $pStyles)) {\n\t\t\t\t\t$this->setFillType($pStyles['type']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('rotation', $pStyles)) {\n\t\t\t\t\t$this->setRotation($pStyles['rotation']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('startcolor', $pStyles)) {\n\t\t\t\t\t$this->getStartColor()->applyFromArray($pStyles['startcolor']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('endcolor', $pStyles)) {\n\t\t\t\t\t$this->getEndColor()->applyFromArray($pStyles['endcolor']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('color', $pStyles)) {\n\t\t\t\t\t$this->getStartColor()->applyFromArray($pStyles['color']);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Invalid style array passed.\");\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Fill Type\n\t *\n\t * @return string\n\t */\n\tpublic function getFillType() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getFillType();\n\t\t}\n\t\treturn $this->_fillType;\n\t}\n\n\t/**\n\t * Set Fill Type\n\t *\n\t * @param string $pValue\tPHPExcel_Style_Fill fill type\n\t * @return PHPExcel_Style_Fill\n\t */\n\tpublic function setFillType($pValue = PHPExcel_Style_Fill::FILL_NONE) {\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('type' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_fillType = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Rotation\n\t *\n\t * @return double\n\t */\n\tpublic function getRotation() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getRotation();\n\t\t}\n\t\treturn $this->_rotation;\n\t}\n\n\t/**\n\t * Set Rotation\n\t *\n\t * @param double $pValue\n\t * @return PHPExcel_Style_Fill\n\t */\n\tpublic function setRotation($pValue = 0) {\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('rotation' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_rotation = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Start Color\n\t *\n\t * @return PHPExcel_Style_Color\n\t */\n\tpublic function getStartColor() {\n\t\treturn $this->_startColor;\n\t}\n\n\t/**\n\t * Set Start Color\n\t *\n\t * @param\tPHPExcel_Style_Color $pValue\n\t * @throws\tPHPExcel_Exception\n\t * @return PHPExcel_Style_Fill\n\t */\n\tpublic function setStartColor(PHPExcel_Style_Color $pValue = null) {\n\t\t// make sure parameter is a real color and not a supervisor\n\t\t$color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;\n\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStartColor()->getStyleArray(array('argb' => $color->getARGB()));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_startColor = $color;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get End Color\n\t *\n\t * @return PHPExcel_Style_Color\n\t */\n\tpublic function getEndColor() {\n\t\treturn $this->_endColor;\n\t}\n\n\t/**\n\t * Set End Color\n\t *\n\t * @param\tPHPExcel_Style_Color $pValue\n\t * @throws\tPHPExcel_Exception\n\t * @return PHPExcel_Style_Fill\n\t */\n\tpublic function setEndColor(PHPExcel_Style_Color $pValue = null) {\n\t\t// make sure parameter is a real color and not a supervisor\n\t\t$color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;\n\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getEndColor()->getStyleArray(array('argb' => $color->getARGB()));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_endColor = $color;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getHashCode();\n\t\t}\n\t\treturn md5(\n\t\t\t  $this->getFillType()\n\t\t\t. $this->getRotation()\n\t\t\t. $this->getStartColor()->getHashCode()\n\t\t\t. $this->getEndColor()->getHashCode()\n\t\t\t. __CLASS__\n\t\t);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Font.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Style_Font\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Style_Font extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable\n{\n\t/* Underline types */\n\tconst UNDERLINE_NONE\t\t\t\t\t= 'none';\n\tconst UNDERLINE_DOUBLE\t\t\t\t\t= 'double';\n\tconst UNDERLINE_DOUBLEACCOUNTING\t\t= 'doubleAccounting';\n\tconst UNDERLINE_SINGLE\t\t\t\t\t= 'single';\n\tconst UNDERLINE_SINGLEACCOUNTING\t\t= 'singleAccounting';\n\n\t/**\n\t * Font Name\n\t *\n\t * @var string\n\t */\n\tprotected $_name\t\t\t= 'Calibri';\n\n\t/**\n\t * Font Size\n\t *\n\t * @var float\n\t */\n\tprotected $_size\t\t\t= 11;\n\n\t/**\n\t * Bold\n\t *\n\t * @var boolean\n\t */\n\tprotected $_bold\t\t\t= FALSE;\n\n\t/**\n\t * Italic\n\t *\n\t * @var boolean\n\t */\n\tprotected $_italic\t\t= FALSE;\n\n\t/**\n\t * Superscript\n\t *\n\t * @var boolean\n\t */\n\tprotected $_superScript\t= FALSE;\n\n\t/**\n\t * Subscript\n\t *\n\t * @var boolean\n\t */\n\tprotected $_subScript\t\t= FALSE;\n\n\t/**\n\t * Underline\n\t *\n\t * @var string\n\t */\n\tprotected $_underline\t\t= self::UNDERLINE_NONE;\n\n\t/**\n\t * Strikethrough\n\t *\n\t * @var boolean\n\t */\n\tprotected $_strikethrough\t= FALSE;\n\n\t/**\n\t * Foreground color\n\t *\n\t * @var PHPExcel_Style_Color\n\t */\n\tprotected $_color;\n\n\t/**\n\t * Create a new PHPExcel_Style_Font\n\t *\n\t * @param\tboolean\t$isSupervisor\tFlag indicating if this is a supervisor or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t * @param\tboolean\t$isConditional\tFlag indicating if this is a conditional style or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t */\n\tpublic function __construct($isSupervisor = FALSE, $isConditional = FALSE)\n\t{\n\t\t// Supervisor?\n\t\tparent::__construct($isSupervisor);\n\n\t\t// Initialise values\n\t\tif ($isConditional) {\n\t\t\t$this->_name\t\t\t= NULL;\n\t\t\t$this->_size\t\t\t= NULL;\n\t\t\t$this->_bold\t\t\t= NULL;\n\t\t\t$this->_italic\t\t\t= NULL;\n\t\t\t$this->_superScript\t\t= NULL;\n\t\t\t$this->_subScript\t\t= NULL;\n\t\t\t$this->_underline\t\t= NULL;\n\t\t\t$this->_strikethrough\t= NULL;\n\t\t\t$this->_color\t\t\t= new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor, $isConditional);\n\t\t} else {\n\t\t\t$this->_color\t= new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK, $isSupervisor);\n\t\t}\n\t\t// bind parent if we are a supervisor\n\t\tif ($isSupervisor) {\n\t\t\t$this->_color->bindParent($this, '_color');\n\t\t}\n\t}\n\n\t/**\n\t * Get the shared style component for the currently active cell in currently active sheet.\n\t * Only used for style supervisor\n\t *\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function getSharedComponent()\n\t{\n\t\treturn $this->_parent->getSharedComponent()->getFont();\n\t}\n\n\t/**\n\t * Build style array from subcomponents\n\t *\n\t * @param array $array\n\t * @return array\n\t */\n\tpublic function getStyleArray($array)\n\t{\n\t\treturn array('font' => $array);\n\t}\n\n\t/**\n\t * Apply styles from array\n\t *\n\t * <code>\n\t * $objPHPExcel->getActiveSheet()->getStyle('B2')->getFont()->applyFromArray(\n\t *\t\tarray(\n\t *\t\t\t'name'\t\t=> 'Arial',\n\t *\t\t\t'bold'\t\t=> TRUE,\n\t *\t\t\t'italic'\t=> FALSE,\n\t *\t\t\t'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE,\n\t *\t\t\t'strike'\t=> FALSE,\n\t *\t\t\t'color'\t\t=> array(\n\t *\t\t\t\t'rgb' => '808080'\n\t *\t\t\t)\n\t *\t\t)\n\t * );\n\t * </code>\n\t *\n\t * @param\tarray\t$pStyles\tArray containing style information\n\t * @throws\tPHPExcel_Exception\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function applyFromArray($pStyles = null) {\n\t\tif (is_array($pStyles)) {\n\t\t\tif ($this->_isSupervisor) {\n\t\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));\n\t\t\t} else {\n\t\t\t\tif (array_key_exists('name', $pStyles)) {\n\t\t\t\t\t$this->setName($pStyles['name']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('bold', $pStyles)) {\n\t\t\t\t\t$this->setBold($pStyles['bold']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('italic', $pStyles)) {\n\t\t\t\t\t$this->setItalic($pStyles['italic']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('superScript', $pStyles)) {\n\t\t\t\t\t$this->setSuperScript($pStyles['superScript']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('subScript', $pStyles)) {\n\t\t\t\t\t$this->setSubScript($pStyles['subScript']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('underline', $pStyles)) {\n\t\t\t\t\t$this->setUnderline($pStyles['underline']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('strike', $pStyles)) {\n\t\t\t\t\t$this->setStrikethrough($pStyles['strike']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('color', $pStyles)) {\n\t\t\t\t\t$this->getColor()->applyFromArray($pStyles['color']);\n\t\t\t\t}\n\t\t\t\tif (array_key_exists('size', $pStyles)) {\n\t\t\t\t\t$this->setSize($pStyles['size']);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Invalid style array passed.\");\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Name\n\t *\n\t * @return string\n\t */\n\tpublic function getName() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getName();\n\t\t}\n\t\treturn $this->_name;\n\t}\n\n\t/**\n\t * Set Name\n\t *\n\t * @param string $pValue\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function setName($pValue = 'Calibri') {\n  \t\tif ($pValue == '') {\n\t\t\t$pValue = 'Calibri';\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('name' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_name = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Size\n\t *\n\t * @return double\n\t */\n\tpublic function getSize() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getSize();\n\t\t}\n\t\treturn $this->_size;\n\t}\n\n\t/**\n\t * Set Size\n\t *\n\t * @param double $pValue\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function setSize($pValue = 10) {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = 10;\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('size' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_size = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Bold\n\t *\n\t * @return boolean\n\t */\n\tpublic function getBold() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getBold();\n\t\t}\n\t\treturn $this->_bold;\n\t}\n\n\t/**\n\t * Set Bold\n\t *\n\t * @param boolean $pValue\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function setBold($pValue = false) {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = false;\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('bold' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_bold = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Italic\n\t *\n\t * @return boolean\n\t */\n\tpublic function getItalic() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getItalic();\n\t\t}\n\t\treturn $this->_italic;\n\t}\n\n\t/**\n\t * Set Italic\n\t *\n\t * @param boolean $pValue\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function setItalic($pValue = false) {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = false;\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('italic' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_italic = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get SuperScript\n\t *\n\t * @return boolean\n\t */\n\tpublic function getSuperScript() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getSuperScript();\n\t\t}\n\t\treturn $this->_superScript;\n\t}\n\n\t/**\n\t * Set SuperScript\n\t *\n\t * @param boolean $pValue\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function setSuperScript($pValue = false) {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = false;\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('superScript' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_superScript = $pValue;\n\t\t\t$this->_subScript = !$pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t\t/**\n\t * Get SubScript\n\t *\n\t * @return boolean\n\t */\n\tpublic function getSubScript() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getSubScript();\n\t\t}\n\t\treturn $this->_subScript;\n\t}\n\n\t/**\n\t * Set SubScript\n\t *\n\t * @param boolean $pValue\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function setSubScript($pValue = false) {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = false;\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('subScript' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_subScript = $pValue;\n\t\t\t$this->_superScript = !$pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Underline\n\t *\n\t * @return string\n\t */\n\tpublic function getUnderline() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getUnderline();\n\t\t}\n\t\treturn $this->_underline;\n\t}\n\n\t/**\n\t * Set Underline\n\t *\n\t * @param string|boolean $pValue\tPHPExcel_Style_Font underline type\n\t *\t\t\t\t\t\t\t\t\tIf a boolean is passed, then TRUE equates to UNDERLINE_SINGLE,\n\t *\t\t\t\t\t\t\t\t\t\tfalse equates to UNDERLINE_NONE\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function setUnderline($pValue = self::UNDERLINE_NONE) {\n\t\tif (is_bool($pValue)) {\n\t\t\t$pValue = ($pValue) ? self::UNDERLINE_SINGLE : self::UNDERLINE_NONE;\n\t\t} elseif ($pValue == '') {\n\t\t\t$pValue = self::UNDERLINE_NONE;\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('underline' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_underline = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Strikethrough\n\t *\n\t * @return boolean\n\t */\n\tpublic function getStrikethrough() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getStrikethrough();\n\t\t}\n\t\treturn $this->_strikethrough;\n\t}\n\n\t/**\n\t * Set Strikethrough\n\t *\n\t * @param boolean $pValue\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function setStrikethrough($pValue = false) {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = false;\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('strike' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_strikethrough = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Color\n\t *\n\t * @return PHPExcel_Style_Color\n\t */\n\tpublic function getColor() {\n\t\treturn $this->_color;\n\t}\n\n\t/**\n\t * Set Color\n\t *\n\t * @param\tPHPExcel_Style_Color $pValue\n\t * @throws\tPHPExcel_Exception\n\t * @return PHPExcel_Style_Font\n\t */\n\tpublic function setColor(PHPExcel_Style_Color $pValue = null) {\n\t\t// make sure parameter is a real color and not a supervisor\n\t\t$color = $pValue->getIsSupervisor() ? $pValue->getSharedComponent() : $pValue;\n\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getColor()->getStyleArray(array('argb' => $color->getARGB()));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_color = $color;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getHashCode();\n\t\t}\n\t\treturn md5(\n\t\t\t  $this->_name\n\t\t\t. $this->_size\n\t\t\t. ($this->_bold ? 't' : 'f')\n\t\t\t. ($this->_italic ? 't' : 'f')\n\t\t\t. ($this->_superScript ? 't' : 'f')\n\t\t\t. ($this->_subScript ? 't' : 'f')\n\t\t\t. $this->_underline\n\t\t\t. ($this->_strikethrough ? 't' : 'f')\n\t\t\t. $this->_color->getHashCode()\n\t\t\t. __CLASS__\n\t\t);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/NumberFormat.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Style_NumberFormat\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Style_NumberFormat extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable\n{\n\t/* Pre-defined formats */\n\tconst FORMAT_GENERAL\t\t\t\t\t= 'General';\n\n\tconst FORMAT_TEXT\t\t\t\t\t\t= '@';\n\n\tconst FORMAT_NUMBER\t\t\t\t\t\t= '0';\n\tconst FORMAT_NUMBER_00\t\t\t\t\t= '0.00';\n\tconst FORMAT_NUMBER_COMMA_SEPARATED1\t= '#,##0.00';\n\tconst FORMAT_NUMBER_COMMA_SEPARATED2\t= '#,##0.00_-';\n\n\tconst FORMAT_PERCENTAGE\t\t\t\t\t= '0%';\n\tconst FORMAT_PERCENTAGE_00\t\t\t\t= '0.00%';\n\n\tconst FORMAT_DATE_YYYYMMDD2\t\t\t\t= 'yyyy-mm-dd';\n\tconst FORMAT_DATE_YYYYMMDD\t\t\t\t= 'yy-mm-dd';\n\tconst FORMAT_DATE_DDMMYYYY\t\t\t\t= 'dd/mm/yy';\n\tconst FORMAT_DATE_DMYSLASH\t\t\t\t= 'd/m/y';\n\tconst FORMAT_DATE_DMYMINUS\t\t\t\t= 'd-m-y';\n\tconst FORMAT_DATE_DMMINUS\t\t\t\t= 'd-m';\n\tconst FORMAT_DATE_MYMINUS\t\t\t\t= 'm-y';\n\tconst FORMAT_DATE_XLSX14\t\t\t\t= 'mm-dd-yy';\n\tconst FORMAT_DATE_XLSX15\t\t\t\t= 'd-mmm-yy';\n\tconst FORMAT_DATE_XLSX16\t\t\t\t= 'd-mmm';\n\tconst FORMAT_DATE_XLSX17\t\t\t\t= 'mmm-yy';\n\tconst FORMAT_DATE_XLSX22\t\t\t\t= 'm/d/yy h:mm';\n\tconst FORMAT_DATE_DATETIME\t\t\t\t= 'd/m/y h:mm';\n\tconst FORMAT_DATE_TIME1\t\t\t\t\t= 'h:mm AM/PM';\n\tconst FORMAT_DATE_TIME2\t\t\t\t\t= 'h:mm:ss AM/PM';\n\tconst FORMAT_DATE_TIME3\t\t\t\t\t= 'h:mm';\n\tconst FORMAT_DATE_TIME4\t\t\t\t\t= 'h:mm:ss';\n\tconst FORMAT_DATE_TIME5\t\t\t\t\t= 'mm:ss';\n\tconst FORMAT_DATE_TIME6\t\t\t\t\t= 'h:mm:ss';\n\tconst FORMAT_DATE_TIME7\t\t\t\t\t= 'i:s.S';\n\tconst FORMAT_DATE_TIME8\t\t\t\t\t= 'h:mm:ss;@';\n\tconst FORMAT_DATE_YYYYMMDDSLASH\t\t\t= 'yy/mm/dd;@';\n\n\tconst FORMAT_CURRENCY_USD_SIMPLE\t\t= '\"$\"#,##0.00_-';\n\tconst FORMAT_CURRENCY_USD\t\t\t\t= '$#,##0_-';\n\tconst FORMAT_CURRENCY_EUR_SIMPLE\t\t= '[$EUR ]#,##0.00_-';\n\n\t/**\n\t * Excel built-in number formats\n\t *\n\t * @var array\n\t */\n\tprotected static $_builtInFormats;\n\n\t/**\n\t * Excel built-in number formats (flipped, for faster lookups)\n\t *\n\t * @var array\n\t */\n\tprotected static $_flippedBuiltInFormats;\n\n\t/**\n\t * Format Code\n\t *\n\t * @var string\n\t */\n\tprotected $_formatCode\t=\tPHPExcel_Style_NumberFormat::FORMAT_GENERAL;\n\n\t/**\n\t * Built-in format Code\n\t *\n\t * @var string\n\t */\n\tprotected $_builtInFormatCode\t= 0;\n\n\t/**\n\t * Create a new PHPExcel_Style_NumberFormat\n\t *\n\t * @param\tboolean\t$isSupervisor\tFlag indicating if this is a supervisor or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t * @param\tboolean\t$isConditional\tFlag indicating if this is a conditional style or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t */\n\tpublic function __construct($isSupervisor = FALSE, $isConditional = FALSE)\n\t{\n\t\t// Supervisor?\n\t\tparent::__construct($isSupervisor);\n\n\t\tif ($isConditional) {\n\t\t\t$this->_formatCode = NULL;\n\t\t\t$this->_builtInFormatCode = FALSE;\n\t\t}\n\t}\n\n\t/**\n\t * Get the shared style component for the currently active cell in currently active sheet.\n\t * Only used for style supervisor\n\t *\n\t * @return PHPExcel_Style_NumberFormat\n\t */\n\tpublic function getSharedComponent()\n\t{\n\t\treturn $this->_parent->getSharedComponent()->getNumberFormat();\n\t}\n\n\t/**\n\t * Build style array from subcomponents\n\t *\n\t * @param array $array\n\t * @return array\n\t */\n\tpublic function getStyleArray($array)\n\t{\n\t\treturn array('numberformat' => $array);\n\t}\n\n\t/**\n\t * Apply styles from array\n\t *\n\t * <code>\n\t * $objPHPExcel->getActiveSheet()->getStyle('B2')->getNumberFormat()->applyFromArray(\n\t *\t\tarray(\n\t *\t\t\t'code' => PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE\n\t *\t\t)\n\t * );\n\t * </code>\n\t *\n\t * @param\tarray\t$pStyles\tArray containing style information\n\t * @throws\tPHPExcel_Exception\n\t * @return PHPExcel_Style_NumberFormat\n\t */\n\tpublic function applyFromArray($pStyles = null)\n\t{\n\t\tif (is_array($pStyles)) {\n\t\t\tif ($this->_isSupervisor) {\n\t\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));\n\t\t\t} else {\n\t\t\t\tif (array_key_exists('code', $pStyles)) {\n\t\t\t\t\t$this->setFormatCode($pStyles['code']);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Invalid style array passed.\");\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Format Code\n\t *\n\t * @return string\n\t */\n\tpublic function getFormatCode()\n\t{\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getFormatCode();\n\t\t}\n\t\tif ($this->_builtInFormatCode !== false)\n\t\t{\n\t\t\treturn self::builtInFormatCode($this->_builtInFormatCode);\n\t\t}\n\t\treturn $this->_formatCode;\n\t}\n\n\t/**\n\t * Set Format Code\n\t *\n\t * @param string $pValue\n\t * @return PHPExcel_Style_NumberFormat\n\t */\n\tpublic function setFormatCode($pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL)\n\t{\n\t\tif ($pValue == '') {\n\t\t\t$pValue = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;\n\t\t}\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('code' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_formatCode = $pValue;\n\t\t\t$this->_builtInFormatCode = self::builtInFormatCodeIndex($pValue);\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Built-In Format Code\n\t *\n\t * @return int\n\t */\n\tpublic function getBuiltInFormatCode()\n\t{\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getBuiltInFormatCode();\n\t\t}\n\t\treturn $this->_builtInFormatCode;\n\t}\n\n\t/**\n\t * Set Built-In Format Code\n\t *\n\t * @param int $pValue\n\t * @return PHPExcel_Style_NumberFormat\n\t */\n\tpublic function setBuiltInFormatCode($pValue = 0)\n\t{\n\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('code' => self::builtInFormatCode($pValue)));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_builtInFormatCode = $pValue;\n\t\t\t$this->_formatCode = self::builtInFormatCode($pValue);\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Fill built-in format codes\n\t */\n\tprivate static function fillBuiltInFormatCodes()\n\t{\n\t\t// Built-in format codes\n\t\tif (is_null(self::$_builtInFormats)) {\n\t\t\tself::$_builtInFormats = array();\n\n\t\t\t// General\n\t\t\tself::$_builtInFormats[0] = PHPExcel_Style_NumberFormat::FORMAT_GENERAL;\n\t\t\tself::$_builtInFormats[1] = '0';\n\t\t\tself::$_builtInFormats[2] = '0.00';\n\t\t\tself::$_builtInFormats[3] = '#,##0';\n\t\t\tself::$_builtInFormats[4] = '#,##0.00';\n\n\t\t\tself::$_builtInFormats[9] = '0%';\n\t\t\tself::$_builtInFormats[10] = '0.00%';\n\t\t\tself::$_builtInFormats[11] = '0.00E+00';\n\t\t\tself::$_builtInFormats[12] = '# ?/?';\n\t\t\tself::$_builtInFormats[13] = '# ??/??';\n\t\t\tself::$_builtInFormats[14] = 'mm-dd-yy';\n\t\t\tself::$_builtInFormats[15] = 'd-mmm-yy';\n\t\t\tself::$_builtInFormats[16] = 'd-mmm';\n\t\t\tself::$_builtInFormats[17] = 'mmm-yy';\n\t\t\tself::$_builtInFormats[18] = 'h:mm AM/PM';\n\t\t\tself::$_builtInFormats[19] = 'h:mm:ss AM/PM';\n\t\t\tself::$_builtInFormats[20] = 'h:mm';\n\t\t\tself::$_builtInFormats[21] = 'h:mm:ss';\n\t\t\tself::$_builtInFormats[22] = 'm/d/yy h:mm';\n\n\t\t\tself::$_builtInFormats[37] = '#,##0 ;(#,##0)';\n\t\t\tself::$_builtInFormats[38] = '#,##0 ;[Red](#,##0)';\n\t\t\tself::$_builtInFormats[39] = '#,##0.00;(#,##0.00)';\n\t\t\tself::$_builtInFormats[40] = '#,##0.00;[Red](#,##0.00)';\n\n\t\t\tself::$_builtInFormats[44] = '_(\"$\"* #,##0.00_);_(\"$\"* \\(#,##0.00\\);_(\"$\"* \"-\"??_);_(@_)';\n\t\t\tself::$_builtInFormats[45] = 'mm:ss';\n\t\t\tself::$_builtInFormats[46] = '[h]:mm:ss';\n\t\t\tself::$_builtInFormats[47] = 'mmss.0';\n\t\t\tself::$_builtInFormats[48] = '##0.0E+0';\n\t\t\tself::$_builtInFormats[49] = '@';\n\n\t\t\t// CHT\n\t\t\tself::$_builtInFormats[27] = '[$-404]e/m/d';\n\t\t\tself::$_builtInFormats[30] = 'm/d/yy';\n\t\t\tself::$_builtInFormats[36] = '[$-404]e/m/d';\n\t\t\tself::$_builtInFormats[50] = '[$-404]e/m/d';\n\t\t\tself::$_builtInFormats[57] = '[$-404]e/m/d';\n\n\t\t\t// THA\n\t\t\tself::$_builtInFormats[59] = 't0';\n\t\t\tself::$_builtInFormats[60] = 't0.00';\n\t\t\tself::$_builtInFormats[61] = 't#,##0';\n\t\t\tself::$_builtInFormats[62] = 't#,##0.00';\n\t\t\tself::$_builtInFormats[67] = 't0%';\n\t\t\tself::$_builtInFormats[68] = 't0.00%';\n\t\t\tself::$_builtInFormats[69] = 't# ?/?';\n\t\t\tself::$_builtInFormats[70] = 't# ??/??';\n\n\t\t\t// Flip array (for faster lookups)\n\t\t\tself::$_flippedBuiltInFormats = array_flip(self::$_builtInFormats);\n\t\t}\n\t}\n\n\t/**\n\t * Get built-in format code\n\t *\n\t * @param\tint\t\t$pIndex\n\t * @return\tstring\n\t */\n\tpublic static function builtInFormatCode($pIndex)\n\t{\n\t\t// Clean parameter\n\t\t$pIndex = intval($pIndex);\n\n\t\t// Ensure built-in format codes are available\n\t\tself::fillBuiltInFormatCodes();\n\n\t\t// Lookup format code\n\t\tif (isset(self::$_builtInFormats[$pIndex])) {\n\t\t\treturn self::$_builtInFormats[$pIndex];\n\t\t}\n\n\t\treturn '';\n\t}\n\n\t/**\n\t * Get built-in format code index\n\t *\n\t * @param\tstring\t\t$formatCode\n\t * @return\tint|boolean\n\t */\n\tpublic static function builtInFormatCodeIndex($formatCode)\n\t{\n\t\t// Ensure built-in format codes are available\n\t\tself::fillBuiltInFormatCodes();\n\n\t\t// Lookup format code\n\t\tif (isset(self::$_flippedBuiltInFormats[$formatCode])) {\n\t\t\treturn self::$_flippedBuiltInFormats[$formatCode];\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode()\n\t{\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getHashCode();\n\t\t}\n\t\treturn md5(\n\t\t\t  $this->_formatCode\n\t\t\t. $this->_builtInFormatCode\n\t\t\t. __CLASS__\n\t\t);\n\t}\n\n\t/**\n\t * Search/replace values to convert Excel date/time format masks to PHP format masks\n\t *\n\t * @var array\n\t */\n\tprivate static $_dateFormatReplacements = array(\n\t\t\t// first remove escapes related to non-format characters\n\t\t\t'\\\\'\t=> '',\n\t\t\t//\t12-hour suffix\n\t\t\t'am/pm'\t=> 'A',\n\t\t\t//\t4-digit year\n\t\t\t'e'\t=> 'Y',\n\t\t\t'yyyy'\t=> 'Y',\n\t\t\t//\t2-digit year\n\t\t\t'yy'\t=> 'y',\n\t\t\t//\tfirst letter of month - no php equivalent\n\t\t\t'mmmmm'\t=> 'M',\n\t\t\t//\tfull month name\n\t\t\t'mmmm'\t=> 'F',\n\t\t\t//\tshort month name\n\t\t\t'mmm'\t=> 'M',\n\t\t\t//\tmm is minutes if time, but can also be month w/leading zero\n\t\t\t//\tso we try to identify times be the inclusion of a : separator in the mask\n\t\t\t//\tIt isn't perfect, but the best way I know how\n\t\t\t':mm'\t=> ':i',\n\t\t\t'mm:'\t=> 'i:',\n\t\t\t//\tmonth leading zero\n\t\t\t'mm'\t=> 'm',\n\t\t\t//\tmonth no leading zero\n\t\t\t'm'\t\t=> 'n',\n\t\t\t//\tfull day of week name\n\t\t\t'dddd'\t=> 'l',\n\t\t\t//\tshort day of week name\n\t\t\t'ddd'\t=> 'D',\n\t\t\t//\tdays leading zero\n\t\t\t'dd'\t=> 'd',\n\t\t\t//\tdays no leading zero\n\t\t\t'd'\t\t=> 'j',\n\t\t\t//\tseconds\n\t\t\t'ss'\t=> 's',\n\t\t\t//\tfractional seconds - no php equivalent\n\t\t\t'.s'\t=> ''\n\t\t);\n\t/**\n\t * Search/replace values to convert Excel date/time format masks hours to PHP format masks (24 hr clock)\n\t *\n\t * @var array\n\t */\n\tprivate static $_dateFormatReplacements24 = array(\n\t\t\t'hh'\t=> 'H',\n\t\t\t'h'\t\t=> 'G'\n\t\t);\n\t/**\n\t * Search/replace values to convert Excel date/time format masks hours to PHP format masks (12 hr clock)\n\t *\n\t * @var array\n\t */\n\tprivate static $_dateFormatReplacements12 = array(\n\t\t\t'hh'\t=> 'h',\n\t\t\t'h'\t\t=> 'g'\n\t\t);\n\n\tprivate static function _formatAsDate(&$value, &$format)\n\t{\n\t\t// dvc: convert Excel formats to PHP date formats\n\n\t\t// strip off first part containing e.g. [$-F800] or [$USD-409]\n\t\t// general syntax: [$<Currency string>-<language info>]\n\t\t// language info is in hexadecimal\n\t\t$format = preg_replace('/^(\\[\\$[A-Z]*-[0-9A-F]*\\])/i', '', $format);\n\n\t\t// OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case\n\t\t$format = strtolower($format);\n\n\t\t$format = strtr($format,self::$_dateFormatReplacements);\n\t\tif (!strpos($format,'A')) {\t// 24-hour time format\n\t\t\t$format = strtr($format,self::$_dateFormatReplacements24);\n\t\t} else {\t\t\t\t\t// 12-hour time format\n\t\t\t$format = strtr($format,self::$_dateFormatReplacements12);\n\t\t}\n\n\t\t$dateObj = PHPExcel_Shared_Date::ExcelToPHPObject($value);\n\t\t$value = $dateObj->format($format);\n\t}\n\n\tprivate static function _formatAsPercentage(&$value, &$format)\n\t{\n\t\tif ($format === self::FORMAT_PERCENTAGE) {\n\t\t\t$value = round( (100 * $value), 0) . '%';\n\t\t} else {\n\t\t\tif (preg_match('/\\.[#0]+/i', $format, $m)) {\n\t\t\t\t$s = substr($m[0], 0, 1) . (strlen($m[0]) - 1);\n\t\t\t\t$format = str_replace($m[0], $s, $format);\n\t\t\t}\n\t\t\tif (preg_match('/^[#0]+/', $format, $m)) {\n\t\t\t\t$format = str_replace($m[0], strlen($m[0]), $format);\n\t\t\t}\n\t\t\t$format = '%' . str_replace('%', 'f%%', $format);\n\n\t\t\t$value = sprintf($format, 100 * $value);\n\t\t}\n\t}\n\n\tprivate static function _formatAsFraction(&$value, &$format)\n\t{\n\t\t$sign = ($value < 0) ? '-' : '';\n\n\t\t$integerPart = floor(abs($value));\n\t\t$decimalPart = trim(fmod(abs($value),1),'0.');\n\t\t$decimalLength = strlen($decimalPart);\n\t\t$decimalDivisor = pow(10,$decimalLength);\n\n\t\t$GCD = PHPExcel_Calculation_MathTrig::GCD($decimalPart,$decimalDivisor);\n\n\t\t$adjustedDecimalPart = $decimalPart/$GCD;\n\t\t$adjustedDecimalDivisor = $decimalDivisor/$GCD;\n\n\t\tif ((strpos($format,'0') !== false) || (strpos($format,'#') !== false) || (substr($format,0,3) == '? ?')) {\n\t\t\tif ($integerPart == 0) {\n\t\t\t\t$integerPart = '';\n\t\t\t}\n\t\t\t$value = \"$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor\";\n\t\t} else {\n\t\t\t$adjustedDecimalPart += $integerPart * $adjustedDecimalDivisor;\n\t\t\t$value = \"$sign$adjustedDecimalPart/$adjustedDecimalDivisor\";\n\t\t}\n\t}\n\n\tprivate static function _complexNumberFormatMask($number, $mask, $level = 0) {\n        $sign = ($number < 0.0);\n        $number = abs($number);\n\t\tif (strpos($mask,'.') !== false) {\n\t\t\t$numbers = explode('.', $number . '.0');\n\t\t\t$masks = explode('.', $mask . '.0');\n\t\t\t$result1 = self::_complexNumberFormatMask($numbers[0], $masks[0], 1);\n\t\t\t$result2 = strrev(self::_complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1]), 1));\n\t\t\treturn (($sign) ? '-' : '') . $result1 . '.' . $result2;\n\t\t}\n\n\t\t$r = preg_match_all('/0+/', $mask, $result, PREG_OFFSET_CAPTURE);\n\t\tif ($r > 1) {\n\t\t\t$result = array_reverse($result[0]);\n\n\t\t\tforeach($result as $block) {\n\t\t\t\t$divisor = 1 . $block[0];\n\t\t\t\t$size = strlen($block[0]);\n\t\t\t\t$offset = $block[1];\n\n\t\t\t\t$blockValue = sprintf(\n\t\t\t\t\t'%0' . $size . 'd',\n\t\t\t\t\tfmod($number, $divisor)\n\t\t\t\t);\n\t\t\t\t$number = floor($number / $divisor);\n\t\t\t\t$mask = substr_replace($mask, $blockValue, $offset, $size);\n\t\t\t}\n\t\t\tif ($number > 0) {\n\t\t\t\t$mask = substr_replace($mask, $number, $offset, 0);\n\t\t\t}\n\t\t\t$result = $mask;\n\t\t} else {\n\t\t\t$result = $number;\n\t\t}\n\n\t\treturn (($sign) ? '-' : '') . $result;\n\t}\n\n\t/**\n\t * Convert a value in a pre-defined format to a PHP string\n\t *\n\t * @param mixed\t$value\t\tValue to format\n\t * @param string\t$format\t\tFormat code\n\t * @param array\t\t$callBack\tCallback function for additional formatting of string\n\t * @return string\tFormatted string\n\t */\n\tpublic static function toFormattedString($value = '0', $format = PHPExcel_Style_NumberFormat::FORMAT_GENERAL, $callBack = null)\n\t{\n\t\t// For now we do not treat strings although section 4 of a format code affects strings\n\t\tif (!is_numeric($value)) return $value;\n\n\t\t// For 'General' format code, we just pass the value although this is not entirely the way Excel does it,\n\t\t// it seems to round numbers to a total of 10 digits.\n\t\tif (($format === PHPExcel_Style_NumberFormat::FORMAT_GENERAL) || ($format === PHPExcel_Style_NumberFormat::FORMAT_TEXT)) {\n\t\t\treturn $value;\n\t\t}\n\n\t\t// Get the sections, there can be up to four sections\n\t\t$sections = explode(';', $format);\n\n\t\t// Fetch the relevant section depending on whether number is positive, negative, or zero?\n\t\t// Text not supported yet.\n\t\t// Here is how the sections apply to various values in Excel:\n\t\t//   1 section:   [POSITIVE/NEGATIVE/ZERO/TEXT]\n\t\t//   2 sections:  [POSITIVE/ZERO/TEXT] [NEGATIVE]\n\t\t//   3 sections:  [POSITIVE/TEXT] [NEGATIVE] [ZERO]\n\t\t//   4 sections:  [POSITIVE] [NEGATIVE] [ZERO] [TEXT]\n\t\tswitch (count($sections)) {\n\t\t\tcase 1:\n\t\t\t\t$format = $sections[0];\n\t\t\t\tbreak;\n\n\t\t\tcase 2:\n\t\t\t\t$format = ($value >= 0) ? $sections[0] : $sections[1];\n\t\t\t\t$value = abs($value); // Use the absolute value\n\t\t\t\tbreak;\n\n\t\t\tcase 3:\n\t\t\t\t$format = ($value > 0) ?\n\t\t\t\t\t$sections[0] : ( ($value < 0) ?\n\t\t\t\t\t\t$sections[1] : $sections[2]);\n\t\t\t\t$value = abs($value); // Use the absolute value\n\t\t\t\tbreak;\n\n\t\t\tcase 4:\n\t\t\t\t$format = ($value > 0) ?\n\t\t\t\t\t$sections[0] : ( ($value < 0) ?\n\t\t\t\t\t\t$sections[1] : $sections[2]);\n\t\t\t\t$value = abs($value); // Use the absolute value\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\t\t\t\t// something is wrong, just use first section\n\t\t\t\t$format = $sections[0];\n\t\t\t\tbreak;\n\t\t}\n\n\t\t// Save format with color information for later use below\n\t\t$formatColor = $format;\n\n\t\t// Strip color information\n\t\t$color_regex = '/^\\\\[[a-zA-Z]+\\\\]/';\n\t\t$format = preg_replace($color_regex, '', $format);\n\n\t\t// Let's begin inspecting the format and converting the value to a formatted string\n\t\tif (preg_match('/^(\\[\\$[A-Z]*-[0-9A-F]*\\])*[hmsdy]/i', $format)) { // datetime format\n\t\t\tself::_formatAsDate($value, $format);\n\t\t} else if (preg_match('/%$/', $format)) { // % number format\n\t\t\tself::_formatAsPercentage($value, $format);\n\t\t} else {\n\t\t\tif ($format === self::FORMAT_CURRENCY_EUR_SIMPLE) {\n\t\t\t\t$value = 'EUR ' . sprintf('%1.2f', $value);\n\t\t\t} else {\n\t\t\t\t// In Excel formats, \"_\" is used to add spacing, which we can't do in HTML\n\t\t\t\t$format = preg_replace('/_./', '', $format);\n\n\t\t\t\t// Some non-number characters are escaped with \\, which we don't need\n\t\t\t\t$format = preg_replace(\"/\\\\\\\\/\", '', $format);\n//              Handle escaped characters, such as \\\" to display a literal \" or \\\\ to display a literal \\\n//              $format = preg_replace('/(?<!\\\\\\\\)\\\"/', '', $format);\n//\t\t\t\t$format = str_replace(array('\\\\\"', '*'), array('\"', ''), $format);\n\n\t\t\t\t// Some non-number strings are quoted, so we'll get rid of the quotes, likewise any positional * symbols\n\t\t\t\t$format = str_replace(array('\"', '*'), '', $format);\n\n\t\t\t\t// Find out if we need thousands separator\n\t\t\t\t// This is indicated by a comma enclosed by a digit placeholder:\n\t\t\t\t//\t\t#,#   or   0,0\n\t\t\t\t$useThousands = preg_match('/(#,#|0,0)/', $format);\n\t\t\t\tif ($useThousands) {\n\t\t\t\t\t$format = preg_replace('/0,0/', '00', $format);\n\t\t\t\t\t$format = preg_replace('/#,#/', '##', $format);\n\t\t\t\t}\n\n\t\t\t\t// Scale thousands, millions,...\n\t\t\t\t// This is indicated by a number of commas after a digit placeholder:\n\t\t\t\t//\t\t#,   or\t0.0,,\n\t\t\t\t$scale = 1; // same as no scale\n\t\t\t\t$matches = array();\n\t\t\t\tif (preg_match('/(#|0)(,+)/', $format, $matches)) {\n\t\t\t\t\t$scale = pow(1000, strlen($matches[2]));\n\n\t\t\t\t\t// strip the commas\n\t\t\t\t\t$format = preg_replace('/0,+/', '0', $format);\n\t\t\t\t\t$format = preg_replace('/#,+/', '#', $format);\n\t\t\t\t}\n\n\t\t\t\tif (preg_match('/#?.*\\?\\/\\?/', $format, $m)) {\n\t\t\t\t\t//echo 'Format mask is fractional '.$format.' <br />';\n\t\t\t\t\tif ($value != (int)$value) {\n\t\t\t\t\t\tself::_formatAsFraction($value, $format);\n\t\t\t\t\t}\n\n\t\t\t\t} else {\n\t\t\t\t\t// Handle the number itself\n\n\t\t\t\t\t// scale number\n\t\t\t\t\t$value = $value / $scale;\n\n\t\t\t\t\t// Strip #\n\t\t\t\t\t$format = preg_replace('/\\\\#/', '0', $format);\n\n\t\t\t\t\t$n = \"/\\[[^\\]]+\\]/\";\n\t\t\t\t\t$m = preg_replace($n, '', $format);\n\t\t\t\t\t$number_regex = \"/(0+)(\\.?)(0*)/\";\n\t\t\t\t\tif (preg_match($number_regex, $m, $matches)) {\n\t\t\t\t\t\t$left = $matches[1];\n\t\t\t\t\t\t$dec = $matches[2];\n\t\t\t\t\t\t$right = $matches[3];\n\n\t\t\t\t\t\t// minimun width of formatted number (including dot)\n\t\t\t\t\t\t$minWidth = strlen($left) + strlen($dec) + strlen($right);\n\t\t\t\t\t\tif ($useThousands) {\n\t\t\t\t\t\t\t$value = number_format(\n\t\t\t\t\t\t\t\t\t\t$value\n\t\t\t\t\t\t\t\t\t\t, strlen($right)\n\t\t\t\t\t\t\t\t\t\t, PHPExcel_Shared_String::getDecimalSeparator()\n\t\t\t\t\t\t\t\t\t\t, PHPExcel_Shared_String::getThousandsSeparator()\n\t\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t$value = preg_replace($number_regex, $value, $format);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (preg_match('/[0#]E[+-]0/i', $format)) {\n\t\t\t\t\t\t\t\t//\tScientific format\n\t\t\t\t\t\t\t\t$value = sprintf('%5.2E', $value);\n\t\t\t\t\t\t\t} elseif (preg_match('/0([^\\d\\.]+)0/', $format)) {\n\t\t\t\t\t\t\t\t$value = self::_complexNumberFormatMask($value, $format);\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t$sprintf_pattern = \"%0$minWidth.\" . strlen($right) . \"f\";\n\t\t\t\t\t\t\t\t$value = sprintf($sprintf_pattern, $value);\n\t\t\t\t\t\t\t\t$value = preg_replace($number_regex, $value, $format);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (preg_match('/\\[\\$(.*)\\]/u', $format, $m)) {\n\t\t\t\t\t//\tCurrency or Accounting\n\t\t\t\t\t$currencyFormat = $m[0];\n\t\t\t\t\t$currencyCode = $m[1];\n\t\t\t\t\tlist($currencyCode) = explode('-',$currencyCode);\n\t\t\t\t\tif ($currencyCode == '') {\n\t\t\t\t\t\t$currencyCode = PHPExcel_Shared_String::getCurrencyCode();\n\t\t\t\t\t}\n\t\t\t\t\t$value = preg_replace('/\\[\\$([^\\]]*)\\]/u',$currencyCode,$value);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Additional formatting provided by callback function\n\t\tif ($callBack !== null) {\n\t\t\tlist($writerInstance, $function) = $callBack;\n\t\t\t$value = $writerInstance->$function($value, $formatColor);\n\t\t}\n\n\t\treturn $value;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Protection.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    1.4.5, 2007-08-23\n */\n\n\n/**\n * PHPExcel_Style_Protection\n *\n * @category   PHPExcel\n * @package    PHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Style_Protection extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable\n{\n\t/** Protection styles */\n\tconst PROTECTION_INHERIT\t\t= 'inherit';\n\tconst PROTECTION_PROTECTED\t\t= 'protected';\n\tconst PROTECTION_UNPROTECTED\t= 'unprotected';\n\n\t/**\n\t * Locked\n\t *\n\t * @var string\n\t */\n\tprotected $_locked;\n\n\t/**\n\t * Hidden\n\t *\n\t * @var string\n\t */\n\tprotected $_hidden;\n\n\t/**\n     * Create a new PHPExcel_Style_Protection\n\t *\n\t * @param\tboolean\t$isSupervisor\tFlag indicating if this is a supervisor or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t * @param\tboolean\t$isConditional\tFlag indicating if this is a conditional style or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n     */\n    public function __construct($isSupervisor = FALSE, $isConditional = FALSE)\n    {\n    \t// Supervisor?\n\t\tparent::__construct($isSupervisor);\n\n    \t// Initialise values\n\t\tif (!$isConditional) {\n\t    \t$this->_locked\t\t\t= self::PROTECTION_INHERIT;\n\t    \t$this->_hidden\t\t\t= self::PROTECTION_INHERIT;\n\t\t}\n    }\n\n\t/**\n\t * Get the shared style component for the currently active cell in currently active sheet.\n\t * Only used for style supervisor\n\t *\n\t * @return PHPExcel_Style_Protection\n\t */\n\tpublic function getSharedComponent()\n\t{\n\t\treturn $this->_parent->getSharedComponent()->getProtection();\n\t}\n\n\t/**\n\t * Build style array from subcomponents\n\t *\n\t * @param array $array\n\t * @return array\n\t */\n\tpublic function getStyleArray($array)\n\t{\n\t\treturn array('protection' => $array);\n\t}\n\n    /**\n     * Apply styles from array\n     *\n     * <code>\n     * $objPHPExcel->getActiveSheet()->getStyle('B2')->getLocked()->applyFromArray(\n     *\t\tarray(\n     *\t\t\t'locked' => TRUE,\n     *\t\t\t'hidden' => FALSE\n     *\t\t)\n     * );\n     * </code>\n     *\n     * @param\tarray\t$pStyles\tArray containing style information\n     * @throws\tPHPExcel_Exception\n     * @return PHPExcel_Style_Protection\n     */\n\tpublic function applyFromArray($pStyles = NULL) {\n\t\tif (is_array($pStyles)) {\n\t\t\tif ($this->_isSupervisor) {\n\t\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($this->getStyleArray($pStyles));\n\t\t\t} else {\n\t\t\t\tif (isset($pStyles['locked'])) {\n\t\t\t\t\t$this->setLocked($pStyles['locked']);\n\t\t\t\t}\n\t\t\t\tif (isset($pStyles['hidden'])) {\n\t\t\t\t\t$this->setHidden($pStyles['hidden']);\n\t\t\t\t}\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Invalid style array passed.\");\n\t\t}\n\t\treturn $this;\n\t}\n\n    /**\n     * Get locked\n     *\n     * @return string\n     */\n    public function getLocked() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getLocked();\n\t\t}\n    \treturn $this->_locked;\n    }\n\n    /**\n     * Set locked\n     *\n     * @param string $pValue\n     * @return PHPExcel_Style_Protection\n     */\n    public function setLocked($pValue = self::PROTECTION_INHERIT) {\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('locked' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_locked = $pValue;\n\t\t}\n\t\treturn $this;\n    }\n\n    /**\n     * Get hidden\n     *\n     * @return string\n     */\n    public function getHidden() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getHidden();\n\t\t}\n    \treturn $this->_hidden;\n    }\n\n    /**\n     * Set hidden\n     *\n     * @param string $pValue\n     * @return PHPExcel_Style_Protection\n     */\n    public function setHidden($pValue = self::PROTECTION_INHERIT) {\n\t\tif ($this->_isSupervisor) {\n\t\t\t$styleArray = $this->getStyleArray(array('hidden' => $pValue));\n\t\t\t$this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n\t\t} else {\n\t\t\t$this->_hidden = $pValue;\n\t\t}\n\t\treturn $this;\n    }\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n\t\tif ($this->_isSupervisor) {\n\t\t\treturn $this->getSharedComponent()->getHashCode();\n\t\t}\n    \treturn md5(\n    \t\t  $this->_locked\n    \t\t. $this->_hidden\n    \t\t. __CLASS__\n    \t);\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Style/Supervisor.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Style_Supervisor\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nabstract class PHPExcel_Style_Supervisor\n{\n\t/**\n\t * Supervisor?\n\t *\n\t * @var boolean\n\t */\n\tprotected $_isSupervisor;\n\n\t/**\n\t * Parent. Only used for supervisor\n\t *\n\t * @var PHPExcel_Style\n\t */\n\tprotected $_parent;\n\n\t/**\n\t * Create a new PHPExcel_Style_Alignment\n\t *\n\t * @param\tboolean\t$isSupervisor\tFlag indicating if this is a supervisor or not\n\t *\t\t\t\t\t\t\t\t\tLeave this value at default unless you understand exactly what\n\t *\t\t\t\t\t\t\t\t\t\tits ramifications are\n\t */\n\tpublic function __construct($isSupervisor = FALSE)\n\t{\n\t\t// Supervisor?\n\t\t$this->_isSupervisor = $isSupervisor;\n\t}\n\n\t/**\n\t * Bind parent. Only used for supervisor\n\t *\n\t * @param PHPExcel $parent\n\t * @return PHPExcel_Style_Supervisor\n\t */\n\tpublic function bindParent($parent, $parentPropertyName=NULL)\n\t{\n\t\t$this->_parent = $parent;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Is this a supervisor or a cell style component?\n\t *\n\t * @return boolean\n\t */\n\tpublic function getIsSupervisor()\n\t{\n\t\treturn $this->_isSupervisor;\n\t}\n\n\t/**\n\t * Get the currently active sheet. Only used for supervisor\n\t *\n\t * @return PHPExcel_Worksheet\n\t */\n\tpublic function getActiveSheet()\n\t{\n\t\treturn $this->_parent->getActiveSheet();\n\t}\n\n\t/**\n\t * Get the currently active cell coordinate in currently active sheet.\n\t * Only used for supervisor\n\t *\n\t * @return string E.g. 'A1'\n\t */\n\tpublic function getSelectedCells()\n\t{\n\t\treturn $this->getActiveSheet()->getSelectedCells();\n\t}\n\n\t/**\n\t * Get the currently active cell coordinate in currently active sheet.\n\t * Only used for supervisor\n\t *\n\t * @return string E.g. 'A1'\n\t */\n\tpublic function getActiveCell()\n\t{\n\t\treturn $this->getActiveSheet()->getActiveCell();\n\t}\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif ((is_object($value)) && ($key != '_parent')) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Style.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Style\n *\n * @category   PHPExcel\n * @package    PHPExcel_Style\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Style extends PHPExcel_Style_Supervisor implements PHPExcel_IComparable\n{\n    /**\n     * Font\n     *\n     * @var PHPExcel_Style_Font\n     */\n    protected $_font;\n\n    /**\n     * Fill\n     *\n     * @var PHPExcel_Style_Fill\n     */\n    protected $_fill;\n\n    /**\n     * Borders\n     *\n     * @var PHPExcel_Style_Borders\n     */\n    protected $_borders;\n\n    /**\n     * Alignment\n     *\n     * @var PHPExcel_Style_Alignment\n     */\n    protected $_alignment;\n\n    /**\n     * Number Format\n     *\n     * @var PHPExcel_Style_NumberFormat\n     */\n    protected $_numberFormat;\n\n    /**\n     * Conditional styles\n     *\n     * @var PHPExcel_Style_Conditional[]\n     */\n    protected $_conditionalStyles;\n\n    /**\n     * Protection\n     *\n     * @var PHPExcel_Style_Protection\n     */\n    protected $_protection;\n\n    /**\n     * Index of style in collection. Only used for real style.\n     *\n     * @var int\n     */\n    protected $_index;\n\n    /**\n     * Use Quote Prefix when displaying in cell editor. Only used for real style.\n     *\n     * @var boolean\n     */\n    protected $_quotePrefix = false;\n\n    /**\n     * Create a new PHPExcel_Style\n     *\n     * @param boolean $isSupervisor Flag indicating if this is a supervisor or not\n     * \t\tLeave this value at default unless you understand exactly what\n     *    its ramifications are\n     * @param boolean $isConditional Flag indicating if this is a conditional style or not\n     *   \tLeave this value at default unless you understand exactly what\n     *    its ramifications are\n     */\n    public function __construct($isSupervisor = false, $isConditional = false)\n    {\n        // Supervisor?\n        $this->_isSupervisor = $isSupervisor;\n\n        // Initialise values\n        $this->_conditionalStyles\t= array();\n        $this->_font              = new PHPExcel_Style_Font($isSupervisor, $isConditional);\n        $this->_fill              = new PHPExcel_Style_Fill($isSupervisor, $isConditional);\n        $this->_borders           = new PHPExcel_Style_Borders($isSupervisor, $isConditional);\n        $this->_alignment         = new PHPExcel_Style_Alignment($isSupervisor, $isConditional);\n        $this->_numberFormat      = new PHPExcel_Style_NumberFormat($isSupervisor, $isConditional);\n        $this->_protection        = new PHPExcel_Style_Protection($isSupervisor, $isConditional);\n\n        // bind parent if we are a supervisor\n        if ($isSupervisor) {\n            $this->_font->bindParent($this);\n            $this->_fill->bindParent($this);\n            $this->_borders->bindParent($this);\n            $this->_alignment->bindParent($this);\n            $this->_numberFormat->bindParent($this);\n            $this->_protection->bindParent($this);\n        }\n    }\n\n    /**\n     * Get the shared style component for the currently active cell in currently active sheet.\n     * Only used for style supervisor\n     *\n     * @return PHPExcel_Style\n     */\n    public function getSharedComponent()\n    {\n        $activeSheet = $this->getActiveSheet();\n        $selectedCell = $this->getActiveCell(); // e.g. 'A1'\n\n        if ($activeSheet->cellExists($selectedCell)) {\n            $xfIndex = $activeSheet->getCell($selectedCell)->getXfIndex();\n        } else {\n            $xfIndex = 0;\n        }\n\n        return $this->_parent->getCellXfByIndex($xfIndex);\n    }\n\n    /**\n     * Get parent. Only used for style supervisor\n     *\n     * @return PHPExcel\n     */\n    public function getParent()\n    {\n        return $this->_parent;\n    }\n\n\t/**\n\t * Build style array from subcomponents\n\t *\n\t * @param array $array\n\t * @return array\n\t */\n\tpublic function getStyleArray($array)\n\t{\n\t\treturn array('quotePrefix' => $array);\n\t}\n\n    /**\n     * Apply styles from array\n     *\n     * <code>\n     * $objPHPExcel->getActiveSheet()->getStyle('B2')->applyFromArray(\n     *         array(\n     *             'font'    => array(\n     *                 'name'      => 'Arial',\n     *                 'bold'      => true,\n     *                 'italic'    => false,\n     *                 'underline' => PHPExcel_Style_Font::UNDERLINE_DOUBLE,\n     *                 'strike'    => false,\n     *                 'color'     => array(\n     *                     'rgb' => '808080'\n     *                 )\n     *             ),\n     *             'borders' => array(\n     *                 'bottom'     => array(\n     *                     'style' => PHPExcel_Style_Border::BORDER_DASHDOT,\n     *                     'color' => array(\n     *                         'rgb' => '808080'\n     *                     )\n     *                 ),\n     *                 'top'     => array(\n     *                     'style' => PHPExcel_Style_Border::BORDER_DASHDOT,\n     *                     'color' => array(\n     *                         'rgb' => '808080'\n     *                     )\n     *                 )\n     *             ),\n     *             'quotePrefix'    => true\n     *         )\n     * );\n     * </code>\n     *\n     * @param    array    $pStyles    Array containing style information\n     * @param     boolean        $pAdvanced    Advanced mode for setting borders.\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Style\n     */\n    public function applyFromArray($pStyles = null, $pAdvanced = true)\n    {\n        if (is_array($pStyles)) {\n            if ($this->_isSupervisor) {\n\n                $pRange = $this->getSelectedCells();\n\n                // Uppercase coordinate\n                $pRange = strtoupper($pRange);\n\n                // Is it a cell range or a single cell?\n                if (strpos($pRange, ':') === false) {\n                    $rangeA = $pRange;\n                    $rangeB = $pRange;\n                } else {\n                    list($rangeA, $rangeB) = explode(':', $pRange);\n                }\n\n                // Calculate range outer borders\n                $rangeStart = PHPExcel_Cell::coordinateFromString($rangeA);\n                $rangeEnd     = PHPExcel_Cell::coordinateFromString($rangeB);\n\n                // Translate column into index\n                $rangeStart[0]    = PHPExcel_Cell::columnIndexFromString($rangeStart[0]) - 1;\n                $rangeEnd[0]    = PHPExcel_Cell::columnIndexFromString($rangeEnd[0]) - 1;\n\n                // Make sure we can loop upwards on rows and columns\n                if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {\n                    $tmp = $rangeStart;\n                    $rangeStart = $rangeEnd;\n                    $rangeEnd = $tmp;\n                }\n\n                // ADVANCED MODE:\n\n                if ($pAdvanced && isset($pStyles['borders'])) {\n\n                    // 'allborders' is a shorthand property for 'outline' and 'inside' and\n                    //        it applies to components that have not been set explicitly\n                    if (isset($pStyles['borders']['allborders'])) {\n                        foreach (array('outline', 'inside') as $component) {\n                            if (!isset($pStyles['borders'][$component])) {\n                                $pStyles['borders'][$component] = $pStyles['borders']['allborders'];\n                            }\n                        }\n                        unset($pStyles['borders']['allborders']); // not needed any more\n                    }\n\n                    // 'outline' is a shorthand property for 'top', 'right', 'bottom', 'left'\n                    //        it applies to components that have not been set explicitly\n                    if (isset($pStyles['borders']['outline'])) {\n                        foreach (array('top', 'right', 'bottom', 'left') as $component) {\n                            if (!isset($pStyles['borders'][$component])) {\n                                $pStyles['borders'][$component] = $pStyles['borders']['outline'];\n                            }\n                        }\n                        unset($pStyles['borders']['outline']); // not needed any more\n                    }\n\n                    // 'inside' is a shorthand property for 'vertical' and 'horizontal'\n                    //        it applies to components that have not been set explicitly\n                    if (isset($pStyles['borders']['inside'])) {\n                        foreach (array('vertical', 'horizontal') as $component) {\n                            if (!isset($pStyles['borders'][$component])) {\n                                $pStyles['borders'][$component] = $pStyles['borders']['inside'];\n                            }\n                        }\n                        unset($pStyles['borders']['inside']); // not needed any more\n                    }\n\n                    // width and height characteristics of selection, 1, 2, or 3 (for 3 or more)\n                    $xMax = min($rangeEnd[0] - $rangeStart[0] + 1, 3);\n                    $yMax = min($rangeEnd[1] - $rangeStart[1] + 1, 3);\n\n                    // loop through up to 3 x 3 = 9 regions\n                    for ($x = 1; $x <= $xMax; ++$x) {\n                        // start column index for region\n                        $colStart = ($x == 3) ?\n                            PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0])\n                                : PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $x - 1);\n\n                        // end column index for region\n                        $colEnd = ($x == 1) ?\n                            PHPExcel_Cell::stringFromColumnIndex($rangeStart[0])\n                                : PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] - $xMax + $x);\n\n                        for ($y = 1; $y <= $yMax; ++$y) {\n\n                            // which edges are touching the region\n                            $edges = array();\n\n                            // are we at left edge\n                            if ($x == 1) {\n                                $edges[] = 'left';\n                            }\n\n                            // are we at right edge\n                            if ($x == $xMax) {\n                                $edges[] = 'right';\n                            }\n\n                            // are we at top edge?\n                            if ($y == 1) {\n                                $edges[] = 'top';\n                            }\n\n                            // are we at bottom edge?\n                            if ($y == $yMax) {\n                                $edges[] = 'bottom';\n                            }\n\n                            // start row index for region\n                            $rowStart = ($y == 3) ?\n                                $rangeEnd[1] : $rangeStart[1] + $y - 1;\n\n                            // end row index for region\n                            $rowEnd = ($y == 1) ?\n                                $rangeStart[1] : $rangeEnd[1] - $yMax + $y;\n\n                            // build range for region\n                            $range = $colStart . $rowStart . ':' . $colEnd . $rowEnd;\n\n                            // retrieve relevant style array for region\n                            $regionStyles = $pStyles;\n                            unset($regionStyles['borders']['inside']);\n\n                            // what are the inner edges of the region when looking at the selection\n                            $innerEdges = array_diff( array('top', 'right', 'bottom', 'left'), $edges );\n\n                            // inner edges that are not touching the region should take the 'inside' border properties if they have been set\n                            foreach ($innerEdges as $innerEdge) {\n                                switch ($innerEdge) {\n                                    case 'top':\n                                    case 'bottom':\n                                        // should pick up 'horizontal' border property if set\n                                        if (isset($pStyles['borders']['horizontal'])) {\n                                            $regionStyles['borders'][$innerEdge] = $pStyles['borders']['horizontal'];\n                                        } else {\n                                            unset($regionStyles['borders'][$innerEdge]);\n                                        }\n                                        break;\n                                    case 'left':\n                                    case 'right':\n                                        // should pick up 'vertical' border property if set\n                                        if (isset($pStyles['borders']['vertical'])) {\n                                            $regionStyles['borders'][$innerEdge] = $pStyles['borders']['vertical'];\n                                        } else {\n                                            unset($regionStyles['borders'][$innerEdge]);\n                                        }\n                                        break;\n                                }\n                            }\n\n                            // apply region style to region by calling applyFromArray() in simple mode\n                            $this->getActiveSheet()->getStyle($range)->applyFromArray($regionStyles, false);\n                        }\n                    }\n                    return $this;\n                }\n\n                // SIMPLE MODE:\n\n                // Selection type, inspect\n                if (preg_match('/^[A-Z]+1:[A-Z]+1048576$/', $pRange)) {\n                    $selectionType = 'COLUMN';\n                } else if (preg_match('/^A[0-9]+:XFD[0-9]+$/', $pRange)) {\n                    $selectionType = 'ROW';\n                } else {\n                    $selectionType = 'CELL';\n                }\n\n                // First loop through columns, rows, or cells to find out which styles are affected by this operation\n                switch ($selectionType) {\n                    case 'COLUMN':\n                        $oldXfIndexes = array();\n                        for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {\n                            $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true;\n                        }\n                        break;\n\n                    case 'ROW':\n                        $oldXfIndexes = array();\n                        for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {\n                            if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() == null) {\n                                $oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style\n                            } else {\n                                $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true;\n                            }\n                        }\n                        break;\n\n                    case 'CELL':\n                        $oldXfIndexes = array();\n                        for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {\n                            for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {\n                                $oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col, $row)->getXfIndex()] = true;\n                            }\n                        }\n                        break;\n                }\n\n                // clone each of the affected styles, apply the style array, and add the new styles to the workbook\n                $workbook = $this->getActiveSheet()->getParent();\n                foreach ($oldXfIndexes as $oldXfIndex => $dummy) {\n                    $style = $workbook->getCellXfByIndex($oldXfIndex);\n                    $newStyle = clone $style;\n                    $newStyle->applyFromArray($pStyles);\n\n                    if ($existingStyle = $workbook->getCellXfByHashCode($newStyle->getHashCode())) {\n                        // there is already such cell Xf in our collection\n                        $newXfIndexes[$oldXfIndex] = $existingStyle->getIndex();\n                    } else {\n                        // we don't have such a cell Xf, need to add\n                        $workbook->addCellXf($newStyle);\n                        $newXfIndexes[$oldXfIndex] = $newStyle->getIndex();\n                    }\n                }\n\n                // Loop through columns, rows, or cells again and update the XF index\n                switch ($selectionType) {\n                    case 'COLUMN':\n                        for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {\n                            $columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col);\n                            $oldXfIndex = $columnDimension->getXfIndex();\n                            $columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]);\n                        }\n                        break;\n\n                    case 'ROW':\n                        for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {\n                            $rowDimension = $this->getActiveSheet()->getRowDimension($row);\n                            $oldXfIndex = $rowDimension->getXfIndex() === null ?\n                                0 : $rowDimension->getXfIndex(); // row without explicit style should be formatted based on default style\n                            $rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]);\n                        }\n                        break;\n\n                    case 'CELL':\n                        for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {\n                            for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {\n                                $cell = $this->getActiveSheet()->getCellByColumnAndRow($col, $row);\n                                $oldXfIndex = $cell->getXfIndex();\n                                $cell->setXfIndex($newXfIndexes[$oldXfIndex]);\n                            }\n                        }\n                        break;\n                }\n\n            } else {\n                // not a supervisor, just apply the style array directly on style object\n                if (array_key_exists('fill', $pStyles)) {\n                    $this->getFill()->applyFromArray($pStyles['fill']);\n                }\n                if (array_key_exists('font', $pStyles)) {\n                    $this->getFont()->applyFromArray($pStyles['font']);\n                }\n                if (array_key_exists('borders', $pStyles)) {\n                    $this->getBorders()->applyFromArray($pStyles['borders']);\n                }\n                if (array_key_exists('alignment', $pStyles)) {\n                    $this->getAlignment()->applyFromArray($pStyles['alignment']);\n                }\n                if (array_key_exists('numberformat', $pStyles)) {\n                    $this->getNumberFormat()->applyFromArray($pStyles['numberformat']);\n                }\n                if (array_key_exists('protection', $pStyles)) {\n                    $this->getProtection()->applyFromArray($pStyles['protection']);\n                }\n                if (array_key_exists('quotePrefix', $pStyles)) {\n                    $this->_quotePrefix = $pStyles['quotePrefix'];\n                }\n            }\n        } else {\n            throw new PHPExcel_Exception(\"Invalid style array passed.\");\n        }\n        return $this;\n    }\n\n    /**\n     * Get Fill\n     *\n     * @return PHPExcel_Style_Fill\n     */\n    public function getFill()\n    {\n        return $this->_fill;\n    }\n\n    /**\n     * Get Font\n     *\n     * @return PHPExcel_Style_Font\n     */\n    public function getFont()\n    {\n        return $this->_font;\n    }\n\n    /**\n     * Set font\n     *\n     * @param PHPExcel_Style_Font $font\n     * @return PHPExcel_Style\n     */\n    public function setFont(PHPExcel_Style_Font $font)\n    {\n        $this->_font = $font;\n        return $this;\n    }\n\n    /**\n     * Get Borders\n     *\n     * @return PHPExcel_Style_Borders\n     */\n    public function getBorders()\n    {\n        return $this->_borders;\n    }\n\n    /**\n     * Get Alignment\n     *\n     * @return PHPExcel_Style_Alignment\n     */\n    public function getAlignment()\n    {\n        return $this->_alignment;\n    }\n\n    /**\n     * Get Number Format\n     *\n     * @return PHPExcel_Style_NumberFormat\n     */\n    public function getNumberFormat()\n    {\n        return $this->_numberFormat;\n    }\n\n    /**\n     * Get Conditional Styles. Only used on supervisor.\n     *\n     * @return PHPExcel_Style_Conditional[]\n     */\n    public function getConditionalStyles()\n    {\n        return $this->getActiveSheet()->getConditionalStyles($this->getActiveCell());\n    }\n\n    /**\n     * Set Conditional Styles. Only used on supervisor.\n     *\n     * @param PHPExcel_Style_Conditional[] $pValue Array of condtional styles\n     * @return PHPExcel_Style\n     */\n    public function setConditionalStyles($pValue = null)\n    {\n        if (is_array($pValue)) {\n            $this->getActiveSheet()->setConditionalStyles($this->getSelectedCells(), $pValue);\n        }\n        return $this;\n    }\n\n    /**\n     * Get Protection\n     *\n     * @return PHPExcel_Style_Protection\n     */\n    public function getProtection()\n    {\n        return $this->_protection;\n    }\n\n    /**\n     * Get quote prefix\n     *\n     * @return boolean\n     */\n    public function getQuotePrefix()\n    {\n        if ($this->_isSupervisor) {\n            return $this->getSharedComponent()->getQuotePrefix();\n        }\n        return $this->_quotePrefix;\n    }\n\n    /**\n     * Set quote prefix\n     *\n     * @param boolean $pValue\n     */\n    public function setQuotePrefix($pValue)\n    {\n        if ($pValue == '') {\n            $pValue = false;\n        }\n        if ($this->_isSupervisor) {\n            $styleArray = array('quotePrefix' => $pValue);\n            $this->getActiveSheet()->getStyle($this->getSelectedCells())->applyFromArray($styleArray);\n        } else {\n            $this->_quotePrefix = (boolean) $pValue;\n        }\n        return $this;\n    }\n\n    /**\n     * Get hash code\n     *\n     * @return string Hash code\n     */\n    public function getHashCode()\n    {\n        $hashConditionals = '';\n        foreach ($this->_conditionalStyles as $conditional) {\n            $hashConditionals .= $conditional->getHashCode();\n        }\n\n        return md5(\n              $this->_fill->getHashCode()\n            . $this->_font->getHashCode()\n            . $this->_borders->getHashCode()\n            . $this->_alignment->getHashCode()\n            . $this->_numberFormat->getHashCode()\n            . $hashConditionals\n            . $this->_protection->getHashCode()\n            . ($this->_quotePrefix  ? 't' : 'f')\n            . __CLASS__\n        );\n    }\n\n    /**\n     * Get own index in style collection\n     *\n     * @return int\n     */\n    public function getIndex()\n    {\n        return $this->_index;\n    }\n\n    /**\n     * Set own index in style collection\n     *\n     * @param int $pValue\n     */\n    public function setIndex($pValue)\n    {\n        $this->_index = $pValue;\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/AutoFilter/Column/Rule.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Worksheet\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_AutoFilter_Column_Rule\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Worksheet\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_AutoFilter_Column_Rule\n{\n\tconst AUTOFILTER_RULETYPE_FILTER\t\t= 'filter';\n\tconst AUTOFILTER_RULETYPE_DATEGROUP\t\t= 'dateGroupItem';\n\tconst AUTOFILTER_RULETYPE_CUSTOMFILTER\t= 'customFilter';\n\tconst AUTOFILTER_RULETYPE_DYNAMICFILTER\t= 'dynamicFilter';\n\tconst AUTOFILTER_RULETYPE_TOPTENFILTER\t= 'top10Filter';\n\n\tprivate static $_ruleTypes = array(\n\t\t//\tCurrently we're not handling\n\t\t//\t\tcolorFilter\n\t\t//\t\textLst\n\t\t//\t\ticonFilter\n\t\tself::AUTOFILTER_RULETYPE_FILTER,\n\t\tself::AUTOFILTER_RULETYPE_DATEGROUP,\n\t\tself::AUTOFILTER_RULETYPE_CUSTOMFILTER,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMICFILTER,\n\t\tself::AUTOFILTER_RULETYPE_TOPTENFILTER,\n\t);\n\n\tconst AUTOFILTER_RULETYPE_DATEGROUP_YEAR\t= 'year';\n\tconst AUTOFILTER_RULETYPE_DATEGROUP_MONTH\t= 'month';\n\tconst AUTOFILTER_RULETYPE_DATEGROUP_DAY\t\t= 'day';\n\tconst AUTOFILTER_RULETYPE_DATEGROUP_HOUR\t= 'hour';\n\tconst AUTOFILTER_RULETYPE_DATEGROUP_MINUTE\t= 'minute';\n\tconst AUTOFILTER_RULETYPE_DATEGROUP_SECOND\t= 'second';\n\n\tprivate static $_dateTimeGroups = array(\n\t\tself::AUTOFILTER_RULETYPE_DATEGROUP_YEAR,\n\t\tself::AUTOFILTER_RULETYPE_DATEGROUP_MONTH,\n\t\tself::AUTOFILTER_RULETYPE_DATEGROUP_DAY,\n\t\tself::AUTOFILTER_RULETYPE_DATEGROUP_HOUR,\n\t\tself::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE,\n\t\tself::AUTOFILTER_RULETYPE_DATEGROUP_SECOND,\n\t);\n\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY\t\t= 'yesterday';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_TODAY\t\t\t= 'today';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW\t\t= 'tomorrow';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE\t= 'yearToDate';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR\t\t= 'thisYear';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER\t= 'thisQuarter';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH\t\t= 'thisMonth';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK\t\t= 'thisWeek';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR\t\t= 'lastYear';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER\t= 'lastQuarter';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH\t\t= 'lastMonth';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK\t\t= 'lastWeek';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR\t\t= 'nextYear';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER\t= 'nextQuarter';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH\t\t= 'nextMonth';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK\t\t= 'nextWeek';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1\t\t= 'M1';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_JANUARY\t\t= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1;\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2\t\t= 'M2';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_FEBRUARY\t\t= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2;\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3\t\t= 'M3';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MARCH\t\t\t= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3;\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4\t\t= 'M4';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_APRIL\t\t\t= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4;\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5\t\t= 'M5';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MAY\t\t\t= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5;\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6\t\t= 'M6';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_JUNE\t\t\t= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6;\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7\t\t= 'M7';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_JULY\t\t\t= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7;\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8\t\t= 'M8';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_AUGUST\t\t= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8;\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9\t\t= 'M9';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_SEPTEMBER\t\t= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9;\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10\t\t= 'M10';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_OCTOBER\t\t= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10;\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11\t\t= 'M11';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_NOVEMBER\t\t= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11;\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12\t\t= 'M12';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_DECEMBER\t\t= self::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12;\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1\t\t= 'Q1';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2\t\t= 'Q2';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3\t\t= 'Q3';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4\t\t= 'Q4';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE\t= 'aboveAverage';\n\tconst AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE\t= 'belowAverage';\n\n\tprivate static $_dynamicTypes = array(\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_TODAY,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_1,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_2,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_3,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_4,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_5,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_6,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_7,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_8,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_9,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_10,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_11,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_MONTH_12,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_1,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_2,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_3,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_QUARTER_4,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE,\n\t\tself::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE,\n\t);\n\n\t/*\n\t *\tThe only valid filter rule operators for filter and customFilter types are:\n\t *\t\t<xsd:enumeration value=\"equal\"/>\n\t *\t\t<xsd:enumeration value=\"lessThan\"/>\n\t *\t\t<xsd:enumeration value=\"lessThanOrEqual\"/>\n\t *\t\t<xsd:enumeration value=\"notEqual\"/>\n\t *\t\t<xsd:enumeration value=\"greaterThanOrEqual\"/>\n\t *\t\t<xsd:enumeration value=\"greaterThan\"/>\n\t */\n\tconst AUTOFILTER_COLUMN_RULE_EQUAL\t\t\t\t= 'equal';\n\tconst AUTOFILTER_COLUMN_RULE_NOTEQUAL\t\t\t= 'notEqual';\n\tconst AUTOFILTER_COLUMN_RULE_GREATERTHAN\t\t= 'greaterThan';\n\tconst AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL\t= 'greaterThanOrEqual';\n\tconst AUTOFILTER_COLUMN_RULE_LESSTHAN\t\t\t= 'lessThan';\n\tconst AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL\t= 'lessThanOrEqual';\n\n\tprivate static $_operators = array(\n\t\tself::AUTOFILTER_COLUMN_RULE_EQUAL,\n\t\tself::AUTOFILTER_COLUMN_RULE_NOTEQUAL,\n\t\tself::AUTOFILTER_COLUMN_RULE_GREATERTHAN,\n\t\tself::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL,\n\t\tself::AUTOFILTER_COLUMN_RULE_LESSTHAN,\n\t\tself::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL,\n\t);\n\n\tconst AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE\t= 'byValue';\n\tconst AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT\t\t= 'byPercent';\n\n\tprivate static $_topTenValue = array(\n\t\tself::AUTOFILTER_COLUMN_RULE_TOPTEN_BY_VALUE,\n\t\tself::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT,\n\t);\n\n\tconst AUTOFILTER_COLUMN_RULE_TOPTEN_TOP\t\t\t= 'top';\n\tconst AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM\t\t= 'bottom';\n\n\tprivate static $_topTenType = array(\n\t\tself::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP,\n\t\tself::AUTOFILTER_COLUMN_RULE_TOPTEN_BOTTOM,\n\t);\n\n\n\t/* Rule Operators (Numeric, Boolean etc) */\n//\tconst AUTOFILTER_COLUMN_RULE_BETWEEN\t\t\t= 'between';\t\t//\tgreaterThanOrEqual 1 && lessThanOrEqual 2\n\t/* Rule Operators (Numeric Special) which are translated to standard numeric operators with calculated values */\n//\tconst AUTOFILTER_COLUMN_RULE_TOPTEN\t\t\t\t= 'topTen';\t\t\t//\tgreaterThan calculated value\n//\tconst AUTOFILTER_COLUMN_RULE_TOPTENPERCENT\t\t= 'topTenPercent';\t//\tgreaterThan calculated value\n//\tconst AUTOFILTER_COLUMN_RULE_ABOVEAVERAGE\t\t= 'aboveAverage';\t//\tValue is calculated as the average\n//\tconst AUTOFILTER_COLUMN_RULE_BELOWAVERAGE\t\t= 'belowAverage';\t//\tValue is calculated as the average\n\t/* Rule Operators (String) which are set as wild-carded values */\n//\tconst AUTOFILTER_COLUMN_RULE_BEGINSWITH\t\t\t= 'beginsWith';\t\t\t// A*\n//\tconst AUTOFILTER_COLUMN_RULE_ENDSWITH\t\t\t= 'endsWith';\t\t\t// *Z\n//\tconst AUTOFILTER_COLUMN_RULE_CONTAINS\t\t\t= 'contains';\t\t\t// *B*\n//\tconst AUTOFILTER_COLUMN_RULE_DOESNTCONTAIN\t\t= 'notEqual';\t\t\t//\tnotEqual *B*\n\t/* Rule Operators (Date Special) which are translated to standard numeric operators with calculated values */\n//\tconst AUTOFILTER_COLUMN_RULE_BEFORE\t\t\t\t= 'lessThan';\n//\tconst AUTOFILTER_COLUMN_RULE_AFTER\t\t\t\t= 'greaterThan';\n//\tconst AUTOFILTER_COLUMN_RULE_YESTERDAY\t\t\t= 'yesterday';\n//\tconst AUTOFILTER_COLUMN_RULE_TODAY\t\t\t\t= 'today';\n//\tconst AUTOFILTER_COLUMN_RULE_TOMORROW\t\t\t= 'tomorrow';\n//\tconst AUTOFILTER_COLUMN_RULE_LASTWEEK\t\t\t= 'lastWeek';\n//\tconst AUTOFILTER_COLUMN_RULE_THISWEEK\t\t\t= 'thisWeek';\n//\tconst AUTOFILTER_COLUMN_RULE_NEXTWEEK\t\t\t= 'nextWeek';\n//\tconst AUTOFILTER_COLUMN_RULE_LASTMONTH\t\t\t= 'lastMonth';\n//\tconst AUTOFILTER_COLUMN_RULE_THISMONTH\t\t\t= 'thisMonth';\n//\tconst AUTOFILTER_COLUMN_RULE_NEXTMONTH\t\t\t= 'nextMonth';\n//\tconst AUTOFILTER_COLUMN_RULE_LASTQUARTER\t\t= 'lastQuarter';\n//\tconst AUTOFILTER_COLUMN_RULE_THISQUARTER\t\t= 'thisQuarter';\n//\tconst AUTOFILTER_COLUMN_RULE_NEXTQUARTER\t\t= 'nextQuarter';\n//\tconst AUTOFILTER_COLUMN_RULE_LASTYEAR\t\t\t= 'lastYear';\n//\tconst AUTOFILTER_COLUMN_RULE_THISYEAR\t\t\t= 'thisYear';\n//\tconst AUTOFILTER_COLUMN_RULE_NEXTYEAR\t\t\t= 'nextYear';\n//\tconst AUTOFILTER_COLUMN_RULE_YEARTODATE\t\t\t= 'yearToDate';\t\t\t//\t<dynamicFilter val=\"40909\" type=\"yearToDate\" maxVal=\"41113\"/>\n//\tconst AUTOFILTER_COLUMN_RULE_ALLDATESINMONTH\t= 'allDatesInMonth';\t//\t<dynamicFilter type=\"M2\"/> for Month/February\n//\tconst AUTOFILTER_COLUMN_RULE_ALLDATESINQUARTER\t= 'allDatesInQuarter';\t//\t<dynamicFilter type=\"Q2\"/> for Quarter 2\n\n\t/**\n\t * Autofilter Column\n\t *\n\t * @var PHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tprivate $_parent = NULL;\n\n\n\t/**\n\t * Autofilter Rule Type\n\t *\n\t * @var string\n\t */\n\tprivate $_ruleType = self::AUTOFILTER_RULETYPE_FILTER;\n\n\n\t/**\n\t * Autofilter Rule Value\n\t *\n\t * @var string\n\t */\n\tprivate $_value = '';\n\n\t/**\n\t * Autofilter Rule Operator\n\t *\n\t * @var string\n\t */\n\tprivate $_operator = self::AUTOFILTER_COLUMN_RULE_EQUAL;\n\n\t/**\n\t * DateTimeGrouping Group Value\n\t *\n\t * @var string\n\t */\n\tprivate $_grouping = '';\n\n\n\t/**\n\t * Create a new PHPExcel_Worksheet_AutoFilter_Column_Rule\n\t *\n\t * @param PHPExcel_Worksheet_AutoFilter_Column $pParent\n\t */\n\tpublic function __construct(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL)\n\t{\n\t\t$this->_parent = $pParent;\n\t}\n\n\t/**\n\t * Get AutoFilter Rule Type\n\t *\n\t * @return string\n\t */\n\tpublic function getRuleType() {\n\t\treturn $this->_ruleType;\n\t}\n\n\t/**\n\t *\tSet AutoFilter Rule Type\n\t *\n\t *\t@param\tstring\t\t$pRuleType\n\t *\t@throws\tPHPExcel_Exception\n\t *\t@return PHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tpublic function setRuleType($pRuleType = self::AUTOFILTER_RULETYPE_FILTER) {\n\t\tif (!in_array($pRuleType,self::$_ruleTypes)) {\n\t\t\tthrow new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.');\n\t\t}\n\n\t\t$this->_ruleType = $pRuleType;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get AutoFilter Rule Value\n\t *\n\t * @return string\n\t */\n\tpublic function getValue() {\n\t\treturn $this->_value;\n\t}\n\n\t/**\n\t *\tSet AutoFilter Rule Value\n\t *\n\t *\t@param\tstring|string[]\t\t$pValue\n\t *\t@throws\tPHPExcel_Exception\n\t *\t@return PHPExcel_Worksheet_AutoFilter_Column_Rule\n\t */\n\tpublic function setValue($pValue = '') {\n\t\tif (is_array($pValue)) {\n\t\t\t$grouping = -1;\n\t\t\tforeach($pValue as $key => $value) {\n\t\t\t\t//\tValidate array entries\n\t\t\t\tif (!in_array($key,self::$_dateTimeGroups)) {\n\t\t\t\t\t//\tRemove any invalid entries from the value array\n\t\t\t\t\tunset($pValue[$key]);\n\t\t\t\t} else {\n\t\t\t\t\t//\tWork out what the dateTime grouping will be\n\t\t\t\t\t$grouping = max($grouping,array_search($key,self::$_dateTimeGroups));\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (count($pValue) == 0) {\n\t\t\t\tthrow new PHPExcel_Exception('Invalid rule value for column AutoFilter Rule.');\n\t\t\t}\n\t\t\t//\tSet the dateTime grouping that we've anticipated\n\t\t\t$this->setGrouping(self::$_dateTimeGroups[$grouping]);\n\t\t}\n\t\t$this->_value = $pValue;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get AutoFilter Rule Operator\n\t *\n\t * @return string\n\t */\n\tpublic function getOperator() {\n\t\treturn $this->_operator;\n\t}\n\n\t/**\n\t *\tSet AutoFilter Rule Operator\n\t *\n\t *\t@param\tstring\t\t$pOperator\n\t *\t@throws\tPHPExcel_Exception\n\t *\t@return PHPExcel_Worksheet_AutoFilter_Column_Rule\n\t */\n\tpublic function setOperator($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL) {\n\t\tif (empty($pOperator))\n\t\t\t$pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL;\n\t\tif ((!in_array($pOperator,self::$_operators)) &&\n\t\t\t(!in_array($pOperator,self::$_topTenValue))) {\n\t\t\tthrow new PHPExcel_Exception('Invalid operator for column AutoFilter Rule.');\n\t\t}\n\t\t$this->_operator = $pOperator;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get AutoFilter Rule Grouping\n\t *\n\t * @return string\n\t */\n\tpublic function getGrouping() {\n\t\treturn $this->_grouping;\n\t}\n\n\t/**\n\t *\tSet AutoFilter Rule Grouping\n\t *\n\t *\t@param\tstring\t\t$pGrouping\n\t *\t@throws\tPHPExcel_Exception\n\t *\t@return PHPExcel_Worksheet_AutoFilter_Column_Rule\n\t */\n\tpublic function setGrouping($pGrouping = NULL) {\n\t\tif (($pGrouping !== NULL) &&\n\t\t\t(!in_array($pGrouping,self::$_dateTimeGroups)) &&\n\t\t\t(!in_array($pGrouping,self::$_dynamicTypes)) &&\n\t\t\t(!in_array($pGrouping,self::$_topTenType))) {\n\t\t\tthrow new PHPExcel_Exception('Invalid rule type for column AutoFilter Rule.');\n\t\t}\n\n\t\t$this->_grouping = $pGrouping;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t *\tSet AutoFilter Rule\n\t *\n\t *\t@param\tstring\t\t\t\t$pOperator\n\t *\t@param\tstring|string[]\t\t$pValue\n\t *\t@param\tstring\t\t\t\t$pGrouping\n\t *\t@throws\tPHPExcel_Exception\n\t *\t@return PHPExcel_Worksheet_AutoFilter_Column_Rule\n\t */\n\tpublic function setRule($pOperator = self::AUTOFILTER_COLUMN_RULE_EQUAL, $pValue = '', $pGrouping = NULL) {\n\t\t$this->setOperator($pOperator);\n\t\t$this->setValue($pValue);\n\t\t//\tOnly set grouping if it's been passed in as a user-supplied argument,\n\t\t//\t\totherwise we're calculating it when we setValue() and don't want to overwrite that\n\t\t//\t\tIf the user supplies an argumnet for grouping, then on their own head be it\n\t\tif ($pGrouping !== NULL)\n\t\t\t$this->setGrouping($pGrouping);\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get this Rule's AutoFilter Column Parent\n\t *\n\t * @return PHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tpublic function getParent() {\n\t\treturn $this->_parent;\n\t}\n\n\t/**\n\t * Set this Rule's AutoFilter Column Parent\n\t *\n\t * @param PHPExcel_Worksheet_AutoFilter_Column\n\t * @return PHPExcel_Worksheet_AutoFilter_Column_Rule\n\t */\n\tpublic function setParent(PHPExcel_Worksheet_AutoFilter_Column $pParent = NULL) {\n\t\t$this->_parent = $pParent;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\tif ($key == '_parent') {\n\t\t\t\t\t//\tDetach from autofilter column parent\n\t\t\t\t\t$this->$key = NULL;\n\t\t\t\t} else {\n\t\t\t\t\t$this->$key = clone $value;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/AutoFilter/Column.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Worksheet\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\t\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_AutoFilter_Column\n *\n * @category\tPHPExcel\n * @package\t\tPHPExcel_Worksheet\n * @copyright\tCopyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_AutoFilter_Column\n{\n\tconst AUTOFILTER_FILTERTYPE_FILTER\t\t\t= 'filters';\n\tconst AUTOFILTER_FILTERTYPE_CUSTOMFILTER\t= 'customFilters';\n\t//\tSupports no more than 2 rules, with an And/Or join criteria\n\t//\t\tif more than 1 rule is defined\n\tconst AUTOFILTER_FILTERTYPE_DYNAMICFILTER\t= 'dynamicFilter';\n\t//\tEven though the filter rule is constant, the filtered data can vary\n\t//\t\te.g. filtered by date = TODAY\n\tconst AUTOFILTER_FILTERTYPE_TOPTENFILTER\t= 'top10';\n\n\t/**\n\t * Types of autofilter rules\n\t *\n\t * @var string[]\n\t */\n\tprivate static $_filterTypes = array(\n\t\t//\tCurrently we're not handling\n\t\t//\t\tcolorFilter\n\t\t//\t\textLst\n\t\t//\t\ticonFilter\n\t\tself::AUTOFILTER_FILTERTYPE_FILTER,\n\t\tself::AUTOFILTER_FILTERTYPE_CUSTOMFILTER,\n\t\tself::AUTOFILTER_FILTERTYPE_DYNAMICFILTER,\n\t\tself::AUTOFILTER_FILTERTYPE_TOPTENFILTER,\n\t);\n\n\t/* Multiple Rule Connections */\n\tconst AUTOFILTER_COLUMN_JOIN_AND\t= 'and';\n\tconst AUTOFILTER_COLUMN_JOIN_OR\t\t= 'or';\n\n\t/**\n\t * Join options for autofilter rules\n\t *\n\t * @var string[]\n\t */\n\tprivate static $_ruleJoins = array(\n\t\tself::AUTOFILTER_COLUMN_JOIN_AND,\n\t\tself::AUTOFILTER_COLUMN_JOIN_OR,\n\t);\n\n\t/**\n\t * Autofilter\n\t *\n\t * @var PHPExcel_Worksheet_AutoFilter\n\t */\n\tprivate $_parent = NULL;\n\n\n\t/**\n\t * Autofilter Column Index\n\t *\n\t * @var string\n\t */\n\tprivate $_columnIndex = '';\n\n\n\t/**\n\t * Autofilter Column Filter Type\n\t *\n\t * @var string\n\t */\n\tprivate $_filterType = self::AUTOFILTER_FILTERTYPE_FILTER;\n\n\n\t/**\n\t * Autofilter Multiple Rules And/Or\n\t *\n\t * @var string\n\t */\n\tprivate $_join = self::AUTOFILTER_COLUMN_JOIN_OR;\n\n\n\t/**\n\t * Autofilter Column Rules\n\t *\n\t * @var array of PHPExcel_Worksheet_AutoFilter_Column_Rule\n\t */\n\tprivate $_ruleset = array();\n\n\n\t/**\n\t * Autofilter Column Dynamic Attributes\n\t *\n\t * @var array of mixed\n\t */\n\tprivate $_attributes = array();\n\n\n\t/**\n\t * Create a new PHPExcel_Worksheet_AutoFilter_Column\n\t *\n\t *\t@param\tstring\t\t                   $pColumn\t\tColumn (e.g. A)\n\t *\t@param\tPHPExcel_Worksheet_AutoFilter  $pParent\t\tAutofilter for this column\n\t */\n\tpublic function __construct($pColumn, PHPExcel_Worksheet_AutoFilter $pParent = NULL)\n\t{\n\t\t$this->_columnIndex = $pColumn;\n\t\t$this->_parent = $pParent;\n\t}\n\n\t/**\n\t * Get AutoFilter Column Index\n\t *\n\t * @return string\n\t */\n\tpublic function getColumnIndex() {\n\t\treturn $this->_columnIndex;\n\t}\n\n\t/**\n\t *\tSet AutoFilter Column Index\n\t *\n\t *\t@param\tstring\t\t$pColumn\t\tColumn (e.g. A)\n\t *\t@throws\tPHPExcel_Exception\n\t *\t@return PHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tpublic function setColumnIndex($pColumn) {\n\t\t// Uppercase coordinate\n\t\t$pColumn = strtoupper($pColumn);\n\t\tif ($this->_parent !== NULL) {\n\t\t\t$this->_parent->testColumnInRange($pColumn);\n\t\t}\n\n\t\t$this->_columnIndex = $pColumn;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get this Column's AutoFilter Parent\n\t *\n\t * @return PHPExcel_Worksheet_AutoFilter\n\t */\n\tpublic function getParent() {\n\t\treturn $this->_parent;\n\t}\n\n\t/**\n\t * Set this Column's AutoFilter Parent\n\t *\n\t * @param PHPExcel_Worksheet_AutoFilter\n\t * @return PHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tpublic function setParent(PHPExcel_Worksheet_AutoFilter $pParent = NULL) {\n\t\t$this->_parent = $pParent;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get AutoFilter Type\n\t *\n\t * @return string\n\t */\n\tpublic function getFilterType() {\n\t\treturn $this->_filterType;\n\t}\n\n\t/**\n\t *\tSet AutoFilter Type\n\t *\n\t *\t@param\tstring\t\t$pFilterType\n\t *\t@throws\tPHPExcel_Exception\n\t *\t@return PHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tpublic function setFilterType($pFilterType = self::AUTOFILTER_FILTERTYPE_FILTER) {\n\t\tif (!in_array($pFilterType,self::$_filterTypes)) {\n\t\t\tthrow new PHPExcel_Exception('Invalid filter type for column AutoFilter.');\n\t\t}\n\n\t\t$this->_filterType = $pFilterType;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get AutoFilter Multiple Rules And/Or Join\n\t *\n\t * @return string\n\t */\n\tpublic function getJoin() {\n\t\treturn $this->_join;\n\t}\n\n\t/**\n\t *\tSet AutoFilter Multiple Rules And/Or\n\t *\n\t *\t@param\tstring\t\t$pJoin\t\tAnd/Or\n\t *\t@throws\tPHPExcel_Exception\n\t *\t@return PHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tpublic function setJoin($pJoin = self::AUTOFILTER_COLUMN_JOIN_OR) {\n\t\t// Lowercase And/Or\n\t\t$pJoin = strtolower($pJoin);\n\t\tif (!in_array($pJoin,self::$_ruleJoins)) {\n\t\t\tthrow new PHPExcel_Exception('Invalid rule connection for column AutoFilter.');\n\t\t}\n\n\t\t$this->_join = $pJoin;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t *\tSet AutoFilter Attributes\n\t *\n\t *\t@param\tstring[]\t\t$pAttributes\n\t *\t@throws\tPHPExcel_Exception\n\t *\t@return PHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tpublic function setAttributes($pAttributes = array()) {\n\t\t$this->_attributes = $pAttributes;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t *\tSet An AutoFilter Attribute\n\t *\n\t *\t@param\tstring\t\t$pName\t\tAttribute Name\n\t *\t@param\tstring\t\t$pValue\t\tAttribute Value\n\t *\t@throws\tPHPExcel_Exception\n\t *\t@return PHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tpublic function setAttribute($pName, $pValue) {\n\t\t$this->_attributes[$pName] = $pValue;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get AutoFilter Column Attributes\n\t *\n\t * @return string\n\t */\n\tpublic function getAttributes() {\n\t\treturn $this->_attributes;\n\t}\n\n\t/**\n\t * Get specific AutoFilter Column Attribute\n\t *\n\t *\t@param\tstring\t\t$pName\t\tAttribute Name\n\t * @return string\n\t */\n\tpublic function getAttribute($pName) {\n\t\tif (isset($this->_attributes[$pName]))\n\t\t\treturn $this->_attributes[$pName];\n\t\treturn NULL;\n\t}\n\n\t/**\n\t * Get all AutoFilter Column Rules\n\t *\n\t * @throws\tPHPExcel_Exception\n\t * @return array of PHPExcel_Worksheet_AutoFilter_Column_Rule\n\t */\n\tpublic function getRules() {\n\t\treturn $this->_ruleset;\n\t}\n\n\t/**\n\t * Get a specified AutoFilter Column Rule\n\t *\n\t * @param\tinteger\t$pIndex\t\tRule index in the ruleset array\n\t * @return\tPHPExcel_Worksheet_AutoFilter_Column_Rule\n\t */\n\tpublic function getRule($pIndex) {\n\t\tif (!isset($this->_ruleset[$pIndex])) {\n\t\t\t$this->_ruleset[$pIndex] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this);\n\t\t}\n\t\treturn $this->_ruleset[$pIndex];\n\t}\n\n\t/**\n\t * Create a new AutoFilter Column Rule in the ruleset\n\t *\n\t * @return\tPHPExcel_Worksheet_AutoFilter_Column_Rule\n\t */\n\tpublic function createRule() {\n\t\t$this->_ruleset[] = new PHPExcel_Worksheet_AutoFilter_Column_Rule($this);\n\n\t\treturn end($this->_ruleset);\n\t}\n\n\t/**\n\t * Add a new AutoFilter Column Rule to the ruleset\n\t *\n\t * @param\tPHPExcel_Worksheet_AutoFilter_Column_Rule\t$pRule\n\t * @param\tboolean\t$returnRule \tFlag indicating whether the rule object or the column object should be returned\n\t * @return\tPHPExcel_Worksheet_AutoFilter_Column|PHPExcel_Worksheet_AutoFilter_Column_Rule\n\t */\n\tpublic function addRule(PHPExcel_Worksheet_AutoFilter_Column_Rule $pRule, $returnRule=TRUE) {\n\t\t$pRule->setParent($this);\n\t\t$this->_ruleset[] = $pRule;\n\n\t\treturn ($returnRule) ? $pRule : $this;\n\t}\n\n\t/**\n\t * Delete a specified AutoFilter Column Rule\n\t *\tIf the number of rules is reduced to 1, then we reset And/Or logic to Or\n\t *\n\t * @param\tinteger\t$pIndex\t\tRule index in the ruleset array\n\t * @return\tPHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tpublic function deleteRule($pIndex) {\n\t\tif (isset($this->_ruleset[$pIndex])) {\n\t\t\tunset($this->_ruleset[$pIndex]);\n\t\t\t//\tIf we've just deleted down to a single rule, then reset And/Or joining to Or\n\t\t\tif (count($this->_ruleset) <= 1) {\n\t\t\t\t$this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR);\n\t\t\t}\n\t\t}\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Delete all AutoFilter Column Rules\n\t *\n\t * @return\tPHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tpublic function clearRules() {\n\t\t$this->_ruleset = array();\n\t\t$this->setJoin(self::AUTOFILTER_COLUMN_JOIN_OR);\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\tif ($key == '_parent') {\n\t\t\t\t\t//\tDetach from autofilter parent\n\t\t\t\t\t$this->$key = NULL;\n\t\t\t\t} else {\n\t\t\t\t\t$this->$key = clone $value;\n\t\t\t\t}\n\t\t\t} elseif ((is_array($value)) && ($key == '_ruleset')) {\n\t\t\t\t//\tThe columns array of PHPExcel_Worksheet_AutoFilter objects\n\t\t\t\t$this->$key = array();\n\t\t\t\tforeach ($value as $k => $v) {\n\t\t\t\t\t$this->$key[$k] = clone $v;\n\t\t\t\t\t// attach the new cloned Rule to this new cloned Autofilter Cloned object\n\t\t\t\t\t$this->$key[$k]->setParent($this);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/AutoFilter.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_AutoFilter\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_AutoFilter\n{\n\t/**\n\t * Autofilter Worksheet\n\t *\n\t * @var PHPExcel_Worksheet\n\t */\n\tprivate $_workSheet = NULL;\n\n\n\t/**\n\t * Autofilter Range\n\t *\n\t * @var string\n\t */\n\tprivate $_range = '';\n\n\n\t/**\n\t * Autofilter Column Ruleset\n\t *\n\t * @var array of PHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tprivate $_columns = array();\n\n\n    /**\n     * Create a new PHPExcel_Worksheet_AutoFilter\n\t *\n\t *\t@param\tstring\t\t$pRange\t\tCell range (i.e. A1:E10)\n\t * @param PHPExcel_Worksheet $pSheet\n     */\n    public function __construct($pRange = '', PHPExcel_Worksheet $pSheet = NULL)\n    {\n\t\t$this->_range = $pRange;\n\t\t$this->_workSheet = $pSheet;\n    }\n\n\t/**\n\t * Get AutoFilter Parent Worksheet\n\t *\n\t * @return PHPExcel_Worksheet\n\t */\n\tpublic function getParent() {\n\t\treturn $this->_workSheet;\n\t}\n\n\t/**\n\t * Set AutoFilter Parent Worksheet\n\t *\n\t * @param PHPExcel_Worksheet $pSheet\n\t * @return PHPExcel_Worksheet_AutoFilter\n\t */\n\tpublic function setParent(PHPExcel_Worksheet $pSheet = NULL) {\n\t\t$this->_workSheet = $pSheet;\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get AutoFilter Range\n\t *\n\t * @return string\n\t */\n\tpublic function getRange() {\n\t\treturn $this->_range;\n\t}\n\n\t/**\n\t *\tSet AutoFilter Range\n\t *\n\t *\t@param\tstring\t\t$pRange\t\tCell range (i.e. A1:E10)\n\t *\t@throws\tPHPExcel_Exception\n\t *\t@return PHPExcel_Worksheet_AutoFilter\n\t */\n\tpublic function setRange($pRange = '') {\n\t\t// Uppercase coordinate\n\t\t$cellAddress = explode('!',strtoupper($pRange));\n\t\tif (count($cellAddress) > 1) {\n\t\t\tlist($worksheet,$pRange) = $cellAddress;\n\t\t}\n\n\t\tif (strpos($pRange,':') !== FALSE) {\n\t\t\t$this->_range = $pRange;\n\t\t} elseif(empty($pRange)) {\n\t\t\t$this->_range = '';\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception('Autofilter must be set on a range of cells.');\n\t\t}\n\n\t\tif (empty($pRange)) {\n\t\t\t//\tDiscard all column rules\n\t\t\t$this->_columns = array();\n\t\t} else {\n\t\t\t//\tDiscard any column rules that are no longer valid within this range\n\t\t\tlist($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range);\n\t\t\tforeach($this->_columns as $key => $value) {\n\t\t\t\t$colIndex = PHPExcel_Cell::columnIndexFromString($key);\n\t\t\t\tif (($rangeStart[0] > $colIndex) || ($rangeEnd[0] < $colIndex)) {\n\t\t\t\t\tunset($this->_columns[$key]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get all AutoFilter Columns\n\t *\n\t * @throws\tPHPExcel_Exception\n\t * @return array of PHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tpublic function getColumns() {\n\t\treturn $this->_columns;\n\t}\n\n\t/**\n\t * Validate that the specified column is in the AutoFilter range\n\t *\n\t * @param\tstring\t$column\t\t\tColumn name (e.g. A)\n\t * @throws\tPHPExcel_Exception\n\t * @return\tinteger\tThe column offset within the autofilter range\n\t */\n\tpublic function testColumnInRange($column) {\n\t\tif (empty($this->_range)) {\n\t\t\tthrow new PHPExcel_Exception(\"No autofilter range is defined.\");\n\t\t}\n\n\t\t$columnIndex = PHPExcel_Cell::columnIndexFromString($column);\n\t\tlist($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range);\n\t\tif (($rangeStart[0] > $columnIndex) || ($rangeEnd[0] < $columnIndex)) {\n\t\t\tthrow new PHPExcel_Exception(\"Column is outside of current autofilter range.\");\n\t\t}\n\n\t\treturn $columnIndex - $rangeStart[0];\n\t}\n\n\t/**\n\t * Get a specified AutoFilter Column Offset within the defined AutoFilter range\n\t *\n\t * @param\tstring\t$pColumn\t\tColumn name (e.g. A)\n\t * @throws\tPHPExcel_Exception\n\t * @return integer\tThe offset of the specified column within the autofilter range\n\t */\n\tpublic function getColumnOffset($pColumn) {\n\t\treturn $this->testColumnInRange($pColumn);\n\t}\n\n\t/**\n\t * Get a specified AutoFilter Column\n\t *\n\t * @param\tstring\t$pColumn\t\tColumn name (e.g. A)\n\t * @throws\tPHPExcel_Exception\n\t * @return PHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tpublic function getColumn($pColumn) {\n\t\t$this->testColumnInRange($pColumn);\n\n\t\tif (!isset($this->_columns[$pColumn])) {\n\t\t\t$this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this);\n\t\t}\n\n\t\treturn $this->_columns[$pColumn];\n\t}\n\n\t/**\n\t * Get a specified AutoFilter Column by it's offset\n\t *\n\t * @param\tinteger\t$pColumnOffset\t\tColumn offset within range (starting from 0)\n\t * @throws\tPHPExcel_Exception\n\t * @return PHPExcel_Worksheet_AutoFilter_Column\n\t */\n\tpublic function getColumnByOffset($pColumnOffset = 0) {\n\t\tlist($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range);\n\t\t$pColumn = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] + $pColumnOffset - 1);\n\n\t\treturn $this->getColumn($pColumn);\n\t}\n\n\t/**\n\t *\tSet AutoFilter\n\t *\n\t *\t@param\tPHPExcel_Worksheet_AutoFilter_Column|string\t\t$pColumn\n\t *\t\t\tA simple string containing a Column ID like 'A' is permitted\n\t *\t@throws\tPHPExcel_Exception\n\t *\t@return PHPExcel_Worksheet_AutoFilter\n\t */\n\tpublic function setColumn($pColumn)\n\t{\n\t\tif ((is_string($pColumn)) && (!empty($pColumn))) {\n\t\t\t$column = $pColumn;\n\t\t} elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) {\n\t\t\t$column = $pColumn->getColumnIndex();\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Column is not within the autofilter range.\");\n\t\t}\n\t\t$this->testColumnInRange($column);\n\n\t\tif (is_string($pColumn)) {\n\t\t\t$this->_columns[$pColumn] = new PHPExcel_Worksheet_AutoFilter_Column($pColumn, $this);\n\t\t} elseif(is_object($pColumn) && ($pColumn instanceof PHPExcel_Worksheet_AutoFilter_Column)) {\n\t\t\t$pColumn->setParent($this);\n\t\t\t$this->_columns[$column] = $pColumn;\n\t\t}\n\t\tksort($this->_columns);\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Clear a specified AutoFilter Column\n\t *\n\t * @param\tstring  $pColumn    Column name (e.g. A)\n\t * @throws\tPHPExcel_Exception\n\t * @return PHPExcel_Worksheet_AutoFilter\n\t */\n\tpublic function clearColumn($pColumn) {\n\t\t$this->testColumnInRange($pColumn);\n\n\t\tif (isset($this->_columns[$pColumn])) {\n\t\t\tunset($this->_columns[$pColumn]);\n\t\t}\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t *\tShift an AutoFilter Column Rule to a different column\n\t *\n\t *\tNote: This method bypasses validation of the destination column to ensure it is within this AutoFilter range.\n\t *\t\tNor does it verify whether any column rule already exists at $toColumn, but will simply overrideany existing value.\n\t *\t\tUse with caution.\n\t *\n\t *\t@param\tstring\t$fromColumn\t\tColumn name (e.g. A)\n\t *\t@param\tstring\t$toColumn\t\tColumn name (e.g. B)\n\t *\t@return PHPExcel_Worksheet_AutoFilter\n\t */\n\tpublic function shiftColumn($fromColumn=NULL,$toColumn=NULL) {\n\t\t$fromColumn = strtoupper($fromColumn);\n\t\t$toColumn = strtoupper($toColumn);\n\n\t\tif (($fromColumn !== NULL) && (isset($this->_columns[$fromColumn])) && ($toColumn !== NULL)) {\n\t\t\t$this->_columns[$fromColumn]->setParent();\n\t\t\t$this->_columns[$fromColumn]->setColumnIndex($toColumn);\n\t\t\t$this->_columns[$toColumn] = $this->_columns[$fromColumn];\n\t\t\t$this->_columns[$toColumn]->setParent($this);\n\t\t\tunset($this->_columns[$fromColumn]);\n\n\t\t\tksort($this->_columns);\n\t\t}\n\n\t\treturn $this;\n\t}\n\n\n\t/**\n\t *\tTest if cell value is in the defined set of values\n\t *\n\t *\t@param\tmixed\t\t$cellValue\n\t *\t@param\tmixed[]\t\t$dataSet\n\t *\t@return boolean\n\t */\n\tprivate static function _filterTestInSimpleDataSet($cellValue,$dataSet)\n\t{\n\t\t$dataSetValues = $dataSet['filterValues'];\n\t\t$blanks = $dataSet['blanks'];\n\t\tif (($cellValue == '') || ($cellValue === NULL)) {\n\t\t\treturn $blanks;\n\t\t}\n\t\treturn in_array($cellValue,$dataSetValues);\n\t}\n\n\t/**\n\t *\tTest if cell value is in the defined set of Excel date values\n\t *\n\t *\t@param\tmixed\t\t$cellValue\n\t *\t@param\tmixed[]\t\t$dataSet\n\t *\t@return boolean\n\t */\n\tprivate static function _filterTestInDateGroupSet($cellValue,$dataSet)\n\t{\n\t\t$dateSet = $dataSet['filterValues'];\n\t\t$blanks = $dataSet['blanks'];\n\t\tif (($cellValue == '') || ($cellValue === NULL)) {\n\t\t\treturn $blanks;\n\t\t}\n\n\t\tif (is_numeric($cellValue)) {\n\t\t\t$dateValue = PHPExcel_Shared_Date::ExcelToPHP($cellValue);\n\t\t\tif ($cellValue < 1) {\n\t\t\t\t//\tJust the time part\n\t\t\t\t$dtVal = date('His',$dateValue);\n\t\t\t\t$dateSet = $dateSet['time'];\n\t\t\t} elseif($cellValue == floor($cellValue)) {\n\t\t\t\t//\tJust the date part\n\t\t\t\t$dtVal = date('Ymd',$dateValue);\n\t\t\t\t$dateSet = $dateSet['date'];\n\t\t\t} else {\n\t\t\t\t//\tdate and time parts\n\t\t\t\t$dtVal = date('YmdHis',$dateValue);\n\t\t\t\t$dateSet = $dateSet['dateTime'];\n\t\t\t}\n\t\t\tforeach($dateSet as $dateValue) {\n\t\t\t\t//\tUse of substr to extract value at the appropriate group level\n\t\t\t\tif (substr($dtVal,0,strlen($dateValue)) == $dateValue)\n\t\t\t\t\treturn TRUE;\n\t\t\t}\n\t\t}\n\n\t\treturn FALSE;\n\t}\n\n\t/**\n\t *\tTest if cell value is within a set of values defined by a ruleset\n\t *\n\t *\t@param\tmixed\t\t$cellValue\n\t *\t@param\tmixed[]\t\t$ruleSet\n\t *\t@return boolean\n\t */\n\tprivate static function _filterTestInCustomDataSet($cellValue, $ruleSet)\n\t{\n\t\t$dataSet = $ruleSet['filterRules'];\n\t\t$join = $ruleSet['join'];\n\t\t$customRuleForBlanks = isset($ruleSet['customRuleForBlanks']) ? $ruleSet['customRuleForBlanks'] : FALSE;\n\n\t\tif (!$customRuleForBlanks) {\n\t\t\t//\tBlank cells are always ignored, so return a FALSE\n\t\t\tif (($cellValue == '') || ($cellValue === NULL)) {\n\t\t\t\treturn FALSE;\n\t\t\t}\n\t\t}\n\t\t$returnVal = ($join == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND);\n\t\tforeach($dataSet as $rule) {\n\t\t\tif (is_numeric($rule['value'])) {\n\t\t\t\t//\tNumeric values are tested using the appropriate operator\n\t\t\t\tswitch ($rule['operator']) {\n\t\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL :\n\t\t\t\t\t\t$retVal\t= ($cellValue == $rule['value']);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL :\n\t\t\t\t\t\t$retVal\t= ($cellValue != $rule['value']);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN :\n\t\t\t\t\t\t$retVal\t= ($cellValue > $rule['value']);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL :\n\t\t\t\t\t\t$retVal\t= ($cellValue >= $rule['value']);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN :\n\t\t\t\t\t\t$retVal\t= ($cellValue < $rule['value']);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL :\n\t\t\t\t\t\t$retVal\t= ($cellValue <= $rule['value']);\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} elseif($rule['value'] == '') {\n\t\t\t\tswitch ($rule['operator']) {\n\t\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL :\n\t\t\t\t\t\t$retVal\t= (($cellValue == '') || ($cellValue === NULL));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_NOTEQUAL :\n\t\t\t\t\t\t$retVal\t= (($cellValue != '') && ($cellValue !== NULL));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tdefault :\n\t\t\t\t\t\t$retVal\t= TRUE;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t//\tString values are always tested for equality, factoring in for wildcards (hence a regexp test)\n\t\t\t\t$retVal\t= preg_match('/^'.$rule['value'].'$/i',$cellValue);\n\t\t\t}\n\t\t\t//\tIf there are multiple conditions, then we need to test both using the appropriate join operator\n\t\t\tswitch ($join) {\n\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR :\n\t\t\t\t\t$returnVal = $returnVal || $retVal;\n\t\t\t\t\t//\tBreak as soon as we have a TRUE match for OR joins,\n\t\t\t\t\t//\t\tto avoid unnecessary additional code execution\n\t\t\t\t\tif ($returnVal)\n\t\t\t\t\t\treturn $returnVal;\n\t\t\t\t\tbreak;\n\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND :\n\t\t\t\t\t$returnVal = $returnVal && $retVal;\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\treturn $returnVal;\n\t}\n\n\t/**\n\t *\tTest if cell date value is matches a set of values defined by a set of months\n\t *\n\t *\t@param\tmixed\t\t$cellValue\n\t *\t@param\tmixed[]\t\t$monthSet\n\t *\t@return boolean\n\t */\n\tprivate static function _filterTestInPeriodDateSet($cellValue, $monthSet)\n\t{\n\t\t//\tBlank cells are always ignored, so return a FALSE\n\t\tif (($cellValue == '') || ($cellValue === NULL)) {\n\t\t\treturn FALSE;\n\t\t}\n\n\t\tif (is_numeric($cellValue)) {\n\t\t\t$dateValue = date('m',PHPExcel_Shared_Date::ExcelToPHP($cellValue));\n\t\t\tif (in_array($dateValue,$monthSet)) {\n\t\t\t\treturn TRUE;\n\t\t\t}\n\t\t}\n\n\t\treturn FALSE;\n\t}\n\n\t/**\n\t *\tSearch/Replace arrays to convert Excel wildcard syntax to a regexp syntax for preg_matching\n\t *\n\t *\t@var\tarray\n\t */\n\tprivate static $_fromReplace = array('\\*', '\\?', '~~', '~.*', '~.?');\n\tprivate static $_toReplace   = array('.*', '.',  '~',  '\\*',  '\\?');\n\n\n\t/**\n\t *\tConvert a dynamic rule daterange to a custom filter range expression for ease of calculation\n\t *\n\t *\t@param\tstring\t\t\t\t\t\t\t\t\t\t$dynamicRuleType\n\t *\t@param\tPHPExcel_Worksheet_AutoFilter_Column\t\t&$filterColumn\n\t *\t@return mixed[]\n\t */\n\tprivate function _dynamicFilterDateRange($dynamicRuleType, &$filterColumn)\n\t{\n\t\t$rDateType = PHPExcel_Calculation_Functions::getReturnDateType();\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC);\n\t\t$val = $maxVal = NULL;\n\n\t\t$ruleValues = array();\n\t\t$baseDate = PHPExcel_Calculation_DateTime::DATENOW();\n\t\t//\tCalculate start/end dates for the required date range based on current date\n\t\tswitch ($dynamicRuleType) {\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK :\n\t\t\t\t$baseDate = strtotime('-7 days',$baseDate);\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK :\n\t\t\t\t$baseDate = strtotime('-7 days',$baseDate);\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH :\n\t\t\t\t$baseDate = strtotime('-1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate)));\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH :\n\t\t\t\t$baseDate = strtotime('+1 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate)));\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER :\n\t\t\t\t$baseDate = strtotime('-3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate)));\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER :\n\t\t\t\t$baseDate = strtotime('+3 month',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate)));\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR :\n\t\t\t\t$baseDate = strtotime('-1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate)));\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR :\n\t\t\t\t$baseDate = strtotime('+1 year',gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate)));\n\t\t\t\tbreak;\n\t\t}\n\n\t\tswitch ($dynamicRuleType) {\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TODAY :\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY :\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW :\n\t\t\t\t$maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate));\n\t\t\t\t$val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate);\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE :\n\t\t\t\t$maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(strtotime('+1 day',$baseDate));\n\t\t\t\t$val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate)));\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISYEAR :\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTYEAR :\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTYEAR :\n\t\t\t\t$maxVal = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,31,12,date('Y',$baseDate)));\n\t\t\t\t++$maxVal;\n\t\t\t\t$val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1,date('Y',$baseDate)));\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISQUARTER :\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTQUARTER :\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTQUARTER :\n\t\t\t\t$thisMonth = date('m',$baseDate);\n\t\t\t\t$thisQuarter = floor(--$thisMonth / 3);\n\t\t\t\t$maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),(1+$thisQuarter)*3,date('Y',$baseDate)));\n\t\t\t\t++$maxVal;\n\t\t\t\t$val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,1+$thisQuarter*3,date('Y',$baseDate)));\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISMONTH :\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTMONTH :\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTMONTH :\n\t\t\t\t$maxVal = (int) PHPExcel_Shared_Date::PHPtoExcel(gmmktime(0,0,0,date('t',$baseDate),date('m',$baseDate),date('Y',$baseDate)));\n\t\t\t\t++$maxVal;\n\t\t\t\t$val = (int) PHPExcel_Shared_Date::PHPToExcel(gmmktime(0,0,0,1,date('m',$baseDate),date('Y',$baseDate)));\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_THISWEEK :\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK :\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_NEXTWEEK :\n\t\t\t\t$dayOfWeek = date('w',$baseDate);\n\t\t\t\t$val = (int) PHPExcel_Shared_Date::PHPToExcel($baseDate) - $dayOfWeek;\n\t\t\t\t$maxVal = $val + 7;\n\t\t\t\tbreak;\n\t\t}\n\n\t\tswitch ($dynamicRuleType) {\n\t\t\t//\tAdjust Today dates for Yesterday and Tomorrow\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YESTERDAY :\n\t\t\t\t--$maxVal;\n\t\t\t\t--$val;\n\t\t\t\tbreak;\n\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_TOMORROW :\n\t\t\t\t++$maxVal;\n\t\t\t\t++$val;\n\t\t\t\tbreak;\n\t\t}\n\n\t\t//\tSet the filter column rule attributes ready for writing\n\t\t$filterColumn->setAttributes(array(\t'val' => $val,\n\t\t\t\t\t\t\t\t\t\t\t'maxVal' => $maxVal\n\t\t\t\t\t\t\t\t\t\t  )\n\t\t\t\t\t\t\t\t\t);\n\n\t\t//\tSet the rules for identifying rows for hide/show\n\t\t$ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL,\n\t\t\t\t\t\t\t   'value' => $val\n\t\t\t\t\t\t\t );\n\t\t$ruleValues[] = array( 'operator' => PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN,\n\t\t\t\t\t\t\t   'value' => $maxVal\n\t\t\t\t\t\t\t );\n\t\tPHPExcel_Calculation_Functions::setReturnDateType($rDateType);\n\n\t\treturn array(\n\t\t\t'method' => '_filterTestInCustomDataSet',\n\t\t\t'arguments' => array( 'filterRules' => $ruleValues,\n\t\t\t\t\t\t\t\t  'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND\n\t\t\t\t\t\t\t\t)\n\t\t);\n\t}\n\n\tprivate function _calculateTopTenValue($columnID,$startRow,$endRow,$ruleType,$ruleValue) {\n\t\t$range = $columnID.$startRow.':'.$columnID.$endRow;\n\t\t$dataValues = PHPExcel_Calculation_Functions::flattenArray(\n\t\t\t$this->_workSheet->rangeToArray($range,NULL,TRUE,FALSE)\n\t\t);\n\n\t\t$dataValues = array_filter($dataValues);\n\t\tif ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) {\n\t\t\trsort($dataValues);\n\t\t} else {\n\t\t\tsort($dataValues);\n\t\t}\n\n\t\treturn array_pop(array_slice($dataValues,0,$ruleValue));\n\t}\n\n\t/**\n\t *\tApply the AutoFilter rules to the AutoFilter Range\n\t *\n\t *\t@throws\tPHPExcel_Exception\n\t *\t@return PHPExcel_Worksheet_AutoFilter\n\t */\n\tpublic function showHideRows()\n\t{\n\t\tlist($rangeStart,$rangeEnd) = PHPExcel_Cell::rangeBoundaries($this->_range);\n\n\t\t//\tThe heading row should always be visible\n//\t\techo 'AutoFilter Heading Row ',$rangeStart[1],' is always SHOWN',PHP_EOL;\n\t\t$this->_workSheet->getRowDimension($rangeStart[1])->setVisible(TRUE);\n\n\t\t$columnFilterTests = array();\n\t\tforeach($this->_columns as $columnID => $filterColumn) {\n\t\t\t$rules = $filterColumn->getRules();\n\t\t\tswitch ($filterColumn->getFilterType()) {\n\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER :\n\t\t\t\t\t$ruleValues = array();\n\t\t\t\t\t//\tBuild a list of the filter value selections\n\t\t\t\t\tforeach($rules as $rule) {\n\t\t\t\t\t\t$ruleType = $rule->getRuleType();\n\t\t\t\t\t\t$ruleValues[] = $rule->getValue();\n\t\t\t\t\t}\n\t\t\t\t\t//\tTest if we want to include blanks in our filter criteria\n\t\t\t\t\t$blanks = FALSE;\n\t\t\t\t\t$ruleDataSet = array_filter($ruleValues);\n\t\t\t\t\tif (count($ruleValues) != count($ruleDataSet))\n\t\t\t\t\t\t$blanks = TRUE;\n\t\t\t\t\tif ($ruleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER) {\n\t\t\t\t\t\t//\tFilter on absolute values\n\t\t\t\t\t\t$columnFilterTests[$columnID] = array(\n\t\t\t\t\t\t\t'method' => '_filterTestInSimpleDataSet',\n\t\t\t\t\t\t\t'arguments' => array( 'filterValues' => $ruleDataSet,\n\t\t\t\t\t\t\t\t\t\t\t\t  'blanks' => $blanks\n\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t//\tFilter on date group values\n\t\t\t\t\t\t$arguments = array(\n                            'date' => array(),\n                            'time' => array(),\n                            'dateTime' => array(),\n                        );\n\t\t\t\t\t\tforeach($ruleDataSet as $ruleValue) {\n\t\t\t\t\t\t\t$date = $time = '';\n\t\t\t\t\t\t\tif ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR])) &&\n\t\t\t\t\t\t\t\t($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR] !== ''))\n\t\t\t\t\t\t\t\t$date .= sprintf('%04d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_YEAR]);\n\t\t\t\t\t\t\tif ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH])) &&\n\t\t\t\t\t\t\t\t($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH] != ''))\n\t\t\t\t\t\t\t\t$date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH]);\n\t\t\t\t\t\t\tif ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY])) &&\n\t\t\t\t\t\t\t\t($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY] !== ''))\n\t\t\t\t\t\t\t\t$date .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_DAY]);\n\t\t\t\t\t\t\tif ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR])) &&\n\t\t\t\t\t\t\t\t($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR] !== ''))\n\t\t\t\t\t\t\t\t$time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_HOUR]);\n\t\t\t\t\t\t\tif ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE])) &&\n\t\t\t\t\t\t\t\t($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE] !== ''))\n\t\t\t\t\t\t\t\t$time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MINUTE]);\n\t\t\t\t\t\t\tif ((isset($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND])) &&\n\t\t\t\t\t\t\t\t($ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND] !== ''))\n\t\t\t\t\t\t\t\t$time .= sprintf('%02d',$ruleValue[PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_SECOND]);\n\t\t\t\t\t\t\t$dateTime = $date . $time;\n\t\t\t\t\t\t\t$arguments['date'][] = $date;\n\t\t\t\t\t\t\t$arguments['time'][] = $time;\n\t\t\t\t\t\t\t$arguments['dateTime'][] = $dateTime;\n\t\t\t\t\t\t}\n\t\t\t\t\t\t//\tRemove empty elements\n\t\t\t\t\t\t$arguments['date'] = array_filter($arguments['date']);\n\t\t\t\t\t\t$arguments['time'] = array_filter($arguments['time']);\n\t\t\t\t\t\t$arguments['dateTime'] = array_filter($arguments['dateTime']);\n\t\t\t\t\t\t$columnFilterTests[$columnID] = array(\n\t\t\t\t\t\t\t'method' => '_filterTestInDateGroupSet',\n\t\t\t\t\t\t\t'arguments' => array( 'filterValues' => $arguments,\n\t\t\t\t\t\t\t\t\t\t\t\t  'blanks' => $blanks\n\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER :\n\t\t\t\t\t$customRuleForBlanks = FALSE;\n\t\t\t\t\t$ruleValues = array();\n\t\t\t\t\t//\tBuild a list of the filter value selections\n\t\t\t\t\tforeach($rules as $rule) {\n\t\t\t\t\t\t$ruleType = $rule->getRuleType();\n\t\t\t\t\t\t$ruleValue = $rule->getValue();\n\t\t\t\t\t\tif (!is_numeric($ruleValue)) {\n\t\t\t\t\t\t\t//\tConvert to a regexp allowing for regexp reserved characters, wildcards and escaped wildcards\n\t\t\t\t\t\t\t$ruleValue = preg_quote($ruleValue);\n\t\t\t\t\t\t\t$ruleValue = str_replace(self::$_fromReplace,self::$_toReplace,$ruleValue);\n\t\t\t\t\t\t\tif (trim($ruleValue) == '') {\n\t\t\t\t\t\t\t\t$customRuleForBlanks = TRUE;\n\t\t\t\t\t\t\t\t$ruleValue = trim($ruleValue);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$ruleValues[] = array( 'operator' => $rule->getOperator(),\n\t\t\t\t\t\t\t\t\t\t\t   'value' => $ruleValue\n\t\t\t\t\t\t\t\t\t\t\t );\n\t\t\t\t\t}\n\t\t\t\t\t$join = $filterColumn->getJoin();\n\t\t\t\t\t$columnFilterTests[$columnID] = array(\n\t\t\t\t\t\t'method' => '_filterTestInCustomDataSet',\n\t\t\t\t\t\t'arguments' => array( 'filterRules' => $ruleValues,\n\t\t\t\t\t\t\t\t\t\t\t  'join' => $join,\n\t\t\t\t\t\t\t\t\t\t\t  'customRuleForBlanks' => $customRuleForBlanks\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER :\n\t\t\t\t\t$ruleValues = array();\n\t\t\t\t\tforeach($rules as $rule) {\n\t\t\t\t\t\t//\tWe should only ever have one Dynamic Filter Rule anyway\n\t\t\t\t\t\t$dynamicRuleType = $rule->getGrouping();\n\t\t\t\t\t\tif (($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE) ||\n\t\t\t\t\t\t\t($dynamicRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_BELOWAVERAGE)) {\n\t\t\t\t\t\t\t//\tNumber (Average) based\n\t\t\t\t\t\t\t//\tCalculate the average\n\t\t\t\t\t\t\t$averageFormula = '=AVERAGE('.$columnID.($rangeStart[1]+1).':'.$columnID.$rangeEnd[1].')';\n\t\t\t\t\t\t\t$average = PHPExcel_Calculation::getInstance()->calculateFormula($averageFormula,NULL,$this->_workSheet->getCell('A1'));\n\t\t\t\t\t\t\t//\tSet above/below rule based on greaterThan or LessTan\n\t\t\t\t\t\t\t$operator = ($dynamicRuleType === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_ABOVEAVERAGE)\n\t\t\t\t\t\t\t\t? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHAN\n\t\t\t\t\t\t\t\t: PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN;\n\t\t\t\t\t\t\t$ruleValues[] = array( 'operator' => $operator,\n\t\t\t\t\t\t\t\t\t\t\t\t   'value' => $average\n\t\t\t\t\t\t\t\t\t\t\t\t );\n\t\t\t\t\t\t\t$columnFilterTests[$columnID] = array(\n\t\t\t\t\t\t\t\t'method' => '_filterTestInCustomDataSet',\n\t\t\t\t\t\t\t\t'arguments' => array( 'filterRules' => $ruleValues,\n\t\t\t\t\t\t\t\t\t\t\t\t\t  'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR\n\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t//\tDate based\n\t\t\t\t\t\t\tif ($dynamicRuleType{0} == 'M' || $dynamicRuleType{0} == 'Q') {\n\t\t\t\t\t\t\t\t//\tMonth or Quarter\n\t\t\t\t\t\t\t\tsscanf($dynamicRuleType,'%[A-Z]%d', $periodType, $period);\n\t\t\t\t\t\t\t\tif ($periodType == 'M') {\n\t\t\t\t\t\t\t\t\t$ruleValues = array($period);\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t--$period;\n\t\t\t\t\t\t\t\t\t$periodEnd = (1+$period)*3;\n\t\t\t\t\t\t\t\t\t$periodStart = 1+$period*3;\n\t\t\t\t\t\t\t\t\t$ruleValues = range($periodStart,periodEnd);\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t$columnFilterTests[$columnID] = array(\n\t\t\t\t\t\t\t\t\t'method' => '_filterTestInPeriodDateSet',\n\t\t\t\t\t\t\t\t\t'arguments' => $ruleValues\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\t$filterColumn->setAttributes(array());\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t//\tDate Range\n\t\t\t\t\t\t\t\t$columnFilterTests[$columnID] = $this->_dynamicFilterDateRange($dynamicRuleType, $filterColumn);\n\t\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tbreak;\n\t\t\t\tcase PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER :\n\t\t\t\t\t$ruleValues = array();\n\t\t\t\t\t$dataRowCount = $rangeEnd[1] - $rangeStart[1];\n\t\t\t\t\tforeach($rules as $rule) {\n\t\t\t\t\t\t//\tWe should only ever have one Dynamic Filter Rule anyway\n\t\t\t\t\t\t$toptenRuleType = $rule->getGrouping();\n\t\t\t\t\t\t$ruleValue = $rule->getValue();\n\t\t\t\t\t\t$ruleOperator = $rule->getOperator();\n\t\t\t\t\t}\n\t\t\t\t\tif ($ruleOperator === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) {\n\t\t\t\t\t\t$ruleValue = floor($ruleValue * ($dataRowCount / 100));\n\t\t\t\t\t}\n\t\t\t\t\tif ($ruleValue < 1) $ruleValue = 1;\n\t\t\t\t\tif ($ruleValue > 500) $ruleValue = 500;\n\n\t\t\t\t\t$maxVal = $this->_calculateTopTenValue($columnID,$rangeStart[1]+1,$rangeEnd[1],$toptenRuleType,$ruleValue);\n\n\t\t\t\t\t$operator = ($toptenRuleType == PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP)\n\t\t\t\t\t\t? PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL\n\t\t\t\t\t\t: PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL;\n\t\t\t\t\t$ruleValues[] = array( 'operator' => $operator,\n\t\t\t\t\t\t\t\t\t\t   'value' => $maxVal\n\t\t\t\t\t\t\t\t\t\t );\n\t\t\t\t\t$columnFilterTests[$columnID] = array(\n\t\t\t\t\t\t'method' => '_filterTestInCustomDataSet',\n\t\t\t\t\t\t'arguments' => array( 'filterRules' => $ruleValues,\n\t\t\t\t\t\t\t\t\t\t\t  'join' => PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR\n\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t);\n\t\t\t\t\t$filterColumn->setAttributes(\n\t\t\t\t\t\tarray('maxVal' => $maxVal)\n\t\t\t\t\t);\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n//\t\techo 'Column Filter Test CRITERIA',PHP_EOL;\n//\t\tvar_dump($columnFilterTests);\n//\n\t\t//\tExecute the column tests for each row in the autoFilter range to determine show/hide,\n\t\tfor ($row = $rangeStart[1]+1; $row <= $rangeEnd[1]; ++$row) {\n//\t\t\techo 'Testing Row = ',$row,PHP_EOL;\n\t\t\t$result = TRUE;\n\t\t\tforeach($columnFilterTests as $columnID => $columnFilterTest) {\n//\t\t\t\techo 'Testing cell ',$columnID.$row,PHP_EOL;\n\t\t\t\t$cellValue = $this->_workSheet->getCell($columnID.$row)->getCalculatedValue();\n//\t\t\t\techo 'Value is ',$cellValue,PHP_EOL;\n\t\t\t\t//\tExecute the filter test\n\t\t\t\t$result = $result &&\n\t\t\t\t\tcall_user_func_array(\n\t\t\t\t\t\tarray('PHPExcel_Worksheet_AutoFilter',$columnFilterTest['method']),\n\t\t\t\t\t\tarray(\n\t\t\t\t\t\t\t$cellValue,\n\t\t\t\t\t\t\t$columnFilterTest['arguments']\n\t\t\t\t\t\t)\n\t\t\t\t\t);\n//\t\t\t\techo (($result) ? 'VALID' : 'INVALID'),PHP_EOL;\n\t\t\t\t//\tIf filter test has resulted in FALSE, exit the loop straightaway rather than running any more tests\n\t\t\t\tif (!$result)\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t\t//\tSet show/hide for the row based on the result of the autoFilter result\n//\t\t\techo (($result) ? 'SHOW' : 'HIDE'),PHP_EOL;\n\t\t\t$this->_workSheet->getRowDimension($row)->setVisible($result);\n\t\t}\n\n\t\treturn $this;\n\t}\n\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\tif ($key == '_workSheet') {\n\t\t\t\t\t//\tDetach from worksheet\n\t\t\t\t\t$this->{$key} = NULL;\n\t\t\t\t} else {\n\t\t\t\t\t$this->{$key} = clone $value;\n\t\t\t\t}\n\t\t\t} elseif ((is_array($value)) && ($key == '_columns')) {\n\t\t\t\t//\tThe columns array of PHPExcel_Worksheet_AutoFilter objects\n\t\t\t\t$this->{$key} = array();\n\t\t\t\tforeach ($value as $k => $v) {\n\t\t\t\t\t$this->{$key}[$k] = clone $v;\n\t\t\t\t\t// attach the new cloned Column to this new cloned Autofilter object\n\t\t\t\t\t$this->{$key}[$k]->setParent($this);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t$this->{$key} = $value;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * toString method replicates previous behavior by returning the range if object is\n\t *    referenced as a property of its parent.\n\t */\n\tpublic function __toString() {\n\t\treturn (string) $this->_range;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/BaseDrawing.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_BaseDrawing\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable\n{\n\t/**\n\t * Image counter\n\t *\n\t * @var int\n\t */\n\tprivate static $_imageCounter = 0;\n\n\t/**\n\t * Image index\n\t *\n\t * @var int\n\t */\n\tprivate $_imageIndex = 0;\n\n\t/**\n\t * Name\n\t *\n\t * @var string\n\t */\n\tprotected $_name;\n\n\t/**\n\t * Description\n\t *\n\t * @var string\n\t */\n\tprotected $_description;\n\n\t/**\n\t * Worksheet\n\t *\n\t * @var PHPExcel_Worksheet\n\t */\n\tprotected $_worksheet;\n\n\t/**\n\t * Coordinates\n\t *\n\t * @var string\n\t */\n\tprotected $_coordinates;\n\n\t/**\n\t * Offset X\n\t *\n\t * @var int\n\t */\n\tprotected $_offsetX;\n\n\t/**\n\t * Offset Y\n\t *\n\t * @var int\n\t */\n\tprotected $_offsetY;\n\n\t/**\n\t * Width\n\t *\n\t * @var int\n\t */\n\tprotected $_width;\n\n\t/**\n\t * Height\n\t *\n\t * @var int\n\t */\n\tprotected $_height;\n\n\t/**\n\t * Proportional resize\n\t *\n\t * @var boolean\n\t */\n\tprotected $_resizeProportional;\n\n\t/**\n\t * Rotation\n\t *\n\t * @var int\n\t */\n\tprotected $_rotation;\n\n\t/**\n\t * Shadow\n\t *\n\t * @var PHPExcel_Worksheet_Drawing_Shadow\n\t */\n\tprotected $_shadow;\n\n    /**\n     * Create a new PHPExcel_Worksheet_BaseDrawing\n     */\n    public function __construct()\n    {\n    \t// Initialise values\n    \t$this->_name\t\t\t\t= '';\n    \t$this->_description\t\t\t= '';\n    \t$this->_worksheet\t\t\t= null;\n    \t$this->_coordinates\t\t\t= 'A1';\n    \t$this->_offsetX\t\t\t\t= 0;\n    \t$this->_offsetY\t\t\t\t= 0;\n    \t$this->_width\t\t\t\t= 0;\n    \t$this->_height\t\t\t\t= 0;\n    \t$this->_resizeProportional\t= true;\n    \t$this->_rotation\t\t\t= 0;\n    \t$this->_shadow\t\t\t\t= new PHPExcel_Worksheet_Drawing_Shadow();\n\n\t\t// Set image index\n\t\tself::$_imageCounter++;\n\t\t$this->_imageIndex \t\t\t= self::$_imageCounter;\n    }\n\n    /**\n     * Get image index\n     *\n     * @return int\n     */\n    public function getImageIndex() {\n    \treturn $this->_imageIndex;\n    }\n\n    /**\n     * Get Name\n     *\n     * @return string\n     */\n    public function getName() {\n    \treturn $this->_name;\n    }\n\n    /**\n     * Set Name\n     *\n     * @param string $pValue\n     * @return PHPExcel_Worksheet_BaseDrawing\n     */\n    public function setName($pValue = '') {\n    \t$this->_name = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Description\n     *\n     * @return string\n     */\n    public function getDescription() {\n    \treturn $this->_description;\n    }\n\n    /**\n     * Set Description\n     *\n     * @param string $pValue\n     * @return PHPExcel_Worksheet_BaseDrawing\n     */\n    public function setDescription($pValue = '') {\n    \t$this->_description = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Worksheet\n     *\n     * @return PHPExcel_Worksheet\n     */\n    public function getWorksheet() {\n    \treturn $this->_worksheet;\n    }\n\n    /**\n     * Set Worksheet\n     *\n     * @param \tPHPExcel_Worksheet \t$pValue\n     * @param \tbool\t\t\t\t$pOverrideOld\tIf a Worksheet has already been assigned, overwrite it and remove image from old Worksheet?\n     * @throws \tPHPExcel_Exception\n     * @return PHPExcel_Worksheet_BaseDrawing\n     */\n    public function setWorksheet(PHPExcel_Worksheet $pValue = null, $pOverrideOld = false) {\n    \tif (is_null($this->_worksheet)) {\n    \t\t// Add drawing to PHPExcel_Worksheet\n\t    \t$this->_worksheet = $pValue;\n\t    \t$this->_worksheet->getCell($this->_coordinates);\n\t    \t$this->_worksheet->getDrawingCollection()->append($this);\n    \t} else {\n    \t\tif ($pOverrideOld) {\n    \t\t\t// Remove drawing from old PHPExcel_Worksheet\n    \t\t\t$iterator = $this->_worksheet->getDrawingCollection()->getIterator();\n\n    \t\t\twhile ($iterator->valid()) {\n    \t\t\t\tif ($iterator->current()->getHashCode() == $this->getHashCode()) {\n    \t\t\t\t\t$this->_worksheet->getDrawingCollection()->offsetUnset( $iterator->key() );\n    \t\t\t\t\t$this->_worksheet = null;\n    \t\t\t\t\tbreak;\n    \t\t\t\t}\n    \t\t\t}\n\n    \t\t\t// Set new PHPExcel_Worksheet\n    \t\t\t$this->setWorksheet($pValue);\n    \t\t} else {\n    \t\t\tthrow new PHPExcel_Exception(\"A PHPExcel_Worksheet has already been assigned. Drawings can only exist on one PHPExcel_Worksheet.\");\n    \t\t}\n    \t}\n    \treturn $this;\n    }\n\n    /**\n     * Get Coordinates\n     *\n     * @return string\n     */\n    public function getCoordinates() {\n    \treturn $this->_coordinates;\n    }\n\n    /**\n     * Set Coordinates\n     *\n     * @param string $pValue\n     * @return PHPExcel_Worksheet_BaseDrawing\n     */\n    public function setCoordinates($pValue = 'A1') {\n    \t$this->_coordinates = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get OffsetX\n     *\n     * @return int\n     */\n    public function getOffsetX() {\n    \treturn $this->_offsetX;\n    }\n\n    /**\n     * Set OffsetX\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_BaseDrawing\n     */\n    public function setOffsetX($pValue = 0) {\n    \t$this->_offsetX = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get OffsetY\n     *\n     * @return int\n     */\n    public function getOffsetY() {\n    \treturn $this->_offsetY;\n    }\n\n    /**\n     * Set OffsetY\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_BaseDrawing\n     */\n    public function setOffsetY($pValue = 0) {\n    \t$this->_offsetY = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Width\n     *\n     * @return int\n     */\n    public function getWidth() {\n    \treturn $this->_width;\n    }\n\n    /**\n     * Set Width\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_BaseDrawing\n     */\n    public function setWidth($pValue = 0) {\n    \t// Resize proportional?\n    \tif ($this->_resizeProportional && $pValue != 0) {\n    \t\t$ratio = $this->_height / ($this->_width != 0 ? $this->_width : 1);\n    \t\t$this->_height = round($ratio * $pValue);\n    \t}\n\n    \t// Set width\n    \t$this->_width = $pValue;\n\n    \treturn $this;\n    }\n\n    /**\n     * Get Height\n     *\n     * @return int\n     */\n    public function getHeight() {\n    \treturn $this->_height;\n    }\n\n    /**\n     * Set Height\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_BaseDrawing\n     */\n    public function setHeight($pValue = 0) {\n    \t// Resize proportional?\n    \tif ($this->_resizeProportional && $pValue != 0) {\n    \t\t$ratio = $this->_width / ($this->_height != 0 ? $this->_height : 1);\n    \t\t$this->_width = round($ratio * $pValue);\n    \t}\n\n    \t// Set height\n    \t$this->_height = $pValue;\n\n    \treturn $this;\n    }\n\n    /**\n     * Set width and height with proportional resize\n\t * Example:\n\t * <code>\n\t * $objDrawing->setResizeProportional(true);\n\t * $objDrawing->setWidthAndHeight(160,120);\n\t * </code>\n\t *\n     * @author Vincent@luo MSN:kele_100@hotmail.com\n     * @param int $width\n     * @param int $height\n     * @return PHPExcel_Worksheet_BaseDrawing\n     */\n\tpublic function setWidthAndHeight($width = 0, $height = 0) {\n\t\t$xratio = $width / ($this->_width != 0 ? $this->_width : 1);\n\t\t$yratio = $height / ($this->_height != 0 ? $this->_height : 1);\n\t\tif ($this->_resizeProportional && !($width == 0 || $height == 0)) {\n\t\t\tif (($xratio * $this->_height) < $height) {\n\t\t\t\t$this->_height = ceil($xratio * $this->_height);\n\t\t\t\t$this->_width  = $width;\n\t\t\t} else {\n\t\t\t\t$this->_width\t= ceil($yratio * $this->_width);\n\t\t\t\t$this->_height\t= $height;\n\t\t\t}\n\t\t} else {\n            $this->_width = $width;\n            $this->_height = $height;\n        }\n\n\t\treturn $this;\n\t}\n\n    /**\n     * Get ResizeProportional\n     *\n     * @return boolean\n     */\n    public function getResizeProportional() {\n    \treturn $this->_resizeProportional;\n    }\n\n    /**\n     * Set ResizeProportional\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_BaseDrawing\n     */\n    public function setResizeProportional($pValue = true) {\n    \t$this->_resizeProportional = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Rotation\n     *\n     * @return int\n     */\n    public function getRotation() {\n    \treturn $this->_rotation;\n    }\n\n    /**\n     * Set Rotation\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_BaseDrawing\n     */\n    public function setRotation($pValue = 0) {\n    \t$this->_rotation = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Shadow\n     *\n     * @return PHPExcel_Worksheet_Drawing_Shadow\n     */\n    public function getShadow() {\n    \treturn $this->_shadow;\n    }\n\n    /**\n     * Set Shadow\n     *\n     * @param \tPHPExcel_Worksheet_Drawing_Shadow $pValue\n     * @throws \tPHPExcel_Exception\n     * @return PHPExcel_Worksheet_BaseDrawing\n     */\n    public function setShadow(PHPExcel_Worksheet_Drawing_Shadow $pValue = null) {\n   \t\t$this->_shadow = $pValue;\n   \t\treturn $this;\n    }\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n    \treturn md5(\n    \t\t  $this->_name\n    \t\t. $this->_description\n    \t\t. $this->_worksheet->getHashCode()\n    \t\t. $this->_coordinates\n    \t\t. $this->_offsetX\n    \t\t. $this->_offsetY\n    \t\t. $this->_width\n    \t\t. $this->_height\n    \t\t. $this->_rotation\n    \t\t. $this->_shadow->getHashCode()\n    \t\t. __CLASS__\n    \t);\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/CellIterator.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    1.8.0, 2014-03-02\n */\n\n\n/**\n * PHPExcel_Worksheet_CellIterator\n *\n * Used to iterate rows in a PHPExcel_Worksheet\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nabstract class PHPExcel_Worksheet_CellIterator\n{\n\t/**\n\t * PHPExcel_Worksheet to iterate\n\t *\n\t * @var PHPExcel_Worksheet\n\t */\n\tprotected $_subject;\n\n\t/**\n\t * Current iterator position\n\t *\n\t * @var mixed\n\t */\n\tprotected $_position = null;\n\n\t/**\n\t * Iterate only existing cells\n\t *\n\t * @var boolean\n\t */\n\tprotected $_onlyExistingCells = false;\n\n\t/**\n\t * Destructor\n\t */\n\tpublic function __destruct() {\n\t\tunset($this->_subject);\n\t}\n\n\t/**\n\t * Get loop only existing cells\n\t *\n\t * @return boolean\n\t */\n    public function getIterateOnlyExistingCells() {\n    \treturn $this->_onlyExistingCells;\n    }\n\n\t/**\n\t * Validate start/end values for \"IterateOnlyExistingCells\" mode, and adjust if necessary\n\t *\n     * @throws PHPExcel_Exception\n\t */\n    abstract protected function adjustForExistingOnlyRange();\n\n\t/**\n\t * Set the iterator to loop only existing cells\n\t *\n\t * @param\tboolean\t\t$value\n     * @throws PHPExcel_Exception\n\t */\n    public function setIterateOnlyExistingCells($value = true) {\n    \t$this->_onlyExistingCells = (boolean) $value;\n\n        $this->adjustForExistingOnlyRange();\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Column.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_Column\n *\n * Represents a column in PHPExcel_Worksheet, used by PHPExcel_Worksheet_ColumnIterator\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_Column\n{\n\t/**\n\t * PHPExcel_Worksheet\n\t *\n\t * @var PHPExcel_Worksheet\n\t */\n\tprivate $_parent;\n\n\t/**\n\t * Column index\n\t *\n\t * @var string\n\t */\n\tprivate $_columnIndex;\n\n\t/**\n\t * Create a new column\n\t *\n\t * @param PHPExcel_Worksheet \t$parent\n\t * @param string\t\t\t\t$columnIndex\n\t */\n\tpublic function __construct(PHPExcel_Worksheet $parent = null, $columnIndex = 'A') {\n\t\t// Set parent and column index\n\t\t$this->_parent \t\t= $parent;\n\t\t$this->_columnIndex = $columnIndex;\n\t}\n\n\t/**\n\t * Destructor\n\t */\n\tpublic function __destruct() {\n\t\tunset($this->_parent);\n\t}\n\n\t/**\n\t * Get column index\n\t *\n\t * @return int\n\t */\n\tpublic function getColumnIndex() {\n\t\treturn $this->_columnIndex;\n\t}\n\n\t/**\n\t * Get cell iterator\n\t *\n\t * @param\tinteger\t\t\t\t$startRow\t    The row number at which to start iterating\n\t * @param\tinteger\t\t\t\t$endRow\t        Optionally, the row number at which to stop iterating\n\t * @return PHPExcel_Worksheet_CellIterator\n\t */\n\tpublic function getCellIterator($startRow = 1, $endRow = null) {\n\t\treturn new PHPExcel_Worksheet_ColumnCellIterator($this->_parent, $this->_columnIndex, $startRow, $endRow);\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/ColumnCellIterator.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_ColumnCellIterator\n *\n * Used to iterate columns in a PHPExcel_Worksheet\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_ColumnCellIterator extends PHPExcel_Worksheet_CellIterator implements Iterator\n{\n\t/**\n\t * Column index\n\t *\n\t * @var string\n\t */\n\tprotected $_columnIndex;\n\n    /**\n\t * Start position\n\t *\n\t * @var int\n\t */\n\tprotected $_startRow = 1;\n\n\t/**\n\t * End position\n\t *\n\t * @var int\n\t */\n\tprotected $_endRow = 1;\n\n\t/**\n\t * Create a new row iterator\n\t *\n\t * @param\tPHPExcel_Worksheet\t$subject\t    The worksheet to iterate over\n     * @param   string              $columnIndex    The column that we want to iterate\n\t * @param\tinteger\t\t\t\t$startRow\t    The row number at which to start iterating\n\t * @param\tinteger\t\t\t\t$endRow\t        Optionally, the row number at which to stop iterating\n\t */\n\tpublic function __construct(PHPExcel_Worksheet $subject = null, $columnIndex, $startRow = 1, $endRow = null) {\n\t\t// Set subject\n\t\t$this->_subject = $subject;\n\t\t$this->_columnIndex = PHPExcel_Cell::columnIndexFromString($columnIndex) - 1;\n\t\t$this->resetEnd($endRow);\n\t\t$this->resetStart($startRow);\n\t}\n\n\t/**\n\t * Destructor\n\t */\n\tpublic function __destruct() {\n\t\tunset($this->_subject);\n\t}\n\n\t/**\n\t * (Re)Set the start row and the current row pointer\n\t *\n\t * @param integer\t$startRow\tThe row number at which to start iterating\n     * @return PHPExcel_Worksheet_ColumnCellIterator\n     * @throws PHPExcel_Exception\n\t */\n\tpublic function resetStart($startRow = 1) {\n\t\t$this->_startRow = $startRow;\n        $this->adjustForExistingOnlyRange();\n\t\t$this->seek($startRow);\n\n        return $this;\n\t}\n\n\t/**\n\t * (Re)Set the end row\n\t *\n\t * @param integer\t$endRow\tThe row number at which to stop iterating\n     * @return PHPExcel_Worksheet_ColumnCellIterator\n     * @throws PHPExcel_Exception\n\t */\n\tpublic function resetEnd($endRow = null) {\n\t\t$this->_endRow = ($endRow) ? $endRow : $this->_subject->getHighestRow();\n        $this->adjustForExistingOnlyRange();\n\n        return $this;\n\t}\n\n\t/**\n\t * Set the row pointer to the selected row\n\t *\n\t * @param integer\t$row\tThe row number to set the current pointer at\n     * @return PHPExcel_Worksheet_ColumnCellIterator\n     * @throws PHPExcel_Exception\n\t */\n\tpublic function seek($row = 1) {\n        if (($row < $this->_startRow) || ($row > $this->_endRow)) {\n            throw new PHPExcel_Exception(\"Row $row is out of range ({$this->_startRow} - {$this->_endRow})\");\n        } elseif ($this->_onlyExistingCells && !($this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $row))) {\n            throw new PHPExcel_Exception('In \"IterateOnlyExistingCells\" mode and Cell does not exist');\n        }\n\t\t$this->_position = $row;\n\n        return $this;\n\t}\n\n\t/**\n\t * Rewind the iterator to the starting row\n\t */\n\tpublic function rewind() {\n\t\t$this->_position = $this->_startRow;\n\t}\n\n\t/**\n\t * Return the current cell in this worksheet column\n\t *\n\t * @return PHPExcel_Worksheet_Row\n\t */\n\tpublic function current() {\n\t\treturn $this->_subject->getCellByColumnAndRow($this->_columnIndex, $this->_position);\n\t}\n\n\t/**\n\t * Return the current iterator key\n\t *\n\t * @return int\n\t */\n\tpublic function key() {\n\t\treturn $this->_position;\n\t}\n\n\t/**\n\t * Set the iterator to its next value\n\t */\n\tpublic function next() {\n        do {\n            ++$this->_position;\n        } while (($this->_onlyExistingCells) &&\n            (!$this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $this->_position)) &&\n            ($this->_position <= $this->_endRow));\n\t}\n\n\t/**\n\t * Set the iterator to its previous value\n\t */\n\tpublic function prev() {\n        if ($this->_position <= $this->_startRow) {\n            throw new PHPExcel_Exception(\"Row is already at the beginning of range ({$this->_startRow} - {$this->_endRow})\");\n        }\n\n        do {\n            --$this->_position;\n        } while (($this->_onlyExistingCells) &&\n            (!$this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $this->_position)) &&\n            ($this->_position >= $this->_startRow));\n\t}\n\n\t/**\n\t * Indicate if more rows exist in the worksheet range of rows that we're iterating\n\t *\n\t * @return boolean\n\t */\n\tpublic function valid() {\n\t\treturn $this->_position <= $this->_endRow;\n\t}\n\n\t/**\n\t * Validate start/end values for \"IterateOnlyExistingCells\" mode, and adjust if necessary\n\t *\n     * @throws PHPExcel_Exception\n\t */\n    protected function adjustForExistingOnlyRange() {\n        if ($this->_onlyExistingCells) {\n            while ((!$this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $this->_startRow)) &&\n                ($this->_startRow <= $this->_endRow)) {\n                ++$this->_startRow;\n            }\n            if ($this->_startRow > $this->_endRow) {\n                throw new PHPExcel_Exception('No cells exist within the specified range');\n            }\n            while ((!$this->_subject->cellExistsByColumnAndRow($this->_columnIndex, $this->_endRow)) &&\n                ($this->_endRow >= $this->_startRow)) {\n                --$this->_endRow;\n            }\n            if ($this->_endRow < $this->_startRow) {\n                throw new PHPExcel_Exception('No cells exist within the specified range');\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/ColumnDimension.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_ColumnDimension\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_ColumnDimension\n{\n\t/**\n\t * Column index\n\t *\n\t * @var int\n\t */\n\tprivate $_columnIndex;\n\n\t/**\n\t * Column width\n\t *\n\t * When this is set to a negative value, the column width should be ignored by IWriter\n\t *\n\t * @var double\n\t */\n\tprivate $_width\t\t\t= -1;\n\n\t/**\n\t * Auto size?\n\t *\n\t * @var bool\n\t */\n\tprivate $_autoSize\t\t= false;\n\n\t/**\n\t * Visible?\n\t *\n\t * @var bool\n\t */\n\tprivate $_visible\t\t= true;\n\n\t/**\n\t * Outline level\n\t *\n\t * @var int\n\t */\n\tprivate $_outlineLevel\t= 0;\n\n\t/**\n\t * Collapsed\n\t *\n\t * @var bool\n\t */\n\tprivate $_collapsed\t\t= false;\n\n\t/**\n\t * Index to cellXf\n\t *\n\t * @var int\n\t */\n\tprivate $_xfIndex;\n\n    /**\n     * Create a new PHPExcel_Worksheet_ColumnDimension\n     *\n     * @param string $pIndex Character column index\n     */\n    public function __construct($pIndex = 'A')\n    {\n    \t// Initialise values\n    \t$this->_columnIndex\t\t= $pIndex;\n\n\t\t// set default index to cellXf\n\t\t$this->_xfIndex = 0;\n    }\n\n    /**\n     * Get ColumnIndex\n     *\n     * @return string\n     */\n    public function getColumnIndex() {\n    \treturn $this->_columnIndex;\n    }\n\n    /**\n     * Set ColumnIndex\n     *\n     * @param string $pValue\n     * @return PHPExcel_Worksheet_ColumnDimension\n     */\n    public function setColumnIndex($pValue) {\n    \t$this->_columnIndex = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Width\n     *\n     * @return double\n     */\n    public function getWidth() {\n    \treturn $this->_width;\n    }\n\n    /**\n     * Set Width\n     *\n     * @param double $pValue\n     * @return PHPExcel_Worksheet_ColumnDimension\n     */\n    public function setWidth($pValue = -1) {\n    \t$this->_width = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Auto Size\n     *\n     * @return bool\n     */\n    public function getAutoSize() {\n    \treturn $this->_autoSize;\n    }\n\n    /**\n     * Set Auto Size\n     *\n     * @param bool $pValue\n     * @return PHPExcel_Worksheet_ColumnDimension\n     */\n    public function setAutoSize($pValue = false) {\n    \t$this->_autoSize = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Visible\n     *\n     * @return bool\n     */\n    public function getVisible() {\n    \treturn $this->_visible;\n    }\n\n    /**\n     * Set Visible\n     *\n     * @param bool $pValue\n     * @return PHPExcel_Worksheet_ColumnDimension\n     */\n    public function setVisible($pValue = true) {\n    \t$this->_visible = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Outline Level\n     *\n     * @return int\n     */\n    public function getOutlineLevel() {\n    \treturn $this->_outlineLevel;\n    }\n\n    /**\n     * Set Outline Level\n     *\n     * Value must be between 0 and 7\n     *\n     * @param int $pValue\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet_ColumnDimension\n     */\n    public function setOutlineLevel($pValue) {\n    \tif ($pValue < 0 || $pValue > 7) {\n    \t\tthrow new PHPExcel_Exception(\"Outline level must range between 0 and 7.\");\n    \t}\n\n    \t$this->_outlineLevel = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Collapsed\n     *\n     * @return bool\n     */\n    public function getCollapsed() {\n    \treturn $this->_collapsed;\n    }\n\n    /**\n     * Set Collapsed\n     *\n     * @param bool $pValue\n     * @return PHPExcel_Worksheet_ColumnDimension\n     */\n    public function setCollapsed($pValue = true) {\n    \t$this->_collapsed = $pValue;\n    \treturn $this;\n    }\n\n\t/**\n\t * Get index to cellXf\n\t *\n\t * @return int\n\t */\n\tpublic function getXfIndex()\n\t{\n\t\treturn $this->_xfIndex;\n\t}\n\n\t/**\n\t * Set index to cellXf\n\t *\n\t * @param int $pValue\n\t * @return PHPExcel_Worksheet_ColumnDimension\n\t */\n\tpublic function setXfIndex($pValue = 0)\n\t{\n\t\t$this->_xfIndex = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/ColumnIterator.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_ColumnIterator\n *\n * Used to iterate columns in a PHPExcel_Worksheet\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_ColumnIterator implements Iterator\n{\n\t/**\n\t * PHPExcel_Worksheet to iterate\n\t *\n\t * @var PHPExcel_Worksheet\n\t */\n\tprivate $_subject;\n\n\t/**\n\t * Current iterator position\n\t *\n\t * @var int\n\t */\n\tprivate $_position = 0;\n\n\t/**\n\t * Start position\n\t *\n\t * @var int\n\t */\n\tprivate $_startColumn = 0;\n\n\n\t/**\n\t * End position\n\t *\n\t * @var int\n\t */\n\tprivate $_endColumn = 0;\n\n\n\t/**\n\t * Create a new column iterator\n\t *\n\t * @param\tPHPExcel_Worksheet\t$subject\tThe worksheet to iterate over\n\t * @param\tstring\t\t\t\t$startColumn\tThe column address at which to start iterating\n\t * @param\tstring\t\t\t\t$endColumn\t    Optionally, the column address at which to stop iterating\n\t */\n\tpublic function __construct(PHPExcel_Worksheet $subject = null, $startColumn = 'A', $endColumn = null) {\n\t\t// Set subject\n\t\t$this->_subject = $subject;\n\t\t$this->resetEnd($endColumn);\n\t\t$this->resetStart($startColumn);\n\t}\n\n\t/**\n\t * Destructor\n\t */\n\tpublic function __destruct() {\n\t\tunset($this->_subject);\n\t}\n\n\t/**\n\t * (Re)Set the start column and the current column pointer\n\t *\n\t * @param integer\t$startColumn\tThe column address at which to start iterating\n     * @return PHPExcel_Worksheet_ColumnIterator\n\t */\n\tpublic function resetStart($startColumn = 'A') {\n        $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1;\n\t\t$this->_startColumn = $startColumnIndex;\n\t\t$this->seek($startColumn);\n\n        return $this;\n\t}\n\n\t/**\n\t * (Re)Set the end column\n\t *\n\t * @param string\t$endColumn\tThe column address at which to stop iterating\n     * @return PHPExcel_Worksheet_ColumnIterator\n\t */\n\tpublic function resetEnd($endColumn = null) {\n\t\t$endColumn = ($endColumn) ? $endColumn : $this->_subject->getHighestColumn();\n\t\t$this->_endColumn = PHPExcel_Cell::columnIndexFromString($endColumn) - 1;\n\n        return $this;\n\t}\n\n\t/**\n\t * Set the column pointer to the selected column\n\t *\n\t * @param string\t$column\tThe column address to set the current pointer at\n     * @return PHPExcel_Worksheet_ColumnIterator\n     * @throws PHPExcel_Exception\n\t */\n\tpublic function seek($column = 'A') {\n        $column = PHPExcel_Cell::columnIndexFromString($column) - 1;\n        if (($column < $this->_startColumn) || ($column > $this->_endColumn)) {\n            throw new PHPExcel_Exception(\"Column $column is out of range ({$this->_startColumn} - {$this->_endColumn})\");\n        }\n\t\t$this->_position = $column;\n\n        return $this;\n    }\n\n\t/**\n\t * Rewind the iterator to the starting column\n\t */\n\tpublic function rewind() {\n\t\t$this->_position = $this->_startColumn;\n\t}\n\n\t/**\n\t * Return the current column in this worksheet\n\t *\n\t * @return PHPExcel_Worksheet_Column\n\t */\n\tpublic function current() {\n\t\treturn new PHPExcel_Worksheet_Column($this->_subject, PHPExcel_Cell::stringFromColumnIndex($this->_position));\n\t}\n\n\t/**\n\t * Return the current iterator key\n\t *\n\t * @return string\n\t */\n\tpublic function key() {\n\t\treturn PHPExcel_Cell::stringFromColumnIndex($this->_position);\n\t}\n\n\t/**\n\t * Set the iterator to its next value\n\t */\n\tpublic function next() {\n\t\t++$this->_position;\n\t}\n\n\t/**\n\t * Set the iterator to its previous value\n     *\n     * @throws PHPExcel_Exception\n\t */\n\tpublic function prev() {\n        if ($this->_position <= $this->_startColumn) {\n            throw new PHPExcel_Exception(\n                \"Column is already at the beginning of range (\" . \n                PHPExcel_Cell::stringFromColumnIndex($this->_endColumn) . \" - \" . \n                PHPExcel_Cell::stringFromColumnIndex($this->_endColumn) . \")\"\n            );\n        }\n\n        --$this->_position;\n\t}\n\n\t/**\n\t * Indicate if more columns exist in the worksheet range of columns that we're iterating\n\t *\n\t * @return boolean\n\t */\n\tpublic function valid() {\n\t\treturn $this->_position <= $this->_endColumn;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Drawing/Shadow.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet_Drawing\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_Drawing_Shadow\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet_Drawing\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_Drawing_Shadow implements PHPExcel_IComparable\n{\n\t/* Shadow alignment */\n\tconst SHADOW_BOTTOM\t\t\t\t\t\t\t= 'b';\n\tconst SHADOW_BOTTOM_LEFT\t\t\t\t\t= 'bl';\n\tconst SHADOW_BOTTOM_RIGHT\t\t\t\t\t= 'br';\n\tconst SHADOW_CENTER\t\t\t\t\t\t\t= 'ctr';\n\tconst SHADOW_LEFT\t\t\t\t\t\t\t= 'l';\n\tconst SHADOW_TOP\t\t\t\t\t\t\t= 't';\n\tconst SHADOW_TOP_LEFT\t\t\t\t\t\t= 'tl';\n\tconst SHADOW_TOP_RIGHT\t\t\t\t\t\t= 'tr';\n\n\t/**\n\t * Visible\n\t *\n\t * @var boolean\n\t */\n\tprivate $_visible;\n\n\t/**\n\t * Blur radius\n\t *\n\t * Defaults to 6\n\t *\n\t * @var int\n\t */\n\tprivate $_blurRadius;\n\n\t/**\n\t * Shadow distance\n\t *\n\t * Defaults to 2\n\t *\n\t * @var int\n\t */\n\tprivate $_distance;\n\n\t/**\n\t * Shadow direction (in degrees)\n\t *\n\t * @var int\n\t */\n\tprivate $_direction;\n\n\t/**\n\t * Shadow alignment\n\t *\n\t * @var int\n\t */\n\tprivate $_alignment;\n\n\t/**\n\t * Color\n\t *\n\t * @var PHPExcel_Style_Color\n\t */\n\tprivate $_color;\n\n\t/**\n\t * Alpha\n\t *\n\t * @var int\n\t */\n\tprivate $_alpha;\n\n    /**\n     * Create a new PHPExcel_Worksheet_Drawing_Shadow\n     */\n    public function __construct()\n    {\n    \t// Initialise values\n    \t$this->_visible\t\t\t\t= false;\n    \t$this->_blurRadius\t\t\t= 6;\n    \t$this->_distance\t\t\t= 2;\n    \t$this->_direction\t\t\t= 0;\n    \t$this->_alignment\t\t\t= PHPExcel_Worksheet_Drawing_Shadow::SHADOW_BOTTOM_RIGHT;\n    \t$this->_color\t\t\t\t= new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_BLACK);\n    \t$this->_alpha\t\t\t\t= 50;\n    }\n\n    /**\n     * Get Visible\n     *\n     * @return boolean\n     */\n    public function getVisible() {\n    \treturn $this->_visible;\n    }\n\n    /**\n     * Set Visible\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Drawing_Shadow\n     */\n    public function setVisible($pValue = false) {\n    \t$this->_visible = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Blur radius\n     *\n     * @return int\n     */\n    public function getBlurRadius() {\n    \treturn $this->_blurRadius;\n    }\n\n    /**\n     * Set Blur radius\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_Drawing_Shadow\n     */\n    public function setBlurRadius($pValue = 6) {\n    \t$this->_blurRadius = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Shadow distance\n     *\n     * @return int\n     */\n    public function getDistance() {\n    \treturn $this->_distance;\n    }\n\n    /**\n     * Set Shadow distance\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_Drawing_Shadow\n     */\n    public function setDistance($pValue = 2) {\n    \t$this->_distance = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Shadow direction (in degrees)\n     *\n     * @return int\n     */\n    public function getDirection() {\n    \treturn $this->_direction;\n    }\n\n    /**\n     * Set Shadow direction (in degrees)\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_Drawing_Shadow\n     */\n    public function setDirection($pValue = 0) {\n    \t$this->_direction = $pValue;\n    \treturn $this;\n    }\n\n   /**\n     * Get Shadow alignment\n     *\n     * @return int\n     */\n    public function getAlignment() {\n    \treturn $this->_alignment;\n    }\n\n    /**\n     * Set Shadow alignment\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_Drawing_Shadow\n     */\n    public function setAlignment($pValue = 0) {\n    \t$this->_alignment = $pValue;\n    \treturn $this;\n    }\n\n   /**\n     * Get Color\n     *\n     * @return PHPExcel_Style_Color\n     */\n    public function getColor() {\n    \treturn $this->_color;\n    }\n\n    /**\n     * Set Color\n     *\n     * @param \tPHPExcel_Style_Color $pValue\n     * @throws \tPHPExcel_Exception\n     * @return PHPExcel_Worksheet_Drawing_Shadow\n     */\n    public function setColor(PHPExcel_Style_Color $pValue = null) {\n   \t\t$this->_color = $pValue;\n   \t\treturn $this;\n    }\n\n   /**\n     * Get Alpha\n     *\n     * @return int\n     */\n    public function getAlpha() {\n    \treturn $this->_alpha;\n    }\n\n    /**\n     * Set Alpha\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_Drawing_Shadow\n     */\n    public function setAlpha($pValue = 0) {\n    \t$this->_alpha = $pValue;\n    \treturn $this;\n    }\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n    \treturn md5(\n    \t\t  ($this->_visible ? 't' : 'f')\n    \t\t. $this->_blurRadius\n    \t\t. $this->_distance\n    \t\t. $this->_direction\n    \t\t. $this->_alignment\n    \t\t. $this->_color->getHashCode()\n    \t\t. $this->_alpha\n    \t\t. __CLASS__\n    \t);\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Drawing.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet_Drawing\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_Drawing\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet_Drawing\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_Drawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable\n{\n\t/**\n\t * Path\n\t *\n\t * @var string\n\t */\n\tprivate $_path;\n\n    /**\n     * Create a new PHPExcel_Worksheet_Drawing\n     */\n    public function __construct()\n    {\n    \t// Initialise values\n    \t$this->_path\t\t\t\t= '';\n\n    \t// Initialize parent\n    \tparent::__construct();\n    }\n\n    /**\n     * Get Filename\n     *\n     * @return string\n     */\n    public function getFilename() {\n    \treturn basename($this->_path);\n    }\n\n    /**\n     * Get indexed filename (using image index)\n     *\n     * @return string\n     */\n    public function getIndexedFilename() {\n    \t$fileName = $this->getFilename();\n    \t$fileName = str_replace(' ', '_', $fileName);\n    \treturn str_replace('.' . $this->getExtension(), '', $fileName) . $this->getImageIndex() . '.' . $this->getExtension();\n    }\n\n    /**\n     * Get Extension\n     *\n     * @return string\n     */\n    public function getExtension() {\n    \t$exploded = explode(\".\", basename($this->_path));\n    \treturn $exploded[count($exploded) - 1];\n    }\n\n    /**\n     * Get Path\n     *\n     * @return string\n     */\n    public function getPath() {\n    \treturn $this->_path;\n    }\n\n    /**\n     * Set Path\n     *\n     * @param \tstring \t\t$pValue\t\t\tFile path\n     * @param \tboolean\t\t$pVerifyFile\tVerify file\n     * @throws \tPHPExcel_Exception\n     * @return PHPExcel_Worksheet_Drawing\n     */\n    public function setPath($pValue = '', $pVerifyFile = true) {\n    \tif ($pVerifyFile) {\n\t    \tif (file_exists($pValue)) {\n\t    \t\t$this->_path = $pValue;\n\n\t    \t\tif ($this->_width == 0 && $this->_height == 0) {\n\t    \t\t\t// Get width/height\n\t    \t\t\tlist($this->_width, $this->_height) = getimagesize($pValue);\n\t    \t\t}\n\t    \t} else {\n\t    \t\tthrow new PHPExcel_Exception(\"File $pValue not found!\");\n\t    \t}\n    \t} else {\n    \t\t$this->_path = $pValue;\n    \t}\n    \treturn $this;\n    }\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n    \treturn md5(\n    \t\t  $this->_path\n    \t\t. parent::getHashCode()\n    \t\t. __CLASS__\n    \t);\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/HeaderFooter.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_HeaderFooter\n *\n * <code>\n * Header/Footer Formatting Syntax taken from Office Open XML Part 4 - Markup Language Reference, page 1970:\n *\n * There are a number of formatting codes that can be written inline with the actual header / footer text, which\n * affect the formatting in the header or footer.\n *\n * Example: This example shows the text \"Center Bold Header\" on the first line (center section), and the date on\n * the second line (center section).\n * \t\t&CCenter &\"-,Bold\"Bold&\"-,Regular\"Header_x000A_&D\n *\n * General Rules:\n * There is no required order in which these codes must appear.\n *\n * The first occurrence of the following codes turns the formatting ON, the second occurrence turns it OFF again:\n * - strikethrough\n * - superscript\n * - subscript\n * Superscript and subscript cannot both be ON at same time. Whichever comes first wins and the other is ignored,\n * while the first is ON.\n * &L - code for \"left section\" (there are three header / footer locations, \"left\", \"center\", and \"right\"). When\n * two or more occurrences of this section marker exist, the contents from all markers are concatenated, in the\n * order of appearance, and placed into the left section.\n * &P - code for \"current page #\"\n * &N - code for \"total pages\"\n * &font size - code for \"text font size\", where font size is a font size in points.\n * &K - code for \"text font color\"\n * RGB Color is specified as RRGGBB\n * Theme Color is specifed as TTSNN where TT is the theme color Id, S is either \"+\" or \"-\" of the tint/shade\n * value, NN is the tint/shade value.\n * &S - code for \"text strikethrough\" on / off\n * &X - code for \"text super script\" on / off\n * &Y - code for \"text subscript\" on / off\n * &C - code for \"center section\". When two or more occurrences of this section marker exist, the contents\n * from all markers are concatenated, in the order of appearance, and placed into the center section.\n *\n * &D - code for \"date\"\n * &T - code for \"time\"\n * &G - code for \"picture as background\"\n * &U - code for \"text single underline\"\n * &E - code for \"double underline\"\n * &R - code for \"right section\". When two or more occurrences of this section marker exist, the contents\n * from all markers are concatenated, in the order of appearance, and placed into the right section.\n * &Z - code for \"this workbook's file path\"\n * &F - code for \"this workbook's file name\"\n * &A - code for \"sheet tab name\"\n * &+ - code for add to page #.\n * &- - code for subtract from page #.\n * &\"font name,font type\" - code for \"text font name\" and \"text font type\", where font name and font type\n * are strings specifying the name and type of the font, separated by a comma. When a hyphen appears in font\n * name, it means \"none specified\". Both of font name and font type can be localized values.\n * &\"-,Bold\" - code for \"bold font style\"\n * &B - also means \"bold font style\".\n * &\"-,Regular\" - code for \"regular font style\"\n * &\"-,Italic\" - code for \"italic font style\"\n * &I - also means \"italic font style\"\n * &\"-,Bold Italic\" code for \"bold italic font style\"\n * &O - code for \"outline style\"\n * &H - code for \"shadow style\"\n * </code>\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_HeaderFooter\n{\n\t/* Header/footer image location */\n\tconst IMAGE_HEADER_LEFT\t\t\t\t\t\t\t= 'LH';\n\tconst IMAGE_HEADER_CENTER\t\t\t\t\t\t= 'CH';\n\tconst IMAGE_HEADER_RIGHT\t\t\t\t\t\t= 'RH';\n\tconst IMAGE_FOOTER_LEFT\t\t\t\t\t\t\t= 'LF';\n\tconst IMAGE_FOOTER_CENTER\t\t\t\t\t\t= 'CF';\n\tconst IMAGE_FOOTER_RIGHT\t\t\t\t\t\t= 'RF';\n\n\t/**\n\t * OddHeader\n\t *\n\t * @var string\n\t */\n\tprivate $_oddHeader\t\t\t= '';\n\n\t/**\n\t * OddFooter\n\t *\n\t * @var string\n\t */\n\tprivate $_oddFooter\t\t\t= '';\n\n\t/**\n\t * EvenHeader\n\t *\n\t * @var string\n\t */\n\tprivate $_evenHeader\t\t= '';\n\n\t/**\n\t * EvenFooter\n\t *\n\t * @var string\n\t */\n\tprivate $_evenFooter\t\t= '';\n\n\t/**\n\t * FirstHeader\n\t *\n\t * @var string\n\t */\n\tprivate $_firstHeader\t\t= '';\n\n\t/**\n\t * FirstFooter\n\t *\n\t * @var string\n\t */\n\tprivate $_firstFooter\t\t= '';\n\n\t/**\n\t * Different header for Odd/Even, defaults to false\n\t *\n\t * @var boolean\n\t */\n\tprivate $_differentOddEven\t= false;\n\n\t/**\n\t * Different header for first page, defaults to false\n\t *\n\t * @var boolean\n\t */\n\tprivate $_differentFirst\t= false;\n\n\t/**\n\t * Scale with document, defaults to true\n\t *\n\t * @var boolean\n\t */\n\tprivate $_scaleWithDocument\t= true;\n\n\t/**\n\t * Align with margins, defaults to true\n\t *\n\t * @var boolean\n\t */\n\tprivate $_alignWithMargins\t= true;\n\n\t/**\n\t * Header/footer images\n\t *\n\t * @var PHPExcel_Worksheet_HeaderFooterDrawing[]\n\t */\n\tprivate $_headerFooterImages = array();\n\n    /**\n     * Create a new PHPExcel_Worksheet_HeaderFooter\n     */\n    public function __construct()\n    {\n    }\n\n    /**\n     * Get OddHeader\n     *\n     * @return string\n     */\n    public function getOddHeader() {\n    \treturn $this->_oddHeader;\n    }\n\n    /**\n     * Set OddHeader\n     *\n     * @param string $pValue\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function setOddHeader($pValue) {\n    \t$this->_oddHeader = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get OddFooter\n     *\n     * @return string\n     */\n    public function getOddFooter() {\n    \treturn $this->_oddFooter;\n    }\n\n    /**\n     * Set OddFooter\n     *\n     * @param string $pValue\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function setOddFooter($pValue) {\n    \t$this->_oddFooter = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get EvenHeader\n     *\n     * @return string\n     */\n    public function getEvenHeader() {\n    \treturn $this->_evenHeader;\n    }\n\n    /**\n     * Set EvenHeader\n     *\n     * @param string $pValue\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function setEvenHeader($pValue) {\n    \t$this->_evenHeader = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get EvenFooter\n     *\n     * @return string\n     */\n    public function getEvenFooter() {\n    \treturn $this->_evenFooter;\n    }\n\n    /**\n     * Set EvenFooter\n     *\n     * @param string $pValue\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function setEvenFooter($pValue) {\n    \t$this->_evenFooter = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get FirstHeader\n     *\n     * @return string\n     */\n    public function getFirstHeader() {\n    \treturn $this->_firstHeader;\n    }\n\n    /**\n     * Set FirstHeader\n     *\n     * @param string $pValue\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function setFirstHeader($pValue) {\n    \t$this->_firstHeader = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get FirstFooter\n     *\n     * @return string\n     */\n    public function getFirstFooter() {\n    \treturn $this->_firstFooter;\n    }\n\n    /**\n     * Set FirstFooter\n     *\n     * @param string $pValue\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function setFirstFooter($pValue) {\n    \t$this->_firstFooter = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get DifferentOddEven\n     *\n     * @return boolean\n     */\n    public function getDifferentOddEven() {\n    \treturn $this->_differentOddEven;\n    }\n\n    /**\n     * Set DifferentOddEven\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function setDifferentOddEven($pValue = false) {\n    \t$this->_differentOddEven = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get DifferentFirst\n     *\n     * @return boolean\n     */\n    public function getDifferentFirst() {\n    \treturn $this->_differentFirst;\n    }\n\n    /**\n     * Set DifferentFirst\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function setDifferentFirst($pValue = false) {\n    \t$this->_differentFirst = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get ScaleWithDocument\n     *\n     * @return boolean\n     */\n    public function getScaleWithDocument() {\n    \treturn $this->_scaleWithDocument;\n    }\n\n    /**\n     * Set ScaleWithDocument\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function setScaleWithDocument($pValue = true) {\n    \t$this->_scaleWithDocument = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get AlignWithMargins\n     *\n     * @return boolean\n     */\n    public function getAlignWithMargins() {\n    \treturn $this->_alignWithMargins;\n    }\n\n    /**\n     * Set AlignWithMargins\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function setAlignWithMargins($pValue = true) {\n    \t$this->_alignWithMargins = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Add header/footer image\n     *\n     * @param PHPExcel_Worksheet_HeaderFooterDrawing $image\n     * @param string $location\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function addImage(PHPExcel_Worksheet_HeaderFooterDrawing $image = null, $location = self::IMAGE_HEADER_LEFT) {\n    \t$this->_headerFooterImages[$location] = $image;\n    \treturn $this;\n    }\n\n    /**\n     * Remove header/footer image\n     *\n     * @param string $location\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function removeImage($location = self::IMAGE_HEADER_LEFT) {\n    \tif (isset($this->_headerFooterImages[$location])) {\n    \t\tunset($this->_headerFooterImages[$location]);\n    \t}\n    \treturn $this;\n    }\n\n    /**\n     * Set header/footer images\n     *\n     * @param PHPExcel_Worksheet_HeaderFooterDrawing[] $images\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function setImages($images) {\n    \tif (!is_array($images)) {\n    \t\tthrow new PHPExcel_Exception('Invalid parameter!');\n    \t}\n\n    \t$this->_headerFooterImages = $images;\n    \treturn $this;\n    }\n\n    /**\n     * Get header/footer images\n     *\n     * @return PHPExcel_Worksheet_HeaderFooterDrawing[]\n     */\n    public function getImages() {\n    \t// Sort array\n    \t$images = array();\n    \tif (isset($this->_headerFooterImages[self::IMAGE_HEADER_LEFT])) \t$images[self::IMAGE_HEADER_LEFT] = \t\t$this->_headerFooterImages[self::IMAGE_HEADER_LEFT];\n    \tif (isset($this->_headerFooterImages[self::IMAGE_HEADER_CENTER])) \t$images[self::IMAGE_HEADER_CENTER] = \t$this->_headerFooterImages[self::IMAGE_HEADER_CENTER];\n    \tif (isset($this->_headerFooterImages[self::IMAGE_HEADER_RIGHT])) \t$images[self::IMAGE_HEADER_RIGHT] = \t$this->_headerFooterImages[self::IMAGE_HEADER_RIGHT];\n    \tif (isset($this->_headerFooterImages[self::IMAGE_FOOTER_LEFT])) \t$images[self::IMAGE_FOOTER_LEFT] = \t\t$this->_headerFooterImages[self::IMAGE_FOOTER_LEFT];\n    \tif (isset($this->_headerFooterImages[self::IMAGE_FOOTER_CENTER])) \t$images[self::IMAGE_FOOTER_CENTER] = \t$this->_headerFooterImages[self::IMAGE_FOOTER_CENTER];\n    \tif (isset($this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT])) \t$images[self::IMAGE_FOOTER_RIGHT] = \t$this->_headerFooterImages[self::IMAGE_FOOTER_RIGHT];\n    \t$this->_headerFooterImages = $images;\n\n    \treturn $this->_headerFooterImages;\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/HeaderFooterDrawing.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_HeaderFooterDrawing\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_HeaderFooterDrawing extends PHPExcel_Worksheet_Drawing implements PHPExcel_IComparable\n{\n\t/**\n\t * Path\n\t *\n\t * @var string\n\t */\n\tprivate $_path;\n\n\t/**\n\t * Name\n\t *\n\t * @var string\n\t */\n\tprotected $_name;\n\n\t/**\n\t * Offset X\n\t *\n\t * @var int\n\t */\n\tprotected $_offsetX;\n\n\t/**\n\t * Offset Y\n\t *\n\t * @var int\n\t */\n\tprotected $_offsetY;\n\n\t/**\n\t * Width\n\t *\n\t * @var int\n\t */\n\tprotected $_width;\n\n\t/**\n\t * Height\n\t *\n\t * @var int\n\t */\n\tprotected $_height;\n\n\t/**\n\t * Proportional resize\n\t *\n\t * @var boolean\n\t */\n\tprotected $_resizeProportional;\n\n    /**\n     * Create a new PHPExcel_Worksheet_HeaderFooterDrawing\n     */\n    public function __construct()\n    {\n    \t// Initialise values\n    \t$this->_path\t\t\t\t= '';\n    \t$this->_name\t\t\t\t= '';\n    \t$this->_offsetX\t\t\t\t= 0;\n    \t$this->_offsetY\t\t\t\t= 0;\n    \t$this->_width\t\t\t\t= 0;\n    \t$this->_height\t\t\t\t= 0;\n    \t$this->_resizeProportional\t= true;\n    }\n\n    /**\n     * Get Name\n     *\n     * @return string\n     */\n    public function getName() {\n    \treturn $this->_name;\n    }\n\n    /**\n     * Set Name\n     *\n     * @param string $pValue\n     * @return PHPExcel_Worksheet_HeaderFooterDrawing\n     */\n    public function setName($pValue = '') {\n    \t$this->_name = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get OffsetX\n     *\n     * @return int\n     */\n    public function getOffsetX() {\n    \treturn $this->_offsetX;\n    }\n\n    /**\n     * Set OffsetX\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_HeaderFooterDrawing\n     */\n    public function setOffsetX($pValue = 0) {\n    \t$this->_offsetX = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get OffsetY\n     *\n     * @return int\n     */\n    public function getOffsetY() {\n    \treturn $this->_offsetY;\n    }\n\n    /**\n     * Set OffsetY\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_HeaderFooterDrawing\n     */\n    public function setOffsetY($pValue = 0) {\n    \t$this->_offsetY = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Width\n     *\n     * @return int\n     */\n    public function getWidth() {\n    \treturn $this->_width;\n    }\n\n    /**\n     * Set Width\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_HeaderFooterDrawing\n     */\n    public function setWidth($pValue = 0) {\n    \t// Resize proportional?\n    \tif ($this->_resizeProportional && $pValue != 0) {\n    \t\t$ratio = $this->_width / $this->_height;\n    \t\t$this->_height = round($ratio * $pValue);\n    \t}\n\n    \t// Set width\n    \t$this->_width = $pValue;\n\n    \treturn $this;\n    }\n\n    /**\n     * Get Height\n     *\n     * @return int\n     */\n    public function getHeight() {\n    \treturn $this->_height;\n    }\n\n    /**\n     * Set Height\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_HeaderFooterDrawing\n     */\n    public function setHeight($pValue = 0) {\n    \t// Resize proportional?\n    \tif ($this->_resizeProportional && $pValue != 0) {\n    \t\t$ratio = $this->_width / $this->_height;\n    \t\t$this->_width = round($ratio * $pValue);\n    \t}\n\n    \t// Set height\n    \t$this->_height = $pValue;\n\n    \treturn $this;\n    }\n\n    /**\n     * Set width and height with proportional resize\n\t * Example:\n\t * <code>\n     * $objDrawing->setResizeProportional(true);\n     * $objDrawing->setWidthAndHeight(160,120);\n\t * </code>\n\t *\n     * @author Vincent@luo MSN:kele_100@hotmail.com\n     * @param int $width\n     * @param int $height\n     * @return PHPExcel_Worksheet_HeaderFooterDrawing\n     */\n\tpublic function setWidthAndHeight($width = 0, $height = 0) {\n\t\t$xratio = $width / $this->_width;\n\t\t$yratio = $height / $this->_height;\n\t\tif ($this->_resizeProportional && !($width == 0 || $height == 0)) {\n\t\t\tif (($xratio * $this->_height) < $height) {\n\t\t\t\t$this->_height = ceil($xratio * $this->_height);\n\t\t\t\t$this->_width  = $width;\n\t\t\t} else {\n\t\t\t\t$this->_width\t= ceil($yratio * $this->_width);\n\t\t\t\t$this->_height\t= $height;\n\t\t\t}\n\t\t}\n\t\treturn $this;\n\t}\n\n    /**\n     * Get ResizeProportional\n     *\n     * @return boolean\n     */\n    public function getResizeProportional() {\n    \treturn $this->_resizeProportional;\n    }\n\n    /**\n     * Set ResizeProportional\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_HeaderFooterDrawing\n     */\n    public function setResizeProportional($pValue = true) {\n    \t$this->_resizeProportional = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Filename\n     *\n     * @return string\n     */\n    public function getFilename() {\n    \treturn basename($this->_path);\n    }\n\n    /**\n     * Get Extension\n     *\n     * @return string\n     */\n    public function getExtension() {\n        $parts = explode(\".\", basename($this->_path));\n        return end($parts);\n    }\n\n    /**\n     * Get Path\n     *\n     * @return string\n     */\n    public function getPath() {\n    \treturn $this->_path;\n    }\n\n    /**\n     * Set Path\n     *\n     * @param \tstring \t\t$pValue\t\t\tFile path\n     * @param \tboolean\t\t$pVerifyFile\tVerify file\n     * @throws \tPHPExcel_Exception\n     * @return PHPExcel_Worksheet_HeaderFooterDrawing\n     */\n    public function setPath($pValue = '', $pVerifyFile = true) {\n    \tif ($pVerifyFile) {\n\t    \tif (file_exists($pValue)) {\n\t    \t\t$this->_path = $pValue;\n\n\t    \t\tif ($this->_width == 0 && $this->_height == 0) {\n\t    \t\t\t// Get width/height\n\t    \t\t\tlist($this->_width, $this->_height) = getimagesize($pValue);\n\t    \t\t}\n\t    \t} else {\n\t    \t\tthrow new PHPExcel_Exception(\"File $pValue not found!\");\n\t    \t}\n    \t} else {\n    \t\t$this->_path = $pValue;\n    \t}\n    \treturn $this;\n    }\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n    \treturn md5(\n    \t\t  $this->_path\n    \t\t. $this->_name\n    \t\t. $this->_offsetX\n    \t\t. $this->_offsetY\n    \t\t. $this->_width\n    \t\t. $this->_height\n    \t\t. __CLASS__\n    \t);\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/MemoryDrawing.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_MemoryDrawing\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_MemoryDrawing extends PHPExcel_Worksheet_BaseDrawing implements PHPExcel_IComparable\n{\n\t/* Rendering functions */\n\tconst RENDERING_DEFAULT\t\t\t\t\t= 'imagepng';\n\tconst RENDERING_PNG\t\t\t\t\t\t= 'imagepng';\n\tconst RENDERING_GIF\t\t\t\t\t\t= 'imagegif';\n\tconst RENDERING_JPEG\t\t\t\t\t= 'imagejpeg';\n\n\t/* MIME types */\n\tconst MIMETYPE_DEFAULT\t\t\t\t\t= 'image/png';\n\tconst MIMETYPE_PNG\t\t\t\t\t\t= 'image/png';\n\tconst MIMETYPE_GIF\t\t\t\t\t\t= 'image/gif';\n\tconst MIMETYPE_JPEG\t\t\t\t\t\t= 'image/jpeg';\n\n\t/**\n\t * Image resource\n\t *\n\t * @var resource\n\t */\n\tprivate $_imageResource;\n\n\t/**\n\t * Rendering function\n\t *\n\t * @var string\n\t */\n\tprivate $_renderingFunction;\n\n\t/**\n\t * Mime type\n\t *\n\t * @var string\n\t */\n\tprivate $_mimeType;\n\n\t/**\n\t * Unique name\n\t *\n\t * @var string\n\t */\n\tprivate $_uniqueName;\n\n    /**\n     * Create a new PHPExcel_Worksheet_MemoryDrawing\n     */\n    public function __construct()\n    {\n    \t// Initialise values\n    \t$this->_imageResource\t\t= null;\n    \t$this->_renderingFunction \t= self::RENDERING_DEFAULT;\n    \t$this->_mimeType\t\t\t= self::MIMETYPE_DEFAULT;\n    \t$this->_uniqueName\t\t\t= md5(rand(0, 9999). time() . rand(0, 9999));\n\n    \t// Initialize parent\n    \tparent::__construct();\n    }\n\n    /**\n     * Get image resource\n     *\n     * @return resource\n     */\n    public function getImageResource() {\n    \treturn $this->_imageResource;\n    }\n\n    /**\n     * Set image resource\n     *\n     * @param\t$value resource\n     * @return PHPExcel_Worksheet_MemoryDrawing\n     */\n    public function setImageResource($value = null) {\n    \t$this->_imageResource = $value;\n\n    \tif (!is_null($this->_imageResource)) {\n\t    \t// Get width/height\n\t    \t$this->_width\t= imagesx($this->_imageResource);\n\t    \t$this->_height\t= imagesy($this->_imageResource);\n    \t}\n    \treturn $this;\n    }\n\n    /**\n     * Get rendering function\n     *\n     * @return string\n     */\n    public function getRenderingFunction() {\n    \treturn $this->_renderingFunction;\n    }\n\n    /**\n     * Set rendering function\n     *\n     * @param string $value\n     * @return PHPExcel_Worksheet_MemoryDrawing\n     */\n    public function setRenderingFunction($value = PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT) {\n    \t$this->_renderingFunction = $value;\n    \treturn $this;\n    }\n\n    /**\n     * Get mime type\n     *\n     * @return string\n     */\n    public function getMimeType() {\n    \treturn $this->_mimeType;\n    }\n\n    /**\n     * Set mime type\n     *\n     * @param string $value\n     * @return PHPExcel_Worksheet_MemoryDrawing\n     */\n    public function setMimeType($value = PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT) {\n    \t$this->_mimeType = $value;\n    \treturn $this;\n    }\n\n    /**\n     * Get indexed filename (using image index)\n     *\n     * @return string\n     */\n    public function getIndexedFilename() {\n\t\t$extension \t= strtolower($this->getMimeType());\n\t\t$extension \t= explode('/', $extension);\n\t\t$extension \t= $extension[1];\n\n    \treturn $this->_uniqueName . $this->getImageIndex() . '.' . $extension;\n    }\n\n\t/**\n\t * Get hash code\n\t *\n\t * @return string\tHash code\n\t */\n\tpublic function getHashCode() {\n    \treturn md5(\n    \t\t  $this->_renderingFunction\n    \t\t. $this->_mimeType\n    \t\t. $this->_uniqueName\n    \t\t. parent::getHashCode()\n    \t\t. __CLASS__\n    \t);\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/PageMargins.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_PageMargins\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_PageMargins\n{\n\t/**\n\t * Left\n\t *\n\t * @var double\n\t */\n\tprivate $_left\t\t= 0.7;\n\n\t/**\n\t * Right\n\t *\n\t * @var double\n\t */\n\tprivate $_right\t\t= 0.7;\n\n\t/**\n\t * Top\n\t *\n\t * @var double\n\t */\n\tprivate $_top\t\t= 0.75;\n\n\t/**\n\t * Bottom\n\t *\n\t * @var double\n\t */\n\tprivate $_bottom\t= 0.75;\n\n\t/**\n\t * Header\n\t *\n\t * @var double\n\t */\n\tprivate $_header \t= 0.3;\n\n\t/**\n\t * Footer\n\t *\n\t * @var double\n\t */\n\tprivate $_footer \t= 0.3;\n\n    /**\n     * Create a new PHPExcel_Worksheet_PageMargins\n     */\n    public function __construct()\n    {\n    }\n\n    /**\n     * Get Left\n     *\n     * @return double\n     */\n    public function getLeft() {\n    \treturn $this->_left;\n    }\n\n    /**\n     * Set Left\n     *\n     * @param double $pValue\n     * @return PHPExcel_Worksheet_PageMargins\n     */\n    public function setLeft($pValue) {\n    \t$this->_left = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Right\n     *\n     * @return double\n     */\n    public function getRight() {\n    \treturn $this->_right;\n    }\n\n    /**\n     * Set Right\n     *\n     * @param double $pValue\n     * @return PHPExcel_Worksheet_PageMargins\n     */\n    public function setRight($pValue) {\n    \t$this->_right = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Top\n     *\n     * @return double\n     */\n    public function getTop() {\n    \treturn $this->_top;\n    }\n\n    /**\n     * Set Top\n     *\n     * @param double $pValue\n     * @return PHPExcel_Worksheet_PageMargins\n     */\n    public function setTop($pValue) {\n    \t$this->_top = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Bottom\n     *\n     * @return double\n     */\n    public function getBottom() {\n    \treturn $this->_bottom;\n    }\n\n    /**\n     * Set Bottom\n     *\n     * @param double $pValue\n     * @return PHPExcel_Worksheet_PageMargins\n     */\n    public function setBottom($pValue) {\n    \t$this->_bottom = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Header\n     *\n     * @return double\n     */\n    public function getHeader() {\n    \treturn $this->_header;\n    }\n\n    /**\n     * Set Header\n     *\n     * @param double $pValue\n     * @return PHPExcel_Worksheet_PageMargins\n     */\n    public function setHeader($pValue) {\n    \t$this->_header = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Footer\n     *\n     * @return double\n     */\n    public function getFooter() {\n    \treturn $this->_footer;\n    }\n\n    /**\n     * Set Footer\n     *\n     * @param double $pValue\n     * @return PHPExcel_Worksheet_PageMargins\n     */\n    public function setFooter($pValue) {\n    \t$this->_footer = $pValue;\n    \treturn $this;\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/PageSetup.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_PageSetup\n *\n * <code>\n * Paper size taken from Office Open XML Part 4 - Markup Language Reference, page 1988:\n *\n * 1 = Letter paper (8.5 in. by 11 in.)\n * 2 = Letter small paper (8.5 in. by 11 in.)\n * 3 = Tabloid paper (11 in. by 17 in.)\n * 4 = Ledger paper (17 in. by 11 in.)\n * 5 = Legal paper (8.5 in. by 14 in.)\n * 6 = Statement paper (5.5 in. by 8.5 in.)\n * 7 = Executive paper (7.25 in. by 10.5 in.)\n * 8 = A3 paper (297 mm by 420 mm)\n * 9 = A4 paper (210 mm by 297 mm)\n * 10 = A4 small paper (210 mm by 297 mm)\n * 11 = A5 paper (148 mm by 210 mm)\n * 12 = B4 paper (250 mm by 353 mm)\n * 13 = B5 paper (176 mm by 250 mm)\n * 14 = Folio paper (8.5 in. by 13 in.)\n * 15 = Quarto paper (215 mm by 275 mm)\n * 16 = Standard paper (10 in. by 14 in.)\n * 17 = Standard paper (11 in. by 17 in.)\n * 18 = Note paper (8.5 in. by 11 in.)\n * 19 = #9 envelope (3.875 in. by 8.875 in.)\n * 20 = #10 envelope (4.125 in. by 9.5 in.)\n * 21 = #11 envelope (4.5 in. by 10.375 in.)\n * 22 = #12 envelope (4.75 in. by 11 in.)\n * 23 = #14 envelope (5 in. by 11.5 in.)\n * 24 = C paper (17 in. by 22 in.)\n * 25 = D paper (22 in. by 34 in.)\n * 26 = E paper (34 in. by 44 in.)\n * 27 = DL envelope (110 mm by 220 mm)\n * 28 = C5 envelope (162 mm by 229 mm)\n * 29 = C3 envelope (324 mm by 458 mm)\n * 30 = C4 envelope (229 mm by 324 mm)\n * 31 = C6 envelope (114 mm by 162 mm)\n * 32 = C65 envelope (114 mm by 229 mm)\n * 33 = B4 envelope (250 mm by 353 mm)\n * 34 = B5 envelope (176 mm by 250 mm)\n * 35 = B6 envelope (176 mm by 125 mm)\n * 36 = Italy envelope (110 mm by 230 mm)\n * 37 = Monarch envelope (3.875 in. by 7.5 in.).\n * 38 = 6 3/4 envelope (3.625 in. by 6.5 in.)\n * 39 = US standard fanfold (14.875 in. by 11 in.)\n * 40 = German standard fanfold (8.5 in. by 12 in.)\n * 41 = German legal fanfold (8.5 in. by 13 in.)\n * 42 = ISO B4 (250 mm by 353 mm)\n * 43 = Japanese double postcard (200 mm by 148 mm)\n * 44 = Standard paper (9 in. by 11 in.)\n * 45 = Standard paper (10 in. by 11 in.)\n * 46 = Standard paper (15 in. by 11 in.)\n * 47 = Invite envelope (220 mm by 220 mm)\n * 50 = Letter extra paper (9.275 in. by 12 in.)\n * 51 = Legal extra paper (9.275 in. by 15 in.)\n * 52 = Tabloid extra paper (11.69 in. by 18 in.)\n * 53 = A4 extra paper (236 mm by 322 mm)\n * 54 = Letter transverse paper (8.275 in. by 11 in.)\n * 55 = A4 transverse paper (210 mm by 297 mm)\n * 56 = Letter extra transverse paper (9.275 in. by 12 in.)\n * 57 = SuperA/SuperA/A4 paper (227 mm by 356 mm)\n * 58 = SuperB/SuperB/A3 paper (305 mm by 487 mm)\n * 59 = Letter plus paper (8.5 in. by 12.69 in.)\n * 60 = A4 plus paper (210 mm by 330 mm)\n * 61 = A5 transverse paper (148 mm by 210 mm)\n * 62 = JIS B5 transverse paper (182 mm by 257 mm)\n * 63 = A3 extra paper (322 mm by 445 mm)\n * 64 = A5 extra paper (174 mm by 235 mm)\n * 65 = ISO B5 extra paper (201 mm by 276 mm)\n * 66 = A2 paper (420 mm by 594 mm)\n * 67 = A3 transverse paper (297 mm by 420 mm)\n * 68 = A3 extra transverse paper (322 mm by 445 mm)\n * </code>\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_PageSetup\n{\n\t/* Paper size */\n\tconst PAPERSIZE_LETTER\t\t\t\t\t\t\t= 1;\n\tconst PAPERSIZE_LETTER_SMALL\t\t\t\t\t= 2;\n\tconst PAPERSIZE_TABLOID\t\t\t\t\t\t\t= 3;\n\tconst PAPERSIZE_LEDGER\t\t\t\t\t\t\t= 4;\n\tconst PAPERSIZE_LEGAL\t\t\t\t\t\t\t= 5;\n\tconst PAPERSIZE_STATEMENT\t\t\t\t\t\t= 6;\n\tconst PAPERSIZE_EXECUTIVE\t\t\t\t\t\t= 7;\n\tconst PAPERSIZE_A3\t\t\t\t\t\t\t\t= 8;\n\tconst PAPERSIZE_A4\t\t\t\t\t\t\t\t= 9;\n\tconst PAPERSIZE_A4_SMALL\t\t\t\t\t\t= 10;\n\tconst PAPERSIZE_A5\t\t\t\t\t\t\t\t= 11;\n\tconst PAPERSIZE_B4\t\t\t\t\t\t\t\t= 12;\n\tconst PAPERSIZE_B5\t\t\t\t\t\t\t\t= 13;\n\tconst PAPERSIZE_FOLIO\t\t\t\t\t\t\t= 14;\n\tconst PAPERSIZE_QUARTO\t\t\t\t\t\t\t= 15;\n\tconst PAPERSIZE_STANDARD_1\t\t\t\t\t\t= 16;\n\tconst PAPERSIZE_STANDARD_2\t\t\t\t\t\t= 17;\n\tconst PAPERSIZE_NOTE\t\t\t\t\t\t\t= 18;\n\tconst PAPERSIZE_NO9_ENVELOPE\t\t\t\t\t= 19;\n\tconst PAPERSIZE_NO10_ENVELOPE\t\t\t\t\t= 20;\n\tconst PAPERSIZE_NO11_ENVELOPE\t\t\t\t\t= 21;\n\tconst PAPERSIZE_NO12_ENVELOPE\t\t\t\t\t= 22;\n\tconst PAPERSIZE_NO14_ENVELOPE\t\t\t\t\t= 23;\n\tconst PAPERSIZE_C\t\t\t\t\t\t\t\t= 24;\n\tconst PAPERSIZE_D\t\t\t\t\t\t\t\t= 25;\n\tconst PAPERSIZE_E\t\t\t\t\t\t\t\t= 26;\n\tconst PAPERSIZE_DL_ENVELOPE\t\t\t\t\t\t= 27;\n\tconst PAPERSIZE_C5_ENVELOPE\t\t\t\t\t\t= 28;\n\tconst PAPERSIZE_C3_ENVELOPE\t\t\t\t\t\t= 29;\n\tconst PAPERSIZE_C4_ENVELOPE\t\t\t\t\t\t= 30;\n\tconst PAPERSIZE_C6_ENVELOPE\t\t\t\t\t\t= 31;\n\tconst PAPERSIZE_C65_ENVELOPE\t\t\t\t\t= 32;\n\tconst PAPERSIZE_B4_ENVELOPE\t\t\t\t\t\t= 33;\n\tconst PAPERSIZE_B5_ENVELOPE\t\t\t\t\t\t= 34;\n\tconst PAPERSIZE_B6_ENVELOPE\t\t\t\t\t\t= 35;\n\tconst PAPERSIZE_ITALY_ENVELOPE\t\t\t\t\t= 36;\n\tconst PAPERSIZE_MONARCH_ENVELOPE\t\t\t\t= 37;\n\tconst PAPERSIZE_6_3_4_ENVELOPE\t\t\t\t\t= 38;\n\tconst PAPERSIZE_US_STANDARD_FANFOLD\t\t\t\t= 39;\n\tconst PAPERSIZE_GERMAN_STANDARD_FANFOLD\t\t\t= 40;\n\tconst PAPERSIZE_GERMAN_LEGAL_FANFOLD\t\t\t= 41;\n\tconst PAPERSIZE_ISO_B4\t\t\t\t\t\t\t= 42;\n\tconst PAPERSIZE_JAPANESE_DOUBLE_POSTCARD\t\t= 43;\n\tconst PAPERSIZE_STANDARD_PAPER_1\t\t\t\t= 44;\n\tconst PAPERSIZE_STANDARD_PAPER_2\t\t\t\t= 45;\n\tconst PAPERSIZE_STANDARD_PAPER_3\t\t\t\t= 46;\n\tconst PAPERSIZE_INVITE_ENVELOPE\t\t\t\t\t= 47;\n\tconst PAPERSIZE_LETTER_EXTRA_PAPER\t\t\t\t= 48;\n\tconst PAPERSIZE_LEGAL_EXTRA_PAPER\t\t\t\t= 49;\n\tconst PAPERSIZE_TABLOID_EXTRA_PAPER\t\t\t\t= 50;\n\tconst PAPERSIZE_A4_EXTRA_PAPER\t\t\t\t\t= 51;\n\tconst PAPERSIZE_LETTER_TRANSVERSE_PAPER\t\t\t= 52;\n\tconst PAPERSIZE_A4_TRANSVERSE_PAPER\t\t\t\t= 53;\n\tconst PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER\t= 54;\n\tconst PAPERSIZE_SUPERA_SUPERA_A4_PAPER\t\t\t= 55;\n\tconst PAPERSIZE_SUPERB_SUPERB_A3_PAPER\t\t\t= 56;\n\tconst PAPERSIZE_LETTER_PLUS_PAPER\t\t\t\t= 57;\n\tconst PAPERSIZE_A4_PLUS_PAPER\t\t\t\t\t= 58;\n\tconst PAPERSIZE_A5_TRANSVERSE_PAPER\t\t\t\t= 59;\n\tconst PAPERSIZE_JIS_B5_TRANSVERSE_PAPER\t\t\t= 60;\n\tconst PAPERSIZE_A3_EXTRA_PAPER\t\t\t\t\t= 61;\n\tconst PAPERSIZE_A5_EXTRA_PAPER\t\t\t\t\t= 62;\n\tconst PAPERSIZE_ISO_B5_EXTRA_PAPER\t\t\t\t= 63;\n\tconst PAPERSIZE_A2_PAPER\t\t\t\t\t\t= 64;\n\tconst PAPERSIZE_A3_TRANSVERSE_PAPER\t\t\t\t= 65;\n\tconst PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER\t\t= 66;\n\n\t/* Page orientation */\n\tconst ORIENTATION_DEFAULT\t= 'default';\n\tconst ORIENTATION_LANDSCAPE\t= 'landscape';\n\tconst ORIENTATION_PORTRAIT\t= 'portrait';\n\n\t/* Print Range Set Method */\n\tconst SETPRINTRANGE_OVERWRITE\t= 'O';\n\tconst SETPRINTRANGE_INSERT\t\t= 'I';\n\n\n\t/**\n\t * Paper size\n\t *\n\t * @var int\n\t */\n\tprivate $_paperSize\t\t= PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER;\n\n\t/**\n\t * Orientation\n\t *\n\t * @var string\n\t */\n\tprivate $_orientation\t= PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT;\n\n\t/**\n\t * Scale (Print Scale)\n\t *\n\t * Print scaling. Valid values range from 10 to 400\n\t * This setting is overridden when fitToWidth and/or fitToHeight are in use\n\t *\n\t * @var int?\n\t */\n\tprivate $_scale\t\t\t= 100;\n\n\t/**\n\t  * Fit To Page\n\t  * Whether scale or fitToWith / fitToHeight applies\n\t  *\n\t  * @var boolean\n\t  */\n\tprivate $_fitToPage\t\t= FALSE;\n\n\t/**\n\t  * Fit To Height\n\t  * Number of vertical pages to fit on\n\t  *\n\t  * @var int?\n\t  */\n\tprivate $_fitToHeight\t= 1;\n\n\t/**\n\t  * Fit To Width\n\t  * Number of horizontal pages to fit on\n\t  *\n\t  * @var int?\n\t  */\n\tprivate $_fitToWidth\t= 1;\n\n\t/**\n\t * Columns to repeat at left\n\t *\n\t * @var array Containing start column and end column, empty array if option unset\n\t */\n\tprivate $_columnsToRepeatAtLeft = array('', '');\n\n\t/**\n\t * Rows to repeat at top\n\t *\n\t * @var array Containing start row number and end row number, empty array if option unset\n\t */\n\tprivate $_rowsToRepeatAtTop = array(0, 0);\n\n\t/**\n\t * Center page horizontally\n\t *\n\t * @var boolean\n\t */\n\tprivate $_horizontalCentered = FALSE;\n\n\t/**\n\t * Center page vertically\n\t *\n\t * @var boolean\n\t */\n\tprivate $_verticalCentered = FALSE;\n\n\t/**\n\t * Print area\n\t *\n\t * @var string\n\t */\n\tprivate $_printArea = NULL;\n\n\t/**\n\t * First page number\n\t *\n\t * @var int\n\t */\n\tprivate $_firstPageNumber = NULL;\n\n    /**\n     * Create a new PHPExcel_Worksheet_PageSetup\n     */\n    public function __construct()\n    {\n    }\n\n    /**\n     * Get Paper Size\n     *\n     * @return int\n     */\n    public function getPaperSize() {\n    \treturn $this->_paperSize;\n    }\n\n    /**\n     * Set Paper Size\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_PageSetup\n     */\n    public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER) {\n    \t$this->_paperSize = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Orientation\n     *\n     * @return string\n     */\n    public function getOrientation() {\n    \treturn $this->_orientation;\n    }\n\n    /**\n     * Set Orientation\n     *\n     * @param string $pValue\n     * @return PHPExcel_Worksheet_PageSetup\n     */\n    public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT) {\n    \t$this->_orientation = $pValue;\n    \treturn $this;\n    }\n\n\t/**\n\t * Get Scale\n\t *\n\t * @return int?\n\t */\n\tpublic function getScale() {\n\t\treturn $this->_scale;\n\t}\n\n\t/**\n\t * Set Scale\n\t *\n\t * Print scaling. Valid values range from 10 to 400\n\t * This setting is overridden when fitToWidth and/or fitToHeight are in use\n\t *\n\t * @param \tint?\t$pValue\n\t * @param boolean\t$pUpdate\tUpdate fitToPage so scaling applies rather than fitToHeight / fitToWidth\n\t * @return PHPExcel_Worksheet_PageSetup\n\t * @throws \tPHPExcel_Exception\n\t */\n\tpublic function setScale($pValue = 100, $pUpdate = true) {\n\t\t// Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface,\n\t\t// but it is apparently still able to handle any scale >= 0, where 0 results in 100\n\t\tif (($pValue >= 0) || is_null($pValue)) {\n\t\t\t$this->_scale = $pValue;\n\t\t\tif ($pUpdate) {\n\t\t\t\t$this->_fitToPage = false;\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Scale must not be negative\");\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Fit To Page\n\t *\n\t * @return boolean\n\t */\n\tpublic function getFitToPage() {\n\t\treturn $this->_fitToPage;\n\t}\n\n\t/**\n\t * Set Fit To Page\n\t *\n\t * @param boolean $pValue\n\t * @return PHPExcel_Worksheet_PageSetup\n\t */\n\tpublic function setFitToPage($pValue = TRUE) {\n\t\t$this->_fitToPage = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Fit To Height\n\t *\n\t * @return int?\n\t */\n\tpublic function getFitToHeight() {\n\t\treturn $this->_fitToHeight;\n\t}\n\n\t/**\n\t * Set Fit To Height\n\t *\n\t * @param int? $pValue\n\t * @param boolean $pUpdate Update fitToPage so it applies rather than scaling\n\t * @return PHPExcel_Worksheet_PageSetup\n\t */\n\tpublic function setFitToHeight($pValue = 1, $pUpdate = TRUE) {\n\t\t$this->_fitToHeight = $pValue;\n\t\tif ($pUpdate) {\n\t\t\t$this->_fitToPage = TRUE;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get Fit To Width\n\t *\n\t * @return int?\n\t */\n\tpublic function getFitToWidth() {\n\t\treturn $this->_fitToWidth;\n\t}\n\n\t/**\n\t * Set Fit To Width\n\t *\n\t * @param int? $pValue\n\t * @param boolean $pUpdate Update fitToPage so it applies rather than scaling\n\t * @return PHPExcel_Worksheet_PageSetup\n\t */\n\tpublic function setFitToWidth($pValue = 1, $pUpdate = TRUE) {\n\t\t$this->_fitToWidth = $pValue;\n\t\tif ($pUpdate) {\n\t\t\t$this->_fitToPage = TRUE;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Is Columns to repeat at left set?\n\t *\n\t * @return boolean\n\t */\n\tpublic function isColumnsToRepeatAtLeftSet() {\n\t\tif (is_array($this->_columnsToRepeatAtLeft)) {\n\t\t\tif ($this->_columnsToRepeatAtLeft[0] != '' && $this->_columnsToRepeatAtLeft[1] != '') {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Get Columns to repeat at left\n\t *\n\t * @return array Containing start column and end column, empty array if option unset\n\t */\n\tpublic function getColumnsToRepeatAtLeft() {\n\t\treturn $this->_columnsToRepeatAtLeft;\n\t}\n\n\t/**\n\t * Set Columns to repeat at left\n\t *\n\t * @param array $pValue Containing start column and end column, empty array if option unset\n\t * @return PHPExcel_Worksheet_PageSetup\n\t */\n\tpublic function setColumnsToRepeatAtLeft($pValue = null) {\n\t\tif (is_array($pValue)) {\n\t\t\t$this->_columnsToRepeatAtLeft = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Set Columns to repeat at left by start and end\n\t *\n\t * @param string $pStart\n\t * @param string $pEnd\n\t * @return PHPExcel_Worksheet_PageSetup\n\t */\n\tpublic function setColumnsToRepeatAtLeftByStartAndEnd($pStart = 'A', $pEnd = 'A') {\n\t\t$this->_columnsToRepeatAtLeft = array($pStart, $pEnd);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Is Rows to repeat at top set?\n\t *\n\t * @return boolean\n\t */\n\tpublic function isRowsToRepeatAtTopSet() {\n\t\tif (is_array($this->_rowsToRepeatAtTop)) {\n\t\t\tif ($this->_rowsToRepeatAtTop[0] != 0 && $this->_rowsToRepeatAtTop[1] != 0) {\n\t\t\t\treturn true;\n\t\t\t}\n\t\t}\n\n\t\treturn false;\n\t}\n\n\t/**\n\t * Get Rows to repeat at top\n\t *\n\t * @return array Containing start column and end column, empty array if option unset\n\t */\n\tpublic function getRowsToRepeatAtTop() {\n\t\treturn $this->_rowsToRepeatAtTop;\n\t}\n\n\t/**\n\t * Set Rows to repeat at top\n\t *\n\t * @param array\t$pValue\tContaining start column and end column, empty array if option unset\n\t * @return PHPExcel_Worksheet_PageSetup\n\t */\n\tpublic function setRowsToRepeatAtTop($pValue = null) {\n\t\tif (is_array($pValue)) {\n\t\t\t$this->_rowsToRepeatAtTop = $pValue;\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Set Rows to repeat at top by start and end\n\t *\n\t * @param int $pStart\n\t * @param int $pEnd\n\t * @return PHPExcel_Worksheet_PageSetup\n\t */\n\tpublic function setRowsToRepeatAtTopByStartAndEnd($pStart = 1, $pEnd = 1) {\n\t\t$this->_rowsToRepeatAtTop = array($pStart, $pEnd);\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get center page horizontally\n\t *\n\t * @return bool\n\t */\n\tpublic function getHorizontalCentered() {\n\t\treturn $this->_horizontalCentered;\n\t}\n\n\t/**\n\t * Set center page horizontally\n\t *\n\t * @param bool $value\n\t * @return PHPExcel_Worksheet_PageSetup\n\t */\n\tpublic function setHorizontalCentered($value = false) {\n\t\t$this->_horizontalCentered = $value;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get center page vertically\n\t *\n\t * @return bool\n\t */\n\tpublic function getVerticalCentered() {\n\t\treturn $this->_verticalCentered;\n\t}\n\n\t/**\n\t * Set center page vertically\n\t *\n\t * @param bool $value\n\t * @return PHPExcel_Worksheet_PageSetup\n\t */\n\tpublic function setVerticalCentered($value = false) {\n\t\t$this->_verticalCentered = $value;\n\t\treturn $this;\n\t}\n\n\t/**\n\t *\tGet print area\n\t *\n\t * @param\tint\t\t$index\tIdentifier for a specific print area range if several ranges have been set\n\t *\t\t\t\t\t\t\tDefault behaviour, or a index value of 0, will return all ranges as a comma-separated string\n\t *\t\t\t\t\t\t\tOtherwise, the specific range identified by the value of $index will be returned\n\t *\t\t\t\t\t\t\tPrint areas are numbered from 1\n\t * @throws\tPHPExcel_Exception\n\t * @return\tstring\n\t */\n\tpublic function getPrintArea($index = 0) {\n\t\tif ($index == 0) {\n\t\t\treturn $this->_printArea;\n\t\t}\n\t\t$printAreas = explode(',',$this->_printArea);\n\t\tif (isset($printAreas[$index-1])) {\n\t\t\treturn $printAreas[$index-1];\n\t\t}\n\t\tthrow new PHPExcel_Exception(\"Requested Print Area does not exist\");\n\t}\n\n\t/**\n\t * Is print area set?\n\t *\n\t * @param\tint\t\t$index\tIdentifier for a specific print area range if several ranges have been set\n\t *\t\t\t\t\t\t\tDefault behaviour, or an index value of 0, will identify whether any print range is set\n\t *\t\t\t\t\t\t\tOtherwise, existence of the range identified by the value of $index will be returned\n\t *\t\t\t\t\t\t\tPrint areas are numbered from 1\n\t * @return\tboolean\n\t */\n\tpublic function isPrintAreaSet($index = 0) {\n\t\tif ($index == 0) {\n\t\t\treturn !is_null($this->_printArea);\n\t\t}\n\t\t$printAreas = explode(',',$this->_printArea);\n\t\treturn isset($printAreas[$index-1]);\n\t}\n\n\t/**\n\t * Clear a print area\n\t *\n\t * @param\tint\t\t$index\tIdentifier for a specific print area range if several ranges have been set\n\t *\t\t\t\t\t\t\tDefault behaviour, or an index value of 0, will clear all print ranges that are set\n\t *\t\t\t\t\t\t\tOtherwise, the range identified by the value of $index will be removed from the series\n\t *\t\t\t\t\t\t\tPrint areas are numbered from 1\n\t * @return\tPHPExcel_Worksheet_PageSetup\n\t */\n\tpublic function clearPrintArea($index = 0) {\n\t\tif ($index == 0) {\n\t\t\t$this->_printArea = NULL;\n\t\t} else {\n\t\t\t$printAreas = explode(',',$this->_printArea);\n\t\t\tif (isset($printAreas[$index-1])) {\n\t\t\t\tunset($printAreas[$index-1]);\n\t\t\t\t$this->_printArea = implode(',',$printAreas);\n\t\t\t}\n\t\t}\n\n    \treturn $this;\n\t}\n\n\t/**\n\t * Set print area. e.g. 'A1:D10' or 'A1:D10,G5:M20'\n\t *\n\t * @param\tstring\t$value\n\t * @param\tint\t\t$index\tIdentifier for a specific print area range allowing several ranges to be set\n\t *\t\t\t\t\t\t\tWhen the method is \"O\"verwrite, then a positive integer index will overwrite that indexed\n\t *\t\t\t\t\t\t\t\tentry in the print areas list; a negative index value will identify which entry to\n\t *\t\t\t\t\t\t\t\toverwrite working bacward through the print area to the list, with the last entry as -1.\n\t *\t\t\t\t\t\t\t\tSpecifying an index value of 0, will overwrite <b>all</b> existing print ranges.\n\t *\t\t\t\t\t\t\tWhen the method is \"I\"nsert, then a positive index will insert after that indexed entry in\n\t *\t\t\t\t\t\t\t\tthe print areas list, while a negative index will insert before the indexed entry.\n\t *\t\t\t\t\t\t\t\tSpecifying an index value of 0, will always append the new print range at the end of the\n\t *\t\t\t\t\t\t\t\tlist.\n\t *\t\t\t\t\t\t\tPrint areas are numbered from 1\n\t * @param\tstring\t$method\tDetermines the method used when setting multiple print areas\n\t *\t\t\t\t\t\t\tDefault behaviour, or the \"O\" method, overwrites existing print area\n\t *\t\t\t\t\t\t\tThe \"I\" method, inserts the new print area before any specified index, or at the end of the list\n\t * @return\tPHPExcel_Worksheet_PageSetup\n\t * @throws\tPHPExcel_Exception\n\t */\n\tpublic function setPrintArea($value, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE) {\n\t\tif (strpos($value,'!') !== false) {\n\t\t\tthrow new PHPExcel_Exception('Cell coordinate must not specify a worksheet.');\n\t\t} elseif (strpos($value,':') === false) {\n\t\t\tthrow new PHPExcel_Exception('Cell coordinate must be a range of cells.');\n\t\t} elseif (strpos($value,'$') !== false) {\n\t\t\tthrow new PHPExcel_Exception('Cell coordinate must not be absolute.');\n\t\t}\n\t\t$value = strtoupper($value);\n\n\t\tif ($method == self::SETPRINTRANGE_OVERWRITE) {\n\t\t\tif ($index == 0) {\n\t\t\t\t$this->_printArea = $value;\n\t\t\t} else {\n\t\t\t\t$printAreas = explode(',',$this->_printArea);\n\t\t\t\tif($index < 0) {\n\t\t\t\t\t$index = count($printAreas) - abs($index) + 1;\n\t\t\t\t}\n\t\t\t\tif (($index <= 0) || ($index > count($printAreas))) {\n\t\t    \t\tthrow new PHPExcel_Exception('Invalid index for setting print range.');\n\t\t\t\t}\n\t\t\t\t$printAreas[$index-1] = $value;\n\t\t\t\t$this->_printArea = implode(',',$printAreas);\n\t\t\t}\n\t\t} elseif($method == self::SETPRINTRANGE_INSERT) {\n\t\t\tif ($index == 0) {\n\t\t\t\t$this->_printArea .= ($this->_printArea == '') ? $value : ','.$value;\n\t\t\t} else {\n\t\t\t\t$printAreas = explode(',',$this->_printArea);\n\t\t\t\tif($index < 0) {\n\t\t\t\t\t$index = abs($index) - 1;\n\t\t\t\t}\n\t\t\t\tif ($index > count($printAreas)) {\n\t\t    \t\tthrow new PHPExcel_Exception('Invalid index for setting print range.');\n\t\t\t\t}\n\t\t\t\t$printAreas = array_merge(array_slice($printAreas,0,$index),array($value),array_slice($printAreas,$index));\n\t\t\t\t$this->_printArea = implode(',',$printAreas);\n\t\t\t}\n\t\t} else {\n    \t\tthrow new PHPExcel_Exception('Invalid method for setting print range.');\n\t\t}\n\n    \treturn $this;\n\t}\n\n\t/**\n\t * Add a new print area (e.g. 'A1:D10' or 'A1:D10,G5:M20') to the list of print areas\n\t *\n\t * @param\tstring\t$value\n\t * @param\tint\t\t$index\tIdentifier for a specific print area range allowing several ranges to be set\n\t *\t\t\t\t\t\t\tA positive index will insert after that indexed entry in the print areas list, while a\n\t *\t\t\t\t\t\t\t\tnegative index will insert before the indexed entry.\n\t *\t\t\t\t\t\t\t\tSpecifying an index value of 0, will always append the new print range at the end of the\n\t *\t\t\t\t\t\t\t\tlist.\n\t *\t\t\t\t\t\t\tPrint areas are numbered from 1\n\t * @return\tPHPExcel_Worksheet_PageSetup\n\t * @throws\tPHPExcel_Exception\n\t */\n\tpublic function addPrintArea($value, $index = -1) {\n\t\treturn $this->setPrintArea($value, $index, self::SETPRINTRANGE_INSERT);\n\t}\n\n\t/**\n\t * Set print area\n\t *\n\t * @param\tint\t\t$column1\tColumn 1\n\t * @param\tint\t\t$row1\t\tRow 1\n\t * @param\tint\t\t$column2\tColumn 2\n\t * @param\tint\t\t$row2\t\tRow 2\n\t * @param\tint\t\t$index\t\tIdentifier for a specific print area range allowing several ranges to be set\n\t *\t\t\t\t\t\t\t\tWhen the method is \"O\"verwrite, then a positive integer index will overwrite that indexed\n\t *\t\t\t\t\t\t\t\t\tentry in the print areas list; a negative index value will identify which entry to\n\t *\t\t\t\t\t\t\t\t\toverwrite working bacward through the print area to the list, with the last entry as -1.\n\t *\t\t\t\t\t\t\t\t\tSpecifying an index value of 0, will overwrite <b>all</b> existing print ranges.\n\t *\t\t\t\t\t\t\t\tWhen the method is \"I\"nsert, then a positive index will insert after that indexed entry in\n\t *\t\t\t\t\t\t\t\t\tthe print areas list, while a negative index will insert before the indexed entry.\n\t *\t\t\t\t\t\t\t\t\tSpecifying an index value of 0, will always append the new print range at the end of the\n\t *\t\t\t\t\t\t\t\t\tlist.\n\t *\t\t\t\t\t\t\t\tPrint areas are numbered from 1\n\t * @param\tstring\t$method\t\tDetermines the method used when setting multiple print areas\n\t *\t\t\t\t\t\t\t\tDefault behaviour, or the \"O\" method, overwrites existing print area\n\t *\t\t\t\t\t\t\t\tThe \"I\" method, inserts the new print area before any specified index, or at the end of the list\n\t * @return\tPHPExcel_Worksheet_PageSetup\n\t * @throws\tPHPExcel_Exception\n\t */\n    public function setPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = 0, $method = self::SETPRINTRANGE_OVERWRITE)\n    {\n    \treturn $this->setPrintArea(PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, $index, $method);\n    }\n\n\t/**\n\t * Add a new print area to the list of print areas\n\t *\n\t * @param\tint\t\t$column1\tStart Column for the print area\n\t * @param\tint\t\t$row1\t\tStart Row for the print area\n\t * @param\tint\t\t$column2\tEnd Column for the print area\n\t * @param\tint\t\t$row2\t\tEnd Row for the print area\n\t * @param\tint\t\t$index\t\tIdentifier for a specific print area range allowing several ranges to be set\n\t *\t\t\t\t\t\t\t\tA positive index will insert after that indexed entry in the print areas list, while a\n\t *\t\t\t\t\t\t\t\t\tnegative index will insert before the indexed entry.\n\t *\t\t\t\t\t\t\t\t\tSpecifying an index value of 0, will always append the new print range at the end of the\n\t *\t\t\t\t\t\t\t\t\tlist.\n\t *\t\t\t\t\t\t\t\tPrint areas are numbered from 1\n\t * @return\tPHPExcel_Worksheet_PageSetup\n\t * @throws\tPHPExcel_Exception\n\t */\n    public function addPrintAreaByColumnAndRow($column1, $row1, $column2, $row2, $index = -1)\n    {\n    \treturn $this->setPrintArea(PHPExcel_Cell::stringFromColumnIndex($column1) . $row1 . ':' . PHPExcel_Cell::stringFromColumnIndex($column2) . $row2, $index, self::SETPRINTRANGE_INSERT);\n\t}\n\n\t/**\n\t * Get first page number\n\t *\n\t * @return int\n\t */\n    public function getFirstPageNumber() {\n\t\treturn $this->_firstPageNumber;\n    }\n\n    /**\n     * Set first page number\n     *\n     * @param int $value\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function setFirstPageNumber($value = null) {\n\t\t$this->_firstPageNumber = $value;\n\t\treturn $this;\n    }\n\n    /**\n     * Reset first page number\n     *\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function resetFirstPageNumber() {\n\t\treturn $this->setFirstPageNumber(null);\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Protection.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_Protection\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_Protection\n{\n\t/**\n\t * Sheet\n\t *\n\t * @var boolean\n\t */\n\tprivate $_sheet\t\t\t\t\t= false;\n\n\t/**\n\t * Objects\n\t *\n\t * @var boolean\n\t */\n\tprivate $_objects\t\t\t\t= false;\n\n\t/**\n\t * Scenarios\n\t *\n\t * @var boolean\n\t */\n\tprivate $_scenarios\t\t\t\t= false;\n\n\t/**\n\t * Format cells\n\t *\n\t * @var boolean\n\t */\n\tprivate $_formatCells\t\t\t= false;\n\n\t/**\n\t * Format columns\n\t *\n\t * @var boolean\n\t */\n\tprivate $_formatColumns\t\t\t= false;\n\n\t/**\n\t * Format rows\n\t *\n\t * @var boolean\n\t */\n\tprivate $_formatRows\t\t\t= false;\n\n\t/**\n\t * Insert columns\n\t *\n\t * @var boolean\n\t */\n\tprivate $_insertColumns\t\t\t= false;\n\n\t/**\n\t * Insert rows\n\t *\n\t * @var boolean\n\t */\n\tprivate $_insertRows\t\t\t= false;\n\n\t/**\n\t * Insert hyperlinks\n\t *\n\t * @var boolean\n\t */\n\tprivate $_insertHyperlinks\t\t= false;\n\n\t/**\n\t * Delete columns\n\t *\n\t * @var boolean\n\t */\n\tprivate $_deleteColumns\t\t\t= false;\n\n\t/**\n\t * Delete rows\n\t *\n\t * @var boolean\n\t */\n\tprivate $_deleteRows\t\t\t= false;\n\n\t/**\n\t * Select locked cells\n\t *\n\t * @var boolean\n\t */\n\tprivate $_selectLockedCells\t\t= false;\n\n\t/**\n\t * Sort\n\t *\n\t * @var boolean\n\t */\n\tprivate $_sort\t\t\t\t\t= false;\n\n\t/**\n\t * AutoFilter\n\t *\n\t * @var boolean\n\t */\n\tprivate $_autoFilter\t\t\t= false;\n\n\t/**\n\t * Pivot tables\n\t *\n\t * @var boolean\n\t */\n\tprivate $_pivotTables\t\t\t= false;\n\n\t/**\n\t * Select unlocked cells\n\t *\n\t * @var boolean\n\t */\n\tprivate $_selectUnlockedCells\t= false;\n\n\t/**\n\t * Password\n\t *\n\t * @var string\n\t */\n\tprivate $_password\t\t\t\t= '';\n\n    /**\n     * Create a new PHPExcel_Worksheet_Protection\n     */\n    public function __construct()\n    {\n    }\n\n    /**\n     * Is some sort of protection enabled?\n     *\n     * @return boolean\n     */\n    function isProtectionEnabled() {\n    \treturn \t$this->_sheet ||\n\t\t\t\t$this->_objects ||\n\t\t\t\t$this->_scenarios ||\n\t\t\t\t$this->_formatCells ||\n\t\t\t\t$this->_formatColumns ||\n\t\t\t\t$this->_formatRows ||\n\t\t\t\t$this->_insertColumns ||\n\t\t\t\t$this->_insertRows ||\n\t\t\t\t$this->_insertHyperlinks ||\n\t\t\t\t$this->_deleteColumns ||\n\t\t\t\t$this->_deleteRows ||\n\t\t\t\t$this->_selectLockedCells ||\n\t\t\t\t$this->_sort ||\n\t\t\t\t$this->_autoFilter ||\n\t\t\t\t$this->_pivotTables ||\n\t\t\t\t$this->_selectUnlockedCells;\n    }\n\n    /**\n     * Get Sheet\n     *\n     * @return boolean\n     */\n    function getSheet() {\n    \treturn $this->_sheet;\n    }\n\n    /**\n     * Set Sheet\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setSheet($pValue = false) {\n    \t$this->_sheet = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Objects\n     *\n     * @return boolean\n     */\n    function getObjects() {\n    \treturn $this->_objects;\n    }\n\n    /**\n     * Set Objects\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setObjects($pValue = false) {\n    \t$this->_objects = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Scenarios\n     *\n     * @return boolean\n     */\n    function getScenarios() {\n    \treturn $this->_scenarios;\n    }\n\n    /**\n     * Set Scenarios\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setScenarios($pValue = false) {\n    \t$this->_scenarios = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get FormatCells\n     *\n     * @return boolean\n     */\n    function getFormatCells() {\n    \treturn $this->_formatCells;\n    }\n\n    /**\n     * Set FormatCells\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setFormatCells($pValue = false) {\n    \t$this->_formatCells = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get FormatColumns\n     *\n     * @return boolean\n     */\n    function getFormatColumns() {\n    \treturn $this->_formatColumns;\n    }\n\n    /**\n     * Set FormatColumns\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setFormatColumns($pValue = false) {\n    \t$this->_formatColumns = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get FormatRows\n     *\n     * @return boolean\n     */\n    function getFormatRows() {\n    \treturn $this->_formatRows;\n    }\n\n    /**\n     * Set FormatRows\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setFormatRows($pValue = false) {\n    \t$this->_formatRows = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get InsertColumns\n     *\n     * @return boolean\n     */\n    function getInsertColumns() {\n    \treturn $this->_insertColumns;\n    }\n\n    /**\n     * Set InsertColumns\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setInsertColumns($pValue = false) {\n    \t$this->_insertColumns = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get InsertRows\n     *\n     * @return boolean\n     */\n    function getInsertRows() {\n    \treturn $this->_insertRows;\n    }\n\n    /**\n     * Set InsertRows\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setInsertRows($pValue = false) {\n    \t$this->_insertRows = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get InsertHyperlinks\n     *\n     * @return boolean\n     */\n    function getInsertHyperlinks() {\n    \treturn $this->_insertHyperlinks;\n    }\n\n    /**\n     * Set InsertHyperlinks\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setInsertHyperlinks($pValue = false) {\n    \t$this->_insertHyperlinks = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get DeleteColumns\n     *\n     * @return boolean\n     */\n    function getDeleteColumns() {\n    \treturn $this->_deleteColumns;\n    }\n\n    /**\n     * Set DeleteColumns\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setDeleteColumns($pValue = false) {\n    \t$this->_deleteColumns = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get DeleteRows\n     *\n     * @return boolean\n     */\n    function getDeleteRows() {\n    \treturn $this->_deleteRows;\n    }\n\n    /**\n     * Set DeleteRows\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setDeleteRows($pValue = false) {\n    \t$this->_deleteRows = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get SelectLockedCells\n     *\n     * @return boolean\n     */\n    function getSelectLockedCells() {\n    \treturn $this->_selectLockedCells;\n    }\n\n    /**\n     * Set SelectLockedCells\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setSelectLockedCells($pValue = false) {\n    \t$this->_selectLockedCells = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Sort\n     *\n     * @return boolean\n     */\n    function getSort() {\n    \treturn $this->_sort;\n    }\n\n    /**\n     * Set Sort\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setSort($pValue = false) {\n    \t$this->_sort = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get AutoFilter\n     *\n     * @return boolean\n     */\n    function getAutoFilter() {\n    \treturn $this->_autoFilter;\n    }\n\n    /**\n     * Set AutoFilter\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setAutoFilter($pValue = false) {\n    \t$this->_autoFilter = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get PivotTables\n     *\n     * @return boolean\n     */\n    function getPivotTables() {\n    \treturn $this->_pivotTables;\n    }\n\n    /**\n     * Set PivotTables\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setPivotTables($pValue = false) {\n    \t$this->_pivotTables = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get SelectUnlockedCells\n     *\n     * @return boolean\n     */\n    function getSelectUnlockedCells() {\n    \treturn $this->_selectUnlockedCells;\n    }\n\n    /**\n     * Set SelectUnlockedCells\n     *\n     * @param boolean $pValue\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setSelectUnlockedCells($pValue = false) {\n    \t$this->_selectUnlockedCells = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Password (hashed)\n     *\n     * @return string\n     */\n    function getPassword() {\n    \treturn $this->_password;\n    }\n\n    /**\n     * Set Password\n     *\n     * @param string \t$pValue\n     * @param boolean \t$pAlreadyHashed If the password has already been hashed, set this to true\n     * @return PHPExcel_Worksheet_Protection\n     */\n    function setPassword($pValue = '', $pAlreadyHashed = false) {\n    \tif (!$pAlreadyHashed) {\n    \t\t$pValue = PHPExcel_Shared_PasswordHasher::hashPassword($pValue);\n    \t}\n\t\t$this->_password = $pValue;\n\t\treturn $this;\n    }\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/Row.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_Row\n *\n * Represents a row in PHPExcel_Worksheet, used by PHPExcel_Worksheet_RowIterator\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_Row\n{\n\t/**\n\t * PHPExcel_Worksheet\n\t *\n\t * @var PHPExcel_Worksheet\n\t */\n\tprivate $_parent;\n\n\t/**\n\t * Row index\n\t *\n\t * @var int\n\t */\n\tprivate $_rowIndex = 0;\n\n\t/**\n\t * Create a new row\n\t *\n\t * @param PHPExcel_Worksheet \t\t$parent\n\t * @param int\t\t\t\t\t\t$rowIndex\n\t */\n\tpublic function __construct(PHPExcel_Worksheet $parent = null, $rowIndex = 1) {\n\t\t// Set parent and row index\n\t\t$this->_parent \t\t= $parent;\n\t\t$this->_rowIndex \t= $rowIndex;\n\t}\n\n\t/**\n\t * Destructor\n\t */\n\tpublic function __destruct() {\n\t\tunset($this->_parent);\n\t}\n\n\t/**\n\t * Get row index\n\t *\n\t * @return int\n\t */\n\tpublic function getRowIndex() {\n\t\treturn $this->_rowIndex;\n\t}\n\n\t/**\n\t * Get cell iterator\n\t *\n\t * @param\tstring\t\t\t\t$startColumn\tThe column address at which to start iterating\n\t * @param\tstring\t\t\t\t$endColumn\t    Optionally, the column address at which to stop iterating\n\t * @return PHPExcel_Worksheet_CellIterator\n\t */\n\tpublic function getCellIterator($startColumn = 'A', $endColumn = null) {\n\t\treturn new PHPExcel_Worksheet_RowCellIterator($this->_parent, $this->_rowIndex, $startColumn, $endColumn);\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/RowCellIterator.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_RowCellIterator\n *\n * Used to iterate columns in a PHPExcel_Worksheet\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_RowCellIterator extends PHPExcel_Worksheet_CellIterator implements Iterator\n{\n\t/**\n\t * Row index\n\t *\n\t * @var int\n\t */\n\tprotected $_rowIndex;\n\n\t/**\n\t * Start position\n\t *\n\t * @var int\n\t */\n\tprotected $_startColumn = 0;\n\n\t/**\n\t * End position\n\t *\n\t * @var int\n\t */\n\tprotected $_endColumn = 0;\n\n\t/**\n\t * Create a new column iterator\n\t *\n\t * @param\tPHPExcel_Worksheet\t$subject\t    The worksheet to iterate over\n     * @param   integer             $rowIndex       The row that we want to iterate\n\t * @param\tstring\t\t\t\t$startColumn\tThe column address at which to start iterating\n\t * @param\tstring\t\t\t\t$endColumn\t    Optionally, the column address at which to stop iterating\n\t */\n\tpublic function __construct(PHPExcel_Worksheet $subject = null, $rowIndex = 1, $startColumn = 'A', $endColumn = null) {\n\t\t// Set subject and row index\n\t\t$this->_subject = $subject;\n\t\t$this->_rowIndex = $rowIndex;\n\t\t$this->resetEnd($endColumn);\n\t\t$this->resetStart($startColumn);\n\t}\n\n\t/**\n\t * Destructor\n\t */\n\tpublic function __destruct() {\n\t\tunset($this->_subject);\n\t}\n\n\t/**\n\t * (Re)Set the start column and the current column pointer\n\t *\n\t * @param integer\t$startColumn\tThe column address at which to start iterating\n     * @return PHPExcel_Worksheet_RowCellIterator\n     * @throws PHPExcel_Exception\n\t */\n\tpublic function resetStart($startColumn = 'A') {\n        $startColumnIndex = PHPExcel_Cell::columnIndexFromString($startColumn) - 1;\n\t\t$this->_startColumn = $startColumnIndex;\n        $this->adjustForExistingOnlyRange();\n\t\t$this->seek(PHPExcel_Cell::stringFromColumnIndex($this->_startColumn));\n\n        return $this;\n\t}\n\n\t/**\n\t * (Re)Set the end column\n\t *\n\t * @param string\t$endColumn\tThe column address at which to stop iterating\n     * @return PHPExcel_Worksheet_RowCellIterator\n     * @throws PHPExcel_Exception\n\t */\n\tpublic function resetEnd($endColumn = null) {\n\t\t$endColumn = ($endColumn) ? $endColumn : $this->_subject->getHighestColumn();\n\t\t$this->_endColumn = PHPExcel_Cell::columnIndexFromString($endColumn) - 1;\n        $this->adjustForExistingOnlyRange();\n\n        return $this;\n\t}\n\n\t/**\n\t * Set the column pointer to the selected column\n\t *\n\t * @param string\t$column\tThe column address to set the current pointer at\n     * @return PHPExcel_Worksheet_RowCellIterator\n     * @throws PHPExcel_Exception\n\t */\n\tpublic function seek($column = 'A') {\n        $column = PHPExcel_Cell::columnIndexFromString($column) - 1;\n        if (($column < $this->_startColumn) || ($column > $this->_endColumn)) {\n            throw new PHPExcel_Exception(\"Column $column is out of range ({$this->_startColumn} - {$this->_endColumn})\");\n        } elseif ($this->_onlyExistingCells && !($this->_subject->cellExistsByColumnAndRow($column, $this->_rowIndex))) {\n            throw new PHPExcel_Exception('In \"IterateOnlyExistingCells\" mode and Cell does not exist');\n        }\n\t\t$this->_position = $column;\n\n        return $this;\n    }\n\n\t/**\n\t * Rewind the iterator to the starting column\n\t */\n\tpublic function rewind() {\n\t\t$this->_position = $this->_startColumn;\n\t}\n\n\t/**\n\t * Return the current cell in this worksheet row\n\t *\n\t * @return PHPExcel_Cell\n\t */\n\tpublic function current() {\n\t\treturn $this->_subject->getCellByColumnAndRow($this->_position, $this->_rowIndex);\n\t}\n\n\t/**\n\t * Return the current iterator key\n\t *\n\t * @return string\n\t */\n\tpublic function key() {\n\t\treturn PHPExcel_Cell::stringFromColumnIndex($this->_position);\n\t}\n\n\t/**\n\t * Set the iterator to its next value\n\t */\n\tpublic function next() {\n        do {\n            ++$this->_position;\n        } while (($this->_onlyExistingCells) &&\n            (!$this->_subject->cellExistsByColumnAndRow($this->_position, $this->_rowIndex)) &&\n            ($this->_position <= $this->_endColumn));\n\t}\n\n\t/**\n\t * Set the iterator to its previous value\n     *\n     * @throws PHPExcel_Exception\n\t */\n\tpublic function prev() {\n        if ($this->_position <= $this->_startColumn) {\n            throw new PHPExcel_Exception(\n                \"Column is already at the beginning of range (\" . \n                PHPExcel_Cell::stringFromColumnIndex($this->_endColumn) . \" - \" . \n                PHPExcel_Cell::stringFromColumnIndex($this->_endColumn) . \")\"\n            );\n        }\n\n        do {\n            --$this->_position;\n        } while (($this->_onlyExistingCells) &&\n            (!$this->_subject->cellExistsByColumnAndRow($this->_position, $this->_rowIndex)) &&\n            ($this->_position >= $this->_startColumn));\n\t}\n\n\t/**\n\t * Indicate if more columns exist in the worksheet range of columns that we're iterating\n\t *\n\t * @return boolean\n\t */\n\tpublic function valid() {\n\t\treturn $this->_position <= $this->_endColumn;\n\t}\n\n\t/**\n\t * Validate start/end values for \"IterateOnlyExistingCells\" mode, and adjust if necessary\n\t *\n     * @throws PHPExcel_Exception\n\t */\n    protected function adjustForExistingOnlyRange() {\n        if ($this->_onlyExistingCells) {\n            while ((!$this->_subject->cellExistsByColumnAndRow($this->_startColumn, $this->_rowIndex)) &&\n                ($this->_startColumn <= $this->_endColumn)) {\n                ++$this->_startColumn;\n            }\n            if ($this->_startColumn > $this->_endColumn) {\n                throw new PHPExcel_Exception('No cells exist within the specified range');\n            }\n            while ((!$this->_subject->cellExistsByColumnAndRow($this->_endColumn, $this->_rowIndex)) &&\n                ($this->_endColumn >= $this->_startColumn)) {\n                --$this->_endColumn;\n            }\n            if ($this->_endColumn < $this->_startColumn) {\n                throw new PHPExcel_Exception('No cells exist within the specified range');\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/RowDimension.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_RowDimension\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_RowDimension\n{\n\t/**\n\t * Row index\n\t *\n\t * @var int\n\t */\n\tprivate $_rowIndex;\n\n\t/**\n\t * Row height (in pt)\n\t *\n\t * When this is set to a negative value, the row height should be ignored by IWriter\n\t *\n\t * @var double\n\t */\n\tprivate $_rowHeight\t\t= -1;\n\n \t/**\n\t * ZeroHeight for Row?\n\t *\n\t * @var bool\n\t */\n\tprivate $_zeroHeight\t= false;\n\n\t/**\n\t * Visible?\n\t *\n\t * @var bool\n\t */\n\tprivate $_visible\t\t= true;\n\n\t/**\n\t * Outline level\n\t *\n\t * @var int\n\t */\n\tprivate $_outlineLevel\t= 0;\n\n\t/**\n\t * Collapsed\n\t *\n\t * @var bool\n\t */\n\tprivate $_collapsed\t\t= false;\n\n\t/**\n\t * Index to cellXf. Null value means row has no explicit cellXf format.\n\t *\n\t * @var int|null\n\t */\n\tprivate $_xfIndex;\n\n    /**\n     * Create a new PHPExcel_Worksheet_RowDimension\n     *\n     * @param int $pIndex Numeric row index\n     */\n    public function __construct($pIndex = 0)\n    {\n    \t// Initialise values\n    \t$this->_rowIndex\t\t= $pIndex;\n\n\t\t// set row dimension as unformatted by default\n\t\t$this->_xfIndex = null;\n    }\n\n    /**\n     * Get Row Index\n     *\n     * @return int\n     */\n    public function getRowIndex() {\n    \treturn $this->_rowIndex;\n    }\n\n    /**\n     * Set Row Index\n     *\n     * @param int $pValue\n     * @return PHPExcel_Worksheet_RowDimension\n     */\n    public function setRowIndex($pValue) {\n    \t$this->_rowIndex = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Row Height\n     *\n     * @return double\n     */\n    public function getRowHeight() {\n    \treturn $this->_rowHeight;\n    }\n\n    /**\n     * Set Row Height\n     *\n     * @param double $pValue\n     * @return PHPExcel_Worksheet_RowDimension\n     */\n    public function setRowHeight($pValue = -1) {\n    \t$this->_rowHeight = $pValue;\n    \treturn $this;\n    }\n\n\t/**\n\t * Get ZeroHeight\n\t *\n\t * @return bool\n\t */\n\tpublic function getZeroHeight() {\n\t\treturn $this->_zeroHeight;\n\t}\n\n\t/**\n\t * Set ZeroHeight\n\t *\n\t * @param bool $pValue\n\t * @return PHPExcel_Worksheet_RowDimension\n\t */\n\tpublic function setZeroHeight($pValue = false) {\n\t\t$this->_zeroHeight = $pValue;\n\t\treturn $this;\n\t}\n\n    /**\n     * Get Visible\n     *\n     * @return bool\n     */\n    public function getVisible() {\n    \treturn $this->_visible;\n    }\n\n    /**\n     * Set Visible\n     *\n     * @param bool $pValue\n     * @return PHPExcel_Worksheet_RowDimension\n     */\n    public function setVisible($pValue = true) {\n    \t$this->_visible = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Outline Level\n     *\n     * @return int\n     */\n    public function getOutlineLevel() {\n    \treturn $this->_outlineLevel;\n    }\n\n    /**\n     * Set Outline Level\n     *\n     * Value must be between 0 and 7\n     *\n     * @param int $pValue\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet_RowDimension\n     */\n    public function setOutlineLevel($pValue) {\n    \tif ($pValue < 0 || $pValue > 7) {\n    \t\tthrow new PHPExcel_Exception(\"Outline level must range between 0 and 7.\");\n    \t}\n\n    \t$this->_outlineLevel = $pValue;\n    \treturn $this;\n    }\n\n    /**\n     * Get Collapsed\n     *\n     * @return bool\n     */\n    public function getCollapsed() {\n    \treturn $this->_collapsed;\n    }\n\n    /**\n     * Set Collapsed\n     *\n     * @param bool $pValue\n     * @return PHPExcel_Worksheet_RowDimension\n     */\n    public function setCollapsed($pValue = true) {\n    \t$this->_collapsed = $pValue;\n    \treturn $this;\n    }\n\n\t/**\n\t * Get index to cellXf\n\t *\n\t * @return int\n\t */\n\tpublic function getXfIndex()\n\t{\n\t\treturn $this->_xfIndex;\n\t}\n\n\t/**\n\t * Set index to cellXf\n\t *\n\t * @param int $pValue\n\t * @return PHPExcel_Worksheet_RowDimension\n\t */\n\tpublic function setXfIndex($pValue = 0)\n\t{\n\t\t$this->_xfIndex = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/RowIterator.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_RowIterator\n *\n * Used to iterate rows in a PHPExcel_Worksheet\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_RowIterator implements Iterator\n{\n\t/**\n\t * PHPExcel_Worksheet to iterate\n\t *\n\t * @var PHPExcel_Worksheet\n\t */\n\tprivate $_subject;\n\n\t/**\n\t * Current iterator position\n\t *\n\t * @var int\n\t */\n\tprivate $_position = 1;\n\n\t/**\n\t * Start position\n\t *\n\t * @var int\n\t */\n\tprivate $_startRow = 1;\n\n\n\t/**\n\t * End position\n\t *\n\t * @var int\n\t */\n\tprivate $_endRow = 1;\n\n\n\t/**\n\t * Create a new row iterator\n\t *\n\t * @param\tPHPExcel_Worksheet\t$subject\tThe worksheet to iterate over\n\t * @param\tinteger\t\t\t\t$startRow\tThe row number at which to start iterating\n\t * @param\tinteger\t\t\t\t$endRow\t    Optionally, the row number at which to stop iterating\n\t */\n\tpublic function __construct(PHPExcel_Worksheet $subject = null, $startRow = 1, $endRow = null) {\n\t\t// Set subject\n\t\t$this->_subject = $subject;\n\t\t$this->resetEnd($endRow);\n\t\t$this->resetStart($startRow);\n\t}\n\n\t/**\n\t * Destructor\n\t */\n\tpublic function __destruct() {\n\t\tunset($this->_subject);\n\t}\n\n\t/**\n\t * (Re)Set the start row and the current row pointer\n\t *\n\t * @param integer\t$startRow\tThe row number at which to start iterating\n     * @return PHPExcel_Worksheet_RowIterator\n\t */\n\tpublic function resetStart($startRow = 1) {\n\t\t$this->_startRow = $startRow;\n\t\t$this->seek($startRow);\n\n        return $this;\n\t}\n\n\t/**\n\t * (Re)Set the end row\n\t *\n\t * @param integer\t$endRow\tThe row number at which to stop iterating\n     * @return PHPExcel_Worksheet_RowIterator\n\t */\n\tpublic function resetEnd($endRow = null) {\n\t\t$this->_endRow = ($endRow) ? $endRow : $this->_subject->getHighestRow();\n\n        return $this;\n\t}\n\n\t/**\n\t * Set the row pointer to the selected row\n\t *\n\t * @param integer\t$row\tThe row number to set the current pointer at\n     * @return PHPExcel_Worksheet_RowIterator\n     * @throws PHPExcel_Exception\n\t */\n\tpublic function seek($row = 1) {\n        if (($row < $this->_startRow) || ($row > $this->_endRow)) {\n            throw new PHPExcel_Exception(\"Row $row is out of range ({$this->_startRow} - {$this->_endRow})\");\n        }\n\t\t$this->_position = $row;\n\n        return $this;\n\t}\n\n\t/**\n\t * Rewind the iterator to the starting row\n\t */\n\tpublic function rewind() {\n\t\t$this->_position = $this->_startRow;\n\t}\n\n\t/**\n\t * Return the current row in this worksheet\n\t *\n\t * @return PHPExcel_Worksheet_Row\n\t */\n\tpublic function current() {\n\t\treturn new PHPExcel_Worksheet_Row($this->_subject, $this->_position);\n\t}\n\n\t/**\n\t * Return the current iterator key\n\t *\n\t * @return int\n\t */\n\tpublic function key() {\n\t\treturn $this->_position;\n\t}\n\n\t/**\n\t * Set the iterator to its next value\n\t */\n\tpublic function next() {\n\t\t++$this->_position;\n\t}\n\n\t/**\n\t * Set the iterator to its previous value\n\t */\n\tpublic function prev() {\n        if ($this->_position <= $this->_startRow) {\n            throw new PHPExcel_Exception(\"Row is already at the beginning of range ({$this->_startRow} - {$this->_endRow})\");\n        }\n\n        --$this->_position;\n\t}\n\n\t/**\n\t * Indicate if more rows exist in the worksheet range of rows that we're iterating\n\t *\n\t * @return boolean\n\t */\n\tpublic function valid() {\n\t\treturn $this->_position <= $this->_endRow;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet/SheetView.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet_SheetView\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet_SheetView\n{\n\n\t/* Sheet View types */\n\tconst SHEETVIEW_NORMAL\t\t\t\t= 'normal';\n\tconst SHEETVIEW_PAGE_LAYOUT\t\t\t= 'pageLayout';\n\tconst SHEETVIEW_PAGE_BREAK_PREVIEW\t= 'pageBreakPreview';\n\n\tprivate static $_sheetViewTypes = array(\n\t\tself::SHEETVIEW_NORMAL,\n\t\tself::SHEETVIEW_PAGE_LAYOUT,\n\t\tself::SHEETVIEW_PAGE_BREAK_PREVIEW,\n\t);\n\n\t/**\n\t * ZoomScale\n\t *\n\t * Valid values range from 10 to 400.\n\t *\n\t * @var int\n\t */\n\tprivate $_zoomScale\t\t\t= 100;\n\n\t/**\n\t * ZoomScaleNormal\n\t *\n\t * Valid values range from 10 to 400.\n\t *\n\t * @var int\n\t */\n\tprivate $_zoomScaleNormal\t= 100;\n\n\t/**\n\t * View\n\t *\n\t * Valid values range from 10 to 400.\n\t *\n\t * @var string\n\t */\n\tprivate $_sheetviewType\t\t= self::SHEETVIEW_NORMAL;\n\n    /**\n     * Create a new PHPExcel_Worksheet_SheetView\n     */\n    public function __construct()\n    {\n    }\n\n\t/**\n\t * Get ZoomScale\n\t *\n\t * @return int\n\t */\n\tpublic function getZoomScale() {\n\t\treturn $this->_zoomScale;\n\t}\n\n\t/**\n\t * Set ZoomScale\n\t *\n\t * Valid values range from 10 to 400.\n\t *\n\t * @param \tint \t$pValue\n\t * @throws \tPHPExcel_Exception\n\t * @return PHPExcel_Worksheet_SheetView\n\t */\n\tpublic function setZoomScale($pValue = 100) {\n\t\t// Microsoft Office Excel 2007 only allows setting a scale between 10 and 400 via the user interface,\n\t\t// but it is apparently still able to handle any scale >= 1\n\t\tif (($pValue >= 1) || is_null($pValue)) {\n\t\t\t$this->_zoomScale = $pValue;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Scale must be greater than or equal to 1.\");\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get ZoomScaleNormal\n\t *\n\t * @return int\n\t */\n\tpublic function getZoomScaleNormal() {\n\t\treturn $this->_zoomScaleNormal;\n\t}\n\n\t/**\n\t * Set ZoomScale\n\t *\n\t * Valid values range from 10 to 400.\n\t *\n\t * @param \tint \t$pValue\n\t * @throws \tPHPExcel_Exception\n\t * @return PHPExcel_Worksheet_SheetView\n\t */\n\tpublic function setZoomScaleNormal($pValue = 100) {\n\t\tif (($pValue >= 1) || is_null($pValue)) {\n\t\t\t$this->_zoomScaleNormal = $pValue;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Scale must be greater than or equal to 1.\");\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get View\n\t *\n\t * @return string\n\t */\n\tpublic function getView() {\n\t\treturn $this->_sheetviewType;\n\t}\n\n\t/**\n\t * Set View\n\t *\n\t * Valid values are\n\t *\t\t'normal'\t\t\tself::SHEETVIEW_NORMAL\n\t *\t\t'pageLayout'\t\tself::SHEETVIEW_PAGE_LAYOUT\n\t *\t\t'pageBreakPreview'\tself::SHEETVIEW_PAGE_BREAK_PREVIEW\n\t *\n\t * @param \tstring \t$pValue\n\t * @throws \tPHPExcel_Exception\n\t * @return PHPExcel_Worksheet_SheetView\n\t */\n\tpublic function setView($pValue = NULL) {\n\t\t//\tMS Excel 2007 allows setting the view to 'normal', 'pageLayout' or 'pageBreakPreview'\n\t\t//\t\tvia the user interface\n\t\tif ($pValue === NULL)\n\t\t\t$pValue = self::SHEETVIEW_NORMAL;\n\t\tif (in_array($pValue, self::$_sheetViewTypes)) {\n\t\t\t$this->_sheetviewType = $pValue;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Exception(\"Invalid sheetview layout type.\");\n\t\t}\n\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Implement PHP __clone to create a deep clone, not just a shallow copy.\n\t */\n\tpublic function __clone() {\n\t\t$vars = get_object_vars($this);\n\t\tforeach ($vars as $key => $value) {\n\t\t\tif (is_object($value)) {\n\t\t\t\t$this->$key = clone $value;\n\t\t\t} else {\n\t\t\t\t$this->$key = $value;\n\t\t\t}\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Worksheet.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Worksheet\n *\n * @category   PHPExcel\n * @package    PHPExcel_Worksheet\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Worksheet implements PHPExcel_IComparable\n{\n    /* Break types */\n    const BREAK_NONE   = 0;\n    const BREAK_ROW    = 1;\n    const BREAK_COLUMN = 2;\n\n    /* Sheet state */\n    const SHEETSTATE_VISIBLE    = 'visible';\n    const SHEETSTATE_HIDDEN     = 'hidden';\n    const SHEETSTATE_VERYHIDDEN = 'veryHidden';\n\n    /**\n     * Invalid characters in sheet title\n     *\n     * @var array\n     */\n    private static $_invalidCharacters = array('*', ':', '/', '\\\\', '?', '[', ']');\n\n    /**\n     * Parent spreadsheet\n     *\n     * @var PHPExcel\n     */\n    private $_parent;\n\n    /**\n     * Cacheable collection of cells\n     *\n     * @var PHPExcel_CachedObjectStorage_xxx\n     */\n    private $_cellCollection = null;\n\n    /**\n     * Collection of row dimensions\n     *\n     * @var PHPExcel_Worksheet_RowDimension[]\n     */\n    private $_rowDimensions = array();\n\n    /**\n     * Default row dimension\n     *\n     * @var PHPExcel_Worksheet_RowDimension\n     */\n    private $_defaultRowDimension = null;\n\n    /**\n     * Collection of column dimensions\n     *\n     * @var PHPExcel_Worksheet_ColumnDimension[]\n     */\n    private $_columnDimensions = array();\n\n    /**\n     * Default column dimension\n     *\n     * @var PHPExcel_Worksheet_ColumnDimension\n     */\n    private $_defaultColumnDimension = null;\n\n    /**\n     * Collection of drawings\n     *\n     * @var PHPExcel_Worksheet_BaseDrawing[]\n     */\n    private $_drawingCollection = null;\n\n    /**\n     * Collection of Chart objects\n     *\n     * @var PHPExcel_Chart[]\n     */\n    private $_chartCollection = array();\n\n    /**\n     * Worksheet title\n     *\n     * @var string\n     */\n    private $_title;\n\n    /**\n     * Sheet state\n     *\n     * @var string\n     */\n    private $_sheetState;\n\n    /**\n     * Page setup\n     *\n     * @var PHPExcel_Worksheet_PageSetup\n     */\n    private $_pageSetup;\n\n    /**\n     * Page margins\n     *\n     * @var PHPExcel_Worksheet_PageMargins\n     */\n    private $_pageMargins;\n\n    /**\n     * Page header/footer\n     *\n     * @var PHPExcel_Worksheet_HeaderFooter\n     */\n    private $_headerFooter;\n\n    /**\n     * Sheet view\n     *\n     * @var PHPExcel_Worksheet_SheetView\n     */\n    private $_sheetView;\n\n    /**\n     * Protection\n     *\n     * @var PHPExcel_Worksheet_Protection\n     */\n    private $_protection;\n\n    /**\n     * Collection of styles\n     *\n     * @var PHPExcel_Style[]\n     */\n    private $_styles = array();\n\n    /**\n     * Conditional styles. Indexed by cell coordinate, e.g. 'A1'\n     *\n     * @var array\n     */\n    private $_conditionalStylesCollection = array();\n\n    /**\n     * Is the current cell collection sorted already?\n     *\n     * @var boolean\n     */\n    private $_cellCollectionIsSorted = false;\n\n    /**\n     * Collection of breaks\n     *\n     * @var array\n     */\n    private $_breaks = array();\n\n    /**\n     * Collection of merged cell ranges\n     *\n     * @var array\n     */\n    private $_mergeCells = array();\n\n    /**\n     * Collection of protected cell ranges\n     *\n     * @var array\n     */\n    private $_protectedCells = array();\n\n    /**\n     * Autofilter Range and selection\n     *\n     * @var PHPExcel_Worksheet_AutoFilter\n     */\n    private $_autoFilter = NULL;\n\n    /**\n     * Freeze pane\n     *\n     * @var string\n     */\n    private $_freezePane = '';\n\n    /**\n     * Show gridlines?\n     *\n     * @var boolean\n     */\n    private $_showGridlines = true;\n\n    /**\n    * Print gridlines?\n    *\n    * @var boolean\n    */\n    private $_printGridlines = false;\n\n    /**\n    * Show row and column headers?\n    *\n    * @var boolean\n    */\n    private $_showRowColHeaders = true;\n\n    /**\n     * Show summary below? (Row/Column outline)\n     *\n     * @var boolean\n     */\n    private $_showSummaryBelow = true;\n\n    /**\n     * Show summary right? (Row/Column outline)\n     *\n     * @var boolean\n     */\n    private $_showSummaryRight = true;\n\n    /**\n     * Collection of comments\n     *\n     * @var PHPExcel_Comment[]\n     */\n    private $_comments = array();\n\n    /**\n     * Active cell. (Only one!)\n     *\n     * @var string\n     */\n    private $_activeCell = 'A1';\n\n    /**\n     * Selected cells\n     *\n     * @var string\n     */\n    private $_selectedCells = 'A1';\n\n    /**\n     * Cached highest column\n     *\n     * @var string\n     */\n    private $_cachedHighestColumn = 'A';\n\n    /**\n     * Cached highest row\n     *\n     * @var int\n     */\n    private $_cachedHighestRow = 1;\n\n    /**\n     * Right-to-left?\n     *\n     * @var boolean\n     */\n    private $_rightToLeft = false;\n\n    /**\n     * Hyperlinks. Indexed by cell coordinate, e.g. 'A1'\n     *\n     * @var array\n     */\n    private $_hyperlinkCollection = array();\n\n    /**\n     * Data validation objects. Indexed by cell coordinate, e.g. 'A1'\n     *\n     * @var array\n     */\n    private $_dataValidationCollection = array();\n\n    /**\n     * Tab color\n     *\n     * @var PHPExcel_Style_Color\n     */\n    private $_tabColor;\n\n    /**\n     * Dirty flag\n     *\n     * @var boolean\n     */\n    private $_dirty    = true;\n\n    /**\n     * Hash\n     *\n     * @var string\n     */\n    private $_hash    = null;\n\n    /**\n    * CodeName\n    *\n    * @var string\n    */\n    private $_codeName = null;\n\n\t/**\n     * Create a new worksheet\n     *\n     * @param PHPExcel        $pParent\n     * @param string        $pTitle\n     */\n    public function __construct(PHPExcel $pParent = null, $pTitle = 'Worksheet')\n    {\n        // Set parent and title\n        $this->_parent = $pParent;\n        $this->setTitle($pTitle, FALSE);\n        // setTitle can change $pTitle\n\t    $this->setCodeName($this->getTitle());\n        $this->setSheetState(PHPExcel_Worksheet::SHEETSTATE_VISIBLE);\n\n        $this->_cellCollection        = PHPExcel_CachedObjectStorageFactory::getInstance($this);\n\n        // Set page setup\n        $this->_pageSetup            = new PHPExcel_Worksheet_PageSetup();\n\n        // Set page margins\n        $this->_pageMargins         = new PHPExcel_Worksheet_PageMargins();\n\n        // Set page header/footer\n        $this->_headerFooter        = new PHPExcel_Worksheet_HeaderFooter();\n\n        // Set sheet view\n        $this->_sheetView            = new PHPExcel_Worksheet_SheetView();\n\n        // Drawing collection\n        $this->_drawingCollection    = new ArrayObject();\n\n        // Chart collection\n        $this->_chartCollection     = new ArrayObject();\n\n        // Protection\n        $this->_protection            = new PHPExcel_Worksheet_Protection();\n\n        // Default row dimension\n        $this->_defaultRowDimension = new PHPExcel_Worksheet_RowDimension(NULL);\n\n        // Default column dimension\n        $this->_defaultColumnDimension    = new PHPExcel_Worksheet_ColumnDimension(NULL);\n\n        $this->_autoFilter            = new PHPExcel_Worksheet_AutoFilter(NULL, $this);\n    }\n\n\n    /**\n     * Disconnect all cells from this PHPExcel_Worksheet object,\n     *    typically so that the worksheet object can be unset\n     *\n     */\n\tpublic function disconnectCells() {\n    \tif ( $this->_cellCollection !== NULL){\n            $this->_cellCollection->unsetWorksheetCells();\n            $this->_cellCollection = NULL;\n    \t}\n        //    detach ourself from the workbook, so that it can then delete this worksheet successfully\n        $this->_parent = null;\n    }\n\n    /**\n     * Code to execute when this worksheet is unset()\n     *\n     */\n\tfunction __destruct() {\n\t\tPHPExcel_Calculation::getInstance($this->_parent)\n\t\t    ->clearCalculationCacheForWorksheet($this->_title);\n\n\t\t$this->disconnectCells();\n\t}\n\n   /**\n     * Return the cache controller for the cell collection\n     *\n     * @return PHPExcel_CachedObjectStorage_xxx\n     */\n\tpublic function getCellCacheController() {\n        return $this->_cellCollection;\n    }    //    function getCellCacheController()\n\n\n    /**\n     * Get array of invalid characters for sheet title\n     *\n     * @return array\n     */\n    public static function getInvalidCharacters()\n    {\n        return self::$_invalidCharacters;\n    }\n\n    /**\n     * Check sheet code name for valid Excel syntax\n     *\n     * @param string $pValue The string to check\n     * @return string The valid string\n     * @throws Exception\n     */\n    private static function _checkSheetCodeName($pValue)\n    {\n        $CharCount = PHPExcel_Shared_String::CountCharacters($pValue);\n        if ($CharCount == 0) {\n            throw new PHPExcel_Exception('Sheet code name cannot be empty.');\n        }\n        // Some of the printable ASCII characters are invalid:  * : / \\ ? [ ] and  first and last characters cannot be a \"'\"\n        if ((str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) || \n            (PHPExcel_Shared_String::Substring($pValue,-1,1)=='\\'') || \n            (PHPExcel_Shared_String::Substring($pValue,0,1)=='\\'')) {\n            throw new PHPExcel_Exception('Invalid character found in sheet code name');\n        }\n \n        // Maximum 31 characters allowed for sheet title\n        if ($CharCount > 31) {\n            throw new PHPExcel_Exception('Maximum 31 characters allowed in sheet code name.');\n        }\n \n        return $pValue;\n    }\n\n   /**\n     * Check sheet title for valid Excel syntax\n     *\n     * @param string $pValue The string to check\n     * @return string The valid string\n     * @throws PHPExcel_Exception\n     */\n    private static function _checkSheetTitle($pValue)\n    {\n        // Some of the printable ASCII characters are invalid:  * : / \\ ? [ ]\n        if (str_replace(self::$_invalidCharacters, '', $pValue) !== $pValue) {\n            throw new PHPExcel_Exception('Invalid character found in sheet title');\n        }\n\n        // Maximum 31 characters allowed for sheet title\n        if (PHPExcel_Shared_String::CountCharacters($pValue) > 31) {\n            throw new PHPExcel_Exception('Maximum 31 characters allowed in sheet title.');\n        }\n\n        return $pValue;\n    }\n\n    /**\n     * Get collection of cells\n     *\n     * @param boolean $pSorted Also sort the cell collection?\n     * @return PHPExcel_Cell[]\n     */\n    public function getCellCollection($pSorted = true)\n    {\n        if ($pSorted) {\n            // Re-order cell collection\n            return $this->sortCellCollection();\n        }\n        if ($this->_cellCollection !== NULL) {\n            return $this->_cellCollection->getCellList();\n        }\n        return array();\n    }\n\n    /**\n     * Sort collection of cells\n     *\n     * @return PHPExcel_Worksheet\n     */\n    public function sortCellCollection()\n    {\n        if ($this->_cellCollection !== NULL) {\n            return $this->_cellCollection->getSortedCellList();\n        }\n        return array();\n    }\n\n    /**\n     * Get collection of row dimensions\n     *\n     * @return PHPExcel_Worksheet_RowDimension[]\n     */\n    public function getRowDimensions()\n    {\n        return $this->_rowDimensions;\n    }\n\n    /**\n     * Get default row dimension\n     *\n     * @return PHPExcel_Worksheet_RowDimension\n     */\n    public function getDefaultRowDimension()\n    {\n        return $this->_defaultRowDimension;\n    }\n\n    /**\n     * Get collection of column dimensions\n     *\n     * @return PHPExcel_Worksheet_ColumnDimension[]\n     */\n    public function getColumnDimensions()\n    {\n        return $this->_columnDimensions;\n    }\n\n    /**\n     * Get default column dimension\n     *\n     * @return PHPExcel_Worksheet_ColumnDimension\n     */\n    public function getDefaultColumnDimension()\n    {\n        return $this->_defaultColumnDimension;\n    }\n\n    /**\n     * Get collection of drawings\n     *\n     * @return PHPExcel_Worksheet_BaseDrawing[]\n     */\n    public function getDrawingCollection()\n    {\n        return $this->_drawingCollection;\n    }\n\n    /**\n     * Get collection of charts\n     *\n     * @return PHPExcel_Chart[]\n     */\n    public function getChartCollection()\n    {\n        return $this->_chartCollection;\n    }\n\n    /**\n     * Add chart\n     *\n     * @param PHPExcel_Chart $pChart\n     * @param int|null $iChartIndex Index where chart should go (0,1,..., or null for last)\n     * @return PHPExcel_Chart\n     */\n    public function addChart(PHPExcel_Chart $pChart = null, $iChartIndex = null)\n    {\n        $pChart->setWorksheet($this);\n        if (is_null($iChartIndex)) {\n            $this->_chartCollection[] = $pChart;\n        } else {\n            // Insert the chart at the requested index\n            array_splice($this->_chartCollection, $iChartIndex, 0, array($pChart));\n        }\n\n        return $pChart;\n    }\n\n    /**\n     * Return the count of charts on this worksheet\n     *\n     * @return int        The number of charts\n     */\n    public function getChartCount()\n    {\n        return count($this->_chartCollection);\n    }\n\n    /**\n     * Get a chart by its index position\n     *\n     * @param string $index Chart index position\n     * @return false|PHPExcel_Chart\n     * @throws PHPExcel_Exception\n     */\n    public function getChartByIndex($index = null)\n    {\n        $chartCount = count($this->_chartCollection);\n        if ($chartCount == 0) {\n            return false;\n        }\n        if (is_null($index)) {\n            $index = --$chartCount;\n        }\n        if (!isset($this->_chartCollection[$index])) {\n            return false;\n        }\n\n        return $this->_chartCollection[$index];\n    }\n\n    /**\n     * Return an array of the names of charts on this worksheet\n     *\n     * @return string[] The names of charts\n     * @throws PHPExcel_Exception\n     */\n    public function getChartNames()\n    {\n        $chartNames = array();\n        foreach($this->_chartCollection as $chart) {\n            $chartNames[] = $chart->getName();\n        }\n        return $chartNames;\n    }\n\n    /**\n     * Get a chart by name\n     *\n     * @param string $chartName Chart name\n     * @return false|PHPExcel_Chart\n     * @throws PHPExcel_Exception\n     */\n    public function getChartByName($chartName = '')\n    {\n        $chartCount = count($this->_chartCollection);\n        if ($chartCount == 0) {\n            return false;\n        }\n        foreach($this->_chartCollection as $index => $chart) {\n            if ($chart->getName() == $chartName) {\n                return $this->_chartCollection[$index];\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Refresh column dimensions\n     *\n     * @return PHPExcel_Worksheet\n     */\n    public function refreshColumnDimensions()\n    {\n        $currentColumnDimensions = $this->getColumnDimensions();\n        $newColumnDimensions = array();\n\n        foreach ($currentColumnDimensions as $objColumnDimension) {\n            $newColumnDimensions[$objColumnDimension->getColumnIndex()] = $objColumnDimension;\n        }\n\n        $this->_columnDimensions = $newColumnDimensions;\n\n        return $this;\n    }\n\n    /**\n     * Refresh row dimensions\n     *\n     * @return PHPExcel_Worksheet\n     */\n    public function refreshRowDimensions()\n    {\n        $currentRowDimensions = $this->getRowDimensions();\n        $newRowDimensions = array();\n\n        foreach ($currentRowDimensions as $objRowDimension) {\n            $newRowDimensions[$objRowDimension->getRowIndex()] = $objRowDimension;\n        }\n\n        $this->_rowDimensions = $newRowDimensions;\n\n        return $this;\n    }\n\n    /**\n     * Calculate worksheet dimension\n     *\n     * @return string  String containing the dimension of this worksheet\n     */\n    public function calculateWorksheetDimension()\n    {\n        // Return\n        return 'A1' . ':' .  $this->getHighestColumn() . $this->getHighestRow();\n    }\n\n    /**\n     * Calculate worksheet data dimension\n     *\n     * @return string  String containing the dimension of this worksheet that actually contain data\n     */\n    public function calculateWorksheetDataDimension()\n    {\n        // Return\n        return 'A1' . ':' .  $this->getHighestDataColumn() . $this->getHighestDataRow();\n    }\n\n    /**\n     * Calculate widths for auto-size columns\n     *\n     * @param  boolean  $calculateMergeCells  Calculate merge cell width\n     * @return PHPExcel_Worksheet;\n     */\n    public function calculateColumnWidths($calculateMergeCells = false)\n    {\n        // initialize $autoSizes array\n        $autoSizes = array();\n        foreach ($this->getColumnDimensions() as $colDimension) {\n            if ($colDimension->getAutoSize()) {\n                $autoSizes[$colDimension->getColumnIndex()] = -1;\n            }\n        }\n\n        // There is only something to do if there are some auto-size columns\n        if (!empty($autoSizes)) {\n\n            // build list of cells references that participate in a merge\n            $isMergeCell = array();\n            foreach ($this->getMergeCells() as $cells) {\n                foreach (PHPExcel_Cell::extractAllCellReferencesInRange($cells) as $cellReference) {\n                    $isMergeCell[$cellReference] = true;\n                }\n            }\n\n            // loop through all cells in the worksheet\n            foreach ($this->getCellCollection(false) as $cellID) {\n                $cell = $this->getCell($cellID);\n\t\t\t\tif (isset($autoSizes[$this->_cellCollection->getCurrentColumn()])) {\n                    // Determine width if cell does not participate in a merge\n\t\t\t\t\tif (!isset($isMergeCell[$this->_cellCollection->getCurrentAddress()])) {\n                        // Calculated value\n                        // To formatted string\n\t\t\t\t\t\t$cellValue = PHPExcel_Style_NumberFormat::toFormattedString(\n\t\t\t\t\t\t\t$cell->getCalculatedValue(),\n\t\t\t\t\t\t\t$this->getParent()->getCellXfByIndex($cell->getXfIndex())->getNumberFormat()->getFormatCode()\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\t$autoSizes[$this->_cellCollection->getCurrentColumn()] = max(\n\t\t\t\t\t\t\t(float) $autoSizes[$this->_cellCollection->getCurrentColumn()],\n                            (float)PHPExcel_Shared_Font::calculateColumnWidth(\n\t\t\t\t\t\t\t\t$this->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont(),\n                                $cellValue,\n\t\t\t\t\t\t\t\t$this->getParent()->getCellXfByIndex($cell->getXfIndex())->getAlignment()->getTextRotation(),\n                                $this->getDefaultStyle()->getFont()\n                            )\n                        );\n                    }\n                }\n            }\n\n            // adjust column widths\n            foreach ($autoSizes as $columnIndex => $width) {\n                if ($width == -1) $width = $this->getDefaultColumnDimension()->getWidth();\n                $this->getColumnDimension($columnIndex)->setWidth($width);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get parent\n     *\n     * @return PHPExcel\n     */\n\tpublic function getParent() {\n        return $this->_parent;\n    }\n\n    /**\n     * Re-bind parent\n     *\n     * @param PHPExcel $parent\n     * @return PHPExcel_Worksheet\n     */\n\tpublic function rebindParent(PHPExcel $parent) {\n        if ($this->_parent !== null) {\n            $namedRanges = $this->_parent->getNamedRanges();\n            foreach ($namedRanges as $namedRange) {\n                $parent->addNamedRange($namedRange);\n            }\n\n            $this->_parent->removeSheetByIndex(\n                $this->_parent->getIndex($this)\n            );\n        }\n        $this->_parent = $parent;\n\n        return $this;\n    }\n\n    /**\n     * Get title\n     *\n     * @return string\n     */\n    public function getTitle()\n    {\n        return $this->_title;\n    }\n\n    /**\n     * Set title\n     *\n     * @param string $pValue String containing the dimension of this worksheet\n     * @param string $updateFormulaCellReferences boolean Flag indicating whether cell references in formulae should\n     *        \tbe updated to reflect the new sheet name.\n     *          This should be left as the default true, unless you are\n     *          certain that no formula cells on any worksheet contain\n     *          references to this worksheet\n     * @return PHPExcel_Worksheet\n     */\n    public function setTitle($pValue = 'Worksheet', $updateFormulaCellReferences = true)\n    {\n        // Is this a 'rename' or not?\n        if ($this->getTitle() == $pValue) {\n            return $this;\n        }\n\n        // Syntax check\n        self::_checkSheetTitle($pValue);\n\n        // Old title\n        $oldTitle = $this->getTitle();\n\n        if ($this->_parent) {\n            // Is there already such sheet name?\n\t\t\tif ($this->_parent->sheetNameExists($pValue)) {\n                // Use name, but append with lowest possible integer\n\n                if (PHPExcel_Shared_String::CountCharacters($pValue) > 29) {\n                    $pValue = PHPExcel_Shared_String::Substring($pValue,0,29);\n                }\n                $i = 1;\n\t\t\t\twhile ($this->_parent->sheetNameExists($pValue . ' ' . $i)) {\n                    ++$i;\n                    if ($i == 10) {\n                        if (PHPExcel_Shared_String::CountCharacters($pValue) > 28) {\n                            $pValue = PHPExcel_Shared_String::Substring($pValue,0,28);\n                        }\n                    } elseif ($i == 100) {\n                        if (PHPExcel_Shared_String::CountCharacters($pValue) > 27) {\n                            $pValue = PHPExcel_Shared_String::Substring($pValue,0,27);\n                        }\n                    }\n                }\n\n                $altTitle = $pValue . ' ' . $i;\n                return $this->setTitle($altTitle,$updateFormulaCellReferences);\n            }\n        }\n\n        // Set title\n        $this->_title = $pValue;\n        $this->_dirty = true;\n\n        if ($this->_parent) {\n            // New title\n            $newTitle = $this->getTitle();\n\t\t\tPHPExcel_Calculation::getInstance($this->_parent)\n\t\t\t    ->renameCalculationCacheForWorksheet($oldTitle, $newTitle);\n            if ($updateFormulaCellReferences)\n\t\t\t\tPHPExcel_ReferenceHelper::getInstance()->updateNamedFormulas($this->_parent, $oldTitle, $newTitle);\n        }\n\n        return $this;\n    }\n\n    /**\n     * Get sheet state\n     *\n     * @return string Sheet state (visible, hidden, veryHidden)\n     */\n\tpublic function getSheetState() {\n        return $this->_sheetState;\n    }\n\n    /**\n     * Set sheet state\n     *\n     * @param string $value Sheet state (visible, hidden, veryHidden)\n     * @return PHPExcel_Worksheet\n     */\n\tpublic function setSheetState($value = PHPExcel_Worksheet::SHEETSTATE_VISIBLE) {\n        $this->_sheetState = $value;\n        return $this;\n    }\n\n    /**\n     * Get page setup\n     *\n     * @return PHPExcel_Worksheet_PageSetup\n     */\n    public function getPageSetup()\n    {\n        return $this->_pageSetup;\n    }\n\n    /**\n     * Set page setup\n     *\n     * @param PHPExcel_Worksheet_PageSetup    $pValue\n     * @return PHPExcel_Worksheet\n     */\n    public function setPageSetup(PHPExcel_Worksheet_PageSetup $pValue)\n    {\n        $this->_pageSetup = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get page margins\n     *\n     * @return PHPExcel_Worksheet_PageMargins\n     */\n    public function getPageMargins()\n    {\n        return $this->_pageMargins;\n    }\n\n    /**\n     * Set page margins\n     *\n     * @param PHPExcel_Worksheet_PageMargins    $pValue\n     * @return PHPExcel_Worksheet\n     */\n    public function setPageMargins(PHPExcel_Worksheet_PageMargins $pValue)\n    {\n        $this->_pageMargins = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get page header/footer\n     *\n     * @return PHPExcel_Worksheet_HeaderFooter\n     */\n    public function getHeaderFooter()\n    {\n        return $this->_headerFooter;\n    }\n\n    /**\n     * Set page header/footer\n     *\n     * @param PHPExcel_Worksheet_HeaderFooter    $pValue\n     * @return PHPExcel_Worksheet\n     */\n    public function setHeaderFooter(PHPExcel_Worksheet_HeaderFooter $pValue)\n    {\n        $this->_headerFooter = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get sheet view\n     *\n     * @return PHPExcel_Worksheet_SheetView\n     */\n    public function getSheetView()\n    {\n        return $this->_sheetView;\n    }\n\n    /**\n     * Set sheet view\n     *\n     * @param PHPExcel_Worksheet_SheetView    $pValue\n     * @return PHPExcel_Worksheet\n     */\n    public function setSheetView(PHPExcel_Worksheet_SheetView $pValue)\n    {\n        $this->_sheetView = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get Protection\n     *\n     * @return PHPExcel_Worksheet_Protection\n     */\n    public function getProtection()\n    {\n        return $this->_protection;\n    }\n\n    /**\n     * Set Protection\n     *\n     * @param PHPExcel_Worksheet_Protection    $pValue\n     * @return PHPExcel_Worksheet\n     */\n    public function setProtection(PHPExcel_Worksheet_Protection $pValue)\n    {\n        $this->_protection = $pValue;\n        $this->_dirty = true;\n\n        return $this;\n    }\n\n    /**\n     * Get highest worksheet column\n     *\n     * @param   string     $row        Return the data highest column for the specified row,\n     *                                     or the highest column of any row if no row number is passed\n     * @return string Highest column name\n     */\n    public function getHighestColumn($row = null)\n    {\n        if ($row == null) {\n            return $this->_cachedHighestColumn;\n        }\n        return $this->getHighestDataColumn($row);\n    }\n\n    /**\n     * Get highest worksheet column that contains data\n     *\n     * @param   string     $row        Return the highest data column for the specified row,\n     *                                     or the highest data column of any row if no row number is passed\n     * @return string Highest column name that contains data\n     */\n    public function getHighestDataColumn($row = null)\n    {\n        return $this->_cellCollection->getHighestColumn($row);\n    }\n\n    /**\n     * Get highest worksheet row\n     *\n     * @param   string     $column     Return the highest data row for the specified column,\n     *                                     or the highest row of any column if no column letter is passed\n     * @return int Highest row number\n     */\n    public function getHighestRow($column = null)\n    {\n        if ($column == null) {\n            return $this->_cachedHighestRow;\n        }\n        return $this->getHighestDataRow($column);\n    }\n\n    /**\n     * Get highest worksheet row that contains data\n     *\n     * @param   string     $column     Return the highest data row for the specified column,\n     *                                     or the highest data row of any column if no column letter is passed\n     * @return string Highest row number that contains data\n     */\n    public function getHighestDataRow($column = null)\n    {\n        return $this->_cellCollection->getHighestRow($column);\n    }\n\n    /**\n     * Get highest worksheet column and highest row that have cell records\n     *\n     * @return array Highest column name and highest row number\n     */\n    public function getHighestRowAndColumn()\n    {\n        return $this->_cellCollection->getHighestRowAndColumn();\n    }\n\n    /**\n     * Set a cell value\n     *\n     * @param string $pCoordinate Coordinate of the cell\n     * @param mixed $pValue Value of the cell\n     * @param bool $returnCell   Return the worksheet (false, default) or the cell (true)\n     * @return PHPExcel_Worksheet|PHPExcel_Cell    Depending on the last parameter being specified\n     */\n    public function setCellValue($pCoordinate = 'A1', $pValue = null, $returnCell = false)\n    {\n        $cell = $this->getCell(strtoupper($pCoordinate))->setValue($pValue);\n        return ($returnCell) ? $cell : $this;\n    }\n\n    /**\n     * Set a cell value by using numeric cell coordinates\n     *\n     * @param string $pColumn Numeric column coordinate of the cell (A = 0)\n     * @param string $pRow Numeric row coordinate of the cell\n     * @param mixed $pValue Value of the cell\n     * @param bool $returnCell Return the worksheet (false, default) or the cell (true)\n     * @return PHPExcel_Worksheet|PHPExcel_Cell    Depending on the last parameter being specified\n     */\n    public function setCellValueByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $returnCell = false)\n    {\n        $cell = $this->getCellByColumnAndRow($pColumn, $pRow)->setValue($pValue);\n        return ($returnCell) ? $cell : $this;\n    }\n\n    /**\n     * Set a cell value\n     *\n     * @param string $pCoordinate Coordinate of the cell\n     * @param mixed  $pValue Value of the cell\n     * @param string $pDataType Explicit data type\n     * @param bool $returnCell Return the worksheet (false, default) or the cell (true)\n     * @return PHPExcel_Worksheet|PHPExcel_Cell    Depending on the last parameter being specified\n     */\n    public function setCellValueExplicit($pCoordinate = 'A1', $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false)\n    {\n        // Set value\n        $cell = $this->getCell(strtoupper($pCoordinate))->setValueExplicit($pValue, $pDataType);\n        return ($returnCell) ? $cell : $this;\n    }\n\n    /**\n     * Set a cell value by using numeric cell coordinates\n     *\n     * @param string $pColumn Numeric column coordinate of the cell\n     * @param string $pRow Numeric row coordinate of the cell\n     * @param mixed $pValue Value of the cell\n     * @param string $pDataType Explicit data type\n     * @param bool $returnCell Return the worksheet (false, default) or the cell (true)\n     * @return PHPExcel_Worksheet|PHPExcel_Cell    Depending on the last parameter being specified\n     */\n    public function setCellValueExplicitByColumnAndRow($pColumn = 0, $pRow = 1, $pValue = null, $pDataType = PHPExcel_Cell_DataType::TYPE_STRING, $returnCell = false)\n    {\n        $cell = $this->getCellByColumnAndRow($pColumn, $pRow)->setValueExplicit($pValue, $pDataType);\n        return ($returnCell) ? $cell : $this;\n    }\n\n    /**\n     * Get cell at a specific coordinate\n     *\n     * @param string $pCoordinate    Coordinate of the cell\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Cell Cell that was found\n     */\n    public function getCell($pCoordinate = 'A1')\n    {\n        $pCoordinate = strtoupper($pCoordinate);\n        // Check cell collection\n        if ($this->_cellCollection->isDataSet($pCoordinate)) {\n            return $this->_cellCollection->getCacheData($pCoordinate);\n        }\n\n        // Worksheet reference?\n        if (strpos($pCoordinate, '!') !== false) {\n            $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true);\n\t\t\treturn $this->_parent->getSheetByName($worksheetReference[0])->getCell($worksheetReference[1]);\n        }\n\n        // Named range?\n        if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) &&\n            (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) {\n            $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this);\n            if ($namedRange !== NULL) {\n                $pCoordinate = $namedRange->getRange();\n                return $namedRange->getWorksheet()->getCell($pCoordinate);\n            }\n        }\n\n        // Uppercase coordinate\n        $pCoordinate = strtoupper($pCoordinate);\n\n        if (strpos($pCoordinate, ':') !== false || strpos($pCoordinate, ',') !== false) {\n            throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.');\n        } elseif (strpos($pCoordinate, '$') !== false) {\n            throw new PHPExcel_Exception('Cell coordinate must not be absolute.');\n        }\n\n        // Create new cell object\n        return $this->_createNewCell($pCoordinate);\n    }\n\n    /**\n     * Get cell at a specific coordinate by using numeric cell coordinates\n     *\n     * @param  string $pColumn Numeric column coordinate of the cell\n     * @param string $pRow Numeric row coordinate of the cell\n     * @return PHPExcel_Cell Cell that was found\n     */\n    public function getCellByColumnAndRow($pColumn = 0, $pRow = 1)\n    {\n        $columnLetter = PHPExcel_Cell::stringFromColumnIndex($pColumn);\n        $coordinate = $columnLetter . $pRow;\n\n        if ($this->_cellCollection->isDataSet($coordinate)) {\n            return $this->_cellCollection->getCacheData($coordinate);\n        }\n\n\t\treturn $this->_createNewCell($coordinate);\n    }\n\n    /**\n     * Create a new cell at the specified coordinate\n     *\n     * @param string $pCoordinate    Coordinate of the cell\n     * @return PHPExcel_Cell Cell that was created\n     */\n\tprivate function _createNewCell($pCoordinate)\n\t{\n\t\t$cell = $this->_cellCollection->addCacheData(\n\t\t\t$pCoordinate,\n\t\t\tnew PHPExcel_Cell(\n\t\t\t\tNULL, \n\t\t\t\tPHPExcel_Cell_DataType::TYPE_NULL, \n\t\t\t\t$this\n\t\t\t)\n\t\t);\n        $this->_cellCollectionIsSorted = false;\n\n        // Coordinates\n        $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate);\n        if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($aCoordinates[0]))\n            $this->_cachedHighestColumn = $aCoordinates[0];\n        $this->_cachedHighestRow = max($this->_cachedHighestRow, $aCoordinates[1]);\n\n        // Cell needs appropriate xfIndex from dimensions records\n\t\t//    but don't create dimension records if they don't already exist\n        $rowDimension    = $this->getRowDimension($aCoordinates[1], FALSE);\n        $columnDimension = $this->getColumnDimension($aCoordinates[0], FALSE);\n\n        if ($rowDimension !== NULL && $rowDimension->getXfIndex() > 0) {\n            // then there is a row dimension with explicit style, assign it to the cell\n            $cell->setXfIndex($rowDimension->getXfIndex());\n        } elseif ($columnDimension !== NULL && $columnDimension->getXfIndex() > 0) {\n            // then there is a column dimension, assign it to the cell\n            $cell->setXfIndex($columnDimension->getXfIndex());\n        }\n\n        return $cell;\n\t}\n\t\n    /**\n     * Does the cell at a specific coordinate exist?\n     *\n     * @param string $pCoordinate  Coordinate of the cell\n     * @throws PHPExcel_Exception\n     * @return boolean\n     */\n    public function cellExists($pCoordinate = 'A1')\n    {\n       // Worksheet reference?\n        if (strpos($pCoordinate, '!') !== false) {\n            $worksheetReference = PHPExcel_Worksheet::extractSheetTitle($pCoordinate, true);\n\t\t\treturn $this->_parent->getSheetByName($worksheetReference[0])->cellExists(strtoupper($worksheetReference[1]));\n        }\n\n        // Named range?\n        if ((!preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_CELLREF.'$/i', $pCoordinate, $matches)) &&\n            (preg_match('/^'.PHPExcel_Calculation::CALCULATION_REGEXP_NAMEDRANGE.'$/i', $pCoordinate, $matches))) {\n            $namedRange = PHPExcel_NamedRange::resolveRange($pCoordinate, $this);\n            if ($namedRange !== NULL) {\n                $pCoordinate = $namedRange->getRange();\n                if ($this->getHashCode() != $namedRange->getWorksheet()->getHashCode()) {\n                    if (!$namedRange->getLocalOnly()) {\n                        return $namedRange->getWorksheet()->cellExists($pCoordinate);\n                    } else {\n                        throw new PHPExcel_Exception('Named range ' . $namedRange->getName() . ' is not accessible from within sheet ' . $this->getTitle());\n                    }\n                }\n            }\n            else { return false; }\n        }\n\n        // Uppercase coordinate\n        $pCoordinate = strtoupper($pCoordinate);\n\n        if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) {\n            throw new PHPExcel_Exception('Cell coordinate can not be a range of cells.');\n        } elseif (strpos($pCoordinate,'$') !== false) {\n            throw new PHPExcel_Exception('Cell coordinate must not be absolute.');\n        } else {\n            // Coordinates\n            $aCoordinates = PHPExcel_Cell::coordinateFromString($pCoordinate);\n\n            // Cell exists?\n            return $this->_cellCollection->isDataSet($pCoordinate);\n        }\n    }\n\n    /**\n     * Cell at a specific coordinate by using numeric cell coordinates exists?\n     *\n     * @param string $pColumn Numeric column coordinate of the cell\n     * @param string $pRow Numeric row coordinate of the cell\n     * @return boolean\n     */\n    public function cellExistsByColumnAndRow($pColumn = 0, $pRow = 1)\n    {\n        return $this->cellExists(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);\n    }\n\n    /**\n     * Get row dimension at a specific row\n     *\n     * @param int $pRow Numeric index of the row\n     * @return PHPExcel_Worksheet_RowDimension\n     */\n    public function getRowDimension($pRow = 1, $create = TRUE)\n    {\n        // Found\n        $found = null;\n\n        // Get row dimension\n        if (!isset($this->_rowDimensions[$pRow])) {\n\t\t\tif (!$create)\n\t\t\t\treturn NULL;\n            $this->_rowDimensions[$pRow] = new PHPExcel_Worksheet_RowDimension($pRow);\n\n            $this->_cachedHighestRow = max($this->_cachedHighestRow,$pRow);\n        }\n        return $this->_rowDimensions[$pRow];\n    }\n\n    /**\n     * Get column dimension at a specific column\n     *\n     * @param string $pColumn String index of the column\n     * @return PHPExcel_Worksheet_ColumnDimension\n     */\n    public function getColumnDimension($pColumn = 'A', $create = TRUE)\n    {\n        // Uppercase coordinate\n        $pColumn = strtoupper($pColumn);\n\n        // Fetch dimensions\n        if (!isset($this->_columnDimensions[$pColumn])) {\n\t\t\tif (!$create)\n\t\t\t\treturn NULL;\n            $this->_columnDimensions[$pColumn] = new PHPExcel_Worksheet_ColumnDimension($pColumn);\n\n            if (PHPExcel_Cell::columnIndexFromString($this->_cachedHighestColumn) < PHPExcel_Cell::columnIndexFromString($pColumn))\n                $this->_cachedHighestColumn = $pColumn;\n        }\n        return $this->_columnDimensions[$pColumn];\n    }\n\n    /**\n     * Get column dimension at a specific column by using numeric cell coordinates\n     *\n     * @param string $pColumn Numeric column coordinate of the cell\n     * @return PHPExcel_Worksheet_ColumnDimension\n     */\n    public function getColumnDimensionByColumn($pColumn = 0)\n    {\n        return $this->getColumnDimension(PHPExcel_Cell::stringFromColumnIndex($pColumn));\n    }\n\n    /**\n     * Get styles\n     *\n     * @return PHPExcel_Style[]\n     */\n    public function getStyles()\n    {\n        return $this->_styles;\n    }\n\n    /**\n     * Get default style of workbook.\n     *\n     * @deprecated\n     * @return PHPExcel_Style\n     * @throws PHPExcel_Exception\n     */\n    public function getDefaultStyle()\n    {\n        return $this->_parent->getDefaultStyle();\n    }\n\n    /**\n     * Set default style - should only be used by PHPExcel_IReader implementations!\n     *\n     * @deprecated\n     * @param PHPExcel_Style $pValue\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function setDefaultStyle(PHPExcel_Style $pValue)\n    {\n        $this->_parent->getDefaultStyle()->applyFromArray(array(\n            'font' => array(\n                'name' => $pValue->getFont()->getName(),\n                'size' => $pValue->getFont()->getSize(),\n            ),\n        ));\n        return $this;\n    }\n\n    /**\n     * Get style for cell\n     *\n     * @param string $pCellCoordinate Cell coordinate (or range) to get style for\n     * @return PHPExcel_Style\n     * @throws PHPExcel_Exception\n     */\n    public function getStyle($pCellCoordinate = 'A1')\n    {\n        // set this sheet as active\n        $this->_parent->setActiveSheetIndex($this->_parent->getIndex($this));\n\n        // set cell coordinate as active\n        $this->setSelectedCells(strtoupper($pCellCoordinate));\n\n        return $this->_parent->getCellXfSupervisor();\n    }\n\n    /**\n     * Get conditional styles for a cell\n     *\n     * @param string $pCoordinate\n     * @return PHPExcel_Style_Conditional[]\n     */\n    public function getConditionalStyles($pCoordinate = 'A1')\n    {\n        $pCoordinate = strtoupper($pCoordinate);\n        if (!isset($this->_conditionalStylesCollection[$pCoordinate])) {\n            $this->_conditionalStylesCollection[$pCoordinate] = array();\n        }\n        return $this->_conditionalStylesCollection[$pCoordinate];\n    }\n\n    /**\n     * Do conditional styles exist for this cell?\n     *\n     * @param string $pCoordinate\n     * @return boolean\n     */\n    public function conditionalStylesExists($pCoordinate = 'A1')\n    {\n        if (isset($this->_conditionalStylesCollection[strtoupper($pCoordinate)])) {\n            return true;\n        }\n        return false;\n    }\n\n    /**\n     * Removes conditional styles for a cell\n     *\n     * @param string $pCoordinate\n     * @return PHPExcel_Worksheet\n     */\n    public function removeConditionalStyles($pCoordinate = 'A1')\n    {\n        unset($this->_conditionalStylesCollection[strtoupper($pCoordinate)]);\n        return $this;\n    }\n\n    /**\n     * Get collection of conditional styles\n     *\n     * @return array\n     */\n    public function getConditionalStylesCollection()\n    {\n        return $this->_conditionalStylesCollection;\n    }\n\n    /**\n     * Set conditional styles\n     *\n     * @param $pCoordinate string E.g. 'A1'\n     * @param $pValue PHPExcel_Style_Conditional[]\n     * @return PHPExcel_Worksheet\n     */\n    public function setConditionalStyles($pCoordinate = 'A1', $pValue)\n    {\n        $this->_conditionalStylesCollection[strtoupper($pCoordinate)] = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get style for cell by using numeric cell coordinates\n     *\n     * @param int $pColumn  Numeric column coordinate of the cell\n     * @param int $pRow Numeric row coordinate of the cell\n     * @param int pColumn2 Numeric column coordinate of the range cell\n     * @param int pRow2 Numeric row coordinate of the range cell\n     * @return PHPExcel_Style\n     */\n    public function getStyleByColumnAndRow($pColumn = 0, $pRow = 1, $pColumn2 = null, $pRow2 = null)\n    {\n        if (!is_null($pColumn2) && !is_null($pRow2)) {\n\t\t    $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow . ':' . \n                PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;\n\t\t    return $this->getStyle($cellRange);\n\t    }\n\n        return $this->getStyle(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);\n    }\n\n    /**\n     * Set shared cell style to a range of cells\n     *\n     * Please note that this will overwrite existing cell styles for cells in range!\n     *\n     * @deprecated\n     * @param PHPExcel_Style $pSharedCellStyle Cell style to share\n     * @param string $pRange Range of cells (i.e. \"A1:B10\"), or just one cell (i.e. \"A1\")\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function setSharedStyle(PHPExcel_Style $pSharedCellStyle = null, $pRange = '')\n    {\n        $this->duplicateStyle($pSharedCellStyle, $pRange);\n        return $this;\n    }\n\n    /**\n     * Duplicate cell style to a range of cells\n     *\n     * Please note that this will overwrite existing cell styles for cells in range!\n     *\n     * @param PHPExcel_Style $pCellStyle Cell style to duplicate\n     * @param string $pRange Range of cells (i.e. \"A1:B10\"), or just one cell (i.e. \"A1\")\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function duplicateStyle(PHPExcel_Style $pCellStyle = null, $pRange = '')\n    {\n        // make sure we have a real style and not supervisor\n        $style = $pCellStyle->getIsSupervisor() ? $pCellStyle->getSharedComponent() : $pCellStyle;\n\n        // Add the style to the workbook if necessary\n        $workbook = $this->_parent;\n\t\tif ($existingStyle = $this->_parent->getCellXfByHashCode($pCellStyle->getHashCode())) {\n            // there is already such cell Xf in our collection\n            $xfIndex = $existingStyle->getIndex();\n        } else {\n            // we don't have such a cell Xf, need to add\n            $workbook->addCellXf($pCellStyle);\n            $xfIndex = $pCellStyle->getIndex();\n        }\n\n        // Calculate range outer borders\n        list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange . ':' . $pRange);\n\n        // Make sure we can loop upwards on rows and columns\n        if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {\n            $tmp = $rangeStart;\n            $rangeStart = $rangeEnd;\n            $rangeEnd = $tmp;\n        }\n\n        // Loop through cells and apply styles\n        for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {\n            for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {\n                $this->getCell(PHPExcel_Cell::stringFromColumnIndex($col - 1) . $row)->setXfIndex($xfIndex);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Duplicate conditional style to a range of cells\n     *\n     * Please note that this will overwrite existing cell styles for cells in range!\n     *\n\t * @param\tarray of PHPExcel_Style_Conditional\t$pCellStyle\tCell style to duplicate\n     * @param string $pRange Range of cells (i.e. \"A1:B10\"), or just one cell (i.e. \"A1\")\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function duplicateConditionalStyle(array $pCellStyle = null, $pRange = '')\n    {\n        foreach($pCellStyle as $cellStyle) {\n            if (!($cellStyle instanceof PHPExcel_Style_Conditional)) {\n                throw new PHPExcel_Exception('Style is not a conditional style');\n            }\n        }\n\n        // Calculate range outer borders\n        list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange . ':' . $pRange);\n\n        // Make sure we can loop upwards on rows and columns\n        if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {\n            $tmp = $rangeStart;\n            $rangeStart = $rangeEnd;\n            $rangeEnd = $tmp;\n        }\n\n        // Loop through cells and apply styles\n        for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {\n            for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {\n                $this->setConditionalStyles(PHPExcel_Cell::stringFromColumnIndex($col - 1) . $row, $pCellStyle);\n            }\n        }\n\n        return $this;\n    }\n\n    /**\n     * Duplicate cell style array to a range of cells\n     *\n     * Please note that this will overwrite existing cell styles for cells in range,\n     * if they are in the styles array. For example, if you decide to set a range of\n     * cells to font bold, only include font bold in the styles array.\n     *\n     * @deprecated\n     * @param array $pStyles Array containing style information\n     * @param string $pRange Range of cells (i.e. \"A1:B10\"), or just one cell (i.e. \"A1\")\n     * @param boolean $pAdvanced Advanced mode for setting borders.\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function duplicateStyleArray($pStyles = null, $pRange = '', $pAdvanced = true)\n    {\n        $this->getStyle($pRange)->applyFromArray($pStyles, $pAdvanced);\n        return $this;\n    }\n\n    /**\n     * Set break on a cell\n     *\n     * @param string $pCell Cell coordinate (e.g. A1)\n     * @param int $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*)\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function setBreak($pCell = 'A1', $pBreak = PHPExcel_Worksheet::BREAK_NONE)\n    {\n        // Uppercase coordinate\n        $pCell = strtoupper($pCell);\n\n        if ($pCell != '') {\n        \tif ($pBreak == PHPExcel_Worksheet::BREAK_NONE) {\n        \t\tif (isset($this->_breaks[$pCell])) {\n\t            \tunset($this->_breaks[$pCell]);\n        \t\t}\n        \t} else {\n\t            $this->_breaks[$pCell] = $pBreak;\n\t        }\n        } else {\n            throw new PHPExcel_Exception('No cell coordinate specified.');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set break on a cell by using numeric cell coordinates\n     *\n     * @param integer $pColumn Numeric column coordinate of the cell\n     * @param integer $pRow Numeric row coordinate of the cell\n     * @param  integer $pBreak Break type (type of PHPExcel_Worksheet::BREAK_*)\n     * @return PHPExcel_Worksheet\n     */\n    public function setBreakByColumnAndRow($pColumn = 0, $pRow = 1, $pBreak = PHPExcel_Worksheet::BREAK_NONE)\n    {\n        return $this->setBreak(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow, $pBreak);\n    }\n\n    /**\n     * Get breaks\n     *\n     * @return array[]\n     */\n    public function getBreaks()\n    {\n        return $this->_breaks;\n    }\n\n    /**\n     * Set merge on a cell range\n     *\n     * @param string $pRange  Cell range (e.g. A1:E1)\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function mergeCells($pRange = 'A1:A1')\n    {\n        // Uppercase coordinate\n        $pRange = strtoupper($pRange);\n\n        if (strpos($pRange,':') !== false) {\n            $this->_mergeCells[$pRange] = $pRange;\n\n            // make sure cells are created\n\n            // get the cells in the range\n            $aReferences = PHPExcel_Cell::extractAllCellReferencesInRange($pRange);\n\n            // create upper left cell if it does not already exist\n            $upperLeft = $aReferences[0];\n            if (!$this->cellExists($upperLeft)) {\n                $this->getCell($upperLeft)->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL);\n            }\n\n            // create or blank out the rest of the cells in the range\n            $count = count($aReferences);\n            for ($i = 1; $i < $count; $i++) {\n                $this->getCell($aReferences[$i])->setValueExplicit(null, PHPExcel_Cell_DataType::TYPE_NULL);\n            }\n\n        } else {\n            throw new PHPExcel_Exception('Merge must be set on a range of cells.');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Set merge on a cell range by using numeric cell coordinates\n     *\n     * @param int $pColumn1    Numeric column coordinate of the first cell\n     * @param int $pRow1        Numeric row coordinate of the first cell\n     * @param int $pColumn2    Numeric column coordinate of the last cell\n     * @param int $pRow2        Numeric row coordinate of the last cell\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function mergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)\n    {\n        $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;\n        return $this->mergeCells($cellRange);\n    }\n\n    /**\n     * Remove merge on a cell range\n     *\n     * @param    string            $pRange        Cell range (e.g. A1:E1)\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function unmergeCells($pRange = 'A1:A1')\n    {\n        // Uppercase coordinate\n        $pRange = strtoupper($pRange);\n\n        if (strpos($pRange,':') !== false) {\n            if (isset($this->_mergeCells[$pRange])) {\n                unset($this->_mergeCells[$pRange]);\n            } else {\n                throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as merged.');\n            }\n        } else {\n            throw new PHPExcel_Exception('Merge can only be removed from a range of cells.');\n        }\n\n        return $this;\n    }\n\n    /**\n     * Remove merge on a cell range by using numeric cell coordinates\n     *\n     * @param int $pColumn1    Numeric column coordinate of the first cell\n     * @param int $pRow1        Numeric row coordinate of the first cell\n     * @param int $pColumn2    Numeric column coordinate of the last cell\n     * @param int $pRow2        Numeric row coordinate of the last cell\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function unmergeCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)\n    {\n        $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;\n        return $this->unmergeCells($cellRange);\n    }\n\n    /**\n     * Get merge cells array.\n     *\n     * @return array[]\n     */\n    public function getMergeCells()\n    {\n        return $this->_mergeCells;\n    }\n\n    /**\n     * Set merge cells array for the entire sheet. Use instead mergeCells() to merge\n     * a single cell range.\n     *\n     * @param array\n     */\n    public function setMergeCells($pValue = array())\n    {\n        $this->_mergeCells = $pValue;\n\n        return $this;\n    }\n\n    /**\n     * Set protection on a cell range\n     *\n     * @param    string            $pRange                Cell (e.g. A1) or cell range (e.g. A1:E1)\n     * @param    string            $pPassword            Password to unlock the protection\n     * @param    boolean        $pAlreadyHashed    If the password has already been hashed, set this to true\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function protectCells($pRange = 'A1', $pPassword = '', $pAlreadyHashed = false)\n    {\n        // Uppercase coordinate\n        $pRange = strtoupper($pRange);\n\n        if (!$pAlreadyHashed) {\n            $pPassword = PHPExcel_Shared_PasswordHasher::hashPassword($pPassword);\n        }\n        $this->_protectedCells[$pRange] = $pPassword;\n\n        return $this;\n    }\n\n    /**\n     * Set protection on a cell range by using numeric cell coordinates\n     *\n     * @param int  $pColumn1            Numeric column coordinate of the first cell\n     * @param int  $pRow1                Numeric row coordinate of the first cell\n     * @param int  $pColumn2            Numeric column coordinate of the last cell\n     * @param int  $pRow2                Numeric row coordinate of the last cell\n     * @param string $pPassword            Password to unlock the protection\n     * @param    boolean $pAlreadyHashed    If the password has already been hashed, set this to true\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function protectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false)\n    {\n        $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;\n        return $this->protectCells($cellRange, $pPassword, $pAlreadyHashed);\n    }\n\n    /**\n     * Remove protection on a cell range\n     *\n     * @param    string            $pRange        Cell (e.g. A1) or cell range (e.g. A1:E1)\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function unprotectCells($pRange = 'A1')\n    {\n        // Uppercase coordinate\n        $pRange = strtoupper($pRange);\n\n        if (isset($this->_protectedCells[$pRange])) {\n            unset($this->_protectedCells[$pRange]);\n        } else {\n            throw new PHPExcel_Exception('Cell range ' . $pRange . ' not known as protected.');\n        }\n        return $this;\n    }\n\n    /**\n     * Remove protection on a cell range by using numeric cell coordinates\n     *\n     * @param int  $pColumn1            Numeric column coordinate of the first cell\n     * @param int  $pRow1                Numeric row coordinate of the first cell\n     * @param int  $pColumn2            Numeric column coordinate of the last cell\n     * @param int $pRow2                Numeric row coordinate of the last cell\n     * @param string $pPassword            Password to unlock the protection\n     * @param    boolean $pAlreadyHashed    If the password has already been hashed, set this to true\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function unprotectCellsByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1, $pPassword = '', $pAlreadyHashed = false)\n    {\n        $cellRange = PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1 . ':' . PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2;\n        return $this->unprotectCells($cellRange, $pPassword, $pAlreadyHashed);\n    }\n\n    /**\n     * Get protected cells\n     *\n     * @return array[]\n     */\n    public function getProtectedCells()\n    {\n        return $this->_protectedCells;\n    }\n\n    /**\n     *    Get Autofilter\n     *\n     *    @return PHPExcel_Worksheet_AutoFilter\n     */\n    public function getAutoFilter()\n    {\n        return $this->_autoFilter;\n    }\n\n    /**\n     *    Set AutoFilter\n     *\n     *    @param    PHPExcel_Worksheet_AutoFilter|string   $pValue\n     *            A simple string containing a Cell range like 'A1:E10' is permitted for backward compatibility\n     *    @throws    PHPExcel_Exception\n     *    @return PHPExcel_Worksheet\n     */\n    public function setAutoFilter($pValue)\n    {\n        $pRange = strtoupper($pValue);\n\n        if (is_string($pValue)) {\n            $this->_autoFilter->setRange($pValue);\n        } elseif(is_object($pValue) && ($pValue instanceof PHPExcel_Worksheet_AutoFilter)) {\n            $this->_autoFilter = $pValue;\n        }\n        return $this;\n    }\n\n    /**\n     *    Set Autofilter Range by using numeric cell coordinates\n     *\n     *    @param  integer  $pColumn1    Numeric column coordinate of the first cell\n     *    @param  integer  $pRow1       Numeric row coordinate of the first cell\n     *    @param  integer  $pColumn2    Numeric column coordinate of the second cell\n     *    @param  integer  $pRow2       Numeric row coordinate of the second cell\n     *    @throws    PHPExcel_Exception\n     *    @return PHPExcel_Worksheet\n     */\n    public function setAutoFilterByColumnAndRow($pColumn1 = 0, $pRow1 = 1, $pColumn2 = 0, $pRow2 = 1)\n    {\n        return $this->setAutoFilter(\n            PHPExcel_Cell::stringFromColumnIndex($pColumn1) . $pRow1\n            . ':' .\n            PHPExcel_Cell::stringFromColumnIndex($pColumn2) . $pRow2\n        );\n    }\n\n    /**\n     * Remove autofilter\n     *\n     * @return PHPExcel_Worksheet\n     */\n    public function removeAutoFilter()\n    {\n        $this->_autoFilter->setRange(NULL);\n        return $this;\n    }\n\n    /**\n     * Get Freeze Pane\n     *\n     * @return string\n     */\n    public function getFreezePane()\n    {\n        return $this->_freezePane;\n    }\n\n    /**\n     * Freeze Pane\n     *\n     * @param    string        $pCell        Cell (i.e. A2)\n     *                                    Examples:\n     *                                        A2 will freeze the rows above cell A2 (i.e row 1)\n     *                                        B1 will freeze the columns to the left of cell B1 (i.e column A)\n     *                                        B2 will freeze the rows above and to the left of cell A2\n     *                                            (i.e row 1 and column A)\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function freezePane($pCell = '')\n    {\n        // Uppercase coordinate\n        $pCell = strtoupper($pCell);\n\n        if (strpos($pCell,':') === false && strpos($pCell,',') === false) {\n            $this->_freezePane = $pCell;\n        } else {\n            throw new PHPExcel_Exception('Freeze pane can not be set on a range of cells.');\n        }\n        return $this;\n    }\n\n    /**\n     * Freeze Pane by using numeric cell coordinates\n     *\n     * @param int $pColumn    Numeric column coordinate of the cell\n     * @param int $pRow        Numeric row coordinate of the cell\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function freezePaneByColumnAndRow($pColumn = 0, $pRow = 1)\n    {\n        return $this->freezePane(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);\n    }\n\n    /**\n     * Unfreeze Pane\n     *\n     * @return PHPExcel_Worksheet\n     */\n    public function unfreezePane()\n    {\n        return $this->freezePane('');\n    }\n\n    /**\n     * Insert a new row, updating all possible related data\n     *\n     * @param int $pBefore    Insert before this one\n     * @param int $pNumRows    Number of rows to insert\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function insertNewRowBefore($pBefore = 1, $pNumRows = 1) {\n        if ($pBefore >= 1) {\n            $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();\n            $objReferenceHelper->insertNewBefore('A' . $pBefore, 0, $pNumRows, $this);\n        } else {\n            throw new PHPExcel_Exception(\"Rows can only be inserted before at least row 1.\");\n        }\n        return $this;\n    }\n\n    /**\n     * Insert a new column, updating all possible related data\n     *\n     * @param int $pBefore    Insert before this one\n     * @param int $pNumCols    Number of columns to insert\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function insertNewColumnBefore($pBefore = 'A', $pNumCols = 1) {\n        if (!is_numeric($pBefore)) {\n            $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();\n            $objReferenceHelper->insertNewBefore($pBefore . '1', $pNumCols, 0, $this);\n        } else {\n            throw new PHPExcel_Exception(\"Column references should not be numeric.\");\n        }\n        return $this;\n    }\n\n    /**\n     * Insert a new column, updating all possible related data\n     *\n     * @param int $pBefore    Insert before this one (numeric column coordinate of the cell)\n     * @param int $pNumCols    Number of columns to insert\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function insertNewColumnBeforeByIndex($pBefore = 0, $pNumCols = 1) {\n        if ($pBefore >= 0) {\n            return $this->insertNewColumnBefore(PHPExcel_Cell::stringFromColumnIndex($pBefore), $pNumCols);\n        } else {\n            throw new PHPExcel_Exception(\"Columns can only be inserted before at least column A (0).\");\n        }\n    }\n\n    /**\n     * Delete a row, updating all possible related data\n     *\n     * @param int $pRow        Remove starting with this one\n     * @param int $pNumRows    Number of rows to remove\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function removeRow($pRow = 1, $pNumRows = 1) {\n        if ($pRow >= 1) {\n            $highestRow = $this->getHighestDataRow();\n            $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();\n            $objReferenceHelper->insertNewBefore('A' . ($pRow + $pNumRows), 0, -$pNumRows, $this);\n            for($r = 0; $r < $pNumRows; ++$r) {\n                $this->getCellCacheController()->removeRow($highestRow);\n                --$highestRow;\n            }\n        } else {\n            throw new PHPExcel_Exception(\"Rows to be deleted should at least start from row 1.\");\n        }\n        return $this;\n    }\n\n    /**\n     * Remove a column, updating all possible related data\n     *\n     * @param string    $pColumn     Remove starting with this one\n     * @param int       $pNumCols    Number of columns to remove\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function removeColumn($pColumn = 'A', $pNumCols = 1) {\n        if (!is_numeric($pColumn)) {\n            $highestColumn = $this->getHighestDataColumn();\n            $pColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($pColumn) - 1 + $pNumCols);\n            $objReferenceHelper = PHPExcel_ReferenceHelper::getInstance();\n            $objReferenceHelper->insertNewBefore($pColumn . '1', -$pNumCols, 0, $this);\n            for($c = 0; $c < $pNumCols; ++$c) {\n                $this->getCellCacheController()->removeColumn($highestColumn);\n                $highestColumn = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::columnIndexFromString($highestColumn) - 2);\n            }\n        } else {\n            throw new PHPExcel_Exception(\"Column references should not be numeric.\");\n        }\n        return $this;\n    }\n\n    /**\n     * Remove a column, updating all possible related data\n     *\n     * @param int $pColumn    Remove starting with this one (numeric column coordinate of the cell)\n     * @param int $pNumCols    Number of columns to remove\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function removeColumnByIndex($pColumn = 0, $pNumCols = 1) {\n        if ($pColumn >= 0) {\n            return $this->removeColumn(PHPExcel_Cell::stringFromColumnIndex($pColumn), $pNumCols);\n        } else {\n            throw new PHPExcel_Exception(\"Columns to be deleted should at least start from column 0\");\n        }\n    }\n\n    /**\n     * Show gridlines?\n     *\n     * @return boolean\n     */\n    public function getShowGridlines() {\n        return $this->_showGridlines;\n    }\n\n    /**\n     * Set show gridlines\n     *\n     * @param boolean $pValue    Show gridlines (true/false)\n     * @return PHPExcel_Worksheet\n     */\n    public function setShowGridlines($pValue = false) {\n        $this->_showGridlines = $pValue;\n        return $this;\n    }\n\n    /**\n    * Print gridlines?\n    *\n    * @return boolean\n    */\n    public function getPrintGridlines() {\n        return $this->_printGridlines;\n    }\n\n    /**\n    * Set print gridlines\n    *\n    * @param boolean $pValue Print gridlines (true/false)\n    * @return PHPExcel_Worksheet\n    */\n    public function setPrintGridlines($pValue = false) {\n        $this->_printGridlines = $pValue;\n        return $this;\n    }\n\n    /**\n    * Show row and column headers?\n    *\n    * @return boolean\n    */\n    public function getShowRowColHeaders() {\n        return $this->_showRowColHeaders;\n    }\n\n    /**\n    * Set show row and column headers\n    *\n    * @param boolean $pValue Show row and column headers (true/false)\n    * @return PHPExcel_Worksheet\n    */\n    public function setShowRowColHeaders($pValue = false) {\n        $this->_showRowColHeaders = $pValue;\n        return $this;\n    }\n\n    /**\n     * Show summary below? (Row/Column outlining)\n     *\n     * @return boolean\n     */\n    public function getShowSummaryBelow() {\n        return $this->_showSummaryBelow;\n    }\n\n    /**\n     * Set show summary below\n     *\n     * @param boolean $pValue    Show summary below (true/false)\n     * @return PHPExcel_Worksheet\n     */\n    public function setShowSummaryBelow($pValue = true) {\n        $this->_showSummaryBelow = $pValue;\n        return $this;\n    }\n\n    /**\n     * Show summary right? (Row/Column outlining)\n     *\n     * @return boolean\n     */\n    public function getShowSummaryRight() {\n        return $this->_showSummaryRight;\n    }\n\n    /**\n     * Set show summary right\n     *\n     * @param boolean $pValue    Show summary right (true/false)\n     * @return PHPExcel_Worksheet\n     */\n    public function setShowSummaryRight($pValue = true) {\n        $this->_showSummaryRight = $pValue;\n        return $this;\n    }\n\n    /**\n     * Get comments\n     *\n     * @return PHPExcel_Comment[]\n     */\n    public function getComments()\n    {\n        return $this->_comments;\n    }\n\n    /**\n     * Set comments array for the entire sheet.\n     *\n\t * @param array of PHPExcel_Comment\n     * @return PHPExcel_Worksheet\n     */\n    public function setComments($pValue = array())\n    {\n        $this->_comments = $pValue;\n\n        return $this;\n    }\n\n    /**\n     * Get comment for cell\n     *\n     * @param string $pCellCoordinate    Cell coordinate to get comment for\n     * @return PHPExcel_Comment\n     * @throws PHPExcel_Exception\n     */\n    public function getComment($pCellCoordinate = 'A1')\n    {\n        // Uppercase coordinate\n        $pCellCoordinate = strtoupper($pCellCoordinate);\n\n        if (strpos($pCellCoordinate,':') !== false || strpos($pCellCoordinate,',') !== false) {\n            throw new PHPExcel_Exception('Cell coordinate string can not be a range of cells.');\n        } else if (strpos($pCellCoordinate,'$') !== false) {\n            throw new PHPExcel_Exception('Cell coordinate string must not be absolute.');\n        } else if ($pCellCoordinate == '') {\n            throw new PHPExcel_Exception('Cell coordinate can not be zero-length string.');\n        } else {\n            // Check if we already have a comment for this cell.\n            // If not, create a new comment.\n            if (isset($this->_comments[$pCellCoordinate])) {\n                return $this->_comments[$pCellCoordinate];\n            } else {\n                $newComment = new PHPExcel_Comment();\n                $this->_comments[$pCellCoordinate] = $newComment;\n                return $newComment;\n            }\n        }\n    }\n\n    /**\n     * Get comment for cell by using numeric cell coordinates\n     *\n     * @param int $pColumn    Numeric column coordinate of the cell\n     * @param int $pRow        Numeric row coordinate of the cell\n     * @return PHPExcel_Comment\n     */\n    public function getCommentByColumnAndRow($pColumn = 0, $pRow = 1)\n    {\n        return $this->getComment(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);\n    }\n\n    /**\n     * Get selected cell\n     *\n     * @deprecated\n     * @return string\n     */\n    public function getSelectedCell()\n    {\n        return $this->getSelectedCells();\n    }\n\n    /**\n     * Get active cell\n     *\n     * @return string Example: 'A1'\n     */\n    public function getActiveCell()\n    {\n        return $this->_activeCell;\n    }\n\n    /**\n     * Get selected cells\n     *\n     * @return string\n     */\n    public function getSelectedCells()\n    {\n        return $this->_selectedCells;\n    }\n\n    /**\n     * Selected cell\n     *\n     * @param    string        $pCoordinate    Cell (i.e. A1)\n     * @return PHPExcel_Worksheet\n     */\n    public function setSelectedCell($pCoordinate = 'A1')\n    {\n        return $this->setSelectedCells($pCoordinate);\n    }\n\n    /**\n     * Select a range of cells.\n     *\n     * @param    string        $pCoordinate    Cell range, examples: 'A1', 'B2:G5', 'A:C', '3:6'\n     * @throws    PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function setSelectedCells($pCoordinate = 'A1')\n    {\n        // Uppercase coordinate\n        $pCoordinate = strtoupper($pCoordinate);\n\n        // Convert 'A' to 'A:A'\n        $pCoordinate = preg_replace('/^([A-Z]+)$/', '${1}:${1}', $pCoordinate);\n\n        // Convert '1' to '1:1'\n        $pCoordinate = preg_replace('/^([0-9]+)$/', '${1}:${1}', $pCoordinate);\n\n        // Convert 'A:C' to 'A1:C1048576'\n        $pCoordinate = preg_replace('/^([A-Z]+):([A-Z]+)$/', '${1}1:${2}1048576', $pCoordinate);\n\n        // Convert '1:3' to 'A1:XFD3'\n        $pCoordinate = preg_replace('/^([0-9]+):([0-9]+)$/', 'A${1}:XFD${2}', $pCoordinate);\n\n        if (strpos($pCoordinate,':') !== false || strpos($pCoordinate,',') !== false) {\n            list($first, ) = PHPExcel_Cell::splitRange($pCoordinate);\n            $this->_activeCell = $first[0];\n        } else {\n            $this->_activeCell = $pCoordinate;\n        }\n        $this->_selectedCells = $pCoordinate;\n        return $this;\n    }\n\n    /**\n     * Selected cell by using numeric cell coordinates\n     *\n     * @param int $pColumn Numeric column coordinate of the cell\n     * @param int $pRow Numeric row coordinate of the cell\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function setSelectedCellByColumnAndRow($pColumn = 0, $pRow = 1)\n    {\n        return $this->setSelectedCells(PHPExcel_Cell::stringFromColumnIndex($pColumn) . $pRow);\n    }\n\n    /**\n     * Get right-to-left\n     *\n     * @return boolean\n     */\n    public function getRightToLeft() {\n        return $this->_rightToLeft;\n    }\n\n    /**\n     * Set right-to-left\n     *\n     * @param boolean $value    Right-to-left true/false\n     * @return PHPExcel_Worksheet\n     */\n    public function setRightToLeft($value = false) {\n        $this->_rightToLeft = $value;\n        return $this;\n    }\n\n    /**\n     * Fill worksheet from values in array\n     *\n     * @param array $source Source array\n     * @param mixed $nullValue Value in source array that stands for blank cell\n     * @param string $startCell Insert array starting from this cell address as the top left coordinate\n     * @param boolean $strictNullComparison Apply strict comparison when testing for null values in the array\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function fromArray($source = null, $nullValue = null, $startCell = 'A1', $strictNullComparison = false) {\n        if (is_array($source)) {\n            //    Convert a 1-D array to 2-D (for ease of looping)\n            if (!is_array(end($source))) {\n                $source = array($source);\n            }\n\n            // start coordinate\n            list ($startColumn, $startRow) = PHPExcel_Cell::coordinateFromString($startCell);\n\n            // Loop through $source\n            foreach ($source as $rowData) {\n                $currentColumn = $startColumn;\n                foreach($rowData as $cellValue) {\n                    if ($strictNullComparison) {\n                        if ($cellValue !== $nullValue) {\n                            // Set cell value\n                            $this->getCell($currentColumn . $startRow)->setValue($cellValue);\n                        }\n                    } else {\n                        if ($cellValue != $nullValue) {\n                            // Set cell value\n                            $this->getCell($currentColumn . $startRow)->setValue($cellValue);\n                        }\n                    }\n                    ++$currentColumn;\n                }\n                ++$startRow;\n            }\n        } else {\n            throw new PHPExcel_Exception(\"Parameter \\$source should be an array.\");\n        }\n        return $this;\n    }\n\n    /**\n     * Create array from a range of cells\n     *\n     * @param string $pRange Range of cells (i.e. \"A1:B10\"), or just one cell (i.e. \"A1\")\n     * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist\n     * @param boolean $calculateFormulas Should formulas be calculated?\n     * @param boolean $formatData Should formatting be applied to cell values?\n     * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero\n     *                               True - Return rows and columns indexed by their actual row and column IDs\n     * @return array\n     */\n\tpublic function rangeToArray($pRange = 'A1', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) {\n        // Returnvalue\n        $returnValue = array();\n        //    Identify the range that we need to extract from the worksheet\n        list($rangeStart, $rangeEnd) = PHPExcel_Cell::rangeBoundaries($pRange);\n        $minCol = PHPExcel_Cell::stringFromColumnIndex($rangeStart[0] -1);\n        $minRow = $rangeStart[1];\n        $maxCol = PHPExcel_Cell::stringFromColumnIndex($rangeEnd[0] -1);\n        $maxRow = $rangeEnd[1];\n\n        $maxCol++;\n        // Loop through rows\n        $r = -1;\n        for ($row = $minRow; $row <= $maxRow; ++$row) {\n            $rRef = ($returnCellRef) ? $row : ++$r;\n            $c = -1;\n            // Loop through columns in the current row\n            for ($col = $minCol; $col != $maxCol; ++$col) {\n                $cRef = ($returnCellRef) ? $col : ++$c;\n                //    Using getCell() will create a new cell if it doesn't already exist. We don't want that to happen\n                //        so we test and retrieve directly against _cellCollection\n                if ($this->_cellCollection->isDataSet($col.$row)) {\n                    // Cell exists\n                    $cell = $this->_cellCollection->getCacheData($col.$row);\n                    if ($cell->getValue() !== null) {\n                        if ($cell->getValue() instanceof PHPExcel_RichText) {\n                            $returnValue[$rRef][$cRef] = $cell->getValue()->getPlainText();\n                        } else {\n                            if ($calculateFormulas) {\n                                $returnValue[$rRef][$cRef] = $cell->getCalculatedValue();\n                            } else {\n                                $returnValue[$rRef][$cRef] = $cell->getValue();\n                            }\n                        }\n\n                        if ($formatData) {\n                            $style = $this->_parent->getCellXfByIndex($cell->getXfIndex());\n                            $returnValue[$rRef][$cRef] = PHPExcel_Style_NumberFormat::toFormattedString(\n                            \t$returnValue[$rRef][$cRef],\n\t\t\t\t\t\t\t\t($style && $style->getNumberFormat()) ?\n\t\t\t\t\t\t\t\t\t$style->getNumberFormat()->getFormatCode() :\n\t\t\t\t\t\t\t\t\tPHPExcel_Style_NumberFormat::FORMAT_GENERAL\n                            );\n                        }\n                    } else {\n                        // Cell holds a NULL\n                        $returnValue[$rRef][$cRef] = $nullValue;\n                    }\n                } else {\n                    // Cell doesn't exist\n                    $returnValue[$rRef][$cRef] = $nullValue;\n                }\n            }\n        }\n\n        // Return\n        return $returnValue;\n    }\n\n\n    /**\n     * Create array from a range of cells\n     *\n     * @param  string $pNamedRange Name of the Named Range\n     * @param  mixed  $nullValue Value returned in the array entry if a cell doesn't exist\n     * @param  boolean $calculateFormulas  Should formulas be calculated?\n     * @param  boolean $formatData  Should formatting be applied to cell values?\n     * @param  boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero\n     *                                True - Return rows and columns indexed by their actual row and column IDs\n     * @return array\n     * @throws PHPExcel_Exception\n     */\n\tpublic function namedRangeToArray($pNamedRange = '', $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) {\n        $namedRange = PHPExcel_NamedRange::resolveRange($pNamedRange, $this);\n        if ($namedRange !== NULL) {\n            $pWorkSheet = $namedRange->getWorksheet();\n            $pCellRange = $namedRange->getRange();\n\n\t\t\treturn $pWorkSheet->rangeToArray(\t$pCellRange,\n\t\t\t\t\t\t\t\t\t\t\t\t$nullValue, $calculateFormulas, $formatData, $returnCellRef);\n        }\n\n        throw new PHPExcel_Exception('Named Range '.$pNamedRange.' does not exist.');\n    }\n\n\n    /**\n     * Create array from worksheet\n     *\n     * @param mixed $nullValue Value returned in the array entry if a cell doesn't exist\n     * @param boolean $calculateFormulas Should formulas be calculated?\n     * @param boolean $formatData  Should formatting be applied to cell values?\n     * @param boolean $returnCellRef False - Return a simple array of rows and columns indexed by number counting from zero\n     *                               True - Return rows and columns indexed by their actual row and column IDs\n     * @return array\n     */\n\tpublic function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) {\n        // Garbage collect...\n        $this->garbageCollect();\n\n        //    Identify the range that we need to extract from the worksheet\n        $maxCol = $this->getHighestColumn();\n        $maxRow = $this->getHighestRow();\n        // Return\n\t\treturn $this->rangeToArray(\t'A1:'.$maxCol.$maxRow,\n\t\t\t\t\t\t\t\t\t$nullValue, $calculateFormulas, $formatData, $returnCellRef);\n    }\n\n    /**\n     * Get row iterator\n     *\n     * @param   integer   $startRow   The row number at which to start iterating\n     * @param   integer   $endRow     The row number at which to stop iterating\n     *\n     * @return PHPExcel_Worksheet_RowIterator\n     */\n\tpublic function getRowIterator($startRow = 1, $endRow = null) {\n        return new PHPExcel_Worksheet_RowIterator($this, $startRow, $endRow);\n    }\n\n    /**\n     * Get column iterator\n     *\n     * @param   string   $startColumn The column address at which to start iterating\n     * @param   string   $endColumn   The column address at which to stop iterating\n     *\n     * @return PHPExcel_Worksheet_ColumnIterator\n     */\n\tpublic function getColumnIterator($startColumn = 'A', $endColumn = null) {\n        return new PHPExcel_Worksheet_ColumnIterator($this, $startColumn, $endColumn);\n    }\n\n    /**\n     * Run PHPExcel garabage collector.\n     *\n     * @return PHPExcel_Worksheet\n     */\n\tpublic function garbageCollect() {\n        // Flush cache\n        $this->_cellCollection->getCacheData('A1');\n        // Build a reference table from images\n//        $imageCoordinates = array();\n//        $iterator = $this->getDrawingCollection()->getIterator();\n//        while ($iterator->valid()) {\n//            $imageCoordinates[$iterator->current()->getCoordinates()] = true;\n//\n//            $iterator->next();\n//        }\n//\n        // Lookup highest column and highest row if cells are cleaned\n        $colRow = $this->_cellCollection->getHighestRowAndColumn();\n        $highestRow = $colRow['row'];\n        $highestColumn = PHPExcel_Cell::columnIndexFromString($colRow['column']);\n\n        // Loop through column dimensions\n        foreach ($this->_columnDimensions as $dimension) {\n            $highestColumn = max($highestColumn,PHPExcel_Cell::columnIndexFromString($dimension->getColumnIndex()));\n        }\n\n        // Loop through row dimensions\n        foreach ($this->_rowDimensions as $dimension) {\n            $highestRow = max($highestRow,$dimension->getRowIndex());\n        }\n\n        // Cache values\n        if ($highestColumn < 0) {\n            $this->_cachedHighestColumn = 'A';\n        } else {\n            $this->_cachedHighestColumn = PHPExcel_Cell::stringFromColumnIndex(--$highestColumn);\n        }\n        $this->_cachedHighestRow = $highestRow;\n\n        // Return\n        return $this;\n    }\n\n    /**\n     * Get hash code\n     *\n     * @return string    Hash code\n     */\n\tpublic function getHashCode() {\n        if ($this->_dirty) {\n            $this->_hash = md5( $this->_title .\n                                $this->_autoFilter .\n                                ($this->_protection->isProtectionEnabled() ? 't' : 'f') .\n                                __CLASS__\n                              );\n            $this->_dirty = false;\n        }\n        return $this->_hash;\n    }\n\n    /**\n     * Extract worksheet title from range.\n     *\n     * Example: extractSheetTitle(\"testSheet!A1\") ==> 'A1'\n     * Example: extractSheetTitle(\"'testSheet 1'!A1\", true) ==> array('testSheet 1', 'A1');\n     *\n     * @param string $pRange    Range to extract title from\n     * @param bool $returnRange    Return range? (see example)\n     * @return mixed\n     */\n\tpublic static function extractSheetTitle($pRange, $returnRange = false) {\n        // Sheet title included?\n        if (($sep = strpos($pRange, '!')) === false) {\n            return '';\n        }\n\n        if ($returnRange) {\n            return array( trim(substr($pRange, 0, $sep),\"'\"),\n                          substr($pRange, $sep + 1)\n                        );\n        }\n\n        return substr($pRange, $sep + 1);\n    }\n\n    /**\n     * Get hyperlink\n     *\n     * @param string $pCellCoordinate    Cell coordinate to get hyperlink for\n     */\n    public function getHyperlink($pCellCoordinate = 'A1')\n    {\n        // return hyperlink if we already have one\n        if (isset($this->_hyperlinkCollection[$pCellCoordinate])) {\n            return $this->_hyperlinkCollection[$pCellCoordinate];\n        }\n\n        // else create hyperlink\n        $this->_hyperlinkCollection[$pCellCoordinate] = new PHPExcel_Cell_Hyperlink();\n        return $this->_hyperlinkCollection[$pCellCoordinate];\n    }\n\n    /**\n     * Set hyperlnk\n     *\n     * @param string $pCellCoordinate    Cell coordinate to insert hyperlink\n     * @param    PHPExcel_Cell_Hyperlink    $pHyperlink\n     * @return PHPExcel_Worksheet\n     */\n    public function setHyperlink($pCellCoordinate = 'A1', PHPExcel_Cell_Hyperlink $pHyperlink = null)\n    {\n        if ($pHyperlink === null) {\n            unset($this->_hyperlinkCollection[$pCellCoordinate]);\n        } else {\n            $this->_hyperlinkCollection[$pCellCoordinate] = $pHyperlink;\n        }\n        return $this;\n    }\n\n    /**\n     * Hyperlink at a specific coordinate exists?\n     *\n     * @param string $pCoordinate\n     * @return boolean\n     */\n    public function hyperlinkExists($pCoordinate = 'A1')\n    {\n        return isset($this->_hyperlinkCollection[$pCoordinate]);\n    }\n\n    /**\n     * Get collection of hyperlinks\n     *\n     * @return PHPExcel_Cell_Hyperlink[]\n     */\n    public function getHyperlinkCollection()\n    {\n        return $this->_hyperlinkCollection;\n    }\n\n    /**\n     * Get data validation\n     *\n     * @param string $pCellCoordinate Cell coordinate to get data validation for\n     */\n    public function getDataValidation($pCellCoordinate = 'A1')\n    {\n        // return data validation if we already have one\n        if (isset($this->_dataValidationCollection[$pCellCoordinate])) {\n            return $this->_dataValidationCollection[$pCellCoordinate];\n        }\n\n        // else create data validation\n        $this->_dataValidationCollection[$pCellCoordinate] = new PHPExcel_Cell_DataValidation();\n        return $this->_dataValidationCollection[$pCellCoordinate];\n    }\n\n    /**\n     * Set data validation\n     *\n     * @param string $pCellCoordinate    Cell coordinate to insert data validation\n     * @param    PHPExcel_Cell_DataValidation    $pDataValidation\n     * @return PHPExcel_Worksheet\n     */\n    public function setDataValidation($pCellCoordinate = 'A1', PHPExcel_Cell_DataValidation $pDataValidation = null)\n    {\n        if ($pDataValidation === null) {\n            unset($this->_dataValidationCollection[$pCellCoordinate]);\n        } else {\n            $this->_dataValidationCollection[$pCellCoordinate] = $pDataValidation;\n        }\n        return $this;\n    }\n\n    /**\n     * Data validation at a specific coordinate exists?\n     *\n     * @param string $pCoordinate\n     * @return boolean\n     */\n    public function dataValidationExists($pCoordinate = 'A1')\n    {\n        return isset($this->_dataValidationCollection[$pCoordinate]);\n    }\n\n    /**\n     * Get collection of data validations\n     *\n     * @return PHPExcel_Cell_DataValidation[]\n     */\n    public function getDataValidationCollection()\n    {\n        return $this->_dataValidationCollection;\n    }\n\n    /**\n     * Accepts a range, returning it as a range that falls within the current highest row and column of the worksheet\n     *\n     * @param string $range\n     * @return string Adjusted range value\n     */\n\tpublic function shrinkRangeToFit($range) {\n        $maxCol = $this->getHighestColumn();\n        $maxRow = $this->getHighestRow();\n        $maxCol = PHPExcel_Cell::columnIndexFromString($maxCol);\n\n        $rangeBlocks = explode(' ',$range);\n        foreach ($rangeBlocks as &$rangeSet) {\n            $rangeBoundaries = PHPExcel_Cell::getRangeBoundaries($rangeSet);\n\n            if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[0][0]) > $maxCol) { $rangeBoundaries[0][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); }\n            if ($rangeBoundaries[0][1] > $maxRow) { $rangeBoundaries[0][1] = $maxRow; }\n            if (PHPExcel_Cell::columnIndexFromString($rangeBoundaries[1][0]) > $maxCol) { $rangeBoundaries[1][0] = PHPExcel_Cell::stringFromColumnIndex($maxCol); }\n            if ($rangeBoundaries[1][1] > $maxRow) { $rangeBoundaries[1][1] = $maxRow; }\n            $rangeSet = $rangeBoundaries[0][0].$rangeBoundaries[0][1].':'.$rangeBoundaries[1][0].$rangeBoundaries[1][1];\n        }\n        unset($rangeSet);\n        $stRange = implode(' ',$rangeBlocks);\n\n        return $stRange;\n    }\n\n    /**\n     * Get tab color\n     *\n     * @return PHPExcel_Style_Color\n     */\n    public function getTabColor()\n    {\n        if ($this->_tabColor === NULL)\n            $this->_tabColor = new PHPExcel_Style_Color();\n\n        return $this->_tabColor;\n    }\n\n    /**\n     * Reset tab color\n     *\n     * @return PHPExcel_Worksheet\n     */\n    public function resetTabColor()\n    {\n        $this->_tabColor = null;\n        unset($this->_tabColor);\n\n        return $this;\n    }\n\n    /**\n     * Tab color set?\n     *\n     * @return boolean\n     */\n    public function isTabColorSet()\n    {\n        return ($this->_tabColor !== NULL);\n    }\n\n    /**\n     * Copy worksheet (!= clone!)\n     *\n     * @return PHPExcel_Worksheet\n     */\n\tpublic function copy() {\n        $copied = clone $this;\n\n        return $copied;\n    }\n\n    /**\n     * Implement PHP __clone to create a deep clone, not just a shallow copy.\n     */\n\tpublic function __clone() {\n        foreach ($this as $key => $val) {\n            if ($key == '_parent') {\n                continue;\n            }\n\n            if (is_object($val) || (is_array($val))) {\n                if ($key == '_cellCollection') {\n                    $newCollection = clone $this->_cellCollection;\n                    $newCollection->copyCellCollection($this);\n                    $this->_cellCollection = $newCollection;\n                } elseif ($key == '_drawingCollection') {\n                    $newCollection = clone $this->_drawingCollection;\n                    $this->_drawingCollection = $newCollection;\n                } elseif (($key == '_autoFilter') && ($this->_autoFilter instanceof PHPExcel_Worksheet_AutoFilter)) {\n                    $newAutoFilter = clone $this->_autoFilter;\n                    $this->_autoFilter = $newAutoFilter;\n                    $this->_autoFilter->setParent($this);\n                } else {\n                    $this->{$key} = unserialize(serialize($val));\n                }\n            }\n        }\n    }\n/**\n\t * Define the code name of the sheet\n\t *\n\t * @param null|string Same rule as Title minus space not allowed (but, like Excel, change silently space to underscore)\n\t * @return objWorksheet\n\t * @throws PHPExcel_Exception\n\t*/\n\tpublic function setCodeName($pValue=null){\n\t\t// Is this a 'rename' or not?\n\t\tif ($this->getCodeName() == $pValue) {\n\t\t\treturn $this;\n\t\t}\n\t\t$pValue = str_replace(' ', '_', $pValue);//Excel does this automatically without flinching, we are doing the same\n\t\t// Syntax check\n        // throw an exception if not valid\n\t\tself::_checkSheetCodeName($pValue);\n\n\t\t// We use the same code that setTitle to find a valid codeName else not using a space (Excel don't like) but a '_'\n\t\t\n        if ($this->getParent()) {\n\t\t\t// Is there already such sheet name?\n\t\t\tif ($this->getParent()->sheetCodeNameExists($pValue)) {\n\t\t\t\t// Use name, but append with lowest possible integer\n\n\t\t\t\tif (PHPExcel_Shared_String::CountCharacters($pValue) > 29) {\n\t\t\t\t\t$pValue = PHPExcel_Shared_String::Substring($pValue,0,29);\n\t\t\t\t}\n\t\t\t\t$i = 1;\n\t\t\t\twhile ($this->getParent()->sheetCodeNameExists($pValue . '_' . $i)) {\n\t\t\t\t\t++$i;\n\t\t\t\t\tif ($i == 10) {\n\t\t\t\t\t\tif (PHPExcel_Shared_String::CountCharacters($pValue) > 28) {\n\t\t\t\t\t\t\t$pValue = PHPExcel_Shared_String::Substring($pValue,0,28);\n\t\t\t\t\t\t}\n\t\t\t\t\t} elseif ($i == 100) {\n\t\t\t\t\t\tif (PHPExcel_Shared_String::CountCharacters($pValue) > 27) {\n\t\t\t\t\t\t\t$pValue = PHPExcel_Shared_String::Substring($pValue,0,27);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t$pValue = $pValue . '_' . $i;// ok, we have a valid name\n\t\t\t\t//codeName is'nt used in formula : no need to call for an update\n\t\t\t\t//return $this->setTitle($altTitle,$updateFormulaCellReferences);\n\t\t\t}\n\t\t}\n\n\t\t$this->_codeName=$pValue;\n\t\treturn $this;\n\t}\n\t/**\n\t * Return the code name of the sheet\n\t *\n\t * @return null|string\n\t*/\n\tpublic function getCodeName(){\n\t\treturn $this->_codeName;\n\t}\n\t/**\n\t * Sheet has a code name ?\n\t * @return boolean\n\t*/\n\tpublic function hasCodeName(){\n\t\treturn !(is_null($this->_codeName));\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/WorksheetIterator.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_WorksheetIterator\n *\n * Used to iterate worksheets in PHPExcel\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_WorksheetIterator implements Iterator\n{\n    /**\n     * Spreadsheet to iterate\n     *\n     * @var PHPExcel\n     */\n    private $_subject;\n\n    /**\n     * Current iterator position\n     *\n     * @var int\n     */\n    private $_position = 0;\n\n    /**\n     * Create a new worksheet iterator\n     *\n     * @param PHPExcel         $subject\n     */\n    public function __construct(PHPExcel $subject = null)\n    {\n        // Set subject\n        $this->_subject = $subject;\n    }\n\n    /**\n     * Destructor\n     */\n    public function __destruct()\n    {\n        unset($this->_subject);\n    }\n\n    /**\n     * Rewind iterator\n     */\n    public function rewind()\n    {\n        $this->_position = 0;\n    }\n\n    /**\n     * Current PHPExcel_Worksheet\n     *\n     * @return PHPExcel_Worksheet\n     */\n    public function current()\n    {\n        return $this->_subject->getSheet($this->_position);\n    }\n\n    /**\n     * Current key\n     *\n     * @return int\n     */\n    public function key()\n    {\n        return $this->_position;\n    }\n\n    /**\n     * Next value\n     */\n    public function next()\n    {\n        ++$this->_position;\n    }\n\n    /**\n     * More PHPExcel_Worksheet instances available?\n     *\n     * @return boolean\n     */\n    public function valid()\n    {\n        return $this->_position < $this->_subject->getSheetCount();\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Abstract.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Abstract\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nabstract class PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter\n{\n\t/**\n\t * Write charts that are defined in the workbook?\n\t * Identifies whether the Writer should write definitions for any charts that exist in the PHPExcel object;\n\t *\n\t * @var\tboolean\n\t */\n\tprotected $_includeCharts = FALSE;\n\n\t/**\n\t * Pre-calculate formulas\n\t * Forces PHPExcel to recalculate all formulae in a workbook when saving, so that the pre-calculated values are\n\t *    immediately available to MS Excel or other office spreadsheet viewer when opening the file\n\t *\n\t * @var boolean\n\t */\n\tprotected $_preCalculateFormulas = TRUE;\n\n\t/**\n\t * Use disk caching where possible?\n\t *\n\t * @var boolean\n\t */\n\tprotected $_useDiskCaching = FALSE;\n\n\t/**\n\t * Disk caching directory\n\t *\n\t * @var string\n\t */\n\tprotected $_diskCachingDirectory\t= './';\n\n\t/**\n\t * Write charts in workbook?\n\t *\t\tIf this is true, then the Writer will write definitions for any charts that exist in the PHPExcel object.\n\t *\t\tIf false (the default) it will ignore any charts defined in the PHPExcel object.\n\t *\n\t * @return\tboolean\n\t */\n\tpublic function getIncludeCharts() {\n\t\treturn $this->_includeCharts;\n\t}\n\n\t/**\n\t * Set write charts in workbook\n\t *\t\tSet to true, to advise the Writer to include any charts that exist in the PHPExcel object.\n\t *\t\tSet to false (the default) to ignore charts.\n\t *\n\t * @param\tboolean\t$pValue\n\t * @return\tPHPExcel_Writer_IWriter\n\t */\n\tpublic function setIncludeCharts($pValue = FALSE) {\n\t\t$this->_includeCharts = (boolean) $pValue;\n\t\treturn $this;\n\t}\n\n    /**\n     * Get Pre-Calculate Formulas flag\n\t *     If this is true (the default), then the writer will recalculate all formulae in a workbook when saving,\n\t *        so that the pre-calculated values are immediately available to MS Excel or other office spreadsheet\n\t *        viewer when opening the file\n\t *     If false, then formulae are not calculated on save. This is faster for saving in PHPExcel, but slower\n\t *        when opening the resulting file in MS Excel, because Excel has to recalculate the formulae itself\n     *\n     * @return boolean\n     */\n    public function getPreCalculateFormulas() {\n    \treturn $this->_preCalculateFormulas;\n    }\n\n    /**\n     * Set Pre-Calculate Formulas\n\t *\t\tSet to true (the default) to advise the Writer to calculate all formulae on save\n\t *\t\tSet to false to prevent precalculation of formulae on save.\n     *\n     * @param boolean $pValue\tPre-Calculate Formulas?\n\t * @return\tPHPExcel_Writer_IWriter\n     */\n    public function setPreCalculateFormulas($pValue = TRUE) {\n    \t$this->_preCalculateFormulas = (boolean) $pValue;\n\t\treturn $this;\n    }\n\n\t/**\n\t * Get use disk caching where possible?\n\t *\n\t * @return boolean\n\t */\n\tpublic function getUseDiskCaching() {\n\t\treturn $this->_useDiskCaching;\n\t}\n\n\t/**\n\t * Set use disk caching where possible?\n\t *\n\t * @param \tboolean \t$pValue\n\t * @param\tstring\t\t$pDirectory\t\tDisk caching directory\n\t * @throws\tPHPExcel_Writer_Exception\twhen directory does not exist\n\t * @return PHPExcel_Writer_Excel2007\n\t */\n\tpublic function setUseDiskCaching($pValue = FALSE, $pDirectory = NULL) {\n\t\t$this->_useDiskCaching = $pValue;\n\n\t\tif ($pDirectory !== NULL) {\n    \t\tif (is_dir($pDirectory)) {\n    \t\t\t$this->_diskCachingDirectory = $pDirectory;\n    \t\t} else {\n    \t\t\tthrow new PHPExcel_Writer_Exception(\"Directory does not exist: $pDirectory\");\n    \t\t}\n\t\t}\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get disk caching directory\n\t *\n\t * @return string\n\t */\n\tpublic function getDiskCachingDirectory() {\n\t\treturn $this->_diskCachingDirectory;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/CSV.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Writer_CSV\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_CSV\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Writer_CSV\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_CSV extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter {\n\t/**\n\t * PHPExcel object\n\t *\n\t * @var PHPExcel\n\t */\n\tprivate $_phpExcel;\n\n\t/**\n\t * Delimiter\n\t *\n\t * @var string\n\t */\n\tprivate $_delimiter\t= ',';\n\n\t/**\n\t * Enclosure\n\t *\n\t * @var string\n\t */\n\tprivate $_enclosure\t= '\"';\n\n\t/**\n\t * Line ending\n\t *\n\t * @var string\n\t */\n\tprivate $_lineEnding\t= PHP_EOL;\n\n\t/**\n\t * Sheet index to write\n\t *\n\t * @var int\n\t */\n\tprivate $_sheetIndex\t= 0;\n\n\t/**\n\t * Whether to write a BOM (for UTF8).\n\t *\n\t * @var boolean\n\t */\n\tprivate $_useBOM = false;\n\n\t/**\n\t * Whether to write a fully Excel compatible CSV file.\n\t *\n\t * @var boolean\n\t */\n\tprivate $_excelCompatibility = false;\n\n\t/**\n\t * Create a new PHPExcel_Writer_CSV\n\t *\n\t * @param\tPHPExcel\t$phpExcel\tPHPExcel object\n\t */\n\tpublic function __construct(PHPExcel $phpExcel) {\n\t\t$this->_phpExcel\t= $phpExcel;\n\t}\n\n\t/**\n\t * Save PHPExcel to file\n\t *\n\t * @param\tstring\t\t$pFilename\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tpublic function save($pFilename = null) {\n\t\t// Fetch sheet\n\t\t$sheet = $this->_phpExcel->getSheet($this->_sheetIndex);\n\n\t\t$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog();\n\t\tPHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE);\n\t\t$saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType();\n\t\tPHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE);\n\n\t\t// Open file\n\t\t$fileHandle = fopen($pFilename, 'wb+');\n\t\tif ($fileHandle === false) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Could not open file $pFilename for writing.\");\n\t\t}\n\n\t\tif ($this->_excelCompatibility) {\n\t\t\tfwrite($fileHandle, \"\\xEF\\xBB\\xBF\");\t//\tEnforce UTF-8 BOM Header\n\t\t\t$this->setEnclosure('\"');\t\t\t\t//\tSet enclosure to \"\n\t\t\t$this->setDelimiter(\";\");\t\t\t    //\tSet delimiter to a semi-colon\n            $this->setLineEnding(\"\\r\\n\");\n\t\t\tfwrite($fileHandle, 'sep=' . $this->getDelimiter() . $this->_lineEnding);\n\t\t} elseif ($this->_useBOM) {\n\t\t\t// Write the UTF-8 BOM code if required\n\t\t\tfwrite($fileHandle, \"\\xEF\\xBB\\xBF\");\n\t\t}\n\n\t\t//\tIdentify the range that we need to extract from the worksheet\n\t\t$maxCol = $sheet->getHighestDataColumn();\n\t\t$maxRow = $sheet->getHighestDataRow();\n\n\t\t// Write rows to file\n\t\tfor($row = 1; $row <= $maxRow; ++$row) {\n\t\t\t// Convert the row to an array...\n\t\t\t$cellsArray = $sheet->rangeToArray('A'.$row.':'.$maxCol.$row,'', $this->_preCalculateFormulas);\n\t\t\t// ... and write to the file\n\t\t\t$this->_writeLine($fileHandle, $cellsArray[0]);\n\t\t}\n\n\t\t// Close file\n\t\tfclose($fileHandle);\n\n\t\tPHPExcel_Calculation::setArrayReturnType($saveArrayReturnType);\n\t\tPHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog);\n\t}\n\n\t/**\n\t * Get delimiter\n\t *\n\t * @return string\n\t */\n\tpublic function getDelimiter() {\n\t\treturn $this->_delimiter;\n\t}\n\n\t/**\n\t * Set delimiter\n\t *\n\t * @param\tstring\t$pValue\t\tDelimiter, defaults to ,\n\t * @return PHPExcel_Writer_CSV\n\t */\n\tpublic function setDelimiter($pValue = ',') {\n\t\t$this->_delimiter = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get enclosure\n\t *\n\t * @return string\n\t */\n\tpublic function getEnclosure() {\n\t\treturn $this->_enclosure;\n\t}\n\n\t/**\n\t * Set enclosure\n\t *\n\t * @param\tstring\t$pValue\t\tEnclosure, defaults to \"\n\t * @return PHPExcel_Writer_CSV\n\t */\n\tpublic function setEnclosure($pValue = '\"') {\n\t\tif ($pValue == '') {\n\t\t\t$pValue = null;\n\t\t}\n\t\t$this->_enclosure = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get line ending\n\t *\n\t * @return string\n\t */\n\tpublic function getLineEnding() {\n\t\treturn $this->_lineEnding;\n\t}\n\n\t/**\n\t * Set line ending\n\t *\n\t * @param\tstring\t$pValue\t\tLine ending, defaults to OS line ending (PHP_EOL)\n\t * @return PHPExcel_Writer_CSV\n\t */\n\tpublic function setLineEnding($pValue = PHP_EOL) {\n\t\t$this->_lineEnding = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get whether BOM should be used\n\t *\n\t * @return boolean\n\t */\n\tpublic function getUseBOM() {\n\t\treturn $this->_useBOM;\n\t}\n\n\t/**\n\t * Set whether BOM should be used\n\t *\n\t * @param\tboolean\t$pValue\t\tUse UTF-8 byte-order mark? Defaults to false\n\t * @return PHPExcel_Writer_CSV\n\t */\n\tpublic function setUseBOM($pValue = false) {\n\t\t$this->_useBOM = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get whether the file should be saved with full Excel Compatibility\n\t *\n\t * @return boolean\n\t */\n\tpublic function getExcelCompatibility() {\n\t\treturn $this->_excelCompatibility;\n\t}\n\n\t/**\n\t * Set whether the file should be saved with full Excel Compatibility\n\t *\n\t * @param\tboolean\t$pValue\t\tSet the file to be written as a fully Excel compatible csv file\n\t *\t\t\t\t\t\t\t\tNote that this overrides other settings such as useBOM, enclosure and delimiter\n\t * @return PHPExcel_Writer_CSV\n\t */\n\tpublic function setExcelCompatibility($pValue = false) {\n\t\t$this->_excelCompatibility = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get sheet index\n\t *\n\t * @return int\n\t */\n\tpublic function getSheetIndex() {\n\t\treturn $this->_sheetIndex;\n\t}\n\n\t/**\n\t * Set sheet index\n\t *\n\t * @param\tint\t\t$pValue\t\tSheet index\n\t * @return PHPExcel_Writer_CSV\n\t */\n\tpublic function setSheetIndex($pValue = 0) {\n\t\t$this->_sheetIndex = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Write line to CSV file\n\t *\n\t * @param\tmixed\t$pFileHandle\tPHP filehandle\n\t * @param\tarray\t$pValues\t\tArray containing values in a row\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeLine($pFileHandle = null, $pValues = null) {\n\t\tif (is_array($pValues)) {\n\t\t\t// No leading delimiter\n\t\t\t$writeDelimiter = false;\n\n\t\t\t// Build the line\n\t\t\t$line = '';\n\n\t\t\tforeach ($pValues as $element) {\n\t\t\t\t// Escape enclosures\n\t\t\t\t$element = str_replace($this->_enclosure, $this->_enclosure . $this->_enclosure, $element);\n\n\t\t\t\t// Add delimiter\n\t\t\t\tif ($writeDelimiter) {\n\t\t\t\t\t$line .= $this->_delimiter;\n\t\t\t\t} else {\n\t\t\t\t\t$writeDelimiter = true;\n\t\t\t\t}\n\n\t\t\t\t// Add enclosed string\n\t\t\t\t$line .= $this->_enclosure . $element . $this->_enclosure;\n\t\t\t}\n\n\t\t\t// Add line ending\n\t\t\t$line .= $this->_lineEnding;\n\n\t\t\t// Write to file\n            fwrite($pFileHandle, $line);\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Invalid data row passed to CSV writer.\");\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Chart.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/**\n * PHPExcel_Writer_Excel2007_Chart\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007_Chart extends\n  PHPExcel_Writer_Excel2007_WriterPart {\n\n  /**\n   * Write charts to XML format\n   *\n   * @param  PHPExcel_Chart $pChart\n   *\n   * @return  string            XML Output\n   * @throws  PHPExcel_Writer_Exception\n   */\n  public function writeChart(PHPExcel_Chart $pChart = NULL) {\n    // Create XML writer\n    $objWriter = NULL;\n    if ($this->getParentWriter()\n        ->getUseDiskCaching()\n    ) {\n      $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()\n          ->getDiskCachingDirectory());\n    } else {\n      $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n    }\n    //\tEnsure that data series values are up-to-date before we save\n    $pChart->refresh();\n\n    // XML header\n    $objWriter->startDocument('1.0', 'UTF-8', 'yes');\n\n    // c:chartSpace\n    $objWriter->startElement('c:chartSpace');\n    $objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');\n    $objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');\n    $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');\n\n    $objWriter->startElement('c:date1904');\n    $objWriter->writeAttribute('val', 0);\n    $objWriter->endElement();\n    $objWriter->startElement('c:lang');\n    $objWriter->writeAttribute('val', \"en-GB\");\n    $objWriter->endElement();\n    $objWriter->startElement('c:roundedCorners');\n    $objWriter->writeAttribute('val', 0);\n    $objWriter->endElement();\n\n    $this->_writeAlternateContent($objWriter);\n\n    $objWriter->startElement('c:chart');\n\n    $this->_writeTitle($pChart->getTitle(), $objWriter);\n\n    $objWriter->startElement('c:autoTitleDeleted');\n    $objWriter->writeAttribute('val', 0);\n    $objWriter->endElement();\n\n    $this->_writePlotArea(\n        $pChart->getPlotArea(),\n        $pChart->getXAxisLabel(),\n        $pChart->getYAxisLabel(),\n        $objWriter,\n        $pChart->getWorksheet(),\n        $pChart->getChartAxisX(),\n        $pChart->getChartAxisY(),\n        $pChart->getMajorGridlines(),\n        $pChart->getMinorGridlines()\n    );\n\n    $this->_writeLegend($pChart->getLegend(), $objWriter);\n\n    $objWriter->startElement('c:plotVisOnly');\n    $objWriter->writeAttribute('val', 1);\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:dispBlanksAs');\n    $objWriter->writeAttribute('val', \"gap\");\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:showDLblsOverMax');\n    $objWriter->writeAttribute('val', 0);\n    $objWriter->endElement();\n\n    $objWriter->endElement();\n\n    $this->_writePrintSettings($objWriter);\n\n    $objWriter->endElement();\n\n    // Return\n    return $objWriter->getData();\n  }\n\n  /**\n   * Write Chart Title\n   *\n   * @param  PHPExcel_Chart_Title $title\n   * @param  PHPExcel_Shared_XMLWriter $objWriter XML Writer\n   *\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private function _writeTitle(PHPExcel_Chart_Title $title = NULL, $objWriter) {\n    if (is_null($title)) {\n      return;\n    }\n\n    $objWriter->startElement('c:title');\n    $objWriter->startElement('c:tx');\n    $objWriter->startElement('c:rich');\n\n    $objWriter->startElement('a:bodyPr');\n    $objWriter->endElement();\n\n    $objWriter->startElement('a:lstStyle');\n    $objWriter->endElement();\n\n    $objWriter->startElement('a:p');\n\n    $caption = $title->getCaption();\n    if ((is_array($caption)) && (count($caption) > 0)) {\n      $caption = $caption[0];\n    }\n    $this->getParentWriter()\n        ->getWriterPart('stringtable')\n        ->writeRichTextForCharts($objWriter, $caption, 'a');\n\n    $objWriter->endElement();\n    $objWriter->endElement();\n    $objWriter->endElement();\n\n    $layout = $title->getLayout();\n    $this->_writeLayout($layout, $objWriter);\n\n    $objWriter->startElement('c:overlay');\n    $objWriter->writeAttribute('val', 0);\n    $objWriter->endElement();\n\n    $objWriter->endElement();\n  }\n\n  /**\n   * Write Chart Legend\n   *\n   * @param  PHPExcel_Chart_Legend $legend\n   * @param  PHPExcel_Shared_XMLWriter $objWriter XML Writer\n   *\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private function _writeLegend(PHPExcel_Chart_Legend $legend = NULL, $objWriter) {\n    if (is_null($legend)) {\n      return;\n    }\n\n    $objWriter->startElement('c:legend');\n\n    $objWriter->startElement('c:legendPos');\n    $objWriter->writeAttribute('val', $legend->getPosition());\n    $objWriter->endElement();\n\n    $layout = $legend->getLayout();\n    $this->_writeLayout($layout, $objWriter);\n\n    $objWriter->startElement('c:overlay');\n    $objWriter->writeAttribute('val', ($legend->getOverlay()) ? '1' : '0');\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:txPr');\n    $objWriter->startElement('a:bodyPr');\n    $objWriter->endElement();\n\n    $objWriter->startElement('a:lstStyle');\n    $objWriter->endElement();\n\n    $objWriter->startElement('a:p');\n    $objWriter->startElement('a:pPr');\n    $objWriter->writeAttribute('rtl', 0);\n\n    $objWriter->startElement('a:defRPr');\n    $objWriter->endElement();\n    $objWriter->endElement();\n\n    $objWriter->startElement('a:endParaRPr');\n    $objWriter->writeAttribute('lang', \"en-US\");\n    $objWriter->endElement();\n\n    $objWriter->endElement();\n    $objWriter->endElement();\n\n    $objWriter->endElement();\n  }\n\n  /**\n   * Write Chart Plot Area\n   *\n   * @param  PHPExcel_Chart_PlotArea $plotArea\n   * @param  PHPExcel_Chart_Title $xAxisLabel\n   * @param  PHPExcel_Chart_Title $yAxisLabel\n   * @param  PHPExcel_Chart_Axis $xAxis\n   * @param  PHPExcel_Chart_Axis $yAxis\n   * @param  PHPExcel_Shared_XMLWriter $objWriter XML Writer\n   *\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private function _writePlotArea(PHPExcel_Chart_PlotArea $plotArea,\n      PHPExcel_Chart_Title $xAxisLabel = NULL,\n      PHPExcel_Chart_Title $yAxisLabel = NULL,\n      $objWriter,\n      PHPExcel_Worksheet $pSheet,\n      PHPExcel_Chart_Axis $xAxis,\n      PHPExcel_Chart_Axis $yAxis,\n      PHPExcel_Chart_GridLines $majorGridlines,\n      PHPExcel_Chart_GridLines $minorGridlines\n  ) {\n    if (is_null($plotArea)) {\n      return;\n    }\n\n    $id1 = $id2 = 0;\n    $this->_seriesIndex = 0;\n    $objWriter->startElement('c:plotArea');\n\n    $layout = $plotArea->getLayout();\n\n    $this->_writeLayout($layout, $objWriter);\n\n    $chartTypes = self::_getChartType($plotArea);\n    $catIsMultiLevelSeries = $valIsMultiLevelSeries = FALSE;\n    $plotGroupingType = '';\n    foreach ($chartTypes as $chartType) {\n      $objWriter->startElement('c:' . $chartType);\n\n      $groupCount = $plotArea->getPlotGroupCount();\n      for ($i = 0; $i < $groupCount; ++$i) {\n        $plotGroup = $plotArea->getPlotGroupByIndex($i);\n        $groupType = $plotGroup->getPlotType();\n        if ($groupType == $chartType) {\n\n          $plotStyle = $plotGroup->getPlotStyle();\n          if ($groupType === PHPExcel_Chart_DataSeries::TYPE_RADARCHART) {\n            $objWriter->startElement('c:radarStyle');\n            $objWriter->writeAttribute('val', $plotStyle);\n            $objWriter->endElement();\n          } elseif ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART) {\n            $objWriter->startElement('c:scatterStyle');\n            $objWriter->writeAttribute('val', $plotStyle);\n            $objWriter->endElement();\n          }\n\n          $this->_writePlotGroup($plotGroup, $chartType, $objWriter, $catIsMultiLevelSeries, $valIsMultiLevelSeries, $plotGroupingType, $pSheet);\n        }\n      }\n\n      $this->_writeDataLbls($objWriter, $layout);\n\n      if ($chartType === PHPExcel_Chart_DataSeries::TYPE_LINECHART) {\n        //\tLine only, Line3D can't be smoothed\n\n        $objWriter->startElement('c:smooth');\n        $objWriter->writeAttribute('val', (integer) $plotGroup->getSmoothLine());\n        $objWriter->endElement();\n      } elseif (($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) ||\n          ($chartType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)\n      ) {\n\n        $objWriter->startElement('c:gapWidth');\n        $objWriter->writeAttribute('val', 150);\n        $objWriter->endElement();\n\n        if ($plotGroupingType == 'percentStacked' ||\n            $plotGroupingType == 'stacked'\n        ) {\n\n          $objWriter->startElement('c:overlap');\n          $objWriter->writeAttribute('val', 100);\n          $objWriter->endElement();\n        }\n      } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) {\n\n        $objWriter->startElement('c:bubbleScale');\n        $objWriter->writeAttribute('val', 25);\n        $objWriter->endElement();\n\n        $objWriter->startElement('c:showNegBubbles');\n        $objWriter->writeAttribute('val', 0);\n        $objWriter->endElement();\n      } elseif ($chartType === PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) {\n\n        $objWriter->startElement('c:hiLowLines');\n        $objWriter->endElement();\n\n        $objWriter->startElement('c:upDownBars');\n\n        $objWriter->startElement('c:gapWidth');\n        $objWriter->writeAttribute('val', 300);\n        $objWriter->endElement();\n\n        $objWriter->startElement('c:upBars');\n        $objWriter->endElement();\n\n        $objWriter->startElement('c:downBars');\n        $objWriter->endElement();\n\n        $objWriter->endElement();\n      }\n\n      //\tGenerate 2 unique numbers to use for axId values\n      //\t\t\t\t\t$id1 = $id2 = rand(10000000,99999999);\n      //\t\t\t\t\tdo {\n      //\t\t\t\t\t\t$id2 = rand(10000000,99999999);\n      //\t\t\t\t\t} while ($id1 == $id2);\n      $id1 = '75091328';\n      $id2 = '75089408';\n\n      if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) &&\n          ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) &&\n          ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)\n      ) {\n\n        $objWriter->startElement('c:axId');\n        $objWriter->writeAttribute('val', $id1);\n        $objWriter->endElement();\n        $objWriter->startElement('c:axId');\n        $objWriter->writeAttribute('val', $id2);\n        $objWriter->endElement();\n      } else {\n        $objWriter->startElement('c:firstSliceAng');\n        $objWriter->writeAttribute('val', 0);\n        $objWriter->endElement();\n\n        if ($chartType === PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) {\n\n          $objWriter->startElement('c:holeSize');\n          $objWriter->writeAttribute('val', 50);\n          $objWriter->endElement();\n        }\n      }\n\n      $objWriter->endElement();\n    }\n\n    if (($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART) &&\n        ($chartType !== PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) &&\n        ($chartType !== PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)\n    ) {\n\n      if ($chartType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) {\n        $this->_writeValAx($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines);\n      } else {\n        $this->_writeCatAx($objWriter, $plotArea, $xAxisLabel, $chartType, $id1, $id2, $catIsMultiLevelSeries, $xAxis, $yAxis);\n      }\n\n      $this->_writeValAx($objWriter, $plotArea, $yAxisLabel, $chartType, $id1, $id2, $valIsMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines);\n    }\n\n    $objWriter->endElement();\n  }\n\n  /**\n   * Write Data Labels\n   *\n   * @param  PHPExcel_Shared_XMLWriter $objWriter XML Writer\n   * @param  PHPExcel_Chart_Layout $chartLayout Chart layout\n   *\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private function _writeDataLbls($objWriter, $chartLayout) {\n    $objWriter->startElement('c:dLbls');\n\n    $objWriter->startElement('c:showLegendKey');\n    $showLegendKey = (empty($chartLayout)) ? 0 : $chartLayout->getShowLegendKey();\n    $objWriter->writeAttribute('val', ((empty($showLegendKey)) ? 0 : 1));\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:showVal');\n    $showVal = (empty($chartLayout)) ? 0 : $chartLayout->getShowVal();\n    $objWriter->writeAttribute('val', ((empty($showVal)) ? 0 : 1));\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:showCatName');\n    $showCatName = (empty($chartLayout)) ? 0 : $chartLayout->getShowCatName();\n    $objWriter->writeAttribute('val', ((empty($showCatName)) ? 0 : 1));\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:showSerName');\n    $showSerName = (empty($chartLayout)) ? 0 : $chartLayout->getShowSerName();\n    $objWriter->writeAttribute('val', ((empty($showSerName)) ? 0 : 1));\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:showPercent');\n    $showPercent = (empty($chartLayout)) ? 0 : $chartLayout->getShowPercent();\n    $objWriter->writeAttribute('val', ((empty($showPercent)) ? 0 : 1));\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:showBubbleSize');\n    $showBubbleSize = (empty($chartLayout)) ? 0 : $chartLayout->getShowBubbleSize();\n    $objWriter->writeAttribute('val', ((empty($showBubbleSize)) ? 0 : 1));\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:showLeaderLines');\n    $showLeaderLines = (empty($chartLayout)) ? 1 : $chartLayout->getShowLeaderLines();\n    $objWriter->writeAttribute('val', ((empty($showLeaderLines)) ? 0 : 1));\n    $objWriter->endElement();\n\n    $objWriter->endElement();\n  }\n\n  /**\n   * Write Category Axis\n   *\n   * @param  PHPExcel_Shared_XMLWriter $objWriter XML Writer\n   * @param  PHPExcel_Chart_PlotArea $plotArea\n   * @param  PHPExcel_Chart_Title $xAxisLabel\n   * @param  string $groupType Chart type\n   * @param  string $id1\n   * @param  string $id2\n   * @param  boolean $isMultiLevelSeries\n   *\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private function _writeCatAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $xAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis) {\n    $objWriter->startElement('c:catAx');\n\n    if ($id1 > 0) {\n      $objWriter->startElement('c:axId');\n      $objWriter->writeAttribute('val', $id1);\n      $objWriter->endElement();\n    }\n\n    $objWriter->startElement('c:scaling');\n    $objWriter->startElement('c:orientation');\n    $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('orientation'));\n    $objWriter->endElement();\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:delete');\n    $objWriter->writeAttribute('val', 0);\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:axPos');\n    $objWriter->writeAttribute('val', \"b\");\n    $objWriter->endElement();\n\n    if (!is_null($xAxisLabel)) {\n      $objWriter->startElement('c:title');\n      $objWriter->startElement('c:tx');\n      $objWriter->startElement('c:rich');\n\n      $objWriter->startElement('a:bodyPr');\n      $objWriter->endElement();\n\n      $objWriter->startElement('a:lstStyle');\n      $objWriter->endElement();\n\n      $objWriter->startElement('a:p');\n      $objWriter->startElement('a:r');\n\n      $caption = $xAxisLabel->getCaption();\n      if (is_array($caption)) {\n        $caption = $caption[0];\n      }\n      $objWriter->startElement('a:t');\n      //\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('xml:space', 'preserve');\n      $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption));\n      $objWriter->endElement();\n\n      $objWriter->endElement();\n      $objWriter->endElement();\n      $objWriter->endElement();\n      $objWriter->endElement();\n\n      $layout = $xAxisLabel->getLayout();\n      $this->_writeLayout($layout, $objWriter);\n\n      $objWriter->startElement('c:overlay');\n      $objWriter->writeAttribute('val', 0);\n      $objWriter->endElement();\n\n      $objWriter->endElement();\n\n    }\n\n    $objWriter->startElement('c:numFmt');\n    $objWriter->writeAttribute('formatCode', $yAxis->getAxisNumberFormat());\n    $objWriter->writeAttribute('sourceLinked', $yAxis->getAxisNumberSourceLinked());\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:majorTickMark');\n    $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('major_tick_mark'));\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:minorTickMark');\n    $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('minor_tick_mark'));\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:tickLblPos');\n    $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('axis_labels'));\n    $objWriter->endElement();\n\n    if ($id2 > 0) {\n      $objWriter->startElement('c:crossAx');\n      $objWriter->writeAttribute('val', $id2);\n      $objWriter->endElement();\n\n      $objWriter->startElement('c:crosses');\n      $objWriter->writeAttribute('val', $yAxis->getAxisOptionsProperty('horizontal_crosses'));\n      $objWriter->endElement();\n    }\n\n    $objWriter->startElement('c:auto');\n    $objWriter->writeAttribute('val', 1);\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:lblAlgn');\n    $objWriter->writeAttribute('val', \"ctr\");\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:lblOffset');\n    $objWriter->writeAttribute('val', 100);\n    $objWriter->endElement();\n\n    if ($isMultiLevelSeries) {\n      $objWriter->startElement('c:noMultiLvlLbl');\n      $objWriter->writeAttribute('val', 0);\n      $objWriter->endElement();\n    }\n    $objWriter->endElement();\n  }\n\n  /**\n   * Write Value Axis\n   *\n   * @param  PHPExcel_Shared_XMLWriter $objWriter XML Writer\n   * @param  PHPExcel_Chart_PlotArea $plotArea\n   * @param  PHPExcel_Chart_Title $yAxisLabel\n   * @param  string $groupType Chart type\n   * @param  string $id1\n   * @param  string $id2\n   * @param  boolean $isMultiLevelSeries\n   *\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private function _writeValAx($objWriter, PHPExcel_Chart_PlotArea $plotArea, $yAxisLabel, $groupType, $id1, $id2, $isMultiLevelSeries, $xAxis, $yAxis, $majorGridlines, $minorGridlines) {\n    $objWriter->startElement('c:valAx');\n\n    if ($id2 > 0) {\n      $objWriter->startElement('c:axId');\n      $objWriter->writeAttribute('val', $id2);\n      $objWriter->endElement();\n    }\n\n    $objWriter->startElement('c:scaling');\n    $objWriter->startElement('c:orientation');\n    $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('orientation'));\n\n    if (!is_null($xAxis->getAxisOptionsProperty('maximum'))) {\n      $objWriter->startElement('c:max');\n      $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('maximum'));\n      $objWriter->endElement();\n    }\n\n    if (!is_null($xAxis->getAxisOptionsProperty('minimum'))) {\n      $objWriter->startElement('c:min');\n      $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minimum'));\n      $objWriter->endElement();\n    }\n\n    $objWriter->endElement();\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:delete');\n    $objWriter->writeAttribute('val', 0);\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:axPos');\n    $objWriter->writeAttribute('val', \"l\");\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:majorGridlines');\n    $objWriter->startElement('c:spPr');\n\n    if (!is_null($majorGridlines->getLineColorProperty('value'))) {\n      $objWriter->startElement('a:ln');\n      $objWriter->writeAttribute('w', $majorGridlines->getLineStyleProperty('width'));\n      $objWriter->startElement('a:solidFill');\n      $objWriter->startElement(\"a:{$majorGridlines->getLineColorProperty('type')}\");\n      $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('value'));\n      $objWriter->startElement('a:alpha');\n      $objWriter->writeAttribute('val', $majorGridlines->getLineColorProperty('alpha'));\n      $objWriter->endElement(); //end alpha\n      $objWriter->endElement(); //end srgbClr\n      $objWriter->endElement(); //end solidFill\n\n      $objWriter->startElement('a:prstDash');\n      $objWriter->writeAttribute('val', $majorGridlines->getLineStyleProperty('dash'));\n      $objWriter->endElement();\n\n      if ($majorGridlines->getLineStyleProperty('join') == 'miter') {\n        $objWriter->startElement('a:miter');\n        $objWriter->writeAttribute('lim', '800000');\n        $objWriter->endElement();\n      } else {\n        $objWriter->startElement('a:bevel');\n        $objWriter->endElement();\n      }\n\n      if (!is_null($majorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')))) {\n        $objWriter->startElement('a:headEnd');\n        $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')));\n        $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('head', 'w'));\n        $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('head', 'len'));\n        $objWriter->endElement();\n      }\n\n      if (!is_null($majorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')))) {\n        $objWriter->startElement('a:tailEnd');\n        $objWriter->writeAttribute('type', $majorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')));\n        $objWriter->writeAttribute('w', $majorGridlines->getLineStyleArrowParameters('end', 'w'));\n        $objWriter->writeAttribute('len', $majorGridlines->getLineStyleArrowParameters('end', 'len'));\n        $objWriter->endElement();\n      }\n      $objWriter->endElement(); //end ln\n    }\n    $objWriter->startElement('a:effectLst');\n\n    if (!is_null($majorGridlines->getGlowSize())) {\n      $objWriter->startElement('a:glow');\n      $objWriter->writeAttribute('rad', $majorGridlines->getGlowSize());\n      $objWriter->startElement(\"a:{$majorGridlines->getGlowColor('type')}\");\n      $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('value'));\n      $objWriter->startElement('a:alpha');\n      $objWriter->writeAttribute('val', $majorGridlines->getGlowColor('alpha'));\n      $objWriter->endElement(); //end alpha\n      $objWriter->endElement(); //end schemeClr\n      $objWriter->endElement(); //end glow\n    }\n\n    if (!is_null($majorGridlines->getShadowProperty('presets'))) {\n      $objWriter->startElement(\"a:{$majorGridlines->getShadowProperty('effect')}\");\n      if (!is_null($majorGridlines->getShadowProperty('blur'))) {\n        $objWriter->writeAttribute('blurRad', $majorGridlines->getShadowProperty('blur'));\n      }\n      if (!is_null($majorGridlines->getShadowProperty('distance'))) {\n        $objWriter->writeAttribute('dist', $majorGridlines->getShadowProperty('distance'));\n      }\n      if (!is_null($majorGridlines->getShadowProperty('direction'))) {\n        $objWriter->writeAttribute('dir', $majorGridlines->getShadowProperty('direction'));\n      }\n      if (!is_null($majorGridlines->getShadowProperty('algn'))) {\n        $objWriter->writeAttribute('algn', $majorGridlines->getShadowProperty('algn'));\n      }\n      if (!is_null($majorGridlines->getShadowProperty(array('size', 'sx')))) {\n        $objWriter->writeAttribute('sx', $majorGridlines->getShadowProperty(array('size', 'sx')));\n      }\n      if (!is_null($majorGridlines->getShadowProperty(array('size', 'sy')))) {\n        $objWriter->writeAttribute('sy', $majorGridlines->getShadowProperty(array('size', 'sy')));\n      }\n      if (!is_null($majorGridlines->getShadowProperty(array('size', 'kx')))) {\n        $objWriter->writeAttribute('kx', $majorGridlines->getShadowProperty(array('size', 'kx')));\n      }\n      if (!is_null($majorGridlines->getShadowProperty('rotWithShape'))) {\n        $objWriter->writeAttribute('rotWithShape', $majorGridlines->getShadowProperty('rotWithShape'));\n      }\n      $objWriter->startElement(\"a:{$majorGridlines->getShadowProperty(array('color', 'type'))}\");\n      $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(array('color', 'value')));\n\n      $objWriter->startElement('a:alpha');\n      $objWriter->writeAttribute('val', $majorGridlines->getShadowProperty(array('color', 'alpha')));\n      $objWriter->endElement(); //end alpha\n\n      $objWriter->endElement(); //end color:type\n      $objWriter->endElement(); //end shadow\n    }\n\n    if (!is_null($majorGridlines->getSoftEdgesSize())) {\n      $objWriter->startElement('a:softEdge');\n      $objWriter->writeAttribute('rad', $majorGridlines->getSoftEdgesSize());\n      $objWriter->endElement(); //end softEdge\n    }\n\n    $objWriter->endElement(); //end effectLst\n    $objWriter->endElement(); //end spPr\n    $objWriter->endElement(); //end majorGridLines\n\n    if ($minorGridlines->getObjectState()) {\n      $objWriter->startElement('c:minorGridlines');\n      $objWriter->startElement('c:spPr');\n\n      if (!is_null($minorGridlines->getLineColorProperty('value'))) {\n        $objWriter->startElement('a:ln');\n        $objWriter->writeAttribute('w', $minorGridlines->getLineStyleProperty('width'));\n        $objWriter->startElement('a:solidFill');\n        $objWriter->startElement(\"a:{$minorGridlines->getLineColorProperty('type')}\");\n        $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('value'));\n        $objWriter->startElement('a:alpha');\n        $objWriter->writeAttribute('val', $minorGridlines->getLineColorProperty('alpha'));\n        $objWriter->endElement(); //end alpha\n        $objWriter->endElement(); //end srgbClr\n        $objWriter->endElement(); //end solidFill\n\n        $objWriter->startElement('a:prstDash');\n        $objWriter->writeAttribute('val', $minorGridlines->getLineStyleProperty('dash'));\n        $objWriter->endElement();\n\n        if ($minorGridlines->getLineStyleProperty('join') == 'miter') {\n          $objWriter->startElement('a:miter');\n          $objWriter->writeAttribute('lim', '800000');\n          $objWriter->endElement();\n        } else {\n          $objWriter->startElement('a:bevel');\n          $objWriter->endElement();\n        }\n\n        if (!is_null($minorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')))) {\n          $objWriter->startElement('a:headEnd');\n          $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(array('arrow', 'head', 'type')));\n          $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('head', 'w'));\n          $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('head', 'len'));\n          $objWriter->endElement();\n        }\n\n        if (!is_null($minorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')))) {\n          $objWriter->startElement('a:tailEnd');\n          $objWriter->writeAttribute('type', $minorGridlines->getLineStyleProperty(array('arrow', 'end', 'type')));\n          $objWriter->writeAttribute('w', $minorGridlines->getLineStyleArrowParameters('end', 'w'));\n          $objWriter->writeAttribute('len', $minorGridlines->getLineStyleArrowParameters('end', 'len'));\n          $objWriter->endElement();\n        }\n        $objWriter->endElement(); //end ln\n      }\n\n      $objWriter->startElement('a:effectLst');\n\n      if (!is_null($minorGridlines->getGlowSize())) {\n        $objWriter->startElement('a:glow');\n        $objWriter->writeAttribute('rad', $minorGridlines->getGlowSize());\n        $objWriter->startElement(\"a:{$minorGridlines->getGlowColor('type')}\");\n        $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('value'));\n        $objWriter->startElement('a:alpha');\n        $objWriter->writeAttribute('val', $minorGridlines->getGlowColor('alpha'));\n        $objWriter->endElement(); //end alpha\n        $objWriter->endElement(); //end schemeClr\n        $objWriter->endElement(); //end glow\n      }\n\n      if (!is_null($minorGridlines->getShadowProperty('presets'))) {\n        $objWriter->startElement(\"a:{$minorGridlines->getShadowProperty('effect')}\");\n        if (!is_null($minorGridlines->getShadowProperty('blur'))) {\n          $objWriter->writeAttribute('blurRad', $minorGridlines->getShadowProperty('blur'));\n        }\n        if (!is_null($minorGridlines->getShadowProperty('distance'))) {\n          $objWriter->writeAttribute('dist', $minorGridlines->getShadowProperty('distance'));\n        }\n        if (!is_null($minorGridlines->getShadowProperty('direction'))) {\n          $objWriter->writeAttribute('dir', $minorGridlines->getShadowProperty('direction'));\n        }\n        if (!is_null($minorGridlines->getShadowProperty('algn'))) {\n          $objWriter->writeAttribute('algn', $minorGridlines->getShadowProperty('algn'));\n        }\n        if (!is_null($minorGridlines->getShadowProperty(array('size', 'sx')))) {\n          $objWriter->writeAttribute('sx', $minorGridlines->getShadowProperty(array('size', 'sx')));\n        }\n        if (!is_null($minorGridlines->getShadowProperty(array('size', 'sy')))) {\n          $objWriter->writeAttribute('sy', $minorGridlines->getShadowProperty(array('size', 'sy')));\n        }\n        if (!is_null($minorGridlines->getShadowProperty(array('size', 'kx')))) {\n          $objWriter->writeAttribute('kx', $minorGridlines->getShadowProperty(array('size', 'kx')));\n        }\n        if (!is_null($minorGridlines->getShadowProperty('rotWithShape'))) {\n          $objWriter->writeAttribute('rotWithShape', $minorGridlines->getShadowProperty('rotWithShape'));\n        }\n        $objWriter->startElement(\"a:{$minorGridlines->getShadowProperty(array('color', 'type'))}\");\n        $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(array('color', 'value')));\n        $objWriter->startElement('a:alpha');\n        $objWriter->writeAttribute('val', $minorGridlines->getShadowProperty(array('color', 'alpha')));\n        $objWriter->endElement(); //end alpha\n        $objWriter->endElement(); //end color:type\n        $objWriter->endElement(); //end shadow\n      }\n\n      if (!is_null($minorGridlines->getSoftEdgesSize())) {\n        $objWriter->startElement('a:softEdge');\n        $objWriter->writeAttribute('rad', $minorGridlines->getSoftEdgesSize());\n        $objWriter->endElement(); //end softEdge\n      }\n\n      $objWriter->endElement(); //end effectLst\n      $objWriter->endElement(); //end spPr\n      $objWriter->endElement(); //end minorGridLines\n    }\n\n    if (!is_null($yAxisLabel)) {\n\n      $objWriter->startElement('c:title');\n      $objWriter->startElement('c:tx');\n      $objWriter->startElement('c:rich');\n\n      $objWriter->startElement('a:bodyPr');\n      $objWriter->endElement();\n\n      $objWriter->startElement('a:lstStyle');\n      $objWriter->endElement();\n\n      $objWriter->startElement('a:p');\n      $objWriter->startElement('a:r');\n\n      $caption = $yAxisLabel->getCaption();\n      if (is_array($caption)) {\n        $caption = $caption[0];\n      }\n\n      $objWriter->startElement('a:t');\n      //\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('xml:space', 'preserve');\n      $objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML($caption));\n      $objWriter->endElement();\n\n      $objWriter->endElement();\n      $objWriter->endElement();\n      $objWriter->endElement();\n      $objWriter->endElement();\n\n      if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) {\n        $layout = $yAxisLabel->getLayout();\n        $this->_writeLayout($layout, $objWriter);\n      }\n\n      $objWriter->startElement('c:overlay');\n      $objWriter->writeAttribute('val', 0);\n      $objWriter->endElement();\n\n      $objWriter->endElement();\n    }\n\n    $objWriter->startElement('c:numFmt');\n    $objWriter->writeAttribute('formatCode', $xAxis->getAxisNumberFormat());\n    $objWriter->writeAttribute('sourceLinked', $xAxis->getAxisNumberSourceLinked());\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:majorTickMark');\n    $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_tick_mark'));\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:minorTickMark');\n    $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_tick_mark'));\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:tickLblPos');\n    $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('axis_labels'));\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:spPr');\n\n    if (!is_null($xAxis->getFillProperty('value'))) {\n      $objWriter->startElement('a:solidFill');\n      $objWriter->startElement(\"a:\" . $xAxis->getFillProperty('type'));\n      $objWriter->writeAttribute('val', $xAxis->getFillProperty('value'));\n      $objWriter->startElement('a:alpha');\n      $objWriter->writeAttribute('val', $xAxis->getFillProperty('alpha'));\n      $objWriter->endElement();\n      $objWriter->endElement();\n      $objWriter->endElement();\n    }\n\n    $objWriter->startElement('a:ln');\n\n    $objWriter->writeAttribute('w', $xAxis->getLineStyleProperty('width'));\n    $objWriter->writeAttribute('cap', $xAxis->getLineStyleProperty('cap'));\n    $objWriter->writeAttribute('cmpd', $xAxis->getLineStyleProperty('compound'));\n\n    if (!is_null($xAxis->getLineProperty('value'))) {\n      $objWriter->startElement('a:solidFill');\n      $objWriter->startElement(\"a:\" . $xAxis->getLineProperty('type'));\n      $objWriter->writeAttribute('val', $xAxis->getLineProperty('value'));\n      $objWriter->startElement('a:alpha');\n      $objWriter->writeAttribute('val', $xAxis->getLineProperty('alpha'));\n      $objWriter->endElement();\n      $objWriter->endElement();\n      $objWriter->endElement();\n    }\n\n    $objWriter->startElement('a:prstDash');\n    $objWriter->writeAttribute('val', $xAxis->getLineStyleProperty('dash'));\n    $objWriter->endElement();\n\n    if ($xAxis->getLineStyleProperty('join') == 'miter') {\n      $objWriter->startElement('a:miter');\n      $objWriter->writeAttribute('lim', '800000');\n      $objWriter->endElement();\n    } else {\n      $objWriter->startElement('a:bevel');\n      $objWriter->endElement();\n    }\n\n    if (!is_null($xAxis->getLineStyleProperty(array('arrow', 'head', 'type')))) {\n      $objWriter->startElement('a:headEnd');\n      $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(array('arrow', 'head', 'type')));\n      $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('head'));\n      $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('head'));\n      $objWriter->endElement();\n    }\n\n    if (!is_null($xAxis->getLineStyleProperty(array('arrow', 'end', 'type')))) {\n      $objWriter->startElement('a:tailEnd');\n      $objWriter->writeAttribute('type', $xAxis->getLineStyleProperty(array('arrow', 'end', 'type')));\n      $objWriter->writeAttribute('w', $xAxis->getLineStyleArrowWidth('end'));\n      $objWriter->writeAttribute('len', $xAxis->getLineStyleArrowLength('end'));\n      $objWriter->endElement();\n    }\n\n    $objWriter->endElement();\n\n    $objWriter->startElement('a:effectLst');\n\n    if (!is_null($xAxis->getGlowProperty('size'))) {\n      $objWriter->startElement('a:glow');\n      $objWriter->writeAttribute('rad', $xAxis->getGlowProperty('size'));\n      $objWriter->startElement(\"a:{$xAxis->getGlowProperty(array('color','type'))}\");\n      $objWriter->writeAttribute('val', $xAxis->getGlowProperty(array('color','value')));\n      $objWriter->startElement('a:alpha');\n      $objWriter->writeAttribute('val', $xAxis->getGlowProperty(array('color','alpha')));\n      $objWriter->endElement();\n      $objWriter->endElement();\n      $objWriter->endElement();\n    }\n\n    if (!is_null($xAxis->getShadowProperty('presets'))) {\n      $objWriter->startElement(\"a:{$xAxis->getShadowProperty('effect')}\");\n\n      if (!is_null($xAxis->getShadowProperty('blur'))) {\n        $objWriter->writeAttribute('blurRad', $xAxis->getShadowProperty('blur'));\n      }\n      if (!is_null($xAxis->getShadowProperty('distance'))) {\n        $objWriter->writeAttribute('dist', $xAxis->getShadowProperty('distance'));\n      }\n      if (!is_null($xAxis->getShadowProperty('direction'))) {\n        $objWriter->writeAttribute('dir', $xAxis->getShadowProperty('direction'));\n      }\n      if (!is_null($xAxis->getShadowProperty('algn'))) {\n        $objWriter->writeAttribute('algn', $xAxis->getShadowProperty('algn'));\n      }\n      if (!is_null($xAxis->getShadowProperty(array('size','sx')))) {\n        $objWriter->writeAttribute('sx', $xAxis->getShadowProperty(array('size','sx')));\n      }\n      if (!is_null($xAxis->getShadowProperty(array('size','sy')))) {\n        $objWriter->writeAttribute('sy', $xAxis->getShadowProperty(array('size','sy')));\n      }\n      if (!is_null($xAxis->getShadowProperty(array('size','kx')))) {\n        $objWriter->writeAttribute('kx', $xAxis->getShadowProperty(array('size','kx')));\n      }\n      if (!is_null($xAxis->getShadowProperty('rotWithShape'))) {\n        $objWriter->writeAttribute('rotWithShape', $xAxis->getShadowProperty('rotWithShape'));\n      }\n\n      $objWriter->startElement(\"a:{$xAxis->getShadowProperty(array('color','type'))}\");\n      $objWriter->writeAttribute('val', $xAxis->getShadowProperty(array('color','value')));\n      $objWriter->startElement('a:alpha');\n      $objWriter->writeAttribute('val', $xAxis->getShadowProperty(array('color','alpha')));\n      $objWriter->endElement();\n      $objWriter->endElement();\n\n      $objWriter->endElement();\n    }\n\n    if (!is_null($xAxis->getSoftEdgesSize())) {\n      $objWriter->startElement('a:softEdge');\n      $objWriter->writeAttribute('rad', $xAxis->getSoftEdgesSize());\n      $objWriter->endElement();\n    }\n\n    $objWriter->endElement(); //effectList\n    $objWriter->endElement(); //end spPr\n\n    if ($id1 > 0) {\n      $objWriter->startElement('c:crossAx');\n      $objWriter->writeAttribute('val', $id2);\n      $objWriter->endElement();\n\n      if (!is_null($xAxis->getAxisOptionsProperty('horizontal_crosses_value'))) {\n        $objWriter->startElement('c:crossesAt');\n        $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses_value'));\n        $objWriter->endElement();\n      } else {\n        $objWriter->startElement('c:crosses');\n        $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('horizontal_crosses'));\n        $objWriter->endElement();\n      }\n\n      $objWriter->startElement('c:crossBetween');\n      $objWriter->writeAttribute('val', \"midCat\");\n      $objWriter->endElement();\n\n      if (!is_null($xAxis->getAxisOptionsProperty('major_unit'))) {\n        $objWriter->startElement('c:majorUnit');\n        $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('major_unit'));\n        $objWriter->endElement();\n      }\n\n      if (!is_null($xAxis->getAxisOptionsProperty('minor_unit'))) {\n        $objWriter->startElement('c:minorUnit');\n        $objWriter->writeAttribute('val', $xAxis->getAxisOptionsProperty('minor_unit'));\n        $objWriter->endElement();\n      }\n\n    }\n\n    if ($isMultiLevelSeries) {\n      if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) {\n        $objWriter->startElement('c:noMultiLvlLbl');\n        $objWriter->writeAttribute('val', 0);\n        $objWriter->endElement();\n      }\n    }\n\n    $objWriter->endElement();\n\n  }\n\n  /**\n   * Get the data series type(s) for a chart plot series\n   *\n   * @param  PHPExcel_Chart_PlotArea $plotArea\n   *\n   * @return  string|array\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private\n  static function _getChartType($plotArea) {\n    $groupCount = $plotArea->getPlotGroupCount();\n\n    if ($groupCount == 1) {\n      $chartType = array(\n          $plotArea->getPlotGroupByIndex(0)\n              ->getPlotType()\n      );\n    } else {\n      $chartTypes = array();\n      for ($i = 0; $i < $groupCount; ++$i) {\n        $chartTypes[] = $plotArea->getPlotGroupByIndex($i)\n            ->getPlotType();\n      }\n      $chartType = array_unique($chartTypes);\n      if (count($chartTypes) == 0) {\n        throw new PHPExcel_Writer_Exception('Chart is not yet implemented');\n      }\n    }\n\n    return $chartType;\n  }\n\n  /**\n   * Write Plot Group (series of related plots)\n   *\n   * @param  PHPExcel_Chart_DataSeries $plotGroup\n   * @param  string $groupType Type of plot for dataseries\n   * @param  PHPExcel_Shared_XMLWriter $objWriter XML Writer\n   * @param  boolean &$catIsMultiLevelSeries Is category a multi-series category\n   * @param  boolean &$valIsMultiLevelSeries Is value set a multi-series set\n   * @param  string &$plotGroupingType Type of grouping for multi-series values\n   * @param  PHPExcel_Worksheet $pSheet\n   *\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private function _writePlotGroup($plotGroup,\n      $groupType,\n      $objWriter,\n      &$catIsMultiLevelSeries,\n      &$valIsMultiLevelSeries,\n      &$plotGroupingType,\n      PHPExcel_Worksheet $pSheet\n  ) {\n    if (is_null($plotGroup)) {\n      return;\n    }\n\n    if (($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART) ||\n        ($groupType == PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D)\n    ) {\n      $objWriter->startElement('c:barDir');\n      $objWriter->writeAttribute('val', $plotGroup->getPlotDirection());\n      $objWriter->endElement();\n    }\n\n    if (!is_null($plotGroup->getPlotGrouping())) {\n      $plotGroupingType = $plotGroup->getPlotGrouping();\n      $objWriter->startElement('c:grouping');\n      $objWriter->writeAttribute('val', $plotGroupingType);\n      $objWriter->endElement();\n    }\n\n    //\tGet these details before the loop, because we can use the count to check for varyColors\n    $plotSeriesOrder = $plotGroup->getPlotOrder();\n    $plotSeriesCount = count($plotSeriesOrder);\n\n    if (($groupType !== PHPExcel_Chart_DataSeries::TYPE_RADARCHART) &&\n        ($groupType !== PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)\n    ) {\n\n      if ($groupType !== PHPExcel_Chart_DataSeries::TYPE_LINECHART) {\n        if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) ||\n            ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) ||\n            ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART) ||\n            ($plotSeriesCount > 1)\n        ) {\n          $objWriter->startElement('c:varyColors');\n          $objWriter->writeAttribute('val', 1);\n          $objWriter->endElement();\n        } else {\n          $objWriter->startElement('c:varyColors');\n          $objWriter->writeAttribute('val', 0);\n          $objWriter->endElement();\n        }\n      }\n    }\n\n    foreach ($plotSeriesOrder as $plotSeriesIdx => $plotSeriesRef) {\n      $objWriter->startElement('c:ser');\n\n      $objWriter->startElement('c:idx');\n      $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesIdx);\n      $objWriter->endElement();\n\n      $objWriter->startElement('c:order');\n      $objWriter->writeAttribute('val', $this->_seriesIndex + $plotSeriesRef);\n      $objWriter->endElement();\n\n      if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) ||\n          ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) ||\n          ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)\n      ) {\n\n        $objWriter->startElement('c:dPt');\n        $objWriter->startElement('c:idx');\n        $objWriter->writeAttribute('val', 3);\n        $objWriter->endElement();\n\n        $objWriter->startElement('c:bubble3D');\n        $objWriter->writeAttribute('val', 0);\n        $objWriter->endElement();\n\n        $objWriter->startElement('c:spPr');\n        $objWriter->startElement('a:solidFill');\n        $objWriter->startElement('a:srgbClr');\n        $objWriter->writeAttribute('val', 'FF9900');\n        $objWriter->endElement();\n        $objWriter->endElement();\n        $objWriter->endElement();\n        $objWriter->endElement();\n      }\n\n      //\tLabels\n      $plotSeriesLabel = $plotGroup->getPlotLabelByIndex($plotSeriesRef);\n      if ($plotSeriesLabel && ($plotSeriesLabel->getPointCount() > 0)) {\n        $objWriter->startElement('c:tx');\n        $objWriter->startElement('c:strRef');\n        $this->_writePlotSeriesLabel($plotSeriesLabel, $objWriter);\n        $objWriter->endElement();\n        $objWriter->endElement();\n      }\n\n      //\tFormatting for the points\n      if (($groupType == PHPExcel_Chart_DataSeries::TYPE_LINECHART) ||\n          ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART)\n      ) {\n        $objWriter->startElement('c:spPr');\n        $objWriter->startElement('a:ln');\n        $objWriter->writeAttribute('w', 12700);\n        if ($groupType == PHPExcel_Chart_DataSeries::TYPE_STOCKCHART) {\n          $objWriter->startElement('a:noFill');\n          $objWriter->endElement();\n        }\n        $objWriter->endElement();\n        $objWriter->endElement();\n      }\n\n      $plotSeriesValues = $plotGroup->getPlotValuesByIndex($plotSeriesRef);\n      if ($plotSeriesValues) {\n        $plotSeriesMarker = $plotSeriesValues->getPointMarker();\n        if ($plotSeriesMarker) {\n          $objWriter->startElement('c:marker');\n          $objWriter->startElement('c:symbol');\n          $objWriter->writeAttribute('val', $plotSeriesMarker);\n          $objWriter->endElement();\n\n          if ($plotSeriesMarker !== 'none') {\n            $objWriter->startElement('c:size');\n            $objWriter->writeAttribute('val', 3);\n            $objWriter->endElement();\n          }\n\n          $objWriter->endElement();\n        }\n      }\n\n      if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART) ||\n          ($groupType === PHPExcel_Chart_DataSeries::TYPE_BARCHART_3D) ||\n          ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART)\n      ) {\n\n        $objWriter->startElement('c:invertIfNegative');\n        $objWriter->writeAttribute('val', 0);\n        $objWriter->endElement();\n      }\n\n      //\tCategory Labels\n      $plotSeriesCategory = $plotGroup->getPlotCategoryByIndex($plotSeriesRef);\n      if ($plotSeriesCategory && ($plotSeriesCategory->getPointCount() > 0)) {\n        $catIsMultiLevelSeries = $catIsMultiLevelSeries || $plotSeriesCategory->isMultiLevelSeries();\n\n        if (($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART) ||\n            ($groupType == PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) ||\n            ($groupType == PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)\n        ) {\n\n          if (!is_null($plotGroup->getPlotStyle())) {\n            $plotStyle = $plotGroup->getPlotStyle();\n            if ($plotStyle) {\n              $objWriter->startElement('c:explosion');\n              $objWriter->writeAttribute('val', 25);\n              $objWriter->endElement();\n            }\n          }\n        }\n\n        if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) ||\n            ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)\n        ) {\n          $objWriter->startElement('c:xVal');\n        } else {\n          $objWriter->startElement('c:cat');\n        }\n\n        $this->_writePlotSeriesValues($plotSeriesCategory, $objWriter, $groupType, 'str', $pSheet);\n        $objWriter->endElement();\n      }\n\n      //\tValues\n      if ($plotSeriesValues) {\n        $valIsMultiLevelSeries = $valIsMultiLevelSeries || $plotSeriesValues->isMultiLevelSeries();\n\n        if (($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) ||\n            ($groupType === PHPExcel_Chart_DataSeries::TYPE_SCATTERCHART)\n        ) {\n          $objWriter->startElement('c:yVal');\n        } else {\n          $objWriter->startElement('c:val');\n        }\n\n        $this->_writePlotSeriesValues($plotSeriesValues, $objWriter, $groupType, 'num', $pSheet);\n        $objWriter->endElement();\n      }\n\n      if ($groupType === PHPExcel_Chart_DataSeries::TYPE_BUBBLECHART) {\n        $this->_writeBubbles($plotSeriesValues, $objWriter, $pSheet);\n      }\n\n      $objWriter->endElement();\n\n    }\n\n    $this->_seriesIndex += $plotSeriesIdx + 1;\n  }\n\n  /**\n   * Write Plot Series Label\n   *\n   * @param  PHPExcel_Chart_DataSeriesValues $plotSeriesLabel\n   * @param  PHPExcel_Shared_XMLWriter $objWriter XML Writer\n   *\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private function _writePlotSeriesLabel($plotSeriesLabel, $objWriter) {\n    if (is_null($plotSeriesLabel)) {\n      return;\n    }\n\n    $objWriter->startElement('c:f');\n    $objWriter->writeRawData($plotSeriesLabel->getDataSource());\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:strCache');\n    $objWriter->startElement('c:ptCount');\n    $objWriter->writeAttribute('val', $plotSeriesLabel->getPointCount());\n    $objWriter->endElement();\n\n    foreach ($plotSeriesLabel->getDataValues() as $plotLabelKey => $plotLabelValue) {\n      $objWriter->startElement('c:pt');\n      $objWriter->writeAttribute('idx', $plotLabelKey);\n\n      $objWriter->startElement('c:v');\n      $objWriter->writeRawData($plotLabelValue);\n      $objWriter->endElement();\n      $objWriter->endElement();\n    }\n    $objWriter->endElement();\n\n  }\n\n  /**\n   * Write Plot Series Values\n   *\n   * @param  PHPExcel_Chart_DataSeriesValues $plotSeriesValues\n   * @param  PHPExcel_Shared_XMLWriter $objWriter XML Writer\n   * @param  string $groupType Type of plot for dataseries\n   * @param  string $dataType Datatype of series values\n   * @param  PHPExcel_Worksheet $pSheet\n   *\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private function _writePlotSeriesValues($plotSeriesValues,\n      $objWriter,\n      $groupType,\n      $dataType = 'str',\n      PHPExcel_Worksheet $pSheet\n  ) {\n    if (is_null($plotSeriesValues)) {\n      return;\n    }\n\n    if ($plotSeriesValues->isMultiLevelSeries()) {\n      $levelCount = $plotSeriesValues->multiLevelCount();\n\n      $objWriter->startElement('c:multiLvlStrRef');\n\n      $objWriter->startElement('c:f');\n      $objWriter->writeRawData($plotSeriesValues->getDataSource());\n      $objWriter->endElement();\n\n      $objWriter->startElement('c:multiLvlStrCache');\n\n      $objWriter->startElement('c:ptCount');\n      $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());\n      $objWriter->endElement();\n\n      for ($level = 0; $level < $levelCount; ++$level) {\n        $objWriter->startElement('c:lvl');\n\n        foreach ($plotSeriesValues->getDataValues() as $plotSeriesKey => $plotSeriesValue) {\n          if (isset($plotSeriesValue[$level])) {\n            $objWriter->startElement('c:pt');\n            $objWriter->writeAttribute('idx', $plotSeriesKey);\n\n            $objWriter->startElement('c:v');\n            $objWriter->writeRawData($plotSeriesValue[$level]);\n            $objWriter->endElement();\n            $objWriter->endElement();\n          }\n        }\n\n        $objWriter->endElement();\n      }\n\n      $objWriter->endElement();\n\n      $objWriter->endElement();\n    } else {\n      $objWriter->startElement('c:' . $dataType . 'Ref');\n\n      $objWriter->startElement('c:f');\n      $objWriter->writeRawData($plotSeriesValues->getDataSource());\n      $objWriter->endElement();\n\n      $objWriter->startElement('c:' . $dataType . 'Cache');\n\n      if (($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART) &&\n          ($groupType != PHPExcel_Chart_DataSeries::TYPE_PIECHART_3D) &&\n          ($groupType != PHPExcel_Chart_DataSeries::TYPE_DONUTCHART)\n      ) {\n\n        if (($plotSeriesValues->getFormatCode() !== NULL) &&\n            ($plotSeriesValues->getFormatCode() !== '')\n        ) {\n          $objWriter->startElement('c:formatCode');\n          $objWriter->writeRawData($plotSeriesValues->getFormatCode());\n          $objWriter->endElement();\n        }\n      }\n\n      $objWriter->startElement('c:ptCount');\n      $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());\n      $objWriter->endElement();\n\n      $dataValues = $plotSeriesValues->getDataValues();\n      if (!empty($dataValues)) {\n        if (is_array($dataValues)) {\n          foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) {\n            $objWriter->startElement('c:pt');\n            $objWriter->writeAttribute('idx', $plotSeriesKey);\n\n            $objWriter->startElement('c:v');\n            $objWriter->writeRawData($plotSeriesValue);\n            $objWriter->endElement();\n            $objWriter->endElement();\n          }\n        }\n      }\n\n      $objWriter->endElement();\n\n      $objWriter->endElement();\n    }\n  }\n\n  /**\n   * Write Bubble Chart Details\n   *\n   * @param  PHPExcel_Chart_DataSeriesValues $plotSeriesValues\n   * @param  PHPExcel_Shared_XMLWriter $objWriter XML Writer\n   *\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private function _writeBubbles($plotSeriesValues, $objWriter, PHPExcel_Worksheet $pSheet) {\n    if (is_null($plotSeriesValues)) {\n      return;\n    }\n\n    $objWriter->startElement('c:bubbleSize');\n    $objWriter->startElement('c:numLit');\n\n    $objWriter->startElement('c:formatCode');\n    $objWriter->writeRawData('General');\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:ptCount');\n    $objWriter->writeAttribute('val', $plotSeriesValues->getPointCount());\n    $objWriter->endElement();\n\n    $dataValues = $plotSeriesValues->getDataValues();\n    if (!empty($dataValues)) {\n      if (is_array($dataValues)) {\n        foreach ($dataValues as $plotSeriesKey => $plotSeriesValue) {\n          $objWriter->startElement('c:pt');\n          $objWriter->writeAttribute('idx', $plotSeriesKey);\n          $objWriter->startElement('c:v');\n          $objWriter->writeRawData(1);\n          $objWriter->endElement();\n          $objWriter->endElement();\n        }\n      }\n    }\n\n    $objWriter->endElement();\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:bubble3D');\n    $objWriter->writeAttribute('val', 0);\n    $objWriter->endElement();\n  }\n\n  /**\n   * Write Layout\n   *\n   * @param  PHPExcel_Chart_Layout $layout\n   * @param  PHPExcel_Shared_XMLWriter $objWriter XML Writer\n   *\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private function _writeLayout(PHPExcel_Chart_Layout $layout = NULL, $objWriter) {\n    $objWriter->startElement('c:layout');\n\n    if (!is_null($layout)) {\n      $objWriter->startElement('c:manualLayout');\n\n      $layoutTarget = $layout->getLayoutTarget();\n      if (!is_null($layoutTarget)) {\n        $objWriter->startElement('c:layoutTarget');\n        $objWriter->writeAttribute('val', $layoutTarget);\n        $objWriter->endElement();\n      }\n\n      $xMode = $layout->getXMode();\n      if (!is_null($xMode)) {\n        $objWriter->startElement('c:xMode');\n        $objWriter->writeAttribute('val', $xMode);\n        $objWriter->endElement();\n      }\n\n      $yMode = $layout->getYMode();\n      if (!is_null($yMode)) {\n        $objWriter->startElement('c:yMode');\n        $objWriter->writeAttribute('val', $yMode);\n        $objWriter->endElement();\n      }\n\n      $x = $layout->getXPosition();\n      if (!is_null($x)) {\n        $objWriter->startElement('c:x');\n        $objWriter->writeAttribute('val', $x);\n        $objWriter->endElement();\n      }\n\n      $y = $layout->getYPosition();\n      if (!is_null($y)) {\n        $objWriter->startElement('c:y');\n        $objWriter->writeAttribute('val', $y);\n        $objWriter->endElement();\n      }\n\n      $w = $layout->getWidth();\n      if (!is_null($w)) {\n        $objWriter->startElement('c:w');\n        $objWriter->writeAttribute('val', $w);\n        $objWriter->endElement();\n      }\n\n      $h = $layout->getHeight();\n      if (!is_null($h)) {\n        $objWriter->startElement('c:h');\n        $objWriter->writeAttribute('val', $h);\n        $objWriter->endElement();\n      }\n\n      $objWriter->endElement();\n    }\n\n    $objWriter->endElement();\n  }\n\n  /**\n   * Write Alternate Content block\n   *\n   * @param  PHPExcel_Shared_XMLWriter $objWriter XML Writer\n   *\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private function _writeAlternateContent($objWriter) {\n    $objWriter->startElement('mc:AlternateContent');\n    $objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006');\n\n    $objWriter->startElement('mc:Choice');\n    $objWriter->writeAttribute('xmlns:c14', 'http://schemas.microsoft.com/office/drawing/2007/8/2/chart');\n    $objWriter->writeAttribute('Requires', 'c14');\n\n    $objWriter->startElement('c14:style');\n    $objWriter->writeAttribute('val', '102');\n    $objWriter->endElement();\n    $objWriter->endElement();\n\n    $objWriter->startElement('mc:Fallback');\n    $objWriter->startElement('c:style');\n    $objWriter->writeAttribute('val', '2');\n    $objWriter->endElement();\n    $objWriter->endElement();\n\n    $objWriter->endElement();\n  }\n\n  /**\n   * Write Printer Settings\n   *\n   * @param  PHPExcel_Shared_XMLWriter $objWriter XML Writer\n   *\n   * @throws  PHPExcel_Writer_Exception\n   */\n  private function _writePrintSettings($objWriter) {\n    $objWriter->startElement('c:printSettings');\n\n    $objWriter->startElement('c:headerFooter');\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:pageMargins');\n    $objWriter->writeAttribute('footer', 0.3);\n    $objWriter->writeAttribute('header', 0.3);\n    $objWriter->writeAttribute('r', 0.7);\n    $objWriter->writeAttribute('l', 0.7);\n    $objWriter->writeAttribute('t', 0.75);\n    $objWriter->writeAttribute('b', 0.75);\n    $objWriter->endElement();\n\n    $objWriter->startElement('c:pageSetup');\n    $objWriter->writeAttribute('orientation', \"portrait\");\n    $objWriter->endElement();\n\n    $objWriter->endElement();\n  }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Comments.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007_Comments\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007_Comments extends PHPExcel_Writer_Excel2007_WriterPart\n{\n\t/**\n\t * Write comments to XML format\n\t *\n\t * @param \tPHPExcel_Worksheet\t\t\t\t$pWorksheet\n\t * @return \tstring \t\t\t\t\t\t\t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeComments(PHPExcel_Worksheet $pWorksheet = null)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n  \t\t// Comments cache\n  \t\t$comments\t= $pWorksheet->getComments();\n\n  \t\t// Authors cache\n  \t\t$authors\t= array();\n  \t\t$authorId\t= 0;\n\t\tforeach ($comments as $comment) {\n\t\t\tif (!isset($authors[$comment->getAuthor()])) {\n\t\t\t\t$authors[$comment->getAuthor()] = $authorId++;\n\t\t\t}\n\t\t}\n\n\t\t// comments\n\t\t$objWriter->startElement('comments');\n\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');\n\n\t\t\t// Loop through authors\n\t\t\t$objWriter->startElement('authors');\n\t\t\tforeach ($authors as $author => $index) {\n\t\t\t\t$objWriter->writeElement('author', $author);\n\t\t\t}\n\t\t\t$objWriter->endElement();\n\n\t\t\t// Loop through comments\n\t\t\t$objWriter->startElement('commentList');\n\t\t\tforeach ($comments as $key => $value) {\n\t\t\t\t$this->_writeComment($objWriter, $key, $value, $authors);\n\t\t\t}\n\t\t\t$objWriter->endElement();\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write comment to XML format\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t\t$objWriter \t\t\tXML Writer\n\t * @param\tstring\t\t\t\t\t\t\t$pCellReference\t\tCell reference\n\t * @param \tPHPExcel_Comment\t\t\t\t$pComment\t\t\tComment\n\t * @param\tarray\t\t\t\t\t\t\t$pAuthors\t\t\tArray of authors\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function _writeComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null, $pAuthors = null)\n\t{\n\t\t// comment\n\t\t$objWriter->startElement('comment');\n\t\t$objWriter->writeAttribute('ref', \t\t$pCellReference);\n\t\t$objWriter->writeAttribute('authorId', \t$pAuthors[$pComment->getAuthor()]);\n\n\t\t\t// text\n\t\t\t$objWriter->startElement('text');\n\t\t\t$this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pComment->getText());\n\t\t\t$objWriter->endElement();\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write VML comments to XML format\n\t *\n\t * @param \tPHPExcel_Worksheet\t\t\t\t$pWorksheet\n\t * @return \tstring \t\t\t\t\t\t\t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeVMLComments(PHPExcel_Worksheet $pWorksheet = null)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n  \t\t// Comments cache\n  \t\t$comments\t= $pWorksheet->getComments();\n\n\t\t// xml\n\t\t$objWriter->startElement('xml');\n\t\t$objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml');\n\t\t$objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office');\n\t\t$objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel');\n\n\t\t\t// o:shapelayout\n\t\t\t$objWriter->startElement('o:shapelayout');\n\t\t\t$objWriter->writeAttribute('v:ext', \t\t'edit');\n\n\t\t\t\t// o:idmap\n\t\t\t\t$objWriter->startElement('o:idmap');\n\t\t\t\t$objWriter->writeAttribute('v:ext', \t'edit');\n\t\t\t\t$objWriter->writeAttribute('data', \t\t'1');\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// v:shapetype\n\t\t\t$objWriter->startElement('v:shapetype');\n\t\t\t$objWriter->writeAttribute('id', \t\t'_x0000_t202');\n\t\t\t$objWriter->writeAttribute('coordsize', '21600,21600');\n\t\t\t$objWriter->writeAttribute('o:spt', \t'202');\n\t\t\t$objWriter->writeAttribute('path', \t\t'm,l,21600r21600,l21600,xe');\n\n\t\t\t\t// v:stroke\n\t\t\t\t$objWriter->startElement('v:stroke');\n\t\t\t\t$objWriter->writeAttribute('joinstyle', \t'miter');\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t// v:path\n\t\t\t\t$objWriter->startElement('v:path');\n\t\t\t\t$objWriter->writeAttribute('gradientshapeok', \t't');\n\t\t\t\t$objWriter->writeAttribute('o:connecttype', \t'rect');\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// Loop through comments\n\t\t\tforeach ($comments as $key => $value) {\n\t\t\t\t$this->_writeVMLComment($objWriter, $key, $value);\n\t\t\t}\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write VML comment to XML format\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t\t$objWriter \t\t\tXML Writer\n\t * @param\tstring\t\t\t\t\t\t\t$pCellReference\t\tCell reference\n\t * @param \tPHPExcel_Comment\t\t\t\t$pComment\t\t\tComment\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function _writeVMLComment(PHPExcel_Shared_XMLWriter $objWriter = null, $pCellReference = 'A1', PHPExcel_Comment $pComment = null)\n\t{\n \t\t// Metadata\n \t\tlist($column, $row) = PHPExcel_Cell::coordinateFromString($pCellReference);\n \t\t$column = PHPExcel_Cell::columnIndexFromString($column);\n \t\t$id = 1024 + $column + $row;\n \t\t$id = substr($id, 0, 4);\n\n\t\t// v:shape\n\t\t$objWriter->startElement('v:shape');\n\t\t$objWriter->writeAttribute('id', \t\t\t'_x0000_s' . $id);\n\t\t$objWriter->writeAttribute('type', \t\t\t'#_x0000_t202');\n\t\t$objWriter->writeAttribute('style', \t\t'position:absolute;margin-left:' . $pComment->getMarginLeft() . ';margin-top:' . $pComment->getMarginTop() . ';width:' . $pComment->getWidth() . ';height:' . $pComment->getHeight() . ';z-index:1;visibility:' . ($pComment->getVisible() ? 'visible' : 'hidden'));\n\t\t$objWriter->writeAttribute('fillcolor', \t'#' . $pComment->getFillColor()->getRGB());\n\t\t$objWriter->writeAttribute('o:insetmode', \t'auto');\n\n\t\t\t// v:fill\n\t\t\t$objWriter->startElement('v:fill');\n\t\t\t$objWriter->writeAttribute('color2', \t\t'#' . $pComment->getFillColor()->getRGB());\n\t\t\t$objWriter->endElement();\n\n\t\t\t// v:shadow\n\t\t\t$objWriter->startElement('v:shadow');\n\t\t\t$objWriter->writeAttribute('on', \t\t\t't');\n\t\t\t$objWriter->writeAttribute('color', \t\t'black');\n\t\t\t$objWriter->writeAttribute('obscured', \t\t't');\n\t\t\t$objWriter->endElement();\n\n\t\t\t// v:path\n\t\t\t$objWriter->startElement('v:path');\n\t\t\t$objWriter->writeAttribute('o:connecttype', 'none');\n\t\t\t$objWriter->endElement();\n\n\t\t\t// v:textbox\n\t\t\t$objWriter->startElement('v:textbox');\n\t\t\t$objWriter->writeAttribute('style', 'mso-direction-alt:auto');\n\n\t\t\t\t// div\n\t\t\t\t$objWriter->startElement('div');\n\t\t\t\t$objWriter->writeAttribute('style', 'text-align:left');\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// x:ClientData\n\t\t\t$objWriter->startElement('x:ClientData');\n\t\t\t$objWriter->writeAttribute('ObjectType', 'Note');\n\n\t\t\t\t// x:MoveWithCells\n\t\t\t\t$objWriter->writeElement('x:MoveWithCells', '');\n\n\t\t\t\t// x:SizeWithCells\n\t\t\t\t$objWriter->writeElement('x:SizeWithCells', '');\n\n\t\t\t\t// x:Anchor\n\t\t\t\t//$objWriter->writeElement('x:Anchor', $column . ', 15, ' . ($row - 2) . ', 10, ' . ($column + 4) . ', 15, ' . ($row + 5) . ', 18');\n\n\t\t\t\t// x:AutoFill\n\t\t\t\t$objWriter->writeElement('x:AutoFill', 'False');\n\n\t\t\t\t// x:Row\n\t\t\t\t$objWriter->writeElement('x:Row', ($row - 1));\n\n\t\t\t\t// x:Column\n\t\t\t\t$objWriter->writeElement('x:Column', ($column - 1));\n\n\t\t\t$objWriter->endElement();\n\n\t\t$objWriter->endElement();\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/ContentTypes.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007_ContentTypes\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007_ContentTypes extends PHPExcel_Writer_Excel2007_WriterPart\n{\n\t/**\n\t * Write content types to XML format\n\t *\n\t * @param \tPHPExcel\t$pPHPExcel\n\t * @param\tboolean\t\t$includeCharts\tFlag indicating if we should include drawing details for charts\n\t * @return \tstring \t\t\t\t\t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeContentTypes(PHPExcel $pPHPExcel = null, $includeCharts = FALSE)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// Types\n\t\t$objWriter->startElement('Types');\n\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/content-types');\n\n\t\t\t// Theme\n\t\t\t$this->_writeOverrideContentType(\n\t\t\t\t$objWriter, '/xl/theme/theme1.xml', 'application/vnd.openxmlformats-officedocument.theme+xml'\n\t\t\t);\n\n\t\t\t// Styles\n\t\t\t$this->_writeOverrideContentType(\n\t\t\t\t$objWriter, '/xl/styles.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.styles+xml'\n\t\t\t);\n\n\t\t\t// Rels\n\t\t\t$this->_writeDefaultContentType(\n\t\t\t\t$objWriter, 'rels', 'application/vnd.openxmlformats-package.relationships+xml'\n\t\t\t);\n\n\t\t\t// XML\n\t\t\t$this->_writeDefaultContentType(\n\t\t\t\t$objWriter, 'xml', 'application/xml'\n\t\t\t);\n\n\t\t\t// VML\n\t\t\t$this->_writeDefaultContentType(\n\t\t\t\t$objWriter, 'vml', 'application/vnd.openxmlformats-officedocument.vmlDrawing'\n\t\t\t);\n\n\t\t\t// Workbook\n\t\t\tif($pPHPExcel->hasMacros()){ //Macros in workbook ?\n\t\t\t\t// Yes : not standard content but \"macroEnabled\"\n\t\t\t\t$this->_writeOverrideContentType(\n\t\t\t\t\t$objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml'\n\t\t\t\t);\n\t\t\t\t//... and define a new type for the VBA project\n\t\t\t\t$this->_writeDefaultContentType(\n\t\t\t\t\t\t\t$objWriter, 'bin', 'application/vnd.ms-office.vbaProject'\n\t\t\t\t\t\t);\n\t\t\t\tif($pPHPExcel->hasMacrosCertificate()){// signed macros ?\n\t\t\t\t\t// Yes : add needed information\n\t\t\t\t\t$this->_writeOverrideContentType(\n\t\t\t\t\t\t$objWriter, '/xl/vbaProjectSignature.bin', 'application/vnd.ms-office.vbaProjectSignature'\n\t\t\t\t);\n\t\t\t\t}\n\t\t\t}else{// no macros in workbook, so standard type\n\t\t\t\t$this->_writeOverrideContentType(\n\t\t\t\t\t$objWriter, '/xl/workbook.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet.main+xml'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// DocProps\n\t\t\t$this->_writeOverrideContentType(\n\t\t\t\t$objWriter, '/docProps/app.xml', 'application/vnd.openxmlformats-officedocument.extended-properties+xml'\n\t\t\t);\n\n\t\t\t$this->_writeOverrideContentType(\n\t\t\t\t$objWriter, '/docProps/core.xml', 'application/vnd.openxmlformats-package.core-properties+xml'\n\t\t\t);\n\n\t\t\t$customPropertyList = $pPHPExcel->getProperties()->getCustomProperties();\n\t\t\tif (!empty($customPropertyList)) {\n\t\t\t\t$this->_writeOverrideContentType(\n\t\t\t\t\t$objWriter, '/docProps/custom.xml', 'application/vnd.openxmlformats-officedocument.custom-properties+xml'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Worksheets\n\t\t\t$sheetCount = $pPHPExcel->getSheetCount();\n\t\t\tfor ($i = 0; $i < $sheetCount; ++$i) {\n\t\t\t\t$this->_writeOverrideContentType(\n\t\t\t\t\t$objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Shared strings\n\t\t\t$this->_writeOverrideContentType(\n\t\t\t\t$objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml'\n\t\t\t);\n\n\t\t\t// Add worksheet relationship content types\n\t\t\t$chart = 1;\n\t\t\tfor ($i = 0; $i < $sheetCount; ++$i) {\n\t\t\t\t$drawings = $pPHPExcel->getSheet($i)->getDrawingCollection();\n\t\t\t\t$drawingCount = count($drawings);\n\t\t\t\t$chartCount = ($includeCharts) ? $pPHPExcel->getSheet($i)->getChartCount() : 0;\n\n\t\t\t\t//\tWe need a drawing relationship for the worksheet if we have either drawings or charts\n\t\t\t\tif (($drawingCount > 0) || ($chartCount > 0)) {\n\t\t\t\t\t$this->_writeOverrideContentType(\n\t\t\t\t\t\t$objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml'\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t//\tIf we have charts, then we need a chart relationship for every individual chart\n\t\t\t\tif ($chartCount > 0) {\n\t\t\t\t\tfor ($c = 0; $c < $chartCount; ++$c) {\n\t\t\t\t\t\t$this->_writeOverrideContentType(\n\t\t\t\t\t\t\t$objWriter, '/xl/charts/chart' . $chart++ . '.xml', 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml'\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Comments\n\t\t\tfor ($i = 0; $i < $sheetCount; ++$i) {\n\t\t\t\tif (count($pPHPExcel->getSheet($i)->getComments()) > 0) {\n\t\t\t\t\t$this->_writeOverrideContentType(\n\t\t\t\t\t\t$objWriter, '/xl/comments' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.comments+xml'\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add media content-types\n\t\t\t$aMediaContentTypes = array();\n\t\t\t$mediaCount = $this->getParentWriter()->getDrawingHashTable()->count();\n\t\t\tfor ($i = 0; $i < $mediaCount; ++$i) {\n\t\t\t\t$extension \t= '';\n\t\t\t\t$mimeType \t= '';\n\n\t\t\t\tif ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) {\n\t\t\t\t\t$extension \t= strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getExtension());\n\t\t\t\t\t$mimeType \t= $this->_getImageMimeType( $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getPath() );\n\t\t\t\t} else if ($this->getParentWriter()->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) {\n\t\t\t\t\t$extension \t= strtolower($this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType());\n\t\t\t\t\t$extension \t= explode('/', $extension);\n\t\t\t\t\t$extension \t= $extension[1];\n\n\t\t\t\t\t$mimeType \t= $this->getParentWriter()->getDrawingHashTable()->getByIndex($i)->getMimeType();\n\t\t\t\t}\n\n\t\t\t\tif (!isset( $aMediaContentTypes[$extension]) ) {\n\t\t\t\t\t\t$aMediaContentTypes[$extension] = $mimeType;\n\n\t\t\t\t\t\t$this->_writeDefaultContentType(\n\t\t\t\t\t\t\t$objWriter, $extension, $mimeType\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tif($pPHPExcel->hasRibbonBinObjects()){//Some additional objects in the ribbon ?\n\t\t\t\t//we need to write \"Extension\" but not already write for media content\n\t\t\t\t$tabRibbonTypes=array_diff($pPHPExcel->getRibbonBinObjects('types'), array_keys($aMediaContentTypes));\n\t\t\t\tforeach($tabRibbonTypes as $aRibbonType){\n\t\t\t\t\t$mimeType='image/.'.$aRibbonType;//we wrote $mimeType like customUI Editor\n\t\t\t\t\t$this->_writeDefaultContentType(\n\t\t\t\t\t\t$objWriter, $aRibbonType, $mimeType\n\t\t\t\t\t);\n\t\t\t\t}\t\n\t\t\t}\n\t\t\t$sheetCount = $pPHPExcel->getSheetCount();\n\t\t\tfor ($i = 0; $i < $sheetCount; ++$i) {\n\t\t\t\tif (count($pPHPExcel->getSheet()->getHeaderFooter()->getImages()) > 0) {\n\t\t\t\t\tforeach ($pPHPExcel->getSheet()->getHeaderFooter()->getImages() as $image) {\n\t\t\t\t\t\tif (!isset( $aMediaContentTypes[strtolower($image->getExtension())]) ) {\n\t\t\t\t\t\t\t$aMediaContentTypes[strtolower($image->getExtension())] = $this->_getImageMimeType( $image->getPath() );\n\n\t\t\t\t\t\t\t$this->_writeDefaultContentType(\n\t\t\t\t\t\t\t\t$objWriter, strtolower($image->getExtension()), $aMediaContentTypes[strtolower($image->getExtension())]\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Get image mime type\n\t *\n\t * @param \tstring\t$pFile\tFilename\n\t * @return \tstring\tMime Type\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _getImageMimeType($pFile = '')\n\t{\n\t\tif (PHPExcel_Shared_File::file_exists($pFile)) {\n\t\t\t$image = getimagesize($pFile);\n\t\t\treturn image_type_to_mime_type($image[2]);\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"File $pFile does not exist\");\n\t\t}\n\t}\n\n\t/**\n\t * Write Default content type\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter \t$objWriter \t\tXML Writer\n\t * @param \tstring \t\t\t\t\t\t$pPartname \t\tPart name\n\t * @param \tstring \t\t\t\t\t\t$pContentType \tContent type\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeDefaultContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '')\n\t{\n\t\tif ($pPartname != '' && $pContentType != '') {\n\t\t\t// Write content type\n\t\t\t$objWriter->startElement('Default');\n\t\t\t$objWriter->writeAttribute('Extension', \t$pPartname);\n\t\t\t$objWriter->writeAttribute('ContentType', \t$pContentType);\n\t\t\t$objWriter->endElement();\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Invalid parameters passed.\");\n\t\t}\n\t}\n\n\t/**\n\t * Write Override content type\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter \t$objWriter \t\tXML Writer\n\t * @param \tstring \t\t\t\t\t\t$pPartname \t\tPart name\n\t * @param \tstring \t\t\t\t\t\t$pContentType \tContent type\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeOverrideContentType(PHPExcel_Shared_XMLWriter $objWriter = null, $pPartname = '', $pContentType = '')\n\t{\n\t\tif ($pPartname != '' && $pContentType != '') {\n\t\t\t// Write content type\n\t\t\t$objWriter->startElement('Override');\n\t\t\t$objWriter->writeAttribute('PartName', \t\t$pPartname);\n\t\t\t$objWriter->writeAttribute('ContentType', \t$pContentType);\n\t\t\t$objWriter->endElement();\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Invalid parameters passed.\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/DocProps.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007_DocProps\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007_DocProps extends PHPExcel_Writer_Excel2007_WriterPart\n{\n/**\n\t * Write docProps/app.xml to XML format\n\t *\n\t * @param \tPHPExcel\t$pPHPExcel\n\t * @return \tstring \t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeDocPropsApp(PHPExcel $pPHPExcel = null)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// Properties\n\t\t$objWriter->startElement('Properties');\n\t\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/extended-properties');\n\t\t\t$objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes');\n\n\t\t\t// Application\n\t\t\t$objWriter->writeElement('Application', \t'Microsoft Excel');\n\n\t\t\t// DocSecurity\n\t\t\t$objWriter->writeElement('DocSecurity', \t'0');\n\n\t\t\t// ScaleCrop\n\t\t\t$objWriter->writeElement('ScaleCrop', \t\t'false');\n\n\t\t\t// HeadingPairs\n\t\t\t$objWriter->startElement('HeadingPairs');\n\n\t\t\t\t// Vector\n\t\t\t\t$objWriter->startElement('vt:vector');\n\t\t\t\t\t$objWriter->writeAttribute('size', \t\t'2');\n\t\t\t\t\t$objWriter->writeAttribute('baseType', \t'variant');\n\n\t\t\t\t\t// Variant\n\t\t\t\t\t$objWriter->startElement('vt:variant');\n\t\t\t\t\t\t$objWriter->writeElement('vt:lpstr', \t'Worksheets');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// Variant\n\t\t\t\t\t$objWriter->startElement('vt:variant');\n\t\t\t\t\t\t$objWriter->writeElement('vt:i4', \t\t$pPHPExcel->getSheetCount());\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// TitlesOfParts\n\t\t\t$objWriter->startElement('TitlesOfParts');\n\n\t\t\t\t// Vector\n\t\t\t\t$objWriter->startElement('vt:vector');\n\t\t\t\t\t$objWriter->writeAttribute('size', \t\t$pPHPExcel->getSheetCount());\n\t\t\t\t\t$objWriter->writeAttribute('baseType',\t'lpstr');\n\n\t\t\t\t\t$sheetCount = $pPHPExcel->getSheetCount();\n\t\t\t\t\tfor ($i = 0; $i < $sheetCount; ++$i) {\n\t\t\t\t\t\t$objWriter->writeElement('vt:lpstr', $pPHPExcel->getSheet($i)->getTitle());\n\t\t\t\t\t}\n\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// Company\n\t\t\t$objWriter->writeElement('Company', \t\t\t$pPHPExcel->getProperties()->getCompany());\n\n\t\t\t// Company\n\t\t\t$objWriter->writeElement('Manager', \t\t\t$pPHPExcel->getProperties()->getManager());\n\n\t\t\t// LinksUpToDate\n\t\t\t$objWriter->writeElement('LinksUpToDate', \t\t'false');\n\n\t\t\t// SharedDoc\n\t\t\t$objWriter->writeElement('SharedDoc', \t\t\t'false');\n\n\t\t\t// HyperlinksChanged\n\t\t\t$objWriter->writeElement('HyperlinksChanged', \t'false');\n\n\t\t\t// AppVersion\n\t\t\t$objWriter->writeElement('AppVersion', \t\t\t'12.0000');\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write docProps/core.xml to XML format\n\t *\n\t * @param \tPHPExcel\t$pPHPExcel\n\t * @return \tstring \t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeDocPropsCore(PHPExcel $pPHPExcel = null)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// cp:coreProperties\n\t\t$objWriter->startElement('cp:coreProperties');\n\t\t\t$objWriter->writeAttribute('xmlns:cp', 'http://schemas.openxmlformats.org/package/2006/metadata/core-properties');\n\t\t\t$objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');\n\t\t\t$objWriter->writeAttribute('xmlns:dcterms', 'http://purl.org/dc/terms/');\n\t\t\t$objWriter->writeAttribute('xmlns:dcmitype', 'http://purl.org/dc/dcmitype/');\n\t\t\t$objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');\n\n\t\t\t// dc:creator\n\t\t\t$objWriter->writeElement('dc:creator',\t\t\t$pPHPExcel->getProperties()->getCreator());\n\n\t\t\t// cp:lastModifiedBy\n\t\t\t$objWriter->writeElement('cp:lastModifiedBy', \t$pPHPExcel->getProperties()->getLastModifiedBy());\n\n\t\t\t// dcterms:created\n\t\t\t$objWriter->startElement('dcterms:created');\n\t\t\t\t$objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF');\n\t\t\t\t$objWriter->writeRawData(date(DATE_W3C, \t$pPHPExcel->getProperties()->getCreated()));\n\t\t\t$objWriter->endElement();\n\n\t\t\t// dcterms:modified\n\t\t\t$objWriter->startElement('dcterms:modified');\n\t\t\t\t$objWriter->writeAttribute('xsi:type', 'dcterms:W3CDTF');\n\t\t\t\t$objWriter->writeRawData(date(DATE_W3C, \t$pPHPExcel->getProperties()->getModified()));\n\t\t\t$objWriter->endElement();\n\n\t\t\t// dc:title\n\t\t\t$objWriter->writeElement('dc:title', \t\t\t$pPHPExcel->getProperties()->getTitle());\n\n\t\t\t// dc:description\n\t\t\t$objWriter->writeElement('dc:description', \t\t$pPHPExcel->getProperties()->getDescription());\n\n\t\t\t// dc:subject\n\t\t\t$objWriter->writeElement('dc:subject', \t\t\t$pPHPExcel->getProperties()->getSubject());\n\n\t\t\t// cp:keywords\n\t\t\t$objWriter->writeElement('cp:keywords', \t\t$pPHPExcel->getProperties()->getKeywords());\n\n\t\t\t// cp:category\n\t\t\t$objWriter->writeElement('cp:category', \t\t$pPHPExcel->getProperties()->getCategory());\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write docProps/custom.xml to XML format\n\t *\n\t * @param \tPHPExcel\t$pPHPExcel\n\t * @return \tstring \t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeDocPropsCustom(PHPExcel $pPHPExcel = null)\n\t{\n\t\t$customPropertyList = $pPHPExcel->getProperties()->getCustomProperties();\n\t\tif (empty($customPropertyList)) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// cp:coreProperties\n\t\t$objWriter->startElement('Properties');\n\t\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/officeDocument/2006/custom-properties');\n\t\t\t$objWriter->writeAttribute('xmlns:vt', 'http://schemas.openxmlformats.org/officeDocument/2006/docPropsVTypes');\n\n\n\t\t\tforeach($customPropertyList as $key => $customProperty) {\n\t\t\t\t$propertyValue = $pPHPExcel->getProperties()->getCustomPropertyValue($customProperty);\n\t\t\t\t$propertyType = $pPHPExcel->getProperties()->getCustomPropertyType($customProperty);\n\n\t\t\t\t$objWriter->startElement('property');\n\t\t\t\t\t$objWriter->writeAttribute('fmtid', \t'{D5CDD505-2E9C-101B-9397-08002B2CF9AE}');\n\t\t\t\t\t$objWriter->writeAttribute('pid', \t\t$key+2);\n\t\t\t\t\t$objWriter->writeAttribute('name', \t\t$customProperty);\n\n\t\t\t\t\tswitch($propertyType) {\n\t\t\t\t\t\tcase 'i' :\n\t\t\t\t\t\t\t$objWriter->writeElement('vt:i4', \t\t$propertyValue);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'f' :\n\t\t\t\t\t\t\t$objWriter->writeElement('vt:r8', \t\t$propertyValue);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'b' :\n\t\t\t\t\t\t\t$objWriter->writeElement('vt:bool', \t($propertyValue) ? 'true' : 'false');\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'd' :\n\t\t\t\t\t\t\t$objWriter->startElement('vt:filetime');\n\t\t\t\t\t\t\t\t$objWriter->writeRawData(date(DATE_W3C, $propertyValue));\n\t\t\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tdefault :\n\t\t\t\t\t\t\t$objWriter->writeElement('vt:lpwstr', \t$propertyValue);\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Drawing.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007_Drawing\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007_Drawing extends PHPExcel_Writer_Excel2007_WriterPart\n{\n\t/**\n\t * Write drawings to XML format\n\t *\n\t * @param \tPHPExcel_Worksheet\t$pWorksheet\n\t * @param\tint\t\t\t\t\t&$chartRef\t\tChart ID\n\t * @param\tboolean\t\t\t\t$includeCharts\tFlag indicating if we should include drawing details for charts\n\t * @return \tstring \t\t\t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeDrawings(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = FALSE)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// xdr:wsDr\n\t\t$objWriter->startElement('xdr:wsDr');\n\t\t$objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing');\n\t\t$objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');\n\n\t\t\t// Loop through images and write drawings\n\t\t\t$i = 1;\n\t\t\t$iterator = $pWorksheet->getDrawingCollection()->getIterator();\n\t\t\twhile ($iterator->valid()) {\n\t\t\t\t$this->_writeDrawing($objWriter, $iterator->current(), $i);\n\n\t\t\t\t$iterator->next();\n\t\t\t\t++$i;\n\t\t\t}\n\n\t\t\tif ($includeCharts) {\n\t\t\t\t$chartCount = $pWorksheet->getChartCount();\n\t\t\t\t// Loop through charts and write the chart position\n\t\t\t\tif ($chartCount > 0) {\n\t\t\t\t\tfor ($c = 0; $c < $chartCount; ++$c) {\n\t\t\t\t\t\t$this->_writeChart($objWriter, $pWorksheet->getChartByIndex($c), $c+$i);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write drawings to XML format\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_Chart\t\t\t\t$pChart\n\t * @param \tint\t\t\t\t\t\t\t$pRelationId\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function _writeChart(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Chart $pChart = null, $pRelationId = -1)\n\t{\n\t\t$tl = $pChart->getTopLeftPosition();\n\t\t$tl['colRow'] = PHPExcel_Cell::coordinateFromString($tl['cell']);\n\t\t$br = $pChart->getBottomRightPosition();\n\t\t$br['colRow'] = PHPExcel_Cell::coordinateFromString($br['cell']);\n\n\t\t$objWriter->startElement('xdr:twoCellAnchor');\n\n\t\t\t$objWriter->startElement('xdr:from');\n\t\t\t\t$objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($tl['colRow'][0]) - 1);\n\t\t\t\t$objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['xOffset']));\n\t\t\t\t$objWriter->writeElement('xdr:row', $tl['colRow'][1] - 1);\n\t\t\t\t$objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($tl['yOffset']));\n\t\t\t$objWriter->endElement();\n\t\t\t$objWriter->startElement('xdr:to');\n\t\t\t\t$objWriter->writeElement('xdr:col', PHPExcel_Cell::columnIndexFromString($br['colRow'][0]) - 1);\n\t\t\t\t$objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['xOffset']));\n\t\t\t\t$objWriter->writeElement('xdr:row', $br['colRow'][1] - 1);\n\t\t\t\t$objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($br['yOffset']));\n\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->startElement('xdr:graphicFrame');\n\t\t\t\t$objWriter->writeAttribute('macro', '');\n\t\t\t\t$objWriter->startElement('xdr:nvGraphicFramePr');\n\t\t\t\t\t$objWriter->startElement('xdr:cNvPr');\n\t\t\t\t\t\t$objWriter->writeAttribute('name', 'Chart '.$pRelationId);\n\t\t\t\t\t\t$objWriter->writeAttribute('id', 1025 * $pRelationId);\n\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t$objWriter->startElement('xdr:cNvGraphicFramePr');\n\t\t\t\t\t\t$objWriter->startElement('a:graphicFrameLocks');\n\t\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t$objWriter->startElement('xdr:xfrm');\n\t\t\t\t\t$objWriter->startElement('a:off');\n\t\t\t\t\t\t$objWriter->writeAttribute('x', '0');\n\t\t\t\t\t\t$objWriter->writeAttribute('y', '0');\n\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t$objWriter->startElement('a:ext');\n\t\t\t\t\t\t$objWriter->writeAttribute('cx', '0');\n\t\t\t\t\t\t$objWriter->writeAttribute('cy', '0');\n\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t$objWriter->startElement('a:graphic');\n\t\t\t\t\t$objWriter->startElement('a:graphicData');\n\t\t\t\t\t\t$objWriter->writeAttribute('uri', 'http://schemas.openxmlformats.org/drawingml/2006/chart');\n\t\t\t\t\t\t$objWriter->startElement('c:chart');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('xmlns:c', 'http://schemas.openxmlformats.org/drawingml/2006/chart');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('r:id', 'rId'.$pRelationId);\n\t\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t$objWriter->endElement();\n\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->startElement('xdr:clientData');\n\t\t\t$objWriter->endElement();\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write drawings to XML format\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t\t\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_Worksheet_BaseDrawing\t\t$pDrawing\n\t * @param \tint\t\t\t\t\t\t\t\t\t$pRelationId\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function _writeDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet_BaseDrawing $pDrawing = null, $pRelationId = -1)\n\t{\n\t\tif ($pRelationId >= 0) {\n\t\t\t// xdr:oneCellAnchor\n\t\t\t$objWriter->startElement('xdr:oneCellAnchor');\n\t\t\t\t// Image location\n\t\t\t\t$aCoordinates \t\t= PHPExcel_Cell::coordinateFromString($pDrawing->getCoordinates());\n\t\t\t\t$aCoordinates[0] \t= PHPExcel_Cell::columnIndexFromString($aCoordinates[0]);\n\n\t\t\t\t// xdr:from\n\t\t\t\t$objWriter->startElement('xdr:from');\n\t\t\t\t\t$objWriter->writeElement('xdr:col', $aCoordinates[0] - 1);\n\t\t\t\t\t$objWriter->writeElement('xdr:colOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetX()));\n\t\t\t\t\t$objWriter->writeElement('xdr:row', $aCoordinates[1] - 1);\n\t\t\t\t\t$objWriter->writeElement('xdr:rowOff', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getOffsetY()));\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t// xdr:ext\n\t\t\t\t$objWriter->startElement('xdr:ext');\n\t\t\t\t\t$objWriter->writeAttribute('cx', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getWidth()));\n\t\t\t\t\t$objWriter->writeAttribute('cy', PHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getHeight()));\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t// xdr:pic\n\t\t\t\t$objWriter->startElement('xdr:pic');\n\n\t\t\t\t\t// xdr:nvPicPr\n\t\t\t\t\t$objWriter->startElement('xdr:nvPicPr');\n\n\t\t\t\t\t\t// xdr:cNvPr\n\t\t\t\t\t\t$objWriter->startElement('xdr:cNvPr');\n\t\t\t\t\t\t$objWriter->writeAttribute('id', $pRelationId);\n\t\t\t\t\t\t$objWriter->writeAttribute('name', $pDrawing->getName());\n\t\t\t\t\t\t$objWriter->writeAttribute('descr', $pDrawing->getDescription());\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// xdr:cNvPicPr\n\t\t\t\t\t\t$objWriter->startElement('xdr:cNvPicPr');\n\n\t\t\t\t\t\t\t// a:picLocks\n\t\t\t\t\t\t\t$objWriter->startElement('a:picLocks');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('noChangeAspect', '1');\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// xdr:blipFill\n\t\t\t\t\t$objWriter->startElement('xdr:blipFill');\n\n\t\t\t\t\t\t// a:blip\n\t\t\t\t\t\t$objWriter->startElement('a:blip');\n\t\t\t\t\t\t$objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');\n\t\t\t\t\t\t$objWriter->writeAttribute('r:embed', 'rId' . $pRelationId);\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// a:stretch\n\t\t\t\t\t\t$objWriter->startElement('a:stretch');\n\t\t\t\t\t\t\t$objWriter->writeElement('a:fillRect', null);\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// xdr:spPr\n\t\t\t\t\t$objWriter->startElement('xdr:spPr');\n\n\t\t\t\t\t\t// a:xfrm\n\t\t\t\t\t\t$objWriter->startElement('a:xfrm');\n\t\t\t\t\t\t$objWriter->writeAttribute('rot', PHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getRotation()));\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// a:prstGeom\n\t\t\t\t\t\t$objWriter->startElement('a:prstGeom');\n\t\t\t\t\t\t$objWriter->writeAttribute('prst', 'rect');\n\n\t\t\t\t\t\t\t// a:avLst\n\t\t\t\t\t\t\t$objWriter->writeElement('a:avLst', null);\n\n\t\t\t\t\t\t$objWriter->endElement();\n\n//\t\t\t\t\t\t// a:solidFill\n//\t\t\t\t\t\t$objWriter->startElement('a:solidFill');\n\n//\t\t\t\t\t\t\t// a:srgbClr\n//\t\t\t\t\t\t\t$objWriter->startElement('a:srgbClr');\n//\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'FFFFFF');\n\n///* SHADE\n//\t\t\t\t\t\t\t\t// a:shade\n//\t\t\t\t\t\t\t\t$objWriter->startElement('a:shade');\n//\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '85000');\n//\t\t\t\t\t\t\t\t$objWriter->endElement();\n//*/\n\n//\t\t\t\t\t\t\t$objWriter->endElement();\n\n//\t\t\t\t\t\t$objWriter->endElement();\n/*\n\t\t\t\t\t\t// a:ln\n\t\t\t\t\t\t$objWriter->startElement('a:ln');\n\t\t\t\t\t\t$objWriter->writeAttribute('w', '88900');\n\t\t\t\t\t\t$objWriter->writeAttribute('cap', 'sq');\n\n\t\t\t\t\t\t\t// a:solidFill\n\t\t\t\t\t\t\t$objWriter->startElement('a:solidFill');\n\n\t\t\t\t\t\t\t\t// a:srgbClr\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:srgbClr');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'FFFFFF');\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t// a:miter\n\t\t\t\t\t\t\t$objWriter->startElement('a:miter');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('lim', '800000');\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t$objWriter->endElement();\n*/\n\n\t\t\t\t\t\tif ($pDrawing->getShadow()->getVisible()) {\n\t\t\t\t\t\t\t// a:effectLst\n\t\t\t\t\t\t\t$objWriter->startElement('a:effectLst');\n\n\t\t\t\t\t\t\t\t// a:outerShdw\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:outerShdw');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('blurRad', \t\tPHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getBlurRadius()));\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('dist',\t\t\tPHPExcel_Shared_Drawing::pixelsToEMU($pDrawing->getShadow()->getDistance()));\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('dir',\t\t\tPHPExcel_Shared_Drawing::degreesToAngle($pDrawing->getShadow()->getDirection()));\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('algn',\t\t\t$pDrawing->getShadow()->getAlignment());\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('rotWithShape', \t'0');\n\n\t\t\t\t\t\t\t\t\t// a:srgbClr\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:srgbClr');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val',\t\t$pDrawing->getShadow()->getColor()->getRGB());\n\n\t\t\t\t\t\t\t\t\t\t// a:alpha\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:alpha');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', \t$pDrawing->getShadow()->getAlpha() * 1000);\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t\t}\n/*\n\n\t\t\t\t\t\t// a:scene3d\n\t\t\t\t\t\t$objWriter->startElement('a:scene3d');\n\n\t\t\t\t\t\t\t// a:camera\n\t\t\t\t\t\t\t$objWriter->startElement('a:camera');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('prst', 'orthographicFront');\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t// a:lightRig\n\t\t\t\t\t\t\t$objWriter->startElement('a:lightRig');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('rig', 'twoPt');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('dir', 't');\n\n\t\t\t\t\t\t\t\t// a:rot\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:rot');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('lat', '0');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('lon', '0');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('rev', '0');\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t$objWriter->endElement();\n*/\n/*\n\t\t\t\t\t\t// a:sp3d\n\t\t\t\t\t\t$objWriter->startElement('a:sp3d');\n\n\t\t\t\t\t\t\t// a:bevelT\n\t\t\t\t\t\t\t$objWriter->startElement('a:bevelT');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('w', '25400');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('h', '19050');\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t// a:contourClr\n\t\t\t\t\t\t\t$objWriter->startElement('a:contourClr');\n\n\t\t\t\t\t\t\t\t// a:srgbClr\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:srgbClr');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'FFFFFF');\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t$objWriter->endElement();\n*/\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t// xdr:clientData\n\t\t\t\t$objWriter->writeElement('xdr:clientData', null);\n\n\t\t\t$objWriter->endElement();\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Invalid parameters passed.\");\n\t\t}\n\t}\n\n\t/**\n\t * Write VML header/footer images to XML format\n\t *\n\t * @param \tPHPExcel_Worksheet\t\t\t\t$pWorksheet\n\t * @return \tstring \t\t\t\t\t\t\t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeVMLHeaderFooterImages(PHPExcel_Worksheet $pWorksheet = null)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n  \t\t// Header/footer images\n  \t\t$images = $pWorksheet->getHeaderFooter()->getImages();\n\n\t\t// xml\n\t\t$objWriter->startElement('xml');\n\t\t$objWriter->writeAttribute('xmlns:v', 'urn:schemas-microsoft-com:vml');\n\t\t$objWriter->writeAttribute('xmlns:o', 'urn:schemas-microsoft-com:office:office');\n\t\t$objWriter->writeAttribute('xmlns:x', 'urn:schemas-microsoft-com:office:excel');\n\n\t\t\t// o:shapelayout\n\t\t\t$objWriter->startElement('o:shapelayout');\n\t\t\t$objWriter->writeAttribute('v:ext', \t\t'edit');\n\n\t\t\t\t// o:idmap\n\t\t\t\t$objWriter->startElement('o:idmap');\n\t\t\t\t$objWriter->writeAttribute('v:ext', \t'edit');\n\t\t\t\t$objWriter->writeAttribute('data', \t\t'1');\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// v:shapetype\n\t\t\t$objWriter->startElement('v:shapetype');\n\t\t\t$objWriter->writeAttribute('id', \t\t\t\t\t'_x0000_t75');\n\t\t\t$objWriter->writeAttribute('coordsize', \t\t\t'21600,21600');\n\t\t\t$objWriter->writeAttribute('o:spt', \t\t\t\t'75');\n\t\t\t$objWriter->writeAttribute('o:preferrelative', \t\t't');\n\t\t\t$objWriter->writeAttribute('path', \t\t\t\t\t'm@4@5l@4@11@9@11@9@5xe');\n\t\t\t$objWriter->writeAttribute('filled',\t\t \t\t'f');\n\t\t\t$objWriter->writeAttribute('stroked',\t\t \t\t'f');\n\n\t\t\t\t// v:stroke\n\t\t\t\t$objWriter->startElement('v:stroke');\n\t\t\t\t$objWriter->writeAttribute('joinstyle', \t\t'miter');\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t// v:formulas\n\t\t\t\t$objWriter->startElement('v:formulas');\n\n\t\t\t\t\t// v:f\n\t\t\t\t\t$objWriter->startElement('v:f');\n\t\t\t\t\t$objWriter->writeAttribute('eqn', \t\t'if lineDrawn pixelLineWidth 0');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// v:f\n\t\t\t\t\t$objWriter->startElement('v:f');\n\t\t\t\t\t$objWriter->writeAttribute('eqn', \t\t'sum @0 1 0');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// v:f\n\t\t\t\t\t$objWriter->startElement('v:f');\n\t\t\t\t\t$objWriter->writeAttribute('eqn', \t\t'sum 0 0 @1');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// v:f\n\t\t\t\t\t$objWriter->startElement('v:f');\n\t\t\t\t\t$objWriter->writeAttribute('eqn', \t\t'prod @2 1 2');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// v:f\n\t\t\t\t\t$objWriter->startElement('v:f');\n\t\t\t\t\t$objWriter->writeAttribute('eqn', \t\t'prod @3 21600 pixelWidth');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// v:f\n\t\t\t\t\t$objWriter->startElement('v:f');\n\t\t\t\t\t$objWriter->writeAttribute('eqn', \t\t'prod @3 21600 pixelHeight');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// v:f\n\t\t\t\t\t$objWriter->startElement('v:f');\n\t\t\t\t\t$objWriter->writeAttribute('eqn', \t\t'sum @0 0 1');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// v:f\n\t\t\t\t\t$objWriter->startElement('v:f');\n\t\t\t\t\t$objWriter->writeAttribute('eqn', \t\t'prod @6 1 2');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// v:f\n\t\t\t\t\t$objWriter->startElement('v:f');\n\t\t\t\t\t$objWriter->writeAttribute('eqn', \t\t'prod @7 21600 pixelWidth');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// v:f\n\t\t\t\t\t$objWriter->startElement('v:f');\n\t\t\t\t\t$objWriter->writeAttribute('eqn', \t\t'sum @8 21600 0');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// v:f\n\t\t\t\t\t$objWriter->startElement('v:f');\n\t\t\t\t\t$objWriter->writeAttribute('eqn', \t\t'prod @7 21600 pixelHeight');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// v:f\n\t\t\t\t\t$objWriter->startElement('v:f');\n\t\t\t\t\t$objWriter->writeAttribute('eqn', \t\t'sum @10 21600 0');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t// v:path\n\t\t\t\t$objWriter->startElement('v:path');\n\t\t\t\t$objWriter->writeAttribute('o:extrusionok', \t'f');\n\t\t\t\t$objWriter->writeAttribute('gradientshapeok', \t't');\n\t\t\t\t$objWriter->writeAttribute('o:connecttype', \t'rect');\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t// o:lock\n\t\t\t\t$objWriter->startElement('o:lock');\n\t\t\t\t$objWriter->writeAttribute('v:ext', \t\t\t'edit');\n\t\t\t\t$objWriter->writeAttribute('aspectratio', \t\t't');\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// Loop through images\n\t\t\tforeach ($images as $key => $value) {\n\t\t\t\t$this->_writeVMLHeaderFooterImage($objWriter, $key, $value);\n\t\t\t}\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write VML comment to XML format\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t\t$objWriter \t\t\tXML Writer\n\t * @param\tstring\t\t\t\t\t\t\t$pReference\t\t\tReference\n\t * @param \tPHPExcel_Worksheet_HeaderFooterDrawing\t$pImage\t\tImage\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function _writeVMLHeaderFooterImage(PHPExcel_Shared_XMLWriter $objWriter = null, $pReference = '', PHPExcel_Worksheet_HeaderFooterDrawing $pImage = null)\n\t{\n\t\t// Calculate object id\n\t\tpreg_match('{(\\d+)}', md5($pReference), $m);\n\t\t$id = 1500 + (substr($m[1], 0, 2) * 1);\n\n\t\t// Calculate offset\n\t\t$width = $pImage->getWidth();\n\t\t$height = $pImage->getHeight();\n\t\t$marginLeft = $pImage->getOffsetX();\n\t\t$marginTop = $pImage->getOffsetY();\n\n\t\t// v:shape\n\t\t$objWriter->startElement('v:shape');\n\t\t$objWriter->writeAttribute('id', \t\t\t$pReference);\n\t\t$objWriter->writeAttribute('o:spid', \t\t'_x0000_s' . $id);\n\t\t$objWriter->writeAttribute('type', \t\t\t'#_x0000_t75');\n\t\t$objWriter->writeAttribute('style', \t\t\"position:absolute;margin-left:{$marginLeft}px;margin-top:{$marginTop}px;width:{$width}px;height:{$height}px;z-index:1\");\n\n\t\t\t// v:imagedata\n\t\t\t$objWriter->startElement('v:imagedata');\n\t\t\t$objWriter->writeAttribute('o:relid', \t\t'rId' . $pReference);\n\t\t\t$objWriter->writeAttribute('o:title', \t\t$pImage->getName());\n\t\t\t$objWriter->endElement();\n\n\t\t\t// o:lock\n\t\t\t$objWriter->startElement('o:lock');\n\t\t\t$objWriter->writeAttribute('v:ext', \t\t'edit');\n\t\t\t$objWriter->writeAttribute('rotation', \t\t't');\n\t\t\t$objWriter->endElement();\n\n\t\t$objWriter->endElement();\n\t}\n\n\n\t/**\n\t * Get an array of all drawings\n\t *\n\t * @param \tPHPExcel\t\t\t\t\t\t\t$pPHPExcel\n\t * @return \tPHPExcel_Worksheet_Drawing[]\t\tAll drawings in PHPExcel\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function allDrawings(PHPExcel $pPHPExcel = null)\n\t{\n\t\t// Get an array of all drawings\n\t\t$aDrawings\t= array();\n\n\t\t// Loop through PHPExcel\n\t\t$sheetCount = $pPHPExcel->getSheetCount();\n\t\tfor ($i = 0; $i < $sheetCount; ++$i) {\n\t\t\t// Loop through images and add to array\n\t\t\t$iterator = $pPHPExcel->getSheet($i)->getDrawingCollection()->getIterator();\n\t\t\twhile ($iterator->valid()) {\n\t\t\t\t$aDrawings[] = $iterator->current();\n\n  \t\t\t\t$iterator->next();\n\t\t\t}\n\t\t}\n\n\t\treturn $aDrawings;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Rels.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007_Rels\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007_Rels extends PHPExcel_Writer_Excel2007_WriterPart\n{\n\t/**\n\t * Write relationships to XML format\n\t *\n\t * @param \tPHPExcel\t$pPHPExcel\n\t * @return \tstring \t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeRelationships(PHPExcel $pPHPExcel = null)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// Relationships\n\t\t$objWriter->startElement('Relationships');\n\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');\n\n\t\t\t$customPropertyList = $pPHPExcel->getProperties()->getCustomProperties();\n\t\t\tif (!empty($customPropertyList)) {\n\t\t\t\t// Relationship docProps/app.xml\n\t\t\t\t$this->_writeRelationship(\n\t\t\t\t\t$objWriter,\n\t\t\t\t\t4,\n\t\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/custom-properties',\n\t\t\t\t\t'docProps/custom.xml'\n\t\t\t\t);\n\n\t\t\t}\n\n\t\t\t// Relationship docProps/app.xml\n\t\t\t$this->_writeRelationship(\n\t\t\t\t$objWriter,\n\t\t\t\t3,\n\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/extended-properties',\n\t\t\t\t'docProps/app.xml'\n\t\t\t);\n\n\t\t\t// Relationship docProps/core.xml\n\t\t\t$this->_writeRelationship(\n\t\t\t\t$objWriter,\n\t\t\t\t2,\n\t\t\t\t'http://schemas.openxmlformats.org/package/2006/relationships/metadata/core-properties',\n\t\t\t\t'docProps/core.xml'\n\t\t\t);\n\n\t\t\t// Relationship xl/workbook.xml\n\t\t\t$this->_writeRelationship(\n\t\t\t\t$objWriter,\n\t\t\t\t1,\n\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument',\n\t\t\t\t'xl/workbook.xml'\n\t\t\t);\n\t\t\t// a custom UI in workbook ?\n\t\t\tif($pPHPExcel->hasRibbon()){\n\t\t\t\t$this->_writeRelationShip(\n\t\t\t\t\t$objWriter,\n\t\t\t\t\t5,\n\t\t\t\t\t'http://schemas.microsoft.com/office/2006/relationships/ui/extensibility',\n\t\t\t\t\t$pPHPExcel->getRibbonXMLData('target')\n\t\t\t\t);\n\t\t\t}\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write workbook relationships to XML format\n\t *\n\t * @param \tPHPExcel\t$pPHPExcel\n\t * @return \tstring \t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeWorkbookRelationships(PHPExcel $pPHPExcel = null)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// Relationships\n\t\t$objWriter->startElement('Relationships');\n\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');\n\n\t\t\t// Relationship styles.xml\n\t\t\t$this->_writeRelationship(\n\t\t\t\t$objWriter,\n\t\t\t\t1,\n\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles',\n\t\t\t\t'styles.xml'\n\t\t\t);\n\n\t\t\t// Relationship theme/theme1.xml\n\t\t\t$this->_writeRelationship(\n\t\t\t\t$objWriter,\n\t\t\t\t2,\n\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/theme',\n\t\t\t\t'theme/theme1.xml'\n\t\t\t);\n\n\t\t\t// Relationship sharedStrings.xml\n\t\t\t$this->_writeRelationship(\n\t\t\t\t$objWriter,\n\t\t\t\t3,\n\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings',\n\t\t\t\t'sharedStrings.xml'\n\t\t\t);\n\n\t\t\t// Relationships with sheets\n\t\t\t$sheetCount = $pPHPExcel->getSheetCount();\n\t\t\tfor ($i = 0; $i < $sheetCount; ++$i) {\n\t\t\t\t$this->_writeRelationship(\n\t\t\t\t\t$objWriter,\n\t\t\t\t\t($i + 1 + 3),\n\t\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/worksheet',\n\t\t\t\t\t'worksheets/sheet' . ($i + 1) . '.xml'\n\t\t\t\t);\n\t\t\t}\n\t\t\t// Relationships for vbaProject if needed\n\t\t\t// id : just after the last sheet\n\t\t\tif($pPHPExcel->hasMacros()){\n\t\t\t\t$this->_writeRelationShip(\n\t\t\t\t\t$objWriter,\n\t\t\t\t\t($i + 1 + 3),\n\t\t\t\t\t'http://schemas.microsoft.com/office/2006/relationships/vbaProject',\n\t\t\t\t\t'vbaProject.bin'\n\t\t\t\t);\n\t\t\t\t++$i;//increment i if needed for an another relation\n\t\t\t}\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write worksheet relationships to XML format\n\t *\n\t * Numbering is as follows:\n\t * \trId1 \t\t\t\t- Drawings\n\t *  rId_hyperlink_x \t- Hyperlinks\n\t *\n\t * @param \tPHPExcel_Worksheet\t$pWorksheet\n\t * @param \tint\t\t\t\t\t$pWorksheetId\n\t * @param\tboolean\t\t\t\t$includeCharts\tFlag indicating if we should write charts\n\t * @return \tstring \t\t\t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeWorksheetRelationships(PHPExcel_Worksheet $pWorksheet = null, $pWorksheetId = 1, $includeCharts = FALSE)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// Relationships\n\t\t$objWriter->startElement('Relationships');\n\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');\n\n\t\t\t// Write drawing relationships?\n\t\t\t$d = 0;\n\t\t\tif ($includeCharts) {\n\t\t\t\t$charts = $pWorksheet->getChartCollection();\n\t\t\t} else {\n\t\t\t\t$charts = array();\n\t\t\t}\n\t\t\tif (($pWorksheet->getDrawingCollection()->count() > 0) ||\n\t\t\t\t(count($charts) > 0)) {\n\t\t\t\t$this->_writeRelationship(\n\t\t\t\t\t$objWriter,\n\t\t\t\t\t++$d,\n\t\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing',\n\t\t\t\t\t'../drawings/drawing' . $pWorksheetId . '.xml'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Write chart relationships?\n//\t\t\t$chartCount = 0;\n//\t\t\t$charts = $pWorksheet->getChartCollection();\n//\t\t\techo 'Chart Rels: ' , count($charts) , '<br />';\n//\t\t\tif (count($charts) > 0) {\n//\t\t\t\tforeach($charts as $chart) {\n//\t\t\t\t\t$this->_writeRelationship(\n//\t\t\t\t\t\t$objWriter,\n//\t\t\t\t\t\t++$d,\n//\t\t\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',\n//\t\t\t\t\t\t'../charts/chart' . ++$chartCount . '.xml'\n//\t\t\t\t\t);\n//\t\t\t\t}\n//\t\t\t}\n//\n\t\t\t// Write hyperlink relationships?\n\t\t\t$i = 1;\n\t\t\tforeach ($pWorksheet->getHyperlinkCollection() as $hyperlink) {\n\t\t\t\tif (!$hyperlink->isInternal()) {\n\t\t\t\t\t$this->_writeRelationship(\n\t\t\t\t\t\t$objWriter,\n\t\t\t\t\t\t'_hyperlink_' . $i,\n\t\t\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink',\n\t\t\t\t\t\t$hyperlink->getUrl(),\n\t\t\t\t\t\t'External'\n\t\t\t\t\t);\n\n\t\t\t\t\t++$i;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Write comments relationship?\n\t\t\t$i = 1;\n\t\t\tif (count($pWorksheet->getComments()) > 0) {\n\t\t\t\t$this->_writeRelationship(\n\t\t\t\t\t$objWriter,\n\t\t\t\t\t'_comments_vml' . $i,\n\t\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing',\n\t\t\t\t\t'../drawings/vmlDrawing' . $pWorksheetId . '.vml'\n\t\t\t\t);\n\n\t\t\t\t$this->_writeRelationship(\n\t\t\t\t\t$objWriter,\n\t\t\t\t\t'_comments' . $i,\n\t\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments',\n\t\t\t\t\t'../comments' . $pWorksheetId . '.xml'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\t// Write header/footer relationship?\n\t\t\t$i = 1;\n\t\t\tif (count($pWorksheet->getHeaderFooter()->getImages()) > 0) {\n\t\t\t\t$this->_writeRelationship(\n\t\t\t\t\t$objWriter,\n\t\t\t\t\t'_headerfooter_vml' . $i,\n\t\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing',\n\t\t\t\t\t'../drawings/vmlDrawingHF' . $pWorksheetId . '.vml'\n\t\t\t\t);\n\t\t\t}\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write drawing relationships to XML format\n\t *\n\t * @param \tPHPExcel_Worksheet\t$pWorksheet\n\t * @param\tint\t\t\t\t\t&$chartRef\t\tChart ID\n\t * @param\tboolean\t\t\t\t$includeCharts\tFlag indicating if we should write charts\n\t * @return \tstring \t\t\t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null, &$chartRef, $includeCharts = FALSE)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// Relationships\n\t\t$objWriter->startElement('Relationships');\n\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');\n\n\t\t\t// Loop through images and write relationships\n\t\t\t$i = 1;\n\t\t\t$iterator = $pWorksheet->getDrawingCollection()->getIterator();\n\t\t\twhile ($iterator->valid()) {\n\t\t\t\tif ($iterator->current() instanceof PHPExcel_Worksheet_Drawing\n\t\t\t\t\t|| $iterator->current() instanceof PHPExcel_Worksheet_MemoryDrawing) {\n\t\t\t\t\t// Write relationship for image drawing\n\t\t\t\t\t$this->_writeRelationship(\n\t\t\t\t\t\t$objWriter,\n\t\t\t\t\t\t$i,\n\t\t\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',\n\t\t\t\t\t\t'../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename())\n\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t$iterator->next();\n\t\t\t\t++$i;\n\t\t\t}\n\n\t\t\tif ($includeCharts) {\n\t\t\t\t// Loop through charts and write relationships\n\t\t\t\t$chartCount = $pWorksheet->getChartCount();\n\t\t\t\tif ($chartCount > 0) {\n\t\t\t\t\tfor ($c = 0; $c < $chartCount; ++$c) {\n\t\t\t\t\t\t$this->_writeRelationship(\n\t\t\t\t\t\t\t$objWriter,\n\t\t\t\t\t\t\t$i++,\n\t\t\t\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart',\n\t\t\t\t\t\t\t'../charts/chart' . ++$chartRef . '.xml'\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write header/footer drawing relationships to XML format\n\t *\n\t * @param \tPHPExcel_Worksheet\t\t\t$pWorksheet\n\t * @return \tstring \t\t\t\t\t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeHeaderFooterDrawingRelationships(PHPExcel_Worksheet $pWorksheet = null)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// Relationships\n\t\t$objWriter->startElement('Relationships');\n\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');\n\n\t\t\t// Loop through images and write relationships\n\t\t\tforeach ($pWorksheet->getHeaderFooter()->getImages() as $key => $value) {\n\t\t\t\t// Write relationship for image drawing\n\t\t\t\t$this->_writeRelationship(\n\t\t\t\t\t$objWriter,\n\t\t\t\t\t$key,\n\t\t\t\t\t'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image',\n\t\t\t\t\t'../media/' . $value->getIndexedFilename()\n\t\t\t\t);\n\t\t\t}\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write Override content type\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter \t$objWriter \t\tXML Writer\n\t * @param \tint\t\t\t\t\t\t\t$pId\t\t\tRelationship ID. rId will be prepended!\n\t * @param \tstring\t\t\t\t\t\t$pType\t\t\tRelationship type\n\t * @param \tstring \t\t\t\t\t\t$pTarget\t\tRelationship target\n\t * @param \tstring \t\t\t\t\t\t$pTargetMode\tRelationship target mode\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeRelationship(PHPExcel_Shared_XMLWriter $objWriter = null, $pId = 1, $pType = '', $pTarget = '', $pTargetMode = '')\n\t{\n\t\tif ($pType != '' && $pTarget != '') {\n\t\t\t// Write relationship\n\t\t\t$objWriter->startElement('Relationship');\n\t\t\t$objWriter->writeAttribute('Id', \t\t'rId' . $pId);\n\t\t\t$objWriter->writeAttribute('Type', \t\t$pType);\n\t\t\t$objWriter->writeAttribute('Target',\t$pTarget);\n\n\t\t\tif ($pTargetMode != '') {\n\t\t\t\t$objWriter->writeAttribute('TargetMode',\t$pTargetMode);\n\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Invalid parameters passed.\");\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/RelsRibbon.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version     ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007_RelsRibbon\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007_RelsRibbon extends PHPExcel_Writer_Excel2007_WriterPart\n{\n\t/**\n\t * Write relationships for additional objects of custom UI (ribbon)\n\t *\n\t * @param \tPHPExcel\t$pPHPExcel\n\t * @return \tstring \t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeRibbonRelationships(PHPExcel $pPHPExcel = null){\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// Relationships\n\t\t$objWriter->startElement('Relationships');\n\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');\n\t\t$localRels=$pPHPExcel->getRibbonBinObjects('names');\n\t\tif(is_array($localRels)){\n\t\t\tforeach($localRels as $aId=>$aTarget){\n\t\t\t\t$objWriter->startElement('Relationship');\n\t\t\t\t$objWriter->writeAttribute('Id', $aId);\n\t\t\t\t$objWriter->writeAttribute('Type', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image');\n\t\t\t\t$objWriter->writeAttribute('Target', $aTarget);\n\t\t\t\t$objWriter->endElement();//Relationship\n\t\t\t}\n\t\t}\n\t\t$objWriter->endElement();//Relationships\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/RelsVBA.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version     ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007_RelsVBA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007_RelsVBA extends PHPExcel_Writer_Excel2007_WriterPart\n{\n\t/**\n\t * Write relationships for a signed VBA Project\n\t *\n\t * @param \tPHPExcel\t$pPHPExcel\n\t * @return \tstring \t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeVBARelationships(PHPExcel $pPHPExcel = null){\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// Relationships\n\t\t$objWriter->startElement('Relationships');\n\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/package/2006/relationships');\n\t\t$objWriter->startElement('Relationship');\n\t\t$objWriter->writeAttribute('Id', 'rId1');\n\t\t$objWriter->writeAttribute('Type', 'http://schemas.microsoft.com/office/2006/relationships/vbaProjectSignature');\n\t\t$objWriter->writeAttribute('Target', 'vbaProjectSignature.bin');\n\t\t$objWriter->endElement();//Relationship\n\t\t$objWriter->endElement();//Relationships\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/StringTable.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007_StringTable\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007_StringTable extends PHPExcel_Writer_Excel2007_WriterPart\n{\n\t/**\n\t * Create worksheet stringtable\n\t *\n\t * @param \tPHPExcel_Worksheet \t$pSheet\t\t\t\tWorksheet\n\t * @param \tstring[] \t\t\t\t$pExistingTable \tExisting table to eventually merge with\n\t * @return \tstring[] \t\t\t\tString table for worksheet\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function createStringTable($pSheet = null, $pExistingTable = null)\n\t{\n\t\tif ($pSheet !== NULL) {\n\t\t\t// Create string lookup table\n\t\t\t$aStringTable = array();\n\t\t\t$cellCollection = null;\n\t\t\t$aFlippedStringTable = null;\t// For faster lookup\n\n\t\t\t// Is an existing table given?\n\t\t\tif (($pExistingTable !== NULL) && is_array($pExistingTable)) {\n\t\t\t\t$aStringTable = $pExistingTable;\n\t\t\t}\n\n\t\t\t// Fill index array\n\t\t\t$aFlippedStringTable = $this->flipStringTable($aStringTable);\n\n\t\t\t// Loop through cells\n\t\t\tforeach ($pSheet->getCellCollection() as $cellID) {\n\t\t\t\t$cell = $pSheet->getCell($cellID);\n\t\t\t\t$cellValue = $cell->getValue();\n\t\t\t\tif (!is_object($cellValue) &&\n\t\t\t\t\t($cellValue !== NULL) &&\n\t\t\t\t\t$cellValue !== '' &&\n\t\t\t\t\t!isset($aFlippedStringTable[$cellValue]) &&\n\t\t\t\t\t($cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_STRING2 || $cell->getDataType() == PHPExcel_Cell_DataType::TYPE_NULL)) {\n\t\t\t\t\t\t$aStringTable[] = $cellValue;\n\t\t\t\t\t\t$aFlippedStringTable[$cellValue] = true;\n\t\t\t\t} elseif ($cellValue instanceof PHPExcel_RichText &&\n\t\t\t\t\t\t  ($cellValue !== NULL) &&\n\t\t\t\t\t\t  !isset($aFlippedStringTable[$cellValue->getHashCode()])) {\n\t\t\t\t\t\t\t\t$aStringTable[] = $cellValue;\n\t\t\t\t\t\t\t\t$aFlippedStringTable[$cellValue->getHashCode()] = true;\n\t        \t}\n\t        }\n\n\t        // Return\n\t        return $aStringTable;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Invalid PHPExcel_Worksheet object passed.\");\n\t\t}\n\t}\n\n\t/**\n\t * Write string table to XML format\n\t *\n\t * @param \tstring[] \t$pStringTable\n\t * @return \tstring \t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeStringTable($pStringTable = null)\n\t{\n\t\tif ($pStringTable !== NULL) {\n\t\t\t// Create XML writer\n\t\t\t$objWriter = null;\n\t\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t\t} else {\n\t\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t\t}\n\n\t\t\t// XML header\n\t\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t\t// String table\n\t\t\t$objWriter->startElement('sst');\n\t\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');\n\t\t\t$objWriter->writeAttribute('uniqueCount', count($pStringTable));\n\n\t\t\t\t// Loop through string table\n\t\t\t\tforeach ($pStringTable as $textElement) {\n\t\t\t\t\t$objWriter->startElement('si');\n\n\t\t\t\t\t\tif (! $textElement instanceof PHPExcel_RichText) {\n\t\t\t\t\t\t\t$textToWrite = PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $textElement );\n\t\t\t\t\t\t\t$objWriter->startElement('t');\n\t\t\t\t\t\t\tif ($textToWrite !== trim($textToWrite)) {\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('xml:space', 'preserve');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$objWriter->writeRawData($textToWrite);\n\t\t\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t\t} else if ($textElement instanceof PHPExcel_RichText) {\n\t\t\t\t\t\t\t$this->writeRichText($objWriter, $textElement);\n\t\t\t\t\t\t}\n\n                    $objWriter->endElement();\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// Return\n\t\t\treturn $objWriter->getData();\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Invalid string table array passed.\");\n\t\t}\n\t}\n\n\t/**\n\t * Write Rich Text\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_RichText\t\t\t$pRichText\t\tRich text\n\t * @param \tstring\t\t\t\t\t\t$prefix\t\t\tOptional Namespace prefix\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeRichText(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_RichText $pRichText = null, $prefix=NULL)\n\t{\n\t\tif ($prefix !== NULL)\n\t\t\t$prefix .= ':';\n\t\t// Loop through rich text elements\n\t\t$elements = $pRichText->getRichTextElements();\n\t\tforeach ($elements as $element) {\n\t\t\t// r\n\t\t\t$objWriter->startElement($prefix.'r');\n\n\t\t\t\t// rPr\n\t\t\t\tif ($element instanceof PHPExcel_RichText_Run) {\n\t\t\t\t\t// rPr\n\t\t\t\t\t$objWriter->startElement($prefix.'rPr');\n\n\t\t\t\t\t\t// rFont\n\t\t\t\t\t\t$objWriter->startElement($prefix.'rFont');\n\t\t\t\t\t\t$objWriter->writeAttribute('val', $element->getFont()->getName());\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// Bold\n\t\t\t\t\t\t$objWriter->startElement($prefix.'b');\n\t\t\t\t\t\t$objWriter->writeAttribute('val', ($element->getFont()->getBold() ? 'true' : 'false'));\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// Italic\n\t\t\t\t\t\t$objWriter->startElement($prefix.'i');\n\t\t\t\t\t\t$objWriter->writeAttribute('val', ($element->getFont()->getItalic() ? 'true' : 'false'));\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// Superscript / subscript\n\t\t\t\t\t\tif ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) {\n\t\t\t\t\t\t\t$objWriter->startElement($prefix.'vertAlign');\n\t\t\t\t\t\t\tif ($element->getFont()->getSuperScript()) {\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'superscript');\n\t\t\t\t\t\t\t} else if ($element->getFont()->getSubScript()) {\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'subscript');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Strikethrough\n\t\t\t\t\t\t$objWriter->startElement($prefix.'strike');\n\t\t\t\t\t\t$objWriter->writeAttribute('val', ($element->getFont()->getStrikethrough() ? 'true' : 'false'));\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// Color\n\t\t\t\t\t\t$objWriter->startElement($prefix.'color');\n\t\t\t\t\t\t$objWriter->writeAttribute('rgb', $element->getFont()->getColor()->getARGB());\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// Size\n\t\t\t\t\t\t$objWriter->startElement($prefix.'sz');\n\t\t\t\t\t\t$objWriter->writeAttribute('val', $element->getFont()->getSize());\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// Underline\n\t\t\t\t\t\t$objWriter->startElement($prefix.'u');\n\t\t\t\t\t\t$objWriter->writeAttribute('val', $element->getFont()->getUnderline());\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t}\n\n\t\t\t\t// t\n\t\t\t\t$objWriter->startElement($prefix.'t');\n\t\t\t\t$objWriter->writeAttribute('xml:space', 'preserve');\n\t\t\t\t$objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $element->getText() ));\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write Rich Text\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t$objWriter \t\tXML Writer\n\t * @param \tstring|PHPExcel_RichText\t$pRichText\t\ttext string or Rich text\n\t * @param \tstring\t\t\t\t\t\t$prefix\t\t\tOptional Namespace prefix\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeRichTextForCharts(PHPExcel_Shared_XMLWriter $objWriter = null, $pRichText = null, $prefix=NULL)\n\t{\n\t\tif (!$pRichText instanceof PHPExcel_RichText) {\n\t\t\t$textRun = $pRichText;\n\t\t\t$pRichText = new PHPExcel_RichText();\n\t\t\t$pRichText->createTextRun($textRun);\n\t\t}\n\n\t\tif ($prefix !== NULL)\n\t\t\t$prefix .= ':';\n\t\t// Loop through rich text elements\n\t\t$elements = $pRichText->getRichTextElements();\n\t\tforeach ($elements as $element) {\n\t\t\t// r\n\t\t\t$objWriter->startElement($prefix.'r');\n\n\t\t\t\t// rPr\n\t\t\t\t$objWriter->startElement($prefix.'rPr');\n\n\t\t\t\t\t// Bold\n\t\t\t\t\t$objWriter->writeAttribute('b', ($element->getFont()->getBold() ? 1 : 0));\n\t\t\t\t\t// Italic\n\t\t\t\t\t$objWriter->writeAttribute('i', ($element->getFont()->getItalic() ? 1 : 0));\n\t\t\t\t\t// Underline\n\t\t\t\t\t$underlineType = $element->getFont()->getUnderline();\n\t\t\t\t\tswitch($underlineType) {\n\t\t\t\t\t\tcase 'single' :\n\t\t\t\t\t\t\t$underlineType = 'sng';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t\tcase 'double' :\n\t\t\t\t\t\t\t$underlineType = 'dbl';\n\t\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\t$objWriter->writeAttribute('u', $underlineType);\n\t\t\t\t\t// Strikethrough\n\t\t\t\t\t$objWriter->writeAttribute('strike', ($element->getFont()->getStrikethrough() ? 'sngStrike' : 'noStrike'));\n\n\t\t\t\t\t// rFont\n\t\t\t\t\t$objWriter->startElement($prefix.'latin');\n\t\t\t\t\t\t$objWriter->writeAttribute('typeface', $element->getFont()->getName());\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// Superscript / subscript\n//\t\t\t\t\tif ($element->getFont()->getSuperScript() || $element->getFont()->getSubScript()) {\n//\t\t\t\t\t\t$objWriter->startElement($prefix.'vertAlign');\n//\t\t\t\t\t\tif ($element->getFont()->getSuperScript()) {\n//\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'superscript');\n//\t\t\t\t\t\t} else if ($element->getFont()->getSubScript()) {\n//\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'subscript');\n//\t\t\t\t\t\t}\n//\t\t\t\t\t\t$objWriter->endElement();\n//\t\t\t\t\t}\n//\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t// t\n\t\t\t\t$objWriter->startElement($prefix.'t');\n//\t\t\t\t\t$objWriter->writeAttribute('xml:space', 'preserve');\t//\tExcel2010 accepts, Excel2007 complains\n\t\t\t\t\t$objWriter->writeRawData(PHPExcel_Shared_String::ControlCharacterPHP2OOXML( $element->getText() ));\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Flip string table (for index searching)\n\t *\n\t * @param \tarray\t$stringTable\tStringtable\n\t * @return \tarray\n\t */\n\tpublic function flipStringTable($stringTable = array()) {\n\t\t// Return value\n\t\t$returnValue = array();\n\n\t\t// Loop through stringtable and add flipped items to $returnValue\n\t\tforeach ($stringTable as $key => $value) {\n\t\t\tif (! $value instanceof PHPExcel_RichText) {\n\t\t\t\t$returnValue[$value] = $key;\n\t\t\t} else if ($value instanceof PHPExcel_RichText) {\n\t\t\t\t$returnValue[$value->getHashCode()] = $key;\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $returnValue;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Style.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007_Style\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007_Style extends PHPExcel_Writer_Excel2007_WriterPart\n{\n\t/**\n\t * Write styles to XML format\n\t *\n\t * @param \tPHPExcel\t$pPHPExcel\n\t * @return \tstring \t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeStyles(PHPExcel $pPHPExcel = null)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// styleSheet\n\t\t$objWriter->startElement('styleSheet');\n\t\t$objWriter->writeAttribute('xml:space', 'preserve');\n\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');\n\n\t\t\t// numFmts\n\t\t\t$objWriter->startElement('numFmts');\n\t\t\t$objWriter->writeAttribute('count', $this->getParentWriter()->getNumFmtHashTable()->count());\n\n\t\t\t\t// numFmt\n\t\t\t\tfor ($i = 0; $i < $this->getParentWriter()->getNumFmtHashTable()->count(); ++$i) {\n\t\t\t\t\t$this->_writeNumFmt($objWriter, $this->getParentWriter()->getNumFmtHashTable()->getByIndex($i), $i);\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// fonts\n\t\t\t$objWriter->startElement('fonts');\n\t\t\t$objWriter->writeAttribute('count', $this->getParentWriter()->getFontHashTable()->count());\n\n\t\t\t\t// font\n\t\t\t\tfor ($i = 0; $i < $this->getParentWriter()->getFontHashTable()->count(); ++$i) {\n\t\t\t\t\t$this->_writeFont($objWriter, $this->getParentWriter()->getFontHashTable()->getByIndex($i));\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// fills\n\t\t\t$objWriter->startElement('fills');\n\t\t\t$objWriter->writeAttribute('count', $this->getParentWriter()->getFillHashTable()->count());\n\n\t\t\t\t// fill\n\t\t\t\tfor ($i = 0; $i < $this->getParentWriter()->getFillHashTable()->count(); ++$i) {\n\t\t\t\t\t$this->_writeFill($objWriter, $this->getParentWriter()->getFillHashTable()->getByIndex($i));\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// borders\n\t\t\t$objWriter->startElement('borders');\n\t\t\t$objWriter->writeAttribute('count', $this->getParentWriter()->getBordersHashTable()->count());\n\n\t\t\t\t// border\n\t\t\t\tfor ($i = 0; $i < $this->getParentWriter()->getBordersHashTable()->count(); ++$i) {\n\t\t\t\t\t$this->_writeBorder($objWriter, $this->getParentWriter()->getBordersHashTable()->getByIndex($i));\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// cellStyleXfs\n\t\t\t$objWriter->startElement('cellStyleXfs');\n\t\t\t$objWriter->writeAttribute('count', 1);\n\n\t\t\t\t// xf\n\t\t\t\t$objWriter->startElement('xf');\n\t\t\t\t\t$objWriter->writeAttribute('numFmtId', \t0);\n\t\t\t\t\t$objWriter->writeAttribute('fontId', \t0);\n\t\t\t\t\t$objWriter->writeAttribute('fillId', \t0);\n\t\t\t\t\t$objWriter->writeAttribute('borderId',\t0);\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// cellXfs\n\t\t\t$objWriter->startElement('cellXfs');\n\t\t\t$objWriter->writeAttribute('count', count($pPHPExcel->getCellXfCollection()));\n\n\t\t\t\t// xf\n\t\t\t\tforeach ($pPHPExcel->getCellXfCollection() as $cellXf) {\n\t\t\t\t\t$this->_writeCellStyleXf($objWriter, $cellXf, $pPHPExcel);\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// cellStyles\n\t\t\t$objWriter->startElement('cellStyles');\n\t\t\t$objWriter->writeAttribute('count', 1);\n\n\t\t\t\t// cellStyle\n\t\t\t\t$objWriter->startElement('cellStyle');\n\t\t\t\t\t$objWriter->writeAttribute('name', \t\t'Normal');\n\t\t\t\t\t$objWriter->writeAttribute('xfId', \t\t0);\n\t\t\t\t\t$objWriter->writeAttribute('builtinId',\t0);\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// dxfs\n\t\t\t$objWriter->startElement('dxfs');\n\t\t\t$objWriter->writeAttribute('count', $this->getParentWriter()->getStylesConditionalHashTable()->count());\n\n\t\t\t\t// dxf\n\t\t\t\tfor ($i = 0; $i < $this->getParentWriter()->getStylesConditionalHashTable()->count(); ++$i) {\n\t\t\t\t\t$this->_writeCellStyleDxf($objWriter, $this->getParentWriter()->getStylesConditionalHashTable()->getByIndex($i)->getStyle());\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// tableStyles\n\t\t\t$objWriter->startElement('tableStyles');\n\t\t\t$objWriter->writeAttribute('defaultTableStyle', 'TableStyleMedium9');\n\t\t\t$objWriter->writeAttribute('defaultPivotStyle', 'PivotTableStyle1');\n\t\t\t$objWriter->endElement();\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write Fill\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter \t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_Style_Fill\t\t\t$pFill\t\t\tFill style\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null)\n\t{\n\t\t// Check if this is a pattern type or gradient type\n\t\tif ($pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR ||\n\t\t\t$pFill->getFillType() === PHPExcel_Style_Fill::FILL_GRADIENT_PATH) {\n\t\t\t// Gradient fill\n\t\t\t$this->_writeGradientFill($objWriter, $pFill);\n\t\t} elseif($pFill->getFillType() !== NULL) {\n\t\t\t// Pattern fill\n\t\t\t$this->_writePatternFill($objWriter, $pFill);\n\t\t}\n\t}\n\n\t/**\n\t * Write Gradient Fill\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter \t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_Style_Fill\t\t\t$pFill\t\t\tFill style\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeGradientFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null)\n\t{\n\t\t// fill\n\t\t$objWriter->startElement('fill');\n\n\t\t\t// gradientFill\n\t\t\t$objWriter->startElement('gradientFill');\n\t\t\t\t$objWriter->writeAttribute('type', \t\t$pFill->getFillType());\n\t\t\t\t$objWriter->writeAttribute('degree', \t$pFill->getRotation());\n\n\t\t\t\t// stop\n\t\t\t\t$objWriter->startElement('stop');\n\t\t\t\t$objWriter->writeAttribute('position', '0');\n\n\t\t\t\t\t// color\n\t\t\t\t\t$objWriter->startElement('color');\n\t\t\t\t\t$objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB());\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t// stop\n\t\t\t\t$objWriter->startElement('stop');\n\t\t\t\t$objWriter->writeAttribute('position', '1');\n\n\t\t\t\t\t// color\n\t\t\t\t\t$objWriter->startElement('color');\n\t\t\t\t\t$objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB());\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write Pattern Fill\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t\t\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_Style_Fill\t\t\t\t\t$pFill\t\t\tFill style\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writePatternFill(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Fill $pFill = null)\n\t{\n\t\t// fill\n\t\t$objWriter->startElement('fill');\n\n\t\t\t// patternFill\n\t\t\t$objWriter->startElement('patternFill');\n\t\t\t\t$objWriter->writeAttribute('patternType', $pFill->getFillType());\n\n\t\t\t\tif ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) {\n\t\t\t\t\t// fgColor\n\t\t\t\t\tif ($pFill->getStartColor()->getARGB()) {\n\t\t\t\t\t\t$objWriter->startElement('fgColor');\n\t\t\t\t\t\t$objWriter->writeAttribute('rgb', $pFill->getStartColor()->getARGB());\n\t\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif ($pFill->getFillType() !== PHPExcel_Style_Fill::FILL_NONE) {\n\t\t\t\t\t// bgColor\n\t\t\t\t\tif ($pFill->getEndColor()->getARGB()) {\n\t\t\t\t\t\t$objWriter->startElement('bgColor');\n\t\t\t\t\t\t$objWriter->writeAttribute('rgb', $pFill->getEndColor()->getARGB());\n\t\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write Font\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_Style_Font\t\t\t\t$pFont\t\t\tFont style\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeFont(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Font $pFont = null)\n\t{\n\t\t// font\n\t\t$objWriter->startElement('font');\n\t\t\t//\tWeird! The order of these elements actually makes a difference when opening Excel2007\n\t\t\t//\t\tfiles in Excel2003 with the compatibility pack. It's not documented behaviour,\n\t\t\t//\t\tand makes for a real WTF!\n\n\t\t\t// Bold. We explicitly write this element also when false (like MS Office Excel 2007 does\n\t\t\t// for conditional formatting). Otherwise it will apparently not be picked up in conditional\n\t\t\t// formatting style dialog\n\t\t\tif ($pFont->getBold() !== NULL) {\n\t\t\t\t$objWriter->startElement('b');\n\t\t\t\t\t$objWriter->writeAttribute('val', $pFont->getBold() ? '1' : '0');\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\t\t\t// Italic\n\t\t\tif ($pFont->getItalic() !== NULL) {\n\t\t\t\t$objWriter->startElement('i');\n\t\t\t\t\t$objWriter->writeAttribute('val', $pFont->getItalic() ? '1' : '0');\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\t\t\t// Strikethrough\n\t\t\tif ($pFont->getStrikethrough() !== NULL) {\n\t\t\t\t$objWriter->startElement('strike');\n\t\t\t\t$objWriter->writeAttribute('val', $pFont->getStrikethrough() ? '1' : '0');\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\t\t\t// Underline\n\t\t\tif ($pFont->getUnderline() !== NULL) {\n\t\t\t\t$objWriter->startElement('u');\n\t\t\t\t$objWriter->writeAttribute('val', $pFont->getUnderline());\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\t\t\t// Superscript / subscript\n\t\t\tif ($pFont->getSuperScript() === TRUE || $pFont->getSubScript() === TRUE) {\n\t\t\t\t$objWriter->startElement('vertAlign');\n\t\t\t\tif ($pFont->getSuperScript() === TRUE) {\n\t\t\t\t\t$objWriter->writeAttribute('val', 'superscript');\n\t\t\t\t} else if ($pFont->getSubScript() === TRUE) {\n\t\t\t\t\t$objWriter->writeAttribute('val', 'subscript');\n\t\t\t\t}\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\t\t\t// Size\n\t\t\tif ($pFont->getSize() !== NULL) {\n\t\t\t\t$objWriter->startElement('sz');\n\t\t\t\t\t$objWriter->writeAttribute('val', $pFont->getSize());\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\t\t\t// Foreground color\n\t\t\tif ($pFont->getColor()->getARGB() !== NULL) {\n\t\t\t\t$objWriter->startElement('color');\n\t\t\t\t$objWriter->writeAttribute('rgb', $pFont->getColor()->getARGB());\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\t\t\t// Name\n\t\t\tif ($pFont->getName() !== NULL) {\n\t\t\t\t$objWriter->startElement('name');\n\t\t\t\t\t$objWriter->writeAttribute('val', $pFont->getName());\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write Border\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t\t\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_Style_Borders\t\t\t\t$pBorders\t\tBorders style\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeBorder(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_Borders $pBorders = null)\n\t{\n\t\t// Write border\n\t\t$objWriter->startElement('border');\n\t\t\t// Diagonal?\n\t\t\tswitch ($pBorders->getDiagonalDirection()) {\n\t\t\t\tcase PHPExcel_Style_Borders::DIAGONAL_UP:\n\t\t\t\t\t$objWriter->writeAttribute('diagonalUp', \t'true');\n\t\t\t\t\t$objWriter->writeAttribute('diagonalDown', \t'false');\n\t\t\t\t\tbreak;\n\t\t\t\tcase PHPExcel_Style_Borders::DIAGONAL_DOWN:\n\t\t\t\t\t$objWriter->writeAttribute('diagonalUp', \t'false');\n\t\t\t\t\t$objWriter->writeAttribute('diagonalDown', \t'true');\n\t\t\t\t\tbreak;\n\t\t\t\tcase PHPExcel_Style_Borders::DIAGONAL_BOTH:\n\t\t\t\t\t$objWriter->writeAttribute('diagonalUp', \t'true');\n\t\t\t\t\t$objWriter->writeAttribute('diagonalDown', \t'true');\n\t\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// BorderPr\n\t\t\t$this->_writeBorderPr($objWriter, 'left',\t\t$pBorders->getLeft());\n\t\t\t$this->_writeBorderPr($objWriter, 'right',\t\t$pBorders->getRight());\n\t\t\t$this->_writeBorderPr($objWriter, 'top',\t\t$pBorders->getTop());\n\t\t\t$this->_writeBorderPr($objWriter, 'bottom',\t\t$pBorders->getBottom());\n\t\t\t$this->_writeBorderPr($objWriter, 'diagonal',\t$pBorders->getDiagonal());\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write Cell Style Xf\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t\t\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_Style\t\t\t\t\t\t$pStyle\t\t\tStyle\n\t * @param \tPHPExcel\t\t\t\t\t\t\t$pPHPExcel\t\tWorkbook\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeCellStyleXf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null, PHPExcel $pPHPExcel = null)\n\t{\n\t\t// xf\n\t\t$objWriter->startElement('xf');\n\t\t\t$objWriter->writeAttribute('xfId', 0);\n\t\t\t$objWriter->writeAttribute('fontId', \t\t\t(int)$this->getParentWriter()->getFontHashTable()->getIndexForHashCode($pStyle->getFont()->getHashCode()));\n            if ($pStyle->getQuotePrefix()) {\n                $objWriter->writeAttribute('quotePrefix', \t    1);\n            }\n\n\t\t\tif ($pStyle->getNumberFormat()->getBuiltInFormatCode() === false) {\n\t\t\t\t$objWriter->writeAttribute('numFmtId', \t\t\t(int)($this->getParentWriter()->getNumFmtHashTable()->getIndexForHashCode($pStyle->getNumberFormat()->getHashCode()) + 164)   );\n\t\t\t} else {\n\t\t\t\t$objWriter->writeAttribute('numFmtId', \t\t\t(int)$pStyle->getNumberFormat()->getBuiltInFormatCode());\n\t\t\t}\n\n\t\t\t$objWriter->writeAttribute('fillId', \t\t\t(int)$this->getParentWriter()->getFillHashTable()->getIndexForHashCode($pStyle->getFill()->getHashCode()));\n\t\t\t$objWriter->writeAttribute('borderId', \t\t\t(int)$this->getParentWriter()->getBordersHashTable()->getIndexForHashCode($pStyle->getBorders()->getHashCode()));\n\n\t\t\t// Apply styles?\n\t\t\t$objWriter->writeAttribute('applyFont', \t\t($pPHPExcel->getDefaultStyle()->getFont()->getHashCode() != $pStyle->getFont()->getHashCode()) ? '1' : '0');\n\t\t\t$objWriter->writeAttribute('applyNumberFormat', ($pPHPExcel->getDefaultStyle()->getNumberFormat()->getHashCode() != $pStyle->getNumberFormat()->getHashCode()) ? '1' : '0');\n\t\t\t$objWriter->writeAttribute('applyFill', \t\t($pPHPExcel->getDefaultStyle()->getFill()->getHashCode() != $pStyle->getFill()->getHashCode()) ? '1' : '0');\n\t\t\t$objWriter->writeAttribute('applyBorder', \t\t($pPHPExcel->getDefaultStyle()->getBorders()->getHashCode() != $pStyle->getBorders()->getHashCode()) ? '1' : '0');\n\t\t\t$objWriter->writeAttribute('applyAlignment',\t($pPHPExcel->getDefaultStyle()->getAlignment()->getHashCode() != $pStyle->getAlignment()->getHashCode()) ? '1' : '0');\n\t\t\tif ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) {\n\t\t\t\t$objWriter->writeAttribute('applyProtection', 'true');\n\t\t\t}\n\n\t\t\t// alignment\n\t\t\t$objWriter->startElement('alignment');\n\t\t\t\t$objWriter->writeAttribute('horizontal', \t$pStyle->getAlignment()->getHorizontal());\n\t\t\t\t$objWriter->writeAttribute('vertical', \t\t$pStyle->getAlignment()->getVertical());\n\n\t\t\t\t$textRotation = 0;\n\t\t\t\tif ($pStyle->getAlignment()->getTextRotation() >= 0) {\n\t\t\t\t\t$textRotation = $pStyle->getAlignment()->getTextRotation();\n\t\t\t\t} else if ($pStyle->getAlignment()->getTextRotation() < 0) {\n\t\t\t\t\t$textRotation = 90 - $pStyle->getAlignment()->getTextRotation();\n\t\t\t\t}\n\t\t\t\t$objWriter->writeAttribute('textRotation', \t$textRotation);\n\n\t\t\t\t$objWriter->writeAttribute('wrapText', \t\t($pStyle->getAlignment()->getWrapText() ? 'true' : 'false'));\n\t\t\t\t$objWriter->writeAttribute('shrinkToFit', \t($pStyle->getAlignment()->getShrinkToFit() ? 'true' : 'false'));\n\n\t\t\t\tif ($pStyle->getAlignment()->getIndent() > 0) {\n\t\t\t\t\t$objWriter->writeAttribute('indent', \t$pStyle->getAlignment()->getIndent());\n\t\t\t\t}\n\t\t\t\tif ($pStyle->getAlignment()->getReadorder() > 0) {\n\t\t\t\t\t$objWriter->writeAttribute('readingOrder', \t$pStyle->getAlignment()->getReadorder());\n\t\t\t\t}\n\t\t\t$objWriter->endElement();\n\n\t\t\t// protection\n\t\t\tif ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT || $pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) {\n\t\t\t\t$objWriter->startElement('protection');\n\t\t\t\t\tif ($pStyle->getProtection()->getLocked() != PHPExcel_Style_Protection::PROTECTION_INHERIT) {\n\t\t\t\t\t\t$objWriter->writeAttribute('locked', \t\t($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false'));\n\t\t\t\t\t}\n\t\t\t\t\tif ($pStyle->getProtection()->getHidden() != PHPExcel_Style_Protection::PROTECTION_INHERIT) {\n\t\t\t\t\t\t$objWriter->writeAttribute('hidden', \t\t($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false'));\n\t\t\t\t\t}\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write Cell Style Dxf\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter \t\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_Style\t\t\t\t\t$pStyle\t\t\tStyle\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeCellStyleDxf(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style $pStyle = null)\n\t{\n\t\t// dxf\n\t\t$objWriter->startElement('dxf');\n\n\t\t\t// font\n\t\t\t$this->_writeFont($objWriter, $pStyle->getFont());\n\n\t\t\t// numFmt\n\t\t\t$this->_writeNumFmt($objWriter, $pStyle->getNumberFormat());\n\n\t\t\t// fill\n\t\t\t$this->_writeFill($objWriter, $pStyle->getFill());\n\n\t\t\t// alignment\n\t\t\t$objWriter->startElement('alignment');\n\t\t\t\tif ($pStyle->getAlignment()->getHorizontal() !== NULL) {\n\t\t\t\t\t$objWriter->writeAttribute('horizontal', $pStyle->getAlignment()->getHorizontal());\n\t\t\t\t}\n\t\t\t\tif ($pStyle->getAlignment()->getVertical() !== NULL) {\n\t\t\t\t\t$objWriter->writeAttribute('vertical', $pStyle->getAlignment()->getVertical());\n\t\t\t\t}\n\n\t\t\t\tif ($pStyle->getAlignment()->getTextRotation() !== NULL) {\n\t\t\t\t\t$textRotation = 0;\n\t\t\t\t\tif ($pStyle->getAlignment()->getTextRotation() >= 0) {\n\t\t\t\t\t\t$textRotation = $pStyle->getAlignment()->getTextRotation();\n\t\t\t\t\t} else if ($pStyle->getAlignment()->getTextRotation() < 0) {\n\t\t\t\t\t\t$textRotation = 90 - $pStyle->getAlignment()->getTextRotation();\n\t\t\t\t\t}\n\t\t\t\t\t$objWriter->writeAttribute('textRotation', \t$textRotation);\n\t\t\t\t}\n\t\t\t$objWriter->endElement();\n\n\t\t\t// border\n\t\t\t$this->_writeBorder($objWriter, $pStyle->getBorders());\n\n\t\t\t// protection\n\t\t\tif (($pStyle->getProtection()->getLocked() !== NULL) ||\n\t\t\t\t($pStyle->getProtection()->getHidden() !== NULL)) {\n\t\t\t\tif ($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT ||\n\t\t\t\t\t$pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT) {\n\t\t\t\t\t$objWriter->startElement('protection');\n\t\t\t\t\t\tif (($pStyle->getProtection()->getLocked() !== NULL) &&\n\t\t\t\t\t\t\t($pStyle->getProtection()->getLocked() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) {\n\t\t\t\t\t\t\t$objWriter->writeAttribute('locked', ($pStyle->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false'));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (($pStyle->getProtection()->getHidden() !== NULL) &&\n\t\t\t\t\t\t\t($pStyle->getProtection()->getHidden() !== PHPExcel_Style_Protection::PROTECTION_INHERIT)) {\n\t\t\t\t\t\t\t$objWriter->writeAttribute('hidden', ($pStyle->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED ? 'true' : 'false'));\n\t\t\t\t\t\t}\n\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t}\n\t\t\t}\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write BorderPr\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t\t$objWriter \t\tXML Writer\n\t * @param \tstring\t\t\t\t\t\t\t$pName\t\t\tElement name\n\t * @param \tPHPExcel_Style_Border\t\t\t$pBorder\t\tBorder style\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeBorderPr(PHPExcel_Shared_XMLWriter $objWriter = null, $pName = 'left', PHPExcel_Style_Border $pBorder = null)\n\t{\n\t\t// Write BorderPr\n\t\tif ($pBorder->getBorderStyle() != PHPExcel_Style_Border::BORDER_NONE) {\n\t\t\t$objWriter->startElement($pName);\n\t\t\t$objWriter->writeAttribute('style', \t$pBorder->getBorderStyle());\n\n\t\t\t\t// color\n\t\t\t\t$objWriter->startElement('color');\n\t\t\t\t$objWriter->writeAttribute('rgb', \t$pBorder->getColor()->getARGB());\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write NumberFormat\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t\t\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_Style_NumberFormat\t\t\t$pNumberFormat\tNumber Format\n\t * @param \tint\t\t\t\t\t\t\t\t\t$pId\t\t\tNumber Format identifier\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeNumFmt(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Style_NumberFormat $pNumberFormat = null, $pId = 0)\n\t{\n\t\t// Translate formatcode\n\t\t$formatCode = $pNumberFormat->getFormatCode();\n\n\t\t// numFmt\n\t\tif ($formatCode !== NULL) {\n\t\t\t$objWriter->startElement('numFmt');\n\t\t\t\t$objWriter->writeAttribute('numFmtId', ($pId + 164));\n\t\t\t\t$objWriter->writeAttribute('formatCode', $formatCode);\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Get an array of all styles\n\t *\n\t * @param \tPHPExcel\t\t\t\t$pPHPExcel\n\t * @return \tPHPExcel_Style[]\t\tAll styles in PHPExcel\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function allStyles(PHPExcel $pPHPExcel = null)\n\t{\n\t\t$aStyles = $pPHPExcel->getCellXfCollection();\n\n\t\treturn $aStyles;\n\t}\n\n\t/**\n\t * Get an array of all conditional styles\n\t *\n\t * @param \tPHPExcel\t\t\t\t\t\t\t$pPHPExcel\n\t * @return \tPHPExcel_Style_Conditional[]\t\tAll conditional styles in PHPExcel\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function allConditionalStyles(PHPExcel $pPHPExcel = null)\n\t{\n\t\t// Get an array of all styles\n\t\t$aStyles\t\t= array();\n\n\t\t$sheetCount = $pPHPExcel->getSheetCount();\n\t\tfor ($i = 0; $i < $sheetCount; ++$i) {\n\t\t\tforeach ($pPHPExcel->getSheet($i)->getConditionalStylesCollection() as $conditionalStyles) {\n\t\t\t\tforeach ($conditionalStyles as $conditionalStyle) {\n\t\t\t\t\t$aStyles[] = $conditionalStyle;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn $aStyles;\n\t}\n\n\t/**\n\t * Get an array of all fills\n\t *\n\t * @param \tPHPExcel\t\t\t\t\t\t$pPHPExcel\n\t * @return \tPHPExcel_Style_Fill[]\t\tAll fills in PHPExcel\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function allFills(PHPExcel $pPHPExcel = null)\n\t{\n\t\t// Get an array of unique fills\n\t\t$aFills \t= array();\n\n\t\t// Two first fills are predefined\n\t\t$fill0 = new PHPExcel_Style_Fill();\n\t\t$fill0->setFillType(PHPExcel_Style_Fill::FILL_NONE);\n\t\t$aFills[] = $fill0;\n\n\t\t$fill1 = new PHPExcel_Style_Fill();\n\t\t$fill1->setFillType(PHPExcel_Style_Fill::FILL_PATTERN_GRAY125);\n\t\t$aFills[] = $fill1;\n\t\t// The remaining fills\n\t\t$aStyles \t= $this->allStyles($pPHPExcel);\n\t\tforeach ($aStyles as $style) {\n\t\t\tif (!array_key_exists($style->getFill()->getHashCode(), $aFills)) {\n\t\t\t\t$aFills[ $style->getFill()->getHashCode() ] = $style->getFill();\n\t\t\t}\n\t\t}\n\n\t\treturn $aFills;\n\t}\n\n\t/**\n\t * Get an array of all fonts\n\t *\n\t * @param \tPHPExcel\t\t\t\t\t\t$pPHPExcel\n\t * @return \tPHPExcel_Style_Font[]\t\tAll fonts in PHPExcel\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function allFonts(PHPExcel $pPHPExcel = null)\n\t{\n\t\t// Get an array of unique fonts\n\t\t$aFonts \t= array();\n\t\t$aStyles \t= $this->allStyles($pPHPExcel);\n\n\t\tforeach ($aStyles as $style) {\n\t\t\tif (!array_key_exists($style->getFont()->getHashCode(), $aFonts)) {\n\t\t\t\t$aFonts[ $style->getFont()->getHashCode() ] = $style->getFont();\n\t\t\t}\n\t\t}\n\n\t\treturn $aFonts;\n\t}\n\n\t/**\n\t * Get an array of all borders\n\t *\n\t * @param \tPHPExcel\t\t\t\t\t\t$pPHPExcel\n\t * @return \tPHPExcel_Style_Borders[]\t\tAll borders in PHPExcel\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function allBorders(PHPExcel $pPHPExcel = null)\n\t{\n\t\t// Get an array of unique borders\n\t\t$aBorders \t= array();\n\t\t$aStyles \t= $this->allStyles($pPHPExcel);\n\n\t\tforeach ($aStyles as $style) {\n\t\t\tif (!array_key_exists($style->getBorders()->getHashCode(), $aBorders)) {\n\t\t\t\t$aBorders[ $style->getBorders()->getHashCode() ] = $style->getBorders();\n\t\t\t}\n\t\t}\n\n\t\treturn $aBorders;\n\t}\n\n\t/**\n\t * Get an array of all number formats\n\t *\n\t * @param \tPHPExcel\t\t\t\t\t\t\t\t$pPHPExcel\n\t * @return \tPHPExcel_Style_NumberFormat[]\t\tAll number formats in PHPExcel\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function allNumberFormats(PHPExcel $pPHPExcel = null)\n\t{\n\t\t// Get an array of unique number formats\n\t\t$aNumFmts \t= array();\n\t\t$aStyles \t= $this->allStyles($pPHPExcel);\n\n\t\tforeach ($aStyles as $style) {\n\t\t\tif ($style->getNumberFormat()->getBuiltInFormatCode() === false && !array_key_exists($style->getNumberFormat()->getHashCode(), $aNumFmts)) {\n\t\t\t\t$aNumFmts[ $style->getNumberFormat()->getHashCode() ] = $style->getNumberFormat();\n\t\t\t}\n\t\t}\n\n\t\treturn $aNumFmts;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Theme.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007_Theme\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007_Theme extends PHPExcel_Writer_Excel2007_WriterPart\n{\n\t/**\n\t * Map of Major fonts to write\n\t * @static\tarray of string\n\t *\n\t */\n\tprivate static $_majorFonts = array(\n\t\t\t\t\t'Jpan' => 'ＭＳ Ｐゴシック',\n\t\t\t\t\t'Hang' => '맑은 고딕',\n\t\t\t\t\t'Hans' => '宋体',\n\t\t\t\t\t'Hant' => '新細明體',\n\t\t\t\t\t'Arab' => 'Times New Roman',\n\t\t\t\t\t'Hebr' => 'Times New Roman',\n\t\t\t\t\t'Thai' => 'Tahoma',\n\t\t\t\t\t'Ethi' => 'Nyala',\n\t\t\t\t\t'Beng' => 'Vrinda',\n\t\t\t\t\t'Gujr' => 'Shruti',\n\t\t\t\t\t'Khmr' => 'MoolBoran',\n\t\t\t\t\t'Knda' => 'Tunga',\n\t\t\t\t\t'Guru' => 'Raavi',\n\t\t\t\t\t'Cans' => 'Euphemia',\n\t\t\t\t\t'Cher' => 'Plantagenet Cherokee',\n\t\t\t\t\t'Yiii' => 'Microsoft Yi Baiti',\n\t\t\t\t\t'Tibt' => 'Microsoft Himalaya',\n\t\t\t\t\t'Thaa' => 'MV Boli',\n\t\t\t\t\t'Deva' => 'Mangal',\n\t\t\t\t\t'Telu' => 'Gautami',\n\t\t\t\t\t'Taml' => 'Latha',\n\t\t\t\t\t'Syrc' => 'Estrangelo Edessa',\n\t\t\t\t\t'Orya' => 'Kalinga',\n\t\t\t\t\t'Mlym' => 'Kartika',\n\t\t\t\t\t'Laoo' => 'DokChampa',\n\t\t\t\t\t'Sinh' => 'Iskoola Pota',\n\t\t\t\t\t'Mong' => 'Mongolian Baiti',\n\t\t\t\t\t'Viet' => 'Times New Roman',\n\t\t\t\t\t'Uigh' => 'Microsoft Uighur',\n\t\t\t\t\t'Geor' => 'Sylfaen',\n\t\t\t);\n\n\t/**\n\t * Map of Minor fonts to write\n\t * @static\tarray of string\n\t *\n\t */\n\tprivate static $_minorFonts = array(\n\t\t\t\t\t'Jpan' => 'ＭＳ Ｐゴシック',\n\t\t\t\t\t'Hang' => '맑은 고딕',\n\t\t\t\t\t'Hans' => '宋体',\n\t\t\t\t\t'Hant' => '新細明體',\n\t\t\t\t\t'Arab' => 'Arial',\n\t\t\t\t\t'Hebr' => 'Arial',\n\t\t\t\t\t'Thai' => 'Tahoma',\n\t\t\t\t\t'Ethi' => 'Nyala',\n\t\t\t\t\t'Beng' => 'Vrinda',\n\t\t\t\t\t'Gujr' => 'Shruti',\n\t\t\t\t\t'Khmr' => 'DaunPenh',\n\t\t\t\t\t'Knda' => 'Tunga',\n\t\t\t\t\t'Guru' => 'Raavi',\n\t\t\t\t\t'Cans' => 'Euphemia',\n\t\t\t\t\t'Cher' => 'Plantagenet Cherokee',\n\t\t\t\t\t'Yiii' => 'Microsoft Yi Baiti',\n\t\t\t\t\t'Tibt' => 'Microsoft Himalaya',\n\t\t\t\t\t'Thaa' => 'MV Boli',\n\t\t\t\t\t'Deva' => 'Mangal',\n\t\t\t\t\t'Telu' => 'Gautami',\n\t\t\t\t\t'Taml' => 'Latha',\n\t\t\t\t\t'Syrc' => 'Estrangelo Edessa',\n\t\t\t\t\t'Orya' => 'Kalinga',\n\t\t\t\t\t'Mlym' => 'Kartika',\n\t\t\t\t\t'Laoo' => 'DokChampa',\n\t\t\t\t\t'Sinh' => 'Iskoola Pota',\n\t\t\t\t\t'Mong' => 'Mongolian Baiti',\n\t\t\t\t\t'Viet' => 'Arial',\n\t\t\t\t\t'Uigh' => 'Microsoft Uighur',\n\t\t\t\t\t'Geor' => 'Sylfaen',\n\t\t\t);\n\n\t/**\n\t * Map of core colours\n\t * @static\tarray of string\n\t *\n\t */\n\t\tprivate static $_colourScheme = array(\n\t\t\t\t\t'dk2'\t\t=> '1F497D',\n\t\t\t\t\t'lt2'\t\t=> 'EEECE1',\n\t\t\t\t\t'accent1'\t=> '4F81BD',\n\t\t\t\t\t'accent2'\t=> 'C0504D',\n\t\t\t\t\t'accent3'\t=> '9BBB59',\n\t\t\t\t\t'accent4'\t=> '8064A2',\n\t\t\t\t\t'accent5'\t=> '4BACC6',\n\t\t\t\t\t'accent6'\t=> 'F79646',\n\t\t\t\t\t'hlink'\t\t=> '0000FF',\n\t\t\t\t\t'folHlink'\t=> '800080',\n\t\t\t);\n\t\t\t\n\t/**\n\t * Write theme to XML format\n\t *\n\t * @param \tPHPExcel\t$pPHPExcel\n\t * @return \tstring \t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeTheme(PHPExcel $pPHPExcel = null)\n\t{\n\t\t\t// Create XML writer\n\t\t\t$objWriter = null;\n\t\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t\t} else {\n\t\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t\t}\n\n\t\t\t// XML header\n\t\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t\t// a:theme\n\t\t\t$objWriter->startElement('a:theme');\n\t\t\t$objWriter->writeAttribute('xmlns:a', 'http://schemas.openxmlformats.org/drawingml/2006/main');\n\t\t\t$objWriter->writeAttribute('name', 'Office Theme');\n\n\t\t\t\t// a:themeElements\n\t\t\t\t$objWriter->startElement('a:themeElements');\n\n\t\t\t\t\t// a:clrScheme\n\t\t\t\t\t$objWriter->startElement('a:clrScheme');\n\t\t\t\t\t$objWriter->writeAttribute('name', 'Office');\n\n\t\t\t\t\t\t// a:dk1\n\t\t\t\t\t\t$objWriter->startElement('a:dk1');\n\n\t\t\t\t\t\t\t// a:sysClr\n\t\t\t\t\t\t\t$objWriter->startElement('a:sysClr');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'windowText');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('lastClr', '000000');\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// a:lt1\n\t\t\t\t\t\t$objWriter->startElement('a:lt1');\n\n\t\t\t\t\t\t\t// a:sysClr\n\t\t\t\t\t\t\t$objWriter->startElement('a:sysClr');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'window');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('lastClr', 'FFFFFF');\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// a:dk2\n\t\t\t\t\t\t$this->_writeColourScheme($objWriter);\n\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// a:fontScheme\n\t\t\t\t\t$objWriter->startElement('a:fontScheme');\n\t\t\t\t\t$objWriter->writeAttribute('name', 'Office');\n\n\t\t\t\t\t\t// a:majorFont\n\t\t\t\t\t\t$objWriter->startElement('a:majorFont');\n\t\t\t\t\t\t\t$this->_writeFonts($objWriter, 'Cambria', self::$_majorFonts);\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// a:minorFont\n\t\t\t\t\t\t$objWriter->startElement('a:minorFont');\n\t\t\t\t\t\t\t$this->_writeFonts($objWriter, 'Calibri', self::$_minorFonts);\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t// a:fmtScheme\n\t\t\t\t\t$objWriter->startElement('a:fmtScheme');\n\t\t\t\t\t$objWriter->writeAttribute('name', 'Office');\n\n\t\t\t\t\t\t// a:fillStyleLst\n\t\t\t\t\t\t$objWriter->startElement('a:fillStyleLst');\n\n\t\t\t\t\t\t\t// a:solidFill\n\t\t\t\t\t\t\t$objWriter->startElement('a:solidFill');\n\n\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t// a:gradFill\n\t\t\t\t\t\t\t$objWriter->startElement('a:gradFill');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('rotWithShape', '1');\n\n\t\t\t\t\t\t\t\t// a:gsLst\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:gsLst');\n\n\t\t\t\t\t\t\t\t\t// a:gs\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:gs');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('pos', '0');\n\n\t\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:tint\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:tint');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '50000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t\t// a:satMod\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:satMod');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '300000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t// a:gs\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:gs');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('pos', '35000');\n\n\t\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:tint\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:tint');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '37000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t\t// a:satMod\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:satMod');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '300000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t// a:gs\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:gs');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('pos', '100000');\n\n\t\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:tint\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:tint');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '15000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t\t// a:satMod\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:satMod');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '350000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t// a:lin\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:lin');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('ang', '16200000');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('scaled', '1');\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t// a:gradFill\n\t\t\t\t\t\t\t$objWriter->startElement('a:gradFill');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('rotWithShape', '1');\n\n\t\t\t\t\t\t\t\t// a:gsLst\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:gsLst');\n\n\t\t\t\t\t\t\t\t\t// a:gs\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:gs');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('pos', '0');\n\n\t\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:shade\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:shade');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '51000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t\t// a:satMod\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:satMod');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '130000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t// a:gs\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:gs');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('pos', '80000');\n\n\t\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:shade\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:shade');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '93000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t\t// a:satMod\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:satMod');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '130000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t// a:gs\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:gs');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('pos', '100000');\n\n\t\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:shade\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:shade');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '94000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t\t// a:satMod\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:satMod');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '135000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t// a:lin\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:lin');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('ang', '16200000');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('scaled', '0');\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// a:lnStyleLst\n\t\t\t\t\t\t$objWriter->startElement('a:lnStyleLst');\n\n\t\t\t\t\t\t\t// a:ln\n\t\t\t\t\t\t\t$objWriter->startElement('a:ln');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('w', '9525');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('cap', 'flat');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('cmpd', 'sng');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('algn', 'ctr');\n\n\t\t\t\t\t\t\t\t// a:solidFill\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:solidFill');\n\n\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:shade\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:shade');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '95000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t\t// a:satMod\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:satMod');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '105000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t// a:prstDash\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:prstDash');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'solid');\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t// a:ln\n\t\t\t\t\t\t\t$objWriter->startElement('a:ln');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('w', '25400');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('cap', 'flat');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('cmpd', 'sng');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('algn', 'ctr');\n\n\t\t\t\t\t\t\t\t// a:solidFill\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:solidFill');\n\n\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t// a:prstDash\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:prstDash');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'solid');\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t// a:ln\n\t\t\t\t\t\t\t$objWriter->startElement('a:ln');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('w', '38100');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('cap', 'flat');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('cmpd', 'sng');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('algn', 'ctr');\n\n\t\t\t\t\t\t\t\t// a:solidFill\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:solidFill');\n\n\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t// a:prstDash\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:prstDash');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'solid');\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t$objWriter->endElement();\n\n\n\n\t\t\t\t\t\t// a:effectStyleLst\n\t\t\t\t\t\t$objWriter->startElement('a:effectStyleLst');\n\n\t\t\t\t\t\t\t// a:effectStyle\n\t\t\t\t\t\t\t$objWriter->startElement('a:effectStyle');\n\n\t\t\t\t\t\t\t\t// a:effectLst\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:effectLst');\n\n\t\t\t\t\t\t\t\t\t// a:outerShdw\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:outerShdw');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('blurRad', '40000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('dist', '20000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('dir', '5400000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('rotWithShape', '0');\n\n\t\t\t\t\t\t\t\t\t\t// a:srgbClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:srgbClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '000000');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:alpha\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:alpha');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '38000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t// a:effectStyle\n\t\t\t\t\t\t\t$objWriter->startElement('a:effectStyle');\n\n\t\t\t\t\t\t\t\t// a:effectLst\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:effectLst');\n\n\t\t\t\t\t\t\t\t\t// a:outerShdw\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:outerShdw');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('blurRad', '40000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('dist', '23000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('dir', '5400000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('rotWithShape', '0');\n\n\t\t\t\t\t\t\t\t\t\t// a:srgbClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:srgbClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '000000');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:alpha\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:alpha');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '35000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t// a:effectStyle\n\t\t\t\t\t\t\t$objWriter->startElement('a:effectStyle');\n\n\t\t\t\t\t\t\t\t// a:effectLst\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:effectLst');\n\n\t\t\t\t\t\t\t\t\t// a:outerShdw\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:outerShdw');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('blurRad', '40000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('dist', '23000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('dir', '5400000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('rotWithShape', '0');\n\n\t\t\t\t\t\t\t\t\t\t// a:srgbClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:srgbClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '000000');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:alpha\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:alpha');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '35000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t// a:scene3d\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:scene3d');\n\n\t\t\t\t\t\t\t\t\t// a:camera\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:camera');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('prst', 'orthographicFront');\n\n\t\t\t\t\t\t\t\t\t\t// a:rot\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:rot');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('lat', '0');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('lon', '0');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('rev', '0');\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t// a:lightRig\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:lightRig');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('rig', 'threePt');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('dir', 't');\n\n\t\t\t\t\t\t\t\t\t\t// a:rot\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:rot');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('lat', '0');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('lon', '0');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('rev', '1200000');\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t// a:sp3d\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:sp3d');\n\n\t\t\t\t\t\t\t\t\t// a:bevelT\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:bevelT');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('w', '63500');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('h', '25400');\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t// a:bgFillStyleLst\n\t\t\t\t\t\t$objWriter->startElement('a:bgFillStyleLst');\n\n\t\t\t\t\t\t\t// a:solidFill\n\t\t\t\t\t\t\t$objWriter->startElement('a:solidFill');\n\n\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t// a:gradFill\n\t\t\t\t\t\t\t$objWriter->startElement('a:gradFill');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('rotWithShape', '1');\n\n\t\t\t\t\t\t\t\t// a:gsLst\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:gsLst');\n\n\t\t\t\t\t\t\t\t\t// a:gs\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:gs');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('pos', '0');\n\n\t\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:tint\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:tint');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '40000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t\t// a:satMod\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:satMod');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '350000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t// a:gs\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:gs');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('pos', '40000');\n\n\t\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:tint\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:tint');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '45000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t\t// a:shade\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:shade');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '99000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t\t// a:satMod\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:satMod');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '350000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t// a:gs\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:gs');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('pos', '100000');\n\n\t\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:shade\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:shade');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '20000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t\t// a:satMod\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:satMod');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '255000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t// a:path\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:path');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('path', 'circle');\n\n\t\t\t\t\t\t\t\t\t// a:fillToRect\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:fillToRect');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('l', '50000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('t', '-80000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('r', '50000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('b', '180000');\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t// a:gradFill\n\t\t\t\t\t\t\t$objWriter->startElement('a:gradFill');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('rotWithShape', '1');\n\n\t\t\t\t\t\t\t\t// a:gsLst\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:gsLst');\n\n\t\t\t\t\t\t\t\t\t// a:gs\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:gs');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('pos', '0');\n\n\t\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:tint\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:tint');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '80000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t\t// a:satMod\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:satMod');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '300000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t// a:gs\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:gs');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('pos', '100000');\n\n\t\t\t\t\t\t\t\t\t\t// a:schemeClr\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:schemeClr');\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', 'phClr');\n\n\t\t\t\t\t\t\t\t\t\t\t// a:shade\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:shade');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '30000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t\t// a:satMod\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:satMod');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', '200000');\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t// a:path\n\t\t\t\t\t\t\t\t$objWriter->startElement('a:path');\n\t\t\t\t\t\t\t\t$objWriter->writeAttribute('path', 'circle');\n\n\t\t\t\t\t\t\t\t\t// a:fillToRect\n\t\t\t\t\t\t\t\t\t$objWriter->startElement('a:fillToRect');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('l', '50000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('t', '50000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('r', '50000');\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('b', '50000');\n\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t// a:objectDefaults\n\t\t\t\t$objWriter->writeElement('a:objectDefaults', null);\n\n\t\t\t\t// a:extraClrSchemeLst\n\t\t\t\t$objWriter->writeElement('a:extraClrSchemeLst', null);\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// Return\n\t\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write fonts to XML format\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t$objWriter\n\t * @param \tstring\t\t\t\t\t\t$latinFont\n\t * @param \tarray of string\t\t\t\t$fontSet\n\t * @return \tstring \t\t\t\t\t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeFonts($objWriter, $latinFont, $fontSet)\n\t{\n\t\t// a:latin\n\t\t$objWriter->startElement('a:latin');\n\t\t$objWriter->writeAttribute('typeface', $latinFont);\n\t\t$objWriter->endElement();\n\n\t\t// a:ea\n\t\t$objWriter->startElement('a:ea');\n\t\t$objWriter->writeAttribute('typeface', '');\n\t\t$objWriter->endElement();\n\n\t\t// a:cs\n\t\t$objWriter->startElement('a:cs');\n\t\t$objWriter->writeAttribute('typeface', '');\n\t\t$objWriter->endElement();\n\n\t\tforeach($fontSet as $fontScript => $typeface) {\n\t\t\t$objWriter->startElement('a:font');\n\t\t\t\t$objWriter->writeAttribute('script', $fontScript);\n\t\t\t\t$objWriter->writeAttribute('typeface', $typeface);\n\t\t\t$objWriter->endElement();\n\t\t}\n\n\t}\n\n\t/**\n\t * Write colour scheme to XML format\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t$objWriter\n\t * @return \tstring \t\t\t\t\t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeColourScheme($objWriter)\n\t{\n\t\tforeach(self::$_colourScheme as $colourName => $colourValue) {\n\t\t\t$objWriter->startElement('a:'.$colourName);\n\n\t\t\t\t$objWriter->startElement('a:srgbClr');\n\t\t\t\t\t$objWriter->writeAttribute('val', $colourValue);\n\t\t\t\t$objWriter->endElement();\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t\t\t\t\t\t\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Workbook.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007_Workbook\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007_Workbook extends PHPExcel_Writer_Excel2007_WriterPart\n{\n\t/**\n\t * Write workbook to XML format\n\t *\n\t * @param \tPHPExcel\t$pPHPExcel\n\t * @param\tboolean\t\t$recalcRequired\tIndicate whether formulas should be recalculated before writing\n\t * @return \tstring \t\tXML Output\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeWorkbook(PHPExcel $pPHPExcel = null, $recalcRequired = FALSE)\n\t{\n\t\t// Create XML writer\n\t\t$objWriter = null;\n\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t} else {\n\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t}\n\n\t\t// XML header\n\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t// workbook\n\t\t$objWriter->startElement('workbook');\n\t\t$objWriter->writeAttribute('xml:space', 'preserve');\n\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');\n\t\t$objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');\n\n\t\t\t// fileVersion\n\t\t\t$this->_writeFileVersion($objWriter);\n\n\t\t\t// workbookPr\n\t\t\t$this->_writeWorkbookPr($objWriter);\n\n\t\t\t// workbookProtection\n\t\t\t$this->_writeWorkbookProtection($objWriter, $pPHPExcel);\n\n\t\t\t// bookViews\n\t\t\tif ($this->getParentWriter()->getOffice2003Compatibility() === false) {\n\t\t\t\t$this->_writeBookViews($objWriter, $pPHPExcel);\n\t\t\t}\n\n\t\t\t// sheets\n\t\t\t$this->_writeSheets($objWriter, $pPHPExcel);\n\n\t\t\t// definedNames\n\t\t\t$this->_writeDefinedNames($objWriter, $pPHPExcel);\n\n\t\t\t// calcPr\n\t\t\t$this->_writeCalcPr($objWriter,$recalcRequired);\n\n\t\t$objWriter->endElement();\n\n\t\t// Return\n\t\treturn $objWriter->getData();\n\t}\n\n\t/**\n\t * Write file version\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter $objWriter \t\tXML Writer\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeFileVersion(PHPExcel_Shared_XMLWriter $objWriter = null)\n\t{\n\t\t$objWriter->startElement('fileVersion');\n\t\t$objWriter->writeAttribute('appName', 'xl');\n\t\t$objWriter->writeAttribute('lastEdited', '4');\n\t\t$objWriter->writeAttribute('lowestEdited', '4');\n\t\t$objWriter->writeAttribute('rupBuild', '4505');\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write WorkbookPr\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter $objWriter \t\tXML Writer\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeWorkbookPr(PHPExcel_Shared_XMLWriter $objWriter = null)\n\t{\n\t\t$objWriter->startElement('workbookPr');\n\n\t\tif (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) {\n\t\t\t$objWriter->writeAttribute('date1904', '1');\n\t\t}\n\n\t\t$objWriter->writeAttribute('codeName', 'ThisWorkbook');\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write BookViews\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter \t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel\t\t\t\t\t$pPHPExcel\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeBookViews(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null)\n\t{\n\t\t// bookViews\n\t\t$objWriter->startElement('bookViews');\n\n\t\t\t// workbookView\n\t\t\t$objWriter->startElement('workbookView');\n\n\t\t\t$objWriter->writeAttribute('activeTab', $pPHPExcel->getActiveSheetIndex());\n\t\t\t$objWriter->writeAttribute('autoFilterDateGrouping', '1');\n\t\t\t$objWriter->writeAttribute('firstSheet', '0');\n\t\t\t$objWriter->writeAttribute('minimized', '0');\n\t\t\t$objWriter->writeAttribute('showHorizontalScroll', '1');\n\t\t\t$objWriter->writeAttribute('showSheetTabs', '1');\n\t\t\t$objWriter->writeAttribute('showVerticalScroll', '1');\n\t\t\t$objWriter->writeAttribute('tabRatio', '600');\n\t\t\t$objWriter->writeAttribute('visibility', 'visible');\n\n\t\t\t$objWriter->endElement();\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write WorkbookProtection\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter \t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel\t\t\t\t\t$pPHPExcel\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeWorkbookProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null)\n\t{\n\t\tif ($pPHPExcel->getSecurity()->isSecurityEnabled()) {\n\t\t\t$objWriter->startElement('workbookProtection');\n\t\t\t$objWriter->writeAttribute('lockRevision',\t\t($pPHPExcel->getSecurity()->getLockRevision() ? 'true' : 'false'));\n\t\t\t$objWriter->writeAttribute('lockStructure', \t($pPHPExcel->getSecurity()->getLockStructure() ? 'true' : 'false'));\n\t\t\t$objWriter->writeAttribute('lockWindows', \t\t($pPHPExcel->getSecurity()->getLockWindows() ? 'true' : 'false'));\n\n\t\t\tif ($pPHPExcel->getSecurity()->getRevisionsPassword() != '') {\n\t\t\t\t$objWriter->writeAttribute('revisionsPassword',\t$pPHPExcel->getSecurity()->getRevisionsPassword());\n\t\t\t}\n\n\t\t\tif ($pPHPExcel->getSecurity()->getWorkbookPassword() != '') {\n\t\t\t\t$objWriter->writeAttribute('workbookPassword',\t$pPHPExcel->getSecurity()->getWorkbookPassword());\n\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write calcPr\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t$objWriter\t\tXML Writer\n\t * @param\tboolean\t\t\t\t\t\t$recalcRequired\tIndicate whether formulas should be recalculated before writing\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeCalcPr(PHPExcel_Shared_XMLWriter $objWriter = null, $recalcRequired = TRUE)\n\t{\n\t\t$objWriter->startElement('calcPr');\n\n\t\t//\tSet the calcid to a higher value than Excel itself will use, otherwise Excel will always recalc\n        //  If MS Excel does do a recalc, then users opening a file in MS Excel will be prompted to save on exit\n        //     because the file has changed\n\t\t$objWriter->writeAttribute('calcId', \t\t\t'999999');\n\t\t$objWriter->writeAttribute('calcMode', \t\t\t'auto');\n\t\t//\tfullCalcOnLoad isn't needed if we've recalculating for the save\n\t\t$objWriter->writeAttribute('calcCompleted', \t($recalcRequired) ? 1 : 0);\n\t\t$objWriter->writeAttribute('fullCalcOnLoad', \t($recalcRequired) ? 0 : 1);\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write sheets\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter \t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel\t\t\t\t\t$pPHPExcel\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeSheets(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null)\n\t{\n\t\t// Write sheets\n\t\t$objWriter->startElement('sheets');\n\t\t$sheetCount = $pPHPExcel->getSheetCount();\n\t\tfor ($i = 0; $i < $sheetCount; ++$i) {\n\t\t\t// sheet\n\t\t\t$this->_writeSheet(\n\t\t\t\t$objWriter,\n\t\t\t\t$pPHPExcel->getSheet($i)->getTitle(),\n\t\t\t\t($i + 1),\n\t\t\t\t($i + 1 + 3),\n\t\t\t\t$pPHPExcel->getSheet($i)->getSheetState()\n\t\t\t);\n\t\t}\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write sheet\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter \t$objWriter \t\tXML Writer\n\t * @param \tstring \t\t\t\t\t\t$pSheetname \t\tSheet name\n\t * @param \tint\t\t\t\t\t\t\t$pSheetId\t \t\tSheet id\n\t * @param \tint\t\t\t\t\t\t\t$pRelId\t\t\t\tRelationship ID\n\t * @param   string                      $sheetState         Sheet state (visible, hidden, veryHidden)\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeSheet(PHPExcel_Shared_XMLWriter $objWriter = null, $pSheetname = '', $pSheetId = 1, $pRelId = 1, $sheetState = 'visible')\n\t{\n\t\tif ($pSheetname != '') {\n\t\t\t// Write sheet\n\t\t\t$objWriter->startElement('sheet');\n\t\t\t$objWriter->writeAttribute('name', \t\t$pSheetname);\n\t\t\t$objWriter->writeAttribute('sheetId', \t$pSheetId);\n\t\t\tif ($sheetState != 'visible' && $sheetState != '') {\n\t\t\t\t$objWriter->writeAttribute('state', $sheetState);\n\t\t\t}\n\t\t\t$objWriter->writeAttribute('r:id', \t\t'rId' . $pRelId);\n\t\t\t$objWriter->endElement();\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Invalid parameters passed.\");\n\t\t}\n\t}\n\n\t/**\n\t * Write Defined Names\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel\t\t\t\t\t$pPHPExcel\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeDefinedNames(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel = null)\n\t{\n\t\t// Write defined names\n\t\t$objWriter->startElement('definedNames');\n\n\t\t// Named ranges\n\t\tif (count($pPHPExcel->getNamedRanges()) > 0) {\n\t\t\t// Named ranges\n\t\t\t$this->_writeNamedRanges($objWriter, $pPHPExcel);\n\t\t}\n\n\t\t// Other defined names\n\t\t$sheetCount = $pPHPExcel->getSheetCount();\n\t\tfor ($i = 0; $i < $sheetCount; ++$i) {\n\t\t\t// definedName for autoFilter\n\t\t\t$this->_writeDefinedNameForAutofilter($objWriter, $pPHPExcel->getSheet($i), $i);\n\n\t\t\t// definedName for Print_Titles\n\t\t\t$this->_writeDefinedNameForPrintTitles($objWriter, $pPHPExcel->getSheet($i), $i);\n\n\t\t\t// definedName for Print_Area\n\t\t\t$this->_writeDefinedNameForPrintArea($objWriter, $pPHPExcel->getSheet($i), $i);\n\t\t}\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write named ranges\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel\t\t\t\t\t$pPHPExcel\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeNamedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel $pPHPExcel)\n\t{\n\t\t// Loop named ranges\n\t\t$namedRanges = $pPHPExcel->getNamedRanges();\n\t\tforeach ($namedRanges as $namedRange) {\n\t\t\t$this->_writeDefinedNameForNamedRange($objWriter, $namedRange);\n\t\t}\n\t}\n\n\t/**\n\t * Write Defined Name for named range\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_NamedRange\t\t\t$pNamedRange\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeDefinedNameForNamedRange(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_NamedRange $pNamedRange)\n\t{\n\t\t// definedName for named range\n\t\t$objWriter->startElement('definedName');\n\t\t$objWriter->writeAttribute('name',\t\t\t$pNamedRange->getName());\n\t\tif ($pNamedRange->getLocalOnly()) {\n\t\t\t$objWriter->writeAttribute('localSheetId',\t$pNamedRange->getScope()->getParent()->getIndex($pNamedRange->getScope()));\n\t\t}\n\n\t\t// Create absolute coordinate and write as raw text\n\t\t$range = PHPExcel_Cell::splitRange($pNamedRange->getRange());\n\t\tfor ($i = 0; $i < count($range); $i++) {\n\t\t\t$range[$i][0] = '\\'' . str_replace(\"'\", \"''\", $pNamedRange->getWorksheet()->getTitle()) . '\\'!' . PHPExcel_Cell::absoluteReference($range[$i][0]);\n\t\t\tif (isset($range[$i][1])) {\n\t\t\t\t$range[$i][1] = PHPExcel_Cell::absoluteReference($range[$i][1]);\n\t\t\t}\n\t\t}\n\t\t$range = PHPExcel_Cell::buildRange($range);\n\n\t\t$objWriter->writeRawData($range);\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write Defined Name for autoFilter\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_Worksheet\t\t\t$pSheet\n\t * @param \tint\t\t\t\t\t\t\t$pSheetId\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeDefinedNameForAutofilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0)\n\t{\n\t\t// definedName for autoFilter\n\t\t$autoFilterRange = $pSheet->getAutoFilter()->getRange();\n\t\tif (!empty($autoFilterRange)) {\n\t\t\t$objWriter->startElement('definedName');\n\t\t\t$objWriter->writeAttribute('name',\t\t\t'_xlnm._FilterDatabase');\n\t\t\t$objWriter->writeAttribute('localSheetId',\t$pSheetId);\n\t\t\t$objWriter->writeAttribute('hidden',\t\t'1');\n\n\t\t\t// Create absolute coordinate and write as raw text\n\t\t\t$range = PHPExcel_Cell::splitRange($autoFilterRange);\n\t\t\t$range = $range[0];\n\t\t\t//\tStrip any worksheet ref so we can make the cell ref absolute\n\t\t\tif (strpos($range[0],'!') !== false) {\n\t\t\t\tlist($ws,$range[0]) = explode('!',$range[0]);\n\t\t\t}\n\n\t\t\t$range[0] = PHPExcel_Cell::absoluteCoordinate($range[0]);\n\t\t\t$range[1] = PHPExcel_Cell::absoluteCoordinate($range[1]);\n\t\t\t$range = implode(':', $range);\n\n\t\t\t$objWriter->writeRawData('\\'' . str_replace(\"'\", \"''\", $pSheet->getTitle()) . '\\'!' . $range);\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write Defined Name for PrintTitles\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_Worksheet\t\t\t$pSheet\n\t * @param \tint\t\t\t\t\t\t\t$pSheetId\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeDefinedNameForPrintTitles(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0)\n\t{\n\t\t// definedName for PrintTitles\n\t\tif ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet() || $pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) {\n\t\t\t$objWriter->startElement('definedName');\n\t\t\t$objWriter->writeAttribute('name',\t\t\t'_xlnm.Print_Titles');\n\t\t\t$objWriter->writeAttribute('localSheetId',\t$pSheetId);\n\n\t\t\t// Setting string\n\t\t\t$settingString = '';\n\n\t\t\t// Columns to repeat\n\t\t\tif ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) {\n\t\t\t\t$repeat = $pSheet->getPageSetup()->getColumnsToRepeatAtLeft();\n\n\t\t\t\t$settingString .= '\\'' . str_replace(\"'\", \"''\", $pSheet->getTitle()) . '\\'!$' . $repeat[0] . ':$' . $repeat[1];\n\t\t\t}\n\n\t\t\t// Rows to repeat\n\t\t\tif ($pSheet->getPageSetup()->isRowsToRepeatAtTopSet()) {\n\t\t\t\tif ($pSheet->getPageSetup()->isColumnsToRepeatAtLeftSet()) {\n\t\t\t\t\t$settingString .= ',';\n\t\t\t\t}\n\n\t\t\t\t$repeat = $pSheet->getPageSetup()->getRowsToRepeatAtTop();\n\n\t\t\t\t$settingString .= '\\'' . str_replace(\"'\", \"''\", $pSheet->getTitle()) . '\\'!$' . $repeat[0] . ':$' . $repeat[1];\n\t\t\t}\n\n\t\t\t$objWriter->writeRawData($settingString);\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write Defined Name for PrintTitles\n\t *\n\t * @param \tPHPExcel_Shared_XMLWriter\t$objWriter \t\tXML Writer\n\t * @param \tPHPExcel_Worksheet\t\t\t$pSheet\n\t * @param \tint\t\t\t\t\t\t\t$pSheetId\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeDefinedNameForPrintArea(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pSheetId = 0)\n\t{\n\t\t// definedName for PrintArea\n\t\tif ($pSheet->getPageSetup()->isPrintAreaSet()) {\n\t\t\t$objWriter->startElement('definedName');\n\t\t\t$objWriter->writeAttribute('name',\t\t\t'_xlnm.Print_Area');\n\t\t\t$objWriter->writeAttribute('localSheetId',\t$pSheetId);\n\n\t\t\t// Setting string\n\t\t\t$settingString = '';\n\n\t\t\t// Print area\n\t\t\t$printArea = PHPExcel_Cell::splitRange($pSheet->getPageSetup()->getPrintArea());\n\n\t\t\t$chunks = array();\n\t\t\tforeach ($printArea as $printAreaRect) {\n\t\t\t\t$printAreaRect[0] = PHPExcel_Cell::absoluteReference($printAreaRect[0]);\n\t\t\t\t$printAreaRect[1] = PHPExcel_Cell::absoluteReference($printAreaRect[1]);\n\t\t\t\t$chunks[] = '\\'' . str_replace(\"'\", \"''\", $pSheet->getTitle()) . '\\'!' . implode(':', $printAreaRect);\n\t\t\t}\n\n\t\t\t$objWriter->writeRawData(implode(',', $chunks));\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/Worksheet.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007_Worksheet\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007_Worksheet extends PHPExcel_Writer_Excel2007_WriterPart\n{\n\t/**\n\t * Write worksheet to XML format\n\t *\n\t * @param\tPHPExcel_Worksheet\t\t$pSheet\n\t * @param\tstring[]\t\t\t\t$pStringTable\n\t * @param\tboolean\t\t\t\t\t$includeCharts\tFlag indicating if we should write charts\n\t * @return\tstring\t\t\t\t\tXML Output\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tpublic function writeWorksheet($pSheet = null, $pStringTable = null, $includeCharts = FALSE)\n\t{\n\t\tif (!is_null($pSheet)) {\n\t\t\t// Create XML writer\n\t\t\t$objWriter = null;\n\t\t\tif ($this->getParentWriter()->getUseDiskCaching()) {\n\t\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n\t\t\t} else {\n\t\t\t\t$objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n\t\t\t}\n\n\t\t\t// XML header\n\t\t\t$objWriter->startDocument('1.0','UTF-8','yes');\n\n\t\t\t// Worksheet\n\t\t\t$objWriter->startElement('worksheet');\n\t\t\t$objWriter->writeAttribute('xml:space', 'preserve');\n\t\t\t$objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main');\n\t\t\t$objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships');\n\n\t\t\t\t// sheetPr\n\t\t\t\t$this->_writeSheetPr($objWriter, $pSheet);\n\n\t\t\t\t// Dimension\n\t\t\t\t$this->_writeDimension($objWriter, $pSheet);\n\n\t\t\t\t// sheetViews\n\t\t\t\t$this->_writeSheetViews($objWriter, $pSheet);\n\n\t\t\t\t// sheetFormatPr\n\t\t\t\t$this->_writeSheetFormatPr($objWriter, $pSheet);\n\n\t\t\t\t// cols\n\t\t\t\t$this->_writeCols($objWriter, $pSheet);\n\n\t\t\t\t// sheetData\n\t\t\t\t$this->_writeSheetData($objWriter, $pSheet, $pStringTable);\n\n\t\t\t\t// sheetProtection\n\t\t\t\t$this->_writeSheetProtection($objWriter, $pSheet);\n\n\t\t\t\t// protectedRanges\n\t\t\t\t$this->_writeProtectedRanges($objWriter, $pSheet);\n\n\t\t\t\t// autoFilter\n\t\t\t\t$this->_writeAutoFilter($objWriter, $pSheet);\n\n\t\t\t\t// mergeCells\n\t\t\t\t$this->_writeMergeCells($objWriter, $pSheet);\n\n\t\t\t\t// conditionalFormatting\n\t\t\t\t$this->_writeConditionalFormatting($objWriter, $pSheet);\n\n\t\t\t\t// dataValidations\n\t\t\t\t$this->_writeDataValidations($objWriter, $pSheet);\n\n\t\t\t\t// hyperlinks\n\t\t\t\t$this->_writeHyperlinks($objWriter, $pSheet);\n\n\t\t\t\t// Print options\n\t\t\t\t$this->_writePrintOptions($objWriter, $pSheet);\n\n\t\t\t\t// Page margins\n\t\t\t\t$this->_writePageMargins($objWriter, $pSheet);\n\n\t\t\t\t// Page setup\n\t\t\t\t$this->_writePageSetup($objWriter, $pSheet);\n\n\t\t\t\t// Header / footer\n\t\t\t\t$this->_writeHeaderFooter($objWriter, $pSheet);\n\n\t\t\t\t// Breaks\n\t\t\t\t$this->_writeBreaks($objWriter, $pSheet);\n\n\t\t\t\t// Drawings and/or Charts\n\t\t\t\t$this->_writeDrawings($objWriter, $pSheet, $includeCharts);\n\n\t\t\t\t// LegacyDrawing\n\t\t\t\t$this->_writeLegacyDrawing($objWriter, $pSheet);\n\n\t\t\t\t// LegacyDrawingHF\n\t\t\t\t$this->_writeLegacyDrawingHF($objWriter, $pSheet);\n\n\t\t\t$objWriter->endElement();\n\n\t\t\t// Return\n\t\t\treturn $objWriter->getData();\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Invalid PHPExcel_Worksheet object passed.\");\n\t\t}\n\t}\n\n\t/**\n\t * Write SheetPr\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeSheetPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// sheetPr\n\t\t$objWriter->startElement('sheetPr');\n\t\t//$objWriter->writeAttribute('codeName',\t\t$pSheet->getTitle());\n\t\tif($pSheet->getParent()->hasMacros()){//if the workbook have macros, we need to have codeName for the sheet\n\t\t\tif($pSheet->hasCodeName()==false){\n\t\t\t\t$pSheet->setCodeName($pSheet->getTitle());\n\t\t\t}\n\t\t\t$objWriter->writeAttribute('codeName',\t\t$pSheet->getCodeName());\n\t\t}\n\t\t\t$autoFilterRange = $pSheet->getAutoFilter()->getRange();\n\t\t\tif (!empty($autoFilterRange)) {\n\t\t\t\t$objWriter->writeAttribute('filterMode', 1);\n\t\t\t\t$pSheet->getAutoFilter()->showHideRows();\n\t\t\t}\n\n\t\t\t// tabColor\n\t\t\tif ($pSheet->isTabColorSet()) {\n\t\t\t\t$objWriter->startElement('tabColor');\n\t\t\t\t$objWriter->writeAttribute('rgb',\t$pSheet->getTabColor()->getARGB());\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\t\t\t// outlinePr\n\t\t\t$objWriter->startElement('outlinePr');\n\t\t\t$objWriter->writeAttribute('summaryBelow',\t($pSheet->getShowSummaryBelow() ? '1' : '0'));\n\t\t\t$objWriter->writeAttribute('summaryRight',\t($pSheet->getShowSummaryRight() ? '1' : '0'));\n\t\t\t$objWriter->endElement();\n\n\t\t\t// pageSetUpPr\n\t\t\tif ($pSheet->getPageSetup()->getFitToPage()) {\n\t\t\t\t$objWriter->startElement('pageSetUpPr');\n\t\t\t\t$objWriter->writeAttribute('fitToPage',\t'1');\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write Dimension\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeDimension(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// dimension\n\t\t$objWriter->startElement('dimension');\n\t\t$objWriter->writeAttribute('ref', $pSheet->calculateWorksheetDimension());\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write SheetViews\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeSheetViews(PHPExcel_Shared_XMLWriter $objWriter = NULL, PHPExcel_Worksheet $pSheet = NULL)\n\t{\n\t\t// sheetViews\n\t\t$objWriter->startElement('sheetViews');\n\n\t\t\t// Sheet selected?\n\t\t\t$sheetSelected = false;\n\t\t\tif ($this->getParentWriter()->getPHPExcel()->getIndex($pSheet) == $this->getParentWriter()->getPHPExcel()->getActiveSheetIndex())\n\t\t\t\t$sheetSelected = true;\n\n\n\t\t\t// sheetView\n\t\t\t$objWriter->startElement('sheetView');\n\t\t\t$objWriter->writeAttribute('tabSelected',\t\t$sheetSelected ? '1' : '0');\n\t\t\t$objWriter->writeAttribute('workbookViewId',\t'0');\n\n\t\t\t\t// Zoom scales\n\t\t\t\tif ($pSheet->getSheetView()->getZoomScale() != 100) {\n\t\t\t\t\t$objWriter->writeAttribute('zoomScale',\t$pSheet->getSheetView()->getZoomScale());\n\t\t\t\t}\n\t\t\t\tif ($pSheet->getSheetView()->getZoomScaleNormal() != 100) {\n\t\t\t\t\t$objWriter->writeAttribute('zoomScaleNormal',\t$pSheet->getSheetView()->getZoomScaleNormal());\n\t\t\t\t}\n\n\t\t\t\t// View Layout Type\n\t\t\t\tif ($pSheet->getSheetView()->getView() !== PHPExcel_Worksheet_SheetView::SHEETVIEW_NORMAL) {\n\t\t\t\t\t$objWriter->writeAttribute('view',\t$pSheet->getSheetView()->getView());\n\t\t\t\t}\n\n\t\t\t\t// Gridlines\n\t\t\t\tif ($pSheet->getShowGridlines()) {\n\t\t\t\t\t$objWriter->writeAttribute('showGridLines',\t'true');\n\t\t\t\t} else {\n\t\t\t\t\t$objWriter->writeAttribute('showGridLines',\t'false');\n\t\t\t\t}\n\n\t\t\t\t// Row and column headers\n\t\t\t\tif ($pSheet->getShowRowColHeaders()) {\n\t\t\t\t\t$objWriter->writeAttribute('showRowColHeaders', '1');\n\t\t\t\t} else {\n\t\t\t\t\t$objWriter->writeAttribute('showRowColHeaders', '0');\n\t\t\t\t}\n\n\t\t\t\t// Right-to-left\n\t\t\t\tif ($pSheet->getRightToLeft()) {\n\t\t\t\t\t$objWriter->writeAttribute('rightToLeft',\t'true');\n\t\t\t\t}\n\n\t\t\t\t$activeCell = $pSheet->getActiveCell();\n\n\t\t\t\t// Pane\n\t\t\t\t$pane = '';\n\t\t\t\t$topLeftCell = $pSheet->getFreezePane();\n\t\t\t\tif (($topLeftCell != '') && ($topLeftCell != 'A1')) {\n\t\t\t\t\t$activeCell = $topLeftCell;\n\t\t\t\t\t// Calculate freeze coordinates\n\t\t\t\t\t$xSplit = $ySplit = 0;\n\n\t\t\t\t\tlist($xSplit, $ySplit) = PHPExcel_Cell::coordinateFromString($topLeftCell);\n\t\t\t\t\t$xSplit = PHPExcel_Cell::columnIndexFromString($xSplit);\n\n\t\t\t\t\t// pane\n\t\t\t\t\t$pane = 'topRight';\n\t\t\t\t\t$objWriter->startElement('pane');\n\t\t\t\t\tif ($xSplit > 1)\n\t\t\t\t\t\t$objWriter->writeAttribute('xSplit',\t$xSplit - 1);\n\t\t\t\t\tif ($ySplit > 1) {\n\t\t\t\t\t\t$objWriter->writeAttribute('ySplit',\t$ySplit - 1);\n\t\t\t\t\t\t$pane = ($xSplit > 1) ? 'bottomRight' : 'bottomLeft';\n\t\t\t\t\t}\n\t\t\t\t\t$objWriter->writeAttribute('topLeftCell',\t$topLeftCell);\n\t\t\t\t\t$objWriter->writeAttribute('activePane',\t$pane);\n\t\t\t\t\t$objWriter->writeAttribute('state',\t\t'frozen');\n\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\tif (($xSplit > 1) && ($ySplit > 1)) {\n\t\t\t\t\t\t//\tWrite additional selections if more than two panes (ie both an X and a Y split)\n\t\t\t\t\t\t$objWriter->startElement('selection');\t$objWriter->writeAttribute('pane', 'topRight');\t\t$objWriter->endElement();\n\t\t\t\t\t\t$objWriter->startElement('selection');\t$objWriter->writeAttribute('pane', 'bottomLeft');\t$objWriter->endElement();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Selection\n//\t\t\t\tif ($pane != '') {\n\t\t\t\t\t//\tOnly need to write selection element if we have a split pane\n\t\t\t\t\t//\t\tWe cheat a little by over-riding the active cell selection, setting it to the split cell\n\t\t\t\t\t$objWriter->startElement('selection');\n\t\t\t\t\tif ($pane != '') {\n\t\t\t\t\t\t$objWriter->writeAttribute('pane', $pane);\n\t\t\t\t\t}\n\t\t\t\t\t$objWriter->writeAttribute('activeCell', $activeCell);\n\t\t\t\t\t$objWriter->writeAttribute('sqref', $activeCell);\n\t\t\t\t\t$objWriter->endElement();\n//\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write SheetFormatPr\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter $objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t  $pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeSheetFormatPr(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// sheetFormatPr\n\t\t$objWriter->startElement('sheetFormatPr');\n\n\t\t\t// Default row height\n\t\t\tif ($pSheet->getDefaultRowDimension()->getRowHeight() >= 0) {\n\t\t\t\t$objWriter->writeAttribute('customHeight',\t\t'true');\n\t\t\t\t$objWriter->writeAttribute('defaultRowHeight',\tPHPExcel_Shared_String::FormatNumber($pSheet->getDefaultRowDimension()->getRowHeight()));\n\t\t\t} else {\n\t\t\t\t$objWriter->writeAttribute('defaultRowHeight', '14.4');\n\t\t\t}\n\n\t\t\t// Set Zero Height row\n\t\t\tif ((string)$pSheet->getDefaultRowDimension()->getZeroHeight()  == '1' ||\n\t\t\t\tstrtolower((string)$pSheet->getDefaultRowDimension()->getZeroHeight()) == 'true' ) {\n\t\t\t\t$objWriter->writeAttribute('zeroHeight', '1');\n\t\t\t}\n\n\t\t\t// Default column width\n\t\t\tif ($pSheet->getDefaultColumnDimension()->getWidth() >= 0) {\n\t\t\t\t$objWriter->writeAttribute('defaultColWidth', PHPExcel_Shared_String::FormatNumber($pSheet->getDefaultColumnDimension()->getWidth()));\n\t\t\t}\n\n\t\t\t// Outline level - row\n\t\t\t$outlineLevelRow = 0;\n\t\t\tforeach ($pSheet->getRowDimensions() as $dimension) {\n\t\t\t\tif ($dimension->getOutlineLevel() > $outlineLevelRow) {\n\t\t\t\t\t$outlineLevelRow = $dimension->getOutlineLevel();\n\t\t\t\t}\n\t\t\t}\n\t\t\t$objWriter->writeAttribute('outlineLevelRow',\t(int)$outlineLevelRow);\n\n\t\t\t// Outline level - column\n\t\t\t$outlineLevelCol = 0;\n\t\t\tforeach ($pSheet->getColumnDimensions() as $dimension) {\n\t\t\t\tif ($dimension->getOutlineLevel() > $outlineLevelCol) {\n\t\t\t\t\t$outlineLevelCol = $dimension->getOutlineLevel();\n\t\t\t\t}\n\t\t\t}\n\t\t\t$objWriter->writeAttribute('outlineLevelCol',\t(int)$outlineLevelCol);\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write Cols\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeCols(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// cols\n\t\tif (count($pSheet->getColumnDimensions()) > 0)  {\n\t\t\t$objWriter->startElement('cols');\n\n\t\t\t\t$pSheet->calculateColumnWidths();\n\n\t\t\t\t// Loop through column dimensions\n\t\t\t\tforeach ($pSheet->getColumnDimensions() as $colDimension) {\n\t\t\t\t\t// col\n\t\t\t\t\t$objWriter->startElement('col');\n\t\t\t\t\t$objWriter->writeAttribute('min',\tPHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex()));\n\t\t\t\t\t$objWriter->writeAttribute('max',\tPHPExcel_Cell::columnIndexFromString($colDimension->getColumnIndex()));\n\n\t\t\t\t\tif ($colDimension->getWidth() < 0) {\n\t\t\t\t\t\t// No width set, apply default of 10\n\t\t\t\t\t\t$objWriter->writeAttribute('width',\t\t'9.10');\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// Width set\n\t\t\t\t\t\t$objWriter->writeAttribute('width',\t\tPHPExcel_Shared_String::FormatNumber($colDimension->getWidth()));\n\t\t\t\t\t}\n\n\t\t\t\t\t// Column visibility\n\t\t\t\t\tif ($colDimension->getVisible() == false) {\n\t\t\t\t\t\t$objWriter->writeAttribute('hidden',\t\t'true');\n\t\t\t\t\t}\n\n\t\t\t\t\t// Auto size?\n\t\t\t\t\tif ($colDimension->getAutoSize()) {\n\t\t\t\t\t\t$objWriter->writeAttribute('bestFit',\t\t'true');\n\t\t\t\t\t}\n\n\t\t\t\t\t// Custom width?\n\t\t\t\t\tif ($colDimension->getWidth() != $pSheet->getDefaultColumnDimension()->getWidth()) {\n\t\t\t\t\t\t$objWriter->writeAttribute('customWidth',\t'true');\n\t\t\t\t\t}\n\n\t\t\t\t\t// Collapsed\n\t\t\t\t\tif ($colDimension->getCollapsed() == true) {\n\t\t\t\t\t\t$objWriter->writeAttribute('collapsed',\t\t'true');\n\t\t\t\t\t}\n\n\t\t\t\t\t// Outline level\n\t\t\t\t\tif ($colDimension->getOutlineLevel() > 0) {\n\t\t\t\t\t\t$objWriter->writeAttribute('outlineLevel',\t$colDimension->getOutlineLevel());\n\t\t\t\t\t}\n\n\t\t\t\t\t// Style\n\t\t\t\t\t$objWriter->writeAttribute('style', $colDimension->getXfIndex());\n\n\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write SheetProtection\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeSheetProtection(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// sheetProtection\n\t\t$objWriter->startElement('sheetProtection');\n\n\t\tif ($pSheet->getProtection()->getPassword() != '') {\n\t\t\t$objWriter->writeAttribute('password',\t\t\t\t$pSheet->getProtection()->getPassword());\n\t\t}\n\n\t\t$objWriter->writeAttribute('sheet',\t\t\t\t\t($pSheet->getProtection()->getSheet()\t\t\t\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('objects',\t\t\t\t($pSheet->getProtection()->getObjects()\t\t\t\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('scenarios',\t\t\t\t($pSheet->getProtection()->getScenarios()\t\t\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('formatCells',\t\t\t($pSheet->getProtection()->getFormatCells()\t\t\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('formatColumns',\t\t\t($pSheet->getProtection()->getFormatColumns()\t\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('formatRows',\t\t\t($pSheet->getProtection()->getFormatRows()\t\t\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('insertColumns',\t\t\t($pSheet->getProtection()->getInsertColumns()\t\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('insertRows',\t\t\t($pSheet->getProtection()->getInsertRows()\t\t\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('insertHyperlinks',\t\t($pSheet->getProtection()->getInsertHyperlinks()\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('deleteColumns',\t\t\t($pSheet->getProtection()->getDeleteColumns()\t\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('deleteRows',\t\t\t($pSheet->getProtection()->getDeleteRows()\t\t\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('selectLockedCells',\t\t($pSheet->getProtection()->getSelectLockedCells()\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('sort',\t\t\t\t\t($pSheet->getProtection()->getSort()\t\t\t\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('autoFilter',\t\t\t($pSheet->getProtection()->getAutoFilter()\t\t\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('pivotTables',\t\t\t($pSheet->getProtection()->getPivotTables()\t\t\t? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('selectUnlockedCells',\t($pSheet->getProtection()->getSelectUnlockedCells()\t? 'true' : 'false'));\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write ConditionalFormatting\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeConditionalFormatting(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// Conditional id\n\t\t$id = 1;\n\n\t\t// Loop through styles in the current worksheet\n\t\tforeach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {\n\t\t\tforeach ($conditionalStyles as $conditional) {\n\t\t\t\t// WHY was this again?\n\t\t\t\t// if ($this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() ) == '') {\n\t\t\t\t//\tcontinue;\n\t\t\t\t// }\n\t\t\t\tif ($conditional->getConditionType() != PHPExcel_Style_Conditional::CONDITION_NONE) {\n\t\t\t\t\t// conditionalFormatting\n\t\t\t\t\t$objWriter->startElement('conditionalFormatting');\n\t\t\t\t\t$objWriter->writeAttribute('sqref',\t$cellCoordinate);\n\n\t\t\t\t\t\t// cfRule\n\t\t\t\t\t\t$objWriter->startElement('cfRule');\n\t\t\t\t\t\t$objWriter->writeAttribute('type',\t\t$conditional->getConditionType());\n\t\t\t\t\t\t$objWriter->writeAttribute('dxfId',\t\t$this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode( $conditional->getHashCode() ));\n\t\t\t\t\t\t$objWriter->writeAttribute('priority',\t$id++);\n\n\t\t\t\t\t\tif (($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS\n\t\t\t\t\t\t\t\t||\n\t\t\t\t\t\t\t $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT)\n\t\t\t\t\t\t\t&& $conditional->getOperatorType() != PHPExcel_Style_Conditional::OPERATOR_NONE) {\n\t\t\t\t\t\t\t$objWriter->writeAttribute('operator',\t$conditional->getOperatorType());\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT\n\t\t\t\t\t\t\t&& !is_null($conditional->getText())) {\n\t\t\t\t\t\t\t$objWriter->writeAttribute('text',\t$conditional->getText());\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT\n\t\t\t\t\t\t\t&& $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_CONTAINSTEXT\n\t\t\t\t\t\t\t&& !is_null($conditional->getText())) {\n\t\t\t\t\t\t\t$objWriter->writeElement('formula',\t'NOT(ISERROR(SEARCH(\"' . $conditional->getText() . '\",' . $cellCoordinate . ')))');\n\t\t\t\t\t\t} else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT\n\t\t\t\t\t\t\t&& $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BEGINSWITH\n\t\t\t\t\t\t\t&& !is_null($conditional->getText())) {\n\t\t\t\t\t\t\t$objWriter->writeElement('formula',\t'LEFT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')=\"' . $conditional->getText() . '\"');\n\t\t\t\t\t\t} else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT\n\t\t\t\t\t\t\t&& $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_ENDSWITH\n\t\t\t\t\t\t\t&& !is_null($conditional->getText())) {\n\t\t\t\t\t\t\t$objWriter->writeElement('formula',\t'RIGHT(' . $cellCoordinate . ',' . strlen($conditional->getText()) . ')=\"' . $conditional->getText() . '\"');\n\t\t\t\t\t\t} else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT\n\t\t\t\t\t\t\t&& $conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_NOTCONTAINS\n\t\t\t\t\t\t\t&& !is_null($conditional->getText())) {\n\t\t\t\t\t\t\t$objWriter->writeElement('formula',\t'ISERROR(SEARCH(\"' . $conditional->getText() . '\",' . $cellCoordinate . '))');\n\t\t\t\t\t\t} else if ($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS\n\t\t\t\t\t\t\t|| $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CONTAINSTEXT\n\t\t\t\t\t\t\t|| $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION) {\n\t\t\t\t\t\t\tforeach ($conditional->getConditions() as $formula) {\n\t\t\t\t\t\t\t\t// Formula\n\t\t\t\t\t\t\t\t$objWriter->writeElement('formula',\t$formula);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Write DataValidations\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeDataValidations(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// Datavalidation collection\n\t\t$dataValidationCollection = $pSheet->getDataValidationCollection();\n\n\t\t// Write data validations?\n\t\tif (!empty($dataValidationCollection)) {\n\t\t\t$objWriter->startElement('dataValidations');\n\t\t\t$objWriter->writeAttribute('count', count($dataValidationCollection));\n\n\t\t\tforeach ($dataValidationCollection as $coordinate => $dv) {\n\t\t\t\t$objWriter->startElement('dataValidation');\n\n\t\t\t\tif ($dv->getType() != '') {\n\t\t\t\t\t$objWriter->writeAttribute('type', $dv->getType());\n\t\t\t\t}\n\n\t\t\t\tif ($dv->getErrorStyle() != '') {\n\t\t\t\t\t$objWriter->writeAttribute('errorStyle', $dv->getErrorStyle());\n\t\t\t\t}\n\n\t\t\t\tif ($dv->getOperator() != '') {\n\t\t\t\t\t$objWriter->writeAttribute('operator', $dv->getOperator());\n\t\t\t\t}\n\n\t\t\t\t$objWriter->writeAttribute('allowBlank',\t\t($dv->getAllowBlank()\t\t? '1'  : '0'));\n\t\t\t\t$objWriter->writeAttribute('showDropDown',\t\t(!$dv->getShowDropDown()\t? '1'  : '0'));\n\t\t\t\t$objWriter->writeAttribute('showInputMessage',\t($dv->getShowInputMessage()\t? '1'  : '0'));\n\t\t\t\t$objWriter->writeAttribute('showErrorMessage',\t($dv->getShowErrorMessage()\t? '1'  : '0'));\n\n\t\t\t\tif ($dv->getErrorTitle() !== '') {\n\t\t\t\t\t$objWriter->writeAttribute('errorTitle', $dv->getErrorTitle());\n\t\t\t\t}\n\t\t\t\tif ($dv->getError() !== '') {\n\t\t\t\t\t$objWriter->writeAttribute('error', $dv->getError());\n\t\t\t\t}\n\t\t\t\tif ($dv->getPromptTitle() !== '') {\n\t\t\t\t\t$objWriter->writeAttribute('promptTitle', $dv->getPromptTitle());\n\t\t\t\t}\n\t\t\t\tif ($dv->getPrompt() !== '') {\n\t\t\t\t\t$objWriter->writeAttribute('prompt', $dv->getPrompt());\n\t\t\t\t}\n\n\t\t\t\t$objWriter->writeAttribute('sqref', $coordinate);\n\n\t\t\t\tif ($dv->getFormula1() !== '') {\n\t\t\t\t\t$objWriter->writeElement('formula1', $dv->getFormula1());\n\t\t\t\t}\n\t\t\t\tif ($dv->getFormula2() !== '') {\n\t\t\t\t\t$objWriter->writeElement('formula2', $dv->getFormula2());\n\t\t\t\t}\n\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write Hyperlinks\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeHyperlinks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// Hyperlink collection\n\t\t$hyperlinkCollection = $pSheet->getHyperlinkCollection();\n\n\t\t// Relation ID\n\t\t$relationId = 1;\n\n\t\t// Write hyperlinks?\n\t\tif (!empty($hyperlinkCollection)) {\n\t\t\t$objWriter->startElement('hyperlinks');\n\n\t\t\tforeach ($hyperlinkCollection as $coordinate => $hyperlink) {\n\t\t\t\t$objWriter->startElement('hyperlink');\n\n\t\t\t\t$objWriter->writeAttribute('ref', $coordinate);\n\t\t\t\tif (!$hyperlink->isInternal()) {\n\t\t\t\t\t$objWriter->writeAttribute('r:id',\t'rId_hyperlink_' . $relationId);\n\t\t\t\t\t++$relationId;\n\t\t\t\t} else {\n\t\t\t\t\t$objWriter->writeAttribute('location',\tstr_replace('sheet://', '', $hyperlink->getUrl()));\n\t\t\t\t}\n\n\t\t\t\tif ($hyperlink->getTooltip() != '') {\n\t\t\t\t\t$objWriter->writeAttribute('tooltip', $hyperlink->getTooltip());\n\t\t\t\t}\n\n\t\t\t\t$objWriter->endElement();\n\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write ProtectedRanges\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeProtectedRanges(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\tif (count($pSheet->getProtectedCells()) > 0) {\n\t\t\t// protectedRanges\n\t\t\t$objWriter->startElement('protectedRanges');\n\n\t\t\t\t// Loop protectedRanges\n\t\t\t\tforeach ($pSheet->getProtectedCells() as $protectedCell => $passwordHash) {\n\t\t\t\t\t// protectedRange\n\t\t\t\t\t$objWriter->startElement('protectedRange');\n\t\t\t\t\t$objWriter->writeAttribute('name',\t\t'p' . md5($protectedCell));\n\t\t\t\t\t$objWriter->writeAttribute('sqref',\t$protectedCell);\n\t\t\t\t\tif (!empty($passwordHash)) {\n\t\t\t\t\t\t$objWriter->writeAttribute('password',\t$passwordHash);\n\t\t\t\t\t}\n\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write MergeCells\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeMergeCells(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\tif (count($pSheet->getMergeCells()) > 0) {\n\t\t\t// mergeCells\n\t\t\t$objWriter->startElement('mergeCells');\n\n\t\t\t\t// Loop mergeCells\n\t\t\t\tforeach ($pSheet->getMergeCells() as $mergeCell) {\n\t\t\t\t\t// mergeCell\n\t\t\t\t\t$objWriter->startElement('mergeCell');\n\t\t\t\t\t$objWriter->writeAttribute('ref', $mergeCell);\n\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write PrintOptions\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writePrintOptions(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// printOptions\n\t\t$objWriter->startElement('printOptions');\n\n\t\t$objWriter->writeAttribute('gridLines',\t($pSheet->getPrintGridlines() ? 'true': 'false'));\n\t\t$objWriter->writeAttribute('gridLinesSet',\t'true');\n\n\t\tif ($pSheet->getPageSetup()->getHorizontalCentered()) {\n\t\t\t$objWriter->writeAttribute('horizontalCentered', 'true');\n\t\t}\n\n\t\tif ($pSheet->getPageSetup()->getVerticalCentered()) {\n\t\t\t$objWriter->writeAttribute('verticalCentered', 'true');\n\t\t}\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write PageMargins\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writePageMargins(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// pageMargins\n\t\t$objWriter->startElement('pageMargins');\n\t\t$objWriter->writeAttribute('left',\t\tPHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft()));\n\t\t$objWriter->writeAttribute('right',\t\tPHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight()));\n\t\t$objWriter->writeAttribute('top',\t\tPHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop()));\n\t\t$objWriter->writeAttribute('bottom',\tPHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom()));\n\t\t$objWriter->writeAttribute('header',\tPHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getHeader()));\n\t\t$objWriter->writeAttribute('footer',\tPHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getFooter()));\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write AutoFilter\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeAutoFilter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t$autoFilterRange = $pSheet->getAutoFilter()->getRange();\n\t\tif (!empty($autoFilterRange)) {\n\t\t\t// autoFilter\n\t\t\t$objWriter->startElement('autoFilter');\n\n\t\t\t// Strip any worksheet reference from the filter coordinates\n\t\t\t$range = PHPExcel_Cell::splitRange($autoFilterRange);\n\t\t\t$range = $range[0];\n\t\t\t//\tStrip any worksheet ref\n\t\t\tif (strpos($range[0],'!') !== false) {\n\t\t\t\tlist($ws,$range[0]) = explode('!',$range[0]);\n\t\t\t}\n\t\t\t$range = implode(':', $range);\n\n\t\t\t$objWriter->writeAttribute('ref',\tstr_replace('$','',$range));\n\n\t\t\t$columns = $pSheet->getAutoFilter()->getColumns();\n\t\t\tif (count($columns > 0)) {\n\t\t\t\tforeach($columns as $columnID => $column) {\n\t\t\t\t\t$rules = $column->getRules();\n\t\t\t\t\tif (count($rules > 0)) {\n\t\t\t\t\t\t$objWriter->startElement('filterColumn');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('colId',\t$pSheet->getAutoFilter()->getColumnOffset($columnID));\n\n\t\t\t\t\t\t\t$objWriter->startElement( $column->getFilterType());\n\t\t\t\t\t\t\t\tif ($column->getJoin() == PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND) {\n\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('and',\t1);\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\tforeach ($rules as $rule) {\n\t\t\t\t\t\t\t\t\tif (($column->getFilterType() === PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER) &&\n\t\t\t\t\t\t\t\t\t\t($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) &&\n\t\t\t\t\t\t\t\t\t\t($rule->getValue() === '')) {\n\t\t\t\t\t\t\t\t\t\t//\tFilter rule for Blanks\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('blank',\t1);\n\t\t\t\t\t\t\t\t\t} elseif($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER) {\n\t\t\t\t\t\t\t\t\t\t//\tDynamic Filter Rule\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('type', $rule->getGrouping());\n\t\t\t\t\t\t\t\t\t\t$val = $column->getAttribute('val');\n\t\t\t\t\t\t\t\t\t\tif ($val !== NULL) {\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val', $val);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t$maxVal = $column->getAttribute('maxVal');\n\t\t\t\t\t\t\t\t\t\tif ($maxVal !== NULL) {\n\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('maxVal', $maxVal);\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t} elseif($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_TOPTENFILTER) {\n\t\t\t\t\t\t\t\t\t\t//\tTop 10 Filter Rule\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val',\t$rule->getValue());\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('percent',\t(($rule->getOperator() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) ? '1' : '0'));\n\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('top',\t(($rule->getGrouping() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_TOP) ? '1': '0'));\n\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t//\tFilter, DateGroupItem or CustomFilter\n\t\t\t\t\t\t\t\t\t\t$objWriter->startElement($rule->getRuleType());\n\n\t\t\t\t\t\t\t\t\t\t\tif ($rule->getOperator() !== PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL) {\n\t\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('operator',\t$rule->getOperator());\n\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\tif ($rule->getRuleType() === PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP) {\n\t\t\t\t\t\t\t\t\t\t\t\t// Date Group filters\n\t\t\t\t\t\t\t\t\t\t\t\tforeach($rule->getValue() as $key => $value) {\n\t\t\t\t\t\t\t\t\t\t\t\t\tif ($value > '') $objWriter->writeAttribute($key,\t$value);\n\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('dateTimeGrouping',\t$rule->getGrouping());\n\t\t\t\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t\t\t\t$objWriter->writeAttribute('val',\t$rule->getValue());\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t$objWriter->endElement();\n\n\t\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write PageSetup\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writePageSetup(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// pageSetup\n\t\t$objWriter->startElement('pageSetup');\n\t\t$objWriter->writeAttribute('paperSize',\t\t$pSheet->getPageSetup()->getPaperSize());\n\t\t$objWriter->writeAttribute('orientation',\t$pSheet->getPageSetup()->getOrientation());\n\n\t\tif (!is_null($pSheet->getPageSetup()->getScale())) {\n\t\t\t$objWriter->writeAttribute('scale',\t\t\t\t $pSheet->getPageSetup()->getScale());\n\t\t}\n\t\tif (!is_null($pSheet->getPageSetup()->getFitToHeight())) {\n\t\t\t$objWriter->writeAttribute('fitToHeight',\t\t $pSheet->getPageSetup()->getFitToHeight());\n\t\t} else {\n\t\t\t$objWriter->writeAttribute('fitToHeight',\t\t '0');\n\t\t}\n\t\tif (!is_null($pSheet->getPageSetup()->getFitToWidth())) {\n\t\t\t$objWriter->writeAttribute('fitToWidth',\t\t $pSheet->getPageSetup()->getFitToWidth());\n\t\t} else {\n\t\t\t$objWriter->writeAttribute('fitToWidth',\t\t '0');\n\t\t}\n\t\tif (!is_null($pSheet->getPageSetup()->getFirstPageNumber())) {\n\t\t\t$objWriter->writeAttribute('firstPageNumber',\t$pSheet->getPageSetup()->getFirstPageNumber());\n\t\t\t$objWriter->writeAttribute('useFirstPageNumber', '1');\n\t\t}\n\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write Header / Footer\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeHeaderFooter(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// headerFooter\n\t\t$objWriter->startElement('headerFooter');\n\t\t$objWriter->writeAttribute('differentOddEven',\t($pSheet->getHeaderFooter()->getDifferentOddEven() ? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('differentFirst',\t($pSheet->getHeaderFooter()->getDifferentFirst() ? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('scaleWithDoc',\t\t($pSheet->getHeaderFooter()->getScaleWithDocument() ? 'true' : 'false'));\n\t\t$objWriter->writeAttribute('alignWithMargins',\t($pSheet->getHeaderFooter()->getAlignWithMargins() ? 'true' : 'false'));\n\n\t\t\t$objWriter->writeElement('oddHeader',\t\t$pSheet->getHeaderFooter()->getOddHeader());\n\t\t\t$objWriter->writeElement('oddFooter',\t\t$pSheet->getHeaderFooter()->getOddFooter());\n\t\t\t$objWriter->writeElement('evenHeader',\t\t$pSheet->getHeaderFooter()->getEvenHeader());\n\t\t\t$objWriter->writeElement('evenFooter',\t\t$pSheet->getHeaderFooter()->getEvenFooter());\n\t\t\t$objWriter->writeElement('firstHeader',\t$pSheet->getHeaderFooter()->getFirstHeader());\n\t\t\t$objWriter->writeElement('firstFooter',\t$pSheet->getHeaderFooter()->getFirstFooter());\n\t\t$objWriter->endElement();\n\t}\n\n\t/**\n\t * Write Breaks\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeBreaks(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// Get row and column breaks\n\t\t$aRowBreaks = array();\n\t\t$aColumnBreaks = array();\n\t\tforeach ($pSheet->getBreaks() as $cell => $breakType) {\n\t\t\tif ($breakType == PHPExcel_Worksheet::BREAK_ROW) {\n\t\t\t\t$aRowBreaks[] = $cell;\n\t\t\t} else if ($breakType == PHPExcel_Worksheet::BREAK_COLUMN) {\n\t\t\t\t$aColumnBreaks[] = $cell;\n\t\t\t}\n\t\t}\n\n\t\t// rowBreaks\n\t\tif (!empty($aRowBreaks)) {\n\t\t\t$objWriter->startElement('rowBreaks');\n\t\t\t$objWriter->writeAttribute('count',\t\t\tcount($aRowBreaks));\n\t\t\t$objWriter->writeAttribute('manualBreakCount',\tcount($aRowBreaks));\n\n\t\t\t\tforeach ($aRowBreaks as $cell) {\n\t\t\t\t\t$coords = PHPExcel_Cell::coordinateFromString($cell);\n\n\t\t\t\t\t$objWriter->startElement('brk');\n\t\t\t\t\t$objWriter->writeAttribute('id',\t$coords[1]);\n\t\t\t\t\t$objWriter->writeAttribute('man',\t'1');\n\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\n\t\t// Second, write column breaks\n\t\tif (!empty($aColumnBreaks)) {\n\t\t\t$objWriter->startElement('colBreaks');\n\t\t\t$objWriter->writeAttribute('count',\t\t\tcount($aColumnBreaks));\n\t\t\t$objWriter->writeAttribute('manualBreakCount',\tcount($aColumnBreaks));\n\n\t\t\t\tforeach ($aColumnBreaks as $cell) {\n\t\t\t\t\t$coords = PHPExcel_Cell::coordinateFromString($cell);\n\n\t\t\t\t\t$objWriter->startElement('brk');\n\t\t\t\t\t$objWriter->writeAttribute('id',\tPHPExcel_Cell::columnIndexFromString($coords[0]) - 1);\n\t\t\t\t\t$objWriter->writeAttribute('man',\t'1');\n\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write SheetData\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @param\tstring[]\t\t\t\t\t\t$pStringTable\tString table\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeSheetData(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pStringTable = null)\n\t{\n\t\tif (is_array($pStringTable)) {\n\t\t\t// Flipped stringtable, for faster index searching\n\t\t\t$aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable);\n\n\t\t\t// sheetData\n\t\t\t$objWriter->startElement('sheetData');\n\n\t\t\t\t// Get column count\n\t\t\t\t$colCount = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn());\n\n\t\t\t\t// Highest row number\n\t\t\t\t$highestRow = $pSheet->getHighestRow();\n\n\t\t\t\t// Loop through cells\n\t\t\t\t$cellsByRow = array();\n\t\t\t\tforeach ($pSheet->getCellCollection() as $cellID) {\n\t\t\t\t\t$cellAddress = PHPExcel_Cell::coordinateFromString($cellID);\n\t\t\t\t\t$cellsByRow[$cellAddress[1]][] = $cellID;\n\t\t\t\t}\n\n\t\t\t\t$currentRow = 0;\n\t\t\t\twhile($currentRow++ < $highestRow) {\n\t\t\t\t\t// Get row dimension\n\t\t\t\t\t$rowDimension = $pSheet->getRowDimension($currentRow);\n\n\t\t\t\t\t// Write current row?\n\t\t\t\t\t$writeCurrentRow =\tisset($cellsByRow[$currentRow]) ||\n\t\t\t\t\t\t\t\t\t\t$rowDimension->getRowHeight() >= 0 ||\n\t\t\t\t\t\t\t\t\t\t$rowDimension->getVisible() == false ||\n\t\t\t\t\t\t\t\t\t\t$rowDimension->getCollapsed() == true ||\n\t\t\t\t\t\t\t\t\t\t$rowDimension->getOutlineLevel() > 0 ||\n\t\t\t\t\t\t\t\t\t\t$rowDimension->getXfIndex() !== null;\n\n\t\t\t\t\tif ($writeCurrentRow) {\n\t\t\t\t\t\t// Start a new row\n\t\t\t\t\t\t$objWriter->startElement('row');\n\t\t\t\t\t\t$objWriter->writeAttribute('r',\t$currentRow);\n\t\t\t\t\t\t$objWriter->writeAttribute('spans',\t'1:' . $colCount);\n\n\t\t\t\t\t\t// Row dimensions\n\t\t\t\t\t\tif ($rowDimension->getRowHeight() >= 0) {\n\t\t\t\t\t\t\t$objWriter->writeAttribute('customHeight',\t'1');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('ht',\t\t\tPHPExcel_Shared_String::FormatNumber($rowDimension->getRowHeight()));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Row visibility\n\t\t\t\t\t\tif ($rowDimension->getVisible() == false) {\n\t\t\t\t\t\t\t$objWriter->writeAttribute('hidden',\t\t'true');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Collapsed\n\t\t\t\t\t\tif ($rowDimension->getCollapsed() == true) {\n\t\t\t\t\t\t\t$objWriter->writeAttribute('collapsed',\t\t'true');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Outline level\n\t\t\t\t\t\tif ($rowDimension->getOutlineLevel() > 0) {\n\t\t\t\t\t\t\t$objWriter->writeAttribute('outlineLevel',\t$rowDimension->getOutlineLevel());\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Style\n\t\t\t\t\t\tif ($rowDimension->getXfIndex() !== null) {\n\t\t\t\t\t\t\t$objWriter->writeAttribute('s',\t$rowDimension->getXfIndex());\n\t\t\t\t\t\t\t$objWriter->writeAttribute('customFormat', '1');\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// Write cells\n\t\t\t\t\t\tif (isset($cellsByRow[$currentRow])) {\n\t\t\t\t\t\t\tforeach($cellsByRow[$currentRow] as $cellAddress) {\n\t\t\t\t\t\t\t\t// Write cell\n\t\t\t\t\t\t\t\t$this->_writeCell($objWriter, $pSheet, $cellAddress, $pStringTable, $aFlippedStringTable);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// End row\n\t\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Invalid parameters passed.\");\n\t\t}\n\t}\n\n\t/**\n\t * Write Cell\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t$objWriter\t\t\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t$pSheet\t\t\t\t\tWorksheet\n\t * @param\tPHPExcel_Cell\t\t\t\t$pCellAddress\t\t\tCell Address\n\t * @param\tstring[]\t\t\t\t\t$pStringTable\t\t\tString table\n\t * @param\tstring[]\t\t\t\t\t$pFlippedStringTable\tString table (flipped), for faster index searching\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeCell(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $pCellAddress = null, $pStringTable = null, $pFlippedStringTable = null)\n\t{\n\t\tif (is_array($pStringTable) && is_array($pFlippedStringTable)) {\n\t\t\t// Cell\n\t\t\t$pCell = $pSheet->getCell($pCellAddress);\n\t\t\t$objWriter->startElement('c');\n\t\t\t$objWriter->writeAttribute('r', $pCellAddress);\n\n\t\t\t// Sheet styles\n\t\t\tif ($pCell->getXfIndex() != '') {\n\t\t\t\t$objWriter->writeAttribute('s', $pCell->getXfIndex());\n\t\t\t}\n\n\t\t\t// If cell value is supplied, write cell value\n\t\t\t$cellValue = $pCell->getValue();\n\t\t\tif (is_object($cellValue) || $cellValue !== '') {\n\t\t\t\t// Map type\n\t\t\t\t$mappedType = $pCell->getDataType();\n\n\t\t\t\t// Write data type depending on its type\n\t\t\t\tswitch (strtolower($mappedType)) {\n\t\t\t\t\tcase 'inlinestr':\t// Inline string\n\t\t\t\t\tcase 's':\t\t\t// String\n\t\t\t\t\tcase 'b':\t\t\t// Boolean\n\t\t\t\t\t\t$objWriter->writeAttribute('t', $mappedType);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'f':\t\t\t// Formula\n\t\t\t\t\t\t$calculatedValue = ($this->getParentWriter()->getPreCalculateFormulas()) ?\n\t\t\t\t\t\t    $pCell->getCalculatedValue() :\n\t\t\t\t\t\t    $cellValue;\n\t\t\t\t\t\tif (is_string($calculatedValue)) {\n\t\t\t\t\t\t\t$objWriter->writeAttribute('t', 'str');\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'e':\t\t\t// Error\n\t\t\t\t\t\t$objWriter->writeAttribute('t', $mappedType);\n\t\t\t\t}\n\n\t\t\t\t// Write data depending on its type\n\t\t\t\tswitch (strtolower($mappedType)) {\n\t\t\t\t\tcase 'inlinestr':\t// Inline string\n\t\t\t\t\t\tif (! $cellValue instanceof PHPExcel_RichText) {\n\t\t\t\t\t\t\t$objWriter->writeElement('t', PHPExcel_Shared_String::ControlCharacterPHP2OOXML( htmlspecialchars($cellValue) ) );\n\t\t\t\t\t\t} else if ($cellValue instanceof PHPExcel_RichText) {\n\t\t\t\t\t\t\t$objWriter->startElement('is');\n\t\t\t\t\t\t\t$this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue);\n\t\t\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 's':\t\t\t// String\n\t\t\t\t\t\tif (! $cellValue instanceof PHPExcel_RichText) {\n\t\t\t\t\t\t\tif (isset($pFlippedStringTable[$cellValue])) {\n\t\t\t\t\t\t\t\t$objWriter->writeElement('v', $pFlippedStringTable[$cellValue]);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else if ($cellValue instanceof PHPExcel_RichText) {\n\t\t\t\t\t\t\t$objWriter->writeElement('v', $pFlippedStringTable[$cellValue->getHashCode()]);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'f':\t\t\t// Formula\n\t\t\t\t\t\t$attributes = $pCell->getFormulaAttributes();\n\t\t\t\t\t\tif($attributes['t'] == 'array') {\n\t\t\t\t\t\t\t$objWriter->startElement('f');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('t', 'array');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('ref', $pCellAddress);\n\t\t\t\t\t\t\t$objWriter->writeAttribute('aca', '1');\n\t\t\t\t\t\t\t$objWriter->writeAttribute('ca', '1');\n\t\t\t\t\t\t\t$objWriter->text(substr($cellValue, 1));\n\t\t\t\t\t\t\t$objWriter->endElement();\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$objWriter->writeElement('f', substr($cellValue, 1));\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ($this->getParentWriter()->getOffice2003Compatibility() === false) {\n\t\t\t\t\t\t\tif ($this->getParentWriter()->getPreCalculateFormulas()) {\n//\t\t\t\t\t\t\t\t$calculatedValue = $pCell->getCalculatedValue();\n\t\t\t\t\t\t\t\tif (!is_array($calculatedValue) && substr($calculatedValue, 0, 1) != '#') {\n\t\t\t\t\t\t\t\t\t$objWriter->writeElement('v', PHPExcel_Shared_String::FormatNumber($calculatedValue));\n\t\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t\t$objWriter->writeElement('v', '0');\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\t$objWriter->writeElement('v', '0');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'n':\t\t\t// Numeric\n\t\t\t\t\t\t// force point as decimal separator in case current locale uses comma\n\t\t\t\t\t\t$objWriter->writeElement('v', str_replace(',', '.', $cellValue));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'b':\t\t\t// Boolean\n\t\t\t\t\t\t$objWriter->writeElement('v', ($cellValue ? '1' : '0'));\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'e':\t\t\t// Error\n\t\t\t\t\t\tif (substr($cellValue, 0, 1) == '=') {\n\t\t\t\t\t\t\t$objWriter->writeElement('f', substr($cellValue, 1));\n\t\t\t\t\t\t\t$objWriter->writeElement('v', substr($cellValue, 1));\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$objWriter->writeElement('v', $cellValue);\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$objWriter->endElement();\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Invalid parameters passed.\");\n\t\t}\n\t}\n\n\t/**\n\t * Write Drawings\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t$pSheet\t\t\tWorksheet\n\t * @param\tboolean\t\t\t\t\t\t$includeCharts\tFlag indicating if we should include drawing details for charts\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeDrawings(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null, $includeCharts = FALSE)\n\t{\n\t\t$chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0;\n\t\t// If sheet contains drawings, add the relationships\n\t\tif (($pSheet->getDrawingCollection()->count() > 0) ||\n\t\t\t($chartCount > 0)) {\n\t\t\t$objWriter->startElement('drawing');\n\t\t\t$objWriter->writeAttribute('r:id', 'rId1');\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write LegacyDrawing\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeLegacyDrawing(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// If sheet contains comments, add the relationships\n\t\tif (count($pSheet->getComments()) > 0) {\n\t\t\t$objWriter->startElement('legacyDrawing');\n\t\t\t$objWriter->writeAttribute('r:id', 'rId_comments_vml1');\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n\n\t/**\n\t * Write LegacyDrawingHF\n\t *\n\t * @param\tPHPExcel_Shared_XMLWriter\t\t$objWriter\t\tXML Writer\n\t * @param\tPHPExcel_Worksheet\t\t\t\t$pSheet\t\t\tWorksheet\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeLegacyDrawingHF(PHPExcel_Shared_XMLWriter $objWriter = null, PHPExcel_Worksheet $pSheet = null)\n\t{\n\t\t// If sheet contains images, add the relationships\n\t\tif (count($pSheet->getHeaderFooter()->getImages()) > 0) {\n\t\t\t$objWriter->startElement('legacyDrawingHF');\n\t\t\t$objWriter->writeAttribute('r:id', 'rId_headerfooter_vml1');\n\t\t\t$objWriter->endElement();\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007/WriterPart.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007_WriterPart\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nabstract class PHPExcel_Writer_Excel2007_WriterPart\n{\n\t/**\n\t * Parent IWriter object\n\t *\n\t * @var PHPExcel_Writer_IWriter\n\t */\n\tprivate $_parentWriter;\n\n\t/**\n\t * Set parent IWriter object\n\t *\n\t * @param PHPExcel_Writer_IWriter\t$pWriter\n\t * @throws PHPExcel_Writer_Exception\n\t */\n\tpublic function setParentWriter(PHPExcel_Writer_IWriter $pWriter = null) {\n\t\t$this->_parentWriter = $pWriter;\n\t}\n\n\t/**\n\t * Get parent IWriter object\n\t *\n\t * @return PHPExcel_Writer_IWriter\n\t * @throws PHPExcel_Writer_Exception\n\t */\n\tpublic function getParentWriter() {\n\t\tif (!is_null($this->_parentWriter)) {\n\t\t\treturn $this->_parentWriter;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"No parent PHPExcel_Writer_IWriter assigned.\");\n\t\t}\n\t}\n\n\t/**\n\t * Set parent IWriter object\n\t *\n\t * @param PHPExcel_Writer_IWriter\t$pWriter\n\t * @throws PHPExcel_Writer_Exception\n\t */\n\tpublic function __construct(PHPExcel_Writer_IWriter $pWriter = null) {\n\t\tif (!is_null($pWriter)) {\n\t\t\t$this->_parentWriter = $pWriter;\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel2007.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel2007\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_2007\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel2007 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter\n{\n\t/**\n\t * Pre-calculate formulas\n\t * Forces PHPExcel to recalculate all formulae in a workbook when saving, so that the pre-calculated values are\n\t *    immediately available to MS Excel or other office spreadsheet viewer when opening the file\n\t *\n     * Overrides the default TRUE for this specific writer for performance reasons\n     *\n\t * @var boolean\n\t */\n\tprotected $_preCalculateFormulas = FALSE;\n\n\t/**\n\t * Office2003 compatibility\n\t *\n\t * @var boolean\n\t */\n\tprivate $_office2003compatibility = false;\n\n\t/**\n\t * Private writer parts\n\t *\n\t * @var PHPExcel_Writer_Excel2007_WriterPart[]\n\t */\n\tprivate $_writerParts\t= array();\n\n\t/**\n\t * Private PHPExcel\n\t *\n\t * @var PHPExcel\n\t */\n\tprivate $_spreadSheet;\n\n\t/**\n\t * Private string table\n\t *\n\t * @var string[]\n\t */\n\tprivate $_stringTable\t= array();\n\n\t/**\n\t * Private unique PHPExcel_Style_Conditional HashTable\n\t *\n\t * @var PHPExcel_HashTable\n\t */\n\tprivate $_stylesConditionalHashTable;\n\n\t/**\n\t * Private unique PHPExcel_Style HashTable\n\t *\n\t * @var PHPExcel_HashTable\n\t */\n\tprivate $_styleHashTable;\n\n\t/**\n\t * Private unique PHPExcel_Style_Fill HashTable\n\t *\n\t * @var PHPExcel_HashTable\n\t */\n\tprivate $_fillHashTable;\n\n\t/**\n\t * Private unique PHPExcel_Style_Font HashTable\n\t *\n\t * @var PHPExcel_HashTable\n\t */\n\tprivate $_fontHashTable;\n\n\t/**\n\t * Private unique PHPExcel_Style_Borders HashTable\n\t *\n\t * @var PHPExcel_HashTable\n\t */\n\tprivate $_bordersHashTable ;\n\n\t/**\n\t * Private unique PHPExcel_Style_NumberFormat HashTable\n\t *\n\t * @var PHPExcel_HashTable\n\t */\n\tprivate $_numFmtHashTable;\n\n\t/**\n\t * Private unique PHPExcel_Worksheet_BaseDrawing HashTable\n\t *\n\t * @var PHPExcel_HashTable\n\t */\n\tprivate $_drawingHashTable;\n\n    /**\n     * Create a new PHPExcel_Writer_Excel2007\n     *\n\t * @param \tPHPExcel\t$pPHPExcel\n     */\n    public function __construct(PHPExcel $pPHPExcel = null)\n    {\n    \t// Assign PHPExcel\n\t\t$this->setPHPExcel($pPHPExcel);\n\n    \t$writerPartsArray = array(\t'stringtable'\t=> 'PHPExcel_Writer_Excel2007_StringTable',\n\t\t\t\t\t\t\t\t\t'contenttypes'\t=> 'PHPExcel_Writer_Excel2007_ContentTypes',\n\t\t\t\t\t\t\t\t\t'docprops' \t\t=> 'PHPExcel_Writer_Excel2007_DocProps',\n\t\t\t\t\t\t\t\t\t'rels'\t\t\t=> 'PHPExcel_Writer_Excel2007_Rels',\n\t\t\t\t\t\t\t\t\t'theme' \t\t=> 'PHPExcel_Writer_Excel2007_Theme',\n\t\t\t\t\t\t\t\t\t'style' \t\t=> 'PHPExcel_Writer_Excel2007_Style',\n\t\t\t\t\t\t\t\t\t'workbook' \t\t=> 'PHPExcel_Writer_Excel2007_Workbook',\n\t\t\t\t\t\t\t\t\t'worksheet' \t=> 'PHPExcel_Writer_Excel2007_Worksheet',\n\t\t\t\t\t\t\t\t\t'drawing' \t\t=> 'PHPExcel_Writer_Excel2007_Drawing',\n\t\t\t\t\t\t\t\t\t'comments' \t\t=> 'PHPExcel_Writer_Excel2007_Comments',\n\t\t\t\t\t\t\t\t\t'chart'\t\t\t=> 'PHPExcel_Writer_Excel2007_Chart',\n\t\t\t\t\t\t\t\t\t'relsvba'\t\t=> 'PHPExcel_Writer_Excel2007_RelsVBA',\n\t\t\t\t\t\t\t\t\t'relsribbonobjects' => 'PHPExcel_Writer_Excel2007_RelsRibbon'\n\t\t\t\t\t\t\t\t );\n\n    \t//\tInitialise writer parts\n\t\t//\t\tand Assign their parent IWriters\n\t\tforeach ($writerPartsArray as $writer => $class) {\n\t\t\t$this->_writerParts[$writer] = new $class($this);\n\t\t}\n\n    \t$hashTablesArray = array( '_stylesConditionalHashTable',\t'_fillHashTable',\t\t'_fontHashTable',\n\t\t\t\t\t\t\t\t  '_bordersHashTable',\t\t\t\t'_numFmtHashTable',\t\t'_drawingHashTable',\n                                  '_styleHashTable'\n\t\t\t\t\t\t\t    );\n\n\t\t// Set HashTable variables\n\t\tforeach ($hashTablesArray as $tableName) {\n\t\t\t$this->$tableName \t= new PHPExcel_HashTable();\n\t\t}\n    }\n\n\t/**\n\t * Get writer part\n\t *\n\t * @param \tstring \t$pPartName\t\tWriter part name\n\t * @return \tPHPExcel_Writer_Excel2007_WriterPart\n\t */\n\tpublic function getWriterPart($pPartName = '') {\n\t\tif ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) {\n\t\t\treturn $this->_writerParts[strtolower($pPartName)];\n\t\t} else {\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t/**\n\t * Save PHPExcel to file\n\t *\n\t * @param \tstring \t\t$pFilename\n\t * @throws \tPHPExcel_Writer_Exception\n\t */\n\tpublic function save($pFilename = null)\n\t{\n\t\tif ($this->_spreadSheet !== NULL) {\n\t\t\t// garbage collect\n\t\t\t$this->_spreadSheet->garbageCollect();\n\n\t\t\t// If $pFilename is php://output or php://stdout, make it a temporary file...\n\t\t\t$originalFilename = $pFilename;\n\t\t\tif (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {\n\t\t\t\t$pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp');\n\t\t\t\tif ($pFilename == '') {\n\t\t\t\t\t$pFilename = $originalFilename;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$saveDebugLog = PHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->getWriteDebugLog();\n\t\t\tPHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog(FALSE);\n\t\t\t$saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType();\n\t\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n\n\t\t\t// Create string lookup table\n\t\t\t$this->_stringTable = array();\n\t\t\tfor ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) {\n\t\t\t\t$this->_stringTable = $this->getWriterPart('StringTable')->createStringTable($this->_spreadSheet->getSheet($i), $this->_stringTable);\n\t\t\t}\n\n\t\t\t// Create styles dictionaries\n\t\t\t$this->_styleHashTable->addFromSource( \t            $this->getWriterPart('Style')->allStyles($this->_spreadSheet) \t\t\t);\n\t\t\t$this->_stylesConditionalHashTable->addFromSource( \t$this->getWriterPart('Style')->allConditionalStyles($this->_spreadSheet) \t\t\t);\n\t\t\t$this->_fillHashTable->addFromSource( \t\t\t\t$this->getWriterPart('Style')->allFills($this->_spreadSheet) \t\t\t);\n\t\t\t$this->_fontHashTable->addFromSource( \t\t\t\t$this->getWriterPart('Style')->allFonts($this->_spreadSheet) \t\t\t);\n\t\t\t$this->_bordersHashTable->addFromSource( \t\t\t$this->getWriterPart('Style')->allBorders($this->_spreadSheet) \t\t\t);\n\t\t\t$this->_numFmtHashTable->addFromSource( \t\t\t$this->getWriterPart('Style')->allNumberFormats($this->_spreadSheet) \t);\n\n\t\t\t// Create drawing dictionary\n\t\t\t$this->_drawingHashTable->addFromSource( \t\t\t$this->getWriterPart('Drawing')->allDrawings($this->_spreadSheet) \t\t);\n\n\t\t\t// Create new ZIP file and open it for writing\n\t\t\t$zipClass = PHPExcel_Settings::getZipClass();\n\t\t\t$objZip = new $zipClass();\n\n\t\t\t//\tRetrieve OVERWRITE and CREATE constants from the instantiated zip class\n\t\t\t//\tThis method of accessing constant values from a dynamic class should work with all appropriate versions of PHP\n\t\t\t$ro = new ReflectionObject($objZip);\n\t\t\t$zipOverWrite = $ro->getConstant('OVERWRITE');\n\t\t\t$zipCreate = $ro->getConstant('CREATE');\n\n\t\t\tif (file_exists($pFilename)) {\n\t\t\t\tunlink($pFilename);\n\t\t\t}\n\t\t\t// Try opening the ZIP file\n\t\t\tif ($objZip->open($pFilename, $zipOverWrite) !== true) {\n\t\t\t\tif ($objZip->open($pFilename, $zipCreate) !== true) {\n\t\t\t\t\tthrow new PHPExcel_Writer_Exception(\"Could not open \" . $pFilename . \" for writing.\");\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add [Content_Types].xml to ZIP file\n\t\t\t$objZip->addFromString('[Content_Types].xml', \t\t\t$this->getWriterPart('ContentTypes')->writeContentTypes($this->_spreadSheet, $this->_includeCharts));\n\n\t\t\t//if hasMacros, add the vbaProject.bin file, Certificate file(if exists)\n\t\t\tif($this->_spreadSheet->hasMacros()){\n\t\t\t\t$macrosCode=$this->_spreadSheet->getMacrosCode();\n\t\t\t\tif(!is_null($macrosCode)){// we have the code ?\n\t\t\t\t\t$objZip->addFromString('xl/vbaProject.bin', $macrosCode);//allways in 'xl', allways named vbaProject.bin\n\t\t\t\t\tif($this->_spreadSheet->hasMacrosCertificate()){//signed macros ?\n\t\t\t\t\t\t// Yes : add the certificate file and the related rels file\n\t\t\t\t\t\t$objZip->addFromString('xl/vbaProjectSignature.bin', $this->_spreadSheet->getMacrosCertificate());\n\t\t\t\t\t\t$objZip->addFromString('xl/_rels/vbaProject.bin.rels',\n\t\t\t\t\t\t\t$this->getWriterPart('RelsVBA')->writeVBARelationships($this->_spreadSheet));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\t//a custom UI in this workbook ? add it (\"base\" xml and additional objects (pictures) and rels)\n\t\t\tif($this->_spreadSheet->hasRibbon()){\n\t\t\t\t$tmpRibbonTarget=$this->_spreadSheet->getRibbonXMLData('target');\n\t\t\t\t$objZip->addFromString($tmpRibbonTarget, $this->_spreadSheet->getRibbonXMLData('data'));\n\t\t\t\tif($this->_spreadSheet->hasRibbonBinObjects()){\n\t\t\t\t\t$tmpRootPath=dirname($tmpRibbonTarget).'/';\n\t\t\t\t\t$ribbonBinObjects=$this->_spreadSheet->getRibbonBinObjects('data');//the files to write\n\t\t\t\t\tforeach($ribbonBinObjects as $aPath=>$aContent){\n\t\t\t\t\t\t$objZip->addFromString($tmpRootPath.$aPath, $aContent);\n\t\t\t\t\t}\n\t\t\t\t\t//the rels for files\n\t\t\t\t\t$objZip->addFromString($tmpRootPath.'_rels/'.basename($tmpRibbonTarget).'.rels',\n\t\t\t\t\t\t$this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->_spreadSheet));\n\t\t\t\t}\n\t\t\t}\n\t\t\t\n\t\t\t// Add relationships to ZIP file\n\t\t\t$objZip->addFromString('_rels/.rels', \t\t\t\t\t$this->getWriterPart('Rels')->writeRelationships($this->_spreadSheet));\n\t\t\t$objZip->addFromString('xl/_rels/workbook.xml.rels', \t$this->getWriterPart('Rels')->writeWorkbookRelationships($this->_spreadSheet));\n\n\t\t\t// Add document properties to ZIP file\n\t\t\t$objZip->addFromString('docProps/app.xml', \t\t\t\t$this->getWriterPart('DocProps')->writeDocPropsApp($this->_spreadSheet));\n\t\t\t$objZip->addFromString('docProps/core.xml', \t\t\t$this->getWriterPart('DocProps')->writeDocPropsCore($this->_spreadSheet));\n\t\t\t$customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->_spreadSheet);\n\t\t\tif ($customPropertiesPart !== NULL) {\n\t\t\t\t$objZip->addFromString('docProps/custom.xml', \t\t$customPropertiesPart);\n\t\t\t}\n\n\t\t\t// Add theme to ZIP file\n\t\t\t$objZip->addFromString('xl/theme/theme1.xml', \t\t\t$this->getWriterPart('Theme')->writeTheme($this->_spreadSheet));\n\n\t\t\t// Add string table to ZIP file\n\t\t\t$objZip->addFromString('xl/sharedStrings.xml', \t\t\t$this->getWriterPart('StringTable')->writeStringTable($this->_stringTable));\n\n\t\t\t// Add styles to ZIP file\n\t\t\t$objZip->addFromString('xl/styles.xml', \t\t\t\t$this->getWriterPart('Style')->writeStyles($this->_spreadSheet));\n\n\t\t\t// Add workbook to ZIP file\n\t\t\t$objZip->addFromString('xl/workbook.xml', \t\t\t\t$this->getWriterPart('Workbook')->writeWorkbook($this->_spreadSheet, $this->_preCalculateFormulas));\n\n\t\t\t$chartCount = 0;\n\t\t\t// Add worksheets\n\t\t\tfor ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) {\n\t\t\t\t$objZip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->_spreadSheet->getSheet($i), $this->_stringTable, $this->_includeCharts));\n\t\t\t\tif ($this->_includeCharts) {\n\t\t\t\t\t$charts = $this->_spreadSheet->getSheet($i)->getChartCollection();\n\t\t\t\t\tif (count($charts) > 0) {\n\t\t\t\t\t\tforeach($charts as $chart) {\n\t\t\t\t\t\t\t$objZip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart));\n\t\t\t\t\t\t\t$chartCount++;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t$chartRef1 = $chartRef2 = 0;\n\t\t\t// Add worksheet relationships (drawings, ...)\n\t\t\tfor ($i = 0; $i < $this->_spreadSheet->getSheetCount(); ++$i) {\n\n\t\t\t\t// Add relationships\n\t\t\t\t$objZip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', \t$this->getWriterPart('Rels')->writeWorksheetRelationships($this->_spreadSheet->getSheet($i), ($i + 1), $this->_includeCharts));\n\n\t\t\t\t$drawings = $this->_spreadSheet->getSheet($i)->getDrawingCollection();\n\t\t\t\t$drawingCount = count($drawings);\n\t\t\t\tif ($this->_includeCharts) {\n\t\t\t\t\t$chartCount = $this->_spreadSheet->getSheet($i)->getChartCount();\n\t\t\t\t}\n\n\t\t\t\t// Add drawing and image relationship parts\n\t\t\t\tif (($drawingCount > 0) || ($chartCount > 0)) {\n\t\t\t\t\t// Drawing relationships\n\t\t\t\t\t$objZip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->_spreadSheet->getSheet($i),$chartRef1, $this->_includeCharts));\n\n\t\t\t\t\t// Drawings\n\t\t\t\t\t$objZip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->_spreadSheet->getSheet($i),$chartRef2,$this->_includeCharts));\n\t\t\t\t}\n\n\t\t\t\t// Add comment relationship parts\n\t\t\t\tif (count($this->_spreadSheet->getSheet($i)->getComments()) > 0) {\n\t\t\t\t\t// VML Comments\n\t\t\t\t\t$objZip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->_spreadSheet->getSheet($i)));\n\n\t\t\t\t\t// Comments\n\t\t\t\t\t$objZip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->_spreadSheet->getSheet($i)));\n\t\t\t\t}\n\n\t\t\t\t// Add header/footer relationship parts\n\t\t\t\tif (count($this->_spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) {\n\t\t\t\t\t// VML Drawings\n\t\t\t\t\t$objZip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->_spreadSheet->getSheet($i)));\n\n\t\t\t\t\t// VML Drawing relationships\n\t\t\t\t\t$objZip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->_spreadSheet->getSheet($i)));\n\n\t\t\t\t\t// Media\n\t\t\t\t\tforeach ($this->_spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) {\n\t\t\t\t\t\t$objZip->addFromString('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath()));\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Add media\n\t\t\tfor ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) {\n\t\t\t\tif ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_Drawing) {\n\t\t\t\t\t$imageContents = null;\n\t\t\t\t\t$imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath();\n\t\t\t\t\tif (strpos($imagePath, 'zip://') !== false) {\n\t\t\t\t\t\t$imagePath = substr($imagePath, 6);\n\t\t\t\t\t\t$imagePathSplitted = explode('#', $imagePath);\n\n\t\t\t\t\t\t$imageZip = new ZipArchive();\n\t\t\t\t\t\t$imageZip->open($imagePathSplitted[0]);\n\t\t\t\t\t\t$imageContents = $imageZip->getFromName($imagePathSplitted[1]);\n\t\t\t\t\t\t$imageZip->close();\n\t\t\t\t\t\tunset($imageZip);\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$imageContents = file_get_contents($imagePath);\n\t\t\t\t\t}\n\n\t\t\t\t\t$objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);\n\t\t\t\t} else if ($this->getDrawingHashTable()->getByIndex($i) instanceof PHPExcel_Worksheet_MemoryDrawing) {\n\t\t\t\t\tob_start();\n\t\t\t\t\tcall_user_func(\n\t\t\t\t\t\t$this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(),\n\t\t\t\t\t\t$this->getDrawingHashTable()->getByIndex($i)->getImageResource()\n\t\t\t\t\t);\n\t\t\t\t\t$imageContents = ob_get_contents();\n\t\t\t\t\tob_end_clean();\n\n\t\t\t\t\t$objZip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tPHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType);\n\t\t\tPHPExcel_Calculation::getInstance($this->_spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);\n\n\t\t\t// Close file\n\t\t\tif ($objZip->close() === false) {\n\t\t\t\tthrow new PHPExcel_Writer_Exception(\"Could not close zip file $pFilename.\");\n\t\t\t}\n\n\t\t\t// If a temporary file was used, copy it to the correct file stream\n\t\t\tif ($originalFilename != $pFilename) {\n\t\t\t\tif (copy($pFilename, $originalFilename) === false) {\n\t\t\t\t\tthrow new PHPExcel_Writer_Exception(\"Could not copy temporary zip file $pFilename to $originalFilename.\");\n\t\t\t\t}\n\t\t\t\t@unlink($pFilename);\n\t\t\t}\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"PHPExcel object unassigned.\");\n\t\t}\n\t}\n\n\t/**\n\t * Get PHPExcel object\n\t *\n\t * @return PHPExcel\n\t * @throws PHPExcel_Writer_Exception\n\t */\n\tpublic function getPHPExcel() {\n\t\tif ($this->_spreadSheet !== null) {\n\t\t\treturn $this->_spreadSheet;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"No PHPExcel assigned.\");\n\t\t}\n\t}\n\n\t/**\n\t * Set PHPExcel object\n\t *\n\t * @param \tPHPExcel \t$pPHPExcel\tPHPExcel object\n\t * @throws\tPHPExcel_Writer_Exception\n\t * @return PHPExcel_Writer_Excel2007\n\t */\n\tpublic function setPHPExcel(PHPExcel $pPHPExcel = null) {\n\t\t$this->_spreadSheet = $pPHPExcel;\n\t\treturn $this;\n\t}\n\n    /**\n     * Get string table\n     *\n     * @return string[]\n     */\n    public function getStringTable() {\n    \treturn $this->_stringTable;\n    }\n\n    /**\n     * Get PHPExcel_Style HashTable\n     *\n     * @return PHPExcel_HashTable\n     */\n    public function getStyleHashTable() {\n    \treturn $this->_styleHashTable;\n    }\n\n    /**\n     * Get PHPExcel_Style_Conditional HashTable\n     *\n     * @return PHPExcel_HashTable\n     */\n    public function getStylesConditionalHashTable() {\n    \treturn $this->_stylesConditionalHashTable;\n    }\n\n    /**\n     * Get PHPExcel_Style_Fill HashTable\n     *\n     * @return PHPExcel_HashTable\n     */\n    public function getFillHashTable() {\n    \treturn $this->_fillHashTable;\n    }\n\n    /**\n     * Get PHPExcel_Style_Font HashTable\n     *\n     * @return PHPExcel_HashTable\n     */\n    public function getFontHashTable() {\n    \treturn $this->_fontHashTable;\n    }\n\n    /**\n     * Get PHPExcel_Style_Borders HashTable\n     *\n     * @return PHPExcel_HashTable\n     */\n    public function getBordersHashTable() {\n    \treturn $this->_bordersHashTable;\n    }\n\n    /**\n     * Get PHPExcel_Style_NumberFormat HashTable\n     *\n     * @return PHPExcel_HashTable\n     */\n    public function getNumFmtHashTable() {\n    \treturn $this->_numFmtHashTable;\n    }\n\n    /**\n     * Get PHPExcel_Worksheet_BaseDrawing HashTable\n     *\n     * @return PHPExcel_HashTable\n     */\n    public function getDrawingHashTable() {\n    \treturn $this->_drawingHashTable;\n    }\n\n    /**\n     * Get Office2003 compatibility\n     *\n     * @return boolean\n     */\n    public function getOffice2003Compatibility() {\n    \treturn $this->_office2003compatibility;\n    }\n\n    /**\n     * Set Office2003 compatibility\n     *\n     * @param boolean $pValue\tOffice2003 compatibility?\n     * @return PHPExcel_Writer_Excel2007\n     */\n    public function setOffice2003Compatibility($pValue = false) {\n    \t$this->_office2003compatibility = $pValue;\n    \treturn $this;\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5/BIFFwriter.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n// Original file header of PEAR::Spreadsheet_Excel_Writer_BIFFwriter (used as the base for this class):\n// -----------------------------------------------------------------------------------------\n// *  Module written/ported by Xavier Noguer <xnoguer@rezebra.com>\n// *\n// *  The majority of this is _NOT_ my code.  I simply ported it from the\n// *  PERL Spreadsheet::WriteExcel module.\n// *\n// *  The author of the Spreadsheet::WriteExcel module is John McNamara\n// *  <jmcnamara@cpan.org>\n// *\n// *  I _DO_ maintain this code, and John McNamara has nothing to do with the\n// *  porting of this code to PHP.  Any questions directly related to this\n// *  class library should be directed to me.\n// *\n// *  License Information:\n// *\n// *    Spreadsheet_Excel_Writer:  A library for generating Excel Spreadsheets\n// *    Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com\n// *\n// *    This library is free software; you can redistribute it and/or\n// *    modify it under the terms of the GNU Lesser General Public\n// *    License as published by the Free Software Foundation; either\n// *    version 2.1 of the License, or (at your option) any later version.\n// *\n// *    This library is distributed in the hope that it will be useful,\n// *    but WITHOUT ANY WARRANTY; without even the implied warranty of\n// *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n// *    Lesser General Public License for more details.\n// *\n// *    You should have received a copy of the GNU Lesser General Public\n// *    License along with this library; if not, write to the Free Software\n// *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n// */\n\n\n/**\n * PHPExcel_Writer_Excel5_BIFFwriter\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel5_BIFFwriter\n{\n\t/**\n\t * The byte order of this architecture. 0 => little endian, 1 => big endian\n\t * @var integer\n\t */\n\tprivate static $_byte_order;\n\n\t/**\n\t * The string containing the data of the BIFF stream\n\t * @var string\n\t */\n\tpublic $_data;\n\n\t/**\n\t * The size of the data in bytes. Should be the same as strlen($this->_data)\n\t * @var integer\n\t */\n\tpublic $_datasize;\n\n\t/**\n\t * The maximum length for a BIFF record (excluding record header and length field). See _addContinue()\n\t * @var integer\n\t * @see _addContinue()\n\t */\n\tpublic $_limit\t= 8224;\n\n\t/**\n\t * Constructor\n\t */\n\tpublic function __construct()\n\t{\n\t\t$this->_data       = '';\n\t\t$this->_datasize   = 0;\n//\t\t$this->_limit      = 8224;\n\t}\n\n\t/**\n\t * Determine the byte order and store it as class data to avoid\n\t * recalculating it for each call to new().\n\t *\n\t * @return int\n\t */\n\tpublic static function getByteOrder()\n\t{\n\t\tif (!isset(self::$_byte_order)) {\n\t\t\t// Check if \"pack\" gives the required IEEE 64bit float\n\t\t\t$teststr = pack(\"d\", 1.2345);\n\t\t\t$number  = pack(\"C8\", 0x8D, 0x97, 0x6E, 0x12, 0x83, 0xC0, 0xF3, 0x3F);\n\t\t\tif ($number == $teststr) {\n\t\t\t\t$byte_order = 0;    // Little Endian\n\t\t\t} elseif ($number == strrev($teststr)){\n\t\t\t\t$byte_order = 1;    // Big Endian\n\t\t\t} else {\n\t\t\t\t// Give up. I'll fix this in a later version.\n\t\t\t\tthrow new PHPExcel_Writer_Exception(\"Required floating point format not supported on this platform.\");\n\t\t\t}\n\t\t\tself::$_byte_order = $byte_order;\n\t\t}\n\n\t\treturn self::$_byte_order;\n\t}\n\n\t/**\n\t * General storage function\n\t *\n\t * @param string $data binary data to append\n\t * @access private\n\t */\n\tfunction _append($data)\n\t{\n\t\tif (strlen($data) - 4 > $this->_limit) {\n\t\t\t$data = $this->_addContinue($data);\n\t\t}\n\t\t$this->_data\t\t.= $data;\n\t\t$this->_datasize\t+= strlen($data);\n\t}\n\n\t/**\n\t * General storage function like _append, but returns string instead of modifying $this->_data\n\t *\n\t * @param string $data binary data to write\n\t * @return string\n\t */\n\tpublic function writeData($data)\n\t{\n\t\tif (strlen($data) - 4 > $this->_limit) {\n\t\t\t$data = $this->_addContinue($data);\n\t\t}\n\t\t$this->_datasize += strlen($data);\n\n\t\treturn $data;\n\t}\n\n\t/**\n\t * Writes Excel BOF record to indicate the beginning of a stream or\n\t * sub-stream in the BIFF file.\n\t *\n\t * @param  integer $type Type of BIFF file to write: 0x0005 Workbook,\n\t *                       0x0010 Worksheet.\n\t * @access private\n\t */\n\tfunction _storeBof($type)\n\t{\n\t\t$record  = 0x0809;\t\t\t// Record identifier\t(BIFF5-BIFF8)\n\t\t$length  = 0x0010;\n\n\t\t// by inspection of real files, MS Office Excel 2007 writes the following\n\t\t$unknown = pack(\"VV\", 0x000100D1, 0x00000406);\n\n\t\t$build   = 0x0DBB;\t\t\t//\tExcel 97\n\t\t$year    = 0x07CC;\t\t\t//\tExcel 97\n\n\t\t$version = 0x0600;\t\t\t//\tBIFF8\n\n\t\t$header  = pack(\"vv\",   $record, $length);\n\t\t$data    = pack(\"vvvv\", $version, $type, $build, $year);\n\t\t$this->_append($header . $data . $unknown);\n\t}\n\n\t/**\n\t * Writes Excel EOF record to indicate the end of a BIFF stream.\n\t *\n\t * @access private\n\t */\n\tfunction _storeEof()\n\t{\n\t\t$record    = 0x000A;   // Record identifier\n\t\t$length    = 0x0000;   // Number of bytes to follow\n\n\t\t$header    = pack(\"vv\", $record, $length);\n\t\t$this->_append($header);\n\t}\n\n\t/**\n\t * Writes Excel EOF record to indicate the end of a BIFF stream.\n\t *\n\t * @access private\n\t */\n\tpublic function writeEof()\n\t{\n\t\t$record    = 0x000A;   // Record identifier\n\t\t$length    = 0x0000;   // Number of bytes to follow\n\t\t$header    = pack(\"vv\", $record, $length);\n\t\treturn $this->writeData($header);\n\t}\n\n\t/**\n\t * Excel limits the size of BIFF records. In Excel 5 the limit is 2084 bytes. In\n\t * Excel 97 the limit is 8228 bytes. Records that are longer than these limits\n\t * must be split up into CONTINUE blocks.\n\t *\n\t * This function takes a long BIFF record and inserts CONTINUE records as\n\t * necessary.\n\t *\n\t * @param  string  $data The original binary data to be written\n\t * @return string        A very convenient string of continue blocks\n\t * @access private\n\t */\n\tfunction _addContinue($data)\n\t{\n\t\t$limit  = $this->_limit;\n\t\t$record = 0x003C;         // Record identifier\n\n\t\t// The first 2080/8224 bytes remain intact. However, we have to change\n\t\t// the length field of the record.\n\t\t$tmp = substr($data, 0, 2) . pack(\"v\", $limit) . substr($data, 4, $limit);\n\n\t\t$header = pack(\"vv\", $record, $limit);  // Headers for continue records\n\n\t\t// Retrieve chunks of 2080/8224 bytes +4 for the header.\n\t\t$data_length = strlen($data);\n\t\tfor ($i = $limit + 4; $i < ($data_length - $limit); $i += $limit) {\n\t\t\t$tmp .= $header;\n\t\t\t$tmp .= substr($data, $i, $limit);\n\t\t}\n\n\t\t// Retrieve the last chunk of data\n\t\t$header  = pack(\"vv\", $record, strlen($data) - $i);\n\t\t$tmp    .= $header;\n\t\t$tmp    .= substr($data, $i, strlen($data) - $i);\n\n\t\treturn $tmp;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5/Escher.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Shared_Escher_DggContainer_BstoreContainer\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel5_Escher\n{\n\t/**\n\t * The object we are writing\n\t */\n\tprivate $_object;\n\n\t/**\n\t * The written binary data\n\t */\n\tprivate $_data;\n\n\t/**\n\t * Shape offsets. Positions in binary stream where a new shape record begins\n\t *\n\t * @var array\n\t */\n\tprivate $_spOffsets;\n\n\t/**\n\t * Shape types.\n\t *\n\t * @var array\n\t */\n\tprivate $_spTypes;\n\t\n\t/**\n\t * Constructor\n\t *\n\t * @param mixed\n\t */\n\tpublic function __construct($object)\n\t{\n\t\t$this->_object = $object;\n\t}\n\n\t/**\n\t * Process the object to be written\n\t */\n\tpublic function close()\n\t{\n\t\t// initialize\n\t\t$this->_data = '';\n\n\t\tswitch (get_class($this->_object)) {\n\n\t\tcase 'PHPExcel_Shared_Escher':\n\t\t\tif ($dggContainer = $this->_object->getDggContainer()) {\n\t\t\t\t$writer = new PHPExcel_Writer_Excel5_Escher($dggContainer);\n\t\t\t\t$this->_data = $writer->close();\n\t\t\t} else if ($dgContainer = $this->_object->getDgContainer()) {\n\t\t\t\t$writer = new PHPExcel_Writer_Excel5_Escher($dgContainer);\n\t\t\t\t$this->_data = $writer->close();\n\t\t\t\t$this->_spOffsets = $writer->getSpOffsets();\n\t\t\t\t$this->_spTypes = $writer->getSpTypes();\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 'PHPExcel_Shared_Escher_DggContainer':\n\t\t\t// this is a container record\n\n\t\t\t// initialize\n\t\t\t$innerData = '';\n\n\t\t\t// write the dgg\n\t\t\t$recVer\t\t\t= 0x0;\n\t\t\t$recInstance\t= 0x0000;\n\t\t\t$recType\t\t= 0xF006;\n\n\t\t\t$recVerInstance  = $recVer;\n\t\t\t$recVerInstance |= $recInstance << 4;\n\n\t\t\t// dgg data\n\t\t\t$dggData =\n\t\t\t\tpack('VVVV'\n\t\t\t\t\t, $this->_object->getSpIdMax() // maximum shape identifier increased by one\n\t\t\t\t\t, $this->_object->getCDgSaved() + 1 // number of file identifier clusters increased by one\n\t\t\t\t\t, $this->_object->getCSpSaved()\n\t\t\t\t\t, $this->_object->getCDgSaved() // count total number of drawings saved\n\t\t\t\t);\n\n\t\t\t// add file identifier clusters (one per drawing)\n\t\t\t$IDCLs = $this->_object->getIDCLs();\n\n\t\t\tforeach ($IDCLs as $dgId => $maxReducedSpId) {\n\t\t\t\t$dggData .= pack('VV', $dgId, $maxReducedSpId + 1);\n\t\t\t}\n\n\t\t\t$header = pack('vvV', $recVerInstance, $recType, strlen($dggData));\n\t\t\t$innerData .= $header . $dggData;\n\n\t\t\t// write the bstoreContainer\n\t\t\tif ($bstoreContainer = $this->_object->getBstoreContainer()) {\n\t\t\t\t$writer = new PHPExcel_Writer_Excel5_Escher($bstoreContainer);\n\t\t\t\t$innerData .= $writer->close();\n\t\t\t}\n\n\t\t\t// write the record\n\t\t\t$recVer\t\t\t= 0xF;\n\t\t\t$recInstance\t= 0x0000;\n\t\t\t$recType\t\t= 0xF000;\n\t\t\t$length\t\t\t= strlen($innerData);\n\n\t\t\t$recVerInstance  = $recVer;\n\t\t\t$recVerInstance |= $recInstance << 4;\n\n\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\n\t\t\t$this->_data = $header . $innerData;\n\t\t\tbreak;\n\n\t\tcase 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer':\n\t\t\t// this is a container record\n\n\t\t\t// initialize\n\t\t\t$innerData = '';\n\n\t\t\t// treat the inner data\n\t\t\tif ($BSECollection = $this->_object->getBSECollection()) {\n\t\t\t\tforeach ($BSECollection as $BSE) {\n\t\t\t\t\t$writer = new PHPExcel_Writer_Excel5_Escher($BSE);\n\t\t\t\t\t$innerData .= $writer->close();\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// write the record\n\t\t\t$recVer\t\t\t= 0xF;\n\t\t\t$recInstance\t= count($this->_object->getBSECollection());\n\t\t\t$recType\t\t= 0xF001;\n\t\t\t$length\t\t\t= strlen($innerData);\n\n\t\t\t$recVerInstance  = $recVer;\n\t\t\t$recVerInstance |= $recInstance << 4;\n\n\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\n\t\t\t$this->_data = $header . $innerData;\n\t\t\tbreak;\n\n\t\tcase 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE':\n\t\t\t// this is a semi-container record\n\n\t\t\t// initialize\n\t\t\t$innerData = '';\n\n\t\t\t// here we treat the inner data\n\t\t\tif ($blip = $this->_object->getBlip()) {\n\t\t\t\t$writer = new PHPExcel_Writer_Excel5_Escher($blip);\n\t\t\t\t$innerData .= $writer->close();\n\t\t\t}\n\n\t\t\t// initialize\n\t\t\t$data = '';\n\n\t\t\t$btWin32 = $this->_object->getBlipType();\n\t\t\t$btMacOS = $this->_object->getBlipType();\n\t\t\t$data .= pack('CC', $btWin32, $btMacOS);\n\n\t\t\t$rgbUid = pack('VVVV', 0,0,0,0); // todo\n\t\t\t$data .= $rgbUid;\n\n\t\t\t$tag = 0;\n\t\t\t$size = strlen($innerData);\n\t\t\t$cRef = 1;\n\t\t\t$foDelay = 0; //todo\n\t\t\t$unused1 = 0x0;\n\t\t\t$cbName = 0x0;\n\t\t\t$unused2 = 0x0;\n\t\t\t$unused3 = 0x0;\n\t\t\t$data .= pack('vVVVCCCC', $tag, $size, $cRef, $foDelay, $unused1, $cbName, $unused2, $unused3);\n\n\t\t\t$data .= $innerData;\n\n\t\t\t// write the record\n\t\t\t$recVer\t\t\t= 0x2;\n\t\t\t$recInstance\t= $this->_object->getBlipType();\n\t\t\t$recType\t\t= 0xF007;\n\t\t\t$length\t\t\t= strlen($data);\n\n\t\t\t$recVerInstance  = $recVer;\n\t\t\t$recVerInstance |=\t$recInstance << 4;\n\n\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\n\t\t\t$this->_data = $header;\n\n\t\t\t$this->_data .= $data;\n\t\t\tbreak;\n\n\t\tcase 'PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip':\n\t\t\t// this is an atom record\n\n\t\t\t// write the record\n\t\t\tswitch ($this->_object->getParent()->getBlipType()) {\n\n\t\t\tcase PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG:\n\t\t\t\t// initialize\n\t\t\t\t$innerData = '';\n\n\t\t\t\t$rgbUid1 = pack('VVVV', 0,0,0,0); // todo\n\t\t\t\t$innerData .= $rgbUid1;\n\n\t\t\t\t$tag = 0xFF; // todo\n\t\t\t\t$innerData .= pack('C', $tag);\n\n\t\t\t\t$innerData .= $this->_object->getData();\n\n\t\t\t\t$recVer\t\t\t= 0x0;\n\t\t\t\t$recInstance\t= 0x46A;\n\t\t\t\t$recType\t\t= 0xF01D;\n\t\t\t\t$length\t\t\t= strlen($innerData);\n\n\t\t\t\t$recVerInstance  = $recVer;\n\t\t\t\t$recVerInstance |=\t$recInstance << 4;\n\n\t\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\n\t\t\t\t$this->_data = $header;\n\n\t\t\t\t$this->_data .= $innerData;\n\t\t\t\tbreak;\n\n\t\t\tcase PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG:\n\t\t\t\t// initialize\n\t\t\t\t$innerData = '';\n\n\t\t\t\t$rgbUid1 = pack('VVVV', 0,0,0,0); // todo\n\t\t\t\t$innerData .= $rgbUid1;\n\n\t\t\t\t$tag = 0xFF; // todo\n\t\t\t\t$innerData .= pack('C', $tag);\n\n\t\t\t\t$innerData .= $this->_object->getData();\n\n\t\t\t\t$recVer\t\t\t= 0x0;\n\t\t\t\t$recInstance\t= 0x6E0;\n\t\t\t\t$recType\t\t= 0xF01E;\n\t\t\t\t$length\t\t\t= strlen($innerData);\n\n\t\t\t\t$recVerInstance  = $recVer;\n\t\t\t\t$recVerInstance |=\t$recInstance << 4;\n\n\t\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\n\t\t\t\t$this->_data = $header;\n\n\t\t\t\t$this->_data .= $innerData;\n\t\t\t\tbreak;\n\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 'PHPExcel_Shared_Escher_DgContainer':\n\t\t\t// this is a container record\n\n\t\t\t// initialize\n\t\t\t$innerData = '';\n\n\t\t\t// write the dg\n\t\t\t$recVer\t\t\t= 0x0;\n\t\t\t$recInstance\t= $this->_object->getDgId();\n\t\t\t$recType\t\t= 0xF008;\n\t\t\t$length\t\t\t= 8;\n\n\t\t\t$recVerInstance  = $recVer;\n\t\t\t$recVerInstance |= $recInstance << 4;\n\n\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\n\t\t\t// number of shapes in this drawing (including group shape)\n\t\t\t$countShapes = count($this->_object->getSpgrContainer()->getChildren());\n\t\t\t$innerData .= $header . pack('VV', $countShapes, $this->_object->getLastSpId());\n\t\t\t//$innerData .= $header . pack('VV', 0, 0);\n\n\t\t\t// write the spgrContainer\n\t\t\tif ($spgrContainer = $this->_object->getSpgrContainer()) {\n\t\t\t\t$writer = new PHPExcel_Writer_Excel5_Escher($spgrContainer);\n\t\t\t\t$innerData .= $writer->close();\n\n\t\t\t\t// get the shape offsets relative to the spgrContainer record\n\t\t\t\t$spOffsets = $writer->getSpOffsets();\n\t\t\t\t$spTypes   = $writer->getSpTypes();\n\t\t\t\t\n\t\t\t\t// save the shape offsets relative to dgContainer\n\t\t\t\tforeach ($spOffsets as & $spOffset) {\n\t\t\t\t\t$spOffset += 24; // add length of dgContainer header data (8 bytes) plus dg data (16 bytes)\n\t\t\t\t}\n\n\t\t\t\t$this->_spOffsets = $spOffsets;\n\t\t\t\t$this->_spTypes = $spTypes;\n\t\t\t}\n\n\t\t\t// write the record\n\t\t\t$recVer\t\t\t= 0xF;\n\t\t\t$recInstance\t= 0x0000;\n\t\t\t$recType\t\t= 0xF002;\n\t\t\t$length\t\t\t= strlen($innerData);\n\n\t\t\t$recVerInstance  = $recVer;\n\t\t\t$recVerInstance |= $recInstance << 4;\n\n\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\n\t\t\t$this->_data = $header . $innerData;\n\t\t\tbreak;\n\n\t\tcase 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer':\n\t\t\t// this is a container record\n\n\t\t\t// initialize\n\t\t\t$innerData = '';\n\n\t\t\t// initialize spape offsets\n\t\t\t$totalSize = 8;\n\t\t\t$spOffsets = array();\n\t\t\t$spTypes   = array();\n\n\t\t\t// treat the inner data\n\t\t\tforeach ($this->_object->getChildren() as $spContainer) {\n\t\t\t\t$writer = new PHPExcel_Writer_Excel5_Escher($spContainer);\n\t\t\t\t$spData = $writer->close();\n\t\t\t\t$innerData .= $spData;\n\n\t\t\t\t// save the shape offsets (where new shape records begin)\n\t\t\t\t$totalSize += strlen($spData);\n\t\t\t\t$spOffsets[] = $totalSize;\n\t\t\t\t\n\t\t\t\t$spTypes = array_merge($spTypes, $writer->getSpTypes());\n\t\t\t}\n\n\t\t\t// write the record\n\t\t\t$recVer\t\t\t= 0xF;\n\t\t\t$recInstance\t= 0x0000;\n\t\t\t$recType\t\t= 0xF003;\n\t\t\t$length\t\t\t= strlen($innerData);\n\n\t\t\t$recVerInstance  = $recVer;\n\t\t\t$recVerInstance |= $recInstance << 4;\n\n\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\n\t\t\t$this->_data = $header . $innerData;\n\t\t\t$this->_spOffsets = $spOffsets;\n\t\t\t$this->_spTypes = $spTypes;\n\t\t\tbreak;\n\n\t\tcase 'PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer':\n\t\t\t// initialize\n\t\t\t$data = '';\n\n\t\t\t// build the data\n\n\t\t\t// write group shape record, if necessary?\n\t\t\tif ($this->_object->getSpgr()) {\n\t\t\t\t$recVer\t\t\t= 0x1;\n\t\t\t\t$recInstance\t= 0x0000;\n\t\t\t\t$recType\t\t= 0xF009;\n\t\t\t\t$length\t\t\t= 0x00000010;\n\n\t\t\t\t$recVerInstance  = $recVer;\n\t\t\t\t$recVerInstance |= $recInstance << 4;\n\n\t\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\n\t\t\t\t$data .= $header . pack('VVVV', 0,0,0,0);\n\t\t\t}\n\t\t\t$this->_spTypes[] = ($this->_object->getSpType());\n\n\t\t\t// write the shape record\n\t\t\t$recVer\t\t\t= 0x2;\n\t\t\t$recInstance\t= $this->_object->getSpType(); // shape type\n\t\t\t$recType\t\t= 0xF00A;\n\t\t\t$length\t\t\t= 0x00000008;\n\n\t\t\t$recVerInstance  = $recVer;\n\t\t\t$recVerInstance |= $recInstance << 4;\n\n\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\n\t\t\t$data .= $header . pack('VV', $this->_object->getSpId(), $this->_object->getSpgr() ? 0x0005 : 0x0A00);\n\n\n\t\t\t// the options\n\t\t\tif ($this->_object->getOPTCollection()) {\n\t\t\t\t$optData = '';\n\n\t\t\t\t$recVer\t\t\t= 0x3;\n\t\t\t\t$recInstance\t= count($this->_object->getOPTCollection());\n\t\t\t\t$recType\t\t= 0xF00B;\n\t\t\t\tforeach ($this->_object->getOPTCollection() as $property => $value) {\n\t\t\t\t\t$optData .= pack('vV', $property, $value);\n\t\t\t\t}\n\t\t\t\t$length\t\t\t= strlen($optData);\n\n\t\t\t\t$recVerInstance  = $recVer;\n\t\t\t\t$recVerInstance |= $recInstance << 4;\n\n\t\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\t\t\t\t$data .= $header . $optData;\n\t\t\t}\n\n\t\t\t// the client anchor\n\t\t\tif ($this->_object->getStartCoordinates()) {\n\t\t\t\t$clientAnchorData = '';\n\n\t\t\t\t$recVer\t\t\t= 0x0;\n\t\t\t\t$recInstance\t= 0x0;\n\t\t\t\t$recType\t\t= 0xF010;\n\n\t\t\t\t// start coordinates\n\t\t\t\tlist($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getStartCoordinates());\n\t\t\t\t$c1 = PHPExcel_Cell::columnIndexFromString($column) - 1;\n\t\t\t\t$r1 = $row - 1;\n\n\t\t\t\t// start offsetX\n\t\t\t\t$startOffsetX = $this->_object->getStartOffsetX();\n\n\t\t\t\t// start offsetY\n\t\t\t\t$startOffsetY = $this->_object->getStartOffsetY();\n\n\t\t\t\t// end coordinates\n\t\t\t\tlist($column, $row) = PHPExcel_Cell::coordinateFromString($this->_object->getEndCoordinates());\n\t\t\t\t$c2 = PHPExcel_Cell::columnIndexFromString($column) - 1;\n\t\t\t\t$r2 = $row - 1;\n\n\t\t\t\t// end offsetX\n\t\t\t\t$endOffsetX = $this->_object->getEndOffsetX();\n\n\t\t\t\t// end offsetY\n\t\t\t\t$endOffsetY = $this->_object->getEndOffsetY();\n\n\t\t\t\t$clientAnchorData = pack('vvvvvvvvv', $this->_object->getSpFlag(),\n\t\t\t\t\t$c1, $startOffsetX, $r1, $startOffsetY,\n\t\t\t\t\t$c2, $endOffsetX, $r2, $endOffsetY);\n\t\t\t\t\n\t\t\t\t$length\t\t\t= strlen($clientAnchorData);\n\n\t\t\t\t$recVerInstance  = $recVer;\n\t\t\t\t$recVerInstance |= $recInstance << 4;\n\n\t\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\t\t\t\t$data .= $header . $clientAnchorData;\n\t\t\t}\n\n\t\t\t// the client data, just empty for now\n\t\t\tif (!$this->_object->getSpgr()) {\n\t\t\t\t$clientDataData = '';\n\n\t\t\t\t$recVer\t\t\t= 0x0;\n\t\t\t\t$recInstance\t= 0x0;\n\t\t\t\t$recType\t\t= 0xF011;\n\n\t\t\t\t$length = strlen($clientDataData);\n\n\t\t\t\t$recVerInstance  = $recVer;\n\t\t\t\t$recVerInstance |= $recInstance << 4;\n\n\t\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\t\t\t\t$data .= $header . $clientDataData;\n\t\t\t}\n\n\t\t\t// write the record\n\t\t\t$recVer\t\t\t= 0xF;\n\t\t\t$recInstance\t= 0x0000;\n\t\t\t$recType\t\t= 0xF004;\n\t\t\t$length\t\t\t= strlen($data);\n\n\t\t\t$recVerInstance  = $recVer;\n\t\t\t$recVerInstance |= $recInstance << 4;\n\n\t\t\t$header = pack('vvV', $recVerInstance, $recType, $length);\n\n\t\t\t$this->_data = $header . $data;\n\t\t\tbreak;\n\n\t\t}\n\n\t\treturn $this->_data;\n\t}\n\n\t/**\n\t * Gets the shape offsets\n\t *\n\t * @return array\n\t */\n\tpublic function getSpOffsets()\n\t{\n\t\treturn $this->_spOffsets;\n\t}\n\n\t/**\n\t * Gets the shape types\n\t *\n\t * @return array\n\t */\n\tpublic function getSpTypes()\n\t{\n\t\treturn $this->_spTypes;\n\t}\n\t\n\t\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5/Font.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel5_Font\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel5_Font\n{\n\t/**\n\t * Color index\n\t *\n\t * @var int\n\t */\n\tprivate $_colorIndex;\n\n\t/**\n\t * Font\n\t *\n\t * @var PHPExcel_Style_Font\n\t */\n\tprivate $_font;\n\n\t/**\n\t * Constructor\n\t *\n\t * @param PHPExcel_Style_Font $font\n\t */\n\tpublic function __construct(PHPExcel_Style_Font $font = null)\n\t{\n\t\t$this->_colorIndex = 0x7FFF;\n\t\t$this->_font = $font;\n\t}\n\n\t/**\n\t * Set the color index\n\t *\n\t * @param int $colorIndex\n\t */\n\tpublic function setColorIndex($colorIndex)\n\t{\n\t\t$this->_colorIndex = $colorIndex;\n\t}\n\n\t/**\n\t * Get font record data\n\t *\n\t * @return string\n\t */\n\tpublic function writeFont()\n\t{\n\t\t$font_outline = 0;\n\t\t$font_shadow = 0;\n\n\t\t$icv = $this->_colorIndex; // Index to color palette\n\t\tif ($this->_font->getSuperScript()) {\n\t\t\t$sss = 1;\n\t\t} else if ($this->_font->getSubScript()) {\n\t\t\t$sss = 2;\n\t\t} else {\n\t\t\t$sss = 0;\n\t\t}\n\t\t$bFamily = 0; // Font family\n\t\t$bCharSet = PHPExcel_Shared_Font::getCharsetFromFontName($this->_font->getName()); // Character set\n\n\t\t$record = 0x31;\t\t// Record identifier\n\t\t$reserved = 0x00;\t// Reserved\n\t\t$grbit = 0x00;\t\t// Font attributes\n\t\tif ($this->_font->getItalic()) {\n\t\t\t$grbit |= 0x02;\n\t\t}\n\t\tif ($this->_font->getStrikethrough()) {\n\t\t\t$grbit |= 0x08;\n\t\t}\n\t\tif ($font_outline) {\n\t\t\t$grbit |= 0x10;\n\t\t}\n\t\tif ($font_shadow) {\n\t\t\t$grbit |= 0x20;\n\t\t}\n\n\t\t$data = pack(\"vvvvvCCCC\",\n\t\t\t$this->_font->getSize() * 20,\t\t\t\t\t\t//\tFontsize (in twips)\n\t\t\t$grbit,\n\t\t\t$icv,\t\t\t\t\t\t\t\t\t\t\t\t//\tColour\n\t\t\tself::_mapBold($this->_font->getBold()),\t\t\t//\tFont weight\n\t\t\t$sss,\t\t\t\t\t\t\t\t\t\t\t\t//\tSuperscript/Subscript\n\t\t\tself::_mapUnderline($this->_font->getUnderline()),\n\t\t\t$bFamily,\n\t\t\t$bCharSet,\n\t\t\t$reserved\n\t\t);\n\t\t$data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($this->_font->getName());\n\n\t\t$length = strlen($data);\n\t\t$header = pack(\"vv\", $record, $length);\n\n\t\treturn($header . $data);\n\t}\n\n\t/**\n\t * Map to BIFF5-BIFF8 codes for bold\n\t *\n\t * @param boolean $bold\n\t * @return int\n\t */\n\tprivate static function _mapBold($bold) {\n\t\tif ($bold) {\n\t\t\treturn 0x2BC;\t//\t700 = Bold font weight\n\t\t}\n\t\treturn 0x190;\t\t//\t400 = Normal font weight\n\t}\n\n\t/**\n\t * Map of BIFF2-BIFF8 codes for underline styles\n\t * @static\tarray of int\n\t *\n\t */\n\tprivate static $_mapUnderline = array(\tPHPExcel_Style_Font::UNDERLINE_NONE\t\t\t\t\t=> 0x00,\n\t\t\t\t\t\t\t\t\t\t\tPHPExcel_Style_Font::UNDERLINE_SINGLE\t\t\t\t=> 0x01,\n\t\t\t\t\t\t\t\t\t\t\tPHPExcel_Style_Font::UNDERLINE_DOUBLE\t\t\t\t=> 0x02,\n\t\t\t\t\t\t\t\t\t\t\tPHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING\t\t=> 0x21,\n\t\t\t\t\t\t\t\t\t\t\tPHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING\t\t=> 0x22,\n\t\t\t\t\t\t\t\t\t\t );\n\t/**\n\t * Map underline\n\t *\n\t * @param string\n\t * @return int\n\t */\n\tprivate static function _mapUnderline($underline) {\n\t\tif (isset(self::$_mapUnderline[$underline]))\n\t\t\treturn self::$_mapUnderline[$underline];\n\t\treturn 0x00;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5/Parser.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n// Original file header of PEAR::Spreadsheet_Excel_Writer_Parser (used as the base for this class):\n// -----------------------------------------------------------------------------------------\n// *  Class for parsing Excel formulas\n// *\n// *  License Information:\n// *\n// *    Spreadsheet_Excel_Writer:  A library for generating Excel Spreadsheets\n// *    Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com\n// *\n// *    This library is free software; you can redistribute it and/or\n// *    modify it under the terms of the GNU Lesser General Public\n// *    License as published by the Free Software Foundation; either\n// *    version 2.1 of the License, or (at your option) any later version.\n// *\n// *    This library is distributed in the hope that it will be useful,\n// *    but WITHOUT ANY WARRANTY; without even the implied warranty of\n// *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n// *    Lesser General Public License for more details.\n// *\n// *    You should have received a copy of the GNU Lesser General Public\n// *    License along with this library; if not, write to the Free Software\n// *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n// */\n\n\n/**\n * PHPExcel_Writer_Excel5_Parser\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel5_Parser\n{\n\t/**\tConstants\t\t\t\t*/\n\t// Sheet title in unquoted form\n\t// Invalid sheet title characters cannot occur in the sheet title:\n\t// \t\t*:/\\?[]\n\t// Moreover, there are valid sheet title characters that cannot occur in unquoted form (there may be more?)\n\t// +-% '^&<>=,;#()\"{}\n\tconst REGEX_SHEET_TITLE_UNQUOTED = '[^\\*\\:\\/\\\\\\\\\\?\\[\\]\\+\\-\\% \\\\\\'\\^\\&\\<\\>\\=\\,\\;\\#\\(\\)\\\"\\{\\}]+';\n\n\t// Sheet title in quoted form (without surrounding quotes)\n\t// Invalid sheet title characters cannot occur in the sheet title:\n\t// *:/\\?[]\t\t\t\t\t(usual invalid sheet title characters)\n\t// Single quote is represented as a pair ''\n\tconst REGEX_SHEET_TITLE_QUOTED = '(([^\\*\\:\\/\\\\\\\\\\?\\[\\]\\\\\\'])+|(\\\\\\'\\\\\\')+)+';\n\n\t/**\n\t * The index of the character we are currently looking at\n\t * @var integer\n\t */\n\tpublic $_current_char;\n\n\t/**\n\t * The token we are working on.\n\t * @var string\n\t */\n\tpublic $_current_token;\n\n\t/**\n\t * The formula to parse\n\t * @var string\n\t */\n\tpublic $_formula;\n\n\t/**\n\t * The character ahead of the current char\n\t * @var string\n\t */\n\tpublic $_lookahead;\n\n\t/**\n\t * The parse tree to be generated\n\t * @var string\n\t */\n\tpublic $_parse_tree;\n\n\t/**\n\t * Array of external sheets\n\t * @var array\n\t */\n\tpublic $_ext_sheets;\n\n\t/**\n\t * Array of sheet references in the form of REF structures\n\t * @var array\n\t */\n\tpublic $_references;\n\n\t/**\n\t * The class constructor\n\t *\n\t */\n\tpublic function __construct()\n\t{\n\t\t$this->_current_char  = 0;\n\t\t$this->_current_token = '';       // The token we are working on.\n\t\t$this->_formula       = '';       // The formula to parse.\n\t\t$this->_lookahead     = '';       // The character ahead of the current char.\n\t\t$this->_parse_tree    = '';       // The parse tree to be generated.\n\t\t$this->_initializeHashes();      // Initialize the hashes: ptg's and function's ptg's\n\t\t$this->_ext_sheets = array();\n\t\t$this->_references = array();\n\t}\n\n\t/**\n\t * Initialize the ptg and function hashes.\n\t *\n\t * @access private\n\t */\n\tfunction _initializeHashes()\n\t{\n\t\t// The Excel ptg indices\n\t\t$this->ptg = array(\n\t\t\t'ptgExp'       => 0x01,\n\t\t\t'ptgTbl'       => 0x02,\n\t\t\t'ptgAdd'       => 0x03,\n\t\t\t'ptgSub'       => 0x04,\n\t\t\t'ptgMul'       => 0x05,\n\t\t\t'ptgDiv'       => 0x06,\n\t\t\t'ptgPower'     => 0x07,\n\t\t\t'ptgConcat'    => 0x08,\n\t\t\t'ptgLT'        => 0x09,\n\t\t\t'ptgLE'        => 0x0A,\n\t\t\t'ptgEQ'        => 0x0B,\n\t\t\t'ptgGE'        => 0x0C,\n\t\t\t'ptgGT'        => 0x0D,\n\t\t\t'ptgNE'        => 0x0E,\n\t\t\t'ptgIsect'     => 0x0F,\n\t\t\t'ptgUnion'     => 0x10,\n\t\t\t'ptgRange'     => 0x11,\n\t\t\t'ptgUplus'     => 0x12,\n\t\t\t'ptgUminus'    => 0x13,\n\t\t\t'ptgPercent'   => 0x14,\n\t\t\t'ptgParen'     => 0x15,\n\t\t\t'ptgMissArg'   => 0x16,\n\t\t\t'ptgStr'       => 0x17,\n\t\t\t'ptgAttr'      => 0x19,\n\t\t\t'ptgSheet'     => 0x1A,\n\t\t\t'ptgEndSheet'  => 0x1B,\n\t\t\t'ptgErr'       => 0x1C,\n\t\t\t'ptgBool'      => 0x1D,\n\t\t\t'ptgInt'       => 0x1E,\n\t\t\t'ptgNum'       => 0x1F,\n\t\t\t'ptgArray'     => 0x20,\n\t\t\t'ptgFunc'      => 0x21,\n\t\t\t'ptgFuncVar'   => 0x22,\n\t\t\t'ptgName'      => 0x23,\n\t\t\t'ptgRef'       => 0x24,\n\t\t\t'ptgArea'      => 0x25,\n\t\t\t'ptgMemArea'   => 0x26,\n\t\t\t'ptgMemErr'    => 0x27,\n\t\t\t'ptgMemNoMem'  => 0x28,\n\t\t\t'ptgMemFunc'   => 0x29,\n\t\t\t'ptgRefErr'    => 0x2A,\n\t\t\t'ptgAreaErr'   => 0x2B,\n\t\t\t'ptgRefN'      => 0x2C,\n\t\t\t'ptgAreaN'     => 0x2D,\n\t\t\t'ptgMemAreaN'  => 0x2E,\n\t\t\t'ptgMemNoMemN' => 0x2F,\n\t\t\t'ptgNameX'     => 0x39,\n\t\t\t'ptgRef3d'     => 0x3A,\n\t\t\t'ptgArea3d'    => 0x3B,\n\t\t\t'ptgRefErr3d'  => 0x3C,\n\t\t\t'ptgAreaErr3d' => 0x3D,\n\t\t\t'ptgArrayV'    => 0x40,\n\t\t\t'ptgFuncV'     => 0x41,\n\t\t\t'ptgFuncVarV'  => 0x42,\n\t\t\t'ptgNameV'     => 0x43,\n\t\t\t'ptgRefV'      => 0x44,\n\t\t\t'ptgAreaV'     => 0x45,\n\t\t\t'ptgMemAreaV'  => 0x46,\n\t\t\t'ptgMemErrV'   => 0x47,\n\t\t\t'ptgMemNoMemV' => 0x48,\n\t\t\t'ptgMemFuncV'  => 0x49,\n\t\t\t'ptgRefErrV'   => 0x4A,\n\t\t\t'ptgAreaErrV'  => 0x4B,\n\t\t\t'ptgRefNV'     => 0x4C,\n\t\t\t'ptgAreaNV'    => 0x4D,\n\t\t\t'ptgMemAreaNV' => 0x4E,\n\t\t\t'ptgMemNoMemN' => 0x4F,\n\t\t\t'ptgFuncCEV'   => 0x58,\n\t\t\t'ptgNameXV'    => 0x59,\n\t\t\t'ptgRef3dV'    => 0x5A,\n\t\t\t'ptgArea3dV'   => 0x5B,\n\t\t\t'ptgRefErr3dV' => 0x5C,\n\t\t\t'ptgAreaErr3d' => 0x5D,\n\t\t\t'ptgArrayA'    => 0x60,\n\t\t\t'ptgFuncA'     => 0x61,\n\t\t\t'ptgFuncVarA'  => 0x62,\n\t\t\t'ptgNameA'     => 0x63,\n\t\t\t'ptgRefA'      => 0x64,\n\t\t\t'ptgAreaA'     => 0x65,\n\t\t\t'ptgMemAreaA'  => 0x66,\n\t\t\t'ptgMemErrA'   => 0x67,\n\t\t\t'ptgMemNoMemA' => 0x68,\n\t\t\t'ptgMemFuncA'  => 0x69,\n\t\t\t'ptgRefErrA'   => 0x6A,\n\t\t\t'ptgAreaErrA'  => 0x6B,\n\t\t\t'ptgRefNA'     => 0x6C,\n\t\t\t'ptgAreaNA'    => 0x6D,\n\t\t\t'ptgMemAreaNA' => 0x6E,\n\t\t\t'ptgMemNoMemN' => 0x6F,\n\t\t\t'ptgFuncCEA'   => 0x78,\n\t\t\t'ptgNameXA'    => 0x79,\n\t\t\t'ptgRef3dA'    => 0x7A,\n\t\t\t'ptgArea3dA'   => 0x7B,\n\t\t\t'ptgRefErr3dA' => 0x7C,\n\t\t\t'ptgAreaErr3d' => 0x7D\n\t\t\t);\n\n\t\t// Thanks to Michael Meeks and Gnumeric for the initial arg values.\n\t\t//\n\t\t// The following hash was generated by \"function_locale.pl\" in the distro.\n\t\t// Refer to function_locale.pl for non-English function names.\n\t\t//\n\t\t// The array elements are as follow:\n\t\t// ptg:   The Excel function ptg code.\n\t\t// args:  The number of arguments that the function takes:\n\t\t//           >=0 is a fixed number of arguments.\n\t\t//           -1  is a variable  number of arguments.\n\t\t// class: The reference, value or array class of the function args.\n\t\t// vol:   The function is volatile.\n\t\t//\n\t\t$this->_functions = array(\n\t\t\t  // function                  ptg  args  class  vol\n\t\t\t  'COUNT'           => array(   0,   -1,    0,    0 ),\n\t\t\t  'IF'              => array(   1,   -1,    1,    0 ),\n\t\t\t  'ISNA'            => array(   2,    1,    1,    0 ),\n\t\t\t  'ISERROR'         => array(   3,    1,    1,    0 ),\n\t\t\t  'SUM'             => array(   4,   -1,    0,    0 ),\n\t\t\t  'AVERAGE'         => array(   5,   -1,    0,    0 ),\n\t\t\t  'MIN'             => array(   6,   -1,    0,    0 ),\n\t\t\t  'MAX'             => array(   7,   -1,    0,    0 ),\n\t\t\t  'ROW'             => array(   8,   -1,    0,    0 ),\n\t\t\t  'COLUMN'          => array(   9,   -1,    0,    0 ),\n\t\t\t  'NA'              => array(  10,    0,    0,    0 ),\n\t\t\t  'NPV'             => array(  11,   -1,    1,    0 ),\n\t\t\t  'STDEV'           => array(  12,   -1,    0,    0 ),\n\t\t\t  'DOLLAR'          => array(  13,   -1,    1,    0 ),\n\t\t\t  'FIXED'           => array(  14,   -1,    1,    0 ),\n\t\t\t  'SIN'             => array(  15,    1,    1,    0 ),\n\t\t\t  'COS'             => array(  16,    1,    1,    0 ),\n\t\t\t  'TAN'             => array(  17,    1,    1,    0 ),\n\t\t\t  'ATAN'            => array(  18,    1,    1,    0 ),\n\t\t\t  'PI'              => array(  19,    0,    1,    0 ),\n\t\t\t  'SQRT'            => array(  20,    1,    1,    0 ),\n\t\t\t  'EXP'             => array(  21,    1,    1,    0 ),\n\t\t\t  'LN'              => array(  22,    1,    1,    0 ),\n\t\t\t  'LOG10'           => array(  23,    1,    1,    0 ),\n\t\t\t  'ABS'             => array(  24,    1,    1,    0 ),\n\t\t\t  'INT'             => array(  25,    1,    1,    0 ),\n\t\t\t  'SIGN'            => array(  26,    1,    1,    0 ),\n\t\t\t  'ROUND'           => array(  27,    2,    1,    0 ),\n\t\t\t  'LOOKUP'          => array(  28,   -1,    0,    0 ),\n\t\t\t  'INDEX'           => array(  29,   -1,    0,    1 ),\n\t\t\t  'REPT'            => array(  30,    2,    1,    0 ),\n\t\t\t  'MID'             => array(  31,    3,    1,    0 ),\n\t\t\t  'LEN'             => array(  32,    1,    1,    0 ),\n\t\t\t  'VALUE'           => array(  33,    1,    1,    0 ),\n\t\t\t  'TRUE'            => array(  34,    0,    1,    0 ),\n\t\t\t  'FALSE'           => array(  35,    0,    1,    0 ),\n\t\t\t  'AND'             => array(  36,   -1,    0,    0 ),\n\t\t\t  'OR'              => array(  37,   -1,    0,    0 ),\n\t\t\t  'NOT'             => array(  38,    1,    1,    0 ),\n\t\t\t  'MOD'             => array(  39,    2,    1,    0 ),\n\t\t\t  'DCOUNT'          => array(  40,    3,    0,    0 ),\n\t\t\t  'DSUM'            => array(  41,    3,    0,    0 ),\n\t\t\t  'DAVERAGE'        => array(  42,    3,    0,    0 ),\n\t\t\t  'DMIN'            => array(  43,    3,    0,    0 ),\n\t\t\t  'DMAX'            => array(  44,    3,    0,    0 ),\n\t\t\t  'DSTDEV'          => array(  45,    3,    0,    0 ),\n\t\t\t  'VAR'             => array(  46,   -1,    0,    0 ),\n\t\t\t  'DVAR'            => array(  47,    3,    0,    0 ),\n\t\t\t  'TEXT'            => array(  48,    2,    1,    0 ),\n\t\t\t  'LINEST'          => array(  49,   -1,    0,    0 ),\n\t\t\t  'TREND'           => array(  50,   -1,    0,    0 ),\n\t\t\t  'LOGEST'          => array(  51,   -1,    0,    0 ),\n\t\t\t  'GROWTH'          => array(  52,   -1,    0,    0 ),\n\t\t\t  'PV'              => array(  56,   -1,    1,    0 ),\n\t\t\t  'FV'              => array(  57,   -1,    1,    0 ),\n\t\t\t  'NPER'            => array(  58,   -1,    1,    0 ),\n\t\t\t  'PMT'             => array(  59,   -1,    1,    0 ),\n\t\t\t  'RATE'            => array(  60,   -1,    1,    0 ),\n\t\t\t  'MIRR'            => array(  61,    3,    0,    0 ),\n\t\t\t  'IRR'             => array(  62,   -1,    0,    0 ),\n\t\t\t  'RAND'            => array(  63,    0,    1,    1 ),\n\t\t\t  'MATCH'           => array(  64,   -1,    0,    0 ),\n\t\t\t  'DATE'            => array(  65,    3,    1,    0 ),\n\t\t\t  'TIME'            => array(  66,    3,    1,    0 ),\n\t\t\t  'DAY'             => array(  67,    1,    1,    0 ),\n\t\t\t  'MONTH'           => array(  68,    1,    1,    0 ),\n\t\t\t  'YEAR'            => array(  69,    1,    1,    0 ),\n\t\t\t  'WEEKDAY'         => array(  70,   -1,    1,    0 ),\n\t\t\t  'HOUR'            => array(  71,    1,    1,    0 ),\n\t\t\t  'MINUTE'          => array(  72,    1,    1,    0 ),\n\t\t\t  'SECOND'          => array(  73,    1,    1,    0 ),\n\t\t\t  'NOW'             => array(  74,    0,    1,    1 ),\n\t\t\t  'AREAS'           => array(  75,    1,    0,    1 ),\n\t\t\t  'ROWS'            => array(  76,    1,    0,    1 ),\n\t\t\t  'COLUMNS'         => array(  77,    1,    0,    1 ),\n\t\t\t  'OFFSET'          => array(  78,   -1,    0,    1 ),\n\t\t\t  'SEARCH'          => array(  82,   -1,    1,    0 ),\n\t\t\t  'TRANSPOSE'       => array(  83,    1,    1,    0 ),\n\t\t\t  'TYPE'            => array(  86,    1,    1,    0 ),\n\t\t\t  'ATAN2'           => array(  97,    2,    1,    0 ),\n\t\t\t  'ASIN'            => array(  98,    1,    1,    0 ),\n\t\t\t  'ACOS'            => array(  99,    1,    1,    0 ),\n\t\t\t  'CHOOSE'          => array( 100,   -1,    1,    0 ),\n\t\t\t  'HLOOKUP'         => array( 101,   -1,    0,    0 ),\n\t\t\t  'VLOOKUP'         => array( 102,   -1,    0,    0 ),\n\t\t\t  'ISREF'           => array( 105,    1,    0,    0 ),\n\t\t\t  'LOG'             => array( 109,   -1,    1,    0 ),\n\t\t\t  'CHAR'            => array( 111,    1,    1,    0 ),\n\t\t\t  'LOWER'           => array( 112,    1,    1,    0 ),\n\t\t\t  'UPPER'           => array( 113,    1,    1,    0 ),\n\t\t\t  'PROPER'          => array( 114,    1,    1,    0 ),\n\t\t\t  'LEFT'            => array( 115,   -1,    1,    0 ),\n\t\t\t  'RIGHT'           => array( 116,   -1,    1,    0 ),\n\t\t\t  'EXACT'           => array( 117,    2,    1,    0 ),\n\t\t\t  'TRIM'            => array( 118,    1,    1,    0 ),\n\t\t\t  'REPLACE'         => array( 119,    4,    1,    0 ),\n\t\t\t  'SUBSTITUTE'      => array( 120,   -1,    1,    0 ),\n\t\t\t  'CODE'            => array( 121,    1,    1,    0 ),\n\t\t\t  'FIND'            => array( 124,   -1,    1,    0 ),\n\t\t\t  'CELL'            => array( 125,   -1,    0,    1 ),\n\t\t\t  'ISERR'           => array( 126,    1,    1,    0 ),\n\t\t\t  'ISTEXT'          => array( 127,    1,    1,    0 ),\n\t\t\t  'ISNUMBER'        => array( 128,    1,    1,    0 ),\n\t\t\t  'ISBLANK'         => array( 129,    1,    1,    0 ),\n\t\t\t  'T'               => array( 130,    1,    0,    0 ),\n\t\t\t  'N'               => array( 131,    1,    0,    0 ),\n\t\t\t  'DATEVALUE'       => array( 140,    1,    1,    0 ),\n\t\t\t  'TIMEVALUE'       => array( 141,    1,    1,    0 ),\n\t\t\t  'SLN'             => array( 142,    3,    1,    0 ),\n\t\t\t  'SYD'             => array( 143,    4,    1,    0 ),\n\t\t\t  'DDB'             => array( 144,   -1,    1,    0 ),\n\t\t\t  'INDIRECT'        => array( 148,   -1,    1,    1 ),\n\t\t\t  'CALL'            => array( 150,   -1,    1,    0 ),\n\t\t\t  'CLEAN'           => array( 162,    1,    1,    0 ),\n\t\t\t  'MDETERM'         => array( 163,    1,    2,    0 ),\n\t\t\t  'MINVERSE'        => array( 164,    1,    2,    0 ),\n\t\t\t  'MMULT'           => array( 165,    2,    2,    0 ),\n\t\t\t  'IPMT'            => array( 167,   -1,    1,    0 ),\n\t\t\t  'PPMT'            => array( 168,   -1,    1,    0 ),\n\t\t\t  'COUNTA'          => array( 169,   -1,    0,    0 ),\n\t\t\t  'PRODUCT'         => array( 183,   -1,    0,    0 ),\n\t\t\t  'FACT'            => array( 184,    1,    1,    0 ),\n\t\t\t  'DPRODUCT'        => array( 189,    3,    0,    0 ),\n\t\t\t  'ISNONTEXT'       => array( 190,    1,    1,    0 ),\n\t\t\t  'STDEVP'          => array( 193,   -1,    0,    0 ),\n\t\t\t  'VARP'            => array( 194,   -1,    0,    0 ),\n\t\t\t  'DSTDEVP'         => array( 195,    3,    0,    0 ),\n\t\t\t  'DVARP'           => array( 196,    3,    0,    0 ),\n\t\t\t  'TRUNC'           => array( 197,   -1,    1,    0 ),\n\t\t\t  'ISLOGICAL'       => array( 198,    1,    1,    0 ),\n\t\t\t  'DCOUNTA'         => array( 199,    3,    0,    0 ),\n\t\t\t  'USDOLLAR'        => array( 204,   -1,    1,    0 ),\n\t\t\t  'FINDB'           => array( 205,   -1,    1,    0 ),\n\t\t\t  'SEARCHB'         => array( 206,   -1,    1,    0 ),\n\t\t\t  'REPLACEB'        => array( 207,    4,    1,    0 ),\n\t\t\t  'LEFTB'           => array( 208,   -1,    1,    0 ),\n\t\t\t  'RIGHTB'          => array( 209,   -1,    1,    0 ),\n\t\t\t  'MIDB'            => array( 210,    3,    1,    0 ),\n\t\t\t  'LENB'            => array( 211,    1,    1,    0 ),\n\t\t\t  'ROUNDUP'         => array( 212,    2,    1,    0 ),\n\t\t\t  'ROUNDDOWN'       => array( 213,    2,    1,    0 ),\n\t\t\t  'ASC'             => array( 214,    1,    1,    0 ),\n\t\t\t  'DBCS'            => array( 215,    1,    1,    0 ),\n\t\t\t  'RANK'            => array( 216,   -1,    0,    0 ),\n\t\t\t  'ADDRESS'         => array( 219,   -1,    1,    0 ),\n\t\t\t  'DAYS360'         => array( 220,   -1,    1,    0 ),\n\t\t\t  'TODAY'           => array( 221,    0,    1,    1 ),\n\t\t\t  'VDB'             => array( 222,   -1,    1,    0 ),\n\t\t\t  'MEDIAN'          => array( 227,   -1,    0,    0 ),\n\t\t\t  'SUMPRODUCT'      => array( 228,   -1,    2,    0 ),\n\t\t\t  'SINH'            => array( 229,    1,    1,    0 ),\n\t\t\t  'COSH'            => array( 230,    1,    1,    0 ),\n\t\t\t  'TANH'            => array( 231,    1,    1,    0 ),\n\t\t\t  'ASINH'           => array( 232,    1,    1,    0 ),\n\t\t\t  'ACOSH'           => array( 233,    1,    1,    0 ),\n\t\t\t  'ATANH'           => array( 234,    1,    1,    0 ),\n\t\t\t  'DGET'            => array( 235,    3,    0,    0 ),\n\t\t\t  'INFO'            => array( 244,    1,    1,    1 ),\n\t\t\t  'DB'              => array( 247,   -1,    1,    0 ),\n\t\t\t  'FREQUENCY'       => array( 252,    2,    0,    0 ),\n\t\t\t  'ERROR.TYPE'      => array( 261,    1,    1,    0 ),\n\t\t\t  'REGISTER.ID'     => array( 267,   -1,    1,    0 ),\n\t\t\t  'AVEDEV'          => array( 269,   -1,    0,    0 ),\n\t\t\t  'BETADIST'        => array( 270,   -1,    1,    0 ),\n\t\t\t  'GAMMALN'         => array( 271,    1,    1,    0 ),\n\t\t\t  'BETAINV'         => array( 272,   -1,    1,    0 ),\n\t\t\t  'BINOMDIST'       => array( 273,    4,    1,    0 ),\n\t\t\t  'CHIDIST'         => array( 274,    2,    1,    0 ),\n\t\t\t  'CHIINV'          => array( 275,    2,    1,    0 ),\n\t\t\t  'COMBIN'          => array( 276,    2,    1,    0 ),\n\t\t\t  'CONFIDENCE'      => array( 277,    3,    1,    0 ),\n\t\t\t  'CRITBINOM'       => array( 278,    3,    1,    0 ),\n\t\t\t  'EVEN'            => array( 279,    1,    1,    0 ),\n\t\t\t  'EXPONDIST'       => array( 280,    3,    1,    0 ),\n\t\t\t  'FDIST'           => array( 281,    3,    1,    0 ),\n\t\t\t  'FINV'            => array( 282,    3,    1,    0 ),\n\t\t\t  'FISHER'          => array( 283,    1,    1,    0 ),\n\t\t\t  'FISHERINV'       => array( 284,    1,    1,    0 ),\n\t\t\t  'FLOOR'           => array( 285,    2,    1,    0 ),\n\t\t\t  'GAMMADIST'       => array( 286,    4,    1,    0 ),\n\t\t\t  'GAMMAINV'        => array( 287,    3,    1,    0 ),\n\t\t\t  'CEILING'         => array( 288,    2,    1,    0 ),\n\t\t\t  'HYPGEOMDIST'     => array( 289,    4,    1,    0 ),\n\t\t\t  'LOGNORMDIST'     => array( 290,    3,    1,    0 ),\n\t\t\t  'LOGINV'          => array( 291,    3,    1,    0 ),\n\t\t\t  'NEGBINOMDIST'    => array( 292,    3,    1,    0 ),\n\t\t\t  'NORMDIST'        => array( 293,    4,    1,    0 ),\n\t\t\t  'NORMSDIST'       => array( 294,    1,    1,    0 ),\n\t\t\t  'NORMINV'         => array( 295,    3,    1,    0 ),\n\t\t\t  'NORMSINV'        => array( 296,    1,    1,    0 ),\n\t\t\t  'STANDARDIZE'     => array( 297,    3,    1,    0 ),\n\t\t\t  'ODD'             => array( 298,    1,    1,    0 ),\n\t\t\t  'PERMUT'          => array( 299,    2,    1,    0 ),\n\t\t\t  'POISSON'         => array( 300,    3,    1,    0 ),\n\t\t\t  'TDIST'           => array( 301,    3,    1,    0 ),\n\t\t\t  'WEIBULL'         => array( 302,    4,    1,    0 ),\n\t\t\t  'SUMXMY2'         => array( 303,    2,    2,    0 ),\n\t\t\t  'SUMX2MY2'        => array( 304,    2,    2,    0 ),\n\t\t\t  'SUMX2PY2'        => array( 305,    2,    2,    0 ),\n\t\t\t  'CHITEST'         => array( 306,    2,    2,    0 ),\n\t\t\t  'CORREL'          => array( 307,    2,    2,    0 ),\n\t\t\t  'COVAR'           => array( 308,    2,    2,    0 ),\n\t\t\t  'FORECAST'        => array( 309,    3,    2,    0 ),\n\t\t\t  'FTEST'           => array( 310,    2,    2,    0 ),\n\t\t\t  'INTERCEPT'       => array( 311,    2,    2,    0 ),\n\t\t\t  'PEARSON'         => array( 312,    2,    2,    0 ),\n\t\t\t  'RSQ'             => array( 313,    2,    2,    0 ),\n\t\t\t  'STEYX'           => array( 314,    2,    2,    0 ),\n\t\t\t  'SLOPE'           => array( 315,    2,    2,    0 ),\n\t\t\t  'TTEST'           => array( 316,    4,    2,    0 ),\n\t\t\t  'PROB'            => array( 317,   -1,    2,    0 ),\n\t\t\t  'DEVSQ'           => array( 318,   -1,    0,    0 ),\n\t\t\t  'GEOMEAN'         => array( 319,   -1,    0,    0 ),\n\t\t\t  'HARMEAN'         => array( 320,   -1,    0,    0 ),\n\t\t\t  'SUMSQ'           => array( 321,   -1,    0,    0 ),\n\t\t\t  'KURT'            => array( 322,   -1,    0,    0 ),\n\t\t\t  'SKEW'            => array( 323,   -1,    0,    0 ),\n\t\t\t  'ZTEST'           => array( 324,   -1,    0,    0 ),\n\t\t\t  'LARGE'           => array( 325,    2,    0,    0 ),\n\t\t\t  'SMALL'           => array( 326,    2,    0,    0 ),\n\t\t\t  'QUARTILE'        => array( 327,    2,    0,    0 ),\n\t\t\t  'PERCENTILE'      => array( 328,    2,    0,    0 ),\n\t\t\t  'PERCENTRANK'     => array( 329,   -1,    0,    0 ),\n\t\t\t  'MODE'            => array( 330,   -1,    2,    0 ),\n\t\t\t  'TRIMMEAN'        => array( 331,    2,    0,    0 ),\n\t\t\t  'TINV'            => array( 332,    2,    1,    0 ),\n\t\t\t  'CONCATENATE'     => array( 336,   -1,    1,    0 ),\n\t\t\t  'POWER'           => array( 337,    2,    1,    0 ),\n\t\t\t  'RADIANS'         => array( 342,    1,    1,    0 ),\n\t\t\t  'DEGREES'         => array( 343,    1,    1,    0 ),\n\t\t\t  'SUBTOTAL'        => array( 344,   -1,    0,    0 ),\n\t\t\t  'SUMIF'           => array( 345,   -1,    0,    0 ),\n\t\t\t  'COUNTIF'         => array( 346,    2,    0,    0 ),\n\t\t\t  'COUNTBLANK'      => array( 347,    1,    0,    0 ),\n\t\t\t  'ISPMT'           => array( 350,    4,    1,    0 ),\n\t\t\t  'DATEDIF'         => array( 351,    3,    1,    0 ),\n\t\t\t  'DATESTRING'      => array( 352,    1,    1,    0 ),\n\t\t\t  'NUMBERSTRING'    => array( 353,    2,    1,    0 ),\n\t\t\t  'ROMAN'           => array( 354,   -1,    1,    0 ),\n\t\t\t  'GETPIVOTDATA'    => array( 358,   -1,    0,    0 ),\n\t\t\t  'HYPERLINK'       => array( 359,   -1,    1,    0 ),\n\t\t\t  'PHONETIC'        => array( 360,    1,    0,    0 ),\n\t\t\t  'AVERAGEA'        => array( 361,   -1,    0,    0 ),\n\t\t\t  'MAXA'            => array( 362,   -1,    0,    0 ),\n\t\t\t  'MINA'            => array( 363,   -1,    0,    0 ),\n\t\t\t  'STDEVPA'         => array( 364,   -1,    0,    0 ),\n\t\t\t  'VARPA'           => array( 365,   -1,    0,    0 ),\n\t\t\t  'STDEVA'          => array( 366,   -1,    0,    0 ),\n\t\t\t  'VARA'            => array( 367,   -1,    0,    0 ),\n\t\t\t  'BAHTTEXT'        => array( 368,    1,    0,    0 ),\n\t\t\t  );\n\t}\n\n\t/**\n\t * Convert a token to the proper ptg value.\n\t *\n\t * @access private\n\t * @param mixed $token The token to convert.\n\t * @return mixed the converted token on success\n\t */\n\tfunction _convert($token)\n\t{\n\t\tif (preg_match(\"/\\\"([^\\\"]|\\\"\\\"){0,255}\\\"/\", $token)) {\n\t\t\treturn $this->_convertString($token);\n\n\t\t} elseif (is_numeric($token)) {\n\t\t\treturn $this->_convertNumber($token);\n\n\t\t// match references like A1 or $A$1\n\t\t} elseif (preg_match('/^\\$?([A-Ia-i]?[A-Za-z])\\$?(\\d+)$/',$token)) {\n\t\t\treturn $this->_convertRef2d($token);\n\n\t\t// match external references like Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1\n\t\t} elseif (preg_match(\"/^\" . self::REGEX_SHEET_TITLE_UNQUOTED . \"(\\:\" . self::REGEX_SHEET_TITLE_UNQUOTED . \")?\\!\\\\$?[A-Ia-i]?[A-Za-z]\\\\$?(\\d+)$/u\",$token)) {\n\t\t\treturn $this->_convertRef3d($token);\n\n\t\t// match external references like 'Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1\n\t\t} elseif (preg_match(\"/^'\" . self::REGEX_SHEET_TITLE_QUOTED . \"(\\:\" . self::REGEX_SHEET_TITLE_QUOTED . \")?'\\!\\\\$?[A-Ia-i]?[A-Za-z]\\\\$?(\\d+)$/u\",$token)) {\n\t\t\treturn $this->_convertRef3d($token);\n\n\t\t// match ranges like A1:B2 or $A$1:$B$2\n\t\t} elseif (preg_match('/^(\\$)?[A-Ia-i]?[A-Za-z](\\$)?(\\d+)\\:(\\$)?[A-Ia-i]?[A-Za-z](\\$)?(\\d+)$/', $token)) {\n\t\t\treturn $this->_convertRange2d($token);\n\n\t\t// match external ranges like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2\n\t\t} elseif (preg_match(\"/^\" . self::REGEX_SHEET_TITLE_UNQUOTED . \"(\\:\" . self::REGEX_SHEET_TITLE_UNQUOTED . \")?\\!\\\\$?([A-Ia-i]?[A-Za-z])?\\\\$?(\\d+)\\:\\\\$?([A-Ia-i]?[A-Za-z])?\\\\$?(\\d+)$/u\",$token)) {\n\t\t\treturn $this->_convertRange3d($token);\n\n\t\t// match external ranges like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2\n\t\t} elseif (preg_match(\"/^'\" . self::REGEX_SHEET_TITLE_QUOTED . \"(\\:\" . self::REGEX_SHEET_TITLE_QUOTED . \")?'\\!\\\\$?([A-Ia-i]?[A-Za-z])?\\\\$?(\\d+)\\:\\\\$?([A-Ia-i]?[A-Za-z])?\\\\$?(\\d+)$/u\",$token)) {\n\t\t\treturn $this->_convertRange3d($token);\n\n\t\t// operators (including parentheses)\n\t\t} elseif (isset($this->ptg[$token])) {\n\t\t\treturn pack(\"C\", $this->ptg[$token]);\n\n        // match error codes\n\t\t} elseif (preg_match(\"/^#[A-Z0\\/]{3,5}[!?]{1}$/\", $token) or $token == '#N/A') {\n\t\t    return $this->_convertError($token);\n\n\t\t// commented so argument number can be processed correctly. See toReversePolish().\n\t\t/*elseif (preg_match(\"/[A-Z0-9\\xc0-\\xdc\\.]+/\",$token))\n\t\t{\n\t\t\treturn($this->_convertFunction($token,$this->_func_args));\n\t\t}*/\n\n\t\t// if it's an argument, ignore the token (the argument remains)\n\t\t} elseif ($token == 'arg') {\n\t\t\treturn '';\n\t\t}\n\n\t\t// TODO: use real error codes\n\t\tthrow new PHPExcel_Writer_Exception(\"Unknown token $token\");\n\t}\n\n\t/**\n\t * Convert a number token to ptgInt or ptgNum\n\t *\n\t * @access private\n\t * @param mixed $num an integer or double for conversion to its ptg value\n\t */\n\tfunction _convertNumber($num)\n\t{\n\t\t// Integer in the range 0..2**16-1\n\t\tif ((preg_match(\"/^\\d+$/\", $num)) and ($num <= 65535)) {\n\t\t\treturn pack(\"Cv\", $this->ptg['ptgInt'], $num);\n\t\t} else { // A float\n\t\t\tif (PHPExcel_Writer_Excel5_BIFFwriter::getByteOrder()) { // if it's Big Endian\n\t\t\t\t$num = strrev($num);\n\t\t\t}\n\t\t\treturn pack(\"Cd\", $this->ptg['ptgNum'], $num);\n\t\t}\n\t}\n\n\t/**\n\t * Convert a string token to ptgStr\n\t *\n\t * @access private\n\t * @param string $string A string for conversion to its ptg value.\n\t * @return mixed the converted token on success\n\t */\n\tfunction _convertString($string)\n\t{\n\t\t// chop away beggining and ending quotes\n\t\t$string = substr($string, 1, strlen($string) - 2);\n\t\tif (strlen($string) > 255) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"String is too long\");\n\t\t}\n\n\t\treturn pack('C', $this->ptg['ptgStr']) . PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($string);\n\t}\n\n\t/**\n\t * Convert a function to a ptgFunc or ptgFuncVarV depending on the number of\n\t * args that it takes.\n\t *\n\t * @access private\n\t * @param string  $token    The name of the function for convertion to ptg value.\n\t * @param integer $num_args The number of arguments the function receives.\n\t * @return string The packed ptg for the function\n\t */\n\tfunction _convertFunction($token, $num_args)\n\t{\n\t\t$args     = $this->_functions[$token][1];\n//\t\t$volatile = $this->_functions[$token][3];\n\n\t\t// Fixed number of args eg. TIME($i,$j,$k).\n\t\tif ($args >= 0) {\n\t\t\treturn pack(\"Cv\", $this->ptg['ptgFuncV'], $this->_functions[$token][0]);\n\t\t}\n\t\t// Variable number of args eg. SUM($i,$j,$k, ..).\n\t\tif ($args == -1) {\n\t\t\treturn pack(\"CCv\", $this->ptg['ptgFuncVarV'], $num_args, $this->_functions[$token][0]);\n\t\t}\n\t}\n\n\t/**\n\t * Convert an Excel range such as A1:D4 to a ptgRefV.\n\t *\n\t * @access private\n\t * @param string\t$range\tAn Excel range in the A1:A2\n\t * @param int\t\t$class\n\t */\n\tfunction _convertRange2d($range, $class=0)\n\t{\n\n\t\t// TODO: possible class value 0,1,2 check Formula.pm\n\t\t// Split the range into 2 cell refs\n\t\tif (preg_match('/^(\\$)?([A-Ia-i]?[A-Za-z])(\\$)?(\\d+)\\:(\\$)?([A-Ia-i]?[A-Za-z])(\\$)?(\\d+)$/', $range)) {\n\t\t\tlist($cell1, $cell2) = explode(':', $range);\n\t\t} else {\n\t\t\t// TODO: use real error codes\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Unknown range separator\");\n\t\t}\n\n\t\t// Convert the cell references\n\t\tlist($row1, $col1) = $this->_cellToPackedRowcol($cell1);\n\t\tlist($row2, $col2) = $this->_cellToPackedRowcol($cell2);\n\n\t\t// The ptg value depends on the class of the ptg.\n\t\tif ($class == 0) {\n\t\t\t$ptgArea = pack(\"C\", $this->ptg['ptgArea']);\n\t\t} elseif ($class == 1) {\n\t\t\t$ptgArea = pack(\"C\", $this->ptg['ptgAreaV']);\n\t\t} elseif ($class == 2) {\n\t\t\t$ptgArea = pack(\"C\", $this->ptg['ptgAreaA']);\n\t\t} else {\n\t\t\t// TODO: use real error codes\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Unknown class $class\");\n\t\t}\n\t\treturn $ptgArea . $row1 . $row2 . $col1. $col2;\n\t}\n\n\t/**\n\t * Convert an Excel 3d range such as \"Sheet1!A1:D4\" or \"Sheet1:Sheet2!A1:D4\" to\n\t * a ptgArea3d.\n\t *\n\t * @access private\n\t * @param string $token An Excel range in the Sheet1!A1:A2 format.\n\t * @return mixed The packed ptgArea3d token on success.\n\t */\n\tfunction _convertRange3d($token)\n\t{\n//\t\t$class = 0; // formulas like Sheet1!$A$1:$A$2 in list type data validation need this class (0x3B)\n\n\t\t// Split the ref at the ! symbol\n\t\tlist($ext_ref, $range) = explode('!', $token);\n\n\t\t// Convert the external reference part (different for BIFF8)\n\t\t$ext_ref = $this->_getRefIndex($ext_ref);\n\n\t\t// Split the range into 2 cell refs\n\t\tlist($cell1, $cell2) = explode(':', $range);\n\n\t\t// Convert the cell references\n\t\tif (preg_match(\"/^(\\\\$)?[A-Ia-i]?[A-Za-z](\\\\$)?(\\d+)$/\", $cell1)) {\n\t\t\tlist($row1, $col1) = $this->_cellToPackedRowcol($cell1);\n\t\t\tlist($row2, $col2) = $this->_cellToPackedRowcol($cell2);\n\t\t} else { // It's a rows range (like 26:27)\n\t\t\t list($row1, $col1, $row2, $col2) = $this->_rangeToPackedRange($cell1.':'.$cell2);\n\t\t}\n\n\t\t// The ptg value depends on the class of the ptg.\n//\t\tif ($class == 0) {\n\t\t\t$ptgArea = pack(\"C\", $this->ptg['ptgArea3d']);\n//\t\t} elseif ($class == 1) {\n//\t\t\t$ptgArea = pack(\"C\", $this->ptg['ptgArea3dV']);\n//\t\t} elseif ($class == 2) {\n//\t\t\t$ptgArea = pack(\"C\", $this->ptg['ptgArea3dA']);\n//\t\t} else {\n//\t\t\tthrow new PHPExcel_Writer_Exception(\"Unknown class $class\");\n//\t\t}\n\n\t\treturn $ptgArea . $ext_ref . $row1 . $row2 . $col1. $col2;\n\t}\n\n\t/**\n\t * Convert an Excel reference such as A1, $B2, C$3 or $D$4 to a ptgRefV.\n\t *\n\t * @access private\n\t * @param string $cell An Excel cell reference\n\t * @return string The cell in packed() format with the corresponding ptg\n\t */\n\tfunction _convertRef2d($cell)\n\t{\n//\t\t$class = 2; // as far as I know, this is magick.\n\n\t\t// Convert the cell reference\n\t\t$cell_array = $this->_cellToPackedRowcol($cell);\n\t\tlist($row, $col) = $cell_array;\n\n\t\t// The ptg value depends on the class of the ptg.\n//\t\tif ($class == 0) {\n//\t\t\t$ptgRef = pack(\"C\", $this->ptg['ptgRef']);\n//\t\t} elseif ($class == 1) {\n//\t\t\t$ptgRef = pack(\"C\", $this->ptg['ptgRefV']);\n//\t\t} elseif ($class == 2) {\n\t\t\t$ptgRef = pack(\"C\", $this->ptg['ptgRefA']);\n//\t\t} else {\n//\t\t\t// TODO: use real error codes\n//\t\t\tthrow new PHPExcel_Writer_Exception(\"Unknown class $class\");\n//\t\t}\n\t\treturn $ptgRef.$row.$col;\n\t}\n\n\t/**\n\t * Convert an Excel 3d reference such as \"Sheet1!A1\" or \"Sheet1:Sheet2!A1\" to a\n\t * ptgRef3d.\n\t *\n\t * @access private\n\t * @param string $cell An Excel cell reference\n\t * @return mixed The packed ptgRef3d token on success.\n\t */\n\tfunction _convertRef3d($cell)\n\t{\n//\t\t$class = 2; // as far as I know, this is magick.\n\n\t\t// Split the ref at the ! symbol\n\t\tlist($ext_ref, $cell) = explode('!', $cell);\n\n\t\t// Convert the external reference part (different for BIFF8)\n\t\t$ext_ref = $this->_getRefIndex($ext_ref);\n\n\t\t// Convert the cell reference part\n\t\tlist($row, $col) = $this->_cellToPackedRowcol($cell);\n\n\t\t// The ptg value depends on the class of the ptg.\n//\t\tif ($class == 0) {\n//\t\t\t$ptgRef = pack(\"C\", $this->ptg['ptgRef3d']);\n//\t\t} elseif ($class == 1) {\n//\t\t\t$ptgRef = pack(\"C\", $this->ptg['ptgRef3dV']);\n//\t\t} elseif ($class == 2) {\n\t\t\t$ptgRef = pack(\"C\", $this->ptg['ptgRef3dA']);\n//\t\t} else {\n//\t\t\tthrow new PHPExcel_Writer_Exception(\"Unknown class $class\");\n//\t\t}\n\n\t\treturn $ptgRef . $ext_ref. $row . $col;\n\t}\n\n    /**\n     * Convert an error code to a ptgErr\n     *\n     * @access\tprivate\n\t * @param\tstring\t$errorCode\tThe error code for conversion to its ptg value\n     * @return\tstring\t\t\t\tThe error code ptgErr\n     */\n    function _convertError($errorCode)\n    {\n\t\tswitch ($errorCode) {\n\t\t\tcase '#NULL!':\treturn pack(\"C\", 0x00);\n\t\t\tcase '#DIV/0!':\treturn pack(\"C\", 0x07);\n\t\t\tcase '#VALUE!':\treturn pack(\"C\", 0x0F);\n\t\t\tcase '#REF!':\treturn pack(\"C\", 0x17);\n\t\t\tcase '#NAME?':\treturn pack(\"C\", 0x1D);\n\t\t\tcase '#NUM!':\treturn pack(\"C\", 0x24);\n\t\t\tcase '#N/A':\treturn pack(\"C\", 0x2A);\n\t\t}\n\t\treturn pack(\"C\", 0xFF);\n    }\n\n\t/**\n\t * Convert the sheet name part of an external reference, for example \"Sheet1\" or\n\t * \"Sheet1:Sheet2\", to a packed structure.\n\t *\n\t * @access\tprivate\n\t * @param\tstring\t$ext_ref\tThe name of the external reference\n\t * @return\tstring\t\t\t\tThe reference index in packed() format\n\t */\n\tfunction _packExtRef($ext_ref)\n\t{\n\t\t$ext_ref = preg_replace(\"/^'/\", '', $ext_ref); // Remove leading  ' if any.\n\t\t$ext_ref = preg_replace(\"/'$/\", '', $ext_ref); // Remove trailing ' if any.\n\n\t\t// Check if there is a sheet range eg., Sheet1:Sheet2.\n\t\tif (preg_match(\"/:/\", $ext_ref)) {\n\t\t\tlist($sheet_name1, $sheet_name2) = explode(':', $ext_ref);\n\n\t\t\t$sheet1 = $this->_getSheetIndex($sheet_name1);\n\t\t\tif ($sheet1 == -1) {\n\t\t\t\tthrow new PHPExcel_Writer_Exception(\"Unknown sheet name $sheet_name1 in formula\");\n\t\t\t}\n\t\t\t$sheet2 = $this->_getSheetIndex($sheet_name2);\n\t\t\tif ($sheet2 == -1) {\n\t\t\t\tthrow new PHPExcel_Writer_Exception(\"Unknown sheet name $sheet_name2 in formula\");\n\t\t\t}\n\n\t\t\t// Reverse max and min sheet numbers if necessary\n\t\t\tif ($sheet1 > $sheet2) {\n\t\t\t\tlist($sheet1, $sheet2) = array($sheet2, $sheet1);\n\t\t\t}\n\t\t} else { // Single sheet name only.\n\t\t\t$sheet1 = $this->_getSheetIndex($ext_ref);\n\t\t\tif ($sheet1 == -1) {\n\t\t\t\tthrow new PHPExcel_Writer_Exception(\"Unknown sheet name $ext_ref in formula\");\n\t\t\t}\n\t\t\t$sheet2 = $sheet1;\n\t\t}\n\n\t\t// References are stored relative to 0xFFFF.\n\t\t$offset = -1 - $sheet1;\n\n\t\treturn pack('vdvv', $offset, 0x00, $sheet1, $sheet2);\n\t}\n\n\t/**\n\t * Look up the REF index that corresponds to an external sheet name\n\t * (or range). If it doesn't exist yet add it to the workbook's references\n\t * array. It assumes all sheet names given must exist.\n\t *\n\t * @access private\n\t * @param string $ext_ref The name of the external reference\n\t * @return mixed The reference index in packed() format on success\n\t */\n\tfunction _getRefIndex($ext_ref)\n\t{\n\t\t$ext_ref = preg_replace(\"/^'/\", '', $ext_ref); // Remove leading  ' if any.\n\t\t$ext_ref = preg_replace(\"/'$/\", '', $ext_ref); // Remove trailing ' if any.\n\t\t$ext_ref = str_replace('\\'\\'', '\\'', $ext_ref); // Replace escaped '' with '\n\n\t\t// Check if there is a sheet range eg., Sheet1:Sheet2.\n\t\tif (preg_match(\"/:/\", $ext_ref)) {\n\t\t\tlist($sheet_name1, $sheet_name2) = explode(':', $ext_ref);\n\n\t\t\t$sheet1 = $this->_getSheetIndex($sheet_name1);\n\t\t\tif ($sheet1 == -1) {\n\t\t\t\tthrow new PHPExcel_Writer_Exception(\"Unknown sheet name $sheet_name1 in formula\");\n\t\t\t}\n\t\t\t$sheet2 = $this->_getSheetIndex($sheet_name2);\n\t\t\tif ($sheet2 == -1) {\n\t\t\t\tthrow new PHPExcel_Writer_Exception(\"Unknown sheet name $sheet_name2 in formula\");\n\t\t\t}\n\n\t\t\t// Reverse max and min sheet numbers if necessary\n\t\t\tif ($sheet1 > $sheet2) {\n\t\t\t\tlist($sheet1, $sheet2) = array($sheet2, $sheet1);\n\t\t\t}\n\t\t} else { // Single sheet name only.\n\t\t\t$sheet1 = $this->_getSheetIndex($ext_ref);\n\t\t\tif ($sheet1 == -1) {\n\t\t\t\tthrow new PHPExcel_Writer_Exception(\"Unknown sheet name $ext_ref in formula\");\n\t\t\t}\n\t\t\t$sheet2 = $sheet1;\n\t\t}\n\n\t\t// assume all references belong to this document\n\t\t$supbook_index = 0x00;\n\t\t$ref = pack('vvv', $supbook_index, $sheet1, $sheet2);\n\t\t$total_references = count($this->_references);\n\t\t$index = -1;\n\t\tfor ($i = 0; $i < $total_references; ++$i) {\n\t\t\tif ($ref == $this->_references[$i]) {\n\t\t\t\t$index = $i;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t\t// if REF was not found add it to references array\n\t\tif ($index == -1) {\n\t\t\t$this->_references[$total_references] = $ref;\n\t\t\t$index = $total_references;\n\t\t}\n\n\t\treturn pack('v', $index);\n\t}\n\n\t/**\n\t * Look up the index that corresponds to an external sheet name. The hash of\n\t * sheet names is updated by the addworksheet() method of the\n\t * PHPExcel_Writer_Excel5_Workbook class.\n\t *\n\t * @access\tprivate\n\t * @param\tstring\t$sheet_name\t\tSheet name\n\t * @return\tinteger\t\t\t\t\tThe sheet index, -1 if the sheet was not found\n\t */\n\tfunction _getSheetIndex($sheet_name)\n\t{\n\t\tif (!isset($this->_ext_sheets[$sheet_name])) {\n\t\t\treturn -1;\n\t\t} else {\n\t\t\treturn $this->_ext_sheets[$sheet_name];\n\t\t}\n\t}\n\n\t/**\n\t * This method is used to update the array of sheet names. It is\n\t * called by the addWorksheet() method of the\n\t * PHPExcel_Writer_Excel5_Workbook class.\n\t *\n\t * @access public\n\t * @see PHPExcel_Writer_Excel5_Workbook::addWorksheet()\n\t * @param string  $name  The name of the worksheet being added\n\t * @param integer $index The index of the worksheet being added\n\t */\n\tfunction setExtSheet($name, $index)\n\t{\n\t\t$this->_ext_sheets[$name] = $index;\n\t}\n\n\t/**\n\t * pack() row and column into the required 3 or 4 byte format.\n\t *\n\t * @access private\n\t * @param string $cell The Excel cell reference to be packed\n\t * @return array Array containing the row and column in packed() format\n\t */\n\tfunction _cellToPackedRowcol($cell)\n\t{\n\t\t$cell = strtoupper($cell);\n\t\tlist($row, $col, $row_rel, $col_rel) = $this->_cellToRowcol($cell);\n\t\tif ($col >= 256) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Column in: $cell greater than 255\");\n\t\t}\n\t\tif ($row >= 65536) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Row in: $cell greater than 65536 \");\n\t\t}\n\n\t\t// Set the high bits to indicate if row or col are relative.\n\t\t$col |= $col_rel << 14;\n\t\t$col |= $row_rel << 15;\n\t\t$col = pack('v', $col);\n\n\t\t$row = pack('v', $row);\n\n\t\treturn array($row, $col);\n\t}\n\n\t/**\n\t * pack() row range into the required 3 or 4 byte format.\n\t * Just using maximum col/rows, which is probably not the correct solution\n\t *\n\t * @access private\n\t * @param string $range The Excel range to be packed\n\t * @return array Array containing (row1,col1,row2,col2) in packed() format\n\t */\n\tfunction _rangeToPackedRange($range)\n\t{\n\t\tpreg_match('/(\\$)?(\\d+)\\:(\\$)?(\\d+)/', $range, $match);\n\t\t// return absolute rows if there is a $ in the ref\n\t\t$row1_rel = empty($match[1]) ? 1 : 0;\n\t\t$row1     = $match[2];\n\t\t$row2_rel = empty($match[3]) ? 1 : 0;\n\t\t$row2     = $match[4];\n\t\t// Convert 1-index to zero-index\n\t\t--$row1;\n\t\t--$row2;\n\t\t// Trick poor inocent Excel\n\t\t$col1 = 0;\n\t\t$col2 = 65535; // FIXME: maximum possible value for Excel 5 (change this!!!)\n\n\t\t// FIXME: this changes for BIFF8\n\t\tif (($row1 >= 65536) or ($row2 >= 65536)) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Row in: $range greater than 65536 \");\n\t\t}\n\n\t\t// Set the high bits to indicate if rows are relative.\n\t\t$col1 |= $row1_rel << 15;\n\t\t$col2 |= $row2_rel << 15;\n\t\t$col1 = pack('v', $col1);\n\t\t$col2 = pack('v', $col2);\n\n\t\t$row1 = pack('v', $row1);\n\t\t$row2 = pack('v', $row2);\n\n\t\treturn array($row1, $col1, $row2, $col2);\n\t}\n\n\t/**\n\t * Convert an Excel cell reference such as A1 or $B2 or C$3 or $D$4 to a zero\n\t * indexed row and column number. Also returns two (0,1) values to indicate\n\t * whether the row or column are relative references.\n\t *\n\t * @access private\n\t * @param string $cell The Excel cell reference in A1 format.\n\t * @return array\n\t */\n\tfunction _cellToRowcol($cell)\n\t{\n\t\tpreg_match('/(\\$)?([A-I]?[A-Z])(\\$)?(\\d+)/',$cell,$match);\n\t\t// return absolute column if there is a $ in the ref\n\t\t$col_rel = empty($match[1]) ? 1 : 0;\n\t\t$col_ref = $match[2];\n\t\t$row_rel = empty($match[3]) ? 1 : 0;\n\t\t$row     = $match[4];\n\n\t\t// Convert base26 column string to a number.\n\t\t$expn   = strlen($col_ref) - 1;\n\t\t$col    = 0;\n\t\t$col_ref_length = strlen($col_ref);\n\t\tfor ($i = 0; $i < $col_ref_length; ++$i) {\n\t\t\t$col += (ord($col_ref{$i}) - 64) * pow(26, $expn);\n\t\t\t--$expn;\n\t\t}\n\n\t\t// Convert 1-index to zero-index\n\t\t--$row;\n\t\t--$col;\n\n\t\treturn array($row, $col, $row_rel, $col_rel);\n\t}\n\n\t/**\n\t * Advance to the next valid token.\n\t *\n\t * @access private\n\t */\n\tfunction _advance()\n\t{\n\t\t$i = $this->_current_char;\n\t\t$formula_length = strlen($this->_formula);\n\t\t// eat up white spaces\n\t\tif ($i < $formula_length) {\n\t\t\twhile ($this->_formula{$i} == \" \") {\n\t\t\t\t++$i;\n\t\t\t}\n\n\t\t\tif ($i < ($formula_length - 1)) {\n\t\t\t\t$this->_lookahead = $this->_formula{$i+1};\n\t\t\t}\n\t\t\t$token = '';\n\t\t}\n\n\t\twhile ($i < $formula_length) {\n\t\t\t$token .= $this->_formula{$i};\n\n\t\t\tif ($i < ($formula_length - 1)) {\n\t\t\t\t$this->_lookahead = $this->_formula{$i+1};\n\t\t\t} else {\n\t\t\t\t$this->_lookahead = '';\n\t\t\t}\n\n\t\t\tif ($this->_match($token) != '') {\n\t\t\t\t//if ($i < strlen($this->_formula) - 1) {\n\t\t\t\t//    $this->_lookahead = $this->_formula{$i+1};\n\t\t\t\t//}\n\t\t\t\t$this->_current_char = $i + 1;\n\t\t\t\t$this->_current_token = $token;\n\t\t\t\treturn 1;\n\t\t\t}\n\n\t\t\tif ($i < ($formula_length - 2)) {\n\t\t\t\t$this->_lookahead = $this->_formula{$i+2};\n\t\t\t} else { // if we run out of characters _lookahead becomes empty\n\t\t\t\t$this->_lookahead = '';\n\t\t\t}\n\t\t\t++$i;\n\t\t}\n\t\t//die(\"Lexical error \".$this->_current_char);\n\t}\n\n\t/**\n\t * Checks if it's a valid token.\n\t *\n\t * @access private\n\t * @param mixed $token The token to check.\n\t * @return mixed       The checked token or false on failure\n\t */\n\tfunction _match($token)\n\t{\n\t\tswitch($token) {\n\t\t\tcase \"+\":\n\t\t\tcase \"-\":\n\t\t\tcase \"*\":\n\t\t\tcase \"/\":\n\t\t\tcase \"(\":\n\t\t\tcase \")\":\n\t\t\tcase \",\":\n\t\t\tcase \";\":\n\t\t\tcase \">=\":\n\t\t\tcase \"<=\":\n\t\t\tcase \"=\":\n\t\t\tcase \"<>\":\n\t\t\tcase \"^\":\n\t\t\tcase \"&\":\n\t\t\tcase \"%\":\n\t\t\t\treturn $token;\n\t\t\t\tbreak;\n\t\t\tcase \">\":\n\t\t\t\tif ($this->_lookahead == '=') { // it's a GE token\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn $token;\n\t\t\t\tbreak;\n\t\t\tcase \"<\":\n\t\t\t\t// it's a LE or a NE token\n\t\t\t\tif (($this->_lookahead == '=') or ($this->_lookahead == '>')) {\n\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\treturn $token;\n\t\t\t\tbreak;\n\t\t\tdefault:\n\t\t\t\t// if it's a reference A1 or $A$1 or $A1 or A$1\n\t\t\t\tif (preg_match('/^\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/',$token) and\n\t\t\t\t   !preg_match(\"/[0-9]/\",$this->_lookahead) and\n\t\t\t\t   ($this->_lookahead != ':') and ($this->_lookahead != '.') and\n\t\t\t\t   ($this->_lookahead != '!'))\n\t\t\t\t{\n\t\t\t\t\treturn $token;\n\t\t\t\t}\n\t\t\t\t// If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1)\n\t\t\t\telseif (preg_match(\"/^\" . self::REGEX_SHEET_TITLE_UNQUOTED . \"(\\:\" . self::REGEX_SHEET_TITLE_UNQUOTED . \")?\\!\\\\$?[A-Ia-i]?[A-Za-z]\\\\$?[0-9]+$/u\",$token) and\n\t\t\t\t\t   !preg_match(\"/[0-9]/\",$this->_lookahead) and\n\t\t\t\t\t   ($this->_lookahead != ':') and ($this->_lookahead != '.'))\n\t\t\t\t{\n\t\t\t\t\treturn $token;\n\t\t\t\t}\n\t\t\t\t// If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1)\n\t\t\t\telseif (preg_match(\"/^'\" . self::REGEX_SHEET_TITLE_QUOTED . \"(\\:\" . self::REGEX_SHEET_TITLE_QUOTED . \")?'\\!\\\\$?[A-Ia-i]?[A-Za-z]\\\\$?[0-9]+$/u\",$token) and\n\t\t\t\t\t   !preg_match(\"/[0-9]/\",$this->_lookahead) and\n\t\t\t\t\t   ($this->_lookahead != ':') and ($this->_lookahead != '.'))\n\t\t\t\t{\n\t\t\t\t\treturn $token;\n\t\t\t\t}\n\t\t\t\t// if it's a range A1:A2 or $A$1:$A$2\n\t\t\t\telseif (preg_match('/^(\\$)?[A-Ia-i]?[A-Za-z](\\$)?[0-9]+:(\\$)?[A-Ia-i]?[A-Za-z](\\$)?[0-9]+$/', $token) and\n\t\t\t\t\t   !preg_match(\"/[0-9]/\",$this->_lookahead))\n\t\t\t\t{\n\t\t\t\t\treturn $token;\n\t\t\t\t}\n\t\t\t\t// If it's an external range like Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2\n\t\t\t\telseif (preg_match(\"/^\" . self::REGEX_SHEET_TITLE_UNQUOTED . \"(\\:\" . self::REGEX_SHEET_TITLE_UNQUOTED . \")?\\!\\\\$?([A-Ia-i]?[A-Za-z])?\\\\$?[0-9]+:\\\\$?([A-Ia-i]?[A-Za-z])?\\\\$?[0-9]+$/u\",$token) and\n\t\t\t\t\t   !preg_match(\"/[0-9]/\",$this->_lookahead))\n\t\t\t\t{\n\t\t\t\t\treturn $token;\n\t\t\t\t}\n\t\t\t\t// If it's an external range like 'Sheet1'!A1:B2 or 'Sheet1:Sheet2'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1:Sheet2'!$A$1:$B$2\n\t\t\t\telseif (preg_match(\"/^'\" . self::REGEX_SHEET_TITLE_QUOTED . \"(\\:\" . self::REGEX_SHEET_TITLE_QUOTED . \")?'\\!\\\\$?([A-Ia-i]?[A-Za-z])?\\\\$?[0-9]+:\\\\$?([A-Ia-i]?[A-Za-z])?\\\\$?[0-9]+$/u\",$token) and\n\t\t\t\t\t   !preg_match(\"/[0-9]/\",$this->_lookahead))\n\t\t\t\t{\n\t\t\t\t\treturn $token;\n\t\t\t\t}\n\t\t\t\t// If it's a number (check that it's not a sheet name or range)\n\t\t\t\telseif (is_numeric($token) and\n\t\t\t\t\t\t(!is_numeric($token.$this->_lookahead) or ($this->_lookahead == '')) and\n\t\t\t\t\t\t($this->_lookahead != '!') and ($this->_lookahead != ':'))\n\t\t\t\t{\n\t\t\t\t\treturn $token;\n\t\t\t\t}\n\t\t\t\t// If it's a string (of maximum 255 characters)\n\t\t\t\telseif (preg_match(\"/\\\"([^\\\"]|\\\"\\\"){0,255}\\\"/\",$token) and $this->_lookahead != '\"' and (substr_count($token, '\"')%2 == 0))\n\t\t\t\t{\n\t\t\t\t\treturn $token;\n\t\t\t\t}\n\t\t\t    // If it's an error code\n\t\t\t    elseif (preg_match(\"/^#[A-Z0\\/]{3,5}[!?]{1}$/\", $token) or $token == '#N/A')\n\t\t\t    {\n\t\t\t        return $token;\n\t\t\t    }\n\t\t\t\t// if it's a function call\n\t\t\t\telseif (preg_match(\"/^[A-Z0-9\\xc0-\\xdc\\.]+$/i\",$token) and ($this->_lookahead == \"(\"))\n\t\t\t\t{\n\t\t\t\t\treturn $token;\n\t\t\t\t}\n\t\t\t\t//\tIt's an argument of some description (e.g. a named range),\n\t\t\t\t//\t\tprecise nature yet to be determined\n\t\t\t\telseif(substr($token,-1) == ')') {\n\t\t\t\t\treturn $token;\n\t\t\t\t}\n\t\t\t\treturn '';\n\t\t}\n\t}\n\n\t/**\n\t * The parsing method. It parses a formula.\n\t *\n\t * @access public\n\t * @param string $formula The formula to parse, without the initial equal\n\t *                        sign (=).\n\t * @return mixed true on success\n\t */\n\tfunction parse($formula)\n\t{\n\t\t$this->_current_char = 0;\n\t\t$this->_formula      = $formula;\n\t\t$this->_lookahead    = isset($formula{1}) ? $formula{1} : '';\n\t\t$this->_advance();\n\t\t$this->_parse_tree   = $this->_condition();\n\t\treturn true;\n\t}\n\n\t/**\n\t * It parses a condition. It assumes the following rule:\n\t * Cond -> Expr [(\">\" | \"<\") Expr]\n\t *\n\t * @access private\n\t * @return mixed The parsed ptg'd tree on success\n\t */\n\tfunction _condition()\n\t{\n\t\t$result = $this->_expression();\n\t\tif ($this->_current_token == \"<\") {\n\t\t\t$this->_advance();\n\t\t\t$result2 = $this->_expression();\n\t\t\t$result = $this->_createTree('ptgLT', $result, $result2);\n\t\t} elseif ($this->_current_token == \">\") {\n\t\t\t$this->_advance();\n\t\t\t$result2 = $this->_expression();\n\t\t\t$result = $this->_createTree('ptgGT', $result, $result2);\n\t\t} elseif ($this->_current_token == \"<=\") {\n\t\t\t$this->_advance();\n\t\t\t$result2 = $this->_expression();\n\t\t\t$result = $this->_createTree('ptgLE', $result, $result2);\n\t\t} elseif ($this->_current_token == \">=\") {\n\t\t\t$this->_advance();\n\t\t\t$result2 = $this->_expression();\n\t\t\t$result = $this->_createTree('ptgGE', $result, $result2);\n\t\t} elseif ($this->_current_token == \"=\") {\n\t\t\t$this->_advance();\n\t\t\t$result2 = $this->_expression();\n\t\t\t$result = $this->_createTree('ptgEQ', $result, $result2);\n\t\t} elseif ($this->_current_token == \"<>\") {\n\t\t\t$this->_advance();\n\t\t\t$result2 = $this->_expression();\n\t\t\t$result = $this->_createTree('ptgNE', $result, $result2);\n\t\t} elseif ($this->_current_token == \"&\") {\n\t\t    $this->_advance();\n\t\t    $result2 = $this->_expression();\n\t\t    $result = $this->_createTree('ptgConcat', $result, $result2);\n\t\t}\n\t\treturn $result;\n\t}\n\n\t/**\n\t * It parses a expression. It assumes the following rule:\n\t * Expr -> Term [(\"+\" | \"-\") Term]\n\t *      -> \"string\"\n\t *      -> \"-\" Term : Negative value\n\t *      -> \"+\" Term : Positive value\n\t *      -> Error code\n\t *\n\t * @access private\n\t * @return mixed The parsed ptg'd tree on success\n\t */\n\tfunction _expression()\n\t{\n\t\t// If it's a string return a string node\n\t\tif (preg_match(\"/\\\"([^\\\"]|\\\"\\\"){0,255}\\\"/\", $this->_current_token)) {\n\t\t\t$tmp = str_replace('\"\"', '\"', $this->_current_token);\n\t\t\tif (($tmp == '\"') || ($tmp == '')) $tmp = '\"\"';\t//\tTrap for \"\" that has been used for an empty string\n\t\t\t$result = $this->_createTree($tmp, '', '');\n\t\t\t$this->_advance();\n\t\t\treturn $result;\n        // If it's an error code\n        } elseif (preg_match(\"/^#[A-Z0\\/]{3,5}[!?]{1}$/\", $this->_current_token) or $this->_current_token == '#N/A'){\n\t\t    $result = $this->_createTree($this->_current_token, 'ptgErr', '');\n\t\t    $this->_advance();\n\t\t    return $result;\n\t\t// If it's a negative value\n        } elseif ($this->_current_token == \"-\") {\n\t\t\t// catch \"-\" Term\n\t\t\t$this->_advance();\n\t\t\t$result2 = $this->_expression();\n\t\t\t$result = $this->_createTree('ptgUminus', $result2, '');\n\t\t\treturn $result;\n        // If it's a positive value\n\t\t} elseif ($this->_current_token == \"+\") {\n\t\t\t// catch \"+\" Term\n\t\t\t$this->_advance();\n\t\t\t$result2 = $this->_expression();\n\t\t\t$result = $this->_createTree('ptgUplus', $result2, '');\n\t\t\treturn $result;\n\t\t}\n\t\t$result = $this->_term();\n\t\twhile (($this->_current_token == \"+\") or\n\t\t\t   ($this->_current_token == \"-\") or\n\t\t\t   ($this->_current_token == \"^\")) {\n\t\t/**/\n\t\t\tif ($this->_current_token == \"+\") {\n\t\t\t\t$this->_advance();\n\t\t\t\t$result2 = $this->_term();\n\t\t\t\t$result = $this->_createTree('ptgAdd', $result, $result2);\n\t\t\t} elseif ($this->_current_token == \"-\") {\n\t\t\t\t$this->_advance();\n\t\t\t\t$result2 = $this->_term();\n\t\t\t\t$result = $this->_createTree('ptgSub', $result, $result2);\n\t\t\t} else {\n\t\t\t\t$this->_advance();\n\t\t\t\t$result2 = $this->_term();\n\t\t\t\t$result = $this->_createTree('ptgPower', $result, $result2);\n\t\t\t}\n\t\t}\n\t\treturn $result;\n\t}\n\n\t/**\n\t * This function just introduces a ptgParen element in the tree, so that Excel\n\t * doesn't get confused when working with a parenthesized formula afterwards.\n\t *\n\t * @access private\n\t * @see _fact()\n\t * @return array The parsed ptg'd tree\n\t */\n\tfunction _parenthesizedExpression()\n\t{\n\t\t$result = $this->_createTree('ptgParen', $this->_expression(), '');\n\t\treturn $result;\n\t}\n\n\t/**\n\t * It parses a term. It assumes the following rule:\n\t * Term -> Fact [(\"*\" | \"/\") Fact]\n\t *\n\t * @access private\n\t * @return mixed The parsed ptg'd tree on success\n\t */\n\tfunction _term()\n\t{\n\t\t$result = $this->_fact();\n\t\twhile (($this->_current_token == \"*\") or\n\t\t\t   ($this->_current_token == \"/\")) {\n\t\t/**/\n\t\t\tif ($this->_current_token == \"*\") {\n\t\t\t\t$this->_advance();\n\t\t\t\t$result2 = $this->_fact();\n\t\t\t\t$result = $this->_createTree('ptgMul', $result, $result2);\n\t\t\t} else {\n\t\t\t\t$this->_advance();\n\t\t\t\t$result2 = $this->_fact();\n\t\t\t\t$result = $this->_createTree('ptgDiv', $result, $result2);\n\t\t\t}\n\t\t}\n\t\treturn $result;\n\t}\n\n\t/**\n\t * It parses a factor. It assumes the following rule:\n\t * Fact -> ( Expr )\n\t *       | CellRef\n\t *       | CellRange\n\t *       | Number\n\t *       | Function\n\t *\n\t * @access private\n\t * @return mixed The parsed ptg'd tree on success\n\t */\n\tfunction _fact()\n\t{\n\t\tif ($this->_current_token == \"(\") {\n\t\t\t$this->_advance();         // eat the \"(\"\n\t\t\t$result = $this->_parenthesizedExpression();\n\t\t\tif ($this->_current_token != \")\") {\n\t\t\t\tthrow new PHPExcel_Writer_Exception(\"')' token expected.\");\n\t\t\t}\n\t\t\t$this->_advance();         // eat the \")\"\n\t\t\treturn $result;\n\t\t}\n\t\t// if it's a reference\n\t\tif (preg_match('/^\\$?[A-Ia-i]?[A-Za-z]\\$?[0-9]+$/',$this->_current_token))\n\t\t{\n\t\t\t$result = $this->_createTree($this->_current_token, '', '');\n\t\t\t$this->_advance();\n\t\t\treturn $result;\n\t\t}\n\t\t// If it's an external reference (Sheet1!A1 or Sheet1:Sheet2!A1 or Sheet1!$A$1 or Sheet1:Sheet2!$A$1)\n\t\telseif (preg_match(\"/^\" . self::REGEX_SHEET_TITLE_UNQUOTED . \"(\\:\" . self::REGEX_SHEET_TITLE_UNQUOTED . \")?\\!\\\\$?[A-Ia-i]?[A-Za-z]\\\\$?[0-9]+$/u\",$this->_current_token))\n\t\t{\n\t\t\t$result = $this->_createTree($this->_current_token, '', '');\n\t\t\t$this->_advance();\n\t\t\treturn $result;\n\t\t}\n\t\t// If it's an external reference ('Sheet1'!A1 or 'Sheet1:Sheet2'!A1 or 'Sheet1'!$A$1 or 'Sheet1:Sheet2'!$A$1)\n\t\telseif (preg_match(\"/^'\" . self::REGEX_SHEET_TITLE_QUOTED . \"(\\:\" . self::REGEX_SHEET_TITLE_QUOTED . \")?'\\!\\\\$?[A-Ia-i]?[A-Za-z]\\\\$?[0-9]+$/u\",$this->_current_token))\n\t\t{\n\t\t\t$result = $this->_createTree($this->_current_token, '', '');\n\t\t\t$this->_advance();\n\t\t\treturn $result;\n\t\t}\n\t\t// if it's a range A1:B2 or $A$1:$B$2\n\t\telseif (preg_match('/^(\\$)?[A-Ia-i]?[A-Za-z](\\$)?[0-9]+:(\\$)?[A-Ia-i]?[A-Za-z](\\$)?[0-9]+$/',$this->_current_token) or\n\t\t\t\tpreg_match('/^(\\$)?[A-Ia-i]?[A-Za-z](\\$)?[0-9]+\\.\\.(\\$)?[A-Ia-i]?[A-Za-z](\\$)?[0-9]+$/',$this->_current_token))\n\t\t{\n\t\t\t// must be an error?\n\t\t\t$result = $this->_createTree($this->_current_token, '', '');\n\t\t\t$this->_advance();\n\t\t\treturn $result;\n\t\t}\n\t\t// If it's an external range (Sheet1!A1:B2 or Sheet1:Sheet2!A1:B2 or Sheet1!$A$1:$B$2 or Sheet1:Sheet2!$A$1:$B$2)\n\t\telseif (preg_match(\"/^\" . self::REGEX_SHEET_TITLE_UNQUOTED . \"(\\:\" . self::REGEX_SHEET_TITLE_UNQUOTED . \")?\\!\\\\$?([A-Ia-i]?[A-Za-z])?\\\\$?[0-9]+:\\\\$?([A-Ia-i]?[A-Za-z])?\\\\$?[0-9]+$/u\",$this->_current_token))\n\t\t{\n\t\t\t// must be an error?\n\t\t\t//$result = $this->_current_token;\n\t\t\t$result = $this->_createTree($this->_current_token, '', '');\n\t\t\t$this->_advance();\n\t\t\treturn $result;\n\t\t}\n\t\t// If it's an external range ('Sheet1'!A1:B2 or 'Sheet1'!A1:B2 or 'Sheet1'!$A$1:$B$2 or 'Sheet1'!$A$1:$B$2)\n\t\telseif (preg_match(\"/^'\" . self::REGEX_SHEET_TITLE_QUOTED . \"(\\:\" . self::REGEX_SHEET_TITLE_QUOTED . \")?'\\!\\\\$?([A-Ia-i]?[A-Za-z])?\\\\$?[0-9]+:\\\\$?([A-Ia-i]?[A-Za-z])?\\\\$?[0-9]+$/u\",$this->_current_token))\n\t\t{\n\t\t\t// must be an error?\n\t\t\t//$result = $this->_current_token;\n\t\t\t$result = $this->_createTree($this->_current_token, '', '');\n\t\t\t$this->_advance();\n\t\t\treturn $result;\n\t\t}\n\t\t// If it's a number or a percent\n\t\telseif (is_numeric($this->_current_token))\n\t\t{\n\t\t    if($this->_lookahead == '%'){\n\t\t        $result = $this->_createTree('ptgPercent', $this->_current_token, '');\n                $this->_advance();  // Skip the percentage operator once we've pre-built that tree\n\t\t    } else {\n\t\t        $result = $this->_createTree($this->_current_token, '', '');\n\t\t    }\n\t\t    $this->_advance();\n\t\t    return $result;\n\t\t}\n\t\t// if it's a function call\n\t\telseif (preg_match(\"/^[A-Z0-9\\xc0-\\xdc\\.]+$/i\",$this->_current_token))\n\t\t{\n\t\t\t$result = $this->_func();\n\t\t\treturn $result;\n\t\t}\n\t\tthrow new PHPExcel_Writer_Exception(\"Syntax error: \".$this->_current_token.\n\t\t\t\t\t\t\t\t \", lookahead: \".$this->_lookahead.\n\t\t\t\t\t\t\t\t \", current char: \".$this->_current_char);\n\t}\n\n\t/**\n\t * It parses a function call. It assumes the following rule:\n\t * Func -> ( Expr [,Expr]* )\n\t *\n\t * @access private\n\t * @return mixed The parsed ptg'd tree on success\n\t */\n\tfunction _func()\n\t{\n\t\t$num_args = 0; // number of arguments received\n\t\t$function = strtoupper($this->_current_token);\n\t\t$result   = ''; // initialize result\n\t\t$this->_advance();\n\t\t$this->_advance();         // eat the \"(\"\n\t\twhile ($this->_current_token != ')') {\n\t\t/**/\n\t\t\tif ($num_args > 0) {\n\t\t\t\tif ($this->_current_token == \",\" or\n\t\t\t\t\t$this->_current_token == \";\")\n\t\t\t\t{\n\t\t\t\t\t$this->_advance();  // eat the \",\" or \";\"\n\t\t\t\t} else {\n\t\t\t\t\tthrow new PHPExcel_Writer_Exception(\"Syntax error: comma expected in \".\n\t\t\t\t\t\t\t\t\t  \"function $function, arg #{$num_args}\");\n\t\t\t\t}\n\t\t\t\t$result2 = $this->_condition();\n\t\t\t\t$result = $this->_createTree('arg', $result, $result2);\n\t\t\t} else { // first argument\n\t\t\t\t$result2 = $this->_condition();\n\t\t\t\t$result = $this->_createTree('arg', '', $result2);\n\t\t\t}\n\t\t\t++$num_args;\n\t\t}\n\t\tif (!isset($this->_functions[$function])) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Function $function() doesn't exist\");\n\t\t}\n\t\t$args = $this->_functions[$function][1];\n\t\t// If fixed number of args eg. TIME($i,$j,$k). Check that the number of args is valid.\n\t\tif (($args >= 0) and ($args != $num_args)) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Incorrect number of arguments in function $function() \");\n\t\t}\n\n\t\t$result = $this->_createTree($function, $result, $num_args);\n\t\t$this->_advance();         // eat the \")\"\n\t\treturn $result;\n\t}\n\n\t/**\n\t * Creates a tree. In fact an array which may have one or two arrays (sub-trees)\n\t * as elements.\n\t *\n\t * @access private\n\t * @param mixed $value The value of this node.\n\t * @param mixed $left  The left array (sub-tree) or a final node.\n\t * @param mixed $right The right array (sub-tree) or a final node.\n\t * @return array A tree\n\t */\n\tfunction _createTree($value, $left, $right)\n\t{\n\t\treturn array('value' => $value, 'left' => $left, 'right' => $right);\n\t}\n\n\t/**\n\t * Builds a string containing the tree in reverse polish notation (What you\n\t * would use in a HP calculator stack).\n\t * The following tree:\n\t *\n\t *    +\n\t *   / \\\n\t *  2   3\n\t *\n\t * produces: \"23+\"\n\t *\n\t * The following tree:\n\t *\n\t *    +\n\t *   / \\\n\t *  3   *\n\t *     / \\\n\t *    6   A1\n\t *\n\t * produces: \"36A1*+\"\n\t *\n\t * In fact all operands, functions, references, etc... are written as ptg's\n\t *\n\t * @access public\n\t * @param array $tree The optional tree to convert.\n\t * @return string The tree in reverse polish notation\n\t */\n\tfunction toReversePolish($tree = array())\n\t{\n\t\t$polish = \"\"; // the string we are going to return\n\t\tif (empty($tree)) { // If it's the first call use _parse_tree\n\t\t\t$tree = $this->_parse_tree;\n\t\t}\n\n\t\tif (is_array($tree['left'])) {\n\t\t\t$converted_tree = $this->toReversePolish($tree['left']);\n\t\t\t$polish .= $converted_tree;\n\t\t} elseif ($tree['left'] != '') { // It's a final node\n\t\t\t$converted_tree = $this->_convert($tree['left']);\n\t\t\t$polish .= $converted_tree;\n\t\t}\n\t\tif (is_array($tree['right'])) {\n\t\t\t$converted_tree = $this->toReversePolish($tree['right']);\n\t\t\t$polish .= $converted_tree;\n\t\t} elseif ($tree['right'] != '') { // It's a final node\n\t\t\t$converted_tree = $this->_convert($tree['right']);\n\t\t\t$polish .= $converted_tree;\n\t\t}\n\t\t// if it's a function convert it here (so we can set it's arguments)\n\t\tif (preg_match(\"/^[A-Z0-9\\xc0-\\xdc\\.]+$/\",$tree['value']) and\n\t\t\t!preg_match('/^([A-Ia-i]?[A-Za-z])(\\d+)$/',$tree['value']) and\n\t\t\t!preg_match(\"/^[A-Ia-i]?[A-Za-z](\\d+)\\.\\.[A-Ia-i]?[A-Za-z](\\d+)$/\",$tree['value']) and\n\t\t\t!is_numeric($tree['value']) and\n\t\t\t!isset($this->ptg[$tree['value']]))\n\t\t{\n\t\t\t// left subtree for a function is always an array.\n\t\t\tif ($tree['left'] != '') {\n\t\t\t\t$left_tree = $this->toReversePolish($tree['left']);\n\t\t\t} else {\n\t\t\t\t$left_tree = '';\n\t\t\t}\n\t\t\t// add it's left subtree and return.\n\t\t\treturn $left_tree.$this->_convertFunction($tree['value'], $tree['right']);\n\t\t} else {\n\t\t\t$converted_tree = $this->_convert($tree['value']);\n\t\t}\n\t\t$polish .= $converted_tree;\n\t\treturn $polish;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5/Workbook.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n// Original file header of PEAR::Spreadsheet_Excel_Writer_Workbook (used as the base for this class):\n// -----------------------------------------------------------------------------------------\n// /*\n// *  Module written/ported by Xavier Noguer <xnoguer@rezebra.com>\n// *\n// *  The majority of this is _NOT_ my code.  I simply ported it from the\n// *  PERL Spreadsheet::WriteExcel module.\n// *\n// *  The author of the Spreadsheet::WriteExcel module is John McNamara\n// *  <jmcnamara@cpan.org>\n// *\n// *  I _DO_ maintain this code, and John McNamara has nothing to do with the\n// *  porting of this code to PHP.  Any questions directly related to this\n// *  class library should be directed to me.\n// *\n// *  License Information:\n// *\n// *    Spreadsheet_Excel_Writer:  A library for generating Excel Spreadsheets\n// *    Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com\n// *\n// *    This library is free software; you can redistribute it and/or\n// *    modify it under the terms of the GNU Lesser General Public\n// *    License as published by the Free Software Foundation; either\n// *    version 2.1 of the License, or (at your option) any later version.\n// *\n// *    This library is distributed in the hope that it will be useful,\n// *    but WITHOUT ANY WARRANTY; without even the implied warranty of\n// *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n// *    Lesser General Public License for more details.\n// *\n// *    You should have received a copy of the GNU Lesser General Public\n// *    License along with this library; if not, write to the Free Software\n// *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n// */\n\n\n/**\n * PHPExcel_Writer_Excel5_Workbook\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel5_Workbook extends PHPExcel_Writer_Excel5_BIFFwriter\n{\n\t/**\n\t * Formula parser\n\t *\n\t * @var PHPExcel_Writer_Excel5_Parser\n\t */\n\tprivate $_parser;\n\n\t/**\n\t * The BIFF file size for the workbook.\n\t * @var integer\n\t * @see _calcSheetOffsets()\n\t */\n\tpublic $_biffsize;\n\n\t/**\n\t * XF Writers\n\t * @var PHPExcel_Writer_Excel5_Xf[]\n\t */\n\tprivate $_xfWriters = array();\n\n\t/**\n\t * Array containing the colour palette\n\t * @var array\n\t */\n\tpublic $_palette;\n\n\t/**\n\t * The codepage indicates the text encoding used for strings\n\t * @var integer\n\t */\n\tpublic $_codepage;\n\n\t/**\n\t * The country code used for localization\n\t * @var integer\n\t */\n\tpublic $_country_code;\n\n\t/**\n\t * Workbook\n\t * @var PHPExcel\n\t */\n\tprivate $_phpExcel;\n\n\t/**\n\t * Fonts writers\n\t *\n\t * @var PHPExcel_Writer_Excel5_Font[]\n\t */\n\tprivate $_fontWriters = array();\n\n\t/**\n\t * Added fonts. Maps from font's hash => index in workbook\n\t *\n\t * @var array\n\t */\n\tprivate $_addedFonts = array();\n\n\t/**\n\t * Shared number formats\n\t *\n\t * @var array\n\t */\n\tprivate $_numberFormats = array();\n\n\t/**\n\t * Added number formats. Maps from numberFormat's hash => index in workbook\n\t *\n\t * @var array\n\t */\n\tprivate $_addedNumberFormats = array();\n\n\t/**\n\t * Sizes of the binary worksheet streams\n\t *\n\t * @var array\n\t */\n\tprivate $_worksheetSizes = array();\n\n\t/**\n\t * Offsets of the binary worksheet streams relative to the start of the global workbook stream\n\t *\n\t * @var array\n\t */\n\tprivate $_worksheetOffsets = array();\n\n\t/**\n\t * Total number of shared strings in workbook\n\t *\n\t * @var int\n\t */\n\tprivate $_str_total;\n\n\t/**\n\t * Number of unique shared strings in workbook\n\t *\n\t * @var int\n\t */\n\tprivate $_str_unique;\n\n\t/**\n\t * Array of unique shared strings in workbook\n\t *\n\t * @var array\n\t */\n\tprivate $_str_table;\n\n\t/**\n\t * Color cache\n\t */\n\tprivate $_colors;\n\n\t/**\n\t * Escher object corresponding to MSODRAWINGGROUP\n\t *\n\t * @var PHPExcel_Shared_Escher\n\t */\n\tprivate $_escher;\n\n\n\t/**\n\t * Class constructor\n\t *\n\t * @param PHPExcel\t$phpExcel\t\tThe Workbook\n\t * @param int\t\t&$str_total\t\tTotal number of strings\n\t * @param int\t\t&$str_unique\tTotal number of unique strings\n\t * @param array\t\t&$str_table\t\tString Table\n\t * @param array\t\t&$colors\t\tColour Table\n\t * @param mixed\t\t$parser\t\t\tThe formula parser created for the Workbook\n\t */\n\tpublic function __construct(PHPExcel $phpExcel = null,\n\t\t\t\t\t\t\t\t&$str_total, &$str_unique, &$str_table, &$colors,\n\t\t\t\t\t\t\t\t$parser )\n\t{\n\t\t// It needs to call its parent's constructor explicitly\n\t\tparent::__construct();\n\n\t\t$this->_parser           = $parser;\n\t\t$this->_biffsize         = 0;\n\t\t$this->_palette          = array();\n\t\t$this->_country_code     = -1;\n\n\t\t$this->_str_total       = &$str_total;\n\t\t$this->_str_unique      = &$str_unique;\n\t\t$this->_str_table       = &$str_table;\n\t\t$this->_colors          = &$colors;\n\t\t$this->_setPaletteXl97();\n\n\t\t$this->_phpExcel = $phpExcel;\n\n\t\t// set BIFFwriter limit for CONTINUE records\n\t\t//\t\t$this->_limit = 8224;\n\t\t$this->_codepage = 0x04B0;\n\n\t\t// Add empty sheets and Build color cache\n\t\t$countSheets = $phpExcel->getSheetCount();\n\t\tfor ($i = 0; $i < $countSheets; ++$i) {\n\t\t\t$phpSheet = $phpExcel->getSheet($i);\n\n\t\t\t$this->_parser->setExtSheet($phpSheet->getTitle(), $i);  // Register worksheet name with parser\n\n\t\t\t$supbook_index = 0x00;\n\t\t\t$ref = pack('vvv', $supbook_index, $i, $i);\n\t\t\t$this->_parser->_references[] = $ref;  // Register reference with parser\n\n\t\t\t// Sheet tab colors?\n\t\t\tif ($phpSheet->isTabColorSet()) {\n\t\t\t\t$this->_addColor($phpSheet->getTabColor()->getRGB());\n\t\t\t}\n\t\t}\n\n\t}\n\n\t/**\n\t * Add a new XF writer\n\t *\n\t * @param PHPExcel_Style\n\t * @param boolean Is it a style XF?\n\t * @return int Index to XF record\n\t */\n\tpublic function addXfWriter($style, $isStyleXf = false)\n\t{\n\t\t$xfWriter = new PHPExcel_Writer_Excel5_Xf($style);\n\t\t$xfWriter->setIsStyleXf($isStyleXf);\n\n\t\t// Add the font if not already added\n\t\t$fontIndex = $this->_addFont($style->getFont());\n\n\t\t// Assign the font index to the xf record\n\t\t$xfWriter->setFontIndex($fontIndex);\n\n\t\t// Background colors, best to treat these after the font so black will come after white in custom palette\n\t\t$xfWriter->setFgColor($this->_addColor($style->getFill()->getStartColor()->getRGB()));\n\t\t$xfWriter->setBgColor($this->_addColor($style->getFill()->getEndColor()->getRGB()));\n\t\t$xfWriter->setBottomColor($this->_addColor($style->getBorders()->getBottom()->getColor()->getRGB()));\n\t\t$xfWriter->setTopColor($this->_addColor($style->getBorders()->getTop()->getColor()->getRGB()));\n\t\t$xfWriter->setRightColor($this->_addColor($style->getBorders()->getRight()->getColor()->getRGB()));\n\t\t$xfWriter->setLeftColor($this->_addColor($style->getBorders()->getLeft()->getColor()->getRGB()));\n\t\t$xfWriter->setDiagColor($this->_addColor($style->getBorders()->getDiagonal()->getColor()->getRGB()));\n\n\t\t// Add the number format if it is not a built-in one and not already added\n\t\tif ($style->getNumberFormat()->getBuiltInFormatCode() === false) {\n\t\t\t$numberFormatHashCode = $style->getNumberFormat()->getHashCode();\n\n\t\t\tif (isset($this->_addedNumberFormats[$numberFormatHashCode])) {\n\t\t\t\t$numberFormatIndex = $this->_addedNumberFormats[$numberFormatHashCode];\n\t\t\t} else {\n\t\t\t\t$numberFormatIndex = 164 + count($this->_numberFormats);\n\t\t\t\t$this->_numberFormats[$numberFormatIndex] = $style->getNumberFormat();\n\t\t\t\t$this->_addedNumberFormats[$numberFormatHashCode] = $numberFormatIndex;\n\t\t\t}\n\t\t} else {\n\t\t\t$numberFormatIndex = (int) $style->getNumberFormat()->getBuiltInFormatCode();\n\t\t}\n\n\t\t// Assign the number format index to xf record\n\t\t$xfWriter->setNumberFormatIndex($numberFormatIndex);\n\n\t\t$this->_xfWriters[] = $xfWriter;\n\n\t\t$xfIndex = count($this->_xfWriters) - 1;\n\t\treturn $xfIndex;\n\t}\n\n\t/**\n\t * Add a font to added fonts\n\t *\n\t * @param PHPExcel_Style_Font $font\n\t * @return int Index to FONT record\n\t */\n\tpublic function _addFont(PHPExcel_Style_Font $font)\n\t{\n\t\t$fontHashCode = $font->getHashCode();\n\t\tif(isset($this->_addedFonts[$fontHashCode])){\n\t\t\t$fontIndex = $this->_addedFonts[$fontHashCode];\n\t\t} else {\n\t\t\t$countFonts = count($this->_fontWriters);\n\t\t\t$fontIndex = ($countFonts < 4) ? $countFonts : $countFonts + 1;\n\n\t\t\t$fontWriter = new PHPExcel_Writer_Excel5_Font($font);\n\t\t\t$fontWriter->setColorIndex($this->_addColor($font->getColor()->getRGB()));\n\t\t\t$this->_fontWriters[] = $fontWriter;\n\n\t\t\t$this->_addedFonts[$fontHashCode] = $fontIndex;\n\t\t}\n\t\treturn $fontIndex;\n\t}\n\n\t/**\n\t * Alter color palette adding a custom color\n\t *\n\t * @param string $rgb E.g. 'FF00AA'\n\t * @return int Color index\n\t */\n\tprivate function _addColor($rgb) {\n\t\tif (!isset($this->_colors[$rgb])) {\n\t\t\tif (count($this->_colors) < 57) {\n\t\t\t\t// then we add a custom color altering the palette\n\t\t\t\t$colorIndex = 8 + count($this->_colors);\n\t\t\t\t$this->_palette[$colorIndex] =\n\t\t\t\t\tarray(\n\t\t\t\t\t\thexdec(substr($rgb, 0, 2)),\n\t\t\t\t\t\thexdec(substr($rgb, 2, 2)),\n\t\t\t\t\t\thexdec(substr($rgb, 4)),\n\t\t\t\t\t\t0\n\t\t\t\t\t);\n\t\t\t\t$this->_colors[$rgb] = $colorIndex;\n\t\t\t} else {\n\t\t\t\t// no room for more custom colors, just map to black\n\t\t\t\t$colorIndex = 0;\n\t\t\t}\n\t\t} else {\n\t\t\t// fetch already added custom color\n\t\t\t$colorIndex = $this->_colors[$rgb];\n\t\t}\n\n\t\treturn $colorIndex;\n\t}\n\n\t/**\n\t * Sets the colour palette to the Excel 97+ default.\n\t *\n\t * @access private\n\t */\n\tfunction _setPaletteXl97()\n\t{\n\t\t$this->_palette = array(\n\t\t\t0x08 => array(0x00, 0x00, 0x00, 0x00),\n\t\t\t0x09 => array(0xff, 0xff, 0xff, 0x00),\n\t\t\t0x0A => array(0xff, 0x00, 0x00, 0x00),\n\t\t\t0x0B => array(0x00, 0xff, 0x00, 0x00),\n\t\t\t0x0C => array(0x00, 0x00, 0xff, 0x00),\n\t\t\t0x0D => array(0xff, 0xff, 0x00, 0x00),\n\t\t\t0x0E => array(0xff, 0x00, 0xff, 0x00),\n\t\t\t0x0F => array(0x00, 0xff, 0xff, 0x00),\n\t\t\t0x10 => array(0x80, 0x00, 0x00, 0x00),\n\t\t\t0x11 => array(0x00, 0x80, 0x00, 0x00),\n\t\t\t0x12 => array(0x00, 0x00, 0x80, 0x00),\n\t\t\t0x13 => array(0x80, 0x80, 0x00, 0x00),\n\t\t\t0x14 => array(0x80, 0x00, 0x80, 0x00),\n\t\t\t0x15 => array(0x00, 0x80, 0x80, 0x00),\n\t\t\t0x16 => array(0xc0, 0xc0, 0xc0, 0x00),\n\t\t\t0x17 => array(0x80, 0x80, 0x80, 0x00),\n\t\t\t0x18 => array(0x99, 0x99, 0xff, 0x00),\n\t\t\t0x19 => array(0x99, 0x33, 0x66, 0x00),\n\t\t\t0x1A => array(0xff, 0xff, 0xcc, 0x00),\n\t\t\t0x1B => array(0xcc, 0xff, 0xff, 0x00),\n\t\t\t0x1C => array(0x66, 0x00, 0x66, 0x00),\n\t\t\t0x1D => array(0xff, 0x80, 0x80, 0x00),\n\t\t\t0x1E => array(0x00, 0x66, 0xcc, 0x00),\n\t\t\t0x1F => array(0xcc, 0xcc, 0xff, 0x00),\n\t\t\t0x20 => array(0x00, 0x00, 0x80, 0x00),\n\t\t\t0x21 => array(0xff, 0x00, 0xff, 0x00),\n\t\t\t0x22 => array(0xff, 0xff, 0x00, 0x00),\n\t\t\t0x23 => array(0x00, 0xff, 0xff, 0x00),\n\t\t\t0x24 => array(0x80, 0x00, 0x80, 0x00),\n\t\t\t0x25 => array(0x80, 0x00, 0x00, 0x00),\n\t\t\t0x26 => array(0x00, 0x80, 0x80, 0x00),\n\t\t\t0x27 => array(0x00, 0x00, 0xff, 0x00),\n\t\t\t0x28 => array(0x00, 0xcc, 0xff, 0x00),\n\t\t\t0x29 => array(0xcc, 0xff, 0xff, 0x00),\n\t\t\t0x2A => array(0xcc, 0xff, 0xcc, 0x00),\n\t\t\t0x2B => array(0xff, 0xff, 0x99, 0x00),\n\t\t\t0x2C => array(0x99, 0xcc, 0xff, 0x00),\n\t\t\t0x2D => array(0xff, 0x99, 0xcc, 0x00),\n\t\t\t0x2E => array(0xcc, 0x99, 0xff, 0x00),\n\t\t\t0x2F => array(0xff, 0xcc, 0x99, 0x00),\n\t\t\t0x30 => array(0x33, 0x66, 0xff, 0x00),\n\t\t\t0x31 => array(0x33, 0xcc, 0xcc, 0x00),\n\t\t\t0x32 => array(0x99, 0xcc, 0x00, 0x00),\n\t\t\t0x33 => array(0xff, 0xcc, 0x00, 0x00),\n\t\t\t0x34 => array(0xff, 0x99, 0x00, 0x00),\n\t\t\t0x35 => array(0xff, 0x66, 0x00, 0x00),\n\t\t\t0x36 => array(0x66, 0x66, 0x99, 0x00),\n\t\t\t0x37 => array(0x96, 0x96, 0x96, 0x00),\n\t\t\t0x38 => array(0x00, 0x33, 0x66, 0x00),\n\t\t\t0x39 => array(0x33, 0x99, 0x66, 0x00),\n\t\t\t0x3A => array(0x00, 0x33, 0x00, 0x00),\n\t\t\t0x3B => array(0x33, 0x33, 0x00, 0x00),\n\t\t\t0x3C => array(0x99, 0x33, 0x00, 0x00),\n\t\t\t0x3D => array(0x99, 0x33, 0x66, 0x00),\n\t\t\t0x3E => array(0x33, 0x33, 0x99, 0x00),\n\t\t\t0x3F => array(0x33, 0x33, 0x33, 0x00),\n\t\t);\n\t}\n\n\t/**\n\t * Assemble worksheets into a workbook and send the BIFF data to an OLE\n\t * storage.\n\t *\n\t * @param\tarray\t$pWorksheetSizes\tThe sizes in bytes of the binary worksheet streams\n\t * @return\tstring\tBinary data for workbook stream\n\t */\n\tpublic function writeWorkbook($pWorksheetSizes = null)\n\t{\n\t\t$this->_worksheetSizes = $pWorksheetSizes;\n\n\t\t// Calculate the number of selected worksheet tabs and call the finalization\n\t\t// methods for each worksheet\n\t\t$total_worksheets = $this->_phpExcel->getSheetCount();\n\n\t\t// Add part 1 of the Workbook globals, what goes before the SHEET records\n\t\t$this->_storeBof(0x0005);\n\t\t$this->_writeCodepage();\n\t\t$this->_writeWindow1();\n\n\t\t$this->_writeDatemode();\n\t\t$this->_writeAllFonts();\n\t\t$this->_writeAllNumFormats();\n\t\t$this->_writeAllXfs();\n\t\t$this->_writeAllStyles();\n\t\t$this->_writePalette();\n\n\t\t// Prepare part 3 of the workbook global stream, what goes after the SHEET records\n\t\t$part3 = '';\n\t\tif ($this->_country_code != -1) {\n\t\t\t$part3 .= $this->_writeCountry();\n\t\t}\n\t\t$part3 .= $this->_writeRecalcId();\n\n\t\t$part3 .= $this->_writeSupbookInternal();\n\t\t/* TODO: store external SUPBOOK records and XCT and CRN records\n\t\tin case of external references for BIFF8 */\n\t\t$part3 .= $this->_writeExternsheetBiff8();\n\t\t$part3 .= $this->_writeAllDefinedNamesBiff8();\n\t\t$part3 .= $this->_writeMsoDrawingGroup();\n\t\t$part3 .= $this->_writeSharedStringsTable();\n\n\t\t$part3 .= $this->writeEof();\n\n\t\t// Add part 2 of the Workbook globals, the SHEET records\n\t\t$this->_calcSheetOffsets();\n\t\tfor ($i = 0; $i < $total_worksheets; ++$i) {\n\t\t\t$this->_writeBoundsheet($this->_phpExcel->getSheet($i), $this->_worksheetOffsets[$i]);\n\t\t}\n\n\t\t// Add part 3 of the Workbook globals\n\t\t$this->_data .= $part3;\n\n\t\treturn $this->_data;\n\t}\n\n\t/**\n\t * Calculate offsets for Worksheet BOF records.\n\t *\n\t * @access private\n\t */\n\tfunction _calcSheetOffsets()\n\t{\n\t\t$boundsheet_length = 10;  // fixed length for a BOUNDSHEET record\n\n\t\t// size of Workbook globals part 1 + 3\n\t\t$offset            = $this->_datasize;\n\n\t\t// add size of Workbook globals part 2, the length of the SHEET records\n\t\t$total_worksheets = count($this->_phpExcel->getAllSheets());\n\t\tforeach ($this->_phpExcel->getWorksheetIterator() as $sheet) {\n\t\t\t$offset += $boundsheet_length + strlen(PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheet->getTitle()));\n\t\t}\n\n\t\t// add the sizes of each of the Sheet substreams, respectively\n\t\tfor ($i = 0; $i < $total_worksheets; ++$i) {\n\t\t\t$this->_worksheetOffsets[$i] = $offset;\n\t\t\t$offset += $this->_worksheetSizes[$i];\n\t\t}\n\t\t$this->_biffsize = $offset;\n\t}\n\n\t/**\n\t * Store the Excel FONT records.\n\t */\n\tprivate function _writeAllFonts()\n\t{\n\t\tforeach ($this->_fontWriters as $fontWriter) {\n\t\t\t$this->_append($fontWriter->writeFont());\n\t\t}\n\t}\n\n\t/**\n\t * Store user defined numerical formats i.e. FORMAT records\n\t */\n\tprivate function _writeAllNumFormats()\n\t{\n\t\tforeach ($this->_numberFormats as $numberFormatIndex => $numberFormat) {\n\t\t\t$this->_writeNumFormat($numberFormat->getFormatCode(), $numberFormatIndex);\n\t\t}\n\t}\n\n\t/**\n\t * Write all XF records.\n\t */\n\tprivate function _writeAllXfs()\n\t{\n\t\tforeach ($this->_xfWriters as $xfWriter) {\n\t\t\t$this->_append($xfWriter->writeXf());\n\t\t}\n\t}\n\n\t/**\n\t * Write all STYLE records.\n\t */\n\tprivate function _writeAllStyles()\n\t{\n\t\t$this->_writeStyle();\n\t}\n\n\t/**\n\t * Write the EXTERNCOUNT and EXTERNSHEET records. These are used as indexes for\n\t * the NAME records.\n\t */\n\tprivate function _writeExterns()\n\t{\n\t\t$countSheets = $this->_phpExcel->getSheetCount();\n\t\t// Create EXTERNCOUNT with number of worksheets\n\t\t$this->_writeExterncount($countSheets);\n\n\t\t// Create EXTERNSHEET for each worksheet\n\t\tfor ($i = 0; $i < $countSheets; ++$i) {\n\t\t\t$this->_writeExternsheet($this->_phpExcel->getSheet($i)->getTitle());\n\t\t}\n\t}\n\n\t/**\n\t * Write the NAME record to define the print area and the repeat rows and cols.\n\t */\n\tprivate function _writeNames()\n\t{\n\t\t// total number of sheets\n\t\t$total_worksheets = $this->_phpExcel->getSheetCount();\n\n\t\t// Create the print area NAME records\n\t\tfor ($i = 0; $i < $total_worksheets; ++$i) {\n\t\t\t$sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup();\n\t\t\t// Write a Name record if the print area has been defined\n\t\t\tif ($sheetSetup->isPrintAreaSet()) {\n\t\t\t\t// Print area\n\t\t\t\t$printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea());\n\t\t\t\t$printArea = $printArea[0];\n\t\t\t\t$printArea[0] = PHPExcel_Cell::coordinateFromString($printArea[0]);\n\t\t\t\t$printArea[1] = PHPExcel_Cell::coordinateFromString($printArea[1]);\n\n\t\t\t\t$print_rowmin = $printArea[0][1] - 1;\n\t\t\t\t$print_rowmax = $printArea[1][1] - 1;\n\t\t\t\t$print_colmin = PHPExcel_Cell::columnIndexFromString($printArea[0][0]) - 1;\n\t\t\t\t$print_colmax = PHPExcel_Cell::columnIndexFromString($printArea[1][0]) - 1;\n\n\t\t\t\t$this->_writeNameShort(\n\t\t\t\t\t$i, // sheet index\n\t\t\t\t\t0x06, // NAME type\n\t\t\t\t\t$print_rowmin,\n\t\t\t\t\t$print_rowmax,\n\t\t\t\t\t$print_colmin,\n\t\t\t\t\t$print_colmax\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t// Create the print title NAME records\n\t\tfor ($i = 0; $i < $total_worksheets; ++$i) {\n\t\t\t$sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup();\n\n\t\t\t// simultaneous repeatColumns repeatRows\n\t\t\tif ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) {\n\t\t\t\t$repeat = $sheetSetup->getColumnsToRepeatAtLeft();\n\t\t\t\t$colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1;\n\t\t\t\t$colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1;\n\n\t\t\t\t$repeat = $sheetSetup->getRowsToRepeatAtTop();\n\t\t\t\t$rowmin = $repeat[0] - 1;\n\t\t\t\t$rowmax = $repeat[1] - 1;\n\n\t\t\t\t$this->_writeNameLong(\n\t\t\t\t\t$i, // sheet index\n\t\t\t\t\t0x07, // NAME type\n\t\t\t\t\t$rowmin,\n\t\t\t\t\t$rowmax,\n\t\t\t\t\t$colmin,\n\t\t\t\t\t$colmax\n\t\t\t\t\t);\n\n\t\t\t// (exclusive) either repeatColumns or repeatRows\n\t\t\t} else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) {\n\n\t\t\t\t// Columns to repeat\n\t\t\t\tif ($sheetSetup->isColumnsToRepeatAtLeftSet()) {\n\t\t\t\t\t$repeat = $sheetSetup->getColumnsToRepeatAtLeft();\n\t\t\t\t\t$colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1;\n\t\t\t\t\t$colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1;\n\t\t\t\t} else {\n\t\t\t\t\t$colmin = 0;\n\t\t\t\t\t$colmax = 255;\n\t\t\t\t}\n\n\t\t\t\t// Rows to repeat\n\t\t\t\tif ($sheetSetup->isRowsToRepeatAtTopSet()) {\n\t\t\t\t\t$repeat = $sheetSetup->getRowsToRepeatAtTop();\n\t\t\t\t\t$rowmin = $repeat[0] - 1;\n\t\t\t\t\t$rowmax = $repeat[1] - 1;\n\t\t\t\t} else {\n\t\t\t\t\t$rowmin = 0;\n\t\t\t\t\t$rowmax = 65535;\n\t\t\t\t}\n\n\t\t\t\t$this->_writeNameShort(\n\t\t\t\t\t$i, // sheet index\n\t\t\t\t\t0x07, // NAME type\n\t\t\t\t\t$rowmin,\n\t\t\t\t\t$rowmax,\n\t\t\t\t\t$colmin,\n\t\t\t\t\t$colmax\n\t\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Writes all the DEFINEDNAME records (BIFF8).\n\t * So far this is only used for repeating rows/columns (print titles) and print areas\n\t */\n\tprivate function _writeAllDefinedNamesBiff8()\n\t{\n\t\t$chunk = '';\n\n\t\t// Named ranges\n\t\tif (count($this->_phpExcel->getNamedRanges()) > 0) {\n\t\t\t// Loop named ranges\n\t\t\t$namedRanges = $this->_phpExcel->getNamedRanges();\n\t\t\tforeach ($namedRanges as $namedRange) {\n\n\t\t\t\t// Create absolute coordinate\n\t\t\t\t$range = PHPExcel_Cell::splitRange($namedRange->getRange());\n\t\t\t\tfor ($i = 0; $i < count($range); $i++) {\n\t\t\t\t\t$range[$i][0] = '\\'' . str_replace(\"'\", \"''\", $namedRange->getWorksheet()->getTitle()) . '\\'!' . PHPExcel_Cell::absoluteCoordinate($range[$i][0]);\n\t\t\t\t\tif (isset($range[$i][1])) {\n\t\t\t\t\t\t$range[$i][1] = PHPExcel_Cell::absoluteCoordinate($range[$i][1]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\t$range = PHPExcel_Cell::buildRange($range); // e.g. Sheet1!$A$1:$B$2\n\n\t\t\t\t// parse formula\n\t\t\t\ttry {\n\t\t\t\t\t$error = $this->_parser->parse($range);\n\t\t\t\t\t$formulaData = $this->_parser->toReversePolish();\n\n\t\t\t\t\t// make sure tRef3d is of type tRef3dR (0x3A)\n\t\t\t\t\tif (isset($formulaData{0}) and ($formulaData{0} == \"\\x7A\" or $formulaData{0} == \"\\x5A\")) {\n\t\t\t\t\t\t$formulaData = \"\\x3A\" . substr($formulaData, 1);\n\t\t\t\t\t}\n\n\t\t\t\t\tif ($namedRange->getLocalOnly()) {\n\t\t\t\t\t\t// local scope\n\t\t\t\t\t\t$scope = $this->_phpExcel->getIndex($namedRange->getScope()) + 1;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// global scope\n\t\t\t\t\t\t$scope = 0;\n\t\t\t\t\t}\n\t\t\t\t\t$chunk .= $this->writeData($this->_writeDefinedNameBiff8($namedRange->getName(), $formulaData, $scope, false));\n\n\t\t\t\t} catch(PHPExcel_Exception $e) {\n\t\t\t\t\t// do nothing\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// total number of sheets\n\t\t$total_worksheets = $this->_phpExcel->getSheetCount();\n\n\t\t// write the print titles (repeating rows, columns), if any\n\t\tfor ($i = 0; $i < $total_worksheets; ++$i) {\n\t\t\t$sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup();\n\t\t\t// simultaneous repeatColumns repeatRows\n\t\t\tif ($sheetSetup->isColumnsToRepeatAtLeftSet() && $sheetSetup->isRowsToRepeatAtTopSet()) {\n\t\t\t\t$repeat = $sheetSetup->getColumnsToRepeatAtLeft();\n\t\t\t\t$colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1;\n\t\t\t\t$colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1;\n\n\t\t\t\t$repeat = $sheetSetup->getRowsToRepeatAtTop();\n\t\t\t\t$rowmin = $repeat[0] - 1;\n\t\t\t\t$rowmax = $repeat[1] - 1;\n\n\t\t\t\t// construct formula data manually\n\t\t\t\t$formulaData = pack('Cv', 0x29, 0x17); // tMemFunc\n\t\t\t\t$formulaData .= pack('Cvvvvv', 0x3B, $i, 0, 65535, $colmin, $colmax); // tArea3d\n\t\t\t\t$formulaData .= pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, 0, 255); // tArea3d\n\t\t\t\t$formulaData .= pack('C', 0x10); // tList\n\n\t\t\t\t// store the DEFINEDNAME record\n\t\t\t\t$chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true));\n\n\t\t\t// (exclusive) either repeatColumns or repeatRows\n\t\t\t} else if ($sheetSetup->isColumnsToRepeatAtLeftSet() || $sheetSetup->isRowsToRepeatAtTopSet()) {\n\n\t\t\t\t// Columns to repeat\n\t\t\t\tif ($sheetSetup->isColumnsToRepeatAtLeftSet()) {\n\t\t\t\t\t$repeat = $sheetSetup->getColumnsToRepeatAtLeft();\n\t\t\t\t\t$colmin = PHPExcel_Cell::columnIndexFromString($repeat[0]) - 1;\n\t\t\t\t\t$colmax = PHPExcel_Cell::columnIndexFromString($repeat[1]) - 1;\n\t\t\t\t} else {\n\t\t\t\t\t$colmin = 0;\n\t\t\t\t\t$colmax = 255;\n\t\t\t\t}\n\t\t\t\t// Rows to repeat\n\t\t\t\tif ($sheetSetup->isRowsToRepeatAtTopSet()) {\n\t\t\t\t\t$repeat = $sheetSetup->getRowsToRepeatAtTop();\n\t\t\t\t\t$rowmin = $repeat[0] - 1;\n\t\t\t\t\t$rowmax = $repeat[1] - 1;\n\t\t\t\t} else {\n\t\t\t\t\t$rowmin = 0;\n\t\t\t\t\t$rowmax = 65535;\n\t\t\t\t}\n\n\t\t\t\t// construct formula data manually because parser does not recognize absolute 3d cell references\n\t\t\t\t$formulaData = pack('Cvvvvv', 0x3B, $i, $rowmin, $rowmax, $colmin, $colmax);\n\n\t\t\t\t// store the DEFINEDNAME record\n\t\t\t\t$chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x07), $formulaData, $i + 1, true));\n\t\t\t}\n\t\t}\n\n\t\t// write the print areas, if any\n\t\tfor ($i = 0; $i < $total_worksheets; ++$i) {\n\t\t\t$sheetSetup = $this->_phpExcel->getSheet($i)->getPageSetup();\n\t\t\tif ($sheetSetup->isPrintAreaSet()) {\n\t\t\t\t// Print area, e.g. A3:J6,H1:X20\n\t\t\t\t$printArea = PHPExcel_Cell::splitRange($sheetSetup->getPrintArea());\n\t\t\t\t$countPrintArea = count($printArea);\n\n\t\t\t\t$formulaData = '';\n\t\t\t\tfor ($j = 0; $j < $countPrintArea; ++$j) {\n\t\t\t\t\t$printAreaRect = $printArea[$j]; // e.g. A3:J6\n\t\t\t\t\t$printAreaRect[0] = PHPExcel_Cell::coordinateFromString($printAreaRect[0]);\n\t\t\t\t\t$printAreaRect[1] = PHPExcel_Cell::coordinateFromString($printAreaRect[1]);\n\n\t\t\t\t\t$print_rowmin = $printAreaRect[0][1] - 1;\n\t\t\t\t\t$print_rowmax = $printAreaRect[1][1] - 1;\n\t\t\t\t\t$print_colmin = PHPExcel_Cell::columnIndexFromString($printAreaRect[0][0]) - 1;\n\t\t\t\t\t$print_colmax = PHPExcel_Cell::columnIndexFromString($printAreaRect[1][0]) - 1;\n\n\t\t\t\t\t// construct formula data manually because parser does not recognize absolute 3d cell references\n\t\t\t\t\t$formulaData .= pack('Cvvvvv', 0x3B, $i, $print_rowmin, $print_rowmax, $print_colmin, $print_colmax);\n\n\t\t\t\t\tif ($j > 0) {\n\t\t\t\t\t\t$formulaData .= pack('C', 0x10); // list operator token ','\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// store the DEFINEDNAME record\n\t\t\t\t$chunk .= $this->writeData($this->_writeDefinedNameBiff8(pack('C', 0x06), $formulaData, $i + 1, true));\n\t\t\t}\n\t\t}\n\n\t\t// write autofilters, if any\n\t\tfor ($i = 0; $i < $total_worksheets; ++$i) {\n\t\t\t$sheetAutoFilter = $this->_phpExcel->getSheet($i)->getAutoFilter();\n\t\t\t$autoFilterRange = $sheetAutoFilter->getRange();\n\t\t\tif(!empty($autoFilterRange)) {\n\t\t\t\t$rangeBounds = PHPExcel_Cell::rangeBoundaries($autoFilterRange);\n\n\t\t\t\t//Autofilter built in name\n\t\t\t\t$name = pack('C', 0x0D);\n\n\t\t\t\t$chunk .= $this->writeData($this->_writeShortNameBiff8($name, $i + 1, $rangeBounds, true));\n\t\t\t}\n\t\t}\n\n\t\treturn $chunk;\n\t}\n\n\t/**\n\t * Write a DEFINEDNAME record for BIFF8 using explicit binary formula data\n\t *\n\t * @param\tstring\t\t$name\t\t\tThe name in UTF-8\n\t * @param\tstring\t\t$formulaData\tThe binary formula data\n\t * @param\tstring\t\t$sheetIndex\t\t1-based sheet index the defined name applies to. 0 = global\n\t * @param\tboolean\t\t$isBuiltIn\t\tBuilt-in name?\n\t * @return\tstring\tComplete binary record data\n\t */\n\tprivate function _writeDefinedNameBiff8($name, $formulaData, $sheetIndex = 0, $isBuiltIn = false)\n\t{\n\t\t$record = 0x0018;\n\n\t\t// option flags\n\t\t$options = $isBuiltIn ? 0x20 : 0x00;\n\n\t\t// length of the name, character count\n\t\t$nlen = PHPExcel_Shared_String::CountCharacters($name);\n\n\t\t// name with stripped length field\n\t\t$name = substr(PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($name), 2);\n\n\t\t// size of the formula (in bytes)\n\t\t$sz = strlen($formulaData);\n\n\t\t// combine the parts\n\t\t$data = pack('vCCvvvCCCC', $options, 0, $nlen, $sz, 0, $sheetIndex, 0, 0, 0, 0)\n\t\t\t. $name . $formulaData;\n\t\t$length = strlen($data);\n\n\t\t$header = pack('vv', $record, $length);\n\n\t\treturn $header . $data;\n\t}\n\n\t/**\n\t * Write a short NAME record\n\t *\n\t * @param\tstring\t\t $name\n\t * @param\tstring\t\t $sheetIndex\t\t1-based sheet index the defined name applies to. 0 = global\n\t * @param\tinteger[][]  $rangeBounds    range boundaries\n\t * @param\tboolean      $isHidden\n\t * @return\tstring\tComplete binary record data\n\t * */\n\tprivate function _writeShortNameBiff8($name, $sheetIndex = 0, $rangeBounds, $isHidden = false){\n\t\t$record = 0x0018;\n\n\t\t// option flags\n\t\t$options = ($isHidden  ? 0x21 : 0x00);\n\n\t\t$extra  = pack('Cvvvvv',\n\t\t\t\t0x3B,\n\t\t\t\t$sheetIndex - 1,\n\t\t\t\t$rangeBounds[0][1] - 1,\n\t\t\t\t$rangeBounds[1][1] - 1,\n\t\t\t\t$rangeBounds[0][0] - 1,\n\t\t\t\t$rangeBounds[1][0] - 1);\n\n\t\t// size of the formula (in bytes)\n\t\t$sz = strlen($extra);\n\n\t\t// combine the parts\n\t\t$data = pack('vCCvvvCCCCC', $options, 0, 1, $sz, 0, $sheetIndex, 0, 0, 0, 0, 0)\n\t\t\t. $name . $extra;\n\t\t$length = strlen($data);\n\n\t\t$header = pack('vv', $record, $length);\n\n\t\treturn $header . $data;\n\t}\n\n\t/**\n\t * Stores the CODEPAGE biff record.\n\t */\n\tprivate function _writeCodepage()\n\t{\n\t\t$record          = 0x0042;             // Record identifier\n\t\t$length          = 0x0002;             // Number of bytes to follow\n\t\t$cv              = $this->_codepage;   // The code page\n\n\t\t$header          = pack('vv', $record, $length);\n\t\t$data            = pack('v',  $cv);\n\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write Excel BIFF WINDOW1 record.\n\t */\n\tprivate function _writeWindow1()\n\t{\n\t\t$record    = 0x003D;                 // Record identifier\n\t\t$length    = 0x0012;                 // Number of bytes to follow\n\n\t\t$xWn       = 0x0000;                 // Horizontal position of window\n\t\t$yWn       = 0x0000;                 // Vertical position of window\n\t\t$dxWn      = 0x25BC;                 // Width of window\n\t\t$dyWn      = 0x1572;                 // Height of window\n\n\t\t$grbit     = 0x0038;                 // Option flags\n\n\t\t// not supported by PHPExcel, so there is only one selected sheet, the active\n\t\t$ctabsel   = 1;       // Number of workbook tabs selected\n\n\t\t$wTabRatio = 0x0258;                 // Tab to scrollbar ratio\n\n\t\t// not supported by PHPExcel, set to 0\n\t\t$itabFirst = 0;     // 1st displayed worksheet\n\t\t$itabCur   = $this->_phpExcel->getActiveSheetIndex();    // Active worksheet\n\n\t\t$header    = pack(\"vv\",        $record, $length);\n\t\t$data      = pack(\"vvvvvvvvv\", $xWn, $yWn, $dxWn, $dyWn,\n\t\t\t\t\t\t\t\t\t   $grbit,\n\t\t\t\t\t\t\t\t\t   $itabCur, $itabFirst,\n\t\t\t\t\t\t\t\t\t   $ctabsel, $wTabRatio);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Writes Excel BIFF BOUNDSHEET record.\n\t *\n\t * @param PHPExcel_Worksheet  $sheet Worksheet name\n\t * @param integer $offset    Location of worksheet BOF\n\t */\n\tprivate function _writeBoundsheet($sheet, $offset)\n\t{\n\t\t$sheetname = $sheet->getTitle();\n\t\t$record    = 0x0085;                    // Record identifier\n\n\t\t// sheet state\n\t\tswitch ($sheet->getSheetState()) {\n\t\t\tcase PHPExcel_Worksheet::SHEETSTATE_VISIBLE:\t$ss = 0x00; break;\n\t\t\tcase PHPExcel_Worksheet::SHEETSTATE_HIDDEN:\t\t$ss = 0x01; break;\n\t\t\tcase PHPExcel_Worksheet::SHEETSTATE_VERYHIDDEN:\t$ss = 0x02; break;\n\t\t\tdefault: $ss = 0x00; break;\n\t\t}\n\n\t\t// sheet type\n\t\t$st = 0x00;\n\n\t\t$grbit     = 0x0000;                    // Visibility and sheet type\n\n\t\t$data      = pack(\"VCC\", $offset, $ss, $st);\n\t\t$data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($sheetname);\n\n\t\t$length = strlen($data);\n\t\t$header = pack(\"vv\",  $record, $length);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write Internal SUPBOOK record\n\t */\n\tprivate function _writeSupbookInternal()\n\t{\n\t\t$record    = 0x01AE;   // Record identifier\n\t\t$length    = 0x0004;   // Bytes to follow\n\n\t\t$header    = pack(\"vv\", $record, $length);\n\t\t$data      = pack(\"vv\", $this->_phpExcel->getSheetCount(), 0x0401);\n\t\treturn $this->writeData($header . $data);\n\t}\n\n\t/**\n\t * Writes the Excel BIFF EXTERNSHEET record. These references are used by\n\t * formulas.\n\t *\n\t */\n\tprivate function _writeExternsheetBiff8()\n\t{\n\t\t$total_references = count($this->_parser->_references);\n\t\t$record   = 0x0017;                     // Record identifier\n\t\t$length   = 2 + 6 * $total_references;  // Number of bytes to follow\n\n\t\t$supbook_index = 0;           // FIXME: only using internal SUPBOOK record\n\t\t$header           = pack(\"vv\",  $record, $length);\n\t\t$data             = pack('v', $total_references);\n\t\tfor ($i = 0; $i < $total_references; ++$i) {\n\t\t\t$data .= $this->_parser->_references[$i];\n\t\t}\n\t\treturn $this->writeData($header . $data);\n\t}\n\n\t/**\n\t * Write Excel BIFF STYLE records.\n\t */\n\tprivate function _writeStyle()\n\t{\n\t\t$record    = 0x0293;   // Record identifier\n\t\t$length    = 0x0004;   // Bytes to follow\n\n\t\t$ixfe      = 0x8000;  // Index to cell style XF\n\t\t$BuiltIn   = 0x00;     // Built-in style\n\t\t$iLevel    = 0xff;     // Outline style level\n\n\t\t$header    = pack(\"vv\",  $record, $length);\n\t\t$data      = pack(\"vCC\", $ixfe, $BuiltIn, $iLevel);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Writes Excel FORMAT record for non \"built-in\" numerical formats.\n\t *\n\t * @param string  $format Custom format string\n\t * @param integer $ifmt   Format index code\n\t */\n\tprivate function _writeNumFormat($format, $ifmt)\n\t{\n\t\t$record    = 0x041E;                      // Record identifier\n\n\t\t$numberFormatString = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($format);\n\t\t$length    = 2 + strlen($numberFormatString);      // Number of bytes to follow\n\n\n\t\t$header    = pack(\"vv\", $record, $length);\n\t\t$data      = pack(\"v\", $ifmt) .  $numberFormatString;\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write DATEMODE record to indicate the date system in use (1904 or 1900).\n\t */\n\tprivate function _writeDatemode()\n\t{\n\t\t$record    = 0x0022;         // Record identifier\n\t\t$length    = 0x0002;         // Bytes to follow\n\n\t\t$f1904     = (PHPExcel_Shared_Date::getExcelCalendar() == PHPExcel_Shared_Date::CALENDAR_MAC_1904) ?\n\t\t\t1 : 0;   // Flag for 1904 date system\n\n\t\t$header    = pack(\"vv\", $record, $length);\n\t\t$data      = pack(\"v\", $f1904);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write BIFF record EXTERNCOUNT to indicate the number of external sheet\n\t * references in the workbook.\n\t *\n\t * Excel only stores references to external sheets that are used in NAME.\n\t * The workbook NAME record is required to define the print area and the repeat\n\t * rows and columns.\n\t *\n\t * A similar method is used in Worksheet.php for a slightly different purpose.\n\t *\n\t * @param integer $cxals Number of external references\n\t */\n\tprivate function _writeExterncount($cxals)\n\t{\n\t\t$record   = 0x0016;          // Record identifier\n\t\t$length   = 0x0002;          // Number of bytes to follow\n\n\t\t$header   = pack(\"vv\", $record, $length);\n\t\t$data     = pack(\"v\",  $cxals);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Writes the Excel BIFF EXTERNSHEET record. These references are used by\n\t * formulas. NAME record is required to define the print area and the repeat\n\t * rows and columns.\n\t *\n\t * A similar method is used in Worksheet.php for a slightly different purpose.\n\t *\n\t * @param string $sheetname Worksheet name\n\t */\n\tprivate function _writeExternsheet($sheetname)\n\t{\n\t\t$record      = 0x0017;                     // Record identifier\n\t\t$length      = 0x02 + strlen($sheetname);  // Number of bytes to follow\n\n\t\t$cch         = strlen($sheetname);         // Length of sheet name\n\t\t$rgch        = 0x03;                       // Filename encoding\n\n\t\t$header      = pack(\"vv\",  $record, $length);\n\t\t$data        = pack(\"CC\", $cch, $rgch);\n\t\t$this->_append($header . $data . $sheetname);\n\t}\n\n\t/**\n\t * Store the NAME record in the short format that is used for storing the print\n\t * area, repeat rows only and repeat columns only.\n\t *\n\t * @param integer $index  Sheet index\n\t * @param integer $type   Built-in name type\n\t * @param integer $rowmin Start row\n\t * @param integer $rowmax End row\n\t * @param integer $colmin Start colum\n\t * @param integer $colmax End column\n\t */\n\tprivate function _writeNameShort($index, $type, $rowmin, $rowmax, $colmin, $colmax)\n\t{\n\t\t$record          = 0x0018;       // Record identifier\n\t\t$length          = 0x0024;       // Number of bytes to follow\n\n\t\t$grbit           = 0x0020;       // Option flags\n\t\t$chKey           = 0x00;         // Keyboard shortcut\n\t\t$cch             = 0x01;         // Length of text name\n\t\t$cce             = 0x0015;       // Length of text definition\n\t\t$ixals           = $index + 1;   // Sheet index\n\t\t$itab            = $ixals;       // Equal to ixals\n\t\t$cchCustMenu     = 0x00;         // Length of cust menu text\n\t\t$cchDescription  = 0x00;         // Length of description text\n\t\t$cchHelptopic    = 0x00;         // Length of help topic text\n\t\t$cchStatustext   = 0x00;         // Length of status bar text\n\t\t$rgch            = $type;        // Built-in name type\n\n\t\t$unknown03       = 0x3b;\n\t\t$unknown04       = 0xffff-$index;\n\t\t$unknown05       = 0x0000;\n\t\t$unknown06       = 0x0000;\n\t\t$unknown07       = 0x1087;\n\t\t$unknown08       = 0x8005;\n\n\t\t$header             = pack(\"vv\", $record, $length);\n\t\t$data               = pack(\"v\", $grbit);\n\t\t$data              .= pack(\"C\", $chKey);\n\t\t$data              .= pack(\"C\", $cch);\n\t\t$data              .= pack(\"v\", $cce);\n\t\t$data              .= pack(\"v\", $ixals);\n\t\t$data              .= pack(\"v\", $itab);\n\t\t$data              .= pack(\"C\", $cchCustMenu);\n\t\t$data              .= pack(\"C\", $cchDescription);\n\t\t$data              .= pack(\"C\", $cchHelptopic);\n\t\t$data              .= pack(\"C\", $cchStatustext);\n\t\t$data              .= pack(\"C\", $rgch);\n\t\t$data              .= pack(\"C\", $unknown03);\n\t\t$data              .= pack(\"v\", $unknown04);\n\t\t$data              .= pack(\"v\", $unknown05);\n\t\t$data              .= pack(\"v\", $unknown06);\n\t\t$data              .= pack(\"v\", $unknown07);\n\t\t$data              .= pack(\"v\", $unknown08);\n\t\t$data              .= pack(\"v\", $index);\n\t\t$data              .= pack(\"v\", $index);\n\t\t$data              .= pack(\"v\", $rowmin);\n\t\t$data              .= pack(\"v\", $rowmax);\n\t\t$data              .= pack(\"C\", $colmin);\n\t\t$data              .= pack(\"C\", $colmax);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Store the NAME record in the long format that is used for storing the repeat\n\t * rows and columns when both are specified. This shares a lot of code with\n\t * _writeNameShort() but we use a separate method to keep the code clean.\n\t * Code abstraction for reuse can be carried too far, and I should know. ;-)\n\t *\n\t * @param integer $index Sheet index\n\t * @param integer $type  Built-in name type\n\t * @param integer $rowmin Start row\n\t * @param integer $rowmax End row\n\t * @param integer $colmin Start colum\n\t * @param integer $colmax End column\n\t */\n\tprivate function _writeNameLong($index, $type, $rowmin, $rowmax, $colmin, $colmax)\n\t{\n\t\t$record          = 0x0018;       // Record identifier\n\t\t$length          = 0x003d;       // Number of bytes to follow\n\t\t$grbit           = 0x0020;       // Option flags\n\t\t$chKey           = 0x00;         // Keyboard shortcut\n\t\t$cch             = 0x01;         // Length of text name\n\t\t$cce             = 0x002e;       // Length of text definition\n\t\t$ixals           = $index + 1;   // Sheet index\n\t\t$itab            = $ixals;       // Equal to ixals\n\t\t$cchCustMenu     = 0x00;         // Length of cust menu text\n\t\t$cchDescription  = 0x00;         // Length of description text\n\t\t$cchHelptopic    = 0x00;         // Length of help topic text\n\t\t$cchStatustext   = 0x00;         // Length of status bar text\n\t\t$rgch            = $type;        // Built-in name type\n\n\t\t$unknown01       = 0x29;\n\t\t$unknown02       = 0x002b;\n\t\t$unknown03       = 0x3b;\n\t\t$unknown04       = 0xffff-$index;\n\t\t$unknown05       = 0x0000;\n\t\t$unknown06       = 0x0000;\n\t\t$unknown07       = 0x1087;\n\t\t$unknown08       = 0x8008;\n\n\t\t$header             = pack(\"vv\",  $record, $length);\n\t\t$data               = pack(\"v\", $grbit);\n\t\t$data              .= pack(\"C\", $chKey);\n\t\t$data              .= pack(\"C\", $cch);\n\t\t$data              .= pack(\"v\", $cce);\n\t\t$data              .= pack(\"v\", $ixals);\n\t\t$data              .= pack(\"v\", $itab);\n\t\t$data              .= pack(\"C\", $cchCustMenu);\n\t\t$data              .= pack(\"C\", $cchDescription);\n\t\t$data              .= pack(\"C\", $cchHelptopic);\n\t\t$data              .= pack(\"C\", $cchStatustext);\n\t\t$data              .= pack(\"C\", $rgch);\n\t\t$data              .= pack(\"C\", $unknown01);\n\t\t$data              .= pack(\"v\", $unknown02);\n\t\t// Column definition\n\t\t$data              .= pack(\"C\", $unknown03);\n\t\t$data              .= pack(\"v\", $unknown04);\n\t\t$data              .= pack(\"v\", $unknown05);\n\t\t$data              .= pack(\"v\", $unknown06);\n\t\t$data              .= pack(\"v\", $unknown07);\n\t\t$data              .= pack(\"v\", $unknown08);\n\t\t$data              .= pack(\"v\", $index);\n\t\t$data              .= pack(\"v\", $index);\n\t\t$data              .= pack(\"v\", 0x0000);\n\t\t$data              .= pack(\"v\", 0x3fff);\n\t\t$data              .= pack(\"C\", $colmin);\n\t\t$data              .= pack(\"C\", $colmax);\n\t\t// Row definition\n\t\t$data              .= pack(\"C\", $unknown03);\n\t\t$data              .= pack(\"v\", $unknown04);\n\t\t$data              .= pack(\"v\", $unknown05);\n\t\t$data              .= pack(\"v\", $unknown06);\n\t\t$data              .= pack(\"v\", $unknown07);\n\t\t$data              .= pack(\"v\", $unknown08);\n\t\t$data              .= pack(\"v\", $index);\n\t\t$data              .= pack(\"v\", $index);\n\t\t$data              .= pack(\"v\", $rowmin);\n\t\t$data              .= pack(\"v\", $rowmax);\n\t\t$data              .= pack(\"C\", 0x00);\n\t\t$data              .= pack(\"C\", 0xff);\n\t\t// End of data\n\t\t$data              .= pack(\"C\", 0x10);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Stores the COUNTRY record for localization\n\t *\n\t * @return string\n\t */\n\tprivate function _writeCountry()\n\t{\n\t\t$record          = 0x008C;    // Record identifier\n\t\t$length          = 4;         // Number of bytes to follow\n\n\t\t$header = pack('vv',  $record, $length);\n\t\t/* using the same country code always for simplicity */\n\t\t$data = pack('vv', $this->_country_code, $this->_country_code);\n\t\t//$this->_append($header . $data);\n\t\treturn $this->writeData($header . $data);\n\t}\n\n\t/**\n\t * Write the RECALCID record\n\t *\n\t * @return string\n\t */\n\tprivate function _writeRecalcId()\n\t{\n\t\t$record = 0x01C1;    // Record identifier\n\t\t$length = 8;         // Number of bytes to follow\n\n\t\t$header = pack('vv',  $record, $length);\n\n\t\t// by inspection of real Excel files, MS Office Excel 2007 writes this\n\t\t$data = pack('VV', 0x000001C1, 0x00001E667);\n\n\t\treturn $this->writeData($header . $data);\n\t}\n\n\t/**\n\t * Stores the PALETTE biff record.\n\t */\n\tprivate function _writePalette()\n\t{\n\t\t$aref            = $this->_palette;\n\n\t\t$record          = 0x0092;                 // Record identifier\n\t\t$length          = 2 + 4 * count($aref);   // Number of bytes to follow\n\t\t$ccv             =         count($aref);   // Number of RGB values to follow\n\t\t$data = '';                                // The RGB data\n\n\t\t// Pack the RGB data\n\t\tforeach ($aref as $color) {\n\t\t\tforeach ($color as $byte) {\n\t\t\t\t$data .= pack(\"C\",$byte);\n\t\t\t}\n\t\t}\n\n\t\t$header = pack(\"vvv\",  $record, $length, $ccv);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Handling of the SST continue blocks is complicated by the need to include an\n\t * additional continuation byte depending on whether the string is split between\n\t * blocks or whether it starts at the beginning of the block. (There are also\n\t * additional complications that will arise later when/if Rich Strings are\n\t * supported).\n\t *\n\t * The Excel documentation says that the SST record should be followed by an\n\t * EXTSST record. The EXTSST record is a hash table that is used to optimise\n\t * access to SST. However, despite the documentation it doesn't seem to be\n\t * required so we will ignore it.\n\t *\n\t * @return string Binary data\n\t */\n\tprivate function _writeSharedStringsTable()\n\t{\n\t\t// maximum size of record data (excluding record header)\n\t\t$continue_limit = 8224;\n\n\t\t// initialize array of record data blocks\n\t\t$recordDatas = array();\n\n\t\t// start SST record data block with total number of strings, total number of unique strings\n\t\t$recordData = pack(\"VV\", $this->_str_total, $this->_str_unique);\n\n\t\t// loop through all (unique) strings in shared strings table\n\t\tforeach (array_keys($this->_str_table) as $string) {\n\n\t\t\t// here $string is a BIFF8 encoded string\n\n\t\t\t// length = character count\n\t\t\t$headerinfo = unpack(\"vlength/Cencoding\", $string);\n\n\t\t\t// currently, this is always 1 = uncompressed\n\t\t\t$encoding = $headerinfo[\"encoding\"];\n\n\t\t\t// initialize finished writing current $string\n\t\t\t$finished = false;\n\n\t\t\twhile ($finished === false) {\n\n\t\t\t\t// normally, there will be only one cycle, but if string cannot immediately be written as is\n\t\t\t\t// there will be need for more than one cylcle, if string longer than one record data block, there\n\t\t\t\t// may be need for even more cycles\n\n\t\t\t\tif (strlen($recordData) + strlen($string) <= $continue_limit) {\n\t\t\t\t\t// then we can write the string (or remainder of string) without any problems\n\t\t\t\t\t$recordData .= $string;\n\n\t\t\t\t\tif (strlen($recordData) + strlen($string) == $continue_limit) {\n\t\t\t\t\t\t// we close the record data block, and initialize a new one\n\t\t\t\t\t\t$recordDatas[] = $recordData;\n\t\t\t\t\t\t$recordData = '';\n\t\t\t\t\t}\n\n\t\t\t\t\t// we are finished writing this string\n\t\t\t\t\t$finished = true;\n\t\t\t\t} else {\n\t\t\t\t\t// special treatment writing the string (or remainder of the string)\n\t\t\t\t\t// If the string is very long it may need to be written in more than one CONTINUE record.\n\n\t\t\t\t\t// check how many bytes more there is room for in the current record\n\t\t\t\t\t$space_remaining = $continue_limit - strlen($recordData);\n\n\t\t\t\t\t// minimum space needed\n\t\t\t\t\t// uncompressed: 2 byte string length length field + 1 byte option flags + 2 byte character\n\t\t\t\t\t// compressed:   2 byte string length length field + 1 byte option flags + 1 byte character\n\t\t\t\t\t$min_space_needed = ($encoding == 1) ? 5 : 4;\n\n\t\t\t\t\t// We have two cases\n\t\t\t\t\t// 1. space remaining is less than minimum space needed\n\t\t\t\t\t//\t\there we must waste the space remaining and move to next record data block\n\t\t\t\t\t// 2. space remaining is greater than or equal to minimum space needed\n\t\t\t\t\t//\t\there we write as much as we can in the current block, then move to next record data block\n\n\t\t\t\t\t// 1. space remaining is less than minimum space needed\n\t\t\t\t\tif ($space_remaining < $min_space_needed) {\n\t\t\t\t\t\t// we close the block, store the block data\n\t\t\t\t\t\t$recordDatas[] = $recordData;\n\n\t\t\t\t\t\t// and start new record data block where we start writing the string\n\t\t\t\t\t\t$recordData = '';\n\n\t\t\t\t\t// 2. space remaining is greater than or equal to minimum space needed\n\t\t\t\t\t} else {\n\t\t\t\t\t\t// initialize effective remaining space, for Unicode strings this may need to be reduced by 1, see below\n\t\t\t\t\t\t$effective_space_remaining = $space_remaining;\n\n\t\t\t\t\t\t// for uncompressed strings, sometimes effective space remaining is reduced by 1\n\t\t\t\t\t\tif ( $encoding == 1 && (strlen($string) - $space_remaining) % 2 == 1 ) {\n\t\t\t\t\t\t\t--$effective_space_remaining;\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\t// one block fininshed, store the block data\n\t\t\t\t\t\t$recordData .= substr($string, 0, $effective_space_remaining);\n\n\t\t\t\t\t\t$string = substr($string, $effective_space_remaining); // for next cycle in while loop\n\t\t\t\t\t\t$recordDatas[] = $recordData;\n\n\t\t\t\t\t\t// start new record data block with the repeated option flags\n\t\t\t\t\t\t$recordData = pack('C', $encoding);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Store the last record data block unless it is empty\n\t\t// if there was no need for any continue records, this will be the for SST record data block itself\n\t\tif (strlen($recordData) > 0) {\n\t\t\t$recordDatas[] = $recordData;\n\t\t}\n\n\t\t// combine into one chunk with all the blocks SST, CONTINUE,...\n\t\t$chunk = '';\n\t\tforeach ($recordDatas as $i => $recordData) {\n\t\t\t// first block should have the SST record header, remaing should have CONTINUE header\n\t\t\t$record = ($i == 0) ? 0x00FC : 0x003C;\n\n\t\t\t$header = pack(\"vv\", $record, strlen($recordData));\n\t\t\t$data = $header . $recordData;\n\n\t\t\t$chunk .= $this->writeData($data);\n\t\t}\n\n\t\treturn $chunk;\n\t}\n\n\t/**\n\t * Writes the MSODRAWINGGROUP record if needed. Possibly split using CONTINUE records.\n\t */\n\tprivate function _writeMsoDrawingGroup()\n\t{\n\t\t// write the Escher stream if necessary\n\t\tif (isset($this->_escher)) {\n\t\t\t$writer = new PHPExcel_Writer_Excel5_Escher($this->_escher);\n\t\t\t$data = $writer->close();\n\n\t\t\t$record = 0x00EB;\n\t\t\t$length = strlen($data);\n\t\t\t$header = pack(\"vv\",  $record, $length);\n\n\t\t\treturn $this->writeData($header . $data);\n\n\t\t} else {\n\t\t\treturn '';\n\t\t}\n\t}\n\n\t/**\n\t * Get Escher object\n\t *\n\t * @return PHPExcel_Shared_Escher\n\t */\n\tpublic function getEscher()\n\t{\n\t\treturn $this->_escher;\n\t}\n\n\t/**\n\t * Set Escher object\n\t *\n\t * @param PHPExcel_Shared_Escher $pValue\n\t */\n\tpublic function setEscher(PHPExcel_Shared_Escher $pValue = null)\n\t{\n\t\t$this->_escher = $pValue;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5/Worksheet.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n// Original file header of PEAR::Spreadsheet_Excel_Writer_Worksheet (used as the base for this class):\n// -----------------------------------------------------------------------------------------\n// /*\n// *  Module written/ported by Xavier Noguer <xnoguer@rezebra.com>\n// *\n// *  The majority of this is _NOT_ my code.  I simply ported it from the\n// *  PERL Spreadsheet::WriteExcel module.\n// *\n// *  The author of the Spreadsheet::WriteExcel module is John McNamara\n// *  <jmcnamara@cpan.org>\n// *\n// *  I _DO_ maintain this code, and John McNamara has nothing to do with the\n// *  porting of this code to PHP.  Any questions directly related to this\n// *  class library should be directed to me.\n// *\n// *  License Information:\n// *\n// *    Spreadsheet_Excel_Writer:  A library for generating Excel Spreadsheets\n// *    Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com\n// *\n// *    This library is free software; you can redistribute it and/or\n// *    modify it under the terms of the GNU Lesser General Public\n// *    License as published by the Free Software Foundation; either\n// *    version 2.1 of the License, or (at your option) any later version.\n// *\n// *    This library is distributed in the hope that it will be useful,\n// *    but WITHOUT ANY WARRANTY; without even the implied warranty of\n// *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n// *    Lesser General Public License for more details.\n// *\n// *    You should have received a copy of the GNU Lesser General Public\n// *    License along with this library; if not, write to the Free Software\n// *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n// */\n\n\n/**\n * PHPExcel_Writer_Excel5_Worksheet\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel5_Worksheet extends PHPExcel_Writer_Excel5_BIFFwriter\n{\n\t/**\n\t * Formula parser\n\t *\n\t * @var PHPExcel_Writer_Excel5_Parser\n\t */\n\tprivate $_parser;\n\n\t/**\n\t * Maximum number of characters for a string (LABEL record in BIFF5)\n\t * @var integer\n\t */\n\tpublic $_xls_strmax;\n\n\t/**\n\t * Array containing format information for columns\n\t * @var array\n\t */\n\tpublic $_colinfo;\n\n\t/**\n\t * Array containing the selected area for the worksheet\n\t * @var array\n\t */\n\tpublic $_selection;\n\n\t/**\n\t * The active pane for the worksheet\n\t * @var integer\n\t */\n\tpublic $_active_pane;\n\n\t/**\n\t * Whether to use outline.\n\t * @var integer\n\t */\n\tpublic $_outline_on;\n\n\t/**\n\t * Auto outline styles.\n\t * @var bool\n\t */\n\tpublic $_outline_style;\n\n\t/**\n\t * Whether to have outline summary below.\n\t * @var bool\n\t */\n\tpublic $_outline_below;\n\n\t/**\n\t * Whether to have outline summary at the right.\n\t * @var bool\n\t */\n\tpublic $_outline_right;\n\n\t/**\n\t * Reference to the total number of strings in the workbook\n\t * @var integer\n\t */\n\tpublic $_str_total;\n\n\t/**\n\t * Reference to the number of unique strings in the workbook\n\t * @var integer\n\t */\n\tpublic $_str_unique;\n\n\t/**\n\t * Reference to the array containing all the unique strings in the workbook\n\t * @var array\n\t */\n\tpublic $_str_table;\n\n\t/**\n\t * Color cache\n\t */\n\tprivate $_colors;\n\n\t/**\n\t * Index of first used row (at least 0)\n\t * @var int\n\t */\n\tprivate $_firstRowIndex;\n\n\t/**\n\t * Index of last used row. (no used rows means -1)\n\t * @var int\n\t */\n\tprivate $_lastRowIndex;\n\n\t/**\n\t * Index of first used column (at least 0)\n\t * @var int\n\t */\n\tprivate $_firstColumnIndex;\n\n\t/**\n\t * Index of last used column (no used columns means -1)\n\t * @var int\n\t */\n\tprivate $_lastColumnIndex;\n\n\t/**\n\t * Sheet object\n\t * @var PHPExcel_Worksheet\n\t */\n\tpublic $_phpSheet;\n\n\t/**\n\t * Count cell style Xfs\n\t *\n\t * @var int\n\t */\n\tprivate $_countCellStyleXfs;\n\n\t/**\n\t * Escher object corresponding to MSODRAWING\n\t *\n\t * @var PHPExcel_Shared_Escher\n\t */\n\tprivate $_escher;\n\n\t/**\n\t * Array of font hashes associated to FONT records index\n\t *\n\t * @var array\n\t */\n\tpublic $_fntHashIndex;\n\n\t/**\n\t * Constructor\n\t *\n\t * @param int\t\t&$str_total\t\tTotal number of strings\n\t * @param int\t\t&$str_unique\tTotal number of unique strings\n\t * @param array\t\t&$str_table\t\tString Table\n\t * @param array\t\t&$colors\t\tColour Table\n\t * @param mixed\t\t$parser\t\t\tThe formula parser created for the Workbook\n\t * @param boolean\t$preCalculateFormulas\tFlag indicating whether formulas should be calculated or just written\n\t * @param string\t$phpSheet\t\tThe worksheet to write\n\t * @param PHPExcel_Worksheet $phpSheet\n\t */\n\tpublic function __construct(&$str_total, &$str_unique, &$str_table, &$colors,\n\t\t\t\t\t\t\t\t$parser, $preCalculateFormulas, $phpSheet)\n\t{\n\t\t// It needs to call its parent's constructor explicitly\n\t\tparent::__construct();\n\n\t\t// change BIFFwriter limit for CONTINUE records\n//\t\t$this->_limit = 8224;\n\n\n\t\t$this->_preCalculateFormulas = $preCalculateFormulas;\n\t\t$this->_str_total\t\t= &$str_total;\n\t\t$this->_str_unique\t\t= &$str_unique;\n\t\t$this->_str_table\t\t= &$str_table;\n\t\t$this->_colors\t\t\t= &$colors;\n\t\t$this->_parser\t\t\t= $parser;\n\n\t\t$this->_phpSheet = $phpSheet;\n\n\t\t//$this->ext_sheets\t\t= array();\n\t\t//$this->offset\t\t\t= 0;\n\t\t$this->_xls_strmax\t\t= 255;\n\t\t$this->_colinfo\t\t\t= array();\n\t\t$this->_selection\t\t= array(0,0,0,0);\n\t\t$this->_active_pane\t\t= 3;\n\n\t\t$this->_print_headers\t\t= 0;\n\n\t\t$this->_outline_style\t\t= 0;\n\t\t$this->_outline_below\t\t= 1;\n\t\t$this->_outline_right\t\t= 1;\n\t\t$this->_outline_on\t\t\t= 1;\n\n\t\t$this->_fntHashIndex\t= array();\n\n\t\t// calculate values for DIMENSIONS record\n\t\t$minR = 1;\n\t\t$minC = 'A';\n\n\t\t$maxR  = $this->_phpSheet->getHighestRow();\n\t\t$maxC = $this->_phpSheet->getHighestColumn();\n\n\t\t// Determine lowest and highest column and row\n//\t\t$this->_firstRowIndex = ($minR > 65535) ? 65535 : $minR;\n\t\t$this->_lastRowIndex = ($maxR > 65535) ? 65535 : $maxR ;\n\n\t\t$this->_firstColumnIndex\t= PHPExcel_Cell::columnIndexFromString($minC);\n\t\t$this->_lastColumnIndex\t\t= PHPExcel_Cell::columnIndexFromString($maxC);\n\n//\t\tif ($this->_firstColumnIndex > 255) $this->_firstColumnIndex = 255;\n\t\tif ($this->_lastColumnIndex > 255) $this->_lastColumnIndex = 255;\n\n\t\t$this->_countCellStyleXfs = count($phpSheet->getParent()->getCellStyleXfCollection());\n\t}\n\n\t/**\n\t * Add data to the beginning of the workbook (note the reverse order)\n\t * and to the end of the workbook.\n\t *\n\t * @access public\n\t * @see PHPExcel_Writer_Excel5_Workbook::storeWorkbook()\n\t */\n\tfunction close()\n\t{\n\t\t$_phpSheet = $this->_phpSheet;\n\n\t\t$num_sheets = $_phpSheet->getParent()->getSheetCount();\n\n\t\t// Write BOF record\n\t\t$this->_storeBof(0x0010);\n\n\t\t// Write PRINTHEADERS\n\t\t$this->_writePrintHeaders();\n\n\t\t// Write PRINTGRIDLINES\n\t\t$this->_writePrintGridlines();\n\n\t\t// Write GRIDSET\n\t\t$this->_writeGridset();\n\n\t\t// Calculate column widths\n\t\t$_phpSheet->calculateColumnWidths();\n\n\t\t// Column dimensions\n\t\tif (($defaultWidth = $_phpSheet->getDefaultColumnDimension()->getWidth()) < 0) {\n\t\t\t$defaultWidth = PHPExcel_Shared_Font::getDefaultColumnWidthByFont($_phpSheet->getParent()->getDefaultStyle()->getFont());\n\t\t}\n\n\t\t$columnDimensions = $_phpSheet->getColumnDimensions();\n\t\t$maxCol = $this->_lastColumnIndex -1;\n\t\tfor ($i = 0; $i <= $maxCol; ++$i) {\n\t\t\t$hidden = 0;\n\t\t\t$level = 0;\n\t\t\t$xfIndex = 15; // there are 15 cell style Xfs\n\n\t\t\t$width = $defaultWidth;\n\n\t\t\t$columnLetter = PHPExcel_Cell::stringFromColumnIndex($i);\n\t\t\tif (isset($columnDimensions[$columnLetter])) {\n\t\t\t\t$columnDimension = $columnDimensions[$columnLetter];\n\t\t\t\tif ($columnDimension->getWidth() >= 0) {\n\t\t\t\t\t$width = $columnDimension->getWidth();\n\t\t\t\t}\n\t\t\t\t$hidden = $columnDimension->getVisible() ? 0 : 1;\n\t\t\t\t$level = $columnDimension->getOutlineLevel();\n\t\t\t\t$xfIndex = $columnDimension->getXfIndex() + 15; // there are 15 cell style Xfs\n\t\t\t}\n\n\t\t\t// Components of _colinfo:\n\t\t\t// $firstcol first column on the range\n\t\t\t// $lastcol  last column on the range\n\t\t\t// $width\twidth to set\n\t\t\t// $xfIndex  The optional cell style Xf index to apply to the columns\n\t\t\t// $hidden   The optional hidden atribute\n\t\t\t// $level\tThe optional outline level\n\t\t\t$this->_colinfo[] = array($i, $i, $width, $xfIndex, $hidden, $level);\n\t\t}\n\n\t\t// Write GUTS\n\t\t$this->_writeGuts();\n\n\t\t// Write DEFAULTROWHEIGHT\n\t\t$this->_writeDefaultRowHeight();\n\n\t\t// Write WSBOOL\n\t\t$this->_writeWsbool();\n\n\t\t// Write horizontal and vertical page breaks\n\t\t$this->_writeBreaks();\n\n\t\t// Write page header\n\t\t$this->_writeHeader();\n\n\t\t// Write page footer\n\t\t$this->_writeFooter();\n\n\t\t// Write page horizontal centering\n\t\t$this->_writeHcenter();\n\n\t\t// Write page vertical centering\n\t\t$this->_writeVcenter();\n\n\t\t// Write left margin\n\t\t$this->_writeMarginLeft();\n\n\t\t// Write right margin\n\t\t$this->_writeMarginRight();\n\n\t\t// Write top margin\n\t\t$this->_writeMarginTop();\n\n\t\t// Write bottom margin\n\t\t$this->_writeMarginBottom();\n\n\t\t// Write page setup\n\t\t$this->_writeSetup();\n\n\t\t// Write sheet protection\n\t\t$this->_writeProtect();\n\n\t\t// Write SCENPROTECT\n\t\t$this->_writeScenProtect();\n\n\t\t// Write OBJECTPROTECT\n\t\t$this->_writeObjectProtect();\n\n\t\t// Write sheet password\n\t\t$this->_writePassword();\n\n\t\t// Write DEFCOLWIDTH record\n\t\t$this->_writeDefcol();\n\n\t\t// Write the COLINFO records if they exist\n\t\tif (!empty($this->_colinfo)) {\n\t\t\t$colcount = count($this->_colinfo);\n\t\t\tfor ($i = 0; $i < $colcount; ++$i) {\n\t\t\t\t$this->_writeColinfo($this->_colinfo[$i]);\n\t\t\t}\n\t\t}\n\t\t$autoFilterRange = $_phpSheet->getAutoFilter()->getRange();\n\t\tif (!empty($autoFilterRange)) {\n\t\t\t// Write AUTOFILTERINFO\n\t\t\t$this->_writeAutoFilterInfo();\n\t\t}\n\n\t\t// Write sheet dimensions\n\t\t$this->_writeDimensions();\n\n\t\t// Row dimensions\n\t\tforeach ($_phpSheet->getRowDimensions() as $rowDimension) {\n\t\t\t$xfIndex = $rowDimension->getXfIndex() + 15; // there are 15 cellXfs\n\t\t\t$this->_writeRow( $rowDimension->getRowIndex() - 1, $rowDimension->getRowHeight(), $xfIndex, ($rowDimension->getVisible() ? '0' : '1'), $rowDimension->getOutlineLevel() );\n\t\t}\n\n\t\t// Write Cells\n\t\tforeach ($_phpSheet->getCellCollection() as $cellID) {\n\t\t\t$cell = $_phpSheet->getCell($cellID);\n\t\t\t$row = $cell->getRow() - 1;\n\t\t\t$column = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1;\n\n\t\t\t// Don't break Excel!\n//\t\t\tif ($row + 1 > 65536 or $column + 1 > 256) {\n\t\t\tif ($row > 65535 || $column > 255) {\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\t// Write cell value\n\t\t\t$xfIndex = $cell->getXfIndex() + 15; // there are 15 cell style Xfs\n\n\t\t\t$cVal = $cell->getValue();\n\t\t\tif ($cVal instanceof PHPExcel_RichText) {\n\t\t\t\t// $this->_writeString($row, $column, $cVal->getPlainText(), $xfIndex);\n\t\t\t\t$arrcRun = array();\n\t\t\t\t$str_len = PHPExcel_Shared_String::CountCharacters($cVal->getPlainText(), 'UTF-8');\n\t\t\t\t$str_pos = 0;\n\t\t\t\t$elements = $cVal->getRichTextElements();\n\t\t\t\tforeach ($elements as $element) {\n\t\t\t\t\t// FONT Index\n\t\t\t\t\tif ($element instanceof PHPExcel_RichText_Run) {\n\t\t\t\t\t\t$str_fontidx = $this->_fntHashIndex[$element->getFont()->getHashCode()];\n\t\t\t\t\t}\n\t\t\t\t\telse {\n\t\t\t\t\t\t$str_fontidx = 0;\n\t\t\t\t\t}\n\t\t\t\t\t$arrcRun[] = array('strlen' => $str_pos, 'fontidx' => $str_fontidx);\n\t\t\t\t\t// Position FROM\n\t\t\t\t\t$str_pos += PHPExcel_Shared_String::CountCharacters($element->getText(), 'UTF-8');\n\t\t\t\t}\n\t\t\t\t$this->_writeRichTextString($row, $column, $cVal->getPlainText(), $xfIndex, $arrcRun);\n\t\t\t} else {\n\t\t\t\tswitch ($cell->getDatatype()) {\n\t\t\t\t\tcase PHPExcel_Cell_DataType::TYPE_STRING:\n\t\t\t\t\tcase PHPExcel_Cell_DataType::TYPE_NULL:\n\t\t\t\t\t\tif ($cVal === '' || $cVal === null) {\n\t\t\t\t\t\t\t$this->_writeBlank($row, $column, $xfIndex);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$this->_writeString($row, $column, $cVal, $xfIndex);\n\t\t\t\t\t\t}\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PHPExcel_Cell_DataType::TYPE_NUMERIC:\n\t\t\t\t\t\t$this->_writeNumber($row, $column, $cVal, $xfIndex);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PHPExcel_Cell_DataType::TYPE_FORMULA:\n\t\t\t\t\t\t$calculatedValue = $this->_preCalculateFormulas ?\n\t\t\t\t\t\t\t$cell->getCalculatedValue() : null;\n\t\t\t\t\t\t$this->_writeFormula($row, $column, $cVal, $xfIndex, $calculatedValue);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PHPExcel_Cell_DataType::TYPE_BOOL:\n\t\t\t\t\t\t$this->_writeBoolErr($row, $column, $cVal, 0, $xfIndex);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PHPExcel_Cell_DataType::TYPE_ERROR:\n\t\t\t\t\t\t$this->_writeBoolErr($row, $column, self::_mapErrorCode($cVal), 1, $xfIndex);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Append\n\t\t$this->_writeMsoDrawing();\n\n\t\t// Write WINDOW2 record\n\t\t$this->_writeWindow2();\n\n\t\t// Write PLV record\n\t\t$this->_writePageLayoutView();\n\n\t\t// Write ZOOM record\n\t\t$this->_writeZoom();\n\t\tif ($_phpSheet->getFreezePane()) {\n\t\t\t$this->_writePanes();\n\t\t}\n\n\t\t// Write SELECTION record\n\t\t$this->_writeSelection();\n\n\t\t// Write MergedCellsTable Record\n\t\t$this->_writeMergedCells();\n\n\t\t// Hyperlinks\n\t\tforeach ($_phpSheet->getHyperLinkCollection() as $coordinate => $hyperlink) {\n\t\t\tlist($column, $row) = PHPExcel_Cell::coordinateFromString($coordinate);\n\n\t\t\t$url = $hyperlink->getUrl();\n\n\t\t\tif ( strpos($url, 'sheet://') !== false ) {\n\t\t\t\t// internal to current workbook\n\t\t\t\t$url = str_replace('sheet://', 'internal:', $url);\n\n\t\t\t} else if ( preg_match('/^(http:|https:|ftp:|mailto:)/', $url) ) {\n\t\t\t\t// URL\n\t\t\t\t// $url = $url;\n\n\t\t\t} else {\n\t\t\t\t// external (local file)\n\t\t\t\t$url = 'external:' . $url;\n\t\t\t}\n\n\t\t\t$this->_writeUrl($row - 1, PHPExcel_Cell::columnIndexFromString($column) - 1, $url);\n\t\t}\n\n\t\t$this->_writeDataValidity();\n\t\t$this->_writeSheetLayout();\n\n\t\t// Write SHEETPROTECTION record\n\t\t$this->_writeSheetProtection();\n\t\t$this->_writeRangeProtection();\n\n\t\t$arrConditionalStyles = $_phpSheet->getConditionalStylesCollection();\n\t\tif(!empty($arrConditionalStyles)){\n\t\t\t$arrConditional = array();\n\t\t\t// @todo CFRule & CFHeader\n\t\t\t// Write CFHEADER record\n\t\t\t$this->_writeCFHeader();\n\t\t\t// Write ConditionalFormattingTable records\n\t\t\tforeach ($arrConditionalStyles as $cellCoordinate => $conditionalStyles) {\n\t\t\t\tforeach ($conditionalStyles as $conditional) {\n\t\t\t\t\tif($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION\n\t\t\t\t\t\t|| $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){\n\t\t\t\t\t\tif(!in_array($conditional->getHashCode(), $arrConditional)){\n\t\t\t\t\t\t\t$arrConditional[] = $conditional->getHashCode();\n\t\t\t\t\t\t\t// Write CFRULE record\n\t\t\t\t\t\t\t$this->_writeCFRule($conditional);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t$this->_storeEof();\n\t}\n\n\t/**\n\t * Write a cell range address in BIFF8\n\t * always fixed range\n\t * See section 2.5.14 in OpenOffice.org's Documentation of the Microsoft Excel File Format\n\t *\n\t * @param string $range E.g. 'A1' or 'A1:B6'\n\t * @return string Binary data\n\t */\n\tprivate function _writeBIFF8CellRangeAddressFixed($range = 'A1')\n\t{\n\t\t$explodes = explode(':', $range);\n\n\t\t// extract first cell, e.g. 'A1'\n\t\t$firstCell = $explodes[0];\n\n\t\t// extract last cell, e.g. 'B6'\n\t\tif (count($explodes) == 1) {\n\t\t\t$lastCell = $firstCell;\n\t\t} else {\n\t\t\t$lastCell = $explodes[1];\n\t\t}\n\n\t\t$firstCellCoordinates = PHPExcel_Cell::coordinateFromString($firstCell); // e.g. array(0, 1)\n\t\t$lastCellCoordinates  = PHPExcel_Cell::coordinateFromString($lastCell);  // e.g. array(1, 6)\n\n\t\treturn(pack('vvvv',\n\t\t\t$firstCellCoordinates[1] - 1,\n\t\t\t$lastCellCoordinates[1] - 1,\n\t\t\tPHPExcel_Cell::columnIndexFromString($firstCellCoordinates[0]) - 1,\n\t\t\tPHPExcel_Cell::columnIndexFromString($lastCellCoordinates[0]) - 1\n\t\t));\n\t}\n\n\t/**\n\t * Retrieves data from memory in one chunk, or from disk in $buffer\n\t * sized chunks.\n\t *\n\t * @return string The data\n\t */\n\tfunction getData()\n\t{\n\t\t$buffer = 4096;\n\n\t\t// Return data stored in memory\n\t\tif (isset($this->_data)) {\n\t\t\t$tmp   = $this->_data;\n\t\t\tunset($this->_data);\n\t\t\treturn $tmp;\n\t\t}\n\t\t// No data to return\n\t\treturn false;\n\t}\n\n\t/**\n\t * Set the option to print the row and column headers on the printed page.\n\t *\n\t * @access public\n\t * @param integer $print Whether to print the headers or not. Defaults to 1 (print).\n\t */\n\tfunction printRowColHeaders($print = 1)\n\t{\n\t\t$this->_print_headers = $print;\n\t}\n\n\t/**\n\t * This method sets the properties for outlining and grouping. The defaults\n\t * correspond to Excel's defaults.\n\t *\n\t * @param bool $visible\n\t * @param bool $symbols_below\n\t * @param bool $symbols_right\n\t * @param bool $auto_style\n\t */\n\tfunction setOutline($visible = true, $symbols_below = true, $symbols_right = true, $auto_style = false)\n\t{\n\t\t$this->_outline_on\t= $visible;\n\t\t$this->_outline_below = $symbols_below;\n\t\t$this->_outline_right = $symbols_right;\n\t\t$this->_outline_style = $auto_style;\n\n\t\t// Ensure this is a boolean vale for Window2\n\t\tif ($this->_outline_on) {\n\t\t\t$this->_outline_on = 1;\n\t\t}\n\t }\n\n\t/**\n\t * Write a double to the specified row and column (zero indexed).\n\t * An integer can be written as a double. Excel will display an\n\t * integer. $format is optional.\n\t *\n\t * Returns  0 : normal termination\n\t *\t\t -2 : row or column out of range\n\t *\n\t * @param integer $row\tZero indexed row\n\t * @param integer $col\tZero indexed column\n\t * @param float   $num\tThe number to write\n\t * @param mixed   $xfIndex The optional XF format\n\t * @return integer\n\t */\n\tprivate function _writeNumber($row, $col, $num, $xfIndex)\n\t{\n\t\t$record\t= 0x0203;\t\t\t\t // Record identifier\n\t\t$length\t= 0x000E;\t\t\t\t // Number of bytes to follow\n\n\t\t$header\t\t= pack(\"vv\",  $record, $length);\n\t\t$data\t\t= pack(\"vvv\", $row, $col, $xfIndex);\n\t\t$xl_double\t= pack(\"d\",   $num);\n\t\tif (self::getByteOrder()) { // if it's Big Endian\n\t\t\t$xl_double = strrev($xl_double);\n\t\t}\n\n\t\t$this->_append($header.$data.$xl_double);\n\t\treturn(0);\n\t}\n\n\t/**\n\t * Write a LABELSST record or a LABEL record. Which one depends on BIFF version\n\t *\n\t * @param int $row Row index (0-based)\n\t * @param int $col Column index (0-based)\n\t * @param string $str The string\n\t * @param int $xfIndex Index to XF record\n\t */\n\tprivate function _writeString($row, $col, $str, $xfIndex)\n\t{\n\t\t$this->_writeLabelSst($row, $col, $str, $xfIndex);\n\t}\n\n\t/**\n\t * Write a LABELSST record or a LABEL record. Which one depends on BIFF version\n\t * It differs from _writeString by the writing of rich text strings.\n\t * @param int $row Row index (0-based)\n\t * @param int $col Column index (0-based)\n\t * @param string $str The string\n\t * @param mixed   $xfIndex The XF format index for the cell\n\t * @param array $arrcRun Index to Font record and characters beginning\n\t */\n\tprivate function _writeRichTextString($row, $col, $str, $xfIndex, $arrcRun){\n\t\t$record\t= 0x00FD;\t\t\t\t   // Record identifier\n\t\t$length\t= 0x000A;\t\t\t\t   // Bytes to follow\n\t\t$str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeShort($str, $arrcRun);\n\n\t\t/* check if string is already present */\n\t\tif (!isset($this->_str_table[$str])) {\n\t\t\t$this->_str_table[$str] = $this->_str_unique++;\n\t\t}\n\t\t$this->_str_total++;\n\n\t\t$header\t= pack('vv',   $record, $length);\n\t\t$data\t= pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]);\n\t\t$this->_append($header.$data);\n\t}\n\n\t/**\n\t * Write a string to the specified row and column (zero indexed).\n\t * NOTE: there is an Excel 5 defined limit of 255 characters.\n\t * $format is optional.\n\t * Returns  0 : normal termination\n\t *\t\t -2 : row or column out of range\n\t *\t\t -3 : long string truncated to 255 chars\n\t *\n\t * @access public\n\t * @param integer $row\tZero indexed row\n\t * @param integer $col\tZero indexed column\n\t * @param string  $str\tThe string to write\n\t * @param mixed   $xfIndex The XF format index for the cell\n\t * @return integer\n\t */\n\tprivate function _writeLabel($row, $col, $str, $xfIndex)\n\t{\n\t\t$strlen\t= strlen($str);\n\t\t$record\t= 0x0204;\t\t\t\t   // Record identifier\n\t\t$length\t= 0x0008 + $strlen;\t\t // Bytes to follow\n\n\t\t$str_error = 0;\n\n\t\tif ($strlen > $this->_xls_strmax) { // LABEL must be < 255 chars\n\t\t\t$str\t= substr($str, 0, $this->_xls_strmax);\n\t\t\t$length\t= 0x0008 + $this->_xls_strmax;\n\t\t\t$strlen\t= $this->_xls_strmax;\n\t\t\t$str_error = -3;\n\t\t}\n\n\t\t$header\t= pack(\"vv\",   $record, $length);\n\t\t$data\t= pack(\"vvvv\", $row, $col, $xfIndex, $strlen);\n\t\t$this->_append($header . $data . $str);\n\t\treturn($str_error);\n\t}\n\n\t/**\n\t * Write a string to the specified row and column (zero indexed).\n\t * This is the BIFF8 version (no 255 chars limit).\n\t * $format is optional.\n\t * Returns  0 : normal termination\n\t *\t\t -2 : row or column out of range\n\t *\t\t -3 : long string truncated to 255 chars\n\t *\n\t * @access public\n\t * @param integer $row\tZero indexed row\n\t * @param integer $col\tZero indexed column\n\t * @param string  $str\tThe string to write\n\t * @param mixed   $xfIndex The XF format index for the cell\n\t * @return integer\n\t */\n\tprivate function _writeLabelSst($row, $col, $str, $xfIndex)\n\t{\n\t\t$record\t= 0x00FD;\t\t\t\t   // Record identifier\n\t\t$length\t= 0x000A;\t\t\t\t   // Bytes to follow\n\n\t\t$str = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($str);\n\n\t\t/* check if string is already present */\n\t\tif (!isset($this->_str_table[$str])) {\n\t\t\t$this->_str_table[$str] = $this->_str_unique++;\n\t\t}\n\t\t$this->_str_total++;\n\n\t\t$header\t= pack('vv',   $record, $length);\n\t\t$data\t= pack('vvvV', $row, $col, $xfIndex, $this->_str_table[$str]);\n\t\t$this->_append($header.$data);\n\t}\n\n\t/**\n\t * Writes a note associated with the cell given by the row and column.\n\t * NOTE records don't have a length limit.\n\t *\n\t * @param integer $row\tZero indexed row\n\t * @param integer $col\tZero indexed column\n\t * @param string  $note   The note to write\n\t */\n\tprivate function _writeNote($row, $col, $note)\n\t{\n\t\t$note_length\t= strlen($note);\n\t\t$record\t\t\t= 0x001C;\t\t\t// Record identifier\n\t\t$max_length\t\t= 2048;\t\t\t\t// Maximun length for a NOTE record\n\n\t\t// Length for this record is no more than 2048 + 6\n\t\t$length\t= 0x0006 + min($note_length, 2048);\n\t\t$header\t= pack(\"vv\",   $record, $length);\n\t\t$data\t= pack(\"vvv\", $row, $col, $note_length);\n\t\t$this->_append($header . $data . substr($note, 0, 2048));\n\n\t\tfor ($i = $max_length; $i < $note_length; $i += $max_length) {\n\t\t\t$chunk  = substr($note, $i, $max_length);\n\t\t\t$length = 0x0006 + strlen($chunk);\n\t\t\t$header = pack(\"vv\",   $record, $length);\n\t\t\t$data   = pack(\"vvv\", -1, 0, strlen($chunk));\n\t\t\t$this->_append($header.$data.$chunk);\n\t\t}\n\t\treturn(0);\n\t}\n\n\t/**\n\t * Write a blank cell to the specified row and column (zero indexed).\n\t * A blank cell is used to specify formatting without adding a string\n\t * or a number.\n\t *\n\t * A blank cell without a format serves no purpose. Therefore, we don't write\n\t * a BLANK record unless a format is specified.\n\t *\n\t * Returns  0 : normal termination (including no format)\n\t *\t\t -1 : insufficient number of arguments\n\t *\t\t -2 : row or column out of range\n\t *\n\t * @param integer $row\tZero indexed row\n\t * @param integer $col\tZero indexed column\n\t * @param mixed   $xfIndex The XF format index\n\t */\n\tfunction _writeBlank($row, $col, $xfIndex)\n\t{\n\t\t$record\t= 0x0201;\t\t\t\t // Record identifier\n\t\t$length\t= 0x0006;\t\t\t\t // Number of bytes to follow\n\n\t\t$header\t= pack(\"vv\",  $record, $length);\n\t\t$data\t  = pack(\"vvv\", $row, $col, $xfIndex);\n\t\t$this->_append($header . $data);\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Write a boolean or an error type to the specified row and column (zero indexed)\n\t *\n\t * @param int $row Row index (0-based)\n\t * @param int $col Column index (0-based)\n\t * @param int $value\n\t * @param boolean $isError Error or Boolean?\n\t * @param int $xfIndex\n\t */\n\tprivate function _writeBoolErr($row, $col, $value, $isError, $xfIndex)\n\t{\n\t\t$record = 0x0205;\n\t\t$length = 8;\n\n\t\t$header\t= pack(\"vv\",  $record, $length);\n\t\t$data\t  = pack(\"vvvCC\", $row, $col, $xfIndex, $value, $isError);\n\t\t$this->_append($header . $data);\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Write a formula to the specified row and column (zero indexed).\n\t * The textual representation of the formula is passed to the parser in\n\t * Parser.php which returns a packed binary string.\n\t *\n\t * Returns  0 : normal termination\n\t *\t\t -1 : formula errors (bad formula)\n\t *\t\t -2 : row or column out of range\n\t *\n\t * @param integer $row\t Zero indexed row\n\t * @param integer $col\t Zero indexed column\n\t * @param string  $formula The formula text string\n\t * @param mixed   $xfIndex  The XF format index\n\t * @param mixed   $calculatedValue  Calculated value\n\t * @return integer\n\t */\n\tprivate function _writeFormula($row, $col, $formula, $xfIndex, $calculatedValue)\n\t{\n\t\t$record\t= 0x0006;\t // Record identifier\n\n\t\t// Initialize possible additional value for STRING record that should be written after the FORMULA record?\n\t\t$stringValue = null;\n\n\t\t// calculated value\n\t\tif (isset($calculatedValue)) {\n\t\t\t// Since we can't yet get the data type of the calculated value,\n\t\t\t// we use best effort to determine data type\n\t\t\tif (is_bool($calculatedValue)) {\n\t\t\t\t// Boolean value\n\t\t\t\t$num = pack('CCCvCv', 0x01, 0x00, (int)$calculatedValue, 0x00, 0x00, 0xFFFF);\n\t\t\t} elseif (is_int($calculatedValue) || is_float($calculatedValue)) {\n\t\t\t\t// Numeric value\n\t\t\t\t$num = pack('d', $calculatedValue);\n\t\t\t} elseif (is_string($calculatedValue)) {\n\t\t\t\tif (array_key_exists($calculatedValue, PHPExcel_Cell_DataType::getErrorCodes())) {\n\t\t\t\t\t// Error value\n\t\t\t\t\t$num = pack('CCCvCv', 0x02, 0x00, self::_mapErrorCode($calculatedValue), 0x00, 0x00, 0xFFFF);\n\t\t\t\t} elseif ($calculatedValue === '') {\n\t\t\t\t\t// Empty string (and BIFF8)\n\t\t\t\t\t$num = pack('CCCvCv', 0x03, 0x00, 0x00, 0x00, 0x00, 0xFFFF);\n\t\t\t\t} else {\n\t\t\t\t\t// Non-empty string value (or empty string BIFF5)\n\t\t\t\t\t$stringValue = $calculatedValue;\n\t\t\t\t\t$num = pack('CCCvCv', 0x00, 0x00, 0x00, 0x00, 0x00, 0xFFFF);\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\t// We are really not supposed to reach here\n\t\t\t\t$num = pack('d', 0x00);\n\t\t\t}\n\t\t} else {\n\t\t\t$num = pack('d', 0x00);\n\t\t}\n\n\t\t$grbit\t\t= 0x03;\t\t\t\t// Option flags\n\t\t$unknown\t= 0x0000;\t\t\t// Must be zero\n\n\t\t// Strip the '=' or '@' sign at the beginning of the formula string\n\t\tif ($formula{0} == '=') {\n\t\t\t$formula = substr($formula,1);\n\t\t} else {\n\t\t\t// Error handling\n\t\t\t$this->_writeString($row, $col, 'Unrecognised character for formula');\n\t\t\treturn -1;\n\t\t}\n\n\t\t// Parse the formula using the parser in Parser.php\n\t\ttry {\n\t\t\t$error = $this->_parser->parse($formula);\n\t\t\t$formula = $this->_parser->toReversePolish();\n\n\t\t\t$formlen\t= strlen($formula);\t// Length of the binary string\n\t\t\t$length\t = 0x16 + $formlen;\t // Length of the record data\n\n\t\t\t$header\t= pack(\"vv\",\t  $record, $length);\n\n\t\t\t$data\t  = pack(\"vvv\", $row, $col, $xfIndex)\n\t\t\t\t\t\t. $num\n\t\t\t\t\t\t. pack(\"vVv\", $grbit, $unknown, $formlen);\n\t\t\t$this->_append($header . $data . $formula);\n\n\t\t\t// Append also a STRING record if necessary\n\t\t\tif ($stringValue !== null) {\n\t\t\t\t$this->_writeStringRecord($stringValue);\n\t\t\t}\n\n\t\t\treturn 0;\n\n\t\t} catch (PHPExcel_Exception $e) {\n\t\t\t// do nothing\n\t\t}\n\n\t}\n\n\t/**\n\t * Write a STRING record. This\n\t *\n\t * @param string $stringValue\n\t */\n\tprivate function _writeStringRecord($stringValue)\n\t{\n\t\t$record = 0x0207;\t // Record identifier\n\t\t$data = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($stringValue);\n\n\t\t$length = strlen($data);\n\t\t$header = pack('vv', $record, $length);\n\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write a hyperlink.\n\t * This is comprised of two elements: the visible label and\n\t * the invisible link. The visible label is the same as the link unless an\n\t * alternative string is specified. The label is written using the\n\t * _writeString() method. Therefore the 255 characters string limit applies.\n\t * $string and $format are optional.\n\t *\n\t * The hyperlink can be to a http, ftp, mail, internal sheet (not yet), or external\n\t * directory url.\n\t *\n\t * Returns  0 : normal termination\n\t *\t\t -2 : row or column out of range\n\t *\t\t -3 : long string truncated to 255 chars\n\t *\n\t * @param integer $row\tRow\n\t * @param integer $col\tColumn\n\t * @param string  $url\tURL string\n\t * @return integer\n\t */\n\tprivate function _writeUrl($row, $col, $url)\n\t{\n\t\t// Add start row and col to arg list\n\t\treturn($this->_writeUrlRange($row, $col, $row, $col, $url));\n\t}\n\n\t/**\n\t * This is the more general form of _writeUrl(). It allows a hyperlink to be\n\t * written to a range of cells. This function also decides the type of hyperlink\n\t * to be written. These are either, Web (http, ftp, mailto), Internal\n\t * (Sheet1!A1) or external ('c:\\temp\\foo.xls#Sheet1!A1').\n\t *\n\t * @access private\n\t * @see _writeUrl()\n\t * @param integer $row1   Start row\n\t * @param integer $col1   Start column\n\t * @param integer $row2   End row\n\t * @param integer $col2   End column\n\t * @param string  $url\tURL string\n\t * @return integer\n\t */\n\tfunction _writeUrlRange($row1, $col1, $row2, $col2, $url)\n\t{\n\t\t// Check for internal/external sheet links or default to web link\n\t\tif (preg_match('[^internal:]', $url)) {\n\t\t\treturn($this->_writeUrlInternal($row1, $col1, $row2, $col2, $url));\n\t\t}\n\t\tif (preg_match('[^external:]', $url)) {\n\t\t\treturn($this->_writeUrlExternal($row1, $col1, $row2, $col2, $url));\n\t\t}\n\t\treturn($this->_writeUrlWeb($row1, $col1, $row2, $col2, $url));\n\t}\n\n\t/**\n\t * Used to write http, ftp and mailto hyperlinks.\n\t * The link type ($options) is 0x03 is the same as absolute dir ref without\n\t * sheet. However it is differentiated by the $unknown2 data stream.\n\t *\n\t * @access private\n\t * @see _writeUrl()\n\t * @param integer $row1   Start row\n\t * @param integer $col1   Start column\n\t * @param integer $row2   End row\n\t * @param integer $col2   End column\n\t * @param string  $url\tURL string\n\t * @return integer\n\t */\n\tfunction _writeUrlWeb($row1, $col1, $row2, $col2, $url)\n\t{\n\t\t$record\t  = 0x01B8;\t\t\t\t\t   // Record identifier\n\t\t$length\t  = 0x00000;\t\t\t\t\t  // Bytes to follow\n\n\t\t// Pack the undocumented parts of the hyperlink stream\n\t\t$unknown1\t= pack(\"H*\", \"D0C9EA79F9BACE118C8200AA004BA90B02000000\");\n\t\t$unknown2\t= pack(\"H*\", \"E0C9EA79F9BACE118C8200AA004BA90B\");\n\n\t\t// Pack the option flags\n\t\t$options\t = pack(\"V\", 0x03);\n\n\t\t// Convert URL to a null terminated wchar string\n\t\t$url\t\t = join(\"\\0\", preg_split(\"''\", $url, -1, PREG_SPLIT_NO_EMPTY));\n\t\t$url\t\t = $url . \"\\0\\0\\0\";\n\n\t\t// Pack the length of the URL\n\t\t$url_len\t = pack(\"V\", strlen($url));\n\n\t\t// Calculate the data length\n\t\t$length\t  = 0x34 + strlen($url);\n\n\t\t// Pack the header data\n\t\t$header\t  = pack(\"vv\",   $record, $length);\n\t\t$data\t\t= pack(\"vvvv\", $row1, $row2, $col1, $col2);\n\n\t\t// Write the packed data\n\t\t$this->_append($header . $data .\n\t\t\t\t\t   $unknown1 . $options .\n\t\t\t\t\t   $unknown2 . $url_len . $url);\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Used to write internal reference hyperlinks such as \"Sheet1!A1\".\n\t *\n\t * @access private\n\t * @see _writeUrl()\n\t * @param integer $row1   Start row\n\t * @param integer $col1   Start column\n\t * @param integer $row2   End row\n\t * @param integer $col2   End column\n\t * @param string  $url\tURL string\n\t * @return integer\n\t */\n\tfunction _writeUrlInternal($row1, $col1, $row2, $col2, $url)\n\t{\n\t\t$record\t  = 0x01B8;\t\t\t\t\t   // Record identifier\n\t\t$length\t  = 0x00000;\t\t\t\t\t  // Bytes to follow\n\n\t\t// Strip URL type\n\t\t$url = preg_replace('/^internal:/', '', $url);\n\n\t\t// Pack the undocumented parts of the hyperlink stream\n\t\t$unknown1\t= pack(\"H*\", \"D0C9EA79F9BACE118C8200AA004BA90B02000000\");\n\n\t\t// Pack the option flags\n\t\t$options\t = pack(\"V\", 0x08);\n\n\t\t// Convert the URL type and to a null terminated wchar string\n\t\t$url .= \"\\0\";\n\n\t\t// character count\n\t\t$url_len = PHPExcel_Shared_String::CountCharacters($url);\n\t\t$url_len = pack('V', $url_len);\n\n\t\t$url = PHPExcel_Shared_String::ConvertEncoding($url, 'UTF-16LE', 'UTF-8');\n\n\t\t// Calculate the data length\n\t\t$length\t  = 0x24 + strlen($url);\n\n\t\t// Pack the header data\n\t\t$header\t  = pack(\"vv\",   $record, $length);\n\t\t$data\t\t= pack(\"vvvv\", $row1, $row2, $col1, $col2);\n\n\t\t// Write the packed data\n\t\t$this->_append($header . $data .\n\t\t\t\t\t   $unknown1 . $options .\n\t\t\t\t\t   $url_len . $url);\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Write links to external directory names such as 'c:\\foo.xls',\n\t * c:\\foo.xls#Sheet1!A1', '../../foo.xls'. and '../../foo.xls#Sheet1!A1'.\n\t *\n\t * Note: Excel writes some relative links with the $dir_long string. We ignore\n\t * these cases for the sake of simpler code.\n\t *\n\t * @access private\n\t * @see _writeUrl()\n\t * @param integer $row1   Start row\n\t * @param integer $col1   Start column\n\t * @param integer $row2   End row\n\t * @param integer $col2   End column\n\t * @param string  $url\tURL string\n\t * @return integer\n\t */\n\tfunction _writeUrlExternal($row1, $col1, $row2, $col2, $url)\n\t{\n\t\t// Network drives are different. We will handle them separately\n\t\t// MS/Novell network drives and shares start with \\\\\n\t\tif (preg_match('[^external:\\\\\\\\]', $url)) {\n\t\t\treturn; //($this->_writeUrlExternal_net($row1, $col1, $row2, $col2, $url, $str, $format));\n\t\t}\n\n\t\t$record\t  = 0x01B8;\t\t\t\t\t   // Record identifier\n\t\t$length\t  = 0x00000;\t\t\t\t\t  // Bytes to follow\n\n\t\t// Strip URL type and change Unix dir separator to Dos style (if needed)\n\t\t//\n\t\t$url = preg_replace('/^external:/', '', $url);\n\t\t$url = preg_replace('/\\//', \"\\\\\", $url);\n\n\t\t// Determine if the link is relative or absolute:\n\t\t//   relative if link contains no dir separator, \"somefile.xls\"\n\t\t//   relative if link starts with up-dir, \"..\\..\\somefile.xls\"\n\t\t//   otherwise, absolute\n\n\t\t$absolute = 0x00; // relative path\n\t\tif ( preg_match('/^[A-Z]:/', $url) ) {\n\t\t\t$absolute = 0x02; // absolute path on Windows, e.g. C:\\...\n\t\t}\n\t\t$link_type\t\t\t   = 0x01 | $absolute;\n\n\t\t// Determine if the link contains a sheet reference and change some of the\n\t\t// parameters accordingly.\n\t\t// Split the dir name and sheet name (if it exists)\n\t\t$dir_long = $url;\n\t\tif (preg_match(\"/\\#/\", $url)) {\n\t\t\t$link_type |= 0x08;\n\t\t}\n\n\n\t\t// Pack the link type\n\t\t$link_type   = pack(\"V\", $link_type);\n\n\t\t// Calculate the up-level dir count e.g.. (..\\..\\..\\ == 3)\n\t\t$up_count\t= preg_match_all(\"/\\.\\.\\\\\\/\", $dir_long, $useless);\n\t\t$up_count\t= pack(\"v\", $up_count);\n\n\t\t// Store the short dos dir name (null terminated)\n\t\t$dir_short   = preg_replace(\"/\\.\\.\\\\\\/\", '', $dir_long) . \"\\0\";\n\n\t\t// Store the long dir name as a wchar string (non-null terminated)\n\t\t$dir_long\t   = $dir_long . \"\\0\";\n\n\t\t// Pack the lengths of the dir strings\n\t\t$dir_short_len = pack(\"V\", strlen($dir_short)\t  );\n\t\t$dir_long_len  = pack(\"V\", strlen($dir_long)\t   );\n\t\t$stream_len\t= pack(\"V\", 0);//strlen($dir_long) + 0x06);\n\n\t\t// Pack the undocumented parts of the hyperlink stream\n\t\t$unknown1 = pack(\"H*\",'D0C9EA79F9BACE118C8200AA004BA90B02000000'\t   );\n\t\t$unknown2 = pack(\"H*\",'0303000000000000C000000000000046'\t\t\t   );\n\t\t$unknown3 = pack(\"H*\",'FFFFADDE000000000000000000000000000000000000000');\n\t\t$unknown4 = pack(\"v\",  0x03\t\t\t\t\t\t\t\t\t\t\t);\n\n\t\t// Pack the main data stream\n\t\t$data\t\t= pack(\"vvvv\", $row1, $row2, $col1, $col2) .\n\t\t\t\t\t\t  $unknown1\t .\n\t\t\t\t\t\t  $link_type\t.\n\t\t\t\t\t\t  $unknown2\t .\n\t\t\t\t\t\t  $up_count\t .\n\t\t\t\t\t\t  $dir_short_len.\n\t\t\t\t\t\t  $dir_short\t.\n\t\t\t\t\t\t  $unknown3\t .\n\t\t\t\t\t\t  $stream_len   ;/*.\n\t\t\t\t\t\t  $dir_long_len .\n\t\t\t\t\t\t  $unknown4\t .\n\t\t\t\t\t\t  $dir_long\t .\n\t\t\t\t\t\t  $sheet_len\t.\n\t\t\t\t\t\t  $sheet\t\t;*/\n\n\t\t// Pack the header data\n\t\t$length   = strlen($data);\n\t\t$header   = pack(\"vv\", $record, $length);\n\n\t\t// Write the packed data\n\t\t$this->_append($header. $data);\n\t\treturn 0;\n\t}\n\n\t/**\n\t * This method is used to set the height and format for a row.\n\t *\n\t * @param integer $row\tThe row to set\n\t * @param integer $height Height we are giving to the row.\n\t *\t\t\t\t\t\tUse null to set XF without setting height\n\t * @param integer $xfIndex  The optional cell style Xf index to apply to the columns\n\t * @param bool\t$hidden The optional hidden attribute\n\t * @param integer $level  The optional outline level for row, in range [0,7]\n\t */\n\tprivate function _writeRow($row, $height, $xfIndex, $hidden = false, $level = 0)\n\t{\n\t\t$record\t  = 0x0208;\t\t\t   // Record identifier\n\t\t$length\t  = 0x0010;\t\t\t   // Number of bytes to follow\n\n\t\t$colMic\t  = 0x0000;\t\t\t   // First defined column\n\t\t$colMac\t  = 0x0000;\t\t\t   // Last defined column\n\t\t$irwMac\t  = 0x0000;\t\t\t   // Used by Excel to optimise loading\n\t\t$reserved\t= 0x0000;\t\t\t   // Reserved\n\t\t$grbit\t   = 0x0000;\t\t\t   // Option flags\n\t\t$ixfe\t\t= $xfIndex;\n\n\t\tif ( $height < 0 ){\n\t\t\t$height = null;\n\t\t}\n\n\t\t// Use _writeRow($row, null, $XF) to set XF format without setting height\n\t\tif ($height != null) {\n\t\t\t$miyRw = $height * 20;  // row height\n\t\t} else {\n\t\t\t$miyRw = 0xff;\t\t  // default row height is 256\n\t\t}\n\n\t\t// Set the options flags. fUnsynced is used to show that the font and row\n\t\t// heights are not compatible. This is usually the case for WriteExcel.\n\t\t// The collapsed flag 0x10 doesn't seem to be used to indicate that a row\n\t\t// is collapsed. Instead it is used to indicate that the previous row is\n\t\t// collapsed. The zero height flag, 0x20, is used to collapse a row.\n\n\t\t$grbit |= $level;\n\t\tif ($hidden) {\n\t\t\t$grbit |= 0x0030;\n\t\t}\n\t\tif ($height !== null) {\n\t\t\t$grbit |= 0x0040; // fUnsynced\n\t\t}\n\t\tif ($xfIndex !== 0xF) {\n\t\t\t$grbit |= 0x0080;\n\t\t}\n\t\t$grbit |= 0x0100;\n\n\t\t$header   = pack(\"vv\",\t   $record, $length);\n\t\t$data\t = pack(\"vvvvvvvv\", $row, $colMic, $colMac, $miyRw,\n\t\t\t\t\t\t\t\t\t $irwMac,$reserved, $grbit, $ixfe);\n\t\t$this->_append($header.$data);\n\t}\n\n\t/**\n\t * Writes Excel DIMENSIONS to define the area in which there is data.\n\t */\n\tprivate function _writeDimensions()\n\t{\n\t\t$record = 0x0200; // Record identifier\n\n\t\t$length = 0x000E;\n\t\t$data = pack('VVvvv'\n\t\t\t\t, $this->_firstRowIndex\n\t\t\t\t, $this->_lastRowIndex + 1\n\t\t\t\t, $this->_firstColumnIndex\n\t\t\t\t, $this->_lastColumnIndex + 1\n\t\t\t\t, 0x0000 // reserved\n\t\t\t);\n\n\t\t$header = pack(\"vv\", $record, $length);\n\t\t$this->_append($header.$data);\n\t}\n\n\t/**\n\t * Write BIFF record Window2.\n\t */\n\tprivate function _writeWindow2()\n\t{\n\t\t$record\t\t = 0x023E;\t // Record identifier\n\t\t$length\t\t = 0x0012;\n\n\t\t$grbit\t\t  = 0x00B6;\t // Option flags\n\t\t$rwTop\t\t  = 0x0000;\t // Top row visible in window\n\t\t$colLeft\t\t= 0x0000;\t // Leftmost column visible in window\n\n\n\t\t// The options flags that comprise $grbit\n\t\t$fDspFmla\t   = 0;\t\t\t\t\t // 0 - bit\n\t\t$fDspGrid\t   = $this->_phpSheet->getShowGridlines() ? 1 : 0; // 1\n\t\t$fDspRwCol\t  = $this->_phpSheet->getShowRowColHeaders() ? 1 : 0; // 2\n\t\t$fFrozen\t\t= $this->_phpSheet->getFreezePane() ? 1 : 0;\t\t// 3\n\t\t$fDspZeros\t  = 1;\t\t\t\t\t // 4\n\t\t$fDefaultHdr\t= 1;\t\t\t\t\t // 5\n\t\t$fArabic\t\t= $this->_phpSheet->getRightToLeft() ? 1 : 0; // 6\n\t\t$fDspGuts\t   = $this->_outline_on;\t// 7\n\t\t$fFrozenNoSplit = 0;\t\t\t\t\t // 0 - bit\n\t\t// no support in PHPExcel for selected sheet, therefore sheet is only selected if it is the active sheet\n\t\t$fSelected\t  = ($this->_phpSheet === $this->_phpSheet->getParent()->getActiveSheet()) ? 1 : 0;\n\t\t$fPaged\t\t = 1;\t\t\t\t\t // 2\n\t\t$fPageBreakPreview = $this->_phpSheet->getSheetView()->getView() === PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_BREAK_PREVIEW;\n\n\t\t$grbit\t\t\t = $fDspFmla;\n\t\t$grbit\t\t\t|= $fDspGrid\t   << 1;\n\t\t$grbit\t\t\t|= $fDspRwCol\t   << 2;\n\t\t$grbit\t\t\t|= $fFrozen\t\t   << 3;\n\t\t$grbit\t\t\t|= $fDspZeros\t   << 4;\n\t\t$grbit\t\t\t|= $fDefaultHdr\t   << 5;\n\t\t$grbit\t\t\t|= $fArabic\t\t   << 6;\n\t\t$grbit\t\t\t|= $fDspGuts\t   << 7;\n\t\t$grbit\t\t\t|= $fFrozenNoSplit << 8;\n\t\t$grbit\t\t\t|= $fSelected\t   << 9;\n\t\t$grbit\t\t\t|= $fPaged\t\t   << 10;\n\t\t$grbit\t\t\t|= $fPageBreakPreview << 11;\n\n\t\t$header  = pack(\"vv\",   $record, $length);\n\t\t$data\t= pack(\"vvv\", $grbit, $rwTop, $colLeft);\n\n\t\t// FIXME !!!\n\t\t$rgbHdr\t   = 0x0040; // Row/column heading and gridline color index\n\t\t$zoom_factor_page_break = ($fPageBreakPreview? $this->_phpSheet->getSheetView()->getZoomScale() : 0x0000);\n\t\t$zoom_factor_normal =  $this->_phpSheet->getSheetView()->getZoomScaleNormal();\n\n\t\t$data .= pack(\"vvvvV\", $rgbHdr, 0x0000, $zoom_factor_page_break, $zoom_factor_normal, 0x00000000);\n\n\t\t$this->_append($header.$data);\n\t}\n\n\t/**\n\t * Write BIFF record DEFAULTROWHEIGHT.\n\t */\n\tprivate function _writeDefaultRowHeight()\n\t{\n\t\t$defaultRowHeight = $this->_phpSheet->getDefaultRowDimension()->getRowHeight();\n\n\t\tif ($defaultRowHeight < 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t// convert to twips\n\t\t$defaultRowHeight = (int) 20 * $defaultRowHeight;\n\n\t\t$record   = 0x0225;\t  // Record identifier\n\t\t$length   = 0x0004;\t  // Number of bytes to follow\n\n\t\t$header   = pack(\"vv\", $record, $length);\n\t\t$data\t = pack(\"vv\",  1, $defaultRowHeight);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write BIFF record DEFCOLWIDTH if COLINFO records are in use.\n\t */\n\tprivate function _writeDefcol()\n\t{\n\t\t$defaultColWidth = 8;\n\n\t\t$record   = 0x0055;\t  // Record identifier\n\t\t$length   = 0x0002;\t  // Number of bytes to follow\n\n\t\t$header = pack(\"vv\", $record, $length);\n\t\t$data = pack(\"v\", $defaultColWidth);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write BIFF record COLINFO to define column widths\n\t *\n\t * Note: The SDK says the record length is 0x0B but Excel writes a 0x0C\n\t * length record.\n\t *\n\t * @param array $col_array This is the only parameter received and is composed of the following:\n\t *\t\t\t\t0 => First formatted column,\n\t *\t\t\t\t1 => Last formatted column,\n\t *\t\t\t\t2 => Col width (8.43 is Excel default),\n\t *\t\t\t\t3 => The optional XF format of the column,\n\t *\t\t\t\t4 => Option flags.\n\t *\t\t\t\t5 => Optional outline level\n\t */\n\tprivate function _writeColinfo($col_array)\n\t{\n\t\tif (isset($col_array[0])) {\n\t\t\t$colFirst = $col_array[0];\n\t\t}\n\t\tif (isset($col_array[1])) {\n\t\t\t$colLast = $col_array[1];\n\t\t}\n\t\tif (isset($col_array[2])) {\n\t\t\t$coldx = $col_array[2];\n\t\t} else {\n\t\t\t$coldx = 8.43;\n\t\t}\n\t\tif (isset($col_array[3])) {\n\t\t\t$xfIndex = $col_array[3];\n\t\t} else {\n\t\t\t$xfIndex = 15;\n\t\t}\n\t\tif (isset($col_array[4])) {\n\t\t\t$grbit = $col_array[4];\n\t\t} else {\n\t\t\t$grbit = 0;\n\t\t}\n\t\tif (isset($col_array[5])) {\n\t\t\t$level = $col_array[5];\n\t\t} else {\n\t\t\t$level = 0;\n\t\t}\n\t\t$record   = 0x007D;\t\t  // Record identifier\n\t\t$length   = 0x000C;\t\t  // Number of bytes to follow\n\n\t\t$coldx   *= 256;\t\t\t // Convert to units of 1/256 of a char\n\n\t\t$ixfe\t = $xfIndex;\n\t\t$reserved = 0x0000;\t\t\t// Reserved\n\n\t\t$level = max(0, min($level, 7));\n\t\t$grbit |= $level << 8;\n\n\t\t$header   = pack(\"vv\",\t $record, $length);\n\t\t$data\t = pack(\"vvvvvv\", $colFirst, $colLast, $coldx,\n\t\t\t\t\t\t\t\t   $ixfe, $grbit, $reserved);\n\t\t$this->_append($header.$data);\n\t}\n\n\t/**\n\t * Write BIFF record SELECTION.\n\t */\n\tprivate function _writeSelection()\n\t{\n\t\t// look up the selected cell range\n\t\t$selectedCells = $this->_phpSheet->getSelectedCells();\n\t\t$selectedCells = PHPExcel_Cell::splitRange($this->_phpSheet->getSelectedCells());\n\t\t$selectedCells = $selectedCells[0];\n\t\tif (count($selectedCells) == 2) {\n\t\t\tlist($first, $last) = $selectedCells;\n\t\t} else {\n\t\t\t$first = $selectedCells[0];\n\t\t\t$last  = $selectedCells[0];\n\t\t}\n\n\t\tlist($colFirst, $rwFirst) = PHPExcel_Cell::coordinateFromString($first);\n\t\t$colFirst = PHPExcel_Cell::columnIndexFromString($colFirst) - 1; // base 0 column index\n\t\t--$rwFirst; // base 0 row index\n\n\t\tlist($colLast, $rwLast) = PHPExcel_Cell::coordinateFromString($last);\n\t\t$colLast = PHPExcel_Cell::columnIndexFromString($colLast) - 1; // base 0 column index\n\t\t--$rwLast; // base 0 row index\n\n\t\t// make sure we are not out of bounds\n\t\t$colFirst = min($colFirst, 255);\n\t\t$colLast  = min($colLast,  255);\n\n\t\t$rwFirst = min($rwFirst, 65535);\n\t\t$rwLast  = min($rwLast,  65535);\n\n\t\t$record   = 0x001D;\t\t\t\t  // Record identifier\n\t\t$length   = 0x000F;\t\t\t\t  // Number of bytes to follow\n\n\t\t$pnn\t  = $this->_active_pane;\t // Pane position\n\t\t$rwAct\t= $rwFirst;\t\t\t\t// Active row\n\t\t$colAct   = $colFirst;\t\t\t   // Active column\n\t\t$irefAct  = 0;\t\t\t\t\t   // Active cell ref\n\t\t$cref\t = 1;\t\t\t\t\t   // Number of refs\n\n\t\tif (!isset($rwLast)) {\n\t\t\t$rwLast   = $rwFirst;\t   // Last  row in reference\n\t\t}\n\t\tif (!isset($colLast)) {\n\t\t\t$colLast  = $colFirst;\t  // Last  col in reference\n\t\t}\n\n\t\t// Swap last row/col for first row/col as necessary\n\t\tif ($rwFirst > $rwLast) {\n\t\t\tlist($rwFirst, $rwLast) = array($rwLast, $rwFirst);\n\t\t}\n\n\t\tif ($colFirst > $colLast) {\n\t\t\tlist($colFirst, $colLast) = array($colLast, $colFirst);\n\t\t}\n\n\t\t$header   = pack(\"vv\",\t\t $record, $length);\n\t\t$data\t = pack(\"CvvvvvvCC\",  $pnn, $rwAct, $colAct,\n\t\t\t\t\t\t\t\t\t   $irefAct, $cref,\n\t\t\t\t\t\t\t\t\t   $rwFirst, $rwLast,\n\t\t\t\t\t\t\t\t\t   $colFirst, $colLast);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Store the MERGEDCELLS records for all ranges of merged cells\n\t */\n\tprivate function _writeMergedCells()\n\t{\n\t\t$mergeCells = $this->_phpSheet->getMergeCells();\n\t\t$countMergeCells = count($mergeCells);\n\n\t\tif ($countMergeCells == 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t// maximum allowed number of merged cells per record\n\t\t$maxCountMergeCellsPerRecord = 1027;\n\n\t\t// record identifier\n\t\t$record = 0x00E5;\n\n\t\t// counter for total number of merged cells treated so far by the writer\n\t\t$i = 0;\n\n\t\t// counter for number of merged cells written in record currently being written\n\t\t$j = 0;\n\n\t\t// initialize record data\n\t\t$recordData = '';\n\n\t\t// loop through the merged cells\n\t\tforeach ($mergeCells as $mergeCell) {\n\t\t\t++$i;\n\t\t\t++$j;\n\n\t\t\t// extract the row and column indexes\n\t\t\t$range = PHPExcel_Cell::splitRange($mergeCell);\n\t\t\tlist($first, $last) = $range[0];\n\t\t\tlist($firstColumn, $firstRow) = PHPExcel_Cell::coordinateFromString($first);\n\t\t\tlist($lastColumn, $lastRow) = PHPExcel_Cell::coordinateFromString($last);\n\n\t\t\t$recordData .= pack('vvvv', $firstRow - 1, $lastRow - 1, PHPExcel_Cell::columnIndexFromString($firstColumn) - 1, PHPExcel_Cell::columnIndexFromString($lastColumn) - 1);\n\n\t\t\t// flush record if we have reached limit for number of merged cells, or reached final merged cell\n\t\t\tif ($j == $maxCountMergeCellsPerRecord or $i == $countMergeCells) {\n\t\t\t\t$recordData = pack('v', $j) . $recordData;\n\t\t\t\t$length = strlen($recordData);\n\t\t\t\t$header = pack('vv', $record, $length);\n\t\t\t\t$this->_append($header . $recordData);\n\n\t\t\t\t// initialize for next record, if any\n\t\t\t\t$recordData = '';\n\t\t\t\t$j = 0;\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Write SHEETLAYOUT record\n\t */\n\tprivate function _writeSheetLayout()\n\t{\n\t\tif (!$this->_phpSheet->isTabColorSet()) {\n\t\t\treturn;\n\t\t}\n\n\t\t$recordData = pack(\n\t\t\t'vvVVVvv'\n\t\t\t, 0x0862\n\t\t\t, 0x0000\t\t// unused\n\t\t\t, 0x00000000\t// unused\n\t\t\t, 0x00000000\t// unused\n\t\t\t, 0x00000014\t// size of record data\n\t\t\t, $this->_colors[$this->_phpSheet->getTabColor()->getRGB()]\t// color index\n\t\t\t, 0x0000\t\t// unused\n\t\t);\n\n\t\t$length = strlen($recordData);\n\n\t\t$record = 0x0862; // Record identifier\n\t\t$header = pack('vv', $record, $length);\n\t\t$this->_append($header . $recordData);\n\t}\n\n\t/**\n\t * Write SHEETPROTECTION\n\t */\n\tprivate function _writeSheetProtection()\n\t{\n\t\t// record identifier\n\t\t$record = 0x0867;\n\n\t\t// prepare options\n\t\t$options  =   (int) !$this->_phpSheet->getProtection()->getObjects()\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getScenarios()           << 1\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getFormatCells()         << 2\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getFormatColumns()       << 3\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getFormatRows()          << 4\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getInsertColumns()       << 5\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getInsertRows()          << 6\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getInsertHyperlinks()    << 7\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getDeleteColumns()       << 8\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getDeleteRows()          << 9\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getSelectLockedCells()   << 10\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getSort()                << 11\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getAutoFilter()          << 12\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getPivotTables()         << 13\n\t\t\t\t\t| (int) !$this->_phpSheet->getProtection()->getSelectUnlockedCells() << 14 ;\n\n\t\t// record data\n\t\t$recordData = pack(\n\t\t\t'vVVCVVvv'\n\t\t\t, 0x0867\t\t// repeated record identifier\n\t\t\t, 0x0000\t\t// not used\n\t\t\t, 0x0000\t\t// not used\n\t\t\t, 0x00\t\t\t// not used\n\t\t\t, 0x01000200\t// unknown data\n\t\t\t, 0xFFFFFFFF\t// unknown data\n\t\t\t, $options\t\t// options\n\t\t\t, 0x0000\t\t// not used\n\t\t);\n\n\t\t$length = strlen($recordData);\n\t\t$header = pack('vv', $record, $length);\n\n\t\t$this->_append($header . $recordData);\n\t}\n\n\t/**\n\t * Write BIFF record RANGEPROTECTION\n\t *\n\t * Openoffice.org's Documentaion of the Microsoft Excel File Format uses term RANGEPROTECTION for these records\n\t * Microsoft Office Excel 97-2007 Binary File Format Specification uses term FEAT for these records\n\t */\n\tprivate function _writeRangeProtection()\n\t{\n\t\tforeach ($this->_phpSheet->getProtectedCells() as $range => $password) {\n\t\t\t// number of ranges, e.g. 'A1:B3 C20:D25'\n\t\t\t$cellRanges = explode(' ', $range);\n\t\t\t$cref = count($cellRanges);\n\n\t\t\t$recordData = pack(\n\t\t\t\t'vvVVvCVvVv',\n\t\t\t\t0x0868,\n\t\t\t\t0x00,\n\t\t\t\t0x0000,\n\t\t\t\t0x0000,\n\t\t\t\t0x02,\n\t\t\t\t0x0,\n\t\t\t\t0x0000,\n\t\t\t\t$cref,\n\t\t\t\t0x0000,\n\t\t\t\t0x00\n\t\t\t);\n\n\t\t\tforeach ($cellRanges as $cellRange) {\n\t\t\t\t$recordData .= $this->_writeBIFF8CellRangeAddressFixed($cellRange);\n\t\t\t}\n\n\t\t\t// the rgbFeat structure\n\t\t\t$recordData .= pack(\n\t\t\t\t'VV',\n\t\t\t\t0x0000,\n\t\t\t\thexdec($password)\n\t\t\t);\n\n\t\t\t$recordData .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong('p' . md5($recordData));\n\n\t\t\t$length = strlen($recordData);\n\n\t\t\t$record = 0x0868;\t\t// Record identifier\n\t\t\t$header = pack(\"vv\", $record, $length);\n\t\t\t$this->_append($header . $recordData);\n\t\t}\n\t}\n\n\t/**\n\t * Write BIFF record EXTERNCOUNT to indicate the number of external sheet\n\t * references in a worksheet.\n\t *\n\t * Excel only stores references to external sheets that are used in formulas.\n\t * For simplicity we store references to all the sheets in the workbook\n\t * regardless of whether they are used or not. This reduces the overall\n\t * complexity and eliminates the need for a two way dialogue between the formula\n\t * parser the worksheet objects.\n\t *\n\t * @param integer $count The number of external sheet references in this worksheet\n\t */\n\tprivate function _writeExterncount($count)\n\t{\n\t\t$record = 0x0016;\t\t  // Record identifier\n\t\t$length = 0x0002;\t\t  // Number of bytes to follow\n\n\t\t$header = pack(\"vv\", $record, $length);\n\t\t$data   = pack(\"v\",  $count);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Writes the Excel BIFF EXTERNSHEET record. These references are used by\n\t * formulas. A formula references a sheet name via an index. Since we store a\n\t * reference to all of the external worksheets the EXTERNSHEET index is the same\n\t * as the worksheet index.\n\t *\n\t * @param string $sheetname The name of a external worksheet\n\t */\n\tprivate function _writeExternsheet($sheetname)\n\t{\n\t\t$record\t= 0x0017;\t\t // Record identifier\n\n\t\t// References to the current sheet are encoded differently to references to\n\t\t// external sheets.\n\t\t//\n\t\tif ($this->_phpSheet->getTitle() == $sheetname) {\n\t\t\t$sheetname = '';\n\t\t\t$length\t= 0x02;  // The following 2 bytes\n\t\t\t$cch\t   = 1;\t // The following byte\n\t\t\t$rgch\t  = 0x02;  // Self reference\n\t\t} else {\n\t\t\t$length\t= 0x02 + strlen($sheetname);\n\t\t\t$cch\t   = strlen($sheetname);\n\t\t\t$rgch\t  = 0x03;  // Reference to a sheet in the current workbook\n\t\t}\n\n\t\t$header = pack(\"vv\",  $record, $length);\n\t\t$data   = pack(\"CC\", $cch, $rgch);\n\t\t$this->_append($header . $data . $sheetname);\n\t}\n\n\t/**\n\t * Writes the Excel BIFF PANE record.\n\t * The panes can either be frozen or thawed (unfrozen).\n\t * Frozen panes are specified in terms of an integer number of rows and columns.\n\t * Thawed panes are specified in terms of Excel's units for rows and columns.\n\t */\n\tprivate function _writePanes()\n\t{\n\t\t$panes = array();\n\t\tif ($freezePane = $this->_phpSheet->getFreezePane()) {\n\t\t\tlist($column, $row) = PHPExcel_Cell::coordinateFromString($freezePane);\n\t\t\t$panes[0] = $row - 1;\n\t\t\t$panes[1] = PHPExcel_Cell::columnIndexFromString($column) - 1;\n\t\t} else {\n\t\t\t// thaw panes\n\t\t\treturn;\n\t\t}\n\n\t\t$y\t   = isset($panes[0]) ? $panes[0] : null;\n\t\t$x\t   = isset($panes[1]) ? $panes[1] : null;\n\t\t$rwTop   = isset($panes[2]) ? $panes[2] : null;\n\t\t$colLeft = isset($panes[3]) ? $panes[3] : null;\n\t\tif (count($panes) > 4) { // if Active pane was received\n\t\t\t$pnnAct = $panes[4];\n\t\t} else {\n\t\t\t$pnnAct = null;\n\t\t}\n\t\t$record  = 0x0041;\t   // Record identifier\n\t\t$length  = 0x000A;\t   // Number of bytes to follow\n\n\t\t// Code specific to frozen or thawed panes.\n\t\tif ($this->_phpSheet->getFreezePane()) {\n\t\t\t// Set default values for $rwTop and $colLeft\n\t\t\tif (!isset($rwTop)) {\n\t\t\t\t$rwTop   = $y;\n\t\t\t}\n\t\t\tif (!isset($colLeft)) {\n\t\t\t\t$colLeft = $x;\n\t\t\t}\n\t\t} else {\n\t\t\t// Set default values for $rwTop and $colLeft\n\t\t\tif (!isset($rwTop)) {\n\t\t\t\t$rwTop   = 0;\n\t\t\t}\n\t\t\tif (!isset($colLeft)) {\n\t\t\t\t$colLeft = 0;\n\t\t\t}\n\n\t\t\t// Convert Excel's row and column units to the internal units.\n\t\t\t// The default row height is 12.75\n\t\t\t// The default column width is 8.43\n\t\t\t// The following slope and intersection values were interpolated.\n\t\t\t//\n\t\t\t$y = 20*$y + 255;\n\t\t\t$x = 113.879*$x + 390;\n\t\t}\n\n\n\t\t// Determine which pane should be active. There is also the undocumented\n\t\t// option to override this should it be necessary: may be removed later.\n\t\t//\n\t\tif (!isset($pnnAct)) {\n\t\t\tif ($x != 0 && $y != 0) {\n\t\t\t\t$pnnAct = 0; // Bottom right\n\t\t\t}\n\t\t\tif ($x != 0 && $y == 0) {\n\t\t\t\t$pnnAct = 1; // Top right\n\t\t\t}\n\t\t\tif ($x == 0 && $y != 0) {\n\t\t\t\t$pnnAct = 2; // Bottom left\n\t\t\t}\n\t\t\tif ($x == 0 && $y == 0) {\n\t\t\t\t$pnnAct = 3; // Top left\n\t\t\t}\n\t\t}\n\n\t\t$this->_active_pane = $pnnAct; // Used in _writeSelection\n\n\t\t$header\t = pack(\"vv\",\t$record, $length);\n\t\t$data\t   = pack(\"vvvvv\", $x, $y, $rwTop, $colLeft, $pnnAct);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Store the page setup SETUP BIFF record.\n\t */\n\tprivate function _writeSetup()\n\t{\n\t\t$record\t   = 0x00A1;\t\t\t\t  // Record identifier\n\t\t$length\t   = 0x0022;\t\t\t\t  // Number of bytes to follow\n\n\t\t$iPaperSize   = $this->_phpSheet->getPageSetup()->getPaperSize();\t// Paper size\n\n\t\t$iScale = $this->_phpSheet->getPageSetup()->getScale() ?\n\t\t\t$this->_phpSheet->getPageSetup()->getScale() : 100;   // Print scaling factor\n\n\t\t$iPageStart   = 0x01;\t\t\t\t // Starting page number\n\t\t$iFitWidth\t= (int) $this->_phpSheet->getPageSetup()->getFitToWidth();\t// Fit to number of pages wide\n\t\t$iFitHeight\t= (int) $this->_phpSheet->getPageSetup()->getFitToHeight();\t// Fit to number of pages high\n\t\t$grbit\t\t= 0x00;\t\t\t\t // Option flags\n\t\t$iRes\t\t = 0x0258;\t\t\t   // Print resolution\n\t\t$iVRes\t\t= 0x0258;\t\t\t   // Vertical print resolution\n\n\t\t$numHdr\t   = $this->_phpSheet->getPageMargins()->getHeader();  // Header Margin\n\n\t\t$numFtr\t   = $this->_phpSheet->getPageMargins()->getFooter();   // Footer Margin\n\t\t$iCopies\t  = 0x01;\t\t\t\t // Number of copies\n\n\t\t$fLeftToRight = 0x0;\t\t\t\t\t // Print over then down\n\n\t\t// Page orientation\n\t\t$fLandscape = ($this->_phpSheet->getPageSetup()->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE) ?\n\t\t\t0x0 : 0x1;\n\n\t\t$fNoPls\t   = 0x0;\t\t\t\t\t // Setup not read from printer\n\t\t$fNoColor\t = 0x0;\t\t\t\t\t // Print black and white\n\t\t$fDraft\t   = 0x0;\t\t\t\t\t // Print draft quality\n\t\t$fNotes\t   = 0x0;\t\t\t\t\t // Print notes\n\t\t$fNoOrient\t= 0x0;\t\t\t\t\t // Orientation not set\n\t\t$fUsePage\t = 0x0;\t\t\t\t\t // Use custom starting page\n\n\t\t$grbit\t\t   = $fLeftToRight;\n\t\t$grbit\t\t  |= $fLandscape\t<< 1;\n\t\t$grbit\t\t  |= $fNoPls\t\t<< 2;\n\t\t$grbit\t\t  |= $fNoColor\t  << 3;\n\t\t$grbit\t\t  |= $fDraft\t\t<< 4;\n\t\t$grbit\t\t  |= $fNotes\t\t<< 5;\n\t\t$grbit\t\t  |= $fNoOrient\t << 6;\n\t\t$grbit\t\t  |= $fUsePage\t  << 7;\n\n\t\t$numHdr = pack(\"d\", $numHdr);\n\t\t$numFtr = pack(\"d\", $numFtr);\n\t\tif (self::getByteOrder()) { // if it's Big Endian\n\t\t\t$numHdr = strrev($numHdr);\n\t\t\t$numFtr = strrev($numFtr);\n\t\t}\n\n\t\t$header = pack(\"vv\", $record, $length);\n\t\t$data1  = pack(\"vvvvvvvv\", $iPaperSize,\n\t\t\t\t\t\t\t\t   $iScale,\n\t\t\t\t\t\t\t\t   $iPageStart,\n\t\t\t\t\t\t\t\t   $iFitWidth,\n\t\t\t\t\t\t\t\t   $iFitHeight,\n\t\t\t\t\t\t\t\t   $grbit,\n\t\t\t\t\t\t\t\t   $iRes,\n\t\t\t\t\t\t\t\t   $iVRes);\n\t\t$data2  = $numHdr.$numFtr;\n\t\t$data3  = pack(\"v\", $iCopies);\n\t\t$this->_append($header . $data1 . $data2 . $data3);\n\t}\n\n\t/**\n\t * Store the header caption BIFF record.\n\t */\n\tprivate function _writeHeader()\n\t{\n\t\t$record  = 0x0014;\t\t\t   // Record identifier\n\n\t\t/* removing for now\n\t\t// need to fix character count (multibyte!)\n\t\tif (strlen($this->_phpSheet->getHeaderFooter()->getOddHeader()) <= 255) {\n\t\t\t$str\t  = $this->_phpSheet->getHeaderFooter()->getOddHeader();\t   // header string\n\t\t} else {\n\t\t\t$str = '';\n\t\t}\n\t\t*/\n\n\t\t$recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->_phpSheet->getHeaderFooter()->getOddHeader());\n\t\t$length = strlen($recordData);\n\n\t\t$header   = pack(\"vv\", $record, $length);\n\n\t\t$this->_append($header . $recordData);\n\t}\n\n\t/**\n\t * Store the footer caption BIFF record.\n\t */\n\tprivate function _writeFooter()\n\t{\n\t\t$record  = 0x0015;\t\t\t   // Record identifier\n\n\t\t/* removing for now\n\t\t// need to fix character count (multibyte!)\n\t\tif (strlen($this->_phpSheet->getHeaderFooter()->getOddFooter()) <= 255) {\n\t\t\t$str = $this->_phpSheet->getHeaderFooter()->getOddFooter();\n\t\t} else {\n\t\t\t$str = '';\n\t\t}\n\t\t*/\n\n\t\t$recordData = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($this->_phpSheet->getHeaderFooter()->getOddFooter());\n\t\t$length = strlen($recordData);\n\n\t\t$header\t= pack(\"vv\", $record, $length);\n\n\t\t$this->_append($header . $recordData);\n\t}\n\n\t/**\n\t * Store the horizontal centering HCENTER BIFF record.\n\t *\n\t * @access private\n\t */\n\tprivate function _writeHcenter()\n\t{\n\t\t$record   = 0x0083;\t\t\t  // Record identifier\n\t\t$length   = 0x0002;\t\t\t  // Bytes to follow\n\n\t\t$fHCenter = $this->_phpSheet->getPageSetup()->getHorizontalCentered() ? 1 : 0;\t // Horizontal centering\n\n\t\t$header\t= pack(\"vv\", $record, $length);\n\t\t$data\t  = pack(\"v\",  $fHCenter);\n\n\t\t$this->_append($header.$data);\n\t}\n\n\t/**\n\t * Store the vertical centering VCENTER BIFF record.\n\t */\n\tprivate function _writeVcenter()\n\t{\n\t\t$record   = 0x0084;\t\t\t  // Record identifier\n\t\t$length   = 0x0002;\t\t\t  // Bytes to follow\n\n\t\t$fVCenter = $this->_phpSheet->getPageSetup()->getVerticalCentered() ? 1 : 0;\t // Horizontal centering\n\n\t\t$header\t= pack(\"vv\", $record, $length);\n\t\t$data\t  = pack(\"v\",  $fVCenter);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Store the LEFTMARGIN BIFF record.\n\t */\n\tprivate function _writeMarginLeft()\n\t{\n\t\t$record  = 0x0026;\t\t\t\t   // Record identifier\n\t\t$length  = 0x0008;\t\t\t\t   // Bytes to follow\n\n\t\t$margin  = $this->_phpSheet->getPageMargins()->getLeft();\t // Margin in inches\n\n\t\t$header\t= pack(\"vv\",  $record, $length);\n\t\t$data\t  = pack(\"d\",   $margin);\n\t\tif (self::getByteOrder()) { // if it's Big Endian\n\t\t\t$data = strrev($data);\n\t\t}\n\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Store the RIGHTMARGIN BIFF record.\n\t */\n\tprivate function _writeMarginRight()\n\t{\n\t\t$record  = 0x0027;\t\t\t\t   // Record identifier\n\t\t$length  = 0x0008;\t\t\t\t   // Bytes to follow\n\n\t\t$margin  = $this->_phpSheet->getPageMargins()->getRight();\t // Margin in inches\n\n\t\t$header\t= pack(\"vv\",  $record, $length);\n\t\t$data\t  = pack(\"d\",   $margin);\n\t\tif (self::getByteOrder()) { // if it's Big Endian\n\t\t\t$data = strrev($data);\n\t\t}\n\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Store the TOPMARGIN BIFF record.\n\t */\n\tprivate function _writeMarginTop()\n\t{\n\t\t$record  = 0x0028;\t\t\t\t   // Record identifier\n\t\t$length  = 0x0008;\t\t\t\t   // Bytes to follow\n\n\t\t$margin  = $this->_phpSheet->getPageMargins()->getTop();\t // Margin in inches\n\n\t\t$header\t= pack(\"vv\",  $record, $length);\n\t\t$data\t  = pack(\"d\",   $margin);\n\t\tif (self::getByteOrder()) { // if it's Big Endian\n\t\t\t$data = strrev($data);\n\t\t}\n\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Store the BOTTOMMARGIN BIFF record.\n\t */\n\tprivate function _writeMarginBottom()\n\t{\n\t\t$record  = 0x0029;\t\t\t\t   // Record identifier\n\t\t$length  = 0x0008;\t\t\t\t   // Bytes to follow\n\n\t\t$margin  = $this->_phpSheet->getPageMargins()->getBottom();\t // Margin in inches\n\n\t\t$header\t= pack(\"vv\",  $record, $length);\n\t\t$data\t  = pack(\"d\",   $margin);\n\t\tif (self::getByteOrder()) { // if it's Big Endian\n\t\t\t$data = strrev($data);\n\t\t}\n\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write the PRINTHEADERS BIFF record.\n\t */\n\tprivate function _writePrintHeaders()\n\t{\n\t\t$record\t  = 0x002a;\t\t\t\t   // Record identifier\n\t\t$length\t  = 0x0002;\t\t\t\t   // Bytes to follow\n\n\t\t$fPrintRwCol = $this->_print_headers;\t // Boolean flag\n\n\t\t$header\t  = pack(\"vv\", $record, $length);\n\t\t$data\t\t= pack(\"v\", $fPrintRwCol);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write the PRINTGRIDLINES BIFF record. Must be used in conjunction with the\n\t * GRIDSET record.\n\t */\n\tprivate function _writePrintGridlines()\n\t{\n\t\t$record\t  = 0x002b;\t\t\t\t\t// Record identifier\n\t\t$length\t  = 0x0002;\t\t\t\t\t// Bytes to follow\n\n\t\t$fPrintGrid  = $this->_phpSheet->getPrintGridlines() ? 1 : 0;\t// Boolean flag\n\n\t\t$header\t  = pack(\"vv\", $record, $length);\n\t\t$data\t  = pack(\"v\", $fPrintGrid);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write the GRIDSET BIFF record. Must be used in conjunction with the\n\t * PRINTGRIDLINES record.\n\t */\n\tprivate function _writeGridset()\n\t{\n\t\t$record\t  = 0x0082;\t\t\t\t\t\t// Record identifier\n\t\t$length\t  = 0x0002;\t\t\t\t\t\t// Bytes to follow\n\n\t\t$fGridSet\t= !$this->_phpSheet->getPrintGridlines();\t // Boolean flag\n\n\t\t$header\t  = pack(\"vv\",  $record, $length);\n\t\t$data\t\t= pack(\"v\",   $fGridSet);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write the AUTOFILTERINFO BIFF record. This is used to configure the number of autofilter select used in the sheet.\n\t */\n\tprivate function _writeAutoFilterInfo(){\n\t\t$record\t  = 0x009D;\t\t\t\t\t\t// Record identifier\n\t\t$length\t  = 0x0002;\t\t\t\t\t\t// Bytes to follow\n\n\t\t$rangeBounds = PHPExcel_Cell::rangeBoundaries($this->_phpSheet->getAutoFilter()->getRange());\n\t\t$iNumFilters = 1 + $rangeBounds[1][0] - $rangeBounds[0][0];\n\n\t\t$header   = pack(\"vv\", $record, $length);\n\t\t$data     = pack(\"v\",  $iNumFilters);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write the GUTS BIFF record. This is used to configure the gutter margins\n\t * where Excel outline symbols are displayed. The visibility of the gutters is\n\t * controlled by a flag in WSBOOL.\n\t *\n\t * @see _writeWsbool()\n\t */\n\tprivate  function _writeGuts()\n\t{\n\t\t$record\t  = 0x0080;   // Record identifier\n\t\t$length\t  = 0x0008;   // Bytes to follow\n\n\t\t$dxRwGut\t = 0x0000;   // Size of row gutter\n\t\t$dxColGut\t= 0x0000;   // Size of col gutter\n\n\t\t// determine maximum row outline level\n\t\t$maxRowOutlineLevel = 0;\n\t\tforeach ($this->_phpSheet->getRowDimensions() as $rowDimension) {\n\t\t\t$maxRowOutlineLevel = max($maxRowOutlineLevel, $rowDimension->getOutlineLevel());\n\t\t}\n\n\t\t$col_level   = 0;\n\n\t\t// Calculate the maximum column outline level. The equivalent calculation\n\t\t// for the row outline level is carried out in _writeRow().\n\t\t$colcount = count($this->_colinfo);\n\t\tfor ($i = 0; $i < $colcount; ++$i) {\n\t\t\t$col_level = max($this->_colinfo[$i][5], $col_level);\n\t\t}\n\n\t\t// Set the limits for the outline levels (0 <= x <= 7).\n\t\t$col_level = max(0, min($col_level, 7));\n\n\t\t// The displayed level is one greater than the max outline levels\n\t\tif ($maxRowOutlineLevel) {\n\t\t\t++$maxRowOutlineLevel;\n\t\t}\n\t\tif ($col_level) {\n\t\t\t++$col_level;\n\t\t}\n\n\t\t$header\t  = pack(\"vv\",   $record, $length);\n\t\t$data\t\t= pack(\"vvvv\", $dxRwGut, $dxColGut, $maxRowOutlineLevel, $col_level);\n\n\t\t$this->_append($header.$data);\n\t}\n\n\t/**\n\t * Write the WSBOOL BIFF record, mainly for fit-to-page. Used in conjunction\n\t * with the SETUP record.\n\t */\n\tprivate function _writeWsbool()\n\t{\n\t\t$record\t  = 0x0081;   // Record identifier\n\t\t$length\t  = 0x0002;   // Bytes to follow\n\t\t$grbit\t   = 0x0000;\n\n\t\t// The only option that is of interest is the flag for fit to page. So we\n\t\t// set all the options in one go.\n\t\t//\n\t\t// Set the option flags\n\t\t$grbit |= 0x0001;\t\t\t\t\t\t   // Auto page breaks visible\n\t\tif ($this->_outline_style) {\n\t\t\t$grbit |= 0x0020; // Auto outline styles\n\t\t}\n\t\tif ($this->_phpSheet->getShowSummaryBelow()) {\n\t\t\t$grbit |= 0x0040; // Outline summary below\n\t\t}\n\t\tif ($this->_phpSheet->getShowSummaryRight()) {\n\t\t\t$grbit |= 0x0080; // Outline summary right\n\t\t}\n\t\tif ($this->_phpSheet->getPageSetup()->getFitToPage()) {\n\t\t\t$grbit |= 0x0100; // Page setup fit to page\n\t\t}\n\t\tif ($this->_outline_on) {\n\t\t\t$grbit |= 0x0400; // Outline symbols displayed\n\t\t}\n\n\t\t$header\t  = pack(\"vv\", $record, $length);\n\t\t$data\t\t= pack(\"v\",  $grbit);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write the HORIZONTALPAGEBREAKS and VERTICALPAGEBREAKS BIFF records.\n\t */\n\tprivate function _writeBreaks()\n\t{\n\t\t// initialize\n\t\t$vbreaks = array();\n\t\t$hbreaks = array();\n\n\t\tforeach ($this->_phpSheet->getBreaks() as $cell => $breakType) {\n\t\t\t// Fetch coordinates\n\t\t\t$coordinates = PHPExcel_Cell::coordinateFromString($cell);\n\n\t\t\t// Decide what to do by the type of break\n\t\t\tswitch ($breakType) {\n\t\t\t\tcase PHPExcel_Worksheet::BREAK_COLUMN:\n\t\t\t\t\t// Add to list of vertical breaks\n\t\t\t\t\t$vbreaks[] = PHPExcel_Cell::columnIndexFromString($coordinates[0]) - 1;\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase PHPExcel_Worksheet::BREAK_ROW:\n\t\t\t\t\t// Add to list of horizontal breaks\n\t\t\t\t\t$hbreaks[] = $coordinates[1];\n\t\t\t\t\tbreak;\n\n\t\t\t\tcase PHPExcel_Worksheet::BREAK_NONE:\n\t\t\t\tdefault:\n\t\t\t\t\t// Nothing to do\n\t\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t//horizontal page breaks\n\t\tif (!empty($hbreaks)) {\n\n\t\t\t// Sort and filter array of page breaks\n\t\t\tsort($hbreaks, SORT_NUMERIC);\n\t\t\tif ($hbreaks[0] == 0) { // don't use first break if it's 0\n\t\t\t\tarray_shift($hbreaks);\n\t\t\t}\n\n\t\t\t$record  = 0x001b;\t\t\t   // Record identifier\n\t\t\t$cbrk\t= count($hbreaks);\t   // Number of page breaks\n\t\t\t$length  = 2 + 6 * $cbrk;\t  // Bytes to follow\n\n\t\t\t$header  = pack(\"vv\", $record, $length);\n\t\t\t$data\t= pack(\"v\",  $cbrk);\n\n\t\t\t// Append each page break\n\t\t\tforeach ($hbreaks as $hbreak) {\n\t\t\t\t$data .= pack(\"vvv\", $hbreak, 0x0000, 0x00ff);\n\t\t\t}\n\n\t\t\t$this->_append($header . $data);\n\t\t}\n\n\t\t// vertical page breaks\n\t\tif (!empty($vbreaks)) {\n\n\t\t\t// 1000 vertical pagebreaks appears to be an internal Excel 5 limit.\n\t\t\t// It is slightly higher in Excel 97/200, approx. 1026\n\t\t\t$vbreaks = array_slice($vbreaks, 0, 1000);\n\n\t\t\t// Sort and filter array of page breaks\n\t\t\tsort($vbreaks, SORT_NUMERIC);\n\t\t\tif ($vbreaks[0] == 0) { // don't use first break if it's 0\n\t\t\t\tarray_shift($vbreaks);\n\t\t\t}\n\n\t\t\t$record  = 0x001a;\t\t\t   // Record identifier\n\t\t\t$cbrk\t= count($vbreaks);\t   // Number of page breaks\n\t\t\t$length  = 2 + 6 * $cbrk;\t  // Bytes to follow\n\n\t\t\t$header  = pack(\"vv\",  $record, $length);\n\t\t\t$data\t= pack(\"v\",   $cbrk);\n\n\t\t\t// Append each page break\n\t\t\tforeach ($vbreaks as $vbreak) {\n\t\t\t\t$data .= pack(\"vvv\", $vbreak, 0x0000, 0xffff);\n\t\t\t}\n\n\t\t\t$this->_append($header . $data);\n\t\t}\n\t}\n\n\t/**\n\t * Set the Biff PROTECT record to indicate that the worksheet is protected.\n\t */\n\tprivate function _writeProtect()\n\t{\n\t\t// Exit unless sheet protection has been specified\n\t\tif (!$this->_phpSheet->getProtection()->getSheet()) {\n\t\t\treturn;\n\t\t}\n\n\t\t$record\t  = 0x0012;\t\t\t // Record identifier\n\t\t$length\t  = 0x0002;\t\t\t // Bytes to follow\n\n\t\t$fLock\t  = 1;\t// Worksheet is protected\n\n\t\t$header\t  = pack(\"vv\", $record, $length);\n\t\t$data\t  = pack(\"v\",  $fLock);\n\n\t\t$this->_append($header.$data);\n\t}\n\n\t/**\n\t * Write SCENPROTECT\n\t */\n\tprivate function _writeScenProtect()\n\t{\n\t\t// Exit if sheet protection is not active\n\t\tif (!$this->_phpSheet->getProtection()->getSheet()) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Exit if scenarios are not protected\n\t\tif (!$this->_phpSheet->getProtection()->getScenarios()) {\n\t\t\treturn;\n\t\t}\n\n\t\t$record = 0x00DD; // Record identifier\n\t\t$length = 0x0002; // Bytes to follow\n\n\t\t$header = pack('vv', $record, $length);\n\t\t$data = pack('v', 1);\n\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write OBJECTPROTECT\n\t */\n\tprivate function _writeObjectProtect()\n\t{\n\t\t// Exit if sheet protection is not active\n\t\tif (!$this->_phpSheet->getProtection()->getSheet()) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Exit if objects are not protected\n\t\tif (!$this->_phpSheet->getProtection()->getObjects()) {\n\t\t\treturn;\n\t\t}\n\n\t\t$record = 0x0063; // Record identifier\n\t\t$length = 0x0002; // Bytes to follow\n\n\t\t$header = pack('vv', $record, $length);\n\t\t$data = pack('v', 1);\n\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write the worksheet PASSWORD record.\n\t */\n\tprivate function _writePassword()\n\t{\n\t\t// Exit unless sheet protection and password have been specified\n\t\tif (!$this->_phpSheet->getProtection()->getSheet() || !$this->_phpSheet->getProtection()->getPassword()) {\n\t\t\treturn;\n\t\t}\n\n\t\t$record\t  = 0x0013;\t\t\t   // Record identifier\n\t\t$length\t  = 0x0002;\t\t\t   // Bytes to follow\n\n\t\t$wPassword   = hexdec($this->_phpSheet->getProtection()->getPassword());\t // Encoded password\n\n\t\t$header\t  = pack(\"vv\", $record, $length);\n\t\t$data\t\t= pack(\"v\",  $wPassword);\n\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Insert a 24bit bitmap image in a worksheet.\n\t *\n\t * @access public\n\t * @param integer $row\t The row we are going to insert the bitmap into\n\t * @param integer $col\t The column we are going to insert the bitmap into\n\t * @param mixed   $bitmap  The bitmap filename or GD-image resource\n\t * @param integer $x\t   The horizontal position (offset) of the image inside the cell.\n\t * @param integer $y\t   The vertical position (offset) of the image inside the cell.\n\t * @param float   $scale_x The horizontal scale\n\t * @param float   $scale_y The vertical scale\n\t */\n\tfunction insertBitmap($row, $col, $bitmap, $x = 0, $y = 0, $scale_x = 1, $scale_y = 1)\n\t{\n\t\t$bitmap_array = (is_resource($bitmap) ? $this->_processBitmapGd($bitmap) : $this->_processBitmap($bitmap));\n\t\tlist($width, $height, $size, $data) = $bitmap_array; //$this->_processBitmap($bitmap);\n\n\t\t// Scale the frame of the image.\n\t\t$width  *= $scale_x;\n\t\t$height *= $scale_y;\n\n\t\t// Calculate the vertices of the image and write the OBJ record\n\t\t$this->_positionImage($col, $row, $x, $y, $width, $height);\n\n\t\t// Write the IMDATA record to store the bitmap data\n\t\t$record\t  = 0x007f;\n\t\t$length\t  = 8 + $size;\n\t\t$cf\t\t  = 0x09;\n\t\t$env\t\t = 0x01;\n\t\t$lcb\t\t = $size;\n\n\t\t$header\t  = pack(\"vvvvV\", $record, $length, $cf, $env, $lcb);\n\t\t$this->_append($header.$data);\n\t}\n\n\t/**\n\t * Calculate the vertices that define the position of the image as required by\n\t * the OBJ record.\n\t *\n\t *\t\t +------------+------------+\n\t *\t\t |\t A\t  |\t  B\t |\n\t *   +-----+------------+------------+\n\t *   |\t |(x1,y1)\t |\t\t\t|\n\t *   |  1  |(A1)._______|______\t  |\n\t *   |\t |\t|\t\t\t  |\t |\n\t *   |\t |\t|\t\t\t  |\t |\n\t *   +-----+----|\tBITMAP\t|-----+\n\t *   |\t |\t|\t\t\t  |\t |\n\t *   |  2  |\t|______________.\t |\n\t *   |\t |\t\t\t|\t\t(B2)|\n\t *   |\t |\t\t\t|\t (x2,y2)|\n\t *   +---- +------------+------------+\n\t *\n\t * Example of a bitmap that covers some of the area from cell A1 to cell B2.\n\t *\n\t * Based on the width and height of the bitmap we need to calculate 8 vars:\n\t *\t $col_start, $row_start, $col_end, $row_end, $x1, $y1, $x2, $y2.\n\t * The width and height of the cells are also variable and have to be taken into\n\t * account.\n\t * The values of $col_start and $row_start are passed in from the calling\n\t * function. The values of $col_end and $row_end are calculated by subtracting\n\t * the width and height of the bitmap from the width and height of the\n\t * underlying cells.\n\t * The vertices are expressed as a percentage of the underlying cell width as\n\t * follows (rhs values are in pixels):\n\t *\n\t *\t   x1 = X / W *1024\n\t *\t   y1 = Y / H *256\n\t *\t   x2 = (X-1) / W *1024\n\t *\t   y2 = (Y-1) / H *256\n\t *\n\t *\t   Where:  X is distance from the left side of the underlying cell\n\t *\t\t\t   Y is distance from the top of the underlying cell\n\t *\t\t\t   W is the width of the cell\n\t *\t\t\t   H is the height of the cell\n\t * The SDK incorrectly states that the height should be expressed as a\n\t *\t\tpercentage of 1024.\n\t *\n\t * @access private\n\t * @param integer $col_start Col containing upper left corner of object\n\t * @param integer $row_start Row containing top left corner of object\n\t * @param integer $x1\t\tDistance to left side of object\n\t * @param integer $y1\t\tDistance to top of object\n\t * @param integer $width\t Width of image frame\n\t * @param integer $height\tHeight of image frame\n\t */\n\tfunction _positionImage($col_start, $row_start, $x1, $y1, $width, $height)\n\t{\n\t\t// Initialise end cell to the same as the start cell\n\t\t$col_end\t= $col_start;  // Col containing lower right corner of object\n\t\t$row_end\t= $row_start;  // Row containing bottom right corner of object\n\n\t\t// Zero the specified offset if greater than the cell dimensions\n\t\tif ($x1 >= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start))) {\n\t\t\t$x1 = 0;\n\t\t}\n\t\tif ($y1 >= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1)) {\n\t\t\t$y1 = 0;\n\t\t}\n\n\t\t$width\t  = $width  + $x1 -1;\n\t\t$height\t = $height + $y1 -1;\n\n\t\t// Subtract the underlying cell widths to find the end cell of the image\n\t\twhile ($width >= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end))) {\n\t\t\t$width -= PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end));\n\t\t\t++$col_end;\n\t\t}\n\n\t\t// Subtract the underlying cell heights to find the end cell of the image\n\t\twhile ($height >= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1)) {\n\t\t\t$height -= PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1);\n\t\t\t++$row_end;\n\t\t}\n\n\t\t// Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell\n\t\t// with zero eight or width.\n\t\t//\n\t\tif (PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start)) == 0) {\n\t\t\treturn;\n\t\t}\n\t\tif (PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end))   == 0) {\n\t\t\treturn;\n\t\t}\n\t\tif (PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1) == 0) {\n\t\t\treturn;\n\t\t}\n\t\tif (PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1)   == 0) {\n\t\t\treturn;\n\t\t}\n\n\t\t// Convert the pixel values to the percentage value expected by Excel\n\t\t$x1 = $x1\t / PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_start))   * 1024;\n\t\t$y1 = $y1\t / PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_start + 1)   *  256;\n\t\t$x2 = $width  / PHPExcel_Shared_Excel5::sizeCol($this->_phpSheet, PHPExcel_Cell::stringFromColumnIndex($col_end))\t * 1024; // Distance to right side of object\n\t\t$y2 = $height / PHPExcel_Shared_Excel5::sizeRow($this->_phpSheet, $row_end + 1)\t *  256; // Distance to bottom of object\n\n\t\t$this->_writeObjPicture($col_start, $x1,\n\t\t\t\t\t\t\t\t $row_start, $y1,\n\t\t\t\t\t\t\t\t $col_end, $x2,\n\t\t\t\t\t\t\t\t $row_end, $y2);\n\t}\n\n\t/**\n\t * Store the OBJ record that precedes an IMDATA record. This could be generalise\n\t * to support other Excel objects.\n\t *\n\t * @param integer $colL Column containing upper left corner of object\n\t * @param integer $dxL  Distance from left side of cell\n\t * @param integer $rwT  Row containing top left corner of object\n\t * @param integer $dyT  Distance from top of cell\n\t * @param integer $colR Column containing lower right corner of object\n\t * @param integer $dxR  Distance from right of cell\n\t * @param integer $rwB  Row containing bottom right corner of object\n\t * @param integer $dyB  Distance from bottom of cell\n\t */\n\tprivate function _writeObjPicture($colL,$dxL,$rwT,$dyT,$colR,$dxR,$rwB,$dyB)\n\t{\n\t\t$record\t  = 0x005d;   // Record identifier\n\t\t$length\t  = 0x003c;   // Bytes to follow\n\n\t\t$cObj\t\t= 0x0001;   // Count of objects in file (set to 1)\n\t\t$OT\t\t  = 0x0008;   // Object type. 8 = Picture\n\t\t$id\t\t  = 0x0001;   // Object ID\n\t\t$grbit\t   = 0x0614;   // Option flags\n\n\t\t$cbMacro\t = 0x0000;   // Length of FMLA structure\n\t\t$Reserved1   = 0x0000;   // Reserved\n\t\t$Reserved2   = 0x0000;   // Reserved\n\n\t\t$icvBack\t = 0x09;\t // Background colour\n\t\t$icvFore\t = 0x09;\t // Foreground colour\n\t\t$fls\t\t = 0x00;\t // Fill pattern\n\t\t$fAuto\t   = 0x00;\t // Automatic fill\n\t\t$icv\t\t = 0x08;\t // Line colour\n\t\t$lns\t\t = 0xff;\t // Line style\n\t\t$lnw\t\t = 0x01;\t // Line weight\n\t\t$fAutoB\t  = 0x00;\t // Automatic border\n\t\t$frs\t\t = 0x0000;   // Frame style\n\t\t$cf\t\t  = 0x0009;   // Image format, 9 = bitmap\n\t\t$Reserved3   = 0x0000;   // Reserved\n\t\t$cbPictFmla  = 0x0000;   // Length of FMLA structure\n\t\t$Reserved4   = 0x0000;   // Reserved\n\t\t$grbit2\t  = 0x0001;   // Option flags\n\t\t$Reserved5   = 0x0000;   // Reserved\n\n\n\t\t$header\t  = pack(\"vv\", $record, $length);\n\t\t$data\t\t= pack(\"V\", $cObj);\n\t\t$data\t   .= pack(\"v\", $OT);\n\t\t$data\t   .= pack(\"v\", $id);\n\t\t$data\t   .= pack(\"v\", $grbit);\n\t\t$data\t   .= pack(\"v\", $colL);\n\t\t$data\t   .= pack(\"v\", $dxL);\n\t\t$data\t   .= pack(\"v\", $rwT);\n\t\t$data\t   .= pack(\"v\", $dyT);\n\t\t$data\t   .= pack(\"v\", $colR);\n\t\t$data\t   .= pack(\"v\", $dxR);\n\t\t$data\t   .= pack(\"v\", $rwB);\n\t\t$data\t   .= pack(\"v\", $dyB);\n\t\t$data\t   .= pack(\"v\", $cbMacro);\n\t\t$data\t   .= pack(\"V\", $Reserved1);\n\t\t$data\t   .= pack(\"v\", $Reserved2);\n\t\t$data\t   .= pack(\"C\", $icvBack);\n\t\t$data\t   .= pack(\"C\", $icvFore);\n\t\t$data\t   .= pack(\"C\", $fls);\n\t\t$data\t   .= pack(\"C\", $fAuto);\n\t\t$data\t   .= pack(\"C\", $icv);\n\t\t$data\t   .= pack(\"C\", $lns);\n\t\t$data\t   .= pack(\"C\", $lnw);\n\t\t$data\t   .= pack(\"C\", $fAutoB);\n\t\t$data\t   .= pack(\"v\", $frs);\n\t\t$data\t   .= pack(\"V\", $cf);\n\t\t$data\t   .= pack(\"v\", $Reserved3);\n\t\t$data\t   .= pack(\"v\", $cbPictFmla);\n\t\t$data\t   .= pack(\"v\", $Reserved4);\n\t\t$data\t   .= pack(\"v\", $grbit2);\n\t\t$data\t   .= pack(\"V\", $Reserved5);\n\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Convert a GD-image into the internal format.\n\t *\n\t * @access private\n\t * @param resource $image The image to process\n\t * @return array Array with data and properties of the bitmap\n\t */\n\tfunction _processBitmapGd($image) {\n\t\t$width = imagesx($image);\n\t\t$height = imagesy($image);\n\n\t\t$data = pack(\"Vvvvv\", 0x000c, $width, $height, 0x01, 0x18);\n\t\tfor ($j=$height; $j--; ) {\n\t\t\tfor ($i=0; $i < $width; ++$i) {\n\t\t\t\t$color = imagecolorsforindex($image, imagecolorat($image, $i, $j));\n\t\t\t\tforeach (array(\"red\", \"green\", \"blue\") as $key) {\n\t\t\t\t\t$color[$key] = $color[$key] + round((255 - $color[$key]) * $color[\"alpha\"] / 127);\n\t\t\t\t}\n\t\t\t\t$data .= chr($color[\"blue\"]) . chr($color[\"green\"]) . chr($color[\"red\"]);\n\t\t\t}\n\t\t\tif (3*$width % 4) {\n\t\t\t\t$data .= str_repeat(\"\\x00\", 4 - 3*$width % 4);\n\t\t\t}\n\t\t}\n\n\t\treturn array($width, $height, strlen($data), $data);\n\t}\n\n\t/**\n\t * Convert a 24 bit bitmap into the modified internal format used by Windows.\n\t * This is described in BITMAPCOREHEADER and BITMAPCOREINFO structures in the\n\t * MSDN library.\n\t *\n\t * @access private\n\t * @param string $bitmap The bitmap to process\n\t * @return array Array with data and properties of the bitmap\n\t */\n\tfunction _processBitmap($bitmap)\n\t{\n\t\t// Open file.\n\t\t$bmp_fd = @fopen($bitmap,\"rb\");\n\t\tif (!$bmp_fd) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Couldn't import $bitmap\");\n\t\t}\n\n\t\t// Slurp the file into a string.\n\t\t$data = fread($bmp_fd, filesize($bitmap));\n\n\t\t// Check that the file is big enough to be a bitmap.\n\t\tif (strlen($data) <= 0x36) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"$bitmap doesn't contain enough data.\\n\");\n\t\t}\n\n\t\t// The first 2 bytes are used to identify the bitmap.\n\t\t$identity = unpack(\"A2ident\", $data);\n\t\tif ($identity['ident'] != \"BM\") {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"$bitmap doesn't appear to be a valid bitmap image.\\n\");\n\t\t}\n\n\t\t// Remove bitmap data: ID.\n\t\t$data = substr($data, 2);\n\n\t\t// Read and remove the bitmap size. This is more reliable than reading\n\t\t// the data size at offset 0x22.\n\t\t//\n\t\t$size_array   = unpack(\"Vsa\", substr($data, 0, 4));\n\t\t$size   = $size_array['sa'];\n\t\t$data   = substr($data, 4);\n\t\t$size  -= 0x36; // Subtract size of bitmap header.\n\t\t$size  += 0x0C; // Add size of BIFF header.\n\n\t\t// Remove bitmap data: reserved, offset, header length.\n\t\t$data = substr($data, 12);\n\n\t\t// Read and remove the bitmap width and height. Verify the sizes.\n\t\t$width_and_height = unpack(\"V2\", substr($data, 0, 8));\n\t\t$width  = $width_and_height[1];\n\t\t$height = $width_and_height[2];\n\t\t$data   = substr($data, 8);\n\t\tif ($width > 0xFFFF) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"$bitmap: largest image width supported is 65k.\\n\");\n\t\t}\n\t\tif ($height > 0xFFFF) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"$bitmap: largest image height supported is 65k.\\n\");\n\t\t}\n\n\t\t// Read and remove the bitmap planes and bpp data. Verify them.\n\t\t$planes_and_bitcount = unpack(\"v2\", substr($data, 0, 4));\n\t\t$data = substr($data, 4);\n\t\tif ($planes_and_bitcount[2] != 24) { // Bitcount\n\t\t\tthrow new PHPExcel_Writer_Exception(\"$bitmap isn't a 24bit true color bitmap.\\n\");\n\t\t}\n\t\tif ($planes_and_bitcount[1] != 1) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"$bitmap: only 1 plane supported in bitmap image.\\n\");\n\t\t}\n\n\t\t// Read and remove the bitmap compression. Verify compression.\n\t\t$compression = unpack(\"Vcomp\", substr($data, 0, 4));\n\t\t$data = substr($data, 4);\n\n\t\t//$compression = 0;\n\t\tif ($compression['comp'] != 0) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"$bitmap: compression not supported in bitmap image.\\n\");\n\t\t}\n\n\t\t// Remove bitmap data: data size, hres, vres, colours, imp. colours.\n\t\t$data = substr($data, 20);\n\n\t\t// Add the BITMAPCOREHEADER data\n\t\t$header  = pack(\"Vvvvv\", 0x000c, $width, $height, 0x01, 0x18);\n\t\t$data\t= $header . $data;\n\n\t\treturn (array($width, $height, $size, $data));\n\t}\n\n\t/**\n\t * Store the window zoom factor. This should be a reduced fraction but for\n\t * simplicity we will store all fractions with a numerator of 100.\n\t */\n\tprivate function _writeZoom()\n\t{\n\t\t// If scale is 100 we don't need to write a record\n\t\tif ($this->_phpSheet->getSheetView()->getZoomScale() == 100) {\n\t\t\treturn;\n\t\t}\n\n\t\t$record\t  = 0x00A0;\t\t\t   // Record identifier\n\t\t$length\t  = 0x0004;\t\t\t   // Bytes to follow\n\n\t\t$header\t  = pack(\"vv\", $record, $length);\n\t\t$data\t\t= pack(\"vv\", $this->_phpSheet->getSheetView()->getZoomScale(), 100);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Get Escher object\n\t *\n\t * @return PHPExcel_Shared_Escher\n\t */\n\tpublic function getEscher()\n\t{\n\t\treturn $this->_escher;\n\t}\n\n\t/**\n\t * Set Escher object\n\t *\n\t * @param PHPExcel_Shared_Escher $pValue\n\t */\n\tpublic function setEscher(PHPExcel_Shared_Escher $pValue = null)\n\t{\n\t\t$this->_escher = $pValue;\n\t}\n\n\t/**\n\t * Write MSODRAWING record\n\t */\n\tprivate function _writeMsoDrawing()\n\t{\n\t\t// write the Escher stream if necessary\n\t\tif (isset($this->_escher)) {\n\t\t\t$writer = new PHPExcel_Writer_Excel5_Escher($this->_escher);\n\t\t\t$data = $writer->close();\n\t\t\t$spOffsets = $writer->getSpOffsets();\n\t\t\t$spTypes = $writer->getSpTypes();\n\t\t\t// write the neccesary MSODRAWING, OBJ records\n\n\t\t\t// split the Escher stream\n\t\t\t$spOffsets[0] = 0;\n\t\t\t$nm = count($spOffsets) - 1; // number of shapes excluding first shape\n\t\t\tfor ($i = 1; $i <= $nm; ++$i) {\n\t\t\t\t// MSODRAWING record\n\t\t\t\t$record = 0x00EC;\t\t\t// Record identifier\n\n\t\t\t\t// chunk of Escher stream for one shape\n\t\t\t\t$dataChunk = substr($data, $spOffsets[$i -1], $spOffsets[$i] - $spOffsets[$i - 1]);\n\n\t\t\t\t$length = strlen($dataChunk);\n\t\t\t\t$header = pack(\"vv\", $record, $length);\n\n\t\t\t\t$this->_append($header . $dataChunk);\n\n\t\t\t\t// OBJ record\n\t\t\t\t$record = 0x005D; // record identifier\n\t\t\t\t$objData = '';\n\n\t\t\t\t// ftCmo\n\t\t\t\tif($spTypes[$i] == 0x00C9){\n\t\t\t\t\t// Add ftCmo (common object data) subobject\n\t\t\t\t\t$objData .=\n\t\t\t\t\t\tpack('vvvvvVVV'\n\t\t\t\t\t\t\t\t, 0x0015\t// 0x0015 = ftCmo\n\t\t\t\t\t\t\t\t, 0x0012\t// length of ftCmo data\n\t\t\t\t\t\t\t\t, 0x0014\t// object type, 0x0014 = filter\n\t\t\t\t\t\t\t\t, $i\t\t// object id number, Excel seems to use 1-based index, local for the sheet\n\t\t\t\t\t\t\t\t, 0x2101\t// option flags, 0x2001 is what OpenOffice.org uses\n\t\t\t\t\t\t\t\t, 0\t\t\t// reserved\n\t\t\t\t\t\t\t\t, 0\t\t\t// reserved\n\t\t\t\t\t\t\t\t, 0\t\t\t// reserved\n\t\t\t\t\t\t);\n\n\t\t\t\t\t// Add ftSbs Scroll bar subobject\n\t\t\t\t\t$objData .= pack('vv', 0x00C, 0x0014);\n\t\t\t\t\t$objData .= pack('H*', '0000000000000000640001000A00000010000100');\n\t\t\t\t\t// Add ftLbsData (List box data) subobject\n\t\t\t\t\t$objData .= pack('vv', 0x0013, 0x1FEE);\n\t\t\t\t\t$objData .= pack('H*', '00000000010001030000020008005700');\n\t\t\t\t}\n\t\t\t\telse {\n\t\t\t\t\t// Add ftCmo (common object data) subobject\n\t\t\t\t\t$objData .=\n\t\t\t\t\t\tpack('vvvvvVVV'\n\t\t\t\t\t\t\t, 0x0015\t// 0x0015 = ftCmo\n\t\t\t\t\t\t\t, 0x0012\t// length of ftCmo data\n\t\t\t\t\t\t\t, 0x0008\t// object type, 0x0008 = picture\n\t\t\t\t\t\t\t, $i\t\t// object id number, Excel seems to use 1-based index, local for the sheet\n\t\t\t\t\t\t\t, 0x6011\t// option flags, 0x6011 is what OpenOffice.org uses\n\t\t\t\t\t\t\t, 0\t\t\t// reserved\n\t\t\t\t\t\t\t, 0\t\t\t// reserved\n\t\t\t\t\t\t\t, 0\t\t\t// reserved\n\t\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\t// ftEnd\n\t\t\t\t$objData .=\n\t\t\t\t\tpack('vv'\n\t\t\t\t\t\t, 0x0000\t// 0x0000 = ftEnd\n\t\t\t\t\t\t, 0x0000\t// length of ftEnd data\n\t\t\t\t\t);\n\n\t\t\t\t$length = strlen($objData);\n\t\t\t\t$header = pack('vv', $record, $length);\n\t\t\t\t$this->_append($header . $objData);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Store the DATAVALIDATIONS and DATAVALIDATION records.\n\t */\n\tprivate function _writeDataValidity()\n\t{\n\t\t// Datavalidation collection\n\t\t$dataValidationCollection = $this->_phpSheet->getDataValidationCollection();\n\n\t\t// Write data validations?\n\t\tif (!empty($dataValidationCollection)) {\n\n\t\t\t// DATAVALIDATIONS record\n\t\t\t$record = 0x01B2;\t  // Record identifier\n\t\t\t$length\t  = 0x0012;\t  // Bytes to follow\n\n\t\t\t$grbit  = 0x0000;\t   // Prompt box at cell, no cached validity data at DV records\n\t\t\t$horPos\t  = 0x00000000;  // Horizontal position of prompt box, if fixed position\n\t\t\t$verPos\t  = 0x00000000;  // Vertical position of prompt box, if fixed position\n\t\t\t$objId  = 0xFFFFFFFF;  // Object identifier of drop down arrow object, or -1 if not visible\n\n\t\t\t$header\t  = pack('vv', $record, $length);\n\t\t\t$data\t\t= pack('vVVVV', $grbit, $horPos, $verPos, $objId,\n\t\t\t\t\t\t\t\t\t\t count($dataValidationCollection));\n\t\t\t$this->_append($header.$data);\n\n\t\t\t// DATAVALIDATION records\n\t\t\t$record = 0x01BE;\t\t\t  // Record identifier\n\n\t\t\tforeach ($dataValidationCollection as $cellCoordinate => $dataValidation) {\n\t\t\t\t// initialize record data\n\t\t\t\t$data = '';\n\n\t\t\t\t// options\n\t\t\t\t$options = 0x00000000;\n\n\t\t\t\t// data type\n\t\t\t\t$type = $dataValidation->getType();\n\t\t\t\tswitch ($type) {\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::TYPE_NONE:\t\t$type = 0x00;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::TYPE_WHOLE:\t\t$type = 0x01;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::TYPE_DECIMAL:\t$type = 0x02;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::TYPE_LIST:\t\t$type = 0x03;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::TYPE_DATE:\t\t$type = 0x04;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::TYPE_TIME:\t\t$type = 0x05;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::TYPE_TEXTLENGTH:\t$type = 0x06;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::TYPE_CUSTOM:\t\t$type = 0x07;\tbreak;\n\t\t\t\t}\n\t\t\t\t$options |= $type << 0;\n\n\t\t\t\t// error style\n\t\t\t\t$errorStyle = $dataValidation->getType();\n\t\t\t\tswitch ($errorStyle) {\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::STYLE_STOP:\t\t\t$errorStyle = 0x00;\t\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::STYLE_WARNING:\t\t$errorStyle = 0x01;\t\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::STYLE_INFORMATION:\t$errorStyle = 0x02;\t\tbreak;\n\t\t\t\t}\n\t\t\t\t$options |= $errorStyle << 4;\n\n\t\t\t\t// explicit formula?\n\t\t\t\tif ($type == 0x03 && preg_match('/^\\\".*\\\"$/', $dataValidation->getFormula1())) {\n\t\t\t\t\t$options |= 0x01\t\t\t\t<< 7;\n\t\t\t\t}\n\n\t\t\t\t// empty cells allowed\n\t\t\t\t$options |= $dataValidation->getAllowBlank() << 8;\n\n\t\t\t\t// show drop down\n\t\t\t\t$options |= (!$dataValidation->getShowDropDown()) << 9;\n\n\t\t\t\t// show input message\n\t\t\t\t$options |= $dataValidation->getShowInputMessage() << 18;\n\n\t\t\t\t// show error message\n\t\t\t\t$options |= $dataValidation->getShowErrorMessage() << 19;\n\n\t\t\t\t// condition operator\n\t\t\t\t$operator = $dataValidation->getOperator();\n\t\t\t\tswitch ($operator) {\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::OPERATOR_BETWEEN: $operator = 0x00\t\t\t;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::OPERATOR_NOTBETWEEN: $operator = 0x01\t\t;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::OPERATOR_EQUAL: $operator = 0x02\t\t\t\t;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::OPERATOR_NOTEQUAL: $operator = 0x03\t\t\t;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHAN: $operator = 0x04\t\t;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::OPERATOR_LESSTHAN: $operator = 0x05\t\t\t;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::OPERATOR_GREATERTHANOREQUAL: $operator = 0x06;\tbreak;\n\t\t\t\t\tcase PHPExcel_Cell_DataValidation::OPERATOR_LESSTHANOREQUAL: $operator = 0x07\t;\tbreak;\n\t\t\t\t}\n\t\t\t\t$options |= $operator << 20;\n\n\t\t\t\t$data\t\t= pack('V', $options);\n\n\t\t\t\t// prompt title\n\t\t\t\t$promptTitle = $dataValidation->getPromptTitle() !== '' ?\n\t\t\t\t\t$dataValidation->getPromptTitle() : chr(0);\n\t\t\t\t$data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($promptTitle);\n\n\t\t\t\t// error title\n\t\t\t\t$errorTitle = $dataValidation->getErrorTitle() !== '' ?\n\t\t\t\t\t$dataValidation->getErrorTitle() : chr(0);\n\t\t\t\t$data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($errorTitle);\n\n\t\t\t\t// prompt text\n\t\t\t\t$prompt = $dataValidation->getPrompt() !== '' ?\n\t\t\t\t\t$dataValidation->getPrompt() : chr(0);\n\t\t\t\t$data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($prompt);\n\n\t\t\t\t// error text\n\t\t\t\t$error = $dataValidation->getError() !== '' ?\n\t\t\t\t\t$dataValidation->getError() : chr(0);\n\t\t\t\t$data .= PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($error);\n\n\t\t\t\t// formula 1\n\t\t\t\ttry {\n\t\t\t\t\t$formula1 = $dataValidation->getFormula1();\n\t\t\t\t\tif ($type == 0x03) { // list type\n\t\t\t\t\t\t$formula1 = str_replace(',', chr(0), $formula1);\n\t\t\t\t\t}\n\t\t\t\t\t$this->_parser->parse($formula1);\n\t\t\t\t\t$formula1 = $this->_parser->toReversePolish();\n\t\t\t\t\t$sz1 = strlen($formula1);\n\n\t\t\t\t} catch(PHPExcel_Exception $e) {\n\t\t\t\t\t$sz1 = 0;\n\t\t\t\t\t$formula1 = '';\n\t\t\t\t}\n\t\t\t\t$data .= pack('vv', $sz1, 0x0000);\n\t\t\t\t$data .= $formula1;\n\n\t\t\t\t// formula 2\n\t\t\t\ttry {\n\t\t\t\t\t$formula2 = $dataValidation->getFormula2();\n\t\t\t\t\tif ($formula2 === '') {\n\t\t\t\t\t\tthrow new PHPExcel_Writer_Exception('No formula2');\n\t\t\t\t\t}\n\t\t\t\t\t$this->_parser->parse($formula2);\n\t\t\t\t\t$formula2 = $this->_parser->toReversePolish();\n\t\t\t\t\t$sz2 = strlen($formula2);\n\n\t\t\t\t} catch(PHPExcel_Exception $e) {\n\t\t\t\t\t$sz2 = 0;\n\t\t\t\t\t$formula2 = '';\n\t\t\t\t}\n\t\t\t\t$data .= pack('vv', $sz2, 0x0000);\n\t\t\t\t$data .= $formula2;\n\n\t\t\t\t// cell range address list\n\t\t\t\t$data .= pack('v', 0x0001);\n\t\t\t\t$data .= $this->_writeBIFF8CellRangeAddressFixed($cellCoordinate);\n\n\t\t\t\t$length = strlen($data);\n\t\t\t$header = pack(\"vv\", $record, $length);\n\n\t\t\t\t$this->_append($header . $data);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Map Error code\n\t *\n\t * @param string $errorCode\n\t * @return int\n\t */\n\tprivate static function _mapErrorCode($errorCode) {\n\t\tswitch ($errorCode) {\n\t\t\tcase '#NULL!':\treturn 0x00;\n\t\t\tcase '#DIV/0!':\treturn 0x07;\n\t\t\tcase '#VALUE!':\treturn 0x0F;\n\t\t\tcase '#REF!':\treturn 0x17;\n\t\t\tcase '#NAME?':\treturn 0x1D;\n\t\t\tcase '#NUM!':\treturn 0x24;\n\t\t\tcase '#N/A':\treturn 0x2A;\n\t\t}\n\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Write PLV Record\n\t */\n\tprivate function _writePageLayoutView(){\n\t\t$record\t  = 0x088B;\t\t\t   // Record identifier\n\t\t$length\t  = 0x0010;\t\t\t   // Bytes to follow\n\n\t\t$rt         = 0x088B; // 2\n\t\t$grbitFrt   = 0x0000; // 2\n\t\t$reserved   = 0x0000000000000000; // 8\n\t\t$wScalvePLV = $this->_phpSheet->getSheetView()->getZoomScale(); // 2\n\n\t\t// The options flags that comprise $grbit\n\t\tif($this->_phpSheet->getSheetView()->getView() == PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT){\n\t\t\t$fPageLayoutView   = 1;\n\t\t} else {\n\t\t\t$fPageLayoutView   = 0;\n\t\t}\n\t\t$fRulerVisible     = 0;\n\t\t$fWhitespaceHidden = 0;\n\n\t\t$grbit      = $fPageLayoutView; // 2\n\t\t$grbit\t\t|= $fRulerVisible\t   << 1;\n\t\t$grbit\t\t|= $fWhitespaceHidden  << 3;\n\n\t\t$header\t  = pack(\"vv\", $record, $length);\n\t\t$data\t  = pack(\"vvVVvv\", $rt, $grbitFrt, 0x00000000, 0x00000000, $wScalvePLV, $grbit);\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write CFRule Record\n\t * @param PHPExcel_Style_Conditional $conditional\n\t */\n\tprivate function _writeCFRule(PHPExcel_Style_Conditional $conditional){\n\t\t$record\t  = 0x01B1;\t\t\t   // Record identifier\n\n\t\t// $type : Type of the CF\n\t\t// $operatorType : Comparison operator\n\t\tif($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION){\n\t\t\t$type = 0x02;\n\t\t\t$operatorType = 0x00;\n\t\t} else if($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){\n\t\t\t$type = 0x01;\n\n\t\t\tswitch ($conditional->getOperatorType()){\n\t\t\t\tcase PHPExcel_Style_Conditional::OPERATOR_NONE:\n\t\t\t\t\t$operatorType = 0x00;\n\t\t\t\t\tbreak;\n\t\t\t\tcase PHPExcel_Style_Conditional::OPERATOR_EQUAL:\n\t\t\t\t\t$operatorType = 0x03;\n\t\t\t\t\tbreak;\n\t\t\t\tcase PHPExcel_Style_Conditional::OPERATOR_GREATERTHAN:\n\t\t\t\t\t$operatorType = 0x05;\n\t\t\t\t\tbreak;\n\t\t\t\tcase PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL:\n\t\t\t\t\t$operatorType = 0x07;\n\t\t\t\t\tbreak;\n\t\t\t\tcase PHPExcel_Style_Conditional::OPERATOR_LESSTHAN:\n\t\t\t\t\t$operatorType = 0x06;\n\t\t\t\t\tbreak;\n\t\t\t\tcase PHPExcel_Style_Conditional::OPERATOR_LESSTHANOREQUAL:\n\t\t\t\t\t$operatorType = 0x08;\n\t\t\t\t\tbreak;\n\t\t\t\tcase PHPExcel_Style_Conditional::OPERATOR_NOTEQUAL:\n\t\t\t\t\t$operatorType = 0x04;\n\t\t\t\t\tbreak;\n\t\t\t\tcase PHPExcel_Style_Conditional::OPERATOR_BETWEEN:\n\t\t\t\t\t$operatorType = 0x01;\n\t\t\t\t\tbreak;\n\t\t\t\t\t// not OPERATOR_NOTBETWEEN 0x02\n\t\t\t}\n\t\t}\n\n\t\t// $szValue1 : size of the formula data for first value or formula\n\t\t// $szValue2 : size of the formula data for second value or formula\n\t\t$arrConditions = $conditional->getConditions();\n\t\t$numConditions = sizeof($arrConditions);\n\t\tif($numConditions == 1){\n\t\t\t$szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000);\n\t\t\t$szValue2 = 0x0000;\n\t\t\t$operand1 = pack('Cv', 0x1E, $arrConditions[0]);\n\t\t\t$operand2 = null;\n\t\t} else if($numConditions == 2 && ($conditional->getOperatorType() == PHPExcel_Style_Conditional::OPERATOR_BETWEEN)){\n\t\t\t$szValue1 = ($arrConditions[0] <= 65535 ? 3 : 0x0000);\n\t\t\t$szValue2 = ($arrConditions[1] <= 65535 ? 3 : 0x0000);\n\t\t\t$operand1 = pack('Cv', 0x1E, $arrConditions[0]);\n\t\t\t$operand2 = pack('Cv', 0x1E, $arrConditions[1]);\n\t\t} else {\n\t\t\t$szValue1 = 0x0000;\n\t\t\t$szValue2 = 0x0000;\n\t\t\t$operand1 = null;\n\t\t\t$operand2 = null;\n\t\t}\n\n\t\t// $flags : Option flags\n\t\t// Alignment\n\t\t$bAlignHz = ($conditional->getStyle()->getAlignment()->getHorizontal() == null ? 1 : 0);\n\t\t$bAlignVt = ($conditional->getStyle()->getAlignment()->getVertical() == null ? 1 : 0);\n\t\t$bAlignWrapTx = ($conditional->getStyle()->getAlignment()->getWrapText() == false ? 1 : 0);\n\t\t$bTxRotation = ($conditional->getStyle()->getAlignment()->getTextRotation() == null ? 1 : 0);\n\t\t$bIndent = ($conditional->getStyle()->getAlignment()->getIndent() == 0 ? 1 : 0);\n\t\t$bShrinkToFit = ($conditional->getStyle()->getAlignment()->getShrinkToFit() == false ? 1 : 0);\n\t\tif($bAlignHz == 0 || $bAlignVt == 0 || $bAlignWrapTx == 0 || $bTxRotation == 0 || $bIndent == 0 || $bShrinkToFit == 0){\n\t\t\t$bFormatAlign = 1;\n\t\t} else {\n\t\t\t$bFormatAlign = 0;\n\t\t}\n\t\t// Protection\n\t\t$bProtLocked = ($conditional->getStyle()->getProtection()->getLocked() == null ? 1 : 0);\n\t\t$bProtHidden = ($conditional->getStyle()->getProtection()->getHidden() == null ? 1 : 0);\n\t\tif($bProtLocked == 0 || $bProtHidden == 0){\n\t\t\t$bFormatProt = 1;\n\t\t} else {\n\t\t\t$bFormatProt = 0;\n\t\t}\n\t\t// Border\n\t\t$bBorderLeft = ($conditional->getStyle()->getBorders()->getLeft()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK\n\t\t\t\t\t\t&& $conditional->getStyle()->getBorders()->getLeft()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0);\n\t\t$bBorderRight = ($conditional->getStyle()->getBorders()->getRight()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK\n\t\t\t\t\t\t&& $conditional->getStyle()->getBorders()->getRight()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0);\n\t\t$bBorderTop = ($conditional->getStyle()->getBorders()->getTop()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK\n\t\t\t\t\t\t&& $conditional->getStyle()->getBorders()->getTop()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0);\n\t\t$bBorderBottom = ($conditional->getStyle()->getBorders()->getBottom()->getColor()->getARGB() == PHPExcel_Style_Color::COLOR_BLACK\n\t\t\t\t\t\t&& $conditional->getStyle()->getBorders()->getBottom()->getBorderStyle() == PHPExcel_Style_Border::BORDER_NONE ? 1 : 0);\n\t\tif($bBorderLeft == 0 || $bBorderRight == 0 || $bBorderTop == 0 || $bBorderBottom == 0){\n\t\t\t$bFormatBorder = 1;\n\t\t} else {\n\t\t\t$bFormatBorder = 0;\n\t\t}\n\t\t// Pattern\n\t\t$bFillStyle = ($conditional->getStyle()->getFill()->getFillType() == null ? 0 : 1);\n\t\t$bFillColor = ($conditional->getStyle()->getFill()->getStartColor()->getARGB() == null ? 0 : 1);\n\t\t$bFillColorBg = ($conditional->getStyle()->getFill()->getEndColor()->getARGB() == null ? 0 : 1);\n\t\tif($bFillStyle == 0 || $bFillColor == 0 || $bFillColorBg == 0){\n\t\t\t$bFormatFill = 1;\n\t\t} else {\n\t\t\t$bFormatFill = 0;\n\t\t}\n\t\t// Font\n\t\tif($conditional->getStyle()->getFont()->getName() != null\n\t\t\t|| $conditional->getStyle()->getFont()->getSize() != null\n\t\t\t|| $conditional->getStyle()->getFont()->getBold() != null\n\t\t\t|| $conditional->getStyle()->getFont()->getItalic() != null\n\t\t\t|| $conditional->getStyle()->getFont()->getSuperScript() != null\n\t\t\t|| $conditional->getStyle()->getFont()->getSubScript() != null\n\t\t\t|| $conditional->getStyle()->getFont()->getUnderline() != null\n\t\t\t|| $conditional->getStyle()->getFont()->getStrikethrough() != null\n\t\t\t|| $conditional->getStyle()->getFont()->getColor()->getARGB() != null){\n\t\t\t$bFormatFont = 1;\n\t\t} else {\n\t\t\t$bFormatFont = 0;\n\t\t}\n\t\t// Alignment\n\t\t$flags = 0;\n\t\t$flags |= (1 == $bAlignHz      ? 0x00000001 : 0);\n\t\t$flags |= (1 == $bAlignVt      ? 0x00000002 : 0);\n\t\t$flags |= (1 == $bAlignWrapTx  ? 0x00000004 : 0);\n\t\t$flags |= (1 == $bTxRotation   ? 0x00000008 : 0);\n\t\t// Justify last line flag\n\t\t$flags |= (1 == 1              ? 0x00000010 : 0);\n\t\t$flags |= (1 == $bIndent       ? 0x00000020 : 0);\n\t\t$flags |= (1 == $bShrinkToFit  ? 0x00000040 : 0);\n\t\t// Default\n\t\t$flags |= (1 == 1              ? 0x00000080 : 0);\n\t\t// Protection\n\t\t$flags |= (1 == $bProtLocked   ? 0x00000100 : 0);\n\t\t$flags |= (1 == $bProtHidden   ? 0x00000200 : 0);\n\t\t// Border\n\t\t$flags |= (1 == $bBorderLeft   ? 0x00000400 : 0);\n\t\t$flags |= (1 == $bBorderRight  ? 0x00000800 : 0);\n\t\t$flags |= (1 == $bBorderTop    ? 0x00001000 : 0);\n\t\t$flags |= (1 == $bBorderBottom ? 0x00002000 : 0);\n\t\t$flags |= (1 == 1              ? 0x00004000 : 0); // Top left to Bottom right border\n\t\t$flags |= (1 == 1              ? 0x00008000 : 0); // Bottom left to Top right border\n\t\t// Pattern\n\t\t$flags |= (1 == $bFillStyle    ? 0x00010000 : 0);\n\t\t$flags |= (1 == $bFillColor    ? 0x00020000 : 0);\n\t\t$flags |= (1 == $bFillColorBg  ? 0x00040000 : 0);\n\t\t$flags |= (1 == 1              ? 0x00380000 : 0);\n\t\t// Font\n\t\t$flags |= (1 == $bFormatFont   ? 0x04000000 : 0);\n\t    // Alignment :\n\t\t$flags |= (1 == $bFormatAlign  ? 0x08000000 : 0);\n\t\t// Border\n\t\t$flags |= (1 == $bFormatBorder ? 0x10000000 : 0);\n\t\t// Pattern\n\t\t$flags |= (1 == $bFormatFill   ? 0x20000000 : 0);\n\t\t// Protection\n\t\t$flags |= (1 == $bFormatProt   ? 0x40000000 : 0);\n\t\t// Text direction\n\t\t$flags |= (1 == 0              ? 0x80000000 : 0);\n\n\t\t// Data Blocks\n\t\tif($bFormatFont == 1){\n\t\t\t// Font Name\n\t\t\tif($conditional->getStyle()->getFont()->getName() == null){\n\t\t\t\t$dataBlockFont =  pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000);\n\t\t\t\t$dataBlockFont .= pack('VVVVVVVV', 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000);\n\t\t\t} else {\n\t\t\t\t$dataBlockFont = PHPExcel_Shared_String::UTF8toBIFF8UnicodeLong($conditional->getStyle()->getFont()->getName());\n\t\t\t}\n\t\t\t// Font Size\n\t\t\tif($conditional->getStyle()->getFont()->getSize() == null){\n\t\t\t\t$dataBlockFont .= pack('V', 20 * 11);\n\t\t\t} else {\n\t\t\t\t$dataBlockFont .= pack('V', 20 * $conditional->getStyle()->getFont()->getSize());\n\t\t\t}\n\t\t\t// Font Options\n\t\t\t$dataBlockFont .= pack('V', 0);\n\t\t\t// Font weight\n\t\t\tif($conditional->getStyle()->getFont()->getBold() == true){\n\t\t\t\t$dataBlockFont .= pack('v', 0x02BC);\n\t\t\t} else {\n\t\t\t\t$dataBlockFont .= pack('v', 0x0190);\n\t\t\t}\n\t\t\t// Escapement type\n\t\t\tif($conditional->getStyle()->getFont()->getSubScript() == true){\n\t\t\t\t$dataBlockFont .= pack('v', 0x02);\n\t\t\t\t$fontEscapement = 0;\n\t\t\t} else if($conditional->getStyle()->getFont()->getSuperScript() == true){\n\t\t\t\t$dataBlockFont .= pack('v', 0x01);\n\t\t\t\t$fontEscapement = 0;\n\t\t\t} else {\n\t\t\t\t$dataBlockFont .= pack('v', 0x00);\n\t\t\t\t$fontEscapement = 1;\n\t\t\t}\n\t\t\t// Underline type\n\t\t\tswitch ($conditional->getStyle()->getFont()->getUnderline()){\n\t\t\t\tcase PHPExcel_Style_Font::UNDERLINE_NONE             : $dataBlockFont .= pack('C', 0x00); $fontUnderline = 0; break;\n\t\t\t\tcase PHPExcel_Style_Font::UNDERLINE_DOUBLE           : $dataBlockFont .= pack('C', 0x02); $fontUnderline = 0; break;\n\t\t\t\tcase PHPExcel_Style_Font::UNDERLINE_DOUBLEACCOUNTING : $dataBlockFont .= pack('C', 0x22); $fontUnderline = 0; break;\n\t\t\t\tcase PHPExcel_Style_Font::UNDERLINE_SINGLE           : $dataBlockFont .= pack('C', 0x01); $fontUnderline = 0; break;\n\t\t\t\tcase PHPExcel_Style_Font::UNDERLINE_SINGLEACCOUNTING : $dataBlockFont .= pack('C', 0x21); $fontUnderline = 0; break;\n\t\t\t\tdefault                                              : $dataBlockFont .= pack('C', 0x00); $fontUnderline = 1; break;\n\t\t\t}\n\t\t\t// Not used (3)\n\t\t\t$dataBlockFont .= pack('vC', 0x0000, 0x00);\n\t\t\t// Font color index\n\t\t\tswitch ($conditional->getStyle()->getFont()->getColor()->getRGB()) {\n\t\t\t\tcase '000000': $colorIdx = 0x08; break;\n\t\t\t\tcase 'FFFFFF': $colorIdx = 0x09; break;\n\t\t\t\tcase 'FF0000': $colorIdx = 0x0A; break;\n\t\t\t\tcase '00FF00': $colorIdx = 0x0B; break;\n\t\t\t\tcase '0000FF': $colorIdx = 0x0C; break;\n\t\t\t\tcase 'FFFF00': $colorIdx = 0x0D; break;\n\t\t\t\tcase 'FF00FF': $colorIdx = 0x0E; break;\n\t\t\t\tcase '00FFFF': $colorIdx = 0x0F; break;\n\t\t\t\tcase '800000': $colorIdx = 0x10; break;\n\t\t\t\tcase '008000': $colorIdx = 0x11; break;\n\t\t\t\tcase '000080': $colorIdx = 0x12; break;\n\t\t\t\tcase '808000': $colorIdx = 0x13; break;\n\t\t\t\tcase '800080': $colorIdx = 0x14; break;\n\t\t\t\tcase '008080': $colorIdx = 0x15; break;\n\t\t\t\tcase 'C0C0C0': $colorIdx = 0x16; break;\n\t\t\t\tcase '808080': $colorIdx = 0x17; break;\n\t\t\t\tcase '9999FF': $colorIdx = 0x18; break;\n\t\t\t\tcase '993366': $colorIdx = 0x19; break;\n\t\t\t\tcase 'FFFFCC': $colorIdx = 0x1A; break;\n\t\t\t\tcase 'CCFFFF': $colorIdx = 0x1B; break;\n\t\t\t\tcase '660066': $colorIdx = 0x1C; break;\n\t\t\t\tcase 'FF8080': $colorIdx = 0x1D; break;\n\t\t\t\tcase '0066CC': $colorIdx = 0x1E; break;\n\t\t\t\tcase 'CCCCFF': $colorIdx = 0x1F; break;\n\t\t\t\tcase '000080': $colorIdx = 0x20; break;\n\t\t\t\tcase 'FF00FF': $colorIdx = 0x21; break;\n\t\t\t\tcase 'FFFF00': $colorIdx = 0x22; break;\n\t\t\t\tcase '00FFFF': $colorIdx = 0x23; break;\n\t\t\t\tcase '800080': $colorIdx = 0x24; break;\n\t\t\t\tcase '800000': $colorIdx = 0x25; break;\n\t\t\t\tcase '008080': $colorIdx = 0x26; break;\n\t\t\t\tcase '0000FF': $colorIdx = 0x27; break;\n\t\t\t\tcase '00CCFF': $colorIdx = 0x28; break;\n\t\t\t\tcase 'CCFFFF': $colorIdx = 0x29; break;\n\t\t\t\tcase 'CCFFCC': $colorIdx = 0x2A; break;\n\t\t\t\tcase 'FFFF99': $colorIdx = 0x2B; break;\n\t\t\t\tcase '99CCFF': $colorIdx = 0x2C; break;\n\t\t\t\tcase 'FF99CC': $colorIdx = 0x2D; break;\n\t\t\t\tcase 'CC99FF': $colorIdx = 0x2E; break;\n\t\t\t\tcase 'FFCC99': $colorIdx = 0x2F; break;\n\t\t\t\tcase '3366FF': $colorIdx = 0x30; break;\n\t\t\t\tcase '33CCCC': $colorIdx = 0x31; break;\n\t\t\t\tcase '99CC00': $colorIdx = 0x32; break;\n\t\t\t\tcase 'FFCC00': $colorIdx = 0x33; break;\n\t\t\t\tcase 'FF9900': $colorIdx = 0x34; break;\n\t\t\t\tcase 'FF6600': $colorIdx = 0x35; break;\n\t\t\t\tcase '666699': $colorIdx = 0x36; break;\n\t\t\t\tcase '969696': $colorIdx = 0x37; break;\n\t\t\t\tcase '003366': $colorIdx = 0x38; break;\n\t\t\t\tcase '339966': $colorIdx = 0x39; break;\n\t\t\t\tcase '003300': $colorIdx = 0x3A; break;\n\t\t\t\tcase '333300': $colorIdx = 0x3B; break;\n\t\t\t\tcase '993300': $colorIdx = 0x3C; break;\n\t\t\t\tcase '993366': $colorIdx = 0x3D; break;\n\t\t\t\tcase '333399': $colorIdx = 0x3E; break;\n\t\t\t\tcase '333333': $colorIdx = 0x3F; break;\n\t\t\t\tdefault: $colorIdx = 0x00; break;\n\t\t\t}\n\t\t\t$dataBlockFont .= pack('V', $colorIdx);\n\t\t\t// Not used (4)\n\t\t\t$dataBlockFont .= pack('V', 0x00000000);\n\t\t\t// Options flags for modified font attributes\n\t\t\t$optionsFlags = 0;\n\t\t\t$optionsFlagsBold = ($conditional->getStyle()->getFont()->getBold() == null ? 1 : 0);\n\t\t\t$optionsFlags |= (1 == $optionsFlagsBold  ? 0x00000002 : 0);\n\t\t\t$optionsFlags |= (1 == 1                  ? 0x00000008 : 0);\n\t\t\t$optionsFlags |= (1 == 1                  ? 0x00000010 : 0);\n\t\t\t$optionsFlags |= (1 == 0                  ? 0x00000020 : 0);\n\t\t\t$optionsFlags |= (1 == 1                  ? 0x00000080 : 0);\n\t\t\t$dataBlockFont .= pack('V', $optionsFlags);\n\t\t\t// Escapement type\n\t\t\t$dataBlockFont .= pack('V', $fontEscapement);\n\t\t\t// Underline type\n\t\t\t$dataBlockFont .= pack('V', $fontUnderline);\n\t\t\t// Always\n\t\t\t$dataBlockFont .= pack('V', 0x00000000);\n\t\t\t// Always\n\t\t\t$dataBlockFont .= pack('V', 0x00000000);\n\t\t\t// Not used (8)\n\t\t\t$dataBlockFont .= pack('VV', 0x00000000, 0x00000000);\n\t\t\t// Always\n\t\t\t$dataBlockFont .= pack('v', 0x0001);\n\t\t}\n\t\tif($bFormatAlign == 1){\n\t\t\t$blockAlign = 0;\n\t\t\t// Alignment and text break\n\t\t\tswitch ($conditional->getStyle()->getAlignment()->getHorizontal()){\n\t\t\t\tcase PHPExcel_Style_Alignment::HORIZONTAL_GENERAL \t\t\t: $blockAlign = 0; break;\n\t\t\t\tcase PHPExcel_Style_Alignment::HORIZONTAL_LEFT\t\t\t\t: $blockAlign = 1; break;\n\t\t\t\tcase PHPExcel_Style_Alignment::HORIZONTAL_RIGHT\t\t\t\t: $blockAlign = 3; break;\n\t\t\t\tcase PHPExcel_Style_Alignment::HORIZONTAL_CENTER\t\t\t: $blockAlign = 2; break;\n\t\t\t\tcase PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS\t: $blockAlign = 6; break;\n\t\t\t\tcase PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY\t\t\t: $blockAlign = 5; break;\n\t\t\t}\n\t\t\tif($conditional->getStyle()->getAlignment()->getWrapText() == true){\n\t\t\t\t$blockAlign |= 1 << 3;\n\t\t\t} else {\n\t\t\t\t$blockAlign |= 0 << 3;\n\t\t\t}\n\t\t\tswitch ($conditional->getStyle()->getAlignment()->getVertical()){\n\t\t\t\tcase PHPExcel_Style_Alignment::VERTICAL_BOTTOM \t\t\t\t: $blockAlign = 2 << 4; break;\n\t\t\t\tcase PHPExcel_Style_Alignment::VERTICAL_TOP\t\t\t\t\t: $blockAlign = 0 << 4; break;\n\t\t\t\tcase PHPExcel_Style_Alignment::VERTICAL_CENTER\t\t\t\t: $blockAlign = 1 << 4; break;\n\t\t\t\tcase PHPExcel_Style_Alignment::VERTICAL_JUSTIFY\t\t\t\t: $blockAlign = 3 << 4; break;\n\t\t\t}\n\t\t\t$blockAlign |= 0 << 7;\n\n\t\t\t// Text rotation angle\n\t\t\t$blockRotation = $conditional->getStyle()->getAlignment()->getTextRotation();\n\n\t\t\t// Indentation\n\t\t\t$blockIndent = $conditional->getStyle()->getAlignment()->getIndent();\n\t\t\tif($conditional->getStyle()->getAlignment()->getShrinkToFit() == true){\n\t\t\t\t$blockIndent |= 1 << 4;\n\t\t\t} else {\n\t\t\t\t$blockIndent |= 0 << 4;\n\t\t\t}\n\t\t\t$blockIndent |= 0 << 6;\n\n\t\t\t// Relative indentation\n\t\t\t$blockIndentRelative = 255;\n\n\t\t\t$dataBlockAlign = pack('CCvvv', $blockAlign, $blockRotation, $blockIndent, $blockIndentRelative, 0x0000);\n\t\t}\n\t\tif($bFormatBorder == 1){\n\t\t\t$blockLineStyle = 0;\n\t\t\tswitch ($conditional->getStyle()->getBorders()->getLeft()->getBorderStyle()){\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_NONE              : $blockLineStyle |= 0x00; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_THIN              : $blockLineStyle |= 0x01; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUM            : $blockLineStyle |= 0x02; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHED            : $blockLineStyle |= 0x03; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DOTTED            : $blockLineStyle |= 0x04; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_THICK             : $blockLineStyle |= 0x05; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DOUBLE            : $blockLineStyle |= 0x06; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_HAIR              : $blockLineStyle |= 0x07; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHED      : $blockLineStyle |= 0x08; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHDOT           : $blockLineStyle |= 0x09; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT     : $blockLineStyle |= 0x0A; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHDOTDOT        : $blockLineStyle |= 0x0B; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT  : $blockLineStyle |= 0x0C; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_SLANTDASHDOT      : $blockLineStyle |= 0x0D; break;\n\t\t\t}\n\t\t\tswitch ($conditional->getStyle()->getBorders()->getRight()->getBorderStyle()){\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_NONE              : $blockLineStyle |= 0x00 << 4; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_THIN              : $blockLineStyle |= 0x01 << 4; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUM            : $blockLineStyle |= 0x02 << 4; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHED            : $blockLineStyle |= 0x03 << 4; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DOTTED            : $blockLineStyle |= 0x04 << 4; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_THICK             : $blockLineStyle |= 0x05 << 4; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DOUBLE            : $blockLineStyle |= 0x06 << 4; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_HAIR              : $blockLineStyle |= 0x07 << 4; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHED      : $blockLineStyle |= 0x08 << 4; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHDOT           : $blockLineStyle |= 0x09 << 4; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT     : $blockLineStyle |= 0x0A << 4; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHDOTDOT        : $blockLineStyle |= 0x0B << 4; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT  : $blockLineStyle |= 0x0C << 4; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_SLANTDASHDOT      : $blockLineStyle |= 0x0D << 4; break;\n\t\t\t}\n\t\t\tswitch ($conditional->getStyle()->getBorders()->getTop()->getBorderStyle()){\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_NONE              : $blockLineStyle |= 0x00 << 8; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_THIN              : $blockLineStyle |= 0x01 << 8; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUM            : $blockLineStyle |= 0x02 << 8; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHED            : $blockLineStyle |= 0x03 << 8; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DOTTED            : $blockLineStyle |= 0x04 << 8; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_THICK             : $blockLineStyle |= 0x05 << 8; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DOUBLE            : $blockLineStyle |= 0x06 << 8; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_HAIR              : $blockLineStyle |= 0x07 << 8; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHED      : $blockLineStyle |= 0x08 << 8; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHDOT           : $blockLineStyle |= 0x09 << 8; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT     : $blockLineStyle |= 0x0A << 8; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHDOTDOT        : $blockLineStyle |= 0x0B << 8; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT  : $blockLineStyle |= 0x0C << 8; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_SLANTDASHDOT      : $blockLineStyle |= 0x0D << 8; break;\n\t\t\t}\n\t\t\tswitch ($conditional->getStyle()->getBorders()->getBottom()->getBorderStyle()){\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_NONE              : $blockLineStyle |= 0x00 << 12; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_THIN              : $blockLineStyle |= 0x01 << 12; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUM            : $blockLineStyle |= 0x02 << 12; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHED            : $blockLineStyle |= 0x03 << 12; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DOTTED            : $blockLineStyle |= 0x04 << 12; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_THICK             : $blockLineStyle |= 0x05 << 12; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DOUBLE            : $blockLineStyle |= 0x06 << 12; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_HAIR              : $blockLineStyle |= 0x07 << 12; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHED      : $blockLineStyle |= 0x08 << 12; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHDOT           : $blockLineStyle |= 0x09 << 12; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT     : $blockLineStyle |= 0x0A << 12; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHDOTDOT        : $blockLineStyle |= 0x0B << 12; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT  : $blockLineStyle |= 0x0C << 12; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_SLANTDASHDOT      : $blockLineStyle |= 0x0D << 12; break;\n\t\t\t}\n\t\t\t//@todo _writeCFRule() => $blockLineStyle => Index Color for left line\n\t\t\t//@todo _writeCFRule() => $blockLineStyle => Index Color for right line\n\t\t\t//@todo _writeCFRule() => $blockLineStyle => Top-left to bottom-right on/off\n\t\t\t//@todo _writeCFRule() => $blockLineStyle => Bottom-left to top-right on/off\n\t\t\t$blockColor = 0;\n\t\t\t//@todo _writeCFRule() => $blockColor => Index Color for top line\n\t\t\t//@todo _writeCFRule() => $blockColor => Index Color for bottom line\n\t\t\t//@todo _writeCFRule() => $blockColor => Index Color for diagonal line\n\t\t\tswitch ($conditional->getStyle()->getBorders()->getDiagonal()->getBorderStyle()){\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_NONE              : $blockColor |= 0x00 << 21; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_THIN              : $blockColor |= 0x01 << 21; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUM            : $blockColor |= 0x02 << 21; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHED            : $blockColor |= 0x03 << 21; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DOTTED            : $blockColor |= 0x04 << 21; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_THICK             : $blockColor |= 0x05 << 21; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DOUBLE            : $blockColor |= 0x06 << 21; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_HAIR              : $blockColor |= 0x07 << 21; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHED      : $blockColor |= 0x08 << 21; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHDOT           : $blockColor |= 0x09 << 21; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT     : $blockColor |= 0x0A << 21; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_DASHDOTDOT        : $blockColor |= 0x0B << 21; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT  : $blockColor |= 0x0C << 21; break;\n\t\t\t\tcase PHPExcel_Style_Border::BORDER_SLANTDASHDOT      : $blockColor |= 0x0D << 21; break;\n\t\t\t}\n\t\t\t$dataBlockBorder = pack('vv', $blockLineStyle, $blockColor);\n\t\t}\n\t\tif($bFormatFill == 1){\n\t\t\t// Fill Patern Style\n\t\t\t$blockFillPatternStyle = 0;\n\t\t\tswitch ($conditional->getStyle()->getFill()->getFillType()){\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_NONE\t\t\t\t\t\t: $blockFillPatternStyle = 0x00; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_SOLID\t\t\t\t\t: $blockFillPatternStyle = 0x01; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY\t\t: $blockFillPatternStyle = 0x02; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY\t\t\t: $blockFillPatternStyle = 0x03; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY\t\t: $blockFillPatternStyle = 0x04; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL\t: $blockFillPatternStyle = 0x05; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL\t\t: $blockFillPatternStyle = 0x06; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN\t\t\t: $blockFillPatternStyle = 0x07; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_DARKUP\t\t\t: $blockFillPatternStyle = 0x08; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID\t\t\t: $blockFillPatternStyle = 0x09; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS\t\t: $blockFillPatternStyle = 0x0A; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL\t: $blockFillPatternStyle = 0x0B; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL\t: $blockFillPatternStyle = 0x0C; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN\t\t: $blockFillPatternStyle = 0x0D; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP\t\t\t: $blockFillPatternStyle = 0x0E; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID\t\t: $blockFillPatternStyle = 0x0F; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS\t\t: $blockFillPatternStyle = 0x10; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_GRAY125\t\t\t: $blockFillPatternStyle = 0x11; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625\t\t\t: $blockFillPatternStyle = 0x12; break;\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR\t\t\t: $blockFillPatternStyle = 0x00; break;\t// does not exist in BIFF8\n\t\t\t\tcase PHPExcel_Style_Fill::FILL_GRADIENT_PATH\t\t\t: $blockFillPatternStyle = 0x00; break;\t// does not exist in BIFF8\n\t\t\t\tdefault                                                 : $blockFillPatternStyle = 0x00; break;\n\t\t\t}\n\t\t\t// Color\n\t\t\tswitch ($conditional->getStyle()->getFill()->getStartColor()->getRGB()) {\n\t\t\t\tcase '000000': $colorIdxBg = 0x08; break;\n\t\t\t\tcase 'FFFFFF': $colorIdxBg = 0x09; break;\n\t\t\t\tcase 'FF0000': $colorIdxBg = 0x0A; break;\n\t\t\t\tcase '00FF00': $colorIdxBg = 0x0B; break;\n\t\t\t\tcase '0000FF': $colorIdxBg = 0x0C; break;\n\t\t\t\tcase 'FFFF00': $colorIdxBg = 0x0D; break;\n\t\t\t\tcase 'FF00FF': $colorIdxBg = 0x0E; break;\n\t\t\t\tcase '00FFFF': $colorIdxBg = 0x0F; break;\n\t\t\t\tcase '800000': $colorIdxBg = 0x10; break;\n\t\t\t\tcase '008000': $colorIdxBg = 0x11; break;\n\t\t\t\tcase '000080': $colorIdxBg = 0x12; break;\n\t\t\t\tcase '808000': $colorIdxBg = 0x13; break;\n\t\t\t\tcase '800080': $colorIdxBg = 0x14; break;\n\t\t\t\tcase '008080': $colorIdxBg = 0x15; break;\n\t\t\t\tcase 'C0C0C0': $colorIdxBg = 0x16; break;\n\t\t\t\tcase '808080': $colorIdxBg = 0x17; break;\n\t\t\t\tcase '9999FF': $colorIdxBg = 0x18; break;\n\t\t\t\tcase '993366': $colorIdxBg = 0x19; break;\n\t\t\t\tcase 'FFFFCC': $colorIdxBg = 0x1A; break;\n\t\t\t\tcase 'CCFFFF': $colorIdxBg = 0x1B; break;\n\t\t\t\tcase '660066': $colorIdxBg = 0x1C; break;\n\t\t\t\tcase 'FF8080': $colorIdxBg = 0x1D; break;\n\t\t\t\tcase '0066CC': $colorIdxBg = 0x1E; break;\n\t\t\t\tcase 'CCCCFF': $colorIdxBg = 0x1F; break;\n\t\t\t\tcase '000080': $colorIdxBg = 0x20; break;\n\t\t\t\tcase 'FF00FF': $colorIdxBg = 0x21; break;\n\t\t\t\tcase 'FFFF00': $colorIdxBg = 0x22; break;\n\t\t\t\tcase '00FFFF': $colorIdxBg = 0x23; break;\n\t\t\t\tcase '800080': $colorIdxBg = 0x24; break;\n\t\t\t\tcase '800000': $colorIdxBg = 0x25; break;\n\t\t\t\tcase '008080': $colorIdxBg = 0x26; break;\n\t\t\t\tcase '0000FF': $colorIdxBg = 0x27; break;\n\t\t\t\tcase '00CCFF': $colorIdxBg = 0x28; break;\n\t\t\t\tcase 'CCFFFF': $colorIdxBg = 0x29; break;\n\t\t\t\tcase 'CCFFCC': $colorIdxBg = 0x2A; break;\n\t\t\t\tcase 'FFFF99': $colorIdxBg = 0x2B; break;\n\t\t\t\tcase '99CCFF': $colorIdxBg = 0x2C; break;\n\t\t\t\tcase 'FF99CC': $colorIdxBg = 0x2D; break;\n\t\t\t\tcase 'CC99FF': $colorIdxBg = 0x2E; break;\n\t\t\t\tcase 'FFCC99': $colorIdxBg = 0x2F; break;\n\t\t\t\tcase '3366FF': $colorIdxBg = 0x30; break;\n\t\t\t\tcase '33CCCC': $colorIdxBg = 0x31; break;\n\t\t\t\tcase '99CC00': $colorIdxBg = 0x32; break;\n\t\t\t\tcase 'FFCC00': $colorIdxBg = 0x33; break;\n\t\t\t\tcase 'FF9900': $colorIdxBg = 0x34; break;\n\t\t\t\tcase 'FF6600': $colorIdxBg = 0x35; break;\n\t\t\t\tcase '666699': $colorIdxBg = 0x36; break;\n\t\t\t\tcase '969696': $colorIdxBg = 0x37; break;\n\t\t\t\tcase '003366': $colorIdxBg = 0x38; break;\n\t\t\t\tcase '339966': $colorIdxBg = 0x39; break;\n\t\t\t\tcase '003300': $colorIdxBg = 0x3A; break;\n\t\t\t\tcase '333300': $colorIdxBg = 0x3B; break;\n\t\t\t\tcase '993300': $colorIdxBg = 0x3C; break;\n\t\t\t\tcase '993366': $colorIdxBg = 0x3D; break;\n\t\t\t\tcase '333399': $colorIdxBg = 0x3E; break;\n\t\t\t\tcase '333333': $colorIdxBg = 0x3F; break;\n\t\t\t\tdefault:       $colorIdxBg = 0x41; break;\n\t\t\t}\n\t\t\t// Fg Color\n\t\t\tswitch ($conditional->getStyle()->getFill()->getEndColor()->getRGB()) {\n\t\t\t\tcase '000000': $colorIdxFg = 0x08; break;\n\t\t\t\tcase 'FFFFFF': $colorIdxFg = 0x09; break;\n\t\t\t\tcase 'FF0000': $colorIdxFg = 0x0A; break;\n\t\t\t\tcase '00FF00': $colorIdxFg = 0x0B; break;\n\t\t\t\tcase '0000FF': $colorIdxFg = 0x0C; break;\n\t\t\t\tcase 'FFFF00': $colorIdxFg = 0x0D; break;\n\t\t\t\tcase 'FF00FF': $colorIdxFg = 0x0E; break;\n\t\t\t\tcase '00FFFF': $colorIdxFg = 0x0F; break;\n\t\t\t\tcase '800000': $colorIdxFg = 0x10; break;\n\t\t\t\tcase '008000': $colorIdxFg = 0x11; break;\n\t\t\t\tcase '000080': $colorIdxFg = 0x12; break;\n\t\t\t\tcase '808000': $colorIdxFg = 0x13; break;\n\t\t\t\tcase '800080': $colorIdxFg = 0x14; break;\n\t\t\t\tcase '008080': $colorIdxFg = 0x15; break;\n\t\t\t\tcase 'C0C0C0': $colorIdxFg = 0x16; break;\n\t\t\t\tcase '808080': $colorIdxFg = 0x17; break;\n\t\t\t\tcase '9999FF': $colorIdxFg = 0x18; break;\n\t\t\t\tcase '993366': $colorIdxFg = 0x19; break;\n\t\t\t\tcase 'FFFFCC': $colorIdxFg = 0x1A; break;\n\t\t\t\tcase 'CCFFFF': $colorIdxFg = 0x1B; break;\n\t\t\t\tcase '660066': $colorIdxFg = 0x1C; break;\n\t\t\t\tcase 'FF8080': $colorIdxFg = 0x1D; break;\n\t\t\t\tcase '0066CC': $colorIdxFg = 0x1E; break;\n\t\t\t\tcase 'CCCCFF': $colorIdxFg = 0x1F; break;\n\t\t\t\tcase '000080': $colorIdxFg = 0x20; break;\n\t\t\t\tcase 'FF00FF': $colorIdxFg = 0x21; break;\n\t\t\t\tcase 'FFFF00': $colorIdxFg = 0x22; break;\n\t\t\t\tcase '00FFFF': $colorIdxFg = 0x23; break;\n\t\t\t\tcase '800080': $colorIdxFg = 0x24; break;\n\t\t\t\tcase '800000': $colorIdxFg = 0x25; break;\n\t\t\t\tcase '008080': $colorIdxFg = 0x26; break;\n\t\t\t\tcase '0000FF': $colorIdxFg = 0x27; break;\n\t\t\t\tcase '00CCFF': $colorIdxFg = 0x28; break;\n\t\t\t\tcase 'CCFFFF': $colorIdxFg = 0x29; break;\n\t\t\t\tcase 'CCFFCC': $colorIdxFg = 0x2A; break;\n\t\t\t\tcase 'FFFF99': $colorIdxFg = 0x2B; break;\n\t\t\t\tcase '99CCFF': $colorIdxFg = 0x2C; break;\n\t\t\t\tcase 'FF99CC': $colorIdxFg = 0x2D; break;\n\t\t\t\tcase 'CC99FF': $colorIdxFg = 0x2E; break;\n\t\t\t\tcase 'FFCC99': $colorIdxFg = 0x2F; break;\n\t\t\t\tcase '3366FF': $colorIdxFg = 0x30; break;\n\t\t\t\tcase '33CCCC': $colorIdxFg = 0x31; break;\n\t\t\t\tcase '99CC00': $colorIdxFg = 0x32; break;\n\t\t\t\tcase 'FFCC00': $colorIdxFg = 0x33; break;\n\t\t\t\tcase 'FF9900': $colorIdxFg = 0x34; break;\n\t\t\t\tcase 'FF6600': $colorIdxFg = 0x35; break;\n\t\t\t\tcase '666699': $colorIdxFg = 0x36; break;\n\t\t\t\tcase '969696': $colorIdxFg = 0x37; break;\n\t\t\t\tcase '003366': $colorIdxFg = 0x38; break;\n\t\t\t\tcase '339966': $colorIdxFg = 0x39; break;\n\t\t\t\tcase '003300': $colorIdxFg = 0x3A; break;\n\t\t\t\tcase '333300': $colorIdxFg = 0x3B; break;\n\t\t\t\tcase '993300': $colorIdxFg = 0x3C; break;\n\t\t\t\tcase '993366': $colorIdxFg = 0x3D; break;\n\t\t\t\tcase '333399': $colorIdxFg = 0x3E; break;\n\t\t\t\tcase '333333': $colorIdxFg = 0x3F; break;\n\t\t\t\tdefault:       $colorIdxFg = 0x40; break;\n\t\t\t}\n\t\t\t$dataBlockFill = pack('v', $blockFillPatternStyle);\n\t\t\t$dataBlockFill .= pack('v', $colorIdxFg | ($colorIdxBg << 7));\n\t\t}\n\t\tif($bFormatProt == 1){\n\t\t\t$dataBlockProtection = 0;\n\t\t\tif($conditional->getStyle()->getProtection()->getLocked() == PHPExcel_Style_Protection::PROTECTION_PROTECTED){\n\t\t\t\t$dataBlockProtection = 1;\n\t\t\t}\n\t\t\tif($conditional->getStyle()->getProtection()->getHidden() == PHPExcel_Style_Protection::PROTECTION_PROTECTED){\n\t\t\t\t$dataBlockProtection = 1 << 1;\n\t\t\t}\n\t\t}\n\n\t\t$data\t  = pack('CCvvVv', $type, $operatorType, $szValue1, $szValue2, $flags, 0x0000);\n\t\tif($bFormatFont == 1){ // Block Formatting : OK\n\t\t\t$data .= $dataBlockFont;\n\t\t}\n\t\tif($bFormatAlign == 1){\n\t\t\t$data .= $dataBlockAlign;\n\t\t}\n\t\tif($bFormatBorder == 1){\n\t\t\t$data .= $dataBlockBorder;\n\t\t}\n\t\tif($bFormatFill == 1){ // Block Formatting : OK\n\t\t\t$data .= $dataBlockFill;\n\t\t}\n\t\tif($bFormatProt == 1){\n\t\t\t$data .= $dataBlockProtection;\n\t\t}\n\t\tif(!is_null($operand1)){\n\t\t\t$data .= $operand1;\n\t\t}\n\t\tif(!is_null($operand2)){\n\t\t\t$data .= $operand2;\n\t\t}\n\t\t$header\t  = pack('vv', $record, strlen($data));\n\t\t$this->_append($header . $data);\n\t}\n\n\t/**\n\t * Write CFHeader record\n\t */\n\tprivate function _writeCFHeader(){\n\t\t$record\t  = 0x01B0;\t\t\t   // Record identifier\n\t\t$length\t  = 0x0016;\t\t\t   // Bytes to follow\n\n\t\t$numColumnMin = null;\n\t\t$numColumnMax = null;\n\t\t$numRowMin = null;\n\t\t$numRowMax = null;\n\t\t$arrConditional = array();\n\t\tforeach ($this->_phpSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {\n\t\t\tforeach ($conditionalStyles as $conditional) {\n\t\t\t\tif($conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_EXPRESSION\n\t\t\t\t\t\t|| $conditional->getConditionType() == PHPExcel_Style_Conditional::CONDITION_CELLIS){\n\t\t\t\t\tif(!in_array($conditional->getHashCode(), $arrConditional)){\n\t\t\t\t\t\t$arrConditional[] = $conditional->getHashCode();\n\t\t\t\t\t}\n\t\t\t\t\t// Cells\n\t\t\t\t\t$arrCoord = PHPExcel_Cell::coordinateFromString($cellCoordinate);\n\t\t\t\t\tif(!is_numeric($arrCoord[0])){\n\t\t\t\t\t\t$arrCoord[0] = PHPExcel_Cell::columnIndexFromString($arrCoord[0]);\n\t\t\t\t\t}\n\t\t\t\t\tif(is_null($numColumnMin) || ($numColumnMin > $arrCoord[0])){\n\t\t\t\t\t\t$numColumnMin = $arrCoord[0];\n\t\t\t\t\t}\n\t\t\t\t\tif(is_null($numColumnMax) || ($numColumnMax < $arrCoord[0])){\n\t\t\t\t\t\t$numColumnMax = $arrCoord[0];\n\t\t\t\t\t}\n\t\t\t\t\tif(is_null($numRowMin) || ($numRowMin > $arrCoord[1])){\n\t\t\t\t\t\t$numRowMin = $arrCoord[1];\n\t\t\t\t\t}\n\t\t\t\t\tif(is_null($numRowMax) || ($numRowMax < $arrCoord[1])){\n\t\t\t\t\t\t$numRowMax = $arrCoord[1];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t$needRedraw = 1;\n\t\t$cellRange = pack('vvvv', $numRowMin-1, $numRowMax-1, $numColumnMin-1, $numColumnMax-1);\n\n\t\t$header\t  = pack('vv', $record, $length);\n\t\t$data\t  = pack('vv', count($arrConditional), $needRedraw);\n\t\t$data     .= $cellRange;\n\t\t$data     .= pack('v', 0x0001);\n\t\t$data     .= $cellRange;\n\t\t$this->_append($header . $data);\n\t}\n}"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5/Xf.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n// Original file header of PEAR::Spreadsheet_Excel_Writer_Format (used as the base for this class):\n// -----------------------------------------------------------------------------------------\n// /*\n// *  Module written/ported by Xavier Noguer <xnoguer@rezebra.com>\n// *\n// *  The majority of this is _NOT_ my code.  I simply ported it from the\n// *  PERL Spreadsheet::WriteExcel module.\n// *\n// *  The author of the Spreadsheet::WriteExcel module is John McNamara\n// *  <jmcnamara@cpan.org>\n// *\n// *  I _DO_ maintain this code, and John McNamara has nothing to do with the\n// *  porting of this code to PHP.  Any questions directly related to this\n// *  class library should be directed to me.\n// *\n// *  License Information:\n// *\n// *    Spreadsheet_Excel_Writer:  A library for generating Excel Spreadsheets\n// *    Copyright (c) 2002-2003 Xavier Noguer xnoguer@rezebra.com\n// *\n// *    This library is free software; you can redistribute it and/or\n// *    modify it under the terms of the GNU Lesser General Public\n// *    License as published by the Free Software Foundation; either\n// *    version 2.1 of the License, or (at your option) any later version.\n// *\n// *    This library is distributed in the hope that it will be useful,\n// *    but WITHOUT ANY WARRANTY; without even the implied warranty of\n// *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n// *    Lesser General Public License for more details.\n// *\n// *    You should have received a copy of the GNU Lesser General Public\n// *    License along with this library; if not, write to the Free Software\n// *    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n// */\n\n\n/**\n * PHPExcel_Writer_Excel5_Xf\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel5_Xf\n{\n    /**\n\t * Style XF or a cell XF ?\n\t *\n\t * @var boolean\n\t */\n\tprivate $_isStyleXf;\n\n\t/**\n\t * Index to the FONT record. Index 4 does not exist\n\t * @var integer\n\t */\n\tprivate $_fontIndex;\n\n\t/**\n\t * An index (2 bytes) to a FORMAT record (number format).\n\t * @var integer\n\t */\n\tpublic $_numberFormatIndex;\n\n\t/**\n\t * 1 bit, apparently not used.\n\t * @var integer\n\t */\n\tpublic $_text_justlast;\n\n\t/**\n\t * The cell's foreground color.\n\t * @var integer\n\t */\n\tpublic $_fg_color;\n\n\t/**\n\t * The cell's background color.\n\t * @var integer\n\t */\n\tpublic $_bg_color;\n\n\t/**\n\t * Color of the bottom border of the cell.\n\t * @var integer\n\t */\n\tpublic $_bottom_color;\n\n\t/**\n\t * Color of the top border of the cell.\n\t * @var integer\n\t */\n\tpublic $_top_color;\n\n\t/**\n\t* Color of the left border of the cell.\n\t* @var integer\n\t*/\n\tpublic $_left_color;\n\n\t/**\n\t * Color of the right border of the cell.\n\t * @var integer\n\t */\n\tpublic $_right_color;\n\n\t/**\n\t * Constructor\n\t *\n\t * @access public\n\t * @param PHPExcel_Style\tThe XF format\n\t */\n\tpublic function __construct(PHPExcel_Style $style = null)\n\t{\n\t\t$this->_isStyleXf =     false;\n\t\t$this->_fontIndex      = 0;\n\n\t\t$this->_numberFormatIndex     = 0;\n\n\t\t$this->_text_justlast  = 0;\n\n\t\t$this->_fg_color       = 0x40;\n\t\t$this->_bg_color       = 0x41;\n\n\t\t$this->_diag           = 0;\n\n\t\t$this->_bottom_color   = 0x40;\n\t\t$this->_top_color      = 0x40;\n\t\t$this->_left_color     = 0x40;\n\t\t$this->_right_color    = 0x40;\n\t\t$this->_diag_color     = 0x40;\n\t\t$this->_style = $style;\n\n\t}\n\n\n\t/**\n\t * Generate an Excel BIFF XF record (style or cell).\n\t *\n\t * @return string The XF record\n\t */\n\tfunction writeXf()\n\t{\n\t\t// Set the type of the XF record and some of the attributes.\n\t\tif ($this->_isStyleXf) {\n\t\t\t$style = 0xFFF5;\n\t\t} else {\n\t\t\t$style   = self::_mapLocked($this->_style->getProtection()->getLocked());\n\t\t\t$style  |= self::_mapHidden($this->_style->getProtection()->getHidden()) << 1;\n\t\t}\n\n\t\t// Flags to indicate if attributes have been set.\n\t\t$atr_num     = ($this->_numberFormatIndex != 0)?1:0;\n\t\t$atr_fnt     = ($this->_fontIndex != 0)?1:0;\n\t\t$atr_alc     = ((int) $this->_style->getAlignment()->getWrapText()) ? 1 : 0;\n\t\t$atr_bdr     = (self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle())   ||\n\t\t\t\t\t\tself::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle())      ||\n\t\t\t\t\t\tself::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle())     ||\n\t\t\t\t\t\tself::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()))?1:0;\n\t\t$atr_pat     = (($this->_fg_color != 0x40) ||\n\t\t\t\t\t\t($this->_bg_color != 0x41) ||\n\t\t\t\t\t\tself::_mapFillType($this->_style->getFill()->getFillType()))?1:0;\n\t\t$atr_prot    = self::_mapLocked($this->_style->getProtection()->getLocked())\n\t\t\t\t\t\t| self::_mapHidden($this->_style->getProtection()->getHidden());\n\n\t\t// Zero the default border colour if the border has not been set.\n\t\tif (self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) == 0) {\n\t\t\t$this->_bottom_color = 0;\n\t\t}\n\t\tif (self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle())  == 0) {\n\t\t\t$this->_top_color = 0;\n\t\t}\n\t\tif (self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) == 0) {\n\t\t\t$this->_right_color = 0;\n\t\t}\n\t\tif (self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) == 0) {\n\t\t\t$this->_left_color = 0;\n\t\t}\n\t\tif (self::_mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) == 0) {\n\t\t\t$this->_diag_color = 0;\n\t\t}\n\n\t\t$record         = 0x00E0;              // Record identifier\n\t\t$length         = 0x0014;              // Number of bytes to follow\n\n\t\t$ifnt           = $this->_fontIndex;   // Index to FONT record\n\t\t$ifmt           = $this->_numberFormatIndex;  // Index to FORMAT record\n\n\t\t$align          = $this->_mapHAlign($this->_style->getAlignment()->getHorizontal());       // Alignment\n\t\t$align         |= (int) $this->_style->getAlignment()->getWrapText()     << 3;\n\t\t$align         |= self::_mapVAlign($this->_style->getAlignment()->getVertical())  << 4;\n\t\t$align         |= $this->_text_justlast << 7;\n\n\t\t$used_attrib    = $atr_num              << 2;\n\t\t$used_attrib   |= $atr_fnt              << 3;\n\t\t$used_attrib   |= $atr_alc              << 4;\n\t\t$used_attrib   |= $atr_bdr              << 5;\n\t\t$used_attrib   |= $atr_pat              << 6;\n\t\t$used_attrib   |= $atr_prot             << 7;\n\n\t\t$icv            = $this->_fg_color;      // fg and bg pattern colors\n\t\t$icv           |= $this->_bg_color      << 7;\n\n\t\t$border1        = self::_mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle());          // Border line style and color\n\t\t$border1       |= self::_mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle())         << 4;\n\t\t$border1       |= self::_mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle())           << 8;\n\t\t$border1       |= self::_mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle())        << 12;\n\t\t$border1       |= $this->_left_color    << 16;\n\t\t$border1       |= $this->_right_color   << 23;\n\n\t\t$diagonalDirection = $this->_style->getBorders()->getDiagonalDirection();\n\t\t$diag_tl_to_rb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH\n\t\t\t\t\t\t\t|| $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_DOWN;\n\t\t$diag_tr_to_lb = $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_BOTH\n\t\t\t\t\t\t\t|| $diagonalDirection == PHPExcel_Style_Borders::DIAGONAL_UP;\n\t\t$border1       |= $diag_tl_to_rb        << 30;\n\t\t$border1       |= $diag_tr_to_lb        << 31;\n\n\t\t$border2        = $this->_top_color;    // Border color\n\t\t$border2       |= $this->_bottom_color   << 7;\n\t\t$border2       |= $this->_diag_color     << 14;\n\t\t$border2       |= self::_mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle())           << 21;\n\t\t$border2       |= self::_mapFillType($this->_style->getFill()->getFillType())        << 26;\n\n\t\t$header      = pack(\"vv\",       $record, $length);\n\n\t\t//BIFF8 options: identation, shrinkToFit and  text direction\n\t\t$biff8_options  = $this->_style->getAlignment()->getIndent();\n\t\t$biff8_options |= (int) $this->_style->getAlignment()->getShrinkToFit() << 4;\n\n\t\t$data  = pack(\"vvvC\", $ifnt, $ifmt, $style, $align);\n\t\t$data .= pack(\"CCC\"\n\t\t\t, self::_mapTextRotation($this->_style->getAlignment()->getTextRotation())\n\t\t\t, $biff8_options\n\t\t\t, $used_attrib\n\t\t\t);\n\t\t$data .= pack(\"VVv\", $border1, $border2, $icv);\n\n\t\treturn($header . $data);\n\t}\n\n\t/**\n\t * Is this a style XF ?\n\t *\n\t * @param boolean $value\n\t */\n\tpublic function setIsStyleXf($value)\n\t{\n\t\t$this->_isStyleXf = $value;\n\t}\n\n\t/**\n\t * Sets the cell's bottom border color\n\t *\n\t * @access public\n\t * @param int $colorIndex Color index\n\t */\n\tfunction setBottomColor($colorIndex)\n\t{\n\t\t$this->_bottom_color = $colorIndex;\n\t}\n\n\t/**\n\t * Sets the cell's top border color\n\t *\n\t * @access public\n\t * @param int $colorIndex Color index\n\t */\n\tfunction setTopColor($colorIndex)\n\t{\n\t\t$this->_top_color = $colorIndex;\n\t}\n\n\t/**\n\t * Sets the cell's left border color\n\t *\n\t * @access public\n\t * @param int $colorIndex Color index\n\t */\n\tfunction setLeftColor($colorIndex)\n\t{\n\t\t$this->_left_color = $colorIndex;\n\t}\n\n\t/**\n\t * Sets the cell's right border color\n\t *\n\t * @access public\n\t * @param int $colorIndex Color index\n\t */\n\tfunction setRightColor($colorIndex)\n\t{\n\t\t$this->_right_color = $colorIndex;\n\t}\n\n\t/**\n\t * Sets the cell's diagonal border color\n\t *\n\t * @access public\n\t * @param int $colorIndex Color index\n\t */\n\tfunction setDiagColor($colorIndex)\n\t{\n\t\t$this->_diag_color = $colorIndex;\n\t}\n\n\n\t/**\n\t * Sets the cell's foreground color\n\t *\n\t * @access public\n\t * @param int $colorIndex Color index\n\t */\n\tfunction setFgColor($colorIndex)\n\t{\n\t\t$this->_fg_color = $colorIndex;\n\t}\n\n\t/**\n\t * Sets the cell's background color\n\t *\n\t * @access public\n\t * @param int $colorIndex Color index\n\t */\n\tfunction setBgColor($colorIndex)\n\t{\n\t\t$this->_bg_color = $colorIndex;\n\t}\n\n\t/**\n\t * Sets the index to the number format record\n\t * It can be date, time, currency, etc...\n\t *\n\t * @access public\n\t * @param integer $numberFormatIndex Index to format record\n\t */\n\tfunction setNumberFormatIndex($numberFormatIndex)\n\t{\n\t\t$this->_numberFormatIndex = $numberFormatIndex;\n\t}\n\n\t/**\n\t * Set the font index.\n\t *\n\t * @param int $value Font index, note that value 4 does not exist\n\t */\n\tpublic function setFontIndex($value)\n\t{\n\t\t$this->_fontIndex = $value;\n\t}\n\n\t/**\n\t * Map of BIFF2-BIFF8 codes for border styles\n\t * @static\tarray of int\n\t *\n\t */\n\tprivate static $_mapBorderStyle = array\t( PHPExcel_Style_Border::BORDER_NONE\t\t\t\t=> 0x00,\n\t\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Border::BORDER_THIN\t\t\t\t=> 0x01,\n\t\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Border::BORDER_MEDIUM\t\t\t\t=> 0x02,\n\t\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Border::BORDER_DASHED\t\t\t\t=> 0x03,\n\t\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Border::BORDER_DOTTED\t\t\t\t=> 0x04,\n\t\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Border::BORDER_THICK\t\t\t\t=> 0x05,\n\t\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Border::BORDER_DOUBLE\t\t\t\t=> 0x06,\n\t\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Border::BORDER_HAIR\t\t\t\t=> 0x07,\n\t\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Border::BORDER_MEDIUMDASHED\t\t=> 0x08,\n\t\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Border::BORDER_DASHDOT\t\t\t\t=> 0x09,\n\t\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT\t\t=> 0x0A,\n\t\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Border::BORDER_DASHDOTDOT\t\t\t=> 0x0B,\n\t\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT\t=> 0x0C,\n\t\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Border::BORDER_SLANTDASHDOT\t\t=> 0x0D,\n\t\t\t\t\t\t\t\t\t\t\t);\n\n\t/**\n\t * Map border style\n\t *\n\t * @param string $borderStyle\n\t * @return int\n\t */\n\tprivate static function _mapBorderStyle($borderStyle) {\n\t\tif (isset(self::$_mapBorderStyle[$borderStyle]))\n\t\t\treturn self::$_mapBorderStyle[$borderStyle];\n\t\treturn 0x00;\n\t}\n\n\t/**\n\t * Map of BIFF2-BIFF8 codes for fill types\n\t * @static\tarray of int\n\t *\n\t */\n\tprivate static $_mapFillType = array( PHPExcel_Style_Fill::FILL_NONE\t\t\t\t\t=> 0x00,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_SOLID\t\t\t\t\t=> 0x01,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_MEDIUMGRAY\t\t=> 0x02,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_DARKGRAY\t\t=> 0x03,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRAY\t\t=> 0x04,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_DARKHORIZONTAL\t=> 0x05,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_DARKVERTICAL\t=> 0x06,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_DARKDOWN\t\t=> 0x07,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_DARKUP\t\t\t=> 0x08,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_DARKGRID\t\t=> 0x09,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_DARKTRELLIS\t\t=> 0x0A,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_LIGHTHORIZONTAL\t=> 0x0B,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_LIGHTVERTICAL\t=> 0x0C,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_LIGHTDOWN\t\t=> 0x0D,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_LIGHTUP\t\t\t=> 0x0E,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_LIGHTGRID\t\t=> 0x0F,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_LIGHTTRELLIS\t=> 0x10,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_GRAY125\t\t\t=> 0x11,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_PATTERN_GRAY0625\t\t=> 0x12,\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR\t\t\t=> 0x00,\t// does not exist in BIFF8\n\t\t\t\t\t\t\t\t\t\t  PHPExcel_Style_Fill::FILL_GRADIENT_PATH\t\t\t=> 0x00,\t// does not exist in BIFF8\n\t\t\t\t\t\t\t\t\t\t);\n\t/**\n\t * Map fill type\n\t *\n\t * @param string $fillType\n\t * @return int\n\t */\n\tprivate static function _mapFillType($fillType) {\n\t\tif (isset(self::$_mapFillType[$fillType]))\n\t\t\treturn self::$_mapFillType[$fillType];\n\t\treturn 0x00;\n\t}\n\n\t/**\n\t * Map of BIFF2-BIFF8 codes for horizontal alignment\n\t * @static\tarray of int\n\t *\n\t */\n\tprivate static $_mapHAlign = array( PHPExcel_Style_Alignment::HORIZONTAL_GENERAL\t\t\t=> 0,\n\t\t\t\t\t\t\t\t\t\tPHPExcel_Style_Alignment::HORIZONTAL_LEFT\t\t\t\t=> 1,\n\t\t\t\t\t\t\t\t\t\tPHPExcel_Style_Alignment::HORIZONTAL_CENTER\t\t\t\t=> 2,\n\t\t\t\t\t\t\t\t\t\tPHPExcel_Style_Alignment::HORIZONTAL_RIGHT\t\t\t\t=> 3,\n\t\t\t\t\t\t\t\t\t\tPHPExcel_Style_Alignment::HORIZONTAL_FILL\t\t\t\t=> 4,\n\t\t\t\t\t\t\t\t\t\tPHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY\t\t\t=> 5,\n\t\t\t\t\t\t\t\t\t\tPHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS\t=> 6,\n\t\t\t\t\t\t\t\t\t  );\n\t/**\n\t * Map to BIFF2-BIFF8 codes for horizontal alignment\n\t *\n\t * @param string $hAlign\n\t * @return int\n\t */\n\tprivate function _mapHAlign($hAlign)\n\t{\n\t\tif (isset(self::$_mapHAlign[$hAlign]))\n\t\t\treturn self::$_mapHAlign[$hAlign];\n\t\treturn 0;\n\t}\n\n\t/**\n\t * Map of BIFF2-BIFF8 codes for vertical alignment\n\t * @static\tarray of int\n\t *\n\t */\n\tprivate static $_mapVAlign = array( PHPExcel_Style_Alignment::VERTICAL_TOP\t\t=> 0,\n\t\t\t\t\t\t\t\t\t\tPHPExcel_Style_Alignment::VERTICAL_CENTER\t=> 1,\n\t\t\t\t\t\t\t\t\t\tPHPExcel_Style_Alignment::VERTICAL_BOTTOM\t=> 2,\n\t\t\t\t\t\t\t\t\t\tPHPExcel_Style_Alignment::VERTICAL_JUSTIFY\t=> 3,\n\t\t\t\t\t\t\t\t\t  );\n\t/**\n\t * Map to BIFF2-BIFF8 codes for vertical alignment\n\t *\n\t * @param string $vAlign\n\t * @return int\n\t */\n\tprivate static function _mapVAlign($vAlign) {\n\t\tif (isset(self::$_mapVAlign[$vAlign]))\n\t\t\treturn self::$_mapVAlign[$vAlign];\n\t\treturn 2;\n\t}\n\n\t/**\n\t * Map to BIFF8 codes for text rotation angle\n\t *\n\t * @param int $textRotation\n\t * @return int\n\t */\n\tprivate static function _mapTextRotation($textRotation) {\n\t\tif ($textRotation >= 0) {\n\t\t\treturn $textRotation;\n\t\t}\n\t\tif ($textRotation == -165) {\n\t\t\treturn 255;\n\t\t}\n\t\tif ($textRotation < 0) {\n\t\t\treturn 90 - $textRotation;\n\t\t}\n\t}\n\n\t/**\n\t * Map locked\n\t *\n\t * @param string\n\t * @return int\n\t */\n\tprivate static function _mapLocked($locked) {\n\t\tswitch ($locked) {\n\t\t\tcase PHPExcel_Style_Protection::PROTECTION_INHERIT:\t\treturn 1;\n\t\t\tcase PHPExcel_Style_Protection::PROTECTION_PROTECTED:\treturn 1;\n\t\t\tcase PHPExcel_Style_Protection::PROTECTION_UNPROTECTED:\treturn 0;\n\t\t\tdefault:\t\t\t\t\t\t\t\t\t\t\t\treturn 1;\n\t\t}\n\t}\n\n\t/**\n\t * Map hidden\n\t *\n\t * @param string\n\t * @return int\n\t */\n\tprivate static function _mapHidden($hidden) {\n\t\tswitch ($hidden) {\n\t\t\tcase PHPExcel_Style_Protection::PROTECTION_INHERIT:\t\treturn 0;\n\t\t\tcase PHPExcel_Style_Protection::PROTECTION_PROTECTED:\treturn 1;\n\t\t\tcase PHPExcel_Style_Protection::PROTECTION_UNPROTECTED:\treturn 0;\n\t\t\tdefault:\t\t\t\t\t\t\t\t\t\t\t\treturn 0;\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Excel5.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Excel5\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_Excel5\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Excel5 extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter\n{\n\t/**\n\t * PHPExcel object\n\t *\n\t * @var PHPExcel\n\t */\n\tprivate $_phpExcel;\n\n\t/**\n\t * Total number of shared strings in workbook\n\t *\n\t * @var int\n\t */\n\tprivate $_str_total\t\t= 0;\n\n\t/**\n\t * Number of unique shared strings in workbook\n\t *\n\t * @var int\n\t */\n\tprivate $_str_unique\t= 0;\n\n\t/**\n\t * Array of unique shared strings in workbook\n\t *\n\t * @var array\n\t */\n\tprivate $_str_table\t\t= array();\n\n\t/**\n\t * Color cache. Mapping between RGB value and color index.\n\t *\n\t * @var array\n\t */\n\tprivate $_colors;\n\n\t/**\n\t * Formula parser\n\t *\n\t * @var PHPExcel_Writer_Excel5_Parser\n\t */\n\tprivate $_parser;\n\n\t/**\n\t * Identifier clusters for drawings. Used in MSODRAWINGGROUP record.\n\t *\n\t * @var array\n\t */\n\tprivate $_IDCLs;\n\n\t/**\n\t * Basic OLE object summary information\n\t *\n\t * @var array\n\t */\n\tprivate $_summaryInformation;\n\n\t/**\n\t * Extended OLE object document summary information\n\t *\n\t * @var array\n\t */\n\tprivate $_documentSummaryInformation;\n\n\t/**\n\t * Create a new PHPExcel_Writer_Excel5\n\t *\n\t * @param\tPHPExcel\t$phpExcel\tPHPExcel object\n\t */\n\tpublic function __construct(PHPExcel $phpExcel) {\n\t\t$this->_phpExcel\t= $phpExcel;\n\n\t\t$this->_parser\t\t= new PHPExcel_Writer_Excel5_Parser();\n\t}\n\n\t/**\n\t * Save PHPExcel to file\n\t *\n\t * @param\tstring\t\t$pFilename\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tpublic function save($pFilename = null) {\n\n\t\t// garbage collect\n\t\t$this->_phpExcel->garbageCollect();\n\n\t\t$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog();\n\t\tPHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE);\n\t\t$saveDateReturnType = PHPExcel_Calculation_Functions::getReturnDateType();\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n\n\t\t// initialize colors array\n\t\t$this->_colors          = array();\n\n\t\t// Initialise workbook writer\n\t\t$this->_writerWorkbook = new PHPExcel_Writer_Excel5_Workbook($this->_phpExcel,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t $this->_str_total, $this->_str_unique, $this->_str_table,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t $this->_colors, $this->_parser);\n\n\t\t// Initialise worksheet writers\n\t\t$countSheets = $this->_phpExcel->getSheetCount();\n\t\tfor ($i = 0; $i < $countSheets; ++$i) {\n\t\t\t$this->_writerWorksheets[$i] = new PHPExcel_Writer_Excel5_Worksheet($this->_str_total, $this->_str_unique,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   $this->_str_table, $this->_colors,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   $this->_parser,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   $this->_preCalculateFormulas,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t   $this->_phpExcel->getSheet($i));\n\t\t}\n\n\t\t// build Escher objects. Escher objects for workbooks needs to be build before Escher object for workbook.\n\t\t$this->_buildWorksheetEschers();\n\t\t$this->_buildWorkbookEscher();\n\n\t\t// add 15 identical cell style Xfs\n\t\t// for now, we use the first cellXf instead of cellStyleXf\n\t\t$cellXfCollection = $this->_phpExcel->getCellXfCollection();\n\t\tfor ($i = 0; $i < 15; ++$i) {\n\t\t\t$this->_writerWorkbook->addXfWriter($cellXfCollection[0], true);\n\t\t}\n\n\t\t// add all the cell Xfs\n\t\tforeach ($this->_phpExcel->getCellXfCollection() as $style) {\n\t\t\t$this->_writerWorkbook->addXfWriter($style, false);\n\t\t}\n\n\t\t// add fonts from rich text eleemnts\n\t\tfor ($i = 0; $i < $countSheets; ++$i) {\n\t\t\tforeach ($this->_writerWorksheets[$i]->_phpSheet->getCellCollection() as $cellID) {\n\t\t\t\t$cell = $this->_writerWorksheets[$i]->_phpSheet->getCell($cellID);\n\t\t\t\t$cVal = $cell->getValue();\n\t\t\t\tif ($cVal instanceof PHPExcel_RichText) {\n\t\t\t\t\t$elements = $cVal->getRichTextElements();\n\t\t\t\t\tforeach ($elements as $element) {\n\t\t\t\t\t\tif ($element instanceof PHPExcel_RichText_Run) {\n\t\t\t\t\t\t\t$font = $element->getFont();\n\t\t\t\t\t\t\t$this->_writerWorksheets[$i]->_fntHashIndex[$font->getHashCode()] = $this->_writerWorkbook->_addFont($font);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// initialize OLE file\n\t\t$workbookStreamName = 'Workbook';\n\t\t$OLE = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs($workbookStreamName));\n\n\t\t// Write the worksheet streams before the global workbook stream,\n\t\t// because the byte sizes of these are needed in the global workbook stream\n\t\t$worksheetSizes = array();\n\t\tfor ($i = 0; $i < $countSheets; ++$i) {\n\t\t\t$this->_writerWorksheets[$i]->close();\n\t\t\t$worksheetSizes[] = $this->_writerWorksheets[$i]->_datasize;\n\t\t}\n\n\t\t// add binary data for global workbook stream\n\t\t$OLE->append($this->_writerWorkbook->writeWorkbook($worksheetSizes));\n\n\t\t// add binary data for sheet streams\n\t\tfor ($i = 0; $i < $countSheets; ++$i) {\n\t\t\t$OLE->append($this->_writerWorksheets[$i]->getData());\n\t\t}\n\n\t\t$this->_documentSummaryInformation = $this->_writeDocumentSummaryInformation();\n\t\t// initialize OLE Document Summary Information\n\t\tif(isset($this->_documentSummaryInformation) && !empty($this->_documentSummaryInformation)){\n\t\t\t$OLE_DocumentSummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'DocumentSummaryInformation'));\n\t\t\t$OLE_DocumentSummaryInformation->append($this->_documentSummaryInformation);\n\t\t}\n\n\t\t$this->_summaryInformation = $this->_writeSummaryInformation();\n\t\t// initialize OLE Summary Information\n\t\tif(isset($this->_summaryInformation) && !empty($this->_summaryInformation)){\n\t\t  $OLE_SummaryInformation = new PHPExcel_Shared_OLE_PPS_File(PHPExcel_Shared_OLE::Asc2Ucs(chr(5) . 'SummaryInformation'));\n\t\t  $OLE_SummaryInformation->append($this->_summaryInformation);\n\t\t}\n\n\t\t// define OLE Parts\n\t\t$arrRootData = array($OLE);\n\t\t// initialize OLE Properties file\n\t\tif(isset($OLE_SummaryInformation)){\n\t\t\t$arrRootData[] = $OLE_SummaryInformation;\n\t\t}\n\t\t// initialize OLE Extended Properties file\n\t\tif(isset($OLE_DocumentSummaryInformation)){\n\t\t\t$arrRootData[] = $OLE_DocumentSummaryInformation;\n\t\t}\n\n\t\t$root = new PHPExcel_Shared_OLE_PPS_Root(time(), time(), $arrRootData);\n\t\t// save the OLE file\n\t\t$res = $root->save($pFilename);\n\n\t\tPHPExcel_Calculation_Functions::setReturnDateType($saveDateReturnType);\n\t\tPHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog);\n\t}\n\n\t/**\n\t * Set temporary storage directory\n\t *\n\t * @deprecated\n\t * @param\tstring\t$pValue\t\tTemporary storage directory\n\t * @throws\tPHPExcel_Writer_Exception\twhen directory does not exist\n\t * @return PHPExcel_Writer_Excel5\n\t */\n\tpublic function setTempDir($pValue = '') {\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Build the Worksheet Escher objects\n\t *\n\t */\n\tprivate function _buildWorksheetEschers()\n\t{\n\t\t// 1-based index to BstoreContainer\n\t\t$blipIndex = 0;\n\t\t$lastReducedSpId = 0;\n\t\t$lastSpId = 0;\n\n\t\tforeach ($this->_phpExcel->getAllsheets() as $sheet) {\n\t\t\t// sheet index\n\t\t\t$sheetIndex = $sheet->getParent()->getIndex($sheet);\n\n\t\t\t$escher = null;\n\n\t\t\t// check if there are any shapes for this sheet\n\t\t\t$filterRange = $sheet->getAutoFilter()->getRange();\n\t\t\tif (count($sheet->getDrawingCollection()) == 0 && empty($filterRange)) {\n\t\t\t\tcontinue;\n\t\t\t}\n\n\t\t\t// create intermediate Escher object\n\t\t\t$escher = new PHPExcel_Shared_Escher();\n\n\t\t\t// dgContainer\n\t\t\t$dgContainer = new PHPExcel_Shared_Escher_DgContainer();\n\n\t\t\t// set the drawing index (we use sheet index + 1)\n\t\t\t$dgId = $sheet->getParent()->getIndex($sheet) + 1;\n\t\t\t$dgContainer->setDgId($dgId);\n\t\t\t$escher->setDgContainer($dgContainer);\n\n\t\t\t// spgrContainer\n\t\t\t$spgrContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer();\n\t\t\t$dgContainer->setSpgrContainer($spgrContainer);\n\n\t\t\t// add one shape which is the group shape\n\t\t\t$spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();\n\t\t\t$spContainer->setSpgr(true);\n\t\t\t$spContainer->setSpType(0);\n\t\t\t$spContainer->setSpId(($sheet->getParent()->getIndex($sheet) + 1) << 10);\n\t\t\t$spgrContainer->addChild($spContainer);\n\n\t\t\t// add the shapes\n\n\t\t\t$countShapes[$sheetIndex] = 0; // count number of shapes (minus group shape), in sheet\n\n\t\t\tforeach ($sheet->getDrawingCollection() as $drawing) {\n\t\t\t\t++$blipIndex;\n\n\t\t\t\t++$countShapes[$sheetIndex];\n\n\t\t\t\t// add the shape\n\t\t\t\t$spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();\n\n\t\t\t\t// set the shape type\n\t\t\t\t$spContainer->setSpType(0x004B);\n\t\t\t\t// set the shape flag\n\t\t\t\t$spContainer->setSpFlag(0x02);\n\n\t\t\t\t// set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)\n\t\t\t\t$reducedSpId = $countShapes[$sheetIndex];\n\t\t\t\t$spId = $reducedSpId\n\t\t\t\t\t| ($sheet->getParent()->getIndex($sheet) + 1) << 10;\n\t\t\t\t$spContainer->setSpId($spId);\n\n\t\t\t\t// keep track of last reducedSpId\n\t\t\t\t$lastReducedSpId = $reducedSpId;\n\n\t\t\t\t// keep track of last spId\n\t\t\t\t$lastSpId = $spId;\n\n\t\t\t\t// set the BLIP index\n\t\t\t\t$spContainer->setOPT(0x4104, $blipIndex);\n\n\t\t\t\t// set coordinates and offsets, client anchor\n\t\t\t\t$coordinates = $drawing->getCoordinates();\n\t\t\t\t$offsetX = $drawing->getOffsetX();\n\t\t\t\t$offsetY = $drawing->getOffsetY();\n\t\t\t\t$width = $drawing->getWidth();\n\t\t\t\t$height = $drawing->getHeight();\n\n\t\t\t\t$twoAnchor = PHPExcel_Shared_Excel5::oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height);\n\n\t\t\t\t$spContainer->setStartCoordinates($twoAnchor['startCoordinates']);\n\t\t\t\t$spContainer->setStartOffsetX($twoAnchor['startOffsetX']);\n\t\t\t\t$spContainer->setStartOffsetY($twoAnchor['startOffsetY']);\n\t\t\t\t$spContainer->setEndCoordinates($twoAnchor['endCoordinates']);\n\t\t\t\t$spContainer->setEndOffsetX($twoAnchor['endOffsetX']);\n\t\t\t\t$spContainer->setEndOffsetY($twoAnchor['endOffsetY']);\n\n\t\t\t\t$spgrContainer->addChild($spContainer);\n\t\t\t}\n\n\t\t\t// AutoFilters\n\t\t\tif(!empty($filterRange)){\n\t\t\t\t$rangeBounds = PHPExcel_Cell::rangeBoundaries($filterRange);\n\t\t\t\t$iNumColStart = $rangeBounds[0][0];\n\t\t\t\t$iNumColEnd = $rangeBounds[1][0];\n\n\t\t\t\t$iInc = $iNumColStart;\n\t\t\t\twhile($iInc <= $iNumColEnd){\n\t\t\t\t\t++$countShapes[$sheetIndex];\n\n\t\t\t\t\t// create an Drawing Object for the dropdown\n\t\t\t\t\t$oDrawing  = new PHPExcel_Worksheet_BaseDrawing();\n\t\t\t\t\t// get the coordinates of drawing\n\t\t\t\t\t$cDrawing   = PHPExcel_Cell::stringFromColumnIndex($iInc - 1) . $rangeBounds[0][1];\n\t\t\t\t\t$oDrawing->setCoordinates($cDrawing);\n\t\t\t\t\t$oDrawing->setWorksheet($sheet);\n\n\t\t\t\t\t// add the shape\n\t\t\t\t\t$spContainer = new PHPExcel_Shared_Escher_DgContainer_SpgrContainer_SpContainer();\n\t\t\t\t\t// set the shape type\n\t\t\t\t\t$spContainer->setSpType(0x00C9);\n\t\t\t\t\t// set the shape flag\n\t\t\t\t\t$spContainer->setSpFlag(0x01);\n\n\t\t\t\t\t// set the shape index (we combine 1-based sheet index and $countShapes to create unique shape index)\n\t\t\t\t\t$reducedSpId = $countShapes[$sheetIndex];\n\t\t\t\t\t$spId = $reducedSpId\n\t\t\t\t\t\t| ($sheet->getParent()->getIndex($sheet) + 1) << 10;\n\t\t\t\t\t$spContainer->setSpId($spId);\n\n\t\t\t\t\t// keep track of last reducedSpId\n\t\t\t\t\t$lastReducedSpId = $reducedSpId;\n\n\t\t\t\t\t// keep track of last spId\n\t\t\t\t\t$lastSpId = $spId;\n\n\t\t\t\t\t$spContainer->setOPT(0x007F, 0x01040104); // Protection -> fLockAgainstGrouping\n\t\t\t\t\t$spContainer->setOPT(0x00BF, 0x00080008); // Text -> fFitTextToShape\n\t\t\t\t\t$spContainer->setOPT(0x01BF, 0x00010000); // Fill Style -> fNoFillHitTest\n\t\t\t\t\t$spContainer->setOPT(0x01FF, 0x00080000); // Line Style -> fNoLineDrawDash\n\t\t\t\t\t$spContainer->setOPT(0x03BF, 0x000A0000); // Group Shape -> fPrint\n\n\t\t\t\t\t// set coordinates and offsets, client anchor\n\t\t\t\t\t$endCoordinates = PHPExcel_Cell::stringFromColumnIndex(PHPExcel_Cell::stringFromColumnIndex($iInc - 1));\n\t\t\t\t\t$endCoordinates .= $rangeBounds[0][1] + 1;\n\n\t\t\t\t\t$spContainer->setStartCoordinates($cDrawing);\n\t\t\t\t\t$spContainer->setStartOffsetX(0);\n\t\t\t\t\t$spContainer->setStartOffsetY(0);\n\t\t\t\t\t$spContainer->setEndCoordinates($endCoordinates);\n\t\t\t\t\t$spContainer->setEndOffsetX(0);\n\t\t\t\t\t$spContainer->setEndOffsetY(0);\n\n\t\t\t\t\t$spgrContainer->addChild($spContainer);\n\t\t\t\t\t$iInc++;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// identifier clusters, used for workbook Escher object\n\t\t\t$this->_IDCLs[$dgId] = $lastReducedSpId;\n\n\t\t\t// set last shape index\n\t\t\t$dgContainer->setLastSpId($lastSpId);\n\n\t\t\t// set the Escher object\n\t\t\t$this->_writerWorksheets[$sheetIndex]->setEscher($escher);\n\t\t}\n\t}\n\n\t/**\n\t * Build the Escher object corresponding to the MSODRAWINGGROUP record\n\t */\n\tprivate function _buildWorkbookEscher()\n\t{\n\t\t$escher = null;\n\n\t\t// any drawings in this workbook?\n\t\t$found = false;\n\t\tforeach ($this->_phpExcel->getAllSheets() as $sheet) {\n\t\t\tif (count($sheet->getDrawingCollection()) > 0) {\n\t\t\t\t$found = true;\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\n\t\t// nothing to do if there are no drawings\n\t\tif (!$found) {\n\t\t\treturn;\n\t\t}\n\n\t\t// if we reach here, then there are drawings in the workbook\n\t\t$escher = new PHPExcel_Shared_Escher();\n\n\t\t// dggContainer\n\t\t$dggContainer = new PHPExcel_Shared_Escher_DggContainer();\n\t\t$escher->setDggContainer($dggContainer);\n\n\t\t// set IDCLs (identifier clusters)\n\t\t$dggContainer->setIDCLs($this->_IDCLs);\n\n\t\t// this loop is for determining maximum shape identifier of all drawing\n\t\t$spIdMax = 0;\n\t\t$totalCountShapes = 0;\n\t\t$countDrawings = 0;\n\n\t\tforeach ($this->_phpExcel->getAllsheets() as $sheet) {\n\t\t\t$sheetCountShapes = 0; // count number of shapes (minus group shape), in sheet\n\n\t\t\tif (count($sheet->getDrawingCollection()) > 0) {\n\t\t\t\t++$countDrawings;\n\n\t\t\t\tforeach ($sheet->getDrawingCollection() as $drawing) {\n\t\t\t\t\t++$sheetCountShapes;\n\t\t\t\t\t++$totalCountShapes;\n\n\t\t\t\t\t$spId = $sheetCountShapes\n\t\t\t\t\t\t| ($this->_phpExcel->getIndex($sheet) + 1) << 10;\n\t\t\t\t\t$spIdMax = max($spId, $spIdMax);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t$dggContainer->setSpIdMax($spIdMax + 1);\n\t\t$dggContainer->setCDgSaved($countDrawings);\n\t\t$dggContainer->setCSpSaved($totalCountShapes + $countDrawings); // total number of shapes incl. one group shapes per drawing\n\n\t\t// bstoreContainer\n\t\t$bstoreContainer = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer();\n\t\t$dggContainer->setBstoreContainer($bstoreContainer);\n\n\t\t// the BSE's (all the images)\n\t\tforeach ($this->_phpExcel->getAllsheets() as $sheet) {\n\t\t\tforeach ($sheet->getDrawingCollection() as $drawing) {\n\t\t\t\tif ($drawing instanceof PHPExcel_Worksheet_Drawing) {\n\n\t\t\t\t\t$filename = $drawing->getPath();\n\n\t\t\t\t\tlist($imagesx, $imagesy, $imageFormat) = getimagesize($filename);\n\n\t\t\t\t\tswitch ($imageFormat) {\n\n\t\t\t\t\tcase 1: // GIF, not supported by BIFF8, we convert to PNG\n\t\t\t\t\t\t$blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG;\n\t\t\t\t\t\tob_start();\n\t\t\t\t\t\timagepng(imagecreatefromgif($filename));\n\t\t\t\t\t\t$blipData = ob_get_contents();\n\t\t\t\t\t\tob_end_clean();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 2: // JPEG\n\t\t\t\t\t\t$blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG;\n\t\t\t\t\t\t$blipData = file_get_contents($filename);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 3: // PNG\n\t\t\t\t\t\t$blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG;\n\t\t\t\t\t\t$blipData = file_get_contents($filename);\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase 6: // Windows DIB (BMP), we convert to PNG\n\t\t\t\t\t\t$blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG;\n\t\t\t\t\t\tob_start();\n\t\t\t\t\t\timagepng(PHPExcel_Shared_Drawing::imagecreatefrombmp($filename));\n\t\t\t\t\t\t$blipData = ob_get_contents();\n\t\t\t\t\t\tob_end_clean();\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tdefault: continue 2;\n\n\t\t\t\t\t}\n\n\t\t\t\t\t$blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip();\n\t\t\t\t\t$blip->setData($blipData);\n\n\t\t\t\t\t$BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE();\n\t\t\t\t\t$BSE->setBlipType($blipType);\n\t\t\t\t\t$BSE->setBlip($blip);\n\n\t\t\t\t\t$bstoreContainer->addBSE($BSE);\n\n\t\t\t\t} else if ($drawing instanceof PHPExcel_Worksheet_MemoryDrawing) {\n\n\t\t\t\t\tswitch ($drawing->getRenderingFunction()) {\n\n\t\t\t\t\tcase PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG:\n\t\t\t\t\t\t$blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_JPEG;\n\t\t\t\t\t\t$renderingFunction = 'imagejpeg';\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\tcase PHPExcel_Worksheet_MemoryDrawing::RENDERING_GIF:\n\t\t\t\t\tcase PHPExcel_Worksheet_MemoryDrawing::RENDERING_PNG:\n\t\t\t\t\tcase PHPExcel_Worksheet_MemoryDrawing::RENDERING_DEFAULT:\n\t\t\t\t\t\t$blipType = PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE::BLIPTYPE_PNG;\n\t\t\t\t\t\t$renderingFunction = 'imagepng';\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tob_start();\n\t\t\t\t\tcall_user_func($renderingFunction, $drawing->getImageResource());\n\t\t\t\t\t$blipData = ob_get_contents();\n\t\t\t\t\tob_end_clean();\n\n\t\t\t\t\t$blip = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE_Blip();\n\t\t\t\t\t$blip->setData($blipData);\n\n\t\t\t\t\t$BSE = new PHPExcel_Shared_Escher_DggContainer_BstoreContainer_BSE();\n\t\t\t\t\t$BSE->setBlipType($blipType);\n\t\t\t\t\t$BSE->setBlip($blip);\n\n\t\t\t\t\t$bstoreContainer->addBSE($BSE);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Set the Escher object\n\t\t$this->_writerWorkbook->setEscher($escher);\n\t}\n\n\t/**\n\t * Build the OLE Part for DocumentSummary Information\n\t * @return string\n\t */\n\tprivate function _writeDocumentSummaryInformation(){\n\n\t\t// offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark)\n\t\t$data = pack('v', 0xFFFE);\n\t\t// offset: 2; size: 2;\n\t\t$data .= pack('v', 0x0000);\n\t\t// offset: 4; size: 2; OS version\n\t\t$data .= pack('v', 0x0106);\n\t\t// offset: 6; size: 2; OS indicator\n\t\t$data .= pack('v', 0x0002);\n\t\t// offset: 8; size: 16\n\t\t$data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00);\n\t\t// offset: 24; size: 4; section count\n\t\t$data .= pack('V', 0x0001);\n\n\t\t// offset: 28; size: 16; first section's class id: 02 d5 cd d5 9c 2e 1b 10 93 97 08 00 2b 2c f9 ae\n\t\t$data .= pack('vvvvvvvv', 0xD502, 0xD5CD, 0x2E9C, 0x101B, 0x9793, 0x0008, 0x2C2B, 0xAEF9);\n\t\t// offset: 44; size: 4; offset of the start\n\t\t$data .= pack('V', 0x30);\n\n\t\t// SECTION\n\t\t$dataSection = array();\n\t\t$dataSection_NumProps = 0;\n\t\t$dataSection_Summary = '';\n\t\t$dataSection_Content = '';\n\n\t\t// GKPIDDSI_CODEPAGE: CodePage\n\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01),\n\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer\n\t\t\t\t\t\t\t   'data'\t=> array('data' => 1252));\n\t\t$dataSection_NumProps++;\n\n\t\t// GKPIDDSI_CATEGORY : Category\n\t\tif($this->_phpExcel->getProperties()->getCategory()){\n\t\t\t$dataProp = $this->_phpExcel->getProperties()->getCategory();\n\t\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02),\n\t\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x1E),\n\t\t\t\t\t\t\t\t   'data'\t=> array('data' => $dataProp, 'length' => strlen($dataProp)));\n\t\t\t$dataSection_NumProps++;\n\t\t}\n\t\t// GKPIDDSI_VERSION :Version of the application that wrote the property storage\n\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x17),\n\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x03),\n\t\t\t\t\t\t\t   'data'\t=> array('pack' => 'V', 'data' => 0x000C0000));\n\t\t$dataSection_NumProps++;\n\t\t// GKPIDDSI_SCALE : FALSE\n\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0B),\n\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x0B),\n\t\t\t\t\t\t\t   'data'\t=> array('data' => false));\n\t\t$dataSection_NumProps++;\n\t\t// GKPIDDSI_LINKSDIRTY : True if any of the values for the linked properties have changed outside of the application\n\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x10),\n\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x0B),\n\t\t\t\t\t\t\t   'data'\t=> array('data' => false));\n\t\t$dataSection_NumProps++;\n\t\t// GKPIDDSI_SHAREDOC : FALSE\n\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13),\n\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x0B),\n\t\t\t\t\t\t\t   'data'\t=> array('data' => false));\n\t\t$dataSection_NumProps++;\n\t\t// GKPIDDSI_HYPERLINKSCHANGED : True if any of the values for the _PID_LINKS (hyperlink text) have changed outside of the application\n\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x16),\n\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x0B),\n\t\t\t\t\t\t\t   'data'\t=> array('data' => false));\n\t\t$dataSection_NumProps++;\n\n\t\t// GKPIDDSI_DOCSPARTS\n\t\t// MS-OSHARED p75 (2.3.3.2.2.1)\n\t\t// Structure is VtVecUnalignedLpstrValue (2.3.3.1.9)\n\t\t// cElements\n\t\t$dataProp = pack('v', 0x0001);\n\t\t$dataProp .= pack('v', 0x0000);\n\t\t// array of UnalignedLpstr\n\t\t  // cch\n\t\t  $dataProp .= pack('v', 0x000A);\n\t\t  $dataProp .= pack('v', 0x0000);\n\t\t  // value\n\t\t  $dataProp .= 'Worksheet'.chr(0);\n\n\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D),\n\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x101E),\n\t\t\t\t\t\t\t   'data'\t=> array('data' => $dataProp, 'length' => strlen($dataProp)));\n\t\t$dataSection_NumProps++;\n\n\t\t// GKPIDDSI_HEADINGPAIR\n\t\t// VtVecHeadingPairValue\n\t\t  // cElements\n\t\t  $dataProp = pack('v', 0x0002);\n\t\t  $dataProp .= pack('v', 0x0000);\n\t\t  // Array of vtHeadingPair\n\t\t    // vtUnalignedString - headingString\n\t\t      // stringType\n\t\t      $dataProp .= pack('v', 0x001E);\n\t\t      // padding\n\t\t      $dataProp .= pack('v', 0x0000);\n\t\t      // UnalignedLpstr\n\t\t        // cch\n\t\t        $dataProp .= pack('v', 0x0013);\n\t\t        $dataProp .= pack('v', 0x0000);\n\t\t        // value\n\t\t        $dataProp .= 'Feuilles de calcul';\n\t\t    // vtUnalignedString - headingParts\n\t\t      // wType : 0x0003 = 32 bit signed integer\n\t\t      $dataProp .= pack('v', 0x0300);\n\t\t      // padding\n\t\t      $dataProp .= pack('v', 0x0000);\n\t\t      // value\n\t\t      $dataProp .= pack('v', 0x0100);\n\t\t      $dataProp .= pack('v', 0x0000);\n\t\t\t  $dataProp .= pack('v', 0x0000);\n\t\t      $dataProp .= pack('v', 0x0000);\n\n        $dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C),\n        \t\t\t\t\t   'offset' => array('pack' => 'V'),\n        \t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x100C),\n        \t\t\t\t\t   'data'\t=> array('data' => $dataProp, 'length' => strlen($dataProp)));\n        $dataSection_NumProps++;\n\n\t\t// \t\t4 \tSection Length\n\t\t//\t\t4 \tProperty count\n\t\t//\t\t8 * $dataSection_NumProps (8 =  ID (4) + OffSet(4))\n\t\t$dataSection_Content_Offset = 8 + $dataSection_NumProps * 8;\n\t\tforeach ($dataSection as $dataProp){\n\t\t\t// Summary\n\t\t\t$dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']);\n\t\t\t// Offset\n\t\t\t$dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset);\n\t\t\t// DataType\n\t\t\t$dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']);\n\t\t\t// Data\n\t\t\tif($dataProp['type']['data'] == 0x02){ // 2 byte signed integer\n\t\t\t\t$dataSection_Content .= pack('V', $dataProp['data']['data']);\n\n\t\t\t\t$dataSection_Content_Offset += 4 + 4;\n\t\t\t}\n\t\t\telseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer\n\t\t\t\t$dataSection_Content .= pack('V', $dataProp['data']['data']);\n\n\t\t\t\t$dataSection_Content_Offset += 4 + 4;\n\t\t\t}\n\t\t\telseif($dataProp['type']['data'] == 0x0B){ // Boolean\n\t\t\t\tif($dataProp['data']['data'] == false){\n\t\t\t\t\t$dataSection_Content .= pack('V', 0x0000);\n\t\t\t\t} else {\n\t\t\t\t\t$dataSection_Content .= pack('V', 0x0001);\n\t\t\t\t}\n\t\t\t\t$dataSection_Content_Offset += 4 + 4;\n\t\t\t}\n\t\t\telseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length\n\t\t\t\t// Null-terminated string\n\t\t\t\t$dataProp['data']['data'] .= chr(0);\n\t\t\t\t$dataProp['data']['length'] += 1;\n\t\t\t\t// Complete the string with null string for being a %4\n\t\t\t\t$dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4));\n\t\t\t\t$dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT);\n\n\t\t\t\t$dataSection_Content .= pack('V', $dataProp['data']['length']);\n\t\t\t\t$dataSection_Content .= $dataProp['data']['data'];\n\n\t\t\t\t$dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']);\n\t\t\t}\n\t\t\telseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)\n\t\t\t\t$dataSection_Content .= $dataProp['data']['data'];\n\n\t\t\t\t$dataSection_Content_Offset += 4 + 8;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Data Type Not Used at the moment\n\t\t\t\t$dataSection_Content .= $dataProp['data']['data'];\n\n\t\t\t\t$dataSection_Content_Offset += 4 + $dataProp['data']['length'];\n\t\t\t}\n\t\t}\n\t\t// Now $dataSection_Content_Offset contains the size of the content\n\n\t\t// section header\n\t\t// offset: $secOffset; size: 4; section length\n\t\t// \t\t+ x  Size of the content (summary + content)\n\t\t$data .= pack('V', $dataSection_Content_Offset);\n\t\t// offset: $secOffset+4; size: 4; property count\n\t\t$data .= pack('V', $dataSection_NumProps);\n\t\t// Section Summary\n\t\t$data .= $dataSection_Summary;\n\t\t// Section Content\n\t\t$data .= $dataSection_Content;\n\n\t\treturn $data;\n\t}\n\n\t/**\n\t * Build the OLE Part for Summary Information\n\t * @return string\n\t */\n\tprivate function _writeSummaryInformation(){\n\t\t// offset: 0; size: 2; must be 0xFE 0xFF (UTF-16 LE byte order mark)\n\t\t$data = pack('v', 0xFFFE);\n\t\t// offset: 2; size: 2;\n\t\t$data .= pack('v', 0x0000);\n\t\t// offset: 4; size: 2; OS version\n\t\t$data .= pack('v', 0x0106);\n\t\t// offset: 6; size: 2; OS indicator\n\t\t$data .= pack('v', 0x0002);\n\t\t// offset: 8; size: 16\n\t\t$data .= pack('VVVV', 0x00, 0x00, 0x00, 0x00);\n\t\t// offset: 24; size: 4; section count\n\t\t$data .= pack('V', 0x0001);\n\n\t\t// offset: 28; size: 16; first section's class id: e0 85 9f f2 f9 4f 68 10 ab 91 08 00 2b 27 b3 d9\n\t\t$data .= pack('vvvvvvvv', 0x85E0, 0xF29F, 0x4FF9, 0x1068, 0x91AB, 0x0008, 0x272B, 0xD9B3);\n\t\t// offset: 44; size: 4; offset of the start\n\t\t$data .= pack('V', 0x30);\n\n\t\t// SECTION\n\t\t$dataSection = array();\n\t\t$dataSection_NumProps = 0;\n\t\t$dataSection_Summary = '';\n\t\t$dataSection_Content = '';\n\n\t\t// CodePage : CP-1252\n\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x01),\n\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x02), // 2 byte signed integer\n\t\t\t\t\t\t\t   'data'\t=> array('data' => 1252));\n\t\t$dataSection_NumProps++;\n\n\t\t//\tTitle\n\t\tif($this->_phpExcel->getProperties()->getTitle()){\n\t\t\t$dataProp = $this->_phpExcel->getProperties()->getTitle();\n\t\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x02),\n\t\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length\n\t\t\t\t\t\t\t\t   'data'\t=> array('data' => $dataProp, 'length' => strlen($dataProp)));\n\t\t\t$dataSection_NumProps++;\n\t\t}\n\t\t//\tSubject\n\t\tif($this->_phpExcel->getProperties()->getSubject()){\n\t\t\t$dataProp = $this->_phpExcel->getProperties()->getSubject();\n\t\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x03),\n\t\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length\n\t\t\t\t\t\t\t\t   'data'\t=> array('data' => $dataProp, 'length' => strlen($dataProp)));\n\t\t\t$dataSection_NumProps++;\n\t\t}\n\t\t//\tAuthor (Creator)\n\t\tif($this->_phpExcel->getProperties()->getCreator()){\n\t\t\t$dataProp = $this->_phpExcel->getProperties()->getCreator();\n\t\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x04),\n\t\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length\n\t\t\t\t\t\t\t\t   'data'\t=> array('data' => $dataProp, 'length' => strlen($dataProp)));\n\t\t\t$dataSection_NumProps++;\n\t\t}\n\t\t//\tKeywords\n\t\tif($this->_phpExcel->getProperties()->getKeywords()){\n\t\t\t$dataProp = $this->_phpExcel->getProperties()->getKeywords();\n\t\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x05),\n\t\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length\n\t\t\t\t\t\t\t\t   'data'\t=> array('data' => $dataProp, 'length' => strlen($dataProp)));\n\t\t\t$dataSection_NumProps++;\n\t\t}\n\t\t//\tComments (Description)\n\t\tif($this->_phpExcel->getProperties()->getDescription()){\n\t\t\t$dataProp = $this->_phpExcel->getProperties()->getDescription();\n\t\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x06),\n\t\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length\n\t\t\t\t\t\t\t\t   'data'\t=> array('data' => $dataProp, 'length' => strlen($dataProp)));\n\t\t\t$dataSection_NumProps++;\n\t\t}\n\t\t//\tLast Saved By (LastModifiedBy)\n\t\tif($this->_phpExcel->getProperties()->getLastModifiedBy()){\n\t\t\t$dataProp = $this->_phpExcel->getProperties()->getLastModifiedBy();\n\t\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x08),\n\t\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x1E), // null-terminated string prepended by dword string length\n\t\t\t\t\t\t\t\t   'data'\t=> array('data' => $dataProp, 'length' => strlen($dataProp)));\n\t\t\t$dataSection_NumProps++;\n\t\t}\n\t\t//\tCreated Date/Time\n\t\tif($this->_phpExcel->getProperties()->getCreated()){\n\t\t\t$dataProp = $this->_phpExcel->getProperties()->getCreated();\n\t\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0C),\n\t\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)\n\t\t\t\t\t\t\t\t   'data'\t=> array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp)));\n\t\t\t$dataSection_NumProps++;\n\t\t}\n\t\t//\tModified Date/Time\n\t\tif($this->_phpExcel->getProperties()->getModified()){\n\t\t\t$dataProp = $this->_phpExcel->getProperties()->getModified();\n\t\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x0D),\n\t\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x40), // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)\n\t\t\t\t\t\t\t\t   'data'\t=> array('data' => PHPExcel_Shared_OLE::LocalDate2OLE($dataProp)));\n\t\t\t$dataSection_NumProps++;\n\t\t}\n\t\t//\tSecurity\n\t\t$dataSection[] = array('summary'=> array('pack' => 'V', 'data' => 0x13),\n\t\t\t\t\t\t\t   'offset' => array('pack' => 'V'),\n\t\t\t\t\t\t\t   'type' \t=> array('pack' => 'V', 'data' => 0x03), // 4 byte signed integer\n\t\t\t\t\t\t\t   'data'\t=> array('data' => 0x00));\n\t\t$dataSection_NumProps++;\n\n\n\t\t// \t\t4 \tSection Length\n\t\t//\t\t4 \tProperty count\n\t\t//\t\t8 * $dataSection_NumProps (8 =  ID (4) + OffSet(4))\n\t\t$dataSection_Content_Offset = 8 + $dataSection_NumProps * 8;\n\t\tforeach ($dataSection as $dataProp){\n\t\t\t// Summary\n\t\t\t$dataSection_Summary .= pack($dataProp['summary']['pack'], $dataProp['summary']['data']);\n\t\t\t// Offset\n\t\t\t$dataSection_Summary .= pack($dataProp['offset']['pack'], $dataSection_Content_Offset);\n\t\t\t// DataType\n\t\t\t$dataSection_Content .= pack($dataProp['type']['pack'], $dataProp['type']['data']);\n\t\t\t// Data\n\t\t\tif($dataProp['type']['data'] == 0x02){ // 2 byte signed integer\n\t\t\t\t$dataSection_Content .= pack('V', $dataProp['data']['data']);\n\n\t\t\t\t$dataSection_Content_Offset += 4 + 4;\n\t\t\t}\n\t\t\telseif($dataProp['type']['data'] == 0x03){ // 4 byte signed integer\n\t\t\t\t$dataSection_Content .= pack('V', $dataProp['data']['data']);\n\n\t\t\t\t$dataSection_Content_Offset += 4 + 4;\n\t\t\t}\n\t\t\telseif($dataProp['type']['data'] == 0x1E){ // null-terminated string prepended by dword string length\n\t\t\t\t// Null-terminated string\n\t\t\t\t$dataProp['data']['data'] .= chr(0);\n\t\t\t\t$dataProp['data']['length'] += 1;\n\t\t\t\t// Complete the string with null string for being a %4\n\t\t\t\t$dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4)==4 ? 0 : (4 - $dataProp['data']['length'] % 4));\n\t\t\t\t$dataProp['data']['data'] = str_pad($dataProp['data']['data'], $dataProp['data']['length'], chr(0), STR_PAD_RIGHT);\n\n\t\t\t\t$dataSection_Content .= pack('V', $dataProp['data']['length']);\n\t\t\t\t$dataSection_Content .= $dataProp['data']['data'];\n\n\t\t\t\t$dataSection_Content_Offset += 4 + 4 + strlen($dataProp['data']['data']);\n\t\t\t}\n\t\t\telseif($dataProp['type']['data'] == 0x40){ // Filetime (64-bit value representing the number of 100-nanosecond intervals since January 1, 1601)\n\t\t\t\t$dataSection_Content .= $dataProp['data']['data'];\n\n\t\t\t\t$dataSection_Content_Offset += 4 + 8;\n\t\t\t}\n\t\t\telse {\n\t\t\t\t// Data Type Not Used at the moment\n\t\t\t}\n\t\t}\n\t\t// Now $dataSection_Content_Offset contains the size of the content\n\n\t\t// section header\n\t\t// offset: $secOffset; size: 4; section length\n\t\t// \t\t+ x  Size of the content (summary + content)\n\t\t$data .= pack('V', $dataSection_Content_Offset);\n\t\t// offset: $secOffset+4; size: 4; property count\n\t\t$data .= pack('V', $dataSection_NumProps);\n\t\t// Section Summary\n\t\t$data .= $dataSection_Summary;\n\t\t// Section Content\n\t\t$data .= $dataSection_Content;\n\n\t\treturn $data;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/Exception.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_Exception\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_Exception extends PHPExcel_Exception {\n\t/**\n\t * Error handler callback\n\t *\n\t * @param mixed $code\n\t * @param mixed $string\n\t * @param mixed $file\n\t * @param mixed $line\n\t * @param mixed $context\n\t */\n\tpublic static function errorHandlerCallback($code, $string, $file, $line, $context) {\n\t\t$e = new self($string, $code);\n\t\t$e->line = $line;\n\t\t$e->file = $file;\n\t\tthrow $e;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/HTML.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Writer_HTML\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license\thttp://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version\t##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_HTML\n *\n * @category   PHPExcel\n * @package\tPHPExcel_Writer_HTML\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_HTML extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter {\n\t/**\n\t * PHPExcel object\n\t *\n\t * @var PHPExcel\n\t */\n\tprotected $_phpExcel;\n\n\t/**\n\t * Sheet index to write\n\t *\n\t * @var int\n\t */\n\tprivate $_sheetIndex\t= 0;\n\n\t/**\n\t * Images root\n\t *\n\t * @var string\n\t */\n\tprivate $_imagesRoot\t= '.';\n\n\t/**\n\t * embed images, or link to images\n\t *\n\t * @var boolean\n\t */\n\tprivate $_embedImages\t= FALSE;\n\n\t/**\n\t * Use inline CSS?\n\t *\n\t * @var boolean\n\t */\n\tprivate $_useInlineCss = false;\n\n\t/**\n\t * Array of CSS styles\n\t *\n\t * @var array\n\t */\n\tprivate $_cssStyles = null;\n\n\t/**\n\t * Array of column widths in points\n\t *\n\t * @var array\n\t */\n\tprivate $_columnWidths = null;\n\n\t/**\n\t * Default font\n\t *\n\t * @var PHPExcel_Style_Font\n\t */\n\tprivate $_defaultFont;\n\n\t/**\n\t * Flag whether spans have been calculated\n\t *\n\t * @var boolean\n\t */\n\tprivate $_spansAreCalculated\t= false;\n\n\t/**\n\t * Excel cells that should not be written as HTML cells\n\t *\n\t * @var array\n\t */\n\tprivate $_isSpannedCell\t= array();\n\n\t/**\n\t * Excel cells that are upper-left corner in a cell merge\n\t *\n\t * @var array\n\t */\n\tprivate $_isBaseCell\t= array();\n\n\t/**\n\t * Excel rows that should not be written as HTML rows\n\t *\n\t * @var array\n\t */\n\tprivate $_isSpannedRow\t= array();\n\n\t/**\n\t * Is the current writer creating PDF?\n\t *\n\t * @var boolean\n\t */\n\tprotected $_isPdf = false;\n\n\t/**\n\t * Generate the Navigation block\n\t *\n\t * @var boolean\n\t */\n\tprivate $_generateSheetNavigationBlock = true;\n\n\t/**\n\t * Create a new PHPExcel_Writer_HTML\n\t *\n\t * @param\tPHPExcel\t$phpExcel\tPHPExcel object\n\t */\n\tpublic function __construct(PHPExcel $phpExcel) {\n\t\t$this->_phpExcel = $phpExcel;\n\t\t$this->_defaultFont = $this->_phpExcel->getDefaultStyle()->getFont();\n\t}\n\n\t/**\n\t * Save PHPExcel to file\n\t *\n\t * @param\tstring\t\t$pFilename\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tpublic function save($pFilename = null) {\n\t\t// garbage collect\n\t\t$this->_phpExcel->garbageCollect();\n\n\t\t$saveDebugLog = PHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->getWriteDebugLog();\n\t\tPHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog(FALSE);\n\t\t$saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType();\n\t\tPHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE);\n\n\t\t// Build CSS\n\t\t$this->buildCSS(!$this->_useInlineCss);\n\n\t\t// Open file\n\t\t$fileHandle = fopen($pFilename, 'wb+');\n\t\tif ($fileHandle === false) {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Could not open file $pFilename for writing.\");\n\t\t}\n\n\t\t// Write headers\n\t\tfwrite($fileHandle, $this->generateHTMLHeader(!$this->_useInlineCss));\n\n\t\t// Write navigation (tabs)\n\t\tif ((!$this->_isPdf) && ($this->_generateSheetNavigationBlock)) {\n\t\t\tfwrite($fileHandle, $this->generateNavigation());\n\t\t}\n\n\t\t// Write data\n\t\tfwrite($fileHandle, $this->generateSheetData());\n\n\t\t// Write footer\n\t\tfwrite($fileHandle, $this->generateHTMLFooter());\n\n\t\t// Close file\n\t\tfclose($fileHandle);\n\n\t\tPHPExcel_Calculation::setArrayReturnType($saveArrayReturnType);\n\t\tPHPExcel_Calculation::getInstance($this->_phpExcel)->getDebugLog()->setWriteDebugLog($saveDebugLog);\n\t}\n\n\t/**\n\t * Map VAlign\n\t *\n\t * @param\tstring\t\t$vAlign\t\tVertical alignment\n\t * @return string\n\t */\n\tprivate function _mapVAlign($vAlign) {\n\t\tswitch ($vAlign) {\n\t\t\tcase PHPExcel_Style_Alignment::VERTICAL_BOTTOM:\t\treturn 'bottom';\n\t\t\tcase PHPExcel_Style_Alignment::VERTICAL_TOP:\t\treturn 'top';\n\t\t\tcase PHPExcel_Style_Alignment::VERTICAL_CENTER:\n\t\t\tcase PHPExcel_Style_Alignment::VERTICAL_JUSTIFY:\treturn 'middle';\n\t\t\tdefault: return 'baseline';\n\t\t}\n\t}\n\n\t/**\n\t * Map HAlign\n\t *\n\t * @param\tstring\t\t$hAlign\t\tHorizontal alignment\n\t * @return string|false\n\t */\n\tprivate function _mapHAlign($hAlign) {\n\t\tswitch ($hAlign) {\n\t\t\tcase PHPExcel_Style_Alignment::HORIZONTAL_GENERAL:\t\t\t\treturn false;\n\t\t\tcase PHPExcel_Style_Alignment::HORIZONTAL_LEFT:\t\t\t\t\treturn 'left';\n\t\t\tcase PHPExcel_Style_Alignment::HORIZONTAL_RIGHT:\t\t\t\treturn 'right';\n\t\t\tcase PHPExcel_Style_Alignment::HORIZONTAL_CENTER:\n\t\t\tcase PHPExcel_Style_Alignment::HORIZONTAL_CENTER_CONTINUOUS:\treturn 'center';\n\t\t\tcase PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY:\t\t\t\treturn 'justify';\n\t\t\tdefault: return false;\n\t\t}\n\t}\n\n\t/**\n\t * Map border style\n\t *\n\t * @param\tint\t\t$borderStyle\t\tSheet index\n\t * @return\tstring\n\t */\n\tprivate function _mapBorderStyle($borderStyle) {\n\t\tswitch ($borderStyle) {\n\t\t\tcase PHPExcel_Style_Border::BORDER_NONE:\t\t\t\treturn 'none';\n\t\t\tcase PHPExcel_Style_Border::BORDER_DASHDOT:\t\t\t\treturn '1px dashed';\n\t\t\tcase PHPExcel_Style_Border::BORDER_DASHDOTDOT:\t\t\treturn '1px dotted';\n\t\t\tcase PHPExcel_Style_Border::BORDER_DASHED:\t\t\t\treturn '1px dashed';\n\t\t\tcase PHPExcel_Style_Border::BORDER_DOTTED:\t\t\t\treturn '1px dotted';\n\t\t\tcase PHPExcel_Style_Border::BORDER_DOUBLE:\t\t\t\treturn '3px double';\n\t\t\tcase PHPExcel_Style_Border::BORDER_HAIR:\t\t\t\treturn '1px solid';\n\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUM:\t\t\t\treturn '2px solid';\n\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHDOT:\t\treturn '2px dashed';\n\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHDOTDOT:\treturn '2px dotted';\n\t\t\tcase PHPExcel_Style_Border::BORDER_MEDIUMDASHED:\t\treturn '2px dashed';\n\t\t\tcase PHPExcel_Style_Border::BORDER_SLANTDASHDOT:\t\treturn '2px dashed';\n\t\t\tcase PHPExcel_Style_Border::BORDER_THICK:\t\t\t\treturn '3px solid';\n\t\t\tcase PHPExcel_Style_Border::BORDER_THIN:\t\t\t\treturn '1px solid';\n\t\t\tdefault: return '1px solid'; // map others to thin\n\t\t}\n\t}\n\n\t/**\n\t * Get sheet index\n\t *\n\t * @return int\n\t */\n\tpublic function getSheetIndex() {\n\t\treturn $this->_sheetIndex;\n\t}\n\n\t/**\n\t * Set sheet index\n\t *\n\t * @param\tint\t\t$pValue\t\tSheet index\n\t * @return PHPExcel_Writer_HTML\n\t */\n\tpublic function setSheetIndex($pValue = 0) {\n\t\t$this->_sheetIndex = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get sheet index\n\t *\n\t * @return boolean\n\t */\n\tpublic function getGenerateSheetNavigationBlock() {\n\t\treturn $this->_generateSheetNavigationBlock;\n\t}\n\n\t/**\n\t * Set sheet index\n\t *\n\t * @param\tboolean\t\t$pValue\t\tFlag indicating whether the sheet navigation block should be generated or not\n\t * @return PHPExcel_Writer_HTML\n\t */\n\tpublic function setGenerateSheetNavigationBlock($pValue = true) {\n\t\t$this->_generateSheetNavigationBlock = (bool) $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Write all sheets (resets sheetIndex to NULL)\n\t */\n\tpublic function writeAllSheets() {\n\t\t$this->_sheetIndex = null;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Generate HTML header\n\t *\n\t * @param\tboolean\t\t$pIncludeStyles\t\tInclude styles?\n\t * @return\tstring\n\t * @throws PHPExcel_Writer_Exception\n\t */\n\tpublic function generateHTMLHeader($pIncludeStyles = false) {\n\t\t// PHPExcel object known?\n\t\tif (is_null($this->_phpExcel)) {\n\t\t\tthrow new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.');\n\t\t}\n\n\t\t// Construct HTML\n\t\t$properties = $this->_phpExcel->getProperties();\n\t\t$html = '<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">' . PHP_EOL;\n\t\t$html .= '<!-- Generated by PHPExcel - http://www.phpexcel.net -->' . PHP_EOL;\n\t\t$html .= '<html>' . PHP_EOL;\n\t\t$html .= '  <head>' . PHP_EOL;\n\t\t$html .= '\t  <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">' . PHP_EOL;\n\t\tif ($properties->getTitle() > '')\n\t\t\t$html .= '\t  <title>' . htmlspecialchars($properties->getTitle()) . '</title>' . PHP_EOL;\n\n\t\tif ($properties->getCreator() > '')\n\t\t\t$html .= '\t  <meta name=\"author\" content=\"' . htmlspecialchars($properties->getCreator()) . '\" />' . PHP_EOL;\n\t\tif ($properties->getTitle() > '')\n\t\t\t$html .= '\t  <meta name=\"title\" content=\"' . htmlspecialchars($properties->getTitle()) . '\" />' . PHP_EOL;\n\t\tif ($properties->getDescription() > '')\n\t\t\t$html .= '\t  <meta name=\"description\" content=\"' . htmlspecialchars($properties->getDescription()) . '\" />' . PHP_EOL;\n\t\tif ($properties->getSubject() > '')\n\t\t\t$html .= '\t  <meta name=\"subject\" content=\"' . htmlspecialchars($properties->getSubject()) . '\" />' . PHP_EOL;\n\t\tif ($properties->getKeywords() > '')\n\t\t\t$html .= '\t  <meta name=\"keywords\" content=\"' . htmlspecialchars($properties->getKeywords()) . '\" />' . PHP_EOL;\n\t\tif ($properties->getCategory() > '')\n\t\t\t$html .= '\t  <meta name=\"category\" content=\"' . htmlspecialchars($properties->getCategory()) . '\" />' . PHP_EOL;\n\t\tif ($properties->getCompany() > '')\n\t\t\t$html .= '\t  <meta name=\"company\" content=\"' . htmlspecialchars($properties->getCompany()) . '\" />' . PHP_EOL;\n\t\tif ($properties->getManager() > '')\n\t\t\t$html .= '\t  <meta name=\"manager\" content=\"' . htmlspecialchars($properties->getManager()) . '\" />' . PHP_EOL;\n\n\t\tif ($pIncludeStyles) {\n\t\t\t$html .= $this->generateStyles(true);\n\t\t}\n\n\t\t$html .= '  </head>' . PHP_EOL;\n\t\t$html .= '' . PHP_EOL;\n\t\t$html .= '  <body>' . PHP_EOL;\n\n\t\t// Return\n\t\treturn $html;\n\t}\n\n\t/**\n\t * Generate sheet data\n\t *\n\t * @return\tstring\n\t * @throws PHPExcel_Writer_Exception\n\t */\n\tpublic function generateSheetData() {\n\t\t// PHPExcel object known?\n\t\tif (is_null($this->_phpExcel)) {\n\t\t\tthrow new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.');\n\t\t}\n\n\t\t// Ensure that Spans have been calculated?\n\t\tif (!$this->_spansAreCalculated) {\n\t\t\t$this->_calculateSpans();\n\t\t}\n\n\t\t// Fetch sheets\n\t\t$sheets = array();\n\t\tif (is_null($this->_sheetIndex)) {\n\t\t\t$sheets = $this->_phpExcel->getAllSheets();\n\t\t} else {\n\t\t\t$sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex);\n\t\t}\n\n\t\t// Construct HTML\n\t\t$html = '';\n\n\t\t// Loop all sheets\n\t\t$sheetId = 0;\n\t\tforeach ($sheets as $sheet) {\n\t\t\t// Write table header\n\t\t\t$html .= $this->_generateTableHeader($sheet);\n\n\t\t\t// Get worksheet dimension\n\t\t\t$dimension = explode(':', $sheet->calculateWorksheetDimension());\n\t\t\t$dimension[0] = PHPExcel_Cell::coordinateFromString($dimension[0]);\n\t\t\t$dimension[0][0] = PHPExcel_Cell::columnIndexFromString($dimension[0][0]) - 1;\n\t\t\t$dimension[1] = PHPExcel_Cell::coordinateFromString($dimension[1]);\n\t\t\t$dimension[1][0] = PHPExcel_Cell::columnIndexFromString($dimension[1][0]) - 1;\n\n\t\t\t// row min,max\n\t\t\t$rowMin = $dimension[0][1];\n\t\t\t$rowMax = $dimension[1][1];\n\n\t\t\t// calculate start of <tbody>, <thead>\n\t\t\t$tbodyStart = $rowMin;\n\t\t\t$theadStart = $theadEnd   = 0; // default: no <thead>\tno </thead>\n\t\t\tif ($sheet->getPageSetup()->isRowsToRepeatAtTopSet()) {\n\t\t\t\t$rowsToRepeatAtTop = $sheet->getPageSetup()->getRowsToRepeatAtTop();\n\n\t\t\t\t// we can only support repeating rows that start at top row\n\t\t\t\tif ($rowsToRepeatAtTop[0] == 1) {\n\t\t\t\t\t$theadStart = $rowsToRepeatAtTop[0];\n\t\t\t\t\t$theadEnd   = $rowsToRepeatAtTop[1];\n\t\t\t\t\t$tbodyStart = $rowsToRepeatAtTop[1] + 1;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Loop through cells\n\t\t\t$row = $rowMin-1;\n\t\t\twhile($row++ < $rowMax) {\n\t\t\t\t// <thead> ?\n\t\t\t\tif ($row == $theadStart) {\n\t\t\t\t\t$html .= '\t\t<thead>' . PHP_EOL;\n                    $cellType = 'th';\n\t\t\t\t}\n\n\t\t\t\t// <tbody> ?\n\t\t\t\tif ($row == $tbodyStart) {\n\t\t\t\t\t$html .= '\t\t<tbody>' . PHP_EOL;\n                    $cellType = 'td';\n\t\t\t\t}\n\n\t\t\t\t// Write row if there are HTML table cells in it\n\t\t\t\tif ( !isset($this->_isSpannedRow[$sheet->getParent()->getIndex($sheet)][$row]) ) {\n\t\t\t\t\t// Start a new rowData\n\t\t\t\t\t$rowData = array();\n\t\t\t\t\t// Loop through columns\n\t\t\t\t\t$column = $dimension[0][0] - 1;\n\t\t\t\t\twhile($column++ < $dimension[1][0]) {\n\t\t\t\t\t\t// Cell exists?\n\t\t\t\t\t\tif ($sheet->cellExistsByColumnAndRow($column, $row)) {\n\t\t\t\t\t\t\t$rowData[$column] = PHPExcel_Cell::stringFromColumnIndex($column) . $row;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$rowData[$column] = '';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\t$html .= $this->_generateRow($sheet, $rowData, $row - 1, $cellType);\n\t\t\t\t}\n\n\t\t\t\t// </thead> ?\n\t\t\t\tif ($row == $theadEnd) {\n\t\t\t\t\t$html .= '\t\t</thead>' . PHP_EOL;\n\t\t\t\t}\n\t\t\t}\n\t\t\t$html .= $this->_extendRowsForChartsAndImages($sheet, $row);\n\n\t\t\t// Close table body.\n\t\t\t$html .= '\t\t</tbody>' . PHP_EOL;\n\n\t\t\t// Write table footer\n\t\t\t$html .= $this->_generateTableFooter();\n\n\t\t\t// Writing PDF?\n\t\t\tif ($this->_isPdf) {\n\t\t\t\tif (is_null($this->_sheetIndex) && $sheetId + 1 < $this->_phpExcel->getSheetCount()) {\n\t\t\t\t\t$html .= '<div style=\"page-break-before:always\" />';\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Next sheet\n\t\t\t++$sheetId;\n\t\t}\n\n\t\t// Return\n\t\treturn $html;\n\t}\n\n\t/**\n\t * Generate sheet tabs\n\t *\n\t * @return\tstring\n\t * @throws PHPExcel_Writer_Exception\n\t */\n\tpublic function generateNavigation()\n\t{\n\t\t// PHPExcel object known?\n\t\tif (is_null($this->_phpExcel)) {\n\t\t\tthrow new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.');\n\t\t}\n\n\t\t// Fetch sheets\n\t\t$sheets = array();\n\t\tif (is_null($this->_sheetIndex)) {\n\t\t\t$sheets = $this->_phpExcel->getAllSheets();\n\t\t} else {\n\t\t\t$sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex);\n\t\t}\n\n\t\t// Construct HTML\n\t\t$html = '';\n\n\t\t// Only if there are more than 1 sheets\n\t\tif (count($sheets) > 1) {\n\t\t\t// Loop all sheets\n\t\t\t$sheetId = 0;\n\n\t\t\t$html .= '<ul class=\"navigation\">' . PHP_EOL;\n\n\t\t\tforeach ($sheets as $sheet) {\n\t\t\t\t$html .= '  <li class=\"sheet' . $sheetId . '\"><a href=\"#sheet' . $sheetId . '\">' . $sheet->getTitle() . '</a></li>' . PHP_EOL;\n\t\t\t\t++$sheetId;\n\t\t\t}\n\n\t\t\t$html .= '</ul>' . PHP_EOL;\n\t\t}\n\n\t\treturn $html;\n\t}\n\n\tprivate function _extendRowsForChartsAndImages(PHPExcel_Worksheet $pSheet, $row) {\n\t\t$rowMax = $row;\n\t\t$colMax = 'A';\n\t\tif ($this->_includeCharts) {\n\t\t\tforeach ($pSheet->getChartCollection() as $chart) {\n\t\t\t\tif ($chart instanceof PHPExcel_Chart) {\n\t\t\t\t    $chartCoordinates = $chart->getTopLeftPosition();\n\t\t\t\t    $chartTL = PHPExcel_Cell::coordinateFromString($chartCoordinates['cell']);\n\t\t\t\t\t$chartCol = PHPExcel_Cell::columnIndexFromString($chartTL[0]);\n\t\t\t\t\tif ($chartTL[1] > $rowMax) {\n\t\t\t\t\t\t$rowMax = $chartTL[1];\n\t\t\t\t\t\tif ($chartCol > PHPExcel_Cell::columnIndexFromString($colMax)) {\n\t\t\t\t\t\t\t$colMax = $chartTL[0];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tforeach ($pSheet->getDrawingCollection() as $drawing) {\n\t\t\tif ($drawing instanceof PHPExcel_Worksheet_Drawing) {\n\t\t\t    $imageTL = PHPExcel_Cell::coordinateFromString($drawing->getCoordinates());\n\t\t\t\t$imageCol = PHPExcel_Cell::columnIndexFromString($imageTL[0]);\n\t\t\t\tif ($imageTL[1] > $rowMax) {\n\t\t\t\t\t$rowMax = $imageTL[1];\n\t\t\t\t\tif ($imageCol > PHPExcel_Cell::columnIndexFromString($colMax)) {\n\t\t\t\t\t\t$colMax = $imageTL[0];\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t$html = '';\n\t\t$colMax++;\n\t\twhile ($row < $rowMax) {\n\t\t\t$html .= '<tr>';\n\t\t\tfor ($col = 'A'; $col != $colMax; ++$col) {\n\t\t\t\t$html .= '<td>';\n\t\t\t\t$html .= $this->_writeImageInCell($pSheet, $col.$row);\n\t\t\t\tif ($this->_includeCharts) {\n\t\t\t\t\t$html .= $this->_writeChartInCell($pSheet, $col.$row);\n\t\t\t\t}\n\t\t\t\t$html .= '</td>';\n\t\t\t}\n\t\t\t++$row;\n\t\t\t$html .= '</tr>';\n\t\t}\n\t\treturn $html;\n\t}\n\n\n\t/**\n\t * Generate image tag in cell\n\t *\n\t * @param\tPHPExcel_Worksheet\t$pSheet\t\t\tPHPExcel_Worksheet\n\t * @param\tstring\t\t\t\t$coordinates\tCell coordinates\n\t * @return\tstring\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeImageInCell(PHPExcel_Worksheet $pSheet, $coordinates) {\n\t\t// Construct HTML\n\t\t$html = '';\n\n\t\t// Write images\n\t\tforeach ($pSheet->getDrawingCollection() as $drawing) {\n\t\t\tif ($drawing instanceof PHPExcel_Worksheet_Drawing) {\n\t\t\t\tif ($drawing->getCoordinates() == $coordinates) {\n\t\t\t\t\t$filename = $drawing->getPath();\n\n\t\t\t\t\t// Strip off eventual '.'\n\t\t\t\t\tif (substr($filename, 0, 1) == '.') {\n\t\t\t\t\t\t$filename = substr($filename, 1);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Prepend images root\n\t\t\t\t\t$filename = $this->getImagesRoot() . $filename;\n\n\t\t\t\t\t// Strip off eventual '.'\n\t\t\t\t\tif (substr($filename, 0, 1) == '.' && substr($filename, 0, 2) != './') {\n\t\t\t\t\t\t$filename = substr($filename, 1);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Convert UTF8 data to PCDATA\n\t\t\t\t\t$filename = htmlspecialchars($filename);\n\n\t\t\t\t\t$html .= PHP_EOL;\n\t\t\t\t\tif ((!$this->_embedImages) || ($this->_isPdf)) {\n\t\t\t\t\t\t$imageData = $filename;\n\t\t\t\t\t} else {\n\t\t\t\t\t\t$imageDetails = getimagesize($filename);\n\t\t\t\t\t\tif ($fp = fopen($filename,\"rb\", 0)) {\n\t\t\t\t\t\t\t$picture = fread($fp,filesize($filename));\n\t\t\t\t\t\t\tfclose($fp);\n\t\t\t\t\t\t\t// base64 encode the binary data, then break it\n\t\t\t\t\t\t\t// into chunks according to RFC 2045 semantics\n\t\t\t\t\t\t\t$base64 = chunk_split(base64_encode($picture));\n\t\t\t\t\t\t\t$imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64;\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$imageData = $filename;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t$html .= '<div style=\"position: relative;\">';\n\t\t\t\t\t$html .= '<img style=\"position: absolute; z-index: 1; left: ' . \n                        $drawing->getOffsetX() . 'px; top: ' . $drawing->getOffsetY() . 'px; width: ' . \n                        $drawing->getWidth() . 'px; height: ' . $drawing->getHeight() . 'px;\" src=\"' . \n                        $imageData . '\" border=\"0\" />';\n\t\t\t\t\t$html .= '</div>';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $html;\n\t}\n\n\t/**\n\t * Generate chart tag in cell\n\t *\n\t * @param\tPHPExcel_Worksheet\t$pSheet\t\t\tPHPExcel_Worksheet\n\t * @param\tstring\t\t\t\t$coordinates\tCell coordinates\n\t * @return\tstring\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _writeChartInCell(PHPExcel_Worksheet $pSheet, $coordinates) {\n\t\t// Construct HTML\n\t\t$html = '';\n\n\t\t// Write charts\n\t\tforeach ($pSheet->getChartCollection() as $chart) {\n\t\t\tif ($chart instanceof PHPExcel_Chart) {\n\t\t\t    $chartCoordinates = $chart->getTopLeftPosition();\n\t\t\t\tif ($chartCoordinates['cell'] == $coordinates) {\n\t\t\t\t\t$chartFileName = PHPExcel_Shared_File::sys_get_temp_dir().'/'.uniqid().'.png';\n\t\t\t\t\tif (!$chart->render($chartFileName)) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\t$html .= PHP_EOL;\n\t\t\t\t\t$imageDetails = getimagesize($chartFileName);\n\t\t\t\t\tif ($fp = fopen($chartFileName,\"rb\", 0)) {\n\t\t\t\t\t\t$picture = fread($fp,filesize($chartFileName));\n\t\t\t\t\t\tfclose($fp);\n\t\t\t\t\t\t// base64 encode the binary data, then break it\n\t\t\t\t\t\t// into chunks according to RFC 2045 semantics\n\t\t\t\t\t\t$base64 = chunk_split(base64_encode($picture));\n\t\t\t\t\t\t$imageData = 'data:'.$imageDetails['mime'].';base64,' . $base64;\n\n\t\t\t\t\t\t$html .= '<div style=\"position: relative;\">';\n\t\t\t\t\t\t$html .= '<img style=\"position: absolute; z-index: 1; left: ' . $chartCoordinates['xOffset'] . 'px; top: ' . $chartCoordinates['yOffset'] . 'px; width: ' . $imageDetails[0] . 'px; height: ' . $imageDetails[1] . 'px;\" src=\"' . $imageData . '\" border=\"0\" />' . PHP_EOL;\n\t\t\t\t\t\t$html .= '</div>';\n\n\t\t\t\t\t\tunlink($chartFileName);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $html;\n\t}\n\n\t/**\n\t * Generate CSS styles\n\t *\n\t * @param\tboolean\t$generateSurroundingHTML\tGenerate surrounding HTML tags? (&lt;style&gt; and &lt;/style&gt;)\n\t * @return\tstring\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tpublic function generateStyles($generateSurroundingHTML = true) {\n\t\t// PHPExcel object known?\n\t\tif (is_null($this->_phpExcel)) {\n\t\t\tthrow new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.');\n\t\t}\n\n\t\t// Build CSS\n\t\t$css = $this->buildCSS($generateSurroundingHTML);\n\n\t\t// Construct HTML\n\t\t$html = '';\n\n\t\t// Start styles\n\t\tif ($generateSurroundingHTML) {\n\t\t\t$html .= '\t<style type=\"text/css\">' . PHP_EOL;\n\t\t\t$html .= '\t  html { ' . $this->_assembleCSS($css['html']) . ' }' . PHP_EOL;\n\t\t}\n\n\t\t// Write all other styles\n\t\tforeach ($css as $styleName => $styleDefinition) {\n\t\t\tif ($styleName != 'html') {\n\t\t\t\t$html .= '\t  ' . $styleName . ' { ' . $this->_assembleCSS($styleDefinition) . ' }' . PHP_EOL;\n\t\t\t}\n\t\t}\n\n\t\t// End styles\n\t\tif ($generateSurroundingHTML) {\n\t\t\t$html .= '\t</style>' . PHP_EOL;\n\t\t}\n\n\t\t// Return\n\t\treturn $html;\n\t}\n\n\t/**\n\t * Build CSS styles\n\t *\n\t * @param\tboolean\t$generateSurroundingHTML\tGenerate surrounding HTML style? (html { })\n\t * @return\tarray\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tpublic function buildCSS($generateSurroundingHTML = true) {\n\t\t// PHPExcel object known?\n\t\tif (is_null($this->_phpExcel)) {\n\t\t\tthrow new PHPExcel_Writer_Exception('Internal PHPExcel object not set to an instance of an object.');\n\t\t}\n\n\t\t// Cached?\n\t\tif (!is_null($this->_cssStyles)) {\n\t\t\treturn $this->_cssStyles;\n\t\t}\n\n\t\t// Ensure that spans have been calculated\n\t\tif (!$this->_spansAreCalculated) {\n\t\t\t$this->_calculateSpans();\n\t\t}\n\n\t\t// Construct CSS\n\t\t$css = array();\n\n\t\t// Start styles\n\t\tif ($generateSurroundingHTML) {\n\t\t\t// html { }\n\t\t\t$css['html']['font-family']\t  = 'Calibri, Arial, Helvetica, sans-serif';\n\t\t\t$css['html']['font-size']\t\t= '11pt';\n\t\t\t$css['html']['background-color'] = 'white';\n\t\t}\n\n\n\t\t// table { }\n\t\t$css['table']['border-collapse']  = 'collapse';\n\t    if (!$this->_isPdf) {\n\t\t\t$css['table']['page-break-after'] = 'always';\n\t\t}\n\n\t\t// .gridlines td { }\n\t\t$css['.gridlines td']['border'] = '1px dotted black';\n\t\t$css['.gridlines th']['border'] = '1px dotted black';\n\n\t\t// .b {}\n\t\t$css['.b']['text-align'] = 'center'; // BOOL\n\n\t\t// .e {}\n\t\t$css['.e']['text-align'] = 'center'; // ERROR\n\n\t\t// .f {}\n\t\t$css['.f']['text-align'] = 'right'; // FORMULA\n\n\t\t// .inlineStr {}\n\t\t$css['.inlineStr']['text-align'] = 'left'; // INLINE\n\n\t\t// .n {}\n\t\t$css['.n']['text-align'] = 'right'; // NUMERIC\n\n\t\t// .s {}\n\t\t$css['.s']['text-align'] = 'left'; // STRING\n\n\t\t// Calculate cell style hashes\n\t\tforeach ($this->_phpExcel->getCellXfCollection() as $index => $style) {\n\t\t\t$css['td.style' . $index] = $this->_createCSSStyle( $style );\n\t\t\t$css['th.style' . $index] = $this->_createCSSStyle( $style );\n\t\t}\n\n\t\t// Fetch sheets\n\t\t$sheets = array();\n\t\tif (is_null($this->_sheetIndex)) {\n\t\t\t$sheets = $this->_phpExcel->getAllSheets();\n\t\t} else {\n\t\t\t$sheets[] = $this->_phpExcel->getSheet($this->_sheetIndex);\n\t\t}\n\n\t\t// Build styles per sheet\n\t\tforeach ($sheets as $sheet) {\n\t\t\t// Calculate hash code\n\t\t\t$sheetIndex = $sheet->getParent()->getIndex($sheet);\n\n\t\t\t// Build styles\n\t\t\t// Calculate column widths\n\t\t\t$sheet->calculateColumnWidths();\n\n\t\t\t// col elements, initialize\n\t\t\t$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn()) - 1;\n\t\t\t$column = -1;\n\t\t\twhile($column++ < $highestColumnIndex) {\n\t\t\t\t$this->_columnWidths[$sheetIndex][$column] = 42; // approximation\n\t\t\t\t$css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = '42pt';\n\t\t\t}\n\n\t\t\t// col elements, loop through columnDimensions and set width\n\t\t\tforeach ($sheet->getColumnDimensions() as $columnDimension) {\n\t\t\t\tif (($width = PHPExcel_Shared_Drawing::cellDimensionToPixels($columnDimension->getWidth(), $this->_defaultFont)) >= 0) {\n\t\t\t\t\t$width = PHPExcel_Shared_Drawing::pixelsToPoints($width);\n\t\t\t\t\t$column = PHPExcel_Cell::columnIndexFromString($columnDimension->getColumnIndex()) - 1;\n\t\t\t\t\t$this->_columnWidths[$sheetIndex][$column] = $width;\n\t\t\t\t\t$css['table.sheet' . $sheetIndex . ' col.col' . $column]['width'] = $width . 'pt';\n\n\t\t\t\t\tif ($columnDimension->getVisible() === false) {\n\t\t\t\t\t\t$css['table.sheet' . $sheetIndex . ' col.col' . $column]['visibility'] = 'collapse';\n\t\t\t\t\t\t$css['table.sheet' . $sheetIndex . ' col.col' . $column]['*display'] = 'none'; // target IE6+7\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Default row height\n\t\t\t$rowDimension = $sheet->getDefaultRowDimension();\n\n\t\t\t// table.sheetN tr { }\n\t\t\t$css['table.sheet' . $sheetIndex . ' tr'] = array();\n\n\t\t\tif ($rowDimension->getRowHeight() == -1) {\n\t\t\t\t$pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont());\n\t\t\t} else {\n\t\t\t\t$pt_height = $rowDimension->getRowHeight();\n\t\t\t}\n\t\t\t$css['table.sheet' . $sheetIndex . ' tr']['height'] = $pt_height . 'pt';\n\t\t\tif ($rowDimension->getVisible() === false) {\n\t\t\t\t$css['table.sheet' . $sheetIndex . ' tr']['display']\t= 'none';\n\t\t\t\t$css['table.sheet' . $sheetIndex . ' tr']['visibility'] = 'hidden';\n\t\t\t}\n\n\t\t\t// Calculate row heights\n\t\t\tforeach ($sheet->getRowDimensions() as $rowDimension) {\n\t\t\t\t$row = $rowDimension->getRowIndex() - 1;\n\n\t\t\t\t// table.sheetN tr.rowYYYYYY { }\n\t\t\t\t$css['table.sheet' . $sheetIndex . ' tr.row' . $row] = array();\n\n\t\t\t\tif ($rowDimension->getRowHeight() == -1) {\n\t\t\t\t\t$pt_height = PHPExcel_Shared_Font::getDefaultRowHeightByFont($this->_phpExcel->getDefaultStyle()->getFont());\n\t\t\t\t} else {\n\t\t\t\t\t$pt_height = $rowDimension->getRowHeight();\n\t\t\t\t}\n\t\t\t\t$css['table.sheet' . $sheetIndex . ' tr.row' . $row]['height'] = $pt_height . 'pt';\n\t\t\t\tif ($rowDimension->getVisible() === false) {\n\t\t\t\t\t$css['table.sheet' . $sheetIndex . ' tr.row' . $row]['display'] = 'none';\n\t\t\t\t\t$css['table.sheet' . $sheetIndex . ' tr.row' . $row]['visibility'] = 'hidden';\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Cache\n\t\tif (is_null($this->_cssStyles)) {\n\t\t\t$this->_cssStyles = $css;\n\t\t}\n\n\t\t// Return\n\t\treturn $css;\n\t}\n\n\t/**\n\t * Create CSS style\n\t *\n\t * @param\tPHPExcel_Style\t\t$pStyle\t\t\tPHPExcel_Style\n\t * @return\tarray\n\t */\n\tprivate function _createCSSStyle(PHPExcel_Style $pStyle) {\n\t\t// Construct CSS\n\t\t$css = '';\n\n\t\t// Create CSS\n\t\t$css = array_merge(\n\t\t\t$this->_createCSSStyleAlignment($pStyle->getAlignment())\n\t\t\t, $this->_createCSSStyleBorders($pStyle->getBorders())\n\t\t\t, $this->_createCSSStyleFont($pStyle->getFont())\n\t\t\t, $this->_createCSSStyleFill($pStyle->getFill())\n\t\t);\n\n\t\t// Return\n\t\treturn $css;\n\t}\n\n\t/**\n\t * Create CSS style (PHPExcel_Style_Alignment)\n\t *\n\t * @param\tPHPExcel_Style_Alignment\t\t$pStyle\t\t\tPHPExcel_Style_Alignment\n\t * @return\tarray\n\t */\n\tprivate function _createCSSStyleAlignment(PHPExcel_Style_Alignment $pStyle) {\n\t\t// Construct CSS\n\t\t$css = array();\n\n\t\t// Create CSS\n\t\t$css['vertical-align'] = $this->_mapVAlign($pStyle->getVertical());\n\t\tif ($textAlign = $this->_mapHAlign($pStyle->getHorizontal())) {\n\t\t\t$css['text-align'] = $textAlign;\n\t\t\tif(in_array($textAlign,array('left','right')))\n\t\t\t\t$css['padding-'.$textAlign] = (string)((int)$pStyle->getIndent() * 9).'px';\n\t\t}\n\n\t\t// Return\n\t\treturn $css;\n\t}\n\n\t/**\n\t * Create CSS style (PHPExcel_Style_Font)\n\t *\n\t * @param\tPHPExcel_Style_Font\t\t$pStyle\t\t\tPHPExcel_Style_Font\n\t * @return\tarray\n\t */\n\tprivate function _createCSSStyleFont(PHPExcel_Style_Font $pStyle) {\n\t\t// Construct CSS\n\t\t$css = array();\n\n\t\t// Create CSS\n\t\tif ($pStyle->getBold()) {\n\t\t\t$css['font-weight'] = 'bold';\n\t\t}\n\t\tif ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE && $pStyle->getStrikethrough()) {\n\t\t\t$css['text-decoration'] = 'underline line-through';\n\t\t} else if ($pStyle->getUnderline() != PHPExcel_Style_Font::UNDERLINE_NONE) {\n\t\t\t$css['text-decoration'] = 'underline';\n\t\t} else if ($pStyle->getStrikethrough()) {\n\t\t\t$css['text-decoration'] = 'line-through';\n\t\t}\n\t\tif ($pStyle->getItalic()) {\n\t\t\t$css['font-style'] = 'italic';\n\t\t}\n\n\t\t$css['color']\t\t= '#' . $pStyle->getColor()->getRGB();\n\t\t$css['font-family']\t= '\\'' . $pStyle->getName() . '\\'';\n\t\t$css['font-size']\t= $pStyle->getSize() . 'pt';\n\n\t\t// Return\n\t\treturn $css;\n\t}\n\n\t/**\n\t * Create CSS style (PHPExcel_Style_Borders)\n\t *\n\t * @param\tPHPExcel_Style_Borders\t\t$pStyle\t\t\tPHPExcel_Style_Borders\n\t * @return\tarray\n\t */\n\tprivate function _createCSSStyleBorders(PHPExcel_Style_Borders $pStyle) {\n\t\t// Construct CSS\n\t\t$css = array();\n\n\t\t// Create CSS\n\t\t$css['border-bottom']\t= $this->_createCSSStyleBorder($pStyle->getBottom());\n\t\t$css['border-top']\t\t= $this->_createCSSStyleBorder($pStyle->getTop());\n\t\t$css['border-left']\t\t= $this->_createCSSStyleBorder($pStyle->getLeft());\n\t\t$css['border-right']\t= $this->_createCSSStyleBorder($pStyle->getRight());\n\n\t\t// Return\n\t\treturn $css;\n\t}\n\n\t/**\n\t * Create CSS style (PHPExcel_Style_Border)\n\t *\n\t * @param\tPHPExcel_Style_Border\t\t$pStyle\t\t\tPHPExcel_Style_Border\n\t * @return\tstring\n\t */\n\tprivate function _createCSSStyleBorder(PHPExcel_Style_Border $pStyle) {\n\t\t// Create CSS\n//\t\t$css = $this->_mapBorderStyle($pStyle->getBorderStyle()) . ' #' . $pStyle->getColor()->getRGB();\n\t\t//\tCreate CSS - add !important to non-none border styles for merged cells  \n\t\t$borderStyle = $this->_mapBorderStyle($pStyle->getBorderStyle());  \n\t\t$css = $borderStyle . ' #' . $pStyle->getColor()->getRGB() . (($borderStyle == 'none') ? '' : ' !important'); \n\n\t\t// Return\n\t\treturn $css;\n\t}\n\n\t/**\n\t * Create CSS style (PHPExcel_Style_Fill)\n\t *\n\t * @param\tPHPExcel_Style_Fill\t\t$pStyle\t\t\tPHPExcel_Style_Fill\n\t * @return\tarray\n\t */\n\tprivate function _createCSSStyleFill(PHPExcel_Style_Fill $pStyle) {\n\t\t// Construct HTML\n\t\t$css = array();\n\n\t\t// Create CSS\n\t\t$value = $pStyle->getFillType() == PHPExcel_Style_Fill::FILL_NONE ?\n\t\t\t'white' : '#' . $pStyle->getStartColor()->getRGB();\n\t\t$css['background-color'] = $value;\n\n\t\t// Return\n\t\treturn $css;\n\t}\n\n\t/**\n\t * Generate HTML footer\n\t */\n\tpublic function generateHTMLFooter() {\n\t\t// Construct HTML\n\t\t$html = '';\n\t\t$html .= '  </body>' . PHP_EOL;\n\t\t$html .= '</html>' . PHP_EOL;\n\n\t\t// Return\n\t\treturn $html;\n\t}\n\n\t/**\n\t * Generate table header\n\t *\n\t * @param\tPHPExcel_Worksheet\t$pSheet\t\tThe worksheet for the table we are writing\n\t * @return\tstring\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _generateTableHeader($pSheet) {\n\t\t$sheetIndex = $pSheet->getParent()->getIndex($pSheet);\n\n\t\t// Construct HTML\n\t\t$html = '';\n\t\t$html .= $this->_setMargins($pSheet);\n\t\t\t\n\t\tif (!$this->_useInlineCss) {\n\t\t\t$gridlines = $pSheet->getShowGridlines() ? ' gridlines' : '';\n\t\t\t$html .= '\t<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" id=\"sheet' . $sheetIndex . '\" class=\"sheet' . $sheetIndex . $gridlines . '\">' . PHP_EOL;\n\t\t} else {\n\t\t\t$style = isset($this->_cssStyles['table']) ?\n\t\t\t\t$this->_assembleCSS($this->_cssStyles['table']) : '';\n\n\t\t\tif ($this->_isPdf && $pSheet->getShowGridlines()) {\n\t\t\t\t$html .= '\t<table border=\"1\" cellpadding=\"1\" id=\"sheet' . $sheetIndex . '\" cellspacing=\"1\" style=\"' . $style . '\">' . PHP_EOL;\n\t\t\t} else {\n\t\t\t\t$html .= '\t<table border=\"0\" cellpadding=\"1\" id=\"sheet' . $sheetIndex . '\" cellspacing=\"0\" style=\"' . $style . '\">' . PHP_EOL;\n\t\t\t}\n\t\t}\n\n\t\t// Write <col> elements\n\t\t$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($pSheet->getHighestColumn()) - 1;\n\t\t$i = -1;\n\t\twhile($i++ < $highestColumnIndex) {\n\t\t    if (!$this->_isPdf) {\n\t\t\t\tif (!$this->_useInlineCss) {\n\t\t\t\t\t$html .= '\t\t<col class=\"col' . $i . '\">' . PHP_EOL;\n\t\t\t\t} else {\n\t\t\t\t\t$style = isset($this->_cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) ?\n\t\t\t\t\t\t$this->_assembleCSS($this->_cssStyles['table.sheet' . $sheetIndex . ' col.col' . $i]) : '';\n\t\t\t\t\t$html .= '\t\t<col style=\"' . $style . '\">' . PHP_EOL;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\t// Return\n\t\treturn $html;\n\t}\n\n\t/**\n\t * Generate table footer\n\t *\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _generateTableFooter() {\n\t\t// Construct HTML\n\t\t$html = '';\n\t\t$html .= '\t</table>' . PHP_EOL;\n\n\t\t// Return\n\t\treturn $html;\n\t}\n\n\t/**\n\t * Generate row\n\t *\n\t * @param\tPHPExcel_Worksheet\t$pSheet\t\t\tPHPExcel_Worksheet\n\t * @param\tarray\t\t\t\t$pValues\t\tArray containing cells in a row\n\t * @param\tint\t\t\t\t\t$pRow\t\t\tRow number (0-based)\n\t * @return\tstring\n\t * @throws\tPHPExcel_Writer_Exception\n\t */\n\tprivate function _generateRow(PHPExcel_Worksheet $pSheet, $pValues = null, $pRow = 0, $cellType = 'td') {\n\t\tif (is_array($pValues)) {\n\t\t\t// Construct HTML\n\t\t\t$html = '';\n\n\t\t\t// Sheet index\n\t\t\t$sheetIndex = $pSheet->getParent()->getIndex($pSheet);\n\n\t\t\t// DomPDF and breaks\n\t\t\tif ($this->_isPdf && count($pSheet->getBreaks()) > 0) {\n\t\t\t\t$breaks = $pSheet->getBreaks();\n\n\t\t\t\t// check if a break is needed before this row\n\t\t\t\tif (isset($breaks['A' . $pRow])) {\n\t\t\t\t\t// close table: </table>\n\t\t\t\t\t$html .= $this->_generateTableFooter();\n\n\t\t\t\t\t// insert page break\n\t\t\t\t\t$html .= '<div style=\"page-break-before:always\" />';\n\n\t\t\t\t\t// open table again: <table> + <col> etc.\n\t\t\t\t\t$html .= $this->_generateTableHeader($pSheet);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Write row start\n\t\t\tif (!$this->_useInlineCss) {\n\t\t\t\t$html .= '\t\t  <tr class=\"row' . $pRow . '\">' . PHP_EOL;\n\t\t\t} else {\n\t\t\t\t$style = isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow])\n\t\t\t\t\t? $this->_assembleCSS($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]) : '';\n\n\t\t\t\t$html .= '\t\t  <tr style=\"' . $style . '\">' . PHP_EOL;\n\t\t\t}\n\n\t\t\t// Write cells\n\t\t\t$colNum = 0;\n\t\t\tforeach ($pValues as $cellAddress) {\n                $cell = ($cellAddress > '') ? $pSheet->getCell($cellAddress) : '';\n\t\t\t\t$coordinate = PHPExcel_Cell::stringFromColumnIndex($colNum) . ($pRow + 1);\n\t\t\t\tif (!$this->_useInlineCss) {\n\t\t\t\t\t$cssClass = '';\n\t\t\t\t\t$cssClass = 'column' . $colNum;\n\t\t\t\t} else {\n\t\t\t\t\t$cssClass = array();\n                    if ($cellType == 'th') {\n                        if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum])) {\n                            $this->_cssStyles['table.sheet' . $sheetIndex . ' th.column' . $colNum];\n                        }\n                    } else {\n                        if (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum])) {\n                            $this->_cssStyles['table.sheet' . $sheetIndex . ' td.column' . $colNum];\n                        }\n                    }\n\t\t\t\t}\n\t\t\t\t$colSpan = 1;\n\t\t\t\t$rowSpan = 1;\n\n\t\t\t\t// initialize\n\t\t\t\t$cellData = '&nbsp;';\n\n\t\t\t\t// PHPExcel_Cell\n\t\t\t\tif ($cell instanceof PHPExcel_Cell) {\n\t\t\t\t\t$cellData = '';\n\t\t\t\t\tif (is_null($cell->getParent())) {\n\t\t\t\t\t\t$cell->attach($pSheet);\n\t\t\t\t\t}\n\t\t\t\t\t// Value\n\t\t\t\t\tif ($cell->getValue() instanceof PHPExcel_RichText) {\n\t\t\t\t\t\t// Loop through rich text elements\n\t\t\t\t\t\t$elements = $cell->getValue()->getRichTextElements();\n\t\t\t\t\t\tforeach ($elements as $element) {\n\t\t\t\t\t\t\t// Rich text start?\n\t\t\t\t\t\t\tif ($element instanceof PHPExcel_RichText_Run) {\n\t\t\t\t\t\t\t\t$cellData .= '<span style=\"' . $this->_assembleCSS($this->_createCSSStyleFont($element->getFont())) . '\">';\n\n\t\t\t\t\t\t\t\tif ($element->getFont()->getSuperScript()) {\n\t\t\t\t\t\t\t\t\t$cellData .= '<sup>';\n\t\t\t\t\t\t\t\t} else if ($element->getFont()->getSubScript()) {\n\t\t\t\t\t\t\t\t\t$cellData .= '<sub>';\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t// Convert UTF8 data to PCDATA\n\t\t\t\t\t\t\t$cellText = $element->getText();\n\t\t\t\t\t\t\t$cellData .= htmlspecialchars($cellText);\n\n\t\t\t\t\t\t\tif ($element instanceof PHPExcel_RichText_Run) {\n\t\t\t\t\t\t\t\tif ($element->getFont()->getSuperScript()) {\n\t\t\t\t\t\t\t\t\t$cellData .= '</sup>';\n\t\t\t\t\t\t\t\t} else if ($element->getFont()->getSubScript()) {\n\t\t\t\t\t\t\t\t\t$cellData .= '</sub>';\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t$cellData .= '</span>';\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tif ($this->_preCalculateFormulas) {\n\t\t\t\t\t\t\t$cellData = PHPExcel_Style_NumberFormat::toFormattedString(\n\t\t\t\t\t\t\t\t$cell->getCalculatedValue(),\n\t\t\t\t\t\t\t\t$pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getNumberFormat()->getFormatCode(),\n\t\t\t\t\t\t\t\tarray($this, 'formatColor')\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t$cellData = PHPExcel_Style_NumberFormat::toFormattedString(\n\t\t\t\t\t\t\t\t$cell->getValue(),\n\t\t\t\t\t\t\t\t$pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getNumberFormat()->getFormatCode(),\n\t\t\t\t\t\t\t\tarray($this, 'formatColor')\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t\t$cellData = htmlspecialchars($cellData);\n\t\t\t\t\t\tif ($pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getFont()->getSuperScript()) {\n\t\t\t\t\t\t\t$cellData = '<sup>'.$cellData.'</sup>';\n\t\t\t\t\t\t} elseif ($pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() )->getFont()->getSubScript()) {\n\t\t\t\t\t\t\t$cellData = '<sub>'.$cellData.'</sub>';\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\t// Converts the cell content so that spaces occuring at beginning of each new line are replaced by &nbsp;\n\t\t\t\t\t// Example: \"  Hello\\n to the world\" is converted to \"&nbsp;&nbsp;Hello\\n&nbsp;to the world\"\n\t\t\t\t\t$cellData = preg_replace(\"/(?m)(?:^|\\\\G) /\", '&nbsp;', $cellData);\n\n\t\t\t\t\t// convert newline \"\\n\" to '<br>'\n\t\t\t\t\t$cellData = nl2br($cellData);\n\n\t\t\t\t\t// Extend CSS class?\n\t\t\t\t\tif (!$this->_useInlineCss) {\n\t\t\t\t\t\t$cssClass .= ' style' . $cell->getXfIndex();\n\t\t\t\t\t\t$cssClass .= ' ' . $cell->getDataType();\n\t\t\t\t\t} else {\n                        if ($cellType == 'th') {\n                            if (isset($this->_cssStyles['th.style' . $cell->getXfIndex()])) {\n                                $cssClass = array_merge($cssClass, $this->_cssStyles['th.style' . $cell->getXfIndex()]);\n                            }\n                        } else {\n                            if (isset($this->_cssStyles['td.style' . $cell->getXfIndex()])) {\n                                $cssClass = array_merge($cssClass, $this->_cssStyles['td.style' . $cell->getXfIndex()]);\n                            }\n                        }\n\n\t\t\t\t\t\t// General horizontal alignment: Actual horizontal alignment depends on dataType\n\t\t\t\t\t\t$sharedStyle = $pSheet->getParent()->getCellXfByIndex( $cell->getXfIndex() );\n\t\t\t\t\t\tif ($sharedStyle->getAlignment()->getHorizontal() == PHPExcel_Style_Alignment::HORIZONTAL_GENERAL\n\t\t\t\t\t\t\t&& isset($this->_cssStyles['.' . $cell->getDataType()]['text-align']))\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$cssClass['text-align'] = $this->_cssStyles['.' . $cell->getDataType()]['text-align'];\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Hyperlink?\n\t\t\t\tif ($pSheet->hyperlinkExists($coordinate) && !$pSheet->getHyperlink($coordinate)->isInternal()) {\n\t\t\t\t\t$cellData = '<a href=\"' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getUrl()) . '\" title=\"' . htmlspecialchars($pSheet->getHyperlink($coordinate)->getTooltip()) . '\">' . $cellData . '</a>';\n\t\t\t\t}\n\n\t\t\t\t// Should the cell be written or is it swallowed by a rowspan or colspan?\n\t\t\t\t$writeCell = ! ( isset($this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])\n\t\t\t\t\t\t\t&& $this->_isSpannedCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum] );\n\n\t\t\t\t// Colspan and Rowspan\n\t\t\t\t$colspan = 1;\n\t\t\t\t$rowspan = 1;\n\t\t\t\tif (isset($this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum])) {\n\t\t\t\t\t$spans = $this->_isBaseCell[$pSheet->getParent()->getIndex($pSheet)][$pRow + 1][$colNum];\n\t\t\t\t\t$rowSpan = $spans['rowspan'];\n\t\t\t\t\t$colSpan = $spans['colspan'];\n\n\t\t\t\t\t//\tAlso apply style from last cell in merge to fix borders -\n\t\t\t\t\t//\t\trelies on !important for non-none border declarations in _createCSSStyleBorder\n\t\t\t\t\t$endCellCoord = PHPExcel_Cell::stringFromColumnIndex($colNum + $colSpan - 1) . ($pRow + $rowSpan);\n\t\t\t\t\tif (!$this->_useInlineCss) {\n\t\t\t\t\t\t$cssClass .= ' style' . $pSheet->getCell($endCellCoord)->getXfIndex();\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// Write\n\t\t\t\tif ($writeCell) {\n\t\t\t\t\t// Column start\n\t\t\t\t\t$html .= '\t\t\t<' . $cellType;\n\t\t\t\t\t\tif (!$this->_useInlineCss) {\n\t\t\t\t\t\t\t$html .= ' class=\"' . $cssClass . '\"';\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t//** Necessary redundant code for the sake of PHPExcel_Writer_PDF **\n\t\t\t\t\t\t\t// We must explicitly write the width of the <td> element because TCPDF\n\t\t\t\t\t\t\t// does not recognize e.g. <col style=\"width:42pt\">\n\t\t\t\t\t\t\t$width = 0;\n\t\t\t\t\t\t\t$i = $colNum - 1;\n\t\t\t\t\t\t\t$e = $colNum + $colSpan - 1;\n\t\t\t\t\t\t\twhile($i++ < $e) {\n\t\t\t\t\t\t\t\tif (isset($this->_columnWidths[$sheetIndex][$i])) {\n\t\t\t\t\t\t\t\t\t$width += $this->_columnWidths[$sheetIndex][$i];\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t$cssClass['width'] = $width . 'pt';\n\n\t\t\t\t\t\t\t// We must also explicitly write the height of the <td> element because TCPDF\n\t\t\t\t\t\t\t// does not recognize e.g. <tr style=\"height:50pt\">\n\t\t\t\t\t\t\tif (isset($this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'])) {\n\t\t\t\t\t\t\t\t$height = $this->_cssStyles['table.sheet' . $sheetIndex . ' tr.row' . $pRow]['height'];\n\t\t\t\t\t\t\t\t$cssClass['height'] = $height;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t//** end of redundant code **\n\n\t\t\t\t\t\t\t$html .= ' style=\"' . $this->_assembleCSS($cssClass) . '\"';\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ($colSpan > 1) {\n\t\t\t\t\t\t\t$html .= ' colspan=\"' . $colSpan . '\"';\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif ($rowSpan > 1) {\n\t\t\t\t\t\t\t$html .= ' rowspan=\"' . $rowSpan . '\"';\n\t\t\t\t\t\t}\n\t\t\t\t\t$html .= '>';\n\n\t\t\t\t\t// Image?\n\t\t\t\t\t$html .= $this->_writeImageInCell($pSheet, $coordinate);\n\n\t\t\t\t\t// Chart?\n\t\t\t\t\tif ($this->_includeCharts) {\n\t\t\t\t\t\t$html .= $this->_writeChartInCell($pSheet, $coordinate);\n\t\t\t\t\t}\n\n\t\t\t\t\t// Cell data\n\t\t\t\t\t$html .= $cellData;\n\n\t\t\t\t\t// Column end\n\t\t\t\t\t$html .= '</'.$cellType.'>' . PHP_EOL;\n\t\t\t\t}\n\n\t\t\t\t// Next column\n\t\t\t\t++$colNum;\n\t\t\t}\n\n\t\t\t// Write row end\n\t\t\t$html .= '\t\t  </tr>' . PHP_EOL;\n\n\t\t\t// Return\n\t\t\treturn $html;\n\t\t} else {\n\t\t\tthrow new PHPExcel_Writer_Exception(\"Invalid parameters passed.\");\n\t\t}\n\t}\n\n\t/**\n\t * Takes array where of CSS properties / values and converts to CSS string\n\t *\n\t * @param array\n\t * @return string\n\t */\n\tprivate function _assembleCSS($pValue = array())\n\t{\n\t\t$pairs = array();\n\t\tforeach ($pValue as $property => $value) {\n\t\t\t$pairs[] = $property . ':' . $value;\n\t\t}\n\t\t$string = implode('; ', $pairs);\n\n\t\treturn $string;\n\t}\n\n\t/**\n\t * Get images root\n\t *\n\t * @return string\n\t */\n\tpublic function getImagesRoot() {\n\t\treturn $this->_imagesRoot;\n\t}\n\n\t/**\n\t * Set images root\n\t *\n\t * @param string $pValue\n\t * @return PHPExcel_Writer_HTML\n\t */\n\tpublic function setImagesRoot($pValue = '.') {\n\t\t$this->_imagesRoot = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get embed images\n\t *\n\t * @return boolean\n\t */\n\tpublic function getEmbedImages() {\n\t\treturn $this->_embedImages;\n\t}\n\n\t/**\n\t * Set embed images\n\t *\n\t * @param boolean $pValue\n\t * @return PHPExcel_Writer_HTML\n\t */\n\tpublic function setEmbedImages($pValue = '.') {\n\t\t$this->_embedImages = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Get use inline CSS?\n\t *\n\t * @return boolean\n\t */\n\tpublic function getUseInlineCss() {\n\t\treturn $this->_useInlineCss;\n\t}\n\n\t/**\n\t * Set use inline CSS?\n\t *\n\t * @param boolean $pValue\n\t * @return PHPExcel_Writer_HTML\n\t */\n\tpublic function setUseInlineCss($pValue = false) {\n\t\t$this->_useInlineCss = $pValue;\n\t\treturn $this;\n\t}\n\n\t/**\n\t * Add color to formatted string as inline style\n\t *\n\t * @param string $pValue Plain formatted value without color\n\t * @param string $pFormat Format code\n\t * @return string\n\t */\n\tpublic function formatColor($pValue, $pFormat)\n\t{\n\t\t// Color information, e.g. [Red] is always at the beginning\n\t\t$color = null; // initialize\n\t\t$matches = array();\n\n\t\t$color_regex = '/^\\\\[[a-zA-Z]+\\\\]/';\n\t\tif (preg_match($color_regex, $pFormat, $matches)) {\n\t\t\t$color = str_replace('[', '', $matches[0]);\n\t\t\t$color = str_replace(']', '', $color);\n\t\t\t$color = strtolower($color);\n\t\t}\n\n\t\t// convert to PCDATA\n\t\t$value = htmlspecialchars($pValue);\n\n\t\t// color span tag\n\t\tif ($color !== null) {\n\t\t\t$value = '<span style=\"color:' . $color . '\">' . $value . '</span>';\n\t\t}\n\n\t\treturn $value;\n\t}\n\n\t/**\n\t * Calculate information about HTML colspan and rowspan which is not always the same as Excel's\n\t */\n\tprivate function _calculateSpans()\n\t{\n\t\t// Identify all cells that should be omitted in HTML due to cell merge.\n\t\t// In HTML only the upper-left cell should be written and it should have\n\t\t//   appropriate rowspan / colspan attribute\n\t\t$sheetIndexes = $this->_sheetIndex !== null ?\n\t\t\tarray($this->_sheetIndex) : range(0, $this->_phpExcel->getSheetCount() - 1);\n\n\t\tforeach ($sheetIndexes as $sheetIndex) {\n\t\t\t$sheet = $this->_phpExcel->getSheet($sheetIndex);\n\n\t\t\t$candidateSpannedRow  = array();\n\n\t\t\t// loop through all Excel merged cells\n\t\t\tforeach ($sheet->getMergeCells() as $cells) {\n\t\t\t\tlist($cells, ) = PHPExcel_Cell::splitRange($cells);\n\t\t\t\t$first = $cells[0];\n\t\t\t\t$last  = $cells[1];\n\n\t\t\t\tlist($fc, $fr) = PHPExcel_Cell::coordinateFromString($first);\n\t\t\t\t$fc = PHPExcel_Cell::columnIndexFromString($fc) - 1;\n\n\t\t\t\tlist($lc, $lr) = PHPExcel_Cell::coordinateFromString($last);\n\t\t\t\t$lc = PHPExcel_Cell::columnIndexFromString($lc) - 1;\n\n\t\t\t\t// loop through the individual cells in the individual merge\n\t\t\t\t$r = $fr - 1;\n\t\t\t\twhile($r++ < $lr) {\n\t\t\t\t\t// also, flag this row as a HTML row that is candidate to be omitted\n\t\t\t\t\t$candidateSpannedRow[$r] = $r;\n\n\t\t\t\t\t$c = $fc - 1;\n\t\t\t\t\twhile($c++ < $lc) {\n\t\t\t\t\t\tif ( !($c == $fc && $r == $fr) ) {\n\t\t\t\t\t\t\t// not the upper-left cell (should not be written in HTML)\n\t\t\t\t\t\t\t$this->_isSpannedCell[$sheetIndex][$r][$c] = array(\n\t\t\t\t\t\t\t\t'baseCell' => array($fr, $fc),\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t// upper-left is the base cell that should hold the colspan/rowspan attribute\n\t\t\t\t\t\t\t$this->_isBaseCell[$sheetIndex][$r][$c] = array(\n\t\t\t\t\t\t\t\t'xlrowspan' => $lr - $fr + 1, // Excel rowspan\n\t\t\t\t\t\t\t\t'rowspan'   => $lr - $fr + 1, // HTML rowspan, value may change\n\t\t\t\t\t\t\t\t'xlcolspan' => $lc - $fc + 1, // Excel colspan\n\t\t\t\t\t\t\t\t'colspan'   => $lc - $fc + 1, // HTML colspan, value may change\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// Identify which rows should be omitted in HTML. These are the rows where all the cells\n\t\t\t//   participate in a merge and the where base cells are somewhere above.\n\t\t\t$countColumns = PHPExcel_Cell::columnIndexFromString($sheet->getHighestColumn());\n\t\t\tforeach ($candidateSpannedRow as $rowIndex) {\n\t\t\t\tif (isset($this->_isSpannedCell[$sheetIndex][$rowIndex])) {\n\t\t\t\t\tif (count($this->_isSpannedCell[$sheetIndex][$rowIndex]) == $countColumns) {\n\t\t\t\t\t\t$this->_isSpannedRow[$sheetIndex][$rowIndex] = $rowIndex;\n\t\t\t\t\t};\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// For each of the omitted rows we found above, the affected rowspans should be subtracted by 1\n\t\t\tif ( isset($this->_isSpannedRow[$sheetIndex]) ) {\n\t\t\t\tforeach ($this->_isSpannedRow[$sheetIndex] as $rowIndex) {\n\t\t\t\t\t$adjustedBaseCells = array();\n\t\t\t\t\t$c = -1;\n\t\t\t\t\t$e = $countColumns - 1;\n\t\t\t\t\twhile($c++ < $e) {\n\t\t\t\t\t\t$baseCell = $this->_isSpannedCell[$sheetIndex][$rowIndex][$c]['baseCell'];\n\n\t\t\t\t\t\tif ( !in_array($baseCell, $adjustedBaseCells) ) {\n\t\t\t\t\t\t\t// subtract rowspan by 1\n\t\t\t\t\t\t\t--$this->_isBaseCell[$sheetIndex][ $baseCell[0] ][ $baseCell[1] ]['rowspan'];\n\t\t\t\t\t\t\t$adjustedBaseCells[] = $baseCell;\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\t// TODO: Same for columns\n\t\t}\n\n\t\t// We have calculated the spans\n\t\t$this->_spansAreCalculated = true;\n\t}\n\n\tprivate function _setMargins(PHPExcel_Worksheet $pSheet) {\n\t\t$htmlPage = '@page { ';\n\t\t$htmlBody = 'body { ';\n\n\t\t$left = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getLeft()) . 'in; ';\n\t\t$htmlPage .= 'left-margin: ' . $left;\n\t\t$htmlBody .= 'left-margin: ' . $left;\n\t\t$right = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getRight()) . 'in; ';\n\t\t$htmlPage .= 'right-margin: ' . $right;\n\t\t$htmlBody .= 'right-margin: ' . $right;\n\t\t$top = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getTop()) . 'in; ';\n\t\t$htmlPage .= 'top-margin: ' . $top;\n\t\t$htmlBody .= 'top-margin: ' . $top;\n\t\t$bottom = PHPExcel_Shared_String::FormatNumber($pSheet->getPageMargins()->getBottom()) . 'in; ';\n\t\t$htmlPage .= 'bottom-margin: ' . $bottom;\n\t\t$htmlBody .= 'bottom-margin: ' . $bottom;\n\n\t\t$htmlPage .= \"}\\n\";\n\t\t$htmlBody .= \"}\\n\";\n\n\t\treturn \"<style>\\n\" . $htmlPage . $htmlBody . \"</style>\\n\";\n\t}\n\t\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/IWriter.php",
    "content": "<?php\n/**\n *  PHPExcel\n *\n *  Copyright (c) 2006 - 2014 PHPExcel\n *\n *  This library is free software; you can redistribute it and/or\n *  modify it under the terms of the GNU Lesser General Public\n *  License as published by the Free Software Foundation; either\n *  version 2.1 of the License, or (at your option) any later version.\n *\n *  This library is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n *  Lesser General Public License for more details.\n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; if not, write to the Free Software\n *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n *  @category   PHPExcel\n *  @package    PHPExcel_Writer\n *  @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n *  @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n *  @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n *  PHPExcel_Writer_IWriter\n *\n *  @category   PHPExcel\n *  @package    PHPExcel_Writer\n *  @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\ninterface PHPExcel_Writer_IWriter\n{\n    /**\n     *  Save PHPExcel to file\n     *\n     *  @param   string       $pFilename  Name of the file to save\n     *  @throws  PHPExcel_Writer_Exception\n     */\n    public function save($pFilename = NULL);\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Cell/Comment.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_OpenDocument_Cell_Comment\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @author     Alexander Pervakov <frost-nzcr4@jagmort.com>\n */\nclass PHPExcel_Writer_OpenDocument_Cell_Comment\n{\n    public static function write(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Cell $cell)\n    {\n        $comments = $cell->getWorksheet()->getComments();\n        if (!isset($comments[$cell->getCoordinate()])) {\n            return;\n        }\n        $comment = $comments[$cell->getCoordinate()];\n\n        $objWriter->startElement('office:annotation');\n            //$objWriter->writeAttribute('draw:style-name', 'gr1');\n            //$objWriter->writeAttribute('draw:text-style-name', 'P1');\n            $objWriter->writeAttribute('svg:width', $comment->getWidth());\n            $objWriter->writeAttribute('svg:height', $comment->getHeight());\n            $objWriter->writeAttribute('svg:x', $comment->getMarginLeft());\n            $objWriter->writeAttribute('svg:y', $comment->getMarginTop());\n            //$objWriter->writeAttribute('draw:caption-point-x', $comment->getMarginLeft());\n            //$objWriter->writeAttribute('draw:caption-point-y', $comment->getMarginTop());\n                $objWriter->writeElement('dc:creator', $comment->getAuthor());\n                // TODO: Not realized in PHPExcel_Comment yet.\n                //$objWriter->writeElement('dc:date', $comment->getDate());\n                $objWriter->writeElement('text:p', $comment->getText()->getPlainText());\n                    //$objWriter->writeAttribute('draw:text-style-name', 'P1');\n        $objWriter->endElement();\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Content.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_OpenDocument_Content\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @author     Alexander Pervakov <frost-nzcr4@jagmort.com>\n */\nclass PHPExcel_Writer_OpenDocument_Content extends PHPExcel_Writer_OpenDocument_WriterPart\n{\n    const NUMBER_COLS_REPEATED_MAX = 1024;\n    const NUMBER_ROWS_REPEATED_MAX = 1048576;\n\n    /**\n     * Write content.xml to XML format\n     *\n     * @param   PHPExcel                   $pPHPExcel\n     * @return  string                     XML Output\n     * @throws  PHPExcel_Writer_Exception\n     */\n    public function write(PHPExcel $pPHPExcel = null)\n    {\n        if (!$pPHPExcel) {\n            $pPHPExcel = $this->getParentWriter()->getPHPExcel(); /* @var $pPHPExcel PHPExcel */\n        }\n\n        $objWriter = null;\n        if ($this->getParentWriter()->getUseDiskCaching()) {\n            $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n        } else {\n            $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n        }\n\n        // XML header\n        $objWriter->startDocument('1.0', 'UTF-8');\n\n        // Content\n        $objWriter->startElement('office:document-content');\n            $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');\n            $objWriter->writeAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0');\n            $objWriter->writeAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0');\n            $objWriter->writeAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0');\n            $objWriter->writeAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0');\n            $objWriter->writeAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0');\n            $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');\n            $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');\n            $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0');\n            $objWriter->writeAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0');\n            $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0');\n            $objWriter->writeAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0');\n            $objWriter->writeAttribute('xmlns:chart', 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0');\n            $objWriter->writeAttribute('xmlns:dr3d', 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0');\n            $objWriter->writeAttribute('xmlns:math', 'http://www.w3.org/1998/Math/MathML');\n            $objWriter->writeAttribute('xmlns:form', 'urn:oasis:names:tc:opendocument:xmlns:form:1.0');\n            $objWriter->writeAttribute('xmlns:script', 'urn:oasis:names:tc:opendocument:xmlns:script:1.0');\n            $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');\n            $objWriter->writeAttribute('xmlns:ooow', 'http://openoffice.org/2004/writer');\n            $objWriter->writeAttribute('xmlns:oooc', 'http://openoffice.org/2004/calc');\n            $objWriter->writeAttribute('xmlns:dom', 'http://www.w3.org/2001/xml-events');\n            $objWriter->writeAttribute('xmlns:xforms', 'http://www.w3.org/2002/xforms');\n            $objWriter->writeAttribute('xmlns:xsd', 'http://www.w3.org/2001/XMLSchema');\n            $objWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');\n            $objWriter->writeAttribute('xmlns:rpt', 'http://openoffice.org/2005/report');\n            $objWriter->writeAttribute('xmlns:of', 'urn:oasis:names:tc:opendocument:xmlns:of:1.2');\n            $objWriter->writeAttribute('xmlns:xhtml', 'http://www.w3.org/1999/xhtml');\n            $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#');\n            $objWriter->writeAttribute('xmlns:tableooo', 'http://openoffice.org/2009/table');\n            $objWriter->writeAttribute('xmlns:field', 'urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0');\n            $objWriter->writeAttribute('xmlns:formx', 'urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0');\n            $objWriter->writeAttribute('xmlns:css3t', 'http://www.w3.org/TR/css3-text/');\n            $objWriter->writeAttribute('office:version', '1.2');\n\n            $objWriter->writeElement('office:scripts');\n            $objWriter->writeElement('office:font-face-decls');\n            $objWriter->writeElement('office:automatic-styles');\n\n            $objWriter->startElement('office:body');\n                $objWriter->startElement('office:spreadsheet');\n                    $objWriter->writeElement('table:calculation-settings');\n                    $this->_writeSheets($objWriter);\n                    $objWriter->writeElement('table:named-expressions');\n                $objWriter->endElement();\n            $objWriter->endElement();\n        $objWriter->endElement();\n\n        return $objWriter->getData();\n    }\n\n    /**\n     * Write sheets\n     *\n     * @param PHPExcel_Shared_XMLWriter $objWriter\n     */\n    private function _writeSheets(PHPExcel_Shared_XMLWriter $objWriter)\n    {\n        $pPHPExcel = $this->getParentWriter()->getPHPExcel(); /* @var $pPHPExcel PHPExcel */\n\n        $sheet_count = $pPHPExcel->getSheetCount();\n        for ($i = 0; $i < $sheet_count; $i++) {\n            //$this->getWriterPart('Worksheet')->writeWorksheet());\n            $objWriter->startElement('table:table');\n                $objWriter->writeAttribute('table:name', $pPHPExcel->getSheet($i)->getTitle());\n                $objWriter->writeElement('office:forms');\n                $objWriter->startElement('table:table-column');\n                    $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);\n                $objWriter->endElement();\n                $this->_writeRows($objWriter, $pPHPExcel->getSheet($i));\n            $objWriter->endElement();\n        }\n    }\n\n    /**\n     * Write rows of the specified sheet\n     *\n     * @param PHPExcel_Shared_XMLWriter $objWriter\n     * @param PHPExcel_Worksheet $sheet\n     */\n    private function _writeRows(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Worksheet $sheet)\n    {\n        $number_rows_repeated = self::NUMBER_ROWS_REPEATED_MAX;\n        $span_row = 0;\n        $rows = $sheet->getRowIterator();\n        while ($rows->valid()) {\n            $number_rows_repeated--;\n            $row = $rows->current();\n            if ($row->getCellIterator()->valid()) {\n                if ($span_row) {\n                    $objWriter->startElement('table:table-row');\n                    if ($span_row > 1) {\n                        $objWriter->writeAttribute('table:number-rows-repeated', $span_row);\n                    }\n                    $objWriter->startElement('table:table-cell');\n                        $objWriter->writeAttribute('table:number-columns-repeated', self::NUMBER_COLS_REPEATED_MAX);\n                    $objWriter->endElement();\n                    $objWriter->endElement();\n                    $span_row = 0;\n                }\n                $objWriter->startElement('table:table-row');\n                $this->_writeCells($objWriter, $row);\n                $objWriter->endElement();\n            } else {\n                $span_row++;\n            }\n            $rows->next();\n        }\n    }\n\n    /**\n     * Write cells of the specified row\n     *\n     * @param PHPExcel_Shared_XMLWriter $objWriter\n     * @param PHPExcel_Worksheet_Row $row\n     * @throws PHPExcel_Writer_Exception\n     */\n    private function _writeCells(PHPExcel_Shared_XMLWriter $objWriter, PHPExcel_Worksheet_Row $row)\n    {\n        $number_cols_repeated = self::NUMBER_COLS_REPEATED_MAX;\n        $prev_column = -1;\n        $cells = $row->getCellIterator();\n        while ($cells->valid()) {\n            $cell = $cells->current();\n            $column = PHPExcel_Cell::columnIndexFromString($cell->getColumn()) - 1;\n\n            $this->_writeCellSpan($objWriter, $column, $prev_column);\n            $objWriter->startElement('table:table-cell');\n\n            switch ($cell->getDataType()) {\n                case PHPExcel_Cell_DataType::TYPE_BOOL:\n                    $objWriter->writeAttribute('office:value-type', 'boolean');\n                    $objWriter->writeAttribute('office:value', $cell->getValue());\n                    $objWriter->writeElement('text:p', $cell->getValue());\n                    break;\n\n                case PHPExcel_Cell_DataType::TYPE_ERROR:\n                    throw new PHPExcel_Writer_Exception('Writing of error not implemented yet.');\n                    break;\n\n                case PHPExcel_Cell_DataType::TYPE_FORMULA:\n                    try {\n                        $formula_value = $cell->getCalculatedValue();\n                    } catch (Exception $e) {\n                        $formula_value = $cell->getValue();\n                    }\n                    $objWriter->writeAttribute('table:formula', 'of:' . $cell->getValue());\n                    if (is_numeric($formula_value)) {\n                        $objWriter->writeAttribute('office:value-type', 'float');\n                    } else {\n                        $objWriter->writeAttribute('office:value-type', 'string');\n                    }\n                    $objWriter->writeAttribute('office:value', $formula_value);\n                    $objWriter->writeElement('text:p', $formula_value);\n                    break;\n\n                case PHPExcel_Cell_DataType::TYPE_INLINE:\n                    throw new PHPExcel_Writer_Exception('Writing of inline not implemented yet.');\n                    break;\n\n                case PHPExcel_Cell_DataType::TYPE_NUMERIC:\n                    $objWriter->writeAttribute('office:value-type', 'float');\n                    $objWriter->writeAttribute('office:value', $cell->getValue());\n                    $objWriter->writeElement('text:p', $cell->getValue());\n                    break;\n\n                case PHPExcel_Cell_DataType::TYPE_STRING:\n                    $objWriter->writeAttribute('office:value-type', 'string');\n                    $objWriter->writeElement('text:p', $cell->getValue());\n                    break;\n            }\n            PHPExcel_Writer_OpenDocument_Cell_Comment::write($objWriter, $cell);\n            $objWriter->endElement();\n            $prev_column = $column;\n            $cells->next();\n        }\n        $number_cols_repeated = $number_cols_repeated - $prev_column - 1;\n        if ($number_cols_repeated > 0) {\n            if ($number_cols_repeated > 1) {\n                $objWriter->startElement('table:table-cell');\n                $objWriter->writeAttribute('table:number-columns-repeated', $number_cols_repeated);\n                $objWriter->endElement();\n            } else {\n                $objWriter->writeElement('table:table-cell');\n            }\n        }\n    }\n\n    /**\n     * Write span\n     *\n     * @param PHPExcel_Shared_XMLWriter $objWriter\n     * @param integer $curColumn\n     * @param integer $prevColumn\n     */\n    private function _writeCellSpan(PHPExcel_Shared_XMLWriter $objWriter, $curColumn, $prevColumn)\n    {\n        $diff = $curColumn - $prevColumn - 1;\n        if (1 === $diff) {\n            $objWriter->writeElement('table:table-cell');\n        } elseif ($diff > 1) {\n            $objWriter->startElement('table:table-cell');\n                $objWriter->writeAttribute('table:number-columns-repeated', $diff);\n            $objWriter->endElement();\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Meta.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_OpenDocument_Meta\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @author     Alexander Pervakov <frost-nzcr4@jagmort.com>\n */\nclass PHPExcel_Writer_OpenDocument_Meta extends PHPExcel_Writer_OpenDocument_WriterPart\n{\n    /**\n     * Write meta.xml to XML format\n     *\n     * @param   PHPExcel                   $pPHPExcel\n     * @return  string                     XML Output\n     * @throws  PHPExcel_Writer_Exception\n     */\n    public function write(PHPExcel $pPHPExcel = null)\n    {\n        if (!$pPHPExcel) {\n            $pPHPExcel = $this->getParentWriter()->getPHPExcel();\n        }\n\n        $objWriter = null;\n        if ($this->getParentWriter()->getUseDiskCaching()) {\n            $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n        } else {\n            $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n        }\n\n        // XML header\n        $objWriter->startDocument('1.0', 'UTF-8');\n\n        // Meta\n        $objWriter->startElement('office:document-meta');\n            $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');\n            $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');\n            $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');\n            $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0');\n            $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');\n            $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#');\n            $objWriter->writeAttribute('office:version', '1.2');\n\n            $objWriter->startElement('office:meta');\n                $objWriter->writeElement('meta:initial-creator', $pPHPExcel->getProperties()->getCreator());\n                $objWriter->writeElement('dc:creator', $pPHPExcel->getProperties()->getCreator());\n                $objWriter->writeElement('meta:creation-date', date(DATE_W3C, $pPHPExcel->getProperties()->getCreated()));\n                $objWriter->writeElement('dc:date', date(DATE_W3C, $pPHPExcel->getProperties()->getCreated()));\n                $objWriter->writeElement('dc:title', $pPHPExcel->getProperties()->getTitle());\n                $objWriter->writeElement('dc:description', $pPHPExcel->getProperties()->getDescription());\n                $objWriter->writeElement('dc:subject', $pPHPExcel->getProperties()->getSubject());\n                $keywords = explode(' ', $pPHPExcel->getProperties()->getKeywords());\n                foreach ($keywords as $keyword) {\n                    $objWriter->writeElement('meta:keyword', $keyword);\n                }\n                //<meta:document-statistic meta:table-count=\"XXX\" meta:cell-count=\"XXX\" meta:object-count=\"XXX\"/>\n                $objWriter->startElement('meta:user-defined');\n                    $objWriter->writeAttribute('meta:name', 'Company');\n                    $objWriter->writeRaw($pPHPExcel->getProperties()->getCompany());\n                $objWriter->endElement();\n                $objWriter->startElement('meta:user-defined');\n                    $objWriter->writeAttribute('meta:name', 'category');\n                    $objWriter->writeRaw($pPHPExcel->getProperties()->getCategory());\n                $objWriter->endElement();\n            $objWriter->endElement();\n        $objWriter->endElement();\n\n        return $objWriter->getData();\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/MetaInf.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_OpenDocument_MetaInf\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @author     Alexander Pervakov <frost-nzcr4@jagmort.com>\n */\nclass PHPExcel_Writer_OpenDocument_MetaInf extends PHPExcel_Writer_OpenDocument_WriterPart\n{\n    /**\n     * Write META-INF/manifest.xml to XML format\n     *\n     * @param     PHPExcel    $pPHPExcel\n     * @return     string         XML Output\n     * @throws     PHPExcel_Writer_Exception\n     */\n    public function writeManifest(PHPExcel $pPHPExcel = null)\n    {\n        if (!$pPHPExcel) {\n            $pPHPExcel = $this->getParentWriter()->getPHPExcel();\n        }\n\n        $objWriter = null;\n        if ($this->getParentWriter()->getUseDiskCaching()) {\n            $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n        } else {\n            $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n        }\n\n        // XML header\n        $objWriter->startDocument('1.0', 'UTF-8');\n\n        // Manifest\n        $objWriter->startElement('manifest:manifest');\n            $objWriter->writeAttribute('xmlns:manifest', 'urn:oasis:names:tc:opendocument:xmlns:manifest:1.0');\n            $objWriter->writeAttribute('manifest:version', '1.2');\n\n            $objWriter->startElement('manifest:file-entry');\n                $objWriter->writeAttribute('manifest:full-path', '/');\n                $objWriter->writeAttribute('manifest:version', '1.2');\n                $objWriter->writeAttribute('manifest:media-type', 'application/vnd.oasis.opendocument.spreadsheet');\n            $objWriter->endElement();\n            $objWriter->startElement('manifest:file-entry');\n                $objWriter->writeAttribute('manifest:full-path', 'meta.xml');\n                $objWriter->writeAttribute('manifest:media-type', 'text/xml');\n            $objWriter->endElement();\n            $objWriter->startElement('manifest:file-entry');\n                $objWriter->writeAttribute('manifest:full-path', 'settings.xml');\n                $objWriter->writeAttribute('manifest:media-type', 'text/xml');\n            $objWriter->endElement();\n            $objWriter->startElement('manifest:file-entry');\n                $objWriter->writeAttribute('manifest:full-path', 'content.xml');\n                $objWriter->writeAttribute('manifest:media-type', 'text/xml');\n            $objWriter->endElement();\n            $objWriter->startElement('manifest:file-entry');\n                $objWriter->writeAttribute('manifest:full-path', 'Thumbnails/thumbnail.png');\n                $objWriter->writeAttribute('manifest:media-type', 'image/png');\n            $objWriter->endElement();\n            $objWriter->startElement('manifest:file-entry');\n                $objWriter->writeAttribute('manifest:full-path', 'styles.xml');\n                $objWriter->writeAttribute('manifest:media-type', 'text/xml');\n            $objWriter->endElement();\n        $objWriter->endElement();\n\n        return $objWriter->getData();\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Mimetype.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_OpenDocument_Mimetype\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @author     Alexander Pervakov <frost-nzcr4@jagmort.com>\n */\nclass PHPExcel_Writer_OpenDocument_Mimetype extends PHPExcel_Writer_OpenDocument_WriterPart\n{\n    /**\n     * Write mimetype to plain text format\n     *\n     * @param     PHPExcel    $pPHPExcel\n     * @return     string         XML Output\n     * @throws     PHPExcel_Writer_Exception\n     */\n    public function write(PHPExcel $pPHPExcel = null)\n    {\n        return 'application/vnd.oasis.opendocument.spreadsheet';\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Settings.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_OpenDocument_Settings\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @author     Alexander Pervakov <frost-nzcr4@jagmort.com>\n */\nclass PHPExcel_Writer_OpenDocument_Settings extends PHPExcel_Writer_OpenDocument_WriterPart\n{\n    /**\n     * Write settings.xml to XML format\n     *\n     * @param   PHPExcel                   $pPHPExcel\n     * @return  string                     XML Output\n     * @throws  PHPExcel_Writer_Exception\n     */\n    public function write(PHPExcel $pPHPExcel = null)\n    {\n        if (!$pPHPExcel) {\n            $pPHPExcel = $this->getParentWriter()->getPHPExcel();\n        }\n\n        $objWriter = null;\n        if ($this->getParentWriter()->getUseDiskCaching()) {\n            $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n        } else {\n            $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n        }\n\n        // XML header\n        $objWriter->startDocument('1.0', 'UTF-8');\n\n        // Settings\n        $objWriter->startElement('office:document-settings');\n            $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');\n            $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');\n            $objWriter->writeAttribute('xmlns:config', 'urn:oasis:names:tc:opendocument:xmlns:config:1.0');\n            $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');\n            $objWriter->writeAttribute('office:version', '1.2');\n\n            $objWriter->startElement('office:settings');\n                $objWriter->startElement('config:config-item-set');\n                    $objWriter->writeAttribute('config:name', 'ooo:view-settings');\n                    $objWriter->startElement('config:config-item-map-indexed');\n                        $objWriter->writeAttribute('config:name', 'Views');\n                    $objWriter->endElement();\n                $objWriter->endElement();\n                $objWriter->startElement('config:config-item-set');\n                    $objWriter->writeAttribute('config:name', 'ooo:configuration-settings');\n                $objWriter->endElement();\n            $objWriter->endElement();\n        $objWriter->endElement();\n\n        return $objWriter->getData();\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Styles.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_OpenDocument_Styles\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @author     Alexander Pervakov <frost-nzcr4@jagmort.com>\n */\nclass PHPExcel_Writer_OpenDocument_Styles extends PHPExcel_Writer_OpenDocument_WriterPart\n{\n    /**\n     * Write styles.xml to XML format\n     *\n     * @param   PHPExcel                   $pPHPExcel\n     * @return  string                     XML Output\n     * @throws  PHPExcel_Writer_Exception\n     */\n    public function write(PHPExcel $pPHPExcel = null)\n    {\n        if (!$pPHPExcel) {\n            $pPHPExcel = $this->getParentWriter()->getPHPExcel();\n        }\n\n        $objWriter = null;\n        if ($this->getParentWriter()->getUseDiskCaching()) {\n            $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());\n        } else {\n            $objWriter = new PHPExcel_Shared_XMLWriter(PHPExcel_Shared_XMLWriter::STORAGE_MEMORY);\n        }\n\n        // XML header\n        $objWriter->startDocument('1.0', 'UTF-8');\n\n        // Content\n        $objWriter->startElement('office:document-styles');\n            $objWriter->writeAttribute('xmlns:office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');\n            $objWriter->writeAttribute('xmlns:style', 'urn:oasis:names:tc:opendocument:xmlns:style:1.0');\n            $objWriter->writeAttribute('xmlns:text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0');\n            $objWriter->writeAttribute('xmlns:table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0');\n            $objWriter->writeAttribute('xmlns:draw', 'urn:oasis:names:tc:opendocument:xmlns:drawing:1.0');\n            $objWriter->writeAttribute('xmlns:fo', 'urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0');\n            $objWriter->writeAttribute('xmlns:xlink', 'http://www.w3.org/1999/xlink');\n            $objWriter->writeAttribute('xmlns:dc', 'http://purl.org/dc/elements/1.1/');\n            $objWriter->writeAttribute('xmlns:meta', 'urn:oasis:names:tc:opendocument:xmlns:meta:1.0');\n            $objWriter->writeAttribute('xmlns:number', 'urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0');\n            $objWriter->writeAttribute('xmlns:presentation', 'urn:oasis:names:tc:opendocument:xmlns:presentation:1.0');\n            $objWriter->writeAttribute('xmlns:svg', 'urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0');\n            $objWriter->writeAttribute('xmlns:chart', 'urn:oasis:names:tc:opendocument:xmlns:chart:1.0');\n            $objWriter->writeAttribute('xmlns:dr3d', 'urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0');\n            $objWriter->writeAttribute('xmlns:math', 'http://www.w3.org/1998/Math/MathML');\n            $objWriter->writeAttribute('xmlns:form', 'urn:oasis:names:tc:opendocument:xmlns:form:1.0');\n            $objWriter->writeAttribute('xmlns:script', 'urn:oasis:names:tc:opendocument:xmlns:script:1.0');\n            $objWriter->writeAttribute('xmlns:ooo', 'http://openoffice.org/2004/office');\n            $objWriter->writeAttribute('xmlns:ooow', 'http://openoffice.org/2004/writer');\n            $objWriter->writeAttribute('xmlns:oooc', 'http://openoffice.org/2004/calc');\n            $objWriter->writeAttribute('xmlns:dom', 'http://www.w3.org/2001/xml-events');\n            $objWriter->writeAttribute('xmlns:rpt', 'http://openoffice.org/2005/report');\n            $objWriter->writeAttribute('xmlns:of', 'urn:oasis:names:tc:opendocument:xmlns:of:1.2');\n            $objWriter->writeAttribute('xmlns:xhtml', 'http://www.w3.org/1999/xhtml');\n            $objWriter->writeAttribute('xmlns:grddl', 'http://www.w3.org/2003/g/data-view#');\n            $objWriter->writeAttribute('xmlns:tableooo', 'http://openoffice.org/2009/table');\n            $objWriter->writeAttribute('xmlns:css3t', 'http://www.w3.org/TR/css3-text/');\n            $objWriter->writeAttribute('office:version', '1.2');\n\n            $objWriter->writeElement('office:font-face-decls');\n            $objWriter->writeElement('office:styles');\n            $objWriter->writeElement('office:automatic-styles');\n            $objWriter->writeElement('office:master-styles');\n        $objWriter->endElement();\n\n        return $objWriter->getData();\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/Thumbnails.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_OpenDocument_Thumbnails\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @author     Alexander Pervakov <frost-nzcr4@jagmort.com>\n */\nclass PHPExcel_Writer_OpenDocument_Thumbnails extends PHPExcel_Writer_OpenDocument_WriterPart\n{\n    /**\n     * Write Thumbnails/thumbnail.png to PNG format\n     *\n     * @param   PHPExcel                   $pPHPExcel\n     * @return  string                     XML Output\n     * @throws  PHPExcel_Writer_Exception\n     */\n    public function writeThumbnail(PHPExcel $pPHPExcel = null)\n    {\n        return '';\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument/WriterPart.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_OpenDocument_WriterPart\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nabstract class PHPExcel_Writer_OpenDocument_WriterPart extends PHPExcel_Writer_Excel2007_WriterPart\n{\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/OpenDocument.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/**\n * PHPExcel_Writer_OpenDocument\n *\n * @category   PHPExcel\n * @package    PHPExcel_Writer_OpenDocument\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @author     Alexander Pervakov <frost-nzcr4@jagmort.com>\n * @link       http://docs.oasis-open.org/office/v1.2/os/OpenDocument-v1.2-os.html\n */\nclass PHPExcel_Writer_OpenDocument extends PHPExcel_Writer_Abstract implements PHPExcel_Writer_IWriter\n{\n    /**\n     * Private writer parts\n     *\n     * @var PHPExcel_Writer_OpenDocument_WriterPart[]\n     */\n    private $_writerParts = array();\n\n    /**\n     * Private PHPExcel\n     *\n     * @var PHPExcel\n     */\n    private $_spreadSheet;\n\n    /**\n     * Create a new PHPExcel_Writer_OpenDocument\n     *\n     * @param PHPExcel $pPHPExcel\n     */\n    public function __construct(PHPExcel $pPHPExcel = null)\n    {\n        $this->setPHPExcel($pPHPExcel);\n\n        $writerPartsArray = array(\n            'content'    => 'PHPExcel_Writer_OpenDocument_Content',\n            'meta'       => 'PHPExcel_Writer_OpenDocument_Meta',\n            'meta_inf'   => 'PHPExcel_Writer_OpenDocument_MetaInf',\n            'mimetype'   => 'PHPExcel_Writer_OpenDocument_Mimetype',\n            'settings'   => 'PHPExcel_Writer_OpenDocument_Settings',\n            'styles'     => 'PHPExcel_Writer_OpenDocument_Styles',\n            'thumbnails' => 'PHPExcel_Writer_OpenDocument_Thumbnails'\n        );\n\n        foreach ($writerPartsArray as $writer => $class) {\n            $this->_writerParts[$writer] = new $class($this);\n        }\n    }\n\n    /**\n     * Get writer part\n     *\n     * @param  string  $pPartName  Writer part name\n     * @return PHPExcel_Writer_Excel2007_WriterPart\n     */\n    public function getWriterPart($pPartName = '')\n    {\n        if ($pPartName != '' && isset($this->_writerParts[strtolower($pPartName)])) {\n            return $this->_writerParts[strtolower($pPartName)];\n        } else {\n            return null;\n        }\n    }\n\n    /**\n     * Save PHPExcel to file\n     *\n     * @param  string  $pFilename\n     * @throws PHPExcel_Writer_Exception\n     */\n    public function save($pFilename = NULL)\n    {\n        if (!$this->_spreadSheet) {\n            throw new PHPExcel_Writer_Exception('PHPExcel object unassigned.');\n        }\n\n        // garbage collect\n        $this->_spreadSheet->garbageCollect();\n\n        // If $pFilename is php://output or php://stdout, make it a temporary file...\n        $originalFilename = $pFilename;\n        if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {\n            $pFilename = @tempnam(PHPExcel_Shared_File::sys_get_temp_dir(), 'phpxltmp');\n            if ($pFilename == '') {\n                $pFilename = $originalFilename;\n            }\n        }\n\n        $objZip = $this->_createZip($pFilename);\n\n        $objZip->addFromString('META-INF/manifest.xml', $this->getWriterPart('meta_inf')->writeManifest());\n        $objZip->addFromString('Thumbnails/thumbnail.png', $this->getWriterPart('thumbnails')->writeThumbnail());\n        $objZip->addFromString('content.xml',  $this->getWriterPart('content')->write());\n        $objZip->addFromString('meta.xml',     $this->getWriterPart('meta')->write());\n        $objZip->addFromString('mimetype',     $this->getWriterPart('mimetype')->write());\n        $objZip->addFromString('settings.xml', $this->getWriterPart('settings')->write());\n        $objZip->addFromString('styles.xml',   $this->getWriterPart('styles')->write());\n\n        // Close file\n        if ($objZip->close() === false) {\n            throw new PHPExcel_Writer_Exception(\"Could not close zip file $pFilename.\");\n        }\n\n        // If a temporary file was used, copy it to the correct file stream\n        if ($originalFilename != $pFilename) {\n            if (copy($pFilename, $originalFilename) === false) {\n                throw new PHPExcel_Writer_Exception(\"Could not copy temporary zip file $pFilename to $originalFilename.\");\n            }\n            @unlink($pFilename);\n        }\n    }\n\n    /**\n     * Create zip object\n     *\n     * @param string $pFilename\n     * @throws PHPExcel_Writer_Exception\n     * @return ZipArchive\n     */\n    private function _createZip($pFilename)\n    {\n        // Create new ZIP file and open it for writing\n        $zipClass = PHPExcel_Settings::getZipClass();\n        $objZip = new $zipClass();\n\n        // Retrieve OVERWRITE and CREATE constants from the instantiated zip class\n        // This method of accessing constant values from a dynamic class should work with all appropriate versions of PHP\n        $ro = new ReflectionObject($objZip);\n        $zipOverWrite = $ro->getConstant('OVERWRITE');\n        $zipCreate = $ro->getConstant('CREATE');\n\n        if (file_exists($pFilename)) {\n            unlink($pFilename);\n        }\n        // Try opening the ZIP file\n        if ($objZip->open($pFilename, $zipOverWrite) !== true) {\n            if ($objZip->open($pFilename, $zipCreate) !== true) {\n                throw new PHPExcel_Writer_Exception(\"Could not open $pFilename for writing.\");\n            }\n        }\n\n        return $objZip;\n    }\n\n    /**\n     * Get PHPExcel object\n     *\n     * @return PHPExcel\n     * @throws PHPExcel_Writer_Exception\n     */\n    public function getPHPExcel()\n    {\n        if ($this->_spreadSheet !== null) {\n            return $this->_spreadSheet;\n        } else {\n            throw new PHPExcel_Writer_Exception('No PHPExcel assigned.');\n        }\n    }\n\n    /**\n     * Set PHPExcel object\n     *\n     * @param  PHPExcel  $pPHPExcel  PHPExcel object\n     * @throws PHPExcel_Writer_Exception\n     * @return PHPExcel_Writer_Excel2007\n     */\n    public function setPHPExcel(PHPExcel $pPHPExcel = null)\n    {\n        $this->_spreadSheet = $pPHPExcel;\n        return $this;\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/PDF/Core.php",
    "content": "<?php\n/**\n *  PHPExcel\n *\n *  Copyright (c) 2006 - 2014 PHPExcel\n *\n *  This library is free software; you can redistribute it and/or\n *  modify it under the terms of the GNU Lesser General Public\n *  License as published by the Free Software Foundation; either\n *  version 2.1 of the License, or (at your option) any later version.\n *\n *  This library is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n *  Lesser General Public License for more details.\n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; if not, write to the Free Software\n *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n *  @category    PHPExcel\n *  @package     PHPExcel_Writer_PDF\n *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n *  @license     http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n *  @version     ##VERSION##, ##DATE##\n */\n\n\n/**\n *  PHPExcel_Writer_PDF_Core\n *\n *  @category    PHPExcel\n *  @package     PHPExcel_Writer_PDF\n *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nabstract class PHPExcel_Writer_PDF_Core extends PHPExcel_Writer_HTML\n{\n    /**\n     * Temporary storage directory\n     *\n     * @var string\n     */\n    protected $_tempDir = '';\n\n    /**\n     * Font\n     *\n     * @var string\n     */\n    protected $_font = 'freesans';\n\n    /**\n     * Orientation (Over-ride)\n     *\n     * @var string\n     */\n    protected $_orientation    = NULL;\n\n    /**\n     * Paper size (Over-ride)\n     *\n     * @var int\n     */\n    protected $_paperSize    = NULL;\n\n\n    /**\n     * Temporary storage for Save Array Return type\n     *\n     * @var string\n     */\n\tprivate $_saveArrayReturnType;\n\n    /**\n     * Paper Sizes xRef List\n     *\n     * @var array\n     */\n    protected static $_paperSizes = array(\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER\n            => 'LETTER',                 //    (8.5 in. by 11 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_SMALL\n            => 'LETTER',                 //    (8.5 in. by 11 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_TABLOID\n            => array(792.00, 1224.00),   //    (11 in. by 17 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_LEDGER\n            => array(1224.00, 792.00),   //    (17 in. by 11 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_LEGAL\n            => 'LEGAL',                  //    (8.5 in. by 14 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_STATEMENT\n            => array(396.00, 612.00),    //    (5.5 in. by 8.5 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_EXECUTIVE\n            => 'EXECUTIVE',              //    (7.25 in. by 10.5 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3\n            => 'A3',                     //    (297 mm by 420 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4\n            => 'A4',                     //    (210 mm by 297 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_SMALL\n            => 'A4',                     //    (210 mm by 297 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_A5\n            => 'A5',                     //    (148 mm by 210 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_B4\n            => 'B4',                     //    (250 mm by 353 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_B5\n            => 'B5',                     //    (176 mm by 250 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_FOLIO\n            => 'FOLIO',                  //    (8.5 in. by 13 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_QUARTO\n            => array(609.45, 779.53),    //    (215 mm by 275 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_1\n            => array(720.00, 1008.00),   //    (10 in. by 14 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_2\n            => array(792.00, 1224.00),   //    (11 in. by 17 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_NOTE\n            => 'LETTER',                 //    (8.5 in. by 11 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO9_ENVELOPE\n            => array(279.00, 639.00),    //    (3.875 in. by 8.875 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO10_ENVELOPE\n            => array(297.00, 684.00),    //    (4.125 in. by 9.5 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO11_ENVELOPE\n            => array(324.00, 747.00),    //    (4.5 in. by 10.375 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO12_ENVELOPE\n            => array(342.00, 792.00),    //    (4.75 in. by 11 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_NO14_ENVELOPE\n            => array(360.00, 828.00),    //    (5 in. by 11.5 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_C\n            => array(1224.00, 1584.00),  //    (17 in. by 22 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_D\n            => array(1584.00, 2448.00),  //    (22 in. by 34 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_E\n            => array(2448.00, 3168.00),  //    (34 in. by 44 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_DL_ENVELOPE\n            => array(311.81, 623.62),    //    (110 mm by 220 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_C5_ENVELOPE\n            => 'C5',                     //    (162 mm by 229 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_C3_ENVELOPE\n            => 'C3',                     //    (324 mm by 458 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_C4_ENVELOPE\n            => 'C4',                     //    (229 mm by 324 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_C6_ENVELOPE\n            => 'C6',                     //    (114 mm by 162 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_C65_ENVELOPE\n            => array(323.15, 649.13),    //    (114 mm by 229 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_B4_ENVELOPE\n            => 'B4',                     //    (250 mm by 353 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_B5_ENVELOPE\n            => 'B5',                     //    (176 mm by 250 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_B6_ENVELOPE\n            => array(498.90, 354.33),    //    (176 mm by 125 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_ITALY_ENVELOPE\n            => array(311.81, 651.97),    //    (110 mm by 230 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_MONARCH_ENVELOPE\n            => array(279.00, 540.00),    //    (3.875 in. by 7.5 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_6_3_4_ENVELOPE\n            => array(261.00, 468.00),    //    (3.625 in. by 6.5 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_US_STANDARD_FANFOLD\n            => array(1071.00, 792.00),   //    (14.875 in. by 11 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_GERMAN_STANDARD_FANFOLD\n            => array(612.00, 864.00),    //    (8.5 in. by 12 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_GERMAN_LEGAL_FANFOLD\n            => 'FOLIO',                  //    (8.5 in. by 13 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_ISO_B4\n            => 'B4',                     //    (250 mm by 353 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_JAPANESE_DOUBLE_POSTCARD\n            => array(566.93, 419.53),    //    (200 mm by 148 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_PAPER_1\n            => array(648.00, 792.00),    //    (9 in. by 11 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_PAPER_2\n            => array(720.00, 792.00),    //    (10 in. by 11 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_STANDARD_PAPER_3\n            => array(1080.00, 792.00),   //    (15 in. by 11 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_INVITE_ENVELOPE\n            => array(623.62, 623.62),    //    (220 mm by 220 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_EXTRA_PAPER\n            => array(667.80, 864.00),    //    (9.275 in. by 12 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_LEGAL_EXTRA_PAPER\n            => array(667.80, 1080.00),   //    (9.275 in. by 15 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_TABLOID_EXTRA_PAPER\n            => array(841.68, 1296.00),   //    (11.69 in. by 18 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_EXTRA_PAPER\n            => array(668.98, 912.76),    //    (236 mm by 322 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_TRANSVERSE_PAPER\n            => array(595.80, 792.00),    //    (8.275 in. by 11 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_TRANSVERSE_PAPER\n            => 'A4',                     //    (210 mm by 297 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_EXTRA_TRANSVERSE_PAPER\n            => array(667.80, 864.00),    //    (9.275 in. by 12 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_SUPERA_SUPERA_A4_PAPER\n            => array(643.46, 1009.13),   //    (227 mm by 356 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_SUPERB_SUPERB_A3_PAPER\n            => array(864.57, 1380.47),   //    (305 mm by 487 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER_PLUS_PAPER\n            => array(612.00, 913.68),    //    (8.5 in. by 12.69 in.)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4_PLUS_PAPER\n            => array(595.28, 935.43),    //    (210 mm by 330 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_A5_TRANSVERSE_PAPER\n            => 'A5',                     //    (148 mm by 210 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_JIS_B5_TRANSVERSE_PAPER\n            => array(515.91, 728.50),    //    (182 mm by 257 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3_EXTRA_PAPER\n            => array(912.76, 1261.42),   //    (322 mm by 445 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_A5_EXTRA_PAPER\n            => array(493.23, 666.14),    //    (174 mm by 235 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_ISO_B5_EXTRA_PAPER\n            => array(569.76, 782.36),    //    (201 mm by 276 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_A2_PAPER\n            => 'A2',                     //    (420 mm by 594 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3_TRANSVERSE_PAPER\n            => 'A3',                     //    (297 mm by 420 mm)\n        PHPExcel_Worksheet_PageSetup::PAPERSIZE_A3_EXTRA_TRANSVERSE_PAPER\n            => array(912.76, 1261.42)    //    (322 mm by 445 mm)\n    );\n\n    /**\n     *  Create a new PHPExcel_Writer_PDF\n     *\n     *  @param     PHPExcel    $phpExcel    PHPExcel object\n     */\n    public function __construct(PHPExcel $phpExcel)\n    {\n        parent::__construct($phpExcel);\n        $this->setUseInlineCss(TRUE);\n        $this->_tempDir = PHPExcel_Shared_File::sys_get_temp_dir();\n    }\n\n    /**\n     *  Get Font\n     *\n     *  @return string\n     */\n    public function getFont()\n    {\n        return $this->_font;\n    }\n\n    /**\n     *  Set font. Examples:\n     *      'arialunicid0-chinese-simplified'\n     *      'arialunicid0-chinese-traditional'\n     *      'arialunicid0-korean'\n     *      'arialunicid0-japanese'\n     *\n     *  @param    string    $fontName\n     */\n    public function setFont($fontName)\n    {\n        $this->_font = $fontName;\n        return $this;\n    }\n\n    /**\n     *  Get Paper Size\n     *\n     *  @return int\n     */\n    public function getPaperSize()\n    {\n        return $this->_paperSize;\n    }\n\n    /**\n     *  Set Paper Size\n     *\n     *  @param  string  $pValue Paper size\n     *  @return PHPExcel_Writer_PDF\n     */\n    public function setPaperSize($pValue = PHPExcel_Worksheet_PageSetup::PAPERSIZE_LETTER)\n    {\n        $this->_paperSize = $pValue;\n        return $this;\n    }\n\n    /**\n     *  Get Orientation\n     *\n     *  @return string\n     */\n    public function getOrientation()\n    {\n        return $this->_orientation;\n    }\n\n    /**\n     *  Set Orientation\n     *\n     *  @param string $pValue  Page orientation\n     *  @return PHPExcel_Writer_PDF\n     */\n    public function setOrientation($pValue = PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT)\n    {\n        $this->_orientation = $pValue;\n        return $this;\n    }\n\n    /**\n     *  Get temporary storage directory\n     *\n     *  @return string\n     */\n    public function getTempDir()\n    {\n        return $this->_tempDir;\n    }\n\n    /**\n     *  Set temporary storage directory\n     *\n     *  @param     string        $pValue        Temporary storage directory\n     *  @throws    PHPExcel_Writer_Exception    when directory does not exist\n     *  @return    PHPExcel_Writer_PDF\n     */\n    public function setTempDir($pValue = '')\n    {\n        if (is_dir($pValue)) {\n            $this->_tempDir = $pValue;\n        } else {\n            throw new PHPExcel_Writer_Exception(\"Directory does not exist: $pValue\");\n        }\n        return $this;\n    }\n\n    /**\n     *  Save PHPExcel to PDF file, pre-save\n     *\n     *  @param     string     $pFilename   Name of the file to save as\n     *  @throws    PHPExcel_Writer_Exception\n     */\n    protected function prepareForSave($pFilename = NULL)\n    {\n        //  garbage collect\n        $this->_phpExcel->garbageCollect();\n\n        $this->_saveArrayReturnType = PHPExcel_Calculation::getArrayReturnType();\n        PHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE);\n\n        //  Open file\n        $fileHandle = fopen($pFilename, 'w');\n        if ($fileHandle === FALSE) {\n            throw new PHPExcel_Writer_Exception(\"Could not open file $pFilename for writing.\");\n        }\n\n        //  Set PDF\n        $this->_isPdf = TRUE;\n        //  Build CSS\n        $this->buildCSS(TRUE);\n\n        return $fileHandle;\n    }\n\n    /**\n     *  Save PHPExcel to PDF file, post-save\n     *\n     *  @param     resource      $fileHandle\n     *  @throws    PHPExcel_Writer_Exception\n     */\n    protected function restoreStateAfterSave($fileHandle)\n    {\n        //  Close file\n        fclose($fileHandle);\n\n        PHPExcel_Calculation::setArrayReturnType($this->_saveArrayReturnType);\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/PDF/DomPDF.php",
    "content": "<?php\n/**\n *  PHPExcel\n *\n *  Copyright (c) 2006 - 2014 PHPExcel\n *\n *  This library is free software; you can redistribute it and/or\n *  modify it under the terms of the GNU Lesser General Public\n *  License as published by the Free Software Foundation; either\n *  version 2.1 of the License, or (at your option) any later version.\n *\n *  This library is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n *  Lesser General Public License for more details.\n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; if not, write to the Free Software\n *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n *  @category    PHPExcel\n *  @package     PHPExcel_Writer_PDF\n *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n *  @license     http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n *  @version     ##VERSION##, ##DATE##\n */\n\n\n/**  Require DomPDF library */\n$pdfRendererClassFile = PHPExcel_Settings::getPdfRendererPath() . '/dompdf_config.inc.php';\nif (file_exists($pdfRendererClassFile)) {\n    require_once $pdfRendererClassFile;\n} else {\n    throw new PHPExcel_Writer_Exception('Unable to load PDF Rendering library');\n}\n\n/**\n *  PHPExcel_Writer_PDF_DomPDF\n *\n *  @category    PHPExcel\n *  @package     PHPExcel_Writer_PDF\n *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_PDF_DomPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter\n{\n    /**\n     *  Create a new PHPExcel_Writer_PDF\n     *\n     *  @param   PHPExcel    $phpExcel    PHPExcel object\n     */\n    public function __construct(PHPExcel $phpExcel)\n    {\n        parent::__construct($phpExcel);\n    }\n\n    /**\n     *  Save PHPExcel to file\n     *\n     *  @param   string     $pFilename   Name of the file to save as\n     *  @throws  PHPExcel_Writer_Exception\n     */\n    public function save($pFilename = NULL)\n    {\n        $fileHandle = parent::prepareForSave($pFilename);\n\n        //  Default PDF paper size\n        $paperSize = 'LETTER';    //    Letter    (8.5 in. by 11 in.)\n\n        //  Check for paper size and page orientation\n        if (is_null($this->getSheetIndex())) {\n            $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation()\n                == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE)\n                    ? 'L'\n                    : 'P';\n            $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize();\n            $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins();\n        } else {\n            $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation()\n                == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE)\n                    ? 'L'\n                    : 'P';\n            $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize();\n            $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins();\n        }\n\n        \n        $orientation = ($orientation == 'L') ? 'landscape' : 'portrait';\n\n        //  Override Page Orientation\n        if (!is_null($this->getOrientation())) {\n            $orientation = ($this->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT)\n                ? PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT\n                : $this->getOrientation();\n        }\n        //  Override Paper Size\n        if (!is_null($this->getPaperSize())) {\n            $printPaperSize = $this->getPaperSize();\n        }\n\n        if (isset(self::$_paperSizes[$printPaperSize])) {\n            $paperSize = self::$_paperSizes[$printPaperSize];\n        }\n\n\n        //  Create PDF\n        $pdf = new DOMPDF();\n        $pdf->set_paper(strtolower($paperSize), $orientation);\n\n        $pdf->load_html(\n            $this->generateHTMLHeader(FALSE) .\n            $this->generateSheetData() .\n            $this->generateHTMLFooter()\n        );\n        $pdf->render();\n\n        //  Write to file\n        fwrite($fileHandle, $pdf->output());\n\n\t\tparent::restoreStateAfterSave($fileHandle);\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/PDF/mPDF.php",
    "content": "<?php\n/**\n *  PHPExcel\n *\n *  Copyright (c) 2006 - 2014 PHPExcel\n *\n *  This library is free software; you can redistribute it and/or\n *  modify it under the terms of the GNU Lesser General Public\n *  License as published by the Free Software Foundation; either\n *  version 2.1 of the License, or (at your option) any later version.\n *\n *  This library is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n *  Lesser General Public License for more details.\n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; if not, write to the Free Software\n *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n *  @category    PHPExcel\n *  @package     PHPExcel_Writer_PDF\n *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n *  @license     http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n *  @version     ##VERSION##, ##DATE##\n */\n\n\n/**  Require mPDF library */\n$pdfRendererClassFile = PHPExcel_Settings::getPdfRendererPath() . '/mpdf.php';\nif (file_exists($pdfRendererClassFile)) {\n    require_once $pdfRendererClassFile;\n} else {\n    throw new PHPExcel_Writer_Exception('Unable to load PDF Rendering library');\n}\n\n/**\n *  PHPExcel_Writer_PDF_mPDF\n *\n *  @category    PHPExcel\n *  @package     PHPExcel_Writer_PDF\n *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_PDF_mPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter\n{\n    /**\n     *  Create a new PHPExcel_Writer_PDF\n     *\n     *  @param  PHPExcel  $phpExcel  PHPExcel object\n     */\n    public function __construct(PHPExcel $phpExcel)\n    {\n        parent::__construct($phpExcel);\n    }\n\n    /**\n     *  Save PHPExcel to file\n     *\n     *  @param     string     $pFilename   Name of the file to save as\n     *  @throws    PHPExcel_Writer_Exception\n     */\n    public function save($pFilename = NULL)\n    {\n        $fileHandle = parent::prepareForSave($pFilename);\n\n        //  Default PDF paper size\n        $paperSize = 'LETTER';    //    Letter    (8.5 in. by 11 in.)\n\n        //  Check for paper size and page orientation\n        if (is_null($this->getSheetIndex())) {\n            $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation()\n                == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE)\n                    ? 'L'\n                    : 'P';\n            $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize();\n            $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins();\n        } else {\n            $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation()\n                == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE)\n                    ? 'L'\n                    : 'P';\n            $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize();\n            $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins();\n        }\n        $this->setOrientation($orientation);\n\n        //  Override Page Orientation\n        if (!is_null($this->getOrientation())) {\n            $orientation = ($this->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_DEFAULT)\n                ? PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT\n                : $this->getOrientation();\n        }\n        $orientation = strtoupper($orientation);\n\n        //  Override Paper Size\n        if (!is_null($this->getPaperSize())) {\n            $printPaperSize = $this->getPaperSize();\n        }\n\n        if (isset(self::$_paperSizes[$printPaperSize])) {\n            $paperSize = self::$_paperSizes[$printPaperSize];\n        }\n\n        //  Create PDF\n        $pdf = new mpdf();\n        $ortmp = $orientation;\n        $pdf->_setPageSize(strtoupper($paperSize), $ortmp);\n        $pdf->DefOrientation = $orientation;\n        $pdf->AddPage($orientation);\n\n        //  Document info\n        $pdf->SetTitle($this->_phpExcel->getProperties()->getTitle());\n        $pdf->SetAuthor($this->_phpExcel->getProperties()->getCreator());\n        $pdf->SetSubject($this->_phpExcel->getProperties()->getSubject());\n        $pdf->SetKeywords($this->_phpExcel->getProperties()->getKeywords());\n        $pdf->SetCreator($this->_phpExcel->getProperties()->getCreator());\n\n        $pdf->WriteHTML(\n            $this->generateHTMLHeader(FALSE) .\n            $this->generateSheetData() .\n            $this->generateHTMLFooter()\n        );\n\n        //  Write to file\n        fwrite($fileHandle, $pdf->Output('', 'S'));\n\n\t\tparent::restoreStateAfterSave($fileHandle);\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/PDF/tcPDF.php",
    "content": "<?php\n/**\n *  PHPExcel\n *\n *  Copyright (c) 2006 - 2014 PHPExcel\n *\n *  This library is free software; you can redistribute it and/or\n *  modify it under the terms of the GNU Lesser General Public\n *  License as published by the Free Software Foundation; either\n *  version 2.1 of the License, or (at your option) any later version.\n *\n *  This library is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n *  Lesser General Public License for more details.\n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; if not, write to the Free Software\n *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n *  @category    PHPExcel\n *  @package     PHPExcel_Writer_PDF\n *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n *  @license     http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n *  @version     ##VERSION##, ##DATE##\n */\n\n\n/**  Require tcPDF library */\n$pdfRendererClassFile = PHPExcel_Settings::getPdfRendererPath() . '/tcpdf.php';\nif (file_exists($pdfRendererClassFile)) {\n    $k_path_url = PHPExcel_Settings::getPdfRendererPath();\n    require_once $pdfRendererClassFile;\n} else {\n    throw new PHPExcel_Writer_Exception('Unable to load PDF Rendering library');\n}\n\n/**\n *  PHPExcel_Writer_PDF_tcPDF\n *\n *  @category    PHPExcel\n *  @package     PHPExcel_Writer_PDF\n *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_PDF_tcPDF extends PHPExcel_Writer_PDF_Core implements PHPExcel_Writer_IWriter\n{\n    /**\n     *  Create a new PHPExcel_Writer_PDF\n     *\n     *  @param  PHPExcel  $phpExcel  PHPExcel object\n     */\n    public function __construct(PHPExcel $phpExcel)\n    {\n        parent::__construct($phpExcel);\n    }\n\n    /**\n     *  Save PHPExcel to file\n     *\n     *  @param     string     $pFilename   Name of the file to save as\n     *  @throws    PHPExcel_Writer_Exception\n     */\n    public function save($pFilename = NULL)\n    {\n        $fileHandle = parent::prepareForSave($pFilename);\n\n        //  Default PDF paper size\n        $paperSize = 'LETTER';    //    Letter    (8.5 in. by 11 in.)\n\n        //  Check for paper size and page orientation\n        if (is_null($this->getSheetIndex())) {\n            $orientation = ($this->_phpExcel->getSheet(0)->getPageSetup()->getOrientation()\n                == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE)\n                    ? 'L'\n                    : 'P';\n            $printPaperSize = $this->_phpExcel->getSheet(0)->getPageSetup()->getPaperSize();\n            $printMargins = $this->_phpExcel->getSheet(0)->getPageMargins();\n        } else {\n            $orientation = ($this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getOrientation()\n                == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE)\n                    ? 'L'\n                    : 'P';\n            $printPaperSize = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageSetup()->getPaperSize();\n            $printMargins = $this->_phpExcel->getSheet($this->getSheetIndex())->getPageMargins();\n        }\n\n        //  Override Page Orientation\n        if (!is_null($this->getOrientation())) {\n            $orientation = ($this->getOrientation() == PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE)\n                ? 'L'\n                : 'P';\n        }\n        //  Override Paper Size\n        if (!is_null($this->getPaperSize())) {\n            $printPaperSize = $this->getPaperSize();\n        }\n\n        if (isset(self::$_paperSizes[$printPaperSize])) {\n            $paperSize = self::$_paperSizes[$printPaperSize];\n        }\n\n\n        //  Create PDF\n        $pdf = new TCPDF($orientation, 'pt', $paperSize);\n        $pdf->setFontSubsetting(FALSE);\n        //    Set margins, converting inches to points (using 72 dpi)\n        $pdf->SetMargins($printMargins->getLeft() * 72, $printMargins->getTop() * 72, $printMargins->getRight() * 72);\n        $pdf->SetAutoPageBreak(TRUE, $printMargins->getBottom() * 72);\n\n        $pdf->setPrintHeader(FALSE);\n        $pdf->setPrintFooter(FALSE);\n\n        $pdf->AddPage();\n\n        //  Set the appropriate font\n        $pdf->SetFont($this->getFont());\n        $pdf->writeHTML(\n            $this->generateHTMLHeader(FALSE) .\n            $this->generateSheetData() .\n            $this->generateHTMLFooter()\n        );\n\n        //  Document info\n        $pdf->SetTitle($this->_phpExcel->getProperties()->getTitle());\n        $pdf->SetAuthor($this->_phpExcel->getProperties()->getCreator());\n        $pdf->SetSubject($this->_phpExcel->getProperties()->getSubject());\n        $pdf->SetKeywords($this->_phpExcel->getProperties()->getKeywords());\n        $pdf->SetCreator($this->_phpExcel->getProperties()->getCreator());\n\n        //  Write to file\n        fwrite($fileHandle, $pdf->output($pFilename, 'S'));\n\n\t\tparent::restoreStateAfterSave($fileHandle);\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/Writer/PDF.php",
    "content": "<?php\n/**\n *  PHPExcel\n *\n *  Copyright (c) 2006 - 2014 PHPExcel\n *\n *  This library is free software; you can redistribute it and/or\n *  modify it under the terms of the GNU Lesser General Public\n *  License as published by the Free Software Foundation; either\n *  version 2.1 of the License, or (at your option) any later version.\n *\n *  This library is distributed in the hope that it will be useful,\n *  but WITHOUT ANY WARRANTY; without even the implied warranty of\n *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n *  Lesser General Public License for more details.\n *\n *  You should have received a copy of the GNU Lesser General Public\n *  License along with this library; if not, write to the Free Software\n *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n *  @category    PHPExcel\n *  @package     PHPExcel_Writer_PDF\n *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n *  @license     http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n *  @version     ##VERSION##, ##DATE##\n */\n\n\n/**\n *  PHPExcel_Writer_PDF\n *\n *  @category    PHPExcel\n *  @package     PHPExcel_Writer_PDF\n *  @copyright   Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel_Writer_PDF implements PHPExcel_Writer_IWriter\n{\n\n    /**\n     * The wrapper for the requested PDF rendering engine\n     *\n     * @var PHPExcel_Writer_PDF_Core\n     */\n    private $_renderer = NULL;\n\n    /**\n     *  Instantiate a new renderer of the configured type within this container class\n     *\n     *  @param  PHPExcel   $phpExcel         PHPExcel object\n     *  @throws PHPExcel_Writer_Exception    when PDF library is not configured\n     */\n    public function __construct(PHPExcel $phpExcel)\n    {\n        $pdfLibraryName = PHPExcel_Settings::getPdfRendererName();\n        if (is_null($pdfLibraryName)) {\n            throw new PHPExcel_Writer_Exception(\"PDF Rendering library has not been defined.\");\n        }\n\n        $pdfLibraryPath = PHPExcel_Settings::getPdfRendererPath();\n        if (is_null($pdfLibraryName)) {\n            throw new PHPExcel_Writer_Exception(\"PDF Rendering library path has not been defined.\");\n        }\n        $includePath = str_replace('\\\\', '/', get_include_path());\n        $rendererPath = str_replace('\\\\', '/', $pdfLibraryPath);\n        if (strpos($rendererPath, $includePath) === false) {\n            set_include_path(get_include_path() . PATH_SEPARATOR . $pdfLibraryPath);\n        }\n\n        $rendererName = 'PHPExcel_Writer_PDF_' . $pdfLibraryName;\n        $this->_renderer = new $rendererName($phpExcel);\n    }\n\n\n    /**\n     *  Magic method to handle direct calls to the configured PDF renderer wrapper class.\n     *\n     *  @param   string   $name        Renderer library method name\n     *  @param   mixed[]  $arguments   Array of arguments to pass to the renderer method\n     *  @return  mixed    Returned data from the PDF renderer wrapper method\n     */\n    public function __call($name, $arguments)\n    {\n        if ($this->_renderer === NULL) {\n            throw new PHPExcel_Writer_Exception(\"PDF Rendering library has not been defined.\");\n        }\n\n        return call_user_func_array(array($this->_renderer, $name), $arguments);\n    }\n\n    /**\n     * {@inheritdoc}\n     */\n    public function save($pFilename = null)\n    {\n        $this->_renderer->save($pFilename);\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/bg/config",
    "content": "##\n## PHPExcel\n##\n\n## Copyright (c) 2006 - 2013 PHPExcel\n##\n## This library is free software; you can redistribute it and/or\n## modify it under the terms of the GNU Lesser General Public\n## License as published by the Free Software Foundation; either\n## version 2.1 of the License, or (at your option) any later version.\n##\n## This library is distributed in the hope that it will be useful,\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n## Lesser General Public License for more details.\n##\n## You should have received a copy of the GNU Lesser General Public\n## License along with this library; if not, write to the Free Software\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n##\n## @category   PHPExcel\n## @package    PHPExcel_Settings\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt  LGPL\n## @version    ##VERSION##, ##DATE##\n##\n##\n\n\nArgumentSeparator\t= ;\n\n\n##\n##\t(For future use)\n##\ncurrencySymbol\t= лв\n\n\n##\n##\tExcel Error Codes\t(For future use)\n\n##\nNULL\t= #ПРАЗНО!\nDIV0\t= #ДЕЛ/0!\nVALUE\t= #СТОЙНОСТ!\nREF\t= #РЕФ!\nNAME\t= #ИМЕ?\nNUM\t= #ЧИСЛО!\nNA\t= #Н/Д\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= Kč\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\n##\r\nNULL\t= #NULL!\r\nDIV0\t= #DIV/0!\r\nVALUE\t= #HODNOTA!\r\nREF\t= #REF!\r\nNAME\t= #NÁZEV?\r\nNUM\t= #NUM!\r\nNA\t= #N/A\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/cs/functions",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Calculation\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/\r\n##\r\n##\r\n\r\n\r\n##\r\n##\tAdd-in and Automation functions\t\tFunkce doplňků a automatizace\r\n##\r\nGETPIVOTDATA\t\t= ZÍSKATKONTDATA\t##\tVrátí data uložená v kontingenční tabulce. Pomocí funkce ZÍSKATKONTDATA můžete načíst souhrnná data z kontingenční tabulky, pokud jsou tato data v kontingenční sestavě zobrazena.\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\tFunkce pro práci s krychlemi\r\n##\r\nCUBEKPIMEMBER\t\t= CUBEKPIMEMBER\t\t##\tVrátí název, vlastnost a velikost klíčového ukazatele výkonu (KUV) a zobrazí v buňce název a vlastnost. Klíčový ukazatel výkonu je kvantifikovatelná veličina, například hrubý měsíční zisk nebo čtvrtletní obrat na zaměstnance, která se používá pro sledování výkonnosti organizace.\r\nCUBEMEMBER\t\t= CUBEMEMBER\t\t##\tVrátí člen nebo n-tici v hierarchii krychle. Slouží k ověření, zda v krychli existuje člen nebo n-tice.\r\nCUBEMEMBERPROPERTY\t= CUBEMEMBERPROPERTY\t##\tVrátí hodnotu vlastnosti člena v krychli. Slouží k ověření, zda v krychli existuje člen s daným názvem, a k vrácení konkrétní vlastnosti tohoto člena.\r\nCUBERANKEDMEMBER\t= CUBERANKEDMEMBER\t##\tVrátí n-tý nebo pořadový člen sady. Použijte ji pro vrácení jednoho nebo více prvků sady, například obchodníka s nejvyšším obratem nebo deseti nejlepších studentů.\r\nCUBESET\t\t\t= CUBESET\t\t##\tDefinuje vypočtenou sadu členů nebo n-tic odesláním výrazu sady do krychle na serveru, který vytvoří sadu a potom ji vrátí do aplikace Microsoft Office Excel.\r\nCUBESETCOUNT\t\t= CUBESETCOUNT\t\t##\tVrátí počet položek v množině\r\nCUBEVALUE\t\t= CUBEVALUE\t\t##\tVrátí úhrnnou hodnotu z krychle.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\tFunkce databáze\r\n##\r\nDAVERAGE\t\t= DPRŮMĚR\t\t##\tVrátí průměr vybraných položek databáze.\r\nDCOUNT\t\t\t= DPOČET\t\t##\tSpočítá buňky databáze obsahující čísla.\r\nDCOUNTA\t\t\t= DPOČET2\t\t##\tSpočítá buňky databáze, které nejsou prázdné.\r\nDGET\t\t\t= DZÍSKAT\t\t##\tExtrahuje z databáze jeden záznam splňující zadaná kritéria.\r\nDMAX\t\t\t= DMAX\t\t\t##\tVrátí maximální hodnotu z vybraných položek databáze.\r\nDMIN\t\t\t= DMIN\t\t\t##\tVrátí minimální hodnotu z vybraných položek databáze.\r\nDPRODUCT\t\t= DSOUČIN\t\t##\tVynásobí hodnoty určitého pole záznamů v databázi, které splňují daná kritéria.\r\nDSTDEV\t\t\t= DSMODCH.VÝBĚR\t\t##\tOdhadne směrodatnou odchylku výběru vybraných položek databáze.\r\nDSTDEVP\t\t\t= DSMODCH\t\t##\tVypočte směrodatnou odchylku základního souboru vybraných položek databáze.\r\nDSUM\t\t\t= DSUMA\t\t\t##\tSečte čísla ve sloupcovém poli záznamů databáze, která splňují daná kritéria.\r\nDVAR\t\t\t= DVAR.VÝBĚR\t\t##\tOdhadne rozptyl výběru vybraných položek databáze.\r\nDVARP\t\t\t= DVAR\t\t\t##\tVypočte rozptyl základního souboru vybraných položek databáze.\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\tFunkce data a času\r\n##\r\nDATE\t\t\t= DATUM\t\t\t##\tVrátí pořadové číslo určitého data.\r\nDATEVALUE\t\t= DATUMHODN\t\t##\tPřevede datum ve formě textu na pořadové číslo.\r\nDAY\t\t\t= DEN\t\t\t##\tPřevede pořadové číslo na den v měsíci.\r\nDAYS360\t\t\t= ROK360\t\t##\tVrátí počet dní mezi dvěma daty na základě roku s 360 dny.\r\nEDATE\t\t\t= EDATE\t\t\t##\tVrátí pořadové číslo data, které označuje určený počet měsíců před nebo po počátečním datu.\r\nEOMONTH\t\t\t= EOMONTH\t\t##\tVrátí pořadové číslo posledního dne měsíce před nebo po zadaném počtu měsíců.\r\nHOUR\t\t\t= HODINA\t\t##\tPřevede pořadové číslo na hodinu.\r\nMINUTE\t\t\t= MINUTA\t\t##\tPřevede pořadové číslo na minutu.\r\nMONTH\t\t\t= MĚSÍC\t\t\t##\tPřevede pořadové číslo na měsíc.\r\nNETWORKDAYS\t\t= NETWORKDAYS\t\t##\tVrátí počet celých pracovních dní mezi dvěma daty.\r\nNOW\t\t\t= NYNÍ\t\t\t##\tVrátí pořadové číslo aktuálního data a času.\r\nSECOND\t\t\t= SEKUNDA\t\t##\tPřevede pořadové číslo na sekundu.\r\nTIME\t\t\t= ČAS\t\t\t##\tVrátí pořadové číslo určitého času.\r\nTIMEVALUE\t\t= ČASHODN\t\t##\tPřevede čas ve formě textu na pořadové číslo.\r\nTODAY\t\t\t= DNES\t\t\t##\tVrátí pořadové číslo dnešního data.\r\nWEEKDAY\t\t\t= DENTÝDNE\t\t##\tPřevede pořadové číslo na den v týdnu.\r\nWEEKNUM\t\t\t= WEEKNUM\t\t##\tPřevede pořadové číslo na číslo představující číselnou pozici týdne v roce.\r\nWORKDAY\t\t\t= WORKDAY\t\t##\tVrátí pořadové číslo data před nebo po zadaném počtu pracovních dní.\r\nYEAR\t\t\t= ROK\t\t\t##\tPřevede pořadové číslo na rok.\r\nYEARFRAC\t\t= YEARFRAC\t\t##\tVrátí část roku vyjádřenou zlomkem a představující počet celých dní mezi počátečním a koncovým datem.\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\tInženýrské funkce (Technické funkce)\r\n##\r\nBESSELI\t\t\t= BESSELI\t\t##\tVrátí modifikovanou Besselovu funkci In(x).\r\nBESSELJ\t\t\t= BESSELJ\t\t##\tVrátí modifikovanou Besselovu funkci Jn(x).\r\nBESSELK\t\t\t= BESSELK\t\t##\tVrátí modifikovanou Besselovu funkci Kn(x).\r\nBESSELY\t\t\t= BESSELY\t\t##\tVrátí Besselovu funkci Yn(x).\r\nBIN2DEC\t\t\t= BIN2DEC\t\t##\tPřevede binární číslo na desítkové.\r\nBIN2HEX\t\t\t= BIN2HEX\t\t##\tPřevede binární číslo na šestnáctkové.\r\nBIN2OCT\t\t\t= BIN2OCT\t\t##\tPřevede binární číslo na osmičkové.\r\nCOMPLEX\t\t\t= COMPLEX\t\t##\tPřevede reálnou a imaginární část na komplexní číslo.\r\nCONVERT\t\t\t= CONVERT\t\t##\tPřevede číslo do jiného jednotkového měrného systému.\r\nDEC2BIN\t\t\t= DEC2BIN\t\t##\tPřevede desítkového čísla na dvojkové\r\nDEC2HEX\t\t\t= DEC2HEX\t\t##\tPřevede desítkové číslo na šestnáctkové.\r\nDEC2OCT\t\t\t= DEC2OCT\t\t##\tPřevede desítkové číslo na osmičkové.\r\nDELTA\t\t\t= DELTA\t\t\t##\tTestuje rovnost dvou hodnot.\r\nERF\t\t\t= ERF\t\t\t##\tVrátí chybovou funkci.\r\nERFC\t\t\t= ERFC\t\t\t##\tVrátí doplňkovou chybovou funkci.\r\nGESTEP\t\t\t= GESTEP\t\t##\tTestuje, zda je číslo větší než mezní hodnota.\r\nHEX2BIN\t\t\t= HEX2BIN\t\t##\tPřevede šestnáctkové číslo na binární.\r\nHEX2DEC\t\t\t= HEX2DEC\t\t##\tPřevede šestnáctkové číslo na desítkové.\r\nHEX2OCT\t\t\t= HEX2OCT\t\t##\tPřevede šestnáctkové číslo na osmičkové.\r\nIMABS\t\t\t= IMABS\t\t\t##\tVrátí absolutní hodnotu (modul) komplexního čísla.\r\nIMAGINARY\t\t= IMAGINARY\t\t##\tVrátí imaginární část komplexního čísla.\r\nIMARGUMENT\t\t= IMARGUMENT\t\t##\tVrátí argument théta, úhel vyjádřený v radiánech.\r\nIMCONJUGATE\t\t= IMCONJUGATE\t\t##\tVrátí komplexně sdružené číslo ke komplexnímu číslu.\r\nIMCOS\t\t\t= IMCOS\t\t\t##\tVrátí kosinus komplexního čísla.\r\nIMDIV\t\t\t= IMDIV\t\t\t##\tVrátí podíl dvou komplexních čísel.\r\nIMEXP\t\t\t= IMEXP\t\t\t##\tVrátí exponenciální tvar komplexního čísla.\r\nIMLN\t\t\t= IMLN\t\t\t##\tVrátí přirozený logaritmus komplexního čísla.\r\nIMLOG10\t\t\t= IMLOG10\t\t##\tVrátí dekadický logaritmus komplexního čísla.\r\nIMLOG2\t\t\t= IMLOG2\t\t##\tVrátí logaritmus komplexního čísla při základu 2.\r\nIMPOWER\t\t\t= IMPOWER\t\t##\tVrátí komplexní číslo umocněné na celé číslo.\r\nIMPRODUCT\t\t= IMPRODUCT\t\t##\tVrátí součin komplexních čísel.\r\nIMREAL\t\t\t= IMREAL\t\t##\tVrátí reálnou část komplexního čísla.\r\nIMSIN\t\t\t= IMSIN\t\t\t##\tVrátí sinus komplexního čísla.\r\nIMSQRT\t\t\t= IMSQRT\t\t##\tVrátí druhou odmocninu komplexního čísla.\r\nIMSUB\t\t\t= IMSUB\t\t\t##\tVrátí rozdíl mezi dvěma komplexními čísly.\r\nIMSUM\t\t\t= IMSUM\t\t\t##\tVrátí součet dvou komplexních čísel.\r\nOCT2BIN\t\t\t= OCT2BIN\t\t##\tPřevede osmičkové číslo na binární.\r\nOCT2DEC\t\t\t= OCT2DEC\t\t##\tPřevede osmičkové číslo na desítkové.\r\nOCT2HEX\t\t\t= OCT2HEX\t\t##\tPřevede osmičkové číslo na šestnáctkové.\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\tFinanční funkce\r\n##\r\nACCRINT\t\t\t= ACCRINT\t\t##\tVrátí nahromaděný úrok z cenného papíru, ze kterého je úrok placen v pravidelných termínech.\r\nACCRINTM\t\t= ACCRINTM\t\t##\tVrátí nahromaděný úrok z cenného papíru, ze kterého je úrok placen k datu splatnosti.\r\nAMORDEGRC\t\t= AMORDEGRC\t\t##\tVrátí lineární amortizaci v každém účetním období pomocí koeficientu amortizace.\r\nAMORLINC\t\t= AMORLINC\t\t##\tVrátí lineární amortizaci v každém účetním období.\r\nCOUPDAYBS\t\t= COUPDAYBS\t\t##\tVrátí počet dnů od začátku období placení kupónů do data splatnosti.\r\nCOUPDAYS\t\t= COUPDAYS\t\t##\tVrátí počet dnů v období placení kupónů, které obsahuje den zúčtování.\r\nCOUPDAYSNC\t\t= COUPDAYSNC\t\t##\tVrátí počet dnů od data zúčtování do následujícího data placení kupónu.\r\nCOUPNCD\t\t\t= COUPNCD\t\t##\tVrátí následující datum placení kupónu po datu zúčtování.\r\nCOUPNUM\t\t\t= COUPNUM\t\t##\tVrátí počet kupónů splatných mezi datem zúčtování a datem splatnosti.\r\nCOUPPCD\t\t\t= COUPPCD\t\t##\tVrátí předchozí datum placení kupónu před datem zúčtování.\r\nCUMIPMT\t\t\t= CUMIPMT\t\t##\tVrátí kumulativní úrok splacený mezi dvěma obdobími.\r\nCUMPRINC\t\t= CUMPRINC\t\t##\tVrátí kumulativní jistinu splacenou mezi dvěma obdobími půjčky.\r\nDB\t\t\t= ODPIS.ZRYCH\t\t##\tVrátí odpis aktiva za určité období pomocí degresivní metody odpisu s pevným zůstatkem.\r\nDDB\t\t\t= ODPIS.ZRYCH2\t\t##\tVrátí odpis aktiva za určité období pomocí dvojité degresivní metody odpisu nebo jiné metody, kterou zadáte.\r\nDISC\t\t\t= DISC\t\t\t##\tVrátí diskontní sazbu cenného papíru.\r\nDOLLARDE\t\t= DOLLARDE\t\t##\tPřevede částku v korunách vyjádřenou zlomkem na částku v korunách vyjádřenou desetinným číslem.\r\nDOLLARFR\t\t= DOLLARFR\t\t##\tPřevede částku v korunách vyjádřenou desetinným číslem na částku v korunách vyjádřenou zlomkem.\r\nDURATION\t\t= DURATION\t\t##\tVrátí roční dobu cenného papíru s pravidelnými úrokovými sazbami.\r\nEFFECT\t\t\t= EFFECT\t\t##\tVrátí efektivní roční úrokovou sazbu.\r\nFV\t\t\t= BUDHODNOTA\t\t##\tVrátí budoucí hodnotu investice.\r\nFVSCHEDULE\t\t= FVSCHEDULE\t\t##\tVrátí budoucí hodnotu počáteční jistiny po použití série sazeb složitého úroku.\r\nINTRATE\t\t\t= INTRATE\t\t##\tVrátí úrokovou sazbu plně investovaného cenného papíru.\r\nIPMT\t\t\t= PLATBA.ÚROK\t\t##\tVrátí výšku úroku investice za dané období.\r\nIRR\t\t\t= MÍRA.VÝNOSNOSTI\t##\tVrátí vnitřní výnosové procento série peněžních toků.\r\nISPMT\t\t\t= ISPMT\t\t\t##\tVypočte výši úroku z investice zaplaceného během určitého období.\r\nMDURATION\t\t= MDURATION\t\t##\tVrátí Macauleyho modifikovanou dobu cenného papíru o nominální hodnotě 100 Kč.\r\nMIRR\t\t\t= MOD.MÍRA.VÝNOSNOSTI\t##\tVrátí vnitřní sazbu výnosu, přičemž kladné a záporné hodnoty peněžních prostředků jsou financovány podle různých sazeb.\r\nNOMINAL\t\t\t= NOMINAL\t\t##\tVrátí nominální roční úrokovou sazbu.\r\nNPER\t\t\t= POČET.OBDOBÍ\t\t##\tVrátí počet období pro investici.\r\nNPV\t\t\t= ČISTÁ.SOUČHODNOTA\t##\tVrátí čistou současnou hodnotu investice vypočítanou na základě série pravidelných peněžních toků a diskontní sazby.\r\nODDFPRICE\t\t= ODDFPRICE\t\t##\tVrátí cenu cenného papíru o nominální hodnotě 100 Kč s odlišným prvním obdobím.\r\nODDFYIELD\t\t= ODDFYIELD\t\t##\tVrátí výnos cenného papíru s odlišným prvním obdobím.\r\nODDLPRICE\t\t= ODDLPRICE\t\t##\tVrátí cenu cenného papíru o nominální hodnotě 100 Kč s odlišným posledním obdobím.\r\nODDLYIELD\t\t= ODDLYIELD\t\t##\tVrátí výnos cenného papíru s odlišným posledním obdobím.\r\nPMT\t\t\t= PLATBA\t\t##\tVrátí hodnotu pravidelné splátky anuity.\r\nPPMT\t\t\t= PLATBA.ZÁKLAD\t\t##\tVrátí hodnotu splátky jistiny pro zadanou investici za dané období.\r\nPRICE\t\t\t= PRICE\t\t\t##\tVrátí cenu cenného papíru o nominální hodnotě 100 Kč, ze kterého je úrok placen v pravidelných termínech.\r\nPRICEDISC\t\t= PRICEDISC\t\t##\tVrátí cenu diskontního cenného papíru o nominální hodnotě 100 Kč.\r\nPRICEMAT\t\t= PRICEMAT\t\t##\tVrátí cenu cenného papíru o nominální hodnotě 100 Kč, ze kterého je úrok placen k datu splatnosti.\r\nPV\t\t\t= SOUČHODNOTA\t\t##\tVrátí současnou hodnotu investice.\r\nRATE\t\t\t= ÚROKOVÁ.MÍRA\t\t##\tVrátí úrokovou sazbu vztaženou na období anuity.\r\nRECEIVED\t\t= RECEIVED\t\t##\tVrátí částku obdrženou k datu splatnosti plně investovaného cenného papíru.\r\nSLN\t\t\t= ODPIS.LIN\t\t##\tVrátí přímé odpisy aktiva pro jedno období.\r\nSYD\t\t\t= ODPIS.NELIN\t\t##\tVrátí směrné číslo ročních odpisů aktiva pro zadané období.\r\nTBILLEQ\t\t\t= TBILLEQ\t\t##\tVrátí výnos směnky státní pokladny ekvivalentní výnosu obligace.\r\nTBILLPRICE\t\t= TBILLPRICE\t\t##\tVrátí cenu směnky státní pokladny o nominální hodnotě 100 Kč.\r\nTBILLYIELD\t\t= TBILLYIELD\t\t##\tVrátí výnos směnky státní pokladny.\r\nVDB\t\t\t= ODPIS.ZA.INT\t\t##\tVrátí odpis aktiva pro určité období nebo část období pomocí degresivní metody odpisu.\r\nXIRR\t\t\t= XIRR\t\t\t##\tVrátí vnitřní výnosnost pro harmonogram peněžních toků, který nemusí být nutně periodický.\r\nXNPV\t\t\t= XNPV\t\t\t##\tVrátí čistou současnou hodnotu pro harmonogram peněžních toků, který nemusí být nutně periodický.\r\nYIELD\t\t\t= YIELD\t\t\t##\tVrátí výnos cenného papíru, ze kterého je úrok placen v pravidelných termínech.\r\nYIELDDISC\t\t= YIELDDISC\t\t##\tVrátí roční výnos diskontního cenného papíru, například směnky státní pokladny.\r\nYIELDMAT\t\t= YIELDMAT\t\t##\tVrátí roční výnos cenného papíru, ze kterého je úrok placen k datu splatnosti.\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\tInformační funkce\r\n##\r\nCELL\t\t\t= POLÍČKO\t\t##\tVrátí informace o formátování, umístění nebo obsahu buňky.\r\nERROR.TYPE\t\t= CHYBA.TYP\t\t##\tVrátí číslo odpovídající typu chyby.\r\nINFO\t\t\t= O.PROSTŘEDÍ\t\t##\tVrátí informace o aktuálním pracovním prostředí.\r\nISBLANK\t\t\t= JE.PRÁZDNÉ\t\t##\tVrátí hodnotu PRAVDA, pokud se argument hodnota odkazuje na prázdnou buňku.\r\nISERR\t\t\t= JE.CHYBA\t\t##\tVrátí hodnotu PRAVDA, pokud je argument hodnota libovolná chybová hodnota (kromě #N/A).\r\nISERROR\t\t\t= JE.CHYBHODN\t\t##\tVrátí hodnotu PRAVDA, pokud je argument hodnota libovolná chybová hodnota.\r\nISEVEN\t\t\t= ISEVEN\t\t##\tVrátí hodnotu PRAVDA, pokud je číslo sudé.\r\nISLOGICAL\t\t= JE.LOGHODN\t\t##\tVrátí hodnotu PRAVDA, pokud je argument hodnota logická hodnota.\r\nISNA\t\t\t= JE.NEDEF\t\t##\tVrátí hodnotu PRAVDA, pokud je argument hodnota chybová hodnota #N/A.\r\nISNONTEXT\t\t= JE.NETEXT\t\t##\tVrátí hodnotu PRAVDA, pokud argument hodnota není text.\r\nISNUMBER\t\t= JE.ČÍSLO\t\t##\tVrátí hodnotu PRAVDA, pokud je argument hodnota číslo.\r\nISODD\t\t\t= ISODD\t\t\t##\tVrátí hodnotu PRAVDA, pokud je číslo liché.\r\nISREF\t\t\t= JE.ODKAZ\t\t##\tVrátí hodnotu PRAVDA, pokud je argument hodnota odkaz.\r\nISTEXT\t\t\t= JE.TEXT\t\t##\tVrátí hodnotu PRAVDA, pokud je argument hodnota text.\r\nN\t\t\t= N\t\t\t##\tVrátí hodnotu převedenou na číslo.\r\nNA\t\t\t= NEDEF\t\t\t##\tVrátí chybovou hodnotu #N/A.\r\nTYPE\t\t\t= TYP\t\t\t##\tVrátí číslo označující datový typ hodnoty.\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\tLogické funkce\r\n##\r\nAND\t\t\t= A\t\t\t##\tVrátí hodnotu PRAVDA, mají-li všechny argumenty hodnotu PRAVDA.\r\nFALSE\t\t\t= NEPRAVDA\t\t##\tVrátí logickou hodnotu NEPRAVDA.\r\nIF\t\t\t= KDYŽ\t\t\t##\tUrčí, který logický test má proběhnout.\r\nIFERROR\t\t\t= IFERROR\t\t##\tPokud je vzorec vyhodnocen jako chyba, vrátí zadanou hodnotu. V opačném případě vrátí výsledek vzorce.\r\nNOT\t\t\t= NE\t\t\t##\tProvede logickou negaci argumentu funkce.\r\nOR\t\t\t= NEBO\t\t\t##\tVrátí hodnotu PRAVDA, je-li alespoň jeden argument roven hodnotě PRAVDA.\r\nTRUE\t\t\t= PRAVDA\t\t##\tVrátí logickou hodnotu PRAVDA.\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\tVyhledávací funkce\r\n##\r\nADDRESS\t\t\t= ODKAZ\t\t\t##\tVrátí textový odkaz na jednu buňku listu.\r\nAREAS\t\t\t= POČET.BLOKŮ\t\t##\tVrátí počet oblastí v odkazu.\r\nCHOOSE\t\t\t= ZVOLIT\t\t##\tZvolí hodnotu ze seznamu hodnot.\r\nCOLUMN\t\t\t= SLOUPEC\t\t##\tVrátí číslo sloupce odkazu.\r\nCOLUMNS\t\t\t= SLOUPCE\t\t##\tVrátí počet sloupců v odkazu.\r\nHLOOKUP\t\t\t= VVYHLEDAT\t\t##\tProhledá horní řádek matice a vrátí hodnotu určené buňky.\r\nHYPERLINK\t\t= HYPERTEXTOVÝ.ODKAZ\t##\tVytvoří zástupce nebo odkaz, který otevře dokument uložený na síťovém serveru, v síti intranet nebo Internet.\r\nINDEX\t\t\t= INDEX\t\t\t##\tPomocí rejstříku zvolí hodnotu z odkazu nebo matice.\r\nINDIRECT\t\t= NEPŘÍMÝ.ODKAZ\t\t##\tVrátí odkaz určený textovou hodnotou.\r\nLOOKUP\t\t\t= VYHLEDAT\t\t##\tVyhledá hodnoty ve vektoru nebo matici.\r\nMATCH\t\t\t= POZVYHLEDAT\t\t##\tVyhledá hodnoty v odkazu nebo matici.\r\nOFFSET\t\t\t= POSUN\t\t\t##\tVrátí posun odkazu od zadaného odkazu.\r\nROW\t\t\t= ŘÁDEK\t\t\t##\tVrátí číslo řádku odkazu.\r\nROWS\t\t\t= ŘÁDKY\t\t\t##\tVrátí počet řádků v odkazu.\r\nRTD\t\t\t= RTD\t\t\t##\tNačte data reálného času z programu, který podporuje automatizaci modelu COM (Automatizace: Způsob práce s objekty určité aplikace z jiné aplikace nebo nástroje pro vývoj. Automatizace (dříve nazývaná automatizace OLE) je počítačovým standardem a je funkcí modelu COM (Component Object Model).).\r\nTRANSPOSE\t\t= TRANSPOZICE\t\t##\tVrátí transponovanou matici.\r\nVLOOKUP\t\t\t= SVYHLEDAT\t\t##\tProhledá první sloupec matice, přesune kurzor v řádku a vrátí hodnotu buňky.\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\tMatematické a trigonometrické funkce\r\n##\r\nABS\t\t\t= ABS\t\t\t##\tVrátí absolutní hodnotu čísla.\r\nACOS\t\t\t= ARCCOS\t\t##\tVrátí arkuskosinus čísla.\r\nACOSH\t\t\t= ARCCOSH\t\t##\tVrátí hyperbolický arkuskosinus čísla.\r\nASIN\t\t\t= ARCSIN\t\t##\tVrátí arkussinus čísla.\r\nASINH\t\t\t= ARCSINH\t\t##\tVrátí hyperbolický arkussinus čísla.\r\nATAN\t\t\t= ARCTG\t\t\t##\tVrátí arkustangens čísla.\r\nATAN2\t\t\t= ARCTG2\t\t##\tVrátí arkustangens x-ové a y-ové souřadnice.\r\nATANH\t\t\t= ARCTGH\t\t##\tVrátí hyperbolický arkustangens čísla.\r\nCEILING\t\t\t= ZAOKR.NAHORU\t\t##\tZaokrouhlí číslo na nejbližší celé číslo nebo na nejbližší násobek zadané hodnoty.\r\nCOMBIN\t\t\t= KOMBINACE\t\t##\tVrátí počet kombinací pro daný počet položek.\r\nCOS\t\t\t= COS\t\t\t##\tVrátí kosinus čísla.\r\nCOSH\t\t\t= COSH\t\t\t##\tVrátí hyperbolický kosinus čísla.\r\nDEGREES\t\t\t= DEGREES\t\t##\tPřevede radiány na stupně.\r\nEVEN\t\t\t= ZAOKROUHLIT.NA.SUDÉ\t##\tZaokrouhlí číslo nahoru na nejbližší celé sudé číslo.\r\nEXP\t\t\t= EXP\t\t\t##\tVrátí základ přirozeného logaritmu e umocněný na zadané číslo.\r\nFACT\t\t\t= FAKTORIÁL\t\t##\tVrátí faktoriál čísla.\r\nFACTDOUBLE\t\t= FACTDOUBLE\t\t##\tVrátí dvojitý faktoriál čísla.\r\nFLOOR\t\t\t= ZAOKR.DOLŮ\t\t##\tZaokrouhlí číslo dolů, směrem k nule.\r\nGCD\t\t\t= GCD\t\t\t##\tVrátí největší společný dělitel.\r\nINT\t\t\t= CELÁ.ČÁST\t\t##\tZaokrouhlí číslo dolů na nejbližší celé číslo.\r\nLCM\t\t\t= LCM\t\t\t##\tVrátí nejmenší společný násobek.\r\nLN\t\t\t= LN\t\t\t##\tVrátí přirozený logaritmus čísla.\r\nLOG\t\t\t= LOGZ\t\t\t##\tVrátí logaritmus čísla při zadaném základu.\r\nLOG10\t\t\t= LOG\t\t\t##\tVrátí dekadický logaritmus čísla.\r\nMDETERM\t\t\t= DETERMINANT\t\t##\tVrátí determinant matice.\r\nMINVERSE\t\t= INVERZE\t\t##\tVrátí inverzní matici.\r\nMMULT\t\t\t= SOUČIN.MATIC\t\t##\tVrátí součin dvou matic.\r\nMOD\t\t\t= MOD\t\t\t##\tVrátí zbytek po dělení.\r\nMROUND\t\t\t= MROUND\t\t##\tVrátí číslo zaokrouhlené na požadovaný násobek.\r\nMULTINOMIAL\t\t= MULTINOMIAL\t\t##\tVrátí mnohočlen z množiny čísel.\r\nODD\t\t\t= ZAOKROUHLIT.NA.LICHÉ\t##\tZaokrouhlí číslo nahoru na nejbližší celé liché číslo.\r\nPI\t\t\t= PI\t\t\t##\tVrátí hodnotu čísla pí.\r\nPOWER\t\t\t= POWER\t\t\t##\tUmocní číslo na zadanou mocninu.\r\nPRODUCT\t\t\t= SOUČIN\t\t##\tVynásobí argumenty funkce.\r\nQUOTIENT\t\t= QUOTIENT\t\t##\tVrátí celou část dělení.\r\nRADIANS\t\t\t= RADIANS\t\t##\tPřevede stupně na radiány.\r\nRAND\t\t\t= NÁHČÍSLO\t\t##\tVrátí náhodné číslo mezi 0 a 1.\r\nRANDBETWEEN\t\t= RANDBETWEEN\t\t##\tVrátí náhodné číslo mezi zadanými čísly.\r\nROMAN\t\t\t= ROMAN\t\t\t##\tPřevede arabskou číslici na římskou ve formátu textu.\r\nROUND\t\t\t= ZAOKROUHLIT\t\t##\tZaokrouhlí číslo na zadaný počet číslic.\r\nROUNDDOWN\t\t= ROUNDDOWN\t\t##\tZaokrouhlí číslo dolů, směrem k nule.\r\nROUNDUP\t\t\t= ROUNDUP\t\t##\tZaokrouhlí číslo nahoru, směrem od nuly.\r\nSERIESSUM\t\t= SERIESSUM\t\t##\tVrátí součet mocninné řady určené podle vzorce.\r\nSIGN\t\t\t= SIGN\t\t\t##\tVrátí znaménko čísla.\r\nSIN\t\t\t= SIN\t\t\t##\tVrátí sinus daného úhlu.\r\nSINH\t\t\t= SINH\t\t\t##\tVrátí hyperbolický sinus čísla.\r\nSQRT\t\t\t= ODMOCNINA\t\t##\tVrátí kladnou druhou odmocninu.\r\nSQRTPI\t\t\t= SQRTPI\t\t##\tVrátí druhou odmocninu výrazu (číslo * pí).\r\nSUBTOTAL\t\t= SUBTOTAL\t\t##\tVrátí souhrn v seznamu nebo databázi.\r\nSUM\t\t\t= SUMA\t\t\t##\tSečte argumenty funkce.\r\nSUMIF\t\t\t= SUMIF\t\t\t##\tSečte buňky vybrané podle zadaných kritérií.\r\nSUMIFS\t\t\t= SUMIFS\t\t##\tSečte buňky určené více zadanými podmínkami.\r\nSUMPRODUCT\t\t= SOUČIN.SKALÁRNÍ\t##\tVrátí součet součinů odpovídajících prvků matic.\r\nSUMSQ\t\t\t= SUMA.ČTVERCŮ\t\t##\tVrátí součet čtverců argumentů.\r\nSUMX2MY2\t\t= SUMX2MY2\t\t##\tVrátí součet rozdílu čtverců odpovídajících hodnot ve dvou maticích.\r\nSUMX2PY2\t\t= SUMX2PY2\t\t##\tVrátí součet součtu čtverců odpovídajících hodnot ve dvou maticích.\r\nSUMXMY2\t\t\t= SUMXMY2\t\t##\tVrátí součet čtverců rozdílů odpovídajících hodnot ve dvou maticích.\r\nTAN\t\t\t= TGTG\t\t\t##\tVrátí tangens čísla.\r\nTANH\t\t\t= TGH\t\t\t##\tVrátí hyperbolický tangens čísla.\r\nTRUNC\t\t\t= USEKNOUT\t\t##\tZkrátí číslo na celé číslo.\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\tStatistické funkce\r\n##\r\nAVEDEV\t\t\t= PRŮMODCHYLKA\t\t##\tVrátí průměrnou hodnotu absolutních odchylek datových bodů od jejich střední hodnoty.\r\nAVERAGE\t\t\t= PRŮMĚR\t\t##\tVrátí průměrnou hodnotu argumentů.\r\nAVERAGEA\t\t= AVERAGEA\t\t##\tVrátí průměrnou hodnotu argumentů včetně čísel, textu a logických hodnot.\r\nAVERAGEIF\t\t= AVERAGEIF\t\t##\tVrátí průměrnou hodnotu (aritmetický průměr) všech buněk v oblasti, které vyhovují příslušné podmínce.\r\nAVERAGEIFS\t\t= AVERAGEIFS\t\t##\tVrátí průměrnou hodnotu (aritmetický průměr) všech buněk vyhovujících několika podmínkám.\r\nBETADIST\t\t= BETADIST\t\t##\tVrátí hodnotu součtového rozdělení beta.\r\nBETAINV\t\t\t= BETAINV\t\t##\tVrátí inverzní hodnotu součtového rozdělení pro zadané rozdělení beta.\r\nBINOMDIST\t\t= BINOMDIST\t\t##\tVrátí hodnotu binomického rozdělení pravděpodobnosti jednotlivých veličin.\r\nCHIDIST\t\t\t= CHIDIST\t\t##\tVrátí jednostrannou pravděpodobnost rozdělení chí-kvadrát.\r\nCHIINV\t\t\t= CHIINV\t\t##\tVrátí hodnotu funkce inverzní k distribuční funkci jednostranné pravděpodobnosti rozdělení chí-kvadrát.\r\nCHITEST\t\t\t= CHITEST\t\t##\tVrátí test nezávislosti.\r\nCONFIDENCE\t\t= CONFIDENCE\t\t##\tVrátí interval spolehlivosti pro střední hodnotu základního souboru.\r\nCORREL\t\t\t= CORREL\t\t##\tVrátí korelační koeficient mezi dvěma množinami dat.\r\nCOUNT\t\t\t= POČET\t\t\t##\tVrátí počet čísel v seznamu argumentů.\r\nCOUNTA\t\t\t= POČET2\t\t##\tVrátí počet hodnot v seznamu argumentů.\r\nCOUNTBLANK\t\t= COUNTBLANK\t\t##\tSpočítá počet prázdných buněk v oblasti.\r\nCOUNTIF\t\t\t= COUNTIF\t\t##\tSpočítá buňky v oblasti, které odpovídají zadaným kritériím.\r\nCOUNTIFS\t\t= COUNTIFS\t\t##\tSpočítá buňky v oblasti, které odpovídají více kritériím.\r\nCOVAR\t\t\t= COVAR\t\t\t##\tVrátí hodnotu kovariance, průměrnou hodnotu součinů párových odchylek\r\nCRITBINOM\t\t= CRITBINOM\t\t##\tVrátí nejmenší hodnotu, pro kterou má součtové binomické rozdělení hodnotu větší nebo rovnu hodnotě kritéria.\r\nDEVSQ\t\t\t= DEVSQ\t\t\t##\tVrátí součet čtverců odchylek.\r\nEXPONDIST\t\t= EXPONDIST\t\t##\tVrátí hodnotu exponenciálního rozdělení.\r\nFDIST\t\t\t= FDIST\t\t\t##\tVrátí hodnotu rozdělení pravděpodobnosti F.\r\nFINV\t\t\t= FINV\t\t\t##\tVrátí hodnotu inverzní funkce k distribuční funkci rozdělení F.\r\nFISHER\t\t\t= FISHER\t\t##\tVrátí hodnotu Fisherovy transformace.\r\nFISHERINV\t\t= FISHERINV\t\t##\tVrátí hodnotu inverzní funkce k Fisherově transformaci.\r\nFORECAST\t\t= FORECAST\t\t##\tVrátí hodnotu lineárního trendu.\r\nFREQUENCY\t\t= ČETNOSTI\t\t##\tVrátí četnost rozdělení jako svislou matici.\r\nFTEST\t\t\t= FTEST\t\t\t##\tVrátí výsledek F-testu.\r\nGAMMADIST\t\t= GAMMADIST\t\t##\tVrátí hodnotu rozdělení gama.\r\nGAMMAINV\t\t= GAMMAINV\t\t##\tVrátí hodnotu inverzní funkce k distribuční funkci součtového rozdělení gama.\r\nGAMMALN\t\t\t= GAMMALN\t\t##\tVrátí přirozený logaritmus funkce gama, Γ(x).\r\nGEOMEAN\t\t\t= GEOMEAN\t\t##\tVrátí geometrický průměr.\r\nGROWTH\t\t\t= LOGLINTREND\t\t##\tVrátí hodnoty exponenciálního trendu.\r\nHARMEAN\t\t\t= HARMEAN\t\t##\tVrátí harmonický průměr.\r\nHYPGEOMDIST\t\t= HYPGEOMDIST\t\t##\tVrátí hodnotu hypergeometrického rozdělení.\r\nINTERCEPT\t\t= INTERCEPT\t\t##\tVrátí úsek lineární regresní čáry.\r\nKURT\t\t\t= KURT\t\t\t##\tVrátí hodnotu excesu množiny dat.\r\nLARGE\t\t\t= LARGE\t\t\t##\tVrátí k-tou největší hodnotu množiny dat.\r\nLINEST\t\t\t= LINREGRESE\t\t##\tVrátí parametry lineárního trendu.\r\nLOGEST\t\t\t= LOGLINREGRESE\t\t##\tVrátí parametry exponenciálního trendu.\r\nLOGINV\t\t\t= LOGINV\t\t##\tVrátí inverzní funkci k distribuční funkci logaritmicko-normálního rozdělení.\r\nLOGNORMDIST\t\t= LOGNORMDIST\t\t##\tVrátí hodnotu součtového logaritmicko-normálního rozdělení.\r\nMAX\t\t\t= MAX\t\t\t##\tVrátí maximální hodnotu seznamu argumentů.\r\nMAXA\t\t\t= MAXA\t\t\t##\tVrátí maximální hodnotu seznamu argumentů včetně čísel, textu a logických hodnot.\r\nMEDIAN\t\t\t= MEDIAN\t\t##\tVrátí střední hodnotu zadaných čísel.\r\nMIN\t\t\t= MIN\t\t\t##\tVrátí minimální hodnotu seznamu argumentů.\r\nMINA\t\t\t= MINA\t\t\t##\tVrátí nejmenší hodnotu v seznamu argumentů včetně čísel, textu a logických hodnot.\r\nMODE\t\t\t= MODE\t\t\t##\tVrátí hodnotu, která se v množině dat vyskytuje nejčastěji.\r\nNEGBINOMDIST\t\t= NEGBINOMDIST\t\t##\tVrátí hodnotu negativního binomického rozdělení.\r\nNORMDIST\t\t= NORMDIST\t\t##\tVrátí hodnotu normálního součtového rozdělení.\r\nNORMINV\t\t\t= NORMINV\t\t##\tVrátí inverzní funkci k funkci normálního součtového rozdělení.\r\nNORMSDIST\t\t= NORMSDIST\t\t##\tVrátí hodnotu standardního normálního součtového rozdělení.\r\nNORMSINV\t\t= NORMSINV\t\t##\tVrátí inverzní funkci k funkci standardního normálního součtového rozdělení.\r\nPEARSON\t\t\t= PEARSON\t\t##\tVrátí Pearsonův výsledný momentový korelační koeficient.\r\nPERCENTILE\t\t= PERCENTIL\t\t##\tVrátí hodnotu k-tého percentilu hodnot v oblasti.\r\nPERCENTRANK\t\t= PERCENTRANK\t\t##\tVrátí pořadí hodnoty v množině dat vyjádřené procentuální částí množiny dat.\r\nPERMUT\t\t\t= PERMUTACE\t\t##\tVrátí počet permutací pro zadaný počet objektů.\r\nPOISSON\t\t\t= POISSON\t\t##\tVrátí hodnotu distribuční funkce Poissonova rozdělení.\r\nPROB\t\t\t= PROB\t\t\t##\tVrátí pravděpodobnost výskytu hodnot v oblasti mezi dvěma mezními hodnotami.\r\nQUARTILE\t\t= QUARTIL\t\t##\tVrátí hodnotu kvartilu množiny dat.\r\nRANK\t\t\t= RANK\t\t\t##\tVrátí pořadí čísla v seznamu čísel.\r\nRSQ\t\t\t= RKQ\t\t\t##\tVrátí druhou mocninu Pearsonova výsledného momentového korelačního koeficientu.\r\nSKEW\t\t\t= SKEW\t\t\t##\tVrátí zešikmení rozdělení.\r\nSLOPE\t\t\t= SLOPE\t\t\t##\tVrátí směrnici lineární regresní čáry.\r\nSMALL\t\t\t= SMALL\t\t\t##\tVrátí k-tou nejmenší hodnotu množiny dat.\r\nSTANDARDIZE\t\t= STANDARDIZE\t\t##\tVrátí normalizovanou hodnotu.\r\nSTDEV\t\t\t= SMODCH.VÝBĚR\t\t##\tVypočte směrodatnou odchylku výběru.\r\nSTDEVA\t\t\t= STDEVA\t\t##\tVypočte směrodatnou odchylku výběru včetně čísel, textu a logických hodnot.\r\nSTDEVP\t\t\t= SMODCH\t\t##\tVypočte směrodatnou odchylku základního souboru.\r\nSTDEVPA\t\t\t= STDEVPA\t\t##\tVypočte směrodatnou odchylku základního souboru včetně čísel, textu a logických hodnot.\r\nSTEYX\t\t\t= STEYX\t\t\t##\tVrátí standardní chybu předpovězené hodnoty y pro každou hodnotu x v regresi.\r\nTDIST\t\t\t= TDIST\t\t\t##\tVrátí hodnotu Studentova t-rozdělení.\r\nTINV\t\t\t= TINV\t\t\t##\tVrátí inverzní funkci k distribuční funkci Studentova t-rozdělení.\r\nTREND\t\t\t= LINTREND\t\t##\tVrátí hodnoty lineárního trendu.\r\nTRIMMEAN\t\t= TRIMMEAN\t\t##\tVrátí střední hodnotu vnitřní části množiny dat.\r\nTTEST\t\t\t= TTEST\t\t\t##\tVrátí pravděpodobnost spojenou se Studentovým t-testem.\r\nVAR\t\t\t= VAR.VÝBĚR\t\t##\tVypočte rozptyl výběru.\r\nVARA\t\t\t= VARA\t\t\t##\tVypočte rozptyl výběru včetně čísel, textu a logických hodnot.\r\nVARP\t\t\t= VAR\t\t\t##\tVypočte rozptyl základního souboru.\r\nVARPA\t\t\t= VARPA\t\t\t##\tVypočte rozptyl základního souboru včetně čísel, textu a logických hodnot.\r\nWEIBULL\t\t\t= WEIBULL\t\t##\tVrátí hodnotu Weibullova rozdělení.\r\nZTEST\t\t\t= ZTEST\t\t\t##\tVrátí jednostrannou P-hodnotu z-testu.\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\tTextové funkce\r\n##\r\nASC\t\t\t= ASC\t\t\t##\tZmění znaky s plnou šířkou (dvoubajtové)v řetězci znaků na znaky s poloviční šířkou (jednobajtové).\r\nBAHTTEXT\t\t= BAHTTEXT\t\t##\tPřevede číslo na text ve formátu, měny ß (baht).\r\nCHAR\t\t\t= ZNAK\t\t\t##\tVrátí znak určený číslem kódu.\r\nCLEAN\t\t\t= VYČISTIT\t\t##\tOdebere z textu všechny netisknutelné znaky.\r\nCODE\t\t\t= KÓD\t\t\t##\tVrátí číselný kód prvního znaku zadaného textového řetězce.\r\nCONCATENATE\t\t= CONCATENATE\t\t##\tSpojí několik textových položek do jedné.\r\nDOLLAR\t\t\t= KČ\t\t\t##\tPřevede číslo na text ve formátu měny Kč (česká koruna).\r\nEXACT\t\t\t= STEJNÉ\t\t##\tZkontroluje, zda jsou dvě textové hodnoty shodné.\r\nFIND\t\t\t= NAJÍT\t\t\t##\tNalezne textovou hodnotu uvnitř jiné (rozlišuje malá a velká písmena).\r\nFINDB\t\t\t= FINDB\t\t\t##\tNalezne textovou hodnotu uvnitř jiné (rozlišuje malá a velká písmena).\r\nFIXED\t\t\t= ZAOKROUHLIT.NA.TEXT\t##\tZformátuje číslo jako text s pevným počtem desetinných míst.\r\nJIS\t\t\t= JIS\t\t\t##\tZmění znaky s poloviční šířkou (jednobajtové) v řetězci znaků na znaky s plnou šířkou (dvoubajtové).\r\nLEFT\t\t\t= ZLEVA\t\t\t##\tVrátí první znaky textové hodnoty umístěné nejvíce vlevo.\r\nLEFTB\t\t\t= LEFTB\t\t\t##\tVrátí první znaky textové hodnoty umístěné nejvíce vlevo.\r\nLEN\t\t\t= DÉLKA\t\t\t##\tVrátí počet znaků textového řetězce.\r\nLENB\t\t\t= LENB\t\t\t##\tVrátí počet znaků textového řetězce.\r\nLOWER\t\t\t= MALÁ\t\t\t##\tPřevede text na malá písmena.\r\nMID\t\t\t= ČÁST\t\t\t##\tVrátí určitý počet znaků textového řetězce počínaje zadaným místem.\r\nMIDB\t\t\t= MIDB\t\t\t##\tVrátí určitý počet znaků textového řetězce počínaje zadaným místem.\r\nPHONETIC\t\t= ZVUKOVÉ\t\t##\tExtrahuje fonetické znaky (furigana) z textového řetězce.\r\nPROPER\t\t\t= VELKÁ2\t\t##\tPřevede první písmeno každého slova textové hodnoty na velké.\r\nREPLACE\t\t\t= NAHRADIT\t\t##\tNahradí znaky uvnitř textu.\r\nREPLACEB\t\t= NAHRADITB\t\t##\tNahradí znaky uvnitř textu.\r\nREPT\t\t\t= OPAKOVAT\t\t##\tZopakuje text podle zadaného počtu opakování.\r\nRIGHT\t\t\t= ZPRAVA\t\t##\tVrátí první znaky textové hodnoty umístěné nejvíce vpravo.\r\nRIGHTB\t\t\t= RIGHTB\t\t##\tVrátí první znaky textové hodnoty umístěné nejvíce vpravo.\r\nSEARCH\t\t\t= HLEDAT\t\t##\tNalezne textovou hodnotu uvnitř jiné (malá a velká písmena nejsou rozlišována).\r\nSEARCHB\t\t\t= SEARCHB\t\t##\tNalezne textovou hodnotu uvnitř jiné (malá a velká písmena nejsou rozlišována).\r\nSUBSTITUTE\t\t= DOSADIT\t\t##\tV textovém řetězci nahradí starý text novým.\r\nT\t\t\t= T\t\t\t##\tPřevede argumenty na text.\r\nTEXT\t\t\t= HODNOTA.NA.TEXT\t##\tZformátuje číslo a převede ho na text.\r\nTRIM\t\t\t= PROČISTIT\t\t##\tOdstraní z textu mezery.\r\nUPPER\t\t\t= VELKÁ\t\t\t##\tPřevede text na velká písmena.\r\nVALUE\t\t\t= HODNOTA\t\t##\tPřevede textový argument na číslo.\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/da/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= kr\n\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #NUL!\r\nDIV0\t= #DIVISION/0!\r\nVALUE\t= #VÆRDI!\r\nREF\t= #REFERENCE!\r\nNAME\t= #NAVN?\r\nNUM\t= #NUM!\r\nNA\t= #I/T\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/da/functions",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Calculation\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/\r\n##\r\n##\r\n\r\n\r\n##\r\n##\tAdd-in and Automation functions\t\t\tTilføjelsesprogram- og automatiseringsfunktioner\r\n##\r\nGETPIVOTDATA\t\t= HENTPIVOTDATA\t\t\t##\tReturnerer data, der er lagret i en pivottabelrapport\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\tKubefunktioner\r\n##\r\nCUBEKPIMEMBER\t\t= KUBE.KPI.MEDLEM\t\t##\tReturnerer navn, egenskab og mål for en KPI-indikator og viser navnet og egenskaben i cellen. En KPI-indikator er en målbar størrelse, f.eks. bruttooverskud pr. måned eller personaleudskiftning pr. kvartal, der bruges til at overvåge en organisations præstationer.\r\nCUBEMEMBER\t\t= KUBE.MEDLEM\t\t\t##\tReturnerer et medlem eller en tupel fra kubehierarkiet. Bruges til at validere, om et medlem eller en tupel findes i kuben.\r\nCUBEMEMBERPROPERTY\t= KUBEMEDLEM.EGENSKAB\t\t##\tReturnerer værdien af en egenskab for et medlem i kuben. Bruges til at validere, om et medlemsnavn findes i kuben, og returnere den angivne egenskab for medlemmet.\r\nCUBERANKEDMEMBER\t= KUBEMEDLEM.RANG\t\t##\tReturnerer det n'te eller rangordnede medlem i et sæt. Bruges til at returnere et eller flere elementer i et sæt, f.eks. topsælgere eller de 10 bedste elever.\r\nCUBESET\t\t\t= KUBESÆT\t\t\t##\tDefinerer et beregnet sæt medlemmer eller tupler ved at sende et sætudtryk til kuben på serveren, som opretter sættet og returnerer det til Microsoft Office Excel.\r\nCUBESETCOUNT\t\t= KUBESÆT.TÆL\t\t\t##\tReturnerer antallet af elementer i et sæt.\r\nCUBEVALUE\t\t= KUBEVÆRDI\t\t\t##\tReturnerer en sammenlagt (aggregeret) værdi fra en kube.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\tDatabasefunktioner\r\n##\r\nDAVERAGE\t\t= DMIDDEL\t\t\t##\tReturnerer gennemsnittet af markerede databaseposter\r\nDCOUNT\t\t\t= DTÆL\t\t\t\t##\tTæller de celler, der indeholder tal, i en database\r\nDCOUNTA\t\t\t= DTÆLV\t\t\t\t##\tTæller udfyldte celler i en database\r\nDGET\t\t\t= DHENT\t\t\t\t##\tUddrager en enkelt post, der opfylder de angivne kriterier, fra en database\r\nDMAX\t\t\t= DMAKS\t\t\t\t##\tReturnerer den største værdi blandt markerede databaseposter\r\nDMIN\t\t\t= DMIN\t\t\t\t##\tReturnerer den mindste værdi blandt markerede databaseposter\r\nDPRODUCT\t\t= DPRODUKT\t\t\t##\tGanger værdierne i et bestemt felt med poster, der opfylder kriterierne i en database\r\nDSTDEV\t\t\t= DSTDAFV\t\t\t##\tBeregner et skøn over standardafvigelsen baseret på en stikprøve af markerede databaseposter\r\nDSTDEVP\t\t\t= DSTDAFVP\t\t\t##\tBeregner standardafvigelsen baseret på hele populationen af markerede databaseposter\r\nDSUM\t\t\t= DSUM\t\t\t\t##\tSammenlægger de tal i feltkolonnen i databasen, der opfylder kriterierne\r\nDVAR\t\t\t= DVARIANS\t\t\t##\tBeregner varians baseret på en stikprøve af markerede databaseposter\r\nDVARP\t\t\t= DVARIANSP\t\t\t##\tBeregner varians baseret på hele populationen af markerede databaseposter\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\tDato- og klokkeslætsfunktioner\r\n##\r\nDATE\t\t\t= DATO\t\t\t\t##\tReturnerer serienummeret for en bestemt dato\r\nDATEVALUE\t\t= DATOVÆRDI\t\t\t##\tKonverterer en dato i form af tekst til et serienummer\r\nDAY\t\t\t= DAG\t\t\t\t##\tKonverterer et serienummer til en dag i måneden\r\nDAYS360\t\t\t= DAGE360\t\t\t##\tBeregner antallet af dage mellem to datoer på grundlag af et år med 360 dage\r\nEDATE\t\t\t= EDATO\t\t\t\t##\tReturnerer serienummeret for den dato, der ligger det angivne antal måneder før eller efter startdatoen\r\nEOMONTH\t\t\t= SLUT.PÅ.MÅNED\t\t\t##\tReturnerer serienummeret på den sidste dag i måneden før eller efter et angivet antal måneder\r\nHOUR\t\t\t= TIME\t\t\t\t##\tKonverterer et serienummer til en time\r\nMINUTE\t\t\t= MINUT\t\t\t\t##\tKonverterer et serienummer til et minut\r\nMONTH\t\t\t= MÅNED\t\t\t\t##\tKonverterer et serienummer til en måned\r\nNETWORKDAYS\t\t= ANTAL.ARBEJDSDAGE\t\t##\tReturnerer antallet af hele arbejdsdage mellem to datoer\r\nNOW\t\t\t= NU\t\t\t\t##\tReturnerer serienummeret for den aktuelle dato eller det aktuelle klokkeslæt\r\nSECOND\t\t\t= SEKUND\t\t\t##\tKonverterer et serienummer til et sekund\r\nTIME\t\t\t= KLOKKESLÆT\t\t\t##\tReturnerer serienummeret for et bestemt klokkeslæt\r\nTIMEVALUE\t\t= TIDSVÆRDI\t\t\t##\tKonverterer et klokkeslæt i form af tekst til et serienummer\r\nTODAY\t\t\t= IDAG\t\t\t\t##\tReturnerer serienummeret for dags dato\r\nWEEKDAY\t\t\t= UGEDAG\t\t\t##\tKonverterer et serienummer til en ugedag\r\nWEEKNUM\t\t\t= UGE.NR\t\t\t##\tKonverterer et serienummer til et tal, der angiver ugenummeret i året\r\nWORKDAY\t\t\t= ARBEJDSDAG\t\t\t##\tReturnerer serienummeret for dagen før eller efter det angivne antal arbejdsdage\r\nYEAR\t\t\t= ÅR\t\t\t\t##\tKonverterer et serienummer til et år\r\nYEARFRAC\t\t= ÅR.BRØK\t\t\t##\tReturnerer årsbrøken, der repræsenterer antallet af hele dage mellem startdato og slutdato\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\tTekniske funktioner\r\n##\r\nBESSELI\t\t\t= BESSELI\t\t\t##\tReturnerer den modificerede Bessel-funktion In(x)\r\nBESSELJ\t\t\t= BESSELJ\t\t\t##\tReturnerer Bessel-funktionen Jn(x)\r\nBESSELK\t\t\t= BESSELK\t\t\t##\tReturnerer den modificerede Bessel-funktion Kn(x)\r\nBESSELY\t\t\t= BESSELY\t\t\t##\tReturnerer Bessel-funktionen Yn(x)\r\nBIN2DEC\t\t\t= BIN.TIL.DEC\t\t\t##\tKonverterer et binært tal til et decimaltal\r\nBIN2HEX\t\t\t= BIN.TIL.HEX\t\t\t##\tKonverterer et binært tal til et heksadecimalt tal\r\nBIN2OCT\t\t\t= BIN.TIL.OKT\t\t\t##\tKonverterer et binært tal til et oktaltal.\r\nCOMPLEX\t\t\t= KOMPLEKS\t\t\t##\tKonverterer reelle og imaginære koefficienter til et komplekst tal\r\nCONVERT\t\t\t= KONVERTER\t\t\t##\tKonverterer et tal fra én måleenhed til en anden\r\nDEC2BIN\t\t\t= DEC.TIL.BIN\t\t\t##\tKonverterer et decimaltal til et binært tal\r\nDEC2HEX\t\t\t= DEC.TIL.HEX\t\t\t##\tKonverterer et decimaltal til et heksadecimalt tal\r\nDEC2OCT\t\t\t= DEC.TIL.OKT\t\t\t##\tKonverterer et decimaltal til et oktaltal\r\nDELTA\t\t\t= DELTA\t\t\t\t##\tTester, om to værdier er ens\r\nERF\t\t\t= FEJLFUNK\t\t\t##\tReturner fejlfunktionen\r\nERFC\t\t\t= FEJLFUNK.KOMP\t\t\t##\tReturnerer den komplementære fejlfunktion\r\nGESTEP\t\t\t= GETRIN\t\t\t##\tTester, om et tal er større end en grænseværdi\r\nHEX2BIN\t\t\t= HEX.TIL.BIN\t\t\t##\tKonverterer et heksadecimalt tal til et binært tal\r\nHEX2DEC\t\t\t= HEX.TIL.DEC\t\t\t##\tKonverterer et decimaltal til et heksadecimalt tal\r\nHEX2OCT\t\t\t= HEX.TIL.OKT\t\t\t##\tKonverterer et heksadecimalt tal til et oktaltal\r\nIMABS\t\t\t= IMAGABS\t\t\t##\tReturnerer den absolutte værdi (modulus) for et komplekst tal\r\nIMAGINARY\t\t= IMAGINÆR\t\t\t##\tReturnerer den imaginære koefficient for et komplekst tal\r\nIMARGUMENT\t\t= IMAGARGUMENT\t\t\t##\tReturnerer argumentet theta, en vinkel udtrykt i radianer\r\nIMCONJUGATE\t\t= IMAGKONJUGERE\t\t\t##\tReturnerer den komplekse konjugation af et komplekst tal\r\nIMCOS\t\t\t= IMAGCOS\t\t\t##\tReturnerer et komplekst tals cosinus\r\nIMDIV\t\t\t= IMAGDIV\t\t\t##\tReturnerer kvotienten for to komplekse tal\r\nIMEXP\t\t\t= IMAGEKSP\t\t\t##\tReturnerer et komplekst tals eksponentialfunktion\r\nIMLN\t\t\t= IMAGLN\t\t\t##\tReturnerer et komplekst tals naturlige logaritme\r\nIMLOG10\t\t\t= IMAGLOG10\t\t\t##\tReturnerer et komplekst tals sædvanlige logaritme (titalslogaritme)\r\nIMLOG2\t\t\t= IMAGLOG2\t\t\t##\tReturnerer et komplekst tals sædvanlige logaritme (totalslogaritme)\r\nIMPOWER\t\t\t= IMAGPOTENS\t\t\t##\tReturnerer et komplekst tal opløftet i en heltalspotens\r\nIMPRODUCT\t\t= IMAGPRODUKT\t\t\t##\tReturnerer produktet af komplekse tal\r\nIMREAL\t\t\t= IMAGREELT\t\t\t##\tReturnerer den reelle koefficient for et komplekst tal\r\nIMSIN\t\t\t= IMAGSIN\t\t\t##\tReturnerer et komplekst tals sinus\r\nIMSQRT\t\t\t= IMAGKVROD\t\t\t##\tReturnerer et komplekst tals kvadratrod\r\nIMSUB\t\t\t= IMAGSUB\t\t\t##\tReturnerer forskellen mellem to komplekse tal\r\nIMSUM\t\t\t= IMAGSUM\t\t\t##\tReturnerer summen af komplekse tal\r\nOCT2BIN\t\t\t= OKT.TIL.BIN\t\t\t##\tKonverterer et oktaltal til et binært tal\r\nOCT2DEC\t\t\t= OKT.TIL.DEC\t\t\t##\tKonverterer et oktaltal til et decimaltal\r\nOCT2HEX\t\t\t= OKT.TIL.HEX\t\t\t##\tKonverterer et oktaltal til et heksadecimalt tal\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\tFinansielle funktioner\r\n##\r\nACCRINT\t\t\t= PÅLØBRENTE\t\t\t##\tReturnerer den påløbne rente for et værdipapir med periodiske renteudbetalinger\r\nACCRINTM\t\t= PÅLØBRENTE.UDLØB\t\t##\tReturnerer den påløbne rente for et værdipapir, hvor renteudbetalingen finder sted ved papirets udløb\r\nAMORDEGRC\t\t= AMORDEGRC\t\t\t##\tReturnerer afskrivningsbeløbet for hver regnskabsperiode ved hjælp af en afskrivningskoefficient\r\nAMORLINC\t\t= AMORLINC\t\t\t##\tReturnerer afskrivningsbeløbet for hver regnskabsperiode\r\nCOUPDAYBS\t\t= KUPONDAGE.SA\t\t\t##\tReturnerer antallet af dage fra starten af kuponperioden til afregningsdatoen\r\nCOUPDAYS\t\t= KUPONDAGE.A\t\t\t##\tReturnerer antallet af dage fra begyndelsen af kuponperioden til afregningsdatoen\r\nCOUPDAYSNC\t\t= KUPONDAGE.ANK\t\t\t##\tReturnerer antallet af dage i den kuponperiode, der indeholder afregningsdatoen\r\nCOUPNCD\t\t\t= KUPONDAG.NÆSTE\t\t##\tReturnerer den næste kupondato efter afregningsdatoen\r\nCOUPNUM\t\t\t= KUPONBETALINGER\t\t##\tReturnerer antallet af kuponudbetalinger mellem afregnings- og udløbsdatoen\r\nCOUPPCD\t\t\t= KUPONDAG.FORRIGE\t\t##\tReturnerer den forrige kupondato før afregningsdatoen\r\nCUMIPMT\t\t\t= AKKUM.RENTE\t\t\t##\tReturnerer den akkumulerede rente, der betales på et lån mellem to perioder\r\nCUMPRINC\t\t= AKKUM.HOVEDSTOL\t\t##\tReturnerer den akkumulerede nedbringelse af hovedstol mellem to perioder\r\nDB\t\t\t= DB\t\t\t\t##\tReturnerer afskrivningen på et aktiv i en angivet periode ved anvendelse af saldometoden\r\nDDB\t\t\t= DSA\t\t\t\t##\tReturnerer afskrivningsbeløbet for et aktiv over en bestemt periode ved anvendelse af dobbeltsaldometoden eller en anden afskrivningsmetode, som du angiver\r\nDISC\t\t\t= DISKONTO\t\t\t##\tReturnerer et værdipapirs diskonto\r\nDOLLARDE\t\t= KR.DECIMAL\t\t\t##\tKonverterer en kronepris udtrykt som brøk til en kronepris udtrykt som decimaltal\r\nDOLLARFR\t\t= KR.BRØK\t\t\t##\tKonverterer en kronepris udtrykt som decimaltal til en kronepris udtrykt som brøk\r\nDURATION\t\t= VARIGHED\t\t\t##\tReturnerer den årlige løbetid for et værdipapir med periodiske renteudbetalinger\r\nEFFECT\t\t\t= EFFEKTIV.RENTE\t\t##\tReturnerer den årlige effektive rente\r\nFV\t\t\t= FV\t\t\t\t##\tReturnerer fremtidsværdien af en investering\r\nFVSCHEDULE\t\t= FVTABEL\t\t\t##\tReturnerer den fremtidige værdi af en hovedstol, når der er tilskrevet rente og rentes rente efter forskellige rentesatser\r\nINTRATE\t\t\t= RENTEFOD\t\t\t##\tReturnerer renten på et fuldt ud investeret værdipapir\r\nIPMT\t\t\t= R.YDELSE\t\t\t##\tReturnerer renten fra en investering for en given periode\r\nIRR\t\t\t= IA\t\t\t\t##\tReturnerer den interne rente for en række pengestrømme\r\nISPMT\t\t\t= ISPMT\t\t\t\t##\tBeregner den betalte rente i løbet af en bestemt investeringsperiode\r\nMDURATION\t\t= MVARIGHED\t\t\t##\tReturnerer Macauleys modificerede løbetid for et værdipapir med en formodet pari på kr. 100\r\nMIRR\t\t\t= MIA\t\t\t\t##\tReturnerer den interne forrentning, hvor positive og negative pengestrømme finansieres til forskellig rente\r\nNOMINAL\t\t\t= NOMINEL\t\t\t##\tReturnerer den årlige nominelle rente\r\nNPER\t\t\t= NPER\t\t\t\t##\tReturnerer antallet af perioder for en investering\r\nNPV\t\t\t= NUTIDSVÆRDI\t\t\t##\tReturnerer nettonutidsværdien for en investering baseret på en række periodiske pengestrømme og en diskonteringssats\r\nODDFPRICE\t\t= ULIGE.KURS.PÅLYDENDE\t\t##\tReturnerer kursen pr. kr. 100 nominel værdi for et værdipapir med en ulige (kort eller lang) første periode\r\nODDFYIELD\t\t= ULIGE.FØRSTE.AFKAST\t\t##\tReturnerer afkastet for et værdipapir med ulige første periode\r\nODDLPRICE\t\t= ULIGE.SIDSTE.KURS\t\t##\tReturnerer kursen pr. kr. 100 nominel værdi for et værdipapir med ulige sidste periode\r\nODDLYIELD\t\t= ULIGE.SIDSTE.AFKAST\t\t##\tReturnerer afkastet for et værdipapir med ulige sidste periode\r\nPMT\t\t\t= YDELSE\t\t\t##\tReturnerer renten fra en investering for en given periode\r\nPPMT\t\t\t= H.YDELSE\t\t\t##\tReturnerer ydelsen på hovedstolen for en investering i en given periode\r\nPRICE\t\t\t= KURS\t\t\t\t##\tReturnerer kursen pr. kr 100 nominel værdi for et værdipapir med periodiske renteudbetalinger\r\nPRICEDISC\t\t= KURS.DISKONTO\t\t\t##\tReturnerer kursen pr. kr 100 nominel værdi for et diskonteret værdipapir\r\nPRICEMAT\t\t= KURS.UDLØB\t\t\t##\tReturnerer kursen pr. kr 100 nominel værdi for et værdipapir, hvor renten udbetales ved papirets udløb\r\nPV\t\t\t= NV\t\t\t\t##\tReturnerer den nuværende værdi af en investering\r\nRATE\t\t\t= RENTE\t\t\t\t##\tReturnerer renten i hver periode for en annuitet\r\nRECEIVED\t\t= MODTAGET.VED.UDLØB\t\t##\tReturnerer det beløb, der modtages ved udløbet af et fuldt ud investeret værdipapir\r\nSLN\t\t\t= LA\t\t\t\t##\tReturnerer den lineære afskrivning for et aktiv i en enkelt periode\r\nSYD\t\t\t= ÅRSAFSKRIVNING\t\t##\tReturnerer den årlige afskrivning på et aktiv i en bestemt periode\r\nTBILLEQ\t\t\t= STATSOBLIGATION\t\t##\tReturnerer det obligationsækvivalente afkast for en statsobligation\r\nTBILLPRICE\t\t= STATSOBLIGATION.KURS\t\t##\tReturnerer kursen pr. kr 100 nominel værdi for en statsobligation\r\nTBILLYIELD\t\t= STATSOBLIGATION.AFKAST\t##\tReturnerer en afkastet på en statsobligation\r\nVDB\t\t\t= VSA\t\t\t\t##\tReturnerer afskrivningen på et aktiv i en angivet periode, herunder delperioder, ved brug af dobbeltsaldometoden\r\nXIRR\t\t\t= INTERN.RENTE\t\t\t##\tReturnerer den interne rente for en plan over pengestrømme, der ikke behøver at være periodiske\r\nXNPV\t\t\t= NETTO.NUTIDSVÆRDI\t\t##\tReturnerer nutidsværdien for en plan over pengestrømme, der ikke behøver at være periodiske\r\nYIELD\t\t\t= AFKAST\t\t\t##\tReturnerer afkastet for et værdipapir med periodiske renteudbetalinger\r\nYIELDDISC\t\t= AFKAST.DISKONTO\t\t##\tReturnerer det årlige afkast for et diskonteret værdipapir, f.eks. en statsobligation\r\nYIELDMAT\t\t= AFKAST.UDLØBSDATO\t\t##\tReturnerer det årlige afkast for et værdipapir, hvor renten udbetales ved papirets udløb\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\tInformationsfunktioner\r\n##\r\nCELL\t\t\t= CELLE\t\t\t\t##\tReturnerer oplysninger om formatering, placering eller indhold af en celle\r\nERROR.TYPE\t\t= FEJLTYPE\t\t\t##\tReturnerer et tal, der svarer til en fejltype\r\nINFO\t\t\t= INFO\t\t\t\t##\tReturnerer oplysninger om det aktuelle operativmiljø\r\nISBLANK\t\t\t= ER.TOM\t\t\t##\tReturnerer SAND, hvis værdien er tom\r\nISERR\t\t\t= ER.FJL\t\t\t##\tReturnerer SAND, hvis værdien er en fejlværdi undtagen #I/T\r\nISERROR\t\t\t= ER.FEJL\t\t\t##\tReturnerer SAND, hvis værdien er en fejlværdi\r\nISEVEN\t\t\t= ER.LIGE\t\t\t##\tReturnerer SAND, hvis tallet er lige\r\nISLOGICAL\t\t= ER.LOGISK\t\t\t##\tReturnerer SAND, hvis værdien er en logisk værdi\r\nISNA\t\t\t= ER.IKKE.TILGÆNGELIG\t\t##\tReturnerer SAND, hvis værdien er fejlværdien #I/T\r\nISNONTEXT\t\t= ER.IKKE.TEKST\t\t\t##\tReturnerer SAND, hvis værdien ikke er tekst\r\nISNUMBER\t\t= ER.TAL\t\t\t##\tReturnerer SAND, hvis værdien er et tal\r\nISODD\t\t\t= ER.ULIGE\t\t\t##\tReturnerer SAND, hvis tallet er ulige\r\nISREF\t\t\t= ER.REFERENCE\t\t\t##\tReturnerer SAND, hvis værdien er en reference\r\nISTEXT\t\t\t= ER.TEKST\t\t\t##\tReturnerer SAND, hvis værdien er tekst\r\nN\t\t\t= TAL\t\t\t\t##\tReturnerer en værdi konverteret til et tal\r\nNA\t\t\t= IKKE.TILGÆNGELIG\t\t##\tReturnerer fejlværdien #I/T\r\nTYPE\t\t\t= VÆRDITYPE\t\t\t##\tReturnerer et tal, der angiver datatypen for en værdi\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\tLogiske funktioner\r\n##\r\nAND\t\t\t= OG\t\t\t\t##\tReturnerer SAND, hvis alle argumenterne er sande\r\nFALSE\t\t\t= FALSK\t\t\t\t##\tReturnerer den logiske værdi FALSK\r\nIF\t\t\t= HVIS\t\t\t\t##\tAngiver en logisk test, der skal udføres\r\nIFERROR\t\t\t= HVIS.FEJL\t\t\t##\tReturnerer en værdi, du angiver, hvis en formel evauleres som en fejl. Returnerer i modsat fald resultatet af formlen\r\nNOT\t\t\t= IKKE\t\t\t\t##\tVender argumentets logik om\r\nOR\t\t\t= ELLER\t\t\t\t##\tReturneret værdien SAND, hvis mindst ét argument er sandt\r\nTRUE\t\t\t= SAND\t\t\t\t##\tReturnerer den logiske værdi SAND\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\tOpslags- og referencefunktioner\r\n##\r\nADDRESS\t\t\t= ADRESSE\t\t\t##\tReturnerer en reference som tekst til en enkelt celle i et regneark\r\nAREAS\t\t\t= OMRÅDER\t\t\t##\tReturnerer antallet af områder i en reference\r\nCHOOSE\t\t\t= VÆLG\t\t\t\t##\tVælger en værdi på en liste med værdier\r\nCOLUMN\t\t\t= KOLONNE\t\t\t##\tReturnerer kolonnenummeret i en reference\r\nCOLUMNS\t\t\t= KOLONNER\t\t\t##\tReturnerer antallet af kolonner i en reference\r\nHLOOKUP\t\t\t= VOPSLAG\t\t\t##\tSøger i den øverste række af en matrix og returnerer værdien af den angivne celle\r\nHYPERLINK\t\t= HYPERLINK\t\t\t##\tOpretter en genvej kaldet et hyperlink, der åbner et dokument, som er lagret på en netværksserver, på et intranet eller på internettet\r\nINDEX\t\t\t= INDEKS\t\t\t##\tAnvender et indeks til at vælge en værdi fra en reference eller en matrix\r\nINDIRECT\t\t= INDIREKTE\t\t\t##\tReturnerer en reference, der er angivet af en tekstværdi\r\nLOOKUP\t\t\t= SLÅ.OP\t\t\t##\tSøger værdier i en vektor eller en matrix\r\nMATCH\t\t\t= SAMMENLIGN\t\t\t##\tSøger værdier i en reference eller en matrix\r\nOFFSET\t\t\t= FORSKYDNING\t\t\t##\tReturnerer en reference forskudt i forhold til en given reference\r\nROW\t\t\t= RÆKKE\t\t\t\t##\tReturnerer rækkenummeret for en reference\r\nROWS\t\t\t= RÆKKER\t\t\t##\tReturnerer antallet af rækker i en reference\r\nRTD\t\t\t= RTD\t\t\t\t##\tHenter realtidsdata fra et program, der understøtter COM-automatisering (Automation: En metode til at arbejde med objekter fra et andet program eller udviklingsværktøj. Automation, som tidligere blev kaldt OLE Automation, er en industristandard og en funktion i COM (Component Object Model).)\r\nTRANSPOSE\t\t= TRANSPONER\t\t\t##\tReturnerer en transponeret matrix\r\nVLOOKUP\t\t\t= LOPSLAG\t\t\t##\tSøger i øverste række af en matrix og flytter på tværs af rækken for at returnere en celleværdi\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\tMatematiske og trigonometriske funktioner\r\n##\r\nABS\t\t\t= ABS\t\t\t\t##\tReturnerer den absolutte værdi af et tal\r\nACOS\t\t\t= ARCCOS\t\t\t##\tReturnerer et tals arcus cosinus\r\nACOSH\t\t\t= ARCCOSH\t\t\t##\tReturnerer den inverse hyperbolske cosinus af tal\r\nASIN\t\t\t= ARCSIN\t\t\t##\tReturnerer et tals arcus sinus\r\nASINH\t\t\t= ARCSINH\t\t\t##\tReturnerer den inverse hyperbolske sinus for tal\r\nATAN\t\t\t= ARCTAN\t\t\t##\tReturnerer et tals arcus tangens\r\nATAN2\t\t\t= ARCTAN2\t\t\t##\tReturnerer de angivne x- og y-koordinaters arcus tangens\r\nATANH\t\t\t= ARCTANH\t\t\t##\tReturnerer et tals inverse hyperbolske tangens\r\nCEILING\t\t\t= AFRUND.LOFT\t\t\t##\tAfrunder et tal til nærmeste heltal eller til nærmeste multiplum af betydning\r\nCOMBIN\t\t\t= KOMBIN\t\t\t##\tReturnerer antallet af kombinationer for et givet antal objekter\r\nCOS\t\t\t= COS\t\t\t\t##\tReturnerer et tals cosinus\r\nCOSH\t\t\t= COSH\t\t\t\t##\tReturnerer den inverse hyperbolske cosinus af et tal\r\nDEGREES\t\t\t= GRADER\t\t\t##\tKonverterer radianer til grader\r\nEVEN\t\t\t= LIGE\t\t\t\t##\tRunder et tal op til nærmeste lige heltal\r\nEXP\t\t\t= EKSP\t\t\t\t##\tReturnerer e opløftet til en potens af et angivet tal\r\nFACT\t\t\t= FAKULTET\t\t\t##\tReturnerer et tals fakultet\r\nFACTDOUBLE\t\t= DOBBELT.FAKULTET\t\t##\tReturnerer et tals dobbelte fakultet\r\nFLOOR\t\t\t= AFRUND.GULV\t\t\t##\tRunder et tal ned mod nul\r\nGCD\t\t\t= STØRSTE.FÆLLES.DIVISOR\t##\tReturnerer den største fælles divisor\r\nINT\t\t\t= HELTAL\t\t\t##\tNedrunder et tal til det nærmeste heltal\r\nLCM\t\t\t= MINDSTE.FÆLLES.MULTIPLUM\t##\tReturnerer det mindste fælles multiplum\r\nLN\t\t\t= LN\t\t\t\t##\tReturnerer et tals naturlige logaritme\r\nLOG\t\t\t= LOG\t\t\t\t##\tReturnerer logaritmen for et tal på grundlag af et angivet grundtal\r\nLOG10\t\t\t= LOG10\t\t\t\t##\tReturnerer titalslogaritmen af et tal\r\nMDETERM\t\t\t= MDETERM\t\t\t##\tReturnerer determinanten for en matrix\r\nMINVERSE\t\t= MINVERT\t\t\t##\tReturnerer den inverse matrix for en matrix\r\nMMULT\t\t\t= MPRODUKT\t\t\t##\tReturnerer matrixproduktet af to matrixer\r\nMOD\t\t\t= REST\t\t\t\t##\tReturnerer restværdien fra division\r\nMROUND\t\t\t= MAFRUND\t\t\t##\tReturnerer et tal afrundet til det ønskede multiplum\r\nMULTINOMIAL\t\t= MULTINOMIAL\t\t\t##\tReturnerer et multinomialt talsæt\r\nODD\t\t\t= ULIGE\t\t\t\t##\tRunder et tal op til nærmeste ulige heltal\r\nPI\t\t\t= PI\t\t\t\t##\tReturnerer værdien af pi\r\nPOWER\t\t\t= POTENS\t\t\t##\tReturnerer resultatet af et tal opløftet til en potens\r\nPRODUCT\t\t\t= PRODUKT\t\t\t##\tMultiplicerer argumenterne\r\nQUOTIENT\t\t= KVOTIENT\t\t\t##\tReturnerer heltalsdelen ved division\r\nRADIANS\t\t\t= RADIANER\t\t\t##\tKonverterer grader til radianer\r\nRAND\t\t\t= SLUMP\t\t\t\t##\tReturnerer et tilfældigt tal mellem 0 og 1\r\nRANDBETWEEN\t\t= SLUMP.MELLEM\t\t\t##\tReturnerer et tilfældigt tal mellem de tal, der angives\r\nROMAN\t\t\t= ROMERTAL\t\t\t##\tKonverterer et arabertal til romertal som tekst\r\nROUND\t\t\t= AFRUND\t\t\t##\tAfrunder et tal til et angivet antal decimaler\r\nROUNDDOWN\t\t= RUND.NED\t\t\t##\tRunder et tal ned mod nul\r\nROUNDUP\t\t\t= RUND.OP\t\t\t##\tRunder et tal op, væk fra 0 (nul)\r\nSERIESSUM\t\t= SERIESUM\t\t\t##\tReturnerer summen af en potensserie baseret på en formel\r\nSIGN\t\t\t= FORTEGN\t\t\t##\tReturnerer et tals fortegn\r\nSIN\t\t\t= SIN\t\t\t\t##\tReturnerer en given vinkels sinusværdi\r\nSINH\t\t\t= SINH\t\t\t\t##\tReturnerer den hyperbolske sinus af et tal\r\nSQRT\t\t\t= KVROD\t\t\t\t##\tReturnerer en positiv kvadratrod\r\nSQRTPI\t\t\t= KVRODPI\t\t\t##\tReturnerer kvadratroden af (tal * pi;)\r\nSUBTOTAL\t\t= SUBTOTAL\t\t\t##\tReturnerer en subtotal på en liste eller i en database\r\nSUM\t\t\t= SUM\t\t\t\t##\tLægger argumenterne sammen\r\nSUMIF\t\t\t= SUM.HVIS\t\t\t##\tLægger de celler sammen, der er specificeret af et givet kriterium.\r\nSUMIFS\t\t\t= SUM.HVISER\t\t\t##\tLægger de celler i et område sammen, der opfylder flere kriterier.\r\nSUMPRODUCT\t\t= SUMPRODUKT\t\t\t##\tReturnerer summen af produkter af ens matrixkomponenter\r\nSUMSQ\t\t\t= SUMKV\t\t\t\t##\tReturnerer summen af argumenternes kvadrater\r\nSUMX2MY2\t\t= SUMX2MY2\t\t\t##\tReturnerer summen af differensen mellem kvadrater af ens værdier i to matrixer\r\nSUMX2PY2\t\t= SUMX2PY2\t\t\t##\tReturnerer summen af summen af kvadrater af tilsvarende værdier i to matrixer\r\nSUMXMY2\t\t\t= SUMXMY2\t\t\t##\tReturnerer summen af kvadrater af differenser mellem ens værdier i to matrixer\r\nTAN\t\t\t= TAN\t\t\t\t##\tReturnerer et tals tangens\r\nTANH\t\t\t= TANH\t\t\t\t##\tReturnerer et tals hyperbolske tangens\r\nTRUNC\t\t\t= AFKORT\t\t\t##\tAfkorter et tal til et heltal\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\tStatistiske funktioner\r\n##\r\nAVEDEV\t\t\t= MAD\t\t\t\t##\tReturnerer den gennemsnitlige numeriske afvigelse fra stikprøvens middelværdi\r\nAVERAGE\t\t\t= MIDDEL\t\t\t##\tReturnerer middelværdien af argumenterne\r\nAVERAGEA\t\t= MIDDELV\t\t\t##\tReturnerer middelværdien af argumenterne og medtager tal, tekst og logiske værdier\r\nAVERAGEIF\t\t= MIDDEL.HVIS\t\t\t##\tReturnerer gennemsnittet (den aritmetiske middelværdi) af alle de celler, der opfylder et givet kriterium, i et område\r\nAVERAGEIFS\t\t= MIDDEL.HVISER\t\t\t##\tReturnerer gennemsnittet (den aritmetiske middelværdi) af alle de celler, der opfylder flere kriterier.\r\nBETADIST\t\t= BETAFORDELING\t\t\t##\tReturnerer den kumulative betafordelingsfunktion\r\nBETAINV\t\t\t= BETAINV\t\t\t##\tReturnerer den inverse kumulative fordelingsfunktion for en angivet betafordeling\r\nBINOMDIST\t\t= BINOMIALFORDELING\t\t##\tReturnerer punktsandsynligheden for binomialfordelingen\r\nCHIDIST\t\t\t= CHIFORDELING\t\t\t##\tReturnerer fraktilsandsynligheden for en chi2-fordeling\r\nCHIINV\t\t\t= CHIINV\t\t\t##\tReturnerer den inverse fraktilsandsynlighed for en chi2-fordeling\r\nCHITEST\t\t\t= CHITEST\t\t\t##\tForetager en test for uafhængighed\r\nCONFIDENCE\t\t= KONFIDENSINTERVAL\t\t##\tReturnerer et konfidensinterval for en population\r\nCORREL\t\t\t= KORRELATION\t\t\t##\tReturnerer korrelationskoefficienten mellem to datasæt\r\nCOUNT\t\t\t= TÆL\t\t\t\t##\tTæller antallet af tal på en liste med argumenter\r\nCOUNTA\t\t\t= TÆLV\t\t\t\t##\tTæller antallet af værdier på en liste med argumenter\r\nCOUNTBLANK\t\t= ANTAL.BLANKE\t\t\t##\tTæller antallet af tomme celler i et område\r\nCOUNTIF\t\t\t= TÆLHVIS\t\t\t##\tTæller antallet af celler, som opfylder de givne kriterier, i et område\r\nCOUNTIFS\t\t= TÆL.HVISER\t\t\t##\tTæller antallet af de celler, som opfylder flere kriterier, i et område\r\nCOVAR\t\t\t= KOVARIANS\t\t\t##\tBeregner kovariansen mellem to stokastiske variabler\r\nCRITBINOM\t\t= KRITBINOM\t\t\t##\tReturnerer den mindste værdi for x, for hvilken det gælder, at fordelingsfunktionen er mindre end eller lig med kriterieværdien.\r\nDEVSQ\t\t\t= SAK\t\t\t\t##\tReturnerer summen af de kvadrerede afvigelser fra middelværdien\r\nEXPONDIST\t\t= EKSPFORDELING\t\t\t##\tReturnerer eksponentialfordelingen\r\nFDIST\t\t\t= FFORDELING\t\t\t##\tReturnerer fraktilsandsynligheden for F-fordelingen\r\nFINV\t\t\t= FINV\t\t\t\t##\tReturnerer den inverse fraktilsandsynlighed for F-fordelingen\r\nFISHER\t\t\t= FISHER\t\t\t##\tReturnerer Fisher-transformationen\r\nFISHERINV\t\t= FISHERINV\t\t\t##\tReturnerer den inverse Fisher-transformation\r\nFORECAST\t\t= PROGNOSE\t\t\t##\tReturnerer en prognoseværdi baseret på lineær tendens\r\nFREQUENCY\t\t= FREKVENS\t\t\t##\tReturnerer en frekvensfordeling i en søjlevektor\r\nFTEST\t\t\t= FTEST\t\t\t\t##\tReturnerer resultatet af en F-test til sammenligning af varians\r\nGAMMADIST\t\t= GAMMAFORDELING\t\t##\tReturnerer fordelingsfunktionen for gammafordelingen\r\nGAMMAINV\t\t= GAMMAINV\t\t\t##\tReturnerer den inverse fordelingsfunktion for gammafordelingen\r\nGAMMALN\t\t\t= GAMMALN\t\t\t##\tReturnerer den naturlige logaritme til gammafordelingen, G(x)\r\nGEOMEAN\t\t\t= GEOMIDDELVÆRDI\t\t##\tReturnerer det geometriske gennemsnit\r\nGROWTH\t\t\t= FORØGELSE\t\t\t##\tReturnerer værdier langs en eksponentiel tendens\r\nHARMEAN\t\t\t= HARMIDDELVÆRDI\t\t##\tReturnerer det harmoniske gennemsnit\r\nHYPGEOMDIST\t\t= HYPGEOFORDELING\t\t##\tReturnerer punktsandsynligheden i en hypergeometrisk fordeling\r\nINTERCEPT\t\t= SKÆRING\t\t\t##\tReturnerer afskæringsværdien på y-aksen i en lineær regression\r\nKURT\t\t\t= TOPSTEJL\t\t\t##\tReturnerer kurtosisværdien for en stokastisk variabel\r\nLARGE\t\t\t= STOR\t\t\t\t##\tReturnerer den k'te største værdi i et datasæt\r\nLINEST\t\t\t= LINREGR\t\t\t##\tReturnerer parameterestimaterne for en lineær tendens\r\nLOGEST\t\t\t= LOGREGR\t\t\t##\tReturnerer parameterestimaterne for en eksponentiel tendens\r\nLOGINV\t\t\t= LOGINV\t\t\t##\tReturnerer den inverse fordelingsfunktion for lognormalfordelingen\r\nLOGNORMDIST\t\t= LOGNORMFORDELING\t\t##\tReturnerer fordelingsfunktionen for lognormalfordelingen\r\nMAX\t\t\t= MAKS\t\t\t\t##\tReturnerer den maksimale værdi på en liste med argumenter.\r\nMAXA\t\t\t= MAKSV\t\t\t\t##\tReturnerer den maksimale værdi på en liste med argumenter og medtager tal, tekst og logiske værdier\r\nMEDIAN\t\t\t= MEDIAN\t\t\t##\tReturnerer medianen for de angivne tal\r\nMIN\t\t\t= MIN\t\t\t\t##\tReturnerer den mindste værdi på en liste med argumenter.\r\nMINA\t\t\t= MINV\t\t\t\t##\tReturnerer den mindste værdi på en liste med argumenter og medtager tal, tekst og logiske værdier\r\nMODE\t\t\t= HYPPIGST\t\t\t##\tReturnerer den hyppigste værdi i et datasæt\r\nNEGBINOMDIST\t\t= NEGBINOMFORDELING\t\t##\tReturnerer den negative binomialfordeling\r\nNORMDIST\t\t= NORMFORDELING\t\t\t##\tReturnerer fordelingsfunktionen for normalfordelingen\r\nNORMINV\t\t\t= NORMINV\t\t\t##\tReturnerer den inverse fordelingsfunktion for normalfordelingen\r\nNORMSDIST\t\t= STANDARDNORMFORDELING\t\t##\tReturnerer fordelingsfunktionen for standardnormalfordelingen\r\nNORMSINV\t\t= STANDARDNORMINV\t\t##\tReturnerer den inverse fordelingsfunktion for standardnormalfordelingen\r\nPEARSON\t\t\t= PEARSON\t\t\t##\tReturnerer Pearsons korrelationskoefficient\r\nPERCENTILE\t\t= FRAKTIL\t\t\t##\tReturnerer den k'te fraktil for datasættet\r\nPERCENTRANK\t\t= PROCENTPLADS\t\t\t##\tReturnerer den procentuelle rang for en given værdi i et datasæt\r\nPERMUT\t\t\t= PERMUT\t\t\t##\tReturnerer antallet af permutationer for et givet sæt objekter\r\nPOISSON\t\t\t= POISSON\t\t\t##\tReturnerer fordelingsfunktionen for en Poisson-fordeling\r\nPROB\t\t\t= SANDSYNLIGHED\t\t\t##\tReturnerer intervalsandsynligheden\r\nQUARTILE\t\t= KVARTIL\t\t\t##\tReturnerer kvartilen i et givet datasæt\r\nRANK\t\t\t= PLADS\t\t\t\t##\tReturnerer rangen for et tal på en liste med tal\r\nRSQ\t\t\t= FORKLARINGSGRAD\t\t##\tReturnerer R2-værdien fra en simpel lineær regression\r\nSKEW\t\t\t= SKÆVHED\t\t\t##\tReturnerer skævheden for en stokastisk variabel\r\nSLOPE\t\t\t= HÆLDNING\t\t\t##\tReturnerer estimatet på hældningen fra en simpel lineær regression\r\nSMALL\t\t\t= MINDSTE\t\t\t##\tReturnerer den k'te mindste værdi i datasættet\r\nSTANDARDIZE\t\t= STANDARDISER\t\t\t##\tReturnerer en standardiseret værdi\r\nSTDEV\t\t\t= STDAFV\t\t\t##\tEstimerer standardafvigelsen på basis af en stikprøve\r\nSTDEVA\t\t\t= STDAFVV\t\t\t##\tBeregner standardafvigelsen på basis af en prøve og medtager tal, tekst og logiske værdier\r\nSTDEVP\t\t\t= STDAFVP\t\t\t##\tBeregner standardafvigelsen på basis af en hel population\r\nSTDEVPA\t\t\t= STDAFVPV\t\t\t##\tBeregner standardafvigelsen på basis af en hel population og medtager tal, tekst og logiske værdier\r\nSTEYX\t\t\t= STFYX\t\t\t\t##\tReturnerer standardafvigelsen for de estimerede y-værdier i den simple lineære regression\r\nTDIST\t\t\t= TFORDELING\t\t\t##\tReturnerer fordelingsfunktionen for Student's t-fordeling\r\nTINV\t\t\t= TINV\t\t\t\t##\tReturnerer den inverse fordelingsfunktion for Student's t-fordeling\r\nTREND\t\t\t= TENDENS\t\t\t##\tReturnerer værdi under antagelse af en lineær tendens\r\nTRIMMEAN\t\t= TRIMMIDDELVÆRDI\t\t##\tReturnerer den trimmede middelværdi for datasættet\r\nTTEST\t\t\t= TTEST\t\t\t\t##\tReturnerer den sandsynlighed, der er forbundet med Student's t-test\r\nVAR\t\t\t= VARIANS\t\t\t##\tBeregner variansen på basis af en prøve\r\nVARA\t\t\t= VARIANSV\t\t\t##\tBeregner variansen på basis af en prøve og medtager tal, tekst og logiske værdier\r\nVARP\t\t\t= VARIANSP\t\t\t##\tBeregner variansen på basis af hele populationen\r\nVARPA\t\t\t= VARIANSPV\t\t\t##\tBeregner variansen på basis af hele populationen og medtager tal, tekst og logiske værdier\r\nWEIBULL\t\t\t= WEIBULL\t\t\t##\tReturnerer fordelingsfunktionen for Weibull-fordelingen\r\nZTEST\t\t\t= ZTEST\t\t\t\t##\tReturnerer sandsynlighedsværdien ved en en-sidet z-test\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\tTekstfunktioner\r\n##\r\nASC\t\t\t= ASC\t\t\t\t##\tÆndrer engelske tegn i fuld bredde (dobbelt-byte) eller katakana i en tegnstreng til tegn i halv bredde (enkelt-byte)\r\nBAHTTEXT\t\t= BAHTTEKST\t\t\t##\tKonverterer et tal til tekst ved hjælp af valutaformatet ß (baht)\r\nCHAR\t\t\t= TEGN\t\t\t\t##\tReturnerer det tegn, der svarer til kodenummeret\r\nCLEAN\t\t\t= RENS\t\t\t\t##\tFjerner alle tegn, der ikke kan udskrives, fra tekst\r\nCODE\t\t\t= KODE\t\t\t\t##\tReturnerer en numerisk kode for det første tegn i en tekststreng\r\nCONCATENATE\t\t= SAMMENKÆDNING\t\t\t##\tSammenkæder adskillige tekstelementer til ét tekstelement\r\nDOLLAR\t\t\t= KR\t\t\t\t##\tKonverterer et tal til tekst ved hjælp af valutaformatet kr. (kroner)\r\nEXACT\t\t\t= EKSAKT\t\t\t##\tKontrollerer, om to tekstværdier er identiske\r\nFIND\t\t\t= FIND\t\t\t\t##\tSøger efter en tekstværdi i en anden tekstværdi (der skelnes mellem store og små bogstaver)\r\nFINDB\t\t\t= FINDB\t\t\t\t##\tSøger efter en tekstværdi i en anden tekstværdi (der skelnes mellem store og små bogstaver)\r\nFIXED\t\t\t= FAST\t\t\t\t##\tFormaterer et tal som tekst med et fast antal decimaler\r\nJIS\t\t\t= JIS\t\t\t\t##\tÆndrer engelske tegn i halv bredde (enkelt-byte) eller katakana i en tegnstreng til tegn i fuld bredde (dobbelt-byte)\r\nLEFT\t\t\t= VENSTRE\t\t\t##\tReturnerer tegnet længst til venstre i en tekstværdi\r\nLEFTB\t\t\t= VENSTREB\t\t\t##\tReturnerer tegnet længst til venstre i en tekstværdi\r\nLEN\t\t\t= LÆNGDE\t\t\t##\tReturnerer antallet af tegn i en tekststreng\r\nLENB\t\t\t= LÆNGDEB\t\t\t##\tReturnerer antallet af tegn i en tekststreng\r\nLOWER\t\t\t= SMÅ.BOGSTAVER\t\t\t##\tKonverterer tekst til små bogstaver\r\nMID\t\t\t= MIDT\t\t\t\t##\tReturnerer et bestemt antal tegn fra en tekststreng fra og med den angivne startposition\r\nMIDB\t\t\t= MIDTB\t\t\t\t##\tReturnerer et bestemt antal tegn fra en tekststreng fra og med den angivne startposition\r\nPHONETIC\t\t= FONETISK\t\t\t##\tUddrager de fonetiske (furigana) tegn fra en tekststreng\r\nPROPER\t\t\t= STORT.FORBOGSTAV\t\t##\tKonverterer første bogstav i hvert ord i teksten til stort bogstav\r\nREPLACE\t\t\t= ERSTAT\t\t\t##\tErstatter tegn i tekst\r\nREPLACEB\t\t= ERSTATB\t\t\t##\tErstatter tegn i tekst\r\nREPT\t\t\t= GENTAG\t\t\t##\tGentager tekst et givet antal gange\r\nRIGHT\t\t\t= HØJRE\t\t\t\t##\tReturnerer tegnet længste til højre i en tekstværdi\r\nRIGHTB\t\t\t= HØJREB\t\t\t##\tReturnerer tegnet længste til højre i en tekstværdi\r\nSEARCH\t\t\t= SØG\t\t\t\t##\tSøger efter en tekstværdi i en anden tekstværdi (der skelnes ikke mellem store og små bogstaver)\r\nSEARCHB\t\t\t= SØGB\t\t\t\t##\tSøger efter en tekstværdi i en anden tekstværdi (der skelnes ikke mellem store og små bogstaver)\r\nSUBSTITUTE\t\t= UDSKIFT\t\t\t##\tUdskifter gammel tekst med ny tekst i en tekststreng\r\nT\t\t\t= T\t\t\t\t##\tKonverterer argumenterne til tekst\r\nTEXT\t\t\t= TEKST\t\t\t\t##\tFormaterer et tal og konverterer det til tekst\r\nTRIM\t\t\t= FJERN.OVERFLØDIGE.BLANKE\t##\tFjerner mellemrum fra tekst\r\nUPPER\t\t\t= STORE.BOGSTAVER\t\t##\tKonverterer tekst til store bogstaver\r\nVALUE\t\t\t= VÆRDI\t\t\t\t##\tKonverterer et tekstargument til et tal\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/de/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= €\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #NULL!\r\nDIV0\t= #DIV/0!\r\nVALUE\t= #WERT!\r\nREF\t= #BEZUG!\r\nNAME\t= #NAME?\r\nNUM\t= #ZAHL!\r\nNA\t= #NV\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/de/functions",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Calculation\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/\r\n##\r\n##\r\n\r\n\r\n##\r\n##\tAdd-in and Automation functions\t\t\tAdd-In- und Automatisierungsfunktionen\r\n##\r\nGETPIVOTDATA\t= PIVOTDATENZUORDNEN\t\t\t##\tIn einem PivotTable-Bericht gespeicherte Daten werden zurückgegeben.\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\tCubefunktionen\r\n##\r\nCUBEKPIMEMBER\t\t= CUBEKPIELEMENT\t\t##\tGibt Name, Eigenschaft und Measure eines Key Performance Indicators (KPI) zurück und zeigt den Namen und die Eigenschaft in der Zelle an. Ein KPI ist ein quantifizierbares Maß, wie z. B. der monatliche Bruttogewinn oder die vierteljährliche Mitarbeiterfluktuation, mit dessen Hilfe das Leistungsverhalten eines Unternehmens überwacht werden kann.\r\nCUBEMEMBER\t\t= CUBEELEMENT\t\t\t##\tGibt ein Element oder ein Tuple in einer Cubehierarchie zurück. Wird verwendet, um zu überprüfen, ob das Element oder Tuple im Cube vorhanden ist.\r\nCUBEMEMBERPROPERTY\t= CUBEELEMENTEIGENSCHAFT\t##\tGibt den Wert einer Elementeigenschaft im Cube zurück. Wird verwendet, um zu überprüfen, ob ein Elementname im Cube vorhanden ist, und um die für dieses Element angegebene Eigenschaft zurückzugeben.\r\nCUBERANKEDMEMBER\t= CUBERANGELEMENT\t\t##\tGibt das n-te oder n-rangige Element in einer Menge zurück. Wird verwendet, um mindestens ein Element in einer Menge zurückzugeben, wie z. B. bester Vertriebsmitarbeiter oder 10 beste Kursteilnehmer.\r\nCUBESET\t\t\t= CUBEMENGE\t\t\t##\tDefiniert eine berechnete Menge Elemente oder Tuples durch Senden eines Mengenausdrucks an den Cube auf dem Server, der die Menge erstellt und an Microsoft Office Excel zurückgibt.\r\nCUBESETCOUNT\t\t= CUBEMENGENANZAHL\t\t##\tGibt die Anzahl der Elemente in einer Menge zurück.\r\nCUBEVALUE\t\t= CUBEWERT\t\t\t##\tGibt einen Aggregatwert aus einem Cube zurück.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\tDatenbankfunktionen\r\n##\r\nDAVERAGE\t\t= DBMITTELWERT\t\t\t##\tGibt den Mittelwert der ausgewählten Datenbankeinträge zurück\r\nDCOUNT\t\t\t= DBANZAHL\t\t\t##\tZählt die Zellen mit Zahlen in einer Datenbank\r\nDCOUNTA\t\t\t= DBANZAHL2\t\t\t##\tZählt nicht leere Zellen in einer Datenbank\r\nDGET\t\t\t= DBAUSZUG\t\t\t##\tExtrahiert aus einer Datenbank einen einzelnen Datensatz, der den angegebenen Kriterien entspricht\r\nDMAX\t\t\t= DBMAX\t\t\t\t##\tGibt den größten Wert aus ausgewählten Datenbankeinträgen zurück\r\nDMIN\t\t\t= DBMIN\t\t\t\t##\tGibt den kleinsten Wert aus ausgewählten Datenbankeinträgen zurück\r\nDPRODUCT\t\t= DBPRODUKT\t\t\t##\tMultipliziert die Werte in einem bestimmten Feld mit Datensätzen, die den Kriterien in einer Datenbank entsprechen\r\nDSTDEV\t\t\t= DBSTDABW\t\t\t##\tSchätzt die Standardabweichung auf der Grundlage einer Stichprobe aus ausgewählten Datenbankeinträgen\r\nDSTDEVP\t\t\t= DBSTDABWN\t\t\t##\tBerechnet die Standardabweichung auf der Grundlage der Grundgesamtheit ausgewählter Datenbankeinträge\r\nDSUM\t\t\t= DBSUMME\t\t\t##\tAddiert die Zahlen in der Feldspalte mit Datensätzen in der Datenbank, die den Kriterien entsprechen\r\nDVAR\t\t\t= DBVARIANZ\t\t\t##\tSchätzt die Varianz auf der Grundlage ausgewählter Datenbankeinträge\r\nDVARP\t\t\t= DBVARIANZEN\t\t\t##\tBerechnet die Varianz auf der Grundlage der Grundgesamtheit ausgewählter Datenbankeinträge\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\tDatums- und Zeitfunktionen\r\n##\r\nDATE\t\t\t= DATUM\t\t\t\t##\tGibt die fortlaufende Zahl eines bestimmten Datums zurück\r\nDATEVALUE\t\t= DATWERT\t\t\t##\tWandelt ein Datum in Form von Text in eine fortlaufende Zahl um\r\nDAY\t\t\t= TAG\t\t\t\t##\tWandelt eine fortlaufende Zahl in den Tag des Monats um\r\nDAYS360\t\t\t= TAGE360\t\t\t##\tBerechnet die Anzahl der Tage zwischen zwei Datumsangaben ausgehend von einem Jahr, das 360 Tage hat\r\nEDATE\t\t\t= EDATUM\t\t\t##\tGibt die fortlaufende Zahl des Datums zurück, bei dem es sich um die angegebene Anzahl von Monaten vor oder nach dem Anfangstermin handelt\r\nEOMONTH\t\t\t= MONATSENDE\t\t\t##\tGibt die fortlaufende Zahl des letzten Tags des Monats vor oder nach einer festgelegten Anzahl von Monaten zurück\r\nHOUR\t\t\t= STUNDE\t\t\t##\tWandelt eine fortlaufende Zahl in eine Stunde um\r\nMINUTE\t\t\t= MINUTE\t\t\t##\tWandelt eine fortlaufende Zahl in eine Minute um\r\nMONTH\t\t\t= MONAT\t\t\t\t##\tWandelt eine fortlaufende Zahl in einen Monat um\r\nNETWORKDAYS\t\t= NETTOARBEITSTAGE\t\t##\tGibt die Anzahl von ganzen Arbeitstagen zwischen zwei Datumswerten zurück\r\nNOW\t\t\t= JETZT\t\t\t\t##\tGibt die fortlaufende Zahl des aktuellen Datums und der aktuellen Uhrzeit zurück\r\nSECOND\t\t\t= SEKUNDE\t\t\t##\tWandelt eine fortlaufende Zahl in eine Sekunde um\r\nTIME\t\t\t= ZEIT\t\t\t\t##\tGibt die fortlaufende Zahl einer bestimmten Uhrzeit zurück\r\nTIMEVALUE\t\t= ZEITWERT\t\t\t##\tWandelt eine Uhrzeit in Form von Text in eine fortlaufende Zahl um\r\nTODAY\t\t\t= HEUTE\t\t\t\t##\tGibt die fortlaufende Zahl des heutigen Datums zurück\r\nWEEKDAY\t\t\t= WOCHENTAG\t\t\t##\tWandelt eine fortlaufende Zahl in den Wochentag um\r\nWEEKNUM\t\t\t= KALENDERWOCHE\t\t\t##\tWandelt eine fortlaufende Zahl in eine Zahl um, die angibt, in welche Woche eines Jahres das angegebene Datum fällt\r\nWORKDAY\t\t\t= ARBEITSTAG\t\t\t##\tGibt die fortlaufende Zahl des Datums vor oder nach einer bestimmten Anzahl von Arbeitstagen zurück\r\nYEAR\t\t\t= JAHR\t\t\t\t##\tWandelt eine fortlaufende Zahl in ein Jahr um\r\nYEARFRAC\t\t= BRTEILJAHRE\t\t\t##\tGibt die Anzahl der ganzen Tage zwischen Ausgangsdatum und Enddatum in Bruchteilen von Jahren zurück\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\tKonstruktionsfunktionen\r\n##\r\nBESSELI\t\t\t= BESSELI\t\t\t##\tGibt die geänderte Besselfunktion In(x) zurück\r\nBESSELJ\t\t\t= BESSELJ\t\t\t##\tGibt die Besselfunktion Jn(x) zurück\r\nBESSELK\t\t\t= BESSELK\t\t\t##\tGibt die geänderte Besselfunktion Kn(x) zurück\r\nBESSELY\t\t\t= BESSELY\t\t\t##\tGibt die Besselfunktion Yn(x) zurück\r\nBIN2DEC\t\t\t= BININDEZ\t\t\t##\tWandelt eine binäre Zahl (Dualzahl) in eine dezimale Zahl um\r\nBIN2HEX\t\t\t= BININHEX\t\t\t##\tWandelt eine binäre Zahl (Dualzahl) in eine hexadezimale Zahl um\r\nBIN2OCT\t\t\t= BININOKT\t\t\t##\tWandelt eine binäre Zahl (Dualzahl) in eine oktale Zahl um\r\nCOMPLEX\t\t\t= KOMPLEXE\t\t\t##\tWandelt den Real- und Imaginärteil in eine komplexe Zahl um\r\nCONVERT\t\t\t= UMWANDELN\t\t\t##\tWandelt eine Zahl von einem Maßsystem in ein anderes um\r\nDEC2BIN\t\t\t= DEZINBIN\t\t\t##\tWandelt eine dezimale Zahl in eine binäre Zahl (Dualzahl) um\r\nDEC2HEX\t\t\t= DEZINHEX\t\t\t##\tWandelt eine dezimale Zahl in eine hexadezimale Zahl um\r\nDEC2OCT\t\t\t= DEZINOKT\t\t\t##\tWandelt eine dezimale Zahl in eine oktale Zahl um\r\nDELTA\t\t\t= DELTA\t\t\t\t##\tÜberprüft, ob zwei Werte gleich sind\r\nERF\t\t\t= GAUSSFEHLER\t\t\t##\tGibt die Gauss'sche Fehlerfunktion zurück\r\nERFC\t\t\t= GAUSSFKOMPL\t\t\t##\tGibt das Komplement zur Gauss'schen Fehlerfunktion zurück\r\nGESTEP\t\t\t= GGANZZAHL\t\t\t##\tÜberprüft, ob eine Zahl größer als ein gegebener Schwellenwert ist\r\nHEX2BIN\t\t\t= HEXINBIN\t\t\t##\tWandelt eine hexadezimale Zahl in eine Binärzahl um\r\nHEX2DEC\t\t\t= HEXINDEZ\t\t\t##\tWandelt eine hexadezimale Zahl in eine dezimale Zahl um\r\nHEX2OCT\t\t\t= HEXINOKT\t\t\t##\tWandelt eine hexadezimale Zahl in eine Oktalzahl um\r\nIMABS\t\t\t= IMABS\t\t\t\t##\tGibt den Absolutbetrag (Modulo) einer komplexen Zahl zurück\r\nIMAGINARY\t\t= IMAGINÄRTEIL\t\t\t##\tGibt den Imaginärteil einer komplexen Zahl zurück\r\nIMARGUMENT\t\t= IMARGUMENT\t\t\t##\tGibt das Argument Theta zurück, einen Winkel, der als Bogenmaß ausgedrückt wird\r\nIMCONJUGATE\t\t= IMKONJUGIERTE\t\t\t##\tGibt die konjugierte komplexe Zahl zu einer komplexen Zahl zurück\r\nIMCOS\t\t\t= IMCOS\t\t\t\t##\tGibt den Kosinus einer komplexen Zahl zurück\r\nIMDIV\t\t\t= IMDIV\t\t\t\t##\tGibt den Quotienten zweier komplexer Zahlen zurück\r\nIMEXP\t\t\t= IMEXP\t\t\t\t##\tGibt die algebraische Form einer in exponentieller Schreibweise vorliegenden komplexen Zahl zurück\r\nIMLN\t\t\t= IMLN\t\t\t\t##\tGibt den natürlichen Logarithmus einer komplexen Zahl zurück\r\nIMLOG10\t\t\t= IMLOG10\t\t\t##\tGibt den Logarithmus einer komplexen Zahl zur Basis 10 zurück\r\nIMLOG2\t\t\t= IMLOG2\t\t\t##\tGibt den Logarithmus einer komplexen Zahl zur Basis 2 zurück\r\nIMPOWER\t\t\t= IMAPOTENZ\t\t\t##\tPotenziert eine komplexe Zahl mit einer ganzen Zahl\r\nIMPRODUCT\t\t= IMPRODUKT\t\t\t##\tGibt das Produkt von komplexen Zahlen zurück\r\nIMREAL\t\t\t= IMREALTEIL\t\t\t##\tGibt den Realteil einer komplexen Zahl zurück\r\nIMSIN\t\t\t= IMSIN\t\t\t\t##\tGibt den Sinus einer komplexen Zahl zurück\r\nIMSQRT\t\t\t= IMWURZEL\t\t\t##\tGibt die Quadratwurzel einer komplexen Zahl zurück\r\nIMSUB\t\t\t= IMSUB\t\t\t\t##\tGibt die Differenz zwischen zwei komplexen Zahlen zurück\r\nIMSUM\t\t\t= IMSUMME\t\t\t##\tGibt die Summe von komplexen Zahlen zurück\r\nOCT2BIN\t\t\t= OKTINBIN\t\t\t##\tWandelt eine oktale Zahl in eine binäre Zahl (Dualzahl) um\r\nOCT2DEC\t\t\t= OKTINDEZ\t\t\t##\tWandelt eine oktale Zahl in eine dezimale Zahl um\r\nOCT2HEX\t\t\t= OKTINHEX\t\t\t##\tWandelt eine oktale Zahl in eine hexadezimale Zahl um\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\tFinanzmathematische Funktionen\r\n##\r\nACCRINT\t\t\t= AUFGELZINS\t\t\t##\tGibt die aufgelaufenen Zinsen (Stückzinsen) eines Wertpapiers mit periodischen Zinszahlungen zurück\r\nACCRINTM\t\t= AUFGELZINSF\t\t\t##\tGibt die aufgelaufenen Zinsen (Stückzinsen) eines Wertpapiers zurück, die bei Fälligkeit ausgezahlt werden\r\nAMORDEGRC\t\t= AMORDEGRK\t\t\t##\tGibt die Abschreibung für die einzelnen Abschreibungszeiträume mithilfe eines Abschreibungskoeffizienten zurück\r\nAMORLINC\t\t= AMORLINEARK\t\t\t##\tGibt die Abschreibung für die einzelnen Abschreibungszeiträume zurück\r\nCOUPDAYBS\t\t= ZINSTERMTAGVA\t\t\t##\tGibt die Anzahl der Tage vom Anfang des Zinstermins bis zum Abrechnungstermin zurück\r\nCOUPDAYS\t\t= ZINSTERMTAGE\t\t\t##\tGibt die Anzahl der Tage der Zinsperiode zurück, die den Abrechnungstermin einschließt\r\nCOUPDAYSNC\t\t= ZINSTERMTAGNZ\t\t\t##\tGibt die Anzahl der Tage vom Abrechnungstermin bis zum nächsten Zinstermin zurück\r\nCOUPNCD\t\t\t= ZINSTERMNZ\t\t\t##\tGibt das Datum des ersten Zinstermins nach dem Abrechnungstermin zurück\r\nCOUPNUM\t\t\t= ZINSTERMZAHL\t\t\t##\tGibt die Anzahl der Zinstermine zwischen Abrechnungs- und Fälligkeitsdatum zurück\r\nCOUPPCD\t\t\t= ZINSTERMVZ\t\t\t##\tGibt das Datum des letzten Zinstermins vor dem Abrechnungstermin zurück\r\nCUMIPMT\t\t\t= KUMZINSZ\t\t\t##\tBerechnet die kumulierten Zinsen, die zwischen zwei Perioden zu zahlen sind\r\nCUMPRINC\t\t= KUMKAPITAL\t\t\t##\tBerechnet die aufgelaufene Tilgung eines Darlehens, die zwischen zwei Perioden zu zahlen ist\r\nDB\t\t\t= GDA2\t\t\t\t##\tGibt die geometrisch-degressive Abschreibung eines Wirtschaftsguts für eine bestimmte Periode zurück\r\nDDB\t\t\t= GDA\t\t\t\t##\tGibt die Abschreibung eines Anlageguts für einen angegebenen Zeitraum unter Verwendung der degressiven Doppelraten-Abschreibung oder eines anderen von Ihnen angegebenen Abschreibungsverfahrens zurück\r\nDISC\t\t\t= DISAGIO\t\t\t##\tGibt den in Prozent ausgedrückten Abzinsungssatz eines Wertpapiers zurück\r\nDOLLARDE\t\t= NOTIERUNGDEZ\t\t\t##\tWandelt eine Notierung, die als Dezimalbruch ausgedrückt wurde, in eine Dezimalzahl um\r\nDOLLARFR\t\t= NOTIERUNGBRU\t\t\t##\tWandelt eine Notierung, die als Dezimalzahl ausgedrückt wurde, in einen Dezimalbruch um\r\nDURATION\t\t= DURATION\t\t\t##\tGibt die jährliche Duration eines Wertpapiers mit periodischen Zinszahlungen zurück\r\nEFFECT\t\t\t= EFFEKTIV\t\t\t##\tGibt die jährliche Effektivverzinsung zurück\r\nFV\t\t\t= ZW\t\t\t\t##\tGibt den zukünftigen Wert (Endwert) einer Investition zurück\r\nFVSCHEDULE\t\t= ZW2\t\t\t\t##\tGibt den aufgezinsten Wert des Anfangskapitals für eine Reihe periodisch unterschiedlicher Zinssätze zurück\r\nINTRATE\t\t\t= ZINSSATZ\t\t\t##\tGibt den Zinssatz eines voll investierten Wertpapiers zurück\r\nIPMT\t\t\t= ZINSZ\t\t\t\t##\tGibt die Zinszahlung einer Investition für die angegebene Periode zurück\r\nIRR\t\t\t= IKV\t\t\t\t##\tGibt den internen Zinsfuß einer Investition ohne Finanzierungskosten oder Reinvestitionsgewinne zurück\r\nISPMT\t\t\t= ISPMT\t\t\t\t##\tBerechnet die während eines bestimmten Zeitraums für eine Investition gezahlten Zinsen\r\nMDURATION\t\t= MDURATION\t\t\t##\tGibt die geänderte Dauer für ein Wertpapier mit einem angenommenen Nennwert von 100 € zurück\r\nMIRR\t\t\t= QIKV\t\t\t\t##\tGibt den internen Zinsfuß zurück, wobei positive und negative Zahlungen zu unterschiedlichen Sätzen finanziert werden\r\nNOMINAL\t\t\t= NOMINAL\t\t\t##\tGibt die jährliche Nominalverzinsung zurück\r\nNPER\t\t\t= ZZR\t\t\t\t##\tGibt die Anzahl der Zahlungsperioden einer Investition zurück\r\nNPV\t\t\t= NBW\t\t\t\t##\tGibt den Nettobarwert einer Investition auf Basis periodisch anfallender Zahlungen und eines Abzinsungsfaktors zurück\r\nODDFPRICE\t\t= UNREGER.KURS\t\t\t##\tGibt den Kurs pro 100 € Nennwert eines Wertpapiers mit einem unregelmäßigen ersten Zinstermin zurück\r\nODDFYIELD\t\t= UNREGER.REND\t\t\t##\tGibt die Rendite eines Wertpapiers mit einem unregelmäßigen ersten Zinstermin zurück\r\nODDLPRICE\t\t= UNREGLE.KURS\t\t\t##\tGibt den Kurs pro 100 € Nennwert eines Wertpapiers mit einem unregelmäßigen letzten Zinstermin zurück\r\nODDLYIELD\t\t= UNREGLE.REND\t\t\t##\tGibt die Rendite eines Wertpapiers mit einem unregelmäßigen letzten Zinstermin zurück\r\nPMT\t\t\t= RMZ\t\t\t\t##\tGibt die periodische Zahlung für eine Annuität zurück\r\nPPMT\t\t\t= KAPZ\t\t\t\t##\tGibt die Kapitalrückzahlung einer Investition für eine angegebene Periode zurück\r\nPRICE\t\t\t= KURS\t\t\t\t##\tGibt den Kurs pro 100 € Nennwert eines Wertpapiers zurück, das periodisch Zinsen auszahlt\r\nPRICEDISC\t\t= KURSDISAGIO\t\t\t##\tGibt den Kurs pro 100 € Nennwert eines unverzinslichen Wertpapiers zurück\r\nPRICEMAT\t\t= KURSFÄLLIG\t\t\t##\tGibt den Kurs pro 100 € Nennwert eines Wertpapiers zurück, das Zinsen am Fälligkeitsdatum auszahlt\r\nPV\t\t\t= BW\t\t\t\t##\tGibt den Barwert einer Investition zurück\r\nRATE\t\t\t= ZINS\t\t\t\t##\tGibt den Zinssatz pro Zeitraum einer Annuität zurück\r\nRECEIVED\t\t= AUSZAHLUNG\t\t\t##\tGibt den Auszahlungsbetrag eines voll investierten Wertpapiers am Fälligkeitstermin zurück\r\nSLN\t\t\t= LIA\t\t\t\t##\tGibt die lineare Abschreibung eines Wirtschaftsguts pro Periode zurück\r\nSYD\t\t\t= DIA\t\t\t\t##\tGibt die arithmetisch-degressive Abschreibung eines Wirtschaftsguts für eine bestimmte Periode zurück\r\nTBILLEQ\t\t\t= TBILLÄQUIV\t\t\t##\tGibt die Rendite für ein Wertpapier zurück\r\nTBILLPRICE\t\t= TBILLKURS\t\t\t##\tGibt den Kurs pro 100 € Nennwert eines Wertpapiers zurück\r\nTBILLYIELD\t\t= TBILLRENDITE\t\t\t##\tGibt die Rendite für ein Wertpapier zurück\r\nVDB\t\t\t= VDB\t\t\t\t##\tGibt die degressive Abschreibung eines Wirtschaftsguts für eine bestimmte Periode oder Teilperiode zurück\r\nXIRR\t\t\t= XINTZINSFUSS\t\t\t##\tGibt den internen Zinsfuß einer Reihe nicht periodisch anfallender Zahlungen zurück\r\nXNPV\t\t\t= XKAPITALWERT\t\t\t##\tGibt den Nettobarwert (Kapitalwert) einer Reihe nicht periodisch anfallender Zahlungen zurück\r\nYIELD\t\t\t= RENDITE\t\t\t##\tGibt die Rendite eines Wertpapiers zurück, das periodisch Zinsen auszahlt\r\nYIELDDISC\t\t= RENDITEDIS\t\t\t##\tGibt die jährliche Rendite eines unverzinslichen Wertpapiers zurück\r\nYIELDMAT\t\t= RENDITEFÄLL\t\t\t##\tGibt die jährliche Rendite eines Wertpapiers zurück, das Zinsen am Fälligkeitsdatum auszahlt\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\tInformationsfunktionen\r\n##\r\nCELL\t\t\t= ZELLE\t\t\t\t##\tGibt Informationen zu Formatierung, Position oder Inhalt einer Zelle zurück\r\nERROR.TYPE\t\t= FEHLER.TYP\t\t\t##\tGibt eine Zahl zurück, die einem Fehlertyp entspricht\r\nINFO\t\t\t= INFO\t\t\t\t##\tGibt Informationen zur aktuellen Betriebssystemumgebung zurück\r\nISBLANK\t\t\t= ISTLEER\t\t\t##\tGibt WAHR zurück, wenn der Wert leer ist\r\nISERR\t\t\t= ISTFEHL\t\t\t##\tGibt WAHR zurück, wenn der Wert ein beliebiger Fehlerwert außer #N/V ist\r\nISERROR\t\t\t= ISTFEHLER\t\t\t##\tGibt WAHR zurück, wenn der Wert ein beliebiger Fehlerwert ist\r\nISEVEN\t\t\t= ISTGERADE\t\t\t##\tGibt WAHR zurück, wenn es sich um eine gerade Zahl handelt\r\nISLOGICAL\t\t= ISTLOG\t\t\t##\tGibt WAHR zurück, wenn der Wert ein Wahrheitswert ist\r\nISNA\t\t\t= ISTNV\t\t\t\t##\tGibt WAHR zurück, wenn der Wert der Fehlerwert #N/V ist\r\nISNONTEXT\t\t= ISTKTEXT\t\t\t##\tGibt WAHR zurück, wenn der Wert ein Element ist, das keinen Text enthält\r\nISNUMBER\t\t= ISTZAHL\t\t\t##\tGibt WAHR zurück, wenn der Wert eine Zahl ist\r\nISODD\t\t\t= ISTUNGERADE\t\t\t##\tGibt WAHR zurück, wenn es sich um eine ungerade Zahl handelt\r\nISREF\t\t\t= ISTBEZUG\t\t\t##\tGibt WAHR zurück, wenn der Wert ein Bezug ist\r\nISTEXT\t\t\t= ISTTEXT\t\t\t##\tGibt WAHR zurück, wenn der Wert ein Element ist, das Text enthält\r\nN\t\t\t= N\t\t\t\t##\tGibt den in eine Zahl umgewandelten Wert zurück\r\nNA\t\t\t= NV\t\t\t\t##\tGibt den Fehlerwert #NV zurück\r\nTYPE\t\t\t= TYP\t\t\t\t##\tGibt eine Zahl zurück, die den Datentyp des angegebenen Werts anzeigt\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\tLogische Funktionen\r\n##\r\nAND\t\t\t= UND\t\t\t\t##\tGibt WAHR zurück, wenn alle zugehörigen Argumente WAHR sind\r\nFALSE\t\t\t= FALSCH\t\t\t##\tGibt den Wahrheitswert FALSCH zurück\r\nIF\t\t\t= WENN\t\t\t\t##\tGibt einen logischen Test zum Ausführen an\r\nIFERROR\t\t\t= WENNFEHLER\t\t\t##\tGibt einen von Ihnen festgelegten Wert zurück, wenn die Auswertung der Formel zu einem Fehler führt; andernfalls wird das Ergebnis der Formel zurückgegeben\r\nNOT\t\t\t= NICHT\t\t\t\t##\tKehrt den Wahrheitswert der zugehörigen Argumente um\r\nOR\t\t\t= ODER\t\t\t\t##\tGibt WAHR zurück, wenn ein Argument WAHR ist\r\nTRUE\t\t\t= WAHR\t\t\t\t##\tGibt den Wahrheitswert WAHR zurück\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\tNachschlage- und Verweisfunktionen\r\n##\r\nADDRESS\t\t\t= ADRESSE\t\t\t##\tGibt einen Bezug auf eine einzelne Zelle in einem Tabellenblatt als Text zurück\r\nAREAS\t\t\t= BEREICHE\t\t\t##\tGibt die Anzahl der innerhalb eines Bezugs aufgeführten Bereiche zurück\r\nCHOOSE\t\t\t= WAHL\t\t\t\t##\tWählt einen Wert aus eine Liste mit Werten aus\r\nCOLUMN\t\t\t= SPALTE\t\t\t##\tGibt die Spaltennummer eines Bezugs zurück\r\nCOLUMNS\t\t\t= SPALTEN\t\t\t##\tGibt die Anzahl der Spalten in einem Bezug zurück\r\nHLOOKUP\t\t\t= HVERWEIS\t\t\t##\tSucht in der obersten Zeile einer Matrix und gibt den Wert der angegebenen Zelle zurück\r\nHYPERLINK\t\t= HYPERLINK\t\t\t##\tErstellt eine Verknüpfung, über die ein auf einem Netzwerkserver, in einem Intranet oder im Internet gespeichertes Dokument geöffnet wird\r\nINDEX\t\t\t= INDEX\t\t\t\t##\tVerwendet einen Index, um einen Wert aus einem Bezug oder einer Matrix auszuwählen\r\nINDIRECT\t\t= INDIREKT\t\t\t##\tGibt einen Bezug zurück, der von einem Textwert angegeben wird\r\nLOOKUP\t\t\t= LOOKUP\t\t\t##\tSucht Werte in einem Vektor oder einer Matrix\r\nMATCH\t\t\t= VERGLEICH\t\t\t##\tSucht Werte in einem Bezug oder einer Matrix\r\nOFFSET\t\t\t= BEREICH.VERSCHIEBEN\t\t##\tGibt einen Bezugoffset aus einem gegebenen Bezug zurück\r\nROW\t\t\t= ZEILE\t\t\t\t##\tGibt die Zeilennummer eines Bezugs zurück\r\nROWS\t\t\t= ZEILEN\t\t\t##\tGibt die Anzahl der Zeilen in einem Bezug zurück\r\nRTD\t\t\t= RTD\t\t\t\t##\tRuft Echtzeitdaten von einem Programm ab, das die COM-Automatisierung (Automatisierung: Ein Verfahren, bei dem aus einer Anwendung oder einem Entwicklungstool heraus mit den Objekten einer anderen Anwendung gearbeitet wird. Die früher als OLE-Automatisierung bezeichnete Automatisierung ist ein Industriestandard und eine Funktion von COM (Component Object Model).) unterstützt\r\nTRANSPOSE\t\t= MTRANS\t\t\t##\tGibt die transponierte Matrix einer Matrix zurück\r\nVLOOKUP\t\t\t= SVERWEIS\t\t\t##\tSucht in der ersten Spalte einer Matrix und arbeitet sich durch die Zeile, um den Wert einer Zelle zurückzugeben\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\tMathematische und trigonometrische Funktionen\r\n##\r\nABS\t\t\t= ABS\t\t\t\t##\tGibt den Absolutwert einer Zahl zurück\r\nACOS\t\t\t= ARCCOS\t\t\t##\tGibt den Arkuskosinus einer Zahl zurück\r\nACOSH\t\t\t= ARCCOSHYP\t\t\t##\tGibt den umgekehrten hyperbolischen Kosinus einer Zahl zurück\r\nASIN\t\t\t= ARCSIN\t\t\t##\tGibt den Arkussinus einer Zahl zurück\r\nASINH\t\t\t= ARCSINHYP\t\t\t##\tGibt den umgekehrten hyperbolischen Sinus einer Zahl zurück\r\nATAN\t\t\t= ARCTAN\t\t\t##\tGibt den Arkustangens einer Zahl zurück\r\nATAN2\t\t\t= ARCTAN2\t\t\t##\tGibt den Arkustangens einer x- und einer y-Koordinate zurück\r\nATANH\t\t\t= ARCTANHYP\t\t\t##\tGibt den umgekehrten hyperbolischen Tangens einer Zahl zurück\r\nCEILING\t\t\t= OBERGRENZE\t\t\t##\tRundet eine Zahl auf die nächste ganze Zahl oder das nächste Vielfache von Schritt\r\nCOMBIN\t\t\t= KOMBINATIONEN\t\t\t##\tGibt die Anzahl der Kombinationen für eine bestimmte Anzahl von Objekten zurück\r\nCOS\t\t\t= COS\t\t\t\t##\tGibt den Kosinus einer Zahl zurück\r\nCOSH\t\t\t= COSHYP\t\t\t##\tGibt den hyperbolischen Kosinus einer Zahl zurück\r\nDEGREES\t\t\t= GRAD\t\t\t\t##\tWandelt Bogenmaß (Radiant) in Grad um\r\nEVEN\t\t\t= GERADE\t\t\t##\tRundet eine Zahl auf die nächste gerade ganze Zahl auf\r\nEXP\t\t\t= EXP\t\t\t\t##\tPotenziert die Basis e mit der als Argument angegebenen Zahl\r\nFACT\t\t\t= FAKULTÄT\t\t\t##\tGibt die Fakultät einer Zahl zurück\r\nFACTDOUBLE\t\t= ZWEIFAKULTÄT\t\t\t##\tGibt die Fakultät zu Zahl mit Schrittlänge 2 zurück\r\nFLOOR\t\t\t= UNTERGRENZE\t\t\t##\tRundet die Zahl auf Anzahl_Stellen ab\r\nGCD\t\t\t= GGT\t\t\t\t##\tGibt den größten gemeinsamen Teiler zurück\r\nINT\t\t\t= GANZZAHL\t\t\t##\tRundet eine Zahl auf die nächstkleinere ganze Zahl ab\r\nLCM\t\t\t= KGV\t\t\t\t##\tGibt das kleinste gemeinsame Vielfache zurück\r\nLN\t\t\t= LN\t\t\t\t##\tGibt den natürlichen Logarithmus einer Zahl zurück\r\nLOG\t\t\t= LOG\t\t\t\t##\tGibt den Logarithmus einer Zahl zu der angegebenen Basis zurück\r\nLOG10\t\t\t= LOG10\t\t\t\t##\tGibt den Logarithmus einer Zahl zur Basis 10 zurück\r\nMDETERM\t\t\t= MDET\t\t\t\t##\tGibt die Determinante einer Matrix zurück\r\nMINVERSE\t\t= MINV\t\t\t\t##\tGibt die inverse Matrix einer Matrix zurück\r\nMMULT\t\t\t= MMULT\t\t\t\t##\tGibt das Produkt zweier Matrizen zurück\r\nMOD\t\t\t= REST\t\t\t\t##\tGibt den Rest einer Division zurück\r\nMROUND\t\t\t= VRUNDEN\t\t\t##\tGibt eine auf das gewünschte Vielfache gerundete Zahl zurück\r\nMULTINOMIAL\t\t= POLYNOMIAL\t\t\t##\tGibt den Polynomialkoeffizienten einer Gruppe von Zahlen zurück\r\nODD\t\t\t= UNGERADE\t\t\t##\tRundet eine Zahl auf die nächste ungerade ganze Zahl auf\r\nPI\t\t\t= PI\t\t\t\t##\tGibt den Wert Pi zurück\r\nPOWER\t\t\t= POTENZ\t\t\t##\tGibt als Ergebnis eine potenzierte Zahl zurück\r\nPRODUCT\t\t\t= PRODUKT\t\t\t##\tMultipliziert die zugehörigen Argumente\r\nQUOTIENT\t\t= QUOTIENT\t\t\t##\tGibt den ganzzahligen Anteil einer Division zurück\r\nRADIANS\t\t\t= BOGENMASS\t\t\t##\tWandelt Grad in Bogenmaß (Radiant) um\r\nRAND\t\t\t= ZUFALLSZAHL\t\t\t##\tGibt eine Zufallszahl zwischen 0 und 1 zurück\r\nRANDBETWEEN\t\t= ZUFALLSBEREICH\t\t##\tGibt eine Zufallszahl aus dem festgelegten Bereich zurück\r\nROMAN\t\t\t= RÖMISCH\t\t\t##\tWandelt eine arabische Zahl in eine römische Zahl als Text um\r\nROUND\t\t\t= RUNDEN\t\t\t##\tRundet eine Zahl auf eine bestimmte Anzahl von Dezimalstellen\r\nROUNDDOWN\t\t= ABRUNDEN\t\t\t##\tRundet die Zahl auf Anzahl_Stellen ab\r\nROUNDUP\t\t\t= AUFRUNDEN\t\t\t##\tRundet die Zahl auf Anzahl_Stellen auf\r\nSERIESSUM\t\t= POTENZREIHE\t\t\t##\tGibt die Summe von Potenzen (zur Berechnung von Potenzreihen und dichotomen Wahrscheinlichkeiten) zurück\r\nSIGN\t\t\t= VORZEICHEN\t\t\t##\tGibt das Vorzeichen einer Zahl zurück\r\nSIN\t\t\t= SIN\t\t\t\t##\tGibt den Sinus einer Zahl zurück\r\nSINH\t\t\t= SINHYP\t\t\t##\tGibt den hyperbolischen Sinus einer Zahl zurück\r\nSQRT\t\t\t= WURZEL\t\t\t##\tGibt die Quadratwurzel einer Zahl zurück\r\nSQRTPI\t\t\t= WURZELPI\t\t\t##\tGibt die Wurzel aus der mit Pi (pi) multiplizierten Zahl zurück\r\nSUBTOTAL\t\t= TEILERGEBNIS\t\t\t##\tGibt ein Teilergebnis in einer Liste oder Datenbank zurück\r\nSUM\t\t\t= SUMME\t\t\t\t##\tAddiert die zugehörigen Argumente\r\nSUMIF\t\t\t= SUMMEWENN\t\t\t##\tAddiert Zahlen, die mit den Suchkriterien übereinstimmen\r\nSUMIFS\t\t\t= SUMMEWENNS\t\t\t##\tDie Zellen, die mehrere Kriterien erfüllen, werden in einem Bereich hinzugefügt\r\nSUMPRODUCT\t\t= SUMMENPRODUKT\t\t\t##\tGibt die Summe der Produkte zusammengehöriger Matrixkomponenten zurück\r\nSUMSQ\t\t\t= QUADRATESUMME\t\t\t##\tGibt die Summe der quadrierten Argumente zurück\r\nSUMX2MY2\t\t= SUMMEX2MY2\t\t\t##\tGibt die Summe der Differenzen der Quadrate für zusammengehörige Komponenten zweier Matrizen zurück\r\nSUMX2PY2\t\t= SUMMEX2PY2\t\t\t##\tGibt die Summe der Quadrate für zusammengehörige Komponenten zweier Matrizen zurück\r\nSUMXMY2\t\t\t= SUMMEXMY2\t\t\t##\tGibt die Summe der quadrierten Differenzen für zusammengehörige Komponenten zweier Matrizen zurück\r\nTAN\t\t\t= TAN\t\t\t\t##\tGibt den Tangens einer Zahl zurück\r\nTANH\t\t\t= TANHYP\t\t\t##\tGibt den hyperbolischen Tangens einer Zahl zurück\r\nTRUNC\t\t\t= KÜRZEN\t\t\t##\tSchneidet die Kommastellen einer Zahl ab und gibt als Ergebnis eine ganze Zahl zurück\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\tStatistische Funktionen\r\n##\r\nAVEDEV\t\t\t= MITTELABW\t\t\t##\tGibt die durchschnittliche absolute Abweichung einer Reihe von Merkmalsausprägungen und ihrem Mittelwert zurück\r\nAVERAGE\t\t\t= MITTELWERT\t\t\t##\tGibt den Mittelwert der zugehörigen Argumente zurück\r\nAVERAGEA\t\t= MITTELWERTA\t\t\t##\tGibt den Mittelwert der zugehörigen Argumente, die Zahlen, Text und Wahrheitswerte enthalten, zurück\r\nAVERAGEIF\t\t= MITTELWERTWENN\t\t##\tDer Durchschnittswert (arithmetisches Mittel) für alle Zellen in einem Bereich, die einem angegebenen Kriterium entsprechen, wird zurückgegeben\r\nAVERAGEIFS\t\t= MITTELWERTWENNS\t\t##\tGibt den Durchschnittswert (arithmetisches Mittel) aller Zellen zurück, die mehreren Kriterien entsprechen\r\nBETADIST\t\t= BETAVERT\t\t\t##\tGibt die Werte der kumulierten Betaverteilungsfunktion zurück\r\nBETAINV\t\t\t= BETAINV\t\t\t##\tGibt das Quantil der angegebenen Betaverteilung zurück\r\nBINOMDIST\t\t= BINOMVERT\t\t\t##\tGibt Wahrscheinlichkeiten einer binomialverteilten Zufallsvariablen zurück\r\nCHIDIST\t\t\t= CHIVERT\t\t\t##\tGibt Werte der Verteilungsfunktion (1-Alpha) einer Chi-Quadrat-verteilten Zufallsgröße zurück\r\nCHIINV\t\t\t= CHIINV\t\t\t##\tGibt Quantile der Verteilungsfunktion (1-Alpha) der Chi-Quadrat-Verteilung zurück\r\nCHITEST\t\t\t= CHITEST\t\t\t##\tGibt die Teststatistik eines Unabhängigkeitstests zurück\r\nCONFIDENCE\t\t= KONFIDENZ\t\t\t##\tErmöglicht die Berechnung des 1-Alpha Konfidenzintervalls für den Erwartungswert einer Zufallsvariablen\r\nCORREL\t\t\t= KORREL\t\t\t##\tGibt den Korrelationskoeffizienten zweier Reihen von Merkmalsausprägungen zurück\r\nCOUNT\t\t\t= ANZAHL\t\t\t##\tGibt die Anzahl der Zahlen in der Liste mit Argumenten an\r\nCOUNTA\t\t\t= ANZAHL2\t\t\t##\tGibt die Anzahl der Werte in der Liste mit Argumenten an\r\nCOUNTBLANK\t\t= ANZAHLLEEREZELLEN\t\t##\tGibt die Anzahl der leeren Zellen in einem Bereich an\r\nCOUNTIF\t\t\t= ZÄHLENWENN\t\t\t##\tGibt die Anzahl der Zellen in einem Bereich an, deren Inhalte mit den Suchkriterien übereinstimmen\r\nCOUNTIFS\t\t= ZÄHLENWENNS\t\t\t##\tGibt die Anzahl der Zellen in einem Bereich an, deren Inhalte mit mehreren Suchkriterien übereinstimmen\r\nCOVAR\t\t\t= KOVAR\t\t\t\t##\tGibt die Kovarianz zurück, den Mittelwert der für alle Datenpunktpaare gebildeten Produkte der Abweichungen\r\nCRITBINOM\t\t= KRITBINOM\t\t\t##\tGibt den kleinsten Wert zurück, für den die kumulierten Wahrscheinlichkeiten der Binomialverteilung kleiner oder gleich einer Grenzwahrscheinlichkeit sind\r\nDEVSQ\t\t\t= SUMQUADABW\t\t\t##\tGibt die Summe der quadrierten Abweichungen der Datenpunkte von ihrem Stichprobenmittelwert zurück\r\nEXPONDIST\t\t= EXPONVERT\t\t\t##\tGibt Wahrscheinlichkeiten einer exponential verteilten Zufallsvariablen zurück\r\nFDIST\t\t\t= FVERT\t\t\t\t##\tGibt Werte der Verteilungsfunktion (1-Alpha) einer F-verteilten Zufallsvariablen zurück\r\nFINV\t\t\t= FINV\t\t\t\t##\tGibt Quantile der F-Verteilung zurück\r\nFISHER\t\t\t= FISHER\t\t\t##\tGibt die Fisher-Transformation zurück\r\nFISHERINV\t\t= FISHERINV\t\t\t##\tGibt die Umkehrung der Fisher-Transformation zurück\r\nFORECAST\t\t= PROGNOSE\t\t\t##\tGibt einen Wert zurück, der sich aus einem linearen Trend ergibt\r\nFREQUENCY\t\t= HÄUFIGKEIT\t\t\t##\tGibt eine Häufigkeitsverteilung als vertikale Matrix zurück\r\nFTEST\t\t\t= FTEST\t\t\t\t##\tGibt die Teststatistik eines F-Tests zurück\r\nGAMMADIST\t\t= GAMMAVERT\t\t\t##\tGibt Wahrscheinlichkeiten einer gammaverteilten Zufallsvariablen zurück\r\nGAMMAINV\t\t= GAMMAINV\t\t\t##\tGibt Quantile der Gammaverteilung zurück\r\nGAMMALN\t\t\t= GAMMALN\t\t\t##\tGibt den natürlichen Logarithmus der Gammafunktion zurück, Γ(x)\r\nGEOMEAN\t\t\t= GEOMITTEL\t\t\t##\tGibt das geometrische Mittel zurück\r\nGROWTH\t\t\t= VARIATION\t\t\t##\tGibt Werte zurück, die sich aus einem exponentiellen Trend ergeben\r\nHARMEAN\t\t\t= HARMITTEL\t\t\t##\tGibt das harmonische Mittel zurück\r\nHYPGEOMDIST\t\t= HYPGEOMVERT\t\t\t##\tGibt Wahrscheinlichkeiten einer hypergeometrisch-verteilten Zufallsvariablen zurück\r\nINTERCEPT\t\t= ACHSENABSCHNITT\t\t##\tGibt den Schnittpunkt der Regressionsgeraden zurück\r\nKURT\t\t\t= KURT\t\t\t\t##\tGibt die Kurtosis (Exzess) einer Datengruppe zurück\r\nLARGE\t\t\t= KGRÖSSTE\t\t\t##\tGibt den k-größten Wert einer Datengruppe zurück\r\nLINEST\t\t\t= RGP\t\t\t\t##\tGibt die Parameter eines linearen Trends zurück\r\nLOGEST\t\t\t= RKP\t\t\t\t##\tGibt die Parameter eines exponentiellen Trends zurück\r\nLOGINV\t\t\t= LOGINV\t\t\t##\tGibt Quantile der Lognormalverteilung zurück\r\nLOGNORMDIST\t\t= LOGNORMVERT\t\t\t##\tGibt Werte der Verteilungsfunktion einer lognormalverteilten Zufallsvariablen zurück\r\nMAX\t\t\t= MAX\t\t\t\t##\tGibt den Maximalwert einer Liste mit Argumenten zurück\r\nMAXA\t\t\t= MAXA\t\t\t\t##\tGibt den Maximalwert einer Liste mit Argumenten zurück, die Zahlen, Text und Wahrheitswerte enthalten\r\nMEDIAN\t\t\t= MEDIAN\t\t\t##\tGibt den Median der angegebenen Zahlen zurück\r\nMIN\t\t\t= MIN\t\t\t\t##\tGibt den Minimalwert einer Liste mit Argumenten zurück\r\nMINA\t\t\t= MINA\t\t\t\t##\tGibt den kleinsten Wert einer Liste mit Argumenten zurück, die Zahlen, Text und Wahrheitswerte enthalten\r\nMODE\t\t\t= MODALWERT\t\t\t##\tGibt den am häufigsten vorkommenden Wert in einer Datengruppe zurück\r\nNEGBINOMDIST\t\t= NEGBINOMVERT\t\t\t##\tGibt Wahrscheinlichkeiten einer negativen, binominal verteilten Zufallsvariablen zurück\r\nNORMDIST\t\t= NORMVERT\t\t\t##\tGibt Wahrscheinlichkeiten einer normal verteilten Zufallsvariablen zurück\r\nNORMINV\t\t\t= NORMINV\t\t\t##\tGibt Quantile der Normalverteilung zurück\r\nNORMSDIST\t\t= STANDNORMVERT\t\t\t##\tGibt Werte der Verteilungsfunktion einer standardnormalverteilten Zufallsvariablen zurück\r\nNORMSINV\t\t= STANDNORMINV\t\t\t##\tGibt Quantile der Standardnormalverteilung zurück\r\nPEARSON\t\t\t= PEARSON\t\t\t##\tGibt den Pearsonschen Korrelationskoeffizienten zurück\r\nPERCENTILE\t\t= QUANTIL\t\t\t##\tGibt das Alpha-Quantil einer Gruppe von Daten zurück\r\nPERCENTRANK\t\t= QUANTILSRANG\t\t\t##\tGibt den prozentualen Rang (Alpha) eines Werts in einer Datengruppe zurück\r\nPERMUT\t\t\t= VARIATIONEN\t\t\t##\tGibt die Anzahl der Möglichkeiten zurück, um k Elemente aus einer Menge von n Elementen ohne Zurücklegen zu ziehen\r\nPOISSON\t\t\t= POISSON\t\t\t##\tGibt Wahrscheinlichkeiten einer poissonverteilten Zufallsvariablen zurück\r\nPROB\t\t\t= WAHRSCHBEREICH\t\t##\tGibt die Wahrscheinlichkeit für ein von zwei Werten eingeschlossenes Intervall zurück\r\nQUARTILE\t\t= QUARTILE\t\t\t##\tGibt die Quartile der Datengruppe zurück\r\nRANK\t\t\t= RANG\t\t\t\t##\tGibt den Rang zurück, den eine Zahl innerhalb einer Liste von Zahlen einnimmt\r\nRSQ\t\t\t= BESTIMMTHEITSMASS\t\t##\tGibt das Quadrat des Pearsonschen Korrelationskoeffizienten zurück\r\nSKEW\t\t\t= SCHIEFE\t\t\t##\tGibt die Schiefe einer Verteilung zurück\r\nSLOPE\t\t\t= STEIGUNG\t\t\t##\tGibt die Steigung der Regressionsgeraden zurück\r\nSMALL\t\t\t= KKLEINSTE\t\t\t##\tGibt den k-kleinsten Wert einer Datengruppe zurück\r\nSTANDARDIZE\t\t= STANDARDISIERUNG\t\t##\tGibt den standardisierten Wert zurück\r\nSTDEV\t\t\t= STABW\t\t\t\t##\tSchätzt die Standardabweichung ausgehend von einer Stichprobe\r\nSTDEVA\t\t\t= STABWA\t\t\t##\tSchätzt die Standardabweichung ausgehend von einer Stichprobe, die Zahlen, Text und Wahrheitswerte enthält\r\nSTDEVP\t\t\t= STABWN\t\t\t##\tBerechnet die Standardabweichung ausgehend von der Grundgesamtheit\r\nSTDEVPA\t\t\t= STABWNA\t\t\t##\tBerechnet die Standardabweichung ausgehend von der Grundgesamtheit, die Zahlen, Text und Wahrheitswerte enthält\r\nSTEYX\t\t\t= STFEHLERYX\t\t\t##\tGibt den Standardfehler der geschätzten y-Werte für alle x-Werte der Regression zurück\r\nTDIST\t\t\t= TVERT\t\t\t\t##\tGibt Werte der Verteilungsfunktion (1-Alpha) einer (Student) t-verteilten Zufallsvariablen zurück\r\nTINV\t\t\t= TINV\t\t\t\t##\tGibt Quantile der t-Verteilung zurück\r\nTREND\t\t\t= TREND\t\t\t\t##\tGibt Werte zurück, die sich aus einem linearen Trend ergeben\r\nTRIMMEAN\t\t= GESTUTZTMITTEL\t\t##\tGibt den Mittelwert einer Datengruppe zurück, ohne die Randwerte zu berücksichtigen\r\nTTEST\t\t\t= TTEST\t\t\t\t##\tGibt die Teststatistik eines Student'schen t-Tests zurück\r\nVAR\t\t\t= VARIANZ\t\t\t##\tSchätzt die Varianz ausgehend von einer Stichprobe\r\nVARA\t\t\t= VARIANZA\t\t\t##\tSchätzt die Varianz ausgehend von einer Stichprobe, die Zahlen, Text und Wahrheitswerte enthält\r\nVARP\t\t\t= VARIANZEN\t\t\t##\tBerechnet die Varianz ausgehend von der Grundgesamtheit\r\nVARPA\t\t\t= VARIANZENA\t\t\t##\tBerechnet die Varianz ausgehend von der Grundgesamtheit, die Zahlen, Text und Wahrheitswerte enthält\r\nWEIBULL\t\t\t= WEIBULL\t\t\t##\tGibt Wahrscheinlichkeiten einer weibullverteilten Zufallsvariablen zurück\r\nZTEST\t\t\t= GTEST\t\t\t\t##\tGibt den einseitigen Wahrscheinlichkeitswert für einen Gausstest (Normalverteilung) zurück\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\tTextfunktionen\r\n##\r\nASC\t\t\t= ASC\t\t\t\t##\tKonvertiert DB-Text in einer Zeichenfolge (lateinische Buchstaben oder Katakana) in SB-Text\r\nBAHTTEXT\t\t= BAHTTEXT\t\t\t##\tWandelt eine Zahl in Text im Währungsformat ß (Baht) um\r\nCHAR\t\t\t= ZEICHEN\t\t\t##\tGibt das der Codezahl entsprechende Zeichen zurück\r\nCLEAN\t\t\t= SÄUBERN\t\t\t##\tLöscht alle nicht druckbaren Zeichen aus einem Text\r\nCODE\t\t\t= CODE\t\t\t\t##\tGibt die Codezahl des ersten Zeichens in einem Text zurück\r\nCONCATENATE\t\t= VERKETTEN\t\t\t##\tVerknüpft mehrere Textelemente zu einem Textelement\r\nDOLLAR\t\t\t= DM\t\t\t\t##\tWandelt eine Zahl in Text im Währungsformat € (Euro) um\r\nEXACT\t\t\t= IDENTISCH\t\t\t##\tPrüft, ob zwei Textwerte identisch sind\r\nFIND\t\t\t= FINDEN\t\t\t##\tSucht nach einem Textwert, der in einem anderen Textwert enthalten ist (Groß-/Kleinschreibung wird unterschieden)\r\nFINDB\t\t\t= FINDENB\t\t\t##\tSucht nach einem Textwert, der in einem anderen Textwert enthalten ist (Groß-/Kleinschreibung wird unterschieden)\r\nFIXED\t\t\t= FEST\t\t\t\t##\tFormatiert eine Zahl als Text mit einer festen Anzahl von Dezimalstellen\r\nJIS\t\t\t= JIS\t\t\t\t##\tKonvertiert SB-Text in einer Zeichenfolge (lateinische Buchstaben oder Katakana) in DB-Text\r\nLEFT\t\t\t= LINKS\t\t\t\t##\tGibt die Zeichen ganz links in einem Textwert zurück\r\nLEFTB\t\t\t= LINKSB\t\t\t##\tGibt die Zeichen ganz links in einem Textwert zurück\r\nLEN\t\t\t= LÄNGE\t\t\t\t##\tGibt die Anzahl der Zeichen in einer Zeichenfolge zurück\r\nLENB\t\t\t= LÄNGEB\t\t\t##\tGibt die Anzahl der Zeichen in einer Zeichenfolge zurück\r\nLOWER\t\t\t= KLEIN\t\t\t\t##\tWandelt Text in Kleinbuchstaben um\r\nMID\t\t\t= TEIL\t\t\t\t##\tGibt eine bestimmte Anzahl Zeichen aus einer Zeichenfolge ab der von Ihnen angegebenen Stelle zurück\r\nMIDB\t\t\t= TEILB\t\t\t\t##\tGibt eine bestimmte Anzahl Zeichen aus einer Zeichenfolge ab der von Ihnen angegebenen Stelle zurück\r\nPHONETIC\t\t= PHONETIC\t\t\t##\tExtrahiert die phonetischen (Furigana-)Zeichen aus einer Textzeichenfolge\r\nPROPER\t\t\t= GROSS2\t\t\t##\tWandelt den ersten Buchstaben aller Wörter eines Textwerts in Großbuchstaben um\r\nREPLACE\t\t\t= ERSETZEN\t\t\t##\tErsetzt Zeichen in Text\r\nREPLACEB\t\t= ERSETZENB\t\t\t##\tErsetzt Zeichen in Text\r\nREPT\t\t\t= WIEDERHOLEN\t\t\t##\tWiederholt einen Text so oft wie angegeben\r\nRIGHT\t\t\t= RECHTS\t\t\t##\tGibt die Zeichen ganz rechts in einem Textwert zurück\r\nRIGHTB\t\t\t= RECHTSB\t\t\t##\tGibt die Zeichen ganz rechts in einem Textwert zurück\r\nSEARCH\t\t\t= SUCHEN\t\t\t##\tSucht nach einem Textwert, der in einem anderen Textwert enthalten ist (Groß-/Kleinschreibung wird nicht unterschieden)\r\nSEARCHB\t\t\t= SUCHENB\t\t\t##\tSucht nach einem Textwert, der in einem anderen Textwert enthalten ist (Groß-/Kleinschreibung wird nicht unterschieden)\r\nSUBSTITUTE\t\t= WECHSELN\t\t\t##\tErsetzt in einer Zeichenfolge neuen Text gegen alten\r\nT\t\t\t= T\t\t\t\t##\tWandelt die zugehörigen Argumente in Text um\r\nTEXT\t\t\t= TEXT\t\t\t\t##\tFormatiert eine Zahl und wandelt sie in Text um\r\nTRIM\t\t\t= GLÄTTEN\t\t\t##\tEntfernt Leerzeichen aus Text\r\nUPPER\t\t\t= GROSS\t\t\t\t##\tWandelt Text in Großbuchstaben um\r\nVALUE\t\t\t= WERT\t\t\t\t##\tWandelt ein Textargument in eine Zahl um\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/en/uk/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= £\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/es/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= $\t##\tI'm surprised that the Excel Documentation suggests $ rather than €\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #¡NULO!\r\nDIV0\t= #¡DIV/0!\r\nVALUE\t= #¡VALOR!\r\nREF\t= #¡REF!\r\nNAME\t= #¿NOMBRE?\r\nNUM\t= #¡NÚM!\r\nNA\t= #N/A\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/es/functions",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Calculation\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/\r\n##\r\n##\r\n\r\n\r\n##\r\n##\tAdd-in and Automation functions\t\t\t\tFunciones de complementos y automatización\r\n##\r\nGETPIVOTDATA\t\t= IMPORTARDATOSDINAMICOS\t\t##\tDevuelve los datos almacenados en un informe de tabla dinámica.\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\t\tFunciones de cubo\r\n##\r\nCUBEKPIMEMBER\t\t= MIEMBROKPICUBO\t\t\t##\tDevuelve un nombre, propiedad y medida de indicador de rendimiento clave (KPI) y muestra el nombre y la propiedad en la celda. Un KPI es una medida cuantificable, como los beneficios brutos mensuales o la facturación trimestral por empleado, que se usa para supervisar el rendimiento de una organización.\r\nCUBEMEMBER\t\t= MIEMBROCUBO\t\t\t\t##\tDevuelve un miembro o tupla en una jerarquía de cubo. Se usa para validar la existencia del miembro o la tupla en el cubo.\r\nCUBEMEMBERPROPERTY\t= PROPIEDADMIEMBROCUBO\t\t\t##\tDevuelve el valor de una propiedad de miembro del cubo Se usa para validar la existencia de un nombre de miembro en el cubo y para devolver la propiedad especificada para este miembro.\r\nCUBERANKEDMEMBER\t= MIEMBRORANGOCUBO\t\t\t##\tDevuelve el miembro n, o clasificado, de un conjunto. Se usa para devolver uno o más elementos de un conjunto, por ejemplo, el representante con mejores ventas o los diez mejores alumnos.\r\nCUBESET\t\t\t= CONJUNTOCUBO\t\t\t\t##\tDefine un conjunto calculado de miembros o tuplas mediante el envío de una expresión de conjunto al cubo en el servidor, lo que crea el conjunto y, después, devuelve dicho conjunto a Microsoft Office Excel.\r\nCUBESETCOUNT\t\t= RECUENTOCONJUNTOCUBO\t\t\t##\tDevuelve el número de elementos de un conjunto.\r\nCUBEVALUE\t\t= VALORCUBO\t\t\t\t##\tDevuelve un valor agregado de un cubo.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\t\tFunciones de base de datos\r\n##\r\nDAVERAGE\t\t= BDPROMEDIO\t\t\t\t##\tDevuelve el promedio de las entradas seleccionadas en la base de datos.\r\nDCOUNT\t\t\t= BDCONTAR\t\t\t\t##\tCuenta el número de celdas que contienen números en una base de datos.\r\nDCOUNTA\t\t\t= BDCONTARA\t\t\t\t##\tCuenta el número de celdas no vacías en una base de datos.\r\nDGET\t\t\t= BDEXTRAER\t\t\t\t##\tExtrae de una base de datos un único registro que cumple los criterios especificados.\r\nDMAX\t\t\t= BDMAX\t\t\t\t\t##\tDevuelve el valor máximo de las entradas seleccionadas de la base de datos.\r\nDMIN\t\t\t= BDMIN\t\t\t\t\t##\tDevuelve el valor mínimo de las entradas seleccionadas de la base de datos.\r\nDPRODUCT\t\t= BDPRODUCTO\t\t\t\t##\tMultiplica los valores de un campo concreto de registros de una base de datos que cumplen los criterios especificados.\r\nDSTDEV\t\t\t= BDDESVEST\t\t\t\t##\tCalcula la desviación estándar a partir de una muestra de entradas seleccionadas en la base de datos.\r\nDSTDEVP\t\t\t= BDDESVESTP\t\t\t\t##\tCalcula la desviación estándar en función de la población total de las entradas seleccionadas de la base de datos.\r\nDSUM\t\t\t= BDSUMA\t\t\t\t##\tSuma los números de la columna de campo de los registros de la base de datos que cumplen los criterios.\r\nDVAR\t\t\t= BDVAR\t\t\t\t\t##\tCalcula la varianza a partir de una muestra de entradas seleccionadas de la base de datos.\r\nDVARP\t\t\t= BDVARP\t\t\t\t##\tCalcula la varianza a partir de la población total de entradas seleccionadas de la base de datos.\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\t\tFunciones de fecha y hora\r\n##\r\nDATE\t\t\t= FECHA\t\t\t\t\t##\tDevuelve el número de serie correspondiente a una fecha determinada.\r\nDATEVALUE\t\t= FECHANUMERO\t\t\t\t##\tConvierte una fecha con formato de texto en un valor de número de serie.\r\nDAY\t\t\t= DIA\t\t\t\t\t##\tConvierte un número de serie en un valor de día del mes.\r\nDAYS360\t\t\t= DIAS360\t\t\t\t##\tCalcula el número de días entre dos fechas a partir de un año de 360 días.\r\nEDATE\t\t\t= FECHA.MES\t\t\t\t##\tDevuelve el número de serie de la fecha equivalente al número indicado de meses anteriores o posteriores a la fecha inicial.\r\nEOMONTH\t\t\t= FIN.MES\t\t\t\t##\tDevuelve el número de serie correspondiente al último día del mes anterior o posterior a un número de meses especificado.\r\nHOUR\t\t\t= HORA\t\t\t\t\t##\tConvierte un número de serie en un valor de hora.\r\nMINUTE\t\t\t= MINUTO\t\t\t\t##\tConvierte un número de serie en un valor de minuto.\r\nMONTH\t\t\t= MES\t\t\t\t\t##\tConvierte un número de serie en un valor de mes.\r\nNETWORKDAYS\t\t= DIAS.LAB\t\t\t\t##\tDevuelve el número de todos los días laborables existentes entre dos fechas.\r\nNOW\t\t\t= AHORA\t\t\t\t\t##\tDevuelve el número de serie correspondiente a la fecha y hora actuales.\r\nSECOND\t\t\t= SEGUNDO\t\t\t\t##\tConvierte un número de serie en un valor de segundo.\r\nTIME\t\t\t= HORA\t\t\t\t\t##\tDevuelve el número de serie correspondiente a una hora determinada.\r\nTIMEVALUE\t\t= HORANUMERO\t\t\t\t##\tConvierte una hora con formato de texto en un valor de número de serie.\r\nTODAY\t\t\t= HOY\t\t\t\t\t##\tDevuelve el número de serie correspondiente al día actual.\r\nWEEKDAY\t\t\t= DIASEM\t\t\t\t##\tConvierte un número de serie en un valor de día de la semana.\r\nWEEKNUM\t\t\t= NUM.DE.SEMANA\t\t\t\t##\tConvierte un número de serie en un número que representa el lugar numérico correspondiente a una semana de un año.\r\nWORKDAY\t\t\t= DIA.LAB\t\t\t\t##\tDevuelve el número de serie de la fecha que tiene lugar antes o después de un número determinado de días laborables.\r\nYEAR\t\t\t= AÑO\t\t\t\t\t##\tConvierte un número de serie en un valor de año.\r\nYEARFRAC\t\t= FRAC.AÑO\t\t\t\t##\tDevuelve la fracción de año que representa el número total de días existentes entre el valor de fecha_inicial y el de fecha_final.\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\t\tFunciones de ingeniería\r\n##\r\nBESSELI\t\t\t= BESSELI\t\t\t\t##\tDevuelve la función Bessel In(x) modificada.\r\nBESSELJ\t\t\t= BESSELJ\t\t\t\t##\tDevuelve la función Bessel Jn(x).\r\nBESSELK\t\t\t= BESSELK\t\t\t\t##\tDevuelve la función Bessel Kn(x) modificada.\r\nBESSELY\t\t\t= BESSELY\t\t\t\t##\tDevuelve la función Bessel Yn(x).\r\nBIN2DEC\t\t\t= BIN.A.DEC\t\t\t\t##\tConvierte un número binario en decimal.\r\nBIN2HEX\t\t\t= BIN.A.HEX\t\t\t\t##\tConvierte un número binario en hexadecimal.\r\nBIN2OCT\t\t\t= BIN.A.OCT\t\t\t\t##\tConvierte un número binario en octal.\r\nCOMPLEX\t\t\t= COMPLEJO\t\t\t\t##\tConvierte coeficientes reales e imaginarios en un número complejo.\r\nCONVERT\t\t\t= CONVERTIR\t\t\t\t##\tConvierte un número de un sistema de medida a otro.\r\nDEC2BIN\t\t\t= DEC.A.BIN\t\t\t\t##\tConvierte un número decimal en binario.\r\nDEC2HEX\t\t\t= DEC.A.HEX\t\t\t\t##\tConvierte un número decimal en hexadecimal.\r\nDEC2OCT\t\t\t= DEC.A.OCT\t\t\t\t##\tConvierte un número decimal en octal.\r\nDELTA\t\t\t= DELTA\t\t\t\t\t##\tComprueba si dos valores son iguales.\r\nERF\t\t\t= FUN.ERROR\t\t\t\t##\tDevuelve la función de error.\r\nERFC\t\t\t= FUN.ERROR.COMPL\t\t\t##\tDevuelve la función de error complementario.\r\nGESTEP\t\t\t= MAYOR.O.IGUAL\t\t\t\t##\tComprueba si un número es mayor que un valor de umbral.\r\nHEX2BIN\t\t\t= HEX.A.BIN\t\t\t\t##\tConvierte un número hexadecimal en binario.\r\nHEX2DEC\t\t\t= HEX.A.DEC\t\t\t\t##\tConvierte un número hexadecimal en decimal.\r\nHEX2OCT\t\t\t= HEX.A.OCT\t\t\t\t##\tConvierte un número hexadecimal en octal.\r\nIMABS\t\t\t= IM.ABS\t\t\t\t##\tDevuelve el valor absoluto (módulo) de un número complejo.\r\nIMAGINARY\t\t= IMAGINARIO\t\t\t\t##\tDevuelve el coeficiente imaginario de un número complejo.\r\nIMARGUMENT\t\t= IM.ANGULO\t\t\t\t##\tDevuelve el argumento theta, un ángulo expresado en radianes.\r\nIMCONJUGATE\t\t= IM.CONJUGADA\t\t\t\t##\tDevuelve la conjugada compleja de un número complejo.\r\nIMCOS\t\t\t= IM.COS\t\t\t\t##\tDevuelve el coseno de un número complejo.\r\nIMDIV\t\t\t= IM.DIV\t\t\t\t##\tDevuelve el cociente de dos números complejos.\r\nIMEXP\t\t\t= IM.EXP\t\t\t\t##\tDevuelve el valor exponencial de un número complejo.\r\nIMLN\t\t\t= IM.LN\t\t\t\t\t##\tDevuelve el logaritmo natural (neperiano) de un número complejo.\r\nIMLOG10\t\t\t= IM.LOG10\t\t\t\t##\tDevuelve el logaritmo en base 10 de un número complejo.\r\nIMLOG2\t\t\t= IM.LOG2\t\t\t\t##\tDevuelve el logaritmo en base 2 de un número complejo.\r\nIMPOWER\t\t\t= IM.POT\t\t\t\t##\tDevuelve un número complejo elevado a una potencia entera.\r\nIMPRODUCT\t\t= IM.PRODUCT\t\t\t\t##\tDevuelve el producto de números complejos.\r\nIMREAL\t\t\t= IM.REAL\t\t\t\t##\tDevuelve el coeficiente real de un número complejo.\r\nIMSIN\t\t\t= IM.SENO\t\t\t\t##\tDevuelve el seno de un número complejo.\r\nIMSQRT\t\t\t= IM.RAIZ2\t\t\t\t##\tDevuelve la raíz cuadrada de un número complejo.\r\nIMSUB\t\t\t= IM.SUSTR\t\t\t\t##\tDevuelve la diferencia entre dos números complejos.\r\nIMSUM\t\t\t= IM.SUM\t\t\t\t##\tDevuelve la suma de números complejos.\r\nOCT2BIN\t\t\t= OCT.A.BIN\t\t\t\t##\tConvierte un número octal en binario.\r\nOCT2DEC\t\t\t= OCT.A.DEC\t\t\t\t##\tConvierte un número octal en decimal.\r\nOCT2HEX\t\t\t= OCT.A.HEX\t\t\t\t##\tConvierte un número octal en hexadecimal.\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\t\tFunciones financieras\r\n##\r\nACCRINT\t\t\t= INT.ACUM\t\t\t\t##\tDevuelve el interés acumulado de un valor bursátil con pagos de interés periódicos.\r\nACCRINTM\t\t= INT.ACUM.V\t\t\t\t##\tDevuelve el interés acumulado de un valor bursátil con pagos de interés al vencimiento.\r\nAMORDEGRC\t\t= AMORTIZ.PROGRE\t\t\t##\tDevuelve la amortización de cada período contable mediante el uso de un coeficiente de amortización.\r\nAMORLINC\t\t= AMORTIZ.LIN\t\t\t\t##\tDevuelve la amortización de cada uno de los períodos contables.\r\nCOUPDAYBS\t\t= CUPON.DIAS.L1\t\t\t\t##\tDevuelve el número de días desde el principio del período de un cupón hasta la fecha de liquidación.\r\nCOUPDAYS\t\t= CUPON.DIAS\t\t\t\t##\tDevuelve el número de días del período (entre dos cupones) donde se encuentra la fecha de liquidación.\r\nCOUPDAYSNC\t\t= CUPON.DIAS.L2\t\t\t\t##\tDevuelve el número de días desde la fecha de liquidación hasta la fecha del próximo cupón.\r\nCOUPNCD\t\t\t= CUPON.FECHA.L2\t\t\t##\tDevuelve la fecha del próximo cupón después de la fecha de liquidación.\r\nCOUPNUM\t\t\t= CUPON.NUM\t\t\t\t##\tDevuelve el número de pagos de cupón entre la fecha de liquidación y la fecha de vencimiento.\r\nCOUPPCD\t\t\t= CUPON.FECHA.L1\t\t\t##\tDevuelve la fecha de cupón anterior a la fecha de liquidación.\r\nCUMIPMT\t\t\t= PAGO.INT.ENTRE\t\t\t##\tDevuelve el interés acumulado pagado entre dos períodos.\r\nCUMPRINC\t\t= PAGO.PRINC.ENTRE\t\t\t##\tDevuelve el capital acumulado pagado de un préstamo entre dos períodos.\r\nDB\t\t\t= DB\t\t\t\t\t##\tDevuelve la amortización de un bien durante un período específico a través del método de amortización de saldo fijo.\r\nDDB\t\t\t= DDB\t\t\t\t\t##\tDevuelve la amortización de un bien durante un período específico a través del método de amortización por doble disminución de saldo u otro método que se especifique.\r\nDISC\t\t\t= TASA.DESC\t\t\t\t##\tDevuelve la tasa de descuento de un valor bursátil.\r\nDOLLARDE\t\t= MONEDA.DEC\t\t\t\t##\tConvierte una cotización de un valor bursátil expresada en forma fraccionaria en una cotización de un valor bursátil expresada en forma decimal.\r\nDOLLARFR\t\t= MONEDA.FRAC\t\t\t\t##\tConvierte una cotización de un valor bursátil expresada en forma decimal en una cotización de un valor bursátil expresada en forma fraccionaria.\r\nDURATION\t\t= DURACION\t\t\t\t##\tDevuelve la duración anual de un valor bursátil con pagos de interés periódico.\r\nEFFECT\t\t\t= INT.EFECTIVO\t\t\t\t##\tDevuelve la tasa de interés anual efectiva.\r\nFV\t\t\t= VF\t\t\t\t\t##\tDevuelve el valor futuro de una inversión.\r\nFVSCHEDULE\t\t= VF.PLAN\t\t\t\t##\tDevuelve el valor futuro de un capital inicial después de aplicar una serie de tasas de interés compuesto.\r\nINTRATE\t\t\t= TASA.INT\t\t\t\t##\tDevuelve la tasa de interés para la inversión total de un valor bursátil.\r\nIPMT\t\t\t= PAGOINT\t\t\t\t##\tDevuelve el pago de intereses de una inversión durante un período determinado.\r\nIRR\t\t\t= TIR\t\t\t\t\t##\tDevuelve la tasa interna de retorno para una serie de flujos de efectivo periódicos.\r\nISPMT\t\t\t= INT.PAGO.DIR\t\t\t\t##\tCalcula el interés pagado durante un período específico de una inversión.\r\nMDURATION\t\t= DURACION.MODIF\t\t\t##\tDevuelve la duración de Macauley modificada de un valor bursátil con un valor nominal supuesto de 100 $.\r\nMIRR\t\t\t= TIRM\t\t\t\t\t##\tDevuelve la tasa interna de retorno donde se financian flujos de efectivo positivos y negativos a tasas diferentes.\r\nNOMINAL\t\t\t= TASA.NOMINAL\t\t\t\t##\tDevuelve la tasa nominal de interés anual.\r\nNPER\t\t\t= NPER\t\t\t\t\t##\tDevuelve el número de períodos de una inversión.\r\nNPV\t\t\t= VNA\t\t\t\t\t##\tDevuelve el valor neto actual de una inversión en función de una serie de flujos periódicos de efectivo y una tasa de descuento.\r\nODDFPRICE\t\t= PRECIO.PER.IRREGULAR.1\t\t##\tDevuelve el precio por un valor nominal de 100 $ de un valor bursátil con un primer período impar.\r\nODDFYIELD\t\t= RENDTO.PER.IRREGULAR.1\t\t##\tDevuelve el rendimiento de un valor bursátil con un primer período impar.\r\nODDLPRICE\t\t= PRECIO.PER.IRREGULAR.2\t\t##\tDevuelve el precio por un valor nominal de 100 $ de un valor bursátil con un último período impar.\r\nODDLYIELD\t\t= RENDTO.PER.IRREGULAR.2\t\t##\tDevuelve el rendimiento de un valor bursátil con un último período impar.\r\nPMT\t\t\t= PAGO\t\t\t\t\t##\tDevuelve el pago periódico de una anualidad.\r\nPPMT\t\t\t= PAGOPRIN\t\t\t\t##\tDevuelve el pago de capital de una inversión durante un período determinado.\r\nPRICE\t\t\t= PRECIO\t\t\t\t##\tDevuelve el precio por un valor nominal de 100 $ de un valor bursátil que paga una tasa de interés periódico.\r\nPRICEDISC\t\t= PRECIO.DESCUENTO\t\t\t##\tDevuelve el precio por un valor nominal de 100 $ de un valor bursátil con descuento.\r\nPRICEMAT\t\t= PRECIO.VENCIMIENTO\t\t\t##\tDevuelve el precio por un valor nominal de 100 $ de un valor bursátil que paga interés a su vencimiento.\r\nPV\t\t\t= VALACT\t\t\t\t##\tDevuelve el valor actual de una inversión.\r\nRATE\t\t\t= TASA\t\t\t\t\t##\tDevuelve la tasa de interés por período de una anualidad.\r\nRECEIVED\t\t= CANTIDAD.RECIBIDA\t\t\t##\tDevuelve la cantidad recibida al vencimiento de un valor bursátil completamente invertido.\r\nSLN\t\t\t= SLN\t\t\t\t\t##\tDevuelve la amortización por método directo de un bien en un período dado.\r\nSYD\t\t\t= SYD\t\t\t\t\t##\tDevuelve la amortización por suma de dígitos de los años de un bien durante un período especificado.\r\nTBILLEQ\t\t\t= LETRA.DE.TES.EQV.A.BONO\t\t##\tDevuelve el rendimiento de un bono equivalente a una letra del Tesoro (de EE.UU.)\r\nTBILLPRICE\t\t= LETRA.DE.TES.PRECIO\t\t\t##\tDevuelve el precio por un valor nominal de 100 $ de una letra del Tesoro (de EE.UU.)\r\nTBILLYIELD\t\t= LETRA.DE.TES.RENDTO\t\t\t##\tDevuelve el rendimiento de una letra del Tesoro (de EE.UU.)\r\nVDB\t\t\t= DVS\t\t\t\t\t##\tDevuelve la amortización de un bien durante un período específico o parcial a través del método de cálculo del saldo en disminución.\r\nXIRR\t\t\t= TIR.NO.PER\t\t\t\t##\tDevuelve la tasa interna de retorno para un flujo de efectivo que no es necesariamente periódico.\r\nXNPV\t\t\t= VNA.NO.PER\t\t\t\t##\tDevuelve el valor neto actual para un flujo de efectivo que no es necesariamente periódico.\r\nYIELD\t\t\t= RENDTO\t\t\t\t##\tDevuelve el rendimiento de un valor bursátil que paga intereses periódicos.\r\nYIELDDISC\t\t= RENDTO.DESC\t\t\t\t##\tDevuelve el rendimiento anual de un valor bursátil con descuento; por ejemplo, una letra del Tesoro (de EE.UU.)\r\nYIELDMAT\t\t= RENDTO.VENCTO\t\t\t\t##\tDevuelve el rendimiento anual de un valor bursátil que paga intereses al vencimiento.\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\t\tFunciones de información\r\n##\r\nCELL\t\t\t= CELDA\t\t\t\t\t##\tDevuelve información acerca del formato, la ubicación o el contenido de una celda.\r\nERROR.TYPE\t\t= TIPO.DE.ERROR\t\t\t\t##\tDevuelve un número que corresponde a un tipo de error.\r\nINFO\t\t\t= INFO\t\t\t\t\t##\tDevuelve información acerca del entorno operativo en uso.\r\nISBLANK\t\t\t= ESBLANCO\t\t\t\t##\tDevuelve VERDADERO si el valor está en blanco.\r\nISERR\t\t\t= ESERR\t\t\t\t\t##\tDevuelve VERDADERO si el valor es cualquier valor de error excepto #N/A.\r\nISERROR\t\t\t= ESERROR\t\t\t\t##\tDevuelve VERDADERO si el valor es cualquier valor de error.\r\nISEVEN\t\t\t= ES.PAR\t\t\t\t##\tDevuelve VERDADERO si el número es par.\r\nISLOGICAL\t\t= ESLOGICO\t\t\t\t##\tDevuelve VERDADERO si el valor es un valor lógico.\r\nISNA\t\t\t= ESNOD\t\t\t\t\t##\tDevuelve VERDADERO si el valor es el valor de error #N/A.\r\nISNONTEXT\t\t= ESNOTEXTO\t\t\t\t##\tDevuelve VERDADERO si el valor no es texto.\r\nISNUMBER\t\t= ESNUMERO\t\t\t\t##\tDevuelve VERDADERO si el valor es un número.\r\nISODD\t\t\t= ES.IMPAR\t\t\t\t##\tDevuelve VERDADERO si el número es impar.\r\nISREF\t\t\t= ESREF\t\t\t\t\t##\tDevuelve VERDADERO si el valor es una referencia.\r\nISTEXT\t\t\t= ESTEXTO\t\t\t\t##\tDevuelve VERDADERO si el valor es texto.\r\nN\t\t\t= N\t\t\t\t\t##\tDevuelve un valor convertido en un número.\r\nNA\t\t\t= ND\t\t\t\t\t##\tDevuelve el valor de error #N/A.\r\nTYPE\t\t\t= TIPO\t\t\t\t\t##\tDevuelve un número que indica el tipo de datos de un valor.\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\t\tFunciones lógicas\r\n##\r\nAND\t\t\t= Y\t\t\t\t\t##\tDevuelve VERDADERO si todos sus argumentos son VERDADERO.\r\nFALSE\t\t\t= FALSO\t\t\t\t\t##\tDevuelve el valor lógico FALSO.\r\nIF\t\t\t= SI\t\t\t\t\t##\tEspecifica una prueba lógica que realizar.\r\nIFERROR\t\t\t= SI.ERROR\t\t\t\t##\tDevuelve un valor que se especifica si una fórmula lo evalúa como un error; de lo contrario, devuelve el resultado de la fórmula.\r\nNOT\t\t\t= NO\t\t\t\t\t##\tInvierte el valor lógico del argumento.\r\nOR\t\t\t= O\t\t\t\t\t##\tDevuelve VERDADERO si cualquier argumento es VERDADERO.\r\nTRUE\t\t\t= VERDADERO\t\t\t\t##\tDevuelve el valor lógico VERDADERO.\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\t\tFunciones de búsqueda y referencia\r\n##\r\nADDRESS\t\t\t= DIRECCION\t\t\t\t##\tDevuelve una referencia como texto a una sola celda de una hoja de cálculo.\r\nAREAS\t\t\t= AREAS\t\t\t\t\t##\tDevuelve el número de áreas de una referencia.\r\nCHOOSE\t\t\t= ELEGIR\t\t\t\t##\tElige un valor de una lista de valores.\r\nCOLUMN\t\t\t= COLUMNA\t\t\t\t##\tDevuelve el número de columna de una referencia.\r\nCOLUMNS\t\t\t= COLUMNAS\t\t\t\t##\tDevuelve el número de columnas de una referencia.\r\nHLOOKUP\t\t\t= BUSCARH\t\t\t\t##\tBusca en la fila superior de una matriz y devuelve el valor de la celda indicada.\r\nHYPERLINK\t\t= HIPERVINCULO\t\t\t\t##\tCrea un acceso directo o un salto que abre un documento almacenado en un servidor de red, en una intranet o en Internet.\r\nINDEX\t\t\t= INDICE\t\t\t\t##\tUsa un índice para elegir un valor de una referencia o matriz.\r\nINDIRECT\t\t= INDIRECTO\t\t\t\t##\tDevuelve una referencia indicada por un valor de texto.\r\nLOOKUP\t\t\t= BUSCAR\t\t\t\t##\tBusca valores de un vector o una matriz.\r\nMATCH\t\t\t= COINCIDIR\t\t\t\t##\tBusca valores de una referencia o matriz.\r\nOFFSET\t\t\t= DESREF\t\t\t\t##\tDevuelve un desplazamiento de referencia respecto a una referencia dada.\r\nROW\t\t\t= FILA\t\t\t\t\t##\tDevuelve el número de fila de una referencia.\r\nROWS\t\t\t= FILAS\t\t\t\t\t##\tDevuelve el número de filas de una referencia.\r\nRTD\t\t\t= RDTR\t\t\t\t\t##\tRecupera datos en tiempo real desde un programa compatible con la automatización COM (automatización: modo de trabajar con los objetos de una aplicación desde otra aplicación o herramienta de entorno. La automatización, antes denominada automatización OLE, es un estándar de la industria y una función del Modelo de objetos componentes (COM).).\r\nTRANSPOSE\t\t= TRANSPONER\t\t\t\t##\tDevuelve la transposición de una matriz.\r\nVLOOKUP\t\t\t= BUSCARV\t\t\t\t##\tBusca en la primera columna de una matriz y se mueve en horizontal por la fila para devolver el valor de una celda.\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\t\tFunciones matemáticas y trigonométricas\r\n##\r\nABS\t\t\t= ABS\t\t\t\t\t##\tDevuelve el valor absoluto de un número.\r\nACOS\t\t\t= ACOS\t\t\t\t\t##\tDevuelve el arcocoseno de un número.\r\nACOSH\t\t\t= ACOSH\t\t\t\t\t##\tDevuelve el coseno hiperbólico inverso de un número.\r\nASIN\t\t\t= ASENO\t\t\t\t\t##\tDevuelve el arcoseno de un número.\r\nASINH\t\t\t= ASENOH\t\t\t\t##\tDevuelve el seno hiperbólico inverso de un número.\r\nATAN\t\t\t= ATAN\t\t\t\t\t##\tDevuelve la arcotangente de un número.\r\nATAN2\t\t\t= ATAN2\t\t\t\t\t##\tDevuelve la arcotangente de las coordenadas \"x\" e \"y\".\r\nATANH\t\t\t= ATANH\t\t\t\t\t##\tDevuelve la tangente hiperbólica inversa de un número.\r\nCEILING\t\t\t= MULTIPLO.SUPERIOR\t\t\t##\tRedondea un número al entero más próximo o al múltiplo significativo más cercano.\r\nCOMBIN\t\t\t= COMBINAT\t\t\t\t##\tDevuelve el número de combinaciones para un número determinado de objetos.\r\nCOS\t\t\t= COS\t\t\t\t\t##\tDevuelve el coseno de un número.\r\nCOSH\t\t\t= COSH\t\t\t\t\t##\tDevuelve el coseno hiperbólico de un número.\r\nDEGREES\t\t\t= GRADOS\t\t\t\t##\tConvierte radianes en grados.\r\nEVEN\t\t\t= REDONDEA.PAR\t\t\t\t##\tRedondea un número hasta el entero par más próximo.\r\nEXP\t\t\t= EXP\t\t\t\t\t##\tDevuelve e elevado a la potencia de un número dado.\r\nFACT\t\t\t= FACT\t\t\t\t\t##\tDevuelve el factorial de un número.\r\nFACTDOUBLE\t\t= FACT.DOBLE\t\t\t\t##\tDevuelve el factorial doble de un número.\r\nFLOOR\t\t\t= MULTIPLO.INFERIOR\t\t\t##\tRedondea un número hacia abajo, en dirección hacia cero.\r\nGCD\t\t\t= M.C.D\t\t\t\t\t##\tDevuelve el máximo común divisor.\r\nINT\t\t\t= ENTERO\t\t\t\t##\tRedondea un número hacia abajo hasta el entero más próximo.\r\nLCM\t\t\t= M.C.M\t\t\t\t\t##\tDevuelve el mínimo común múltiplo.\r\nLN\t\t\t= LN\t\t\t\t\t##\tDevuelve el logaritmo natural (neperiano) de un número.\r\nLOG\t\t\t= LOG\t\t\t\t\t##\tDevuelve el logaritmo de un número en una base especificada.\r\nLOG10\t\t\t= LOG10\t\t\t\t\t##\tDevuelve el logaritmo en base 10 de un número.\r\nMDETERM\t\t\t= MDETERM\t\t\t\t##\tDevuelve la determinante matricial de una matriz.\r\nMINVERSE\t\t= MINVERSA\t\t\t\t##\tDevuelve la matriz inversa de una matriz.\r\nMMULT\t\t\t= MMULT\t\t\t\t\t##\tDevuelve el producto de matriz de dos matrices.\r\nMOD\t\t\t= RESIDUO\t\t\t\t##\tDevuelve el resto de la división.\r\nMROUND\t\t\t= REDOND.MULT\t\t\t\t##\tDevuelve un número redondeado al múltiplo deseado.\r\nMULTINOMIAL\t\t= MULTINOMIAL\t\t\t\t##\tDevuelve el polinomio de un conjunto de números.\r\nODD\t\t\t= REDONDEA.IMPAR\t\t\t##\tRedondea un número hacia arriba hasta el entero impar más próximo.\r\nPI\t\t\t= PI\t\t\t\t\t##\tDevuelve el valor de pi.\r\nPOWER\t\t\t= POTENCIA\t\t\t\t##\tDevuelve el resultado de elevar un número a una potencia.\r\nPRODUCT\t\t\t= PRODUCTO\t\t\t\t##\tMultiplica sus argumentos.\r\nQUOTIENT\t\t= COCIENTE\t\t\t\t##\tDevuelve la parte entera de una división.\r\nRADIANS\t\t\t= RADIANES\t\t\t\t##\tConvierte grados en radianes.\r\nRAND\t\t\t= ALEATORIO\t\t\t\t##\tDevuelve un número aleatorio entre 0 y 1.\r\nRANDBETWEEN\t\t= ALEATORIO.ENTRE\t\t\t##\tDevuelve un número aleatorio entre los números que especifique.\r\nROMAN\t\t\t= NUMERO.ROMANO\t\t\t\t##\tConvierte un número arábigo en número romano, con formato de texto.\r\nROUND\t\t\t= REDONDEAR\t\t\t\t##\tRedondea un número al número de decimales especificado.\r\nROUNDDOWN\t\t= REDONDEAR.MENOS\t\t\t##\tRedondea un número hacia abajo, en dirección hacia cero.\r\nROUNDUP\t\t\t= REDONDEAR.MAS\t\t\t\t##\tRedondea un número hacia arriba, en dirección contraria a cero.\r\nSERIESSUM\t\t= SUMA.SERIES\t\t\t\t##\tDevuelve la suma de una serie de potencias en función de la fórmula.\r\nSIGN\t\t\t= SIGNO\t\t\t\t\t##\tDevuelve el signo de un número.\r\nSIN\t\t\t= SENO\t\t\t\t\t##\tDevuelve el seno de un ángulo determinado.\r\nSINH\t\t\t= SENOH\t\t\t\t\t##\tDevuelve el seno hiperbólico de un número.\r\nSQRT\t\t\t= RAIZ\t\t\t\t\t##\tDevuelve la raíz cuadrada positiva de un número.\r\nSQRTPI\t\t\t= RAIZ2PI\t\t\t\t##\tDevuelve la raíz cuadrada de un número multiplicado por PI (número * pi).\r\nSUBTOTAL\t\t= SUBTOTALES\t\t\t\t##\tDevuelve un subtotal en una lista o base de datos.\r\nSUM\t\t\t= SUMA\t\t\t\t\t##\tSuma sus argumentos.\r\nSUMIF\t\t\t= SUMAR.SI\t\t\t\t##\tSuma las celdas especificadas que cumplen unos criterios determinados.\r\nSUMIFS\t\t\t= SUMAR.SI.CONJUNTO\t\t\t##\tSuma las celdas de un rango que cumplen varios criterios.\r\nSUMPRODUCT\t\t= SUMAPRODUCTO\t\t\t\t##\tDevuelve la suma de los productos de los correspondientes componentes de matriz.\r\nSUMSQ\t\t\t= SUMA.CUADRADOS\t\t\t##\tDevuelve la suma de los cuadrados de los argumentos.\r\nSUMX2MY2\t\t= SUMAX2MENOSY2\t\t\t\t##\tDevuelve la suma de la diferencia de los cuadrados de los valores correspondientes de dos matrices.\r\nSUMX2PY2\t\t= SUMAX2MASY2\t\t\t\t##\tDevuelve la suma de la suma de los cuadrados de los valores correspondientes de dos matrices.\r\nSUMXMY2\t\t\t= SUMAXMENOSY2\t\t\t\t##\tDevuelve la suma de los cuadrados de las diferencias de los valores correspondientes de dos matrices.\r\nTAN\t\t\t= TAN\t\t\t\t\t##\tDevuelve la tangente de un número.\r\nTANH\t\t\t= TANH\t\t\t\t\t##\tDevuelve la tangente hiperbólica de un número.\r\nTRUNC\t\t\t= TRUNCAR\t\t\t\t##\tTrunca un número a un entero.\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\t\tFunciones estadísticas\r\n##\r\nAVEDEV\t\t\t= DESVPROM\t\t\t\t##\tDevuelve el promedio de las desviaciones absolutas de la media de los puntos de datos.\r\nAVERAGE\t\t\t= PROMEDIO\t\t\t\t##\tDevuelve el promedio de sus argumentos.\r\nAVERAGEA\t\t= PROMEDIOA\t\t\t\t##\tDevuelve el promedio de sus argumentos, incluidos números, texto y valores lógicos.\r\nAVERAGEIF\t\t= PROMEDIO.SI\t\t\t\t##\tDevuelve el promedio (media aritmética) de todas las celdas de un rango que cumplen unos criterios determinados.\r\nAVERAGEIFS\t\t= PROMEDIO.SI.CONJUNTO\t\t\t##\tDevuelve el promedio (media aritmética) de todas las celdas que cumplen múltiples criterios.\r\nBETADIST\t\t= DISTR.BETA\t\t\t\t##\tDevuelve la función de distribución beta acumulativa.\r\nBETAINV\t\t\t= DISTR.BETA.INV\t\t\t##\tDevuelve la función inversa de la función de distribución acumulativa de una distribución beta especificada.\r\nBINOMDIST\t\t= DISTR.BINOM\t\t\t\t##\tDevuelve la probabilidad de una variable aleatoria discreta siguiendo una distribución binomial.\r\nCHIDIST\t\t\t= DISTR.CHI\t\t\t\t##\tDevuelve la probabilidad de una variable aleatoria continua siguiendo una distribución chi cuadrado de una sola cola.\r\nCHIINV\t\t\t= PRUEBA.CHI.INV\t\t\t##\tDevuelve la función inversa de la probabilidad de una variable aleatoria continua siguiendo una distribución chi cuadrado de una sola cola.\r\nCHITEST\t\t\t= PRUEBA.CHI\t\t\t\t##\tDevuelve la prueba de independencia.\r\nCONFIDENCE\t\t= INTERVALO.CONFIANZA\t\t\t##\tDevuelve el intervalo de confianza de la media de una población.\r\nCORREL\t\t\t= COEF.DE.CORREL\t\t\t##\tDevuelve el coeficiente de correlación entre dos conjuntos de datos.\r\nCOUNT\t\t\t= CONTAR\t\t\t\t##\tCuenta cuántos números hay en la lista de argumentos.\r\nCOUNTA\t\t\t= CONTARA\t\t\t\t##\tCuenta cuántos valores hay en la lista de argumentos.\r\nCOUNTBLANK\t\t= CONTAR.BLANCO\t\t\t\t##\tCuenta el número de celdas en blanco de un rango.\r\nCOUNTIF\t\t\t= CONTAR.SI\t\t\t\t##\tCuenta el número de celdas, dentro del rango, que cumplen el criterio especificado.\r\nCOUNTIFS\t\t= CONTAR.SI.CONJUNTO\t\t\t##\tCuenta el número de celdas, dentro del rango, que cumplen varios criterios.\r\nCOVAR\t\t\t= COVAR\t\t\t\t\t##\tDevuelve la covarianza, que es el promedio de los productos de las desviaciones para cada pareja de puntos de datos.\r\nCRITBINOM\t\t= BINOM.CRIT\t\t\t\t##\tDevuelve el menor valor cuya distribución binomial acumulativa es menor o igual a un valor de criterio.\r\nDEVSQ\t\t\t= DESVIA2\t\t\t\t##\tDevuelve la suma de los cuadrados de las desviaciones.\r\nEXPONDIST\t\t= DISTR.EXP\t\t\t\t##\tDevuelve la distribución exponencial.\r\nFDIST\t\t\t= DISTR.F\t\t\t\t##\tDevuelve la distribución de probabilidad F.\r\nFINV\t\t\t= DISTR.F.INV\t\t\t\t##\tDevuelve la función inversa de la distribución de probabilidad F.\r\nFISHER\t\t\t= FISHER\t\t\t\t##\tDevuelve la transformación Fisher.\r\nFISHERINV\t\t= PRUEBA.FISHER.INV\t\t\t##\tDevuelve la función inversa de la transformación Fisher.\r\nFORECAST\t\t= PRONOSTICO\t\t\t\t##\tDevuelve un valor en una tendencia lineal.\r\nFREQUENCY\t\t= FRECUENCIA\t\t\t\t##\tDevuelve una distribución de frecuencia como una matriz vertical.\r\nFTEST\t\t\t= PRUEBA.F\t\t\t\t##\tDevuelve el resultado de una prueba F.\r\nGAMMADIST\t\t= DISTR.GAMMA\t\t\t\t##\tDevuelve la distribución gamma.\r\nGAMMAINV\t\t= DISTR.GAMMA.INV\t\t\t##\tDevuelve la función inversa de la distribución gamma acumulativa.\r\nGAMMALN\t\t\t= GAMMA.LN\t\t\t\t##\tDevuelve el logaritmo natural de la función gamma, G(x).\r\nGEOMEAN\t\t\t= MEDIA.GEOM\t\t\t\t##\tDevuelve la media geométrica.\r\nGROWTH\t\t\t= CRECIMIENTO\t\t\t\t##\tDevuelve valores en una tendencia exponencial.\r\nHARMEAN\t\t\t= MEDIA.ARMO\t\t\t\t##\tDevuelve la media armónica.\r\nHYPGEOMDIST\t\t= DISTR.HIPERGEOM\t\t\t##\tDevuelve la distribución hipergeométrica.\r\nINTERCEPT\t\t= INTERSECCION.EJE\t\t\t##\tDevuelve la intersección de la línea de regresión lineal.\r\nKURT\t\t\t= CURTOSIS\t\t\t\t##\tDevuelve la curtosis de un conjunto de datos.\r\nLARGE\t\t\t= K.ESIMO.MAYOR\t\t\t\t##\tDevuelve el k-ésimo mayor valor de un conjunto de datos.\r\nLINEST\t\t\t= ESTIMACION.LINEAL\t\t\t##\tDevuelve los parámetros de una tendencia lineal.\r\nLOGEST\t\t\t= ESTIMACION.LOGARITMICA\t\t##\tDevuelve los parámetros de una tendencia exponencial.\r\nLOGINV\t\t\t= DISTR.LOG.INV\t\t\t\t##\tDevuelve la función inversa de la distribución logarítmico-normal.\r\nLOGNORMDIST\t\t= DISTR.LOG.NORM\t\t\t##\tDevuelve la distribución logarítmico-normal acumulativa.\r\nMAX\t\t\t= MAX\t\t\t\t\t##\tDevuelve el valor máximo de una lista de argumentos.\r\nMAXA\t\t\t= MAXA\t\t\t\t\t##\tDevuelve el valor máximo de una lista de argumentos, incluidos números, texto y valores lógicos.\r\nMEDIAN\t\t\t= MEDIANA\t\t\t\t##\tDevuelve la mediana de los números dados.\r\nMIN\t\t\t= MIN\t\t\t\t\t##\tDevuelve el valor mínimo de una lista de argumentos.\r\nMINA\t\t\t= MINA\t\t\t\t\t##\tDevuelve el valor mínimo de una lista de argumentos, incluidos números, texto y valores lógicos.\r\nMODE\t\t\t= MODA\t\t\t\t\t##\tDevuelve el valor más común de un conjunto de datos.\r\nNEGBINOMDIST\t\t= NEGBINOMDIST\t\t\t\t##\tDevuelve la distribución binomial negativa.\r\nNORMDIST\t\t= DISTR.NORM\t\t\t\t##\tDevuelve la distribución normal acumulativa.\r\nNORMINV\t\t\t= DISTR.NORM.INV\t\t\t##\tDevuelve la función inversa de la distribución normal acumulativa.\r\nNORMSDIST\t\t= DISTR.NORM.ESTAND\t\t\t##\tDevuelve la distribución normal estándar acumulativa.\r\nNORMSINV\t\t= DISTR.NORM.ESTAND.INV\t\t\t##\tDevuelve la función inversa de la distribución normal estándar acumulativa.\r\nPEARSON\t\t\t= PEARSON\t\t\t\t##\tDevuelve el coeficiente de momento de correlación de producto Pearson.\r\nPERCENTILE\t\t= PERCENTIL\t\t\t\t##\tDevuelve el k-ésimo percentil de los valores de un rango.\r\nPERCENTRANK\t\t= RANGO.PERCENTIL\t\t\t##\tDevuelve el rango porcentual de un valor de un conjunto de datos.\r\nPERMUT\t\t\t= PERMUTACIONES\t\t\t\t##\tDevuelve el número de permutaciones de un número determinado de objetos.\r\nPOISSON\t\t\t= POISSON\t\t\t\t##\tDevuelve la distribución de Poisson.\r\nPROB\t\t\t= PROBABILIDAD\t\t\t\t##\tDevuelve la probabilidad de que los valores de un rango se encuentren entre dos límites.\r\nQUARTILE\t\t= CUARTIL\t\t\t\t##\tDevuelve el cuartil de un conjunto de datos.\r\nRANK\t\t\t= JERARQUIA\t\t\t\t##\tDevuelve la jerarquía de un número en una lista de números.\r\nRSQ\t\t\t= COEFICIENTE.R2\t\t\t##\tDevuelve el cuadrado del coeficiente de momento de correlación de producto Pearson.\r\nSKEW\t\t\t= COEFICIENTE.ASIMETRIA\t\t\t##\tDevuelve la asimetría de una distribución.\r\nSLOPE\t\t\t= PENDIENTE\t\t\t\t##\tDevuelve la pendiente de la línea de regresión lineal.\r\nSMALL\t\t\t= K.ESIMO.MENOR\t\t\t\t##\tDevuelve el k-ésimo menor valor de un conjunto de datos.\r\nSTANDARDIZE\t\t= NORMALIZACION\t\t\t\t##\tDevuelve un valor normalizado.\r\nSTDEV\t\t\t= DESVEST\t\t\t\t##\tCalcula la desviación estándar a partir de una muestra.\r\nSTDEVA\t\t\t= DESVESTA\t\t\t\t##\tCalcula la desviación estándar a partir de una muestra, incluidos números, texto y valores lógicos.\r\nSTDEVP\t\t\t= DESVESTP\t\t\t\t##\tCalcula la desviación estándar en función de toda la población.\r\nSTDEVPA\t\t\t= DESVESTPA\t\t\t\t##\tCalcula la desviación estándar en función de toda la población, incluidos números, texto y valores lógicos.\r\nSTEYX\t\t\t= ERROR.TIPICO.XY\t\t\t##\tDevuelve el error estándar del valor de \"y\" previsto para cada \"x\" de la regresión.\r\nTDIST\t\t\t= DISTR.T\t\t\t\t##\tDevuelve la distribución de t de Student.\r\nTINV\t\t\t= DISTR.T.INV\t\t\t\t##\tDevuelve la función inversa de la distribución de t de Student.\r\nTREND\t\t\t= TENDENCIA\t\t\t\t##\tDevuelve valores en una tendencia lineal.\r\nTRIMMEAN\t\t= MEDIA.ACOTADA\t\t\t\t##\tDevuelve la media del interior de un conjunto de datos.\r\nTTEST\t\t\t= PRUEBA.T\t\t\t\t##\tDevuelve la probabilidad asociada a una prueba t de Student.\r\nVAR\t\t\t= VAR\t\t\t\t\t##\tCalcula la varianza en función de una muestra.\r\nVARA\t\t\t= VARA\t\t\t\t\t##\tCalcula la varianza en función de una muestra, incluidos números, texto y valores lógicos.\r\nVARP\t\t\t= VARP\t\t\t\t\t##\tCalcula la varianza en función de toda la población.\r\nVARPA\t\t\t= VARPA\t\t\t\t\t##\tCalcula la varianza en función de toda la población, incluidos números, texto y valores lógicos.\r\nWEIBULL\t\t\t= DIST.WEIBULL\t\t\t\t##\tDevuelve la distribución de Weibull.\r\nZTEST\t\t\t= PRUEBA.Z\t\t\t\t##\tDevuelve el valor de una probabilidad de una cola de una prueba z.\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\t\tFunciones de texto\r\n##\r\nASC\t\t\t= ASC\t\t\t\t\t##\tConvierte las letras inglesas o katakana de ancho completo (de dos bytes) dentro de una cadena de caracteres en caracteres de ancho medio (de un byte).\r\nBAHTTEXT\t\t= TEXTOBAHT\t\t\t\t##\tConvierte un número en texto, con el formato de moneda ß (Baht).\r\nCHAR\t\t\t= CARACTER\t\t\t\t##\tDevuelve el carácter especificado por el número de código.\r\nCLEAN\t\t\t= LIMPIAR\t\t\t\t##\tQuita del texto todos los caracteres no imprimibles.\r\nCODE\t\t\t= CODIGO\t\t\t\t##\tDevuelve un código numérico del primer carácter de una cadena de texto.\r\nCONCATENATE\t\t= CONCATENAR\t\t\t\t##\tConcatena varios elementos de texto en uno solo.\r\nDOLLAR\t\t\t= MONEDA\t\t\t\t##\tConvierte un número en texto, con el formato de moneda $ (dólar).\r\nEXACT\t\t\t= IGUAL\t\t\t\t\t##\tComprueba si dos valores de texto son idénticos.\r\nFIND\t\t\t= ENCONTRAR\t\t\t\t##\tBusca un valor de texto dentro de otro (distingue mayúsculas de minúsculas).\r\nFINDB\t\t\t= ENCONTRARB\t\t\t\t##\tBusca un valor de texto dentro de otro (distingue mayúsculas de minúsculas).\r\nFIXED\t\t\t= DECIMAL\t\t\t\t##\tDa formato a un número como texto con un número fijo de decimales.\r\nJIS\t\t\t= JIS\t\t\t\t\t##\tConvierte las letras inglesas o katakana de ancho medio (de un byte) dentro de una cadena de caracteres en caracteres de ancho completo (de dos bytes).\r\nLEFT\t\t\t= IZQUIERDA\t\t\t\t##\tDevuelve los caracteres del lado izquierdo de un valor de texto.\r\nLEFTB\t\t\t= IZQUIERDAB\t\t\t\t##\tDevuelve los caracteres del lado izquierdo de un valor de texto.\r\nLEN\t\t\t= LARGO\t\t\t\t\t##\tDevuelve el número de caracteres de una cadena de texto.\r\nLENB\t\t\t= LARGOB\t\t\t\t##\tDevuelve el número de caracteres de una cadena de texto.\r\nLOWER\t\t\t= MINUSC\t\t\t\t##\tPone el texto en minúsculas.\r\nMID\t\t\t= EXTRAE\t\t\t\t##\tDevuelve un número específico de caracteres de una cadena de texto que comienza en la posición que se especifique.\r\nMIDB\t\t\t= EXTRAEB\t\t\t\t##\tDevuelve un número específico de caracteres de una cadena de texto que comienza en la posición que se especifique.\r\nPHONETIC\t\t= FONETICO\t\t\t\t##\tExtrae los caracteres fonéticos (furigana) de una cadena de texto.\r\nPROPER\t\t\t= NOMPROPIO\t\t\t\t##\tPone en mayúscula la primera letra de cada palabra de un valor de texto.\r\nREPLACE\t\t\t= REEMPLAZAR\t\t\t\t##\tReemplaza caracteres de texto.\r\nREPLACEB\t\t= REEMPLAZARB\t\t\t\t##\tReemplaza caracteres de texto.\r\nREPT\t\t\t= REPETIR\t\t\t\t##\tRepite el texto un número determinado de veces.\r\nRIGHT\t\t\t= DERECHA\t\t\t\t##\tDevuelve los caracteres del lado derecho de un valor de texto.\r\nRIGHTB\t\t\t= DERECHAB\t\t\t\t##\tDevuelve los caracteres del lado derecho de un valor de texto.\r\nSEARCH\t\t\t= HALLAR\t\t\t\t##\tBusca un valor de texto dentro de otro (no distingue mayúsculas de minúsculas).\r\nSEARCHB\t\t\t= HALLARB\t\t\t\t##\tBusca un valor de texto dentro de otro (no distingue mayúsculas de minúsculas).\r\nSUBSTITUTE\t\t= SUSTITUIR\t\t\t\t##\tSustituye texto nuevo por texto antiguo en una cadena de texto.\r\nT\t\t\t= T\t\t\t\t\t##\tConvierte sus argumentos a texto.\r\nTEXT\t\t\t= TEXTO\t\t\t\t\t##\tDa formato a un número y lo convierte en texto.\r\nTRIM\t\t\t= ESPACIOS\t\t\t\t##\tQuita los espacios del texto.\r\nUPPER\t\t\t= MAYUSC\t\t\t\t##\tPone el texto en mayúsculas.\r\nVALUE\t\t\t= VALOR\t\t\t\t\t##\tConvierte un argumento de texto en un número.\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= $\t#\tSymbol not known, should it be a € (Euro)?\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #TYHJÄ!\r\nDIV0\t= #JAKO/0!\r\nVALUE\t= #ARVO!\r\nREF\t= #VIITTAUS!\r\nNAME\t= #NIMI?\r\nNUM\t= #LUKU!\r\nNA\t= #PUUTTUU\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/fi/functions",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Calculation\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/\r\n##\r\n##\r\n\r\n\r\n##\r\n##\tAdd-in and Automation functions\t\t\tApuohjelma- ja automaatiofunktiot\r\n##\r\nGETPIVOTDATA\t\t= NOUDA.PIVOT.TIEDOT\t\t##\tPalauttaa pivot-taulukkoraporttiin tallennettuja tietoja.\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\tKuutiofunktiot\r\n##\r\nCUBEKPIMEMBER\t\t= KUUTIOKPIJÄSEN\t\t##\tPalauttaa suorituskykyilmaisimen (KPI) nimen, ominaisuuden sekä mitan ja näyttää nimen sekä ominaisuuden solussa. KPI on mitattavissa oleva suure, kuten kuukauden bruttotuotto tai vuosineljänneksen työntekijäkohtainen liikevaihto, joiden avulla tarkkaillaan organisaation suorituskykyä.\r\nCUBEMEMBER\t\t= KUUTIONJÄSEN\t\t\t##\tPalauttaa kuutiohierarkian jäsenen tai monikon. Tällä funktiolla voit tarkistaa, että jäsen tai monikko on olemassa kuutiossa.\r\nCUBEMEMBERPROPERTY\t= KUUTIONJÄSENENOMINAISUUS\t##\tPalauttaa kuution jäsenominaisuuden arvon. Tällä funktiolla voit tarkistaa, että nimi on olemassa kuutiossa, ja palauttaa tämän jäsenen määritetyn ominaisuuden.\r\nCUBERANKEDMEMBER\t= KUUTIONLUOKITELTUJÄSEN\t##\tPalauttaa joukon n:nnen jäsenen. Tällä funktiolla voit palauttaa joukosta elementtejä, kuten parhaan myyjän tai 10 parasta opiskelijaa.\r\nCUBESET\t\t\t= KUUTIOJOUKKO\t\t\t##\tMäärittää lasketun jäsen- tai monikkojoukon lähettämällä joukon lausekkeita palvelimessa olevalle kuutiolle. Palvelin luo joukon ja palauttaa sen Microsoft Office Excelille.\r\nCUBESETCOUNT\t\t= KUUTIOJOUKKOJENMÄÄRÄ\t\t##\tPalauttaa joukon kohteiden määrän.\r\nCUBEVALUE\t\t= KUUTIONARVO\t\t\t##\tPalauttaa koostetun arvon kuutiosta.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\tTietokantafunktiot\r\n##\r\nDAVERAGE\t\t= TKESKIARVO\t\t\t##\tPalauttaa valittujen tietokantamerkintöjen keskiarvon.\r\nDCOUNT\t\t\t= TLASKE\t\t\t##\tLaskee tietokannan lukuja sisältävien solujen määrän.\r\nDCOUNTA\t\t\t= TLASKEA\t\t\t##\tLaskee tietokannan tietoja sisältävien solujen määrän.\r\nDGET\t\t\t= TNOUDA\t\t\t##\tHakee määritettyjä ehtoja vastaavan tietueen tietokannasta.\r\nDMAX\t\t\t= TMAKS\t\t\t\t##\tPalauttaa suurimman arvon tietokannasta valittujen arvojen joukosta.\r\nDMIN\t\t\t= TMIN\t\t\t\t##\tPalauttaa pienimmän arvon tietokannasta valittujen arvojen joukosta.\r\nDPRODUCT\t\t= TTULO\t\t\t\t##\tKertoo määritetyn ehdon täyttävien tietokannan tietueiden tietyssä kentässä olevat arvot.\r\nDSTDEV\t\t\t= TKESKIHAJONTA\t\t\t##\tLaskee keskihajonnan tietokannasta valituista arvoista muodostuvan otoksen perusteella.\r\nDSTDEVP\t\t\t= TKESKIHAJONTAP\t\t##\tLaskee keskihajonnan tietokannasta valittujen arvojen koko populaation perusteella.\r\nDSUM\t\t\t= TSUMMA\t\t\t##\tLisää luvut määritetyn ehdon täyttävien tietokannan tietueiden kenttäsarakkeeseen.\r\nDVAR\t\t\t= TVARIANSSI\t\t\t##\tLaskee varianssin tietokannasta valittujen arvojen otoksen perusteella.\r\nDVARP\t\t\t= TVARIANSSIP\t\t\t##\tLaskee varianssin tietokannasta valittujen arvojen koko populaation perusteella.\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\tPäivämäärä- ja aikafunktiot\r\n##\r\nDATE\t\t\t= PÄIVÄYS\t\t\t##\tPalauttaa annetun päivämäärän järjestysluvun.\r\nDATEVALUE\t\t= PÄIVÄYSARVO\t\t\t##\tMuuntaa tekstimuodossa olevan päivämäärän järjestysluvuksi.\r\nDAY\t\t\t= PÄIVÄ\t\t\t\t##\tMuuntaa järjestysluvun kuukauden päiväksi.\r\nDAYS360\t\t\t= PÄIVÄT360\t\t\t##\tLaskee kahden päivämäärän välisten päivien määrän käyttäen perustana 360-päiväistä vuotta.\r\nEDATE\t\t\t= PÄIVÄ.KUUKAUSI\t\t##\tPalauttaa järjestyslukuna päivämäärän, joka poikkeaa aloituspäivän päivämäärästä annetun kuukausimäärän verran joko eteen- tai taaksepäin.\r\nEOMONTH\t\t\t= KUUKAUSI.LOPPU\t\t##\tPalauttaa järjestyslukuna sen kuukauden viimeisen päivämäärän, joka poikkeaa annetun kuukausimäärän verran eteen- tai taaksepäin.\r\nHOUR\t\t\t= TUNNIT\t\t\t##\tMuuntaa järjestysluvun tunneiksi.\r\nMINUTE\t\t\t= MINUUTIT\t\t\t##\tMuuntaa järjestysluvun minuuteiksi.\r\nMONTH\t\t\t= KUUKAUSI\t\t\t##\tMuuntaa järjestysluvun kuukausiksi.\r\nNETWORKDAYS\t\t= TYÖPÄIVÄT\t\t\t##\tPalauttaa kahden päivämäärän välissä olevien täysien työpäivien määrän.\r\nNOW\t\t\t= NYT\t\t\t\t##\tPalauttaa kuluvan päivämäärän ja ajan järjestysnumeron.\r\nSECOND\t\t\t= SEKUNNIT\t\t\t##\tMuuntaa järjestysluvun sekunneiksi.\r\nTIME\t\t\t= AIKA\t\t\t\t##\tPalauttaa annetun kellonajan järjestysluvun.\r\nTIMEVALUE\t\t= AIKA_ARVO\t\t\t##\tMuuntaa tekstimuodossa olevan kellonajan järjestysluvuksi.\r\nTODAY\t\t\t= TÄMÄ.PÄIVÄ\t\t\t##\tPalauttaa kuluvan päivän päivämäärän järjestysluvun.\r\nWEEKDAY\t\t\t= VIIKONPÄIVÄ\t\t\t##\tMuuntaa järjestysluvun viikonpäiväksi.\r\nWEEKNUM\t\t\t= VIIKKO.NRO\t\t\t##\tMuuntaa järjestysluvun luvuksi, joka ilmaisee viikon järjestysluvun vuoden alusta laskettuna.\r\nWORKDAY\t\t\t= TYÖPÄIVÄ\t\t\t##\tPalauttaa järjestysluvun päivämäärälle, joka sijaitsee annettujen työpäivien verran eteen tai taaksepäin.\r\nYEAR\t\t\t= VUOSI\t\t\t\t##\tMuuntaa järjestysluvun vuosiksi.\r\nYEARFRAC\t\t= VUOSI.OSA\t\t\t##\tPalauttaa määritettyjen päivämäärien (aloituspäivä ja lopetuspäivä) välisen osan vuodesta.\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\tTekniset funktiot\r\n##\r\nBESSELI\t\t\t= BESSELI\t\t\t##\tPalauttaa muunnetun Bessel-funktion In(x).\r\nBESSELJ\t\t\t= BESSELJ\t\t\t##\tPalauttaa Bessel-funktion Jn(x).\r\nBESSELK\t\t\t= BESSELK\t\t\t##\tPalauttaa muunnetun Bessel-funktion Kn(x).\r\nBESSELY\t\t\t= BESSELY\t\t\t##\tPalauttaa Bessel-funktion Yn(x).\r\nBIN2DEC\t\t\t= BINDES\t\t\t##\tMuuntaa binaariluvun desimaaliluvuksi.\r\nBIN2HEX\t\t\t= BINHEKSA\t\t\t##\tMuuntaa binaariluvun heksadesimaaliluvuksi.\r\nBIN2OCT\t\t\t= BINOKT\t\t\t##\tMuuntaa binaariluvun oktaaliluvuksi.\r\nCOMPLEX\t\t\t= KOMPLEKSI\t\t\t##\tMuuntaa reaali- ja imaginaariosien kertoimet kompleksiluvuksi.\r\nCONVERT\t\t\t= MUUNNA\t\t\t##\tMuuntaa luvun toisen mittajärjestelmän mukaiseksi.\r\nDEC2BIN\t\t\t= DESBIN\t\t\t##\tMuuntaa desimaaliluvun binaariluvuksi.\r\nDEC2HEX\t\t\t= DESHEKSA\t\t\t##\tMuuntaa kymmenjärjestelmän luvun heksadesimaaliluvuksi.\r\nDEC2OCT\t\t\t= DESOKT\t\t\t##\tMuuntaa kymmenjärjestelmän luvun oktaaliluvuksi.\r\nDELTA\t\t\t= SAMA.ARVO\t\t\t##\tTarkistaa, ovatko kaksi arvoa yhtä suuria.\r\nERF\t\t\t= VIRHEFUNKTIO\t\t\t##\tPalauttaa virhefunktion.\r\nERFC\t\t\t= VIRHEFUNKTIO.KOMPLEMENTTI\t##\tPalauttaa komplementtivirhefunktion.\r\nGESTEP\t\t\t= RAJA\t\t\t\t##\tTestaa, onko luku suurempi kuin kynnysarvo.\r\nHEX2BIN\t\t\t= HEKSABIN\t\t\t##\tMuuntaa heksadesimaaliluvun binaariluvuksi.\r\nHEX2DEC\t\t\t= HEKSADES\t\t\t##\tMuuntaa heksadesimaaliluvun desimaaliluvuksi.\r\nHEX2OCT\t\t\t= HEKSAOKT\t\t\t##\tMuuntaa heksadesimaaliluvun oktaaliluvuksi.\r\nIMABS\t\t\t= KOMPLEKSI.ITSEISARVO\t\t##\tPalauttaa kompleksiluvun itseisarvon (moduluksen).\r\nIMAGINARY\t\t= KOMPLEKSI.IMAG\t\t##\tPalauttaa kompleksiluvun imaginaariosan kertoimen.\r\nIMARGUMENT\t\t= KOMPLEKSI.ARG\t\t\t##\tPalauttaa theeta-argumentin, joka on radiaaneina annettu kulma.\r\nIMCONJUGATE\t\t= KOMPLEKSI.KONJ\t\t##\tPalauttaa kompleksiluvun konjugaattiluvun.\r\nIMCOS\t\t\t= KOMPLEKSI.COS\t\t\t##\tPalauttaa kompleksiluvun kosinin.\r\nIMDIV\t\t\t= KOMPLEKSI.OSAM\t\t##\tPalauttaa kahden kompleksiluvun osamäärän.\r\nIMEXP\t\t\t= KOMPLEKSI.EKSP\t\t##\tPalauttaa kompleksiluvun eksponentin.\r\nIMLN\t\t\t= KOMPLEKSI.LN\t\t\t##\tPalauttaa kompleksiluvun luonnollisen logaritmin.\r\nIMLOG10\t\t\t= KOMPLEKSI.LOG10\t\t##\tPalauttaa kompleksiluvun kymmenkantaisen logaritmin.\r\nIMLOG2\t\t\t= KOMPLEKSI.LOG2\t\t##\tPalauttaa kompleksiluvun kaksikantaisen logaritmin.\r\nIMPOWER\t\t\t= KOMPLEKSI.POT\t\t\t##\tPalauttaa kokonaislukupotenssiin korotetun kompleksiluvun.\r\nIMPRODUCT\t\t= KOMPLEKSI.TULO\t\t##\tPalauttaa kompleksilukujen tulon.\r\nIMREAL\t\t\t= KOMPLEKSI.REAALI\t\t##\tPalauttaa kompleksiluvun reaaliosan kertoimen.\r\nIMSIN\t\t\t= KOMPLEKSI.SIN\t\t\t##\tPalauttaa kompleksiluvun sinin.\r\nIMSQRT\t\t\t= KOMPLEKSI.NELIÖJ\t\t##\tPalauttaa kompleksiluvun neliöjuuren.\r\nIMSUB\t\t\t= KOMPLEKSI.EROTUS\t\t##\tPalauttaa kahden kompleksiluvun erotuksen.\r\nIMSUM\t\t\t= KOMPLEKSI.SUM\t\t\t##\tPalauttaa kompleksilukujen summan.\r\nOCT2BIN\t\t\t= OKTBIN\t\t\t##\tMuuntaa oktaaliluvun binaariluvuksi.\r\nOCT2DEC\t\t\t= OKTDES\t\t\t##\tMuuntaa oktaaliluvun desimaaliluvuksi.\r\nOCT2HEX\t\t\t= OKTHEKSA\t\t\t##\tMuuntaa oktaaliluvun heksadesimaaliluvuksi.\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\tRahoitusfunktiot   \r\n##\r\nACCRINT\t\t\t= KERTYNYT.KORKO\t\t##\tLaskee arvopaperille kertyneen koron, kun korko kertyy säännöllisin väliajoin.\r\nACCRINTM\t\t= KERTYNYT.KORKO.LOPUSSA\t##\tLaskee arvopaperille kertyneen koron, kun korko maksetaan eräpäivänä.\r\nAMORDEGRC\t\t= AMORDEGRC\t\t\t##\tLaskee kunkin laskentakauden poiston poistokerrointa käyttämällä.\r\nAMORLINC\t\t= AMORLINC\t\t\t##\tPalauttaa kunkin laskentakauden poiston.\r\nCOUPDAYBS\t\t= KORKOPÄIVÄT.ALUSTA\t\t##\tPalauttaa koronmaksukauden aloituspäivän ja tilityspäivän välisen ajanjakson päivien määrän.\r\nCOUPDAYS\t\t= KORKOPÄIVÄT\t\t\t##\tPalauttaa päivien määrän koronmaksukaudelta, johon tilityspäivä kuuluu.\r\nCOUPDAYSNC\t\t= KORKOPÄIVÄT.SEURAAVA\t\t##\tPalauttaa tilityspäivän ja seuraavan koronmaksupäivän välisen ajanjakson päivien määrän.\r\nCOUPNCD\t\t\t= KORKOMAKSU.SEURAAVA\t\t##\tPalauttaa tilityspäivän jälkeisen seuraavan koronmaksupäivän.\r\nCOUPNUM\t\t\t= KORKOPÄIVÄJAKSOT\t\t##\tPalauttaa arvopaperin ostopäivän ja erääntymispäivän välisten koronmaksupäivien määrän.\r\nCOUPPCD\t\t\t= KORKOPÄIVÄ.EDELLINEN\t\t##\tPalauttaa tilityspäivää edeltävän koronmaksupäivän.\r\nCUMIPMT\t\t\t= MAKSETTU.KORKO\t\t##\tPalauttaa kahden jakson välisenä aikana kertyneen koron.\r\nCUMPRINC\t\t= MAKSETTU.LYHENNYS\t\t##\tPalauttaa lainalle kahden jakson välisenä aikana kertyneen lyhennyksen.\r\nDB\t\t\t= DB\t\t\t\t##\tPalauttaa kauden kirjanpidollisen poiston amerikkalaisen DB-menetelmän (Fixed-declining balance) mukaan.\r\nDDB\t\t\t= DDB\t\t\t\t##\tPalauttaa kauden kirjanpidollisen poiston amerikkalaisen DDB-menetelmän (Double-Declining Balance) tai jonkin muun määrittämäsi menetelmän mukaan.\r\nDISC\t\t\t= DISKONTTOKORKO\t\t##\tPalauttaa arvopaperin diskonttokoron.\r\nDOLLARDE\t\t= VALUUTTA.DES\t\t\t##\tMuuntaa murtolukuna ilmoitetun valuuttamäärän desimaaliluvuksi.\r\nDOLLARFR\t\t= VALUUTTA.MURTO\t\t##\tMuuntaa desimaalilukuna ilmaistun valuuttamäärän murtoluvuksi.\r\nDURATION\t\t= KESTO\t\t\t\t##\tPalauttaa keston arvopaperille, jonka koronmaksu tapahtuu säännöllisesti.\r\nEFFECT\t\t\t= KORKO.EFEKT\t\t\t##\tPalauttaa todellisen vuosikoron.\r\nFV\t\t\t= TULEVA.ARVO\t\t\t##\tPalauttaa sijoituksen tulevan arvon.\r\nFVSCHEDULE\t\t= TULEVA.ARVO.ERIKORKO\t\t##\tPalauttaa pääoman tulevan arvon, kun pääomalle on kertynyt korkoa vaihtelevasti.\r\nINTRATE\t\t\t= KORKO.ARVOPAPERI\t\t##\tPalauttaa arvopaperin korkokannan täysin sijoitetulle arvopaperille.\r\nIPMT\t\t\t= IPMT\t\t\t\t##\tLaskee sijoitukselle tai lainalle tiettynä ajanjaksona kertyvän koron.\r\nIRR\t\t\t= SISÄINEN.KORKO\t\t##\tLaskee sisäisen korkokannan kassavirrasta muodostuvalle sarjalle.\r\nISPMT\t\t\t= ONMAKSU\t\t\t##\tLaskee sijoituksen maksetun koron tietyllä jaksolla.\r\nMDURATION\t\t= KESTO.MUUNN\t\t\t##\tPalauttaa muunnetun Macauley-keston arvopaperille, jonka oletettu nimellisarvo on 100 euroa.\r\nMIRR\t\t\t= MSISÄINEN\t\t\t##\tPalauttaa sisäisen korkokannan, kun positiivisten ja negatiivisten kassavirtojen rahoituskorko on erilainen.\r\nNOMINAL\t\t\t= KORKO.VUOSI\t\t\t##\tPalauttaa vuosittaisen nimelliskoron.\r\nNPER\t\t\t= NJAKSO\t\t\t##\tPalauttaa sijoituksen jaksojen määrän.\r\nNPV\t\t\t= NNA\t\t\t\t##\tPalauttaa sijoituksen nykyarvon toistuvista kassavirroista muodostuvan sarjan ja diskonttokoron perusteella.\r\nODDFPRICE\t\t= PARITON.ENS.NIMELLISARVO\t##\tPalauttaa arvopaperin hinnan tilanteessa, jossa ensimmäinen jakso on pariton.\r\nODDFYIELD\t\t= PARITON.ENS.TUOTTO\t\t##\tPalauttaa arvopaperin tuoton tilanteessa, jossa ensimmäinen jakso on pariton.\r\nODDLPRICE\t\t= PARITON.VIIM.NIMELLISARVO\t##\tPalauttaa arvopaperin hinnan tilanteessa, jossa viimeinen jakso on pariton.\r\nODDLYIELD\t\t= PARITON.VIIM.TUOTTO\t\t##\tPalauttaa arvopaperin tuoton tilanteessa, jossa viimeinen jakso on pariton.\r\nPMT\t\t\t= MAKSU\t\t\t\t##\tPalauttaa annuiteetin kausittaisen maksuerän.\r\nPPMT\t\t\t= PPMT\t\t\t\t##\tLaskee sijoitukselle tai lainalle tiettynä ajanjaksona maksettavan lyhennyksen.\r\nPRICE\t\t\t= HINTA\t\t\t\t##\tPalauttaa hinnan 100 euron nimellisarvoa kohden arvopaperille, jonka korko maksetaan säännöllisin väliajoin.\r\nPRICEDISC\t\t= HINTA.DISK\t\t\t##\tPalauttaa diskontatun arvopaperin hinnan 100 euron nimellisarvoa kohden.\r\nPRICEMAT\t\t= HINTA.LUNASTUS\t\t##\tPalauttaa hinnan 100 euron nimellisarvoa kohden arvopaperille, jonka korko maksetaan erääntymispäivänä.\r\nPV\t\t\t= NA\t\t\t\t##\tPalauttaa sijoituksen nykyarvon.\r\nRATE\t\t\t= KORKO\t\t\t\t##\tPalauttaa annuiteetin kausittaisen korkokannan.\r\nRECEIVED\t\t= SAATU.HINTA\t\t\t##\tPalauttaa arvopaperin tuoton erääntymispäivänä kokonaan maksetulle sijoitukselle.\r\nSLN\t\t\t= STP\t\t\t\t##\tPalauttaa sijoituksen tasapoiston yhdeltä jaksolta.\r\nSYD\t\t\t= VUOSIPOISTO\t\t\t##\tPalauttaa sijoituksen vuosipoiston annettuna kautena amerikkalaisen SYD-menetelmän (Sum-of-Year's Digits) avulla.\r\nTBILLEQ\t\t\t= OBLIG.TUOTTOPROS\t\t##\tPalauttaa valtion obligaation tuoton vastaavana joukkovelkakirjan tuottona.\r\nTBILLPRICE\t\t= OBLIG.HINTA\t\t\t##\tPalauttaa obligaation hinnan 100 euron nimellisarvoa kohden.\r\nTBILLYIELD\t\t= OBLIG.TUOTTO\t\t\t##\tPalauttaa obligaation tuoton.\r\nVDB\t\t\t= VDB\t\t\t\t##\tPalauttaa annetun kauden tai kauden osan kirjanpidollisen poiston amerikkalaisen DB-menetelmän (Fixed-declining balance) mukaan.\r\nXIRR\t\t\t= SISÄINEN.KORKO.JAKSOTON\t##\tPalauttaa sisäisen korkokannan kassavirtojen sarjoille, jotka eivät välttämättä ole säännöllisiä.\r\nXNPV\t\t\t= NNA.JAKSOTON\t\t\t##\tPalauttaa nettonykyarvon kassavirtasarjalle, joka ei välttämättä ole kausittainen.\r\nYIELD\t\t\t= TUOTTO\t\t\t##\tPalauttaa tuoton arvopaperille, jonka korko maksetaan säännöllisin väliajoin.\r\nYIELDDISC\t\t= TUOTTO.DISK\t\t\t##\tPalauttaa diskontatun arvopaperin, kuten obligaation, vuosittaisen tuoton.\r\nYIELDMAT\t\t= TUOTTO.ERÄP\t\t\t##\tPalauttaa erääntymispäivänään korkoa tuottavan arvopaperin vuosittaisen tuoton.\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\tErikoisfunktiot\r\n##\r\nCELL\t\t\t= SOLU\t\t\t\t##\tPalauttaa tietoja solun muotoilusta, sijainnista ja sisällöstä.\r\nERROR.TYPE\t\t= VIRHEEN.LAJI\t\t\t##\tPalauttaa virhetyyppiä vastaavan luvun.\r\nINFO\t\t\t= KUVAUS\t\t\t##\tPalauttaa tietoja nykyisestä käyttöympäristöstä.\r\nISBLANK\t\t\t= ONTYHJÄ\t\t\t##\tPalauttaa arvon TOSI, jos arvo on tyhjä.\r\nISERR\t\t\t= ONVIRH\t\t\t##\tPalauttaa arvon TOSI, jos arvo on mikä tahansa virhearvo paitsi arvo #PUUTTUU!.\r\nISERROR\t\t\t= ONVIRHE\t\t\t##\tPalauttaa arvon TOSI, jos arvo on mikä tahansa virhearvo.\r\nISEVEN\t\t\t= ONPARILLINEN\t\t\t##\tPalauttaa arvon TOSI, jos arvo on parillinen.\r\nISLOGICAL\t\t= ONTOTUUS\t\t\t##\tPalauttaa arvon TOSI, jos arvo on mikä tahansa looginen arvo.\r\nISNA\t\t\t= ONPUUTTUU\t\t\t##\tPalauttaa arvon TOSI, jos virhearvo on #PUUTTUU!.\r\nISNONTEXT\t\t= ONEI_TEKSTI\t\t\t##\tPalauttaa arvon TOSI, jos arvo ei ole teksti.\r\nISNUMBER\t\t= ONLUKU\t\t\t##\tPalauttaa arvon TOSI, jos arvo on luku.\r\nISODD\t\t\t= ONPARITON\t\t\t##\tPalauttaa arvon TOSI, jos arvo on pariton.\r\nISREF\t\t\t= ONVIITT\t\t\t##\tPalauttaa arvon TOSI, jos arvo on viittaus.\r\nISTEXT\t\t\t= ONTEKSTI\t\t\t##\tPalauttaa arvon TOSI, jos arvo on teksti.\r\nN\t\t\t= N\t\t\t\t##\tPalauttaa arvon luvuksi muunnettuna.\r\nNA\t\t\t= PUUTTUU\t\t\t##\tPalauttaa virhearvon #PUUTTUU!.\r\nTYPE\t\t\t= TYYPPI\t\t\t##\tPalauttaa luvun, joka ilmaisee arvon tietotyypin.\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\tLoogiset funktiot\r\n##\r\nAND\t\t\t= JA\t\t\t\t##\tPalauttaa arvon TOSI, jos kaikkien argumenttien arvo on TOSI.\r\nFALSE\t\t\t= EPÄTOSI\t\t\t##\tPalauttaa totuusarvon EPÄTOSI.\r\nIF\t\t\t= JOS\t\t\t\t##\tMäärittää suoritettavan loogisen testin.\r\nIFERROR\t\t\t= JOSVIRHE\t\t\t##\tPalauttaa määrittämäsi arvon, jos kaavan tulos on virhe; muussa tapauksessa palauttaa kaavan tuloksen.\r\nNOT\t\t\t= EI\t\t\t\t##\tKääntää argumentin loogisen arvon.\r\nOR\t\t\t= TAI\t\t\t\t##\tPalauttaa arvon TOSI, jos minkä tahansa argumentin arvo on TOSI.\r\nTRUE\t\t\t= TOSI\t\t\t\t##\tPalauttaa totuusarvon TOSI.\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\tHaku- ja viitefunktiot\r\n##\r\nADDRESS\t\t\t= OSOITE\t\t\t##\tPalauttaa laskentataulukon soluun osoittavan viittauksen tekstinä.\r\nAREAS\t\t\t= ALUEET\t\t\t##\tPalauttaa viittauksessa olevien alueiden määrän.\r\nCHOOSE\t\t\t= VALITSE.INDEKSI\t\t##\tValitsee arvon arvoluettelosta.\r\nCOLUMN\t\t\t= SARAKE\t\t\t##\tPalauttaa viittauksen sarakenumeron.\r\nCOLUMNS\t\t\t= SARAKKEET\t\t\t##\tPalauttaa viittauksessa olevien sarakkeiden määrän.\r\nHLOOKUP\t\t\t= VHAKU\t\t\t\t##\tSuorittaa haun matriisin ylimmältä riviltä ja palauttaa määritetyn solun arvon.\r\nHYPERLINK\t\t= HYPERLINKKI\t\t\t##\tLuo pikakuvakkeen tai tekstin, joka avaa verkkopalvelimeen, intranetiin tai Internetiin tallennetun tiedoston.\r\nINDEX\t\t\t= INDEKSI\t\t\t##\tValitsee arvon viittauksesta tai matriisista indeksin mukaan.\r\nINDIRECT\t\t= EPÄSUORA\t\t\t##\tPalauttaa tekstiarvona ilmaistun viittauksen.\r\nLOOKUP\t\t\t= HAKU\t\t\t\t##\tEtsii arvoja vektorista tai matriisista.\r\nMATCH\t\t\t= VASTINE\t\t\t##\tEtsii arvoja viittauksesta tai matriisista.\r\nOFFSET\t\t\t= SIIRTYMÄ\t\t\t##\tPalauttaa annetun viittauksen siirtymän.\r\nROW\t\t\t= RIVI\t\t\t\t##\tPalauttaa viittauksen rivinumeron.\r\nROWS\t\t\t= RIVIT\t\t\t\t##\tPalauttaa viittauksessa olevien rivien määrän.\r\nRTD\t\t\t= RTD\t\t\t\t##\tNoutaa COM-automaatiota (automaatio: Tapa käsitellä sovelluksen objekteja toisesta sovelluksesta tai kehitystyökalusta. Automaatio, jota aiemmin kutsuttiin OLE-automaatioksi, on teollisuusstandardi ja COM-mallin (Component Object Model) ominaisuus.) tukevasta ohjelmasta reaaliaikaisia tietoja.\r\nTRANSPOSE\t\t= TRANSPONOI\t\t\t##\tPalauttaa matriisin käänteismatriisin.\r\nVLOOKUP\t\t\t= PHAKU\t\t\t\t##\tSuorittaa haun matriisin ensimmäisestä sarakkeesta ja palauttaa rivillä olevan solun arvon.\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\tMatemaattiset ja trigonometriset funktiot\r\n##\r\nABS\t\t\t= ITSEISARVO\t\t\t##\tPalauttaa luvun itseisarvon.\r\nACOS\t\t\t= ACOS\t\t\t\t##\tPalauttaa luvun arkuskosinin.\r\nACOSH\t\t\t= ACOSH\t\t\t\t##\tPalauttaa luvun käänteisen hyperbolisen kosinin.\r\nASIN\t\t\t= ASIN\t\t\t\t##\tPalauttaa luvun arkussinin.\r\nASINH\t\t\t= ASINH\t\t\t\t##\tPalauttaa luvun käänteisen hyperbolisen sinin.\r\nATAN\t\t\t= ATAN\t\t\t\t##\tPalauttaa luvun arkustangentin.\r\nATAN2\t\t\t= ATAN2\t\t\t\t##\tPalauttaa arkustangentin x- ja y-koordinaatin perusteella.\r\nATANH\t\t\t= ATANH\t\t\t\t##\tPalauttaa luvun käänteisen hyperbolisen tangentin.\r\nCEILING\t\t\t= PYÖRISTÄ.KERR.YLÖS\t\t##\tPyöristää luvun lähimpään kokonaislukuun tai tarkkuusargumentin lähimpään kerrannaiseen.\r\nCOMBIN\t\t\t= KOMBINAATIO\t\t\t##\tPalauttaa mahdollisten kombinaatioiden määrän annetulle objektien määrälle.\r\nCOS\t\t\t= COS\t\t\t\t##\tPalauttaa luvun kosinin.\r\nCOSH\t\t\t= COSH\t\t\t\t##\tPalauttaa luvun hyperbolisen kosinin.\r\nDEGREES\t\t\t= ASTEET\t\t\t##\tMuuntaa radiaanit asteiksi.\r\nEVEN\t\t\t= PARILLINEN\t\t\t##\tPyöristää luvun ylöspäin lähimpään parilliseen kokonaislukuun.\r\nEXP\t\t\t= EKSPONENTTI\t\t\t##\tPalauttaa e:n korotettuna annetun luvun osoittamaan potenssiin.\r\nFACT\t\t\t= KERTOMA\t\t\t##\tPalauttaa luvun kertoman.\r\nFACTDOUBLE\t\t= KERTOMA.OSA\t\t\t##\tPalauttaa luvun osakertoman.\r\nFLOOR\t\t\t= PYÖRISTÄ.KERR.ALAS\t\t##\tPyöristää luvun alaspäin (nollaa kohti).\r\nGCD\t\t\t= SUURIN.YHT.TEKIJÄ\t\t##\tPalauttaa suurimman yhteisen tekijän.\r\nINT\t\t\t= KOKONAISLUKU\t\t\t##\tPyöristää luvun alaspäin lähimpään kokonaislukuun.\r\nLCM\t\t\t= PIENIN.YHT.JAETTAVA\t\t##\tPalauttaa pienimmän yhteisen tekijän.\r\nLN\t\t\t= LUONNLOG\t\t\t##\tPalauttaa luvun luonnollisen logaritmin.\r\nLOG\t\t\t= LOG\t\t\t\t##\tLaskee luvun logaritmin käyttämällä annettua kantalukua.\r\nLOG10\t\t\t= LOG10\t\t\t\t##\tPalauttaa luvun kymmenkantaisen logaritmin.\r\nMDETERM\t\t\t= MDETERM\t\t\t##\tPalauttaa matriisin matriisideterminantin.\r\nMINVERSE\t\t= MKÄÄNTEINEN\t\t\t##\tPalauttaa matriisin käänteismatriisin.\r\nMMULT\t\t\t= MKERRO\t\t\t##\tPalauttaa kahden matriisin tulon.\r\nMOD\t\t\t= JAKOJ\t\t\t\t##\tPalauttaa jakolaskun jäännöksen.\r\nMROUND\t\t\t= PYÖRISTÄ.KERR\t\t\t##\tPalauttaa luvun pyöristettynä annetun luvun kerrannaiseen.\r\nMULTINOMIAL\t\t= MULTINOMI\t\t\t##\tPalauttaa lukujoukon multinomin.\r\nODD\t\t\t= PARITON\t\t\t##\tPyöristää luvun ylöspäin lähimpään parittomaan kokonaislukuun.\r\nPI\t\t\t= PII\t\t\t\t##\tPalauttaa piin arvon.\r\nPOWER\t\t\t= POTENSSI\t\t\t##\tPalauttaa luvun korotettuna haluttuun potenssiin.\r\nPRODUCT\t\t\t= TULO\t\t\t\t##\tKertoo annetut argumentit.\r\nQUOTIENT\t\t= OSAMÄÄRÄ\t\t\t##\tPalauttaa osamäärän kokonaislukuosan.\r\nRADIANS\t\t\t= RADIAANIT\t\t\t##\tMuuntaa asteet radiaaneiksi.\r\nRAND\t\t\t= SATUNNAISLUKU\t\t\t##\tPalauttaa satunnaisluvun väliltä 0–1.\r\nRANDBETWEEN\t\t= SATUNNAISLUKU.VÄLILTÄ\t\t##\tPalauttaa satunnaisluvun määritettyjen lukujen väliltä.\r\nROMAN\t\t\t= ROMAN\t\t\t\t##\tMuuntaa arabialaisen numeron tekstimuotoiseksi roomalaiseksi numeroksi.\r\nROUND\t\t\t= PYÖRISTÄ\t\t\t##\tPyöristää luvun annettuun määrään desimaaleja.\r\nROUNDDOWN\t\t= PYÖRISTÄ.DES.ALAS\t\t##\tPyöristää luvun alaspäin (nollaa kohti).\r\nROUNDUP\t\t\t= PYÖRISTÄ.DES.YLÖS\t\t##\tPyöristää luvun ylöspäin (poispäin nollasta).\r\nSERIESSUM\t\t= SARJA.SUMMA\t\t\t##\tPalauttaa kaavaan perustuvan potenssisarjan arvon.\r\nSIGN\t\t\t= ETUMERKKI\t\t\t##\tPalauttaa luvun etumerkin.\r\nSIN\t\t\t= SIN\t\t\t\t##\tPalauttaa annetun kulman sinin.\r\nSINH\t\t\t= SINH\t\t\t\t##\tPalauttaa luvun hyperbolisen sinin.\r\nSQRT\t\t\t= NELIÖJUURI\t\t\t##\tPalauttaa positiivisen neliöjuuren.\r\nSQRTPI\t\t\t= NELIÖJUURI.PII\t\t##\tPalauttaa tulon (luku * pii) neliöjuuren.\r\nSUBTOTAL\t\t= VÄLISUMMA\t\t\t##\tPalauttaa luettelon tai tietokannan välisumman.\r\nSUM\t\t\t= SUMMA\t\t\t\t##\tLaskee yhteen annetut argumentit.\r\nSUMIF\t\t\t= SUMMA.JOS\t\t\t##\tLaskee ehdot täyttävien solujen summan.\r\nSUMIFS\t\t\t= SUMMA.JOS.JOUKKO\t\t##\tLaskee yhteen solualueen useita ehtoja vastaavat solut.\r\nSUMPRODUCT\t\t= TULOJEN.SUMMA\t\t\t##\tPalauttaa matriisin toisiaan vastaavien osien tulojen summan.\r\nSUMSQ\t\t\t= NELIÖSUMMA\t\t\t##\tPalauttaa argumenttien neliöiden summan.\r\nSUMX2MY2\t\t= NELIÖSUMMIEN.EROTUS\t\t##\tPalauttaa kahden matriisin toisiaan vastaavien arvojen laskettujen neliösummien erotuksen.\r\nSUMX2PY2\t\t= NELIÖSUMMIEN.SUMMA\t\t##\tPalauttaa kahden matriisin toisiaan vastaavien arvojen neliösummien summan.\r\nSUMXMY2\t\t\t= EROTUSTEN.NELIÖSUMMA\t\t##\tPalauttaa kahden matriisin toisiaan vastaavien arvojen erotusten neliösumman.\r\nTAN\t\t\t= TAN\t\t\t\t##\tPalauttaa luvun tangentin.\r\nTANH\t\t\t= TANH\t\t\t\t##\tPalauttaa luvun hyperbolisen tangentin.\r\nTRUNC\t\t\t= KATKAISE\t\t\t##\tKatkaisee luvun kokonaisluvuksi.\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\tTilastolliset funktiot\r\n##\r\nAVEDEV\t\t\t= KESKIPOIKKEAMA\t\t##\tPalauttaa hajontojen itseisarvojen keskiarvon.\r\nAVERAGE\t\t\t= KESKIARVO\t\t\t##\tPalauttaa argumenttien keskiarvon.\r\nAVERAGEA\t\t= KESKIARVOA\t\t\t##\tPalauttaa argumenttien, mukaan lukien lukujen, tekstin ja loogisten arvojen, keskiarvon.\r\nAVERAGEIF\t\t= KESKIARVO.JOS\t\t\t##\tPalauttaa alueen niiden solujen keskiarvon (aritmeettisen keskiarvon), jotka täyttävät annetut ehdot.\r\nAVERAGEIFS\t\t= KESKIARVO.JOS.JOUKKO\t\t##\tPalauttaa niiden solujen keskiarvon (aritmeettisen keskiarvon), jotka vastaavat useita ehtoja.\r\nBETADIST\t\t= BEETAJAKAUMA\t\t\t##\tPalauttaa kumulatiivisen beetajakaumafunktion arvon.\r\nBETAINV\t\t\t= BEETAJAKAUMA.KÄÄNT\t\t##\tPalauttaa määritetyn beetajakauman käänteisen kumulatiivisen jakaumafunktion arvon.\r\nBINOMDIST\t\t= BINOMIJAKAUMA\t\t\t##\tPalauttaa yksittäisen termin binomijakaumatodennäköisyyden.\r\nCHIDIST\t\t\t= CHIJAKAUMA\t\t\t##\tPalauttaa yksisuuntaisen chi-neliön jakauman todennäköisyyden.\r\nCHIINV\t\t\t= CHIJAKAUMA.KÄÄNT\t\t##\tPalauttaa yksisuuntaisen chi-neliön jakauman todennäköisyyden käänteisarvon.\r\nCHITEST\t\t\t= CHITESTI\t\t\t##\tPalauttaa riippumattomuustestin tuloksen.\r\nCONFIDENCE\t\t= LUOTTAMUSVÄLI\t\t\t##\tPalauttaa luottamusvälin populaation keskiarvolle.\r\nCORREL\t\t\t= KORRELAATIO\t\t\t##\tPalauttaa kahden arvojoukon korrelaatiokertoimen.\r\nCOUNT\t\t\t= LASKE\t\t\t\t##\tLaskee argumenttiluettelossa olevien lukujen määrän.\r\nCOUNTA\t\t\t= LASKE.A\t\t\t##\tLaskee argumenttiluettelossa olevien arvojen määrän.\r\nCOUNTBLANK\t\t= LASKE.TYHJÄT\t\t\t##\tLaskee alueella olevien tyhjien solujen määrän.\r\nCOUNTIF\t\t\t= LASKE.JOS\t\t\t##\tLaskee alueella olevien sellaisten solujen määrän, joiden sisältö vastaa annettuja ehtoja.\r\nCOUNTIFS\t\t= LASKE.JOS.JOUKKO\t\t##\tLaskee alueella olevien sellaisten solujen määrän, joiden sisältö vastaa useita ehtoja.\r\nCOVAR\t\t\t= KOVARIANSSI\t\t\t##\tPalauttaa kovarianssin, joka on keskiarvo havaintoaineiston kunkin pisteparin poikkeamien tuloista.\r\nCRITBINOM\t\t= BINOMIJAKAUMA.KRIT\t\t##\tPalauttaa pienimmän arvon, jossa binomijakauman kertymäfunktion arvo on pienempi tai yhtä suuri kuin vertailuarvo.\r\nDEVSQ\t\t\t= OIKAISTU.NELIÖSUMMA\t\t##\tPalauttaa keskipoikkeamien neliösumman.\r\nEXPONDIST\t\t= EKSPONENTIAALIJAKAUMA\t\t##\tPalauttaa eksponentiaalijakauman.\r\nFDIST\t\t\t= FJAKAUMA\t\t\t##\tPalauttaa F-todennäköisyysjakauman.\r\nFINV\t\t\t= FJAKAUMA.KÄÄNT\t\t##\tPalauttaa F-todennäköisyysjakauman käänteisfunktion.\r\nFISHER\t\t\t= FISHER\t\t\t##\tPalauttaa Fisher-muunnoksen.\r\nFISHERINV\t\t= FISHER.KÄÄNT\t\t\t##\tPalauttaa käänteisen Fisher-muunnoksen.\r\nFORECAST\t\t= ENNUSTE\t\t\t##\tPalauttaa lineaarisen trendin arvon.\r\nFREQUENCY\t\t= TAAJUUS\t\t\t##\tPalauttaa frekvenssijakautuman pystysuuntaisena matriisina.\r\nFTEST\t\t\t= FTESTI\t\t\t##\tPalauttaa F-testin tuloksen.\r\nGAMMADIST\t\t= GAMMAJAKAUMA\t\t\t##\tPalauttaa gammajakauman.\r\nGAMMAINV\t\t= GAMMAJAKAUMA.KÄÄNT\t\t##\tPalauttaa käänteisen gammajakauman kertymäfunktion.\r\nGAMMALN\t\t\t= GAMMALN\t\t\t##\tPalauttaa gammafunktion luonnollisen logaritmin G(x).\r\nGEOMEAN\t\t\t= KESKIARVO.GEOM\t\t##\tPalauttaa geometrisen keskiarvon.\r\nGROWTH\t\t\t= KASVU\t\t\t\t##\tPalauttaa eksponentiaalisen trendin arvon.\r\nHARMEAN\t\t\t= KESKIARVO.HARM\t\t##\tPalauttaa harmonisen keskiarvon.\r\nHYPGEOMDIST\t\t= HYPERGEOM.JAKAUMA\t\t##\tPalauttaa hypergeometrisen jakauman.\r\nINTERCEPT\t\t= LEIKKAUSPISTE\t\t\t##\tPalauttaa lineaarisen regressiosuoran leikkauspisteen.\r\nKURT\t\t\t= KURT\t\t\t\t##\tPalauttaa tietoalueen vinous-arvon eli huipukkuuden.\r\nLARGE\t\t\t= SUURI\t\t\t\t##\tPalauttaa tietojoukon k:nneksi suurimman arvon.\r\nLINEST\t\t\t= LINREGR\t\t\t##\tPalauttaa lineaarisen trendin parametrit.\r\nLOGEST\t\t\t= LOGREGR\t\t\t##\tPalauttaa eksponentiaalisen trendin parametrit.\r\nLOGINV\t\t\t= LOGNORM.JAKAUMA.KÄÄNT\t\t##\tPalauttaa lognormeeratun jakauman käänteisfunktion.\r\nLOGNORMDIST\t\t= LOGNORM.JAKAUMA\t\t##\tPalauttaa lognormaalisen jakauman kertymäfunktion.\r\nMAX\t\t\t= MAKS\t\t\t\t##\tPalauttaa suurimman arvon argumenttiluettelosta.\r\nMAXA\t\t\t= MAKSA\t\t\t\t##\tPalauttaa argumenttien, mukaan lukien lukujen, tekstin ja loogisten arvojen, suurimman arvon.\r\nMEDIAN\t\t\t= MEDIAANI\t\t\t##\tPalauttaa annettujen lukujen mediaanin.\r\nMIN\t\t\t= MIN\t\t\t\t##\tPalauttaa pienimmän arvon argumenttiluettelosta.\r\nMINA\t\t\t= MINA\t\t\t\t##\tPalauttaa argumenttien, mukaan lukien lukujen, tekstin ja loogisten arvojen, pienimmän arvon.\r\nMODE\t\t\t= MOODI\t\t\t\t##\tPalauttaa tietojoukossa useimmin esiintyvän arvon.\r\nNEGBINOMDIST\t\t= BINOMIJAKAUMA.NEG\t\t##\tPalauttaa negatiivisen binomijakauman.\r\nNORMDIST\t\t= NORM.JAKAUMA\t\t\t##\tPalauttaa normaalijakauman kertymäfunktion.\r\nNORMINV\t\t\t= NORM.JAKAUMA.KÄÄNT\t\t##\tPalauttaa käänteisen normaalijakauman kertymäfunktion.\r\nNORMSDIST\t\t= NORM.JAKAUMA.NORMIT\t\t##\tPalauttaa normitetun normaalijakauman kertymäfunktion.\r\nNORMSINV\t\t= NORM.JAKAUMA.NORMIT.KÄÄNT\t##\tPalauttaa normitetun normaalijakauman kertymäfunktion käänteisarvon.\r\nPEARSON\t\t\t= PEARSON\t\t\t##\tPalauttaa Pearsonin tulomomenttikorrelaatiokertoimen.\r\nPERCENTILE\t\t= PROSENTTIPISTE\t\t##\tPalauttaa alueen arvojen k:nnen prosenttipisteen.\r\nPERCENTRANK\t\t= PROSENTTIJÄRJESTYS\t\t##\tPalauttaa tietojoukon arvon prosentuaalisen järjestysluvun.\r\nPERMUT\t\t\t= PERMUTAATIO\t\t\t##\tPalauttaa mahdollisten permutaatioiden määrän annetulle objektien määrälle.\r\nPOISSON\t\t\t= POISSON\t\t\t##\tPalauttaa Poissonin todennäköisyysjakauman.\r\nPROB\t\t\t= TODENNÄKÖISYYS\t\t##\tPalauttaa todennäköisyyden sille, että arvot ovat tietyltä väliltä.\r\nQUARTILE\t\t= NELJÄNNES\t\t\t##\tPalauttaa tietoalueen neljänneksen.\r\nRANK\t\t\t= ARVON.MUKAAN\t\t\t##\tPalauttaa luvun paikan lukuarvoluettelossa.\r\nRSQ\t\t\t= PEARSON.NELIÖ\t\t\t##\tPalauttaa Pearsonin tulomomenttikorrelaatiokertoimen neliön.\r\nSKEW\t\t\t= JAKAUMAN.VINOUS\t\t##\tPalauttaa jakauman vinouden.\r\nSLOPE\t\t\t= KULMAKERROIN\t\t\t##\tPalauttaa lineaarisen regressiosuoran kulmakertoimen.\r\nSMALL\t\t\t= PIENI\t\t\t\t##\tPalauttaa tietojoukon k:nneksi pienimmän arvon.\r\nSTANDARDIZE\t\t= NORMITA\t\t\t##\tPalauttaa normitetun arvon.\r\nSTDEV\t\t\t= KESKIHAJONTA\t\t\t##\tLaskee populaation keskihajonnan otoksen perusteella.\r\nSTDEVA\t\t\t= KESKIHAJONTAA\t\t\t##\tLaskee populaation keskihajonnan otoksen perusteella, mukaan lukien luvut, tekstin ja loogiset arvot.\r\nSTDEVP\t\t\t= KESKIHAJONTAP\t\t\t##\tLaskee normaalijakautuman koko populaation perusteella.\r\nSTDEVPA\t\t\t= KESKIHAJONTAPA\t\t##\tLaskee populaation keskihajonnan koko populaation perusteella, mukaan lukien luvut, tekstin ja totuusarvot.\r\nSTEYX\t\t\t= KESKIVIRHE\t\t\t##\tPalauttaa regression kutakin x-arvoa vastaavan ennustetun y-arvon keskivirheen.\r\nTDIST\t\t\t= TJAKAUMA\t\t\t##\tPalauttaa t-jakautuman.\r\nTINV\t\t\t= TJAKAUMA.KÄÄNT\t\t##\tPalauttaa käänteisen t-jakauman.\r\nTREND\t\t\t= SUUNTAUS\t\t\t##\tPalauttaa lineaarisen trendin arvoja.\r\nTRIMMEAN\t\t= KESKIARVO.TASATTU\t\t##\tPalauttaa tietojoukon tasatun keskiarvon.\r\nTTEST\t\t\t= TTESTI\t\t\t##\tPalauttaa t-testiin liittyvän todennäköisyyden.\r\nVAR\t\t\t= VAR\t\t\t\t##\tArvioi populaation varianssia otoksen perusteella.\r\nVARA\t\t\t= VARA\t\t\t\t##\tLaskee populaation varianssin otoksen perusteella, mukaan lukien luvut, tekstin ja loogiset arvot.\r\nVARP\t\t\t= VARP\t\t\t\t##\tLaskee varianssin koko populaation perusteella.\r\nVARPA\t\t\t= VARPA\t\t\t\t##\tLaskee populaation varianssin koko populaation perusteella, mukaan lukien luvut, tekstin ja totuusarvot.\r\nWEIBULL\t\t\t= WEIBULL\t\t\t##\tPalauttaa Weibullin jakauman.\r\nZTEST\t\t\t= ZTESTI\t\t\t##\tPalauttaa z-testin yksisuuntaisen todennäköisyysarvon.\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\tTekstifunktiot\r\n##\r\nASC\t\t\t= ASC\t\t\t\t##\tMuuntaa merkkijonossa olevat englanninkieliset DBCS- tai katakana-merkit SBCS-merkeiksi.\r\nBAHTTEXT\t\t= BAHTTEKSTI\t\t\t##\tMuuntaa luvun tekstiksi ß (baht) -valuuttamuotoa käyttämällä.\r\nCHAR\t\t\t= MERKKI\t\t\t##\tPalauttaa koodin lukua vastaavan merkin.\r\nCLEAN\t\t\t= SIIVOA\t\t\t##\tPoistaa tekstistä kaikki tulostumattomat merkit.\r\nCODE\t\t\t= KOODI\t\t\t\t##\tPalauttaa tekstimerkkijonon ensimmäisen merkin numerokoodin.\r\nCONCATENATE\t\t= KETJUTA\t\t\t##\tYhdistää useat merkkijonot yhdeksi merkkijonoksi.\r\nDOLLAR\t\t\t= VALUUTTA\t\t\t##\tMuuntaa luvun tekstiksi $ (dollari) -valuuttamuotoa käyttämällä.\r\nEXACT\t\t\t= VERTAA\t\t\t##\tTarkistaa, ovatko kaksi tekstiarvoa samanlaiset.\r\nFIND\t\t\t= ETSI\t\t\t\t##\tEtsii tekstiarvon toisen tekstin sisältä (tunnistaa isot ja pienet kirjaimet).\r\nFINDB\t\t\t= ETSIB\t\t\t\t##\tEtsii tekstiarvon toisen tekstin sisältä (tunnistaa isot ja pienet kirjaimet).\r\nFIXED\t\t\t= KIINTEÄ\t\t\t##\tMuotoilee luvun tekstiksi, jossa on kiinteä määrä desimaaleja.\r\nJIS\t\t\t= JIS\t\t\t\t##\tMuuntaa merkkijonossa olevat englanninkieliset SBCS- tai katakana-merkit DBCS-merkeiksi.\r\nLEFT\t\t\t= VASEN\t\t\t\t##\tPalauttaa tekstiarvon vasemmanpuoliset merkit.\r\nLEFTB\t\t\t= VASENB\t\t\t##\tPalauttaa tekstiarvon vasemmanpuoliset merkit.\r\nLEN\t\t\t= PITUUS\t\t\t##\tPalauttaa tekstimerkkijonon merkkien määrän.\r\nLENB\t\t\t= PITUUSB\t\t\t##\tPalauttaa tekstimerkkijonon merkkien määrän.\r\nLOWER\t\t\t= PIENET\t\t\t##\tMuuntaa tekstin pieniksi kirjaimiksi.\r\nMID\t\t\t= POIMI.TEKSTI\t\t\t##\tPalauttaa määritetyn määrän merkkejä merkkijonosta alkaen annetusta kohdasta.\r\nMIDB\t\t\t= POIMI.TEKSTIB\t\t\t##\tPalauttaa määritetyn määrän merkkejä merkkijonosta alkaen annetusta kohdasta.\r\nPHONETIC\t\t= FONEETTINEN\t\t\t##\tHakee foneettiset (furigana) merkit merkkijonosta.\r\nPROPER\t\t\t= ERISNIMI\t\t\t##\tMuuttaa merkkijonon kunkin sanan ensimmäisen kirjaimen isoksi.\r\nREPLACE\t\t\t= KORVAA\t\t\t##\tKorvaa tekstissä olevat merkit.\r\nREPLACEB\t\t= KORVAAB\t\t\t##\tKorvaa tekstissä olevat merkit.\r\nREPT\t\t\t= TOISTA\t\t\t##\tToistaa tekstin annetun määrän kertoja.\r\nRIGHT\t\t\t= OIKEA\t\t\t\t##\tPalauttaa tekstiarvon oikeanpuoliset merkit.\r\nRIGHTB\t\t\t= OIKEAB\t\t\t##\tPalauttaa tekstiarvon oikeanpuoliset merkit.\r\nSEARCH\t\t\t= KÄY.LÄPI\t\t\t##\tEtsii tekstiarvon toisen tekstin sisältä (isot ja pienet kirjaimet tulkitaan samoiksi merkeiksi).\r\nSEARCHB\t\t\t= KÄY.LÄPIB\t\t\t##\tEtsii tekstiarvon toisen tekstin sisältä (isot ja pienet kirjaimet tulkitaan samoiksi merkeiksi).\r\nSUBSTITUTE\t\t= VAIHDA\t\t\t##\tKorvaa merkkijonossa olevan tekstin toisella.\r\nT\t\t\t= T\t\t\t\t##\tMuuntaa argumentit tekstiksi.\r\nTEXT\t\t\t= TEKSTI\t\t\t##\tMuotoilee luvun ja muuntaa sen tekstiksi.\r\nTRIM\t\t\t= POISTA.VÄLIT\t\t\t##\tPoistaa välilyönnit tekstistä.\r\nUPPER\t\t\t= ISOT\t\t\t\t##\tMuuntaa tekstin isoiksi kirjaimiksi.\r\nVALUE\t\t\t= ARVO\t\t\t\t##\tMuuntaa tekstiargumentin luvuksi.\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= €\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #NUL!\r\nDIV0\t= #DIV/0!\r\nVALUE\t= #VALEUR!\r\nREF\t= #REF!\r\nNAME\t= #NOM?\r\nNUM\t= #NOMBRE!\r\nNA\t= #N/A\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/fr/functions",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Calculation\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/\r\n##\r\n##\r\n\r\n\r\n##\r\n##\tAdd-in and Automation functions\t\t\tFonctions de complément et d’automatisation\r\n##\r\nGETPIVOTDATA\t\t= LIREDONNEESTABCROISDYNAMIQUE\t##\tRenvoie les données stockées dans un rapport de tableau croisé dynamique.\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\tFonctions Cube\r\n##\r\nCUBEKPIMEMBER\t\t= MEMBREKPICUBE\t\t\t##\tRenvoie un nom, une propriété et une mesure d’indicateur de performance clé et affiche le nom et la propriété dans la cellule. Un indicateur de performance clé est une mesure quantifiable, telle que la marge bénéficiaire brute mensuelle ou la rotation trimestrielle du personnel, utilisée pour évaluer les performances d’une entreprise.\r\nCUBEMEMBER\t\t= MEMBRECUBE\t\t\t##\tRenvoie un membre ou un uplet dans une hiérarchie de cubes. Utilisez cette fonction pour valider l’existence du membre ou de l’uplet dans le cube.\r\nCUBEMEMBERPROPERTY\t= PROPRIETEMEMBRECUBE\t\t##\tRenvoie la valeur d’une propriété de membre du cube. Utilisez cette fonction pour valider l’existence d’un nom de membre dans le cube et pour renvoyer la propriété spécifiée pour ce membre.\r\nCUBERANKEDMEMBER\t= RANGMEMBRECUBE\t\t##\tRenvoie le nième membre ou le membre placé à un certain rang dans un ensemble. Utilisez cette fonction pour renvoyer un ou plusieurs éléments d’un ensemble, tels que les meilleurs vendeurs ou les 10 meilleurs étudiants.\r\nCUBESET\t\t\t= JEUCUBE\t\t\t##\tDéfinit un ensemble calculé de membres ou d’uplets en envoyant une expression définie au cube sur le serveur qui crée l’ensemble et le renvoie à Microsoft Office Excel.\r\nCUBESETCOUNT\t\t= NBJEUCUBE\t\t\t##\tRenvoie le nombre d’éléments dans un jeu.\r\nCUBEVALUE\t\t= VALEURCUBE\t\t\t##\tRenvoie une valeur d’agrégation issue d’un cube.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\tFonctions de base de données\r\n##\r\nDAVERAGE\t\t= BDMOYENNE\t\t\t##\tRenvoie la moyenne des entrées de base de données sélectionnées.\r\nDCOUNT\t\t\t= BCOMPTE\t\t\t##\tCompte le nombre de cellules d’une base de données qui contiennent des nombres.\r\nDCOUNTA\t\t\t= BDNBVAL\t\t\t##\tCompte les cellules non vides d’une base de données.\r\nDGET\t\t\t= BDLIRE\t\t\t##\tExtrait d’une base de données un enregistrement unique répondant aux critères spécifiés.\r\nDMAX\t\t\t= BDMAX\t\t\t\t##\tRenvoie la valeur maximale des entrées de base de données sélectionnées.\r\nDMIN\t\t\t= BDMIN\t\t\t\t##\tRenvoie la valeur minimale des entrées de base de données sélectionnées.\r\nDPRODUCT\t\t= BDPRODUIT\t\t\t##\tMultiplie les valeurs d’un champ particulier des enregistrements d’une base de données, qui répondent aux critères spécifiés.\r\nDSTDEV\t\t\t= BDECARTYPE\t\t\t##\tCalcule l’écart type pour un échantillon d’entrées de base de données sélectionnées.\r\nDSTDEVP\t\t\t= BDECARTYPEP\t\t\t##\tCalcule l’écart type pour l’ensemble d’une population d’entrées de base de données sélectionnées.\r\nDSUM\t\t\t= BDSOMME\t\t\t##\tAjoute les nombres dans la colonne de champ des enregistrements de la base de données, qui répondent aux critères.\r\nDVAR\t\t\t= BDVAR\t\t\t\t##\tCalcule la variance pour un échantillon d’entrées de base de données sélectionnées.\r\nDVARP\t\t\t= BDVARP\t\t\t##\tCalcule la variance pour l’ensemble d’une population d’entrées de base de données sélectionnées.\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\tFonctions de date et d’heure\r\n##\r\nDATE\t\t\t= DATE\t\t\t\t##\tRenvoie le numéro de série d’une date précise.\r\nDATEVALUE\t\t= DATEVAL\t\t\t##\tConvertit une date représentée sous forme de texte en numéro de série.\r\nDAY\t\t\t= JOUR\t\t\t\t##\tConvertit un numéro de série en jour du mois.\r\nDAYS360\t\t\t= JOURS360\t\t\t##\tCalcule le nombre de jours qui séparent deux dates sur la base d’une année de 360 jours.\r\nEDATE\t\t\t= MOIS.DECALER\t\t\t##\tRenvoie le numéro séquentiel de la date qui représente une date spécifiée (l’argument date_départ), corrigée en plus ou en moins du nombre de mois indiqué.\r\nEOMONTH\t\t\t= FIN.MOIS\t\t\t##\tRenvoie le numéro séquentiel de la date du dernier jour du mois précédant ou suivant la date_départ du nombre de mois indiqué.\r\nHOUR\t\t\t= HEURE\t\t\t\t##\tConvertit un numéro de série en heure.\r\nMINUTE\t\t\t= MINUTE\t\t\t##\tConvertit un numéro de série en minute.\r\nMONTH\t\t\t= MOIS\t\t\t\t##\tConvertit un numéro de série en mois.\r\nNETWORKDAYS\t\t= NB.JOURS.OUVRES\t\t##\tRenvoie le nombre de jours ouvrés entiers compris entre deux dates.\r\nNOW\t\t\t= MAINTENANT\t\t\t##\tRenvoie le numéro de série de la date et de l’heure du jour.\r\nSECOND\t\t\t= SECONDE\t\t\t##\tConvertit un numéro de série en seconde.\r\nTIME\t\t\t= TEMPS\t\t\t\t##\tRenvoie le numéro de série d’une heure précise.\r\nTIMEVALUE\t\t= TEMPSVAL\t\t\t##\tConvertit une date représentée sous forme de texte en numéro de série.\r\nTODAY\t\t\t= AUJOURDHUI\t\t\t##\tRenvoie le numéro de série de la date du jour.\r\nWEEKDAY\t\t\t= JOURSEM\t\t\t##\tConvertit un numéro de série en jour de la semaine.\r\nWEEKNUM\t\t\t= NO.SEMAINE\t\t\t##\tConvertit un numéro de série en un numéro représentant l’ordre de la semaine dans l’année.\r\nWORKDAY\t\t\t= SERIE.JOUR.OUVRE\t\t##\tRenvoie le numéro de série de la date avant ou après le nombre de jours ouvrés spécifiés.\r\nYEAR\t\t\t= ANNEE\t\t\t\t##\tConvertit un numéro de série en année.\r\nYEARFRAC\t\t= FRACTION.ANNEE\t\t##\tRenvoie la fraction de l’année représentant le nombre de jours entre la date de début et la date de fin.\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\tFonctions d’ingénierie\r\n##\r\nBESSELI\t\t\t= BESSELI\t\t\t##\tRenvoie la fonction Bessel modifiée In(x).\r\nBESSELJ\t\t\t= BESSELJ\t\t\t##\tRenvoie la fonction Bessel Jn(x).\r\nBESSELK\t\t\t= BESSELK\t\t\t##\tRenvoie la fonction Bessel modifiée Kn(x).\r\nBESSELY\t\t\t= BESSELY\t\t\t##\tRenvoie la fonction Bessel Yn(x).\r\nBIN2DEC\t\t\t= BINDEC\t\t\t##\tConvertit un nombre binaire en nombre décimal.\r\nBIN2HEX\t\t\t= BINHEX\t\t\t##\tConvertit un nombre binaire en nombre hexadécimal.\r\nBIN2OCT\t\t\t= BINOCT\t\t\t##\tConvertit un nombre binaire en nombre octal.\r\nCOMPLEX\t\t\t= COMPLEXE\t\t\t##\tConvertit des coefficients réel et imaginaire en un nombre complexe.\r\nCONVERT\t\t\t= CONVERT\t\t\t##\tConvertit un nombre d’une unité de mesure à une autre.\r\nDEC2BIN\t\t\t= DECBIN\t\t\t##\tConvertit un nombre décimal en nombre binaire.\r\nDEC2HEX\t\t\t= DECHEX\t\t\t##\tConvertit un nombre décimal en nombre hexadécimal.\r\nDEC2OCT\t\t\t= DECOCT\t\t\t##\tConvertit un nombre décimal en nombre octal.\r\nDELTA\t\t\t= DELTA\t\t\t\t##\tTeste l’égalité de deux nombres.\r\nERF\t\t\t= ERF\t\t\t\t##\tRenvoie la valeur de la fonction d’erreur.\r\nERFC\t\t\t= ERFC\t\t\t\t##\tRenvoie la valeur de la fonction d’erreur complémentaire.\r\nGESTEP\t\t\t= SUP.SEUIL\t\t\t##\tTeste si un nombre est supérieur à une valeur de seuil.\r\nHEX2BIN\t\t\t= HEXBIN\t\t\t##\tConvertit un nombre hexadécimal en nombre binaire.\r\nHEX2DEC\t\t\t= HEXDEC\t\t\t##\tConvertit un nombre hexadécimal en nombre décimal.\r\nHEX2OCT\t\t\t= HEXOCT\t\t\t##\tConvertit un nombre hexadécimal en nombre octal.\r\nIMABS\t\t\t= COMPLEXE.MODULE\t\t##\tRenvoie la valeur absolue (module) d’un nombre complexe.\r\nIMAGINARY\t\t= COMPLEXE.IMAGINAIRE\t\t##\tRenvoie le coefficient imaginaire d’un nombre complexe.\r\nIMARGUMENT\t\t= COMPLEXE.ARGUMENT\t\t##\tRenvoie l’argument thêta, un angle exprimé en radians.\r\nIMCONJUGATE\t\t= COMPLEXE.CONJUGUE\t\t##\tRenvoie le nombre complexe conjugué d’un nombre complexe.\r\nIMCOS\t\t\t= IMCOS\t\t\t\t##\tRenvoie le cosinus d’un nombre complexe.\r\nIMDIV\t\t\t= COMPLEXE.DIV\t\t\t##\tRenvoie le quotient de deux nombres complexes.\r\nIMEXP\t\t\t= COMPLEXE.EXP\t\t\t##\tRenvoie la fonction exponentielle d’un nombre complexe.\r\nIMLN\t\t\t= COMPLEXE.LN\t\t\t##\tRenvoie le logarithme népérien d’un nombre complexe.\r\nIMLOG10\t\t\t= COMPLEXE.LOG10\t\t##\tCalcule le logarithme en base 10 d’un nombre complexe.\r\nIMLOG2\t\t\t= COMPLEXE.LOG2\t\t\t##\tCalcule le logarithme en base 2 d’un nombre complexe.\r\nIMPOWER\t\t\t= COMPLEXE.PUISSANCE\t\t##\tRenvoie un nombre complexe élevé à une puissance entière.\r\nIMPRODUCT\t\t= COMPLEXE.PRODUIT\t\t##\tRenvoie le produit de plusieurs nombres complexes.\r\nIMREAL\t\t\t= COMPLEXE.REEL\t\t\t##\tRenvoie le coefficient réel d’un nombre complexe.\r\nIMSIN\t\t\t= COMPLEXE.SIN\t\t\t##\tRenvoie le sinus d’un nombre complexe.\r\nIMSQRT\t\t\t= COMPLEXE.RACINE\t\t##\tRenvoie la racine carrée d’un nombre complexe.\r\nIMSUB\t\t\t= COMPLEXE.DIFFERENCE\t\t##\tRenvoie la différence entre deux nombres complexes.\r\nIMSUM\t\t\t= COMPLEXE.SOMME\t\t##\tRenvoie la somme de plusieurs nombres complexes.\r\nOCT2BIN\t\t\t= OCTBIN\t\t\t##\tConvertit un nombre octal en nombre binaire.\r\nOCT2DEC\t\t\t= OCTDEC\t\t\t##\tConvertit un nombre octal en nombre décimal.\r\nOCT2HEX\t\t\t= OCTHEX\t\t\t##\tConvertit un nombre octal en nombre hexadécimal.\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\tFonctions financières\r\n##\r\nACCRINT\t\t\t= INTERET.ACC\t\t\t##\tRenvoie l’intérêt couru non échu d’un titre dont l’intérêt est perçu périodiquement.\r\nACCRINTM\t\t= INTERET.ACC.MAT\t\t##\tRenvoie l’intérêt couru non échu d’un titre dont l’intérêt est perçu à l’échéance.\r\nAMORDEGRC\t\t= AMORDEGRC\t\t\t##\tRenvoie l’amortissement correspondant à chaque période comptable en utilisant un coefficient d’amortissement.\r\nAMORLINC\t\t= AMORLINC\t\t\t##\tRenvoie l’amortissement d’un bien à la fin d’une période fiscale donnée.\r\nCOUPDAYBS\t\t= NB.JOURS.COUPON.PREC\t\t##\tRenvoie le nombre de jours entre le début de la période de coupon et la date de liquidation.\r\nCOUPDAYS\t\t= NB.JOURS.COUPONS\t\t##\tRenvoie le nombre de jours pour la période du coupon contenant la date de liquidation.\r\nCOUPDAYSNC\t\t= NB.JOURS.COUPON.SUIV\t\t##\tRenvoie le nombre de jours entre la date de liquidation et la date du coupon suivant la date de liquidation.\r\nCOUPNCD\t\t\t= DATE.COUPON.SUIV\t\t##\tRenvoie la première date de coupon ultérieure à la date de règlement.\r\nCOUPNUM\t\t\t= NB.COUPONS\t\t\t##\tRenvoie le nombre de coupons dus entre la date de règlement et la date d’échéance.\r\nCOUPPCD\t\t\t= DATE.COUPON.PREC\t\t##\tRenvoie la date de coupon précédant la date de règlement.\r\nCUMIPMT\t\t\t= CUMUL.INTER\t\t\t##\tRenvoie l’intérêt cumulé payé sur un emprunt entre deux périodes.\r\nCUMPRINC\t\t= CUMUL.PRINCPER\t\t##\tRenvoie le montant cumulé des remboursements du capital d’un emprunt effectués entre deux périodes.\r\nDB\t\t\t= DB\t\t\t\t##\tRenvoie l’amortissement d’un bien pour une période spécifiée en utilisant la méthode de l’amortissement dégressif à taux fixe.\r\nDDB\t\t\t= DDB\t\t\t\t##\tRenvoie l’amortissement d’un bien pour toute période spécifiée, en utilisant la méthode de l’amortissement dégressif à taux double ou selon un coefficient à spécifier.\r\nDISC\t\t\t= TAUX.ESCOMPTE\t\t\t##\tCalcule le taux d’escompte d’une transaction.\r\nDOLLARDE\t\t= PRIX.DEC\t\t\t##\tConvertit un prix en euros, exprimé sous forme de fraction, en un prix en euros exprimé sous forme de nombre décimal.\r\nDOLLARFR\t\t= PRIX.FRAC\t\t\t##\tConvertit un prix en euros, exprimé sous forme de nombre décimal, en un prix en euros exprimé sous forme de fraction.\r\nDURATION\t\t= DUREE\t\t\t\t##\tRenvoie la durée, en années, d’un titre dont l’intérêt est perçu périodiquement.\r\nEFFECT\t\t\t= TAUX.EFFECTIF\t\t\t##\tRenvoie le taux d’intérêt annuel effectif.\r\nFV\t\t\t= VC\t\t\t\t##\tRenvoie la valeur future d’un investissement.\r\nFVSCHEDULE\t\t= VC.PAIEMENTS\t\t\t##\tCalcule la valeur future d’un investissement en appliquant une série de taux d’intérêt composites.\r\nINTRATE\t\t\t= TAUX.INTERET\t\t\t##\tAffiche le taux d’intérêt d’un titre totalement investi.\r\nIPMT\t\t\t= INTPER\t\t\t##\tCalcule le montant des intérêts d’un investissement pour une période donnée.\r\nIRR\t\t\t= TRI\t\t\t\t##\tCalcule le taux de rentabilité interne d’un investissement pour une succession de trésoreries.\r\nISPMT\t\t\t= ISPMT\t\t\t\t##\tCalcule le montant des intérêts d’un investissement pour une période donnée.\r\nMDURATION\t\t= DUREE.MODIFIEE\t\t##\tRenvoie la durée de Macauley modifiée pour un titre ayant une valeur nominale hypothétique de 100_euros.\r\nMIRR\t\t\t= TRIM\t\t\t\t##\tCalcule le taux de rentabilité interne lorsque les paiements positifs et négatifs sont financés à des taux différents.\r\nNOMINAL\t\t\t= TAUX.NOMINAL\t\t\t##\tCalcule le taux d’intérêt nominal annuel.\r\nNPER\t\t\t= NPM\t\t\t\t##\tRenvoie le nombre de versements nécessaires pour rembourser un emprunt.\r\nNPV\t\t\t= VAN\t\t\t\t##\tCalcule la valeur actuelle nette d’un investissement basé sur une série de décaissements et un taux d’escompte.\r\nODDFPRICE\t\t= PRIX.PCOUPON.IRREG\t\t##\tRenvoie le prix par tranche de valeur nominale de 100 euros d’un titre dont la première période de coupon est irrégulière.\r\nODDFYIELD\t\t= REND.PCOUPON.IRREG\t\t##\tRenvoie le taux de rendement d’un titre dont la première période de coupon est irrégulière.\r\nODDLPRICE\t\t= PRIX.DCOUPON.IRREG\t\t##\tRenvoie le prix par tranche de valeur nominale de 100 euros d’un titre dont la première période de coupon est irrégulière.\r\nODDLYIELD\t\t= REND.DCOUPON.IRREG\t\t##\tRenvoie le taux de rendement d’un titre dont la dernière période de coupon est irrégulière.\r\nPMT\t\t\t= VPM\t\t\t\t##\tCalcule le paiement périodique d’un investissement donné.\r\nPPMT\t\t\t= PRINCPER\t\t\t##\tCalcule, pour une période donnée, la part de remboursement du principal d’un investissement.\r\nPRICE\t\t\t= PRIX.TITRE\t\t\t##\tRenvoie le prix d’un titre rapportant des intérêts périodiques, pour une valeur nominale de 100 euros.\r\nPRICEDISC\t\t= VALEUR.ENCAISSEMENT\t\t##\tRenvoie la valeur d’encaissement d’un escompte commercial, pour une valeur nominale de 100 euros.\r\nPRICEMAT\t\t= PRIX.TITRE.ECHEANCE\t\t##\tRenvoie le prix d’un titre dont la valeur nominale est 100 euros et qui rapporte des intérêts à l’échéance.\r\nPV\t\t\t= PV\t\t\t\t##\tCalcule la valeur actuelle d’un investissement.\r\nRATE\t\t\t= TAUX\t\t\t\t##\tCalcule le taux d’intérêt par période pour une annuité.\r\nRECEIVED\t\t= VALEUR.NOMINALE\t\t##\tRenvoie la valeur nominale à échéance d’un effet de commerce.\r\nSLN\t\t\t= AMORLIN\t\t\t##\tCalcule l’amortissement linéaire d’un bien pour une période donnée.\r\nSYD\t\t\t= SYD\t\t\t\t##\tCalcule l’amortissement d’un bien pour une période donnée sur la base de la méthode américaine Sum-of-Years Digits (amortissement dégressif à taux décroissant appliqué à une valeur constante).\r\nTBILLEQ\t\t\t= TAUX.ESCOMPTE.R\t\t##\tRenvoie le taux d’escompte rationnel d’un bon du Trésor.\r\nTBILLPRICE\t\t= PRIX.BON.TRESOR\t\t##\tRenvoie le prix d’un bon du Trésor d’une valeur nominale de 100 euros.\r\nTBILLYIELD\t\t= RENDEMENT.BON.TRESOR\t\t##\tCalcule le taux de rendement d’un bon du Trésor.\r\nVDB\t\t\t= VDB\t\t\t\t##\tRenvoie l’amortissement d’un bien pour une période spécifiée ou partielle en utilisant une méthode de l’amortissement dégressif à taux fixe.\r\nXIRR\t\t\t= TRI.PAIEMENTS\t\t\t##\tCalcule le taux de rentabilité interne d’un ensemble de paiements non périodiques.\r\nXNPV\t\t\t= VAN.PAIEMENTS\t\t\t##\tRenvoie la valeur actuelle nette d’un ensemble de paiements non périodiques.\r\nYIELD\t\t\t= RENDEMENT.TITRE\t\t##\tCalcule le rendement d’un titre rapportant des intérêts périodiquement.\r\nYIELDDISC\t\t= RENDEMENT.SIMPLE\t\t##\tCalcule le taux de rendement d’un emprunt à intérêt simple (par exemple, un bon du Trésor).\r\nYIELDMAT\t\t= RENDEMENT.TITRE.ECHEANCE\t##\tRenvoie le rendement annuel d’un titre qui rapporte des intérêts à l’échéance.\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\tFonctions d’information\r\n##\r\nCELL\t\t\t= CELLULE\t\t\t##\tRenvoie des informations sur la mise en forme, l’emplacement et le contenu d’une cellule.\r\nERROR.TYPE\t\t= TYPE.ERREUR\t\t\t##\tRenvoie un nombre correspondant à un type d’erreur.\r\nINFO\t\t\t= INFORMATIONS\t\t\t##\tRenvoie des informations sur l’environnement d’exploitation actuel.\r\nISBLANK\t\t\t= ESTVIDE\t\t\t##\tRenvoie VRAI si l’argument valeur est vide.\r\nISERR\t\t\t= ESTERR\t\t\t##\tRenvoie VRAI si l’argument valeur fait référence à une valeur d’erreur, sauf #N/A.\r\nISERROR\t\t\t= ESTERREUR\t\t\t##\tRenvoie VRAI si l’argument valeur fait référence à une valeur d’erreur.\r\nISEVEN\t\t\t= EST.PAIR\t\t\t##\tRenvoie VRAI si le chiffre est pair.\r\nISLOGICAL\t\t= ESTLOGIQUE\t\t\t##\tRenvoie VRAI si l’argument valeur fait référence à une valeur logique.\r\nISNA\t\t\t= ESTNA\t\t\t\t##\tRenvoie VRAI si l’argument valeur fait référence à la valeur d’erreur #N/A.\r\nISNONTEXT\t\t= ESTNONTEXTE\t\t\t##\tRenvoie VRAI si l’argument valeur ne se présente pas sous forme de texte.\r\nISNUMBER\t\t= ESTNUM\t\t\t##\tRenvoie VRAI si l’argument valeur représente un nombre.\r\nISODD\t\t\t= EST.IMPAIR\t\t\t##\tRenvoie VRAI si le chiffre est impair.\r\nISREF\t\t\t= ESTREF\t\t\t##\tRenvoie VRAI si l’argument valeur est une référence.\r\nISTEXT\t\t\t= ESTTEXTE\t\t\t##\tRenvoie VRAI si l’argument valeur se présente sous forme de texte.\r\nN\t\t\t= N\t\t\t\t##\tRenvoie une valeur convertie en nombre.\r\nNA\t\t\t= NA\t\t\t\t##\tRenvoie la valeur d’erreur #N/A.\r\nTYPE\t\t\t= TYPE\t\t\t\t##\tRenvoie un nombre indiquant le type de données d’une valeur.\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\tFonctions logiques\r\n##\r\nAND\t\t\t= ET\t\t\t\t##\tRenvoie VRAI si tous ses arguments sont VRAI.\r\nFALSE\t\t\t= FAUX\t\t\t\t##\tRenvoie la valeur logique FAUX.\r\nIF\t\t\t= SI\t\t\t\t##\tSpécifie un test logique à effectuer.\r\nIFERROR\t\t\t= SIERREUR\t\t\t##\tRenvoie une valeur que vous spécifiez si une formule génère une erreur ; sinon, elle renvoie le résultat de la formule.\r\nNOT\t\t\t= NON\t\t\t\t##\tInverse la logique de cet argument.\r\nOR\t\t\t= OU\t\t\t\t##\tRenvoie VRAI si un des arguments est VRAI.\r\nTRUE\t\t\t= VRAI\t\t\t\t##\tRenvoie la valeur logique VRAI.\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\tFonctions de recherche et de référence\r\n##\r\nADDRESS\t\t\t= ADRESSE\t\t\t##\tRenvoie une référence sous forme de texte à une seule cellule d’une feuille de calcul.\r\nAREAS\t\t\t= ZONES\t\t\t\t##\tRenvoie le nombre de zones dans une référence.\r\nCHOOSE\t\t\t= CHOISIR\t\t\t##\tChoisit une valeur dans une liste.\r\nCOLUMN\t\t\t= COLONNE\t\t\t##\tRenvoie le numéro de colonne d’une référence.\r\nCOLUMNS\t\t\t= COLONNES\t\t\t##\tRenvoie le nombre de colonnes dans une référence.\r\nHLOOKUP\t\t\t= RECHERCHEH\t\t\t##\tEffectue une recherche dans la première ligne d’une matrice et renvoie la valeur de la cellule indiquée.\r\nHYPERLINK\t\t= LIEN_HYPERTEXTE\t\t##\tCrée un raccourci ou un renvoi qui ouvre un document stocké sur un serveur réseau, sur un réseau Intranet ou sur Internet.\r\nINDEX\t\t\t= INDEX\t\t\t\t##\tUtilise un index pour choisir une valeur provenant d’une référence ou d’une matrice.\r\nINDIRECT\t\t= INDIRECT\t\t\t##\tRenvoie une référence indiquée par une valeur de texte.\r\nLOOKUP\t\t\t= RECHERCHE\t\t\t##\tRecherche des valeurs dans un vecteur ou une matrice.\r\nMATCH\t\t\t= EQUIV\t\t\t\t##\tRecherche des valeurs dans une référence ou une matrice.\r\nOFFSET\t\t\t= DECALER\t\t\t##\tRenvoie une référence décalée par rapport à une référence donnée.\r\nROW\t\t\t= LIGNE\t\t\t\t##\tRenvoie le numéro de ligne d’une référence.\r\nROWS\t\t\t= LIGNES\t\t\t##\tRenvoie le nombre de lignes dans une référence.\r\nRTD\t\t\t= RTD\t\t\t\t##\tExtrait les données en temps réel à partir d’un programme prenant en charge l’automation COM (Automation : utilisation des objets d'une application à partir d'une autre application ou d'un autre outil de développement. Autrefois appelée OLE Automation, Automation est une norme industrielle et une fonctionnalité du modèle d'objet COM (Component Object Model).).\r\nTRANSPOSE\t\t= TRANSPOSE\t\t\t##\tRenvoie la transposition d’une matrice.\r\nVLOOKUP\t\t\t= RECHERCHEV\t\t\t##\tEffectue une recherche dans la première colonne d’une matrice et se déplace sur la ligne pour renvoyer la valeur d’une cellule.\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\tFonctions mathématiques et trigonométriques\r\n##\r\nABS\t\t\t= ABS\t\t\t\t##\tRenvoie la valeur absolue d’un nombre.\r\nACOS\t\t\t= ACOS\t\t\t\t##\tRenvoie l’arccosinus d’un nombre.\r\nACOSH\t\t\t= ACOSH\t\t\t\t##\tRenvoie le cosinus hyperbolique inverse d’un nombre.\r\nASIN\t\t\t= ASIN\t\t\t\t##\tRenvoie l’arcsinus d’un nombre.\r\nASINH\t\t\t= ASINH\t\t\t\t##\tRenvoie le sinus hyperbolique inverse d’un nombre.\r\nATAN\t\t\t= ATAN\t\t\t\t##\tRenvoie l’arctangente d’un nombre.\r\nATAN2\t\t\t= ATAN2\t\t\t\t##\tRenvoie l’arctangente des coordonnées x et y.\r\nATANH\t\t\t= ATANH\t\t\t\t##\tRenvoie la tangente hyperbolique inverse d’un nombre.\r\nCEILING\t\t\t= PLAFOND\t\t\t##\tArrondit un nombre au nombre entier le plus proche ou au multiple le plus proche de l’argument précision en s’éloignant de zéro.\r\nCOMBIN\t\t\t= COMBIN\t\t\t##\tRenvoie le nombre de combinaisons que l’on peut former avec un nombre donné d’objets.\r\nCOS\t\t\t= COS\t\t\t\t##\tRenvoie le cosinus d’un nombre.\r\nCOSH\t\t\t= COSH\t\t\t\t##\tRenvoie le cosinus hyperbolique d’un nombre.\r\nDEGREES\t\t\t= DEGRES\t\t\t##\tConvertit des radians en degrés.\r\nEVEN\t\t\t= PAIR\t\t\t\t##\tArrondit un nombre au nombre entier pair le plus proche en s’éloignant de zéro.\r\nEXP\t\t\t= EXP\t\t\t\t##\tRenvoie e élevé à la puissance d’un nombre donné.\r\nFACT\t\t\t= FACT\t\t\t\t##\tRenvoie la factorielle d’un nombre.\r\nFACTDOUBLE\t\t= FACTDOUBLE\t\t\t##\tRenvoie la factorielle double d’un nombre.\r\nFLOOR\t\t\t= PLANCHER\t\t\t##\tArrondit un nombre en tendant vers 0 (zéro).\r\nGCD\t\t\t= PGCD\t\t\t\t##\tRenvoie le plus grand commun diviseur.\r\nINT\t\t\t= ENT\t\t\t\t##\tArrondit un nombre à l’entier immédiatement inférieur.\r\nLCM\t\t\t= PPCM\t\t\t\t##\tRenvoie le plus petit commun multiple.\r\nLN\t\t\t= LN\t\t\t\t##\tRenvoie le logarithme népérien d’un nombre.\r\nLOG\t\t\t= LOG\t\t\t\t##\tRenvoie le logarithme d’un nombre dans la base spécifiée.\r\nLOG10\t\t\t= LOG10\t\t\t\t##\tCalcule le logarithme en base 10 d’un nombre.\r\nMDETERM\t\t\t= DETERMAT\t\t\t##\tRenvoie le déterminant d’une matrice.\r\nMINVERSE\t\t= INVERSEMAT\t\t\t##\tRenvoie la matrice inverse d’une matrice.\r\nMMULT\t\t\t= PRODUITMAT\t\t\t##\tRenvoie le produit de deux matrices.\r\nMOD\t\t\t= MOD\t\t\t\t##\tRenvoie le reste d’une division.\r\nMROUND\t\t\t= ARRONDI.AU.MULTIPLE\t\t##\tDonne l’arrondi d’un nombre au multiple spécifié.\r\nMULTINOMIAL\t\t= MULTINOMIALE\t\t\t##\tCalcule la multinomiale d’un ensemble de nombres.\r\nODD\t\t\t= IMPAIR\t\t\t##\tRenvoie le nombre, arrondi à la valeur du nombre entier impair le plus proche en s’éloignant de zéro.\r\nPI\t\t\t= PI\t\t\t\t##\tRenvoie la valeur de pi.\r\nPOWER\t\t\t= PUISSANCE\t\t\t##\tRenvoie la valeur du nombre élevé à une puissance.\r\nPRODUCT\t\t\t= PRODUIT\t\t\t##\tMultiplie ses arguments.\r\nQUOTIENT\t\t= QUOTIENT\t\t\t##\tRenvoie la partie entière du résultat d’une division.\r\nRADIANS\t\t\t= RADIANS\t\t\t##\tConvertit des degrés en radians.\r\nRAND\t\t\t= ALEA\t\t\t\t##\tRenvoie un nombre aléatoire compris entre 0 et 1.\r\nRANDBETWEEN\t\t= ALEA.ENTRE.BORNES\t\t##\tRenvoie un nombre aléatoire entre les nombres que vous spécifiez.\r\nROMAN\t\t\t= ROMAIN\t\t\t##\tConvertit des chiffres arabes en chiffres romains, sous forme de texte.\r\nROUND\t\t\t= ARRONDI\t\t\t##\tArrondit un nombre au nombre de chiffres indiqué.\r\nROUNDDOWN\t\t= ARRONDI.INF\t\t\t##\tArrondit un nombre en tendant vers 0 (zéro).\r\nROUNDUP\t\t\t= ARRONDI.SUP\t\t\t##\tArrondit un nombre à l’entier supérieur, en s’éloignant de zéro.\r\nSERIESSUM\t\t= SOMME.SERIES\t\t\t##\tRenvoie la somme d’une série géométrique en s’appuyant sur la formule suivante :\r\nSIGN\t\t\t= SIGNE\t\t\t\t##\tRenvoie le signe d’un nombre.\r\nSIN\t\t\t= SIN\t\t\t\t##\tRenvoie le sinus d’un angle donné.\r\nSINH\t\t\t= SINH\t\t\t\t##\tRenvoie le sinus hyperbolique d’un nombre.\r\nSQRT\t\t\t= RACINE\t\t\t##\tRenvoie la racine carrée d’un nombre.\r\nSQRTPI\t\t\t= RACINE.PI\t\t\t##\tRenvoie la racine carrée de (nombre * pi).\r\nSUBTOTAL\t\t= SOUS.TOTAL\t\t\t##\tRenvoie un sous-total dans une liste ou une base de données.\r\nSUM\t\t\t= SOMME\t\t\t\t##\tCalcule la somme de ses arguments.\r\nSUMIF\t\t\t= SOMME.SI\t\t\t##\tAdditionne les cellules spécifiées si elles répondent à un critère donné.\r\nSUMIFS\t\t\t= SOMME.SI.ENS\t\t\t##\tAjoute les cellules d’une plage qui répondent à plusieurs critères.\r\nSUMPRODUCT\t\t= SOMMEPROD\t\t\t##\tMultiplie les valeurs correspondantes des matrices spécifiées et calcule la somme de ces produits.\r\nSUMSQ\t\t\t= SOMME.CARRES\t\t\t##\tRenvoie la somme des carrés des arguments.\r\nSUMX2MY2\t\t= SOMME.X2MY2\t\t\t##\tRenvoie la somme de la différence des carrés des valeurs correspondantes de deux matrices.\r\nSUMX2PY2\t\t= SOMME.X2PY2\t\t\t##\tRenvoie la somme de la somme des carrés des valeurs correspondantes de deux matrices.\r\nSUMXMY2\t\t\t= SOMME.XMY2\t\t\t##\tRenvoie la somme des carrés des différences entre les valeurs correspondantes de deux matrices.\r\nTAN\t\t\t= TAN\t\t\t\t##\tRenvoie la tangente d’un nombre.\r\nTANH\t\t\t= TANH\t\t\t\t##\tRenvoie la tangente hyperbolique d’un nombre.\r\nTRUNC\t\t\t= TRONQUE\t\t\t##\tRenvoie la partie entière d’un nombre.\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\tFonctions statistiques\r\n##\r\nAVEDEV\t\t\t= ECART.MOYEN\t\t\t##\tRenvoie la moyenne des écarts absolus observés dans la moyenne des points de données.\r\nAVERAGE\t\t\t= MOYENNE\t\t\t##\tRenvoie la moyenne de ses arguments.\r\nAVERAGEA\t\t= AVERAGEA\t\t\t##\tRenvoie la moyenne de ses arguments, nombres, texte et valeurs logiques inclus.\r\nAVERAGEIF\t\t= MOYENNE.SI\t\t\t##\tRenvoie la moyenne (arithmétique) de toutes les cellules d’une plage qui répondent à des critères donnés.\r\nAVERAGEIFS\t\t= MOYENNE.SI.ENS\t\t##\tRenvoie la moyenne (arithmétique) de toutes les cellules qui répondent à plusieurs critères.\r\nBETADIST\t\t= LOI.BETA\t\t\t##\tRenvoie la fonction de distribution cumulée.\r\nBETAINV\t\t\t= BETA.INVERSE\t\t\t##\tRenvoie l’inverse de la fonction de distribution cumulée pour une distribution bêta spécifiée.\r\nBINOMDIST\t\t= LOI.BINOMIALE\t\t\t##\tRenvoie la probabilité d’une variable aléatoire discrète suivant la loi binomiale.\r\nCHIDIST\t\t\t= LOI.KHIDEUX\t\t\t##\tRenvoie la probabilité unilatérale de la distribution khi-deux.\r\nCHIINV\t\t\t= KHIDEUX.INVERSE\t\t##\tRenvoie l’inverse de la probabilité unilatérale de la distribution khi-deux.\r\nCHITEST\t\t\t= TEST.KHIDEUX\t\t\t##\tRenvoie le test d’indépendance.\r\nCONFIDENCE\t\t= INTERVALLE.CONFIANCE\t\t##\tRenvoie l’intervalle de confiance pour une moyenne de population.\r\nCORREL\t\t\t= COEFFICIENT.CORRELATION\t##\tRenvoie le coefficient de corrélation entre deux séries de données.\r\nCOUNT\t\t\t= NB\t\t\t\t##\tDétermine les nombres compris dans la liste des arguments.\r\nCOUNTA\t\t\t= NBVAL\t\t\t\t##\tDétermine le nombre de valeurs comprises dans la liste des arguments.\r\nCOUNTBLANK\t\t= NB.VIDE\t\t\t##\tCompte le nombre de cellules vides dans une plage.\r\nCOUNTIF\t\t\t= NB.SI\t\t\t\t##\tCompte le nombre de cellules qui répondent à un critère donné dans une plage.\r\nCOUNTIFS\t\t= NB.SI.ENS\t\t\t##\tCompte le nombre de cellules à l’intérieur d’une plage qui répondent à plusieurs critères.\r\nCOVAR\t\t\t= COVARIANCE\t\t\t##\tRenvoie la covariance, moyenne des produits des écarts pour chaque série d’observations.\r\nCRITBINOM\t\t= CRITERE.LOI.BINOMIALE\t\t##\tRenvoie la plus petite valeur pour laquelle la distribution binomiale cumulée est inférieure ou égale à une valeur de critère.\r\nDEVSQ\t\t\t= SOMME.CARRES.ECARTS\t\t##\tRenvoie la somme des carrés des écarts.\r\nEXPONDIST\t\t= LOI.EXPONENTIELLE\t\t##\tRenvoie la distribution exponentielle.\r\nFDIST\t\t\t= LOI.F\t\t\t\t##\tRenvoie la distribution de probabilité F.\r\nFINV\t\t\t= INVERSE.LOI.F\t\t\t##\tRenvoie l’inverse de la distribution de probabilité F.\r\nFISHER\t\t\t= FISHER\t\t\t##\tRenvoie la transformation de Fisher.\r\nFISHERINV\t\t= FISHER.INVERSE\t\t##\tRenvoie l’inverse de la transformation de Fisher.\r\nFORECAST\t\t= PREVISION\t\t\t##\tCalcule une valeur par rapport à une tendance linéaire.\r\nFREQUENCY\t\t= FREQUENCE\t\t\t##\tCalcule la fréquence d’apparition des valeurs dans une plage de valeurs, puis renvoie des nombres sous forme de matrice verticale.\r\nFTEST\t\t\t= TEST.F\t\t\t##\tRenvoie le résultat d’un test F.\r\nGAMMADIST\t\t= LOI.GAMMA\t\t\t##\tRenvoie la probabilité d’une variable aléatoire suivant une loi Gamma.\r\nGAMMAINV\t\t= LOI.GAMMA.INVERSE\t\t##\tRenvoie, pour une probabilité donnée, la valeur d’une variable aléatoire suivant une loi Gamma.\r\nGAMMALN\t\t\t= LNGAMMA\t\t\t##\tRenvoie le logarithme népérien de la fonction Gamma, G(x)\r\nGEOMEAN\t\t\t= MOYENNE.GEOMETRIQUE\t\t##\tRenvoie la moyenne géométrique.\r\nGROWTH\t\t\t= CROISSANCE\t\t\t##\tCalcule des valeurs par rapport à une tendance exponentielle.\r\nHARMEAN\t\t\t= MOYENNE.HARMONIQUE\t\t##\tRenvoie la moyenne harmonique.\r\nHYPGEOMDIST\t\t= LOI.HYPERGEOMETRIQUE\t\t##\tRenvoie la probabilité d’une variable aléatoire discrète suivant une loi hypergéométrique.\r\nINTERCEPT\t\t= ORDONNEE.ORIGINE\t\t##\tRenvoie l’ordonnée à l’origine d’une droite de régression linéaire.\r\nKURT\t\t\t= KURTOSIS\t\t\t##\tRenvoie le kurtosis d’une série de données.\r\nLARGE\t\t\t= GRANDE.VALEUR\t\t\t##\tRenvoie la k-ième plus grande valeur d’une série de données.\r\nLINEST\t\t\t= DROITEREG\t\t\t##\tRenvoie les paramètres d’une tendance linéaire.\r\nLOGEST\t\t\t= LOGREG\t\t\t##\tRenvoie les paramètres d’une tendance exponentielle.\r\nLOGINV\t\t\t= LOI.LOGNORMALE.INVERSE\t##\tRenvoie l’inverse de la probabilité pour une variable aléatoire suivant la loi lognormale.\r\nLOGNORMDIST\t\t= LOI.LOGNORMALE\t\t##\tRenvoie la probabilité d’une variable aléatoire continue suivant une loi lognormale.\r\nMAX\t\t\t= MAX\t\t\t\t##\tRenvoie la valeur maximale contenue dans une liste d’arguments.\r\nMAXA\t\t\t= MAXA\t\t\t\t##\tRenvoie la valeur maximale d’une liste d’arguments, nombres, texte et valeurs logiques inclus.\r\nMEDIAN\t\t\t= MEDIANE\t\t\t##\tRenvoie la valeur médiane des nombres donnés.\r\nMIN\t\t\t= MIN\t\t\t\t##\tRenvoie la valeur minimale contenue dans une liste d’arguments.\r\nMINA\t\t\t= MINA\t\t\t\t##\tRenvoie la plus petite valeur d’une liste d’arguments, nombres, texte et valeurs logiques inclus.\r\nMODE\t\t\t= MODE\t\t\t\t##\tRenvoie la valeur la plus courante d’une série de données.\r\nNEGBINOMDIST\t\t= LOI.BINOMIALE.NEG\t\t##\tRenvoie la probabilité d’une variable aléatoire discrète suivant une loi binomiale négative.\r\nNORMDIST\t\t= LOI.NORMALE\t\t\t##\tRenvoie la probabilité d’une variable aléatoire continue suivant une loi normale.\r\nNORMINV\t\t\t= LOI.NORMALE.INVERSE\t\t##\tRenvoie, pour une probabilité donnée, la valeur d’une variable aléatoire suivant une loi normale standard.\r\nNORMSDIST\t\t= LOI.NORMALE.STANDARD\t\t##\tRenvoie la probabilité d’une variable aléatoire continue suivant une loi normale standard.\r\nNORMSINV\t\t= LOI.NORMALE.STANDARD.INVERSE\t##\tRenvoie l’inverse de la distribution cumulée normale standard.\r\nPEARSON\t\t\t= PEARSON\t\t\t##\tRenvoie le coefficient de corrélation d’échantillonnage de Pearson.\r\nPERCENTILE\t\t= CENTILE\t\t\t##\tRenvoie le k-ième centile des valeurs d’une plage.\r\nPERCENTRANK\t\t= RANG.POURCENTAGE\t\t##\tRenvoie le rang en pourcentage d’une valeur d’une série de données.\r\nPERMUT\t\t\t= PERMUTATION\t\t\t##\tRenvoie le nombre de permutations pour un nombre donné d’objets.\r\nPOISSON\t\t\t= LOI.POISSON\t\t\t##\tRenvoie la probabilité d’une variable aléatoire suivant une loi de Poisson.\r\nPROB\t\t\t= PROBABILITE\t\t\t##\tRenvoie la probabilité que des valeurs d’une plage soient comprises entre deux limites.\r\nQUARTILE\t\t= QUARTILE\t\t\t##\tRenvoie le quartile d’une série de données.\r\nRANK\t\t\t= RANG\t\t\t\t##\tRenvoie le rang d’un nombre contenu dans une liste.\r\nRSQ\t\t\t= COEFFICIENT.DETERMINATION\t##\tRenvoie la valeur du coefficient de détermination R^2 d’une régression linéaire.\r\nSKEW\t\t\t= COEFFICIENT.ASYMETRIE\t\t##\tRenvoie l’asymétrie d’une distribution.\r\nSLOPE\t\t\t= PENTE\t\t\t\t##\tRenvoie la pente d’une droite de régression linéaire.\r\nSMALL\t\t\t= PETITE.VALEUR\t\t\t##\tRenvoie la k-ième plus petite valeur d’une série de données.\r\nSTANDARDIZE\t\t= CENTREE.REDUITE\t\t##\tRenvoie une valeur centrée réduite.\r\nSTDEV\t\t\t= ECARTYPE\t\t\t##\tÉvalue l’écart type d’une population en se basant sur un échantillon de cette population.\r\nSTDEVA\t\t\t= STDEVA\t\t\t##\tÉvalue l’écart type d’une population en se basant sur un échantillon de cette population, nombres, texte et valeurs logiques inclus.\r\nSTDEVP\t\t\t= ECARTYPEP\t\t\t##\tCalcule l’écart type d’une population à partir de la population entière.\r\nSTDEVPA\t\t\t= STDEVPA\t\t\t##\tCalcule l’écart type d’une population à partir de l’ensemble de la population, nombres, texte et valeurs logiques inclus.\r\nSTEYX\t\t\t= ERREUR.TYPE.XY\t\t##\tRenvoie l’erreur type de la valeur y prévue pour chaque x de la régression.\r\nTDIST\t\t\t= LOI.STUDENT\t\t\t##\tRenvoie la probabilité d’une variable aléatoire suivant une loi T de Student.\r\nTINV\t\t\t= LOI.STUDENT.INVERSE\t\t##\tRenvoie, pour une probabilité donnée, la valeur d’une variable aléatoire suivant une loi T de Student.\r\nTREND\t\t\t= TENDANCE\t\t\t##\tRenvoie des valeurs par rapport à une tendance linéaire.\r\nTRIMMEAN\t\t= MOYENNE.REDUITE\t\t##\tRenvoie la moyenne de l’intérieur d’une série de données.\r\nTTEST\t\t\t= TEST.STUDENT\t\t\t##\tRenvoie la probabilité associée à un test T de Student.\r\nVAR\t\t\t= VAR\t\t\t\t##\tCalcule la variance sur la base d’un échantillon.\r\nVARA\t\t\t= VARA\t\t\t\t##\tEstime la variance d’une population en se basant sur un échantillon de cette population, nombres, texte et valeurs logiques incluses.\r\nVARP\t\t\t= VAR.P\t\t\t\t##\tCalcule la variance sur la base de l’ensemble de la population.\r\nVARPA\t\t\t= VARPA\t\t\t\t##\tCalcule la variance d’une population en se basant sur la population entière, nombres, texte et valeurs logiques inclus.\r\nWEIBULL\t\t\t= LOI.WEIBULL\t\t\t##\tRenvoie la probabilité d’une variable aléatoire suivant une loi de Weibull.\r\nZTEST\t\t\t= TEST.Z\t\t\t##\tRenvoie la valeur de probabilité unilatérale d’un test z.\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\tFonctions de texte\r\n##\r\nASC\t\t\t= ASC\t\t\t\t##\tChange les caractères anglais ou katakana à pleine chasse (codés sur deux octets) à l’intérieur d’une chaîne de caractères en caractères à demi-chasse (codés sur un octet).\r\nBAHTTEXT\t\t= BAHTTEXT\t\t\t##\tConvertit un nombre en texte en utilisant le format monétaire ß (baht).\r\nCHAR\t\t\t= CAR\t\t\t\t##\tRenvoie le caractère spécifié par le code numérique.\r\nCLEAN\t\t\t= EPURAGE\t\t\t##\tSupprime tous les caractères de contrôle du texte.\r\nCODE\t\t\t= CODE\t\t\t\t##\tRenvoie le numéro de code du premier caractère du texte.\r\nCONCATENATE\t\t= CONCATENER\t\t\t##\tAssemble plusieurs éléments textuels de façon à n’en former qu’un seul.\r\nDOLLAR\t\t\t= EURO\t\t\t\t##\tConvertit un nombre en texte en utilisant le format monétaire € (euro).\r\nEXACT\t\t\t= EXACT\t\t\t\t##\tVérifie si deux valeurs de texte sont identiques.\r\nFIND\t\t\t= TROUVE\t\t\t##\tTrouve un valeur textuelle dans une autre, en respectant la casse.\r\nFINDB\t\t\t= TROUVERB\t\t\t##\tTrouve un valeur textuelle dans une autre, en respectant la casse.\r\nFIXED\t\t\t= CTXT\t\t\t\t##\tConvertit un nombre au format texte avec un nombre de décimales spécifié.\r\nJIS\t\t\t= JIS\t\t\t\t##\tChange les caractères anglais ou katakana à demi-chasse (codés sur un octet) à l’intérieur d’une chaîne de caractères en caractères à à pleine chasse (codés sur deux octets).\r\nLEFT\t\t\t= GAUCHE\t\t\t##\tRenvoie des caractères situés à l’extrême gauche d’une chaîne de caractères.\r\nLEFTB\t\t\t= GAUCHEB\t\t\t##\tRenvoie des caractères situés à l’extrême gauche d’une chaîne de caractères.\r\nLEN\t\t\t= NBCAR\t\t\t\t##\tRenvoie le nombre de caractères contenus dans une chaîne de texte.\r\nLENB\t\t\t= LENB\t\t\t\t##\tRenvoie le nombre de caractères contenus dans une chaîne de texte.\r\nLOWER\t\t\t= MINUSCULE\t\t\t##\tConvertit le texte en minuscules.\r\nMID\t\t\t= STXT\t\t\t\t##\tRenvoie un nombre déterminé de caractères d’une chaîne de texte à partir de la position que vous indiquez.\r\nMIDB\t\t\t= STXTB\t\t\t\t##\tRenvoie un nombre déterminé de caractères d’une chaîne de texte à partir de la position que vous indiquez.\r\nPHONETIC\t\t= PHONETIQUE\t\t\t##\tExtrait les caractères phonétiques (furigana) d’une chaîne de texte.\r\nPROPER\t\t\t= NOMPROPRE\t\t\t##\tMet en majuscules la première lettre de chaque mot dans une chaîne textuelle.\r\nREPLACE\t\t\t= REMPLACER\t\t\t##\tRemplace des caractères dans un texte.\r\nREPLACEB\t\t= REMPLACERB\t\t\t##\tRemplace des caractères dans un texte.\r\nREPT\t\t\t= REPT\t\t\t\t##\tRépète un texte un certain nombre de fois.\r\nRIGHT\t\t\t= DROITE\t\t\t##\tRenvoie des caractères situés à l’extrême droite d’une chaîne de caractères.\r\nRIGHTB\t\t\t= DROITEB\t\t\t##\tRenvoie des caractères situés à l’extrême droite d’une chaîne de caractères.\r\nSEARCH\t\t\t= CHERCHE\t\t\t##\tTrouve un texte dans un autre texte (sans respecter la casse).\r\nSEARCHB\t\t\t= CHERCHERB\t\t\t##\tTrouve un texte dans un autre texte (sans respecter la casse).\r\nSUBSTITUTE\t\t= SUBSTITUE\t\t\t##\tRemplace l’ancien texte d’une chaîne de caractères par un nouveau.\r\nT\t\t\t= T\t\t\t\t##\tConvertit ses arguments en texte.\r\nTEXT\t\t\t= TEXTE\t\t\t\t##\tConvertit un nombre au format texte.\r\nTRIM\t\t\t= SUPPRESPACE\t\t\t##\tSupprime les espaces du texte.\r\nUPPER\t\t\t= MAJUSCULE\t\t\t##\tConvertit le texte en majuscules.\r\nVALUE\t\t\t= CNUM\t\t\t\t##\tConvertit un argument textuel en nombre\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= Ft\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\n##\r\nNULL\t= #NULLA!\r\nDIV0\t= #ZÉRÓOSZTÓ!\r\nVALUE\t= #ÉRTÉK!\r\nREF\t= #HIV!\r\nNAME\t= #NÉV?\r\nNUM\t= #SZÁM!\r\nNA\t= #HIÁNYZIK\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/hu/functions",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Calculation\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/\r\n##\r\n##\r\n\r\n\r\n##\r\n##\tAdd-in and Automation functions\t\t\tBővítmények és automatizálási függvények\r\n##\r\nGETPIVOTDATA\t\t= KIMUTATÁSADATOT.VESZ\t\t##\tA kimutatásokban tárolt adatok visszaadására használható.\r\n\r\n\r\n##\r\n##\tCube functions Kockafüggvények   \r\n##\r\nCUBEKPIMEMBER\t\t= KOCKA.FŐTELJMUT\t\t##\tEgy fő teljesítménymutató (KPI) nevét, tulajdonságát és mértékegységét adja eredményül, a nevet és a tulajdonságot megjeleníti a cellában. A KPI-k számszerűsíthető mérési lehetőséget jelentenek – ilyen mutató például a havi bruttó nyereség vagy az egy alkalmazottra jutó negyedéves forgalom –, egy szervezet teljesítményének nyomonkövetésére használhatók.\r\nCUBEMEMBER\t\t= KOCKA.TAG\t\t\t##\tKockahierachia tagját vagy rekordját adja eredményül. Ellenőrizhető vele, hogy szerepel-e a kockában az adott tag vagy rekord.\r\nCUBEMEMBERPROPERTY\t= KOCKA.TAG.TUL\t\t\t##\tA kocka egyik tagtulajdonságának értékét adja eredményül. Használatával ellenőrizhető, hogy szerepel-e egy tagnév a kockában, eredménye pedig az erre a tagra vonatkozó, megadott tulajdonság.\r\nCUBERANKEDMEMBER\t= KOCKA.HALM.ELEM\t\t##\tEgy halmaz rangsor szerinti n-edik tagját adja eredményül. Használatával egy halmaz egy vagy több elemét kaphatja meg, például a legnagyobb teljesítményű üzletkötőt vagy a 10 legjobb tanulót.\r\nCUBESET\t\t\t= KOCKA.HALM\t\t\t##\tSzámított tagok vagy rekordok halmazát adja eredményül, ehhez egy beállított kifejezést elküld a kiszolgálón található kockának, majd ezt a halmazt adja vissza a Microsoft Office Excel alkalmazásnak.\r\nCUBESETCOUNT\t\t= KOCKA.HALM.DB\t\t\t##\tEgy halmaz elemszámát adja eredményül.\r\nCUBEVALUE\t\t= KOCKA.ÉRTÉK\t\t\t##\tKockából összesített értéket ad eredményül.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\tAdatbázis-kezelő függvények\r\n##\r\nDAVERAGE\t\t= AB.ÁTLAG\t\t\t##\tA kijelölt adatbáziselemek átlagát számítja ki.\r\nDCOUNT\t\t\t= AB.DARAB\t\t\t##\tMegszámolja, hogy az adatbázisban hány cella tartalmaz számokat.\r\nDCOUNTA\t\t\t= AB.DARAB2\t\t\t##\tMegszámolja az adatbázisban lévő nem üres cellákat.\r\nDGET\t\t\t= AB.MEZŐ\t\t\t##\tEgy adatbázisból egyetlen olyan rekordot ad vissza, amely megfelel a megadott feltételeknek.\r\nDMAX\t\t\t= AB.MAX\t\t\t##\tA kiválasztott adatbáziselemek közül a legnagyobb értéket adja eredményül.\r\nDMIN\t\t\t= AB.MIN\t\t\t##\tA kijelölt adatbáziselemek közül a legkisebb értéket adja eredményül.\r\nDPRODUCT\t\t= AB.SZORZAT\t\t\t##\tAz adatbázis megadott feltételeknek eleget tevő rekordjaira összeszorozza a megadott mezőben található számértékeket, és eredményül ezt a szorzatot adja.\r\nDSTDEV\t\t\t= AB.SZÓRÁS\t\t\t##\tA kijelölt adatbáziselemek egy mintája alapján megbecsüli a szórást.\r\nDSTDEVP\t\t\t= AB.SZÓRÁS2\t\t\t##\tA kijelölt adatbáziselemek teljes sokasága alapján kiszámítja a szórást.\r\nDSUM\t\t\t= AB.SZUM\t\t\t##\tÖsszeadja a feltételnek megfelelő adatbázisrekordok mezőoszlopában a számokat.\r\nDVAR\t\t\t= AB.VAR\t\t\t##\tA kijelölt adatbáziselemek mintája alapján becslést ad a szórásnégyzetre.\r\nDVARP\t\t\t= AB.VAR2\t\t\t##\tA kijelölt adatbáziselemek teljes sokasága alapján kiszámítja a szórásnégyzetet.\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\tDátumfüggvények\r\n##\r\nDATE\t\t\t= DÁTUM\t\t\t\t##\tAdott dátum dátumértékét adja eredményül.\r\nDATEVALUE\t\t= DÁTUMÉRTÉK\t\t\t##\tSzövegként megadott dátumot dátumértékké alakít át.\r\nDAY\t\t\t= NAP\t\t\t\t##\tDátumértéket a hónap egy napjává (0-31) alakít.\r\nDAYS360\t\t\t= NAP360\t\t\t##\tKét dátum közé eső napok számát számítja ki a 360 napos év alapján.\r\nEDATE\t\t\t= EDATE\t\t\t\t##\tAdott dátumnál adott számú hónappal korábbi vagy későbbi dátum dátumértékét adja eredményül.\r\nEOMONTH\t\t\t= EOMONTH\t\t\t##\tAdott dátumnál adott számú hónappal korábbi vagy későbbi hónap utolsó napjának dátumértékét adja eredményül.\r\nHOUR\t\t\t= ÓRA\t\t\t\t##\tIdőértéket órákká alakít.\r\nMINUTE\t\t\t= PERC\t\t\t\t##\tIdőértéket percekké alakít.\r\nMONTH\t\t\t= HÓNAP\t\t\t\t##\tIdőértéket hónapokká alakít.\r\nNETWORKDAYS\t\t= NETWORKDAYS\t\t\t##\tKét dátum között a teljes munkanapok számát adja meg.\r\nNOW\t\t\t= MOST\t\t\t\t##\tA napi dátum dátumértékét és a pontos idő időértékét adja eredményül.\r\nSECOND\t\t\t= MPERC\t\t\t\t##\tIdőértéket másodpercekké alakít át.\r\nTIME\t\t\t= IDŐ\t\t\t\t##\tAdott időpont időértékét adja meg.\r\nTIMEVALUE\t\t= IDŐÉRTÉK\t\t\t##\tSzövegként megadott időpontot időértékké alakít át.\r\nTODAY\t\t\t= MA\t\t\t\t##\tA napi dátum dátumértékét adja eredményül.\r\nWEEKDAY\t\t\t= HÉT.NAPJA\t\t\t##\tDátumértéket a hét napjává alakítja át.\r\nWEEKNUM\t\t\t= WEEKNUM\t\t\t##\tVisszatérési értéke egy szám, amely azt mutatja meg, hogy a megadott dátum az év hányadik hetére esik.\r\nWORKDAY\t\t\t= WORKDAY\t\t\t##\tAdott dátumnál adott munkanappal korábbi vagy későbbi dátum dátumértékét adja eredményül.\r\nYEAR\t\t\t= ÉV\t\t\t\t##\tSorszámot évvé alakít át.\r\nYEARFRAC\t\t= YEARFRAC\t\t\t##\tAz adott dátumok közötti teljes napok számát törtévként adja meg.\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\tMérnöki függvények\r\n##\r\nBESSELI\t\t\t= BESSELI\t\t\t##\tAz In(x) módosított Bessel-függvény értékét adja eredményül.\r\nBESSELJ\t\t\t= BESSELJ\t\t\t##\tA Jn(x) Bessel-függvény értékét adja eredményül.\r\nBESSELK\t\t\t= BESSELK\t\t\t##\tA Kn(x) módosított Bessel-függvény értékét adja eredményül.\r\nBESSELY\t\t\t= BESSELY\t\t\t##\tAz Yn(x) módosított Bessel-függvény értékét adja eredményül.\r\nBIN2DEC\t\t\t= BIN2DEC\t\t\t##\tBináris számot decimálissá alakít át.\r\nBIN2HEX\t\t\t= BIN2HEX\t\t\t##\tBináris számot hexadecimálissá alakít át.\r\nBIN2OCT\t\t\t= BIN2OCT\t\t\t##\tBináris számot oktálissá alakít át.\r\nCOMPLEX\t\t\t= COMPLEX\t\t\t##\tValós és képzetes részből komplex számot képez.\r\nCONVERT\t\t\t= CONVERT\t\t\t##\tMértékegységeket vált át.\r\nDEC2BIN\t\t\t= DEC2BIN\t\t\t##\tDecimális számot binárissá alakít át.\r\nDEC2HEX\t\t\t= DEC2HEX\t\t\t##\tDecimális számot hexadecimálissá alakít át.\r\nDEC2OCT\t\t\t= DEC2OCT\t\t\t##\tDecimális számot oktálissá alakít át.\r\nDELTA\t\t\t= DELTA\t\t\t\t##\tAzt vizsgálja, hogy két érték egyenlő-e.\r\nERF\t\t\t= ERF\t\t\t\t##\tA hibafüggvény értékét adja eredményül.\r\nERFC\t\t\t= ERFC\t\t\t\t##\tA kiegészített hibafüggvény értékét adja eredményül.\r\nGESTEP\t\t\t= GESTEP\t\t\t##\tAzt vizsgálja, hogy egy szám nagyobb-e adott küszöbértéknél.\r\nHEX2BIN\t\t\t= HEX2BIN\t\t\t##\tHexadecimális számot binárissá alakít át.\r\nHEX2DEC\t\t\t= HEX2DEC\t\t\t##\tHexadecimális számot decimálissá alakít át.\r\nHEX2OCT\t\t\t= HEX2OCT\t\t\t##\tHexadecimális számot oktálissá alakít át.\r\nIMABS\t\t\t= IMABS\t\t\t\t##\tKomplex szám abszolút értékét (modulusát) adja eredményül.\r\nIMAGINARY\t\t= IMAGINARY\t\t\t##\tKomplex szám képzetes részét adja eredményül.\r\nIMARGUMENT\t\t= IMARGUMENT\t\t\t##\tA komplex szám radiánban kifejezett théta argumentumát adja eredményül.\r\nIMCONJUGATE\t\t= IMCONJUGATE\t\t\t##\tKomplex szám komplex konjugáltját adja eredményül.\r\nIMCOS\t\t\t= IMCOS\t\t\t\t##\tKomplex szám koszinuszát adja eredményül.\r\nIMDIV\t\t\t= IMDIV\t\t\t\t##\tKét komplex szám hányadosát adja eredményül.\r\nIMEXP\t\t\t= IMEXP\t\t\t\t##\tAz e szám komplex kitevőjű hatványát adja eredményül.\r\nIMLN\t\t\t= IMLN\t\t\t\t##\tKomplex szám természetes logaritmusát adja eredményül.\r\nIMLOG10\t\t\t= IMLOG10\t\t\t##\tKomplex szám tízes alapú logaritmusát adja eredményül.\r\nIMLOG2\t\t\t= IMLOG2\t\t\t##\tKomplex szám kettes alapú logaritmusát adja eredményül.\r\nIMPOWER\t\t\t= IMPOWER\t\t\t##\tKomplex szám hatványát adja eredményül.\r\nIMPRODUCT\t\t= IMPRODUCT\t\t\t##\tKomplex számok szorzatát adja eredményül.\r\nIMREAL\t\t\t= IMREAL\t\t\t##\tKomplex szám valós részét adja eredményül.\r\nIMSIN\t\t\t= IMSIN\t\t\t\t##\tKomplex szám szinuszát adja eredményül.\r\nIMSQRT\t\t\t= IMSQRT\t\t\t##\tKomplex szám négyzetgyökét adja eredményül.\r\nIMSUB\t\t\t= IMSUB\t\t\t\t##\tKét komplex szám különbségét adja eredményül.\r\nIMSUM\t\t\t= IMSUM\t\t\t\t##\tKomplex számok összegét adja eredményül.\r\nOCT2BIN\t\t\t= OCT2BIN\t\t\t##\tOktális számot binárissá alakít át.\r\nOCT2DEC\t\t\t= OCT2DEC\t\t\t##\tOktális számot decimálissá alakít át.\r\nOCT2HEX\t\t\t= OCT2HEX\t\t\t##\tOktális számot hexadecimálissá alakít át.\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\tPénzügyi függvények\r\n##\r\nACCRINT\t\t\t= ACCRINT\t\t\t##\tPeriodikusan kamatozó értékpapír felszaporodott kamatát adja eredményül.\r\nACCRINTM\t\t= ACCRINTM\t\t\t##\tLejáratkor kamatozó értékpapír felszaporodott kamatát adja eredményül.\r\nAMORDEGRC\t\t= AMORDEGRC\t\t\t##\tÁllóeszköz lineáris értékcsökkenését adja meg az egyes könyvelési időszakokra vonatkozóan.\r\nAMORLINC\t\t= AMORLINC\t\t\t##\tAz egyes könyvelési időszakokban az értékcsökkenést adja meg.\r\nCOUPDAYBS\t\t= COUPDAYBS\t\t\t##\tA szelvényidőszak kezdetétől a kifizetés időpontjáig eltelt napokat adja vissza.\r\nCOUPDAYS\t\t= COUPDAYS\t\t\t##\tA kifizetés időpontját magában foglaló szelvényperiódus hosszát adja meg napokban.\r\nCOUPDAYSNC\t\t= COUPDAYSNC\t\t\t##\tA kifizetés időpontja és a legközelebbi szelvénydátum közötti napok számát adja meg.\r\nCOUPNCD\t\t\t= COUPNCD\t\t\t##\tA kifizetést követő legelső szelvénydátumot adja eredményül.\r\nCOUPNUM\t\t\t= COUPNUM\t\t\t##\tA kifizetés és a lejárat időpontja között kifizetendő szelvények számát adja eredményül.\r\nCOUPPCD\t\t\t= COUPPCD\t\t\t##\tA kifizetés előtti utolsó szelvénydátumot adja eredményül.\r\nCUMIPMT\t\t\t= CUMIPMT\t\t\t##\tKét fizetési időszak között kifizetett kamat halmozott értékét adja eredményül.\r\nCUMPRINC\t\t= CUMPRINC\t\t\t##\tKét fizetési időszak között kifizetett részletek halmozott (kamatot nem tartalmazó) értékét adja eredményül.\r\nDB\t\t\t= KCS2\t\t\t\t##\tEszköz adott időszak alatti értékcsökkenését számítja ki a lineáris leírási modell alkalmazásával.\r\nDDB\t\t\t= KCSA\t\t\t\t##\tEszköz értékcsökkenését számítja ki adott időszakra vonatkozóan a progresszív vagy egyéb megadott leírási modell alkalmazásával.\r\nDISC\t\t\t= DISC\t\t\t\t##\tÉrtékpapír leszámítolási kamatlábát adja eredményül.\r\nDOLLARDE\t\t= DOLLARDE\t\t\t##\tEgy közönséges törtként megadott számot tizedes törtté alakít át.\r\nDOLLARFR\t\t= DOLLARFR\t\t\t##\tTizedes törtként megadott számot közönséges törtté alakít át.\r\nDURATION\t\t= DURATION\t\t\t##\tPeriodikus kamatfizetésű értékpapír éves kamatérzékenységét adja eredményül.\r\nEFFECT\t\t\t= EFFECT\t\t\t##\tAz éves tényleges kamatláb értékét adja eredményül.\r\nFV\t\t\t= JBÉ\t\t\t\t##\tBefektetés jövőbeli értékét számítja ki.\r\nFVSCHEDULE\t\t= FVSCHEDULE\t\t\t##\tA kezdőtőke adott kamatlábak szerint megnövelt jövőbeli értékét adja eredményül.\r\nINTRATE\t\t\t= INTRATE\t\t\t##\tA lejáratig teljesen lekötött értékpapír kamatrátáját adja eredményül.\r\nIPMT\t\t\t= RRÉSZLET\t\t\t##\tHiteltörlesztésen belül a tőketörlesztés nagyságát számítja ki adott időszakra.\r\nIRR\t\t\t= BMR\t\t\t\t##\tA befektetés belső megtérülési rátáját számítja ki pénzáramláshoz.\r\nISPMT\t\t\t= LRÉSZLETKAMAT\t\t\t##\tA befektetés adott időszakára fizetett kamatot számítja ki.\r\nMDURATION\t\t= MDURATION\t\t\t##\tEgy 100 Ft névértékű értékpapír Macauley-féle módosított kamatérzékenységét adja eredményül.\r\nMIRR\t\t\t= MEGTÉRÜLÉS\t\t\t##\tA befektetés belső megtérülési rátáját számítja ki a költségek és a bevételek különböző kamatlába mellett.\r\nNOMINAL\t\t\t= NOMINAL\t\t\t##\tAz éves névleges kamatláb értékét adja eredményül.\r\nNPER\t\t\t= PER.SZÁM\t\t\t##\tA törlesztési időszakok számát adja meg.\r\nNPV\t\t\t= NMÉ\t\t\t\t##\tBefektetéshez kapcsolódó pénzáramlás nettó jelenértékét számítja ki ismert pénzáramlás és kamatláb mellett.\r\nODDFPRICE\t\t= ODDFPRICE\t\t\t##\tEgy 100 Ft névértékű, a futamidő elején töredék-időszakos értékpapír árát adja eredményül.\r\nODDFYIELD\t\t= ODDFYIELD\t\t\t##\tA futamidő elején töredék-időszakos értékpapír hozamát adja eredményül.\r\nODDLPRICE\t\t= ODDLPRICE\t\t\t##\tEgy 100 Ft névértékű, a futamidő végén töredék-időszakos értékpapír árát adja eredményül.\r\nODDLYIELD\t\t= ODDLYIELD\t\t\t##\tA futamidő végén töredék-időszakos értékpapír hozamát adja eredményül.\r\nPMT\t\t\t= RÉSZLET\t\t\t##\tA törlesztési időszakra vonatkozó törlesztési összeget számítja ki.\r\nPPMT\t\t\t= PRÉSZLET\t\t\t##\tHiteltörlesztésen belül a tőketörlesztés nagyságát számítja ki adott időszakra.\r\nPRICE\t\t\t= PRICE\t\t\t\t##\tEgy 100 Ft névértékű, periodikusan kamatozó értékpapír árát adja eredményül.\r\nPRICEDISC\t\t= PRICEDISC\t\t\t##\tEgy 100 Ft névértékű leszámítolt értékpapír árát adja eredményül.\r\nPRICEMAT\t\t= PRICEMAT\t\t\t##\tEgy 100 Ft névértékű, a lejáratkor kamatozó értékpapír árát adja eredményül.\r\nPV\t\t\t= MÉ\t\t\t\t##\tBefektetés jelenlegi értékét számítja ki.\r\nRATE\t\t\t= RÁTA\t\t\t\t##\tEgy törlesztési időszakban az egy időszakra eső kamatláb nagyságát számítja ki.\r\nRECEIVED\t\t= RECEIVED\t\t\t##\tA lejáratig teljesen lekötött értékpapír lejáratakor kapott összegét adja eredményül.\r\nSLN\t\t\t= LCSA\t\t\t\t##\tTárgyi eszköz egy időszakra eső amortizációját adja meg bruttó érték szerinti lineáris leírási kulcsot alkalmazva.\r\nSYD\t\t\t= SYD\t\t\t\t##\tTárgyi eszköz értékcsökkenését számítja ki adott időszakra az évek számjegyösszegével dolgozó módszer alapján.\r\nTBILLEQ\t\t\t= TBILLEQ\t\t\t##\tKincstárjegy kötvény-egyenértékű hozamát adja eredményül.\r\nTBILLPRICE\t\t= TBILLPRICE\t\t\t##\tEgy 100 Ft névértékű kincstárjegy árát adja eredményül.\r\nTBILLYIELD\t\t= TBILLYIELD\t\t\t##\tKincstárjegy hozamát adja eredményül.\r\nVDB\t\t\t= ÉCSRI\t\t\t\t##\tTárgyi eszköz amortizációját számítja ki megadott vagy részidőszakra a csökkenő egyenleg módszerének alkalmazásával.\r\nXIRR\t\t\t= XIRR\t\t\t\t##\tÜtemezett készpénzforgalom (cash flow) belső megtérülési kamatrátáját adja eredményül.\r\nXNPV\t\t\t= XNPV\t\t\t\t##\tÜtemezett készpénzforgalom (cash flow) nettó jelenlegi értékét adja eredményül.\r\nYIELD\t\t\t= YIELD\t\t\t\t##\tPeriodikusan kamatozó értékpapír hozamát adja eredményül.\r\nYIELDDISC\t\t= YIELDDISC\t\t\t##\tLeszámítolt értékpapír (például kincstárjegy) éves hozamát adja eredményül.\r\nYIELDMAT\t\t= YIELDMAT\t\t\t##\tLejáratkor kamatozó értékpapír éves hozamát adja eredményül.\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\tInformációs függvények\r\n##\r\nCELL\t\t\t= CELLA\t\t\t\t##\tEgy cella formátumára, elhelyezkedésére vagy tartalmára vonatkozó adatokat ad eredményül.\r\nERROR.TYPE\t\t= HIBA.TÍPUS\t\t\t##\tEgy hibatípushoz tartozó számot ad eredményül.\r\nINFO\t\t\t= INFÓ\t\t\t\t##\tA rendszer- és munkakörnyezet pillanatnyi állapotáról ad felvilágosítást.\r\nISBLANK\t\t\t= ÜRES\t\t\t\t##\tEredménye IGAZ, ha az érték üres.\r\nISERR\t\t\t= HIBA\t\t\t\t##\tEredménye IGAZ, ha az érték valamelyik hibaérték a #HIÁNYZIK kivételével.\r\nISERROR\t\t\t= HIBÁS\t\t\t\t##\tEredménye IGAZ, ha az érték valamelyik hibaérték.\r\nISEVEN\t\t\t= ISEVEN\t\t\t##\tEredménye IGAZ, ha argumentuma páros szám.\r\nISLOGICAL\t\t= LOGIKAI\t\t\t##\tEredménye IGAZ, ha az érték logikai érték.\r\nISNA\t\t\t= NINCS\t\t\t\t##\tEredménye IGAZ, ha az érték a #HIÁNYZIK hibaérték.\r\nISNONTEXT\t\t= NEM.SZÖVEG\t\t\t##\tEredménye IGAZ, ha az érték nem szöveg.\r\nISNUMBER\t\t= SZÁM\t\t\t\t##\tEredménye IGAZ, ha az érték szám.\r\nISODD\t\t\t= ISODD\t\t\t\t##\tEredménye IGAZ, ha argumentuma páratlan szám.\r\nISREF\t\t\t= HIVATKOZÁS\t\t\t##\tEredménye IGAZ, ha az érték hivatkozás.\r\nISTEXT\t\t\t= SZÖVEG.E\t\t\t##\tEredménye IGAZ, ha az érték szöveg.\r\nN\t\t\t= N\t\t\t\t##\tArgumentumának értékét számmá alakítja.\r\nNA\t\t\t= HIÁNYZIK\t\t\t##\tEredménye a #HIÁNYZIK hibaérték.\r\nTYPE\t\t\t= TÍPUS\t\t\t\t##\tÉrték adattípusának azonosítószámát adja eredményül.\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\tLogikai függvények\r\n##\r\nAND\t\t\t= ÉS\t\t\t\t##\tEredménye IGAZ, ha minden argumentuma IGAZ.\r\nFALSE\t\t\t= HAMIS\t\t\t\t##\tA HAMIS logikai értéket adja eredményül.\r\nIF\t\t\t= HA\t\t\t\t##\tLogikai vizsgálatot hajt végre.\r\nIFERROR\t\t\t= HAHIBA\t\t\t##\tA megadott értéket adja vissza, ha egy képlet hibához vezet; más esetben a képlet értékét adja eredményül.\r\nNOT\t\t\t= NEM\t\t\t\t##\tArgumentuma értékének ellentettjét adja eredményül.\r\nOR\t\t\t= VAGY\t\t\t\t##\tEredménye IGAZ, ha bármely argumentuma IGAZ.\r\nTRUE\t\t\t= IGAZ\t\t\t\t##\tAz IGAZ logikai értéket adja eredményül.\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\tKeresési és hivatkozási függvények\r\n##\r\nADDRESS\t\t\t= CÍM\t\t\t\t##\tA munkalap egy cellájára való hivatkozást adja szövegként eredményül.\r\nAREAS\t\t\t= TERÜLET\t\t\t##\tHivatkozásban a területek számát adja eredményül.\r\nCHOOSE\t\t\t= VÁLASZT\t\t\t##\tÉrtékek listájából választ ki egy elemet.\r\nCOLUMN\t\t\t= OSZLOP\t\t\t##\tEgy hivatkozás oszlopszámát adja eredményül.\r\nCOLUMNS\t\t\t= OSZLOPOK\t\t\t##\tA hivatkozásban található oszlopok számát adja eredményül.\r\nHLOOKUP\t\t\t= VKERES\t\t\t##\tA megadott tömb felső sorában adott értékű elemet keres, és a megtalált elem oszlopából adott sorban elhelyezkedő értékkel tér vissza.\r\nHYPERLINK\t\t= HIPERHIVATKOZÁS\t\t##\tHálózati kiszolgálón, intraneten vagy az interneten tárolt dokumentumot megnyitó parancsikont vagy hivatkozást hoz létre.\r\nINDEX\t\t\t= INDEX\t\t\t\t##\tTömb- vagy hivatkozás indexszel megadott értékét adja vissza.\r\nINDIRECT\t\t= INDIREKT\t\t\t##\tSzöveg megadott hivatkozást ad eredményül.\r\nLOOKUP\t\t\t= KERES\t\t\t\t##\tVektorban vagy tömbben keres meg értékeket.\r\nMATCH\t\t\t= HOL.VAN\t\t\t##\tHivatkozásban vagy tömbben értékeket keres.\r\nOFFSET\t\t\t= OFSZET\t\t\t##\tHivatkozás egy másik hivatkozástól számított távolságát adja meg.\r\nROW\t\t\t= SOR\t\t\t\t##\tEgy hivatkozás sorának számát adja meg.\r\nROWS\t\t\t= SOROK\t\t\t\t##\tEgy hivatkozás sorainak számát adja meg.\r\nRTD\t\t\t= RTD\t\t\t\t##\tValós idejű adatokat keres vissza a COM automatizmust (automatizálás: Egy alkalmazás objektumaival való munka másik alkalmazásból vagy fejlesztőeszközből. A korábban OLE automatizmusnak nevezett automatizálás iparági szabvány, a Component Object Model (COM) szolgáltatása.) támogató programból.\r\nTRANSPOSE\t\t= TRANSZPONÁLÁS\t\t\t##\tEgy tömb transzponáltját adja eredményül.\r\nVLOOKUP\t\t\t= FKERES\t\t\t##\tA megadott tömb bal szélső oszlopában megkeres egy értéket, majd annak sora és a megadott oszlop metszéspontjában levő értéked adja eredményül.\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\tMatematikai és trigonometrikus függvények\r\n##\r\nABS\t\t\t= ABS\t\t\t\t##\tEgy szám abszolút értékét adja eredményül.\r\nACOS\t\t\t= ARCCOS\t\t\t##\tEgy szám arkusz koszinuszát számítja ki.\r\nACOSH\t\t\t= ACOSH\t\t\t\t##\tEgy szám inverz koszinusz hiperbolikuszát számítja ki.\r\nASIN\t\t\t= ARCSIN\t\t\t##\tEgy szám arkusz szinuszát számítja ki.\r\nASINH\t\t\t= ASINH\t\t\t\t##\tEgy szám inverz szinusz hiperbolikuszát számítja ki.\r\nATAN\t\t\t= ARCTAN\t\t\t##\tEgy szám arkusz tangensét számítja ki.\r\nATAN2\t\t\t= ARCTAN2\t\t\t##\tX és y koordináták alapján számítja ki az arkusz tangens értéket.\r\nATANH\t\t\t= ATANH\t\t\t\t##\tA szám inverz tangens hiperbolikuszát számítja ki.\r\nCEILING\t\t\t= PLAFON\t\t\t##\tEgy számot a legközelebbi egészre vagy a pontosságként megadott érték legközelebb eső többszörösére kerekít.\r\nCOMBIN\t\t\t= KOMBINÁCIÓK\t\t\t##\tAdott számú objektum összes lehetséges kombinációinak számát számítja ki.\r\nCOS\t\t\t= COS\t\t\t\t##\tEgy szám koszinuszát számítja ki.\r\nCOSH\t\t\t= COSH\t\t\t\t##\tEgy szám koszinusz hiperbolikuszát számítja ki.\r\nDEGREES\t\t\t= FOK\t\t\t\t##\tRadiánt fokká alakít át.\r\nEVEN\t\t\t= PÁROS\t\t\t\t##\tEgy számot a legközelebbi páros egész számra kerekít.\r\nEXP\t\t\t= KITEVŐ\t\t\t##\tAz e adott kitevőjű hatványát adja eredményül.\r\nFACT\t\t\t= FAKT\t\t\t\t##\tEgy szám faktoriálisát számítja ki.\r\nFACTDOUBLE\t\t= FACTDOUBLE\t\t\t##\tEgy szám dupla faktoriálisát adja eredményül.\r\nFLOOR\t\t\t= PADLÓ\t\t\t\t##\tEgy számot lefelé, a nulla felé kerekít.\r\nGCD\t\t\t= GCD\t\t\t\t##\tA legnagyobb közös osztót adja eredményül.\r\nINT\t\t\t= INT\t\t\t\t##\tEgy számot lefelé kerekít a legközelebbi egészre.\r\nLCM\t\t\t= LCM\t\t\t\t##\tA legkisebb közös többszöröst adja eredményül.\r\nLN\t\t\t= LN\t\t\t\t##\tEgy szám természetes logaritmusát számítja ki.\r\nLOG\t\t\t= LOG\t\t\t\t##\tEgy szám adott alapú logaritmusát számítja ki.\r\nLOG10\t\t\t= LOG10\t\t\t\t##\tEgy szám 10-es alapú logaritmusát számítja ki.\r\nMDETERM\t\t\t= MDETERM\t\t\t##\tEgy tömb mátrix-determinánsát számítja ki.\r\nMINVERSE\t\t= INVERZ.MÁTRIX\t\t\t##\tEgy tömb mátrix inverzét adja eredményül.\r\nMMULT\t\t\t= MSZORZAT\t\t\t##\tKét tömb mátrix-szorzatát adja meg.\r\nMOD\t\t\t= MARADÉK\t\t\t##\tEgy szám osztási maradékát adja eredményül.\r\nMROUND\t\t\t= MROUND\t\t\t##\tA kívánt többszörösére kerekített értéket ad eredményül.\r\nMULTINOMIAL\t\t= MULTINOMIAL\t\t\t##\tSzámhalmaz multinomiálisát adja eredményül.\r\nODD\t\t\t= PÁRATLAN\t\t\t##\tEgy számot a legközelebbi páratlan számra kerekít.\r\nPI\t\t\t= PI\t\t\t\t##\tA pi matematikai állandót adja vissza.\r\nPOWER\t\t\t= HATVÁNY\t\t\t##\tEgy szám adott kitevőjű hatványát számítja ki.\r\nPRODUCT\t\t\t= SZORZAT\t\t\t##\tArgumentumai szorzatát számítja ki.\r\nQUOTIENT\t\t= QUOTIENT\t\t\t##\tEgy hányados egész részét adja eredményül.\r\nRADIANS\t\t\t= RADIÁN\t\t\t##\tFokot radiánná alakít át.\r\nRAND\t\t\t= VÉL\t\t\t\t##\tEgy 0 és 1 közötti véletlen számot ad eredményül.\r\nRANDBETWEEN\t\t= RANDBETWEEN\t\t\t##\tMegadott számok közé eső véletlen számot állít elő.\r\nROMAN\t\t\t= RÓMAI\t\t\t\t##\tEgy számot római számokkal kifejezve szövegként ad eredményül.\r\nROUND\t\t\t= KEREKÍTÉS\t\t\t##\tEgy számot adott számú számjegyre kerekít.\r\nROUNDDOWN\t\t= KEREKÍTÉS.LE\t\t\t##\tEgy számot lefelé, a nulla felé kerekít.\r\nROUNDUP\t\t\t= KEREKÍTÉS.FEL\t\t\t##\tEgy számot felfelé, a nullától távolabbra kerekít.\r\nSERIESSUM\t\t= SERIESSUM\t\t\t##\tHatványsor összegét adja eredményül.\r\nSIGN\t\t\t= ELŐJEL\t\t\t##\tEgy szám előjelét adja meg.\r\nSIN\t\t\t= SIN\t\t\t\t##\tEgy szög szinuszát számítja ki.\r\nSINH\t\t\t= SINH\t\t\t\t##\tEgy szám szinusz hiperbolikuszát számítja ki.\r\nSQRT\t\t\t= GYÖK\t\t\t\t##\tEgy szám pozitív négyzetgyökét számítja ki.\r\nSQRTPI\t\t\t= SQRTPI\t\t\t##\tA (szám*pi) négyzetgyökét adja eredményül.\r\nSUBTOTAL\t\t= RÉSZÖSSZEG\t\t\t##\tLista vagy adatbázis részösszegét adja eredményül.\r\nSUM\t\t\t= SZUM\t\t\t\t##\tÖsszeadja az argumentumlistájában lévő számokat.\r\nSUMIF\t\t\t= SZUMHA\t\t\t##\tA megadott feltételeknek eleget tevő cellákban található értékeket adja össze.\r\nSUMIFS\t\t\t= SZUMHATÖBB\t\t\t##\tTöbb megadott feltételnek eleget tévő tartománycellák összegét adja eredményül.\r\nSUMPRODUCT\t\t= SZORZATÖSSZEG\t\t\t##\tA megfelelő tömbelemek szorzatának összegét számítja ki.\r\nSUMSQ\t\t\t= NÉGYZETÖSSZEG\t\t\t##\tArgumentumai négyzetének összegét számítja ki.\r\nSUMX2MY2\t\t= SZUMX2BŐLY2\t\t\t##\tKét tömb megfelelő elemei négyzetének különbségét összegzi.\r\nSUMX2PY2\t\t= SZUMX2MEGY2\t\t\t##\tKét tömb megfelelő elemei négyzetének összegét összegzi.\r\nSUMXMY2\t\t\t= SZUMXBŐLY2\t\t\t##\tKét tömb megfelelő elemei különbségének négyzetösszegét számítja ki.\r\nTAN\t\t\t= TAN\t\t\t\t##\tEgy szám tangensét számítja ki.\r\nTANH\t\t\t= TANH\t\t\t\t##\tEgy szám tangens hiperbolikuszát számítja ki.\r\nTRUNC\t\t\t= CSONK\t\t\t\t##\tEgy számot egésszé csonkít.\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\tStatisztikai függvények\r\n##\r\nAVEDEV\t\t\t= ÁTL.ELTÉRÉS\t\t\t##\tAz adatpontoknak átlaguktól való átlagos abszolút eltérését számítja ki.\r\nAVERAGE\t\t\t= ÁTLAG\t\t\t\t##\tArgumentumai átlagát számítja ki.\r\nAVERAGEA\t\t= ÁTLAGA\t\t\t##\tArgumentumai átlagát számítja ki (beleértve a számokat, szöveget és logikai értékeket).\r\nAVERAGEIF\t\t= ÁTLAGHA\t\t\t##\tA megadott feltételnek eleget tévő tartomány celláinak átlagát (számtani közepét) adja eredményül.\r\nAVERAGEIFS\t\t= ÁTLAGHATÖBB\t\t\t##\tA megadott feltételeknek eleget tévő cellák átlagát (számtani közepét) adja eredményül.\r\nBETADIST\t\t= BÉTA.ELOSZLÁS\t\t\t##\tA béta-eloszlás függvényt számítja ki.\r\nBETAINV\t\t\t= INVERZ.BÉTA\t\t\t##\tAdott béta-eloszláshoz kiszámítja a béta eloszlásfüggvény inverzét.\r\nBINOMDIST\t\t= BINOM.ELOSZLÁS\t\t##\tA diszkrét binomiális eloszlás valószínűségértékét számítja ki.\r\nCHIDIST\t\t\t= KHI.ELOSZLÁS\t\t\t##\tA khi-négyzet-eloszlás egyszélű valószínűségértékét számítja ki.\r\nCHIINV\t\t\t= INVERZ.KHI\t\t\t##\tA khi-négyzet-eloszlás egyszélű valószínűségértékének inverzét számítja ki.\r\nCHITEST\t\t\t= KHI.PRÓBA\t\t\t##\tFüggetlenségvizsgálatot hajt végre.\r\nCONFIDENCE\t\t= MEGBÍZHATÓSÁG\t\t\t##\tEgy statisztikai sokaság várható értékének megbízhatósági intervallumát adja eredményül.\r\nCORREL\t\t\t= KORREL\t\t\t##\tKét adathalmaz korrelációs együtthatóját számítja ki.\r\nCOUNT\t\t\t= DARAB\t\t\t\t##\tMegszámolja, hogy argumentumlistájában hány szám található.\r\nCOUNTA\t\t\t= DARAB2\t\t\t##\tMegszámolja, hogy argumentumlistájában hány érték található.\r\nCOUNTBLANK\t\t= DARABÜRES\t\t\t##\tEgy tartományban összeszámolja az üres cellákat.\r\nCOUNTIF\t\t\t= DARABTELI\t\t\t##\tEgy tartományban összeszámolja azokat a cellákat, amelyek eleget tesznek a megadott feltételnek.\r\nCOUNTIFS\t\t= DARABHATÖBB\t\t\t##\tEgy tartományban összeszámolja azokat a cellákat, amelyek eleget tesznek több feltételnek.\r\nCOVAR\t\t\t= KOVAR\t\t\t\t##\tA kovarianciát, azaz a páronkénti eltérések szorzatának átlagát számítja ki.\r\nCRITBINOM\t\t= KRITBINOM\t\t\t##\tAzt a legkisebb számot adja eredményül, amelyre a binomiális eloszlásfüggvény értéke nem kisebb egy adott határértéknél.\r\nDEVSQ\t\t\t= SQ\t\t\t\t##\tAz átlagtól való eltérések négyzetének összegét számítja ki.\r\nEXPONDIST\t\t= EXP.ELOSZLÁS\t\t\t##\tAz exponenciális eloszlás értékét számítja ki.\r\nFDIST\t\t\t= F.ELOSZLÁS\t\t\t##\tAz F-eloszlás értékét számítja ki.\r\nFINV\t\t\t= INVERZ.F\t\t\t##\tAz F-eloszlás inverzének értékét számítja ki.\r\nFISHER\t\t\t= FISHER\t\t\t##\tFisher-transzformációt hajt végre.\r\nFISHERINV\t\t= INVERZ.FISHER\t\t\t##\tA Fisher-transzformáció inverzét hajtja végre.\r\nFORECAST\t\t= ELŐREJELZÉS\t\t\t##\tAz ismert értékek alapján lineáris regresszióval becsült értéket ad eredményül.\r\nFREQUENCY\t\t= GYAKORISÁG\t\t\t##\tA gyakorisági vagy empirikus eloszlás értékét függőleges tömbként adja eredményül.\r\nFTEST\t\t\t= F.PRÓBA\t\t\t##\tAz F-próba értékét adja eredményül.\r\nGAMMADIST\t\t= GAMMA.ELOSZLÁS\t\t##\tA gamma-eloszlás értékét számítja ki.\r\nGAMMAINV\t\t= INVERZ.GAMMA\t\t\t##\tA gamma-eloszlás eloszlásfüggvénye inverzének értékét számítja ki.\r\nGAMMALN\t\t\t= GAMMALN\t\t\t##\tA gamma-függvény természetes logaritmusát számítja ki.\r\nGEOMEAN\t\t\t= MÉRTANI.KÖZÉP\t\t\t##\tArgumentumai mértani középértékét számítja ki.\r\nGROWTH\t\t\t= NÖV\t\t\t\t##\tExponenciális regresszió alapján ad becslést.\r\nHARMEAN\t\t\t= HARM.KÖZÉP\t\t\t##\tArgumentumai harmonikus átlagát számítja ki.\r\nHYPGEOMDIST\t\t= HIPERGEOM.ELOSZLÁS\t\t##\tA hipergeometriai eloszlás értékét számítja ki.\r\nINTERCEPT\t\t= METSZ\t\t\t\t##\tA regressziós egyenes y tengellyel való metszéspontját határozza meg.\r\nKURT\t\t\t= CSÚCSOSSÁG\t\t\t##\tEgy adathalmaz csúcsosságát számítja ki.\r\nLARGE\t\t\t= NAGY\t\t\t\t##\tEgy adathalmaz k-adik legnagyobb elemét adja eredményül.\r\nLINEST\t\t\t= LIN.ILL\t\t\t##\tA legkisebb négyzetek módszerével az adatokra illesztett egyenes paramétereit határozza meg.\r\nLOGEST\t\t\t= LOG.ILL\t\t\t##\tAz adatokra illesztett exponenciális görbe paramétereit határozza meg.\r\nLOGINV\t\t\t= INVERZ.LOG.ELOSZLÁS\t\t##\tA lognormális eloszlás inverzét számítja ki.\r\nLOGNORMDIST\t\t= LOG.ELOSZLÁS\t\t\t##\tA lognormális eloszlásfüggvény értékét számítja ki.\r\nMAX\t\t\t= MAX\t\t\t\t##\tAz argumentumai között szereplő legnagyobb számot adja meg.\r\nMAXA\t\t\t= MAX2\t\t\t\t##\tAz argumentumai között szereplő legnagyobb számot adja meg (beleértve a számokat, szöveget és logikai értékeket).\r\nMEDIAN\t\t\t= MEDIÁN\t\t\t##\tAdott számhalmaz mediánját számítja ki.\r\nMIN\t\t\t= MIN\t\t\t\t##\tAz argumentumai között szereplő legkisebb számot adja meg.\r\nMINA\t\t\t= MIN2\t\t\t\t##\tAz argumentumai között szereplő legkisebb számot adja meg, beleértve a számokat, szöveget és logikai értékeket.\r\nMODE\t\t\t= MÓDUSZ\t\t\t##\tEgy adathalmazból kiválasztja a leggyakrabban előforduló számot.\r\nNEGBINOMDIST\t\t= NEGBINOM.ELOSZL\t\t##\tA negatív binomiális eloszlás értékét számítja ki.\r\nNORMDIST\t\t= NORM.ELOSZL\t\t\t##\tA normális eloszlás értékét számítja ki.\r\nNORMINV\t\t\t= INVERZ.NORM\t\t\t##\tA normális eloszlás eloszlásfüggvénye inverzének értékét számítja ki.\r\nNORMSDIST\t\t= STNORMELOSZL\t\t\t##\tA standard normális eloszlás eloszlásfüggvényének értékét számítja ki.\r\nNORMSINV\t\t= INVERZ.STNORM\t\t\t##\tA standard normális eloszlás eloszlásfüggvénye inverzének értékét számítja ki.\r\nPEARSON\t\t\t= PEARSON\t\t\t##\tA Pearson-féle korrelációs együtthatót számítja ki.\r\nPERCENTILE\t\t= PERCENTILIS\t\t\t##\tEgy tartományban található értékek k-adik percentilisét, azaz százalékosztályát adja eredményül.\r\nPERCENTRANK\t\t= SZÁZALÉKRANG\t\t\t##\tEgy értéknek egy adathalmazon belül vett százalékos rangját (elhelyezkedését) számítja ki.\r\nPERMUT\t\t\t= VARIÁCIÓK\t\t\t##\tAdott számú objektum k-ad osztályú ismétlés nélküli variációinak számát számítja ki.\r\nPOISSON\t\t\t= POISSON\t\t\t##\tA Poisson-eloszlás értékét számítja ki.\r\nPROB\t\t\t= VALÓSZÍNŰSÉG\t\t\t##\tAnnak valószínűségét számítja ki, hogy adott értékek két határérték közé esnek.\r\nQUARTILE\t\t= KVARTILIS\t\t\t##\tEgy adathalmaz kvartilisét (negyedszintjét) számítja ki.\r\nRANK\t\t\t= SORSZÁM\t\t\t##\tKiszámítja, hogy egy szám hányadik egy számsorozatban.\r\nRSQ\t\t\t= RNÉGYZET\t\t\t##\tKiszámítja a Pearson-féle szorzatmomentum korrelációs együtthatójának négyzetét.\r\nSKEW\t\t\t= FERDESÉG\t\t\t##\tEgy eloszlás ferdeségét határozza meg.\r\nSLOPE\t\t\t= MEREDEKSÉG\t\t\t##\tEgy lineáris regressziós egyenes meredekségét számítja ki.\r\nSMALL\t\t\t= KICSI\t\t\t\t##\tEgy adathalmaz k-adik legkisebb elemét adja meg.\r\nSTANDARDIZE\t\t= NORMALIZÁLÁS\t\t\t##\tNormalizált értéket ad eredményül.\r\nSTDEV\t\t\t= SZÓRÁS\t\t\t##\tEgy statisztikai sokaság mintájából kiszámítja annak szórását.\r\nSTDEVA\t\t\t= SZÓRÁSA\t\t\t##\tEgy statisztikai sokaság mintájából kiszámítja annak szórását (beleértve a számokat, szöveget és logikai értékeket).\r\nSTDEVP\t\t\t= SZÓRÁSP\t\t\t##\tEgy statisztikai sokaság egészéből kiszámítja annak szórását.\r\nSTDEVPA\t\t\t= SZÓRÁSPA\t\t\t##\tEgy statisztikai sokaság egészéből kiszámítja annak szórását (beleértve számokat, szöveget és logikai értékeket).\r\nSTEYX\t\t\t= STHIBAYX\t\t\t##\tEgy regresszió esetén az egyes x-értékek alapján meghatározott y-értékek standard hibáját számítja ki.\r\nTDIST\t\t\t= T.ELOSZLÁS\t\t\t##\tA Student-féle t-eloszlás értékét számítja ki.\r\nTINV\t\t\t= INVERZ.T\t\t\t##\tA Student-féle t-eloszlás inverzét számítja ki.\r\nTREND\t\t\t= TREND\t\t\t\t##\tLineáris trend értékeit számítja ki.\r\nTRIMMEAN\t\t= RÉSZÁTLAG\t\t\t##\tEgy adathalmaz középső részének átlagát számítja ki.\r\nTTEST\t\t\t= T.PRÓBA\t\t\t##\tA Student-féle t-próbához tartozó valószínűséget számítja ki.\r\nVAR\t\t\t= VAR\t\t\t\t##\tMinta alapján becslést ad a varianciára.\r\nVARA\t\t\t= VARA\t\t\t\t##\tMinta alapján becslést ad a varianciára (beleértve számokat, szöveget és logikai értékeket).\r\nVARP\t\t\t= VARP\t\t\t\t##\tEgy statisztikai sokaság varianciáját számítja ki.\r\nVARPA\t\t\t= VARPA\t\t\t\t##\tEgy statisztikai sokaság varianciáját számítja ki (beleértve számokat, szöveget és logikai értékeket).\r\nWEIBULL\t\t\t= WEIBULL\t\t\t##\tA Weibull-féle eloszlás értékét számítja ki.\r\nZTEST\t\t\t= Z.PRÓBA\t\t\t##\tAz egyszélű z-próbával kapott valószínűségértéket számítja ki.\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\tSzövegműveletekhez használható függvények\r\n##\r\nASC\t\t\t= ASC\t\t\t\t##\tSzöveg teljes szélességű (kétbájtos) latin és katakana karaktereit félszélességű (egybájtos) karakterekké alakítja.\r\nBAHTTEXT\t\t= BAHTSZÖVEG\t\t\t##\tSzámot szöveggé alakít a ß (baht) pénznemformátum használatával.\r\nCHAR\t\t\t= KARAKTER\t\t\t##\tA kódszámmal meghatározott karaktert adja eredményül.\r\nCLEAN\t\t\t= TISZTÍT\t\t\t##\tA szövegből eltávolítja az összes nem nyomtatható karaktert.\r\nCODE\t\t\t= KÓD\t\t\t\t##\tKaraktersorozat első karakterének numerikus kódját adja eredményül.\r\nCONCATENATE\t\t= ÖSSZEFŰZ\t\t\t##\tTöbb szövegelemet egyetlen szöveges elemmé fűz össze.\r\nDOLLAR\t\t\t= FORINT\t\t\t##\tSzámot pénznem formátumú szöveggé alakít át.\r\nEXACT\t\t\t= AZONOS\t\t\t##\tMegvizsgálja, hogy két érték azonos-e.\r\nFIND\t\t\t= SZÖVEG.TALÁL\t\t\t##\tKaraktersorozatot keres egy másikban (a kis- és nagybetűk megkülönböztetésével).\r\nFINDB\t\t\t= SZÖVEG.TALÁL2\t\t\t##\tKaraktersorozatot keres egy másikban (a kis- és nagybetűk megkülönböztetésével).\r\nFIXED\t\t\t= FIX\t\t\t\t##\tSzámot szöveges formátumúra alakít adott számú tizedesjegyre kerekítve.\r\nJIS\t\t\t= JIS\t\t\t\t##\tA félszélességű (egybájtos) latin és a katakana karaktereket teljes szélességű (kétbájtos) karakterekké alakítja.\r\nLEFT\t\t\t= BAL\t\t\t\t##\tSzöveg bal szélső karaktereit adja eredményül.\r\nLEFTB\t\t\t= BAL2\t\t\t\t##\tSzöveg bal szélső karaktereit adja eredményül.\r\nLEN\t\t\t= HOSSZ\t\t\t\t##\tSzöveg karakterekben mért hosszát adja eredményül.\r\nLENB\t\t\t= HOSSZ2\t\t\t##\tSzöveg karakterekben mért hosszát adja eredményül.\r\nLOWER\t\t\t= KISBETŰ\t\t\t##\tSzöveget kisbetűssé alakít át.\r\nMID\t\t\t= KÖZÉP\t\t\t\t##\tA szöveg adott pozíciójától kezdve megadott számú karaktert ad vissza eredményként.\r\nMIDB\t\t\t= KÖZÉP2\t\t\t##\tA szöveg adott pozíciójától kezdve megadott számú karaktert ad vissza eredményként.\r\nPHONETIC\t\t= PHONETIC\t\t\t##\tSzöveg furigana (fonetikus) karaktereit adja vissza.\r\nPROPER\t\t\t= TNÉV\t\t\t\t##\tSzöveg minden szavának kezdőbetűjét nagybetűsre cseréli.\r\nREPLACE\t\t\t= CSERE\t\t\t\t##\tA szövegen belül karaktereket cserél.\r\nREPLACEB\t\t= CSERE2\t\t\t##\tA szövegen belül karaktereket cserél.\r\nREPT\t\t\t= SOKSZOR\t\t\t##\tMegadott számú alkalommal megismétel egy szövegrészt.\r\nRIGHT\t\t\t= JOBB\t\t\t\t##\tSzövegrész jobb szélső karaktereit adja eredményül.\r\nRIGHTB\t\t\t= JOBB2\t\t\t\t##\tSzövegrész jobb szélső karaktereit adja eredményül.\r\nSEARCH\t\t\t= SZÖVEG.KERES\t\t\t##\tKaraktersorozatot keres egy másikban (a kis- és nagybetűk között nem tesz különbséget).\r\nSEARCHB\t\t\t= SZÖVEG.KERES2\t\t\t##\tKaraktersorozatot keres egy másikban (a kis- és nagybetűk között nem tesz különbséget).\r\nSUBSTITUTE\t\t= HELYETTE\t\t\t##\tSzövegben adott karaktereket másikra cserél.\r\nT\t\t\t= T\t\t\t\t##\tArgumentumát szöveggé alakítja át.\r\nTEXT\t\t\t= SZÖVEG\t\t\t##\tSzámértéket alakít át adott számformátumú szöveggé.\r\nTRIM\t\t\t= TRIM\t\t\t\t##\tA szövegből eltávolítja a szóközöket.\r\nUPPER\t\t\t= NAGYBETŰS\t\t\t##\tSzöveget nagybetűssé alakít át.\r\nVALUE\t\t\t= ÉRTÉK\t\t\t\t##\tSzöveget számmá alakít át.\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/it/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= €\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #NULLO!\r\nDIV0\t= #DIV/0!\r\nVALUE\t= #VALORE!\r\nREF\t= #RIF!\r\nNAME\t= #NOME?\r\nNUM\t= #NUM!\r\nNA\t= #N/D\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/it/functions",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Calculation\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/\r\n##\r\n##\r\n\r\n\r\n##\r\n##\tAdd-in and Automation functions\t\t\tFunzioni di automazione e dei componenti aggiuntivi\r\n##\r\nGETPIVOTDATA\t\t= INFO.DATI.TAB.PIVOT\t\t##\tRestituisce i dati memorizzati in un rapporto di tabella pivot\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\tFunzioni cubo\r\n##\r\nCUBEKPIMEMBER\t\t= MEMBRO.KPI.CUBO\t\t##\tRestituisce il nome, la proprietà e la misura di un indicatore di prestazioni chiave (KPI) e visualizza il nome e la proprietà nella cella. Un KPI è una misura quantificabile, ad esempio l'utile lordo mensile o il fatturato trimestrale dei dipendenti, utilizzata per il monitoraggio delle prestazioni di un'organizzazione.\r\nCUBEMEMBER\t\t= MEMBRO.CUBO\t\t\t##\tRestituisce un membro o una tupla in una gerarchia di cubi. Consente di verificare l'esistenza del membro o della tupla nel cubo.\r\nCUBEMEMBERPROPERTY\t= PROPRIETÀ.MEMBRO.CUBO\t\t##\tRestituisce il valore di una proprietà di un membro del cubo. Consente di verificare l'esistenza di un nome di membro all'interno del cubo e di restituire la proprietà specificata per tale membro.\r\nCUBERANKEDMEMBER\t= MEMBRO.CUBO.CON.RANGO\t\t##\tRestituisce l'n-esimo membro o il membro ordinato di un insieme. Consente di restituire uno o più elementi in un insieme, ad esempio l'agente di vendita migliore o i primi 10 studenti.\r\nCUBESET\t\t\t= SET.CUBO\t\t\t##\tDefinisce un insieme di tuple o membri calcolati mediante l'invio di un'espressione di insieme al cubo sul server. In questo modo l'insieme viene creato e restituito a Microsoft Office Excel.\r\nCUBESETCOUNT\t\t= CONTA.SET.CUBO\t\t##\tRestituisce il numero di elementi di un insieme.\r\nCUBEVALUE\t\t= VALORE.CUBO\t\t\t##\tRestituisce un valore aggregato da un cubo.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\tFunzioni di database\r\n##\r\nDAVERAGE\t\t= DB.MEDIA\t\t\t##\tRestituisce la media di voci del database selezionate\r\nDCOUNT\t\t\t= DB.CONTA.NUMERI\t\t##\tConta le celle di un database contenenti numeri\r\nDCOUNTA\t\t\t= DB.CONTA.VALORI\t\t##\tConta le celle non vuote in un database\r\nDGET\t\t\t= DB.VALORI\t\t\t##\tEstrae da un database un singolo record che soddisfa i criteri specificati\r\nDMAX\t\t\t= DB.MAX\t\t\t##\tRestituisce il valore massimo dalle voci selezionate in un database\r\nDMIN\t\t\t= DB.MIN\t\t\t##\tRestituisce il valore minimo dalle voci di un database selezionate\r\nDPRODUCT\t\t= DB.PRODOTTO\t\t\t##\tMoltiplica i valori in un determinato campo di record che soddisfano i criteri del database\r\nDSTDEV\t\t\t= DB.DEV.ST\t\t\t##\tRestituisce una stima della deviazione standard sulla base di un campione di voci di un database selezionate\r\nDSTDEVP\t\t\t= DB.DEV.ST.POP\t\t\t##\tCalcola la deviazione standard sulla base di tutte le voci di un database selezionate\r\nDSUM\t\t\t= DB.SOMMA\t\t\t##\tAggiunge i numeri nel campo colonna di record del database che soddisfa determinati criteri\r\nDVAR\t\t\t= DB.VAR\t\t\t##\tRestituisce una stima della varianza sulla base di un campione da voci di un database selezionate\r\nDVARP\t\t\t= DB.VAR.POP\t\t\t##\tCalcola la varianza sulla base di tutte le voci di un database selezionate\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\tFunzioni data e ora\r\n##\r\nDATE\t\t\t= DATA\t\t\t\t##\tRestituisce il numero seriale di una determinata data\r\nDATEVALUE\t\t= DATA.VALORE\t\t\t##\tConverte una data sotto forma di testo in un numero seriale\r\nDAY\t\t\t= GIORNO\t\t\t##\tConverte un numero seriale in un giorno del mese\r\nDAYS360\t\t\t= GIORNO360\t\t\t##\tCalcola il numero di giorni compreso tra due date basandosi su un anno di 360 giorni\r\nEDATE\t\t\t= DATA.MESE\t\t\t##\tRestituisce il numero seriale della data che rappresenta il numero di mesi prima o dopo la data di inizio\r\nEOMONTH\t\t\t= FINE.MESE\t\t\t##\tRestituisce il numero seriale dell'ultimo giorno del mese, prima o dopo un determinato numero di mesi\r\nHOUR\t\t\t= ORA\t\t\t\t##\tConverte un numero seriale in un'ora\r\nMINUTE\t\t\t= MINUTO\t\t\t##\tConverte un numero seriale in un minuto\r\nMONTH\t\t\t= MESE\t\t\t\t##\tConverte un numero seriale in un mese\r\nNETWORKDAYS\t\t= GIORNI.LAVORATIVI.TOT\t\t##\tRestituisce il numero di tutti i giorni lavorativi compresi fra due date\r\nNOW\t\t\t= ADESSO\t\t\t##\tRestituisce il numero seriale della data e dell'ora corrente\r\nSECOND\t\t\t= SECONDO\t\t\t##\tConverte un numero seriale in un secondo\r\nTIME\t\t\t= ORARIO\t\t\t##\tRestituisce il numero seriale di una determinata ora\r\nTIMEVALUE\t\t= ORARIO.VALORE\t\t\t##\tConverte un orario in forma di testo in un numero seriale\r\nTODAY\t\t\t= OGGI\t\t\t\t##\tRestituisce il numero seriale relativo alla data odierna\r\nWEEKDAY\t\t\t= GIORNO.SETTIMANA\t\t##\tConverte un numero seriale in un giorno della settimana\r\nWEEKNUM\t\t\t= NUM.SETTIMANA\t\t\t##\tConverte un numero seriale in un numero che rappresenta la posizione numerica di una settimana nell'anno\r\nWORKDAY\t\t\t= GIORNO.LAVORATIVO\t\t##\tRestituisce il numero della data prima o dopo un determinato numero di giorni lavorativi\r\nYEAR\t\t\t= ANNO\t\t\t\t##\tConverte un numero seriale in un anno\r\nYEARFRAC\t\t= FRAZIONE.ANNO\t\t\t##\tRestituisce la frazione dell'anno che rappresenta il numero dei giorni compresi tra una data_ iniziale e una data_finale\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\tFunzioni ingegneristiche\r\n##\r\nBESSELI\t\t\t= BESSEL.I\t\t\t##\tRestituisce la funzione di Bessel modificata In(x)\r\nBESSELJ\t\t\t= BESSEL.J\t\t\t##\tRestituisce la funzione di Bessel Jn(x)\r\nBESSELK\t\t\t= BESSEL.K\t\t\t##\tRestituisce la funzione di Bessel modificata Kn(x)\r\nBESSELY\t\t\t= BESSEL.Y\t\t\t##\tRestituisce la funzione di Bessel Yn(x)\r\nBIN2DEC\t\t\t= BINARIO.DECIMALE\t\t##\tConverte un numero binario in decimale\r\nBIN2HEX\t\t\t= BINARIO.HEX\t\t\t##\tConverte un numero binario in esadecimale\r\nBIN2OCT\t\t\t= BINARIO.OCT\t\t\t##\tConverte un numero binario in ottale\r\nCOMPLEX\t\t\t= COMPLESSO\t\t\t##\tConverte i coefficienti reali e immaginari in numeri complessi\r\nCONVERT\t\t\t= CONVERTI\t\t\t##\tConverte un numero da un sistema di misura in un altro\r\nDEC2BIN\t\t\t= DECIMALE.BINARIO\t\t##\tConverte un numero decimale in binario\r\nDEC2HEX\t\t\t= DECIMALE.HEX\t\t\t##\tConverte un numero decimale in esadecimale\r\nDEC2OCT\t\t\t= DECIMALE.OCT\t\t\t##\tConverte un numero decimale in ottale\r\nDELTA\t\t\t= DELTA\t\t\t\t##\tVerifica se due valori sono uguali\r\nERF\t\t\t= FUNZ.ERRORE\t\t\t##\tRestituisce la funzione di errore\r\nERFC\t\t\t= FUNZ.ERRORE.COMP\t\t##\tRestituisce la funzione di errore complementare\r\nGESTEP\t\t\t= SOGLIA\t\t\t##\tVerifica se un numero è maggiore del valore di soglia\r\nHEX2BIN\t\t\t= HEX.BINARIO\t\t\t##\tConverte un numero esadecimale in binario\r\nHEX2DEC\t\t\t= HEX.DECIMALE\t\t\t##\tConverte un numero esadecimale in decimale\r\nHEX2OCT\t\t\t= HEX.OCT\t\t\t##\tConverte un numero esadecimale in ottale\r\nIMABS\t\t\t= COMP.MODULO\t\t\t##\tRestituisce il valore assoluto (modulo) di un numero complesso\r\nIMAGINARY\t\t= COMP.IMMAGINARIO\t\t##\tRestituisce il coefficiente immaginario di un numero complesso\r\nIMARGUMENT\t\t= COMP.ARGOMENTO\t\t##\tRestituisce l'argomento theta, un angolo espresso in radianti\r\nIMCONJUGATE\t\t= COMP.CONIUGATO\t\t##\tRestituisce il complesso coniugato del numero complesso\r\nIMCOS\t\t\t= COMP.COS\t\t\t##\tRestituisce il coseno di un numero complesso\r\nIMDIV\t\t\t= COMP.DIV\t\t\t##\tRestituisce il quoziente di due numeri complessi\r\nIMEXP\t\t\t= COMP.EXP\t\t\t##\tRestituisce il valore esponenziale di un numero complesso\r\nIMLN\t\t\t= COMP.LN\t\t\t##\tRestituisce il logaritmo naturale di un numero complesso\r\nIMLOG10\t\t\t= COMP.LOG10\t\t\t##\tRestituisce il logaritmo in base 10 di un numero complesso\r\nIMLOG2\t\t\t= COMP.LOG2\t\t\t##\tRestituisce un logaritmo in base 2 di un numero complesso\r\nIMPOWER\t\t\t= COMP.POTENZA\t\t\t##\tRestituisce il numero complesso elevato a una potenza intera\r\nIMPRODUCT\t\t= COMP.PRODOTTO\t\t\t##\tRestituisce il prodotto di numeri complessi compresi tra 2 e 29\r\nIMREAL\t\t\t= COMP.PARTE.REALE\t\t##\tRestituisce il coefficiente reale di un numero complesso\r\nIMSIN\t\t\t= COMP.SEN\t\t\t##\tRestituisce il seno di un numero complesso\r\nIMSQRT\t\t\t= COMP.RADQ\t\t\t##\tRestituisce la radice quadrata di un numero complesso\r\nIMSUB\t\t\t= COMP.DIFF\t\t\t##\tRestituisce la differenza fra due numeri complessi\r\nIMSUM\t\t\t= COMP.SOMMA\t\t\t##\tRestituisce la somma di numeri complessi\r\nOCT2BIN\t\t\t= OCT.BINARIO\t\t\t##\tConverte un numero ottale in binario\r\nOCT2DEC\t\t\t= OCT.DECIMALE\t\t\t##\tConverte un numero ottale in decimale\r\nOCT2HEX\t\t\t= OCT.HEX\t\t\t##\tConverte un numero ottale in esadecimale\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\tFunzioni finanziarie\r\n##\r\nACCRINT\t\t\t= INT.MATURATO.PER\t\t##\tRestituisce l'interesse maturato di un titolo che paga interessi periodici\r\nACCRINTM\t\t= INT.MATURATO.SCAD\t\t##\tRestituisce l'interesse maturato di un titolo che paga interessi alla scadenza\r\nAMORDEGRC\t\t= AMMORT.DEGR\t\t\t##\tRestituisce l'ammortamento per ogni periodo contabile utilizzando un coefficiente di ammortamento\r\nAMORLINC\t\t= AMMORT.PER\t\t\t##\tRestituisce l'ammortamento per ogni periodo contabile\r\nCOUPDAYBS\t\t= GIORNI.CED.INIZ.LIQ\t\t##\tRestituisce il numero dei giorni che vanno dall'inizio del periodo di durata della cedola alla data di liquidazione\r\nCOUPDAYS\t\t= GIORNI.CED\t\t\t##\tRestituisce il numero dei giorni relativi al periodo della cedola che contiene la data di liquidazione\r\nCOUPDAYSNC\t\t= GIORNI.CED.NUOVA\t\t##\tRestituisce il numero di giorni che vanno dalla data di liquidazione alla data della cedola successiva\r\nCOUPNCD\t\t\t= DATA.CED.SUCC\t\t\t##\tRestituisce un numero che rappresenta la data della cedola successiva alla data di liquidazione\r\nCOUPNUM\t\t\t= NUM.CED\t\t\t##\tRestituisce il numero di cedole pagabili fra la data di liquidazione e la data di scadenza\r\nCOUPPCD\t\t\t= DATA.CED.PREC\t\t\t##\tRestituisce un numero che rappresenta la data della cedola precedente alla data di liquidazione\r\nCUMIPMT\t\t\t= INT.CUMUL\t\t\t##\tRestituisce l'interesse cumulativo pagato fra due periodi\r\nCUMPRINC\t\t= CAP.CUM\t\t\t##\tRestituisce il capitale cumulativo pagato per estinguere un debito fra due periodi\r\nDB\t\t\t= DB\t\t\t\t##\tRestituisce l'ammortamento di un bene per un periodo specificato utilizzando il metodo di ammortamento a quote fisse decrescenti\r\nDDB\t\t\t= AMMORT\t\t\t##\tRestituisce l'ammortamento di un bene per un periodo specificato utilizzando il metodo di ammortamento a doppie quote decrescenti o altri metodi specificati\r\nDISC\t\t\t= TASSO.SCONTO\t\t\t##\tRestituisce il tasso di sconto per un titolo\r\nDOLLARDE\t\t= VALUTA.DEC\t\t\t##\tConverte un prezzo valuta, espresso come frazione, in prezzo valuta, espresso come numero decimale\r\nDOLLARFR\t\t= VALUTA.FRAZ\t\t\t##\tConverte un prezzo valuta, espresso come numero decimale, in prezzo valuta, espresso come frazione\r\nDURATION\t\t= DURATA\t\t\t##\tRestituisce la durata annuale di un titolo con i pagamenti di interesse periodico\r\nEFFECT\t\t\t= EFFETTIVO\t\t\t##\tRestituisce l'effettivo tasso di interesse annuo\r\nFV\t\t\t= VAL.FUT\t\t\t##\tRestituisce il valore futuro di un investimento\r\nFVSCHEDULE\t\t= VAL.FUT.CAPITALE\t\t##\tRestituisce il valore futuro di un capitale iniziale dopo aver applicato una serie di tassi di interesse composti\r\nINTRATE\t\t\t= TASSO.INT\t\t\t##\tRestituisce il tasso di interesse per un titolo interamente investito\r\nIPMT\t\t\t= INTERESSI\t\t\t##\tRestituisce il valore degli interessi per un investimento relativo a un periodo specifico\r\nIRR\t\t\t= TIR.COST\t\t\t##\tRestituisce il tasso di rendimento interno per una serie di flussi di cassa\r\nISPMT\t\t\t= INTERESSE.RATA\t\t##\tCalcola l'interesse di un investimento pagato durante un periodo specifico\r\nMDURATION\t\t= DURATA.M\t\t\t##\tRestituisce la durata Macauley modificata per un titolo con un valore presunto di € 100\r\nMIRR\t\t\t= TIR.VAR\t\t\t##\tRestituisce il tasso di rendimento interno in cui i flussi di cassa positivi e negativi sono finanziati a tassi differenti\r\nNOMINAL\t\t\t= NOMINALE\t\t\t##\tRestituisce il tasso di interesse nominale annuale\r\nNPER\t\t\t= NUM.RATE\t\t\t##\tRestituisce un numero di periodi relativi a un investimento\r\nNPV\t\t\t= VAN\t\t\t\t##\tRestituisce il valore attuale netto di un investimento basato su una serie di flussi di cassa periodici e sul tasso di sconto\r\nODDFPRICE\t\t= PREZZO.PRIMO.IRR\t\t##\tRestituisce il prezzo di un titolo dal valore nominale di € 100 avente il primo periodo di durata irregolare\r\nODDFYIELD\t\t= REND.PRIMO.IRR\t\t##\tRestituisce il rendimento di un titolo avente il primo periodo di durata irregolare\r\nODDLPRICE\t\t= PREZZO.ULTIMO.IRR\t\t##\tRestituisce il prezzo di un titolo dal valore nominale di € 100 avente l'ultimo periodo di durata irregolare\r\nODDLYIELD\t\t= REND.ULTIMO.IRR\t\t##\tRestituisce il rendimento di un titolo avente l'ultimo periodo di durata irregolare\r\nPMT\t\t\t= RATA\t\t\t\t##\tRestituisce il pagamento periodico di una rendita annua\r\nPPMT\t\t\t= P.RATA\t\t\t##\tRestituisce il pagamento sul capitale di un investimento per un dato periodo\r\nPRICE\t\t\t= PREZZO\t\t\t##\tRestituisce il prezzo di un titolo dal valore nominale di € 100 che paga interessi periodici\r\nPRICEDISC\t\t= PREZZO.SCONT\t\t\t##\tRestituisce il prezzo di un titolo scontato dal valore nominale di € 100\r\nPRICEMAT\t\t= PREZZO.SCAD\t\t\t##\tRestituisce il prezzo di un titolo dal valore nominale di € 100 che paga gli interessi alla scadenza\r\nPV\t\t\t= VA\t\t\t\t##\tRestituisce il valore attuale di un investimento\r\nRATE\t\t\t= TASSO\t\t\t\t##\tRestituisce il tasso di interesse per un periodo di un'annualità\r\nRECEIVED\t\t= RICEV.SCAD\t\t\t##\tRestituisce l'ammontare ricevuto alla scadenza di un titolo interamente investito\r\nSLN\t\t\t= AMMORT.COST\t\t\t##\tRestituisce l'ammortamento a quote costanti di un bene per un singolo periodo\r\nSYD\t\t\t= AMMORT.ANNUO\t\t\t##\tRestituisce l'ammortamento a somma degli anni di un bene per un periodo specificato\r\nTBILLEQ\t\t\t= BOT.EQUIV\t\t\t##\tRestituisce il rendimento equivalente ad un'obbligazione per un Buono ordinario del Tesoro\r\nTBILLPRICE\t\t= BOT.PREZZO\t\t\t##\tRestituisce il prezzo di un Buono del Tesoro dal valore nominale di € 100\r\nTBILLYIELD\t\t= BOT.REND\t\t\t##\tRestituisce il rendimento di un Buono del Tesoro\r\nVDB\t\t\t= AMMORT.VAR\t\t\t##\tRestituisce l'ammortamento di un bene per un periodo specificato o parziale utilizzando il metodo a doppie quote proporzionali ai valori residui\r\nXIRR\t\t\t= TIR.X\t\t\t\t##\tRestituisce il tasso di rendimento interno di un impiego di flussi di cassa\r\nXNPV\t\t\t= VAN.X\t\t\t\t##\tRestituisce il valore attuale netto di un impiego di flussi di cassa non necessariamente periodici\r\nYIELD\t\t\t= REND\t\t\t\t##\tRestituisce il rendimento di un titolo che frutta interessi periodici\r\nYIELDDISC\t\t= REND.TITOLI.SCONT\t\t##\tRestituisce il rendimento annuale di un titolo scontato, ad esempio un Buono del Tesoro\r\nYIELDMAT\t\t= REND.SCAD\t\t\t##\tRestituisce il rendimento annuo di un titolo che paga interessi alla scadenza\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\tFunzioni relative alle informazioni\r\n##\r\nCELL\t\t\t= CELLA\t\t\t\t##\tRestituisce le informazioni sulla formattazione, la posizione o i contenuti di una cella\r\nERROR.TYPE\t\t= ERRORE.TIPO\t\t\t##\tRestituisce un numero che corrisponde a un tipo di errore\r\nINFO\t\t\t= INFO\t\t\t\t##\tRestituisce le informazioni sull'ambiente operativo corrente\r\nISBLANK\t\t\t= VAL.VUOTO\t\t\t##\tRestituisce VERO se il valore è vuoto\r\nISERR\t\t\t= VAL.ERR\t\t\t##\tRestituisce VERO se il valore è un valore di errore qualsiasi tranne #N/D\r\nISERROR\t\t\t= VAL.ERRORE\t\t\t##\tRestituisce VERO se il valore è un valore di errore qualsiasi\r\nISEVEN\t\t\t= VAL.PARI\t\t\t##\tRestituisce VERO se il numero è pari\r\nISLOGICAL\t\t= VAL.LOGICO\t\t\t##\tRestituisce VERO se il valore è un valore logico\r\nISNA\t\t\t= VAL.NON.DISP\t\t\t##\tRestituisce VERO se il valore è un valore di errore #N/D\r\nISNONTEXT\t\t= VAL.NON.TESTO\t\t\t##\tRestituisce VERO se il valore non è in formato testo\r\nISNUMBER\t\t= VAL.NUMERO\t\t\t##\tRestituisce VERO se il valore è un numero\r\nISODD\t\t\t= VAL.DISPARI\t\t\t##\tRestituisce VERO se il numero è dispari\r\nISREF\t\t\t= VAL.RIF\t\t\t##\tRestituisce VERO se il valore è un riferimento\r\nISTEXT\t\t\t= VAL.TESTO\t\t\t##\tRestituisce VERO se il valore è in formato testo\r\nN\t\t\t= NUM\t\t\t\t##\tRestituisce un valore convertito in numero\r\nNA\t\t\t= NON.DISP\t\t\t##\tRestituisce il valore di errore #N/D\r\nTYPE\t\t\t= TIPO\t\t\t\t##\tRestituisce un numero che indica il tipo di dati relativi a un valore\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\tFunzioni logiche\r\n##\r\nAND\t\t\t= E\t\t\t\t##\tRestituisce VERO se tutti gli argomenti sono VERO\r\nFALSE\t\t\t= FALSO\t\t\t\t##\tRestituisce il valore logico FALSO\r\nIF\t\t\t= SE\t\t\t\t##\tSpecifica un test logico da eseguire\r\nIFERROR\t\t\t= SE.ERRORE\t\t\t##\tRestituisce un valore specificato se una formula fornisce un errore come risultato; in caso contrario, restituisce il risultato della formula\r\nNOT\t\t\t= NON\t\t\t\t##\tInverte la logica degli argomenti\r\nOR\t\t\t= O\t\t\t\t##\tRestituisce VERO se un argomento qualsiasi è VERO\r\nTRUE\t\t\t= VERO\t\t\t\t##\tRestituisce il valore logico VERO\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\tFunzioni di ricerca e di riferimento\r\n##\r\nADDRESS\t\t\t= INDIRIZZO\t\t\t##\tRestituisce un riferimento come testo in una singola cella di un foglio di lavoro\r\nAREAS\t\t\t= AREE\t\t\t\t##\tRestituisce il numero di aree in un riferimento\r\nCHOOSE\t\t\t= SCEGLI\t\t\t##\tSceglie un valore da un elenco di valori\r\nCOLUMN\t\t\t= RIF.COLONNA\t\t\t##\tRestituisce il numero di colonna di un riferimento\r\nCOLUMNS\t\t\t= COLONNE\t\t\t##\tRestituisce il numero di colonne in un riferimento\r\nHLOOKUP\t\t\t= CERCA.ORIZZ\t\t\t##\tEffettua una ricerca nella riga superiore di una matrice e restituisce il valore della cella specificata\r\nHYPERLINK\t\t= COLLEG.IPERTESTUALE\t\t##\tCrea un collegamento che apre un documento memorizzato in un server di rete, una rete Intranet o Internet\r\nINDEX\t\t\t= INDICE\t\t\t##\tUtilizza un indice per scegliere un valore da un riferimento o da una matrice\r\nINDIRECT\t\t= INDIRETTO\t\t\t##\tRestituisce un riferimento specificato da un valore testo\r\nLOOKUP\t\t\t= CERCA\t\t\t\t##\tRicerca i valori in un vettore o in una matrice\r\nMATCH\t\t\t= CONFRONTA\t\t\t##\tRicerca i valori in un riferimento o in una matrice\r\nOFFSET\t\t\t= SCARTO\t\t\t##\tRestituisce uno scarto di riferimento da un riferimento dato\r\nROW\t\t\t= RIF.RIGA\t\t\t##\tRestituisce il numero di riga di un riferimento\r\nROWS\t\t\t= RIGHE\t\t\t\t##\tRestituisce il numero delle righe in un riferimento\r\nRTD\t\t\t= DATITEMPOREALE\t\t##\tRecupera dati in tempo reale da un programma che supporta l'automazione COM (automazione: Metodo per utilizzare gli oggetti di un'applicazione da un'altra applicazione o da un altro strumento di sviluppo. Precedentemente nota come automazione OLE, l'automazione è uno standard del settore e una caratteristica del modello COM (Component Object Model).)\r\nTRANSPOSE\t\t= MATR.TRASPOSTA\t\t##\tRestituisce la trasposizione di una matrice\r\nVLOOKUP\t\t\t= CERCA.VERT\t\t\t##\tEffettua una ricerca nella prima colonna di una matrice e si sposta attraverso la riga per restituire il valore di una cella\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\tFunzioni matematiche e trigonometriche\r\n##\r\nABS\t\t\t= ASS\t\t\t\t##\tRestituisce il valore assoluto di un numero.\r\nACOS\t\t\t= ARCCOS\t\t\t##\tRestituisce l'arcocoseno di un numero\r\nACOSH\t\t\t= ARCCOSH\t\t\t##\tRestituisce l'inverso del coseno iperbolico di un numero\r\nASIN\t\t\t= ARCSEN\t\t\t##\tRestituisce l'arcoseno di un numero\r\nASINH\t\t\t= ARCSENH\t\t\t##\tRestituisce l'inverso del seno iperbolico di un numero\r\nATAN\t\t\t= ARCTAN\t\t\t##\tRestituisce l'arcotangente di un numero\r\nATAN2\t\t\t= ARCTAN.2\t\t\t##\tRestituisce l'arcotangente delle coordinate x e y specificate\r\nATANH\t\t\t= ARCTANH\t\t\t##\tRestituisce l'inverso della tangente iperbolica di un numero\r\nCEILING\t\t\t= ARROTONDA.ECCESSO\t\t##\tArrotonda un numero per eccesso all'intero più vicino o al multiplo più vicino a peso\r\nCOMBIN\t\t\t= COMBINAZIONE\t\t\t##\tRestituisce il numero di combinazioni possibili per un numero assegnato di elementi\r\nCOS\t\t\t= COS\t\t\t\t##\tRestituisce il coseno dell'angolo specificato\r\nCOSH\t\t\t= COSH\t\t\t\t##\tRestituisce il coseno iperbolico di un numero\r\nDEGREES\t\t\t= GRADI\t\t\t\t##\tConverte i radianti in gradi\r\nEVEN\t\t\t= PARI\t\t\t\t##\tArrotonda il valore assoluto di un numero per eccesso al più vicino intero pari\r\nEXP\t\t\t= ESP\t\t\t\t##\tRestituisce il numero e elevato alla potenza di num\r\nFACT\t\t\t= FATTORIALE\t\t\t##\tRestituisce il fattoriale di un numero\r\nFACTDOUBLE\t\t= FATT.DOPPIO\t\t\t##\tRestituisce il fattoriale doppio di un numero\r\nFLOOR\t\t\t= ARROTONDA.DIFETTO\t\t##\tArrotonda un numero per difetto al multiplo più vicino a zero\r\nGCD\t\t\t= MCD\t\t\t\t##\tRestituisce il massimo comune divisore\r\nINT\t\t\t= INT\t\t\t\t##\tArrotonda un numero per difetto al numero intero più vicino\r\nLCM\t\t\t= MCM\t\t\t\t##\tRestituisce il minimo comune multiplo\r\nLN\t\t\t= LN\t\t\t\t##\tRestituisce il logaritmo naturale di un numero\r\nLOG\t\t\t= LOG\t\t\t\t##\tRestituisce il logaritmo di un numero in una specificata base\r\nLOG10\t\t\t= LOG10\t\t\t\t##\tRestituisce il logaritmo in base 10 di un numero\r\nMDETERM\t\t\t= MATR.DETERM\t\t\t##\tRestituisce il determinante di una matrice\r\nMINVERSE\t\t= MATR.INVERSA\t\t\t##\tRestituisce l'inverso di una matrice\r\nMMULT\t\t\t= MATR.PRODOTTO\t\t\t##\tRestituisce il prodotto di due matrici\r\nMOD\t\t\t= RESTO\t\t\t\t##\tRestituisce il resto della divisione\r\nMROUND\t\t\t= ARROTONDA.MULTIPLO\t\t##\tRestituisce un numero arrotondato al multiplo desiderato\r\nMULTINOMIAL\t\t= MULTINOMIALE\t\t\t##\tRestituisce il multinomiale di un insieme di numeri\r\nODD\t\t\t= DISPARI\t\t\t##\tArrotonda un numero per eccesso al più vicino intero dispari\r\nPI\t\t\t= PI.GRECO\t\t\t##\tRestituisce il valore di pi greco\r\nPOWER\t\t\t= POTENZA\t\t\t##\tRestituisce il risultato di un numero elevato a potenza\r\nPRODUCT\t\t\t= PRODOTTO\t\t\t##\tMoltiplica i suoi argomenti\r\nQUOTIENT\t\t= QUOZIENTE\t\t\t##\tRestituisce la parte intera di una divisione\r\nRADIANS\t\t\t= RADIANTI\t\t\t##\tConverte i gradi in radianti\r\nRAND\t\t\t= CASUALE\t\t\t##\tRestituisce un numero casuale compreso tra 0 e 1\r\nRANDBETWEEN\t\t= CASUALE.TRA\t\t\t##\tRestituisce un numero casuale compreso tra i numeri specificati\r\nROMAN\t\t\t= ROMANO\t\t\t##\tRestituisce il numero come numero romano sotto forma di testo\r\nROUND\t\t\t= ARROTONDA\t\t\t##\tArrotonda il numero al numero di cifre specificato\r\nROUNDDOWN\t\t= ARROTONDA.PER.DIF\t\t##\tArrotonda il valore assoluto di un numero per difetto\r\nROUNDUP\t\t\t= ARROTONDA.PER.ECC\t\t##\tArrotonda il valore assoluto di un numero per eccesso\r\nSERIESSUM\t\t= SOMMA.SERIE\t\t\t##\tRestituisce la somma di una serie di potenze in base alla formula\r\nSIGN\t\t\t= SEGNO\t\t\t\t##\tRestituisce il segno di un numero\r\nSIN\t\t\t= SEN\t\t\t\t##\tRestituisce il seno di un dato angolo\r\nSINH\t\t\t= SENH\t\t\t\t##\tRestituisce il seno iperbolico di un numero\r\nSQRT\t\t\t= RADQ\t\t\t\t##\tRestituisce una radice quadrata\r\nSQRTPI\t\t\t= RADQ.PI.GRECO\t\t\t##\tRestituisce la radice quadrata di un numero (numero * pi greco)\r\nSUBTOTAL\t\t= SUBTOTALE\t\t\t##\tRestituisce un subtotale in un elenco o in un database\r\nSUM\t\t\t= SOMMA\t\t\t\t##\tSomma i suoi argomenti\r\nSUMIF\t\t\t= SOMMA.SE\t\t\t##\tSomma le celle specificate da un dato criterio\r\nSUMIFS\t\t\t= SOMMA.PIÙ.SE\t\t\t##\tSomma le celle in un intervallo che soddisfano più criteri\r\nSUMPRODUCT\t\t= MATR.SOMMA.PRODOTTO\t\t##\tRestituisce la somma dei prodotti dei componenti corrispondenti della matrice\r\nSUMSQ\t\t\t= SOMMA.Q\t\t\t##\tRestituisce la somma dei quadrati degli argomenti\r\nSUMX2MY2\t\t= SOMMA.DIFF.Q\t\t\t##\tRestituisce la somma della differenza dei quadrati dei corrispondenti elementi in due matrici\r\nSUMX2PY2\t\t= SOMMA.SOMMA.Q\t\t\t##\tRestituisce la somma della somma dei quadrati dei corrispondenti elementi in due matrici\r\nSUMXMY2\t\t\t= SOMMA.Q.DIFF\t\t\t##\tRestituisce la somma dei quadrati delle differenze dei corrispondenti elementi in due matrici\r\nTAN\t\t\t= TAN\t\t\t\t##\tRestituisce la tangente di un numero\r\nTANH\t\t\t= TANH\t\t\t\t##\tRestituisce la tangente iperbolica di un numero\r\nTRUNC\t\t\t= TRONCA\t\t\t##\tTronca la parte decimale di un numero\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\tFunzioni statistiche\r\n##\r\nAVEDEV\t\t\t= MEDIA.DEV\t\t\t##\tRestituisce la media delle deviazioni assolute delle coordinate rispetto alla loro media\r\nAVERAGE\t\t\t= MEDIA\t\t\t\t##\tRestituisce la media degli argomenti\r\nAVERAGEA\t\t= MEDIA.VALORI\t\t\t##\tRestituisce la media degli argomenti, inclusi i numeri, il testo e i valori logici\r\nAVERAGEIF\t\t= MEDIA.SE\t\t\t##\tRestituisce la media aritmetica di tutte le celle in un intervallo che soddisfano un determinato criterio\r\nAVERAGEIFS\t\t= MEDIA.PIÙ.SE\t\t\t##\tRestituisce la media aritmetica di tutte le celle che soddisfano più criteri\r\nBETADIST\t\t= DISTRIB.BETA\t\t\t##\tRestituisce la funzione di distribuzione cumulativa beta\r\nBETAINV\t\t\t= INV.BETA\t\t\t##\tRestituisce l'inverso della funzione di distribuzione cumulativa per una distribuzione beta specificata\r\nBINOMDIST\t\t= DISTRIB.BINOM\t\t\t##\tRestituisce la distribuzione binomiale per il termine individuale\r\nCHIDIST\t\t\t= DISTRIB.CHI\t\t\t##\tRestituisce la probabilità a una coda per la distribuzione del chi quadrato\r\nCHIINV\t\t\t= INV.CHI\t\t\t##\tRestituisce l'inverso della probabilità ad una coda per la distribuzione del chi quadrato\r\nCHITEST\t\t\t= TEST.CHI\t\t\t##\tRestituisce il test per l'indipendenza\r\nCONFIDENCE\t\t= CONFIDENZA\t\t\t##\tRestituisce l'intervallo di confidenza per una popolazione\r\nCORREL\t\t\t= CORRELAZIONE\t\t\t##\tRestituisce il coefficiente di correlazione tra due insiemi di dati\r\nCOUNT\t\t\t= CONTA.NUMERI\t\t\t##\tConta la quantità di numeri nell'elenco di argomenti\r\nCOUNTA\t\t\t= CONTA.VALORI\t\t\t##\tConta il numero di valori nell'elenco di argomenti\r\nCOUNTBLANK\t\t= CONTA.VUOTE\t\t\t##\tConta il numero di celle vuote all'interno di un intervallo\r\nCOUNTIF\t\t\t= CONTA.SE\t\t\t##\tConta il numero di celle all'interno di un intervallo che soddisfa i criteri specificati\r\nCOUNTIFS\t\t= CONTA.PIÙ.SE\t\t\t##\tConta il numero di celle in un intervallo che soddisfano più criteri.\r\nCOVAR\t\t\t= COVARIANZA\t\t\t##\tCalcola la covarianza, la media dei prodotti delle deviazioni accoppiate\r\nCRITBINOM\t\t= CRIT.BINOM\t\t\t##\tRestituisce il più piccolo valore per il quale la distribuzione cumulativa binomiale risulta maggiore o uguale ad un valore di criterio\r\nDEVSQ\t\t\t= DEV.Q\t\t\t\t##\tRestituisce la somma dei quadrati delle deviazioni\r\nEXPONDIST\t\t= DISTRIB.EXP\t\t\t##\tRestituisce la distribuzione esponenziale\r\nFDIST\t\t\t= DISTRIB.F\t\t\t##\tRestituisce la distribuzione di probabilità F\r\nFINV\t\t\t= INV.F\t\t\t\t##\tRestituisce l'inverso della distribuzione della probabilità F\r\nFISHER\t\t\t= FISHER\t\t\t##\tRestituisce la trasformazione di Fisher\r\nFISHERINV\t\t= INV.FISHER\t\t\t##\tRestituisce l'inverso della trasformazione di Fisher\r\nFORECAST\t\t= PREVISIONE\t\t\t##\tRestituisce i valori lungo una tendenza lineare\r\nFREQUENCY\t\t= FREQUENZA\t\t\t##\tRestituisce la distribuzione di frequenza come matrice verticale\r\nFTEST\t\t\t= TEST.F\t\t\t##\tRestituisce il risultato di un test F\r\nGAMMADIST\t\t= DISTRIB.GAMMA\t\t\t##\tRestituisce la distribuzione gamma\r\nGAMMAINV\t\t= INV.GAMMA\t\t\t##\tRestituisce l'inverso della distribuzione cumulativa gamma\r\nGAMMALN\t\t\t= LN.GAMMA\t\t\t##\tRestituisce il logaritmo naturale della funzione gamma, G(x)\r\nGEOMEAN\t\t\t= MEDIA.GEOMETRICA\t\t##\tRestituisce la media geometrica\r\nGROWTH\t\t\t= CRESCITA\t\t\t##\tRestituisce i valori lungo una linea di tendenza esponenziale\r\nHARMEAN\t\t\t= MEDIA.ARMONICA\t\t##\tRestituisce la media armonica\r\nHYPGEOMDIST\t\t= DISTRIB.IPERGEOM\t\t##\tRestituisce la distribuzione ipergeometrica\r\nINTERCEPT\t\t= INTERCETTA\t\t\t##\tRestituisce l'intercetta della retta di regressione lineare\r\nKURT\t\t\t= CURTOSI\t\t\t##\tRestituisce la curtosi di un insieme di dati\r\nLARGE\t\t\t= GRANDE\t\t\t##\tRestituisce il k-esimo valore più grande in un insieme di dati\r\nLINEST\t\t\t= REGR.LIN\t\t\t##\tRestituisce i parametri di una tendenza lineare\r\nLOGEST\t\t\t= REGR.LOG\t\t\t##\tRestituisce i parametri di una linea di tendenza esponenziale\r\nLOGINV\t\t\t= INV.LOGNORM\t\t\t##\tRestituisce l'inverso di una distribuzione lognormale\r\nLOGNORMDIST\t\t= DISTRIB.LOGNORM\t\t##\tRestituisce la distribuzione lognormale cumulativa\r\nMAX\t\t\t= MAX\t\t\t\t##\tRestituisce il valore massimo in un elenco di argomenti\r\nMAXA\t\t\t= MAX.VALORI\t\t\t##\tRestituisce il valore massimo in un elenco di argomenti, inclusi i numeri, il testo e i valori logici\r\nMEDIAN\t\t\t= MEDIANA\t\t\t##\tRestituisce la mediana dei numeri specificati\r\nMIN\t\t\t= MIN\t\t\t\t##\tRestituisce il valore minimo in un elenco di argomenti\r\nMINA\t\t\t= MIN.VALORI\t\t\t##\tRestituisce il più piccolo valore in un elenco di argomenti, inclusi i numeri, il testo e i valori logici\r\nMODE\t\t\t= MODA\t\t\t\t##\tRestituisce il valore più comune in un insieme di dati\r\nNEGBINOMDIST\t\t= DISTRIB.BINOM.NEG\t\t##\tRestituisce la distribuzione binomiale negativa\r\nNORMDIST\t\t= DISTRIB.NORM\t\t\t##\tRestituisce la distribuzione cumulativa normale\r\nNORMINV\t\t\t= INV.NORM\t\t\t##\tRestituisce l'inverso della distribuzione cumulativa normale standard\r\nNORMSDIST\t\t= DISTRIB.NORM.ST\t\t##\tRestituisce la distribuzione cumulativa normale standard\r\nNORMSINV\t\t= INV.NORM.ST\t\t\t##\tRestituisce l'inverso della distribuzione cumulativa normale\r\nPEARSON\t\t\t= PEARSON\t\t\t##\tRestituisce il coefficiente del momento di correlazione di Pearson\r\nPERCENTILE\t\t= PERCENTILE\t\t\t##\tRestituisce il k-esimo dato percentile di valori in un intervallo\r\nPERCENTRANK\t\t= PERCENT.RANGO\t\t\t##\tRestituisce il rango di un valore in un insieme di dati come percentuale\r\nPERMUT\t\t\t= PERMUTAZIONE\t\t\t##\tRestituisce il numero delle permutazioni per un determinato numero di oggetti\r\nPOISSON\t\t\t= POISSON\t\t\t##\tRestituisce la distribuzione di Poisson\r\nPROB\t\t\t= PROBABILITÀ\t\t\t##\tCalcola la probabilità che dei valori in un intervallo siano compresi tra due limiti\r\nQUARTILE\t\t= QUARTILE\t\t\t##\tRestituisce il quartile di un insieme di dati\r\nRANK\t\t\t= RANGO\t\t\t\t##\tRestituisce il rango di un numero in un elenco di numeri\r\nRSQ\t\t\t= RQ\t\t\t\t##\tRestituisce la radice quadrata del coefficiente di momento di correlazione di Pearson\r\nSKEW\t\t\t= ASIMMETRIA\t\t\t##\tRestituisce il grado di asimmetria di una distribuzione\r\nSLOPE\t\t\t= PENDENZA\t\t\t##\tRestituisce la pendenza di una retta di regressione lineare\r\nSMALL\t\t\t= PICCOLO\t\t\t##\tRestituisce il k-esimo valore più piccolo in un insieme di dati\r\nSTANDARDIZE\t\t= NORMALIZZA\t\t\t##\tRestituisce un valore normalizzato\r\nSTDEV\t\t\t= DEV.ST\t\t\t##\tRestituisce una stima della deviazione standard sulla base di un campione\r\nSTDEVA\t\t\t= DEV.ST.VALORI\t\t\t##\tRestituisce una stima della deviazione standard sulla base di un campione, inclusi i numeri, il testo e i valori logici\r\nSTDEVP\t\t\t= DEV.ST.POP\t\t\t##\tCalcola la deviazione standard sulla base di un'intera popolazione\r\nSTDEVPA\t\t\t= DEV.ST.POP.VALORI\t\t##\tCalcola la deviazione standard sulla base sull'intera popolazione, inclusi i numeri, il testo e i valori logici\r\nSTEYX\t\t\t= ERR.STD.YX\t\t\t##\tRestituisce l'errore standard del valore previsto per y per ogni valore x nella regressione\r\nTDIST\t\t\t= DISTRIB.T\t\t\t##\tRestituisce la distribuzione t di Student\r\nTINV\t\t\t= INV.T\t\t\t\t##\tRestituisce l'inversa della distribuzione t di Student\r\nTREND\t\t\t= TENDENZA\t\t\t##\tRestituisce i valori lungo una linea di tendenza lineare\r\nTRIMMEAN\t\t= MEDIA.TRONCATA\t\t##\tRestituisce la media della parte interna di un insieme di dati\r\nTTEST\t\t\t= TEST.T\t\t\t##\tRestituisce la probabilità associata ad un test t di Student\r\nVAR\t\t\t= VAR\t\t\t\t##\tStima la varianza sulla base di un campione\r\nVARA\t\t\t= VAR.VALORI\t\t\t##\tStima la varianza sulla base di un campione, inclusi i numeri, il testo e i valori logici\r\nVARP\t\t\t= VAR.POP\t\t\t##\tCalcola la varianza sulla base dell'intera popolazione\r\nVARPA\t\t\t= VAR.POP.VALORI\t\t##\tCalcola la deviazione standard sulla base sull'intera popolazione, inclusi i numeri, il testo e i valori logici\r\nWEIBULL\t\t\t= WEIBULL\t\t\t##\tRestituisce la distribuzione di Weibull\r\nZTEST\t\t\t= TEST.Z\t\t\t##\tRestituisce il valore di probabilità a una coda per un test z\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\tFunzioni di testo\r\n##\r\nASC\t\t\t= ASC\t\t\t\t##\tModifica le lettere inglesi o il katakana a doppio byte all'interno di una stringa di caratteri in caratteri a singolo byte\r\nBAHTTEXT\t\t= BAHTTESTO\t\t\t##\tConverte un numero in testo, utilizzando il formato valuta ß (baht)\r\nCHAR\t\t\t= CODICE.CARATT\t\t\t##\tRestituisce il carattere specificato dal numero di codice\r\nCLEAN\t\t\t= LIBERA\t\t\t##\tElimina dal testo tutti i caratteri che non è possibile stampare\r\nCODE\t\t\t= CODICE\t\t\t##\tRestituisce il codice numerico del primo carattere di una stringa di testo\r\nCONCATENATE\t\t= CONCATENA\t\t\t##\tUnisce diversi elementi di testo in un unico elemento di testo\r\nDOLLAR\t\t\t= VALUTA\t\t\t##\tConverte un numero in testo, utilizzando il formato valuta € (euro)\r\nEXACT\t\t\t= IDENTICO\t\t\t##\tVerifica se due valori di testo sono uguali\r\nFIND\t\t\t= TROVA\t\t\t\t##\tRileva un valore di testo all'interno di un altro (distinzione tra maiuscole e minuscole)\r\nFINDB\t\t\t= TROVA.B\t\t\t##\tRileva un valore di testo all'interno di un altro (distinzione tra maiuscole e minuscole)\r\nFIXED\t\t\t= FISSO\t\t\t\t##\tFormatta un numero come testo con un numero fisso di decimali\r\nJIS\t\t\t= ORDINAMENTO.JIS\t\t##\tModifica le lettere inglesi o i caratteri katakana a byte singolo all'interno di una stringa di caratteri in caratteri a byte doppio.\r\nLEFT\t\t\t= SINISTRA\t\t\t##\tRestituisce il carattere più a sinistra di un valore di testo\r\nLEFTB\t\t\t= SINISTRA.B\t\t\t##\tRestituisce il carattere più a sinistra di un valore di testo\r\nLEN\t\t\t= LUNGHEZZA\t\t\t##\tRestituisce il numero di caratteri di una stringa di testo\r\nLENB\t\t\t= LUNB\t\t\t\t##\tRestituisce il numero di caratteri di una stringa di testo\r\nLOWER\t\t\t= MINUSC\t\t\t##\tConverte il testo in lettere minuscole\r\nMID\t\t\t= MEDIA\t\t\t\t##\tRestituisce un numero specifico di caratteri di una stringa di testo a partire dalla posizione specificata\r\nMIDB\t\t\t= MEDIA.B\t\t\t##\tRestituisce un numero specifico di caratteri di una stringa di testo a partire dalla posizione specificata\r\nPHONETIC\t\t= FURIGANA\t\t\t##\tEstrae i caratteri fonetici (furigana) da una stringa di testo.\r\nPROPER\t\t\t= MAIUSC.INIZ\t\t\t##\tConverte in maiuscolo la prima lettera di ogni parola di un valore di testo\r\nREPLACE\t\t\t= RIMPIAZZA\t\t\t##\tSostituisce i caratteri all'interno di un testo\r\nREPLACEB\t\t= SOSTITUISCI.B\t\t\t##\tSostituisce i caratteri all'interno di un testo\r\nREPT\t\t\t= RIPETI\t\t\t##\tRipete un testo per un dato numero di volte\r\nRIGHT\t\t\t= DESTRA\t\t\t##\tRestituisce il carattere più a destra di un valore di testo\r\nRIGHTB\t\t\t= DESTRA.B\t\t\t##\tRestituisce il carattere più a destra di un valore di testo\r\nSEARCH\t\t\t= RICERCA\t\t\t##\tRileva un valore di testo all'interno di un altro (non è sensibile alle maiuscole e minuscole)\r\nSEARCHB\t\t\t= CERCA.B\t\t\t##\tRileva un valore di testo all'interno di un altro (non è sensibile alle maiuscole e minuscole)\r\nSUBSTITUTE\t\t= SOSTITUISCI\t\t\t##\tSostituisce il nuovo testo al testo contenuto in una stringa\r\nT\t\t\t= T\t\t\t\t##\tConverte gli argomenti in testo\r\nTEXT\t\t\t= TESTO\t\t\t\t##\tFormatta un numero e lo converte in testo\r\nTRIM\t\t\t= ANNULLA.SPAZI\t\t\t##\tElimina gli spazi dal testo\r\nUPPER\t\t\t= MAIUSC\t\t\t##\tConverte il testo in lettere maiuscole\r\nVALUE\t\t\t= VALORE\t\t\t##\tConverte un argomento di testo in numero\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= €\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #LEEG!\r\nDIV0\t= #DEEL/0!\r\nVALUE\t= #WAARDE!\r\nREF\t= #VERW!\r\nNAME\t= #NAAM?\r\nNUM\t= #GETAL!\r\nNA\t= #N/B\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/nl/functions",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Calculation\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/\r\n##\r\n##\r\n\r\n\r\n##\r\n##\tAdd-in and Automation functions\t\t\tAutomatiseringsfuncties en functies in invoegtoepassingen\r\n##\r\nGETPIVOTDATA\t\t= DRAAITABEL.OPHALEN\t\t##\tGeeft gegevens uit een draaitabelrapport als resultaat\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\tKubusfuncties\r\n##\r\nCUBEKPIMEMBER\t\t= KUBUSKPILID\t\t\t##\tRetourneert de naam, eigenschap en waarde van een KPI (prestatie-indicator) en geeft de naam en de eigenschap in de cel weer. Een KPI is een meetbare waarde, zoals de maandelijkse brutowinst of de omzet per kwartaal per werknemer, die wordt gebruikt om de prestaties van een organisatie te bewaken\r\nCUBEMEMBER\t\t= KUBUSLID\t\t\t##\tRetourneert een lid of tupel in een kubushiërarchie. Wordt gebruikt om te controleren of het lid of de tupel in de kubus aanwezig is\r\nCUBEMEMBERPROPERTY\t= KUBUSLIDEIGENSCHAP\t\t##\tRetourneert de waarde van een lideigenschap in de kubus. Wordt gebruikt om te controleren of de lidnaam in de kubus bestaat en retourneert de opgegeven eigenschap voor dit lid\r\nCUBERANKEDMEMBER\t= KUBUSGERANGCHIKTLID\t\t##\tRetourneert het zoveelste, gerangschikte lid in een set. Wordt gebruikt om een of meer elementen in een set te retourneren, zoals de tien beste verkopers of de tien beste studenten\r\nCUBESET\t\t\t= KUBUSSET\t\t\t##\tDefinieert een berekende set leden of tupels door een ingestelde expressie naar de kubus op de server te sturen, alwaar de set wordt gemaakt en vervolgens wordt geretourneerd naar Microsoft Office Excel\r\nCUBESETCOUNT\t\t= KUBUSSETAANTAL\t\t##\tRetourneert het aantal onderdelen in een set\r\nCUBEVALUE\t\t= KUBUSWAARDE\t\t\t##\tRetourneert een samengestelde waarde van een kubus\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\tDatabasefuncties\r\n##\r\nDAVERAGE\t\t= DBGEMIDDELDE\t\t\t##\tBerekent de gemiddelde waarde in geselecteerde databasegegevens\r\nDCOUNT\t\t\t= DBAANTAL\t\t\t##\tTelt de cellen met getallen in een database\r\nDCOUNTA\t\t\t= DBAANTALC\t\t\t##\tTelt de niet-lege cellen in een database\r\nDGET\t\t\t= DBLEZEN\t\t\t##\tRetourneert één record dat voldoet aan de opgegeven criteria uit een database\r\nDMAX\t\t\t= DBMAX\t\t\t\t##\tRetourneert de maximumwaarde in de geselecteerde databasegegevens\r\nDMIN\t\t\t= DBMIN\t\t\t\t##\tRetourneert de minimumwaarde in de geselecteerde databasegegevens\r\nDPRODUCT\t\t= DBPRODUCT\t\t\t##\tVermenigvuldigt de waarden in een bepaald veld van de records die voldoen aan de criteria in een database\r\nDSTDEV\t\t\t= DBSTDEV\t\t\t##\tMaakt een schatting van de standaarddeviatie op basis van een steekproef uit geselecteerde databasegegevens\r\nDSTDEVP\t\t\t= DBSTDEVP\t\t\t##\tBerekent de standaarddeviatie op basis van de volledige populatie van geselecteerde databasegegevens\r\nDSUM\t\t\t= DBSOM\t\t\t\t##\tTelt de getallen uit een kolom records in de database op die voldoen aan de criteria\r\nDVAR\t\t\t= DBVAR\t\t\t\t##\tMaakt een schatting van de variantie op basis van een steekproef uit geselecteerde databasegegevens\r\nDVARP\t\t\t= DBVARP\t\t\t##\tBerekent de variantie op basis van de volledige populatie van geselecteerde databasegegevens\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\tDatum- en tijdfuncties\r\n##\r\nDATE\t\t\t= DATUM\t\t\t\t##\tGeeft als resultaat het seriële getal van een opgegeven datum\r\nDATEVALUE\t\t= DATUMWAARDE\t\t\t##\tConverteert een datum in de vorm van tekst naar een serieel getal\r\nDAY\t\t\t= DAG\t\t\t\t##\tConverteert een serieel getal naar een dag van de maand\r\nDAYS360\t\t\t= DAGEN360\t\t\t##\tBerekent het aantal dagen tussen twee datums op basis van een jaar met 360 dagen\r\nEDATE\t\t\t= ZELFDE.DAG\t\t\t##\tGeeft als resultaat het seriële getal van een datum die het opgegeven aantal maanden voor of na de begindatum ligt\r\nEOMONTH\t\t\t= LAATSTE.DAG\t\t\t##\tGeeft als resultaat het seriële getal van de laatste dag van de maand voor of na het opgegeven aantal maanden\r\nHOUR\t\t\t= UUR\t\t\t\t##\tConverteert een serieel getal naar uren\r\nMINUTE\t\t\t= MINUUT\t\t\t##\tConverteert een serieel naar getal minuten\r\nMONTH\t\t\t= MAAND\t\t\t\t##\tConverteert een serieel getal naar een maand\r\nNETWORKDAYS\t\t= NETTO.WERKDAGEN\t\t##\tGeeft als resultaat het aantal hele werkdagen tussen twee datums\r\nNOW\t\t\t= NU\t\t\t\t##\tGeeft als resultaat het seriële getal van de huidige datum en tijd\r\nSECOND\t\t\t= SECONDE\t\t\t##\tConverteert een serieel getal naar seconden\r\nTIME\t\t\t= TIJD\t\t\t\t##\tGeeft als resultaat het seriële getal van een bepaald tijdstip\r\nTIMEVALUE\t\t= TIJDWAARDE\t\t\t##\tConverteert de tijd in de vorm van tekst naar een serieel getal\r\nTODAY\t\t\t= VANDAAG\t\t\t##\tGeeft als resultaat het seriële getal van de huidige datum\r\nWEEKDAY\t\t\t= WEEKDAG\t\t\t##\tConverteert een serieel getal naar een weekdag\r\nWEEKNUM\t\t\t= WEEKNUMMER\t\t\t##\tConverteert een serieel getal naar een weeknummer\r\nWORKDAY\t\t\t= WERKDAG\t\t\t##\tGeeft als resultaat het seriële getal van de datum voor of na een bepaald aantal werkdagen\r\nYEAR\t\t\t= JAAR\t\t\t\t##\tConverteert een serieel getal naar een jaar\r\nYEARFRAC\t\t= JAAR.DEEL\t\t\t##\tGeeft als resultaat het gedeelte van het jaar, uitgedrukt in het aantal hele dagen tussen begindatum en einddatum\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\tTechnische functies\r\n##\r\nBESSELI\t\t\t= BESSEL.Y\t\t\t##\tGeeft als resultaat de gewijzigde Bessel-functie In(x)\r\nBESSELJ\t\t\t= BESSEL.J\t\t\t##\tGeeft als resultaat de Bessel-functie Jn(x)\r\nBESSELK\t\t\t= BESSEL.K\t\t\t##\tGeeft als resultaat de gewijzigde Bessel-functie Kn(x)\r\nBESSELY\t\t\t= BESSEL.Y\t\t\t##\tGeeft als resultaat de gewijzigde Bessel-functie Yn(x)\r\nBIN2DEC\t\t\t= BIN.N.DEC\t\t\t##\tConverteert een binair getal naar een decimaal getal\r\nBIN2HEX\t\t\t= BIN.N.HEX\t\t\t##\tConverteert een binair getal naar een hexadecimaal getal\r\nBIN2OCT\t\t\t= BIN.N.OCT\t\t\t##\tConverteert een binair getal naar een octaal getal\r\nCOMPLEX\t\t\t= COMPLEX\t\t\t##\tConverteert reële en imaginaire coëfficiënten naar een complex getal\r\nCONVERT\t\t\t= CONVERTEREN\t\t\t##\tConverteert een getal in de ene maateenheid naar een getal in een andere maateenheid\r\nDEC2BIN\t\t\t= DEC.N.BIN\t\t\t##\tConverteert een decimaal getal naar een binair getal\r\nDEC2HEX\t\t\t= DEC.N.HEX\t\t\t##\tConverteert een decimaal getal naar een hexadecimaal getal\r\nDEC2OCT\t\t\t= DEC.N.OCT\t\t\t##\tConverteert een decimaal getal naar een octaal getal\r\nDELTA\t\t\t= DELTA\t\t\t\t##\tTest of twee waarden gelijk zijn\r\nERF\t\t\t= FOUTFUNCTIE\t\t\t##\tGeeft als resultaat de foutfunctie\r\nERFC\t\t\t= FOUT.COMPLEMENT\t\t##\tGeeft als resultaat de complementaire foutfunctie\r\nGESTEP\t\t\t= GROTER.DAN\t\t\t##\tTest of een getal groter is dan de drempelwaarde\r\nHEX2BIN\t\t\t= HEX.N.BIN\t\t\t##\tConverteert een hexadecimaal getal naar een binair getal\r\nHEX2DEC\t\t\t= HEX.N.DEC\t\t\t##\tConverteert een hexadecimaal getal naar een decimaal getal\r\nHEX2OCT\t\t\t= HEX.N.OCT\t\t\t##\tConverteert een hexadecimaal getal naar een octaal getal\r\nIMABS\t\t\t= C.ABS\t\t\t\t##\tGeeft als resultaat de absolute waarde (modulus) van een complex getal\r\nIMAGINARY\t\t= C.IM.DEEL\t\t\t##\tGeeft als resultaat de imaginaire coëfficiënt van een complex getal\r\nIMARGUMENT\t\t= C.ARGUMENT\t\t\t##\tGeeft als resultaat het argument thèta, een hoek uitgedrukt in radialen\r\nIMCONJUGATE\t\t= C.TOEGEVOEGD\t\t\t##\tGeeft als resultaat het complexe toegevoegde getal van een complex getal\r\nIMCOS\t\t\t= C.COS\t\t\t\t##\tGeeft als resultaat de cosinus van een complex getal\r\nIMDIV\t\t\t= C.QUOTIENT\t\t\t##\tGeeft als resultaat het quotiënt van twee complexe getallen\r\nIMEXP\t\t\t= C.EXP\t\t\t\t##\tGeeft als resultaat de exponent van een complex getal\r\nIMLN\t\t\t= C.LN\t\t\t\t##\tGeeft als resultaat de natuurlijke logaritme van een complex getal\r\nIMLOG10\t\t\t= C.LOG10\t\t\t##\tGeeft als resultaat de logaritme met grondtal 10 van een complex getal\r\nIMLOG2\t\t\t= C.LOG2\t\t\t##\tGeeft als resultaat de logaritme met grondtal 2 van een complex getal\r\nIMPOWER\t\t\t= C.MACHT\t\t\t##\tGeeft als resultaat een complex getal dat is verheven tot de macht van een geheel getal\r\nIMPRODUCT\t\t= C.PRODUCT\t\t\t##\tGeeft als resultaat het product van complexe getallen\r\nIMREAL\t\t\t= C.REEEL.DEEL\t\t\t##\tGeeft als resultaat de reële coëfficiënt van een complex getal\r\nIMSIN\t\t\t= C.SIN\t\t\t\t##\tGeeft als resultaat de sinus van een complex getal\r\nIMSQRT\t\t\t= C.WORTEL\t\t\t##\tGeeft als resultaat de vierkantswortel van een complex getal\r\nIMSUB\t\t\t= C.VERSCHIL\t\t\t##\tGeeft als resultaat het verschil tussen twee complexe getallen\r\nIMSUM\t\t\t= C.SOM\t\t\t\t##\tGeeft als resultaat de som van complexe getallen\r\nOCT2BIN\t\t\t= OCT.N.BIN\t\t\t##\tConverteert een octaal getal naar een binair getal\r\nOCT2DEC\t\t\t= OCT.N.DEC\t\t\t##\tConverteert een octaal getal naar een decimaal getal\r\nOCT2HEX\t\t\t= OCT.N.HEX\t\t\t##\tConverteert een octaal getal naar een hexadecimaal getal\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\tFinanciële functies\r\n##\r\nACCRINT\t\t\t= SAMENG.RENTE\t\t\t##\tBerekent de opgelopen rente voor een waardepapier waarvan de rente periodiek wordt uitgekeerd\r\nACCRINTM\t\t= SAMENG.RENTE.V\t\t##\tBerekent de opgelopen rente voor een waardepapier waarvan de rente op de vervaldatum wordt uitgekeerd\r\nAMORDEGRC\t\t= AMORDEGRC\t\t\t##\tGeeft als resultaat de afschrijving voor elke boekingsperiode door een afschrijvingscoëfficiënt toe te passen\r\nAMORLINC\t\t= AMORLINC\t\t\t##\tBerekent de afschrijving voor elke boekingsperiode\r\nCOUPDAYBS\t\t= COUP.DAGEN.BB\t\t\t##\tBerekent het aantal dagen vanaf het begin van de coupontermijn tot de stortingsdatum\r\nCOUPDAYS\t\t= COUP.DAGEN\t\t\t##\tGeeft als resultaat het aantal dagen in de coupontermijn waarin de stortingsdatum valt\r\nCOUPDAYSNC\t\t= COUP.DAGEN.VV\t\t\t##\tGeeft als resultaat het aantal dagen vanaf de stortingsdatum tot de volgende couponvervaldatum\r\nCOUPNCD\t\t\t= COUP.DATUM.NB\t\t\t##\tGeeft als resultaat de volgende coupondatum na de stortingsdatum\r\nCOUPNUM\t\t\t= COUP.AANTAL\t\t\t##\tGeeft als resultaat het aantal coupons dat nog moet worden uitbetaald tussen de stortingsdatum en de vervaldatum\r\nCOUPPCD\t\t\t= COUP.DATUM.VB\t\t\t##\tGeeft als resultaat de vorige couponvervaldatum vóór de stortingsdatum\r\nCUMIPMT\t\t\t= CUM.RENTE\t\t\t##\tGeeft als resultaat de cumulatieve rente die tussen twee termijnen is uitgekeerd\r\nCUMPRINC\t\t= CUM.HOOFDSOM\t\t\t##\tGeeft als resultaat de cumulatieve hoofdsom van een lening die tussen twee termijnen is terugbetaald\r\nDB\t\t\t= DB\t\t\t\t##\tGeeft als resultaat de afschrijving van activa voor een bepaalde periode met behulp van de 'fixed declining balance'-methode\r\nDDB\t\t\t= DDB\t\t\t\t##\tGeeft als resultaat de afschrijving van activa over een bepaalde termijn met behulp van de 'double declining balance'-methode of een andere methode die u opgeeft\r\nDISC\t\t\t= DISCONTO\t\t\t##\tGeeft als resultaat het discontopercentage voor een waardepapier\r\nDOLLARDE\t\t= EURO.DE\t\t\t##\tConverteert een prijs in euro's, uitgedrukt in een breuk, naar een prijs in euro's, uitgedrukt in een decimaal getal\r\nDOLLARFR\t\t= EURO.BR\t\t\t##\tConverteert een prijs in euro's, uitgedrukt in een decimaal getal, naar een prijs in euro's, uitgedrukt in een breuk\r\nDURATION\t\t= DUUR\t\t\t\t##\tGeeft als resultaat de gewogen gemiddelde looptijd voor een waardepapier met periodieke rentebetalingen\r\nEFFECT\t\t\t= EFFECT.RENTE\t\t\t##\tGeeft als resultaat het effectieve jaarlijkse rentepercentage\r\nFV\t\t\t= TW\t\t\t\t##\tGeeft als resultaat de toekomstige waarde van een investering\r\nFVSCHEDULE\t\t= TOEK.WAARDE2\t\t\t##\tGeeft als resultaat de toekomstige waarde van een bepaalde hoofdsom na het toepassen van een reeks samengestelde rentepercentages\r\nINTRATE\t\t\t= RENTEPERCENTAGE\t\t##\tGeeft als resultaat het rentepercentage voor een volgestort waardepapier\r\nIPMT\t\t\t= IBET\t\t\t\t##\tGeeft als resultaat de te betalen rente voor een investering over een bepaalde termijn\r\nIRR\t\t\t= IR\t\t\t\t##\tGeeft als resultaat de interne rentabiliteit voor een reeks cashflows\r\nISPMT\t\t\t= ISBET\t\t\t\t##\tGeeft als resultaat de rente die is betaald tijdens een bepaalde termijn van een investering\r\nMDURATION\t\t= AANG.DUUR\t\t\t##\tGeeft als resultaat de aangepaste Macauley-looptijd voor een waardepapier, aangenomen dat de nominale waarde € 100 bedraagt\r\nMIRR\t\t\t= GIR\t\t\t\t##\tGeeft als resultaat de interne rentabiliteit voor een serie cashflows, waarbij voor betalingen een ander rentepercentage geldt dan voor inkomsten\r\nNOMINAL\t\t\t= NOMINALE.RENTE\t\t##\tGeeft als resultaat het nominale jaarlijkse rentepercentage\r\nNPER\t\t\t= NPER\t\t\t\t##\tGeeft als resultaat het aantal termijnen van een investering\r\nNPV\t\t\t= NHW\t\t\t\t##\tGeeft als resultaat de netto huidige waarde van een investering op basis van een reeks periodieke cashflows en een discontopercentage\r\nODDFPRICE\t\t= AFW.ET.PRIJS\t\t\t##\tGeeft als resultaat de prijs per € 100 nominale waarde voor een waardepapier met een afwijkende eerste termijn\r\nODDFYIELD\t\t= AFW.ET.REND\t\t\t##\tGeeft als resultaat het rendement voor een waardepapier met een afwijkende eerste termijn\r\nODDLPRICE\t\t= AFW.LT.PRIJS\t\t\t##\tGeeft als resultaat de prijs per € 100 nominale waarde voor een waardepapier met een afwijkende laatste termijn\r\nODDLYIELD\t\t= AFW.LT.REND\t\t\t##\tGeeft als resultaat het rendement voor een waardepapier met een afwijkende laatste termijn\r\nPMT\t\t\t= BET\t\t\t\t##\tGeeft als resultaat de periodieke betaling voor een annuïteit\r\nPPMT\t\t\t= PBET\t\t\t\t##\tGeeft als resultaat de afbetaling op de hoofdsom voor een bepaalde termijn\r\nPRICE\t\t\t= PRIJS.NOM\t\t\t##\tGeeft als resultaat de prijs per € 100 nominale waarde voor een waardepapier waarvan de rente periodiek wordt uitgekeerd\r\nPRICEDISC\t\t= PRIJS.DISCONTO\t\t##\tGeeft als resultaat de prijs per € 100 nominale waarde voor een verdisconteerd waardepapier\r\nPRICEMAT\t\t= PRIJS.VERVALDAG\t\t##\tGeeft als resultaat de prijs per € 100 nominale waarde voor een waardepapier waarvan de rente wordt uitgekeerd op de vervaldatum\r\nPV\t\t\t= HW\t\t\t\t##\tGeeft als resultaat de huidige waarde van een investering\r\nRATE\t\t\t= RENTE\t\t\t\t##\tGeeft als resultaat het periodieke rentepercentage voor een annuïteit\r\nRECEIVED\t\t= OPBRENGST\t\t\t##\tGeeft als resultaat het bedrag dat op de vervaldatum wordt uitgekeerd voor een volgestort waardepapier\r\nSLN\t\t\t= LIN.AFSCHR\t\t\t##\tGeeft als resultaat de lineaire afschrijving van activa over één termijn\r\nSYD\t\t\t= SYD\t\t\t\t##\tGeeft als resultaat de afschrijving van activa over een bepaalde termijn met behulp van de 'Sum-Of-Years-Digits'-methode\r\nTBILLEQ\t\t\t= SCHATK.OBL\t\t\t##\tGeeft als resultaat het rendement op schatkistpapier, dat op dezelfde manier wordt berekend als het rendement op obligaties\r\nTBILLPRICE\t\t= SCHATK.PRIJS\t\t\t##\tBepaalt de prijs per € 100 nominale waarde voor schatkistpapier\r\nTBILLYIELD\t\t= SCHATK.REND\t\t\t##\tBerekent het rendement voor schatkistpapier\r\nVDB\t\t\t= VDB\t\t\t\t##\tGeeft als resultaat de afschrijving van activa over een gehele of gedeeltelijke termijn met behulp van de 'declining balance'-methode\r\nXIRR\t\t\t= IR.SCHEMA\t\t\t##\tBerekent de interne rentabiliteit voor een betalingsschema van cashflows\r\nXNPV\t\t\t= NHW2\t\t\t\t##\tBerekent de huidige nettowaarde voor een betalingsschema van cashflows\r\nYIELD\t\t\t= RENDEMENT\t\t\t##\tGeeft als resultaat het rendement voor een waardepapier waarvan de rente periodiek wordt uitgekeerd\r\nYIELDDISC\t\t= REND.DISCONTO\t\t\t##\tGeeft als resultaat het jaarlijkse rendement voor een verdisconteerd waardepapier, bijvoorbeeld schatkistpapier\r\nYIELDMAT\t\t= REND.VERVAL\t\t\t##\tGeeft als resultaat het jaarlijkse rendement voor een waardepapier waarvan de rente wordt uitgekeerd op de vervaldatum\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\tInformatiefuncties\r\n##\r\nCELL\t\t\t= CEL\t\t\t\t##\tGeeft als resultaat informatie over de opmaak, locatie of inhoud van een cel\r\nERROR.TYPE\t\t= TYPE.FOUT\t\t\t##\tGeeft als resultaat een getal dat overeenkomt met een van de foutwaarden van Microsoft Excel\r\nINFO\t\t\t= INFO\t\t\t\t##\tGeeft als resultaat informatie over de huidige besturingsomgeving\r\nISBLANK\t\t\t= ISLEEG\t\t\t##\tGeeft als resultaat WAAR als de waarde leeg is\r\nISERR\t\t\t= ISFOUT2\t\t\t##\tGeeft als resultaat WAAR als de waarde een foutwaarde is, met uitzondering van #N/B\r\nISERROR\t\t\t= ISFOUT\t\t\t##\tGeeft als resultaat WAAR als de waarde een foutwaarde is\r\nISEVEN\t\t\t= IS.EVEN\t\t\t##\tGeeft als resultaat WAAR als het getal even is\r\nISLOGICAL\t\t= ISLOGISCH\t\t\t##\tGeeft als resultaat WAAR als de waarde een logische waarde is\r\nISNA\t\t\t= ISNB\t\t\t\t##\tGeeft als resultaat WAAR als de waarde de foutwaarde #N/B is\r\nISNONTEXT\t\t= ISGEENTEKST\t\t\t##\tGeeft als resultaat WAAR als de waarde geen tekst is\r\nISNUMBER\t\t= ISGETAL\t\t\t##\tGeeft als resultaat WAAR als de waarde een getal is\r\nISODD\t\t\t= IS.ONEVEN\t\t\t##\tGeeft als resultaat WAAR als het getal oneven is\r\nISREF\t\t\t= ISVERWIJZING\t\t\t##\tGeeft als resultaat WAAR als de waarde een verwijzing is\r\nISTEXT\t\t\t= ISTEKST\t\t\t##\tGeeft als resultaat WAAR als de waarde tekst is\r\nN\t\t\t= N\t\t\t\t##\tGeeft als resultaat een waarde die is geconverteerd naar een getal\r\nNA\t\t\t= NB\t\t\t\t##\tGeeft als resultaat de foutwaarde #N/B\r\nTYPE\t\t\t= TYPE\t\t\t\t##\tGeeft als resultaat een getal dat het gegevenstype van een waarde aangeeft\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\tLogische functies\r\n##\r\nAND\t\t\t= EN\t\t\t\t##\tGeeft als resultaat WAAR als alle argumenten WAAR zijn\r\nFALSE\t\t\t= ONWAAR\t\t\t##\tGeeft als resultaat de logische waarde ONWAAR\r\nIF\t\t\t= ALS\t\t\t\t##\tGeeft een logische test aan\r\nIFERROR\t\t\t= ALS.FOUT\t\t\t##\tRetourneert een waarde die u opgeeft als een formule een fout oplevert, anders wordt het resultaat van de formule geretourneerd\r\nNOT\t\t\t= NIET\t\t\t\t##\tKeert de logische waarde van het argument om\r\nOR\t\t\t= OF\t\t\t\t##\tGeeft als resultaat WAAR als minimaal een van de argumenten WAAR is\r\nTRUE\t\t\t= WAAR\t\t\t\t##\tGeeft als resultaat de logische waarde WAAR\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\tZoek- en verwijzingsfuncties\r\n##\r\nADDRESS\t\t\t= ADRES\t\t\t\t##\tGeeft als resultaat een verwijzing, in de vorm van tekst, naar één bepaalde cel in een werkblad\r\nAREAS\t\t\t= BEREIKEN\t\t\t##\tGeeft als resultaat het aantal bereiken in een verwijzing\r\nCHOOSE\t\t\t= KIEZEN\t\t\t##\tKiest een waarde uit een lijst met waarden\r\nCOLUMN\t\t\t= KOLOM\t\t\t\t##\tGeeft als resultaat het kolomnummer van een verwijzing\r\nCOLUMNS\t\t\t= KOLOMMEN\t\t\t##\tGeeft als resultaat het aantal kolommen in een verwijzing\r\nHLOOKUP\t\t\t= HORIZ.ZOEKEN\t\t\t##\tZoekt in de bovenste rij van een matrix naar een bepaalde waarde en geeft als resultaat de gevonden waarde in de opgegeven cel\r\nHYPERLINK\t\t= HYPERLINK\t\t\t##\tMaakt een snelkoppeling of een sprong waarmee een document wordt geopend dat is opgeslagen op een netwerkserver, een intranet of op internet\r\nINDEX\t\t\t= INDEX\t\t\t\t##\tKiest met een index een waarde uit een verwijzing of een matrix\r\nINDIRECT\t\t= INDIRECT\t\t\t##\tGeeft als resultaat een verwijzing die wordt aangegeven met een tekstwaarde\r\nLOOKUP\t\t\t= ZOEKEN\t\t\t##\tZoekt naar bepaalde waarden in een vector of een matrix\r\nMATCH\t\t\t= VERGELIJKEN\t\t\t##\tZoekt naar bepaalde waarden in een verwijzing of een matrix\r\nOFFSET\t\t\t= VERSCHUIVING\t\t\t##\tGeeft als resultaat een nieuwe verwijzing die is verschoven ten opzichte van een bepaalde verwijzing\r\nROW\t\t\t= RIJ\t\t\t\t##\tGeeft als resultaat het rijnummer van een verwijzing\r\nROWS\t\t\t= RIJEN\t\t\t\t##\tGeeft als resultaat het aantal rijen in een verwijzing\r\nRTD\t\t\t= RTG\t\t\t\t##\tHaalt realtimegegevens op uit een programma dat COM-automatisering (automatisering: een methode waarmee de ene toepassing objecten van een andere toepassing of ontwikkelprogramma kan besturen. Automatisering werd vroeger OLE-automatisering genoemd. Automatisering is een industrienorm die deel uitmaakt van het Component Object Model (COM).) ondersteunt\r\nTRANSPOSE\t\t= TRANSPONEREN\t\t\t##\tGeeft als resultaat de getransponeerde van een matrix\r\nVLOOKUP\t\t\t= VERT.ZOEKEN\t\t\t##\tZoekt in de meest linkse kolom van een matrix naar een bepaalde waarde en geeft als resultaat de waarde in de opgegeven cel\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\tWiskundige en trigonometrische functies\r\n##\r\nABS\t\t\t= ABS\t\t\t\t##\tGeeft als resultaat de absolute waarde van een getal\r\nACOS\t\t\t= BOOGCOS\t\t\t##\tGeeft als resultaat de boogcosinus van een getal\r\nACOSH\t\t\t= BOOGCOSH\t\t\t##\tGeeft als resultaat de inverse cosinus hyperbolicus van een getal\r\nASIN\t\t\t= BOOGSIN\t\t\t##\tGeeft als resultaat de boogsinus van een getal\r\nASINH\t\t\t= BOOGSINH\t\t\t##\tGeeft als resultaat de inverse sinus hyperbolicus van een getal\r\nATAN\t\t\t= BOOGTAN\t\t\t##\tGeeft als resultaat de boogtangens van een getal\r\nATAN2\t\t\t= BOOGTAN2\t\t\t##\tGeeft als resultaat de boogtangens van de x- en y-coördinaten\r\nATANH\t\t\t= BOOGTANH\t\t\t##\tGeeft als resultaat de inverse tangens hyperbolicus van een getal\r\nCEILING\t\t\t= AFRONDEN.BOVEN\t\t##\tRondt de absolute waarde van een getal naar boven af op het dichtstbijzijnde gehele getal of het dichtstbijzijnde significante veelvoud\r\nCOMBIN\t\t\t= COMBINATIES\t\t\t##\tGeeft als resultaat het aantal combinaties voor een bepaald aantal objecten\r\nCOS\t\t\t= COS\t\t\t\t##\tGeeft als resultaat de cosinus van een getal\r\nCOSH\t\t\t= COSH\t\t\t\t##\tGeeft als resultaat de cosinus hyperbolicus van een getal\r\nDEGREES\t\t\t= GRADEN\t\t\t##\tConverteert radialen naar graden\r\nEVEN\t\t\t= EVEN\t\t\t\t##\tRondt het getal af op het dichtstbijzijnde gehele even getal\r\nEXP\t\t\t= EXP\t\t\t\t##\tVerheft e tot de macht van een bepaald getal\r\nFACT\t\t\t= FACULTEIT\t\t\t##\tGeeft als resultaat de faculteit van een getal\r\nFACTDOUBLE\t\t= DUBBELE.FACULTEIT\t\t##\tGeeft als resultaat de dubbele faculteit van een getal\r\nFLOOR\t\t\t= AFRONDEN.BENEDEN\t\t##\tRondt de absolute waarde van een getal naar beneden af\r\nGCD\t\t\t= GGD\t\t\t\t##\tGeeft als resultaat de grootste gemene deler\r\nINT\t\t\t= INTEGER\t\t\t##\tRondt een getal naar beneden af op het dichtstbijzijnde gehele getal\r\nLCM\t\t\t= KGV\t\t\t\t##\tGeeft als resultaat het kleinste gemene veelvoud\r\nLN\t\t\t= LN\t\t\t\t##\tGeeft als resultaat de natuurlijke logaritme van een getal\r\nLOG\t\t\t= LOG\t\t\t\t##\tGeeft als resultaat de logaritme met het opgegeven grondtal van een getal\r\nLOG10\t\t\t= LOG10\t\t\t\t##\tGeeft als resultaat de logaritme met grondtal 10 van een getal\r\nMDETERM\t\t\t= DETERMINANTMAT\t\t##\tGeeft als resultaat de determinant van een matrix\r\nMINVERSE\t\t= INVERSEMAT\t\t\t##\tGeeft als resultaat de inverse van een matrix\r\nMMULT\t\t\t= PRODUCTMAT\t\t\t##\tGeeft als resultaat het product van twee matrices\r\nMOD\t\t\t= REST\t\t\t\t##\tGeeft als resultaat het restgetal van een deling\r\nMROUND\t\t\t= AFRONDEN.N.VEELVOUD\t\t##\tGeeft als resultaat een getal afgerond op het gewenste veelvoud\r\nMULTINOMIAL\t\t= MULTINOMIAAL\t\t\t##\tGeeft als resultaat de multinomiaalcoëfficiënt van een reeks getallen\r\nODD\t\t\t= ONEVEN\t\t\t##\tRondt de absolute waarde van het getal naar boven af op het dichtstbijzijnde gehele oneven getal\r\nPI\t\t\t= PI\t\t\t\t##\tGeeft als resultaat de waarde van pi\r\nPOWER\t\t\t= MACHT\t\t\t\t##\tVerheft een getal tot een macht\r\nPRODUCT\t\t\t= PRODUCT\t\t\t##\tVermenigvuldigt de argumenten met elkaar\r\nQUOTIENT\t\t= QUOTIENT\t\t\t##\tGeeft als resultaat de uitkomst van een deling als geheel getal\r\nRADIANS\t\t\t= RADIALEN\t\t\t##\tConverteert graden naar radialen\r\nRAND\t\t\t= ASELECT\t\t\t##\tGeeft als resultaat een willekeurig getal tussen 0 en 1\r\nRANDBETWEEN\t\t= ASELECTTUSSEN\t\t\t##\tGeeft een willekeurig getal tussen de getallen die u hebt opgegeven\r\nROMAN\t\t\t= ROMEINS\t\t\t##\tConverteert een Arabisch getal naar een Romeins getal en geeft het resultaat weer in de vorm van tekst\r\nROUND\t\t\t= AFRONDEN\t\t\t##\tRondt een getal af op het opgegeven aantal decimalen\r\nROUNDDOWN\t\t= AFRONDEN.NAAR.BENEDEN\t\t##\tRondt de absolute waarde van een getal naar beneden af\r\nROUNDUP\t\t\t= AFRONDEN.NAAR.BOVEN\t\t##\tRondt de absolute waarde van een getal naar boven af\r\nSERIESSUM\t\t= SOM.MACHTREEKS\t\t##\tGeeft als resultaat de som van een machtreeks die is gebaseerd op de formule\r\nSIGN\t\t\t= POS.NEG\t\t\t##\tGeeft als resultaat het teken van een getal\r\nSIN\t\t\t= SIN\t\t\t\t##\tGeeft als resultaat de sinus van de opgegeven hoek\r\nSINH\t\t\t= SINH\t\t\t\t##\tGeeft als resultaat de sinus hyperbolicus van een getal\r\nSQRT\t\t\t= WORTEL\t\t\t##\tGeeft als resultaat de positieve vierkantswortel van een getal\r\nSQRTPI\t\t\t= WORTEL.PI\t\t\t##\tGeeft als resultaat de vierkantswortel van (getal * pi)\r\nSUBTOTAL\t\t= SUBTOTAAL\t\t\t##\tGeeft als resultaat een subtotaal voor een bereik\r\nSUM\t\t\t= SOM\t\t\t\t##\tTelt de argumenten op\r\nSUMIF\t\t\t= SOM.ALS\t\t\t##\tTelt de getallen bij elkaar op die voldoen aan een bepaald criterium\r\nSUMIFS\t\t\t= SOMMEN.ALS\t\t\t##\tTelt de cellen in een bereik op die aan meerdere criteria voldoen\r\nSUMPRODUCT\t\t= SOMPRODUCT\t\t\t##\tGeeft als resultaat de som van de producten van de corresponderende matrixelementen\r\nSUMSQ\t\t\t= KWADRATENSOM\t\t\t##\tGeeft als resultaat de som van de kwadraten van de argumenten\r\nSUMX2MY2\t\t= SOM.X2MINY2\t\t\t##\tGeeft als resultaat de som van het verschil tussen de kwadraten van corresponderende waarden in twee matrices\r\nSUMX2PY2\t\t= SOM.X2PLUSY2\t\t\t##\tGeeft als resultaat de som van de kwadratensom van corresponderende waarden in twee matrices\r\nSUMXMY2\t\t\t= SOM.XMINY.2\t\t\t##\tGeeft als resultaat de som van de kwadraten van de verschillen tussen de corresponderende waarden in twee matrices\r\nTAN\t\t\t= TAN\t\t\t\t##\tGeeft als resultaat de tangens van een getal\r\nTANH\t\t\t= TANH\t\t\t\t##\tGeeft als resultaat de tangens hyperbolicus van een getal\r\nTRUNC\t\t\t= GEHEEL\t\t\t##\tKapt een getal af tot een geheel getal\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\tStatistische functies\r\n##\r\nAVEDEV\t\t\t= GEM.DEVIATIE\t\t\t##\tGeeft als resultaat het gemiddelde van de absolute deviaties van gegevenspunten ten opzichte van hun gemiddelde waarde\r\nAVERAGE\t\t\t= GEMIDDELDE\t\t\t##\tGeeft als resultaat het gemiddelde van de argumenten\r\nAVERAGEA\t\t= GEMIDDELDEA\t\t\t##\tGeeft als resultaat het gemiddelde van de argumenten, inclusief getallen, tekst en logische waarden\r\nAVERAGEIF\t\t= GEMIDDELDE.ALS\t\t##\tGeeft het gemiddelde (rekenkundig gemiddelde) als resultaat van alle cellen in een bereik die voldoen aan de opgegeven criteria\r\nAVERAGEIFS\t\t= GEMIDDELDEN.ALS\t\t##\tGeeft het gemiddelde (rekenkundig gemiddelde) als resultaat van alle cellen die aan meerdere criteria voldoen\r\nBETADIST\t\t= BETA.VERD\t\t\t##\tGeeft als resultaat de cumulatieve bèta-verdelingsfunctie\r\nBETAINV\t\t\t= BETA.INV\t\t\t##\tGeeft als resultaat de inverse van de cumulatieve verdelingsfunctie voor een gegeven bèta-verdeling\r\nBINOMDIST\t\t= BINOMIALE.VERD\t\t##\tGeeft als resultaat de binomiale verdeling\r\nCHIDIST\t\t\t= CHI.KWADRAAT\t\t\t##\tGeeft als resultaat de eenzijdige kans van de chi-kwadraatverdeling\r\nCHIINV\t\t\t= CHI.KWADRAAT.INV\t\t##\tGeeft als resultaat de inverse van een eenzijdige kans van de chi-kwadraatverdeling\r\nCHITEST\t\t\t= CHI.TOETS\t\t\t##\tGeeft als resultaat de onafhankelijkheidstoets\r\nCONFIDENCE\t\t= BETROUWBAARHEID\t\t##\tGeeft als resultaat het betrouwbaarheidsinterval van een gemiddelde waarde voor de elementen van een populatie\r\nCORREL\t\t\t= CORRELATIE\t\t\t##\tGeeft als resultaat de correlatiecoëfficiënt van twee gegevensverzamelingen\r\nCOUNT\t\t\t= AANTAL\t\t\t##\tTelt het aantal getallen in de argumentenlijst\r\nCOUNTA\t\t\t= AANTALARG\t\t\t##\tTelt het aantal waarden in de argumentenlijst\r\nCOUNTBLANK\t\t= AANTAL.LEGE.CELLEN\t\t##\tTelt het aantal lege cellen in een bereik\r\nCOUNTIF\t\t\t= AANTAL.ALS\t\t\t##\tTelt in een bereik het aantal cellen die voldoen aan een bepaald criterium\r\nCOUNTIFS\t\t= AANTALLEN.ALS\t\t\t##\tTelt in een bereik het aantal cellen die voldoen aan meerdere criteria\r\nCOVAR\t\t\t= COVARIANTIE\t\t\t##\tGeeft als resultaat de covariantie, het gemiddelde van de producten van de gepaarde deviaties\r\nCRITBINOM\t\t= CRIT.BINOM\t\t\t##\tGeeft als resultaat de kleinste waarde waarvoor de binomiale verdeling kleiner is dan of gelijk is aan het criterium\r\nDEVSQ\t\t\t= DEV.KWAD\t\t\t##\tGeeft als resultaat de som van de deviaties in het kwadraat\r\nEXPONDIST\t\t= EXPON.VERD\t\t\t##\tGeeft als resultaat de exponentiële verdeling\r\nFDIST\t\t\t= F.VERDELING\t\t\t##\tGeeft als resultaat de F-verdeling\r\nFINV\t\t\t= F.INVERSE\t\t\t##\tGeeft als resultaat de inverse van de F-verdeling\r\nFISHER\t\t\t= FISHER\t\t\t##\tGeeft als resultaat de Fisher-transformatie\r\nFISHERINV\t\t= FISHER.INV\t\t\t##\tGeeft als resultaat de inverse van de Fisher-transformatie\r\nFORECAST\t\t= VOORSPELLEN\t\t\t##\tGeeft als resultaat een waarde op basis van een lineaire trend\r\nFREQUENCY\t\t= FREQUENTIE\t\t\t##\tGeeft als resultaat een frequentieverdeling in de vorm van een verticale matrix\r\nFTEST\t\t\t= F.TOETS\t\t\t##\tGeeft als resultaat een F-toets\r\nGAMMADIST\t\t= GAMMA.VERD\t\t\t##\tGeeft als resultaat de gamma-verdeling\r\nGAMMAINV\t\t= GAMMA.INV\t\t\t##\tGeeft als resultaat de inverse van de cumulatieve gamma-verdeling\r\nGAMMALN\t\t\t= GAMMA.LN\t\t\t##\tGeeft als resultaat de natuurlijke logaritme van de gamma-functie, G(x)\r\nGEOMEAN\t\t\t= MEETK.GEM\t\t\t##\tGeeft als resultaat het meetkundige gemiddelde\r\nGROWTH\t\t\t= GROEI\t\t\t\t##\tGeeft als resultaat de waarden voor een exponentiële trend\r\nHARMEAN\t\t\t= HARM.GEM\t\t\t##\tGeeft als resultaat het harmonische gemiddelde\r\nHYPGEOMDIST\t\t= HYPERGEO.VERD\t\t\t##\tGeeft als resultaat de hypergeometrische verdeling\r\nINTERCEPT\t\t= SNIJPUNT\t\t\t##\tGeeft als resultaat het snijpunt van de lineaire regressielijn met de y-as\r\nKURT\t\t\t= KURTOSIS\t\t\t##\tGeeft als resultaat de kurtosis van een gegevensverzameling\r\nLARGE\t\t\t= GROOTSTE\t\t\t##\tGeeft als resultaat de op k-1 na grootste waarde in een gegevensverzameling\r\nLINEST\t\t\t= LIJNSCH\t\t\t##\tGeeft als resultaat de parameters van een lineaire trend\r\nLOGEST\t\t\t= LOGSCH\t\t\t##\tGeeft als resultaat de parameters van een exponentiële trend\r\nLOGINV\t\t\t= LOG.NORM.INV\t\t\t##\tGeeft als resultaat de inverse van de logaritmische normale verdeling\r\nLOGNORMDIST\t\t= LOG.NORM.VERD\t\t\t##\tGeeft als resultaat de cumulatieve logaritmische normale verdeling\r\nMAX\t\t\t= MAX\t\t\t\t##\tGeeft als resultaat de maximumwaarde in een lijst met argumenten\r\nMAXA\t\t\t= MAXA\t\t\t\t##\tGeeft als resultaat de maximumwaarde in een lijst met argumenten, inclusief getallen, tekst en logische waarden\r\nMEDIAN\t\t\t= MEDIAAN\t\t\t##\tGeeft als resultaat de mediaan van de opgegeven getallen\r\nMIN\t\t\t= MIN\t\t\t\t##\tGeeft als resultaat de minimumwaarde in een lijst met argumenten\r\nMINA\t\t\t= MINA\t\t\t\t##\tGeeft als resultaat de minimumwaarde in een lijst met argumenten, inclusief getallen, tekst en logische waarden\r\nMODE\t\t\t= MODUS\t\t\t\t##\tGeeft als resultaat de meest voorkomende waarde in een gegevensverzameling\r\nNEGBINOMDIST\t\t= NEG.BINOM.VERD\t\t##\tGeeft als resultaat de negatieve binomiaalverdeling\r\nNORMDIST\t\t= NORM.VERD\t\t\t##\tGeeft als resultaat de cumulatieve normale verdeling\r\nNORMINV\t\t\t= NORM.INV\t\t\t##\tGeeft als resultaat de inverse van de cumulatieve standaardnormale verdeling\r\nNORMSDIST\t\t= STAND.NORM.VERD\t\t##\tGeeft als resultaat de cumulatieve standaardnormale verdeling\r\nNORMSINV\t\t= STAND.NORM.INV\t\t##\tGeeft als resultaat de inverse van de cumulatieve normale verdeling\r\nPEARSON\t\t\t= PEARSON\t\t\t##\tGeeft als resultaat de correlatiecoëfficiënt van Pearson\r\nPERCENTILE\t\t= PERCENTIEL\t\t\t##\tGeeft als resultaat het k-de percentiel van waarden in een bereik\r\nPERCENTRANK\t\t= PERCENT.RANG\t\t\t##\tGeeft als resultaat de positie, in procenten uitgedrukt, van een waarde in de rangorde van een gegevensverzameling\r\nPERMUT\t\t\t= PERMUTATIES\t\t\t##\tGeeft als resultaat het aantal permutaties voor een gegeven aantal objecten\r\nPOISSON\t\t\t= POISSON\t\t\t##\tGeeft als resultaat de Poisson-verdeling\r\nPROB\t\t\t= KANS\t\t\t\t##\tGeeft als resultaat de kans dat waarden zich tussen twee grenzen bevinden\r\nQUARTILE\t\t= KWARTIEL\t\t\t##\tGeeft als resultaat het kwartiel van een gegevensverzameling\r\nRANK\t\t\t= RANG\t\t\t\t##\tGeeft als resultaat het rangnummer van een getal in een lijst getallen\r\nRSQ\t\t\t= R.KWADRAAT\t\t\t##\tGeeft als resultaat het kwadraat van de Pearson-correlatiecoëfficiënt\r\nSKEW\t\t\t= SCHEEFHEID\t\t\t##\tGeeft als resultaat de mate van asymmetrie van een verdeling\r\nSLOPE\t\t\t= RICHTING\t\t\t##\tGeeft als resultaat de richtingscoëfficiënt van een lineaire regressielijn\r\nSMALL\t\t\t= KLEINSTE\t\t\t##\tGeeft als resultaat de op k-1 na kleinste waarde in een gegevensverzameling\r\nSTANDARDIZE\t\t= NORMALISEREN\t\t\t##\tGeeft als resultaat een genormaliseerde waarde\r\nSTDEV\t\t\t= STDEV\t\t\t\t##\tMaakt een schatting van de standaarddeviatie op basis van een steekproef\r\nSTDEVA\t\t\t= STDEVA\t\t\t##\tMaakt een schatting van de standaarddeviatie op basis van een steekproef, inclusief getallen, tekst en logische waarden\r\nSTDEVP\t\t\t= STDEVP\t\t\t##\tBerekent de standaarddeviatie op basis van de volledige populatie\r\nSTDEVPA\t\t\t= STDEVPA\t\t\t##\tBerekent de standaarddeviatie op basis van de volledige populatie, inclusief getallen, tekst en logische waarden\r\nSTEYX\t\t\t= STAND.FOUT.YX\t\t\t##\tGeeft als resultaat de standaardfout in de voorspelde y-waarde voor elke x in een regressie\r\nTDIST\t\t\t= T.VERD\t\t\t##\tGeeft als resultaat de Student T-verdeling\r\nTINV\t\t\t= T.INV\t\t\t\t##\tGeeft als resultaat de inverse van de Student T-verdeling\r\nTREND\t\t\t= TREND\t\t\t\t##\tGeeft als resultaat de waarden voor een lineaire trend\r\nTRIMMEAN\t\t= GETRIMD.GEM\t\t\t##\tGeeft als resultaat het gemiddelde van waarden in een gegevensverzameling\r\nTTEST\t\t\t= T.TOETS\t\t\t##\tGeeft als resultaat de kans met behulp van de Student T-toets\r\nVAR\t\t\t= VAR\t\t\t\t##\tMaakt een schatting van de variantie op basis van een steekproef\r\nVARA\t\t\t= VARA\t\t\t\t##\tMaakt een schatting van de variantie op basis van een steekproef, inclusief getallen, tekst en logische waarden\r\nVARP\t\t\t= VARP\t\t\t\t##\tBerekent de variantie op basis van de volledige populatie\r\nVARPA\t\t\t= VARPA\t\t\t\t##\tBerekent de standaarddeviatie op basis van de volledige populatie, inclusief getallen, tekst en logische waarden\r\nWEIBULL\t\t\t= WEIBULL\t\t\t##\tGeeft als resultaat de Weibull-verdeling\r\nZTEST\t\t\t= Z.TOETS\t\t\t##\tGeeft als resultaat de eenzijdige kanswaarde van een Z-toets\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\tTekstfuncties\r\n##\r\nASC\t\t\t= ASC\t\t\t\t##\tWijzigt Nederlandse letters of katakanatekens over de volle breedte (dubbel-bytetekens) binnen een tekenreeks in tekens over de halve breedte (enkel-bytetekens)\r\nBAHTTEXT\t\t= BAHT.TEKST\t\t\t##\tConverteert een getal naar tekst met de valutanotatie ß (baht)\r\nCHAR\t\t\t= TEKEN\t\t\t\t##\tGeeft als resultaat het teken dat hoort bij de opgegeven code\r\nCLEAN\t\t\t= WISSEN.CONTROL\t\t##\tVerwijdert alle niet-afdrukbare tekens uit een tekst\r\nCODE\t\t\t= CODE\t\t\t\t##\tGeeft als resultaat de numerieke code voor het eerste teken in een tekenreeks\r\nCONCATENATE\t\t= TEKST.SAMENVOEGEN\t\t##\tVoegt verschillende tekstfragmenten samen tot één tekstfragment\r\nDOLLAR\t\t\t= EURO\t\t\t\t##\tConverteert een getal naar tekst met de valutanotatie € (euro)\r\nEXACT\t\t\t= GELIJK\t\t\t##\tControleert of twee tekenreeksen identiek zijn\r\nFIND\t\t\t= VIND.ALLES\t\t\t##\tZoekt een bepaalde tekenreeks in een tekst (waarbij onderscheid wordt gemaakt tussen hoofdletters en kleine letters)\r\nFINDB\t\t\t= VIND.ALLES.B\t\t\t##\tZoekt een bepaalde tekenreeks in een tekst (waarbij onderscheid wordt gemaakt tussen hoofdletters en kleine letters)\r\nFIXED\t\t\t= VAST\t\t\t\t##\tMaakt een getal als tekst met een vast aantal decimalen op\r\nJIS\t\t\t= JIS\t\t\t\t##\tWijzigt Nederlandse letters of katakanatekens over de halve breedte (enkel-bytetekens) binnen een tekenreeks in tekens over de volle breedte (dubbel-bytetekens)\r\nLEFT\t\t\t= LINKS\t\t\t\t##\tGeeft als resultaat de meest linkse tekens in een tekenreeks\r\nLEFTB\t\t\t= LINKSB\t\t\t##\tGeeft als resultaat de meest linkse tekens in een tekenreeks\r\nLEN\t\t\t= LENGTE\t\t\t##\tGeeft als resultaat het aantal tekens in een tekenreeks\r\nLENB\t\t\t= LENGTEB\t\t\t##\tGeeft als resultaat het aantal tekens in een tekenreeks\r\nLOWER\t\t\t= KLEINE.LETTERS\t\t##\tZet tekst om in kleine letters\r\nMID\t\t\t= MIDDEN\t\t\t##\tGeeft als resultaat een bepaald aantal tekens van een tekenreeks vanaf de positie die u opgeeft\r\nMIDB\t\t\t= DEELB\t\t\t\t##\tGeeft als resultaat een bepaald aantal tekens van een tekenreeks vanaf de positie die u opgeeft\r\nPHONETIC\t\t= FONETISCH\t\t\t##\tHaalt de fonetische tekens (furigana) uit een tekenreeks op\r\nPROPER\t\t\t= BEGINLETTERS\t\t\t##\tZet de eerste letter van elk woord in een tekst om in een hoofdletter\r\nREPLACE\t\t\t= VERVANG\t\t\t##\tVervangt tekens binnen een tekst\r\nREPLACEB\t\t= VERVANGENB\t\t\t##\tVervangt tekens binnen een tekst\r\nREPT\t\t\t= HERHALING\t\t\t##\tHerhaalt een tekst een aantal malen\r\nRIGHT\t\t\t= RECHTS\t\t\t##\tGeeft als resultaat de meest rechtse tekens in een tekenreeks\r\nRIGHTB\t\t\t= RECHTSB\t\t\t##\tGeeft als resultaat de meest rechtse tekens in een tekenreeks\r\nSEARCH\t\t\t= VIND.SPEC\t\t\t##\tZoekt een bepaalde tekenreeks in een tekst (waarbij geen onderscheid wordt gemaakt tussen hoofdletters en kleine letters)\r\nSEARCHB\t\t\t= VIND.SPEC.B\t\t\t##\tZoekt een bepaalde tekenreeks in een tekst (waarbij geen onderscheid wordt gemaakt tussen hoofdletters en kleine letters)\r\nSUBSTITUTE\t\t= SUBSTITUEREN\t\t\t##\tVervangt oude tekst door nieuwe tekst in een tekenreeks\r\nT\t\t\t= T\t\t\t\t##\tConverteert de argumenten naar tekst\r\nTEXT\t\t\t= TEKST\t\t\t\t##\tMaakt een getal op en converteert het getal naar tekst\r\nTRIM\t\t\t= SPATIES.WISSEN\t\t##\tVerwijdert de spaties uit een tekst\r\nUPPER\t\t\t= HOOFDLETTERS\t\t\t##\tZet tekst om in hoofdletters\r\nVALUE\t\t\t= WAARDE\t\t\t##\tConverteert tekst naar een getal\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/no/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= kr\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #NULL!\r\nDIV0\t= #DIV/0!\r\nVALUE\t= #VERDI!\r\nREF\t= #REF!\r\nNAME\t= #NAVN?\r\nNUM\t= #NUM!\r\nNA\t= #I/T\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/no/functions",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Calculation\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/\r\n##\r\n##\r\n\r\n\r\n##\r\n##\tAdd-in and Automation functions\t\t\t\tFunksjonene Tillegg og Automatisering\r\n##\r\nGETPIVOTDATA\t\t= HENTPIVOTDATA\t\t\t\t##\tReturnerer data som er lagret i en pivottabellrapport\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\t\tKubefunksjoner\r\n##\r\nCUBEKPIMEMBER\t\t= KUBEKPIMEDLEM\t\t\t\t##\tReturnerer navnet, egenskapen og målet for en viktig ytelsesindikator (KPI), og viser navnet og egenskapen i cellen. En KPI er en målbar enhet, for eksempel månedlig bruttoinntjening eller kvartalsvis inntjening per ansatt, og brukes til å overvåke ytelsen i en organisasjon.\r\nCUBEMEMBER\t\t= KUBEMEDLEM\t\t\t\t##\tReturnerer et medlem eller en tuppel i et kubehierarki. Brukes til å validere at medlemmet eller tuppelen finnes i kuben.\r\nCUBEMEMBERPROPERTY\t= KUBEMEDLEMEGENSKAP\t\t\t##\tReturnerer verdien til en medlemsegenskap i kuben. Brukes til å validere at et medlemsnavn finnes i kuben, og til å returnere den angitte egenskapen for dette medlemmet.\r\nCUBERANKEDMEMBER\t= KUBERANGERTMEDLEM\t\t\t##\tReturnerer det n-te, eller rangerte, medlemmet i et sett. Brukes til å returnere ett eller flere elementer i et sett, for eksempel de 10 beste studentene.\r\nCUBESET\t\t\t= KUBESETT\t\t\t\t##\tDefinerer et beregnet sett av medlemmer eller tuppeler ved å sende et settuttrykk til kuben på serveren, noe som oppretter settet og deretter returnerer dette settet til Microsoft Office Excel.\r\nCUBESETCOUNT\t\t= KUBESETTANTALL\t\t\t##\tReturnerer antallet elementer i et sett.\r\nCUBEVALUE\t\t= KUBEVERDI\t\t\t\t##\tReturnerer en aggregert verdi fra en kube.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\t\tDatabasefunksjoner\r\n##\r\nDAVERAGE\t\t= DGJENNOMSNITT\t\t\t\t##\tReturnerer gjennomsnittet av merkede databaseposter\r\nDCOUNT\t\t\t= DANTALL\t\t\t\t##\tTeller celler som inneholder tall i en database\r\nDCOUNTA\t\t\t= DANTALLA\t\t\t\t##\tTeller celler som ikke er tomme i en database\r\nDGET\t\t\t= DHENT\t\t\t\t\t##\tTrekker ut fra en database en post som oppfyller angitte vilkår\r\nDMAX\t\t\t= DMAKS\t\t\t\t\t##\tReturnerer maksimumsverdien fra merkede databaseposter\r\nDMIN\t\t\t= DMIN\t\t\t\t\t##\tReturnerer minimumsverdien fra merkede databaseposter\r\nDPRODUCT\t\t= DPRODUKT\t\t\t\t##\tMultipliserer verdiene i et bestemt felt med poster som oppfyller vilkårene i en database\r\nDSTDEV\t\t\t= DSTDAV\t\t\t\t##\tEstimerer standardavviket basert på et utvalg av merkede databaseposter\r\nDSTDEVP\t\t\t= DSTAVP\t\t\t\t##\tBeregner standardavviket basert på at merkede databaseposter utgjør hele populasjonen\r\nDSUM\t\t\t= DSUMMER\t\t\t\t##\tLegger til tallene i feltkolonnen med poster, i databasen som oppfyller vilkårene\r\nDVAR\t\t\t= DVARIANS\t\t\t\t##\tEstimerer variansen basert på et utvalg av merkede databaseposter\r\nDVARP\t\t\t= DVARIANSP\t\t\t\t##\tBeregner variansen basert på at merkede databaseposter utgjør hele populasjonen\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\t\tDato- og tidsfunksjoner\r\n##\r\nDATE\t\t\t= DATO\t\t\t\t\t##\tReturnerer serienummeret som svarer til en bestemt dato\r\nDATEVALUE\t\t= DATOVERDI\t\t\t\t##\tKonverterer en dato med tekstformat til et serienummer\r\nDAY\t\t\t= DAG\t\t\t\t\t##\tKonverterer et serienummer til en dag i måneden\r\nDAYS360\t\t\t= DAGER360\t\t\t\t##\tBeregner antall dager mellom to datoer basert på et år med 360 dager\r\nEDATE\t\t\t= DAG.ETTER\t\t\t\t##\tReturnerer serienummeret som svarer til datoen som er det indikerte antall måneder før eller etter startdatoen\r\nEOMONTH\t\t\t= MÅNEDSSLUTT\t\t\t\t##\tReturnerer serienummeret som svarer til siste dag i måneden, før eller etter et angitt antall måneder\r\nHOUR\t\t\t= TIME\t\t\t\t\t##\tKonverterer et serienummer til en time\r\nMINUTE\t\t\t= MINUTT\t\t\t\t##\tKonverterer et serienummer til et minutt\r\nMONTH\t\t\t= MÅNED\t\t\t\t\t##\tKonverterer et serienummer til en måned\r\nNETWORKDAYS\t\t= NETT.ARBEIDSDAGER\t\t\t##\tReturnerer antall hele arbeidsdager mellom to datoer\r\nNOW\t\t\t= NÅ\t\t\t\t\t##\tReturnerer serienummeret som svarer til gjeldende dato og klokkeslett\r\nSECOND\t\t\t= SEKUND\t\t\t\t##\tKonverterer et serienummer til et sekund\r\nTIME\t\t\t= TID\t\t\t\t\t##\tReturnerer serienummeret som svarer til et bestemt klokkeslett\r\nTIMEVALUE\t\t= TIDSVERDI\t\t\t\t##\tKonverterer et klokkeslett i tekstformat til et serienummer\r\nTODAY\t\t\t= IDAG\t\t\t\t\t##\tReturnerer serienummeret som svarer til dagens dato\r\nWEEKDAY\t\t\t= UKEDAG\t\t\t\t##\tKonverterer et serienummer til en ukedag\r\nWEEKNUM\t\t\t= UKENR\t\t\t\t\t##\tKonverterer et serienummer til et tall som representerer hvilket nummer uken har i et år\r\nWORKDAY\t\t\t= ARBEIDSDAG\t\t\t\t##\tReturnerer serienummeret som svarer til datoen før eller etter et angitt antall arbeidsdager\r\nYEAR\t\t\t= ÅR\t\t\t\t\t##\tKonverterer et serienummer til et år\r\nYEARFRAC\t\t= ÅRDEL\t\t\t\t\t##\tReturnerer brøkdelen for året, som svarer til antall hele dager mellom startdato og sluttdato\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\t\tTekniske funksjoner\r\n##\r\nBESSELI\t\t\t= BESSELI\t\t\t\t##\tReturnerer den endrede Bessel-funksjonen In(x)\r\nBESSELJ\t\t\t= BESSELJ\t\t\t\t##\tReturnerer Bessel-funksjonen Jn(x)\r\nBESSELK\t\t\t= BESSELK\t\t\t\t##\tReturnerer den endrede Bessel-funksjonen Kn(x)\r\nBESSELY\t\t\t= BESSELY\t\t\t\t##\tReturnerer Bessel-funksjonen Yn(x)\r\nBIN2DEC\t\t\t= BINTILDES\t\t\t\t##\tKonverterer et binært tall til et desimaltall\r\nBIN2HEX\t\t\t= BINTILHEKS\t\t\t\t##\tKonverterer et binært tall til et heksadesimaltall\r\nBIN2OCT\t\t\t= BINTILOKT\t\t\t\t##\tKonverterer et binært tall til et oktaltall\r\nCOMPLEX\t\t\t= KOMPLEKS\t\t\t\t##\tKonverterer reelle og imaginære koeffisienter til et komplekst tall\r\nCONVERT\t\t\t= KONVERTER\t\t\t\t##\tKonverterer et tall fra ett målsystem til et annet\r\nDEC2BIN\t\t\t= DESTILBIN\t\t\t\t##\tKonverterer et desimaltall til et binærtall\r\nDEC2HEX\t\t\t= DESTILHEKS\t\t\t\t##\tKonverterer et heltall i 10-tallsystemet til et heksadesimalt tall\r\nDEC2OCT\t\t\t= DESTILOKT\t\t\t\t##\tKonverterer et heltall i 10-tallsystemet til et oktaltall\r\nDELTA\t\t\t= DELTA\t\t\t\t\t##\tUndersøker om to verdier er like\r\nERF\t\t\t= FEILF\t\t\t\t\t##\tReturnerer feilfunksjonen\r\nERFC\t\t\t= FEILFK\t\t\t\t##\tReturnerer den komplementære feilfunksjonen\r\nGESTEP\t\t\t= GRENSEVERDI\t\t\t\t##\tTester om et tall er større enn en terskelverdi\r\nHEX2BIN\t\t\t= HEKSTILBIN\t\t\t\t##\tKonverterer et heksadesimaltall til et binært tall\r\nHEX2DEC\t\t\t= HEKSTILDES\t\t\t\t##\tKonverterer et heksadesimalt tall til et heltall i 10-tallsystemet\r\nHEX2OCT\t\t\t= HEKSTILOKT\t\t\t\t##\tKonverterer et heksadesimalt tall til et oktaltall\r\nIMABS\t\t\t= IMABS\t\t\t\t\t##\tReturnerer absoluttverdien (koeffisienten) til et komplekst tall\r\nIMAGINARY\t\t= IMAGINÆR\t\t\t\t##\tReturnerer den imaginære koeffisienten til et komplekst tall\r\nIMARGUMENT\t\t= IMARGUMENT\t\t\t\t##\tReturnerer argumentet theta, som er en vinkel uttrykt i radianer\r\nIMCONJUGATE\t\t= IMKONJUGERT\t\t\t\t##\tReturnerer den komplekse konjugaten til et komplekst tall\r\nIMCOS\t\t\t= IMCOS\t\t\t\t\t##\tReturnerer cosinus til et komplekst tall\r\nIMDIV\t\t\t= IMDIV\t\t\t\t\t##\tReturnerer kvotienten til to komplekse tall\r\nIMEXP\t\t\t= IMEKSP\t\t\t\t##\tReturnerer eksponenten til et komplekst tall\r\nIMLN\t\t\t= IMLN\t\t\t\t\t##\tReturnerer den naturlige logaritmen for et komplekst tall\r\nIMLOG10\t\t\t= IMLOG10\t\t\t\t##\tReturnerer logaritmen med grunntall 10 for et komplekst tall\r\nIMLOG2\t\t\t= IMLOG2\t\t\t\t##\tReturnerer logaritmen med grunntall 2 for et komplekst tall\r\nIMPOWER\t\t\t= IMOPPHØY\t\t\t\t##\tReturnerer et komplekst tall opphøyd til en heltallspotens\r\nIMPRODUCT\t\t= IMPRODUKT\t\t\t\t##\tReturnerer produktet av komplekse tall\r\nIMREAL\t\t\t= IMREELL\t\t\t\t##\tReturnerer den reelle koeffisienten til et komplekst tall\r\nIMSIN\t\t\t= IMSIN\t\t\t\t\t##\tReturnerer sinus til et komplekst tall\r\nIMSQRT\t\t\t= IMROT\t\t\t\t\t##\tReturnerer kvadratroten av et komplekst tall\r\nIMSUB\t\t\t= IMSUB\t\t\t\t\t##\tReturnerer differansen mellom to komplekse tall\r\nIMSUM\t\t\t= IMSUMMER\t\t\t\t##\tReturnerer summen av komplekse tall\r\nOCT2BIN\t\t\t= OKTTILBIN\t\t\t\t##\tKonverterer et oktaltall til et binært tall\r\nOCT2DEC\t\t\t= OKTTILDES\t\t\t\t##\tKonverterer et oktaltall til et desimaltall\r\nOCT2HEX\t\t\t= OKTTILHEKS\t\t\t\t##\tKonverterer et oktaltall til et heksadesimaltall\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\t\tØkonomiske funksjoner\r\n##\r\nACCRINT\t\t\t= PÅLØPT.PERIODISK.RENTE\t\t##\tReturnerer påløpte renter for et verdipapir som betaler periodisk rente\r\nACCRINTM\t\t= PÅLØPT.FORFALLSRENTE\t\t\t##\tReturnerer den påløpte renten for et verdipapir som betaler rente ved forfall\r\nAMORDEGRC\t\t= AMORDEGRC\t\t\t\t##\tReturnerer avskrivningen for hver regnskapsperiode ved hjelp av en avskrivingskoeffisient\r\nAMORLINC\t\t= AMORLINC\t\t\t\t##\tReturnerer avskrivingen for hver regnskapsperiode\r\nCOUPDAYBS\t\t= OBLIG.DAGER.FF\t\t\t##\tReturnerer antall dager fra begynnelsen av den rentebærende perioden til innløsningsdatoen\r\nCOUPDAYS\t\t= OBLIG.DAGER\t\t\t\t##\tReturnerer antall dager i den rentebærende perioden som inneholder innløsningsdatoen\r\nCOUPDAYSNC\t\t= OBLIG.DAGER.NF\t\t\t##\tReturnerer antall dager fra betalingsdato til neste renteinnbetalingsdato\r\nCOUPNCD\t\t\t= OBLIG.DAGER.EF\t\t\t##\tReturnerer obligasjonsdatoen som kommer etter oppgjørsdatoen\r\nCOUPNUM\t\t\t= OBLIG.ANTALL\t\t\t\t##\tReturnerer antall obligasjoner som skal betales mellom oppgjørsdatoen og forfallsdatoen\r\nCOUPPCD\t\t\t= OBLIG.DAG.FORRIGE\t\t\t##\tReturnerer obligasjonsdatoen som kommer før oppgjørsdatoen\r\nCUMIPMT\t\t\t= SAMLET.RENTE\t\t\t\t##\tReturnerer den kumulative renten som er betalt mellom to perioder\r\nCUMPRINC\t\t= SAMLET.HOVEDSTOL\t\t\t##\tReturnerer den kumulative hovedstolen som er betalt for et lån mellom to perioder\r\nDB\t\t\t= DAVSKR\t\t\t\t##\tReturnerer avskrivningen for et aktivum i en angitt periode, foretatt med fast degressiv avskrivning\r\nDDB\t\t\t= DEGRAVS\t\t\t\t##\tReturnerer avskrivningen for et aktivum for en gitt periode, ved hjelp av dobbel degressiv avskrivning eller en metode som du selv angir\r\nDISC\t\t\t= DISKONTERT\t\t\t\t##\tReturnerer diskonteringsraten for et verdipapir\r\nDOLLARDE\t\t= DOLLARDE\t\t\t\t##\tKonverterer en valutapris uttrykt som en brøk, til en valutapris uttrykt som et desimaltall\r\nDOLLARFR\t\t= DOLLARBR\t\t\t\t##\tKonverterer en valutapris uttrykt som et desimaltall, til en valutapris uttrykt som en brøk\r\nDURATION\t\t= VARIGHET\t\t\t\t##\tReturnerer årlig varighet for et verdipapir med renter som betales periodisk\r\nEFFECT\t\t\t= EFFEKTIV.RENTE\t\t\t##\tReturnerer den effektive årlige rentesatsen\r\nFV\t\t\t= SLUTTVERDI\t\t\t\t##\tReturnerer fremtidig verdi for en investering\r\nFVSCHEDULE\t\t= SVPLAN\t\t\t\t##\tReturnerer den fremtidige verdien av en inngående hovedstol etter å ha anvendt en serie med sammensatte rentesatser\r\nINTRATE\t\t\t= RENTESATS\t\t\t\t##\tReturnerer rentefoten av et fullfinansiert verdipapir\r\nIPMT\t\t\t= RAVDRAG\t\t\t\t##\tReturnerer betalte renter på en investering for en gitt periode\r\nIRR\t\t\t= IR\t\t\t\t\t##\tReturnerer internrenten for en serie kontantstrømmer\r\nISPMT\t\t\t= ER.AVDRAG\t\t\t\t##\tBeregner renten som er betalt for en investering i løpet av en bestemt periode\r\nMDURATION\t\t= MVARIGHET\t\t\t\t##\tReturnerer Macauleys modifiserte varighet for et verdipapir med en antatt pålydende verdi på kr 100,00\r\nMIRR\t\t\t= MODIR\t\t\t\t\t##\tReturnerer internrenten der positive og negative kontantstrømmer finansieres med forskjellige satser\r\nNOMINAL\t\t\t= NOMINELL\t\t\t\t##\tReturnerer årlig nominell rentesats\r\nNPER\t\t\t= PERIODER\t\t\t\t##\tReturnerer antall perioder for en investering\r\nNPV\t\t\t= NNV\t\t\t\t\t##\tReturnerer netto nåverdi for en investering, basert på en serie periodiske kontantstrømmer og en rentesats\r\nODDFPRICE\t\t= AVVIKFP.PRIS\t\t\t\t##\tReturnerer pris pålydende kr 100 for et verdipapir med en odde første periode\r\nODDFYIELD\t\t= AVVIKFP.AVKASTNING\t\t\t##\tReturnerer avkastingen for et verdipapir med en odde første periode\r\nODDLPRICE\t\t= AVVIKSP.PRIS\t\t\t\t##\tReturnerer pris pålydende kr 100 for et verdipapir med en odde siste periode\r\nODDLYIELD\t\t= AVVIKSP.AVKASTNING\t\t\t##\tReturnerer avkastingen for et verdipapir med en odde siste periode\r\nPMT\t\t\t= AVDRAG\t\t\t\t##\tReturnerer periodisk betaling for en annuitet\r\nPPMT\t\t\t= AMORT\t\t\t\t\t##\tReturnerer betalingen på hovedstolen for en investering i en gitt periode\r\nPRICE\t\t\t= PRIS\t\t\t\t\t##\tReturnerer prisen per pålydende kr 100 for et verdipapir som gir periodisk avkastning\r\nPRICEDISC\t\t= PRIS.DISKONTERT\t\t\t##\tReturnerer prisen per pålydende kr 100 for et diskontert verdipapir\r\nPRICEMAT\t\t= PRIS.FORFALL\t\t\t\t##\tReturnerer prisen per pålydende kr 100 av et verdipapir som betaler rente ved forfall\r\nPV\t\t\t= NÅVERDI\t\t\t\t##\tReturnerer nåverdien av en investering\r\nRATE\t\t\t= RENTE\t\t\t\t\t##\tReturnerer rentesatsen per periode for en annuitet\r\nRECEIVED\t\t= MOTTATT.AVKAST\t\t\t##\tReturnerer summen som mottas ved forfallsdato for et fullinvestert verdipapir\r\nSLN\t\t\t= LINAVS\t\t\t\t##\tReturnerer den lineære avskrivningen for et aktivum i én periode\r\nSYD\t\t\t= ÅRSAVS\t\t\t\t##\tReturnerer årsavskrivningen for et aktivum i en angitt periode\r\nTBILLEQ\t\t\t= TBILLEKV\t\t\t\t##\tReturnerer den obligasjonsekvivalente avkastningen for en statsobligasjon\r\nTBILLPRICE\t\t= TBILLPRIS\t\t\t\t##\tReturnerer prisen per pålydende kr 100 for en statsobligasjon\r\nTBILLYIELD\t\t= TBILLAVKASTNING\t\t\t##\tReturnerer avkastningen til en statsobligasjon\r\nVDB\t\t\t= VERDIAVS\t\t\t\t##\tReturnerer avskrivningen for et aktivum i en angitt periode eller delperiode, ved hjelp av degressiv avskrivning\r\nXIRR\t\t\t= XIR\t\t\t\t\t##\tReturnerer internrenten for en serie kontantstrømmer som ikke nødvendigvis er periodiske\r\nXNPV\t\t\t= XNNV\t\t\t\t\t##\tReturnerer netto nåverdi for en serie kontantstrømmer som ikke nødvendigvis er periodiske\r\nYIELD\t\t\t= AVKAST\t\t\t\t##\tReturnerer avkastningen på et verdipapir som betaler periodisk rente\r\nYIELDDISC\t\t= AVKAST.DISKONTERT\t\t\t##\tReturnerer årlig avkastning for et diskontert verdipapir, for eksempel en statskasseveksel\r\nYIELDMAT\t\t= AVKAST.FORFALL\t\t\t##\tReturnerer den årlige avkastningen for et verdipapir som betaler rente ved forfallsdato\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\t\tInformasjonsfunksjoner\r\n##\r\nCELL\t\t\t= CELLE\t\t\t\t\t##\tReturnerer informasjon om formatering, plassering eller innholdet til en celle\r\nERROR.TYPE\t\t= FEIL.TYPE\t\t\t\t##\tReturnerer et tall som svarer til en feiltype\r\nINFO\t\t\t= INFO\t\t\t\t\t##\tReturnerer informasjon om gjeldende operativmiljø\r\nISBLANK\t\t\t= ERTOM\t\t\t\t\t##\tReturnerer SANN hvis verdien er tom\r\nISERR\t\t\t= ERFEIL\t\t\t\t##\tReturnerer SANN hvis verdien er en hvilken som helst annen feilverdi enn #I/T\r\nISERROR\t\t\t= ERFEIL\t\t\t\t##\tReturnerer SANN hvis verdien er en hvilken som helst feilverdi\r\nISEVEN\t\t\t= ERPARTALL\t\t\t\t##\tReturnerer SANN hvis tallet er et partall\r\nISLOGICAL\t\t= ERLOGISK\t\t\t\t##\tReturnerer SANN hvis verdien er en logisk verdi\r\nISNA\t\t\t= ERIT\t\t\t\t\t##\tReturnerer SANN hvis verdien er feilverdien #I/T\r\nISNONTEXT\t\t= ERIKKETEKST\t\t\t\t##\tReturnerer SANN hvis verdien ikke er tekst\r\nISNUMBER\t\t= ERTALL\t\t\t\t##\tReturnerer SANN hvis verdien er et tall\r\nISODD\t\t\t= ERODDETALL\t\t\t\t##\tReturnerer SANN hvis tallet er et oddetall\r\nISREF\t\t\t= ERREF\t\t\t\t\t##\tReturnerer SANN hvis verdien er en referanse\r\nISTEXT\t\t\t= ERTEKST\t\t\t\t##\tReturnerer SANN hvis verdien er tekst\r\nN\t\t\t= N\t\t\t\t\t##\tReturnerer en verdi som er konvertert til et tall\r\nNA\t\t\t= IT\t\t\t\t\t##\tReturnerer feilverdien #I/T\r\nTYPE\t\t\t= VERDITYPE\t\t\t\t##\tReturnerer et tall som indikerer datatypen til en verdi\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\t\tLogiske funksjoner\r\n##\r\nAND\t\t\t= OG\t\t\t\t\t##\tReturnerer SANN hvis alle argumentene er lik SANN\r\nFALSE\t\t\t= USANN\t\t\t\t\t##\tReturnerer den logiske verdien USANN\r\nIF\t\t\t= HVIS\t\t\t\t\t##\tAngir en logisk test som skal utføres\r\nIFERROR\t\t\t= HVISFEIL\t\t\t\t##\tReturnerer en verdi du angir hvis en formel evaluerer til en feil. Ellers returnerer den resultatet av formelen.\r\nNOT\t\t\t= IKKE\t\t\t\t\t##\tReverserer logikken til argumentet\r\nOR\t\t\t= ELLER\t\t\t\t\t##\tReturnerer SANN hvis ett eller flere argumenter er lik SANN\r\nTRUE\t\t\t= SANN\t\t\t\t\t##\tReturnerer den logiske verdien SANN\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\t\tOppslag- og referansefunksjoner\r\n##\r\nADDRESS\t\t\t= ADRESSE\t\t\t\t##\tReturnerer en referanse som tekst til en enkelt celle i et regneark\r\nAREAS\t\t\t= OMRÅDER\t\t\t\t##\tReturnerer antall områder i en referanse\r\nCHOOSE\t\t\t= VELG\t\t\t\t\t##\tVelger en verdi fra en liste med verdier\r\nCOLUMN\t\t\t= KOLONNE\t\t\t\t##\tReturnerer kolonnenummeret for en referanse\r\nCOLUMNS\t\t\t= KOLONNER\t\t\t\t##\tReturnerer antall kolonner i en referanse\r\nHLOOKUP\t\t\t= FINN.KOLONNE\t\t\t\t##\tLeter i den øverste raden i en matrise og returnerer verdien for den angitte cellen\r\nHYPERLINK\t\t= HYPERKOBLING\t\t\t\t##\tOppretter en snarvei eller et hopp som åpner et dokument som er lagret på en nettverksserver, et intranett eller Internett\r\nINDEX\t\t\t= INDEKS\t\t\t\t##\tBruker en indeks til å velge en verdi fra en referanse eller matrise\r\nINDIRECT\t\t= INDIREKTE\t\t\t\t##\tReturnerer en referanse angitt av en tekstverdi\r\nLOOKUP\t\t\t= SLÅ.OPP\t\t\t\t##\tSlår opp verdier i en vektor eller matrise\r\nMATCH\t\t\t= SAMMENLIGNE\t\t\t\t##\tSlår opp verdier i en referanse eller matrise\r\nOFFSET\t\t\t= FORSKYVNING\t\t\t\t##\tReturnerer en referanseforskyvning fra en gitt referanse\r\nROW\t\t\t= RAD\t\t\t\t\t##\tReturnerer radnummeret for en referanse\r\nROWS\t\t\t= RADER\t\t\t\t\t##\tReturnerer antall rader i en referanse\r\nRTD\t\t\t= RTD\t\t\t\t\t##\tHenter sanntidsdata fra et program som støtter COM-automatisering (automatisering: En måte å arbeide på med programobjekter fra et annet program- eller utviklingsverktøy. Tidligere kalt OLE-automatisering. Automatisering er en bransjestandard og en funksjon i Component Object Model (COM).)\r\nTRANSPOSE\t\t= TRANSPONER\t\t\t\t##\tReturnerer transponeringen av en matrise\r\nVLOOKUP\t\t\t= FINN.RAD\t\t\t\t##\tLeter i den første kolonnen i en matrise og flytter bortover raden for å returnere verdien til en celle\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\t\tMatematikk- og trigonometrifunksjoner\r\n##\r\nABS\t\t\t= ABS\t\t\t\t\t##\tReturnerer absoluttverdien til et tall\r\nACOS\t\t\t= ARCCOS\t\t\t\t##\tReturnerer arcus cosinus til et tall\r\nACOSH\t\t\t= ARCCOSH\t\t\t\t##\tReturnerer den inverse hyperbolske cosinus til et tall\r\nASIN\t\t\t= ARCSIN\t\t\t\t##\tReturnerer arcus sinus til et tall\r\nASINH\t\t\t= ARCSINH\t\t\t\t##\tReturnerer den inverse hyperbolske sinus til et tall\r\nATAN\t\t\t= ARCTAN\t\t\t\t##\tReturnerer arcus tangens til et tall\r\nATAN2\t\t\t= ARCTAN2\t\t\t\t##\tReturnerer arcus tangens fra x- og y-koordinater\r\nATANH\t\t\t= ARCTANH\t\t\t\t##\tReturnerer den inverse hyperbolske tangens til et tall\r\nCEILING\t\t\t= AVRUND.GJELDENDE.MULTIPLUM\t\t##\tRunder av et tall til nærmeste heltall eller til nærmeste signifikante multiplum\r\nCOMBIN\t\t\t= KOMBINASJON\t\t\t\t##\tReturnerer antall kombinasjoner for ett gitt antall objekter\r\nCOS\t\t\t= COS\t\t\t\t\t##\tReturnerer cosinus til et tall\r\nCOSH\t\t\t= COSH\t\t\t\t\t##\tReturnerer den hyperbolske cosinus til et tall\r\nDEGREES\t\t\t= GRADER\t\t\t\t##\tKonverterer radianer til grader\r\nEVEN\t\t\t= AVRUND.TIL.PARTALL\t\t\t##\tRunder av et tall oppover til nærmeste heltall som er et partall\r\nEXP\t\t\t= EKSP\t\t\t\t\t##\tReturnerer e opphøyd i en angitt potens\r\nFACT\t\t\t= FAKULTET\t\t\t\t##\tReturnerer fakultet til et tall\r\nFACTDOUBLE\t\t= DOBBELFAKT\t\t\t\t##\tReturnerer et talls doble fakultet\r\nFLOOR\t\t\t= AVRUND.GJELDENDE.MULTIPLUM.NED\t##\tAvrunder et tall nedover, mot null\r\nGCD\t\t\t= SFF\t\t\t\t\t##\tReturnerer høyeste felles divisor\r\nINT\t\t\t= HELTALL\t\t\t\t##\tAvrunder et tall nedover til nærmeste heltall\r\nLCM\t\t\t= MFM\t\t\t\t\t##\tReturnerer minste felles multiplum\r\nLN\t\t\t= LN\t\t\t\t\t##\tReturnerer den naturlige logaritmen til et tall\r\nLOG\t\t\t= LOG\t\t\t\t\t##\tReturnerer logaritmen for et tall til et angitt grunntall\r\nLOG10\t\t\t= LOG10\t\t\t\t\t##\tReturnerer logaritmen med grunntall 10 for et tall\r\nMDETERM\t\t\t= MDETERM\t\t\t\t##\tReturnerer matrisedeterminanten til en matrise\r\nMINVERSE\t\t= MINVERS\t\t\t\t##\tReturnerer den inverse matrisen til en matrise\r\nMMULT\t\t\t= MMULT\t\t\t\t\t##\tReturnerer matriseproduktet av to matriser\r\nMOD\t\t\t= REST\t\t\t\t\t##\tReturnerer resten fra en divisjon\r\nMROUND\t\t\t= MRUND\t\t\t\t\t##\tReturnerer et tall avrundet til det ønskede multiplum\r\nMULTINOMIAL\t\t= MULTINOMINELL\t\t\t\t##\tReturnerer det multinominelle for et sett med tall\r\nODD\t\t\t= AVRUND.TIL.ODDETALL\t\t\t##\tRunder av et tall oppover til nærmeste heltall som er et oddetall\r\nPI\t\t\t= PI\t\t\t\t\t##\tReturnerer verdien av pi\r\nPOWER\t\t\t= OPPHØYD.I\t\t\t\t##\tReturnerer resultatet av et tall opphøyd i en potens\r\nPRODUCT\t\t\t= PRODUKT\t\t\t\t##\tMultipliserer argumentene\r\nQUOTIENT\t\t= KVOTIENT\t\t\t\t##\tReturnerer heltallsdelen av en divisjon\r\nRADIANS\t\t\t= RADIANER\t\t\t\t##\tKonverterer grader til radianer\r\nRAND\t\t\t= TILFELDIG\t\t\t\t##\tReturnerer et tilfeldig tall mellom 0 og 1\r\nRANDBETWEEN\t\t= TILFELDIGMELLOM\t\t\t##\tReturnerer et tilfeldig tall innenfor et angitt område\r\nROMAN\t\t\t= ROMERTALL\t\t\t\t##\tKonverterer vanlige tall til romertall, som tekst\r\nROUND\t\t\t= AVRUND\t\t\t\t##\tAvrunder et tall til et angitt antall sifre\r\nROUNDDOWN\t\t= AVRUND.NED\t\t\t\t##\tAvrunder et tall nedover, mot null\r\nROUNDUP\t\t\t= AVRUND.OPP\t\t\t\t##\tRunder av et tall oppover, bort fra null\r\nSERIESSUM\t\t= SUMMER.REKKE\t\t\t\t##\tReturnerer summen av en geometrisk rekke, basert på formelen\r\nSIGN\t\t\t= FORTEGN\t\t\t\t##\tReturnerer fortegnet for et tall\r\nSIN\t\t\t= SIN\t\t\t\t\t##\tReturnerer sinus til en gitt vinkel\r\nSINH\t\t\t= SINH\t\t\t\t\t##\tReturnerer den hyperbolske sinus til et tall\r\nSQRT\t\t\t= ROT\t\t\t\t\t##\tReturnerer en positiv kvadratrot\r\nSQRTPI\t\t\t= ROTPI\t\t\t\t\t##\tReturnerer kvadratroten av (tall * pi)\r\nSUBTOTAL\t\t= DELSUM\t\t\t\t##\tReturnerer en delsum i en liste eller database\r\nSUM\t\t\t= SUMMER\t\t\t\t##\tLegger sammen argumentene\r\nSUMIF\t\t\t= SUMMERHVIS\t\t\t\t##\tLegger sammen cellene angitt ved et gitt vilkår\r\nSUMIFS\t\t\t= SUMMER.HVIS.SETT\t\t\t##\tLegger sammen cellene i et område som oppfyller flere vilkår\r\nSUMPRODUCT\t\t= SUMMERPRODUKT\t\t\t\t##\tReturnerer summen av produktene av tilsvarende matrisekomponenter\r\nSUMSQ\t\t\t= SUMMERKVADRAT\t\t\t\t##\tReturnerer kvadratsummen av argumentene\r\nSUMX2MY2\t\t= SUMMERX2MY2\t\t\t\t##\tReturnerer summen av differansen av kvadratene for tilsvarende verdier i to matriser\r\nSUMX2PY2\t\t= SUMMERX2PY2\t\t\t\t##\tReturnerer summen av kvadratsummene for tilsvarende verdier i to matriser\r\nSUMXMY2\t\t\t= SUMMERXMY2\t\t\t\t##\tReturnerer summen av kvadratene av differansen for tilsvarende verdier i to matriser\r\nTAN\t\t\t= TAN\t\t\t\t\t##\tReturnerer tangens for et tall\r\nTANH\t\t\t= TANH\t\t\t\t\t##\tReturnerer den hyperbolske tangens for et tall\r\nTRUNC\t\t\t= AVKORT\t\t\t\t##\tKorter av et tall til et heltall\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\t\tStatistiske funksjoner\r\n##\r\nAVEDEV\t\t\t= GJENNOMSNITTSAVVIK\t\t\t##\tReturnerer datapunktenes gjennomsnittlige absoluttavvik fra middelverdien\r\nAVERAGE\t\t\t= GJENNOMSNITT\t\t\t\t##\tReturnerer gjennomsnittet for argumentene\r\nAVERAGEA\t\t= GJENNOMSNITTA\t\t\t\t##\tReturnerer gjennomsnittet for argumentene, inkludert tall, tekst og logiske verdier\r\nAVERAGEIF\t\t= GJENNOMSNITTHVIS\t\t\t##\tReturnerer gjennomsnittet (aritmetisk gjennomsnitt) av alle cellene i et område som oppfyller et bestemt vilkår\r\nAVERAGEIFS\t\t= GJENNOMSNITT.HVIS.SETT\t\t##\tReturnerer gjennomsnittet (aritmetisk middelverdi) av alle celler som oppfyller flere vilkår.\r\nBETADIST\t\t= BETA.FORDELING\t\t\t##\tReturnerer den kumulative betafordelingsfunksjonen\r\nBETAINV\t\t\t= INVERS.BETA.FORDELING\t\t\t##\tReturnerer den inverse verdien til fordelingsfunksjonen for en angitt betafordeling\r\nBINOMDIST\t\t= BINOM.FORDELING\t\t\t##\tReturnerer den individuelle binomiske sannsynlighetsfordelingen\r\nCHIDIST\t\t\t= KJI.FORDELING\t\t\t\t##\tReturnerer den ensidige sannsynligheten for en kjikvadrert fordeling\r\nCHIINV\t\t\t= INVERS.KJI.FORDELING\t\t\t##\tReturnerer den inverse av den ensidige sannsynligheten for den kjikvadrerte fordelingen\r\nCHITEST\t\t\t= KJI.TEST\t\t\t\t##\tUtfører testen for uavhengighet\r\nCONFIDENCE\t\t= KONFIDENS\t\t\t\t##\tReturnerer konfidensintervallet til gjennomsnittet for en populasjon\r\nCORREL\t\t\t= KORRELASJON\t\t\t\t##\tReturnerer korrelasjonskoeffisienten mellom to datasett\r\nCOUNT\t\t\t= ANTALL\t\t\t\t##\tTeller hvor mange tall som er i argumentlisten\r\nCOUNTA\t\t\t= ANTALLA\t\t\t\t##\tTeller hvor mange verdier som er i argumentlisten\r\nCOUNTBLANK\t\t= TELLBLANKE\t\t\t\t##\tTeller antall tomme celler i et område.\r\nCOUNTIF\t\t\t= ANTALL.HVIS\t\t\t\t##\tTeller antall celler i et område som oppfyller gitte vilkår\r\nCOUNTIFS\t\t= ANTALL.HVIS.SETT\t\t\t##\tTeller antallet ikke-tomme celler i et område som oppfyller flere vilkår\r\nCOVAR\t\t\t= KOVARIANS\t\t\t\t##\tReturnerer kovariansen, gjennomsnittet av produktene av parvise avvik\r\nCRITBINOM\t\t= GRENSE.BINOM\t\t\t\t##\tReturnerer den minste verdien der den kumulative binomiske fordelingen er mindre enn eller lik en vilkårsverdi\r\nDEVSQ\t\t\t= AVVIK.KVADRERT\t\t\t##\tReturnerer summen av kvadrerte avvik\r\nEXPONDIST\t\t= EKSP.FORDELING\t\t\t##\tReturnerer eksponentialfordelingen\r\nFDIST\t\t\t= FFORDELING\t\t\t\t##\tReturnerer F-sannsynlighetsfordelingen\r\nFINV\t\t\t= FFORDELING.INVERS\t\t\t##\tReturnerer den inverse av den sannsynlige F-fordelingen\r\nFISHER\t\t\t= FISHER\t\t\t\t##\tReturnerer Fisher-transformasjonen\r\nFISHERINV\t\t= FISHERINV\t\t\t\t##\tReturnerer den inverse av Fisher-transformasjonen\r\nFORECAST\t\t= PROGNOSE\t\t\t\t##\tReturnerer en verdi langs en lineær trend\r\nFREQUENCY\t\t= FREKVENS\t\t\t\t##\tReturnerer en frekvensdistribusjon som en loddrett matrise\r\nFTEST\t\t\t= FTEST\t\t\t\t\t##\tReturnerer resultatet av en F-test\r\nGAMMADIST\t\t= GAMMAFORDELING\t\t\t##\tReturnerer gammafordelingen\r\nGAMMAINV\t\t= GAMMAINV\t\t\t\t##\tReturnerer den inverse av den gammakumulative fordelingen\r\nGAMMALN\t\t\t= GAMMALN\t\t\t\t##\tReturnerer den naturlige logaritmen til gammafunksjonen G(x)\r\nGEOMEAN\t\t\t= GJENNOMSNITT.GEOMETRISK\t\t##\tReturnerer den geometriske middelverdien\r\nGROWTH\t\t\t= VEKST\t\t\t\t\t##\tReturnerer verdier langs en eksponentiell trend\r\nHARMEAN\t\t\t= GJENNOMSNITT.HARMONISK\t\t##\tReturnerer den harmoniske middelverdien\r\nHYPGEOMDIST\t\t= HYPGEOM.FORDELING\t\t\t##\tReturnerer den hypergeometriske fordelingen\r\nINTERCEPT\t\t= SKJÆRINGSPUNKT\t\t\t##\tReturnerer skjæringspunktet til den lineære regresjonslinjen\r\nKURT\t\t\t= KURT\t\t\t\t\t##\tReturnerer kurtosen til et datasett\r\nLARGE\t\t\t= N.STØRST\t\t\t\t##\tReturnerer den n-te største verdien i et datasett\r\nLINEST\t\t\t= RETTLINJE\t\t\t\t##\tReturnerer parameterne til en lineær trend\r\nLOGEST\t\t\t= KURVE\t\t\t\t\t##\tReturnerer parameterne til en eksponentiell trend\r\nLOGINV\t\t\t= LOGINV\t\t\t\t##\tReturnerer den inverse lognormale fordelingen\r\nLOGNORMDIST\t\t= LOGNORMFORD\t\t\t\t##\tReturnerer den kumulative lognormale fordelingen\r\nMAX\t\t\t= STØRST\t\t\t\t##\tReturnerer maksimumsverdien i en argumentliste\r\nMAXA\t\t\t= MAKSA\t\t\t\t\t##\tReturnerer maksimumsverdien i en argumentliste, inkludert tall, tekst og logiske verdier\r\nMEDIAN\t\t\t= MEDIAN\t\t\t\t##\tReturnerer medianen til tallene som er gitt\r\nMIN\t\t\t= MIN\t\t\t\t\t##\tReturnerer minimumsverdien i en argumentliste\r\nMINA\t\t\t= MINA\t\t\t\t\t##\tReturnerer den minste verdien i en argumentliste, inkludert tall, tekst og logiske verdier\r\nMODE\t\t\t= MODUS\t\t\t\t\t##\tReturnerer den vanligste verdien i et datasett\r\nNEGBINOMDIST\t\t= NEGBINOM.FORDELING\t\t\t##\tReturnerer den negative binomiske fordelingen\r\nNORMDIST\t\t= NORMALFORDELING\t\t\t##\tReturnerer den kumulative normalfordelingen\r\nNORMINV\t\t\t= NORMINV\t\t\t\t##\tReturnerer den inverse kumulative normalfordelingen\r\nNORMSDIST\t\t= NORMSFORDELING\t\t\t##\tReturnerer standard kumulativ normalfordeling\r\nNORMSINV\t\t= NORMSINV\t\t\t\t##\tReturnerer den inverse av den den kumulative standard normalfordelingen\r\nPEARSON\t\t\t= PEARSON\t\t\t\t##\tReturnerer produktmomentkorrelasjonskoeffisienten, Pearson\r\nPERCENTILE\t\t= PERSENTIL\t\t\t\t##\tReturnerer den n-te persentil av verdiene i et område\r\nPERCENTRANK\t\t= PROSENTDEL\t\t\t\t##\tReturnerer prosentrangeringen av en verdi i et datasett\r\nPERMUT\t\t\t= PERMUTER\t\t\t\t##\tReturnerer antall permutasjoner for et gitt antall objekter\r\nPOISSON\t\t\t= POISSON\t\t\t\t##\tReturnerer Poissons sannsynlighetsfordeling\r\nPROB\t\t\t= SANNSYNLIG\t\t\t\t##\tReturnerer sannsynligheten for at verdier i et område ligger mellom to grenser\r\nQUARTILE\t\t= KVARTIL\t\t\t\t##\tReturnerer kvartilen til et datasett\r\nRANK\t\t\t= RANG\t\t\t\t\t##\tReturnerer rangeringen av et tall, eller plassen tallet har i en rekke\r\nRSQ\t\t\t= RKVADRAT\t\t\t\t##\tReturnerer kvadratet av produktmomentkorrelasjonskoeffisienten (Pearsons r)\r\nSKEW\t\t\t= SKJEVFORDELING\t\t\t##\tReturnerer skjevheten i en fordeling\r\nSLOPE\t\t\t= STIGNINGSTALL\t\t\t\t##\tReturnerer stigningtallet for den lineære regresjonslinjen\r\nSMALL\t\t\t= N.MINST\t\t\t\t##\tReturnerer den n-te minste verdien i et datasett\r\nSTANDARDIZE\t\t= NORMALISER\t\t\t\t##\tReturnerer en normalisert verdi\r\nSTDEV\t\t\t= STDAV\t\t\t\t\t##\tEstimere standardavvik på grunnlag av et utvalg\r\nSTDEVA\t\t\t= STDAVVIKA\t\t\t\t##\tEstimerer standardavvik basert på et utvalg, inkludert tall, tekst og logiske verdier\r\nSTDEVP\t\t\t= STDAVP\t\t\t\t##\tBeregner standardavvik basert på hele populasjonen\r\nSTDEVPA\t\t\t= STDAVVIKPA\t\t\t\t##\tBeregner standardavvik basert på hele populasjonen, inkludert tall, tekst og logiske verdier\r\nSTEYX\t\t\t= STANDARDFEIL\t\t\t\t##\tReturnerer standardfeilen for den predikerte y-verdien for hver x i regresjonen\r\nTDIST\t\t\t= TFORDELING\t\t\t\t##\tReturnerer en Student t-fordeling\r\nTINV\t\t\t= TINV\t\t\t\t\t##\tReturnerer den inverse Student t-fordelingen\r\nTREND\t\t\t= TREND\t\t\t\t\t##\tReturnerer verdier langs en lineær trend\r\nTRIMMEAN\t\t= TRIMMET.GJENNOMSNITT\t\t\t##\tReturnerer den interne middelverdien til et datasett\r\nTTEST\t\t\t= TTEST\t\t\t\t\t##\tReturnerer sannsynligheten assosiert med en Student t-test\r\nVAR\t\t\t= VARIANS\t\t\t\t##\tEstimerer varians basert på et utvalg\r\nVARA\t\t\t= VARIANSA\t\t\t\t##\tEstimerer varians basert på et utvalg, inkludert tall, tekst og logiske verdier\r\nVARP\t\t\t= VARIANSP\t\t\t\t##\tBeregner varians basert på hele populasjonen\r\nVARPA\t\t\t= VARIANSPA\t\t\t\t##\tBeregner varians basert på hele populasjonen, inkludert tall, tekst og logiske verdier\r\nWEIBULL\t\t\t= WEIBULL.FORDELING\t\t\t##\tReturnerer Weibull-fordelingen\r\nZTEST\t\t\t= ZTEST\t\t\t\t\t##\tReturnerer den ensidige sannsynlighetsverdien for en z-test\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\t\tTekstfunksjoner\r\n##\r\nASC\t\t\t= STIGENDE\t\t\t\t##\tEndrer fullbreddes (dobbeltbyte) engelske bokstaver eller katakana i en tegnstreng, til halvbreddes (enkeltbyte) tegn\r\nBAHTTEXT\t\t= BAHTTEKST\t\t\t\t##\tKonverterer et tall til tekst, og bruker valutaformatet ß (baht)\r\nCHAR\t\t\t= TEGNKODE\t\t\t\t##\tReturnerer tegnet som svarer til kodenummeret\r\nCLEAN\t\t\t= RENSK\t\t\t\t\t##\tFjerner alle tegn som ikke kan skrives ut, fra teksten\r\nCODE\t\t\t= KODE\t\t\t\t\t##\tReturnerer en numerisk kode for det første tegnet i en tekststreng\r\nCONCATENATE\t\t= KJEDE.SAMMEN\t\t\t\t##\tSlår sammen flere tekstelementer til ett tekstelement\r\nDOLLAR\t\t\t= VALUTA\t\t\t\t##\tKonverterer et tall til tekst, og bruker valutaformatet $ (dollar)\r\nEXACT\t\t\t= EKSAKT\t\t\t\t##\tKontrollerer om to tekstverdier er like\r\nFIND\t\t\t= FINN\t\t\t\t\t##\tFinner en tekstverdi inne i en annen (skiller mellom store og små bokstaver)\r\nFINDB\t\t\t= FINNB\t\t\t\t\t##\tFinner en tekstverdi inne i en annen (skiller mellom store og små bokstaver)\r\nFIXED\t\t\t= FASTSATT\t\t\t\t##\tFormaterer et tall som tekst med et bestemt antall desimaler\r\nJIS\t\t\t= JIS\t\t\t\t\t##\tEndrer halvbreddes (enkeltbyte) engelske bokstaver eller katakana i en tegnstreng, til fullbreddes (dobbeltbyte) tegn\r\nLEFT\t\t\t= VENSTRE\t\t\t\t##\tReturnerer tegnene lengst til venstre i en tekstverdi\r\nLEFTB\t\t\t= VENSTREB\t\t\t\t##\tReturnerer tegnene lengst til venstre i en tekstverdi\r\nLEN\t\t\t= LENGDE\t\t\t\t##\tReturnerer antall tegn i en tekststreng\r\nLENB\t\t\t= LENGDEB\t\t\t\t##\tReturnerer antall tegn i en tekststreng\r\nLOWER\t\t\t= SMÅ\t\t\t\t\t##\tKonverterer tekst til små bokstaver\r\nMID\t\t\t= DELTEKST\t\t\t\t##\tReturnerer et angitt antall tegn fra en tekststreng, og begynner fra posisjonen du angir\r\nMIDB\t\t\t= DELTEKSTB\t\t\t\t##\tReturnerer et angitt antall tegn fra en tekststreng, og begynner fra posisjonen du angir\r\nPHONETIC\t\t= FURIGANA\t\t\t\t##\tTrekker ut fonetiske tegn (furigana) fra en tekststreng\r\nPROPER\t\t\t= STOR.FORBOKSTAV\t\t\t##\tGir den første bokstaven i hvert ord i en tekstverdi stor forbokstav\r\nREPLACE\t\t\t= ERSTATT\t\t\t\t##\tErstatter tegn i en tekst\r\nREPLACEB\t\t= ERSTATTB\t\t\t\t##\tErstatter tegn i en tekst\r\nREPT\t\t\t= GJENTA\t\t\t\t##\tGjentar tekst et gitt antall ganger\r\nRIGHT\t\t\t= HØYRE\t\t\t\t\t##\tReturnerer tegnene lengst til høyre i en tekstverdi\r\nRIGHTB\t\t\t= HØYREB\t\t\t\t##\tReturnerer tegnene lengst til høyre i en tekstverdi\r\nSEARCH\t\t\t= SØK\t\t\t\t\t##\tFinner en tekstverdi inne i en annen (skiller ikke mellom store og små bokstaver)\r\nSEARCHB\t\t\t= SØKB\t\t\t\t\t##\tFinner en tekstverdi inne i en annen (skiller ikke mellom store og små bokstaver)\r\nSUBSTITUTE\t\t= BYTT.UT\t\t\t\t##\tBytter ut gammel tekst med ny tekst i en tekststreng\r\nT\t\t\t= T\t\t\t\t\t##\tKonverterer argumentene til tekst\r\nTEXT\t\t\t= TEKST\t\t\t\t\t##\tFormaterer et tall og konverterer det til tekst\r\nTRIM\t\t\t= TRIMME\t\t\t\t##\tFjerner mellomrom fra tekst\r\nUPPER\t\t\t= STORE\t\t\t\t\t##\tKonverterer tekst til store bokstaver\r\nVALUE\t\t\t= VERDI\t\t\t\t\t##\tKonverterer et tekstargument til et tall\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= zł\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #ZERO!\r\nDIV0\t= #DZIEL/0!\r\nVALUE\t= #ARG!\r\nREF\t= #ADR!\r\nNAME\t= #NAZWA?\r\nNUM\t= #LICZBA!\r\nNA\t= #N/D!\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/pl/functions",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Calculation\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/\r\n##\r\n##\r\n\r\n\r\n##\r\n##\tAdd-in and Automation functions\t\t\tFunkcje dodatków i automatyzacji\r\n##\r\nGETPIVOTDATA\t\t= WEŹDANETABELI\t\t\t##\tZwraca dane przechowywane w raporcie tabeli przestawnej.\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\tFunkcje modułów\r\n##\r\nCUBEKPIMEMBER\t\t= ELEMENT.KPI.MODUŁU\t\t##\tZwraca nazwę, właściwość i miarę kluczowego wskaźnika wydajności (KPI) oraz wyświetla nazwę i właściwość w komórce. Wskaźnik KPI jest miarą ilościową, taką jak miesięczny zysk brutto lub kwartalna fluktuacja pracowników, używaną do monitorowania wydajności organizacji.\r\nCUBEMEMBER\t\t= ELEMENT.MODUŁU\t\t##\tZwraca element lub krotkę z hierarchii modułu. Służy do sprawdzania, czy element lub krotka istnieje w module.\r\nCUBEMEMBERPROPERTY\t= WŁAŚCIWOŚĆ.ELEMENTU.MODUŁU\t##\tZwraca wartość właściwości elementu w module. Służy do sprawdzania, czy nazwa elementu istnieje w module, i zwracania określonej właściwości dla tego elementu.\r\nCUBERANKEDMEMBER\t= USZEREGOWANY.ELEMENT.MODUŁU\t##\tZwraca n-ty (albo uszeregowany) element zestawu. Służy do zwracania elementu lub elementów zestawu, na przykład najlepszego sprzedawcy lub 10 najlepszych studentów.\r\nCUBESET\t\t\t= ZESTAW.MODUŁÓW\t\t##\tDefiniuje obliczony zestaw elementów lub krotek, wysyłając wyrażenie zestawu do serwera modułu, który tworzy zestaw i zwraca go do programu Microsoft Office Excel.\r\nCUBESETCOUNT\t\t= LICZNIK.MODUŁÓW.ZESTAWU\t##\tZwraca liczbę elementów zestawu.\r\nCUBEVALUE\t\t= WARTOŚĆ.MODUŁU\t\t##\tZwraca zagregowaną wartość z modułu.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\tFunkcje baz danych\r\n##\r\nDAVERAGE\t\t= BD.ŚREDNIA\t\t\t##\tZwraca wartość średniej wybranych wpisów bazy danych.\r\nDCOUNT\t\t\t= BD.ILE.REKORDÓW\t\t##\tZlicza komórki zawierające liczby w bazie danych.\r\nDCOUNTA\t\t\t= BD.ILE.REKORDÓW.A\t\t##\tZlicza niepuste komórki w bazie danych.\r\nDGET\t\t\t= BD.POLE\t\t\t##\tWyodrębnia z bazy danych jeden rekord spełniający określone kryteria.\r\nDMAX\t\t\t= BD.MAX\t\t\t##\tZwraca wartość maksymalną z wybranych wpisów bazy danych.\r\nDMIN\t\t\t= BD.MIN\t\t\t##\tZwraca wartość minimalną z wybranych wpisów bazy danych.\r\nDPRODUCT\t\t= BD.ILOCZYN\t\t\t##\tMnoży wartości w konkretnym, spełniającym kryteria polu rekordów bazy danych.\r\nDSTDEV\t\t\t= BD.ODCH.STANDARD\t\t##\tSzacuje odchylenie standardowe na podstawie próbki z wybranych wpisów bazy danych.\r\nDSTDEVP\t\t\t= BD.ODCH.STANDARD.POPUL\t##\tOblicza odchylenie standardowe na podstawie całej populacji wybranych wpisów bazy danych.\r\nDSUM\t\t\t= BD.SUMA\t\t\t##\tDodaje liczby w kolumnie pól rekordów bazy danych, które spełniają kryteria.\r\nDVAR\t\t\t= BD.WARIANCJA\t\t\t##\tSzacuje wariancję na podstawie próbki z wybranych wpisów bazy danych.\r\nDVARP\t\t\t= BD.WARIANCJA.POPUL\t\t##\tOblicza wariancję na podstawie całej populacji wybranych wpisów bazy danych.\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\tFunkcje dat, godzin i czasu\r\n##\r\nDATE\t\t\t= DATA\t\t\t\t##\tZwraca liczbę seryjną dla wybranej daty.\r\nDATEVALUE\t\t= DATA.WARTOŚĆ\t\t\t##\tKonwertuje datę w formie tekstu na liczbę seryjną.\r\nDAY\t\t\t= DZIEŃ\t\t\t\t##\tKonwertuje liczbę seryjną na dzień miesiąca.\r\nDAYS360\t\t\t= DNI.360\t\t\t##\tOblicza liczbę dni między dwiema datami na podstawie roku 360-dniowego.\r\nEDATE\t\t\t= UPŁDNI\t\t\t##\tZwraca liczbę seryjną daty jako wskazaną liczbę miesięcy przed określoną datą początkową lub po niej.\r\nEOMONTH\t\t\t= EOMONTH\t\t\t##\tZwraca liczbę seryjną ostatniego dnia miesiąca przed określoną liczbą miesięcy lub po niej.\r\nHOUR\t\t\t= GODZINA\t\t\t##\tKonwertuje liczbę seryjną na godzinę.\r\nMINUTE\t\t\t= MINUTA\t\t\t##\tKonwertuje liczbę seryjną na minutę.\r\nMONTH\t\t\t= MIESIĄC\t\t\t##\tKonwertuje liczbę seryjną na miesiąc.\r\nNETWORKDAYS\t\t= NETWORKDAYS\t\t\t##\tZwraca liczbę pełnych dni roboczych między dwiema datami.\r\nNOW\t\t\t= TERAZ\t\t\t\t##\tZwraca liczbę seryjną bieżącej daty i godziny.\r\nSECOND\t\t\t= SEKUNDA\t\t\t##\tKonwertuje liczbę seryjną na sekundę.\r\nTIME\t\t\t= CZAS\t\t\t\t##\tZwraca liczbę seryjną określonego czasu.\r\nTIMEVALUE\t\t= CZAS.WARTOŚĆ\t\t\t##\tKonwertuje czas w formie tekstu na liczbę seryjną.\r\nTODAY\t\t\t= DZIŚ\t\t\t\t##\tZwraca liczbę seryjną dla daty bieżącej.\r\nWEEKDAY\t\t\t= DZIEŃ.TYG\t\t\t##\tKonwertuje liczbę seryjną na dzień tygodnia.\r\nWEEKNUM\t\t\t= WEEKNUM\t\t\t##\tKonwertuje liczbę seryjną na liczbę reprezentującą numer tygodnia w roku.\r\nWORKDAY\t\t\t= WORKDAY\t\t\t##\tZwraca liczbę seryjną dla daty przed określoną liczbą dni roboczych lub po niej.\r\nYEAR\t\t\t= ROK\t\t\t\t##\tKonwertuje liczbę seryjną na rok.\r\nYEARFRAC\t\t= YEARFRAC\t\t\t##\tZwraca część roku reprezentowaną przez pełną liczbę dni między datą początkową a datą końcową.\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\tFunkcje inżynierskie\r\n##\r\nBESSELI\t\t\t= BESSELI\t\t\t##\tZwraca wartość zmodyfikowanej funkcji Bessela In(x).\r\nBESSELJ\t\t\t= BESSELJ\t\t\t##\tZwraca wartość funkcji Bessela Jn(x).\r\nBESSELK\t\t\t= BESSELK\t\t\t##\tZwraca wartość zmodyfikowanej funkcji Bessela Kn(x).\r\nBESSELY\t\t\t= BESSELY\t\t\t##\tZwraca wartość funkcji Bessela Yn(x).\r\nBIN2DEC\t\t\t= BIN2DEC\t\t\t##\tKonwertuje liczbę w postaci dwójkowej na liczbę w postaci dziesiętnej.\r\nBIN2HEX\t\t\t= BIN2HEX\t\t\t##\tKonwertuje liczbę w postaci dwójkowej na liczbę w postaci szesnastkowej.\r\nBIN2OCT\t\t\t= BIN2OCT\t\t\t##\tKonwertuje liczbę w postaci dwójkowej na liczbę w postaci ósemkowej.\r\nCOMPLEX\t\t\t= COMPLEX\t\t\t##\tKonwertuje część rzeczywistą i urojoną na liczbę zespoloną.\r\nCONVERT\t\t\t= CONVERT\t\t\t##\tKonwertuje liczbę z jednego systemu miar na inny.\r\nDEC2BIN\t\t\t= DEC2BIN\t\t\t##\tKonwertuje liczbę w postaci dziesiętnej na postać dwójkową.\r\nDEC2HEX\t\t\t= DEC2HEX\t\t\t##\tKonwertuje liczbę w postaci dziesiętnej na liczbę w postaci szesnastkowej.\r\nDEC2OCT\t\t\t= DEC2OCT\t\t\t##\tKonwertuje liczbę w postaci dziesiętnej na liczbę w postaci ósemkowej.\r\nDELTA\t\t\t= DELTA\t\t\t\t##\tSprawdza, czy dwie wartości są równe.\r\nERF\t\t\t= ERF\t\t\t\t##\tZwraca wartość funkcji błędu.\r\nERFC\t\t\t= ERFC\t\t\t\t##\tZwraca wartość komplementarnej funkcji błędu.\r\nGESTEP\t\t\t= GESTEP\t\t\t##\tSprawdza, czy liczba jest większa niż wartość progowa.\r\nHEX2BIN\t\t\t= HEX2BIN\t\t\t##\tKonwertuje liczbę w postaci szesnastkowej na liczbę w postaci dwójkowej.\r\nHEX2DEC\t\t\t= HEX2DEC\t\t\t##\tKonwertuje liczbę w postaci szesnastkowej na liczbę w postaci dziesiętnej.\r\nHEX2OCT\t\t\t= HEX2OCT\t\t\t##\tKonwertuje liczbę w postaci szesnastkowej na liczbę w postaci ósemkowej.\r\nIMABS\t\t\t= IMABS\t\t\t\t##\tZwraca wartość bezwzględną (moduł) liczby zespolonej.\r\nIMAGINARY\t\t= IMAGINARY\t\t\t##\tZwraca wartość części urojonej liczby zespolonej.\r\nIMARGUMENT\t\t= IMARGUMENT\t\t\t##\tZwraca wartość argumentu liczby zespolonej, przy czym kąt wyrażony jest w radianach.\r\nIMCONJUGATE\t\t= IMCONJUGATE\t\t\t##\tZwraca wartość liczby sprzężonej danej liczby zespolonej.\r\nIMCOS\t\t\t= IMCOS\t\t\t\t##\tZwraca wartość cosinusa liczby zespolonej.\r\nIMDIV\t\t\t= IMDIV\t\t\t\t##\tZwraca wartość ilorazu dwóch liczb zespolonych.\r\nIMEXP\t\t\t= IMEXP\t\t\t\t##\tZwraca postać wykładniczą liczby zespolonej.\r\nIMLN\t\t\t= IMLN\t\t\t\t##\tZwraca wartość logarytmu naturalnego liczby zespolonej.\r\nIMLOG10\t\t\t= IMLOG10\t\t\t##\tZwraca wartość logarytmu dziesiętnego liczby zespolonej.\r\nIMLOG2\t\t\t= IMLOG2\t\t\t##\tZwraca wartość logarytmu liczby zespolonej przy podstawie 2.\r\nIMPOWER\t\t\t= IMPOWER\t\t\t##\tZwraca wartość liczby zespolonej podniesionej do potęgi całkowitej.\r\nIMPRODUCT\t\t= IMPRODUCT\t\t\t##\tZwraca wartość iloczynu liczb zespolonych.\r\nIMREAL\t\t\t= IMREAL\t\t\t##\tZwraca wartość części rzeczywistej liczby zespolonej.\r\nIMSIN\t\t\t= IMSIN\t\t\t\t##\tZwraca wartość sinusa liczby zespolonej.\r\nIMSQRT\t\t\t= IMSQRT\t\t\t##\tZwraca wartość pierwiastka kwadratowego z liczby zespolonej.\r\nIMSUB\t\t\t= IMSUB\t\t\t\t##\tZwraca wartość różnicy dwóch liczb zespolonych.\r\nIMSUM\t\t\t= IMSUM\t\t\t\t##\tZwraca wartość sumy liczb zespolonych.\r\nOCT2BIN\t\t\t= OCT2BIN\t\t\t##\tKonwertuje liczbę w postaci ósemkowej na liczbę w postaci dwójkowej.\r\nOCT2DEC\t\t\t= OCT2DEC\t\t\t##\tKonwertuje liczbę w postaci ósemkowej na liczbę w postaci dziesiętnej.\r\nOCT2HEX\t\t\t= OCT2HEX\t\t\t##\tKonwertuje liczbę w postaci ósemkowej na liczbę w postaci szesnastkowej.\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\tFunkcje finansowe\r\n##\r\nACCRINT\t\t\t= ACCRINT\t\t\t##\tZwraca narosłe odsetki dla papieru wartościowego z oprocentowaniem okresowym.\r\nACCRINTM\t\t= ACCRINTM\t\t\t##\tZwraca narosłe odsetki dla papieru wartościowego z oprocentowaniem w terminie wykupu.\r\nAMORDEGRC\t\t= AMORDEGRC\t\t\t##\tZwraca amortyzację dla każdego okresu rozliczeniowego z wykorzystaniem współczynnika amortyzacji.\r\nAMORLINC\t\t= AMORLINC\t\t\t##\tZwraca amortyzację dla każdego okresu rozliczeniowego.\r\nCOUPDAYBS\t\t= COUPDAYBS\t\t\t##\tZwraca liczbę dni od początku okresu dywidendy do dnia rozliczeniowego.\r\nCOUPDAYS\t\t= COUPDAYS\t\t\t##\tZwraca liczbę dni w okresie dywidendy, z uwzględnieniem dnia rozliczeniowego.\r\nCOUPDAYSNC\t\t= COUPDAYSNC\t\t\t##\tZwraca liczbę dni od dnia rozliczeniowego do daty następnego dnia dywidendy.\r\nCOUPNCD\t\t\t= COUPNCD\t\t\t##\tZwraca dzień następnej dywidendy po dniu rozliczeniowym.\r\nCOUPNUM\t\t\t= COUPNUM\t\t\t##\tZwraca liczbę dywidend płatnych między dniem rozliczeniowym a dniem wykupu.\r\nCOUPPCD\t\t\t= COUPPCD\t\t\t##\tZwraca dzień poprzedniej dywidendy przed dniem rozliczeniowym.\r\nCUMIPMT\t\t\t= CUMIPMT\t\t\t##\tZwraca wartość procentu składanego płatnego między dwoma okresami.\r\nCUMPRINC\t\t= CUMPRINC\t\t\t##\tZwraca wartość kapitału skumulowanego spłaty pożyczki między dwoma okresami.\r\nDB\t\t\t= DB\t\t\t\t##\tZwraca amortyzację środka trwałego w danym okresie metodą degresywną z zastosowaniem stałej bazowej.\r\nDDB\t\t\t= DDB\t\t\t\t##\tZwraca amortyzację środka trwałego za podany okres metodą degresywną z zastosowaniem podwójnej bazowej lub metodą określoną przez użytkownika.\r\nDISC\t\t\t= DISC\t\t\t\t##\tZwraca wartość stopy dyskontowej papieru wartościowego.\r\nDOLLARDE\t\t= DOLLARDE\t\t\t##\tKonwertuje cenę w postaci ułamkowej na cenę wyrażoną w postaci dziesiętnej.\r\nDOLLARFR\t\t= DOLLARFR\t\t\t##\tKonwertuje cenę wyrażoną w postaci dziesiętnej na cenę wyrażoną w postaci ułamkowej.\r\nDURATION\t\t= DURATION\t\t\t##\tZwraca wartość rocznego przychodu z papieru wartościowego o okresowych wypłatach oprocentowania.\r\nEFFECT\t\t\t= EFFECT\t\t\t##\tZwraca wartość efektywnej rocznej stopy procentowej.\r\nFV\t\t\t= FV\t\t\t\t##\tZwraca przyszłą wartość lokaty.\r\nFVSCHEDULE\t\t= FVSCHEDULE\t\t\t##\tZwraca przyszłą wartość kapitału początkowego wraz z szeregiem procentów składanych.\r\nINTRATE\t\t\t= INTRATE\t\t\t##\tZwraca wartość stopy procentowej papieru wartościowego całkowicie ulokowanego.\r\nIPMT\t\t\t= IPMT\t\t\t\t##\tZwraca wysokość spłaty oprocentowania lokaty za dany okres.\r\nIRR\t\t\t= IRR\t\t\t\t##\tZwraca wartość wewnętrznej stopy zwrotu dla serii przepływów gotówkowych.\r\nISPMT\t\t\t= ISPMT\t\t\t\t##\tOblicza wysokość spłaty oprocentowania za dany okres lokaty.\r\nMDURATION\t\t= MDURATION\t\t\t##\tZwraca wartość zmodyfikowanego okresu Macauleya dla papieru wartościowego o założonej wartości nominalnej 100 zł.\r\nMIRR\t\t\t= MIRR\t\t\t\t##\tZwraca wartość wewnętrznej stopy zwrotu dla przypadku, gdy dodatnie i ujemne przepływy gotówkowe mają różne stopy.\r\nNOMINAL\t\t\t= NOMINAL\t\t\t##\tZwraca wysokość nominalnej rocznej stopy procentowej.\r\nNPER\t\t\t= NPER\t\t\t\t##\tZwraca liczbę okresów dla lokaty.\r\nNPV\t\t\t= NPV\t\t\t\t##\tZwraca wartość bieżącą netto lokaty na podstawie szeregu okresowych przepływów gotówkowych i stopy dyskontowej.\r\nODDFPRICE\t\t= ODDFPRICE\t\t\t##\tZwraca cenę za 100 zł wartości nominalnej papieru wartościowego z nietypowym pierwszym okresem.\r\nODDFYIELD\t\t= ODDFYIELD\t\t\t##\tZwraca rentowność papieru wartościowego z nietypowym pierwszym okresem.\r\nODDLPRICE\t\t= ODDLPRICE\t\t\t##\tZwraca cenę za 100 zł wartości nominalnej papieru wartościowego z nietypowym ostatnim okresem.\r\nODDLYIELD\t\t= ODDLYIELD\t\t\t##\tZwraca rentowność papieru wartościowego z nietypowym ostatnim okresem.\r\nPMT\t\t\t= PMT\t\t\t\t##\tZwraca wartość okresowej płatności raty rocznej.\r\nPPMT\t\t\t= PPMT\t\t\t\t##\tZwraca wysokość spłaty kapitału w przypadku lokaty dla danego okresu.\r\nPRICE\t\t\t= PRICE\t\t\t\t##\tZwraca cenę za 100 zł wartości nominalnej papieru wartościowego z oprocentowaniem okresowym.\r\nPRICEDISC\t\t= PRICEDISC\t\t\t##\tZwraca cenę za 100 zł wartości nominalnej papieru wartościowego zdyskontowanego.\r\nPRICEMAT\t\t= PRICEMAT\t\t\t##\tZwraca cenę za 100 zł wartości nominalnej papieru wartościowego z oprocentowaniem w terminie wykupu.\r\nPV\t\t\t= PV\t\t\t\t##\tZwraca wartość bieżącą lokaty.\r\nRATE\t\t\t= RATE\t\t\t\t##\tZwraca wysokość stopy procentowej w okresie raty rocznej.\r\nRECEIVED\t\t= RECEIVED\t\t\t##\tZwraca wartość kapitału otrzymanego przy wykupie papieru wartościowego całkowicie ulokowanego.\r\nSLN\t\t\t= SLN\t\t\t\t##\tZwraca amortyzację środka trwałego za jeden okres metodą liniową.\r\nSYD\t\t\t= SYD\t\t\t\t##\tZwraca amortyzację środka trwałego za dany okres metodą sumy cyfr lat amortyzacji.\r\nTBILLEQ\t\t\t= TBILLEQ\t\t\t##\tZwraca rentowność ekwiwalentu obligacji dla bonu skarbowego.\r\nTBILLPRICE\t\t= TBILLPRICE\t\t\t##\tZwraca cenę za 100 zł wartości nominalnej bonu skarbowego.\r\nTBILLYIELD\t\t= TBILLYIELD\t\t\t##\tZwraca rentowność bonu skarbowego.\r\nVDB\t\t\t= VDB\t\t\t\t##\tOblicza amortyzację środka trwałego w danym okresie lub jego części metodą degresywną.\r\nXIRR\t\t\t= XIRR\t\t\t\t##\tZwraca wartość wewnętrznej stopy zwrotu dla serii rozłożonych w czasie przepływów gotówkowych, niekoniecznie okresowych.\r\nXNPV\t\t\t= XNPV\t\t\t\t##\tZwraca wartość bieżącą netto dla serii rozłożonych w czasie przepływów gotówkowych, niekoniecznie okresowych.\r\nYIELD\t\t\t= YIELD\t\t\t\t##\tZwraca rentowność papieru wartościowego z oprocentowaniem okresowym.\r\nYIELDDISC\t\t= YIELDDISC\t\t\t##\tZwraca roczną rentowność zdyskontowanego papieru wartościowego, na przykład bonu skarbowego.\r\nYIELDMAT\t\t= YIELDMAT\t\t\t##\tZwraca roczną rentowność papieru wartościowego oprocentowanego przy wykupie.\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\tFunkcje informacyjne\r\n##\r\nCELL\t\t\t= KOMÓRKA\t\t\t##\tZwraca informacje o formacie, położeniu lub zawartości komórki.\r\nERROR.TYPE\t\t= NR.BŁĘDU\t\t\t##\tZwraca liczbę odpowiadającą typowi błędu.\r\nINFO\t\t\t= INFO\t\t\t\t##\tZwraca informację o aktualnym środowisku pracy.\r\nISBLANK\t\t\t= CZY.PUSTA\t\t\t##\tZwraca wartość PRAWDA, jeśli wartość jest pusta.\r\nISERR\t\t\t= CZY.BŁ\t\t\t##\tZwraca wartość PRAWDA, jeśli wartość jest dowolną wartością błędu, z wyjątkiem #N/D!.\r\nISERROR\t\t\t= CZY.BŁĄD\t\t\t##\tZwraca wartość PRAWDA, jeśli wartość jest dowolną wartością błędu.\r\nISEVEN\t\t\t= ISEVEN\t\t\t##\tZwraca wartość PRAWDA, jeśli liczba jest parzysta.\r\nISLOGICAL\t\t= CZY.LOGICZNA\t\t\t##\tZwraca wartość PRAWDA, jeśli wartość jest wartością logiczną.\r\nISNA\t\t\t= CZY.BRAK\t\t\t##\tZwraca wartość PRAWDA, jeśli wartość jest wartością błędu #N/D!.\r\nISNONTEXT\t\t= CZY.NIE.TEKST\t\t\t##\tZwraca wartość PRAWDA, jeśli wartość nie jest tekstem.\r\nISNUMBER\t\t= CZY.LICZBA\t\t\t##\tZwraca wartość PRAWDA, jeśli wartość jest liczbą.\r\nISODD\t\t\t= ISODD\t\t\t\t##\tZwraca wartość PRAWDA, jeśli liczba jest nieparzysta.\r\nISREF\t\t\t= CZY.ADR\t\t\t##\tZwraca wartość PRAWDA, jeśli wartość jest odwołaniem.\r\nISTEXT\t\t\t= CZY.TEKST\t\t\t##\tZwraca wartość PRAWDA, jeśli wartość jest tekstem.\r\nN\t\t\t= L\t\t\t\t##\tZwraca wartość przekonwertowaną na postać liczbową.\r\nNA\t\t\t= BRAK\t\t\t\t##\tZwraca wartość błędu #N/D!.\r\nTYPE\t\t\t= TYP\t\t\t\t##\tZwraca liczbę wskazującą typ danych wartości.\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\tFunkcje logiczne\r\n##\r\nAND\t\t\t= ORAZ\t\t\t\t##\tZwraca wartość PRAWDA, jeśli wszystkie argumenty mają wartość PRAWDA.\r\nFALSE\t\t\t= FAŁSZ\t\t\t\t##\tZwraca wartość logiczną FAŁSZ.\r\nIF\t\t\t= JEŻELI\t\t\t##\tOkreśla warunek logiczny do sprawdzenia.\r\nIFERROR\t\t\t= JEŻELI.BŁĄD\t\t\t##\tZwraca określoną wartość, jeśli wynikiem obliczenia formuły jest błąd; w przeciwnym przypadku zwraca wynik formuły.\r\nNOT\t\t\t= NIE\t\t\t\t##\tOdwraca wartość logiczną argumentu.\r\nOR\t\t\t= LUB\t\t\t\t##\tZwraca wartość PRAWDA, jeśli co najmniej jeden z argumentów ma wartość PRAWDA.\r\nTRUE\t\t\t= PRAWDA\t\t\t##\tZwraca wartość logiczną PRAWDA.\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\tFunkcje wyszukiwania i odwołań\r\n##\r\nADDRESS\t\t\t= ADRES\t\t\t\t##\tZwraca odwołanie do jednej komórki w arkuszu jako wartość tekstową.\r\nAREAS\t\t\t= OBSZARY\t\t\t##\tZwraca liczbę obszarów występujących w odwołaniu.\r\nCHOOSE\t\t\t= WYBIERZ\t\t\t##\tWybiera wartość z listy wartości.\r\nCOLUMN\t\t\t= NR.KOLUMNY\t\t\t##\tZwraca numer kolumny z odwołania.\r\nCOLUMNS\t\t\t= LICZBA.KOLUMN\t\t\t##\tZwraca liczbę kolumn dla danego odwołania.\r\nHLOOKUP\t\t\t= WYSZUKAJ.POZIOMO\t\t##\tPrzegląda górny wiersz tablicy i zwraca wartość wskazanej komórki.\r\nHYPERLINK\t\t= HIPERŁĄCZE\t\t\t##\tTworzy skrót lub skok, który pozwala otwierać dokument przechowywany na serwerze sieciowym, w sieci intranet lub w Internecie.\r\nINDEX\t\t\t= INDEKS\t\t\t##\tUżywa indeksu do wybierania wartości z odwołania lub tablicy.\r\nINDIRECT\t\t= ADR.POŚR\t\t\t##\tZwraca odwołanie określone przez wartość tekstową.\r\nLOOKUP\t\t\t= WYSZUKAJ\t\t\t##\tWyszukuje wartości w wektorze lub tablicy.\r\nMATCH\t\t\t= PODAJ.POZYCJĘ\t\t\t##\tWyszukuje wartości w odwołaniu lub w tablicy.\r\nOFFSET\t\t\t= PRZESUNIĘCIE\t\t\t##\tZwraca adres przesunięty od danego odwołania.\r\nROW\t\t\t= WIERSZ\t\t\t##\tZwraca numer wiersza odwołania.\r\nROWS\t\t\t= ILE.WIERSZY\t\t\t##\tZwraca liczbę wierszy dla danego odwołania.\r\nRTD\t\t\t= RTD\t\t\t\t##\tPobiera dane w czasie rzeczywistym z programu obsługującego automatyzację COM (Automatyzacja: Sposób pracy z obiektami aplikacji pochodzącymi z innej aplikacji lub narzędzia projektowania. Nazywana wcześniej Automatyzacją OLE, Automatyzacja jest standardem przemysłowym i funkcją obiektowego modelu składników (COM, Component Object Model).).\r\nTRANSPOSE\t\t= TRANSPONUJ\t\t\t##\tZwraca transponowaną tablicę.\r\nVLOOKUP\t\t\t= WYSZUKAJ.PIONOWO\t\t##\tPrzeszukuje pierwszą kolumnę tablicy i przechodzi wzdłuż wiersza, aby zwrócić wartość komórki.\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\tFunkcje matematyczne i trygonometryczne\r\n##\r\nABS\t\t\t= MODUŁ.LICZBY\t\t\t##\tZwraca wartość absolutną liczby.\r\nACOS\t\t\t= ACOS\t\t\t\t##\tZwraca arcus cosinus liczby.\r\nACOSH\t\t\t= ACOSH\t\t\t\t##\tZwraca arcus cosinus hiperboliczny liczby.\r\nASIN\t\t\t= ASIN\t\t\t\t##\tZwraca arcus sinus liczby.\r\nASINH\t\t\t= ASINH\t\t\t\t##\tZwraca arcus sinus hiperboliczny liczby.\r\nATAN\t\t\t= ATAN\t\t\t\t##\tZwraca arcus tangens liczby.\r\nATAN2\t\t\t= ATAN2\t\t\t\t##\tZwraca arcus tangens liczby na podstawie współrzędnych x i y.\r\nATANH\t\t\t= ATANH\t\t\t\t##\tZwraca arcus tangens hiperboliczny liczby.\r\nCEILING\t\t\t= ZAOKR.W.GÓRĘ\t\t\t##\tZaokrągla liczbę do najbliższej liczby całkowitej lub do najbliższej wielokrotności dokładności.\r\nCOMBIN\t\t\t= KOMBINACJE\t\t\t##\tZwraca liczbę kombinacji dla danej liczby obiektów.\r\nCOS\t\t\t= COS\t\t\t\t##\tZwraca cosinus liczby.\r\nCOSH\t\t\t= COSH\t\t\t\t##\tZwraca cosinus hiperboliczny liczby.\r\nDEGREES\t\t\t= STOPNIE\t\t\t##\tKonwertuje radiany na stopnie.\r\nEVEN\t\t\t= ZAOKR.DO.PARZ\t\t\t##\tZaokrągla liczbę w górę do najbliższej liczby parzystej.\r\nEXP\t\t\t= EXP\t\t\t\t##\tZwraca wartość liczby e podniesionej do potęgi określonej przez podaną liczbę.\r\nFACT\t\t\t= SILNIA\t\t\t##\tZwraca silnię liczby.\r\nFACTDOUBLE\t\t= FACTDOUBLE\t\t\t##\tZwraca podwójną silnię liczby.\r\nFLOOR\t\t\t= ZAOKR.W.DÓŁ\t\t\t##\tZaokrągla liczbę w dół, w kierunku zera.\r\nGCD\t\t\t= GCD\t\t\t\t##\tZwraca największy wspólny dzielnik.\r\nINT\t\t\t= ZAOKR.DO.CAŁK\t\t\t##\tZaokrągla liczbę w dół do najbliższej liczby całkowitej.\r\nLCM\t\t\t= LCM\t\t\t\t##\tZwraca najmniejszą wspólną wielokrotność.\r\nLN\t\t\t= LN\t\t\t\t##\tZwraca logarytm naturalny podanej liczby.\r\nLOG\t\t\t= LOG\t\t\t\t##\tZwraca logarytm danej liczby przy zadanej podstawie.\r\nLOG10\t\t\t= LOG10\t\t\t\t##\tZwraca logarytm dziesiętny liczby.\r\nMDETERM\t\t\t= WYZNACZNIK.MACIERZY\t\t##\tZwraca wyznacznik macierzy tablicy.\r\nMINVERSE\t\t= MACIERZ.ODW\t\t\t##\tZwraca odwrotność macierzy tablicy.\r\nMMULT\t\t\t= MACIERZ.ILOCZYN\t\t##\tZwraca iloczyn macierzy dwóch tablic.\r\nMOD\t\t\t= MOD\t\t\t\t##\tZwraca resztę z dzielenia.\r\nMROUND\t\t\t= MROUND\t\t\t##\tZwraca liczbę zaokrągloną do żądanej wielokrotności.\r\nMULTINOMIAL\t\t= MULTINOMIAL\t\t\t##\tZwraca wielomian dla zbioru liczb.\r\nODD\t\t\t= ZAOKR.DO.NPARZ\t\t##\tZaokrągla liczbę w górę do najbliższej liczby nieparzystej.\r\nPI\t\t\t= PI\t\t\t\t##\tZwraca wartość liczby Pi.\r\nPOWER\t\t\t= POTĘGA\t\t\t##\tZwraca liczbę podniesioną do potęgi.\r\nPRODUCT\t\t\t= ILOCZYN\t\t\t##\tMnoży argumenty.\r\nQUOTIENT\t\t= QUOTIENT\t\t\t##\tZwraca iloraz (całkowity).\r\nRADIANS\t\t\t= RADIANY\t\t\t##\tKonwertuje stopnie na radiany.\r\nRAND\t\t\t= LOS\t\t\t\t##\tZwraca liczbę pseudolosową z zakresu od 0 do 1.\r\nRANDBETWEEN\t\t= RANDBETWEEN\t\t\t##\tZwraca liczbę pseudolosową z zakresu określonego przez podane argumenty.\r\nROMAN\t\t\t= RZYMSKIE\t\t\t##\tKonwertuje liczbę arabską na rzymską jako tekst.\r\nROUND\t\t\t= ZAOKR\t\t\t\t##\tZaokrągla liczbę do określonej liczby cyfr.\r\nROUNDDOWN\t\t= ZAOKR.DÓŁ\t\t\t##\tZaokrągla liczbę w dół, w kierunku zera.\r\nROUNDUP\t\t\t= ZAOKR.GÓRA\t\t\t##\tZaokrągla liczbę w górę, w kierunku od zera.\r\nSERIESSUM\t\t= SERIESSUM\t\t\t##\tZwraca sumę szeregu potęgowego na podstawie wzoru.\r\nSIGN\t\t\t= ZNAK.LICZBY\t\t\t##\tZwraca znak liczby.\r\nSIN\t\t\t= SIN\t\t\t\t##\tZwraca sinus danego kąta.\r\nSINH\t\t\t= SINH\t\t\t\t##\tZwraca sinus hiperboliczny liczby.\r\nSQRT\t\t\t= PIERWIASTEK\t\t\t##\tZwraca dodatni pierwiastek kwadratowy.\r\nSQRTPI\t\t\t= SQRTPI\t\t\t##\tZwraca pierwiastek kwadratowy iloczynu (liczba * Pi).\r\nSUBTOTAL\t\t= SUMY.POŚREDNIE\t\t##\tZwraca sumę częściową listy lub bazy danych.\r\nSUM\t\t\t= SUMA\t\t\t\t##\tDodaje argumenty.\r\nSUMIF\t\t\t= SUMA.JEŻELI\t\t\t##\tDodaje komórki określone przez podane kryterium.\r\nSUMIFS\t\t\t= SUMA.WARUNKÓW\t\t\t##\tDodaje komórki w zakresie, które spełniają wiele kryteriów.\r\nSUMPRODUCT\t\t= SUMA.ILOCZYNÓW\t\t##\tZwraca sumę iloczynów odpowiednich elementów tablicy.\r\nSUMSQ\t\t\t= SUMA.KWADRATÓW\t\t##\tZwraca sumę kwadratów argumentów.\r\nSUMX2MY2\t\t= SUMA.X2.M.Y2\t\t\t##\tZwraca sumę różnic kwadratów odpowiednich wartości w dwóch tablicach.\r\nSUMX2PY2\t\t= SUMA.X2.P.Y2\t\t\t##\tZwraca sumę sum kwadratów odpowiednich wartości w dwóch tablicach.\r\nSUMXMY2\t\t\t= SUMA.XMY.2\t\t\t##\tZwraca sumę kwadratów różnic odpowiednich wartości w dwóch tablicach.\r\nTAN\t\t\t= TAN\t\t\t\t##\tZwraca tangens liczby.\r\nTANH\t\t\t= TANH\t\t\t\t##\tZwraca tangens hiperboliczny liczby.\r\nTRUNC\t\t\t= LICZBA.CAŁK\t\t\t##\tPrzycina liczbę do wartości całkowitej.\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\tFunkcje statystyczne\r\n##\r\nAVEDEV\t\t\t= ODCH.ŚREDNIE\t\t\t##\tZwraca średnią wartość odchyleń absolutnych punktów danych od ich wartości średniej.\r\nAVERAGE\t\t\t= ŚREDNIA\t\t\t##\tZwraca wartość średnią argumentów.\r\nAVERAGEA\t\t= ŚREDNIA.A\t\t\t##\tZwraca wartość średnią argumentów, z uwzględnieniem liczb, tekstów i wartości logicznych.\r\nAVERAGEIF\t\t= ŚREDNIA.JEŻELI\t\t##\tZwraca średnią (średnią arytmetyczną) wszystkich komórek w zakresie, które spełniają podane kryteria.\r\nAVERAGEIFS\t\t= ŚREDNIA.WARUNKÓW\t\t##\tZwraca średnią (średnią arytmetyczną) wszystkich komórek, które spełniają jedno lub więcej kryteriów.\r\nBETADIST\t\t= ROZKŁAD.BETA\t\t\t##\tZwraca skumulowaną funkcję gęstości prawdopodobieństwa beta.\r\nBETAINV\t\t\t= ROZKŁAD.BETA.ODW\t\t##\tZwraca odwrotność skumulowanej funkcji gęstości prawdopodobieństwa beta.\r\nBINOMDIST\t\t= ROZKŁAD.DWUM\t\t\t##\tZwraca pojedynczy składnik dwumianowego rozkładu prawdopodobieństwa.\r\nCHIDIST\t\t\t= ROZKŁAD.CHI\t\t\t##\tZwraca wartość jednostronnego prawdopodobieństwa rozkładu chi-kwadrat.\r\nCHIINV\t\t\t= ROZKŁAD.CHI.ODW\t\t##\tZwraca odwrotność wartości jednostronnego prawdopodobieństwa rozkładu chi-kwadrat.\r\nCHITEST\t\t\t= TEST.CHI\t\t\t##\tZwraca test niezależności.\r\nCONFIDENCE\t\t= UFNOŚĆ\t\t\t##\tZwraca interwał ufności dla średniej populacji.\r\nCORREL\t\t\t= WSP.KORELACJI\t\t\t##\tZwraca współczynnik korelacji dwóch zbiorów danych.\r\nCOUNT\t\t\t= ILE.LICZB\t\t\t##\tZlicza liczby znajdujące się na liście argumentów.\r\nCOUNTA\t\t\t= ILE.NIEPUSTYCH\t\t##\tZlicza wartości znajdujące się na liście argumentów.\r\nCOUNTBLANK\t\t= LICZ.PUSTE\t\t\t##\tZwraca liczbę pustych komórek w pewnym zakresie.\r\nCOUNTIF\t\t\t= LICZ.JEŻELI\t\t\t##\tZlicza komórki wewnątrz zakresu, które spełniają podane kryteria.\r\nCOUNTIFS\t\t= LICZ.WARUNKI\t\t\t##\tZlicza komórki wewnątrz zakresu, które spełniają wiele kryteriów.\r\nCOVAR\t\t\t= KOWARIANCJA\t\t\t##\tZwraca kowariancję, czyli średnią wartość iloczynów odpowiednich odchyleń.\r\nCRITBINOM\t\t= PRÓG.ROZKŁAD.DWUM\t\t##\tZwraca najmniejszą wartość, dla której skumulowany rozkład dwumianowy jest mniejszy niż wartość kryterium lub równy jej.\r\nDEVSQ\t\t\t= ODCH.KWADRATOWE\t\t##\tZwraca sumę kwadratów odchyleń.\r\nEXPONDIST\t\t= ROZKŁAD.EXP\t\t\t##\tZwraca rozkład wykładniczy.\r\nFDIST\t\t\t= ROZKŁAD.F\t\t\t##\tZwraca rozkład prawdopodobieństwa F.\r\nFINV\t\t\t= ROZKŁAD.F.ODW\t\t\t##\tZwraca odwrotność rozkładu prawdopodobieństwa F.\r\nFISHER\t\t\t= ROZKŁAD.FISHER\t\t##\tZwraca transformację Fishera.\r\nFISHERINV\t\t= ROZKŁAD.FISHER.ODW\t\t##\tZwraca odwrotność transformacji Fishera.\r\nFORECAST\t\t= REGLINX\t\t\t##\tZwraca wartość trendu liniowego.\r\nFREQUENCY\t\t= CZĘSTOŚĆ\t\t\t##\tZwraca rozkład częstotliwości jako tablicę pionową.\r\nFTEST\t\t\t= TEST.F\t\t\t##\tZwraca wynik testu F.\r\nGAMMADIST\t\t= ROZKŁAD.GAMMA\t\t\t##\tZwraca rozkład gamma.\r\nGAMMAINV\t\t= ROZKŁAD.GAMMA.ODW\t\t##\tZwraca odwrotność skumulowanego rozkładu gamma.\r\nGAMMALN\t\t\t= ROZKŁAD.LIN.GAMMA\t\t##\tZwraca logarytm naturalny funkcji gamma, Γ(x).\r\nGEOMEAN\t\t\t= ŚREDNIA.GEOMETRYCZNA\t\t##\tZwraca średnią geometryczną.\r\nGROWTH\t\t\t= REGEXPW\t\t\t##\tZwraca wartości trendu wykładniczego.\r\nHARMEAN\t\t\t= ŚREDNIA.HARMONICZNA\t\t##\tZwraca średnią harmoniczną.\r\nHYPGEOMDIST\t\t= ROZKŁAD.HIPERGEOM\t\t##\tZwraca rozkład hipergeometryczny.\r\nINTERCEPT\t\t= ODCIĘTA\t\t\t##\tZwraca punkt przecięcia osi pionowej z linią regresji liniowej.\r\nKURT\t\t\t= KURTOZA\t\t\t##\tZwraca kurtozę zbioru danych.\r\nLARGE\t\t\t= MAX.K\t\t\t\t##\tZwraca k-tą największą wartość ze zbioru danych.\r\nLINEST\t\t\t= REGLINP\t\t\t##\tZwraca parametry trendu liniowego.\r\nLOGEST\t\t\t= REGEXPP\t\t\t##\tZwraca parametry trendu wykładniczego.\r\nLOGINV\t\t\t= ROZKŁAD.LOG.ODW\t\t##\tZwraca odwrotność rozkładu logarytmu naturalnego.\r\nLOGNORMDIST\t\t= ROZKŁAD.LOG\t\t\t##\tZwraca skumulowany rozkład logarytmu naturalnego.\r\nMAX\t\t\t= MAX\t\t\t\t##\tZwraca maksymalną wartość listy argumentów.\r\nMAXA\t\t\t= MAX.A\t\t\t\t##\tZwraca maksymalną wartość listy argumentów, z uwzględnieniem liczb, tekstów i wartości logicznych.\r\nMEDIAN\t\t\t= MEDIANA\t\t\t##\tZwraca medianę podanych liczb.\r\nMIN\t\t\t= MIN\t\t\t\t##\tZwraca minimalną wartość listy argumentów.\r\nMINA\t\t\t= MIN.A\t\t\t\t##\tZwraca najmniejszą wartość listy argumentów, z uwzględnieniem liczb, tekstów i wartości logicznych.\r\nMODE\t\t\t= WYST.NAJCZĘŚCIEJ\t\t##\tZwraca wartość najczęściej występującą w zbiorze danych.\r\nNEGBINOMDIST\t\t= ROZKŁAD.DWUM.PRZEC\t\t##\tZwraca ujemny rozkład dwumianowy.\r\nNORMDIST\t\t= ROZKŁAD.NORMALNY\t\t##\tZwraca rozkład normalny skumulowany.\r\nNORMINV\t\t\t= ROZKŁAD.NORMALNY.ODW\t\t##\tZwraca odwrotność rozkładu normalnego skumulowanego.\r\nNORMSDIST\t\t= ROZKŁAD.NORMALNY.S\t\t##\tZwraca standardowy rozkład normalny skumulowany.\r\nNORMSINV\t\t= ROZKŁAD.NORMALNY.S.ODW\t##\tZwraca odwrotność standardowego rozkładu normalnego skumulowanego.\r\nPEARSON\t\t\t= PEARSON\t\t\t##\tZwraca współczynnik korelacji momentu iloczynu Pearsona.\r\nPERCENTILE\t\t= PERCENTYL\t\t\t##\tWyznacza k-ty percentyl wartości w zakresie.\r\nPERCENTRANK\t\t= PROCENT.POZYCJA\t\t##\tZwraca procentową pozycję wartości w zbiorze danych.\r\nPERMUT\t\t\t= PERMUTACJE\t\t\t##\tZwraca liczbę permutacji dla danej liczby obiektów.\r\nPOISSON\t\t\t= ROZKŁAD.POISSON\t\t##\tZwraca rozkład Poissona.\r\nPROB\t\t\t= PRAWDPD\t\t\t##\tZwraca prawdopodobieństwo, że wartości w zakresie leżą pomiędzy dwiema granicami.\r\nQUARTILE\t\t= KWARTYL\t\t\t##\tWyznacza kwartyl zbioru danych.\r\nRANK\t\t\t= POZYCJA\t\t\t##\tZwraca pozycję liczby na liście liczb.\r\nRSQ\t\t\t= R.KWADRAT\t\t\t##\tZwraca kwadrat współczynnika korelacji momentu iloczynu Pearsona.\r\nSKEW\t\t\t= SKOŚNOŚĆ\t\t\t##\tZwraca skośność rozkładu.\r\nSLOPE\t\t\t= NACHYLENIE\t\t\t##\tZwraca nachylenie linii regresji liniowej.\r\nSMALL\t\t\t= MIN.K\t\t\t\t##\tZwraca k-tą najmniejszą wartość ze zbioru danych.\r\nSTANDARDIZE\t\t= NORMALIZUJ\t\t\t##\tZwraca wartość znormalizowaną.\r\nSTDEV\t\t\t= ODCH.STANDARDOWE\t\t##\tSzacuje odchylenie standardowe na podstawie próbki.\r\nSTDEVA\t\t\t= ODCH.STANDARDOWE.A\t\t##\tSzacuje odchylenie standardowe na podstawie próbki, z uwzględnieniem liczb, tekstów i wartości logicznych.\r\nSTDEVP\t\t\t= ODCH.STANDARD.POPUL\t\t##\tOblicza odchylenie standardowe na podstawie całej populacji.\r\nSTDEVPA\t\t\t= ODCH.STANDARD.POPUL.A\t\t##\tOblicza odchylenie standardowe na podstawie całej populacji, z uwzględnieniem liczb, teksów i wartości logicznych.\r\nSTEYX\t\t\t= REGBŁSTD\t\t\t##\tZwraca błąd standardowy przewidzianej wartości y dla każdej wartości x w regresji.\r\nTDIST\t\t\t= ROZKŁAD.T\t\t\t##\tZwraca rozkład t-Studenta.\r\nTINV\t\t\t= ROZKŁAD.T.ODW\t\t\t##\tZwraca odwrotność rozkładu t-Studenta.\r\nTREND\t\t\t= REGLINW\t\t\t##\tZwraca wartości trendu liniowego.\r\nTRIMMEAN\t\t= ŚREDNIA.WEWN\t\t\t##\tZwraca średnią wartość dla wnętrza zbioru danych.\r\nTTEST\t\t\t= TEST.T\t\t\t##\tZwraca prawdopodobieństwo związane z testem t-Studenta.\r\nVAR\t\t\t= WARIANCJA\t\t\t##\tSzacuje wariancję na podstawie próbki.\r\nVARA\t\t\t= WARIANCJA.A\t\t\t##\tSzacuje wariancję na podstawie próbki, z uwzględnieniem liczb, tekstów i wartości logicznych.\r\nVARP\t\t\t= WARIANCJA.POPUL\t\t##\tOblicza wariancję na podstawie całej populacji.\r\nVARPA\t\t\t= WARIANCJA.POPUL.A\t\t##\tOblicza wariancję na podstawie całej populacji, z uwzględnieniem liczb, tekstów i wartości logicznych.\r\nWEIBULL\t\t\t= ROZKŁAD.WEIBULL\t\t##\tZwraca rozkład Weibulla.\r\nZTEST\t\t\t= TEST.Z\t\t\t##\tZwraca wartość jednostronnego prawdopodobieństwa testu z.\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\tFunkcje tekstowe\r\n##\r\nASC\t\t\t= ASC\t\t\t\t##\tZamienia litery angielskie lub katakana o pełnej szerokości (dwubajtowe) w ciągu znaków na znaki o szerokości połówkowej (jednobajtowe).\r\nBAHTTEXT\t\t= BAHTTEXT\t\t\t##\tKonwertuje liczbę na tekst, stosując format walutowy ß (baht).\r\nCHAR\t\t\t= ZNAK\t\t\t\t##\tZwraca znak o podanym numerze kodu.\r\nCLEAN\t\t\t= OCZYŚĆ\t\t\t##\tUsuwa z tekstu wszystkie znaki, które nie mogą być drukowane.\r\nCODE\t\t\t= KOD\t\t\t\t##\tZwraca kod numeryczny pierwszego znaku w ciągu tekstowym.\r\nCONCATENATE\t\t= ZŁĄCZ.TEKSTY\t\t\t##\tŁączy kilka oddzielnych tekstów w jeden tekst.\r\nDOLLAR\t\t\t= KWOTA\t\t\t\t##\tKonwertuje liczbę na tekst, stosując format walutowy $ (dolar).\r\nEXACT\t\t\t= PORÓWNAJ\t\t\t##\tSprawdza identyczność dwóch wartości tekstowych.\r\nFIND\t\t\t= ZNAJDŹ\t\t\t##\tZnajduje jedną wartość tekstową wewnątrz innej (z uwzględnieniem wielkich i małych liter).\r\nFINDB\t\t\t= ZNAJDŹB\t\t\t##\tZnajduje jedną wartość tekstową wewnątrz innej (z uwzględnieniem wielkich i małych liter).\r\nFIXED\t\t\t= ZAOKR.DO.TEKST\t\t##\tFormatuje liczbę jako tekst przy stałej liczbie miejsc dziesiętnych.\r\nJIS\t\t\t= JIS\t\t\t\t##\tZmienia litery angielskie lub katakana o szerokości połówkowej (jednobajtowe) w ciągu znaków na znaki o pełnej szerokości (dwubajtowe).\r\nLEFT\t\t\t= LEWY\t\t\t\t##\tZwraca skrajne lewe znaki z wartości tekstowej.\r\nLEFTB\t\t\t= LEWYB\t\t\t\t##\tZwraca skrajne lewe znaki z wartości tekstowej.\r\nLEN\t\t\t= DŁ\t\t\t\t##\tZwraca liczbę znaków ciągu tekstowego.\r\nLENB\t\t\t= DŁ.B\t\t\t\t##\tZwraca liczbę znaków ciągu tekstowego.\r\nLOWER\t\t\t= LITERY.MAŁE\t\t\t##\tKonwertuje wielkie litery tekstu na małe litery.\r\nMID\t\t\t= FRAGMENT.TEKSTU\t\t##\tZwraca określoną liczbę znaków z ciągu tekstowego, zaczynając od zadanej pozycji.\r\nMIDB\t\t\t= FRAGMENT.TEKSTU.B\t\t##\tZwraca określoną liczbę znaków z ciągu tekstowego, zaczynając od zadanej pozycji.\r\nPHONETIC\t\t= PHONETIC\t\t\t##\tWybiera znaki fonetyczne (furigana) z ciągu tekstowego.\r\nPROPER\t\t\t= Z.WIELKIEJ.LITERY\t\t##\tZastępuje pierwszą literę każdego wyrazu tekstu wielką literą.\r\nREPLACE\t\t\t= ZASTĄP\t\t\t##\tZastępuje znaki w tekście.\r\nREPLACEB\t\t= ZASTĄP.B\t\t\t##\tZastępuje znaki w tekście.\r\nREPT\t\t\t= POWT\t\t\t\t##\tPowiela tekst daną liczbę razy.\r\nRIGHT\t\t\t= PRAWY\t\t\t\t##\tZwraca skrajne prawe znaki z wartości tekstowej.\r\nRIGHTB\t\t\t= PRAWYB\t\t\t##\tZwraca skrajne prawe znaki z wartości tekstowej.\r\nSEARCH\t\t\t= SZUKAJ.TEKST\t\t\t##\tWyszukuje jedną wartość tekstową wewnątrz innej (bez uwzględniania wielkości liter).\r\nSEARCHB\t\t\t= SZUKAJ.TEKST.B\t\t##\tWyszukuje jedną wartość tekstową wewnątrz innej (bez uwzględniania wielkości liter).\r\nSUBSTITUTE\t\t= PODSTAW\t\t\t##\tPodstawia nowy tekst w miejsce poprzedniego tekstu w ciągu tekstowym.\r\nT\t\t\t= T\t\t\t\t##\tKonwertuje argumenty na tekst.\r\nTEXT\t\t\t= TEKST\t\t\t\t##\tFormatuje liczbę i konwertuje ją na tekst.\r\nTRIM\t\t\t= USUŃ.ZBĘDNE.ODSTĘPY\t\t##\tUsuwa spacje z tekstu.\r\nUPPER\t\t\t= LITERY.WIELKIE\t\t##\tKonwertuje znaki tekstu na wielkie litery.\r\nVALUE\t\t\t= WARTOŚĆ\t\t\t##\tKonwertuje argument tekstowy na liczbę.\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/br/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= R$\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #NULO!\r\nDIV0\t= #DIV/0!\r\nVALUE\t= #VALOR!\r\nREF\t= #REF!\r\nNAME\t= #NOME?\r\nNUM\t= #NÚM!\r\nNA\t= #N/D\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/br/functions",
    "content": "##\r\n##\tAdd-in and Automation functions\t\t\tFunções Suplemento e Automação\r\n##\r\nGETPIVOTDATA\t\t= INFODADOSTABELADINÂMICA\t##\tRetorna os dados armazenados em um relatório de tabela dinâmica\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\tFunções de Cubo\r\n##\r\nCUBEKPIMEMBER\t\t= MEMBROKPICUBO\t\t\t##\tRetorna o nome de um KPI (indicador de desempenho-chave), uma propriedade e uma medida e exibe o nome e a propriedade na célula. Um KPI é uma medida quantificável, como o lucro bruto mensal ou a rotatividade trimestral dos funcionários, usada para monitorar o desempenho de uma organização.\r\nCUBEMEMBER\t\t= MEMBROCUBO\t\t\t##\tRetorna um membro ou tupla em uma hierarquia de cubo. Use para validar se o membro ou tupla existe no cubo.\r\nCUBEMEMBERPROPERTY\t= PROPRIEDADEMEMBROCUBO\t\t##\tRetorna o valor da propriedade de um membro no cubo. Usada para validar a existência do nome do membro no cubo e para retornar a propriedade especificada para esse membro.\r\nCUBERANKEDMEMBER\t= MEMBROCLASSIFICADOCUBO\t##\tRetorna o enésimo membro, ou o membro ordenado, em um conjunto. Use para retornar um ou mais elementos em um conjunto, assim como o melhor vendedor ou os dez melhores alunos.\r\nCUBESET\t\t\t= CONJUNTOCUBO\t\t\t##\tDefine um conjunto calculado de membros ou tuplas enviando uma expressão do conjunto para o cubo no servidor, que cria o conjunto e o retorna para o Microsoft Office Excel.\r\nCUBESETCOUNT\t\t= CONTAGEMCONJUNTOCUBO\t\t##\tRetorna o número de itens em um conjunto.\r\nCUBEVALUE\t\t= VALORCUBO\t\t\t##\tRetorna um valor agregado de um cubo.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\tFunções de banco de dados\r\n##\r\nDAVERAGE\t\t= BDMÉDIA\t\t\t##\tRetorna a média das entradas selecionadas de um banco de dados\r\nDCOUNT\t\t\t= BDCONTAR\t\t\t##\tConta as células que contêm números em um banco de dados\r\nDCOUNTA\t\t\t= BDCONTARA\t\t\t##\tConta células não vazias em um banco de dados\r\nDGET\t\t\t= BDEXTRAIR\t\t\t##\tExtrai de um banco de dados um único registro que corresponde a um critério específico\r\nDMAX\t\t\t= BDMÁX\t\t\t\t##\tRetorna o valor máximo de entradas selecionadas de um banco de dados\r\nDMIN\t\t\t= BDMÍN\t\t\t\t##\tRetorna o valor mínimo de entradas selecionadas de um banco de dados\r\nDPRODUCT\t\t= BDMULTIPL\t\t\t##\tMultiplica os valores em um campo específico de registros que correspondem ao critério em um banco de dados\r\nDSTDEV\t\t\t= BDEST\t\t\t\t##\tEstima o desvio padrão com base em uma amostra de entradas selecionadas de um banco de dados\r\nDSTDEVP\t\t\t= BDDESVPA\t\t\t##\tCalcula o desvio padrão com base na população inteira de entradas selecionadas de um banco de dados\r\nDSUM\t\t\t= BDSOMA\t\t\t##\tAdiciona os números à coluna de campos de registros do banco de dados que correspondem ao critério\r\nDVAR\t\t\t= BDVAREST\t\t\t##\tEstima a variância com base em uma amostra de entradas selecionadas de um banco de dados\r\nDVARP\t\t\t= BDVARP\t\t\t##\tCalcula a variância com base na população inteira de entradas selecionadas de um banco de dados\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\tFunções de data e hora\r\n##\r\nDATE\t\t\t= DATA\t\t\t\t##\tRetorna o número de série de uma data específica\r\nDATEVALUE\t\t= DATA.VALOR\t\t\t##\tConverte uma data na forma de texto para um número de série\r\nDAY\t\t\t= DIA\t\t\t\t##\tConverte um número de série em um dia do mês\r\nDAYS360\t\t\t= DIAS360\t\t\t##\tCalcula o número de dias entre duas datas com base em um ano de 360 dias\r\nEDATE\t\t\t= DATAM\t\t\t\t##\tRetorna o número de série da data que é o número indicado de meses antes ou depois da data inicial\r\nEOMONTH\t\t\t= FIMMÊS\t\t\t##\tRetorna o número de série do último dia do mês antes ou depois de um número especificado de meses\r\nHOUR\t\t\t= HORA\t\t\t\t##\tConverte um número de série em uma hora\r\nMINUTE\t\t\t= MINUTO\t\t\t##\tConverte um número de série em um minuto\r\nMONTH\t\t\t= MÊS\t\t\t\t##\tConverte um número de série em um mês\r\nNETWORKDAYS\t\t= DIATRABALHOTOTAL\t\t##\tRetorna o número de dias úteis inteiros entre duas datas\r\nNOW\t\t\t= AGORA\t\t\t\t##\tRetorna o número de série seqüencial da data e hora atuais\r\nSECOND\t\t\t= SEGUNDO\t\t\t##\tConverte um número de série em um segundo\r\nTIME\t\t\t= HORA\t\t\t\t##\tRetorna o número de série de uma hora específica\r\nTIMEVALUE\t\t= VALOR.TEMPO\t\t\t##\tConverte um horário na forma de texto para um número de série\r\nTODAY\t\t\t= HOJE\t\t\t\t##\tRetorna o número de série da data de hoje\r\nWEEKDAY\t\t\t= DIA.DA.SEMANA\t\t\t##\tConverte um número de série em um dia da semana\r\nWEEKNUM\t\t\t= NÚMSEMANA\t\t\t##\tConverte um número de série em um número que representa onde a semana cai numericamente em um ano\r\nWORKDAY\t\t\t= DIATRABALHO\t\t\t##\tRetorna o número de série da data antes ou depois de um número específico de dias úteis\r\nYEAR\t\t\t= ANO\t\t\t\t##\tConverte um número de série em um ano\r\nYEARFRAC\t\t= FRAÇÃOANO\t\t\t##\tRetorna a fração do ano que representa o número de dias entre data_inicial e data_final\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\tFunções de engenharia\r\n##\r\nBESSELI\t\t\t= BESSELI\t\t\t##\tRetorna a função de Bessel In(x) modificada\r\nBESSELJ\t\t\t= BESSELJ\t\t\t##\tRetorna a função de Bessel Jn(x)\r\nBESSELK\t\t\t= BESSELK\t\t\t##\tRetorna a função de Bessel Kn(x) modificada\r\nBESSELY\t\t\t= BESSELY\t\t\t##\tRetorna a função de Bessel Yn(x)\r\nBIN2DEC\t\t\t= BIN2DEC\t\t\t##\tConverte um número binário em decimal\r\nBIN2HEX\t\t\t= BIN2HEX\t\t\t##\tConverte um número binário em hexadecimal\r\nBIN2OCT\t\t\t= BIN2OCT\t\t\t##\tConverte um número binário em octal\r\nCOMPLEX\t\t\t= COMPLEX\t\t\t##\tConverte coeficientes reais e imaginários e um número complexo\r\nCONVERT\t\t\t= CONVERTER\t\t\t##\tConverte um número de um sistema de medida para outro\r\nDEC2BIN\t\t\t= DECABIN\t\t\t##\tConverte um número decimal em binário\r\nDEC2HEX\t\t\t= DECAHEX\t\t\t##\tConverte um número decimal em hexadecimal\r\nDEC2OCT\t\t\t= DECAOCT\t\t\t##\tConverte um número decimal em octal\r\nDELTA\t\t\t= DELTA\t\t\t\t##\tTesta se dois valores são iguais\r\nERF\t\t\t= FUNERRO\t\t\t##\tRetorna a função de erro\r\nERFC\t\t\t= FUNERROCOMPL\t\t\t##\tRetorna a função de erro complementar\r\nGESTEP\t\t\t= DEGRAU\t\t\t##\tTesta se um número é maior do que um valor limite\r\nHEX2BIN\t\t\t= HEXABIN\t\t\t##\tConverte um número hexadecimal em binário\r\nHEX2DEC\t\t\t= HEXADEC\t\t\t##\tConverte um número hexadecimal em decimal\r\nHEX2OCT\t\t\t= HEXAOCT\t\t\t##\tConverte um número hexadecimal em octal\r\nIMABS\t\t\t= IMABS\t\t\t\t##\tRetorna o valor absoluto (módulo) de um número complexo\r\nIMAGINARY\t\t= IMAGINÁRIO\t\t\t##\tRetorna o coeficiente imaginário de um número complexo\r\nIMARGUMENT\t\t= IMARG\t\t\t\t##\tRetorna o argumento teta, um ângulo expresso em radianos\r\nIMCONJUGATE\t\t= IMCONJ\t\t\t##\tRetorna o conjugado complexo de um número complexo\r\nIMCOS\t\t\t= IMCOS\t\t\t\t##\tRetorna o cosseno de um número complexo\r\nIMDIV\t\t\t= IMDIV\t\t\t\t##\tRetorna o quociente de dois números complexos\r\nIMEXP\t\t\t= IMEXP\t\t\t\t##\tRetorna o exponencial de um número complexo\r\nIMLN\t\t\t= IMLN\t\t\t\t##\tRetorna o logaritmo natural de um número complexo\r\nIMLOG10\t\t\t= IMLOG10\t\t\t##\tRetorna o logaritmo de base 10 de um número complexo\r\nIMLOG2\t\t\t= IMLOG2\t\t\t##\tRetorna o logaritmo de base 2 de um número complexo\r\nIMPOWER\t\t\t= IMPOT\t\t\t\t##\tRetorna um número complexo elevado a uma potência inteira\r\nIMPRODUCT\t\t= IMPROD\t\t\t##\tRetorna o produto de números complexos\r\nIMREAL\t\t\t= IMREAL\t\t\t##\tRetorna o coeficiente real de um número complexo\r\nIMSIN\t\t\t= IMSENO\t\t\t##\tRetorna o seno de um número complexo\r\nIMSQRT\t\t\t= IMRAIZ\t\t\t##\tRetorna a raiz quadrada de um número complexo\r\nIMSUB\t\t\t= IMSUBTR\t\t\t##\tRetorna a diferença entre dois números complexos\r\nIMSUM\t\t\t= IMSOMA\t\t\t##\tRetorna a soma de números complexos\r\nOCT2BIN\t\t\t= OCTABIN\t\t\t##\tConverte um número octal em binário\r\nOCT2DEC\t\t\t= OCTADEC\t\t\t##\tConverte um número octal em decimal\r\nOCT2HEX\t\t\t= OCTAHEX\t\t\t##\tConverte um número octal em hexadecimal\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\tFunções financeiras\r\n##\r\nACCRINT\t\t\t= JUROSACUM\t\t\t##\tRetorna a taxa de juros acumulados de um título que paga uma taxa periódica de juros\r\nACCRINTM\t\t= JUROSACUMV\t\t\t##\tRetorna os juros acumulados de um título que paga juros no vencimento\r\nAMORDEGRC\t\t= AMORDEGRC\t\t\t##\tRetorna a depreciação para cada período contábil usando o coeficiente de depreciação\r\nAMORLINC\t\t= AMORLINC\t\t\t##\tRetorna a depreciação para cada período contábil\r\nCOUPDAYBS\t\t= CUPDIASINLIQ\t\t\t##\tRetorna o número de dias do início do período de cupom até a data de liquidação\r\nCOUPDAYS\t\t= CUPDIAS\t\t\t##\tRetorna o número de dias no período de cupom que contém a data de quitação\r\nCOUPDAYSNC\t\t= CUPDIASPRÓX\t\t\t##\tRetorna o número de dias da data de liquidação até a data do próximo cupom\r\nCOUPNCD\t\t\t= CUPDATAPRÓX\t\t\t##\tRetorna a próxima data de cupom após a data de quitação\r\nCOUPNUM\t\t\t= CUPNÚM\t\t\t##\tRetorna o número de cupons pagáveis entre as datas de quitação e vencimento\r\nCOUPPCD\t\t\t= CUPDATAANT\t\t\t##\tRetorna a data de cupom anterior à data de quitação\r\nCUMIPMT\t\t\t= PGTOJURACUM\t\t\t##\tRetorna os juros acumulados pagos entre dois períodos\r\nCUMPRINC\t\t= PGTOCAPACUM\t\t\t##\tRetorna o capital acumulado pago sobre um empréstimo entre dois períodos\r\nDB\t\t\t= BD\t\t\t\t##\tRetorna a depreciação de um ativo para um período especificado, usando o método de balanço de declínio fixo\r\nDDB\t\t\t= BDD\t\t\t\t##\tRetorna a depreciação de um ativo com relação a um período especificado usando o método de saldos decrescentes duplos ou qualquer outro método especificado por você\r\nDISC\t\t\t= DESC\t\t\t\t##\tRetorna a taxa de desconto de um título\r\nDOLLARDE\t\t= MOEDADEC\t\t\t##\tConverte um preço em formato de moeda, na forma fracionária, em um preço na forma decimal\r\nDOLLARFR\t\t= MOEDAFRA\t\t\t##\tConverte um preço, apresentado na forma decimal, em um preço apresentado na forma fracionária\r\nDURATION\t\t= DURAÇÃO\t\t\t##\tRetorna a duração anual de um título com pagamentos de juros periódicos\r\nEFFECT\t\t\t= EFETIVA\t\t\t##\tRetorna a taxa de juros anual efetiva\r\nFV\t\t\t= VF\t\t\t\t##\tRetorna o valor futuro de um investimento\r\nFVSCHEDULE\t\t= VFPLANO\t\t\t##\tRetorna o valor futuro de um capital inicial após a aplicação de uma série de taxas de juros compostas\r\nINTRATE\t\t\t= TAXAJUROS\t\t\t##\tRetorna a taxa de juros de um título totalmente investido\r\nIPMT\t\t\t= IPGTO\t\t\t\t##\tRetorna o pagamento de juros para um investimento em um determinado período\r\nIRR\t\t\t= TIR\t\t\t\t##\tRetorna a taxa interna de retorno de uma série de fluxos de caixa\r\nISPMT\t\t\t= ÉPGTO\t\t\t\t##\tCalcula os juros pagos durante um período específico de um investimento\r\nMDURATION\t\t= MDURAÇÃO\t\t\t##\tRetorna a duração de Macauley modificada para um título com um valor de paridade equivalente a R$ 100\r\nMIRR\t\t\t= MTIR\t\t\t\t##\tCalcula a taxa interna de retorno em que fluxos de caixa positivos e negativos são financiados com diferentes taxas\r\nNOMINAL\t\t\t= NOMINAL\t\t\t##\tRetorna a taxa de juros nominal anual\r\nNPER\t\t\t= NPER\t\t\t\t##\tRetorna o número de períodos de um investimento\r\nNPV\t\t\t= VPL\t\t\t\t##\tRetorna o valor líquido atual de um investimento com base em uma série de fluxos de caixa periódicos e em uma taxa de desconto\r\nODDFPRICE\t\t= PREÇOPRIMINC\t\t\t##\tRetorna o preço por R$ 100 de valor nominal de um título com um primeiro período indefinido\r\nODDFYIELD\t\t= LUCROPRIMINC\t\t\t##\tRetorna o rendimento de um título com um primeiro período indefinido\r\nODDLPRICE\t\t= PREÇOÚLTINC\t\t\t##\tRetorna o preço por R$ 100 de valor nominal de um título com um último período de cupom indefinido\r\nODDLYIELD\t\t= LUCROÚLTINC\t\t\t##\tRetorna o rendimento de um título com um último período indefinido\r\nPMT\t\t\t= PGTO\t\t\t\t##\tRetorna o pagamento periódico de uma anuidade\r\nPPMT\t\t\t= PPGTO\t\t\t\t##\tRetorna o pagamento de capital para determinado período de investimento\r\nPRICE\t\t\t= PREÇO\t\t\t\t##\tRetorna a preço por R$ 100,00 de valor nominal de um título que paga juros periódicos\r\nPRICEDISC\t\t= PREÇODESC\t\t\t##\tRetorna o preço por R$ 100,00 de valor nominal de um título descontado\r\nPRICEMAT\t\t= PREÇOVENC\t\t\t##\tRetorna o preço por R$ 100,00 de valor nominal de um título que paga juros no vencimento\r\nPV\t\t\t= VP\t\t\t\t##\tRetorna o valor presente de um investimento\r\nRATE\t\t\t= TAXA\t\t\t\t##\tRetorna a taxa de juros por período de uma anuidade\r\nRECEIVED\t\t= RECEBER\t\t\t##\tRetorna a quantia recebida no vencimento de um título totalmente investido\r\nSLN\t\t\t= DPD\t\t\t\t##\tRetorna a depreciação em linha reta de um ativo durante um período\r\nSYD\t\t\t= SDA\t\t\t\t##\tRetorna a depreciação dos dígitos da soma dos anos de um ativo para um período especificado\r\nTBILLEQ\t\t\t= OTN\t\t\t\t##\tRetorna o rendimento de um título equivalente a uma obrigação do Tesouro\r\nTBILLPRICE\t\t= OTNVALOR\t\t\t##\tRetorna o preço por R$ 100,00 de valor nominal de uma obrigação do Tesouro\r\nTBILLYIELD\t\t= OTNLUCRO\t\t\t##\tRetorna o rendimento de uma obrigação do Tesouro\r\nVDB\t\t\t= BDV\t\t\t\t##\tRetorna a depreciação de um ativo para um período especificado ou parcial usando um método de balanço declinante\r\nXIRR\t\t\t= XTIR\t\t\t\t##\tFornece a taxa interna de retorno para um programa de fluxos de caixa que não é necessariamente periódico\r\nXNPV\t\t\t= XVPL\t\t\t\t##\tRetorna o valor presente líquido de um programa de fluxos de caixa que não é necessariamente periódico\r\nYIELD\t\t\t= LUCRO\t\t\t\t##\tRetorna o lucro de um título que paga juros periódicos\r\nYIELDDISC\t\t= LUCRODESC\t\t\t##\tRetorna o rendimento anual de um título descontado. Por exemplo, uma obrigação do Tesouro\r\nYIELDMAT\t\t= LUCROVENC\t\t\t##\tRetorna o lucro anual de um título que paga juros no vencimento\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\tFunções de informação\r\n##\r\nCELL\t\t\t= CÉL\t\t\t\t##\tRetorna informações sobre formatação, localização ou conteúdo de uma célula\r\nERROR.TYPE\t\t= TIPO.ERRO\t\t\t##\tRetorna um número correspondente a um tipo de erro\r\nINFO\t\t\t= INFORMAÇÃO\t\t\t##\tRetorna informações sobre o ambiente operacional atual\r\nISBLANK\t\t\t= ÉCÉL.VAZIA\t\t\t##\tRetorna VERDADEIRO se o valor for vazio\r\nISERR\t\t\t= ÉERRO\t\t\t\t##\tRetorna VERDADEIRO se o valor for um valor de erro diferente de #N/D\r\nISERROR\t\t\t= ÉERROS\t\t\t##\tRetorna VERDADEIRO se o valor for um valor de erro\r\nISEVEN\t\t\t= ÉPAR\t\t\t\t##\tRetorna VERDADEIRO se o número for par\r\nISLOGICAL\t\t= ÉLÓGICO\t\t\t##\tRetorna VERDADEIRO se o valor for um valor lógico\r\nISNA\t\t\t= É.NÃO.DISP\t\t\t##\tRetorna VERDADEIRO se o valor for o valor de erro #N/D\r\nISNONTEXT\t\t= É.NÃO.TEXTO\t\t\t##\tRetorna VERDADEIRO se o valor for diferente de texto\r\nISNUMBER\t\t= ÉNÚM\t\t\t\t##\tRetorna VERDADEIRO se o valor for um número\r\nISODD\t\t\t= ÉIMPAR\t\t\t##\tRetorna VERDADEIRO se o número for ímpar\r\nISREF\t\t\t= ÉREF\t\t\t\t##\tRetorna VERDADEIRO se o valor for uma referência\r\nISTEXT\t\t\t= ÉTEXTO\t\t\t##\tRetorna VERDADEIRO se o valor for texto\r\nN\t\t\t= N\t\t\t\t##\tRetorna um valor convertido em um número\r\nNA\t\t\t= NÃO.DISP\t\t\t##\tRetorna o valor de erro #N/D\r\nTYPE\t\t\t= TIPO\t\t\t\t##\tRetorna um número indicando o tipo de dados de um valor\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\tFunções lógicas\r\n##\r\nAND\t\t\t= E\t\t\t\t##\tRetorna VERDADEIRO se todos os seus argumentos forem VERDADEIROS\r\nFALSE\t\t\t= FALSO\t\t\t\t##\tRetorna o valor lógico FALSO\r\nIF\t\t\t= SE\t\t\t\t##\tEspecifica um teste lógico a ser executado\r\nIFERROR\t\t\t= SEERRO\t\t\t##\tRetornará um valor que você especifica se uma fórmula for avaliada para um erro; do contrário, retornará o resultado da fórmula\r\nNOT\t\t\t= NÃO\t\t\t\t##\tInverte o valor lógico do argumento\r\nOR\t\t\t= OU\t\t\t\t##\tRetorna VERDADEIRO se um dos argumentos for VERDADEIRO\r\nTRUE\t\t\t= VERDADEIRO\t\t\t##\tRetorna o valor lógico VERDADEIRO\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\tFunções de pesquisa e referência\r\n##\r\nADDRESS\t\t\t= ENDEREÇO\t\t\t##\tRetorna uma referência como texto para uma única célula em uma planilha\r\nAREAS\t\t\t= ÁREAS\t\t\t\t##\tRetorna o número de áreas em uma referência\r\nCHOOSE\t\t\t= ESCOLHER\t\t\t##\tEscolhe um valor a partir de uma lista de valores\r\nCOLUMN\t\t\t= COL\t\t\t\t##\tRetorna o número da coluna de uma referência\r\nCOLUMNS\t\t\t= COLS\t\t\t\t##\tRetorna o número de colunas em uma referência\r\nHLOOKUP\t\t\t= PROCH\t\t\t\t##\tProcura na linha superior de uma matriz e retorna o valor da célula especificada\r\nHYPERLINK\t\t= HYPERLINK\t\t\t##\tCria um atalho ou salto que abre um documento armazenado em um servidor de rede, uma intranet ou na Internet\r\nINDEX\t\t\t= ÍNDICE\t\t\t##\tUsa um índice para escolher um valor de uma referência ou matriz\r\nINDIRECT\t\t= INDIRETO\t\t\t##\tRetorna uma referência indicada por um valor de texto\r\nLOOKUP\t\t\t= PROC\t\t\t\t##\tProcura valores em um vetor ou em uma matriz\r\nMATCH\t\t\t= CORRESP\t\t\t##\tProcura valores em uma referência ou em uma matriz\r\nOFFSET\t\t\t= DESLOC\t\t\t##\tRetorna um deslocamento de referência com base em uma determinada referência\r\nROW\t\t\t= LIN\t\t\t\t##\tRetorna o número da linha de uma referência\r\nROWS\t\t\t= LINS\t\t\t\t##\tRetorna o número de linhas em uma referência\r\nRTD\t\t\t= RTD\t\t\t\t##\tRecupera dados em tempo real de um programa que ofereça suporte a automação COM (automação: uma forma de trabalhar com objetos de um aplicativo a partir de outro aplicativo ou ferramenta de desenvolvimento. Chamada inicialmente de automação OLE, a automação é um padrão industrial e um recurso do modelo de objeto componente (COM).)\r\nTRANSPOSE\t\t= TRANSPOR\t\t\t##\tRetorna a transposição de uma matriz\r\nVLOOKUP\t\t\t= PROCV\t\t\t\t##\tProcura na primeira coluna de uma matriz e move ao longo da linha para retornar o valor de uma célula\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\tFunções matemáticas e trigonométricas\r\n##\r\nABS\t\t\t= ABS\t\t\t\t##\tRetorna o valor absoluto de um número\r\nACOS\t\t\t= ACOS\t\t\t\t##\tRetorna o arco cosseno de um número\r\nACOSH\t\t\t= ACOSH\t\t\t\t##\tRetorna o cosseno hiperbólico inverso de um número\r\nASIN\t\t\t= ASEN\t\t\t\t##\tRetorna o arco seno de um número\r\nASINH\t\t\t= ASENH\t\t\t\t##\tRetorna o seno hiperbólico inverso de um número\r\nATAN\t\t\t= ATAN\t\t\t\t##\tRetorna o arco tangente de um número\r\nATAN2\t\t\t= ATAN2\t\t\t\t##\tRetorna o arco tangente das coordenadas x e y especificadas\r\nATANH\t\t\t= ATANH\t\t\t\t##\tRetorna a tangente hiperbólica inversa de um número\r\nCEILING\t\t\t= TETO\t\t\t\t##\tArredonda um número para o inteiro mais próximo ou para o múltiplo mais próximo de significância\r\nCOMBIN\t\t\t= COMBIN\t\t\t##\tRetorna o número de combinações de um determinado número de objetos\r\nCOS\t\t\t= COS\t\t\t\t##\tRetorna o cosseno de um número\r\nCOSH\t\t\t= COSH\t\t\t\t##\tRetorna o cosseno hiperbólico de um número\r\nDEGREES\t\t\t= GRAUS\t\t\t\t##\tConverte radianos em graus\r\nEVEN\t\t\t= PAR\t\t\t\t##\tArredonda um número para cima até o inteiro par mais próximo\r\nEXP\t\t\t= EXP\t\t\t\t##\tRetorna e elevado à potência de um número especificado\r\nFACT\t\t\t= FATORIAL\t\t\t##\tRetorna o fatorial de um número\r\nFACTDOUBLE\t\t= FATDUPLO\t\t\t##\tRetorna o fatorial duplo de um número\r\nFLOOR\t\t\t= ARREDMULTB\t\t\t##\tArredonda um número para baixo até zero\r\nGCD\t\t\t= MDC\t\t\t\t##\tRetorna o máximo divisor comum\r\nINT\t\t\t= INT\t\t\t\t##\tArredonda um número para baixo até o número inteiro mais próximo\r\nLCM\t\t\t= MMC\t\t\t\t##\tRetorna o mínimo múltiplo comum\r\nLN\t\t\t= LN\t\t\t\t##\tRetorna o logaritmo natural de um número\r\nLOG\t\t\t= LOG\t\t\t\t##\tRetorna o logaritmo de um número de uma base especificada\r\nLOG10\t\t\t= LOG10\t\t\t\t##\tRetorna o logaritmo de base 10 de um número\r\nMDETERM\t\t\t= MATRIZ.DETERM\t\t\t##\tRetorna o determinante de uma matriz de uma variável do tipo matriz\r\nMINVERSE\t\t= MATRIZ.INVERSO\t\t##\tRetorna a matriz inversa de uma matriz\r\nMMULT\t\t\t= MATRIZ.MULT\t\t\t##\tRetorna o produto de duas matrizes\r\nMOD\t\t\t= RESTO\t\t\t\t##\tRetorna o resto da divisão\r\nMROUND\t\t\t= MARRED\t\t\t##\tRetorna um número arredondado ao múltiplo desejado\r\nMULTINOMIAL\t\t= MULTINOMIAL\t\t\t##\tRetorna o multinomial de um conjunto de números\r\nODD\t\t\t= ÍMPAR\t\t\t\t##\tArredonda um número para cima até o inteiro ímpar mais próximo\r\nPI\t\t\t= PI\t\t\t\t##\tRetorna o valor de Pi\r\nPOWER\t\t\t= POTÊNCIA\t\t\t##\tFornece o resultado de um número elevado a uma potência\r\nPRODUCT\t\t\t= MULT\t\t\t\t##\tMultiplica seus argumentos\r\nQUOTIENT\t\t= QUOCIENTE\t\t\t##\tRetorna a parte inteira de uma divisão\r\nRADIANS\t\t\t= RADIANOS\t\t\t##\tConverte graus em radianos\r\nRAND\t\t\t= ALEATÓRIO\t\t\t##\tRetorna um número aleatório entre 0 e 1\r\nRANDBETWEEN\t\t= ALEATÓRIOENTRE\t\t##\tRetorna um número aleatório entre os números especificados\r\nROMAN\t\t\t= ROMANO\t\t\t##\tConverte um algarismo arábico em romano, como texto\r\nROUND\t\t\t= ARRED\t\t\t\t##\tArredonda um número até uma quantidade especificada de dígitos\r\nROUNDDOWN\t\t= ARREDONDAR.PARA.BAIXO\t\t##\tArredonda um número para baixo até zero\r\nROUNDUP\t\t\t= ARREDONDAR.PARA.CIMA\t\t##\tArredonda um número para cima, afastando-o de zero\r\nSERIESSUM\t\t= SOMASEQÜÊNCIA\t\t\t##\tRetorna a soma de uma série polinomial baseada na fórmula\r\nSIGN\t\t\t= SINAL\t\t\t\t##\tRetorna o sinal de um número\r\nSIN\t\t\t= SEN\t\t\t\t##\tRetorna o seno de um ângulo dado\r\nSINH\t\t\t= SENH\t\t\t\t##\tRetorna o seno hiperbólico de um número\r\nSQRT\t\t\t= RAIZ\t\t\t\t##\tRetorna uma raiz quadrada positiva\r\nSQRTPI\t\t\t= RAIZPI\t\t\t##\tRetorna a raiz quadrada de (núm* pi)\r\nSUBTOTAL\t\t= SUBTOTAL\t\t\t##\tRetorna um subtotal em uma lista ou em um banco de dados\r\nSUM\t\t\t= SOMA\t\t\t\t##\tSoma seus argumentos\r\nSUMIF\t\t\t= SOMASE\t\t\t##\tAdiciona as células especificadas por um determinado critério\r\nSUMIFS\t\t\t= SOMASE\t\t\t##\tAdiciona as células em um intervalo que atende a vários critérios\r\nSUMPRODUCT\t\t= SOMARPRODUTO\t\t\t##\tRetorna a soma dos produtos de componentes correspondentes de matrizes\r\nSUMSQ\t\t\t= SOMAQUAD\t\t\t##\tRetorna a soma dos quadrados dos argumentos\r\nSUMX2MY2\t\t= SOMAX2DY2\t\t\t##\tRetorna a soma da diferença dos quadrados dos valores correspondentes em duas matrizes\r\nSUMX2PY2\t\t= SOMAX2SY2\t\t\t##\tRetorna a soma da soma dos quadrados dos valores correspondentes em duas matrizes\r\nSUMXMY2\t\t\t= SOMAXMY2\t\t\t##\tRetorna a soma dos quadrados das diferenças dos valores correspondentes em duas matrizes\r\nTAN\t\t\t= TAN\t\t\t\t##\tRetorna a tangente de um número\r\nTANH\t\t\t= TANH\t\t\t\t##\tRetorna a tangente hiperbólica de um número\r\nTRUNC\t\t\t= TRUNCAR\t\t\t##\tTrunca um número para um inteiro\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\tFunções estatísticas\r\n##\r\nAVEDEV\t\t\t= DESV.MÉDIO\t\t\t##\tRetorna a média aritmética dos desvios médios dos pontos de dados a partir de sua média\r\nAVERAGE\t\t\t= MÉDIA\t\t\t\t##\tRetorna a média dos argumentos\r\nAVERAGEA\t\t= MÉDIAA\t\t\t##\tRetorna a média dos argumentos, inclusive números, texto e valores lógicos\r\nAVERAGEIF\t\t= MÉDIASE\t\t\t##\tRetorna a média (média aritmética) de todas as células em um intervalo que atendem a um determinado critério\r\nAVERAGEIFS\t\t= MÉDIASES\t\t\t##\tRetorna a média (média aritmética) de todas as células que atendem a múltiplos critérios.\r\nBETADIST\t\t= DISTBETA\t\t\t##\tRetorna a função de distribuição cumulativa beta\r\nBETAINV\t\t\t= BETA.ACUM.INV\t\t\t##\tRetorna o inverso da função de distribuição cumulativa para uma distribuição beta especificada\r\nBINOMDIST\t\t= DISTRBINOM\t\t\t##\tRetorna a probabilidade de distribuição binomial do termo individual\r\nCHIDIST\t\t\t= DIST.QUI\t\t\t##\tRetorna a probabilidade unicaudal da distribuição qui-quadrada\r\nCHIINV\t\t\t= INV.QUI\t\t\t##\tRetorna o inverso da probabilidade uni-caudal da distribuição qui-quadrada\r\nCHITEST\t\t\t= TESTE.QUI\t\t\t##\tRetorna o teste para independência\r\nCONFIDENCE\t\t= INT.CONFIANÇA\t\t\t##\tRetorna o intervalo de confiança para uma média da população\r\nCORREL\t\t\t= CORREL\t\t\t##\tRetorna o coeficiente de correlação entre dois conjuntos de dados\r\nCOUNT\t\t\t= CONT.NÚM\t\t\t##\tCalcula quantos números há na lista de argumentos\r\nCOUNTA\t\t\t= CONT.VALORES\t\t\t##\tCalcula quantos valores há na lista de argumentos\r\nCOUNTBLANK\t\t= CONTAR.VAZIO\t\t\t##\tConta o número de células vazias no intervalo especificado\r\nCOUNTIF\t\t\t= CONT.SE\t\t\t##\tCalcula o número de células não vazias em um intervalo que corresponde a determinados critérios\r\nCOUNTIFS\t\t= CONT.SES\t\t\t##\tConta o número de células dentro de um intervalo que atende a múltiplos critérios\r\nCOVAR\t\t\t= COVAR\t\t\t\t##\tRetorna a covariância, a média dos produtos dos desvios pares\r\nCRITBINOM\t\t= CRIT.BINOM\t\t\t##\tRetorna o menor valor para o qual a distribuição binomial cumulativa é menor ou igual ao valor padrão\r\nDEVSQ\t\t\t= DESVQ\t\t\t\t##\tRetorna a soma dos quadrados dos desvios\r\nEXPONDIST\t\t= DISTEXPON\t\t\t##\tRetorna a distribuição exponencial\r\nFDIST\t\t\t= DISTF\t\t\t\t##\tRetorna a distribuição de probabilidade F\r\nFINV\t\t\t= INVF\t\t\t\t##\tRetorna o inverso da distribuição de probabilidades F\r\nFISHER\t\t\t= FISHER\t\t\t##\tRetorna a transformação Fisher\r\nFISHERINV\t\t= FISHERINV\t\t\t##\tRetorna o inverso da transformação Fisher\r\nFORECAST\t\t= PREVISÃO\t\t\t##\tRetorna um valor ao longo de uma linha reta\r\nFREQUENCY\t\t= FREQÜÊNCIA\t\t\t##\tRetorna uma distribuição de freqüência como uma matriz vertical\r\nFTEST\t\t\t= TESTEF\t\t\t##\tRetorna o resultado de um teste F\r\nGAMMADIST\t\t= DISTGAMA\t\t\t##\tRetorna a distribuição gama\r\nGAMMAINV\t\t= INVGAMA\t\t\t##\tRetorna o inverso da distribuição cumulativa gama\r\nGAMMALN\t\t\t= LNGAMA\t\t\t##\tRetorna o logaritmo natural da função gama, G(x)\r\nGEOMEAN\t\t\t= MÉDIA.GEOMÉTRICA\t\t##\tRetorna a média geométrica\r\nGROWTH\t\t\t= CRESCIMENTO\t\t\t##\tRetorna valores ao longo de uma tendência exponencial\r\nHARMEAN\t\t\t= MÉDIA.HARMÔNICA\t\t##\tRetorna a média harmônica\r\nHYPGEOMDIST\t\t= DIST.HIPERGEOM\t\t##\tRetorna a distribuição hipergeométrica\r\nINTERCEPT\t\t= INTERCEPÇÃO\t\t\t##\tRetorna a intercepção da linha de regressão linear\r\nKURT\t\t\t= CURT\t\t\t\t##\tRetorna a curtose de um conjunto de dados\r\nLARGE\t\t\t= MAIOR\t\t\t\t##\tRetorna o maior valor k-ésimo de um conjunto de dados\r\nLINEST\t\t\t= PROJ.LIN\t\t\t##\tRetorna os parâmetros de uma tendência linear\r\nLOGEST\t\t\t= PROJ.LOG\t\t\t##\tRetorna os parâmetros de uma tendência exponencial\r\nLOGINV\t\t\t= INVLOG\t\t\t##\tRetorna o inverso da distribuição lognormal\r\nLOGNORMDIST\t\t= DIST.LOGNORMAL\t\t##\tRetorna a distribuição lognormal cumulativa\r\nMAX\t\t\t= MÁXIMO\t\t\t##\tRetorna o valor máximo em uma lista de argumentos\r\nMAXA\t\t\t= MÁXIMOA\t\t\t##\tRetorna o maior valor em uma lista de argumentos, inclusive números, texto e valores lógicos\r\nMEDIAN\t\t\t= MED\t\t\t\t##\tRetorna a mediana dos números indicados\r\nMIN\t\t\t= MÍNIMO\t\t\t##\tRetorna o valor mínimo em uma lista de argumentos\r\nMINA\t\t\t= MÍNIMOA\t\t\t##\tRetorna o menor valor em uma lista de argumentos, inclusive números, texto e valores lógicos\r\nMODE\t\t\t= MODO\t\t\t\t##\tRetorna o valor mais comum em um conjunto de dados\r\nNEGBINOMDIST\t\t= DIST.BIN.NEG\t\t\t##\tRetorna a distribuição binomial negativa\r\nNORMDIST\t\t= DIST.NORM\t\t\t##\tRetorna a distribuição cumulativa normal\r\nNORMINV\t\t\t= INV.NORM\t\t\t##\tRetorna o inverso da distribuição cumulativa normal\r\nNORMSDIST\t\t= DIST.NORMP\t\t\t##\tRetorna a distribuição cumulativa normal padrão\r\nNORMSINV\t\t= INV.NORMP\t\t\t##\tRetorna o inverso da distribuição cumulativa normal padrão\r\nPEARSON\t\t\t= PEARSON\t\t\t##\tRetorna o coeficiente de correlação do momento do produto Pearson\r\nPERCENTILE\t\t= PERCENTIL\t\t\t##\tRetorna o k-ésimo percentil de valores em um intervalo\r\nPERCENTRANK\t\t= ORDEM.PORCENTUAL\t\t##\tRetorna a ordem percentual de um valor em um conjunto de dados\r\nPERMUT\t\t\t= PERMUT\t\t\t##\tRetorna o número de permutações de um determinado número de objetos\r\nPOISSON\t\t\t= POISSON\t\t\t##\tRetorna a distribuição Poisson\r\nPROB\t\t\t= PROB\t\t\t\t##\tRetorna a probabilidade de valores em um intervalo estarem entre dois limites\r\nQUARTILE\t\t= QUARTIL\t\t\t##\tRetorna o quartil do conjunto de dados\r\nRANK\t\t\t= ORDEM\t\t\t\t##\tRetorna a posição de um número em uma lista de números\r\nRSQ\t\t\t= RQUAD\t\t\t\t##\tRetorna o quadrado do coeficiente de correlação do momento do produto de Pearson\r\nSKEW\t\t\t= DISTORÇÃO\t\t\t##\tRetorna a distorção de uma distribuição\r\nSLOPE\t\t\t= INCLINAÇÃO\t\t\t##\tRetorna a inclinação da linha de regressão linear\r\nSMALL\t\t\t= MENOR\t\t\t\t##\tRetorna o menor valor k-ésimo do conjunto de dados\r\nSTANDARDIZE\t\t= PADRONIZAR\t\t\t##\tRetorna um valor normalizado\r\nSTDEV\t\t\t= DESVPAD\t\t\t##\tEstima o desvio padrão com base em uma amostra\r\nSTDEVA\t\t\t= DESVPADA\t\t\t##\tEstima o desvio padrão com base em uma amostra, inclusive números, texto e valores lógicos\r\nSTDEVP\t\t\t= DESVPADP\t\t\t##\tCalcula o desvio padrão com base na população total\r\nSTDEVPA\t\t\t= DESVPADPA\t\t\t##\tCalcula o desvio padrão com base na população total, inclusive números, texto e valores lógicos\r\nSTEYX\t\t\t= EPADYX\t\t\t##\tRetorna o erro padrão do valor-y previsto para cada x da regressão\r\nTDIST\t\t\t= DISTT\t\t\t\t##\tRetorna a distribuição t de Student\r\nTINV\t\t\t= INVT\t\t\t\t##\tRetorna o inverso da distribuição t de Student\r\nTREND\t\t\t= TENDÊNCIA\t\t\t##\tRetorna valores ao longo de uma tendência linear\r\nTRIMMEAN\t\t= MÉDIA.INTERNA\t\t\t##\tRetorna a média do interior de um conjunto de dados\r\nTTEST\t\t\t= TESTET\t\t\t##\tRetorna a probabilidade associada ao teste t de Student\r\nVAR\t\t\t= VAR\t\t\t\t##\tEstima a variância com base em uma amostra\r\nVARA\t\t\t= VARA\t\t\t\t##\tEstima a variância com base em uma amostra, inclusive números, texto e valores lógicos\r\nVARP\t\t\t= VARP\t\t\t\t##\tCalcula a variância com base na população inteira\r\nVARPA\t\t\t= VARPA\t\t\t\t##\tCalcula a variância com base na população total, inclusive números, texto e valores lógicos\r\nWEIBULL\t\t\t= WEIBULL\t\t\t##\tRetorna a distribuição Weibull\r\nZTEST\t\t\t= TESTEZ\t\t\t##\tRetorna o valor de probabilidade uni-caudal de um teste-z\r\n\r\n\r\n##\r\n##\tText functions\t\t\tFunções de texto\r\n##\r\nASC\t\t\t= ASC\t\t\t\t##\tAltera letras do inglês ou katakana de largura total (bytes duplos) dentro de uma seqüência de caracteres para caracteres de meia largura (byte único)\r\nBAHTTEXT\t\t= BAHTTEXT\t\t\t##\tConverte um número em um texto, usando o formato de moeda ß (baht)\r\nCHAR\t\t\t= CARACT\t\t\t##\tRetorna o caractere especificado pelo número de código\r\nCLEAN\t\t\t= TIRAR\t\t\t\t##\tRemove todos os caracteres do texto que não podem ser impressos\r\nCODE\t\t\t= CÓDIGO\t\t\t##\tRetorna um código numérico para o primeiro caractere de uma seqüência de caracteres de texto\r\nCONCATENATE\t\t= CONCATENAR\t\t\t##\tAgrupa vários itens de texto em um único item de texto\r\nDOLLAR\t\t\t= MOEDA\t\t\t\t##\tConverte um número em texto, usando o formato de moeda $ (dólar)\r\nEXACT\t\t\t= EXATO\t\t\t\t##\tVerifica se dois valores de texto são idênticos\r\nFIND\t\t\t= PROCURAR\t\t\t##\tProcura um valor de texto dentro de outro (diferencia maiúsculas de minúsculas)\r\nFINDB\t\t\t= PROCURARB\t\t\t##\tProcura um valor de texto dentro de outro (diferencia maiúsculas de minúsculas)\r\nFIXED\t\t\t= DEF.NÚM.DEC\t\t\t##\tFormata um número como texto com um número fixo de decimais\r\nJIS\t\t\t= JIS\t\t\t\t##\tAltera letras do inglês ou katakana de meia largura (byte único) dentro de uma seqüência de caracteres para caracteres de largura total (bytes duplos)\r\nLEFT\t\t\t= ESQUERDA\t\t\t##\tRetorna os caracteres mais à esquerda de um valor de texto\r\nLEFTB\t\t\t= ESQUERDAB\t\t\t##\tRetorna os caracteres mais à esquerda de um valor de texto\r\nLEN\t\t\t= NÚM.CARACT\t\t\t##\tRetorna o número de caracteres em uma seqüência de texto\r\nLENB\t\t\t= NÚM.CARACTB\t\t\t##\tRetorna o número de caracteres em uma seqüência de texto\r\nLOWER\t\t\t= MINÚSCULA\t\t\t##\tConverte texto para minúsculas\r\nMID\t\t\t= EXT.TEXTO\t\t\t##\tRetorna um número específico de caracteres de uma seqüência de texto começando na posição especificada\r\nMIDB\t\t\t= EXT.TEXTOB\t\t\t##\tRetorna um número específico de caracteres de uma seqüência de texto começando na posição especificada\r\nPHONETIC\t\t= FONÉTICA\t\t\t##\tExtrai os caracteres fonéticos (furigana) de uma seqüência de caracteres de texto\r\nPROPER\t\t\t= PRI.MAIÚSCULA\t\t\t##\tColoca a primeira letra de cada palavra em maiúscula em um valor de texto\r\nREPLACE\t\t\t= MUDAR\t\t\t\t##\tMuda os caracteres dentro do texto\r\nREPLACEB\t\t= MUDARB\t\t\t##\tMuda os caracteres dentro do texto\r\nREPT\t\t\t= REPT\t\t\t\t##\tRepete o texto um determinado número de vezes\r\nRIGHT\t\t\t= DIREITA\t\t\t##\tRetorna os caracteres mais à direita de um valor de texto\r\nRIGHTB\t\t\t= DIREITAB\t\t\t##\tRetorna os caracteres mais à direita de um valor de texto\r\nSEARCH\t\t\t= LOCALIZAR\t\t\t##\tLocaliza um valor de texto dentro de outro (não diferencia maiúsculas de minúsculas)\r\nSEARCHB\t\t\t= LOCALIZARB\t\t\t##\tLocaliza um valor de texto dentro de outro (não diferencia maiúsculas de minúsculas)\r\nSUBSTITUTE\t\t= SUBSTITUIR\t\t\t##\tSubstitui um novo texto por um texto antigo em uma seqüência de texto\r\nT\t\t\t= T\t\t\t\t##\tConverte os argumentos em texto\r\nTEXT\t\t\t= TEXTO\t\t\t\t##\tFormata um número e o converte em texto\r\nTRIM\t\t\t= ARRUMAR\t\t\t##\tRemove espaços do texto\r\nUPPER\t\t\t= MAIÚSCULA\t\t\t##\tConverte o texto em maiúsculas\r\nVALUE\t\t\t= VALOR\t\t\t\t##\tConverte um argumento de texto em um número\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= €\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #NULO!\r\nDIV0\t= #DIV/0!\r\nVALUE\t= #VALOR!\r\nREF\t= #REF!\r\nNAME\t= #NOME?\r\nNUM\t= #NÚM!\r\nNA\t= #N/D\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/pt/functions",
    "content": "##\r\n##\tAdd-in and Automation functions\t\t\tFunções de Suplemento e Automatização\r\n##\r\nGETPIVOTDATA\t\t= OBTERDADOSDIN\t\t\t##\tDevolve dados armazenados num relatório de Tabela Dinâmica\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\tFunções de cubo\r\n##\r\nCUBEKPIMEMBER\t\t= MEMBROKPICUBO\t\t\t##\tDevolve o nome, propriedade e medição de um KPI (key performance indicator) e apresenta o nome e a propriedade na célula. Um KPI é uma medida quantificável, como, por exemplo, o lucro mensal bruto ou a rotatividade trimestral de pessoal, utilizada para monitorizar o desempenho de uma organização.\r\nCUBEMEMBER\t\t= MEMBROCUBO\t\t\t##\tDevolve um membro ou cadeia de identificação numa hierarquia de cubo. Utilizada para validar a existência do membro ou cadeia de identificação no cubo.\r\nCUBEMEMBERPROPERTY\t= PROPRIEDADEMEMBROCUBO\t\t##\tDevolve o valor de uma propriedade de membro no cubo. Utilizada para validar a existência de um nome de membro no cubo e para devolver a propriedade especificada para esse membro.\r\nCUBERANKEDMEMBER\t= MEMBROCLASSIFICADOCUBO\t##\tDevolve o enésimo ou a classificação mais alta num conjunto. Utilizada para devolver um ou mais elementos num conjunto, tal como o melhor vendedor ou os 10 melhores alunos.\r\nCUBESET\t\t\t= CONJUNTOCUBO\t\t\t##\tDefine um conjunto calculado de membros ou cadeias de identificação enviando uma expressão de conjunto para o cubo no servidor, que cria o conjunto e, em seguida, devolve o conjunto ao Microsoft Office Excel.\r\nCUBESETCOUNT\t\t= CONTARCONJUNTOCUBO\t\t##\tDevolve o número de itens num conjunto.\r\nCUBEVALUE\t\t= VALORCUBO\t\t\t##\tDevolve um valor agregado do cubo.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\tFunções de base de dados\r\n##\r\nDAVERAGE\t\t= BDMÉDIA\t\t\t##\tDevolve a média das entradas da base de dados seleccionadas\r\nDCOUNT\t\t\t= BDCONTAR\t\t\t##\tConta as células que contêm números numa base de dados\r\nDCOUNTA\t\t\t= BDCONTAR.VAL\t\t\t##\tConta as células que não estejam em branco numa base de dados\r\nDGET\t\t\t= BDOBTER\t\t\t##\tExtrai de uma base de dados um único registo que corresponde aos critérios especificados\r\nDMAX\t\t\t= BDMÁX\t\t\t\t##\tDevolve o valor máximo das entradas da base de dados seleccionadas\r\nDMIN\t\t\t= BDMÍN\t\t\t\t##\tDevolve o valor mínimo das entradas da base de dados seleccionadas\r\nDPRODUCT\t\t= BDMULTIPL\t\t\t##\tMultiplica os valores de um determinado campo de registos que correspondem aos critérios numa base de dados\r\nDSTDEV\t\t\t= BDDESVPAD\t\t\t##\tCalcula o desvio-padrão com base numa amostra de entradas da base de dados seleccionadas\r\nDSTDEVP\t\t\t= BDDESVPADP\t\t\t##\tCalcula o desvio-padrão com base na população total das entradas da base de dados seleccionadas\r\nDSUM\t\t\t= BDSOMA\t\t\t##\tAdiciona os números na coluna de campo dos registos de base de dados que correspondem aos critérios\r\nDVAR\t\t\t= BDVAR\t\t\t\t##\tCalcula a variância com base numa amostra das entradas de base de dados seleccionadas\r\nDVARP\t\t\t= BDVARP\t\t\t##\tCalcula a variância com base na população total das entradas de base de dados seleccionadas\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\tFunções de data e hora\r\n##\r\nDATE\t\t\t= DATA\t\t\t\t##\tDevolve o número de série de uma determinada data\r\nDATEVALUE\t\t= DATA.VALOR\t\t\t##\tConverte uma data em forma de texto num número de série\r\nDAY\t\t\t= DIA\t\t\t\t##\tConverte um número de série num dia do mês\r\nDAYS360\t\t\t= DIAS360\t\t\t##\tCalcula o número de dias entre duas datas com base num ano com 360 dias\r\nEDATE\t\t\t= DATAM\t\t\t\t##\tDevolve um número de série de data que corresponde ao número de meses indicado antes ou depois da data de início\r\nEOMONTH\t\t\t= FIMMÊS\t\t\t##\tDevolve o número de série do último dia do mês antes ou depois de um número de meses especificado\r\nHOUR\t\t\t= HORA\t\t\t\t##\tConverte um número de série numa hora\r\nMINUTE\t\t\t= MINUTO\t\t\t##\tConverte um número de série num minuto\r\nMONTH\t\t\t= MÊS\t\t\t\t##\tConverte um número de série num mês\r\nNETWORKDAYS\t\t= DIATRABALHOTOTAL\t\t##\tDevolve o número total de dias úteis entre duas datas\r\nNOW\t\t\t= AGORA\t\t\t\t##\tDevolve o número de série da data e hora actuais\r\nSECOND\t\t\t= SEGUNDO\t\t\t##\tConverte um número de série num segundo\r\nTIME\t\t\t= TEMPO\t\t\t\t##\tDevolve o número de série de um determinado tempo\r\nTIMEVALUE\t\t= VALOR.TEMPO\t\t\t##\tConverte um tempo em forma de texto num número de série\r\nTODAY\t\t\t= HOJE\t\t\t\t##\tDevolve o número de série da data actual\r\nWEEKDAY\t\t\t= DIA.SEMANA\t\t\t##\tConverte um número de série num dia da semana\r\nWEEKNUM\t\t\t= NÚMSEMANA\t\t\t##\tConverte um número de série num número que representa o número da semana num determinado ano\r\nWORKDAY\t\t\t= DIA.TRABALHO\t\t\t##\tDevolve o número de série da data antes ou depois de um número de dias úteis especificado\r\nYEAR\t\t\t= ANO\t\t\t\t##\tConverte um número de série num ano\r\nYEARFRAC\t\t= FRACÇÃOANO\t\t\t##\tDevolve a fracção de ano que representa o número de dias inteiros entre a data_de_início e a data_de_fim\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\tFunções de engenharia\r\n##\r\nBESSELI\t\t\t= BESSELI\t\t\t##\tDevolve a função de Bessel modificada In(x)\r\nBESSELJ\t\t\t= BESSELJ\t\t\t##\tDevolve a função de Bessel Jn(x)\r\nBESSELK\t\t\t= BESSELK\t\t\t##\tDevolve a função de Bessel modificada Kn(x)\r\nBESSELY\t\t\t= BESSELY\t\t\t##\tDevolve a função de Bessel Yn(x)\r\nBIN2DEC\t\t\t= BINADEC\t\t\t##\tConverte um número binário em decimal\r\nBIN2HEX\t\t\t= BINAHEX\t\t\t##\tConverte um número binário em hexadecimal\r\nBIN2OCT\t\t\t= BINAOCT\t\t\t##\tConverte um número binário em octal\r\nCOMPLEX\t\t\t= COMPLEXO\t\t\t##\tConverte coeficientes reais e imaginários num número complexo\r\nCONVERT\t\t\t= CONVERTER\t\t\t##\tConverte um número de um sistema de medida noutro\r\nDEC2BIN\t\t\t= DECABIN\t\t\t##\tConverte um número decimal em binário\r\nDEC2HEX\t\t\t= DECAHEX\t\t\t##\tConverte um número decimal em hexadecimal\r\nDEC2OCT\t\t\t= DECAOCT\t\t\t##\tConverte um número decimal em octal\r\nDELTA\t\t\t= DELTA\t\t\t\t##\tTesta se dois valores são iguais\r\nERF\t\t\t= FUNCERRO\t\t\t##\tDevolve a função de erro\r\nERFC\t\t\t= FUNCERROCOMPL\t\t\t##\tDevolve a função de erro complementar\r\nGESTEP\t\t\t= DEGRAU\t\t\t##\tTesta se um número é maior do que um valor limite\r\nHEX2BIN\t\t\t= HEXABIN\t\t\t##\tConverte um número hexadecimal em binário\r\nHEX2DEC\t\t\t= HEXADEC\t\t\t##\tConverte um número hexadecimal em decimal\r\nHEX2OCT\t\t\t= HEXAOCT\t\t\t##\tConverte um número hexadecimal em octal\r\nIMABS\t\t\t= IMABS\t\t\t\t##\tDevolve o valor absoluto (módulo) de um número complexo\r\nIMAGINARY\t\t= IMAGINÁRIO\t\t\t##\tDevolve o coeficiente imaginário de um número complexo\r\nIMARGUMENT\t\t= IMARG\t\t\t\t##\tDevolve o argumento Teta, um ângulo expresso em radianos\r\nIMCONJUGATE\t\t= IMCONJ\t\t\t##\tDevolve o conjugado complexo de um número complexo\r\nIMCOS\t\t\t= IMCOS\t\t\t\t##\tDevolve o co-seno de um número complexo\r\nIMDIV\t\t\t= IMDIV\t\t\t\t##\tDevolve o quociente de dois números complexos\r\nIMEXP\t\t\t= IMEXP\t\t\t\t##\tDevolve o exponencial de um número complexo\r\nIMLN\t\t\t= IMLN\t\t\t\t##\tDevolve o logaritmo natural de um número complexo\r\nIMLOG10\t\t\t= IMLOG10\t\t\t##\tDevolve o logaritmo de base 10 de um número complexo\r\nIMLOG2\t\t\t= IMLOG2\t\t\t##\tDevolve o logaritmo de base 2 de um número complexo\r\nIMPOWER\t\t\t= IMPOT\t\t\t\t##\tDevolve um número complexo elevado a uma potência inteira\r\nIMPRODUCT\t\t= IMPROD\t\t\t##\tDevolve o produto de números complexos\r\nIMREAL\t\t\t= IMREAL\t\t\t##\tDevolve o coeficiente real de um número complexo\r\nIMSIN\t\t\t= IMSENO\t\t\t##\tDevolve o seno de um número complexo\r\nIMSQRT\t\t\t= IMRAIZ\t\t\t##\tDevolve a raiz quadrada de um número complexo\r\nIMSUB\t\t\t= IMSUBTR\t\t\t##\tDevolve a diferença entre dois números complexos\r\nIMSUM\t\t\t= IMSOMA\t\t\t##\tDevolve a soma de números complexos\r\nOCT2BIN\t\t\t= OCTABIN\t\t\t##\tConverte um número octal em binário\r\nOCT2DEC\t\t\t= OCTADEC\t\t\t##\tConverte um número octal em decimal\r\nOCT2HEX\t\t\t= OCTAHEX\t\t\t##\tConverte um número octal em hexadecimal\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\tFunções financeiras\r\n##\r\nACCRINT\t\t\t= JUROSACUM\t\t\t##\tDevolve os juros acumulados de um título que paga juros periódicos\r\nACCRINTM\t\t= JUROSACUMV\t\t\t##\tDevolve os juros acumulados de um título que paga juros no vencimento\r\nAMORDEGRC\t\t= AMORDEGRC\t\t\t##\tDevolve a depreciação correspondente a cada período contabilístico utilizando um coeficiente de depreciação\r\nAMORLINC\t\t= AMORLINC\t\t\t##\tDevolve a depreciação correspondente a cada período contabilístico\r\nCOUPDAYBS\t\t= CUPDIASINLIQ\t\t\t##\tDevolve o número de dias entre o início do período do cupão e a data de regularização\r\nCOUPDAYS\t\t= CUPDIAS\t\t\t##\tDevolve o número de dias no período do cupão que contém a data de regularização\r\nCOUPDAYSNC\t\t= CUPDIASPRÓX\t\t\t##\tDevolve o número de dias entre a data de regularização e a data do cupão seguinte\r\nCOUPNCD\t\t\t= CUPDATAPRÓX\t\t\t##\tDevolve a data do cupão seguinte após a data de regularização\r\nCOUPNUM\t\t\t= CUPNÚM\t\t\t##\tDevolve o número de cupões a serem pagos entre a data de regularização e a data de vencimento\r\nCOUPPCD\t\t\t= CUPDATAANT\t\t\t##\tDevolve a data do cupão anterior antes da data de regularização\r\nCUMIPMT\t\t\t= PGTOJURACUM\t\t\t##\tDevolve os juros cumulativos pagos entre dois períodos\r\nCUMPRINC\t\t= PGTOCAPACUM\t\t\t##\tDevolve o capital cumulativo pago a título de empréstimo entre dois períodos\r\nDB\t\t\t= BD\t\t\t\t##\tDevolve a depreciação de um activo relativo a um período especificado utilizando o método das quotas degressivas fixas\r\nDDB\t\t\t= BDD\t\t\t\t##\tDevolve a depreciação de um activo relativo a um período especificado utilizando o método das quotas degressivas duplas ou qualquer outro método especificado\r\nDISC\t\t\t= DESC\t\t\t\t##\tDevolve a taxa de desconto de um título\r\nDOLLARDE\t\t= MOEDADEC\t\t\t##\tConverte um preço em unidade monetária, expresso como uma fracção, num preço em unidade monetária, expresso como um número decimal\r\nDOLLARFR\t\t= MOEDAFRA\t\t\t##\tConverte um preço em unidade monetária, expresso como um número decimal, num preço em unidade monetária, expresso como uma fracção\r\nDURATION\t\t= DURAÇÃO\t\t\t##\tDevolve a duração anual de um título com pagamentos de juros periódicos\r\nEFFECT\t\t\t= EFECTIVA\t\t\t##\tDevolve a taxa de juros anual efectiva\r\nFV\t\t\t= VF\t\t\t\t##\tDevolve o valor futuro de um investimento\r\nFVSCHEDULE\t\t= VFPLANO\t\t\t##\tDevolve o valor futuro de um capital inicial após a aplicação de uma série de taxas de juro compostas\r\nINTRATE\t\t\t= TAXAJUROS\t\t\t##\tDevolve a taxa de juros de um título investido na totalidade\r\nIPMT\t\t\t= IPGTO\t\t\t\t##\tDevolve o pagamento dos juros de um investimento durante um determinado período\r\nIRR\t\t\t= TIR\t\t\t\t##\tDevolve a taxa de rentabilidade interna para uma série de fluxos monetários\r\nISPMT\t\t\t= É.PGTO\t\t\t##\tCalcula os juros pagos durante um período específico de um investimento\r\nMDURATION\t\t= MDURAÇÃO\t\t\t##\tDevolve a duração modificada de Macauley de um título com um valor de paridade equivalente a € 100\r\nMIRR\t\t\t= MTIR\t\t\t\t##\tDevolve a taxa interna de rentabilidade em que os fluxos monetários positivos e negativos são financiados com taxas diferentes\r\nNOMINAL\t\t\t= NOMINAL\t\t\t##\tDevolve a taxa de juros nominal anual\r\nNPER\t\t\t= NPER\t\t\t\t##\tDevolve o número de períodos de um investimento\r\nNPV\t\t\t= VAL\t\t\t\t##\tDevolve o valor actual líquido de um investimento com base numa série de fluxos monetários periódicos e numa taxa de desconto\r\nODDFPRICE\t\t= PREÇOPRIMINC\t\t\t##\tDevolve o preço por € 100 do valor nominal de um título com um período inicial incompleto\r\nODDFYIELD\t\t= LUCROPRIMINC\t\t\t##\tDevolve o lucro de um título com um período inicial incompleto\r\nODDLPRICE\t\t= PREÇOÚLTINC\t\t\t##\tDevolve o preço por € 100 do valor nominal de um título com um período final incompleto\r\nODDLYIELD\t\t= LUCROÚLTINC\t\t\t##\tDevolve o lucro de um título com um período final incompleto\r\nPMT\t\t\t= PGTO\t\t\t\t##\tDevolve o pagamento periódico de uma anuidade\r\nPPMT\t\t\t= PPGTO\t\t\t\t##\tDevolve o pagamento sobre o capital de um investimento num determinado período\r\nPRICE\t\t\t= PREÇO\t\t\t\t##\tDevolve o preço por € 100 do valor nominal de um título que paga juros periódicos\r\nPRICEDISC\t\t= PREÇODESC\t\t\t##\tDevolve o preço por € 100 do valor nominal de um título descontado\r\nPRICEMAT\t\t= PREÇOVENC\t\t\t##\tDevolve o preço por € 100 do valor nominal de um título que paga juros no vencimento\r\nPV\t\t\t= VA\t\t\t\t##\tDevolve o valor actual de um investimento\r\nRATE\t\t\t= TAXA\t\t\t\t##\tDevolve a taxa de juros por período de uma anuidade\r\nRECEIVED\t\t= RECEBER\t\t\t##\tDevolve o montante recebido no vencimento de um título investido na totalidade\r\nSLN\t\t\t= AMORT\t\t\t\t##\tDevolve uma depreciação linear de um activo durante um período\r\nSYD\t\t\t= AMORTD\t\t\t##\tDevolve a depreciação por algarismos da soma dos anos de um activo durante um período especificado\r\nTBILLEQ\t\t\t= OTN\t\t\t\t##\tDevolve o lucro de um título equivalente a uma Obrigação do Tesouro\r\nTBILLPRICE\t\t= OTNVALOR\t\t\t##\tDevolve o preço por € 100 de valor nominal de uma Obrigação do Tesouro\r\nTBILLYIELD\t\t= OTNLUCRO\t\t\t##\tDevolve o lucro de uma Obrigação do Tesouro\r\nVDB\t\t\t= BDV\t\t\t\t##\tDevolve a depreciação de um activo relativo a um período específico ou parcial utilizando um método de quotas degressivas\r\nXIRR\t\t\t= XTIR\t\t\t\t##\tDevolve a taxa interna de rentabilidade de um plano de fluxos monetários que não seja necessariamente periódica\r\nXNPV\t\t\t= XVAL\t\t\t\t##\tDevolve o valor actual líquido de um plano de fluxos monetários que não seja necessariamente periódico\r\nYIELD\t\t\t= LUCRO\t\t\t\t##\tDevolve o lucro de um título que paga juros periódicos\r\nYIELDDISC\t\t= LUCRODESC\t\t\t##\tDevolve o lucro anual de um título emitido abaixo do valor nominal, por exemplo, uma Obrigação do Tesouro\r\nYIELDMAT\t\t= LUCROVENC\t\t\t##\tDevolve o lucro anual de um título que paga juros na data de vencimento\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\tFunções de informação\r\n##\r\nCELL\t\t\t= CÉL\t\t\t\t##\tDevolve informações sobre a formatação, localização ou conteúdo de uma célula\r\nERROR.TYPE\t\t= TIPO.ERRO\t\t\t##\tDevolve um número correspondente a um tipo de erro\r\nINFO\t\t\t= INFORMAÇÃO\t\t\t##\tDevolve informações sobre o ambiente de funcionamento actual\r\nISBLANK\t\t\t= É.CÉL.VAZIA\t\t\t##\tDevolve VERDADEIRO se o valor estiver em branco\r\nISERR\t\t\t= É.ERROS\t\t\t##\tDevolve VERDADEIRO se o valor for um valor de erro diferente de #N/D\r\nISERROR\t\t\t= É.ERRO\t\t\t##\tDevolve VERDADEIRO se o valor for um valor de erro\r\nISEVEN\t\t\t= ÉPAR\t\t\t\t##\tDevolve VERDADEIRO se o número for par\r\nISLOGICAL\t\t= É.LÓGICO\t\t\t##\tDevolve VERDADEIRO se o valor for lógico\r\nISNA\t\t\t= É.NÃO.DISP\t\t\t##\tDevolve VERDADEIRO se o valor for o valor de erro #N/D\r\nISNONTEXT\t\t= É.NÃO.TEXTO\t\t\t##\tDevolve VERDADEIRO se o valor não for texto\r\nISNUMBER\t\t= É.NÚM\t\t\t\t##\tDevolve VERDADEIRO se o valor for um número\r\nISODD\t\t\t= ÉÍMPAR\t\t\t##\tDevolve VERDADEIRO se o número for ímpar\r\nISREF\t\t\t= É.REF\t\t\t\t##\tDevolve VERDADEIRO se o valor for uma referência\r\nISTEXT\t\t\t= É.TEXTO\t\t\t##\tDevolve VERDADEIRO se o valor for texto\r\nN\t\t\t= N\t\t\t\t##\tDevolve um valor convertido num número\r\nNA\t\t\t= NÃO.DISP\t\t\t##\tDevolve o valor de erro #N/D\r\nTYPE\t\t\t= TIPO\t\t\t\t##\tDevolve um número que indica o tipo de dados de um valor\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\tFunções lógicas\r\n##\r\nAND\t\t\t= E\t\t\t\t##\tDevolve VERDADEIRO se todos os respectivos argumentos corresponderem a VERDADEIRO\r\nFALSE\t\t\t= FALSO\t\t\t\t##\tDevolve o valor lógico FALSO\r\nIF\t\t\t= SE\t\t\t\t##\tEspecifica um teste lógico a ser executado\r\nIFERROR\t\t\t= SE.ERRO\t\t\t##\tDevolve um valor definido pelo utilizador se ocorrer um erro na fórmula, e devolve o resultado da fórmula se não ocorrer nenhum erro\r\nNOT\t\t\t= NÃO\t\t\t\t##\tInverte a lógica do respectivo argumento\r\nOR\t\t\t= OU\t\t\t\t##\tDevolve VERDADEIRO se qualquer argumento for VERDADEIRO\r\nTRUE\t\t\t= VERDADEIRO\t\t\t##\tDevolve o valor lógico VERDADEIRO\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\tFunções de pesquisa e referência\r\n##\r\nADDRESS\t\t\t= ENDEREÇO\t\t\t##\tDevolve uma referência a uma única célula numa folha de cálculo como texto\r\nAREAS\t\t\t= ÁREAS\t\t\t\t##\tDevolve o número de áreas numa referência\r\nCHOOSE\t\t\t= SELECCIONAR\t\t\t##\tSelecciona um valor a partir de uma lista de valores\r\nCOLUMN\t\t\t= COL\t\t\t\t##\tDevolve o número da coluna de uma referência\r\nCOLUMNS\t\t\t= COLS\t\t\t\t##\tDevolve o número de colunas numa referência\r\nHLOOKUP\t\t\t= PROCH\t\t\t\t##\tProcura na linha superior de uma matriz e devolve o valor da célula indicada\r\nHYPERLINK\t\t= HIPERLIGAÇÃO\t\t\t##\tCria um atalho ou hiperligação que abre um documento armazenado num servidor de rede, numa intranet ou na Internet\r\nINDEX\t\t\t= ÍNDICE\t\t\t##\tUtiliza um índice para escolher um valor de uma referência ou de uma matriz\r\nINDIRECT\t\t= INDIRECTO\t\t\t##\tDevolve uma referência indicada por um valor de texto\r\nLOOKUP\t\t\t= PROC\t\t\t\t##\tProcura valores num vector ou numa matriz\r\nMATCH\t\t\t= CORRESP\t\t\t##\tProcura valores numa referência ou numa matriz\r\nOFFSET\t\t\t= DESLOCAMENTO\t\t\t##\tDevolve o deslocamento de referência de uma determinada referência\r\nROW\t\t\t= LIN\t\t\t\t##\tDevolve o número da linha de uma referência\r\nROWS\t\t\t= LINS\t\t\t\t##\tDevolve o número de linhas numa referência\r\nRTD\t\t\t= RTD\t\t\t\t##\tObtém dados em tempo real a partir de um programa que suporte automatização COM (automatização: modo de trabalhar com objectos de uma aplicação a partir de outra aplicação ou ferramenta de desenvolvimento. Anteriormente conhecida como automatização OLE, a automatização é uma norma da indústria de software e uma funcionalidade COM (Component Object Model).)\r\nTRANSPOSE\t\t= TRANSPOR\t\t\t##\tDevolve a transposição de uma matriz\r\nVLOOKUP\t\t\t= PROCV\t\t\t\t##\tProcura na primeira coluna de uma matriz e percorre a linha para devolver o valor de uma célula\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\tFunções matemáticas e trigonométricas\r\n##\r\nABS\t\t\t= ABS\t\t\t\t##\tDevolve o valor absoluto de um número\r\nACOS\t\t\t= ACOS\t\t\t\t##\tDevolve o arco de co-seno de um número\r\nACOSH\t\t\t= ACOSH\t\t\t\t##\tDevolve o co-seno hiperbólico inverso de um número\r\nASIN\t\t\t= ASEN\t\t\t\t##\tDevolve o arco de seno de um número\r\nASINH\t\t\t= ASENH\t\t\t\t##\tDevolve o seno hiperbólico inverso de um número\r\nATAN\t\t\t= ATAN\t\t\t\t##\tDevolve o arco de tangente de um número\r\nATAN2\t\t\t= ATAN2\t\t\t\t##\tDevolve o arco de tangente das coordenadas x e y\r\nATANH\t\t\t= ATANH\t\t\t\t##\tDevolve a tangente hiperbólica inversa de um número\r\nCEILING\t\t\t= ARRED.EXCESSO\t\t\t##\tArredonda um número para o número inteiro mais próximo ou para o múltiplo de significância mais próximo\r\nCOMBIN\t\t\t= COMBIN\t\t\t##\tDevolve o número de combinações de um determinado número de objectos\r\nCOS\t\t\t= COS\t\t\t\t##\tDevolve o co-seno de um número\r\nCOSH\t\t\t= COSH\t\t\t\t##\tDevolve o co-seno hiperbólico de um número\r\nDEGREES\t\t\t= GRAUS\t\t\t\t##\tConverte radianos em graus\r\nEVEN\t\t\t= PAR\t\t\t\t##\tArredonda um número por excesso para o número inteiro mais próximo\r\nEXP\t\t\t= EXP\t\t\t\t##\tDevolve e elevado à potência de um determinado número\r\nFACT\t\t\t= FACTORIAL\t\t\t##\tDevolve o factorial de um número\r\nFACTDOUBLE\t\t= FACTDUPLO\t\t\t##\tDevolve o factorial duplo de um número\r\nFLOOR\t\t\t= ARRED.DEFEITO\t\t\t##\tArredonda um número por defeito até zero\r\nGCD\t\t\t= MDC\t\t\t\t##\tDevolve o maior divisor comum\r\nINT\t\t\t= INT\t\t\t\t##\tArredonda um número por defeito para o número inteiro mais próximo\r\nLCM\t\t\t= MMC\t\t\t\t##\tDevolve o mínimo múltiplo comum\r\nLN\t\t\t= LN\t\t\t\t##\tDevolve o logaritmo natural de um número\r\nLOG\t\t\t= LOG\t\t\t\t##\tDevolve o logaritmo de um número com uma base especificada\r\nLOG10\t\t\t= LOG10\t\t\t\t##\tDevolve o logaritmo de base 10 de um número\r\nMDETERM\t\t\t= MATRIZ.DETERM\t\t\t##\tDevolve o determinante matricial de uma matriz\r\nMINVERSE\t\t= MATRIZ.INVERSA\t\t##\tDevolve o inverso matricial de uma matriz\r\nMMULT\t\t\t= MATRIZ.MULT\t\t\t##\tDevolve o produto matricial de duas matrizes\r\nMOD\t\t\t= RESTO\t\t\t\t##\tDevolve o resto da divisão\r\nMROUND\t\t\t= MARRED\t\t\t##\tDevolve um número arredondado para o múltiplo pretendido\r\nMULTINOMIAL\t\t= POLINOMIAL\t\t\t##\tDevolve o polinomial de um conjunto de números\r\nODD\t\t\t= ÍMPAR\t\t\t\t##\tArredonda por excesso um número para o número inteiro ímpar mais próximo\r\nPI\t\t\t= PI\t\t\t\t##\tDevolve o valor de pi\r\nPOWER\t\t\t= POTÊNCIA\t\t\t##\tDevolve o resultado de um número elevado a uma potência\r\nPRODUCT\t\t\t= PRODUTO\t\t\t##\tMultiplica os respectivos argumentos\r\nQUOTIENT\t\t= QUOCIENTE\t\t\t##\tDevolve a parte inteira de uma divisão\r\nRADIANS\t\t\t= RADIANOS\t\t\t##\tConverte graus em radianos\r\nRAND\t\t\t= ALEATÓRIO\t\t\t##\tDevolve um número aleatório entre 0 e 1\r\nRANDBETWEEN\t\t= ALEATÓRIOENTRE\t\t##\tDevolve um número aleatório entre os números especificados\r\nROMAN\t\t\t= ROMANO\t\t\t##\tConverte um número árabe em romano, como texto\r\nROUND\t\t\t= ARRED\t\t\t\t##\tArredonda um número para um número de dígitos especificado\r\nROUNDDOWN\t\t= ARRED.PARA.BAIXO\t\t##\tArredonda um número por defeito até zero\r\nROUNDUP\t\t\t= ARRED.PARA.CIMA\t\t##\tArredonda um número por excesso, afastando-o de zero\r\nSERIESSUM\t\t= SOMASÉRIE\t\t\t##\tDevolve a soma de uma série de potências baseada na fórmula\r\nSIGN\t\t\t= SINAL\t\t\t\t##\tDevolve o sinal de um número\r\nSIN\t\t\t= SEN\t\t\t\t##\tDevolve o seno de um determinado ângulo\r\nSINH\t\t\t= SENH\t\t\t\t##\tDevolve o seno hiperbólico de um número\r\nSQRT\t\t\t= RAIZQ\t\t\t\t##\tDevolve uma raiz quadrada positiva\r\nSQRTPI\t\t\t= RAIZPI\t\t\t##\tDevolve a raiz quadrada de (núm * pi)\r\nSUBTOTAL\t\t= SUBTOTAL\t\t\t##\tDevolve um subtotal numa lista ou base de dados\r\nSUM\t\t\t= SOMA\t\t\t\t##\tAdiciona os respectivos argumentos\r\nSUMIF\t\t\t= SOMA.SE\t\t\t##\tAdiciona as células especificadas por um determinado critério\r\nSUMIFS\t\t\t= SOMA.SE.S\t\t\t##\tAdiciona as células num intervalo que cumpre vários critérios\r\nSUMPRODUCT\t\t= SOMARPRODUTO\t\t\t##\tDevolve a soma dos produtos de componentes de matrizes correspondentes\r\nSUMSQ\t\t\t= SOMARQUAD\t\t\t##\tDevolve a soma dos quadrados dos argumentos\r\nSUMX2MY2\t\t= SOMAX2DY2\t\t\t##\tDevolve a soma da diferença dos quadrados dos valores correspondentes em duas matrizes\r\nSUMX2PY2\t\t= SOMAX2SY2\t\t\t##\tDevolve a soma da soma dos quadrados dos valores correspondentes em duas matrizes\r\nSUMXMY2\t\t\t= SOMAXMY2\t\t\t##\tDevolve a soma dos quadrados da diferença dos valores correspondentes em duas matrizes\r\nTAN\t\t\t= TAN\t\t\t\t##\tDevolve a tangente de um número\r\nTANH\t\t\t= TANH\t\t\t\t##\tDevolve a tangente hiperbólica de um número\r\nTRUNC\t\t\t= TRUNCAR\t\t\t##\tTrunca um número para um número inteiro\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\tFunções estatísticas\r\n##\r\nAVEDEV\t\t\t= DESV.MÉDIO\t\t\t##\tDevolve a média aritmética dos desvios absolutos à média dos pontos de dados\r\nAVERAGE\t\t\t= MÉDIA\t\t\t\t##\tDevolve a média dos respectivos argumentos\r\nAVERAGEA\t\t= MÉDIAA\t\t\t##\tDevolve uma média dos respectivos argumentos, incluindo números, texto e valores lógicos\r\nAVERAGEIF\t\t= MÉDIA.SE\t\t\t##\tDevolve a média aritmética de todas as células num intervalo que cumprem determinado critério\r\nAVERAGEIFS\t\t= MÉDIA.SE.S\t\t\t##\tDevolve a média aritmética de todas as células que cumprem múltiplos critérios\r\nBETADIST\t\t= DISTBETA\t\t\t##\tDevolve a função de distribuição cumulativa beta\r\nBETAINV\t\t\t= BETA.ACUM.INV\t\t\t##\tDevolve o inverso da função de distribuição cumulativa relativamente a uma distribuição beta específica\r\nBINOMDIST\t\t= DISTRBINOM\t\t\t##\tDevolve a probabilidade de distribuição binomial de termo individual\r\nCHIDIST\t\t\t= DIST.CHI\t\t\t##\tDevolve a probabilidade unicaudal da distribuição qui-quadrada\r\nCHIINV\t\t\t= INV.CHI\t\t\t##\tDevolve o inverso da probabilidade unicaudal da distribuição qui-quadrada\r\nCHITEST\t\t\t= TESTE.CHI\t\t\t##\tDevolve o teste para independência\r\nCONFIDENCE\t\t= INT.CONFIANÇA\t\t\t##\tDevolve o intervalo de confiança correspondente a uma média de população\r\nCORREL\t\t\t= CORREL\t\t\t##\tDevolve o coeficiente de correlação entre dois conjuntos de dados\r\nCOUNT\t\t\t= CONTAR\t\t\t##\tConta os números que existem na lista de argumentos\r\nCOUNTA\t\t\t= CONTAR.VAL\t\t\t##\tConta os valores que existem na lista de argumentos\r\nCOUNTBLANK\t\t= CONTAR.VAZIO\t\t\t##\tConta o número de células em branco num intervalo\r\nCOUNTIF\t\t\t= CONTAR.SE\t\t\t##\tCalcula o número de células num intervalo que corresponde aos critérios determinados\r\nCOUNTIFS\t\t= CONTAR.SE.S\t\t\t##\tConta o número de células num intervalo que cumprem múltiplos critérios\r\nCOVAR\t\t\t= COVAR\t\t\t\t##\tDevolve a covariância, que é a média dos produtos de desvios de pares\r\nCRITBINOM\t\t= CRIT.BINOM\t\t\t##\tDevolve o menor valor em que a distribuição binomial cumulativa é inferior ou igual a um valor de critério\r\nDEVSQ\t\t\t= DESVQ\t\t\t\t##\tDevolve a soma dos quadrados dos desvios\r\nEXPONDIST\t\t= DISTEXPON\t\t\t##\tDevolve a distribuição exponencial\r\nFDIST\t\t\t= DISTF\t\t\t\t##\tDevolve a distribuição da probabilidade F\r\nFINV\t\t\t= INVF\t\t\t\t##\tDevolve o inverso da distribuição da probabilidade F\r\nFISHER\t\t\t= FISHER\t\t\t##\tDevolve a transformação Fisher\r\nFISHERINV\t\t= FISHERINV\t\t\t##\tDevolve o inverso da transformação Fisher\r\nFORECAST\t\t= PREVISÃO\t\t\t##\tDevolve um valor ao longo de uma tendência linear\r\nFREQUENCY\t\t= FREQUÊNCIA\t\t\t##\tDevolve uma distribuição de frequência como uma matriz vertical\r\nFTEST\t\t\t= TESTEF\t\t\t##\tDevolve o resultado de um teste F\r\nGAMMADIST\t\t= DISTGAMA\t\t\t##\tDevolve a distribuição gama\r\nGAMMAINV\t\t= INVGAMA\t\t\t##\tDevolve o inverso da distribuição gama cumulativa\r\nGAMMALN\t\t\t= LNGAMA\t\t\t##\tDevolve o logaritmo natural da função gama, Γ(x)\r\nGEOMEAN\t\t\t= MÉDIA.GEOMÉTRICA\t\t##\tDevolve a média geométrica\r\nGROWTH\t\t\t= CRESCIMENTO\t\t\t##\tDevolve valores ao longo de uma tendência exponencial\r\nHARMEAN\t\t\t= MÉDIA.HARMÓNICA\t\t##\tDevolve a média harmónica\r\nHYPGEOMDIST\t\t= DIST.HIPERGEOM\t\t##\tDevolve a distribuição hipergeométrica\r\nINTERCEPT\t\t= INTERCEPTAR\t\t\t##\tDevolve a intercepção da linha de regressão linear\r\nKURT\t\t\t= CURT\t\t\t\t##\tDevolve a curtose de um conjunto de dados\r\nLARGE\t\t\t= MAIOR\t\t\t\t##\tDevolve o maior valor k-ésimo de um conjunto de dados\r\nLINEST\t\t\t= PROJ.LIN\t\t\t##\tDevolve os parâmetros de uma tendência linear\r\nLOGEST\t\t\t= PROJ.LOG\t\t\t##\tDevolve os parâmetros de uma tendência exponencial\r\nLOGINV\t\t\t= INVLOG\t\t\t##\tDevolve o inverso da distribuição normal logarítmica\r\nLOGNORMDIST\t\t= DIST.NORMALLOG\t\t##\tDevolve a distribuição normal logarítmica cumulativa\r\nMAX\t\t\t= MÁXIMO\t\t\t##\tDevolve o valor máximo numa lista de argumentos\r\nMAXA\t\t\t= MÁXIMOA\t\t\t##\tDevolve o valor máximo numa lista de argumentos, incluindo números, texto e valores lógicos\r\nMEDIAN\t\t\t= MED\t\t\t\t##\tDevolve a mediana dos números indicados\r\nMIN\t\t\t= MÍNIMO\t\t\t##\tDevolve o valor mínimo numa lista de argumentos\r\nMINA\t\t\t= MÍNIMOA\t\t\t##\tDevolve o valor mínimo numa lista de argumentos, incluindo números, texto e valores lógicos\r\nMODE\t\t\t= MODA\t\t\t\t##\tDevolve o valor mais comum num conjunto de dados\r\nNEGBINOMDIST\t\t= DIST.BIN.NEG\t\t\t##\tDevolve a distribuição binominal negativa\r\nNORMDIST\t\t= DIST.NORM\t\t\t##\tDevolve a distribuição cumulativa normal\r\nNORMINV\t\t\t= INV.NORM\t\t\t##\tDevolve o inverso da distribuição cumulativa normal\r\nNORMSDIST\t\t= DIST.NORMP\t\t\t##\tDevolve a distribuição cumulativa normal padrão\r\nNORMSINV\t\t= INV.NORMP\t\t\t##\tDevolve o inverso da distribuição cumulativa normal padrão\r\nPEARSON\t\t\t= PEARSON\t\t\t##\tDevolve o coeficiente de correlação momento/produto de Pearson\r\nPERCENTILE\t\t= PERCENTIL\t\t\t##\tDevolve o k-ésimo percentil de valores num intervalo\r\nPERCENTRANK\t\t= ORDEM.PERCENTUAL\t\t##\tDevolve a ordem percentual de um valor num conjunto de dados\r\nPERMUT\t\t\t= PERMUTAR\t\t\t##\tDevolve o número de permutações de um determinado número de objectos\r\nPOISSON\t\t\t= POISSON\t\t\t##\tDevolve a distribuição de Poisson\r\nPROB\t\t\t= PROB\t\t\t\t##\tDevolve a probabilidade dos valores num intervalo se encontrarem entre dois limites\r\nQUARTILE\t\t= QUARTIL\t\t\t##\tDevolve o quartil de um conjunto de dados\r\nRANK\t\t\t= ORDEM\t\t\t\t##\tDevolve a ordem de um número numa lista numérica\r\nRSQ\t\t\t= RQUAD\t\t\t\t##\tDevolve o quadrado do coeficiente de correlação momento/produto de Pearson\r\nSKEW\t\t\t= DISTORÇÃO\t\t\t##\tDevolve a distorção de uma distribuição\r\nSLOPE\t\t\t= DECLIVE\t\t\t##\tDevolve o declive da linha de regressão linear\r\nSMALL\t\t\t= MENOR\t\t\t\t##\tDevolve o menor valor de k-ésimo de um conjunto de dados\r\nSTANDARDIZE\t\t= NORMALIZAR\t\t\t##\tDevolve um valor normalizado\r\nSTDEV\t\t\t= DESVPAD\t\t\t##\tCalcula o desvio-padrão com base numa amostra\r\nSTDEVA\t\t\t= DESVPADA\t\t\t##\tCalcula o desvio-padrão com base numa amostra, incluindo números, texto e valores lógicos\r\nSTDEVP\t\t\t= DESVPADP\t\t\t##\tCalcula o desvio-padrão com base na população total\r\nSTDEVPA\t\t\t= DESVPADPA\t\t\t##\tCalcula o desvio-padrão com base na população total, incluindo números, texto e valores lógicos\r\nSTEYX\t\t\t= EPADYX\t\t\t##\tDevolve o erro-padrão do valor de y previsto para cada x na regressão\r\nTDIST\t\t\t= DISTT\t\t\t\t##\tDevolve a distribuição t de Student\r\nTINV\t\t\t= INVT\t\t\t\t##\tDevolve o inverso da distribuição t de Student\r\nTREND\t\t\t= TENDÊNCIA\t\t\t##\tDevolve valores ao longo de uma tendência linear\r\nTRIMMEAN\t\t= MÉDIA.INTERNA\t\t\t##\tDevolve a média do interior de um conjunto de dados\r\nTTEST\t\t\t= TESTET\t\t\t##\tDevolve a probabilidade associada ao teste t de Student\r\nVAR\t\t\t= VAR\t\t\t\t##\tCalcula a variância com base numa amostra\r\nVARA\t\t\t= VARA\t\t\t\t##\tCalcula a variância com base numa amostra, incluindo números, texto e valores lógicos\r\nVARP\t\t\t= VARP\t\t\t\t##\tCalcula a variância com base na população total\r\nVARPA\t\t\t= VARPA\t\t\t\t##\tCalcula a variância com base na população total, incluindo números, texto e valores lógicos\r\nWEIBULL\t\t\t= WEIBULL\t\t\t##\tDevolve a distribuição Weibull\r\nZTEST\t\t\t= TESTEZ\t\t\t##\tDevolve o valor de probabilidade unicaudal de um teste-z\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\tFunções de texto\r\n##\r\nASC\t\t\t= ASC\t\t\t\t##\tAltera letras ou katakana de largura total (byte duplo) numa cadeia de caracteres para caracteres de largura média (byte único)\r\nBAHTTEXT\t\t= TEXTO.BAHT\t\t\t##\tConverte um número em texto, utilizando o formato monetário ß (baht)\r\nCHAR\t\t\t= CARÁCT\t\t\t##\tDevolve o carácter especificado pelo número de código\r\nCLEAN\t\t\t= LIMPAR\t\t\t##\tRemove do texto todos os caracteres não imprimíveis\r\nCODE\t\t\t= CÓDIGO\t\t\t##\tDevolve um código numérico correspondente ao primeiro carácter numa cadeia de texto\r\nCONCATENATE\t\t= CONCATENAR\t\t\t##\tAgrupa vários itens de texto num único item de texto\r\nDOLLAR\t\t\t= MOEDA\t\t\t\t##\tConverte um número em texto, utilizando o formato monetário € (Euro)\r\nEXACT\t\t\t= EXACTO\t\t\t##\tVerifica se dois valores de texto são idênticos\r\nFIND\t\t\t= LOCALIZAR\t\t\t##\tLocaliza um valor de texto dentro de outro (sensível às maiúsculas e minúsculas)\r\nFINDB\t\t\t= LOCALIZARB\t\t\t##\tLocaliza um valor de texto dentro de outro (sensível às maiúsculas e minúsculas)\r\nFIXED\t\t\t= FIXA\t\t\t\t##\tFormata um número como texto com um número fixo de decimais\r\nJIS\t\t\t= JIS\t\t\t\t##\tAltera letras ou katakana de largura média (byte único) numa cadeia de caracteres para caracteres de largura total (byte duplo)\r\nLEFT\t\t\t= ESQUERDA\t\t\t##\tDevolve os caracteres mais à esquerda de um valor de texto\r\nLEFTB\t\t\t= ESQUERDAB\t\t\t##\tDevolve os caracteres mais à esquerda de um valor de texto\r\nLEN\t\t\t= NÚM.CARACT\t\t\t##\tDevolve o número de caracteres de uma cadeia de texto\r\nLENB\t\t\t= NÚM.CARACTB\t\t\t##\tDevolve o número de caracteres de uma cadeia de texto\r\nLOWER\t\t\t= MINÚSCULAS\t\t\t##\tConverte o texto em minúsculas\r\nMID\t\t\t= SEG.TEXTO\t\t\t##\tDevolve um número específico de caracteres de uma cadeia de texto, a partir da posição especificada\r\nMIDB\t\t\t= SEG.TEXTOB\t\t\t##\tDevolve um número específico de caracteres de uma cadeia de texto, a partir da posição especificada\r\nPHONETIC\t\t= FONÉTICA\t\t\t##\tRetira os caracteres fonéticos (furigana) de uma cadeia de texto\r\nPROPER\t\t\t= INICIAL.MAIÚSCULA\t\t##\tColoca em maiúsculas a primeira letra de cada palavra de um valor de texto\r\nREPLACE\t\t\t= SUBSTITUIR\t\t\t##\tSubstitui caracteres no texto\r\nREPLACEB\t\t= SUBSTITUIRB\t\t\t##\tSubstitui caracteres no texto\r\nREPT\t\t\t= REPETIR\t\t\t##\tRepete texto um determinado número de vezes\r\nRIGHT\t\t\t= DIREITA\t\t\t##\tDevolve os caracteres mais à direita de um valor de texto\r\nRIGHTB\t\t\t= DIREITAB\t\t\t##\tDevolve os caracteres mais à direita de um valor de texto\r\nSEARCH\t\t\t= PROCURAR\t\t\t##\tLocaliza um valor de texto dentro de outro (não sensível a maiúsculas e minúsculas)\r\nSEARCHB\t\t\t= PROCURARB\t\t\t##\tLocaliza um valor de texto dentro de outro (não sensível a maiúsculas e minúsculas)\r\nSUBSTITUTE\t\t= SUBST\t\t\t\t##\tSubstitui texto novo por texto antigo numa cadeia de texto\r\nT\t\t\t= T\t\t\t\t##\tConverte os respectivos argumentos em texto\r\nTEXT\t\t\t= TEXTO\t\t\t\t##\tFormata um número e converte-o em texto\r\nTRIM\t\t\t= COMPACTAR\t\t\t##\tRemove espaços do texto\r\nUPPER\t\t\t= MAIÚSCULAS\t\t\t##\tConverte texto em maiúsculas\r\nVALUE\t\t\t= VALOR\t\t\t\t##\tConverte um argumento de texto num número\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= р\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #ПУСТО!\r\nDIV0\t= #ДЕЛ/0!\r\nVALUE\t= #ЗНАЧ!\r\nREF\t= #ССЫЛ!\r\nNAME\t= #ИМЯ?\r\nNUM\t= #ЧИСЛО!\r\nNA\t= #Н/Д\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/ru/functions",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Calculation\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n## Data in this file derived from information provided by web-junior (http://www.web-junior.net/)\r\n##\r\n##\r\n\r\n\r\n##\r\n##\tAdd-in and Automation functions\t\t\t\tФункции надстроек и автоматизации\r\n##\r\nGETPIVOTDATA\t\t= ПОЛУЧИТЬ.ДАННЫЕ.СВОДНОЙ.ТАБЛИЦЫ\t##\tВозвращает данные, хранящиеся в отчете сводной таблицы.\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\t\tФункции Куб\r\n##\r\nCUBEKPIMEMBER\t\t= КУБЭЛЕМЕНТКИП\t\t\t\t##\tВозвращает свойство ключевого индикатора производительности «(КИП)» и отображает имя «КИП» в ячейке. «КИП» представляет собой количественную величину, такую как ежемесячная валовая прибыль или ежеквартальная текучесть кадров, используемой для контроля эффективности работы организации.\r\nCUBEMEMBER\t\t= КУБЭЛЕМЕНТ\t\t\t\t##\tВозвращает элемент или кортеж из куба. Используется для проверки существования элемента или кортежа в кубе.\r\nCUBEMEMBERPROPERTY\t= КУБСВОЙСТВОЭЛЕМЕНТА\t\t\t##\tВозвращает значение свойства элемента из куба. Используется для проверки существования имени элемента в кубе и возвращает указанное свойство для этого элемента.\r\nCUBERANKEDMEMBER\t= КУБПОРЭЛЕМЕНТ\t\t\t\t##\tВозвращает n-ый или ранжированный элемент в множество. Используется для возвращения одного или нескольких элементов в множество, например, лучшего продавца или 10 лучших студентов.\r\nCUBESET\t\t\t= КУБМНОЖ\t\t\t\t##\tОпределяет вычислительное множество элементов или кортежей, отправляя на сервер выражение, которое создает множество, а затем возвращает его в Microsoft Office Excel.\r\nCUBESETCOUNT\t\t= КУБЧИСЛОЭЛМНОЖ\t\t\t##\tВозвращает число элементов множества.\r\nCUBEVALUE\t\t= КУБЗНАЧЕНИЕ\t\t\t\t##\tВозвращает обобщенное значение из куба.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\t\tФункции для работы с базами данных\r\n##\r\nDAVERAGE\t\t= ДСРЗНАЧ\t\t\t\t##\tВозвращает среднее значение выбранных записей базы данных.\r\nDCOUNT\t\t\t= БСЧЁТ\t\t\t\t\t##\tПодсчитывает количество числовых ячеек в базе данных.\r\nDCOUNTA\t\t\t= БСЧЁТА\t\t\t\t##\tПодсчитывает количество непустых ячеек в базе данных.\r\nDGET\t\t\t= БИЗВЛЕЧЬ\t\t\t\t##\tИзвлекает из базы данных одну запись, удовлетворяющую заданному условию.\r\nDMAX\t\t\t= ДМАКС\t\t\t\t\t##\tВозвращает максимальное значение среди выделенных записей базы данных.\r\nDMIN\t\t\t= ДМИН\t\t\t\t\t##\tВозвращает минимальное значение среди выделенных записей базы данных.\r\nDPRODUCT\t\t= БДПРОИЗВЕД\t\t\t\t##\tПеремножает значения определенного поля в записях базы данных, удовлетворяющих условию.\r\nDSTDEV\t\t\t= ДСТАНДОТКЛ\t\t\t\t##\tОценивает стандартное отклонение по выборке для выделенных записей базы данных.\r\nDSTDEVP\t\t\t= ДСТАНДОТКЛП\t\t\t\t##\tВычисляет стандартное отклонение по генеральной совокупности для выделенных записей базы данных\r\nDSUM\t\t\t= БДСУММ\t\t\t\t##\tСуммирует числа в поле для записей базы данных, удовлетворяющих условию.\r\nDVAR\t\t\t= БДДИСП\t\t\t\t##\tОценивает дисперсию по выборке из выделенных записей базы данных\r\nDVARP\t\t\t= БДДИСПП\t\t\t\t##\tВычисляет дисперсию по генеральной совокупности для выделенных записей базы данных\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\t\tФункции даты и времени\r\n##\r\nDATE\t\t\t= ДАТА\t\t\t\t\t##\tВозвращает заданную дату в числовом формате.\r\nDATEVALUE\t\t= ДАТАЗНАЧ\t\t\t\t##\tПреобразует дату из текстового формата в числовой формат.\r\nDAY\t\t\t= ДЕНЬ\t\t\t\t\t##\tПреобразует дату в числовом формате в день месяца.\r\nDAYS360\t\t\t= ДНЕЙ360\t\t\t\t##\tВычисляет количество дней между двумя датами на основе 360-дневного года.\r\nEDATE\t\t\t= ДАТАМЕС\t\t\t\t##\tВозвращает дату в числовом формате, отстоящую на заданное число месяцев вперед или назад от начальной даты.\r\nEOMONTH\t\t\t= КОНМЕСЯЦА\t\t\t\t##\tВозвращает дату в числовом формате для последнего дня месяца, отстоящего вперед или назад на заданное число месяцев.\r\nHOUR\t\t\t= ЧАС\t\t\t\t\t##\tПреобразует дату в числовом формате в часы.\r\nMINUTE\t\t\t= МИНУТЫ\t\t\t\t##\tПреобразует дату в числовом формате в минуты.\r\nMONTH\t\t\t= МЕСЯЦ\t\t\t\t\t##\tПреобразует дату в числовом формате в месяцы.\r\nNETWORKDAYS\t\t= ЧИСТРАБДНИ\t\t\t\t##\tВозвращает количество рабочих дней между двумя датами.\r\nNOW\t\t\t= ТДАТА\t\t\t\t\t##\tВозвращает текущую дату и время в числовом формате.\r\nSECOND\t\t\t= СЕКУНДЫ\t\t\t\t##\tПреобразует дату в числовом формате в секунды.\r\nTIME\t\t\t= ВРЕМЯ\t\t\t\t\t##\tВозвращает заданное время в числовом формате.\r\nTIMEVALUE\t\t= ВРЕМЗНАЧ\t\t\t\t##\tПреобразует время из текстового формата в числовой формат.\r\nTODAY\t\t\t= СЕГОДНЯ\t\t\t\t##\tВозвращает текущую дату в числовом формате.\r\nWEEKDAY\t\t\t= ДЕНЬНЕД\t\t\t\t##\tПреобразует дату в числовом формате в день недели.\r\nWEEKNUM\t\t\t= НОМНЕДЕЛИ\t\t\t\t##\tПреобразует числовое представление в число, которое указывает, на какую неделю года приходится указанная дата.\r\nWORKDAY\t\t\t= РАБДЕНЬ\t\t\t\t##\tВозвращает дату в числовом формате, отстоящую вперед или назад на заданное количество рабочих дней.\r\nYEAR\t\t\t= ГОД\t\t\t\t\t##\tПреобразует дату в числовом формате в год.\r\nYEARFRAC\t\t= ДОЛЯГОДА\t\t\t\t##\tВозвращает долю года, которую составляет количество дней между начальной и конечной датами.\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\t\tИнженерные функции\r\n##\r\nBESSELI\t\t\t= БЕССЕЛЬ.I\t \t\t\t##\tВозвращает модифицированную функцию Бесселя In(x).\r\nBESSELJ\t\t\t= БЕССЕЛЬ.J\t\t\t\t##\tВозвращает функцию Бесселя Jn(x).\r\nBESSELK\t\t\t= БЕССЕЛЬ.K\t\t\t\t##\tВозвращает модифицированную функцию Бесселя Kn(x).\r\nBESSELY\t\t\t= БЕССЕЛЬ.Y\t\t\t\t##\tВозвращает функцию Бесселя Yn(x).\r\nBIN2DEC\t\t\t= ДВ.В.ДЕС\t\t\t\t##\tПреобразует двоичное число в десятичное.\r\nBIN2HEX\t\t\t= ДВ.В.ШЕСТН\t\t\t\t##\tПреобразует двоичное число в шестнадцатеричное.\r\nBIN2OCT\t\t\t= ДВ.В.ВОСЬМ\t\t\t\t##\tПреобразует двоичное число в восьмеричное.\r\nCOMPLEX\t\t\t= КОМПЛЕКСН\t\t\t\t##\tПреобразует коэффициенты при вещественной и мнимой частях комплексного числа в комплексное число.\r\nCONVERT\t\t\t= ПРЕОБР\t\t\t\t##\tПреобразует число из одной системы единиц измерения в другую.\r\nDEC2BIN\t\t\t= ДЕС.В.ДВ\t\t\t\t##\tПреобразует десятичное число в двоичное.\r\nDEC2HEX\t\t\t= ДЕС.В.ШЕСТН\t\t\t\t##\tПреобразует десятичное число в шестнадцатеричное.\r\nDEC2OCT\t\t\t= ДЕС.В.ВОСЬМ\t\t\t\t##\tПреобразует десятичное число в восьмеричное.\r\nDELTA\t\t\t= ДЕЛЬТА\t\t\t\t##\tПроверяет равенство двух значений.\r\nERF\t\t\t= ФОШ\t\t\t\t\t##\tВозвращает функцию ошибки.\r\nERFC\t\t\t= ДФОШ\t\t\t\t\t##\tВозвращает дополнительную функцию ошибки.\r\nGESTEP\t\t\t= ПОРОГ\t\t\t\t\t##\tПроверяет, не превышает ли данное число порогового значения.\r\nHEX2BIN\t\t\t= ШЕСТН.В.ДВ\t\t\t\t##\tПреобразует шестнадцатеричное число в двоичное.\r\nHEX2DEC\t\t\t= ШЕСТН.В.ДЕС\t\t\t\t##\tПреобразует шестнадцатеричное число в десятичное.\r\nHEX2OCT\t\t\t= ШЕСТН.В.ВОСЬМ\t\t\t\t##\tПреобразует шестнадцатеричное число в восьмеричное.\r\nIMABS\t\t\t= МНИМ.ABS\t\t\t\t##\tВозвращает абсолютную величину (модуль) комплексного числа.\r\nIMAGINARY\t\t= МНИМ.ЧАСТЬ\t\t\t\t##\tВозвращает коэффициент при мнимой части комплексного числа.\r\nIMARGUMENT\t\t= МНИМ.АРГУМЕНТ\t\t\t\t##\tВозвращает значение аргумента комплексного числа (тета) — угол, выраженный в радианах.\r\nIMCONJUGATE\t\t= МНИМ.СОПРЯЖ\t\t\t\t##\tВозвращает комплексно-сопряженное комплексное число.\r\nIMCOS\t\t\t= МНИМ.COS\t\t\t\t##\tВозвращает косинус комплексного числа.\r\nIMDIV\t\t\t= МНИМ.ДЕЛ\t\t\t\t##\tВозвращает частное от деления двух комплексных чисел.\r\nIMEXP\t\t\t= МНИМ.EXP\t\t\t\t##\tВозвращает экспоненту комплексного числа.\r\nIMLN\t\t\t= МНИМ.LN\t\t\t\t##\tВозвращает натуральный логарифм комплексного числа.\r\nIMLOG10\t\t\t= МНИМ.LOG10\t\t\t\t##\tВозвращает обычный (десятичный) логарифм комплексного числа.\r\nIMLOG2\t\t\t= МНИМ.LOG2\t\t\t\t##\tВозвращает двоичный логарифм комплексного числа.\r\nIMPOWER\t\t\t= МНИМ.СТЕПЕНЬ\t\t\t\t##\tВозвращает комплексное число, возведенное в целую степень.\r\nIMPRODUCT\t\t= МНИМ.ПРОИЗВЕД\t\t\t\t##\tВозвращает произведение от 2 до 29 комплексных чисел.\r\nIMREAL\t\t\t= МНИМ.ВЕЩ\t\t\t\t##\tВозвращает коэффициент при вещественной части комплексного числа.\r\nIMSIN\t\t\t= МНИМ.SIN\t\t\t\t##\tВозвращает синус комплексного числа.\r\nIMSQRT\t\t\t= МНИМ.КОРЕНЬ\t\t\t\t##\tВозвращает значение квадратного корня из комплексного числа.\r\nIMSUB\t\t\t= МНИМ.РАЗН\t\t\t\t##\tВозвращает разность двух комплексных чисел.\r\nIMSUM\t\t\t= МНИМ.СУММ\t\t\t\t##\tВозвращает сумму комплексных чисел.\r\nOCT2BIN\t\t\t= ВОСЬМ.В.ДВ\t\t\t\t##\tПреобразует восьмеричное число в двоичное.\r\nOCT2DEC\t\t\t= ВОСЬМ.В.ДЕС\t\t\t\t##\tПреобразует восьмеричное число в десятичное.\r\nOCT2HEX\t\t\t= ВОСЬМ.В.ШЕСТН\t\t\t\t##\tПреобразует восьмеричное число в шестнадцатеричное.\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\t\tФинансовые функции\r\n##\r\nACCRINT\t\t\t= НАКОПДОХОД\t\t\t\t##\tВозвращает накопленный процент по ценным бумагам с периодической выплатой процентов.\r\nACCRINTM\t\t= НАКОПДОХОДПОГАШ\t\t\t##\tВозвращает накопленный процент по ценным бумагам, проценты по которым выплачиваются в срок погашения.\r\nAMORDEGRC\t\t= АМОРУМ\t\t\t\t##\tВозвращает величину амортизации для каждого периода, используя коэффициент амортизации.\r\nAMORLINC\t\t= АМОРУВ\t\t\t\t##\tВозвращает величину амортизации для каждого периода.\r\nCOUPDAYBS\t\t= ДНЕЙКУПОНДО\t\t\t\t##\tВозвращает количество дней от начала действия купона до даты соглашения.\r\nCOUPDAYS\t\t= ДНЕЙКУПОН\t\t\t\t##\tВозвращает число дней в периоде купона, содержащем дату соглашения.\r\nCOUPDAYSNC\t\t= ДНЕЙКУПОНПОСЛЕ\t\t\t##\tВозвращает число дней от даты соглашения до срока следующего купона.\r\nCOUPNCD\t\t\t= ДАТАКУПОНПОСЛЕ\t\t\t##\tВозвращает следующую дату купона после даты соглашения.\r\nCOUPNUM\t\t\t= ЧИСЛКУПОН\t\t\t\t##\tВозвращает количество купонов, которые могут быть оплачены между датой соглашения и сроком вступления в силу.\r\nCOUPPCD\t\t\t= ДАТАКУПОНДО\t\t\t\t##\tВозвращает предыдущую дату купона перед датой соглашения.\r\nCUMIPMT\t\t\t= ОБЩПЛАТ\t\t\t\t##\tВозвращает общую выплату, произведенную между двумя периодическими выплатами.\r\nCUMPRINC\t\t= ОБЩДОХОД\t\t\t\t##\tВозвращает общую выплату по займу между двумя периодами.\r\nDB\t\t\t= ФУО\t\t\t\t\t##\tВозвращает величину амортизации актива для заданного периода, рассчитанную методом фиксированного уменьшения остатка.\r\nDDB\t\t\t= ДДОБ\t\t\t\t\t##\tВозвращает величину амортизации актива за данный период, используя метод двойного уменьшения остатка или иной явно указанный метод.\r\nDISC\t\t\t= СКИДКА\t\t\t\t##\tВозвращает норму скидки для ценных бумаг.\r\nDOLLARDE\t\t= РУБЛЬ.ДЕС\t\t\t\t##\tПреобразует цену в рублях, выраженную в виде дроби, в цену в рублях, выраженную десятичным числом.\r\nDOLLARFR\t\t= РУБЛЬ.ДРОБЬ\t\t\t\t##\tПреобразует цену в рублях, выраженную десятичным числом, в цену в рублях, выраженную в виде дроби.\r\nDURATION\t\t= ДЛИТ\t\t\t\t\t##\tВозвращает ежегодную продолжительность действия ценных бумаг с периодическими выплатами по процентам.\r\nEFFECT\t\t\t= ЭФФЕКТ\t\t\t\t##\tВозвращает действующие ежегодные процентные ставки.\r\nFV\t\t\t= БС\t\t\t\t\t##\tВозвращает будущую стоимость инвестиции.\r\nFVSCHEDULE\t\t= БЗРАСПИС\t\t\t\t##\tВозвращает будущую стоимость первоначальной основной суммы после начисления ряда сложных процентов.\r\nINTRATE\t\t\t= ИНОРМА\t\t\t\t##\tВозвращает процентную ставку для полностью инвестированных ценных бумаг.\r\nIPMT\t\t\t= ПРПЛТ\t\t\t\t\t##\tВозвращает величину выплаты прибыли на вложения за данный период.\r\nIRR\t\t\t= ВСД\t\t\t\t\t##\tВозвращает внутреннюю ставку доходности для ряда потоков денежных средств.\r\nISPMT\t\t\t= ПРОЦПЛАТ\t\t\t\t##\tВычисляет выплаты за указанный период инвестиции.\r\nMDURATION\t\t= МДЛИТ\t\t\t\t\t##\tВозвращает модифицированную длительность Маколея для ценных бумаг с предполагаемой номинальной стоимостью 100 рублей.\r\nMIRR\t\t\t= МВСД\t\t\t\t\t##\tВозвращает внутреннюю ставку доходности, при которой положительные и отрицательные денежные потоки имеют разные значения ставки.\r\nNOMINAL\t\t\t= НОМИНАЛ\t\t\t\t##\tВозвращает номинальную годовую процентную ставку.\r\nNPER\t\t\t= КПЕР\t\t\t\t\t##\tВозвращает общее количество периодов выплаты для данного вклада.\r\nNPV\t\t\t= ЧПС\t\t\t\t\t##\tВозвращает чистую приведенную стоимость инвестиции, основанной на серии периодических денежных потоков и ставке дисконтирования.\r\nODDFPRICE\t\t= ЦЕНАПЕРВНЕРЕГ\t\t\t\t##\tВозвращает цену за 100 рублей нарицательной стоимости ценных бумаг с нерегулярным первым периодом.\r\nODDFYIELD\t\t= ДОХОДПЕРВНЕРЕГ\t\t\t##\tВозвращает доход по ценным бумагам с нерегулярным первым периодом.\r\nODDLPRICE\t\t= ЦЕНАПОСЛНЕРЕГ\t\t\t\t##\tВозвращает цену за 100 рублей нарицательной стоимости ценных бумаг с нерегулярным последним периодом.\r\nODDLYIELD\t\t= ДОХОДПОСЛНЕРЕГ\t\t\t##\tВозвращает доход по ценным бумагам с нерегулярным последним периодом.\r\nPMT\t\t\t= ПЛТ\t\t\t\t\t##\tВозвращает величину выплаты за один период аннуитета.\r\nPPMT\t\t\t= ОСПЛТ\t\t\t\t\t##\tВозвращает величину выплат в погашение основной суммы по инвестиции за заданный период.\r\nPRICE\t\t\t= ЦЕНА\t\t\t\t\t##\tВозвращает цену за 100 рублей нарицательной стоимости ценных бумаг, по которым производится периодическая выплата процентов.\r\nPRICEDISC\t\t= ЦЕНАСКИДКА\t\t\t\t##\tВозвращает цену за 100 рублей номинальной стоимости ценных бумаг, на которые сделана скидка.\r\nPRICEMAT\t\t= ЦЕНАПОГАШ\t\t\t\t##\tВозвращает цену за 100 рублей номинальной стоимости ценных бумаг, проценты по которым выплачиваются в срок погашения.\r\nPV\t\t\t= ПС\t\t\t\t\t##\tВозвращает приведенную (к текущему моменту) стоимость инвестиции.\r\nRATE\t\t\t= СТАВКА\t\t\t\t##\tВозвращает процентную ставку по аннуитету за один период.\r\nRECEIVED\t\t= ПОЛУЧЕНО\t\t\t\t##\tВозвращает сумму, полученную к сроку погашения полностью обеспеченных ценных бумаг.\r\nSLN\t\t\t= АПЛ\t\t\t\t\t##\tВозвращает величину линейной амортизации актива за один период.\r\nSYD\t\t\t= АСЧ\t\t\t\t\t##\tВозвращает величину амортизации актива за данный период, рассчитанную методом суммы годовых чисел.\r\nTBILLEQ\t\t\t= РАВНОКЧЕК\t\t\t\t##\tВозвращает эквивалентный облигации доход по казначейскому чеку.\r\nTBILLPRICE\t\t= ЦЕНАКЧЕК\t\t\t\t##\tВозвращает цену за 100 рублей нарицательной стоимости для казначейского чека.\r\nTBILLYIELD\t\t= ДОХОДКЧЕК\t\t\t\t##\tВозвращает доход по казначейскому чеку.\r\nVDB\t\t\t= ПУО\t\t\t\t\t##\tВозвращает величину амортизации актива для указанного или частичного периода при использовании метода сокращающегося баланса.\r\nXIRR\t\t\t= ЧИСТВНДОХ\t\t\t\t##\tВозвращает внутреннюю ставку доходности для графика денежных потоков, которые не обязательно носят периодический характер.\r\nXNPV\t\t\t= ЧИСТНЗ\t\t\t\t##\tВозвращает чистую приведенную стоимость для денежных потоков, которые не обязательно являются периодическими.\r\nYIELD\t\t\t= ДОХОД\t\t\t\t\t##\tВозвращает доход от ценных бумаг, по которым производятся периодические выплаты процентов.\r\nYIELDDISC\t\t= ДОХОДСКИДКА\t\t\t\t##\tВозвращает годовой доход по ценным бумагам, на которые сделана скидка (пример — казначейские чеки).\r\nYIELDMAT\t\t= ДОХОДПОГАШ\t\t\t\t##\tВозвращает годовой доход от ценных бумаг, проценты по которым выплачиваются в срок погашения.\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\t\tИнформационные функции\r\n##\r\nCELL\t\t\t= ЯЧЕЙКА\t\t\t\t##\tВозвращает информацию о формате, расположении или содержимом ячейки.\r\nERROR.TYPE\t\t= ТИП.ОШИБКИ\t\t\t\t##\tВозвращает числовой код, соответствующий типу ошибки.\r\nINFO\t\t\t= ИНФОРМ\t\t\t\t##\tВозвращает информацию о текущей операционной среде.\r\nISBLANK\t\t\t= ЕПУСТО\t\t\t\t##\tВозвращает значение ИСТИНА, если аргумент является ссылкой на пустую ячейку.\r\nISERR\t\t\t= ЕОШ\t\t\t\t\t##\tВозвращает значение ИСТИНА, если аргумент ссылается на любое значение ошибки, кроме #Н/Д.\r\nISERROR\t\t\t= ЕОШИБКА\t\t\t\t##\tВозвращает значение ИСТИНА, если аргумент ссылается на любое значение ошибки.\r\nISEVEN\t\t\t= ЕЧЁТН\t\t\t\t\t##\tВозвращает значение ИСТИНА, если значение аргумента является четным числом.\r\nISLOGICAL\t\t= ЕЛОГИЧ\t\t\t\t##\tВозвращает значение ИСТИНА, если аргумент ссылается на логическое значение.\r\nISNA\t\t\t= ЕНД\t\t\t\t\t##\tВозвращает значение ИСТИНА, если аргумент ссылается на значение ошибки #Н/Д.\r\nISNONTEXT\t\t= ЕНЕТЕКСТ\t\t\t\t##\tВозвращает значение ИСТИНА, если значение аргумента не является текстом.\r\nISNUMBER\t\t= ЕЧИСЛО\t\t\t\t##\tВозвращает значение ИСТИНА, если аргумент ссылается на число.\r\nISODD\t\t\t= ЕНЕЧЁТ\t\t\t\t##\tВозвращает значение ИСТИНА, если значение аргумента является нечетным числом.\r\nISREF\t\t\t= ЕССЫЛКА\t\t\t\t##\tВозвращает значение ИСТИНА, если значение аргумента является ссылкой.\r\nISTEXT\t\t\t= ЕТЕКСТ\t\t\t\t##\tВозвращает значение ИСТИНА, если значение аргумента является текстом.\r\nN\t\t\t= Ч\t\t\t\t\t##\tВозвращает значение, преобразованное в число.\r\nNA\t\t\t= НД\t\t\t\t\t##\tВозвращает значение ошибки #Н/Д.\r\nTYPE\t\t\t= ТИП\t\t\t\t\t##\tВозвращает число, обозначающее тип данных значения.\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\t\tЛогические функции\r\n##\r\nAND\t\t\t= И\t\t\t\t\t##\tRenvoie VRAI si tous ses arguments sont VRAI.\r\nFALSE\t\t\t= ЛОЖЬ\t\t\t\t\t##\tВозвращает логическое значение ЛОЖЬ.\r\nIF\t\t\t= ЕСЛИ\t\t\t\t\t##\tВыполняет проверку условия.\r\nIFERROR\t\t\t= ЕСЛИОШИБКА\t\t\t\t##\tВозвращает введённое значение, если вычисление по формуле вызывает ошибку; в противном случае функция возвращает результат вычисления.\r\nNOT\t\t\t= НЕ\t\t\t\t\t##\tМеняет логическое значение своего аргумента на противоположное.\r\nOR\t\t\t= ИЛИ\t\t\t\t\t##\tВозвращает значение ИСТИНА, если хотя бы один аргумент имеет значение ИСТИНА.\r\nTRUE\t\t\t= ИСТИНА\t\t\t\t##\tВозвращает логическое значение ИСТИНА.\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\t\tФункции ссылки и поиска\r\n##\r\nADDRESS\t\t\t= АДРЕС\t\t\t\t\t##\tВозвращает ссылку на отдельную ячейку листа в виде текста.\r\nAREAS\t\t\t= ОБЛАСТИ\t\t\t\t##\tВозвращает количество областей в ссылке.\r\nCHOOSE\t\t\t= ВЫБОР\t\t\t\t\t##\tВыбирает значение из списка значений по индексу.\r\nCOLUMN\t\t\t= СТОЛБЕЦ\t\t\t\t##\tВозвращает номер столбца, на который указывает ссылка.\r\nCOLUMNS\t\t\t= ЧИСЛСТОЛБ\t\t\t\t##\tВозвращает количество столбцов в ссылке.\r\nHLOOKUP\t\t\t= ГПР\t\t\t\t\t##\tИщет в первой строке массива и возвращает значение отмеченной ячейки\r\nHYPERLINK\t\t= ГИПЕРССЫЛКА\t\t\t\t##\tСоздает ссылку, открывающую документ, который находится на сервере сети, в интрасети или в Интернете.\r\nINDEX\t\t\t= ИНДЕКС\t\t\t\t##\tИспользует индекс для выбора значения из ссылки или массива.\r\nINDIRECT\t\t= ДВССЫЛ\t\t\t\t##\tВозвращает ссылку, заданную текстовым значением.\r\nLOOKUP\t\t\t= ПРОСМОТР\t\t\t\t##\tИщет значения в векторе или массиве.\r\nMATCH\t\t\t= ПОИСКПОЗ\t\t\t\t##\tИщет значения в ссылке или массиве.\r\nOFFSET\t\t\t= СМЕЩ\t\t\t\t\t##\tВозвращает смещение ссылки относительно заданной ссылки.\r\nROW\t\t\t= СТРОКА\t\t\t\t##\tВозвращает номер строки, определяемой ссылкой.\r\nROWS\t\t\t= ЧСТРОК\t\t\t\t##\tВозвращает количество строк в ссылке.\r\nRTD\t\t\t= ДРВ\t\t\t\t\t##\tИзвлекает данные реального времени из программ, поддерживающих автоматизацию COM (Программирование объектов. Стандартное средство для работы с объектами некоторого приложения из другого приложения или средства разработки. Программирование объектов (ранее называемое программированием OLE) является функцией модели COM (Component Object Model, модель компонентных объектов).).\r\nTRANSPOSE\t\t= ТРАНСП\t\t\t\t##\tВозвращает транспонированный массив.\r\nVLOOKUP\t\t\t= ВПР\t\t\t\t\t##\tИщет значение в первом столбце массива и возвращает значение из ячейки в найденной строке и указанном столбце.\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\t\tМатематические и тригонометрические функции\r\n##\r\nABS\t\t\t= ABS\t\t\t\t\t##\tВозвращает модуль (абсолютную величину) числа.\r\nACOS\t\t\t= ACOS\t\t\t\t\t##\tВозвращает арккосинус числа.\r\nACOSH\t\t\t= ACOSH\t\t\t\t\t##\tВозвращает гиперболический арккосинус числа.\r\nASIN\t\t\t= ASIN\t\t\t\t\t##\tВозвращает арксинус числа.\r\nASINH\t\t\t= ASINH\t\t\t\t\t##\tВозвращает гиперболический арксинус числа.\r\nATAN\t\t\t= ATAN\t\t\t\t\t##\tВозвращает арктангенс числа.\r\nATAN2\t\t\t= ATAN2\t\t\t\t\t##\tВозвращает арктангенс для заданных координат x и y.\r\nATANH\t\t\t= ATANH\t\t\t\t\t##\tВозвращает гиперболический арктангенс числа.\r\nCEILING\t\t\t= ОКРВВЕРХ\t\t\t\t##\tОкругляет число до ближайшего целого или до ближайшего кратного указанному значению.\r\nCOMBIN\t\t\t= ЧИСЛКОМБ\t\t\t\t##\tВозвращает количество комбинаций для заданного числа объектов.\r\nCOS\t\t\t= COS\t\t\t\t\t##\tВозвращает косинус числа.\r\nCOSH\t\t\t= COSH\t\t\t\t\t##\tВозвращает гиперболический косинус числа.\r\nDEGREES\t\t\t= ГРАДУСЫ\t\t\t\t##\tПреобразует радианы в градусы.\r\nEVEN\t\t\t= ЧЁТН\t\t\t\t\t##\tОкругляет число до ближайшего четного целого.\r\nEXP\t\t\t= EXP\t\t\t\t\t##\tВозвращает число e, возведенное в указанную степень.\r\nFACT\t\t\t= ФАКТР\t\t\t\t\t##\tВозвращает факториал числа.\r\nFACTDOUBLE\t\t= ДВФАКТР\t\t\t\t##\tВозвращает двойной факториал числа.\r\nFLOOR\t\t\t= ОКРВНИЗ\t\t\t\t##\tОкругляет число до ближайшего меньшего по модулю значения.\r\nGCD\t\t\t= НОД\t\t\t\t\t##\tВозвращает наибольший общий делитель.\r\nINT\t\t\t= ЦЕЛОЕ\t\t\t\t\t##\tОкругляет число до ближайшего меньшего целого.\r\nLCM\t\t\t= НОК\t\t\t\t\t##\tВозвращает наименьшее общее кратное.\r\nLN\t\t\t= LN\t\t\t\t\t##\tВозвращает натуральный логарифм числа.\r\nLOG\t\t\t= LOG\t\t\t\t\t##\tВозвращает логарифм числа по заданному основанию.\r\nLOG10\t\t\t= LOG10\t\t\t\t\t##\tВозвращает десятичный логарифм числа.\r\nMDETERM\t\t\t= МОПРЕД\t\t\t\t##\tВозвращает определитель матрицы массива.\r\nMINVERSE\t\t= МОБР\t\t\t\t\t##\tВозвращает обратную матрицу массива.\r\nMMULT\t\t\t= МУМНОЖ\t\t\t\t##\tВозвращает произведение матриц двух массивов.\r\nMOD\t\t\t= ОСТАТ\t\t\t\t\t##\tВозвращает остаток от деления.\r\nMROUND\t\t\t= ОКРУГЛТ\t\t\t\t##\tВозвращает число, округленное с требуемой точностью.\r\nMULTINOMIAL\t\t= МУЛЬТИНОМ\t\t\t\t##\tВозвращает мультиномиальный коэффициент множества чисел.\r\nODD\t\t\t= НЕЧЁТ\t\t\t\t\t##\tОкругляет число до ближайшего нечетного целого.\r\nPI\t\t\t= ПИ\t\t\t\t\t##\tВозвращает число пи.\r\nPOWER\t\t\t= СТЕПЕНЬ\t\t\t\t##\tВозвращает результат возведения числа в степень.\r\nPRODUCT\t\t\t= ПРОИЗВЕД\t\t\t\t##\tВозвращает произведение аргументов.\r\nQUOTIENT\t\t= ЧАСТНОЕ\t\t\t\t##\tВозвращает целую часть частного при делении.\r\nRADIANS\t\t\t= РАДИАНЫ\t\t\t\t##\tПреобразует градусы в радианы.\r\nRAND\t\t\t= СЛЧИС\t\t\t\t\t##\tВозвращает случайное число в интервале от 0 до 1.\r\nRANDBETWEEN\t\t= СЛУЧМЕЖДУ\t\t\t\t##\tВозвращает случайное число в интервале между двумя заданными числами.\r\nROMAN\t\t\t= РИМСКОЕ\t\t\t\t##\tПреобразует арабские цифры в римские в виде текста.\r\nROUND\t\t\t= ОКРУГЛ\t\t\t\t##\tОкругляет число до указанного количества десятичных разрядов.\r\nROUNDDOWN\t\t= ОКРУГЛВНИЗ\t\t\t\t##\tОкругляет число до ближайшего меньшего по модулю значения.\r\nROUNDUP\t\t\t= ОКРУГЛВВЕРХ\t\t\t\t##\tОкругляет число до ближайшего большего по модулю значения.\r\nSERIESSUM\t\t= РЯД.СУММ\t\t\t\t##\tВозвращает сумму степенного ряда, вычисленную по формуле.\r\nSIGN\t\t\t= ЗНАК\t\t\t\t\t##\tВозвращает знак числа.\r\nSIN\t\t\t= SIN\t\t\t\t\t##\tВозвращает синус заданного угла.\r\nSINH\t\t\t= SINH\t\t\t\t\t##\tВозвращает гиперболический синус числа.\r\nSQRT\t\t\t= КОРЕНЬ\t\t\t\t##\tВозвращает положительное значение квадратного корня.\r\nSQRTPI\t\t\t= КОРЕНЬПИ\t\t\t\t##\tВозвращает квадратный корень из значения выражения (число * ПИ).\r\nSUBTOTAL\t\t= ПРОМЕЖУТОЧНЫЕ.ИТОГИ\t\t\t##\tВозвращает промежуточный итог в списке или базе данных.\r\nSUM\t\t\t= СУММ\t\t\t\t\t##\tСуммирует аргументы.\r\nSUMIF\t\t\t= СУММЕСЛИ\t\t\t\t##\tСуммирует ячейки, удовлетворяющие заданному условию.\r\nSUMIFS\t\t\t= СУММЕСЛИМН\t\t\t\t##\tСуммирует диапазон ячеек, удовлетворяющих нескольким условиям. \r\nSUMPRODUCT\t\t= СУММПРОИЗВ\t\t\t\t##\tВозвращает сумму произведений соответствующих элементов массивов.\r\nSUMSQ\t\t\t= СУММКВ\t\t\t\t##\tВозвращает сумму квадратов аргументов.\r\nSUMX2MY2\t\t= СУММРАЗНКВ\t\t\t\t##\tВозвращает сумму разностей квадратов соответствующих значений в двух массивах.\r\nSUMX2PY2\t\t= СУММСУММКВ\t\t\t\t##\tВозвращает сумму сумм квадратов соответствующих элементов двух массивов.\r\nSUMXMY2\t\t\t= СУММКВРАЗН\t\t\t\t##\tВозвращает сумму квадратов разностей соответствующих значений в двух массивах.\r\nTAN\t\t\t= TAN\t\t\t\t\t##\tВозвращает тангенс числа.\r\nTANH\t\t\t= TANH\t\t\t\t\t##\tВозвращает гиперболический тангенс числа.\r\nTRUNC\t\t\t= ОТБР\t\t\t\t\t##\tОтбрасывает дробную часть числа.\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\t\tСтатистические функции\r\n##\r\nAVEDEV\t\t\t= СРОТКЛ\t\t\t\t##\tВозвращает среднее арифметическое абсолютных значений отклонений точек данных от среднего.\r\nAVERAGE\t\t\t= СРЗНАЧ\t\t\t\t##\tВозвращает среднее арифметическое аргументов.\r\nAVERAGEA\t\t= СРЗНАЧА\t\t\t\t##\tВозвращает среднее арифметическое аргументов, включая числа, текст и логические значения.\r\nAVERAGEIF\t\t= СРЗНАЧЕСЛИ \t\t\t\t##\tВозвращает среднее значение (среднее арифметическое) всех ячеек в диапазоне, которые удовлетворяют данному условию.\r\nAVERAGEIFS\t\t= СРЗНАЧЕСЛИМН \t\t\t\t##\tВозвращает среднее значение (среднее арифметическое) всех ячеек, которые удовлетворяют нескольким условиям. \r\nBETADIST\t\t= БЕТАРАСП\t\t\t\t##\tВозвращает интегральную функцию бета-распределения.\r\nBETAINV\t\t\t= БЕТАОБР\t\t\t\t##\tВозвращает обратную интегральную функцию указанного бета-распределения.\r\nBINOMDIST\t\t= БИНОМРАСП\t\t\t\t##\tВозвращает отдельное значение биномиального распределения.\r\nCHIDIST\t\t\t= ХИ2РАСП\t\t\t\t##\tВозвращает одностороннюю вероятность распределения хи-квадрат.\r\nCHIINV\t\t\t= ХИ2ОБР\t\t\t\t##\tВозвращает обратное значение односторонней вероятности распределения хи-квадрат.\r\nCHITEST\t\t\t= ХИ2ТЕСТ\t\t\t\t##\tВозвращает тест на независимость.\r\nCONFIDENCE\t\t= ДОВЕРИТ\t\t\t\t##\tВозвращает доверительный интервал для среднего значения по генеральной совокупности.\r\nCORREL\t\t\t= КОРРЕЛ\t\t\t\t##\tВозвращает коэффициент корреляции между двумя множествами данных.\r\nCOUNT\t\t\t= СЧЁТ\t\t\t\t\t##\tПодсчитывает количество чисел в списке аргументов.\r\nCOUNTA\t\t\t= СЧЁТЗ\t\t\t\t\t##\tПодсчитывает количество значений в списке аргументов.\r\nCOUNTBLANK\t\t= СЧИТАТЬПУСТОТЫ\t\t\t##\tПодсчитывает количество пустых ячеек в диапазоне\r\nCOUNTIF\t\t\t= СЧЁТЕСЛИ \t\t\t\t##\tПодсчитывает количество ячеек в диапазоне, удовлетворяющих заданному условию\r\nCOUNTIFS\t\t= СЧЁТЕСЛИМН\t\t\t\t##\tПодсчитывает количество ячеек внутри диапазона, удовлетворяющих нескольким условиям.\r\nCOVAR\t\t\t= КОВАР\t\t\t\t\t##\tВозвращает ковариацию, среднее произведений парных отклонений\r\nCRITBINOM\t\t= КРИТБИНОМ\t\t\t\t##\tВозвращает наименьшее значение, для которого интегральное биномиальное распределение меньше или равно заданному критерию.\r\nDEVSQ\t\t\t= КВАДРОТКЛ\t\t\t\t##\tВозвращает сумму квадратов отклонений.\r\nEXPONDIST\t\t= ЭКСПРАСП\t\t\t\t##\tВозвращает экспоненциальное распределение.\r\nFDIST\t\t\t= FРАСП\t\t\t\t\t##\tВозвращает F-распределение вероятности.\r\nFINV\t\t\t= FРАСПОБР\t\t\t\t##\tВозвращает обратное значение для F-распределения вероятности.\r\nFISHER\t\t\t= ФИШЕР\t\t\t\t\t##\tВозвращает преобразование Фишера.\r\nFISHERINV\t\t= ФИШЕРОБР\t\t\t\t##\tВозвращает обратное преобразование Фишера.\r\nFORECAST\t\t= ПРЕДСКАЗ\t\t\t\t##\tВозвращает значение линейного тренда.\r\nFREQUENCY\t\t= ЧАСТОТА\t\t\t\t##\tВозвращает распределение частот в виде вертикального массива.\r\nFTEST\t\t\t= ФТЕСТ\t\t\t\t\t##\tВозвращает результат F-теста.\r\nGAMMADIST\t\t= ГАММАРАСП\t\t\t\t##\tВозвращает гамма-распределение.\r\nGAMMAINV\t\t= ГАММАОБР\t\t\t\t##\tВозвращает обратное гамма-распределение.\r\nGAMMALN\t\t\t= ГАММАНЛОГ\t\t\t\t##\tВозвращает натуральный логарифм гамма функции, Γ(x).\r\nGEOMEAN\t\t\t= СРГЕОМ\t\t\t\t##\tВозвращает среднее геометрическое.\r\nGROWTH\t\t\t= РОСТ\t\t\t\t\t##\tВозвращает значения в соответствии с экспоненциальным трендом.\r\nHARMEAN\t\t\t= СРГАРМ\t\t\t\t##\tВозвращает среднее гармоническое.\r\nHYPGEOMDIST\t\t= ГИПЕРГЕОМЕТ\t\t\t\t##\tВозвращает гипергеометрическое распределение.\r\nINTERCEPT\t\t= ОТРЕЗОК\t\t\t\t##\tВозвращает отрезок, отсекаемый на оси линией линейной регрессии.\r\nKURT\t\t\t= ЭКСЦЕСС\t\t\t\t##\tВозвращает эксцесс множества данных.\r\nLARGE\t\t\t= НАИБОЛЬШИЙ\t\t\t\t##\tВозвращает k-ое наибольшее значение в множестве данных.\r\nLINEST\t\t\t= ЛИНЕЙН\t\t\t\t##\tВозвращает параметры линейного тренда.\r\nLOGEST\t\t\t= ЛГРФПРИБЛ\t\t\t\t##\tВозвращает параметры экспоненциального тренда.\r\nLOGINV\t\t\t= ЛОГНОРМОБР\t\t\t\t##\tВозвращает обратное логарифмическое нормальное распределение.\r\nLOGNORMDIST\t\t= ЛОГНОРМРАСП\t\t\t\t##\tВозвращает интегральное логарифмическое нормальное распределение.\r\nMAX\t\t\t= МАКС\t\t\t\t\t##\tВозвращает наибольшее значение в списке аргументов.\r\nMAXA\t\t\t= МАКСА\t\t\t\t\t##\tВозвращает наибольшее значение в списке аргументов, включая числа, текст и логические значения.\r\nMEDIAN\t\t\t= МЕДИАНА\t\t\t\t##\tВозвращает медиану заданных чисел.\r\nMIN\t\t\t= МИН\t\t\t\t\t##\tВозвращает наименьшее значение в списке аргументов.\r\nMINA\t\t\t= МИНА\t\t\t\t\t##\tВозвращает наименьшее значение в списке аргументов, включая числа, текст и логические значения.\r\nMODE\t\t\t= МОДА\t\t\t\t\t##\tВозвращает значение моды множества данных.\r\nNEGBINOMDIST\t\t= ОТРБИНОМРАСП\t\t\t\t##\tВозвращает отрицательное биномиальное распределение.\r\nNORMDIST\t\t= НОРМРАСП\t\t\t\t##\tВозвращает нормальную функцию распределения.\r\nNORMINV\t\t\t= НОРМОБР\t\t\t\t##\tВозвращает обратное нормальное распределение.\r\nNORMSDIST\t\t= НОРМСТРАСП\t\t\t\t##\tВозвращает стандартное нормальное интегральное распределение.\r\nNORMSINV\t\t= НОРМСТОБР\t\t\t\t##\tВозвращает обратное значение стандартного нормального распределения.\r\nPEARSON\t\t\t= ПИРСОН\t\t\t\t##\tВозвращает коэффициент корреляции Пирсона.\r\nPERCENTILE\t\t= ПЕРСЕНТИЛЬ\t\t\t\t##\tВозвращает k-ую персентиль для значений диапазона.\r\nPERCENTRANK\t\t= ПРОЦЕНТРАНГ\t\t\t\t##\tВозвращает процентную норму значения в множестве данных.\r\nPERMUT\t\t\t= ПЕРЕСТ\t\t\t\t##\tВозвращает количество перестановок для заданного числа объектов.\r\nPOISSON\t\t\t= ПУАССОН\t\t\t\t##\tВозвращает распределение Пуассона.\r\nPROB\t\t\t= ВЕРОЯТНОСТЬ\t\t\t\t##\tВозвращает вероятность того, что значение из диапазона находится внутри заданных пределов.\r\nQUARTILE\t\t= КВАРТИЛЬ\t\t\t\t##\tВозвращает квартиль множества данных.\r\nRANK\t\t\t= РАНГ\t\t\t\t\t##\tВозвращает ранг числа в списке чисел.\r\nRSQ\t\t\t= КВПИРСОН\t\t\t\t##\tВозвращает квадрат коэффициента корреляции Пирсона.\r\nSKEW\t\t\t= СКОС\t\t\t\t\t##\tВозвращает асимметрию распределения.\r\nSLOPE\t\t\t= НАКЛОН\t\t\t\t##\tВозвращает наклон линии линейной регрессии.\r\nSMALL\t\t\t= НАИМЕНЬШИЙ\t\t\t\t##\tВозвращает k-ое наименьшее значение в множестве данных.\r\nSTANDARDIZE\t\t= НОРМАЛИЗАЦИЯ\t\t\t\t##\tВозвращает нормализованное значение.\r\nSTDEV\t\t\t= СТАНДОТКЛОН\t\t\t\t##\tОценивает стандартное отклонение по выборке.\r\nSTDEVA\t\t\t= СТАНДОТКЛОНА\t\t\t\t##\tОценивает стандартное отклонение по выборке, включая числа, текст и логические значения.\r\nSTDEVP\t\t\t= СТАНДОТКЛОНП\t\t\t\t##\tВычисляет стандартное отклонение по генеральной совокупности.\r\nSTDEVPA\t\t\t= СТАНДОТКЛОНПА\t\t\t\t##\tВычисляет стандартное отклонение по генеральной совокупности, включая числа, текст и логические значения.\r\nSTEYX\t\t\t= СТОШYX\t\t\t\t##\tВозвращает стандартную ошибку предсказанных значений y для каждого значения x в регрессии.\r\nTDIST\t\t\t= СТЬЮДРАСП\t\t\t\t##\tВозвращает t-распределение Стьюдента.\r\nTINV\t\t\t= СТЬЮДРАСПОБР\t\t\t\t##\tВозвращает обратное t-распределение Стьюдента.\r\nTREND\t\t\t= ТЕНДЕНЦИЯ\t\t\t\t##\tВозвращает значения в соответствии с линейным трендом.\r\nTRIMMEAN\t\t= УРЕЗСРЕДНЕЕ\t\t\t\t##\tВозвращает среднее внутренности множества данных.\r\nTTEST\t\t\t= ТТЕСТ\t\t\t\t\t##\tВозвращает вероятность, соответствующую критерию Стьюдента.\r\nVAR\t\t\t= ДИСП\t\t\t\t\t##\tОценивает дисперсию по выборке.\r\nVARA\t\t\t= ДИСПА\t\t\t\t\t##\tОценивает дисперсию по выборке, включая числа, текст и логические значения.\r\nVARP\t\t\t= ДИСПР\t\t\t\t\t##\tВычисляет дисперсию для генеральной совокупности.\r\nVARPA\t\t\t= ДИСПРА\t\t\t\t##\tВычисляет дисперсию для генеральной совокупности, включая числа, текст и логические значения.\r\nWEIBULL\t\t\t= ВЕЙБУЛЛ\t\t\t\t##\tВозвращает распределение Вейбулла.\r\nZTEST\t\t\t= ZТЕСТ\t\t\t\t\t##\tВозвращает двустороннее P-значение z-теста.\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\t\tТекстовые функции\r\n##\r\nASC\t\t\t= ASC\t\t\t\t\t##\tДля языков с двухбайтовыми наборами знаков (например, катакана) преобразует полноширинные (двухбайтовые) знаки в полуширинные (однобайтовые).\r\nBAHTTEXT\t\t= БАТТЕКСТ\t\t\t\t##\tПреобразует число в текст, используя денежный формат ß (БАТ).\r\nCHAR\t\t\t= СИМВОЛ\t\t\t\t##\tВозвращает знак с заданным кодом.\r\nCLEAN\t\t\t= ПЕЧСИМВ\t\t\t\t##\tУдаляет все непечатаемые знаки из текста.\r\nCODE\t\t\t= КОДСИМВ\t\t\t\t##\tВозвращает числовой код первого знака в текстовой строке.\r\nCONCATENATE\t\t= СЦЕПИТЬ\t\t\t\t##\tОбъединяет несколько текстовых элементов в один.\r\nDOLLAR\t\t\t= РУБЛЬ\t\t\t\t\t##\tПреобразует число в текст, используя денежный формат.\r\nEXACT\t\t\t= СОВПАД\t\t\t\t##\tПроверяет идентичность двух текстовых значений.\r\nFIND\t\t\t= НАЙТИ\t\t\t\t\t##\tИщет вхождения одного текстового значения в другом (с учетом регистра).\r\nFINDB\t\t\t= НАЙТИБ\t\t\t\t##\tИщет вхождения одного текстового значения в другом (с учетом регистра).\r\nFIXED\t\t\t= ФИКСИРОВАННЫЙ\t\t\t\t##\tФорматирует число и преобразует его в текст с заданным числом десятичных знаков.\r\nJIS\t\t\t= JIS\t\t\t\t\t##\tДля языков с двухбайтовыми наборами знаков (например, катакана) преобразует полуширинные (однобайтовые) знаки в текстовой строке в полноширинные (двухбайтовые).\r\nLEFT\t\t\t= ЛЕВСИМВ\t\t\t\t##\tВозвращает крайние слева знаки текстового значения.\r\nLEFTB\t\t\t= ЛЕВБ\t\t\t\t\t##\tВозвращает крайние слева знаки текстового значения.\r\nLEN\t\t\t= ДЛСТР\t\t\t\t\t##\tВозвращает количество знаков в текстовой строке.\r\nLENB\t\t\t= ДЛИНБ\t\t\t\t\t##\tВозвращает количество знаков в текстовой строке.\r\nLOWER\t\t\t= СТРОЧН\t\t\t\t##\tПреобразует все буквы текста в строчные.\r\nMID\t\t\t= ПСТР\t\t\t\t\t##\tВозвращает заданное число знаков из строки текста, начиная с указанной позиции.\r\nMIDB\t\t\t= ПСТРБ\t\t\t\t\t##\tВозвращает заданное число знаков из строки текста, начиная с указанной позиции.\r\nPHONETIC\t\t= PHONETIC\t\t\t\t##\tИзвлекает фонетические (фуригана) знаки из текстовой строки.\r\nPROPER\t\t\t= ПРОПНАЧ\t\t\t\t##\tПреобразует первую букву в каждом слове текста в прописную.\r\nREPLACE\t\t\t= ЗАМЕНИТЬ\t\t\t\t##\tЗаменяет знаки в тексте.\r\nREPLACEB\t\t= ЗАМЕНИТЬБ\t\t\t\t##\tЗаменяет знаки в тексте.\r\nREPT\t\t\t= ПОВТОР\t\t\t\t##\tПовторяет текст заданное число раз.\r\nRIGHT\t\t\t= ПРАВСИМВ\t\t\t\t##\tВозвращает крайние справа знаки текстовой строки.\r\nRIGHTB\t\t\t= ПРАВБ\t\t\t\t\t##\tВозвращает крайние справа знаки текстовой строки.\r\nSEARCH\t\t\t= ПОИСК\t\t\t\t\t##\tИщет вхождения одного текстового значения в другом (без учета регистра).\r\nSEARCHB\t\t\t= ПОИСКБ\t\t\t\t##\tИщет вхождения одного текстового значения в другом (без учета регистра).\r\nSUBSTITUTE\t\t= ПОДСТАВИТЬ\t\t\t\t##\tЗаменяет в текстовой строке старый текст новым.\r\nT\t\t\t= Т\t\t\t\t\t##\tПреобразует аргументы в текст.\r\nTEXT\t\t\t= ТЕКСТ\t\t\t\t\t##\tФорматирует число и преобразует его в текст.\r\nTRIM\t\t\t= СЖПРОБЕЛЫ\t\t\t\t##\tУдаляет из текста пробелы.\r\nUPPER\t\t\t= ПРОПИСН\t\t\t\t##\tПреобразует все буквы текста в прописные.\r\nVALUE\t\t\t= ЗНАЧЕН\t\t\t\t##\tПреобразует текстовый аргумент в число.\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/sv/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= kr\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #Skärning!\r\nDIV0\t= #Division/0!\r\nVALUE\t= #Värdefel!\r\nREF\t= #Referens!\r\nNAME\t= #Namn?\r\nNUM\t= #Ogiltigt!\r\nNA\t= #Saknas!\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/sv/functions",
    "content": "##\r\n##\tAdd-in and Automation functions\t\t\tTilläggs- och automatiseringsfunktioner\r\n##\r\nGETPIVOTDATA\t\t= HÄMTA.PIVOTDATA\t\t##\tReturnerar data som lagrats i en pivottabellrapport\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\tKubfunktioner\r\n##\r\nCUBEKPIMEMBER\t\t= KUBKPIMEDLEM\t\t\t##\tReturnerar namn, egenskap och mått för en KPI och visar namnet och egenskapen i cellen. En KPI, eller prestandaindikator, är ett kvantifierbart mått, t.ex. månatlig bruttovinst eller personalomsättning per kvartal, som används för att analysera ett företags resultat.\r\nCUBEMEMBER\t\t= KUBMEDLEM\t\t\t##\tReturnerar en medlem eller ett par i en kubhierarki. Används för att verifiera att medlemmen eller paret finns i kuben.\r\nCUBEMEMBERPROPERTY\t= KUBMEDLEMSEGENSKAP\t\t##\tReturnerar värdet för en medlemsegenskap i kuben. Används för att verifiera att ett medlemsnamn finns i kuben, samt för att returnera den angivna egenskapen för medlemmen.\r\nCUBERANKEDMEMBER\t= KUBRANGORDNADMEDLEM\t\t##\tReturnerar den n:te, eller rangordnade, medlemmen i en uppsättning. Används för att returnera ett eller flera element i en uppsättning, till exempelvis den bästa försäljaren eller de tio bästa eleverna.\r\nCUBESET\t\t\t= KUBINSTÄLLNING\t\t##\tDefinierar en beräknad uppsättning medlemmar eller par genom att skicka ett bestämt uttryck till kuben på servern, som skapar uppsättningen och sedan returnerar den till Microsoft Office Excel.\r\nCUBESETCOUNT\t\t= KUBINSTÄLLNINGANTAL\t\t##\tReturnerar antalet objekt i en uppsättning.\r\nCUBEVALUE\t\t= KUBVÄRDE\t\t\t##\tReturnerar ett mängdvärde från en kub.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\tDatabasfunktioner\r\n##\r\nDAVERAGE\t\t= DMEDEL\t\t\t##\tReturnerar medelvärdet av databasposterna\r\nDCOUNT\t\t\t= DANTAL\t\t\t##\tRäknar antalet celler som innehåller tal i en databas\r\nDCOUNTA\t\t\t= DANTALV\t\t\t##\tRäknar ifyllda celler i en databas\r\nDGET\t\t\t= DHÄMTA\t\t\t##\tHämtar en enstaka post från en databas som uppfyller de angivna villkoren\r\nDMAX\t\t\t= DMAX\t\t\t\t##\tReturnerar det största värdet från databasposterna\r\nDMIN\t\t\t= DMIN\t\t\t\t##\tReturnerar det minsta värdet från databasposterna\r\nDPRODUCT\t\t= DPRODUKT\t\t\t##\tMultiplicerar värdena i ett visst fält i poster som uppfyller villkoret\r\nDSTDEV\t\t\t= DSTDAV\t\t\t##\tUppskattar standardavvikelsen baserat på ett urval av databasposterna\r\nDSTDEVP\t\t\t= DSTDAVP\t\t\t##\tBeräknar standardavvikelsen utifrån hela populationen av valda databasposter\r\nDSUM\t\t\t= DSUMMA\t\t\t##\tSummerar talen i kolumnfält i databasposter som uppfyller villkoret\r\nDVAR\t\t\t= DVARIANS\t\t\t##\tUppskattar variansen baserat på ett urval av databasposterna\r\nDVARP\t\t\t= DVARIANSP\t\t\t##\tBeräknar variansen utifrån hela populationen av valda databasposter\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\tTid- och datumfunktioner\r\n##\r\nDATE\t\t\t= DATUM\t\t\t\t##\tReturnerar ett serienummer för ett visst datum\r\nDATEVALUE\t\t= DATUMVÄRDE\t\t\t##\tKonverterar ett datum i textformat till ett serienummer\r\nDAY\t\t\t= DAG\t\t\t\t##\tKonverterar ett serienummer till dag i månaden\r\nDAYS360\t\t\t= DAGAR360\t\t\t##\tBeräknar antalet dagar mellan två datum baserat på ett 360-dagarsår\r\nEDATE\t\t\t= EDATUM\t\t\t##\tReturnerar serienumret för ett datum som infaller ett visst antal månader före eller efter startdatumet\r\nEOMONTH\t\t\t= SLUTMÅNAD\t\t\t##\tReturnerar serienumret för sista dagen i månaden ett visst antal månader tidigare eller senare\r\nHOUR\t\t\t= TIMME\t\t\t\t##\tKonverterar ett serienummer till en timme\r\nMINUTE\t\t\t= MINUT\t\t\t\t##\tKonverterar ett serienummer till en minut\r\nMONTH\t\t\t= MÅNAD\t\t\t\t##\tKonverterar ett serienummer till en månad\r\nNETWORKDAYS\t\t= NETTOARBETSDAGAR\t\t##\tReturnerar antalet hela arbetsdagar mellan två datum\r\nNOW\t\t\t= NU\t\t\t\t##\tReturnerar serienumret för dagens datum och aktuell tid\r\nSECOND\t\t\t= SEKUND\t\t\t##\tKonverterar ett serienummer till en sekund\r\nTIME\t\t\t= KLOCKSLAG\t\t\t##\tReturnerar serienumret för en viss tid\r\nTIMEVALUE\t\t= TIDVÄRDE\t\t\t##\tKonverterar en tid i textformat till ett serienummer\r\nTODAY\t\t\t= IDAG\t\t\t\t##\tReturnerar serienumret för dagens datum\r\nWEEKDAY\t\t\t= VECKODAG\t\t\t##\tKonverterar ett serienummer till en dag i veckan\r\nWEEKNUM\t\t\t= VECKONR\t\t\t##\tKonverterar ett serienummer till ett veckonummer\r\nWORKDAY\t\t\t= ARBETSDAGAR\t\t\t##\tReturnerar serienumret för ett datum ett visst antal arbetsdagar tidigare eller senare\r\nYEAR\t\t\t= ÅR\t\t\t\t##\tKonverterar ett serienummer till ett år\r\nYEARFRAC\t\t= ÅRDEL\t\t\t\t##\tReturnerar en del av ett år som representerar antalet hela dagar mellan start- och slutdatum\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\tTekniska funktioner\r\n##\r\nBESSELI\t\t\t= BESSELI\t\t\t##\tReturnerar den modifierade Bessel-funktionen In(x)\r\nBESSELJ\t\t\t= BESSELJ\t\t\t##\tReturnerar Bessel-funktionen Jn(x)\r\nBESSELK\t\t\t= BESSELK\t\t\t##\tReturnerar den modifierade Bessel-funktionen Kn(x)\r\nBESSELY\t\t\t= BESSELY\t\t\t##\tReturnerar Bessel-funktionen Yn(x)\r\nBIN2DEC\t\t\t= BIN.TILL.DEC\t\t\t##\tOmvandlar ett binärt tal till decimalt\r\nBIN2HEX\t\t\t= BIN.TILL.HEX\t\t\t##\tOmvandlar ett binärt tal till hexadecimalt\r\nBIN2OCT\t\t\t= BIN.TILL.OKT\t\t\t##\tOmvandlar ett binärt tal till oktalt\r\nCOMPLEX\t\t\t= KOMPLEX\t\t\t##\tOmvandlar reella och imaginära koefficienter till ett komplext tal\r\nCONVERT\t\t\t= KONVERTERA\t\t\t##\tOmvandlar ett tal från ett måttsystem till ett annat\r\nDEC2BIN\t\t\t= DEC.TILL.BIN\t\t\t##\tOmvandlar ett decimalt tal till binärt\r\nDEC2HEX\t\t\t= DEC.TILL.HEX\t\t\t##\tOmvandlar ett decimalt tal till hexadecimalt\r\nDEC2OCT\t\t\t= DEC.TILL.OKT\t\t\t##\tOmvandlar ett decimalt tal till oktalt\r\nDELTA\t\t\t= DELTA\t\t\t\t##\tTestar om två värden är lika\r\nERF\t\t\t= FELF\t\t\t\t##\tReturnerar felfunktionen\r\nERFC\t\t\t= FELFK\t\t\t\t##\tReturnerar den komplementära felfunktionen\r\nGESTEP\t\t\t= SLSTEG\t\t\t##\tTestar om ett tal är större än ett tröskelvärde\r\nHEX2BIN\t\t\t= HEX.TILL.BIN\t\t\t##\tOmvandlar ett hexadecimalt tal till binärt\r\nHEX2DEC\t\t\t= HEX.TILL.DEC\t\t\t##\tOmvandlar ett hexadecimalt tal till decimalt\r\nHEX2OCT\t\t\t= HEX.TILL.OKT\t\t\t##\tOmvandlar ett hexadecimalt tal till oktalt\r\nIMABS\t\t\t= IMABS\t\t\t\t##\tReturnerar absolutvärdet (modulus) för ett komplext tal\r\nIMAGINARY\t\t= IMAGINÄR\t\t\t##\tReturnerar den imaginära koefficienten för ett komplext tal\r\nIMARGUMENT\t\t= IMARGUMENT\t\t\t##\tReturnerar det komplexa talets argument, en vinkel uttryckt i radianer\r\nIMCONJUGATE\t\t= IMKONJUGAT\t\t\t##\tReturnerar det komplexa talets konjugat\r\nIMCOS\t\t\t= IMCOS\t\t\t\t##\tReturnerar cosinus för ett komplext tal\r\nIMDIV\t\t\t= IMDIV\t\t\t\t##\tReturnerar kvoten för två komplexa tal\r\nIMEXP\t\t\t= IMEUPPHÖJT\t\t\t##\tReturnerar exponenten för ett komplext tal\r\nIMLN\t\t\t= IMLN\t\t\t\t##\tReturnerar den naturliga logaritmen för ett komplext tal\r\nIMLOG10\t\t\t= IMLOG10\t\t\t##\tReturnerar 10-logaritmen för ett komplext tal\r\nIMLOG2\t\t\t= IMLOG2\t\t\t##\tReturnerar 2-logaritmen för ett komplext tal\r\nIMPOWER\t\t\t= IMUPPHÖJT\t\t\t##\tReturnerar ett komplext tal upphöjt till en exponent\r\nIMPRODUCT\t\t= IMPRODUKT\t\t\t##\tReturnerar produkten av komplexa tal\r\nIMREAL\t\t\t= IMREAL\t\t\t##\tReturnerar den reella koefficienten för ett komplext tal\r\nIMSIN\t\t\t= IMSIN\t\t\t\t##\tReturnerar sinus för ett komplext tal\r\nIMSQRT\t\t\t= IMROT\t\t\t\t##\tReturnerar kvadratroten av ett komplext tal\r\nIMSUB\t\t\t= IMDIFF\t\t\t##\tReturnerar differensen mellan två komplexa tal\r\nIMSUM\t\t\t= IMSUM\t\t\t\t##\tReturnerar summan av komplexa tal\r\nOCT2BIN\t\t\t= OKT.TILL.BIN\t\t\t##\tOmvandlar ett oktalt tal till binärt\r\nOCT2DEC\t\t\t= OKT.TILL.DEC\t\t\t##\tOmvandlar ett oktalt tal till decimalt\r\nOCT2HEX\t\t\t= OKT.TILL.HEX\t\t\t##\tOmvandlar ett oktalt tal till hexadecimalt\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\tFinansiella funktioner\r\n##\r\nACCRINT\t\t\t= UPPLRÄNTA\t\t\t##\tReturnerar den upplupna räntan för värdepapper med periodisk ränta\r\nACCRINTM\t\t= UPPLOBLRÄNTA\t\t\t##\tReturnerar den upplupna räntan för ett värdepapper som ger avkastning på förfallodagen\r\nAMORDEGRC\t\t= AMORDEGRC\t\t\t##\tReturnerar avskrivningen för varje redovisningsperiod med hjälp av en avskrivningskoefficient\r\nAMORLINC\t\t= AMORLINC\t\t\t##\tReturnerar avskrivningen för varje redovisningsperiod\r\nCOUPDAYBS\t\t= KUPDAGBB\t\t\t##\tReturnerar antal dagar från början av kupongperioden till likviddagen\r\nCOUPDAYS\t\t= KUPDAGARS\t\t\t##\tReturnerar antalet dagar i kupongperioden som innehåller betalningsdatumet\r\nCOUPDAYSNC\t\t= KUPDAGNK\t\t\t##\tReturnerar antalet dagar från betalningsdatumet till nästa kupongdatum\r\nCOUPNCD\t\t\t= KUPNKD\t\t\t##\tReturnerar nästa kupongdatum efter likviddagen\r\nCOUPNUM\t\t\t= KUPANT\t\t\t##\tReturnerar kuponger som förfaller till betalning mellan likviddagen och förfallodagen\r\nCOUPPCD\t\t\t= KUPFKD\t\t\t##\tReturnerar föregående kupongdatum före likviddagen\r\nCUMIPMT\t\t\t= KUMRÄNTA\t\t\t##\tReturnerar den ackumulerade räntan som betalats mellan två perioder\r\nCUMPRINC\t\t= KUMPRIS\t\t\t##\tReturnerar det ackumulerade kapitalbeloppet som betalats på ett lån mellan två perioder\r\nDB\t\t\t= DB\t\t\t\t##\tReturnerar avskrivningen för en tillgång under en angiven tid enligt metoden för fast degressiv avskrivning\r\nDDB\t\t\t= DEGAVSKR\t\t\t##\tReturnerar en tillgångs värdeminskning under en viss period med hjälp av dubbel degressiv avskrivning eller någon annan metod som du anger\r\nDISC\t\t\t= DISK\t\t\t\t##\tReturnerar diskonteringsräntan för ett värdepapper\r\nDOLLARDE\t\t= DECTAL\t\t\t##\tOmvandlar ett pris uttryckt som ett bråk till ett decimaltal\r\nDOLLARFR\t\t= BRÅK\t\t\t\t##\tOmvandlar ett pris i kronor uttryckt som ett decimaltal till ett bråk\r\nDURATION\t\t= LÖPTID\t\t\t##\tReturnerar den årliga löptiden för en säkerhet med periodiska räntebetalningar\r\nEFFECT\t\t\t= EFFRÄNTA\t\t\t##\tReturnerar den årliga effektiva räntesatsen\r\nFV\t\t\t= SLUTVÄRDE\t\t\t##\tReturnerar det framtida värdet på en investering\r\nFVSCHEDULE\t\t= FÖRRÄNTNING\t\t\t##\tReturnerar det framtida värdet av ett begynnelsekapital beräknat på olika räntenivåer\r\nINTRATE\t\t\t= ÅRSRÄNTA\t\t\t##\tReturnerar räntesatsen för ett betalt värdepapper\r\nIPMT\t\t\t= RBETALNING\t\t\t##\tReturnerar räntedelen av en betalning för en given period\r\nIRR\t\t\t= IR\t\t\t\t##\tReturnerar internräntan för en serie betalningar\r\nISPMT\t\t\t= RALÅN\t\t\t\t##\tBeräknar räntan som har betalats under en specifik betalningsperiod\r\nMDURATION\t\t= MLÖPTID\t\t\t##\tReturnerar den modifierade Macauley-löptiden för ett värdepapper med det antagna nominella värdet 100 kr\r\nMIRR\t\t\t= MODIR\t\t\t\t##\tReturnerar internräntan där positiva och negativa betalningar finansieras med olika räntor\r\nNOMINAL\t\t\t= NOMRÄNTA\t\t\t##\tReturnerar den årliga nominella räntesatsen\r\nNPER\t\t\t= PERIODER\t\t\t##\tReturnerar antalet perioder för en investering\r\nNPV\t\t\t= NETNUVÄRDE\t\t\t##\tReturnerar nuvärdet av en serie periodiska betalningar vid en given diskonteringsränta\r\nODDFPRICE\t\t= UDDAFPRIS\t\t\t##\tReturnerar priset per 100 kr nominellt värde för ett värdepapper med en udda första period\r\nODDFYIELD\t\t= UDDAFAVKASTNING\t\t##\tReturnerar avkastningen för en säkerhet med en udda första period\r\nODDLPRICE\t\t= UDDASPRIS\t\t\t##\tReturnerar priset per 100 kr nominellt värde för ett värdepapper med en udda sista period\r\nODDLYIELD\t\t= UDDASAVKASTNING\t\t##\tReturnerar avkastningen för en säkerhet med en udda sista period\r\nPMT\t\t\t= BETALNING\t\t\t##\tReturnerar den periodiska betalningen för en annuitet\r\nPPMT\t\t\t= AMORT\t\t\t\t##\tReturnerar amorteringsdelen av en annuitetsbetalning för en given period\r\nPRICE\t\t\t= PRIS\t\t\t\t##\tReturnerar priset per 100 kr nominellt värde för ett värdepapper som ger periodisk ränta\r\nPRICEDISC\t\t= PRISDISK\t\t\t##\tReturnerar priset per 100 kr nominellt värde för ett diskonterat värdepapper\r\nPRICEMAT\t\t= PRISFÖRF\t\t\t##\tReturnerar priset per 100 kr nominellt värde för ett värdepapper som ger ränta på förfallodagen\r\nPV\t\t\t= PV\t\t\t\t##\tReturnerar nuvärdet av en serie lika stora periodiska betalningar\r\nRATE\t\t\t= RÄNTA\t\t\t\t##\tReturnerar räntesatsen per period i en annuitet\r\nRECEIVED\t\t= BELOPP\t\t\t##\tReturnerar beloppet som utdelas på förfallodagen för ett betalat värdepapper\r\nSLN\t\t\t= LINAVSKR\t\t\t##\tReturnerar den linjära avskrivningen för en tillgång under en period\r\nSYD\t\t\t= ÅRSAVSKR\t\t\t##\tReturnerar den årliga avskrivningssumman för en tillgång under en angiven period\r\nTBILLEQ\t\t\t= SSVXEKV\t\t\t##\tReturnerar avkastningen motsvarande en obligation för en statsskuldväxel\r\nTBILLPRICE\t\t= SSVXPRIS\t\t\t##\tReturnerar priset per 100 kr nominellt värde för en statsskuldväxel\r\nTBILLYIELD\t\t= SSVXRÄNTA\t\t\t##\tReturnerar avkastningen för en statsskuldväxel\r\nVDB\t\t\t= VDEGRAVSKR\t\t\t##\tReturnerar avskrivningen för en tillgång under en angiven period (med degressiv avskrivning)\r\nXIRR\t\t\t= XIRR\t\t\t\t##\tReturnerar internräntan för en serie betalningar som inte nödvändigtvis är periodiska\r\nXNPV\t\t\t= XNUVÄRDE\t\t\t##\tReturnerar det nuvarande nettovärdet för en serie betalningar som inte nödvändigtvis är periodiska\r\nYIELD\t\t\t= NOMAVK\t\t\t##\tReturnerar avkastningen för ett värdepapper som ger periodisk ränta\r\nYIELDDISC\t\t= NOMAVKDISK\t\t\t##\tReturnerar den årliga avkastningen för diskonterade värdepapper, exempelvis en statsskuldväxel\r\nYIELDMAT\t\t= NOMAVKFÖRF\t\t\t##\tReturnerar den årliga avkastningen för ett värdepapper som ger ränta på förfallodagen\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\tInformationsfunktioner\r\n##\r\nCELL\t\t\t= CELL\t\t\t\t##\tReturnerar information om formatering, plats och innehåll i en cell\r\nERROR.TYPE\t\t= FEL.TYP\t\t\t##\tReturnerar ett tal som motsvarar ett felvärde\r\nINFO\t\t\t= INFO\t\t\t\t##\tReturnerar information om operativsystemet\r\nISBLANK\t\t\t= ÄRREF\t\t\t\t##\tReturnerar SANT om värdet är tomt\r\nISERR\t\t\t= Ä\t\t\t\t##\tReturnerar SANT om värdet är ett felvärde annat än #SAKNAS!\r\nISERROR\t\t\t= ÄRFEL\t\t\t\t##\tReturnerar SANT om värdet är ett felvärde\r\nISEVEN\t\t\t= ÄRJÄMN\t\t\t##\tReturnerar SANT om talet är jämnt\r\nISLOGICAL\t\t= ÄREJTEXT\t\t\t##\tReturnerar SANT om värdet är ett logiskt värde\r\nISNA\t\t\t= ÄRLOGISK\t\t\t##\tReturnerar SANT om värdet är felvärdet #SAKNAS!\r\nISNONTEXT\t\t= ÄRSAKNAD\t\t\t##\tReturnerar SANT om värdet inte är text\r\nISNUMBER\t\t= ÄRTAL\t\t\t\t##\tReturnerar SANT om värdet är ett tal\r\nISODD\t\t\t= ÄRUDDA\t\t\t##\tReturnerar SANT om talet är udda\r\nISREF\t\t\t= ÄRTOM\t\t\t\t##\tReturnerar SANT om värdet är en referens\r\nISTEXT\t\t\t= ÄRTEXT\t\t\t##\tReturnerar SANT om värdet är text\r\nN\t\t\t= N\t\t\t\t##\tReturnerar ett värde omvandlat till ett tal\r\nNA\t\t\t= SAKNAS\t\t\t##\tReturnerar felvärdet #SAKNAS!\r\nTYPE\t\t\t= VÄRDETYP\t\t\t##\tReturnerar ett tal som anger värdets datatyp\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\tLogiska funktioner\r\n##\r\nAND\t\t\t= OCH\t\t\t\t##\tReturnerar SANT om alla argument är sanna\r\nFALSE\t\t\t= FALSKT\t\t\t##\tReturnerar det logiska värdet FALSKT\r\nIF\t\t\t= OM\t\t\t\t##\tAnger vilket logiskt test som ska utföras\r\nIFERROR\t\t\t= OMFEL\t\t\t\t##\tReturnerar ett värde som du anger om en formel utvärderar till ett fel; annars returneras resultatet av formeln\r\nNOT\t\t\t= ICKE\t\t\t\t##\tInverterar logiken för argumenten\r\nOR\t\t\t= ELLER\t\t\t\t##\tReturnerar SANT om något argument är SANT\r\nTRUE\t\t\t= SANT\t\t\t\t##\tReturnerar det logiska värdet SANT\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\tSök- och referensfunktioner\r\n##\r\nADDRESS\t\t\t= ADRESS\t\t\t##\tReturnerar en referens som text till en enstaka cell i ett kalkylblad\r\nAREAS\t\t\t= OMRÅDEN\t\t\t##\tReturnerar antalet områden i en referens\r\nCHOOSE\t\t\t= VÄLJ\t\t\t\t##\tVäljer ett värde i en lista över värden\r\nCOLUMN\t\t\t= KOLUMN\t\t\t##\tReturnerar kolumnnumret för en referens\r\nCOLUMNS\t\t\t= KOLUMNER\t\t\t##\tReturnerar antalet kolumner i en referens\r\nHLOOKUP\t\t\t= LETAKOLUMN\t\t\t##\tSöker i den översta raden i en matris och returnerar värdet för angiven cell\r\nHYPERLINK\t\t= HYPERLÄNK\t\t\t##\tSkapar en genväg eller ett hopp till ett dokument i nätverket, i ett intranät eller på Internet\r\nINDEX\t\t\t= INDEX\t\t\t\t##\tAnvänder ett index för ett välja ett värde i en referens eller matris\r\nINDIRECT\t\t= INDIREKT\t\t\t##\tReturnerar en referens som anges av ett textvärde\r\nLOOKUP\t\t\t= LETAUPP\t\t\t##\tLetar upp värden i en vektor eller matris\r\nMATCH\t\t\t= PASSA\t\t\t\t##\tLetar upp värden i en referens eller matris\r\nOFFSET\t\t\t= FÖRSKJUTNING\t\t\t##\tReturnerar en referens förskjuten i förhållande till en given referens\r\nROW\t\t\t= RAD\t\t\t\t##\tReturnerar radnumret för en referens\r\nROWS\t\t\t= RADER\t\t\t\t##\tReturnerar antalet rader i en referens\r\nRTD\t\t\t= RTD\t\t\t\t##\tHämtar realtidsdata från ett program som stöder COM-automation (Automation: Ett sätt att arbeta med ett programs objekt från ett annat program eller utvecklingsverktyg. Detta kallades tidigare för OLE Automation, och är en branschstandard och ingår i Component Object Model (COM).)\r\nTRANSPOSE\t\t= TRANSPONERA\t\t\t##\tTransponerar en matris\r\nVLOOKUP\t\t\t= LETARAD\t\t\t##\tLetar i den första kolumnen i en matris och flyttar över raden för att returnera värdet för en cell\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\tMatematiska och trigonometriska funktioner\r\n##\r\nABS\t\t\t= ABS\t\t\t\t##\tReturnerar absolutvärdet av ett tal\r\nACOS\t\t\t= ARCCOS\t\t\t##\tReturnerar arcus cosinus för ett tal\r\nACOSH\t\t\t= ARCCOSH\t\t\t##\tReturnerar inverterad hyperbolisk cosinus för ett tal\r\nASIN\t\t\t= ARCSIN\t\t\t##\tReturnerar arcus cosinus för ett tal\r\nASINH\t\t\t= ARCSINH\t\t\t##\tReturnerar hyperbolisk arcus sinus för ett tal\r\nATAN\t\t\t= ARCTAN\t\t\t##\tReturnerar arcus tangens för ett tal\r\nATAN2\t\t\t= ARCTAN2\t\t\t##\tReturnerar arcus tangens för en x- och en y- koordinat\r\nATANH\t\t\t= ARCTANH\t\t\t##\tReturnerar hyperbolisk arcus tangens för ett tal\r\nCEILING\t\t\t= RUNDA.UPP\t\t\t##\tAvrundar ett tal till närmaste heltal eller närmaste signifikanta multipel\r\nCOMBIN\t\t\t= KOMBIN\t\t\t##\tReturnerar antalet kombinationer för ett givet antal objekt\r\nCOS\t\t\t= COS\t\t\t\t##\tReturnerar cosinus för ett tal\r\nCOSH\t\t\t= COSH\t\t\t\t##\tReturnerar hyperboliskt cosinus för ett tal\r\nDEGREES\t\t\t= GRADER\t\t\t##\tOmvandlar radianer till grader\r\nEVEN\t\t\t= JÄMN\t\t\t\t##\tAvrundar ett tal uppåt till närmaste heltal\r\nEXP\t\t\t= EXP\t\t\t\t##\tReturnerar e upphöjt till ett givet tal\r\nFACT\t\t\t= FAKULTET\t\t\t##\tReturnerar fakulteten för ett tal\r\nFACTDOUBLE\t\t= DUBBELFAKULTET\t\t##\tReturnerar dubbelfakulteten för ett tal\r\nFLOOR\t\t\t= RUNDA.NED\t\t\t##\tAvrundar ett tal nedåt mot noll\r\nGCD\t\t\t= SGD\t\t\t\t##\tReturnerar den största gemensamma nämnaren\r\nINT\t\t\t= HELTAL\t\t\t##\tAvrundar ett tal nedåt till närmaste heltal\r\nLCM\t\t\t= MGM\t\t\t\t##\tReturnerar den minsta gemensamma multipeln\r\nLN\t\t\t= LN\t\t\t\t##\tReturnerar den naturliga logaritmen för ett tal\r\nLOG\t\t\t= LOG\t\t\t\t##\tReturnerar logaritmen för ett tal för en given bas\r\nLOG10\t\t\t= LOG10\t\t\t\t##\tReturnerar 10-logaritmen för ett tal\r\nMDETERM\t\t\t= MDETERM\t\t\t##\tReturnerar matrisen som är avgörandet av en matris\r\nMINVERSE\t\t= MINVERT\t\t\t##\tReturnerar matrisinversen av en matris\r\nMMULT\t\t\t= MMULT\t\t\t\t##\tReturnerar matrisprodukten av två matriser\r\nMOD\t\t\t= REST\t\t\t\t##\tReturnerar resten vid en division\r\nMROUND\t\t\t= MAVRUNDA\t\t\t##\tReturnerar ett tal avrundat till en given multipel\r\nMULTINOMIAL\t\t= MULTINOMIAL\t\t\t##\tReturnerar multinomialen för en uppsättning tal\r\nODD\t\t\t= UDDA\t\t\t\t##\tAvrundar ett tal uppåt till närmaste udda heltal\r\nPI\t\t\t= PI\t\t\t\t##\tReturnerar värdet pi\r\nPOWER\t\t\t= UPPHÖJT.TILL\t\t\t##\tReturnerar resultatet av ett tal upphöjt till en exponent\r\nPRODUCT\t\t\t= PRODUKT\t\t\t##\tMultiplicerar argumenten\r\nQUOTIENT\t\t= KVOT\t\t\t\t##\tReturnerar heltalsdelen av en division\r\nRADIANS\t\t\t= RADIANER\t\t\t##\tOmvandlar grader till radianer\r\nRAND\t\t\t= SLUMP\t\t\t\t##\tReturnerar ett slumptal mellan 0 och 1\r\nRANDBETWEEN\t\t= SLUMP.MELLAN\t\t\t##\tReturnerar ett slumptal mellan de tal som du anger\r\nROMAN\t\t\t= ROMERSK\t\t\t##\tOmvandlar vanliga (arabiska) siffror till romerska som text\r\nROUND\t\t\t= AVRUNDA\t\t\t##\tAvrundar ett tal till ett angivet antal siffror\r\nROUNDDOWN\t\t= AVRUNDA.NEDÅT\t\t\t##\tAvrundar ett tal nedåt mot noll\r\nROUNDUP\t\t\t= AVRUNDA.UPPÅT\t\t\t##\tAvrundar ett tal uppåt, från noll\r\nSERIESSUM\t\t= SERIESUMMA\t\t\t##\tReturnerar summan av en potensserie baserat på formeln\r\nSIGN\t\t\t= TECKEN\t\t\t##\tReturnerar tecknet för ett tal\r\nSIN\t\t\t= SIN\t\t\t\t##\tReturnerar sinus för en given vinkel\r\nSINH\t\t\t= SINH\t\t\t\t##\tReturnerar hyperbolisk sinus för ett tal\r\nSQRT\t\t\t= ROT\t\t\t\t##\tReturnerar den positiva kvadratroten\r\nSQRTPI\t\t\t= ROTPI\t\t\t\t##\tReturnerar kvadratroten för (tal * pi)\r\nSUBTOTAL\t\t= DELSUMMA\t\t\t##\tReturnerar en delsumma i en lista eller databas\r\nSUM\t\t\t= SUMMA\t\t\t\t##\tSummerar argumenten\r\nSUMIF\t\t\t= SUMMA.OM\t\t\t##\tSummerar celler enligt ett angivet villkor\r\nSUMIFS\t\t\t= SUMMA.OMF\t\t\t##\tLägger till cellerna i ett område som uppfyller flera kriterier\r\nSUMPRODUCT\t\t= PRODUKTSUMMA\t\t\t##\tReturnerar summan av produkterna i motsvarande matriskomponenter\r\nSUMSQ\t\t\t= KVADRATSUMMA\t\t\t##\tReturnerar summan av argumentens kvadrater\r\nSUMX2MY2\t\t= SUMMAX2MY2\t\t\t##\tReturnerar summan av differensen mellan kvadraterna för motsvarande värden i två matriser\r\nSUMX2PY2\t\t= SUMMAX2PY2\t\t\t##\tReturnerar summan av summan av kvadraterna av motsvarande värden i två matriser\r\nSUMXMY2\t\t\t= SUMMAXMY2\t\t\t##\tReturnerar summan av kvadraten av skillnaden mellan motsvarande värden i två matriser\r\nTAN\t\t\t= TAN\t\t\t\t##\tReturnerar tangens för ett tal\r\nTANH\t\t\t= TANH\t\t\t\t##\tReturnerar hyperbolisk tangens för ett tal\r\nTRUNC\t\t\t= AVKORTA\t\t\t##\tAvkortar ett tal till ett heltal\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\tStatistiska funktioner\r\n##\r\nAVEDEV\t\t\t= MEDELAVV\t\t\t##\tReturnerar medelvärdet för datapunkters absoluta avvikelse från deras medelvärde\r\nAVERAGE\t\t\t= MEDEL\t\t\t\t##\tReturnerar medelvärdet av argumenten\r\nAVERAGEA\t\t= AVERAGEA\t\t\t##\tReturnerar medelvärdet av argumenten, inklusive tal, text och logiska värden\r\nAVERAGEIF\t\t= MEDELOM\t\t\t##\tReturnerar medelvärdet (aritmetiskt medelvärde) för alla celler i ett område som uppfyller ett givet kriterium\r\nAVERAGEIFS\t\t= MEDELOMF\t\t\t##\tReturnerar medelvärdet (det aritmetiska medelvärdet) för alla celler som uppfyller flera villkor.\r\nBETADIST\t\t= BETAFÖRD\t\t\t##\tReturnerar den kumulativa betafördelningsfunktionen\r\nBETAINV\t\t\t= BETAINV\t\t\t##\tReturnerar inversen till den kumulativa fördelningsfunktionen för en viss betafördelning\r\nBINOMDIST\t\t= BINOMFÖRD\t\t\t##\tReturnerar den individuella binomialfördelningen\r\nCHIDIST\t\t\t= CHI2FÖRD\t\t\t##\tReturnerar den ensidiga sannolikheten av c2-fördelningen\r\nCHIINV\t\t\t= CHI2INV\t\t\t##\tReturnerar inversen av chi2-fördelningen\r\nCHITEST\t\t\t= CHI2TEST\t\t\t##\tReturnerar oberoendetesten\r\nCONFIDENCE\t\t= KONFIDENS\t\t\t##\tReturnerar konfidensintervallet för en populations medelvärde\r\nCORREL\t\t\t= KORREL\t\t\t##\tReturnerar korrelationskoefficienten mellan två datamängder\r\nCOUNT\t\t\t= ANTAL\t\t\t\t##\tRäknar hur många tal som finns bland argumenten\r\nCOUNTA\t\t\t= ANTALV\t\t\t##\tRäknar hur många värden som finns bland argumenten\r\nCOUNTBLANK\t\t= ANTAL.TOMMA\t\t\t##\tRäknar antalet tomma celler i ett område\r\nCOUNTIF\t\t\t= ANTAL.OM\t\t\t##\tRäknar antalet celler i ett område som uppfyller angivna villkor.\r\nCOUNTIFS\t\t= ANTAL.OMF\t\t\t##\tRäknar antalet celler i ett område som uppfyller flera villkor.\r\nCOVAR\t\t\t= KOVAR\t\t\t\t##\tReturnerar kovariansen, d.v.s. medelvärdet av produkterna för parade avvikelser\r\nCRITBINOM\t\t= KRITBINOM\t\t\t##\tReturnerar det minsta värdet för vilket den kumulativa binomialfördelningen är mindre än eller lika med ett villkorsvärde\r\nDEVSQ\t\t\t= KVADAVV\t\t\t##\tReturnerar summan av kvadrater på avvikelser\r\nEXPONDIST\t\t= EXPONFÖRD\t\t\t##\tReturnerar exponentialfördelningen\r\nFDIST\t\t\t= FFÖRD\t\t\t\t##\tReturnerar F-sannolikhetsfördelningen\r\nFINV\t\t\t= FINV\t\t\t\t##\tReturnerar inversen till F-sannolikhetsfördelningen\r\nFISHER\t\t\t= FISHER\t\t\t##\tReturnerar Fisher-transformationen\r\nFISHERINV\t\t= FISHERINV\t\t\t##\tReturnerar inversen till Fisher-transformationen\r\nFORECAST\t\t= PREDIKTION\t\t\t##\tReturnerar ett värde längs en linjär trendlinje\r\nFREQUENCY\t\t= FREKVENS\t\t\t##\tReturnerar en frekvensfördelning som en lodrät matris\r\nFTEST\t\t\t= FTEST\t\t\t\t##\tReturnerar resultatet av en F-test\r\nGAMMADIST\t\t= GAMMAFÖRD\t\t\t##\tReturnerar gammafördelningen\r\nGAMMAINV\t\t= GAMMAINV\t\t\t##\tReturnerar inversen till den kumulativa gammafördelningen\r\nGAMMALN\t\t\t= GAMMALN\t\t\t##\tReturnerar den naturliga logaritmen för gammafunktionen, G(x)\r\nGEOMEAN\t\t\t= GEOMEDEL\t\t\t##\tReturnerar det geometriska medelvärdet\r\nGROWTH\t\t\t= EXPTREND\t\t\t##\tReturnerar värden längs en exponentiell trend\r\nHARMEAN\t\t\t= HARMMEDEL\t\t\t##\tReturnerar det harmoniska medelvärdet\r\nHYPGEOMDIST\t\t= HYPGEOMFÖRD\t\t\t##\tReturnerar den hypergeometriska fördelningen\r\nINTERCEPT\t\t= SKÄRNINGSPUNKT\t\t##\tReturnerar skärningspunkten för en linjär regressionslinje\r\nKURT\t\t\t= TOPPIGHET\t\t\t##\tReturnerar toppigheten av en mängd data\r\nLARGE\t\t\t= STÖRSTA\t\t\t##\tReturnerar det n:te största värdet i en mängd data\r\nLINEST\t\t\t= REGR\t\t\t\t##\tReturnerar parametrar till en linjär trendlinje\r\nLOGEST\t\t\t= EXPREGR\t\t\t##\tReturnerar parametrarna i en exponentiell trend\r\nLOGINV\t\t\t= LOGINV\t\t\t##\tReturnerar inversen till den lognormala fördelningen\r\nLOGNORMDIST\t\t= LOGNORMFÖRD\t\t\t##\tReturnerar den kumulativa lognormala fördelningen\r\nMAX\t\t\t= MAX\t\t\t\t##\tReturnerar det största värdet i en lista av argument\r\nMAXA\t\t\t= MAXA\t\t\t\t##\tReturnerar det största värdet i en lista av argument, inklusive tal, text och logiska värden\r\nMEDIAN\t\t\t= MEDIAN\t\t\t##\tReturnerar medianen för angivna tal\r\nMIN\t\t\t= MIN\t\t\t\t##\tReturnerar det minsta värdet i en lista med argument\r\nMINA\t\t\t= MINA\t\t\t\t##\tReturnerar det minsta värdet i en lista över argument, inklusive tal, text och logiska värden\r\nMODE\t\t\t= TYPVÄRDE\t\t\t##\tReturnerar det vanligaste värdet i en datamängd\r\nNEGBINOMDIST\t\t= NEGBINOMFÖRD\t\t\t##\tReturnerar den negativa binomialfördelningen\r\nNORMDIST\t\t= NORMFÖRD\t\t\t##\tReturnerar den kumulativa normalfördelningen\r\nNORMINV\t\t\t= NORMINV\t\t\t##\tReturnerar inversen till den kumulativa normalfördelningen\r\nNORMSDIST\t\t= NORMSFÖRD\t\t\t##\tReturnerar den kumulativa standardnormalfördelningen\r\nNORMSINV\t\t= NORMSINV\t\t\t##\tReturnerar inversen till den kumulativa standardnormalfördelningen\r\nPEARSON\t\t\t= PEARSON\t\t\t##\tReturnerar korrelationskoefficienten till Pearsons momentprodukt\r\nPERCENTILE\t\t= PERCENTIL\t\t\t##\tReturnerar den n:te percentilen av värden i ett område\r\nPERCENTRANK\t\t= PROCENTRANG\t\t\t##\tReturnerar procentrangen för ett värde i en datamängd\r\nPERMUT\t\t\t= PERMUT\t\t\t##\tReturnerar antal permutationer för ett givet antal objekt\r\nPOISSON\t\t\t= POISSON\t\t\t##\tReturnerar Poisson-fördelningen\r\nPROB\t\t\t= SANNOLIKHET\t\t\t##\tReturnerar sannolikheten att värden i ett område ligger mellan två gränser\r\nQUARTILE\t\t= KVARTIL\t\t\t##\tReturnerar kvartilen av en mängd data\r\nRANK\t\t\t= RANG\t\t\t\t##\tReturnerar rangordningen för ett tal i en lista med tal\r\nRSQ\t\t\t= RKV\t\t\t\t##\tReturnerar kvadraten av Pearsons produktmomentkorrelationskoefficient\r\nSKEW\t\t\t= SNEDHET\t\t\t##\tReturnerar snedheten för en fördelning\r\nSLOPE\t\t\t= LUTNING\t\t\t##\tReturnerar lutningen på en linjär regressionslinje\r\nSMALL\t\t\t= MINSTA\t\t\t##\tReturnerar det n:te minsta värdet i en mängd data\r\nSTANDARDIZE\t\t= STANDARDISERA\t\t\t##\tReturnerar ett normaliserat värde\r\nSTDEV\t\t\t= STDAV\t\t\t\t##\tUppskattar standardavvikelsen baserat på ett urval\r\nSTDEVA\t\t\t= STDEVA\t\t\t##\tUppskattar standardavvikelsen baserat på ett urval, inklusive tal, text och logiska värden\r\nSTDEVP\t\t\t= STDAVP\t\t\t##\tBeräknar standardavvikelsen baserat på hela populationen\r\nSTDEVPA\t\t\t= STDEVPA\t\t\t##\tBeräknar standardavvikelsen baserat på hela populationen, inklusive tal, text och logiska värden\r\nSTEYX\t\t\t= STDFELYX\t\t\t##\tReturnerar standardfelet för ett förutspått y-värde för varje x-värde i regressionen\r\nTDIST\t\t\t= TFÖRD\t\t\t\t##\tReturnerar Students t-fördelning\r\nTINV\t\t\t= TINV\t\t\t\t##\tReturnerar inversen till Students t-fördelning\r\nTREND\t\t\t= TREND\t\t\t\t##\tReturnerar värden längs en linjär trend\r\nTRIMMEAN\t\t= TRIMMEDEL\t\t\t##\tReturnerar medelvärdet av mittpunkterna i en datamängd\r\nTTEST\t\t\t= TTEST\t\t\t\t##\tReturnerar sannolikheten beräknad ur Students t-test\r\nVAR\t\t\t= VARIANS\t\t\t##\tUppskattar variansen baserat på ett urval\r\nVARA\t\t\t= VARA\t\t\t\t##\tUppskattar variansen baserat på ett urval, inklusive tal, text och logiska värden\r\nVARP\t\t\t= VARIANSP\t\t\t##\tBeräknar variansen baserat på hela populationen\r\nVARPA\t\t\t= VARPA\t\t\t\t##\tBeräknar variansen baserat på hela populationen, inklusive tal, text och logiska värden\r\nWEIBULL\t\t\t= WEIBULL\t\t\t##\tReturnerar Weibull-fördelningen\r\nZTEST\t\t\t= ZTEST\t\t\t\t##\tReturnerar det ensidiga sannolikhetsvärdet av ett z-test\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\tTextfunktioner\r\n##\r\nASC\t\t\t= ASC\t\t\t\t##\tÄndrar helbredds (dubbel byte) engelska bokstäver eller katakana inom en teckensträng till tecken med halvt breddsteg (enkel byte)\r\nBAHTTEXT\t\t= BAHTTEXT\t\t\t##\tOmvandlar ett tal till text med valutaformatet ß (baht)\r\nCHAR\t\t\t= TECKENKOD\t\t\t##\tReturnerar tecknet som anges av kod\r\nCLEAN\t\t\t= STÄDA\t\t\t\t##\tTar bort alla icke utskrivbara tecken i en text\r\nCODE\t\t\t= KOD\t\t\t\t##\tReturnerar en numerisk kod för det första tecknet i en textsträng\r\nCONCATENATE\t\t= SAMMANFOGA\t\t\t##\tSammanfogar flera textdelar till en textsträng\r\nDOLLAR\t\t\t= VALUTA\t\t\t##\tOmvandlar ett tal till text med valutaformat\r\nEXACT\t\t\t= EXAKT\t\t\t\t##\tKontrollerar om två textvärden är identiska\r\nFIND\t\t\t= HITTA\t\t\t\t##\tHittar en text i en annan (skiljer på gemener och versaler)\r\nFINDB\t\t\t= HITTAB\t\t\t##\tHittar en text i en annan (skiljer på gemener och versaler)\r\nFIXED\t\t\t= FASTTAL\t\t\t##\tFormaterar ett tal som text med ett fast antal decimaler\r\nJIS\t\t\t= JIS\t\t\t\t##\tÄndrar halvbredds (enkel byte) engelska bokstäver eller katakana inom en teckensträng till tecken med helt breddsteg (dubbel byte)\r\nLEFT\t\t\t= VÄNSTER\t\t\t##\tReturnerar tecken längst till vänster i en sträng\r\nLEFTB\t\t\t= VÄNSTERB\t\t\t##\tReturnerar tecken längst till vänster i en sträng\r\nLEN\t\t\t= LÄNGD\t\t\t\t##\tReturnerar antalet tecken i en textsträng\r\nLENB\t\t\t= LÄNGDB\t\t\t##\tReturnerar antalet tecken i en textsträng\r\nLOWER\t\t\t= GEMENER\t\t\t##\tOmvandlar text till gemener\r\nMID\t\t\t= EXTEXT\t\t\t##\tReturnerar angivet antal tecken från en text med början vid den position som du anger\r\nMIDB\t\t\t= EXTEXTB\t\t\t##\tReturnerar angivet antal tecken från en text med början vid den position som du anger\r\nPHONETIC\t\t= PHONETIC\t\t\t##\tReturnerar de fonetiska (furigana) tecknen i en textsträng\r\nPROPER\t\t\t= INITIAL\t\t\t##\tÄndrar första bokstaven i varje ord i ett textvärde till versal\r\nREPLACE\t\t\t= ERSÄTT\t\t\t##\tErsätter tecken i text\r\nREPLACEB\t\t= ERSÄTTB\t\t\t##\tErsätter tecken i text\r\nREPT\t\t\t= REP\t\t\t\t##\tUpprepar en text ett bestämt antal gånger\r\nRIGHT\t\t\t= HÖGER\t\t\t\t##\tReturnerar tecken längst till höger i en sträng\r\nRIGHTB\t\t\t= HÖGERB\t\t\t##\tReturnerar tecken längst till höger i en sträng\r\nSEARCH\t\t\t= SÖK\t\t\t\t##\tHittar ett textvärde i ett annat (skiljer inte på gemener och versaler)\r\nSEARCHB\t\t\t= SÖKB\t\t\t\t##\tHittar ett textvärde i ett annat (skiljer inte på gemener och versaler)\r\nSUBSTITUTE\t\t= BYT.UT\t\t\t##\tErsätter gammal text med ny text i en textsträng\r\nT\t\t\t= T\t\t\t\t##\tOmvandlar argumenten till text\r\nTEXT\t\t\t= TEXT\t\t\t\t##\tFormaterar ett tal och omvandlar det till text\r\nTRIM\t\t\t= RENSA\t\t\t\t##\tTar bort blanksteg från text\r\nUPPER\t\t\t= VERSALER\t\t\t##\tOmvandlar text till versaler\r\nVALUE\t\t\t= TEXTNUM\t\t\t##\tOmvandlar ett textargument till ett tal\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/config",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Settings\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n##\r\n\r\n\r\nArgumentSeparator\t= ;\r\n\r\n\r\n##\r\n##\t(For future use)\r\n##\r\ncurrencySymbol\t= YTL\r\n\r\n\r\n##\r\n##\tExcel Error Codes\t(For future use)\r\r\n##\r\nNULL\t= #BOŞ!\r\nDIV0\t= #SAYI/0!\r\nVALUE\t= #DEĞER!\r\nREF\t= #BAŞV!\r\nNAME\t= #AD?\r\nNUM\t= #SAYI!\r\nNA\t= #YOK\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel/locale/tr/functions",
    "content": "##\r\n## PHPExcel\r\n##\r\r\n## Copyright (c) 2006 - 2013 PHPExcel\r\n##\r\n## This library is free software; you can redistribute it and/or\r\n## modify it under the terms of the GNU Lesser General Public\r\n## License as published by the Free Software Foundation; either\r\n## version 2.1 of the License, or (at your option) any later version.\r\n##\r\n## This library is distributed in the hope that it will be useful,\r\n## but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n## Lesser General Public License for more details.\r\n##\r\n## You should have received a copy of the GNU Lesser General Public\r\n## License along with this library; if not, write to the Free Software\r\n## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n##\r\n## @category   PHPExcel\r\n## @package    PHPExcel_Calculation\r\n## @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n## @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n## @version    ##VERSION##, ##DATE##\r\n##\r\n## Data in this file derived from http://www.piuha.fi/excel-function-name-translation/\r\n##\r\n##\r\n\r\n\r\n##\r\n##\tAdd-in and Automation functions\t\t\tEklenti ve Otomasyon fonksiyonları\r\n##\r\nGETPIVOTDATA\t\t= ÖZETVERİAL\t##\tBir Özet Tablo raporunda saklanan verileri verir.\r\n\r\n\r\n##\r\n##\tCube functions\t\t\t\t\tKüp işlevleri\r\n##\r\nCUBEKPIMEMBER\t\t= KÜPKPIÜYE\t\t\t##\tKilit performans göstergesi (KPI-Key Performance Indicator) adını, özelliğini ve ölçüsünü verir ve hücredeki ad ve özelliği gösterir. KPI, bir kurumun performansını izlemek için kullanılan aylık brüt kâr ya da üç aylık çalışan giriş çıkışları gibi ölçülebilen bir birimdir.\r\nCUBEMEMBER\t\t\t= KÜPÜYE\t\t\t##\tBir küp hiyerarşisinde bir üyeyi veya kaydı verir. Üye veya kaydın küpte varolduğunu doğrulamak için kullanılır.\r\nCUBEMEMBERPROPERTY\t= KÜPÜYEÖZELLİĞİ\t##\tBir küpte bir üyenin özelliğinin değerini verir. Küp içinde üye adının varlığını doğrulamak ve bu üyenin belli özelliklerini getirmek için kullanılır.\r\nCUBERANKEDMEMBER\t= KÜPÜYESIRASI \t\t##\tBir küme içindeki üyenin derecesini veya kaçıncı olduğunu verir. En iyi satış elemanı, veya en iyi on öğrenci gibi bir kümedeki bir veya daha fazla öğeyi getirmek için kullanılır.\r\nCUBESET\t\t\t\t= KÜPKÜME\t\t\t##\tKümeyi oluşturan ve ardından bu kümeyi Microsoft Office Excel'e getiren sunucudaki küpe küme ifadelerini göndererek hesaplanan üye veya kayıt kümesini tanımlar.\r\nCUBESETCOUNT\t\t= KÜPKÜMESAY\t\t##\tBir kümedeki öğelerin sayısını getirir.\r\nCUBEVALUE\t\t\t= KÜPDEĞER \t\t\t##\tBir küpten toplam değeri getirir.\r\n\r\n\r\n##\r\n##\tDatabase functions\t\t\t\tVeritabanı işlevleri\r\n##\r\nDAVERAGE\t\t= VSEÇORT\t\t\t##\tSeçili veritabanı girdilerinin ortalamasını verir.\r\nDCOUNT\t\t\t= VSEÇSAY\t\t\t##\tVeritabanında sayı içeren hücre sayısını hesaplar.\r\nDCOUNTA\t\t\t= VSEÇSAYDOLU\t\t##\tVeritabanındaki boş olmayan hücreleri sayar.\r\nDGET\t\t\t= VAL\t\t\t\t##\tVeritabanından, belirtilen ölçütlerle eşleşen tek bir rapor çıkarır.\r\nDMAX\t\t\t= VSEÇMAK\t\t\t##\tSeçili veritabanı girişlerinin en yüksek değerini verir.\r\nDMIN\t\t\t= VSEÇMİN\t\t\t##\tSeçili veritabanı girişlerinin en düşük değerini verir.\r\nDPRODUCT\t\t= VSEÇÇARP\t\t\t##\tKayıtların belli bir alanında bulunan, bir veritabanındaki ölçütlerle eşleşen değerleri çarpar.\r\nDSTDEV\t\t\t= VSEÇSTDSAPMA\t\t##\tSeçili veritabanı girişlerinden oluşan bir örneğe dayanarak, standart sapmayı tahmin eder.\r\nDSTDEVP\t\t\t= VSEÇSTDSAPMAS\t\t##\tStandart sapmayı, seçili veritabanı girişlerinin tüm popülasyonunu esas alarak hesaplar.\r\nDSUM\t\t\t= VSEÇTOPLA\t\t\t##\tKayıtların alan sütununda bulunan, ölçütle eşleşen sayıları toplar.\r\nDVAR\t\t\t= VSEÇVAR\t\t\t##\tSeçili veritabanı girişlerinden oluşan bir örneği esas alarak farkı tahmin eder.\r\nDVARP\t\t\t= VSEÇVARS\t\t\t##\tSeçili veritabanı girişlerinin tüm popülasyonunu esas alarak farkı hesaplar.\r\n\r\n\r\n##\r\n##\tDate and time functions\t\t\t\tTarih ve saat işlevleri\r\n##\r\nDATE\t\t\t= TARİH\t\t\t\t##\tBelirli bir tarihin seri numarasını verir.\r\nDATEVALUE\t\t= TARİHSAYISI\t\t##\tMetin biçimindeki bir tarihi seri numarasına dönüştürür.\r\nDAY\t\t\t\t= GÜN\t\t\t\t##\tSeri numarasını, ayın bir gününe dönüştürür.\r\nDAYS360\t\t\t= GÜN360\t\t\t##\tİki tarih arasındaki gün sayısını, 360 günlük yılı esas alarak hesaplar.\r\nEDATE\t\t\t= SERİTARİH\t\t\t##\tBaşlangıç tarihinden itibaren, belirtilen ay sayısından önce veya sonraki tarihin seri numarasını verir.\r\nEOMONTH\t\t\t= SERİAY\t\t\t##\tBelirtilen sayıda ay önce veya sonraki ayın son gününün seri numarasını verir.\r\nHOUR\t\t\t= SAAT\t\t\t\t##\tBir seri numarasını saate dönüştürür.\r\nMINUTE\t\t\t= DAKİKA\t\t\t##\tBir seri numarasını dakikaya dönüştürür.\r\nMONTH\t\t\t= AY\t\t\t\t##\tBir seri numarasını aya dönüştürür.\r\nNETWORKDAYS\t\t= TAMİŞGÜNÜ\t\t\t##\tİki tarih arasındaki tam çalışma günlerinin sayısını verir.\r\nNOW\t\t\t\t= ŞİMDİ\t\t\t\t##\tGeçerli tarihin ve saatin seri numarasını verir.\r\nSECOND\t\t\t= SANİYE\t\t\t##\tBir seri numarasını saniyeye dönüştürür.\r\nTIME\t\t\t= ZAMAN\t\t\t\t##\tBelirli bir zamanın seri numarasını verir.\r\nTIMEVALUE\t\t= ZAMANSAYISI\t\t##\tMetin biçimindeki zamanı seri numarasına dönüştürür.\r\nTODAY\t\t\t= BUGÜN\t\t\t\t##\tBugünün tarihini seri numarasına dönüştürür.\r\nWEEKDAY\t\t\t= HAFTANINGÜNÜ\t\t##\tBir seri numarasını, haftanın gününe dönüştürür.\r\nWEEKNUM\t\t\t= HAFTASAY\t\t\t##\tDizisel değerini, haftanın yıl içinde bulunduğu konumu sayısal olarak gösteren sayıya dönüştürür.\r\nWORKDAY\t\t\t= İŞGÜNÜ\t\t\t##\tBelirtilen sayıda çalışma günü öncesinin ya da sonrasının tarihinin seri numarasını verir.\r\nYEAR\t\t\t= YIL\t\t\t\t##\tBir seri numarasını yıla dönüştürür.\r\nYEARFRAC\t\t= YILORAN\t\t\t##\tBaşlangıç_tarihi ve bitiş_tarihi arasındaki tam günleri gösteren yıl kesrini verir.\r\n\r\n\r\n##\r\n##\tEngineering functions\t\t\t\tMühendislik işlevleri\r\n##\r\nBESSELI\t\t\t= BESSELI\t\t\t##\tDeğiştirilmiş Bessel fonksiyonu In(x)'i verir.\r\nBESSELJ\t\t\t= BESSELJ\t\t\t##\tBessel fonksiyonu Jn(x)'i verir.\r\nBESSELK\t\t\t= BESSELK\t\t\t##\tDeğiştirilmiş Bessel fonksiyonu Kn(x)'i verir.\r\nBESSELY\t\t\t= BESSELY\t\t\t##\tBessel fonksiyonu Yn(x)'i verir.\r\nBIN2DEC\t\t\t= BIN2DEC\t\t\t##\tİkili bir sayıyı, ondalık sayıya dönüştürür.\r\nBIN2HEX\t\t\t= BIN2HEX\t\t\t##\tİkili bir sayıyı, onaltılıya dönüştürür.\r\nBIN2OCT\t\t\t= BIN2OCT\t\t\t##\tİkili bir sayıyı, sekizliye dönüştürür.\r\nCOMPLEX\t\t\t= KARMAŞIK\t\t\t##\tGerçek ve sanal katsayıları, karmaşık sayıya dönüştürür.\r\nCONVERT\t\t\t= ÇEVİR\t\t\t\t##\tBir sayıyı, bir ölçüm sisteminden bir başka ölçüm sistemine dönüştürür.\r\nDEC2BIN\t\t\t= DEC2BIN\t\t\t##\tOndalık bir sayıyı, ikiliye dönüştürür.\r\nDEC2HEX\t\t\t= DEC2HEX\t\t\t##\tOndalık bir sayıyı, onaltılıya dönüştürür.\r\nDEC2OCT\t\t\t= DEC2OCT\t\t\t##\tOndalık bir sayıyı sekizliğe dönüştürür.\r\nDELTA\t\t\t= DELTA\t\t\t\t##\tİki değerin eşit olup olmadığını sınar.\r\nERF\t\t\t\t= HATAİŞLEV\t\t\t##\tHata işlevini verir.\r\nERFC\t\t\t= TÜMHATAİŞLEV\t\t##\tTümleyici hata işlevini verir.\r\nGESTEP\t\t\t= BESINIR\t\t\t##\tBir sayının eşik değerinden büyük olup olmadığını sınar.\r\nHEX2BIN\t\t\t= HEX2BIN\t\t\t##\tOnaltılı bir sayıyı ikiliye dönüştürür.\r\nHEX2DEC\t\t\t= HEX2DEC\t\t\t##\tOnaltılı bir sayıyı ondalığa dönüştürür.\r\nHEX2OCT\t\t\t= HEX2OCT\t\t\t##\tOnaltılı bir sayıyı sekizliğe dönüştürür.\r\nIMABS\t\t\t= SANMUTLAK\t\t\t##\tKarmaşık bir sayının mutlak değerini (modül) verir.\r\nIMAGINARY\t\t= SANAL\t\t\t\t##\tKarmaşık bir sayının sanal katsayısını verir.\r\nIMARGUMENT\t\t= SANBAĞ_DEĞİŞKEN\t##\tRadyanlarla belirtilen bir açı olan teta bağımsız değişkenini verir.\r\nIMCONJUGATE\t\t= SANEŞLENEK\t\t##\tKarmaşık bir sayının karmaşık eşleniğini verir.\r\nIMCOS\t\t\t= SANCOS\t\t\t##\tKarmaşık bir sayının kosinüsünü verir.\r\nIMDIV\t\t\t= SANBÖL\t\t\t##\tİki karmaşık sayının bölümünü verir.\r\nIMEXP\t\t\t= SANÜS\t\t\t\t##\tKarmaşık bir sayının üssünü verir.\r\nIMLN\t\t\t= SANLN\t\t\t\t##\tKarmaşık bir sayının doğal logaritmasını verir.\r\nIMLOG10\t\t\t= SANLOG10\t\t\t##\tKarmaşık bir sayının, 10 tabanında logaritmasını verir.\r\nIMLOG2\t\t\t= SANLOG2\t\t\t##\tKarmaşık bir sayının 2 tabanında logaritmasını verir.\r\nIMPOWER\t\t\t= SANÜSSÜ\t\t\t##\tKarmaşık bir sayıyı, bir tamsayı üssüne yükseltilmiş olarak verir.\r\nIMPRODUCT\t\t= SANÇARP\t\t\t##\tKarmaşık sayıların çarpımını verir.\r\nIMREAL\t\t\t= SANGERÇEK\t\t\t##\tKarmaşık bir sayının, gerçek katsayısını verir.\r\nIMSIN\t\t\t= SANSIN\t\t\t##\tKarmaşık bir sayının sinüsünü verir.\r\nIMSQRT\t\t\t= SANKAREKÖK\t\t##\tKarmaşık bir sayının karekökünü verir.\r\nIMSUB\t\t\t= SANÇIKAR\t\t\t##\tİki karmaşık sayının farkını verir.\r\nIMSUM\t\t\t= SANTOPLA\t\t\t##\tKarmaşık sayıların toplamını verir.\r\nOCT2BIN\t\t\t= OCT2BIN\t\t\t##\tSekizli bir sayıyı ikiliye dönüştürür.\r\nOCT2DEC\t\t\t= OCT2DEC\t\t\t##\tSekizli bir sayıyı ondalığa dönüştürür.\r\nOCT2HEX\t\t\t= OCT2HEX\t\t\t##\tSekizli bir sayıyı onaltılıya dönüştürür.\r\n\r\n\r\n##\r\n##\tFinancial functions\t\t\t\tFinansal fonksiyonlar\r\n##\r\nACCRINT\t\t\t= GERÇEKFAİZ\t\t##\tDönemsel faiz ödeyen hisse senedine ilişkin tahakkuk eden faizi getirir.\r\nACCRINTM\t\t= GERÇEKFAİZV\t\t##\tVadesinde ödeme yapan bir tahvilin tahakkuk etmiş faizini verir.\r\nAMORDEGRC\t\t= AMORDEGRC\t\t\t##\tYıpranma katsayısı kullanarak her hesap döneminin değer kaybını verir.\r\nAMORLINC\t\t= AMORLINC\t\t\t##\tHer hesap dönemi içindeki yıpranmayı verir.\r\nCOUPDAYBS\t\t= KUPONGÜNBD\t\t##\tKupon süresinin başlangıcından alış tarihine kadar olan süredeki gün sayısını verir.\r\nCOUPDAYS\t\t= KUPONGÜN\t\t\t##\tKupon süresindeki, gün sayısını, alış tarihini de içermek üzere, verir.\r\nCOUPDAYSNC\t\t= KUPONGÜNDSK\t\t##\tAlış tarihinden bir sonraki kupon tarihine kadar olan gün sayısını verir.\r\nCOUPNCD\t\t\t= KUPONGÜNSKT\t\t##\tAlış tarihinden bir sonraki kupon tarihini verir.\r\nCOUPNUM\t\t\t= KUPONSAYI\t\t\t##\tAlış tarihiyle vade tarihi arasında ödenecek kuponların sayısını verir.\r\nCOUPPCD\t\t\t= KUPONGÜNÖKT\t\t##\tAlış tarihinden bir önceki kupon tarihini verir.\r\nCUMIPMT\t\t\t= AİÇVERİMORANI\t\t##\tİki dönem arasında ödenen kümülatif faizi verir.\r\nCUMPRINC\t\t= ANA_PARA_ÖDEMESİ\t##\tİki dönem arasında bir borç üzerine ödenen birikimli temeli verir.\r\nDB\t\t\t\t= AZALANBAKİYE\t\t##\tBir malın belirtilen bir süre içindeki yıpranmasını, sabit azalan bakiye yöntemini kullanarak verir.\r\nDDB\t\t\t\t= ÇİFTAZALANBAKİYE\t##\tBir malın belirtilen bir süre içindeki yıpranmasını, çift azalan bakiye yöntemi ya da sizin belirttiğiniz başka bir yöntemi kullanarak verir.\r\nDISC\t\t\t= İNDİRİM\t\t\t##\tBir tahvilin indirim oranını verir.\r\nDOLLARDE\t\t= LİRAON\t\t\t##\tKesir olarak tanımlanmış lira fiyatını, ondalık sayı olarak tanımlanmış lira fiyatına dönüştürür.\r\nDOLLARFR\t\t= LİRAKES\t\t\t##\tOndalık sayı olarak tanımlanmış lira fiyatını, kesir olarak tanımlanmış lira fiyatına dönüştürür.\r\nDURATION\t\t= SÜRE\t\t\t\t##\tBelli aralıklarla faiz ödemesi yapan bir tahvilin yıllık süresini verir.\r\nEFFECT\t\t\t= ETKİN\t\t\t\t##\tEfektif yıllık faiz oranını verir.\r\nFV\t\t\t\t= ANBD\t\t\t\t##\tBir yatırımın gelecekteki değerini verir.\r\nFVSCHEDULE\t\t= GDPROGRAM\t\t\t##\tBir seri birleşik faiz oranı uyguladıktan sonra, bir başlangıçtaki anaparanın gelecekteki değerini verir.\r\nINTRATE\t\t\t= FAİZORANI\t\t\t##\tTam olarak yatırım yapılmış bir tahvilin faiz oranını verir.\r\nIPMT\t\t\t= FAİZTUTARI\t\t##\tBir yatırımın verilen bir süre için faiz ödemesini verir.\r\nIRR\t\t\t\t= İÇ_VERİM_ORANI\t##\tBir para akışı serisi için, iç verim oranını verir.\r\nISPMT\t\t\t= ISPMT\t\t\t\t##\tYatırımın belirli bir dönemi boyunca ödenen faizi hesaplar.\r\nMDURATION\t\t= MSÜRE\t\t\t\t##\tVarsayılan par değeri 10.000.000 lira olan bir tahvil için Macauley değiştirilmiş süreyi verir.\r\nMIRR\t\t\t= D_İÇ_VERİM_ORANI\t##\tPozitif ve negatif para akışlarının farklı oranlarda finanse edildiği durumlarda, iç verim oranını verir.\r\nNOMINAL\t\t\t= NOMİNAL\t\t\t##\tYıllık nominal faiz oranını verir.\r\nNPER\t\t\t= DÖNEM_SAYISI\t\t##\tBir yatırımın dönem sayısını verir.\r\nNPV\t\t\t\t= NBD\t\t\t\t##\tBir yatırımın bugünkü net değerini, bir dönemsel para akışları serisine ve bir indirim oranına bağlı olarak verir.\r\nODDFPRICE\t\t= TEKYDEĞER\t\t\t##\tTek bir ilk dönemi olan bir tahvilin değerini, her 100.000.000 lirada bir verir.\r\nODDFYIELD\t\t= TEKYÖDEME\t\t\t##\tTek bir ilk dönemi olan bir tahvilin ödemesini verir.\r\nODDLPRICE\t\t= TEKSDEĞER\t\t\t##\tTek bir son dönemi olan bir tahvilin fiyatını her 10.000.000 lirada bir verir.\r\nODDLYIELD\t\t= TEKSÖDEME\t\t\t##\tTek bir son dönemi olan bir tahvilin ödemesini verir.\r\nPMT\t\t\t\t= DEVRESEL_ÖDEME\t##\tBir yıllık dönemsel ödemeyi verir.\r\nPPMT\t\t\t= ANA_PARA_ÖDEMESİ\t##\tVerilen bir süre için, bir yatırımın anaparasına dayanan ödemeyi verir.\r\nPRICE\t\t\t= DEĞER\t\t\t\t##\tDönemsel faiz ödeyen bir tahvilin fiyatını 10.000.00 liralık değer başına verir.\r\nPRICEDISC\t\t= DEĞERİND\t\t\t##\tİndirimli bir tahvilin fiyatını 10.000.000 liralık nominal değer başına verir.\r\nPRICEMAT\t\t= DEĞERVADE\t\t\t##\tFaizini vade sonunda ödeyen bir tahvilin fiyatını 10.000.000 nominal değer başına verir.\r\nPV\t\t\t\t= BD\t\t\t\t##\tBir yatırımın bugünkü değerini verir.\r\nRATE\t\t\t= FAİZ_ORANI\t\t##\tBir yıllık dönem başına düşen faiz oranını verir.\r\nRECEIVED\t\t= GETİRİ\t\t\t##\tTam olarak yatırılmış bir tahvilin vadesinin bitiminde alınan miktarı verir.\r\nSLN\t\t\t\t= DA\t\t\t\t##\tBir malın bir dönem içindeki doğrusal yıpranmasını verir.\r\nSYD\t\t\t\t= YAT\t\t\t\t##\tBir malın belirli bir dönem için olan amortismanını verir.\r\nTBILLEQ\t\t\t= HTAHEŞ\t\t\t##\tBir Hazine bonosunun bono eşdeğeri ödemesini verir.\r\nTBILLPRICE\t\t= HTAHDEĞER\t\t\t##\tBir Hazine bonosunun değerini, 10.000.000 liralık nominal değer başına verir.\r\nTBILLYIELD\t\t= HTAHÖDEME\t\t\t##\tBir Hazine bonosunun ödemesini verir.\r\nVDB\t\t\t\t= DAB\t\t\t\t##\tBir malın amortismanını, belirlenmiş ya da kısmi bir dönem için, bir azalan bakiye yöntemi kullanarak verir.\r\nXIRR\t\t\t= AİÇVERİMORANI\t\t##\tDönemsel olması gerekmeyen bir para akışları programı için, iç verim oranını verir.\r\nXNPV\t\t\t= ANBD\t\t\t\t##\tDönemsel olması gerekmeyen bir para akışları programı için, bugünkü net değeri verir.\r\nYIELD\t\t\t= ÖDEME\t\t\t\t##\tBelirli aralıklarla faiz ödeyen bir tahvilin ödemesini verir.\r\nYIELDDISC\t\t= ÖDEMEİND\t\t\t##\tİndirimli bir tahvilin yıllık ödemesini verir; örneğin, bir Hazine bonosunun.\r\nYIELDMAT\t\t= ÖDEMEVADE\t\t\t##\tVadesinin bitiminde faiz ödeyen bir tahvilin yıllık ödemesini verir.\r\n\r\n\r\n##\r\n##\tInformation functions\t\t\t\tBilgi fonksiyonları\r\n##\r\nCELL\t\t\t= HÜCRE\t\t\t##\tBir hücrenin biçimlendirmesi, konumu ya da içeriği hakkında bilgi verir.\r\nERROR.TYPE\t\t= HATA.TİPİ\t\t##\tBir hata türüne ilişkin sayıları verir.\r\nINFO\t\t\t= BİLGİ\t\t\t##\tGeçerli işletim ortamı hakkında bilgi verir.\r\nISBLANK\t\t\t= EBOŞSA\t\t##\tDeğer boşsa, DOĞRU verir.\r\nISERR\t\t\t= EHATA\t\t\t##\tDeğer, #YOK dışındaki bir hata değeriyse, DOĞRU verir.\r\nISERROR\t\t\t= EHATALIYSA\t##\tDeğer, herhangi bir hata değeriyse, DOĞRU verir.\r\nISEVEN\t\t\t= ÇİFTTİR\t\t##\tSayı çiftse, DOĞRU verir.\r\nISLOGICAL\t\t= EMANTIKSALSA\t##\tDeğer, mantıksal bir değerse, DOĞRU verir.\r\nISNA\t\t\t= EYOKSA\t\t##\tDeğer, #YOK hata değeriyse, DOĞRU verir.\r\nISNONTEXT\t\t= EMETİNDEĞİLSE\t##\tDeğer, metin değilse, DOĞRU verir.\r\nISNUMBER\t\t= ESAYIYSA\t\t##\tDeğer, bir sayıysa, DOĞRU verir.\r\nISODD\t\t\t= TEKTİR\t\t##\tSayı tekse, DOĞRU verir.\r\nISREF\t\t\t= EREFSE\t\t##\tDeğer bir başvuruysa, DOĞRU verir.\r\nISTEXT\t\t\t= EMETİNSE\t\t##\tDeğer bir metinse DOĞRU verir.\r\nN\t\t\t\t= N\t\t\t\t##\tSayıya dönüştürülmüş bir değer verir.\r\nNA\t\t\t\t= YOKSAY\t\t##\t#YOK hata değerini verir.\r\nTYPE\t\t\t= TİP\t\t\t##\tBir değerin veri türünü belirten bir sayı verir.\r\n\r\n\r\n##\r\n##\tLogical functions\t\t\t\tMantıksal fonksiyonlar\r\n##\r\nAND\t\t\t\t= VE\t\t\t##\tBütün bağımsız değişkenleri DOĞRU ise, DOĞRU verir.\r\nFALSE\t\t\t= YANLIŞ\t\t##\tYANLIŞ mantıksal değerini verir.\r\nIF\t\t\t\t= EĞER\t\t\t##\tGerçekleştirilecek bir mantıksal sınama belirtir.\r\nIFERROR\t\t\t= EĞERHATA\t\t##\tFormül hatalıysa belirttiğiniz değeri verir; bunun dışındaki durumlarda formülün sonucunu verir.\r\nNOT\t\t\t\t= DEĞİL\t\t\t##\tBağımsız değişkeninin mantığını tersine çevirir.\r\nOR\t\t\t\t= YADA\t\t\t##\tBağımsız değişkenlerden herhangi birisi DOĞRU ise, DOĞRU verir.\r\nTRUE\t\t\t= DOĞRU\t\t\t##\tDOĞRU mantıksal değerini verir.\r\n\r\n\r\n##\r\n##\tLookup and reference functions\t\t\tArama ve Başvuru fonksiyonları\r\n##\r\nADDRESS\t\t\t= ADRES\t\t\t\t##\tBir başvuruyu, çalışma sayfasındaki tek bir hücreye metin olarak verir.\r\nAREAS\t\t\t= ALANSAY\t\t\t##\tRenvoie le nombre de zones dans une référence.\r\nCHOOSE\t\t\t= ELEMAN\t\t\t##\tDeğerler listesinden bir değer seçer.\r\nCOLUMN\t\t\t= SÜTUN\t\t\t\t##\tBir başvurunun sütun sayısını verir.\r\nCOLUMNS\t\t\t= SÜTUNSAY\t\t\t##\tBir başvurudaki sütunların sayısını verir.\r\nHLOOKUP\t\t\t= YATAYARA\t\t\t##\tBir dizinin en üst satırına bakar ve belirtilen hücrenin değerini verir.\r\nHYPERLINK\t\t= KÖPRÜ\t\t\t\t##\tBir ağ sunucusunda, bir intranette ya da Internet'te depolanan bir belgeyi açan bir kısayol ya da atlama oluşturur.\r\nINDEX\t\t\t= İNDİS\t\t\t\t##\tBaşvurudan veya diziden bir değer seçmek için, bir dizin kullanır.\r\nINDIRECT\t\t= DOLAYLI\t\t\t##\tMetin değeriyle belirtilen bir başvuru verir.\r\nLOOKUP\t\t\t= ARA\t\t\t\t##\tBir vektördeki veya dizideki değerleri arar.\r\nMATCH\t\t\t= KAÇINCI\t\t\t##\tBir başvurudaki veya dizideki değerleri arar.\r\nOFFSET\t\t\t= KAYDIR\t\t\t##\tVerilen bir başvurudan, bir başvuru kaydırmayı verir.\r\nROW\t\t\t\t= SATIR\t\t\t\t##\tBir başvurunun satır sayısını verir.\r\nROWS\t\t\t= SATIRSAY\t\t\t##\tBir başvurudaki satırların sayısını verir.\r\nRTD\t\t\t\t= RTD\t\t\t\t##\tCOM otomasyonunu destekleyen programdan gerçek zaman verileri alır.\r\nTRANSPOSE\t\t= DEVRİK_DÖNÜŞÜM\t##\tBir dizinin devrik dönüşümünü verir.\r\nVLOOKUP\t\t\t= DÜŞEYARA\t\t\t##\tBir dizinin ilk sütununa bakar ve bir hücrenin değerini vermek için satır boyunca hareket eder.\r\n\r\n\r\n##\r\n##\tMath and trigonometry functions\t\t\tMatematik ve trigonometri fonksiyonları\r\n##\r\nABS\t\t\t\t= MUTLAK\t\t\t##\tBir sayının mutlak değerini verir.\r\nACOS\t\t\t= ACOS\t\t\t\t##\tBir sayının ark kosinüsünü verir.\r\nACOSH\t\t\t= ACOSH\t\t\t\t##\tBir sayının ters hiperbolik kosinüsünü verir.\r\nASIN\t\t\t= ASİN\t\t\t\t##\tBir sayının ark sinüsünü verir.\r\nASINH\t\t\t= ASİNH\t\t\t\t##\tBir sayının ters hiperbolik sinüsünü verir.\r\nATAN\t\t\t= ATAN\t\t\t\t##\tBir sayının ark tanjantını verir.\r\nATAN2\t\t\t= ATAN2\t\t\t\t##\tArk tanjantı, x- ve y- koordinatlarından verir.\r\nATANH\t\t\t= ATANH\t\t\t\t##\tBir sayının ters hiperbolik tanjantını verir.\r\nCEILING\t\t\t= TAVANAYUVARLA\t\t##\tBir sayıyı, en yakın tamsayıya ya da en yakın katına yuvarlar.\r\nCOMBIN\t\t\t= KOMBİNASYON\t\t##\tVerilen sayıda öğenin kombinasyon sayısını verir.\r\nCOS\t\t\t\t= COS\t\t\t\t##\tBir sayının kosinüsünü verir.\r\nCOSH\t\t\t= COSH\t\t\t\t##\tBir sayının hiperbolik kosinüsünü verir.\r\nDEGREES\t\t\t= DERECE\t\t\t##\tRadyanları dereceye dönüştürür.\r\nEVEN\t\t\t= ÇİFT\t\t\t\t##\tBir sayıyı, en yakın daha büyük çift tamsayıya yuvarlar.\r\nEXP\t\t\t\t= ÜS\t\t\t\t##\te'yi, verilen bir sayının üssüne yükseltilmiş olarak verir.\r\nFACT\t\t\t= ÇARPINIM\t\t\t##\tBir sayının faktörünü verir.\r\nFACTDOUBLE\t\t= ÇİFTFAKTÖR\t\t##\tBir sayının çift çarpınımını verir.\r\nFLOOR\t\t\t= TABANAYUVARLA\t\t##\tBir sayıyı, daha küçük sayıya, sıfıra yakınsayarak yuvarlar.\r\nGCD\t\t\t\t= OBEB\t\t\t\t##\tEn büyük ortak böleni verir.\r\nINT\t\t\t\t= TAMSAYI\t\t\t##\tBir sayıyı aşağıya doğru en yakın tamsayıya yuvarlar.\r\nLCM\t\t\t\t= OKEK\t\t\t\t##\tEn küçük ortak katı verir.\r\nLN\t\t\t\t= LN\t\t\t\t##\tBir sayının doğal logaritmasını verir.\r\nLOG\t\t\t\t= LOG\t\t\t\t##\tBir sayının, belirtilen bir tabandaki logaritmasını verir.\r\nLOG10\t\t\t= LOG10\t\t\t\t##\tBir sayının 10 tabanında logaritmasını verir.\r\nMDETERM\t\t\t= DETERMİNANT\t\t##\tBir dizinin dizey determinantını verir.\r\nMINVERSE\t\t= DİZEY_TERS\t\t##\tBir dizinin dizey tersini verir.\r\nMMULT\t\t\t= DÇARP\t\t\t\t##\tİki dizinin dizey çarpımını verir.\r\nMOD\t\t\t\t= MODÜLO\t\t\t##\tBölmeden kalanı verir.\r\nMROUND\t\t\t= KYUVARLA\t\t\t##\tİstenen kata yuvarlanmış bir sayı verir.\r\nMULTINOMIAL\t\t= ÇOKTERİMLİ\t\t##\tBir sayılar kümesinin çok terimlisini verir.\r\nODD\t\t\t\t= TEK\t\t\t\t##\tBir sayıyı en yakın daha büyük tek sayıya yuvarlar.\r\nPI\t\t\t\t= Pİ\t\t\t\t##\tPi değerini verir.\r\nPOWER\t\t\t= KUVVET\t\t\t##\tBir üsse yükseltilmiş sayının sonucunu verir.\r\nPRODUCT\t\t\t= ÇARPIM\t\t\t##\tBağımsız değişkenlerini çarpar.\r\nQUOTIENT\t\t= BÖLÜM\t\t\t\t##\tBir bölme işleminin tamsayı kısmını verir.\r\nRADIANS\t\t\t= RADYAN\t\t\t##\tDereceleri radyanlara dönüştürür.\r\nRAND\t\t\t= S_SAYI_ÜRET\t\t##\t0 ile 1 arasında rastgele bir sayı verir.\r\nRANDBETWEEN\t\t= RASTGELEARALIK\t##\tBelirttiğiniz sayılar arasında rastgele bir sayı verir.\r\nROMAN\t\t\t= ROMEN\t\t\t\t##\tBir normal rakamı, metin olarak, romen rakamına çevirir.\r\nROUND\t\t\t= YUVARLA\t\t\t##\tBir sayıyı, belirtilen basamak sayısına yuvarlar.\r\nROUNDDOWN\t\t= AŞAĞIYUVARLA\t\t##\tBir sayıyı, daha küçük sayıya, sıfıra yakınsayarak yuvarlar.\r\nROUNDUP\t\t\t= YUKARIYUVARLA\t\t##\tBir sayıyı daha büyük sayıya, sıfırdan ıraksayarak yuvarlar.\r\nSERIESSUM\t\t= SERİTOPLA\t\t\t##\tBir üs serisinin toplamını, formüle bağlı olarak verir.\r\nSIGN\t\t\t= İŞARET\t\t\t##\tBir sayının işaretini verir.\r\nSIN\t\t\t\t= SİN\t\t\t\t##\tVerilen bir açının sinüsünü verir.\r\nSINH\t\t\t= SİNH\t\t\t\t##\tBir sayının hiperbolik sinüsünü verir.\r\nSQRT\t\t\t= KAREKÖK\t\t\t##\tPozitif bir karekök verir.\r\nSQRTPI\t\t\t= KAREKÖKPİ\t\t\t##\t(* Pi sayısının) kare kökünü verir.\r\nSUBTOTAL\t\t= ALTTOPLAM\t\t\t##\tBir listedeki ya da veritabanındaki bir alt toplamı verir.\r\nSUM\t\t\t\t= TOPLA\t\t\t\t##\tBağımsız değişkenlerini toplar.\r\nSUMIF\t\t\t= ETOPLA\t\t\t##\tVerilen ölçütle belirlenen hücreleri toplar.\r\nSUMIFS\t\t\t= SUMIFS\t\t\t##\tBir aralıktaki, birden fazla ölçüte uyan hücreleri ekler.\r\nSUMPRODUCT\t\t= TOPLA.ÇARPIM\t\t##\tİlişkili dizi bileşenlerinin çarpımlarının toplamını verir.\r\nSUMSQ\t\t\t= TOPKARE\t\t\t##\tBağımsız değişkenlerin karelerinin toplamını verir.\r\nSUMX2MY2\t\t= TOPX2EY2\t\t\t##\tİki dizideki ilişkili değerlerin farkının toplamını verir.\r\nSUMX2PY2\t\t= TOPX2AY2\t\t\t##\tİki dizideki ilişkili değerlerin karelerinin toplamının toplamını verir.\r\nSUMXMY2\t\t\t= TOPXEY2\t\t\t##\tİki dizideki ilişkili değerlerin farklarının karelerinin toplamını verir.\r\nTAN\t\t\t\t= TAN\t\t\t\t##\tBir sayının tanjantını verir.\r\nTANH\t\t\t= TANH\t\t\t\t##\tBir sayının hiperbolik tanjantını verir.\r\nTRUNC\t\t\t= NSAT\t\t\t\t##\tBir sayının, tamsayı durumuna gelecek şekilde, fazlalıklarını atar.\r\n\r\n\r\n##\r\n##\tStatistical functions\t\t\t\tİstatistiksel fonksiyonlar\r\n##\r\nAVEDEV\t\t\t= ORTSAP\t\t\t##\tVeri noktalarının ortalamalarından mutlak sapmalarının ortalamasını verir.\r\nAVERAGE\t\t\t= ORTALAMA\t\t\t##\tBağımsız değişkenlerinin ortalamasını verir.\r\nAVERAGEA\t\t= ORTALAMAA\t\t\t##\tBağımsız değişkenlerinin, sayılar, metin ve mantıksal değerleri içermek üzere ortalamasını verir.\r\nAVERAGEIF\t\t= EĞERORTALAMA \t\t##\tVerili ölçütü karşılayan bir aralıktaki bütün hücrelerin ortalamasını (aritmetik ortalama) hesaplar.\r\nAVERAGEIFS\t\t= EĞERLERORTALAMA \t##\tBirden çok ölçüte uyan tüm hücrelerin ortalamasını (aritmetik ortalama) hesaplar.\r\nBETADIST\t\t= BETADAĞ\t\t\t##\tBeta birikimli dağılım fonksiyonunu verir.\r\nBETAINV\t\t\t= BETATERS\t\t\t##\tBelirli bir beta dağılımı için birikimli dağılım fonksiyonunun tersini verir.\r\nBINOMDIST\t\t= BİNOMDAĞ\t\t\t##\tTek terimli binom dağılımı olasılığını verir.\r\nCHIDIST\t\t\t= KİKAREDAĞ\t\t\t##\tKikare dağılımın tek kuyruklu olasılığını verir.\r\nCHIINV\t\t\t= KİKARETERS\t\t##\tKikare dağılımın kuyruklu olasılığının tersini verir.\r\nCHITEST\t\t\t= KİKARETEST\t\t##\tBağımsızlık sınamalarını verir.\r\nCONFIDENCE\t\t= GÜVENİRLİK\t\t##\tBir popülasyon ortalaması için güvenirlik aralığını verir.\r\nCORREL\t\t\t= KORELASYON\t\t##\tİki veri kümesi arasındaki bağlantı katsayısını verir.\r\nCOUNT\t\t\t= BAĞ_DEĞ_SAY\t\t##\tBağımsız değişkenler listesinde kaç tane sayı bulunduğunu sayar.\r\nCOUNTA\t\t\t= BAĞ_DEĞ_DOLU_SAY\t##\tBağımsız değişkenler listesinde kaç tane değer bulunduğunu sayar.\r\nCOUNTBLANK\t\t= BOŞLUKSAY \t\t##\tAralıktaki boş hücre sayısını hesaplar.\r\nCOUNTIF\t\t\t= EĞERSAY \t\t\t##\tVerilen ölçütlere uyan bir aralık içindeki hücreleri sayar.\r\nCOUNTIFS\t\t= ÇOKEĞERSAY \t\t##\tBirden çok ölçüte uyan bir aralık içindeki hücreleri sayar.\r\nCOVAR\t\t\t= KOVARYANS \t\t##\tEşleştirilmiş sapmaların ortalaması olan kovaryansı verir.\r\nCRITBINOM\t\t= KRİTİKBİNOM\t\t##\tBirikimli binom dağılımının bir ölçüt değerinden küçük veya ölçüt değerine eşit olduğu en küçük değeri verir.\r\nDEVSQ\t\t\t= SAPKARE\t\t\t##\tSapmaların karelerinin toplamını verir.\r\nEXPONDIST\t\t= ÜSTELDAĞ\t\t\t##\tÜstel dağılımı verir.\r\nFDIST\t\t\t= FDAĞ\t\t\t\t##\tF olasılık dağılımını verir.\r\nFINV\t\t\t= FTERS\t\t\t\t##\tF olasılık dağılımının tersini verir.\r\nFISHER\t\t\t= FISHER\t\t\t##\tFisher dönüşümünü verir.\r\nFISHERINV\t\t= FISHERTERS\t\t##\tFisher dönüşümünün tersini verir.\r\nFORECAST\t\t= TAHMİN\t\t\t##\tBir doğrusal eğilim boyunca bir değer verir.\r\nFREQUENCY\t\t= SIKLIK\t\t\t##\tBir sıklık dağılımını, dikey bir dizi olarak verir.\r\nFTEST\t\t\t= FTEST\t\t\t\t##\tBir F-test'in sonucunu verir.\r\nGAMMADIST\t\t= GAMADAĞ\t\t\t##\tGama dağılımını verir.\r\nGAMMAINV\t\t= GAMATERS\t\t\t##\tGama kümülatif dağılımının tersini verir.\r\nGAMMALN\t\t\t= GAMALN\t\t\t##\tGama fonksiyonunun (?(x)) doğal logaritmasını verir.\r\nGEOMEAN\t\t\t= GEOORT\t\t\t##\tGeometrik ortayı verir.\r\nGROWTH\t\t\t= BÜYÜME\t\t\t##\tÜstel bir eğilim boyunca değerler verir.\r\nHARMEAN\t\t\t= HARORT\t\t\t##\tHarmonik ortayı verir.\r\nHYPGEOMDIST\t\t= HİPERGEOMDAĞ\t\t##\tHipergeometrik dağılımı verir.\r\nINTERCEPT\t\t= KESMENOKTASI\t\t##\tDoğrusal çakıştırma çizgisinin kesişme noktasını verir.\r\nKURT\t\t\t= BASIKLIK\t\t\t##\tBir veri kümesinin basıklığını verir.\r\nLARGE\t\t\t= BÜYÜK\t\t\t\t##\tBir veri kümesinde k. en büyük değeri verir.\r\nLINEST\t\t\t= DOT\t\t\t\t##\tDoğrusal bir eğilimin parametrelerini verir.\r\nLOGEST\t\t\t= LOT\t\t\t\t##\tÜstel bir eğilimin parametrelerini verir.\r\nLOGINV\t\t\t= LOGTERS\t\t\t##\tBir lognormal dağılımının tersini verir.\r\nLOGNORMDIST\t\t= LOGNORMDAĞ\t\t##\tBirikimli lognormal dağılımını verir.\r\nMAX\t\t\t\t= MAK\t\t\t\t##\tBir bağımsız değişkenler listesindeki en büyük değeri verir.\r\nMAXA\t\t\t= MAKA\t\t\t\t##\tBir bağımsız değişkenler listesindeki, sayılar, metin ve mantıksal değerleri içermek üzere, en büyük değeri verir.\r\nMEDIAN\t\t\t= ORTANCA\t\t\t##\tBelirtilen sayıların orta değerini verir.\r\nMIN\t\t\t\t= MİN\t\t\t\t##\tBir bağımsız değişkenler listesindeki en küçük değeri verir.\r\nMINA\t\t\t= MİNA\t\t\t\t##\tBir bağımsız değişkenler listesindeki, sayılar, metin ve mantıksal değerleri de içermek üzere, en küçük değeri verir.\r\nMODE\t\t\t= ENÇOK_OLAN\t\t##\tBir veri kümesindeki en sık rastlanan değeri verir.\r\nNEGBINOMDIST\t= NEGBİNOMDAĞ\t\t##\tNegatif binom dağılımını verir.\r\nNORMDIST\t\t= NORMDAĞ\t\t\t##\tNormal birikimli dağılımı verir.\r\nNORMINV\t\t\t= NORMTERS\t\t\t##\tNormal kümülatif dağılımın tersini verir.\r\nNORMSDIST\t\t= NORMSDAĞ\t\t\t##\tStandart normal birikimli dağılımı verir.\r\nNORMSINV\t\t= NORMSTERS\t\t\t##\tStandart normal birikimli dağılımın tersini verir.\r\nPEARSON\t\t\t= PEARSON\t\t\t##\tPearson çarpım moment korelasyon katsayısını verir.\r\nPERCENTILE\t\t= YÜZDEBİRLİK\t\t##\tBir aralık içerisinde bulunan değerlerin k. frekans toplamını verir.\r\nPERCENTRANK\t\t= YÜZDERANK\t\t\t##\tBir veri kümesindeki bir değerin yüzde mertebesini verir.\r\nPERMUT\t\t\t= PERMÜTASYON\t\t##\tVerilen sayıda nesne için permütasyon sayısını verir.\r\nPOISSON\t\t\t= POISSON\t\t\t##\tPoisson dağılımını verir.\r\nPROB\t\t\t= OLASILIK\t\t\t##\tBir aralıktaki değerlerin iki sınır arasında olması olasılığını verir.\r\nQUARTILE\t\t= DÖRTTEBİRLİK\t\t##\tBir veri kümesinin dörtte birliğini verir.\r\nRANK\t\t\t= RANK\t\t\t\t##\tBir sayılar listesinde bir sayının mertebesini verir.\r\nRSQ\t\t\t\t= RKARE\t\t\t\t##\tPearson çarpım moment korelasyon katsayısının karesini verir.\r\nSKEW\t\t\t= ÇARPIKLIK\t\t\t##\tBir dağılımın çarpıklığını verir.\r\nSLOPE\t\t\t= EĞİM\t\t\t\t##\tDoğrusal çakışma çizgisinin eğimini verir.\r\nSMALL\t\t\t= KÜÇÜK\t\t\t\t##\tBir veri kümesinde k. en küçük değeri verir.\r\nSTANDARDIZE\t\t= STANDARTLAŞTIRMA\t##\tNormalleştirilmiş bir değer verir.\r\nSTDEV\t\t\t= STDSAPMA\t\t\t##\tBir örneğe dayanarak standart sapmayı tahmin eder.\r\nSTDEVA\t\t\t= STDSAPMAA\t\t\t##\tStandart sapmayı, sayılar, metin ve mantıksal değerleri içermek üzere, bir örneğe bağlı olarak tahmin eder.\r\nSTDEVP\t\t\t= STDSAPMAS\t\t\t##\tStandart sapmayı, tüm popülasyona bağlı olarak hesaplar.\r\nSTDEVPA\t\t\t= STDSAPMASA\t\t##\tStandart sapmayı, sayılar, metin ve mantıksal değerleri içermek üzere, tüm popülasyona bağlı olarak hesaplar.\r\nSTEYX\t\t\t= STHYX\t\t\t\t##\tRegresyondaki her x için tahmini y değerinin standart hatasını verir.\r\nTDIST\t\t\t= TDAĞ\t\t\t\t##\tT-dağılımını verir.\r\nTINV\t\t\t= TTERS\t\t\t\t##\tT-dağılımının tersini verir.\r\nTREND\t\t\t= EĞİLİM\t\t\t##\tDoğrusal bir eğilim boyunca değerler verir.\r\nTRIMMEAN\t\t= KIRPORTALAMA\t\t##\tBir veri kümesinin içinin ortalamasını verir.\r\nTTEST\t\t\t= TTEST\t\t\t\t##\tT-test'le ilişkilendirilmiş olasılığı verir.\r\nVAR\t\t\t\t= VAR\t\t\t\t##\tVaryansı, bir örneğe bağlı olarak tahmin eder.\r\nVARA\t\t\t= VARA\t\t\t\t##\tVaryansı, sayılar, metin ve mantıksal değerleri içermek üzere, bir örneğe bağlı olarak tahmin eder.\r\nVARP\t\t\t= VARS\t\t\t\t##\tVaryansı, tüm popülasyona dayanarak hesaplar.\r\nVARPA\t\t\t= VARSA\t\t\t\t##\tVaryansı, sayılar, metin ve mantıksal değerleri içermek üzere, tüm popülasyona bağlı olarak hesaplar.\r\nWEIBULL\t\t\t= WEIBULL\t\t\t##\tWeibull dağılımını hesaplar.\r\nZTEST\t\t\t= ZTEST\t\t\t\t##\tZ-testinin tek kuyruklu olasılık değerini hesaplar.\r\n\r\n\r\n##\r\n##\tText functions\t\t\t\t\tMetin fonksiyonları\r\n##\r\nASC\t\t\t\t= ASC \t\t\t\t##\tBir karakter dizesindeki çift enli (iki bayt) İngilizce harfleri veya katakanayı yarım enli (tek bayt) karakterlerle değiştirir.\r\nBAHTTEXT\t\t= BAHTTEXT \t\t\t##\tSayıyı, ß (baht) para birimi biçimini kullanarak metne dönüştürür.\r\nCHAR\t\t\t= DAMGA \t\t\t##\tKod sayısıyla belirtilen karakteri verir.\r\nCLEAN\t\t\t= TEMİZ\t\t\t\t##\tMetindeki bütün yazdırılamaz karakterleri kaldırır.\r\nCODE\t\t\t= KOD\t\t\t\t##\tBir metin dizesindeki ilk karakter için sayısal bir kod verir.\r\nCONCATENATE\t\t= BİRLEŞTİR\t\t\t##\tPek çok metin öğesini bir metin öğesi olarak birleştirir.\r\nDOLLAR\t\t\t= LİRA\t\t\t\t##\tBir sayıyı YTL (yeni Türk lirası) para birimi biçimini kullanarak metne dönüştürür.\r\nEXACT\t\t\t= ÖZDEŞ\t\t\t\t##\tİki metin değerinin özdeş olup olmadığını anlamak için, değerleri denetler.\r\nFIND\t\t\t= BUL\t\t\t\t##\tBir metin değerini, bir başkasının içinde bulur (büyük küçük harf duyarlıdır).\r\nFINDB\t\t\t= BULB\t\t\t\t##\tBir metin değerini, bir başkasının içinde bulur (büyük küçük harf duyarlıdır).\r\nFIXED\t\t\t= SAYIDÜZENLE\t\t##\tBir sayıyı, sabit sayıda ondalıkla, metin olarak biçimlendirir.\r\nJIS\t\t\t\t= JIS\t\t\t\t##\tBir karakter dizesindeki tek enli (tek bayt) İngilizce harfleri veya katakanayı çift enli (iki bayt) karakterlerle değiştirir.\r\nLEFT\t\t\t= SOL\t\t\t\t##\tBir metin değerinden en soldaki karakterleri verir.\r\nLEFTB\t\t\t= SOLB\t\t\t\t##\tBir metin değerinden en soldaki karakterleri verir.\r\nLEN\t\t\t\t= UZUNLUK\t\t\t##\tBir metin dizesindeki karakter sayısını verir.\r\nLENB\t\t\t= UZUNLUKB\t\t\t##\tBir metin dizesindeki karakter sayısını verir.\r\nLOWER\t\t\t= KÜÇÜKHARF\t\t\t##\tMetni küçük harfe çevirir.\r\nMID\t\t\t\t= ORTA\t\t\t\t##\tBir metin dizesinden belirli sayıda karakteri, belirttiğiniz konumdan başlamak üzere verir.\r\nMIDB\t\t\t= ORTAB\t\t\t\t##\tBir metin dizesinden belirli sayıda karakteri, belirttiğiniz konumdan başlamak üzere verir.\r\nPHONETIC\t\t= SES\t\t\t\t##\tMetin dizesinden ses (furigana) karakterlerini ayıklar.\r\nPROPER\t\t\t= YAZIM.DÜZENİ\t\t##\tBir metin değerinin her bir sözcüğünün ilk harfini büyük harfe çevirir.\r\nREPLACE\t\t\t= DEĞİŞTİR\t\t\t##\tMetnin içindeki karakterleri değiştirir.\r\nREPLACEB\t\t= DEĞİŞTİRB\t\t\t##\tMetnin içindeki karakterleri değiştirir.\r\nREPT\t\t\t= YİNELE\t\t\t##\tMetni belirtilen sayıda yineler.\r\nRIGHT\t\t\t= SAĞ\t\t\t\t##\tBir metin değerinden en sağdaki karakterleri verir.\r\nRIGHTB\t\t\t= SAĞB\t\t\t\t##\tBir metin değerinden en sağdaki karakterleri verir.\r\nSEARCH\t\t\t= BUL\t\t\t\t##\tBir metin değerini, bir başkasının içinde bulur (büyük küçük harf duyarlı değildir).\r\nSEARCHB\t\t\t= BULB\t\t\t\t##\tBir metin değerini, bir başkasının içinde bulur (büyük küçük harf duyarlı değildir).\r\nSUBSTITUTE\t\t= YERİNEKOY\t\t\t##\tBir metin dizesinde, eski metnin yerine yeni metin koyar.\r\nT\t\t\t\t= M\t\t\t\t\t##\tBağımsız değerlerini metne dönüştürür.\r\nTEXT\t\t\t= METNEÇEVİR\t\t##\tBir sayıyı biçimlendirir ve metne dönüştürür.\r\nTRIM\t\t\t= KIRP\t\t\t\t##\tMetindeki boşlukları kaldırır.\r\nUPPER\t\t\t= BÜYÜKHARF\t\t\t##\tMetni büyük harfe çevirir.\r\nVALUE\t\t\t= SAYIYAÇEVİR\t\t##\tBir metin bağımsız değişkenini sayıya dönüştürür.\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Classes/PHPExcel.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (c) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n\n/** PHPExcel root directory */\nif (!defined('PHPEXCEL_ROOT')) {\n    define('PHPEXCEL_ROOT', dirname(__FILE__) . '/');\n    require(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n}\n\n\n/**\n * PHPExcel\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n */\nclass PHPExcel\n{\n    /**\n     * Unique ID\n     *\n     * @var string\n     */\n    private $_uniqueID;\n\n    /**\n     * Document properties\n     *\n     * @var PHPExcel_DocumentProperties\n     */\n    private $_properties;\n\n    /**\n     * Document security\n     *\n     * @var PHPExcel_DocumentSecurity\n     */\n    private $_security;\n\n    /**\n     * Collection of Worksheet objects\n     *\n     * @var PHPExcel_Worksheet[]\n     */\n    private $_workSheetCollection = array();\n\n    /**\n\t * Calculation Engine\n\t *\n\t * @var PHPExcel_Calculation\n\t */\n\tprivate $_calculationEngine = NULL;\n\n    /**\n     * Active sheet index\n     *\n     * @var int\n     */\n    private $_activeSheetIndex = 0;\n\n    /**\n     * Named ranges\n     *\n     * @var PHPExcel_NamedRange[]\n     */\n    private $_namedRanges = array();\n\n    /**\n     * CellXf supervisor\n     *\n     * @var PHPExcel_Style\n     */\n    private $_cellXfSupervisor;\n\n    /**\n     * CellXf collection\n     *\n     * @var PHPExcel_Style[]\n     */\n    private $_cellXfCollection = array();\n\n    /**\n     * CellStyleXf collection\n     *\n     * @var PHPExcel_Style[]\n     */\n    private $_cellStyleXfCollection = array();\n\n\t/**\n\t* _hasMacros : this workbook have macros ?\n\t*\n\t* @var bool\n\t*/\n\tprivate $_hasMacros = FALSE;\n\n\t/**\n\t* _macrosCode : all macros code (the vbaProject.bin file, this include form, code,  etc.), NULL if no macro\n\t*\n\t* @var binary\n\t*/\n\tprivate $_macrosCode=NULL;\n\t/**\n\t* _macrosCertificate : if macros are signed, contains vbaProjectSignature.bin file, NULL if not signed\n\t*\n\t* @var binary\n\t*/\n\tprivate $_macrosCertificate=NULL;\n\n\t/**\n\t* _ribbonXMLData : NULL if workbook is'nt Excel 2007 or not contain a customized UI\n\t*\n\t* @var NULL|string\n\t*/\n\tprivate $_ribbonXMLData=NULL;\n\n\t/**\n\t* _ribbonBinObjects : NULL if workbook is'nt Excel 2007 or not contain embedded objects (picture(s)) for Ribbon Elements\n\t* ignored if $_ribbonXMLData is null\n\t*\n\t* @var NULL|array\n\t*/\n\tprivate $_ribbonBinObjects=NULL;\n\n\t/**\n\t* The workbook has macros ?\n\t*\n\t* @return true if workbook has macros, false if not\n\t*/\n\tpublic function hasMacros(){\n\t\treturn $this->_hasMacros;\n\t}\n\n\t/**\n\t* Define if a workbook has macros\n\t*\n\t* @param true|false\n\t*/\n\tpublic function setHasMacros($hasMacros=false){\n\t\t$this->_hasMacros=(bool)$hasMacros;\n\t}\n\n\t/**\n\t* Set the macros code\n\t*\n\t* @param binary string|null\n\t*/\n\tpublic function setMacrosCode($MacrosCode){\n\t\t$this->_macrosCode=$MacrosCode;\n\t\t$this->setHasMacros(!is_null($MacrosCode));\n\t}\n\n\t/**\n\t* Return the macros code\n\t*\n\t* @return binary|null\n\t*/\n\tpublic function getMacrosCode(){\n\t\treturn $this->_macrosCode;\n\t}\n\n\t/**\n\t* Set the macros certificate\n\t*\n\t* @param binary|null\n\t*/\n\tpublic function setMacrosCertificate($Certificate=NULL){\n\t\t$this->_macrosCertificate=$Certificate;\n\t}\n\n\t/**\n\t* Is the project signed ?\n\t*\n\t* @return true|false\n\t*/\n\tpublic function hasMacrosCertificate(){\n\t\treturn !is_null($this->_macrosCertificate);\n\t}\n\n\t/**\n\t* Return the macros certificate\n\t*\n\t* @return binary|null\n\t*/\n\tpublic function getMacrosCertificate(){\n\t\treturn $this->_macrosCertificate;\n\t}\n\n\t/**\n\t* Remove all macros, certificate from spreadsheet\n\t*\n\t* @param none\n\t* @return void\n\t*/\n\tpublic function discardMacros(){\n\t\t$this->_hasMacros=false;\n\t\t$this->_macrosCode=NULL;\n\t\t$this->_macrosCertificate=NULL;\n\t}\n\n\t/**\n\t* set ribbon XML data\n\t*\n\t*/\n\tpublic function setRibbonXMLData($Target=NULL, $XMLData=NULL){\n\t\tif(!is_null($Target) && !is_null($XMLData)){\n\t\t\t$this->_ribbonXMLData=array('target'=>$Target, 'data'=>$XMLData);\n\t\t}else{\n\t\t\t$this->_ribbonXMLData=NULL;\n\t\t}\n\t}\n\n\t/**\n\t* retrieve ribbon XML Data\n\t*\n\t* return string|null|array\n\t*/\n\tpublic function getRibbonXMLData($What='all'){//we need some constants here...\n\t\t$ReturnData=NULL;\n\t\t$What=strtolower($What);\n\t\tswitch($What){\n\t\tcase 'all':\n\t\t\t$ReturnData=$this->_ribbonXMLData;\n\t\t\tbreak;\n\t\tcase 'target':\n\t\tcase 'data':\n\t\t\tif(is_array($this->_ribbonXMLData) && array_key_exists($What,$this->_ribbonXMLData)){\n\t\t\t\t$ReturnData=$this->_ribbonXMLData[$What];\n\t\t\t}//else $ReturnData stay at null\n\t\t\tbreak;\n\t\t}//default: $ReturnData at null\n\t\treturn $ReturnData;\n\t}\n\n\t/**\n\t* store binaries ribbon objects (pictures)\n\t*\n\t*/\n\tpublic function setRibbonBinObjects($BinObjectsNames=NULL, $BinObjectsData=NULL){\n\t\tif(!is_null($BinObjectsNames) && !is_null($BinObjectsData)){\n\t\t\t$this->_ribbonBinObjects=array('names'=>$BinObjectsNames, 'data'=>$BinObjectsData);\n\t\t}else{\n\t\t\t$this->_ribbonBinObjects=NULL;\n\t\t}\n\t}\n\t/**\n\t* return the extension of a filename. Internal use for a array_map callback (php<5.3 don't like lambda function)\n\t*\n\t*/\n\tprivate function _getExtensionOnly($ThePath){\n\t\treturn pathinfo($ThePath, PATHINFO_EXTENSION);\n\t}\n\n\t/**\n\t* retrieve Binaries Ribbon Objects\n\t*\n\t*/\n\tpublic function getRibbonBinObjects($What='all'){\n\t\t$ReturnData=NULL;\n\t\t$What=strtolower($What);\n\t\tswitch($What){\n\t\tcase 'all':\n\t\t\treturn $this->_ribbonBinObjects;\n\t\t\tbreak;\n\t\tcase 'names':\n\t\tcase 'data':\n\t\t\tif(is_array($this->_ribbonBinObjects) && array_key_exists($What, $this->_ribbonBinObjects)){\n\t\t\t\t$ReturnData=$this->_ribbonBinObjects[$What];\n\t\t\t}\n\t\t\tbreak;\n\t\tcase 'types':\n\t\t\tif(is_array($this->_ribbonBinObjects) && array_key_exists('data', $this->_ribbonBinObjects) && is_array($this->_ribbonBinObjects['data'])){\n\t\t\t\t$tmpTypes=array_keys($this->_ribbonBinObjects['data']);\n\t\t\t\t$ReturnData=array_unique(array_map(array($this,'_getExtensionOnly'), $tmpTypes));\n\t\t\t}else\n\t\t\t\t$ReturnData=array();//the caller want an array... not null if empty\n\t\t\tbreak;\n\t\t}\n\t\treturn $ReturnData;\n\t}\n\n\t/**\n\t* This workbook have a custom UI ?\n\t*\n\t* @return true|false\n\t*/\n\tpublic function hasRibbon(){\n\t\treturn !is_null($this->_ribbonXMLData);\n\t}\n\n\t/**\n\t* This workbook have additionnal object for the ribbon ?\n\t*\n\t* @return true|false\n\t*/\n\tpublic function hasRibbonBinObjects(){\n\t\treturn !is_null($this->_ribbonBinObjects);\n\t}\n\n\t/**\n     * Check if a sheet with a specified code name already exists\n     *\n     * @param string $pSheetCodeName  Name of the worksheet to check\n     * @return boolean\n     */\n    public function sheetCodeNameExists($pSheetCodeName)\n    {\n\t\treturn ($this->getSheetByCodeName($pSheetCodeName) !== NULL);\n    }\n\n\t/**\n\t * Get sheet by code name. Warning : sheet don't have always a code name !\n\t *\n\t * @param string $pName Sheet name\n\t * @return PHPExcel_Worksheet\n\t */\n\tpublic function getSheetByCodeName($pName = '')\n\t{\n\t\t$worksheetCount = count($this->_workSheetCollection);\n\t\tfor ($i = 0; $i < $worksheetCount; ++$i) {\n\t\t\tif ($this->_workSheetCollection[$i]->getCodeName() == $pName) {\n\t\t\t\treturn $this->_workSheetCollection[$i];\n\t\t\t}\n\t\t}\n\n\t\treturn null;\n\t}\n\n\t /**\n\t * Create a new PHPExcel with one Worksheet\n\t */\n\tpublic function __construct()\n\t{\n\t\t$this->_uniqueID = uniqid();\n\t\t$this->_calculationEngine\t= PHPExcel_Calculation::getInstance($this);\n\n\t\t// Initialise worksheet collection and add one worksheet\n\t\t$this->_workSheetCollection = array();\n\t\t$this->_workSheetCollection[] = new PHPExcel_Worksheet($this);\n\t\t$this->_activeSheetIndex = 0;\n\n        // Create document properties\n        $this->_properties = new PHPExcel_DocumentProperties();\n\n        // Create document security\n        $this->_security = new PHPExcel_DocumentSecurity();\n\n        // Set named ranges\n        $this->_namedRanges = array();\n\n        // Create the cellXf supervisor\n        $this->_cellXfSupervisor = new PHPExcel_Style(true);\n        $this->_cellXfSupervisor->bindParent($this);\n\n        // Create the default style\n        $this->addCellXf(new PHPExcel_Style);\n        $this->addCellStyleXf(new PHPExcel_Style);\n    }\n\n    /**\n     * Code to execute when this worksheet is unset()\n     *\n     */\n    public function __destruct() {\n        PHPExcel_Calculation::unsetInstance($this);\n        $this->disconnectWorksheets();\n    }    //    function __destruct()\n\n    /**\n     * Disconnect all worksheets from this PHPExcel workbook object,\n     *    typically so that the PHPExcel object can be unset\n     *\n     */\n    public function disconnectWorksheets()\n    {\n    \t$worksheet = NULL;\n        foreach($this->_workSheetCollection as $k => &$worksheet) {\n            $worksheet->disconnectCells();\n            $this->_workSheetCollection[$k] = null;\n        }\n        unset($worksheet);\n        $this->_workSheetCollection = array();\n    }\n\n\t/**\n\t * Return the calculation engine for this worksheet\n\t *\n\t * @return PHPExcel_Calculation\n\t */\n\tpublic function getCalculationEngine()\n\t{\n\t\treturn $this->_calculationEngine;\n\t}\t//\tfunction getCellCacheController()\n\n    /**\n     * Get properties\n     *\n     * @return PHPExcel_DocumentProperties\n     */\n    public function getProperties()\n    {\n        return $this->_properties;\n    }\n\n    /**\n     * Set properties\n     *\n     * @param PHPExcel_DocumentProperties    $pValue\n     */\n    public function setProperties(PHPExcel_DocumentProperties $pValue)\n    {\n        $this->_properties = $pValue;\n    }\n\n    /**\n     * Get security\n     *\n     * @return PHPExcel_DocumentSecurity\n     */\n    public function getSecurity()\n    {\n        return $this->_security;\n    }\n\n    /**\n     * Set security\n     *\n     * @param PHPExcel_DocumentSecurity    $pValue\n     */\n    public function setSecurity(PHPExcel_DocumentSecurity $pValue)\n    {\n        $this->_security = $pValue;\n    }\n\n    /**\n     * Get active sheet\n     *\n     * @return PHPExcel_Worksheet\n     *\n     * @throws PHPExcel_Exception\n     */\n    public function getActiveSheet()\n    {\n        return $this->getSheet($this->_activeSheetIndex);\n    }\n\n    /**\n     * Create sheet and add it to this workbook\n     *\n     * @param  int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)\n     * @return PHPExcel_Worksheet\n     * @throws PHPExcel_Exception\n     */\n    public function createSheet($iSheetIndex = NULL)\n    {\n        $newSheet = new PHPExcel_Worksheet($this);\n        $this->addSheet($newSheet, $iSheetIndex);\n        return $newSheet;\n    }\n\n    /**\n     * Check if a sheet with a specified name already exists\n     *\n     * @param  string $pSheetName  Name of the worksheet to check\n     * @return boolean\n     */\n    public function sheetNameExists($pSheetName)\n    {\n        return ($this->getSheetByName($pSheetName) !== NULL);\n    }\n\n    /**\n     * Add sheet\n     *\n     * @param  PHPExcel_Worksheet $pSheet\n     * @param  int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)\n     * @return PHPExcel_Worksheet\n     * @throws PHPExcel_Exception\n     */\n    public function addSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = NULL)\n    {\n        if ($this->sheetNameExists($pSheet->getTitle())) {\n            throw new PHPExcel_Exception(\n            \t\"Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename this worksheet first.\"\n            );\n        }\n\n        if($iSheetIndex === NULL) {\n            if ($this->_activeSheetIndex < 0) {\n                $this->_activeSheetIndex = 0;\n            }\n            $this->_workSheetCollection[] = $pSheet;\n        } else {\n            // Insert the sheet at the requested index\n            array_splice(\n                $this->_workSheetCollection,\n                $iSheetIndex,\n                0,\n                array($pSheet)\n                );\n\n            // Adjust active sheet index if necessary\n            if ($this->_activeSheetIndex >= $iSheetIndex) {\n                ++$this->_activeSheetIndex;\n            }\n        }\n\n        if ($pSheet->getParent() === null) {\n            $pSheet->rebindParent($this);\n        }\n\n        return $pSheet;\n    }\n\n    /**\n     * Remove sheet by index\n     *\n     * @param  int $pIndex Active sheet index\n     * @throws PHPExcel_Exception\n     */\n    public function removeSheetByIndex($pIndex = 0)\n    {\n\n        $numSheets = count($this->_workSheetCollection);\n\n        if ($pIndex > $numSheets - 1) {\n            throw new PHPExcel_Exception(\n            \t\"You tried to remove a sheet by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}.\"\n            );\n        } else {\n            array_splice($this->_workSheetCollection, $pIndex, 1);\n        }\n        // Adjust active sheet index if necessary\n        if (($this->_activeSheetIndex >= $pIndex) &&\n            ($pIndex > count($this->_workSheetCollection) - 1)) {\n            --$this->_activeSheetIndex;\n        }\n\n    }\n\n    /**\n     * Get sheet by index\n     *\n     * @param  int $pIndex Sheet index\n     * @return PHPExcel_Worksheet\n     * @throws PHPExcel_Exception\n     */\n    public function getSheet($pIndex = 0)\n    {\n        if (!isset($this->_workSheetCollection[$pIndex])) {\n            $numSheets = $this->getSheetCount();\n            throw new PHPExcel_Exception(\n                \"Your requested sheet index: {$pIndex} is out of bounds. The actual number of sheets is {$numSheets}.\"\n            );\n        }\n\n        return $this->_workSheetCollection[$pIndex];\n    }\n\n    /**\n     * Get all sheets\n     *\n     * @return PHPExcel_Worksheet[]\n     */\n    public function getAllSheets()\n    {\n        return $this->_workSheetCollection;\n    }\n\n    /**\n     * Get sheet by name\n     *\n     * @param  string $pName Sheet name\n     * @return PHPExcel_Worksheet\n     */\n    public function getSheetByName($pName = '')\n    {\n        $worksheetCount = count($this->_workSheetCollection);\n        for ($i = 0; $i < $worksheetCount; ++$i) {\n            if ($this->_workSheetCollection[$i]->getTitle() === $pName) {\n                return $this->_workSheetCollection[$i];\n            }\n        }\n\n        return NULL;\n    }\n\n    /**\n     * Get index for sheet\n     *\n     * @param  PHPExcel_Worksheet $pSheet\n     * @return Sheet index\n     * @throws PHPExcel_Exception\n     */\n    public function getIndex(PHPExcel_Worksheet $pSheet)\n    {\n        foreach ($this->_workSheetCollection as $key => $value) {\n            if ($value->getHashCode() == $pSheet->getHashCode()) {\n                return $key;\n            }\n        }\n\n        throw new PHPExcel_Exception(\"Sheet does not exist.\");\n    }\n\n    /**\n     * Set index for sheet by sheet name.\n     *\n     * @param  string $sheetName Sheet name to modify index for\n     * @param  int $newIndex New index for the sheet\n     * @return New sheet index\n     * @throws PHPExcel_Exception\n     */\n    public function setIndexByName($sheetName, $newIndex)\n    {\n        $oldIndex = $this->getIndex($this->getSheetByName($sheetName));\n        $pSheet = array_splice(\n            $this->_workSheetCollection,\n            $oldIndex,\n            1\n        );\n        array_splice(\n            $this->_workSheetCollection,\n            $newIndex,\n            0,\n            $pSheet\n        );\n        return $newIndex;\n    }\n\n    /**\n     * Get sheet count\n     *\n     * @return int\n     */\n    public function getSheetCount()\n    {\n        return count($this->_workSheetCollection);\n    }\n\n    /**\n     * Get active sheet index\n     *\n     * @return int Active sheet index\n     */\n    public function getActiveSheetIndex()\n    {\n        return $this->_activeSheetIndex;\n    }\n\n    /**\n     * Set active sheet index\n     *\n     * @param  int $pIndex Active sheet index\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function setActiveSheetIndex($pIndex = 0)\n    {\n        $numSheets = count($this->_workSheetCollection);\n\n        if ($pIndex > $numSheets - 1) {\n            throw new PHPExcel_Exception(\n            \t\"You tried to set a sheet active by the out of bounds index: {$pIndex}. The actual number of sheets is {$numSheets}.\"\n            );\n        } else {\n            $this->_activeSheetIndex = $pIndex;\n        }\n        return $this->getActiveSheet();\n    }\n\n    /**\n     * Set active sheet index by name\n     *\n     * @param  string $pValue Sheet title\n     * @return PHPExcel_Worksheet\n     * @throws PHPExcel_Exception\n     */\n    public function setActiveSheetIndexByName($pValue = '')\n    {\n        if (($worksheet = $this->getSheetByName($pValue)) instanceof PHPExcel_Worksheet) {\n            $this->setActiveSheetIndex($this->getIndex($worksheet));\n            return $worksheet;\n        }\n\n        throw new PHPExcel_Exception('Workbook does not contain sheet:' . $pValue);\n    }\n\n    /**\n     * Get sheet names\n     *\n     * @return string[]\n     */\n    public function getSheetNames()\n    {\n        $returnValue = array();\n        $worksheetCount = $this->getSheetCount();\n        for ($i = 0; $i < $worksheetCount; ++$i) {\n            $returnValue[] = $this->getSheet($i)->getTitle();\n        }\n\n        return $returnValue;\n    }\n\n    /**\n     * Add external sheet\n     *\n     * @param  PHPExcel_Worksheet $pSheet External sheet to add\n     * @param  int|null $iSheetIndex Index where sheet should go (0,1,..., or null for last)\n     * @throws PHPExcel_Exception\n     * @return PHPExcel_Worksheet\n     */\n    public function addExternalSheet(PHPExcel_Worksheet $pSheet, $iSheetIndex = null) {\n        if ($this->sheetNameExists($pSheet->getTitle())) {\n            throw new PHPExcel_Exception(\"Workbook already contains a worksheet named '{$pSheet->getTitle()}'. Rename the external sheet first.\");\n        }\n\n        // count how many cellXfs there are in this workbook currently, we will need this below\n        $countCellXfs = count($this->_cellXfCollection);\n\n        // copy all the shared cellXfs from the external workbook and append them to the current\n        foreach ($pSheet->getParent()->getCellXfCollection() as $cellXf) {\n            $this->addCellXf(clone $cellXf);\n        }\n\n        // move sheet to this workbook\n        $pSheet->rebindParent($this);\n\n        // update the cellXfs\n        foreach ($pSheet->getCellCollection(false) as $cellID) {\n            $cell = $pSheet->getCell($cellID);\n            $cell->setXfIndex( $cell->getXfIndex() + $countCellXfs );\n        }\n\n        return $this->addSheet($pSheet, $iSheetIndex);\n    }\n\n    /**\n     * Get named ranges\n     *\n     * @return PHPExcel_NamedRange[]\n     */\n    public function getNamedRanges() {\n        return $this->_namedRanges;\n    }\n\n    /**\n     * Add named range\n     *\n     * @param  PHPExcel_NamedRange $namedRange\n     * @return PHPExcel\n     */\n    public function addNamedRange(PHPExcel_NamedRange $namedRange) {\n        if ($namedRange->getScope() == null) {\n            // global scope\n            $this->_namedRanges[$namedRange->getName()] = $namedRange;\n        } else {\n            // local scope\n            $this->_namedRanges[$namedRange->getScope()->getTitle().'!'.$namedRange->getName()] = $namedRange;\n        }\n        return true;\n    }\n\n    /**\n     * Get named range\n     *\n     * @param  string $namedRange\n     * @param  PHPExcel_Worksheet|null $pSheet Scope. Use null for global scope\n     * @return PHPExcel_NamedRange|null\n     */\n    public function getNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) {\n        $returnValue = null;\n\n        if ($namedRange != '' && ($namedRange !== NULL)) {\n            // first look for global defined name\n            if (isset($this->_namedRanges[$namedRange])) {\n                $returnValue = $this->_namedRanges[$namedRange];\n            }\n\n            // then look for local defined name (has priority over global defined name if both names exist)\n            if (($pSheet !== NULL) && isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {\n                $returnValue = $this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange];\n            }\n        }\n\n        return $returnValue;\n    }\n\n    /**\n     * Remove named range\n     *\n     * @param  string  $namedRange\n     * @param  PHPExcel_Worksheet|null  $pSheet  Scope: use null for global scope.\n     * @return PHPExcel\n     */\n    public function removeNamedRange($namedRange, PHPExcel_Worksheet $pSheet = null) {\n        if ($pSheet === NULL) {\n            if (isset($this->_namedRanges[$namedRange])) {\n                unset($this->_namedRanges[$namedRange]);\n            }\n        } else {\n            if (isset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange])) {\n                unset($this->_namedRanges[$pSheet->getTitle() . '!' . $namedRange]);\n            }\n        }\n        return $this;\n    }\n\n    /**\n     * Get worksheet iterator\n     *\n     * @return PHPExcel_WorksheetIterator\n     */\n    public function getWorksheetIterator() {\n        return new PHPExcel_WorksheetIterator($this);\n    }\n\n    /**\n     * Copy workbook (!= clone!)\n     *\n     * @return PHPExcel\n     */\n    public function copy() {\n        $copied = clone $this;\n\n        $worksheetCount = count($this->_workSheetCollection);\n        for ($i = 0; $i < $worksheetCount; ++$i) {\n            $this->_workSheetCollection[$i] = $this->_workSheetCollection[$i]->copy();\n            $this->_workSheetCollection[$i]->rebindParent($this);\n        }\n\n        return $copied;\n    }\n\n    /**\n     * Implement PHP __clone to create a deep clone, not just a shallow copy.\n     */\n    public function __clone() {\n        foreach($this as $key => $val) {\n            if (is_object($val) || (is_array($val))) {\n                $this->{$key} = unserialize(serialize($val));\n            }\n        }\n    }\n\n    /**\n     * Get the workbook collection of cellXfs\n     *\n     * @return PHPExcel_Style[]\n     */\n    public function getCellXfCollection()\n    {\n        return $this->_cellXfCollection;\n    }\n\n    /**\n     * Get cellXf by index\n     *\n     * @param  int $pIndex\n     * @return PHPExcel_Style\n     */\n    public function getCellXfByIndex($pIndex = 0)\n    {\n        return $this->_cellXfCollection[$pIndex];\n    }\n\n    /**\n     * Get cellXf by hash code\n     *\n     * @param  string $pValue\n     * @return PHPExcel_Style|false\n     */\n    public function getCellXfByHashCode($pValue = '')\n    {\n        foreach ($this->_cellXfCollection as $cellXf) {\n            if ($cellXf->getHashCode() == $pValue) {\n                return $cellXf;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Check if style exists in style collection\n     *\n     * @param  PHPExcel_Style $pCellStyle\n     * @return boolean\n     */\n    public function cellXfExists($pCellStyle = null)\n    {\n        return in_array($pCellStyle, $this->_cellXfCollection, true);\n    }\n\n    /**\n     * Get default style\n     *\n     * @return PHPExcel_Style\n     * @throws PHPExcel_Exception\n     */\n    public function getDefaultStyle()\n    {\n        if (isset($this->_cellXfCollection[0])) {\n            return $this->_cellXfCollection[0];\n        }\n        throw new PHPExcel_Exception('No default style found for this workbook');\n    }\n\n    /**\n     * Add a cellXf to the workbook\n     *\n     * @param PHPExcel_Style $style\n     */\n    public function addCellXf(PHPExcel_Style $style)\n    {\n        $this->_cellXfCollection[] = $style;\n        $style->setIndex(count($this->_cellXfCollection) - 1);\n    }\n\n    /**\n     * Remove cellXf by index. It is ensured that all cells get their xf index updated.\n     *\n     * @param  int $pIndex Index to cellXf\n     * @throws PHPExcel_Exception\n     */\n    public function removeCellXfByIndex($pIndex = 0)\n    {\n        if ($pIndex > count($this->_cellXfCollection) - 1) {\n            throw new PHPExcel_Exception(\"CellXf index is out of bounds.\");\n        } else {\n            // first remove the cellXf\n            array_splice($this->_cellXfCollection, $pIndex, 1);\n\n            // then update cellXf indexes for cells\n            foreach ($this->_workSheetCollection as $worksheet) {\n                foreach ($worksheet->getCellCollection(false) as $cellID) {\n                    $cell = $worksheet->getCell($cellID);\n                    $xfIndex = $cell->getXfIndex();\n                    if ($xfIndex > $pIndex ) {\n                        // decrease xf index by 1\n                        $cell->setXfIndex($xfIndex - 1);\n                    } else if ($xfIndex == $pIndex) {\n                        // set to default xf index 0\n                        $cell->setXfIndex(0);\n                    }\n                }\n            }\n        }\n    }\n\n    /**\n     * Get the cellXf supervisor\n     *\n     * @return PHPExcel_Style\n     */\n    public function getCellXfSupervisor()\n    {\n        return $this->_cellXfSupervisor;\n    }\n\n    /**\n     * Get the workbook collection of cellStyleXfs\n     *\n     * @return PHPExcel_Style[]\n     */\n    public function getCellStyleXfCollection()\n    {\n        return $this->_cellStyleXfCollection;\n    }\n\n    /**\n     * Get cellStyleXf by index\n     *\n     * @param  int $pIndex\n     * @return PHPExcel_Style\n     */\n    public function getCellStyleXfByIndex($pIndex = 0)\n    {\n        return $this->_cellStyleXfCollection[$pIndex];\n    }\n\n    /**\n     * Get cellStyleXf by hash code\n     *\n     * @param  string $pValue\n     * @return PHPExcel_Style|false\n     */\n    public function getCellStyleXfByHashCode($pValue = '')\n    {\n        foreach ($this->_cellStyleXfCollection as $cellStyleXf) {\n            if ($cellStyleXf->getHashCode() == $pValue) {\n                return $cellStyleXf;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * Add a cellStyleXf to the workbook\n     *\n     * @param PHPExcel_Style $pStyle\n     */\n    public function addCellStyleXf(PHPExcel_Style $pStyle)\n    {\n        $this->_cellStyleXfCollection[] = $pStyle;\n        $pStyle->setIndex(count($this->_cellStyleXfCollection) - 1);\n    }\n\n    /**\n     * Remove cellStyleXf by index\n     *\n     * @param int $pIndex\n     * @throws PHPExcel_Exception\n     */\n    public function removeCellStyleXfByIndex($pIndex = 0)\n    {\n        if ($pIndex > count($this->_cellStyleXfCollection) - 1) {\n            throw new PHPExcel_Exception(\"CellStyleXf index is out of bounds.\");\n        } else {\n            array_splice($this->_cellStyleXfCollection, $pIndex, 1);\n        }\n    }\n\n    /**\n     * Eliminate all unneeded cellXf and afterwards update the xfIndex for all cells\n     * and columns in the workbook\n     */\n    public function garbageCollect()\n    {\n        // how many references are there to each cellXf ?\n        $countReferencesCellXf = array();\n        foreach ($this->_cellXfCollection as $index => $cellXf) {\n            $countReferencesCellXf[$index] = 0;\n        }\n\n        foreach ($this->getWorksheetIterator() as $sheet) {\n\n            // from cells\n            foreach ($sheet->getCellCollection(false) as $cellID) {\n                $cell = $sheet->getCell($cellID);\n                ++$countReferencesCellXf[$cell->getXfIndex()];\n            }\n\n            // from row dimensions\n            foreach ($sheet->getRowDimensions() as $rowDimension) {\n                if ($rowDimension->getXfIndex() !== null) {\n                    ++$countReferencesCellXf[$rowDimension->getXfIndex()];\n                }\n            }\n\n            // from column dimensions\n            foreach ($sheet->getColumnDimensions() as $columnDimension) {\n                ++$countReferencesCellXf[$columnDimension->getXfIndex()];\n            }\n        }\n\n        // remove cellXfs without references and create mapping so we can update xfIndex\n        // for all cells and columns\n        $countNeededCellXfs = 0;\n        foreach ($this->_cellXfCollection as $index => $cellXf) {\n            if ($countReferencesCellXf[$index] > 0 || $index == 0) { // we must never remove the first cellXf\n                ++$countNeededCellXfs;\n            } else {\n                unset($this->_cellXfCollection[$index]);\n            }\n            $map[$index] = $countNeededCellXfs - 1;\n        }\n        $this->_cellXfCollection = array_values($this->_cellXfCollection);\n\n        // update the index for all cellXfs\n        foreach ($this->_cellXfCollection as $i => $cellXf) {\n            $cellXf->setIndex($i);\n        }\n\n        // make sure there is always at least one cellXf (there should be)\n        if (empty($this->_cellXfCollection)) {\n            $this->_cellXfCollection[] = new PHPExcel_Style();\n        }\n\n        // update the xfIndex for all cells, row dimensions, column dimensions\n        foreach ($this->getWorksheetIterator() as $sheet) {\n\n            // for all cells\n            foreach ($sheet->getCellCollection(false) as $cellID) {\n                $cell = $sheet->getCell($cellID);\n                $cell->setXfIndex( $map[$cell->getXfIndex()] );\n            }\n\n            // for all row dimensions\n            foreach ($sheet->getRowDimensions() as $rowDimension) {\n                if ($rowDimension->getXfIndex() !== null) {\n                    $rowDimension->setXfIndex( $map[$rowDimension->getXfIndex()] );\n                }\n            }\n\n            // for all column dimensions\n            foreach ($sheet->getColumnDimensions() as $columnDimension) {\n                $columnDimension->setXfIndex( $map[$columnDimension->getXfIndex()] );\n            }\n\n\t\t\t// also do garbage collection for all the sheets\n            $sheet->garbageCollect();\n        }\n    }\n\n    /**\n     * Return the unique ID value assigned to this spreadsheet workbook\n     *\n     * @return string\n     */\n    public function getID() {\n        return $this->_uniqueID;\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/.gitignore",
    "content": "\n*.xls\n*.xlsx"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/01pharSimple.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** Include PHPExcel */\nrequire_once '../Build/PHPExcel.phar';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"PHPExcel Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"PHPExcel Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for PHPExcel, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office PHPExcel php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A1', 'Hello')\n            ->setCellValue('B2', 'world!')\n            ->setCellValue('C1', 'Hello')\n            ->setCellValue('D2', 'world!');\n\n// Miscellaneous glyphs, UTF-8\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A4', 'Miscellaneous glyphs')\n            ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Simple');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Save Excel5 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/01simple-download-ods.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\nif (PHP_SAPI == 'cli')\n\tdie('This example should only be run from a Web Browser');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A1', 'Hello')\n            ->setCellValue('B2', 'world!')\n            ->setCellValue('C1', 'Hello')\n            ->setCellValue('D2', 'world!');\n\n// Miscellaneous glyphs, UTF-8\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A4', 'Miscellaneous glyphs')\n            ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');\n\n// Rename worksheet\n$objPHPExcel->getActiveSheet()->setTitle('Simple');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Redirect output to a client’s web browser (OpenDocument)\nheader('Content-Type: application/vnd.oasis.opendocument.spreadsheet');\nheader('Content-Disposition: attachment;filename=\"01simple.ods\"');\nheader('Cache-Control: max-age=0');\n// If you're serving to IE 9, then the following may be needed\nheader('Cache-Control: max-age=1');\n\n// If you're serving to IE over SSL, then the following may be needed\nheader ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past\nheader ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified\nheader ('Cache-Control: cache, must-revalidate'); // HTTP/1.1\nheader ('Pragma: public'); // HTTP/1.0\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'OpenDocument');\n$objWriter->save('php://output');\nexit;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/01simple-download-pdf.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\nif (PHP_SAPI == 'cli')\n\tdie('This example should only be run from a Web Browser');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n//\tChange these values to select the Rendering library that you wish to use\n//\t\tand its directory location on your server\n//$rendererName = PHPExcel_Settings::PDF_RENDERER_TCPDF;\n$rendererName = PHPExcel_Settings::PDF_RENDERER_MPDF;\n//$rendererName = PHPExcel_Settings::PDF_RENDERER_DOMPDF;\n//$rendererLibrary = 'tcPDF5.9';\n$rendererLibrary = 'mPDF5.4';\n//$rendererLibrary = 'domPDF0.6.0beta3';\n$rendererLibraryPath = dirname(__FILE__).'/../../../libraries/PDF/' . $rendererLibrary;\n\n\n// Create new PHPExcel object\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"PDF Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"PDF Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for PDF, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"pdf php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A1', 'Hello')\n            ->setCellValue('B2', 'world!')\n            ->setCellValue('C1', 'Hello')\n            ->setCellValue('D2', 'world!');\n\n// Miscellaneous glyphs, UTF-8\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A4', 'Miscellaneous glyphs')\n            ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');\n\n// Rename worksheet\n$objPHPExcel->getActiveSheet()->setTitle('Simple');\n$objPHPExcel->getActiveSheet()->setShowGridLines(false);\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\nif (!PHPExcel_Settings::setPdfRenderer(\n\t\t$rendererName,\n\t\t$rendererLibraryPath\n\t)) {\n\tdie(\n\t\t'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .\n\t\t'<br />' .\n\t\t'at the top of this script as appropriate for your directory structure'\n\t);\n}\n\n\n// Redirect output to a client’s web browser (PDF)\nheader('Content-Type: application/pdf');\nheader('Content-Disposition: attachment;filename=\"01simple.pdf\"');\nheader('Cache-Control: max-age=0');\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF');\n$objWriter->save('php://output');\nexit;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/01simple-download-xls.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\nif (PHP_SAPI == 'cli')\n\tdie('This example should only be run from a Web Browser');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A1', 'Hello')\n            ->setCellValue('B2', 'world!')\n            ->setCellValue('C1', 'Hello')\n            ->setCellValue('D2', 'world!');\n\n// Miscellaneous glyphs, UTF-8\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A4', 'Miscellaneous glyphs')\n            ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');\n\n// Rename worksheet\n$objPHPExcel->getActiveSheet()->setTitle('Simple');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Redirect output to a client’s web browser (Excel5)\nheader('Content-Type: application/vnd.ms-excel');\nheader('Content-Disposition: attachment;filename=\"01simple.xls\"');\nheader('Cache-Control: max-age=0');\n// If you're serving to IE 9, then the following may be needed\nheader('Cache-Control: max-age=1');\n\n// If you're serving to IE over SSL, then the following may be needed\nheader ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past\nheader ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified\nheader ('Cache-Control: cache, must-revalidate'); // HTTP/1.1\nheader ('Pragma: public'); // HTTP/1.0\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save('php://output');\nexit;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/01simple-download-xlsx.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\nif (PHP_SAPI == 'cli')\n\tdie('This example should only be run from a Web Browser');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A1', 'Hello')\n            ->setCellValue('B2', 'world!')\n            ->setCellValue('C1', 'Hello')\n            ->setCellValue('D2', 'world!');\n\n// Miscellaneous glyphs, UTF-8\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A4', 'Miscellaneous glyphs')\n            ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');\n\n// Rename worksheet\n$objPHPExcel->getActiveSheet()->setTitle('Simple');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Redirect output to a client’s web browser (Excel2007)\nheader('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');\nheader('Content-Disposition: attachment;filename=\"01simple.xlsx\"');\nheader('Cache-Control: max-age=0');\n// If you're serving to IE 9, then the following may be needed\nheader('Cache-Control: max-age=1');\n\n// If you're serving to IE over SSL, then the following may be needed\nheader ('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past\nheader ('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT'); // always modified\nheader ('Cache-Control: cache, must-revalidate'); // HTTP/1.1\nheader ('Pragma: public'); // HTTP/1.0\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save('php://output');\nexit;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/01simple.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"PHPExcel Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"PHPExcel Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for PHPExcel, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office PHPExcel php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A1', 'Hello')\n            ->setCellValue('B2', 'world!')\n            ->setCellValue('C1', 'Hello')\n            ->setCellValue('D2', 'world!');\n\n// Miscellaneous glyphs, UTF-8\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A4', 'Miscellaneous glyphs')\n            ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');\n\n\n$objPHPExcel->getActiveSheet()->setCellValue('A8',\"Hello\\nWorld\");\n$objPHPExcel->getActiveSheet()->getRowDimension(8)->setRowHeight(-1);\n$objPHPExcel->getActiveSheet()->getStyle('A8')->getAlignment()->setWrapText(true);\n\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Simple');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/01simplePCLZip.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"PHPExcel Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"PHPExcel Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for PHPExcel, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office PHPExcel php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A1', 'Hello')\n            ->setCellValue('B2', 'world!')\n            ->setCellValue('C1', 'Hello')\n            ->setCellValue('D2', 'world!');\n\n// Miscellaneous glyphs, UTF-8\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A4', 'Miscellaneous glyphs')\n            ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');\n\n\n$objPHPExcel->getActiveSheet()->setCellValue('A8',\"Hello\\nWorld\");\n$objPHPExcel->getActiveSheet()->getRowDimension(8)->setRowHeight(-1);\n$objPHPExcel->getActiveSheet()->getStyle('A8')->getAlignment()->setWrapText(true);\n\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Simple');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n// Use PCLZip rather than ZipArchive to create the Excel2007 OfficeOpenXML file\nPHPExcel_Settings::setZipClass(PHPExcel_Settings::PCLZIP);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/02types-xls.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE); \nini_set('display_startup_errors', TRUE); \ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n// Set default font\necho date('H:i:s') , \" Set default font\" , EOL;\n$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial')\n                                          ->setSize(10);\n\n// Add some data, resembling some different data types\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'String')\n                              ->setCellValue('B1', 'Simple')\n                              ->setCellValue('C1', 'PHPExcel');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A2', 'String')\n                              ->setCellValue('B2', 'Symbols')\n                              ->setCellValue('C2', '!+&=()~§±æþ');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A3', 'String')\n                              ->setCellValue('B3', 'UTF-8')\n                              ->setCellValue('C3', 'Создать MS Excel Книги из PHP скриптов');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Number')\n                              ->setCellValue('B4', 'Integer')\n                              ->setCellValue('C4', 12);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Number')\n                              ->setCellValue('B5', 'Float')\n                              ->setCellValue('C5', 34.56);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Number')\n                              ->setCellValue('B6', 'Negative')\n                              ->setCellValue('C6', -7.89);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Boolean')\n                              ->setCellValue('B7', 'True')\n                              ->setCellValue('C7', true);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Boolean')\n                              ->setCellValue('B8', 'False')\n                              ->setCellValue('C8', false);\n\n$dateTimeNow = time();\n$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Date/Time')\n                              ->setCellValue('B9', 'Date')\n                              ->setCellValue('C9', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow ));\n$objPHPExcel->getActiveSheet()->getStyle('C9')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Date/Time')\n                              ->setCellValue('B10', 'Time')\n                              ->setCellValue('C10', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow ));\n$objPHPExcel->getActiveSheet()->getStyle('C10')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A11', 'Date/Time')\n                              ->setCellValue('B11', 'Date and Time')\n                              ->setCellValue('C11', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow ));\n$objPHPExcel->getActiveSheet()->getStyle('C11')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A12', 'NULL')\n                              ->setCellValue('C12', NULL);\n\n$objRichText = new PHPExcel_RichText();\n$objRichText->createText('你好 ');\n$objPayable = $objRichText->createTextRun('你 好 吗？');\n$objPayable->getFont()->setBold(true);\n$objPayable->getFont()->setItalic(true);\n$objPayable->getFont()->setColor( new PHPExcel_Style_Color( PHPExcel_Style_Color::COLOR_DARKGREEN ) );\n\n$objRichText->createText(', unless specified otherwise on the invoice.');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A13', 'Rich Text')\n                              ->setCellValue('C13', $objRichText);\n\n\n$objRichText2 = new PHPExcel_RichText();\n$objRichText2->createText(\"black text\\n\");\n\n$objRed = $objRichText2->createTextRun(\"red text\");\n$objRed->getFont()->setColor( new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_RED  ) );\n\n$objPHPExcel->getActiveSheet()->getCell(\"C14\")->setValue($objRichText2);\n$objPHPExcel->getActiveSheet()->getStyle(\"C14\")->getAlignment()->setWrapText(true);\n\n\n$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);\n$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true);\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Datatypes');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\necho date('H:i:s') , \" Reload workbook from saved file\" , EOL;\n$callStartTime = microtime(true);\n\n$objPHPExcel = PHPExcel_IOFactory::load(str_replace('.php', '.xls', __FILE__));\n\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\necho 'Call time to reload Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\nvar_dump($objPHPExcel->getActiveSheet()->toArray());\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done testing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/02types.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE); \nini_set('display_startup_errors', TRUE); \ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n// Set default font\necho date('H:i:s') , \" Set default font\" , EOL;\n$objPHPExcel->getDefaultStyle()->getFont()->setName('Arial')\n                                          ->setSize(10);\n\n// Add some data, resembling some different data types\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'String')\n                              ->setCellValue('B1', 'Simple')\n                              ->setCellValue('C1', 'PHPExcel');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A2', 'String')\n                              ->setCellValue('B2', 'Symbols')\n                              ->setCellValue('C2', '!+&=()~§±æþ');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A3', 'String')\n                              ->setCellValue('B3', 'UTF-8')\n                              ->setCellValue('C3', 'Создать MS Excel Книги из PHP скриптов');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Number')\n                              ->setCellValue('B4', 'Integer')\n                              ->setCellValue('C4', 12);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Number')\n                              ->setCellValue('B5', 'Float')\n                              ->setCellValue('C5', 34.56);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Number')\n                              ->setCellValue('B6', 'Negative')\n                              ->setCellValue('C6', -7.89);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Boolean')\n                              ->setCellValue('B7', 'True')\n                              ->setCellValue('C7', true);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Boolean')\n                              ->setCellValue('B8', 'False')\n                              ->setCellValue('C8', false);\n\n$dateTimeNow = time();\n$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Date/Time')\n                              ->setCellValue('B9', 'Date')\n                              ->setCellValue('C9', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow ));\n$objPHPExcel->getActiveSheet()->getStyle('C9')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Date/Time')\n                              ->setCellValue('B10', 'Time')\n                              ->setCellValue('C10', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow ));\n$objPHPExcel->getActiveSheet()->getStyle('C10')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_TIME4);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A11', 'Date/Time')\n                              ->setCellValue('B11', 'Date and Time')\n                              ->setCellValue('C11', PHPExcel_Shared_Date::PHPToExcel( $dateTimeNow ));\n$objPHPExcel->getActiveSheet()->getStyle('C11')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_DATETIME);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A12', 'NULL')\n                              ->setCellValue('C12', NULL);\n\n$objRichText = new PHPExcel_RichText();\n$objRichText->createText('你好 ');\n\n$objPayable = $objRichText->createTextRun('你 好 吗？');\n$objPayable->getFont()->setBold(true);\n$objPayable->getFont()->setItalic(true);\n$objPayable->getFont()->setColor( new PHPExcel_Style_Color( PHPExcel_Style_Color::COLOR_DARKGREEN ) );\n\n$objRichText->createText(', unless specified otherwise on the invoice.');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A13', 'Rich Text')\n                              ->setCellValue('C13', $objRichText);\n\n\n$objRichText2 = new PHPExcel_RichText();\n$objRichText2->createText(\"black text\\n\");\n\n$objRed = $objRichText2->createTextRun(\"red text\");\n$objRed->getFont()->setColor( new PHPExcel_Style_Color(PHPExcel_Style_Color::COLOR_RED  ) );\n\n$objPHPExcel->getActiveSheet()->getCell(\"C14\")->setValue($objRichText2);\n$objPHPExcel->getActiveSheet()->getStyle(\"C14\")->getAlignment()->setWrapText(true);\n\n\n$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);\n$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setAutoSize(true);\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Datatypes');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\necho date('H:i:s') , \" Reload workbook from saved file\" , EOL;\n$callStartTime = microtime(true);\n\n$objPHPExcel = PHPExcel_IOFactory::load(str_replace('.php', '.xlsx', __FILE__));\n\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\necho 'Call time to reload Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\nvar_dump($objPHPExcel->getActiveSheet()->toArray());\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done testing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/03formulas.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data, we will use some formulas here\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Sum:');\n\n$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Range #1')\n                              ->setCellValue('B2', 3)\n                              ->setCellValue('B3', 7)\n                              ->setCellValue('B4', 13)\n                              ->setCellValue('B5', '=SUM(B2:B4)');\necho date('H:i:s') , \" Sum of Range #1 is \" ,\n                     $objPHPExcel->getActiveSheet()->getCell('B5')->getCalculatedValue() , EOL;\n\n$objPHPExcel->getActiveSheet()->setCellValue('C1', 'Range #2')\n                              ->setCellValue('C2', 5)\n                              ->setCellValue('C3', 11)\n                              ->setCellValue('C4', 17)\n                              ->setCellValue('C5', '=SUM(C2:C4)');\necho date('H:i:s') , \" Sum of Range #2 is \" ,\n                     $objPHPExcel->getActiveSheet()->getCell('C5')->getCalculatedValue() , EOL;\n\n$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Total of both ranges:');\n$objPHPExcel->getActiveSheet()->setCellValue('B7', '=SUM(B5:C5)');\necho date('H:i:s') , \" Sum of both Ranges is \" ,\n                     $objPHPExcel->getActiveSheet()->getCell('B7')->getCalculatedValue() , EOL;\n\n$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Minimum of both ranges:');\n$objPHPExcel->getActiveSheet()->setCellValue('B8', '=MIN(B2:C4)');\necho date('H:i:s') , \" Minimum value in either Range is \" ,\n                     $objPHPExcel->getActiveSheet()->getCell('B8')->getCalculatedValue() , EOL;\n\n$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Maximum of both ranges:');\n$objPHPExcel->getActiveSheet()->setCellValue('B9', '=MAX(B2:C4)');\necho date('H:i:s') , \" Maximum value in either Range is \" ,\n                     $objPHPExcel->getActiveSheet()->getCell('B9')->getCalculatedValue() , EOL;\n\n$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Average of both ranges:');\n$objPHPExcel->getActiveSheet()->setCellValue('B10', '=AVERAGE(B2:C4)');\necho date('H:i:s') , \" Average value of both Ranges is \" ,\n                     $objPHPExcel->getActiveSheet()->getCell('B10')->getCalculatedValue() , EOL;\n\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Formulas');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n\n//\n//  If we set Pre Calculated Formulas to true then PHPExcel will calculate all formulae in the\n//    workbook before saving. This adds time and memory overhead, and can cause some problems with formulae\n//    using functions or features (such as array formulae) that aren't yet supported by the calculation engine\n//  If the value is false (the default) for the Excel2007 Writer, then MS Excel (or the application used to\n//    open the file) will need to recalculate values itself to guarantee that the correct results are available.\n//\n//$objWriter->setPreCalculateFormulas(true);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/04printing.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data, we will use printing features\necho date('H:i:s') , \" Add some data\" , EOL;\nfor ($i = 1; $i < 200; $i++) {\n\t$objPHPExcel->getActiveSheet()->setCellValue('A' . $i, $i);\n\t$objPHPExcel->getActiveSheet()->setCellValue('B' . $i, 'Test value');\n}\n\n// Set header and footer. When no different headers for odd/even are used, odd header is assumed.\necho date('H:i:s') , \" Set header/footer\" , EOL;\n$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddHeader('&L&G&C&HPlease treat this document as confidential!');\n$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddFooter('&L&B' . $objPHPExcel->getProperties()->getTitle() . '&RPage &P of &N');\n\n// Add a drawing to the header\necho date('H:i:s') , \" Add a drawing to the header\" , EOL;\n$objDrawing = new PHPExcel_Worksheet_HeaderFooterDrawing();\n$objDrawing->setName('PHPExcel logo');\n$objDrawing->setPath('./images/phpexcel_logo.gif');\n$objDrawing->setHeight(36);\n$objPHPExcel->getActiveSheet()->getHeaderFooter()->addImage($objDrawing, PHPExcel_Worksheet_HeaderFooter::IMAGE_HEADER_LEFT);\n\n// Set page orientation and size\necho date('H:i:s') , \" Set page orientation and size\" , EOL;\n$objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE);\n$objPHPExcel->getActiveSheet()->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Printing');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/05featuredemo.inc.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Create a first sheet, representing sales data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Invoice');\n$objPHPExcel->getActiveSheet()->setCellValue('D1', PHPExcel_Shared_Date::PHPToExcel( gmmktime(0,0,0,date('m'),date('d'),date('Y')) ));\n$objPHPExcel->getActiveSheet()->getStyle('D1')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_XLSX15);\n$objPHPExcel->getActiveSheet()->setCellValue('E1', '#12566');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A3', 'Product Id');\n$objPHPExcel->getActiveSheet()->setCellValue('B3', 'Description');\n$objPHPExcel->getActiveSheet()->setCellValue('C3', 'Price');\n$objPHPExcel->getActiveSheet()->setCellValue('D3', 'Amount');\n$objPHPExcel->getActiveSheet()->setCellValue('E3', 'Total');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A4', '1001');\n$objPHPExcel->getActiveSheet()->setCellValue('B4', 'PHP for dummies');\n$objPHPExcel->getActiveSheet()->setCellValue('C4', '20');\n$objPHPExcel->getActiveSheet()->setCellValue('D4', '1');\n$objPHPExcel->getActiveSheet()->setCellValue('E4', '=IF(D4<>\"\",C4*D4,\"\")');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A5', '1012');\n$objPHPExcel->getActiveSheet()->setCellValue('B5', 'OpenXML for dummies');\n$objPHPExcel->getActiveSheet()->setCellValue('C5', '22');\n$objPHPExcel->getActiveSheet()->setCellValue('D5', '2');\n$objPHPExcel->getActiveSheet()->setCellValue('E5', '=IF(D5<>\"\",C5*D5,\"\")');\n\n$objPHPExcel->getActiveSheet()->setCellValue('E6', '=IF(D6<>\"\",C6*D6,\"\")');\n$objPHPExcel->getActiveSheet()->setCellValue('E7', '=IF(D7<>\"\",C7*D7,\"\")');\n$objPHPExcel->getActiveSheet()->setCellValue('E8', '=IF(D8<>\"\",C8*D8,\"\")');\n$objPHPExcel->getActiveSheet()->setCellValue('E9', '=IF(D9<>\"\",C9*D9,\"\")');\n\n$objPHPExcel->getActiveSheet()->setCellValue('D11', 'Total excl.:');\n$objPHPExcel->getActiveSheet()->setCellValue('E11', '=SUM(E4:E9)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('D12', 'VAT:');\n$objPHPExcel->getActiveSheet()->setCellValue('E12', '=E11*0.21');\n\n$objPHPExcel->getActiveSheet()->setCellValue('D13', 'Total incl.:');\n$objPHPExcel->getActiveSheet()->setCellValue('E13', '=E11+E12');\n\n// Add comment\necho date('H:i:s') , \" Add comments\" , EOL;\n\n$objPHPExcel->getActiveSheet()->getComment('E11')->setAuthor('PHPExcel');\n$objCommentRichText = $objPHPExcel->getActiveSheet()->getComment('E11')->getText()->createTextRun('PHPExcel:');\n$objCommentRichText->getFont()->setBold(true);\n$objPHPExcel->getActiveSheet()->getComment('E11')->getText()->createTextRun(\"\\r\\n\");\n$objPHPExcel->getActiveSheet()->getComment('E11')->getText()->createTextRun('Total amount on the current invoice, excluding VAT.');\n\n$objPHPExcel->getActiveSheet()->getComment('E12')->setAuthor('PHPExcel');\n$objCommentRichText = $objPHPExcel->getActiveSheet()->getComment('E12')->getText()->createTextRun('PHPExcel:');\n$objCommentRichText->getFont()->setBold(true);\n$objPHPExcel->getActiveSheet()->getComment('E12')->getText()->createTextRun(\"\\r\\n\");\n$objPHPExcel->getActiveSheet()->getComment('E12')->getText()->createTextRun('Total amount of VAT on the current invoice.');\n\n$objPHPExcel->getActiveSheet()->getComment('E13')->setAuthor('PHPExcel');\n$objCommentRichText = $objPHPExcel->getActiveSheet()->getComment('E13')->getText()->createTextRun('PHPExcel:');\n$objCommentRichText->getFont()->setBold(true);\n$objPHPExcel->getActiveSheet()->getComment('E13')->getText()->createTextRun(\"\\r\\n\");\n$objPHPExcel->getActiveSheet()->getComment('E13')->getText()->createTextRun('Total amount on the current invoice, including VAT.');\n$objPHPExcel->getActiveSheet()->getComment('E13')->setWidth('100pt');\n$objPHPExcel->getActiveSheet()->getComment('E13')->setHeight('100pt');\n$objPHPExcel->getActiveSheet()->getComment('E13')->setMarginLeft('150pt');\n$objPHPExcel->getActiveSheet()->getComment('E13')->getFillColor()->setRGB('EEEEEE');\n\n\n// Add rich-text string\necho date('H:i:s') , \" Add rich-text string\" , EOL;\n$objRichText = new PHPExcel_RichText();\n$objRichText->createText('This invoice is ');\n\n$objPayable = $objRichText->createTextRun('payable within thirty days after the end of the month');\n$objPayable->getFont()->setBold(true);\n$objPayable->getFont()->setItalic(true);\n$objPayable->getFont()->setColor( new PHPExcel_Style_Color( PHPExcel_Style_Color::COLOR_DARKGREEN ) );\n\n$objRichText->createText(', unless specified otherwise on the invoice.');\n\n$objPHPExcel->getActiveSheet()->getCell('A18')->setValue($objRichText);\n\n// Merge cells\necho date('H:i:s') , \" Merge cells\" , EOL;\n$objPHPExcel->getActiveSheet()->mergeCells('A18:E22');\n$objPHPExcel->getActiveSheet()->mergeCells('A28:B28');\t\t// Just to test...\n$objPHPExcel->getActiveSheet()->unmergeCells('A28:B28');\t// Just to test...\n\n// Protect cells\necho date('H:i:s') , \" Protect cells\" , EOL;\n$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true);\t// Needs to be set to true in order to enable any worksheet protection!\n$objPHPExcel->getActiveSheet()->protectCells('A3:E13', 'PHPExcel');\n\n// Set cell number formats\necho date('H:i:s') , \" Set cell number formats\" , EOL;\n$objPHPExcel->getActiveSheet()->getStyle('E4:E13')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE);\n\n// Set column widths\necho date('H:i:s') , \" Set column widths\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setAutoSize(true);\n$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(12);\n$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setWidth(12);\n\n// Set fonts\necho date('H:i:s') , \" Set fonts\" , EOL;\n$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setName('Candara');\n$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setSize(20);\n$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setBold(true);\n$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);\n$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_WHITE);\n\n$objPHPExcel->getActiveSheet()->getStyle('D1')->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_WHITE);\n$objPHPExcel->getActiveSheet()->getStyle('E1')->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_WHITE);\n\n$objPHPExcel->getActiveSheet()->getStyle('D13')->getFont()->setBold(true);\n$objPHPExcel->getActiveSheet()->getStyle('E13')->getFont()->setBold(true);\n\n// Set alignments\necho date('H:i:s') , \" Set alignments\" , EOL;\n$objPHPExcel->getActiveSheet()->getStyle('D11')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);\n$objPHPExcel->getActiveSheet()->getStyle('D12')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);\n$objPHPExcel->getActiveSheet()->getStyle('D13')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);\n\n$objPHPExcel->getActiveSheet()->getStyle('A18')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_JUSTIFY);\n$objPHPExcel->getActiveSheet()->getStyle('A18')->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER);\n\n$objPHPExcel->getActiveSheet()->getStyle('B5')->getAlignment()->setShrinkToFit(true);\n\n// Set thin black border outline around column\necho date('H:i:s') , \" Set thin black border outline around column\" , EOL;\n$styleThinBlackBorderOutline = array(\n\t'borders' => array(\n\t\t'outline' => array(\n\t\t\t'style' => PHPExcel_Style_Border::BORDER_THIN,\n\t\t\t'color' => array('argb' => 'FF000000'),\n\t\t),\n\t),\n);\n$objPHPExcel->getActiveSheet()->getStyle('A4:E10')->applyFromArray($styleThinBlackBorderOutline);\n\n\n// Set thick brown border outline around \"Total\"\necho date('H:i:s') , \" Set thick brown border outline around Total\" , EOL;\n$styleThickBrownBorderOutline = array(\n\t'borders' => array(\n\t\t'outline' => array(\n\t\t\t'style' => PHPExcel_Style_Border::BORDER_THICK,\n\t\t\t'color' => array('argb' => 'FF993300'),\n\t\t),\n\t),\n);\n$objPHPExcel->getActiveSheet()->getStyle('D13:E13')->applyFromArray($styleThickBrownBorderOutline);\n\n// Set fills\necho date('H:i:s') , \" Set fills\" , EOL;\n$objPHPExcel->getActiveSheet()->getStyle('A1:E1')->getFill()->setFillType(PHPExcel_Style_Fill::FILL_SOLID);\n$objPHPExcel->getActiveSheet()->getStyle('A1:E1')->getFill()->getStartColor()->setARGB('FF808080');\n\n// Set style for header row using alternative method\necho date('H:i:s') , \" Set style for header row using alternative method\" , EOL;\n$objPHPExcel->getActiveSheet()->getStyle('A3:E3')->applyFromArray(\n\t\tarray(\n\t\t\t'font'    => array(\n\t\t\t\t'bold'      => true\n\t\t\t),\n\t\t\t'alignment' => array(\n\t\t\t\t'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_RIGHT,\n\t\t\t),\n\t\t\t'borders' => array(\n\t\t\t\t'top'     => array(\n \t\t\t\t\t'style' => PHPExcel_Style_Border::BORDER_THIN\n \t\t\t\t)\n\t\t\t),\n\t\t\t'fill' => array(\n\t \t\t\t'type'       => PHPExcel_Style_Fill::FILL_GRADIENT_LINEAR,\n\t  \t\t\t'rotation'   => 90,\n\t \t\t\t'startcolor' => array(\n\t \t\t\t\t'argb' => 'FFA0A0A0'\n\t \t\t\t),\n\t \t\t\t'endcolor'   => array(\n\t \t\t\t\t'argb' => 'FFFFFFFF'\n\t \t\t\t)\n\t \t\t)\n\t\t)\n);\n\n$objPHPExcel->getActiveSheet()->getStyle('A3')->applyFromArray(\n\t\tarray(\n\t\t\t'alignment' => array(\n\t\t\t\t'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_LEFT,\n\t\t\t),\n\t\t\t'borders' => array(\n\t\t\t\t'left'     => array(\n \t\t\t\t\t'style' => PHPExcel_Style_Border::BORDER_THIN\n \t\t\t\t)\n\t\t\t)\n\t\t)\n);\n\n$objPHPExcel->getActiveSheet()->getStyle('B3')->applyFromArray(\n\t\tarray(\n\t\t\t'alignment' => array(\n\t\t\t\t'horizontal' => PHPExcel_Style_Alignment::HORIZONTAL_LEFT,\n\t\t\t)\n\t\t)\n);\n\n$objPHPExcel->getActiveSheet()->getStyle('E3')->applyFromArray(\n\t\tarray(\n\t\t\t'borders' => array(\n\t\t\t\t'right'     => array(\n \t\t\t\t\t'style' => PHPExcel_Style_Border::BORDER_THIN\n \t\t\t\t)\n\t\t\t)\n\t\t)\n);\n\n// Unprotect a cell\necho date('H:i:s') , \" Unprotect a cell\" , EOL;\n$objPHPExcel->getActiveSheet()->getStyle('B1')->getProtection()->setLocked(PHPExcel_Style_Protection::PROTECTION_UNPROTECTED);\n\n// Add a hyperlink to the sheet\necho date('H:i:s') , \" Add a hyperlink to an external website\" , EOL;\n$objPHPExcel->getActiveSheet()->setCellValue('E26', 'www.phpexcel.net');\n$objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setUrl('http://www.phpexcel.net');\n$objPHPExcel->getActiveSheet()->getCell('E26')->getHyperlink()->setTooltip('Navigate to website');\n$objPHPExcel->getActiveSheet()->getStyle('E26')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);\n\necho date('H:i:s') , \" Add a hyperlink to another cell on a different worksheet within the workbook\" , EOL;\n$objPHPExcel->getActiveSheet()->setCellValue('E27', 'Terms and conditions');\n$objPHPExcel->getActiveSheet()->getCell('E27')->getHyperlink()->setUrl(\"sheet://'Terms and conditions'!A1\");\n$objPHPExcel->getActiveSheet()->getCell('E27')->getHyperlink()->setTooltip('Review terms and conditions');\n$objPHPExcel->getActiveSheet()->getStyle('E27')->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_RIGHT);\n\n// Add a drawing to the worksheet\necho date('H:i:s') , \" Add a drawing to the worksheet\" , EOL;\n$objDrawing = new PHPExcel_Worksheet_Drawing();\n$objDrawing->setName('Logo');\n$objDrawing->setDescription('Logo');\n$objDrawing->setPath('./images/officelogo.jpg');\n$objDrawing->setHeight(36);\n$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());\n\n// Add a drawing to the worksheet\necho date('H:i:s') , \" Add a drawing to the worksheet\" , EOL;\n$objDrawing = new PHPExcel_Worksheet_Drawing();\n$objDrawing->setName('Paid');\n$objDrawing->setDescription('Paid');\n$objDrawing->setPath('./images/paid.png');\n$objDrawing->setCoordinates('B15');\n$objDrawing->setOffsetX(110);\n$objDrawing->setRotation(25);\n$objDrawing->getShadow()->setVisible(true);\n$objDrawing->getShadow()->setDirection(45);\n$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());\n\n// Add a drawing to the worksheet\necho date('H:i:s') , \" Add a drawing to the worksheet\" , EOL;\n$objDrawing = new PHPExcel_Worksheet_Drawing();\n$objDrawing->setName('PHPExcel logo');\n$objDrawing->setDescription('PHPExcel logo');\n$objDrawing->setPath('./images/phpexcel_logo.gif');\n$objDrawing->setHeight(36);\n$objDrawing->setCoordinates('D24');\n$objDrawing->setOffsetX(10);\n$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());\n\n// Play around with inserting and removing rows and columns\necho date('H:i:s') , \" Play around with inserting and removing rows and columns\" , EOL;\n$objPHPExcel->getActiveSheet()->insertNewRowBefore(6, 10);\n$objPHPExcel->getActiveSheet()->removeRow(6, 10);\n$objPHPExcel->getActiveSheet()->insertNewColumnBefore('E', 5);\n$objPHPExcel->getActiveSheet()->removeColumn('E', 5);\n\n// Set header and footer. When no different headers for odd/even are used, odd header is assumed.\necho date('H:i:s') , \" Set header/footer\" , EOL;\n$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddHeader('&L&BInvoice&RPrinted on &D');\n$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddFooter('&L&B' . $objPHPExcel->getProperties()->getTitle() . '&RPage &P of &N');\n\n// Set page orientation and size\necho date('H:i:s') , \" Set page orientation and size\" , EOL;\n$objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT);\n$objPHPExcel->getActiveSheet()->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);\n\n// Rename first worksheet\necho date('H:i:s') , \" Rename first worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Invoice');\n\n\n// Create a new worksheet, after the default sheet\necho date('H:i:s') , \" Create a second Worksheet object\" , EOL;\n$objPHPExcel->createSheet();\n\n// Llorem ipsum...\n$sLloremIpsum = 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Vivamus eget ante. Sed cursus nunc semper tortor. Aliquam luctus purus non elit. Fusce vel elit commodo sapien dignissim dignissim. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas. Curabitur accumsan magna sed massa. Nullam bibendum quam ac ipsum. Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Proin augue. Praesent malesuada justo sed orci. Pellentesque lacus ligula, sodales quis, ultricies a, ultricies vitae, elit. Sed luctus consectetuer dolor. Vivamus vel sem ut nisi sodales accumsan. Nunc et felis. Suspendisse semper viverra odio. Morbi at odio. Integer a orci a purus venenatis molestie. Nam mattis. Praesent rhoncus, nisi vel mattis auctor, neque nisi faucibus sem, non dapibus elit pede ac nisl. Cras turpis.';\n\n// Add some data to the second sheet, resembling some different data types\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(1);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Terms and conditions');\n$objPHPExcel->getActiveSheet()->setCellValue('A3', $sLloremIpsum);\n$objPHPExcel->getActiveSheet()->setCellValue('A4', $sLloremIpsum);\n$objPHPExcel->getActiveSheet()->setCellValue('A5', $sLloremIpsum);\n$objPHPExcel->getActiveSheet()->setCellValue('A6', $sLloremIpsum);\n\n// Set the worksheet tab color\necho date('H:i:s') , \" Set the worksheet tab color\" , EOL;\n$objPHPExcel->getActiveSheet()->getTabColor()->setARGB('FF0094FF');;\n\n// Set alignments\necho date('H:i:s') , \" Set alignments\" , EOL;\n$objPHPExcel->getActiveSheet()->getStyle('A3:A6')->getAlignment()->setWrapText(true);\n\n// Set column widths\necho date('H:i:s') , \" Set column widths\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(80);\n\n// Set fonts\necho date('H:i:s') , \" Set fonts\" , EOL;\n$objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setName('Candara');\n$objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setSize(20);\n$objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setBold(true);\n$objPHPExcel->getActiveSheet()->getStyle('A1')->getFont()->setUnderline(PHPExcel_Style_Font::UNDERLINE_SINGLE);\n\n$objPHPExcel->getActiveSheet()->getStyle('A3:A6')->getFont()->setSize(8);\n\n// Add a drawing to the worksheet\necho date('H:i:s') , \" Add a drawing to the worksheet\" , EOL;\n$objDrawing = new PHPExcel_Worksheet_Drawing();\n$objDrawing->setName('Terms and conditions');\n$objDrawing->setDescription('Terms and conditions');\n$objDrawing->setPath('./images/termsconditions.jpg');\n$objDrawing->setCoordinates('B14');\n$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());\n\n// Set page orientation and size\necho date('H:i:s') , \" Set page orientation and size\" , EOL;\n$objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE);\n$objPHPExcel->getActiveSheet()->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);\n\n// Rename second worksheet\necho date('H:i:s') , \" Rename second worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Terms and conditions');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/05featuredemo.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\ninclude \"05featuredemo.inc.php\";\n\n/** Include PHPExcel_IOFactory */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/06largescale-with-cellcaching-sqlite.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_sqlite;\nif (PHPExcel_Settings::setCacheStorageMethod($cacheMethod)) {\n    echo date('H:i:s') , \" Enable Cell Caching using \" , $cacheMethod , \" method\" , EOL;\n} else {\n    echo date('H:i:s') , \" Unable to set Cell Caching using \" , $cacheMethod , \" method, reverting to memory\" , EOL;\n}\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Create a first sheet\necho date('H:i:s') , \" Add data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', \"Firstname\");\n$objPHPExcel->getActiveSheet()->setCellValue('B1', \"Lastname\");\n$objPHPExcel->getActiveSheet()->setCellValue('C1', \"Phone\");\n$objPHPExcel->getActiveSheet()->setCellValue('D1', \"Fax\");\n$objPHPExcel->getActiveSheet()->setCellValue('E1', \"Is Client ?\");\n\n\n// Hide \"Phone\" and \"fax\" column\necho date('H:i:s') , \" Hide 'Phone' and 'fax' columns\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false);\n$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false);\n\n\n// Set outline levels\necho date('H:i:s') , \" Set outline levels\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1)\n                                                       ->setVisible(false)\n                                                       ->setCollapsed(true);\n\n// Freeze panes\necho date('H:i:s') , \" Freeze panes\" , EOL;\n$objPHPExcel->getActiveSheet()->freezePane('A2');\n\n\n// Rows to repeat at top\necho date('H:i:s') , \" Rows to repeat at top\" , EOL;\n$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1);\n\n\n// Add data\nfor ($i = 2; $i <= 5000; $i++) {\n\t$objPHPExcel->getActiveSheet()->setCellValue('A' . $i, \"FName $i\")\n\t                              ->setCellValue('B' . $i, \"LName $i\")\n\t                              ->setCellValue('C' . $i, \"PhoneNo $i\")\n\t                              ->setCellValue('D' . $i, \"FaxNo $i\")\n\t                              ->setCellValue('E' . $i, true);\n}\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/06largescale-with-cellcaching-sqlite3.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_sqlite3;\nif (PHPExcel_Settings::setCacheStorageMethod($cacheMethod)) {\n    echo date('H:i:s') , \" Enable Cell Caching using \" , $cacheMethod , \" method\" , EOL;\n} else {\n    echo date('H:i:s') , \" Unable to set Cell Caching using \" , $cacheMethod , \" method, reverting to memory\" , EOL;\n}\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Create a first sheet\necho date('H:i:s') , \" Add data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', \"Firstname\");\n$objPHPExcel->getActiveSheet()->setCellValue('B1', \"Lastname\");\n$objPHPExcel->getActiveSheet()->setCellValue('C1', \"Phone\");\n$objPHPExcel->getActiveSheet()->setCellValue('D1', \"Fax\");\n$objPHPExcel->getActiveSheet()->setCellValue('E1', \"Is Client ?\");\n\n\n// Hide \"Phone\" and \"fax\" column\necho date('H:i:s') , \" Hide 'Phone' and 'fax' columns\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false);\n$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false);\n\n\n// Set outline levels\necho date('H:i:s') , \" Set outline levels\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1)\n                                                       ->setVisible(false)\n                                                       ->setCollapsed(true);\n\n// Freeze panes\necho date('H:i:s') , \" Freeze panes\" , EOL;\n$objPHPExcel->getActiveSheet()->freezePane('A2');\n\n\n// Rows to repeat at top\necho date('H:i:s') , \" Rows to repeat at top\" , EOL;\n$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1);\n\n\n// Add data\nfor ($i = 2; $i <= 5000; $i++) {\n\t$objPHPExcel->getActiveSheet()->setCellValue('A' . $i, \"FName $i\")\n\t                              ->setCellValue('B' . $i, \"LName $i\")\n\t                              ->setCellValue('C' . $i, \"PhoneNo $i\")\n\t                              ->setCellValue('D' . $i, \"FaxNo $i\")\n\t                              ->setCellValue('E' . $i, true);\n}\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/06largescale-with-cellcaching.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_in_memory_gzip;\nif (!PHPExcel_Settings::setCacheStorageMethod($cacheMethod)) {\n\tdie($cacheMethod . \" caching method is not available\" . EOL);\n}\necho date('H:i:s') , \" Enable Cell Caching using \" , $cacheMethod , \" method\" , EOL;\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Create a first sheet\necho date('H:i:s') , \" Add data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', \"Firstname\");\n$objPHPExcel->getActiveSheet()->setCellValue('B1', \"Lastname\");\n$objPHPExcel->getActiveSheet()->setCellValue('C1', \"Phone\");\n$objPHPExcel->getActiveSheet()->setCellValue('D1', \"Fax\");\n$objPHPExcel->getActiveSheet()->setCellValue('E1', \"Is Client ?\");\n\n\n// Hide \"Phone\" and \"fax\" column\necho date('H:i:s') , \" Hide 'Phone' and 'fax' columns\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false);\n$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false);\n\n\n// Set outline levels\necho date('H:i:s') , \" Set outline levels\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1)\n                                                       ->setVisible(false)\n                                                       ->setCollapsed(true);\n\n// Freeze panes\necho date('H:i:s') , \" Freeze panes\" , EOL;\n$objPHPExcel->getActiveSheet()->freezePane('A2');\n\n\n// Rows to repeat at top\necho date('H:i:s') , \" Rows to repeat at top\" , EOL;\n$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1);\n\n\n// Add data\nfor ($i = 2; $i <= 5000; $i++) {\n\t$objPHPExcel->getActiveSheet()->setCellValue('A' . $i, \"FName $i\")\n\t                              ->setCellValue('B' . $i, \"LName $i\")\n\t                              ->setCellValue('C' . $i, \"PhoneNo $i\")\n\t                              ->setCellValue('D' . $i, \"FaxNo $i\")\n\t                              ->setCellValue('E' . $i, true);\n}\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/06largescale-xls.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n/*\nAfter doing some test, I've got these results benchmarked\nfor writing to Excel2007:\n\n\tNumber of rows\tSeconds to generate\n\t200\t\t\t\t3\n\t500\t\t\t\t4\n\t1000\t\t\t6\n\t2000\t\t\t12\n\t4000\t\t\t36\n\t8000\t\t\t64\n\t15000\t\t\t465\n*/\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Create a first sheet\necho date('H:i:s') , \" Add data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', \"Firstname\");\n$objPHPExcel->getActiveSheet()->setCellValue('B1', \"Lastname\");\n$objPHPExcel->getActiveSheet()->setCellValue('C1', \"Phone\");\n$objPHPExcel->getActiveSheet()->setCellValue('D1', \"Fax\");\n$objPHPExcel->getActiveSheet()->setCellValue('E1', \"Is Client ?\");\n\n\n// Hide \"Phone\" and \"fax\" column\necho date('H:i:s') , \" Hide 'Phone' and 'fax' columns\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false);\n$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false);\n\n\n// Set outline levels\necho date('H:i:s') , \" Set outline levels\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1)\n                                                       ->setVisible(false)\n                                                       ->setCollapsed(true);\n\n// Freeze panes\necho date('H:i:s') , \" Freeze panes\" , EOL;\n$objPHPExcel->getActiveSheet()->freezePane('A2');\n\n\n// Rows to repeat at top\necho date('H:i:s') , \" Rows to repeat at top\" , EOL;\n$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1);\n\n\n// Add data\nfor ($i = 2; $i <= 5000; $i++) {\n\t$objPHPExcel->getActiveSheet()->setCellValue('A' . $i, \"FName $i\")\n\t                              ->setCellValue('B' . $i, \"LName $i\")\n\t                              ->setCellValue('C' . $i, \"PhoneNo $i\")\n\t                              ->setCellValue('D' . $i, \"FaxNo $i\")\n\t                              ->setCellValue('E' . $i, true);\n}\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/06largescale.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n/*\nAfter doing some test, I've got these results benchmarked\nfor writing to Excel2007:\n\n\tNumber of rows\tSeconds to generate\n\t200\t\t\t\t3\n\t500\t\t\t\t4\n\t1000\t\t\t6\n\t2000\t\t\t12\n\t4000\t\t\t36\n\t8000\t\t\t64\n\t15000\t\t\t465\n*/\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Create a first sheet\necho date('H:i:s') , \" Add data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', \"Firstname\");\n$objPHPExcel->getActiveSheet()->setCellValue('B1', \"Lastname\");\n$objPHPExcel->getActiveSheet()->setCellValue('C1', \"Phone\");\n$objPHPExcel->getActiveSheet()->setCellValue('D1', \"Fax\");\n$objPHPExcel->getActiveSheet()->setCellValue('E1', \"Is Client ?\");\n\n\n// Hide \"Phone\" and \"fax\" column\necho date('H:i:s') , \" Hide 'Phone' and 'fax' columns\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setVisible(false);\n$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setVisible(false);\n\n\n// Set outline levels\necho date('H:i:s') , \" Set outline levels\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('E')->setOutlineLevel(1)\n                                                       ->setVisible(false)\n                                                       ->setCollapsed(true);\n\n// Freeze panes\necho date('H:i:s') , \" Freeze panes\" , EOL;\n$objPHPExcel->getActiveSheet()->freezePane('A2');\n\n\n// Rows to repeat at top\necho date('H:i:s') , \" Rows to repeat at top\" , EOL;\n$objPHPExcel->getActiveSheet()->getPageSetup()->setRowsToRepeatAtTopByStartAndEnd(1, 1);\n\n\n// Add data\nfor ($i = 2; $i <= 5000; $i++) {\n\t$objPHPExcel->getActiveSheet()->setCellValue('A' . $i, \"FName $i\")\n\t                              ->setCellValue('B' . $i, \"LName $i\")\n\t                              ->setCellValue('C' . $i, \"PhoneNo $i\")\n\t                              ->setCellValue('D' . $i, \"FaxNo $i\")\n\t                              ->setCellValue('E' . $i, true);\n}\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/07reader.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel_IOFactory */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\n\n\nif (!file_exists(\"05featuredemo.xlsx\")) {\n\texit(\"Please run 05featuredemo.php first.\" . EOL);\n}\n\necho date('H:i:s') , \" Load from Excel2007 file\" , EOL;\n$callStartTime = microtime(true);\n\n$objPHPExcel = PHPExcel_IOFactory::load(\"05featuredemo.xlsx\");\n\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\necho 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/07readerPCLZip.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel_IOFactory */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\n\n\nif (!file_exists(\"05featuredemo.xlsx\")) {\n\texit(\"Please run 05featuredemo.php first.\" . EOL);\n}\n\n// Use PCLZip rather than ZipArchive to read the Excel2007 OfficeOpenXML file\nPHPExcel_Settings::setZipClass(PHPExcel_Settings::PCLZIP);\n\necho date('H:i:s') , \" Load from Excel2007 file\" , EOL;\n$callStartTime = microtime(true);\n\n$objPHPExcel = PHPExcel_IOFactory::load(\"05featuredemo.xlsx\");\n\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\necho 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/08conditionalformatting.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Create a first sheet, representing sales data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Description')\n                              ->setCellValue('B1', 'Amount');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Paycheck received')\n                              ->setCellValue('B2', 100);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A3', 'Cup of coffee bought')\n                              ->setCellValue('B3', -1.5);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Cup of coffee bought')\n                              ->setCellValue('B4', -1.5);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Cup of tea bought')\n                              ->setCellValue('B5', -1.2);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Found some money')\n                              ->setCellValue('B6', 8);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Total:')\n                              ->setCellValue('B7', '=SUM(B2:B6)');\n\n\n// Set column widths\necho date('H:i:s') , \" Set column widths\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(30);\n$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(12);\n\n\n// Add conditional formatting\necho date('H:i:s') , \" Add conditional formatting\" , EOL;\n$objConditional1 = new PHPExcel_Style_Conditional();\n$objConditional1->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS)\n                ->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_BETWEEN)\n                ->addCondition('200')\n                ->addCondition('400');\n$objConditional1->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_YELLOW);\n$objConditional1->getStyle()->getFont()->setBold(true);\n$objConditional1->getStyle()->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE);\n\n$objConditional2 = new PHPExcel_Style_Conditional();\n$objConditional2->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS)\n                ->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_LESSTHAN)\n                ->addCondition('0');\n$objConditional2->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED);\n$objConditional2->getStyle()->getFont()->setItalic(true);\n$objConditional2->getStyle()->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE);\n\n$objConditional3 = new PHPExcel_Style_Conditional();\n$objConditional3->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS)\n                ->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL)\n                ->addCondition('0');\n$objConditional3->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_GREEN);\n$objConditional3->getStyle()->getFont()->setItalic(true);\n$objConditional3->getStyle()->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE);\n\n$conditionalStyles = $objPHPExcel->getActiveSheet()->getStyle('B2')->getConditionalStyles();\narray_push($conditionalStyles, $objConditional1);\narray_push($conditionalStyles, $objConditional2);\narray_push($conditionalStyles, $objConditional3);\n$objPHPExcel->getActiveSheet()->getStyle('B2')->setConditionalStyles($conditionalStyles);\n\n\n//\tduplicate the conditional styles across a range of cells\necho date('H:i:s') , \" Duplicate the conditional formatting across a range of cells\" , EOL;\n$objPHPExcel->getActiveSheet()->duplicateConditionalStyle(\n\t\t\t\t$objPHPExcel->getActiveSheet()->getStyle('B2')->getConditionalStyles(),\n\t\t\t\t'B3:B7'\n\t\t\t  );\n\n\n// Set fonts\necho date('H:i:s') , \" Set fonts\" , EOL;\n$objPHPExcel->getActiveSheet()->getStyle('A1:B1')->getFont()->setBold(true);\n//$objPHPExcel->getActiveSheet()->getStyle('B1')->getFont()->setBold(true);\n$objPHPExcel->getActiveSheet()->getStyle('A7:B7')->getFont()->setBold(true);\n//$objPHPExcel->getActiveSheet()->getStyle('B7')->getFont()->setBold(true);\n\n\n// Set header and footer. When no different headers for odd/even are used, odd header is assumed.\necho date('H:i:s') , \" Set header/footer\" , EOL;\n$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddHeader('&L&BPersonal cash register&RPrinted on &D');\n$objPHPExcel->getActiveSheet()->getHeaderFooter()->setOddFooter('&L&B' . $objPHPExcel->getProperties()->getTitle() . '&RPage &P of &N');\n\n\n// Set page orientation and size\necho date('H:i:s') , \" Set page orientation and size\" , EOL;\n$objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_PORTRAIT);\n$objPHPExcel->getActiveSheet()->getPageSetup()->setPaperSize(PHPExcel_Worksheet_PageSetup::PAPERSIZE_A4);\n\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Invoice');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Save Excel5 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/08conditionalformatting2.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Create a first sheet, representing sales data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()\n    ->setCellValue('A1', '-0.5')\n    ->setCellValue('A2', '-0.25')\n    ->setCellValue('A3', '0.0')\n    ->setCellValue('A4', '0.25')\n    ->setCellValue('A5', '0.5')\n    ->setCellValue('A6', '0.75')\n    ->setCellValue('A7', '1.0')\n    ->setCellValue('A8', '1.25')\n;\n\n$objPHPExcel->getActiveSheet()->getStyle('A1:A8')\n    ->getNumberFormat()\n    ->setFormatCode(\n        PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00\n    );\n\n\n// Add conditional formatting\necho date('H:i:s') , \" Add conditional formatting\" , EOL;\n$objConditional1 = new PHPExcel_Style_Conditional();\n$objConditional1->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS)\n    ->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_LESSTHAN)\n    ->addCondition('0');\n$objConditional1->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_RED);\n\n$objConditional3 = new PHPExcel_Style_Conditional();\n$objConditional3->setConditionType(PHPExcel_Style_Conditional::CONDITION_CELLIS)\n    ->setOperatorType(PHPExcel_Style_Conditional::OPERATOR_GREATERTHANOREQUAL)\n    ->addCondition('1');\n$objConditional3->getStyle()->getFont()->getColor()->setARGB(PHPExcel_Style_Color::COLOR_GREEN);\n\n$conditionalStyles = $objPHPExcel->getActiveSheet()->getStyle('A1')->getConditionalStyles();\narray_push($conditionalStyles, $objConditional1);\narray_push($conditionalStyles, $objConditional3);\n$objPHPExcel->getActiveSheet()->getStyle('A1')->setConditionalStyles($conditionalStyles);\n\n\n//\tduplicate the conditional styles across a range of cells\necho date('H:i:s') , \" Duplicate the conditional formatting across a range of cells\" , EOL;\n$objPHPExcel->getActiveSheet()->duplicateConditionalStyle(\n\t\t\t\t$objPHPExcel->getActiveSheet()->getStyle('A1')->getConditionalStyles(),\n\t\t\t\t'A2:A8'\n\t\t\t  );\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Save Excel5 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/09pagebreaks.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Create a first sheet\necho date('H:i:s') , \" Add data and page breaks\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', \"Firstname\")\n                              ->setCellValue('B1', \"Lastname\")\n                              ->setCellValue('C1', \"Phone\")\n                              ->setCellValue('D1', \"Fax\")\n                              ->setCellValue('E1', \"Is Client ?\");\n\n\n// Add data\nfor ($i = 2; $i <= 50; $i++) {\n\t$objPHPExcel->getActiveSheet()->setCellValue('A' . $i, \"FName $i\");\n\t$objPHPExcel->getActiveSheet()->setCellValue('B' . $i, \"LName $i\");\n\t$objPHPExcel->getActiveSheet()->setCellValue('C' . $i, \"PhoneNo $i\");\n\t$objPHPExcel->getActiveSheet()->setCellValue('D' . $i, \"FaxNo $i\");\n\t$objPHPExcel->getActiveSheet()->setCellValue('E' . $i, true);\n\n\t// Add page breaks every 10 rows\n\tif ($i % 10 == 0) {\n\t\t// Add a page break\n\t\t$objPHPExcel->getActiveSheet()->setBreak( 'A' . $i, PHPExcel_Worksheet::BREAK_ROW );\n\t}\n}\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setTitle('Printing Options');\n\n// Set print headers\n$objPHPExcel->getActiveSheet()\n    ->getHeaderFooter()->setOddHeader('&C&24&K0000FF&B&U&A');\n$objPHPExcel->getActiveSheet()\n    ->getHeaderFooter()->setEvenHeader('&C&24&K0000FF&B&U&A');\n\n// Set print footers\n$objPHPExcel->getActiveSheet()\n    ->getHeaderFooter()->setOddFooter('&R&D &T&C&F&LPage &P / &N');\n$objPHPExcel->getActiveSheet()\n    ->getHeaderFooter()->setEvenFooter('&L&D &T&C&F&RPage &P / &N');\n\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/10autofilter-selection-1.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s').' Create new PHPExcel object'.EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s').' Set document properties'.EOL;\n$objPHPExcel->getProperties()->setCreator('Maarten Balliauw')\n\t\t\t\t\t\t\t ->setLastModifiedBy('Maarten Balliauw')\n\t\t\t\t\t\t\t ->setTitle('PHPExcel Test Document')\n\t\t\t\t\t\t\t ->setSubject('PHPExcel Test Document')\n\t\t\t\t\t\t\t ->setDescription('Test document for PHPExcel, generated using PHP classes.')\n\t\t\t\t\t\t\t ->setKeywords('office PHPExcel php')\n\t\t\t\t\t\t\t ->setCategory('Test result file');\n\n// Create the worksheet\necho date('H:i:s').' Add data'.EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Financial Year')\n                              ->setCellValue('B1', 'Financial Period')\n                              ->setCellValue('C1', 'Country')\n                              ->setCellValue('D1', 'Date')\n                              ->setCellValue('E1', 'Sales Value')\n                              ->setCellValue('F1', 'Expenditure')\n                              ;\n$startYear = $endYear = $currentYear = date('Y');\n$startYear--;\n$endYear++;\n\n$years = range($startYear,$endYear);\n$periods = range(1,12);\n$countries = array(\t'United States',\t'UK',\t\t'France',\t'Germany',\n\t\t\t\t\t'Italy',\t\t\t'Spain',\t'Portugal',\t'Japan'\n\t\t\t\t  );\n\n$row = 2;\nforeach($years as $year) {\n\tforeach($periods as $period) {\n\t\tforeach($countries as $country) {\n\t\t\t$endDays = date('t',mktime(0,0,0,$period,1,$year));\n\t\t\tfor($i = 1; $i <= $endDays; ++$i) {\n\t\t\t\t$eDate = PHPExcel_Shared_Date::FormattedPHPToExcel(\n\t\t\t\t\t$year,\n\t\t\t\t\t$period,\n\t\t\t\t\t$i\n\t\t\t\t);\n\t\t\t\t$value = rand(500,1000) * (1 + rand(-0.25,+0.25));\n\t\t\t\t$salesValue = $invoiceValue = NULL;\n\t\t\t\t$incomeOrExpenditure = rand(-1,1);\n\t\t\t\tif ($incomeOrExpenditure == -1) {\n\t\t\t\t\t$expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25));\n\t\t\t\t\t$income = NULL;\n\t\t\t\t} elseif ($incomeOrExpenditure == 1) {\n\t\t\t\t\t$expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25));\n\t\t\t\t\t$income = rand(500,1000) * (1 + rand(-0.25,+0.25));;\n\t\t\t\t} else {\n\t\t\t\t\t$expenditure = NULL;\n\t\t\t\t\t$income = rand(500,1000) * (1 + rand(-0.25,+0.25));;\n\t\t\t\t}\n\t\t\t\t$dataArray = array(\t$year,\n\t\t\t\t\t\t\t\t\t$period,\n\t\t\t\t\t\t\t\t\t$country,\n\t\t\t\t\t\t\t\t\t$eDate,\n\t\t\t\t\t\t\t\t\t$income,\n\t\t\t\t\t\t\t\t\t$expenditure,\n\t\t\t\t\t\t\t\t  );\n\t\t\t\t$objPHPExcel->getActiveSheet()->fromArray($dataArray, NULL, 'A'.$row++);\n\t\t\t}\n\t\t}\n\t}\n}\n$row--;\n\n\n// Set styling\necho date('H:i:s').' Set styling'.EOL;\n$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getFont()->setBold(true);\n$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getAlignment()->setWrapText(TRUE);\n$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12.5);\n$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(10.5);\n$objPHPExcel->getActiveSheet()->getStyle('D2:D'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2);\n$objPHPExcel->getActiveSheet()->getStyle('E2:F'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE);\n$objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(14);\n$objPHPExcel->getActiveSheet()->freezePane('A2');\n\n\n\n// Set autofilter range\necho date('H:i:s').' Set autofilter range'.EOL;\n// Always include the complete filter range!\n// Excel does support setting only the caption\n// row, but that's not a best practise...\n$objPHPExcel->getActiveSheet()->setAutoFilter($objPHPExcel->getActiveSheet()->calculateWorksheetDimension());\n\n// Set active filters\n$autoFilter = $objPHPExcel->getActiveSheet()->getAutoFilter();\necho date('H:i:s').' Set active filters'.EOL;\n// Filter the Country column on a filter value of countries beginning with the letter U (or Japan)\n//     We use * as a wildcard, so specify as U* and using a wildcard requires customFilter\n$autoFilter->getColumn('C')\n    ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER)\n    ->createRule()\n\t\t->setRule(\n\t\t\tPHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,\n\t\t\t'u*'\n\t\t)\n\t\t->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);\n$autoFilter->getColumn('C')\n    ->createRule()\n\t\t->setRule(\n\t\t\tPHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,\n\t\t\t'japan'\n\t\t)\n\t\t->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);\n// Filter the Date column on a filter value of the first day of every period of the current year\n//\tWe us a dateGroup ruletype for this, although it is still a standard filter\nforeach($periods as $period) {\n\t$endDate = date('t',mktime(0,0,0,$period,1,$currentYear));\n\n\t$autoFilter->getColumn('D')\n\t    ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER)\n\t    ->createRule()\n\t\t\t->setRule(\n\t\t\t\tPHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,\n\t\t\t\tarray(\n\t\t\t\t\t'year' => $currentYear,\n\t\t\t\t\t'month' => $period,\n\t\t\t\t\t'day' => $endDate\n\t\t\t\t)\n\t\t\t)\n\t\t\t->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP);\n}\n// Display only sales values that are blank\n//     Standard filter, operator equals, and value of NULL\n$autoFilter->getColumn('E')\n    ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER)\n    ->createRule()\n\t\t->setRule(\n\t\t\tPHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,\n\t\t\t''\n\t\t);\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s').' Peak memory usage: '.(memory_get_peak_usage(true) / 1024 / 1024).' MB'.EOL;\n\n// Echo done\necho date('H:i:s').' Done writing files'.EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/10autofilter-selection-2.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s').' Create new PHPExcel object'.EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s').' Set document properties'.EOL;\n$objPHPExcel->getProperties()->setCreator('Maarten Balliauw')\n\t\t\t\t\t\t\t ->setLastModifiedBy('Maarten Balliauw')\n\t\t\t\t\t\t\t ->setTitle('PHPExcel Test Document')\n\t\t\t\t\t\t\t ->setSubject('PHPExcel Test Document')\n\t\t\t\t\t\t\t ->setDescription('Test document for PHPExcel, generated using PHP classes.')\n\t\t\t\t\t\t\t ->setKeywords('office PHPExcel php')\n\t\t\t\t\t\t\t ->setCategory('Test result file');\n\n// Create the worksheet\necho date('H:i:s').' Add data'.EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Financial Year')\n                              ->setCellValue('B1', 'Financial Period')\n                              ->setCellValue('C1', 'Country')\n                              ->setCellValue('D1', 'Date')\n                              ->setCellValue('E1', 'Sales Value')\n                              ->setCellValue('F1', 'Expenditure')\n                              ;\n$startYear = $endYear = $currentYear = date('Y');\n$startYear--;\n$endYear++;\n\n$years = range($startYear,$endYear);\n$periods = range(1,12);\n$countries = array(\t'United States',\t'UK',\t\t'France',\t'Germany',\n\t\t\t\t\t'Italy',\t\t\t'Spain',\t'Portugal',\t'Japan'\n\t\t\t\t  );\n\n$row = 2;\nforeach($years as $year) {\n\tforeach($periods as $period) {\n\t\tforeach($countries as $country) {\n\t\t\t$endDays = date('t',mktime(0,0,0,$period,1,$year));\n\t\t\tfor($i = 1; $i <= $endDays; ++$i) {\n\t\t\t\t$eDate = PHPExcel_Shared_Date::FormattedPHPToExcel(\n\t\t\t\t\t$year,\n\t\t\t\t\t$period,\n\t\t\t\t\t$i\n\t\t\t\t);\n\t\t\t\t$value = rand(500,1000) * (1 + rand(-0.25,+0.25));\n\t\t\t\t$salesValue = $invoiceValue = NULL;\n\t\t\t\t$incomeOrExpenditure = rand(-1,1);\n\t\t\t\tif ($incomeOrExpenditure == -1) {\n\t\t\t\t\t$expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25));\n\t\t\t\t\t$income = NULL;\n\t\t\t\t} elseif ($incomeOrExpenditure == 1) {\n\t\t\t\t\t$expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25));\n\t\t\t\t\t$income = rand(500,1000) * (1 + rand(-0.25,+0.25));;\n\t\t\t\t} else {\n\t\t\t\t\t$expenditure = NULL;\n\t\t\t\t\t$income = rand(500,1000) * (1 + rand(-0.25,+0.25));;\n\t\t\t\t}\n\t\t\t\t$dataArray = array(\t$year,\n\t\t\t\t\t\t\t\t\t$period,\n\t\t\t\t\t\t\t\t\t$country,\n\t\t\t\t\t\t\t\t\t$eDate,\n\t\t\t\t\t\t\t\t\t$income,\n\t\t\t\t\t\t\t\t\t$expenditure,\n\t\t\t\t\t\t\t\t  );\n\t\t\t\t$objPHPExcel->getActiveSheet()->fromArray($dataArray, NULL, 'A'.$row++);\n\t\t\t}\n\t\t}\n\t}\n}\n$row--;\n\n\n// Set styling\necho date('H:i:s').' Set styling'.EOL;\n$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getFont()->setBold(true);\n$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getAlignment()->setWrapText(TRUE);\n$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12.5);\n$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(10.5);\n$objPHPExcel->getActiveSheet()->getStyle('D2:D'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2);\n$objPHPExcel->getActiveSheet()->getStyle('E2:F'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE);\n$objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(14);\n$objPHPExcel->getActiveSheet()->freezePane('A2');\n\n\n\n// Set autofilter range\necho date('H:i:s').' Set autofilter range'.EOL;\n// Always include the complete filter range!\n// Excel does support setting only the caption\n// row, but that's not a best practise...\n$objPHPExcel->getActiveSheet()->setAutoFilter($objPHPExcel->getActiveSheet()->calculateWorksheetDimension());\n\n// Set active filters\n$autoFilter = $objPHPExcel->getActiveSheet()->getAutoFilter();\necho date('H:i:s').' Set active filters'.EOL;\n// Filter the Country column on a filter value of Germany\n//\tAs it's just a simple value filter, we can use FILTERTYPE_FILTER\n$autoFilter->getColumn('C')\n    ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER)\n    ->createRule()\n\t\t->setRule(\n\t\t\tPHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,\n\t\t\t'Germany'\n\t\t);\n// Filter the Date column on a filter value of the year to date\n$autoFilter->getColumn('D')\n\t->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER)\n\t->createRule()\n\t\t->setRule(\n\t\t\tPHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,\n\t\t\tNULL,\n\t\t\tPHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMIC_YEARTODATE\n\t\t)\n\t\t->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DYNAMICFILTER);\n// Display only sales values that are between 400 and 600\n$autoFilter->getColumn('E')\n    ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER)\n    ->createRule()\n\t\t->setRule(\n\t\t\tPHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_GREATERTHANOREQUAL,\n\t\t\t400\n\t\t)\n\t\t->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);\n$autoFilter->getColumn('E')\n    ->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND)\n    ->createRule()\n\t\t->setRule(\n\t\t\tPHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHANOREQUAL,\n\t\t\t600\n\t\t)\n\t\t->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s').' Peak memory usage: '.(memory_get_peak_usage(true) / 1024 / 1024).' MB'.EOL;\n\n// Echo done\necho date('H:i:s').' Done writing files'.EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/10autofilter-selection-display.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s').' Create new PHPExcel object'.EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s').' Set document properties'.EOL;\n$objPHPExcel->getProperties()->setCreator('Maarten Balliauw')\n\t\t\t\t\t\t\t ->setLastModifiedBy('Maarten Balliauw')\n\t\t\t\t\t\t\t ->setTitle('PHPExcel Test Document')\n\t\t\t\t\t\t\t ->setSubject('PHPExcel Test Document')\n\t\t\t\t\t\t\t ->setDescription('Test document for PHPExcel, generated using PHP classes.')\n\t\t\t\t\t\t\t ->setKeywords('office PHPExcel php')\n\t\t\t\t\t\t\t ->setCategory('Test result file');\n\n// Create the worksheet\necho date('H:i:s').' Add data'.EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Financial Year')\n                              ->setCellValue('B1', 'Financial Period')\n                              ->setCellValue('C1', 'Country')\n                              ->setCellValue('D1', 'Date')\n                              ->setCellValue('E1', 'Sales Value')\n                              ->setCellValue('F1', 'Expenditure')\n                              ;\n$startYear = $endYear = $currentYear = date('Y');\n$startYear--;\n$endYear++;\n\n$years = range($startYear,$endYear);\n$periods = range(1,12);\n$countries = array(\t'United States',\t'UK',\t\t'France',\t'Germany',\n\t\t\t\t\t'Italy',\t\t\t'Spain',\t'Portugal',\t'Japan'\n\t\t\t\t  );\n\n$row = 2;\nforeach($years as $year) {\n\tforeach($periods as $period) {\n\t\tforeach($countries as $country) {\n\t\t\t$endDays = date('t',mktime(0,0,0,$period,1,$year));\n\t\t\tfor($i = 1; $i <= $endDays; ++$i) {\n\t\t\t\t$eDate = PHPExcel_Shared_Date::FormattedPHPToExcel(\n\t\t\t\t\t$year,\n\t\t\t\t\t$period,\n\t\t\t\t\t$i\n\t\t\t\t);\n\t\t\t\t$value = rand(500,1000) * (1 + rand(-0.25,+0.25));\n\t\t\t\t$salesValue = $invoiceValue = NULL;\n\t\t\t\t$incomeOrExpenditure = rand(-1,1);\n\t\t\t\tif ($incomeOrExpenditure == -1) {\n\t\t\t\t\t$expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25));\n\t\t\t\t\t$income = NULL;\n\t\t\t\t} elseif ($incomeOrExpenditure == 1) {\n\t\t\t\t\t$expenditure = rand(-500,-1000) * (1 + rand(-0.25,+0.25));\n\t\t\t\t\t$income = rand(500,1000) * (1 + rand(-0.25,+0.25));;\n\t\t\t\t} else {\n\t\t\t\t\t$expenditure = NULL;\n\t\t\t\t\t$income = rand(500,1000) * (1 + rand(-0.25,+0.25));;\n\t\t\t\t}\n\t\t\t\t$dataArray = array(\t$year,\n\t\t\t\t\t\t\t\t\t$period,\n\t\t\t\t\t\t\t\t\t$country,\n\t\t\t\t\t\t\t\t\t$eDate,\n\t\t\t\t\t\t\t\t\t$income,\n\t\t\t\t\t\t\t\t\t$expenditure,\n\t\t\t\t\t\t\t\t  );\n\t\t\t\t$objPHPExcel->getActiveSheet()->fromArray($dataArray, NULL, 'A'.$row++);\n\t\t\t}\n\t\t}\n\t}\n}\n$row--;\n\n\n// Set styling\necho date('H:i:s').' Set styling'.EOL;\n$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getFont()->setBold(true);\n$objPHPExcel->getActiveSheet()->getStyle('A1:F1')->getAlignment()->setWrapText(TRUE);\n$objPHPExcel->getActiveSheet()->getColumnDimension('C')->setWidth(12.5);\n$objPHPExcel->getActiveSheet()->getColumnDimension('D')->setWidth(10.5);\n$objPHPExcel->getActiveSheet()->getStyle('D2:D'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_DATE_YYYYMMDD2);\n$objPHPExcel->getActiveSheet()->getStyle('E2:F'.$row)->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE);\n$objPHPExcel->getActiveSheet()->getColumnDimension('F')->setWidth(14);\n$objPHPExcel->getActiveSheet()->freezePane('A2');\n\n\n\n// Set autofilter range\necho date('H:i:s').' Set autofilter range'.EOL;\n// Always include the complete filter range!\n// Excel does support setting only the caption\n// row, but that's not a best practise...\n$objPHPExcel->getActiveSheet()->setAutoFilter($objPHPExcel->getActiveSheet()->calculateWorksheetDimension());\n\n// Set active filters\n$autoFilter = $objPHPExcel->getActiveSheet()->getAutoFilter();\necho date('H:i:s').' Set active filters'.EOL;\n// Filter the Country column on a filter value of countries beginning with the letter U (or Japan)\n//     We use * as a wildcard, so specify as U* and using a wildcard requires customFilter\n$autoFilter->getColumn('C')\n    ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_CUSTOMFILTER)\n    ->createRule()\n\t\t->setRule(\n\t\t\tPHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,\n\t\t\t'u*'\n\t\t)\n\t\t->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);\n$autoFilter->getColumn('C')\n    ->createRule()\n\t\t->setRule(\n\t\t\tPHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,\n\t\t\t'japan'\n\t\t)\n\t\t->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER);\n// Filter the Date column on a filter value of the first day of every period of the current year\n//\tWe us a dateGroup ruletype for this, although it is still a standard filter\nforeach($periods as $period) {\n\t$endDate = date('t',mktime(0,0,0,$period,1,$currentYear));\n\n\t$autoFilter->getColumn('D')\n\t    ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER)\n\t    ->createRule()\n\t\t\t->setRule(\n\t\t\t\tPHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,\n\t\t\t\tarray(\n\t\t\t\t\t'year' => $currentYear,\n\t\t\t\t\t'month' => $period,\n\t\t\t\t\t'day' => $endDate\n\t\t\t\t)\n\t\t\t)\n\t\t\t->setRuleType(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP);\n}\n// Display only sales values that are blank\n//     Standard filter, operator equals, and value of NULL\n$autoFilter->getColumn('E')\n    ->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER)\n    ->createRule()\n\t\t->setRule(\n\t\t\tPHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL,\n\t\t\t''\n\t\t);\n\n// Execute filtering\necho date('H:i:s').' Execute filtering'.EOL;\n$autoFilter->showHideRows();\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Display Results of filtering\necho date('H:i:s').' Display filtered rows'.EOL;\nforeach ($objPHPExcel->getActiveSheet()->getRowIterator() as $row) {\n\tif ($objPHPExcel->getActiveSheet()->getRowDimension($row->getRowIndex())->getVisible()) {\n\t\techo '    Row number - ' , $row->getRowIndex() , ' ';\n\t\techo $objPHPExcel->getActiveSheet()->getCell('C'.$row->getRowIndex())->getValue(), ' ';\n\t\techo $objPHPExcel->getActiveSheet()->getCell('D'.$row->getRowIndex())->getFormattedValue(), ' ';\n\t\techo EOL;\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/10autofilter.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n// Create new PHPExcel object\necho date('H:i:s').' Create new PHPExcel object'.EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s').' Set document properties'.EOL;\n$objPHPExcel->getProperties()->setCreator('Maarten Balliauw')\n\t\t\t\t\t\t\t ->setLastModifiedBy('Maarten Balliauw')\n\t\t\t\t\t\t\t ->setTitle('PHPExcel Test Document')\n\t\t\t\t\t\t\t ->setSubject('PHPExcel Test Document')\n\t\t\t\t\t\t\t ->setDescription('Test document for PHPExcel, generated using PHP classes.')\n\t\t\t\t\t\t\t ->setKeywords('office PHPExcel php')\n\t\t\t\t\t\t\t ->setCategory('Test result file');\n\n// Create the worksheet\necho date('H:i:s').' Add data'.EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Year')\n                              ->setCellValue('B1', 'Quarter')\n                              ->setCellValue('C1', 'Country')\n                              ->setCellValue('D1', 'Sales');\n\n$dataArray = array(array('2010',\t'Q1',\t'United States',\t790),\n                   array('2010',\t'Q2',\t'United States',\t730),\n                   array('2010',\t'Q3',\t'United States',\t860),\n                   array('2010',\t'Q4',\t'United States',\t850),\n                   array('2011',\t'Q1',\t'United States',\t800),\n                   array('2011',\t'Q2',\t'United States',\t700),\n                   array('2011',\t'Q3',\t'United States',\t900),\n                   array('2011',\t'Q4',\t'United States',\t950),\n                   array('2010',\t'Q1',\t'Belgium',\t\t\t380),\n                   array('2010',\t'Q2',\t'Belgium',\t\t\t390),\n                   array('2010',\t'Q3',\t'Belgium',\t\t\t420),\n                   array('2010',\t'Q4',\t'Belgium',\t\t\t460),\n                   array('2011',\t'Q1',\t'Belgium',\t\t\t400),\n                   array('2011',\t'Q2',\t'Belgium',\t\t\t350),\n                   array('2011',\t'Q3',\t'Belgium',\t\t\t450),\n                   array('2011',\t'Q4',\t'Belgium',\t\t\t500),\n                   array('2010',\t'Q1',\t'UK',\t\t\t\t690),\n                   array('2010',\t'Q2',\t'UK',\t\t\t\t610),\n                   array('2010',\t'Q3',\t'UK',\t\t\t\t620),\n                   array('2010',\t'Q4',\t'UK',\t\t\t\t600),\n                   array('2011',\t'Q1',\t'UK',\t\t\t\t720),\n                   array('2011',\t'Q2',\t'UK',\t\t\t\t650),\n                   array('2011',\t'Q3',\t'UK',\t\t\t\t580),\n                   array('2011',\t'Q4',\t'UK',\t\t\t\t510),\n                   array('2010',\t'Q1',\t'France',\t\t\t510),\n                   array('2010',\t'Q2',\t'France',\t\t\t490),\n                   array('2010',\t'Q3',\t'France',\t\t\t460),\n                   array('2010',\t'Q4',\t'France', \t\t\t590),\n                   array('2011',\t'Q1',\t'France',\t\t\t620),\n                   array('2011',\t'Q2',\t'France',\t\t\t650),\n                   array('2011',\t'Q3',\t'France',\t\t\t415),\n                   array('2011',\t'Q4',\t'France', \t\t\t570),\n                   array('2010',\t'Q1',\t'Germany',\t\t\t720),\n                   array('2010',\t'Q2',\t'Germany',\t\t\t680),\n                   array('2010',\t'Q3',\t'Germany',\t\t\t640),\n                   array('2010',\t'Q4',\t'Germany',\t\t\t660),\n                   array('2011',\t'Q1',\t'Germany',\t\t\t680),\n                   array('2011',\t'Q2',\t'Germany',\t\t\t620),\n                   array('2011',\t'Q3',\t'Germany',\t\t\t710),\n                   array('2011',\t'Q4',\t'Germany',\t\t\t690),\n                   array('2010',\t'Q1',\t'Spain',\t\t\t510),\n                   array('2010',\t'Q2',\t'Spain',\t\t\t490),\n                   array('2010',\t'Q3',\t'Spain',\t\t\t470),\n                   array('2010',\t'Q4',\t'Spain',\t\t\t420),\n                   array('2011',\t'Q1',\t'Spain',\t\t\t460),\n                   array('2011',\t'Q2',\t'Spain',\t\t\t390),\n                   array('2011',\t'Q3',\t'Spain',\t\t\t430),\n                   array('2011',\t'Q4',\t'Spain',\t\t\t415),\n                   array('2010',\t'Q1',\t'Italy',\t\t\t440),\n                   array('2010',\t'Q2',\t'Italy',\t\t\t410),\n                   array('2010',\t'Q3',\t'Italy',\t\t\t420),\n                   array('2010',\t'Q4',\t'Italy',\t\t\t450),\n                   array('2011',\t'Q1',\t'Italy',\t\t\t430),\n                   array('2011',\t'Q2',\t'Italy',\t\t\t370),\n                   array('2011',\t'Q3',\t'Italy',\t\t\t350),\n                   array('2011',\t'Q4',\t'Italy',\t\t\t335),\n                  );\n$objPHPExcel->getActiveSheet()->fromArray($dataArray, NULL, 'A2');\n\n// Set title row bold\necho date('H:i:s').' Set title row bold'.EOL;\n$objPHPExcel->getActiveSheet()->getStyle('A1:D1')->getFont()->setBold(true);\n\n// Set autofilter\necho date('H:i:s').' Set autofilter'.EOL;\n// Always include the complete filter range!\n// Excel does support setting only the caption\n// row, but that's not a best practise...\n$objPHPExcel->getActiveSheet()->setAutoFilter($objPHPExcel->getActiveSheet()->calculateWorksheetDimension());\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s').' Peak memory usage: '.(memory_get_peak_usage(true) / 1024 / 1024).' MB'.EOL;\n\n// Echo done\necho date('H:i:s').' Done writing files'.EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/11documentsecurity-xls.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Hello');\n$objPHPExcel->getActiveSheet()->setCellValue('B2', 'world!');\n$objPHPExcel->getActiveSheet()->setCellValue('C1', 'Hello');\n$objPHPExcel->getActiveSheet()->setCellValue('D2', 'world!');\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Simple');\n\n\n// Set document security\necho date('H:i:s') , \" Set document security\" , EOL;\n$objPHPExcel->getSecurity()->setLockWindows(true);\n$objPHPExcel->getSecurity()->setLockStructure(true);\n$objPHPExcel->getSecurity()->setWorkbookPassword(\"PHPExcel\");\n\n\n// Set sheet security\necho date('H:i:s') , \" Set sheet security\" , EOL;\n$objPHPExcel->getActiveSheet()->getProtection()->setPassword('PHPExcel');\n$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); // This should be enabled in order to enable any of the following!\n$objPHPExcel->getActiveSheet()->getProtection()->setSort(true);\n$objPHPExcel->getActiveSheet()->getProtection()->setInsertRows(true);\n$objPHPExcel->getActiveSheet()->getProtection()->setFormatCells(true);\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/11documentsecurity.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Hello');\n$objPHPExcel->getActiveSheet()->setCellValue('B2', 'world!');\n$objPHPExcel->getActiveSheet()->setCellValue('C1', 'Hello');\n$objPHPExcel->getActiveSheet()->setCellValue('D2', 'world!');\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Simple');\n\n\n// Set document security\necho date('H:i:s') , \" Set document security\" , EOL;\n$objPHPExcel->getSecurity()->setLockWindows(true);\n$objPHPExcel->getSecurity()->setLockStructure(true);\n$objPHPExcel->getSecurity()->setWorkbookPassword(\"PHPExcel\");\n\n\n// Set sheet security\necho date('H:i:s') , \" Set sheet security\" , EOL;\n$objPHPExcel->getActiveSheet()->getProtection()->setPassword('PHPExcel');\n$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true); // This should be enabled in order to enable any of the following!\n$objPHPExcel->getActiveSheet()->getProtection()->setSort(true);\n$objPHPExcel->getActiveSheet()->getProtection()->setInsertRows(true);\n$objPHPExcel->getActiveSheet()->getProtection()->setFormatCells(true);\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/12cellProtection.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Mark Baker\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Mark Baker\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Crouching');\n$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Tiger');\n$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Hidden');\n$objPHPExcel->getActiveSheet()->setCellValue('B2', 'Dragon');\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Simple');\n\n\n// Set document security\necho date('H:i:s') , \" Set cell protection\" , EOL;\n\n\n// Set sheet security\necho date('H:i:s') , \" Set sheet security\" , EOL;\n$objPHPExcel->getActiveSheet()->getProtection()->setSheet(true);\n$objPHPExcel->getActiveSheet()\n\t->getStyle('A2:B2')\n\t->getProtection()->setLocked(\n\t\tPHPExcel_Style_Protection::PROTECTION_UNPROTECTED\n\t);\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/13calculation.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\nmt_srand(1234567890);\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// List functions\necho date('H:i:s') , \" List implemented functions\" , EOL;\n$objCalc = PHPExcel_Calculation::getInstance();\nprint_r($objCalc->listFunctionNames());\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Add some data, we will use some formulas here\necho date('H:i:s') , \" Add some data and formulas\" , EOL;\n$objPHPExcel->getActiveSheet()->setCellValue('A14', 'Count:')\n                              ->setCellValue('A15', 'Sum:')\n                              ->setCellValue('A16', 'Max:')\n                              ->setCellValue('A17', 'Min:')\n                              ->setCellValue('A18', 'Average:')\n                              ->setCellValue('A19', 'Median:')\n                              ->setCellValue('A20', 'Mode:');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A22', 'CountA:')\n                              ->setCellValue('A23', 'MaxA:')\n                              ->setCellValue('A24', 'MinA:');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A26', 'StDev:')\n                              ->setCellValue('A27', 'StDevA:')\n                              ->setCellValue('A28', 'StDevP:')\n                              ->setCellValue('A29', 'StDevPA:');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A31', 'DevSq:')\n                              ->setCellValue('A32', 'Var:')\n                              ->setCellValue('A33', 'VarA:')\n                              ->setCellValue('A34', 'VarP:')\n                              ->setCellValue('A35', 'VarPA:');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A37', 'Date:');\n\n\n$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Range 1')\n                              ->setCellValue('B2', 2)\n                              ->setCellValue('B3', 8)\n                              ->setCellValue('B4', 10)\n                              ->setCellValue('B5', True)\n                              ->setCellValue('B6', False)\n                              ->setCellValue('B7', 'Text String')\n                              ->setCellValue('B9', '22')\n                              ->setCellValue('B10', 4)\n                              ->setCellValue('B11', 6)\n                              ->setCellValue('B12', 12);\n\n$objPHPExcel->getActiveSheet()->setCellValue('B14', '=COUNT(B2:B12)')\n                              ->setCellValue('B15', '=SUM(B2:B12)')\n                              ->setCellValue('B16', '=MAX(B2:B12)')\n                              ->setCellValue('B17', '=MIN(B2:B12)')\n                              ->setCellValue('B18', '=AVERAGE(B2:B12)')\n                              ->setCellValue('B19', '=MEDIAN(B2:B12)')\n                              ->setCellValue('B20', '=MODE(B2:B12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('B22', '=COUNTA(B2:B12)')\n                              ->setCellValue('B23', '=MAXA(B2:B12)')\n                              ->setCellValue('B24', '=MINA(B2:B12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('B26', '=STDEV(B2:B12)')\n                              ->setCellValue('B27', '=STDEVA(B2:B12)')\n                              ->setCellValue('B28', '=STDEVP(B2:B12)')\n                              ->setCellValue('B29', '=STDEVPA(B2:B12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('B31', '=DEVSQ(B2:B12)')\n                              ->setCellValue('B32', '=VAR(B2:B12)')\n                              ->setCellValue('B33', '=VARA(B2:B12)')\n                              ->setCellValue('B34', '=VARP(B2:B12)')\n                              ->setCellValue('B35', '=VARPA(B2:B12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('B37', '=DATE(2007, 12, 21)')\n                              ->setCellValue('B38', '=DATEDIF( DATE(2007, 12, 21), DATE(2007, 12, 22), \"D\" )')\n                              ->setCellValue('B39', '=DATEVALUE(\"01-Feb-2006 10:06 AM\")')\n                              ->setCellValue('B40', '=DAY( DATE(2006, 1, 2) )')\n                              ->setCellValue('B41', '=DAYS360( DATE(2002, 2, 3), DATE(2005, 5, 31) )');\n\n\n$objPHPExcel->getActiveSheet()->setCellValue('C1', 'Range 2')\n                              ->setCellValue('C2', 1)\n                              ->setCellValue('C3', 2)\n                              ->setCellValue('C4', 2)\n                              ->setCellValue('C5', 3)\n                              ->setCellValue('C6', 3)\n                              ->setCellValue('C7', 3)\n                              ->setCellValue('C8', '0')\n                              ->setCellValue('C9', 4)\n                              ->setCellValue('C10', 4)\n                              ->setCellValue('C11', 4)\n                              ->setCellValue('C12', 4);\n\n$objPHPExcel->getActiveSheet()->setCellValue('C14', '=COUNT(C2:C12)')\n                              ->setCellValue('C15', '=SUM(C2:C12)')\n                              ->setCellValue('C16', '=MAX(C2:C12)')\n                              ->setCellValue('C17', '=MIN(C2:C12)')\n                              ->setCellValue('C18', '=AVERAGE(C2:C12)')\n                              ->setCellValue('C19', '=MEDIAN(C2:C12)')\n                              ->setCellValue('C20', '=MODE(C2:C12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('C22', '=COUNTA(C2:C12)')\n                              ->setCellValue('C23', '=MAXA(C2:C12)')\n                              ->setCellValue('C24', '=MINA(C2:C12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('C26', '=STDEV(C2:C12)')\n                              ->setCellValue('C27', '=STDEVA(C2:C12)')\n                              ->setCellValue('C28', '=STDEVP(C2:C12)')\n                              ->setCellValue('C29', '=STDEVPA(C2:C12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('C31', '=DEVSQ(C2:C12)')\n                              ->setCellValue('C32', '=VAR(C2:C12)')\n                              ->setCellValue('C33', '=VARA(C2:C12)')\n                              ->setCellValue('C34', '=VARP(C2:C12)')\n                              ->setCellValue('C35', '=VARPA(C2:C12)');\n\n\n$objPHPExcel->getActiveSheet()->setCellValue('D1', 'Range 3')\n                              ->setCellValue('D2', 2)\n                              ->setCellValue('D3', 3)\n                              ->setCellValue('D4', 4);\n\n$objPHPExcel->getActiveSheet()->setCellValue('D14', '=((D2 * D3) + D4) & \" should be 10\"');\n\n$objPHPExcel->getActiveSheet()->setCellValue('E12', 'Other functions')\n                              ->setCellValue('E14', '=PI()')\n                              ->setCellValue('E15', '=RAND()')\n                              ->setCellValue('E16', '=RANDBETWEEN(5, 10)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('E17', 'Count of both ranges:')\n                              ->setCellValue('F17', '=COUNT(B2:C12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('E18', 'Total of both ranges:')\n                              ->setCellValue('F18', '=SUM(B2:C12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('E19', 'Maximum of both ranges:')\n                              ->setCellValue('F19', '=MAX(B2:C12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('E20', 'Minimum of both ranges:')\n                              ->setCellValue('F20', '=MIN(B2:C12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('E21', 'Average of both ranges:')\n                              ->setCellValue('F21', '=AVERAGE(B2:C12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('E22', 'Median of both ranges:')\n                              ->setCellValue('F22', '=MEDIAN(B2:C12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('E23', 'Mode of both ranges:')\n                              ->setCellValue('F23', '=MODE(B2:C12)');\n\n\n// Calculated data\necho date('H:i:s') , \" Calculated data\" , EOL;\nfor ($col = 'B'; $col != 'G'; ++$col) {\n    for($row = 14; $row <= 41; ++$row) {\n        if ((!is_null($formula = $objPHPExcel->getActiveSheet()->getCell($col.$row)->getValue())) &&\n\t\t\t($formula[0] == '=')) {\n            echo 'Value of ' , $col , $row , ' [' , $formula , ']: ' ,\n                               $objPHPExcel->getActiveSheet()->getCell($col.$row)->getCalculatedValue() . EOL;\n        }\n    }\n}\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n\n//\n//  If we set Pre Calculated Formulas to true then PHPExcel will calculate all formulae in the\n//    workbook before saving. This adds time and memory overhead, and can cause some problems with formulae\n//    using functions or features (such as array formulae) that aren't yet supported by the calculation engine\n//  If the value is false (the default) for the Excel2007 Writer, then MS Excel (or the application used to\n//    open the file) will need to recalculate values itself to guarantee that the correct results are available.\n//\n//$objWriter->setPreCalculateFormulas(true);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/14excel5.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\ninclude \"05featuredemo.inc.php\";\n\n/** PHPExcel_IOFactory */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/15datavalidation-xls.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Create a first sheet\necho date('H:i:s') , \" Add data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', \"Cell B3 and B5 contain data validation...\")\n                              ->setCellValue('A3', \"Number:\")\n                              ->setCellValue('B3', \"10\")\n                              ->setCellValue('A5', \"List:\")\n                              ->setCellValue('B5', \"Item A\")\n                              ->setCellValue('A7', \"List #2:\")\n                              ->setCellValue('B7', \"Item #2\")\n                              ->setCellValue('D2', \"Item #1\")\n                              ->setCellValue('D3', \"Item #2\")\n                              ->setCellValue('D4', \"Item #3\")\n                              ->setCellValue('D5', \"Item #4\")\n                              ->setCellValue('D6', \"Item #5\")\n                              ;\n\n\n// Set data validation\necho date('H:i:s') , \" Set data validation\" , EOL;\n$objValidation = $objPHPExcel->getActiveSheet()->getCell('B3')->getDataValidation();\n$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_WHOLE );\n$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP );\n$objValidation->setAllowBlank(true);\n$objValidation->setShowInputMessage(true);\n$objValidation->setShowErrorMessage(true);\n$objValidation->setErrorTitle('Input error');\n$objValidation->setError('Only numbers between 10 and 20 are allowed!');\n$objValidation->setPromptTitle('Allowed input');\n$objValidation->setPrompt('Only numbers between 10 and 20 are allowed.');\n$objValidation->setFormula1(10);\n$objValidation->setFormula2(20);\n\n$objValidation = $objPHPExcel->getActiveSheet()->getCell('B5')->getDataValidation();\n$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST );\n$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION );\n$objValidation->setAllowBlank(false);\n$objValidation->setShowInputMessage(true);\n$objValidation->setShowErrorMessage(true);\n$objValidation->setShowDropDown(true);\n$objValidation->setErrorTitle('Input error');\n$objValidation->setError('Value is not in list.');\n$objValidation->setPromptTitle('Pick from list');\n$objValidation->setPrompt('Please pick a value from the drop-down list.');\n$objValidation->setFormula1('\"Item A,Item B,Item C\"');\t// Make sure to put the list items between \" and \"  !!!\n\n$objValidation = $objPHPExcel->getActiveSheet()->getCell('B7')->getDataValidation();\n$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST );\n$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION );\n$objValidation->setAllowBlank(false);\n$objValidation->setShowInputMessage(true);\n$objValidation->setShowErrorMessage(true);\n$objValidation->setShowDropDown(true);\n$objValidation->setErrorTitle('Input error');\n$objValidation->setError('Value is not in list.');\n$objValidation->setPromptTitle('Pick from list');\n$objValidation->setPrompt('Please pick a value from the drop-down list.');\n$objValidation->setFormula1('$D$2:$D$6');\t// Make sure NOT to put a range of cells or a formula between \" and \"  !!!\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/15datavalidation.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Create a first sheet\necho date('H:i:s') , \" Add data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', \"Cell B3 and B5 contain data validation...\")\n                              ->setCellValue('A3', \"Number:\")\n                              ->setCellValue('B3', \"10\")\n                              ->setCellValue('A5', \"List:\")\n                              ->setCellValue('B5', \"Item A\")\n                              ->setCellValue('A7', \"List #2:\")\n                              ->setCellValue('B7', \"Item #2\")\n                              ->setCellValue('D2', \"Item #1\")\n                              ->setCellValue('D3', \"Item #2\")\n                              ->setCellValue('D4', \"Item #3\")\n                              ->setCellValue('D5', \"Item #4\")\n                              ->setCellValue('D6', \"Item #5\")\n                              ;\n\n\n// Set data validation\necho date('H:i:s') , \" Set data validation\" , EOL;\n$objValidation = $objPHPExcel->getActiveSheet()->getCell('B3')->getDataValidation();\n$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_WHOLE );\n$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_STOP );\n$objValidation->setAllowBlank(true);\n$objValidation->setShowInputMessage(true);\n$objValidation->setShowErrorMessage(true);\n$objValidation->setErrorTitle('Input error');\n$objValidation->setError('Only numbers between 10 and 20 are allowed!');\n$objValidation->setPromptTitle('Allowed input');\n$objValidation->setPrompt('Only numbers between 10 and 20 are allowed.');\n$objValidation->setFormula1(10);\n$objValidation->setFormula2(20);\n\n$objValidation = $objPHPExcel->getActiveSheet()->getCell('B5')->getDataValidation();\n$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST );\n$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION );\n$objValidation->setAllowBlank(false);\n$objValidation->setShowInputMessage(true);\n$objValidation->setShowErrorMessage(true);\n$objValidation->setShowDropDown(true);\n$objValidation->setErrorTitle('Input error');\n$objValidation->setError('Value is not in list.');\n$objValidation->setPromptTitle('Pick from list');\n$objValidation->setPrompt('Please pick a value from the drop-down list.');\n$objValidation->setFormula1('\"Item A,Item B,Item C\"');\t// Make sure to put the list items between \" and \" if your list is simply a comma-separated list of values !!!\n\n\n$objValidation = $objPHPExcel->getActiveSheet()->getCell('B7')->getDataValidation();\n$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST );\n$objValidation->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION );\n$objValidation->setAllowBlank(false);\n$objValidation->setShowInputMessage(true);\n$objValidation->setShowErrorMessage(true);\n$objValidation->setShowDropDown(true);\n$objValidation->setErrorTitle('Input error');\n$objValidation->setError('Value is not in list.');\n$objValidation->setPromptTitle('Pick from list');\n$objValidation->setPrompt('Please pick a value from the drop-down list.');\n$objValidation->setFormula1('$D$2:$D$6');\t// Make sure NOT to put a range of cells or a formula between \" and \"  !!!\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/16csv.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\ninclude \"05featuredemo.inc.php\";\n\n/** PHPExcel_IOFactory */\nrequire_once '../Classes/PHPExcel/IOFactory.php';\n\n\necho date('H:i:s') , \" Write to CSV format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV')->setDelimiter(',')\n                                                                  ->setEnclosure('\"')\n                                                                  ->setLineEnding(\"\\r\\n\")\n                                                                  ->setSheetIndex(0)\n                                                                  ->save(str_replace('.php', '.csv', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.csv', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\necho date('H:i:s') , \" Read from CSV format\" , EOL;\n$callStartTime = microtime(true);\n$objReader = PHPExcel_IOFactory::createReader('CSV')->setDelimiter(',')\n                                                    ->setEnclosure('\"')\n                                                    ->setLineEnding(\"\\r\\n\")\n                                                    ->setSheetIndex(0);\n$objPHPExcelFromCSV = $objReader->load(str_replace('.php', '.csv', __FILE__));\n\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\necho 'Call time to reload Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter2007 = PHPExcel_IOFactory::createWriter($objPHPExcelFromCSV, 'Excel2007');\n$objWriter2007->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\necho date('H:i:s') , \" Write to CSV format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriterCSV = PHPExcel_IOFactory::createWriter($objPHPExcelFromCSV, 'CSV');\n$objWriterCSV->setExcelCompatibility(true);\n$objWriterCSV->save(str_replace('.php', '_excel.csv', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\necho date('H:i:s') , \" File written to \" , str_replace('.php', '_excel.csv', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/17html.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\ninclude \"05featuredemo.inc.php\";\n\n/** PHPExcel_IOFactory */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\n\n\necho date('H:i:s') , \" Write to HTML format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML');\n$objWriter->setSheetIndex(0);\n//$objWriter->setImagesRoot('http://www.example.com');\n$objWriter->save(str_replace('.php', '.htm', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.htm', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/18extendedcalculation.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// List functions\necho date('H:i:s') . \" List implemented functions\\n\";\n$objCalc = PHPExcel_Calculation::getInstance();\nprint_r($objCalc->listFunctionNames());\n\n// Create new PHPExcel object\necho date('H:i:s') . \" Create new PHPExcel object\\n\";\n$objPHPExcel = new PHPExcel();\n\n// Add some data, we will use some formulas here\necho date('H:i:s') . \" Add some data\\n\";\n$objPHPExcel->getActiveSheet()->setCellValue('A14', 'Count:');\n\n$objPHPExcel->getActiveSheet()->setCellValue('B1', 'Range 1');\n$objPHPExcel->getActiveSheet()->setCellValue('B2', 2);\n$objPHPExcel->getActiveSheet()->setCellValue('B3', 8);\n$objPHPExcel->getActiveSheet()->setCellValue('B4', 10);\n$objPHPExcel->getActiveSheet()->setCellValue('B5', True);\n$objPHPExcel->getActiveSheet()->setCellValue('B6', False);\n$objPHPExcel->getActiveSheet()->setCellValue('B7', 'Text String');\n$objPHPExcel->getActiveSheet()->setCellValue('B9', '22');\n$objPHPExcel->getActiveSheet()->setCellValue('B10', 4);\n$objPHPExcel->getActiveSheet()->setCellValue('B11', 6);\n$objPHPExcel->getActiveSheet()->setCellValue('B12', 12);\n\n$objPHPExcel->getActiveSheet()->setCellValue('B14', '=COUNT(B2:B12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('C1', 'Range 2');\n$objPHPExcel->getActiveSheet()->setCellValue('C2', 1);\n$objPHPExcel->getActiveSheet()->setCellValue('C3', 2);\n$objPHPExcel->getActiveSheet()->setCellValue('C4', 2);\n$objPHPExcel->getActiveSheet()->setCellValue('C5', 3);\n$objPHPExcel->getActiveSheet()->setCellValue('C6', 3);\n$objPHPExcel->getActiveSheet()->setCellValue('C7', 3);\n$objPHPExcel->getActiveSheet()->setCellValue('C8', '0');\n$objPHPExcel->getActiveSheet()->setCellValue('C9', 4);\n$objPHPExcel->getActiveSheet()->setCellValue('C10', 4);\n$objPHPExcel->getActiveSheet()->setCellValue('C11', 4);\n$objPHPExcel->getActiveSheet()->setCellValue('C12', 4);\n\n$objPHPExcel->getActiveSheet()->setCellValue('C14', '=COUNT(C2:C12)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('D1', 'Range 3');\n$objPHPExcel->getActiveSheet()->setCellValue('D2', 2);\n$objPHPExcel->getActiveSheet()->setCellValue('D3', 3);\n$objPHPExcel->getActiveSheet()->setCellValue('D4', 4);\n\n$objPHPExcel->getActiveSheet()->setCellValue('D5', '=((D2 * D3) + D4) & \" should be 10\"');\n\n$objPHPExcel->getActiveSheet()->setCellValue('E1', 'Other functions');\n$objPHPExcel->getActiveSheet()->setCellValue('E2', '=PI()');\n$objPHPExcel->getActiveSheet()->setCellValue('E3', '=RAND()');\n$objPHPExcel->getActiveSheet()->setCellValue('E4', '=RANDBETWEEN(5, 10)');\n\n$objPHPExcel->getActiveSheet()->setCellValue('E14', 'Count of both ranges:');\n$objPHPExcel->getActiveSheet()->setCellValue('F14', '=COUNT(B2:C12)');\n\n// Calculated data\necho date('H:i:s') . \" Calculated data\\n\";\necho 'Value of B14 [=COUNT(B2:B12)]: ' . $objPHPExcel->getActiveSheet()->getCell('B14')->getCalculatedValue() . \"\\r\\n\";\n\n\n// Echo memory peak usage\necho date('H:i:s') . \" Peak memory usage: \" . (memory_get_peak_usage(true) / 1024 / 1024) . \" MB\\r\\n\";\n\n// Echo done\necho date('H:i:s') . \" Done\" , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/19namedrange.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Firstname:')\n                              ->setCellValue('A2', 'Lastname:')\n                              ->setCellValue('A3', 'Fullname:')\n                              ->setCellValue('B1', 'Maarten')\n                              ->setCellValue('B2', 'Balliauw')\n                              ->setCellValue('B3', '=B1 & \" \" & B2');\n\n// Define named ranges\necho date('H:i:s') , \" Define named ranges\" , EOL;\n$objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonName', $objPHPExcel->getActiveSheet(), 'B1') );\n$objPHPExcel->addNamedRange( new PHPExcel_NamedRange('PersonLN', $objPHPExcel->getActiveSheet(), 'B2') );\n\n// Rename named ranges\necho date('H:i:s') , \" Rename named ranges\" , EOL;\n$objPHPExcel->getNamedRange('PersonName')->setName('PersonFN');\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Person');\n\n\n// Create a new worksheet, after the default sheet\necho date('H:i:s') , \" Create new Worksheet object\" , EOL;\n$objPHPExcel->createSheet();\n\n// Add some data to the second sheet, resembling some different data types\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(1);\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'Firstname:')\n                              ->setCellValue('A2', 'Lastname:')\n                              ->setCellValue('A3', 'Fullname:')\n                              ->setCellValue('B1', '=PersonFN')\n                              ->setCellValue('B2', '=PersonLN')\n                              ->setCellValue('B3', '=PersonFN & \" \" & PersonLN');\n\n// Resolve range\necho date('H:i:s') , \" Resolve range\" , EOL;\necho 'Cell B1 {=PersonFN}: ' , $objPHPExcel->getActiveSheet()->getCell('B1')->getCalculatedValue() , EOL;\necho 'Cell B3 {=PersonFN & \" \" & PersonLN}: ' , $objPHPExcel->getActiveSheet()->getCell('B3')->getCalculatedValue() , EOL;\necho 'Cell Person!B1: ' , $objPHPExcel->getActiveSheet()->getCell('Person!B1')->getCalculatedValue() , EOL;\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Person (cloned)');\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/20readexcel5.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (C) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n/** Error reporting */\r\nerror_reporting(E_ALL);\r\nini_set('display_errors', TRUE);\r\nini_set('display_startup_errors', TRUE);\r\ndate_default_timezone_set('Europe/London');\r\n\r\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\r\n\r\ndate_default_timezone_set('Europe/London');\r\n\r\n/** Include PHPExcel_IOFactory */\r\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\r\n\r\n\r\nif (!file_exists(\"14excel5.xls\")) {\r\n\texit(\"Please run 14excel5.php first.\\n\");\r\n}\r\n\r\necho date('H:i:s') , \" Load workbook from Excel5 file\" , EOL;\r\n$callStartTime = microtime(true);\r\n\r\n$objPHPExcel = PHPExcel_IOFactory::load(\"14excel5.xls\");\r\n\r\n$callEndTime = microtime(true);\r\n$callTime = $callEndTime - $callStartTime;\r\n\r\necho 'Call time to load Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\r\n// Echo memory usage\r\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\r\n\r\n\r\n// Save Excel 2007 file\r\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\r\n$callStartTime = microtime(true);\r\n\r\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\r\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\r\n$callEndTime = microtime(true);\r\n$callTime = $callEndTime - $callStartTime;\r\n\r\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\r\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\r\n// Echo memory usage\r\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\r\n\r\n\r\n// Echo memory peak usage\r\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\r\n\r\n// Echo done\r\necho date('H:i:s') , \" Done reading file\" , EOL;\r\necho 'File has been created in ' , getcwd() , EOL;\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/21pdf.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\ninclude \"05featuredemo.inc.php\";\n\n/** PHPExcel_IOFactory */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\n\n\n//\tChange these values to select the Rendering library that you wish to use\n//\t\tand its directory location on your server\n//$rendererName = PHPExcel_Settings::PDF_RENDERER_TCPDF;\n//$rendererName = PHPExcel_Settings::PDF_RENDERER_MPDF;\n$rendererName = PHPExcel_Settings::PDF_RENDERER_DOMPDF;\n//$rendererLibrary = 'tcPDF5.9';\n//$rendererLibrary = 'mPDF5.4';\n$rendererLibrary = 'domPDF0.6.0beta3';\n$rendererLibraryPath = '/php/libraries/PDF/' . $rendererLibrary;\n\n\necho date('H:i:s') , \" Hide grid lines\" , EOL;\n$objPHPExcel->getActiveSheet()->setShowGridLines(false);\n\necho date('H:i:s') , \" Set orientation to landscape\" , EOL;\n$objPHPExcel->getActiveSheet()->getPageSetup()->setOrientation(PHPExcel_Worksheet_PageSetup::ORIENTATION_LANDSCAPE);\n\n\necho date('H:i:s') , \" Write to PDF format using {$rendererName}\" , EOL;\n\nif (!PHPExcel_Settings::setPdfRenderer(\n\t\t$rendererName,\n\t\t$rendererLibraryPath\n\t)) {\n\tdie(\n\t\t'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .\n\t\tEOL .\n\t\t'at the top of this script as appropriate for your directory structure'\n\t);\n}\n\n\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF');\n$objWriter->setSheetIndex(0);\n$objWriter->save(str_replace('.php', '_'.$rendererName.'.pdf', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\necho date('H:i:s') , \" File written to \" , str_replace('.php', '_'.$rendererName.'.pdf', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/22heavilyformatted.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n\n$objPHPExcel->getActiveSheet()->getStyle('A1:T100')->applyFromArray(\n\tarray('fill' \t=> array(\n\t\t\t\t\t\t\t\t'type'\t\t=> PHPExcel_Style_Fill::FILL_SOLID,\n\t\t\t\t\t\t\t\t'color'\t\t=> array('argb' => 'FFCCFFCC')\n\t\t\t\t\t\t\t),\n\t\t  'borders' => array(\n\t\t\t\t\t\t\t\t'bottom'\t=> array('style' => PHPExcel_Style_Border::BORDER_THIN),\n\t\t\t\t\t\t\t\t'right'\t\t=> array('style' => PHPExcel_Style_Border::BORDER_MEDIUM)\n\t\t\t\t\t\t\t)\n\t\t )\n\t);\n\n$objPHPExcel->getActiveSheet()->getStyle('C5:R95')->applyFromArray(\n\tarray('fill' \t=> array(\n\t\t\t\t\t\t\t\t'type'\t\t=> PHPExcel_Style_Fill::FILL_SOLID,\n\t\t\t\t\t\t\t\t'color'\t\t=> array('argb' => 'FFFFFF00')\n\t\t\t\t\t\t\t),\n\t\t )\n\t);\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/23sharedstyles.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0);\n\n$sharedStyle1 = new PHPExcel_Style();\n$sharedStyle2 = new PHPExcel_Style();\n\n$sharedStyle1->applyFromArray(\n\tarray('fill' \t=> array(\n\t\t\t\t\t\t\t\t'type'\t\t=> PHPExcel_Style_Fill::FILL_SOLID,\n\t\t\t\t\t\t\t\t'color'\t\t=> array('argb' => 'FFCCFFCC')\n\t\t\t\t\t\t\t),\n\t\t  'borders' => array(\n\t\t\t\t\t\t\t\t'bottom'\t=> array('style' => PHPExcel_Style_Border::BORDER_THIN),\n\t\t\t\t\t\t\t\t'right'\t\t=> array('style' => PHPExcel_Style_Border::BORDER_MEDIUM)\n\t\t\t\t\t\t\t)\n\t\t ));\n\n$sharedStyle2->applyFromArray(\n\tarray('fill' \t=> array(\n\t\t\t\t\t\t\t\t'type'\t\t=> PHPExcel_Style_Fill::FILL_SOLID,\n\t\t\t\t\t\t\t\t'color'\t\t=> array('argb' => 'FFFFFF00')\n\t\t\t\t\t\t\t),\n\t\t  'borders' => array(\n\t\t\t\t\t\t\t\t'bottom'\t=> array('style' => PHPExcel_Style_Border::BORDER_THIN),\n\t\t\t\t\t\t\t\t'right'\t\t=> array('style' => PHPExcel_Style_Border::BORDER_MEDIUM)\n\t\t\t\t\t\t\t)\n\t\t ));\n\n$objPHPExcel->getActiveSheet()->setSharedStyle($sharedStyle1, \"A1:T100\");\n$objPHPExcel->getActiveSheet()->setSharedStyle($sharedStyle2, \"C5:R95\");\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/24readfilter.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** PHPExcel_IOFactory */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\n\n\n// Check prerequisites\nif (!file_exists(\"06largescale.xlsx\")) {\n\texit(\"Please run 06largescale.php first.\\n\");\n}\n\nclass MyReadFilter implements PHPExcel_Reader_IReadFilter\n{\n\tpublic function readCell($column, $row, $worksheetName = '') {\n\t\t// Read title row and rows 20 - 30\n\t\tif ($row == 1 || ($row >= 20 && $row <= 30)) {\n\t\t\treturn true;\n\t\t}\n\n\t\treturn false;\n\t}\n}\n\n\necho date('H:i:s') , \" Load from Excel2007 file\" , EOL;\n$objReader = PHPExcel_IOFactory::createReader('Excel2007');\n$objReader->setReadFilter( new MyReadFilter() );\n$objPHPExcel = $objReader->load(\"06largescale.xlsx\");\n\necho date('H:i:s') , \" Remove unnecessary rows\" , EOL;\n$objPHPExcel->getActiveSheet()->removeRow(2, 18);\n\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/25inmemoryimage.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n// Generate an image\necho date('H:i:s') , \" Generate an image\" , EOL;\n$gdImage = @imagecreatetruecolor(120, 20) or die('Cannot Initialize new GD image stream');\n$textColor = imagecolorallocate($gdImage, 255, 255, 255);\nimagestring($gdImage, 1, 5, 5,  'Created with PHPExcel', $textColor);\n\n// Add a drawing to the worksheet\necho date('H:i:s') , \" Add a drawing to the worksheet\" , EOL;\n$objDrawing = new PHPExcel_Worksheet_MemoryDrawing();\n$objDrawing->setName('Sample image');\n$objDrawing->setDescription('Sample image');\n$objDrawing->setImageResource($gdImage);\n$objDrawing->setRenderingFunction(PHPExcel_Worksheet_MemoryDrawing::RENDERING_JPEG);\n$objDrawing->setMimeType(PHPExcel_Worksheet_MemoryDrawing::MIMETYPE_DEFAULT);\n$objDrawing->setHeight(36);\n$objDrawing->setWorksheet($objPHPExcel->getActiveSheet());\n\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/26utf8.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n//\tChange these values to select the PDF Rendering library that you wish to use\n//\t\tand its directory location on your server\n//$rendererName = PHPExcel_Settings::PDF_RENDERER_TCPDF;\n//$rendererName = PHPExcel_Settings::PDF_RENDERER_MPDF;\n$rendererName = PHPExcel_Settings::PDF_RENDERER_DOMPDF;\n//$rendererLibrary = 'tcPDF5.9';\n//$rendererLibrary = 'mPDF5.4';\n$rendererLibrary = 'domPDF0.6.0beta3';\n$rendererLibraryPath = '/php/libraries/PDF/' . $rendererLibrary;\n\n\n// Read from Excel2007 (.xlsx) template\necho date('H:i:s') , \" Load Excel2007 template file\" , EOL;\n$objReader = PHPExcel_IOFactory::createReader('Excel2007');\n$objPHPExcel = $objReader->load(\"templates/26template.xlsx\");\n\n/** at this point, we could do some manipulations with the template, but we skip this step */\n\n// Export to Excel2007 (.xlsx)\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n// Export to Excel5 (.xls)\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n// Export to HTML (.html)\necho date('H:i:s') , \" Write to HTML format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML');\n$objWriter->save(str_replace('.php', '.htm', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.htm', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n// Export to PDF (.pdf)\necho date('H:i:s') , \" Write to PDF format\" , EOL;\ntry {\n\tif (!PHPExcel_Settings::setPdfRenderer(\n\t\t$rendererName,\n\t\t$rendererLibraryPath\n\t)) {\n\t\techo (\n\t\t\t'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .\n\t\t\tEOL .\n\t\t\t'at the top of this script as appropriate for your directory structure' .\n\t\t\tEOL\n\t\t);\n\t} else {\n\t\t$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF');\n\t\t$objWriter->save(str_replace('.php', '.pdf', __FILE__));\n\t\techo date('H:i:s') , \" File written to \" , str_replace('.php', '.pdf', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\t}\n} catch (Exception $e) {\n\techo date('H:i:s') , ' EXCEPTION: ', $e->getMessage() , EOL;\n}\n\n// Remove first two rows with field headers before exporting to CSV\necho date('H:i:s') , \" Removing first two heading rows for CSV export\" , EOL;\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->removeRow(1, 2);\n\n// Export to CSV (.csv)\necho date('H:i:s') , \" Write to CSV format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');\n$objWriter->save(str_replace('.php', '.csv', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.csv', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n// Export to CSV with BOM (.csv)\necho date('H:i:s') , \" Write to CSV format (with BOM)\" , EOL;\n$objWriter->setUseBOM(true);\n$objWriter->save(str_replace('.php', '-bom.csv', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '-bom.csv', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/27imagesexcel5.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Read from Excel5 (.xls) template\necho date('H:i:s') , \" Load Excel2007 template file\" , EOL;\n$objReader = PHPExcel_IOFactory::createReader('Excel5');\n$objPHPExcel = $objReader->load(\"templates/27template.xls\");\n\n// Export to Excel2007 (.xlsx)\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n// Export to Excel5 (.xls)\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/28iterator.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** PHPExcel_IOFactory */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\n\n\nif (!file_exists(\"05featuredemo.xlsx\")) {\n\texit(\"Please run 05featuredemo.php first.\" . EOL);\n}\n\necho date('H:i:s') , \" Load from Excel2007 file\" , EOL;\n$objReader = PHPExcel_IOFactory::createReader('Excel2007');\n$objPHPExcel = $objReader->load(\"05featuredemo.xlsx\");\n\necho date('H:i:s') , \" Iterate worksheets\" , EOL;\nforeach ($objPHPExcel->getWorksheetIterator() as $worksheet) {\n\techo 'Worksheet - ' , $worksheet->getTitle() , EOL;\n\n\tforeach ($worksheet->getRowIterator() as $row) {\n\t\techo '    Row number - ' , $row->getRowIndex() , EOL;\n\n\t\t$cellIterator = $row->getCellIterator();\n\t\t$cellIterator->setIterateOnlyExistingCells(false); // Loop all cells, even if it is not set\n\t\tforeach ($cellIterator as $cell) {\n\t\t\tif (!is_null($cell)) {\n\t\t\t\techo '        Cell - ' , $cell->getCoordinate() , ' - ' , $cell->getCalculatedValue() , EOL;\n\t\t\t}\n\t\t}\n\t}\n}\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/29advancedvaluebinder.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Set timezone\necho date('H:i:s') , \" Set timezone\" , EOL;\ndate_default_timezone_set('UTC');\n\n// Set value binder\necho date('H:i:s') , \" Set value binder\" , EOL;\nPHPExcel_Cell::setValueBinder( new PHPExcel_Cell_AdvancedValueBinder() );\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for Office 2007 XLSX, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n// Set default font\necho date('H:i:s') , \" Set default font\" , EOL;\n$objPHPExcel->getActiveSheet()->getDefaultStyle()->getFont()->setName('Arial');\n$objPHPExcel->getActiveSheet()->getDefaultStyle()->getFont()->setSize(10);\n\n// Set column widths\necho date('H:i:s') , \" Set column widths\" , EOL;\n$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setAutoSize(true);\n$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(14);\n\n// Add some data, resembling some different data types\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->getActiveSheet()->setCellValue('A1', 'String value:')\n                              ->setCellValue('B1', 'Mark Baker');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A2', 'Numeric value #1:')\n                              ->setCellValue('B2', 12345);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A3', 'Numeric value #2:')\n                              ->setCellValue('B3', -12.345);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A4', 'Numeric value #3:')\n                              ->setCellValue('B4', .12345);\n\n$objPHPExcel->getActiveSheet()->setCellValue('A5', 'Numeric value #4:')\n                              ->setCellValue('B5', '12345');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A6', 'Numeric value #5:')\n                              ->setCellValue('B6', '1.2345');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A7', 'Numeric value #6:')\n                              ->setCellValue('B7', '.12345');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A8', 'Numeric value #7:')\n                              ->setCellValue('B8', '1.234e-5');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A9', 'Numeric value #8:')\n                              ->setCellValue('B9', '-1.234e+5');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A10', 'Boolean value:')\n                              ->setCellValue('B10', 'TRUE');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A11', 'Percentage value #1:')\n                              ->setCellValue('B11', '10%');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A12', 'Percentage value #2:')\n                              ->setCellValue('B12', '12.5%');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A13', 'Fraction value #1:')\n                              ->setCellValue('B13', '-1/2');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A14', 'Fraction value #2:')\n                              ->setCellValue('B14', '3 1/2');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A15', 'Fraction value #3:')\n                              ->setCellValue('B15', '-12 3/4');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A16', 'Fraction value #4:')\n                              ->setCellValue('B16', '13/4');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A17', 'Currency value #1:')\n                              ->setCellValue('B17', '$12345');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A18', 'Currency value #2:')\n                              ->setCellValue('B18', '$12345.67');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A19', 'Currency value #3:')\n                              ->setCellValue('B19', '$12,345.67');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A20', 'Date value #1:')\n                              ->setCellValue('B20', '21 December 1983');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A21', 'Date value #2:')\n                              ->setCellValue('B21', '19-Dec-1960');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A22', 'Date value #3:')\n                              ->setCellValue('B22', '07/12/1982');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A23', 'Date value #4:')\n                              ->setCellValue('B23', '24-11-1950');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A24', 'Date value #5:')\n                              ->setCellValue('B24', '17-Mar');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A25', 'Time value #1:')\n                              ->setCellValue('B25', '01:30');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A26', 'Time value #2:')\n                              ->setCellValue('B26', '01:30:15');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A27', 'Date/Time value:')\n                              ->setCellValue('B27', '19-Dec-1960 01:30');\n\n$objPHPExcel->getActiveSheet()->setCellValue('A28', 'Formula:')\n                              ->setCellValue('B28', '=SUM(B2:B9)');\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Advanced value binder');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n// Save Excel5 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/30template.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (C) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n/** Error reporting */\r\nerror_reporting(E_ALL);\r\nini_set('display_errors', TRUE);\r\nini_set('display_startup_errors', TRUE);\r\n\r\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\r\n\r\ndate_default_timezone_set('Europe/London');\r\n\r\n/** PHPExcel_IOFactory */\r\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\r\n\r\n\r\n\r\necho date('H:i:s') , \" Load from Excel5 template\" , EOL;\r\n$objReader = PHPExcel_IOFactory::createReader('Excel5');\r\n$objPHPExcel = $objReader->load(\"templates/30template.xls\");\r\n\r\n\r\n\r\n\r\necho date('H:i:s') , \" Add new data to the template\" , EOL;\r\n$data = array(array('title'\t\t=> 'Excel for dummies',\r\n\t\t\t\t\t'price'\t\t=> 17.99,\r\n\t\t\t\t\t'quantity'\t=> 2\r\n\t\t\t\t   ),\r\n\t\t\t  array('title'\t\t=> 'PHP for dummies',\r\n\t\t\t\t\t'price'\t\t=> 15.99,\r\n\t\t\t\t\t'quantity'\t=> 1\r\n\t\t\t\t   ),\r\n\t\t\t  array('title'\t\t=> 'Inside OOP',\r\n\t\t\t\t\t'price'\t\t=> 12.95,\r\n\t\t\t\t\t'quantity'\t=> 1\r\n\t\t\t\t   )\r\n\t\t\t );\r\n\r\n$objPHPExcel->getActiveSheet()->setCellValue('D1', PHPExcel_Shared_Date::PHPToExcel(time()));\r\n\r\n$baseRow = 5;\r\nforeach($data as $r => $dataRow) {\r\n\t$row = $baseRow + $r;\r\n\t$objPHPExcel->getActiveSheet()->insertNewRowBefore($row,1);\r\n\r\n\t$objPHPExcel->getActiveSheet()->setCellValue('A'.$row, $r+1)\r\n\t                              ->setCellValue('B'.$row, $dataRow['title'])\r\n\t                              ->setCellValue('C'.$row, $dataRow['price'])\r\n\t                              ->setCellValue('D'.$row, $dataRow['quantity'])\r\n\t                              ->setCellValue('E'.$row, '=C'.$row.'*D'.$row);\r\n}\r\n$objPHPExcel->getActiveSheet()->removeRow($baseRow-1,1);\r\n\r\n\r\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\r\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\r\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\r\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\r\n\r\n\r\n// Echo memory peak usage\r\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\r\n\r\n// Echo done\r\necho date('H:i:s') , \" Done writing file\" , EOL;\r\necho 'File has been created in ' , getcwd() , EOL;\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/31docproperties_write-xls.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (C) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n/** Error reporting */\r\nerror_reporting(E_ALL);\r\nini_set('display_errors', TRUE);\r\nini_set('display_startup_errors', TRUE);\r\n\r\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\r\n\r\ndate_default_timezone_set('Europe/London');\r\n\r\n/** Include PHPExcel */\r\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\r\n\r\n\r\n$inputFileType = 'Excel5';\r\n$inputFileName = 'templates/31docproperties.xls';\r\n\r\n\r\necho date('H:i:s') , \" Load Tests from $inputFileType file\" , EOL;\r\n$callStartTime = microtime(true);\r\n\r\n$objPHPExcelReader = PHPExcel_IOFactory::createReader($inputFileType);\r\n$objPHPExcel = $objPHPExcelReader->load($inputFileName);\r\n\r\n$callEndTime = microtime(true);\r\n$callTime = $callEndTime - $callStartTime;\r\necho 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\r\n// Echo memory usage\r\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\r\n\r\n\r\necho date('H:i:s') , \" Adjust properties\" , EOL;\r\n$objPHPExcel->getProperties()->setTitle(\"Office 95 XLS Test Document\")\r\n\t\t\t\t\t\t\t ->setSubject(\"Office 95 XLS Test Document\")\r\n\t\t\t\t\t\t\t ->setDescription(\"Test XLS document, generated using PHPExcel\")\r\n\t\t\t\t\t\t\t ->setKeywords(\"office 95 biff php\");\r\n\r\n\r\n// Save Excel 95 file\r\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\r\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\r\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\r\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\r\n\r\n\r\n// Echo memory peak usage\r\necho date('H:i:s') , \" Peak memory usage: \" . (memory_get_peak_usage(true) / 1024 / 1024) . \" MB\" , EOL;\r\n\r\n\r\necho EOL;\r\n// Reread File\r\necho date('H:i:s') , \" Reread Excel5 file\" , EOL;\r\n$objPHPExcelRead = PHPExcel_IOFactory::load(str_replace('.php', '.xls', __FILE__));\r\n\r\n// Set properties\r\necho date('H:i:s') , \" Get properties\" , EOL;\r\n\r\necho 'Core Properties:' , EOL;\r\necho '    Created by - ' , $objPHPExcel->getProperties()->getCreator() , EOL;\r\necho '    Created on - ' , date('d-M-Y',$objPHPExcel->getProperties()->getCreated()) , ' at ' ,\r\n                       date('H:i:s',$objPHPExcel->getProperties()->getCreated()) , EOL;\r\necho '    Last Modified by - ' , $objPHPExcel->getProperties()->getLastModifiedBy() , EOL;\r\necho '    Last Modified on - ' , date('d-M-Y',$objPHPExcel->getProperties()->getModified()) , ' at ' ,\r\n                             date('H:i:s',$objPHPExcel->getProperties()->getModified()) , EOL;\r\necho '    Title - ' , $objPHPExcel->getProperties()->getTitle() , EOL;\r\necho '    Subject - ' , $objPHPExcel->getProperties()->getSubject() , EOL;\r\necho '    Description - ' , $objPHPExcel->getProperties()->getDescription() , EOL;\r\necho '    Keywords: - ' , $objPHPExcel->getProperties()->getKeywords() , EOL;\r\n\r\n\r\necho 'Extended (Application) Properties:' , EOL;\r\necho '    Category - ' , $objPHPExcel->getProperties()->getCategory() , EOL;\r\necho '    Company - ' , $objPHPExcel->getProperties()->getCompany() , EOL;\r\necho '    Manager - ' , $objPHPExcel->getProperties()->getManager() , EOL;\r\n\r\n\r\necho 'Custom Properties:' , EOL;\r\n$customProperties = $objPHPExcel->getProperties()->getCustomProperties();\r\nforeach($customProperties as $customProperty) {\r\n\t$propertyValue = $objPHPExcel->getProperties()->getCustomPropertyValue($customProperty);\r\n\t$propertyType = $objPHPExcel->getProperties()->getCustomPropertyType($customProperty);\r\n\techo '    ' , $customProperty , ' - (' , $propertyType , ') - ';\r\n\tif ($propertyType == PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE) {\r\n\t\techo date('d-M-Y H:i:s',$propertyValue) , EOL;\r\n\t} elseif ($propertyType == PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN) {\r\n\t\techo (($propertyValue) ? 'TRUE' : 'FALSE') , EOL;\r\n\t} else {\r\n\t\techo $propertyValue , EOL;\r\n\t}\r\n}\r\n\r\n// Echo memory peak usage\r\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) . \" MB\" , EOL;\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/31docproperties_write.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (C) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n/** Error reporting */\r\nerror_reporting(E_ALL);\r\nini_set('display_errors', TRUE);\r\nini_set('display_startup_errors', TRUE);\r\n\r\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\r\n\r\ndate_default_timezone_set('Europe/London');\r\n\r\n/** Include PHPExcel */\r\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\r\n\r\n\r\n$inputFileType = 'Excel2007';\r\n$inputFileName = 'templates/31docproperties.xlsx';\r\n\r\n\r\necho date('H:i:s') , \" Load Tests from $inputFileType file\" , EOL;\r\n$callStartTime = microtime(true);\r\n\r\n$objPHPExcelReader = PHPExcel_IOFactory::createReader($inputFileType);\r\n$objPHPExcel = $objPHPExcelReader->load($inputFileName);\r\n\r\n$callEndTime = microtime(true);\r\n$callTime = $callEndTime - $callStartTime;\r\necho 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\r\n// Echo memory usage\r\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\r\n\r\n\r\necho date('H:i:s') , \" Adjust properties\" , EOL;\r\n$objPHPExcel->getProperties()->setTitle(\"Office 2007 XLSX Test Document\")\r\n\t\t\t\t\t\t\t ->setSubject(\"Office 2007 XLSX Test Document\")\r\n\t\t\t\t\t\t\t ->setDescription(\"Test XLSX document, generated using PHPExcel\")\r\n\t\t\t\t\t\t\t ->setKeywords(\"office 2007 openxml php\");\r\n\r\n\r\n// Save Excel 2007 file\r\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\r\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\r\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\r\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\r\n\r\n\r\n// Echo memory peak usage\r\necho date('H:i:s') , \" Peak memory usage: \" . (memory_get_peak_usage(true) / 1024 / 1024) . \" MB\" , EOL;\r\n\r\n\r\necho EOL;\r\n// Reread File\r\necho date('H:i:s') , \" Reread Excel2007 file\" , EOL;\r\n$objPHPExcelRead = PHPExcel_IOFactory::load(str_replace('.php', '.xlsx', __FILE__));\r\n\r\n// Set properties\r\necho date('H:i:s') , \" Get properties\" , EOL;\r\n\r\necho 'Core Properties:' , EOL;\r\necho '    Created by - ' , $objPHPExcel->getProperties()->getCreator() , EOL;\r\necho '    Created on - ' , date('d-M-Y',$objPHPExcel->getProperties()->getCreated()) , ' at ' ,\r\n                       date('H:i:s',$objPHPExcel->getProperties()->getCreated()) , EOL;\r\necho '    Last Modified by - ' , $objPHPExcel->getProperties()->getLastModifiedBy() , EOL;\r\necho '    Last Modified on - ' , date('d-M-Y',$objPHPExcel->getProperties()->getModified()) , ' at ' ,\r\n                             date('H:i:s',$objPHPExcel->getProperties()->getModified()) , EOL;\r\necho '    Title - ' , $objPHPExcel->getProperties()->getTitle() , EOL;\r\necho '    Subject - ' , $objPHPExcel->getProperties()->getSubject() , EOL;\r\necho '    Description - ' , $objPHPExcel->getProperties()->getDescription() , EOL;\r\necho '    Keywords: - ' , $objPHPExcel->getProperties()->getKeywords() , EOL;\r\n\r\n\r\necho 'Extended (Application) Properties:' , EOL;\r\necho '    Category - ' , $objPHPExcel->getProperties()->getCategory() , EOL;\r\necho '    Company - ' , $objPHPExcel->getProperties()->getCompany() , EOL;\r\necho '    Manager - ' , $objPHPExcel->getProperties()->getManager() , EOL;\r\n\r\n\r\necho 'Custom Properties:' , EOL;\r\n$customProperties = $objPHPExcel->getProperties()->getCustomProperties();\r\nforeach($customProperties as $customProperty) {\r\n\t$propertyValue = $objPHPExcel->getProperties()->getCustomPropertyValue($customProperty);\r\n\t$propertyType = $objPHPExcel->getProperties()->getCustomPropertyType($customProperty);\r\n\techo '    ' , $customProperty , ' - (' , $propertyType , ') - ';\r\n\tif ($propertyType == PHPExcel_DocumentProperties::PROPERTY_TYPE_DATE) {\r\n\t\techo date('d-M-Y H:i:s',$propertyValue) , EOL;\r\n\t} elseif ($propertyType == PHPExcel_DocumentProperties::PROPERTY_TYPE_BOOLEAN) {\r\n\t\techo (($propertyValue) ? 'TRUE' : 'FALSE') , EOL;\r\n\t} else {\r\n\t\techo $propertyValue , EOL;\r\n\t}\r\n}\r\n\r\n// Echo memory peak usage\r\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) . \" MB\" , EOL;\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/32chartreadwrite.php",
    "content": "<?php\r\n\r\n/** Error reporting */\r\nerror_reporting(E_ALL);\r\nini_set('display_errors', TRUE);\r\nini_set('display_startup_errors', TRUE);\r\ndate_default_timezone_set('Europe/London');\r\n\r\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\r\n\r\ndate_default_timezone_set('Europe/London');\r\n\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (C) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n/** Include path **/\r\nset_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/');\r\n\r\n/** PHPExcel_IOFactory */\r\ninclude 'PHPExcel/IOFactory.php';\r\n\r\n$inputFileType = 'Excel2007';\r\n$inputFileNames = 'templates/32readwrite*[0-9].xlsx';\r\n\r\nif ((isset($argc)) && ($argc > 1)) {\r\n\t$inputFileNames = array();\r\n\tfor($i = 1; $i < $argc; ++$i) {\r\n\t\t$inputFileNames[] = dirname(__FILE__) . '/templates/' . $argv[$i];\r\n\t}\r\n} else {\r\n\t$inputFileNames = glob($inputFileNames);\r\n}\r\nforeach($inputFileNames as $inputFileName) {\r\n\t$inputFileNameShort = basename($inputFileName);\r\n\r\n\tif (!file_exists($inputFileName)) {\r\n\t\techo date('H:i:s') , \" File \" , $inputFileNameShort , ' does not exist' , EOL;\r\n\t\tcontinue;\r\n\t}\r\n\r\n\techo date('H:i:s') , \" Load Test from $inputFileType file \" , $inputFileNameShort , EOL;\r\n\r\n\t$objReader = PHPExcel_IOFactory::createReader($inputFileType);\r\n\t$objReader->setIncludeCharts(TRUE);\r\n\t$objPHPExcel = $objReader->load($inputFileName);\r\n\r\n\r\n\techo date('H:i:s') , \" Iterate worksheets looking at the charts\" , EOL;\r\n\tforeach ($objPHPExcel->getWorksheetIterator() as $worksheet) {\r\n\t\t$sheetName = $worksheet->getTitle();\r\n\t\techo 'Worksheet: ' , $sheetName , EOL;\r\n\r\n\t\t$chartNames = $worksheet->getChartNames();\r\n\t\tif(empty($chartNames)) {\r\n\t\t\techo '    There are no charts in this worksheet' , EOL;\r\n\t\t} else {\r\n\t\t\tnatsort($chartNames);\r\n\t\t\tforeach($chartNames as $i => $chartName) {\r\n\t\t\t\t$chart = $worksheet->getChartByName($chartName);\r\n\t\t\t\tif (!is_null($chart->getTitle())) {\r\n\t\t\t\t\t$caption = '\"' . implode(' ',$chart->getTitle()->getCaption()) . '\"';\r\n\t\t\t\t} else {\r\n\t\t\t\t\t$caption = 'Untitled';\r\n\t\t\t\t}\r\n\t\t\t\techo '    ' , $chartName , ' - ' , $caption , EOL;\r\n\t\t\t\techo str_repeat(' ',strlen($chartName)+3);\r\n\t\t\t\t$groupCount = $chart->getPlotArea()->getPlotGroupCount();\r\n\t\t\t\tif ($groupCount == 1) {\r\n\t\t\t\t\t$chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();\r\n\t\t\t\t\techo '    ' , $chartType , EOL;\r\n\t\t\t\t} else {\r\n\t\t\t\t\t$chartTypes = array();\r\n\t\t\t\t\tfor($i = 0; $i < $groupCount; ++$i) {\r\n\t\t\t\t\t\t$chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();\r\n\t\t\t\t\t}\r\n\t\t\t\t\t$chartTypes = array_unique($chartTypes);\r\n\t\t\t\t\tif (count($chartTypes) == 1) {\r\n\t\t\t\t\t\t$chartType = 'Multiple Plot ' . array_pop($chartTypes);\r\n\t\t\t\t\t\techo '    ' , $chartType , EOL;\r\n\t\t\t\t\t} elseif (count($chartTypes) == 0) {\r\n\t\t\t\t\t\techo '    *** Type not yet implemented' , EOL;\r\n\t\t\t\t\t} else {\r\n\t\t\t\t\t\techo '    Combination Chart' , EOL;\r\n\t\t\t\t\t}\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n\r\n\r\n\t$outputFileName = basename($inputFileName);\r\n\r\n\techo date('H:i:s') , \" Write Tests to Excel2007 file \" , EOL;\r\n\t$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\r\n\t$objWriter->setIncludeCharts(TRUE);\r\n\t$objWriter->save($outputFileName);\r\n\techo date('H:i:s') , \" File written to \" , $outputFileName , EOL;\r\n\r\n\t$objPHPExcel->disconnectWorksheets();\r\n\tunset($objPHPExcel);\r\n}\r\n\r\n// Echo memory peak usage\r\necho date('H:i:s') , ' Peak memory usage: ' , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\r\n\r\n// Echo done\r\necho date('H:i:s') , \" Done writing files\" , EOL;\r\necho 'Files have been created in ' , getcwd() , EOL;\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/33chartcreate-area.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n$objPHPExcel = new PHPExcel();\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->fromArray(\n\tarray(\n\t\tarray('',\t2010,\t2011,\t2012),\n\t\tarray('Q1',   12,   15,\t\t21),\n\t\tarray('Q2',   56,   73,\t\t86),\n\t\tarray('Q3',   52,   61,\t\t69),\n\t\tarray('Q4',   30,   32,\t\t0),\n\t)\n);\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1),\t//\t2010\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),\t//\t2011\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1),\t//\t2012\n);\n//\tSet the X-Axis Labels\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$xAxisTickValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4),\t//\tQ1 to Q4\n);\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),\n);\n\n//\tBuild the dataseries\n$series = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_AREACHART,\t\t\t\t// plotType\n\tPHPExcel_Chart_DataSeries::GROUPING_PERCENT_STACKED,\t// plotGrouping\n\trange(0, count($dataSeriesValues)-1),\t\t\t\t\t// plotOrder\n\t$dataSeriesLabels,\t\t\t\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues,\t\t\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues\t\t\t\t\t\t\t\t\t\t// plotValues\n);\n\n//\tSet the series in the plot area\n$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));\n//\tSet the chart legend\n$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false);\n\n$title = new PHPExcel_Chart_Title('Test %age-Stacked Area Chart');\n$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');\n\n\n//\tCreate the chart\n$chart = new PHPExcel_Chart(\n\t'chart1',\t\t// name\n\t$title,\t\t\t// title\n\t$legend,\t\t// legend\n\t$plotArea,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\tNULL,\t\t\t// xAxisLabel\n\t$yAxisLabel\t\t// yAxisLabel\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart->setTopLeftPosition('A7');\n$chart->setBottomRightPosition('H20');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->setIncludeCharts(TRUE);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/33chartcreate-bar-stacked.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n$objPHPExcel = new PHPExcel();\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->fromArray(\n\tarray(\n\t\tarray('',\t2010,\t2011,\t2012),\n\t\tarray('Q1',   12,   15,\t\t21),\n\t\tarray('Q2',   56,   73,\t\t86),\n\t\tarray('Q3',   52,   61,\t\t69),\n\t\tarray('Q4',   30,   32,\t\t0),\n\t)\n);\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1),\t//\t2010\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),\t//\t2011\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1),\t//\t2012\n);\n//\tSet the X-Axis Labels\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$xAxisTickValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4),\t//\tQ1 to Q4\n);\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),\n);\n\n//\tBuild the dataseries\n$series = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_BARCHART,\t\t// plotType\n\tPHPExcel_Chart_DataSeries::GROUPING_STACKED,\t// plotGrouping\n\trange(0, count($dataSeriesValues)-1),\t\t\t// plotOrder\n\t$dataSeriesLabels,\t\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues,\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues\t\t\t\t\t\t\t\t// plotValues\n);\n//\tSet additional dataseries parameters\n//\t\tMake it a horizontal bar rather than a vertical column graph\n$series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_BAR);\n\n//\tSet the series in the plot area\n$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));\n//\tSet the chart legend\n$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);\n\n$title = new PHPExcel_Chart_Title('Test Chart');\n$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');\n\n\n//\tCreate the chart\n$chart = new PHPExcel_Chart(\n\t'chart1',\t\t// name\n\t$title,\t\t\t// title\n\t$legend,\t\t// legend\n\t$plotArea,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\tNULL,\t\t\t// xAxisLabel\n\t$yAxisLabel\t\t// yAxisLabel\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart->setTopLeftPosition('A7');\n$chart->setBottomRightPosition('H20');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->setIncludeCharts(TRUE);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/33chartcreate-bar.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n$objPHPExcel = new PHPExcel();\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->fromArray(\n\tarray(\n\t\tarray('',\t2010,\t2011,\t2012),\n\t\tarray('Q1',   12,   15,\t\t21),\n\t\tarray('Q2',   56,   73,\t\t86),\n\t\tarray('Q3',   52,   61,\t\t69),\n\t\tarray('Q4',   30,   32,\t\t0),\n\t)\n);\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1),\t//\t2010\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),\t//\t2011\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1),\t//\t2012\n);\n//\tSet the X-Axis Labels\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$xAxisTickValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4),\t//\tQ1 to Q4\n);\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),\n);\n\n//\tBuild the dataseries\n$series = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_BARCHART,\t\t// plotType\n\tPHPExcel_Chart_DataSeries::GROUPING_CLUSTERED,\t// plotGrouping\n\trange(0, count($dataSeriesValues)-1),\t\t\t// plotOrder\n\t$dataSeriesLabels,\t\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues,\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues\t\t\t\t\t\t\t\t// plotValues\n);\n//\tSet additional dataseries parameters\n//\t\tMake it a horizontal bar rather than a vertical column graph\n$series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_BAR);\n\n//\tSet the series in the plot area\n$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));\n//\tSet the chart legend\n$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);\n\n$title = new PHPExcel_Chart_Title('Test Bar Chart');\n$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');\n\n\n//\tCreate the chart\n$chart = new PHPExcel_Chart(\n\t'chart1',\t\t// name\n\t$title,\t\t\t// title\n\t$legend,\t\t// legend\n\t$plotArea,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\tNULL,\t\t\t// xAxisLabel\n\t$yAxisLabel\t\t// yAxisLabel\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart->setTopLeftPosition('A7');\n$chart->setBottomRightPosition('H20');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->setIncludeCharts(TRUE);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/33chartcreate-column-2.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n$objPHPExcel = new PHPExcel();\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->fromArray(\n\tarray(\n\t\tarray('',\t\t'',\t\t'Budget',\t'Forecast',\t'Actual'),\n\t\tarray('2010',\t'Q1',   47,   \t\t44,\t\t\t43\t\t),\n\t\tarray('',\t\t'Q2',   56,   \t\t53,\t\t\t50\t\t),\n\t\tarray('',\t\t'Q3',   52,   \t\t46,\t\t\t45\t\t),\n\t\tarray('',\t\t'Q4',   45,   \t\t40,\t\t\t40\t\t),\n\t\tarray('2011',\t'Q1',   51,   \t\t42,\t\t\t46\t\t),\n\t\tarray('',\t\t'Q2',   53,   \t\t58,\t\t\t56\t\t),\n\t\tarray('',\t\t'Q3',   64,   \t\t66,\t\t\t69\t\t),\n\t\tarray('',\t\t'Q4',   54,   \t\t55,\t\t\t56\t\t),\n\t\tarray('2012',\t'Q1',   49,   \t\t52,\t\t\t58\t\t),\n\t\tarray('',\t\t'Q2',   68,   \t\t73,\t\t\t86\t\t),\n\t\tarray('',\t\t'Q3',   72,   \t\t78,\t\t\t0\t\t),\n\t\tarray('',\t\t'Q4',   50,   \t\t60,\t\t\t0\t\t),\n\t)\n);\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),\t//\t'Budget'\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1),\t//\t'Forecast'\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$E$1', NULL, 1),\t//\t'Actual'\n);\n//\tSet the X-Axis Labels\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$xAxisTickValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$B$13', NULL, 12),\t//\tQ1 to Q4 for 2010 to 2012\n);\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$13', NULL, 12),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$13', NULL, 12),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$E$2:$E$13', NULL, 12),\n);\n\n//\tBuild the dataseries\n$series = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_BARCHART,\t\t// plotType\n\tPHPExcel_Chart_DataSeries::GROUPING_CLUSTERED,\t// plotGrouping\n\trange(0, count($dataSeriesValues)-1),\t\t\t// plotOrder\n\t$dataSeriesLabels,\t\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues,\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues\t\t\t\t\t\t\t\t// plotValues\n);\n//\tSet additional dataseries parameters\n//\t\tMake it a vertical column rather than a horizontal bar graph\n$series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_COL);\n\n//\tSet the series in the plot area\n$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));\n//\tSet the chart legend\n$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_BOTTOM, NULL, false);\n\n$title = new PHPExcel_Chart_Title('Test Grouped Column Chart');\n$xAxisLabel = new PHPExcel_Chart_Title('Financial Period');\n$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');\n\n\n//\tCreate the chart\n$chart = new PHPExcel_Chart(\n\t'chart1',\t\t// name\n\t$title,\t\t\t// title\n\t$legend,\t\t// legend\n\t$plotArea,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\t$xAxisLabel,\t// xAxisLabel\n\t$yAxisLabel\t\t// yAxisLabel\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart->setTopLeftPosition('G2');\n$chart->setBottomRightPosition('P20');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->setIncludeCharts(TRUE);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/33chartcreate-column.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n$objPHPExcel = new PHPExcel();\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->fromArray(\n\tarray(\n\t\tarray('',\t2010,\t2011,\t2012),\n\t\tarray('Q1',   12,   15,\t\t21),\n\t\tarray('Q2',   56,   73,\t\t86),\n\t\tarray('Q3',   52,   61,\t\t69),\n\t\tarray('Q4',   30,   32,\t\t0),\n\t)\n);\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1),\t//\t2010\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),\t//\t2011\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1),\t//\t2012\n);\n//\tSet the X-Axis Labels\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$xAxisTickValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4),\t//\tQ1 to Q4\n);\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),\n);\n\n//\tBuild the dataseries\n$series = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_BARCHART,\t\t// plotType\n\tPHPExcel_Chart_DataSeries::GROUPING_STANDARD,\t// plotGrouping\n\trange(0, count($dataSeriesValues)-1),\t\t\t// plotOrder\n\t$dataSeriesLabels,\t\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues,\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues\t\t\t\t\t\t\t\t// plotValues\n);\n//\tSet additional dataseries parameters\n//\t\tMake it a vertical column rather than a horizontal bar graph\n$series->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_COL);\n\n//\tSet the series in the plot area\n$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));\n//\tSet the chart legend\n$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);\n\n$title = new PHPExcel_Chart_Title('Test Column Chart');\n$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');\n\n\n//\tCreate the chart\n$chart = new PHPExcel_Chart(\n\t'chart1',\t\t// name\n\t$title,\t\t\t// title\n\t$legend,\t\t// legend\n\t$plotArea,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\tNULL,\t\t\t// xAxisLabel\n\t$yAxisLabel\t\t// yAxisLabel\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart->setTopLeftPosition('A7');\n$chart->setBottomRightPosition('H20');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->setIncludeCharts(TRUE);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/33chartcreate-composite.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n$objPHPExcel = new PHPExcel();\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->fromArray(\n\tarray(\n\t\tarray('',\t\t'Rainfall (mm)',\t'Temperature (°F)',\t'Humidity (%)'),\n\t\tarray('Jan',\t\t78,   \t\t\t\t52,\t\t\t\t\t61),\n\t\tarray('Feb',\t\t64,   \t\t\t\t54,\t\t\t\t\t62),\n\t\tarray('Mar',\t\t62,   \t\t\t\t57,\t\t\t\t\t63),\n\t\tarray('Apr',\t\t21,   \t\t\t\t62,\t\t\t\t\t59),\n\t\tarray('May',\t\t11,   \t\t\t\t75,\t\t\t\t\t60),\n\t\tarray('Jun',\t\t1,   \t\t\t\t75,\t\t\t\t\t57),\n\t\tarray('Jul',\t\t1,   \t\t\t\t79,\t\t\t\t\t56),\n\t\tarray('Aug',\t\t1,   \t\t\t\t79,\t\t\t\t\t59),\n\t\tarray('Sep',\t\t10,   \t\t\t\t75,\t\t\t\t\t60),\n\t\tarray('Oct',\t\t40,   \t\t\t\t68,\t\t\t\t\t63),\n\t\tarray('Nov',\t\t69,   \t\t\t\t62,\t\t\t\t\t64),\n\t\tarray('Dec',\t\t89,   \t\t\t\t57,\t\t\t\t\t66),\n\t)\n);\n\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels1 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1),\t//\tTemperature\n);\n$dataSeriesLabels2 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),\t//\tRainfall\n);\n$dataSeriesLabels3 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1),\t//\tHumidity\n);\n\n//\tSet the X-Axis Labels\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$xAxisTickValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$13', NULL, 12),\t//\tJan to Dec\n);\n\n\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues1 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$13', NULL, 12),\n);\n\n//\tBuild the dataseries\n$series1 = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_BARCHART,\t\t// plotType\n\tPHPExcel_Chart_DataSeries::GROUPING_CLUSTERED,\t// plotGrouping\n\trange(0, count($dataSeriesValues1)-1),\t\t\t// plotOrder\n\t$dataSeriesLabels1,\t\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues,\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues1\t\t\t\t\t\t\t\t// plotValues\n);\n//\tSet additional dataseries parameters\n//\t\tMake it a vertical column rather than a horizontal bar graph\n$series1->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_COL);\n\n\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues2 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$13', NULL, 12),\n);\n\n//\tBuild the dataseries\n$series2 = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_LINECHART,\t\t// plotType\n\tPHPExcel_Chart_DataSeries::GROUPING_STANDARD,\t// plotGrouping\n\trange(0, count($dataSeriesValues2)-1),\t\t\t// plotOrder\n\t$dataSeriesLabels2,\t\t\t\t\t\t\t\t// plotLabel\n\tNULL,\t\t\t\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues2\t\t\t\t\t\t\t\t// plotValues\n);\n\n\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues3 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$13', NULL, 12),\n);\n\n//\tBuild the dataseries\n$series3 = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_AREACHART,\t\t// plotType\n\tPHPExcel_Chart_DataSeries::GROUPING_STANDARD,\t// plotGrouping\n\trange(0, count($dataSeriesValues2)-1),\t\t\t// plotOrder\n\t$dataSeriesLabels3,\t\t\t\t\t\t\t\t// plotLabel\n\tNULL,\t\t\t\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues3\t\t\t\t\t\t\t\t// plotValues\n);\n\n\n//\tSet the series in the plot area\n$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series1, $series2, $series3));\n//\tSet the chart legend\n$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);\n\n$title = new PHPExcel_Chart_Title('Average Weather Chart for Crete');\n\n\n//\tCreate the chart\n$chart = new PHPExcel_Chart(\n\t'chart1',\t\t// name\n\t$title,\t\t\t// title\n\t$legend,\t\t// legend\n\t$plotArea,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\tNULL,\t\t\t// xAxisLabel\n\tNULL\t\t\t// yAxisLabel\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart->setTopLeftPosition('F2');\n$chart->setBottomRightPosition('O16');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->setIncludeCharts(TRUE);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/33chartcreate-line.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n$objPHPExcel = new PHPExcel();\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->fromArray(\n\tarray(\n\t\tarray('',\t2010,\t2011,\t2012),\n\t\tarray('Q1',   12,   15,\t\t21),\n\t\tarray('Q2',   56,   73,\t\t86),\n\t\tarray('Q3',   52,   61,\t\t69),\n\t\tarray('Q4',   30,   32,\t\t0),\n\t)\n);\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1),\t//\t2010\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),\t//\t2011\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1),\t//\t2012\n);\n//\tSet the X-Axis Labels\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$xAxisTickValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4),\t//\tQ1 to Q4\n);\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),\n);\n\n//\tBuild the dataseries\n$series = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_LINECHART,\t\t// plotType\n\tPHPExcel_Chart_DataSeries::GROUPING_STACKED,\t// plotGrouping\n\trange(0, count($dataSeriesValues)-1),\t\t\t// plotOrder\n\t$dataSeriesLabels,\t\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues,\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues\t\t\t\t\t\t\t\t// plotValues\n);\n\n//\tSet the series in the plot area\n$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));\n//\tSet the chart legend\n$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false);\n\n$title = new PHPExcel_Chart_Title('Test Stacked Line Chart');\n$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');\n\n\n//\tCreate the chart\n$chart = new PHPExcel_Chart(\n\t'chart1',\t\t// name\n\t$title,\t\t\t// title\n\t$legend,\t\t// legend\n\t$plotArea,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\tNULL,\t\t\t// xAxisLabel\n\t$yAxisLabel\t\t// yAxisLabel\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart->setTopLeftPosition('A7');\n$chart->setBottomRightPosition('H20');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->setIncludeCharts(TRUE);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/33chartcreate-multiple-charts.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n$objPHPExcel = new PHPExcel();\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->fromArray(\n\tarray(\n\t\tarray('',\t2010,\t2011,\t2012),\n\t\tarray('Q1',   12,   15,\t\t21),\n\t\tarray('Q2',   56,   73,\t\t86),\n\t\tarray('Q3',   52,   61,\t\t69),\n\t\tarray('Q4',   30,   32,\t\t0),\n\t)\n);\n\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels1 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1),\t//\t2010\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),\t//\t2011\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1),\t//\t2012\n);\n//\tSet the X-Axis Labels\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$xAxisTickValues1 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4),\t//\tQ1 to Q4\n);\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues1 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),\n);\n\n//\tBuild the dataseries\n$series1 = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_AREACHART,\t\t\t\t// plotType\n\tPHPExcel_Chart_DataSeries::GROUPING_PERCENT_STACKED,\t// plotGrouping\n\trange(0, count($dataSeriesValues1)-1),\t\t\t\t\t// plotOrder\n\t$dataSeriesLabels1,\t\t\t\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues1,\t\t\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues1\t\t\t\t\t\t\t\t\t\t// plotValues\n);\n\n//\tSet the series in the plot area\n$plotArea1 = new PHPExcel_Chart_PlotArea(NULL, array($series1));\n//\tSet the chart legend\n$legend1 = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false);\n\n$title1 = new PHPExcel_Chart_Title('Test %age-Stacked Area Chart');\n$yAxisLabel1 = new PHPExcel_Chart_Title('Value ($k)');\n\n\n//\tCreate the chart\n$chart1 = new PHPExcel_Chart(\n\t'chart1',\t\t// name\n\t$title1,\t\t// title\n\t$legend1,\t\t// legend\n\t$plotArea1,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\tNULL,\t\t\t// xAxisLabel\n\t$yAxisLabel1\t// yAxisLabel\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart1->setTopLeftPosition('A7');\n$chart1->setBottomRightPosition('H20');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart1);\n\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels2 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1),\t//\t2010\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),\t//\t2011\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1),\t//\t2012\n);\n//\tSet the X-Axis Labels\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$xAxisTickValues2 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4),\t//\tQ1 to Q4\n);\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues2 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),\n);\n\n//\tBuild the dataseries\n$series2 = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_BARCHART,\t\t// plotType\n\tPHPExcel_Chart_DataSeries::GROUPING_STANDARD,\t// plotGrouping\n\trange(0, count($dataSeriesValues2)-1),\t\t\t// plotOrder\n\t$dataSeriesLabels2,\t\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues2,\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues2\t\t\t\t\t\t\t\t// plotValues\n);\n//\tSet additional dataseries parameters\n//\t\tMake it a vertical column rather than a horizontal bar graph\n$series2->setPlotDirection(PHPExcel_Chart_DataSeries::DIRECTION_COL);\n\n//\tSet the series in the plot area\n$plotArea2 = new PHPExcel_Chart_PlotArea(NULL, array($series2));\n//\tSet the chart legend\n$legend2 = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);\n\n$title2 = new PHPExcel_Chart_Title('Test Column Chart');\n$yAxisLabel2 = new PHPExcel_Chart_Title('Value ($k)');\n\n\n//\tCreate the chart\n$chart2 = new PHPExcel_Chart(\n\t'chart2',\t\t// name\n\t$title2,\t\t// title\n\t$legend2,\t\t// legend\n\t$plotArea2,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\tNULL,\t\t\t// xAxisLabel\n\t$yAxisLabel2\t// yAxisLabel\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart2->setTopLeftPosition('I7');\n$chart2->setBottomRightPosition('P20');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart2);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->setIncludeCharts(TRUE);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/33chartcreate-pie.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n$objPHPExcel = new PHPExcel();\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->fromArray(\n\tarray(\n\t\tarray('',\t2010,\t2011,\t2012),\n\t\tarray('Q1',   12,   15,\t\t21),\n\t\tarray('Q2',   56,   73,\t\t86),\n\t\tarray('Q3',   52,   61,\t\t69),\n\t\tarray('Q4',   30,   32,\t\t0),\n\t)\n);\n\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels1 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),\t//\t2011\n);\n//\tSet the X-Axis Labels\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$xAxisTickValues1 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4),\t//\tQ1 to Q4\n);\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues1 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),\n);\n\n//\tBuild the dataseries\n$series1 = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_PIECHART,\t\t\t\t// plotType\n\tNULL,\t\t\t                                        // plotGrouping (Pie charts don't have any grouping)\n\trange(0, count($dataSeriesValues1)-1),\t\t\t\t\t// plotOrder\n\t$dataSeriesLabels1,\t\t\t\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues1,\t\t\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues1\t\t\t\t\t\t\t\t\t\t// plotValues\n);\n\n//\tSet up a layout object for the Pie chart\n$layout1 = new PHPExcel_Chart_Layout();\n$layout1->setShowVal(TRUE);\n$layout1->setShowPercent(TRUE);\n\n//\tSet the series in the plot area\n$plotArea1 = new PHPExcel_Chart_PlotArea($layout1, array($series1));\n//\tSet the chart legend\n$legend1 = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);\n\n$title1 = new PHPExcel_Chart_Title('Test Pie Chart');\n\n\n//\tCreate the chart\n$chart1 = new PHPExcel_Chart(\n\t'chart1',\t\t// name\n\t$title1,\t\t// title\n\t$legend1,\t\t// legend\n\t$plotArea1,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\tNULL,\t\t\t// xAxisLabel\n\tNULL\t\t\t// yAxisLabel\t\t- Pie charts don't have a Y-Axis\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart1->setTopLeftPosition('A7');\n$chart1->setBottomRightPosition('H20');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart1);\n\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels2 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),\t//\t2011\n);\n//\tSet the X-Axis Labels\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$xAxisTickValues2 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4),\t//\tQ1 to Q4\n);\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues2 = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),\n);\n\n//\tBuild the dataseries\n$series2 = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_DONUTCHART,\t\t// plotType\n\tNULL,\t\t\t                                // plotGrouping (Donut charts don't have any grouping)\n\trange(0, count($dataSeriesValues2)-1),\t\t\t// plotOrder\n\t$dataSeriesLabels2,\t\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues2,\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues2\t\t\t\t\t\t\t\t// plotValues\n);\n\n//\tSet up a layout object for the Pie chart\n$layout2 = new PHPExcel_Chart_Layout();\n$layout2->setShowVal(TRUE);\n$layout2->setShowCatName(TRUE);\n\n//\tSet the series in the plot area\n$plotArea2 = new PHPExcel_Chart_PlotArea($layout2, array($series2));\n\n$title2 = new PHPExcel_Chart_Title('Test Donut Chart');\n\n\n//\tCreate the chart\n$chart2 = new PHPExcel_Chart(\n\t'chart2',\t\t// name\n\t$title2,\t\t// title\n\tNULL,\t\t\t// legend\n\t$plotArea2,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\tNULL,\t\t\t// xAxisLabel\n\tNULL\t\t\t// yAxisLabel\t\t- Like Pie charts, Donut charts don't have a Y-Axis\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart2->setTopLeftPosition('I7');\n$chart2->setBottomRightPosition('P20');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart2);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->setIncludeCharts(TRUE);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/33chartcreate-radar.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n$objPHPExcel = new PHPExcel();\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->fromArray(\n\tarray(\n\t\tarray('',\t2010,\t2011,\t2012),\n\t\tarray('Jan',   47,   45,\t\t71),\n\t\tarray('Feb',   56,   73,\t\t86),\n\t\tarray('Mar',   52,   61,\t\t69),\n\t\tarray('Apr',   40,   52,\t\t60),\n\t\tarray('May',   42,   55,\t\t71),\n\t\tarray('Jun',   58,   63,\t\t76),\n\t\tarray('Jul',   53,   61,\t\t89),\n\t\tarray('Aug',   46,   69,\t\t85),\n\t\tarray('Sep',   62,   75,\t\t81),\n\t\tarray('Oct',   51,   70,\t\t96),\n\t\tarray('Nov',   55,   66,\t\t89),\n\t\tarray('Dec',   68,   62,\t\t0),\n\t)\n);\n\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),\t//\t2011\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1),\t//\t2012\n);\n//\tSet the X-Axis Labels\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$xAxisTickValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$13', NULL, 12),\t//\tJan to Dec\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$13', NULL, 12),\t//\tJan to Dec\n);\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$13', NULL, 12),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$13', NULL, 12),\n);\n\n//\tBuild the dataseries\n$series = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_RADARCHART,\t\t\t\t// plotType\n\tNULL,\t\t\t\t\t\t\t\t\t\t\t\t\t// plotGrouping (Radar charts don't have any grouping)\n\trange(0, count($dataSeriesValues)-1),\t\t\t\t\t// plotOrder\n\t$dataSeriesLabels,\t\t\t\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues,\t\t\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues,\t\t\t\t\t\t\t\t\t\t// plotValues\n\tNULL,\t\t\t\t\t\t\t\t\t\t\t\t\t// smooth line\n\tPHPExcel_Chart_DataSeries::STYLE_MARKER\t\t\t\t\t// plotStyle\n);\n\n//\tSet up a layout object for the Pie chart\n$layout = new PHPExcel_Chart_Layout();\n\n//\tSet the series in the plot area\n$plotArea = new PHPExcel_Chart_PlotArea($layout, array($series));\n//\tSet the chart legend\n$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);\n\n$title = new PHPExcel_Chart_Title('Test Radar Chart');\n\n\n//\tCreate the chart\n$chart = new PHPExcel_Chart(\n\t'chart1',\t\t// name\n\t$title,\t\t\t// title\n\t$legend,\t\t// legend\n\t$plotArea,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\tNULL,\t\t\t// xAxisLabel\n\tNULL\t\t\t// yAxisLabel\t\t- Radar charts don't have a Y-Axis\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart->setTopLeftPosition('F2');\n$chart->setBottomRightPosition('M15');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->setIncludeCharts(TRUE);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/33chartcreate-scatter.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n$objPHPExcel = new PHPExcel();\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->fromArray(\n\tarray(\n\t\tarray('',\t2010,\t2011,\t2012),\n\t\tarray('Q1',   12,   15,\t\t21),\n\t\tarray('Q2',   56,   73,\t\t86),\n\t\tarray('Q3',   52,   61,\t\t69),\n\t\tarray('Q4',   30,   32,\t\t0),\n\t)\n);\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1),\t//\t2010\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1),\t//\t2011\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1),\t//\t2012\n);\n//\tSet the X-Axis Labels\n$xAxisTickValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$5', NULL, 4),\t//\tQ1 to Q4\n);\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$5', NULL, 4),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$5', NULL, 4),\n);\n\n//\tBuild the dataseries\n$series = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_SCATTERCHART,\t// plotType\n\tNULL,\t\t\t\t\t\t\t\t\t\t\t// plotGrouping (Scatter charts don't have any grouping)\n\trange(0, count($dataSeriesValues)-1),\t\t\t// plotOrder\n\t$dataSeriesLabels,\t\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues,\t\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues,\t\t\t\t\t\t\t\t// plotValues\n\tNULL,\t\t\t\t\t\t\t\t\t\t\t// smooth line\n\tPHPExcel_Chart_DataSeries::STYLE_LINEMARKER\t\t// plotStyle\n);\n\n//\tSet the series in the plot area\n$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));\n//\tSet the chart legend\n$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_TOPRIGHT, NULL, false);\n\n$title = new PHPExcel_Chart_Title('Test Scatter Chart');\n$yAxisLabel = new PHPExcel_Chart_Title('Value ($k)');\n\n\n//\tCreate the chart\n$chart = new PHPExcel_Chart(\n\t'chart1',\t\t// name\n\t$title,\t\t\t// title\n\t$legend,\t\t// legend\n\t$plotArea,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\tNULL,\t\t\t// xAxisLabel\n\t$yAxisLabel\t\t// yAxisLabel\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart->setTopLeftPosition('A7');\n$chart->setBottomRightPosition('H20');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->setIncludeCharts(TRUE);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/33chartcreate-stock.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n$objPHPExcel = new PHPExcel();\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->fromArray(\n\tarray(\n\t\tarray('Counts', \t\t'Max', \t\t'Min', \t\t'Min Threshold', \t'Max Threshold'\t),\n\t\tarray(10,\t\t \t\t10, \t\t5, \t\t\t0, \t\t\t\t\t50\t\t\t\t),\n\t\tarray(30,\t\t \t\t20, \t\t10, \t\t0,\t \t\t\t\t50\t\t\t\t),\n\t\tarray(20,\t\t \t\t30, \t\t15, \t\t0,\t \t\t\t\t50\t\t\t\t),\n\t\tarray(40,\t\t \t\t10, \t\t0, \t\t\t0, \t\t\t\t\t50\t\t\t\t),\n\t\tarray(100,\t\t \t\t40, \t\t5, \t\t\t0, \t\t\t\t\t50\t\t\t\t),\n\t), null, 'A1', true\n);\n$objWorksheet->getStyle('B2:E6')->getNumberFormat()->setFormatCode(PHPExcel_Style_NumberFormat::FORMAT_NUMBER_00);\n\n\n//\tSet the Labels for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesLabels = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$B$1', NULL, 1), //Max / Open\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$C$1', NULL, 1), //Min / Close\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$D$1', NULL, 1), //Min Threshold / Min\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$E$1', NULL, 1), //Max Threshold / Max\n);\n//\tSet the X-Axis Labels\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$xAxisTickValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('String', 'Worksheet!$A$2:$A$6', NULL, 5),\t//\tCounts\n);\n//\tSet the Data values for each data series we want to plot\n//\t\tDatatype\n//\t\tCell reference for data\n//\t\tFormat Code\n//\t\tNumber of datapoints in series\n//\t\tData values\n//\t\tData Marker\n$dataSeriesValues = array(\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$B$2:$B$6', NULL, 5),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$C$2:$C$6', NULL, 5),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$D$2:$D$6', NULL, 5),\n\tnew PHPExcel_Chart_DataSeriesValues('Number', 'Worksheet!$E$2:$E$6', NULL, 5),\n);\n\n//\tBuild the dataseries\n$series = new PHPExcel_Chart_DataSeries(\n\tPHPExcel_Chart_DataSeries::TYPE_STOCKCHART,\t// plotType\n\tnull,\t\t\t\t\t\t\t\t\t\t// plotGrouping - if we set this to not null, then xlsx throws error\n\trange(0, count($dataSeriesValues)-1),\t\t// plotOrder\n\t$dataSeriesLabels,\t\t\t\t\t\t\t// plotLabel\n\t$xAxisTickValues,\t\t\t\t\t\t\t// plotCategory\n\t$dataSeriesValues\t\t\t\t\t\t\t// plotValues\n);\n\n//\tSet the series in the plot area\n$plotArea = new PHPExcel_Chart_PlotArea(NULL, array($series));\n//\tSet the chart legend\n$legend = new PHPExcel_Chart_Legend(PHPExcel_Chart_Legend::POSITION_RIGHT, NULL, false);\n\n$title = new PHPExcel_Chart_Title('Test Stock Chart');\n$xAxisLabel = new PHPExcel_Chart_Title('Counts');\n$yAxisLabel = new PHPExcel_Chart_Title('Values');\n\n//\tCreate the chart\n$chart = new PHPExcel_Chart(\n\t'stock-chart',\t// name\n\t$title,\t\t\t// title\n\t$legend,\t\t// legend\n\t$plotArea,\t\t// plotArea\n\ttrue,\t\t\t// plotVisibleOnly\n\t0,\t\t\t\t// displayBlanksAs\n\t$xAxisLabel,\t// xAxisLabel\n\t$yAxisLabel\t\t// yAxisLabel\n);\n\n//\tSet the position where the chart should appear in the worksheet\n$chart->setTopLeftPosition('A7');\n$chart->setBottomRightPosition('H20');\n\n//\tAdd the chart to the worksheet\n$objWorksheet->addChart($chart);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->setIncludeCharts(TRUE);\n$filename = str_replace('.php', '.xlsx', __FILE__);\nif(file_exists($filename)) {\n\tunlink($filename);\n}\n$objWriter->save($filename);\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/34chartupdate.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\nif (!file_exists(\"33chartcreate-bar.xlsx\")) {\n\texit(\"Please run 33chartcreate-bar.php first.\" . EOL);\n}\n\necho date('H:i:s') , \" Load from Excel2007 file\" , EOL;\n$objReader = PHPExcel_IOFactory::createReader(\"Excel2007\");\n$objReader->setIncludeCharts(TRUE);\n$objPHPExcel = $objReader->load(\"33chartcreate-bar.xlsx\");\n\n\necho date('H:i:s') , \" Update cell data values that are displayed in the chart\" , EOL;\n$objWorksheet = $objPHPExcel->getActiveSheet();\n$objWorksheet->fromArray(\n\tarray(\n\t\tarray(50-12,   50-15,\t\t50-21),\n\t\tarray(50-56,   50-73,\t\t50-86),\n\t\tarray(50-52,   50-61,\t\t50-69),\n\t\tarray(50-30,   50-32,\t\t50),\n\t),\n\tNULL,\n\t'B2'\n);\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->setIncludeCharts(TRUE);\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/35chartrender.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Include path **/\nset_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/');\n\n/** PHPExcel_IOFactory */\ninclude 'PHPExcel/IOFactory.php';\n\n\n//\tChange these values to select the Rendering library that you wish to use\n//\t\tand its directory location on your server\n$rendererName = PHPExcel_Settings::CHART_RENDERER_JPGRAPH;\n$rendererLibrary = 'jpgraph3.5.0b1/src/';\n$rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary;\n\n\nif (!PHPExcel_Settings::setChartRenderer(\n\t\t$rendererName,\n\t\t$rendererLibraryPath\n\t)) {\n\tdie(\n\t\t'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .\n\t\tEOL .\n\t\t'at the top of this script as appropriate for your directory structure'\n\t);\n}\n\n\n$inputFileType = 'Excel2007';\n$inputFileNames = 'templates/32readwrite*[0-9].xlsx';\n\n\tif ((isset($argc)) && ($argc > 1)) {\n\t$inputFileNames = array();\n\tfor($i = 1; $i < $argc; ++$i) {\n\t\t$inputFileNames[] = dirname(__FILE__) . '/templates/' . $argv[$i];\n\t}\n} else {\n\t$inputFileNames = glob($inputFileNames);\n}\nforeach($inputFileNames as $inputFileName) {\n\t$inputFileNameShort = basename($inputFileName);\n\n\tif (!file_exists($inputFileName)) {\n\t\techo date('H:i:s') , \" File \" , $inputFileNameShort , ' does not exist' , EOL;\n\t\tcontinue;\n\t}\n\n\techo date('H:i:s') , \" Load Test from $inputFileType file \" , $inputFileNameShort , EOL;\n\n\t$objReader = PHPExcel_IOFactory::createReader($inputFileType);\n\t$objReader->setIncludeCharts(TRUE);\n\t$objPHPExcel = $objReader->load($inputFileName);\n\n\n\techo date('H:i:s') , \" Iterate worksheets looking at the charts\" , EOL;\n\tforeach ($objPHPExcel->getWorksheetIterator() as $worksheet) {\n\t\t$sheetName = $worksheet->getTitle();\n\t\techo 'Worksheet: ' , $sheetName , EOL;\n\n\t\t$chartNames = $worksheet->getChartNames();\n\t\tif(empty($chartNames)) {\n\t\t\techo '    There are no charts in this worksheet' , EOL;\n\t\t} else {\n\t\t\tnatsort($chartNames);\n\t\t\tforeach($chartNames as $i => $chartName) {\n\t\t\t\t$chart = $worksheet->getChartByName($chartName);\n\t\t\t\tif (!is_null($chart->getTitle())) {\n\t\t\t\t\t$caption = '\"' . implode(' ',$chart->getTitle()->getCaption()) . '\"';\n\t\t\t\t} else {\n\t\t\t\t\t$caption = 'Untitled';\n\t\t\t\t}\n\t\t\t\techo '    ' , $chartName , ' - ' , $caption , EOL;\n\t\t\t\techo str_repeat(' ',strlen($chartName)+3);\n\n\t\t\t\t$jpegFile = '35'.str_replace('.xlsx', '.jpg', substr($inputFileNameShort,2));\n\t\t\t\tif (file_exists($jpegFile)) {\n\t\t\t\t\tunlink($jpegFile);\n\t\t\t\t}\n\t\t\t\ttry {\n\t\t\t\t\t$chart->render($jpegFile);\n\t\t\t\t} catch (Exception $e) {\n\t\t\t\t\techo 'Error rendering chart: ',$e->getMessage();\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\n\t$objPHPExcel->disconnectWorksheets();\n\tunset($objPHPExcel);\n}\n\n// Echo memory peak usage\necho date('H:i:s') , ' Peak memory usage: ' , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done rendering charts as images\" , EOL;\necho 'Image files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/36chartreadwriteHTML.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Include path **/\nset_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/');\n\n/** PHPExcel_IOFactory */\ninclude 'PHPExcel/IOFactory.php';\n\n\n//\tChange these values to select the Rendering library that you wish to use\n//\t\tand its directory location on your server\n$rendererName = PHPExcel_Settings::CHART_RENDERER_JPGRAPH;\n$rendererLibrary = 'jpgraph3.5.0b1/src';\n$rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary;\n\n\nif (!PHPExcel_Settings::setChartRenderer(\n\t\t$rendererName,\n\t\t$rendererLibraryPath\n\t)) {\n\tdie(\n\t\t'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .\n\t\tEOL .\n\t\t'at the top of this script as appropriate for your directory structure'\n\t);\n}\n\n\n$inputFileType = 'Excel2007';\n$inputFileNames = 'templates/36write*.xlsx';\n\nif ((isset($argc)) && ($argc > 1)) {\n\t$inputFileNames = array();\n\tfor($i = 1; $i < $argc; ++$i) {\n\t\t$inputFileNames[] = dirname(__FILE__) . '/templates/' . $argv[$i];\n\t}\n} else {\n\t$inputFileNames = glob($inputFileNames);\n}\nforeach($inputFileNames as $inputFileName) {\n\t$inputFileNameShort = basename($inputFileName);\n\n\tif (!file_exists($inputFileName)) {\n\t\techo date('H:i:s') , \" File \" , $inputFileNameShort , ' does not exist' , EOL;\n\t\tcontinue;\n\t}\n\n\techo date('H:i:s') , \" Load Test from $inputFileType file \" , $inputFileNameShort , EOL;\n\n\t$objReader = PHPExcel_IOFactory::createReader($inputFileType);\n\t$objReader->setIncludeCharts(TRUE);\n\t$objPHPExcel = $objReader->load($inputFileName);\n\n\n\techo date('H:i:s') , \" Iterate worksheets looking at the charts\" , EOL;\n\tforeach ($objPHPExcel->getWorksheetIterator() as $worksheet) {\n\t\t$sheetName = $worksheet->getTitle();\n\t\techo 'Worksheet: ' , $sheetName , EOL;\n\n\t\t$chartNames = $worksheet->getChartNames();\n\t\tif(empty($chartNames)) {\n\t\t\techo '    There are no charts in this worksheet' , EOL;\n\t\t} else {\n\t\t\tnatsort($chartNames);\n\t\t\tforeach($chartNames as $i => $chartName) {\n\t\t\t\t$chart = $worksheet->getChartByName($chartName);\n\t\t\t\tif (!is_null($chart->getTitle())) {\n\t\t\t\t\t$caption = '\"' . implode(' ',$chart->getTitle()->getCaption()) . '\"';\n\t\t\t\t} else {\n\t\t\t\t\t$caption = 'Untitled';\n\t\t\t\t}\n\t\t\t\techo '    ' , $chartName , ' - ' , $caption , EOL;\n\t\t\t\techo str_repeat(' ',strlen($chartName)+3);\n\t\t\t\t$groupCount = $chart->getPlotArea()->getPlotGroupCount();\n\t\t\t\tif ($groupCount == 1) {\n\t\t\t\t\t$chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();\n\t\t\t\t\techo '    ' , $chartType , EOL;\n\t\t\t\t} else {\n\t\t\t\t\t$chartTypes = array();\n\t\t\t\t\tfor($i = 0; $i < $groupCount; ++$i) {\n\t\t\t\t\t\t$chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();\n\t\t\t\t\t}\n\t\t\t\t\t$chartTypes = array_unique($chartTypes);\n\t\t\t\t\tif (count($chartTypes) == 1) {\n\t\t\t\t\t\t$chartType = 'Multiple Plot ' . array_pop($chartTypes);\n\t\t\t\t\t\techo '    ' , $chartType , EOL;\n\t\t\t\t\t} elseif (count($chartTypes) == 0) {\n\t\t\t\t\t\techo '    *** Type not yet implemented' , EOL;\n\t\t\t\t\t} else {\n\t\t\t\t\t\techo '    Combination Chart' , EOL;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\n\t$outputFileName = str_replace('.xlsx', '.html', basename($inputFileName));\n\n\techo date('H:i:s') , \" Write Tests to HTML file \" , EOL;\n\t$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'HTML');\n\t$objWriter->setIncludeCharts(TRUE);\n\t$objWriter->save($outputFileName);\n\techo date('H:i:s') , \" File written to \" , $outputFileName , EOL;\n\n\t$objPHPExcel->disconnectWorksheets();\n\tunset($objPHPExcel);\n}\n\n// Echo memory peak usage\necho date('H:i:s') , ' Peak memory usage: ' , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/36chartreadwritePDF.php",
    "content": "<?php\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Include path **/\nset_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/');\n\n/** PHPExcel_IOFactory */\ninclude 'PHPExcel/IOFactory.php';\n\n\n//\tChange these values to select the Rendering library that you wish to use\n//\t\tfor PDF files, and its directory location on your server\n//$rendererName = PHPExcel_Settings::PDF_RENDERER_TCPDF;\n$rendererName = PHPExcel_Settings::PDF_RENDERER_MPDF;\n//$rendererName = PHPExcel_Settings::PDF_RENDERER_DOMPDF;\n//$rendererLibrary = 'tcPDF5.9';\n$rendererLibrary = 'mPDF5.4';\n//$rendererLibrary = 'domPDF0.6.0beta3';\n$rendererLibraryPath = '/php/libraries/PDF/' . $rendererLibrary;\n\n\nif (!PHPExcel_Settings::setPdfRenderer(\n\t\t$rendererName,\n\t\t$rendererLibraryPath\n\t)) {\n\tdie(\n\t\t'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .\n\t\tEOL .\n\t\t'at the top of this script as appropriate for your directory structure'\n\t);\n}\n\n\n//\tChange these values to select the Rendering library that you wish to use\n//\t\tfor Chart images, and its directory location on your server\n$rendererName = PHPExcel_Settings::CHART_RENDERER_JPGRAPH;\n$rendererLibrary = 'jpgraph3.5.0b1/src';\n$rendererLibraryPath = '/php/libraries/Charts/' . $rendererLibrary;\n\n\nif (!PHPExcel_Settings::setChartRenderer(\n\t\t$rendererName,\n\t\t$rendererLibraryPath\n\t)) {\n\tdie(\n\t\t'NOTICE: Please set the $rendererName and $rendererLibraryPath values' .\n\t\tEOL .\n\t\t'at the top of this script as appropriate for your directory structure'\n\t);\n}\n\n\n$inputFileType = 'Excel2007';\n$inputFileNames = 'templates/36write*.xlsx';\n\nif ((isset($argc)) && ($argc > 1)) {\n\t$inputFileNames = array();\n\tfor($i = 1; $i < $argc; ++$i) {\n\t\t$inputFileNames[] = dirname(__FILE__) . '/templates/' . $argv[$i];\n\t}\n} else {\n\t$inputFileNames = glob($inputFileNames);\n}\nforeach($inputFileNames as $inputFileName) {\n\t$inputFileNameShort = basename($inputFileName);\n\n\tif (!file_exists($inputFileName)) {\n\t\techo date('H:i:s') , \" File \" , $inputFileNameShort , ' does not exist' , EOL;\n\t\tcontinue;\n\t}\n\n\techo date('H:i:s') , \" Load Test from $inputFileType file \" , $inputFileNameShort , EOL;\n\n\t$objReader = PHPExcel_IOFactory::createReader($inputFileType);\n\t$objReader->setIncludeCharts(TRUE);\n\t$objPHPExcel = $objReader->load($inputFileName);\n\n\n\techo date('H:i:s') , \" Iterate worksheets looking at the charts\" , EOL;\n\tforeach ($objPHPExcel->getWorksheetIterator() as $worksheet) {\n\t\t$sheetName = $worksheet->getTitle();\n\t\techo 'Worksheet: ' , $sheetName , EOL;\n\n\t\t$chartNames = $worksheet->getChartNames();\n\t\tif(empty($chartNames)) {\n\t\t\techo '    There are no charts in this worksheet' , EOL;\n\t\t} else {\n\t\t\tnatsort($chartNames);\n\t\t\tforeach($chartNames as $i => $chartName) {\n\t\t\t\t$chart = $worksheet->getChartByName($chartName);\n\t\t\t\tif (!is_null($chart->getTitle())) {\n\t\t\t\t\t$caption = '\"' . implode(' ',$chart->getTitle()->getCaption()) . '\"';\n\t\t\t\t} else {\n\t\t\t\t\t$caption = 'Untitled';\n\t\t\t\t}\n\t\t\t\techo '    ' , $chartName , ' - ' , $caption , EOL;\n\t\t\t\techo str_repeat(' ',strlen($chartName)+3);\n\t\t\t\t$groupCount = $chart->getPlotArea()->getPlotGroupCount();\n\t\t\t\tif ($groupCount == 1) {\n\t\t\t\t\t$chartType = $chart->getPlotArea()->getPlotGroupByIndex(0)->getPlotType();\n\t\t\t\t\techo '    ' , $chartType , EOL;\n\t\t\t\t} else {\n\t\t\t\t\t$chartTypes = array();\n\t\t\t\t\tfor($i = 0; $i < $groupCount; ++$i) {\n\t\t\t\t\t\t$chartTypes[] = $chart->getPlotArea()->getPlotGroupByIndex($i)->getPlotType();\n\t\t\t\t\t}\n\t\t\t\t\t$chartTypes = array_unique($chartTypes);\n\t\t\t\t\tif (count($chartTypes) == 1) {\n\t\t\t\t\t\t$chartType = 'Multiple Plot ' . array_pop($chartTypes);\n\t\t\t\t\t\techo '    ' , $chartType , EOL;\n\t\t\t\t\t} elseif (count($chartTypes) == 0) {\n\t\t\t\t\t\techo '    *** Type not yet implemented' , EOL;\n\t\t\t\t\t} else {\n\t\t\t\t\t\techo '    Combination Chart' , EOL;\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\n\t$outputFileName = str_replace('.xlsx', '.pdf', basename($inputFileName));\n\n\techo date('H:i:s') , \" Write Tests to HTML file \" , EOL;\n\t$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'PDF');\n\t$objWriter->setIncludeCharts(TRUE);\n\t$objWriter->save($outputFileName);\n\techo date('H:i:s') , \" File written to \" , $outputFileName , EOL;\n\n\t$objPHPExcel->disconnectWorksheets();\n\tunset($objPHPExcel);\n}\n\n// Echo memory peak usage\necho date('H:i:s') , ' Peak memory usage: ' , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/37page_layout_view.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"PHPOffice\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"PHPOffice\")\n\t\t\t\t\t\t\t ->setTitle(\"PHPExcel Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"PHPExcel Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for PHPExcel, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"Office PHPExcel php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A1', 'Hello')\n            ->setCellValue('B2', 'world!');\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n// Set the page layout view as page layout\n$objPHPExcel->getActiveSheet()->getSheetView()->setView(PHPExcel_Worksheet_SheetView::SHEETVIEW_PAGE_LAYOUT);\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n// Save Excel5 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/38cloneWorksheet.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"PHPExcel Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"PHPExcel Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for PHPExcel, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office PHPExcel php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\necho date('H:i:s') , \" Add some data\" , EOL;\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A1', 'Hello')\n            ->setCellValue('B2', 'world!')\n            ->setCellValue('C1', 'Hello')\n            ->setCellValue('D2', 'world!');\n\n// Miscellaneous glyphs, UTF-8\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A4', 'Miscellaneous glyphs')\n            ->setCellValue('A5', 'éàèùâêîôûëïüÿäöüç');\n\n\n$objPHPExcel->getActiveSheet()->setCellValue('A8',\"Hello\\nWorld\");\n$objPHPExcel->getActiveSheet()->getRowDimension(8)->setRowHeight(-1);\n$objPHPExcel->getActiveSheet()->getStyle('A8')->getAlignment()->setWrapText(true);\n\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Simple');\n\n\n// Clone worksheet\necho date('H:i:s') , \" Clone worksheet\" , EOL;\n$clonedSheet = clone $objPHPExcel->getActiveSheet();\n$clonedSheet\n    ->setCellValue('A1', 'Goodbye')\n    ->setCellValue('A2', 'cruel')\n    ->setCellValue('C1', 'Goodbye')\n    ->setCellValue('C2', 'cruel');\n\n// Rename cloned worksheet\necho date('H:i:s') , \" Rename cloned worksheet\" , EOL;\n$clonedSheet->setTitle('Simple Clone');\n$objPHPExcel->addSheet($clonedSheet);\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/39dropdown.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()\n    ->setCreator(\"PHPOffice\")\n\t->setLastModifiedBy(\"PHPOffice\")\n\t->setTitle(\"PHPExcel Test Document\")\n\t->setSubject(\"PHPExcel Test Document\")\n\t->setDescription(\"Test document for PHPExcel, generated using PHP classes.\")\n\t->setKeywords(\"Office PHPExcel php\")\n\t->setCategory(\"Test result file\");\n\n\nfunction transpose($value) {\n    return array($value);\n}\n\n// Add some data\n$continentColumn = 'D';\n$column = 'F';\n\n// Set data for dropdowns\nforeach(glob('./data/continents/*') as $key => $filename) {\n    $continent = pathinfo($filename, PATHINFO_FILENAME);\n    echo \"Loading $continent\", EOL;\n    $continent = str_replace(' ','_',$continent);\n    $countries = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);\n    $countryCount = count($countries);\n\n    // Transpose $countries from a row to a column array\n    $countries = array_map('transpose', $countries);\n    $objPHPExcel->getActiveSheet()\n        ->fromArray($countries, null, $column . '1');\n    $objPHPExcel->addNamedRange(\n        new PHPExcel_NamedRange(\n            $continent, \n            $objPHPExcel->getActiveSheet(), $column . '1:' . $column . $countryCount\n        )\n    );\n    $objPHPExcel->getActiveSheet()\n        ->getColumnDimension($column)\n        ->setVisible(false);\n\n    $objPHPExcel->getActiveSheet()\n        ->setCellValue($continentColumn . ($key+1), $continent);\n\n    ++$column;\n}\n\n// Hide the dropdown data\n$objPHPExcel->getActiveSheet()\n    ->getColumnDimension($continentColumn)\n    ->setVisible(false);\n\n$objPHPExcel->addNamedRange(\n    new PHPExcel_NamedRange(\n        'Continents', \n        $objPHPExcel->getActiveSheet(), $continentColumn . '1:' . $continentColumn . ($key+1)\n    )\n);\n\n\n// Set selection cells\n$objPHPExcel->getActiveSheet()\n    ->setCellValue('A1', 'Continent:');\n$objPHPExcel->getActiveSheet()\n    ->setCellValue('B1', 'Select continent');\n$objPHPExcel->getActiveSheet()\n    ->setCellValue('B3', '=' . $column . 1);\n$objPHPExcel->getActiveSheet()\n    ->setCellValue('B3', 'Select country');\n$objPHPExcel->getActiveSheet()\n    ->getStyle('A1:A3')\n    ->getFont()->setBold(true);\n\n// Set linked validators\n$objValidation = $objPHPExcel->getActiveSheet()\n    ->getCell('B1')\n    ->getDataValidation();\n$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST )\n    ->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION )\n    ->setAllowBlank(false)\n    ->setShowInputMessage(true)\n    ->setShowErrorMessage(true)\n    ->setShowDropDown(true)\n    ->setErrorTitle('Input error')\n    ->setError('Continent is not in the list.')\n    ->setPromptTitle('Pick from the list')\n    ->setPrompt('Please pick a continent from the drop-down list.')\n    ->setFormula1('=Continents');\n\n$objPHPExcel->getActiveSheet()\n    ->setCellValue('A3', 'Country:');\n$objPHPExcel->getActiveSheet()\n    ->getStyle('A3')\n    ->getFont()->setBold(true);\n\n$objValidation = $objPHPExcel->getActiveSheet()\n    ->getCell('B3')\n    ->getDataValidation();\n$objValidation->setType( PHPExcel_Cell_DataValidation::TYPE_LIST )\n    ->setErrorStyle( PHPExcel_Cell_DataValidation::STYLE_INFORMATION )\n    ->setAllowBlank(false)\n    ->setShowInputMessage(true)\n    ->setShowErrorMessage(true)\n    ->setShowDropDown(true)\n    ->setErrorTitle('Input error')\n    ->setError('Country is not in the list.')\n    ->setPromptTitle('Pick from the list')\n    ->setPrompt('Please pick a country from the drop-down list.')\n    ->setFormula1('=INDIRECT($B$1)');\n\n\n$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(12);\n$objPHPExcel->getActiveSheet()->getColumnDimension('B')->setWidth(30);\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n// Save Excel 2007 file\n// This linked validation list method only seems to work for Excel2007, not for Excel5\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/40duplicateStyle.php",
    "content": "<?php\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n$worksheet = $objPHPExcel->getActiveSheet();\n\necho date('H:i:s') , \" Create styles array\" , EOL;\n$styles = array();\nfor ($i = 0; $i < 10; $i++) {\n    $style = new PHPExcel_Style();\n    $style->getFont()->setSize($i + 4);\n    $styles[] = $style;\n}\n\necho date('H:i:s') , \" Add data (begin)\" , EOL;\n$t = microtime(true);\nfor ($col = 0; $col < 50; $col++) {\n    for ($row = 0; $row < 100; $row++) {\n        $str = ($row + $col);\n        $style = $styles[$row % 10];\n        $coord = PHPExcel_Cell::stringFromColumnIndex($col) . ($row + 1);\n        $worksheet->setCellValue($coord, $str);\n        $worksheet->duplicateStyle($style, $coord);\n    }\n}\n$d = microtime(true) - $t;\necho date('H:i:s') , \" Add data (end), time: \" . round($d, 2) . \" s\", EOL;\n\n\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\n\n\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\necho date('H:i:s') , \" Done writing file\" , EOL;\necho 'File has been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/41password.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\ndate_default_timezone_set('Europe/London');\n\ninclude \"05featuredemo.inc.php\";\n\n/** Include PHPExcel_IOFactory */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\n\n\n// Set password against the spreadsheet file\n$objPHPExcel->getSecurity()->setLockWindows(true);\n$objPHPExcel->getSecurity()->setLockStructure(true);\n$objPHPExcel->getSecurity()->setWorkbookPassword('secret');\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/42richText.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\nini_set('display_errors', TRUE);\nini_set('display_startup_errors', TRUE);\ndate_default_timezone_set('Europe/London');\n\ndefine('EOL',(PHP_SAPI == 'cli') ? PHP_EOL : '<br />');\n\n/** Include PHPExcel */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel.php';\n\n\n// Create new PHPExcel object\necho date('H:i:s') , \" Create new PHPExcel object\" , EOL;\n$objPHPExcel = new PHPExcel();\n\n// Set document properties\necho date('H:i:s') , \" Set document properties\" , EOL;\n$objPHPExcel->getProperties()->setCreator(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setLastModifiedBy(\"Maarten Balliauw\")\n\t\t\t\t\t\t\t ->setTitle(\"PHPExcel Test Document\")\n\t\t\t\t\t\t\t ->setSubject(\"PHPExcel Test Document\")\n\t\t\t\t\t\t\t ->setDescription(\"Test document for PHPExcel, generated using PHP classes.\")\n\t\t\t\t\t\t\t ->setKeywords(\"office PHPExcel php\")\n\t\t\t\t\t\t\t ->setCategory(\"Test result file\");\n\n\n// Add some data\necho date('H:i:s') , \" Add some data\" , EOL;\n\n$html1='<font color=\"#0000ff\">\n<h1 align=\"center\">My very first example of rich text<br />generated from html markup</h1>\n<p>\n<font size=\"14\" COLOR=\"rgb(0,255,128)\">\n<b>This block</b> contains an <i>italicized</i> word;\nwhile this block uses an <u>underline</u>.\n</font>\n</p>\n<p align=\"right\"><font size=\"9\" color=\"red\">\nI want to eat <ins><del>healthy food</del><strong>pizza</strong></ins>.\n</font>\n';\n\n$html2='<p>\n<font color=\"#ff0000\">\n    100&deg;C is a hot temperature\n</font>\n<br>\n<font color=\"#0080ff\">\n    10&deg;F is cold\n</font>\n</p>';\n\n$html3='2<sup>3</sup> equals 8';\n\n$html4='H<sub>2</sub>SO<sub>4</sub> is the chemical formula for Sulphuric acid';\n\n\n$wizard = new PHPExcel_Helper_HTML;\n$richText = $wizard->toRichTextObject($html1);\n\n$objPHPExcel->setActiveSheetIndex(0)\n    ->setCellValue('A1', $richText);\n\n$objPHPExcel->getActiveSheet()->getColumnDimension('A')->setWidth(48);\n$objPHPExcel->getActiveSheet()->getRowDimension(1)->setRowHeight(-1);\n$objPHPExcel->getActiveSheet()->getStyle('A1')\n    ->getAlignment()\n    ->setWrapText(true);\n\n$richText = $wizard->toRichTextObject($html2);\n\n$objPHPExcel->setActiveSheetIndex(0)\n    ->setCellValue('A2', $richText);\n\n$objPHPExcel->getActiveSheet()->getRowDimension(1)->setRowHeight(-1);\n$objPHPExcel->getActiveSheet()->getStyle('A2')\n    ->getAlignment()\n    ->setWrapText(true);\n\n$objPHPExcel->setActiveSheetIndex(0)\n            ->setCellValue('A3', $wizard->toRichTextObject($html3));\n\n$objPHPExcel->setActiveSheetIndex(0)\n    ->setCellValue('A4', $wizard->toRichTextObject($html4));\n\n\n// Rename worksheet\necho date('H:i:s') , \" Rename worksheet\" , EOL;\n$objPHPExcel->getActiveSheet()->setTitle('Simple');\n\n\n// Set active sheet index to the first sheet, so Excel opens this as the first sheet\n$objPHPExcel->setActiveSheetIndex(0);\n\n\n// Save Excel 2007 file\necho date('H:i:s') , \" Write to Excel2007 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Save Excel 95 file\necho date('H:i:s') , \" Write to Excel5 format\" , EOL;\n$callStartTime = microtime(true);\n\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\n\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', pathinfo(__FILE__, PATHINFO_BASENAME)) , EOL;\necho 'Call time to write Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing files\" , EOL;\necho 'Files have been created in ' , getcwd() , EOL;\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/Excel2003XMLReader.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (C) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n/** Error reporting */\r\nerror_reporting(E_ALL);\r\n\r\ndate_default_timezone_set('Europe/London');\r\n\r\n/** PHPExcel_IOFactory */\r\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\r\n\r\n\r\necho date('H:i:s') , \" Load from Excel2003XML file\" , PHP_EOL;\r\n$callStartTime = microtime(true);\r\n\r\n$objReader = PHPExcel_IOFactory::createReader('Excel2003XML');\r\n$objPHPExcel = $objReader->load(\"Excel2003XMLTest.xml\");\r\n\r\n\r\n$callEndTime = microtime(true);\r\n$callTime = $callEndTime - $callStartTime;\r\necho 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , PHP_EOL;\r\n// Echo memory usage\r\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , PHP_EOL;\r\n\r\n\r\necho date('H:i:s') , \" Write to Excel5 format\" , PHP_EOL;\r\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');\r\n$objWriter->save(str_replace('.php', '.xls', __FILE__));\r\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xls', __FILE__) , PHP_EOL;\r\n\r\n\r\n// Echo memory peak usage\r\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , PHP_EOL;\r\n\r\n// Echo done\r\necho date('H:i:s') , \" Done writing file\" , PHP_EOL;\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/Excel2003XMLTest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><?mso-application progid=\"Excel.Sheet\"?><Workbook xmlns:c=\"urn:schemas-microsoft-com:office:component:spreadsheet\" xmlns:html=\"http://www.w3.org/TR/REC-html40\" xmlns:o=\"urn:schemas-microsoft-com:office:office\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\" xmlns:x2=\"http://schemas.microsoft.com/office/excel/2003/xml\" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"><OfficeDocumentSettings xmlns=\"urn:schemas-microsoft-com:office:office\"><Colors><Color><Index>3</Index><RGB>#000000</RGB></Color><Color><Index>4</Index><RGB>#0000ff</RGB></Color><Color><Index>5</Index><RGB>#008000</RGB></Color><Color><Index>6</Index><RGB>#00ccff</RGB></Color><Color><Index>7</Index><RGB>#800080</RGB></Color><Color><Index>8</Index><RGB>#993366</RGB></Color><Color><Index>9</Index><RGB>#c0c0c0</RGB></Color><Color><Index>10</Index><RGB>#c47512</RGB></Color><Color><Index>11</Index><RGB>#ccffcc</RGB></Color><Color><Index>12</Index><RGB>#ddbc7d</RGB></Color><Color><Index>13</Index><RGB>#ff0000</RGB></Color><Color><Index>14</Index><RGB>#ff00ff</RGB></Color><Color><Index>15</Index><RGB>#ff6600</RGB></Color><Color><Index>16</Index><RGB>#ff9900</RGB></Color><Color><Index>17</Index><RGB>#ff99cc</RGB></Color><Color><Index>18</Index><RGB>#ffff00</RGB></Color></Colors></OfficeDocumentSettings><ExcelWorkbook xmlns=\"urn:schemas-microsoft-com:office:excel\"><WindowHeight>9000</WindowHeight><WindowWidth>13860</WindowWidth><WindowTopX>240</WindowTopX><WindowTopY>75</WindowTopY><ProtectStructure>False</ProtectStructure><ProtectWindows>False</ProtectWindows></ExcelWorkbook><Styles><Style ss:ID=\"Default\" ss:Name=\"Default\"/><Style ss:ID=\"Result\" ss:Name=\"Result\"><Font ss:Bold=\"1\" ss:Italic=\"1\" ss:Underline=\"Single\"/></Style><Style ss:ID=\"Result2\" ss:Name=\"Result2\"><Font ss:Bold=\"1\" ss:Italic=\"1\" ss:Underline=\"Single\"/><NumberFormat ss:Format=\"Currency\"/></Style><Style ss:ID=\"Heading\" ss:Name=\"Heading\"><Font ss:Bold=\"1\" ss:Italic=\"1\" ss:Size=\"16\"/></Style><Style ss:ID=\"Heading1\" ss:Name=\"Heading1\"><Font ss:Bold=\"1\" ss:Italic=\"1\" ss:Size=\"16\"/></Style><Style ss:ID=\"Gnumeric-default\" ss:Name=\"Gnumeric-default\"><Font ss:Color=\"#000000\" ss:FontName=\"Sans\" ss:Size=\"10\"/></Style><Style ss:ID=\"co1\"/><Style ss:ID=\"co2\"/><Style ss:ID=\"co3\"/><Style ss:ID=\"co4\"/><Style ss:ID=\"co5\"/><Style ss:ID=\"co6\"/><Style ss:ID=\"co7\"/><Style ss:ID=\"co8\"/><Style ss:ID=\"co9\"/><Style ss:ID=\"ta1\"/><Style ss:ID=\"ce1\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Bold=\"1\" ss:Color=\"#ff0000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce2\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Bold=\"1\" ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Italic=\"1\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce3\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\" ss:Underline=\"Single\"/></Style><Style ss:ID=\"ce4\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce5\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce6\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\" ss:Underline=\"Single\"/></Style><Style ss:ID=\"ce7\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\" ss:Underline=\"Double\"/></Style><Style ss:ID=\"ce8\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\" ss:StrikeThrough=\"1\"/></Style><Style ss:ID=\"ce9\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/><NumberFormat ss:Format=\"Short Date\"/></Style><Style ss:ID=\"ce10\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/><NumberFormat ss:Format=\"Fixed\"/></Style><Style ss:ID=\"ce11\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/><NumberFormat ss:Format=\"Short Time\"/></Style><Style ss:ID=\"ce12\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/><NumberFormat ss:Format=\"General Date\"/></Style><Style ss:ID=\"ce13\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Sans\" ss:Size=\"10\"/></Style><Style ss:ID=\"ce14\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Sans\" ss:Size=\"10\" ss:Underline=\"Single\"/></Style><Style ss:ID=\"ce15\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Sans\" ss:Size=\"10\" ss:Underline=\"Double\"/></Style><Style ss:ID=\"ce16\"><Alignment ss:Vertical=\"Bottom\" ss:WrapText=\"1\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Sans\" ss:Size=\"10\"/></Style><Style ss:ID=\"ce17\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#0000ff\" ss:FontName=\"Sans\" ss:Size=\"10\" ss:Underline=\"Single\"/></Style><Style ss:ID=\"ce18\"><Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Center\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"3\" ss:Color=\"#00b050\"/><Border ss:Position=\"Left\" ss:LineStyle=\"Continuous\" ss:Weight=\"3\" ss:Color=\"#0070c0\"/><Border ss:Position=\"Right\" ss:LineStyle=\"Continuous\" ss:Weight=\"3\" ss:Color=\"#ffff00\"/><Border ss:Position=\"Top\" ss:LineStyle=\"Continuous\" ss:Weight=\"3\" ss:Color=\"#ff0000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce19\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Top\" ss:LineStyle=\"Continuous\" ss:Weight=\"2\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce20\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"2\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce21\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Left\" ss:LineStyle=\"Continuous\" ss:Weight=\"2\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce22\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Right\" ss:LineStyle=\"Continuous\" ss:Weight=\"2\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce23\"><Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Center\" ss:Rotate=\"90\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Sans\" ss:Size=\"10\"/></Style><Style ss:ID=\"ce24\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/><NumberFormat ss:Format=\"General\"/></Style><Style ss:ID=\"ce25\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/><NumberFormat ss:Format=\"General\"/></Style><Style ss:ID=\"ce26\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Bold=\"1\" ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce27\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Italic=\"1\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce28\"><Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Center\" ss:Rotate=\"45\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Sans\" ss:Size=\"10\"/></Style><Style ss:ID=\"ce29\"><Alignment ss:Vertical=\"Top\" ss:WrapText=\"1\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce30\"><Alignment ss:Vertical=\"Bottom\" ss:WrapText=\"1\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce31\"><Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Center\" ss:Rotate=\"-90\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Sans\" ss:Size=\"10\"/></Style><Style ss:ID=\"ce32\"><Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Center\" ss:WrapText=\"1\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce33\"><Alignment ss:Vertical=\"Bottom\" ss:WrapText=\"1\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce34\"><Alignment ss:Vertical=\"Bottom\" ss:WrapText=\"1\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce35\"><Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Center\" ss:Rotate=\"-45\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Sans\" ss:Size=\"10\"/></Style><Style ss:ID=\"ce36\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce37\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/><Interior ss:Color=\"#ff0000\" ss:Pattern=\"Solid\"/></Style><Style ss:ID=\"ce38\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/><Interior ss:Color=\"#ff9900\" ss:Pattern=\"Solid\"/></Style><Style ss:ID=\"ce39\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/><Interior ss:Color=\"#ffff00\" ss:Pattern=\"Solid\"/></Style><Style ss:ID=\"ce40\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/><Interior ss:Color=\"#008000\" ss:Pattern=\"Solid\"/></Style><Style ss:ID=\"ce41\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/><Interior ss:Color=\"#0000ff\" ss:Pattern=\"Solid\"/></Style><Style ss:ID=\"ce42\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/><Interior ss:Color=\"#993366\" ss:Pattern=\"Solid\"/></Style><Style ss:ID=\"ce43\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/><Interior ss:Color=\"#ff99cc\" ss:Pattern=\"Solid\"/></Style><Style ss:ID=\"ce44\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/><Interior ss:Color=\"#ddbc7d\" ss:Pattern=\"Solid\"/></Style><Style ss:ID=\"ce45\"><Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Center\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/><Interior ss:Color=\"#00ccff\" ss:Pattern=\"Solid\"/></Style><Style ss:ID=\"ce46\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#ff0000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce47\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#ff6600\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce48\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#ffff00\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce49\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#008000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce50\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#0000ff\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce51\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#800080\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce52\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#ff00ff\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce53\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#c47512\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce54\"><Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Center\" ss:WrapText=\"1\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#ccffcc\" ss:FontName=\"Calibri\" ss:Size=\"11\"/><Interior ss:Color=\"#ff0000\" ss:Pattern=\"Solid\"/></Style><Style ss:ID=\"ce55\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce56\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce57\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce58\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"1\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce59\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"2\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce60\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"2\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce61\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"2\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce62\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"2\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce63\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"2\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce64\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"3\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce65\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders><Border ss:Position=\"Bottom\" ss:LineStyle=\"Double\" ss:Weight=\"3\" ss:Color=\"#000000\"/></Borders><Font ss:Color=\"#000000\" ss:FontName=\"Calibri\" ss:Size=\"11\"/></Style><Style ss:ID=\"ce66\"><Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Bottom\" ss:WrapText=\"1\" ss:Rotate=\"0\"/><Borders/><Font ss:Bold=\"1\" ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"12\"/></Style><Style ss:ID=\"ce67\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/><NumberFormat ss:Format=\"General\"/></Style><Style ss:ID=\"ce68\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/><NumberFormat ss:Format=\"Medium Date\"/></Style><Style ss:ID=\"ce69\"><Alignment ss:Vertical=\"Bottom\" ss:Rotate=\"0\"/><Borders/><Font ss:Color=\"#000000\" ss:FontName=\"Arial1\" ss:Size=\"11\"/><NumberFormat ss:Format=\"Medium Time\"/></Style><Style ss:ID=\"gr1\"/><Style ss:ID=\"gr2\"/><Style ss:ID=\"ta_extref\"/><Style ss:ID=\"P1\"><Font ss:FontName=\"Sans\" ss:Size=\"10\"/></Style><Style ss:ID=\"T1\"/></Styles><ss:Worksheet ss:Name=\"Sample Data\"><Table ss:StyleID=\"ta1\"><Column ss:Width=\"96.4913\"/><Column ss:Span=\"1\" ss:Width=\"48.3874\"/><Column ss:Index=\"4\" ss:Width=\"35.8866\"/><Column ss:Span=\"6\" ss:Width=\"48.3874\"/><Column ss:Index=\"12\" ss:Width=\"50.2583\"/><Column ss:Span=\"1011\" ss:Width=\"48.3874\"/><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce1\"><ss:Data xmlns=\"http://www.w3.org/TR/REC-html40\" ss:Type=\"String\">Test String 1</ss:Data><Comment><ss:Data xmlns=\"http://www.w3.org/TR/REC-html40\"><Font html:Face=\"Sans\" html:Size=\"10\">Test for a simple colour-formatted string</Font></ss:Data></Comment></Cell><Cell ss:StyleID=\"ce4\"><Data ss:Type=\"Number\">1</Data></Cell><Cell ss:StyleID=\"ce4\"><Data ss:Type=\"Number\">5</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce2\"><Data ss:Type=\"String\">A</Data></Cell><Cell ss:StyleID=\"ce26\"><Data ss:Type=\"String\">E</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B1]+[.C1]\"><Data ss:Type=\"Number\">6</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.E1]&amp;[.F1]\"><Data ss:Type=\"String\">AE</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce2\"><Data ss:Type=\"String\">Test - String 2</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">2</Data></Cell><Cell ss:StyleID=\"ce4\"><Data ss:Type=\"Number\">6</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">B</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">F</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B2]+[.C2]\"><Data ss:Type=\"Number\">8</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.E2]&amp;[.F2]\"><Data ss:Type=\"String\">BF</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce55\"><Data ss:Type=\"String\">Dot</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce3\"><Data ss:Type=\"String\">Test #3</Data></Cell><Cell ss:StyleID=\"ce4\"><Data ss:Type=\"Number\">3</Data></Cell><Cell ss:StyleID=\"ce4\"><Data ss:Type=\"Number\">7</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce26\"><Data ss:Type=\"String\">C</Data></Cell><Cell ss:StyleID=\"ce2\"><Data ss:Type=\"String\">G</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B3]+[.C3]\"><Data ss:Type=\"Number\">10</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.E3]&amp;[.F3]\"><Data ss:Type=\"String\">CG</Data></Cell><Cell ss:StyleID=\"ce37\"><Data ss:Type=\"String\">Red</Data></Cell><Cell ss:StyleID=\"ce46\"><Data ss:Type=\"String\">Red</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce56\"><Data ss:Type=\"String\">Dash</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce4\"><Data ss:Type=\"String\">Test with (\") in string</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">4</Data></Cell><Cell ss:StyleID=\"ce4\"><Data ss:Type=\"Number\">8</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce27\"><Data ss:Type=\"String\">D</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">H</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B4]+[.C4]\"><Data ss:Type=\"Number\">12</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.E4]&amp;[.F4]\"><Data ss:Type=\"String\">DH</Data></Cell><Cell ss:StyleID=\"ce38\"><Data ss:Type=\"String\">Orange</Data></Cell><Cell ss:StyleID=\"ce47\"><Data ss:Type=\"String\">Orange</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce57\"><Data ss:Type=\"String\">Dash/Dot/Dot</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=SUM([.B1:.B4])\"><Data ss:Type=\"Number\">10</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=SUM([.C1:.C4])\"><Data ss:Type=\"Number\">26</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=SUM([.B1:.C4])\"><Data ss:Type=\"Number\">36</Data></Cell><Cell ss:StyleID=\"ce39\"><Data ss:Type=\"String\">Yellow</Data></Cell><Cell ss:StyleID=\"ce48\"><Data ss:Type=\"String\">Yellow</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce58\"><Data ss:Type=\"String\">Dash/Dot</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce6\"><Data ss:Type=\"String\">Test #3</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">1.23</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=TRUE()\"><Data ss:Type=\"Boolean\">1</Data></Cell><Cell ss:StyleID=\"ce24\"><Data ss:Type=\"Boolean\">1</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce40\"><Data ss:Type=\"String\">Green</Data></Cell><Cell ss:StyleID=\"ce49\"><Data ss:Type=\"String\">Green</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce56\"><Data ss:Type=\"String\">Thin Line</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce7\"><Data ss:Type=\"String\">Test #3</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">2.34</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=FALSE()\"><Data ss:Type=\"Boolean\">0</Data></Cell><Cell ss:StyleID=\"ce25\"><Data ss:Type=\"Boolean\">0</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=SUM(marksrange)\"><Data ss:Type=\"Number\">0</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce41\"><Data ss:Type=\"String\">Blue</Data></Cell><Cell ss:StyleID=\"ce50\"><Data ss:Type=\"String\">Blue</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce59\"><Data ss:Type=\"String\">Thick Dash/Dot/Dot</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:Index=\"8\" ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce8\"><Data ss:Type=\"String\">Test #3</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">3.45</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce42\"><Data ss:Type=\"String\">Purple</Data></Cell><Cell ss:StyleID=\"ce51\"><Data ss:Type=\"String\">Purple</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce60\"><Data ss:Type=\"String\">Variant Thick Dash/Dot/Dot</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"13.4929\"><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce43\"><Data ss:Type=\"String\">Pink</Data></Cell><Cell ss:StyleID=\"ce52\"><Data ss:Type=\"String\">Pink</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce61\"><Data ss:Type=\"String\">Thick Dash/Dot</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce9\"><Data ss:Type=\"DateTime\">1960-12-19T00:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce19\"><Data ss:Type=\"String\">TOP</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">0</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce44\"><Data ss:Type=\"String\">Brown</Data></Cell><Cell ss:StyleID=\"ce53\"><Data ss:Type=\"String\">Brown</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce62\"><Data ss:Type=\"String\">Thick Dash</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce10\"><Data ss:Type=\"Number\">1.5</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=12/0\"><Data ss:Type=\"Number\">0</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce63\"><Data ss:Type=\"String\">Thick Line</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"13.4929\"><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce20\"><Data ss:Type=\"String\">BOTTOM</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce64\"><Data ss:Type=\"String\">Extra Thick Line</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce11\"><Data ss:Type=\"DateTime\">1899-12-31T02:30:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><ss:Data xmlns=\"http://www.w3.org/TR/REC-html40\" ss:Type=\"String\">Мойва сушеная</ss:Data><Comment><ss:Data xmlns=\"http://www.w3.org/TR/REC-html40\"><Font html:Face=\"Sans\" html:Size=\"10\">Tests for UTF-8 content</Font></ss:Data></Comment></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce65\"><Data ss:Type=\"String\">Double Line</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce21\"><Data ss:Type=\"String\">LEFT</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">Ärendetext</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce12\"><Data ss:Type=\"DateTime\">1960-12-19T01:30:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">Højde</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:Index=\"16\" ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce22\"><Data ss:Type=\"String\">RIGHT</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"13.4929\"><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:Height=\"41.7543\"><Cell ss:StyleID=\"ce5\"/><Cell ss:MergeAcross=\"1\" ss:MergeDown=\"1\" ss:StyleID=\"ce18\"><Data ss:Type=\"String\">BOX</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce29\"><Data ss:Type=\"String\">Test Column 1</Data></Cell><Cell ss:StyleID=\"ce30\"/><Cell ss:StyleID=\"ce33\"/><Cell ss:StyleID=\"ce36\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:Height=\"41.7543\"><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce30\"/><Cell ss:StyleID=\"ce32\"><Data ss:Type=\"String\">Test Column 2</Data></Cell><Cell ss:StyleID=\"ce30\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce45\"><Data ss:Type=\"String\">Patterned</Data></Cell><Cell ss:StyleID=\"ce54\"><Data ss:Type=\"String\">Patterned 2</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:Height=\"41.7543\"><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce30\"/><Cell ss:StyleID=\"ce30\"/><Cell ss:StyleID=\"ce34\"><Data ss:Type=\"String\">Test Column 3</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">Underline None</Data></Cell><Cell ss:Index=\"3\" ss:MergeAcross=\"1\" ss:MergeDown=\"4\" ss:StyleID=\"ce23\"><Data ss:Type=\"String\">Rotate 90</Data></Cell><Cell ss:MergeAcross=\"1\" ss:MergeDown=\"4\" ss:StyleID=\"ce28\"><Data ss:Type=\"String\">Rotate 45</Data></Cell><Cell ss:MergeAcross=\"1\" ss:MergeDown=\"4\" ss:StyleID=\"ce31\"><Data ss:Type=\"String\">Rotate -90</Data></Cell><Cell ss:MergeAcross=\"1\" ss:MergeDown=\"4\" ss:StyleID=\"ce35\"><Data ss:Type=\"String\">Rotate -45</Data></Cell><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:StyleID=\"ce14\"><Data ss:Type=\"String\">Underline 1</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">Subscript</Data></Cell><Cell ss:Index=\"1016\" ss:StyleID=\"ce13\"/></Row><Row ss:Index=\"24\" ss:Height=\"12.8409\"><Cell ss:StyleID=\"ce15\"><Data ss:Type=\"String\">Underline 2</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">Superscript</Data></Cell><Cell ss:Index=\"1016\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:StyleID=\"ce14\"><Data ss:Type=\"String\">Underline 3</Data></Cell><Cell ss:Index=\"1016\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:StyleID=\"ce15\"><Data ss:Type=\"String\">Underline 4</Data></Cell><Cell ss:Index=\"1016\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"49.2378\"><Cell ss:MergeAcross=\"2\" ss:StyleID=\"ce16\"><ss:Data xmlns=\"http://www.w3.org/TR/REC-html40\" ss:Type=\"String\">I don't know if Gnumeric supports <B><Font html:Face=\"Sans\" html:Color=\"#000000\" html:Size=\"10\">Rich Text</Font></B> in the same way as <B><Font html:Face=\"Sans\" html:Color=\"#000000\" html:Size=\"10\">Excel</Font></B>, And this row should be autofit height with text wrap</ss:Data></Cell><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/><Cell ss:StyleID=\"ce16\"/></Row><Row ss:Height=\"13.4079\"><Cell ss:MergeAcross=\"2\" ss:HRef=\"http://www.phpexcel.net/\" ss:StyleID=\"ce17\"><Data ss:Type=\"String\">PHPExcel</Data></Cell><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Index=\"65536\" ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row></Table><x:WorksheetOptions/></ss:Worksheet><ss:Worksheet ss:Name=\"Report Data\"><Table ss:StyleID=\"ta1\"><Column ss:Span=\"2\" ss:Width=\"56.2394\"/><Column ss:Index=\"4\" ss:Width=\"78.7465\"/><Column ss:Width=\"58.5071\"/><Column ss:Width=\"27.4961\"/><Column ss:Width=\"78.7465\"/><Column ss:Width=\"68.5984\"/><Column ss:Span=\"1015\" ss:Width=\"48.3874\"/><Column ss:Index=\"1025\"/><Column ss:Span=\"1\"/><Row ss:AutoFitHeight=\"0\" ss:Height=\"31.4929\"><Cell ss:StyleID=\"ce66\"/><Cell ss:StyleID=\"ce66\"/><Cell ss:StyleID=\"ce66\"/><Cell ss:StyleID=\"ce66\"/><Cell ss:StyleID=\"ce66\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce66\"/><Cell ss:StyleID=\"ce66\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"31.4929\"><Cell ss:StyleID=\"ce66\"><Data ss:Type=\"String\">Heading 1</Data></Cell><Cell ss:StyleID=\"ce66\"><Data ss:Type=\"String\">Heading 2</Data></Cell><Cell ss:StyleID=\"ce66\"><Data ss:Type=\"String\">Third Heading</Data></Cell><Cell ss:StyleID=\"ce66\"><Data ss:Type=\"String\">Date Heading</Data></Cell><Cell ss:StyleID=\"ce66\"><Data ss:Type=\"String\">Time Heading</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce66\"><Data ss:Type=\"String\">Adjusted Date</Data></Cell><Cell ss:StyleID=\"ce66\"><Data ss:Type=\"String\">Adjusted Number</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce13\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\"/></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">Adjusted Number</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">Third Heading</Data></Cell></Row><Row><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">1</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">1.11</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">1.11</Data></Cell></Row><Row><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">2</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">4.44</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">2.22</Data></Cell></Row><Row><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">3</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">9.99</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">3.33</Data></Cell></Row><Row><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">4</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">17.76</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">4.44</Data></Cell></Row><Row ss:Index=\"8\"><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">5</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">27.75</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">5.55</Data></Cell></Row><Row><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">6</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">39.96</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">6.66</Data></Cell></Row><Row><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">7</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">54.39</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">7.77</Data></Cell></Row><Row><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">8</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">71.04</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">8.88</Data></Cell></Row><Row><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">9</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">89.91</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">9.99</Data></Cell></Row><Row><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">10</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">111</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">11.1</Data></Cell></Row><Row><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">11</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">134.31</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">12.21</Data></Cell></Row><Row><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">12</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">159.84</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">13.32</Data></Cell></Row><Row ss:Index=\"16\"><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"String\">13</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">1.11</Data></Cell><Cell ss:StyleID=\"ce13\"><Data ss:Type=\"Number\">-1.11</Data></Cell></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">ABC</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">1</Data></Cell><Cell ss:StyleID=\"ce67\"><Data ss:Type=\"Number\">1.11</Data></Cell><Cell ss:StyleID=\"ce68\"><Data ss:Type=\"DateTime\">2001-01-01T00:00:00.000</Data></Cell><Cell ss:StyleID=\"ce69\"><Data ss:Type=\"DateTime\">1899-12-31T01:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce68\" ss:Formula=\"of:=[.D3]-[.B3]\"><Data ss:Type=\"DateTime\">2000-12-31T00:00:00.000</Data></Cell><Cell ss:StyleID=\"ce67\" ss:Formula=\"of:=[.B3]*[.C3]\"><Data ss:Type=\"Number\">1.11</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">A</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B3]&amp;[.J3]\"><Data ss:Type=\"String\">1A</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">BCD</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">2</Data></Cell><Cell ss:StyleID=\"ce67\"><Data ss:Type=\"Number\">2.22</Data></Cell><Cell ss:StyleID=\"ce68\"><Data ss:Type=\"DateTime\">2002-02-02T00:00:00.000</Data></Cell><Cell ss:StyleID=\"ce69\"><Data ss:Type=\"DateTime\">1899-12-31T02:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce68\" ss:Formula=\"of:=[.D4]-[.B4]\"><Data ss:Type=\"DateTime\">2002-01-31T00:00:00.000</Data></Cell><Cell ss:StyleID=\"ce67\" ss:Formula=\"of:=[.B4]*[.C4]\"><Data ss:Type=\"Number\">4.44</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">B</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B4]&amp;[.J4]\"><Data ss:Type=\"String\">2B</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">CDE</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">3</Data></Cell><Cell ss:StyleID=\"ce67\"><Data ss:Type=\"Number\">3.33</Data></Cell><Cell ss:StyleID=\"ce68\"><Data ss:Type=\"DateTime\">2003-03-03T00:00:00.000</Data></Cell><Cell ss:StyleID=\"ce69\"><Data ss:Type=\"DateTime\">1899-12-31T03:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce68\" ss:Formula=\"of:=[.D5]-[.B5]\"><Data ss:Type=\"DateTime\">2003-02-28T00:00:00.000</Data></Cell><Cell ss:StyleID=\"ce67\" ss:Formula=\"of:=[.B5]*[.C5]\"><Data ss:Type=\"Number\">9.99</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">C</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B5]&amp;[.J5]\"><Data ss:Type=\"String\">3C</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">DEF</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">4</Data></Cell><Cell ss:StyleID=\"ce67\"><Data ss:Type=\"Number\">4.44</Data></Cell><Cell ss:StyleID=\"ce68\"><Data ss:Type=\"DateTime\">2004-04-03T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce69\"><Data ss:Type=\"DateTime\">1899-12-31T04:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce68\" ss:Formula=\"of:=[.D6]-[.B6]\"><Data ss:Type=\"DateTime\">2004-03-30T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce67\" ss:Formula=\"of:=[.B6]*[.C6]\"><Data ss:Type=\"Number\">17.76</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">D</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B6]&amp;[.J6]\"><Data ss:Type=\"String\">4D</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">EFG</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">5</Data></Cell><Cell ss:StyleID=\"ce67\"><Data ss:Type=\"Number\">5.55</Data></Cell><Cell ss:StyleID=\"ce68\"><Data ss:Type=\"DateTime\">2005-05-04T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce69\"><Data ss:Type=\"DateTime\">1899-12-31T05:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce68\" ss:Formula=\"of:=[.D7]-[.B7]\"><Data ss:Type=\"DateTime\">2005-04-29T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce67\" ss:Formula=\"of:=[.B7]*[.C7]\"><Data ss:Type=\"Number\">27.75</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">E</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B7]&amp;[.J7]\"><Data ss:Type=\"String\">5E</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">FGH</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">6</Data></Cell><Cell ss:StyleID=\"ce67\"><Data ss:Type=\"Number\">6.66</Data></Cell><Cell ss:StyleID=\"ce68\"><Data ss:Type=\"DateTime\">2006-06-05T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce69\"><Data ss:Type=\"DateTime\">1899-12-31T06:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce68\" ss:Formula=\"of:=[.D8]-[.B8]\"><Data ss:Type=\"DateTime\">2006-05-30T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce67\" ss:Formula=\"of:=[.B8]*[.C8]\"><Data ss:Type=\"Number\">39.96</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">F</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B8]&amp;[.J8]\"><Data ss:Type=\"String\">6F</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">GHI</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">7</Data></Cell><Cell ss:StyleID=\"ce67\"><Data ss:Type=\"Number\">7.77</Data></Cell><Cell ss:StyleID=\"ce68\"><Data ss:Type=\"DateTime\">2007-07-06T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce69\"><Data ss:Type=\"DateTime\">1899-12-31T07:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce68\" ss:Formula=\"of:=[.D9]-[.B9]\"><Data ss:Type=\"DateTime\">2007-06-29T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce67\" ss:Formula=\"of:=[.B9]*[.C9]\"><Data ss:Type=\"Number\">54.39</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">G</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B9]&amp;[.J9]\"><Data ss:Type=\"String\">7G</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:Index=\"24\" ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">HIJ</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">8</Data></Cell><Cell ss:StyleID=\"ce67\"><Data ss:Type=\"Number\">8.88</Data></Cell><Cell ss:StyleID=\"ce68\"><Data ss:Type=\"DateTime\">2008-08-07T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce69\"><Data ss:Type=\"DateTime\">1899-12-31T08:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce68\" ss:Formula=\"of:=[.D10]-[.B10]\"><Data ss:Type=\"DateTime\">2008-07-30T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce67\" ss:Formula=\"of:=[.B10]*[.C10]\"><Data ss:Type=\"Number\">71.04</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">H</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B10]&amp;[.J10]\"><Data ss:Type=\"String\">8H</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">IJK</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">9</Data></Cell><Cell ss:StyleID=\"ce67\"><Data ss:Type=\"Number\">9.99</Data></Cell><Cell ss:StyleID=\"ce68\"><Data ss:Type=\"DateTime\">2009-09-08T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce69\"><Data ss:Type=\"DateTime\">1899-12-31T09:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce68\" ss:Formula=\"of:=[.D11]-[.B11]\"><Data ss:Type=\"DateTime\">2009-08-30T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce67\" ss:Formula=\"of:=[.B11]*[.C11]\"><Data ss:Type=\"Number\">89.91</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">I</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B11]&amp;[.J11]\"><Data ss:Type=\"String\">9I</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">JKL</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">10</Data></Cell><Cell ss:StyleID=\"ce67\"><Data ss:Type=\"Number\">11.1</Data></Cell><Cell ss:StyleID=\"ce68\"><Data ss:Type=\"DateTime\">2010-10-09T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce69\"><Data ss:Type=\"DateTime\">1899-12-31T10:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce68\" ss:Formula=\"of:=[.D12]-[.B12]\"><Data ss:Type=\"DateTime\">2010-09-29T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce67\" ss:Formula=\"of:=[.B12]*[.C12]\"><Data ss:Type=\"Number\">111</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">J</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B12]&amp;[.J12]\"><Data ss:Type=\"String\">10J</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">KLM</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">11</Data></Cell><Cell ss:StyleID=\"ce67\"><Data ss:Type=\"Number\">12.21</Data></Cell><Cell ss:StyleID=\"ce68\"><Data ss:Type=\"DateTime\">2011-11-11T00:00:00.000</Data></Cell><Cell ss:StyleID=\"ce69\"><Data ss:Type=\"DateTime\">1899-12-31T11:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce68\" ss:Formula=\"of:=[.D13]-[.B13]\"><Data ss:Type=\"DateTime\">2011-10-31T00:00:00.000</Data></Cell><Cell ss:StyleID=\"ce67\" ss:Formula=\"of:=[.B13]*[.C13]\"><Data ss:Type=\"Number\">134.31</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">K</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B13]&amp;[.J13]\"><Data ss:Type=\"String\">11K</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">LMN</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">12</Data></Cell><Cell ss:StyleID=\"ce67\"><Data ss:Type=\"Number\">13.32</Data></Cell><Cell ss:StyleID=\"ce68\"><Data ss:Type=\"DateTime\">2012-12-12T00:00:00.000</Data></Cell><Cell ss:StyleID=\"ce69\"><Data ss:Type=\"DateTime\">1899-12-31T288:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce68\" ss:Formula=\"of:=[.D14]-[.B14]\"><Data ss:Type=\"DateTime\">2012-11-30T00:00:00.000</Data></Cell><Cell ss:StyleID=\"ce67\" ss:Formula=\"of:=[.B14]*[.C14]\"><Data ss:Type=\"Number\">159.84</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">L</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B14]&amp;[.J14]\"><Data ss:Type=\"String\">12L</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">ZYX</Data></Cell><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"Number\">-1</Data></Cell><Cell ss:StyleID=\"ce67\"><Data ss:Type=\"Number\">-1.11</Data></Cell><Cell ss:StyleID=\"ce68\"><Data ss:Type=\"DateTime\">1999-12-01T00:00:00.000</Data></Cell><Cell ss:StyleID=\"ce69\"><Data ss:Type=\"DateTime\">1899-12-31T23:00:00.000</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce68\" ss:Formula=\"of:=[.D15]-[.B15]\"><Data ss:Type=\"DateTime\">1999-12-02T00:00:00.000</Data></Cell><Cell ss:StyleID=\"ce67\" ss:Formula=\"of:=[.B15]*[.C15]\"><Data ss:Type=\"Number\">1.11</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"><Data ss:Type=\"String\">M</Data></Cell><Cell ss:StyleID=\"ce5\" ss:Formula=\"of:=[.B15]&amp;[.J15]\"><Data ss:Type=\"String\">-1M</Data></Cell><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/><Cell ss:StyleID=\"ce5\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:AutoFitHeight=\"0\" ss:Height=\"14.9953\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row><Row ss:Index=\"65550\" ss:Height=\"12.8409\"><Cell ss:Index=\"1024\" ss:StyleID=\"ce13\"/></Row></Table><x:WorksheetOptions/></ss:Worksheet></Workbook>"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/GnumericReader.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (C) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n/** Error reporting */\r\nerror_reporting(E_ALL);\r\n\r\ndate_default_timezone_set('Europe/London');\r\n\r\n/** PHPExcel_IOFactory */\r\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\r\n\r\necho date('H:i:s') , \" Load from Gnumeric file\" , PHP_EOL;\r\n$callStartTime = microtime(true);\r\n\r\n$objReader = PHPExcel_IOFactory::createReader('Gnumeric');\r\n$objPHPExcel = $objReader->load(\"GnumericTest.gnumeric\");\r\n\r\n\r\n$callEndTime = microtime(true);\r\n$callTime = $callEndTime - $callStartTime;\r\necho 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , PHP_EOL;\r\n// Echo memory usage\r\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , PHP_EOL;\r\n\r\n\r\necho date('H:i:s') , \" Write to Excel2007 format\" , PHP_EOL;\r\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\r\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\r\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL;\r\n\r\n\r\n// Echo memory peak usage\r\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , PHP_EOL;\r\n\r\n// Echo done\r\necho date('H:i:s') , \" Done writing file\" , PHP_EOL;\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/OOCalcReader.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (C) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n/** Error reporting */\r\nerror_reporting(E_ALL);\r\n\r\ndate_default_timezone_set('Europe/London');\r\n\r\n/** PHPExcel_IOFactory */\r\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\r\n\r\necho date('H:i:s') , \" Load from OOCalc file\" , PHP_EOL;\r\n$callStartTime = microtime(true);\r\n\r\n$objReader = PHPExcel_IOFactory::createReader('OOCalc');\r\n$objPHPExcel = $objReader->load(\"OOCalcTest.ods\");\r\n\r\n\r\n$callEndTime = microtime(true);\r\n$callTime = $callEndTime - $callStartTime;\r\necho 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , PHP_EOL;\r\n// Echo memory usage\r\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , PHP_EOL;\r\n\r\n\r\necho date('H:i:s') , \" Write to Excel2007 format\" , PHP_EOL;\r\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\r\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\r\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL;\r\n\r\n\r\n// Echo memory peak usage\r\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , PHP_EOL;\r\n\r\n// Echo done\r\necho date('H:i:s') , \" Done writing file\" , PHP_EOL;\r\n\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/OOCalcReaderPCLZip.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\n\ndate_default_timezone_set('Europe/London');\n\n/** PHPExcel_IOFactory */\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\n\n// Use PCLZip rather than ZipArchive to read the Excel2007 OfficeOpenXML file\nPHPExcel_Settings::setZipClass(PHPExcel_Settings::PCLZIP);\n\necho date('H:i:s') , \" Load from OOCalc file\" , PHP_EOL;\n$callStartTime = microtime(true);\n\n$objReader = PHPExcel_IOFactory::createReader('OOCalc');\n$objPHPExcel = $objReader->load(\"OOCalcTest.ods\");\n\n\n$callEndTime = microtime(true);\n$callTime = $callEndTime - $callStartTime;\necho 'Call time to read Workbook was ' , sprintf('%.4f',$callTime) , \" seconds\" , PHP_EOL;\n// Echo memory usage\necho date('H:i:s') , ' Current memory usage: ' , (memory_get_usage(true) / 1024 / 1024) , \" MB\" , PHP_EOL;\n\n\necho date('H:i:s') , \" Write to Excel2007 format\" , PHP_EOL;\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL;\n\n\n// Echo memory peak usage\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , PHP_EOL;\n\n// Echo done\necho date('H:i:s') , \" Done writing file\" , PHP_EOL;\n\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/Quadratic.php",
    "content": "<html>\r\n<head>\r\n<title>Quadratic Equation Solver</title>\r\n</head>\r\n<body>\r\n<?php\r\n\r\n/**\tError reporting\t\t**/\r\nerror_reporting(E_ALL);\r\n\r\n/**\tInclude path\t\t**/\r\nset_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/');\r\n\r\n?>\r\n<h1>Quadratic Equation Solver</h1>\r\n<form action=\"Quadratic.php\" method=\"POST\">\r\nEnter the coefficients for the Ax<sup>2</sup> + Bx + C = 0\r\n<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\r\n\t<tr><td><b>A&nbsp;</b></td>\r\n\t\t<td><input name=\"A\" type=\"text\" size=\"8\" value=\"<?php echo (isset($_POST['A'])) ? htmlentities($_POST['A']) : ''; ?>\"></td>\r\n\t</tr>\r\n\t<tr><td><b>B&nbsp;</b></td>\r\n\t\t<td><input name=\"B\" type=\"text\" size=\"8\" value=\"<?php echo (isset($_POST['B'])) ? htmlentities($_POST['B']) : ''; ?>\"></td>\r\n\t</tr>\r\n\t<tr><td><b>C&nbsp;</b></td>\r\n\t\t<td><input name=\"C\" type=\"text\" size=\"8\" value=\"<?php echo (isset($_POST['C'])) ? htmlentities($_POST['C']) : ''; ?>\"></td>\r\n\t</tr>\r\n</table>\r\n<input name=\"submit\" type=\"submit\" value=\"calculate\"><br />\r\nIf A=0, the equation is not quadratic.\r\n</form>\r\n\r\n<?php\r\n/**\tIf the user has submitted the form, then we need to execute a calculation **/\r\nif (isset($_POST['submit'])) {\r\n\tif ($_POST['A'] == 0) {\r\n\t\techo 'The equation is not quadratic';\r\n\t} else {\r\n\t\t/**\tSo we include PHPExcel to perform the calculations\t**/\r\n\t\tinclude 'PHPExcel/IOFactory.php';\r\n\r\n\t\t/**\tLoad the quadratic equation solver worksheet into memory\t\t\t**/\r\n\t\t$objPHPExcel = PHPExcel_IOFactory::load('./Quadratic.xlsx');\r\n\r\n\t\t/**\tSet our A, B and C values\t\t\t**/\r\n\t\t$objPHPExcel->getActiveSheet()->setCellValue('A1', $_POST['A']);\r\n\t\t$objPHPExcel->getActiveSheet()->setCellValue('B1', $_POST['B']);\r\n\t\t$objPHPExcel->getActiveSheet()->setCellValue('C1', $_POST['C']);\r\n\r\n\r\n\t\t/**\tCalculate and Display the results\t\t\t**/\r\n\t\techo '<hr /><b>Roots:</b><br />';\r\n\r\n\t\t$callStartTime = microtime(true);\r\n\t\techo $objPHPExcel->getActiveSheet()->getCell('B5')->getCalculatedValue().'<br />';\r\n\t\techo $objPHPExcel->getActiveSheet()->getCell('B6')->getCalculatedValue().'<br />';\r\n\t\t$callEndTime = microtime(true);\r\n\t\t$callTime = $callEndTime - $callStartTime;\r\n\r\n\t\techo '<hr />Call time for Quadratic Equation Solution was '.sprintf('%.4f',$callTime).' seconds<br /><hr />';\r\n\t\techo ' Peak memory usage: '.(memory_get_peak_usage(true) / 1024 / 1024).' MB<br />';\r\n\t}\r\n}\r\n\r\n?>\r\n\r\n</body>\r\n<html>\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/Quadratic2.php",
    "content": "<html>\r\n<head>\r\n<title>Quadratic Equation Solver</title>\r\n</head>\r\n<body>\r\n<?php\r\n\r\n/**\tError reporting\t\t**/\r\nerror_reporting(E_ALL);\r\n\r\n/**\tInclude path\t\t**/\r\nset_include_path(get_include_path() . PATH_SEPARATOR . dirname(__FILE__) . '/../Classes/');\r\n\r\n?>\r\n<h1>Quadratic Equation Solver</h1>\r\n<form action=\"Quadratic2.php\" method=\"POST\">\r\nEnter the coefficients for the Ax<sup>2</sup> + Bx + C = 0\r\n<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\r\n\t<tr><td><b>A&nbsp;</b></td>\r\n\t\t<td><input name=\"A\" type=\"text\" size=\"8\" value=\"<?php echo (isset($_POST['A'])) ? htmlentities($_POST['A']) : ''; ?>\"></td>\r\n\t</tr>\r\n\t<tr><td><b>B&nbsp;</b></td>\r\n\t\t<td><input name=\"B\" type=\"text\" size=\"8\" value=\"<?php echo (isset($_POST['B'])) ? htmlentities($_POST['B']) : ''; ?>\"></td>\r\n\t</tr>\r\n\t<tr><td><b>C&nbsp;</b></td>\r\n\t\t<td><input name=\"C\" type=\"text\" size=\"8\" value=\"<?php echo (isset($_POST['C'])) ? htmlentities($_POST['C']) : ''; ?>\"></td>\r\n\t</tr>\r\n</table>\r\n<input name=\"submit\" type=\"submit\" value=\"calculate\"><br />\r\nIf A=0, the equation is not quadratic.\r\n</form>\r\n\r\n<?php\r\n/**\tIf the user has submitted the form, then we need to execute a calculation **/\r\nif (isset($_POST['submit'])) {\r\n\tif ($_POST['A'] == 0) {\r\n\t\techo 'The equation is not quadratic';\r\n\t} else {\r\n\t\t/**\tSo we include PHPExcel to perform the calculations\t**/\r\n\t\tinclude 'PHPExcel/Calculation.php';\r\n\r\n\t\t/**\tCalculate and Display the results\t\t\t**/\r\n\t\techo '<hr /><b>Roots:</b><br />';\r\n\r\n\t\t$callStartTime = microtime(true);\r\n\t\t$discriminantFormula = '=POWER('.$_POST['B'].',2) - (4 * '.$_POST['A'].' * '.$_POST['C'].')';\r\n\t\t$discriminant = PHPExcel_Calculation::getInstance()->calculateFormula($discriminantFormula);\r\n\r\n\t\t$r1Formula = '=IMDIV(IMSUM(-'.$_POST['B'].',IMSQRT('.$discriminant.')),2 * '.$_POST['A'].')';\r\n\t\t$r2Formula = '=IF('.$discriminant.'=0,\"Only one root\",IMDIV(IMSUB(-'.$_POST['B'].',IMSQRT('.$discriminant.')),2 * '.$_POST['A'].'))';\r\n\r\n\t\techo PHPExcel_Calculation::getInstance()->calculateFormula($r1Formula).'<br />';\r\n\t\techo PHPExcel_Calculation::getInstance()->calculateFormula($r2Formula).'<br />';\r\n\t\t$callEndTime = microtime(true);\r\n\t\t$callTime = $callEndTime - $callStartTime;\r\n\r\n\t\techo '<hr />Call time for Quadratic Equation Solution was '.sprintf('%.4f',$callTime).' seconds<br /><hr />';\r\n\t\techo ' Peak memory usage: '.(memory_get_peak_usage(true) / 1024 / 1024).' MB<br />';\r\n\t}\r\n}\r\n\r\n?>\r\n\r\n</body>\r\n<html>\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/SylkReader.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (C) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n/** Error reporting */\r\nerror_reporting(E_ALL);\r\n\r\ndate_default_timezone_set('Europe/London');\r\n\r\n/** PHPExcel_IOFactory */\r\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\r\n\r\n\r\necho date('H:i:s') , \" Load from SYLK file\" , PHP_EOL;\r\n$objPHPExcel = PHPExcel_IOFactory::load(\"SylkTest.slk\");\r\n\r\necho date('H:i:s') , \" Write to Excel2007 format\" , PHP_EOL;\r\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\r\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\r\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL;\r\n\r\n\r\n// Echo memory peak usage\r\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , PHP_EOL;\r\n\r\n// Echo done\r\necho date('H:i:s') , \" Done writing file\" , PHP_EOL;\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/SylkTest.slk",
    "content": "ID;PWXL;N;E\r\nP;PGeneral\r\nP;P0\r\nP;P0.00\r\nP;P#,##0\r\nP;P#,##0.00\r\nP;P#,##0;;\\-#,##0\r\nP;P#,##0;;[Red]\\-#,##0\r\nP;P#,##0.00;;\\-#,##0.00\r\nP;P#,##0.00;;[Red]\\-#,##0.00\r\nP;P\"$\"#,##0;;\\-\"$\"#,##0\r\nP;P\"$\"#,##0;;[Red]\\-\"$\"#,##0\r\nP;P\"$\"#,##0.00;;\\-\"$\"#,##0.00\r\nP;P\"$\"#,##0.00;;[Red]\\-\"$\"#,##0.00\r\nP;P0%\r\nP;P0.00%\r\nP;P0.00E+00\r\nP;P##0.0E+0\r\nP;P#\\ ?/?\r\nP;P#\\ ??/??\r\nP;Pdd/mm/yyyy\r\nP;Pdd\\-mmm\\-yy\r\nP;Pdd\\-mmm\r\nP;Pmmm\\-yy\r\nP;Ph:mm\\ AM/PM\r\nP;Ph:mm:ss\\ AM/PM\r\nP;Phh:mm\r\nP;Phh:mm:ss\r\nP;Pdd/mm/yyyy\\ hh:mm\r\nP;Pmm:ss\r\nP;Pmm:ss.0\r\nP;P@\r\nP;P[h]:mm:ss\r\nP;P_-\"$\"* #,##0_-;;\\-\"$\"* #,##0_-;;_-\"$\"* \"-\"_-;;_-@_-\r\nP;P_-* #,##0_-;;\\-* #,##0_-;;_-* \"-\"_-;;_-@_-\r\nP;P_-\"$\"* #,##0.00_-;;\\-\"$\"* #,##0.00_-;;_-\"$\"* \"-\"??_-;;_-@_-\r\nP;P_-* #,##0.00_-;;\\-* #,##0.00_-;;_-* \"-\"??_-;;_-@_-\r\nP;FArial;M200\r\nP;FArial;M200\r\nP;FArial;M200\r\nP;FArial;M200\r\nP;EArial;M200\r\nP;EArial;M200\r\nP;EArial;M200\r\nP;EArial;M200;SB\r\nP;EArial;M200;SBI\r\nP;EArial;M200;SI\r\nP;EArial;M200;SU\r\nP;EArial;M200;L11\r\nP;EArial;M200;SB\r\nP;EArial;M200\r\nP;EArial;M200;SI\r\nP;EArial;M200;SBI\r\nP;EArial;M200;SBU\r\nP;EArial;M200;SBIU\r\nP;EArial;M200\r\nP;EArial;M200;SI\r\nF;P0;DG0G8;M255\r\nB;Y18;X10;D0 0 17 9\r\nO;L;D;V0;K47;G100 0.001\r\nF;W1 1 17\r\nF;W4 6 6\r\nF;M270;R9\r\nF;M270;R12\r\nF;M270;R17\r\nF;M270;R18\r\nF;SM12;Y1;X1\r\nC;K\"Test String 1\"\r\nF;SM19;X2\r\nC;K1\r\nF;SM19;X3\r\nC;K5\r\nF;SIDM18;X5\r\nC;K\"A\"\r\nF;SDM17;X6\r\nC;K\"E\"\r\nC;X8;K6;ERC[-6]+RC[-5]\r\nC;X10;K\"AE\";ERC[-5]&RC[-4]\r\nF;SSM0;Y2;X1\r\nC;K\"Test - String 2\"\r\nC;X2;K2\r\nF;SM19;X3\r\nC;K6\r\nC;X5;K\"B\"\r\nC;X6;K\"F\"\r\nC;X8;K8;ERC[-6]+RC[-5]\r\nC;X10;K\"BF\";ERC[-5]&RC[-4]\r\nC;Y3;X1;K\"Test #3\"\r\nF;SM19;X2\r\nC;K3\r\nF;SM19;X3\r\nC;K7\r\nF;SDM13;X5\r\nC;K\"C\"\r\nF;SIDM16;X6\r\nC;K\"G\"\r\nC;X8;K10;ERC[-6]+RC[-5]\r\nC;X10;K\"CG\";ERC[-5]&RC[-4]\r\nF;SM11;Y4;X1\r\nC;K\"Test with (;;) in string\"\r\nC;X2;K4\r\nF;SM19;X3\r\nC;K8\r\nF;SIM15;X5\r\nC;K\"D\"\r\nC;X6;K\"H\"\r\nC;X8;K12;ERC[-6]+RC[-5]\r\nC;X10;K\"DH\";ERC[-5]&RC[-4]\r\nC;Y5;X8;K10;ESUM(R[-4]C[-6]:R[-1]C[-6])\r\nC;X9;K26;ESUM(R[-4]C[-6]:R[-1]C[-6])\r\nC;X10;K36;ESUM(R[-4]C[-8]:R[-1]C[-7])\r\nC;Y6;X2;K1.23\r\nC;X3;KTRUE\r\nF;P19;FG0G;X4\r\nC;Y7;X2;K2.34\r\nC;X3;KFALSE\r\nC;Y8;X2;K3.45\r\nF;Y9;X1\r\nF;X2\r\nF;X3\r\nF;X4\r\nF;X5\r\nF;X6\r\nF;X7\r\nF;X8\r\nF;X9\r\nF;X10\r\nF;P19;FG0G;Y10;X1\r\nC;K22269\r\nF;STM0;X3\r\nC;K\"TOP\"\r\nF;P17;FG0G;Y11;X1\r\nC;K1.5\r\nF;Y12\r\nF;X2\r\nF;SBM0;X3\r\nC;K\"BOTTOM\"\r\nF;X4\r\nF;X5\r\nF;X6\r\nF;X7\r\nF;X8\r\nF;X9\r\nF;X10\r\nF;SLM0;Y14;X3\r\nC;K\"LEFT\"\r\nF;SRM0;Y16\r\nC;K\"RIGHT\"\r\nF;Y17\r\nF;SLRTBM0;Y18\r\nC;K\"BOX\"\r\nE\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/XMLReader.php",
    "content": "<?php\r\n/**\r\n * PHPExcel\r\n *\r\n * Copyright (C) 2006 - 2014 PHPExcel\r\n *\r\n * This library is free software; you can redistribute it and/or\r\n * modify it under the terms of the GNU Lesser General Public\r\n * License as published by the Free Software Foundation; either\r\n * version 2.1 of the License, or (at your option) any later version.\r\n *\r\n * This library is distributed in the hope that it will be useful,\r\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\r\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r\n * Lesser General Public License for more details.\r\n *\r\n * You should have received a copy of the GNU Lesser General Public\r\n * License along with this library; if not, write to the Free Software\r\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\r\n *\r\n * @category   PHPExcel\r\n * @package    PHPExcel\r\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\r\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\r\n * @version    ##VERSION##, ##DATE##\r\n */\r\n\r\n/** Error reporting */\r\nerror_reporting(E_ALL);\r\n\r\ndate_default_timezone_set('Europe/London');\r\n\r\n/** PHPExcel_IOFactory */\r\nrequire_once dirname(__FILE__) . '/../Classes/PHPExcel/IOFactory.php';\r\n\r\n\r\necho date('H:i:s') , \" Load from XML file\" , PHP_EOL;\r\n$inputFileName = \"XMLTest.xml\";\r\n\r\n/**  Identify the type of $inputFileName  **/\r\n$inputFileType = PHPExcel_IOFactory::identify($inputFileName);\r\necho 'Loading ' , $inputFileName , ' using ' , $inputFileType , \" Reader\" , PHP_EOL;\r\n\r\n/**  Create a new Reader of the type that has been identified  **/\r\n$objReader = PHPExcel_IOFactory::createReader($inputFileType);\r\n/**  Load $inputFileName to a PHPExcel Object  **/\r\n$objPHPExcel = $objReader->load($inputFileName);\r\n\r\n\r\necho date('H:i:s') , \" Write to Excel2007 format\" , PHP_EOL;\r\n$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');\r\n$objWriter->save(str_replace('.php', '.xlsx', __FILE__));\r\necho date('H:i:s') , \" File written to \" , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL;\r\n\r\n\r\n// Echo memory peak usage\r\necho date('H:i:s') , \" Peak memory usage: \" , (memory_get_peak_usage(true) / 1024 / 1024) , \" MB\" , PHP_EOL;\r\n\r\n// Echo done\r\necho date('H:i:s') , \" Done writing file\" , PHP_EOL;\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/XMLTest.xml",
    "content": "<?xml version=\"1.0\"?>\r\n<?mso-application progid=\"Excel.Sheet\"?>\r\n<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n xmlns:o=\"urn:schemas-microsoft-com:office:office\"\r\n xmlns:x=\"urn:schemas-microsoft-com:office:excel\"\r\n xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"\r\n xmlns:html=\"http://www.w3.org/TR/REC-html40\">\r\n <DocumentProperties xmlns=\"urn:schemas-microsoft-com:office:office\">\r\n  <Title>Excel 2003 XML Test Workbook</Title>\r\n  <Subject>This is a test workbook saved as Excel 2003 XML</Subject>\r\n  <Author>Mark Baker</Author>\r\n  <Keywords>PHPExcel Excel 2003 XML Reader</Keywords>\r\n  <Description>This is a test for the PHPExcel Reader for workbooks saved using Excel 2003's XML Format</Description>\r\n  <LastAuthor>Mark Baker</LastAuthor>\r\n  <Created>2009-09-11T08:26:08Z</Created>\r\n  <LastSaved>2009-09-17T22:53:09Z</LastSaved>\r\n  <Category>Reader</Category>\r\n  <Company>PHPExcel</Company>\r\n  <Version>14.00</Version>\r\n </DocumentProperties>\r\n <OfficeDocumentSettings xmlns=\"urn:schemas-microsoft-com:office:office\">\r\n  <AllowPNG/>\r\n </OfficeDocumentSettings>\r\n <ExcelWorkbook xmlns=\"urn:schemas-microsoft-com:office:excel\">\r\n  <WindowHeight>13176</WindowHeight>\r\n  <WindowWidth>28452</WindowWidth>\r\n  <WindowTopX>240</WindowTopX>\r\n  <WindowTopY>516</WindowTopY>\r\n  <ProtectStructure>False</ProtectStructure>\r\n  <ProtectWindows>False</ProtectWindows>\r\n </ExcelWorkbook>\r\n <Styles>\r\n  <Style ss:ID=\"Default\" ss:Name=\"Normal\">\r\n   <Alignment ss:Vertical=\"Bottom\"/>\r\n   <Borders/>\r\n   <Font ss:FontName=\"Calibri\" ss:Size=\"11\" ss:Color=\"#000000\"/>\r\n   <Interior/>\r\n   <NumberFormat/>\r\n   <Protection/>\r\n  </Style>\r\n  <Style ss:ID=\"m42221568\">\r\n   <Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Center\"/>\r\n   <Borders>\r\n    <Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"3\"\r\n     ss:Color=\"#00B050\"/>\r\n    <Border ss:Position=\"Left\" ss:LineStyle=\"Continuous\" ss:Weight=\"3\"\r\n     ss:Color=\"#0070C0\"/>\r\n    <Border ss:Position=\"Right\" ss:LineStyle=\"Continuous\" ss:Weight=\"3\"\r\n     ss:Color=\"#FFFF00\"/>\r\n    <Border ss:Position=\"Top\" ss:LineStyle=\"Continuous\" ss:Weight=\"3\"\r\n     ss:Color=\"#FF0000\"/>\r\n   </Borders>\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s62\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#FF0000\" ss:Bold=\"1\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s63\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s64\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\" ss:Bold=\"1\"\r\n    ss:Italic=\"1\" ss:Underline=\"Single\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s65\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\" ss:Bold=\"1\"\r\n    ss:Underline=\"Single\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s66\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\" ss:Bold=\"1\"/>\r\n   <Interior/>\r\n  </Style>\r\n  <Style ss:ID=\"s67\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\"/>\r\n   <Interior/>\r\n  </Style>\r\n  <Style ss:ID=\"s68\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\" ss:Bold=\"1\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s69\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\" ss:Bold=\"1\"\r\n    ss:Italic=\"1\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s70\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\" ss:Underline=\"Single\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s71\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\" ss:Italic=\"1\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s72\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\"/>\r\n   <NumberFormat ss:Format=\"Short Date\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s73\">\r\n   <Borders>\r\n    <Border ss:Position=\"Top\" ss:LineStyle=\"Continuous\" ss:Weight=\"2\"\r\n     ss:Color=\"#000000\"/>\r\n   </Borders>\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s74\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\"/>\r\n   <NumberFormat ss:Format=\"#\\ ?/?\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s75\">\r\n   <Borders>\r\n    <Border ss:Position=\"Bottom\" ss:LineStyle=\"Continuous\" ss:Weight=\"2\"\r\n     ss:Color=\"#000000\"/>\r\n   </Borders>\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s76\">\r\n   <Borders>\r\n    <Border ss:Position=\"Left\" ss:LineStyle=\"Continuous\" ss:Weight=\"2\"\r\n     ss:Color=\"#000000\"/>\r\n   </Borders>\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s77\">\r\n   <Borders>\r\n    <Border ss:Position=\"Right\" ss:LineStyle=\"Continuous\" ss:Weight=\"2\"\r\n     ss:Color=\"#000000\"/>\r\n   </Borders>\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s85\">\r\n   <Borders>\r\n    <Border ss:Position=\"DiagonalLeft\" ss:LineStyle=\"Double\" ss:Weight=\"3\"\r\n     ss:Color=\"#FF0000\"/>\r\n    <Border ss:Position=\"DiagonalRight\" ss:LineStyle=\"Double\" ss:Weight=\"3\"\r\n     ss:Color=\"#FF0000\"/>\r\n   </Borders>\r\n  </Style>\r\n  <Style ss:ID=\"s86\">\r\n   <Alignment ss:Horizontal=\"Center\" ss:Vertical=\"Bottom\" ss:WrapText=\"1\"/>\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"12\" ss:Color=\"#000000\" ss:Bold=\"1\"\r\n    ss:Underline=\"Single\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s87\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\"/>\r\n   <NumberFormat ss:Format=\"0.00;[Red]0.00\"/>\r\n  </Style>\r\n  <Style ss:ID=\"s88\">\r\n   <Font ss:FontName=\"Arial\" ss:Size=\"11\" ss:Color=\"#000000\"/>\r\n   <NumberFormat ss:Format=\"dd\\-mmm\\-yyyy\"/>\r\n  </Style>\r\n </Styles>\r\n <Worksheet ss:Name=\"Sample Data\">\r\n  <Table ss:ExpandedColumnCount=\"10\" ss:ExpandedRowCount=\"20\" x:FullColumns=\"1\"\r\n   x:FullRows=\"1\" ss:DefaultRowHeight=\"15\">\r\n   <Column ss:AutoFitWidth=\"0\" ss:Width=\"90.6\"/>\r\n   <Column ss:Index=\"4\" ss:AutoFitWidth=\"0\" ss:Width=\"33.6\"/>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell ss:StyleID=\"s62\"><Data ss:Type=\"String\">Test String 1</Data></Cell>\r\n    <Cell ss:StyleID=\"s63\"><Data ss:Type=\"Number\">1</Data></Cell>\r\n    <Cell ss:StyleID=\"s63\"><Data ss:Type=\"Number\">5</Data></Cell>\r\n    <Cell ss:Index=\"5\" ss:StyleID=\"s64\"><Data ss:Type=\"String\">A</Data></Cell>\r\n    <Cell ss:StyleID=\"s65\"><Data ss:Type=\"String\">E</Data></Cell>\r\n    <Cell ss:Index=\"8\" ss:Formula=\"=RC[-6]+RC[-5]\"><Data ss:Type=\"Number\">6</Data></Cell>\r\n    <Cell ss:Index=\"10\" ss:Formula=\"=RC[-5]&amp;RC[-4]\"><Data ss:Type=\"String\">AE</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell ss:StyleID=\"s66\"><Data ss:Type=\"String\">Test - String 2</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">2</Data></Cell>\r\n    <Cell ss:StyleID=\"s63\"><Data ss:Type=\"Number\">6</Data></Cell>\r\n    <Cell ss:Index=\"5\"><Data ss:Type=\"String\">B</Data></Cell>\r\n    <Cell><Data ss:Type=\"String\">F</Data></Cell>\r\n    <Cell ss:Index=\"8\" ss:Formula=\"=RC[-6]+RC[-5]\"><Data ss:Type=\"Number\">8</Data></Cell>\r\n    <Cell ss:Index=\"10\" ss:Formula=\"=RC[-5]&amp;RC[-4]\"><Data ss:Type=\"String\">BF</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell ss:StyleID=\"s67\"><Data ss:Type=\"String\">Test #3</Data></Cell>\r\n    <Cell ss:StyleID=\"s63\"><Data ss:Type=\"Number\">3</Data></Cell>\r\n    <Cell ss:StyleID=\"s63\"><Data ss:Type=\"Number\">7</Data></Cell>\r\n    <Cell ss:Index=\"5\" ss:StyleID=\"s68\"><Data ss:Type=\"String\">C</Data></Cell>\r\n    <Cell ss:StyleID=\"s69\"><Data ss:Type=\"String\">G</Data></Cell>\r\n    <Cell ss:Index=\"8\" ss:Formula=\"=RC[-6]+RC[-5]\"><Data ss:Type=\"Number\">10</Data></Cell>\r\n    <Cell ss:Index=\"10\" ss:Formula=\"=RC[-5]&amp;RC[-4]\"><Data ss:Type=\"String\">CG</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell ss:StyleID=\"s70\"><Data ss:Type=\"String\">Test with (&quot;) in string</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">4</Data></Cell>\r\n    <Cell ss:StyleID=\"s63\"><Data ss:Type=\"Number\">8</Data></Cell>\r\n    <Cell ss:Index=\"5\" ss:StyleID=\"s71\"><Data ss:Type=\"String\">D</Data></Cell>\r\n    <Cell><Data ss:Type=\"String\">H</Data></Cell>\r\n    <Cell ss:Index=\"8\" ss:Formula=\"=RC[-6]+RC[-5]\"><Data ss:Type=\"Number\">12</Data></Cell>\r\n    <Cell ss:Index=\"10\" ss:Formula=\"=RC[-5]&amp;RC[-4]\"><Data ss:Type=\"String\">DH</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell ss:Index=\"8\" ss:Formula=\"=SUM(R[-4]C[-6]:R[-1]C[-6])\"><Data\r\n      ss:Type=\"Number\">10</Data></Cell>\r\n    <Cell ss:Formula=\"=SUM(R[-4]C[-6]:R[-1]C[-6])\"><Data ss:Type=\"Number\">26</Data></Cell>\r\n    <Cell ss:Formula=\"=SUM(R[-4]C[-8]:R[-1]C[-7])\"><Data ss:Type=\"Number\">36</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell ss:Index=\"2\"><Data ss:Type=\"Number\">1.23</Data></Cell>\r\n    <Cell><Data ss:Type=\"Boolean\">1</Data></Cell>\r\n    <Cell ss:StyleID=\"s72\"/>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell ss:Index=\"2\"><Data ss:Type=\"Number\">2.34</Data></Cell>\r\n    <Cell><Data ss:Type=\"Boolean\">0</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell ss:Index=\"2\"><Data ss:Type=\"Number\">3.45</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\" ss:Height=\"13.5\"/>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell ss:StyleID=\"s72\"><Data ss:Type=\"DateTime\">1960-12-19T00:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"3\" ss:StyleID=\"s73\"><Data ss:Type=\"String\">TOP</Data></Cell>\r\n    <Cell ss:Index=\"7\" ss:Formula=\"=#N/A\"><Data ss:Type=\"Error\">#N/A</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell ss:StyleID=\"s74\"><Data ss:Type=\"Number\">1.5</Data></Cell>\r\n    <Cell ss:Index=\"7\" ss:Formula=\"=12/0\"><Data ss:Type=\"Error\">#DIV/0!</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\" ss:Height=\"13.5\">\r\n    <Cell ss:Index=\"3\" ss:StyleID=\"s75\"><Data ss:Type=\"String\">BOTTOM</Data></Cell>\r\n   </Row>\r\n   <Row ss:Index=\"14\" ss:AutoFitHeight=\"0\">\r\n    <Cell ss:Index=\"3\" ss:StyleID=\"s76\"><Data ss:Type=\"String\">LEFT</Data></Cell>\r\n   </Row>\r\n   <Row ss:Index=\"16\" ss:AutoFitHeight=\"0\">\r\n    <Cell ss:Index=\"3\" ss:StyleID=\"s77\"><Data ss:Type=\"String\">RIGHT</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\" ss:Height=\"13.5\"/>\r\n   <Row ss:AutoFitHeight=\"0\" ss:Height=\"13.5\">\r\n    <Cell ss:Index=\"2\" ss:MergeAcross=\"1\" ss:MergeDown=\"1\" ss:StyleID=\"m42221568\"><Data\r\n      ss:Type=\"String\">BOX</Data></Cell>\r\n    <Cell ss:Index=\"5\" ss:StyleID=\"s85\"/>\r\n    <Cell ss:Index=\"7\"><Data ss:Type=\"String\">Test Column 1</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell ss:Index=\"8\"><Data ss:Type=\"String\">Test Column 2</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell ss:Index=\"9\"><Data ss:Type=\"String\">Test Column 3</Data></Cell>\r\n   </Row>\r\n  </Table>\r\n  <WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\">\r\n   <PageSetup>\r\n    <Header x:Margin=\"0.3\"/>\r\n    <Footer x:Margin=\"0.3\"/>\r\n    <PageMargins x:Bottom=\"0.75\" x:Left=\"0.7\" x:Right=\"0.7\" x:Top=\"0.75\"/>\r\n   </PageSetup>\r\n   <Unsynced/>\r\n   <Print>\r\n    <ValidPrinterInfo/>\r\n    <HorizontalResolution>600</HorizontalResolution>\r\n    <VerticalResolution>600</VerticalResolution>\r\n   </Print>\r\n   <Selected/>\r\n   <Panes>\r\n    <Pane>\r\n     <Number>3</Number>\r\n     <ActiveRow>17</ActiveRow>\r\n     <ActiveCol>4</ActiveCol>\r\n    </Pane>\r\n   </Panes>\r\n   <ProtectObjects>False</ProtectObjects>\r\n   <ProtectScenarios>False</ProtectScenarios>\r\n   <AllowFormatCells/>\r\n   <AllowSizeCols/>\r\n   <AllowSizeRows/>\r\n   <AllowInsertCols/>\r\n   <AllowInsertRows/>\r\n   <AllowInsertHyperlinks/>\r\n   <AllowDeleteCols/>\r\n   <AllowDeleteRows/>\r\n   <AllowSort/>\r\n   <AllowFilter/>\r\n   <AllowUsePivotTables/>\r\n  </WorksheetOptions>\r\n </Worksheet>\r\n <Worksheet ss:Name=\"Report Data\">\r\n  <Table ss:ExpandedColumnCount=\"7\" ss:ExpandedRowCount=\"14\" x:FullColumns=\"1\"\r\n   x:FullRows=\"1\" ss:DefaultRowHeight=\"15\">\r\n   <Column ss:AutoFitWidth=\"0\" ss:Width=\"66.600000000000009\"/>\r\n   <Column ss:AutoFitWidth=\"0\" ss:Width=\"68.399999999999991\"/>\r\n   <Column ss:AutoFitWidth=\"0\" ss:Width=\"62.400000000000006\"/>\r\n   <Column ss:Width=\"69.599999999999994\"/>\r\n   <Column ss:Index=\"6\" ss:Width=\"69.599999999999994\"/>\r\n   <Column ss:AutoFitWidth=\"0\" ss:Width=\"64.8\"/>\r\n   <Row ss:AutoFitHeight=\"0\" ss:Height=\"31.5\">\r\n    <Cell ss:StyleID=\"s86\"><Data ss:Type=\"String\">Heading 1</Data></Cell>\r\n    <Cell ss:StyleID=\"s86\"><Data ss:Type=\"String\">Heading 2</Data></Cell>\r\n    <Cell ss:StyleID=\"s86\"><Data ss:Type=\"String\">Third Heading</Data></Cell>\r\n    <Cell ss:StyleID=\"s86\"><Data ss:Type=\"String\">Date Heading</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s86\"><Data ss:Type=\"String\">Adjusted Date</Data></Cell>\r\n    <Cell ss:StyleID=\"s86\"><Data ss:Type=\"String\">Adjusted Number</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell><Data ss:Type=\"String\">ABC</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">1</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\"><Data ss:Type=\"Number\">1.1100000000000001</Data></Cell>\r\n    <Cell ss:StyleID=\"s88\"><Data ss:Type=\"DateTime\">2001-01-01T00:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s88\" ss:Formula=\"=RC[-2]-RC[-4]\"><Data\r\n      ss:Type=\"DateTime\">2000-12-31T00:00:00.000</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\" ss:Formula=\"=RC[-5]*RC[-4]\"><Data ss:Type=\"Number\">1.1100000000000001</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell><Data ss:Type=\"String\">BCD</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">2</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\"><Data ss:Type=\"Number\">2.2200000000000002</Data></Cell>\r\n    <Cell ss:StyleID=\"s88\"><Data ss:Type=\"DateTime\">2002-02-02T00:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s88\" ss:Formula=\"=RC[-2]-RC[-4]\"><Data\r\n      ss:Type=\"DateTime\">2002-01-31T00:00:00.000</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\" ss:Formula=\"=RC[-5]*RC[-4]\"><Data ss:Type=\"Number\">4.4400000000000004</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell><Data ss:Type=\"String\">CDE</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">3</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\"><Data ss:Type=\"Number\">3.33</Data></Cell>\r\n    <Cell ss:StyleID=\"s88\"><Data ss:Type=\"DateTime\">2003-03-03T00:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s88\" ss:Formula=\"=RC[-2]-RC[-4]\"><Data\r\n      ss:Type=\"DateTime\">2003-02-28T00:00:00.000</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\" ss:Formula=\"=RC[-5]*RC[-4]\"><Data ss:Type=\"Number\">9.99</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell><Data ss:Type=\"String\">DEF</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">4</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\"><Data ss:Type=\"Number\">4.4400000000000004</Data></Cell>\r\n    <Cell ss:StyleID=\"s88\"><Data ss:Type=\"DateTime\">2004-04-03T23:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s88\" ss:Formula=\"=RC[-2]-RC[-4]\"><Data\r\n      ss:Type=\"DateTime\">2004-03-30T23:00:00.000</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\" ss:Formula=\"=RC[-5]*RC[-4]\"><Data ss:Type=\"Number\">17.760000000000002</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell><Data ss:Type=\"String\">EFG</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">5</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\"><Data ss:Type=\"Number\">5.55</Data></Cell>\r\n    <Cell ss:StyleID=\"s88\"><Data ss:Type=\"DateTime\">2005-05-04T23:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s88\" ss:Formula=\"=RC[-2]-RC[-4]\"><Data\r\n      ss:Type=\"DateTime\">2005-04-29T23:00:00.000</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\" ss:Formula=\"=RC[-5]*RC[-4]\"><Data ss:Type=\"Number\">27.75</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell><Data ss:Type=\"String\">FGH</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">6</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\"><Data ss:Type=\"Number\">6.66</Data></Cell>\r\n    <Cell ss:StyleID=\"s88\"><Data ss:Type=\"DateTime\">2006-06-05T23:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s88\" ss:Formula=\"=RC[-2]-RC[-4]\"><Data\r\n      ss:Type=\"DateTime\">2006-05-30T23:00:00.000</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\" ss:Formula=\"=RC[-5]*RC[-4]\"><Data ss:Type=\"Number\">39.96</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell><Data ss:Type=\"String\">GHI</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">7</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\"><Data ss:Type=\"Number\">7.77</Data></Cell>\r\n    <Cell ss:StyleID=\"s88\"><Data ss:Type=\"DateTime\">2007-07-06T23:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s88\" ss:Formula=\"=RC[-2]-RC[-4]\"><Data\r\n      ss:Type=\"DateTime\">2007-06-29T23:00:00.000</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\" ss:Formula=\"=RC[-5]*RC[-4]\"><Data ss:Type=\"Number\">54.39</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell><Data ss:Type=\"String\">HIJ</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">8</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\"><Data ss:Type=\"Number\">8.8800000000000008</Data></Cell>\r\n    <Cell ss:StyleID=\"s88\"><Data ss:Type=\"DateTime\">2008-08-07T23:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s88\" ss:Formula=\"=RC[-2]-RC[-4]\"><Data\r\n      ss:Type=\"DateTime\">2008-07-30T23:00:00.000</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\" ss:Formula=\"=RC[-5]*RC[-4]\"><Data ss:Type=\"Number\">71.040000000000006</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell><Data ss:Type=\"String\">IJK</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">9</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\"><Data ss:Type=\"Number\">9.99</Data></Cell>\r\n    <Cell ss:StyleID=\"s88\"><Data ss:Type=\"DateTime\">2009-09-08T23:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s88\" ss:Formula=\"=RC[-2]-RC[-4]\"><Data\r\n      ss:Type=\"DateTime\">2009-08-30T23:00:00.000</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\" ss:Formula=\"=RC[-5]*RC[-4]\"><Data ss:Type=\"Number\">89.91</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell><Data ss:Type=\"String\">JKL</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">10</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\"><Data ss:Type=\"Number\">11.1</Data></Cell>\r\n    <Cell ss:StyleID=\"s88\"><Data ss:Type=\"DateTime\">2010-10-09T23:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s88\" ss:Formula=\"=RC[-2]-RC[-4]\"><Data\r\n      ss:Type=\"DateTime\">2010-09-29T23:00:00.000</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\" ss:Formula=\"=RC[-5]*RC[-4]\"><Data ss:Type=\"Number\">111</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell><Data ss:Type=\"String\">KLM</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">11</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\"><Data ss:Type=\"Number\">12.21</Data></Cell>\r\n    <Cell ss:StyleID=\"s88\"><Data ss:Type=\"DateTime\">2011-11-11T00:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s88\" ss:Formula=\"=RC[-2]-RC[-4]\"><Data\r\n      ss:Type=\"DateTime\">2011-10-31T00:00:00.000</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\" ss:Formula=\"=RC[-5]*RC[-4]\"><Data ss:Type=\"Number\">134.31</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell><Data ss:Type=\"String\">LMN</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">12</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\"><Data ss:Type=\"Number\">13.32</Data></Cell>\r\n    <Cell ss:StyleID=\"s88\"><Data ss:Type=\"DateTime\">2012-12-12T00:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s88\" ss:Formula=\"=RC[-2]-RC[-4]\"><Data\r\n      ss:Type=\"DateTime\">2012-11-30T00:00:00.000</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\" ss:Formula=\"=RC[-5]*RC[-4]\"><Data ss:Type=\"Number\">159.84</Data></Cell>\r\n   </Row>\r\n   <Row ss:AutoFitHeight=\"0\">\r\n    <Cell><Data ss:Type=\"String\">ZYX</Data></Cell>\r\n    <Cell><Data ss:Type=\"Number\">-1</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\"><Data ss:Type=\"Number\">-1.1100000000000001</Data></Cell>\r\n    <Cell ss:StyleID=\"s88\"><Data ss:Type=\"DateTime\">1999-12-01T00:00:00.000</Data></Cell>\r\n    <Cell ss:Index=\"6\" ss:StyleID=\"s88\" ss:Formula=\"=RC[-2]-RC[-4]\"><Data\r\n      ss:Type=\"DateTime\">1999-12-02T00:00:00.000</Data></Cell>\r\n    <Cell ss:StyleID=\"s87\" ss:Formula=\"=RC[-5]*RC[-4]\"><Data ss:Type=\"Number\">1.1100000000000001</Data></Cell>\r\n   </Row>\r\n  </Table>\r\n  <WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\">\r\n   <PageSetup>\r\n    <Header x:Margin=\"0.3\"/>\r\n    <Footer x:Margin=\"0.3\"/>\r\n    <PageMargins x:Bottom=\"0.75\" x:Left=\"0.7\" x:Right=\"0.7\" x:Top=\"0.75\"/>\r\n   </PageSetup>\r\n   <Unsynced/>\r\n   <Print>\r\n    <ValidPrinterInfo/>\r\n    <HorizontalResolution>600</HorizontalResolution>\r\n    <VerticalResolution>600</VerticalResolution>\r\n   </Print>\r\n   <ProtectObjects>False</ProtectObjects>\r\n   <ProtectScenarios>False</ProtectScenarios>\r\n   <AllowFormatCells/>\r\n   <AllowSizeCols/>\r\n   <AllowSizeRows/>\r\n   <AllowInsertCols/>\r\n   <AllowInsertRows/>\r\n   <AllowInsertHyperlinks/>\r\n   <AllowDeleteCols/>\r\n   <AllowDeleteRows/>\r\n   <AllowSort/>\r\n   <AllowFilter/>\r\n   <AllowUsePivotTables/>\r\n  </WorksheetOptions>\r\n  <ConditionalFormatting xmlns=\"urn:schemas-microsoft-com:office:excel\">\r\n   <Range>R2C3:R14C3</Range>\r\n   <Condition>\r\n    <Qualifier>Greater</Qualifier>\r\n    <Value1>0</Value1>\r\n    <Format Style='color:#006100;background:#C6EFCE'/>\r\n   </Condition>\r\n   <Condition>\r\n    <Qualifier>Less</Qualifier>\r\n    <Value1>0</Value1>\r\n    <Format Style='color:#9C0006;background:#FFC7CE'/>\r\n   </Condition>\r\n  </ConditionalFormatting>\r\n </Worksheet>\r\n</Workbook>\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/data/continents/Africa.txt",
    "content": "Algeria\nAngola\nBenin\nBotswana\nBurkina\nBurundi\nCameroon\nCape Verde\nCentral African Republic\nChad\nComoros\nCongo\nCongo, Democratic Republic of\nDjibouti\nEgypt\nEquatorial Guinea\nEritrea\nEthiopia\nGabon\nGambia\nGhana\nGuinea\nGuinea-Bissau\nIvory Coast\nKenya\nLesotho\nLiberia\nLibya\nMadagascar\nMalawi\nMali\nMauritania\nMauritius\nMorocco\nMozambique\nNamibia\nNiger\nNigeria\nRwanda\nSao Tome and Principe \nSenegal\nSeychelles\nSierra Leone\nSomalia\nSouth Africa\nSouth Sudan\nSudan\nSwaziland\nTanzania\nTogo\nTunisia\nUganda\nZambia\nZimbabwe\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/data/continents/Asia.txt",
    "content": "Afghanistan\nBahrain\nBangladesh\nBhutan\nBrunei\nBurma (Myanmar)\nCambodia\nChina\nEast Timor\nIndia\nIndonesia\nIran\nIraq\nIsrael\nJapan\nJordan\nKazakhstan\nKorea, North\nKorea, South\nKuwait\nKyrgyzstan\nLaos\nLebanon\nMalaysia\nMaldives\nMongolia\nNepal\nOman\nPakistan\nPhilippines\nQatar\nRussian Federation\nSaudi Arabia\nSingapore\nSri Lanka\nSyria\nTajikistan\nThailand\nTurkey\nTurkmenistan\nUnited Arab Emirates\nUzbekistan\nVietnam\nYemen\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/data/continents/Europe.txt",
    "content": "Albania\nAndorra\nArmenia\nAustria\nAzerbaijan\nBelarus\nBelgium\nBosnia and Herzegovina\nBulgaria\nCroatia\nCyprus\nCzech Republic\nDenmark\nEstonia\nFinland\nFrance\nGeorgia\nGermany\nGreece\nHungary\nIceland\nIreland\nItaly\nLatvia\nLiechtenstein\nLithuania\nLuxembourg\nMacedonia\nMalta\nMoldova\nMonaco\nMontenegro\nNetherlands\nNorway\nPoland\nPortugal\nRomania\nSan Marino\nSerbia\nSlovakia\nSlovenia\nSpain\nSweden\nSwitzerland\nUkraine\nUnited Kingdom\nVatican City\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/data/continents/North America.txt",
    "content": "Antigua and Barbuda\nBahamas\nBarbados\nBelize\nCanada\nCosta Rica\nCuba\nDominica\nDominican Republic\nEl Salvador\nGrenada\nGuatemala\nHaiti\nHonduras\nJamaica\nMexico\nNicaragua\nPanama\nSaint Kitts and Nevis\nSaint Lucia\nSaint Vincent and the Grenadines\nTrinidad and Tobago\nUnited States\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/data/continents/Oceania.txt",
    "content": "Australia\nFiji\nKiribati\nMarshall Islands\nMicronesia\nNauru\nNew Zealand\nPalau\nPapua New Guinea\nSamoa\nSolomon Islands\nTonga\nTuvalu\nVanuatu\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/data/continents/South America.txt",
    "content": "Argentina\nBolivia\nBrazil\nChile\nColombia\nEcuador\nGuyana\nParaguay\nPeru\nSuriname\nUruguay\nVenezuela\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/Examples/runall.php",
    "content": "<?php\n/**\n * PHPExcel\n *\n * Copyright (C) 2006 - 2014 PHPExcel\n *\n * This library is free software; you can redistribute it and/or\n * modify it under the terms of the GNU Lesser General Public\n * License as published by the Free Software Foundation; either\n * version 2.1 of the License, or (at your option) any later version.\n *\n * This library is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this library; if not, write to the Free Software\n * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n *\n * @category   PHPExcel\n * @package    PHPExcel\n * @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n * @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n * @version    ##VERSION##, ##DATE##\n */\n\n/** Error reporting */\nerror_reporting(E_ALL);\n\nif (PHP_SAPI != 'cli') {\n\tdie ('This script executes all tests, and should only be run from the command line');\n}\n\n// List of tests\n$aTests = array(\n\t  '01simple.php'\n\t, '01simplePCLZip.php'\n\t, '02types.php'\n\t, '02types-xls.php'\n\t, '03formulas.php'\n\t, '04printing.php'\n\t, '05featuredemo.php'\n\t, '06largescale.php'\n\t, '06largescale-with-cellcaching.php'\n\t, '06largescale-with-cellcaching-sqlite.php'\n\t, '06largescale-with-cellcaching-sqlite3.php'\n\t, '06largescale-xls.php'\n\t, '07reader.php'\n\t, '07readerPCLZip.php'\n\t, '08conditionalformatting.php'\n\t, '08conditionalformatting2.php'\n\t, '09pagebreaks.php'\n\t, '10autofilter.php'\n\t, '10autofilter-selection-1.php'\n\t, '10autofilter-selection-2.php'\n\t, '10autofilter-selection-display.php'\n\t, '11documentsecurity.php'\n\t, '11documentsecurity-xls.php'\n\t, '12cellProtection.php'\n\t, '13calculation.php'\n    , '13calculationCyclicFormulae.php'\n\t, '14excel5.php'\n\t, '15datavalidation.php'\n\t, '15datavalidation-xls.php'\n\t, '16csv.php'\n\t, '17html.php'\n\t, '18extendedcalculation.php'\n\t, '19namedrange.php'\n\t, '20readexcel5.php'\n\t, '21pdf.php'\n\t, '22heavilyformatted.php'\n\t, '23sharedstyles.php'\n\t, '24readfilter.php'\n\t, '25inmemoryimage.php'\n\t, '26utf8.php'\n\t, '27imagesexcel5.php'\n\t, '28iterator.php'\n\t, '29advancedvaluebinder.php'\n\t, '30template.php'\n\t, '31docproperties_write.php'\n\t, '31docproperties_write-xls.php'\n\t, '32chartreadwrite.php'\n\t, '33chartcreate-area.php'\n\t, '33chartcreate-bar.php'\n\t, '33chartcreate-bar-stacked.php'\n\t, '33chartcreate-column.php'\n\t, '33chartcreate-column-2.php'\n\t, '33chartcreate-line.php'\n\t, '33chartcreate-pie.php'\n\t, '33chartcreate-radar.php'\n\t, '33chartcreate-stock.php'\n\t, '33chartcreate-multiple-charts.php'\n\t, '33chartcreate-composite.php'\n\t, '34chartupdate.php'\n\t, '35chartrender.php'\n\t, '36chartreadwriteHTML.php'\n\t, '36chartreadwritePDF.php'\n\t, '37page_layout_view.php'\n\t, '38cloneWorksheet.php'\n    , '39dropdown.php'\n\t, '40duplicateStyle.php'\n\t, '41password.php'\n\t, '42richText.php'\n\t, 'OOCalcReader.php'\n\t, 'OOCalcReaderPCLZip.php'\n\t, 'SylkReader.php'\n\t, 'Excel2003XMLReader.php'\n\t, 'XMLReader.php'\n\t, 'GnumericReader.php'\n);\n\n// First, clear all previous run results\nforeach ($aTests as $sTest) {\n\t@unlink( str_replace('.php', '.xls', \t$sTest) );\n\t@unlink( str_replace('.php', '.xlsx', \t$sTest) );\n\t@unlink( str_replace('.php', '.csv',\t$sTest) );\n\t@unlink( str_replace('.php', '.htm',\t$sTest) );\n\t@unlink( str_replace('.php', '.pdf',\t$sTest) );\n}\n\n// Run all tests\nforeach ($aTests as $sTest) {\n\techo '============== TEST ==============' . \"\\r\\n\";\n\techo 'Test name: ' . $sTest . \"\\r\\n\";\n\techo \"\\r\\n\";\n\techo shell_exec('php ' . $sTest);\n\techo \"\\r\\n\";\n\techo \"\\r\\n\";\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/changelog.txt",
    "content": "**************************************************************************************\n* PHPExcel\n*\n* Copyright (c) 2006 - 2014 PHPExcel\n*\n* This library is free software; you can redistribute it and/or\n* modify it under the terms of the GNU Lesser General Public\n* License as published by the Free Software Foundation; either\n* version 2.1 of the License, or (at your option) any later version.\n*\n* This library is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n* Lesser General Public License for more details.\n*\n* You should have received a copy of the GNU Lesser General Public\n* License along with this library; if not, write to the Free Software\n* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n*\n* @copyright  Copyright (c) 2006 - 2014 PHPExcel (http://www.codeplex.com/PHPExcel)\n* @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL\n* @version    1.8.1, 2015-04-30\n**************************************************************************************\n\n2015-04-30 (v1.8.1):\n- Bugfix:   (goncons)         Work Item GH-397  - Fix for Writing an Open Document cell with non-numeric formula\n- Bugfix:   (sarciszewski)    Work Item GH-329  - Avoid potential divide by zero in basedrawing\n- Bugfix:   (ymaerschalck)    Work Item GH-405  - XML External Entity (XXE) Processing, different behaviour between simplexml_load_string() and simplexml_load_file().\n- Bugfix:   (MBaker)                            - Fix to ensure that current cell is maintained when executing formula calculations\n- Bugfix:   (MBaker)          Work Item GH-350  - Keep/set the value on Reader _loadSheetsOnly as NULL, courtesy of Restless-ET \n- Bugfix:   (MBaker)          Work Item CP18105 - Loading an Excel 2007 spreadsheet throws an \"Autofilter must be set on a range of cells\" exception\n- Bugfix:   (MBaker)          Work Item GH-388  - Fix to autoloader registration for backward compatibility with PHP 5.2.0 not accepting the prepend flag\n- Bugfix:   (MBaker)          Work Item GH-384  - DOM loadHTMLFile() failing with options flags when using PHP < 5.4.0\n- Bugfix:   (MBaker)                            - Fix for percentage operator in formulae for BIFF Writer\n- Bugfix:   (MBaker)                            - Fix to getStyle() call for cell object\n- Bugfix:   (MBaker)                            - Discard Autofilters in Excel2007 Reader when filter range isn't a valid range\n- Bugfix:   (frozenstupidity) Work Item GH-423  - Fix invalid NA return in VLOOKUP\n- Bugfix:   (wiseloren)       Work Item CP21454 - \"No Impact\" conditional formatting fix for NumberFormat\n- Bugfix:   (bobwitlox)       Work Item GH-467  - Bug in Excel2003XML reader, parsing merged cells\n- Bugfix:   (MBaker)          Work Item GH-302  - Fix for CEIL() and FLOOR() when number argument is zero\n- Bugfix:   (MBaker)                            - Remove cells cleanly when calling RemoveRow() or RemoveColumn()\n- General:  (MBaker)                            - Small performance improvement for autosize columns\n- General:  (frost-nzcr4)     Work Item GH-379  - Change the getter/setter for zeroHeight to camel case\n- General:  (MBaker)          Work Item GH-394  - DefaultValueBinder is too much aggressive when converting string to numeric\n- General:  (MBaker)                            - Default precalculate formulas to false for writers\n- General:  (MBaker)                            - Set default Cyclic Reference behaviour to 1 to eliminate exception when using a single cyclic iteration in formulae\n- General:  (MBaker)          Work Item GH-396  - Some Excel writer libraries erroneously use Codepage 21010 for UTF-16LE\n- Feature:  (WiktrzGE)        Work Item GH-404  - Methods to manage most of the existing options for Chart Axis, Major Grid-lines and Minor Grid-lines\n- Feature:  (frost-nzcr4)     Work Item GH-403  - ODS read/write comments in the cell\n- Feature:  (CQD)             Work Item GH-389  - Additional Mac CJK codepage definitions\n- Feature:  (bolovincev)      Work Item GH-269  - Update Worksheet.php getStyleByColumnAndRow() to allow a range of cells rather than just a single cell\n- Feature:  (MBaker)                            - New methods added for testing cell status within merge groups\n- Feature:  (cifren/MBaker)   Work Item GH-205  - Handling merge cells in HTML Reader\n- Feature:  (MBaker)                            - Helper to convert basic HTML markup to a Rich Text object\n- Feature:  (MBaker)                            - Improved Iterators\n                                                    New Column Iterator\n                                                    Support for row and column ranges\n                                                    Improved handling for next/prev\n- Security: (MBaker)                            - XML filescan in XML-based Readers to prevent XML Entity Expansion (XEE)\n                                                    (see http://projects.webappsec.org/w/page/13247002/XML%20Entity%20Expansion for an explanation of XEE injection) attacks\n                                                  Reference CVE-2015-3542 - Identification of problem courtesy of Dawid Golunski (Pentest Ltd.)\n\n\n                                                  2014-03-02 (v1.8.0):\n- Bugfix:   (MBaker)          Work item CP19830 - Undefined variable: fileHandle in CSV Reader\n- Bugfix:   (MBaker)          Work item CP19968 - Out of memory in style/supervisor.php\n- Bugfix:   (MBaker)                            - Style error with merged cells in PDF Writer\n- Bugfix:   (MBaker)                            - Problem with cloning worksheets\n- Bugfix:   (tavoarcila)      Work Item GH-259  - Bug fix reading Open Office files\n- Bugfix:   (MBaker)          Work item CP20397 - Serious bug in absolute cell reference used in shared formula\n                                                  Would also have affected insert/delete column/row\n- Bugfix:   (RomanSyroeshko)  Work Item GH-267  - CHOOSE() returns \"#VALUE!\" if the 1st entry is chosen\n- Bugfix:   (Gemorroj)        Work Item GH-268  - When duplicating styles, styles shifted by one column to the right\n                                                  Fix also applied to duplicating conditional styles\n- Bugfix:   (IndrekHaav)      Work Item GH-212  - Fix for formulae that reference a sheet whose name begins with a digit:\n                                                  these were erroneously identified as numeric values, causing the parser to throw an undefined variable error.\n- Bugfix:   (IndrekHaav)      Work Item CP16208 - Fixed undefined variable error due to $styleArray being used before it's initialised\n- Bugfix:   (PowerKiKi)       Work Item GH-273  - ISTEXT() return wrong result if referencing an empty but formatted cell\n- Bugfix:   (PowerKiKi)       Work Item GH-270/GH-31  - Binary comparison of strings are case insensitive\n- Bugfix:   (MBaker)          Work Item GH-275  - Insert New Row/Column Before is not correctly updating formula references\n- Bugfix:   (MBaker)          Work Item GH-257  - Passing an array of cells to _generateRow() in the HTML/PDF Writer causes caching problems with last cell in the range\n- Bugfix:   (MBaker)          Work Item GH-193  - Fix to empty worksheet garbage collection when using cell caching\n- Bugfix:   (Jazzo)           Work Item GH-248  - Excel2007 does not correctly mark rows as hidden\n- Bugfix:   (Roy Shahbazian)  Work Item GH-299  - Fixed typo in Chart/Layout set/getYMode()\n- Bugfix:   (EliuFlorez)      Work item GH-279  - Fatal error: Call to a member function cellExists() line: 3327 in calculation.php if referenced worksheet doesn't exist\n- Bugfix:   (MBaker)          Work Item GH-290  - AdvancedValueBinder \"Division by zero\"-error\n- Bugfix:   (MBaker)          Work Item CP20604 - Adding Sheet to Workbook Bug\n- Bugfix:   (MBaker)          Work item CP20703 - Calculation engine incorrectly evaluates empty cells as #VALUE\n- Bugfix:   (MBaker)          Work item CP20760 - Formula references to cell on another sheet in ODS files\n- Bugfix:   (MBaker)          Work item GH321,GH158,CP17824 - LibreOffice created XLSX files results in an empty file.\n- Feature:  (amerov)                            - Implementation of the Excel HLOOKUP() function\n- Feature:  (MBaker)                            - Added \"Quote Prefix\" to style settings (Excel2007 Reader and Writer only)\n- Feature:  (MBaker)                            - Added Horizontal FILL alignment for Excel5 and Excel2007 Readers/Writers, and Horizontal DISTRIBUTED alignment for Excel2007 Reader/Writer\n- Feature:  (trvrnrth)        Work Item GH-261  - Add support for reading protected (RC4 encrypted) .xls files\n- Feature:  (LWol)            Work Item GH-252  - Adding support for macros, Ribbon in Excel 2007\n- General:  (cdhutch)         Work item CP20055 - Remove array_shift in ReferenceHelper::insertNewBefore improves column or row delete speed\n- General:  (MBaker)                            - Improve stock chart handling and rendering, with help from Swashata Ghosh\n- General:  (MBaker)                            - Fix to calculation properties for Excel2007 so that the opening application will only recalculate on load if it's actually required\n- General:  (MBaker)                            - Modified Excel2007 Writer to default preCalculateFormulas to false\n                                                  Note that autosize columns will still recalculate affected formulae internally\n- General:  (dresenhista)     Work Item GH-242  - Functionality to getHighestRow() for a specified column, and getHighestColumn() for a specified row\n- General:  (adamriyadi)      Work Item GH-247  - Modify PHPExcel_Reader_Excel2007 to use zipClass from PHPExcel_Settings::getZipClass()\n                                                  This allows the use of PCLZip when reading for people that don't have access to ZipArchive\n- General:  (infojunkie)      Work Item GH-276  - Convert properties to string in OOCalc reader\n- Security: (maartenba)       Work Item GH-322  - Disable libxml external entity loading by default.\n                                                  This is to prevent XML External Entity Processing (XXE) injection attacks (see http://websec.io/2012/08/27/Preventing-XEE-in-PHP.html for an explanation of XXE injection).\n                                                  Reference CVE-2014-2054\n\n\n2013-06-02 (v1.7.9):\n- Feature:  (MBaker)    Include charts option for HTML Writer\n- Feature:  (MBaker)    Added composer file\n- Feature:  (MBaker)    Added getStyle() method to Cell object\n- Bugfix:   (Asker)     Work item 18777  - Error in PHPEXCEL/Calculation.php script on line 2976 (stack pop check)\n- Bugfix:   (MBaker)    Work item 18794  - CSV files without a file extension being identified as HTML\n- Bugfix:   (AndreKR)   Work item GH-66  - Wrong check for maximum number of rows in Excel5 Writer\n- Bugfix:   (MBaker)    Work item GH-67  - Cache directory for DiscISAM cache storage cannot be set\n- Bugfix:   (MBaker)    Work item 17976  - Fix to Excel2007 Reader for hyperlinks with an anchor fragment (following a #), otherwise they were treated as sheet references\n- Bugfix:   (MBaker)    Work item 18963  - getSheetNames() fails on numeric (floating point style) names with trailing zeroes\n- Bugfix:   (MBaker)    Work item GH-130 - Single cell print area\n- General:  (kea)       Work item GH-69  - Improved AdvancedValueBinder for currency\n- General:  (MBaker)    Work items 17936 and 17840 - Fix for environments where there is no access to /tmp but to upload_tmp_dir\n                        Provided an option to set the sys_get_temp_dir() call to use the upload_tmp_dir; though by default the standard temp directory will still be used\n- General:  (amironov ) Work item GH-84  - Search style by identity in PHPExcel_Worksheet::duplicateStyle()\n- General:  (karak)     Work item GH-85  - Fill SheetView IO in Excel5\n- General:  (cfhay)     Work item 18958  - Memory and Speed improvements in PHPExcel_Reader_Excel5\n- General:  (MBaker)    Work item GH-78  - Modify listWorksheetNames() and listWorksheetInfo to use XMLReader with streamed XML rather than SimpleXML\n- General:  (dbonsch)                      Restructuring of PHPExcel Exceptions\n- General:  (MBaker)    Work items 16926 and 15145 - Refactor Calculation Engine from singleton to a Multiton\n                        Ensures that calculation cache is maintained independently for different workbooks\n- General:  (MBaker)                       Modify cell's getCalculatedValue() method to return the content of RichText objects rather than the RichText object itself\n- Bugfix:   (techhead)  Work item GH-70  - Fixed formula/formatting bug when removing rows\n- Bugfix:   (alexgann)  Work item GH-63  - Fix to cellExists for non-existent namedRanges\n- Bugfix:   (MBaker)    Work item 18844  - cache_in_memory_gzip \"eats\" last worksheet line, cache_in_memory doesn't\n- Feature:  (Progi1984) Work item GH-22  - Sheet View in Excel5 Writer\n- Bugfix:   (amironov)  Work item GH-82  - PHPExcel_Worksheet::getCellCollection() may not return last cached cell\n- Bugfix:   (teso)      Work item 18551  - Rich Text containing UTF-8 characters creating unreadable content with Excel5 Writer\n- Bugfix:   (MBaker)    Work item GH-104 - echo statements in HTML.php\n- Feature:  (Progi1984) Work item GH-8/CP11704 : Conditional formatting in Excel 5 Writer\n- Bugfix:   (MBaker)    Work item GH-113 - canRead() Error for GoogleDocs ODS files: in ODS files from Google Docs there is no mimetype file\n- Bugfix:   (MBaker)    Work item GH-80  - \"Sheet index is out of bounds.\" Exception\n- Bugfix:   (ccorliss)  Work item GH-105 - Fixed number format fatal error\n- Bugfix:   (MBaker)                     - Add DROP TABLE in destructor for SQLite and SQLite3 cache controllers\n- Bugfix:   (alexgann)  Work item GH-154 - Fix merged-cell borders on HTML/PDF output\n- Bugfix:   (Shanto)    Work item GH-161 - Fix: Hyperlinks break when removing rows\n- Bugfix:   (neclimdul) Work item GH-166 - Fix Extra Table Row From Images and Charts\n\n\n2012-10-12 (v1.7.8):\n- Special:  (kkamkou)    Phar builder script to add phar file as a distribution option\n- Feature:  (MBaker)     Refactor PDF Writer to allow use with a choice of PDF Rendering library\n                         rather than restricting to tcPDF\n                         Current options are tcPDF, mPDF, DomPDF\n                         tcPDF Library has now been removed from the deployment bundle\n- Feature:  (MBaker)     Initial version of HTML Reader\n- Feature:  (Progi1984) & (blazzy) Work items 9605 - Implement support for AutoFilter in PHPExcel_Writer_Excel5\n- Feature:  (MBaker)     Modified ERF and ERFC Engineering functions to accept Excel 2010's modified acceptance of negative arguments\n- Feature:  (k1LoW)      Support SheetView `view` attribute (Excel2007)\n- Feature:  (MBaker)     Excel compatibility option added for writing CSV files\n                         While Excel 2010 can read CSV files with a simple UTF-8 BOM, Excel2007 and earlier require UTF-16LE encoded tab-separated files.\n                         The new setExcelCompatibility(TRUE) option for the CSV Writer will generate files with this formatting for easy import into Excel2007 and below.\n- Feature:  (MBaker)     Language implementations for Turkish (tr)\n- Feature:  (MBaker)     Added fraction tests to advanced value binder\n- Feature:  (MBaker)     Allow call to font setUnderline() for underline format to specify a simple boolean for UNDERLINE_NONE or UNDERLINE_SINGLE\n- General:  (alexgann)   Add Currency detection to the Advanced Value Binder\n- General:  (MBaker)     Work item 18404 - setCellValueExplicitByColumnAndRow() do not return PHPExcel_Worksheet\n- General:  (MBaker)     Work item 18324 - Reader factory doesn't read anymore XLTX and XLT files\n- General:  (MBaker)     Magic __toString() method added to Cell object to return raw data value as a string\n- General:  (alexgann)   Add cell indent to html rendering\n- General:  (Raghav1981) ZeroHeight for rows in sheet format\n- Bugfix:   (cyberconte) Patch 12318 - OOCalc cells containing <text:span> inside the <text:p> tag\n- Bugfix:   (schir1964)  Fix to listWorksheetInfo() method for OOCalc Reader\n- Bugfix:   (MBaker)     Support for \"e\" (epoch) date format mask\n                         Rendered as a 4-digit CE year in non-Excel outputs\n- Bugfix:   (MBaker)     Work items 15799 and 18278 - Background color cell is always black when editing cell\n- Bugfix:   (MBaker)     Work items 15905 and 18183 - Allow \"no impact\" to formats on Conditional Formatting\n- Bugfix:   (wackonline) OOCalc Reader fix for NULL cells\n- Bugfix:   (seltzlab)   Fix to excel2007 Chart Writer when a $plotSeriesValues is empty\n- Bugfix:   (MBaker)     Various fixes to Chart handling\n- Bugfix:   (MBaker)     Work item 18370 - Error loading xlsx file with column breaks\n- Bugfix:   (MBaker)     OOCalc Reader now handles percentage and currency data types\n- Bugfix:   (MBaker)     Work Item 18415 - mb_stripos empty delimiter\n- Bugfix:   (takaakik)   Work Item 15455 - getNestingLevel() Error on Excel5 Read\n- Bugfix:   (MBaker)     Fix to Excel5 Reader when cell annotations are defined before their referenced text objects\n- Bugfix:   (MBaker)     OOCalc Reader modified to process number-rows-repeated\n- Bugfix:   (MBaker)     Work item 18377 - Chart Title compatibility on Excel 2007\n- Bugfix:   (MBaker)     Work item 18146 - Chart Refresh returning cell reference rather than values\n- Bugfix:   (MBaker)     Work item 18145 - Autoshape being identified in twoCellAnchor when includeCharts is TRUE triggering load error\n- Bugfix:   (MBaker)     Work item 18325 - v-type texts for series labels now recognised and parsed correctly\n- Bugfix:   (wolf5x)     Work item 18492 - load file failed if the file has no extensionType\n- Bugfix:   (dverspui)   Pattern fill colours in Excel2007 Style Writer\n- Bugfix:   (MBaker)     Excel2007 Writer order of font style elements to conform with Excel2003 using compatibility pack\n- Bugfix:   (MBaker)     Work item 18425 - Problems with $_activeSheetIndex when decreased below 0.\n- Bugfix:   (MBaker)     Work item 18597 - PHPExcel_CachedObjectStorage_SQLite3::cacheMethodIsAvailable() uses class_exists - autoloader throws error\n- Bugfix:   (MBaker)     Work item 18598 - Cannot access private property PHPExcel_CachedObjectStorageFactory::$_cacheStorageMethod\n- Bugfix:   (MBaker)     Work item 18397 - Data titles for charts\n                         PHPExcel_Chart_Layout now has methods for getting/setting switches for displaying/hiding chart data labels\n- Bugfix:   (MBaker)     Discard single cell merge ranges when reading (stupid that Excel allows them in the first place)\n- Bugfix:   (MBaker)     Discard hidden autoFilter named ranges\n\n\n2012-05-19 (v1.7.7):\n- Bugfix:   (Progi1984) Work item 8916 - Support for Rich-Text in PHPExcel_Writer_Excel5\n- Bugfix:   (cyberconte) Work item 17471 - OOCalc cells contain same data bug?\n- Feature:  (schir1964) listWorksheetInfo() method added to Readers... courtesy of Christopher Mullins\n- Feature:  (MBaker)    Options for cell caching using Igbinary and SQLite/SQlite3.\n- Feature:  (MBaker)    Additional row iterator options: allow a start row to be defined in the constructor; seek(), and prev() methods added.\n- Feature:  (Progi1984) Work item 9759 - Implement document properties in Excel5 writer\n- Feature:  (MBaker)    Work item 16 - Implement chart functionality (EXPERIMENTAL)\n                        Initial definition of chart objects.\n                        Reading Chart definitions through the Excel2007 Reader\n                        Facility to render charts to images using the 3rd-party jpgraph library\n                        Writing Charts using the Excel2007 Writer\n- General:  (MBaker)    Fix to build to ensure that Examples are included with the documentation\n- General:  (MBaker)    Reduce cell caching overhead using dirty flag to ensure that cells are only rewritten to the cache if they have actually been changed\n- General:  (MBaker)    Improved memory usage in CSV Writer\n- General:  (MBaker)    Improved speed and memory usage in Excel5 Writer\n- General:  (MBaker)    Experimental -\n                        Added getHighestDataColumn(), getHighestDataRow(), getHighestRowAndColumn() and calculateWorksheetDataDimension() methods for the worksheet that return the highest row and column that have cell records\n- General:  (MBaker)    Change iterators to implement Iterator rather than extend CachingIterator, as a fix for PHP 5.4. changes in SPL\n- Bugfix:   (MBaker)    Work item 15459 - Invalid cell coordinate in Autofilter for Excel2007 Writer\n- Bugfix:   (MBaker)    Work item 15518 - PCLZip library issue\n- Bugfix:   (MBaker)    Work item 15537 - Excel2007 Reader canRead function bug\n- Bugfix:   (MBaker)    Support for Excel functions whose return can be used as either a value or as a cell reference depending on its context within a formula\n- Bugfix:   (gilles06)  Work item 15707 - ini_set() call in Calculation class destructor\n- Bugfix:   (MBaker)    Work item 15786 - RangeToArray strange array keys\n- Bugfix:   (MBaker)    Work item 15762 - INDIRECT() function doesn't work with named ranges\n- Bugfix:   (MBaker)    Locale-specific fix to text functions when passing a boolean argument instead of a string\n- Bugfix:   (MBaker)    Work item 16246 - reader/CSV fails on this file\n                        auto_detect_line_endings now set in CSV reader\n- Bugfix:   (MBaker)    Work item 16212 - $arguments improperly used in CachedObjectStorage/PHPTemp.php\n- Bugfix:   (MBaker)    Work item 16643 - Bug In Cache System (cell reference when throwing caching errors)\n- Bugfix:   (MBaker)    Work item 16895 - PHP Invalid index notice on writing excel file when active sheet has been deleted\n- Bugfix:   (MBaker)    Work item 16956 - External links in Excel2010 files cause Fatal error\n- Bugfix:   (MBaker)    Work item 16960 - Previous calculation engine error conditions trigger cyclic reference errors\n- Bugfix:   (mkopinsky) Work item 16266 - PHPExcel_Style::applyFromArray() returns null rather than style object in advanced mode\n- Bugfix:   (fauvel)    Work item 16958 - Cell::getFormattedValue returns RichText object instead of string\n- Bugfix:   (MBaker)    Work item 17166 - Indexed colors do not refer to Excel's indexed colors?\n- Bugfix:   (MBaker)    Work item 17199 - Indexed colors should be consistent with Excel and start from 1 (current index starts at 0)\n- Bugfix:   (MBaker)    Work item 17262 - Named Range definition in .xls when sheet reeference is quote wrapped\n- Bugfix:   (MBaker)    Work item 17403 - duplicateStyle() method doesn't duplicate conditional formats\n                                          Added an equivalent duplicateConditionalStyle() method for duplicating conditional styles\n- Bugfix:   (bnr)       Work item 17501 - =sumproduct(A,B) <> =sumproduct(B,A) in xlsx\n- Bugfix:   (Progi1984) Work item 8916  - Support for Rich-Text in PHPExcel_Writer_Excel5\n- General:  (MBaker)    Work item 15405 - Two easy to fix Issues concerning PHPExcel_Token_Stack (l10n/UC)\n- General:  (MBaker)    Work item 15461 - Locale file paths not fit for windows\n- General:  (MBaker)    Work item 16643 - Add file directory as a cache option for cache_to_discISAM\n- General:  (MBaker)    Work item 16923 - Datatype.php & constant TYPE_NULL\n- General:  (MBaker)    Ensure use of system temp directory for all temporary work files, unless explicitly specified\n- General:  (char101)   Work item 16359 - [Patch] faster stringFromColumnIndex()\n- General:  (whit1206)  Work item 16028 - Fix for projects that still use old autoloaders\n- General:  (atz)       Work item 17024 - Unknown codepage: 10007\n                        Additional Mac codepages\n\n\n2011-02-27 (v1.7.6):\n- Feature:  (MBaker)  Provide option to use PCLZip as an alternative to ZipArchive.\n                      This allows the writing of Excel2007 files, even without ZipArchive enabled (it does require zlib), or when php_zip is one of the buggy PHP 5.2.6 or 5.2.8 versions\n                      It can be enabled using PHPExcel_Settings::setZipClass(PHPExcel_Settings::PCLZIP);\n                      Note that it is not yet implemented as an alternative to ZipArchive for those Readers that are extracting from zips\n- Feature:  (MBaker)  Work item 14979 - Added listWorksheetNames() method to Readers that support multiple worksheets in a workbook, allowing a user to extract a list of all the worksheet names from a file without parsing/loading the whole file.\n- Feature:  (MBaker)  Speed boost and memory reduction in the Worksheet toArray() method.\n- Feature:  (MBaker)  Added new rangeToArray() and namedRangeToArray() methods to the PHPExcel_Worksheet object.\n                      Functionally, these are identical to the toArray() method, except that they take an additional first parameter of a Range (e.g. 'B2:C3') or a Named Range name.\n                      Modified the toArray() method so that it actually uses rangeToArray().\n- Feature:  (MBaker)  Added support for cell comments in the OOCalc, Gnumeric and Excel2003XML Readers, and in the Excel5 Reader\n- Feature:  (MBaker)  Improved toFormattedString() handling for Currency and Accounting formats to render currency symbols\n- Feature:  (MBaker)  Work Item  2346 - Implement more Excel calculation functions\n                      Implemented the DAVERAGE(), DCOUNT(), DCOUNTA(), DGET(), DMAX(), DMIN(), DPRODUCT(), DSTDEV(), DSTDEVP(), DSUM(), DVAR() and DVARP() Database functions\n- Bugfix:   (MBaker)  Work item 14888 - Simple =IF() formula disappears\n- Bugfix:   (MBaker)  Work item 14898 - PHP Warning: preg_match(): Compilation failed: PCRE does not support \\\\L, \\\\l, \\\\N, \\\\P, \\\\p, \\\\U, \\\\u, or \\\\X\n- Bugfix:   (MBaker)  Work item 14901 - VLOOKUP choking on parameters in PHPExcel.1.7.5/PHPExcel_Writer_Excel2007\n- Bugfix:   (MBaker)  Work item 14973 - PHPExcel_Cell::isInRange() incorrect results - offset by one column\n- Bugfix:   (MBaker)  Treat CodePage of 0 as CP1251 (for .xls files written by applications that don't set the CodePage correctly, such as Apple Numbers)\n- Bugfix:   (MB)      Work item 11583 - Need method for removing autoFilter\n- Bugfix:   (MBaker)  Work item 15029 - coordinateFromString throws exception for rows greater than 99,999\n- Bugfix:   (MBaker)  Work item 14999 - PHPExcel Excel2007 Reader colour problems with solidfill\n- Bugfix:   (MBaker)  Work item 13215 - Formatting get lost and edit a template XLSX file\n- Bugfix:   (MBaker)  Work item 14029 - Excel 2007 Reader /writer lost fontcolor\n- Bugfix:   (MBaker)  Work item 13374 - file that makes cells go black\n- Bugfix:   (MBaker)  Minor patchfix for Excel2003XML Reader when XML is defined with a charset attribute\n- Bugfix:   (MBaker)  Work item 15089 - PHPExcel_Worksheet->toArray() index problem\n- Bugfix:   (MBaker)  Work item 15094 - Merge cells 'un-merge' when using an existing spreadsheet\n- Bugfix:   (MBaker)  Work item 15129 - Worksheet fromArray() only working with 2-D arrays\n- Bugfix:   (xkeshav) Work item 15172 - rangeToarray function modified for non-existent cells\n- Bugfix:   (MBaker)  Work item 14980 - Images not getting copyied with the ->clone function\n- Bugfix:   (MBaker)  Work item 11576 - AdvancedValueBinder.php: String sometimes becomes a date when it shouldn't\n- Bugfix:   (MBaker)  Fix Excel5 Writer so that it only writes column dimensions for columns that are actually used rather than the full range (A to IV)\n- Bugfix:   (MBaker)  Work item 15198 - FreezePane causing damaged or modified error\n                      The freezePaneByColumnAndRow() method row argument should default to 1 rather than 0.\n                      Default row argument for all __ByColumnAndRow() methods should be 1\n- Bugfix:   (MBaker)  Work item 15121 - Column reference rather than cell reference in Print Area definition\n                      Fix Excel2007 Writer to handle print areas that are defined as row or column ranges rather than just as cell ranges\n- Bugfix:   (MBaker)  Reduced false positives from isDateTimeFormatCode() method by suppressing testing within quoted strings\n- Bugfix:   (MBaker)  Work item 15312 - Caching and tmp partition exhaustion\n- Bugfix:   (MBaker)  Work item 15308 - Writing to Variable No Longer Works. $_tmp_dir Missing in PHPExcel\\PHPExcel\\Shared\\OLE\\PPS\\Root.php\n- Bugfix:   (MBaker)  Work item 15379 - Named ranges with dot don't get parsed properly\n- Bugfix:   (MBaker)  Work item 15096 - insertNewRowBefore fails to consistently update references\n- Bugfix:   (MBaker)  \"i\" is not a valid character for Excel date format masks (in isDateTimeFormatCode() method)\n- Bugfix:   (MKunert) Work item 15421 - PHPExcel_ReferenceHelper::insertNewBefore() is missing an 'Update worksheet: comments' section\n- Bugfix:   (MBaker)  Work item 15409 - Full column/row references in named ranges not supported by updateCellReference()\n- General:  (MBaker)  Improved performance (speed), for building the Shared Strings table in the Excel2007 Writer.\n- General:  (MBaker)  Improved performance (speed), for PHP to Excel date conversions\n- General:  (MBaker)  Enhanced SheetViews element structures in the Excel2007 Writer for frozen panes.\n- General:  (MBaker)  Removed Serialized Reader/Writer as these no longer work.\n\n\n2010-12-10 (v1.7.5):\n- Feature:  (MBaker)    Work item 8769 - Implement Gnumeric File Format\n                        Initial work on Gnumeric Reader (Worksheet Data, Document Properties and basic Formatting)\n- Feature:  (MBaker)    (incorporating part of Workitem 9759) - Support for Extended Workbook Properties in Excel2007, Excel5 and OOCalc Readers; support for User-defined Workbook Properties in Excel2007 and OOCalc Readers\n- Feature:  (MBaker)    Support for Extended and User-defined Workbook Properties in Excel2007 Writer\n- Feature:  (MBaker)    Provided a setGenerateSheetNavigationBlock(false); option to suppress generation of the sheet navigation block when writing multiple worksheets to HTML\n- Feature:  (MBaker)    Advanced Value Binder now recognises TRUE/FALSE strings (locale-specific) and converts to boolean\n- Feature:  (MBaker)    Work item 14301 - PHPExcel_Worksheet->toArray() is returning truncated values\n- Feature:  (MBaker)    Configure PDF Writer margins based on Excel Worksheet Margin Settings value\n- Feature:  (MBaker)    Added Contiguous flag for the CSV Reader, when working with Read Filters\n- Feature:  (MBaker)    Added getFormattedValue() method for cell object\n- Feature:  (MBaker)    Added strictNullComparison argument to the worksheet fromArray() method\n- Feature:  (MBaker)    Fix to toFormattedString() method in PHPExcel_Style_NumberFormat to handle fractions with a # code for the integer part\n- Bugfix:   (MB)        Work item 14143 - NA() doesn't propagate in matrix calc - quick fix in JAMA/Matrix.php\n- Bugfix:   (Progi1984) Work item 7895 - Excel5 : Formula : String constant containing double quotation mark\n- Bugfix:   (Progi1984) Work item 7895 - Excel5 : Formula : Percent\n- Bugfix:   (Progi1984) Work item 7895 - Excel5 : Formula : Error constant\n- Bugfix:   (Progi1984) Work item 7895 - Excel5 : Formula : Concatenation operator\n- Bugfix:   (MBaker)    Work item 14146 - Worksheet clone broken for CachedObjectStorage_Memory\n- Bugfix:   (MBaker)    Work item 12998 - PHPExcel_Reader_Excel2007 fails when gradient fill without type is present in a file\n- Bugfix:   (MBaker)    Work item 14176 - @ format for numeric strings in XLSX to CSV conversion\n- Bugfix:   (MBaker)    Work item 14223 - Advanced Value Binder Not Working?\n- Bugfix:   (MBaker)    Work item 14226 - unassigned object variable in PHPExcel->removeCellXfByIndex\n- Bugfix:   (MBaker)    Work item 14236 - problem with getting cell values from another worksheet... (if cell doesn't exist)\n- Bugfix:   (MBaker)    Work items 14260 & 14233 - Setting cell values to one char strings & Trouble reading one character string (thanks gorfou)\n- Bugfix:   (MBaker)    Work item 14256 - Worksheet title exception when duplicate worksheet is being renamed but exceeds the 31 character limit\n- Bugfix:   (MBaker)    Work item 14086 - Named range with sheet name that contains the $ throws exception when getting the cell\n- Bugfix:   (MBaker)    Added autoloader to DefaultValueBinder and AdvancedValueBinder\n- Bugfix:   (MBaker)    Modified PHPExcel_Shared_Date::isDateTimeFormatCode() to return false if format code begins with \"_\" or with \"0 \" to prevent false positives\n                        These leading characters are most commonly associated with number, currency or accounting (or occasionally fraction) formats\n- Bugfix:   (MBaker)    Work item 14374 - BUG : Excel5 and setReadFilter ?\n- Bugfix:   (MBaker)    Work item 14425 - Wrong exception message while deleting column\n- Bugfix:   (MBaker)    Work item 14679 - Formula evaluation fails with Japanese sheet refs\n- Bugfix:   (MBaker)    Work item 13559 - PHPExcel_Writer_PDF does not handle cell borders correctly\n- Bugfix:   (MBaker)    Work item 14831 - Style : applyFromArray() for 'allborders' not working\n- Bugfix:   (MBaker)    Work item 14837 - Using $this when not in object context in Excel5 Reader\n- General:  (MBaker)    Applied patch 6609 - Removes a unnecessary loop through each cell when applying conditional formatting to a range.\n- General:  (MBaker)    Applied patch 7169 - Removed spurious PHP end tags (?>)\n- General:  (MBaker)    Improved performance (speed) and reduced memory overheads, particularly for the Writers, but across the whole library.\n\n\n2010-08-26 (v1.7.4):\n- Bugfix:   (Progi1984) Work item 7895 - Excel5 : Formula : Power\n- Bugfix:   (Progi1984) Work item 7895 - Excel5 : Formula : Unary plus\n- Bugfix:   (Progi1984) Excel5 : Just write the Escher stream if necessary in Worksheet\n- Bugfix:   (MBaker)    Work item 13433 - Syntax errors in memcache.php 1.7.3c\n- Bugfix:   (MBaker)    Work item 13450 - Standard Deviation functions returning DIV/0 Error when Standard Deviation is zero\n- Feature:  (MBaker)    Support for print area with several ranges in the Excel2007 reader, and improved features for editing print area with several ranges\n- Feature:  (MBaker)    Work item 13769 - Improved Cell Exception Reporting\n- Feature:  (MBaker)    Support for row or column ranges in the calculation engine, e.g. =SUM(C:C) or =SUM(1:2)\n                        Also support in the calculation engine for absolute row or column ranges e.g. =SUM($C:$E) or =SUM($3:5)\n- Bugfix:   (ET)        Work item 13455 - Picture problem with Excel 2003\n- Bugfix:   (MBaker)    Work item 13484 - Wrong variable used in addExternalSheet in PHPExcel.php\n- Bugfix:   (MBaker)    Work item 13515 - \"Invalid cell coordinate\" error when formula access data from an other sheet\n- Bugfix:   (MBaker)    (related to Work item 13515) Calculation engine confusing cell range worksheet when referencing cells in a different worksheet to the formula\n- Bugfix:   (MBaker)    Work item 13752 - Wrong var naming in Worksheet->garbageCollect()\n- Bugfix:   (MBaker)    Work item 13764 - PHPExcel_Style_*::__clone() methods cause cloning loops?\n- Bugfix:   (MBaker)    Work item 11488 - Recent builds causing problems loading xlsx files? (ZipArchive issue?)\n- Bugfix:   (MBaker)    Work item 13856 - cache_to_apc causes fatal error when processing large data sets\n- Bugfix:   (MBaker)    Work item 13880 - OOCalc reader misses first line if it's a 'table-header-row'\n- Bugfix:   (MBaker)    Work item 14011 - using cache with copy or clone bug?\n                                        Fixed $worksheet->copy() or clone $worksheet when using cache_in_memory, cache_in_memory_gzip, cache_in_memory_serialized, cache_to_discISAM, cache_to_phpTemp, cache_to_apc and cache_to_memcache;\n                                        Fixed but untested when using cache_to_wincache.\n- Bugfix:   (MBaker)    Fixed problems with reading Excel2007 Properties\n- General:  (MB)        Applied patch 6324 - PHP Strict Standards: Non-static method PHPExcel_Shared_String::utf16_decode() should not be called statically\n- General:  (MBaker)    Applied patch 6360 - Array functions were ignored when loading an existing file containing them, and as a result, they would lose their 'cse' status.\n- General:  (MBaker)    Minor memory tweaks to Excel2007 Writer\n- General:  (MBaker)    Modified ReferenceHelper updateFormulaReferences() method to handle updates to row and column cell ranges (including absolute references e.g. =SUM(A:$E) or =SUM($5:5), and range/cell references that reference a worksheet by name), and to provide both performance and memory improvements.\n- General:  (MBaker)    Modified Excel2007 Reader so that ReferenceHelper class is instantiated only once rather than for every shared formula in a workbook.\n- General:  (MBaker)    Correct handling for additional (synonym) formula tokens in Excel5 Reader\n- General:  (MBaker)    Additional reading of some Excel2007 Extended Properties (Company, Manager)\n\n\n2010-06-01 (v1.7.3c):\n- Bugfix:   (MB)     Work item 13012 - Fatal error: Class 'ZipArchive' not found... ...Reader/Excel2007.php on line 217\n- Bugfix:   (MBaker) Work item 13398 - PHPExcel_Writer_Excel2007 error after 1.7.3b\n\n\n2010-05-31 (v1.7.3b):\n- Bugfix:   (MBaker) Work item 12903 - Infinite loop when reading\n- Bugfix:   (MB)     Work item 13381 - Wrong method chaining on PHPExcel_Worksheet class\n\n\n2010-05-17 (v1.7.3):\n- General:  (ET)     Applied patch 4990 (modified)\n- General:  (MB)     Applied patch 5568 (modified)\n- General:  (MB)     Applied patch 5943\n- General:  (MB)     Work item 13042 - Upgrade build script to use Phing\n- General:  (ET)     Work item 11586 - Replacing var with public/private\n- General:  (MBaker) Applied Anthony's Sterling's Class Autoloader to reduce memory overhead by \"Lazy Loading\" of classes\n- General:  (MBaker) Modification to functions that accept a date parameter to support string values containing ordinals as per Excel (English language only)\n- General:  (MBaker) Modify PHPExcel_Style_NumberFormat::toFormattedString() to handle dates that fall outside of PHP's 32-bit date range\n- General:  (MBaker) Applied patch 5207\n- General:  (ET)     Work item 11970 - PHPExcel developer documentation: Set page margins\n- Feature:  (ET)     Work item 11038 - Special characters and accents in SYLK reader\n- Feature:  (MBaker) Work Item  2346 - Implement more Excel calculation functions\n                     - Implemented the COUPDAYS(), COUPDAYBS(), COUPDAYSNC(), COUPNCD(), COUPPCD() and PRICE() Financial functions\n                     - Implemented the N() and TYPE() Information functions\n                     - Implemented the HYPERLINK() Lookup and Reference function\n- Feature:  (ET)     Work item 11526 - Horizontal page break support in PHPExcel_Writer_PDF\n- Feature:  (ET)     Work item 11529 - Introduce method setActiveSheetIndexByName()\n- Feature:  (ET)     Work item 11550 - AdvancedValueBinder.php: Automatically wrap text when there is new line in string (ALT+\"Enter\")\n- Feature:  (ET)     Work item 10300 - Data validation support in PHPExcel_Reader_Excel5 and PHPExcel_Writer_Excel5\n- Feature:  (MB)     Work item 11616 - Improve autosize calculation\n- Feature:  (MBaker) Methods to translate locale-specific function names in formulae\n                     - Language implementations for Czech (cs), Danish (da), German (de), English (uk), Spanish (es), Finnish (fi), French (fr), Hungarian (hu), Italian (it), Dutch (nl), Norwegian (no), Polish (pl), Portuguese (pt), Brazilian Portuguese (pt_br), Russian (ru) and Swedish (sv)\n- Feature:  (ET)     Work item 9759 - Implement document properties in Excel5 reader/writer\n                     - Fixed so far for PHPExcel_Reader_Excel5\n- Feature:  (ET)     Work item 11849 - Show/hide row and column headers in worksheet\n- Feature:  (ET)     Work item 11919 - Can't set font on writing PDF (by key)\n- Feature:  (ET)     Work item 12096 - Thousands scale (1000^n) support in PHPExcel_Style_NumberFormat::toFormattedString\n- Feature:  (ET)     Work item  6911 - Implement repeating rows in PDF and HTML writer\n- Feature:  (ET)     Work item 12289 - Sheet tabs in PHPExcel_Writer_HTML\n- Feature:  (MB)     Work item 13041 - Add Wincache CachedObjectProvider\n- Feature:  (MBaker) Configure PDF Writer paper size based on Excel Page Settings value, and provided methods to override paper size and page orientation with the writer\n                     - Note PHPExcel defaults to Letter size, while the previous PDF writer enforced A4 size, so PDF writer will now default to Letter\n- Feature:  (MBaker) Initial implementation of cell caching: allowing larger workbooks to be managed, but at a cost in speed\n- Feature:  (MBaker) Added an identify() method to the IO Factory that identifies the reader which will be used to load a particular file without actually loading it.\n- Bugfix:   (MBaker) Work item 10979 - Warning messages with INDEX function having 2 arguments\n- Bugfix:   (ET)     Work item 11473 - setValue('=') should result in string instead of formula\n- Bugfix:   (MBaker) Work item 11471 - method _raiseFormulaError should no be private\n- Bugfix:   (ET)     Work item 11485 - Fatal error: Call to undefined function mb_substr() in ...Classes\\PHPExcel\\Reader\\Excel5.php on line 2903\n- Bugfix:   (ET)     Work item 11487 - getBold(), getItallic(), getStrikeThrough() not always working with PHPExcel_Reader_Excel2007\n- Bugfix:   (ET)     Work item 11492 - AdvancedValueBinder.php not working correctly for $cell->setValue('hh:mm:ss')\n- Bugfix:   (MBaker) Fixed leap year handling for the YEARFRAC() Date/Time function when basis ia 1 (Actual/actual)\n- Bugfix:   (MBaker) Work item 11490 - Warning messages\n                     - Calculation Engine code modified to enforce strict standards for pass by reference\n- Bugfix:   (ET)     Work item 11483 - PHPExcel_Cell_AdvancedValueBinder doesnt work for dates in far future\n- Bugfix:   (ET)     Work item 11528 - MSODRAWING bug with long CONTINUE record in PHPExcel_Reader_Excel5\n- Bugfix:   (ET)     Work item 11571 - PHPExcel_Reader_Excel2007 reads print titles as named range when there is more than one sheet\n- Bugfix:   (ET)     Work item 11561 - missing @return in phpdocblock in reader classes\n- Bugfix:   (ET)     Work item 11576 - AdvancedValueBinder.php: String sometimes becomes a date when it shouldn't\n- Bugfix:   (ET)     Work item 11588 - Small numbers escape treatment in PHPExcel_Style_NumberFormat::toFormattedString()\n- Bugfix:   (ET)     Work item 11590 - Blank styled cells are not blank in output by HTML writer due to &nbsp;\n- Bugfix:   (MBaker) Work item 11587 - Calculation engine bug: Existing, blank cell + number gives #NUM\n- Bugfix:   (ET)     Work item 11608 - AutoSize only measures length of first line in cell with multiple lines (ALT+Enter)\n- Bugfix:   (ET)     Work item 11608 - Fatal error running Tests/12serializedfileformat.php (PHPExcel 1.7.2)\n- Bugfix:   (MBaker) Fixed various errors in the WORKDAY() and NETWORKDAYS() Date/Time functions (particularly related to holidays)\n- Bugfix:   (ET)     Work item 11660 - Uncaught exception 'Exception' with message 'Valid scale is between 10 and 400.' in Classes/PHPExcel/Worksheet/SheetView.php:115\n- Bugfix:   (ET)     Work item 11551 - \"Unrecognized token 39 in formula\" with PHPExcel_Reader_Excel5 (occuring with add-in functions)\n- Bugfix:   (ET)     Work item 11668 - Excel2007 reader not reading PHPExcel_Style_Conditional::CONDITION_EXPRESSION\n- Bugfix:   (MBaker) Fix to the BESSELI(), BESSELJ(), BESSELK(), BESSELY() and COMPLEX() Engineering functions to use correct default values for parameters\n- Bugfix:   (MBaker) Work item 11525 - DATEVALUE function not working for pure time values + allow DATEVALUE() function to handle partial dates (e.g. \"1-Jun\" or \"12/2010\")\n- Bugfix:   (MBaker) Fix for empty quoted strings in formulae\n- Bugfix:   (MBaker) Trap for division by zero in Bessel functions\n- Bugfix:   (MBaker) Fix to OOCalc Reader to convert semi-colon (;) argument separator in formulae to a comma (,)\n- Bugfix:   (ET)     Work item 11693 - PHPExcel_Writer_Excel5_Parser cannot parse formula like =SUM(C$5:C5)\n- Bugfix:   (MBaker) Fix to OOCalc Reader to handle dates that fall outside 32-bit PHP's date range\n- Bugfix:   (ET)     Work item 11692 - File->sys_get_temp_dir() can fail in safe mode\n- Bugfix:   (ET)     Work item 11727 - Sheet references in Excel5 writer do not work when referenced sheet title contains non-Latin symbols\n- Bugfix:   (ET)     Work item 11743 - Bug in HTML writer can result in missing rows in output\n- Bugfix:   (ET)     Work item 11674 - setShowGridLines(true) not working with PHPExcel_Writer_PDF\n- Bugfix:   (ET)     Work item 11836 - PHPExcel_Worksheet_RowIterator initial position incorrect\n- Bugfix:   (ET)     Work item 11835 - PHPExcel_Worksheet_HeaderFooterDrawing Strict Exception thrown (by jshaw86)\n- Bugfix:   (ET)     Work item 11850 - Parts of worksheet lost when there are embedded charts (Excel5 reader)\n- Bugfix:   (MBaker) VLOOKUP() function error when lookup value is passed as a cell reference rather than an absolute value\n- Bugfix:   (ET)     Work item 12041 - First segment of Rich-Text not read correctly by PHPExcel_Reader_Excel2007\n- Bugfix:   (MBaker) Work item 12048 - Fatal Error with getCell('name') when name matches the pattern for a cell reference\n- Bugfix:   (ET)     Work item 12039 - excel5 writer appears to be swapping image locations\n- Bugfix:   (ET)     Work item 11954 - Undefined index: host in ZipStreamWrapper.php, line 94 and line 101\n- Bugfix:   (ET)     Work item 11672 - BIFF8 File Format problem (too short COLINFO record)\n- Bugfix:   (ET)     Work item 12121 - Column width sometimes changed after read/write with Excel2007 reader/writer\n- Bugfix:   (ET)     Work item 11964 - Worksheet.php throws a fatal error when styling is turned off via setReadDataOnly on the reader\n- Bugfix:   (MBaker) Work item 11851 - Checking for Circular References in Formulae\n                     - Calculation Engine code now traps for cyclic references, raising an error or throwing an exception, or allows 1 or more iterations through cyclic references, based on a configuration setting\n- Bugfix:   (ET)     Work item 12244 - PNG transparency using Excel2007 writer\n- Bugfix:   (ET)     Work item 12221 - Custom readfilter error when cell formulas reference excluded cells (Excel5 reader)\n- Bugfix:   (ET)     Work item 12288 - Protection problem in XLS\n- Bugfix:   (ET)     Work item 12300 - getColumnDimension()->setAutoSize() incorrect on cells with Number Formatting\n- Bugfix:   (ET)     Work item 12378 - Notices reading Excel file with Add-in funcitons (PHPExcel_Reader_Excel5)\n- Bugfix:   (ET)     Work item 12380 - Excel5 reader not reading formulas with deleted sheet references\n- Bugfix:   (ET)     Work item 12404 - Named range (defined name) scope problems for in PHPExcel\n- Bugfix:   (ET)     Work item 12423 - PHP Parse error: syntax error, unexpected T_PUBLIC in PHPExcel/Calculation.php on line 3482\n- Bugfix:   (ET)     Work item 12505 - Named ranges don't appear in name box using Excel5 writer\n- Bugfix:   (ET)     Work item 12509 - Many merged cells + autoSize column -> slows down the writer\n- Bugfix:   (ET)     Work item 12539 - Incorrect fallback order comment in Shared/Strings.php ConvertEncoding()\n- Bugfix:   (ET)     Work item 12538 - IBM AIX iconv() will not work, should revert to mbstring etc. instead\n- Bugfix:   (ET)     Work item 12568 - Excel5 writer and mbstring functions overload\n- Bugfix:   (MBaker) Work item 12672 - OFFSET needs to flattenSingleValue the $rows and $columns args\n- Bugfix:   (MBaker) Work item 12546 - Formula with DMAX(): Notice: Undefined offset: 2 in ...\\PHPExcel\\Calculation.php on line 2365\n                     - Note that the Database functions have not yet been implemented\n- Bugfix:   (MBaker) Work item 12839 - Call to a member function getParent() on a non-object in Classes\\\\PHPExcel\\\\Calculation.php Title is required\n- Bugfix:   (MBaker) Work item 12935 - Cyclic Reference in Formula\n- Bugfix:   (MBaker) Work item 13025 - Memory error...data validation?\n\n\n2010/01/11 (v1.7.2):\n- General:  (ET)     Applied patch 4362\n- General:  (ET)     Applied patch 4363 (modified)\n- General:  (MBaker) Work item 10874 - 1.7.1 Extremely Slow - Refactored PHPExcel_Calculation_Functions::flattenArray() method and set calculation cache timer default to 2.5 seconds\n- General:  (MBaker) Allow formulae to contain line breaks\n- General:  (ET)     Work item 10910 - split() function deprecated in PHP 5.3.0\n- General:  (ET)     sys_get_temp_dir() requires PHP 5.2.1, not PHP 5.2 [provide fallback function for PHP 5.2.0]\n- General:  (MBaker) Applied patch 4640 - Implementation of the ISPMT() Financial function by Matt Groves\n- General:  (MBaker) Work item 11052 - Put the example of formula with more arguments in documentation\n- General:  (MBaker) Improved accuracy for the GAMMAINV() Statistical Function\n- Feature:  (ET)     Work item 10409 - XFEXT record support to fix colors change from Excel5 reader, and copy/paste color change with Excel5 writer\n                     - Excel5 reader reads RGB color information in XFEXT records for borders, font color and fill color\n- Feature:  (MBaker) Work Item  2346 - Implement more Excel calculation functions\n                     - Implemented the FVSCHEDULE(), XNPV(), IRR(), MIRR(), XIRR() and RATE() Financial functions\n                     - Implemented the SUMPRODUCT() Mathematical function\n                     - Implemented the ZTEST() Statistical Function\n- Feature:  (ET)     Work item 10919 - Multiple print areas in one sheet\n- Feature:  (ET)     Work item 10930 - Store calculated values in output by PHPExcel_Writer_Excel5\n- Feature:  (ET)     Work item 10939 - Sheet protection options in Excel5 reader/writer\n- Feature:  (MBaker) Modification of the COUNT(), AVERAGE(), AVERAGEA(), DEVSQ, AVEDEV(), STDEV(), STDEVA(), STDEVP(), STDEVPA(), VARA() and VARPA() SKEW() and KURT() functions to correctly handle boolean values depending on whether they're passed in as values, values within a matrix or values within a range of cells.\n- Feature:  (ET)     Work item  9932 - Cell range selection\n- Feature:  (MB)     Work item 10266 - Root-relative path handling\n- Feature:  (ET)     Work item 11315 - Named Ranges not working with PHPExcel_Writer_Excel5\n- Bugfix:   (MB)     Work item 11206 - Excel2007 Reader fails to load Apache POI generated Excel\n- Bugfix:   (MB)     Work item 11154 - Number format is broken when system's thousands separator is empty\n- Bugfix:   (MB)     Work item 11401 - ReferenceHelper::updateNamedFormulas throws errors if oldName is empty\n- Bugfix:   (MB)     Work item 11296 - parse_url() fails to parse path to an image in xlsx\n- Bugfix:   (ET)     Work item 10876 - Workaround for iconv_substr() bug in PHP 5.2.0\n- Bugfix:   (ET)     Work item 10877 - 1 pixel error for image width and height with PHPExcel_Writer_Excel5\n- Bugfix:   (MBaker) Fix to GEOMEAN() Statistical function\n- Bugfix:   (ET)     Work item 10884 - setValue('-') and setValue('.') sets numeric 0 instead of 1-character string\n- Bugfix:   (ET)     Work item 10885 - Row height sometimes much too low after read with PHPExcel_Reader_Excel5\n- Bugfix:   (ET)     Work item 10888 - Diagonal border. Miscellaneous missing support.\n                     - Constant PHPExcel_Style_Borders::DIAGONAL_BOTH added to support double-diagonal (cross)\n                     - PHPExcel_Reader_Excel2007 not always reading diagonal borders (only recognizes 'true' and not '1')\n                     - PHPExcel_Reader_Excel5 support for diagonal borders\n                     - PHPExcel_Writer_Excel5 support for diagonal borders\n- Bugfix:   (ET)     Work item 10894 - Session bug: Fatal error: Call to a member function bindValue() on a non-object in ...\\Classes\\PHPExcel\\Cell.php on line 217\n- Bugfix:   (ET)     Work item 10896 - Colors messed up saving twice with same instance of PHPExcel_Writer_Excel5 (regression since 1.7.0)\n- Bugfix:   (ET)     Work item 10917 - Method PHPExcel_Worksheet::setDefaultStyle is not working\n- Bugfix:   (ET)     Work item 10897 - PHPExcel_Reader_CSV::canRead() sometimes says false when it shouldn't\n- Bugfix:   (ET)     Work item 10922 - Changes in workbook not picked up between two saves with PHPExcel_Writer_Excel2007\n- Bugfix:   (ET)     Work item 10913 - Decimal and thousands separators missing in HTML and PDF output\n- Bugfix:   (ET)     Work item 10936 - Notices with PHPExcel_Reader_Excel5 and named array constants\n- Bugfix:   (MBaker) Work item 10938 - Calculation engine limitation on 32-bit platform with integers > 2147483647\n- Bugfix:   (ET)     Work item 10959 - Shared(?) formulae containing absolute cell references not read correctly using Excel5 Reader\n- Bugfix:   (MBaker) Work item 10962 - Warning messages with intersection operator involving single cell\n- Bugfix:   (ET)     Work item 10980 - Infinite loop in Excel5 reader caused by zero-length string in SST\n- Bugfix:   (ET)     Work item 10983 - Remove unnecessary cell sorting to improve speed by approx. 18% in HTML and PDF writers\n- Bugfix:   (MBaker) Work item 10977 - Cannot read A1 cell content - OO_Reader\n- Bugfix:   (ET)     Work item 11000 - Transliteration failed, invalid encoding\n\n\n2009/11/02 (v1.7.1):\n- General:  (ET) Work item 10687 - ereg() function deprecated in PHP 5.3.0\n- General:  (MB) Work item 10739 - Writer Interface Inconsequence - setTempDir and setUseDiskCaching\n- General:  (ET) Upgrade to TCPDF 4.8.009\n- Feature:  (ET) Work item  7333 - Support for row and column styles (feature request)\n            -   Basic implementation for Excel2007/Excel5 reader/writer\n- Feature:  (ET) Work item 10459 - Hyperlink to local file in Excel5 reader/writer\n- Feature:  (MB) Work item 10472 - Color Tab (Color Sheet's name)\n- Feature:  (ET) Work item 10488 - Border style \"double\" support in PHPExcel_Writer_HTML\n- Feature:  (ET) Work item 10492 - Multi-section number format support in HTML/PDF/CSV writers\n- Feature:  (MBaker) - Some additional performance tweaks in the calculation engine\n- Feature:  (MBaker) - Fix result of DB() and DDB() Financial functions to 2dp when in Gnumeric Compatibility mode\n- Feature:  (MBaker) - Added AMORDEGRC(), AMORLINC() and COUPNUM() Financial function (no validation of parameters yet)\n- Feature:  (MBaker) - Improved accuracy of TBILLEQ(), TBILLPRICE() and TBILLYIELD() Financial functions when in Excel or Gnumeric mode\n- Feature:  (MBaker) - Added INDIRECT() Lookup/Reference function (only supports full addresses at the moment)\n- Feature:  (MB) Work item 10498 - PHPExcel_Reader_CSV::canRead() improvements\n- Feature:  (ET) Work item 10500 - Input encoding option for PHPExcel_Reader_CSV\n- Feature:  (ET) Work item 10493 - Colored number format support, e.g. [Red], in HTML/PDF output\n- Feature:  (ET) Work item 10559 - Color Tab (Color Sheet's name) [Excel5 reader/writer support]\n- Feature:  (MBaker) Initial version of SYLK (slk) and Excel 2003 XML Readers (Cell data and basic cell formatting)\n- Feature:  (MBaker) Initial version of Open Office Calc (ods) Reader (Cell data only)\n- Feature:  (MBaker) Initial use of \"pass by reference\" in the calculation engine for ROW() and COLUMN() Lookup/Reference functions\n- Feature:  (MBaker) Work item 2346 - COLUMNS() and ROWS() Lookup/Reference functions, and SUBSTITUTE() Text function\n- Feature:  (ET) Work item 10502 - AdvancedValueBinder(): Re-enable zero-padded string-to-number conversion, e.g '0004' -> 4\n- Feature:  (ET) Work item 10600 - Make PHP type match Excel datatype\n- Feature:  (MB) Work item 10630 - Change first page number on header\n- Feature:  (MB) Applied patch 3941\n- Feature:  (MB,ET) Work item 10745 - Hidden sheets\n- Feature:  (ET) Work item 10761 - mbstring fallback when iconv is broken\n- Feature:  (MBaker) Added support for matrix/value comparisons (e.g. ={1,2;3,4}>=3 or 2<>{1,2;3,4}) - Note, can't yet handle comparison of two matrices\n- Feature:  (MBaker) Improved handling for validation and error trapping in a number of functions\n- Feature:  (MBaker) Improved support for fraction number formatting\n- Feature:  (ET) Work item 10455 - Support Reading CSV with Byte Order Mark (BOM)\n- Feature:  (ET) Work item 10860 - addExternalSheet() at specified index\n- Bugfix:   (MBaker) Work item 10684 - Named range can no longer be passed to worksheet->getCell()\n- Bugfix:   (ET) Work item 10455 - RichText HTML entities no longer working in PHPExcel 1.7.0\n- Bugfix:   (ET) Work item  7610 - Fit-to-width value of 1 is lost after read/write of Excel2007 spreadsheet [+ support for simultaneous scale/fitToPage]\n- Bugfix:   (MB) Work item 10469 - Performance issue identified by profiling\n- Bugfix:   (ET) Work item 10473 - setSelectedCell is wrong\n- Bugfix:   (ET) Work item 10481 - Images get squeezed/stretched with (Mac) Verdana 10 Excel files using Excel5 reader/writer\n- Bugfix:   (MBaker) Work item 10482 - Error in argument count for DATEDIF() function\n- Bugfix:   (MBaker) Work item 10452 - updateFormulaReferences is buggy\n- Bugfix:   (MB) Work item 10485 - CellIterator returns null Cell if onlyExistingCells is set and key() is in use\n- Bugfix:   (MBaker) Work item 10453 - Wrong RegEx for parsing cell references in formulas\n- Bugfix:   (MB) Work item 10486 - Optimisation subverted to devastating effect if IterateOnlyExistingCells is clear\n- Bugfix:   (ET) Work item 10494 - Fatal error: Uncaught exception 'Exception' with message 'Unrecognized token 6C in formula'... with PHPExcel_Reader_Excel5\n- Bugfix:   (MBaker) Work item 10490 - Fractions stored as text are not treated as numbers by PHPExcel's calculation engine\n- Bugfix:   (ET) Work item 10503 - AutoFit (autosize) row height not working in PHPExcel_Writer_Excel5\n- Bugfix:   (MBaker) Fixed problem with null values breaking the calculation stack\n- Bugfix:   (ET) Work item 10524 - Date number formats sometimes fail with PHPExcel_Style_NumberFormat::toFormattedString, e.g. [$-40047]mmmm d yyyy\n- Bugfix:   (MBaker) Fixed minor problem with DATEDIFF YM calculation\n- Bugfix:   (MB) Applied patch 3695\n- Bugfix:   (ET) Work item 10536 - setAutosize() and Date cells not working properly\n- Bugfix:   (ET) Work item 10556 - Time value hour offset in output by HTML/PDF/CSV writers (system timezone problem)\n- Bugfix:   (ET) Work item 10558 - Control characters 0x14-0x1F are not treated by PHPExcel\n- Bugfix:   (ET) Work item 10560 - PHPExcel_Writer_Excel5 not working when open_basedir restriction is in effect\n- Bugfix:   (MBaker) Work item 10563 - IF formula calculation problem in PHPExcel 1.7.0 (string comparisons)\n- Bugfix:   (MBaker) Improved CODE() Text function result for UTF-8 characters\n- Bugfix:   (ET) Work item 10568 - Empty rows are collapsed with HTML/PDF writer\n- Bugfix:   (ET) Work item 10569 - Gaps between rows in output by PHPExcel_Writer_PDF (Upgrading to TCPDF 4.7.003)\n- Bugfix:   (ET) Work item 10575 - Problem reading formulas (Excel5 reader problem with \"fake\" shared formulas)\n- Bugfix:   (MBaker) Work item 10588 - Error type in formula: \"_raiseFormulaError message is Formula Error: An unexpected error occured\"\n- Bugfix:   (ET) Work item 10599 - Miscellaneous column width problems in Excel5/Excel2007 writer\n- Bugfix:   (ET) Work item 10615 - Reader/Excel5 'Unrecognized token 2D in formula' in latest version\n- Bugfix:   (ET) Work item 10623 - on php 5.3 PHPExcel 1.7 Excel 5 reader fails in _getNextToken, token = 2C, throws exception\n- Bugfix:   (ET) Work item 10617 - Fatal error when altering styles after workbook has been saved\n- Bugfix:   (ET) Work item 10661 - Images vertically stretched or squeezed when default font size is changed (PHPExcel_Writer_Excel5)\n- Bugfix:   (ET) Work item 10676 - Styles not read in \"manipulated\" Excel2007 workbook\n- Bugfix:   (ET) Work item 10059 - Windows 7 says corrupt file by PHPExcel_Writer_Excel5 when opening in Excel\n- Bugfix:   (MBaker) Work item 10708 - Calculations sometimes not working with cell references to other sheets\n- Bugfix:   (ET) Work item 10706 - Problem with merged cells after insertNewRowBefore()\n- Bugfix:   (MBaker) Applied patch 4023\n- Bugfix:   (MBaker) Fix to SUMIF() and COUNTIF() Statistical functions for when condition is a match against a string value\n- Bugfix:   (ET) Work item 10721 - PHPExcel_Cell::coordinateFromString should throw exception for bad string parameter\n- Bugfix:   (ET) Work item 10723 - EucrosiaUPC (Thai font) not working with PHPExcel_Writer_Excel5\n- Bugfix:   (MBaker) Improved the return of calculated results when the result value is an array\n- Bugfix:   (MBaker) Allow calculation engine to support Functions prefixed with @ within formulae\n- Bugfix:   (MBaker) Work item 10632 - Intersection operator (space operator) fatal error with calculation engine\n- Bugfix:   (ET) Work item 10742 - Chinese, Japanese, Korean characters show as squares in PDF\n- Bugfix:   (ET) Work item 10756 - sheet title allows invalid characters\n- Bugfix:   (ET) Work item 10757 - Sheet!$A$1 as function argument in formula causes infinite loop in Excel5 writer\n- Bugfix:   (MBaker) Work item 10740 - Cell range involving name not working with calculation engine - Modified calculation parser to handle range operator (:), but doesn't currently handle worksheet references with spaces or other non-alphameric characters, or trap erroneous references\n- Bugfix:   (MBaker) Work item 10798 - DATE function problem with calculation engine (says too few arguments given)\n- Bugfix:   (MBaker) Work item 10799 - Blank cell can cause wrong calculated value\n- Bugfix:   (MBaker) Modified ROW() and COLUMN() Lookup/Reference Functions to return an array when passed a cell range, plus some additional work on INDEX()\n- Bugfix:   (ET) Work item 10817 - Images not showing in Excel 97 using PHPExcel_Writer_Excel5 (patch by Jordi Gutiérrez Hermoso)\n- Bugfix:   (ET) Work item 10785 - When figures are contained in the excel sheet, Reader was stopped\n- Bugfix:   (MBaker) Work item 10818 - Formulas changed after insertNewRowBefore()\n- Bugfix:   (ET) Work item 10825 - Cell range row offset problem with shared formulas using PHPExcel_Reader_Excel5\n- Bugfix:   (MBaker) Work item 10832 - Warning: Call-time pass-by-reference has been deprecated\n- Bugfix:   (ET) Work item 10849 - Image should \"Move but don't size with cells\" instead of \"Move and size with cells\" with PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 10856 - Opening a Excel5 generated XLS in Excel 2007 results in header/footer entry not showing on input\n- Bugfix:   (ET) Work item 10859 - addExternalSheet() not returning worksheet\n- Bugfix:   (MBaker) Work item 10629 - Invalid results in formulas with named ranges\n\n\n2009/08/10 (v1.7.0):\n- General:  (ET) Work item  9893 - Expand documentation: Number formats\n- General:  (ET) Work item  9941 - Class 'PHPExcel_Cell_AdvancedValueBinder' not found\n- General:  (MB) Work item  9960 - Change return type of date functions to PHPExcel_Calculation_Functions::RETURNDATE_EXCEL\n- Feature:  (MBaker) - New RPN and stack-based calculation engine for improved performance of formula calculation\n            -   Faster (anything between 2 and 12 times faster than the old parser, depending on the complexity and nature of the formula)\n            -   Significantly more memory efficient when formulae reference cells across worksheets\n            -   Correct behaviour when referencing Named Ranges that exist on several worksheets\n            -   Support for Excel ^ (Exponential) and % (Percentage) operators\n            -   Support for matrices within basic arithmetic formulae (e.g. ={1,2,3;4,5,6;7,8,9}/2)\n            -   Better trapping/handling of NaN and infinity results (return #NUM! error)\n            -   Improved handling of empty parameters for Excel functions\n            -   Optional logging of calculation steps\n- Feature:  (MBaker) - New calculation engine can be accessed independently of workbooks (for use as a standalone calculator)\n- Feature:  (MBaker) Work Item  2346 - Implement more Excel calculation functions\n            -   Initial implementation of the COUNTIF() and SUMIF() Statistical functions\n            -   Added ACCRINT() Financial function\n- Feature:  (MBaker) - Modifications to number format handling for dddd and ddd masks in dates, use of thousand separators even when locale only implements it for money, and basic fraction masks (0 ?/? and ?/?)\n- Feature:  (ET) Work item  9794 - Support arbitrary fixed number of decimals in PHPExcel_Style_NumberFormat::toFormattedString()\n- Feature:  (ET) Work item  6857 - Improving performance and memory on data dumps\n            -    Various style optimizations (merging from branch wi6857-memory)\n            -    Moving hyperlink and dataValidation properties from cell to worksheet for lower PHP memory usage\n- Feature:  (MB) Work item  9869 - Provide fluent interfaces where possible\n- Feature:  (ET) Work item  9899 - Make easy way to apply a border to a rectangular selection\n- Feature:  (ET) Work item  9906 - Support for system window colors in PHPExcel_Reader_Excel5\n- Feature:  (ET) Work item  9911 - Horizontal center across selection\n- Feature:  (ET) Work item  9919 - Merged cells record, write to full record size in PHPExcel_Writer_Excel5\n- Feature:  (MB) Work item  9895 - Add page break between sheets in exported PDF\n- Feature:  (ET) Work item  9902 - Sanitization of UTF-8 input for cell values\n- Feature:  (ET) Work item  9930 - Read cached calculated value with PHPExcel_Reader_Excel5\n- Feature:  (ET) Work item  9896 - Miscellaneous CSS improvements for PHPExcel_Writer_HTML\n- Feature:  (ET) Work item  9947 - getProperties: setCompany feature request\n- Feature:  (MB) Patch 2981 - Insert worksheet at a specified index\n- Feature:  (MB) Patch 3018 - Change worksheet index\n- Feature:  (MB) Patch 3039 - Readfilter for CSV reader\n- Feature:  (ET) Work item 10172 - Check value of mbstring.func_overload when saving with PHPExcel_Writer_Excel5\n- Feature:  (ET) Work item 10251 - Eliminate dependency of an include path pointing to class directory\n- Feature:  (ET) Work item 10292 - Method for getting the correct reader for a certain file (contribution)\n- Feature:  (ET) Work item 10287 - Choosing specific row in fromArray method\n- Feature:  (ET) Work item 10319 - Shared formula support in PHPExcel_Reader_Excel5\n- Feature:  (MB,ET) Work item 10345 - Right-to-left column direction in worksheet\n- Bugfix:   (ET) Work item  9824 - PHPExcel_Reader_Excel5 not reading PHPExcel_Style_NumberFormat::FORMAT_NUMBER ('0')\n- Bugfix:   (ET) Work item  9858 - Fractional row height in locale other than English results in corrupt output using PHPExcel_Writer_Excel2007\n- Bugfix:   (ET) Work item  9846 - Fractional (decimal) numbers not inserted correctly when locale is other than English\n- Bugfix:   (ET) Work item  9863 - Fractional calculated value in locale other than English results in corrupt output using PHPExcel_Writer_Excel2007\n- Bugfix:   (ET) Work item  9830 - Locale aware decimal and thousands separator in exported formats HTML, CSV, PDF\n- Bugfix:   (MB) Work item  9819 - Cannot Add Image with Space on its Name\n- Bugfix:   (ET) Work item  9884 - Black line at top of every page in output by PHPExcel_Writer_PDF\n- Bugfix:   (ET) Work item  9885 - Border styles and border colors not showing in HTML output (regression since 1.6.4)\n- Bugfix:   (ET) Work item  9888 - Hidden screen gridlines setting in worksheet not read by PHPExcel_Reader_Excel2007\n- Bugfix:   (MB) Work item  9913 - Some valid sheet names causes corrupt output using PHPExcel_Writer_Excel2007\n- Bugfix:   (ET) Work item  9934 - More than 32,767 characters in a cell gives corrupt Excel file\n- Bugfix:   (ET) Work item  9937 - Images not getting copyied with the ->copy() function\n- Bugfix:   (ET) Work item  9940 - Bad calculation of column width setAutoSize(true) function\n- Bugfix:   (ET) Work item  9968 - Dates are sometimes offset by 1 day in output by HTML and PDF writers depending on system timezone setting\n- Bugfix:   (ET) Work item 10003 - Wingdings symbol fonts not working with PHPExcel_Writer_Excel5\n- Bugfix:   (MB) Work item 10010 - White space string prefix stripped by PHPExcel_Writer_Excel2007\n- Bugfix:   (ET) Work item 10023 - The name of the Workbook stream MUST be \"Workbook\", not \"Book\"\n- Bugfix:   (ET) Work item 10030 - Avoid message \"Microsoft Excel recalculates formulas...\" when closing xls file from Excel\n- Bugfix:   (ET) Work item 10031 - Non-unique newline representation causes problems with LEN formula\n- Bugfix:   (ET) Work item 10033 - Newline in cell not showing with PHPExcel_Writer_HTML and PHPExcel_Writer_PDF\n- Bugfix:   (ET) Work item 10046 - Rich-Text strings get prefixed by &nbsp; when output by HTML writer\n- Bugfix:   (ET) Work item 10052 - Leading spaces do not appear in output by HTML/PDF writers\n- Bugfix:   (MB) Work item 10061 - Empty Apache POI-generated file can not be read\n- Bugfix:   (ET) Work item 10068 - Column width not scaling correctly with font size in HTML and PDF writers\n- Bugfix:   (ET) Work item 10069 - Inaccurate row heights with HTML writer\n- Bugfix:   (MB) Patch 2992 - Reference helper\n- Bugfix:   (MBaker)  - Excel 5 Named ranges should not be local to the worksheet, but accessible from all worksheets\n- Bugfix:   (ET) Work item 10088 - Row heights are ignored by PHPExcel_Writer_PDF\n- Bugfix:   (MB) Patch 3003 - Write raw XML\n- Bugfix:   (ET) Work item 10098 - removeRow(), removeColumn() not always clearing cell values\n- Bugfix:   (ET) Work item 10142 - Problem reading certain hyperlink records with PHPExcel_Reader_Excel5\n- Bugfix:   (ET) Work item 10143 - Hyperlink cell range read failure with PHPExcel_Reader_Excel2007\n- Bugfix:   (MB) Work item 10149 - 'Column string index can not be empty.'\n- Bugfix:   (ET) Work item 10204 - getHighestColumn() sometimes says there are 256 columns with PHPExcel_Reader_Excel5\n- Bugfix:   (ET) Work item 10220 - extractSheetTitle fails when sheet title contains exclamation mark (!)\n- Bugfix:   (ET) Work item 10221 - setTitle() sometimes erroneously appends integer to sheet name\n- Bugfix:   (ET) Work item 10229 - Mac BIFF5 Excel file read failure (missing support for Mac OS Roman character set)\n- Bugfix:   (ET) Work item 10230 - BIFF5 header and footer incorrectly read by PHPExcel_Reader_Excel5\n- Bugfix:   (ET) Work item 10259 - iconv notices when reading hyperlinks with PHPExcel_Reader_Excel5\n- Bugfix:   (ET) Work item 10252 - Excel5 reader OLE read failure with small Mac BIFF5 Excel files\n- Bugfix:   (ET) Work item 10272 - Problem in reading formula : IF( IF ) with PHPExcel_Reader_Excel5\n- Bugfix:   (ET) Work item 10274 - Error reading formulas referencing external sheets with PHPExcel_Reader_Excel5\n- Bugfix:   (ET) Work item 10291 - Image horizontally stretched when default font size is increased (PHPExcel_Writer_Excel5)\n- Bugfix:   (ET) Work item 10333 - Undefined offset in Reader\\Excel5.php on line 3572\n- Bugfix:   (MB) Work item 10340 - PDF output different then XLS (copied data)\n- Bugfix:   (ET) Work item 10352 - Internal hyperlinks with UTF-8 sheet names not working in PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 10361 - String shared formula result read error with PHPExcel_Reader_Excel5\n- Bugfix:   (ET) Work item 10363 - Uncaught exception 'Exception' with message 'Valid scale is between 10 and 400.' in Classes/PHPExcel/Worksheet/PageSetup.php:338\n- Bugfix:   (ET) Work item 10355 - Using setLoadSheetsOnly fails if you do not use setReadDataOnly(true) and sheet is not the first sheet\n- Bugfix:   (MB) Work item 10362 - getCalculatedValue() sometimes incorrect with IF formula and 0-values\n- Bugfix:   (MBaker) Work Item  10198 - Excel Reader 2007 problem with \"shared\" formulae when \"master\" is an error\n- Bugfix:   (MBaker) Work Item  10106 - Named Range Bug, using the same range name on different worksheets\n- Bugfix:   (MBaker) Work Item  10004 - Java code in JAMA classes\n- Bugfix:   (MBaker) Work Item  9659 - getCalculatedValue() not working with some formulas involving error types\n- Bugfix:   (MBaker) Work Item  9447 - evaluation of both return values in an IF() statement returning an error if either result was an error, irrespective of the IF evaluation\n- Bugfix:   (MBaker) Work Item  6203 - Power in formulas: new calculation engine no longer treats ^ as a bitwise XOR operator\n- Bugfix:   (MBaker) - Bugfixes and improvements to many of the Excel functions in PHPExcel\n            -   Added optional \"places\" parameter in the BIN2HEX(), BIN2OCT, DEC2BIN(), DEC2OCT(), DEC2HEX(), HEX2BIN(), HEX2OCT(), OCT2BIN() and OCT2HEX() Engineering Functions\n            -    Trap for unbalanced matrix sizes in MDETERM() and MINVERSE() Mathematic and Trigonometric functions\n            -    Fix for default characters parameter value for LEFT() and RIGHT() Text functions\n            -    Fix for GCD() and LCB() Mathematical functions when the parameters include a zero (0) value\n            -    Fix for BIN2OCT() Engineering Function for 2s complement values (which were returning hex values)\n            -    Fix for BESSELK() and BESSELY() Engineering functions\n            -    Fix for IMDIV() Engineering Function when result imaginary component is positive (wasn't setting the sign)\n            -    Fix for ERF() Engineering Function when called with an upper limit value for the integration\n            -    Fix to DATE() Date/Time Function for year value of 0\n            -    Set ISPMT() function as category FINANCIAL\n            -    Fix for DOLLARDE() and DOLLARFR() Financial functions\n            -    Fix to EFFECT() Financial function (treating $nominal_rate value as a variable name rather than a value)\n            -    Fix to CRITBINOM() Statistical function (CurrentValue and EssentiallyZero treated as constants rather than variables)\n                     Note that an Error in the function logic can still lead to a permanent loop\n            -    Fix to MOD() Mathematical function to work with floating point results\n            -    Fix for QUOTIENT() Mathematical function\n            -    Fix to HOUR(), MINUTE() and SECOND() Date/Time functions to return an error when passing in a floating point value of 1.0 or greater, or less than 0\n            -    LOG() Function now correctly returns base-10 log when called with only one parameter, rather than the natural log as the default base\n            -    Modified text functions to handle multibyte character set (UTF-8).\n\n\n2009/04/22 (v1.6.7):\n- General:  (MB) Work item 9416 - Deprecate misspelled setStriketrough() and getStriketrough() methods\n- General:  (MB) Work item 9526 - Performance improvement when saving file\n- Feature:  (MB) Work item 9598 - Check that sheet title has maximum 31 characters\n- Feature:  (MB, ET) Work item 9631 - True support for Excel built-in number format codes\n- Feature:  (ET) Work item 9683 - Ability to read defect BIFF5 Excel file without CODEPAGE record\n- Feature:  (MB) Work item 9701 - Auto-detect which reader to invoke\n- Feature:  (ET) Work item 9214 - Deprecate insertion of dates using PHP-time (Unix time) [request for removal of feature]\n- Feature:  (ET) Work item 9747 - Support for entering time values like '9:45', '09:45' using AdvancedValueBinder\n- Feature:  (ET) Work item 9797 - DataType dependent horizontal alignment in HTML and PDF writer\n- Bugfix:   (MB) Work item 9375 - Cloning data validation object causes script to stop\n- Bugfix:   (ET) Work item 9400 - Simultaneous repeating rows and repeating columns not working with PHPExcel_Writer_Excel5\n- Bugfix:   (MB) Work item 9399 - Simultaneous repeating rows and repeating columns not working with PHPExcel_Writer_Excel2007\n- Bugfix:   (ET) Work item 9437 - Row outline level not working with PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 9452 - Occasional notices with PHPExcel_Reader_Excel5 when Excel file contains drawing elements\n- Bugfix:   (ET) Work item 9453 - PHPExcel_Reader_Excel5 fails as a whole when workbook contains images other than JPEG/PNG\n- Bugfix:   (ET) Work item 9444 - Excel5 writer checks for iconv but does not necessarily use it\n- Bugfix:   (ET) Work item 9463 - Altering a style on copied worksheet alters also the original\n- Bugfix:   (MB) Work item 9480 - Formulas are incorrectly updated when a sheet is renamed\n- Bugfix:   (MB) Work item 9513 - PHPExcel_Worksheet::extractSheetTitle not treating single quotes correctly\n- Bugfix:   (MB) Work item 9477 - PHP Warning raised in function array_key_exists\n- Bugfix:   (MB) Work item 9599 - getAlignWithMargins() gives wrong value when using PHPExcel_Reader_Excel2007\n- Bugfix:   (MB) Work item 9600 - getScaleWithDocument() gives wrong value when using PHPExcel_Reader_Excel2007\n- Bugfix:   (MB) Work item 9630 - PHPExcel_Reader_Excel2007 not reading the first user-defined number format\n- Bugfix:   (MB) Work item 9647 - Print area converted to uppercase after read with PHPExcel_Reader_Excel2007\n- Bugfix:   (MB) Work item 9661 - Incorrect reading of scope for named range using PHPExcel_Reader_Excel2007\n- Bugfix:   (MB) Work item 9690 - Error with pattern (getFillType) and rbg (getRGB)\n- Bugfix:   (ET) Work item 9712 - AdvancedValueBinder affected by system timezone setting when inserting date values\n- Bugfix:   (ET) Work item 9743 - PHPExcel_Reader_Excel2007 not reading value of active sheet index\n- Bugfix:   (ET) Work item 9742 - getARGB() sometimes returns SimpleXMLElement object instead of string with PHPExcel_Reader_Excel2007\n- Bugfix:   (ET) Work item 9731 - Negative image offset causes defects in 14excel5.xls and 20readexcel5.xlsx\n- Bugfix:   (ET) Work item 9758 - HTML & PDF Writer not working with mergeCells (regression since 1.6.5)\n- Bugfix:   (ET) Work item 9774 - Too wide columns with HTML and PDF writer\n- Bugfix:   (MB) Work item 9775 - PDF and cyrillic fonts\n- Bugfix:   (ET) Work item 9793 - Percentages not working correctly with HTML and PDF writers (shows 0.25% instead of 25%)\n- Bugfix:   (ET) Work item 9791 - PHPExcel_Writer_HTML creates extra borders around cell contents using setUseInlineCss(true)\n- Bugfix:   (ET) Work item 9784 - Problem with text wrap + merged cells in HTML and PDF writer\n- Bugfix:   (ET) Work item 9814 - Adjacent path separators in include_path causing IOFactory to violate open_basedir restriction\n\n\n--------------------------------------------------------------------------------\nBREAKING CHANGE! In previous versions of PHPExcel up to and including 1.6.6,\nwhen a cell had a date-like number format code, it was possible to enter a date\ndirectly using an integer PHP-time without converting to Excel date format.\n\nStarting with PHPExcel 1.6.7 this is no longer supported. Refer to the developer\ndocumentation for more information on entering dates into a cell.\n--------------------------------------------------------------------------------\n\n\n2009/03/02 (v1.6.6):\n- General:  (MB) Work item 9102 - Improve support for built-in number formats in PHPExcel_Reader_Excel2007\n- General:  (ET) Work item 9281 - Source files are in both UNIX and DOS formats - changed to UNIX\n- General:  (MB) Work item 9338 - Update documentation: Which language to write formulas in?\n- Feature:  (ET) Work item 8817 - Ignore DEFCOLWIDTH records with value 8 in PHPExcel_Reader_Excel5\n- Feature:  (ET) Work item 8847 - Support for width, height, offsetX, offsetY for images in PHPExcel_Reader_Excel5\n- Feature:  (MB) Work item 8870 - Disk Caching in specific folder\n- Feature:  (MBaker) Work item 2346 - Added SUMX2MY2, SUMX2PY2, SUMXMY2, MDETERM and MINVERSE Mathematical and Trigonometric Functions\n- Feature:  (MBaker) Work item 2346 - Added CONVERT Engineering Function\n- Feature:  (MBaker) Work item 2346 - Added DB, DDB, DISC, DOLLARDE, DOLLARFR, INTRATE, IPMT, PPMT, PRICEDISC, PRICEMAT and RECEIVED Financial Functions\n- Feature:  (MBaker) Work item 2346 - Added ACCRINTM, CUMIPMT, CUMPRINC, TBILLEQ, TBILLPRICE, TBILLYIELD, YIELDDISC and YIELDMAT Financial Functions\n- Feature:  (MBaker) Work item 2346 - Added DOLLAR Text Function\n- Feature:  (MBaker) Work item 2346 - Added CORREL, COVAR, FORECAST, INTERCEPT, RSQ, SLOPE and STEYX Statistical Functions\n- Feature:  (MBaker) Work item 2346 - Added PEARSON Statistical Functions as a synonym for CORREL\n- Feature:  (MBaker) Work item 2346 - Added LINEST, LOGEST (currently only valid for stats = false), TREND and GROWTH Statistical Functions\n- Feature:  (MBaker) Work item 2346 - Added RANK and PERCENTRANK Statistical Functions\n- Feature:  (MBaker) Work item 2346 - Added ROMAN Mathematical Function (Classic form only)\n- Feature:  (MB) Work item 8931 - Update documentation to show example of getCellByColumnAndRow($col, $row)\n- Feature:  (MB) Work item 8770 - Implement worksheet, row and cell iterators\n- Feature:  (MB) Work item 9001 - Support for arbitrary defined names (named range)\n- Feature:  (MB, ET) Work item 9016 - Update formulas when sheet title / named range title changes\n- Feature:  (MB) Work item 9103 - Ability to read cached calculated value\n- Feature:  (MBaker, ET) Work item 8483 - Support for Excel 1904 calendar date mode (Mac)\n- Feature:  (ET) Work item 9194 - PHPExcel_Writer_Excel5 improvements writing shared strings table\n- Feature:  (ET) Work item 9248 - PHPExcel_Writer_Excel5 iconv fallback when mbstring extension is not enabled\n- Feature:  (ET) Work item 9253 - UTF-8 support in font names in PHPExcel_Writer_Excel5\n- Feature:  (MB) Work item 9215 - Implement value binding architecture\n- Feature:  (MB) Work item 6742 - PDF writer not working with UTF-8\n- Feature:  (ET) Work item 9355 - Eliminate duplicate style entries in multisheet workbook written by PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 8810 - Redirect to client browser fails due to trailing white space in class definitions\n- Bugfix:   (MB) Work item 8816 - Spurious column dimension element introduced in blank worksheet after using PHPExcel_Writer_Excel2007\n- Bugfix:   (ET) Work item 8830 - Image gets slightly narrower than expected when using PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 8831 - Image laid over non-visible row gets squeezed in height when using PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 8860 - PHPExcel_Reader_Excel5 fails when there are 10 or more images in the workbook\n- Bugfix:   (MB) Work item 8909 - Different header/footer images in different sheets not working with PHPExcel_Writer_Excel2007\n- Bugfix:   (MB, ET) Work item 8924 - Fractional seconds disappear when using PHPExcel_Reader_Excel2007 and PHPExcel_Reader_Excel5\n- Bugfix:   (ET) Work item 7994 - Images not showing in OpenOffice when using PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 9047 - Images not showing on print using PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 9085 - PHPExcel_Writer_Excel5 maximum allowed record size 4 bytes too short\n- Bugfix:   (MB) Work item 9119 - Not numeric strings are formatted as dates and numbers using worksheet's toArray method\n- Bugfix:   (ET) Work item 9132 - Excel5 simple formula parsing error\n- Bugfix:   (ET) Work item 9206 - Problems writing dates with CSV\n- Bugfix:   (ET) Work item 9203 - PHPExcel_Reader_Excel5 reader fails with fatal error when reading group shapes\n- Bugfix:   (ET) Work item 9231 - PHPExcel_Writer_Excel5 fails completely when workbook contains more than 57 colors\n- Bugfix:   (ET) Work item 9244 - PHPExcel_Writer_PDF not compatible with autoload\n- Bugfix:   (ET) Work item 9250 - Fatal error: Call to a member function getNestingLevel() on a non-object in PHPExcel/Reader/Excel5.php on line 690\n- Bugfix:   (MB) Work item 9246 - Notices when running test 04printing.php on PHP 5.2.8\n- Bugfix:   (MB) Work item 9294 - insertColumn() spawns creation of spurious RowDimension\n- BugFix:   (MBaker) Work item 9296 - Fix declarations for methods in extended Trend classes\n- Bugfix:   (MBaker) Work item 2346 - Fix to parameters for the FORECAST Statistical Function\n- Bugfix:   (MB) Work item 7083 - PDF writer problems with cell height and text wrapping\n- Bugfix:   (MBaker) Work Item 9337 - Fix test for calculated value in case the returned result is an array\n- Bugfix:   (ET) Work Item 9354 - Column greater than 256 results in corrupt Excel file using PHPExcel_Writer_Excel5\n- Bugfix:   (MB) Work item 9351 - Excel Numberformat 0.00 results in non internal decimal places values in toArray() Method\n- Bugfix:   (MB,ET) Work item 9356 - setAutoSize not taking into account text rotation\n- Bugfix:   (ET) Work item 9372 - Call to undefined method PHPExcel_Worksheet_MemoryDrawing::getPath() in PHPExcel/Writer/HTML.php\n\n\n2009/01/05 (v1.6.5):\n- General:  (MB) Applied patch 2063\n- General:  (MB) Applied patch from work item 8073 - Optimise Shared Strings\n- General:  (MB) Applied patch from work item 8074 - Optimise Cell Sorting\n- General:  (MB) Applied patch from work item 8075 - Optimise Style Hashing\n- General:  (ET) Applied patch from work item 8245 - UTF-8 enhancements\n- General:  (ET) Applied patch from work item 8283 - PHPExcel_Writer_HTML validation errors against strict HTML 4.01 / CSS 2.1\n- General:  (MB) Documented work items 6203 and 8110 in manual\n- General:  (ET) Restructure package hierachy so classes can be found more easily in auto-generated API (from work item 8468)\n- General:  (MB) Work item 8806 - Redirect output to a client's browser: Update recommendation in documentation\n- Feature:  (ET) Work item 7897 - PHPExcel_Reader_Excel5 support for print gridlines\n- Feature:  (ET) Work item 7899 - Screen gridlines support in Excel5 reader/writer\n- Feature:  (MB, ET) Work item 7552 - Option for adding image to spreadsheet from image resource in memory\n- Feature:  (ET) Work item 7862 - PHPExcel_Reader_Excel5 style support for BIFF5 files (Excel 5.0 - Excel 95)\n- Feature:  (ET) Work item 7918 - PHPExcel_Reader_Excel5 support for user-defined colors and special built-in colors\n- Feature:  (ET) Work item 7992 - Support for freeze panes in PHPExcel_Reader_Excel5\n- Feature:  (ET) Work item 7996 - Support for header and footer margins in PHPExcel_Reader_Excel5\n- Feature:  (ET) Work item 7997 - Support for active sheet index in Excel5 reader/writer\n- Feature:  (MB) Work item 7991 - Freeze panes not read by PHPExcel_Reader_Excel2007\n- Feature:  (MB, ET) Work item 7993 - Support for screen zoom level (feature request)\n- Feature:  (ET) Work item 8012 - Support for default style in PHPExcel_Reader_Excel5\n- Feature:  (MB) Work item 8094 - Apple iWork / Numbers.app incompatibility\n- Feature:  (MB) Work item 7931 - Support \"between rule\" in conditional formatting\n- Feature:  (MB) Work item 8308 - Comment size, width and height control (feature request)\n- Feature:  (ET) Work item 8418 - Improve method for storing MERGEDCELLS records in PHPExcel_Writer_Excel5\n- Feature:  (ET) Work item 8435 - Support for protectCells() in Excel5 reader/writer\n- Feature:  (ET) Work item 8472 - Support for fitToWidth and fitToHeight pagesetup properties in PHPExcel_Reader_Excel5\n- Feature:  (ET) Work item 8489 - Support for setShowSummaryBelow() and setShowSummaryRight() in PHPExcel_Writer_Excel5\n- Feature:  (MB) Work item 8483 - Support for Excel 1904 calendar date mode (Mac)\n- Feature:  (ET) Work item 7538 - Excel5 reader: Support for reading images (bitmaps)\n- Feature:  (ET) Work item 8787 - Support for default style in PHPExcel_Writer_Excel5\n- Feature:  (MBaker) Modified calculate() method to return either an array or the first value from the array for those functions that return arrays rather than single values (e.g the MMULT and TRANSPOSE function). This performance can be modified based on the $returnArrayAsType which can be set/retrieved by calling the setArrayReturnType() and getArrayReturnType() methods of the PHPExcel_Calculation class.\n- Feature:  (MBaker) Work item 2346 - Added ERROR.TYPE Information Function, MMULT Mathematical and Trigonometry Function, and TRANSPOSE Lookup and Reference Function\n- Bugfix:   (ET) Work item 7896 - setPrintGridlines(true) not working with PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 7907 - Incorrect mapping of fill patterns in PHPExcel_Writer_Excel5\n- Bugfix:   (MB) Work item 7898 - setShowGridlines(false) not working with PHPExcel_Writer_Excel2007\n- Bugfix:   (MB) Work item 7905 - getShowGridlines() gives inverted value when reading sheet with PHPExcel_Reader_Excel2007\n- Bugfix:   (ET) Work item 7944 - User-defined column width becomes slightly larger after read/write with Excel5\n- Bugfix:   (ET) Work item 7949 - Incomplete border style support in PHPExcel_Writer_Excel5\n- Bugfix:   (MB) Work item 7928 - Conditional formatting \"containsText\" read/write results in MS Office Excel 2007 crash\n- Bugfix:   (MB) Work item 7995 - All sheets are always selected in output when using PHPExcel_Writer_Excel2007\n- Bugfix:   (MB) Work item 8013 - COLUMN function warning message during plain read/write\n- Bugfix:   (MB) Work item 8155 - setValue(0) results in string data type '0'\n- Bugfix:   (MB) Work item 8226 - Styles not removed when removing rows from sheet\n- Bugfix:   (MB) Work item 8301 - =IF formula causes fatal error during $objWriter->save() in Excel2007 format\n- Bugfix:   (ET) Work item 8333 - Exception thrown reading valid xls file: \"Excel file is corrupt. Didn't find CONTINUE record while reading shared strings\"\n- Bugfix:   (ET) Work item 8320 - MS Outlook corrupts files generated by PHPExcel_Writer_Excel5\n- Bugfix:   (MB) Work item 8351 - Undefined method PHPExcel_Worksheet::setFreezePane() in ReferenceHelper.php on line 271\n- Bugfix:   (MB) Work item 8401 - Ampersands (&), left and right angles (<, >) in Rich-Text strings leads to corrupt output using PHPExcel_Writer_Excel2007\n- Bugfix:   (ET) Work item 8408 - Print header and footer not supporting UTF-8 in PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 8463 - Vertical page breaks not working with PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 8476 - Missing support for accounting underline types in PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 8482 - Infinite loops when reading corrupt xls file using PHPExcel_Reader_Excel5\n- Bugfix:   (ET) Work item 8566 - Sheet protection password not working with PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 8596 - PHPExcel_Style_NumberFormat::FORMAT_NUMBER ignored by PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 8781 - PHPExcel_Reader_Excel5 fails a whole when workbook contains a chart\n- Bugfix:   (ET) Work item 8788 - Occasional loss of column widths using PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 8795 - Notices while reading formulas with deleted sheet references using PHPExcel_Reader_Excel5\n- Bugfix:   (MB) Work item 8807 - Default style not read by PHPExcel_Reader_Excel2007\n- Bugfix:   (MB) Work item 9341 - Blank rows occupy too much space in file generated by PHPExcel_Writer_Excel2007\n\n\n2008/10/27 (v1.6.4):\n- General:  (ET) Work item 7882 - RK record number error in MS developer documentation: 0x007E should be 0x027E\n- Feature:  (MBaker) Work item 7878 - getHighestColumn() returning \"@\" for blank worksheet causes corrupt output\n- Feature:  (MBaker) Work item 2346 - Implement ROW and COLUMN Lookup/Reference Functions (when specified with a parameter)\n- Feature:  (MBaker) Work item 2346 - Implement initial work on OFFSET Lookup/Reference Function (returning address rather than value at address)\n- Feature:  (ET) Work item 7416 - Excel5 reader: Page margins\n- Feature:  (ET) Work item 7417 - Excel5 reader: Header & Footer\n- Feature:  (ET) Work item 7449 - Excel5 reader support for page setup (paper size etc.)\n- Feature:  (MB) Work item 7445 - Improve speed and memory consumption of PHPExcel_Writer_CSV\n- Feature:  (MB) Work item 7432 - Better recognition of number format in HTML, CSV, and PDF writer\n- Feature:  (MB) Work item 7485 - Font support: Superscript and Subscript\n- Feature:  (ET) Work item 7509 - Excel5 reader font support: Super- and subscript\n- Feature:  (ET) Work item 7521 - Excel5 reader style support: Text rotation and stacked text\n- Feature:  (ET) Work item 7530 - Excel5 reader: Support for hyperlinks\n- Feature:  (MB, ET) Work item 7557 - Import sheet by request\n- Feature:  (ET) Work item 7607 - PHPExcel_Reader_Excel5 support for page breaks\n- Feature:  (ET) Work item 7622 - PHPExcel_Reader_Excel5 support for shrink-to-fit\n- Feature:  (MB, ET) Work item 7675 - Support for error types\n- Feature:  (ET) Work item 7388 - Excel5 reader true formula support\n- Feature:  (ET) Work item 7701 - Support for named ranges (defined names) in PHPExcel_Reader_Excel5\n- Feature:  (ET) Work item 7781 - Support for repeating rows and repeating columns (print titles) in PHPExcel_Reader_Excel5\n- Feature:  (ET) Work item 7783 - Support for print area in PHPExcel_Reader_Excel5\n- Feature:  (ET) Work item 7795 - Excel5 reader and writer support for horizontal and vertical centering of page\n- Feature:  (MB) Applied patch 1962\n- Feature:  (ET) Work item 7866 - Excel5 reader and writer support for hidden cells (formulas)\n- Feature:  (MB, ET) Work item 7612 - Support for indentation in cells (feature request)\n- Feature:  (MB, ET) Work item 7828 - Option for reading only specified interval of rows in a sheet\n- Bugfix:   (MBaker) Work item 7367 - PHPExcel_Calculation_Functions::DATETIMENOW() and PHPExcel_Calculation_Functions::DATENOW() to force UTC\n- Bugfix:   (MBaker) Work item 7395 - Modified PHPExcel_Shared_Date::FormattedPHPToExcel() and PHPExcel_Shared_Date::ExcelToPHP to force datatype for return values\n- Bugfix:   (ET) Work item 7450 - Excel5 reader not producing UTF-8 strings with BIFF5 files\n- Bugfix:   (MB) Work item 7470 - Array constant in formula gives run-time notice with Excel2007 writer\n- Bugfix:   (MB) Work item 7494 - PHPExcel_Reader_Excel2007 setReadDataOnly(true) returns Rich-Text\n- Bugfix:   (ET) Work item 7496 - PHPExcel_Reader_Excel5 setReadDataOnly(true) returns Rich-Text\n- Bugfix:   (MB) Work item 7497 - Characters before superscript or subscript losing style\n- Bugfix:   (MB) Work item 7507 - Subscript not working with HTML writer\n- Bugfix:   (MB) Work item 7508 - DefaultColumnDimension not working on first column (A)\n- Bugfix:   (MB) Work item 7527 - Negative numbers are stored as text in PHPExcel_Writer_2007\n- Bugfix:   (ET) Work item 7531 - Text rotation and stacked text not working with PHPExcel_Writer_Excel5\n- Bugfix:   (MB) Work item 7536 - PHPExcel_Shared_Date::isDateTimeFormatCode erroneously says true\n- Bugfix:   (MB) Work item 7559 - Different images with same filename in separate directories become duplicates\n- Bugfix:   (ET) Work item 7568 - PHPExcel_Reader_Excel5 not returning sheet names as UTF-8 using for Excel 95 files\n- Bugfix:   (MB) Work item 7575 - setAutoSize(true) on empty column gives column width of 10 using PHPExcel_Writer_Excel2007\n- Bugfix:   (MB, ET) Work item 7573 - setAutoSize(true) on empty column gives column width of 255 using PHPExcel_Writer_Excel5\n- Bugfix:   (MB) Work item 7514 - Worksheet_Drawing bug\n- Bugfix:   (MB) Work item 7593 - getCalculatedValue() with REPT function causes script to stop\n- Bugfix:   (MB) Work item 7594 - getCalculatedValue() with LEN function causes script to stop\n- Bugfix:   (MB) Work item 7600 - Explicit fit-to-width (page setup) results in fit-to-height becoming 1\n- Bugfix:   (MB) Work item 7610 - Fit-to-width value of 1 is lost after read/write of Excel2007 spreadsheet\n- Bugfix:   (MB) Work item 7516 - Conditional styles not read properly using PHPExcel_Reader_Excel2007\n- Bugfix:   (MB) Work item 7611 - PHPExcel_Writer_2007: Default worksheet style works only for first sheet\n- Bugfix:   (ET) Work item 6940 - Cannot Lock Cells using PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 7621 - Incorrect cell protection values found when using Excel5 reader\n- Bugfix:   (ET) Work item 7623 - Default row height not working above highest row using PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 7637 - Default column width does not get applied when using PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 7642 - Broken support for UTF-8 string formula results in PHPExcel_Reader_Excel5\n- Bugfix:   (ET) Work item 7643 - UTF-8 sheet names not working with PHPExcel_Writer_Excel5\n- Bugfix:   (MB) Work item 7631 - getCalculatedValue() with ISNONTEXT function causes script to stop\n- Bugfix:   (ET) Work item 7652 - Missing BIFF3 functions in PHPExcel_Writer_Excel5: USDOLLAR (YEN), FINDB, SEARCHB, REPLACEB, LEFTB, RIGHTB, MIDB, LENB, ASC, DBCS (JIS)\n- Bugfix:   (ET) Work item 7663 - Excel5 reader doesn't read numbers correctly in 64-bit systems\n- Bugfix:   (ET) Work item 7667 - Missing BIFF5 functions in PHPExcel_Writer_Excel5: ISPMT, DATEDIF, DATESTRING, NUMBERSTRING\n- Bugfix:   (ET) Work item 7668 - Missing BIFF8 functions in PHPExcel_Writer_Excel5: GETPIVOTDATA, HYPERLINK, PHONETIC, AVERAGEA, MAXA, MINA, STDEVPA, VARPA, STDEVA, VARA\n- Bugfix:   (MB) Work item 7657 - Wrong host value in PHPExcel_Shared_ZipStreamWrapper::stream_open()\n- Bugfix:   (ET) Work item 7676 - PHPExcel_Reader_Excel5 not reading explicitly entered error types in cells\n- Bugfix:   (ET) Work item 7678 - Boolean and error data types not preserved for formula results in PHPExcel_Reader_Excel5\n- Bugfix:   (MB) Work item 7695 - PHPExcel_Reader_Excel2007 ignores cell data type\n- Bugfix:   (ET) Work item 7712 - PHPExcel_Reader_Excel5 ignores cell data type\n- Bugfix:   (ET) Work item 7587 - PHPExcel_Writer_Excel5 not aware of data type\n- Bugfix:   (ET) Work item 7713 - Long strings sometimes truncated when using PHPExcel_Reader_Excel5\n- Bugfix:   (ET) Work item 7727 - Direct entry of boolean or error type in cell not supported by PHPExcel_Writer_Excel5\n- Bugfix:   (MB) Work item 7714 - PHPExcel_Reader_Excel2007: Error reading cell with data type string, date number format, and numeric-like cell value\n- Bugfix:   (ET) Work item 7735 - Row and column outlines (group indent level) not showing after using PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 7737 - Missing UTF-8 support in number format codes for PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 7750 - Missing UTF-8 support with PHPExcel_Writer_Excel5 for explicit string in formula\n- Bugfix:   (MB) Work item 7726 - Problem with class constants in PHPExcel_Style_NumberFormat\n- Bugfix:   (ET) Work item 7758 - Sometimes errors with PHPExcel_Reader_Excel5 reading hyperlinks\n- Bugfix:   (ET) Work item 7759 - Hyperlink in cell always results in string data type when using PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 7771 - Excel file with blank sheet seen as broken in MS Office Excel 2007 when created by PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 7785 - PHPExcel_Reader_Excel5: Incorrect reading of formula with explicit string containing (escaped) double-quote\n- Bugfix:   (MB) Work item 7787 - getCalculatedValue() fails on formula with sheet name containing (escaped) single-quote\n- Bugfix:   (MB) Work item 7786 - getCalculatedValue() fails on formula with explicit string containing (escaped) double-quote\n- Bugfix:   (MB) Work item 7780 - Problems with simultaneous repeatRowsAtTop and repeatColumnsAtLeft using Excel2007 reader and writer\n- Bugfix:   (ET) Work item 7802 - PHPExcel_Reader_Excel5: Error reading formulas with sheet reference containing special characters\n- Bugfix:   (ET) Work item 7831 - Off-sheet references sheet!A1 not working with PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 7834 - Repeating rows/columns (print titles), print area not working with PHPExcel_Writer_Excel5\n- Bugfix:   (ET) Work item 7849 - Formula having datetime number format shows as text when using PHPExcel_Writer_Excel5\n- Bugfix:   (MBaker) Work item 7863 - Cannot set formula to hidden using applyFromArray()\n- Bugfix:   (MBaker) Work item 7805 - HTML/PDF Writers limited to 26 columns by calculateWorksheetDimension (erroneous comparison in getHighestColumn() method)\n- Bugfix:   (MB) Work item 7873 - Formula returning error type is lost when read by PHPExcel_Reader_Excel2007\n- Bugfix:   (ET) Work item 7883 - PHPExcel_Reader_Excel5: Cell style lost for last column in group of blank cells\n- Bugfix:   (MB) Work item 7886 - Column width sometimes collapses to auto size using Excel2007 reader/writer\n- Bugfix:   (MB) Work item 9343 - Data Validation Formula = 0 crashes Excel\n\n\n2008/08/25 (v1.6.3):\n- Bugfix:   (MBaker) Work item 7367 - Modified PHPExcel_Shared_Date::PHPToExcel() to force UTC\n- General:  (MB) Applied patch 1629\n- General:  (MB) Applied patch 1644\n- General:  (MB) Work item 6485 - Implement repeatRow and repeatColumn in Excel5 writer\n- General:  (MB) Work item 6838 - Remove scene3d filter in Excel2007 drawing\n- Feature:  (MBaker) Work item 2346 - Implement CHOOSE and INDEX Lookup/Reference Functions\n- Feature:  (MBaker) Work item 2346 - Implement CLEAN Text Functions\n- Feature:  (MBaker) Work item 2346 - Implement YEARFRAC Date/Time Functions\n- Feature:  (MB) Work item 6508 - Implement 2 options for print/show gridlines\n- Feature:  (MB) Work item 7270 - Add VLOOKUP function (contribution)\n- Feature:  (MB) Work item 7182 - Implemented: ShrinkToFit\n- Feature:  (MB) Work item 7218 - Row heights not updated correctly when inserting new rows\n- Feature:  (MB) Work item 7157 - Copy worksheets within the same workbook\n- Feature:  (ET) Work item 7290 - Excel5 reader style support: horizontal and vertical alignment plus text wrap\n- Feature:  (ET) Work item 7294 - Excel5 reader support for merged cells\n- Feature:  (ET) Work item 7296 - Excel5 reader: Sheet Protection\n- Feature:  (ET) Work item 7297 - Excel5 reader: Password for sheet protection\n- Feature:  (ET) Work item 7299 - Excel5 reader: Column width\n- Feature:  (ET) Work item 7301 - Excel5 reader: Row height\n- Feature:  (ET) Work item 7304 - Excel5 reader: Font support\n- Feature:  (ET) Work item 7324 - Excel5 reader: support for locked cells\n- Feature:  (ET) Work item 7330 - Excel5 reader style support: Fill (background colors and patterns)\n- Feature:  (ET) Work item 7332 - Excel5 reader style support: Borders (style and color)\n- Feature:  (ET) Work item 7346 - Excel5 reader: Rich-Text support\n- Feature:  (MB) Work item 7313 - Read Excel built-in number formats with Excel 2007 reader\n- Feature:  (ET) Work item 7317 - Excel5 reader: Number format support\n- Feature:  (MB) Work item 7362 - Creating a copy of PHPExcel object\n- Feature:  (ET) Work item 7373 - Excel5 reader: support for row / column outline (group)\n- Feature:  (MB) Work item 7380 - Implement default row/column sizes\n- Feature:  (MB) Work item 7364 - Writer HTML - option to return styles and table separately\n- Feature:  (ET) Work item 7393 - Excel5 reader: Support for remaining built-in number formats\n- Bugfix:   (MBaker) Fixed rounding in HOUR MINUTE and SECOND Time functions, and improved performance for these\n- Bugfix:   (MBaker) Fix to TRIM function\n- Bugfix:   (MBaker) Fixed range validation in TIME Functions.php\n- Bugfix:   (MBaker) EDATE and EOMONTH functions now return date values based on the returnDateType flag\n- Bugfix:   (MBaker) Write date values that are the result of a calculation function correctly as Excel serialized dates rather than PHP serialized date values\n- Bugfix:   (MB) Work item 6690 - Excel2007 reader not always reading boolean correctly\n- Bugfix:   (MB) Work item 6275 - Columns above IZ\n- Bugfix:   (MB) Work item 6853 - Other locale than English causes Excel2007 writer to produce broken xlsx\n- Bugfix:   (MB) Work item 7061 - Typo: Number_fromat in NumberFormat.php\n- Bugfix:   (MB) Work item 6865 - Bug in Worksheet_BaseDrawing setWidth()\n- Bugfix:   (MB) Work item 6891 - PDF writer collapses column width for merged cells\n- Bugfix:   (MB) Work item 6867 - Issues with drawings filenames\n- Bugfix:   (MB) Work item 7073 - fromArray() local variable isn't defined\n- Bugfix:   (MB) Work item 7276 - PHPExcel_Writer_Excel5->setTempDir() not passed to all classes involved in writing to a file\n- Bugfix:   (MB) Work item 7277 - Excel5 reader not handling UTF-8 properly\n- Bugfix:   (MB) Work item 7327 - If you write a 0 value in cell, cell shows as empty\n- Bugfix:   (MB) Work item 7302 - Excel2007 writer: Row height ignored for empty rows\n- Bugfix:   (MB) Work item 7281 - Excel2007 (comments related error)\n- Bugfix:   (MB) Work item 7345 - Column width in other locale\n- Bugfix:   (MB) Work item 7347 - Excel2007 reader not reading underlined Rich-Text\n- Bugfix:   (ET) Work item 7357 - Excel5 reader converting booleans to strings\n- Bugfix:   (MB) Work item 7365 - Recursive Object Memory Leak\n- Bugfix:   (MB) Work item 7372 - Excel2007 writer ignoring row dimensions without cells\n- Bugfix:   (ET) Work item 7382 - Excel5 reader is converting formatted numbers / dates to strings\n\n\n2008/06/23 (v1.6.2):\n- General:  (MB) Work item 6088 - Document style array values\n- General:  (MB) Applied patch 1195\n- General:  (MB) Work item 6178 - Redirecting output to a client’s web browser - http headers\n- General:  (MB) Work item 6187 - Improve worksheet garbage collection\n- General:  (MBaker) Functions that return date values can now be configured to return as Excel serialized date/time, PHP serialized date/time, or a PHP date/time object.\n- General:  (MBaker) Functions that explicitly accept dates as parameters now permit values as Excel serialized date/time, PHP serialized date/time, a valid date string, or a PHP date/time object.\n- General:  (MBaker) Implement ACOSH, ASINH and ATANH functions for those operating platforms/PHP versions that don't include these functions\n- General:  (MBaker) Implement ATAN2 logic reversing the arguments as per Excel\n- General:  (MBaker) Additional validation of parameters for COMBIN\n- General:  (MBaker) Fixed validation for CEILING and FLOOR when the value and significance parameters have different signs; and allowed default value of 1 or -1 for significance when in GNUMERIC compatibility mode\n- Feature:  (MBaker) Work item 2346 - Implement ADDRESS, ISLOGICAL, ISTEXT and ISNONTEXT functions\n- Feature:  (MBaker) Work item 2346 - Implement COMPLEX, IMAGINARY, IMREAL, IMARGUMENT, IMCONJUGATE, IMABS, IMSUB, IMDIV, IMSUM, IMPRODUCT, IMSQRT, IMEXP, IMLN, IMLOG10, IMLOG2, IMPOWER IMCOS and IMSIN Engineering functions\n- Feature:  (MBaker) Work item 2346 - Implement NETWORKDAYS and WORKDAY Date/Time functions\n- Feature:  (MB) Work item 6100 - Make cell column AAA available\n- Feature:  (MB) Work item 6095 - Mark particular cell as selected when opening Excel\n- Feature:  (MB) Work item 6120 - Multiple sheets in PDF and HTML\n- Feature:  (MB) Work item 6227 - Implement PHPExcel_ReaderFactory and PHPExcel_WriterFactory\n- Feature:  (MB) Work item 6249 - Set image root of PHPExcel_Writer_HTML\n- Feature:  (MB) Work item 6264 - Enable/disable calculation cache\n- Feature:  (MB) Work item 6259 - PDF writer and multi-line text\n- Feature:  (MB) Work item 6350 - Feature request - setCacheExpirationTime()\n- Feature:  (JB) Work item 6370 - Implement late-binding mechanisms to reduce memory footprint\n- Feature:  (JB) Work item 6430 - Implement shared styles\n- Feature:  (MB) Work item 6391 - Copy sheet from external Workbook to active Workbook\n- Feature:  (MB) Work item 6428 - Functions in Conditional Formatting\n- Bugfix:   (MB) Work item 6096 - Default Style in Excel5\n- Bugfix:   (MB) Work item 6150 - Numbers starting with '+' cause Excel 2007 errors\n- Bugfix:   (MB) Work item 6092 - ExcelWriter5 is not PHP5 compatible, using it with E_STRICT results in a bunch of errors (applied patches)\n- Bugfix:   (MB) Work item 6179 - Error Reader Excel2007 line 653 foreach ($relsDrawing->Relationship as $ele)\n- Bugfix:   (MB) Work item 6229 - Worksheet toArray() screws up DATE\n- Bugfix:   (MB) Work item 6253 - References to a Richtext cell in a formula\n- Bugfix:   (MB) Work item 6285 - insertNewColumnBefore Bug\n- Bugfix:   (MB) Work item 6319 - Error reading Excel2007 file with shapes\n- Bugfix:   (MBaker) Work item 6302 - Determine whether date values need conversion from PHP dates to Excel dates before writing to file, based on the data type (float or integer)\n- Bugfix:   (MBaker) Fixes to DATE function when it is given negative input parameters\n- Bugfix:   (MB) Work item 6347 - PHPExcel handles empty cells other than Excel\n- Bugfix:   (MB) Work item 6348 - PHPExcel handles 0 and \"\" as being the same\n- Bugfix:   (MB) Work item 6357 - Problem Using Excel2007 Reader for Spreadsheets containing images\n- Bugfix:   (MB) Work item 6359 - ShowGridLines ignored when reading/writing Excel 2007\n- Bugfix:   (MB) Work item 6426 - Bug With Word Wrap in Excel 2007 Reader\n\n\n2008/04/28 (v1.6.1):\n- General:  (MB) Work item 5532 - Fix documentation printing\n- General:  (MB) Work item 5586 - Memory usage improvements\n- General:  (MB) Applied patch 990\n- General:  (MB) Applied patch 991\n- Feature:  (BM) Work item 2841 - Implement PHPExcel_Reader_Excel5\n- Feature:  (MB) Work item 5564 - Implement \"toArray\" and \"fromArray\" method\n- Feature:  (MB) Work item 5665 - Read shared formula\n- Feature:  (MB) Work item 5681 - Read image twoCellAnchor\n- Feature:  (MB) Work item 4446 - &G Image as bg for headerfooter\n- Feature:  (MB) Work item 5834 - Implement page layout functionality for Excel5 format\n- Feature:  (MB) Work item 6039 - Feature request: PHPExcel_Writer_PDF\n- Bugfix:   (MB) Work item 5517 - DefinedNames null check\n- Bugfix:   (MB) Work item 5463 - Hyperlinks should not always have trailing slash\n- Bugfix:   (MB) Work item 5592 - Saving Error - Uncaught exception (#REF! named range)\n- Bugfix:   (MB) Work item 5634 - Error when creating Zip file on Linux System (Not Windows)\n- Bugfix:   (MB) Work item 5876 - Time incorrecly formated\n- Bugfix:   (MB) Work item 5914 - Conditional formatting - second rule not applied\n- Bugfix:   (MB) Work item 5978 - PHPExcel_Reader_Excel2007 cannot load PHPExcel_Shared_File\n- Bugfix:   (MB) Work item 6020 - Output redirection to web browser\n\n\n2008/02/14 (v1.6.0):\n- General:  (MB) Work item 3156 - Use PHPExcel datatypes in formula calculation\n- Feature:  (MB) Work item 5019 - Center on page when printing\n- Feature:  (MB) Work item 5099 - Hyperlink to other spreadsheet\n- Feature:  (MB) Work item 5104 - Set the print area of a worksheet\n- Feature:  (MB) Work item 5118 - Read \"definedNames\" property of worksheet\n- Feature:  (MB) Work item 5338 - Set default style for all cells\n- Feature:  (MB) Work item 4216 - Named Ranges\n- Feature:  (MB) Work item 5398 - Implement worksheet references (Sheet1!A1)\n- Bugfix:   (MB) Work item 4967 - Redirect output to a client's web browser\n- Bugfix:   (MB) Work item 5008 - \"File Error: data may have been lost.\" seen in Excel 2007 and Excel 2003 SP3 when opening XLS file\n- Bugfix:   (MB) Work item 5165 - Bug in style's getHashCode()\n- Bugfix:   (MB) Work item 5165 - PHPExcel_Reader not correctly reading numeric values\n- Bugfix:   (MB) Work item 5324 - Text rotation is read incorrectly\n- Bugfix:   (MB) Work item 5326 - Enclosure \" and data \" result a bad data : \\\" instead of \"\"\n- Bugfix:   (MB) Work item 5332 - Formula parser - IF statement returning array instead of scalar\n- Bugfix:   (MB) Work item 5351 - setFitToWidth(nbpage) & setFitToWidth(nbpage) work partially\n- Bugfix:   (MB) Work item 5361 - Worksheet::setTitle() causes unwanted renaming\n- Bugfix:   (MB) Work item 5407 - Hyperlinks not working. Results in broken xlsx file.\n\n\n2007/12/24 (v1.5.5):\n- General:  (MB) Work item 4135 - Grouping Rows\n- General:  (MB) Work item 4427 - Semi-nightly builds\n- Feature:  (MB) Work item 3155 - Implement \"date\" datatype\n- Feature:  (MB) Work item 4150 - Date format not honored in CSV writer\n- Feature:  (MB) Work item 4199 - RichText and sharedStrings\n- Feature:  (MB) Work item 2346 - Implement more Excel calculation functions\n            -    Addition of DATE, DATEDIF, DATEVALUE, DAY, DAYS360\n- Feature:  (MBaker) Work item 2346 - Implement more Excel calculation functions\n            -    Addition of AVEDEV, HARMEAN and GEOMEAN\n            -    Addition of the BINOMDIST (Non-cumulative only), COUNTBLANK, EXPONDIST, FISHER, FISHERINV, NORMDIST, NORMSDIST, PERMUT, POISSON (Non-cumulative only) and STANDARDIZE Statistical Functions\n            -    Addition of the CEILING, COMBIN, EVEN, FACT, FACTDOUBLE, FLOOR, MULTINOMIAL, ODD, ROUNDDOWN, ROUNDUP, SIGN, SQRTPI and SUMSQ Mathematical Functions\n            -    Addition of the NORMINV, NORMSINV, CONFIDENCE and SKEW Statistical Functions\n            -    Addition of the CRITBINOM, HYPGEOMDIST, KURT, LOGINV, LOGNORMDIST, NEGBINOMDIST and WEIBULL Statistical Functions\n            -    Addition of the LARGE, PERCENTILE, QUARTILE, SMALL and TRIMMEAN Statistical Functions\n            -    Addition of the BIN2HEX, BIN2OCT, DELTA, ERF, ERFC, GESTEP, HEX2BIN, HEX2DEC, HEX2OCT, OCT2BIN and OCT2HEX Engineering Functions\n            -    Addition of the CHIDIST, GAMMADIST and GAMMALN Statistical Functions\n            -    Addition of the GCD, LCM, MROUND and SUBTOTAL Mathematical Functions\n            -    Addition of the LOWER, PROPER and UPPER Text Functions\n            -    Addition of the BETADIST and BETAINV Statistical Functions\n            -    Addition of the CHIINV and GAMMAINV Statistical Functions\n            -    Addition of the SERIESSUM Mathematical Function\n            -    Addition of the CHAR, CODE, FIND, LEN, REPT, SEARCH, T, TRIM Text Functions\n            -    Addition of the FALSE and TRUE Boolean Functions\n            -    Addition of the TDIST and TINV Statistical Functions\n            -    Addition of the EDATE, EOMONTH, YEAR, MONTH, TIME, TIMEVALUE, HOUR, MINUTE, SECOND, WEEKDAY, WEEKNUM, NOW, TODAY and Date/Time Function\n            -    Addition of the BESSELI, BESSELJ, BESSELK and BESSELY Engineering Functions\n            -    Addition of the SLN and SYD Financial Functions\n            -    reworked MODE calculation to handle floating point numbers\n            -    Improved error trapping for invalid input values\n            -    Fix to SMALL, LARGE, PERCENTILE and TRIMMEAN to eliminate non-numeric values\n            -    Added CDF to BINOMDIST and POISSON\n            -    Fix to a potential endless loop in CRITBINOM, together with other bugfixes to the algorithm\n            -    Fix to SQRTPI so that it will work with a real value parameter rather than just integers\n            -    Trap for passing negative values to FACT\n            -    Improved accuracy of the NORMDIST cumulative function, and of the ERF and ERFC functions\n            -    Replicated Excel data-type and error handling for BIN, DEC, OCT and HEX conversion functions\n            -    Replicated Excel data-type and error handling for AND and OR Boolean functions\n            -    Bugfix to MROUND\n            -    Rework of the DATE, DATEVALUE, DAY, DAYS360 and DATEDIF date/Time functions to use Excel dates rather than straight PHP dates\n            -    Rework of the AND, OR Boolean functions to ignore string values\n            -    Rework of the BIN2DEC, BIN2HEX, BIN2OCT, DEC2BIN, DEC2HEX, DEC2OCT Engineering functions to handle two's complement\n            -    Excel, Gnumeric and OpenOffice Calc compatibility flag for functions\n                 Note, not all functions have yet been written to work with the Gnumeric and OpenOffice Calc compatibility flags\n            -    1900 or 1904 Calendar flag for date functions\n            -    Reworked ExcelToPHP date method to handle the Excel 1900 leap year\n                 Note that this will not correctly return values prior to 13-Dec-1901 20:45:52 as this is the minimum value that PHP date serial values can handle. If you need to work with dates prior to this, then an ExcelToPHPObject method has been added which will work correctly with values between Excel's 1900 calendar base date of 1-Jan-1900, and 13-Dec-1901\n            -    Addition of ExcelToPHPObject date method to return a PHP DateTime object from an Excel date serial value\n            -    PHPToExcel method modified to accept either PHP date serial numbers or PHP DateTime objects\n            -    Addition of FormattedPHPToExcel which will accept a date and time broken to into year, month, day, hour, minute, second and return an Excel date serial value\n- Feature:  (MB) Work item 4485 - Control characters in Excel 2007\n- Feature:  (MB) Work item 4796 - BaseDrawing::setWidthAndHeight method request\n- Feature:  (MB) Work item 4798 - Page Setup -> Print Titles -> Sheet -> 'Rows to repeat at top'\n- Feature:  (MB) Work item 4433 - Comment functionality\n- Bugfix:   (MB) Work item 4124 - Undefined variable in PHPExcel_Writer_Serialized\n- Bugfix:   (MB) Work item 4125 - Notice: Object of class PHPExcel_RichText could not be converted to int\n- Bugfix:   (MB) Work item 4126 - Excel5Writer: utf8 string not converted to utf16\n- Bugfix:   (MB) Work item 4180 - PHPExcel_RichText and autosize\n- Bugfix:   (MB) Work item 4574 - Excel5Writer produces broken xls files after change mentioned in work item 4126\n- Bugfix:   (MB) Work item 4797 - Small bug in PHPExcel_Reader_Excel2007 function _readStyle\n\n\n2007/10/23 (v 1.5.0):\n- General:  (MB) Work item 3265 - Refactor PHPExcel Drawing\n- Feature:  (CS) Work item 3079 - Update Shared/OLE.php to latest version from PEAR\n- Feature:  (MB) Work item 3217 - Excel2007 vs Excel2003 compatibility pack\n- Feature:  (MB) Work item 3234 - Cell protection (lock/unlock)\n- Feature:  (MB) Work item 3543 - Create clickable links (hyperlinks)\n- Feature:  (MB) Work item 3241 - Additional page setup parameters\n- Feature:  (MB) Work item 3300 - Make temporary file path configurable (Excel5)\n- Feature:  (MB) Work item 3306 - Small addition to applyFromArray for font\n- Feature:  (MB) Work item 3373 - Better feedback when save of file is not possible\n- Bugfix:   (MB) Work item 3181 - Text Rotation\n- Bugfix:   (MB) Work item 3237 - Small bug in Page Orientation\n- Bugfix:   (MB) Work item 3812 - insertNewColumnBeforeByColumn undefined\n- Bugfix:   (MB) Work item 3893 - Sheet references not working in formula (Excel5 Writer)\n\n\n2007/08/23 (v 1.4.5):\n- General:  (MB) Work item 3003 - Class file endings\n- General:  (MB) Work item 3081 - Different calculation engine improvements\n- General:  (MB) Work item 3082 - Different improvements in PHPExcel_Reader_Excel2007\n- General:  (MB) Work item 3146 - Set XML indentation in PHPExcel_Writer_Excel2007\n- Feature:  (MB) Work item 3159 -  Optionally store temporary Excel2007 writer data in file instead of memory\n- Feature:  (MB) Work item 3063 - Implement show/hide gridlines\n- Feature:  (MB) Work item 3064 - Implement option to read only data\n- Feature:  (MB) Work item 3080 - Optionally disable formula precalculation\n- Feature:  (MB) Work item 3154 - Explicitly set cell datatype\n- Feature:  (MBaker) Work item 2346 - Implement more Excel calculation functions\n             -    Addition of MINA, MAXA, COUNTA, AVERAGEA, MEDIAN, MODE, DEVSQ, STDEV, STDEVA, STDEVP, STDEVPA, VAR, VARA, VARP and VARPA Excel Functions\n             -    Fix to SUM, PRODUCT, QUOTIENT, MIN, MAX, COUNT and AVERAGE functions when cell contains a numeric value in a string datatype, bringing it in line with MS Excel behaviour\n- Bugfix:   (MB) Work item 2881 - File_exists on ZIP fails on some installations\n- Bugfix:   (MB) Work item 2879 - Argument in textRotation should be -90..90\n- Bugfix:   (MB) Work item 2883 - Excel2007 reader/writer not implementing OpenXML/SpreadsheetML styles 100% correct\n- Bugfix:   (MB) Work item 2513 - Active sheet index not read/saved\n- Bugfix:   (MB) Work item 2935 - Print and print preview of generated XLSX causes Excel2007 to crash\n- Bugfix:   (MB) Work item 2952 - Error in Calculations - COUNT() function\n- Bugfix:   (MB) Work item 3002 - HTML and CSV writer not writing last row\n- Bugfix:   (MB) Work item 3017 - Memory leak in Excel5 writer\n- Bugfix:   (MB) Work item 3044 - Printing (PHPExcel_Writer_Excel5)\n- Bugfix:   (MB) Work item 3046 - Problems reading zip://\n- Bugfix:   (MB) Work item 3047 - Error reading conditional formatting\n- Bugfix:   (MB) Work item 3067 - Bug in Excel5 writer (storePanes)\n- Bugfix:   (MB) Work item 3077 - Memory leak in PHPExcel_Style_Color\n\n\n2007/07/23 (v 1.4.0):\n- General:  (MB) Work item 2687 - Coding convention / code cleanup\n- General:  (MB) Work item 2717 - Use set_include_path in tests\n- General:  (MB) Work item 2812 - Move PHPExcel_Writer_Excel5 OLE to PHPExcel_Shared_OLE\n- Feature:  (MB) Work item 2679 - Hide/Unhide Column or Row\n- Feature:  (MB) Work item 2271 - Implement multi-cell styling\n- Feature:  (MB) Work item 2720 - Implement CSV file format (reader/writer)\n- Feature:  (MB) Work item 2845 - Implement HTML file format\n- Bugfix:   (MB) Work item 2513 - Active sheet index not read/saved\n- Bugfix:   (MB) Work item 2678 - Freeze Panes with PHPExcel_Writer_Excel5\n- Bugfix:   (MB) Work item 2680 - OLE.php\n- Bugfix:   (MB) Work item 2736 - Copy and pasting multiple drop-down list cells breaks reader\n- Bugfix:   (MB) Work item 2775 - Function setAutoFilterByColumnAndRow takes wrong arguments\n- Bugfix:   (MB) Work item 2858 - Simplexml_load_file fails on ZipArchive\n\n\n2007/06/27 (v 1.3.5):\n- General:  (MB) Work item 15   - Documentation\n- Feature:  (JV) PHPExcel_Writer_Excel5\n- Feature:  (JV) PHPExcel_Reader_Excel2007: Image shadows\n- Feature:  (MB) Work item 2385 - Data validation\n- Feature:  (MB) Work item  187 - Implement richtext strings\n- Bugfix:   (MB) Work item 2443 - Empty relations when adding image to any sheet but the first one\n- Bugfix:   (MB) Work item 2536 - Excel2007 crashes on print preview\n\n\n2007/06/05 (v 1.3.0):\n- General:  (MB) Work item 1942 - Create PEAR package\n- General:  (MB) Work item 2331 - Replace *->duplicate() by __clone()\n- Feature:  (JV) PHPExcel_Reader_Excel2007: Column auto-size, Protection, Merged cells, Wrap text, Page breaks, Auto filter, Images\n- Feature:  (MB) Work item 245  - Implement \"freezing\" panes\n- Feature:  (MB) Work item 2273 - Cell addressing alternative\n- Feature:  (MB) Work item 2270 - Implement cell word-wrap attribute\n- Feature:  (MB) Work item 2282 - Auto-size column\n- Feature:  (MB) Work item 241  - Implement formula calculation\n- Feature:  (MB) Work item 2375 - Insert/remove row/column\n- Bugfix:   (MB) Work item 1931 - PHPExcel_Worksheet::getCell() should not accept absolute coordinates\n- Bugfix:   (MB) Work item 2272 - Cell reference without row number\n- Bugfix:   (MB) Work item 2276 - Styles with same coordinate but different worksheet\n- Bugfix:   (MB) Work item 2290 - PHPExcel_Worksheet->getCellCollection() usort error\n- Bugfix:   (SS) Work item 2353 - Bug in PHPExcel_Cell::stringFromColumnIndex\n- Bugfix:   (JV) Work item 2353 - Reader: numFmts can be missing, use cellStyleXfs instead of cellXfs in styles\n\n\n2007/04/26 (v 1.2.0):\n- General:  (MB) Stringtable attribute \"count\" not necessary, provides wrong info to Excel sometimes...\n- General:  (MB) Updated tests to address more document properties\n- General:  (MB) Some refactoring in PHPExcel_Writer_Excel2007_Workbook\n- General:  (MB) New package: PHPExcel_Shared\n- General:  (MB) Password hashing algorithm implemented in PHPExcel_Shared_PasswordHasher\n- General:  (MB) Moved pixel conversion functions to PHPExcel_Shared_Drawing\n- General:  (MB) Work item 244 - Switch over to LGPL license\n- General:  (MB) Work item 5 - Include PHPExcel version in file headers\n- Feature:  (MB) Work item 6 - Autofilter\n- Feature:  (MB) Work item 7 - Extra document property: keywords\n- Feature:  (MB) Work item 8 - Extra document property: category\n- Feature:  (MB) Work item 9 - Document security\n- Feature:  (MB) Work item 10 - PHPExcel_Writer_Serialized and PHPExcel_Reader_Serialized\n- Feature:  (MB) Work item 11 - Alternative syntax: Addressing a cell\n- Feature:  (MB) Work item 12 - Merge cells\n- Feature:  (MB) Work item 13 - Protect ranges of cells with a password\n- Bugfix:   (JV) Work item 14 - (style/fill/patternFill/fgColor or bgColor can be empty)\n\n\n2007/03/26 (v 1.1.1):\n- Bugfix:   (MB) Work item 1250 - Syntax error in \"Classes/PHPExcel/Writer/Excel2007.php\" on line 243\n- General:  (MB) Work item 1282 - Reader should check if file exists and throws an exception when it doesn't\n\n\n2007/03/22 (v 1.1.0):\n- Changed filenames of tests\n- Bugfix:   (MB) Work item 836 - Style information lost after passing trough Excel2007_Reader\n- Bugfix:   (MB) Work item 913 - Number of columns > AZ fails fixed in PHPExcel_Cell::columnIndexFromString\n- General:  (MB) Added a brief file with installation instructions\n- Feature:  (MB) Page breaks (horizontal and vertical)\n- Feature:  (MB) Image shadows\n\n\n\n2007/02/22 (v 1.0.0):\n- Changelog now includes developer initials\n- Bugfix:   (JV) PHPExcel->removeSheetByIndex now re-orders sheets after deletion, so no array indexes are lost\n- Bugfix:   (JV) PHPExcel_Writer_Excel2007_Worksheet::_writeCols() used direct assignment to $pSheet->getColumnDimension('A')->Width instead of $pSheet->getColumnDimension('A')->setWidth()\n- Bugfix:   (JV) DocumentProperties used $this->LastModifiedBy instead of $this->_lastModifiedBy.\n- Bugfix:   (JV) Only first = should be removed when writing formula in PHPExcel_Writer_Excel2007_Worksheet.\n- General:  (JV) Consistency of method names to camelCase\n- General:  (JV) Updated tests to match consistency changes\n- General:  (JV) Detection of mime-types now with image_type_to_mime_type()\n- General:  (JV) Constants now hold string value used in Excel 2007\n- General:  (MB) Fixed folder name case (WorkSheet -> Worksheet)\n- Feature:  (MB) PHPExcel classes (not the Writer classes) can be duplicated, using a duplicate() method.\n- Feature:  (MB) Cell styles can now be duplicated to a range of cells using PHPExcel_Worksheet->duplicateStyle()\n- Feature:  (MB) Conditional formatting\n- Feature:  (JV) Reader for Excel 2007 (not supporting full specification yet!)\n\n\n\n2007/01/31 (v 1.0.0 RC):\n- Project name has been changed to PHPExcel\n- Project homepage is now http://www.codeplex.com/PHPExcel\n- Started versioning at number: PHPExcel 1.0.0 RC\n\n\n\n2007/01/22:\n- Fixed some performance issues on large-scale worksheets (mainly loops vs. indexed arrays)\n- Performance on creating StringTable has been increased\n- Performance on writing Excel2007 worksheet has been increased\n\n\n\n2007/01/18:\n- Images can now be rotated\n- Fixed bug: When drawings have full path specified, no mime type can be deducted\n- Fixed bug: Only one drawing can be added to a worksheet\n\n\n\n2007/01/12:\n- Refactoring of some classes to use ArrayObject instead of array()\n- Cell style now has support for number format (i.e. #,##0)\n- Implemented embedding images\n\n\n\n2007/01/02:\n- Cell style now has support for fills, including gradient fills\n- Cell style now has support for fonts\n- Cell style now has support for border colors\n- Cell style now has support for font colors\n- Cell style now has support for alignment\n\n\n\n2006/12/21:\n- Support for cell style borders\n- Support for cell styles\n- Refactoring of Excel2007 Writer into multiple classes in package SpreadSheet_Writer_Excel2007\n- Refactoring of all classes, changed public members to public properties using getter/setter\n- Worksheet names are now unique. On duplicate worksheet names, a number is appended.\n- Worksheet now has parent SpreadSheet object\n- Worksheet now has support for page header and footer\n- Worksheet now has support for page margins\n- Worksheet now has support for page setup (only Paper size and Orientation)\n- Worksheet properties now accessible by using getProperties()\n- Worksheet now has support for row and column dimensions (height / width)\n- Exceptions thrown have a more clear description\n\n\n\nInitial version:\n- Create a Spreadsheet object\n- Add one or more Worksheet objects\n- Add cells to Worksheet objects\n- Export Spreadsheet object to Excel 2007 OpenXML format\n- Each cell supports the following data formats: string, number, formula, boolean."
  },
  {
    "path": "vendor/phpoffice/phpexcel/composer.json",
    "content": "{\n    \"name\": \"phpoffice/phpexcel\",\n    \"description\": \"PHPExcel - OpenXML - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine\",\n    \"keywords\": [\"PHP\",\"Excel\",\"OpenXML\",\"xlsx\",\"xls\",\"spreadsheet\"],\n    \"homepage\": \"http://phpexcel.codeplex.com\",\n    \"type\": \"library\",\n    \"license\": \"LGPL\",\n    \"authors\": [\n        {\n            \"name\": \"Maarten Balliauw\",\n            \"homepage\": \"http://blog.maartenballiauw.be\"\n        },\n        {\n            \"name\": \"Mark Baker\"\n        },\n        {\n            \"name\": \"Franck Lefevre\",\n            \"homepage\": \"http://blog.rootslabs.net\"\n        },\n        {\n            \"name\": \"Erik Tilt\"\n        }\n    ],\n    \"require\": {\n        \"php\": \">=5.2.0\",\n        \"ext-xml\": \"*\",\n        \"ext-xmlwriter\": \"*\"\n    },\n    \"recommend\": {\n        \"ext-zip\": \"*\",\n        \"ext-gd2\": \"*\"\n    },\n    \"autoload\": {\n        \"psr-0\": {\n            \"PHPExcel\": \"Classes/\"\n        }\n    }\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/install.txt",
    "content": "**************************************************************************************\n* PHPExcel\n*\n* Copyright (c) 2006 - 2011 PHPExcel\n*\n* This library is free software; you can redistribute it and/or\n* modify it under the terms of the GNU Lesser General Public\n* License as published by the Free Software Foundation; either\n* version 2.1 of the License, or (at your option) any later version.\n*\n* This library is distributed in the hope that it will be useful,\n* but WITHOUT ANY WARRANTY; without even the implied warranty of\n* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n* Lesser General Public License for more details.\n*\n* You should have received a copy of the GNU Lesser General Public\n* License along with this library; if not, write to the Free Software\n* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA\n*\n* @copyright  Copyright (c) 2006 - 2013 PHPExcel (http://www.codeplex.com/PHPExcel)\n* @license    http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt\tLGPL\n* @version    ##VERSION##, ##DATE##\n**************************************************************************************\n\nRequirements\n------------\n\nThe following requirements should be met prior to using PHPExcel:\n* PHP version 5.2.0 or higher\n* PHP extension php_zip enabled *)\n* PHP extension php_xml enabled\n* PHP extension php_gd2 enabled (if not compiled in)\n\n*) php_zip is only needed by PHPExcel_Reader_Excel2007, PHPExcel_Writer_Excel2007,\n   PHPExcel_Reader_OOCalc. In other words, if you need PHPExcel to handle .xlsx or .ods\n   files you will need the zip extension, but otherwise not.\n\n\n\nInstallation instructions\n-------------------------\n\nInstallation is quite easy: copy the contents of the Classes folder to any location\nin your application required.\n\nExample:\n\nIf your web root folder is /var/www/ you may want to create a subfolder called\n/var/www/Classes/ and copy the files into that folder so you end up with files:\n\n/var/www/Classes/PHPExcel.php\n/var/www/Classes/PHPExcel/Calculation.php\n/var/www/Classes/PHPExcel/Cell.php\n...\n\n\n\nGetting started\n---------------\n\nA good way to get started is to run some of the tests included in the download.\nCopy the \"Examples\" folder next to your \"Classes\" folder from above so you end up with:\n\n/var/www/Examples/01simple.php\n/var/www/Examples/02types.php\n...\n\nStart running the test by pointing your browser to the test scripts:\n\nhttp://example.com/Examples/01simple.php\nhttp://example.com/Examples/02types.php\n...\n\nNote: It may be necessary to modify the include/require statements at the beginning of\neach of the test scripts if your \"Classes\" folder from above is named differently.\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/license.md",
    "content": "GNU LESSER GENERAL PUBLIC LICENSE\n\n   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n  0. This License Agreement applies to any software library or other\nprogram which contains a notice placed by the copyright holder or\nother authorized party saying it may be distributed under the terms of\nthis Lesser General Public License (also called \"this License\").\nEach licensee is addressed as \"you\".\n\n  A \"library\" means a collection of software functions and/or data\nprepared so as to be conveniently linked with application programs\n(which use some of those functions and data) to form executables.\n\n  The \"Library\", below, refers to any such software library or work\nwhich has been distributed under these terms.  A \"work based on the\nLibrary\" means either the Library or any derivative work under\ncopyright law: that is to say, a work containing the Library or a\nportion of it, either verbatim or with modifications and/or translated\nstraightforwardly into another language.  (Hereinafter, translation is\nincluded without limitation in the term \"modification\".)\n\n  \"Source code\" for a work means the preferred form of the work for\nmaking modifications to it.  For a library, complete source code means\nall the source code for all modules it contains, plus any associated\ninterface definition files, plus the scripts used to control compilation\nand installation of the library.\n\n  Activities other than copying, distribution and modification are not\ncovered by this License; they are outside its scope.  The act of\nrunning a program using the Library is not restricted, and output from\nsuch a program is covered only if its contents constitute a work based\non the Library (independent of the use of the Library in a tool for\nwriting it).  Whether that is true depends on what the Library does\nand what the program that uses the Library does.\n  \n  1. You may copy and distribute verbatim copies of the Library's\ncomplete source code as you receive it, in any medium, provided that\nyou conspicuously and appropriately publish on each copy an\nappropriate copyright notice and disclaimer of warranty; keep intact\nall the notices that refer to this License and to the absence of any\nwarranty; and distribute a copy of this License along with the\nLibrary.\n\n  You may charge a fee for the physical act of transferring a copy,\nand you may at your option offer warranty protection in exchange for a\nfee.\n\n  2. You may modify your copy or copies of the Library or any portion\nof it, thus forming a work based on the Library, and copy and\ndistribute such modifications or work under the terms of Section 1\nabove, provided that you also meet all of these conditions:\n\n    a) The modified work must itself be a software library.\n\n    b) You must cause the files modified to carry prominent notices\n    stating that you changed the files and the date of any change.\n\n    c) You must cause the whole of the work to be licensed at no\n    charge to all third parties under the terms of this License.\n\n    d) If a facility in the modified Library refers to a function or a\n    table of data to be supplied by an application program that uses\n    the facility, other than as an argument passed when the facility\n    is invoked, then you must make a good faith effort to ensure that,\n    in the event an application does not supply such function or\n    table, the facility still operates, and performs whatever part of\n    its purpose remains meaningful.\n\n    (For example, a function in a library to compute square roots has\n    a purpose that is entirely well-defined independent of the\n    application.  Therefore, Subsection 2d requires that any\n    application-supplied function or table used by this function must\n    be optional: if the application does not supply it, the square\n    root function must still compute square roots.)\n\nThese requirements apply to the modified work as a whole.  If\nidentifiable sections of that work are not derived from the Library,\nand can be reasonably considered independent and separate works in\nthemselves, then this License, and its terms, do not apply to those\nsections when you distribute them as separate works.  But when you\ndistribute the same sections as part of a whole which is a work based\non the Library, the distribution of the whole must be on the terms of\nthis License, whose permissions for other licensees extend to the\nentire whole, and thus to each and every part regardless of who wrote\nit.\n\nThus, it is not the intent of this section to claim rights or contest\nyour rights to work written entirely by you; rather, the intent is to\nexercise the right to control the distribution of derivative or\ncollective works based on the Library.\n\nIn addition, mere aggregation of another work not based on the Library\nwith the Library (or with a work based on the Library) on a volume of\na storage or distribution medium does not bring the other work under\nthe scope of this License.\n\n  3. You may opt to apply the terms of the ordinary GNU General Public\nLicense instead of this License to a given copy of the Library.  To do\nthis, you must alter all the notices that refer to this License, so\nthat they refer to the ordinary GNU General Public License, version 2,\ninstead of to this License.  (If a newer version than version 2 of the\nordinary GNU General Public License has appeared, then you can specify\nthat version instead if you wish.)  Do not make any other change in\nthese notices.\n\n  Once this change is made in a given copy, it is irreversible for\nthat copy, so the ordinary GNU General Public License applies to all\nsubsequent copies and derivative works made from that copy.\n\n  This option is useful when you wish to copy part of the code of\nthe Library into a program that is not a library.\n\n  4. You may copy and distribute the Library (or a portion or\nderivative of it, under Section 2) in object code or executable form\nunder the terms of Sections 1 and 2 above provided that you accompany\nit with the complete corresponding machine-readable source code, which\nmust be distributed under the terms of Sections 1 and 2 above on a\nmedium customarily used for software interchange.\n\n  If distribution of object code is made by offering access to copy\nfrom a designated place, then offering equivalent access to copy the\nsource code from the same place satisfies the requirement to\ndistribute the source code, even though third parties are not\ncompelled to copy the source along with the object code.\n\n  5. A program that contains no derivative of any portion of the\nLibrary, but is designed to work with the Library by being compiled or\nlinked with it, is called a \"work that uses the Library\".  Such a\nwork, in isolation, is not a derivative work of the Library, and\ntherefore falls outside the scope of this License.\n\n  However, linking a \"work that uses the Library\" with the Library\ncreates an executable that is a derivative of the Library (because it\ncontains portions of the Library), rather than a \"work that uses the\nlibrary\".  The executable is therefore covered by this License.\nSection 6 states terms for distribution of such executables.\n\n  When a \"work that uses the Library\" uses material from a header file\nthat is part of the Library, the object code for the work may be a\nderivative work of the Library even though the source code is not.\nWhether this is true is especially significant if the work can be\nlinked without the Library, or if the work is itself a library.  The\nthreshold for this to be true is not precisely defined by law.\n\n  If such an object file uses only numerical parameters, data\nstructure layouts and accessors, and small macros and small inline\nfunctions (ten lines or less in length), then the use of the object\nfile is unrestricted, regardless of whether it is legally a derivative\nwork.  (Executables containing this object code plus portions of the\nLibrary will still fall under Section 6.)\n\n  Otherwise, if the work is a derivative of the Library, you may\ndistribute the object code for the work under the terms of Section 6.\nAny executables containing that work also fall under Section 6,\nwhether or not they are linked directly with the Library itself.\n\n  6. As an exception to the Sections above, you may also combine or\nlink a \"work that uses the Library\" with the Library to produce a\nwork containing portions of the Library, and distribute that work\nunder terms of your choice, provided that the terms permit\nmodification of the work for the customer's own use and reverse\nengineering for debugging such modifications.\n\n  You must give prominent notice with each copy of the work that the\nLibrary is used in it and that the Library and its use are covered by\nthis License.  You must supply a copy of this License.  If the work\nduring execution displays copyright notices, you must include the\ncopyright notice for the Library among them, as well as a reference\ndirecting the user to the copy of this License.  Also, you must do one\nof these things:\n\n    a) Accompany the work with the complete corresponding\n    machine-readable source code for the Library including whatever\n    changes were used in the work (which must be distributed under\n    Sections 1 and 2 above); and, if the work is an executable linked\n    with the Library, with the complete machine-readable \"work that\n    uses the Library\", as object code and/or source code, so that the\n    user can modify the Library and then relink to produce a modified\n    executable containing the modified Library.  (It is understood\n    that the user who changes the contents of definitions files in the\n    Library will not necessarily be able to recompile the application\n    to use the modified definitions.)\n\n    b) Use a suitable shared library mechanism for linking with the\n    Library.  A suitable mechanism is one that (1) uses at run time a\n    copy of the library already present on the user's computer system,\n    rather than copying library functions into the executable, and (2)\n    will operate properly with a modified version of the library, if\n    the user installs one, as long as the modified version is\n    interface-compatible with the version that the work was made with.\n\n    c) Accompany the work with a written offer, valid for at\n    least three years, to give the same user the materials\n    specified in Subsection 6a, above, for a charge no more\n    than the cost of performing this distribution.\n\n    d) If distribution of the work is made by offering access to copy\n    from a designated place, offer equivalent access to copy the above\n    specified materials from the same place.\n\n    e) Verify that the user has already received a copy of these\n    materials or that you have already sent this user a copy.\n\n  For an executable, the required form of the \"work that uses the\nLibrary\" must include any data and utility programs needed for\nreproducing the executable from it.  However, as a special exception,\nthe materials to be distributed need not include anything that is\nnormally distributed (in either source or binary form) with the major\ncomponents (compiler, kernel, and so on) of the operating system on\nwhich the executable runs, unless that component itself accompanies\nthe executable.\n\n  It may happen that this requirement contradicts the license\nrestrictions of other proprietary libraries that do not normally\naccompany the operating system.  Such a contradiction means you cannot\nuse both them and the Library together in an executable that you\ndistribute.\n\n  7. You may place library facilities that are a work based on the\nLibrary side-by-side in a single library together with other library\nfacilities not covered by this License, and distribute such a combined\nlibrary, provided that the separate distribution of the work based on\nthe Library and of the other library facilities is otherwise\npermitted, and provided that you do these two things:\n\n    a) Accompany the combined library with a copy of the same work\n    based on the Library, uncombined with any other library\n    facilities.  This must be distributed under the terms of the\n    Sections above.\n\n    b) Give prominent notice with the combined library of the fact\n    that part of it is a work based on the Library, and explaining\n    where to find the accompanying uncombined form of the same work.\n\n  8. You may not copy, modify, sublicense, link with, or distribute\nthe Library except as expressly provided under this License.  Any\nattempt otherwise to copy, modify, sublicense, link with, or\ndistribute the Library is void, and will automatically terminate your\nrights under this License.  However, parties who have received copies,\nor rights, from you under this License will not have their licenses\nterminated so long as such parties remain in full compliance.\n\n  9. You are not required to accept this License, since you have not\nsigned it.  However, nothing else grants you permission to modify or\ndistribute the Library or its derivative works.  These actions are\nprohibited by law if you do not accept this License.  Therefore, by\nmodifying or distributing the Library (or any work based on the\nLibrary), you indicate your acceptance of this License to do so, and\nall its terms and conditions for copying, distributing or modifying\nthe Library or works based on it.\n\n  10. Each time you redistribute the Library (or any work based on the\nLibrary), the recipient automatically receives a license from the\noriginal licensor to copy, distribute, link with or modify the Library\nsubject to these terms and conditions.  You may not impose any further\nrestrictions on the recipients' exercise of the rights granted herein.\nYou are not responsible for enforcing compliance by third parties with\nthis License.\n\n  11. If, as a consequence of a court judgment or allegation of patent\ninfringement or for any other reason (not limited to patent issues),\nconditions are imposed on you (whether by court order, agreement or\notherwise) that contradict the conditions of this License, they do not\nexcuse you from the conditions of this License.  If you cannot\ndistribute so as to satisfy simultaneously your obligations under this\nLicense and any other pertinent obligations, then as a consequence you\nmay not distribute the Library at all.  For example, if a patent\nlicense would not permit royalty-free redistribution of the Library by\nall those who receive copies directly or indirectly through you, then\nthe only way you could satisfy both it and this License would be to\nrefrain entirely from distribution of the Library.\n\nIf any portion of this section is held invalid or unenforceable under any\nparticular circumstance, the balance of the section is intended to apply,\nand the section as a whole is intended to apply in other circumstances.\n\nIt is not the purpose of this section to induce you to infringe any\npatents or other property right claims or to contest validity of any\nsuch claims; this section has the sole purpose of protecting the\nintegrity of the free software distribution system which is\nimplemented by public license practices.  Many people have made\ngenerous contributions to the wide range of software distributed\nthrough that system in reliance on consistent application of that\nsystem; it is up to the author/donor to decide if he or she is willing\nto distribute software through any other system and a licensee cannot\nimpose that choice.\n\nThis section is intended to make thoroughly clear what is believed to\nbe a consequence of the rest of this License.\n\n  12. If the distribution and/or use of the Library is restricted in\ncertain countries either by patents or by copyrighted interfaces, the\noriginal copyright holder who places the Library under this License may add\nan explicit geographical distribution limitation excluding those countries,\nso that distribution is permitted only in or among countries not thus\nexcluded.  In such case, this License incorporates the limitation as if\nwritten in the body of this License.\n\n  13. The Free Software Foundation may publish revised and/or new\nversions of the Lesser General Public License from time to time.\nSuch new versions will be similar in spirit to the present version,\nbut may differ in detail to address new problems or concerns.\n\nEach version is given a distinguishing version number.  If the Library\nspecifies a version number of this License which applies to it and\n\"any later version\", you have the option of following the terms and\nconditions either of that version or of any later version published by\nthe Free Software Foundation.  If the Library does not specify a\nlicense version number, you may choose any version ever published by\nthe Free Software Foundation.\n\n  14. If you wish to incorporate parts of the Library into other free\nprograms whose distribution conditions are incompatible with these,\nwrite to the author to ask for permission.  For software which is\ncopyrighted by the Free Software Foundation, write to the Free\nSoftware Foundation; we sometimes make exceptions for this.  Our\ndecision will be guided by the two goals of preserving the free status\nof all derivatives of our free software and of promoting the sharing\nand reuse of software generally.\n\nNO WARRANTY\n\n  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO\nWARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\nEXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\nOTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY\nKIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE\nIMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\nPURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\nLIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME\nTHE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\nWRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\nAND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU\nFOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR\nCONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\nLIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\nRENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\nFAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF\nSUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\nDAMAGES.\n\nEND OF TERMS AND CONDITIONS"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/AutoloaderTest.php",
    "content": "<?php\n\n\nclass AutoloaderTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n    }\n\n    public function testAutoloaderNonPHPExcelClass()\n    {\n        $className = 'InvalidClass';\n\n        $result = PHPExcel_Autoloader::Load($className);\n        //    Must return a boolean...\n        $this->assertTrue(is_bool($result));\n        //    ... indicating failure\n        $this->assertFalse($result);\n    }\n\n    public function testAutoloaderInvalidPHPExcelClass()\n    {\n        $className = 'PHPExcel_Invalid_Class';\n\n        $result = PHPExcel_Autoloader::Load($className);\n        //    Must return a boolean...\n        $this->assertTrue(is_bool($result));\n        //    ... indicating failure\n        $this->assertFalse($result);\n    }\n\n    public function testAutoloadValidPHPExcelClass()\n    {\n        $className = 'PHPExcel_IOFactory';\n\n        $result = PHPExcel_Autoloader::Load($className);\n        //    Check that class has been loaded\n        $this->assertTrue(class_exists($className));\n    }\n\n    public function testAutoloadInstantiateSuccess()\n    {\n        $result = new PHPExcel_Calculation_Function(1,2,3);\n        //    Must return an object...\n        $this->assertTrue(is_object($result));\n        //    ... of the correct type\n        $this->assertTrue(is_a($result,'PHPExcel_Calculation_Function'));\n    }\n\n}"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Calculation/DateTimeTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass DateTimeTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\n        PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL);\n\t}\n\n    /**\n     * @dataProvider providerDATE\n     */\n\tpublic function testDATE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerDATE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/DATE.data');\n\t}\n\n\tpublic function testDATEtoPHP()\n\t{\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC);\n\t\t$result = PHPExcel_Calculation_DateTime::DATE(2012,1,31);\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n\t\t$this->assertEquals(1327968000, $result, NULL, 1E-8);\n\t}\n\n\tpublic function testDATEtoPHPObject()\n\t{\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT);\n\t\t$result = PHPExcel_Calculation_DateTime::DATE(2012,1,31);\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n        //    Must return an object...\n        $this->assertTrue(is_object($result));\n        //    ... of the correct type\n        $this->assertTrue(is_a($result,'DateTime'));\n        //    ... with the correct value\n        $this->assertEquals($result->format('d-M-Y'),'31-Jan-2012');\n\t}\n\n\tpublic function testDATEwith1904Calendar()\n\t{\n\t\tPHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904);\n\t\t$result = PHPExcel_Calculation_DateTime::DATE(1918,11,11);\n\t\tPHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900);\n        $this->assertEquals($result,5428);\n\t}\n\n\tpublic function testDATEwith1904CalendarError()\n\t{\n\t\tPHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_MAC_1904);\n\t\t$result = PHPExcel_Calculation_DateTime::DATE(1901,1,31);\n\t\tPHPExcel_Shared_Date::setExcelCalendar(PHPExcel_Shared_Date::CALENDAR_WINDOWS_1900);\n        $this->assertEquals($result,'#NUM!');\n\t}\n\n    /**\n     * @dataProvider providerDATEVALUE\n     */\n\tpublic function testDATEVALUE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEVALUE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerDATEVALUE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/DATEVALUE.data');\n\t}\n\n\tpublic function testDATEVALUEtoPHP()\n\t{\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC);\n\t\t$result = PHPExcel_Calculation_DateTime::DATEVALUE('2012-1-31');\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n\t\t$this->assertEquals(1327968000, $result, NULL, 1E-8);\n\t}\n\n\tpublic function testDATEVALUEtoPHPObject()\n\t{\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT);\n\t\t$result = PHPExcel_Calculation_DateTime::DATEVALUE('2012-1-31');\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n        //    Must return an object...\n        $this->assertTrue(is_object($result));\n        //    ... of the correct type\n        $this->assertTrue(is_a($result,'DateTime'));\n        //    ... with the correct value\n        $this->assertEquals($result->format('d-M-Y'),'31-Jan-2012');\n\t}\n\n    /**\n     * @dataProvider providerYEAR\n     */\n\tpublic function testYEAR()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEAR'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerYEAR()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/YEAR.data');\n\t}\n\n    /**\n     * @dataProvider providerMONTH\n     */\n\tpublic function testMONTH()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MONTHOFYEAR'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerMONTH()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/MONTH.data');\n\t}\n\n    /**\n     * @dataProvider providerWEEKNUM\n     */\n\tpublic function testWEEKNUM()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WEEKOFYEAR'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerWEEKNUM()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/WEEKNUM.data');\n\t}\n\n    /**\n     * @dataProvider providerWEEKDAY\n     */\n\tpublic function testWEEKDAY()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFWEEK'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerWEEKDAY()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/WEEKDAY.data');\n\t}\n\n    /**\n     * @dataProvider providerDAY\n     */\n\tpublic function testDAY()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYOFMONTH'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerDAY()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/DAY.data');\n\t}\n\n    /**\n     * @dataProvider providerTIME\n     */\n\tpublic function testTIME()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIME'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerTIME()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/TIME.data');\n\t}\n\n\tpublic function testTIMEtoPHP()\n\t{\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC);\n\t\t$result = PHPExcel_Calculation_DateTime::TIME(7,30,20);\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n\t\t$this->assertEquals(27020, $result, NULL, 1E-8);\n\t}\n\n\tpublic function testTIMEtoPHPObject()\n\t{\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT);\n\t\t$result = PHPExcel_Calculation_DateTime::TIME(7,30,20);\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n        //    Must return an object...\n        $this->assertTrue(is_object($result));\n        //    ... of the correct type\n        $this->assertTrue(is_a($result,'DateTime'));\n        //    ... with the correct value\n        $this->assertEquals($result->format('H:i:s'),'07:30:20');\n\t}\n\n    /**\n     * @dataProvider providerTIMEVALUE\n     */\n\tpublic function testTIMEVALUE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','TIMEVALUE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerTIMEVALUE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/TIMEVALUE.data');\n\t}\n\n\tpublic function testTIMEVALUEtoPHP()\n\t{\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC);\n\t\t$result = PHPExcel_Calculation_DateTime::TIMEVALUE('7:30:20');\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n\t\t$this->assertEquals(23420, $result, NULL, 1E-8);\n\t}\n\n\tpublic function testTIMEVALUEtoPHPObject()\n\t{\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT);\n\t\t$result = PHPExcel_Calculation_DateTime::TIMEVALUE('7:30:20');\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n        //    Must return an object...\n        $this->assertTrue(is_object($result));\n        //    ... of the correct type\n        $this->assertTrue(is_a($result,'DateTime'));\n        //    ... with the correct value\n        $this->assertEquals($result->format('H:i:s'),'07:30:20');\n\t}\n\n    /**\n     * @dataProvider providerHOUR\n     */\n\tpublic function testHOUR()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','HOUROFDAY'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerHOUR()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/HOUR.data');\n\t}\n\n    /**\n     * @dataProvider providerMINUTE\n     */\n\tpublic function testMINUTE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','MINUTEOFHOUR'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerMINUTE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/MINUTE.data');\n\t}\n\n    /**\n     * @dataProvider providerSECOND\n     */\n\tpublic function testSECOND()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','SECONDOFMINUTE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerSECOND()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/SECOND.data');\n\t}\n\n    /**\n     * @dataProvider providerNETWORKDAYS\n     */\n\tpublic function testNETWORKDAYS()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','NETWORKDAYS'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerNETWORKDAYS()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/NETWORKDAYS.data');\n\t}\n\n    /**\n     * @dataProvider providerWORKDAY\n     */\n\tpublic function testWORKDAY()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','WORKDAY'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerWORKDAY()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/WORKDAY.data');\n\t}\n\n    /**\n     * @dataProvider providerEDATE\n     */\n\tpublic function testEDATE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EDATE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerEDATE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/EDATE.data');\n\t}\n\n\tpublic function testEDATEtoPHP()\n\t{\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC);\n\t\t$result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26',-1);\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n\t\t$this->assertEquals(1324857600, $result, NULL, 1E-8);\n\t}\n\n\tpublic function testEDATEtoPHPObject()\n\t{\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT);\n\t\t$result = PHPExcel_Calculation_DateTime::EDATE('2012-1-26',-1);\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n        //    Must return an object...\n        $this->assertTrue(is_object($result));\n        //    ... of the correct type\n        $this->assertTrue(is_a($result,'DateTime'));\n        //    ... with the correct value\n        $this->assertEquals($result->format('d-M-Y'),'26-Dec-2011');\n\t}\n\n    /**\n     * @dataProvider providerEOMONTH\n     */\n\tpublic function testEOMONTH()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','EOMONTH'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerEOMONTH()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/EOMONTH.data');\n\t}\n\n\tpublic function testEOMONTHtoPHP()\n\t{\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_NUMERIC);\n\t\t$result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26',-1);\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n\t\t$this->assertEquals(1325289600, $result, NULL, 1E-8);\n\t}\n\n\tpublic function testEOMONTHtoPHPObject()\n\t{\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_PHP_OBJECT);\n\t\t$result = PHPExcel_Calculation_DateTime::EOMONTH('2012-1-26',-1);\n\t\tPHPExcel_Calculation_Functions::setReturnDateType(PHPExcel_Calculation_Functions::RETURNDATE_EXCEL);\n        //    Must return an object...\n        $this->assertTrue(is_object($result));\n        //    ... of the correct type\n        $this->assertTrue(is_a($result,'DateTime'));\n        //    ... with the correct value\n        $this->assertEquals($result->format('d-M-Y'),'31-Dec-2011');\n\t}\n\n    /**\n     * @dataProvider providerDATEDIF\n     */\n\tpublic function testDATEDIF()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DATEDIF'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerDATEDIF()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/DATEDIF.data');\n\t}\n\n    /**\n     * @dataProvider providerDAYS360\n     */\n\tpublic function testDAYS360()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','DAYS360'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerDAYS360()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/DAYS360.data');\n\t}\n\n    /**\n     * @dataProvider providerYEARFRAC\n     */\n\tpublic function testYEARFRAC()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_DateTime','YEARFRAC'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerYEARFRAC()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/DateTime/YEARFRAC.data');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Calculation/EngineeringTest.php",
    "content": "<?php\n\n//  Custom assertion class for handling precision of Complex numbers\nrequire_once 'custom/complexAssert.php';\n\n//  Data Provider handler\nrequire_once 'testDataFileIterator.php';\n\n\nclass EngineeringTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\n        PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL);\n\t}\n\n    /**\n     * @dataProvider providerBESSELI\n     */\n\tpublic function testBESSELI()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELI'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerBESSELI()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELI.data');\n\t}\n\n    /**\n     * @dataProvider providerBESSELJ\n     */\n\tpublic function testBESSELJ()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELJ'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerBESSELJ()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELJ.data');\n\t}\n\n    /**\n     * @dataProvider providerBESSELK\n     */\n\tpublic function testBESSELK()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELK'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerBESSELK()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELK.data');\n\t}\n\n    /**\n     * @dataProvider providerBESSELY\n     */\n\tpublic function testBESSELY()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BESSELY'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerBESSELY()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/BESSELY.data');\n\t}\n\n    /**\n     * @dataProvider providerCOMPLEX\n     */\n\tpublic function testCOMPLEX()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','COMPLEX'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerCOMPLEX()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/COMPLEX.data');\n\t}\n\n    /**\n     * @dataProvider providerIMAGINARY\n     */\n\tpublic function testIMAGINARY()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMAGINARY'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIMAGINARY()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMAGINARY.data');\n\t}\n\n    /**\n     * @dataProvider providerIMREAL\n     */\n\tpublic function testIMREAL()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMREAL'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIMREAL()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMREAL.data');\n\t}\n\n    /**\n     * @dataProvider providerIMABS\n     */\n\tpublic function testIMABS()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMABS'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIMABS()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMABS.data');\n\t}\n\n    /**\n     * @dataProvider providerIMARGUMENT\n     */\n\tpublic function testIMARGUMENT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMARGUMENT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIMARGUMENT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMARGUMENT.data');\n\t}\n\n    /**\n     * @dataProvider providerIMCONJUGATE\n     */\n\tpublic function testIMCONJUGATE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCONJUGATE'),$args);\n\t\t$complexAssert = new complexAssert();\n\t\t$this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),\n\t\t\t\t\t\t  $complexAssert->getErrorMessage());\n\t}\n\n    public function providerIMCONJUGATE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMCONJUGATE.data');\n\t}\n\n    /**\n     * @dataProvider providerIMCOS\n     */\n\tpublic function testIMCOS()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMCOS'),$args);\n\t\t$complexAssert = new complexAssert();\n\t\t$this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),\n\t\t\t\t\t\t  $complexAssert->getErrorMessage());\n\t}\n\n    public function providerIMCOS()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMCOS.data');\n\t}\n\n    /**\n     * @dataProvider providerIMDIV\n     */\n\tpublic function testIMDIV()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMDIV'),$args);\n\t\t$complexAssert = new complexAssert();\n\t\t$this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),\n\t\t\t\t\t\t  $complexAssert->getErrorMessage());\n\t}\n\n    public function providerIMDIV()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMDIV.data');\n\t}\n\n    /**\n     * @dataProvider providerIMEXP\n     */\n\tpublic function testIMEXP()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMEXP'),$args);\n\t\t$complexAssert = new complexAssert();\n\t\t$this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),\n\t\t\t\t\t\t  $complexAssert->getErrorMessage());\n\t}\n\n    public function providerIMEXP()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMEXP.data');\n\t}\n\n    /**\n     * @dataProvider providerIMLN\n     */\n\tpublic function testIMLN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLN'),$args);\n\t\t$complexAssert = new complexAssert();\n\t\t$this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),\n\t\t\t\t\t\t  $complexAssert->getErrorMessage());\n\t}\n\n    public function providerIMLN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMLN.data');\n\t}\n\n    /**\n     * @dataProvider providerIMLOG2\n     */\n\tpublic function testIMLOG2()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG2'),$args);\n\t\t$complexAssert = new complexAssert();\n\t\t$this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),\n\t\t\t\t\t\t  $complexAssert->getErrorMessage());\n\t}\n\n    public function providerIMLOG2()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMLOG2.data');\n\t}\n\n    /**\n     * @dataProvider providerIMLOG10\n     */\n\tpublic function testIMLOG10()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMLOG10'),$args);\n\t\t$complexAssert = new complexAssert();\n\t\t$this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),\n\t\t\t\t\t\t  $complexAssert->getErrorMessage());\n\t}\n\n    public function providerIMLOG10()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMLOG10.data');\n\t}\n\n    /**\n     * @dataProvider providerIMPOWER\n     */\n\tpublic function testIMPOWER()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPOWER'),$args);\n\t\t$complexAssert = new complexAssert();\n\t\t$this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),\n\t\t\t\t\t\t  $complexAssert->getErrorMessage());\n\t}\n\n    public function providerIMPOWER()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMPOWER.data');\n\t}\n\n    /**\n     * @dataProvider providerIMPRODUCT\n     */\n\tpublic function testIMPRODUCT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMPRODUCT'),$args);\n\t\t$complexAssert = new complexAssert();\n\t\t$this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),\n\t\t\t\t\t\t  $complexAssert->getErrorMessage());\n\t}\n\n    public function providerIMPRODUCT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMPRODUCT.data');\n\t}\n\n    /**\n     * @dataProvider providerIMSIN\n     */\n\tpublic function testIMSIN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSIN'),$args);\n\t\t$complexAssert = new complexAssert();\n\t\t$this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),\n\t\t\t\t\t\t  $complexAssert->getErrorMessage());\n\t}\n\n    public function providerIMSIN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMSIN.data');\n\t}\n\n    /**\n     * @dataProvider providerIMSQRT\n     */\n\tpublic function testIMSQRT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSQRT'),$args);\n\t\t$complexAssert = new complexAssert();\n\t\t$this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),\n\t\t\t\t\t\t  $complexAssert->getErrorMessage());\n\t}\n\n    public function providerIMSQRT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMSQRT.data');\n\t}\n\n    /**\n     * @dataProvider providerIMSUB\n     */\n\tpublic function testIMSUB()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUB'),$args);\n\t\t$complexAssert = new complexAssert();\n\t\t$this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),\n\t\t\t\t\t\t  $complexAssert->getErrorMessage());\n\t}\n\n    public function providerIMSUB()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUB.data');\n\t}\n\n    /**\n     * @dataProvider providerIMSUM\n     */\n\tpublic function testIMSUM()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','IMSUM'),$args);\n\t\t$complexAssert = new complexAssert();\n\t\t$this->assertTrue($complexAssert->assertComplexEquals($expectedResult, $result, 1E-8),\n\t\t\t\t\t\t  $complexAssert->getErrorMessage());\n\t}\n\n    public function providerIMSUM()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/IMSUM.data');\n\t}\n\n    /**\n     * @dataProvider providerERF\n     */\n\tpublic function testERF()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERF'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerERF()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/ERF.data');\n\t}\n\n    /**\n     * @dataProvider providerERFC\n     */\n\tpublic function testERFC()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','ERFC'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerERFC()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/ERFC.data');\n\t}\n\n    /**\n     * @dataProvider providerBIN2DEC\n     */\n\tpublic function testBIN2DEC()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTODEC'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerBIN2DEC()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2DEC.data');\n\t}\n\n    /**\n     * @dataProvider providerBIN2HEX\n     */\n\tpublic function testBIN2HEX()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOHEX'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerBIN2HEX()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2HEX.data');\n\t}\n\n    /**\n     * @dataProvider providerBIN2OCT\n     */\n\tpublic function testBIN2OCT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','BINTOOCT'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerBIN2OCT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/BIN2OCT.data');\n\t}\n\n    /**\n     * @dataProvider providerDEC2BIN\n     */\n\tpublic function testDEC2BIN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOBIN'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL);\n\t}\n\n    public function providerDEC2BIN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2BIN.data');\n\t}\n\n    /**\n     * @dataProvider providerDEC2HEX\n     */\n\tpublic function testDEC2HEX()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOHEX'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL);\n\t}\n\n    public function providerDEC2HEX()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2HEX.data');\n\t}\n\n    /**\n     * @dataProvider providerDEC2OCT\n     */\n\tpublic function testDEC2OCT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DECTOOCT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL);\n\t}\n\n    public function providerDEC2OCT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/DEC2OCT.data');\n\t}\n\n    /**\n     * @dataProvider providerHEX2BIN\n     */\n\tpublic function testHEX2BIN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOBIN'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL);\n\t}\n\n    public function providerHEX2BIN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2BIN.data');\n\t}\n\n    /**\n     * @dataProvider providerHEX2DEC\n     */\n\tpublic function testHEX2DEC()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTODEC'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL);\n\t}\n\n    public function providerHEX2DEC()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2DEC.data');\n\t}\n\n    /**\n     * @dataProvider providerHEX2OCT\n     */\n\tpublic function testHEX2OCT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','HEXTOOCT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL);\n\t}\n\n    public function providerHEX2OCT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/HEX2OCT.data');\n\t}\n\n    /**\n     * @dataProvider providerOCT2BIN\n     */\n\tpublic function testOCT2BIN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOBIN'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL);\n\t}\n\n    public function providerOCT2BIN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2BIN.data');\n\t}\n\n    /**\n     * @dataProvider providerOCT2DEC\n     */\n\tpublic function testOCT2DEC()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTODEC'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL);\n\t}\n\n    public function providerOCT2DEC()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2DEC.data');\n\t}\n\n    /**\n     * @dataProvider providerOCT2HEX\n     */\n\tpublic function testOCT2HEX()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','OCTTOHEX'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL);\n\t}\n\n    public function providerOCT2HEX()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/OCT2HEX.data');\n\t}\n\n    /**\n     * @dataProvider providerDELTA\n     */\n\tpublic function testDELTA()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','DELTA'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL);\n\t}\n\n    public function providerDELTA()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/DELTA.data');\n\t}\n\n    /**\n     * @dataProvider providerGESTEP\n     */\n\tpublic function testGESTEP()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','GESTEP'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL);\n\t}\n\n    public function providerGESTEP()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/GESTEP.data');\n\t}\n\n\tpublic function testGetConversionGroups()\n\t{\n\t\t$result = PHPExcel_Calculation_Engineering::getConversionGroups();\n\t\t$this->assertInternalType('array', $result);\n\t}\n\n\tpublic function testGetConversionGroupUnits()\n\t{\n\t\t$result = PHPExcel_Calculation_Engineering::getConversionGroupUnits();\n\t\t$this->assertInternalType('array', $result);\n\t}\n\n\tpublic function testGetConversionGroupUnitDetails()\n\t{\n\t\t$result = PHPExcel_Calculation_Engineering::getConversionGroupUnitDetails();\n\t\t$this->assertInternalType('array', $result);\n\t}\n\n\tpublic function testGetConversionMultipliers()\n\t{\n\t\t$result = PHPExcel_Calculation_Engineering::getConversionMultipliers();\n\t\t$this->assertInternalType('array', $result);\n\t}\n\n    /**\n     * @dataProvider providerCONVERTUOM\n     */\n\tpublic function testCONVERTUOM()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Engineering','CONVERTUOM'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL);\n\t}\n\n    public function providerCONVERTUOM()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Engineering/CONVERTUOM.data');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Calculation/FinancialTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass FinancialTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\n        PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL);\n\t}\n\n    /**\n     * @dataProvider providerACCRINT\n     */\n\tpublic function testACCRINT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','ACCRINT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerACCRINT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/ACCRINT.data');\n\t}\n\n    /**\n     * @dataProvider providerACCRINTM\n     */\n\tpublic function testACCRINTM()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','ACCRINTM'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerACCRINTM()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/ACCRINTM.data');\n\t}\n\n    /**\n     * @dataProvider providerAMORDEGRC\n     */\n\tpublic function testAMORDEGRC()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORDEGRC'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerAMORDEGRC()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/AMORDEGRC.data');\n\t}\n\n    /**\n     * @dataProvider providerAMORLINC\n     */\n\tpublic function testAMORLINC()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','AMORLINC'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerAMORLINC()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/AMORLINC.data');\n\t}\n\n    /**\n     * @dataProvider providerCOUPDAYBS\n     */\n\tpublic function testCOUPDAYBS()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYBS'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerCOUPDAYBS()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYBS.data');\n\t}\n\n    /**\n     * @dataProvider providerCOUPDAYS\n     */\n\tpublic function testCOUPDAYS()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYS'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerCOUPDAYS()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYS.data');\n\t}\n\n    /**\n     * @dataProvider providerCOUPDAYSNC\n     */\n\tpublic function testCOUPDAYSNC()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPDAYSNC'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerCOUPDAYSNC()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/COUPDAYSNC.data');\n\t}\n\n    /**\n     * @dataProvider providerCOUPNCD\n     */\n\tpublic function testCOUPNCD()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNCD'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerCOUPNCD()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/COUPNCD.data');\n\t}\n\n    /**\n     * @dataProvider providerCOUPNUM\n     */\n\tpublic function testCOUPNUM()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPNUM'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerCOUPNUM()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/COUPNUM.data');\n\t}\n\n    /**\n     * @dataProvider providerCOUPPCD\n     */\n\tpublic function testCOUPPCD()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','COUPPCD'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerCOUPPCD()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/COUPPCD.data');\n\t}\n\n    /**\n     * @dataProvider providerCUMIPMT\n     */\n\tpublic function testCUMIPMT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMIPMT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerCUMIPMT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/CUMIPMT.data');\n\t}\n\n    /**\n     * @dataProvider providerCUMPRINC\n     */\n\tpublic function testCUMPRINC()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','CUMPRINC'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerCUMPRINC()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/CUMPRINC.data');\n\t}\n\n    /**\n     * @dataProvider providerDB\n     */\n\tpublic function testDB()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','DB'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerDB()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/DB.data');\n\t}\n\n    /**\n     * @dataProvider providerDDB\n     */\n\tpublic function testDDB()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','DDB'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerDDB()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/DDB.data');\n\t}\n\n    /**\n     * @dataProvider providerDISC\n     */\n\tpublic function testDISC()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','DISC'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerDISC()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/DISC.data');\n\t}\n\n    /**\n     * @dataProvider providerDOLLARDE\n     */\n\tpublic function testDOLLARDE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARDE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerDOLLARDE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/DOLLARDE.data');\n\t}\n\n    /**\n     * @dataProvider providerDOLLARFR\n     */\n\tpublic function testDOLLARFR()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','DOLLARFR'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerDOLLARFR()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/DOLLARFR.data');\n\t}\n\n    /**\n     * @dataProvider providerEFFECT\n     */\n\tpublic function testEFFECT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','EFFECT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerEFFECT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/EFFECT.data');\n\t}\n\n    /**\n     * @dataProvider providerFV\n     */\n\tpublic function testFV()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','FV'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerFV()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/FV.data');\n\t}\n\n    /**\n     * @dataProvider providerFVSCHEDULE\n     */\n\tpublic function testFVSCHEDULE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','FVSCHEDULE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerFVSCHEDULE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/FVSCHEDULE.data');\n\t}\n\n    /**\n     * @dataProvider providerINTRATE\n     */\n\tpublic function testINTRATE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','INTRATE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerINTRATE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/INTRATE.data');\n\t}\n\n    /**\n     * @dataProvider providerIPMT\n     */\n\tpublic function testIPMT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','IPMT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIPMT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/IPMT.data');\n\t}\n\n    /**\n     * @dataProvider providerIRR\n     */\n\tpublic function testIRR()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','IRR'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIRR()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/IRR.data');\n\t}\n\n    /**\n     * @dataProvider providerISPMT\n     */\n\tpublic function testISPMT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','ISPMT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerISPMT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/ISPMT.data');\n\t}\n\n    /**\n     * @dataProvider providerMIRR\n     */\n\tpublic function testMIRR()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','MIRR'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerMIRR()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/MIRR.data');\n\t}\n\n    /**\n     * @dataProvider providerNOMINAL\n     */\n\tpublic function testNOMINAL()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','NOMINAL'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerNOMINAL()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/NOMINAL.data');\n\t}\n\n    /**\n     * @dataProvider providerNPER\n     */\n\tpublic function testNPER()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPER'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerNPER()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/NPER.data');\n\t}\n\n    /**\n     * @dataProvider providerNPV\n     */\n\tpublic function testNPV()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','NPV'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerNPV()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/NPV.data');\n\t}\n\n    /**\n     * @dataProvider providerPRICE\n     */\n\tpublic function testPRICE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','PRICE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerPRICE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/PRICE.data');\n\t}\n\n    /**\n     * @dataProvider providerRATE\n     */\n\tpublic function testRATE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','RATE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerRATE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/RATE.data');\n\t}\n\n    /**\n     * @dataProvider providerXIRR\n     */\n\tpublic function testXIRR()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Financial','XIRR'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerXIRR()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Financial/XIRR.data');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Calculation/FunctionsTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass FunctionsTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\n        PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL);\n\t}\n\n\tpublic function testDUMMY()\n\t{\n\t\t$result = PHPExcel_Calculation_Functions::DUMMY();\n\t\t$this->assertEquals('#Not Yet Implemented', $result);\n\t}\n\n\tpublic function testDIV0()\n\t{\n\t\t$result = PHPExcel_Calculation_Functions::DIV0();\n\t\t$this->assertEquals('#DIV/0!', $result);\n\t}\n\n\tpublic function testNA()\n\t{\n\t\t$result = PHPExcel_Calculation_Functions::NA();\n\t\t$this->assertEquals('#N/A', $result);\n\t}\n\n\tpublic function testNaN()\n\t{\n\t\t$result = PHPExcel_Calculation_Functions::NaN();\n\t\t$this->assertEquals('#NUM!', $result);\n\t}\n\n\tpublic function testNAME()\n\t{\n\t\t$result = PHPExcel_Calculation_Functions::NAME();\n\t\t$this->assertEquals('#NAME?', $result);\n\t}\n\n\tpublic function testREF()\n\t{\n\t\t$result = PHPExcel_Calculation_Functions::REF();\n\t\t$this->assertEquals('#REF!', $result);\n\t}\n\n\tpublic function testNULL()\n\t{\n\t\t$result = PHPExcel_Calculation_Functions::NULL();\n\t\t$this->assertEquals('#NULL!', $result);\n\t}\n\n\tpublic function testVALUE()\n\t{\n\t\t$result = PHPExcel_Calculation_Functions::VALUE();\n\t\t$this->assertEquals('#VALUE!', $result);\n\t}\n\n    /**\n     * @dataProvider providerIS_BLANK\n     */\n\tpublic function testIS_BLANK()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_BLANK'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIS_BLANK()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Functions/IS_BLANK.data');\n\t}\n\n    /**\n     * @dataProvider providerIS_ERR\n     */\n\tpublic function testIS_ERR()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERR'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIS_ERR()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Functions/IS_ERR.data');\n\t}\n\n    /**\n     * @dataProvider providerIS_ERROR\n     */\n\tpublic function testIS_ERROR()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ERROR'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIS_ERROR()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Functions/IS_ERROR.data');\n\t}\n\n    /**\n     * @dataProvider providerERROR_TYPE\n     */\n\tpublic function testERROR_TYPE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Functions','ERROR_TYPE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerERROR_TYPE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Functions/ERROR_TYPE.data');\n\t}\n\n    /**\n     * @dataProvider providerIS_LOGICAL\n     */\n\tpublic function testIS_LOGICAL()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_LOGICAL'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIS_LOGICAL()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Functions/IS_LOGICAL.data');\n\t}\n\n    /**\n     * @dataProvider providerIS_NA\n     */\n\tpublic function testIS_NA()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NA'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIS_NA()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Functions/IS_NA.data');\n\t}\n\n    /**\n     * @dataProvider providerIS_NUMBER\n     */\n\tpublic function testIS_NUMBER()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NUMBER'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIS_NUMBER()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Functions/IS_NUMBER.data');\n\t}\n\n    /**\n     * @dataProvider providerIS_TEXT\n     */\n\tpublic function testIS_TEXT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_TEXT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIS_TEXT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Functions/IS_TEXT.data');\n\t}\n\n    /**\n     * @dataProvider providerIS_NONTEXT\n     */\n\tpublic function testIS_NONTEXT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_NONTEXT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIS_NONTEXT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Functions/IS_NONTEXT.data');\n\t}\n\n    /**\n     * @dataProvider providerIS_EVEN\n     */\n\tpublic function testIS_EVEN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_EVEN'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIS_EVEN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Functions/IS_EVEN.data');\n\t}\n\n    /**\n     * @dataProvider providerIS_ODD\n     */\n\tpublic function testIS_ODD()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Functions','IS_ODD'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerIS_ODD()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Functions/IS_ODD.data');\n\t}\n\n    /**\n     * @dataProvider providerTYPE\n     */\n\tpublic function testTYPE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Functions','TYPE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerTYPE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Functions/TYPE.data');\n\t}\n\n    /**\n     * @dataProvider providerN\n     */\n\tpublic function testN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Functions','N'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Functions/N.data');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Calculation/LogicalTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass LogicalTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\n        PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL);\n\t}\n\n\tpublic function testTRUE()\n\t{\n\t\t$result = PHPExcel_Calculation_Logical::TRUE();\n\t\t$this->assertEquals(TRUE, $result);\n\t}\n\n\tpublic function testFALSE()\n\t{\n\t\t$result = PHPExcel_Calculation_Logical::FALSE();\n\t\t$this->assertEquals(FALSE, $result);\n\t}\n\n    /**\n     * @dataProvider providerAND\n     */\n\tpublic function testAND()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_AND'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerAND()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Logical/AND.data');\n\t}\n\n    /**\n     * @dataProvider providerOR\n     */\n\tpublic function testOR()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Logical','LOGICAL_OR'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerOR()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Logical/OR.data');\n\t}\n\n    /**\n     * @dataProvider providerNOT\n     */\n    public function testNOT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Logical','NOT'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerNOT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Logical/NOT.data');\n    }\n\n    /**\n     * @dataProvider providerIF\n     */\n    public function testIF()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Logical','STATEMENT_IF'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerIF()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/Logical/IF.data');\n\t}\n\n    /**\n     * @dataProvider providerIFERROR\n     */\n    public function testIFERROR()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_Logical','IFERROR'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerIFERROR()\n    {\n        return new testDataFileIterator('rawTestData/Calculation/Logical/IFERROR.data');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Calculation/LookupRefTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass LookupRefTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\n        PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL);\n\t}\n\n    /**\n     * @dataProvider providerHLOOKUP\n     */\n\tpublic function testHLOOKUP()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_LookupRef','HLOOKUP'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerHLOOKUP()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/LookupRef/HLOOKUP.data');\n\t}\n\n    /**\n     * @dataProvider providerVLOOKUP\n     */\n\tpublic function testVLOOKUP()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_LookupRef','VLOOKUP'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerVLOOKUP()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/LookupRef/VLOOKUP.data');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Calculation/MathTrigTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass MathTrigTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\n        PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL);\n\t}\n\n    /**\n     * @dataProvider providerATAN2\n     */\n\tpublic function testATAN2()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ATAN2'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerATAN2()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/ATAN2.data');\n\t}\n\n    /**\n     * @dataProvider providerCEILING\n     */\n\tpublic function testCEILING()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','CEILING'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerCEILING()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/CEILING.data');\n\t}\n\n    /**\n     * @dataProvider providerCOMBIN\n     */\n\tpublic function testCOMBIN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','COMBIN'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerCOMBIN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/COMBIN.data');\n\t}\n\n    /**\n     * @dataProvider providerEVEN\n     */\n\tpublic function testEVEN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','EVEN'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerEVEN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/EVEN.data');\n\t}\n\n    /**\n     * @dataProvider providerODD\n     */\n\tpublic function testODD()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ODD'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerODD()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/ODD.data');\n\t}\n\n    /**\n     * @dataProvider providerFACT\n     */\n\tpublic function testFACT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerFACT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/FACT.data');\n\t}\n\n    /**\n     * @dataProvider providerFACTDOUBLE\n     */\n\tpublic function testFACTDOUBLE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FACTDOUBLE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerFACTDOUBLE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/FACTDOUBLE.data');\n\t}\n\n    /**\n     * @dataProvider providerFLOOR\n     */\n\tpublic function testFLOOR()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','FLOOR'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerFLOOR()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/FLOOR.data');\n\t}\n\n    /**\n     * @dataProvider providerGCD\n     */\n\tpublic function testGCD()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','GCD'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerGCD()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/GCD.data');\n\t}\n\n    /**\n     * @dataProvider providerLCM\n     */\n\tpublic function testLCM()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LCM'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerLCM()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/LCM.data');\n\t}\n\n    /**\n     * @dataProvider providerINT\n     */\n\tpublic function testINT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','INT'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerINT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/INT.data');\n\t}\n\n    /**\n     * @dataProvider providerSIGN\n     */\n\tpublic function testSIGN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SIGN'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerSIGN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/SIGN.data');\n\t}\n\n    /**\n     * @dataProvider providerPOWER\n     */\n\tpublic function testPOWER()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','POWER'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerPOWER()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/POWER.data');\n\t}\n\n    /**\n     * @dataProvider providerLOG\n     */\n\tpublic function testLOG()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','LOG_BASE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerLOG()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/LOG.data');\n\t}\n\n    /**\n     * @dataProvider providerMOD\n     */\n\tpublic function testMOD()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MOD'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerMOD()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/MOD.data');\n\t}\n\n    /**\n     * @dataProvider providerMDETERM\n     */\n\tpublic function testMDETERM()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MDETERM'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerMDETERM()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/MDETERM.data');\n\t}\n\n    /**\n     * @dataProvider providerMINVERSE\n     */\n\tpublic function testMINVERSE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MINVERSE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerMINVERSE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/MINVERSE.data');\n\t}\n\n    /**\n     * @dataProvider providerMMULT\n     */\n\tpublic function testMMULT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MMULT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerMMULT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/MMULT.data');\n\t}\n\n    /**\n     * @dataProvider providerMULTINOMIAL\n     */\n\tpublic function testMULTINOMIAL()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MULTINOMIAL'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerMULTINOMIAL()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/MULTINOMIAL.data');\n\t}\n\n    /**\n     * @dataProvider providerMROUND\n     */\n\tpublic function testMROUND()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\tPHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_VALUE);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','MROUND'),$args);\n\t\tPHPExcel_Calculation::setArrayReturnType(PHPExcel_Calculation::RETURN_ARRAY_AS_ARRAY);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerMROUND()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/MROUND.data');\n\t}\n\n    /**\n     * @dataProvider providerPRODUCT\n     */\n\tpublic function testPRODUCT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','PRODUCT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerPRODUCT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/PRODUCT.data');\n\t}\n\n    /**\n     * @dataProvider providerQUOTIENT\n     */\n\tpublic function testQUOTIENT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','QUOTIENT'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerQUOTIENT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/QUOTIENT.data');\n\t}\n\n    /**\n     * @dataProvider providerROUNDUP\n     */\n\tpublic function testROUNDUP()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDUP'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerROUNDUP()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/ROUNDUP.data');\n\t}\n\n    /**\n     * @dataProvider providerROUNDDOWN\n     */\n\tpublic function testROUNDDOWN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROUNDDOWN'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerROUNDDOWN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/ROUNDDOWN.data');\n\t}\n\n    /**\n     * @dataProvider providerSERIESSUM\n     */\n\tpublic function testSERIESSUM()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SERIESSUM'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerSERIESSUM()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/SERIESSUM.data');\n\t}\n\n    /**\n     * @dataProvider providerSUMSQ\n     */\n\tpublic function testSUMSQ()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SUMSQ'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerSUMSQ()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/SUMSQ.data');\n\t}\n\n    /**\n     * @dataProvider providerTRUNC\n     */\n\tpublic function testTRUNC()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','TRUNC'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerTRUNC()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/TRUNC.data');\n\t}\n\n    /**\n     * @dataProvider providerROMAN\n     */\n\tpublic function testROMAN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','ROMAN'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerROMAN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/ROMAN.data');\n\t}\n\n    /**\n     * @dataProvider providerSQRTPI\n     */\n\tpublic function testSQRTPI()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_MathTrig','SQRTPI'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-12);\n\t}\n\n    public function providerSQRTPI()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/MathTrig/SQRTPI.data');\n    }\n\n    /**\n     * @dataProvider providerSUMIF\n     */\n    public function testSUMIF()\n    {\n        $args = func_get_args();\n        $expectedResult = array_pop($args);\n        $result = call_user_func_array(array('PHPExcel_Calculation_MathTrig', 'SUMIF'), $args);\n        $this->assertEquals($expectedResult, $result, NULL, 1E-12);\n    }\n\n    public function providerSUMIF()\n    {\n        return array(\n            array(\n                array(\n                    array(1),\n                    array(5),\n                    array(10),\n                ),\n                '>=5',\n                15,\n            ),\n            array(\n                array(\n                    array('text'),\n                    array(2),\n                ),\n                '=text',\n                array(\n                    array(10),\n                    array(100),\n                ),\n                10,\n            ),\n            array(\n                array(\n                    array('\"text with quotes\"'),\n                    array(2),\n                ),\n                '=\"text with quotes\"',\n                array(\n                    array(10),\n                    array(100),\n                ),\n                10,\n            ),\n            array(\n                array(\n                    array('\"text with quotes\"'),\n                    array(''),\n                ),\n                '>\"', // Compare to the single characater \" (double quote)\n                array(\n                    array(10),\n                    array(100),\n                ),\n                10\n            ),\n            array(\n                array(\n                    array(''),\n                    array('anything'),\n                ),\n                '>\"', // Compare to the single characater \" (double quote)\n                array(\n                    array(10),\n                    array(100),\n                ),\n                100\n            ),\n        );\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Calculation/TextDataTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass TextDataTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\n        PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL);\n\t}\n\n    /**\n     * @dataProvider providerCHAR\n     */\n\tpublic function testCHAR()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','CHARACTER'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerCHAR()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/CHAR.data');\n\t}\n\n    /**\n     * @dataProvider providerCODE\n     */\n\tpublic function testCODE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','ASCIICODE'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerCODE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/CODE.data');\n\t}\n\n    /**\n     * @dataProvider providerCONCATENATE\n     */\n\tpublic function testCONCATENATE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','CONCATENATE'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerCONCATENATE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/CONCATENATE.data');\n\t}\n\n    /**\n     * @dataProvider providerLEFT\n     */\n\tpublic function testLEFT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','LEFT'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerLEFT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/LEFT.data');\n\t}\n\n    /**\n     * @dataProvider providerMID\n     */\n\tpublic function testMID()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','MID'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerMID()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/MID.data');\n\t}\n\n    /**\n     * @dataProvider providerRIGHT\n     */\n\tpublic function testRIGHT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','RIGHT'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerRIGHT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/RIGHT.data');\n\t}\n\n    /**\n     * @dataProvider providerLOWER\n     */\n\tpublic function testLOWER()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','LOWERCASE'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerLOWER()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/LOWER.data');\n\t}\n\n    /**\n     * @dataProvider providerUPPER\n     */\n\tpublic function testUPPER()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','UPPERCASE'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerUPPER()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/UPPER.data');\n\t}\n\n    /**\n     * @dataProvider providerPROPER\n     */\n\tpublic function testPROPER()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','PROPERCASE'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerPROPER()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/PROPER.data');\n\t}\n\n    /**\n     * @dataProvider providerLEN\n     */\n\tpublic function testLEN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','STRINGLENGTH'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerLEN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/LEN.data');\n\t}\n\n    /**\n     * @dataProvider providerSEARCH\n     */\n\tpublic function testSEARCH()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHINSENSITIVE'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerSEARCH()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/SEARCH.data');\n\t}\n\n    /**\n     * @dataProvider providerFIND\n     */\n\tpublic function testFIND()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','SEARCHSENSITIVE'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerFIND()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/FIND.data');\n\t}\n\n    /**\n     * @dataProvider providerREPLACE\n     */\n\tpublic function testREPLACE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','REPLACE'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerREPLACE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/REPLACE.data');\n\t}\n\n    /**\n     * @dataProvider providerSUBSTITUTE\n     */\n\tpublic function testSUBSTITUTE()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','SUBSTITUTE'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerSUBSTITUTE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/SUBSTITUTE.data');\n\t}\n\n    /**\n     * @dataProvider providerTRIM\n     */\n\tpublic function testTRIM()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMSPACES'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerTRIM()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/TRIM.data');\n\t}\n\n    /**\n     * @dataProvider providerCLEAN\n     */\n\tpublic function testCLEAN()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','TRIMNONPRINTABLE'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerCLEAN()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/CLEAN.data');\n\t}\n\n    /**\n     * @dataProvider providerDOLLAR\n     */\n\tpublic function testDOLLAR()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','DOLLAR'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerDOLLAR()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/DOLLAR.data');\n\t}\n\n    /**\n     * @dataProvider providerFIXED\n     */\n\tpublic function testFIXED()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','FIXEDFORMAT'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerFIXED()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/FIXED.data');\n\t}\n\n    /**\n     * @dataProvider providerT\n     */\n\tpublic function testT()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','RETURNSTRING'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/T.data');\n\t}\n\n    /**\n     * @dataProvider providerTEXT\n     */\n\tpublic function testTEXT()\n\t{\n\t\t//\tEnforce decimal and thousands separator values to UK/US, and currency code to USD\n\t\tcall_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),'.');\n\t\tcall_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),',');\n\t\tcall_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),'$');\n\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','TEXTFORMAT'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerTEXT()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/TEXT.data');\n\t}\n\n    /**\n     * @dataProvider providerVALUE\n     */\n\tpublic function testVALUE()\n\t{\n\t\tcall_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),'.');\n\t\tcall_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),' ');\n\t\tcall_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),'$');\n\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Calculation_TextData','VALUE'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-8);\n\t}\n\n    public function providerVALUE()\n    {\n    \treturn new testDataFileIterator('rawTestData/Calculation/TextData/VALUE.data');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/CalculationTest.php",
    "content": "<?php\n\nrequire_once 'testDataFileIterator.php';\n\nclass CalculationTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\n        PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL);\n    }\n\n    /**\n     * @dataProvider providerBinaryComparisonOperation\n     */\n    public function testBinaryComparisonOperation($formula, $expectedResultExcel, $expectedResultOpenOffice)\n    {\n        PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_EXCEL);\n        $resultExcel = \\PHPExcel_Calculation::getInstance()->_calculateFormulaValue($formula);\n        $this->assertEquals($expectedResultExcel, $resultExcel, 'should be Excel compatible');\n\n        PHPExcel_Calculation_Functions::setCompatibilityMode(PHPExcel_Calculation_Functions::COMPATIBILITY_OPENOFFICE);\n        $resultOpenOffice = \\PHPExcel_Calculation::getInstance()->_calculateFormulaValue($formula);\n        $this->assertEquals($expectedResultOpenOffice, $resultOpenOffice, 'should be OpenOffice compatible');\n    }\n\n    public function providerBinaryComparisonOperation()\n    {\n        return new testDataFileIterator('rawTestData/CalculationBinaryComparisonOperation.data');\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Cell/AdvancedValueBinderTest.php",
    "content": "<?php\n\nclass AdvancedValueBinderTest extends PHPUnit_Framework_TestCase\n{\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n    }\n\n    public function provider()\n    {\n        if (!class_exists('PHPExcel_Style_NumberFormat')) {\n          $this->setUp();\n        }\n        $currencyUSD = PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE;\n        $currencyEURO = str_replace('$', '€', PHPExcel_Style_NumberFormat::FORMAT_CURRENCY_USD_SIMPLE);\n\n        return array(\n          array('10%', 0.1, PHPExcel_Style_NumberFormat::FORMAT_PERCENTAGE_00, ',', '.', '$'),\n          array('$10.11', 10.11, $currencyUSD, ',', '.', '$'),\n          array('$1,010.12', 1010.12, $currencyUSD, ',', '.', '$'),\n          array('$20,20', 20.2, $currencyUSD, '.', ',', '$'),\n          array('$2.020,20', 2020.2, $currencyUSD, '.', ',', '$'),\n          array('€2.020,20', 2020.2, $currencyEURO, '.', ',', '€'),\n          array('€ 2.020,20', 2020.2, $currencyEURO, '.', ',', '€'),\n          array('€2,020.22', 2020.22, $currencyEURO, ',', '.', '€'),\n        );\n    }\n\n    /**\n     * @dataProvider provider\n     */\n    public function testCurrency($value, $valueBinded, $format, $thousandsSeparator, $decimalSeparator, $currencyCode)\n    {\n        $sheet = $this->getMock(\n\t\t\t'PHPExcel_Worksheet', \n\t\t\tarray('getStyle', 'getNumberFormat', 'setFormatCode','getCellCacheController')\n\t\t);\n        $cache = $this->getMockBuilder('PHPExcel_CachedObjectStorage_Memory')\n        \t->disableOriginalConstructor()\n        \t->getMock();\n        $cache->expects($this->any())\n                 ->method('getParent')\n                 ->will($this->returnValue($sheet));\n\n        $sheet->expects($this->once())\n                 ->method('getStyle')\n                 ->will($this->returnSelf());\n        $sheet->expects($this->once())\n                 ->method('getNumberFormat')\n                 ->will($this->returnSelf());\n        $sheet->expects($this->once())\n                 ->method('setFormatCode')\n                 ->with($format)\n                 ->will($this->returnSelf());\n        $sheet->expects($this->any())\n                 ->method('getCellCacheController')\n                 ->will($this->returnValue($cache));\n\n        PHPExcel_Shared_String::setCurrencyCode($currencyCode);\n        PHPExcel_Shared_String::setDecimalSeparator($decimalSeparator);\n        PHPExcel_Shared_String::setThousandsSeparator($thousandsSeparator);\n\n        $cell = new PHPExcel_Cell(NULL, PHPExcel_Cell_DataType::TYPE_STRING, $sheet);\n\n        $binder = new PHPExcel_Cell_AdvancedValueBinder();\n        $binder->bindValue($cell, $value);\n        $this->assertEquals($valueBinded, $cell->getValue());\n    }\n}"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Cell/DataTypeTest.php",
    "content": "<?php\n\n\nclass DataTypeTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n\tpublic function testGetErrorCodes()\n\t{\n\t\t$result = call_user_func(array('PHPExcel_Cell_DataType','getErrorCodes'));\n\t\t$this->assertInternalType('array', $result);\n\t\t$this->assertGreaterThan(0, count($result));\n\t\t$this->assertArrayHasKey('#NULL!', $result);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Cell/DefaultValueBinderTest.php",
    "content": "<?php\n\nrequire_once 'testDataFileIterator.php';\n\nclass DefaultValueBinderTest extends PHPUnit_Framework_TestCase\n{\n    protected $cellStub;\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n    protected function createCellStub()\n    {\n        // Create a stub for the Cell class.\n        $this->cellStub = $this->getMockBuilder('PHPExcel_Cell')\n            ->disableOriginalConstructor()\n            ->getMock();\n        // Configure the stub.\n        $this->cellStub->expects($this->any())\n             ->method('setValueExplicit')\n             ->will($this->returnValue(true));\n\n    }\n\n    /**\n     * @dataProvider binderProvider\n     */\n    public function testBindValue($value)\n\t{\n\t\t$this->createCellStub();\n        $binder = new PHPExcel_Cell_DefaultValueBinder();\n\t\t$result = $binder->bindValue($this->cellStub, $value);\n\t\t$this->assertTrue($result);\n\t}\n\n    public function binderProvider()\n    {\n        return array(\n            array(null),\n            array(''),\n            array('ABC'),\n            array('=SUM(A1:B2)'),\n            array(true),\n            array(false),\n            array(123),\n            array(-123.456),\n            array('123'),\n            array('-123.456'),\n            array('#REF!'),\n            array(new DateTime()),\n        );\n    }\n\n    /**\n     * @dataProvider providerDataTypeForValue\n     */\n\tpublic function testDataTypeForValue()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Cell_DefaultValueBinder','dataTypeForValue'), $args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerDataTypeForValue()\n    {\n    \treturn new testDataFileIterator('rawTestData/Cell/DefaultValueBinder.data');\n\t}\n\n\tpublic function testDataTypeForRichTextObject()\n\t{\n        $objRichText = new PHPExcel_RichText();\n        $objRichText->createText('Hello World');\n\n        $expectedResult = PHPExcel_Cell_DataType::TYPE_INLINE;\n\t\t$result = call_user_func(array('PHPExcel_Cell_DefaultValueBinder','dataTypeForValue'), $objRichText);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Cell/HyperlinkTest.php",
    "content": "<?php\n\n\nclass HyperlinkTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n\tpublic function testGetUrl()\n\t{\n\t\t$urlValue = 'http://www.phpexcel.net';\n\n\t\t$testInstance = new PHPExcel_Cell_Hyperlink($urlValue);\n\n\t\t$result = $testInstance->getUrl();\n\t\t$this->assertEquals($urlValue,$result);\n\t}\n\n\tpublic function testSetUrl()\n\t{\n\t\t$initialUrlValue = 'http://www.phpexcel.net';\n\t\t$newUrlValue = 'http://github.com/PHPOffice/PHPExcel';\n\n\t\t$testInstance = new PHPExcel_Cell_Hyperlink($initialUrlValue);\n\t\t$result = $testInstance->setUrl($newUrlValue);\n\t\t$this->assertTrue($result instanceof PHPExcel_Cell_Hyperlink);\n\n\t\t$result = $testInstance->getUrl();\n\t\t$this->assertEquals($newUrlValue,$result);\n\t}\n\n\tpublic function testGetTooltip()\n\t{\n\t\t$tooltipValue = 'PHPExcel Web Site';\n\n\t\t$testInstance = new PHPExcel_Cell_Hyperlink(NULL, $tooltipValue);\n\n\t\t$result = $testInstance->getTooltip();\n\t\t$this->assertEquals($tooltipValue,$result);\n\t}\n\n\tpublic function testSetTooltip()\n\t{\n\t\t$initialTooltipValue = 'PHPExcel Web Site';\n\t\t$newTooltipValue = 'PHPExcel Repository on Github';\n\n\t\t$testInstance = new PHPExcel_Cell_Hyperlink(NULL, $initialTooltipValue);\n\t\t$result = $testInstance->setTooltip($newTooltipValue);\n\t\t$this->assertTrue($result instanceof PHPExcel_Cell_Hyperlink);\n\n\t\t$result = $testInstance->getTooltip();\n\t\t$this->assertEquals($newTooltipValue,$result);\n\t}\n\n\tpublic function testIsInternal()\n\t{\n\t\t$initialUrlValue = 'http://www.phpexcel.net';\n\t\t$newUrlValue = 'sheet://Worksheet1!A1';\n\n\t\t$testInstance = new PHPExcel_Cell_Hyperlink($initialUrlValue);\n\t\t$result = $testInstance->isInternal();\n\t\t$this->assertFalse($result);\n\n\t\t$testInstance->setUrl($newUrlValue);\n\t\t$result = $testInstance->isInternal();\n\t\t$this->assertTrue($result);\n\t}\n\n\tpublic function testGetHashCode()\n\t{\n\t\t$urlValue = 'http://www.phpexcel.net';\n\t\t$tooltipValue = 'PHPExcel Web Site';\n\t\t$initialExpectedHash = 'd84d713aed1dbbc8a7c5af183d6c7dbb';\n\n\t\t$testInstance = new PHPExcel_Cell_Hyperlink($urlValue, $tooltipValue);\n\n\t\t$result = $testInstance->getHashCode();\n\t\t$this->assertEquals($initialExpectedHash,$result);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/CellTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass CellTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n    /**\n     * @dataProvider providerColumnString\n     */\n\tpublic function testColumnIndexFromString()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Cell','columnIndexFromString'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerColumnString()\n    {\n    \treturn new testDataFileIterator('rawTestData/ColumnString.data');\n\t}\n\n    public function testColumnIndexFromStringTooLong()\n\t{\n\t\t$cellAddress = 'ABCD';\n\t\ttry {\n\t\t\t$result = call_user_func(array('PHPExcel_Cell','columnIndexFromString'),$cellAddress);\n\t\t} catch (PHPExcel_Exception $e) {\n\t\t\t$this->assertEquals($e->getMessage(), 'Column string index can not be longer than 3 characters');\n\t\t\treturn;\n\t\t}\n\t\t$this->fail('An expected exception has not been raised.');\n\t}\n\n    public function testColumnIndexFromStringTooShort()\n\t{\n\t\t$cellAddress = '';\n\t\ttry {\n\t\t\t$result = call_user_func(array('PHPExcel_Cell','columnIndexFromString'),$cellAddress);\n\t\t} catch (PHPExcel_Exception $e) {\n\t\t\t$this->assertEquals($e->getMessage(), 'Column string index can not be empty');\n\t\t\treturn;\n\t\t}\n\t\t$this->fail('An expected exception has not been raised.');\n\t}\n\n    /**\n     * @dataProvider providerColumnIndex\n     */\n\tpublic function testStringFromColumnIndex()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Cell','stringFromColumnIndex'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerColumnIndex()\n    {\n    \treturn new testDataFileIterator('rawTestData/ColumnIndex.data');\n\t}\n\n    /**\n     * @dataProvider providerCoordinates\n     */\n\tpublic function testCoordinateFromString()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Cell','coordinateFromString'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerCoordinates()\n    {\n    \treturn new testDataFileIterator('rawTestData/CellCoordinates.data');\n\t}\n\n    public function testCoordinateFromStringWithRangeAddress()\n\t{\n\t\t$cellAddress = 'A1:AI2012';\n\t\ttry {\n\t\t\t$result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress);\n\t\t} catch (PHPExcel_Exception $e) {\n\t\t\t$this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells');\n\t\t\treturn;\n\t\t}\n\t\t$this->fail('An expected exception has not been raised.');\n\t}\n\n    public function testCoordinateFromStringWithEmptyAddress()\n\t{\n\t\t$cellAddress = '';\n\t\ttry {\n\t\t\t$result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress);\n\t\t} catch (PHPExcel_Exception $e) {\n\t\t\t$this->assertEquals($e->getMessage(), 'Cell coordinate can not be zero-length string');\n\t\t\treturn;\n\t\t}\n\t\t$this->fail('An expected exception has not been raised.');\n\t}\n\n    public function testCoordinateFromStringWithInvalidAddress()\n\t{\n\t\t$cellAddress = 'AI';\n\t\ttry {\n\t\t\t$result = call_user_func(array('PHPExcel_Cell','coordinateFromString'),$cellAddress);\n\t\t} catch (PHPExcel_Exception $e) {\n\t\t\t$this->assertEquals($e->getMessage(), 'Invalid cell coordinate '.$cellAddress);\n\t\t\treturn;\n\t\t}\n\t\t$this->fail('An expected exception has not been raised.');\n\t}\n\n    /**\n     * @dataProvider providerAbsoluteCoordinates\n     */\n\tpublic function testAbsoluteCoordinateFromString()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Cell','absoluteCoordinate'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerAbsoluteCoordinates()\n    {\n    \treturn new testDataFileIterator('rawTestData/CellAbsoluteCoordinate.data');\n\t}\n\n    public function testAbsoluteCoordinateFromStringWithRangeAddress()\n\t{\n\t\t$cellAddress = 'A1:AI2012';\n\t\ttry {\n\t\t\t$result = call_user_func(array('PHPExcel_Cell','absoluteCoordinate'),$cellAddress);\n\t\t} catch (PHPExcel_Exception $e) {\n\t\t\t$this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells');\n\t\t\treturn;\n\t\t}\n\t\t$this->fail('An expected exception has not been raised.');\n\t}\n\n    /**\n     * @dataProvider providerAbsoluteReferences\n     */\n\tpublic function testAbsoluteReferenceFromString()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Cell','absoluteReference'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerAbsoluteReferences()\n    {\n    \treturn new testDataFileIterator('rawTestData/CellAbsoluteReference.data');\n\t}\n\n    public function testAbsoluteReferenceFromStringWithRangeAddress()\n\t{\n\t\t$cellAddress = 'A1:AI2012';\n\t\ttry {\n\t\t\t$result = call_user_func(array('PHPExcel_Cell','absoluteReference'),$cellAddress);\n\t\t} catch (PHPExcel_Exception $e) {\n\t\t\t$this->assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells');\n\t\t\treturn;\n\t\t}\n\t\t$this->fail('An expected exception has not been raised.');\n\t}\n\n    /**\n     * @dataProvider providerSplitRange\n     */\n\tpublic function testSplitRange()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Cell','splitRange'),$args);\n\t\tforeach($result as $key => $split) {\n\t\t\tif (!is_array($expectedResult[$key])) {\n\t\t\t\t$this->assertEquals($expectedResult[$key], $split[0]);\n\t\t\t} else {\n\t\t\t\t$this->assertEquals($expectedResult[$key], $split);\n\t\t\t}\n\t\t}\n\t}\n\n    public function providerSplitRange()\n    {\n    \treturn new testDataFileIterator('rawTestData/CellSplitRange.data');\n\t}\n\n    /**\n     * @dataProvider providerBuildRange\n     */\n\tpublic function testBuildRange()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Cell','buildRange'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerBuildRange()\n    {\n    \treturn new testDataFileIterator('rawTestData/CellBuildRange.data');\n\t}\n\n    public function testBuildRangeInvalid()\n\t{\n\t\t$cellRange = '';\n\t\ttry {\n\t\t\t$result = call_user_func(array('PHPExcel_Cell','buildRange'),$cellRange);\n\t\t} catch (PHPExcel_Exception $e) {\n\t\t\t$this->assertEquals($e->getMessage(), 'Range does not contain any information');\n\t\t\treturn;\n\t\t}\n\t\t$this->fail('An expected exception has not been raised.');\n\t}\n\n    /**\n     * @dataProvider providerRangeBoundaries\n     */\n\tpublic function testRangeBoundaries()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Cell','rangeBoundaries'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerRangeBoundaries()\n    {\n    \treturn new testDataFileIterator('rawTestData/CellRangeBoundaries.data');\n\t}\n\n    /**\n     * @dataProvider providerRangeDimension\n     */\n\tpublic function testRangeDimension()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Cell','rangeDimension'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerRangeDimension()\n    {\n    \treturn new testDataFileIterator('rawTestData/CellRangeDimension.data');\n\t}\n\n    /**\n     * @dataProvider providerGetRangeBoundaries\n     */\n\tpublic function testGetRangeBoundaries()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Cell','getRangeBoundaries'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerGetRangeBoundaries()\n    {\n    \treturn new testDataFileIterator('rawTestData/CellGetRangeBoundaries.data');\n\t}\n\n    /**\n     * @dataProvider providerExtractAllCellReferencesInRange\n     */\n\tpublic function testExtractAllCellReferencesInRange()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Cell','extractAllCellReferencesInRange'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerExtractAllCellReferencesInRange()\n    {\n    \treturn new testDataFileIterator('rawTestData/CellExtractAllCellReferencesInRange.data');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Chart/DataSeriesValuesTest.php",
    "content": "<?php\n\n\nclass DataSeriesValuesTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n\tpublic function testSetDataType()\n\t{\n\t\t$dataTypeValues = array(\n\t\t\t'Number',\n\t\t\t'String'\n\t\t);\n\n\t\t$testInstance = new PHPExcel_Chart_DataSeriesValues;\n\n\t\tforeach($dataTypeValues as $dataTypeValue) {\n\t\t\t$result = $testInstance->setDataType($dataTypeValue);\n\t\t\t$this->assertTrue($result instanceof PHPExcel_Chart_DataSeriesValues);\n\t\t}\n\t}\n\n\tpublic function testSetInvalidDataTypeThrowsException()\n\t{\n\t\t$testInstance = new PHPExcel_Chart_DataSeriesValues;\n\n\t\ttry {\n\t\t\t$result = $testInstance->setDataType('BOOLEAN');\n\t\t} catch (Exception $e) {\n\t\t\t$this->assertEquals($e->getMessage(), 'Invalid datatype for chart data series values');\n\t\t\treturn;\n\t\t}\n\t\t$this->fail('An expected exception has not been raised.');\n\t}\n\n\tpublic function testGetDataType()\n\t{\n\t\t$dataTypeValue = 'String';\n\n\t\t$testInstance = new PHPExcel_Chart_DataSeriesValues;\n\t\t$setValue = $testInstance->setDataType($dataTypeValue);\n\n\t\t$result = $testInstance->getDataType();\n\t\t$this->assertEquals($dataTypeValue,$result);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Chart/LayoutTest.php",
    "content": "<?php\n\n\nclass LayoutTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n\tpublic function testSetLayoutTarget()\n\t{\n\t\t$LayoutTargetValue = 'String';\n\n\t\t$testInstance = new PHPExcel_Chart_Layout;\n\n\t\t$result = $testInstance->setLayoutTarget($LayoutTargetValue);\n\t\t$this->assertTrue($result instanceof PHPExcel_Chart_Layout);\n\t}\n\n\tpublic function testGetLayoutTarget()\n\t{\n\t\t$LayoutTargetValue = 'String';\n\n\t\t$testInstance = new PHPExcel_Chart_Layout;\n\t\t$setValue = $testInstance->setLayoutTarget($LayoutTargetValue);\n\n\t\t$result = $testInstance->getLayoutTarget();\n\t\t$this->assertEquals($LayoutTargetValue,$result);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Chart/LegendTest.php",
    "content": "<?php\n\n\nclass LegendTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT'))\n        {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n\tpublic function testSetPosition()\n\t{\n\t\t$positionValues = array(\n\t\t\tPHPExcel_Chart_Legend::POSITION_RIGHT,\n\t\t\tPHPExcel_Chart_Legend::POSITION_LEFT,\n\t\t\tPHPExcel_Chart_Legend::POSITION_TOP,\n\t\t\tPHPExcel_Chart_Legend::POSITION_BOTTOM,\n\t\t\tPHPExcel_Chart_Legend::POSITION_TOPRIGHT,\n\t\t);\n\n\t\t$testInstance = new PHPExcel_Chart_Legend;\n\n\t\tforeach($positionValues as $positionValue) {\n\t\t\t$result = $testInstance->setPosition($positionValue);\n\t\t\t$this->assertTrue($result);\n\t\t}\n\t}\n\n\tpublic function testSetInvalidPositionReturnsFalse()\n\t{\n\t\t$testInstance = new PHPExcel_Chart_Legend;\n\n\t\t$result = $testInstance->setPosition('BottomLeft');\n\t\t$this->assertFalse($result);\n\t\t//\tEnsure that value is unchanged\n\t\t$result = $testInstance->getPosition();\n\t\t$this->assertEquals(PHPExcel_Chart_Legend::POSITION_RIGHT,$result);\n\t}\n\n\tpublic function testGetPosition()\n\t{\n\t\t$PositionValue = PHPExcel_Chart_Legend::POSITION_BOTTOM;\n\n\t\t$testInstance = new PHPExcel_Chart_Legend;\n\t\t$setValue = $testInstance->setPosition($PositionValue);\n\n\t\t$result = $testInstance->getPosition();\n\t\t$this->assertEquals($PositionValue,$result);\n\t}\n\n\tpublic function testSetPositionXL()\n\t{\n\t\t$positionValues = array(\n\t\t\tPHPExcel_Chart_Legend::xlLegendPositionBottom,\n\t\t\tPHPExcel_Chart_Legend::xlLegendPositionCorner,\n\t\t\tPHPExcel_Chart_Legend::xlLegendPositionCustom,\n\t\t\tPHPExcel_Chart_Legend::xlLegendPositionLeft,\n\t\t\tPHPExcel_Chart_Legend::xlLegendPositionRight,\n\t\t\tPHPExcel_Chart_Legend::xlLegendPositionTop,\n\t\t);\n\n\t\t$testInstance = new PHPExcel_Chart_Legend;\n\n\t\tforeach($positionValues as $positionValue) {\n\t\t\t$result = $testInstance->setPositionXL($positionValue);\n\t\t\t$this->assertTrue($result);\n\t\t}\n\t}\n\n\tpublic function testSetInvalidXLPositionReturnsFalse()\n\t{\n\t\t$testInstance = new PHPExcel_Chart_Legend;\n\n\t\t$result = $testInstance->setPositionXL(999);\n\t\t$this->assertFalse($result);\n\t\t//\tEnsure that value is unchanged\n\t\t$result = $testInstance->getPositionXL();\n\t\t$this->assertEquals(PHPExcel_Chart_Legend::xlLegendPositionRight,$result);\n\t}\n\n\tpublic function testGetPositionXL()\n\t{\n\t\t$PositionValue = PHPExcel_Chart_Legend::xlLegendPositionCorner;\n\n\t\t$testInstance = new PHPExcel_Chart_Legend;\n\t\t$setValue = $testInstance->setPositionXL($PositionValue);\n\n\t\t$result = $testInstance->getPositionXL();\n\t\t$this->assertEquals($PositionValue,$result);\n\t}\n\n\tpublic function testSetOverlay()\n\t{\n\t\t$overlayValues = array(\n\t\t\tTRUE,\n\t\t\tFALSE,\n\t\t);\n\n\t\t$testInstance = new PHPExcel_Chart_Legend;\n\n\t\tforeach($overlayValues as $overlayValue) {\n\t\t\t$result = $testInstance->setOverlay($overlayValue);\n\t\t\t$this->assertTrue($result);\n\t\t}\n\t}\n\n\tpublic function testSetInvalidOverlayReturnsFalse()\n\t{\n\t\t$testInstance = new PHPExcel_Chart_Legend;\n\n\t\t$result = $testInstance->setOverlay('INVALID');\n\t\t$this->assertFalse($result);\n\n\t\t$result = $testInstance->getOverlay();\n\t\t$this->assertFalse($result);\n\t}\n\n\tpublic function testGetOverlay()\n\t{\n\t\t$OverlayValue = TRUE;\n\n\t\t$testInstance = new PHPExcel_Chart_Legend;\n\t\t$setValue = $testInstance->setOverlay($OverlayValue);\n\n\t\t$result = $testInstance->getOverlay();\n\t\t$this->assertEquals($OverlayValue,$result);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Reader/XEEValidatorTest.php",
    "content": "<?php\n\n\nclass XEEValidatorTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n    /**\n     * @dataProvider providerInvalidXML\n     * @expectedException PHPExcel_Reader_Exception\n     */\n\tpublic function testInvalidXML($filename)\n\t{\n        $reader = $this->getMockForAbstractClass('PHPExcel_Reader_Abstract');\n        $expectedResult = 'FAILURE: Should throw an Exception rather than return a value';\n\t\t$result = $reader->securityScanFile($filename);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerInvalidXML()\n    {\n        $tests = [];\n        foreach(glob('rawTestData/Reader/XEETestInvalid*.xml') as $file) {\n            $tests[] = [realpath($file), true];\n        }\n        return $tests;\n\t}\n\n    /**\n     * @dataProvider providerValidXML\n     */\n\tpublic function testValidXML($filename, $expectedResult)\n\t{\n        $reader = $this->getMockForAbstractClass('PHPExcel_Reader_Abstract');\n\t\t$result = $reader->securityScanFile($filename);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerValidXML()\n    {\n        $tests = [];\n        foreach(glob('rawTestData/Reader/XEETestValid*.xml') as $file) {\n            $tests[] = [realpath($file), file_get_contents($file)];\n        }\n        return $tests;\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/ReferenceHelperTest.php",
    "content": "<?php\n\n\nclass ReferenceHelperTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n\tpublic function testColumnSort()\n\t{\n\t\t$columnBase = $columnExpectedResult = array(\n\t\t\t'A','B','Z',\n\t\t\t'AA','AB','AZ',\n\t\t\t'BA','BB','BZ',\n\t\t\t'ZA','ZB','ZZ',\n\t\t\t'AAA','AAB','AAZ',\n\t\t\t'ABA','ABB','ABZ',\n\t\t\t'AZA','AZB','AZZ',\n\t\t\t'BAA','BAB','BAZ',\n\t\t\t'BBA','BBB','BBZ',\n\t\t\t'BZA','BZB','BZZ'\n\t\t);\n\t\tshuffle($columnBase);\n\t\tusort($columnBase, array('PHPExcel_ReferenceHelper','columnSort'));\n\t\tforeach($columnBase as $key => $value) {\n\t\t\t$this->assertEquals($columnExpectedResult[$key], $value);\n\t\t}\n\t}\n\n\tpublic function testColumnReverseSort()\n\t{\n\t\t$columnBase = $columnExpectedResult = array(\n\t\t\t'A','B','Z',\n\t\t\t'AA','AB','AZ',\n\t\t\t'BA','BB','BZ',\n\t\t\t'ZA','ZB','ZZ',\n\t\t\t'AAA','AAB','AAZ',\n\t\t\t'ABA','ABB','ABZ',\n\t\t\t'AZA','AZB','AZZ',\n\t\t\t'BAA','BAB','BAZ',\n\t\t\t'BBA','BBB','BBZ',\n\t\t\t'BZA','BZB','BZZ'\n\t\t);\n\t\tshuffle($columnBase);\n\t\t$columnExpectedResult = array_reverse($columnExpectedResult);\n\t\tusort($columnBase, array('PHPExcel_ReferenceHelper','columnReverseSort'));\n\t\tforeach($columnBase as $key => $value) {\n\t\t\t$this->assertEquals($columnExpectedResult[$key], $value);\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Shared/CodePageTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass CodePageTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n    /**\n     * @dataProvider providerCodePage\n     */\n\tpublic function testCodePageNumberToName()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Shared_CodePage','NumberToName'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerCodePage()\n    {\n    \treturn new testDataFileIterator('rawTestData/Shared/CodePage.data');\n\t}\n\n    public function testNumberToNameWithInvalidCodePage()\n\t{\n\t\t$invalidCodePage = 12345;\n\t\ttry {\n\t\t\t$result = call_user_func(array('PHPExcel_Shared_CodePage','NumberToName'),$invalidCodePage);\n\t\t} catch (Exception $e) {\n\t\t\t$this->assertEquals($e->getMessage(), 'Unknown codepage: 12345');\n\t\t\treturn;\n\t\t}\n\t\t$this->fail('An expected exception has not been raised.');\n\t}\n\n    public function testNumberToNameWithUnsupportedCodePage()\n\t{\n\t\t$unsupportedCodePage = 720;\n\t\ttry {\n\t\t\t$result = call_user_func(array('PHPExcel_Shared_CodePage','NumberToName'),$unsupportedCodePage);\n\t\t} catch (Exception $e) {\n\t\t\t$this->assertEquals($e->getMessage(), 'Code page 720 not supported.');\n\t\t\treturn;\n\t\t}\n\t\t$this->fail('An expected exception has not been raised.');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Shared/DateTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass DateTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n\tpublic function testSetExcelCalendar()\n\t{\n\t\t$calendarValues = array(\n\t\t\tPHPExcel_Shared_Date::CALENDAR_MAC_1904,\n\t\t\tPHPExcel_Shared_Date::CALENDAR_WINDOWS_1900,\n\t\t);\n\n\t\tforeach($calendarValues as $calendarValue) {\n\t\t\t$result = call_user_func(array('PHPExcel_Shared_Date','setExcelCalendar'),$calendarValue);\n\t\t\t$this->assertTrue($result);\n\t\t}\n\t}\n\n    public function testSetExcelCalendarWithInvalidValue()\n\t{\n\t\t$unsupportedCalendar = '2012';\n\t\t$result = call_user_func(array('PHPExcel_Shared_Date','setExcelCalendar'),$unsupportedCalendar);\n\t\t$this->assertFalse($result);\n\t}\n\n    /**\n     * @dataProvider providerDateTimeExcelToPHP1900\n     */\n\tpublic function testDateTimeExcelToPHP1900()\n\t{\n\t\t$result = call_user_func(\n\t\t\tarray('PHPExcel_Shared_Date','setExcelCalendar'),\n\t\t\tPHPExcel_Shared_Date::CALENDAR_WINDOWS_1900\n\t\t);\n\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\tif ($args[0] < 1) {\n\t\t\t$expectedResult += gmmktime(0,0,0);\n\t\t}\n\t\t$result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerDateTimeExcelToPHP1900()\n    {\n    \treturn new testDataFileIterator('rawTestData/Shared/DateTimeExcelToPHP1900.data');\n\t}\n\n    /**\n     * @dataProvider providerDateTimePHPToExcel1900\n     */\n\tpublic function testDateTimePHPToExcel1900()\n\t{\n\t\t$result = call_user_func(\n\t\t\tarray('PHPExcel_Shared_Date','setExcelCalendar'),\n\t\t\tPHPExcel_Shared_Date::CALENDAR_WINDOWS_1900\n\t\t);\n\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Shared_Date','PHPToExcel'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-5);\n\t}\n\n    public function providerDateTimePHPToExcel1900()\n    {\n    \treturn new testDataFileIterator('rawTestData/Shared/DateTimePHPToExcel1900.data');\n\t}\n\n    /**\n     * @dataProvider providerDateTimeFormattedPHPToExcel1900\n     */\n\tpublic function testDateTimeFormattedPHPToExcel1900()\n\t{\n\t\t$result = call_user_func(\n\t\t\tarray('PHPExcel_Shared_Date','setExcelCalendar'),\n\t\t\tPHPExcel_Shared_Date::CALENDAR_WINDOWS_1900\n\t\t);\n\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Shared_Date','FormattedPHPToExcel'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-5);\n\t}\n\n    public function providerDateTimeFormattedPHPToExcel1900()\n    {\n    \treturn new testDataFileIterator('rawTestData/Shared/DateTimeFormattedPHPToExcel1900.data');\n\t}\n\n    /**\n     * @dataProvider providerDateTimeExcelToPHP1904\n     */\n\tpublic function testDateTimeExcelToPHP1904()\n\t{\n\t\t$result = call_user_func(\n\t\t\tarray('PHPExcel_Shared_Date','setExcelCalendar'),\n\t\t\tPHPExcel_Shared_Date::CALENDAR_MAC_1904\n\t\t);\n\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\tif ($args[0] < 1) {\n\t\t\t$expectedResult += gmmktime(0,0,0);\n\t\t}\n\t\t$result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerDateTimeExcelToPHP1904()\n    {\n    \treturn new testDataFileIterator('rawTestData/Shared/DateTimeExcelToPHP1904.data');\n\t}\n\n    /**\n     * @dataProvider providerDateTimePHPToExcel1904\n     */\n\tpublic function testDateTimePHPToExcel1904()\n\t{\n\t\t$result = call_user_func(\n\t\t\tarray('PHPExcel_Shared_Date','setExcelCalendar'),\n\t\t\tPHPExcel_Shared_Date::CALENDAR_MAC_1904\n\t\t);\n\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Shared_Date','PHPToExcel'),$args);\n\t\t$this->assertEquals($expectedResult, $result, NULL, 1E-5);\n\t}\n\n    public function providerDateTimePHPToExcel1904()\n    {\n    \treturn new testDataFileIterator('rawTestData/Shared/DateTimePHPToExcel1904.data');\n\t}\n\n    /**\n     * @dataProvider providerIsDateTimeFormatCode\n     */\n\tpublic function testIsDateTimeFormatCode()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Shared_Date','isDateTimeFormatCode'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerIsDateTimeFormatCode()\n    {\n    \treturn new testDataFileIterator('rawTestData/Shared/DateTimeFormatCodes.data');\n\t}\n\n    /**\n     * @dataProvider providerDateTimeExcelToPHP1900Timezone\n     */\n\tpublic function testDateTimeExcelToPHP1900Timezone()\n\t{\n\t\t$result = call_user_func(\n\t\t\tarray('PHPExcel_Shared_Date','setExcelCalendar'),\n\t\t\tPHPExcel_Shared_Date::CALENDAR_WINDOWS_1900\n\t\t);\n\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\tif ($args[0] < 1) {\n\t\t\t$expectedResult += gmmktime(0,0,0);\n\t\t}\n\t\t$result = call_user_func_array(array('PHPExcel_Shared_Date','ExcelToPHP'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerDateTimeExcelToPHP1900Timezone()\n    {\n    \treturn new testDataFileIterator('rawTestData/Shared/DateTimeExcelToPHP1900Timezone.data');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Shared/FileTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass FileTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n\tpublic function testGetUseUploadTempDirectory()\n\t{\n\t\t$expectedResult = FALSE;\n\n\t\t$result = call_user_func(array('PHPExcel_Shared_File','getUseUploadTempDirectory'));\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testSetUseUploadTempDirectory()\n\t{\n\t\t$useUploadTempDirectoryValues = array(\n\t\t\tTRUE,\n\t\t\tFALSE,\n\t\t);\n\n\t\tforeach($useUploadTempDirectoryValues as $useUploadTempDirectoryValue) {\n\t\t\tcall_user_func(array('PHPExcel_Shared_File','setUseUploadTempDirectory'),$useUploadTempDirectoryValue);\n\n\t\t\t$result = call_user_func(array('PHPExcel_Shared_File','getUseUploadTempDirectory'));\n\t\t\t$this->assertEquals($useUploadTempDirectoryValue, $result);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Shared/FontTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass FontTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n\tpublic function testGetAutoSizeMethod()\n\t{\n\t\t$expectedResult = PHPExcel_Shared_Font::AUTOSIZE_METHOD_APPROX;\n\n\t\t$result = call_user_func(array('PHPExcel_Shared_Font','getAutoSizeMethod'));\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testSetAutoSizeMethod()\n\t{\n\t\t$autosizeMethodValues = array(\n\t\t\tPHPExcel_Shared_Font::AUTOSIZE_METHOD_EXACT,\n\t\t\tPHPExcel_Shared_Font::AUTOSIZE_METHOD_APPROX,\n\t\t);\n\n\t\tforeach($autosizeMethodValues as $autosizeMethodValue) {\n\t\t\t$result = call_user_func(array('PHPExcel_Shared_Font','setAutoSizeMethod'),$autosizeMethodValue);\n\t\t\t$this->assertTrue($result);\n\t\t}\n\t}\n\n    public function testSetAutoSizeMethodWithInvalidValue()\n\t{\n\t\t$unsupportedAutosizeMethod = 'guess';\n\n\t\t$result = call_user_func(array('PHPExcel_Shared_Font','setAutoSizeMethod'),$unsupportedAutosizeMethod);\n\t\t$this->assertFalse($result);\n\t}\n\n    /**\n     * @dataProvider providerFontSizeToPixels\n     */\n\tpublic function testFontSizeToPixels()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Shared_Font','fontSizeToPixels'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerFontSizeToPixels()\n    {\n    \treturn new testDataFileIterator('rawTestData/Shared/FontSizeToPixels.data');\n\t}\n\n    /**\n     * @dataProvider providerInchSizeToPixels\n     */\n\tpublic function testInchSizeToPixels()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Shared_Font','inchSizeToPixels'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerInchSizeToPixels()\n    {\n    \treturn new testDataFileIterator('rawTestData/Shared/InchSizeToPixels.data');\n\t}\n\n    /**\n     * @dataProvider providerCentimeterSizeToPixels\n     */\n\tpublic function testCentimeterSizeToPixels()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Shared_Font','centimeterSizeToPixels'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerCentimeterSizeToPixels()\n    {\n    \treturn new testDataFileIterator('rawTestData/Shared/CentimeterSizeToPixels.data');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Shared/PasswordHasherTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass PasswordHasherTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n    /**\n     * @dataProvider providerHashPassword\n     */\n\tpublic function testHashPassword()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Shared_PasswordHasher','hashPassword'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerHashPassword()\n    {\n    \treturn new testDataFileIterator('rawTestData/Shared/PasswordHashes.data');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Shared/StringTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass StringTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n\tpublic function testGetIsMbStringEnabled()\n\t{\n\t\t$result = call_user_func(array('PHPExcel_Shared_String','getIsMbstringEnabled'));\n\t\t$this->assertTrue($result);\n\t}\n\n\tpublic function testGetIsIconvEnabled()\n\t{\n\t\t$result = call_user_func(array('PHPExcel_Shared_String','getIsIconvEnabled'));\n\t\t$this->assertTrue($result);\n\t}\n\n\tpublic function testGetDecimalSeparator()\n\t{\n\t\t$localeconv = localeconv();\n\n\t\t$expectedResult = (!empty($localeconv['decimal_point'])) ? $localeconv['decimal_point'] : ',';\n\t\t$result = call_user_func(array('PHPExcel_Shared_String','getDecimalSeparator'));\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testSetDecimalSeparator()\n\t{\n\t\t$expectedResult = ',';\n\t\t$result = call_user_func(array('PHPExcel_Shared_String','setDecimalSeparator'),$expectedResult);\n\n\t\t$result = call_user_func(array('PHPExcel_Shared_String','getDecimalSeparator'));\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testGetThousandsSeparator()\n\t{\n\t\t$localeconv = localeconv();\n\n\t\t$expectedResult = (!empty($localeconv['thousands_sep'])) ? $localeconv['thousands_sep'] : ',';\n\t\t$result = call_user_func(array('PHPExcel_Shared_String','getThousandsSeparator'));\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testSetThousandsSeparator()\n\t{\n\t\t$expectedResult = ' ';\n\t\t$result = call_user_func(array('PHPExcel_Shared_String','setThousandsSeparator'),$expectedResult);\n\n\t\t$result = call_user_func(array('PHPExcel_Shared_String','getThousandsSeparator'));\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testGetCurrencyCode()\n\t{\n\t\t$localeconv = localeconv();\n\n\t\t$expectedResult = (!empty($localeconv['currency_symbol'])) ? $localeconv['currency_symbol'] : '$';\n\t\t$result = call_user_func(array('PHPExcel_Shared_String','getCurrencyCode'));\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testSetCurrencyCode()\n\t{\n\t\t$expectedResult = '£';\n\t\t$result = call_user_func(array('PHPExcel_Shared_String','setCurrencyCode'),$expectedResult);\n\n\t\t$result = call_user_func(array('PHPExcel_Shared_String','getCurrencyCode'));\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Shared/TimeZoneTest.php",
    "content": "<?php\n\n\nclass TimeZoneTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n\tpublic function testSetTimezone()\n\t{\n\t\t$timezoneValues = array(\n\t\t\t'Europe/Prague',\n\t\t\t'Asia/Tokyo',\n\t\t\t'America/Indiana/Indianapolis',\n\t\t\t'Pacific/Honolulu',\n\t\t\t'Atlantic/St_Helena',\n\t\t);\n\n\t\tforeach($timezoneValues as $timezoneValue) {\n\t\t\t$result = call_user_func(array('PHPExcel_Shared_TimeZone','setTimezone'),$timezoneValue);\n\t\t\t$this->assertTrue($result);\n\t\t}\n\n\t}\n\n    public function testSetTimezoneWithInvalidValue()\n\t{\n\t\t$unsupportedTimezone = 'Etc/GMT+10';\n\t\t$result = call_user_func(array('PHPExcel_Shared_TimeZone','setTimezone'),$unsupportedTimezone);\n\t\t$this->assertFalse($result);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Style/ColorTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass ColorTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n    /**\n     * @dataProvider providerColorGetRed\n     */\n\tpublic function testGetRed()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Style_Color','getRed'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerColorGetRed()\n    {\n    \treturn new testDataFileIterator('rawTestData/Style/ColorGetRed.data');\n\t}\n\n    /**\n     * @dataProvider providerColorGetGreen\n     */\n\tpublic function testGetGreen()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Style_Color','getGreen'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerColorGetGreen()\n    {\n    \treturn new testDataFileIterator('rawTestData/Style/ColorGetGreen.data');\n\t}\n\n    /**\n     * @dataProvider providerColorGetBlue\n     */\n\tpublic function testGetBlue()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Style_Color','getBlue'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerColorGetBlue()\n    {\n    \treturn new testDataFileIterator('rawTestData/Style/ColorGetBlue.data');\n\t}\n\n    /**\n     * @dataProvider providerColorChangeBrightness\n     */\n\tpublic function testChangeBrightness()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Style_Color','changeBrightness'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerColorChangeBrightness()\n    {\n    \treturn new testDataFileIterator('rawTestData/Style/ColorChangeBrightness.data');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Style/NumberFormatTest.php",
    "content": "<?php\n\n\nrequire_once 'testDataFileIterator.php';\n\nclass NumberFormatTest extends PHPUnit_Framework_TestCase\n{\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\n\t\tPHPExcel_Shared_String::setDecimalSeparator('.');\n\t\tPHPExcel_Shared_String::setThousandsSeparator(',');\n\t}\n\n    /**\n     * @dataProvider providerNumberFormat\n     */\n\tpublic function testFormatValueWithMask()\n\t{\n\t\t$args = func_get_args();\n\t\t$expectedResult = array_pop($args);\n\t\t$result = call_user_func_array(array('PHPExcel_Style_NumberFormat','toFormattedString'),$args);\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    public function providerNumberFormat()\n    {\n    \treturn new testDataFileIterator('rawTestData/Style/NumberFormat.data');\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/Column/RuleTest.php",
    "content": "<?php\n\n\nclass RuleTest extends PHPUnit_Framework_TestCase\n{\n\tprivate $_testAutoFilterRuleObject;\n\n\tprivate $_mockAutoFilterColumnObject;\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\n        $this->_mockAutoFilterColumnObject = $this->getMockBuilder('PHPExcel_Worksheet_AutoFilter_Column')\n        \t->disableOriginalConstructor()\n        \t->getMock();\n\n        $this->_mockAutoFilterColumnObject->expects($this->any())\n        \t->method('testColumnInRange')\n        \t->will($this->returnValue(3));\n\n\t\t$this->_testAutoFilterRuleObject = new PHPExcel_Worksheet_AutoFilter_Column_Rule(\n\t\t\t$this->_mockAutoFilterColumnObject\n\t\t);\n    }\n\n\tpublic function testGetRuleType()\n\t{\n\t\t$result = $this->_testAutoFilterRuleObject->getRuleType();\n\t\t$this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_FILTER, $result);\n\t}\n\n\tpublic function testSetRuleType()\n\t{\n\t\t$expectedResult = PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP;\n\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterRuleObject->setRuleType($expectedResult);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result);\n\n\t\t$result = $this->_testAutoFilterRuleObject->getRuleType();\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testSetValue()\n\t{\n\t\t$expectedResult = 100;\n\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterRuleObject->setValue($expectedResult);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result);\n\n\t\t$result = $this->_testAutoFilterRuleObject->getValue();\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testGetOperator()\n\t{\n\t\t$result = $this->_testAutoFilterRuleObject->getOperator();\n\t\t$this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_EQUAL, $result);\n\t}\n\n\tpublic function testSetOperator()\n\t{\n\t\t$expectedResult = PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN;\n\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterRuleObject->setOperator($expectedResult);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result);\n\n\t\t$result = $this->_testAutoFilterRuleObject->getOperator();\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testSetGrouping()\n\t{\n\t\t$expectedResult = PHPExcel_Worksheet_AutoFilter_Column_Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH;\n\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterRuleObject->setGrouping($expectedResult);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result);\n\n\t\t$result = $this->_testAutoFilterRuleObject->getGrouping();\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testGetParent()\n\t{\n\t\t$result = $this->_testAutoFilterRuleObject->getParent();\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result);\n\t}\n\n\tpublic function testSetParent()\n\t{\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterRuleObject->setParent($this->_mockAutoFilterColumnObject);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result);\n\t}\n\n\tpublic function testClone()\n\t{\n\t\t$result = clone $this->_testAutoFilterRuleObject;\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column_Rule', $result);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Worksheet/AutoFilter/ColumnTest.php",
    "content": "<?php\n\n\nclass AutofilterColumnTest extends PHPUnit_Framework_TestCase\n{\n\tprivate $_testInitialColumn = 'H';\n\n\tprivate $_testAutoFilterColumnObject;\n\n\tprivate $_mockAutoFilterObject;\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\n        $this->_mockAutoFilterObject = $this->getMockBuilder('PHPExcel_Worksheet_AutoFilter')\n        \t->disableOriginalConstructor()\n        \t->getMock();\n\n        $this->_mockAutoFilterObject->expects($this->any())\n        \t->method('testColumnInRange')\n        \t->will($this->returnValue(3));\n\n\t\t$this->_testAutoFilterColumnObject = new PHPExcel_Worksheet_AutoFilter_Column(\n\t\t\t$this->_testInitialColumn,\n\t\t\t$this->_mockAutoFilterObject\n\t\t);\n    }\n\n\tpublic function testGetColumnIndex()\n\t{\n\t\t$result = $this->_testAutoFilterColumnObject->getColumnIndex();\n\t\t$this->assertEquals($this->_testInitialColumn, $result);\n\t}\n\n\tpublic function testSetColumnIndex()\n\t{\n\t\t$expectedResult = 'L';\n\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterColumnObject->setColumnIndex($expectedResult);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result);\n\n\t\t$result = $this->_testAutoFilterColumnObject->getColumnIndex();\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testGetParent()\n\t{\n\t\t$result = $this->_testAutoFilterColumnObject->getParent();\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result);\n\t}\n\n\tpublic function testSetParent()\n\t{\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterColumnObject->setParent($this->_mockAutoFilterObject);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result);\n\t}\n\n\tpublic function testGetFilterType()\n\t{\n\t\t$result = $this->_testAutoFilterColumnObject->getFilterType();\n\t\t$this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_FILTER, $result);\n\t}\n\n\tpublic function testSetFilterType()\n\t{\n\t\t$result = $this->_testAutoFilterColumnObject->setFilterType(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result);\n\n\t\t$result = $this->_testAutoFilterColumnObject->getFilterType();\n\t\t$this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER, $result);\n\t}\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n\tpublic function testSetInvalidFilterTypeThrowsException()\n\t{\n\t\t$expectedResult = 'Unfiltered';\n\n\t\t$result = $this->_testAutoFilterColumnObject->setFilterType($expectedResult);\n\t}\n\n\tpublic function testGetJoin()\n\t{\n\t\t$result = $this->_testAutoFilterColumnObject->getJoin();\n\t\t$this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_OR, $result);\n\t}\n\n\tpublic function testSetJoin()\n\t{\n\t\t$result = $this->_testAutoFilterColumnObject->setJoin(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result);\n\n\t\t$result = $this->_testAutoFilterColumnObject->getJoin();\n\t\t$this->assertEquals(PHPExcel_Worksheet_AutoFilter_Column::AUTOFILTER_COLUMN_JOIN_AND, $result);\n\t}\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n\tpublic function testSetInvalidJoinThrowsException()\n\t{\n\t\t$expectedResult = 'Neither';\n\n\t\t$result = $this->_testAutoFilterColumnObject->setJoin($expectedResult);\n\t}\n\n\tpublic function testSetAttributes()\n\t{\n\t\t$attributeSet = array(\t'val' => 100,\n\t\t\t\t\t\t\t\t'maxVal' => 200\n\t\t\t\t\t\t\t );\n\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterColumnObject->setAttributes($attributeSet);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result);\n\t}\n\n\tpublic function testGetAttributes()\n\t{\n\t\t$attributeSet = array(\t'val' => 100,\n\t\t\t\t\t\t\t\t'maxVal' => 200\n\t\t\t\t\t\t\t );\n\n\t\t$this->_testAutoFilterColumnObject->setAttributes($attributeSet);\n\n\t\t$result = $this->_testAutoFilterColumnObject->getAttributes();\n\t\t$this->assertTrue(is_array($result));\n\t\t$this->assertEquals(count($attributeSet), count($result));\n\t}\n\n\tpublic function testSetAttribute()\n\t{\n\t\t$attributeSet = array(\t'val' => 100,\n\t\t\t\t\t\t\t\t'maxVal' => 200\n\t\t\t\t\t\t\t );\n\n\t\tforeach($attributeSet as $attributeName => $attributeValue) {\n\t\t\t//\tSetters return the instance to implement the fluent interface\n\t\t\t$result = $this->_testAutoFilterColumnObject->setAttribute($attributeName,$attributeValue);\n\t\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result);\n\t\t}\n\t}\n\n\tpublic function testGetAttribute()\n\t{\n\t\t$attributeSet = array(\t'val' => 100,\n\t\t\t\t\t\t\t\t'maxVal' => 200\n\t\t\t\t\t\t\t );\n\n\t\t$this->_testAutoFilterColumnObject->setAttributes($attributeSet);\n\n\t\tforeach($attributeSet as $attributeName => $attributeValue) {\n\t\t\t$result = $this->_testAutoFilterColumnObject->getAttribute($attributeName);\n\t\t\t$this->assertEquals($attributeValue, $result);\n\t\t}\n\t\t$result = $this->_testAutoFilterColumnObject->getAttribute('nonExistentAttribute');\n\t\t$this->assertNull($result);\n\t}\n\n\tpublic function testClone()\n\t{\n\t\t$result = clone $this->_testAutoFilterColumnObject;\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Worksheet/AutoFilterTest.php",
    "content": "<?php\n\n\nclass AutoFilterTest extends PHPUnit_Framework_TestCase\n{\n\tprivate $_testInitialRange = 'H2:O256';\n\n\tprivate $_testAutoFilterObject;\n\n\n    public function setUp()\n    {\n        if (!defined('PHPEXCEL_ROOT')) {\n            define('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n        }\n        require_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\n        $this->_mockWorksheetObject = $this->getMockBuilder('PHPExcel_Worksheet')\n        \t->disableOriginalConstructor()\n        \t->getMock();\n        $this->_mockCacheController = $this->getMockBuilder('PHPExcel_CachedObjectStorage_Memory')\n        \t->disableOriginalConstructor()\n        \t->getMock();\n        $this->_mockWorksheetObject->expects($this->any())\n            ->method('getCellCacheController')\n            ->will($this->returnValue($this->_mockCacheController));\n\n\t\t$this->_testAutoFilterObject = new PHPExcel_Worksheet_AutoFilter(\n\t\t\t$this->_testInitialRange,\n\t\t\t$this->_mockWorksheetObject\n\t\t);\n    }\n\n\tpublic function testToString()\n\t{\n\t\t$expectedResult = $this->_testInitialRange;\n\n\t\t//\tmagic __toString should return the active autofilter range\n\t\t$result = $this->_testAutoFilterObject;\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testGetParent()\n\t{\n\t\t$result = $this->_testAutoFilterObject->getParent();\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet', $result);\n\t}\n\n\tpublic function testSetParent()\n\t{\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterObject->setParent($this->_mockWorksheetObject);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result);\n\t}\n\n\tpublic function testGetRange()\n\t{\n\t\t$expectedResult = $this->_testInitialRange;\n\n\t\t//\tResult should be the active autofilter range\n\t\t$result = $this->_testAutoFilterObject->getRange();\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n\tpublic function testSetRange()\n\t{\n\t\t$ranges = array('G1:J512' => 'Worksheet1!G1:J512',\n\t\t\t\t\t\t'K1:N20' => 'K1:N20'\n\t\t\t\t\t   );\n\n\t\tforeach($ranges as $actualRange => $fullRange) {\n\t\t\t//\tSetters return the instance to implement the fluent interface\n\t\t\t$result = $this->_testAutoFilterObject->setRange($fullRange);\n\t\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result);\n\n\t\t\t//\tResult should be the new autofilter range\n\t\t\t$result = $this->_testAutoFilterObject->getRange();\n\t\t\t$this->assertEquals($actualRange, $result);\n\t\t}\n\t}\n\n\tpublic function testClearRange()\n\t{\n\t\t$expectedResult = '';\n\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterObject->setRange();\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result);\n\n\t\t//\tResult should be a clear range\n\t\t$result = $this->_testAutoFilterObject->getRange();\n\t\t$this->assertEquals($expectedResult, $result);\n\t}\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n\tpublic function testSetRangeInvalidRange()\n\t{\n\t\t$expectedResult = 'A1';\n\n\t\t$result = $this->_testAutoFilterObject->setRange($expectedResult);\n\t}\n\n\tpublic function testGetColumnsEmpty()\n\t{\n\t\t//\tThere should be no columns yet defined\n\t\t$result = $this->_testAutoFilterObject->getColumns();\n\t\t$this->assertInternalType('array', $result);\n\t\t$this->assertEquals(0, count($result));\n\t}\n\n\tpublic function testGetColumnOffset()\n\t{\n\t\t$columnIndexes = array(\t'H' => 0,\n\t\t\t\t\t\t\t\t'K' => 3,\n\t\t\t\t\t\t\t\t'M' => 5\n\t\t\t\t\t\t\t  );\n\n\t\t//\tIf we request a specific column by its column ID, we should get an\n\t\t//\tinteger returned representing the column offset within the range\n\t\tforeach($columnIndexes as $columnIndex => $columnOffset) {\n\t\t\t$result = $this->_testAutoFilterObject->getColumnOffset($columnIndex);\n\t\t\t$this->assertEquals($columnOffset, $result);\n\t\t}\n\t}\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n    public function testGetInvalidColumnOffset()\n\t{\n\t\t$invalidColumn = 'G';\n\n\t\t$result = $this->_testAutoFilterObject->getColumnOffset($invalidColumn);\n\t}\n\n\tpublic function testSetColumnWithString()\n\t{\n\t\t$expectedResult = 'L';\n\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterObject->setColumn($expectedResult);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result);\n\n\t\t$result = $this->_testAutoFilterObject->getColumns();\n\t\t//\tResult should be an array of PHPExcel_Worksheet_AutoFilter_Column\n\t\t//\tobjects for each column we set indexed by the column ID\n\t\t$this->assertInternalType('array', $result);\n\t\t$this->assertEquals(1, count($result));\n\t\t$this->assertArrayHasKey($expectedResult,$result);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$expectedResult]);\n\t}\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n    public function testSetInvalidColumnWithString()\n\t{\n\t\t$invalidColumn = 'A';\n\n\t\t$result = $this->_testAutoFilterObject->setColumn($invalidColumn);\n\t}\n\n\tpublic function testSetColumnWithColumnObject()\n\t{\n\t\t$expectedResult = 'M';\n\t\t$columnObject = new PHPExcel_Worksheet_AutoFilter_Column($expectedResult);\n\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterObject->setColumn($columnObject);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result);\n\n\t\t$result = $this->_testAutoFilterObject->getColumns();\n\t\t//\tResult should be an array of PHPExcel_Worksheet_AutoFilter_Column\n\t\t//\tobjects for each column we set indexed by the column ID\n\t\t$this->assertInternalType('array', $result);\n\t\t$this->assertEquals(1, count($result));\n\t\t$this->assertArrayHasKey($expectedResult,$result);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$expectedResult]);\n\t}\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n    public function testSetInvalidColumnWithObject()\n\t{\n\t\t$invalidColumn = 'E';\n\t\t$columnObject = new PHPExcel_Worksheet_AutoFilter_Column($invalidColumn);\n\n\t\t$result = $this->_testAutoFilterObject->setColumn($invalidColumn);\n\t}\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n    public function testSetColumnWithInvalidDataType()\n\t{\n\t\t$invalidColumn = 123.456;\n\t\t$columnObject = new PHPExcel_Worksheet_AutoFilter_Column($invalidColumn);\n\n\t\t$result = $this->_testAutoFilterObject->setColumn($invalidColumn);\n\t}\n\n\tpublic function testGetColumns()\n\t{\n\t\t$columnIndexes = array('L','M');\n\n\t\tforeach($columnIndexes as $columnIndex) {\n\t\t\t$this->_testAutoFilterObject->setColumn($columnIndex);\n\t\t}\n\n\t\t$result = $this->_testAutoFilterObject->getColumns();\n\t\t//\tResult should be an array of PHPExcel_Worksheet_AutoFilter_Column\n\t\t//\tobjects for each column we set indexed by the column ID\n\t\t$this->assertInternalType('array', $result);\n\t\t$this->assertEquals(count($columnIndexes), count($result));\n\t\tforeach($columnIndexes as $columnIndex) {\n\t\t\t$this->assertArrayHasKey($columnIndex,$result);\n\t\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result[$columnIndex]);\n\t\t}\n\t}\n\n\tpublic function testGetColumn()\n\t{\n\t\t$columnIndexes = array('L','M');\n\n\t\tforeach($columnIndexes as $columnIndex) {\n\t\t\t$this->_testAutoFilterObject->setColumn($columnIndex);\n\t\t}\n\n\t\t//\tIf we request a specific column by its column ID, we should\n\t\t//\tget a PHPExcel_Worksheet_AutoFilter_Column object returned\n\t\tforeach($columnIndexes as $columnIndex) {\n\t\t\t$result = $this->_testAutoFilterObject->getColumn($columnIndex);\n\t\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result);\n\t\t}\n\t}\n\n\tpublic function testGetColumnByOffset()\n\t{\n\t\t$columnIndexes = array(\t0 => 'H',\n\t\t\t\t\t\t\t\t3 => 'K',\n\t\t\t\t\t\t\t\t5 => 'M'\n\t\t\t\t\t\t\t  );\n\n\t\t//\tIf we request a specific column by its offset, we should\n\t\t//\tget a PHPExcel_Worksheet_AutoFilter_Column object returned\n\t\tforeach($columnIndexes as $columnIndex => $columnID) {\n\t\t\t$result = $this->_testAutoFilterObject->getColumnByOffset($columnIndex);\n\t\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result);\n\t\t\t$this->assertEquals($result->getColumnIndex(),$columnID);\n\t\t}\n\t}\n\n\tpublic function testGetColumnIfNotSet()\n\t{\n\t\t//\tIf we request a specific column by its column ID, we should\n\t\t//\tget a PHPExcel_Worksheet_AutoFilter_Column object returned\n\t\t$result = $this->_testAutoFilterObject->getColumn('K');\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter_Column', $result);\n\t}\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n\tpublic function testGetColumnWithoutRangeSet()\n\t{\n\t\t//\tClear the range\n\t\t$result = $this->_testAutoFilterObject->setRange();\n\n\t\t$result = $this->_testAutoFilterObject->getColumn('A');\n\t}\n\n\tpublic function testClearRangeWithExistingColumns()\n\t{\n\t\t$expectedResult = '';\n\n\t\t$columnIndexes = array('L','M','N');\n\t\tforeach($columnIndexes as $columnIndex) {\n\t\t\t$this->_testAutoFilterObject->setColumn($columnIndex);\n\t\t}\n\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterObject->setRange();\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result);\n\n\t\t//\tRange should be cleared\n\t\t$result = $this->_testAutoFilterObject->getRange();\n\t\t$this->assertEquals($expectedResult, $result);\n\n\t\t//\tColumn array should be cleared\n\t\t$result = $this->_testAutoFilterObject->getColumns();\n\t\t$this->assertInternalType('array', $result);\n\t\t$this->assertEquals(0, count($result));\n\t}\n\n\tpublic function testSetRangeWithExistingColumns()\n\t{\n\t\t$expectedResult = 'G1:J512';\n\n\t\t//\tThese columns should be retained\n\t\t$columnIndexes1 = array('I','J');\n\t\tforeach($columnIndexes1 as $columnIndex) {\n\t\t\t$this->_testAutoFilterObject->setColumn($columnIndex);\n\t\t}\n\t\t//\tThese columns should be discarded\n\t\t$columnIndexes2 = array('K','L','M');\n\t\tforeach($columnIndexes2 as $columnIndex) {\n\t\t\t$this->_testAutoFilterObject->setColumn($columnIndex);\n\t\t}\n\n\t\t//\tSetters return the instance to implement the fluent interface\n\t\t$result = $this->_testAutoFilterObject->setRange($expectedResult);\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result);\n\n\t\t//\tRange should be correctly set\n\t\t$result = $this->_testAutoFilterObject->getRange();\n\t\t$this->assertEquals($expectedResult, $result);\n\n\t\t//\tOnly columns that existed in the original range and that\n\t\t//\t\tstill fall within the new range should be retained\n\t\t$result = $this->_testAutoFilterObject->getColumns();\n\t\t$this->assertInternalType('array', $result);\n\t\t$this->assertEquals(count($columnIndexes1), count($result));\n\t}\n\n\tpublic function testClone()\n\t{\n\t\t$columnIndexes = array('L','M');\n\n\t\tforeach($columnIndexes as $columnIndex) {\n\t\t\t$this->_testAutoFilterObject->setColumn($columnIndex);\n\t\t}\n\n\t\t$result = clone $this->_testAutoFilterObject;\n\t\t$this->assertInstanceOf('PHPExcel_Worksheet_AutoFilter', $result);\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Worksheet/CellCollectionTest.php",
    "content": "<?php\n\nclass CellCollectionTest extends PHPUnit_Framework_TestCase\n{\n\n\tpublic function setUp()\n\t{\n\t\tif (!defined('PHPEXCEL_ROOT'))\n\t\t{\n\t\t\tdefine('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n\t\t}\n\t\trequire_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n\t}\n\n\n\tpublic function testCacheLastCell()\n\t{\n\t\t$methods = PHPExcel_CachedObjectStorageFactory::getCacheStorageMethods();\n\t\tforeach ($methods as $method) {\n\t\t\tPHPExcel_CachedObjectStorageFactory::initialize($method);\n\t\t\t$workbook = new PHPExcel();\n\t\t\t$cells = array('A1', 'A2');\n\t\t\t$worksheet = $workbook->getActiveSheet();\n\t\t\t$worksheet->setCellValue('A1', 1);\n\t\t\t$worksheet->setCellValue('A2', 2);\n\t\t\t$this->assertEquals($cells, $worksheet->getCellCollection(), \"Cache method \\\"$method\\\".\");\n\t\t\tPHPExcel_CachedObjectStorageFactory::finalize();\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Worksheet/ColumnCellIteratorTest.php",
    "content": "<?php\n\nclass ColumnCellIteratorTest extends PHPUnit_Framework_TestCase\n{\n    public $mockWorksheet;\n    public $mockColumnCell;\n\n\tpublic function setUp()\n\t{\n\t\tif (!defined('PHPEXCEL_ROOT')) {\n\t\t\tdefine('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n\t\t}\n\t\trequire_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n        \n        $this->mockCell = $this->getMockBuilder('PHPExcel_Cell')\n            ->disableOriginalConstructor()\n            ->getMock();\n\n        $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet')\n            ->disableOriginalConstructor()\n            ->getMock();\n\n        $this->mockWorksheet->expects($this->any())\n                 ->method('getHighestRow')\n                 ->will($this->returnValue(5));\n        $this->mockWorksheet->expects($this->any())\n                 ->method('getCellByColumnAndRow')\n                 ->will($this->returnValue($this->mockCell));\n    }\n\n\n\tpublic function testIteratorFullRange()\n\t{\n        $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A');\n        $ColumnCellIndexResult = 1;\n        $this->assertEquals($ColumnCellIndexResult, $iterator->key());\n        \n        foreach($iterator as $key => $ColumnCell) {\n            $this->assertEquals($ColumnCellIndexResult++, $key);\n            $this->assertInstanceOf('PHPExcel_Cell', $ColumnCell);\n        }\n\t}\n\n\tpublic function testIteratorStartEndRange()\n\t{\n        $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A', 2, 4);\n        $ColumnCellIndexResult = 2;\n        $this->assertEquals($ColumnCellIndexResult, $iterator->key());\n        \n        foreach($iterator as $key => $ColumnCell) {\n            $this->assertEquals($ColumnCellIndexResult++, $key);\n            $this->assertInstanceOf('PHPExcel_Cell', $ColumnCell);\n        }\n\t}\n\n\tpublic function testIteratorSeekAndPrev()\n\t{\n        $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A', 2, 4);\n        $columnIndexResult = 4;\n        $iterator->seek(4);\n        $this->assertEquals($columnIndexResult, $iterator->key());\n\n        for($i = 1; $i < $columnIndexResult-1; $i++) {\n            $iterator->prev();\n            $this->assertEquals($columnIndexResult - $i, $iterator->key());\n        }\n\t}\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n    public function testSeekOutOfRange()\n    {\n        $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A', 2, 4);\n        $iterator->seek(1);\n    }\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n    public function testPrevOutOfRange()\n    {\n        $iterator = new PHPExcel_Worksheet_ColumnCellIterator($this->mockWorksheet, 'A', 2, 4);\n        $iterator->prev();\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Worksheet/ColumnIteratorTest.php",
    "content": "<?php\n\nclass ColumnIteratorTest extends PHPUnit_Framework_TestCase\n{\n    public $mockWorksheet;\n    public $mockColumn;\n\n\tpublic function setUp()\n\t{\n\t\tif (!defined('PHPEXCEL_ROOT')) {\n\t\t\tdefine('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n\t\t}\n\t\trequire_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n        \n        $this->mockColumn = $this->getMockBuilder('PHPExcel_Worksheet_Column')\n            ->disableOriginalConstructor()\n            ->getMock();\n\n        $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet')\n            ->disableOriginalConstructor()\n            ->getMock();\n\n        $this->mockWorksheet->expects($this->any())\n                 ->method('getHighestColumn')\n                 ->will($this->returnValue('E'));\n        $this->mockWorksheet->expects($this->any())\n                 ->method('current')\n                 ->will($this->returnValue($this->mockColumn));\n    }\n\n\n\tpublic function testIteratorFullRange()\n\t{\n        $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet);\n        $columnIndexResult = 'A';\n        $this->assertEquals($columnIndexResult, $iterator->key());\n        \n        foreach($iterator as $key => $column) {\n            $this->assertEquals($columnIndexResult++, $key);\n            $this->assertInstanceOf('PHPExcel_Worksheet_Column', $column);\n        }\n\t}\n\n\tpublic function testIteratorStartEndRange()\n\t{\n        $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'B', 'D');\n        $columnIndexResult = 'B';\n        $this->assertEquals($columnIndexResult, $iterator->key());\n        \n        foreach($iterator as $key => $column) {\n            $this->assertEquals($columnIndexResult++, $key);\n            $this->assertInstanceOf('PHPExcel_Worksheet_Column', $column);\n        }\n\t}\n\n\tpublic function testIteratorSeekAndPrev()\n\t{\n        $ranges = range('A','E');\n        $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'B', 'D');\n        $columnIndexResult = 'D';\n        $iterator->seek('D');\n        $this->assertEquals($columnIndexResult, $iterator->key());\n\n        for($i = 1; $i < array_search($columnIndexResult, $ranges); $i++) {\n            $iterator->prev();\n            $expectedResult = $ranges[array_search($columnIndexResult, $ranges) - $i];\n            $this->assertEquals($expectedResult, $iterator->key());\n        }\n\t}\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n    public function testSeekOutOfRange()\n    {\n        $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'B', 'D');\n        $iterator->seek('A');\n    }\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n    public function testPrevOutOfRange()\n    {\n        $iterator = new PHPExcel_Worksheet_ColumnIterator($this->mockWorksheet, 'B', 'D');\n        $iterator->prev();\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Worksheet/RowCellIteratorTest.php",
    "content": "<?php\n\nclass RowCellIteratorTest extends PHPUnit_Framework_TestCase\n{\n    public $mockWorksheet;\n    public $mockRowCell;\n\n\tpublic function setUp()\n\t{\n\t\tif (!defined('PHPEXCEL_ROOT')) {\n\t\t\tdefine('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n\t\t}\n\t\trequire_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n        \n        $this->mockCell = $this->getMockBuilder('PHPExcel_Cell')\n            ->disableOriginalConstructor()\n            ->getMock();\n\n        $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet')\n            ->disableOriginalConstructor()\n            ->getMock();\n\n        $this->mockWorksheet->expects($this->any())\n                 ->method('getHighestColumn')\n                 ->will($this->returnValue('E'));\n        $this->mockWorksheet->expects($this->any())\n                 ->method('getCellByColumnAndRow')\n                 ->will($this->returnValue($this->mockCell));\n    }\n\n\n\tpublic function testIteratorFullRange()\n\t{\n        $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet);\n        $RowCellIndexResult = 'A';\n        $this->assertEquals($RowCellIndexResult, $iterator->key());\n        \n        foreach($iterator as $key => $RowCell) {\n            $this->assertEquals($RowCellIndexResult++, $key);\n            $this->assertInstanceOf('PHPExcel_Cell', $RowCell);\n        }\n\t}\n\n\tpublic function testIteratorStartEndRange()\n\t{\n        $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet, 2, 'B', 'D');\n        $RowCellIndexResult = 'B';\n        $this->assertEquals($RowCellIndexResult, $iterator->key());\n        \n        foreach($iterator as $key => $RowCell) {\n            $this->assertEquals($RowCellIndexResult++, $key);\n            $this->assertInstanceOf('PHPExcel_Cell', $RowCell);\n        }\n\t}\n\n\tpublic function testIteratorSeekAndPrev()\n\t{\n        $ranges = range('A','E');\n        $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet, 2, 'B', 'D');\n        $RowCellIndexResult = 'D';\n        $iterator->seek('D');\n        $this->assertEquals($RowCellIndexResult, $iterator->key());\n\n        for($i = 1; $i < array_search($RowCellIndexResult, $ranges); $i++) {\n            $iterator->prev();\n            $expectedResult = $ranges[array_search($RowCellIndexResult, $ranges) - $i];\n            $this->assertEquals($expectedResult, $iterator->key());\n        }\n\t}\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n    public function testSeekOutOfRange()\n    {\n        $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet, 2, 'B', 'D');\n        $iterator->seek(1);\n    }\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n    public function testPrevOutOfRange()\n    {\n        $iterator = new PHPExcel_Worksheet_RowCellIterator($this->mockWorksheet, 2, 'B', 'D');\n        $iterator->prev();\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Worksheet/RowIteratorTest.php",
    "content": "<?php\n\nclass RowIteratorTest extends PHPUnit_Framework_TestCase\n{\n    public $mockWorksheet;\n    public $mockRow;\n\n\tpublic function setUp()\n\t{\n\t\tif (!defined('PHPEXCEL_ROOT')) {\n\t\t\tdefine('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n\t\t}\n\t\trequire_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n        \n        $this->mockRow = $this->getMockBuilder('PHPExcel_Worksheet_Row')\n            ->disableOriginalConstructor()\n            ->getMock();\n\n        $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet')\n            ->disableOriginalConstructor()\n            ->getMock();\n\n        $this->mockWorksheet->expects($this->any())\n                 ->method('getHighestRow')\n                 ->will($this->returnValue(5));\n        $this->mockWorksheet->expects($this->any())\n                 ->method('current')\n                 ->will($this->returnValue($this->mockRow));\n    }\n\n\n\tpublic function testIteratorFullRange()\n\t{\n        $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet);\n        $rowIndexResult = 1;\n        $this->assertEquals($rowIndexResult, $iterator->key());\n        \n        foreach($iterator as $key => $row) {\n            $this->assertEquals($rowIndexResult++, $key);\n            $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row);\n        }\n\t}\n\n\tpublic function testIteratorStartEndRange()\n\t{\n        $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4);\n        $rowIndexResult = 2;\n        $this->assertEquals($rowIndexResult, $iterator->key());\n        \n        foreach($iterator as $key => $row) {\n            $this->assertEquals($rowIndexResult++, $key);\n            $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row);\n        }\n\t}\n\n\tpublic function testIteratorSeekAndPrev()\n\t{\n        $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4);\n        $columnIndexResult = 4;\n        $iterator->seek(4);\n        $this->assertEquals($columnIndexResult, $iterator->key());\n\n        for($i = 1; $i < $columnIndexResult-1; $i++) {\n            $iterator->prev();\n            $this->assertEquals($columnIndexResult - $i, $iterator->key());\n        }\n\t}\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n    public function testSeekOutOfRange()\n    {\n        $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4);\n        $iterator->seek(1);\n    }\n\n    /**\n     * @expectedException PHPExcel_Exception\n     */\n    public function testPrevOutOfRange()\n    {\n        $iterator = new PHPExcel_Worksheet_RowIterator($this->mockWorksheet, 2, 4);\n        $iterator->prev();\n    }\n\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Worksheet/WorksheetColumnTest.php",
    "content": "<?php\n\nclass WorksheetColumnTest extends PHPUnit_Framework_TestCase\n{\n    public $mockWorksheet;\n    public $mockColumn;\n\n\tpublic function setUp()\n\t{\n\t\tif (!defined('PHPEXCEL_ROOT')) {\n\t\t\tdefine('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n\t\t}\n\t\trequire_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n        \n        $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet')\n            ->disableOriginalConstructor()\n            ->getMock();\n        $this->mockWorksheet->expects($this->any())\n                 ->method('getHighestRow')\n                 ->will($this->returnValue(5));\n    }\n\n\n\tpublic function testInstantiateColumnDefault()\n\t{\n        $column = new PHPExcel_Worksheet_Column($this->mockWorksheet);\n        $this->assertInstanceOf('PHPExcel_Worksheet_Column', $column);\n        $columnIndex = $column->getColumnIndex();\n        $this->assertEquals('A', $columnIndex);\n\t}\n\n\tpublic function testInstantiateColumnSpecified()\n\t{\n        $column = new PHPExcel_Worksheet_Column($this->mockWorksheet, 'E');\n        $this->assertInstanceOf('PHPExcel_Worksheet_Column', $column);\n        $columnIndex = $column->getColumnIndex();\n        $this->assertEquals('E', $columnIndex);\n\t}\n\n\tpublic function testGetCellIterator()\n\t{\n        $column = new PHPExcel_Worksheet_Column($this->mockWorksheet);\n        $cellIterator = $column->getCellIterator();\n        $this->assertInstanceOf('PHPExcel_Worksheet_ColumnCellIterator', $cellIterator);\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/Classes/PHPExcel/Worksheet/WorksheetRowTest.php",
    "content": "<?php\n\nclass WorksheetRowTest extends PHPUnit_Framework_TestCase\n{\n    public $mockWorksheet;\n    public $mockRow;\n\n\tpublic function setUp()\n\t{\n\t\tif (!defined('PHPEXCEL_ROOT')) {\n\t\t\tdefine('PHPEXCEL_ROOT', APPLICATION_PATH . '/');\n\t\t}\n\t\trequire_once(PHPEXCEL_ROOT . 'PHPExcel/Autoloader.php');\n        \n        $this->mockWorksheet = $this->getMockBuilder('PHPExcel_Worksheet')\n            ->disableOriginalConstructor()\n            ->getMock();\n        $this->mockWorksheet->expects($this->any())\n                 ->method('getHighestColumn')\n                 ->will($this->returnValue('E'));\n    }\n\n\n\tpublic function testInstantiateRowDefault()\n\t{\n        $row = new PHPExcel_Worksheet_Row($this->mockWorksheet);\n        $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row);\n        $rowIndex = $row->getRowIndex();\n        $this->assertEquals(1, $rowIndex);\n\t}\n\n\tpublic function testInstantiateRowSpecified()\n\t{\n        $row = new PHPExcel_Worksheet_Row($this->mockWorksheet, 5);\n        $this->assertInstanceOf('PHPExcel_Worksheet_Row', $row);\n        $rowIndex = $row->getRowIndex();\n        $this->assertEquals(5, $rowIndex);\n\t}\n\n\tpublic function testGetCellIterator()\n\t{\n        $row = new PHPExcel_Worksheet_Row($this->mockWorksheet);\n        $cellIterator = $row->getCellIterator();\n        $this->assertInstanceOf('PHPExcel_Worksheet_RowCellIterator', $cellIterator);\n\t}\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/bootstrap.php",
    "content": "<?php\n/**\n * $Id: bootstrap.php 2892 2011-08-14 15:11:50Z markbaker@phpexcel.net $\n *\n * @copyright   Copyright (C) 2011-2014 PHPExcel. All rights reserved.\n * @package     PHPExcel\n * @subpackage  PHPExcel Unit Tests\n * @author      Mark Baker\n */\n\nchdir(dirname(__FILE__));\n\nsetlocale(LC_ALL, 'en_US.utf8');\n\n// PHP 5.3 Compat\ndate_default_timezone_set('Europe/London');\n\n// Define path to application directory\ndefined('APPLICATION_PATH')\n\t|| define('APPLICATION_PATH', realpath(dirname(__FILE__) . '/../Classes'));\n\n// Define path to application tests directory\ndefined('APPLICATION_TESTS_PATH')\n\t|| define('APPLICATION_TESTS_PATH', realpath(dirname(__FILE__) ));\n\n// Define application environment\ndefined('APPLICATION_ENV') || define('APPLICATION_ENV', 'ci');\n\n// Ensure library/ is on include_path\nset_include_path(implode(PATH_SEPARATOR, array(\n\trealpath(APPLICATION_PATH . '/../Classes'),\n\t'./',\n\tdirname(__FILE__),\n\tget_include_path(),\n)));\n\n\n/**\n * @todo Sort out xdebug in vagrant so that this works in all sandboxes\n * For now, it is safer to test for it rather then remove it.\n */\necho \"PHPExcel tests beginning\\n\";\n\nif(extension_loaded('xdebug')) {\n\techo \"Xdebug extension loaded and running\\n\";\n\txdebug_enable();\n} else {\n\techo 'Xdebug not found, you should run the following at the command line: echo \"zend_extension=/usr/lib64/php/modules/xdebug.so\" > /etc/php.d/xdebug.ini' . \"\\n\";\n}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/custom/Complex.php",
    "content": "<?php\r\n\r\nclass Complex {\r\n\r\n\tprivate $realPart = 0;\r\n\tprivate $imaginaryPart = 0;\r\n\tprivate $suffix = NULL;\r\n\r\n\tpublic static function _parseComplex($complexNumber)\r\n\t{\r\n\t\t//\tTest for real number, with no imaginary part\r\n\t\tif (is_numeric($complexNumber))\r\n\t\t\treturn array( $complexNumber, 0, NULL );\r\n\r\n\t\t//\tFix silly human errors\r\n\t\tif (strpos($complexNumber,'+-') !== FALSE)\r\n\t\t\t$complexNumber = str_replace('+-','-',$complexNumber);\r\n\t\tif (strpos($complexNumber,'++') !== FALSE)\r\n\t\t\t$complexNumber = str_replace('++','+',$complexNumber);\r\n\t\tif (strpos($complexNumber,'--') !== FALSE)\r\n\t\t\t$complexNumber = str_replace('--','-',$complexNumber);\r\n\r\n\t\t//\tBasic validation of string, to parse out real and imaginary parts, and any suffix\r\n\t\t$validComplex = preg_match('/^([\\-\\+]?(\\d+\\.?\\d*|\\d*\\.?\\d+)([Ee][\\-\\+]?[0-2]?\\d{1,3})?)([\\-\\+]?(\\d+\\.?\\d*|\\d*\\.?\\d+)([Ee][\\-\\+]?[0-2]?\\d{1,3})?)?(([\\-\\+]?)([ij]?))$/ui',$complexNumber,$complexParts);\r\n\r\n\t\tif (!$validComplex) {\r\n\t\t\t//\tNeither real nor imaginary part, so test to see if we actually have a suffix\r\n\t\t\t$validComplex = preg_match('/^([\\-\\+]?)([ij])$/ui',$complexNumber,$complexParts);\r\n\t\t\tif (!$validComplex) {\r\n\t\t\t\tthrow new Exception('COMPLEX: Invalid complex number');\r\n\t\t\t}\r\n\t\t\t//\tWe have a suffix, so set the real to 0, the imaginary to either 1 or -1 (as defined by the sign)\r\n\t\t\t$imaginary = 1;\r\n\t\t\tif ($complexParts[1] === '-') {\r\n\t\t\t\t$imaginary = 0 - $imaginary;\r\n\t\t\t}\r\n\t\t\treturn array(0, $imaginary, $complexParts[2]);\r\n\t\t}\r\n\r\n\t\t//\tIf we don't have an imaginary part, identify whether it should be +1 or -1...\r\n\t\tif (($complexParts[4] === '') && ($complexParts[9] !== '')) {\r\n\t\t\tif ($complexParts[7] !== $complexParts[9]) {\r\n\t\t\t\t$complexParts[4] = 1;\r\n\t\t\t\tif ($complexParts[8] === '-') {\r\n\t\t\t\t\t$complexParts[4] = -1;\r\n\t\t\t\t}\r\n\t\t\t//\t... or if we have only the real and no imaginary part (in which case our real should be the imaginary)\r\n\t\t\t} else {\r\n\t\t\t\t$complexParts[4] = $complexParts[1];\r\n\t\t\t\t$complexParts[1] = 0;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t//\tReturn real and imaginary parts and suffix as an array, and set a default suffix if user input lazily\r\n\t\treturn array( $complexParts[1],\r\n\t\t\t\t\t  $complexParts[4],\r\n\t\t\t\t\t  !empty($complexParts[9]) ? $complexParts[9] : 'i'\r\n\t\t\t\t\t);\r\n\t}\t//\tfunction _parseComplex()\r\n\r\n\r\n\tpublic function __construct($realPart, $imaginaryPart = null, $suffix = 'i')\r\n\t{\r\n\t\tif ($imaginaryPart === null) {\r\n\t\t\tif (is_array($realPart)) {\r\n\t\t\t\t//\tWe have an array of (potentially) real and imaginary parts, and any suffix\r\n\t\t\t\tlist ($realPart, $imaginaryPart, $suffix) = array_values($realPart) + array(0.0, 0.0, 'i');\r\n\t\t\t} elseif((is_string($realPart)) || (is_numeric($realPart))) {\r\n\t\t\t\t//\tWe've been given a string to parse to extract the real and imaginary parts, and any suffix\r\n\t\t\t\tlist ($realPart, $imaginaryPart, $suffix) = self::_parseComplex($realPart);\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\t//\tSet parsed values in our properties\r\n\t\t$this->realPart = (float) $realPart;\r\n\t\t$this->imaginaryPart = (float) $imaginaryPart;\r\n\t\t$this->suffix = strtolower($suffix);\r\n\t}\r\n\r\n\tpublic function getReal()\r\n\t{\r\n\t\treturn $this->realPart;\r\n\t}\r\n\r\n\tpublic function getImaginary()\r\n\t{\r\n\t\treturn $this->imaginaryPart;\r\n\t}\r\n\r\n\tpublic function getSuffix()\r\n\t{\r\n\t\treturn $this->suffix;\r\n\t}\r\n\r\n\tpublic function __toString() {\r\n\t\t$str = \"\";\r\n\t\tif ($this->imaginaryPart != 0.0) {\r\n\t\t\tif (abs($this->imaginaryPart) != 1.0) {\r\n\t\t\t\t$str .= $this->imaginaryPart . $this->suffix;\r\n\t\t\t} else {\r\n\t\t\t\t$str .= (($this->imaginaryPart < 0.0) ? '-' : ''). $this->suffix;\r\n\t\t\t}\r\n\t\t}\r\n\t\tif ($this->realPart != 0.0) {\r\n\t\t\tif (($str) && ($this->imaginaryPart > 0.0))\r\n\t\t\t\t$str = \"+\" . $str;\r\n\t\t\t$str = $this->realPart . $str;\r\n\t\t}\r\n\t\tif (!$str)\r\n\t\t\t$str = \"0.0\";\r\n\t\treturn $str;\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/custom/complexAssert.php",
    "content": "<?php\r\n\r\ninclude_once dirname(__FILE__).'/Complex.php';\r\n\r\n\r\nclass complexAssert {\r\n\r\n\tprivate $_errorMessage\t= '';\r\n\r\n    public function assertComplexEquals($expected, $actual, $delta = 0)\r\n    {\r\n\t\tif ($expected{0} === '#') {\r\n\t\t\t//\tExpecting an error, so we do a straight string comparison\r\n\t\t\tif ($expected === $actual) {\r\n\t\t\t\treturn TRUE;\r\n\t\t\t}\r\n\t\t\t$this->_errorMessage = 'Expected Error: ' .\r\n\t\t\t                       $actual . ' !== ' . $expected;\r\n            return FALSE;\r\n\t\t}\r\n\r\n        $expectedComplex = new Complex($expected);\r\n        $actualComplex = new Complex($actual);\r\n\r\n\t\tif (!is_numeric($actualComplex->getReal()) || !is_numeric($expectedComplex->getReal())) {\r\n\t\t\tif ($actualComplex->getReal() !== $expectedComplex->getReal()) {\r\n\t\t\t\t$this->_errorMessage = 'Mismatched String: ' .\r\n\t\t\t\t                       $actualComplex->getReal() . ' !== ' . $expectedComplex->getReal();\r\n\t            return FALSE;\r\n\t\t\t}\r\n\t\t\treturn TRUE;\r\n\t\t}\r\n\r\n        if ($actualComplex->getReal() < ($expectedComplex->getReal() - $delta) ||\r\n            $actualComplex->getReal() > ($expectedComplex->getReal() + $delta)) {\r\n\t\t\t$this->_errorMessage = 'Mismatched Real part: ' .\r\n\t\t\t                       $actualComplex->getReal() . ' != ' . $expectedComplex->getReal();\r\n            return FALSE;\r\n        }\r\n\r\n        if ($actualComplex->getImaginary() < ($expectedComplex->getImaginary() - $delta) ||\r\n            $actualComplex->getImaginary() > ($expectedComplex->getImaginary() + $delta)) {\r\n\t\t\t$this->_errorMessage = 'Mismatched Imaginary part: ' .\r\n\t\t\t                       $actualComplex->getImaginary() . ' != ' . $expectedComplex->getImaginary();\r\n            return FALSE;\r\n        }\r\n\r\n        if ($actualComplex->getSuffix() !== $actualComplex->getSuffix()) {\r\n\t\t\t$this->_errorMessage = 'Mismatched Suffix: ' .\r\n\t\t\t                       $actualComplex->getSuffix() . ' != ' . $expectedComplex->getSuffix();\r\n            return FALSE;\r\n\t\t}\r\n\r\n        return TRUE;\r\n    }\r\n\r\n\r\n\tpublic function getErrorMessage() {\r\n\t\treturn $this->_errorMessage;\r\n\t}\r\n\r\n}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/phpunit-cc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \r\n<phpunit bootstrap=\"./bootstrap.php\"\r\n    backupGlobals=\"true\"\r\n    colors=\"true\" \r\n    convertErrorsToExceptions=\"true\" \r\n    convertNoticesToExceptions=\"true\" \r\n    convertWarningsToExceptions=\"true\" \r\n    processIsolation=\"false\" \r\n    syntaxCheck=\"true\" \r\n    verbose=\"true\" \r\n    strict=\"true\"\r\n    stopOnError=\"false\"\r\n    stopOnFailure=\"false\"\r\n    stopOnIncomplete=\"false\"\r\n    stopOnSkipped=\"false\">\r\n    <php>\r\n        <ini name=\"memory_limit\" value=\"2048M\"/>\r\n    </php>\r\n    <testsuite name=\"PHPExcel Unit Test Suite\">\r\n        <directory suffix=\"Test.php\">./Classes</directory>\r\n    </testsuite>\r\n    <filter>\r\n        <whitelist>\r\n            <directory suffix=\".php\">../Classes</directory>\r\n            <exclude>\r\n                <directory>../Classes/PHPExcel/Shared/PCLZip</directory>\r\n                <directory>../Classes/PHPExcel/Shared/JAMA</directory>\r\n                <directory>../Classes/PHPExcel/Writer/PDF</directory>\r\n            </exclude>\r\n        </whitelist>\r\n    </filter>\r\n    <logging>\r\n        <log type=\"coverage-html\" target=\"./codeCoverage\" charset=\"UTF-8\"\r\n             yui=\"true\" highlight=\"false\"\r\n             lowUpperBound=\"35\" highLowerBound=\"70\"/>\r\n        <log type=\"coverage-clover\" target=\"./codeCoverage/codeCoverage.xml\"/>\r\n        <log type=\"metrics-xml\" target=\"./metrics/metrics.xml\"/>\r\n        <log type=\"test-xml\" target=\"./testResults/logfile.xml\" logIncompleteSkipped=\"false\"/>\r\n    </logging>\r\n</phpunit> \r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/phpunit.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \r\n<phpunit bootstrap=\"./bootstrap.php\"\r\n    backupGlobals=\"true\"\r\n    colors=\"true\" \r\n    convertErrorsToExceptions=\"true\" \r\n    convertNoticesToExceptions=\"true\" \r\n    convertWarningsToExceptions=\"true\" \r\n    processIsolation=\"false\" \r\n    syntaxCheck=\"true\" \r\n    verbose=\"true\" \r\n    strict=\"true\"\r\n    stopOnError=\"false\"\r\n    stopOnFailure=\"false\"\r\n    stopOnIncomplete=\"false\"\r\n    stopOnSkipped=\"false\">\r\n    <php>\r\n        <ini name=\"memory_limit\" value=\"2048M\"/>\r\n    </php>\r\n    <testsuite name=\"PHPExcel Unit Test Suite\">\r\n        <directory suffix=\"Test.php\">./Classes</directory>\r\n    </testsuite>\r\n    <filter>\r\n        <whitelist>\r\n            <directory suffix=\".php\">../Classes</directory>\r\n            <exclude>\r\n                <directory>../Classes/PHPExcel/Shared/PCLZip</directory>\r\n                <directory>../Classes/PHPExcel/Shared/JAMA</directory>\r\n                <directory>../Classes/PHPExcel/Writer/PDF</directory>\r\n            </exclude>\r\n        </whitelist>\r\n    </filter>\r\n</phpunit> \r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/DATE.data",
    "content": "# Year\tMonth\tDay\t\tResult\t\tComments\r\n18,\t11,\t11,\t\t6890\r\n1900,\t1,\t1,\t\t1\t\t//\tExcel 1900 Calendar Base Date\r\n1900,\t2,\t28,\t\t59\t\t//\tDay before Excel mythical 1900 leap day\r\n1900,\t2,\t29,\t\t60\t\t//\tExcel mythical 1900 leap day\r\n1900,\t3,\t1,\t\t61\t\t//\tDay after Excel mythical 1900 leap day\r\n1901,\t12,\t13,\t\t713\t\t//\tDay after Excel mythical 1900 leap day\r\n1901,\t12,\t14,\t\t714\t\t//\tPHP 32-bit Earliest Date\r\n1903,\t12,\t31,\t\t1461\r\n1904,\t1,\t1,\t\t1462\t\t//\tExcel 1904 Calendar Base Date\r\n1904,\t1,\t2,\t\t1463\r\n1960,\t12,\t19,\t\t22269\r\n1970,\t1,\t1,\t\t25569\t\t//\tPHP Base Date\r\n1982,\t12,\t7,\t\t30292\r\n2008,\t6,\t12,\t\t39611\r\n2038,\t1,\t19,\t\t50424\t\t//\tPHP 32-bit Latest Date\r\n2038,\t1,\t20,\t\t50425\t\t//\tDay after PHP 32-bit Latest Date\r\n2008,\t1,\t1,\t\t39448\r\n2008,\t1,\t,\t\t39447\r\n2008,\t1,\t-1,\t\t39446\r\n2008,\t1,\t-30,\t\t39417\r\n2008,\t1,\t-31,\t\t39416\r\n2008,\t1,\t-365,\t\t39082\r\n2008,\t3,\t1,\t\t39508\r\n2008,\t3,\t,\t\t39507\r\n2008,\t3,\t-1,\t\t39506\r\n2008,\t3,\t-365,\t\t39142\r\n2008,\t,\t1,\t\t39417\r\n2008,\t-1,\t1,\t\t39387\r\n2008,\t-11,\t1,\t\t39083\r\n2008,\t-12,\t1,\t\t39052\r\n2008,\t-13,\t1,\t\t39022\r\n2008,\t-13,\t30,\t\t39051\r\n2008,\t-13,\t,\t\t39021\r\n2008,\t-13,\t-30,\t\t38991\r\n2008,\t-13,\t-31,\t\t38990\r\n2008,\t13,\t1,\t\t39814\r\n2007,\t15,\t,\t\t39507\r\n2008,\t26,\t1,\t\t40210\r\n2008,\t26,\t-10,\t\t40199\r\n2008,\t-26,\t61,\t\t38686\r\n2010,\t-15,\t-50,\t\t39641\r\n2010,\t-15,\t50,\t\t39741\r\n2010,\t15,\t-50,\t\t40552\r\n2010,\t15,\t50,\t\t40652\r\n2010,\t1.5,\t1,\t\t40179\r\n2010,\t1.5,\t0,\t\t40178\r\n2010,\t0,\t1.5,\t\t40148\r\n2010,\t1,\t1.5,\t\t40179\r\n2012,\t6,\t15,\t\t41075\r\n2012,\t6,\t,\t\t41060\r\n2012,\t,\t15,\t\t40892\r\n,\t6,\t15,\t\t167\r\n10,\t6,\t15,\t\t3819\r\n10,\t,\t,\t\t3622\r\n,\t10,\t,\t\t274\r\n,\t,\t10,\t\t\"#NUM!\"\r\n-20,\t,\t,\t\t\"#NUM!\"\r\n-20,\t6,\t15,\t\t\"#NUM!\"\r\n9999,\t12,\t31,\t\t2958465\t\t//\tExcel Maximum Date\r\n10000,\t1,\t1,\t\t\"#NUM!\"\t\t//\tExceeded Excel Maximum Date\r\n2008,\t8,\t10,\t\t39670\r\n2008,\t12,\t31,\t\t39813\r\n2008,\t8,\t32,\t\t39692\r\n2008,\t13,\t31,\t\t39844\r\n2009,\t1,\t0,\t\t39813\r\n2009,\t1,\t-1,\t\t39812\r\n2009,\t0,\t0,\t\t39782\r\n2009,\t0,\t-1,\t\t39781\r\n2009,\t-1,\t0,\t\t39752\r\n2009,\t-1,\t-1,\t\t39751\r\n2010,\t0,\t-1,\t\t40146\r\n2010,\t5,\t31,\t\t40329\r\n2010,\t1,\t'21st',\t\t40199\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n2010,\t\"March\",'21st',\t\t40258\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n2010,\t\"March\",21,\t\t40258\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"ABC\",\t1,\t21,\t\t\"#VALUE!\"\r\n2010,\t\"DEF\",\t21,\t\t\"#VALUE!\"\r\n2010,\t3,\t\"GHI\",\t\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/DATEDIF.data",
    "content": "\"ABC\",\t\t\"2007-1-10\",\t\"Y\",\t\"#VALUE!\"\r\n\"2007-1-1\",\t\"DEF\",\t\t\"Y\",\t\"#VALUE!\"\r\n\"2007-1-1\",\t\"2007-1-10\",\t\"XYZ\",\t\"#VALUE!\"\r\n\"2007-1-10\",\t\"2007-1-1\",\t\"Y\",\t\"#NUM!\"\r\n\"2007-12-31\",\t\"2008-1-10\",\t\"Y\",\t0\r\n\"2007-1-1\",\t\"2007-1-10\",\t\"Y\",\t0\r\n\"2007-1-1\",\t\"2007-1-10\",\t\"M\",\t0\r\n\"2007-1-1\",\t\"2007-1-10\",\t\"D\",\t9\r\n\"2007-1-1\",\t\"2007-1-10\",\t\"YM\",\t0\r\n\"2007-1-1\",\t\"2007-1-10\",\t\"YD\",\t9\r\n\"2007-1-1\",\t\"2007-1-10\",\t\"MD\",\t9\r\n\"2007-1-1\",\t\"2007-12-31\",\t\"Y\",\t0\r\n\"2007-1-1\",\t\"2007-12-31\",\t\"M\",\t11\r\n\"2007-1-1\",\t\"2007-12-31\",\t\"D\",\t364\r\n\"2007-1-1\",\t\"2007-12-31\",\t\"YM\",\t11\r\n\"2007-1-1\",\t\"2007-12-31\",\t\"YD\",\t364\r\n\"2007-1-1\",\t\"2007-12-31\",\t\"MD\",\t30\r\n\"2007-1-1\",\t\"2008-7-1\",\t\"Y\",\t1\r\n\"2007-1-1\",\t\"2008-7-1\",\t\"M\",\t18\r\n\"2007-1-1\",\t\"2008-7-1\",\t\"D\",\t547\r\n\"2007-1-1\",\t\"2008-7-1\",\t\"YM\",\t6\r\n\"2007-1-1\",\t\"2008-7-1\",\t\"YD\",\t181\r\n\"2007-1-1\",\t\"2008-7-1\",\t\"MD\",\t0\r\n\"2007-1-1\",\t\"2007-1-31\",\t\"Y\",\t0\r\n\"2007-1-1\",\t\"2007-1-31\",\t\"M\",\t0\r\n\"2007-1-1\",\t\"2007-1-31\",\t\"D\",\t30\r\n\"2007-1-1\",\t\"2007-1-31\",\t\"YM\",\t0\r\n\"2007-1-1\",\t\"2007-1-31\",\t\"YD\",\t30\r\n\"2007-1-1\",\t\"2007-1-31\",\t\"MD\",\t30\r\n\"2007-1-1\",\t\"2007-2-1\",\t\"Y\",\t0\r\n\"2007-1-1\",\t\"2007-2-1\",\t\"M\",\t1\r\n\"2007-1-1\",\t\"2007-2-1\",\t\"D\",\t31\r\n\"2007-1-1\",\t\"2007-2-1\",\t\"YM\",\t1\r\n\"2007-1-1\",\t\"2007-2-1\",\t\"YD\",\t31\r\n\"2007-1-1\",\t\"2007-2-1\",\t\"MD\",\t0\r\n\"2007-1-1\",\t\"2007-2-28\",\t\"Y\",\t0\r\n\"2007-1-1\",\t\"2007-2-28\",\t\"M\",\t1\r\n\"2007-1-1\",\t\"2007-2-28\",\t\"D\",\t58\r\n\"2007-1-1\",\t\"2007-2-28\",\t\"YM\",\t1\r\n\"2007-1-1\",\t\"2007-2-28\",\t\"YD\",\t58\r\n\"2007-1-1\",\t\"2007-2-28\",\t\"MD\",\t27\r\n\"2007-1-31\",\t\"2007-2-1\",\t\"Y\",\t0\r\n\"2007-1-31\",\t\"2007-2-1\",\t\"M\",\t0\r\n\"2007-1-31\",\t\"2007-2-1\",\t\"D\",\t1\r\n\"2007-1-31\",\t\"2007-2-1\",\t\"YM\",\t0\r\n\"2007-1-31\",\t\"2007-2-1\",\t\"YD\",\t1\r\n\"2007-1-31\",\t\"2007-2-1\",\t\"MD\",\t1\r\n\"2007-1-31\",\t\"2007-3-1\",\t\"Y\",\t0\r\n\"2007-1-31\",\t\"2007-3-1\",\t\"M\",\t1\r\n\"2007-1-31\",\t\"2007-3-1\",\t\"D\",\t29\r\n\"2007-1-31\",\t\"2007-3-1\",\t\"YM\",\t1\r\n\"2007-1-31\",\t\"2007-3-1\",\t\"YD\",\t29\r\n\"2007-1-31\",\t\"2007-3-1\",\t\"MD\",\t-2\r\n\"2007-1-31\",\t\"2007-3-31\",\t\"Y\",\t0\r\n\"2007-1-31\",\t\"2007-3-31\",\t\"M\",\t2\r\n\"2007-1-31\",\t\"2007-3-31\",\t\"D\",\t59\r\n\"2007-1-31\",\t\"2007-3-31\",\t\"YM\",\t2\r\n\"2007-1-31\",\t\"2007-3-31\",\t\"YD\",\t59\r\n\"2007-1-31\",\t\"2007-3-31\",\t\"MD\",\t0\r\n\"2008-1-1\",\t\"2008-9-1\",\t\"Y\",\t0\r\n\"2008-1-1\",\t\"2008-9-1\",\t\"M\",\t8\r\n\"2008-1-1\",\t\"2008-9-1\",\t\"D\",\t244\r\n\"2008-1-1\",\t\"2008-9-1\",\t\"YM\",\t8\r\n\"2008-1-1\",\t\"2008-9-1\",\t\"YD\",\t244\r\n\"2008-1-1\",\t\"2008-9-1\",\t\"MD\",\t0\r\n\"2007-2-1\",\t\"2008-4-1\",\t\"Y\",\t1\r\n\"2007-2-1\",\t\"2008-4-1\",\t\"M\",\t14\r\n\"2007-2-1\",\t\"2008-4-1\",\t\"D\",\t425\r\n\"2007-2-1\",\t\"2008-4-1\",\t\"YM\",\t2\r\n\"2007-2-1\",\t\"2008-4-1\",\t\"YD\",\t59\r\n\"2007-2-1\",\t\"2008-4-1\",\t\"MD\",\t0\r\n\"1960-12-19\",\t\"2008-6-28\",\t\"Y\",\t47\r\n\"1960-12-19\",\t\"2008-6-28\",\t\"M\",\t570\r\n\"1960-12-19\",\t\"2008-6-28\",\t\"D\",\t17358\r\n\"1960-12-19\",\t\"2008-6-28\",\t\"YM\",\t6\r\n\"1960-12-19\",\t\"2008-6-28\",\t\"YD\",\t191\r\n\"1960-12-19\",\t\"2008-6-28\",\t\"MD\",\t9\r\n\"1982-12-7\",\t\"2008-6-28\",\t\"Y\",\t25\r\n\"1982-12-7\",\t\"2008-6-28\",\t\"M\",\t306\r\n\"1982-12-7\",\t\"2008-6-28\",\t\"D\",\t9335\r\n\"1982-12-7\",\t\"2008-6-28\",\t\"YM\",\t6\r\n\"1982-12-7\",\t\"2008-6-28\",\t\"YD\",\t203\r\n\"1982-12-7\",\t\"2008-6-28\",\t\"MD\",\t21\r\n\"2007-12-25\",\t\"2010-3-17\",\t\"Y\",\t2\r\n\"2007-12-25\",\t\"2010-3-17\",\t\"M\",\t26\r\n\"2007-12-25\",\t\"2010-3-17\",\t\"D\",\t813\r\n\"2007-12-25\",\t\"2010-3-17\",\t\"YM\",\t2\r\n\"2007-12-25\",\t\"2010-3-17\",\t\"YD\",\t82\r\n\"2007-12-25\",\t\"2010-3-17\",\t\"MD\",\t20\r\n\"19-12-1960\",\t\"26-01-2012\"\t\"Y\",\t51\r\n\"19-12-1960\",\t\"26-01-2012\"\t\"M\",\t613\r\n\"19-12-1960\",\t\"26-01-2012\"\t\"D\",\t18665\r\n\"19-12-1960\",\t\"26-01-2012\"\t\"YM\",\t1\r\n\"19-12-1960\",\t\"26-01-2012\"\t\"YD\",\t38\r\n\"19-12-1960\",\t\"26-01-2012\"\t\"MD\",\t7\r\n\"19-12-1960\",\t\"12-12-2012\"\t\"Y\",\t50\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/DATEVALUE.data",
    "content": "# Date String\t\t\tResult\r\n\"25-Dec-1899\",\t\t\t\"#VALUE!\"\r\n\"31-Dec-1899\",\t\t\t\"#VALUE!\"\r\n\"1-Jan-1900\",\t\t\t1\r\n\"1900/2/28\",\t\t\t59\r\n\"29-02-1900\",\t\t\t60\r\n\"29th February 1900\",\t\t60\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"1900/3/1\",\t\t\t61\r\n\"13-12-1901\",\t\t\t713\r\n\"14-12-1901\",\t\t\t714\r\n\"1903/12/31\",\t\t\t1461\r\n\"1-Jan-1904\",\t\t\t1462\r\n\"2nd-Jan-1904\",\t\t\t1463\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"19-12-1960\",\t\t\t22269\r\n\"1st January 1970\",\t\t25569\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"7-Dec-1982\",\t\t\t30292\r\n\"1-1-2008\",\t\t\t39448\r\n\"2038-01-19\",\t\t\t50424\r\n\"2-6-2008\",\t\t\t39601\r\n\"December 25th 2008\",\t\t39807\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"1 Jan-2008\",\t\t\t39448\r\n\"12-31-2008\",\t\t\t39813\t\t//\tMS Excel success or failure dependent on country settings\r\n\"31-12-2008\",\t\t\t39813\t\t//\t\tPHPExcel tries to handle both US and UK formats, irrespective of country settings\r\n\"8/22/2008\",\t\t\t39682\t\t//\tMS Excel success or failure dependent on country settings\r\n\"22/8/2008\",\t\t\t39682\t\t//\t\tPHPExcel tries to handle both US and UK formats, irrespective of country settings\r\n\"22/8/08\",\t\t\t39682\r\n\"22-AUG-2008\",\t\t\t39682\r\n\"2008/02/23\",\t\t\t39501\r\n\"6-7-2008\",\t\t\t39635\r\n\"28-2-2007\",\t\t\t39141\t\t//\tMS Excel success or failure dependent on country settings\r\n\"2-28-2007\",\t\t\t39141\t\t//\t\tPHPExcel tries to handle both US and UK formats, irrespective of country settings\r\n\"29-2-2007\",\t\t\t\"#VALUE!\"\t//\tShould fail because it's an invalid date, but PHPExcel currently adjusts to 1-3-2007 - FIX NEEDED\r\n\"1/1/1999\",\t\t\t36161\r\n\"1954-07-20\",\t\t\t19925\r\n\"22 August 98\",\t\t\t36029\r\n\"1st March 2007\",\t\t39142\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"The 1st day of March 2007\",\t\"#VALUE!\"\r\n\"1 Jan\",\t\t\t41275\r\n\"31/12\",\t\t\t41639\r\n\"12/31\",\t\t\t11658\t\t//\tExcel reads as 1st December 1931, not 31st December in current year\r\n\"5-JUL\",\t\t\t41460\r\n\"5 Jul\",\t\t\t41460\r\n\"12/2008\",\t\t\t39783\r\n\"10/32\",\t\t\t11963\r\n11,\t\t\t\t\"#VALUE!\"\r\nTRUE,\t\t\t\t\"#VALUE!\"\r\nFALSE,\t\t\t\t\"#VALUE!\"\r\n1,\t\t\t\t\"#VALUE!\"\r\n12345,\t\t\t\t\"#VALUE!\"\r\n12,\t\t\t\t\"#VALUE!\"\r\n\"12-Feb-2010\",\t\t\t40221\r\n\"Feb-12-2010\",\t\t\t40221\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"February-12-2010\",\t\t40221\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"February 12 2010\",\t\t40221\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"18 Feb 2010\",\t\t\t40227\r\n\"17th 3rd 2010\",\t\t40254\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"Feb 18th 2010\",\t\t40227\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"1st Feb 2010\",\t\t\t40210\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"1st-Feb-2010\",\t\t\t40210\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"1me Fev 2010\",\t\t\t\"#VALUE!\"\r\n\"February 1st 2010\",\t\t40210\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"2nd Feb 2010\",\t\t\t40211\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"Second Feb 2010\",\t\t\"#VALUE!\"\r\n\"First August 2010\",\t\t\"#VALUE!\"\r\n\"1st August 2010\",\t\t40391\t\t//\tMS Excel will fail with a #VALUE return, but PHPExcel can parse this date\r\n\"15:30:25\",\t\t\t0\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/DAY.data",
    "content": "# Date Value\tResult\r\n22269,\t\t19\r\n30348,\t\t1\r\n30843,\t\t10\r\n\"11-Nov-1918\",\t11\r\n\"28-Feb-1904\",\t28\r\n\"Invalid\",\t\"#VALUE!\"\r\n-1,\t\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/DAYS360.data",
    "content": "\"ABC\",\t\t\"2007-1-10\",\tFALSE,\t\"#VALUE!\"\r\n\"2007-1-1\",\t\"DEF\",\t\tTRUE,\t\"#VALUE!\"\r\n\"2007-1-1\",\t\"2007-1-10\",\t\"XYZ\",\t\"#VALUE!\"\r\n\"2007-1-10\",\t\"2007-1-1\",\t\"Y\",\t\"#VALUE!\"\r\n\"2007-1-1\",\t\"2007-1-10\",\tFALSE,\t9\r\n\"2007-1-1\",\t\"2007-1-10\",\tTRUE,\t9\r\n\"2007-1-1\",\t\"2007-12-31\",\tFALSE,\t360\r\n\"2007-1-1\",\t\"2007-12-31\",\tTRUE,\t359\r\n\"2007-1-1\",\t\"2008-7-1\",\tFALSE,\t540\t\r\n\"2007-1-1\",\t\"2008-7-1\",\tTRUE,\t540\t\r\n\"2007-1-1\",\t\"2007-1-31\",\tFALSE,\t30\t\r\n\"2007-1-1\",\t\"2007-1-31\",\tTRUE,\t29\t\r\n\"2007-1-1\",\t\"2007-2-1\",\tFALSE,\t30\t\r\n\"2007-1-1\",\t\"2007-2-1\",\tTRUE,\t30\t\r\n\"2007-1-1\",\t\"2007-2-28\",\tFALSE,\t57\t\r\n\"2007-1-1\",\t\"2007-2-28\",\tTRUE,\t57\t\r\n\"2007-1-31\",\t\"2007-2-1\",\tFALSE,\t1\t\r\n\"2007-1-31\",\t\"2007-2-1\",\tTRUE,\t1\t\r\n\"2007-1-31\",\t\"2007-3-1\",\tFALSE,\t31\t\r\n\"2007-1-31\",\t\"2007-3-1\",\tTRUE,\t31\t\r\n\"2007-1-31\",\t\"2007-3-31\",\tFALSE,\t60\t\r\n\"2007-1-31\",\t\"2007-3-31\",\tTRUE,\t60\t\r\n\"2008-1-1\",\t\"2008-9-1\",\tFALSE,\t240\t\r\n\"2008-1-1\",\t\"2008-9-1\",\tTRUE,\t240\t\r\n\"2007-2-1\",\t\"2008-4-1\",\tFALSE,\t420\t\r\n\"2007-2-1\",\t\"2008-4-1\",\tTRUE,\t420\t\r\n\"1960-12-19\",\t\"2008-6-28\",\tFALSE,\t17109\r\n\"1960-12-19\",\t\"2008-6-28\",\tTRUE,\t17109\r\n\"1982-12-7\",\t\"2008-6-28\",\tFALSE,\t9201\r\n\"1982-12-7\",\t\"2008-6-28\",\tTRUE,\t9201\r\n\"2000-2-28\",\t\"2000-3-31\",\tFALSE,\t33\r\n\"2000-2-28\",\t\"2000-3-31\",\tTRUE,\t32\r\n\"2000-2-29\",\t\"2000-3-31\",\tFALSE,\t30\r\n\"2000-2-29\",\t\"2000-3-31\",\tTRUE,\t31\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/EDATE.data",
    "content": "\"15-Jan-2008\",\t1,\t39493\r\n\"15-Jan-2008\",\t-1,\t39431\r\n\"15-Jan-2008\",\t2,\t39522\r\n\"31-Mar-2007\",\t1,\t39202\r\n\"31-Mar-2007\",\t-1,\t39141\r\n\"31-Mar-2008\",\t-1,\t39507\r\n\"31-Mar-2008\",\t-4,\t39416\r\n\"29-Feb-2008\",\t-12,\t39141\r\n\"15-Mar-2007\",\t3,\t39248\r\n22269.0,\t0,\t22269\r\n22269.0,\t2,\t22331\r\n22269.0,\t110,\t25618\r\n22269.0,\t-110,\t18920\r\n\"15-Mar-2007\",\t\"ABC\",\t\"#VALUE!\"\r\n\"Invalid\",\t12,\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/EOMONTH.data",
    "content": "\"15-Jan-2008\",\t1,\t39507\r\n\"15-Jan-2008\",\t-1,\t39447\r\n\"15-Jan-2008\",\t2,\t39538\r\n\"31-Mar-2007\",\t1,\t39202\r\n\"31-Mar-2007\",\t-1,\t39141\r\n\"31-Mar-2008\",\t-1,\t39507\r\n\"31-Mar-2008\",\t-4,\t39416\r\n\"29-Feb-2008\",\t-12,\t39141\r\n\"15-Mar-2007\",\t3,\t39263\r\n22269.0,\t0,\t22281\r\n22269.0,\t2,\t22340\r\n22269.0,\t110,\t25627\r\n22269.0,\t-110,\t18932\r\n22269.0,\t3,\t22371\r\n22269.0,\t3.75,\t22371\r\n\"15-Mar-2007\",\t\"ABC\",\t\"#VALUE!\"\r\n\"Invalid\",\t12,\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/HOUR.data",
    "content": "0.25,\t\t\t6\r\n0.75,\t\t\t18\r\n0.5,\t\t\t12\r\n0.6,\t\t\t14\r\n\"11-Nov-1918 11:11\",\t11\r\n\"11:59 PM\",\t\t23\r\n\"23:59:59\",\t\t23\r\n3600,\t\t\t2\r\n-3600,\t\t\t0\r\n7200,\t\t\t3\r\n65535,\t\t\t19\r\n\"1 O'Clock\",\t\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/MINUTE.data",
    "content": "0.2,\t\t\t48\r\n0.4,\t\t\t36\r\n0.6,\t\t\t24\r\n0.8,\t\t\t12\r\n\"11-Nov-1918 11:15\",\t15\r\n\"11:59 PM\",\t\t59\r\n\"23:59:59\",\t\t59\r\n3600,\t\t\t0\r\n-3600,\t\t\t0\r\n12500,\t\t\t28\r\n65535,\t\t\t12\r\n\"Half past 1 O'Clock\",\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/MONTH.data",
    "content": ",\t\t1\r\n0,\t\t1\r\n22269.0,\t12\r\n30348.0,\t2\r\n30843.0,\t6\r\n\"11-Nov-1918\",\t11\r\n\"28-Feb-1904\",\t2\r\n\"01 Jul 2003\",\t7\r\n38094,\t\t4\r\n\"Dec 2003\",\t12\r\n-10,\t\t\"#NUM!\"\r\n\"ABCD\",\t\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/NETWORKDAYS.data",
    "content": "\"1-Jan-2007\", \"10-Jan-2007\",\t\t\t\t\t\t\t8\r\n\"18-Jun-2008\", \"20-Jun-2008\",\t\t\t\t\t\t\t3\r\n\"16-Jun-2008\", \"20-Jun-2008\",\t\t\t\t\t\t\t5\r\n\"14-Jun-2008\", \"20-Jun-2008\",\t\t\t\t\t\t\t5\r\n\"20-Jun-2008\", \"20-Jun-2008\",\t\t\t\t\t\t\t1\r\n\"21-Jun-2008\", \"21-Jun-2008\",\t\t\t\t\t\t\t0\r\n\"20-Jun-2008\", \"20-Jun-2008\", \"20-Jun-2008\",\t\t\t\t\t0\r\n\"20-Jun-2008\", \"20-Jun-2008\", \"20-Jun-2008\", \"20-Jun-2008\",\t\t\t0\r\n\"14-Jun-2008\", \"25-Jun-2008\",\t\t\t\t\t\t\t8\r\n\"19-Dec-1960\", \"10-Jan-1961\",\t\t\t\t\t\t\t17\r\n\"10-Jan-1961\", \"19-Dec-1960\",\t\t\t\t\t\t\t-17\r\n\"19-Dec-1960\", \"10-Jan-1961\", \"25-Dec-1960\", \"26-Dec-1960\", \"01-Jan-1961\",\t16\r\n\"10-Jan-1961\", \"19-Dec-1960\", \"25-Dec-1960\", \"26-Dec-1960\", \"01-Jan-1961\",\t-16\r\n\"1-Jan-2007\", \"31-Mar-2007\",\t\t\t\t\t\t\t65\r\n\"1-Jan-2007\", \"31-Jan-2007\",\t\t\t\t\t\t\t23\r\n\"1-Jan-2007\", \"1-Feb-2007\",\t\t\t\t\t\t\t24\r\n\"1-Jan-2007\", \"28-Feb-2007\",\t\t\t\t\t\t\t43\r\n\"31-Jan-2007\", \"1-Feb-2007\",\t\t\t\t\t\t\t2\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/SECOND.data",
    "content": "0.2339930556,\t\t57\r\n0.4202893519,\t\t13\r\n0.6078935185,\t\t22\r\n0.8022106481,\t\t11\r\n\"11-Nov-1918 11:15:35\",\t35\r\n\"11:59 PM\",\t\t0\r\n\"23:59:59\",\t\t59\r\n3600,\t\t\t0\r\n-3601,\t\t\t59\r\n12500,\t\t\t20\r\n65535,\t\t\t15\r\n\"Half past 1 O'Clock\",\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/TIME.data",
    "content": "18,\t11,\t11,\t0.757766203704\r\n6,\t15,\t5,\t0.260474537037\r\n12,\t30,\t10,\t0.520949074074\r\n18,\t45,\t25,\t0.781539351852\r\n15,\t32,\t50,\t0.647800925926\r\n12,\t,\t61,\t0.500706018519\r\n11,\t,\t-1,\t0.458321759259\r\n10,\t,\t-67,\t0.415891203704\r\n13,\t62,\t5,\t0.584780092593\r\n9,\t-80,\t17,\t0.319641203704\r\n8,\t-162,\t,\t0.220833333333\r\n2,\t-120,\t-1,\t\"#NUM!\"\r\n2,\t-120,\t,\t0.000000000000\r\n2,\t-120,\t1,\t0.000011574074\r\n36,\t1,\t2,\t0.500717592593\r\n-1,\t2,\t3,\t\"#NUM!\"\r\n-1,\t61,\t29,\t0.001030092593\r\n-1,\t61,\t-60,\t0.000000000000\r\n\"A\",\t,\t,\t\"#VALUE!\"\r\n11,\t59,\t0,\t0.499305555556\r\n12,\t0,\t0,\t0.500000000000\r\n16,\t48,\t10,\t0.700115740741\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/TIMEVALUE.data",
    "content": "\"12:00:00 am\",\t\t0\r\n\"12:01:02 am\",\t\t0.000717593\r\n\"12:03 pm\",\t\t0.502083333\r\n\"12:7:11 pm\",\t\t0.504988426\r\n\"4:13:39\",\t\t0.176145833\r\n\"6:20:17 pm\",\t\t0.764085648\r\n\"18:33:27\",\t\t0.773229167\r\n\"31/12/2007 03:27:15\",\t0.143923611\r\n\"9:44:55 pm\",\t\t0.90619213\r\n12,\t\t\t\"#VALUE!\"\r\n\"13:01\",\t\t0.542361111\r\n\"33:45\",\t\t0.40625\r\n\"13:01PM\",\t\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/WEEKDAY.data",
    "content": "\"24-Oct-1968\",\t\t5\r\n\"24-Oct-1968\",\t2,\t4\r\n\"24-Oct-1968\",\t3,\t3\r\n\"2000-06-14\",\t\t4\r\n\"2000-06-14\",\t2,\t3\r\n\"2000-06-14\",\t3,\t2\r\n\"1996-07-24\",\t\t4\r\n\"1996-07-24\",\t2,\t3\r\n\"1996-07-24\",\t3,\t2\r\n\"1996-07-27\",\t\t7\r\n\"1996-07-27\",\t2,\t6\r\n\"1996-07-27\",\t3,\t5\r\n\"1977-7-31\",\t\t1\r\n\"1977-7-31\",\t2,\t7\r\n\"1977-7-31\",\t3,\t6\r\n\"1977-8-1\",\t\t2\r\n\"1977-8-1\",\t2,\t1\r\n\"1977-8-1\",\t3,\t0\r\n\"1900-2-5\",\t2,\t7\r\n\"1900-2-1\",\t\t1\r\n38093,\t\t\t6\r\n38093,\t\t2,\t5\r\n38093,\t\t3,\t4\r\n\"3/7/1977\",\t\"A\",\t\"#VALUE!\"\r\n\"3/7/1977\",\t0,\t\"#NUM!\"\r\n\"Invalid\",\t1,\t\"#VALUE!\"\r\n-1,\t\t\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/WEEKNUM.data",
    "content": "\"21-Dec-2000\",\t1,\t52\r\n\"1995-01-01\",\t1,\t1\r\n\"3/7/1977\",\t\t27\r\n\"3/7/1977\",\t\"A\",\t\"#VALUE!\"\r\n\"3/7/1977\",\t0,\t\"#NUM!\"\r\n\"Invalid\",\t1,\t\"#VALUE!\"\r\n-1,\t\t\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/WORKDAY.data",
    "content": "\"1-Jan-2007\",\t\"ABC\",\t\"#VALUE!\"\r\n\"1-Jan-2007\",\t9,\t39094\r\n\"18-Jun-2008\",\t2,\t39619\r\n\"16-Jun-2008\",\t4,\t39619\r\n\"14-Jun-2008\",\t6,\t39622\r\n\"14-Jun-2008\",\t11,\t39629\r\n\"14-Jun-2008\",\t-2,\t39611\r\n\"14-Jun-2008\",\t-6,\t39605\r\n\"19-Dec-2008\",\t10,\t39815\r\n\"19-Dec-2008\",\t10,\t\"25-Dec-2008\",\t\"26-Dec-2008\",\t\"01-Jan-2009\",\t39820\r\n\"19-Dec-2008\",\t10,\t{\"25-Dec-2008\"|\"26-Dec-2008\"|\"01-Jan-2009\"},\t39820\r\n39820,\t\t-10,\t{\"25-Dec-2008\"|\"26-Dec-2008\"|\"01-Jan-2009\"},\t39801\r\n\"5-Apr-2012\",\t3,\t{\"6-Apr-2012\"|\"9-Apr-2012\"},\t\t\t41010\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/YEAR.data",
    "content": ",\t\t1900\r\n1,\t\t1900\r\n33333.33,\t1991\r\n22269.0,\t1960\r\n30348.0,\t1983\r\n30843.0,\t1984\r\n\"01 Jan 2525\",\t2525\r\n\"11-Nov-1918\",\t1918\r\n\"28-Feb-1904\",\t1904\r\n-10,\t\t\"#NUM!\"\r\n\"ABCD\",\t\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/DateTime/YEARFRAC.data",
    "content": "\"2007-1-1\",\t\"2007-1-10\",\t0,\t0.025\r\n\"2007-1-1\",\t\"2007-1-10\",\t1,\t0.02465753424658\r\n\"2007-1-1\",\t\"2007-1-10\",\t2,\t0.025\r\n\"2007-1-1\",\t\"2007-1-10\",\t3,\t0.02465753424658\r\n\"2007-1-1\",\t\"2007-1-10\",\t4,\t0.025\r\n\"2007-1-1\",\t\"2007-12-31\",\t0,\t1.0\r\n\"2007-1-1\",\t\"2007-12-31\",\t1,\t0.99726027397260\r\n\"2007-1-1\",\t\"2007-12-31\",\t2,\t1.01111111111111\r\n\"2007-1-1\",\t\"2007-12-31\",\t3,\t0.99726027397260\r\n\"2007-1-1\",\t\"2007-12-31\",\t4,\t0.99722222222222\r\n\"2007-1-1\",\t\"2008-7-1\",\t0,\t1.5\r\n\"2007-1-1\",\t\"2008-7-1\",\t1,\t1.49658002735978\r\n\"2007-1-1\",\t\"2008-7-1\",\t2,\t1.51944444444444\r\n\"2007-1-1\",\t\"2008-7-1\",\t3,\t1.49863013698630\r\n\"2007-1-1\",\t\"2008-7-1\",\t4,\t1.5\r\n\"2007-1-1\",\t\"2007-1-31\",\t0,\t0.08333333333333\r\n\"2007-1-1\",\t\"2007-1-31\",\t1,\t0.08219178082192\r\n\"2007-1-1\",\t\"2007-1-31\",\t2,\t0.08333333333333\r\n\"2007-1-1\",\t\"2007-1-31\",\t3,\t0.08219178082192\r\n\"2007-1-1\",\t\"2007-1-31\",\t4,\t0.08055555555556\r\n\"2007-1-1\",\t\"2007-2-1\",\t0,\t0.08333333333333\r\n\"2007-1-1\",\t\"2007-2-1\",\t1,\t0.08493150684932\r\n\"2007-1-1\",\t\"2007-2-1\",\t2,\t0.08611111111111\r\n\"2007-1-1\",\t\"2007-2-1\",\t3,\t0.08493150684932\r\n\"2007-1-1\",\t\"2007-2-1\",\t4,\t0.08333333333333\r\n\"2007-1-1\",\t\"2007-2-28\",\t0,\t0.15833333333333\r\n\"2007-1-1\",\t\"2007-2-28\",\t1,\t0.15890410958904\r\n\"2007-1-1\",\t\"2007-2-28\",\t2,\t0.16111111111111\r\n\"2007-1-1\",\t\"2007-2-28\",\t3,\t0.15890410958904\r\n\"2007-1-1\",\t\"2007-2-28\",\t4,\t0.15833333333333\r\n\"2007-1-31\",\t\"2007-2-1\",\t0,\t0.00277777777778\r\n\"2007-1-31\",\t\"2007-2-1\",\t1,\t0.00273972602740\r\n\"2007-1-31\",\t\"2007-2-1\",\t2,\t0.00277777777778\r\n\"2007-1-31\",\t\"2007-2-1\",\t3,\t0.00273972602740\r\n\"2007-1-31\",\t\"2007-2-1\",\t4,\t0.00277777777778\r\n\"2007-1-31\",\t\"2007-3-1\",\t0,\t0.08611111111111\r\n\"2007-1-31\",\t\"2007-3-1\",\t1,\t0.07945205479452\r\n\"2007-1-31\",\t\"2007-3-1\",\t2,\t0.08055555555556\r\n\"2007-1-31\",\t\"2007-3-1\",\t3,\t0.07945205479452\r\n\"2007-1-31\",\t\"2007-3-1\",\t4,\t0.08611111111111\r\n\"2007-1-31\",\t\"2007-3-31\",\t0,\t0.16666666666667\r\n\"2007-1-31\",\t\"2007-3-31\",\t1,\t0.16164383561644\r\n\"2007-1-31\",\t\"2007-3-31\",\t2,\t0.16388888888889\r\n\"2007-1-31\",\t\"2007-3-31\",\t3,\t0.16164383561644\r\n\"2007-1-31\",\t\"2007-3-31\",\t4,\t0.16666666666667\r\n\"2008-1-1\",\t\"2008-9-1\",\t0,\t0.66666666666667\r\n\"2008-1-1\",\t\"2008-9-1\",\t1,\t0.66666666666667\r\n\"2008-1-1\",\t\"2008-9-1\",\t2,\t0.67777777777778\r\n\"2008-1-1\",\t\"2008-9-1\",\t3,\t0.66849315068493\r\n\"2008-1-1\",\t\"2008-9-1\",\t4,\t0.66666666666667\r\n\"2007-2-1\",\t\"2008-4-1\",\t0,\t1.16666666666667\r\n\"2007-2-1\",\t\"2008-4-1\",\t1,\t1.16279069767442\r\n\"2007-2-1\",\t\"2008-4-1\",\t2,\t1.18055555555556\r\n\"2007-2-1\",\t\"2008-4-1\",\t3,\t1.16438356164384\r\n\"2007-2-1\",\t\"2008-4-1\",\t4,\t1.16666666666667\r\n\"1960-12-19\",\t\"2008-6-28\",\t0,\t47.525\r\n\"1960-12-19\",\t\"2008-6-28\",\t1,\t47.52162252765670\r\n\"1960-12-19\",\t\"2008-6-28\",\t2,\t48.21666666666670\r\n\"1960-12-19\",\t\"2008-6-28\",\t3,\t47.55616438356160\r\n\"1960-12-19\",\t\"2008-6-28\",\t4,\t47.525\r\n\"1982-12-7\",\t\"2008-6-28\",\t0,\t25.55833333333330\r\n\"1982-12-7\",\t\"2008-6-28\",\t1,\t25.55718921111340\r\n\"1982-12-7\",\t\"2008-6-28\",\t2,\t25.93055555555560\r\n\"1982-12-7\",\t\"2008-6-28\",\t3,\t25.57534246575340\r\n\"1982-12-7\",\t\"2008-6-28\",\t4,\t25.55833333333330\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/BESSELI.data",
    "content": "1.5,\t-1,\t\"#NUM!\"\r\n-1,\t6,\t2.2488660949282200E-05\r\n0,\t3,\t0.0\r\n3,\t0,\t4.8807925650332900\r\n1,\t5,\t2.7146314958504900E-04\r\n1.5,\t1,\t9.8166642847516600E-01\r\n-1.5,\t2.5,\t3.3783462087443800E-01\r\n-1.5,\t14.99,\t2.1218581758012900E-13\r\n1,\t30,\t3.5395005050254700E-42\r\n2.5,\t1,\t2.5167162420253600\r\n2.5,\t1.5,\t2.5167162420253600\r\n-2.5,\t1.5,\t-2.5167162420253600\r\n3.5,\t1,\t6.2058349320630000\r\n0.7,\t3,\t7.3673733669342700E-03\r\n3.5,\t2,\t3.8320120716293600\r\n35,\t2,\t1.0129348967887200E+14\r\n-35,\t2,\t1.0129348967887200E+14\r\n-35,\t3,\t-9.4217724797020600E+13\r\n-35,\t4,\t8.5141821583727800E+13\r\n1.5,\t\"XYZ\",\t\"#VALUE!\"\r\n\"ABC\",\t3,\t\"#VALUE!\"\r\n-9,\t1,\t-1.0309147086534900E+03\r\n-3.5,\t1,\t-6.2058349320630000\r\n-0.735,\t1,\t-3.9288151661176300E-01\r\n0,\t1,\t0.0\r\n0.035,\t1,\t1.7502679823335300E-02\r\n1,\t1,\t5.6515909758194300E-01\r\n1.5,\t1,\t9.8166642847516600E-01\r\n2.5,\t1,\t2.5167162420253600\r\n3.5,\t1,\t6.2058349320630000\r\n-9,\t2,\t8.6449622063929800E+02\r\n-3.5,\t2,\t3.8320120716293600\r\n-0.735,\t2,\t7.0619941066585700E-02\r\n0,\t2,\t0.0\r\n0.035,\t2,\t1.5314063208086000E-04\r\n0.9,\t2,\t1.0825972222234100E-01\r\n1,\t2,\t1.3574766658069900E-01\r\n1.9,\t2,\t6.0327243548745000E-01\r\n2.5,\t2,\t1.2764661588156100\r\n3.5,\t2,\t3.8320120716293600\r\n4,\t2,\t6.4221894991960900\r\n0.035,\t3,\t8.9329755645604500E-07\r\n0.7,\t3,\t7.3673733669342700E-03\r\n0.89,\t3,\t1.5428502532466100E-02\r\n4,\t3,\t3.3372758428109200\r\n4,\t5,\t5.0472437285149600E-01\r\n1.5,\t7,\t2.8406417355214300E-05\r\n3,\t9,\t1.3237298826652200E-04\r\n-3.5,\t0,\t7.3782034775718600\r\n-1.5,\t0,\t1.6467232021476800\r\n0,\t0,\t1.0\r\n1,\t0,\t1.2660658480342600\r\n1.5,\t0,\t1.6467232021476800\r\n2.5,\t0,\t3.2898391723912900\r\n3.5,\t0,\t7.3782034775718600\r\n-3.5,\t-1,\t\"#NUM!\"\r\nTRUE,\t1,\t\"#VALUE!\"\r\n1,\tTRUE,\t\"#VALUE!\"\r\n21,\t2,\t1.0477785626593200E+08\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/BESSELJ.data",
    "content": "1.5,\t-1,\t\"#NUM!\"\r\n0,\t1,\t0.0\r\n1,\t1,\t4.4005058567713000E-01\r\n1,\t5,\t2.4975773021123400E-04\r\n1.9,\t2,\t3.2992582866978500E-01\r\n-2.5,\t1.5,\t-4.9709410250442200E-01\r\n3.5,\t1,\t1.3737752717818600E-01\r\n0.89,\t3,\t1.3974004027880800E-02\r\n3.5,\t2,\t4.5862918476829000E-01\r\n35,\t2,\t1.2935945082689100E-01\r\n-35,\t2,\t1.2935945082689100E-01\r\n-35,\t3,\t2.9207004782372000E-02\r\n-35,\t4,\t-1.3436636593244100E-01\r\n1.5,\t\"XYZ\",\t\"#VALUE!\"\r\n\"ABC\",\t3,\t\"#VALUE!\"\r\n-3.5,\t1,\t-1.3737752717818600E-01\r\n-0.735,\t1,\t-3.4323577520309400E-01\r\n0,\t1,\t0.0\r\n0.035,\t1,\t1.7497320451918700E-02\r\n1.5,\t1,\t5.5793650789080400E-01\r\n2.5,\t1,\t4.9709410250442200E-01\r\n3.5,\t1,\t1.3737752717818600E-01\r\n-9,\t2,\t1.4484636919412800E-01\r\n-0.735,\t2,\t6.4538955636373900E-02\r\n0,\t2,\t0.0\r\n0.9,\t2,\t9.4586304292255000E-02\r\n1.9,\t2,\t3.2992582866978500E-01\r\n0.035,\t2,\t1.5310936908796500E-04\r\n3.5,\t2,\t4.5862918476829000E-01\r\n4,\t2,\t3.6412814319431200E-01\r\n0.035,\t3,\t8.9316078090293600E-07\r\n0.7,\t3,\t6.9296548267509400E-03\r\n0.89,\t3,\t1.3974004027880800E-02\r\n4,\t3,\t4.3017147115339600E-01\r\n4,\t5,\t1.3208665605594800E-01\r\n1.5,\t7,\t2.4679795788287900E-05\r\n3,\t9,\t8.4395021309091800E-05\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/BESSELK.data",
    "content": "1.5,\t-1,\t\"#NUM!\"\r\n0,\t2,\t\"#NUM!\"\r\n0.1,\t3,\t7.9900124326586500E+03\r\n1,\t0,\t4.2102442108341800E-01\r\n1.5,\t0,\t2.1380556932365400E-01\r\n-1.5,\t2,\t\"#NUM!\"\r\n1.5,\t1,\t2.7738780363225900E-01\r\n1.5,\t2,\t5.8365597416666600E-01\r\n2.3,\t1.5,\t9.4982447142959400E-02\r\n2.5,\t1,\t7.3890815650266900E-02\r\n3.5,\t1,\t2.2239393224640700E-02\r\n3.5,\t3,\t5.9161817991348200E-02\r\n3,\t9,\t3.9795880106238500E+02\r\n3.5,\t2,\t3.2307121670869000E-02\r\n1.5,\t\"XYZ\",\t\"#VALUE!\"\r\n\"ABC\",\t3,\t\"#VALUE!\"\r\n-3.5,\t1,\t\"#NUM!\"\r\n-0.735,\t1,\t\"#NUM!\"\r\n0,\t1,\t\"#NUM!\"\r\n0.035,\t1,\t2.8501970000186900E+01\r\n1.5,\t1,\t2.7738780363225900E-01\r\n2.5,\t1,\t7.3890815650266900E-02\r\n3.5,\t1,\t2.2239393224640700E-02\r\n-9,\t2,\t\"#NUM!\"\r\n-0.735,\t2,\t\"#NUM!\"\r\n0,\t2,\t\"#NUM!\"\r\n0.9,\t2,\t2.0790271301014400\r\n1.9,\t2,\t2.9690930137427500E-01\r\n0.035,\t2,\t1.6321537072931900E+03\r\n3.5,\t2,\t3.2307121670869000E-02\r\n4,\t2,\t1.7401425543547400E-02\r\n0.035,\t3,\t1.8656035423207900E+05\r\n0.7,\t3,\t2.1972168909566600E+01\r\n0.89,\t3,\t1.0317473075007600E+01\r\n4,\t3,\t2.9884924431707800E-02\r\n4,\t5,\t1.5434254881392600E-01\r\n1.5,\t7,\t2.4577004526116700E+03\r\n3,\t9,\t3.9795880106238500E+02\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/BESSELY.data",
    "content": "1.5,\t-1,\t\"#NUM!\"\r\n1.23,\t45.67,\t-2.7027311261175000E+63\r\n2.5,\t0,\t4.9807035844668900E-01\r\n2.5,\t1,\t1.4591813750831300E-01\r\n2.5,\t2,\t-3.8133584844003800E-01\r\n3.5,\t1,\t4.1018841662769800E-01\r\n3.5,\t3,\t-3.5833534643622900E-01\r\n4,\t2,\t2.1590359910699000E-01\r\n3.5,\t2,\t4.5371436417535000E-02\r\n12.5,\t0,\t-1.7121430684466900E-01\r\n12.5,\t1,\t-1.5383825635163900E-01\r\n12.5,\t2,\t1.4660018586805400E-01\r\n12.5,\t22,\t-3.5760343503878700E+02\r\n1.5,\t\"XYZ\",\t\"#VALUE!\"\r\n\"ABC\",\t3,\t\"#VALUE!\"\r\n-3.5,\t1,\t\"#NUM!\"\r\n-0.735,\t1,\t\"#NUM!\"\r\n0,\t1,\t\"#NUM!\"\r\n0.035,\t1,\t-1.8233338940000000E+01\r\n1.5,\t1,\t-4.1230862700000000E-01\r\n2.5,\t1,\t1.4591813800000000E-01\r\n3.5,\t1,\t4.1018841700000000E-01\r\n-9,\t2,\t\"#NUM!\"\r\n-0.735,\t2,\t\"#NUM!\"\r\n0,\t2,\t\"#NUM!\"\r\n0.9,\t2,\t-1.9459096070000000\r\n1.9,\t2,\t-6.6987867400000000E-01\r\n0.035,\t2,\t-1.0396979410000000E+03\r\n3.5,\t2,\t4.5371436000000000E-02\r\n4,\t2,\t2.1590359900000000E-01\r\n0.035,\t3,\t-1.1880438840000000E+05\r\n0.7,\t3,\t-1.5819479070000000E+01\r\n0.89,\t3,\t-8.0204412520000000\r\n4,\t3,\t-1.8202211000000000E-01\r\n4,\t5,\t-7.9585141800000000E-01\r\n1.5,\t7,\t-1.8873970340000000E+03\r\n3,\t9,\t-4.4495950710000000E+02\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/BIN2DEC.data",
    "content": "\"10110010\",\t\"178\"\r\n\"1100100\",\t\"100\"\r\n\"111001010101\",\t\"#NUM!\"\t\t//\tToo large\r\n\"101\",\t\t\"5\"\r\n\"10\",\t\t\"2\"\r\n\"0\",\t\t\"0\"\r\n\"21\",\t\t\"#NUM!\"\t\t//\tInvalid binary number\r\nTRUE,\t\t\"#VALUE!\"\t//\tNon string\r\n\"1110010101\",\t\"-107\"\t\t//\t2's Complement\r\n\"1111111111\",\t\"-1\"\t\t//\t2's Complement\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/BIN2HEX.data",
    "content": "\"10110010\",\t\t\"B2\"\r\n\"111001010101\",\t\t\"#NUM!\"\t\t//\tToo large\r\n\"11111011\",\t4,\t\"00FB\"\t\t//\tLeading places\r\n\"11111011\",\t3.75,\t\"0FB\"\t\t//\tLeading places as a float\r\n\"11111011\",\t-1,\t\"#NUM!\"\t\t//\tLeading places negative\r\n\"11111011\",\t\"ABC\",\t\"#VALUE!\"\t//\tLeading places non-numeric\r\n\"1110\",\t\t\t\"E\"\r\n\"101\",\t\t\t\"5\"\r\n\"10\",\t\t\t\"2\"\r\n\"0\",\t\t\t\"0\"\r\n\"21\",\t\t\t\"#NUM!\"\t\t//\tInvalid binary number\r\nTRUE,\t\t\t\"#VALUE!\"\t//\tNon string\r\n\"1110010101\",\t\t\"FFFFFFFF95\"\t//\t2's Complement\r\n\"1111111111\",\t\t\"FFFFFFFFFF\"\t//\t2's Complement\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/BIN2OCT.data",
    "content": "\"1100100\",\t\t\"144\"\r\n\"10110010\",\t\t\"262\"\r\n\"111001010101\",\t\t\"#NUM!\"\t\t//\tToo large\r\n\"1001\",\t\t3,\t\"011\"\t\t//\tLeading places\r\n\"1001\",\t\t4.75,\t\"0011\"\t\t//\tLeading places as a float\r\n\"1001\",\t\t-1,\t\"#NUM!\"\t\t//\tLeading places negative\r\n\"1001\",\t\t\"ABC\",\t\"#VALUE!\"\t//\tLeading places non-numeric\r\n\"00000010\",\t\t\"2\"\r\n\"00000101\",\t\t\"5\"\r\n\"00001101\",\t\t\"15\"\r\n\"0\",\t\t\t\"0\"\r\n\"21\",\t\t\t\"#NUM!\"\t\t//\tInvalid binary number\r\nTRUE,\t\t\t\"#VALUE!\"\t//\tNon string\r\n\"1110010101\",\t\t\"7777777625\"\t//\t2's Complement\r\n\"1111111111\",\t\t\"7777777777\"\t//\t2's Complement\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/COMPLEX.data",
    "content": "3,\t\t4,\t\t\"3+4i\"\r\n3,\t\t4,\t\"j\",\t\"3+4j\"\r\n12.34,\t\t5.67,\t\"j\",\t\"12.34+5.67j\"\r\n3.5,\t\t\"A\",\t\t\"#VALUE!\"\r\n1.234E-5,\t6.78E9,\t\t\"1.234E-5+6780000000i\"\r\n1.234E5,\t6.78E-9,\t\"123400+6.78E-9i\"\r\n3.5,\t\t2.5,\t\t\"3.5+2.5i\"\r\n3.5,\t\t1,\t\t\"3.5+i\"\r\n3.5,\t\t0,\t\t3.5\r\n3.5,\t\t-1,\t\t\"3.5-i\"\r\n3.5,\t\t-2.5,\t\t\"3.5-2.5i\"\r\n1,\t\t2.5,\t\t\"1+2.5i\"\r\n1,\t\t1,\t\t\"1+i\"\r\n1,\t\t0,\t\t1\r\n1,\t\t-1,\t\t\"1-i\"\r\n1,\t\t-2.5,\t\t\"1-2.5i\"\r\n0,\t\t2.5,\t\t\"2.5i\"\r\n0,\t\t1,\t\t\"i\"\r\n0,\t\t0,\t\t0\r\n0,\t\t-1,\t\t\"-i\"\r\n0,\t\t-2.5,\t\t\"-2.5i\"\r\n-1,\t\t2.5,\t\t\"-1+2.5i\"\r\n-1,\t\t1,\t\t\"-1+i\"\r\n-1,\t\t0,\t\t-1\r\n-1,\t\t-1,\t\t\"-1-i\"\r\n-1,\t\t-2.5,\t\t\"-1-2.5i\"\r\n-3.5,\t\t2.5,\t\t\"-3.5+2.5i\"\r\n-3.5,\t\t1,\t\t\"-3.5+i\"\r\n-3.5,\t\t0,\t\t\"-3.5\"\r\n-3.5,\t\t-1,\t\t\"-3.5-i\"\r\n-3.5,\t\t-2.5,\t\t\"-3.5-2.5i\"\r\n-2.5,\t\t-2.5,\t\t\"-2.5-2.5i\"\r\n-2.5,\t\t-2.5,\t\t\"-2.5-2.5i\"\r\n-1.5,\t\t-2.5,\t\t\"-1.5-2.5i\"\r\n-1.5,\t\t-2.5,\t\t\"-1.5-2.5i\"\r\n-0.5,\t\t-2.5,\t\t\"-0.5-2.5i\"\r\n0,\t\t-2.5,\t\t\"-2.5i\"\r\n0.5,\t\t-2.5,\t\t\"0.5-2.5i\"\r\n1,\t\t-2.5,\t\t\"1-2.5i\"\r\n1.5,\t\t-2.5,\t\t\"1.5-2.5i\"\r\n2,\t\t-2.5,\t\t\"2-2.5i\"\r\n2.5,\t\t-2.5,\t\t\"2.5-2.5i\"\r\n3,\t\t-2.5,\t\t\"3-2.5i\"\r\n3.5,\t\t-2.5,\t\t\"3.5-2.5i\"\r\n-2.5,\t\t-2.5,\t\t\"-2.5-2.5i\"\r\n-2.5,\t\t-2.5,\t\t\"-2.5-2.5i\"\r\n-1.5,\t\t-2.5,\t\t\"-1.5-2.5i\"\r\n-1.5,\t\t-2.5,\t\t\"-1.5-2.5i\"\r\n-0.5,\t\t-2.5,\t\t\"-0.5-2.5i\"\r\n0,\t\t-2.5,\t\t\"-2.5i\"\r\n0.5,\t\t-2.5,\t\t\"0.5-2.5i\"\r\n1,\t\t-2.5,\t\t\"1-2.5i\"\r\n1.5,\t\t-2.5,\t\t\"1.5-2.5i\"\r\n2,\t\t-2.5,\t\t\"2-2.5i\"\r\n2.5,\t\t-2.5,\t\t\"2.5-2.5i\"\r\n3,\t\t-2.5,\t\t\"3-2.5i\"\r\n3.5,\t\t-2.5,\t\t\"3.5-2.5i\"\r\n-2.5,\t\t-1.5,\t\t\"-2.5-1.5i\"\r\n-2.5,\t\t-1.5,\t\t\"-2.5-1.5i\"\r\n-1.5,\t\t-1.5,\t\t\"-1.5-1.5i\"\r\n-1.5,\t\t-1.5,\t\t\"-1.5-1.5i\"\r\n-0.5,\t\t-1.5,\t\t\"-0.5-1.5i\"\r\n0,\t\t-1.5,\t\t\"-1.5i\"\r\n0.5,\t\t-1.5,\t\t\"0.5-1.5i\"\r\n1,\t\t-1.5,\t\t\"1-1.5i\"\r\n1.5,\t\t-1.5,\t\t\"1.5-1.5i\"\r\n2,\t\t-1.5,\t\t\"2-1.5i\"\r\n2.5,\t\t-1.5,\t\t\"2.5-1.5i\"\r\n3,\t\t-1.5,\t\t\"3-1.5i\"\r\n3.5,\t\t-1.5,\t\t\"3.5-1.5i\"\r\n-2.5,\t\t-1.5,\t\t\"-2.5-1.5i\"\r\n-2.5,\t\t-1.5,\t\t\"-2.5-1.5i\"\r\n-1.5,\t\t-1.5,\t\t\"-1.5-1.5i\"\r\n-1.5,\t\t-1.5,\t\t\"-1.5-1.5i\"\r\n-0.5,\t\t-1.5,\t\t\"-0.5-1.5i\"\r\n0,\t\t-1.5,\t\t\"-1.5i\"\r\n0.5,\t\t-1.5,\t\t\"0.5-1.5i\"\r\n1,\t\t-1.5,\t\t\"1-1.5i\"\r\n1.5,\t\t-1.5,\t\t\"1.5-1.5i\"\r\n2,\t\t-1.5,\t\t\"2-1.5i\"\r\n2.5,\t\t-1.5,\t\t\"2.5-1.5i\"\r\n3,\t\t-1.5,\t\t\"3-1.5i\"\r\n3.5,\t\t-1.5,\t\t\"3.5-1.5i\"\r\n-2.5,\t\t-0.5,\t\t\"-2.5-0.5i\"\r\n-2.5,\t\t-0.5,\t\t\"-2.5-0.5i\"\r\n-1.5,\t\t-0.5,\t\t\"-1.5-0.5i\"\r\n-1.5,\t\t-0.5,\t\t\"-1.5-0.5i\"\r\n-0.5,\t\t-0.5,\t\t\"-0.5-0.5i\"\r\n0,\t\t-0.5,\t\t\"-0.5i\"\r\n0.5,\t\t-0.5,\t\t\"0.5-0.5i\"\r\n1,\t\t-0.5,\t\t\"1-0.5i\"\r\n1.5,\t\t-0.5,\t\t\"1.5-0.5i\"\r\n2,\t\t-0.5,\t\t\"2-0.5i\"\r\n2.5,\t\t-0.5,\t\t\"2.5-0.5i\"\r\n3,\t\t-0.5,\t\t\"3-0.5i\"\r\n3.5,\t\t-0.5,\t\t\"3.5-0.5i\"\r\n-2.5,\t\t0,\t\t-2.5\r\n-2.5,\t\t0,\t\t-2.5\r\n-1.5,\t\t0,\t\t-1.5\r\n-1.5,\t\t0,\t\t-1.5\r\n-0.5,\t\t0,\t\t-0.5\r\n0,\t\t0,\t\t0\r\n0.5,\t\t0,\t\t0.5\r\n1,\t\t0,\t\t1\r\n1.5,\t\t0,\t\t1.5\r\n2,\t\t0,\t\t2\r\n2.5,\t\t0,\t\t2.5\r\n3,\t\t0,\t\t3\r\n3.5,\t\t0,\t\t3.5\r\n-2.5,\t\t0.5,\t\t\"-2.5+0.5i\"\r\n-2.5,\t\t0.5,\t\t\"-2.5+0.5i\"\r\n-1.5,\t\t0.5,\t\t\"-1.5+0.5i\"\r\n-1.5,\t\t0.5,\t\t\"-1.5+0.5i\"\r\n-0.5,\t\t0.5,\t\t\"-0.5+0.5i\"\r\n0,\t\t0.5,\t\t\"0.5i\"\r\n0.5,\t\t0.5,\t\t\"0.5+0.5i\"\r\n1,\t\t0.5,\t\t\"1+0.5i\"\r\n1.5,\t\t0.5,\t\t\"1.5+0.5i\"\r\n2,\t\t0.5,\t\t\"2+0.5i\"\r\n2.5,\t\t0.5,\t\t\"2.5+0.5i\"\r\n3,\t\t0.5,\t\t\"3+0.5i\"\r\n3.5,\t\t0.5,\t\t\"3.5+0.5i\"\r\n-2.5,\t\t1,\t\t\"-2.5+i\"\r\n-2.5,\t\t1,\t\t\"-2.5+i\"\r\n-1.5,\t\t1,\t\t\"-1.5+i\"\r\n-1.5,\t\t1,\t\t\"-1.5+i\"\r\n-0.5,\t\t1,\t\t\"-0.5+i\"\r\n0,\t\t1,\t\t\"i\"\r\n0.5,\t\t1,\t\t\"0.5+i\"\r\n1,\t\t1,\t\t\"1+i\"\r\n1.5,\t\t1,\t\t\"1.5+i\"\r\n2,\t\t1,\t\t\"2+i\"\r\n2.5,\t\t1,\t\t\"2.5+i\"\r\n3,\t\t1,\t\t\"3+i\"\r\n3.5,\t\t1,\t\t\"3.5+i\"\r\n-2.5,\t\t1.5,\t\t\"-2.5+1.5i\"\r\n-2.5,\t\t1.5,\t\t\"-2.5+1.5i\"\r\n-1.5,\t\t1.5,\t\t\"-1.5+1.5i\"\r\n-1.5,\t\t1.5,\t\t\"-1.5+1.5i\"\r\n-0.5,\t\t1.5,\t\t\"-0.5+1.5i\"\r\n0,\t\t1.5,\t\t\"1.5i\"\r\n0.5,\t\t1.5,\t\t\"0.5+1.5i\"\r\n1,\t\t1.5,\t\t\"1+1.5i\"\r\n1.5,\t\t1.5,\t\t\"1.5+1.5i\"\r\n2,\t\t1.5,\t\t\"2+1.5i\"\r\n2.5,\t\t1.5,\t\t\"2.5+1.5i\"\r\n3,\t\t1.5,\t\t\"3+1.5i\"\r\n3.5,\t\t1.5,\t\t\"3.5+1.5i\"\r\n-2.5,\t\t2,\t\t\"-2.5+2i\"\r\n-2.5,\t\t2,\t\t\"-2.5+2i\"\r\n-1.5,\t\t2,\t\t\"-1.5+2i\"\r\n-1.5,\t\t2,\t\t\"-1.5+2i\"\r\n-0.5,\t\t2,\t\t\"-0.5+2i\"\r\n0,\t\t2,\t\t\"2i\"\r\n0.5,\t\t2,\t\t\"0.5+2i\"\r\n1,\t\t2,\t\t\"1+2i\"\r\n1.5,\t\t2,\t\t\"1.5+2i\"\r\n2,\t\t2,\t\t\"2+2i\"\r\n2.5,\t\t2,\t\t\"2.5+2i\"\r\n3,\t\t2,\t\t\"3+2i\"\r\n3.5,\t\t2,\t\t\"3.5+2i\"\r\n-2.5,\t\t2.5,\t\t\"-2.5+2.5i\"\r\n-2.5,\t\t2.5,\t\t\"-2.5+2.5i\"\r\n-1.5,\t\t2.5,\t\t\"-1.5+2.5i\"\r\n-1.5,\t\t2.5,\t\t\"-1.5+2.5i\"\r\n-0.5,\t\t2.5,\t\t\"-0.5+2.5i\"\r\n0,\t\t2.5,\t\t\"2.5i\"\r\n0.5,\t\t2.5,\t\t\"0.5+2.5i\"\r\n1,\t\t2.5,\t\t\"1+2.5i\"\r\n1.5,\t\t2.5,\t\t\"1.5+2.5i\"\r\n2,\t\t2.5,\t\t\"2+2.5i\"\r\n2.5,\t\t2.5,\t\t\"2.5+2.5i\"\r\n3,\t\t2.5,\t\t\"3+2.5i\"\r\n3.5,\t\t2.5,\t\t\"3.5+2.5i\"\r\n-2.5,\t\t3,\t\t\"-2.5+3i\"\r\n-2.5,\t\t3,\t\t\"-2.5+3i\"\r\n-1.5,\t\t3,\t\t\"-1.5+3i\"\r\n-1.5,\t\t3,\t\t\"-1.5+3i\"\r\n-0.5,\t\t3,\t\t\"-0.5+3i\"\r\n0,\t\t3,\t\t\"3i\"\r\n0.5,\t\t3,\t\t\"0.5+3i\"\r\n1,\t\t3,\t\t\"1+3i\"\r\n1.5,\t\t3,\t\t\"1.5+3i\"\r\n2,\t\t3,\t\t\"2+3i\"\r\n2.5,\t\t3,\t\t\"2.5+3i\"\r\n3,\t\t3,\t\t\"3+3i\"\r\n3.5,\t\t3,\t\t\"3.5+3i\"\r\n-2.5,\t\t3.5,\t\t\"-2.5+3.5i\"\r\n-2.5,\t\t3.5,\t\t\"-2.5+3.5i\"\r\n-1.5,\t\t3.5,\t\t\"-1.5+3.5i\"\r\n-1.5,\t\t3.5,\t\t\"-1.5+3.5i\"\r\n-0.5,\t\t3.5,\t\t\"-0.5+3.5i\"\r\n0,\t\t3.5,\t\t\"3.5i\"\r\n0.5,\t\t3.5,\t\t\"0.5+3.5i\"\r\n1,\t\t3.5,\t\t\"1+3.5i\"\r\n1.5,\t\t3.5,\t\t\"1.5+3.5i\"\r\n2,\t\t3.5,\t\t\"2+3.5i\"\r\n2.5,\t\t3.5,\t\t\"2.5+3.5i\"\r\n3,\t\t3.5,\t\t\"3+3.5i\"\r\n3.5,\t\t3.5,\t\t\"3.5+3.5i\"\r\n-2.5,\t\t-2.5,\t\"i\",\t\"-2.5-2.5i\"\r\n-2.5,\t\t-2.5,\t\"i\",\t\"-2.5-2.5i\"\r\n-1.5,\t\t-2.5,\t\"i\",\t\"-1.5-2.5i\"\r\n-1.5,\t\t-2.5,\t\"i\",\t\"-1.5-2.5i\"\r\n-0.5,\t\t-2.5,\t\"i\",\t\"-0.5-2.5i\"\r\n0,\t\t-2.5,\t\"i\",\t\"-2.5i\"\r\n0.5,\t\t-2.5,\t\"i\",\t\"0.5-2.5i\"\r\n1,\t\t-2.5,\t\"i\",\t\"1-2.5i\"\r\n1.5,\t\t-2.5,\t\"i\",\t\"1.5-2.5i\"\r\n2,\t\t-2.5,\t\"i\",\t\"2-2.5i\"\r\n2.5,\t\t-2.5,\t\"i\",\t\"2.5-2.5i\"\r\n3,\t\t-2.5,\t\"i\",\t\"3-2.5i\"\r\n3.5,\t\t-2.5,\t\"i\",\t\"3.5-2.5i\"\r\n-2.5,\t\t-2.5,\t\"i\",\t\"-2.5-2.5i\"\r\n-2.5,\t\t-2.5,\t\"i\",\t\"-2.5-2.5i\"\r\n-1.5,\t\t-2.5,\t\"i\",\t\"-1.5-2.5i\"\r\n-1.5,\t\t-2.5,\t\"i\",\t\"-1.5-2.5i\"\r\n-0.5,\t\t-2.5,\t\"i\",\t\"-0.5-2.5i\"\r\n0,\t\t-2.5,\t\"i\",\t\"-2.5i\"\r\n0.5,\t\t-2.5,\t\"i\",\t\"0.5-2.5i\"\r\n1,\t\t-2.5,\t\"i\",\t\"1-2.5i\"\r\n1.5,\t\t-2.5,\t\"i\",\t\"1.5-2.5i\"\r\n2,\t\t-2.5,\t\"i\",\t\"2-2.5i\"\r\n2.5,\t\t-2.5,\t\"i\",\t\"2.5-2.5i\"\r\n3,\t\t-2.5,\t\"i\",\t\"3-2.5i\"\r\n3.5,\t\t-2.5,\t\"i\",\t\"3.5-2.5i\"\r\n-2.5,\t\t-1.5,\t\"i\",\t\"-2.5-1.5i\"\r\n-2.5,\t\t-1.5,\t\"i\",\t\"-2.5-1.5i\"\r\n-1.5,\t\t-1.5,\t\"i\",\t\"-1.5-1.5i\"\r\n-1.5,\t\t-1.5,\t\"i\",\t\"-1.5-1.5i\"\r\n-0.5,\t\t-1.5,\t\"i\",\t\"-0.5-1.5i\"\r\n0,\t\t-1.5,\t\"i\",\t\"-1.5i\"\r\n0.5,\t\t-1.5,\t\"i\",\t\"0.5-1.5i\"\r\n1,\t\t-1.5,\t\"i\",\t\"1-1.5i\"\r\n1.5,\t\t-1.5,\t\"i\",\t\"1.5-1.5i\"\r\n2,\t\t-1.5,\t\"i\",\t\"2-1.5i\"\r\n2.5,\t\t-1.5,\t\"i\",\t\"2.5-1.5i\"\r\n3,\t\t-1.5,\t\"i\",\t\"3-1.5i\"\r\n3.5,\t\t-1.5,\t\"i\",\t\"3.5-1.5i\"\r\n-2.5,\t\t-1.5,\t\"i\",\t\"-2.5-1.5i\"\r\n-2.5,\t\t-1.5,\t\"i\",\t\"-2.5-1.5i\"\r\n-1.5,\t\t-1.5,\t\"i\",\t\"-1.5-1.5i\"\r\n-1.5,\t\t-1.5,\t\"i\",\t\"-1.5-1.5i\"\r\n-0.5,\t\t-1.5,\t\"i\",\t\"-0.5-1.5i\"\r\n0,\t\t-1.5,\t\"i\",\t\"-1.5i\"\r\n0.5,\t\t-1.5,\t\"i\",\t\"0.5-1.5i\"\r\n1,\t\t-1.5,\t\"i\",\t\"1-1.5i\"\r\n1.5,\t\t-1.5,\t\"i\",\t\"1.5-1.5i\"\r\n2,\t\t-1.5,\t\"i\",\t\"2-1.5i\"\r\n2.5,\t\t-1.5,\t\"i\",\t\"2.5-1.5i\"\r\n3,\t\t-1.5,\t\"i\",\t\"3-1.5i\"\r\n3.5,\t\t-1.5,\t\"i\",\t\"3.5-1.5i\"\r\n-2.5,\t\t-0.5,\t\"i\",\t\"-2.5-0.5i\"\r\n-2.5,\t\t-0.5,\t\"i\",\t\"-2.5-0.5i\"\r\n-1.5,\t\t-0.5,\t\"i\",\t\"-1.5-0.5i\"\r\n-1.5,\t\t-0.5,\t\"i\",\t\"-1.5-0.5i\"\r\n-0.5,\t\t-0.5,\t\"i\",\t\"-0.5-0.5i\"\r\n0,\t\t-0.5,\t\"i\",\t\"-0.5i\"\r\n0.5,\t\t-0.5,\t\"i\",\t\"0.5-0.5i\"\r\n1,\t\t-0.5,\t\"i\",\t\"1-0.5i\"\r\n1.5,\t\t-0.5,\t\"i\",\t\"1.5-0.5i\"\r\n2,\t\t-0.5,\t\"i\",\t\"2-0.5i\"\r\n2.5,\t\t-0.5,\t\"i\",\t\"2.5-0.5i\"\r\n3,\t\t-0.5,\t\"i\",\t\"3-0.5i\"\r\n3.5,\t\t-0.5,\t\"i\",\t\"3.5-0.5i\"\r\n-2.5,\t\t0,\t\"i\",\t-2.5\r\n-2.5,\t\t0,\t\"i\",\t-2.5\r\n-1.5,\t\t0,\t\"i\",\t-1.5\r\n-1.5,\t\t0,\t\"i\",\t-1.5\r\n-0.5,\t\t0,\t\"i\",\t-0.5\r\n0,\t\t0,\t\"i\",\t0\r\n0.5,\t\t0,\t\"i\",\t0.5\r\n1,\t\t0,\t\"i\",\t1\r\n1.5,\t\t0,\t\"i\",\t1.5\r\n2,\t\t0,\t\"i\",\t2\r\n2.5,\t\t0,\t\"i\",\t2.5\r\n3,\t\t0,\t\"i\",\t3\r\n3.5,\t\t0,\t\"i\",\t3.5\r\n-2.5,\t\t0.5,\t\"i\",\t\"-2.5+0.5i\"\r\n-2.5,\t\t0.5,\t\"i\",\t\"-2.5+0.5i\"\r\n-1.5,\t\t0.5,\t\"i\",\t\"-1.5+0.5i\"\r\n-1.5,\t\t0.5,\t\"i\",\t\"-1.5+0.5i\"\r\n-0.5,\t\t0.5,\t\"i\",\t\"-0.5+0.5i\"\r\n0,\t\t0.5,\t\"i\",\t\"0.5i\"\r\n0.5,\t\t0.5,\t\"i\",\t\"0.5+0.5i\"\r\n1,\t\t0.5,\t\"i\",\t\"1+0.5i\"\r\n1.5,\t\t0.5,\t\"i\",\t\"1.5+0.5i\"\r\n2,\t\t0.5,\t\"i\",\t\"2+0.5i\"\r\n2.5,\t\t0.5,\t\"i\",\t\"2.5+0.5i\"\r\n3,\t\t0.5,\t\"i\",\t\"3+0.5i\"\r\n3.5,\t\t0.5,\t\"i\",\t\"3.5+0.5i\"\r\n-2.5,\t\t1,\t\"i\",\t\"-2.5+i\"\r\n-2.5,\t\t1,\t\"i\",\t\"-2.5+i\"\r\n-1.5,\t\t1,\t\"i\",\t\"-1.5+i\"\r\n-1.5,\t\t1,\t\"i\",\t\"-1.5+i\"\r\n-0.5,\t\t1,\t\"i\",\t\"-0.5+i\"\r\n0,\t\t1,\t\"i\",\t\"i\"\r\n0.5,\t\t1,\t\"i\",\t\"0.5+i\"\r\n1,\t\t1,\t\"i\",\t\"1+i\"\r\n1.5,\t\t1,\t\"i\",\t\"1.5+i\"\r\n2,\t\t1,\t\"i\",\t\"2+i\"\r\n2.5,\t\t1,\t\"i\",\t\"2.5+i\"\r\n3,\t\t1,\t\"i\",\t\"3+i\"\r\n3.5,\t\t1,\t\"i\",\t\"3.5+i\"\r\n-2.5,\t\t1.5,\t\"i\",\t\"-2.5+1.5i\"\r\n-2.5,\t\t1.5,\t\"i\",\t\"-2.5+1.5i\"\r\n-1.5,\t\t1.5,\t\"i\",\t\"-1.5+1.5i\"\r\n-1.5,\t\t1.5,\t\"i\",\t\"-1.5+1.5i\"\r\n-0.5,\t\t1.5,\t\"i\",\t\"-0.5+1.5i\"\r\n0,\t\t1.5,\t\"i\",\t\"1.5i\"\r\n0.5,\t\t1.5,\t\"i\",\t\"0.5+1.5i\"\r\n1,\t\t1.5,\t\"i\",\t\"1+1.5i\"\r\n1.5,\t\t1.5,\t\"i\",\t\"1.5+1.5i\"\r\n2,\t\t1.5,\t\"i\",\t\"2+1.5i\"\r\n2.5,\t\t1.5,\t\"i\",\t\"2.5+1.5i\"\r\n3,\t\t1.5,\t\"i\",\t\"3+1.5i\"\r\n3.5,\t\t1.5,\t\"i\",\t\"3.5+1.5i\"\r\n-2.5,\t\t2,\t\"i\",\t\"-2.5+2i\"\r\n-2.5,\t\t2,\t\"i\",\t\"-2.5+2i\"\r\n-1.5,\t\t2,\t\"i\",\t\"-1.5+2i\"\r\n-1.5,\t\t2,\t\"i\",\t\"-1.5+2i\"\r\n-0.5,\t\t2,\t\"i\",\t\"-0.5+2i\"\r\n0,\t\t2,\t\"i\",\t\"2i\"\r\n0.5,\t\t2,\t\"i\",\t\"0.5+2i\"\r\n1,\t\t2,\t\"i\",\t\"1+2i\"\r\n1.5,\t\t2,\t\"i\",\t\"1.5+2i\"\r\n2,\t\t2,\t\"i\",\t\"2+2i\"\r\n2.5,\t\t2,\t\"i\",\t\"2.5+2i\"\r\n3,\t\t2,\t\"i\",\t\"3+2i\"\r\n3.5,\t\t2,\t\"i\",\t\"3.5+2i\"\r\n-2.5,\t\t2.5,\t\"i\",\t\"-2.5+2.5i\"\r\n-2.5,\t\t2.5,\t\"i\",\t\"-2.5+2.5i\"\r\n-1.5,\t\t2.5,\t\"i\",\t\"-1.5+2.5i\"\r\n-1.5,\t\t2.5,\t\"i\",\t\"-1.5+2.5i\"\r\n-0.5,\t\t2.5,\t\"i\",\t\"-0.5+2.5i\"\r\n0,\t\t2.5,\t\"i\",\t\"2.5i\"\r\n0.5,\t\t2.5,\t\"i\",\t\"0.5+2.5i\"\r\n1,\t\t2.5,\t\"i\",\t\"1+2.5i\"\r\n1.5,\t\t2.5,\t\"i\",\t\"1.5+2.5i\"\r\n2,\t\t2.5,\t\"i\",\t\"2+2.5i\"\r\n2.5,\t\t2.5,\t\"i\",\t\"2.5+2.5i\"\r\n3,\t\t2.5,\t\"i\",\t\"3+2.5i\"\r\n3.5,\t\t2.5,\t\"i\",\t\"3.5+2.5i\"\r\n-2.5,\t\t3,\t\"i\",\t\"-2.5+3i\"\r\n-2.5,\t\t3,\t\"i\",\t\"-2.5+3i\"\r\n-1.5,\t\t3,\t\"i\",\t\"-1.5+3i\"\r\n-1.5,\t\t3,\t\"i\",\t\"-1.5+3i\"\r\n-0.5,\t\t3,\t\"i\",\t\"-0.5+3i\"\r\n0,\t\t3,\t\"i\",\t\"3i\"\r\n0.5,\t\t3,\t\"i\",\t\"0.5+3i\"\r\n1,\t\t3,\t\"i\",\t\"1+3i\"\r\n1.5,\t\t3,\t\"i\",\t\"1.5+3i\"\r\n2,\t\t3,\t\"i\",\t\"2+3i\"\r\n2.5,\t\t3,\t\"i\",\t\"2.5+3i\"\r\n3,\t\t3,\t\"i\",\t\"3+3i\"\r\n3.5,\t\t3,\t\"i\",\t\"3.5+3i\"\r\n-2.5,\t\t3.5,\t\"i\",\t\"-2.5+3.5i\"\r\n-2.5,\t\t3.5,\t\"i\",\t\"-2.5+3.5i\"\r\n-1.5,\t\t3.5,\t\"i\",\t\"-1.5+3.5i\"\r\n-1.5,\t\t3.5,\t\"i\",\t\"-1.5+3.5i\"\r\n-0.5,\t\t3.5,\t\"i\",\t\"-0.5+3.5i\"\r\n0,\t\t3.5,\t\"i\",\t\"3.5i\"\r\n0.5,\t\t3.5,\t\"i\",\t\"0.5+3.5i\"\r\n1,\t\t3.5,\t\"i\",\t\"1+3.5i\"\r\n1.5,\t\t3.5,\t\"i\",\t\"1.5+3.5i\"\r\n2,\t\t3.5,\t\"i\",\t\"2+3.5i\"\r\n2.5,\t\t3.5,\t\"i\",\t\"2.5+3.5i\"\r\n3,\t\t3.5,\t\"i\",\t\"3+3.5i\"\r\n3.5,\t\t3.5,\t\"i\",\t\"3.5+3.5i\"\r\n-2.5,\t\t-2.5,\t\"j\",\t\"-2.5-2.5j\"\r\n-2.5,\t\t-2.5,\t\"j\",\t\"-2.5-2.5j\"\r\n-1.5,\t\t-2.5,\t\"j\",\t\"-1.5-2.5j\"\r\n-1.5,\t\t-2.5,\t\"j\",\t\"-1.5-2.5j\"\r\n-0.5,\t\t-2.5,\t\"j\",\t\"-0.5-2.5j\"\r\n0,\t\t-2.5,\t\"j\",\t\"-2.5j\"\r\n0.5,\t\t-2.5,\t\"j\",\t\"0.5-2.5j\"\r\n1,\t\t-2.5,\t\"j\",\t\"1-2.5j\"\r\n1.5,\t\t-2.5,\t\"j\",\t\"1.5-2.5j\"\r\n2,\t\t-2.5,\t\"j\",\t\"2-2.5j\"\r\n2.5,\t\t-2.5,\t\"j\",\t\"2.5-2.5j\"\r\n3,\t\t-2.5,\t\"j\",\t\"3-2.5j\"\r\n3.5,\t\t-2.5,\t\"j\",\t\"3.5-2.5j\"\r\n-2.5,\t\t-2.5,\t\"j\",\t\"-2.5-2.5j\"\r\n-2.5,\t\t-2.5,\t\"j\",\t\"-2.5-2.5j\"\r\n-1.5,\t\t-2.5,\t\"j\",\t\"-1.5-2.5j\"\r\n-1.5,\t\t-2.5,\t\"j\",\t\"-1.5-2.5j\"\r\n-0.5,\t\t-2.5,\t\"j\",\t\"-0.5-2.5j\"\r\n0,\t\t-2.5,\t\"j\",\t\"-2.5j\"\r\n0.5,\t\t-2.5,\t\"j\",\t\"0.5-2.5j\"\r\n1,\t\t-2.5,\t\"j\",\t\"1-2.5j\"\r\n1.5,\t\t-2.5,\t\"j\",\t\"1.5-2.5j\"\r\n2,\t\t-2.5,\t\"j\",\t\"2-2.5j\"\r\n2.5,\t\t-2.5,\t\"j\",\t\"2.5-2.5j\"\r\n3,\t\t-2.5,\t\"j\",\t\"3-2.5j\"\r\n3.5,\t\t-2.5,\t\"j\",\t\"3.5-2.5j\"\r\n-2.5,\t\t-1.5,\t\"j\",\t\"-2.5-1.5j\"\r\n-2.5,\t\t-1.5,\t\"j\",\t\"-2.5-1.5j\"\r\n-1.5,\t\t-1.5,\t\"j\",\t\"-1.5-1.5j\"\r\n-1.5,\t\t-1.5,\t\"j\",\t\"-1.5-1.5j\"\r\n-0.5,\t\t-1.5,\t\"j\",\t\"-0.5-1.5j\"\r\n0,\t\t-1.5,\t\"j\",\t\"-1.5j\"\r\n0.5,\t\t-1.5,\t\"j\",\t\"0.5-1.5j\"\r\n1,\t\t-1.5,\t\"j\",\t\"1-1.5j\"\r\n1.5,\t\t-1.5,\t\"j\",\t\"1.5-1.5j\"\r\n2,\t\t-1.5,\t\"j\",\t\"2-1.5j\"\r\n2.5,\t\t-1.5,\t\"j\",\t\"2.5-1.5j\"\r\n3,\t\t-1.5,\t\"j\",\t\"3-1.5j\"\r\n3.5,\t\t-1.5,\t\"j\",\t\"3.5-1.5j\"\r\n-2.5,\t\t-1.5,\t\"j\",\t\"-2.5-1.5j\"\r\n-2.5,\t\t-1.5,\t\"j\",\t\"-2.5-1.5j\"\r\n-1.5,\t\t-1.5,\t\"j\",\t\"-1.5-1.5j\"\r\n-1.5,\t\t-1.5,\t\"j\",\t\"-1.5-1.5j\"\r\n-0.5,\t\t-1.5,\t\"j\",\t\"-0.5-1.5j\"\r\n0,\t\t-1.5,\t\"j\",\t\"-1.5j\"\r\n0.5,\t\t-1.5,\t\"j\",\t\"0.5-1.5j\"\r\n1,\t\t-1.5,\t\"j\",\t\"1-1.5j\"\r\n1.5,\t\t-1.5,\t\"j\",\t\"1.5-1.5j\"\r\n2,\t\t-1.5,\t\"j\",\t\"2-1.5j\"\r\n2.5,\t\t-1.5,\t\"j\",\t\"2.5-1.5j\"\r\n3,\t\t-1.5,\t\"j\",\t\"3-1.5j\"\r\n3.5,\t\t-1.5,\t\"j\",\t\"3.5-1.5j\"\r\n-2.5,\t\t-0.5,\t\"j\",\t\"-2.5-0.5j\"\r\n-2.5,\t\t-0.5,\t\"j\",\t\"-2.5-0.5j\"\r\n-1.5,\t\t-0.5,\t\"j\",\t\"-1.5-0.5j\"\r\n-1.5,\t\t-0.5,\t\"j\",\t\"-1.5-0.5j\"\r\n-0.5,\t\t-0.5,\t\"j\",\t\"-0.5-0.5j\"\r\n0,\t\t-0.5,\t\"j\",\t\"-0.5j\"\r\n0.5,\t\t-0.5,\t\"j\",\t\"0.5-0.5j\"\r\n1,\t\t-0.5,\t\"j\",\t\"1-0.5j\"\r\n1.5,\t\t-0.5,\t\"j\",\t\"1.5-0.5j\"\r\n2,\t\t-0.5,\t\"j\",\t\"2-0.5j\"\r\n2.5,\t\t-0.5,\t\"j\",\t\"2.5-0.5j\"\r\n3,\t\t-0.5,\t\"j\",\t\"3-0.5j\"\r\n3.5,\t\t-0.5,\t\"j\",\t\"3.5-0.5j\"\r\n-2.5,\t\t0,\t\"j\",\t-2.5\r\n-2.5,\t\t0,\t\"j\",\t-2.5\r\n-1.5,\t\t0,\t\"j\",\t-1.5\r\n-1.5,\t\t0,\t\"j\",\t-1.5\r\n-0.5,\t\t0,\t\"j\",\t-0.5\r\n0,\t\t0,\t\"j\",\t0\r\n0.5,\t\t0,\t\"j\",\t0.5\r\n1,\t\t0,\t\"j\",\t1\r\n1.5,\t\t0,\t\"j\",\t1.5\r\n2,\t\t0,\t\"j\",\t2\r\n2.5,\t\t0,\t\"j\",\t2.5\r\n3,\t\t0,\t\"j\",\t3\r\n3.5,\t\t0,\t\"j\",\t3.5\r\n-2.5,\t\t0.5,\t\"j\",\t\"-2.5+0.5j\"\r\n-2.5,\t\t0.5,\t\"j\",\t\"-2.5+0.5j\"\r\n-1.5,\t\t0.5,\t\"j\",\t\"-1.5+0.5j\"\r\n-1.5,\t\t0.5,\t\"j\",\t\"-1.5+0.5j\"\r\n-0.5,\t\t0.5,\t\"j\",\t\"-0.5+0.5j\"\r\n0,\t\t0.5,\t\"j\",\t\"0.5j\"\r\n0.5,\t\t0.5,\t\"j\",\t\"0.5+0.5j\"\r\n1,\t\t0.5,\t\"j\",\t\"1+0.5j\"\r\n1.5,\t\t0.5,\t\"j\",\t\"1.5+0.5j\"\r\n2,\t\t0.5,\t\"j\",\t\"2+0.5j\"\r\n2.5,\t\t0.5,\t\"j\",\t\"2.5+0.5j\"\r\n3,\t\t0.5,\t\"j\",\t\"3+0.5j\"\r\n3.5,\t\t0.5,\t\"j\",\t\"3.5+0.5j\"\r\n-2.5,\t\t1,\t\"j\",\t\"-2.5+j\"\r\n-2.5,\t\t1,\t\"j\",\t\"-2.5+j\"\r\n-1.5,\t\t1,\t\"j\",\t\"-1.5+j\"\r\n-1.5,\t\t1,\t\"j\",\t\"-1.5+j\"\r\n-0.5,\t\t1,\t\"j\",\t\"-0.5+j\"\r\n0,\t\t1,\t\"j\",\t\"j\"\r\n0.5,\t\t1,\t\"j\",\t\"0.5+j\"\r\n1,\t\t1,\t\"j\",\t\"1+j\"\r\n1.5,\t\t1,\t\"j\",\t\"1.5+j\"\r\n2,\t\t1,\t\"j\",\t\"2+j\"\r\n2.5,\t\t1,\t\"j\",\t\"2.5+j\"\r\n3,\t\t1,\t\"j\",\t\"3+j\"\r\n3.5,\t\t1,\t\"j\",\t\"3.5+j\"\r\n-2.5,\t\t1.5,\t\"j\",\t\"-2.5+1.5j\"\r\n-2.5,\t\t1.5,\t\"j\",\t\"-2.5+1.5j\"\r\n-1.5,\t\t1.5,\t\"j\",\t\"-1.5+1.5j\"\r\n-1.5,\t\t1.5,\t\"j\",\t\"-1.5+1.5j\"\r\n-0.5,\t\t1.5,\t\"j\",\t\"-0.5+1.5j\"\r\n0,\t\t1.5,\t\"j\",\t\"1.5j\"\r\n0.5,\t\t1.5,\t\"j\",\t\"0.5+1.5j\"\r\n1,\t\t1.5,\t\"j\",\t\"1+1.5j\"\r\n1.5,\t\t1.5,\t\"j\",\t\"1.5+1.5j\"\r\n2,\t\t1.5,\t\"j\",\t\"2+1.5j\"\r\n2.5,\t\t1.5,\t\"j\",\t\"2.5+1.5j\"\r\n3,\t\t1.5,\t\"j\",\t\"3+1.5j\"\r\n3.5,\t\t1.5,\t\"j\",\t\"3.5+1.5j\"\r\n-2.5,\t\t2,\t\"j\",\t\"-2.5+2j\"\r\n-2.5,\t\t2,\t\"j\",\t\"-2.5+2j\"\r\n-1.5,\t\t2,\t\"j\",\t\"-1.5+2j\"\r\n-1.5,\t\t2,\t\"j\",\t\"-1.5+2j\"\r\n-0.5,\t\t2,\t\"j\",\t\"-0.5+2j\"\r\n0,\t\t2,\t\"j\",\t\"2j\"\r\n0.5,\t\t2,\t\"j\",\t\"0.5+2j\"\r\n1,\t\t2,\t\"j\",\t\"1+2j\"\r\n1.5,\t\t2,\t\"j\",\t\"1.5+2j\"\r\n2,\t\t2,\t\"j\",\t\"2+2j\"\r\n2.5,\t\t2,\t\"j\",\t\"2.5+2j\"\r\n3,\t\t2,\t\"j\",\t\"3+2j\"\r\n3.5,\t\t2,\t\"j\",\t\"3.5+2j\"\r\n-2.5,\t\t2.5,\t\"j\",\t\"-2.5+2.5j\"\r\n-2.5,\t\t2.5,\t\"j\",\t\"-2.5+2.5j\"\r\n-1.5,\t\t2.5,\t\"j\",\t\"-1.5+2.5j\"\r\n-1.5,\t\t2.5,\t\"j\",\t\"-1.5+2.5j\"\r\n-0.5,\t\t2.5,\t\"j\",\t\"-0.5+2.5j\"\r\n0,\t\t2.5,\t\"j\",\t\"2.5j\"\r\n0.5,\t\t2.5,\t\"j\",\t\"0.5+2.5j\"\r\n1,\t\t2.5,\t\"j\",\t\"1+2.5j\"\r\n1.5,\t\t2.5,\t\"j\",\t\"1.5+2.5j\"\r\n2,\t\t2.5,\t\"j\",\t\"2+2.5j\"\r\n2.5,\t\t2.5,\t\"j\",\t\"2.5+2.5j\"\r\n3,\t\t2.5,\t\"j\",\t\"3+2.5j\"\r\n3.5,\t\t2.5,\t\"j\",\t\"3.5+2.5j\"\r\n-2.5,\t\t3,\t\"j\",\t\"-2.5+3j\"\r\n-2.5,\t\t3,\t\"j\",\t\"-2.5+3j\"\r\n-1.5,\t\t3,\t\"j\",\t\"-1.5+3j\"\r\n-1.5,\t\t3,\t\"j\",\t\"-1.5+3j\"\r\n-0.5,\t\t3,\t\"j\",\t\"-0.5+3j\"\r\n0,\t\t3,\t\"j\",\t\"3j\"\r\n0.5,\t\t3,\t\"j\",\t\"0.5+3j\"\r\n1,\t\t3,\t\"j\",\t\"1+3j\"\r\n1.5,\t\t3,\t\"j\",\t\"1.5+3j\"\r\n2,\t\t3,\t\"j\",\t\"2+3j\"\r\n2.5,\t\t3,\t\"j\",\t\"2.5+3j\"\r\n3,\t\t3,\t\"j\",\t\"3+3j\"\r\n3.5,\t\t3,\t\"j\",\t\"3.5+3j\"\r\n-2.5,\t\t3.5,\t\"j\",\t\"-2.5+3.5j\"\r\n-2.5,\t\t3.5,\t\"j\",\t\"-2.5+3.5j\"\r\n-1.5,\t\t3.5,\t\"j\",\t\"-1.5+3.5j\"\r\n-1.5,\t\t3.5,\t\"j\",\t\"-1.5+3.5j\"\r\n-0.5,\t\t3.5,\t\"j\",\t\"-0.5+3.5j\"\r\n0,\t\t3.5,\t\"j\",\t\"3.5j\"\r\n0.5,\t\t3.5,\t\"j\",\t\"0.5+3.5j\"\r\n1,\t\t3.5,\t\"j\",\t\"1+3.5j\"\r\n1.5,\t\t3.5,\t\"j\",\t\"1.5+3.5j\"\r\n2,\t\t3.5,\t\"j\",\t\"2+3.5j\"\r\n2.5,\t\t3.5,\t\"j\",\t\"2.5+3.5j\"\r\n3,\t\t3.5,\t\"j\",\t\"3+3.5j\"\r\n3.5,\t\t3.5,\t\"j\",\t\"3.5+3.5j\"\r\n-1.23,\t\t-4.56,\t\t\"-1.23-4.56i\"\r\n0,\t\t-3.21,\t\"i\",\t\"-3.21i\"\r\n1.23,\t\t-2.34,\t\"j\",\t\"1.23-2.34j\"\r\n-1.23,\t\t0,\t\t-1.23\r\n0,\t\t0,\t\"i\",\t0\r\n1.23,\t\t0,\t\"j\",\t1.23\r\n-1.23,\t\t4.56,\t\t\"-1.23+4.56i\"\r\n0,\t\t3.21,\t\"i\",\t\"3.21i\"\r\n1.23,\t\t2.34,\t\"j\",\t\"1.23+2.34j\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/CONVERTUOM.data",
    "content": "1.0,\t\"lbm\",\t\"kg\",\t0.45359230974881\r\n123.45,\t\"kg\",\t\"kg\",\t123.45\r\n68,\t\"F\",\t\"C\",\t20\r\n20,\t\"C\",\t\"F\",\t68\r\n68,\t\"F\",\t\"K\",\t293.15\r\n293.15,\t\"K\",\t\"F\",\t68\r\n22,\t\"C\",\t\"K\",\t295.15\r\n295.65,\t\"K\",\t\"C\",\t22.5\r\n2.5,\t\"ft\",\t\"sec\",\t\"#N/A\"\r\n12345,\t\"m\",\t\"km\",\t12.345\r\n12.345,\t\"km\",\t\"m\",\t12345\r\n1,\t\"km\",\t\"mi\",\t0.62137119223733\r\n\"three\",\"ft\",\t\"yds\",\t\"#VALUE!\"\r\n123.45,\t\"K\",\t\"kel\",\t123.45\r\n123.45,\t\"C\",\t\"cel\",\t123.45\r\n123.45,\t\"F\",\t\"fah\",\t123.45\r\n1,\t\"ft\",\t\"day\",\t\"#N/A\"\r\n123.45,\t\"m\",\t\"m\",\t123.45\r\n234.56,\t\"km\",\t\"km\",\t234.56\r\n234.56,\t\"kpt\",\t\"lt\",\t\"#N/A\"\r\n234.56,\t\"sm\",\t\"m\",\t\"#N/A\"\r\n234.56,\t\"lt\",\t\"kpt\",\t\"#N/A\"\r\n234.56,\t\"m\",\t\"sm\",\t\"#N/A\"\r\n12.345,\t\"km\",\t\"mm\",\t12345000\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/DEC2BIN.data",
    "content": "357,\t\t\t\"101100101\"\r\n1357,\t\t\t\"#NUM!\"\t\t//\tToo large\r\n9,\t\t4,\t\"1001\"\r\n9,\t\t8,\t\"00001001\"\r\n9,\t\t6.75,\t\"001001\"\t//\tLeading places as a float\r\n9,\t\t-1,\t\"#NUM!\"\t\t//\tLeading places negative\r\n9,\t\t\"ABC\",\t\"#VALUE!\"\t//\tLeading places non-numeric\r\n246,\t\t\t\"11110110\"\r\n12345,\t\t\t\"#NUM!\"\r\n123456789,\t\t\"#NUM!\"\r\n123.45,\t\t\t\"1111011\"\r\n0,\t\t\t\"0\"\r\n\"3579A\",\t\t\"#VALUE!\"\t//\tInvalid decimal\r\nTRUE,\t\t\t\"#VALUE!\"\t//\tNon string\r\n-100,\t\t\t\"1110011100\"\t//\t2's Complement\r\n-107,\t\t\t\"1110010101\"\t//\t2's Complement\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/DEC2HEX.data",
    "content": "\"357\",\t\t\t\"165\"\r\n\"1357\",\t\t\t\"54D\"\r\n\"246\",\t\t\t\"F6\"\r\n\"12345\",\t\t\"3039\"\r\n\"123456789\",\t\t\"75BCD15\"\r\n\"100\",\t\t4,\t\"0064\"\r\n\"100\",\t\t5.75,\t\"00064\"\t\t//\tLeading places as a float\r\n\"100\",\t\t-1,\t\"#NUM!\"\t\t//\tLeading places negative\r\n\"100\",\t\t\"ABC\",\t\"#VALUE!\"\t//\tLeading places non-numeric\r\n\"123.45\",\t\t\"7B\"\r\n\"0\",\t\t\t\"0\"\r\n\"3579A\",\t\t\"#VALUE!\"\t//\tInvalid decimal\r\nTRUE,\t\t\t\"#VALUE!\"\t//\tNon string\r\n\"-54\",\t\t\t\"FFFFFFFFCA\"\t//\t2's Complement\r\n\"-107\",\t\t\t\"FFFFFFFF95\"\t//\t2's Complement\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/DEC2OCT.data",
    "content": "\"357\",\t\t\t\"545\"\r\n\"1357\",\t\t\t\"2515\"\r\n\"246\",\t\t\t\"366\"\r\n\"12345\",\t\t\"30071\"\r\n\"123456789\",\t\t\"726746425\"\r\n\"123.45\",\t\t\"173\"\r\n\"58,\t\t3,\t\"072\"\r\n\"0\",\t\t\t\"0\"\r\n\"3579A\",\t\t\"#VALUE!\"\t//\tInvalid decimal\r\nTRUE,\t\t\t\"#VALUE!\"\t//\tNon string\r\n\"-100\",\t\t\t\"7777777634\"\t//\t2's Complement\r\n\"-107\",\t\t\t\"7777777625\"\t//\t2's Complement\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/DELTA.data",
    "content": "-1.5,\t-1.5,\t1\r\n-0.75,\t-1.5,\t0\r\n0,\t-1.5,\t0\r\n0.75,\t-1.5,\t0\r\n1.5,\t-1.5,\t0\r\n-1.5,\t-0.75,\t0\r\n-0.75,\t-0.75,\t1\r\n0,\t-0.75,\t0\r\n0.75,\t-0.75,\t0\r\n1.5,\t-0.75,\t0\r\n-1.5,\t0,\t0\r\n-0.75,\t0,\t0\r\n0,\t0,\t1\r\n0.75,\t0,\t0\r\n1.5,\t0,\t0\r\n-1.5,\t0.75,\t0\r\n-0.75,\t0.75,\t0\r\n0,\t0.75,\t0\r\n0.75,\t0.75,\t1\r\n1.5,\t0.75,\t0\r\n-1.5,\t1.5,\t0\r\n-0.75,\t1.5,\t0\r\n0,\t1.5,\t0\r\n0.75,\t1.5,\t0\r\n1.5,\t1.5,\t1\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/ERF.data",
    "content": "# lower\tbound\tupper bound\tResult\r\n0,\t\t\t\t0.0\r\n0.01,\t\t\t\t0.0112834155558496\r\n0.05,\t\t\t\t0.0563719777970166\r\n0.1,\t\t\t\t0.1124629160182850\r\n0.125,\t\t\t\t0.1403162048013340\r\n0.15,\t\t\t\t0.1679959714273630\r\n0.2,\t\t\t\t0.2227025892104780\r\n0.25,\t\t\t\t0.2763263901682370\r\n0.3,\t\t\t\t0.3286267594591270\r\n0.35,\t\t\t\t0.3793820535623100\r\n0.4,\t\t\t\t0.4283923550466680\r\n0.45,\t\t\t\t0.4754817197869240\r\n0.5,\t\t\t\t0.5204998778130470\r\n0.6,\t\t\t\t0.6038560908479260\r\n0.7,\t\t\t\t0.6778011938374180\r\n0.8,\t\t\t\t0.7421009647076610\r\n0.9,\t\t\t\t0.7969082124228320\r\n1,\t\t\t\t0.8427007929497150\r\n1.1,\t\t\t\t0.8802050695740820\r\n1.2,\t\t\t\t0.9103139782296350\r\n1.3,\t\t\t\t0.9340079449406520\r\n1.4,\t\t\t\t0.9522851197626490\r\n1.5,\t\t\t\t0.9661051464753110\r\n1.75,\t\t\t\t0.9866716712191820\r\n2,\t\t\t\t0.9953222650189530\r\n2.5,\t\t\t\t0.9995930479825550\r\n3,\t\t\t\t0.9999779095030010\r\n3.5,\t\t\t\t0.9999992569016280\r\n4,\t\t\t\t0.9999999845827420\r\n4.5,\t\t\t\t0.9999999998033840\r\n5,\t\t\t\t0.9999999999984630\r\n5.5,\t\t\t\t0.9999999999999930\r\n6,\t\t\t\t1.0\r\n32,\t\t\t\t1.0\r\n-0.1,\t\t\t\t-0.1124629160182850\r\n-1,\t\t\t\t-0.8427007929497150\r\nTRUE,\t\t\t\t\"#VALUE!\"\r\nFALSE,\t\t\t\t\"#VALUE!\"\r\n\"2\",\t\t\t\t0.9953222650189530\r\n\"TWO\",\t\t\t\t\"#VALUE!\"\r\n-1.5,\t\t-1.5,\t\t0.0\r\n-0.75,\t\t-1.5,\t\t-0.2549495128217960\r\n0,\t\t-1.5,\t\t-0.9661051464753110\r\n0.75,\t\t-1.5,\t\t-1.6772607801288300\r\n1.5,\t\t-1.5,\t\t-1.9322102929506200\r\n2.25,\t\t-1.5,\t\t-1.9646424298886300\r\n3,\t\t-1.5,\t\t-1.9660830559783100\r\n3.75,\t\t-1.5,\t\t-1.9661050327480500\r\n4.5,\t\t-1.5,\t\t-1.9661051462786900\r\n-1.5,\t\t-0.75,\t\t0.2549495128217960\r\n-0.75,\t\t-0.75,\t\t0.0\r\n0,\t\t-0.75,\t\t-0.7111556336535150\r\n0.75,\t\t-0.75,\t\t-1.4223112673070300\r\n1.5,\t\t-0.75,\t\t-1.6772607801288300\r\n2.25,\t\t-0.75,\t\t-1.7096929170668300\r\n3,\t\t-0.75,\t\t-1.7111335431565200\r\n3.75,\t\t-0.75,\t\t-1.7111555199262600\r\n4.5,\t\t-0.75,\t\t-1.7111556334569000\r\n-1.5,\t\t0,\t\t0.9661051464753110\r\n-0.75,\t\t0,\t\t0.7111556336535150\r\n0,\t\t0,\t\t0.0\r\n0.75,\t\t0,\t\t-0.7111556336535150\r\n1.5,\t\t0,\t\t-0.9661051464753110\r\n2.25,\t\t0,\t\t-0.9985372834133190\r\n3,\t\t0,\t\t-0.9999779095030010\r\n3.75,\t\t0,\t\t-0.9999998862727430\r\n4.5,\t\t0,\t\t-0.9999999998033840\r\n-1.5,\t\t0.75,\t\t1.6772607801288300\r\n-0.75,\t\t0.75,\t\t1.4223112673070300\r\n0,\t\t0.75,\t\t0.7111556336535150\r\n0.75,\t\t0.75,\t\t0.0\r\n1.5,\t\t0.75,\t\t-0.2549495128217960\r\n2.25,\t\t0.75,\t\t-0.2873816497598040\r\n3,\t\t0.75,\t\t-0.2888222758494860\r\n3.75,\t\t0.75,\t\t-0.2888442526192280\r\n4.5,\t\t0.75,\t\t-0.2888443661498690\r\n-1.5,\t\t1.5,\t\t1.9322102929506200\r\n-0.75,\t\t1.5,\t\t1.6772607801288300\r\n0,\t\t1.5,\t\t0.9661051464753110\r\n0.75,\t\t1.5,\t\t0.2549495128217960\r\n1.5,\t\t1.5,\t\t0.0\r\n2.25,\t\t1.5,\t\t-0.0324321369380081\r\n3,\t\t1.5,\t\t-0.0338727630276906\r\n3.75,\t\t1.5,\t\t-0.0338947397974326\r\n4.5,\t\t1.5,\t\t-0.0338948533280732\r\n-1.5,\t\t2.25,\t\t1.9646424298886300\r\n-0.75,\t\t2.25,\t\t1.7096929170668300\r\n0,\t\t2.25,\t\t0.9985372834133190\r\n0.75,\t\t2.25,\t\t0.2873816497598040\r\n1.5,\t\t2.25,\t\t0.0324321369380081\r\n2.25,\t\t2.25,\t\t0.0\r\n3,\t\t2.25,\t\t-0.0014406260896825\r\n3.75,\t\t2.25,\t\t-0.0014626028594246\r\n4.5,\t\t2.25,\t\t-0.0014627163900651\r\n-1.5,\t\t3,\t\t1.9660830559783100\r\n-0.75,\t\t3,\t\t1.7111335431565200\r\n0,\t\t3,\t\t0.9999779095030010\r\n0.75,\t\t3,\t\t0.2888222758494860\r\n1.5,\t\t3,\t\t0.0338727630276906\r\n2.25,\t\t3,\t\t0.0014406260896825\r\n3,\t\t3,\t\t0.0\r\n3.75,\t\t3,\t\t-0.0000219767697420\r\n4.5,\t\t3,\t\t-0.0000220903003826\r\n-1.5,\t\t3.75,\t\t1.9661050327480500\r\n-0.75,\t\t3.75,\t\t1.7111555199262600\r\n0,\t\t3.75,\t\t0.9999998862727430\r\n0.75,\t\t3.75,\t\t0.2888442526192280\r\n1.5,\t\t3.75,\t\t0.0338947397974326\r\n2.25,\t\t3.75,\t\t0.0014626028594246\r\n3,\t\t3.75,\t\t0.0000219767697420\r\n3.75,\t\t3.75,\t\t0.0\r\n4.5,\t\t3.75,\t\t-0.0000001135306406\r\n-1.5,\t\t4.5,\t\t1.9661051462786900\r\n-0.75,\t\t4.5,\t\t1.7111556334569000\r\n0,\t\t4.5,\t\t0.9999999998033840\r\n0.75,\t\t4.5,\t\t0.2888443661498690\r\n1.5,\t\t4.5,\t\t0.0338948533280732\r\n2.25,\t\t4.5,\t\t0.0014627163900651\r\n3,\t\t4.5,\t\t0.0000220903003826\r\n3.75,\t\t4.5,\t\t0.0000001135306406\r\n4.5,\t\t4.5,\t\t0.0\r\n5,\t\t-1,\t\t-1.8427007929481800\r\n-5,\t\t1,\t\t1.8427007929481800\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/ERFC.data",
    "content": "# x value\tResult\r\n0,\t\t1.0\r\n0.01,\t\t0.9887165844441500\r\n0.05,\t\t0.9436280222029830\r\n0.1,\t\t0.8875370839817150\r\n0.125,\t\t0.8596837951986660\r\n0.15,\t\t0.8320040285726360\r\n0.2,\t\t0.7772974107895220\r\n0.25,\t\t0.7236736098317630\r\n0.3,\t\t0.6713732405408730\r\n0.35,\t\t0.6206179464376900\r\n0.4,\t\t0.5716076449533320\r\n0.45,\t\t0.5245182802130760\r\n0.5,\t\t0.4795001221869530\r\n0.6,\t\t0.3961439091520740\r\n0.7,\t\t0.3221988061625820\r\n0.8,\t\t0.2578990352923390\r\n0.9,\t\t0.2030917875771680\r\n1,\t\t0.1572992070502850\r\n1.1,\t\t0.1197949304259180\r\n1.2,\t\t0.0896860217703646\r\n1.3,\t\t0.0659920550593475\r\n1.4,\t\t0.0477148802373512\r\n1.5,\t\t0.0338948535246893\r\n1.75,\t\t0.0133283287808176\r\n2,\t\t0.0046777349810473\r\n2.5,\t\t0.0004069520174450\r\n3,\t\t0.0000220904969986\r\n3.5,\t\t0.0000007430983723\r\n4,\t\t0.0000000154172579\r\n4.5,\t\t0.0000000001966160\r\n5,\t\t0.0000000000015375\r\n5.5,\t\t0.0000000000000074\r\n6,\t\t0.0\r\n32,\t\t0.0\r\n-0.1,\t\t1.1124629160182900\r\n-1,\t\t1.8427007929497100\r\nTRUE,\t\t\"#VALUE!\"\r\nFALSE,\t\t\"#VALUE!\"\r\n\"2\",\t\t0.0046777349810473\r\n\"TWO\",\t\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/GESTEP.data",
    "content": "-1.5,\t-1.5,\t1\r\n-0.75,\t-1.5,\t1\r\n0,\t-1.5,\t1\r\n0.75,\t-1.5,\t1\r\n1.5,\t-1.5,\t1\r\n2.25,\t-1.5,\t1\r\n3,\t-1.5,\t1\r\n3.75,\t-1.5,\t1\r\n4.5,\t-1.5,\t1\r\n-1.5,\t-0.75,\t0\r\n-0.75,\t-0.75,\t1\r\n0,\t-0.75,\t1\r\n0.75,\t-0.75,\t1\r\n1.5,\t-0.75,\t1\r\n2.25,\t-0.75,\t1\r\n3,\t-0.75,\t1\r\n3.75,\t-0.75,\t1\r\n4.5,\t-0.75,\t1\r\n-1.5,\t0,\t0\r\n-0.75,\t0,\t0\r\n0,\t0,\t1\r\n0.75,\t0,\t1\r\n1.5,\t0,\t1\r\n2.25,\t0,\t1\r\n3,\t0,\t1\r\n3.75,\t0,\t1\r\n4.5,\t0,\t1\r\n-1.5,\t0.75,\t0\r\n-0.75,\t0.75,\t0\r\n0,\t0.75,\t0\r\n0.75,\t0.75,\t1\r\n1.5,\t0.75,\t1\r\n2.25,\t0.75,\t1\r\n3,\t0.75,\t1\r\n3.75,\t0.75,\t1\r\n4.5,\t0.75,\t1\r\n-1.5,\t1.5,\t0\r\n-0.75,\t1.5,\t0\r\n0,\t1.5,\t0\r\n0.75,\t1.5,\t0\r\n1.5,\t1.5,\t1\r\n2.25,\t1.5,\t1\r\n3,\t1.5,\t1\r\n3.75,\t1.5,\t1\r\n4.5,\t1.5,\t1\r\n-1.5,\t2.25,\t0\r\n-0.75,\t2.25,\t0\r\n0,\t2.25,\t0\r\n0.75,\t2.25,\t0\r\n1.5,\t2.25,\t0\r\n2.25,\t2.25,\t1\r\n3,\t2.25,\t1\r\n3.75,\t2.25,\t1\r\n4.5,\t2.25,\t1\r\n-1.5,\t3,\t0\r\n-0.75,\t3,\t0\r\n0,\t3,\t0\r\n0.75,\t3,\t0\r\n1.5,\t3,\t0\r\n2.25,\t3,\t0\r\n3,\t3,\t1\r\n3.75,\t3,\t1\r\n4.5,\t3,\t1\r\n-1.5,\t3.75,\t0\r\n-0.75,\t3.75,\t0\r\n0,\t3.75,\t0\r\n0.75,\t3.75,\t0\r\n1.5,\t3.75,\t0\r\n2.25,\t3.75,\t0\r\n3,\t3.75,\t0\r\n3.75,\t3.75,\t1\r\n4.5,\t3.75,\t1\r\n-1.5,\t4.5,\t0\r\n-0.75,\t4.5,\t0\r\n0,\t4.5,\t0\r\n0.75,\t4.5,\t0\r\n1.5,\t4.5,\t0\r\n2.25,\t4.5,\t0\r\n3,\t4.5,\t0\r\n3.75,\t4.5,\t0\r\n4.5,\t4.5,\t1\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/HEX2BIN.data",
    "content": "\"01AB\",\t\t\t\"110101011\"\r\n\"ABCD\",\t\t\t\"#NUM!\"\r\n\"F6\",\t\t\t\"11110110\"\r\n\"F\",\t\t8,\t\"00001111\"\r\n\"B7\",\t\t\t\"10110111\"\r\n\"12345\",\t\t\"#NUM!\"\r\n\"123456789\",\t\t\"#NUM!\"\r\n\"123.45\",\t\t\"#NUM!\"\r\n\"0\",\t\t\t\"0\"\r\n\"G3579A\",\t\t\"#NUM!\"\r\nTRUE,\t\t\t\"#VALUE!\"\r\n\"-107\",\t\t\t\"#NUM!\"\r\n\"FFFFFFFFFF\",\t\t\"1111111111\"\t//\t2's Complement\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/HEX2DEC.data",
    "content": "\"01AB\",\t\t\"427\"\r\n\"ABCD\",\t\t\"43981\"\r\n\"F6\",\t\t\"246\"\r\n\"12345\",\t\"74565\"\r\n\"123456789\",\t\"4886718345\"\r\n\"123.45\",\t\"#NUM!\"\r\n\"0\",\t\t\"0\"\r\n\"G3579A\",\t\"#NUM!\"\r\nTRUE,\t\t\"#VALUE!\"\r\n\"-107\",\t\t\"#NUM!\"\r\n\"A5\",\t\t\"165\"\r\n\"FFFFFFFF5B\",\t\"-165\"\r\n\"3DA408B9\",\t\"1034160313\"\t//\t2's Complement\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/HEX2OCT.data",
    "content": "\"01AB\",\t\t\t\"653\"\r\n\"ABCD\",\t\t\t\"125715\"\r\n\"F6\",\t\t\t\"366\"\r\n\"3B4E\",\t\t\t\"35516\"\r\n\"F\",\t\t3,\t\"017\"\r\n\"12345\",\t\t\"221505\"\r\n\"123456789\",\t\t\"#NUM!\"\r\n\"123.45\",\t\t\"#NUM!\"\r\n\"0\",\t\t\t\"0\"\r\n\"G3579A\",\t\t\"#NUM!\"\r\nTRUE,\t\t\t\"#VALUE!\"\r\n\"-107\",\t\t\t\"#NUM!\"\r\n\"FFFFFFFF00\",\t\t\"7777777400\"\t//\t2's Complement\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMABS.data",
    "content": "\"12.34+5.67j\",\t\t13.580298229420\r\n\"1.234E-5+6.78E9i\",\t6.78E9\r\n\"3.5+2.5i\",\t\t4.301162633521\r\n\"3.5+i\",\t\t3.640054944640\r\n\"3.5\",\t\t\t3.5\r\n\"3.5-i\",\t\t3.640054944640\r\n\"3.5-2.5i\",\t\t4.301162633521\r\n\"1+2.5i\",\t\t2.692582403567\r\n\"1+i\",\t\t\t1.414213562373\r\n\"1\",\t\t\t1\r\n\"1-i\",\t\t\t1.414213562373\r\n\"1-2.5i\",\t\t2.692582403567\r\n\"2.5i\",\t\t\t2.5\r\n\"i\",\t\t\t1\r\n\"0\",\t\t\t0\r\n\"-i\",\t\t\t1\r\n\"-2.5i\",\t\t2.5\r\n\"-1+2.5i\",\t\t2.692582403567\r\n\"-1+i\",\t\t\t1.414213562373\r\n\"-1\",\t\t\t1\r\n\"-1-i\",\t\t\t1.414213562373\r\n\"-1-2.5i\",\t\t2.692582403567\r\n\"-3.5+2.5i\",\t\t4.301162633521\r\n\"-3.5+i\",\t\t3.640054944640\r\n\"-3.5\",\t\t\t3.5\r\n\"-3.5-i\",\t\t3.640054944640\r\n\"-3.5-2.5i\",\t\t4.301162633521\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMAGINARY.data",
    "content": "\"12.34+5.67j\",\t\t5.67\r\n\"1.234E-5+6.78E9i\",\t6.78E9\r\n\"3.5+2.5i\",\t\t2.5\r\n\"3.5+i\",\t\t1\r\n\"3.5\",\t\t\t0\r\n\"3.5-i\",\t\t-1\r\n\"3.5-2.5i\",\t\t-2.5\r\n\"1+2.5i\",\t\t2.5\r\n\"1+i\",\t\t\t1\r\n\"1\",\t\t\t0\r\n1,\t\t\t0\r\n\"1-i\",\t\t\t-1\r\n\"1-2.5i\",\t\t-2.5\r\n\"2.5i\",\t\t\t2.5\r\n\"i\",\t\t\t1\r\n\"0\",\t\t\t0\r\n0,\t\t\t0\r\n0.0,\t\t\t0\r\n\"-i\",\t\t\t-1\r\n\"-2.5i\",\t\t-2.5\r\n\"-1+2.5i\",\t\t2.5\r\n\"-1+i\",\t\t\t1\r\n\"-1\",\t\t\t0\r\n\"-1-i\",\t\t\t-1\r\n\"-1-2.5i\",\t\t-2.5\r\n\"-3.5+2.5i\",\t\t2.5\r\n\"-3.5+i\",\t\t1\r\n\"-3.5\",\t\t\t0\r\n\"-3.5-i\",\t\t-1\r\n\"-3.5-2.5i\",\t\t-2.5\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMARGUMENT.data",
    "content": "\"12.34+5.67j\",\t0.430710595550\r\n\"3.5+2.5i\",\t0.620249485983\r\n\"3.5+i\",\t0.278299659005\r\n\"3.5\",\t\t0\r\n\"3.5-i\",\t-0.278299659005\r\n\"3.5-2.5i\",\t-0.620249485983\r\n\"1+2.5i\",\t1.190289949683\r\n\"1+i\",\t\t0.785398163397\r\n\"1\",\t\t0\r\n\"1-i\",\t\t-0.785398163397\r\n\"1-2.5i\",\t-1.190289949683\r\n\"2.5i\",\t\t1.570796326795\r\n\"i\",\t\t1.570796326795\r\n\"0\",\t\t\"#DIV/0!\"\r\n\"-i\",\t\t-1.570796326795\r\n\"-2.5i\",\t-1.570796326795\r\n\"-1+2.5i\",\t1.951302703907\r\n\"-1+i\",\t\t2.356194490192\r\n\"-1\",\t\t3.141592653590\r\n\"-1-i\",\t\t-2.356194490192\r\n\"-1-2.5i\",\t-1.951302703907\r\n\"-3.5+2.5i\",\t2.521343167607\r\n\"-3.5+i\",\t2.863292994585\r\n\"-3.5\",\t\t3.141592653590\r\n\"-3.5-i\",\t-2.863292994585\r\n\"-3.5-2.5i\",\t-2.521343167607\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMCONJUGATE.data",
    "content": "\"12.34+5.67j\",\t\"12.34-5.67j\"\r\n\"3.5+2.5i\",\t\"3.5-2.5i\"\r\n\"3.5+i\",\t\"3.5-i\"\r\n\"3.5\",\t\t\"3.5\"\r\n\"3.5-i\",\t\"3.5+i\"\r\n\"3.5-2.5i\",\t\"3.5+2.5i\"\r\n\"1+2.5i\",\t\"1-2.5i\"\r\n\"1+i\",\t\t\"1-i\"\r\n\"1\",\t\t\"1\"\r\n\"1-i\",\t\t\"1+i\"\r\n\"1-2.5i\",\t\"1+2.5i\"\r\n\"2.5i\",\t\t\"-2.5i\"\r\n\"i\",\t\t\"-i\"\r\n\"0\",\t\t\"0\"\r\n\"-i\",\t\t\"i\"\r\n\"-2.5i\",\t\"2.5i\"\r\n\"-1+2.5i\",\t\"-1-2.5i\"\r\n\"-1+i\",\t\t\"-1-i\"\r\n\"-1\",\t\t\"-1\"\r\n\"-1-i\",\t\t\"-1+i\"\r\n\"-1-2.5i\",\t\"-1+2.5i\"\r\n\"-3.5+2.5i\",\t\"-3.5-2.5i\"\r\n\"-3.5+i\",\t\"-3.5-i\"\r\n\"-3.5\",\t\t\"-3.5\"\r\n\"-3.5-i\",\t\"-3.5+i\"\r\n\"-3.5-2.5i\",\t\"-3.5+2.5i\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMCOS.data",
    "content": "\"12.34+5.67j\",\t\"141.319179436356+32.547610312508j\"\r\n\"3.5+2.5i\",\t\"-5.74262349163406+2.12231025604134i\"\r\n\"3.5+i\",\t\"-1.44502817950166+0.412240867891067i\"\r\n\"3.5\",\t\t\"-0.936456687290796\"\r\n\"3.5-i\",\t\"-1.44502817950166-0.412240867891067i\"\r\n\"3.5-2.5i\",\t\"-5.74262349163406-2.12231025604134i\"\r\n\"1+2.5i\",\t\"3.31329014611322-5.0910715229497i\"\r\n\"1+i\",\t\t\"0.833730025131149-0.988897705762865i\"\r\n\"1\",\t\t\"0.54030230586814\"\r\n\"1-i\",\t\t\"0.833730025131149+0.988897705762865i\"\r\n\"1-2.5i\",\t\"3.31329014611322+5.0910715229497i\"\r\n\"2.5i\",\t\t\"6.13228947966369\"\r\n\"i\",\t\t\"1.54308063481524\"\r\n\"0\",\t\t\"1\"\r\n\"-i\",\t\t\"1.54308063481524\"\r\n\"-2.5i\",\t\"6.13228947966369\"\r\n\"-1+2.5i\",\t\"3.31329014611322+5.0910715229497i\"\r\n\"-1+i\",\t\t\"0.833730025131149+0.988897705762865i\"\r\n\"-1\",\t\t\"0.54030230586814\"\r\n\"-1-i\",\t\t\"0.833730025131149-0.988897705762865i\"\r\n\"-1-2.5i\",\t\"3.31329014611322-5.0910715229497i\"\r\n\"-3.5+2.5i\",\t\"-5.74262349163406-2.12231025604134i\"\r\n\"-3.5+i\",\t\"-1.44502817950166-0.412240867891067i\"\r\n\"-3.5\",\t\t\"-0.936456687290796\"\r\n\"-3.5-i\",\t\"-1.44502817950166+0.412240867891067i\"\r\n\"-3.5-2.5i\",\t\"-5.74262349163406+2.12231025604134i\"\r\n\"3\",\t\t\"-0.989992496600445\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMDIV.data",
    "content": "\"12.34+5.67j\",\t\"123.45+67.89i\",\t\"#NUM!\"\r\n\"12.34+5.67j\",\t\"123.45+67.89j\",\t\"0.0961415519586104-0.00694248653276682j\"\r\n\"-12.34+5.67i\",\t\"-123.45+67.89i\",\t\"0.0961415519586104+0.00694248653276682i\"\r\n\"-12.34-5.67i\",\t\"-123.45+67.89i\",\t\"0.0573549954111941+0.0774712890924744i\"\r\n\"-12.34+5.67i\",\t\"-123.45-67.89i\",\t\"0.0573549954111941-0.0774712890924744i\"\r\n\"-12.34-5.67i\",\t\"-123.45-67.89i\",\t\"0.0961415519586104-0.00694248653276682i\"\r\n\"12.34+5.67i\",\t\"-123.45+67.89i\",\t\"-0.0573549954111941-0.0774712890924744i\"\r\n\"12.34-5.67i\",\t\"-123.45+67.89i\",\t\"-0.0961415519586104-0.00694248653276682i\"\r\n\"12.34+5.67i\",\t\"-123.45-67.89i\",\t\"-0.0961415519586104+0.00694248653276682i\"\r\n\"12.34-5.67i\",\t\"-123.45-67.89i\",\t\"-0.0573549954111941+0.0774712890924744i\"\r\n\"-12.34+5.67i\",\t\"123.45+67.89i\",\t\"-0.0573549954111941+0.0774712890924744i\"\r\n\"-12.34-5.67i\",\t\"123.45+67.89i\",\t\"-0.0961415519586104+0.00694248653276682i\"\r\n\"-12.34+5.67i\",\t\"123.45-67.89i\",\t\"-0.0961415519586104-0.00694248653276682i\"\r\n\"-12.34-5.67i\",\t\"123.45-67.89i\",\t\"-0.0573549954111941-0.0774712890924744i\"\r\n\"-12.34-5.67i\",\t\"123.45-67.89\",\t\t\"#NUM!\"\r\n\"-12.34-5.67j\",\t\"123.45-67.89\",\t\t\"#NUM!\"\r\n\"-12.34-5.67\",\t\"123.45-67.89j\",\t\"#NUM!\"\r\n\"-12.34-5.67i\",\t\"-12.34-5.67i\",\t\t\"1\"\r\n\"-12.34\",\t\"123.45-67.89i\",\t\"-0.0767482736849023-0.0422068878126206i\"\r\n\"-12.34-5.67i\",\t\"-12.34\",\t\t\"1+0.459481361426256i\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMEXP.data",
    "content": "\"12.34+5.67j\",\t\t\"187004.11273906-131589.323796073j\"\r\n\"-12.34E-5+6.78E9i\",\t\"1.79747131321615E+308+1.79747131321615E+308i\"\r\n\"3.5+2.5i\",\t\t\"-26.5302329126575+19.8186755366902i\"\r\n\"3.5+i\",\t\t\"17.8923550531471+27.8656919720394i\"\r\n\"3.5\",\t\t\t\"33.1154519586923\"\r\n\"3.5-i\",\t\t\"17.8923550531471-27.8656919720394i\"\r\n\"3.5-2.5i\",\t\t\"-26.5302329126575-19.8186755366902i\"\r\n\"1+2.5i\",\t\t\"-2.17773413212721+1.62681595415671i\"\r\n\"1+i\",\t\t\t\"1.46869393991589+2.28735528717884i\"\r\n\"1\",\t\t\t\"2.71828182845905\"\r\n\"1-i\",\t\t\t\"1.46869393991589-2.28735528717884i\"\r\n\"1-2.5i\",\t\t\"-2.17773413212721-1.62681595415671i\"\r\n\"2.5i\",\t\t\t\"-0.801143615546934+0.598472144103957i\"\r\n\"i\",\t\t\t\"0.54030230586814+0.841470984807897i\"\r\n\"0\",\t\t\t\"1\"\r\n\"-i\",\t\t\t\"0.54030230586814-0.841470984807897i\"\r\n\"-2.5i\",\t\t\"-0.801143615546934-0.598472144103957i\"\r\n\"-1+2.5i\",\t\t\"-0.294724265585475+0.220165597929638i\"\r\n\"-1+i\",\t\t\t\"0.198766110346413+0.309559875653112i\"\r\n\"-1\",\t\t\t\"0.367879441171442\"\r\n\"-1-i\",\t\t\t\"0.198766110346413-0.309559875653112i\"\r\n\"-1-2.5i\",\t\t\"-0.294724265585475-0.220165597929638i\"\r\n\"-3.5+2.5i\",\t\t\"-0.0241924409350133+0.0180722928030842i\"\r\n\"-3.5+i\",\t\t\"0.016315715894263+0.025410221967i\"\r\n\"-3.5\",\t\t\t\"0.0301973834223185\"\r\n\"-3.5-i\",\t\t\"0.016315715894263-0.025410221967i\"\r\n\"-3.5-2.5i\",\t\t\"-0.0241924409350133-0.0180722928030842i\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMLN.data",
    "content": "\"12.34+5.67j\",\t\t\"2.60862008281875+0.430710595550204j\"\r\n\"-1.234E-5+6.78E9i\",\t\"22.6372429388987+1.5707963267949i\"\r\n\"3.5+2.5i\",\t\t\"1.45888536604214+0.620249485982821i\"\r\n\"3.5+i\",\t\t\t\"1.29199877621612+0.278299659005111i\"\r\n\"3.5\",\t\t\t\"1.25276296849537\"\r\n\"3.5-i\",\t\t\t\"1.29199877621612-0.278299659005111i\"\r\n\"3.5-2.5i\",\t\t\"1.45888536604214-0.620249485982821i\"\r\n\"1+2.5i\",\t\t\"0.990500734433292+1.19028994968253i\"\r\n\"1+i\",\t\t\t\"0.346573590279973+0.785398163397448i\"\r\n\"1\",\t\t\t\"0\"\r\n\"1-i\",\t\t\t\"0.346573590279973-0.785398163397448i\"\r\n\"1-2.5i\",\t\t\"0.990500734433292-1.19028994968253i\"\r\n\"2.5i\",\t\t\t\"0.916290731874155+1.5707963267949i\"\r\n\"i\",\t\t\t\"1.5707963267949i\"\r\n\"0\",\t\t\t\"#NUM!\"\r\n\"-i\",\t\t\t\"-1.5707963267949i\"\r\n\"-2.5i\",\t\t\t\"0.916290731874155-1.5707963267949i\"\r\n\"-1+2.5i\",\t\t\"0.990500734433292+1.95130270390726i\"\r\n\"-1+i\",\t\t\t\"0.346573590279973+2.35619449019234i\"\r\n\"-1\",\t\t\t\"3.14159265358979i\"\r\n\"-1-i\",\t\t\t\"0.346573590279973-2.35619449019234i\"\r\n\"-1-2.5i\",\t\t\"0.990500734433292-1.95130270390726i\"\r\n\"-3.5+2.5i\",\t\t\"1.45888536604214+2.52134316760697i\"\r\n\"-3.5+i\",\t\t\"1.29199877621612+2.86329299458468i\"\r\n\"-3.5\",\t\t\t\"1.25276296849537+3.14159265358979i\"\r\n\"-3.5-i\",\t\t\"1.29199877621612-2.86329299458468i\"\r\n\"-3.5-2.5i\",\t\t\"1.45888536604214-2.52134316760697i\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMLOG10.data",
    "content": "\"12.34+5.67j\",\t\t\"1.13290930735019+0.187055234944717j\"\r\n\"-12.34E-5+6.78E9i\",\t\"9.83122969386706+0.682188176920927i\"\r\n\"3.5+2.5i\",\t\t\"0.633585864201507+0.269370929165668i\"\r\n\"3.5+i\",\t\t\"0.561107939136413+0.120864006221476i\"\r\n\"3.5\",\t\t\t\"0.544068044350276\"\r\n\"3.5-i\",\t\t\"0.561107939136413-0.120864006221476i\"\r\n\"3.5-2.5i\",\t\t\"0.633585864201507-0.269370929165668i\"\r\n\"1+2.5i\",\t\t\"0.430169003285497+0.516936357012023i\"\r\n\"1+i\",\t\t\t\"0.150514997831991+0.34109408846046i\"\r\n\"1\",\t\t\t\"0\"\r\n\"1-i\",\t\t\t\"0.150514997831991-0.34109408846046i\"\r\n\"1-2.5i\",\t\t\"0.430169003285497-0.516936357012023i\"\r\n\"2.5i\",\t\t\t\"0.397940008672038+0.68218817692092i\"\r\n\"i\",\t\t\t\"0.68218817692092i\"\r\n\"0\",\t\t\t\"#NUM!\"\r\n\"-i\",\t\t\t\"-0.68218817692092i\"\r\n\"-2.5i\",\t\t\"0.397940008672038-0.68218817692092i\"\r\n\"-1+2.5i\",\t\t\"0.430169003285497+0.847439996829817i\"\r\n\"-1+i\",\t\t\t\"0.150514997831991+1.02328226538138i\"\r\n\"-1\",\t\t\t\"1.36437635384184i\"\r\n\"-1-i\",\t\t\t\"0.150514997831991-1.02328226538138i\"\r\n\"-1-2.5i\",\t\t\"0.430169003285497-0.847439996829817i\"\r\n\"-3.5+2.5i\",\t\t\"0.633585864201507+1.09500542467617i\"\r\n\"-3.5+i\",\t\t\"0.561107939136413+1.24351234762036i\"\r\n\"-3.5\",\t\t\t\"0.544068044350276+1.36437635384184i\"\r\n\"-3.5-i\",\t\t\"0.561107939136413-1.24351234762036i\"\r\n\"-3.5-2.5i\",\t\t\"0.633585864201507-1.09500542467617i\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMLOG2.data",
    "content": "\"12.34+5.67j\",\t\t\"3.76344325733562+0.621384040306436j\"\r\n\"-12.34E-5+6.78E9i\",\t\"32.6586381298614+2.26618007108803i\"\r\n\"3.5+2.5i\",\t\t\"2.10472668297646+0.894830857610216i\"\r\n\"3.5+i\",\t\t\"1.86396022742506+0.401501537958665i\"\r\n\"3.5\",\t\t\t\"1.80735492219671\"\r\n\"3.5-i\",\t\t\"1.86396022742506-0.401501537958665i\"\r\n\"3.5-2.5i\",\t\t\"2.10472668297646-0.894830857610216i\"\r\n\"1+2.5i\",\t\t\"1.42899049767377+1.71722540775913i\"\r\n\"1+i\",\t\t\t\"0.500000000038482+1.13309003554401i\"\r\n\"1\",\t\t\t\"0\"\r\n\"1-i\",\t\t\t\"0.500000000038482-1.13309003554401i\"\r\n\"1-2.5i\",\t\t\"1.42899049767377-1.71722540775913i\"\r\n\"2.5i\",\t\t\t\"1.3219280949891+2.26618007108801i\"\r\n\"i\",\t\t\t\"2.26618007108801i\"\r\n\"0\",\t\t\t\"#NUM!\"\r\n\"-i\",\t\t\t\"-2.26618007108801i\"\r\n\"-2.5i\",\t\t\"1.3219280949891-2.26618007108801i\"\r\n\"-1+2.5i\",\t\t\"1.42899049767377+2.81513473441689i\"\r\n\"-1+i\",\t\t\t\"0.500000000038482+3.39927010663201i\"\r\n\"-1\",\t\t\t\"4.53236014217602i\"\r\n\"-1-i\",\t\t\t\"0.500000000038482-3.39927010663201i\"\r\n\"-1-2.5i\",\t\t\"1.42899049767377-2.81513473441689i\"\r\n\"-3.5+2.5i\",\t\t\"2.10472668297646+3.63752928456581i\"\r\n\"-3.5+i\",\t\t\"1.86396022742506+4.13085860421736i\"\r\n\"-3.5\",\t\t\t\"1.80735492219671+4.53236014217602i\"\r\n\"-3.5-i\",\t\t\"1.86396022742506-4.13085860421736i\"\r\n\"-3.5-2.5i\",\t\t\"2.10472668297646-3.63752928456581i\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMPOWER.data",
    "content": "\"12.34+5.67j\",\t2,\t\t\"120.1267+139.9356j\"\r\n\"12.34+5.67j\",\t3,\t\t\"688.928626+2407.923693j\"\r\n\"12.34+5.67j\",\t-1,\t\t\"6.69108496973016E-002-3.07442883131037E-002j\"\r\n\"12.34+5.67j\",\t-2,\t\t\"3.53185054333564E-003-4.11425290873718E-003j\"\r\n\"12.34+5.67j\",\t0.5,\t\t\"3.60002071031685+0.787495469644252j\"\r\n\"12.34+5.67j\",\t-0.25,\t\t\"0.517904976730581-5.59833234375533E-002j\"\r\n\"12.34+5.67j\",\t0,\t\t\"1\"\r\n\"-i\",\t\t2,\t\t\"-1-1.34451369308841E-014i\"\r\n\"1-i\",\t\t2,\t\t\"1.22460635382238E-016-2i\"\r\n\"2.5i\",\t\t2,\t\t\"-6.25+8.40321058180257E-014i\"\r\n\"2.5i\",\t\t\"2.5\",\t\t\"-6.98771242968685-6.98771242968684i\"\r\n\"2.5i\",\t\t\"2.5i\",\t\t\"#VALUE!\"\r\n\"2.5\",\t\t\"2.5\",\t\t9.88211768802619\r\n\"2\",\t\t\"2\",\t\t4\r\n\"-12.34-5.67i\",\t\"-12.34\",\t\"-4.69972844488573E-15+9.35464904349343E-15i\"\r\n\"12.34-5.67i\",\t\"-12.34\",\t\"5.93343000067521E-15-8.62503997728057E-15i\"\r\n\"-12.34-5.67i\",\t\"12.34\",\t\"-42881944468901.9-85355046682682.3i\"\r\n\"12.34-5.67i\",\t\"12.34\",\t\"54138663282971.3+78697841733874.3i\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMPRODUCT.data",
    "content": "\"12.34+5.67j\",\t\"123.45+67.89i\",\t\t\t\"#NUM!\"\r\n\"12.34+5.67j\",\t\t\t\t\t\t\"12.34+5.67j\"\r\n\"12.34+5.67i\",\t\"123.45+67.89i\",\t\"5.67\",\t\t\"6454.936089+8718.895647i\"\r\n\"12.34+5.67j\",\t\"123.45+67.89j\",\t\"5.67\",\t\t\"6454.936089+8718.895647j\"\r\n\"12.34+5.67j\",\t\"123.45+67.89j\",\t\t\t\"1138.4367+1537.7241j\"\r\n\"12.34-5.67i\",\t\"123.45+67.89i\",\t\t\t\"1908.3093+137.8011i\"\r\n\"12.34+5.67i\",\t\"123.45-67.89i\",\t\t\t\"1908.3093-137.8011i\"\r\n\"12.34-5.67i\",\t\"123.45-67.89i\",\t\t\t\"1138.4367-1537.7241i\"\r\n\"-12.34+5.67i\",\t\"123.45+67.89i\",\t\t\t\"-1908.3093-137.8011i\"\r\n\"-12.34-5.67i\",\t\"123.45+67.89i\",\t\t\t\"-1138.4367-1537.7241i\"\r\n\"12.34+5.67i\",\t\"-123.45+67.89i\",\t\t\t\"-1908.3093+137.8011i\"\r\n\"-12.34+5.67i\",\t\"-123.45+67.89i\",\t\t\t\"1138.4367-1537.7241i\"\r\n\"-12.34-5.67i\",\t\"-123.45-67.89i\",\t\t\t\"1138.4367+1537.7241i\"\r\n\"-12.34\",\t\"123.45-67.89i\",\t\t\t\"-1523.373+837.7626i\"\r\n\"-12.34-5.67i\",\t\"-12.34\",\t\t\t\t\"152.2756+69.9678i\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMREAL.data",
    "content": "12.34+5.67j\",\t\t12.34\r\n\"-1.234E-5+6.78E9i\",\t-1.234E-5\r\n\"3.5+2.5i\",\t\t3.5\r\n\"3.5+i\",\t\t3.5\r\n\"3.5\",\t\t\t3.5\r\n3.5,\t\t\t3.5\r\n\"3.5-i\",\t\t3.5\r\n\"3.5-2.5i\",\t\t3.5\r\n\"1+2.5i\",\t\t1\r\n\"1+i\",\t\t\t1\r\n\"1\",\t\t\t1\r\n1,\t\t\t1\r\n\"1-i\",\t\t\t1\r\n\"1-2.5i\",\t\t1\r\n\"2.5i\",\t\t\t0\r\n\"i\",\t\t\t0\r\n\"0\",\t\t\t0\r\n0,\t\t\t0\r\n\"-i\",\t\t\t0\r\n\"-2.5i\",\t\t0\r\n\"-1+2.5i\",\t\t-1\r\n\"-1+i\",\t\t\t-1\r\n\"-1\",\t\t\t-1\r\n\"-1-i\",\t\t\t-1\r\n\"-1-2.5i\",\t\t-1\r\n\"-3.5+2.5i\",\t\t-3.5\r\n\"-3.5+i\",\t\t-3.5\r\n\"-3.5\",\t\t\t-3.5\r\n\"-3.5-i\",\t\t-3.5\r\n\"-3.5-2.5i\",\t\t-3.5\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMSIN.data",
    "content": "\"12.34+5.67j\",\t\"-32.5483841590412+141.315819535092j\"\r\n\"3.5+2.5i\",\t\"-2.15110429680353-5.66575444574645i\"\r\n\"3.5+i\",\t\"-0.541286805665839-1.10052501669986i\"\r\n\"3.5\",\t\t\"-0.35078322768962\"\r\n\"3.5-i\",\t\"-0.541286805665839+1.10052501669986i\"\r\n\"3.5-2.5i\",\t\"-2.15110429680353+5.66575444574645i\"\r\n\"1+2.5i\",\t\"5.16014366757971+3.26893943207955i\"\r\n\"1+i\",\t\t\"1.29845758141598+0.634963914784736i\"\r\n\"1\",\t\t\"0.841470984807897\"\r\n\"1-i\",\t\t\"1.29845758141598-0.634963914784736i\"\r\n\"1-2.5i\",\t\"5.16014366757971-3.26893943207955i\"\r\n\"2.5i\",\t\t\"6.05020448103979i\"\r\n\"i\",\t\t\"1.1752011936438i\"\r\n\"0\",\t\t\"0\"\r\n\"-i\",\t\t\"-1.1752011936438i\"\r\n\"-2.5i\",\t\"-6.05020448103979i\"\r\n\"-1+2.5i\",\t\"-5.16014366757971+3.26893943207955i\"\r\n\"-1+i\",\t\t\"-1.29845758141598+0.634963914784736i\"\r\n\"-1\",\t\t\"-0.841470984807897\"\r\n\"-1-i\",\t\t\"-1.29845758141598-0.634963914784736i\"\r\n\"-1-2.5i\",\t\"-5.16014366757971-3.26893943207955i\"\r\n\"-3.5+2.5i\",\t\"2.15110429680353-5.66575444574645i\"\r\n\"-3.5+i\",\t\"0.541286805665839-1.10052501669986i\"\r\n\"-3.5\",\t\t\"0.35078322768962\"\r\n\"-3.5-i\",\t\"0.541286805665839+1.10052501669986i\"\r\n\"-3.5-2.5i\",\t\"2.15110429680353+5.66575444574645i\"\r\n\"3\",\t\t\"0.141120008059867\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMSQRT.data",
    "content": "\"12.34+5.67j\",\t\t\"3.60002071031685+0.787495469644252j\"\r\n\"-1.234E-5+6.78E9i\",\t\"58223.7065120385+58223.7065120386i\"\r\n\"3.5+2.5i\",\t\t\"1.9749889409211+0.632914936433528i\"\r\n\"3.5+i\",\t\t\"1.88945163270197+0.264627043818521i\"\r\n\"3.5\",\t\t\t\"1.87082869338697\"\r\n\"3.5-i\",\t\t\"1.88945163270197-0.264627043818521i\"\r\n\"3.5-2.5i\",\t\t\"1.9749889409211-0.632914936433528i\"\r\n\"1+2.5i\",\t\t\"1.35878298553655+0.919940868634298i\"\r\n\"1+i\",\t\t\t\"1.09868411346781+0.455089860562227i\"\r\n\"1\",\t\t\t\"1\"\r\n\"1-i\",\t\t\t\"1.09868411346781-0.455089860562227i\"\r\n\"1-2.5i\",\t\t\"1.35878298553655-0.919940868634298i\"\r\n\"2.5i\",\t\t\t\"1.11803398874989+1.11803398874989i\"\r\n\"i\",\t\t\t\"0.707106781186548+0.707106781186547i\"\r\n\"0\",\t\t\t\"0\"\r\n\"-i\",\t\t\t\"0.707106781186548-0.707106781186547i\"\r\n\"-2.5i\",\t\t\"1.11803398874989-1.11803398874989i\"\r\n\"-1+2.5i\",\t\t\"0.919940868634298+1.35878298553655i\"\r\n\"-1+i\",\t\t\t\"0.455089860562227+1.09868411346781i\"\r\n\"-1\",\t\t\t\"6.12303176911189E-017+i\"\r\n\"-1-i\",\t\t\t\"0.455089860562227-1.09868411346781i\"\r\n\"-1-2.5i\",\t\t\"0.919940868634298-1.35878298553655i\"\r\n\"-3.5+2.5i\",\t\t\"0.632914936433528+1.9749889409211i\"\r\n\"-3.5+i\",\t\t\"0.264627043818521+1.88945163270197i\"\r\n\"-3.5\",\t\t\t\"1.14551435241745E-016+1.87082869338697i\"\r\n\"-3.5-i\",\t\t\"0.264627043818521-1.88945163270197i\"\r\n\"-3.5-2.5i\",\t\t\"0.632914936433528-1.9749889409211i\"\r\n\"9\",\t\t\t\"3\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMSUB.data",
    "content": "\"12.34+5.67j\",\t\t\"123.45+67.89i\",\t\t\t\t\"#NUM!\"\r\n\"123.45+67.89j\",\t\"12.34+5.67j\",\t\t\t\t\t\"111.11+62.22j\"\r\n\"12.34+5.67j\",\t\t\"123.45+67.89j\",\t\t\t\t\"-111.11-62.22j\"\r\n\"12.34+5.67i\",\t\t\"123.45+67.89i\",\t\"123.45+67.89i\",\t\"-111.11-62.22i\"\r\n\"-12.34-5.67i\",\t\t\"123.45-67.89i\",\t\t\t\t\"-135.79+62.22i\"\r\n\"12.34-5.67i\",\t\t\"-123.45-67.89i\",\t\t\t\t\"135.79+62.22i\"\r\n\"-12.34-5.67i\",\t\t\"-123.45-67.89i\",\t\t\t\t\"111.11+62.22i\"\r\n\"-12.34-5.67i\",\t\t\"-123.45-67.89\",\t\t\t\t\"#NUM!\"\r\n\"-12.34-5.67j\",\t\t\"-123.45-67.89\",\t\t\t\t\"#NUM!\"\r\n\"-12.34-5.67\",\t\t\"-123.45-67.89j\",\t\t\t\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/IMSUM.data",
    "content": "\"12.34+5.67j\",\t\"123.45+67.89i\",\t\t\t\t\"#NUM!\"\r\n\"12.34+5.67j\",\t\"123.45+67.89j\",\t\t\t\t\"135.79+73.56j\"\r\n\"12.34-5.67i\",\t\"123.45+67.89i\",\t\t\t\t\"135.79+62.22i\"\r\n\"12.34+5.67i\",\t\"123.45-67.89i\",\t\t\t\t\"135.79-62.22i\"\r\n\"12.34-5.67i\",\t\"123.45-67.89i\",\t\t\t\t\"135.79-73.56i\"\r\n\"12.34+5.67i\",\t\"123.45+67.89i\",\t\"123.45+67.89i\",\t\"259.24+141.45i\"\r\n\"12.34+5.67i\",\t\"123.45+67.89i\",\t\"123.45+67.89j\",\t\"#NUM!\"\r\n\"-12.34-5.67i\",\t\"123.45-67.89i\",\t\t\t\t\"111.11-73.56i\"\r\n\"12.34-5.67i\",\t\"-123.45-67.89i\",\t\t\t\t\"-111.11-73.56i\"\r\n\"-12.34-5.67i\",\t\"-123.45-67.89i\",\t\t\t\t\"-135.79-73.56i\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/OCT2BIN.data",
    "content": "\"1357\",\t\t\t\"#NUM!\"\r\n\"246\",\t\t\t\"10100110\"\r\n\"3\",\t\t3,\t\"011\"\r\n\"12345\",\t\t\"#NUM!\"\r\n\"123.45\",\t\t\"#NUM!\"\r\n\"0\",\t\t\t\"0\"\r\nTRUE,\t\t\t\"#VALUE!\"\r\n\"3579\",\t\t\t\"#NUM!\"\r\n\"7777777000\",\t\t\"1000000000\"\t//\t2's Complement\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/OCT2DEC.data",
    "content": "\"1357\",\t\t\"751\"\r\n\"246\",\t\t\"166\"\r\n\"12345\",\t\"5349\"\r\n\"123.45\",\t\"#NUM!\"\r\n\"0\",\t\t\"0\"\r\nTRUE,\t\t\"#VALUE!\"\r\n\"3579\",\t\t\"#NUM!\"\r\n\"54\",\t\t\"44\"\r\n\"7777777533\",\t\"-165\"\t//\t2's Complement\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Engineering/OCT2HEX.data",
    "content": "\"1357\",\t\t\t\"2EF\"\r\n\"246\",\t\t\t\"A6\"\r\n\"12345\",\t\t\"14E5\"\r\n\"100\",\t\t4,\t\"0040\"\r\n\"123.45\",\t\t\"#NUM!\"\r\n\"0\",\t\t\t\"0\"\r\nTRUE,\t\t\t\"#VALUE!\"\r\n\"3579\",\t\t\t\"#NUM!\"\r\n\"7777777533\",\t\t\"FFFFFFFF5B\"\t//\t2's Complement\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/ACCRINT.data",
    "content": "#Issue date\t1st Interest\tSettlement\tRate\tPar\tFreq\tBasis\tResult\r\n\"2008-03-01\",\t\"2008-08-31\",\t\"2008-05-01\",\t0.10,\t1000,\t2,\t0,\t16.666666666667\r\n\"2008-03-05\",\t\"2008-08-31\",\t\"2008-05-01\",\t0.10,\t1000,\t2,\t0,\t15.555555555556\r\n\"2010-01-01\",\t\"2010-06-30\",\t\"2010-04-01\",\t0.08,\t10000,\t4,\t\t202.222222222222\r\n\"2008-03-05\",\t\"2008-08-31\",\t\"2008-05-01\",\t-0.10,\t1000,\t2,\t0,\t\"#NUM!\"\r\n\"Invalid Date\",\t\"2008-08-31\",\t\"2008-05-01\",\t0.10,\t1000,\t2,\t0,\t\"#VALUE!\"\r\n\"2008-03-01\",\t\"2008-08-31\",\t\"2008-05-01\",\t\"ABC\",\t1000,\t2,\t0,\t\"#VALUE!\"\r\n\"2008-03-01\",\t\"2008-08-31\",\t\"2008-05-01\",\t0.10,\t1000,\t2,\t\"ABC\",\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/ACCRINTM.data",
    "content": "#Issue date\tSettlement\tRate\tPar\tBasis\tResult\r\n\"2008-04-01\",\t\"2008-06-15\",\t0.10,\t1000,\t3,\t20.547945205479\r\n\"2010-01-01\",\t\"2010-12-31\",\t0.08,\t10000,\t\t800\r\n\"2008-03-05\",\t\"2008-08-31\",\t-0.10,\t1000,\t2,\t\"#NUM!\"\r\n\"Invalid Date\",\t\"2008-08-31\",\t0.10,\t1000,\t2,\t\"#VALUE!\"\r\n\"2008-03-01\",\t\"2008-08-31\",\t\"ABC\",\t1000,\t2,\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/AMORDEGRC.data",
    "content": "#Cost\tDate purchased\tEnd of the 1st period\tSalvage\tPeriod\tDepreciation\tBasis\tResult\r\n2400,\t\"2008-08-19\",\t\"2008-12-31\",\t\t300,\t1,\t0.15,\t\t1,\t776\r\n150,\t\"2011-01-01\",\t\"2011-09-30\",\t\t20,\t1,\t0.2,\t\t4,\t42\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/AMORLINC.data",
    "content": "#Cost\tDate purchased\tEnd of the 1st period\tSalvage\tPeriod\tDepreciation\tBasis\tResult\r\n2400,\t\"2008-08-19\",\t\"2008-12-31\",\t\t300,\t1,\t0.15,\t\t1,\t360\r\n150,\t\"2011-01-01\",\t\"2011-09-30\",\t\t20,\t1,\t0.2,\t\t4,\t30\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/COUPDAYBS.data",
    "content": "#Settlement\tMaturity\tFrequency\tBasis\tResult\r\n\"25-Jan-2007\",\t\"15-Nov-2008\",\t2,\t\t1,\t71\r\n\"2011-01-01\",\t\"2012-10-25\",\t4,\t\t\t66\r\n\"Invalid Date\",\t\"15-Nov-2008\",\t2,\t\t1,\t\"#VALUE!\"\r\n\"25-Jan-2007\",\t\"Invalid Date\",\t2,\t\t1,\t\"#VALUE!\"\r\n\"25-Jan-2007\",\t\"15-Nov-2008\",\t3,\t\t1,\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/COUPDAYS.data",
    "content": "#Settlement\tMaturity\tFrequency\tBasis\tResult\r\n\"25-Jan-2007\",\t\"15-Nov-2008\",\t2,\t\t1,\t181\r\n\"2011-01-01\",\t\"2012-10-25\",\t4,\t\t\t90\r\n\"Invalid Date\",\t\"15-Nov-2008\",\t2,\t\t1,\t\"#VALUE!\"\r\n\"25-Jan-2007\",\t\"Invalid Date\",\t2,\t\t1,\t\"#VALUE!\"\r\n\"25-Jan-2007\",\t\"15-Nov-2008\",\t3,\t\t1,\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/COUPDAYSNC.data",
    "content": "#Settlement\tMaturity\tFrequency\tBasis\tResult\r\n\"25-Jan-2007\",\t\"15-Nov-2008\",\t2,\t\t1,\t110\r\n\"2011-01-01\",\t\"2012-10-25\",\t4,\t\t\t24\r\n\"Invalid Date\",\t\"15-Nov-2008\",\t2,\t\t1,\t\"#VALUE!\"\r\n\"25-Jan-2007\",\t\"Invalid Date\",\t2,\t\t1,\t\"#VALUE!\"\r\n\"25-Jan-2007\",\t\"15-Nov-2008\",\t3,\t\t1,\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/COUPNCD.data",
    "content": "#Settlement\tMaturity\tFrequency\tBasis\tResult\r\n\"25-Jan-2007\",\t\"15-Nov-2008\",\t2,\t\t1,\t39217\r\n\"2011-01-01\",\t\"2012-10-25\",\t4,\t\t\t40568\r\n\"Invalid Date\",\t\"15-Nov-2008\",\t2,\t\t1,\t\"#VALUE!\"\r\n\"25-Jan-2007\",\t\"Invalid Date\",\t2,\t\t1,\t\"#VALUE!\"\r\n\"25-Jan-2007\",\t\"15-Nov-2008\",\t3,\t\t1,\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/COUPNUM.data",
    "content": "#Settlement\tMaturity\tFrequency\tBasis\tResult\r\n\"25-Jan-2007\",\t\"15-Nov-2008\",\t2,\t\t1,\t4\r\n\"2011-01-01\",\t\"2012-10-25\",\t4,\t\t0,\t8\r\n\"Invalid Date\",\t\"15-Nov-2008\",\t2,\t\t1,\t\"#VALUE!\"\r\n\"25-Jan-2007\",\t\"Invalid Date\",\t2,\t\t1,\t\"#VALUE!\"\r\n\"25-Jan-2007\",\t\"15-Nov-2008\",\t3,\t\t1,\t\"#NUM!\"\r\n\"01-Jan-2008\",\t\"31-Dec-2012\",\t1,\t\t1,\t5\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/COUPPCD.data",
    "content": "#Settlement\tMaturity\tFrequency\tBasis\tResult\r\n\"25-Jan-2007\",\t\"15-Nov-2008\",\t2,\t\t1,\t39036\r\n\"2011-01-01\",\t\"2012-10-25\",\t4,\t\t\t40476\r\n\"Invalid Date\",\t\"15-Nov-2008\",\t2,\t\t1,\t\"#VALUE!\"\r\n\"25-Jan-2007\",\t\"Invalid Date\",\t2,\t\t1,\t\"#VALUE!\"\r\n\"25-Jan-2007\",\t\"15-Nov-2008\",\t3,\t\t1,\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/CUMIPMT.data",
    "content": "#rate\t\tnper\tpv\tstart_period\tend_period\ttype\tresult\r\n0.0075,\t\t360,\t125000,\t13,\t\t24,\t\t0,\t-11135.232130751\r\n0.0075,\t\t360,\t125000,\t1,\t\t1,\t\t0,\t-937.50\r\n0.004166666667,\t60,\t50000,\t1,\t\t12,\t\t0,\t-2294.9775375121\r\n0.004166666667,\t60,\t50000,\t13,\t\t24,\t\t0,\t-1833.1000667254\r\n0.004166666667,\t60,\t50000,\t25,\t\t36,\t\t0,\t-1347.5920679425\r\n0.004166666667,\t60,\t50000,\t37,\t\t48,\t\t0,\t-837.24455850309\r\n0.004166666667,\t60,\t50000,\t49,\t\t60,\t\t0,\t-300.78670189939\r\n0.0075,\t\t360,\t125000,\t24,\t\t13,\t\t0,\t\"#VALUE!\"\r\n0.0075,\t\t360,\t125000,\t24,\t\t13,\t\t2,\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/CUMPRINC.data",
    "content": "#rate\t\tnper\tpv\tstart_period\tend_period\ttype\tresult\r\n0.0075,\t\t360,\t125000,\t13,\t\t24,\t\t0,\t-934.10712342088\r\n0.0075,\t\t360,\t125000,\t1,\t\t1,\t\t0,\t-68.278271180977\r\n0.004166666667,\t60,\t50000,\t1,\t\t12,\t\t0,\t-9027.7626490046\r\n0.004166666667,\t60,\t50000,\t13,\t\t24,\t\t0,\t-9489.6401197913\r\n0.004166666667,\t60,\t50000,\t25,\t\t36,\t\t0,\t-9975.1481185741\r\n0.004166666667,\t60,\t50000,\t37,\t\t48,\t\t0,\t-10485.495628014\r\n0.004166666667,\t60,\t50000,\t49,\t\t60,\t\t0,\t-11021.953484617\r\n0.0075,\t\t360,\t125000,\t24,\t\t13,\t\t0,\t\"#VALUE!\"\r\n0.0075,\t\t360,\t125000,\t24,\t\t13,\t\t2,\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/DB.data",
    "content": "#cost\t\tsalvage\t\tlife\tperiod\tmonth\tresult\r\n1000000,\t100000,\t\t6,\t1,\t7,\t186083.33333333\r\n1000000,\t100000,\t\t6,\t2,\t7,\t259639.41666667\r\n1000000,\t100000,\t\t6,\t3,\t7,\t176814.44275\r\n1000000,\t100000,\t\t6,\t4,\t7,\t120410.63551275\r\n1000000,\t100000,\t\t6,\t5,\t7,\t81999.642784183\r\n1000000,\t100000,\t\t6,\t6,\t7,\t55841.756736028\r\n1000000,\t100000,\t\t6,\t7,\t7,\t15845.098473848\r\n10000,\t\t1000,\t\t5,\t1,\t6,\t1845.00\r\n10000,\t\t1000,\t\t5,\t2,\t6,\t3009.195\r\n10000,\t\t1000,\t\t5,\t3,\t6,\t1898.802045\r\n10000,\t\t1000,\t\t5,\t4,\t6,\t1198.144090395\r\n10000,\t\t1000,\t\t5,\t5,\t6,\t756.02892103925\r\n10000,\t\t1000,\t\t5,\t6,\t6,\t238.52712458788\r\n0,\t\t0,\t\t5,\t6,\t6,\t0.0\r\n-1000,\t\t100,\t\t5,\t6,\t6,\t\"#NUM!\"\r\n\"ABC\",\t\t100,\t\t5,\t6,\t6,\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/DDB.data",
    "content": "#cost\t\tsalvage\t\tlife\tperiod\tmonth\tresult\r\n2400,\t\t300,\t\t36500,\t1,\t\t0.13150684931507\r\n2400,\t\t300,\t\t36500,\t2,\t\t0.13149964346031\r\n2400,\t\t300,\t\t36500,\t7,\t\t0.13146362010871\r\n2400,\t\t300,\t\t36500,\t7,\t14,\t0.91843145432708\r\n2400,\t\t300,\t\t120,\t1,\t2,\t40.00\r\n2400,\t\t300,\t\t10,\t1,\t2,\t480.00\r\n2400,\t\t300,\t\t10,\t2,\t1.5,\t306.00\r\n2400,\t\t300,\t\t10,\t10,\t\t22.12254720000030\r\n10000,\t\t1000,\t\t5,\t1,\t\t4000.00\r\n10000,\t\t1000,\t\t5,\t2,\t\t2400.00\r\n10000,\t\t1000,\t\t5,\t3,\t\t1440.00\r\n10000,\t\t1000,\t\t5,\t4,\t\t864.00\r\n10000,\t\t1000,\t\t5,\t5,\t\t296.00\r\n-2400,\t\t300,\t\t36500,\t1,\t\t\"#NUM!\"\r\n\"ABC\",\t\t300,\t\t36500,\t1,\t\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/DISC.data",
    "content": "#settlement\tmaturity\tprice\tredemption\tbasis\tresult\r\n\"2007-01-25\",\t\"2007-06-15\",\t97.975,\t100,\t\t1,\t0.052420213\r\n\"2010-04-01\",\t\"2015-03-31\",\t95,\t100,\t\t\t0.01\r\n\"2010-04-01\",\t\"2015-03-31\",\t0,\t100,\t\t\t\"#NUM!\"\r\n\"2010-04-01\",\t\"2015-03-31\",\t\"ABC\",\t100,\t\t\t\"#VALUE!\"\r\n\"Invalid Date\",\t\"2007-06-15\",\t97.975,\t100,\t\t1,\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/DOLLARDE.data",
    "content": "#fractional_dollar\tfraction\tresult\r\n1.02,\t\t\t16,\t\t1.125\r\n1.1,\t\t\t32,\t\t1.3125\r\n1.01,\t\t\t16,\t\t1.0625\r\n1.1,\t\t\t16,\t\t1.625\r\n1.03,\t\t\t32,\t\t1.09375\r\n1.3,\t\t\t32,\t\t1.9375\r\n1.12,\t\t\t32,\t\t1.375\r\n1.2345,\t\t\t0,\t\t\"#DIV/0!\"\r\n1.2345,\t\t\t-2,\t\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/DOLLARFR.data",
    "content": "#decimal_dollar\t\tfraction\tresult\r\n1.125,\t\t\t16,\t\t1.02\r\n1.125,\t\t\t32,\t\t1.04\r\n1.0625,\t\t\t16,\t\t1.01\r\n1.625,\t\t\t16,\t\t1.1\r\n1.09375,\t\t32,\t\t1.03\r\n1.9375,\t\t\t32,\t\t1.3\r\n1.375,\t\t\t32,\t\t1.12\r\n1.2345,\t\t\t0,\t\t\"#DIV/0!\"\r\n1.2345,\t\t\t-2,\t\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/EFFECT.data",
    "content": "#nominal_rate\tnpery\tResult\r\n0.0525,\t\t4,\t0.053542667370758\r\n0.10,\t\t4,\t0.103812890625\r\n0.10,\t\t2,\t0.1025\r\n0.025,\t\t2,\t0.02515625\r\n1,\t\t0,\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/FV.data",
    "content": "#rate\t\tnper\tpmt\tpv\ttype\tResult\r\n0.005,\t\t10,\t-200,\t-500,\t1,\t2581.4033740601\r\n0.01,\t\t12,\t-1000,\t\t\t12682.503013197\r\n0.009166666667,\t35,\t-2000,\t,\t1,\t82846.246372418\r\n0.005,\t\t12,\t-100,\t-1000,\t1,\t2301.4018303409\r\n0.004166666667,\t60,\t-1000,\t\t\t68006.082841536\r\n0.025,\t\t16,\t-2000,\t0,\t1,\t39729.460894166\r\n0.1,\t\t12,\t-100,\t0,\t2,\t\"#NUM!\"\r\n0.0,\t\t12,\t-100,\t-100,\t\t1300\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/FVSCHEDULE.data",
    "content": "#principal\tschedule\t\t\tResult\r\n1,\t\t{0.09|0.11|0.1},\t\t1.33089\r\n10,\t\t{0.09;0.11;0.1},\t\t13.3089\r\n10000,\t\t{0.05|0.05|0.035|0.035|0.035},\t12223.614571875\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/INTRATE.data",
    "content": "#Settlement\tMaturity\tInvestment\tRedemption\tBasis\tResult\r\n\"2008-02-15\",\t\"2008-05-15\",\t1000000,\t1014420,\t2,\t0.05768\r\n\"2005-04-01\",\t\"2010-03-31\",\t1000,\t\t2125,\t\t\t0.225\r\n\"2008-02-15\",\t\"2008-05-15\",\t1000000,\t1014420,\t\"ABC\",\t\"#VALUE!\"\r\n\"2008-02-15\",\t\"2008-05-15\",\t1000000,\t-1014420,\t2,\t\"#NUM!\"\r\n\"Invalid Date\",\t\"2008-05-15\",\t1000000,\t1014420,\t2,\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/IPMT.data",
    "content": "#rate\t\tper\tnper\tpv\t\tfv\t\ttype\tResult\r\n0.008333333333,\t3,\t3,\t8000,\t\t\t\t\t-22.406893015021\r\n0.10,\t\t3,\t3,\t8000,\t\t\t\t\t-292.44712990937\r\n0.004166666667,\t1,\t60,\t50000,\t\t\t\t\t-208.33333335\r\n0.004166666667,\t2,\t60,\t50000,\t\t\t\t\t-205.26988189617\r\n0.00875,\t1,\t8,\t10000,\t\t5000,\t\t1,\t0.00\r\n0.00875,\t2,\t8,\t10000,\t\t5000,\t\t1,\t-70.968650395559\r\n0.005,\t\t2,\t8,\t2500,\t\t200,\t\t6,\t\"#NUM!\"\r\n0.005,\t\t8,\t2,\t2500,\t\t200,\t\t1,\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/IRR.data",
    "content": "#values\t\t\t\t\tguess\tResult\r\n{-70000;12000;15000;18000;21000},\t\t-0.021244848273410\r\n{-70000;12000;15000;18000;21000;26000},\t\t0.08663094803652\r\n{-70000;12000;15000;18000},\t\t0.10,\t-0.18213746414550\r\n{-100;20|24|28.80},\t\t\t\t-0.13618951095869\r\n{-100;20|24|28.80|34.56|41.47},\t\t\t0.130575756371527\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/ISPMT.data",
    "content": "#rate\t\tper\tnper\tpv\t\tresult\r\n0.008333333333,\t1,\t36,\t8000000,\t-64814.814812222\r\n0.10,\t\t1,\t3,\t8000000,\t-533333.33333333\r\n0.004166666667,\t1,\t60,\t50000,\t\t-204.8611111275\r\n0.004166666667,\t2,\t60,\t50000,\t\t-201.388888905\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/MIRR.data",
    "content": "#values\t\t\t\t\t\tfinance_rate\treinvestment_rate\tResult\r\n{-120000;39000|30000|21000|37000|46000},\t0.10,\t\t0.12,\t\t\t0.12609413036591\r\n{-120000;39000|30000|21000},\t\t\t0.10,\t\t0.12,\t\t\t-0.048044655249981\r\n{-120000;39000|30000|21000|37000|46000},\t0.10,\t\t0.14,\t\t\t0.13475911082831\r\n{-100;12|14|11},\t\t\t\t5.5,\t\t5,\t\t\t0.74021752686287\r\n{-100;12|14|11|13|16},\t\t\t\t5.5,\t\t5,\t\t\t1.8579321744785\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/NOMINAL.data",
    "content": "#effect_rate\tnpery\tresult\r\n0.053543,\t4,\t0.052500319868356\r\n0.10,\t\t4,\t0.09645475633778\r\n0.10,\t\t2,\t0.097617696340303\r\n0.025,\t\t12,\t0.024718035238113\r\n-0.025,\t\t12,\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/NPER.data",
    "content": "#rate\t\tpmt\tpv\tfv\ttype\tresult\r\n0.01,\t\t-100,\t-1000,\t10000,\t1,\t59.673865674295\r\n0.01,\t\t-100,\t-1000,\t10000,\t\t60.082122853762\r\n0.01,\t\t-100,\t-1000,\t\t\t-9.5785940398132\r\n0.003333333333,\t-1000,\t50000,\t\t\t54.78757726\r\n0.015,\t\t-1200,\t9000,\t5000,\t1,\t11.90373729\r\n0.015,\t\t-1200,\t9000,\t5000,\t2,\t\"#NUM!\"\r\n0.015,\t\t0.0,\t0.0,\t5000,\t1,\t\"#NUM!\"\r\n0.0,\t\t0.0,\t-500,\t5000,\t1,\t\"#NUM!\"\r\n0.0,\t\t-50,\t-250,\t150,\t1,\t-2.0\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/NPV.data",
    "content": "#rate\t\tvalues\t\t\t\t\tresult\r\n0.10,\t-10000,\t3000,\t4200,\t6800,\t\t\t1188.4434123352\r\n0.08,\t8000,\t9200,\t10000,\t12000,\t14500,\t\t41922.061554932\r\n0.08,\t8000,\t9200,\t10000,\t12000,\t14500,\t-9000,\t36250.534912984\r\n0.05,\t2000,\t2400,\t2900,\t3500,\t4100,\t\t12678.677633095\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/PRICE.data",
    "content": "#Settlement\tMaturity\tRate\tYield\tRedemption\tFrequency\tBasis\tResult\r\n\"15-Feb-2008\",\t\"15-Nov-2017\",\t0.0575,\t0.065,\t100,\t\t2,\t\t0,\t94.6343616213221\r\n\"15-Feb-2008\",\t\"15-Nov-2017\",\t0.0575,\t0.065,\t100,\t\t2,\t\t1,\t94.6354492078772\r\n\"15-Feb-2008\",\t\"15-Nov-2017\",\t0.0575,\t0.065,\t100,\t\t2,\t\t2,\t94.6365640300251\r\n\"15-Feb-2008\",\t\"15-Nov-2017\",\t0.0575,\t0.065,\t100,\t\t2,\t\t3,\t94.6351747967845\r\n\"01-Apr-2012\",\t\"31-Mar-2020\",\t0.12,\t0.10,\t100,\t\t2,\t\tNULL,\t110.8344835932160\r\n\"01-Apr-2012\",\t\"31-Mar-2020\",\t0.12,\t0.10,\t100,\t\t2,\t\t1,\t110.8345373958590\r\n\"01-Apr-2012\",\t\"31-Mar-2020\",\t0.12,\t0.10,\t100,\t\t2,\t\t2,\t110.8344835932160\r\n\"01-Apr-2012\",\t\"31-Mar-2020\",\t0.12,\t0.10,\t100,\t\t2,\t\t3,\t110.8345285514390\r\n\"01-Apr-2012\",\t\"31-Mar-2020\",\t0.12,\t0.10,\t100,\t\t4,\t\t3,\t110.9217329631980\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/RATE.data",
    "content": "#Periods\tPayment\tPresent Value\tFuture Value\tType\tGuess\tResult\r\n48,\t\t-200,\t8000,\t\t\t\t\t\t0.0077014724882014\r\n60,\t\t-6000,\t120000,\t\t\t\t\t\t0.0467819164224934\r\n60,\t\t-1000,\t120000,\t\t\t\t\t\t-0.0204429522193565\r\n24,\t\t-250,\t5000,\t\t\t\t\t\t0.0151308439023434\r\n24,\t\t-250,\t5000,\t\tNULL,\t\t1,\t\t0.0165501190667120\r\n208,\t\t-700,\t8000,\t\t\t\t\t\t0.0874999976840937\r\n10,\t\t-1000,\t6500,\t\t\t\t\t\t0.0871137556058636\r\n6,\t\t-1000,\t100000,\t\t-126068,\t\t\t0.0484721272835728\r\n6,\t\t1000,\t100000,\t\t-126068,\t\t\t0.0302728738275435\r\n6,\t\t-1000,\t-100000,\t126068,\t\t0,\t\t0.0302728738275437\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Financial/XIRR.data",
    "content": "#values\t\t\t\t\tdates\t\t\t\t\t\t\t\t\t\tguess\tResult\r\n{-10000;2750|4250|3250|2750|46000},\t{\"2008-01-01\";\"2008-03-01\"|\"2008-10-30\"|\"2009-02-15\"|\"2009-04-01\"},\t\t0.10,\t0.373362535\r\n{-100;20|40|25},\t\t\t{\"2010-01-01\";\"2010-04-01\"|\"2010-10-01\"|\"2011-02-01\"},\t\t\t\t\t-0.3024\r\n{-100;20|40|25|8|15},\t\t\t{\"2010-01-01\";\"2010-04-01\"|\"2010-10-01\"|\"2011-02-01\"|\"2011-03-01\"|\"2011-06-01\"},\t0.2095\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Functions/ERROR_TYPE.data",
    "content": "\t\t\"#N/A\"\r\nNULL,\t\t\"#N/A\"\r\n-1,\t\t\"#N/A\"\r\n1.25,\t\t\"#N/A\"\r\n\"\",\t\t\"#N/A\"\r\n\"2.5\",\t\t\"#N/A\"\r\nTRUE,\t\t\"#N/A\"\r\n\"#NULL!\",\t1\r\n\"#DIV/0!\",\t2\r\n\"#VALUE!\",\t3\r\n\"#REF!\",\t4\r\n\"#NAME?\",\t5\r\n\"#NUM!\",\t6\r\n\"#N/A\",\t\t7\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Functions/IS_BLANK.data",
    "content": "\t\tTRUE\r\nNULL,\t\tTRUE\r\n-1,\t\tFALSE\r\n0,\t\tFALSE\r\n9,\t\tFALSE\r\n1.5,\t\tFALSE\r\n\"\",\t\tFALSE\r\n\"-1\",\t\tFALSE\r\n\"2\",\t\tFALSE\r\n\"-1.5\",\t\tFALSE\r\n\"ABC\",\t\tFALSE\r\n\"#VALUE!\",\tFALSE\r\n\"#N/A\",\t\tFALSE\r\n\"TRUE\",\t\tFALSE\r\nTRUE,\t\tFALSE\r\nFALSE,\t\tFALSE\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Functions/IS_ERR.data",
    "content": "\t\tFALSE\r\nNULL,\t\tFALSE\r\n-1,\t\tFALSE\r\n0,\t\tFALSE\r\n9,\t\tFALSE\r\n1.5,\t\tFALSE\r\n\"\",\t\tFALSE\r\n\"-1\",\t\tFALSE\r\n\"2\",\t\tFALSE\r\n\"-1.5\",\t\tFALSE\r\n\"ABC\",\t\tFALSE\r\n\"#VALUE!\",\tTRUE\r\n\"#N/A\",\t\tFALSE\r\n\"TRUE\",\t\tFALSE\r\nTRUE,\t\tFALSE\r\nFALSE,\t\tFALSE\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Functions/IS_ERROR.data",
    "content": "\t\tFALSE\r\nNULL,\t\tFALSE\r\n-1,\t\tFALSE\r\n0,\t\tFALSE\r\n9,\t\tFALSE\r\n1.5,\t\tFALSE\r\n\"\",\t\tFALSE\r\n\"-1\",\t\tFALSE\r\n\"2\",\t\tFALSE\r\n\"-1.5\",\t\tFALSE\r\n\"ABC\",\t\tFALSE\r\n\"#VALUE!\",\tTRUE\r\n\"#N/A\",\t\tTRUE\r\n\"TRUE\",\t\tFALSE\r\nTRUE,\t\tFALSE\r\nFALSE,\t\tFALSE\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Functions/IS_EVEN.data",
    "content": "\t\t\"#NAME?\"\r\nNULL,\t\t\"#NAME?\"\r\n-1,\t\tFALSE\r\n0,\t\tTRUE\r\n9,\t\tFALSE\r\n1.25,\t\tFALSE\r\n1.5,\t\tFALSE\r\n2.25,\t\tTRUE\r\n2.5,\t\tTRUE\r\n\"\",\t\t\"#VALUE!\"\r\n\"-1\",\t\tFALSE\r\n\"2\",\t\tTRUE\r\n\"-1.5\",\t\tFALSE\r\n\"2.5\",\t\tTRUE\r\n\"ABC\",\t\t\"#VALUE!\"\r\n\"#VALUE!\",\t\"#VALUE!\"\r\n\"#N/A\",\t\t\"#VALUE!\"\r\n\"TRUE\",\t\t\"#VALUE!\"\r\nTRUE,\t\t\"#VALUE!\"\r\nFALSE,\t\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Functions/IS_LOGICAL.data",
    "content": "\t\tFALSE\r\nNULL,\t\tFALSE\r\n-1,\t\tFALSE\r\n0,\t\tFALSE\r\n9,\t\tFALSE\r\n1.5,\t\tFALSE\r\n\"\",\t\tFALSE\r\n\"-1\",\t\tFALSE\r\n\"2\",\t\tFALSE\r\n\"-1.5\",\t\tFALSE\r\n\"ABC\",\t\tFALSE\r\n\"#VALUE!\",\tFALSE\r\n\"#N/A\",\t\tFALSE\r\n\"TRUE\",\t\tFALSE\r\nTRUE,\t\tTRUE\r\nFALSE,\t\tTRUE\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Functions/IS_NA.data",
    "content": "\t\tFALSE\r\nNULL,\t\tFALSE\r\n-1,\t\tFALSE\r\n0,\t\tFALSE\r\n9,\t\tFALSE\r\n1.5,\t\tFALSE\r\n\"\",\t\tFALSE\r\n\"-1\",\t\tFALSE\r\n\"2\",\t\tFALSE\r\n\"-1.5\",\t\tFALSE\r\n\"ABC\",\t\tFALSE\r\n\"#VALUE!\",\tFALSE\r\n\"#N/A\",\t\tTRUE\r\n\"TRUE\",\t\tFALSE\r\nTRUE,\t\tFALSE\r\nFALSE,\t\tFALSE\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Functions/IS_NONTEXT.data",
    "content": "\t\tTRUE\r\nNULL,\t\tTRUE\r\n-1,\t\tTRUE\r\n0,\t\tTRUE\r\n9,\t\tTRUE\r\n1.5,\t\tTRUE\r\n\"\",\t\tFALSE\r\n\"-1\",\t\tFALSE\r\n\"2\",\t\tFALSE\r\n\"-1.5\",\t\tFALSE\r\n\"ABC\",\t\tFALSE\r\n\"#VALUE!\",\tTRUE\r\n\"#N/A\",\t\tTRUE\r\n\"TRUE\",\t\tFALSE\r\nTRUE,\t\tTRUE\r\nFALSE,\t\tTRUE\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Functions/IS_NUMBER.data",
    "content": "\t\tFALSE\r\nNULL,\t\tFALSE\r\n-1,\t\tTRUE\r\n0,\t\tTRUE\r\n9,\t\tTRUE\r\n1.5,\t\tTRUE\r\n\"\",\t\tFALSE\r\n\"-1\",\t\tFALSE\r\n\"2\",\t\tFALSE\r\n\"-1.5\",\t\tFALSE\r\n\"ABC\",\t\tFALSE\r\n\"#VALUE!\",\tFALSE\r\n\"#N/A\",\t\tFALSE\r\n\"TRUE\",\t\tFALSE\r\nTRUE,\t\tFALSE\r\nFALSE,\t\tFALSE\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Functions/IS_ODD.data",
    "content": "\t\t\"#NAME?\"\r\nNULL,\t\t\"#NAME?\"\r\n-1,\t\tTRUE\r\n0,\t\tFALSE\r\n9,\t\tTRUE\r\n1.25,\t\tTRUE\r\n1.5,\t\tTRUE\r\n2.25,\t\tFALSE\r\n2.5,\t\tFALSE\r\n\"\",\t\t\"#VALUE!\"\r\n\"-1\",\t\tTRUE\r\n\"2\",\t\tFALSE\r\n\"-1.5\",\t\tTRUE\r\n\"2.5\",\t\tFALSE\r\n\"ABC\",\t\t\"#VALUE!\"\r\n\"#VALUE!\",\t\"#VALUE!\"\r\n\"#N/A\",\t\t\"#VALUE!\"\r\n\"TRUE\",\t\t\"#VALUE!\"\r\nTRUE,\t\t\"#VALUE!\"\r\nFALSE,\t\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Functions/IS_TEXT.data",
    "content": "\t\tFALSE\r\nNULL,\t\tFALSE\r\n-1,\t\tFALSE\r\n0,\t\tFALSE\r\n9,\t\tFALSE\r\n1.5,\t\tFALSE\r\n\"\",\t\tTRUE\r\n\"-1\",\t\tTRUE\r\n\"2\",\t\tTRUE\r\n\"-1.5\",\t\tTRUE\r\n\"ABC\",\t\tTRUE\r\n\"#VALUE!\",\tFALSE\r\n\"#N/A\",\t\tFALSE\r\n\"TRUE\",\t\tTRUE\r\nTRUE,\t\tFALSE\r\nFALSE,\t\tFALSE\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Functions/N.data",
    "content": "\t\t\t0\r\nNULL,\t\t\t0\r\n-1,\t\t\t-1\r\n1.25,\t\t\t1.25\r\n\"\",\t\t\t0\r\n\"2.5\",\t\t\t0\r\n\"TRUE\",\t\t\t0\r\n\"ABCDE\",\t\t0\r\nTRUE,\t\t\t1\r\n\"#DIV/0!\",\t\t\"#DIV/0!\"\r\n\"#NUM!\",\t\t\"#NUM!\"\r\n{},\t\t\t0\r\n{123},\t\t\t123\r\n{123|456},\t\t123\r\n{123|\"A\"},\t\t123\r\n{\"A\"|123},\t\t0\r\n{\"A\"|123;456|789},\t0\r\n{123|\"A\";456|789},\t123\r\n{123|456;\"A\"|789},\t123\r\n{123|456;789|\"A\"},\t123\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Functions/TYPE.data",
    "content": "\t\t\t1\r\nNULL,\t\t\t1\r\n-1,\t\t\t1\r\n1.25,\t\t\t1\r\n\"\",\t\t\t2\r\n\"2.5\",\t\t\t2\r\n\"TRUE\",\t\t\t2\r\n\"ABCDE\",\t\t2\r\nTRUE,\t\t\t4\r\n\"#DIV/0!\",\t\t16\r\n\"#NUM!\",\t\t16\r\n{},\t\t\t1\r\n{1},\t\t\t1\r\n{1;2;3},\t\t64\r\n{1|2|3;4|5|6;7|8|9},\t64\r\n{|;|},\t\t\t64\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Logical/AND.data",
    "content": "\"#VALUE!\"\t\t\t\t\t//\tNo arguments\r\nNULL,\tTRUE\t\t\t\t\t//\tNULL\r\nTRUE,\tNULL,\tTRUE\t\t\t\t//\tBoolean TRUE and NULL\r\nFALSE,\tNULL,\tFALSE\t\t\t\t//\tBoolean FALSE and NULL\r\nTRUE,\tTRUE,\tTRUE\t\t\t\t//\tBoth TRUE Booleans\r\nTRUE,\tFALSE,\tFALSE\t\t\t\t//\tMixed Booleans\r\nFALSE,\tTRUE,\tFALSE\t\t\t\t//\tMixed Booleans\r\nFALSE,\tFALSE,\tFALSE\t\t\t\t//\tBoth FALSE Booleans\r\nTRUE,\tTRUE,\tFALSE,\tFALSE\t\t\t//\tMultiple Mixed Booleans\r\nTRUE,\tTRUE,\tTRUE,\tTRUE\t\t\t//\tMultiple TRUE Booleans\r\nFALSE,\tFALSE,\tFALSE,\tFALSE,\tFALSE\t\t//\tMultiple FALSE Booleans\r\n-1,\t-2,\tTRUE\r\n0,\t0,\tFALSE\r\n0,\t1,\tFALSE\r\n1,\t1,\tTRUE\r\n\"1\",1,\t\"#VALUE!\"\r\n\"TRUE\",\t1,\tTRUE\t\t\t\t//\t'TRUE' String\r\n\"FALSE\",TRUE,\tFALSE\t\t\t\t//\t'FALSE' String\r\n\"ABCD\",\t1,\t\"#VALUE!\"\t\t\t//\tNon-numeric String\r\n-2,\t1,\tTRUE\r\n-2,\t0,\tFALSE\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Logical/IF.data",
    "content": "0\r\nTRUE,\t0\r\nFALSE,\tFALSE\r\nTRUE,\t\"ABC\",\t\"ABC\"\r\nFALSE,\t\"ABC\",\tFALSE\r\nTRUE,\t\"ABC\",\t\"XYZ\",\t\"ABC\"\r\nFALSE,\t\"ABC\",\t\"XYZ\",\t\"XYZ\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Logical/IFERROR.data",
    "content": ",\t\t\"Error\",\tNULL\r\nTRUE,\t\t\"Error\",\tTRUE\r\n42,\t\t\"Error\",\t42\r\n\"\",\t\t\"Error\",\t\"\"\r\n\"ABC\",\t\t\"Error\",\t\"ABC\"\r\n\"#VALUE!\",\t\"Error\",\t\"Error\"\r\n\"#NAME?\",\t\"Error\",\t\"Error\"\r\n\"#N/A\",\t\t\"Error\",\t\"Error\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Logical/NOT.data",
    "content": "TRUE\r\nNULL,\tTRUE\r\n-1,\tFALSE\r\n0,\tTRUE\r\n1,\tFALSE\r\n2,\tFALSE\r\n-1.5,\tFALSE\r\n1.5,\tFALSE\r\n\"-1\",\t\"#VALUE!\"\r\n\"0\",\t\"#VALUE!\"\r\n\"1\",\t\"#VALUE!\"\r\n\"2\",\t\"#VALUE!\"\r\n\"-1.5\",\t\"#VALUE!\"\r\n\"1.5\",\t\"#VALUE!\"\r\n\"\",\t\"#VALUE!\"\r\n\"ABC\",\t\"#VALUE!\"\r\n\"FALSE\",TRUE\r\n\"TRUE\",\tFALSE\r\nTRUE,\tFALSE\r\nFALSE,\tTRUE\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/Logical/OR.data",
    "content": "\"#VALUE!\"\t\t\t\t//\tNo arguments\r\nNULL,\tFALSE\t\t\t\t//\tNULL\r\nTRUE,\tNULL,\tTRUE\t\t\t//\tBoolean TRUE and NULL\r\nFALSE,\tNULL,\tFALSE\t\t\t//\tBoolean FALSE and NULL\r\nTRUE,\tTRUE,\tTRUE\t\t\t//\tBoth TRUE Booleans\r\nTRUE,\tFALSE,\tTRUE\t\t\t//\tMixed Booleans\r\nFALSE,\tTRUE,\tTRUE\t\t\t//\tMixed Booleans\r\nFALSE,\tFALSE,\tFALSE\t\t\t//\tBoth FALSE Booleans\r\nTRUE,\tTRUE,\tFALSE,\tTRUE\t\t//\tMultiple Mixed Booleans\r\nTRUE,\tTRUE,\tTRUE,\tTRUE\t\t//\tMultiple TRUE Booleans\r\nFALSE,\tFALSE,\tFALSE,\tFALSE,\tFALSE\t//\tMultiple FALSE Booleans\r\n-1,\t-2,\tTRUE\r\n0,\t0,\tFALSE\r\n0,\t1,\tTRUE\r\n1,\t1,\tTRUE\r\n\"TRUE\",\t1,\tTRUE\t\t\t//\t'TRUE' String\r\n\"FALSE\",TRUE,\tTRUE\t\t\t//\t'FALSE' String\r\n\"ABCD\",\t1,\t\"#VALUE!\"\t\t//\tNon-numeric String\r\n-2,\t1,\tTRUE\r\n-2,\t0,\tTRUE\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/LookupRef/HLOOKUP.data",
    "content": "10251,\t\t{\"Order ID\"|10247|10249|10250|10251|10252|10253;\"Unit Price\"|14.00|18.60|7.70|16.80|16.80|64.80;\"Quantity\"|12|9|10|6|20|40},\t2,\tFALSE,\t16.8\n10251,\t\t{\"Order ID\"|10247|10249|10250|10251|10252|10253;\"Unit Price\"|14.00|18.60|7.70|16.80|16.80|64.80;\"Quantity\"|12|9|10|6|20|40},\t3,\tFALSE,\t6.0\n10248,\t\t{\"Order ID\"|10247|10249|10250|10251|10252|10253;\"Unit Price\"|14.00|18.60|7.70|16.80|16.80|64.80;\"Quantity\"|12|9|10|6|20|40},\t2,\tFALSE,\t\"#N/A\"\n10248,\t\t{\"Order ID\"|10247|10249|10250|10251|10252|10253;\"Unit Price\"|14.00|18.60|7.70|16.80|16.80|64.80;\"Quantity\"|12|9|10|6|20|40},\t2,\tTRUE,\t14.0\n\"Axles\",\t{\"Axles\"|\"Bearings\"|\"Bolts\";4|4|9;5|7|10;6|8|11},\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t2,\tTRUE,\t4\n\"Bearings\",\t{\"Axles\"|\"Bearings\"|\"Bolts\";4|4|9;5|7|10;6|8|11},\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t3,\tFALSE,\t7\n\"B\",\t\t{\"Axles\"|\"Bearings\"|\"Bolts\";4|4|9;5|7|10;6|8|11},\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t3,\tTRUE,\t5\n\"Bolts\",\t{\"Axles\"|\"Bearings\"|\"Bolts\";4|4|9;5|7|10;6|8|11},\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t4,\t\t\t11\n3,\t\t\t{1|2|3;\"a\"|\"b\"|\"c\";\"d\"|\"e\"|\"f\"},\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t2,\tTRUE,\t\"c\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/LookupRef/VLOOKUP.data",
    "content": "1,\t\t{\"Density\"|\"Viscosity\"|\"Temperature\";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0},\t2,\tFALSE,\t2.17\n1,\t\t{\"Density\"|\"Viscosity\"|\"Temperature\";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0},\t3,\tTRUE,\t100\n.7,\t\t{\"Density\"|\"Viscosity\"|\"Temperature\";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0},\t3,\tFALSE,\t\"#N/A\"\n0.1,\t\t{\"Density\"|\"Viscosity\"|\"Temperature\";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0},\t2,\tTRUE,\t\"#N/A\"\n2,\t\t{\"Density\"|\"Viscosity\"|\"Temperature\";0.457|3.55|500;0.525|3.25|400;0.616|2.93|300;0.675|2.75|250;0.746|2.57|200;0.835|2.38|150;0.946|2.17|100;1.09|1.95|50;1.29|1.71|0},\t2,\tTRUE,\t1.71\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/ATAN2.data",
    "content": "#x_num\ty_num\tResult\r\n0,\t0,\t\"#DIV/0!\"\r\n1,\t1,\t0.785398163397\r\n-1,\t-1,\t-2.356194490192\r\n-1,\t1,\t2.356194490192\r\n1,\t-1,\t-0.785398163397\r\n0.5,\t1,\t1.107148717794\r\n-0.5,\t2,\t1.815774989922\r\n1,\t0.8,\t0.674740942224\r\n0.8,\t-0.6,\t-0.643501108793\r\n1,\t-9,\t-1.460139105621\r\n0.2,\t0,\t0.0\r\n0.1,\t0.2,\t1.107148717794\r\n0,\t0.2,\t1.570796326795\r\n\"A\",\t0.2,\t\"#VALUE!\"\r\nTRUE,\t1,\t0.785398163397\r\nFALSE,\t-2.5,\t-1.570796326795\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/CEILING.data",
    "content": "#number\t\tsignificance\tresult\r\n2.5,\t\t1,\t\t3.0\r\n-2.5,\t\t-2,\t\t-4.0\r\n1.5,\t\t0.1,\t\t1.5\r\n0.234,\t\t0.01,\t\t0.24\r\n-2.341,\t\t-0.1,\t\t-2.4\r\n8,\t\t0,\t\t0.0\r\n8,\t\t1.5,\t\t9.0\r\n8,\t\t-1.5,\t\t\"#NUM!\"\r\n-8,\t\t1.5,\t\t\"#NUM!\"\r\n-8,\t\t-1.5,\t\t-9.0\r\n8.26,\t\t0.05,\t\t8.3\r\n2.341,\t\t0.05,\t\t2.35\r\n123.456,\t\t\t\"#VALUE!\"\r\n\"PHPExcel\",\t\t\t\"#VALUE!\"\r\n210.67,\t\t1,\t\t211.0\r\n210.67,\t\t0.05,\t\t210.70\r\n210.63,\t\t0.05,\t\t210.65\r\n2.98,\t\t2,\t\t4.0\r\n-2.98,\t\t2,\t\t\"#NUM!\"\r\n-4.5,\t\t-1,\t\t-5.0\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/COMBIN.data",
    "content": "#NumObjs\tNumInSet\tResult\r\n7,\t\t3,\t\t35\r\n8,\t\t2,\t\t28\r\n8,\t\t3,\t\t56\r\n8,\t\t4,\t\t70\r\n100,\t\t3,\t\t161700\r\n-7,\t\t-10,\t\t\"#NUM!\"\r\n-7,\t\t10,\t\t\"#NUM!\"\r\n7,\t\t-10,\t\t\"#NUM!\"\r\n2,\t\t3,\t\t\"#NUM!\"\r\n2,\t\t2,\t\t1\r\n2,\t\t1,\t\t2\r\n2,\t\t0,\t\t1\r\n2.5,\t\t2,\t\t1\r\n\"ABCD\",\t\t\"EFGH\",\t\t\"#VALUE!\"\r\n10,\t\t5,\t\t252\r\n10,\t\t3,\t\t120\r\n21,\t\t5,\t\t20349\r\n6,\t\t1,\t\t6\r\n6,\t\t2,\t\t15\r\n6,\t\t3,\t\t20\r\n6,\t\t4,\t\t15\r\n6,\t\t5,\t\t6\r\n6,\t\t6,\t\t1\r\n6,\t\t7,\t\t\"#NUM!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/EVEN.data",
    "content": ",\t0\r\n5.4,\t6\r\n-5.4,\t-6\r\n1.5,\t2\r\n0.1,\t2\r\n3,\t4\r\n2,\t2\r\n-2,\t-2\r\n-1,\t-2\r\n\"ABC\",\t\"#VALUE!\"\r\nTRUE,\t2\r\nFALSE,\t0\r\n0,\t0\r\n210.61,\t212\r\n2.98,\t4\r\n-2.98,\t-4\r\n6,\t6\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/FACT.data",
    "content": "5,\t120\r\n1.9,\t1\r\n0,\t1\r\n-4,\t\"#NUM!\"\r\n1,\t1\r\n3,\t6\r\n6,\t720\r\n10,\t3628800\r\n3.2,\t6\r\n\"ABC\",\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/FACTDOUBLE.data",
    "content": "0,\t1\r\n6,\t48\r\n7,\t105\r\n5,\t15\r\n8,\t384\r\n13,\t135135\r\n-1,\t\"#NUM!\"\r\n\"ABC\",\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/FLOOR.data",
    "content": "2.5,\t1,\t2\r\n-2.5,\t-2,\t-2\r\n-2.5,\t2,\t\"#NUM!\"\r\n2.5,\t-2,\t\"#NUM!\"\r\n123.456,0,\t\"#DIV/0!\"\r\n1.5,\t0.1,\t1.5\r\n0.234,\t0.01,\t0.23\r\n123.456,\t\"#VALUE!\"\r\n\"ABC\",\t\t\"#VALUE!\"\r\n17,\t3,\t15\r\n19,\t4,\t16\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/GCD.data",
    "content": "5,\t2,\t\t1\r\n24,\t36,\t\t12\r\n7,\t1,\t\t1\r\n5,\t0,\t\t5\r\n30,\t15,\t10,\t5\r\n42,\t56,\t140,\t14\r\n24,\t28,\t40,\t4\r\n27,\t45,\t54,\t9\r\n84,\t126,\t196,\t14\r\n3,\t5,\t7,\t1\r\n3,\t5,\t0,\t1\r\n3,\t5,\t-7,\t\"#NUM!\"\r\n3,\t6,\t12,\t3\r\n3,\t6,\t\"12\",\t3\r\n3,\t6,\t\"ABC\",\t\"#VALUE!\"\r\n3,\t\t\t3\r\n15,\t10,\t25,\t5\r\n0,\t8,\t12,\t4\r\n7,\t2,\t\t1\r\n0,\t0,\t\t0\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/INT.data",
    "content": ",\t0\r\n5.4,\t5\r\n-5.4,\t-6\r\n-3.2,\t-4\r\n1.5,\t1\r\n0.1,\t0\r\n-0.1,\t-1\r\n3,\t3\r\n2,\t2\r\n-2.01,\t-3\r\n-2,\t-2\r\n-1,\t-1\r\n\"ABC\",\t\"#VALUE!\"\r\nTRUE,\t1\r\nFALSE,\t0\r\n0,\t0\r\n\"-3.5\",\t-4\r\n8.9,\t8\r\n-8.9,\t-9\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/LCM.data",
    "content": "5,\t2,\t\t10\r\n24,\t36,\t\t72\r\n3,\t7,\t12,\t84\r\n24.9,\t36.9,\t\t72\r\n6,\t22,\t121,\t726\r\n6,\t\"ABC\",\t\t\"#VALUE!\"\r\n24,\t-12,\t\t\"#NUM!\"\r\n3,\t0,\t\t0\r\n1,\t5,\t\t5\r\n15,\t10,\t25,\t150\r\n1,\t8,\t12,\t24\r\n7,\t2,\t\t14\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/LOG.data",
    "content": "#number\tbase\t\tresult\r\n\"ABC\",\t\t\t\"#VALUE!\"\r\n\"123ABC\",\t\t\"#VALUE!\"\r\n1.2345,\t\t\t0.0914910942679511\r\n-1.5,\t-0.75,\t\t\"#NUM!\"\r\n0,\t-0.75,\t\t\"#NUM!\"\r\n3.75,\t-0.75,\t\t\"#NUM!\"\r\n-1.5,\t0,\t\t\"#NUM!\"\r\n0,\t0,\t\t\"#NUM!\"\r\n3.75,\t0,\t\t\"#NUM!\"\r\n-0.75,\t0.75,\t\t\"#NUM!\"\r\n0,\t0.75,\t\t\"#NUM!\"\r\n0.75,\t0.75,\t\t1.0\r\n1.5,\t0.75,\t\t-1.4094208396532100\r\n2.25,\t0.75,\t\t-2.8188416793064200\r\n3,\t0.75,\t\t-3.8188416793064200\r\n3.75,\t0.75,\t\t-4.5945019399978900\r\n4.5,\t0.75,\t\t-5.2282625189596300\r\n-0.75,\t1.5,\t\t\"#NUM!\"\r\n0,\t1.5,\t\t\"#NUM!\"\r\n0.75,\t1.5,\t\t-0.7095112913514550\r\n1.5,\t1.5,\t\t1.0\r\n2.25,\t1.5,\t\t2.0\r\n3,\t1.5,\t\t2.7095112913514500\r\n3.75,\t1.5,\t\t3.2598510045646600\r\n4.5,\t1.5,\t\t3.7095112913514500\r\n-0.75,\t2.25,\t\t\"#NUM!\"\r\n0,\t2.25,\t\t\"#NUM!\"\r\n0.75,\t2.25,\t\t-0.3547556456757270\r\n1.5,\t2.25,\t\t0.5\r\n2.25,\t2.25,\t\t1.0\r\n3,\t2.25,\t\t1.3547556456757300\r\n3.75,\t2.25,\t\t1.6299255022823300\r\n4.5,\t2.25,\t\t1.8547556456757300\r\n-0.75,\t3,\t\t\"#NUM!\"\r\n0,\t3,\t\t\"#NUM!\"\r\n0.75,\t3,\t\t-0.2618595071429150\r\n1.5,\t3,\t\t0.3690702464285430\r\n2.25,\t3,\t\t0.7381404928570850\r\n3,\t3,\t\t1.0\r\n3.75,\t3,\t\t1.2031140135750100\r\n4.5,\t3,\t\t1.3690702464285400\r\n-0.75,\t3.75,\t\t\"#NUM!\"\r\n0,\t3.75,\t\t\"#NUM!\"\r\n0.75,\t3.75,\t\t-0.2176514479827300\r\n1.5,\t3.75,\t\t0.3067624865675560\r\n2.25,\t3.75,\t\t0.6135249731351110\r\n3,\t3.75,\t\t0.8311764211178410\r\n3.75,\t3.75,\t\t1.0\r\n4.5,\t3.75,\t\t1.1379389076854000\r\n-0.75,\t4.5,\t\t\"#NUM!\"\r\n0,\t4.5,\t\t\"#NUM!\"\r\n0.75,\t4.5,\t\t-0.1912681309275550\r\n1.5,\t4.5,\t\t0.2695772896908150\r\n2.25,\t4.5,\t\t0.5391545793816300\r\n3,\t4.5,\t\t0.7304227103091850\r\n3.75,\t4.5,\t\t0.8787817986064220\r\n4.5,\t4.5,\t\t1.0\r\n64,\t2,\t\t6\r\n100,\t\t\t2\r\n4,\t0.5,\t\t-2\r\n500,\t\t\t2.698970004336\r\n10,\t\t\t1\r\n8,\t2,\t\t3\r\n86,\t2.7182818,\t4.454347342888\r\n20,\t\t\t1.301029995664\r\n20,\t10,\t\t1.301029995664\r\n20,\t25,\t\t0.930676558073\r\n25,\t5.1,\t\t1.975690971574\r\n200,\t3,\t\t4.822736302150\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/MDETERM.data",
    "content": "{1|2|3;4|5|6;7|8|9},\t\t\t6.661338147750940E-16\r\n{1.1|2.2|3.3;4.4|5.5|6.6;7.7|8.8|9.9},\t1.61204383175573E-15\r\n{10|20|30;40|50|60;70|80|90},\t\t-4.26325641456060E-12\r\n{8|1|6;3|5|7;4|9|2},\t\t\t-3.6E+02\r\n{5|2;7|1},\t\t\t\t-9\r\n{6|4|2;3|5|3;2|3|4},\t\t\t40\r\n{0.2|1;0.35|10.8},\t\t\t1.81\r\n{0.2|1|-0.9;0.35|10.8|4;-3.15|5|},\t\"#VALUE!\"\r\n{1|2;3|4},\t\t\t\t-2\r\n{1|2|1;3|4|2;1|1|2},\t\t\t-3\r\n{1|3|8|5;1|3|6|1;1|1|1|0;7|3|10|2},\t88\r\n{3|6|1;1|1|0;3|10|2},\t\t\t1\r\n{3|6;1|1},\t\t\t\t-3\r\n{1|3|8|5;1|3|6|1},\t\t\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/MINVERSE.data",
    "content": "{1|2|3;4|5|6;7|8|9},    {-4.50359962737050E+15|9.00719925474099E+15|-4.50359962737050E+15;9.00719925474100E+15|-1.80143985094820E+16|9.00719925474099E+15;-4.50359962737050E+15|9.00719925474099E+15|-4.50359962737050E+15}\r\n{10|20|30;40|50|60;70|80|90},\t\t{7.03687441776639E+13|-1.40737488355328E+14|7.03687441776640E+13;-1.40737488355328E+14|2.81474976710656E+14|-1.40737488355328E+14;7.03687441776641E+13|-1.40737488355328E+14|7.03687441776640E+13}\r\n{8|1|6;3|5|7;4|9|2},\t\t\t{1.47222222222222E-01|-1.44444444444444E-01|6.38888888888889E-02;-6.11111111111111E-02|2.22222222222222E-02|1.05555555555556E-01;-1.94444444444444E-02|1.88888888888889E-01|-1.02777777777778E-01}\r\n{4|-1;2|0},\t\t\t\t{0|0.5;-1|2}\r\n{1|2|1;3|4|-1;0|2|0},\t\t\t{0.25|0.25|-0.75;0|0|0.5;0.75|-0.25|-0.25}\r\n{1|4|1|1;1|4|0|1;2|3|1|2;3|2|6|4},\t{3.2|-4.8|2.8|-1;0.2|0.2|0.2|0;1|-1|0|0;-4|5|-2|1}\r\n{0.2|1;0.35|10.8},\t\t\t{5.96685082872928|-0.55248618784530;-0.19337016574586|0.11049723756906}\r\n{0.2|1|-0.9;0.35|10.8|4;-3.15|5},\t\"#VALUE!\"\r\n{1|2;3|4},\t\t\t\t{-2|1;1.5|-0.5}\r\n{1|2|1;3|4|2;1|1|2},\t\t\t{-2|1|0;1.33333333333333|-0.33333333333333|-0.33333333333333;0.33333333333333|-0.33333333333333|0.66666666666667}\r\n{2|3;4|5},   {-2.5|1.5;2|-1}\r\n{5|8;7|9},  {-0.818181818181818|0.727272727272727;0.636363636363636|-0.454545454545455}\r\n{45|78;17|50},  {0.054112554112554|-0.084415584415584;-0.018398268398268|0.048701298701299}\r\n{2|2;2|1},   {-0.5|1.0;1|-1}\r\n{1|4|6;7|4|10;15|16|20},    {-0.2941176470588230|0.0588235294117647|0.0588235294117647;0.0367647058823529|-0.2573529411764710|0.1176470588235290;0.1911764705882350|0.1617647058823530|-0.0882352941176471}"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/MMULT.data",
    "content": "{1|2;3|4},\t\t{1|2;3|4},\t\t{7|10;15|22}\r\n{1|2|3;4|5|6;7|8|9},\t{1|2|3;4|5|6;7|8|9},\t{30|36|42;66|81|96;102|126|150}\r\n{1|2;3|4},\t\t2,\t\t\t\"#VALUE!\"   // Mismatched dimensions\r\n{1|2;3|4},\t\t{2},\t\t\t\"#VALUE!\"   // Mismatched dimensions\r\n{1.2;2.4},      {3.6|4.5},          {14.43|14.43;14.43|14.43}\r\n2,\t\t\t{1|2;3|4},\t\t\"#VALUE!\"   // Mismatched dimensions\r\n{2},\t\t\t{1|2;3|4},\t\t\"#VALUE!\"   // Mismatched dimensions\r\n{1|2;3|4},\t\t{2|4},\t\t\t\"#VALUE!\"\r\n{1|2;3|4},\t\t{2;4},\t\t\t{{10};{22}}\r\n{2|4},\t\t\t{1|2;3|4},\t\t{14|20}\r\n{2;4},\t\t\t{1|2;3|4},\t\t\"#VALUE!\"   // Mismatched dimensions\r\n{1|2;3|4;5|6},\t\t{1|2|3;4|5|6},\t\t{9|12|15;19|26|33;29|40|51}\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/MOD.data",
    "content": "19,\t17,\t2\r\n19,\t-13,\t-7\r\n34,\t17,\t0\r\n34,\t0,\t\"#DIV/0!\"\r\n3,\t2,\t1\r\n-3,\t2,\t1\r\n3,\t-2,\t-1\r\n-3,\t-2,\t-1\r\n2.5,\t1.3,\t1.2\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/MROUND.data",
    "content": "10,\t\t3,\t9\r\n-10,\t\t-3,\t-9\r\n1.3,\t\t0.2,\t1.4\r\n5,\t\t0,\t0\r\n3.14159,\t0.002,\t3.142\r\n-3.14159,\t-.02,\t-3.14\r\n31415.92654,\t10,\t31420\r\n31415.92654,\t1,\t31416\r\n5,\t\t-2,\t\"#NUM!\"\r\n\"ABC\",\t\t1,\t\"#VALUE!\"\r\n1.234,\t\t\"ABC\",\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/MULTINOMIAL.data",
    "content": "2,\t3,\t4,\t\t1260\r\n3,\t1,\t2,\t5,\t27720\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/ODD.data",
    "content": ",\t1\r\n5.4,\t7\r\n-5.4,\t-7\r\n1.5,\t3\r\n0.1,\t1\r\n3,\t3\r\n2,\t3\r\n-2,\t-3\r\n-1,\t-1\r\n\"ABC\",\t\"#VALUE!\"\r\nTRUE,\t1\r\nFALSE,\t1\r\n0,\t1\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/POWER.data",
    "content": "-1.5,\t-1.5,\t\"#NUM!\"\r\n-0.75,\t-1.5,\t\"#NUM!\"\r\n0,\t-1.5,\t\"#DIV/0!\"\r\n0.75,\t-1.5,\t1.539600717839\r\n1.5,\t-1.5,\t0.54433105395182\r\n2.25,\t-1.5,\t0.2962962962963\r\n3,\t-1.5,\t0.19245008972988\r\n3.75,\t-1.5,\t0.13770607453182\r\n4.5,\t-1.5,\t0.10475656017579\r\n-1.5,\t-0.75,\t\"#NUM!\"\r\n-0.75,\t-0.75,\t\"#NUM!\"\r\n0,\t-0.75,\t\"#DIV/0!\"\r\n0.75,\t-0.75,\t1.2408064788028\r\n1.5,\t-0.75,\t0.73778794646688\r\n2.25,\t-0.75,\t0.54433105395182\r\n3,\t-0.75,\t0.43869133765083\r\n3.75,\t-0.75,\t0.37108769116183\r\n4.5,\t-0.75,\t0.32366118113822\r\n-1.5,\t0,\t1\r\n-0.75,\t0,\t1\r\n0,\t0,\t\"#NUM!\"\r\n0.75,\t0,\t1\r\n1.5,\t0,\t1\r\n2.25,\t0,\t1\r\n3,\t0,\t1\r\n3.75,\t0,\t1\r\n4.5,\t0,\t1\r\n-1.5,\t0.75,\t\"#NUM!\"\r\n-0.75,\t0.75,\t\"#NUM!\"\r\n0,\t0.75,\t0\r\n0.75,\t0.75,\t0.80592744886766\r\n1.5,\t0.75,\t1.35540300541477\r\n2.25,\t0.75,\t1.83711730708738\r\n3,\t0.75,\t2.27950705695478\r\n3.75,\t0.75,\t2.69478083972313\r\n4.5,\t0.75,\t3.08965071586068\r\n-1.5,\t1.5,\t\"#NUM!\"\r\n-0.75,\t1.5,\t\"#NUM!\"\r\n0,\t1.5,\t0\r\n0.75,\t1.5,\t0.64951905283833\r\n1.5,\t1.5,\t1.83711730708738\r\n2.25,\t1.5,\t3.375\r\n3,\t1.5,\t5.19615242270663\r\n3.75,\t1.5,\t7.26184377413891\r\n4.5,\t1.5,\t9.54594154601839\r\n-1.5,\t2.25,\t\"#NUM!\"\r\n-0.75,\t2.25,\t\"#NUM!\"\r\n0,\t2.25,\t0\r\n0.75,\t2.25,\t0.52346523324493\r\n1.5,\t2.25,\t2.49003431932572\r\n2.25,\t2.25,\t6.20027091141992\r\n3,\t2.25,\t11.8446661165724\r\n3.75,\t2.25,\t19.5690774636122\r\n4.5,\t2.25,\t29.4936251312199\r\n-1.5,\t3,\t-3.375\r\n-0.75,\t3,\t-0.421875\r\n0,\t3,\t0\r\n0.75,\t3,\t0.421875\r\n1.5,\t3,\t3.375\r\n2.25,\t3,\t11.390625\r\n3,\t3,\t27\r\n3.75,\t3,\t52.734375\r\n4.5,\t3,\t91.125\r\n-1.5,\t3.75,\t\"#NUM!\"\r\n-0.75,\t3.75,\t\"#NUM!\"\r\n0,\t3.75,\t0\r\n0.75,\t3.75,\t0.34000064249104\r\n1.5,\t3.75,\t4.57448514327484\r\n2.25,\t3.75,\t20.9259143260422\r\n3,\t3.75,\t61.546690537779\r\n3.75,\t3.75,\t142.107583344775\r\n4.5,\t3.75,\t281.544421482804\r\n-1.5,\t4.5,\t\"#NUM!\"\r\n-0.75,\t4.5,\t\"#NUM!\"\r\n0,\t4.5,\t0\r\n0.75,\t4.5,\t0.27401585041617\r\n1.5,\t4.5,\t6.20027091141992\r\n2.25,\t4.5,\t38.443359375\r\n3,\t4.5,\t140.296115413079\r\n3.75,\t4.5,\t382.948792776857\r\n4.5,\t4.5,\t869.873923380926\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/PRODUCT.data",
    "content": "5,\t15,\t30,\t\t\t2250\r\n5,\t15,\t30,\t2,\t\t4500\r\n3,\t6,\t2,\t8,\t5,\t1440\r\n3,\t4,\t\t\t\t12\r\n3,\t4,\t4.5,\t\t\t54\r\n3,\t4,\t4.5,\t-6.78,\t\t-366.12\r\n3,\t4,\t4.5,\t-6.78,\t-2,\t732.24\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/QUOTIENT.data",
    "content": "5,\t2,\t2\r\n4.5,\t3.1,\t1\r\n-10,\t3,\t-3\r\n10,\t2.2,\t4\r\n5.5,\t2.667,\t2\r\n-7,\t2,\t-4\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/ROMAN.data",
    "content": "49,\t\"XLIX\"\r\n50,\t\"L\"\r\n2012,\t\"MMXII\"\r\n999,\t\"CMXCIX\"\r\n499,\t\"CDXCIX\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/ROUNDDOWN.data",
    "content": "662.79,\t\t0,\t662\r\n662.79,\t\t1,\t662.7\r\n54.1,\t\t-1,\t50\r\n55.1,\t\t-1,\t50\r\n-23.67,\t\t1,\t-23.6\r\n3.2,\t\t0,\t3\r\n3.2,\t\t0.01,\t3\r\n76.9,\t\t0,\t76\r\n3.14159,\t3,\t3.141\r\n-3.14159,\t1,\t-3.1\r\n31415.92654,\t-2,\t31400\r\n31415.92654,\t-1,\t31410\r\n\"ABC\",\t\t1,\t\"#VALUE!\"\r\n1.234,\t\t\"ABC\",\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/ROUNDUP.data",
    "content": "662.79,\t\t0,\t663\r\n662.79,\t\t1,\t662.8\r\n54.1,\t\t-1,\t60\r\n55.1,\t\t-1,\t60\r\n-23.62,\t\t1,\t-23.7\r\n3.2,\t\t0,\t4\r\n3.2,\t\t0.01,\t4\r\n76.9,\t\t0,\t77\r\n3.14159,\t3,\t3.142\r\n-3.14159,\t1,\t-3.2\r\n31415.92654,\t-2,\t31500\r\n31415.92654,\t-1,\t31420\r\n\"ABC\",\t\t1,\t\"#VALUE!\"\r\n1.234,\t\t\"ABC\",\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/SERIESSUM.data",
    "content": "5,\t1,\t1,\t{1|1|1|1|1},\t3905\r\n2,\t1,\t2,\t{1|2|3|4|5},\t3186\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/SIGN.data",
    "content": "-1.5,\t-1\r\n-1,\t-1\r\n-0.5,\t-1\r\n0,\t0\r\n0.5,\t1\r\n1,\t1\r\n1.5,\t1\r\n2,\t1\r\n2.5,\t1\r\n\"ABC\",\t\"#VALUE!\"\r\nTRUE,\t1\r\nFALSE,\t0\r\n\"-3.5\",\t-1\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/SQRTPI.data",
    "content": "\"ABC\",\t\"#VALUE!\"\r\n-1.5,\t\"#NUM!\"\r\n-1,\t\"#NUM!\"\r\n-0.5,\t\"#NUM!\"\r\n0,\t0.000000000000000000\r\n0.5,\t1.253314137315500000\r\n1,\t1.772453850905520000\r\n1.5,\t2.170803763674800000\r\n2,\t2.506628274631000000\r\n2.5,\t2.802495608198960000\r\n3,\t3.069980123839470000\r\n3.5,\t3.315957521978270000\r\n4,\t3.544907701811030000\r\n4.5,\t3.759942411946500000\r\n5,\t3.963327297606010000\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/SUMSQ.data",
    "content": "3,\t4,\t\t\t25\r\n5,\t2,\t1,\t3,\t39\r\n5,\t2,\t1,\t6,\t66\r\n1,\t3,\t\t\t10\r\n1,\t3,\t2,\t4,\t30\r\n3,\t5,\t7,\t\t83\r\n1,\t2,\t3,\t\t14\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/MathTrig/TRUNC.data",
    "content": "3.14159,\t2,\t3.14\r\n3.14159,\t3,\t3.141\r\n-3.14159,\t2,\t-3.14\r\n-3.14159,\t3,\t-3.141\r\n31415.92654,\t10,\t31415.92654\r\n-31415.92654,\t10,\t-31415.92654\r\n31415.92654,\t2,\t31415.92\r\n31415.92654,\t-2,\t31400\r\n31415.92654,\t-10,\t0\r\n-31415.92654,\t-10,\t0\r\n12345.6789,\t-3,\t12000\r\n12345.6789,\t-2,\t12300\r\n12345.6789,\t-1,\t12340\r\n12345.6789,\t0,\t12345\r\n12345.6789,\t1,\t12345.6\r\n12345.6789,\t2,\t12345.67\r\n12345.6789,\t3,\t12345.678\r\n\"ABC\",\t\t2,\t\"#VALUE!\"\r\n31415.92654,\t\"ABC\",\t\"#VALUE!\"\r\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/CHAR.data",
    "content": "\"ABC\",\t\"#VALUE!\"\n-5,\t\"#VALUE!\"\n65,\t\"A\"\n123,\t\"{\"\n126,\t\"~\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/CLEAN.data",
    "content": "\"\u0005\u0006\u0007\b\u0001\u0002HELLO      \",\t\"HELLO      \"\n\"\tHELLO\",\t\t\"HELLO\"\n\"HELLO    WORLD\",\t\"HELLO    WORLD\"\nTRUE,\t\t\t\"TRUE\"\nNULL,\t\t\tNULL\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/CODE.data",
    "content": ",\t\t\"#VALUE!\"\n\"\",\t\t\"#VALUE!\"\n\"ABC\",\t\t65\n123,\t\t49\nTRUE,\t\t84\n\"DEF\",\t\t68\n\"PHPExcel\",\t80\n1.5,\t\t49\n\"Mark Baker\",\t77\n\"mark baker\",\t109\n\"£125.00\",\t163\n\"Бензин\",\t1234"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/CONCATENATE.data",
    "content": "\"ABCDE\",\t\"FGHIJ\",\t\t\"ABCDEFGHIJ\"\n1,\t\t2,\t\t3,\t\"123\"\n\"Boolean\",\t\"-\",\t\tTRUE,\t\"Boolean-TRUE\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/DOLLAR.data",
    "content": "123.456,\t2,\t'\"$123.46\"'\n123.321,\t2,\t'\"$123.32\"'\n1234567,\t-3,\t'\"$1,235,000\"'\n1234567,\t-5,\t'\"$1,200,000\"'\n\"ABC\",\t\t2,\t\"#NUM!\"\n123.456,\t\"ABC\",\t\"#NUM!\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/FIND.data",
    "content": "\"E\",\t\"QWERTYUIOP\",\t\t3\n\"D\",\t\"ABCDEFGHI\",\t\t4\n\"E\",\tTRUE,\t\t\t4\n\"E\",\tFALSE,\t\t\t5\n\"A\",\t\"Mark Baker\",\t\t\"#VALUE!\"\n\"A\",\t\"MARK BAKER\",\t\t2\n\"a\",\t\"Mark Baker\",\t2,\t2\n\"k\",\t\"Mark Baker\",\t2,\t4\n\"k\",\t\"Mark Baker\",\t5,\t8\n\"a\",\t\"Mark Baker\",\t3,\t7\n\"BITE\",\t\"BIT\",\t\t\t\"#VALUE!\"\n\"\",\t\"Mark Baker\",\t\t1\n\"\",\t\"Mark Baker\",\t8,\t8\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/FIXED.data",
    "content": "123456.789,\t2,\tFALSE,\t'\"123,456.79\"'\n123456.789,\t1,\tTRUE,\t'\"123456.8\"'\n123456.789,\t2,\tTRUE,\t'\"123456.79\"'\n\"ABC\",\t\t2,\tNULL,\t\"#NUM!\"\n123.456,\t\"ABC\",\tNULL,\t\"#NUM!\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/LEFT.data",
    "content": ",\t\t1,\t\"\"\n\"\",\t\t1,\t\"\"\n\"QWERTYUIOP\",\t-1,\t\"#VALUE!\"\n\"ABCDEFGHI\",\t3,\t\"ABC\"\nTRUE,\t\t2,\t\"TR\"\nFALSE,\t\t2,\t\"FA\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/LEN.data",
    "content": ",\t\t0\n\"\",\t\t0\n\"AbCdEfGhI\",\t9\n\"MARK BAKER\",\t10\nTRUE,\t\t4\nFALSE,\t\t5\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/LOWER.data",
    "content": "\"AbCdEfGhI\",\t\"abcdefghi\"\n\"MARK BAKER\",\t\"mark baker\"\nTRUE,\t\t\"true\"\nFALSE,\t\t\"false\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/MID.data",
    "content": ",\t\t1,\t1,\t\"\"\n\"\",\t\t1,\t1,\t\"\"\n\"QWERTYUIOP\",\t-1,\t1,\t\"#VALUE!\"\n\"QWERTYUIOP\",\t5,\t-1,\t\"#VALUE!\"\n\"QWERTYUIOP\",\t5,\t\t\"\"\n\"QWERTYUIOP\",\t8,\t20,\t\"IOP\"\n\"ABCDEFGHI\",\t4,\t3,\t\"DEF\"\nTRUE,\t\t2,\t1,\t\"R\"\nFALSE,\t\t2,\t2,\t\"AL\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/PROPER.data",
    "content": "\"MARK BAKER\",\t\"Mark Baker\"\nTRUE,\t\t\"True\"\nFALSE,\t\t\"False\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/REPLACE.data",
    "content": "\"QWERTYUIOP\",\t3,\t3,\t\"DFG\",\t\"QWDFGYUIOP\"\n\"QWERTYUIOP\",\t5,\t3,\t\"DFG\",\t\"QWERDFGIOP\"\n\"QWERTYUIOP\",\t3,\t0,\t\"DFG\",\t\"QWDFGERTYUIOP\"\n\"QWERTYUIOP\",\t5,\t0,\t\"DFG\",\t\"QWERDFGTYUIOP\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/RIGHT.data",
    "content": ",\t\t1,\t\"\"\n\"\",\t\t1,\t\"\"\n\"QWERTYUIOP\",\t-1,\t\"#VALUE!\"\n\"ABCDEFGHI\",\t3,\t\"GHI\"\nTRUE,\t\t2,\t\"UE\"\nFALSE,\t\t2,\t\"SE\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/SEARCH.data",
    "content": "\"E\",\t\"QWERTYUIOP\",\t\t3\n\"D\",\t\"ABCDEFGHI\",\t\t4\n\"E\",\tTRUE,\t\t\t4\n\"E\",\tFALSE,\t\t\t5\n\"A\",\t\"Mark Baker\",\t\t2\n\"C\",\t\"Mark Baker\",\t\t\"#VALUE!\"\n\"A\",\t\"Mark Baker\",\t3,\t7\n\"K\",\t\"Mark Baker\",\t\t4\n\"K\",\t\"Mark Baker\",\t5,\t8\n\"A\",\t\"Mark Baker\",\t2,\t2\n\"BITE\",\t\"BIT\",\t\t\t\"#VALUE!\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/SUBSTITUTE.data",
    "content": "\"QWERTYUIOP\",\t\"ERT\",\t\"DFG\",\t\t\t\"QWDFGYUIOP\"\n\"Mark Baker\",\t\"a\",\t\"x\",\t\t\t\"Mxrk Bxker\"\n\"Mark Baker\",\t\"a\",\t\"x\",\t\t1,\t\"Mxrk Baker\"\n\"Mark Baker\",\t\"x\",\t\"a\",\t\t1,\t\"Mark Baker\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/T.data",
    "content": "123456.789,\tNULL\n\"123456.789\",\t\"123456.789\"\n\"Mark Baker\",\t\"Mark Baker\"\nNULL,\t\tNULL\nTRUE,\t\tNULL\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/TEXT.data",
    "content": "123.456,\t\t'\"$#,##0.00\"',\t\"$123.46\"\n-123.456,\t\t'\"$#,##0.00\"',\t\"$-123.46\"\n123.456,\t\t'\"#,##0.00\"',\t\"123.46\"\n123.456,\t\t'\"#,##0\"',\t\t\"123\"\n123.456,\t\t\"00000\",\t\t\"00123\"\n123456.789,\t\t'\"$#,##0.00\"',\t'\"$123,456.79\"'\n123456.789,\t\t'\"#,##0.00\"',\t'\"123,456.79\"'\n123456.789,\t\t\"0.00E+00\",\t\t\"1.23E05\"\n-123456.789,\t\"0.00E+00\",\t\t\"-1.23E05\"\n0.000012345,\t\"0.00E+00\",\t\t\"1.23E-05\"\n\"19-Dec-1960\",\t\"yyyy-mm-dd\",\t\"1960-12-19\"\n\"1-Jan-2012\",\t\"yyyy-mm-dd\",\t\"2012-01-01\"\n1.75,\t\t\t\"# ?/?\",\t\t\"1 3/4\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/TRIM.data",
    "content": "\"HELLO    \",\t\t\"HELLO\"\n\"    HELLO\",\t\t\"HELLO\"\n\"   HELLO      \",\t\"HELLO\"\n\"\tHELLO\",\t\t\"\tHELLO\"\n\"HELLO    WORLD\",\t\"HELLO WORLD\"\nTRUE,\t\t\t\"TRUE\"\nNULL,\t\t\tNULL\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/UPPER.data",
    "content": "\"AbCdEfGhI\",\t\"ABCDEFGHI\"\n\"mark baker\",\t\"MARK BAKER\"\nTRUE,\t\t\"TRUE\"\nFALSE,\t\t\"FALSE\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Calculation/TextData/VALUE.data",
    "content": "\"1000\",\t        \"1000\"\n\"1 000\",\t    \"1000\"\n\"$1 000\",\t\t\"1000\"\n\"£1 000\",\t\t\"#VALUE!\"\n\"1.1\",\t\t    \"1.1\"\n\"1 000.1\",\t\t\"1000.1\"\n\"13 Monkeys\",\t\"#VALUE!\"\n\"1-Jan-2014\",\t\"41640\"\n\"12:34:56\",     \"0.524259259259259\"\n\"2:46 AM\",      \"0.11527777777778\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/CalculationBinaryComparisonOperation.data",
    "content": "# formula, expectedResultExcel, expectedResultOpenOffice\n'=TRUE',\tTRUE,\tTRUE\n'=1 + 2.5',\t3.5,\t3.5\n'=2.5 + 1',\t3.5,\t3.5\n'=1 - 2.5',\t-1.5,\t-1.5\n'=2.5 - 1',\t1.5,\t1.5\n'=3 > 1',\tTRUE,\tTRUE\n'=3 > 3',\tFALSE,\tFALSE\n'=1 > 3',\tFALSE,\tFALSE\n'=3 < 1',\tFALSE,\tFALSE\n'=3 < 3',\tFALSE,\tFALSE\n'=1 < 3',\tTRUE,\tTRUE\n'=3 = 1',\tFALSE,\tFALSE\n'=3 = 3',\tTRUE,\tTRUE\n'=1 = 1.0',\tTRUE,\tTRUE\n'=3 >= 1',\tTRUE,\tTRUE\n'=3 >= 3',\tTRUE,\tTRUE\n'=1 >= 3',\tFALSE,\tFALSE\n'=3 <= 1',\tFALSE,\tFALSE\n'=3 <= 3',\tTRUE,\tTRUE\n'=1 <= 3',\tTRUE,\tTRUE\n'=3 <> 1',\tTRUE,\tTRUE\n'=3 <> 3',\tFALSE,\tFALSE\n'=1 <> 1.0',\tFALSE,\tFALSE\n'=\"a\" > \"a\"',\tFALSE,\tFALSE\n'=\"A\" > \"A\"',\tFALSE,\tFALSE\n'=\"A\" > \"a\"',\tFALSE,\tTRUE\n'=\"a\" > \"A\"',\tFALSE,\tFALSE\n'=\"a\" < \"a\"',\tFALSE,\tFALSE\n'=\"A\" < \"A\"',\tFALSE,\tFALSE\n'=\"A\" < \"a\"',\tFALSE,\tFALSE\n'=\"a\" < \"A\"',\tFALSE,\tTRUE\n'=\"a\" = \"a\"',\tTRUE,\tTRUE\n'=\"A\" = \"A\"',\tTRUE,\tTRUE\n'=\"A\" = \"a\"',\tTRUE,\tFALSE\n'=\"a\" = \"A\"',\tTRUE,\tFALSE\n'=\"a\" <= \"a\"',\tTRUE,\tTRUE\n'=\"A\" <= \"A\"',\tTRUE,\tTRUE\n'=\"A\" <= \"a\"',\tTRUE,\tFALSE\n'=\"a\" <= \"A\"',\tTRUE,\tTRUE\n'=\"a\" >= \"a\"',\tTRUE,\tTRUE\n'=\"A\" >= \"A\"',\tTRUE,\tTRUE\n'=\"A\" >= \"a\"',\tTRUE,\tTRUE\n'=\"a\" >= \"A\"',\tTRUE,\tFALSE\n'=\"a\" <> \"a\"',\tFALSE,\tFALSE\n'=\"A\" <> \"A\"',\tFALSE,\tFALSE\n'=\"A\" <> \"a\"',\tFALSE,\tTRUE\n'=\"a\" <> \"A\"',\tFALSE,\tTRUE\n'=\"A\" > \"b\"',\tFALSE,\tTRUE\n'=\"a\" > \"b\"',\tFALSE,\tFALSE\n'=\"b\" > \"a\"',\tTRUE,\tTRUE\n'=\"b\" > \"A\"',\tTRUE,\tFALSE\n'=\"a2\" > \"a10\"',\tTRUE,\tTRUE // Test natural sorting is not used\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Cell/DefaultValueBinder.data",
    "content": "NULL,       \"null\"\n,           \"null\"\n\"#NULL!\",   \"e\"\nFALSE,      \"b\"\nTRUE,       \"b\"\n\"FALSE\",    \"s\"\n\"TRUE\",     \"s\"\n\"\",         \"s\"\n\"ABC\",      \"s\"\n\"123\",      \"n\"\n123,        \"n\"\n0.123,      \"n\"\n\"-123\",     \"n\"\n\"1.23E4\",   \"n\"\n\"-1.23E4\",  \"n\"\n\"1.23E-4\",  \"n\"\n\"000123\",   \"s\"\n\"=123\",     \"f\"\n\"#DIV/0!\",  \"e\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/CellAbsoluteCoordinate.data",
    "content": "\"A1\",\t\t\t\t\"$A$1\"\n\"A12\",\t\t\t\t\"$A$12\"\n\"J1\",\t\t\t\t\"$J$1\"\n\"J20\",\t\t\t\t\"$J$20\"\n\"AI1\",\t\t\t\t\"$AI$1\"\n\"AI2012\",\t\t\t\"$AI$2012\"\n\"'Worksheet1'!AI256\",\t\t\"'Worksheet1'!$AI$256\"\n\"Worksheet1!AI256\",\t\t\"Worksheet1!$AI$256\"\n\"'Data Worksheet'!AI256\",\t\"'Data Worksheet'!$AI$256\"\n\"'Worksheet1'!$AI256\",\t\t\"'Worksheet1'!$AI$256\"\n\"'Worksheet1'!AI$256\",\t\t\"'Worksheet1'!$AI$256\"\n\"'Worksheet1'!$AI$256\",\t\t\"'Worksheet1'!$AI$256\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/CellAbsoluteReference.data",
    "content": "\"A1\",\t\t\t\t\"$A$1\"\n\"A12\",\t\t\t\t\"$A$12\"\n\"J1\",\t\t\t\t\"$J$1\"\n\"J20\",\t\t\t\t\"$J$20\"\n\"AI1\",\t\t\t\t\"$AI$1\"\n\"AI2012\",\t\t\t\"$AI$2012\"\n\"'Worksheet1'!AI256\",\t\t\"'Worksheet1'!$AI$256\"\n\"Worksheet1!AI256\",\t\t\"Worksheet1!$AI$256\"\n\"'Data Worksheet'!AI256\",\t\"'Data Worksheet'!$AI$256\"\n\"AI\",\t\t\t\t\"$AI\"\n2012,\t\t\t\t\"$2012\"\n\"Worksheet1!AI\",\t\t\"Worksheet1!$AI\"\n\"Worksheet1!256\",\t\t\"Worksheet1!$256\"\n\"'Worksheet1'!$AI256\",\t\t\"'Worksheet1'!$AI$256\"\n\"'Worksheet1'!AI$256\",\t\t\"'Worksheet1'!$AI$256\"\n\"'Worksheet1'!$AI$256\",\t\t\"'Worksheet1'!$AI$256\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/CellBuildRange.data",
    "content": "{\"B4\"|\"E9\"},\t\t\"B4:E9\"\n{\"B4\"|\"E9\";\"H2\"|\"O11\"},\t'\"B4:E9,H2:O11\"'\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/CellCoordinates.data",
    "content": "\"A1\",\t\t{\"A\";1}\n\"A12\",\t\t{\"A\";12}\n\"J1\",\t\t{\"J\";1}\n\"J20\",\t\t{\"J\";20}\n\"AI1\",\t\t{\"AI\";1}\n\"AI2012\",\t{\"AI\";2012}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/CellExtractAllCellReferencesInRange.data",
    "content": "\"B4:B6\",\t\t{\"B4\";\"B5\";\"B6\"}\n'\"B4:B6,D4:D6\"',\t{\"B4\";\"B5\";\"B6\";\"D4\";\"D5\";\"D6\"}\n'\"B4:B6 D4:D6\"',\t{\"B4\";\"B5\";\"B6\";\"D4\";\"D5\";\"D6\"}\n\"B4:D6\",\t\t{\"B4\";\"B5\";\"B6\";\"C4\";\"C5\";\"C6\";\"D4\";\"D5\";\"D6\"}\n'\"B4:D6,C5:E7\"',\t{\"B4\";\"B5\";\"B6\";\"C4\";\"C5\";\"C6\";\"C7\";\"D4\";\"D5\";\"D6\";\"D7\";\"E5\";\"E6\";\"E7\"}\n'\"B4:D6 C5:E7\"',\t{\"B4\";\"B5\";\"B6\";\"C4\";\"C5\";\"C6\";\"C7\";\"D4\";\"D5\";\"D6\";\"D7\";\"E5\";\"E6\";\"E7\"}\n\"B2:D4 C5:D5 E3:E5 D6:E6 F4:F6\",\t{\"B2\";\"B3\";\"B4\";\"C2\";\"C3\";\"C4\";\"C5\";\"D2\";\"D3\";\"D4\";\"D5\";\"D6\";\"E3\";\"E4\";\"E5\";\"E6\";\"F4\";\"F5\";\"F6\"}\n\"B2:D4 C3:E5 D4:F6\",\t{\"B2\";\"B3\";\"B4\";\"C2\";\"C3\";\"C4\";\"C5\";\"D2\";\"D3\";\"D4\";\"D5\";\"D6\";\"E3\";\"E4\";\"E5\";\"E6\";\"F4\";\"F5\";\"F6\"}\n\"B4:B6 B8\",\t\t{\"B4\";\"B5\";\"B6\";\"B8\"}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/CellGetRangeBoundaries.data",
    "content": "\"B4:E9\",\t\t{\"B\"|4;\"E\"|9}\n\"B4\",\t\t\t{\"B\"|4;\"B\"|4}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/CellRangeBoundaries.data",
    "content": "\"B4:E9\",\t\t{2|4;5|9}\n\"B4\",\t\t\t{2|4;2|4}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/CellRangeDimension.data",
    "content": "\"B4:E9\",\t\t{4;6}\n\"B4\",\t\t\t{1;1}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/CellSplitRange.data",
    "content": "\"B4:E9\",\t\t{\"B4\"|\"E9\"}\n\"B4\",\t\t\t{\"B4\"}\n'\"B4:E9,H2:O11\"',\t{\"B4\"|\"E9\";\"H2\"|\"O11\"}\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/ColumnIndex.data",
    "content": "0,\t\"A\"\n25,\t\"Z\"\n26,\t\"AA\"\n27,\t\"AB\"\n51,\t\"AZ\"\n52,\t\"BA\"\n701,\t\"ZZ\"\n702,\t\"AAA\"\n1378,\t\"BAA\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/ColumnString.data",
    "content": "\"A\",\t1\n\"Z\",\t26\n\"AA\",\t27\n\"AB\",\t28\n\"AZ\",\t52\n\"BA\",\t53\n\"ZZ\",\t702\n\"AAA\",\t703\n\"BAA\",\t1379\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Reader/XEETestInvalidUTF-8.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<!DOCTYPE root [\n     <!ENTITY x0 \"DoS\">\n]>\n\n<root>\n\ttest: (&x0;)\n</root>"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Reader/XEETestValidUTF-8.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<root>\n\ttest: Valid\n</root>"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Shared/CentimeterSizeToPixels.data",
    "content": "0.1,\t3.7795275591\n0.2,\t7.5590551182\n0.5,\t18.8976377955\n1.0,\t37.795275591\n2.0,\t75.590551182\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Shared/CodePage.data",
    "content": "367,\t\"ASCII\"\t\t\t//\tASCII\n437,\t\"CP437\"\t\t\t//\tOEM US\n737,\t\"CP737\"\t\t\t//\tOEM Greek\n775,\t\"CP775\"\t\t\t//\tOEM Baltic\n850,\t\"CP850\"\t\t\t//\tOEM Latin I\n852,\t\"CP852\"\t\t\t//\tOEM Latin II (Central European)\n855,\t\"CP855\"\t\t\t//\tOEM Cyrillic\n857,\t\"CP857\"\t\t\t//\tOEM Turkish\n858,\t\"CP858\"\t\t\t//\tOEM Multilingual Latin I with Euro\n860,\t\"CP860\"\t\t\t//\tOEM Portugese\n861,\t\"CP861\"\t\t\t//\tOEM Icelandic\n862,\t\"CP862\"\t\t\t//\tOEM Hebrew\n863,\t\"CP863\"\t\t\t//\tOEM Canadian (French)\n864,\t\"CP864\"\t\t\t//\tOEM Arabic\n865,\t\"CP865\"\t\t\t//\tOEM Nordic\n866,\t\"CP866\"\t\t\t//\tOEM Cyrillic (Russian)\n869,\t\"CP869\"\t\t\t//\tOEM Greek (Modern)\n874,\t\"CP874\"\t\t\t//\tANSI Thai\n932,\t\"CP932\"\t\t\t//\tANSI Japanese Shift-JIS\n936,\t\"CP936\"\t\t\t//\tANSI Chinese Simplified GBK\n949,\t\"CP949\"\t\t\t//\tANSI Korean (Wansung)\n950,\t\"CP950\"\t\t\t//\tANSI Chinese Traditional BIG5\n1200,\t\"UTF-16LE\"\t\t//\tUTF-16 (BIFF8)\n1250,\t\"CP1250\"\t\t//\tANSI Latin II (Central European)\n1251,\t\"CP1251\"\t\t//\tANSI Cyrillic\n0,\t\"CP1252\"\t\t//\tANSI Latin I (BIFF4-BIFF7)\n1252,\t\"CP1252\"\t\t//\tANSI Latin I (BIFF4-BIFF7)\n1253,\t\"CP1253\"\t\t//\tANSI Greek\n1254,\t\"CP1254\"\t\t//\tANSI Turkish\n1255,\t\"CP1255\"\t\t//\tANSI Hebrew\n1256,\t\"CP1256\"\t\t//\tANSI Arabic\n1257,\t\"CP1257\"\t\t//\tANSI Baltic\n1258,\t\"CP1258\"\t\t//\tANSI Vietnamese\n1361,\t\"CP1361\"\t\t//\tANSI Korean (Johab)\n10000,\t\"MAC\"\t\t\t//\tApple Roman\n10006,\t\"MACGREEK\"\t\t//\tMacintosh Greek\n10007,\t\"MACCYRILLIC\"\t\t//\tMacintosh Cyrillic\n10029,\t\"MACCENTRALEUROPE\"\t//\tMacintosh Central Europe\n10079, \t\"MACICELAND\"\t\t//\tMacintosh Icelandic\n10081, \t\"MACTURKISH\"\t\t//\tMacintosh Turkish\n32768,\t\"MAC\"\t\t\t//\tApple Roman\n65000,\t\"UTF-7\"\t\t\t//\tUnicode (UTF-7)\n65001,\t\"UTF-8\"\t\t\t//\tUnicode (UTF-8)\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Shared/DateTimeExcelToPHP1900.data",
    "content": "#Excel DateTimeStamp\tResult\t\tComments\n714,\t\t\t-2147472000\t//\tPHP 32-bit Earliest Date\t14-Dec-1901\n1461,\t\t\t-2082931200\t//\t\t\t\t\t31-Dec-1903\n1462,\t\t\t-2082844800\t//\tExcel 1904 Calendar Base Date\t01-Jan-1904\n1463,\t\t\t-2082758400\t//\t\t\t\t\t02-Jan-1904\n22269,\t\t\t-285120000\t//\t\t\t\t\t19-Dec-1960\n25569,\t\t\t0\t\t//\tPHP Base Date\t\t\t01-Jan-1970\n30292,\t\t\t408067200\t//\t\t\t\t\t07-Dec-1982\n39611,\t\t\t1213228800\t//\t\t\t\t\t12-Jun-2008\n50424,\t\t\t2147472000\t//\tPHP 32-bit Latest Date\t\t19-Jan-2038\n1234.56789,\t\t-2102494934\t//\t\t\t\t\t18-May-1903 13:37:46\n12345.6789,\t\t-1142494943\t//\t\t\t\t\t18-Oct-1933 16:17:37\n0.5,\t\t\t43200\t\t//\t\t\t\t\t12:00:00\n0.75,\t\t\t64800\t\t//\t\t\t\t\t18:00.00\n0.12345,\t\t10666\t\t//\t\t\t\t\t02:57:46\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Shared/DateTimeExcelToPHP1900Timezone.data",
    "content": "#Excel DateTimeStamp\tAdjust\tTimezone\t\tResult\t\tComments\n22269,\t\t\tTRUE,\t'America/New_York',\t-285138000\t//\t\t\t\t\t19-Dec-1960 00:00:00 UST\n25569,\t\t\tTRUE,\t'America/New_York',\t-18000\t\t//\tPHP Base Date\t\t\t01-Jan-1970 00:00:00 UST\n30292,\t\t\tTRUE,\t'America/New_York',\t408049200\t//\t\t\t\t\t07-Dec-1982 00:00:00 UST\n39611,\t\t\tTRUE,\t'America/New_York',\t1213214400\t//\t\t\t\t\t12-Jun-2008 00:00:00 UST\n50424,\t\t\tTRUE,\t'America/New_York',\t2147454000\t//\tPHP 32-bit Latest Date\t\t19-Jan-2038 00:00:00 UST\n22345.56789,\t\tTRUE,\t'America/New_York',\t-278522534\t//\t\t\t\t\t18-May-1903 13:37:46 UST\n22345.6789,\t\tTRUE,\t'America/New_York',\t-278512943\t//\t\t\t\t\t18-Oct-1933 16:17:37 UST\n0.5,\t\t\tTRUE,\t'America/New_York',\t25200\t\t//\t\t\t\t\t12:00:00 UST\n0.75,\t\t\tTRUE,\t'America/New_York',\t46800\t\t//\t\t\t\t\t18:00.00 UST\n0.12345,\t\tTRUE,\t'America/New_York',\t-7334\t\t//\t\t\t\t\t02:57:46 UST\n41215,\t\t\tTRUE,\t'America/New_York',\t1351800000\t//\t\t\t\t\t02-Nov-2012 00:00:00 UST\n22269,\t\t\tTRUE,\t'Pacific/Auckland',\t-285076800\t//\t\t\t\t\t19-Dec-1960 00:00:00 UST\n25569,\t\t\tTRUE,\t'Pacific/Auckland',\t43200\t\t//\tPHP Base Date\t\t\t01-Jan-1970 00:00:00 UST\n30292,\t\t\tTRUE,\t'Pacific/Auckland',\t408114000\t//\t\t\t\t\t07-Dec-1982 00:00:00 UST\n39611,\t\t\tTRUE,\t'Pacific/Auckland',\t1213272000\t//\t\t\t\t\t12-Jun-2008 00:00:00 UST\n50423.5,\t\tTRUE,\t'Pacific/Auckland',\t2147475600\t//\tPHP 32-bit Latest Date\t\t19-Jan-2038 00:00:00 UST\n22345.56789,\t\tTRUE,\t'Pacific/Auckland',\t-278461334\t//\t\t\t\t\t18-May-1903 13:37:46 UST\n22345.6789,\t\tTRUE,\t'Pacific/Auckland',\t-278451743\t//\t\t\t\t\t18-Oct-1933 16:17:37 UST\n0.5,\t\t\tTRUE,\t'Pacific/Auckland',\t90000\t\t//\t\t\t\t\t12:00:00 UST\n0.75,\t\t\tTRUE,\t'Pacific/Auckland',\t111600\t\t//\t\t\t\t\t18:00.00 UST\n0.12345,\t\tTRUE,\t'Pacific/Auckland',\t57466\t\t//\t\t\t\t\t02:57:46 UST\n41215,\t\t\tTRUE,\t'Pacific/Auckland',\t1351861200\t//\t\t\t\t\t02-Nov-2012 00:00:00 UST\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Shared/DateTimeExcelToPHP1904.data",
    "content": "#Excel DateTimeStamp\tResult\n1462,\t\t\t-1956528000\n1463,\t\t\t-1956441600\n22269,\t\t\t-158803200\n25569,\t\t\t126316800\n30292,\t\t\t534384000\n39611,\t\t\t1339545600\n0.25,\t\t\t21600\t\t//\t\t\t\t\t06:00:00\n0.3333333333333333333,\t28800\t\t//\t\t\t\t\t08:00.00\n0.54321,\t\t46933\t\t//\t\t\t\t\t02:57:46\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Shared/DateTimeFormatCodes.data",
    "content": "#Excel Format Code\t\t\tResult\n\"General\",\t\t\t\tFALSE\n\"@\",\t\t\t\t\tFALSE\n\"0\",\t\t\t\t\tFALSE\n\"0.00\",\t\t\t\t\tFALSE\n\"#,##0.00\",\t\t\t\tFALSE\n\"#,##0.00_-\",\t\t\t\tFALSE\n\"0%\",\t\t\t\t\tFALSE\n\"0.00%\",\t\t\t\tFALSE\n\"yyyy-mm-dd\",\t\t\t\tTRUE\n\"yy-mm-dd\",\t\t\t\tTRUE\n\"dd/mm/yy\",\t\t\t\tTRUE\n\"d/m/y\",\t\t\t\tTRUE\n\"d-m-y\",\t\t\t\tTRUE\n\"d-m\",\t\t\t\t\tTRUE\n\"m-y\",\t\t\t\t\tTRUE\n\"mm-dd-yy\",\t\t\t\tTRUE\n\"d-mmm-yy\",\t\t\t\tTRUE\n\"d-mmm\",\t\t\t\tTRUE\n\"mmm-yy\",\t\t\t\tTRUE\n\"m/d/yy h:mm\",\t\t\t\tTRUE\n\"d/m/y h:mm\",\t\t\t\tTRUE\n\"h:mm AM/PM\",\t\t\t\tTRUE\n\"h:mm:ss AM/PM\",\t\t\tTRUE\n\"h:mm\",\t\t\t\t\tTRUE\n\"h:mm:ss\",\t\t\t\tTRUE\n\"mm:ss\",\t\t\t\tTRUE\n\"h:mm:ss\",\t\t\t\tTRUE\n\"i:s.S\",\t\t\t\tTRUE\n\"h:mm:ss;@\",\t\t\t\tTRUE\n\"yy/mm/dd;@\",\t\t\t\tTRUE\n\"\\\"$\\\"#,##0.00_-\",\t\t\tFALSE\n\"$#,##0_-\",\t\t\t\tFALSE\n\"[$EUR ]#,##0.00_-\",\t\t\tFALSE\n\"_[$EUR ]#,##0.00_-\",\t\t\tFALSE\n\"[Green]#,##0.00;[Red]#,##0.00_-\",\tFALSE\n\"#,##0.00 \\\"dollars\\\"\",\t\t\tFALSE\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Shared/DateTimeFormattedPHPToExcel1900.data",
    "content": "#Year\tMonth\tDay\tHours\tMinutes\tSeconds\tResult\t\tComments\n1901,\t12,\t14,\t\t\t\t714\t\t//\tPHP 32-bit Earliest Date\t14-Dec-1901\n1903,\t12,\t31,\t\t\t\t1461\t\t//\t\t\t\t\t31-Dec-1903\n1904,\t1,\t1,\t\t\t\t1462\t\t//\tExcel 1904 Calendar Base Date\t01-Jan-1904\n1904,\t1,\t2,\t\t\t\t1463\t\t//\t\t\t\t\t02-Jan-1904\n1960,\t12,\t19,\t\t\t\t22269\t\t//\t\t\t\t\t19-Dec-1960\n1970,\t1,\t1,\t\t\t\t25569\t\t//\tPHP Base Date\t\t\t01-Jan-1970\n1982,\t12,\t7,\t\t\t\t30292\t\t//\t\t\t\t\t07-Dec-1982\n2008,\t6,\t12,\t\t\t\t39611\t\t//\t\t\t\t\t12-Jun-2008\n2038,\t1,\t19,\t\t\t\t50424\t\t//\tPHP 32-bit Latest Date\t\t19-Jan-2038\n1903,\t5,\t18,\t13,\t37,\t46,\t1234.56789\t//\t\t\t\t\t18-May-1903 13:37:46\n1933,\t10,\t18,\t16,\t17,\t37,\t12345.6789\t//\t\t\t\t\t18-Oct-1933 16:17:37\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Shared/DateTimePHPToExcel1900.data",
    "content": "#Excel DateTimeStamp\tResult\t\tComments\n-2147472000,\t\t714\t\t//\tPHP 32-bit Earliest Date\t14-Dec-1901\n-2082931200,\t\t1461\t\t//\t\t\t\t\t31-Dec-1903\n-2082844800,\t\t1462\t\t//\tExcel 1904 Calendar Base Date\t01-Jan-1904\n-2082758400,\t\t1463\t\t//\t\t\t\t\t02-Jan-1904\n-285120000,\t\t22269\t\t//\t\t\t\t\t19-Dec-1960\n0,\t\t\t25569\t\t//\tPHP Base Date\t\t\t01-Jan-1970\n408067200,\t\t30292\t\t//\t\t\t\t\t07-Dec-1982\n1213228800,\t\t39611\t\t//\t\t\t\t\t12-Jun-2008\n2147472000,\t\t50424\t\t//\tPHP 32-bit Latest Date\t\t19-Jan-2038\n-2102494934,\t\t1234.56789\t//\t\t\t\t\t18-May-1903 13:37:46\n-1142494943,\t\t12345.6789\t//\t\t\t\t\t18-Oct-1933 16:17:37\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Shared/DateTimePHPToExcel1904.data",
    "content": "#Excel DateTimeStamp\tResult\n-1956528000,\t\t1462\n-1956441600,\t\t1463\n-158803200,\t\t22269\n126316800,\t\t25569\n534384000,\t\t30292\n1339545600,\t\t39611\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Shared/FontSizeToPixels.data",
    "content": "6,\t8\n7,\t9\n8,\t10\n9,\t12\n10,\t13\n11,\t14\n12,\t16\n14,\t18\n16,\t21\n18,\t24\n20,\t26\n22,\t29\n24,\t32\n36,\t48\n48,\t64\n60,\t80\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Shared/InchSizeToPixels.data",
    "content": "0.1,\t9.6\n0.2,\t19.2\n0.5,\t48.0\n1.0,\t96.0\n2.0,\t192.0\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Shared/PasswordHashes.data",
    "content": "\"PHPExcel\",\t\t\t\t\t\t\"8053\"\n\"Mark Baker\",\t\t\t\t\t\"877D\"\n\"!+&=()~§±æþ\",\t\t\t\t\t\"C0EA\"\n\"μυστικό κωδικό πρόσβασης\",\t\t\"FFFF26DD\"\n\"গোপন পাসওয়ার্ড\",\t\t\t\t\t\t\"E858\"\n\"Секретный пароль\",\t\t\t\t\"EA5F\"\n\"秘密口令\",\t\t\t\t\t\t\"C07E\"\n\"leyndarmál lykilorð\",\t\t\t\"99E8\"\n\"\",\t\t\t\t\t\t\t\t\"CE4B\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Style/ColorChangeBrightness.data",
    "content": "\"FFAABBCC\",\t0.1,\t\"FFB2C1D1\"\t//\tRGBA\n\"FFAABBCC\",\t-0.1,\t\"FF99A8B7\"\t//\tRGBA\n\"AABBCC\",\t0.1,\t\"B2C1D1\"\t//\tRGB\n\"AABBCC\",\t-0.1,\t\"99A8B7\"\t//\tRGB\n\"FF0000\",\t0.1,\t\"FF1919\"\n\"FF0000\",\t-0.1,\t\"E50000\"\n\"FF8080\",\t0.1,\t\"FF8C8C\"\n\"FF8080\",\t-0.1,\t\"E57373\"\n\"FF0000\",\t0.15,\t\"FF2626\"\n\"FF0000\",\t-0.15,\t\"D80000\"\n\"FF8080\",\t0.15,\t\"FF9393\"\n\"FF8080\",\t-0.15,\t\"D86C6C\"\n\"FFF008\",\t0.5,\t\"FFF783\"\n\"FFF008\",\t-0.5,\t\"7F7804\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Style/ColorGetBlue.data",
    "content": "\"FFAABBCC\",\t\t\"CC\"\t//\tRGBA (hex)\n\"FFAABBCC\",\tFALSE,\t204\t//\tRGBA (decimal)\n\"AABBCC\",\t\t\"CC\"\t//\tRGB (hex)\n\"AABBCC\",\tFALSE,\t204\t//\tRGB (decimal)\n\"FFFF00\",\t\t\"00\"\n\"FFFF00\",\tFALSE,\t0\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Style/ColorGetGreen.data",
    "content": "\"FFAABBCC\",\t\t\"BB\"\t//\tRGBA (hex)\n\"FFAABBCC\",\tFALSE,\t187\t//\tRGBA (decimal)\n\"AABBCC\",\t\t\"BB\"\t//\tRGB (hex)\n\"AABBCC\",\tFALSE,\t187\t//\tRGB (decimal)\n\"FF00FF\",\t\t\"00\"\n\"FF00FF\",\tFALSE,\t0\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Style/ColorGetRed.data",
    "content": "\"FFAABBCC\",\t\t\"AA\"\t//\tRGBA (hex)\n\"FFAABBCC\",\tFALSE,\t170\t//\tRGBA (decimal)\n\"AABBCC\",\t\t\"AA\"\t//\tRGB (hex)\n\"AABBCC\",\tFALSE,\t170\t//\tRGB (decimal)\n\"00FFFF\",\t\t\"00\"\n\"00FFFF\",\tFALSE,\t0\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/rawTestData/Style/NumberFormat.data",
    "content": "# value\t\tformat\t\t\t\t\t\t\t\t\tresult\n0.0,\t\t\"0.0\",\t\t\t\t\t\t\t\t\t\"0.0\"\n0.0,\t\t\"0\",\t\t\t\t\t\t\t\t\t\"0\"\n0,\t\t\t\"0.0\",\t\t\t\t\t\t\t\t\t\"0.0\"\n0,\t\t\t\"0\",\t\t\t\t\t\t\t\t\t\"0\"\n0,\t\t\t\"##0\",\t\t\t\t\t\t\t\t\t\"000\"\n12,\t\t\t\"#.0#\",\t\t\t\t\t\t\t\t\t\"12.0\"\n0.1,\t\t\"0.0\",\t\t\t\t\t\t\t\t\t\"0.1\"\n0.1,\t\t\"0\",\t\t\t\t\t\t\t\t\t\"0\"\n5.5555,\t\t\"0.###\",\t\t\t\t\t\t\t\t\"5.556\"\n5.5555,\t\t\"0.0##\",\t\t\t\t\t\t\t\t\"5.556\"\t\n5.5555,\t\t\"0.00#\",\t\t\t\t\t\t\t\t\"5.556\"\n5.5555,\t\t\"0.000\",\t\t\t\t\t\t\t\t\"5.556\"\n5.5555,\t\t\"0.0000\",\t\t\t\t\t\t\t\t\"5.5555\"\n12345.6789,\t'\"#,##0.00\"',\t\t\t\t\t\t\t'\"12,345.68\"'\n12345.6789,\t'\"#,##0.000\"',\t\t\t\t\t\t\t'\"12,345.679\"'\n12345.6789,\t'\"£ #,##0.00\"',\t\t\t\t\t\t\t'\"£ 12,345.68\"'\n12345.6789,\t'\"$ #,##0.000\"',\t\t\t\t\t\t'\"$ 12,345.679\"'\n5.6789,\t\t'\"#,##0.00\"',\t\t\t\t\t\t\t'\"5.68\"'\n12000,\t\t'\"#,###\"',\t\t\t\t\t\t\t\t'\"12,000\"'\n12000,\t\t'\"#,\"',\t\t\t\t\t\t\t\t\t'12'\n12200000,\t'\"0.0,,\"',\t\t\t\t\t\t\t\t'12.2'\t\t// Scaling test\n0.08,\t\t\"0%\",\t\t\t\t\t\t\t\t\t\"8%\"\n0.8,\t\t\"0%\",\t\t\t\t\t\t\t\t\t\"80%\"\n2.8,\t\t\"0%\",\t\t\t\t\t\t\t\t\t\"280%\"\n125.74,\t\t'$0.00\" Surplus\";$-0.00\" Shortage\"',\t\"$125.74 Surplus\"\n-125.74,\t'$0.00\" Surplus\";$-0.00\" Shortage\"',\t\"$-125.74 Shortage\"\n-125.74,\t'$0.00\" Surplus\";$0.00\" Shortage\"',\t\t\"$125.74 Shortage\"\n5.25,\t\t'# ???/???',\t\t\t\t\t\t\t\"5 1/4\"\t\t// Fraction\n5.3,\t\t'# ???/???',\t\t\t\t\t\t\t\"5 3/10\"\t// Vulgar Fraction\n5.25,\t\t'???/???',\t\t\t\t\t\t\t\t\"21/4\"\n123456789,\t'(000) 0-0000-000',\t\t\t\t\t\t\"(001) 2-3456-789\"\n123456789,\t'0 (+00) 0000 00 00 00',\t\t\t\t\"0 (+00) 0123 45 67 89\"\n123456789,\t'0000:00:00',\t\t\t\t\t\t\t\"12345:67:89\"\n-123456789,\t'0000:00:00',\t\t\t\t\t\t\t\"-12345:67:89\"\n1234567.89,\t'0000:00.00',\t\t\t\t\t\t\t\"12345:67.89\"\n-1234567.89,'0000:00.00',\t\t\t\t\t\t\t\"-12345:67.89\"\n"
  },
  {
    "path": "vendor/phpoffice/phpexcel/unitTests/testDataFileIterator.php",
    "content": "<?php\r\n\r\nclass testDataFileIterator implements Iterator\r\n{\r\n\r\n    protected $file;\r\n    protected $key = 0;\r\n    protected $current;\r\n\r\n    public function __construct($file)\r\n    {\r\n        $this->file = fopen($file, 'r');\r\n    }\r\n\r\n    public function __destruct()\r\n    {\r\n        fclose($this->file);\r\n    }\r\n\r\n    public function rewind()\r\n    {\r\n        rewind($this->file);\r\n        $this->current = $this->_parseNextDataset();\r\n        $this->key = 0;\r\n    }\r\n\r\n    public function valid()\r\n    {\r\n        return !feof($this->file);\r\n    }\r\n\r\n    public function key()\r\n    {\r\n        return $this->key;\r\n    }\r\n\r\n    public function current()\r\n    {\r\n        return $this->current;\r\n    }\r\n\r\n    public function next()\r\n    {\r\n        $this->current = $this->_parseNextDataset();\r\n        $this->key++;\r\n    }\r\n\r\n    private function _parseNextDataset()\r\n    {\r\n        //    Read a line of test data from the file\r\n        do {\r\n            //    Only take lines that contain test data and that aren't commented out\r\n            $testDataRow = trim(fgets($this->file));\r\n        } while (($testDataRow > '') && ($testDataRow{0} === '#'));\r\n\r\n        //    Discard any comments at the end of the line\r\n        list($testData) = explode('//',$testDataRow);\r\n\r\n        //    Split data into an array of individual values and a result\r\n        $dataSet = $this->_getcsv($testData, ',', \"'\");\r\n        foreach($dataSet as &$dataValue) {\r\n            $dataValue = $this->_parseDataValue($dataValue);\r\n        }\r\n        unset($dataValue);\r\n\r\n        return $dataSet;\r\n    }\r\n\r\n    private function _getcsv($input, $delimiter, $enclosure)\r\n    {\r\n        if (function_exists('str_getcsv')) {\r\n            return str_getcsv($input, $delimiter, $enclosure);\r\n        }\r\n\r\n        $temp = fopen('php://memory', 'rw');\r\n        fwrite($temp, $input);\r\n        rewind($temp);\r\n        $data = fgetcsv($temp, strlen($input), $delimiter, $enclosure);\r\n        fclose($temp);\r\n\r\n        if ($data === false) {\r\n            $data = array(null);\r\n        }\r\n\r\n        return $data;\r\n    }\r\n\r\n    private function _parseDataValue($dataValue) {\r\n        //    discard any white space\r\n        $dataValue = trim($dataValue);\r\n        //    test for the required datatype and convert accordingly\r\n        if (!is_numeric($dataValue)) {\r\n            if($dataValue == '') {\r\n                $dataValue = NULL;\r\n            } elseif($dataValue == '\"\"') {\r\n                $dataValue = '';\r\n            } elseif(($dataValue[0] == '\"') && ($dataValue[strlen($dataValue)-1] == '\"')) {\r\n                $dataValue = substr($dataValue,1,-1);\r\n            } elseif(($dataValue[0] == '{') && ($dataValue[strlen($dataValue)-1] == '}')) {\r\n                $dataValue = explode(';',substr($dataValue,1,-1));\r\n                foreach($dataValue as &$dataRow) {\r\n                    if (strpos($dataRow,'|') !== FALSE) {\r\n                        $dataRow = explode('|',$dataRow);\r\n                        foreach($dataRow as &$dataCell) {\r\n                            $dataCell = $this->_parseDataValue($dataCell);\r\n                        }\r\n                        unset($dataCell);\r\n                    } else {\r\n                        $dataRow = $this->_parseDataValue($dataRow);\r\n                    }\r\n                }\r\n                unset($dataRow);\r\n            } else {\r\n                switch (strtoupper($dataValue)) {\r\n                    case 'NULL' :  $dataValue = NULL; break;\r\n                    case 'TRUE' :  $dataValue = TRUE; break;\r\n                    case 'FALSE' : $dataValue = FALSE; break;\r\n                }\r\n            }\r\n        } else {\r\n            if (strpos($dataValue,'.') !== FALSE) {\r\n                $dataValue = (float) $dataValue;\r\n            } else {\r\n                $dataValue = (int) $dataValue;\r\n            }\r\n        }\r\n\r\n\t\treturn $dataValue;\r\n    }\r\n\r\n}\r\n"
  },
  {
    "path": "wemall7.sql",
    "content": "-- phpMyAdmin SQL Dump\n-- version 4.4.10\n-- http://www.phpmyadmin.net\n--\n-- Host: localhost:3306\n-- Generation Time: 2017-05-03 18:54:08\n-- 服务器版本： 5.5.42\n-- PHP Version: 5.5.26\n\nSET SQL_MODE = \"NO_AUTO_VALUE_ON_ZERO\";\nSET time_zone = \"+00:00\";\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `addons_putong_demo_config`\n--\n\nCREATE TABLE `addons_putong_demo_config` (\n  `id` int(10) unsigned NOT NULL,\n  `name` text NOT NULL COMMENT '活动名称',\n  `file_id` int(11) NOT NULL COMMENT '活动图片',\n  `sub` text NOT NULL COMMENT '活动描述',\n  `detail` text NOT NULL COMMENT '活动详情',\n  `timerange` text NOT NULL COMMENT '活动时间',\n  `remark` text NOT NULL COMMENT '备注',\n  `status` int(1) NOT NULL DEFAULT '1' COMMENT '1:开启0:关闭',\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `addons_putong_demo_config`\n--\n\nINSERT INTO `addons_putong_demo_config` (`id`, `name`, `file_id`, `sub`, `detail`, `timerange`, `remark`, `status`, `created_at`, `updated_at`) VALUES\n(1, '活动名称', 1, '这里是活动描述', '', '2017-05-01 12:00:00 --- 2017-05-25 11:59:59', '', 1, '2017-05-01 10:25:26', '2017-05-01 12:12:04'),\n(2, '活动2', 1, '活动描述', '<p>111</p>', '2017-05-01 12:00:00 --- 2017-05-11 11:59:59', '', 1, '2017-05-01 10:37:35', '2017-05-01 12:11:06');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `admin`\n--\n\nCREATE TABLE `admin` (\n  `id` int(10) unsigned NOT NULL COMMENT '用户ID',\n  `group_id` int(11) NOT NULL DEFAULT '1' COMMENT '用户组id',\n  `username` char(16) NOT NULL COMMENT '用户名',\n  `password` char(32) NOT NULL COMMENT '密码',\n  `email` char(32) NOT NULL COMMENT '用户邮箱',\n  `mobile` char(15) NOT NULL DEFAULT '' COMMENT '用户手机',\n  `reg_ip` varchar(20) NOT NULL DEFAULT '0' COMMENT '注册IP',\n  `last_login_time` timestamp NULL DEFAULT NULL COMMENT '最后登录时间',\n  `last_login_ip` text COMMENT '最后登录IP',\n  `status` tinyint(4) DEFAULT '0' COMMENT '用户状态',\n  `remark` text NOT NULL COMMENT '备注',\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='后台用户表';\n\n--\n-- 转存表中的数据 `admin`\n--\n\nINSERT INTO `admin` (`id`, `group_id`, `username`, `password`, `email`, `mobile`, `reg_ip`, `last_login_time`, `last_login_ip`, `status`, `remark`, `created_at`, `updated_at`) VALUES\n(1, 1, 'admin', '21232f297a57a5a743894a0e4a801fc3', '296720094@qq.com', '18053449656', '0', '2017-05-03 07:58:17', '0.0.0.0', 1, '1', '0000-00-00 00:00:00', '2017-05-03 07:58:17'),\n(2, 2, '1', 'c4ca4238a0b923820dcc509a6f75849b', '1604583867@qq.com', '18538753627', '0', '2017-05-01 10:03:14', '0.0.0.0', 1, '1', '2017-05-01 09:47:46', '2017-05-01 10:03:14');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `analysis`\n--\n\nCREATE TABLE `analysis` (\n  `id` int(10) unsigned NOT NULL,\n  `orders` int(11) NOT NULL,\n  `trades` float NOT NULL,\n  `registers` int(11) NOT NULL,\n  `users` int(11) NOT NULL COMMENT '当天购买人数',\n  `date` text,\n  `created_at` timestamp NULL DEFAULT NULL,\n  `updated_at` timestamp NULL DEFAULT NULL\n) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `analysis`\n--\n\nINSERT INTO `analysis` (`id`, `orders`, `trades`, `registers`, `users`, `date`, `created_at`, `updated_at`) VALUES\n(1, 0, 0, 1, 0, '2017-05-01', '2017-04-30 23:22:28', NULL),\n(2, 0, 0, 1, 0, '2017-05-02', '2017-05-01 21:21:32', NULL);\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `article`\n--\n\nCREATE TABLE `article` (\n  `id` int(10) unsigned NOT NULL,\n  `category_id` int(11) NOT NULL,\n  `title` text NOT NULL,\n  `author` text NOT NULL COMMENT '作者',\n  `sub` text NOT NULL,\n  `content` text NOT NULL,\n  `remark` text,\n  `visiter` int(11) NOT NULL DEFAULT '0',\n  `status` int(11) NOT NULL COMMENT '1:开启0:关闭',\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `article`\n--\n\nINSERT INTO `article` (`id`, `category_id`, `title`, `author`, `sub`, `content`, `remark`, `visiter`, `status`, `created_at`, `updated_at`) VALUES\n(1, 1, '文章功能测试', '2222', '2222', '<p>22222222</p>', '1', 11, 1, '2016-01-05 14:41:14', '2017-03-02 06:52:09'),\n(2, 2, '2222', '222', '222', '<p>222</p>', '1', 2, 1, '2017-01-14 07:06:18', '2017-03-02 06:52:01'),\n(3, 1, '121', '12', '122', '<p><img src=\"http://img.baidu.com/hi/jx2/j_0016.gif\"/></p>', '12', 9, 1, '2017-02-17 02:27:38', '2017-05-01 13:29:14');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `article_category`\n--\n\nCREATE TABLE `article_category` (\n  `id` int(11) unsigned NOT NULL,\n  `pid` int(11) NOT NULL COMMENT '上级',\n  `name` text NOT NULL COMMENT '类型',\n  `status` int(11) NOT NULL COMMENT '1:开启0:关闭',\n  `remark` text NOT NULL COMMENT '备注',\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='文章类型';\n\n--\n-- 转存表中的数据 `article_category`\n--\n\nINSERT INTO `article_category` (`id`, `pid`, `name`, `status`, `remark`, `created_at`, `updated_at`) VALUES\n(1, 0, '类型1', 1, '1211', '2016-12-08 23:17:30', '2017-05-01 13:17:02'),\n(2, 0, '类型2', 1, '', '2016-12-10 02:18:40', '2017-01-14 01:44:13'),\n(3, 2, '类型3', 1, '233232', '2016-12-11 04:13:00', '2017-03-02 06:51:21'),\n(4, 1, '222234', 1, '34444', '2017-03-02 06:50:51', '2017-03-02 06:51:12');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `auth_group`\n--\n\nCREATE TABLE `auth_group` (\n  `id` int(8) unsigned NOT NULL,\n  `title` char(100) NOT NULL DEFAULT '',\n  `status` int(1) NOT NULL DEFAULT '1' COMMENT '1:启用0:禁用',\n  `rules` text NOT NULL,\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `auth_group`\n--\n\nINSERT INTO `auth_group` (`id`, `title`, `status`, `rules`, `created_at`, `updated_at`) VALUES\n(1, '超级管理员', 1, '1,2,3,4,5,6,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,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,', '2017-01-16 01:28:11', '0000-00-00 00:00:00'),\n(2, '普通管理员', 1, '1,2,3,4,5,6,7', '2017-01-16 06:59:52', '2017-05-01 09:59:09');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `auth_group_access`\n--\n\nCREATE TABLE `auth_group_access` (\n  `id` int(10) unsigned NOT NULL,\n  `uid` int(11) NOT NULL,\n  `group_id` int(11) NOT NULL\n) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `auth_group_access`\n--\n\nINSERT INTO `auth_group_access` (`id`, `uid`, `group_id`) VALUES\n(1, 1, 1),\n(2, 2, 2);\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `auth_rule`\n--\n\nCREATE TABLE `auth_rule` (\n  `id` mediumint(8) unsigned NOT NULL,\n  `name` char(80) NOT NULL DEFAULT '',\n  `title` char(20) NOT NULL DEFAULT '',\n  `type` int(11) NOT NULL DEFAULT '1',\n  `rank` int(11) NOT NULL COMMENT '排序',\n  `status` tinyint(1) NOT NULL DEFAULT '1',\n  `condition` char(100) DEFAULT NULL,\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=50 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `auth_rule`\n--\n\nINSERT INTO `auth_rule` (`id`, `name`, `title`, `type`, `rank`, `status`, `condition`, `created_at`, `updated_at`) VALUES\n(1, 'admin/index/index', '系统首页', 1, 0, 1, '', '2017-01-09 08:37:37', '0000-00-00 00:00:00'),\n(2, 'admin/auth.group/index', '管理员用户组', 1, 0, 1, NULL, '2017-05-01 07:30:02', '0000-00-00 00:00:00'),\n(3, 'admin/auth.group/add', '新增修改用户组', 1, 0, 1, NULL, '2017-05-01 07:31:00', '0000-00-00 00:00:00'),\n(4, 'admin/auth.group/del', '删除用户组', 1, 0, 1, NULL, '2017-05-01 07:32:35', '0000-00-00 00:00:00'),\n(5, 'admin/auth.group/update', '开启关闭用户组', 1, 0, 1, NULL, '2017-05-01 07:33:01', '0000-00-00 00:00:00'),\n(6, 'admin/auth.admin/index', '管理员列表', 1, 0, 1, NULL, '2017-05-01 07:33:38', '0000-00-00 00:00:00'),\n(7, 'admin/auth.admin/add', '新增修改管理员', 1, 0, 1, NULL, '2017-05-01 07:34:02', '0000-00-00 00:00:00'),\n(8, 'admin/auth.admin/del', '删除管理员', 1, 0, 1, NULL, '2017-05-01 07:34:31', '0000-00-00 00:00:00'),\n(9, 'admin/auth.admin/update', '开启关闭管理员', 1, 0, 1, NULL, '2017-05-01 07:34:56', '0000-00-00 00:00:00'),\n(10, 'admin/addons/index', '插件管理', 1, 0, 1, NULL, '2017-05-01 10:08:37', '0000-00-00 00:00:00'),\n(11, 'admin/addons/shop', '插件商店', 1, 0, 1, NULL, '2017-05-01 10:09:15', '0000-00-00 00:00:00'),\n(12, 'admin/file/index', '图片管理', 1, 0, 1, NULL, '2017-05-01 11:07:22', '0000-00-00 00:00:00'),\n(13, 'admin/file/upload', '图片上传', 1, 0, 1, NULL, '2017-05-01 11:07:51', '0000-00-00 00:00:00'),\n(14, 'admin/user.index/index', '用户列表', 1, 0, 1, NULL, '2017-05-01 12:27:54', '0000-00-00 00:00:00'),\n(15, 'admin/user.index/add', '修改用户信息', 1, 0, 1, NULL, '2017-05-01 12:38:14', '0000-00-00 00:00:00'),\n(16, 'admin/user.index/update', '更新用户状态', 1, 0, 1, NULL, '2017-05-01 12:42:54', '0000-00-00 00:00:00'),\n(17, 'admin/user.index/export', '导出用户信息', 1, 0, 1, NULL, '2017-05-01 12:46:02', '0000-00-00 00:00:00'),\n(18, 'admin/user.level/index', '会员等级管理', 1, 0, 1, NULL, '2017-05-01 12:52:42', '0000-00-00 00:00:00'),\n(19, 'admin/user.level/add', '新增修改\b会员等级', 1, 0, 1, NULL, '2017-05-01 12:55:40', '0000-00-00 00:00:00'),\n(20, 'admin/article.category/index', '文章分类管理', 1, 0, 1, NULL, '2017-05-01 13:03:30', '0000-00-00 00:00:00'),\n(21, 'admin/article.category/add', '新增修改文章分类', 1, 0, 1, NULL, '2017-05-01 13:07:14', '0000-00-00 00:00:00'),\n(22, 'admin/article.category/update', '更改文章分类状态', 1, 0, 1, NULL, '2017-05-01 13:21:59', '0000-00-00 00:00:00'),\n(23, 'admin/article.index/index', '文章列表', 1, 0, 1, NULL, '2017-05-01 13:25:27', '0000-00-00 00:00:00'),\n(24, 'admin/article.index/add', '新增修改文章', 1, 0, 1, NULL, '2017-05-01 13:26:03', '0000-00-00 00:00:00'),\n(25, 'admin/article.index/update', '更新文章状态', 1, 0, 1, NULL, '2017-05-01 13:26:24', '0000-00-00 00:00:00'),\n(26, 'admin/config.site/index', '站点设置', 1, 0, 1, NULL, '2017-05-02 02:45:54', '0000-00-00 00:00:00'),\n(27, 'admin/wx.config/index', '微信配置', 1, 0, 1, NULL, '2017-05-03 08:02:56', '0000-00-00 00:00:00'),\n(28, 'admin/wx.menu/index', '微信菜单设置', 1, 0, 1, NULL, '2017-05-03 09:02:06', '0000-00-00 00:00:00'),\n(29, 'admin/wx.menu/add', '新增修改微信菜单', 1, 0, 1, NULL, '2017-05-03 09:02:32', '0000-00-00 00:00:00'),\n(30, 'admin/wx.menu/del', '删除微信菜单', 1, 0, 1, NULL, '2017-05-03 09:03:02', '0000-00-00 00:00:00'),\n(31, 'admin/wx.reply/index', '微信自定义回复设置', 1, 0, 1, NULL, '2017-05-03 09:03:37', '0000-00-00 00:00:00'),\n(32, 'admin/wx.reply/add', '新增修改微信自定义回复', 1, 0, 1, NULL, '2017-05-03 09:04:13', '0000-00-00 00:00:00'),\n(33, 'admin/wx.reply/del', '删除微信自定义回复', 1, 0, 1, NULL, '2017-05-03 09:04:52', '0000-00-00 00:00:00'),\n(34, 'admin/wx.tplmsg/index', '模版消息列表', 1, 0, 1, NULL, '2017-05-03 09:06:01', '0000-00-00 00:00:00'),\n(35, 'admin/wx.tplmsg/add', '新增修改模版消息', 1, 0, 1, NULL, '2017-05-03 09:06:25', '0000-00-00 00:00:00'),\n(36, 'admin/wx.tplmsg/update', '开启关闭模版消息', 1, 0, 1, NULL, '2017-05-03 09:06:51', '0000-00-00 00:00:00'),\n(37, 'admin/wx.kefu/index', '多客服设置', 1, 0, 1, NULL, '2017-05-03 09:07:38', '0000-00-00 00:00:00'),\n(38, 'admin/wx.print/index', '微信打印机设置', 1, 0, 1, NULL, '2017-05-03 09:08:02', '0000-00-00 00:00:00'),\n(39, 'admin/tpl.shop/index', '模版设置', 1, 0, 1, NULL, '2017-05-03 09:11:42', '0000-00-00 00:00:00'),\n(40, 'admin/tpl.mail/index', '邮件模版列表', 1, 0, 1, NULL, '2017-05-03 09:14:42', '0000-00-00 00:00:00'),\n(41, 'admin/tpl.mail/add', '新增修改邮件模版', 1, 0, 1, NULL, '2017-05-03 09:15:03', '0000-00-00 00:00:00'),\n(42, 'admin/tpl.mail/update', '更新邮件模版状态', 1, 0, 1, NULL, '2017-05-03 09:15:27', '0000-00-00 00:00:00'),\n(43, 'admin/tpl.mail/send', '测试邮件模版', 1, 0, 1, NULL, '2017-05-03 09:18:28', '0000-00-00 00:00:00'),\n(44, 'admin/tpl.sms/index', '短信模版列表', 1, 0, 1, NULL, '2017-05-03 09:18:55', '0000-00-00 00:00:00'),\n(45, 'admin/tpl.sms/add', '编辑短信模版', 1, 0, 1, NULL, '2017-05-03 09:20:38', '0000-00-00 00:00:00'),\n(46, 'admin/tpl.sms/update', '开启关闭短信模版', 1, 0, 1, NULL, '2017-05-03 09:21:15', '0000-00-00 00:00:00'),\n(47, 'admin/tpl.sms/send', '短信模版测试发送', 1, 0, 1, NULL, '2017-05-03 09:21:41', '0000-00-00 00:00:00'),\n(48, 'admin/config.sms/index', '短信配置', 1, 0, 1, NULL, '2017-05-03 09:25:38', '0000-00-00 00:00:00'),\n(49, 'admin/config.mail/index', '邮件配置', 1, 0, 1, NULL, '2017-05-03 09:26:19', '0000-00-00 00:00:00');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `config`\n--\n\nCREATE TABLE `config` (\n  `id` int(10) unsigned NOT NULL,\n  `title` text NOT NULL COMMENT '标题',\n  `keywords` text NOT NULL COMMENT '关键词',\n  `logo_id` int(11) NOT NULL COMMENT 'Logo',\n  `description` text NOT NULL COMMENT '描述',\n  `copyright` text NOT NULL COMMENT '版权',\n  `theme` text NOT NULL COMMENT '模版',\n  `tongji_code` text COMMENT '统计代码',\n  `created_at` timestamp NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `config`\n--\n\nINSERT INTO `config` (`id`, `title`, `keywords`, `logo_id`, `description`, `copyright`, `theme`, `tongji_code`, `created_at`, `updated_at`) VALUES\n(1, '单用户微商城', 'wemall', 1, '111111', 'Copyright © 2015 wemallshop.com All Rights Reserved 豫ICP备16009619号', 'default', '1111121', '2017-01-10 13:30:26', '2017-05-03 10:33:25');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `file`\n--\n\nCREATE TABLE `file` (\n  `id` int(10) unsigned NOT NULL,\n  `name` text NOT NULL,\n  `ext` text NOT NULL,\n  `type` text NOT NULL,\n  `savename` text NOT NULL,\n  `savepath` text NOT NULL,\n  `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP\n) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `file`\n--\n\nINSERT INTO `file` (`id`, `name`, `ext`, `type`, `savename`, `savepath`, `time`) VALUES\n(1, 'U4530P18DT20110710182825.jpg', '', 'image/jpeg', '8245f8334edabfa0bd90e8b9ab116093.jpg', '20170501/', '2017-05-01 11:10:01');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `mail`\n--\n\nCREATE TABLE `mail` (\n  `id` int(11) unsigned NOT NULL,\n  `host` text NOT NULL COMMENT '服务器地址',\n  `port` int(11) NOT NULL COMMENT '服务器端口',\n  `secure` double NOT NULL COMMENT '1:加密0:不加密',\n  `replyTo` text NOT NULL COMMENT '回信地址',\n  `user` text NOT NULL COMMENT '发送邮箱',\n  `pass` text NOT NULL COMMENT '授权码,通过QQ获取',\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1;\n\n--\n-- 转存表中的数据 `mail`\n--\n\nINSERT INTO `mail` (`id`, `host`, `port`, `secure`, `replyTo`, `user`, `pass`, `created_at`, `updated_at`) VALUES\n(1, 'smtpdm.aliyun.com', 465, 1, 'koahub@163.com', '1', '1', '2017-02-16 01:52:41', '2017-05-03 10:33:38');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `mail_tpl`\n--\n\nCREATE TABLE `mail_tpl` (\n  `id` int(11) unsigned NOT NULL,\n  `type` text NOT NULL COMMENT '类型',\n  `name` text NOT NULL COMMENT '模版名',\n  `content` text NOT NULL COMMENT '内容',\n  `status` int(11) NOT NULL DEFAULT '1' COMMENT '状态1:开启0:关闭',\n  `mail` text NOT NULL COMMENT '测试发送邮箱',\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `mail_tpl`\n--\n\nINSERT INTO `mail_tpl` (`id`, `type`, `name`, `content`, `status`, `mail`, `created_at`, `updated_at`) VALUES\n(1, 'register', '注册模版', '<p>您好，欢迎您注册wemallshop微信商城，您的验证码是：$code</p>', 1, '1604583867@qq.com', '0000-00-00 00:00:00', '2017-02-18 09:38:44');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `sms`\n--\n\nCREATE TABLE `sms` (\n  `id` int(10) unsigned NOT NULL,\n  `app_key` text NOT NULL,\n  `app_secret` text NOT NULL,\n  `sign` text NOT NULL COMMENT '短信签名',\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `sms`\n--\n\nINSERT INTO `sms` (`id`, `app_key`, `app_secret`, `sign`, `created_at`, `updated_at`) VALUES\n(1, '23643041', '17f711feb8fd1a0f3c376d4eaaa2710b', 'tp商城', '2016-07-19 09:38:40', '2017-05-03 10:33:31');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `sms_tpl`\n--\n\nCREATE TABLE `sms_tpl` (\n  `id` int(11) unsigned NOT NULL,\n  `type` text NOT NULL COMMENT '类型',\n  `name` text NOT NULL COMMENT '模版名',\n  `template_code` text NOT NULL COMMENT '模版ID',\n  `content` text NOT NULL COMMENT '内容',\n  `status` int(11) NOT NULL DEFAULT '1' COMMENT '状态1:开启0:关闭',\n  `phone` text NOT NULL COMMENT '测试发送邮箱',\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `sms_tpl`\n--\n\nINSERT INTO `sms_tpl` (`id`, `type`, `name`, `template_code`, `content`, `status`, `phone`, `created_at`, `updated_at`) VALUES\n(1, 'register', '短信验证码', 'SMS_47900069', '您的本次验证码${code}，10分钟内输入有效，感谢使用平台', 1, '15238027761', '0000-00-00 00:00:00', '2017-02-18 09:13:21');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `user`\n--\n\nCREATE TABLE `user` (\n  `id` int(10) unsigned NOT NULL,\n  `contact_id` int(11) NOT NULL COMMENT '默认地址',\n  `avater_id` int(11) NOT NULL COMMENT '头像',\n  `nickname` text,\n  `username` text NOT NULL,\n  `phone` text,\n  `password` text NOT NULL,\n  `token` text,\n  `money` float NOT NULL DEFAULT '0',\n  `score` float NOT NULL DEFAULT '0',\n  `status` int(11) NOT NULL DEFAULT '1' COMMENT '1:启用0:禁用',\n  `buy_num` int(11) NOT NULL COMMENT '用户购买量',\n  `remark` text,\n  `last_login_ip` text,\n  `last_login_time` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00',\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `user`\n--\n\nINSERT INTO `user` (`id`, `contact_id`, `avater_id`, `nickname`, `username`, `phone`, `password`, `token`, `money`, `score`, `status`, `buy_num`, `remark`, `last_login_ip`, `last_login_time`, `created_at`, `updated_at`) VALUES\n(1, 3, 78, NULL, 'wemall', '1', 'c4ca4238a0b923820dcc509a6f75849b', '', 2, 420, 1, 192, '1211', '192.168.0.120', '2017-05-02 03:17:11', '2017-05-01 02:14:20', '2017-05-01 12:38:32'),\n(2, 1, 1, '清月曦', '清月曦', '', '', NULL, 0, 0, 1, 0, '1', NULL, '2017-05-01 16:00:00', '2017-05-02 12:40:38', '2017-05-01 12:40:55');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `user_level`\n--\n\nCREATE TABLE `user_level` (\n  `id` int(11) NOT NULL,\n  `name` text NOT NULL,\n  `score` float NOT NULL COMMENT '达到积分',\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `user_level`\n--\n\nINSERT INTO `user_level` (`id`, `name`, `score`, `created_at`, `updated_at`) VALUES\n(1, '基础会员', 0, '2017-02-15 09:58:33', '2017-03-02 09:42:02'),\n(2, '初级会员', 50, '2016-12-26 15:53:37', '2017-02-15 10:37:28'),\n(3, '白金会员', 100, '2017-01-05 23:03:20', '2017-02-15 10:37:37'),\n(4, '铂金会员', 500, '2017-01-05 23:05:46', '2017-02-15 10:37:53'),\n(5, '黄金会员', 1000, '2017-03-02 07:12:29', '2017-05-01 12:56:15');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `wx_config`\n--\n\nCREATE TABLE `wx_config` (\n  `id` int(5) NOT NULL,\n  `token` text NOT NULL,\n  `appid` text NOT NULL,\n  `appsecret` text NOT NULL,\n  `encodingaeskey` text NOT NULL,\n  `x_appid` text NOT NULL COMMENT '小程序',\n  `x_appsecret` text NOT NULL COMMENT '小程序',\n  `old_id` text NOT NULL COMMENT '原始id',\n  `switch` int(11) NOT NULL,\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `wx_config`\n--\n\nINSERT INTO `wx_config` (`id`, `token`, `appid`, `appsecret`, `encodingaeskey`, `x_appid`, `x_appsecret`, `old_id`, `switch`, `created_at`, `updated_at`) VALUES\n(1, 'wemall', 'wx6d040141df50d2113', '523c93731918e84766114ca8f73133824', 'vkG6JOKy7f2f1nejqJalOJkjJEK5JJlNaJjjSQ6Q2gM', 'wx5f1a51823b8371ae8', '8e157d2823fb72dcb17f9762308b8333', 'gh_6f79b1a839f1', 1, '2016-01-05 02:16:16', '2017-05-03 10:33:43');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `wx_kefu`\n--\n\nCREATE TABLE `wx_kefu` (\n  `id` int(5) NOT NULL,\n  `status` int(11) NOT NULL,\n  `kefu` text NOT NULL,\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `wx_kefu`\n--\n\nINSERT INTO `wx_kefu` (`id`, `status`, `kefu`, `created_at`, `updated_at`) VALUES\n(1, 1, 'biyuehun', '0000-00-00 00:00:00', '2017-05-03 10:34:06');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `wx_menu`\n--\n\nCREATE TABLE `wx_menu` (\n  `id` int(5) NOT NULL,\n  `pid` int(5) NOT NULL DEFAULT '0',\n  `type` text,\n  `name` text NOT NULL,\n  `key` text NOT NULL,\n  `url` text NOT NULL,\n  `rank` text NOT NULL,\n  `status` tinyint(1) NOT NULL,\n  `remark` text,\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `wx_menu`\n--\n\nINSERT INTO `wx_menu` (`id`, `pid`, `type`, `name`, `key`, `url`, `rank`, `status`, `remark`, `created_at`, `updated_at`) VALUES\n(1, 0, 'view', '商业版', '111', 'http://www.wemallshop.com/wemall/index.php/App/Index/index', '1', 0, '2', '2016-02-18 06:46:22', '2017-01-11 10:28:43'),\n(2, 1, 'view', '分销版', '', 'http://www.wemallshop.com/wfx/App/Shop/index', '4', 0, '1213', '2015-11-06 09:25:28', '2017-02-16 10:17:00'),\n(3, 0, 'click', 'QQ客服', 'qqkf', '', '3', 0, '2034210985', '2015-12-31 08:19:22', '2017-05-03 09:03:10');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `wx_print`\n--\n\nCREATE TABLE `wx_print` (\n  `id` int(11) NOT NULL,\n  `apikey` varchar(100) DEFAULT NULL COMMENT 'apikey',\n  `mkey` varchar(100) DEFAULT NULL COMMENT '秘钥',\n  `partner` varchar(100) DEFAULT NULL COMMENT '用户id',\n  `machine_code` varchar(100) DEFAULT NULL COMMENT '机器码',\n  `switch` int(11) NOT NULL,\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `wx_print`\n--\n\nINSERT INTO `wx_print` (`id`, `apikey`, `mkey`, `partner`, `machine_code`, `switch`, `created_at`, `updated_at`) VALUES\n(1, '61', '31', '16', '16', 0, '2016-08-07 11:49:22', '2017-05-03 10:34:09');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `wx_reply`\n--\n\nCREATE TABLE `wx_reply` (\n  `id` int(10) unsigned NOT NULL,\n  `type` text NOT NULL,\n  `title` text NOT NULL,\n  `description` text NOT NULL,\n  `file_id` int(11) NOT NULL,\n  `url` text NOT NULL,\n  `key` text NOT NULL,\n  `remark` text,\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `wx_reply`\n--\n\nINSERT INTO `wx_reply` (`id`, `type`, `title`, `description`, `file_id`, `url`, `key`, `remark`, `created_at`, `updated_at`) VALUES\n(1, 'news', '恭喜你加入WeMall，欢迎体验WeMall商业版，WeMall分销版和WeMall开源版。WeMall商业版更新，速度提升30%，致力于打造世界上最快，体验最好的微商城。客服QQ：2034210985', '1111', 29, '', 'subscribe', '1212', '2016-01-05 02:19:53', '2017-03-02 06:49:04'),\n(2, 'news', '欢迎来到商业版wemall商城', '欢迎来到商业版wemall商城11111', 103, 'http://www.wemallshop.com/3/App/Index/index', '商城', '', '2016-01-05 02:23:41', '2017-03-02 06:49:49'),\n(3, 'news', '2222222', '111', 103, '1111', '11111', '1111', '2017-01-12 09:27:57', '2017-03-02 06:49:41');\n\n-- --------------------------------------------------------\n\n--\n-- 表的结构 `wx_tplmsg`\n--\n\nCREATE TABLE `wx_tplmsg` (\n  `id` int(10) unsigned NOT NULL,\n  `name` text NOT NULL,\n  `type` text NOT NULL,\n  `title` text NOT NULL,\n  `status` int(11) NOT NULL,\n  `remark` text NOT NULL,\n  `template_id_short` text NOT NULL,\n  `template_id` text NOT NULL,\n  `created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,\n  `updated_at` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00'\n) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;\n\n--\n-- 转存表中的数据 `wx_tplmsg`\n--\n\nINSERT INTO `wx_tplmsg` (`id`, `name`, `type`, `title`, `status`, `remark`, `template_id_short`, `template_id`, `created_at`, `updated_at`) VALUES\n(1, '订单提醒(新订单通知)', 'order', '尊敬的客户,您的订单已成功提交！', 1, '666', 'OPENTM201785396', '', '2016-08-07 11:50:16', '2017-01-12 23:07:32'),\n(2, '支付提醒(订单支付成功通知)', 'pay', '您已成功支付', 1, '3333', 'OPENTM207791277', '', '2016-08-07 11:50:16', '2017-01-12 23:07:35'),\n(3, '发货提醒(订单发货提醒)', 'delivery', '尊敬的客户,您的订单已发货！', 1, '33312', 'OPENTM207763419', '', '2016-08-07 11:50:16', '2017-02-16 11:04:46');\n\n--\n-- Indexes for dumped tables\n--\n\n--\n-- Indexes for table `addons_putong_demo_config`\n--\nALTER TABLE `addons_putong_demo_config`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `admin`\n--\nALTER TABLE `admin`\n  ADD PRIMARY KEY (`id`),\n  ADD UNIQUE KEY `username` (`username`),\n  ADD KEY `status` (`status`);\n\n--\n-- Indexes for table `analysis`\n--\nALTER TABLE `analysis`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `article`\n--\nALTER TABLE `article`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `article_category`\n--\nALTER TABLE `article_category`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `auth_group`\n--\nALTER TABLE `auth_group`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `auth_group_access`\n--\nALTER TABLE `auth_group_access`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `auth_rule`\n--\nALTER TABLE `auth_rule`\n  ADD PRIMARY KEY (`id`),\n  ADD UNIQUE KEY `name` (`name`);\n\n--\n-- Indexes for table `config`\n--\nALTER TABLE `config`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `file`\n--\nALTER TABLE `file`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `mail`\n--\nALTER TABLE `mail`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `mail_tpl`\n--\nALTER TABLE `mail_tpl`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `sms`\n--\nALTER TABLE `sms`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `sms_tpl`\n--\nALTER TABLE `sms_tpl`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `user`\n--\nALTER TABLE `user`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `user_level`\n--\nALTER TABLE `user_level`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `wx_config`\n--\nALTER TABLE `wx_config`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `wx_kefu`\n--\nALTER TABLE `wx_kefu`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `wx_menu`\n--\nALTER TABLE `wx_menu`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `wx_print`\n--\nALTER TABLE `wx_print`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `wx_reply`\n--\nALTER TABLE `wx_reply`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- Indexes for table `wx_tplmsg`\n--\nALTER TABLE `wx_tplmsg`\n  ADD PRIMARY KEY (`id`);\n\n--\n-- AUTO_INCREMENT for dumped tables\n--\n\n--\n-- AUTO_INCREMENT for table `addons_putong_demo_config`\n--\nALTER TABLE `addons_putong_demo_config`\n  MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=3;\n--\n-- AUTO_INCREMENT for table `admin`\n--\nALTER TABLE `admin`\n  MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '用户ID',AUTO_INCREMENT=3;\n--\n-- AUTO_INCREMENT for table `analysis`\n--\nALTER TABLE `analysis`\n  MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=3;\n--\n-- AUTO_INCREMENT for table `article`\n--\nALTER TABLE `article`\n  MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=4;\n--\n-- AUTO_INCREMENT for table `article_category`\n--\nALTER TABLE `article_category`\n  MODIFY `id` int(11) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=5;\n--\n-- AUTO_INCREMENT for table `auth_group`\n--\nALTER TABLE `auth_group`\n  MODIFY `id` int(8) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=3;\n--\n-- AUTO_INCREMENT for table `auth_group_access`\n--\nALTER TABLE `auth_group_access`\n  MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=3;\n--\n-- AUTO_INCREMENT for table `auth_rule`\n--\nALTER TABLE `auth_rule`\n  MODIFY `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=50;\n--\n-- AUTO_INCREMENT for table `config`\n--\nALTER TABLE `config`\n  MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;\n--\n-- AUTO_INCREMENT for table `file`\n--\nALTER TABLE `file`\n  MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;\n--\n-- AUTO_INCREMENT for table `mail`\n--\nALTER TABLE `mail`\n  MODIFY `id` int(11) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;\n--\n-- AUTO_INCREMENT for table `mail_tpl`\n--\nALTER TABLE `mail_tpl`\n  MODIFY `id` int(11) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;\n--\n-- AUTO_INCREMENT for table `sms`\n--\nALTER TABLE `sms`\n  MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;\n--\n-- AUTO_INCREMENT for table `sms_tpl`\n--\nALTER TABLE `sms_tpl`\n  MODIFY `id` int(11) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;\n--\n-- AUTO_INCREMENT for table `user`\n--\nALTER TABLE `user`\n  MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=3;\n--\n-- AUTO_INCREMENT for table `user_level`\n--\nALTER TABLE `user_level`\n  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=6;\n--\n-- AUTO_INCREMENT for table `wx_config`\n--\nALTER TABLE `wx_config`\n  MODIFY `id` int(5) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;\n--\n-- AUTO_INCREMENT for table `wx_kefu`\n--\nALTER TABLE `wx_kefu`\n  MODIFY `id` int(5) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;\n--\n-- AUTO_INCREMENT for table `wx_menu`\n--\nALTER TABLE `wx_menu`\n  MODIFY `id` int(5) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=4;\n--\n-- AUTO_INCREMENT for table `wx_print`\n--\nALTER TABLE `wx_print`\n  MODIFY `id` int(11) NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=2;\n--\n-- AUTO_INCREMENT for table `wx_reply`\n--\nALTER TABLE `wx_reply`\n  MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=4;\n--\n-- AUTO_INCREMENT for table `wx_tplmsg`\n--\nALTER TABLE `wx_tplmsg`\n  MODIFY `id` int(10) unsigned NOT NULL AUTO_INCREMENT,AUTO_INCREMENT=4;\n"
  }
]